diff --git a/Translations/BitmapEditor.html b/Translations/BitmapEditor.html index 4da92db4..b35d3af1 100644 --- a/Translations/BitmapEditor.html +++ b/Translations/BitmapEditor.html @@ -141,10 +141,36 @@ } } } + stringFromMatrix(true, false); + } + + function escapedToMatrix(str) { + app.encodedEscapeSequence = str; + clearMatrix(); + var strs = str.split("\\x"); + var c = 0; + var rs = 7; + for (var i = 0; i 0) { + v = parseInt(d, 16); + sv = padLeft(v.toString(2), "0", 8); + for (r = 0; r < 8; r++) { + paint(getCell(rs - r, c), sv.charAt(r) == '1'); + } + c++; + if (c >= app.matrix.cols) { + c = 0; + rs += 8; + } + } + } + stringFromMatrix(false, true); } - function stringFromMatrix() { + function stringFromMatrix(skipEncodedData, skipEncodedEscapeSequence) { var str = ""; + var strEscaped = ""; var delim = ""; var blocks = app.matrix.rows / 8; var rs = 7; @@ -158,11 +184,17 @@ } } str += delim + "0x" + padLeft(b.toString(16).toUpperCase(), "0", 2); + strEscaped += "\\x" + padLeft(b.toString(16).toUpperCase(), "0", 2); delim = ","; } rs += 8; } - app.encodedData = str; + if (!skipEncodedData) { + app.encodedData = str; + } + if (!skipEncodedEscapeSequence) { + app.encodedEscapeSequence = strEscaped; + } return str; } @@ -175,12 +207,16 @@ rows: 16 }, type: "big", - encodedData: "" + encodedData: "", + encodedEscapeSequence: "", }, methods : { VtoMatrix : function(val) { toMatrix(val); }, + escapedToMatrix : function(val) { + escapedToMatrix(val); + }, VchangeSize : function() { if (app.type == "big") { @@ -236,10 +272,11 @@
- +
- \ No newline at end of file + diff --git a/Translations/TranslationEditor.html b/Translations/TranslationEditor.html index 6f0ee320..91b982b7 100644 --- a/Translations/TranslationEditor.html +++ b/Translations/TranslationEditor.html @@ -48,8 +48,8 @@ } else if (id == "current-lang-file") { if (checkTranslationFile(file.name)) { app.current = json; - if (!app.current.cyrillicGlyphs){ - app.current.cyrillicGlyphs = false; + if (!app.current.fonts){ + app.current.fonts = ["ascii_basic"]; } app.meta.currentLoaded = true; } @@ -137,6 +137,7 @@ loaded: false, }, obsolete : {}, + fontToAdd: "latin_extended", }, methods : { validateInput: function(valMap, id, mode) { @@ -246,7 +247,15 @@ } else { valMap[id] = message; } - } + }, + + removeFont: function(i) { + this.current.fonts.splice(i, 1); + }, + + addFont: function() { + this.current.fonts.push(this.fontToAdd); + }, } }); app.def = def; @@ -289,12 +298,20 @@ - Font table to use + Font tables to use
("ascii_basic" must be first) - + + + + + diff --git a/Translations/font_tables.py b/Translations/font_tables.py index b5d9635a..e2f8cff9 100755 --- a/Translations/font_tables.py +++ b/Translations/font_tables.py @@ -1,822 +1,874 @@ -# coding=utf-8 -def get_font_map(): +from typing import Dict, Final, Tuple + + +def get_font_map_ascii_basic() -> Dict[str, bytes]: font = { - " ": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "!": "0x00,0x00,0x00,0x00,0x7C,0xFF,0xFF,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x00,0x00,0x00,0x00,0x00,", - '"': "0x00,0x00,0x00,0x3C,0x3C,0x00,0x00,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "#": "0x00,0x00,0x10,0x90,0xF0,0x7E,0x1E,0x90,0xF0,0x7E,0x1E,0x10,0x00,0x02,0x1E,0x1F,0x03,0x02,0x1E,0x1F,0x03,0x02,0x00,0x00,", - "$": "0x00,0x00,0x78,0xFC,0xCC,0xFF,0xFF,0xCC,0xCC,0x88,0x00,0x00,0x00,0x00,0x04,0x0C,0x0C,0x3F,0x3F,0x0C,0x0F,0x07,0x00,0x00,", - "%": "0x00,0x00,0x38,0x38,0x38,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x00,0x30,0x38,0x1C,0x0E,0x07,0x03,0x01,0x38,0x38,0x38,0x00,", - "&": "0x00,0x00,0x00,0xB8,0xFC,0xC6,0xE2,0x3E,0x1C,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x31,0x21,0x37,0x1E,0x1C,0x36,0x22,0x00,", - "'": "0x00,0x00,0x00,0x00,0x27,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "(": "0x00,0x00,0x00,0xF0,0xFC,0xFE,0x07,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x1F,0x38,0x20,0x20,0x00,0x00,0x00,", - ")": "0x00,0x00,0x00,0x01,0x01,0x07,0xFE,0xFC,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x38,0x1F,0x0F,0x03,0x00,0x00,0x00,", - "*": "0x00,0x00,0x98,0xB8,0xE0,0xF8,0xF8,0xE0,0xB8,0x98,0x00,0x00,0x00,0x00,0x0C,0x0E,0x03,0x0F,0x0F,0x03,0x0E,0x0C,0x00,0x00,", - "+": "0x00,0x00,0x80,0x80,0x80,0xF0,0xF0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0F,0x0F,0x01,0x01,0x01,0x00,0x00,", - ",": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB8,0xF8,0x78,0x00,0x00,0x00,0x00,0x00,", - "-": "0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,", - ".": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,", - "/": "0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x00,0x18,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,", - "0": "0x00,0xF8,0xFE,0x06,0x03,0x83,0xC3,0x63,0x33,0x1E,0xFE,0xF8,0x00,0x07,0x1F,0x1E,0x33,0x31,0x30,0x30,0x30,0x18,0x1F,0x07,", - "1": "0x00,0x00,0x00,0x0C,0x0C,0x0E,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x3F,0x3F,0x30,0x30,0x30,0x00,", - "2": "0x00,0x1C,0x1E,0x07,0x03,0x03,0x83,0xC3,0xE3,0x77,0x3E,0x1C,0x00,0x30,0x38,0x3C,0x3E,0x37,0x33,0x31,0x30,0x30,0x30,0x30,", - "3": "0x00,0x0C,0x0E,0x07,0xC3,0xC3,0xC3,0xC3,0xC3,0xE7,0x7E,0x3C,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0E,", - "4": "0x00,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0xFF,0xFF,0x00,0x00,0x00,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x03,0x03,", - "5": "0x00,0x3F,0x7F,0x63,0x63,0x63,0x63,0x63,0x63,0xE3,0xC3,0x83,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,", - "6": "0x00,0xC0,0xF0,0xF8,0xDC,0xCE,0xC7,0xC3,0xC3,0xC3,0x80,0x00,0x00,0x0F,0x1F,0x39,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,", - "7": "0x00,0x03,0x03,0x03,0x03,0x03,0x03,0xC3,0xF3,0x3F,0x0F,0x03,0x00,0x00,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00,", - "8": "0x00,0x00,0xBC,0xFE,0xE7,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x0F,0x1F,0x39,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,", - "9": "0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xFC,0x00,0x00,0x00,0x30,0x30,0x30,0x38,0x1C,0x0E,0x07,0x03,0x00,", - ":": "0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00,", - ";": "0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9C,0xFC,0x7C,0x00,0x00,0x00,0x00,0x00,", - "<": "0x00,0x00,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,0x00,", - "=": "0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x00,", - ">": "0x00,0x00,0x03,0x07,0x0E,0x1C,0x38,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x30,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,", - "?": "0x00,0x1C,0x1E,0x07,0x03,0x83,0xC3,0xE3,0x77,0x3E,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x37,0x00,0x00,0x00,0x00,0x00,", - "@": "0x00,0xF8,0xFE,0x07,0xF3,0xFB,0x1B,0xFB,0xFB,0x07,0xFE,0xF8,0x00,0x0F,0x1F,0x18,0x33,0x37,0x36,0x37,0x37,0x36,0x03,0x01,", - "A": "0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", - "B": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "C": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "D": "0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "E": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "F": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "G": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC7,0xC6,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,", - "H": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "I": "0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "J": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x0E,0x1E,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "K": "0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,", - "L": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "M": "0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,", - "N": "0x00,0xFF,0xFF,0x0E,0x38,0xF0,0xC0,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x03,0x07,0x1C,0x3F,0x3F,0x00,", - "O": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "P": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,", - "Р": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,", - "Q": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x36,0x3E,0x1C,0x3F,0x33,0x00,", - "R": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x03,0x07,0x0F,0x1D,0x38,0x30,0x00,", - "S": "0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC7,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "T": "0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "U": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "V": "0x00,0x07,0x3F,0xF8,0xC0,0x00,0x00,0xC0,0xF8,0x3F,0x07,0x00,0x00,0x00,0x00,0x01,0x0F,0x3E,0x3E,0x0F,0x01,0x00,0x00,0x00,", - "W": "0x00,0xFF,0xFF,0x00,0x00,0x80,0x80,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x06,0x03,0x03,0x06,0x1C,0x3F,0x3F,0x00,", - "X": "0x00,0x03,0x0F,0x1C,0x30,0xE0,0xE0,0x30,0x1C,0x0F,0x03,0x00,0x00,0x30,0x3C,0x0E,0x03,0x01,0x01,0x03,0x0E,0x3C,0x30,0x00,", - "Y": "0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "Z": "0x00,0x03,0x03,0x03,0x03,0xC3,0xE3,0x33,0x1F,0x0F,0x03,0x00,0x00,0x30,0x3C,0x3E,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x00,", - "[": "0x00,0x00,0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x00,0x00,0x00,", - "\\": "0x00,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x18,", - "]": "0x00,0x00,0x00,0x03,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,0x00,0x00,", - "^": "0x00,0x60,0x70,0x38,0x1C,0x0E,0x07,0x0E,0x1C,0x38,0x70,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "_": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,", - "`": "0x00,0x00,0x00,0x00,0x00,0x3E,0x7E,0x4E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "a": "0x00,0x00,0x40,0x60,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "b": "0x00,0xFF,0xFF,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "c": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,", - "d": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xE0,0xC0,0xFF,0xFF,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,", - "e": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,", - "f": "0x00,0xC0,0xC0,0xFC,0xFE,0xC7,0xC3,0xC3,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "g": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,", - "h": "0x00,0xFF,0xFF,0xC0,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,", - "i": "0x00,0x00,0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "j": "0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xE0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00,", - "k": "0x00,0x00,0xFF,0xFF,0x00,0x80,0xC0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x07,0x0F,0x1C,0x38,0x30,0x00,0x00,", - "l": "0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "m": "0x00,0xE0,0xC0,0xE0,0xE0,0xC0,0xC0,0xE0,0xE0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,", - "n": "0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "o": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "p": "0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x0C,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,", - "q": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x0C,0xFF,0xFF,0x00,", - "r": "0x00,0x00,0xE0,0xE0,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "s": "0x00,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,", - "t": "0x00,0x60,0x60,0xFE,0xFE,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x30,0x30,0x30,0x30,0x00,0x00,0x00,", - "u": "0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "v": "0x00,0x60,0xE0,0x80,0x00,0x00,0x00,0x00,0x80,0xE0,0x60,0x00,0x00,0x00,0x01,0x07,0x1E,0x38,0x38,0x1E,0x07,0x01,0x00,0x00,", - "w": "0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x07,0x1F,0x38,0x1C,0x0F,0x0F,0x1C,0x38,0x1F,0x07,0x00,", - "x": "0x00,0x60,0xE0,0xC0,0x80,0x00,0x80,0xC0,0xE0,0x60,0x00,0x00,0x00,0x30,0x38,0x1D,0x0F,0x07,0x0F,0x1D,0x38,0x30,0x00,0x00,", - "y": "0x00,0x00,0x60,0xE0,0x80,0x00,0x00,0x80,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,", - "z": "0x00,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x60,0x20,0x00,0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x30,0x00,0x00,", - "{": "0x00,0x00,0x80,0xC0,0xFC,0x7E,0x07,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x1F,0x3F,0x70,0x60,0x60,0x60,0x00,0x00,", - "|": "0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "}": "0x00,0x00,0x03,0x03,0x03,0x07,0x7E,0xFC,0xC0,0x80,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x70,0x3F,0x1F,0x01,0x00,0x00,0x00,", - "~": "0x00,0x10,0x18,0x0C,0x04,0x0C,0x18,0x10,0x18,0x0C,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "¡": "0x00,0x00,0x00,0x00,0x80,0xF3,0xF3,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x3F,0x3F,0x0F,0x00,0x00,0x00,0x00,", - "¢": "0x00,0x00,0xE0,0xF0,0x38,0xFE,0xFE,0x18,0x38,0x30,0x00,0x00,0x00,0x00,0x03,0x07,0x0E,0x3F,0x3F,0x0C,0x0E,0x06,0x00,0x00,", - "£": "0x00,0x00,0x00,0x80,0xF8,0xFC,0x8C,0x8C,0x1C,0x18,0x00,0x00,0x00,0x00,0x18,0x1C,0x1F,0x0B,0x18,0x18,0x18,0x18,0x08,0x00,", - "¤": "0x00,0xF6,0xFE,0x18,0x0C,0x0C,0x0C,0x0C,0x18,0xFE,0xF6,0x00,0x00,0x1B,0x1F,0x06,0x0C,0x0C,0x0C,0x0C,0x06,0x1F,0x1B,0x00,", - "¥": "0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x00,0x0A,0x0A,0x0A,0x3F,0x3F,0x0A,0x0A,0x0A,0x00,0x00,", - "¦": "0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "§": "0x00,0x00,0xDC,0xFE,0x22,0x22,0x22,0x22,0xE6,0xC4,0x00,0x00,0x00,0x00,0x08,0x19,0x11,0x11,0x11,0x11,0x1F,0x0E,0x00,0x00,", - "¨": "0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "©": "0x00,0xF0,0xF8,0x1C,0xCC,0xEC,0x2C,0x6C,0x4C,0x1C,0xF8,0xF0,0x00,0x07,0x0F,0x1C,0x19,0x1B,0x1A,0x1B,0x19,0x1C,0x0F,0x07,", - "«": "0x00,0x80,0xC0,0x60,0x20,0x00,0x80,0xC0,0x60,0x20,0x00,0x00,0x00,0x00,0x01,0x03,0x02,0x00,0x00,0x01,0x03,0x02,0x00,0x00,", - "¬": "0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,", - "®": "0x00,0xF0,0xF8,0x1C,0xEC,0xEC,0xAC,0xEC,0x4C,0x1C,0xF8,0xF0,0x00,0x07,0x0F,0x1C,0x1B,0x1B,0x18,0x1B,0x1B,0x1C,0x0F,0x07,", - "¯": "0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "°": "0x00,0x00,0x00,0x1E,0x3F,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "±": "0x00,0x00,0x00,0xC0,0xC0,0xF0,0xF0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x1B,0x1B,0x18,0x18,0x00,0x00,0x00,", - "²": "0x00,0x00,0x19,0x1D,0x15,0x17,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "³": "0x00,0x00,0x11,0x15,0x15,0x1F,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "´": "0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "µ": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0xFF,0xFF,0x0E,0x0C,0x0C,0x0C,0x06,0x0F,0x0F,0x00,0x00,", - "¶": "0x00,0x38,0x7C,0xC6,0x82,0xFE,0xFE,0x02,0xFE,0xFE,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x3F,0x3F,0x00,0x00,", - "¹": "0x00,0x00,0x12,0x1F,0x1F,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "»": "0x00,0x20,0x60,0xC0,0x80,0x00,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x00,0x02,0x03,0x01,0x00,0x00,0x00,", - "¼": "0x00,0x48,0x7C,0x7C,0x40,0x80,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x06,0x07,0x04,0x1F,0x1F,0x00,", - "½": "0x00,0x48,0x7C,0x7C,0x40,0x80,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00,0x19,0x1D,0x17,0x12,0x00,", - "¾": "0x00,0x44,0x54,0x7C,0x28,0x80,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x06,0x07,0x04,0x1F,0x1F,0x00,", - "¿": "0x00,0x00,0x00,0x80,0xC0,0xFB,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x1F,0x3B,0x31,0x30,0x30,0x30,0x38,0x1E,0x0E,0x00,", - "À": "0x00,0x00,0x00,0x80,0xE1,0x7B,0x7E,0xE4,0x80,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Á": "0x00,0x00,0x00,0x80,0xE4,0x7E,0x7B,0xE1,0x80,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Â": "0x00,0x00,0x00,0x84,0xE6,0x7B,0x7B,0xE6,0x84,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Ã": "0x00,0x00,0x00,0x82,0xE3,0x79,0x7B,0xE2,0x83,0x01,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Ä": "0x00,0x00,0x00,0x83,0xE3,0x78,0x78,0xE3,0x83,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Å": "0x00,0x00,0x00,0x80,0xE2,0x75,0x75,0xE2,0x80,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Æ": "0x00,0x00,0x80,0xF0,0x7C,0x1F,0xFF,0xFF,0xC3,0xC3,0x03,0x00,0x00,0x3C,0x3F,0x07,0x06,0x06,0x3F,0x3F,0x30,0x30,0x30,0x00,", - "Ç": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x1E,0x1C,0x00,0x00,0x01,0x07,0xCE,0xDC,0xF8,0xF8,0x18,0x1C,0x0E,0x06,0x00,", - "È": "0x00,0xF8,0xF8,0x99,0x9B,0x9E,0x9C,0x98,0x98,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "É": "0x00,0xF8,0xF8,0x98,0x98,0x9C,0x9E,0x9B,0x99,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "Ê": "0x00,0xF8,0xF8,0x9C,0x9E,0x9B,0x9B,0x9E,0x9C,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "Ë": "0x00,0xF8,0xF8,0x9B,0x9B,0x98,0x98,0x9B,0x9B,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "Ì": "0x00,0x00,0x00,0x19,0x1B,0xFE,0xFC,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Í": "0x00,0x00,0x00,0x18,0x18,0xFC,0xFE,0x1B,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Î": "0x00,0x00,0x00,0x1C,0x1E,0xFB,0xFB,0x1E,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ï": "0x00,0x00,0x00,0x1B,0x1B,0xF8,0xF8,0x1B,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ð": "0x00,0xC0,0xFF,0xFF,0xC3,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "Ñ": "0x00,0xF8,0xF8,0x72,0xE3,0xC1,0x83,0x02,0x03,0xF9,0xF8,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x03,0x07,0x0E,0x3F,0x3F,0x00,", - "Ò": "0x00,0xE0,0xF0,0x39,0x1B,0x1E,0x1C,0x18,0x38,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Ó": "0x00,0xE0,0xF0,0x38,0x18,0x1C,0x1E,0x1B,0x39,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Ô": "0x00,0xE0,0xF0,0x3C,0x1E,0x1B,0x1B,0x1E,0x3C,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Õ": "0x00,0xE0,0xF0,0x3A,0x1B,0x19,0x1B,0x1A,0x3B,0xF1,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Ö": "0x00,0xE0,0xF0,0x3B,0x1B,0x18,0x18,0x1B,0x3B,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "×": "0x00,0xF0,0xF8,0x1C,0x0C,0x8C,0xEC,0x7C,0x18,0xFC,0xF4,0x00,0x00,0x2F,0x3F,0x18,0x3E,0x37,0x31,0x30,0x38,0x1F,0x0F,0x00,", - "Ù": "0x00,0xF8,0xF8,0x01,0x03,0x06,0x04,0x00,0x00,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "Ú": "0x00,0xF8,0xF8,0x00,0x00,0x04,0x06,0x03,0x01,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "Û": "0x00,0xF8,0xF8,0x04,0x06,0x03,0x03,0x06,0x04,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "Ü": "0x00,0xF8,0xF8,0x03,0x03,0x00,0x00,0x03,0x03,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "Ý": "0x00,0x08,0x18,0x30,0x60,0xC4,0xC6,0x63,0x31,0x18,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "ß": "0x00,0x00,0xC0,0xE0,0x30,0x10,0x10,0x30,0xE0,0xC0,0x00,0x00,0x00,0x00,0xFF,0xFF,0x21,0x21,0x21,0x33,0x3F,0x1E,0x00,0x00,", - "à": "0x00,0x00,0x40,0x60,0x62,0x66,0x6C,0x68,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "á": "0x00,0x00,0x40,0x60,0x68,0x6C,0x66,0x62,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "â": "0x00,0x00,0x40,0x68,0x6C,0x66,0x66,0x6C,0x68,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "ã": "0x00,0x00,0x40,0x68,0x6C,0x64,0x6C,0x68,0x6C,0xE4,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "ä": "0x00,0x00,0x40,0x6C,0x6C,0x60,0x60,0x6C,0x6C,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "å": "0x00,0x00,0x40,0x60,0x64,0x6A,0x6A,0x64,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "æ": "0x00,0x80,0xC0,0x40,0x40,0xC0,0x80,0x40,0x40,0xC0,0x80,0x00,0x00,0x1C,0x3E,0x22,0x22,0x1F,0x3F,0x22,0x22,0x33,0x11,0x00,", - "ç": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0xB8,0xB0,0xF0,0xF0,0x30,0x38,0x18,0x08,0x00,", - "è": "0x00,0x80,0xC0,0xE0,0x62,0x66,0x6C,0x68,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x33,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,", - "é": "0x00,0x80,0xC0,0xE0,0x60,0x68,0x6C,0x66,0x62,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,", - "ê": "0x00,0x80,0xC0,0xE8,0x6C,0x66,0x66,0x6C,0x68,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x33,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,", - "ë": "0x00,0x80,0xC0,0xEC,0x6C,0x60,0x60,0x6C,0x6C,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x33,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,", - "ì": "0x00,0x00,0x00,0x00,0x62,0xE6,0xEC,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "í": "0x00,0x00,0x00,0x00,0x68,0xEC,0xE6,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "î": "0x00,0x00,0x00,0x08,0x6C,0xE6,0xE6,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ï": "0x00,0x00,0x00,0x0C,0x6C,0xE0,0xEC,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ñ": "0x00,0x00,0xE0,0xE8,0x6C,0x64,0x6C,0x68,0xEC,0xC4,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "ò": "0x00,0x80,0xC0,0xE0,0x62,0x66,0x6C,0x68,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "ó": "0x00,0x80,0xC0,0xE0,0x68,0x6C,0x66,0x62,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "ô": "0x00,0x80,0xC0,0xE8,0x6C,0x66,0x66,0x6C,0xE8,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "õ": "0x00,0x80,0xC8,0xEC,0x64,0x6C,0x68,0x6C,0xE4,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "ö": "0x00,0x80,0xC0,0xEC,0x6C,0x60,0x60,0x6C,0xEC,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "÷": "0x00,0x00,0x80,0x80,0x80,0xB0,0xB0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0D,0x0D,0x01,0x01,0x01,0x00,0x00,", - "ø": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xE0,0xC0,0xE0,0xA0,0x00,0x00,0x2F,0x3F,0x18,0x3C,0x36,0x33,0x31,0x38,0x1F,0x0F,0x00,", - "ù": "0x00,0xE0,0xE0,0x00,0x02,0x06,0x0C,0x08,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "ú": "0x00,0xE0,0xE0,0x00,0x08,0x0C,0x06,0x02,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "û": "0x00,0xE0,0xE0,0x08,0x0C,0x06,0x06,0x0C,0x08,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "ü": "0x00,0xE0,0xE0,0x0C,0x0C,0x00,0x00,0x0C,0x0C,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "ý": "0x00,0x00,0x60,0xE0,0x80,0x10,0x18,0x8C,0xE4,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,", - "þ": "0x00,0x00,0x03,0xFF,0xFF,0x1B,0x18,0x18,0xF8,0xF0,0x00,0x00,0x00,0x00,0x30,0x3F,0x3F,0x36,0x06,0x06,0x07,0x03,0x00,0x00,", - "ÿ": "0x00,0x00,0x60,0xEC,0x8C,0x00,0x00,0x8C,0xEC,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,", - "Ѐ": "0x00,0xFC,0xFC,0x8D,0x8F,0x8E,0x8C,0x8C,0x8C,0x0C,0x0C,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "Ё": "0x00,0xFE,0xFE,0xC7,0xC7,0xC6,0xC6,0xC7,0xC7,0x06,0x06,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "Ђ": "0x00,0x03,0xFF,0xFF,0x83,0xC3,0xC3,0xC3,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x00,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Ѓ": "0x00,0xFC,0xFC,0x0C,0x0C,0x0C,0x0E,0x0F,0x0D,0x0C,0x0C,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Є": "0x00,0xF8,0xFC,0xCE,0xC7,0xC3,0xC3,0xC3,0x07,0x0E,0x0C,0x00,0x00,0x07,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "Ѕ": "0x00,0x3C,0x7E,0x67,0xE3,0xC3,0xC3,0xC3,0x87,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x31,0x39,0x1F,0x0F,0x00,", - "І": "0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ї": "0x00,0x00,0x00,0x0D,0x0D,0xFC,0xFC,0x0D,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ј": "0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x0E,0x1E,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Љ": "0x00,0x00,0xFE,0xFF,0x03,0x03,0xFF,0xFF,0xC0,0xC0,0x80,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x3F,0x3F,0x30,0x39,0x1F,0x0F,", - "Њ": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xFF,0xFF,0xC0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x3F,0x3F,0x30,0x39,0x1F,0x0F,", - "Ћ": "0x00,0x03,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x00,0x00,0x00,0x01,0x3F,0x3F,0x00,", - "Ќ": "0x00,0xFF,0xFF,0xC0,0xE2,0xF3,0x39,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,", - "Ѝ": "0x00,0xFF,0xFF,0x00,0x01,0xC3,0xF2,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Ў": "0x00,0x07,0x1F,0x7C,0xF1,0xC1,0xC1,0xF1,0x7C,0x1F,0x07,0x00,0x00,0x00,0x30,0x30,0x3C,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,", - "Џ": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x1F,0x1F,0x18,0x18,0x78,0x78,0x18,0x18,0x1F,0x1F,0x00,", - "А": "0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", - "Б": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x83,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "В": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Г": "0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Ґ": "0x00,0xFC,0xFC,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x0F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Д": "0x00,0x00,0xF8,0xFE,0x0F,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x70,0x7F,0x1F,0x18,0x18,0x18,0x18,0x1F,0x7F,0x70,0x00,", - "Е": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "Ж": "0x00,0x03,0x0F,0xFC,0xE0,0xFF,0xFF,0xE0,0xFC,0x0F,0x03,0x00,0x00,0x38,0x3F,0x07,0x00,0x3F,0x3F,0x00,0x07,0x3F,0x38,0x00,", - "З": "0x0C,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC3,0xC3,0xE7,0x7E,0x3C,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0E,", - "И": "0x00,0xFF,0xFF,0x00,0x00,0xC0,0xF0,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Й": "0x00,0xFF,0xFF,0x00,0x02,0xC3,0xF1,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "К": "0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,", - "Л": "0x00,0x00,0xF0,0xFC,0x1E,0x07,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "М": "0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,", - "Н": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "О": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "П": "0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Р": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,", - "С": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "Т": "0x00,0x03,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "У": "0x00,0x07,0x1F,0x7C,0xF0,0xC0,0xC0,0xF0,0x7C,0x1F,0x07,0x00,0x00,0x00,0x30,0x30,0x3C,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,", - "Ф": "0x00,0xF8,0xFC,0x0E,0x06,0xFF,0xFF,0x06,0x0E,0xFC,0xF8,0x00,0x00,0x03,0x07,0x0E,0x0C,0x3F,0x3F,0x0C,0x0E,0x07,0x03,0x00,", - "Х": "0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x03,0x0F,0x3C,0x30,0x00,", - "Ц": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x1F,0x1F,0x18,0x18,0x18,0x18,0x18,0x1F,0x7F,0x78,0x00,", - "Ч": "0x00,0x7F,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Ш": "0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,", - "Щ": "0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x1F,0x1F,0x18,0x18,0x1F,0x1F,0x18,0x18,0x1F,0x7F,0x70,", - "Ъ": "0x03,0x03,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Ы": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x00,0x3F,0x3F,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,0x3F,0x3F,", - "Ь": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Э": "0x00,0x0C,0x0E,0x07,0xC3,0xC3,0xC3,0xC7,0xCE,0xFC,0xF8,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0F,0x07,0x00,", - "Ю": "0x00,0xFF,0xFF,0xC0,0xFC,0xFE,0x07,0x03,0x07,0xFE,0xFC,0x00,0x00,0x3F,0x3F,0x00,0x0F,0x1F,0x38,0x30,0x38,0x1F,0x0F,0x00,", - "Я": "0x00,0x7C,0xFE,0xC7,0x83,0x83,0x83,0x83,0x83,0xFF,0xFF,0x00,0x00,0x30,0x38,0x1D,0x0F,0x07,0x03,0x01,0x01,0x3F,0x3F,0x00,", - "а": "0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1E,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "б": "0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,", - "в": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x00,0x3F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,", - "г": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "ґ": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x3C,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "д": "0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x00,0x60,0x7F,0x3F,0x30,0x30,0x30,0x30,0x3F,0x7F,0x60,0x00,", - "е": "0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", - "ж": "0x00,0x30,0xF0,0xC0,0x00,0xF0,0xF0,0x00,0xC0,0xF0,0x30,0x00,0x00,0x30,0x3C,0x0F,0x03,0x3F,0x3F,0x03,0x0F,0x3C,0x30,0x00,", - "з": "0x00,0x60,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x18,0x38,0x30,0x33,0x33,0x33,0x33,0x33,0x3F,0x1D,0x00,", - "и": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "й": "0x00,0xF0,0xF0,0x00,0x04,0x08,0x88,0xC4,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "к": "0x00,0xF0,0xF0,0x80,0x80,0xC0,0xE0,0x70,0x30,0x10,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x07,0x0E,0x1C,0x38,0x30,0x20,0x00,", - "л": "0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "м": "0x00,0xF0,0xF0,0xE0,0xC0,0x80,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "н": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,", - "о": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "п": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "р": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,", - "с": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x18,0x08,0x00,", - "т": "0x00,0x30,0x30,0x30,0x30,0xF0,0xF0,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "у": "0x00,0x30,0xF0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xF0,0x30,0x00,0x00,0x60,0xE0,0xC3,0xE7,0x7C,0x3C,0x0F,0x03,0x00,0x00,0x00,", - "ф": "0x00,0x80,0xC0,0x60,0x60,0xF0,0xF0,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x30,0x30,0xFF,0xFF,0x30,0x30,0x1F,0x0F,0x00,", - "х": "0x00,0x30,0x70,0xC0,0x80,0x00,0x00,0x80,0xC0,0x70,0x30,0x00,0x00,0x30,0x38,0x0C,0x07,0x03,0x03,0x07,0x0C,0x38,0x30,0x00,", - "ц": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x3F,0xFF,0xF0,0x00,", - "ч": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,", - "ш": "0x00,0xF0,0xF0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,", - "щ": "0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0xFF,0xE0,", - "ъ": "0x30,0x30,0xF0,0xF0,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "ы": "0x00,0xF0,0xF0,0x80,0x80,0x80,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x31,0x31,0x3B,0x1F,0x0E,0x00,0x3F,0x3F,0x00,", - "ь": "0x00,0xF0,0xF0,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "э": "0x00,0x40,0x60,0x70,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x08,0x18,0x38,0x30,0x33,0x33,0x33,0x3B,0x1F,0x0F,0x00,", - "ю": "0x00,0xF0,0xF0,0x00,0xE0,0xF0,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x3F,0x3F,0x03,0x1F,0x3F,0x30,0x30,0x30,0x3F,0x1F,0x00,", - "я": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x21,0x33,0x3B,0x1E,0x0E,0x06,0x06,0x06,0x3F,0x3F,0x00,", - "ѐ": "0x00,0xE0,0xF0,0x32,0x36,0x36,0x34,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", - "ё": "0x00,0xE0,0xF0,0x34,0x34,0x30,0x30,0x34,0x34,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", - "ђ": "0x00,0x30,0xFC,0xFC,0x30,0xB0,0xB0,0xB0,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x07,0x03,0x01,0x01,0xC1,0xFF,0x3F,0x00,", - "ѓ": "0x00,0xF0,0xF0,0x30,0x30,0x34,0x36,0x32,0x30,0x30,0x30,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "є": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x30,0x38,0x18,0x08,0x00,", - "ѕ": "0x00,0xE0,0xF0,0xB0,0xB0,0x30,0x30,0x30,0x30,0x70,0x60,0x00,0x00,0x18,0x39,0x31,0x33,0x33,0x33,0x37,0x36,0x3E,0x1C,0x00,", - "і": "0x00,0x00,0x00,0x00,0x30,0xF6,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ї": "0x00,0x00,0x00,0x04,0x34,0xF0,0xF4,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ј": "0x00,0x00,0x00,0x00,0x00,0x30,0x30,0xF6,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xE0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00,", - "љ": "0x00,0x00,0xE0,0xF0,0x30,0x30,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x3F,0x3F,0x33,0x33,0x1E,0x0C,", - "њ": "0x00,0xF0,0xF0,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x03,0x3F,0x3F,0x33,0x33,0x1E,0x0C,", - "ћ": "0x00,0x30,0xFC,0xFC,0xB0,0xB0,0xB0,0xB0,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x3F,0x3F,0x00,", - "ќ": "0x00,0xF0,0xF0,0x80,0x88,0xCC,0xE4,0x70,0x30,0x10,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x07,0x0E,0x1C,0x38,0x30,0x20,0x00,", - "ѝ": "0x00,0xF0,0xF0,0x00,0x06,0x0C,0x88,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "ў": "0x00,0x30,0xF0,0xC0,0x04,0x08,0x08,0x04,0xC0,0xF0,0x30,0x00,0x00,0x60,0xE0,0xC3,0xE7,0x7C,0x3C,0x0F,0x03,0x00,0x00,0x00,", - "џ": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0xF0,0xF0,0x30,0x30,0x3F,0x3F,0x00,", - "Ā": "0x00,0x00,0x00,0xE0,0xF9,0x1D,0x1D,0xF9,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", - "ā": "0x00,0x00,0x40,0x60,0x68,0x68,0x68,0x68,0x68,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "Ă": "0x00,0x00,0x00,0xE0,0xF9,0x1A,0x1A,0xF9,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", - "ă": "0x00,0x00,0x40,0x60,0x64,0x68,0x68,0x68,0x64,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "Ą": "0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x67,0xBF,0xB8,0x00,", - "ą": "0x00,0x00,0x40,0x60,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x73,0xBF,0xBF,0x00,", - "Ć": "0x00,0x80,0xE0,0x70,0x38,0x18,0x1A,0x1B,0x39,0x70,0x60,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "ć": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x68,0x6C,0x64,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,", - "Ĉ": "0x00,0x80,0xE0,0x70,0x3A,0x1B,0x19,0x1B,0x3A,0x70,0x60,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "ĉ": "0x00,0x80,0xC0,0xE0,0x68,0x6C,0x64,0x6C,0x68,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,", - "Ċ": "0x00,0x80,0xE0,0x70,0x38,0x18,0x1A,0x18,0x38,0x70,0x60,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "ċ": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x68,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,", - "Č": "0x00,0x80,0xE0,0x70,0x39,0x1B,0x1A,0x1B,0x39,0x70,0x60,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "č": "0x00,0x80,0xC0,0xE0,0x64,0x6C,0x68,0x6C,0x64,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,", - "Ď": "0x00,0xF8,0xF8,0x19,0x1B,0x1A,0x1B,0x39,0x70,0xE0,0x80,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "ď": "0x00,0x80,0xC0,0xE0,0x60,0x60,0xE0,0xFF,0xFF,0x00,0x05,0x03,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x3F,0x3F,0x00,0x00,0x00,", - "Đ": "0xC0,0xFF,0xFF,0xC3,0xC3,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "đ": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xE4,0xC4,0xFF,0xFF,0x04,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,", - "Ē": "0x00,0xFC,0xFC,0x8C,0x8D,0x8D,0x8D,0x8D,0x8C,0x0C,0x0C,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "ē": "0x00,0x80,0xC0,0xE0,0x68,0x68,0x68,0x68,0x68,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,", - "Ĕ": "0x00,0xF8,0xF8,0x98,0x99,0x9A,0x9A,0x99,0x98,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "ĕ": "0x00,0x80,0xC0,0xE0,0x64,0x68,0x68,0x68,0x64,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,", - "Ė": "0x00,0xF8,0xF8,0x98,0x98,0x98,0x9A,0x98,0x98,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "ė": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x68,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,", - "Ę": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x70,0xB0,0xB0,0x00,", - "ę": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x73,0xB3,0xB3,0x13,0x01,0x00,", - "Ě": "0x00,0xF8,0xF8,0x98,0x99,0x9B,0x9A,0x9B,0x99,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "ě": "0x00,0x80,0xC0,0xE0,0x64,0x6C,0x68,0x6C,0x64,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,", - "Ĝ": "0x00,0x80,0xE0,0x70,0x1A,0x1B,0x19,0x1B,0x1A,0x38,0x30,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "ĝ": "0x00,0x80,0xC0,0xE0,0x68,0x6C,0x64,0x6C,0x68,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,", - "Ğ": "0x00,0x80,0xE0,0x70,0x1A,0x19,0x19,0x19,0x1A,0x38,0x30,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "ğ": "0x00,0x80,0xC0,0xE0,0x68,0x64,0x64,0x64,0x68,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,", - "Ġ": "0x00,0x80,0xE0,0x70,0x18,0x18,0x1A,0x18,0x18,0x38,0x30,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "ġ": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x68,0x60,0x60,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,", - "Ģ": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC7,0xC6,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0xB0,0x70,0x30,0x3F,0x3F,0x00,", - "ģ": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x6C,0x6A,0x60,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,", - "Ĥ": "0x00,0xFC,0xFC,0x80,0x82,0x81,0x81,0x82,0x80,0xFC,0xFC,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x3F,0x3F,0x00,", - "ĥ": "0x00,0xFE,0xFE,0xC0,0x62,0x63,0x61,0xE3,0xC2,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,", - "Ħ": "0x02,0xFF,0xFF,0xC2,0xC2,0xC2,0xC2,0xC2,0xC2,0xFF,0xFF,0x02,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "ħ": "0x04,0xFF,0xFF,0xC4,0x64,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,", - "Ĩ": "0x00,0x00,0x00,0x1A,0x19,0xFB,0xFB,0x1A,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ĩ": "0x00,0x00,0x00,0x08,0x64,0xEC,0xE8,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ī": "0x00,0x00,0x00,0x0C,0x0D,0xFD,0xFD,0x0D,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ī": "0x00,0x00,0x00,0x08,0x68,0xE8,0xE8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ĭ": "0x00,0x00,0x00,0x18,0x19,0xFA,0xFA,0x19,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ĭ": "0x00,0x00,0x00,0x00,0x64,0xE8,0xE8,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Į": "0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x7F,0xBF,0xB0,0x30,0x00,0x00,0x00,", - "į": "0x00,0x00,0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x7F,0xBF,0xB0,0x30,0x00,0x00,0x00,", - "İ": "0x00,0x00,0x00,0x18,0x18,0xF8,0xFA,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ı": "0x00,0x00,0x00,0x00,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "IJ": "0x00,0x03,0xFF,0xFF,0x03,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x30,0x3F,0x3F,0x30,0x0C,0x1C,0x30,0x30,0x3F,0x1F,0x00,", - "ij": "0x00,0x00,0x20,0xEC,0xEC,0x00,0x00,0x20,0xEC,0xEC,0x00,0x00,0x00,0x00,0x30,0x3F,0x3F,0x70,0xC0,0xC0,0xFF,0x7F,0x00,0x00,", - "Ĵ": "0x00,0x00,0x00,0x00,0x02,0x03,0x01,0x03,0x02,0xF8,0xF8,0x00,0x00,0x0E,0x1E,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ĵ": "0x00,0x00,0x00,0x00,0x00,0x08,0x6C,0xE4,0xEC,0x08,0x00,0x00,0x00,0x00,0x00,0x60,0xE0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00,", - "Ķ": "0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0xA3,0x67,0x0E,0x1C,0x38,0x30,0x00,", - "ķ": "0x00,0x00,0xFF,0xFF,0x00,0x80,0xC0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0xA7,0x6F,0x1C,0x38,0x30,0x00,0x00,", - "ĸ": "0x00,0x00,0xE0,0xE0,0x00,0x80,0xC0,0xE0,0x60,0x20,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x07,0x0F,0x1C,0x38,0x30,0x00,0x00,", - "Ĺ": "0x00,0xF8,0xFA,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "ĺ": "0x00,0x00,0x00,0x00,0x18,0xFA,0xFB,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ļ": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0xB0,0x70,0x30,0x30,0x30,0x30,0x00,", - "ļ": "0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0xBF,0x7F,0x30,0x30,0x00,0x00,0x00,", - "Ľ": "0x00,0xFF,0xFF,0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "ľ": "0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ŀ": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "ŀ": "0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ł": "0x80,0xFF,0xFF,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "ł": "0x00,0x00,0x00,0x00,0x83,0xFF,0xFF,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ń": "0x00,0xFF,0xFF,0x0E,0x38,0xF2,0xC3,0x01,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x03,0x07,0x1C,0x3F,0x3F,0x00,", - "ń": "0x00,0x00,0xE0,0xE0,0x60,0x68,0x6C,0x64,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Ņ": "0x00,0xFF,0xFF,0x0E,0x38,0xF0,0xC0,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0xA0,0x63,0x07,0x1C,0x3F,0x3F,0x00,", - "ņ": "0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0xA0,0x60,0x00,0x3F,0x3F,0x00,", - "Ň": "0x00,0xFF,0xFF,0x0E,0x38,0xF1,0xC2,0x01,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x03,0x07,0x1C,0x3F,0x3F,0x00,", - "ň": "0x00,0x00,0xE0,0xE0,0x64,0x6C,0x68,0x6C,0xE4,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "ʼn": "0x00,0x0A,0xE6,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Ŋ": "0x00,0x00,0xFF,0xFF,0x06,0x03,0x03,0x03,0x07,0xFE,0xFC,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x20,0x20,0x30,0x1F,0x0F,0x00,", - "ŋ": "0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0xC0,0xC0,0xFF,0x7F,0x00,", - "Ō": "0x00,0xC0,0xF0,0x38,0x1D,0x0D,0x0D,0x1D,0x38,0xF0,0xC0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "ō": "0x00,0x80,0xC0,0xE0,0x68,0x68,0x68,0x68,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Ŏ": "0x00,0x80,0xE0,0x70,0x39,0x1A,0x1A,0x39,0x70,0xE0,0x80,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "ŏ": "0x00,0x80,0xC0,0xE0,0x64,0x68,0x68,0x64,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Ő": "0x00,0x80,0xE0,0x70,0x3A,0x19,0x1A,0x39,0x70,0xE0,0x80,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "ő": "0x00,0x80,0xC0,0xE0,0x68,0x64,0x68,0x64,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Œ": "0xF0,0xFC,0x0E,0x03,0x03,0x07,0xFE,0xFF,0xC3,0xC3,0xC3,0x00,0x03,0x0F,0x1C,0x30,0x30,0x38,0x1F,0x3F,0x30,0x30,0x30,0x00,", - "œ": "0x80,0xC0,0xE0,0x60,0x60,0xE0,0xC0,0x60,0x60,0x60,0x40,0x80,0x0F,0x1F,0x38,0x30,0x30,0x1F,0x1F,0x3B,0x33,0x33,0x1B,0x09,", - "Ŕ": "0x00,0xF8,0xF8,0x98,0x98,0x9A,0x9B,0x99,0xF8,0xF0,0x60,0x00,0x00,0x3F,0x3F,0x01,0x01,0x03,0x07,0x0F,0x1D,0x38,0x30,0x00,", - "ŕ": "0x00,0x00,0xE0,0xE0,0xC0,0x60,0x68,0x6C,0x64,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Ŗ": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0xA3,0x67,0x0F,0x1D,0x38,0x30,0x00,", - "ŗ": "0x00,0x00,0xE0,0xE0,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00,", - "Ř": "0x00,0xF8,0xF8,0x99,0x9B,0x9A,0x9B,0x99,0xF8,0xF0,0x60,0x00,0x00,0x3F,0x3F,0x01,0x01,0x03,0x07,0x0F,0x1D,0x38,0x30,0x00,", - "ř": "0x00,0x00,0xE0,0xE0,0xC4,0x6C,0x68,0x6C,0x64,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Ś": "0x00,0x60,0xF0,0xF8,0x98,0x9A,0x9B,0x99,0x98,0x30,0x20,0x00,0x00,0x0C,0x1C,0x39,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "ś": "0x00,0xC0,0xE0,0x60,0x68,0x6C,0x64,0x60,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,", - "Ŝ": "0x00,0x60,0xF0,0xF8,0x9A,0x9B,0x99,0x9B,0x9A,0x30,0x20,0x00,0x00,0x0C,0x1C,0x39,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "ŝ": "0x00,0xC0,0xE0,0x68,0x6C,0x64,0x6C,0x68,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,", - "Ş": "0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC7,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0xB0,0xF0,0x30,0x39,0x1F,0x0F,0x00,", - "ş": "0x00,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0xB3,0xF3,0x33,0x3F,0x1E,0x00,0x00,0x00,", - "Š": "0x00,0x60,0xF0,0xF8,0x99,0x9B,0x9A,0x9B,0x99,0x30,0x20,0x00,0x00,0x0C,0x1C,0x39,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "š": "0x00,0xC0,0xE0,0x64,0x6C,0x68,0x6C,0x64,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,", - "Ţ": "0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,0xBF,0x60,0x00,0x00,0x00,0x00,", - "ţ": "0x00,0x60,0x60,0xFE,0xFE,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0xB0,0xB0,0xF0,0x30,0x00,0x00,0x00,", - "Ť": "0x00,0x00,0x18,0x19,0x1B,0xFA,0xFA,0x1B,0x19,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "ť": "0x00,0x60,0x60,0xFE,0xFE,0x60,0x65,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x30,0x30,0x30,0x30,0x00,0x00,0x00,", - "Ŧ": "0x00,0x00,0x03,0xC3,0xC3,0xFF,0xFF,0xC3,0xC3,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "ŧ": "0x00,0x30,0x30,0xFE,0xFE,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x1F,0x3F,0x33,0x33,0x30,0x30,0x00,0x00,0x00,", - "Ũ": "0x00,0xF8,0xF8,0x02,0x01,0x03,0x03,0x02,0x01,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ũ": "0x00,0xE0,0xE0,0x08,0x04,0x0C,0x0C,0x08,0x04,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "Ū": "0x00,0xFC,0xFC,0x00,0x01,0x01,0x01,0x01,0x00,0xFC,0xFC,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ū": "0x00,0xE0,0xE0,0x00,0x08,0x08,0x08,0x08,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "Ŭ": "0x00,0xFC,0xFC,0x00,0x01,0x02,0x02,0x01,0x00,0xFC,0xFC,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ŭ": "0x00,0xE0,0xE0,0x00,0x04,0x08,0x08,0x04,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "Ů": "0x00,0xF8,0xF8,0x00,0x06,0x09,0x09,0x06,0x00,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ů": "0x00,0xE0,0xE0,0x00,0x0C,0x12,0x12,0x0C,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "Ű": "0x00,0xF8,0xF8,0x00,0x02,0x01,0x02,0x01,0x00,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ű": "0x00,0xE0,0xE0,0x00,0x08,0x04,0x08,0x04,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "Ų": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x07,0x1F,0x38,0x30,0xF0,0xB0,0xB0,0x38,0x1F,0x07,0x00,", - "ų": "0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0xF0,0xB0,0xB0,0x18,0x3F,0x3F,0x00,", - "Ŵ": "0x00,0xFC,0xFC,0x00,0x02,0x81,0x81,0x02,0x00,0xFC,0xFC,0x00,0x00,0x3F,0x3F,0x1C,0x06,0x03,0x03,0x06,0x1C,0x3F,0x3F,0x00,", - "ŵ": "0x00,0xE0,0xE0,0x00,0x04,0xE8,0xE8,0x04,0x00,0xE0,0xE0,0x00,0x00,0x07,0x1F,0x38,0x1C,0x0F,0x0F,0x1C,0x38,0x1F,0x07,0x00,", - "Ŷ": "0x00,0x02,0x0E,0x3C,0xF2,0xC1,0xC1,0xF2,0x3C,0x0E,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "ŷ": "0x00,0x00,0x60,0xE0,0x88,0x04,0x04,0x88,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,", - "Ÿ": "0x00,0x02,0x0E,0x3C,0xF1,0xC0,0xC0,0xF1,0x3C,0x0E,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "Ź": "0x00,0x18,0x18,0x18,0x18,0x1A,0x9B,0xD9,0xF8,0x78,0x38,0x00,0x00,0x30,0x38,0x3C,0x3E,0x37,0x33,0x31,0x30,0x30,0x30,0x00,", - "ź": "0x00,0x60,0x60,0x60,0x68,0x6C,0xE4,0xE0,0x60,0x20,0x00,0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x30,0x00,0x00,", - "Ż": "0x00,0x18,0x18,0x18,0x18,0x18,0x9A,0xD8,0xF8,0x78,0x38,0x00,0x00,0x30,0x38,0x3C,0x3E,0x37,0x33,0x31,0x30,0x30,0x30,0x00,", - "ż": "0x00,0x60,0x60,0x60,0x60,0x68,0xE0,0xE0,0x60,0x20,0x00,0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x30,0x00,0x00,", - "Ž": "0x00,0x18,0x18,0x18,0x19,0x1B,0x9A,0xDB,0xF9,0x78,0x38,0x00,0x00,0x30,0x38,0x3C,0x3E,0x37,0x33,0x31,0x30,0x30,0x30,0x00,", - "ž": "0x00,0x60,0x60,0x64,0x6C,0x68,0xEC,0xE4,0x60,0x20,0x00,0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x30,0x00,0x00,", - "ſ": "0x00,0x00,0x00,0x00,0xFC,0xFE,0x06,0x06,0x0E,0x0C,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x00,0x00,0x00,0x00,0x00,", + # U+0000..U+007F Basic Latin + " ": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "!": b"\x00\x00\x00\x00\x7C\xFF\xFF\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x33\x00\x00\x00\x00\x00", + '"': b"\x00\x00\x00\x3C\x3C\x00\x00\x3C\x3C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "#": b"\x00\x00\x10\x90\xF0\x7E\x1E\x90\xF0\x7E\x1E\x10\x00\x02\x1E\x1F\x03\x02\x1E\x1F\x03\x02\x00\x00", + "$": b"\x00\x00\x78\xFC\xCC\xFF\xFF\xCC\xCC\x88\x00\x00\x00\x00\x04\x0C\x0C\x3F\x3F\x0C\x0F\x07\x00\x00", + "%": b"\x00\x00\x38\x38\x38\x00\x80\xC0\xE0\x70\x38\x1C\x00\x30\x38\x1C\x0E\x07\x03\x01\x38\x38\x38\x00", + "&": b"\x00\x00\x00\xB8\xFC\xC6\xE2\x3E\x1C\x00\x00\x00\x00\x00\x1F\x3F\x31\x21\x37\x1E\x1C\x36\x22\x00", + "'": b"\x00\x00\x00\x00\x27\x3F\x1F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "(": b"\x00\x00\x00\xF0\xFC\xFE\x07\x01\x01\x00\x00\x00\x00\x00\x00\x03\x0F\x1F\x38\x20\x20\x00\x00\x00", + ")": b"\x00\x00\x00\x01\x01\x07\xFE\xFC\xF0\x00\x00\x00\x00\x00\x00\x20\x20\x38\x1F\x0F\x03\x00\x00\x00", + "*": b"\x00\x00\x98\xB8\xE0\xF8\xF8\xE0\xB8\x98\x00\x00\x00\x00\x0C\x0E\x03\x0F\x0F\x03\x0E\x0C\x00\x00", + "+": b"\x00\x00\x80\x80\x80\xF0\xF0\x80\x80\x80\x00\x00\x00\x00\x01\x01\x01\x0F\x0F\x01\x01\x01\x00\x00", + ",": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xB8\xF8\x78\x00\x00\x00\x00\x00", + "-": b"\x00\x00\x80\x80\x80\x80\x80\x80\x80\x80\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00", + ".": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x38\x38\x38\x00\x00\x00\x00\x00", + "/": b"\x00\x00\x00\x00\x00\x80\xC0\xE0\x70\x38\x1C\x0E\x00\x18\x1C\x0E\x07\x03\x01\x00\x00\x00\x00\x00", + "0": b"\x00\xF8\xFE\x06\x03\x83\xC3\x63\x33\x1E\xFE\xF8\x00\x07\x1F\x1E\x33\x31\x30\x30\x30\x18\x1F\x07", + "1": b"\x00\x00\x00\x0C\x0C\x0E\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x30\x30\x30\x3F\x3F\x30\x30\x30\x00", + "2": b"\x00\x1C\x1E\x07\x03\x03\x83\xC3\xE3\x77\x3E\x1C\x00\x30\x38\x3C\x3E\x37\x33\x31\x30\x30\x30\x30", + "3": b"\x00\x0C\x0E\x07\xC3\xC3\xC3\xC3\xC3\xE7\x7E\x3C\x00\x0C\x1C\x38\x30\x30\x30\x30\x30\x39\x1F\x0E", + "4": b"\x00\xC0\xE0\x70\x38\x1C\x0E\x07\xFF\xFF\x00\x00\x00\x03\x03\x03\x03\x03\x03\x03\x3F\x3F\x03\x03", + "5": b"\x00\x3F\x7F\x63\x63\x63\x63\x63\x63\xE3\xC3\x83\x00\x0C\x1C\x38\x30\x30\x30\x30\x30\x38\x1F\x0F", + "6": b"\x00\xC0\xF0\xF8\xDC\xCE\xC7\xC3\xC3\xC3\x80\x00\x00\x0F\x1F\x39\x30\x30\x30\x30\x30\x39\x1F\x0F", + "7": b"\x00\x03\x03\x03\x03\x03\x03\xC3\xF3\x3F\x0F\x03\x00\x00\x00\x00\x30\x3C\x0F\x03\x00\x00\x00\x00", + "8": b"\x00\x00\xBC\xFE\xE7\xC3\xC3\xC3\xE7\xFE\xBC\x00\x00\x0F\x1F\x39\x30\x30\x30\x30\x30\x39\x1F\x0F", + "9": b"\x00\x3C\x7E\xE7\xC3\xC3\xC3\xC3\xC3\xE7\xFE\xFC\x00\x00\x00\x30\x30\x30\x38\x1C\x0E\x07\x03\x00", + ":": b"\x00\x00\x00\x00\x70\x70\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1C\x1C\x1C\x00\x00\x00\x00\x00", + ";": b"\x00\x00\x00\x00\x70\x70\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9C\xFC\x7C\x00\x00\x00\x00\x00", + "<": b"\x00\x00\xC0\xE0\xF0\x38\x1C\x0E\x07\x03\x00\x00\x00\x00\x00\x01\x03\x07\x0E\x1C\x38\x30\x00\x00", + "=": b"\x00\x00\x60\x60\x60\x60\x60\x60\x60\x60\x60\x00\x00\x00\x06\x06\x06\x06\x06\x06\x06\x06\x06\x00", + ">": b"\x00\x00\x03\x07\x0E\x1C\x38\xF0\xE0\xC0\x00\x00\x00\x00\x30\x38\x1C\x0E\x07\x03\x01\x00\x00\x00", + "?": b"\x00\x1C\x1E\x07\x03\x83\xC3\xE3\x77\x3E\x1C\x00\x00\x00\x00\x00\x00\x37\x37\x00\x00\x00\x00\x00", + "@": b"\x00\xF8\xFE\x07\xF3\xFB\x1B\xFB\xFB\x07\xFE\xF8\x00\x0F\x1F\x18\x33\x37\x36\x37\x37\x36\x03\x01", + "A": b"\x00\x00\x00\xE0\xFC\x1F\x1F\xFC\xE0\x00\x00\x00\x00\x38\x3F\x07\x06\x06\x06\x06\x07\x3F\x38\x00", + "B": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xE7\xFE\xBC\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x39\x1F\x0F\x00", + "C": b"\x00\xF0\xFC\x0E\x07\x03\x03\x03\x07\x0E\x0C\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "D": b"\x00\xFF\xFF\x03\x03\x03\x03\x07\x0E\xFC\xF0\x00\x00\x3F\x3F\x30\x30\x30\x30\x38\x1C\x0F\x03\x00", + "E": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xC3\xC3\x03\x03\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "F": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xC3\xC3\x03\x03\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "G": b"\x00\xF0\xFC\x0E\x07\x03\xC3\xC3\xC3\xC7\xC6\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x30\x3F\x3F\x00", + "H": b"\x00\xFF\xFF\xC0\xC0\xC0\xC0\xC0\xC0\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "I": b"\x00\x00\x00\x03\x03\xFF\xFF\x03\x03\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "J": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x0E\x1E\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "K": b"\x00\xFF\xFF\xC0\xE0\xF0\x38\x1C\x0E\x07\x03\x00\x00\x3F\x3F\x00\x01\x03\x07\x0E\x1C\x38\x30\x00", + "L": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "M": b"\x00\xFF\xFF\x1E\x78\xE0\xE0\x78\x1E\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x01\x01\x00\x00\x3F\x3F\x00", + "N": b"\x00\xFF\xFF\x0E\x38\xF0\xC0\x00\x00\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x03\x07\x1C\x3F\x3F\x00", + "O": b"\x00\xF0\xFC\x0E\x07\x03\x03\x07\x0E\xFC\xF0\x00\x00\x03\x0F\x1C\x38\x30\x30\x38\x1C\x0F\x03\x00", + "P": b"\x00\xFF\xFF\x83\x83\x83\x83\x83\xC7\xFE\x7C\x00\x00\x3F\x3F\x01\x01\x01\x01\x01\x01\x00\x00\x00", + "Q": b"\x00\xF0\xFC\x0E\x07\x03\x03\x07\x0E\xFC\xF0\x00\x00\x03\x0F\x1C\x38\x30\x36\x3E\x1C\x3F\x33\x00", + "R": b"\x00\xFF\xFF\x83\x83\x83\x83\x83\xC7\xFE\x7C\x00\x00\x3F\x3F\x01\x01\x03\x07\x0F\x1D\x38\x30\x00", + "S": b"\x00\x3C\x7E\xE7\xC3\xC3\xC3\xC3\xC7\x8E\x0C\x00\x00\x0C\x1C\x38\x30\x30\x30\x30\x39\x1F\x0F\x00", + "T": b"\x00\x00\x03\x03\x03\xFF\xFF\x03\x03\x03\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "U": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "V": b"\x00\x07\x3F\xF8\xC0\x00\x00\xC0\xF8\x3F\x07\x00\x00\x00\x00\x01\x0F\x3E\x3E\x0F\x01\x00\x00\x00", + "W": b"\x00\xFF\xFF\x00\x00\x80\x80\x00\x00\xFF\xFF\x00\x00\x3F\x3F\x1C\x06\x03\x03\x06\x1C\x3F\x3F\x00", + "X": b"\x00\x03\x0F\x1C\x30\xE0\xE0\x30\x1C\x0F\x03\x00\x00\x30\x3C\x0E\x03\x01\x01\x03\x0E\x3C\x30\x00", + "Y": b"\x00\x03\x0F\x3C\xF0\xC0\xC0\xF0\x3C\x0F\x03\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "Z": b"\x00\x03\x03\x03\x03\xC3\xE3\x33\x1F\x0F\x03\x00\x00\x30\x3C\x3E\x33\x31\x30\x30\x30\x30\x30\x00", + "[": b"\x00\x00\x00\xFF\xFF\x03\x03\x03\x03\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x00\x00\x00", + "\\": b"\x00\x0E\x1C\x38\x70\xE0\xC0\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x07\x0E\x1C\x18", + "]": b"\x00\x00\x00\x03\x03\x03\x03\xFF\xFF\x00\x00\x00\x00\x00\x00\x30\x30\x30\x30\x3F\x3F\x00\x00\x00", + "^": b"\x00\x60\x70\x38\x1C\x0E\x07\x0E\x1C\x38\x70\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "_": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0", + "`": b"\x00\x00\x00\x00\x00\x3E\x7E\x4E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "a": b"\x00\x00\x40\x60\x60\x60\x60\x60\x60\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "b": b"\x00\xFF\xFF\xC0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x38\x1F\x0F\x00", + "c": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\x60\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x18\x08\x00", + "d": b"\x00\x80\xC0\xE0\x60\x60\x60\xE0\xC0\xFF\xFF\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x3F\x3F\x00", + "e": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\x60\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x01\x00", + "f": b"\x00\xC0\xC0\xFC\xFE\xC7\xC3\xC3\x03\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00", + "g": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\x60\xE0\xE0\x00\x00\x03\xC7\xCE\xCC\xCC\xCC\xCC\xE6\x7F\x3F\x00", + "h": b"\x00\xFF\xFF\xC0\x60\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00\x00", + "i": b"\x00\x00\x00\x00\x60\xEC\xEC\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "j": b"\x00\x00\x00\x00\x00\x00\x60\xEC\xEC\x00\x00\x00\x00\x00\x00\x60\xE0\xC0\xC0\xFF\x7F\x00\x00\x00", + "k": b"\x00\x00\xFF\xFF\x00\x80\xC0\xE0\x60\x00\x00\x00\x00\x00\x3F\x3F\x03\x07\x0F\x1C\x38\x30\x00\x00", + "l": b"\x00\x00\x00\x00\x03\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "m": b"\x00\xE0\xC0\xE0\xE0\xC0\xC0\xE0\xE0\xC0\x80\x00\x00\x3F\x3F\x00\x00\x3F\x3F\x00\x00\x3F\x3F\x00", + "n": b"\x00\x00\xE0\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "o": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "p": b"\x00\xE0\xE0\x60\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\xFF\xFF\x0C\x18\x18\x18\x18\x1C\x0F\x07\x00", + "q": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\x60\xE0\xE0\x00\x00\x07\x0F\x1C\x18\x18\x18\x18\x0C\xFF\xFF\x00", + "r": b"\x00\x00\xE0\xE0\xC0\x60\x60\x60\x60\xE0\xC0\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00", + "s": b"\x00\xC0\xE0\x60\x60\x60\x60\x60\x40\x00\x00\x00\x00\x11\x33\x33\x33\x33\x33\x3F\x1E\x00\x00\x00", + "t": b"\x00\x60\x60\xFE\xFE\x60\x60\x60\x00\x00\x00\x00\x00\x00\x00\x1F\x3F\x30\x30\x30\x30\x00\x00\x00", + "u": b"\x00\xE0\xE0\x00\x00\x00\x00\x00\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "v": b"\x00\x60\xE0\x80\x00\x00\x00\x00\x80\xE0\x60\x00\x00\x00\x01\x07\x1E\x38\x38\x1E\x07\x01\x00\x00", + "w": b"\x00\xE0\xE0\x00\x00\xE0\xE0\x00\x00\xE0\xE0\x00\x00\x07\x1F\x38\x1C\x0F\x0F\x1C\x38\x1F\x07\x00", + "x": b"\x00\x60\xE0\xC0\x80\x00\x80\xC0\xE0\x60\x00\x00\x00\x30\x38\x1D\x0F\x07\x0F\x1D\x38\x30\x00\x00", + "y": b"\x00\x00\x60\xE0\x80\x00\x00\x80\xE0\x60\x00\x00\x00\x00\x00\x81\xE7\x7E\x1E\x07\x01\x00\x00\x00", + "z": b"\x00\x60\x60\x60\x60\x60\xE0\xE0\x60\x20\x00\x00\x00\x30\x38\x3C\x36\x33\x31\x30\x30\x30\x00\x00", + "{": b"\x00\x00\x80\xC0\xFC\x7E\x07\x03\x03\x03\x00\x00\x00\x00\x00\x01\x1F\x3F\x70\x60\x60\x60\x00\x00", + "|": b"\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "}": b"\x00\x00\x03\x03\x03\x07\x7E\xFC\xC0\x80\x00\x00\x00\x00\x60\x60\x60\x70\x3F\x1F\x01\x00\x00\x00", + "~": b"\x00\x10\x18\x0C\x04\x0C\x18\x10\x18\x0C\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", } return font -def get_small_font_map(): +def get_font_map_latin_extended() -> Dict[str, bytes]: font = { - " ": "0x00, 0x00, 0x00, 0x00, 0x00, 0x00,", - "!": "0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,", - '"': "0x00, 0x07, 0x00, 0x07, 0x00, 0x00,", - "#": "0x14, 0x7f, 0x14, 0x7f, 0x14, 0x00,", - "$": "0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x00,", - "%": "0x23, 0x13, 0x08, 0x64, 0x62, 0x00,", - "&": "0x36, 0x49, 0x56, 0x20, 0x58, 0x00,", - "'": "0x00, 0x05, 0x03, 0x00, 0x00, 0x00,", - "(": "0x00, 0x1c, 0x22, 0x41, 0x00, 0x00,", - ")": "0x00, 0x41, 0x22, 0x1c, 0x00, 0x00,", - "*": "0x14, 0x08, 0x3e, 0x08, 0x14, 0x00,", - "+": "0x08, 0x08, 0x3e, 0x08, 0x08, 0x00,", - ",": "0x00, 0x50, 0x30, 0x00, 0x00, 0x00,", - "-": "0x08, 0x08, 0x08, 0x08, 0x08, 0x00,", - ".": "0x00, 0x60, 0x60, 0x00, 0x00, 0x00,", - "/": "0x20, 0x10, 0x08, 0x04, 0x02, 0x00,", - "0": "0x3e, 0x51, 0x49, 0x45, 0x3e, 0x00,", - "1": "0x00, 0x42, 0x7f, 0x40, 0x00, 0x00,", - "2": "0x42, 0x61, 0x51, 0x49, 0x46, 0x00,", - "3": "0x21, 0x41, 0x45, 0x4b, 0x31, 0x00,", - "4": "0x18, 0x14, 0x12, 0x7f, 0x10, 0x00,", - "5": "0x27, 0x45, 0x45, 0x45, 0x39, 0x00,", - "6": "0x3c, 0x4a, 0x49, 0x49, 0x30, 0x00,", - "7": "0x01, 0x71, 0x09, 0x05, 0x03, 0x00,", - "8": "0x36, 0x49, 0x49, 0x49, 0x36, 0x00,", - "9": "0x06, 0x49, 0x49, 0x29, 0x1e, 0x00,", - ":": "0x00, 0x36, 0x36, 0x00, 0x00, 0x00,", - ";": "0x00, 0x56, 0x36, 0x00, 0x00, 0x00,", - "<": "0x08, 0x14, 0x22, 0x41, 0x00, 0x00,", - "=": "0x14, 0x14, 0x14, 0x14, 0x14, 0x00,", - ">": "0x00, 0x41, 0x22, 0x14, 0x08, 0x00,", - "?": "0x02, 0x01, 0x51, 0x09, 0x06, 0x00,", - "@": "0x32, 0x49, 0x79, 0x41, 0x3e, 0x00,", - "A": "0x7e, 0x09, 0x09, 0x09, 0x7e, 0x00,", - "B": "0x7f, 0x49, 0x49, 0x49, 0x36, 0x00,", - "C": "0x3e, 0x41, 0x41, 0x41, 0x22, 0x00,", - "D": "0x7f, 0x41, 0x41, 0x22, 0x1c, 0x00,", - "E": "0x7f, 0x49, 0x49, 0x49, 0x41, 0x00,", - "F": "0x7f, 0x09, 0x09, 0x09, 0x01, 0x00,", - "G": "0x3e, 0x41, 0x41, 0x49, 0x7a, 0x00,", - "H": "0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00,", - "I": "0x00, 0x41, 0x7f, 0x41, 0x00, 0x00,", - "J": "0x20, 0x40, 0x41, 0x3f, 0x01, 0x00,", - "K": "0x7f, 0x08, 0x14, 0x22, 0x41, 0x00,", - "L": "0x7f, 0x40, 0x40, 0x40, 0x40, 0x00,", - "M": "0x7f, 0x02, 0x0c, 0x02, 0x7f, 0x00,", - "N": "0x7f, 0x04, 0x08, 0x10, 0x7f, 0x00,", - "O": "0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00,", - "P": "0x7f, 0x09, 0x09, 0x09, 0x06, 0x00,", - "Q": "0x3e, 0x41, 0x51, 0x21, 0x5e, 0x00,", - "R": "0x7f, 0x09, 0x19, 0x29, 0x46, 0x00,", - "S": "0x26, 0x49, 0x49, 0x49, 0x32, 0x00,", - "T": "0x01, 0x01, 0x7f, 0x01, 0x01, 0x00,", - "U": "0x3f, 0x40, 0x40, 0x40, 0x3f, 0x00,", - "V": "0x1f, 0x20, 0x40, 0x20, 0x1f, 0x00,", - "W": "0x3f, 0x40, 0x38, 0x40, 0x3f, 0x00,", - "X": "0x63, 0x14, 0x08, 0x14, 0x63, 0x00,", - "Y": "0x07, 0x08, 0x70, 0x08, 0x07, 0x00,", - "Z": "0x61, 0x51, 0x49, 0x45, 0x43, 0x00,", - "[": "0x00, 0x7f, 0x41, 0x41, 0x00, 0x00,", - "\\": "0x02, 0x04, 0x08, 0x10, 0x20, 0x00,", - "]": "0x00, 0x41, 0x41, 0x7f, 0x00, 0x00,", - "^": "0x04, 0x02, 0x01, 0x02, 0x04, 0x00,", - "_": "0x40, 0x40, 0x40, 0x40, 0x40, 0x00,", - "`": "0x00, 0x03, 0x05, 0x00, 0x00, 0x00,", - "a": "0x20, 0x54, 0x54, 0x54, 0x78, 0x00,", - "b": "0x7f, 0x48, 0x44, 0x44, 0x38, 0x00,", - "c": "0x38, 0x44, 0x44, 0x44, 0x20, 0x00,", - "d": "0x38, 0x44, 0x44, 0x48, 0x7f, 0x00,", - "e": "0x38, 0x54, 0x54, 0x54, 0x18, 0x00,", - "f": "0x00, 0x04, 0x7e, 0x05, 0x01, 0x00,", - "g": "0x08, 0x54, 0x54, 0x54, 0x3c, 0x00,", - "h": "0x7f, 0x08, 0x04, 0x04, 0x78, 0x00,", - "i": "0x00, 0x44, 0x7d, 0x40, 0x00, 0x00,", - "j": "0x20, 0x40, 0x44, 0x3d, 0x00, 0x00,", - "k": "0x00, 0x7f, 0x10, 0x28, 0x44, 0x00,", - "l": "0x00, 0x41, 0x7f, 0x40, 0x00, 0x00,", - "m": "0x7c, 0x04, 0x78, 0x04, 0x78, 0x00,", - "n": "0x7c, 0x08, 0x04, 0x04, 0x78, 0x00,", - "o": "0x38, 0x44, 0x44, 0x44, 0x38, 0x00,", - "p": "0x7c, 0x14, 0x14, 0x14, 0x08, 0x00,", - "q": "0x08, 0x14, 0x14, 0x14, 0x7c, 0x00,", - "r": "0x7c, 0x08, 0x04, 0x04, 0x08, 0x00,", - "s": "0x48, 0x54, 0x54, 0x54, 0x24, 0x00,", - "t": "0x04, 0x3e, 0x44, 0x40, 0x20, 0x00,", - "u": "0x3c, 0x40, 0x40, 0x20, 0x7c, 0x00,", - "v": "0x0c, 0x30, 0x40, 0x30, 0x0c, 0x00,", - "w": "0x3c, 0x40, 0x30, 0x40, 0x3c, 0x00,", - "x": "0x44, 0x24, 0x38, 0x48, 0x44, 0x00,", - "y": "0x44, 0x48, 0x30, 0x10, 0x0c, 0x00,", - "z": "0x44, 0x64, 0x54, 0x4c, 0x44, 0x00,", - "{": "0x08, 0x36, 0x41, 0x00, 0x00, 0x00,", - "|": "0x00, 0x00, 0x77, 0x00, 0x00, 0x00,", - "}": "0x00, 0x00, 0x41, 0x36, 0x08, 0x00,", - "~": "0x02, 0x01, 0x02, 0x04, 0x02, 0x00,", - "¡": "0x00, 0x00, 0x79, 0x00, 0x00, 0x00,", - "¢": "0x1c, 0x22, 0x7f, 0x22, 0x10, 0x00,", - "£": "0x50, 0x7e, 0x51, 0x41, 0x42, 0x00,", - "¤": "0x22, 0x1c, 0x14, 0x1c, 0x22, 0x00,", - "¥": "0x15, 0x16, 0x7c, 0x16, 0x15, 0x00,", - "¦": "0x00, 0x00, 0x77, 0x00, 0x00, 0x00,", - "§": "0x4a, 0x55, 0x55, 0x55, 0x29, 0x00,", - "¨": "0x00, 0x01, 0x00, 0x01, 0x00, 0x00,", - "©": "0x00, 0x18, 0x24, 0x24, 0x00, 0x00,", - "«": "0x08, 0x14, 0x00, 0x08, 0x14, 0x00,", - "¬": "0x08, 0x08, 0x08, 0x08, 0x38, 0x00,", - "­": "0x08, 0x08, 0x08, 0x08, 0x08, 0x00,", - "¯": "0x00, 0x01, 0x01, 0x01, 0x00, 0x00,", - "°": "0x00, 0x00, 0x07, 0x05, 0x07, 0x00,", - "±": "0x44, 0x44, 0x5f, 0x44, 0x44, 0x00,", - "²": "0x1d, 0x15, 0x17, 0x00, 0x00, 0x00,", - "³": "0x15, 0x15, 0x1f, 0x00, 0x00, 0x00,", - "´": "0x00, 0x04, 0x02, 0x01, 0x00, 0x00,", - "µ": "0x7c, 0x10, 0x10, 0x0c, 0x10, 0x00,", - "¶": "0x02, 0x07, 0x7f, 0x01, 0x7f, 0x00,", - "·": "0x00, 0x00, 0x08, 0x00, 0x00, 0x00,", - "¸": "0x00, 0x40, 0x60, 0x00, 0x00, 0x00,", - "¹": "0x12, 0x1f, 0x10, 0x00, 0x00, 0x00,", - "º": "0x07, 0x05, 0x07, 0x00, 0x00, 0x00,", - "»": "0x14, 0x08, 0x00, 0x14, 0x08, 0x00,", - "¼": "0x21, 0x17, 0x38, 0x24, 0x72, 0x00,", - "½": "0x21, 0x17, 0x78, 0x54, 0x5e, 0x00,", - "¿": "0x30, 0x48, 0x45, 0x40, 0x20, 0x00,", - "À": "0x78, 0x15, 0x16, 0x14, 0x78, 0x00,", - "Á": "0x78, 0x14, 0x16, 0x15, 0x78, 0x00,", - "Â": "0x78, 0x16, 0x15, 0x16, 0x78, 0x00,", - "Ã": "0x7a, 0x29, 0x2a, 0x79, 0x00, 0x00,", - "Ä": "0x78, 0x15, 0x14, 0x15, 0x78, 0x00,", - "Å": "0x78, 0x14, 0x15, 0x14, 0x78, 0x00,", - "Æ": "0x7e, 0x09, 0x7f, 0x49, 0x49, 0x00,", - "Ç": "0x0e, 0x51, 0x71, 0x11, 0x08, 0x00,", - "È": "0x7c, 0x55, 0x56, 0x44, 0x44, 0x00,", - "É": "0x7c, 0x54, 0x56, 0x45, 0x44, 0x00,", - "Ê": "0x7c, 0x56, 0x55, 0x46, 0x44, 0x00,", - "Ë": "0x7c, 0x55, 0x54, 0x45, 0x44, 0x00,", - "Ì": "0x00, 0x49, 0x7a, 0x48, 0x00, 0x00,", - "Í": "0x00, 0x48, 0x7a, 0x49, 0x00, 0x00,", - "Î": "0x00, 0x4a, 0x79, 0x4a, 0x00, 0x00,", - "Ï": "0x44, 0x45, 0x7c, 0x45, 0x44, 0x00,", - "Ð": "0x08, 0x7f, 0x49, 0x22, 0x1c, 0x00,", - "Ñ": "0x7a, 0x11, 0x22, 0x79, 0x00, 0x00,", - "Ò": "0x38, 0x45, 0x46, 0x44, 0x38, 0x00,", - "Ó": "0x38, 0x44, 0x46, 0x45, 0x38, 0x00,", - "Ô": "0x38, 0x46, 0x45, 0x46, 0x38, 0x00,", - "Õ": "0x32, 0x49, 0x4a, 0x31, 0x00, 0x00,", - "Ö": "0x38, 0x45, 0x44, 0x45, 0x38, 0x00,", - "ő": "0x38, 0x45, 0x44, 0x45, 0x38, 0x00,", - "×": "0x22, 0x14, 0x08, 0x14, 0x22, 0x00,", - "Ø": "0x58, 0x24, 0x54, 0x48, 0x34, 0x00,", - "Ù": "0x38, 0x41, 0x42, 0x40, 0x38, 0x00,", - "Ú": "0x38, 0x40, 0x42, 0x41, 0x38, 0x00,", - "Û": "0x38, 0x42, 0x41, 0x42, 0x38, 0x00,", - "Ü": "0x3c, 0x41, 0x40, 0x41, 0x3c, 0x00,", - "Ý": "0x04, 0x08, 0x72, 0x09, 0x04, 0x00,", - "Þ": "0x7f, 0x22, 0x22, 0x22, 0x1c, 0x00,", - "ß": "0x7e, 0x11, 0x25, 0x25, 0x1a, 0x00,", - "à": "0x20, 0x55, 0x56, 0x54, 0x78, 0x00,", - "á": "0x20, 0x54, 0x56, 0x55, 0x78, 0x00,", - "â": "0x20, 0x56, 0x55, 0x56, 0x78, 0x00,", - "ã": "0x22, 0x55, 0x56, 0x55, 0x78, 0x00,", - "ä": "0x20, 0x55, 0x54, 0x55, 0x78, 0x00,", - "å": "0x20, 0x54, 0x55, 0x54, 0x78, 0x00,", - "æ": "0x24, 0x54, 0x7c, 0x54, 0x48, 0x00,", - "ç": "0x1c, 0x22, 0x62, 0x22, 0x10, 0x00,", - "è": "0x38, 0x55, 0x56, 0x54, 0x08, 0x00,", - "é": "0x38, 0x54, 0x56, 0x55, 0x08, 0x00,", - "ê": "0x38, 0x56, 0x55, 0x56, 0x08, 0x00,", - "ë": "0x38, 0x55, 0x54, 0x55, 0x08, 0x00,", - "ì": "0x00, 0x45, 0x7e, 0x40, 0x00, 0x00,", - "í": "0x00, 0x44, 0x7e, 0x41, 0x00, 0x00,", - "î": "0x00, 0x46, 0x7d, 0x42, 0x00, 0x00,", - "ï": "0x00, 0x45, 0x7c, 0x41, 0x00, 0x00,", - "ñ": "0x78, 0x12, 0x09, 0x0a, 0x71, 0x00,", - "ò": "0x38, 0x45, 0x46, 0x44, 0x38, 0x00,", - "ó": "0x38, 0x44, 0x46, 0x45, 0x38, 0x00,", - "ô": "0x38, 0x46, 0x45, 0x46, 0x38, 0x00,", - "õ": "0x32, 0x49, 0x4a, 0x31, 0x00, 0x00,", - "ö": "0x38, 0x45, 0x44, 0x45, 0x38, 0x00,", - "÷": "0x08, 0x08, 0x2a, 0x08, 0x08, 0x00,", - "ø": "0x58, 0x24, 0x54, 0x48, 0x34, 0x00,", - "ù": "0x3c, 0x41, 0x42, 0x20, 0x7c, 0x00,", - "ú": "0x3c, 0x40, 0x42, 0x21, 0x7c, 0x00,", - "û": "0x3c, 0x42, 0x41, 0x22, 0x7c, 0x00,", - "ü": "0x3c, 0x41, 0x40, 0x21, 0x5c, 0x00,", - "ű": "0x3c, 0x41, 0x40, 0x21, 0x5c, 0x00,", - "ų": "0x3C, 0x40, 0x40, 0x20, 0xDC, 0x80,", - "ý": "0x44, 0x48, 0x32, 0x11, 0x0c, 0x00,", - "þ": "0x7c, 0x28, 0x28, 0x10, 0x00, 0x00,", - "ÿ": "0x44, 0x49, 0x30, 0x11, 0x0c, 0x00,", - "Ѐ": "0x7c, 0x55, 0x56, 0x44, 0x44, 0x00,", - "Ё": "0x7c, 0x55, 0x54, 0x45, 0x44, 0x00,", - "Ђ": "0x01, 0x7f, 0x09, 0x49, 0x31, 0x00,", - "Ѓ": "0x7c, 0x04, 0x06, 0x05, 0x04, 0x00,", - "Є": "0x3e, 0x49, 0x49, 0x41, 0x00, 0x00,", - "Ѕ": "0x06, 0x49, 0x49, 0x49, 0x30, 0x00,", - "І": "0x41, 0x41, 0x7f, 0x41, 0x41, 0x00,", - "Ї": "0x44, 0x45, 0x7c, 0x45, 0x44, 0x00,", - "Ј": "0x20, 0x40, 0x41, 0x3f, 0x01, 0x00,", - "Љ": "0x7f, 0x01, 0x7f, 0x48, 0x30, 0x00,", - "Њ": "0x7f, 0x08, 0x7f, 0x48, 0x30, 0x00,", - "Ћ": "0x01, 0x01, 0x7f, 0x09, 0x71, 0x00,", - "Ќ": "0x7c, 0x12, 0x29, 0x44, 0x00, 0x00,", - "Ѝ": "0x7c, 0x21, 0x12, 0x08, 0x7c, 0x00,", - "Ў": "0x44, 0x49, 0x32, 0x09, 0x04, 0x00,", - "Џ": "0x3f, 0x20, 0x60, 0x20, 0x3f, 0x00,", - "А": "0x7e, 0x09, 0x09, 0x09, 0x7e, 0x00,", - "Б": "0x7f, 0x49, 0x49, 0x49, 0x31, 0x00,", - "В": "0x7f, 0x49, 0x49, 0x49, 0x36, 0x00,", - "Г": "0x7f, 0x01, 0x01, 0x01, 0x01, 0x00,", - "Ґ": "0x7E, 0x02, 0x02, 0x02, 0x03, 0x00,", - "Д": "0x60, 0x3f, 0x21, 0x3f, 0x60, 0x00,", - "Е": "0x7f, 0x49, 0x49, 0x49, 0x41, 0x00,", - "Ж": "0x77, 0x08, 0x7f, 0x08, 0x77, 0x00,", - "З": "0x00, 0x41, 0x49, 0x49, 0x36, 0x00,", - "И": "0x7f, 0x10, 0x08, 0x04, 0x7f, 0x00,", - "Й": "0x7c, 0x21, 0x12, 0x09, 0x7c, 0x00,", - "К": "0x7f, 0x08, 0x14, 0x22, 0x41, 0x00,", - "Л": "0x40, 0x3f, 0x01, 0x01, 0x7f, 0x00,", - "М": "0x7f, 0x02, 0x04, 0x02, 0x7f, 0x00,", - "Н": "0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00,", - "О": "0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00,", - "П": "0x7f, 0x01, 0x01, 0x01, 0x7f, 0x00,", - "Р": "0x7f, 0x09, 0x09, 0x09, 0x06, 0x00,", - "С": "0x3e, 0x41, 0x41, 0x41, 0x22, 0x00,", - "Т": "0x01, 0x01, 0x7f, 0x01, 0x01, 0x00,", - "У": "0x47, 0x48, 0x30, 0x08, 0x07, 0x00,", - "Ф": "0x0c, 0x12, 0x7f, 0x12, 0x0c, 0x00,", - "Х": "0x63, 0x14, 0x08, 0x14, 0x63, 0x00,", - "Ц": "0x3f, 0x20, 0x20, 0x3f, 0x60, 0x00,", - "Ч": "0x07, 0x08, 0x08, 0x08, 0x7f, 0x00,", - "Ш": "0x7F, 0x40, 0x7F, 0x40, 0x7F, 0x00,", - "Щ": "0x7F, 0x40, 0x7F, 0x40, 0x7F, 0xC0,", - "Ъ": "0x01, 0x7f, 0x48, 0x48, 0x30, 0x00,", - "Ы": "0x7f, 0x48, 0x30, 0x00, 0x7f, 0x00,", - "Ь": "0x00, 0x7f, 0x48, 0x48, 0x30, 0x00,", - "Э": "0x22, 0x49, 0x49, 0x2a, 0x1c, 0x00,", - "Ю": "0x7f, 0x08, 0x3e, 0x41, 0x3e, 0x00,", - "Я": "0x46, 0x29, 0x19, 0x09, 0x7f, 0x00,", - "а": "0x20, 0x54, 0x54, 0x54, 0x78, 0x00,", - "б": "0x3c, 0x4a, 0x4a, 0x4a, 0x30, 0x00,", - "в": "0x7c, 0x54, 0x54, 0x54, 0x28, 0x00,", - "г": "0x7c, 0x04, 0x04, 0x04, 0x04, 0x00,", - "ґ": "0x7C, 0x04, 0x04, 0x04, 0x06, 0x00,", - "д": "0x40, 0x3c, 0x24, 0x3c, 0x60, 0x00,", - "е": "0x38, 0x54, 0x54, 0x54, 0x18, 0x00,", - "ж": "0x6c, 0x10, 0x7c, 0x10, 0x6c, 0x00,", - "з": "0x28, 0x44, 0x54, 0x54, 0x28, 0x00,", - "и": "0x7c, 0x20, 0x10, 0x08, 0x7c, 0x00,", - "й": "0x7c, 0x21, 0x12, 0x09, 0x7c, 0x00,", - "к": "0x7c, 0x10, 0x28, 0x44, 0x00, 0x00,", - "л": "0x40, 0x3c, 0x04, 0x04, 0x7c, 0x00,", - "м": "0x7c, 0x08, 0x10, 0x08, 0x7c, 0x00,", - "н": "0x7c, 0x10, 0x10, 0x10, 0x7c, 0x00,", - "о": "0x38, 0x44, 0x44, 0x44, 0x38, 0x00,", - "п": "0x7c, 0x04, 0x04, 0x04, 0x7c, 0x00,", - "р": "0x7c, 0x14, 0x14, 0x14, 0x08, 0x00,", - "с": "0x38, 0x44, 0x44, 0x44, 0x20, 0x00,", - "т": "0x04, 0x04, 0x7c, 0x04, 0x04, 0x00,", - "у": "0x4c, 0x50, 0x20, 0x10, 0x0c, 0x00,", - "ф": "0x18, 0x24, 0x7e, 0x24, 0x18, 0x00,", - "х": "0x44, 0x28, 0x10, 0x28, 0x44, 0x00,", - "ц": "0x3c, 0x20, 0x20, 0x3c, 0x60, 0x00,", - "ч": "0x0c, 0x10, 0x10, 0x10, 0x7c, 0x00,", - "ш": "0x7C, 0x40, 0x7C, 0x40, 0x7C, 0x00,", - "щ": "0x7C, 0x40, 0x7C, 0x40, 0xFC, 0x00,", - "ъ": "0x04, 0x7c, 0x50, 0x20, 0x00, 0x00,", - "ы": "0x7c, 0x50, 0x20, 0x00, 0x7c, 0x00,", - "ь": "0x00, 0x7c, 0x50, 0x20, 0x00, 0x00,", - "э": "0x28, 0x44, 0x54, 0x54, 0x28, 0x00,", - "ю": "0x7c, 0x10, 0x38, 0x44, 0x38, 0x00,", - "я": "0x48, 0x34, 0x14, 0x14, 0x7c, 0x00,", - "ѐ": "0x38, 0x55, 0x56, 0x54, 0x08, 0x00,", - "ё": "0x38, 0x55, 0x54, 0x55, 0x08, 0x00,", - "ђ": "0x02, 0x3f, 0x12, 0x48, 0x30, 0x00,", - "ѓ": "0x7c, 0x04, 0x06, 0x05, 0x04, 0x00,", - "є": "0x38, 0x54, 0x54, 0x44, 0x28, 0x00,", - "ѕ": "0x08, 0x54, 0x54, 0x54, 0x20, 0x00,", - "і": "0x00, 0x44, 0x7d, 0x40, 0x00, 0x00,", - "ї": "0x00, 0x45, 0x7c, 0x41, 0x00, 0x00,", - "ј": "0x20, 0x40, 0x44, 0x3d, 0x00, 0x00,", - "љ": "0x7c, 0x04, 0x7c, 0x50, 0x20, 0x00,", - "њ": "0x7c, 0x10, 0x7c, 0x50, 0x20, 0x00,", - "ћ": "0x04, 0x7e, 0x14, 0x10, 0x60, 0x00,", - "ќ": "0x7c, 0x12, 0x29, 0x44, 0x00, 0x00,", - "ѝ": "0x7c, 0x21, 0x12, 0x08, 0x7c, 0x00,", - "ў": "0x4c, 0x51, 0x22, 0x11, 0x0c, 0x00,", - "џ": "0x3c, 0x20, 0x60, 0x20, 0x3c, 0x00,", - "Ā": "0x78, 0x15, 0x15, 0x15, 0x78, 0x00,", - "ā": "0x20, 0x55, 0x55, 0x55, 0x78, 0x00,", - "Ă": "0x78, 0x15, 0x16, 0x15, 0x78, 0x00,", - "ă": "0x20, 0x55, 0x56, 0x55, 0x78, 0x00,", - "Ą": "0x7e, 0x09, 0x09, 0x49, 0xbe, 0x00,", - "ą": "0x20, 0x54, 0x54, 0xd4, 0x78, 0x00,", - "Ć": "0x38, 0x44, 0x46, 0x45, 0x28, 0x00,", - "ć": "0x38, 0x44, 0x46, 0x45, 0x20, 0x00,", - "Ĉ": "0x38, 0x46, 0x45, 0x46, 0x28, 0x00,", - "ĉ": "0x38, 0x46, 0x45, 0x46, 0x20, 0x00,", - "Ċ": "0x38, 0x44, 0x45, 0x44, 0x28, 0x00,", - "ċ": "0x38, 0x44, 0x45, 0x44, 0x20, 0x00,", - "Č": "0x38, 0x45, 0x46, 0x45, 0x28, 0x00,", - "č": "0x38, 0x45, 0x46, 0x45, 0x20, 0x00,", - "Ď": "0x7c, 0x45, 0x46, 0x29, 0x10, 0x00,", - "ď": "0x38, 0x44, 0x44, 0x4A, 0x7F, 0x00,", - "Đ": "0x08, 0x7f, 0x49, 0x22, 0x1c, 0x00,", - "đ": "0x38, 0x44, 0x44, 0x4A, 0x7F, 0x00,", - "Ē": "0x7c, 0x55, 0x55, 0x55, 0x44, 0x00,", - "ē": "0x38, 0x55, 0x55, 0x55, 0x08, 0x00,", - "Ĕ": "0x7c, 0x55, 0x56, 0x55, 0x44, 0x00,", - "ĕ": "0x38, 0x55, 0x56, 0x55, 0x08, 0x00,", - "Ė": "0x7c, 0x54, 0x55, 0x54, 0x44, 0x00,", - "ė": "0x38, 0x54, 0x55, 0x54, 0x08, 0x00,", - "Ę": "0x7f, 0x49, 0x49, 0xc9, 0x41, 0x00,", - "ę": "0x38, 0x54, 0x54, 0xd4, 0x18, 0x00,", - "Ě": "0x7c, 0x55, 0x56, 0x55, 0x44, 0x00,", - "ě": "0x38, 0x55, 0x56, 0x55, 0x08, 0x00,", - "Ĝ": "0x38, 0x46, 0x55, 0x56, 0x70, 0x00,", - "ĝ": "0x08, 0x56, 0x55, 0x56, 0x3c, 0x00,", - "Ğ": "0x38, 0x45, 0x56, 0x55, 0x30, 0x00,", - "ğ": "0x08, 0x55, 0x56, 0x55, 0x3c, 0x00,", - "Ġ": "0x38, 0x44, 0x55, 0x54, 0x30, 0x00,", - "ġ": "0x08, 0x54, 0x55, 0x54, 0x3c, 0x00,", - "Ģ": "0x0e, 0x51, 0x35, 0x15, 0x1c, 0x00,", - "Ĥ": "0x7c, 0x12, 0x11, 0x12, 0x7c, 0x00,", - "ĥ": "0x02, 0x79, 0x22, 0x10, 0x60, 0x00,", - "Ħ": "0x02, 0x7f, 0x0a, 0x7f, 0x02, 0x00,", - "ħ": "0x02, 0x7f, 0x12, 0x08, 0x70, 0x00,", - "Ĩ": "0x4a, 0x49, 0x7a, 0x49, 0x48, 0x00,", - "ĩ": "0x02, 0x49, 0x7a, 0x41, 0x00, 0x00,", - "Ī": "0x44, 0x45, 0x7d, 0x45, 0x44, 0x00,", - "ī": "0x00, 0x45, 0x7d, 0x41, 0x00, 0x00,", - "Ĭ": "0x44, 0x45, 0x7e, 0x45, 0x44, 0x00,", - "ĭ": "0x00, 0x45, 0x7e, 0x41, 0x00, 0x00,", - "Į": "0x00, 0x41, 0x7f, 0xc1, 0x00, 0x00,", - "į": "0x00, 0x44, 0x7d, 0xc0, 0x00, 0x00,", - "İ": "0x44, 0x44, 0x7d, 0x44, 0x44, 0x00,", - "ı": "0x00, 0x44, 0x7c, 0x40, 0x00, 0x00,", - "ij": "0x44, 0x7d, 0x40, 0x44, 0x3d, 0x00,", - "Ĵ": "0x20, 0x40, 0x46, 0x3d, 0x06, 0x00,", - "ĵ": "0x00, 0x20, 0x46, 0x3d, 0x02, 0x00,", - "Ķ": "0x1f, 0x44, 0x2a, 0x11, 0x00, 0x00,", - "ķ": "0x1f, 0x44, 0x2a, 0x11, 0x00, 0x00,", - "ĸ": "0x7c, 0x10, 0x28, 0x44, 0x00, 0x00,", - "Ĺ": "0x7c, 0x40, 0x42, 0x41, 0x40, 0x00,", - "Ľ": "0x7c, 0x40, 0x42, 0x41, 0x40, 0x00,", - "ĺ": "0x00, 0x44, 0x7e, 0x41, 0x00, 0x00,", - "Ļ": "0x1f, 0x50, 0x30, 0x10, 0x10, 0x00,", - "ļ": "0x00, 0x51, 0x3f, 0x10, 0x00, 0x00,", - "ľ": "0x00, 0x41, 0x7f, 0x40, 0x03, 0x00,", - "Ŀ": "0x7f, 0x40, 0x40, 0x48, 0x40, 0x00,", - "ŀ": "0x00, 0x41, 0x7f, 0x40, 0x08, 0x00,", - "Ł": "0x10, 0x7F, 0x48, 0x44, 0x40, 0x00,", - "ł": "0x00, 0x49, 0x7F, 0x44, 0x00, 0x00,", - "Ń": "0x7c, 0x08, 0x12, 0x21, 0x7c, 0x00,", - "ń": "0x7c, 0x08, 0x06, 0x05, 0x78, 0x00,", - "Ņ": "0x1f, 0x42, 0x24, 0x08, 0x1f, 0x00,", - "ņ": "0x1f, 0x42, 0x21, 0x01, 0x1e, 0x00,", - "Ň": "0x7c, 0x09, 0x12, 0x21, 0x7c, 0x00,", - "ň": "0x7c, 0x09, 0x06, 0x05, 0x78, 0x00,", - "Ō": "0x38, 0x45, 0x45, 0x45, 0x38, 0x00,", - "ō": "0x38, 0x45, 0x45, 0x45, 0x38, 0x00,", - "Ŏ": "0x38, 0x45, 0x46, 0x45, 0x38, 0x00,", - "ŏ": "0x38, 0x45, 0x46, 0x45, 0x38, 0x00,", - "Œ": "0x3e, 0x41, 0x7f, 0x49, 0x49, 0x00,", - "œ": "0x38, 0x44, 0x7c, 0x54, 0x58, 0x00,", - "Ŕ": "0x7c, 0x14, 0x16, 0x15, 0x68, 0x00,", - "ŕ": "0x7c, 0x08, 0x06, 0x05, 0x08, 0x00,", - "Ŗ": "0x1f, 0x45, 0x25, 0x05, 0x1a, 0x00,", - "ŗ": "0x1f, 0x42, 0x21, 0x01, 0x02, 0x00,", - "Ř": "0x7c, 0x15, 0x16, 0x15, 0x68, 0x00,", - "ř": "0x7c, 0x09, 0x06, 0x05, 0x08, 0x00,", - "Ś": "0x08, 0x54, 0x56, 0x55, 0x20, 0x00,", - "ś": "0x48, 0x54, 0x56, 0x55, 0x24, 0x00,", - "Ŝ": "0x08, 0x56, 0x55, 0x56, 0x20, 0x00,", - "ŝ": "0x48, 0x56, 0x55, 0x56, 0x24, 0x00,", - "Ş": "0x02, 0x55, 0x35, 0x15, 0x08, 0x00,", - "ş": "0x12, 0x55, 0x35, 0x15, 0x09, 0x00,", - "Š": "0x08, 0x55, 0x56, 0x55, 0x20, 0x00,", - "š": "0x48, 0x55, 0x56, 0x55, 0x24, 0x00,", - "Ţ": "0x01, 0x41, 0x3f, 0x01, 0x01, 0x00,", - "ţ": "0x02, 0x4f, 0x32, 0x10, 0x08, 0x00,", - "Ť": "0x04, 0x05, 0x7e, 0x05, 0x04, 0x00,", - "ť": "0x04, 0x3e, 0x44, 0x40, 0x23, 0x00,", - "Ŧ": "0x01, 0x09, 0x7f, 0x09, 0x01, 0x00,", - "ŧ": "0x14, 0x3e, 0x54, 0x40, 0x20, 0x00,", - "Ū": "0x3c, 0x41, 0x41, 0x41, 0x3c, 0x00,", - "ū": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", - "Ŭ": "0x3c, 0x41, 0x42, 0x41, 0x3c, 0x00,", - "ŭ": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", - "Ů": "0x3c, 0x40, 0x41, 0x40, 0x3c, 0x00,", - "ů": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", - "Ŵ": "0x3c, 0x42, 0x39, 0x42, 0x3c, 0x00,", - "ŵ": "0x3c, 0x42, 0x31, 0x42, 0x3c, 0x00,", - "Ŷ": "0x04, 0x0a, 0x71, 0x0a, 0x04, 0x00,", - "ŷ": "0x04, 0x4a, 0x31, 0x12, 0x0c, 0x00,", - "Ÿ": "0x04, 0x09, 0x70, 0x09, 0x04, 0x00,", - "Ź": "0x44, 0x64, 0x56, 0x4d, 0x44, 0x00,", - "ź": "0x44, 0x64, 0x56, 0x4d, 0x44, 0x00,", - "Ż": "0x44, 0x64, 0x55, 0x4c, 0x44, 0x00,", - "ż": "0x44, 0x64, 0x55, 0x4c, 0x44, 0x00,", - "Ž": "0x44, 0x65, 0x56, 0x4d, 0x44, 0x00,", - "ž": "0x44, 0x65, 0x56, 0x4d, 0x44, 0x00,", - "ſ": "0x00, 0x04, 0x7e, 0x01, 0x01, 0x00,", + # U+0080..U+00FF Latin-1 Supplement + "¡": b"\x00\x00\x00\x00\x80\xF3\xF3\x80\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x3F\x3F\x0F\x00\x00\x00\x00", + "¢": b"\x00\x00\xE0\xF0\x38\xFE\xFE\x18\x38\x30\x00\x00\x00\x00\x03\x07\x0E\x3F\x3F\x0C\x0E\x06\x00\x00", + "£": b"\x00\x00\x00\x80\xF8\xFC\x8C\x8C\x1C\x18\x00\x00\x00\x00\x18\x1C\x1F\x0B\x18\x18\x18\x18\x08\x00", + "¤": b"\x00\xF6\xFE\x18\x0C\x0C\x0C\x0C\x18\xFE\xF6\x00\x00\x1B\x1F\x06\x0C\x0C\x0C\x0C\x06\x1F\x1B\x00", + "¥": b"\x00\x03\x0F\x3C\xF0\xC0\xC0\xF0\x3C\x0F\x03\x00\x00\x00\x0A\x0A\x0A\x3F\x3F\x0A\x0A\x0A\x00\x00", + "¦": b"\x00\x00\x00\x00\x00\x1F\x1F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "§": b"\x00\x00\xDC\xFE\x22\x22\x22\x22\xE6\xC4\x00\x00\x00\x00\x08\x19\x11\x11\x11\x11\x1F\x0E\x00\x00", + "¨": b"\x00\x00\x00\x03\x03\x00\x00\x03\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "©": b"\x00\xF0\xF8\x1C\xCC\xEC\x2C\x6C\x4C\x1C\xF8\xF0\x00\x07\x0F\x1C\x19\x1B\x1A\x1B\x19\x1C\x0F\x07", + "«": b"\x00\x80\xC0\x60\x20\x00\x80\xC0\x60\x20\x00\x00\x00\x00\x01\x03\x02\x00\x00\x01\x03\x02\x00\x00", + "¬": b"\x18\x18\x18\x18\x18\x18\x18\x18\x18\xF8\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x03\x00", + "®": b"\x00\xF0\xF8\x1C\xEC\xEC\xAC\xEC\x4C\x1C\xF8\xF0\x00\x07\x0F\x1C\x1B\x1B\x18\x1B\x1B\x1C\x0F\x07", + "¯": b"\x00\x00\x00\x00\x00\x0C\x0C\x0C\x0C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "°": b"\x00\x00\x00\x1E\x3F\x33\x33\x3F\x1E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "±": b"\x00\x00\x00\xC0\xC0\xF0\xF0\xC0\xC0\x00\x00\x00\x00\x00\x00\x18\x18\x1B\x1B\x18\x18\x00\x00\x00", + "²": b"\x00\x00\x19\x1D\x15\x17\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "³": b"\x00\x00\x11\x15\x15\x1F\x0A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "´": b"\x00\x00\x00\x00\x04\x06\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "µ": b"\x00\xF0\xF0\x00\x00\x00\x00\x00\xF0\xF0\x00\x00\x00\xFF\xFF\x0E\x0C\x0C\x0C\x06\x0F\x0F\x00\x00", + "¶": b"\x00\x38\x7C\xC6\x82\xFE\xFE\x02\xFE\xFE\x02\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x3F\x3F\x00\x00", + "¹": b"\x00\x00\x12\x1F\x1F\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "»": b"\x00\x20\x60\xC0\x80\x00\x20\x60\xC0\x80\x00\x00\x00\x02\x03\x01\x00\x00\x02\x03\x01\x00\x00\x00", + "¼": b"\x00\x48\x7C\x7C\x40\x80\xC0\x60\x30\x10\x00\x00\x00\x00\x04\x06\x03\x01\x06\x07\x04\x1F\x1F\x00", + "½": b"\x00\x48\x7C\x7C\x40\x80\xC0\x60\x30\x10\x00\x00\x00\x00\x04\x06\x03\x01\x00\x19\x1D\x17\x12\x00", + "¾": b"\x00\x44\x54\x7C\x28\x80\xC0\x60\x30\x10\x00\x00\x00\x00\x04\x06\x03\x01\x06\x07\x04\x1F\x1F\x00", + "¿": b"\x00\x00\x00\x80\xC0\xFB\x7B\x00\x00\x00\x00\x00\x00\x0E\x1F\x3B\x31\x30\x30\x30\x38\x1E\x0E\x00", + "À": b"\x00\x00\x00\x80\xE1\x7B\x7E\xE4\x80\x00\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Á": b"\x00\x00\x00\x80\xE4\x7E\x7B\xE1\x80\x00\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Â": b"\x00\x00\x00\x84\xE6\x7B\x7B\xE6\x84\x00\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Ã": b"\x00\x00\x00\x82\xE3\x79\x7B\xE2\x83\x01\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Ä": b"\x00\x00\x00\x83\xE3\x78\x78\xE3\x83\x00\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Å": b"\x00\x00\x00\x80\xE2\x75\x75\xE2\x80\x00\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Æ": b"\x00\x00\x80\xF0\x7C\x1F\xFF\xFF\xC3\xC3\x03\x00\x00\x3C\x3F\x07\x06\x06\x3F\x3F\x30\x30\x30\x00", + "Ç": b"\x00\xF0\xFC\x0E\x07\x03\x03\x03\x07\x1E\x1C\x00\x00\x01\x07\xCE\xDC\xF8\xF8\x18\x1C\x0E\x06\x00", + "È": b"\x00\xF8\xF8\x99\x9B\x9E\x9C\x98\x98\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "É": b"\x00\xF8\xF8\x98\x98\x9C\x9E\x9B\x99\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "Ê": b"\x00\xF8\xF8\x9C\x9E\x9B\x9B\x9E\x9C\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "Ë": b"\x00\xF8\xF8\x9B\x9B\x98\x98\x9B\x9B\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "Ì": b"\x00\x00\x00\x19\x1B\xFE\xFC\x18\x18\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Í": b"\x00\x00\x00\x18\x18\xFC\xFE\x1B\x19\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Î": b"\x00\x00\x00\x1C\x1E\xFB\xFB\x1E\x1C\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ï": b"\x00\x00\x00\x1B\x1B\xF8\xF8\x1B\x1B\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ð": b"\x00\xC0\xFF\xFF\xC3\x03\x03\x07\x0E\xFC\xF0\x00\x00\x00\x3F\x3F\x30\x30\x30\x38\x1C\x0F\x03\x00", + "Ñ": b"\x00\xF8\xF8\x72\xE3\xC1\x83\x02\x03\xF9\xF8\x00\x00\x3F\x3F\x00\x00\x01\x03\x07\x0E\x3F\x3F\x00", + "Ò": b"\x00\xE0\xF0\x39\x1B\x1E\x1C\x18\x38\xF0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Ó": b"\x00\xE0\xF0\x38\x18\x1C\x1E\x1B\x39\xF0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Ô": b"\x00\xE0\xF0\x3C\x1E\x1B\x1B\x1E\x3C\xF0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Õ": b"\x00\xE0\xF0\x3A\x1B\x19\x1B\x1A\x3B\xF1\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Ö": b"\x00\xE0\xF0\x3B\x1B\x18\x18\x1B\x3B\xF0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "×": b"\x00\xF0\xF8\x1C\x0C\x8C\xEC\x7C\x18\xFC\xF4\x00\x00\x2F\x3F\x18\x3E\x37\x31\x30\x38\x1F\x0F\x00", + "Ù": b"\x00\xF8\xF8\x01\x03\x06\x04\x00\x00\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "Ú": b"\x00\xF8\xF8\x00\x00\x04\x06\x03\x01\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "Û": b"\x00\xF8\xF8\x04\x06\x03\x03\x06\x04\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "Ü": b"\x00\xF8\xF8\x03\x03\x00\x00\x03\x03\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "Ý": b"\x00\x08\x18\x30\x60\xC4\xC6\x63\x31\x18\x08\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "ß": b"\x00\x00\xC0\xE0\x30\x10\x10\x30\xE0\xC0\x00\x00\x00\x00\xFF\xFF\x21\x21\x21\x33\x3F\x1E\x00\x00", + "à": b"\x00\x00\x40\x60\x62\x66\x6C\x68\x60\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "á": b"\x00\x00\x40\x60\x68\x6C\x66\x62\x60\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "â": b"\x00\x00\x40\x68\x6C\x66\x66\x6C\x68\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "ã": b"\x00\x00\x40\x68\x6C\x64\x6C\x68\x6C\xE4\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "ä": b"\x00\x00\x40\x6C\x6C\x60\x60\x6C\x6C\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "å": b"\x00\x00\x40\x60\x64\x6A\x6A\x64\x60\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "æ": b"\x00\x80\xC0\x40\x40\xC0\x80\x40\x40\xC0\x80\x00\x00\x1C\x3E\x22\x22\x1F\x3F\x22\x22\x33\x11\x00", + "ç": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x0F\x1F\xB8\xB0\xF0\xF0\x30\x38\x18\x08\x00", + "è": b"\x00\x80\xC0\xE0\x62\x66\x6C\x68\x60\xC0\x80\x00\x00\x0F\x1F\x33\x33\x33\x33\x33\x33\x13\x03\x00", + "é": b"\x00\x80\xC0\xE0\x60\x68\x6C\x66\x62\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x03\x00", + "ê": b"\x00\x80\xC0\xE8\x6C\x66\x66\x6C\x68\xC0\x80\x00\x00\x0F\x1F\x33\x33\x33\x33\x33\x33\x13\x03\x00", + "ë": b"\x00\x80\xC0\xEC\x6C\x60\x60\x6C\x6C\xC0\x80\x00\x00\x0F\x1F\x33\x33\x33\x33\x33\x33\x13\x03\x00", + "ì": b"\x00\x00\x00\x00\x62\xE6\xEC\x08\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "í": b"\x00\x00\x00\x00\x68\xEC\xE6\x02\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "î": b"\x00\x00\x00\x08\x6C\xE6\xE6\x0C\x08\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ï": b"\x00\x00\x00\x0C\x6C\xE0\xEC\x0C\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ñ": b"\x00\x00\xE0\xE8\x6C\x64\x6C\x68\xEC\xC4\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "ò": b"\x00\x80\xC0\xE0\x62\x66\x6C\x68\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "ó": b"\x00\x80\xC0\xE0\x68\x6C\x66\x62\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "ô": b"\x00\x80\xC0\xE8\x6C\x66\x66\x6C\xE8\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "õ": b"\x00\x80\xC8\xEC\x64\x6C\x68\x6C\xE4\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "ö": b"\x00\x80\xC0\xEC\x6C\x60\x60\x6C\xEC\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "÷": b"\x00\x00\x80\x80\x80\xB0\xB0\x80\x80\x80\x00\x00\x00\x00\x01\x01\x01\x0D\x0D\x01\x01\x01\x00\x00", + "ø": b"\x00\x80\xC0\xE0\x60\x60\x60\xE0\xC0\xE0\xA0\x00\x00\x2F\x3F\x18\x3C\x36\x33\x31\x38\x1F\x0F\x00", + "ù": b"\x00\xE0\xE0\x00\x02\x06\x0C\x08\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "ú": b"\x00\xE0\xE0\x00\x08\x0C\x06\x02\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "û": b"\x00\xE0\xE0\x08\x0C\x06\x06\x0C\x08\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "ü": b"\x00\xE0\xE0\x0C\x0C\x00\x00\x0C\x0C\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "ý": b"\x00\x00\x60\xE0\x80\x10\x18\x8C\xE4\x60\x00\x00\x00\x00\x00\x81\xE7\x7E\x1E\x07\x01\x00\x00\x00", + "þ": b"\x00\x00\x03\xFF\xFF\x1B\x18\x18\xF8\xF0\x00\x00\x00\x00\x30\x3F\x3F\x36\x06\x06\x07\x03\x00\x00", + "ÿ": b"\x00\x00\x60\xEC\x8C\x00\x00\x8C\xEC\x60\x00\x00\x00\x00\x00\x81\xE7\x7E\x1E\x07\x01\x00\x00\x00", + # U+0100..U+017F Latin Extended A + "Ā": b"\x00\x00\x00\xE0\xF9\x1D\x1D\xF9\xE0\x00\x00\x00\x00\x38\x3F\x07\x06\x06\x06\x06\x07\x3F\x38\x00", + "ā": b"\x00\x00\x40\x60\x68\x68\x68\x68\x68\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "Ă": b"\x00\x00\x00\xE0\xF9\x1A\x1A\xF9\xE0\x00\x00\x00\x00\x38\x3F\x07\x06\x06\x06\x06\x07\x3F\x38\x00", + "ă": b"\x00\x00\x40\x60\x64\x68\x68\x68\x64\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "Ą": b"\x00\x00\x00\xE0\xFC\x1F\x1F\xFC\xE0\x00\x00\x00\x00\x38\x3F\x07\x06\x06\x06\x06\x67\xBF\xB8\x00", + "ą": b"\x00\x00\x40\x60\x60\x60\x60\x60\x60\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x73\xBF\xBF\x00", + "Ć": b"\x00\x80\xE0\x70\x38\x18\x1A\x1B\x39\x70\x60\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "ć": b"\x00\x80\xC0\xE0\x60\x60\x68\x6C\x64\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x18\x08\x00", + "Ĉ": b"\x00\x80\xE0\x70\x3A\x1B\x19\x1B\x3A\x70\x60\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "ĉ": b"\x00\x80\xC0\xE0\x68\x6C\x64\x6C\x68\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x18\x08\x00", + "Ċ": b"\x00\x80\xE0\x70\x38\x18\x1A\x18\x38\x70\x60\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "ċ": b"\x00\x80\xC0\xE0\x60\x60\x68\x60\x60\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x18\x08\x00", + "Č": b"\x00\x80\xE0\x70\x39\x1B\x1A\x1B\x39\x70\x60\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "č": b"\x00\x80\xC0\xE0\x64\x6C\x68\x6C\x64\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x18\x08\x00", + "Ď": b"\x00\xF8\xF8\x19\x1B\x1A\x1B\x39\x70\xE0\x80\x00\x00\x3F\x3F\x30\x30\x30\x30\x38\x1C\x0F\x03\x00", + "ď": b"\x00\x80\xC0\xE0\x60\x60\xE0\xFF\xFF\x00\x05\x03\x00\x0F\x1F\x38\x30\x30\x30\x3F\x3F\x00\x00\x00", + "Đ": b"\xC0\xFF\xFF\xC3\xC3\x03\x03\x07\x0E\xFC\xF0\x00\x00\x3F\x3F\x30\x30\x30\x30\x38\x1C\x0F\x03\x00", + "đ": b"\x00\x80\xC0\xE0\x60\x60\x60\xE4\xC4\xFF\xFF\x04\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x3F\x3F\x00", + "Ē": b"\x00\xFC\xFC\x8C\x8D\x8D\x8D\x8D\x8C\x0C\x0C\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "ē": b"\x00\x80\xC0\xE0\x68\x68\x68\x68\x68\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x01\x00", + "Ĕ": b"\x00\xF8\xF8\x98\x99\x9A\x9A\x99\x98\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "ĕ": b"\x00\x80\xC0\xE0\x64\x68\x68\x68\x64\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x01\x00", + "Ė": b"\x00\xF8\xF8\x98\x98\x98\x9A\x98\x98\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "ė": b"\x00\x80\xC0\xE0\x60\x60\x68\x60\x60\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x01\x00", + "Ę": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xC3\xC3\x03\x03\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x70\xB0\xB0\x00", + "ę": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\x60\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x73\xB3\xB3\x13\x01\x00", + "Ě": b"\x00\xF8\xF8\x98\x99\x9B\x9A\x9B\x99\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "ě": b"\x00\x80\xC0\xE0\x64\x6C\x68\x6C\x64\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x01\x00", + "Ĝ": b"\x00\x80\xE0\x70\x1A\x1B\x19\x1B\x1A\x38\x30\x00\x00\x03\x0F\x1C\x38\x30\x33\x33\x33\x3F\x3F\x00", + "ĝ": b"\x00\x80\xC0\xE0\x68\x6C\x64\x6C\x68\xE0\xE0\x00\x00\x03\xC7\xCE\xCC\xCC\xCC\xCC\xE6\x7F\x3F\x00", + "Ğ": b"\x00\x80\xE0\x70\x1A\x19\x19\x19\x1A\x38\x30\x00\x00\x03\x0F\x1C\x38\x30\x33\x33\x33\x3F\x3F\x00", + "ğ": b"\x00\x80\xC0\xE0\x68\x64\x64\x64\x68\xE0\xE0\x00\x00\x03\xC7\xCE\xCC\xCC\xCC\xCC\xE6\x7F\x3F\x00", + "Ġ": b"\x00\x80\xE0\x70\x18\x18\x1A\x18\x18\x38\x30\x00\x00\x03\x0F\x1C\x38\x30\x33\x33\x33\x3F\x3F\x00", + "ġ": b"\x00\x80\xC0\xE0\x60\x60\x68\x60\x60\xE0\xE0\x00\x00\x03\xC7\xCE\xCC\xCC\xCC\xCC\xE6\x7F\x3F\x00", + "Ģ": b"\x00\xF0\xFC\x0E\x07\x03\xC3\xC3\xC3\xC7\xC6\x00\x00\x03\x0F\x1C\x38\x30\xB0\x70\x30\x3F\x3F\x00", + "ģ": b"\x00\x80\xC0\xE0\x60\x60\x6C\x6A\x60\xE0\xE0\x00\x00\x03\xC7\xCE\xCC\xCC\xCC\xCC\xE6\x7F\x3F\x00", + "Ĥ": b"\x00\xFC\xFC\x80\x82\x81\x81\x82\x80\xFC\xFC\x00\x00\x3F\x3F\x01\x01\x01\x01\x01\x01\x3F\x3F\x00", + "ĥ": b"\x00\xFE\xFE\xC0\x62\x63\x61\xE3\xC2\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00\x00", + "Ħ": b"\x02\xFF\xFF\xC2\xC2\xC2\xC2\xC2\xC2\xFF\xFF\x02\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "ħ": b"\x04\xFF\xFF\xC4\x64\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00\x00", + "Ĩ": b"\x00\x00\x00\x1A\x19\xFB\xFB\x1A\x19\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ĩ": b"\x00\x00\x00\x08\x64\xEC\xE8\x04\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ī": b"\x00\x00\x00\x0C\x0D\xFD\xFD\x0D\x0C\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ī": b"\x00\x00\x00\x08\x68\xE8\xE8\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ĭ": b"\x00\x00\x00\x18\x19\xFA\xFA\x19\x18\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ĭ": b"\x00\x00\x00\x00\x64\xE8\xE8\x04\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Į": b"\x00\x00\x00\x03\x03\xFF\xFF\x03\x03\x00\x00\x00\x00\x00\x00\x30\x30\x7F\xBF\xB0\x30\x00\x00\x00", + "į": b"\x00\x00\x00\x00\x60\xEC\xEC\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x7F\xBF\xB0\x30\x00\x00\x00", + "İ": b"\x00\x00\x00\x18\x18\xF8\xFA\x18\x18\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ı": b"\x00\x00\x00\x00\x60\xE0\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "IJ": b"\x00\x03\xFF\xFF\x03\x00\x00\x00\x03\xFF\xFF\x00\x00\x30\x3F\x3F\x30\x0C\x1C\x30\x30\x3F\x1F\x00", + "ij": b"\x00\x00\x20\xEC\xEC\x00\x00\x20\xEC\xEC\x00\x00\x00\x00\x30\x3F\x3F\x70\xC0\xC0\xFF\x7F\x00\x00", + "Ĵ": b"\x00\x00\x00\x00\x02\x03\x01\x03\x02\xF8\xF8\x00\x00\x0E\x1E\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ĵ": b"\x00\x00\x00\x00\x00\x08\x6C\xE4\xEC\x08\x00\x00\x00\x00\x00\x60\xE0\xC0\xC0\xFF\x7F\x00\x00\x00", + "Ķ": b"\x00\xFF\xFF\xC0\xE0\xF0\x38\x1C\x0E\x07\x03\x00\x00\x3F\x3F\x00\x01\xA3\x67\x0E\x1C\x38\x30\x00", + "ķ": b"\x00\x00\xFF\xFF\x00\x80\xC0\xE0\x60\x00\x00\x00\x00\x00\x3F\x3F\x03\xA7\x6F\x1C\x38\x30\x00\x00", + "ĸ": b"\x00\x00\xE0\xE0\x00\x80\xC0\xE0\x60\x20\x00\x00\x00\x00\x3F\x3F\x03\x07\x0F\x1C\x38\x30\x00\x00", + "Ĺ": b"\x00\xF8\xFA\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "ĺ": b"\x00\x00\x00\x00\x18\xFA\xFB\x01\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ļ": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\xB0\x70\x30\x30\x30\x30\x00", + "ļ": b"\x00\x00\x00\x00\x03\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\xBF\x7F\x30\x30\x00\x00\x00", + "Ľ": b"\x00\xFF\xFF\x00\x00\x05\x03\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "ľ": b"\x00\x00\x00\x00\x03\xFF\xFF\x00\x05\x03\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ŀ": b"\x00\xFF\xFF\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "ŀ": b"\x00\x00\x00\x00\x03\xFF\xFF\x00\x40\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ł": b"\x80\xFF\xFF\x20\x10\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "ł": b"\x00\x00\x00\x00\x83\xFF\xFF\x20\x10\x00\x00\x00\x00\x00\x00\x31\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ń": b"\x00\xFF\xFF\x0E\x38\xF2\xC3\x01\x00\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x03\x07\x1C\x3F\x3F\x00", + "ń": b"\x00\x00\xE0\xE0\x60\x68\x6C\x64\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "Ņ": b"\x00\xFF\xFF\x0E\x38\xF0\xC0\x00\x00\xFF\xFF\x00\x00\x3F\x3F\x00\x00\xA0\x63\x07\x1C\x3F\x3F\x00", + "ņ": b"\x00\x00\xE0\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\xA0\x60\x00\x3F\x3F\x00", + "Ň": b"\x00\xFF\xFF\x0E\x38\xF1\xC2\x01\x00\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x03\x07\x1C\x3F\x3F\x00", + "ň": b"\x00\x00\xE0\xE0\x64\x6C\x68\x6C\xE4\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "ʼn": b"\x00\x0A\xE6\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "Ŋ": b"\x00\x00\xFF\xFF\x06\x03\x03\x03\x07\xFE\xFC\x00\x00\x00\x3F\x3F\x00\x00\x20\x20\x30\x1F\x0F\x00", + "ŋ": b"\x00\x00\xE0\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\xC0\xC0\xFF\x7F\x00", + "Ō": b"\x00\xC0\xF0\x38\x1D\x0D\x0D\x1D\x38\xF0\xC0\x00\x00\x03\x0F\x1C\x38\x30\x30\x38\x1C\x0F\x03\x00", + "ō": b"\x00\x80\xC0\xE0\x68\x68\x68\x68\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Ŏ": b"\x00\x80\xE0\x70\x39\x1A\x1A\x39\x70\xE0\x80\x00\x00\x03\x0F\x1C\x38\x30\x30\x38\x1C\x0F\x03\x00", + "ŏ": b"\x00\x80\xC0\xE0\x64\x68\x68\x64\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Ő": b"\x00\x80\xE0\x70\x3A\x19\x1A\x39\x70\xE0\x80\x00\x00\x03\x0F\x1C\x38\x30\x30\x38\x1C\x0F\x03\x00", + "ő": b"\x00\x80\xC0\xE0\x68\x64\x68\x64\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Œ": b"\xF0\xFC\x0E\x03\x03\x07\xFE\xFF\xC3\xC3\xC3\x00\x03\x0F\x1C\x30\x30\x38\x1F\x3F\x30\x30\x30\x00", + "œ": b"\x80\xC0\xE0\x60\x60\xE0\xC0\x60\x60\x60\x40\x80\x0F\x1F\x38\x30\x30\x1F\x1F\x3B\x33\x33\x1B\x09", + "Ŕ": b"\x00\xF8\xF8\x98\x98\x9A\x9B\x99\xF8\xF0\x60\x00\x00\x3F\x3F\x01\x01\x03\x07\x0F\x1D\x38\x30\x00", + "ŕ": b"\x00\x00\xE0\xE0\xC0\x60\x68\x6C\x64\xE0\xC0\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00", + "Ŗ": b"\x00\xFF\xFF\x83\x83\x83\x83\x83\xC7\xFE\x7C\x00\x00\x3F\x3F\x01\x01\xA3\x67\x0F\x1D\x38\x30\x00", + "ŗ": b"\x00\x00\xE0\xE0\xC0\x60\x60\x60\x60\xE0\xC0\x00\x00\x00\x3F\x3F\x00\xA0\x60\x00\x00\x00\x00\x00", + "Ř": b"\x00\xF8\xF8\x99\x9B\x9A\x9B\x99\xF8\xF0\x60\x00\x00\x3F\x3F\x01\x01\x03\x07\x0F\x1D\x38\x30\x00", + "ř": b"\x00\x00\xE0\xE0\xC4\x6C\x68\x6C\x64\xE0\xC0\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00", + "Ś": b"\x00\x60\xF0\xF8\x98\x9A\x9B\x99\x98\x30\x20\x00\x00\x0C\x1C\x39\x31\x31\x31\x31\x3B\x1F\x0E\x00", + "ś": b"\x00\xC0\xE0\x60\x68\x6C\x64\x60\x40\x00\x00\x00\x00\x11\x33\x33\x33\x33\x33\x3F\x1E\x00\x00\x00", + "Ŝ": b"\x00\x60\xF0\xF8\x9A\x9B\x99\x9B\x9A\x30\x20\x00\x00\x0C\x1C\x39\x31\x31\x31\x31\x3B\x1F\x0E\x00", + "ŝ": b"\x00\xC0\xE0\x68\x6C\x64\x6C\x68\x40\x00\x00\x00\x00\x11\x33\x33\x33\x33\x33\x3F\x1E\x00\x00\x00", + "Ş": b"\x00\x3C\x7E\xE7\xC3\xC3\xC3\xC3\xC7\x8E\x0C\x00\x00\x0C\x1C\x38\x30\xB0\xF0\x30\x39\x1F\x0F\x00", + "ş": b"\x00\xC0\xE0\x60\x60\x60\x60\x60\x40\x00\x00\x00\x00\x11\x33\x33\xB3\xF3\x33\x3F\x1E\x00\x00\x00", + "Š": b"\x00\x60\xF0\xF8\x99\x9B\x9A\x9B\x99\x30\x20\x00\x00\x0C\x1C\x39\x31\x31\x31\x31\x3B\x1F\x0E\x00", + "š": b"\x00\xC0\xE0\x64\x6C\x68\x6C\x64\x40\x00\x00\x00\x00\x11\x33\x33\x33\x33\x33\x3F\x1E\x00\x00\x00", + "Ţ": b"\x00\x00\x03\x03\x03\xFF\xFF\x03\x03\x03\x00\x00\x00\x00\x00\x00\x00\xBF\xBF\x60\x00\x00\x00\x00", + "ţ": b"\x00\x60\x60\xFE\xFE\x60\x60\x60\x00\x00\x00\x00\x00\x00\x00\x1F\x3F\xB0\xB0\xF0\x30\x00\x00\x00", + "Ť": b"\x00\x00\x18\x19\x1B\xFA\xFA\x1B\x19\x18\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "ť": b"\x00\x60\x60\xFE\xFE\x60\x65\x63\x00\x00\x00\x00\x00\x00\x00\x1F\x3F\x30\x30\x30\x30\x00\x00\x00", + "Ŧ": b"\x00\x00\x03\xC3\xC3\xFF\xFF\xC3\xC3\x03\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "ŧ": b"\x00\x30\x30\xFE\xFE\x30\x30\x30\x00\x00\x00\x00\x00\x03\x03\x1F\x3F\x33\x33\x30\x30\x00\x00\x00", + "Ũ": b"\x00\xF8\xF8\x02\x01\x03\x03\x02\x01\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ũ": b"\x00\xE0\xE0\x08\x04\x0C\x0C\x08\x04\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "Ū": b"\x00\xFC\xFC\x00\x01\x01\x01\x01\x00\xFC\xFC\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ū": b"\x00\xE0\xE0\x00\x08\x08\x08\x08\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "Ŭ": b"\x00\xFC\xFC\x00\x01\x02\x02\x01\x00\xFC\xFC\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ŭ": b"\x00\xE0\xE0\x00\x04\x08\x08\x04\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "Ů": b"\x00\xF8\xF8\x00\x06\x09\x09\x06\x00\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ů": b"\x00\xE0\xE0\x00\x0C\x12\x12\x0C\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "Ű": b"\x00\xF8\xF8\x00\x02\x01\x02\x01\x00\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ű": b"\x00\xE0\xE0\x00\x08\x04\x08\x04\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "Ų": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x07\x1F\x38\x30\xF0\xB0\xB0\x38\x1F\x07\x00", + "ų": b"\x00\xE0\xE0\x00\x00\x00\x00\x00\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\xF0\xB0\xB0\x18\x3F\x3F\x00", + "Ŵ": b"\x00\xFC\xFC\x00\x02\x81\x81\x02\x00\xFC\xFC\x00\x00\x3F\x3F\x1C\x06\x03\x03\x06\x1C\x3F\x3F\x00", + "ŵ": b"\x00\xE0\xE0\x00\x04\xE8\xE8\x04\x00\xE0\xE0\x00\x00\x07\x1F\x38\x1C\x0F\x0F\x1C\x38\x1F\x07\x00", + "Ŷ": b"\x00\x02\x0E\x3C\xF2\xC1\xC1\xF2\x3C\x0E\x02\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "ŷ": b"\x00\x00\x60\xE0\x88\x04\x04\x88\xE0\x60\x00\x00\x00\x00\x00\x81\xE7\x7E\x1E\x07\x01\x00\x00\x00", + "Ÿ": b"\x00\x02\x0E\x3C\xF1\xC0\xC0\xF1\x3C\x0E\x02\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "Ź": b"\x00\x18\x18\x18\x18\x1A\x9B\xD9\xF8\x78\x38\x00\x00\x30\x38\x3C\x3E\x37\x33\x31\x30\x30\x30\x00", + "ź": b"\x00\x60\x60\x60\x68\x6C\xE4\xE0\x60\x20\x00\x00\x00\x30\x38\x3C\x36\x33\x31\x30\x30\x30\x00\x00", + "Ż": b"\x00\x18\x18\x18\x18\x18\x9A\xD8\xF8\x78\x38\x00\x00\x30\x38\x3C\x3E\x37\x33\x31\x30\x30\x30\x00", + "ż": b"\x00\x60\x60\x60\x60\x68\xE0\xE0\x60\x20\x00\x00\x00\x30\x38\x3C\x36\x33\x31\x30\x30\x30\x00\x00", + "Ž": b"\x00\x18\x18\x18\x19\x1B\x9A\xDB\xF9\x78\x38\x00\x00\x30\x38\x3C\x3E\x37\x33\x31\x30\x30\x30\x00", + "ž": b"\x00\x60\x60\x64\x6C\x68\xEC\xE4\x60\x20\x00\x00\x00\x30\x38\x3C\x36\x33\x31\x30\x30\x30\x00\x00", + "ſ": b"\x00\x00\x00\x00\xFC\xFE\x06\x06\x0E\x0C\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x00\x00\x00\x00\x00", } return font + + +def get_font_map_cyrillic() -> Dict[str, bytes]: + font = { + # U+0400..U+04FF Cyrillic + "Ѐ": b"\x00\xFC\xFC\x8D\x8F\x8E\x8C\x8C\x8C\x0C\x0C\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "Ё": b"\x00\xFE\xFE\xC7\xC7\xC6\xC6\xC7\xC7\x06\x06\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "Ђ": b"\x00\x03\xFF\xFF\x83\xC3\xC3\xC3\xC0\x80\x00\x00\x00\x00\x3F\x3F\x01\x00\x30\x30\x39\x1F\x0F\x00", + "Ѓ": b"\x00\xFC\xFC\x0C\x0C\x0C\x0E\x0F\x0D\x0C\x0C\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "Є": b"\x00\xF8\xFC\xCE\xC7\xC3\xC3\xC3\x07\x0E\x0C\x00\x00\x07\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "Ѕ": b"\x00\x3C\x7E\x67\xE3\xC3\xC3\xC3\x87\x8E\x0C\x00\x00\x0C\x1C\x38\x30\x30\x30\x31\x39\x1F\x0F\x00", + "І": b"\x00\x00\x00\x03\x03\xFF\xFF\x03\x03\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ї": b"\x00\x00\x00\x0D\x0D\xFC\xFC\x0D\x0D\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ј": b"\x00\x00\x00\x00\x00\x00\x03\x03\x03\xFF\xFF\x00\x00\x0E\x1E\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Љ": b"\x00\x00\xFE\xFF\x03\x03\xFF\xFF\xC0\xC0\x80\x00\x00\x30\x3F\x1F\x00\x00\x3F\x3F\x30\x39\x1F\x0F", + "Њ": b"\x00\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xC0\xC0\x80\x00\x00\x3F\x3F\x00\x00\x00\x3F\x3F\x30\x39\x1F\x0F", + "Ћ": b"\x00\x03\xFF\xFF\xC3\xC3\xC3\xC3\xC0\x80\x00\x00\x00\x00\x3F\x3F\x01\x00\x00\x00\x01\x3F\x3F\x00", + "Ќ": b"\x00\xFF\xFF\xC0\xE2\xF3\x39\x1C\x0E\x07\x03\x00\x00\x3F\x3F\x00\x01\x03\x07\x0E\x1C\x38\x30\x00", + "Ѝ": b"\x00\xFF\xFF\x00\x01\xC3\xF2\x38\x0E\xFF\xFF\x00\x00\x3F\x3F\x1C\x07\x03\x00\x00\x00\x3F\x3F\x00", + "Ў": b"\x00\x07\x1F\x7C\xF1\xC1\xC1\xF1\x7C\x1F\x07\x00\x00\x00\x30\x30\x3C\x0F\x07\x01\x00\x00\x00\x00", + "Џ": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x1F\x1F\x18\x18\x78\x78\x18\x18\x1F\x1F\x00", + "А": b"\x00\x00\x00\xE0\xFC\x1F\x1F\xFC\xE0\x00\x00\x00\x00\x38\x3F\x07\x06\x06\x06\x06\x07\x3F\x38\x00", + "Б": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xC3\xC3\x83\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x39\x1F\x0F\x00", + "В": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xE7\xFE\xBC\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x39\x1F\x0F\x00", + "Г": b"\x00\xFF\xFF\x03\x03\x03\x03\x03\x03\x03\x03\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "Ґ": b"\x00\xFC\xFC\x0C\x0C\x0C\x0C\x0C\x0C\x0F\x0F\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "Д": b"\x00\x00\xF8\xFE\x0F\x03\x03\x03\xFF\xFF\x00\x00\x00\x70\x7F\x1F\x18\x18\x18\x18\x1F\x7F\x70\x00", + "Е": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xC3\xC3\x03\x03\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "Ж": b"\x00\x03\x0F\xFC\xE0\xFF\xFF\xE0\xFC\x0F\x03\x00\x00\x38\x3F\x07\x00\x3F\x3F\x00\x07\x3F\x38\x00", + "З": b"\x0C\x0E\x07\x03\xC3\xC3\xC3\xC3\xC3\xE7\x7E\x3C\x0C\x1C\x38\x30\x30\x30\x30\x30\x30\x39\x1F\x0E", + "И": b"\x00\xFF\xFF\x00\x00\xC0\xF0\x38\x0E\xFF\xFF\x00\x00\x3F\x3F\x1C\x07\x03\x00\x00\x00\x3F\x3F\x00", + "Й": b"\x00\xFF\xFF\x00\x02\xC3\xF1\x38\x0E\xFF\xFF\x00\x00\x3F\x3F\x1C\x07\x03\x00\x00\x00\x3F\x3F\x00", + "К": b"\x00\xFF\xFF\xC0\xE0\xF0\x38\x1C\x0E\x07\x03\x00\x00\x3F\x3F\x00\x01\x03\x07\x0E\x1C\x38\x30\x00", + "Л": b"\x00\x00\xF0\xFC\x1E\x07\x03\x03\x03\xFF\xFF\x00\x00\x30\x3F\x1F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "М": b"\x00\xFF\xFF\x1E\x78\xE0\xE0\x78\x1E\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x01\x01\x00\x00\x3F\x3F\x00", + "Н": b"\x00\xFF\xFF\xC0\xC0\xC0\xC0\xC0\xC0\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "О": b"\x00\xF0\xFC\x0E\x07\x03\x03\x07\x0E\xFC\xF0\x00\x00\x03\x0F\x1C\x38\x30\x30\x38\x1C\x0F\x03\x00", + "П": b"\x00\xFF\xFF\x03\x03\x03\x03\x03\x03\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "Р": b"\x00\xFF\xFF\x83\x83\x83\x83\x83\xC7\xFE\x7C\x00\x00\x3F\x3F\x01\x01\x01\x01\x01\x01\x00\x00\x00", + "С": b"\x00\xF0\xFC\x0E\x07\x03\x03\x03\x07\x0E\x0C\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "Т": b"\x00\x03\x03\x03\x03\xFF\xFF\x03\x03\x03\x03\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "У": b"\x00\x07\x1F\x7C\xF0\xC0\xC0\xF0\x7C\x1F\x07\x00\x00\x00\x30\x30\x3C\x0F\x07\x01\x00\x00\x00\x00", + "Ф": b"\x00\xF8\xFC\x0E\x06\xFF\xFF\x06\x0E\xFC\xF8\x00\x00\x03\x07\x0E\x0C\x3F\x3F\x0C\x0E\x07\x03\x00", + "Х": b"\x00\x03\x0F\x3C\xF0\xC0\xC0\xF0\x3C\x0F\x03\x00\x00\x30\x3C\x0F\x03\x00\x00\x03\x0F\x3C\x30\x00", + "Ц": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x1F\x1F\x18\x18\x18\x18\x18\x1F\x7F\x78\x00", + "Ч": b"\x00\x7F\xFF\xC0\xC0\xC0\xC0\xC0\xC0\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "Ш": b"\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x3F\x3F\x30\x30\x3F\x3F\x30\x30\x3F\x3F\x00", + "Щ": b"\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x1F\x1F\x18\x18\x1F\x1F\x18\x18\x1F\x7F\x70", + "Ъ": b"\x03\x03\xFF\xFF\xC0\xC0\xC0\xC0\xC0\x80\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x39\x1F\x0F\x00", + "Ы": b"\x00\xFF\xFF\xC0\xC0\xC0\xC0\x80\x00\x00\xFF\xFF\x00\x3F\x3F\x30\x30\x30\x39\x1F\x0F\x00\x3F\x3F", + "Ь": b"\x00\xFF\xFF\xC0\xC0\xC0\xC0\xC0\xC0\x80\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x39\x1F\x0F\x00", + "Э": b"\x00\x0C\x0E\x07\xC3\xC3\xC3\xC7\xCE\xFC\xF8\x00\x00\x0C\x1C\x38\x30\x30\x30\x38\x1C\x0F\x07\x00", + "Ю": b"\x00\xFF\xFF\xC0\xFC\xFE\x07\x03\x07\xFE\xFC\x00\x00\x3F\x3F\x00\x0F\x1F\x38\x30\x38\x1F\x0F\x00", + "Я": b"\x00\x7C\xFE\xC7\x83\x83\x83\x83\x83\xFF\xFF\x00\x00\x30\x38\x1D\x0F\x07\x03\x01\x01\x3F\x3F\x00", + "а": b"\x00\x00\x30\x30\x30\x30\x30\x30\x30\xF0\xE0\x00\x00\x1E\x3F\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "б": b"\x00\xE0\xF0\x30\x30\x30\x30\x30\x30\x30\x00\x00\x00\x1F\x3F\x33\x33\x33\x33\x33\x33\x3F\x1E\x00", + "в": b"\x00\xF0\xF0\x30\x30\x30\x30\x30\xF0\xE0\x00\x00\x00\x3F\x3F\x33\x33\x33\x33\x33\x33\x3F\x1E\x00", + "г": b"\x00\xF0\xF0\x30\x30\x30\x30\x30\x30\x30\x30\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "ґ": b"\x00\xF0\xF0\x30\x30\x30\x30\x30\x30\x3C\x3C\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "д": b"\x00\x00\xC0\xE0\x70\x30\x30\x30\xF0\xF0\x00\x00\x00\x60\x7F\x3F\x30\x30\x30\x30\x3F\x7F\x60\x00", + "е": b"\x00\xE0\xF0\x30\x30\x30\x30\x30\x30\xF0\xE0\x00\x00\x1F\x3F\x33\x33\x33\x33\x33\x33\x33\x33\x00", + "ж": b"\x00\x30\xF0\xC0\x00\xF0\xF0\x00\xC0\xF0\x30\x00\x00\x30\x3C\x0F\x03\x3F\x3F\x03\x0F\x3C\x30\x00", + "з": b"\x00\x60\x70\x30\x30\x30\x30\x30\x30\xF0\xE0\x00\x00\x18\x38\x30\x33\x33\x33\x33\x33\x3F\x1D\x00", + "и": b"\x00\xF0\xF0\x00\x00\x00\x80\xC0\xE0\xF0\xF0\x00\x00\x3F\x3F\x1C\x0E\x07\x03\x01\x00\x3F\x3F\x00", + "й": b"\x00\xF0\xF0\x00\x04\x08\x88\xC4\xE0\xF0\xF0\x00\x00\x3F\x3F\x1C\x0E\x07\x03\x01\x00\x3F\x3F\x00", + "к": b"\x00\xF0\xF0\x80\x80\xC0\xE0\x70\x30\x10\x00\x00\x00\x3F\x3F\x03\x03\x07\x0E\x1C\x38\x30\x20\x00", + "л": b"\x00\x00\xC0\xE0\x70\x30\x30\x30\x30\xF0\xF0\x00\x00\x30\x3F\x1F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "м": b"\x00\xF0\xF0\xE0\xC0\x80\x80\xC0\xE0\xF0\xF0\x00\x00\x3F\x3F\x00\x01\x03\x03\x01\x00\x3F\x3F\x00", + "н": b"\x00\xF0\xF0\x00\x00\x00\x00\x00\x00\xF0\xF0\x00\x00\x3F\x3F\x03\x03\x03\x03\x03\x03\x3F\x3F\x00", + "о": b"\x00\xC0\xE0\x70\x30\x30\x30\x30\x70\xE0\xC0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "п": b"\x00\xF0\xF0\x30\x30\x30\x30\x30\x30\xF0\xF0\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "р": b"\x00\xF0\xF0\x30\x30\x30\x30\x30\x70\xE0\xC0\x00\x00\xFF\xFF\x0C\x0C\x0C\x0C\x0C\x0E\x07\x03\x00", + "с": b"\x00\xC0\xE0\x70\x30\x30\x30\x30\x70\x60\x40\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x18\x08\x00", + "т": b"\x00\x30\x30\x30\x30\xF0\xF0\x30\x30\x30\x30\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "у": b"\x00\x30\xF0\xC0\x00\x00\x00\x00\xC0\xF0\x30\x00\x00\x60\xE0\xC3\xE7\x7C\x3C\x0F\x03\x00\x00\x00", + "ф": b"\x00\x80\xC0\x60\x60\xF0\xF0\x60\x60\xC0\x80\x00\x00\x0F\x1F\x30\x30\xFF\xFF\x30\x30\x1F\x0F\x00", + "х": b"\x00\x30\x70\xC0\x80\x00\x00\x80\xC0\x70\x30\x00\x00\x30\x38\x0C\x07\x03\x03\x07\x0C\x38\x30\x00", + "ц": b"\x00\xF0\xF0\x00\x00\x00\x00\x00\xF0\xF0\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x3F\xFF\xF0\x00", + "ч": b"\x00\xF0\xF0\x00\x00\x00\x00\x00\x00\xF0\xF0\x00\x00\x01\x03\x03\x03\x03\x03\x03\x03\x3F\x3F\x00", + "ш": b"\x00\xF0\xF0\x00\x00\xE0\xE0\x00\x00\xF0\xF0\x00\x00\x3F\x3F\x30\x30\x3F\x3F\x30\x30\x3F\x3F\x00", + "щ": b"\x00\xF0\xF0\x00\x00\xF0\xF0\x00\x00\xF0\xF0\x00\x00\x3F\x3F\x30\x30\x3F\x3F\x30\x30\x3F\xFF\xE0", + "ъ": b"\x30\x30\xF0\xF0\x80\x80\x80\x80\x80\x00\x00\x00\x00\x00\x3F\x3F\x31\x31\x31\x31\x3B\x1F\x0E\x00", + "ы": b"\x00\xF0\xF0\x80\x80\x80\x00\x00\x00\xF0\xF0\x00\x00\x3F\x3F\x31\x31\x3B\x1F\x0E\x00\x3F\x3F\x00", + "ь": b"\x00\xF0\xF0\x80\x80\x80\x80\x80\x80\x00\x00\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x3B\x1F\x0E\x00", + "э": b"\x00\x40\x60\x70\x30\x30\x30\x30\x70\xE0\xC0\x00\x00\x08\x18\x38\x30\x33\x33\x33\x3B\x1F\x0F\x00", + "ю": b"\x00\xF0\xF0\x00\xE0\xF0\x30\x30\x30\xF0\xE0\x00\x00\x3F\x3F\x03\x1F\x3F\x30\x30\x30\x3F\x1F\x00", + "я": b"\x00\xC0\xE0\x70\x30\x30\x30\x30\x30\xF0\xF0\x00\x00\x21\x33\x3B\x1E\x0E\x06\x06\x06\x3F\x3F\x00", + "ѐ": b"\x00\xE0\xF0\x32\x36\x36\x34\x30\x30\xF0\xE0\x00\x00\x1F\x3F\x33\x33\x33\x33\x33\x33\x33\x33\x00", + "ё": b"\x00\xE0\xF0\x34\x34\x30\x30\x34\x34\xF0\xE0\x00\x00\x1F\x3F\x33\x33\x33\x33\x33\x33\x33\x33\x00", + "ђ": b"\x00\x30\xFC\xFC\x30\xB0\xB0\xB0\x80\x80\x00\x00\x00\x00\x3F\x3F\x07\x03\x01\x01\xC1\xFF\x3F\x00", + "ѓ": b"\x00\xF0\xF0\x30\x30\x34\x36\x32\x30\x30\x30\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "є": b"\x00\xC0\xE0\x70\x30\x30\x30\x30\x70\x60\x40\x00\x00\x0F\x1F\x3B\x33\x33\x33\x30\x38\x18\x08\x00", + "ѕ": b"\x00\xE0\xF0\xB0\xB0\x30\x30\x30\x30\x70\x60\x00\x00\x18\x39\x31\x33\x33\x33\x37\x36\x3E\x1C\x00", + "і": b"\x00\x00\x00\x00\x30\xF6\xF6\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ї": b"\x00\x00\x00\x04\x34\xF0\xF4\x04\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ј": b"\x00\x00\x00\x00\x00\x30\x30\xF6\xF6\x00\x00\x00\x00\x00\x00\x60\xE0\xC0\xC0\xFF\x7F\x00\x00\x00", + "љ": b"\x00\x00\xE0\xF0\x30\x30\xF0\xF0\x00\x00\x00\x00\x00\x30\x3F\x1F\x00\x00\x3F\x3F\x33\x33\x1E\x0C", + "њ": b"\x00\xF0\xF0\x00\x00\x00\xF0\xF0\x00\x00\x00\x00\x00\x3F\x3F\x03\x03\x03\x3F\x3F\x33\x33\x1E\x0C", + "ћ": b"\x00\x30\xFC\xFC\xB0\xB0\xB0\xB0\x80\x80\x00\x00\x00\x00\x3F\x3F\x01\x01\x01\x01\x01\x3F\x3F\x00", + "ќ": b"\x00\xF0\xF0\x80\x88\xCC\xE4\x70\x30\x10\x00\x00\x00\x3F\x3F\x03\x03\x07\x0E\x1C\x38\x30\x20\x00", + "ѝ": b"\x00\xF0\xF0\x00\x06\x0C\x88\xC0\xE0\xF0\xF0\x00\x00\x3F\x3F\x1C\x0E\x07\x03\x01\x00\x3F\x3F\x00", + "ў": b"\x00\x30\xF0\xC0\x04\x08\x08\x04\xC0\xF0\x30\x00\x00\x60\xE0\xC3\xE7\x7C\x3C\x0F\x03\x00\x00\x00", + "џ": b"\x00\xF0\xF0\x00\x00\x00\x00\x00\x00\xF0\xF0\x00\x00\x3F\x3F\x30\x30\xF0\xF0\x30\x30\x3F\x3F\x00", + } + return font + + +def get_small_font_map_ascii_basic() -> Dict[str, bytes]: + font = { + # U+0000..U+007F Basic Latin + " ": b"\x00\x00\x00\x00\x00\x00", + "!": b"\x00\x00\x4f\x00\x00\x00", + '"': b"\x00\x07\x00\x07\x00\x00", + "#": b"\x14\x7f\x14\x7f\x14\x00", + "$": b"\x24\x2a\x7f\x2a\x12\x00", + "%": b"\x23\x13\x08\x64\x62\x00", + "&": b"\x36\x49\x56\x20\x58\x00", + "'": b"\x00\x05\x03\x00\x00\x00", + "(": b"\x00\x1c\x22\x41\x00\x00", + ")": b"\x00\x41\x22\x1c\x00\x00", + "*": b"\x14\x08\x3e\x08\x14\x00", + "+": b"\x08\x08\x3e\x08\x08\x00", + ",": b"\x00\x50\x30\x00\x00\x00", + "-": b"\x08\x08\x08\x08\x08\x00", + ".": b"\x00\x60\x60\x00\x00\x00", + "/": b"\x20\x10\x08\x04\x02\x00", + "0": b"\x3e\x51\x49\x45\x3e\x00", + "1": b"\x00\x42\x7f\x40\x00\x00", + "2": b"\x42\x61\x51\x49\x46\x00", + "3": b"\x21\x41\x45\x4b\x31\x00", + "4": b"\x18\x14\x12\x7f\x10\x00", + "5": b"\x27\x45\x45\x45\x39\x00", + "6": b"\x3c\x4a\x49\x49\x30\x00", + "7": b"\x01\x71\x09\x05\x03\x00", + "8": b"\x36\x49\x49\x49\x36\x00", + "9": b"\x06\x49\x49\x29\x1e\x00", + ":": b"\x00\x36\x36\x00\x00\x00", + ";": b"\x00\x56\x36\x00\x00\x00", + "<": b"\x08\x14\x22\x41\x00\x00", + "=": b"\x14\x14\x14\x14\x14\x00", + ">": b"\x00\x41\x22\x14\x08\x00", + "?": b"\x02\x01\x51\x09\x06\x00", + "@": b"\x32\x49\x79\x41\x3e\x00", + "A": b"\x7e\x09\x09\x09\x7e\x00", + "B": b"\x7f\x49\x49\x49\x36\x00", + "C": b"\x3e\x41\x41\x41\x22\x00", + "D": b"\x7f\x41\x41\x22\x1c\x00", + "E": b"\x7f\x49\x49\x49\x41\x00", + "F": b"\x7f\x09\x09\x09\x01\x00", + "G": b"\x3e\x41\x41\x49\x7a\x00", + "H": b"\x7f\x08\x08\x08\x7f\x00", + "I": b"\x00\x41\x7f\x41\x00\x00", + "J": b"\x20\x40\x41\x3f\x01\x00", + "K": b"\x7f\x08\x14\x22\x41\x00", + "L": b"\x7f\x40\x40\x40\x40\x00", + "M": b"\x7f\x02\x0c\x02\x7f\x00", + "N": b"\x7f\x04\x08\x10\x7f\x00", + "O": b"\x3e\x41\x41\x41\x3e\x00", + "P": b"\x7f\x09\x09\x09\x06\x00", + "Q": b"\x3e\x41\x51\x21\x5e\x00", + "R": b"\x7f\x09\x19\x29\x46\x00", + "S": b"\x26\x49\x49\x49\x32\x00", + "T": b"\x01\x01\x7f\x01\x01\x00", + "U": b"\x3f\x40\x40\x40\x3f\x00", + "V": b"\x1f\x20\x40\x20\x1f\x00", + "W": b"\x3f\x40\x38\x40\x3f\x00", + "X": b"\x63\x14\x08\x14\x63\x00", + "Y": b"\x07\x08\x70\x08\x07\x00", + "Z": b"\x61\x51\x49\x45\x43\x00", + "[": b"\x00\x7f\x41\x41\x00\x00", + "\\": b"\x02\x04\x08\x10\x20\x00", + "]": b"\x00\x41\x41\x7f\x00\x00", + "^": b"\x04\x02\x01\x02\x04\x00", + "_": b"\x40\x40\x40\x40\x40\x00", + "`": b"\x00\x03\x05\x00\x00\x00", + "a": b"\x20\x54\x54\x54\x78\x00", + "b": b"\x7f\x48\x44\x44\x38\x00", + "c": b"\x38\x44\x44\x44\x20\x00", + "d": b"\x38\x44\x44\x48\x7f\x00", + "e": b"\x38\x54\x54\x54\x18\x00", + "f": b"\x00\x04\x7e\x05\x01\x00", + "g": b"\x08\x54\x54\x54\x3c\x00", + "h": b"\x7f\x08\x04\x04\x78\x00", + "i": b"\x00\x44\x7d\x40\x00\x00", + "j": b"\x20\x40\x44\x3d\x00\x00", + "k": b"\x00\x7f\x10\x28\x44\x00", + "l": b"\x00\x41\x7f\x40\x00\x00", + "m": b"\x7c\x04\x78\x04\x78\x00", + "n": b"\x7c\x08\x04\x04\x78\x00", + "o": b"\x38\x44\x44\x44\x38\x00", + "p": b"\x7c\x14\x14\x14\x08\x00", + "q": b"\x08\x14\x14\x14\x7c\x00", + "r": b"\x7c\x08\x04\x04\x08\x00", + "s": b"\x48\x54\x54\x54\x24\x00", + "t": b"\x04\x3e\x44\x40\x20\x00", + "u": b"\x3c\x40\x40\x20\x7c\x00", + "v": b"\x0c\x30\x40\x30\x0c\x00", + "w": b"\x3c\x40\x30\x40\x3c\x00", + "x": b"\x44\x24\x38\x48\x44\x00", + "y": b"\x44\x48\x30\x10\x0c\x00", + "z": b"\x44\x64\x54\x4c\x44\x00", + "{": b"\x08\x36\x41\x00\x00\x00", + "|": b"\x00\x00\x77\x00\x00\x00", + "}": b"\x00\x00\x41\x36\x08\x00", + "~": b"\x02\x01\x02\x04\x02\x00", + } + return font + + +def get_small_font_map_latin_extended() -> Dict[str, bytes]: + font = { + # U+0080..U+00FF Latin-1 Supplement + "¡": b"\x00\x00\x79\x00\x00\x00", + "¢": b"\x1c\x22\x7f\x22\x10\x00", + "£": b"\x50\x7e\x51\x41\x42\x00", + "¤": b"\x22\x1c\x14\x1c\x22\x00", + "¥": b"\x15\x16\x7c\x16\x15\x00", + "¦": b"\x00\x00\x77\x00\x00\x00", + "§": b"\x4a\x55\x55\x55\x29\x00", + "¨": b"\x00\x01\x00\x01\x00\x00", + "©": b"\x00\x18\x24\x24\x00\x00", + "«": b"\x08\x14\x00\x08\x14\x00", + "¬": b"\x08\x08\x08\x08\x38\x00", + "­": b"\x08\x08\x08\x08\x08\x00", + "¯": b"\x00\x01\x01\x01\x00\x00", + "°": b"\x00\x00\x07\x05\x07\x00", + "±": b"\x44\x44\x5f\x44\x44\x00", + "²": b"\x1d\x15\x17\x00\x00\x00", + "³": b"\x15\x15\x1f\x00\x00\x00", + "´": b"\x00\x04\x02\x01\x00\x00", + "µ": b"\x7c\x10\x10\x0c\x10\x00", + "¶": b"\x02\x07\x7f\x01\x7f\x00", + "·": b"\x00\x00\x08\x00\x00\x00", + "¸": b"\x00\x40\x60\x00\x00\x00", + "¹": b"\x12\x1f\x10\x00\x00\x00", + "º": b"\x07\x05\x07\x00\x00\x00", + "»": b"\x14\x08\x00\x14\x08\x00", + "¼": b"\x21\x17\x38\x24\x72\x00", + "½": b"\x21\x17\x78\x54\x5e\x00", + "¿": b"\x30\x48\x45\x40\x20\x00", + "À": b"\x78\x15\x16\x14\x78\x00", + "Á": b"\x78\x14\x16\x15\x78\x00", + "Â": b"\x78\x16\x15\x16\x78\x00", + "Ã": b"\x7a\x29\x2a\x79\x00\x00", + "Ä": b"\x78\x15\x14\x15\x78\x00", + "Å": b"\x78\x14\x15\x14\x78\x00", + "Æ": b"\x7e\x09\x7f\x49\x49\x00", + "Ç": b"\x0e\x51\x71\x11\x08\x00", + "È": b"\x7c\x55\x56\x44\x44\x00", + "É": b"\x7c\x54\x56\x45\x44\x00", + "Ê": b"\x7c\x56\x55\x46\x44\x00", + "Ë": b"\x7c\x55\x54\x45\x44\x00", + "Ì": b"\x00\x49\x7a\x48\x00\x00", + "Í": b"\x00\x48\x7a\x49\x00\x00", + "Î": b"\x00\x4a\x79\x4a\x00\x00", + "Ï": b"\x44\x45\x7c\x45\x44\x00", + "Ð": b"\x08\x7f\x49\x22\x1c\x00", + "Ñ": b"\x7a\x11\x22\x79\x00\x00", + "Ò": b"\x38\x45\x46\x44\x38\x00", + "Ó": b"\x38\x44\x46\x45\x38\x00", + "Ô": b"\x38\x46\x45\x46\x38\x00", + "Õ": b"\x32\x49\x4a\x31\x00\x00", + "Ö": b"\x38\x45\x44\x45\x38\x00", + "×": b"\x22\x14\x08\x14\x22\x00", + "Ø": b"\x58\x24\x54\x48\x34\x00", + "Ù": b"\x38\x41\x42\x40\x38\x00", + "Ú": b"\x38\x40\x42\x41\x38\x00", + "Û": b"\x38\x42\x41\x42\x38\x00", + "Ü": b"\x3c\x41\x40\x41\x3c\x00", + "Ý": b"\x04\x08\x72\x09\x04\x00", + "Þ": b"\x7f\x22\x22\x22\x1c\x00", + "ß": b"\x7e\x11\x25\x25\x1a\x00", + "à": b"\x20\x55\x56\x54\x78\x00", + "á": b"\x20\x54\x56\x55\x78\x00", + "â": b"\x20\x56\x55\x56\x78\x00", + "ã": b"\x22\x55\x56\x55\x78\x00", + "ä": b"\x20\x55\x54\x55\x78\x00", + "å": b"\x20\x54\x55\x54\x78\x00", + "æ": b"\x24\x54\x7c\x54\x48\x00", + "ç": b"\x1c\x22\x62\x22\x10\x00", + "è": b"\x38\x55\x56\x54\x08\x00", + "é": b"\x38\x54\x56\x55\x08\x00", + "ê": b"\x38\x56\x55\x56\x08\x00", + "ë": b"\x38\x55\x54\x55\x08\x00", + "ì": b"\x00\x45\x7e\x40\x00\x00", + "í": b"\x00\x44\x7e\x41\x00\x00", + "î": b"\x00\x46\x7d\x42\x00\x00", + "ï": b"\x00\x45\x7c\x41\x00\x00", + "ñ": b"\x78\x12\x09\x0a\x71\x00", + "ò": b"\x38\x45\x46\x44\x38\x00", + "ó": b"\x38\x44\x46\x45\x38\x00", + "ô": b"\x38\x46\x45\x46\x38\x00", + "õ": b"\x32\x49\x4a\x31\x00\x00", + "ö": b"\x38\x45\x44\x45\x38\x00", + "÷": b"\x08\x08\x2a\x08\x08\x00", + "ø": b"\x58\x24\x54\x48\x34\x00", + "ù": b"\x3c\x41\x42\x20\x7c\x00", + "ú": b"\x3c\x40\x42\x21\x7c\x00", + "û": b"\x3c\x42\x41\x22\x7c\x00", + "ü": b"\x3c\x41\x40\x21\x5c\x00", + "ű": b"\x3c\x41\x40\x21\x5c\x00", + "ų": b"\x3C\x40\x40\x20\xDC\x80", + "ý": b"\x44\x48\x32\x11\x0c\x00", + "þ": b"\x7c\x28\x28\x10\x00\x00", + "ÿ": b"\x44\x49\x30\x11\x0c\x00", + # U+0100..U+017F Latin Extended A + "Ā": b"\x78\x15\x15\x15\x78\x00", + "ā": b"\x20\x55\x55\x55\x78\x00", + "Ă": b"\x78\x15\x16\x15\x78\x00", + "ă": b"\x20\x55\x56\x55\x78\x00", + "Ą": b"\x7e\x09\x09\x49\xbe\x00", + "ą": b"\x20\x54\x54\xd4\x78\x00", + "Ć": b"\x38\x44\x46\x45\x28\x00", + "ć": b"\x38\x44\x46\x45\x20\x00", + "Ĉ": b"\x38\x46\x45\x46\x28\x00", + "ĉ": b"\x38\x46\x45\x46\x20\x00", + "Ċ": b"\x38\x44\x45\x44\x28\x00", + "ċ": b"\x38\x44\x45\x44\x20\x00", + "Č": b"\x38\x45\x46\x45\x28\x00", + "č": b"\x38\x45\x46\x45\x20\x00", + "Ď": b"\x7c\x45\x46\x29\x10\x00", + "ď": b"\x38\x44\x44\x4A\x7F\x00", + "Đ": b"\x08\x7f\x49\x22\x1c\x00", + "đ": b"\x38\x44\x44\x4A\x7F\x00", + "Ē": b"\x7c\x55\x55\x55\x44\x00", + "ē": b"\x38\x55\x55\x55\x08\x00", + "Ĕ": b"\x7c\x55\x56\x55\x44\x00", + "ĕ": b"\x38\x55\x56\x55\x08\x00", + "Ė": b"\x7c\x54\x55\x54\x44\x00", + "ė": b"\x38\x54\x55\x54\x08\x00", + "Ę": b"\x7f\x49\x49\xc9\x41\x00", + "ę": b"\x38\x54\x54\xd4\x18\x00", + "Ě": b"\x7c\x55\x56\x55\x44\x00", + "ě": b"\x38\x55\x56\x55\x08\x00", + "Ĝ": b"\x38\x46\x55\x56\x70\x00", + "ĝ": b"\x08\x56\x55\x56\x3c\x00", + "Ğ": b"\x38\x45\x56\x55\x30\x00", + "ğ": b"\x08\x55\x56\x55\x3c\x00", + "Ġ": b"\x38\x44\x55\x54\x30\x00", + "ġ": b"\x08\x54\x55\x54\x3c\x00", + "Ģ": b"\x0e\x51\x35\x15\x1c\x00", + "Ĥ": b"\x7c\x12\x11\x12\x7c\x00", + "ĥ": b"\x02\x79\x22\x10\x60\x00", + "Ħ": b"\x02\x7f\x0a\x7f\x02\x00", + "ħ": b"\x02\x7f\x12\x08\x70\x00", + "Ĩ": b"\x4a\x49\x7a\x49\x48\x00", + "ĩ": b"\x02\x49\x7a\x41\x00\x00", + "Ī": b"\x44\x45\x7d\x45\x44\x00", + "ī": b"\x00\x45\x7d\x41\x00\x00", + "Ĭ": b"\x44\x45\x7e\x45\x44\x00", + "ĭ": b"\x00\x45\x7e\x41\x00\x00", + "Į": b"\x00\x41\x7f\xc1\x00\x00", + "į": b"\x00\x44\x7d\xc0\x00\x00", + "İ": b"\x44\x44\x7d\x44\x44\x00", + "ı": b"\x00\x44\x7c\x40\x00\x00", + "ij": b"\x44\x7d\x40\x44\x3d\x00", + "Ĵ": b"\x20\x40\x46\x3d\x06\x00", + "ĵ": b"\x00\x20\x46\x3d\x02\x00", + "Ķ": b"\x1f\x44\x2a\x11\x00\x00", + "ķ": b"\x1f\x44\x2a\x11\x00\x00", + "ĸ": b"\x7c\x10\x28\x44\x00\x00", + "Ĺ": b"\x7c\x40\x42\x41\x40\x00", + "Ľ": b"\x7c\x40\x42\x41\x40\x00", + "ĺ": b"\x00\x44\x7e\x41\x00\x00", + "Ļ": b"\x1f\x50\x30\x10\x10\x00", + "ļ": b"\x00\x51\x3f\x10\x00\x00", + "ľ": b"\x00\x41\x7f\x40\x03\x00", + "Ŀ": b"\x7f\x40\x40\x48\x40\x00", + "ŀ": b"\x00\x41\x7f\x40\x08\x00", + "Ł": b"\x10\x7F\x48\x44\x40\x00", + "ł": b"\x00\x49\x7F\x44\x00\x00", + "Ń": b"\x7c\x08\x12\x21\x7c\x00", + "ń": b"\x7c\x08\x06\x05\x78\x00", + "Ņ": b"\x1f\x42\x24\x08\x1f\x00", + "ņ": b"\x1f\x42\x21\x01\x1e\x00", + "Ň": b"\x7c\x09\x12\x21\x7c\x00", + "ň": b"\x7c\x09\x06\x05\x78\x00", + "Ō": b"\x38\x45\x45\x45\x38\x00", + "ō": b"\x38\x45\x45\x45\x38\x00", + "Ŏ": b"\x38\x45\x46\x45\x38\x00", + "ŏ": b"\x38\x45\x46\x45\x38\x00", + "ő": b"\x38\x45\x44\x45\x38\x00", + "Œ": b"\x3e\x41\x7f\x49\x49\x00", + "œ": b"\x38\x44\x7c\x54\x58\x00", + "Ŕ": b"\x7c\x14\x16\x15\x68\x00", + "ŕ": b"\x7c\x08\x06\x05\x08\x00", + "Ŗ": b"\x1f\x45\x25\x05\x1a\x00", + "ŗ": b"\x1f\x42\x21\x01\x02\x00", + "Ř": b"\x7c\x15\x16\x15\x68\x00", + "ř": b"\x7c\x09\x06\x05\x08\x00", + "Ś": b"\x08\x54\x56\x55\x20\x00", + "ś": b"\x48\x54\x56\x55\x24\x00", + "Ŝ": b"\x08\x56\x55\x56\x20\x00", + "ŝ": b"\x48\x56\x55\x56\x24\x00", + "Ş": b"\x02\x55\x35\x15\x08\x00", + "ş": b"\x12\x55\x35\x15\x09\x00", + "Š": b"\x08\x55\x56\x55\x20\x00", + "š": b"\x48\x55\x56\x55\x24\x00", + "Ţ": b"\x01\x41\x3f\x01\x01\x00", + "ţ": b"\x02\x4f\x32\x10\x08\x00", + "Ť": b"\x04\x05\x7e\x05\x04\x00", + "ť": b"\x04\x3e\x44\x40\x23\x00", + "Ŧ": b"\x01\x09\x7f\x09\x01\x00", + "ŧ": b"\x14\x3e\x54\x40\x20\x00", + "Ū": b"\x3c\x41\x41\x41\x3c\x00", + "ū": b"\x3c\x41\x41\x21\x7c\x00", + "Ŭ": b"\x3c\x41\x42\x41\x3c\x00", + "ŭ": b"\x3c\x41\x41\x21\x7c\x00", + "Ů": b"\x3c\x40\x41\x40\x3c\x00", + "ů": b"\x3c\x41\x41\x21\x7c\x00", + "Ŵ": b"\x3c\x42\x39\x42\x3c\x00", + "ŵ": b"\x3c\x42\x31\x42\x3c\x00", + "Ŷ": b"\x04\x0a\x71\x0a\x04\x00", + "ŷ": b"\x04\x4a\x31\x12\x0c\x00", + "Ÿ": b"\x04\x09\x70\x09\x04\x00", + "Ź": b"\x44\x64\x56\x4d\x44\x00", + "ź": b"\x44\x64\x56\x4d\x44\x00", + "Ż": b"\x44\x64\x55\x4c\x44\x00", + "ż": b"\x44\x64\x55\x4c\x44\x00", + "Ž": b"\x44\x65\x56\x4d\x44\x00", + "ž": b"\x44\x65\x56\x4d\x44\x00", + "ſ": b"\x00\x04\x7e\x01\x01\x00", + } + return font + + +def get_small_font_map_cyrillic() -> Dict[str, bytes]: + font = { + # U+0400..U+04FF Cyrillic + "Ѐ": b"\x7c\x55\x56\x44\x44\x00", + "Ё": b"\x7c\x55\x54\x45\x44\x00", + "Ђ": b"\x01\x7f\x09\x49\x31\x00", + "Ѓ": b"\x7c\x04\x06\x05\x04\x00", + "Є": b"\x3e\x49\x49\x41\x00\x00", + "Ѕ": b"\x06\x49\x49\x49\x30\x00", + "І": b"\x41\x41\x7f\x41\x41\x00", + "Ї": b"\x44\x45\x7c\x45\x44\x00", + "Ј": b"\x20\x40\x41\x3f\x01\x00", + "Љ": b"\x7f\x01\x7f\x48\x30\x00", + "Њ": b"\x7f\x08\x7f\x48\x30\x00", + "Ћ": b"\x01\x01\x7f\x09\x71\x00", + "Ќ": b"\x7c\x12\x29\x44\x00\x00", + "Ѝ": b"\x7c\x21\x12\x08\x7c\x00", + "Ў": b"\x44\x49\x32\x09\x04\x00", + "Џ": b"\x3f\x20\x60\x20\x3f\x00", + "А": b"\x7e\x09\x09\x09\x7e\x00", + "Б": b"\x7f\x49\x49\x49\x31\x00", + "В": b"\x7f\x49\x49\x49\x36\x00", + "Г": b"\x7f\x01\x01\x01\x01\x00", + "Ґ": b"\x7E\x02\x02\x02\x03\x00", + "Д": b"\x60\x3f\x21\x3f\x60\x00", + "Е": b"\x7f\x49\x49\x49\x41\x00", + "Ж": b"\x77\x08\x7f\x08\x77\x00", + "З": b"\x00\x41\x49\x49\x36\x00", + "И": b"\x7f\x10\x08\x04\x7f\x00", + "Й": b"\x7c\x21\x12\x09\x7c\x00", + "К": b"\x7f\x08\x14\x22\x41\x00", + "Л": b"\x40\x3f\x01\x01\x7f\x00", + "М": b"\x7f\x02\x04\x02\x7f\x00", + "Н": b"\x7f\x08\x08\x08\x7f\x00", + "О": b"\x3e\x41\x41\x41\x3e\x00", + "П": b"\x7f\x01\x01\x01\x7f\x00", + "Р": b"\x7f\x09\x09\x09\x06\x00", + "С": b"\x3e\x41\x41\x41\x22\x00", + "Т": b"\x01\x01\x7f\x01\x01\x00", + "У": b"\x47\x48\x30\x08\x07\x00", + "Ф": b"\x0c\x12\x7f\x12\x0c\x00", + "Х": b"\x63\x14\x08\x14\x63\x00", + "Ц": b"\x3f\x20\x20\x3f\x60\x00", + "Ч": b"\x07\x08\x08\x08\x7f\x00", + "Ш": b"\x7F\x40\x7F\x40\x7F\x00", + "Щ": b"\x7F\x40\x7F\x40\x7F\xC0", + "Ъ": b"\x01\x7f\x48\x48\x30\x00", + "Ы": b"\x7f\x48\x30\x00\x7f\x00", + "Ь": b"\x00\x7f\x48\x48\x30\x00", + "Э": b"\x22\x49\x49\x2a\x1c\x00", + "Ю": b"\x7f\x08\x3e\x41\x3e\x00", + "Я": b"\x46\x29\x19\x09\x7f\x00", + "а": b"\x20\x54\x54\x54\x78\x00", + "б": b"\x3c\x4a\x4a\x4a\x30\x00", + "в": b"\x7c\x54\x54\x54\x28\x00", + "г": b"\x7c\x04\x04\x04\x04\x00", + "ґ": b"\x7C\x04\x04\x04\x06\x00", + "д": b"\x40\x3c\x24\x3c\x60\x00", + "е": b"\x38\x54\x54\x54\x18\x00", + "ж": b"\x6c\x10\x7c\x10\x6c\x00", + "з": b"\x28\x44\x54\x54\x28\x00", + "и": b"\x7c\x20\x10\x08\x7c\x00", + "й": b"\x7c\x21\x12\x09\x7c\x00", + "к": b"\x7c\x10\x28\x44\x00\x00", + "л": b"\x40\x3c\x04\x04\x7c\x00", + "м": b"\x7c\x08\x10\x08\x7c\x00", + "н": b"\x7c\x10\x10\x10\x7c\x00", + "о": b"\x38\x44\x44\x44\x38\x00", + "п": b"\x7c\x04\x04\x04\x7c\x00", + "р": b"\x7c\x14\x14\x14\x08\x00", + "с": b"\x38\x44\x44\x44\x20\x00", + "т": b"\x04\x04\x7c\x04\x04\x00", + "у": b"\x4c\x50\x20\x10\x0c\x00", + "ф": b"\x18\x24\x7e\x24\x18\x00", + "х": b"\x44\x28\x10\x28\x44\x00", + "ц": b"\x3c\x20\x20\x3c\x60\x00", + "ч": b"\x0c\x10\x10\x10\x7c\x00", + "ш": b"\x7C\x40\x7C\x40\x7C\x00", + "щ": b"\x7C\x40\x7C\x40\xFC\x00", + "ъ": b"\x04\x7c\x50\x20\x00\x00", + "ы": b"\x7c\x50\x20\x00\x7c\x00", + "ь": b"\x00\x7c\x50\x20\x00\x00", + "э": b"\x28\x44\x54\x54\x28\x00", + "ю": b"\x7c\x10\x38\x44\x38\x00", + "я": b"\x48\x34\x14\x14\x7c\x00", + "ѐ": b"\x38\x55\x56\x54\x08\x00", + "ё": b"\x38\x55\x54\x55\x08\x00", + "ђ": b"\x02\x3f\x12\x48\x30\x00", + "ѓ": b"\x7c\x04\x06\x05\x04\x00", + "є": b"\x38\x54\x54\x44\x28\x00", + "ѕ": b"\x08\x54\x54\x54\x20\x00", + "і": b"\x00\x44\x7d\x40\x00\x00", + "ї": b"\x00\x45\x7c\x41\x00\x00", + "ј": b"\x20\x40\x44\x3d\x00\x00", + "љ": b"\x7c\x04\x7c\x50\x20\x00", + "њ": b"\x7c\x10\x7c\x50\x20\x00", + "ћ": b"\x04\x7e\x14\x10\x60\x00", + "ќ": b"\x7c\x12\x29\x44\x00\x00", + "ѝ": b"\x7c\x21\x12\x08\x7c\x00", + "ў": b"\x4c\x51\x22\x11\x0c\x00", + "џ": b"\x3c\x20\x60\x20\x3c\x00", + } + return font + + +NAME_ASCII_BASIC: Final = "ascii_basic" +NAME_LATIN_EXTENDED: Final = "latin_extended" +NAME_CYRILLIC: Final = "cyrillic" +NAME_CJK: Final = "cjk" + + +def get_font_maps_for_name( + font_name: str, +) -> Tuple[Dict[str, bytes], Dict[str, bytes]]: + if font_name == NAME_ASCII_BASIC: + return get_font_map_ascii_basic(), get_small_font_map_ascii_basic() + elif font_name == NAME_LATIN_EXTENDED: + return get_font_map_latin_extended(), get_small_font_map_latin_extended() + elif font_name == NAME_CYRILLIC: + return get_font_map_cyrillic(), get_small_font_map_cyrillic() + else: + raise ValueError("Invalid font name") diff --git a/Translations/lzfx.py b/Translations/lzfx.py new file mode 100644 index 00000000..9f389673 --- /dev/null +++ b/Translations/lzfx.py @@ -0,0 +1,91 @@ +import ctypes +import functools +import os +from pathlib import Path + +HERE = Path(__file__).resolve().parent + + +@functools.lru_cache(maxsize=None) +def _liblzfx(): + so_path = os.path.join(HERE, "../source/Objects/host/lzfx/liblzfx.so") + liblzfx = ctypes.cdll.LoadLibrary(so_path) + return liblzfx + + +@functools.lru_cache(maxsize=None) +def _fn_lzfx_compress(): + """Returns the lzfx_compress C function. + :: + + /* Buffer-to buffer compression. + + Supply pre-allocated input and output buffers via ibuf and obuf, and + their size in bytes via ilen and olen. Buffers may not overlap. + + On success, the function returns a non-negative value and the argument + olen contains the compressed size in bytes. On failure, a negative + value is returned and olen is not modified. + */ + int lzfx_compress(const void* ibuf, unsigned int ilen, + void* obuf, unsigned int *olen); + """ + + fn = _liblzfx().lzfx_compress + fn.argtype = [ + ctypes.c_char_p, + ctypes.c_uint, + ctypes.c_char_p, + ctypes.POINTER(ctypes.c_uint), + ] + fn.restype = ctypes.c_int + return fn + + +def compress(data: bytes) -> bytes: + """Returns a bytes object of the lzfx-compressed data.""" + + fn_compress = _fn_lzfx_compress() + + output_buffer_len = len(data) + 8 + + ibuf = data + ilen = len(ibuf) + obuf = ctypes.create_string_buffer(output_buffer_len) + olen = ctypes.c_uint(output_buffer_len) + + res = fn_compress(ibuf, ilen, obuf, ctypes.byref(olen)) + + if res < 0: + raise LzfxError(res) + else: + return bytes(obuf[: olen.value]) # type: ignore + + +class LzfxError(Exception): + """Exception raised for lzfx compression or decompression error. + + Attributes: + error_code -- The source error code, which is a negative integer + error_name -- The constant name of the error + message -- explanation of the error + """ + + # define LZFX_ESIZE -1 /* Output buffer too small */ + # define LZFX_ECORRUPT -2 /* Invalid data for decompression */ + # define LZFX_EARGS -3 /* Arguments invalid (NULL) */ + + def __init__(self, error_code): + self.error_code = error_code + if error_code == -1: + self.error_name = "LZFX_ESIZE" + self.message = "Output buffer too small" + elif error_code == -2: + self.error_name = "LZFX_ECORRUPT" + self.message = "Invalid data for decompression" + elif error_code == -3: + self.error_name = "LZFX_EARGS" + self.message = "Arguments invalid (NULL)" + else: + self.error_name = "UNKNOWN" + self.message = "Unknown error" diff --git a/Translations/make_translation.py b/Translations/make_translation.py index 296fc9a3..4eb7a3b7 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -5,19 +5,21 @@ import functools import json import logging import os +import pickle import re import subprocess import sys from datetime import datetime from itertools import chain from pathlib import Path -from typing import Dict, List, Optional, TextIO, Tuple, Union +from typing import BinaryIO, Dict, List, Optional, TextIO, Tuple, Union from dataclasses import dataclass from bdflib import reader as bdfreader from bdflib.model import Font, Glyph import font_tables +import lzfx logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) @@ -79,7 +81,7 @@ def write_start(f: TextIO): f.write('#include "Translation.h"\n') -def get_constants() -> List[Tuple[str, str]]: +def get_constants(build_version: str) -> List[Tuple[str, str]]: # Extra constants that are used in the firmware that are shared across all languages return [ ("SymbolPlus", "+"), @@ -94,7 +96,7 @@ def get_constants() -> List[Tuple[str, str]]: ("SymbolVolts", "V"), ("SymbolDC", "DC"), ("SymbolCellCount", "S"), - ("SymbolVersionNumber", buildVersion), + ("SymbolVersionNumber", build_version), ] @@ -116,7 +118,7 @@ def get_debug_menu() -> List[str]: ] -def get_letter_counts(defs: dict, lang: dict) -> List[str]: +def get_letter_counts(defs: dict, lang: dict, build_version: str) -> List[str]: text_list = [] # iterate over all strings obj = lang["menuOptions"] @@ -169,7 +171,7 @@ def get_letter_counts(defs: dict, lang: dict) -> List[str]: for mod in defs["menuGroups"]: eid = mod["id"] text_list.append(obj[eid]["desc"]) - constants = get_constants() + constants = get_constants(build_version) for x in constants: text_list.append(x[1]) text_list.extend(get_debug_menu()) @@ -191,7 +193,7 @@ def get_letter_counts(defs: dict, lang: dict) -> List[str]: return symbols_by_occurrence -def get_cjk_glyph(sym: str) -> str: +def get_cjk_glyph(sym: str) -> bytes: glyph: Glyph = cjk_font()[ord(sym)] data = glyph.data @@ -224,15 +226,15 @@ def get_cjk_glyph(sym: str) -> str: # top-most pixel. The data goes from the left-most to the right-most column # of the top half, then from the left-most to the right-most column of the # bottom half. - s = "" + bs = bytearray() for block in range(2): for c in range(dst_w): b = 0 for r in range(8): if get_cell(c, r + 8 * block): b |= 0x01 << r - s += f"0x{b:02X}," - return s + bs.append(b) + return bytes(bs) def get_bytes_from_font_index(index: int) -> bytes: @@ -290,90 +292,173 @@ def bytes_to_escaped(b: bytes) -> str: return "".join((f"\\x{i:02X}" for i in b)) -def get_font_map_and_table(text_list: List[str]) -> Tuple[str, Dict[str, bytes]]: +def bytes_to_c_hex(b: bytes) -> str: + return ", ".join((f"0x{i:02X}" for i in b)) + "," + + +@dataclass +class FontMap: + font12: Dict[str, bytes] + font06: Dict[str, Optional[bytes]] + + +@dataclass +class FontMapsPerFont: + font12_maps: Dict[str, Dict[str, bytes]] + font06_maps: Dict[str, Dict[str, Optional[bytes]]] + sym_lists: Dict[str, List[str]] + + +def get_font_map_per_font(text_list: List[str], fonts: List[str]) -> FontMapsPerFont: + pending_sym_set = set(text_list) + if len(pending_sym_set) != len(text_list): + raise ValueError("`text_list` contains duplicated symbols") + + if fonts[0] != font_tables.NAME_ASCII_BASIC: + raise ValueError( + f'First item in `fonts` must be "{font_tables.NAME_ASCII_BASIC}"' + ) + + total_symbol_count = len(text_list) + # \x00 is for NULL termination and \x01 is for newline, so the maximum + # number of symbols allowed is as follow (see also the comments in + # `get_bytes_from_font_index`): + if total_symbol_count > (0x10 * 0xFF - 15) - 2: # 4063 + raise ValueError( + f"Error, too many used symbols for this version (total {total_symbol_count})" + ) + + logging.info(f"Generating fonts for {total_symbol_count} symbols") + + # Collect font bitmaps by the defined font order: + font12_maps: Dict[str, Dict[str, bytes]] = {} + font06_maps: Dict[str, Dict[str, Optional[bytes]]] = {} + sym_lists: Dict[str, List[str]] = {} + for font in fonts: + font12_maps[font] = {} + font12_map = font12_maps[font] + font06_maps[font] = {} + font06_map = font06_maps[font] + sym_lists[font] = [] + sym_list = sym_lists[font] + + if len(pending_sym_set) == 0: + logging.warning( + f"Font {font} not used because all symbols already have font bitmaps" + ) + continue + + if font == font_tables.NAME_CJK: + is_cjk = True + else: + is_cjk = False + font12: Dict[str, bytes] + font06: Dict[str, bytes] + font12, font06 = font_tables.get_font_maps_for_name(font) + + for sym in text_list: + if sym not in pending_sym_set: + continue + if is_cjk: + font12_line = get_cjk_glyph(sym) + if font12_line is None: + continue + font06_line = None + else: + try: + font12_line = font12[sym] + font06_line = font06[sym] + except KeyError: + continue + font12_map[sym] = font12_line + font06_map[sym] = font06_line + sym_list.append(sym) + pending_sym_set.remove(sym) + + if len(sym_list) == 0: + logging.warning(f"Font {font} not used by any symbols on the list") + if len(pending_sym_set) > 0: + raise KeyError(f"Symbols not found in specified fonts: {pending_sym_set}") + + return FontMapsPerFont(font12_maps, font06_maps, sym_lists) + + +def get_font_map_and_table( + text_list: List[str], fonts: List[str] +) -> Tuple[List[str], FontMap, Dict[str, bytes]]: # the text list is sorted # allocate out these in their order as number codes symbol_map: Dict[str, bytes] = {"\n": bytes([1])} index = 2 # start at 2, as 0= null terminator,1 = new line forced_first_symbols = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] - # Get the font table, which does not include CJK chars - font_table = font_tables.get_font_map() - font_small_table = font_tables.get_small_font_map() - - # We want to put all CJK chars after non-CJK ones so that the CJK chars - # do not need to be in the small font table to save space. - # We assume all symbols not in the font table to be a CJK char. - # We also enforce that numbers are first. - ordered_normal_sym_list: List[str] = forced_first_symbols + [ - x for x in text_list if x not in forced_first_symbols and x in font_table - ] - ordered_cjk_sym_list: List[str] = [ - x for x in text_list if x not in forced_first_symbols and x not in font_table + # We enforce that numbers come first. + text_list = forced_first_symbols + [ + x for x in text_list if x not in forced_first_symbols ] - total_symbol_count = len(ordered_normal_sym_list) + len(ordered_cjk_sym_list) - # \x00 is for NULL termination and \x01 is for newline, so the maximum - # number of symbols allowed is as follow (see also the comments in - # `get_bytes_from_font_index`): - if total_symbol_count > (0x10 * 0xFF - 15) - 2: # 4063 - logging.error( - f"Error, too many used symbols for this version (total {total_symbol_count})" - ) - sys.exit(1) + font_maps = get_font_map_per_font(text_list, fonts) + font12_maps = font_maps.font12_maps + font06_maps = font_maps.font06_maps - logging.info(f"Generating fonts for {total_symbol_count} symbols") + # Build the full font maps + font12_map = {} + font06_map = {} + for font in fonts: + font12_map.update(font12_maps[font]) + font06_map.update(font06_maps[font]) - for sym in chain(ordered_normal_sym_list, ordered_cjk_sym_list): - if sym in symbol_map: - raise ValueError("Symbol not found in symbol map") + # Collect all symbols by the original symbol order, but also making sure + # all symbols with only large font must be placed after all symbols with + # both small and large fonts + sym_list_both_fonts = [] + sym_list_large_only = [] + for sym in text_list: + if font06_map[sym] is None: + sym_list_large_only.append(sym) + else: + sym_list_both_fonts.append(sym) + sym_list = sym_list_both_fonts + sym_list_large_only + + # Assign symbol bytes by font index + for index, sym in enumerate(sym_list, index): + assert sym not in symbol_map symbol_map[sym] = get_bytes_from_font_index(index) - index += 1 - font_table_strings = [] - font_small_table_strings = [] - for sym in ordered_normal_sym_list: - if sym not in font_table: - logging.error(f"Missing Large font element for {sym}") - sys.exit(1) - font_line: str = font_table[sym] - font_table_strings.append( - f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}" - ) - if sym not in font_small_table: - logging.error(f"Missing Small font element for {sym}") - sys.exit(1) - font_line = font_small_table[sym] - font_small_table_strings.append( - f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}" - ) + return sym_list, FontMap(font12_map, font06_map), symbol_map - for sym in ordered_cjk_sym_list: - if sym in font_table: - raise ValueError("Symbol already exists in font_table") - font_line = get_cjk_glyph(sym) - if font_line is None: - logging.error(f"Missing Large font element for {sym}") - sys.exit(1) - font_table_strings.append( - f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}" - ) - # No data to add to the small font table - font_small_table_strings.append( - f"// {bytes_to_escaped(symbol_map[sym])} -> {sym}" - ) +def make_font_table_cpp( + sym_list: List[str], font_map: FontMap, symbol_map: Dict[str, bytes] +) -> str: + output_table = make_font_table_12_cpp(sym_list, font_map, symbol_map) + output_table += make_font_table_06_cpp(sym_list, font_map, symbol_map) + return output_table + + +def make_font_table_12_cpp( + sym_list: List[str], font_map: FontMap, symbol_map: Dict[str, bytes] +) -> str: output_table = "const uint8_t USER_FONT_12[] = {\n" - for line in font_table_strings: - # join font table int one large string - output_table += line + "\n" + for sym in sym_list: + output_table += f"{bytes_to_c_hex(font_map.font12[sym])}//{bytes_to_escaped(symbol_map[sym])} -> {sym}\n" output_table += "};\n" - output_table += "const uint8_t USER_FONT_6x8[] = {\n" - for line in font_small_table_strings: - # join font table int one large string - output_table += line + "\n" + return output_table + + +def make_font_table_06_cpp( + sym_list: List[str], font_map: FontMap, symbol_map: Dict[str, bytes] +) -> str: + output_table = "const uint8_t USER_FONT_6x8[] = {\n" + for sym in sym_list: + font_bytes = font_map.font06[sym] + if font_bytes: + font_line = bytes_to_c_hex(font_bytes) + else: + font_line = "// " # placeholder + output_table += f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}\n" output_table += "};\n" - return output_table, symbol_map + return output_table def convert_string_bytes(symbol_conversion_table: Dict[str, bytes], text: str) -> bytes: @@ -397,29 +482,178 @@ def escape(string: str) -> str: return json.dumps(string, ensure_ascii=False) +def write_bytes_as_c_array( + f: TextIO, name: str, data: bytes, indent: int = 2, bytes_per_line: int = 16 +) -> None: + f.write(f"const uint8_t {name}[] = {{\n") + for i in range(0, len(data), bytes_per_line): + f.write(" " * indent) + f.write(", ".join((f"0x{b:02X}" for b in data[i : i + bytes_per_line]))) + f.write(",\n") + f.write(f"}}; // {name}\n\n") + + @dataclass -class TranslationItem: - info: str - str_index: int +class LanguageData: + lang: dict + defs: dict + build_version: str + sym_list: List[str] + font_map: FontMap + symbol_conversion_table: Dict[str, bytes] -def write_language(lang: dict, defs: dict, f: TextIO) -> None: +def prepare_language(lang: dict, defs: dict, build_version: str) -> LanguageData: + language_code: str = lang["languageCode"] + logging.info(f"Preparing language data for {language_code}") + # Iterate over all of the text to build up the symbols & counts + text_list = get_letter_counts(defs, lang, build_version) + # From the letter counts, need to make a symbol translator & write out the font + fonts = lang["fonts"] + sym_list, font_map, symbol_conversion_table = get_font_map_and_table( + text_list, fonts + ) + return LanguageData( + lang, defs, build_version, sym_list, font_map, symbol_conversion_table + ) + + +def write_language( + data: LanguageData, + f: TextIO, + strings_bin: Optional[bytes] = None, + compress_font: bool = False, +) -> None: + lang = data.lang + defs = data.defs + build_version = data.build_version + sym_list = data.sym_list + font_map = data.font_map + symbol_conversion_table = data.symbol_conversion_table + language_code: str = lang["languageCode"] logging.info(f"Generating block for {language_code}") - # Iterate over all of the text to build up the symbols & counts - text_list = get_letter_counts(defs, lang) - # From the letter counts, need to make a symbol translator & write out the font - font_table_text, symbol_conversion_table = get_font_map_and_table(text_list) try: lang_name = lang["languageLocalName"] except KeyError: lang_name = language_code - f.write(f"\n// ---- {lang_name} ----\n\n") - f.write(font_table_text) + if strings_bin or compress_font: + f.write('#include "lzfx.h"\n') + f.write(f"\n// ---- {lang_name} ----\n\n") + if not compress_font: + font_table_text = make_font_table_cpp( + sym_list, font_map, symbol_conversion_table + ) + f.write(font_table_text) + else: + font12_uncompressed = bytearray() + for sym in sym_list: + font12_uncompressed.extend(font_map.font12[sym]) + font12_compressed = lzfx.compress(bytes(font12_uncompressed)) + logging.info( + f"Font table 12x16 compressed from {len(font12_uncompressed)} to {len(font12_compressed)} bytes (ratio {len(font12_compressed) / len(font12_uncompressed):.3})" + ) + write_bytes_as_c_array(f, "font_12x16_lzfx", font12_compressed) + font_table_text = make_font_table_06_cpp( + sym_list, font_map, symbol_conversion_table + ) + f.write(font_table_text) + + f.write(f"\n// ---- {lang_name} ----\n\n") + + translation_common_text = get_translation_common_text( + defs, symbol_conversion_table, build_version + ) + f.write(translation_common_text) + f.write( + f"const bool HasFahrenheit = {('true' if lang.get('tempUnitFahrenheit', True) else 'false')};\n\n" + ) + + if not compress_font: + f.write("extern const uint8_t *const Font_12x16 = USER_FONT_12;\n") + else: + f.write( + f"static uint8_t font_out_buffer[{len(font12_uncompressed)}];\n\n" + "extern const uint8_t *const Font_12x16 = font_out_buffer;\n" + ) + f.write("extern const uint8_t *const Font_6x8 = USER_FONT_6x8;\n\n") + + if not strings_bin: + translation_strings_and_indices_text = get_translation_strings_and_indices_text( + lang, defs, symbol_conversion_table + ) + f.write(translation_strings_and_indices_text) + f.write( + "const TranslationIndexTable *const Tr = &TranslationIndices;\n" + "const char *const TranslationStrings = TranslationStringsData;\n\n" + ) + else: + compressed = lzfx.compress(strings_bin) + logging.info( + f"Strings compressed from {len(strings_bin)} to {len(compressed)} bytes (ratio {len(compressed) / len(strings_bin):.3})" + ) + write_bytes_as_c_array(f, "translation_data_lzfx", compressed) + f.write( + f"static uint8_t translation_data_out_buffer[{len(strings_bin)}] __attribute__((__aligned__(2)));\n\n" + "const TranslationIndexTable *const Tr = reinterpret_cast(translation_data_out_buffer);\n" + "const char *const TranslationStrings = reinterpret_cast(translation_data_out_buffer) + sizeof(TranslationIndexTable);\n\n" + ) + + if not strings_bin and not compress_font: + f.write("void prepareTranslations() {}\n\n") + else: + f.write("void prepareTranslations() {\n" " unsigned int outsize;\n") + if compress_font: + f.write( + " outsize = sizeof(font_out_buffer);\n" + " lzfx_decompress(font_12x16_lzfx, sizeof(font_12x16_lzfx), font_out_buffer, &outsize);\n" + ) + if strings_bin: + f.write( + " outsize = sizeof(translation_data_out_buffer);\n" + " lzfx_decompress(translation_data_lzfx, sizeof(translation_data_lzfx), translation_data_out_buffer, &outsize);\n" + ) + f.write("}\n\n") + + sanity_checks_text = get_translation_sanity_checks_text(defs) + f.write(sanity_checks_text) + + +def get_translation_common_text( + defs: dict, symbol_conversion_table: Dict[str, bytes], build_version +) -> str: + translation_common_text = "" + + # Write out firmware constant options + constants = get_constants(build_version) + for x in constants: + translation_common_text += f'const char* {x[0]} = "{convert_string(symbol_conversion_table, x[1])}";//{x[1]} \n' + translation_common_text += "\n" + + # Debug Menu + translation_common_text += "const char* DebugMenu[] = {\n" + + for c in get_debug_menu(): + translation_common_text += ( + f'\t "{convert_string(symbol_conversion_table, c)}",//{c} \n' + ) + translation_common_text += "};\n\n" + return translation_common_text + + +@dataclass +class TranslationItem: + info: str + str_index: int + + +def get_translation_strings_and_indices_text( + lang: dict, defs: dict, symbol_conversion_table: Dict[str, bytes] +) -> str: str_table: List[str] = [] str_group_messages: List[TranslationItem] = [] str_group_messageswarn: List[TranslationItem] = [] @@ -478,21 +712,6 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: str_group_characters.append(TranslationItem(eid, len(str_table))) str_table.append(obj[eid]) - # Write out firmware constant options - constants = get_constants() - for x in constants: - f.write( - f'const char* {x[0]} = "{convert_string(symbol_conversion_table, x[1])}";//{x[1]} \n' - ) - f.write("\n") - - # Debug Menu - f.write("const char* DebugMenu[] = {\n") - - for c in get_debug_menu(): - f.write(f'\t "{convert_string(symbol_conversion_table, c)}",//{c} \n') - f.write("};\n\n") - # ----- Reading SettingsDescriptions obj = lang["menuOptions"] @@ -537,8 +756,6 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: ) str_table.append(obj[eid]["desc"]) - f.write("\n") - @dataclass class RemappedTranslationItem: str_index: int @@ -573,14 +790,13 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: str_offsets = [-1] * len(str_table) offset = 0 write_null = False - f.write("const char TranslationStringsData[] = {\n") + translation_strings_text = "const char TranslationStringsData[] = {\n" for i, source_str in enumerate(str_table): - if write_null: - f.write(' "\\0"\n') - write_null = True if str_remapping[i] is not None: - write_null = False continue + if write_null: + translation_strings_text += ' "\\0"\n' + write_null = True # Find what items use this string str_used_by = [i] + [ j for j, r in enumerate(str_remapping) if r and r.str_index == i @@ -597,40 +813,35 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: ]: for item in group: if item.str_index == j: - f.write(f" // - {pre_info} {item.info}\n") + translation_strings_text += ( + f" // - {pre_info} {item.info}\n" + ) if j == i: - f.write(f" // {offset: >4}: {escape(source_str)}\n") + translation_strings_text += f" // {offset: >4}: {escape(source_str)}\n" str_offsets[j] = offset else: remapped = str_remapping[j] assert remapped is not None - f.write( - f" // {offset + remapped.str_start_offset: >4}: {escape(str_table[j])}\n" - ) + translation_strings_text += f" // {offset + remapped.str_start_offset: >4}: {escape(str_table[j])}\n" str_offsets[j] = offset + remapped.str_start_offset - converted_str = convert_string(symbol_conversion_table, source_str) - f.write(f' "{converted_str}"') + converted_bytes = convert_string_bytes(symbol_conversion_table, source_str) + translation_strings_text += f' "{bytes_to_escaped(converted_bytes)}"' str_offsets[i] = offset - # Sanity check: Each "char" in `converted_str` should be in format - # `\xFF`, so the length should be divisible by 4. - assert len(converted_str) % 4 == 0 # Add the length and the null terminator - offset += len(converted_str) // 4 + 1 - f.write("\n};\n\n") + offset += len(converted_bytes) + 1 + translation_strings_text += "\n}; // TranslationStringsData\n\n" def get_offset(idx: int) -> int: assert str_offsets[idx] >= 0 return str_offsets[idx] - f.write("const TranslationIndexTable TranslationIndices = {\n") + translation_indices_text = "const TranslationIndexTable TranslationIndices = {\n" # ----- Write the messages string indices: for group in [str_group_messages, str_group_messageswarn, str_group_characters]: for item in group: - f.write( - f" .{item.info} = {get_offset(item.str_index)}, // {escape(str_table[item.str_index])}\n" - ) - f.write("\n") + translation_indices_text += f" .{item.info} = {get_offset(item.str_index)}, // {escape(str_table[item.str_index])}\n" + translation_indices_text += "\n" # ----- Write the settings index tables: for group, name in [ @@ -640,30 +851,25 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: (str_group_settingmenuentriesdesc, "SettingsMenuEntriesDescriptions"), ]: max_len = 30 - f.write(f" .{name} = {{\n") + translation_indices_text += f" .{name} = {{\n" for item in group: - f.write( - f" /* {item.info.ljust(max_len)[:max_len]} */ {get_offset(item.str_index)}, // {escape(str_table[item.str_index])}\n" - ) - f.write(f" }}, // {name}\n\n") + translation_indices_text += f" /* {item.info.ljust(max_len)[:max_len]} */ {get_offset(item.str_index)}, // {escape(str_table[item.str_index])}\n" + translation_indices_text += f" }}, // {name}\n\n" - f.write("}; // TranslationIndices\n\n") - f.write("const TranslationIndexTable *const Tr = &TranslationIndices;\n") - f.write("const char *const TranslationStrings = TranslationStringsData;\n\n") + translation_indices_text += "}; // TranslationIndices\n\n" - f.write( - f"const bool HasFahrenheit = {('true' if lang.get('tempUnitFahrenheit', True) else 'false')};\n" - ) + return translation_strings_text + translation_indices_text - f.write("\n// Verify SettingsItemIndex values:\n") + +def get_translation_sanity_checks_text(defs: dict) -> str: + sanity_checks_text = "\n// Verify SettingsItemIndex values:\n" for i, mod in enumerate(defs["menuOptions"]): eid = mod["id"] - f.write( + sanity_checks_text += ( f"static_assert(static_cast(SettingsItemIndex::{eid}) == {i});\n" ) - f.write( - f"static_assert(static_cast(SettingsItemIndex::NUM_ITEMS) == {len(defs['menuOptions'])});\n" - ) + sanity_checks_text += f"static_assert(static_cast(SettingsItemIndex::NUM_ITEMS) == {len(defs['menuOptions'])});\n" + return sanity_checks_text def read_version() -> str: @@ -683,6 +889,34 @@ def read_version() -> str: def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser() + parser.add_argument( + "--output-pickled", + help="Write pickled language data for later reuse", + type=argparse.FileType("wb"), + required=False, + dest="output_pickled", + ) + parser.add_argument( + "--input-pickled", + help="Use previously generated pickled language data", + type=argparse.FileType("rb"), + required=False, + dest="input_pickled", + ) + parser.add_argument( + "--strings-bin", + help="Use generated TranslationIndices + TranslationStrings data and compress them", + type=argparse.FileType("rb"), + required=False, + dest="strings_bin", + ) + parser.add_argument( + "--compress-font", + help="Compress the font table", + action="store_true", + required=False, + dest="compress_font", + ) parser.add_argument( "--output", "-o", help="Target file", type=argparse.FileType("w"), required=True ) @@ -690,23 +924,57 @@ def parse_args() -> argparse.Namespace: return parser.parse_args() -if __name__ == "__main__": +def main() -> None: json_dir = HERE args = parse_args() - try: - buildVersion = read_version() - except FileNotFoundError: - logging.error("error: Could not find version info ") + if args.input_pickled and args.output_pickled: + logging.error("error: Both --output-pickled and --input-pickled are specified") sys.exit(1) - logging.info(f"Build version: {buildVersion}") - logging.info(f"Making {args.languageCode} from {json_dir}") + language_data: LanguageData + if args.input_pickled: + logging.info(f"Reading pickled language data from {args.input_pickled.name}...") + language_data = pickle.load(args.input_pickled) + if language_data.lang["languageCode"] != args.languageCode: + logging.error( + f"error: languageCode {args.languageCode} does not match language data {language_data.lang['languageCode']}" + ) + sys.exit(1) + logging.info(f"Read language data for {language_data.lang['languageCode']}") + logging.info(f"Build version: {language_data.build_version}") + else: + try: + build_version = read_version() + except FileNotFoundError: + logging.error("error: Could not find version info ") + sys.exit(1) + + logging.info(f"Build version: {build_version}") + logging.info(f"Making {args.languageCode} from {json_dir}") + + lang_ = read_translation(json_dir, args.languageCode) + defs_ = load_json(os.path.join(json_dir, "translations_def.js"), True) + language_data = prepare_language(lang_, defs_, build_version) - lang_ = read_translation(json_dir, args.languageCode) - defs_ = load_json(os.path.join(json_dir, "translations_def.js"), True) out_ = args.output write_start(out_) - write_language(lang_, defs_, out_) + if args.strings_bin: + write_language( + language_data, + out_, + args.strings_bin.read(), + compress_font=args.compress_font, + ) + else: + write_language(language_data, out_, compress_font=args.compress_font) + + if args.output_pickled: + logging.info(f"Writing pickled data to {args.output_pickled.name}") + pickle.dump(language_data, args.output_pickled) logging.info("Done") + + +if __name__ == "__main__": + main() diff --git a/Translations/make_translation_test.py b/Translations/make_translation_test.py index 39b6f83b..9b2d1ba4 100644 --- a/Translations/make_translation_test.py +++ b/Translations/make_translation_test.py @@ -24,6 +24,12 @@ class TestMakeTranslation(unittest.TestCase): self.assertEqual(bytes_to_escaped(b"\x00"), "\\x00") self.assertEqual(bytes_to_escaped(b"\xF1\xAB"), "\\xF1\\xAB") + def test_bytes_to_c_hex(self): + from make_translation import bytes_to_c_hex + + self.assertEqual(bytes_to_c_hex(b"\x00"), "0x00,") + self.assertEqual(bytes_to_c_hex(b"\xF1\xAB"), "0xF1, 0xAB,") + if __name__ == "__main__": unittest.main() diff --git a/Translations/translation_BG.json b/Translations/translation_BG.json index 6b5e3a35..5c285352 100644 --- a/Translations/translation_BG.json +++ b/Translations/translation_BG.json @@ -1,7 +1,10 @@ { "languageCode": "BG", "languageLocalName": "Български", - "cyrillicGlyphs": true, + "fonts": [ + "ascii_basic", + "cyrillic" + ], "messages": { "SettingsCalibrationDone": "Калибрацията завършена!", "SettingsCalibrationWarning": "Уверете се, че върха на поялника е със стайна температура преди да продължите!", diff --git a/Translations/translation_CS.json b/Translations/translation_CS.json index 8aed567d..645994f8 100644 --- a/Translations/translation_CS.json +++ b/Translations/translation_CS.json @@ -1,7 +1,10 @@ { "languageCode": "CS", "languageLocalName": "Český", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibrace dokončena!", "SettingsCalibrationWarning": "Ujistěte se, že hrot má pokojovou teplotu!", diff --git a/Translations/translation_DA.json b/Translations/translation_DA.json index ea13608b..1541e74b 100644 --- a/Translations/translation_DA.json +++ b/Translations/translation_DA.json @@ -1,7 +1,10 @@ { "languageCode": "DA", "languageLocalName": "Dansk", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibration done!", "SettingsCalibrationWarning": "Sørg for at loddespidsen er ved stuetemperatur, inden du fortsætter!", diff --git a/Translations/translation_DE.json b/Translations/translation_DE.json index 1226dfad..efd46499 100644 --- a/Translations/translation_DE.json +++ b/Translations/translation_DE.json @@ -1,7 +1,10 @@ { "languageCode": "DE", "languageLocalName": "Deutsch", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "tempUnitFahrenheit": false, "messages": { "SettingsCalibrationDone": "Kalibrierung abgeschlossen!", @@ -58,10 +61,10 @@ "SettingSensitivityLow": "N", "SettingSensitivityMedium": "M", "SettingSensitivityHigh": "H", - "SettingLockDisableChar": "D", + "SettingLockDisableChar": "A", "SettingLockBoostChar": "B", "SettingLockFullChar": "V", - "SettingNAChar": "N/A" + "SettingNAChar": "-" }, "menuGroups": { "PowerMenu": { @@ -267,7 +270,7 @@ "Tasten-", "sperre" ], - "desc": "Langes drücken beider Tasten im Lötmodus sperrt diese " + "desc": "Langes drücken beider Tasten im Lötmodus sperrt diese " }, "MinVolCell": { "text2": [ @@ -288,14 +291,14 @@ "Anim.", "Geschw." ], - "desc": "Geschwindigkeit der Icon-Animationen im Menü " + "desc": "Geschwindigkeit der Icon-Animationen im Menü " }, "PowerPulseWait": { "text2": [ "Leistungsimpulse", "Wartezeit" ], - "desc": "Wartezeit vor dem Auslösen jedes Wachhalteimpulses (x 2,5s)" + "desc": "Dauer vor Abgabe von Wachhalteimpulsen (x 2,5s)" }, "PowerPulseDuration": { "text2": [ diff --git a/Translations/translation_EN.json b/Translations/translation_EN.json index 51d79ea0..d5b67ae4 100644 --- a/Translations/translation_EN.json +++ b/Translations/translation_EN.json @@ -1,7 +1,9 @@ { "languageCode": "EN", "languageLocalName": "English", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic" + ], "tempUnitFahrenheit": true, "messages": { "SettingsCalibrationDone": "Calibration done!", @@ -281,21 +283,21 @@ "Anim.", "loop" ], - "desc": "Loop icon animations in root menu" + "desc": "Loop icon animations in main menu" }, "AnimSpeed": { "text2": [ "Anim.", "speed" ], - "desc": "Speed of icon animations in menu " + "desc": "Pace of icon animations in menu " }, "PowerPulseWait": { "text2": [ "Power pulse", - "wait time" + "delay" ], - "desc": "Time to wait before triggering every keep-awake pulse (x 2.5s)" + "desc": "Delay before keep-awake pulse is triggered (x 2.5s)" }, "PowerPulseDuration": { "text2": [ diff --git a/Translations/translation_ES.json b/Translations/translation_ES.json index f4ff297e..117ed864 100644 --- a/Translations/translation_ES.json +++ b/Translations/translation_ES.json @@ -1,7 +1,10 @@ { "languageCode": "ES", "languageLocalName": "Castellano", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "¡Calibrada!", "SettingsCalibrationWarning": "¡Asegúrate que la punta esté a temperatura ambiente antes de empezar!", diff --git a/Translations/translation_FI.json b/Translations/translation_FI.json index d263d7ec..f4ebef8f 100644 --- a/Translations/translation_FI.json +++ b/Translations/translation_FI.json @@ -1,45 +1,45 @@ { "languageCode": "FI", "languageLocalName": "Suomi", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { - "SettingsCalibrationDone": "Calibration done!", "SettingsCalibrationWarning": "Varmista että kärki on huoneenlämpöinen ennen jatkamista!", "SettingsResetWarning": "Haluatko varmasti palauttaa oletusarvot?", - "UVLOWarningString": "DC LOW", + "UVLOWarningString": "DC ALH.", "UndervoltageString": "Alijännite", "InputVoltageString": "Jännite: ", - "WarningTipTempString": "Lämpötila: ", - "BadTipString": "VIKATILA", "SleepingSimpleString": "Zzzz", "SleepingAdvancedString": "Lepotila...", - "WarningSimpleString": "HOT", - "WarningAdvancedString": "! KÄRKI KUUMA !", "SleepingTipAdvancedString": "Kärki:", - "IdleTipString": "Kärki:", - "IdleSetString": " Asetus:", - "TipDisconnectedString": "KÄRKI ON IRTI", + "IdleTipString": "Pää:", + "IdleSetString": "Aseta:", + "TipDisconnectedString": "KÄRKI PUUTTUU", "SolderingAdvancedPowerPrompt": "Teho: ", - "OffString": "OFF", - "YourGainMessage": "Your gain:" + "OffString": "Off" }, "messagesWarn": { - "ResetOKMessage": "Reset OK", + "ResetOKMessage": [ + "Palautus", + "onnistui" + ], "SettingsResetMessage": [ - "Settings were", - "reset!" + "Asetukset", + "palautettu!" ], "NoAccelerometerMessage": [ - "No accelerometer", - "detected!" + "Kiihtyvyysanturi", + "puuttuu!" ], "NoPowerDeliveryMessage": [ - "No USB-PD IC", - "detected!" + "USB-PD IC", + "puuttuu!" ], - "LockingKeysString": " LOCKED", - "UnlockingKeysString": "UNLOCKED", - "WarningKeysLockedString": "!LOCKED!" + "LockingKeysString": " LUKITTU", + "UnlockingKeysString": "AUKI", + "WarningKeysLockedString": "!LUKKO!" }, "characters": { "SettingRightChar": "O", @@ -48,27 +48,27 @@ "SettingFastChar": "N", "SettingSlowChar": "H", "SettingMediumChar": "M", - "SettingOffChar": "O", - "SettingStartSolderingChar": "T", - "SettingStartSleepChar": "S", - "SettingStartSleepOffChar": "O", - "SettingStartNoneChar": "F", - "SettingSensitivityOff": "O", - "SettingSensitivityLow": "L", - "SettingSensitivityMedium": "M", - "SettingSensitivityHigh": "H", - "SettingLockDisableChar": "D", - "SettingLockBoostChar": "B", - "SettingLockFullChar": "F", + "SettingOffChar": "P", + "SettingStartSolderingChar": "K", + "SettingStartSleepChar": "L", + "SettingStartSleepOffChar": "N", + "SettingStartNoneChar": "E", + "SettingSensitivityOff": "P", + "SettingSensitivityLow": "A", + "SettingSensitivityMedium": "K", + "SettingSensitivityHigh": "S", + "SettingLockDisableChar": "P", + "SettingLockBoostChar": "V", + "SettingLockFullChar": "K", "SettingNAChar": "N/A" }, "menuGroups": { "PowerMenu": { "text2": [ - "Power", - "settings" + "Virta-", + "asetukset" ], - "desc": "Power settings" + "desc": "Virta-asetukset" }, "SolderingMenu": { "text2": [ @@ -105,56 +105,56 @@ "Virtalähde", "DC" ], - "desc": "Käytettävä virtalähde. Asettaa katkaisujänniteen. " + "desc": "Virtalähde. Asettaa katkaisujännitteen. " }, "SleepTemperature": { "text2": [ "Lepotilan", "lämpötila" ], - "desc": "Lepotilan lämpötila. " + "desc": "Kärjen lämpötila \"lepotilassa\"" }, "SleepTimeout": { "text2": [ "Lepotilan", "viive" ], - "desc": "Lepotilan viive. " + "desc": "\"Lepotilan\" ajastus " }, "ShutdownTimeout": { "text2": [ "Sammutus", "viive" ], - "desc": "Automaattisen sammutuksen aikaviive. " + "desc": "Automaattisen sammutuksen ajastus " }, "MotionSensitivity": { "text2": [ "Liikkeen", "herkkyys" ], - "desc": "Liikkeentunnistuksen herkkyys. <0=pois, 1=epäherkin, 9=herkin>" + "desc": "0=pois päältä | 1=vähäinen herkkyys | ... | 9=suurin herkkyys" }, "TemperatureUnit": { "text2": [ "Lämpötilan", "yksikkö" ], - "desc": "Lämpötilan yksikkö. " + "desc": "" }, "AdvancedIdle": { "text2": [ "Tiedot", "lepotilassa" ], - "desc": "Näyttää yksityiskohtaisemmat tiedot lepotilassa." + "desc": "Näyttää yksityiskohtaisemmat pienemmällä fontilla tiedot lepotilassa." }, "DisplayRotation": { "text2": [ "Näytön", "kierto" ], - "desc": "Näytön kierto. " + "desc": "A=automaattinen | V=vasenkätinen | O=oikeakätinen" }, "BoostTemperature": { "text2": [ @@ -175,133 +175,133 @@ "Jäähdytyksen", "vilkutus" ], - "desc": "Vilkuttaa jäähtyessä juotoskärjen lämpötilaa sen ollessa vielä vaarallisen kuuma." + "desc": "Vilkuttaa jäähtyessä juotoskärjen lämpötilaa sen ollessa vielä vaarallisen kuuma" }, "TemperatureCalibration": { "text2": [ "Kalibroi", "lämpötila?" ], - "desc": "Kalibroi kärjen lämpötilaeron." + "desc": "Kalibroi kärjen lämpötilaeron" }, "SettingsReset": { "text2": [ "Palauta", "tehdasasetukset?" ], - "desc": "Palauta kaikki asetukset oletusarvoihin." + "desc": "Palauta kaikki asetukset oletusarvoihin" }, "VoltageCalibration": { "text2": [ "Kalibroi", "tulojännite?" ], - "desc": "Tulojännitten kalibrointi (VIN). Painikkeilla säädetään ja pitkään painamalla poistutaan." + "desc": "Tulojännitten kalibrointi (VIN) " }, "AdvancedSoldering": { "text2": [ "Tarkempi", "juotosnäyttö" ], - "desc": "Näyttää yksityiskohtaisemmat tiedot juotostilassa." + "desc": "Näyttää yksityiskohtaisemmat tiedot pienellä fontilla juotostilassa" }, "ScrollingSpeed": { "text2": [ - "Tietojen", - "näyttönopeus" + "Selityksien", + "nopeus" ], - "desc": "Näiden selitetekstien vieritysnopeus." + "desc": "Selityksien vieritysnopeus " }, "QCMaxVoltage": { "text2": [ - "Power", - "Wattage" + "QC", + "jännite" ], - "desc": "Power Wattage of the power adapter used" + "desc": "Ensisijainen maksimi QC jännite" }, "PowerLimit": { "text2": [ - "Power", - "Limit" + "Tehon-", + "rajoitus" ], - "desc": "Maximum power the iron can use " + "desc": "Suurin sallittu teho " }, "ReverseButtonTempChange": { "text2": [ - "Key +-", - "reverse?" + "Suunnanvaihto", + "+ - näppäimille" ], - "desc": "Reverse the tip temperature change buttons plus minus assignment." + "desc": "Lämpötilapainikkeiden suunnan vaihtaminen" }, "TempChangeShortStep": { "text2": [ - "Temp change", - "short?" + "Lämmön muutos", + "lyhyt painal." ], - "desc": "Temperature change steps on short button press!" + "desc": "Lämpötilan muutos lyhyellä painalluksella" }, "TempChangeLongStep": { "text2": [ - "Temp change", - "long?" + "Lämmön muutos", + "pitkä painal." ], - "desc": "Temperature change steps on long button press!" + "desc": "Lämpötilan muutos pitkällä painalluksella" }, "PowerPulsePower": { "text2": [ - "Power", - "Pulse W" + "Herätyspulssin", + "voimakkuus" ], - "desc": "Keep awake pulse power intensity" + "desc": "Herätyspulssin voimakkuus " }, "HallEffSensitivity": { "text2": [ - "Hall Eff", - "Sensitivity" + "Hall-", + "herk." ], - "desc": "Sensitivity of the Hall effect sensor in detecting sleep " + "desc": "Hall-efektianturin herkkyys lepotilan tunnistuksessa " }, "LockingMode": { "text2": [ - "Allow buttons", - "locking" + "Salli nappien", + "lukitus" ], - "desc": "When soldering, long press on both buttons lock them " + "desc": "Kolvatessa paina molempia näppäimiä lukitaksesi ne " }, "MinVolCell": { "text2": [ - "Minimum", - "voltage" + "Pienin", + "jännite" ], - "desc": "Minimum allowed voltage per cell <3S: 3.0V - 3.7V, 4/5/6S: 2.4V - 3.7V>" + "desc": "Pienin sallittu jännite per kenno <3S: 3.0V - 3.7V, 4/5/6S: 2.4V - 3.7V>" }, "AnimLoop": { "text2": [ - "Anim.", - "loop" + "Animaation", + "toistaminen" ], - "desc": "Loop icon animations in root menu" + "desc": "Toista animaatiot valikossa" }, "AnimSpeed": { "text2": [ - "Anim.", - "speed" + "Animaation", + "nopeus" ], - "desc": "Speed of icon animations in menu " + "desc": "Animaatioiden nopeus valikossa " }, "PowerPulseWait": { "text2": [ - "Power pulse", - "wait time" + "Pulssin", + "odotusaika" ], - "desc": "Time to wait before triggering every keep-awake pulse (x 2.5s)" + "desc": "Odotusaika herätyspulssin lähetykseen (x 2.5s)" }, "PowerPulseDuration": { "text2": [ - "Power pulse", - "duration" + "Pulssin", + "kesto" ], - "desc": "Keep-awake-pulse duration (x 250ms)" + "desc": "Herätyspulssin kesto (x 250ms)" } } } diff --git a/Translations/translation_FR.json b/Translations/translation_FR.json index 3d171913..1a1cf1f7 100644 --- a/Translations/translation_FR.json +++ b/Translations/translation_FR.json @@ -1,7 +1,10 @@ { "languageCode": "FR", "languageLocalName": "Français", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibration effectuée !", "SettingsCalibrationWarning": "Assurez-vous que la panne soit à température ambiante avant de continuer !", @@ -277,31 +280,31 @@ }, "AnimLoop": { "text2": [ - "Anim.", - "loop" + "Icônes", + "animées" ], - "desc": "Loop icon animations in root menu" + "desc": "Animations des icônes dans le menu principal" }, "AnimSpeed": { "text2": [ - "Anim.", - "speed" + "Vitesse", + "d'animations" ], - "desc": "Speed of icon animations in menu " + "desc": "Vitesse des animations des icônes dans le menu " }, "PowerPulseWait": { "text2": [ - "Power pulse", - "wait time" + "Délai entre", + "les impulsions" ], - "desc": "Time to wait before triggering every keep-awake pulse (x 2.5s)" + "desc": "Délai entre chaque impulsions pour empêcher la mise en veille (x 2.5s)" }, "PowerPulseDuration": { "text2": [ - "Power pulse", - "duration" + "Durée des", + "impulsions" ], - "desc": "Keep-awake-pulse duration (x 250ms)" + "desc": "Durée des impulsions pour empêcher la mise en veille (x 250ms)" } } } diff --git a/Translations/translation_HR.json b/Translations/translation_HR.json index 28816082..a488a994 100644 --- a/Translations/translation_HR.json +++ b/Translations/translation_HR.json @@ -1,7 +1,10 @@ { "languageCode": "HR", "languageLocalName": "Hrvatski", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibracija gotova!", "SettingsCalibrationWarning": "Provjerite da je vršak ohlađen na sobnu temperaturu prije nego što nastavite!", diff --git a/Translations/translation_HU.json b/Translations/translation_HU.json index 26f2e21d..13d2e0ed 100644 --- a/Translations/translation_HU.json +++ b/Translations/translation_HU.json @@ -1,7 +1,10 @@ { "languageCode": "HU", "languageLocalName": "Magyar", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibráció befejezve!", "SettingsCalibrationWarning": "Folytatás előtt győződjön meg róla, hogy a páka szobahőmérsékletű!", diff --git a/Translations/translation_IT.json b/Translations/translation_IT.json index af7db547..dfcebc61 100644 --- a/Translations/translation_IT.json +++ b/Translations/translation_IT.json @@ -1,7 +1,10 @@ { "languageCode": "IT", "languageLocalName": "Italiano", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibrazione effettuata", "SettingsCalibrationWarning": "Assicurati che la punta si trovi a temperatura ambiente prima di continuare!", diff --git a/Translations/translation_JA_JP.json b/Translations/translation_JA_JP.json index f5e95fa8..20bde0dd 100644 --- a/Translations/translation_JA_JP.json +++ b/Translations/translation_JA_JP.json @@ -1,7 +1,10 @@ { "languageCode": "JA_JP", "languageLocalName": "日本語", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "cjk" + ], "tempUnitFahrenheit": true, "messages": { "SettingsCalibrationDone": "校正完了", @@ -113,7 +116,7 @@ }, "DisplayRotation": { "text2": "画面の向き", - "desc": "A=自動 | L=左利き | R=右利き" + "desc": "自=自動 | 左=左利き | 右=右利き" }, "BoostTemperature": { "text2": "ブースト温度", @@ -200,4 +203,4 @@ "desc": "電源供給元をオンに保つために使用される、電力パルスの時間長 " } } -} \ No newline at end of file +} diff --git a/Translations/translation_LT.json b/Translations/translation_LT.json index ae84c9d3..aba3520d 100644 --- a/Translations/translation_LT.json +++ b/Translations/translation_LT.json @@ -1,7 +1,10 @@ { "languageCode": "LT", "languageLocalName": "Lietuvių", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibravimas atliktas!", "SettingsCalibrationWarning": "Prieš tęsdami įsitikinkite, kad antgalis yra kambario temperatūros!", diff --git a/Translations/translation_NL.json b/Translations/translation_NL.json index 72f34da5..5d4d5f6a 100644 --- a/Translations/translation_NL.json +++ b/Translations/translation_NL.json @@ -1,7 +1,10 @@ { "languageCode": "NL", "languageLocalName": "Nederlands", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibratie klaar!", "SettingsCalibrationWarning": "Zorg ervoor dat te punt op kamertemperatuur is voor je verder gaat!", diff --git a/Translations/translation_NL_BE.json b/Translations/translation_NL_BE.json index e4c0c10c..00ae61bf 100644 --- a/Translations/translation_NL_BE.json +++ b/Translations/translation_NL_BE.json @@ -1,7 +1,10 @@ { "languageCode": "NL_BE", "languageLocalName": "Vlaams", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Gecalibreerd!", "SettingsCalibrationWarning": "Zorg vooraf dat de punt op kamertemperatuur is!", diff --git a/Translations/translation_NO.json b/Translations/translation_NO.json index 6f5ef113..90401145 100644 --- a/Translations/translation_NO.json +++ b/Translations/translation_NO.json @@ -1,7 +1,10 @@ { "languageCode": "NO", "languageLocalName": "Norsk", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibration done!", "SettingsCalibrationWarning": "Sørg for at loddespissen har romtemperatur før du fortsetter!", diff --git a/Translations/translation_PL.json b/Translations/translation_PL.json index 7a0ccb1f..4159e226 100644 --- a/Translations/translation_PL.json +++ b/Translations/translation_PL.json @@ -1,7 +1,10 @@ { "languageCode": "PL", "languageLocalName": "Polski", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "tempUnitFahrenheit": false, "messages": { "SettingsCalibrationDone": "Kalibracja udana!", diff --git a/Translations/translation_PT.json b/Translations/translation_PT.json index 7d7c541b..06b51d37 100644 --- a/Translations/translation_PT.json +++ b/Translations/translation_PT.json @@ -1,7 +1,10 @@ { "languageCode": "PT", "languageLocalName": "Português", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibração terminada!", "SettingsCalibrationWarning": "A ponta deve estar à temperatura ambiente antes de continuar!", diff --git a/Translations/translation_RU.json b/Translations/translation_RU.json index b6746b86..b3de0c81 100644 --- a/Translations/translation_RU.json +++ b/Translations/translation_RU.json @@ -1,7 +1,11 @@ { "languageCode": "RU", "languageLocalName": "Русский", - "cyrillicGlyphs": true, + "fonts": [ + "ascii_basic", + "latin_extended", + "cyrillic" + ], "messages": { "SettingsCalibrationDone": "Калибровка завершена!", "SettingsCalibrationWarning": "Прежде чем продолжить, пожалуйста, убедитесь, что жало имеет комнатную температуру!", diff --git a/Translations/translation_SK.json b/Translations/translation_SK.json index 6423287a..56e9e19d 100644 --- a/Translations/translation_SK.json +++ b/Translations/translation_SK.json @@ -1,7 +1,10 @@ { "languageCode": "SK", "languageLocalName": "Slovenčina", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibrácia hotová!", "SettingsCalibrationWarning": "Najprv sa prosím uistite, že hrot má izbovú teplotu!", diff --git a/Translations/translation_SL.json b/Translations/translation_SL.json index 52e4bf44..622fb026 100644 --- a/Translations/translation_SL.json +++ b/Translations/translation_SL.json @@ -1,7 +1,10 @@ { "languageCode": "SL", "languageLocalName": "Slovenščina", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibracija opravljena!", "SettingsCalibrationWarning": "Pred nadaljevanjem mora biti konica segreta na sobno temperaturo!", diff --git a/Translations/translation_SR_CYRL.json b/Translations/translation_SR_CYRL.json index 69620f63..4c0eb951 100644 --- a/Translations/translation_SR_CYRL.json +++ b/Translations/translation_SR_CYRL.json @@ -1,7 +1,10 @@ { "languageCode": "SR_CYRL", "languageLocalName": "Српски", - "cyrillicGlyphs": true, + "fonts": [ + "ascii_basic", + "cyrillic" + ], "messages": { "SettingsCalibrationDone": "Калибрација готова", "SettingsCalibrationWarning": "Проверите да ли је врх охлађен на собну температуру пре него што наставите", diff --git a/Translations/translation_SR_LATN.json b/Translations/translation_SR_LATN.json index 573e99fa..d5192fe7 100644 --- a/Translations/translation_SR_LATN.json +++ b/Translations/translation_SR_LATN.json @@ -1,7 +1,10 @@ { "languageCode": "SR_LATN", "languageLocalName": "Srpski", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibracija gotova", "SettingsCalibrationWarning": "Proverite da li je vrh ohlađen na sobnu temperaturu pre nego što nastavite", diff --git a/Translations/translation_SV.json b/Translations/translation_SV.json index da04a036..b30449c2 100644 --- a/Translations/translation_SV.json +++ b/Translations/translation_SV.json @@ -1,7 +1,10 @@ { "languageCode": "SV", "languageLocalName": "Svenska", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibration done!", "SettingsCalibrationWarning": "Please ensure the tip is at room temperature before continuing!", diff --git a/Translations/translation_TR.json b/Translations/translation_TR.json index 7092bc70..50c3a01f 100644 --- a/Translations/translation_TR.json +++ b/Translations/translation_TR.json @@ -1,7 +1,10 @@ { "languageCode": "TR", "languageLocalName": "Türkçe", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibrasyon tamamlandı!", "SettingsCalibrationWarning": "Lütfen devam etmeden önce ucun oda sıcaklığında olduğunu garantiye alın!", diff --git a/Translations/translation_UK.json b/Translations/translation_UK.json index 94959c8a..fbd44a3a 100644 --- a/Translations/translation_UK.json +++ b/Translations/translation_UK.json @@ -1,7 +1,11 @@ { "languageCode": "UK", "languageLocalName": "Українська", - "cyrillicGlyphs": true, + "fonts": [ + "ascii_basic", + "latin_extended", + "cyrillic" + ], "messages": { "SettingsCalibrationDone": "Калібрування виконане!", "SettingsCalibrationWarning": "Переконайтеся, що жало охололо до кімнатної температури, перш ніж продовжувати!", diff --git a/Translations/translation_YUE_HK.json b/Translations/translation_YUE_HK.json index 23ab1a0e..19af3103 100644 --- a/Translations/translation_YUE_HK.json +++ b/Translations/translation_YUE_HK.json @@ -1,7 +1,10 @@ { "languageCode": "YUE_HK", "languageLocalName": "廣東話 (香港)", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "cjk" + ], "tempUnitFahrenheit": true, "messages": { "SettingsCalibrationDone": "校正完成!", @@ -113,7 +116,7 @@ }, "DisplayRotation": { "text2": "畫面方向", - "desc": "A=自動 | L=使用左手 | R=使用右手" + "desc": "自=自動 | 左=使用左手 | 右=使用右手" }, "BoostTemperature": { "text2": "增熱温度", diff --git a/Translations/translation_ZH_CN.json b/Translations/translation_ZH_CN.json index 898e1263..5ef42239 100644 --- a/Translations/translation_ZH_CN.json +++ b/Translations/translation_ZH_CN.json @@ -1,7 +1,10 @@ { "languageCode": "ZH_CN", "languageLocalName": "简体中文", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "cjk" + ], "tempUnitFahrenheit": true, "messages": { "SettingsCalibrationDone": "校正完成!", @@ -113,7 +116,7 @@ }, "DisplayRotation": { "text2": "画面方向", - "desc": "A=自动 | L=使用左手 | R=使用右手" + "desc": "自=自动 | 左=使用左手 | 右=使用右手" }, "BoostTemperature": { "text2": "增热温度", diff --git a/Translations/translation_ZH_TW.json b/Translations/translation_ZH_TW.json index 2dc083a6..5d9aed5f 100644 --- a/Translations/translation_ZH_TW.json +++ b/Translations/translation_ZH_TW.json @@ -1,7 +1,10 @@ { "languageCode": "ZH_TW", "languageLocalName": "正體中文", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "cjk" + ], "tempUnitFahrenheit": true, "messages": { "SettingsCalibrationDone": "校正完成!", @@ -113,7 +116,7 @@ }, "DisplayRotation": { "text2": "畫面方向", - "desc": "A=自動 | L=使用左手 | R=使用右手" + "desc": "自=自動 | 左=使用左手 | 右=使用右手" }, "BoostTemperature": { "text2": "增熱溫度", diff --git a/source/Core/Drivers/OLED.cpp b/source/Core/Drivers/OLED.cpp index 479a5523..f1e057bc 100644 --- a/source/Core/Drivers/OLED.cpp +++ b/source/Core/Drivers/OLED.cpp @@ -117,7 +117,7 @@ void OLED::drawChar(const uint16_t charCode, const FontStyle fontStyle) { static uint8_t fontWidth, fontHeight; switch (fontStyle) { case FontStyle::SMALL: - currentFont = USER_FONT_6x8; + currentFont = Font_6x8; fontHeight = 8; fontWidth = 6; break; @@ -128,7 +128,7 @@ void OLED::drawChar(const uint16_t charCode, const FontStyle fontStyle) { break; case FontStyle::LARGE: default: - currentFont = USER_FONT_12; + currentFont = Font_12x16; fontHeight = 16; fontWidth = 12; break; diff --git a/source/Core/Inc/Translation.h b/source/Core/Inc/Translation.h index 67277906..62327d7f 100644 --- a/source/Core/Inc/Translation.h +++ b/source/Core/Inc/Translation.h @@ -8,9 +8,8 @@ #ifndef TRANSLATION_H_ #define TRANSLATION_H_ #include "stdint.h" -extern const uint8_t USER_FONT_12[]; -extern const uint8_t USER_FONT_6x8[]; -extern const bool HasFahrenheit; + +extern const bool HasFahrenheit; extern const char *SymbolPlus; extern const char *SymbolMinus; @@ -114,10 +113,15 @@ struct TranslationIndexTable { extern const TranslationIndexTable *const Tr; extern const char *const TranslationStrings; +extern const uint8_t *const Font_12x16; +extern const uint8_t *const Font_6x8; + constexpr uint8_t settings_item_index(const SettingsItemIndex i) { return static_cast(i); } // Use a constexpr function for type-checking. #define SETTINGS_DESC(i) (settings_item_index(i) + 1) const char *translatedString(uint16_t index); +void prepareTranslations(); + #endif /* TRANSLATION_H_ */ diff --git a/source/Core/Threads/GUIThread.cpp b/source/Core/Threads/GUIThread.cpp index 8a4c6b99..8437c4dc 100644 --- a/source/Core/Threads/GUIThread.cpp +++ b/source/Core/Threads/GUIThread.cpp @@ -746,6 +746,8 @@ void showWarnings() { uint8_t idleScreenBGF[sizeof(idleScreenBG)]; /* StartGUITask function */ void startGUITask(void const *argument __unused) { + prepareTranslations(); + OLED::initialize(); // start up the LCD uint8_t tempWarningState = 0; diff --git a/source/Core/lzfx/README.md b/source/Core/lzfx/README.md new file mode 100644 index 00000000..82420cf0 --- /dev/null +++ b/source/Core/lzfx/README.md @@ -0,0 +1,79 @@ +This directory contains file originally by other people. + + +## Simplified LZFX-based compression library + +- `lzfx.c` +- `lzfx.h` + +The above files are obtained from https://github.com/janding/lzfx (commit +448017f). It is a fork by Jan Ding (GitHub user "janding") based on the LZFX +compression library by Andrew Collette. + +### License: + +``` +LZFX is copyright (c) 2009 Andrew Collette and subject to the BSD license +(below). Original LZF copyright statement follows. + +Copyright (c) 2000-2007 Marc Alexander Lehmann + +Redistribution and use in source and binary forms, with or without modifica- +tion, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- +CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- +CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- +ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. +``` + + +## lzfx-boot + +- `lzfx-host-compress.c` (original: `lzfx-raw.c`) + +The above file is obtained from https://github.com/janding/lzfx-boot (commit +88b1596). + +### License: + +``` +BSD 2-Clause License + +Copyright (c) 2017, Jan Ding +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` diff --git a/source/Core/lzfx/lzfx.c b/source/Core/lzfx/lzfx.c new file mode 100644 index 00000000..81d1560a --- /dev/null +++ b/source/Core/lzfx/lzfx.c @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2009 Andrew Collette + * http://lzfx.googlecode.com + * + * Implements an LZF-compatible compressor/decompressor based on the liblzf + * codebase written by Marc Lehmann. This code is released under the BSD + * license. License and original copyright statement follow. + * + * + * Copyright (c) 2000-2008 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lzfx.h" + +#define LZFX_HSIZE (1 << (LZFX_HLOG)) + +/* We need this for memset */ +#ifdef __cplusplus +#include +#else +#include +#endif + +#if __GNUC__ >= 3 +#define fx_expect_false(expr) __builtin_expect((expr) != 0, 0) +#define fx_expect_true(expr) __builtin_expect((expr) != 0, 1) +#else +#define fx_expect_false(expr) (expr) +#define fx_expect_true(expr) (expr) +#endif + +typedef unsigned char u8; +typedef const u8 * LZSTATE[LZFX_HSIZE]; + +/* Define the hash function */ +#define LZFX_FRST(p) (((p[0]) << 8) | p[1]) +#define LZFX_NEXT(v, p) (((v) << 8) | p[2]) +#define LZFX_IDX(h) (((h >> (3 * 8 - LZFX_HLOG)) - h) & (LZFX_HSIZE - 1)) + +/* These cannot be changed, as they are related to the compressed format. */ +#define LZFX_MAX_LIT (1 << 5) - 1 +#define LZFX_MAX_OFF (1 << 13) +#define LZFX_MAX_REF ((1 << 8) + (1 << 3) - 2) + +static int lzfx_getsize(const void *ibuf, unsigned int ilen, unsigned int *olen); + +/* Compressed format + + There are two kinds of structures in LZF/LZFX: literal runs and back + references. Literals are encoded as follows: + + LLLLL000 + + Back references are encoded as follows. The smallest possible encoded + length value is 1, as otherwise the control byte would be recognized as + a literal run. At least three bytes must match for a back reference + to be inserted. The offset (distance to the desired data in the output + buffer) is encoded as o - 1, as all offsets are at least 1. The binary + format is: + + oooooLLL oooooooo for backrefs of real length < 7 (1 <= L < 7) + ooooo111 LLLLLLLL oooooooo for backrefs of real length >= 7 (L >= 7) +*/ +int lzfx_compress(const void *const ibuf, const unsigned int ilen, void *obuf, unsigned int *const olen) { + + /* Hash table; an array of u8*'s which point + to various locations in the input buffer */ + const u8 *htab[LZFX_HSIZE]; + + const u8 ** hslot; /* Pointer to entry in hash table */ + unsigned int hval; /* Hash value generated by macros above */ + const u8 * ref; /* Pointer to candidate match location in input */ + + const u8 * ip = (const u8 *)ibuf; + const u8 *const in_end = ip + ilen; + + u8 * op = (u8 *)obuf; + const u8 *const out_end = (olen == NULL ? NULL : op + *olen); + + int lit; /* # of bytes in current literal run */ + +#if defined(WIN32) && defined(_M_X64) + unsigned _int64 off; /* workaround for missing POSIX compliance */ +#else + unsigned long off; +#endif + + if (olen == NULL) + return LZFX_EARGS; + if (ibuf == NULL) { + if (ilen != 0) + return LZFX_EARGS; + *olen = 0; + return 0; + } + if (obuf == NULL) + return LZFX_EARGS; + + memset(htab, 0, sizeof(htab)); + + /* Start a literal run. Whenever we do this the output pointer is + advanced because the current byte will hold the encoded length. */ + lit = 0; + op++; + + hval = LZFX_FRST(ip); + + while (ip + 2 < in_end) { /* The NEXT macro reads 2 bytes ahead */ + + hval = LZFX_NEXT(hval, ip); + hslot = htab + LZFX_IDX(hval); + + ref = *hslot; + *hslot = ip; + + if (ref < ip && (off = ip - ref - 1) < LZFX_MAX_OFF && ip + 4 < in_end /* Backref takes up to 3 bytes, so don't bother */ + && ref > (u8 *)ibuf && ref[0] == ip[0] && ref[1] == ip[1] && ref[2] == ip[2]) { + + unsigned int len = 3; /* We already know 3 bytes match */ + const unsigned int maxlen = in_end - ip - 2 > LZFX_MAX_REF ? LZFX_MAX_REF : in_end - ip - 2; + + /* lit == 0: op + 3 must be < out_end (because we undo the run) + lit != 0: op + 3 + 1 must be < out_end */ + if (fx_expect_false(op - !lit + 3 + 1 >= out_end)) + return LZFX_ESIZE; + + op[-lit - 1] = lit << 3; /* Terminate literal run */ + op -= !lit; /* Undo run if length is zero */ + + /* Start checking at the fourth byte */ + while (len < maxlen && ref[len] == ip[len]) + len++; + + /* Format 1: [oooooLLL oooooooo] */ + if (len < 7) { + *op++ = ((off >> 8) << 3) + len; + *op++ = off; + + /* Format 2: [ooooo111 LLLLLLLL oooooooo] */ + } else { + *op++ = ((off >> 8) << 3) + 7; + *op++ = len - 7; + *op++ = off; + } + + lit = 0; + op++; + + ip += len - 1; /* ip = initial ip + #octets - 1 */ + + if (fx_expect_false(ip + 3 >= in_end)) { + ip++; /* Code following expects exit at bottom of loop */ + break; + } + + hval = LZFX_FRST(ip); + hval = LZFX_NEXT(hval, ip); + htab[LZFX_IDX(hval)] = ip; + + ip++; /* ip = initial ip + #octets */ + + } else { + /* Keep copying literal bytes */ + + if (fx_expect_false(op >= out_end)) + return LZFX_ESIZE; + + lit++; + *op++ = *ip++; + + if (fx_expect_false(lit == LZFX_MAX_LIT)) { + op[-lit - 1] = lit << 3; /* stop run */ + lit = 0; + op++; /* start run */ + } + + } /* if() found match in htab */ + + } /* while(ip < ilen -2) */ + + /* At most 3 bytes remain in input. We therefore need 4 bytes available + in the output buffer to store them (3 data + ctrl byte).*/ + if (op + 3 > out_end) + return LZFX_ESIZE; + + while (ip < in_end) { + + lit++; + *op++ = *ip++; + + if (fx_expect_false(lit == LZFX_MAX_LIT)) { + op[-lit - 1] = lit << 3; + lit = 0; + op++; + } + } + + op[-lit - 1] = lit << 3; + op -= !lit; + + *olen = op - (u8 *)obuf; + return 0; +} + +/* Decompressor */ +int lzfx_decompress(const void *ibuf, unsigned int ilen, void *obuf, unsigned int *olen) { + + u8 const * ip = (const u8 *)ibuf; + u8 const *const in_end = ip + ilen; + u8 * op = (u8 *)obuf; + u8 const *const out_end = (olen == NULL ? NULL : op + *olen); + + unsigned int remain_len = 0; + int rc; + + if (olen == NULL) + return LZFX_EARGS; + if (ibuf == NULL) { + if (ilen != 0) + return LZFX_EARGS; + *olen = 0; + return 0; + } + if (obuf == NULL) { + if (olen != 0) + return LZFX_EARGS; + return lzfx_getsize(ibuf, ilen, olen); + } + + do { + unsigned int ctrl = *ip++; + + /* Format LLLLL000: a literal byte string follows, of length L */ + if ((ctrl & 0x7) == 0) { + unsigned int len = ctrl >> 3; + + if (fx_expect_false(op + len > out_end)) { + --ip; /* Rewind to control byte */ + goto guess; + } + if (fx_expect_false(ip + len > in_end)) + return LZFX_ECORRUPT; + + do + *op++ = *ip++; + while (--len); + + /* Format #1 [oooooLLL oooooooo]: backref of length L+1 + ^^^^^ ^^^^^^^^ + A B + #2 [ooooo111 LLLLLLLL oooooooo] backref of length L+7 + ^^^^^ ^^^^^^^^ + A B + In both cases the location of the backref is computed from the + remaining part of the data as follows: + + location = op - A*256 - B - 1 + */ + } else { + + unsigned int len = ctrl & 0x7; + u8 * ref = op - ((ctrl >> 3) << 8) - 1; + + if (len == 7) + len += *ip++; /* i.e. format #2 */ + + if (fx_expect_false(op + len > out_end)) { + ip -= (len >= 7) ? 2 : 1; /* Rewind to control byte */ + goto guess; + } + if (fx_expect_false(ip >= in_end)) + return LZFX_ECORRUPT; + + ref -= *ip++; + + if (fx_expect_false(ref < (u8 *)obuf)) + return LZFX_ECORRUPT; + + do + *op++ = *ref++; + while (--len); + } + + } while (ip < in_end); + + *olen = op - (u8 *)obuf; + + return 0; + +guess: + rc = lzfx_getsize(ip, ilen - (ip - (u8 *)ibuf), &remain_len); + if (rc >= 0) + *olen = remain_len + (op - (u8 *)obuf); + return rc; +} + +/* Guess len. No parameters may be NULL; this is not checked. */ +static int lzfx_getsize(const void *ibuf, unsigned int ilen, unsigned int *olen) { + + u8 const * ip = (const u8 *)ibuf; + u8 const *const in_end = ip + ilen; + int tot_len = 0; + + while (ip < in_end) { + + unsigned int ctrl = *ip++; + + if ((ctrl & 0x7) == 0) { + + if (ip + (ctrl >> 3) > in_end) + return LZFX_ECORRUPT; + + tot_len += (ctrl >> 3); + ip += (ctrl >> 3); + + } else { + + unsigned int len = ctrl & 0x7; + + if (len == 7) { /* i.e. format #2 */ + len += *ip++; + } + + if (ip >= in_end) + return LZFX_ECORRUPT; + + ip++; /* skip the ref byte */ + + tot_len += len; + } + } + + *olen = tot_len; + + return 0; +} diff --git a/source/Core/lzfx/lzfx.h b/source/Core/lzfx/lzfx.h new file mode 100644 index 00000000..7b6e472e --- /dev/null +++ b/source/Core/lzfx/lzfx.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009 Andrew Collette + * http://lzfx.googlecode.com + * + * Implements an LZF-compatible compressor/decompressor based on the liblzf + * codebase written by Marc Lehmann. This code is released under the BSD + * license. License and original copyright statement follow. + * + * + * Copyright (c) 2000-2008 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LZFX_H +#define LZFX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Documented behavior, including function signatures and error codes, + is guaranteed to remain unchanged for releases with the same major + version number. Releases of the same major version are also able + to read each other's output, although the output itself is not + guaranteed to be byte-for-byte identical. +*/ +#define LZFX_VERSION_MAJOR 0 +#define LZFX_VERSION_MINOR 1 +#define LZFX_VERSION_STRING "0.1" + +/* Hashtable size (2**LZFX_HLOG entries) */ +#ifndef LZFX_HLOG +#define LZFX_HLOG 16 +#endif + +/* Predefined errors. */ +#define LZFX_ESIZE -1 /* Output buffer too small */ +#define LZFX_ECORRUPT -2 /* Invalid data for decompression */ +#define LZFX_EARGS -3 /* Arguments invalid (NULL) */ + +/* Buffer-to buffer compression. + + Supply pre-allocated input and output buffers via ibuf and obuf, and + their size in bytes via ilen and olen. Buffers may not overlap. + + On success, the function returns a non-negative value and the argument + olen contains the compressed size in bytes. On failure, a negative + value is returned and olen is not modified. +*/ +int lzfx_compress(const void *ibuf, unsigned int ilen, void *obuf, unsigned int *olen); + +/* Buffer-to-buffer decompression. + + Supply pre-allocated input and output buffers via ibuf and obuf, and + their size in bytes via ilen and olen. Buffers may not overlap. + + On success, the function returns a non-negative value and the argument + olen contains the uncompressed size in bytes. On failure, a negative + value is returned. + + If the failure code is LZFX_ESIZE, olen contains the minimum buffer size + required to hold the decompressed data. Otherwise, olen is not modified. + + Supplying a zero *olen is a valid and supported strategy to determine the + required buffer size. This does not require decompression of the entire + stream and is consequently very fast. Argument obuf may be NULL in + this case only. +*/ +int lzfx_decompress(const void *ibuf, unsigned int ilen, void *obuf, unsigned int *olen); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/source/Makefile b/source/Makefile index 21d93e03..b86c3c88 100644 --- a/source/Makefile +++ b/source/Makefile @@ -13,8 +13,16 @@ endif ALL_LANGUAGES=BG CS DA DE EN ES FI FR HR HU IT JA_JP LT NL NL_BE NO PL PT RU SK SL SR_CYRL SR_LATN SV TR UK YUE_HK ZH_CN ZH_TW +# Defines for host tools +ifeq ($(HOST_CC),) +HOST_CC := gcc +endif +HOST_OUTPUT_DIR=Objects/host + + # Enumerate all of the include directories APP_INC_DIR = ./Core/Inc +LZFX_INC_DIR = ./Core/lzfx MINIWARE_INC_CMSIS_DEVICE = ./Core/BSP/Miniware/Vendor/CMSIS/Device/ST/STM32F1xx/Include MINIWARE_CMSIS_CORE_INC_DIR = ./Core/BSP/Miniware/Vendor/CMSIS/Include MINIWARE_HAL_INC_DIR = ./Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Inc @@ -34,6 +42,7 @@ PINE_NMSIS_INC_DIR = ./Core/BSP/Pine64/Vendor/NMSIS/Core/Include PINE_FREERTOS_PORT_INC_DIR = ./Core/BSP/Pine64/Vendor/OS/FreeRTOS/Source/portable/GCC SOURCE_THREADS_DIR = ./Core/Threads SOURCE_CORE_DIR = ./Core/Src +SOURCE_LZFX_DIR = ./Core/lzfx SOURCE_DRIVERS_DIR = ./Core/Drivers INC_PD_DRIVERS_DIR = ./Core/Drivers/FUSB302 SOURCE_MIDDLEWARES_DIR = ./Middlewares @@ -101,6 +110,7 @@ DEV_CXXFLAGS= -MMD -MP -MF "$(@:%.o=%.d)" -MT "$@" endif INCLUDES = -I$(APP_INC_DIR) \ + -I$(LZFX_INC_DIR) \ -I$(FRTOS_CMIS_INC_DIR) \ -I$(FRTOS_INC_DIR) \ -I$(DRIVER_INC_DIR) \ @@ -114,7 +124,8 @@ SOURCE := $(shell find $(SOURCE_THREADS_DIR) -type f -name '*.c') \ $(shell find $(SOURCE_CORE_DIR) -type f -name '*.c') \ $(shell find $(SOURCE_DRIVERS_DIR) -type f -name '*.c') \ $(shell find $(DEVICE_BSP_DIR) -type f -name '*.c') \ -$(shell find $(SOURCE_MIDDLEWARES_DIR) -type f -name '*.c') +$(shell find $(SOURCE_MIDDLEWARES_DIR) -type f -name '*.c') \ +$(SOURCE_LZFX_DIR)/lzfx.c SOURCE_CPP := $(shell find $(SOURCE_THREADS_DIR) -type f -name '*.cpp') \ $(shell find $(SOURCE_CORE_DIR) -type f -name '*.cpp') \ $(shell find $(SOURCE_DRIVERS_DIR) -type f -name '*.cpp') \ @@ -296,10 +307,35 @@ all: $(ALL_FIRMWARE_TARGETS) $(SIZE) --format=berkeley $< $(OBJCOPY) $< -O binary $@ -$(HEXFILE_DIR)/$(model)_%.elf : $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) $(OUTPUT_DIR)/Core/Gen/Translation.%.o Makefile $(LDSCRIPT) +$(HEXFILE_DIR)/$(model)_%.elf : \ + $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation.%.o \ + Makefile $(LDSCRIPT) @test -d $(@D) || mkdir -p $(@D) @echo Linking $@ - @$(CPP) $(CXXFLAGS) $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) $(OUTPUT_DIR)/Core/Gen/Translation.$*.o $(LIBS) $(LINKER_FLAGS) -o$@ -Wl,-Map=$@.map + @$(CPP) $(CXXFLAGS) $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation.$*.o \ + $(LIBS) $(LINKER_FLAGS) -o$@ -Wl,-Map=$@.map + +$(HEXFILE_DIR)/$(model)_string_compressed_%.elf : \ + $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation_lzfx.%.o \ + Makefile $(LDSCRIPT) + @test -d $(@D) || mkdir -p $(@D) + @echo Linking $@ + @$(CPP) $(CXXFLAGS) $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation_lzfx.$*.o \ + $(LIBS) $(LINKER_FLAGS) -o$@ -Wl,-Map=$@.map + +$(HEXFILE_DIR)/$(model)_font_compressed_%.elf : \ + $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation_lzfx_font.%.o \ + Makefile $(LDSCRIPT) + @test -d $(@D) || mkdir -p $(@D) + @echo Linking $@ + @$(CPP) $(CXXFLAGS) $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation_lzfx_font.$*.o \ + $(LIBS) $(LINKER_FLAGS) -o$@ -Wl,-Map=$@.map $(OUT_OBJS): $(OUTPUT_DIR)/%.o : %.c Makefile @test -d $(@D) || mkdir -p $(@D) @@ -316,10 +352,61 @@ $(OUT_OBJS_S): $(OUTPUT_DIR)/%.o: %.S Makefile @echo 'Building file: $<' @$(AS) -c $(AFLAGS) $< -o $@ -Core/Gen/Translation.%.cpp: ../Translations/translation_%.json Makefile ../Translations/make_translation.py ../Translations/translations_def.js ../Translations/font_tables.py ../Translations/wqy-bitmapsong/wenquanyi_9pt.bdf - @test -d $(@D) || mkdir -p $(@D) +Core/Gen/Translation.%.cpp $(OUTPUT_DIR)/Core/Gen/translation.files/%.pickle: ../Translations/translation_%.json \ + ../Translations/make_translation.py \ + ../Translations/translations_def.js \ + ../Translations/font_tables.py \ + Makefile ../Translations/wqy-bitmapsong/wenquanyi_9pt.bdf + @test -d Core/Gen || mkdir -p Core/Gen + @test -d $(OUTPUT_DIR)/Core/Gen/translation.files || mkdir -p $(OUTPUT_DIR)/Core/Gen/translation.files @echo 'Generating translations for language $*' - @python3 ../Translations/make_translation.py -o $(PWD)/$@ $* + @python3 ../Translations/make_translation.py \ + -o $(PWD)/Core/Gen/Translation.$*.cpp \ + --output-pickled $(OUTPUT_DIR)/Core/Gen/translation.files/$*.pickle \ + $* + +# +# The recipes to produce compressed translation data: +# + +$(OUTPUT_DIR)/Core/Gen/translation.files/%.o: Core/Gen/Translation.%.cpp + @test -d $(@D) || mkdir -p $(@D) + @echo Generating $@ + @$(CPP) -c $(filter-out -flto -g3,$(CXXFLAGS)) $< -o $@ + +$(HOST_OUTPUT_DIR)/lzfx/liblzfx.so: Core/lzfx/lzfx.c + @test -d $(@D) || mkdir -p $(@D) + @echo Building host lzfx shared library $@ + @$(HOST_CC) -Wno-unused-result -fPIC -shared -O $^ -o $@ + +$(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.bin: $(OUTPUT_DIR)/Core/Gen/translation.files/%.o + @echo Dumping translation strings data from $< + @# Extract the raw strings data from the object file + @$(OBJCOPY) -O binary -j .rodata._ZL18TranslationIndices $< $(@D)/$*.data.TranslationIndices.bin + @test -s $(@D)/$*.data.TranslationIndices.bin || (rm $(@D)/$*.data.TranslationIndices.bin; echo 'ERROR: Output for .rodata._ZL18TranslationIndices is empty!' >&2; false) + @$(OBJCOPY) -O binary -j .rodata._ZL22TranslationStringsData $< $(@D)/$*.data.TranslationStrings.bin + @test -s $(@D)/$*.data.TranslationStrings.bin || (rm $(@D)/$*.data.TranslationStrings.bin; echo 'ERROR: Output for .rodata._ZL22TranslationStringsData is empty!' >&2; false) + @cat $(@D)/$*.data.TranslationIndices.bin $(@D)/$*.data.TranslationStrings.bin > $@ + +Core/Gen/Translation_lzfx.%.cpp: $(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.bin $(OUTPUT_DIR)/Core/Gen/translation.files/%.pickle $(HOST_OUTPUT_DIR)/lzfx/liblzfx.so + @test -d $(@D) || mkdir -p $(@D) + @echo Generating lzfx compressed translation for $* + @python3 ../Translations/make_translation.py \ + -o $(PWD)/Core/Gen/Translation_lzfx.$*.cpp \ + --input-pickled $(OUTPUT_DIR)/Core/Gen/translation.files/$*.pickle \ + --strings-bin $(OUTPUT_DIR)/Core/Gen/translation.files/$*.strings.bin \ + $* + +Core/Gen/Translation_lzfx_font.%.cpp: $(OUTPUT_DIR)/Core/Gen/translation.files/%.pickle $(HOST_OUTPUT_DIR)/lzfx/liblzfx.so + @test -d $(@D) || mkdir -p $(@D) + @echo Generating lzfx compressed translation for $* + @python3 ../Translations/make_translation.py \ + -o $(PWD)/Core/Gen/Translation_lzfx_font.$*.cpp \ + --input-pickled $(OUTPUT_DIR)/Core/Gen/translation.files/$*.pickle \ + --compress-font \ + $* + + clean : rm -Rf Core/Gen @@ -350,3 +437,5 @@ check-style: -include $(OUT_OBJS:.o=.d) -include $(OUT_OBJS_CPP:.o=.d) -include $(OUTPUT_DIR)/Core/Gen/Translation.*.d +-include $(OUTPUT_DIR)/Core/Gen/Translation_*.d +-include $(OUTPUT_DIR)/Core/Gen/translation.files/*.d