From 9f04900092e2f773a5d9f7fbffe3dfe4ae38a01d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=AE=B8=E6=99=9F=E6=98=8A?= <545403892@qq.com>
Date: Mon, 23 Mar 2026 13:07:16 +0800
Subject: [PATCH] Add textline, unzip image, and window widgets
- Implemented sgl_textline widget for displaying multi-line text with customizable properties such as font, color, and background.
- Added sgl_unzip_image widget to handle compressed image data, including drawing with transparency and color replacement.
- Created sgl_win widget for window management, featuring title text, close button, and customizable appearance attributes.
- Each widget includes necessary functions for creation, property setting, and rendering.
---
Core/Src/stm32f4xx_it.c | 55 +-
MDK-ARM/freertos_f407.uvoptx | 427 +-
MDK-ARM/freertos_f407.uvprojx | 177 +-
MDK-ARM/freertos_f407/freertos_f407.hex | 11117 ++++++++--------
User/application/app.c | 24 +-
User/board/board.c | 240 +-
User/system/lib/lcd/lcd_tft_154.c | 209 +-
User/system/lib/lcd/lcds.h | 16 +-
User/system/sgl/build.cmake | 28 +
User/system/sgl/core/build.cmake | 33 +
User/system/sgl/core/lm.cfg | 31 +
User/system/sgl/core/sgl_anim.c | 422 +
User/system/sgl/core/sgl_core.c | 1611 +++
User/system/sgl/core/sgl_event.c | 437 +
User/system/sgl/core/sgl_log.c | 78 +
User/system/sgl/core/sgl_math.c | 434 +
User/system/sgl/core/sgl_misc.c | 166 +
User/system/sgl/core/sgl_snprintf.c | 306 +
User/system/sgl/draw/build.cmake | 34 +
User/system/sgl/draw/lm.cfg | 32 +
User/system/sgl/draw/sgl_draw_arc.c | 244 +
User/system/sgl/draw/sgl_draw_circle.c | 299 +
User/system/sgl/draw/sgl_draw_icon.c | 79 +
User/system/sgl/draw/sgl_draw_line.c | 195 +
User/system/sgl/draw/sgl_draw_rect.c | 454 +
User/system/sgl/draw/sgl_draw_ring.c | 110 +
User/system/sgl/draw/sgl_draw_text.c | 357 +
User/system/sgl/draw/sgl_draw_xform.c | 157 +
User/system/sgl/fonts/build.cmake | 64 +
User/system/sgl/fonts/lm.cfg | 55 +
User/system/sgl/fonts/sgl_ascii_consolas14.c | 662 +
User/system/sgl/fonts/sgl_ascii_consolas23.c | 1198 ++
User/system/sgl/fonts/sgl_ascii_consolas24.c | 1239 ++
.../sgl/fonts/sgl_ascii_consolas24_compress.c | 1183 ++
User/system/sgl/fonts/sgl_ascii_consolas34.c | 2048 +++
User/system/sgl/fonts/sgl_ascii_song23.c | 1740 +++
User/system/sgl/include/sgl_anim.h | 392 +
User/system/sgl/include/sgl_cfgfix.h | 230 +
User/system/sgl/include/sgl_core.h | 2164 +++
User/system/sgl/include/sgl_draw.h | 513 +
User/system/sgl/include/sgl_errno.h | 170 +
User/system/sgl/include/sgl_event.h | 220 +
User/system/sgl/include/sgl_font.h | 66 +
User/system/sgl/include/sgl_list.h | 307 +
User/system/sgl/include/sgl_log.h | 193 +
User/system/sgl/include/sgl_math.h | 188 +
User/system/sgl/include/sgl_misc.h | 53 +
User/system/sgl/include/sgl_mm.h | 112 +
User/system/sgl/include/sgl_theme.h | 79 +
User/system/sgl/include/sgl_types.h | 337 +
User/system/sgl/lm.cfg | 117 +
User/system/sgl/mm/build.cmake | 52 +
User/system/sgl/mm/bump/sgl_mm.c | 137 +
User/system/sgl/mm/lm.cfg | 66 +
User/system/sgl/mm/lwmem/lwmem.c | 1439 ++
User/system/sgl/mm/lwmem/lwmem.h | 160 +
User/system/sgl/mm/lwmem/lwmem_opt.h | 156 +
User/system/sgl/mm/lwmem/sgl_mm.c | 137 +
User/system/sgl/mm/other/sgl_mm.c | 141 +
User/system/sgl/mm/tlsf/sgl_mm.c | 128 +
User/system/sgl/mm/tlsf/tlsf.c | 1265 ++
User/system/sgl/mm/tlsf/tlsf.h | 93 +
User/system/sgl/sgl.h | 65 +
User/system/sgl/sgl_config.h | 23 +
User/system/sgl/widgets/2dball/sgl_2dball.c | 122 +
User/system/sgl/widgets/2dball/sgl_2dball.h | 110 +
User/system/sgl/widgets/arc/sgl_arc.c | 119 +
User/system/sgl/widgets/arc/sgl_arc.h | 149 +
User/system/sgl/widgets/bar/sgl_bar.c | 123 +
User/system/sgl/widgets/bar/sgl_bar.h | 204 +
User/system/sgl/widgets/box/sgl_box.c | 265 +
User/system/sgl/widgets/box/sgl_box.h | 189 +
User/system/sgl/widgets/build.cmake | 54 +
User/system/sgl/widgets/button/sgl_button.c | 121 +
User/system/sgl/widgets/button/sgl_button.h | 193 +
User/system/sgl/widgets/canvas/sgl_canvas.c | 67 +
User/system/sgl/widgets/canvas/sgl_canvas.h | 97 +
.../sgl/widgets/checkbox/sgl_checkbox.c | 190 +
.../sgl/widgets/checkbox/sgl_checkbox.h | 132 +
User/system/sgl/widgets/circle/sgl_circle.c | 94 +
User/system/sgl/widgets/circle/sgl_circle.h | 138 +
.../sgl/widgets/dropdown/sgl_dropdown.c | 329 +
.../sgl/widgets/dropdown/sgl_dropdown.h | 227 +
User/system/sgl/widgets/ext_img/sgl_ext_img.c | 249 +
User/system/sgl/widgets/ext_img/sgl_ext_img.h | 224 +
User/system/sgl/widgets/icon/sgl_icon.c | 81 +
User/system/sgl/widgets/icon/sgl_icon.h | 107 +
.../sgl/widgets/keyboard/sgl_keyboard.c | 551 +
.../sgl/widgets/keyboard/sgl_keyboard.h | 275 +
User/system/sgl/widgets/label/sgl_label.c | 131 +
User/system/sgl/widgets/label/sgl_label.h | 191 +
User/system/sgl/widgets/led/sgl_led.c | 136 +
User/system/sgl/widgets/led/sgl_led.h | 157 +
User/system/sgl/widgets/line/sgl_line.c | 132 +
User/system/sgl/widgets/line/sgl_line.h | 112 +
.../sgl/widgets/listview/sgl_listview.c | 286 +
.../sgl/widgets/listview/sgl_listview.h | 88 +
User/system/sgl/widgets/lm.cfg | 54 +
User/system/sgl/widgets/msgbox/sgl_msgbox.c | 233 +
User/system/sgl/widgets/msgbox/sgl_msgbox.h | 378 +
.../sgl/widgets/numberkbd/sgl_numberkbd.c | 277 +
.../sgl/widgets/numberkbd/sgl_numberkbd.h | 259 +
User/system/sgl/widgets/polygon/sgl_polygon.c | 379 +
User/system/sgl/widgets/polygon/sgl_polygon.h | 166 +
.../sgl/widgets/progress/sgl_progress.c | 102 +
.../sgl/widgets/progress/sgl_progress.h | 234 +
.../sgl/widgets/rectangle/sgl_rectangle.c | 103 +
.../sgl/widgets/rectangle/sgl_rectangle.h | 135 +
User/system/sgl/widgets/ring/sgl_ring.c | 86 +
User/system/sgl/widgets/ring/sgl_ring.h | 103 +
User/system/sgl/widgets/scope/sgl_scope.c | 442 +
User/system/sgl/widgets/scope/sgl_scope.h | 304 +
User/system/sgl/widgets/scroll/sgl_scroll.c | 156 +
User/system/sgl/widgets/scroll/sgl_scroll.h | 149 +
User/system/sgl/widgets/slider/sgl_slider.c | 129 +
User/system/sgl/widgets/slider/sgl_slider.h | 174 +
User/system/sgl/widgets/switch/sgl_switch.c | 114 +
User/system/sgl/widgets/switch/sgl_switch.h | 205 +
User/system/sgl/widgets/textbox/sgl_textbox.c | 155 +
User/system/sgl/widgets/textbox/sgl_textbox.h | 182 +
.../sgl/widgets/textline/sgl_textline.c | 88 +
.../sgl/widgets/textline/sgl_textline.h | 169 +
.../sgl/widgets/unzip_image/sgl_unzip_image.c | 237 +
.../sgl/widgets/unzip_image/sgl_unzip_image.h | 124 +
User/system/sgl/widgets/win/sgl_win.c | 102 +
User/system/sgl/widgets/win/sgl_win.h | 214 +
126 files changed, 40271 insertions(+), 5789 deletions(-)
create mode 100644 User/system/sgl/build.cmake
create mode 100644 User/system/sgl/core/build.cmake
create mode 100644 User/system/sgl/core/lm.cfg
create mode 100644 User/system/sgl/core/sgl_anim.c
create mode 100644 User/system/sgl/core/sgl_core.c
create mode 100644 User/system/sgl/core/sgl_event.c
create mode 100644 User/system/sgl/core/sgl_log.c
create mode 100644 User/system/sgl/core/sgl_math.c
create mode 100644 User/system/sgl/core/sgl_misc.c
create mode 100644 User/system/sgl/core/sgl_snprintf.c
create mode 100644 User/system/sgl/draw/build.cmake
create mode 100644 User/system/sgl/draw/lm.cfg
create mode 100644 User/system/sgl/draw/sgl_draw_arc.c
create mode 100644 User/system/sgl/draw/sgl_draw_circle.c
create mode 100644 User/system/sgl/draw/sgl_draw_icon.c
create mode 100644 User/system/sgl/draw/sgl_draw_line.c
create mode 100644 User/system/sgl/draw/sgl_draw_rect.c
create mode 100644 User/system/sgl/draw/sgl_draw_ring.c
create mode 100644 User/system/sgl/draw/sgl_draw_text.c
create mode 100644 User/system/sgl/draw/sgl_draw_xform.c
create mode 100644 User/system/sgl/fonts/build.cmake
create mode 100644 User/system/sgl/fonts/lm.cfg
create mode 100644 User/system/sgl/fonts/sgl_ascii_consolas14.c
create mode 100644 User/system/sgl/fonts/sgl_ascii_consolas23.c
create mode 100644 User/system/sgl/fonts/sgl_ascii_consolas24.c
create mode 100644 User/system/sgl/fonts/sgl_ascii_consolas24_compress.c
create mode 100644 User/system/sgl/fonts/sgl_ascii_consolas34.c
create mode 100644 User/system/sgl/fonts/sgl_ascii_song23.c
create mode 100644 User/system/sgl/include/sgl_anim.h
create mode 100644 User/system/sgl/include/sgl_cfgfix.h
create mode 100644 User/system/sgl/include/sgl_core.h
create mode 100644 User/system/sgl/include/sgl_draw.h
create mode 100644 User/system/sgl/include/sgl_errno.h
create mode 100644 User/system/sgl/include/sgl_event.h
create mode 100644 User/system/sgl/include/sgl_font.h
create mode 100644 User/system/sgl/include/sgl_list.h
create mode 100644 User/system/sgl/include/sgl_log.h
create mode 100644 User/system/sgl/include/sgl_math.h
create mode 100644 User/system/sgl/include/sgl_misc.h
create mode 100644 User/system/sgl/include/sgl_mm.h
create mode 100644 User/system/sgl/include/sgl_theme.h
create mode 100644 User/system/sgl/include/sgl_types.h
create mode 100644 User/system/sgl/lm.cfg
create mode 100644 User/system/sgl/mm/build.cmake
create mode 100644 User/system/sgl/mm/bump/sgl_mm.c
create mode 100644 User/system/sgl/mm/lm.cfg
create mode 100644 User/system/sgl/mm/lwmem/lwmem.c
create mode 100644 User/system/sgl/mm/lwmem/lwmem.h
create mode 100644 User/system/sgl/mm/lwmem/lwmem_opt.h
create mode 100644 User/system/sgl/mm/lwmem/sgl_mm.c
create mode 100644 User/system/sgl/mm/other/sgl_mm.c
create mode 100644 User/system/sgl/mm/tlsf/sgl_mm.c
create mode 100644 User/system/sgl/mm/tlsf/tlsf.c
create mode 100644 User/system/sgl/mm/tlsf/tlsf.h
create mode 100644 User/system/sgl/sgl.h
create mode 100644 User/system/sgl/sgl_config.h
create mode 100644 User/system/sgl/widgets/2dball/sgl_2dball.c
create mode 100644 User/system/sgl/widgets/2dball/sgl_2dball.h
create mode 100644 User/system/sgl/widgets/arc/sgl_arc.c
create mode 100644 User/system/sgl/widgets/arc/sgl_arc.h
create mode 100644 User/system/sgl/widgets/bar/sgl_bar.c
create mode 100644 User/system/sgl/widgets/bar/sgl_bar.h
create mode 100644 User/system/sgl/widgets/box/sgl_box.c
create mode 100644 User/system/sgl/widgets/box/sgl_box.h
create mode 100644 User/system/sgl/widgets/build.cmake
create mode 100644 User/system/sgl/widgets/button/sgl_button.c
create mode 100644 User/system/sgl/widgets/button/sgl_button.h
create mode 100644 User/system/sgl/widgets/canvas/sgl_canvas.c
create mode 100644 User/system/sgl/widgets/canvas/sgl_canvas.h
create mode 100644 User/system/sgl/widgets/checkbox/sgl_checkbox.c
create mode 100644 User/system/sgl/widgets/checkbox/sgl_checkbox.h
create mode 100644 User/system/sgl/widgets/circle/sgl_circle.c
create mode 100644 User/system/sgl/widgets/circle/sgl_circle.h
create mode 100644 User/system/sgl/widgets/dropdown/sgl_dropdown.c
create mode 100644 User/system/sgl/widgets/dropdown/sgl_dropdown.h
create mode 100644 User/system/sgl/widgets/ext_img/sgl_ext_img.c
create mode 100644 User/system/sgl/widgets/ext_img/sgl_ext_img.h
create mode 100644 User/system/sgl/widgets/icon/sgl_icon.c
create mode 100644 User/system/sgl/widgets/icon/sgl_icon.h
create mode 100644 User/system/sgl/widgets/keyboard/sgl_keyboard.c
create mode 100644 User/system/sgl/widgets/keyboard/sgl_keyboard.h
create mode 100644 User/system/sgl/widgets/label/sgl_label.c
create mode 100644 User/system/sgl/widgets/label/sgl_label.h
create mode 100644 User/system/sgl/widgets/led/sgl_led.c
create mode 100644 User/system/sgl/widgets/led/sgl_led.h
create mode 100644 User/system/sgl/widgets/line/sgl_line.c
create mode 100644 User/system/sgl/widgets/line/sgl_line.h
create mode 100644 User/system/sgl/widgets/listview/sgl_listview.c
create mode 100644 User/system/sgl/widgets/listview/sgl_listview.h
create mode 100644 User/system/sgl/widgets/lm.cfg
create mode 100644 User/system/sgl/widgets/msgbox/sgl_msgbox.c
create mode 100644 User/system/sgl/widgets/msgbox/sgl_msgbox.h
create mode 100644 User/system/sgl/widgets/numberkbd/sgl_numberkbd.c
create mode 100644 User/system/sgl/widgets/numberkbd/sgl_numberkbd.h
create mode 100644 User/system/sgl/widgets/polygon/sgl_polygon.c
create mode 100644 User/system/sgl/widgets/polygon/sgl_polygon.h
create mode 100644 User/system/sgl/widgets/progress/sgl_progress.c
create mode 100644 User/system/sgl/widgets/progress/sgl_progress.h
create mode 100644 User/system/sgl/widgets/rectangle/sgl_rectangle.c
create mode 100644 User/system/sgl/widgets/rectangle/sgl_rectangle.h
create mode 100644 User/system/sgl/widgets/ring/sgl_ring.c
create mode 100644 User/system/sgl/widgets/ring/sgl_ring.h
create mode 100644 User/system/sgl/widgets/scope/sgl_scope.c
create mode 100644 User/system/sgl/widgets/scope/sgl_scope.h
create mode 100644 User/system/sgl/widgets/scroll/sgl_scroll.c
create mode 100644 User/system/sgl/widgets/scroll/sgl_scroll.h
create mode 100644 User/system/sgl/widgets/slider/sgl_slider.c
create mode 100644 User/system/sgl/widgets/slider/sgl_slider.h
create mode 100644 User/system/sgl/widgets/switch/sgl_switch.c
create mode 100644 User/system/sgl/widgets/switch/sgl_switch.h
create mode 100644 User/system/sgl/widgets/textbox/sgl_textbox.c
create mode 100644 User/system/sgl/widgets/textbox/sgl_textbox.h
create mode 100644 User/system/sgl/widgets/textline/sgl_textline.c
create mode 100644 User/system/sgl/widgets/textline/sgl_textline.h
create mode 100644 User/system/sgl/widgets/unzip_image/sgl_unzip_image.c
create mode 100644 User/system/sgl/widgets/unzip_image/sgl_unzip_image.h
create mode 100644 User/system/sgl/widgets/win/sgl_win.c
create mode 100644 User/system/sgl/widgets/win/sgl_win.h
diff --git a/Core/Src/stm32f4xx_it.c b/Core/Src/stm32f4xx_it.c
index 675eacb..cbd6ea0 100644
--- a/Core/Src/stm32f4xx_it.c
+++ b/Core/Src/stm32f4xx_it.c
@@ -22,6 +22,7 @@
#include "stm32f4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
+#include "sgl.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -71,8 +72,8 @@ extern TIM_HandleTypeDef htim6;
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
- * @brief This function handles Non maskable interrupt.
- */
+ * @brief This function handles Non maskable interrupt.
+ */
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
@@ -86,8 +87,8 @@ void NMI_Handler(void)
}
/**
- * @brief This function handles Hard fault interrupt.
- */
+ * @brief This function handles Hard fault interrupt.
+ */
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
@@ -101,8 +102,8 @@ void HardFault_Handler(void)
}
/**
- * @brief This function handles Memory management fault.
- */
+ * @brief This function handles Memory management fault.
+ */
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
@@ -116,8 +117,8 @@ void MemManage_Handler(void)
}
/**
- * @brief This function handles Pre-fetch fault, memory access fault.
- */
+ * @brief This function handles Pre-fetch fault, memory access fault.
+ */
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
@@ -131,8 +132,8 @@ void BusFault_Handler(void)
}
/**
- * @brief This function handles Undefined instruction or illegal state.
- */
+ * @brief This function handles Undefined instruction or illegal state.
+ */
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
@@ -146,8 +147,8 @@ void UsageFault_Handler(void)
}
/**
- * @brief This function handles Debug monitor.
- */
+ * @brief This function handles Debug monitor.
+ */
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
@@ -166,8 +167,8 @@ void DebugMon_Handler(void)
/******************************************************************************/
/**
- * @brief This function handles USART1 global interrupt.
- */
+ * @brief This function handles USART1 global interrupt.
+ */
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
@@ -186,12 +187,12 @@ void USART1_IRQHandler(void)
}
/**
- * @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts.
- */
+ * @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts.
+ */
void TIM6_DAC_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
-
+ sgl_tick_inc(1);
/* USER CODE END TIM6_DAC_IRQn 0 */
HAL_TIM_IRQHandler(&htim6);
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
@@ -200,8 +201,8 @@ void TIM6_DAC_IRQHandler(void)
}
/**
- * @brief This function handles DMA2 stream2 global interrupt.
- */
+ * @brief This function handles DMA2 stream2 global interrupt.
+ */
void DMA2_Stream2_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream2_IRQn 0 */
@@ -214,8 +215,8 @@ void DMA2_Stream2_IRQHandler(void)
}
/**
- * @brief This function handles DMA2 stream3 global interrupt.
- */
+ * @brief This function handles DMA2 stream3 global interrupt.
+ */
void DMA2_Stream3_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream3_IRQn 0 */
@@ -227,8 +228,8 @@ void DMA2_Stream3_IRQHandler(void)
}
/**
- * @brief This function handles USB On The Go FS global interrupt.
- */
+ * @brief This function handles USB On The Go FS global interrupt.
+ */
void OTG_FS_IRQHandler(void)
{
/* USER CODE BEGIN OTG_FS_IRQn 0 */
@@ -241,8 +242,8 @@ void OTG_FS_IRQHandler(void)
}
/**
- * @brief This function handles DMA2 stream6 global interrupt.
- */
+ * @brief This function handles DMA2 stream6 global interrupt.
+ */
void DMA2_Stream6_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream6_IRQn 0 */
@@ -254,8 +255,8 @@ void DMA2_Stream6_IRQHandler(void)
}
/**
- * @brief This function handles DMA2 stream7 global interrupt.
- */
+ * @brief This function handles DMA2 stream7 global interrupt.
+ */
void DMA2_Stream7_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream7_IRQn 0 */
diff --git a/MDK-ARM/freertos_f407.uvoptx b/MDK-ARM/freertos_f407.uvoptx
index 41e1ef1..f1045b4 100644
--- a/MDK-ARM/freertos_f407.uvoptx
+++ b/MDK-ARM/freertos_f407.uvoptx
@@ -200,6 +200,11 @@
1
hspi3,0x10
+
+ 9
+ 1
+ sgl_system
+
@@ -283,7 +288,7 @@
Application/User/Core
- 0
+ 1
0
0
0
@@ -1315,7 +1320,7 @@
User/system/lib/lcd
- 1
+ 0
0
0
0
@@ -1479,7 +1484,7 @@
User/system/little_shell
- 1
+ 0
0
0
0
@@ -1545,6 +1550,422 @@
+
+ User/system/sgl
+ 1
+ 0
+ 0
+ 0
+
+ 19
+ 96
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\core\sgl_core.c
+ sgl_core.c
+ 0
+ 0
+
+
+ 19
+ 97
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\core\sgl_anim.c
+ sgl_anim.c
+ 0
+ 0
+
+
+ 19
+ 98
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\core\sgl_event.c
+ sgl_event.c
+ 0
+ 0
+
+
+ 19
+ 99
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\core\sgl_log.c
+ sgl_log.c
+ 0
+ 0
+
+
+ 19
+ 100
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\core\sgl_math.c
+ sgl_math.c
+ 0
+ 0
+
+
+ 19
+ 101
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\core\sgl_misc.c
+ sgl_misc.c
+ 0
+ 0
+
+
+ 19
+ 102
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\core\sgl_snprintf.c
+ sgl_snprintf.c
+ 0
+ 0
+
+
+ 19
+ 103
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\draw\sgl_draw_arc.c
+ sgl_draw_arc.c
+ 0
+ 0
+
+
+ 19
+ 104
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\draw\sgl_draw_circle.c
+ sgl_draw_circle.c
+ 0
+ 0
+
+
+ 19
+ 105
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\draw\sgl_draw_icon.c
+ sgl_draw_icon.c
+ 0
+ 0
+
+
+ 19
+ 106
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\draw\sgl_draw_line.c
+ sgl_draw_line.c
+ 0
+ 0
+
+
+ 19
+ 107
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\draw\sgl_draw_rect.c
+ sgl_draw_rect.c
+ 0
+ 0
+
+
+ 19
+ 108
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\draw\sgl_draw_ring.c
+ sgl_draw_ring.c
+ 0
+ 0
+
+
+ 19
+ 109
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\draw\sgl_draw_text.c
+ sgl_draw_text.c
+ 0
+ 0
+
+
+ 19
+ 110
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\draw\sgl_draw_xform.c
+ sgl_draw_xform.c
+ 0
+ 0
+
+
+ 19
+ 111
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\fonts\sgl_ascii_song23.c
+ sgl_ascii_song23.c
+ 0
+ 0
+
+
+ 19
+ 112
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\mm\lwmem\sgl_mm.c
+ sgl_mm.c
+ 0
+ 0
+
+
+ 19
+ 113
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\mm\lwmem\lwmem.c
+ lwmem.c
+ 0
+ 0
+
+
+ 19
+ 114
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\label\sgl_label.c
+ sgl_label.c
+ 0
+ 0
+
+
+ 19
+ 115
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\line\sgl_line.c
+ sgl_line.c
+ 0
+ 0
+
+
+ 19
+ 116
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\rectangle\sgl_rectangle.c
+ sgl_rectangle.c
+ 0
+ 0
+
+
+ 19
+ 117
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\circle\sgl_circle.c
+ sgl_circle.c
+ 0
+ 0
+
+
+ 19
+ 118
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\ring\sgl_ring.c
+ sgl_ring.c
+ 0
+ 0
+
+
+ 19
+ 119
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\arc\sgl_arc.c
+ sgl_arc.c
+ 0
+ 0
+
+
+ 19
+ 120
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\button\sgl_button.c
+ sgl_button.c
+ 0
+ 0
+
+
+ 19
+ 121
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\slider\sgl_slider.c
+ sgl_slider.c
+ 0
+ 0
+
+
+ 19
+ 122
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\progress\sgl_progress.c
+ sgl_progress.c
+ 0
+ 0
+
+
+ 19
+ 123
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\switch\sgl_switch.c
+ sgl_switch.c
+ 0
+ 0
+
+
+ 19
+ 124
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\msgbox\sgl_msgbox.c
+ sgl_msgbox.c
+ 0
+ 0
+
+
+ 19
+ 125
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\textline\sgl_textline.c
+ sgl_textline.c
+ 0
+ 0
+
+
+ 19
+ 126
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\textbox\sgl_textbox.c
+ sgl_textbox.c
+ 0
+ 0
+
+
+ 19
+ 127
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\checkbox\sgl_checkbox.c
+ sgl_checkbox.c
+ 0
+ 0
+
+
+ 19
+ 128
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\icon\sgl_icon.c
+ sgl_icon.c
+ 0
+ 0
+
+
+ 19
+ 129
+ 1
+ 0
+ 0
+ 0
+ ..\User\system\sgl\widgets\numberkbd\sgl_numberkbd.c
+ sgl_numberkbd.c
+ 0
+ 0
+
+
+
::CMSIS
0
diff --git a/MDK-ARM/freertos_f407.uvprojx b/MDK-ARM/freertos_f407.uvprojx
index 1b50b6a..a597ca1 100644
--- a/MDK-ARM/freertos_f407.uvprojx
+++ b/MDK-ARM/freertos_f407.uvprojx
@@ -339,7 +339,7 @@
--diag_suppress=68 --diag_suppress=111 --diag_suppress=188 --diag_suppress=223 --diag_suppress=546 --diag_suppress=1295
STM32,USE_HAL_DRIVER,STM32F407xx
- ../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../User/application;../User/board;../User/system;../User/system/lib/inc;../User/system/bsp;../FATFS/Target;../FATFS/App;../Middlewares/Third_Party/FatFs/src;../User/system/lib/lcd;../User/system/lib/lcd/gui/Config;../User/system/lib/lcd/gui/Core;../USB_DEVICE/App;../USB_DEVICE/Target;../Middlewares/ST/STM32_USB_Device_Library/Core/Inc;../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc;../User/system/letter_shell
+ ../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../User/application;../User/board;../User/system;../User/system/lib/inc;../User/system/bsp;../FATFS/Target;../FATFS/App;../Middlewares/Third_Party/FatFs/src;../User/system/lib/lcd;../User/system/lib/lcd/gui/Config;../User/system/lib/lcd/gui/Core;../USB_DEVICE/App;../USB_DEVICE/Target;../Middlewares/ST/STM32_USB_Device_Library/Core/Inc;../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc;../User/system/letter_shell;..\User\system\sgl;..\User\system\sgl\include;..\User\system\sgl\widgets;..\User\system\sgl\mm\lwmem
@@ -3621,6 +3621,181 @@
+
+ User/system/sgl
+
+
+ sgl_core.c
+ 1
+ ..\User\system\sgl\core\sgl_core.c
+
+
+ sgl_anim.c
+ 1
+ ..\User\system\sgl\core\sgl_anim.c
+
+
+ sgl_event.c
+ 1
+ ..\User\system\sgl\core\sgl_event.c
+
+
+ sgl_log.c
+ 1
+ ..\User\system\sgl\core\sgl_log.c
+
+
+ sgl_math.c
+ 1
+ ..\User\system\sgl\core\sgl_math.c
+
+
+ sgl_misc.c
+ 1
+ ..\User\system\sgl\core\sgl_misc.c
+
+
+ sgl_snprintf.c
+ 1
+ ..\User\system\sgl\core\sgl_snprintf.c
+
+
+ sgl_draw_arc.c
+ 1
+ ..\User\system\sgl\draw\sgl_draw_arc.c
+
+
+ sgl_draw_circle.c
+ 1
+ ..\User\system\sgl\draw\sgl_draw_circle.c
+
+
+ sgl_draw_icon.c
+ 1
+ ..\User\system\sgl\draw\sgl_draw_icon.c
+
+
+ sgl_draw_line.c
+ 1
+ ..\User\system\sgl\draw\sgl_draw_line.c
+
+
+ sgl_draw_rect.c
+ 1
+ ..\User\system\sgl\draw\sgl_draw_rect.c
+
+
+ sgl_draw_ring.c
+ 1
+ ..\User\system\sgl\draw\sgl_draw_ring.c
+
+
+ sgl_draw_text.c
+ 1
+ ..\User\system\sgl\draw\sgl_draw_text.c
+
+
+ sgl_draw_xform.c
+ 1
+ ..\User\system\sgl\draw\sgl_draw_xform.c
+
+
+ sgl_ascii_song23.c
+ 1
+ ..\User\system\sgl\fonts\sgl_ascii_song23.c
+
+
+ sgl_mm.c
+ 1
+ ..\User\system\sgl\mm\lwmem\sgl_mm.c
+
+
+ lwmem.c
+ 1
+ ..\User\system\sgl\mm\lwmem\lwmem.c
+
+
+ sgl_label.c
+ 1
+ ..\User\system\sgl\widgets\label\sgl_label.c
+
+
+ sgl_line.c
+ 1
+ ..\User\system\sgl\widgets\line\sgl_line.c
+
+
+ sgl_rectangle.c
+ 1
+ ..\User\system\sgl\widgets\rectangle\sgl_rectangle.c
+
+
+ sgl_circle.c
+ 1
+ ..\User\system\sgl\widgets\circle\sgl_circle.c
+
+
+ sgl_ring.c
+ 1
+ ..\User\system\sgl\widgets\ring\sgl_ring.c
+
+
+ sgl_arc.c
+ 1
+ ..\User\system\sgl\widgets\arc\sgl_arc.c
+
+
+ sgl_button.c
+ 1
+ ..\User\system\sgl\widgets\button\sgl_button.c
+
+
+ sgl_slider.c
+ 1
+ ..\User\system\sgl\widgets\slider\sgl_slider.c
+
+
+ sgl_progress.c
+ 1
+ ..\User\system\sgl\widgets\progress\sgl_progress.c
+
+
+ sgl_switch.c
+ 1
+ ..\User\system\sgl\widgets\switch\sgl_switch.c
+
+
+ sgl_msgbox.c
+ 1
+ ..\User\system\sgl\widgets\msgbox\sgl_msgbox.c
+
+
+ sgl_textline.c
+ 1
+ ..\User\system\sgl\widgets\textline\sgl_textline.c
+
+
+ sgl_textbox.c
+ 1
+ ..\User\system\sgl\widgets\textbox\sgl_textbox.c
+
+
+ sgl_checkbox.c
+ 1
+ ..\User\system\sgl\widgets\checkbox\sgl_checkbox.c
+
+
+ sgl_icon.c
+ 1
+ ..\User\system\sgl\widgets\icon\sgl_icon.c
+
+
+ sgl_numberkbd.c
+ 1
+ ..\User\system\sgl\widgets\numberkbd\sgl_numberkbd.c
+
+
+
::CMSIS
diff --git a/MDK-ARM/freertos_f407/freertos_f407.hex b/MDK-ARM/freertos_f407/freertos_f407.hex
index 0975ca9..488e04d 100644
--- a/MDK-ARM/freertos_f407/freertos_f407.hex
+++ b/MDK-ARM/freertos_f407/freertos_f407.hex
@@ -1,8 +1,8 @@
:020000040800F2
-:10000000B019012061020008E5470008C343000859
-:10001000E14700089D090008818E000800000000EB
+:10000000405601206102000805490008E344000849
+:1000100001490008BD0A0008B58F00080000000073
:10002000000000000000000000000000A101000826
-:10003000D30B000800000000FD010008A95B0008C8
+:10003000F30C000800000000FD010008C95C000886
:100040007B0200087B0200087B0200087B0200089C
:100050007B0200087B0200087B0200087B0200088C
:100060007B0200087B0200087B0200087B0200087C
@@ -12,19 +12,19 @@
:1000A0007B0200087B0200087B0200087B0200083C
:1000B0007B0200087B0200087B0200087B0200082C
:1000C0007B0200087B0200087B0200087B0200081C
-:1000D0007B020008616400087B0200087B020008C4
+:1000D0007B020008956500087B0200087B0200088F
:1000E0007B0200087B0200087B0200087B020008FC
:1000F0007B0200087B0200087B0200087B020008EC
:100100007B0200087B0200087B0200087B020008DB
-:100110007B0200087B020008A95C00087B02000843
-:100120007B0200087B020008890A0008990A00087F
+:100110007B0200087B020008C95D00087B02000822
+:100120007B0200087B020008A90B0008B90B00083D
:100130007B0200087B0200087B0200087B020008AB
-:100140007B0200087B0200087B020008E9470008E8
-:100150007B020008A90A0008B90A00087B0200080F
+:100140007B0200087B0200087B02000809490008C6
+:100150007B020008C90B0008D90B00087B020008CD
:100160007B0200087B0200087B0200087B0200087B
:100170007B0200087B0200087B02000800000000F0
-:100180007B0200087B020008DFF810D000F050FB73
-:100190000048004785A70008AFF30080B019012090
+:100180007B0200087B020008DFF810D000F0E0FBE3
+:100190000048004701AC0008AFF300804056012042
:1001A0002C4B19680868B0E8F04F80F30988BFF35A
:1001B0006F8F4FF0000080F311887047000000003F
:1001C00008480068006880F308884FF0000080F35A
@@ -33,5457 +33,5666 @@
:1001F00070010160704700BF88ED00E0EFF30980F7
:10020000BFF36F8F134B1A681EF0100F08BF20ED5D
:10021000108A20E9F04F106009B44FF0500080F3CD
-:100220001188BFF34F8FBFF36F8F0DF03BFA4FF084
+:100220001188BFF34F8FBFF36F8F11F0A5FD4FF013
:10023000000080F3118809BC19680868B0E8F04F25
:100240001EF0100F08BFB0EC108A80F30988BFF3CE
:100250006F8F704714000020EFF305807047000097
:100260000648804706480047FEE7FEE7FEE7FEE750
-:10027000FEE7FEE7FEE7FEE7FEE7FEE7955C000827
+:10027000FEE7FEE7FEE7FEE7FEE7FEE7B55D000806
:10028000890100082DE9F05F0546002092469B4653
:1002900088460646814640241BE02846414647469C
-:1002A000224600F0A6F953465A46C01A914110D38F
-:1002B00011461846224600F08DF92D1A67EB010809
-:1002C0004F4622460120002100F084F917EB000977
+:1002A000224600F036FA53465A46C01A914110D3FE
+:1002B00011461846224600F01DFA2D1A67EB010878
+:1002C0004F4622460120002100F014FA17EB0009E6
:1002D0004E41201EA4F10104DFDC484631462A4687
-:1002E0004346BDE8F09F40EA01039B0703D009E0C5
-:1002F00008C9121F08C0042AFAD203E011F8013B12
-:1003000000F8013B521EF9D27047D2B201E000F86A
-:10031000012B491EFBD270470022F6E710B51346A9
-:100320000A4604461946FFF7F0FF204610BD421C5E
-:1003300010F8011B0029FBD1801A704710B500226C
-:1003400000E0521C835C8C5CA34201D1002BF8D1ED
-:10035000D8B2E1B2401A10BD30B5054600200346C0
-:1003600000E05B1C934205D2EC5CC85C201A01D112
-:10037000002CF6D130BD2DE9FE4F804681EA030006
-:10038000C00F0C46009021F0004123F00045B8EB6F
-:100390000200A94105D24046214690461C460B4624
-:1003A000024623F00040104347D0270DC7F30A0050
-:1003B000C3F30A510290401A019040286BDAC3F34C
-:1003C000130040F4801B0098924620B10023D2EB2A
-:1003D000030A63EB0B0B01985946C0F140025046EB
-:1003E00000F0F8F806460D4650465946019A00F0CE
-:1003F00010F910EB08006141002487EA115284EAE9
-:10040000E7731A4340D0009A62B3019A012A4FEA77
-:10041000075215DC001B61EB02014FF0004202EABB
-:100420000752CDE90042001C41F5801132462B46AF
-:1004300000F010F903B0BDE8F08F40462146F9E71F
-:10044000001B61EB0201001C41F5801300185B41A9
-:100450002018A2F5001747EB030140EAD570B61942
-:100460006D4111E06D084FEA360645EAC0754FEA66
-:100470000752001B61EB0201001C41F58011490885
-:100480004FEA30000019514132462B4603B0BDE817
-:10049000F04F00F0D0B80098012240000023D0EBCC
-:1004A000020263EBE073009821464FEAE074B8EB78
-:1004B000000061EB0401E9E783F000435BE781F0B2
-:1004C000004158E72DE9FE4F81EA030404F000449F
-:1004D00021F0004100944FF0000B23F0004350EA5C
-:1004E00001045ED052EA03045BD0C3F30A54C1F3A3
-:1004F0000A552C44A4F2F3340194A0FB0254C1F336
-:10050000130141F48011C3F3130343F4801301FB7F
-:10051000024400FB034E840A970A44EA815447EAE6
-:100520008357A4FB076802958D0A05FB07854FEAF0
-:10053000932C04FB0C542705029D4FEA065847EA0A
-:100540001637B5EB08056EEB070C870E920E47EADF
-:10055000811742EA8312A7FB0201B6EB0B0164EBA1
-:1005600000042B0D43EA0C335E1844EB1C50DA46B2
-:100570005146E7FB0201C5F313044FEA0B3343EA8C
-:1005800014534FEA0432019C43EA0603A4F10C041D
-:100590000294009CCDE900B400F05CF803B0BDE823
-:1005A000F08F00200146F9E730B50B4601460020E8
-:1005B0002022012409E021FA02F59D4205D303FA25
-:1005C00002F5491B04FA02F52844151EA2F10102A6
-:1005D000F1DC30BD202A04DB203A00FA02F10020D1
-:1005E00070479140C2F1200320FA03F31943904071
-:1005F0007047202A04DB203A21FA02F000217047DC
-:1006000021FA02F3D040C2F120029140084319467A
-:100610007047202A06DBCB17203A41FA02F043EA62
-:10062000E07306E041FA02F3D040C2F120029140AB
-:1006300008431946704710B5141E73F1000408DA18
-:10064000401C41F1000192185B411A4301D120F096
-:10065000010010BD2DE9F04D92469B4611B1B1FA53
-:1006600081F202E0B0FA80F220329046FFF7B2FF4A
-:1006700004460F4640EA0A0041EA0B0153465A4637
-:10068000084313D0114653EA010019D0C8F14002C3
-:100690005046FFF7AEFF05460E46504659464246C5
-:1006A000FFF798FF084305D0012004E020463946B3
-:1006B000BDE8F08D0020054346EAE0762C43374341
-:1006C0000A986305E40AA0EB08000022FD0A44EA48
-:1006D00047540A3002D500200146E9E70105101908
-:1006E0006941DDE9084500196941BDE8F04DA2E71F
-:1006F0002DE9F04D81EA030404F0004B21F00045A0
-:1007000014464FF0000A23F0004150EA050220D0C1
-:1007100054EA01021DD0C5F30A570246C5F313037C
-:10072000C1F31300C1F30A5640F4801543F480135B
-:10073000A7EB0608101BD64608F2FD3873EB050040
-:1007400002D308F1010801E092185B41B8F1000FF3
-:1007500003DA00200146BDE8F08D00204FF480113F
-:10076000064684460EE0171B73EB050705D3121BE4
-:1007700063EB050306434CEA010C49084FEA3000DD
-:1007800092185B4150EA0107EDD152EA030012D002
-:1007900082EA040083EA0501084305D0101BAB413F
-:1007A00006D20122002306E000224FF0004302E0BF
-:1007B0006FF0010253101AEB06004CEB085110EBDE
-:1007C0000A0041EB0B01BDE8F04DFFF734BFC1F368
-:1007D0000A52C1F3130140F2FF3341F480119A42EF
-:1007E00002DA00200146704740F233439A42A2F2F7
-:1007F000334202DC5242FFF7FCBEFFF7EBBE0000C3
-:1008000030B5041E71F1000404DB4FF00044404297
-:1008100064EB0101141E73F1000405DB1C464FF06C
-:100820000043524263EB0403994208BF904230BD3B
-:10083000064C074D06E0E06840F0010394E807002D
-:1008400098471034AC42F6D3FFF7A2FCEC530108F2
-:100850001C54010870B58C1810F8015B15F00703E3
-:1008600001D110F8013B2A1106D110F8012B03E049
-:1008700010F8016B01F8016B5B1EF9D12B0705D451
-:100880000023521E0DD401F8013BFAE710F8013B9A
-:10089000CB1A921C03E013F8015B01F8015B521EB6
-:1008A000F9D5A142D8D3002070BD000010B50124B5
-:1008B000A102034800F03AFD00B10024204610BD1B
-:1008C0000004024010B504462146024802F0DCFC58
-:1008D00010BD00000C05002010B5044802F0E7FC34
-:1008E000042801D0012010BD0020FCE70C050020E9
-:1008F00010B5002400F014F8012801D0012010BD2B
-:10090000064802F0E6FC044634B94FF4006103489F
-:1009100002F070FB00B101242046F0E70C05002036
-:1009200008B501200090FFF7C1FF08B90020009032
-:100930009DF8000008BD00002DE9F04104460D4679
-:100940001646002733462A462146044802F0F6FDA3
-:1009500000B101273846BDE8F08100000C050020F9
-:1009600010B500220121024800680AF0CFF810BD3E
-:10097000A80000202DE9F04104460D461646002748
-:1009800033462A462146044802F086FE00B101277C
-:100990003846BDE8F08100000C05002000BFFEE7EE
-:1009A0000346042B15D007DC7BB1012B0ED0022BA4
-:1009B0000DD0032B12D10BE0202B0BD0212B0AD012
-:1009C000222B09D0232B09D107E008E007E006E03D
-:1009D00005E004E003E002E001E000E000BF00BF4A
-:1009E000002070470020704710B5002204490548D8
-:1009F00005F0EFFF0449034805F0DCFF002010BDBF
-:100A00006C02012090F500206CFA002070B50446BD
-:100A10000D46204629680CF02FFB2146034805F0BF
-:100A2000C9FF024805F092FF002070BD90F500203C
-:100A300010B503460C460021084610BD2DE9F041D3
-:100A400004460D4600260A48D0F8BC72D7F81402B6
-:100A500010B10120BDE8F0812A462146044805F086
-:100A6000B8FF034806F068F806463046F2E7000093
-:100A700090F50020024600BF1AB901E000BF00BF98
-:100A8000FCE700BF0120704710B5024800F060F994
-:100A900010BD0000EC06002010B5024800F058F927
-:100AA00010BD00009005002010B5024800F050F97C
-:100AB00010BD0000F005002010B5024800F048F914
-:100AC00010BD00004C07002001460878103818239C
-:100AD000B0FBF3F20848805CC865032A05D90868B2
-:100AE0006FF30900001D886503E008686FF30900D3
-:100AF0008865886D7047000088E70008014600207F
-:100B00008A6A8B69CBB932B1012A0DD0022A03D08F
-:100B1000032A10D10EE000BFCB6A03F08073B3F15B
-:100B2000807F00D1012007E0CB6AB3F1C07F00D104
-:100B3000012001E000E000BF34E08B69B3F5005F05
-:100B40001AD132B1012A07D0022A03D0032A11D1C7
-:100B50000AE000BF01200EE0CB6A03F08073B3F11E
-:100B6000807F00D1012006E0CB6AB3F1C07F00D1C5
-:100B7000012000E000BF15E032B1012A05D0022AB1
-:100B800004D0032A0CD103E000BF00BF012008E01D
-:100B9000CB6A03F08073B3F1807F00D1012000E0C5
-:100BA00000BF00BF704730B50468246824F4802477
-:100BB00005682C60046863608468402C04D1046874
-:100BC000A2600468E16003E00468A1600468E26078
-:100BD00030BD704772B600BFFEE730B504460D4623
-:100BE00000222946204600F001F830BDF0B503464A
-:100BF000012500241148807B02281CDA00200F4EBA
-:100C0000B67B0E4FB8553846867B001D40F826301F
-:100C1000001F867B0C3082553E46B07B461CBE735F
-:100C2000044604F1300008703A2048702F20887084
-:100C30000020C87000252846F0BD000080F5002087
-:100C400070B50A480468001D0568001D0668344434
-:100C500054B108220649204603F0B5FB042204499A
-:100C60001031284603F0AFFB70BD0000107AFF1F63
-:100C70006601002070B50446A56D00F06FFB0646C6
-:100C800094F83500022808D08020606500BF00205D
-:100C900084F8340000BF012070BD2068006820F097
-:100CA0001600216808602068406920F080002168F3
-:100CB0004861206C08B9A06C28B12068006820F059
-:100CC0000800216808602068006820F001002168A1
-:100CD000086010E000F042FB801B05280BD92020A3
-:100CE0006065032084F8350000BF002084F83400DC
-:100CF00000BF0320D0E72068006800F00100002852
-:100D0000E8D194F85C103F208840A860012084F866
-:100D1000350000BF002084F8340000BF00BFBBE7EF
-:100D2000014691F83500022803D080204865012053
-:100D30007047052081F835000868006820F0010040
-:100D40000A6810600020F3E70146486D7047000014
-:100D5000F8B50446002000908C4800684FF4165106
-:100D6000B0FBF1F7A56D2E6894F85C100820884060
-:100D7000304098B12068006800F0040070B120682D
-:100D8000006820F004002168086094F85C100820D6
-:100D90008840A860606D40F00100606594F85C10C8
-:100DA00001208840304068B12068406900F0800030
-:100DB00040B194F85C1001208840A860606D40F05C
-:100DC0000200606594F85C1004208840304068B1EF
-:100DD0002068006800F0020040B194F85C10042024
-:100DE0008840A860606D40F00400606594F85C1075
-:100DF00010208840304078B32068006800F0080078
-:100E000050B394F85C1010208840A86020680068F7
-:100E100000F4802080B12068006800F4002028B928
-:100E2000206CC8B12046216C884715E0A06C98B1B1
-:100E30002046A16C88470FE02068006800F48070AD
-:100E400028B92068006820F0080021680860206C3C
-:100E500010B12046216C884794F85C10202088400F
-:100E60003040002865D02068006800F0100000289D
-:100E70005FD094F85C1020208840A86094F835007A
-:100E8000052828D12068006820F016002168086035
-:100E90002068406920F0800021684861206C08B912
-:100EA000A06C28B12068006820F008002168086064
-:100EB00094F85C103F208840A860012084F8350039
-:100EC00000BF002084F8340000BF206D10B1204620
-:100ED000216D8847F8BD2068006800F4802080B14B
-:100EE0002068006800F4002028B9606C10B120462A
-:100EF000616C88471DE0E06BD8B12046E16B884704
-:100F000017E02068006800F4807068B92068006805
-:100F100020F0100021680860012084F8350000BF2F
-:100F2000002084F8340000BFE06B10B12046E16B74
-:100F30008847606D38B3606D00F00100F0B10520A6
-:100F400084F835002068006820F0010021680860FE
-:100F500000BF0098401C0090B84200D905E020680E
-:100F6000006800F001000028F3D100BF012084F8E0
-:100F7000350000BF002084F8340000BFE06C10B1E1
-:100F80002046E16C884700BFA4E700001000002065
-:100F90002DE9F0410446002500F0E0F9074614B9B8
-:100FA0000120BDE8F081606A00B100BF022084F832
-:100FB000350000BF002084F8340000BF20680068BE
-:100FC00020F00100216808600AE000F0C7F9C01BAA
-:100FD000052805D920206065032084F83500E0E766
-:100FE0002068006800F001000028EED12068056844
-:100FF00021480540D4E901010843E168084321691B
-:10100000084361690843A1690843E1690843216A0B
-:1010100008430543606A042803D1D4E90B0108435F
-:101020000543206805602068456925F00705606A6A
-:101030000543606A04280DD1A06A0543E06A48B1FF
-:101040002046FFF75BFD28B140206065012084F851
-:101050003500A6E7206845612046FFF735FD0646C6
-:1010600094F85C103F208840B0600020606501204B
-:1010700084F83500002094E73F8010F02DE9F04718
-:1010800004460D4616461F464FF00008D4F8589007
-:1010900000BF94F83400012802D10220BDE8F08797
-:1010A000012084F8340000BF94F83500012825D1D0
-:1010B000022084F83500002060653B463246294610
-:1010C0002046FFF770FD94F85C103F208840C9F877
-:1010D00008002068006840F0160021680860206C55
-:1010E00028B12068006840F0080021680860206886
-:1010F000006840F001002168086006E000BF0020A1
-:1011000084F8340000BF4FF002084046C6E70000F4
-:1011100070B5044600F022F906462546681C10B159
-:1011200004480078054400BF00F018F9801BA8426D
-:10113000FAD370BD0C000020F8B502460B4600251E
-:10114000002400200021D6E0012606FA01F51E68E1
-:1011500006EA0504AC4274D11E7906F00306012E9E
-:1011600004D01E7906F00306022E13D190684F00BA
-:101170000326BE40B0434F00DE68BE40304390605F
-:10118000506801268E40B0431E79C6F300168E408B
-:10119000304350601E7906F00306032E09D0D06854
-:1011A0004F000326BE40B0434F009E68BE40304310
-:1011B000D0601E7906F00306022E13D1CF0802F18B
-:1011C000200656F827004E07F70E0F26BE40B04304
-:1011D0004F07FF0E1E69BE403043CF0802F12006C4
-:1011E00046F8270010684F000326BE40B0431E7922
-:1011F00006F003064F00BE40304310605E6806F400
-:101200004036002E76D000BF002600963C4E366851
-:1012100046F480463A4F3E603E46366806F48046C5
-:10122000009600BF00BF374E8F0856F827008E0784
-:10123000370F0F26BE40B043334EB24202D10026D4
-:1012400024E057E0314EB24201D101261EE0304E7B
-:10125000B24201D1022619E02E4EB24201D103263C
-:1012600014E02D4EB24201D104260FE02B4EB242C3
-:1012700001D105260AE02A4EB24201D1062605E038
-:10128000284EB24201D1072600E008268F073F0F03
-:10129000BE4030431B4E8F0846F82700224E306870
-:1012A000A0435E6806F4801606B120431E4E3060EF
-:1012B000361D3068A0435E6806F4001606B1204370
-:1012C000194E361D3060184E361F3068A0435E68D8
-:1012D00006F4003606B12043134E361F3060361F29
-:1012E0003068A0435E6806F4803606B120430E4E97
-:1012F000083E3060491C1029FFF426AFF8BD0000FD
-:101300004438024008380140000002400004024016
-:1013100000080240000C024000100240001402408D
-:1013200000180240001C0240083C014002461369BC
-:101330000B400BB1012000E00020704710B542695E
-:1013400021EA020302EA010443EA0443836110BD77
-:101350000AB1816101E00B048361704701480068B4
-:101360007047000004000020034800680349097822
-:101370000844014908607047040000200C00002068
-:1013800010B50D48006840F400700B49086008462D
-:10139000006840F4806008600846006840F480708F
-:1013A0000860032000F0DCF8042000F007F800F0EB
-:1013B0005FF8002010BD0000003C02402DE9F04124
-:1013C00088B004460027B84600BF0020019023489B
-:1013D000006840F01000214908600846006800F0ED
-:1013E0001000019000BF00BF02A903A801F052F94C
-:1013F000069F1FB901F076F9054602E001F072F987
-:1014000045001748B5FBF0F0A0F101081548164952
-:10141000086040F2E7311448C160C0F80480002140
-:1014200001618160816102F0A0FB064696B90E4819
-:1014300002F0D0FB06466EB9362000F043F8102CBF
-:1014400007D200222146362000F04CF807480460FD
-:1014500000E00126304608B0BDE8F0814038024087
-:1014600040420F0000100040AC07002008000020A0
-:1014700008B500BF002000901148006840F480408B
-:101480000F4908600846006800F48040009000BFE3
-:1014900000BF00BF00200090081F006840F080508F
-:1014A000091F08600846006800F08050009000BFE7
-:1014B00000BF00220F21901E00F014F808BD0000AC
-:1014C0004438024001460846002809DB00F01F03AB
-:1014D00001229A4043099B0003F1E023C3F8002155
-:1014E00000BF70472DE9F05F80460D461646002785
-:1014F00007F0F6FC074639462A46334601F0070056
-:10150000C0F1070ABAF1040F02D94FF0040A01E052
-:10151000C0F1070AD14600F1040ABAF1070F02D25E
-:101520004FF0000A01E0A0F1030AD4464FF0010A8F
-:101530000AFA09FAAAF1010A0AEA020A0AFA0CFAF4
-:101540004FF0010B0BFA0CFBABF1010B0BEA030B99
-:101550004AEA0B042146404607F0CAFCBDE8F09F6A
-:1015600000BF00F00702064B19684FF6FF03194051
-:10157000044B0B4343EA0221014B196000BF704743
-:101580000CED00E00000FA05704702461068416269
-:1015900000207047F0B5034615461868446A21B923
-:1015A00044EA05401E68B06219E01868806A04EBDE
-:1015B0001044002208E0186800F5827050F82200FC
-:1015C00004EB1044501CC2B2481E9042F3D844EAC7
-:1015D0000547186800F582704E1E40F826700020FE
-:1015E000F0BD10B50446D4F8080505F010FF10BD95
-:1015F00070B504460D4605EBC50304F13C0101EB53
-:1016000083010A692946D4F8080505F0FBFD70BD81
-:1016100070B504460D4605EBC50304F51F7101EBDB
-:1016200083010A692946D4F8080505F06FFE70BDEC
-:1016300010B50446D4F8080505F0ECFE10BD2DE900
-:10164000F04104460D4605F08000802808D105F0E1
-:101650000F0000EBC00104F13C0000EB810607E045
-:1016600005F00F0000EBC00104F51F7000EB8106D0
-:101670003146206807F0C0F907463846BDE8F081DA
-:1016800070B504460E4606F0800080280AD106F0A8
-:101690000F0000EBC00104F13C0000EB81050120CC
-:1016A000687009E006F00F0000EBC00104F51F7040
-:1016B00000EB81050020687006F00F00287000BF65
-:1016C00094F8BC04012801D1022070BD012084F8E7
-:1016D000BC0400BF2946206806F06EFC00BF002055
-:1016E00084F8BC0400BF00BFEFE770B504460E46A7
-:1016F00006F00F006168884201D9012070BD06F034
-:10170000800080280AD106F00F0000EBC00104F130
-:101710003C0000EB81050120687009E006F00F0035
-:1017200000EBC00104F51F7000EB8105002068701C
-:101730000020A87006F00F00287000BF94F8BC04C9
-:10174000012801D10220D9E7012084F8BC0400BFA0
-:101750002946206806F018FF00BF002084F8BC046A
-:1017600000BF00BFCAE7024601F00F0000EBC00354
-:1017700002F51F7000EB8300006A70472DE9F04707
-:1017800005460E4690461F464FF0000906F08000C1
-:1017900080280AD106F00F0000EBC00105F13C00E3
-:1017A00000EB81040120607009E006F00F0000EBFF
-:1017B000C00105F51F7000EB81040020607006F089
-:1017C0000F002070C4F80C802771607808B1207871
-:1017D0002081022F01D10020607100BF95F8BC0468
-:1017E000012802D10220BDE8F087012085F8BC0461
-:1017F00000BF2146286806F0F5FA00BF002085F8F2
-:10180000BC0400BF4846EEE72DE9F04104460E4611
-:101810001746984606F00F0000EBC00104F51F7054
-:1018200000EB81052F61C5F81880002028626870E0
-:1018300006F00F0028702069012800D16F6106F0C2
-:101840000F0028B9227C2946206806F077FD04E0C5
-:10185000227C2946206806F02BFF0020BDE8F0819D
-:1018600070B504460D4605F00F006168884201D945
-:10187000012070BD05F0800080280AD105F00F001E
-:1018800000EBC00104F13C0000EB81060120707008
-:1018900007E005EBC50104F51F7000EB8106002091
-:1018A00070700120B07005F00F00307000BF94F828
-:1018B000BC04012801D10220DBE7012084F8BC042C
-:1018C00000BF3146206806F0A6FE05F00F0028B9DB
-:1018D000217C04F2C442206806F01EFE00BF0020F6
-:1018E00084F8BC0400BF00BFC3E72DE9F041044603
-:1018F0000E461746984606F00F0000EBC00104F1B3
-:101900003C0000EB81052F61C5F81880002028629B
-:101910000120687006F00F0028702069012800D1AE
-:101920006F6106F00F0028B9227C2946206806F076
-:1019300005FD04E0227C2946206806F0B9FE00205F
-:10194000BDE8F0812DE9FE4F0446D4F800B05E46B4
-:10195000206807F038F9002874D1206807F072F980
-:1019600008B9BDE8FE8F40F608008059C0F30D208D
-:10197000C4F8FC04206807F065F900F002000228B2
-:1019800005D12068406900F00200216848612068A4
-:1019900007F058F900F01000102845D12068806940
-:1019A00020F0100021688861DBF8209009F00F001A
-:1019B00000EBC00104F51F7000EB810AC9F343403E
-:1019C00002281AD147F6F07009EA000030B3C9F3D3
-:1019D0000A125846DAF8101007F039F9C9F30A115B
-:1019E000DAF810000844CAF81000C9F30A11DAF84E
-:1019F00020000844CAF8200010E0C9F3434006283C
-:101A00000CD1082204F2C441584607F020F9C9F36A
-:101A10000A11DAF820000844CAF82000206880691A
-:101A200040F0100021688861206807F00BF900F48D
-:101A30000020B0F5002F7BD10025206807F0D2F8F8
-:101A4000029072E0E1E2029800F00100002868D004
-:101A5000E9B2206807F0E9F8804608F0010048B1D3
-:101A6000012106F5306000EB4510816029462046D3
-:101A700002F0F4FE08F00800082809D1082106F554
-:101A8000306000EB451081602946204602F0B4FE2C
-:101A900008F01000102805D1102106F5306000EB89
-:101AA0004510816008F00200022824D1DBF8140000
-:101AB00000F08000802807D140F60400805940F4EF
-:101AC000806140F60400815105EBC50104F51F70EB
-:101AD00000EB810A9AF80300012806D100208AF859
-:101AE0000300E9B2204600F09BFA022106F53060BF
-:101AF00000EB4510816008F02000202805D120214E
-:101B000006F5306000EB4510816008F40050B0F538
-:101B1000005F06D14FF4005106F5306000EB451030
-:101B200081606D1C029840080290029800288AD1BA
-:101B3000206807F087F800F48020B0F5802F7DD171
-:101B4000206807F045F8029000259AE0029800F01E
-:101B50000100002873D0E9B2206807F04DF88046F4
-:101B600008F00100F0B305F00F010120884001905A
-:101B700040F634008159019821EA000040F6340112
-:101B80008851012106F5106000EB45108160206945
-:101B9000012824D105EBC50104F13C0000EB8100D4
-:101BA00005EBC502016904F13C0000EB8200C0684E
-:101BB000014405EBC50204F13C0000EB8200016129
-:101BC0006DB905EBC50104F13C0000EB81008069B3
-:101BD00028B904F2C4420121206806F09DFCE9B254
-:101BE000204600E001E0FFF703FD08F008000828A8
-:101BF00005D1082106F5106000EB4510816008F062
-:101C00001000102805D1102106F5106000EB4510DA
-:101C1000816008F04000402805D1402106F51060A1
-:101C200000EB4510816008F0020002281DD1294612
-:101C3000584606F089FF05EBC50101E025E01CE0F0
-:101C400004F13C0000EB810A9AF80300012806D158
-:101C500000208AF80300E9B2204600F0D8F90221FA
-:101C600006F5106000EB4510816008F080008028C8
-:101C700003D12946204602F093FE6D1C02984008CD
-:101C80000290029800287FF461AF206806F0DAFF26
-:101C900000F00040B0F1004F1CD140F60400805924
-:101CA00020F0010140F60400815194F8F404012869
-:101CB00007D1002084F8F40400212046FFF764FCDB
-:101CC00002E0204600F0D4FA2068406900F00040AD
-:101CD00021684861206806F0B5FF00F40060B0F5A7
-:101CE000006F0ED140F60800805900F0010010B1DD
-:101CF000204600F015FB2068406900F40060216870
-:101D00004861206806F09EFF00F48050B0F5805FC7
-:101D10007ED140F60400805920F0010140F6040015
-:101D200081511021206806F00FFF002732E04FF6A6
-:101D30007F3106F5106000EB4710816006F51060FA
-:101D400000EB4710006820F4001106F5106000EB6E
-:101D5000471001604FF67F3106F5306000EB471009
-:101D6000816006F5306000EB4710006820F4001138
-:101D700006F5306000EB4710016006F5306000EBBF
-:101D80004710006840F0006106F5306000EB471036
-:101D900001607F1C6068B842C9D840F61C008059B9
-:101DA00040F0011140F61C008151206B70B1D6F853
-:101DB000840840F00B01C6F8841840F644008059AE
-:101DC00040F00B0140F6440081510FE040F6140052
-:101DD000805942F22B01084340F614018851081F34
-:101DE000805940F00B014FF401608151D6F8000892
-:101DF00020F4FE60C6F80008217C04F2C44220688A
-:101E000006F08AFB2068406900F48050216800E0F9
-:101E100000E04861206806F015FF00F40050B0F5BE
-:101E2000005F17D1206806F045F8206806F0B8FE7C
-:101E3000E06000F051FC0090227B2068009906F0E1
-:101E400089FF204600F0FCF92068406900F400504A
-:101E500021684861206806F0F5FE00F008000828B7
-:101E600008D1204600F00BFA2068406900F0080015
-:101E700021684861206806F0E5FE00F080008028B7
-:101E800018D1DBF8180020F08000CBF818000125ED
-:101E90000DE005EBC50104F51F7000EB8100C07873
-:101EA000012803D1E9B22046FFF7C9FB6D1C606829
-:101EB000A842EED8206806F0C5FE00F48010B0F508
-:101EC000801F2DD1012522E006F5106000EB4510A2
-:101ED000D0F8009005EBC50104F13C0000EB810057
-:101EE0000079012812D109F00040B0F1004F0DD166
-:101EF000012105EBC50204F13C0000EB8200C1703A
-:101F0000E8B240F080012046FFF799FB6D1C606845
-:101F1000A842D9D82068406900F48010216848613F
-:101F2000206806F08FFE00F40010B0F5001F44D1C9
-:101F3000012538E006F5306000EB4510D0F8009040
-:101F400005EBC50104F51F7000EB81000079012845
-:101F500028D109F00040B0F1004F23D109F48030BE
-:101F600094F8FC1401F0010188421BD1012105EB1A
-:101F7000C50204F51F7000EB8200C170DBF8180089
-:101F800040F08000CBF81800DBF8140000F080006F
-:101F900040B940F60400805940F4007140F6040056
-:101FA000815103E06D1C6068A842C3D800BF20685F
-:101FB000406900F4001021684861206806F042FE84
-:101FC00000F08040B0F1804F08D12046FFF709FBB8
-:101FD0002068406900F0804021684861206806F070
-:101FE00031FE00F0040004280FD12068D0F80490DE
-:101FF00009F00400042802D12046FFF719FB2068ED
-:10200000406840EA09002168486000BFA9E470B553
-:1020100004460D462946D4F8080505F067FA70BD58
-:1020200070B504460D462946D4F8080505F082FA35
-:1020300070BD70B58AB0044614B901200AB070BDF5
-:10204000266894F8BD0428B9002084F8BC04204612
-:1020500000F0A2F8032084F8BD04F06B00F4807057
-:1020600008B900212161206806F060F9282204F1F6
-:1020700010016846FEF737F994E80F0005F02EFFCF
-:1020800020B1022084F8BD040120D7E70021206898
-:1020900006F00DFE002531E0012105EBC50204F13B
-:1020A0003C0000EB8200417005EBC50104F13C00EF
-:1020B00000F8215005EBC50100EB810005810021EE
-:1020C00005EBC50204F13C0000EB8200017105EB59
-:1020D000C50204F13C0000EB8200C16005EBC502C3
-:1020E00004F13C0000EB8200016105EBC50204F144
-:1020F0003C0000EB82008161681CC5B26068A842A8
-:10210000CAD800252AE0002105EBC50204F51F709E
-:1021100000EB8200417005EBC50104F51F7000F86B
-:102120002150002105EBC50200EB8200017105EB97
-:10213000C50204F51F7000EB8200C16005EBC5020B
-:1021400004F51F7000EB8200016105EBC50204F588
-:102150001F7000EB82008161681CC5B26068A842F4
-:10216000D1D8282204F110016846FEF7BCF894E8A3
-:102170000F0005F0EBFF20B1022084F8BD04012020
-:102180005CE7002084F83800012084F8BD04206852
-:1021900005F0CAFF002051E710B586B004461421AF
-:1021A00001A8FEF7B9F82068B0F1A04F42D100BFF6
-:1021B000002000902048006840F001001E4908609F
-:1021C0000846006800F00100009000BF00BF4FF417
-:1021D000C050019002200290002003900320049040
-:1021E0000A20059001A91548FEF7A6FF00BF124876
-:1021F000001D006840F080000F49091D086000BF05
-:10220000002000900C481430006840F480400A49D7
-:10221000143108600846006800F48040009000BF58
-:1022200000BF00BF002205214320FFF75BF94320D8
-:10223000FFF748F906B010BD3038024000000240F8
-:1022400070B504460125E06808B9002506E0E0689D
-:10225000022801D1012501E0FEF7BCFC2946D4F893
-:10226000080505F010FAD4F8080505F0B7F970BDB7
-:1022700010B50446D4F8080505F0E6F910BD10B510
-:102280000446D4F8080505F0EAF910BD70B5044617
-:102290000D4600BF94F8BC04012801D1022070BD96
-:1022A000012084F8BC0400BF84F838502946206817
-:1022B00006F031FD00BF002084F8BC0400BF00BF61
-:1022C000EDE710B5044604F2C441D4F8080505F062
-:1022D000F1F910BD70B50446256800BF94F8BC0440
-:1022E000012801D1022070BD012084F8BC0400BF88
-:1022F000A06A012806D1A069012803D0A86B40F488
-:102300008030A863206806F0EDFB206805F0FAFE37
-:1023100000BF002084F8BC0400BF00BFE3E700005A
-:1023200010B50446D4F8080505F021FA2068D0F865
-:10233000000E40F001002168C1F8000E206A28B1AB
-:102340000348006840F006000149086010BD000025
-:1023500010ED00E008B50120034908620348006859
-:10236000009000BF08BD000000000E420070004059
-:10237000F8B5044600250026207800F0010020B9B9
-:10238000207800F0040004282FD100205B498866E3
-:10239000FEF7E4FF054606E0FEF7E0FF401B0228DB
-:1023A00001D90320F8BD56480068C0F3C06000287A
-:1023B000F2D160688101207A41EA0070504984318D
-:1023C000086001204D498866FEF7C8FF054606E013
-:1023D000FEF7C4FF401B022801D90320E2E748486A
-:1023E0000068C0F3C0600028F2D0207800F002003E
-:1023F00002287DD100BF0020009041484030006895
-:1024000040F080503E49403108600846006800F0C6
-:102410008050009000BF00BF3A48006840F48070D0
-:1024200038490860FEF79AFF054606E0FEF796FF7A
-:10243000401B022801D90320B4E73248006800F4A9
-:1024400080700028F2D02E487030006800F440768A
-:102450004EB3A08900F44070B04224D028487030B8
-:10246000006820F4407601202749086000200860B9
-:10247000234870300660006800F0010098B1FEF754
-:102480006DFF054608E0FEF769FF401B41F2883109
-:10249000884201D9032085E7194870300068C0F3ED
-:1024A00040000028EFD000BFA08900F44070B0F5D4
-:1024B000407F0CD112480830006820F4F810134A0D
-:1024C000E168114008430E490831086007E00C48F4
-:1024D0000830006820F4F8100949083108600848FD
-:1024E00070300068A189C1F30B010843044900E082
-:1024F00002E07031086000BF002053E7000047424F
-:102500000038024000700040400E4742FFFCFF0FC1
-:1025100070B504460D460CB9012070BD58480068DE
-:1025200000F00700A84209D255490D70084600681E
-:1025300000F00700A84201D00120EEE7207800F06B
-:10254000020002281DD1207800F00400042805D1E3
-:102550004C48006840F4E0504A490860207800F098
-:102560000800082805D14748006840F46040454904
-:1025700008604448006820F0F000A1680843414921
-:102580000860207800F00100A8B36068012807D136
-:102590003C4808380068C0F34040B8B90120BCE7A7
-:1025A0006068022802D06068032807D135480838DF
-:1025B0000068C0F3406048B90120AEE731480838F0
-:1025C0000068C0F3400008B90120A6E72D48006864
-:1025D00020F00300616808432A490860FEF7BEFE48
-:1025E000064609E0FEF7BAFE801B41F288318842B8
-:1025F00002D9032091E707E02248006800F00C00B0
-:102600006168B0EB810FEDD11D48006800F0070054
-:10261000A84209D91A490D700846006800F0070061
-:10262000A84201D0012078E7207800F004000428B7
-:1026300007D11448006820F4E050E16808431149CC
-:102640000860207800F00800082808D10D480068CC
-:1026500020F46040216940EAC1000A49086000F0A6
-:1026600061F808490968C1F30311074A515CC84081
-:102670000649086006480068FEF7A0FE00204CE707
-:10268000003C02400838024090E70008100000209B
-:10269000080000200F2202600D4A126802F00302B7
-:1026A00042600B4A126802F0F0028260084A126827
-:1026B00002F4E052C260064A126802F46042D20894
-:1026C0000261044A126802F007020A6070470000C3
-:1026D00008380240003C0240014800687047000092
-:1026E0001000002000B5FFF7F7FF04490968C1F3A7
-:1026F0008221034A515CC84000BD000008380240F6
-:10270000A0E7000800B5FFF7E7FF04490968C1F337
-:102710004231034A515CC84000BD00000838024005
-:10272000A0E700082DE9F047002400250026A14677
-:102730002548006800F00C0020B1042805D00828C6
-:102740003AD105E0DFF8849039E0DFF8849036E094
-:102750001D48001F006800F03F041B48001F006870
-:1027600000F4800078B11A481749091F0968C1F3BD
-:102770008811A0FB01700146224600233846FDF770
-:1027800081FD05460EE011480F49091F0968C1F394
-:102790008811A0FB01700146224600233846FDF750
-:1027A00071FD05460848001F0068C0F30140401C49
-:1027B0004600B5FBF6F902E0DFF8109000BF00BF5D
-:1027C0004846BDE8F0870000083802400024F400C5
-:1027D00000127A00F8B504460CB90120F8BD207843
-:1027E00000F00100002874D0F948006800F00C00E7
-:1027F00004280DD0F648006800F00C00082813D11A
-:10280000F348001F006800F48000B0F5800F0BD182
-:10281000EF4808380068C0F34040002859D060688D
-:10282000002856D10120D9E700BF6068B0F5803F8D
-:1028300008D1E7480838006840F48030E449083996
-:1028400008601EE06068B0F5A02F0DD1E0480838A0
-:10285000006840F48020DE490839086008460068B6
-:1028600040F4803008600CE0D9480838006820F453
-:102870008030D749083908600846006820F4802075
-:10288000086000BF606890B1FEF768FD054606E08D
-:10289000FEF764FD401B642801D903209EE7CC4865
-:1028A00008380068C0F340400028F1D011E0FEF77E
-:1028B00055FD054606E0FEF751FD401B642801D991
-:1028C00003208BE7C24808380068C0F34040002866
-:1028D000F1D1207800F0020002285FD1BC480068E6
-:1028E00000F00C0058B1BA48006800F00C0008284D
-:1028F0001CD1B748001F006800F48000B0B9B4488C
-:1029000008380068C0F3400020B1E068012801D019
-:10291000012063E7AE480838006820F0F80021691C
-:1029200040EAC100AA490839086037E0E06800B30E
-:102930000120A8490860FEF711FD054606E0FEF7F4
-:102940000DFD401B022801D9032047E7A0480838A5
-:102950000068C0F340000028F1D09D4808380068A6
-:1029600020F0F800216940EAC1009949083908605F
-:1029700014E0002097490860FEF7F0FC054606E0E9
-:10298000FEF7ECFC401B022801D9032026E7904803
-:1029900008380068C0F340000028F1D1207800F02A
-:1029A000080008282CD16069A8B101208A49086074
-:1029B000FEF7D4FC054606E0FEF7D0FC401B0228DB
-:1029C00001D903200AE782486C300068C0F3400058
-:1029D0000028F1D014E000207F490860FEF7BEFC1B
-:1029E000054606E0FEF7BAFC401B022801D9032089
-:1029F000F4E677486C300068C0F340000028F1D15D
-:102A0000207800F00400042870D100277048383086
-:102A1000006800F0805090B900BF002000906C4822
-:102A20003830006840F08050694938310860084605
-:102A3000006800F08050009000BF00BF0127674889
-:102A4000006800F48070B0B96448006840F4807099
-:102A500062490860FEF782FC054606E0FEF77EFC50
-:102A6000401B022801D90320B8E65C48006800F446
-:102A700080700028F2D000BFA068012808D1544817
-:102A80006830006840F001005149683108601DE07D
-:102A9000A06805280DD14E486830006840F0040059
-:102AA0004B49683108600846006840F00100086042
-:102AB0000CE047486830006820F001004449683164
-:102AC00008600846006820F00400086000BFA068A5
-:102AD000A8B1FEF743FC054609E0FEF73FFC401BAA
-:102AE00041F28831884202D9032077E626E038484F
-:102AF00068300068C0F340000028EED013E0FEF715
-:102B00002DFC054608E0FEF729FC401B41F2883108
-:102B1000884201D9032061E62D4868300068C0F37F
-:102B200040000028EFD1012F07D129483830006834
-:102B300020F0805026493831086000BFA069002885
-:102B400045D02348006800F00C0008285DD0A0693B
-:102B5000022845D100201F490866FEF7FFFB054605
-:102B600006E0FEF7FBFB401B022801D9032035E6F7
-:102B7000174808380068C0F340600028F1D1D4E954
-:102B800007010843616A40EA81110122A06AC2EB91
-:102B9000500041EA00412C20005D41EA00600C49F0
-:102BA000091F086001200B490866FEF7D7FB0546A0
-:102BB00006E0FEF7D3FB401B022801D903200DE6F7
-:102BC000034808380068C0F340600028F1D049E0AD
-:102BD0000838024000004742800E47420070004023
-:102BE000002021490866FEF7B9FB054606E0FEF71E
-:102BF000B5FB401B022801D90320EFE51B48006804
-:102C0000C0F340600028F2D12CE0A069012800D177
-:102C1000E4E51648001D0668A069012820D006F4E6
-:102C20008001E06981421BD106F03F01206A8142A8
-:102C300016D147F6C0703040616AB0EB811F0FD1EA
-:102C400006F440310122A06AC2EB5000B1EB004F04
-:102C500006D106F070612C20005DB1EB006F01D051
-:102C60000120BBE50020B9E50000474200380240E2
-:102C700010B50023046804F1500303EB81031A60CC
-:102C800010BD000070B505460B46164600242868A6
-:102C900040680E4900EA0104200CD870C4F30420F7
-:102CA000587004F03F009870C4F3423018705EB959
-:102CB000D87801F0D0FED870587801F0CCFE58706A
-:102CC000987801F0C8FE9870002070BD3FFFFF00AB
-:102CD00070B504460B46164600252068806A586089
-:102CE00020680069C0F30E009860206800680E49F3
-:102CF00000EA0105C5F305401870C5F306205870B9
-:102D000005F07F009870A80DD8705EB9187801F0B2
-:102D1000A2FE1870587801F09EFE5870987801F065
-:102D20009AFE9870002070BD7F7F7F0070B50446CA
-:102D300001250CB9012070BD607F20B900202077EB
-:102D4000204600F045F80220607700BFCA202168C5
-:102D5000486253202168486200BF204601F094FE7B
-:102D60000546EDB9206880681849084021688860E8
-:102D700021696068084361690843216889680843DC
-:102D8000216888602168E0680861206801692089FD
-:102D900041EA004021680861204601F09AFE05469C
-:102DA0006DB92068006C20F48020216808642068D8
-:102DB000006CA1690843216808640120607700BFA6
-:102DC000FF202168486200BF2846B4E7BFFF8FFF9D
-:102DD0001FB504460020009001900290039009491D
-:102DE000206888420CD102200090C0010390684600
-:102DF000FFF7BEFA08B1FDF7EDFE012002490860B9
-:102E00001FBD0000002800403C0E47422DE9F04164
-:102E100005460C4617464FF0000800BF287F0128E2
-:102E200002D10220BDE8F0810120287700BF0220F6
-:102E300068774FB9607800F01000102804D16078EE
-:102E400000F0EF000A30607087B9E07801F00EFE04
-:102E50000304607801F00AFE43EA0023A07801F041
-:102E600005FE0343207843EA403809E0E078000497
-:102E7000617840EA0120A1780843217840EA41388E
-:102E800000BFCA202968486253202968486200BFF1
-:102E9000284601F0F9FD064646B90B4808EA00004D
-:102EA00029684860284601F014FE06460EB9012044
-:102EB000687700BFFF202968486200BF00BF00207C
-:102EC000287700BF3046ADE73FFFFF002DE9F04116
-:102ED00004460D4617464FF0000800BF207F01282A
-:102EE00002D10220BDE8F0810120207700BF02203E
-:102EF0006077CFB92068806800F0400000B102E040
-:102F00000020E87000BF287801F0B0FD0304687865
-:102F100001F0ACFD43EA0023A87801F0A7FD0343CC
-:102F2000E87843EA805812E02068806800F04000AA
-:102F300000B102E00020E87000BF28780004697842
-:102F400040EA0120A9780843E97840EA815800BFA7
-:102F5000CA202168486253202168486200BF204689
-:102F600001F092FD0646B6B9124808EA0000216851
-:102F700008602068806820F4802021688860D5E996
-:102F80000301084321688968084321688860204656
-:102F900001F09FFD06460EB90120607700BFFF20BB
-:102FA0002168486200BF00BF0020207700BF304684
-:102FB00098E700007F7F7F0070B5044600252068F9
-:102FC000C06820F0A0002168C860FEF7C7F9054678
-:102FD00007E0FEF7C3F9401BB0F57A7F01D9032063
-:102FE00070BD2068C06800F020000028F1D00020EB
-:102FF000F6E70000F0B589B004460E46002703202E
-:1030000084F83400606C032820D0B6F5805F04D1CA
-:10301000A06B40F08050A0631CE0B6F5006F07D1B4
-:10302000204602F0E7FB0546A06B2843A06311E0B1
-:103030003EB9204602F0AAFB0546A06B2843A063D8
-:1030400008E0A06B40F00060A06303E0A06B40F0DC
-:103050008050A063A06B38B11748216888630120B5
-:1030600084F83400012713E060680390A06804909E
-:10307000E0680590069660690790A069089006A828
-:1030800007C88DE80700206803A90EC901F05DFD9F
-:103090004FF40071206801F0C9FD054635B10648BE
-:1030A00021688863A06B2843A0630127012084F86E
-:1030B0003400384609B0F0BDFF05400070470000FD
-:1030C00010B50246506E800F0870506EC0F38360DA
-:1030D0004870506EC0F301608870506E000CC8706C
-:1030E000B2F86400000A087192F864004871906EAA
-:1030F000000DC880906EC0F3034008726820805AAB
-:10310000C0F3C03048726820805AC0F380308872A3
-:103110006820805AC0F34030C8726820805AC0F3DB
-:103120000030087300204873506C002836D16820A6
-:10313000805A8005030DD06E43EA90700861D06E0E
-:10314000C0F3C2600875D06EC0F302604875D06EDF
-:10315000C0F342508875D06EC0F38240C875D06EFF
-:10316000C0F3C23008760869401C50650B7E506D74
-:1031700003F007039B1C01249C4060435065087AC0
-:1031800000F00F03012098409065D2E915035B0A17
-:103190005843D0654FF40073136621E0506C01284A
-:1031A00013D16820805C8006830AD06E43EA104009
-:1031B00008610869401C83025365536DD3654FF461
-:1031C00000739365936D13660AE02E481368986345
-:1031D000906B40F080509063012082F8340010BD65
-:1031E0006C20805AC0F3803001F8190F6C20805A8F
-:1031F000C0F3C61048706C20805C00F07F008870BF
-:10320000106FC00FC870106FC0F341700871106F5D
-:10321000C0F382604871106FC0F383508871106FE3
-:10322000C0F34050C87100200872106FC0F3004016
-:1032300048727020805AC0F3C03088727020805A63
-:10324000C0F38030C8727020805AC0F340300873D9
-:103250007020805AC0F3003048737020805AC0F349
-:10326000812088737020805AC0F30120C8737020B9
-:10327000805CC0F3460008740120487419390020AE
-:10328000ADE70000FF0540000246506C0860906CFE
-:103290004860D06C8860106DC860506D0861906D9A
-:1032A0004861D06D8861106EC86100207047F8B524
-:1032B0000446002000906946204602F04FFA054679
-:1032C00015B1A06B2843A0630098C0F34326304695
-:1032D000F8BD10B504460CB9012010BD94F83400B7
-:1032E00020B900202077204600F06AF8032084F8F7
-:1032F0003400204600F00CF808B10120EDE7002072
-:10330000A0632063012084F834000020E5E700007A
-:1033100070B58AB00446002004900590069007908E
-:1033200008907620099007A807C88DE80700206854
-:1033300004A90EC901F009FC064616B101200AB025
-:1033400070BD00201C490860206801F018FC0120B5
-:103350001949A039C1F8A0000220FDF7D9FE204686
-:1033600002F096F905463DB1012084F83400A06BC7
-:103370002843A0630120E2E7204602F007F9054652
-:103380003DB1012084F83400A06B2843A0630120E4
-:10339000D5E74FF40071206801F048FC05464DB1B7
-:1033A000064821688863A06B2843A063012084F845
-:1033B0003400C4E70020C2E7A0802542FF0540009A
-:1033C00010B586B00446142101A8FCF7A5FF5449A6
-:1033D000206888427ED100BF0020009051480068DC
-:1033E00040F400604F4908600846006800F400603F
-:1033F000009000BF00BF00BF002000904948143873
-:10340000006840F004004749143908600846006825
-:1034100000F00400009000BF00BF00BF002000903B
-:103420000846006840F0080008600846006800F0A0
-:103430000800009000BF00BF4FF4F8500190022038
-:10344000029001200390022004900C20059001A915
-:103450003548FDF771FE0420019002200290012002
-:103460000390022004900C20059001A92F48FDF73D
-:1034700063FE2F482F4908604FF00060486000212C
-:103480002C488160C1604FF4806101618900416115
-:10349000890081612021C161002101620421416212
-:1034A000032181624FF40001C16289100163FDF7BD
-:1034B0006FFD08B1FDF78EFB00BF1E4820648463DA
-:1034C00000BF1B4848301C4908604FF0006048604E
-:1034D000402100E021E0184881600021C1604FF4E4
-:1034E0008061016189004161890081612021C161A0
-:1034F0000021016204214162032181624FF4000135
-:10350000C16289100163FDF743FD08B1FDF762FB5D
-:1035100000BF0948E063846300BF06B010BD00002F
-:10352000002C01404438024000080240000C0240D8
-:103530005864024090050020F00500202DE9F0437A
-:1035400087B004460F4691461D46C8463FB9A06B5A
-:1035500040F00060A063012007B0BDE8F08394F85C
-:10356000340001287ED10020A06308EB0501E06D46
-:10357000814205D9A06B40F00070A0630120EBE709
-:10358000032084F8340000202168C8622068C06BE2
-:1035900040F22A3108432168C8633848216CC86367
-:1035A0003748216CC8640020216C08650021206C1C
-:1035B0008160206C0068006820F0C000216C896880
-:1035C0000843216C096808606A029308226802F1C6
-:1035D00080013A46206CFDF751FD80B12068C06B38
-:1035E00020F495702168C863264821688863A06B21
-:1035F00040F08040A063012084F83400ACE7012053
-:1036000021490860606C012801D04FEA48284FF03A
-:10361000FF300190680202909020039002200490F5
-:10362000002005900120069001A9206801F068FAA9
-:10363000012D07D9822020634146206801F05EFBFE
-:10364000064606E0812020634146206801F072FBB7
-:10365000064676B10B4821688863A06B3043A063AF
-:10366000012000E007E084F83400002020630120FE
-:1036700072E7002070E702206EE70000F1530008B7
-:103680007D530008FF0540008C85254210B5044697
-:10369000FDF766F910BD00002DE9F04387B0044640
-:1036A000884691461D464F46B8F1000F07D1A06BE2
-:1036B00040F00060A063012007B0BDE8F08394F8FB
-:1036C0003400012874D10020A0637919E06D814293
-:1036D00005D9A06B40F00070A0630120ECE7032047
-:1036E00084F8340000202168C8622068C06B40F272
-:1036F0001A2108432168C8633848E16BC863384819
-:10370000E16BC8640020E16B0865606C012800D0A3
-:103710007F02012D07D9A02020633946206801F0DF
-:10372000E7FB064606E0902020633946206801F05A
-:10373000FBFB064666B12B4821688863A06B3043CB
-:10374000A063012084F83400002020630120B3E747
-:103750000120254908604021E06B8160E06B006832
-:10376000006820F0C000E16B89680843E16B0968DC
-:10377000086069028B08216801F180024146E06B14
-:10378000FDF77CFCA8B12068C06B40F21A21884389
-:103790002168C863134821688863A06B40F08040AB
-:1037A000A063012084F8340000202063012083E717
-:1037B00011E04FF0FF3001906802029090200390DA
-:1037C0000020049005900120069001A9206801F0D6
-:1037D00097F9002070E702206EE7000039540008D6
-:1037E0007D530008FF0540008C85254210B5044636
-:1037F0000CB9012010BD606A38B96068B0F5827FED
-:1038000000D105E00021E16102E000212161616158
-:103810000021A16294F8510028B9002084F85000DA
-:10382000204600F047F8022084F851002068006824
-:1038300020F0400021680860A08800F4827021898F
-:1038400001F404410843A18901F400610843217C8B
-:1038500001F002010843217D01F001010843218BA1
-:1038600001F400710843217F01F038010843202151
-:10387000095D01F080010843218D01F400510843E6
-:10388000216808600421A06901EA104094F824101E
-:1038900001F010010843216848602068C06920F4E5
-:1038A00000602168C86100206065012084F8510033
-:1038B00000209FE710B586B00446142101A8FCF74C
-:1038C0002BFD1B49206888422FD100BF00200090AB
-:1038D0001848006840F4004016490860084600682F
-:1038E00000F40040009000BF00BF00BF0020009027
-:1038F00010481038006840F002000E491039086086
-:103900000846006800F00200009000BF00BF3820A9
-:1039100001900220029000200390032004900620D2
-:10392000059001A90448FDF707FC06B010BD000092
-:10393000003C004040380240000402402DE9FF5F97
-:103940000446884691461D460E9E012002900020A6
-:10395000019000BF94F85000012803D1022004B068
-:10396000BDE8F09F012084F8500000BFFDF7F6FC91
-:10397000074694F851B060680390AA46BBF1010F66
-:103980000BD00398B0F5827F04D1A06810B9BBF1C9
-:10399000040F02D002200190DBE0B8F1000F03D049
-:1039A000B9F1000F00D015B901200190D1E094F8D1
-:1039B0005100042802D0052084F8510000206065E1
-:1039C000C4F83890E587A587C4F83080E586A586D9
-:1039D000206460642068006800F04000402805D042
-:1039E0002068006840F0400021680860E068B0F599
-:1039F000006F4AD1606810B1BAF1010F09D1206B94
-:103A000000882168C860206B801C2063E08E401E07
-:103A1000E08633E02068806800F00200022810D1C0
-:103A2000E08E70B1029801280BD1206B00882168CC
-:103A3000C860206B801C2063E08E401EE086002062
-:103A400002902068806800F0010068B1E08F58B1F2
-:103A50002068C068A16B0880A06B801CA063E08F09
-:103A6000401EE08701200290FDF778FCC01BB042A9
-:103A700004D3701C10B1032001906AE0E08E00288E
-:103A8000C8D1E08F0028C5D14AE0606810B1BAF112
-:103A9000010F09D1206B007821680873206B401C4E
-:103AA0002063E08E401EE08634E02068806800F0ED
-:103AB0000200022810D1E08E70B1029801280BD1CB
-:103AC000206B007821680873206B401C2063E08E17
-:103AD000401EE086002002902068806800F001000F
-:103AE00068B1E08F58B12068C068A16B0870A06B06
-:103AF000401CA063E08F401EE08701200290FDF78C
-:103B00002DFCC01BB04201D3701C00B916B90320B4
-:103B100001901EE0E08E0028C7D1E08F0028C4D1BC
-:103B20003A463146204601F08DFF20B10120019038
-:103B3000202060650DE0A06850B900BF0020009013
-:103B40002068C068009020688068009000BF00BFB7
-:103B500000BF012084F8510000BF002084F850000D
-:103B600000BF0198FBE67047704710B504460CB9DA
-:103B7000012010BD94F83D0028B9002084F83C00D5
-:103B8000204600F025F8022084F83D00211D206821
-:103B900002F092F8012084F8460000BF84F83E004D
-:103BA00001213F200155402001554120015500BF12
-:103BB00000BF012084F842004320015544200155F4
-:103BC0004520015500BF012084F83D000020D0E7CA
-:103BD00070470000014691F83D00012801D0012006
-:103BE0007047022081F83D000868C06840F001007D
-:103BF0000B68D8601A4B086898421BD00868B0F16F
-:103C0000804F17D0174B0868984213D0164B08689E
-:103C100098420FD0154B086898420BD0144B086897
-:103C2000984207D0134B0868984203D0124B08689B
-:103C300098420CD10868806800F00702062A0CD070
-:103C40000868006840F001000B68186005E008682B
-:103C5000006840F001000B6818600020C0E7000019
-:103C6000000001400004004000080040000C00403B
-:103C7000000401400040014000180040704710B5AA
-:103C8000044620680069C0F34000D8B12068C068CD
-:103C9000C0F34000B0B16FF002002168086101205C
-:103CA00020772068806900F0030018B12046FFF7F4
-:103CB000E5FF05E0204600F0ADF8204600F0ABF847
-:103CC0000020207720680069C0F38000D8B1206808
-:103CD000C068C0F38000B0B16FF0040021680861D3
-:103CE000022020772068806900F4407018B12046D7
-:103CF000FFF7C4FF05E0204600F08CF8204600F0F6
-:103D00008AF80020207720680069C0F3C000D8B18D
-:103D10002068C068C0F3C000B0B16FF0080021682F
-:103D20000861042020772068C06900F0030018B102
-:103D30002046FFF7A3FF05E0204600F06BF8204681
-:103D400000F069F80020207720680069C0F30010B7
-:103D5000D8B12068C068C0F30010B0B16FF0100097
-:103D600021680861082020772068C06900F440704D
-:103D700018B12046FFF782FF05E0204600F04AF820
-:103D8000204600F048F8002020772068006900F005
-:103D9000010058B12068C06800F0010030B16FF038
-:103DA000010021680861204600F036F820680069AB
-:103DB000C0F3C01058B12068C068C0F3C01030B163
-:103DC0006FF08000216808612046FFF7CCFE206874
-:103DD0000069C0F3801058B12068C068C0F380103B
-:103DE00030B16FF0400021680861204600F020F8F3
-:103DF00020680069C0F3401058B12068C068C0F363
-:103E0000401030B16FF02000216808612046FFF7B4
-:103E1000ABFE10BD7047704710B5044603492068DB
-:103E2000884201D1FDF7A0FA10BD0000001000404B
-:103E300070477047704700002DE9F84F044620682E
-:103E400005682068C668206847694FF00009CA46BF
-:103E500005F00F09B9F1000F0AD105F0200038B1C3
-:103E600006F0200020B1204602F085F8BDE8F88F6A
-:103E7000B9F1000F7CD007F0010018B906F490707A
-:103E8000002875D005F0010030B106F4807018B13B
-:103E9000206C40F00100206405F0040030B107F010
-:103EA000010018B1206C40F00200206405F002000F
-:103EB00030B107F0010018B1206C40F0040020641C
-:103EC00005F0080048B106F0200010B907F0010025
-:103ED00018B1206C40F008002064206C002846D007
-:103EE00005F0200028B106F0200010B1204602F0B5
-:103EF00042F820684069C0F3801A206C00F0080086
-:103F000010B9BAF1000F2DD0204601F0DBFF206878
-:103F1000406900F04000402820D100BF00BF216868
-:103F2000143151E8001F21F040002168143141E8AC
-:103F30000002002AF3D100BFA06B50B17548A16BFD
-:103F40000865A06BFCF7ECFE88B1A06B016D88479B
-:103F50000DE02046FFF76EFF09E009E02046FFF77D
-:103F600069FF04E02046FFF765FF002020647DE73D
-:103F7000206B012876D105F01000002872D006F0E1
-:103F800010000028FAD000BF0020009020680068D0
-:103F9000009020684068009000BF00BF2068406922
-:103FA00000F0400040285ED1A06B006840681FFA16
-:103FB00080F8B8F1000F54D0A08D404551DDA4F831
-:103FC0002E80A06BC069B0F5807F43D000BF00BFDA
-:103FD00021680C3151E8001F21F4807021680C31F8
-:103FE00041E80002002AF3D100BF00BF00BF2168F2
-:103FF000143151E8001F21F001002168143141E81B
-:104000000002002AF3D100BF00BF00BF21681431B5
-:1040100051E8001F21F040002168143141E80002FE
-:10402000002AF3D100BF202084F83E000020206346
-:1040300000BF00BF21680C3151E8001F21F01000C3
-:1040400021680C3141E80002002AF3D100BFA06BC7
-:10405000FCF710FEA08DE28D801A81B22046FFF79A
-:10406000E8FE03E740E0A08DE18D401A1FFA80F8DA
-:10407000E08DC0B3B8F1000F35D000BF00BF21689C
-:104080000C3151E8001F21F4907021680C3141E897
-:104090000002002AF3D100BF00BF00BF2168143125
-:1040A00051E8001F21F001002168143141E80002AD
-:1040B000002AF3D100BF202084F83E0000202063B6
-:1040C00000BF00BF21680C3151E8001F21F0100033
-:1040D00021680C3141E80002002AF3D100BF4146BB
-:1040E0002046FFF7A6FEC1E605F0800030B106F0DD
-:1040F000800018B1204602F039F9B7E605F040001B
-:1041000030B106F0400018B1204601F011FFADE6D5
-:1041100000BFABE6915D000810B504460CB9012064
-:1041200010BDA06900B100E000BF94F83D0028B9BF
-:10413000002084F83C00204600F028F8242084F871
-:104140003D002068C06820F400502168C860204607
-:1041500001F08EFF2068006920F49040216808611A
-:104160002068406920F02A00216848612068C06802
-:1041700040F400502168C86000202064202084F8AA
-:104180003D0084F83E000020CAE7000010B586B06C
-:104190000446142101A8FCF7BFF83D492068884275
-:1041A00074D100BF002000903A48006840F0100031
-:1041B000384908600846006800F01000009000BF11
-:1041C00000BF00BF0020009032481438006840F063
-:1041D00001003049143908600846006800F0010009
-:1041E000009000BF00BF4FF4C06001900220029019
-:1041F00000200390032004900720059001A9264881
-:10420000FCF79AFF2548264908604FF00060486097
-:10421000002123488160C1604FF480610161002169
-:1042200041618161C16101624162FCF7B1FE08B187
-:10423000FCF7D0FC00BF1A48A063846300BF174896
-:104240007830184908604FF00060486040211548F8
-:1042500081600021C1604FF48061016100214161F2
-:104260008161C16101624162FCF792FE08B1FCF715
-:10427000B1FC00BF0B486063846300BF00220521CE
-:104280002520FDF72FF92520FDF71CF906B010BDFC
-:1042900000100140443802400000024040640240E7
-:1042A000EC0600204C07002070B504460D4616466B
-:1042B00094F83E00202816D105B10EB9012070BD3A
-:1042C00000BF94F83C00012801D10220F7E701204B
-:1042D00084F83C0000BF0020206332462946204677
-:1042E00001F0DCFFEBE70220E9E7704770472DE9BA
-:1042F000F84F04460E46174699464FF0000A94F8C8
-:104300003D0020285AD106B117B90120BDE8F88F29
-:1043100000BF94F83C00012801D10220F6E70120FB
-:1043200084F83C0000BF00202064212084F83D0078
-:10433000FDF714F88246A784E784A068B0F5805F93
-:1043400004D1206910B90025B04602E035464FF08F
-:10435000000800BF002084F83C0000BF1BE053466B
-:10436000002280212046CDF8009002F02FF808B1FD
-:104370000320CBE745B9B8F80000C0F30800216876
-:10438000486008F1020803E02878216848606D1C45
-:10439000E08C401EE084E08C0028E0D153460022EF
-:1043A00040212046CDF8009002F010F808B103201B
-:1043B000ACE7202084F83D000020A7E70220A5E715
-:1043C000704700BFFEE730B50B46002100BF16E086
-:1043D0000A24B4EB107F05D9302404EB107403F8E1
-:1043E000114005E0412404EB10740A3C03F811402D
-:1043F000000100254C00641C1D554C1CE1B291428B
-:10440000E6DB30BD08B500BF00200090164800680C
-:1044100040F48000144908600846006800F48000F9
-:10442000009000BF00BF002205213A20FDF75AF896
-:104430003A20FDF747F800220F213B20FDF752F804
-:104440003B20FDF73FF800220F214520FDF74AF8F9
-:104450004520FDF737F8002205214620FDF742F8F8
-:104460004620FDF72FF808BD3038024010B503494B
-:104470000348FCF7B2FB0349087010BDAD000020F3
-:1044800010E80008AC00002000B587B01C220649E7
-:104490006846FBF728FF0021684606F067FB0349E2
-:1044A000086007B000BD00006CE7000800000020B5
-:1044B00000B587B0142102A8FBF72EFF00BF002033
-:1044C00001907F48006840F010007D490860084670
-:1044D000006800F01000019000BF00BF00BF002086
-:1044E00001900846006840F0040008600846006833
-:1044F00000F00400019000BF00BF00BF0020019049
-:104500000846006840F0200008600846006800F097
-:104510002000019000BF00BF00BF002001900846AE
-:10452000006840F0800008600846006800F08000E5
-:10453000019000BF00BF00BF002001900846006846
-:1045400040F0010008600846006800F0010001909A
-:1045500000BF00BF00BF002001900846006840F087
-:10456000020008600846006800F00200019000BFE9
-:1045700000BF00BF002001900846006840F04000E6
-:1045800008600846006800F04000019000BF00BFCE
-:1045900000BF002001900846006840F00800086055
-:1045A0000846006800F00800019000BF00BF00222C
-:1045B0004FF400514348FCF7CBFE00224FF4C051AA
-:1045C0004148FCF7C5FE4FF6FF70029003200390B0
-:1045D0000020049002A93D48FCF7AEFD4FF40050C6
-:1045E00002900120039000200490059002A9354814
-:1045F000FCF7A2FD4FF6FF7002900320039000200D
-:10460000049002A93248FCF797FDFF200290032096
-:1046100003900020049002A92A48FCF78DFD48F27F
-:10462000FF100290032003900020049002A9294863
-:10463000FCF782FD4FF6C730029003200390002064
-:10464000049002A92448FCF777FD4FF6FF70029012
-:10465000032003900020049002A92048FCF76CFD81
-:104660004FF48060029000200390049002A91A4841
-:10467000FCF762FD4CF2FB700290032003900020D7
-:10468000049002A91048FCF757FD4FF4C050029067
-:104690000120039000200490059002A90A48FCF72D
-:1046A0004BFD4FF4005002904FF48810039000200F
-:1046B000049002A90448FCF73FFD07B000BD0000CC
-:1046C0003038024000080240000C02400010024056
-:1046D00000140240000002400004024000180240A2
-:1046E00010B50A480A490860002048607F21084840
-:1046F0008160FF21C1600021016141618161FEF79C
-:1047000015FB08B1FCF766FA10BD00000028004058
-:10471000EC0400207047000010B50E480E490860F8
-:104720004FF48270486000210B488160C1600161D4
-:1047300041614FF4007181610021C16101624162F8
-:1047400081620A21C162FFF751F808B1FCF742FA11
-:1047500010BD0000003C00405006002010B50B4882
-:104760000B4908604FF4E13048600021084881603F
-:10477000C16001610C21416100218161C161FFF7CC
-:10478000CBFC08B1FCF726FA10BD00000010014078
-:10479000A806002010B500220D490E4802F0EFFCDB
-:1047A00008B1FCF717FA0C490A4803F01DF808B1E4
-:1047B000FCF710FA0949074802F0F0F808B1FCF7D5
-:1047C00009FA044803F012F908B1FCF703FA10BD26
-:1047D0003001002090F50020A4010020800100207D
-:1047E00000BFFEE700BFFEE710B50248FDF7AAF8DC
-:1047F00010BD00006C0A01202DE9F04704460D466B
-:1048000026683746D6F8408007F5306000EB451043
-:10481000D0F80890104880450BD909F40040B0F555
-:10482000004F06D14FF4004107F5306000EB451012
-:1048300081602046FDF745FD0748804508D920697D
-:10484000012805D104F2C4420121206803F064FE6E
-:104850000020BDE8F08700000A30544F2DE9F047F2
-:1048600005460C46D5F800904E46D9F840A006F50E
-:10487000306000EB4410D0F808802869012855D139
-:1048800008F0080008280FD1434882450BD908F4E6
-:104890000040B0F5004F7BD14FF4004106F5306089
-:1048A00000EB4410816073E008F02000202806D15E
-:1048B000202106F5306000EB4410816068E008F0CC
-:1048C0002800002864D1344882450CD908F40040FF
-:1048D000B0F5004F07D14FF4004106F5306000EB12
-:1048E0004410816054E004EBC40105F51F7000EB37
-:1048F000810706F5306000EB4410F9690069C0F3E8
-:104900001200081A386264B9B86930B905F2C442B5
-:104910000121286803F000FE03E0396A3869084481
-:104920003861E1B22846FCF773FE31E01B4882454E
-:104930001BD108F40040B0F5004F07D14FF40041FF
-:1049400006F5306000EB4410816021E008F02000A3
-:10495000202805D1202106F5306000EB441081604D
-:10496000E1B22846FCF754FE12E06CB904EBC40136
-:1049700005F51F7000EB8100806928B905F2C4427B
-:104980000021286803F0C8FDE1B22846FCF740FE8C
-:104990000020BDE8F08700000A30544F0A31544F20
-:1049A0002DE9F84F07460E46D7F80090C84606EBAB
-:1049B000C60107F13C0000EB8104A169206A88422E
-:1049C00002D90120BDE8F88F216AA069451AE06884
-:1049D000A84200D2E568E81C4FEA900A17E0216A75
-:1049E000A069451AE068A84200D2E568E81C4FEAD1
-:1049F000900A387CABB2F2B200904846216904F0CC
-:104A00001DFA206928442061206A2844206208F5A4
-:104A1000106000EB4610806980B2504506D3A16952
-:104A2000206A884202D2A0690028D8D1216AA069F0
-:104A300088420ED806F00F01012000FA01FB40F673
-:104A4000340050F8080020EA0B0040F6340141F829
-:104A500008000020B6E7014600BF080900EB80000F
-:104A6000420001F00F001044C0B27047014600221E
-:104A700004E0501CC2B2A1F10A00C1B20A29F8D266
-:104A8000100741EA1060704770B504460026002503
-:104A90002068C06800F04000C8B92068C06840F0D5
-:104AA00080002168C860FCF759FC064608E0FCF766
-:104AB00055FC801BB0F57A7F02D904206077012570
-:104AC0002068C06800F0400008B9012DEFD12846E9
-:104AD00070BD70B5044600252068C06820F08000D5
-:104AE0002168C8602068806800F0200030B9204646
-:104AF000FEF762FA10B1042060770125284670BDE8
-:104B000010B5024600230868506248689062D1E9F7
-:104B1000020420430C6920434C6920430343D06ABC
-:104B200020F0F7001843D062002010BD014608694C
-:104B3000C0B270470146086800F0030070470246A3
-:104B400002F114004318186870470FB410B50446FA
-:104B50000021DDE903021043059A1043069A104331
-:104B6000079A1043089A10430143606847F6FF62B2
-:104B7000904308436060002010BC5DF814FB0146C0
-:104B800003200860002070470146D1F8800070477C
-:104B900010B50246002308689060D1E90104204363
-:104BA000CC6820430C6920430343D0686FF30B00AB
-:104BB0001843D060002010BD70B585B005460C4686
-:104BC00000943720019040200290002003904FF481
-:104BD0008060049069462846FFF7DAFF41F2883288
-:104BE0003721284600F0DCF90646304605B070BD96
-:104BF00070B585B005460C460B482043009029202F
-:104C0000019040200290002003904FF480600490B7
-:104C100069462846FFF7BCFF284600F0C9FA064659
-:104C2000304605B070BD00000000108070B585B042
-:104C300005460C4600941020019040200290002070
-:104C400003904FF48060049069462846FFF7A0FF68
-:104C500041F288321021284600F0A2F9064630467B
-:104C600005B070BD70B585B005460C4600940620B1
-:104C7000019040200290002003904FF48060049047
-:104C800069462846FFF784FF41F28832062128460C
-:104C900000F086F90646304605B070BD30B585B0E7
-:104CA0000446002000900190029003904FF4806031
-:104CB000049069462046FFF76BFF204600F050F94C
-:104CC0000546284605B030BD30B585B004464FF4E2
-:104CD000D5700090082001904020029000200390A1
-:104CE0004FF48060049069462046FFF751FF20464C
-:104CF00000F0E6FA0546284605B030BD70B585B02F
-:104D000005460C460094122001904020029000209D
-:104D100003904FF48060049069462846FFF738FFFF
-:104D200041F288321221284600F03AF90646304610
-:104D300005B070BD70B585B005460C4600941120D5
-:104D4000019040200290002003904FF48060049076
-:104D500069462846FFF71CFF41F288321121284698
-:104D600000F01EF90646304605B070BDF0B585B0BE
-:104D7000064614461D4600940720019040200290EC
-:104D8000002003904FF48060049069463046FFF79E
-:104D9000FFFE41F288320721304600F001F9074654
-:104DA000384605B0F0BD30B585B00446002000900F
-:104DB00002200190C0200290002003904FF48060F8
-:104DC000049069462046FFF7E3FE204600F0BEF956
-:104DD0000546284605B030BD70B585B005460C4681
-:104DE000009409200190C0200290002003904FF40D
-:104DF0008060049069462846FFF7CAFE284600F006
-:104E0000A5F90646304605B070BD30B585B00446FC
-:104E10000020009033200190402002900020039059
-:104E20004FF48060049069462046FFF7B1FE41F2DE
-:104E300088323321204600F0B3F80546284605B0F5
-:104E400030BD70B585B005460C4600940D2001902C
-:104E500040200290002003904FF480600490694647
-:104E60002846FFF795FE41F288320D21284600F0D2
-:104E700097F80646304605B070BD70B585B005465A
-:104E80000C4600200090032001904020029000205A
-:104E900003904FF48060049069462846FFF778FE3F
-:104EA00022460321284600F0AFF90646304605B0F9
-:104EB00070BD000030B585B00446002000900C2085
-:104EC000019040200290002003904FF480600490F5
-:104ED00069462046FFF75CFE044A0C21204600F09C
-:104EE0005FF80546284605B030BD000000E1F50535
-:104EF00070B585B005460C460094192001904020FD
-:104F00000290002003904FF4806004906946284688
-:104F1000FFF73EFE41F288321921284600F040F8A2
-:104F20000646304605B070BD70B585B005460C46E6
-:104F300000941820019040200290002003904FF42C
-:104F40008060049069462846FFF722FE41F28832CD
-:104F50001821284600F024F80646304605B070BDFA
-:104F600001460E480068C0084FF47A73B0FBF3F0B6
-:104F700041F2883300FB03F200BF101EA2F10102D0
-:104F800002D14FF000407047486B00F080000028CD
-:104F9000F3D0C52088630020F5E700001000002052
-:104FA0002DE9F04305460F46904666480068C00864
-:104FB0004FF47A71B0FBF1F000FB08F900BFB9F1D2
-:104FC0000000A9F1010903D14FF00040BDE8F083D2
-:104FD0006E6B06F045000028F1D006F40060002852
-:104FE000EDD1686B00F0040010B10420A863EDE778
-:104FF000686B00F0010010B10120A863E6E7C5204E
-:10500000A8632846FFF792FDB84201D00120DDE7F2
-:1050100000212846FFF793FD04464B48204008B97D
-:105020000020D3E704F00040B0F1004F02D14FF070
-:105030000070CBE704F08040B0F1804F01D14020F8
-:10504000C4E704F00050B0F1005F01D18020BDE75B
-:1050500004F08050B0F1805F02D14FF48070B5E76A
-:1050600004F00060B0F1006F02D14FF40070ADE7C2
-:1050700004F08060B0F1806F02D14FF48060A5E74A
-:1050800004F08070B0F1807F02D14FF400609DE7A2
-:1050900004F40000B0F5000F02D14FF4805095E702
-:1050A00004F48000B0F5800F02D14FF400508DE77A
-:1050B00004F40010B0F5001F02D14FF4804085E7E2
-:1050C00004F48010B0F5801F02D14FF400407DE75A
-:1050D00004F48020B0F5802F02D14FF4003075E742
-:1050E00004F40030B0F5003F02D14FF480206DE7AA
-:1050F00004F48030B0F5803F02D14FF4002065E722
-:1051000004F40040B0F5004F02D14FF480105DE789
-:1051100004F48040B0F5804F02D14FF4001055E701
-:1051200004F40050B0F5005F02D14FF480004DE769
-:1051300004F00800082801D1000547E74FF480304B
-:1051400044E700001000002008E0FFFD10B5014614
-:1051500016480068C0084FF47A74B0FBF4F041F2CE
-:10516000883400FB04F300BF181EA3F1010302D131
-:105170004FF0004010BD4A6B02F045000028F3D00C
-:1051800002F400600028EFD1486B00F0040010B179
-:1051900004208863EEE7486B00F0010010B10120A5
-:1051A0008863E7E7C52088630020E3E7100000205C
-:1051B00010B5014613480068C0084FF47A74B0FB7C
-:1051C000F4F041F2883400FB04F300BF181EA3F191
-:1051D000010302D14FF0004010BD4A6B02F04500C0
-:1051E0000028F3D002F400600028EFD1486B00F0F3
-:1051F000040010B104208863EEE7C5208863002016
-:10520000EAE70000100000202DE9F04304460F46B5
-:1052100090462A480068C0084FF47A71B0FBF1F05C
-:1052200041F2883100FB01F900BFB9F10000A9F19A
-:10523000010903D14FF00040BDE8F083666B06F032
-:1052400045000028F1D006F400600028EDD1606B25
-:1052500000F0040010B10420A063EDE7606B00F0E3
-:10526000010010B10120A063E6E72046FFF75EFCD5
-:10527000B84201D00120DFE7C520A063002120460D
-:10528000FFF75DFC054605F4604020B9280CA8F83E
-:1052900000000020D0E705F48040B0F5804F02D137
-:1052A0004FF40050C8E705F40040B0F5004F02D1BC
-:1052B0004FF48050C0E74FF48030BDE7100000206D
-:1052C00010B5014618480068C0084FF47A74B0FB66
-:1052D000F4F041F2883400FB04F300BF181EA3F180
-:1052E000010302D14FF0004010BD4A6B02F04500AF
-:1052F0000028F3D002F400600028EFD1486B00F0E2
-:10530000040010B104208863EEE7486B00F0010050
-:1053100010B101208863E7E7486B00F0400008B156
-:10532000402088630020DFE71000002010B504460D
-:10533000012007490870FBF7CFFA28B90448007824
-:1053400020F00100024908700148007810BD0000FB
-:10535000A400002070B5044605F06CFB054604E08F
-:10536000FBF7BAFA08B9002070BD05F063FB401BDB
-:10537000A042F5D34FF0FF30F6E700002DE9F041F1
-:105380000646B46B3046FBF7DFFC02282CD0206CBD
-:10539000476DE06BD0F85480012F02D0B8F1010FB7
-:1053A0001FD11248216888632068C06B20F49D706B
-:1053B0002168C863A06B40F08040A0632046FDF7E1
-:1053C00076FF0546062D01D0052D05D12068FFF793
-:1053D00071FDA16B0843A063012084F83400002014
-:1053E00020632046FDF76AFEBDE8F081FF0540001E
-:1053F00070B50646B46B206B82280AD12068FFF78F
-:1054000059FD05462DB1A06B2843A0632046FDF74A
-:1054100055FE2068C06A20F008002168C86240F28A
-:105420003A5021688863012084F83400002020630A
-:105430002046FEF72BF970BD0146886B0268D26BDF
-:1054400042F480720368DA6370472DE9F04389B053
-:1054500004460F46FBF782FF81464FF0000800200C
-:10546000019002903E4608212068FFF7DFFB0546C9
-:105470001DB1284609B0BDE8F0835022125B11042B
-:105480002068FFF799FB05460DB12846F2E74FF07B
-:10549000FF300390082004903020059002200690F1
-:1054A000002007900120089003A92068FFF728FB3F
-:1054B0002068FFF7AAFC05460DB12846DAE71CE094
-:1054C0002068406B00F4001040B12068FFF75CFBDF
-:1054D00001A941F8280008F1010805E02068406BA7
-:1054E00000F4005000B90EE0FBF738FFA0EB090014
-:1054F000401C10B94FF00040BCE72068406B00F042
-:105500002A000028DCD000BF2068406B00F00800B3
-:1055100018B1082021688863ACE72068406B00F070
-:10552000020018B1022021688863A3E72068406B5D
-:1055300000F0200018B12020216888639AE740F22B
-:105540003A502168886302980006029901F47F416D
-:1055500040EA0120029901F47F0140EA11200299FA
-:1055600040EA11603060361D01980006019901F48F
-:105570007F4140EA0120019901F47F0140EA1120B6
-:10558000019940EA11603060002073E730B58FB0B8
-:105590000446012003902068FFF7CCFA18B94FF0B9
-:1055A00080600FB030BD606C03281BD02068FFF70F
-:1055B000FAFB05460DB12846F3E700212068FFF706
-:1055C000BEFA606704212068FFF7B9FAA0670821D6
-:1055D0002068FFF7B4FAE0670C212068FFF7AFFA04
-:1055E00080210851606C032807D003A92068FFF7C9
-:1055F00044FC05460DB12846D3E7606C032820D053
-:10560000BDF80C1021655022125B11042068FFF7D1
-:10561000E3FB05460DB12846C3E700212068FFF7EC
-:105620008EFA606604212068FFF789FAA0660821D7
-:105630002068FFF784FAE0660C212068FFF77FFA04
-:10564000206704212068FFF77AFA010DE16404A9BC
-:105650002046FDF735FD10B14FF08050A1E75020F6
-:10566000005B01040A4600232068FFF77FFB054624
-:105670000DB1284695E7D4E90412A069CDE90012DE
-:10568000029094E80F00FFF760FA002089E700001D
-:10569000F8B5044600200090002600272068FFF798
-:1056A000FDFA05460DB12846F8BD2068FFF70CFB52
-:1056B000054645B10021A1642068FFF7EFFA0546D1
-:1056C0001DB12846F0E70121A164A06C012808D192
-:1056D00000212068FFF770FA054615B14FF08050A1
-:1056E000E2E71DE000212068FFF766FA05460DB1EC
-:1056F0002846D9E718492068FFF77AFA054615B118
-:105700004FF08050D0E700212068FFF718FA0646D6
-:10571000012080EAD67080F001070098401C0090BC
-:105720004FF6FF710098884201D2002FDAD04FF671
-:10573000FF710098884202D34FF08070B4E706F002
-:105740008040B0F1804F02D10120606401E0002070
-:1057500060640020A8E70000000010C170B5044696
-:105760000D4615B94FF0006070BD5022125B110458
-:105770002068FFF766FB06460EB13046F4E70021CD
-:105780002068FFF7DCF928600020EDE77CB50446CF
-:1057900000200090019000212068FFF7D0F900F070
-:1057A0000070B0F1007F02D14FF400607CBD69460B
-:1057B0002046FFF74AFE05460DB12846F6E7019858
-:1057C00000F4803098B15022125B11042068FFF77A
-:1057D000F3F905460DB12846E8E700212068FFF7F8
-:1057E00041FA05460DB12846E0E70020DEE74FF01C
-:1057F0008060DBE77CB5044600200090019000212A
-:105800002068FFF79CF900F00070B0F1007F02D132
-:105810004FF400607CBD69462046FFF716FE054642
-:105820000DB12846F6E7019800F4802098B1502287
-:10583000125B11042068FFF7BFF905460DB1284639
-:10584000E8E702212068FFF70DFA05460DB128466A
-:10585000E0E70020DEE74FF08060DBE71FB504469D
-:1058600001201649087005F0D7F810B3FBF740F88F
-:1058700020B92046FFF75AFD104908700F480078FC
-:10588000012816D00E48006850B90E4B0FCB8DE89A
-:105890000F000021684605F0D7F80949086000BFED
-:1058A0000748006828B90548007840F0010003491E
-:1058B00008700248007804B010BD0000A400002069
-:1058C000A800002024E80008F0B589B007460D467E
-:1058D000144601261648007800F0010010B103209C
-:1058E00009B0F0BD35B1012D06D0022D0BD0032D2E
-:1058F00018D10FE0002617E001A8FAF7E3FF079898
-:105900002060002610E001A8FAF7DCFF089820804C
-:10591000002609E001A8FAF7D5FF0898400A2060A0
-:10592000002601E0042600BF00BF3046D8E7000093
-:10593000A40000202DE9F04786B082460E461746A7
-:1059400098464FF0010947F23050FFF703FD002859
-:1059500003DA484606B0BDE8F0874246394630468D
-:10596000FAF7EAFF044614BB47F2305211480168C7
-:10597000684605F07DF89DE8070003AB07C3039870
-:10598000102814D10498012811D105F053F80546C8
-:1059900005E0FAF7A1FF10B94FF0000906E005F0A5
-:1059A00049F8401B47F230518842F2D300BF4846C5
-:1059B000D0E70000A800002010B504462046FFF7FD
-:1059C000B5FC10BD2DE9F04387B081460D46164663
-:1059D0001F464FF0010847F23050FFF7BBFC00288C
-:1059E00003DA404607B0BDE8F0833A463146284620
-:1059F000FAF7C0FF10BB47F230521148016801A806
-:105A000005F036F801A807C804AB07C304981028AE
-:105A100014D10598022811D105F00CF8044605E0D0
-:105A2000FAF75AFF10B94FF0000806E005F002F847
-:105A3000001B47F230518842F2D300BF4046D1E705
-:105A4000A80000207CB504460D461646164800689E
-:105A50001821B0FBF1F01549B0FBF1F04FF47A7169
-:105A6000484301906068B0F5827F0DD12B4600223B
-:105A700080212046009600F01BF898B1606D40F040
-:105A80002000606503207CBD00BF019800B908E0DC
-:105A90000198401E019020688068C0F3C010002863
-:105AA000F3D100BF0020EEE71000002040420F00BD
-:105AB0002DE9F84F04460D4690461E46DDF8289025
-:105AC000FBF74CFCA0EB0900371AFBF747FC8246BA
-:105AD0002C480068C0F3CB307843009045E0701C40
-:105AE000002842D0FBF73AFCA0EB0A00B84200D2F3
-:105AF000A7BB2068406820F0E0002168486060682B
-:105B0000B0F5827F0DD1A068B0F5004F03D0A0683A
-:105B1000B0F5806F05D12068006820F04000216852
-:105B20000860A06AB0F5005F0DD100BF2068006872
-:105B300020F40050216808602068006840F400509C
-:105B40002168086000BF012084F8510000BF0020D8
-:105B500084F8500000BF0320BDE8F88FFFE70098ED
-:105B600000B900270098401E0090206880682840F7
-:105B7000A84201D1012000E000204045AFD1002023
-:105B8000EAE700001000002030B501460A4613780D
-:105B9000521C147843EA042030BDFEF7FBFD00BF21
-:105BA000012004F02DFFFBE710B500BF502080F36B
-:105BB0001188BFF34F8FBFF36F8F00BF08F0A4FBB6
-:105BC00018B14FF080500449086000BF002080F3F6
-:105BD000118800BF10BD000004ED00E000B593B0D7
-:105BE000302107A8FAF798FB142102A8FAF794FBD2
-:105BF00000BF002001902548006840F080502349F4
-:105C000008600846006800F08050019000BF00BFA7
-:105C100000BF002001901E48006840F480401C49ED
-:105C200008600846006800F48040019000BF00BF93
-:105C3000052007904FF48030089001200990022041
-:105C40000D9041050E9104210F91A8211091022180
-:105C500011910721129107A8FCF7BCFD08B1FAF7D2
-:105C6000B9FF0F20029002200390002004904FF40F
-:105C7000A05005904FF480500690052102A8FCF733
-:105C800047FC08B1FAF7A6FF13B000BD4038024048
-:105C9000007000400348006840F47000014908604B
-:105CA0007047000088ED00E010B50248FDF7E7FFFF
-:105CB00010BD0000AC07002010B50268294B9842C7
-:105CC0000ED0B0F1804F0BD0274B984208D0274B15
-:105CD000984205D0264B984202D0264B984203D1D9
-:105CE00022F070024B681A431E4B984220D0B0F14C
-:105CF000804F1DD01C4B98421AD01C4B984217D095
-:105D00001B4B984214D01B4B984211D01A4B98420F
-:105D10000ED01A4B98420BD0194B984208D0194B11
-:105D2000984205D0184B984202D0184B984203D1A4
-:105D300022F44072CB681A4322F080034C6943EA94
-:105D4000040202608B68C3620B688362054B984251
-:105D500002D0084B984201D10B69036301234361D0
-:105D600010BD000000000140000400400008004099
-:105D7000000C00400004014000400140004401408C
-:105D80000048014000180040001C00400020004076
-:105D900070B50546AC6B0020E085E0842046FEF738
-:105DA00049F870BD70B506460025B46B206840699F
-:105DB000C0F3C01594F83D00212805D125B100207D
-:105DC000E084204600F0C4F820684069C0F38015E4
-:105DD00094F83E00222805D125B10020E085204618
-:105DE00000F070F8206C40F0100020642046FEF7B0
-:105DF00021F870BD70B50546AC6B2868006800F4EA
-:105E00008070002842D1E08500BF00BF21680C31BE
-:105E100051E8001F21F4807021680C3141E8000234
-:105E2000002AF3D100BF00BF00BF2168143151E840
-:105E3000001F21F001002168143141E80002002A0E
-:105E4000F3D100BF00BF00BF2168143151E8001F2B
-:105E500021F040002168143141E80002002AF3D10A
-:105E600000BF202084F83E00206B01280ED100BF27
-:105E700000BF21680C3151E8001F21F0100021689B
-:105E80000C3141E80002002AF3D100BF206B012849
-:105E900004D1A18D2046FDF7CCFF02E02046FEF79D
-:105EA00024FA70BD70B50546AC6B206B012805D196
-:105EB000A08D41082046FDF7BCFF02E02046FEF71A
-:105EC00015FA70BD00BF00BF02680C3252E8002F07
-:105ED00022F4907102680C3242E80013002BF3D1D7
-:105EE00000BF00BF00BF0268143252E8002F22F04A
-:105EF00001010268143242E80013002BF3D100BF05
-:105F0000016B01290ED100BF00BF02680C3252E8BC
-:105F1000002F22F0100102680C3242E80013002B1F
-:105F2000F3D100BF202180F83E10002101637047AB
-:105F300010B504462068C06820F040002168C860A1
-:105F4000202084F83D002046FEF73AFA002010BDDC
-:105F500000BF00BF02680C3252E8002F22F0C001DF
-:105F600002680C3242E80013002BF3D100BF20215D
-:105F700080F83D107047F8B5044694F83E0022289A
-:105F800073D1A068B0F5805F0CD1206950B90025AD
-:105F9000A66A20684068C0F308003080A06A801CB0
-:105FA000A06215E0A56A0026A068B0F5805F03D066
-:105FB000A06828B9206918B920684068287004E0F2
-:105FC0002068406800F07F002870A06A401CA06232
-:105FD000E08D401E80B2E085002844D12068C06872
-:105FE00020F020002168C8602068C06820F480701C
-:105FF0002168C8602068406920F00100216848617C
-:10600000202084F83E00206B012826D10020206348
-:1060100000BF00BF21680C3151E8001F21F01000C3
-:1060200021680C3141E80002002AF3D100BF20684A
-:10603000006800F0100010280AD100BF0020009076
-:1060400020680068009020684068009000BF00BF92
-:10605000A18D2046FDF7EDFE02E02046FEF745F952
-:106060000020F8BD01E00020FBE70220F9E7000076
-:106070002DE9F84F04462068006920F44050E1689B
-:106080000843216808612169A068084361690843E1
-:10609000E169084300902068C06849F20C618843B8
-:1060A000009908432168C8602068406920F4407066
-:1060B000A16908432168486176492068884203D075
-:1060C00075492068884203D1FCF71CFB814602E039
-:1060D000FCF708FB8146E069B0F5004F6CD1022067
-:1060E0006168A0FB015003461920A9FB007001461E
-:1060F0002A463846FAF7C6F86421B0FBF1F04FEAB9
-:10610000001A02206168A0FB01510B461920A9FB6F
-:1061100000712A463846FAF7B5F8834602206168CE
-:10612000A0FB015003461920A9FB00712A463846FE
-:10613000FAF7A8F86421B0FBF1F000EBC00101EB25
-:106140000010ABEB8000322101EBC0006421B0FBFA
-:10615000F1F000F0F8000AEB400A02206168A0FBB1
-:10616000015003461920A9FB007001462A46384613
-:10617000FAF788F8834602206168A0FB01500346C5
-:106180001920A9FB00712A463846FAF77BF86421EA
-:10619000B0FBF1F000EBC00101EB0010ABEB8000B5
-:1061A000322101EBC0006421B0FBF1F000F00700E8
-:1061B0005044216888606AE004206168A0FB0150B7
-:1061C00003461920A9FB007001462A463846FAF713
-:1061D00059F8824604206168A0FB0150034619204B
-:1061E000A9FB007001462A463846FAF74BF86421AD
-:1061F000B0FBF1F000EBC00101EB0010AAEB800056
-:10620000322101EB00106421B0FBF1F000F0F00A44
-:1062100004206168A0FB017003461920A9FB00510E
-:106220003A462846FAF72EF86421B0FBF1F00AEB63
-:10623000001A04206168A0FB01510B461920A9FB3C
-:1062400000712A463846FAF71DF883460420616833
-:10625000A0FB015003461920A9FB007001462A4605
-:106260003846FAF70FF86421B0FBF1F000EBC001FB
-:1062700001EB0010ABEB8000322101EB0010642138
-:10628000B0FBF1F000F00F00504421688860BDE8D9
-:10629000F88F0000001001400014014077B581B074
-:1062A000044615460298A062A5850020206422209D
-:1062B00084F83E002A48A16BC8632A48A16B086491
-:1062C0002948A16BC8640020A16B086502AE326842
-:1062D0002368191D2B46A06BFAF7D0FE00BF0020E3
-:1062E000009020680068009020684068009000BF1F
-:1062F00000BF00BF002084F83C0000BF206970B1DF
-:1063000000BF00BF21680C3151E8001F41F48070CC
-:1063100021680C3141E80002002AF3D100BF00BF20
-:1063200000BF2168143151E8001F41F001002168CD
-:10633000143141E80002002AF3D100BF00BF00BFC2
-:106340002168143151E8001F41F0400021681431E8
-:1063500041E80002002AF3D100BF002004B070BD64
-:10636000F55D0008A55E0008A55D0008014691F8EE
-:106370003D00212828D18868B0F5805F0BD10869DD
-:1063800048B90A6A1088C0F308000B685860086AA8
-:10639000801C086205E00B6A581C086218780B68BC
-:1063A0005860C88C401E80B2C88458B90868C0685C
-:1063B00020F080000B68D8600868C06840F040009A
-:1063C0000B68D860002070470220FCE72DE9F041FF
-:1063D00004460D4617469846069E34E0701C88B366
-:1063E0002EB1FAF7BBFFA0EB0800B0422BD900BFDB
-:1063F00000BF21680C3151E8001F21F4D0702168E2
-:106400000C3141E80002002AF3D100BF00BF00BFF9
-:106410002168143151E8001F21F001002168143176
-:1064200041E80002002AF3D100BF202084F83D009B
-:1064300084F83E0000BF002084F83C0000BF032029
-:10644000BDE8F081FFE7206800682840A84201D13C
-:10645000012000E00020B842C0D00020F0E700009A
-:1064600008B50D480068006800F0100010280ED133
-:1064700000BF0020009008480068006800900648AF
-:1064800000684068009000BF00BF06F023FC02488F
-:10649000FDF7D2FC08BD0000A80600202DE9F04160
-:1064A00004460D46D4F8C87204F53070D4F8D412FE
-:1064B00050F8210010B90320BDE8F08104F53070D8
-:1064C000D4F8D41250F8216005F00F0000EB8001E1
-:1064D00004F1140000EB8100406838B305F00F00B0
-:1064E00000EB800104F1140000EB8100416805F02D
-:1064F0000F0000EBC00207F13C0000EB8200C06817
-:10650000B1FBF0F200FB121080B9002105F00F0082
-:1065100000EB800204F1140000EB820041600023D4
-:106520001A462946204601F02CF917E00020C6F84B
-:10653000140204F53170D4F8D41250F82100006927
-:1065400060B1D6F8080204F53171D4F8D42251F8BC
-:1065500022102A460B6906F5047198470020ABE724
-:1065600070B504460E4604F53070D4F8D41250F8D5
-:106570002150D4F8D41250F8210008B9032070BD7E
-:106580003146204600F059FFC5F80C02D5F8040248
-:1065900004F53171D4F8D43251F82310CA6805F5E6
-:1065A000037190470020EAE770B504460D46304875
-:1065B0000178204600F013FE00212D48007800F0FD
-:1065C0000F0000EB800204F1140000EB8200018256
-:1065D00028480178204600F002FE00212548007876
-:1065E00000F00F0000EB800204F5AA7000EB8200BF
-:1065F000018221480178204600F0F1FD00211E486B
-:10660000007800F00F0000EB800204F1140000EBB2
-:10661000820001821848007800F00F0000EB800231
-:1066200004F1140000EB8200418204F53070D4F8CC
-:10663000D41250F82100C8B104F53171D4F8D42235
-:1066400051F822104868804704F53071D4F8D422FC
-:1066500051F8220001F0BEFB002104F53070D4F89F
-:10666000D42240F822100020C4F8BC02002070BDE3
-:106670001F020020200200202102002070B50446E5
-:1066800004F53070D4F8D41250F821500DB903201D
-:1066900070BD04F53170D4F8D41250F8210098B1CF
-:1066A00095F80002FF280FD095F8012295F8000216
-:1066B00004F53171D4F8D46251F826108B6829465C
-:1066C0009847FF2085F800020020E1E701460A20F4
-:1066D0000880014870470000980100202DE9F04132
-:1066E000044682210D4800F0A0FC054601210B481C
-:1066F00000F09BFC06468121084800F096FC074606
-:106700000DB11020A8710EB14020B0800FB1402013
-:10671000B880432020800148BDE8F081DC010020E2
-:106720002DE9F041044682210E4800F07EFC05462A
-:1067300001210C4800F079FC06468121094800F04F
-:1067400074FC07460DB11020A87116B14FF400700B
-:10675000B08017B14FF40070B8804320208001480A
-:10676000BDE8F081DC0100202DE9F04104468221E2
-:106770000D4800F05AFC054601210B4800F055FC7D
-:1067800006468121084800F050FC07460DB1102054
-:10679000A8710EB14020B0800FB14020B8804320D6
-:1067A00020800148BDE8F081DC01002070B504467E
-:1067B0000E464FF4077001F00FFB054645B9002166
-:1067C00004F53070D4F8D42240F82210022070BDB5
-:1067D0004FF407712846F9F79FFD04F53070D4F89F
-:1067E000D41240F82150D4F8D41250F82100C4F843
-:1067F000BC02207C98BB4FF4007302225048017801
-:10680000204600F0BBFE01214D48007800F00F004B
-:1068100000EB800204F1140000EB820001824B02C5
-:10682000022248480178204600F0A8FE0121454890
-:10683000007800F00F0000EB800204F5AA7000EB76
-:106840008200018210214048007800F00F0000EB28
-:10685000800204F1140000EB8200418232E0FFE785
-:106860004023022236480178204600F087FE0121AD
-:106870003348007800F00F0000EB800204F11400B0
-:1068800000EB82000182402302222E48017820463C
-:1068900000F074FE01212B48007800F00F0000EB9F
-:1068A000800204F5AA7000EB8200018210212648C4
-:1068B000007800F00F0000EB800204F1140000EB00
-:1068C00082004182082303221F480178204600F0FD
-:1068D00055FE01211C48007800F00F0000EB8002FB
-:1068E00004F1140000EB820001820020C5F80402CC
-:1068F00004F53171D4F8D42251F822100868804789
-:106900000020C5F81402C5F81802D5F8040208B929
-:1069100002205CE7207C48B94FF4007309480178F5
-:106920002046D5F8042200F041FE07E04023054848
-:1069300001782046D5F8042200F038FE002046E712
-:106940001F020020200200202102002070B5044612
-:1069500004F53070D4F8D41250F82150D4F8D41281
-:1069600050F8210008B9032070BD207C48B94FF4CD
-:106970000073094801782046D5F8042200F016FE7D
-:1069800007E04023044801782046D5F8042200F0AF
-:106990000DFE0020E8E7000020020020024609B9B1
-:1069A0000320704702F53170D2F8D43240F823103A
-:1069B0000020F6E710B5024602F53070D2F8D44256
-:1069C00050F824300BB9032010BDC3F80412002086
-:1069D000FAE730B503460C4603F53070D3F8D452CD
-:1069E00050F8251009B9032030BDC1F80842C1F89C
-:1069F00010220020F8E72DE9FC4105460C4605F57C
-:106A00003070D5F8D41250F8216000200190009029
-:106A1000804616B90320BDE8FC81207800F06000B4
-:106A200000283DD020287CD1E08868B3207800F091
-:106A30008000B8B1E288607805F53171D5F8D4C22C
-:106A400051F82C108B6831469847E088072801D907
-:106A5000072000E0E08807463A463146284600F025
-:106A600015F91CE0607886F80002E088402801D221
-:106A7000E08800E0402086F8010296F801223146C5
-:106A8000284600F0E2F80AE0607805F53171D5F8A3
-:106A9000D42251F8221000228B682146984747E003
-:106AA000607830B1012832D00A2813D00B282FD1BA
-:106AB00021E095F89C02032805D102226946284668
-:106AC00000F0E4F805E02146284600F0B2F84FF067
-:106AD000030824E095F89C02032805D1012201A9AE
-:106AE000284600F0D3F805E02146284600F0A1F83A
-:106AF0004FF0030813E095F89C02032805D02146C7
-:106B0000284600F096F84FF0030808E009E006E098
-:106B10002146284600F08DF84FF0030800BF00BF63
-:106B200006E02146284600F084F84FF0030800BF35
-:106B300000BF40466FE7000070B5044604F53070B2
-:106B4000D4F8D41250F821500126D4F8D41250F8B9
-:106B5000210008B9032070BDD5F81402C8B901207E
-:106B6000C5F814020C48007800F00F0000EB80021A
-:106B700004F1140000EB8200D5F8101241600648C1
-:106B800001782046D5F81032D5F8082200F0F9FD3A
-:106B900000263046DFE700001F02002070B50446E3
-:106BA0000D460026D4F8B802294642682046904790
-:106BB00000B10326304670BD70B504460D4694F80A
-:106BC0009C02012804D0022803D003280CD101E044
-:106BD00000BF00BF6888012805D10020C4F8A402C6
-:106BE000204600F064F804E02946204600F021F831
-:106BF00000BF00BF70BD0246002070470246002063
-:106C0000704770B506460C4615462B4622460021B5
-:106C1000304600F0CBFC002070BD70B506460C4637
-:106C200015462B4622460021304600F0AAFD0020E2
-:106C300070BD70B504460D468021204600F075FDFC
-:106C40000021204600F071FD70BD70B504460E466F
-:106C500015460320C4F894024FF4AC700551001D92
-:106C600005512B4632460021204600F09FFC0020B3
-:106C700070BD10B504460520C4F8940200231A46DE
-:106C80001946204600F092FC002010BD70B5044665
-:106C90000E4615460220C4F89402A561E5612B4614
-:106CA00032460021204600F06CFD002070BD10B57A
-:106CB00004460420C4F8940200231A4619462046CC
-:106CC00000F05FFD002010BD70B505460C462DB9E3
-:106CD0002246064906A000F012FA04E022460349C3
-:106CE00003A000F00CFA014870BD00006CF8002011
-:106CF00043444320436F6E666967000002461220DA
-:106D000008800148704700004C01002070B505461E
-:106D10000C462DB92246064906A000F0F0F904E021
-:106D20002246034903A000F0EAF9014870BD0000C3
-:106D30006CF8002043444320496E746572666163B9
-:106D400065000000024604200880014870470000EA
-:106D50006001002070B505460C462246024903A09A
-:106D600000F0CDF9004870BD6CF8002053544D6917
-:106D700063726F656C656374726F6E696373000034
-:106D800070B505460C462DB92246064906A000F00E
-:106D9000B6F904E02246034903A000F0B0F9014827
-:106DA00070BD00006CF8002053544D3332205669FA
-:106DB000727475616C20436F6D506F7274000000C7
-:106DC00070B505460C461A202080F9F739FF0148B6
-:106DD00070BD00006401002070B504460D46E888CF
-:106DE000012804D029462046FFF723FF1EE094F82F
-:106DF0009C02012804D0022803D0032810D109E006
-:106E000000BF0020A060012204F108012046FFF726
-:106E10003DFF0AE00122211D2046FFF737FF04E075
-:106E200029462046FFF705FF00BF00BF70BDF8B53B
-:106E300004460E46002000900027002570880012AE
-:106E4000082875D2DFE800F0C7040C20C7C7A5B535
-:106E5000207CD4F8B4120A68694690470746C1E01E
-:106E6000207C40B9D4F8B802816A68468847074652
-:106E70000220787007E0D4F8B802C16A68468847F3
-:106E8000074602207870ADE0B078062878D2DFE8B7
-:106E900000F00316293C5063D4F8B402406838B1BE
-:106EA000207CD4F8B4124A6869469047074605E04A
-:106EB00031462046FFF7BDFE681CC5B267E0D4F836
-:106EC000B402806838B1207CD4F8B4128A6869466C
-:106ED0009047074605E031462046FFF7AAFE681CAA
-:106EE000C5B254E0D4F8B402C06838B1207CD4F8FC
-:106EF000B412CA6869469047074605E03146204605
-:106F0000FFF797FE681CC5B241E0D4F8B4020069EF
-:106F100038B1207CD4F8B4120A6969469047074614
-:106F200005E031462046FFF784FE681CC5B22EE01E
-:106F300051E0D4F8B402406938B1207CD4F8B412DE
-:106F40004A6969469047074605E031462046FFF703
-:106F500070FE681CC5B21AE0D4F8B402806940B172
-:106F6000207CD4F8B4128A6969469047074606E047
-:106F700006E031462046FFF75CFE681CC5B206E01D
-:106F800031462046FFF755FE681CC5B200BF00BF62
-:106F900028E0207C30B9D4F8B802416B68468847B5
-:106FA000074605E031462046FFF743FE681CC5B2A0
-:106FB00018E0207C40B9D4F8B802016B68468847D5
-:106FC00007460720787005E031462046FFF731FE7E
-:106FD000681CC5B206E031462046FFF72AFE681C51
-:106FE000C5B200BF00BF05B1F8BDF088C0B1BDF8A3
-:106FF000000080B1F088BDF80010884202DDBDF8C5
-:10700000000000E0F0880090BDF8002039462046DE
-:10701000FFF73CFE07E031462046FFF70AFE02E09C
-:107020002046FFF744FE00BFDEE72DE9F8410546A4
-:107030000F462C462E464FF0000870883178884263
-:1070400018DD307800900FE06946204600F020F807
-:1070500004466078052807D1A04698F80200B84297
-:1070600000D106E04FF000087088BDF8001088429B
-:10707000EADC00BF4046BDE8F881014600200A4630
-:1070800002E0431CD8B2521C1378002BF9D1704790
-:1070900010B5024610460B88047823440B80037811
-:1070A000981810BD70B504460D4694F89C0201284E
-:1070B00004D0022803D003281AD101E000BF00BF8A
-:1070C000E888022804D029462046FFF7B2FD14E0E4
-:1070D0000120E060D4F8A40218B1E06840F002009A
-:1070E000E060022204F10C012046FFF7CFFD04E02E
-:1070F00029462046FFF79DFD00BF00BF70BD2DE96A
-:10710000F04107460D46904600240FB9BDE8F081D6
-:107110003E463046FFF7B1FF022101EB4000A8F8E0
-:10712000000098F800002855601CC4B203202855C0
-:10713000601CC4B208E030782855761C601CC4B2CC
-:1071400000202855601CC4B230780028F3D100BF5D
-:10715000DCE70146002031B1012906D0022906D022
-:10716000032908D105E0002007E0032005E0012005
-:1071700003E0032001E0032000BF00BF70472DE9BA
-:10718000F04104460D46164614B90320BDE8F081CF
-:107190000020C4F8B802C4F8C402C4F8D0020DB18B
-:1071A000C4F8B452012084F89C022670204600F0F6
-:1071B0004DF907463846E9E72DE9F04104460D460A
-:1071C000002600272946D4F8C802FAF78EFA0646A8
-:1071D0003046FFF7BEFF07463846BDE8F0812DE98F
-:1071E000F04104460D46002600272946D4F8C8027F
-:1071F000FAF746FA06463046FFF7ABFF0746384631
-:10720000BDE8F0812DE9F04704460F469146002F76
-:1072100056D104F11405D4F89402022846D1D5E9D8
-:10722000020188420FD9D5E90201401AA8604946F7
-:107230002046AA68FFF7F1FC00231A4619462046AB
-:1072400000F0B4F932E0D5E90210884217D1E968BC
-:107250006868884213D36868D4F8981288420ED2BE
-:10726000002211462046FFF7D8FC0020C4F89802FF
-:1072700000231A461946204600F098F916E094F8C3
-:107280009C0203280BD1D4F8B802C06838B10020A2
-:10729000C4F8D402D4F8B802C168204688478021D7
-:1072A000204600F042FA2046FFF7E3FC94F8A002E3
-:1072B00050B3204600F0BCFA002084F8A00223E07E
-:1072C00047F080012046FFF796FC0646FF2E1BD0B4
-:1072D000D6B994F89C02032816D104F52E7050F804
-:1072E0002600406980B1C4F8D46204F52E7050F8CD
-:1072F000260039464269204690478046B8F1000F83
-:1073000002D04046BDE8F0870020FBE72DE9F047BA
-:1073100005460F4690464FF00009002F51D105F564
-:10732000AA76D5F8940203286FD1D6E902018842E3
-:1073300010D9D6E90201401AB060D6E902018842AC
-:1073400001D2B06800E0F068024641462846FFF7E7
-:1073500058FC5AE095F8AA0200F01F0020B101285D
-:1073600004D0022812D109E0002411E040F2AE203E
-:10737000415D2846FFF742FC044609E040F2AE209A
-:10738000415D2846FFF737FC044601E0002400BFBA
-:1073900000BF94B995F89C0203280ED105F52E7014
-:1073A00050F82400006940B1C5F8D44205F52E70AC
-:1073B00050F824000169284688472846FFF777FCE3
-:1073C00023E007F07F012846FFF715FC0446FF2C59
-:1073D0001BD0D4B995F89C02032810D105F52E7066
-:1073E00050F82400806950B1C5F8D44205F52E70DC
-:1073F00050F8240039468269284690478146B9F101
-:10740000000F02D04846BDE8F0870020FBE70146A8
-:107410000020704770B504460025012084F89C02C6
-:10742000D4F8B80238B12179D4F8B80242682046BD
-:10743000904700B10325284670BD70B504460D463F
-:107440002946D4F8C802FAF78EF970BD10B5044683
-:10745000207800282AD11648C0F80845C4F8C80288
-:107460004FF0A040124908600420486002211048F3
-:10747000C16000210161022181610021C1610162BD
-:107480004162C1620163FAF7D4FD08B1F9F7A2FBCA
-:1074900080210748FAF779F8402200210448FAF7DA
-:1074A00079F8802201210248FAF774F8002010BD13
-:1074B0006C0A012010B50246D2F8C83201F08000F3
-:1074C000802809D101F07F0000EBC00403F13C00EB
-:1074D00000EB8400807810BD01F07F0000EBC00459
-:1074E00003F51F7000EB84008078F4E770B5044664
-:1074F0000D4604F52E70D4F8D41250F8210008B9C6
-:10750000032070BD94F89C02032811D104F52E705D
-:10751000D4F8D41250F82100006A48B104F52E7056
-:10752000D4F8D41250F821002946026A2046904728
-:107530000020E6E770B504460D4604F52E70D4F839
-:10754000D41250F8210008B9032070BD94F89C02B1
-:10755000032811D104F52E70D4F8D41250F821006C
-:10756000406A48B104F52E70D4F8D41250F82100C6
-:107570002946426A204690470020E6E72DE9F04779
-:1075800004460F4615461E464FF00008C1462B46DE
-:1075900032463946D4F8C802FAF7F0F88046404639
-:1075A000FFF7D7FD81464846BDE8F0872DE9F04753
-:1075B00004460D4616461F464FF00008C1463B469E
-:1075C00032462946D4F8C802FAF71EF980464046EA
-:1075D000FFF7BFFD81464846BDE8F08770B5044619
-:1075E0000025012084F89C020020C4F89402606009
-:1075F000C4F8A40284F8A002D4F8B80258B1D4F8B0
-:10760000B802406838B12179D4F8B80242682046FF
-:10761000904700B103254023002211462046FFF782
-:10762000ADFF01214FF4B27001534021001F015101
-:107630004023002280212046FFF7A0FF0121A184E2
-:1076400040212162284670BD014691F89C02042821
-:1076500003D191F89D0281F89C020020704710B57B
-:10766000044694F89C0203280BD1D4F8B80240B128
-:10767000D4F8B802C06920B1D4F8B802C169204674
-:107680008847002010BD02461174002070472DE984
-:10769000F04104460D46002600272946D4F8C802CA
-:1076A000FAF7F4FD06463046FFF753FD0746384625
-:1076B000BDE8F08170B504460D46294604F2AA20C3
-:1076C00000F077F80120C4F894024FF42C70005BAE
-:1076D000C4F8980294F8AA0200F01F0020B1012813
-:1076E00009D0022815D10DE004F2AA21204600F0AD
-:1076F00083F9064616E004F2AA21204600F013FBA7
-:1077000006460FE004F2AA21204600F0CCF9064616
-:1077100008E094F8AA0200F08001204600F005F885
-:10772000064600BF00BF304670BD2DE9F04104465B
-:107730000D46002600272946D4F8C802FAF790F82B
-:1077400006463046FFF705FD07463846BDE8F0819E
-:1077500070B5044600250026D4F8C802FAF7BAFD31
-:1077600005462846FFF7F5FC0646304670BD014643
-:1077700091F89C0281F89D02042081F89C0200206F
-:1077800070472DE9F04704460D4616461F464FF058
-:107790000008C1463B4632462946D4F8C802FAF7EB
-:1077A000A4F880464046FFF7D4FC81464846BDE831
-:1077B000F08770B505460E46344620782870641C64
-:1077C00020786870641C2046FEF7DEF96880641C2F
-:1077D000641C2046FEF7D8F9A880641C641C20466F
-:1077E000FEF7D2F9E88070BD38B504460D4600209A
-:1077F00000900DB9032038BDC4F8B85204F52E70BE
-:10780000D4F8D41250F82100C06A50B104F52E709B
-:10781000D4F8D42250F82200C16A68468847C4F8D8
-:10782000D002D4F8D802401CC4F8D8020020E2E705
-:1078300001460020704770B504460D46A88810BB6D
-:10784000E88800BB688880281DD2A87800F07F06F1
-:1078500094F89C02032804D129462046FFF7E9F951
-:1078600015E084F89E6231462046FFF710FF20465F
-:10787000FFF71DFA1EB1022084F89C0207E00120E8
-:1078800084F89C0203E029462046FFF7D2F970BD38
-:1078900070B504460D460026D4F8B80230B1D4F8CD
-:1078A000B80229460268204690470646304670BD19
-:1078B00070B504460E460025B0783D49087008466C
-:1078C0000078012805D931462046FFF7B2F9032098
-:1078D00070BD94F89C02022802D0032859D11FE001
-:1078E00033480078C0B13248007860603048017891
-:1078F0002046FFF7CDFF05463DB131462046FFF754
-:1079000098F9022084F89C0209E02046FFF7CFF99D
-:10791000032084F89C0202E02046FFF7C8F943E008
-:107920002348007870B9022084F89C02204800782F
-:1079300060601F4801782046FFF730F92046FFF7C6
-:10794000B6F925E01A490978606888421DD0217986
-:107950002046FFF723F91648007860601448017844
-:107960002046FFF795FF05465DB131462046FFF7FB
-:1079700060F921792046FFF711F9022084F89C0272
-:1079800006E02046FFF793F902E02046FFF78FF963
-:107990000AE031462046FFF74CF9054801782046B9
-:1079A000FFF7FCF8032500BF00BF284690E7000062
-:1079B0009401002070B505460C466088012805D169
-:1079C000C5F8A4022846FFF772F90EE06088022885
-:1079D00007D1A088001285F8A0022846FFF767F9B2
-:1079E00003E021462846FFF724F970BD10B5044690
-:1079F0002046FFF7ADFE10BD70B504460D460026CB
-:107A0000287800F0600088B1202802D0402842D1B8
-:107A100000E000BF04F52E70D4F8D41250F8210015
-:107A20002946826820469047064639E068780A2849
-:107A30002AD2DFE800F01A24291F290A0529150F88
-:107A400029462046FFF7F3F923E029462046FFF7B1
-:107A5000F2FE1EE029462046FFF72AFF064618E000
-:107A600029462046FFF7B8F913E029462046FFF7DC
-:107A700019FB0EE029462046FFF79CFF09E0294646
-:107A80002046FFF799F804E029462046FFF7D1F891
-:107A900000BF00BF04E029462046FFF7CAF800BF38
-:107AA00000BF304670BD2DE9F04705460F464FF048
-:107AB00000093C79387800F06000F8B1202802D045
-:107AC00040287DD100E000BF21462846FFF793F80B
-:107AD0000646FF2E11D086B9C5F8D46205F52E7082
-:107AE00050F82600806840B105F52E7050F8260049
-:107AF0003946826828469047814610E17878002808
-:107B00007AD001282FD003286ED195F89C02022844
-:107B100002D0032820D110E054B1802C08D0214697
-:107B20002846FFF702FE80212846FFF7FEFD03E00E
-:107B300039462846FFF77DF813E0788840B93CB114
-:107B4000802C05D0F88818B921462846FFF7EDFDAE
-:107B50002846FFF7ACF804E039462846FFF769F8F5
-:107B600000BF00BFD4E095F89C02022802D0032891
-:107B70003BD110E054B1802C08D021462846FFF7B5
-:107B8000D4FD80212846FFF7D0FD03E03946284682
-:107B9000FFF74FF82EE0788820BB04F07F0018B183
-:107BA00021462846FFF708FB2846FFF780F82146C4
-:107BB0002846FFF720F80646FF2E13D096B900E0BE
-:107BC000A8E0C5F8D46205F52E7050F8260080684C
-:107BD00040B105F52E7050F82600394682682846D7
-:107BE0009047814606E007E08DE039462846FFF7DA
-:107BF00020F800BF00BF8BE095F89C02022802D05D
-:107C0000032879D126E034B1802C04D039462846A7
-:107C1000FFF70FF875E004F08000802808D104F029
-:107C20007F0000EB800105F1140000EB810007E00C
-:107C300004F07F0000EB800105F5AA7000EB8100E5
-:107C400080460020C8F80000022241462846FFF77F
-:107C50001DF856E004F0800080280ED104F00F00DB
-:107C600000EB800105F1140000EB8100008A98B957
-:107C700039462846FEF7DDFF43E004F00F0000EB35
-:107C8000800105F5AA7000EB8100008A20B9394611
-:107C90002846FEF7CEFF34E004F08000802808D1AB
-:107CA00004F07F0000EB800105F1140000EB81007F
-:107CB00007E004F07F0000EB800105F5AA7000EBFF
-:107CC000810080460CB1802C03D10020C8F8000050
-:107CD0000CE021462846FFF7EDFB20B10120C8F853
-:107CE000000003E008E00020C8F80000022241463E
-:107CF0002846FEF7CBFF04E039462846FEF799FFF9
-:107D000000BF00BF04E039462846FEF792FF00BFDF
-:107D100000BF04E039462846FEF78BFF00BF00BFD6
-:107D20004846BDE8F0872DE9F04105460E4600279C
-:107D3000307800F0600030B1202802D0402840D1D7
-:107D400000E000BF00BF95F89C02012804D0022883
-:107D500003D003282ED101E000BF00BF30790128F5
-:107D600023D831792846FEF749FF0446FF2C14D06A
-:107D70009CB905F52E7050F82400806858B1C5F8FC
-:107D8000D44205F52E7050F824003146826828460A
-:107D90009047074602E0032700E00327F08840B938
-:107DA0003FB92846FEF783FF03E031462846FEF739
-:107DB00040FF04E031462846FEF73BFF00BF00BF0E
-:107DC00004E031462846FEF734FF00BF00BF3846C6
-:107DD000BDE8F0817047000001460148704700008F
-:107DE000780F012070B504460B4622461978587862
-:107DF00001282CD140F61C0080581D7805F00F0694
-:107E00000125B540ADB2284340F61C05A85002F547
-:107E1000106000EB4110006800F40040F0BB98894E
-:107E2000C0F30A001D7940EA854040EA815040F0E5
-:107E3000805040F4004002F5106505EB41152D68B7
-:107E4000284302F5106505EB411528602DE040F64A
-:107E50001C0080581D7805F00F060125B540144E12
-:107E600006EA0545284340F61C05A85002F5306097
-:107E700000EB4110006800F4004078B99889C0F325
-:107E80000A001D7940EA854040F0805040F40040EF
-:107E900002F5306505EB41152D6800E005E028434B
-:107EA00002F5306505EB41152860002070BD00002B
-:107EB0000000FFFF01460A464FF410608058C30AD5
-:107EC000DB024FF41060835040F60400805840F409
-:107ED000807340F604008350002070470FB470B5E3
-:107EE00004460A98012817D1A06B20F48030A063C3
-:107EF000E0681A490840E060E06820F44010E06063
-:107F00001198012803D1E06840F48010E060204619
-:107F100000F026F8054612E0E06840F04000E0601E
-:107F2000204600F01DF805460E9820B9A06B40F4DD
-:107F30008030A06303E0A06B20F48030A063089839
-:107F4000012807D1A06840F00600A060A06840F0BA
-:107F50002000A060284670BC5DF814FBBFFFBDFF89
-:107F600008B501460020009000BF0098401C00901A
-:107F7000104A0098904201D9032008BD086900F01A
-:107F800000400028F1D000200090086940F0010076
-:107F9000086100BF0098401C0090064A009890427B
-:107FA00001D90320E9E7086900F001000028F1D1B8
-:107FB00000BFE2E7400D030070B504460B462246C1
-:107FC00019785878012848D102F5106000EB41106B
-:107FD000006800F00040B0F1004F17D102F51060CA
-:107FE00000EB4110006840F0006502F5106000EB06
-:107FF0004110056002F5106000EB4110006840F090
-:10800000804502F5106000EB4110056040F63C0031
-:1080100080581D7805F00F060125B540ADB2A84384
-:1080200040F63C05A85040F61C0080581D7805F02D
-:108030000F060125B540ADB2A84340F61C05A85077
-:1080400002F5106000EB411000682B4D284002F54E
-:10805000106505EB411528604BE002F5306000EB40
-:108060004110006800F00040B0F1004F17D102F558
-:10807000306000EB4110006840F0006502F53060B0
-:1080800000EB4110056002F5306000EB4110006824
-:1080900040F0804502F5306000EB4110056040F68D
-:1080A0003C0080581D7805F00F060125B540134EA1
-:1080B00006EA0545A84340F63C05A85040F61C00DA
-:1080C0008558187800F00F060120B0400B4E06EAE4
-:1080D0000040854340F61C00855002F5306000EBFF
-:1080E00041100068064D284002F5306505EB41154A
-:1080F0002860002070BD0000007833EC0000FFFF16
-:108100000078F3EF01460A46D2F8000E20F0030093
-:10811000C2F8000E40F60400805820F0020340F63A
-:10812000040083500020704701460A46D2F8000E32
-:1081300020F00300C2F8000E40F60400805840F022
-:10814000020340F604008350002070470FB4F0B5DE
-:10815000054600272E46002405E0002105F5827023
-:1081600040F82410641C0F2CF7D31098A0B940F6E7
-:108170000400805940F0020140F604008151A86BD0
-:1081800040F40010A863A86B20F40020A863A86B3B
-:1081900020F48020A86307E0A86B20F40010A863F7
-:1081A000A86B40F40020A8630020C6F8000ED6F8A3
-:1081B0000008C6F800080B9801280BD1089820B9D0
-:1081C0000021284600F0BCFD08E00121284600F00F
-:1081D000B7FD03E00321284600F0B2FD1021284638
-:1081E00000F0B2FC00B10127284600F083FC00B18A
-:1081F000012700214FF401608151001D815140F69B
-:108200001C00815100242EE006F5106000EB4410A4
-:10821000006800F00040B0F1004F10D13CB94FF0C1
-:10822000006106F5106000EB441001600DE04FF0B6
-:10823000904106F5106000EB4410016005E000215C
-:1082400006F5106000EB44100160002106F5106097
-:1082500000EB441001614FF67F3106F5106000EB32
-:1082600044108160641C0698A042CDD800242EE002
-:1082700006F5306000EB4410006800F00040B0F1FB
-:10828000004F10D13CB94FF0006106F5306000EBB3
-:10829000441001600DE04FF0904106F5306000EBB6
-:1082A0004410016005E0002106F5306000EB441049
-:1082B0000160002106F5306000EB441001614FF6CB
-:1082C0007F3106F5306000EB44108160641C069835
-:1082D000A042CDD84FF40160805920F480714FF452
-:1082E000016081510020A8616FF0804068610998A9
-:1082F00018B9A86940F01000A861A86909490843A5
-:10830000A8610C9818B1A86940F00800A8611098FD
-:10831000012803D1A86904490843A8613846F0BC84
-:108320005DF814FB00383C8004000040014688687A
-:1083300020F001008860002070470000F0B505467D
-:108340000B4614462A4619785878012875D1986941
-:1083500020BB02F5106000EB411000696D4E30400B
-:1083600002F5106606EB4116306102F5106000EB75
-:108370004110006940F4002602F5106000EB411046
-:10838000066102F5106000EB41100069C60CF604AE
-:1083900002F5106000EB4110066137E002F5106055
-:1083A00000EB41100069C60CF60402F5106000EB0A
-:1083B0004110066102F5106000EB41100069554E56
-:1083C000304002F5106606EB41163061DE689869B0
-:1083D000B04201D9D868986102F5106000EB4110F5
-:1083E000006940F4002602F5106000EB41100661C0
-:1083F00002F5106000EB411000699E69C6F3120699
-:10840000304302F5106606EB41163061012C15D1A0
-:10841000586928B102F5106000EB41105E694661B1
-:1084200002F5106000EB4110006840F0044602F5D0
-:10843000106000EB411006606AE01BE002F510607E
-:1084400000EB4110006840F0044602F5106000EBBC
-:1084500041100660986900285AD040F634008058D0
-:108460001E7806F00F070126BE40304340F6340662
-:10847000B0504DE002F5306000EB41100069C60CD1
-:10848000F60402F5306000EB4110066102F5306041
-:1084900000EB411000691F4E304002F5306606EBDC
-:1084A00041163061986908B1D8689861D868D86178
-:1084B00002F5306000EB4110006940F4002602F53F
-:1084C000306000EB4110066102F5306000EB4110B6
-:1084D0000069DE69C6F31206304302F5306606EB2A
-:1084E00041163061012C07D1186928B102F53060BE
-:1084F00000EB41101E69466102F5306000EB41104F
-:10850000006840F0044602F5306000EB4110066060
-:108510000020F0BDFFFF07E070B503460C4619468A
-:108520001D6C1848854209D94FF43060405800F05E
-:108530000040B0F1004F01D1002070BD0026C1F80D
-:10854000106BD1F8100B40F40026C1F8106BD1F875
-:10855000100B40F01806C1F8106BD1F8100B40F06A
-:10856000C046C1F8106B012C09D1C1F8142B4FF48F
-:108570003060405840F080264FF430604650002074
-:10858000DBE700000A30544F30B504460B46224664
-:108590001978587801281ED102F5106000EB4110BF
-:1085A000006820F4001502F5106000EB4110056032
-:1085B0001879032802D0187902282AD102F5106010
-:1085C00000EB4110006840F0805502F5106000EBB0
-:1085D000411005601DE002F5306000EB41100068BD
-:1085E00020F4001502F5306000EB411005601879A9
-:1085F000032802D0187902280BD102F5306000EB75
-:108600004110006840F0805502F5306000EB4110E9
-:108610000560002030BD30B504460B46224619786F
-:108620005878012821D102F5106000EB4110006854
-:1086300000F0004060B959B102F5106000EB411044
-:10864000006820F0804502F5106000EB41100560E5
-:1086500002F5106000EB4110006840F4001502F5CF
-:10866000106000EB4110056020E002F5306000EB87
-:108670004110006800F0004060B959B102F5306067
-:1086800000EB4110006820F0804502F5306000EBFF
-:108690004110056002F5306000EB4110006840F4C5
-:1086A000001502F5306000EB41100560002030BD80
-:1086B0002DE9F84381460E4617464D4634787078CA
-:1086C00001287DD1B06920BB05F5106000EB441096
-:1086D0000069C849084005F5106101EB44110861C3
-:1086E00005F5106000EB4410006940F4002105F529
-:1086F000106000EB4410016105F5106000EB4410C0
-:108700000069C10CC90405F5106000EB441001615B
-:1087100055E005F5106000EB44100069C10CC90478
-:1087200005F5106000EB4410016105F5106000EBE9
-:1087300044100069AF49084005F5106101EB441190
-:108740000861F168B0690844401EB0FBF1F0A94926
-:10875000C94301EAC04005F5106101EB4411096904
-:10876000084305F5106101EB4411086105F510603F
-:1087700000EB44100069B169C1F31201084305F52B
-:10878000106101EB441108613079012817D105F51A
-:10879000106000EB4410006920F0C04105F5106046
-:1087A00000EB4410016105F5106000EB4410006916
-:1087B00040F0005105F5106000EB4410016100E04D
-:1087C0007FE0012F36D1706928B105F5106000EB0C
-:1087D000441071694161307901281ED140F60800CA
-:1087E000405900F4807060B905F5106000EB44104A
-:1087F000006840F0005105F5106000EB4410016086
-:108800000BE005F5106000EB4410006840F080516B
-:1088100005F5106000EB4410016005F5106000EBF9
-:108820004410006840F0044105F5106000EB44106E
-:108830000160DCE005F5106000EB4410006840F0DA
-:10884000044105F5106000EB441001603079012807
-:108850000FD0B0690028ECD040F634004059317890
-:1088600001F00F0201219140084340F634014851C4
-:10887000BDE040F60800405900F4807060B905F58D
-:10888000106000EB4410006840F0005105F51060E6
-:1088900000EB441001600BE005F5106000EB4410A4
-:1088A000006840F0805105F5106000EB4410016055
-:1088B0000097308B83B232784846316900F0BEFAB7
-:1088C00095E005F5306000EB44100069C10CC90467
-:1088D00005F5306000EB4410016105F5306000EBF8
-:1088E000441000694349084005F5306101EB44112B
-:1088F0000861B069D0B905F5306000EB441000693B
-:10890000F168C1F31201084305F5306101EB441130
-:10891000086105F5306000EB4410006940F4002167
-:1089200005F5306000EB4410016128E0F168B069A2
-:108930000844401EB0FBF1F01FFA80F8F06800FB1D
-:1089400008F0F06105F5306000EB4410006929493A
-:10895000C94301EAC841084305F5306101EB441100
-:10896000086105F5306000EB44100069F169C1F35E
-:108970001201084305F5306101EB44110861012F34
-:1089800007D1306928B105F5306000EB441031693A
-:108990004161307901281ED140F60800405900F4A9
-:1089A000807060B905F5306000EB4410006840F05D
-:1089B000005105F5306000EB441001600BE005F557
-:1089C000306000EB4410006840F0805105F53060E5
-:1089D00000EB4410016005F5306000EB44100068C6
-:1089E00040F0044105F5306000EB441001600020C8
-:1089F000BDE8F883FFFF07E078B503460024009444
-:108A000000201A464C78012C35D10C7802F51065FF
-:108A100005EB4414246804F00044B4F1004F60D125
-:108A20000C7805EB4414246844F000660C7805EBE0
-:108A3000441426600C7805EB4414246844F0804606
-:108A40000C7805EB4414266000BF009C641C009465
-:108A500042F21075009CAC4201D901200AE00C786A
-:108A600002F5106505EB4414246804F00044B4F1E9
-:108A7000004FEAD035E00C7802F5306505EB441480
-:108A8000246804F00044B4F1004F2AD10C7805EBBF
-:108A90004414246844F000660C7805EB4414266006
-:108AA0000C7805EB4414246844F080460C7805EB00
-:108AB0004414266000BF009C641C009442F21075B0
-:108AC000009CAC4201D901200AE00C7802F5306527
-:108AD00005EB4414246804F00044B4F1004FEAD0DC
-:108AE00000BF78BD0146886840F001008860002022
-:108AF0007047000008B501460020009000BF0098B4
-:108B0000401C00900F4A0098904201D9032008BDF4
-:108B1000086900F000400028F1D0002000901020EB
-:108B2000086100BF0098401C0090064A00989042DF
-:108B300001D90320EBE7086900F010001028F1D0FC
-:108B40000020E4E7400D030008B502460020009035
-:108B500000BF0098401C0090104B0098984201D92B
-:108B6000032008BD106900F000400028F1D000206B
-:108B70000090202040EA8110106100BF0098401C46
-:108B80000090064B0098984201D90320E9E710694C
-:108B900000F020002028F1D00020E2E7400D030083
-:108BA00010B501460B4640F60804E45804F00602EE
-:108BB0000AB9002006E0022A01D0062A01D10220CB
-:108BC00000E00F2010BD0146486900F00100704729
-:108BD00001460B4640F61800C258001DC05802401E
-:108BE00090B2704701460B4640F61800C258001D6F
-:108BF000C0580240100C704770B5024613464FF43F
-:108C00000166F45840F63406F55801F00F0625FACF
-:108C100006F606F0010644EAC61403F5106606EBF4
-:108C20004116B66806EA040070BD10B50246134648
-:108C300003F5306404EB4114A06840F61404E458D2
-:108C4000204010BD014648698A69104070472DE9EF
-:108C5000F04104460D46274628464FEA920C02F0A2
-:108C6000030300210AE04FF4805858F80780C0F849
-:108C70000080401C401C401C401C491C6145F2D334
-:108C80009BB100214FF4805858F8076000BF4FEAAD
-:108C9000C10826FA08F880F80080491C401CA3F19E
-:108CA00001081FFA88F3002BF1D1BDE8F08170B5FF
-:108CB00004460E460025E06820F0C040E060012E2A
-:108CC00010D1E06840F00050E06000BF0120F8F7EC
-:108CD0001FFA6D1C2046FFF776FF012815D0322DB4
-:108CE000F4D312E07EB9E06840F08040E06000BF5D
-:108CF0000120F8F70DFA6D1C2046FFF764FF20B144
-:108D0000322DF5D301E0012070BD322D01D10120BB
-:108D1000FAE70020F8E710B502460B461146D1F8F5
-:108D2000000820F4FE60C1F80008D1F800084FF4F4
-:108D3000FE6404EA03142043C1F80008002010BDBB
-:108D400002461346D3F800080843C3F80008002081
-:108D50007047000030B503461446022C49D12D4817
-:108D6000814204D32C48814201D20F2245E02A4897
-:108D7000814204D32948814201D20E223DE0274896
-:108D8000814204D32648814201D20D2235E0244895
-:108D9000814204D32348814201D20C222DE0214894
-:108DA000814204D32048814201D20B2225E01E4893
-:108DB000814204D31D48814201D20A221DE01B4892
-:108DC000814204D31A48814201D2092215E0184891
-:108DD000814204D31748814201D208220DE0154890
-:108DE000814204D31448814201D2072205E00622C1
-:108DF00003E00CB9092200E00922D86820F4705081
-:108E0000D860D8684FF4705505EA82252843D860A9
-:108E1000002030BDC0ACD800C0E1E4000024F40064
-:108E200080730601A0491A01002D310140A44C01B4
-:108E300000366E0120ABA6010048E8012DE9F043A1
-:108E400004460D461E46DDF81CC0A0462946BCF16E
-:108E5000000F12D1F01C870800230CE0D1F800901D
-:108E600008F5805000EB0230C0F80090491C491C06
-:108E7000491C491C5B1CBB42F0D30020BDE8F083B9
-:108E800000BFFEE70FB4084B10B504A902AA03986F
-:108E900000F046FC044602A9002001F061F92046DA
-:108EA00010BC5DF814FB000061A100087CB50C004B
-:108EB0001D461646014601D0601E00E00020CDE9A7
-:108EC0000010064B6A462946304600F029FC002C6B
-:108ED00002D0009A002111707CBD000069A000083A
-:108EE00002480068C0F30220704700000CED00E06B
-:108EF00010B5002804DB0A07130E054A135406E0D8
-:108F00000A07140E034A00F00F031B1FD45410BDB0
-:108F100000E400E018ED00E002E008C8121F08C1FC
-:108F2000002AFAD170477047002001E001C1121FEA
-:108F3000002AFBD170472DE9FC410446A089401E60
-:108F400080B200906089401E83B200221146204604
-:108F5000266FB0472068006A006800684FF6BF714E
-:108F600008402168096A096808602068006A00688A
-:108F7000006840F400602168096A09680860206898
-:108F8000006A0068006840F040002168096A0968CA
-:108F9000086020680169D1E90401CDE90001206879
-:108FA0000669F7683B4696E80700B847002508E0E1
-:108FB000608A2168096A0968C860206801F0E8F8D9
-:108FC0006D1C6089A1894843A842F1D8206801F04E
-:108FD000D6F820680169D1E90401CDE900012068D3
-:108FE0000669D6E902733A46D6E90001B847206817
-:108FF000006A006800684FF6BF7108402168096A7E
-:10900000096808602068006A006800684FF2FF7114
-:1090100008402168096A096808602068006A0068D9
-:10902000006840F040002168096A09680860BDE8EE
-:10903000FC8100002DE9FE4F0446884691461D46FE
-:109040000026B2460027B346A5F12000C5B220682D
-:109050000169D1E90401CDE900012068D0F810E0F0
-:10906000DEF80CC063469EE80700E04700BF33E02F
-:10907000A0690068A169098905FB0161405C029053
-:109080004FF0000A22E0029800F0010028B1A08A07
-:109090002249096821F8170004E0608A1F4909681D
-:1090A00021F81700029840100290781C87B20BF14B
-:1090B00001001FFA80FBA0698088584502D14FF05B
-:1090C000000B06E00AF101001FFA80FABAF1080F5E
-:1090D000D9DB00BF701C86B2A0690089B042C7DC32
-:1090E000A069C0884844401E80B20090A069808872
-:1090F0004044401E83B24A4641462046D4F870C0E0
-:10910000E047A0698088A169C988484382B20348C2
-:109110000168204601F045F8BDE8FE8F2C010020D3
-:109120002DE9FE4F0446884691461E46002500273D
-:109130000020029083461BE0E06902680089691CF8
-:109140004843105C317888420BD1E069028901689C
-:10915000681C00FB021040787178884201D1AA4651
-:1091600007E0A81C85B2E0694089A84200DC00E065
-:10917000E2E700BF0025002733E0E0690068E1690D
-:1091800009890AFB0100C05D01900020029022E0E5
-:10919000019800F0010028B1A08A2349096821F84C
-:1091A000150004E0608A2049096821F81500681C50
-:1091B00085B20198401001900BF101001FFA80FB6D
-:1091C000E0698088584502D14FF0000B06E0029814
-:1091D000401C80B2029002980828D9DB00BF781C9E
-:1091E00087B2E0690089B842C7DCE069C0884844BA
-:1091F000401E80B20090E06980884044401E83B2E7
-:109200004A4641462046D4F870C0E047E06980886D
-:10921000E169C988484382B203480168204600F0EA
-:10922000C0FFBDE8FE8F00002C0100202DE9F041B9
-:1092300005460E4617461C4619E020787F280BDCB1
-:1092400023783A4631462846FFF7F4FEA86980881D
-:10925000304486B2641C0AE023463A46314628462A
-:10926000FFF75EFFE8698088304486B2A41C20784E
-:109270000028E2D1BDE8F0812DE9FF5F82B0002136
-:10928000DDE90430020DDDF840B0034318D044F6A8
-:109290001050A2F2FF3242431514119801281FD03A
-:1092A000A5EB0B00401C5FEA000A4FF000064E4F92
-:1092B000DFF83891B046504615D5CAF1000413E0E6
-:1092C000119801244AA3012801D16FEA0B010298E9
-:1092D000119AC0E90031C0E9024206B0BDE8F09F32
-:1092E000CBF10000DFE704460021404A491842EB79
-:1092F0000450CDE9001012E0E00707D032463B46AB
-:1093000040464946F7F7DEF88046894632463B46F6
-:1093100010461946F7F7D6F806460F466410002C9B
-:10932000EAD1DDE90401DDE90023BAF1000F06DA34
-:10933000F7F7C8F842464B46F7F7C4F805E0F7F7E9
-:10934000D7F942464B46F7F7D3F904460E460022BA
-:10935000284BF7F755FA03D84FF0FF30014607E0E6
-:109360000022254B20463146F7F705F8F7F72FFA8C
-:10937000102409E0002C0ADB0A220023F6F782FF02
-:10938000039B30321A55641E50EA0102F2D1641C6C
-:10939000039AC4F111031444119A012A03D0012243
-:1093A00008430DD10AE0084304D000204FF0110B10
-:1093B000119072E7A3EB0B056D1E0DE05B4504DD1C
-:1093C0004FF0000205F1010504E003DA4FF000025E
-:1093D000A5F10105002AECD002981199C0E90231EB
-:1093E000C0E9004579E70000000014400000F03FAC
-:1093F000300000000000F0430000E03F30B50022E4
-:109400000023002401F478052A0A01F47C456B0945
-:10941000C1F3C40442EA03052543458230BD000080
-:10942000014601F1100000E0001D02681AB9024A6D
-:1094300012689042F8D370478400002070B504464B
-:109440000D460CB1012100E00021084640F2051153
-:10945000F7F710FB0DB1012100E0002108464FF4A1
-:109460008371F7F707FB002084F831002562206A3A
-:109470000068006840F04000216A0968086070BD1B
-:109480007CB504460A20F7F743FE4FF48055294681
-:10949000012001F097FA9749086008460068A06229
-:1094A00020680169D1E90401CDE90001206805695E
-:1094B000EE68334695E80700B0473621206800F093
-:1094C000E5FE0021206800F01BFF3A21206800F033
-:1094D000DDFE0521206800F013FFB221206800F0B6
-:1094E000D5FE0C21206800F00BFF0C21206800F055
-:1094F00007FF0021206800F003FF3321206800F0FF
-:10950000FFFE3321206800F0FBFEB721206800F049
-:10951000BDFE3521206800F0F3FEBB21206800F07D
-:10952000B5FE1921206800F0EBFEC021206800F094
-:10953000ADFE2C21206800F0E3FEC221206800F07F
-:10954000A5FE0121206800F0DBFEC321206800F0A9
-:109550009DFE1221206800F0D3FEC421206800F097
-:1095600095FE2021206800F0CBFEC621206800F087
-:109570008DFE0F21206800F0C3FED021206800F08E
-:1095800085FEA421206800F0BBFEA121206800F028
-:10959000B7FEE021206800F079FED021206800F0BD
-:1095A000AFFE0421206800F0ABFE0D21206800F022
-:1095B000A7FE1121206800F0A3FE1321206800F00F
-:1095C0009FFE2B21206800F09BFE3F21206800F0C9
-:1095D00097FE5421206800F093FE4C21206800F093
-:1095E0008FFE1821206800F08BFE0D21206800F00E
-:1095F00087FE0B21206800F083FE1F21206800F009
-:109600007FFE2321206800F07BFEE121206800F02E
-:109610003DFED021206800F073FE0421206800F098
-:109620006FFE0C21206800F06BFE1121206800F015
-:1096300067FE1321206800F063FE2C21206800F0F3
-:109640005FFE3F21206800F05BFE4421206800F0AF
-:1096500057FE5121206800F053FE2F21206800F0B2
-:109660004FFE1F21206800F04BFE1F21206800F0F4
-:1096700047FE2021206800F043FE2321206800F0EF
-:109680003FFE2121206800F001FE1121206800F03A
-:10969000FDFD7820F7F73CFD2921206800F0F6FD5C
-:1096A000206800F06CFD20680169D1E90401CDE972
-:1096B000000120680569D5E902633246D5E9000159
-:1096C000B04702212046E26D904700212046E26E1D
-:1096D00090476FF07F412046226E90472046616F91
-:1096E0008847842002590449204690470020A075ED
-:1096F0007CBD00002C010020FC00002010B50648B5
-:10970000046803E02046FFF78BFE04460348006828
-:109710008442F7D310BD00008000002084000020A8
-:109720002DE9FF4F95B09A46884606460025EEE1A2
-:10973000252877D100242746F94A0121039400E027
-:10974000044316F8013F203B01FA03F01042F7D121
-:1097500030782A2811D06FF02F033078A0F1300232
-:10976000092A16D8039A44F0020402EB820203EBA2
-:1097700042021044761C0390EFE758F8042B039242
-:10978000002A03DA504244F40054039044F00204E7
-:10979000761C30782E2816D116F8010F44F00404F8
-:1097A0002A280DD06FF02F023078A0F13003092B5A
-:1097B00009D807EB870302EB4303C718761CF3E7CE
-:1097C00058F8047B761C30786C280FD006DC4C28C7
-:1097D00017D068280DD06A2814D104E0742810D05E
-:1097E0007A280FD10DE044F400140AE044F4801408
-:1097F00001E044F440147278824202D104F58014EE
-:10980000761C761C307866280BD013DC582877D06D
-:1098100009DC002875D04528F6D04628F4D0472822
-:109820001AD193E118E0632835D0642879D06528EF
-:1098300012D18BE1702873D008DC6728F1D0692839
-:109840006FD06E280DD06F2806D1ACE073282CD0D5
-:10985000752874D0782853D05246179990476D1CBC
-:1098600054E1C4F30250022809D003280DD0D8F8DF
-:10987000001004280DD00D6008F1040846E1D8F866
-:109880000010EA17C1E90052F6E7D8F800100D8081
-:10989000F2E70D70F0E718F8041B8DF800100020B7
-:1098A0008DF80100EB46012003E058F804BB4FF0AF
-:1098B000FF3061074FF0000102D40DE009F1010112
-:1098C0008946B9420FDA8145F8DB1BF809100029F7
-:1098D000F4D108E009F1010189468142FADB1BF865
-:1098E00009100029F6D103985346A0EB0907214639
-:1098F0003846179A00F080FA284400EB090507E083
-:1099000044E008E10DE01BF8010B5246179990471F
-:10991000B9F10109F7D2534621463846179AF2E0C9
-:1099200039E00A21C4F302524FF0000B0091022AE1
-:1099300006D058F8040BC117032A09D00AE023E027
-:1099400008F1070020F00702F2E80201904605E066
-:1099500000B2C117042A01D140B2C117002906DAAA
-:109960000A460021404261EB02012D2202E022055D
-:1099700004D52B228DF80420012203E0E20701D058
-:109980002022F7E7914657E00A2100E010214FF02E
-:10999000000B00910BE010214FF0000B44F0040489
-:1099A0000827009103E008204FF0000B0090C4F35B
-:1099B0000252022A05D058F8040B0021032A08D0CD
-:1099C00008E008F1070020F00702F2E802019046E3
-:1099D00003E080B2042A00D1C0B24FF00009220790
-:1099E0002AD53278702A07D0DDF800C08CF0100C30
-:1099F0005CEA0B0C05D00EE040228DF80420012219
-:109A000008E050EA010306D030238DF804308DF8C9
-:109A1000052002229146009B83F0080353EA0B03C2
-:109A20000AD150EA010201D1620705D530228DF832
-:109A300004204FF001097F1E3278582A04D039A241
-:109A40000C920CAA02920BE03BA2F9E75B46009A4B
-:109A5000F6F718FC0C9B9B5C029A521E0292137044
-:109A600050EA0102F2D1029804A9081A00F1200B71
-:109A7000600702D524F4803400E001275F4502DD51
-:109A8000A7EB0B0000E0002000EB0B010090039817
-:109A90004944401A0390E00306D453462146179ADE
-:109AA000039800F0A9F90544002706E001A85246F2
-:109AB000C05D179990476D1C7F1C4F45F6DBE00396
-:109AC0000CD553462146179A039800F095F90544A2
-:109AD00004E030205246179990476D1C0099481EAB
-:109AE00000900029F5DC08E00298029952460078BF
-:109AF000491C0291179990476D1CBBF10001ABF115
-:109B0000010BF1DC5BE100F065F90544761C30786F
-:109B100000287FF40DAE19B02846BDE8F08F000094
-:109B20000928010030313233343536373839616233
-:109B300063646566000000003031323334353637F7
-:109B4000383941424344454600000000600700D4D4
-:109B5000062708F1070020F00700F0E802238046FE
-:109B600003F0004C5FEA0C0001D097A009E020054B
-:109B700001D596A005E0E00701D095A001E0AFF285
-:109B80004C001390307823F0004365280CD006DC9D
-:109B9000452809D046281DD047287FD13BE06628BC
-:109BA00018D067287AD136E00021112F01DB11206F
-:109BB00000E0781CCDE9000104A90CA8FFF75CFBCC
-:109BC000DDE90D010C9A4FF0000B07F1010910922D
-:109BD00000914EE04FF000400097CDE9011004A93C
-:109BE0000CA8FFF749FBDDE90D020C9B0F994FF024
-:109BF000000B91461093009211B9791C00EB0109FA
-:109C0000B7EB090003D4C0F1FF3B07F10109A9EB51
-:109C10000700019042E0012F00DA01270021112FF7
-:109C200001DD112000E03846CDE9000104A90CA8AF
-:109C3000FFF722FBDDE90D010C9A00914FF0000BBC
-:109C4000B946109221070FD4009A4A4503DA91468B
-:109C500001E0A9F10109B9F1010F05DD109AA9F19F
-:109C60000101515C3029F4D0B84202DA10F1040F3E
-:109C700003DA0121CDE9011010E0002803DC834460
-:109C8000A9EB000102E0411C494500DD8946A0EB3B
-:109C90000B00401C01904FF000400290200705D4BB
-:109CA0000198484502DB4FF0FF30019000208DF80D
-:109CB0004B0002980DF14B07B0F1004F25D0022068
-:109CC0000C902B200D90029800280CDA4042029054
-:109CD0002D200D9007E00A210298F6F765FC30313F
-:109CE000029007F8011D0C99481E0C900029F2DC27
-:109CF00002980028EFD1791E0D980870307800F096
-:109D0000200040F0450007F8020D11A8C01BC01D3F
-:109D100002901398007800B1012000EB090101982E
-:109D200001EBE071029801440398401A401E039031
-:109D3000E00306D453462146179A039800F05CF8D6
-:109D400005441398007818B15246179990476D1C36
-:109D5000E00323D553462146179A039800F04CF8A8
-:109D600005441BE0BBF1000F07DB0098584504DDFC
-:109D70001098179910F80B0001E0179930205246FF
-:109D8000904701980BF1010B401E05F10105019070
-:109D900004D12E205246179990476D1CB9F100014D
-:109DA000A9F10109DEDC05E017F8010B524617990D
-:109DB00090476D1C0299481E02900029F4DC53461E
-:109DC0002146179A03989EE62D0000002B00000004
-:109DD000200000002DE9F041044600251E461746EC
-:109DE000880404D405E039462020B0476D1C641E69
-:109DF000F9D52846BDE8F0812DE9F041044600255B
-:109E00001E469046C80301D5302700E0202788046D
-:109E100004D505E041463846B0476D1C641EF9D5AF
-:109E20002846BDE8F0810FB410B5BDF80C100298BB
-:109E3000F7F77CFA012802D110BC5DF814FB002072
-:109E4000FAE70FB410B5BDF80C1000220298F7F72E
-:109E50007FFA10BC5DF814FB0FB410B5BDF80C1000
-:109E600001220298F7F774FA10BC5DF814FB2DE993
-:109E7000FC4704460D4616461F46DDF8288020683C
-:109E80000169D1E90401CDE900012068D0F810C0D2
-:109E9000DCF80C904B469CE80700C8472A21206854
-:109EA00000F0F4F9E2892A4491B2206800F017FA30
-:109EB000E2893A4491B2206800F011FA2B2120681F
-:109EC00000F0E4F9228A324491B2206800F007FAE7
-:109ED000228A424491B2206800F001FA2C212068C5
-:109EE00000F0D4F9206800F04AF920680169D1E94E
-:109EF0000401CDE900012068D0F810C0DCE902932C
-:109F00004A46DCE90001C847BDE8FC87816170472B
-:109F100030B500220023002401F478052A0A01F458
-:109F20007C456B09C1F3C40442EA030525438582DD
-:109F300030BD2DE9FC4104460D46257220680169BB
-:109F4000D1E90401CDE9000120680669F7683B46C4
-:109F500096E80700B8475DB93621206800F096F909
-:109F60007021206800F0CCF90020E08120822AE0F6
-:109F7000022D0BD13621206800F088F900212068DD
-:109F800000F0BEF90020E08120821CE0012D0CD100
-:109F90003621206800F07AF9A021206800F0B0F99D
-:109FA0005020E081002020820DE0032D0BD13621CE
-:109FB000206800F06BF9C021206800F0A1F90020B2
-:109FC000E08150202082206800F0D9F820680169E3
-:109FD000D1E90401CDE9000120680669D6E90273E0
-:109FE0003A46D6E90001B847BDE8FC8170B50446A1
-:109FF0000D46E561A888142816D004DC0C2807D08B
-:10A00000102823D10AE0182814D020281ED117E0E8
-:10A01000842002590F492046904718E084200259B5
-:10A020000D492046904712E0842002590B492046F2
-:10A0300090470CE08420025909492046904706E0E9
-:10A040008420025907492046904700E000BF00BF26
-:10A0500070BD000020010020140100200801002034
-:10A06000FC000020F00000204A68002A06D00A68A0
-:10A07000531C0B6010704868401E486070472DE903
-:10A08000FC4105460E4600270DB1012100E00021EC
-:10A090000846DD21F6F7EEFC2C460CB1012100E06C
-:10A0A000002108463621F6F7E5FCA06960B1A169F8
-:10A0B000D1E90401CDE90001D4F818C0DCF80C8026
-:10A0C00043469CE80700C04700BF284602F0AAFEAE
-:10A0D0003146284602F0D7FE0746284602F086FEA3
-:10A0E0003846BDE8FC812DE9FC4705460E4617467B
-:10A0F0004FF000080DB1012100E000210846F021D9
-:10A10000F6F7B8FC2C460CB1012100E0002108460E
-:10A110002821F6F7AFFCA06960B1A169D1E904017B
-:10A12000CDE90001D4F818C0DCE902934A46DCE925
-:10A130000001C84700BF284602F074FE002407E073
-:10A140003178284602F09FFE8046761C601C84B25F
-:10A15000BC42F5DB284602F049FE4046BDE8FC87DC
-:10A160000A68531C0B60107070470FB410B5BDF82F
-:10A170000C100298F7F7E2F810BC5DF814FB00BF72
-:10A18000016A0968896801F080010029F8D17047E7
-:10A1900000BF016A0968896801F002010029F8D04E
-:10A1A00070472DE9FC4104460E4617462068006AB8
-:10A1B000006800684FF6BF7108402168096A0968A5
-:10A1C00008602068006A0068006840F40060216848
-:10A1D000096A096808602068006A0068006840F041
-:10A1E00040002168096A0968086020680169D1E9AE
-:10A1F0000401CDE900012068D0F810C0DCF80C8023
-:10A2000043469CE80700C047002509E036F81500E2
-:10A210002168096A0968C8602068FFF7B9FF6D1CEA
-:10A22000BD42F3D32068FFF7AAFF20680169D1E996
-:10A230000401CDE900012068D0F810C0DCE90283F8
-:10A240004246DCE90001C0472068006A00680068F7
-:10A250004FF6BF7108402168096A096808602068E4
-:10A26000006A006800684FF2FF7108402168096ABF
-:10A27000096808602068006A0068006840F04000D3
-:10A280002168096A09680860BDE8FC812DE9FC4184
-:10A2900004460D462046FFF772FFE169D1E904014B
-:10A2A000CDE90001E669F7683B4696E80700B84744
-:10A2B000206A0068C5602046FFF76AFF2046FFF766
-:10A2C0005EFFE169D1E90401CDE90001E669D6E963
-:10A2D00002733A46D6E90001B847BDE8FC8170B583
-:10A2E00004460D462812216A0968C8602046FFF717
-:10A2F0004FFF206A0068C5602046FFF749FF70BD28
-:10A3000070B504460D46206A0068C5602046FFF718
-:10A310003FFF70BD1CB502F0BDFE054801210023C2
-:10A320008A02CDE9001003A1064803F03DFF1CBDE1
-:10A330007C000020627573696E6573735F7461736E
-:10A340006B00000059A3000810B500F0BBF801F045
-:10A3500025F801F0EFF810BD00BF01F0A5F800F0FE
-:10A3600039F9002000F000FA4FF47A7003F06CF82D
-:10A37000F3E7F0B503460024012901D0022904D1F6
-:10A3800001F10C00C1B2581E83B24D1C05EB45050E
-:10A39000052695FBF6F5022606FB012635441D44ED
-:10A3A0001846DE1703EB967605EBA605642693FBAD
-:10A3B000F6F6AD1B4FF4C87693FBF6F63544072648
-:10A3C00095FBF6F706FB1755ECB2601CC0B2F0BD6A
-:10A3D0002DE9F04105460E4618273946002000F0C9
-:10A3E000F1FA04460CB1012100E0002108463621B3
-:10A3F000F6F740FB2560A6800548A0600548E060B0
-:10A4000005482061054860612046BDE8F0810000F4
-:10A41000599E0008439E00086BA10008279E000873
-:10A4200000BFEFF3058008B1012070470020FCE772
-:10A430000FB470B598252946002000F0C3FA0446F1
-:10A440000CB1012100E0002108461C21F6F712FBA7
-:10A45000204604A9382203E011F8013B00F8013B33
-:10A46000131EA2F10105AAB2F6D100BF012184F8A2
-:10A470009410022020B1012803D0022807D101E066
-:10A480000CE00BE004F1380000F03EF906E0204655
-:10A4900000F007F8002070BC5DF814FB00BF2046F8
-:10A4A000F9E710B504460CB1012100E0002108468F
-:10A4B0001421F6F7DFFA00BF2146002000F058FA19
-:10A4C00000BF10BD30B5ADB04FF400613D48FFF79F
-:10A4D0007FFF29904FF480513A48FFF779FF2C9085
-:10A4E0003822394918A8F5F7FEFE0020049029A863
-:10A4F0000FC88DE80F00012026A90EC902F034FC18
-:10A50000189018983149C26A9047232218A90AA8BE
-:10A51000F5F7E9FE9DF883008DF84B00142221A980
-:10A5200013A8F5F7E0FE28220EA96846F5F7DBFE32
-:10A530000AA80FC8FFF77CFF25490861096909B11E
-:10A54000012100E0002108464FF48771F6F792FAE6
-:10A550001F4800690068C169D1E90401CDE9000123
-:10A560001B4800690068C469194800690068C0692F
-:10A57000856894E80F00A8471548006900680169DC
-:10A58000D1E90401CDE900011148006900680469BE
-:10A590000F48006900680069856894E80F00A847C3
-:10A5A00000224FF400510748F6F7D2FE084A10691E
-:10A5B0001269916B8847012251030248F6F7C8FEE1
-:10A5C0002DB030BD000C0240A8E700085006002066
-:10A5D000E444002030B5A5B0802105A8F5F79CFE25
-:10A5E000334908690969D1F88820324990473049D0
-:10A5F00008690969CA6E002190472D4908690969EF
-:10A600000A6E6FF07F41904746242949086909691D
-:10A610000A6E2949904726490869096927A32246F5
-:10A620008D6E0D21A8472249086909690A6E2749DC
-:10A6300090471F490969C969C98821448AB21C49E0
-:10A640000869096922A38D6E0D21A8471849086978
-:10A6500009690A6E23499047154908690969D1F8C3
-:10A660008420214990471248007B1149C97A104A39
-:10A67000927A0F4BDB79CDE90032CDE902100C481C
-:10A680008379808800F5FA6218A105A8FEF7FAFB25
-:10A6900007490969C969C98804EB41018AB20449BB
-:10A6A0000869096905AB8D6E0D21A84725B030BD3D
-:10A6B000E4440020D8000020FF80800053544D3334
-:10A6C0003220525443B2E2CAD400000080FFFF009F
-:10A6D000C6C1C4BBB7D6B1E6C2CA3A3234302A3298
-:10A6E000343000008080FF000801002025642D2503
-:10A6F0003032642D2530326420253032643A2530E2
-:10A7000032643A253032640010B504460CB10121A0
-:10A7100000E00021084640F2AF11F6F7ABF9094816
-:10A720002060094860620948A0620948A06309489E
-:10A73000E06409482065094820630948E063094846
-:10A74000606310BD81940008339F0008119F0008CA
-:10A750006F9E00080D9F0008ED9F00082D920008D5
-:10A76000378F0008FD93000810B504462CB94FF44C
-:10A7700000510348F6F7E2FD00E000BF00BF10BD46
-:10A7800000080240F6F7FCFDFBF728FAF9F790FE07
-:10A79000F9F738FEF9F7A4FFF9F7BCFFF9F766FE01
-:10A7A000F9F7DCFFF9F7B8FF002000F04BF80120C3
-:10A7B00000F048F8FFF7C8FDFFF7ACFDF9F764FEBD
-:10A7C00000F033F900BFFEE701460020842901D0E4
-:10A7D000CA1C1044704700002DE9F04104460E46A3
-:10A7E0001548005D38B91448183801682046884774
-:10A7F0000120BDE8F081114850F82400B04219D979
-:10A800000F4850F82400B6FBF0F70B48083850F812
-:10A81000240030F81780002508E000210648083899
-:10A8200050F824007A1920F812106D1C4545F4DB0D
-:10A830000020DEE70120DCE7A000002008E8000897
-:10A8400000E8000810B504460C4951F824104A00ED
-:10A850000B4951F82400002100F0C8F8094951F8CB
-:10A8600024200749083951F82400002100F0BEF8DF
-:10A87000012103480830015510BD0000F8E7000829
-:10A880009800002008E800082DE9F04704460F462C
-:10A890000025A9462348005D20B9224818380168E0
-:10A8A000204688471FB94FF0FF30BDE8F0871E48AB
-:10A8B00050F82400B7FBF0F61B4850F82400B7FB13
-:10A8C000F0F100FB117000B1761C184850F824001C
-:10A8D000451E22E01348083850F8240030F81500CF
-:10A8E00010B909F1010901E04FF00009B14513D198
-:10A8F0004FF0000809E00B48083850F8240005EB39
-:10A90000080220F8126008F10108B045F3D30648A8
-:10A9100050F824006843C8E76D1E002DDADA4FF0C6
-:10A92000FF30C2E7A000002000E80008F8E70008B8
-:10A9300010B501460023002207E00B4850F8210023
-:10A9400030F8120000B15B1C521C084850F821007E
-:10A950009042F2D864205843044C54F82140B0FB94
-:10A96000F4F0C0B210BD000098000020F8E7000825
-:10A970002DE9F04104460D460DB9BDE8F0810F48C0
-:10A9800050F824002E1A0E4850F82400B6FBF0F1BF
-:10A990000A48083050F8240030F81100084951F8EE
-:10A9A000241000FB01F73A460021284600F01EF86B
-:10A9B00031462046FFF710FF00BFDEE79000002081
-:10A9C00000E8000870B504460E4631462046FFF701
-:10A9D0005BFF0546681C08B9002070BD024850F8AE
-:10A9E00024002844F9E700009000002030B5034619
-:10A9F00001E003F8011B141EA2F10102F9D130BDE0
-:10AA000070B5044625460DB1294600E001210846EF
-:10AA100002F01AFD002070BD10B503F055FC0128AE
-:10AA200001D1002010BD0120FCE710B502F0DAFDD5
-:10AA3000002010BD10B5FFF7F3FC10B103F05AFC75
-:10AA400010BD03F051FCFBE7F8B504460D46A068C5
-:10AA500040B1E06830B10020009094E80F0002F0AF
-:10AA600059FFF8BD0022D4E9000102F026FFF8E703
-:10AA70002DE9FF4107460D4614460295002001903E
-:10AA80003DB9802000909DE8070087E80700BDE8F9
-:10AA9000FF81002003900026601C08B9761E03E0A9
-:10AAA00014B1264606B90126FFF7BAFCB0B103AAD5
-:10AAB00001A9284603F0F0F9012802D110200090E6
-:10AAC00001E0002000900398B8B14FF080500E498B
-:10AAD0000860BFF34F8FBFF36F8F0EE0324601A9BE
-:10AAE000284603F025F9012802D11020009004E047
-:10AAF0000EB9002000E0402000909DE8070087E8A4
-:10AB0000070000BFC3E7000004ED00E077B581B0A7
-:10AB10000646144600200090254605B90125FFF79A
-:10AB20007FFCA8B100236A4602A9304603F082F8F0
-:10AB3000012802D0FF2004B070BD009890B14FF002
-:10AB4000805009490860BFF34F8FBFF36F8F09E052
-:10AB500000232A4602A9304602F098FF012801D0BE
-:10AB6000FF20E8E70020E6E704ED00E07FB50446BB
-:10AB70000D46606998B1A06988B1B4F90800FFF783
-:10AB800023FE0646D4E90510CDE9006102902B466C
-:10AB90002269D4E9001003F039FB039013E0B4F903
-:10ABA0000800FFF711FE064603A8CDE90060238ADE
-:10ABB0009AB22B46D4E9001003F0F6FA012802D02D
-:10ABC000002004B070BD0398FBE700002DE9F041C0
-:10ABD00005460E461C4807681C480068001D02F028
-:10ABE000F3FA50B91948006890F82C1001208840F9
-:10ABF00017490968814316480160681C38B936B1A5
-:10AC000012480168091D134802F028FB1AE07C195C
-:10AC10000E4800684460BC4207D20C480168091D18
-:10AC20000D48006802F000FB0CE008480168091DAF
-:10AC30000A48006802F0F8FA09480068844201D224
-:10AC400007480460BDE8F0812800002014000020BF
-:10AC50002C000020D00800201C000020180000203C
-:10AC60004400002010B5044602F004FB23480068AD
-:10AC7000401C224908602248006840B9204804600E
-:10AC80000846006801280DD100F0BEF90AE01D4811
-:10AC9000006838B91A480068C06AE16A884201D879
-:10ACA0001748046018480068401C1749086094F869
-:10ACB0002C10012088401549096808431349086091
-:10ACC000E16A01EB8101124A02EB8100211D02F0D1
-:10ACD000C5FA02F0F9FA0B48006868B10848006844
-:10ACE000C06AE16A884207D24FF080500949086083
-:10ACF000BFF34F8FBFF36F8F10BD00002400002003
-:10AD00001400002030000020400000202C00002013
-:10AD1000F407002004ED00E010B516E002F0AAFAF6
-:10AD20000C48C068C468201D02F04EFA0A4800684A
-:10AD3000401E0949086009480068401E074908602C
-:10AD400002F0C2FA204600F05FF8044800680028CC
-:10AD5000E4D110BDBC080020240000202000002009
-:10AD600070B504460D46206C70B1216CE06801445A
-:10AD7000E160D4E90210884201D32168E1602846ED
-:10AD8000226CE168F5F7AFFA70BD2DE9F041044699
-:10AD90000F4615464FF00008A66B206C48B9206896
-:10ADA00000282CD1A06803F053FB80460020A0604F
-:10ADB00025E07DB93946226C6068F5F794FA216C7C
-:10ADC000606808446060D4E90101884217D32068B4
-:10ADD000606014E03946226CE068F5F784FA216C73
-:10ADE000E068411AE1602168E068884203D2216C82
-:10ADF000A068411AE160022D01D106B1761E701CD7
-:10AE0000A0634046BDE8F08110B5044694F85100B7
-:10AE100030B9206B02F076FA204602F073FA1AE09D
-:10AE200094F85100012803D1204602F06BFA12E099
-:10AE300094F85100022801D1012000E0002050B90F
-:10AE400000BF502080F31188BFF34F8FBFF36F8F87
-:10AE500000BF00BFFEE710BD01464A6A22B10A6B7F
-:10AE60001268C2F1070000E00020704730B54FF4CF
-:10AE70007053174800F007042CB1C01D20F00700E4
-:10AE8000134C041B1B1B0246124C22600024114D64
-:10AE90006C60D018083820F007000F4C20600024A8
-:10AEA0000D4D2D686C600C4D2D682C601146441AB8
-:10AEB0004C60094C24680C60084D4C682C60084DAF
-:10AEC0004C682C604FF00044064D2C6030BD0000F3
-:10AED000E4080020500000205800002060000020FE
-:10AEE0005C0000206C00002000BFFFF715FF064843
-:10AEF00000680128F9D94FF0805004490860BFF379
-:10AF00004F8FBFF36F8FF0E7F407002004ED00E0F0
-:10AF100010B5044654B10020A06020600021E1601B
-:10AF200000231A461946204602F0B0FD10BD2DE957
-:10AF3000F04106460D4617469846069C0DB924601A
-:10AF400000E02760E66325640121204602F052FDFF
-:10AF5000BDE8F0812DE9FF5F81460E469246DDE9AE
-:10AF60000E7B109CAAF10100216B01EB800828F0F8
-:10AF7000070808F0070008B9012000E0002050B9D8
-:10AF800000BF502080F31188BFF34F8FBFF36F8F46
-:10AF900000BF00BFFEE786B1002507E0715D04F148
-:10AFA00034004155705D00B902E06D1C102DF5D3E1
-:10AFB00000BF00214320015502E0002084F8340046
-:10AFC000072F00D30627E76267640020A064201DD6
-:10AFD00002F027F904F1180002F023F92461C7F107
-:10AFE0000700A06164620020E06484F850004946D4
-:10AFF0004046039A00F0BCF92060BBF1000F01D07D
-:10B00000CBF80040BDE8FF9F10B5002407E004EB3B
-:10B0100084010F4A02EB810002F0F6F8641C072C51
-:10B02000F5D30C4802F0F0F80B4802F0EDF80B48AD
-:10B0300002F0EAF80A4802F0E7F80A4802F0E4F8F9
-:10B0400004480949086004480849086010BD000028
-:10B05000F40700208008002094080020A8080020A1
-:10B06000BC080020D0080020180000201C00002090
-:10B0700010B50146164800E0006803688B42FBD318
-:10B080000246436813448B4204D143684C6823440E
-:10B09000436001460A464B6813440468A34211D139
-:10B0A0000C4C03682468A34208D04B6804686468A9
-:10B0B00023444B6003681B680B6005E0054B1B686D
-:10B0C0000B6001E003680B60884200D0016010BD96
-:10B0D000500000205800002070B5054602F0CAF864
-:10B0E000A86B08B9012400E0002402F0EDF8204626
-:10B0F00070BD70B5054602F0BDF8A86BE96B8842DB
-:10B1000001D1012400E0002402F0DEF8204670BDE9
-:10B110000A490968096809B9012100E0002121B143
-:10B120004FF0FF31064A116006E004490968C9681A
-:10B13000C868034A41681160704700001800002089
-:10B14000440000200E480068401C08B9012000E0BF
-:10B15000002050B900BF502080F31188BFF34F8FFB
-:10B16000BFF36F8F00BF00BFFEE700BF502080F32A
-:10B170001188BFF34F8FBFF36F8F00BF00BFFEE793
-:10B180007000002070B5044602F074F894F9455040
-:10B1900010E0606A08B9012000E0002038B904F12D
-:10B1A000240003F015FA18B102F088F900E003E07A
-:10B1B000681E45B2002DECDC00BFFF2084F845007E
-:10B1C00002F082F802F056F894F9445010E0206939
-:10B1D00008B9012000E0002048B904F1100003F094
-:10B1E000F7F908B102F06AF9681E45B200E001E023
-:10B1F000002DECDC00BFFF2084F8440002F064F86E
-:10B2000070BD00002DE9F04104464FF0000802F047
-:10B2100041FA4948006808B9FFF728FE4748006826
-:10B220002040002870D1D4B1083404F00700B0B138
-:10B2300004F00700C0F10800044404F0070008B956
-:10B24000012000E0002050B900BF502080F3118899
-:10B25000BFF34F8FBFF36F8F00BF00BFFEE7002C1F
-:10B2600052D03748006884424ED8364E3046056882
-:10B2700001E02E462D686868A04202D228680028A6
-:10B28000F7D12D48006885423ED0306800F10808AB
-:10B29000286830606868001B102819D92F1907F03A
-:10B2A000070008B9012000E0002050B900BF50207D
-:10B2B00080F31188BFF34F8FBFF36F8F00BF00BFC4
-:10B2C000FEE76868001B78606C603846FFF7D0FEC8
-:10B2D0001B4968680968081A194908600846006827
-:10B2E00019490968884203D2154800681649086060
-:10B2F000124968680968084368600020286013489C
-:10B300000068401C1149086003F0AEF908F007001E
-:10B3100008B9012000E0002050B900BF502080F3A0
-:10B320001188BFF34F8FBFF36F8F00BF00BFFEE7E1
-:10B330004046BDE8F0810000580000206C0000206D
-:10B340005C0000205000002060000020640000200D
-:10B350000648006830B10549096801F14800896C68
-:10B36000491C01600148006870470000140000207B
-:10B37000001F4FF080730360001F21F00103036082
-:10B38000001F054B036014380260001F6FF00203BA
-:10B39000036020387047000045B100083EB5002426
-:10B3A000002000F035F884B245F2500084422CD0E1
-:10B3B000401C844229D01920ADF8040001208DF8EA
-:10B3C00006008DF807009DF807209DF80610BDF8CF
-:10B3D000043003F5FA6398B2FEF7CBFF8DF808004E
-:10B3E00000208DF800008DF801008DF8020000218A
-:10B3F000009800F037F8DDE9010100F013F845F29C
-:10B400005101002000F07AF800BF01203EBD00008D
-:10B4100001460022024800EB8102106870470000DC
-:10B420005028004003B581B09DF806008DF801005A
-:10B430009DF807008DF80200BDF80400C0B28DF839
-:10B4400003009DF808008DF80000002269460448BA
-:10B45000F7F7DCFC08B901200EBD0020FCE7000076
-:10B46000EC04002013B586B00C469DF818008DF84A
-:10B4700004009DF819008DF805009DF81A008DF85C
-:10B4800006008DF80740002004900590002201A9D5
-:10B490000448F7F71BFD10B9012008B010BD0020CB
-:10B4A000FBE70000EC04002000B587B0002201A9F2
-:10B4B0001048F7F70DFC002206A90E48F7F7E2FB4B
-:10B4C0009DF804000C4988729DF805100A48C17265
-:10B4D0009DF8061001739DF8181001729DF819105F
-:10B4E00081719DF81A10C1719DF81B000249888076
-:10B4F00007B000BDEC040020E444002070B5044611
-:10B500000D46F6F727FF2A4621460248F7F7B0FB1B
-:10B5100070BD0000EC04002010B588B069460448F6
-:10B52000F7F7B2FE04460CB108B010BD00BFFBE750
-:10B53000F844002010B50E480E490860002048600D
-:10B5400000210C488160C160016141610421816179
-:10B55000F7F7BFFE08B1F5F73DFB4FF40061054872
-:10B56000F7F748FD08B1F5F735FBFFF7D5FF10BD3C
-:10B57000002C0140F84400200146002009E0074A61
-:10B5800052F820201AB9054A42F820107047421C90
-:10B5900010B20528F3DB00BFF8E700009811012086
-:10B5A00010B504460121204600F075F810BD0000DA
-:10B5B00010B50446226891682069F4F7BFFE60B9AF
-:10B5C00094F8600020F00100401C84F860000848F6
-:10B5D0000168204601F066FB04E00548416B204607
-:10B5E00001F060FB0020A0810021E18110BD00007E
-:10B5F000240200200246087858B1487800F00F0075
-:10B60000082806D0106878B1087813681B781840AD
-:10B6100050B192F8600000F0010018B94878C0F30A
-:10B62000001008B1002070474FF0FF30FBE700002A
-:10B6300010B500F01BFB044624B10348816B204683
-:10B6400001F030FB10BD00002402002070B504465C
-:10B65000A189E089081A05B205E02021204601F001
-:10B660003BFA681E05B2002DF7DC217B204600F076
-:10B670007FF870BD10B500F0F9FA044614B1204609
-:10B6800000F054FD10BD10B504464FF0FF312046C8
-:10B6900000F001F810BD2DE9F04104460D46681C8C
-:10B6A00008B9012000E000200746E08908B9012D13
-:10B6B00005D0E089A189884203D1681C08B9BDE89A
-:10B6C000F081E089A189884210D1012D0ED1E08955
-:10B6D000401EE081A089401EA0810021A28920692E
-:10B6E00081540121204600F043F83FE038460AE04B
-:10B6F000E18901442269525CE1890144491E2369C0
-:10B700005A54411C08B2A289E189511A8142EFDCE6
-:10B71000A089401EA08137B9E089401EE081082140
-:10B72000204601F0D9F90021A28920698154E089DD
-:10B7300006B206E02069815D204601F0CDF9701C5B
-:10B7400006B2A089B042F5DC2021204601F0C4F900
-:10B75000A189E089081A401C06B205E008212046AC
-:10B7600001F0BAF9701E06B2002EF7DC00BFA6E7A2
-:10B7700070B505460C4603E004A1284601F092FA94
-:10B78000201EA4F10101CCB2F6D170BD0820080042
-:10B7900010B504464FF0FF31204600F041FB10BDCC
-:10B7A00010B50446204600F005F80121204601F0BE
-:10B7B000FFF910BD70B50446A08900B970BD002125
-:10B7C000A2892069815494F8600000F0010010B350
-:10B7D000204600F086FB204600F0DEFD0021E181DE
-:10B7E000A181E08E00B9E9E70DA1204601F05AFAE7
-:10B7F00000232046A26D616900F077FE054625B161
-:10B800002946204600F018FE04E0064881692046DB
-:10B8100001F048FA02E02046FFF7CAFE00BFCDE77C
-:10B820000D0A00002402002010B502461146002037
-:10B830000B78302B07D14B78782B02D04B78582BD4
-:10B8400001D103200EE00B78302B07D14B78622B0F
-:10B8500002D04B78422B01D1012003E00B78302B32
-:10B8600000D1022006E00B782E2B03D14B780BB1D0
-:10B87000042003E011F8014B002CF4D100BF10BDEF
-:10B8800002461378272B01D1531C00E013461946BA
-:10B8900000200B785C2B1AD14B786E2B0ED004DC79
-:10B8A000302B0FD0622B0FD104E0722B04D0742BFD
-:10B8B0000AD105E0082009E00D2007E00A2005E094
-:10B8C000092003E0002001E0487800BF00E008788C
-:10B8D000704700002DE9F84F05464FF0000A4FF081
-:10B8E0000A0B2C4600200090012600279FED330A0A
-:10B8F00010EE109A804628782D2800D1B61E711CB3
-:10B9000009B9012100E000214819FFF78DFF8246A7
-:10B91000BAF1010F0FD0BAF1020F07D0BAF1030F3D
-:10B920000ED14FF0100B022000900AE04FF0080BF0
-:10B930000120009005E04FF0020B0220009000E093
-:10B9400000BF00BF00982918701C08B9012000E052
-:10B9500000200C1811E020782E2803D14FF00108A8
-:10B96000641C0AE0207800F025F907FB0B0708EBC0
-:10B9700088004FEA4008641C00BF20780028EAD104
-:10B98000BAF1040F17D1B8F1000F14D000EE107AFD
-:10B99000B8EE401A00EE108AB8EE400AC1EE000A76
-:10B9A00000EE106AB8EEC00A20EE800A10EE109A7F
-:10B9B0004846BDE8F88F07FB06F0FAE700000000F4
-:10B9C0002DE9F04107460C4616461D4626B1207863
-:10B9D00024282FD1607868B32078272808D1607890
-:10B9E00030B12046FFF74CFF28600020BDE8F08111
-:10B9F00020782D2805D02078302808DB20783928B9
-:10BA000005DC2046FFF766FF28600020EEE720787F
-:10BA1000242807D1607828B12A462146384600F00C
-:10BA200031F8E3E7207828B1204600F006F82860D6
-:10BA30000020DBE74FF0FF30D8E770B5044625461D
-:10BA400000262078222802D1601C0446054613E017
-:10BA500028785C2805D12846FFF712FFA0556D1CF9
-:10BA600007E02878222802D10020A05501E028789C
-:10BA7000A0556D1C701C86B228780028E8D1A0550E
-:10BA8000204670BD2DE9F04104460D4616460023C0
-:10BA9000691C2046A26D00F028FD07463FB13946DB
-:10BAA000204600F0FDF830600020BDE8F0814FF046
-:10BAB000FF30FAE72DE9F0478CB080460C4615467A
-:10BAC0001E464FF0000A202104A8F4F725FCA078B8
-:10BAD00000F00F01681E814203DDA07800F00F0026
-:10BAE00000E0681E07464FF0000912E004A800EBD2
-:10BAF000890309F1010056F8201000224046FFF7A3
-:10BB00005FFF20B14FF0FF300CB0BDE8F08709F1C6
-:10BB10000109681E4845E9DC082F45D2DFE807F037
-:10BB200004080E151C232C37A068804782463EE08F
-:10BB3000D4F808900498C847824638E0D4F80890B2
-:10BB4000DDE90401C847824631E0D4F8089004A832
-:10BB500007C8C84782462AE0D4F8089004A80FC84E
-:10BB6000C847824623E0D4F808900898009004A8BB
-:10BB70000FC8C84782461AE0D4F80890DDE90801EA
-:10BB8000CDE9000104A80FC8C84782460FE0D4F8E9
-:10BB90000890DDE908120A98CDE90012029004A885
-:10BBA0000FC8C847824602E04FF0FF3A00BF00BF0F
-:10BBB0005046A9E70146302905DB392903DCA1F10C
-:10BBC0003000C0B27047612905DB662903DCA1F1B2
-:10BBD0005700C0B2F6E7412905DB462903DCA1F195
-:10BBE0003700C0B2EEE70020ECE70146487800F0ED
-:10BBF0000F00012801DCC8687047487800F00F008A
-:10BC0000072801DCC868F7E7487800F00F0008282B
-:10BC100001DCC868F0E7C868EEE7000010B504462C
-:10BC2000002004E03021104A1154411CC8B20928F8
-:10BC3000F8DB607800F00F00012801DC606810BDBF
-:10BC4000607800F00F00072801DC6068F7E7607893
-:10BC500000F00F00082801DC6068F0E70249606826
-:10BC600000F005FF0048EAE7AC110120002111E0D7
-:10BC70000A4850F8210058B1084850F8210090F8BF
-:10BC80006000C0F3400018B1044850F8210070472C
-:10BC9000481C01B20529EBDB0020F8E798110120D0
-:10BCA0002DE9F04107460C460026607800F00F00B1
-:10BCB000801E06281BD2DFE800F003060A0D0E10D6
-:10BCC000A068066814E0A068B0F9006010E0A06801
-:10BCD00006780DE000BFA6680AE0A06845681DB1BF
-:10BCE000A1680868A84700E00020064600E000BF01
-:10BCF00000BF3046BDE8F0812DE9F0470446884694
-:10BD0000B8F1000F01D1BDE8F0872046E16E884709
-:10BD100018274FF00009208F00F47F4018B100274A
-:10BD20006FF0FF090EE0A06B00F47F0018B1082748
-:10BD3000DFF8BC9006E0A06B00F07F4010B1102748
-:10BD40004FF07F49A66D00253EE006EB05104078D8
-:10BD500000F00F00092835D106EB05112046FFF74A
-:10BD600049FC70BB06EB0510406800EA0900A16BB6
-:10BD7000884227D106EB05104168FF20B8400840F3
-:10BD800008FA07F188421DD108FA07F1A06B0843B1
-:10BD9000A0634FF0000847B106EB05104068A7F11B
-:10BDA0000801FF228A40104058B906EB0510806850
-:10BDB00020B106EB05108168204688470021A16369
-:10BDC00006E0FFE7681C05B25C20005BA842BCDC13
-:10BDD00000BFB8F1000F05D00021A1634146204605
-:10BDE00000F0CCFA2046216F884700BF8BE70000A7
-:10BDF0000000FFFF70B504460D46FFF737FF06460B
-:10BE000006B970BD012C03D1304600F089F905E078
-:10BE1000012C03DD3046696800F094FE00BFF0E7B6
-:10BE200070B504460D46002D25DDB4F9541054209C
-:10BE3000005B401E02B2542002535020025B52208D
-:10BE4000005B824202DD5020005B01E05220005B7B
-:10BE5000404281421DDC5020015B5220005B814248
-:10BE600002DD5020005B01E05220005B404201B245
-:10BE7000542001530DE0002D0ADA5420005B401CD1
-:10BE800001B254200153002903DD0021015370BD8C
-:10BE9000FDE72046FFF7DAFB5420005B18B90021CC
-:10BEA000A181E1811BE05220005B401DB4F95410D8
-:10BEB0000844052190FBF1F201FB120104F13C0062
-:10BEC00050F821603146206900F000FDA08100B9E2
-:10BED000DDE7A189E1812046216900F0E3FE00BF92
-:10BEE000D5E710B504460021542001535020005BD3
-:10BEF000002810DD5222125B21690AB9052201E0F7
-:10BF00005222125B521E04F13C0353F82200F4F754
-:10BF100015FA00B910BD5222135B04F13C0252F82D
-:10BF20002300216900F0D2FC28B15220005B401CA4
-:10BF300081B2522001535020005B401C81B250203E
-:10BF40000153052901DD052101535220005B05281D
-:10BF500002DB00215220015300BFDBE72DE9F04155
-:10BF600004460D4616460020A0810021E181206094
-:10BF700094F8600020F00100401C84F86000256106
-:10BF8000062096FBF0F0A086542001535020015368
-:10BF900052200153002009E0A28E411C02FB0152F5
-:10BFA00004F13C0141F82020411C08B20528F3DBD4
-:10BFB0000E48A0650E480D49401AC0F30F115C20D1
-:10BFC00001532046FFF7D8FA00230AA12046A26DAC
-:10BFD00000F08BFA07463946204600F0C3FA0121EB
-:10BFE000204600F0E5FDBDE8F08100001C5401088A
-:10BFF0003C5501086C6574746572000070B50446A8
-:10C000000D46A189A08E401E81420DDB3848416853
-:10C01000204600F047FE0121204600F0C9FD2046E1
-:10C02000216900F03FFE70BDE089A189884218D1E6
-:10C03000A189481CA081206945540021A28920695A
-:10C040008154E089401CE08194F8600000F0010018
-:10C0500008B1284600E02A200146204600F03CFDB9
-:10C0600044E0E089A189884240DAA289E189511A35
-:10C0700008B20AE0E1890144491E2269525CE18963
-:10C08000014423695A54411E08B20028F2DCE189B8
-:10C09000481CE081206945540021A089401C80B2E1
-:10C0A0002269A0811154E089401E06B20EE094F886
-:10C0B000600000F0010010B12069805D00E02A20DE
-:10C0C0000146204600F008FD701C06B2A089B0426F
-:10C0D000EDDCA189E089081A06B205E008212046B6
-:10C0E00000F0FAFC701E06B2002EF7DC00BF9AE7E3
-:10C0F0002402002010B5FFF7B9FD044614B1204614
-:10C1000000F0B8F810BD10B50446E089002806DD3F
-:10C110000821204600F0E0FCE089401EE08110BDCF
-:10C1200010B50446204600F001F810BD70B5054674
-:10C13000AE6D10488168284600F0B4FD002413E07D
-:10C1400006EB0410407800F00F0001280ADC06EB33
-:10C1500004112846FFF74EFA20B906EB04112846D1
-:10C1600000F00AF8601C04B25C20405BA042E7DCEF
-:10C1700070BD0000240200202DE9F04107460C4666
-:10C180002046FFF74BFD05462946384600F08AFD5C
-:10C19000C0F1160006B2002E01DD304600E004209A
-:10C1A000064600BF2021384600F096FC701E00B203
-:10C1B000061EF7D1607800F00F00012805DC2A4840
-:10C1C000016C384600F06EFD25E0607800F00F004D
-:10C1D000072805DC2448416C384600F063FD1AE06E
-:10C1E000607800F00F00082805DC1F48816C384695
-:10C1F00000F058FD0FE0607800F00F00092805DC22
-:10C200001948C16C384600F04DFD04E01648016D38
-:10C21000384600F047FD15A1384600F043FD0725DC
-:10C220000DE020780122AA40104008B1782000E0FB
-:10C230002D200146384600F04FFC681E45B2002D07
-:10C24000EFDA0AA1384600F02DFD2046FFF7CDFCBD
-:10C2500005462946384600F047FC05A1384600F05F
-:10C2600021FDBDE8F0810000240200202020000014
-:10C270000D0A000070B50646B56D13484169304699
-:10C2800000F010FD00241AE005EB0410407800F0E7
-:10C290000F00082811DD05EB0410407800F00F00B6
-:10C2A00009280ADC05EB04113046FFF7A3F920B991
-:10C2B00005EB04113046FFF75FFF601C04B25C2001
-:10C2C000805BA042E0DC70BD2402002070B5064611
-:10C2D000B56D13480169304600F0E4FC00241AE013
-:10C2E00005EB0410407800F00F00072811DD05EB86
-:10C2F0000410407800F00F0008280ADC05EB041158
-:10C300003046FFF777F920B905EB04113046FFF707
-:10C3100033FF601C04B25C20805BA042E0DC70BD97
-:10C320002402002070B50646B56D1348C16830463A
-:10C3300000F0B8FC00241AE005EB0410407800F08F
-:10C340000F00012811DD05EB0410407800F00F000C
-:10C3500007280ADC05EB04113046FFF74BF920B93A
-:10C3600005EB04113046FFF707FF601C04B25C20A8
-:10C37000805BA042E0DC70BD2402002070B5044662
-:10C380000D4694F8600020F0040084F8600029460F
-:10C390002046FFF733FE70BD18B504460820009014
-:10C3A000A189202304F11402206900F0EDF9E08650
-:10C3B00018BD70B5044600252BE004F1140050F8B8
-:10C3C0002500007822280CD1002104F1140050F837
-:10C3D0002500017004F1140050F82510491C40F8A4
-:10C3E000251004F1140151F82500F3F7A0FF86B2DF
-:10C3F00004F1140050F82510701E085C222806D1A4
-:10C40000002104F1140050F82520701E1154681CFE
-:10C4100085B2E08EA842D0DC70BD10B50446E0893C
-:10C42000A189884207DAE289501CE0812069815C99
-:10C43000204600F051FB10BD2DE9F04104460D46A9
-:10C44000002694F8600020F00200801C84F8600050
-:10C45000687800F00F0088B92046FFF7AAFFAF68A0
-:10C46000E08E04F11401B84706466878C0F3401026
-:10C4700018B93146204600F0CFFB2DE0687800F077
-:10C480000F00012810D1E28E04F114032946204642
-:10C49000FFF710FB06466878C0F34010E0B931465C
-:10C4A000204600F0B9FB17E0687800F00F00022882
-:10C4B00009DB687800F00F00072804DC29462046D5
-:10C4C00000F002F908E0687800F00F00082803D1B6
-:10C4D0002946204600F046F894F8600020F002005B
-:10C4E00084F860003046BDE8F0812DE9F04706464B
-:10C4F000884614461F465C20805BB16D611AA0EB34
-:10C5000011101FFA80F9002528E004EB051040788F
-:10C5100000F00F00092805D004EB05113046FFF7A5
-:10C5200069F800B118E004EB0510FFF777FB8246CD
-:10C5300047B951464046F3F701FF60B904EB0510D7
-:10C54000BDE8F0873A4651464046F3F705FF10B97B
-:10C5500004EB0510F4E700BF681C85B24D45D4DB41
-:10C560000020EDE770B504460D462560A86858B177
-:10C57000A868F3F7DCFE38B1E08E022806DBA1697B
-:10C58000A868F3F7DBFE08B9012000E0002094F86A
-:10C59000601060F3000184F860100848816B204649
-:10C5A00000F080FB94F8600000F0010020B1034827
-:10C5B0000168204600F076FB70BD000024020020D8
-:10C5C0002DE9F04106460F46FFF750FB054615B929
-:10C5D0000020BDE8F081002331462846AA6DFFF710
-:10C5E00084FF044634B91148816A284600F05AFB9A
-:10C5F0000020EEE7607800F00F00022804DB60788E
-:10C6000000F00F0007280ADD3146284600F04AFBFB
-:10C610000648416A284600F045FB0020D9E73A4623
-:10C620002146284600F004F8D3E700002402002049
-:10C630002DE9F04106460C4615466078C0F380109F
-:10C6400028B12048016A304600F02CFB34E06078C5
-:10C6500000F00F00801E06282CD2DFE800F0030651
-:10C660000A0D1218A068056025E029B2A0680180B3
-:10C6700021E0A06805701EE02946A06800F026F9B8
-:10C6800019E01048C169304600F00CFB13E0A068C7
-:10C69000806870B1A068006830B1A0688768A16840
-:10C6A00008682946B84704E0A06887682846B84764
-:10C6B00000BF00E000BF00BF2146304600F004F894
-:10C6C000BDE8F08124020020FEB505460C4626A2F6
-:10C6D00007CA8DE8070021462846FFF7E1FA07461A
-:10C6E0002846616800F0DEFA22A1284600F0DAFA56
-:10C6F000607800F00F0005280CD11FA1284600F03B
-:10C70000D1FA3946284600F0CDFA1BA1284600F0A0
-:10C71000C9FA21E06946384600F07EF9C0F10B0005
-:10C72000694646183146284600F0BCFA13A128464F
-:10C7300000F0B8FA002004E030210DF80010411C90
-:10C7400008B20B28F8DB6946384600F090F96946D4
-:10C75000284600F0A7FA00BF00BF0AA1284600F053
-:10C76000A1FA3846FEBD0000303030303030303075
-:10C7700030303000203D2000220000002C20307896
-:10C78000000000000D0A00002DE9FF4F04468C4612
-:10C7900015460D9F4FF00108002000900190029077
-:10C7A00003900021002600BF04E0002245F820206D
-:10C7B000421C10B2B842F8DB002068E011BB225CDA
-:10C7C0009A420DD0B8F1010F0AD1BE4208DA04EB4B
-:10C7D000000A3246761C45F822A04FF0000811E00E
-:10C7E000225C9A4202D0225C202A0BD1B8F1000FC1
-:10C7F00008D100222254421CA25C202A01D04FF012
-:10C80000010842E0002234E0002918DD14F800900D
-:10C81000DFF888A00AEB420A9AF801A0D1450ED1B0
-:10C82000A1F101091DF80990DFF870A01AF812A013
-:10C83000D14504D1A1F1010909F0FF011BE014F871
-:10C840000090DFF858A01AF812A0D1450DD1DFF8FA
-:10C850004C9019F812B0894601F1010A0AF0FF0163
-:10C860000DF809B001F00F0105E002F1010909F02E
-:10C87000FF02002AC8D000BF225C5C2A04D1421CFF
-:10C88000A25C0AB1421C90B200BF421C90B260454B
-:10C8900094DB304604B0BDE8F08F00007802002041
-:10C8A00030B502460B460020002108E0545C5D5C78
-:10C8B000AC4200D008E0441CA0B24C1CA1B2545CB5
-:10C8C00014B15C5C002CF1D100BF30BD02460020E9
-:10C8D00003E00B5C1354431C98B20B5C002BF8D1A3
-:10C8E000135470472DE9F84F0446B4F834A04FF0C4
-:10C8F00000080025A08938B92046FFF711FC012166
-:10C90000204600F055F970E0A08900286DDD002177
-:10C91000A28920698154A66D002737E006EB071134
-:10C920002046FEF767FE78BB06EB0710FFF776F9A7
-:10C93000834659462069FFF7B3FFA189884223D176
-:10C94000F5B1012D03D12AA1204600F0ABF906EB89
-:10C9500008112046FFF710FC06EB0710FFF75EF901
-:10C96000834606EB0810FFF759F959460090FFF788
-:10C9700097FF8146CA4501DD484600E050468246A1
-:10C980001FFA87F8681C85B2781C07B25C20005B30
-:10C99000B842C3DC0DB9BDE8F88F012D02D12046A5
-:10C9A000FEF754FE4DB106EB0810FFF737F90746C6
-:10C9B00039462069FFF78AFFA081012D0ADD06EBC9
-:10C9C00008112046FFF7D8FB0121204600F0F0F8BF
-:10C9D000A4F80CA00021A28920698154A189E181D9
-:10C9E0002046216900F05EF900BF00BFD3E70000D8
-:10C9F0000D0A000008B505462C460CE0606E50B1EB
-:10CA000001216846626E9047012804D19DF800100C
-:10CA10002046FFF771F9F1E730B502460B241346C3
-:10CA2000002A00DA53420020C8720DE00A2093FB6E
-:10CA3000F0F500FB15303030C5B2601EC0B20446C0
-:10CA40000D540A2093FBF0F3002BEFD1002A04DAF7
-:10CA50002D25601EC0B204460D5422B93025601E3B
-:10CA6000C0B204460D54C4F10B0040B230BD30B525
-:10CA700002460B460824002018720EE002F00F0157
-:10CA8000092902DD01F1570001E001F13000C5B2D2
-:10CA9000601EC0B204461D541209002AEED1C4F132
-:10CAA000080040B230BD10B5044601212046FFF712
-:10CAB000B7F910BD10B5FFF7D9F8044614B12046F8
-:10CAC000FFF704FC10BD10B5FFF7D0F8044614B111
-:10CAD0002046FFF727FC10BD13B50446012101A82D
-:10CAE000A26E90471CBD00002DE9F04104460F46A0
-:10CAF00000253E46A06E10B90020BDE8F08102E09E
-:10CB0000761C681C85B2307828B130780D2802D0A8
-:10CB100030780A28F4D1242D08DD24213846A26E6D
-:10CB20009047032106A0A26E904703E029463846AD
-:10CB3000A26E9047242D01DD2420DEE72720DCE7CC
-:10CB40002E2E2E002DE9F04104460E4600233146DC
-:10CB50002046A26DFFF7C9FC0546EDB11248C16A37
-:10CB6000204600F09FF82846FFF758F80746394658
-:10CB7000204600F097F80DA1204600F093F82846D3
-:10CB8000FFF733F807463946204600F08BF807A137
-:10CB9000204600F087F804E003488169204600F051
-:10CBA00081F8BDE8F0810000240200200D0A000099
-:10CBB00070B504460D4694F8600000F00100D8B14D
-:10CBC0001DB110A1204600F06DF820684168204694
-:10CBD00000F068F80CA1204600F064F8A06808B1E5
-:10CBE000A06800E009A00146204600F05BF808A11B
-:10CBF000204600F057F804E00648016B204600F09C
-:10CC000051F870BD0D0A00003A0000002F0000002E
-:10CC10002420000024020020FEB505460C4618A280
-:10CC2000D2E900109268CDE90102009117A12846CF
-:10CC300000F038F869462046FFF7EEFEC0F10B0021
-:10CC4000694646183146284600F02CF812A12846BD
-:10CC500000F028F8002004E030210DF80010411CFD
-:10CC600008B20B28F8DB69462046FFF700FF69464B
-:10CC7000284600F017F80AA1284600F013F8FEBD78
-:10CC800030303030303030303030300052657475F4
-:10CC9000726E3A20000000002C2030780000000066
-:10CCA0000D0A00002DE9F04104460D4600262F46EE
-:10CCB000A06E10B90020BDE8F08101E0701C86B2C2
-:10CCC00017F8011B0029F9D131462846A26E90477A
-:10CCD00080B2F0E7F0B51E49896B09684968C1F573
-:10CCE000807188B21B490988884203DB1949098889
-:10CCF000411A04E017490988C1F5807101448BB2DB
-:10CD0000002120E0134E36887218D61702EB166603
-:10CD10003612A2EB0626104FBD5D104E3688721CEF
-:10CD2000D61702EB5666F611A2EBC616B4B20C4A41
-:10CD30001288944205D00B4A084E36889555074A0A
-:10CD400014804A1C91B29942DCDB02490880F0BD94
-:10CD5000A8060020840200202C140120800200205C
-:10CD6000820200202C1501200FB42DE9F041054668
-:10CD70000E9F022D01DA012100E0002108464FF448
-:10CD80008771F3F777FE342631460020FDF71AFE4F
-:10CD9000044600BF201D07A91C2203E011F8013B37
-:10CDA00000F8013B131EA2F10106B2B2F6D100BF9A
-:10CDB000278084F830500A49E1625DB1012D04D129
-:10CDC000084860620849A16204E040F21F11002097
-:10CDD000F3F750FE2046BDE8F0015DF814FB0000BB
-:10CDE0003D9400087FA00008E7A000087CB5044639
-:10CDF0000CB1012100E0002108464421F3F73AFE7E
-:10CE0000206970B12169D1E90401CDE900012569EA
-:10CE1000D5E902633246D5E90001B047204600F06B
-:10CE20001CF87CBD7CB504460CB1012100E000215A
-:10CE300008465321F3F71EFE206968B12169D1E944
-:10CE40000401CDE900012569EE68334695E8070045
-:10CE5000B047204600F001F87CBD70B504460025BF
-:10CE60000CB1012100E0002108460D21F3F702FE7C
-:10CE70002588002D06DD00E000BF281EA5F1010178
-:10CE80008DB2F9D170BD2DE9F34182B00446FF2780
-:10CE90000CB1012100E000210846A921F3F7EAFDC9
-:10CEA00094F8310001287ED100269AE025460DB184
-:10CEB000012100E0002108468C21F3F7DBFDE86842
-:10CEC00060B1E968D1E90401CDE90001D5F80CC0F1
-:10CED000DCF80C8043469CE80700C04700BF2046B2
-:10CEE000FFF7BBFF9DF80C0000F08000C8B125469D
-:10CEF0000DB1012100E0002108466221F3F7BAFDDF
-:10CF0000686860B16968D1E90401CDE90001D5F82C
-:10CF100004C0DCE902834246DCE90001C04700BFEF
-:10CF200019E025460DB1012100E0002108467021DD
-:10CF3000F3F7A0FD686860B16968D1E90401CDE943
-:10CF40000001D5F804C0DCF80C8043469CE80700DB
-:10CF5000C04700BF00BF2046FFF77FFF25460DB149
-:10CF6000012100E0002108467E21F3F783FDE868F7
-:10CF700060B1E968D1E90401CDE90001D5F80CC040
-:10CF8000DCE902834246DCE90001C04700BF2046DD
-:10CF9000FFF763FF9DF80C004006000E0390780633
-:10CFA000070EA06800E023E00068C0B125460DB17F
-:10CFB000012100E0002108469A21F3F75BFDA968F2
-:10CFC000D1E90401CDE90001D5F808C0DCF81480EE
-:10CFD0009CE80F00C047012801D1781CC7B2701C23
-:10CFE000C6B2082EFFF662AF384604B0BDE8F08145
-:10CFF000002001904FF4FA600090012301AA03A9D8
-:10D00000206AF6F79BFC08B1FF20EEE79DF80400CC
-:10D01000EBE700000FB4F8B507A800904FF40061EB
-:10D020001348009B069AFBF741FF0546002000903D
-:10D030000326104890F89C02032812D10D48D0F81E
-:10D04000BC72F4F78BF9044605E0F4F787F9001B8E
-:10D05000B04200D903E0D7F814020028F5D100BF90
-:10D0600000BFA9B20248F3F7E9FCF8BC5DF814FB75
-:10D070006C02012090F5002070B505460C46214653
-:10D0800001A0FFF7C7FF70BD6C656E203D202564D1
-:10D090000D0A00001CB5012000F0FEFB14490860D9
-:10D0A000144815498866154848661548C8661548E5
-:10D0B00008674FF4007214490F48FEF74FFF4FF412
-:10D0C000807212491248F7F7EFF811480068C068FB
-:10D0D00040F010000E490968C86000200121064B8D
-:10D0E0008A02CDE900100BA10D4801F05DF81CBDCE
-:10D0F0007C020020ADD10008B81101203DD100080C
-:10D1000025D1000891D100082C1201202C140120F7
-:10D11000A80600207368656C6C5F7461736B000017
-:10D12000F5C9000810B504464FF0FF310248006809
-:10D1300000F018FF002010BD7C02002030B5024630
-:10D140000B46002119E00F4800880F4C2488A042AC
-:10D1500000D114E00D480C4C2488055D08464C1C99
-:10D16000A1B21554084C2488601CC41700EB546409
-:10D17000E411A0EBC414044D2C809942E3DB00BF02
-:10D1800008B230BD80020020820200202C15012050
-:10D1900010B5044600231A4619460348006800F0FB
-:10D1A00075FC002010BD00007C02002070B5054613
-:10D1B0000C4640F2FF13224629460248F7F797F83B
-:10D1C00020B270BDA806002001460A69D1E90130ED
-:10D1D0009860D1E9010358605068884201D188689D
-:10D1E0005060002008611068401E10601068704791
-:10D1F000034B0360034B0B608023136070470000F8
-:10D2000098020020EC02002000F1080141604FF07C
-:10D21000FF31816000F10801C160016100210160FE
-:10D22000704700210161704710B502460B685C1C15
-:10D230000CB9106907E002F1080000E0406844689A
-:10D2400024689C42FAD944684C604C68A1608860AC
-:10D2500041600A611468641C146010BD42684A6031
-:10D2600093688B60936859609160086103685B1CE8
-:10D270000360704700BF502080F31188BFF34F8FC9
-:10D28000BFF36F8F00BF0E480068401C0C49086058
-:10D2900008460068012812D10A480068C0B208B9DF
-:10D2A000012000E0002050B900BF502080F3118819
-:10D2B000BFF34F8FBFF36F8F00BF00BFFEE7704714
-:10D2C0007000002004ED00E00D48006850B900BF78
-:10D2D000502080F31188BFF34F8FBFF36F8F00BFD3
-:10D2E00000BFFEE706480068401E05490860084682
-:10D2F000006820B9002080F3118800BF00BF70478C
-:10D300007000002070B506463546002E44D0083D1A
-:10D310002C46224960680968084008B1012000E0F5
-:10D32000002050B900BF502080F31188BFF34F8F09
-:10D33000BFF36F8F00BF00BFFEE7206808B9012070
-:10D3400000E0002050B900BF502080F31188BFF3E7
-:10D350004F8FBFF36F8F00BF00BFFEE70F496068BC
-:10D3600009680840C0B12068B0B90C496068096814
-:10D370008843606000F08EF90949606809680844D4
-:10D38000074908602046FDF773FE06480068401C08
-:10D390000449086001F068F970BD00006C000020CD
-:10D3A0005C0000206800002000204FF0E0210861B0
-:10D3B0008861064800684FF47A71B0FBF1F0401EB6
-:10D3C0004FF0E021486107200861704710000020FD
-:10D3D00070B5F2F741FF0446102C16D304F1E0209B
-:10D3E00090F8F05315480078854201DB012000E0F9
-:10D3F000002050B900BF502080F31188BFF34F8F39
-:10D40000BFF36F8F00BF00BFFEE70D48006800F458
-:10D41000E0600C490968884201D8012000E0002042
-:10D4200050B900BF502080F31188BFF34F8FBFF376
-:10D430006F8F00BF00BFFEE770BD000074000020CA
-:10D440000CED00E07800002070B504460025D4B152
-:10D450001248006808B9012000E0002050B900BF60
-:10D46000502080F31188BFF34F8FBFF36F8F00BF41
-:10D4700000BFFEE700F00EF900212046FDF7A6FBF5
-:10D4800001F0F2F805463DB94FF0805004490860BC
-:10D49000BFF34F8FBFF36F8F70BD00004C000020B3
-:10D4A00004ED00E00349096801600349096841602F
-:10D4B000704700003C0000202800002001200149A6
-:10D4C000086070473800002070B504460D4654B916
-:10D4D00000BF502080F31188BFF34F8FBFF36F8FD1
-:10D4E00000BF00BFFEE70548016818312046FFF77E
-:10D4F0009BFE01212846FDF769FB70BD140000204A
-:10D500002DE9F04706460F4634464FF00109002E3C
-:10D5100060D0A06C50B900BF502080F31188BFF3D9
-:10D520004F8FBFF36F8F00BF00BFFEE7606CB84244
-:10D5300001D23D4600E0656CE06AA8424AD0A06C8A
-:10D54000012847D124480068844201D0012000E02E
-:10D55000002050B900BF502080F31188BFF34F8FD7
-:10D56000BFF36F8F00BF00BFFEE7D4F82C80E562E9
-:10D57000A06900F0004010B9C5F10700A06108EBF8
-:10D580008801164A02EB81016069884201D10120BD
-:10D5900000E00020F0B1201DFFF716FE40B994F81E
-:10D5A0002C10012088400E49096881430C48016015
-:10D5B00094F82C100120884009490968084308495B
-:10D5C0000860E16A01EB8101044A02EB8100211D40
-:10D5D000FFF744FEBDE8F08714000020F4070020A8
-:10D5E0002C00002010B586B000200590049003AAFE
-:10D5F00004A905A8FFF7FCFD0022DDE9041013468D
-:10D60000CDE9002102901CA11D48039A00F0FEFD07
-:10D610001C4908600846006808B1012400E00024A5
-:10D62000012C15D100BF502080F31188BFF34F8F1C
-:10D63000BFF36F8F00BF4FF0FF3013490860012028
-:10D640001249086000201249086000F071F810E0EB
-:10D65000601C08B1012000E0002050B900BF50203C
-:10D6600080F31188BFF34F8FBFF36F8F00BF00BFF0
-:10D67000FEE706B010BD000049444C450000000024
-:10D68000E9AE0008480000204400002030000020DF
-:10D690002800002002480068401C014908607047CB
-:10D6A0004C0000201D48006818B101201C4908608A
-:10D6B00032E000201A4908601A480068B0FA80F089
-:10D6C000C0F11F0101EB8100174A52F8200008B198
-:10D6D000012000E0002050B900BF502080F31188E5
-:10D6E000BFF34F8FBFF36F8F00BF00BFFEE701EBAB
-:10D6F00081020D4B03EB820042685268426000F1E8
-:10D7000008024368934202D142685268426042680C
-:10D71000D268064B1A6000BF704700004C00002022
-:10D72000380000202C000020F40700201400002006
-:10D730001CB5524800685249884201D0012000E0DF
-:10D74000002050B900BF502080F31188BFF34F8FE5
-:10D75000BFF36F8F00BF00BFFEE74848006848492D
-:10D76000491E884201D0012000E0002050B900BFCE
-:10D77000502080F31188BFF34F8FBFF36F8F00BF2E
-:10D7800000BFFEE73F49084600780190FF200A46A7
-:10D7900010700846007800909DF8000000F0F0003E
-:10D7A0009DF80020904201D1012000E0002050B9F6
-:10D7B00000BF502080F31188BFF34F8FBFF36F8FEE
-:10D7C00000BF00BFFEE79DF8000000F050002E4AA9
-:10D7D000107007202D4A106009E02C480068401E98
-:10D7E0002A4A10609DF800004006000E00909DF847
-:10D7F000000000F080008028EFD024480068C0F1CD
-:10D800000700042801D1012000E0002050B900BF2A
-:10D81000502080F31188BFF34F8FBFF36F8F00BF8D
-:10D8200000BFFEE7194800680002184A1060104661
-:10D83000008800F4E0601060124A019810700F48F0
-:10D840002030006840F470000C4920310860084620
-:10D85000006840F070400860FFF7A6FD00200C490A
-:10D860000860F2F7C1FC0B48006840F040400949ED
-:10D870000860F2F7A5FC00201CBD000000ED00E0F0
-:10D8800071C20F4100E400E0740000207800002025
-:10D890007000002034EF00E02DE9F041044601263D
-:10D8A000002722460021012000F007F805462846FF
-:10D8B000FDF72EFB2846BDE8F0812DE9F84305462B
-:10D8C0000E4617460DB1012000E0002050B900BF00
-:10D8D000502080F31188BFF34F8FBFF36F8F00BFCD
-:10D8E00000BFFEE705FB06F808F14800FDF78AFCDB
-:10D8F000044664B1A14609F14809002084F84600B5
-:10D900003B464A46314628460094FDF710FB204628
-:10D91000BDE8F8832DE9F84380460E4617461D46BC
-:10D92000DDF82090B8F1000F01D0012000E00020C8
-:10D9300050B900BF502080F31188BFF34F8FBFF361
-:10D940006F8F00BF00BFFEE70DB1012000E0002097
-:10D9500050B900BF502080F31188BFF34F8FBFF341
-:10D960006F8F00BF00BFFEE707B10EB1012000E0DE
-:10D97000002050B900BF502080F31188BFF34F8FB3
-:10D98000BFF36F8F00BF00BFFEE707B90EB90120DC
-:10D9900000E0002050B900BF502080F31188BFF391
-:10D9A0004F8FBFF36F8F00BF00BFFEE7482000908E
-:10D9B0000098482801D1012000E0002050B900BFA4
-:10D9C000502080F31188BFF34F8FBFF36F8F00BFDC
-:10D9D00000BFFEE700BF2C464CB1012084F8460092
-:10D9E0004B463A46314640460094FDF7A0FA2046A1
-:10D9F000BDE8F88370B505460E462C4654B900BF05
-:10DA0000502080F31188BFF34F8FBFF36F8F00BF9B
-:10DA100000BFFEE7FFF72EFCD4E90F12206801FBE0
-:10DA20000200A0600020A06320686060E06B401EE0
-:10DA3000226C216800FB0211E160FF2084F84400A1
-:10DA400084F845009EB9206908B9012000E0002053
-:10DA5000A8B904F1100000F0BBFD80B14FF0805078
-:10DA600009490860BFF34F8FBFF36F8F07E004F1E0
-:10DA70001000FFF7C9FB04F12400FFF7C5FBFFF717
-:10DA800023FC012070BD000004ED00E02DE9FF4300
-:10DA900083B0064688461D464FF00009344654B907
-:10DAA00000BF502080F31188BFF34F8FBFF36F8FFB
-:10DAB00000BF00BFFEE7B8F1000F01D1206C08B92C
-:10DAC000012000E0002050B900BF502080F31188F1
-:10DAD000BFF34F8FBFF36F8F00BF00BFFEE7022D74
-:10DAE00002D1E06B012801D1012000E0002050B9F3
-:10DAF00000BF502080F31188BFF34F8FBFF36F8FAB
-:10DB000000BF00BFFEE700F0DFFB08B9059808B9C9
-:10DB1000012000E0002050B900BF502080F31188A0
-:10DB2000BFF34F8FBFF36F8F00BF00BFFEE700BF93
-:10DB3000FFF7A0FBA06BE16B884201D3022D28D137
-:10DB40002A4641462046FDF720F90746606A08B993
-:10DB5000012000E0002068B904F1240000F038FD45
-:10DB600088B14FF0805032490860BFF34F8FBFF348
-:10DB70006F8F08E03FB14FF080502D490860BFF330
-:10DB80004F8FBFF36F8FFFF79FFB012007B0BDE8FA
-:10DB9000F083059818B9FFF797FB0020F6E7B9F175
-:10DBA000000F04D101A8FFF77DFC4FF00109FFF73A
-:10DBB0008BFBFFF76FFDFFF75DFB94F94400401C02
-:10DBC00010B9002084F8440094F94500401C10B9B5
-:10DBD000002084F84500FFF777FB05A901A800F0B5
-:10DBE0009DFAF0B92046FDF784FAA0B104F11000C7
-:10DBF0000599FFF769FC2046FDF7C4FA00F034FDF3
-:10DC0000002895D14FF0805009490860BFF34F8F2D
-:10DC1000BFF36F8F8CE72046FDF7B4FA00F024FDC8
-:10DC200086E72046FDF7AEFA00F01EFD0020ADE7C6
-:10DC300004ED00E02DE9F84F07468A4690461E465F
-:10DC40003C4654B900BF502080F31188BFF34F8F7A
-:10DC5000BFF36F8F00BF00BFFEE7BAF1000F01D125
-:10DC6000206C08B9012000E0002050B900BF50200E
-:10DC700080F31188BFF34F8FBFF36F8F00BF00BFDA
-:10DC8000FEE7022E02D1E06B012801D1012000E065
-:10DC9000002050B900BF502080F31188BFF34F8F90
-:10DCA000BFF36F8F00BF00BFFEE7FFF791FB00BF20
-:10DCB0005021EFF3118081F31188BFF34F8FBFF331
-:10DCC0006F8F00BF0546A06BE16B884201D3022E27
-:10DCD00025D194F945B0A06B0090324651462046BC
-:10DCE000FDF753F80BF1010088B9606A08B901200B
-:10DCF00000E0002050B904F1240000F069FC28B1D4
-:10DD0000B8F1000F02D00120C8F8000004E00BF1C8
-:10DD1000010040B284F845004FF0010901E04FF0E6
-:10DD2000000900BF85F3118800BF4846BDE8F88FA1
-:10DD30002DE9F74183B005460E464FF000082C460A
-:10DD400054B900BF502080F31188BFF34F8FBFF349
-:10DD50006F8F00BF00BFFEE70EB9206C08B901202D
-:10DD600000E0002050B900BF502080F31188BFF3BD
-:10DD70004F8FBFF36F8F00BF00BFFEE700F0A4FA24
-:10DD800008B9059808B9012000E0002050B900BF8B
-:10DD9000502080F31188BFF34F8FBFF36F8F00BF08
-:10DDA00000BFFEE700BFFFF765FAA76BF7B131468A
-:10DDB0002046FCF7D5FF781EA063206908B9012032
-:10DDC00000E0002060B904F1100000F001FC38B15F
-:10DDD0004FF080502F490860BFF34F8FBFF36F8F14
-:10DDE000FFF772FA012006B0BDE8F081059818B976
-:10DDF000FFF76AFA0020F6E7B8F1000F04D101A896
-:10DE0000FFF750FB4FF00108FFF75EFAFFF742FC07
-:10DE1000FFF730FA94F94400401C10B9002084F850
-:10DE2000440094F94500401C10B9002084F84500D6
-:10DE3000FFF74AFA05A901A800F070F9F0B92046E9
-:10DE4000FDF74AF9A0B104F124000599FFF73CFB66
-:10DE50002046FDF797F900F007FC0028A3D14FF00A
-:10DE600080500C490860BFF34F8FBFF36F8F9AE764
-:10DE70002046FDF787F900F0F7FB94E72046FDF711
-:10DE800081F900F0F1FB2046FDF726F900288AD041
-:10DE90000020A8E704ED00E02DE9F05F0646894682
-:10DEA0001746344654B900BF502080F31188BFF3A1
-:10DEB0004F8FBFF36F8F00BF00BFFEE7B9F1000FB8
-:10DEC00001D1206C08B9012000E0002050B900BF4A
-:10DED000502080F31188BFF34F8FBFF36F8F00BFC7
-:10DEE00000BFFEE7FFF774FA00BF5021EFF3118087
-:10DEF00081F31188BFF34F8FBFF36F8F00BF0546CB
-:10DF0000D4F838A0BAF1000F22D094F944B04946B1
-:10DF10002046FCF725FFAAF10100A0630BF10100E8
-:10DF200070B9206908B9012000E0002068B904F147
-:10DF3000100000F04DFB40B13FB10120386004E01B
-:10DF40000BF1010040B284F844004FF0010801E0F9
-:10DF50004FF0000800BF85F3118800BF4046BDE8C0
-:10DF6000F09F00002DE9F34182B005464FF0000814
-:10DF70002C46002654B900BF502080F31188BFF30F
-:10DF80004F8FBFF36F8F00BF00BFFEE7206C08B953
-:10DF9000012000E0002050B900BF502080F311881C
-:10DFA000BFF34F8FBFF36F8F00BF00BFFEE700F0DE
-:10DFB0008BF908B9039808B9012000E0002050B996
-:10DFC00000BF502080F31188BFF34F8FBFF36F8FD6
-:10DFD00000BF00BFFEE700BFFFF74CF9A76BFFB122
-:10DFE000781EA063206810B9FDF7B2F9A06020691F
-:10DFF00008B9012000E0002060B904F1100000F031
-:10E00000E7FA38B14FF0805043490860BFF34F8FB3
-:10E01000BFF36F8FFFF758F9012004B0BDE8F0811E
-:10E02000039898B90EB9012000E0002050B900BF54
-:10E03000502080F31188BFF34F8FBFF36F8F00BF65
-:10E0400000BFFEE7FFF740F90020E6E7B8F1000F58
-:10E0500004D16846FFF726FA4FF00108FFF734F9BC
-:10E06000FFF718FBFFF706F994F94400401C10B9BC
-:10E07000002084F8440094F94500401C10B90020A9
-:10E0800084F84500FFF720F903A9684600F046F838
-:10E0900040BB2046FDF720F8F0B1206838B9FFF703
-:10E0A000E9F8A06800F038FA0646FFF70DF904F128
-:10E0B00024000399FFF708FA2046FDF763F800F003
-:10E0C000D3FA002888D14FF0805013490860BFF37D
-:10E0D0004F8FBFF36F8F7FE72046FDF753F800F0B7
-:10E0E000C3FA79E72046FDF74DF800F0BDFA204667
-:10E0F000FCF7F2FF0028EED05EB1FFF7BBF8204638
-:10E10000FCF7AAFE07463946A068FFF7F9F9FFF7C2
-:10E11000DBF8002081E7000004ED00E070B5054663
-:10E120000C4655B900BF502080F31188BFF34F8FC4
-:10E13000BFF36F8F00BF00BFFEE754B900BF502090
-:10E1400080F31188BFF34F8FBFF36F8F00BF00BF05
-:10E15000FEE7FFF78FF8124802686868131A206814
-:10E16000401C08B9002617E00E4928680968884253
-:10E1700004D06868904201D801260DE020689842DA
-:10E1800007D92068C01A20602846FFF78BF90026BF
-:10E1900002E0002020600126FFF796F8304670BDAF
-:10E1A000280000203C0000202DE9FF4F85B080466C
-:10E1B00089461746DDE912ABB800FDF723F806469D
-:10E1C00056B15420FDF71EF804460CB1266304E056
-:10E1D0003046FFF797F800E000248CB1002084F867
-:10E1E0005100CDE900ABCDE902403A4649464046F0
-:10E1F000089BFCF7AFFE2046FCF734FD012501E04B
-:10E200004FF0FF35284609B0BDE8F08F2DE9F04FFB
-:10E2100085B00746884691469A46DDE90EB6109CC1
-:10E220000EB1012000E0002050B900BF502080F363
-:10E230001188BFF34F8FBFF36F8F00BF00BFFEE7A2
-:10E240000CB1012000E0002050B900BF502080F345
-:10E250001188BFF34F8FBFF36F8F00BF00BFFEE782
-:10E26000542003900398542801D1012000E000209D
-:10E2700050B900BF502080F31188BFF34F8FBFF318
-:10E280006F8F00BF00BFFEE700BFB4B1AEB125463F
-:10E290002C462E63022085F85100002004A9534625
-:10E2A0004A46CDE900B1CDE9025041463846FCF777
-:10E2B00051FE2846FCF7D6FC01E0002004900498AB
-:10E2C00005B0BDE8F08F00000549096809B90120D3
-:10E2D00005E00449096809B9022000E00020704700
-:10E2E000300000204C000020014908687047000001
-:10E2F0002800002070B5FFF76BF80025014804687E
-:10E30000204670BD280000202DE9F0414FF00008A4
-:10E310004448006800287CD143480068451C4248B6
-:10E32000056015BB41480068006808B9012000E09D
-:10E33000002050B900BF502080F31188BFF34F8FE9
-:10E34000BFF36F8F00BF00BFFEE73848076838484B
-:10E350000068364908603648076036480068401C47
-:10E3600034490860FCF7D4FE00BF3348006885429A
-:10E370003CD300BF2D480068006808B9012000E0C8
-:10E38000002020B14FF0FF302B4908602DE02748D6
-:10E390000068C068C4686668B54202D22648066054
-:10E3A00023E0201DFEF710FFA06A18B104F1180049
-:10E3B000FEF70AFF94F82C10012088401F490968D5
-:10E3C00008431E490860E16A01EB81011C4A02EB27
-:10E3D0008100211DFEF742FF1A49E06A0968C96AF7
-:10E3E0008842C7D34FF00108C4E700BF1548006852
-:10E3F000C06A00EB8000124951F82000012801D9C1
-:10E400004FF001081048006808B14FF0010805E01E
-:10E41000FFE70E480068401C0C4908604046BDE814
-:10E42000F08100004C00002028000020180000208F
-:10E430001C0000203C000020440000202C00002094
-:10E44000F4070020140000203800002034000020D1
-:10E4500070B505462C460026002D55D02B48006887
-:10E46000844201D1012000E0002050B900BF5020BB
-:10E4700080F31188BFF34F8FBFF36F8F00BF00BFD2
-:10E48000FEE7A06C50B900BF502080F31188BFF3A5
-:10E490004F8FBFF36F8F00BF00BFFEE7A06C401E21
-:10E4A000A064616CE06A88422ED0A06C60BB201D25
-:10E4B000FEF78AFE78B9E06A00EB8000144951F853
-:10E4C000200040B994F82C100120884011490968B7
-:10E4D000814310480160606CE062E06AC0F10700AF
-:10E4E000A06194F82C10012088400A49096808436B
-:10E4F00008490860E16A01EB8101054A02EB8100ED
-:10E50000211DFEF7ABFE0126304670BD1400002031
-:10E51000F40700202C00002070B505462C4600268C
-:10E52000002D4DD02749E06A0968C96A884240D267
-:10E53000A06900F0004028B922480068C06AC0F114
-:10E540000700A061E16A01EB81011F4A02EB810132
-:10E550006069884201D1012000E0002018B3201D2D
-:10E56000FEF732FE40B994F82C100120884017497C
-:10E57000096881431548016012480068C06AE0627A
-:10E5800094F82C10012088401049096808430F496D
-:10E590000860E16A01EB81010B4A02EB8100211D59
-:10E5A000FEF75CFE03E007480068C06AE0620126EF
-:10E5B00006E00449606C0968C96A884200D20126F5
-:10E5C000304670BD14000020F40700202C0000200D
-:10E5D00070B50646F068C46854B900BF502080F397
-:10E5E0001188BFF34F8FBFF36F8F00BF00BFFEE7EF
-:10E5F00004F11800FEF7E8FD15480068A8B9201DD1
-:10E60000FEF7E2FD94F82C100120884011490968BA
-:10E61000084310490860E16A01EB81010E4A02EBF0
-:10E620008100211DFEF71AFE04E004F118010B48D9
-:10E63000FEF714FE0A49E06A0968C96A884204D9EB
-:10E64000012501200749086000E00025284670BD2B
-:10E650004C0000202C000020F4070020A808002017
-:10E66000140000203800002070B500240026364831
-:10E67000006850B900BF502080F31188BFF34F8F5E
-:10E68000BFF36F8F00BF00BFFEE7FEF7F3FD2E481C
-:10E690000068401E2C4908600846006800284FD1D9
-:10E6A0002A48006800284BD024E02948C068C46884
-:10E6B00004F11800FEF788FD201DFEF785FD94F893
-:10E6C0002C1001208840234909680843214908602B
-:10E6D000E16A01EB8101204A02EB8100211DFEF776
-:10E6E000BDFD1E49E06A0968C96A884202D301205B
-:10E6F0001B4908601648006808B9012000E00020A6
-:10E700000028D2D00CB1FCF703FD1648056865B1AE
-:10E7100000BFFFF7F9FD10B10120114908606D1E1F
-:10E72000002DF6D100200F4908600D48006838B16F
-:10E73000012630070C490860BFF34F8FBFF36F8F7E
-:10E74000FEF7C2FD304670BD4C00002024000020C2
-:10E75000A80800202C000020F4070020140000204E
-:10E76000380000203400002004ED00E03C51010896
-:10E770009B5B00080000000000000000800000001B
-:10E780000000000000000000000610160006101631
-:10E790000000000000000000010203040607080951
-:10E7A000000000000102030400000000000000005F
-:10E7B0000200F000F0000000000000000000000077
-:10E7C0000000000000000000000003000000000046
-:10E7D0000000000000000000000000000000000039
-:10E7E0005F6C697374006C69737420616C6C206376
-:10E7F0006F6D6D616E640000001000000008000085
-:10E800000800000008000000008000000040000038
-:10E810005D580008B959000835590008C559000865
-:10E82000C95800080A0000000200000000000000B3
-:10E83000000000004000FE079200FE079204FE0761
-:10E8400002008A04BA028A01AA041907C2B9200088
-:10E8500000000000000000000000000000000000B8
-:10E8600000000000200020002000200024012402DD
-:10E87000220222042104200020003800D0A1200020
-:10E880000000000000000000000000000000000088
-:10E89000000000002000A70722012A012A012F0101
-:10E8A000AA072601220116011301C807B0E02000C3
-:10E8B0000000000000000000000000000000000058
-:10E8C0000000000008012701440104013F01440148
-:10E8D0000E011607E501040104010401BFC6200072
-:10E8E0000000000000000000000000000000000028
-:10E8F0000000000084008400F4078F008400F4030B
-:10E900002C0227024401840044013606BCBC2000CE
-:10E9100000000000000000000000000000000000F7
-:10E9200000000000000000000000000000000000E7
-:10E9300000000000000000000000000000000000D7
-:10E9400000000000000000000000000000000000C7
-:10E9500000000000000000000000000000000000B7
-:10E9600000000000000000000000000000000000A7
-:10E970000000000000000000000000000000000097
-:10E980000000000000000000000000000000000087
-:10E990000000000000000000000000000000000077
-:10E9A0000000000000000000000000000000000067
-:10E9B0000000000000000000000000000000000057
-:10E9C0000000000000000000000000000000000047
-:10E9D0000000000000000000000000000000000037
-:10E9E0000000000000000000000000000000000027
-:10E9F0000000000000000000000000000000000017
-:10EA00000000000000000000000000000000000006
-:10EA10000000000080000001FC7F44044404FC3F2F
-:10EA200044244424FC3F14021422F41A1206122235
-:10EA3000D122303CC2B920000000000000000000DC
-:10EA400000000000000000000000000000000000C6
-:10EA500000000000800080008000800080008808A6
-:10EA6000881088208420844082408140800080007B
-:10EA7000A0004000D0A12000000000000000000025
-:10EA80000000000000000000000000000000000086
-:10EA900000000000000100011F7D441144114411D9
-:10EAA00044115F7D4411241104119C108710427C95
-:10EAB00020001000B0E02000000000000000000076
-:10EAC0000000000000000000000000000000000046
-:10EAD000000000001008B8080F0908090808BF085E
-:10EAE00008091C092C080A78CA0F09080808080830
-:10EAF00008080808BFC62000000000000000000051
-:10EB00000000000000000000000000000000000005
-:10EB100000000000080408040804C87F3F0408043B
-:10EB20000804A83F18210C110B12080A0804080A4F
-:10EB30008A116460BCBC20000000000000000000DE
-:10EB400000000000000000000000000000000000C5
-:10EB500000000000000000000000000000000000B5
-:10EB600000000000000000000000000000000000A5
-:10EB70000000000000000000000000000000000095
-:10EB80000000000000000000000000000000000085
-:10EB90000000000000000000000000000000000075
-:10EBA0000000000000000000000000000000000065
-:10EBB0000000000000000000000000000000000055
-:10EBC0000000000000000000000000000000000045
-:10EBD0000000000000000000000000000000000035
-:10EBE0000000000000000000000000000000000025
-:10EBF0000000000000000000000000000000000015
-:10EC00000000000000000000000000000000000004
-:10EC100000000000000000000000000000000000F4
-:10EC200000000000000000000000000000000000E4
-:10EC300000000000000000000000000000000000D4
-:10EC400000000000000000000000000000000000C4
-:10EC500000000000000000000000000000000000B4
-:10EC600000000000000000000000000000000000A4
-:10EC70000000000000000000000000000000000094
-:10EC80000000000000000000000000000000000084
-:10EC900000000000000000000400000C00F8EE037B
-:10ECA000081100081100F8FF01081101081101F80E
-:10ECB000F701080801C81001489001C87300481006
-:10ECC00002481402441302C4F003020000000000D2
-:10ECD000C2B9200000000000000000000000000099
-:10ECE0000000000000000000000000000000000024
-:10ECF0000000000000000000000000000000000014
-:10ED00000000000000000000000000000000000003
-:10ED1000040000040000040000040000040040049B
-:10ED20000060240020C400208401100403080403B0
-:10ED3000080402040402000400000400000400802F
-:10ED40000700000200000000D0A120000000000029
-:10ED500000000000000000000000000000000000B3
-:10ED600000000000000000000000000000000000A3
-:10ED70000000000000000000000000000000000093
-:10ED800000000000000000000400EC040010BC03C0
-:10ED9000104400104400104400104500FC450010D1
-:10EDA000E503904400104400104400D0420030427B
-:10EDB000000E410082F80740000030000000000013
-:10EDC000B0E0200000000000000000000000000093
-:10EDD0000000000000000000000000000000000033
-:10EDE0000000000000000000000000000000000023
-:10EDF0000000000000000000000000000000000013
-:10EE00008000C081003C800020880020900020907D
-:10EE100000FC8100208000608800B09000308107F5
-:10EE200028F9002487002280002080002080002014
-:10EE30008000208000000000BFC62000000000000D
-:10EE400000000000000000000000000000000000C2
-:10EE500000000000000000000000000000000000B2
-:10EE600000000000000000000000000000000000A2
-:10EE700000000000000000101000302000202000E2
-:10EE8000202000FCFF03202000202000202000E0A4
-:10EE9000F8013804012684002088002048002070F2
-:10EEA000002030002048003C860390010200000052
-:10EEB000BCBC2000000000000000000000000000BA
-:10EEC0000000000000000000000000000000000042
-:10EED0000000000000000000000000000000000032
-:10EEE0000000000000000000000000000000000022
-:10EEF0000000000000000000000000FCFF03000014
-:10EF000000000000000000000000F8FF0100000009
-:10EF1000000000000000000000000000FEFF0700ED
-:10EF20000000000000000000C8FD200000000000FC
-:10EF300000000000000000000000000000000000D1
-:10EF400000000000000000000000000000000000C1
-:10EF500000000000000000000000000000000000B1
-:10EF600000000000000000000000000000000000A1
-:10EF7000000000102000FEFF01102000F03F0010F4
-:10EF80002000F03F00102000FFFF03102100FCFFD5
-:10EF900000030103FEFF010000000000000000006C
-:10EFA000BBF920000000000000000000000000008D
-:10EFB0000000000000000000000000000000000051
-:10EFC0000000000000000000000000000000000041
-:10EFD0000000000000000000000000000000000031
-:10EFE0000000000000000000000000400000F01FD2
-:10EFF00000181800040C00FFFF00048200048200C7
-:10F00000FCFF00048000040000040002F8FF01007F
-:10F010000000000000000000C9AB2000000000005C
-:10F0200000000000000000000000000000000000E0
-:10F0300000000000000000000000000000000000D0
-:10F0400000000000000000000000000000000000C0
-:10F0500000000000000000000000000000000000B0
-:10F0600000000000000000000000000000000000A0
-:10F070000000000000000000000000000000000090
-:10F080000000000000000000000000000000000080
-:10F090000000000000000000000000000000000070
-:10F0A0000000000000000000000000000000000060
-:10F0B0000000000000000000000000000000000050
-:10F0C0000000000000000000000000000000000040
-:10F0D0000000000000000000000000000000000030
-:10F0E0000000000000000000000000000000000020
-:10F0F0000000000000000000000000000000000010
-:10F1000000000000000000000000000000000000FF
-:10F1100000000000000000000000000000000000EF
-:10F1200000000000000000000000000000000000DF
-:10F1300000000000000000000000000000000000CF
-:10F1400000000000000000001000003010F0FF3F41
-:10F15000104200104200104200F0FF1F1042081041
-:10F160004208104208F0FF0F10200890C0009041A4
-:10F170000890410E904F0398C100884110884910B3
-:10F1800084473084C13F020000000000C2B9200063
-:10F19000000000000000000000000000000000006F
-:10F1A000000000000000000000000000000000005F
-:10F1B000000000000000000000000000000000004F
-:10F1C000000000000000000000000000000000003F
-:10F1D00000000000000000000000001800001800FF
-:10F1E000001000001000001000001000809000804F
-:10F1F0001101C0100240100460101C3010181010D3
-:10F200003008103004102000100000100000100022
-:10F21000001900001E00000C00000000D0A120001A
-:10F2200000000000000000000000000000000000DE
-:10F2300000000000000000000000000000000000CE
-:10F2400000000000000000000000000000000000BE
-:10F2500000000000000000000000000000000000AE
-:10F2600000000000000000001000003000FED13F50
-:10F27000201002201002201002201002201402FC94
-:10F28000150220140220D63F201202201202201064
-:10F2900002A009026008021C080206040200020221
-:10F2A00000F13FC00000200000000000B0E020009E
-:10F2B000000000000000000000000000000000004E
-:10F2C000000000000000000000000000000000003E
-:10F2D000000000000000000000000000000000002E
-:10F2E000000000000000000000000000000000001E
-:10F2F0000000000000000000000400070CF80004FB
-:10F30000C00004C06004C0C004C00004FE0704C004
-:10F310000004C02004E06004E04304F04624D0442C
-:10F3200074C8800FC87804C40404C20004C0000478
-:10F33000C00004C00004C00004400004BFC6200098
-:10F3400000000000000000000000000000000000BD
-:10F3500000000000000000000000000000000000AD
-:10F36000000000000000000000000000000000009D
-:10F37000000000000000000000000000000000008D
-:10F38000000000000000002080006080016080001C
-:10F39000608000608000FEFF3F6080006080006051
-:10F3A0008000608200E0FD1F7010086E100C642069
-:10F3B00004602006604002604003608001604003FA
-:10F3C00064300E780C7C200310000000BCBC2000D0
-:10F3D000000000000000000000000000000000002D
-:10F3E000000000000000000000000000000000001D
-:10F3F000000000000000000000000000000000000D
-:10F4000000000000000000000000000000000000FC
-:10F4100000000000000000000000000000000000EC
-:10F420000000C0F8FFC018C0CC18C0CCF8FFCC1842
-:10F43000C0CC180CCC180CCCD8FFCCD8CCCCD8CCA9
-:10F44000CCD8CCCCCCCCC0CCCCC004FCC0060C7E80
-:10F45000000000000000000000000000CBA220001F
-:10F46000000000000000000000000000000000009C
-:10F47000000000000000000000000000000000008C
-:10F48000000000000000000000000000000000007C
-:10F49000000000000000000000000000000000006C
-:10F4A000000000000000000000000000000000005C
-:10F4B000000000F8FF7F180060180060F8FF7F1858
-:10F4C0000666180C06180803D8FF7F180C06180CDF
-:10F4D00006F8FFFF0C0C060C0C06040606060306D5
-:10F4E000030106000000000000000000C6C120006B
-:10F4F000000000000000000000000000000000000C
-:10F5000000000000000000000000000000000000FB
-:10F5100000000000000000000000000000000000EB
-:10F5200000000000000000000000000000000000DB
-:10F5300000000000000000000000000000000000CB
-:10F540000200C084FFCC9CC1CC88C1CC80D9CC83C4
-:10F55000D9CC8ED9CC98D9CC80D9CC80D9CC88D9EB
-:10F56000CC98CDCC0C0CCC0C36C00C63C0C6C1C042
-:10F5700074807D000000000000000000B2E2200066
-:10F58000000000000000000000000000000000007B
-:10F59000000000000000000000000000000000006B
-:10F5A000000000000000000000000000000000005B
-:10F5B000000000000000000000000000000000004B
-:10F5C000000000000000000000000000000000003B
-:10F5D00002001B0C007318004338000380FFFF007B
-:10F5E00000031F000318000398FF031818021818DF
-:10F5F00006981806D8188678188C38F88D9C0F98BD
-:10F600000800F0000000000000000000CAD4200044
-:10F6100000000000000000000000000000000000EA
-:10F6200000000000000000000000000000000000DA
-:10F6300000000000000000000000000000000000CA
-:10F6400000000000000000000000000000000000BA
-:10F6500000000000000000000000000000000000AA
-:10F66000008301FEFFFF008301F0FF3F300030F018
-:10F67000FF3F300030F0FF3F300C30000600FEFF4F
-:10F68000FFC0300CF8FF7F67309860301860301F83
-:10F69000003000000000000000000000C4BB20009B
-:10F6A000000000000000000000000000000000005A
-:10F6B000000000000000000000000000000000004A
-:10F6C000000000000000000000000000000000003A
-:10F6D000000000000000000000000000000000002A
-:10F6E000000000000000000000000000000000001A
-:10F6F00000630080C100C080016000033000061874
-:10F70000001C0E00700200C0F8FF0F00030E000383
-:10F710000E800106800106C0000660000738FC0369
-:10F720000E0000000000000000000000B7D620001E
-:10F7300000000000000000000000000000000000C9
-:10F7400000000000000000000000000000000000B9
-:10F7500000000000000000000000000000000000A9
-:10F760000000000000000000000000000000000099
-:10F770000000000000000000000000000018600C05
-:10F78000306018306010FEE1FF00600082EDC1C4FF
-:10F790006C636C6C36FE65FF30661830661830603E
-:10F7A00018FEB1FF3030183818181C1C180E0E182F
-:10F7B000020218000000000000000000B1E6200076
-:10F7C0000000000000000000000000000000000039
-:10F7D0000000000000000000000000000000000029
-:10F7E0000000000000000000000000000000000019
-:10F7F0000000000000000000000000000000000009
-:10F8000000000000000000000000000000000000F8
-:10F81000003800007000FFFFFF003800064E608CCB
-:10F820006338D03F08001C00202604F8C31CCFFF1B
-:10F83000F1023041003000FFFFFF003000003000D7
-:10F84000003000000000000000000000C2CA2000DC
-:10F8500000000000000000000000000000000000A8
-:10F860000000000000000000000000000000000098
-:10F870000000000000000000000000000000000088
-:10F880000000000000000000000000000000000078
-:10F8900000000000000000000000000000308000B8
-:10F8A00030800130000330FEFFFE06C03086C430D9
-:10F8B0004018303030301860F00FC03EF87F300014
-:10F8C0000330000330000330000330000330FFFF3B
-:10F8D0001E0000000000000000000000BFD8200053
-:10F8E0000000000000000000000000000000000018
-:10F8F0000000000000000000000000000000000008
-:10F9000000000000000000000000000000000000F7
-:10F9100000000000000000000000000000000000E7
-:10F9200000000000000000000000000000000000D7
-:10F930008001609801608C0163FC3F6386016382F3
-:10F940000163FFFF63800163800163FC7F638C615F
-:10F95000638C61638C61608C61608C3D6080013F71
-:10F96000000000000000000000000000D6C62000DB
-:10F970000000000000000000000000000000000087
-:10F980000000000000000000000000000000000077
-:10F990000000000000000000000000000000000067
-:10F9A0000000000000000000000000000000000057
-:10F9B0000000000000000000000000000000000047
-:10F9C000000000FCC77F0CC6600CC660FCC77F0C43
-:10F9D000C660003006FEFFFF006E0000C701F001A8
-:10F9E0000F1F00F8FCC77F0CC6600CC660FCC77F09
-:10F9F0000CC660000000000000000000C6F72000F8
-:10FA000000000000000000000000000000000000F6
-:10FA100000000000000000000000000000000000E6
-:10FA200000000000000000000000000000000000D6
-:10FA300000000000000000000000000000000000C6
-:10FA400000000000000000000000000000000800AE
-:10FA5000001800003000FEFFFF0600C00600C0E0F6
-:10FA6000FF0F00000700800100E000003000FFFFF2
-:10FA7000FF003000003000003000003000801F0028
-:10FA8000000000000000000000000000D7D62000A9
-:10FA90000000000000000000000000000000000066
-:10FAA0000000000000000000000000000000000056
-:10FAB0000000000000000000000000000000000046
-:10FAC0000000000000000000000000000000000036
-:10FAD0000000000000000000000000000020800185
-:10FAE00030C000F8DFFFC8600684710C02390801DD
-:10FAF000100060000C70000CB8FFFF3C000C3604D6
-:10FB00000C320C0C30180C30100C30000C30000C87
-:10FB100030E007000000000000000000B7FB2000FC
-:10FB200000000000000000000000000000000000D5
-:10FB300000000000000000000000000000000000C5
-:10FB400000000000000000000000000000000000B5
-:10FB500000000000000000000000000000000000A5
-:10FB60000000000000000000000000000000000095
-:10FB7000C0300060E000F0FFFF386000F6FFFF33A8
-:10FB80006000F0FFFF306000F0FFFF300000003049
-:10FB900000003000FEFFFF00FE01803107703038AA
-:10FBA0000F30C0000000000000000000BCAF2000CB
-:10FBB0000000000000000000000000000000000045
-:10FBC0000000000000000000000000000000000035
-:10FBD0000000000000000000000000000000000025
-:10FBE0000000000000000000000000000000000015
-:10FBF0000000000000000000000000000000000005
-:10FC0000001800001800001800001800FCFF7F0C0E
-:10FC100018600C18600C18600C18600C1860FCFF61
-:10FC20007F0C186000180000180000180000180071
-:10FC3000001800000000000000000000D6D02000E6
-:10FC400000000000000000000000000000000000B4
-:10FC500000000000000000000000000000000000A4
-:10FC60000000000000000000000000000000000094
-:10FC70000000000000000000000000000000000084
-:10FC800000000000000000000000000000001C0058
-:10FC9000003800006000FFFFFF60000C60000CC037
-:10FCA0000006C0000680010300830100C700006C4D
-:10FCB0000000380000EE00C0830778003C0600E03A
-:10FCC000000000000000000000000000CEC4200082
-:10FCD0000000000000000000000000000000000024
-:10FCE0000000000000000000000000000000000014
-:10FCF0000000000000000000000000000000000004
-:10FD000000000000000000000000000000000000F3
-:10FD100000000000000000000000000000000000E3
-:10FD2000000000F8FF3F180030180030F8FF3F18BF
-:10FD30000030180030F8FF3F18003004C62008C615
-:10FD40003018C63830C61820C60800C600FEFFFFAF
-:10FD5000000000000000000000000000CFD42000E0
-:10FD60000000000000000000000000000000000093
-:10FD70000000000000000000000000000000000083
-:10FD80000000000000000000000000000000000073
-:10FD90000000000000000000000000000000000063
-:10FDA0000000000000000000000000000000000053
-:10FDB000000000FCFF7F00000000000000000000C9
-:10FDC0000000FFFFFF00300020300430300C3830DE
-:10FDD000181830300C30600630C00230800030001F
-:10FDE000801F00000000000000000000CABE2000CC
-:10FDF0000000000000000000000000000000000003
-:10FE000000000000000000000000000000000000F2
-:10FE100000000000000000000000000000000000E2
-:10FE200000000000000000000000000000000000D2
-:10FE300000000000000000000000000000000000C2
-:10FE4000000000FEFFFF00300000300000300030F6
-:10FE5000300030300030300030F07F303000303053
-:10FE600000303000303000303000303000FFFFFF15
-:10FE7000000000000000000000000000D5FD200090
-:10FE80000000000000000000000000000000000072
-:10FE90000000000000000000000000000000000062
-:10FEA0000000000000000000000000000000000052
-:10FEB0000000000000000000000000000000000042
-:10FEC0000000000000000000000000000000000032
-:10FED000000300800100C0FF076000033880010CB0
-:10FEE0006000F4FF3F3000303030303030303030A0
-:10FEF0003030303030303030F83000980300070EAA
-:10FF0000E001781E00C0000000000000B8BA200028
-:10FF100000000000000000000000000000000000E1
-:10FF200000000000000000000000000000000000D1
-:10FF300000000000000000000000000000000000C1
-:10FF400000000000000000000000000000000000B1
-:10FF500000000000000000000000000000000000A1
-:10FF6000003000003000003000003000603006300B
-:10FF7000300C30301C1830381830300C30600E30F7
-:10FF8000E00630C0023080003000003000C01F00AA
-:10FF9000000000000000000000000000D0A12000D0
-:10FFA0000000000000000000000000000000000051
-:10FFB0000000000000000000000000000000000041
-:10FFC0000000000000000000000000000000000031
-:10FFD0000000000000000000000000000000000021
-:10FFE0000000000000000000000000000000000011
-:10FFF000C00003C60C01C48601C080FFFECF60E0D4
+:1002E0004346BDE8F09F2DE9F0410024061B25465A
+:1002F00071F1000605DA01240027D0EB070067EB57
+:100300000101161E73F1000605DA0027D2EB070281
+:10031000012567EB0303FFF7B5FF86460E46174638
+:100320009C46AC4204D00025D0EB050E65EB0106DF
+:1003300024B10020D2EB000760EB030C704631467D
+:100340003A466346BDE8F08110B5431A934209D29C
+:100350008318881803E010F8011D03F8011D521ED0
+:10036000F9D210BD40EA01039B0703D009E008C998
+:10037000121F08C0042AFAD203E011F8013B00F86A
+:10038000013B521EF9D210BDD2B201E000F8012BA0
+:10039000491EFBD270470022F6E710B513460A4605
+:1003A00004461946FFF7F0FF204610BD421C10F826
+:1003B000011B0029FBD1801A704710B5002200E014
+:1003C000521C835C8C5CA34201D1002BF8D1D8B2C3
+:1003D000E1B2401A10BD034611F8012B00F8012BC1
+:1003E000002AF9D11846704730B50546002003466B
+:1003F00000E05B1C934205D2EC5CC85C201A01D182
+:10040000002CF6D130BD2DE9FE4F804681EA030075
+:10041000C00F0C46009021F0004123F00045B8EBDE
+:100420000200A94105D24046214690461C460B4693
+:10043000024623F00040104347D0270DC7F30A00BF
+:10044000C3F30A510290401A019040286BDAC3F3BB
+:10045000130040F4801B0098924620B10023D2EB99
+:10046000030A63EB0B0B01985946C0F1400250465A
+:1004700000F040F906460D4650465946019A00F0F4
+:1004800058F910EB08006141002487EA115284EA10
+:10049000E7731A4340D0009A62B3019A012A4FEAE7
+:1004A000075215DC001B61EB02014FF0004202EA2B
+:1004B0000752CDE90042001C41F5801132462B461F
+:1004C00000F058F903B0BDE8F08F40462146F9E747
+:1004D000001B61EB0201001C41F5801300185B4119
+:1004E0002018A2F5001747EB030140EAD570B619B2
+:1004F0006D4111E06D084FEA360645EAC0754FEAD6
+:100500000752001B61EB0201001C41F580114908F4
+:100510004FEA30000019514132462B4603B0BDE886
+:10052000F04F00F018B90098012240000023D0EBF2
+:10053000020263EBE073009821464FEAE074B8EBE7
+:10054000000061EB0401E9E783F000435BE781F021
+:10055000004158E72DE9FE4F81EA030404F000440E
+:1005600021F0004100944FF0000B23F0004350EACB
+:1005700001045ED052EA03045BD0C3F30A54C1F312
+:100580000A552C44A4F2F3340194A0FB0254C1F3A5
+:10059000130141F48011C3F3130343F4801301FBEF
+:1005A000024400FB034E840A970A44EA815447EA56
+:1005B0008357A4FB076802958D0A05FB07854FEA60
+:1005C000932C04FB0C542705029D4FEA065847EA7A
+:1005D0001637B5EB08056EEB070C870E920E47EA4F
+:1005E000811742EA8312A7FB0201B6EB0B0164EB11
+:1005F00000042B0D43EA0C335E1844EB1C50DA4622
+:100600005146E7FB0201C5F313044FEA0B3343EAFB
+:1006100014534FEA0432019C43EA0603A4F10C048C
+:100620000294009CCDE900B400F0A4F803B0BDE84A
+:10063000F08F00200146F9E70EB5C10F80EAE070A7
+:100640000844CA07002140F233438DE80E000A46F1
+:100650000B4600F08FF803B000BD70B5C1F30A522D
+:1006600001F000450024C1F3130140F2FF3341F4CF
+:1006700080119A4201DA002070BD40F233439A4261
+:10068000A2F2334203DC524200F043F800E0904013
+:100690002C43F1D0404270BD30B5041E71F100040E
+:1006A00004DB4FF00044404264EB0101141E73F17F
+:1006B000000405DB1C464FF00043524263EB040389
+:1006C0008B4208BF824230BD30B50B460146002048
+:1006D0002022012409E021FA02F59D4205D303FA04
+:1006E00002F5491B04FA02F52844151EA2F1010285
+:1006F000F1DC30BD202A04DB203A00FA02F10020B0
+:1007000070479140C2F1200320FA03F3194390404F
+:100710007047202A04DB203A21FA02F000217047BA
+:1007200021FA02F3D040C2F1200291400843194659
+:100730007047202A06DBCB17203A41FA02F043EA41
+:10074000E07306E041FA02F3D040C2F1200291408A
+:1007500008431946704710B5141E73F1000408DAF7
+:10076000401C41F1000192185B411A4301D120F075
+:10077000010010BD2DE9F04D92469B4611B1B1FA32
+:1007800081F202E0B0FA80F220329046FFF7B2FF29
+:1007900004460F4640EA0A0041EA0B0153465A4616
+:1007A000084313D0114653EA010019D0C8F14002A2
+:1007B0005046FFF7AEFF05460E46504659464246A4
+:1007C000FFF798FF084305D0012004E02046394692
+:1007D000BDE8F08D0020054346EAE0762C43374320
+:1007E0000A986305E40AA0EB08000022FD0A44EA27
+:1007F00047540A3002D500200146E9E701051019E7
+:100800006941DDE9084500196941BDE8F04DA2E7FD
+:100810002DE9F04D81EA030404F0004B21F000457E
+:1008200014464FF0000A23F0004150EA050220D0A0
+:1008300054EA01021DD0C5F30A570246C5F313035B
+:10084000C1F31300C1F30A5640F4801543F480133A
+:10085000A7EB0608101BD64608F2FD3873EB05001F
+:1008600002D308F1010801E092185B41B8F1000FD2
+:1008700003DA00200146BDE8F08D00204FF480111E
+:10088000064684460EE0171B73EB050705D3121BC3
+:1008900063EB050306434CEA010C49084FEA3000BC
+:1008A00092185B4150EA0107EDD152EA030012D0E1
+:1008B00082EA040083EA0501084305D0101BAB411E
+:1008C00006D20122002306E000224FF0004302E09E
+:1008D0006FF0010253101AEB06004CEB085110EBBD
+:1008E0000A0041EB0B01BDE8F04DFFF734BFC1F347
+:1008F0000A52C1F3130140F2FF3341F480119A42CE
+:1009000002DA00200146704740F233439A42A2F2D5
+:10091000334202DC5242FFF7FCBEFFF7EBBE0000A1
+:1009200030B5041E71F1000404DB4FF00044404276
+:1009300064EB0101141E73F1000405DB1C464FF04B
+:100940000043524263EB0403994208BF904230BD1A
+:10095000064C074D06E0E06840F0010394E807000C
+:1009600098471034AC42F6D3FFF712FC3C61010803
+:100970006C61010870B58C1810F8015B15F0070365
+:1009800001D110F8013B2A1106D110F8012B03E028
+:1009900010F8016B01F8016B5B1EF9D12B0705D430
+:1009A0000023521E0DD401F8013BFAE710F8013B79
+:1009B000CB1A921C03E013F8015B01F8015B521E95
+:1009C000F9D5A142D8D3002070BD000010B5012494
+:1009D000A102034800F03AFD00B10024204610BDFA
+:1009E0000004024010B504462146024802F0DCFC37
+:1009F00010BD0000C804002010B5044802F0E7FC58
+:100A0000042801D0012010BD0020FCE7C80400200C
+:100A100010B5002400F014F8012801D0012010BD09
+:100A2000064802F0E6FC044634B94FF4006103487E
+:100A300002F070FB00B101242046F0E7C80400205A
+:100A400008B501200090FFF7C1FF08B90020009011
+:100A50009DF8000008BD00002DE9F04104460D4658
+:100A60001646002733462A462146044802F0F6FD82
+:100A700000B101273846BDE8F0810000C80400201D
+:100A800010B500220121024800680AF07DFA10BD6D
+:100A9000D80000202DE9F04104460D4616460027F7
+:100AA00033462A462146044802F086FE00B101275B
+:100AB0003846BDE8F0810000C804002000BFFEE712
+:100AC0000346042B15D007DC7BB1012B0ED0022B83
+:100AD0000DD0032B12D10BE0202B0BD0212B0AD0F1
+:100AE000222B09D0232B09D107E008E007E006E01C
+:100AF00005E004E003E002E001E000E000BF00BF29
+:100B0000002070470020704710B5002204490548B6
+:100B100005F0F9FF0449034805F0E6FF002010BD89
+:100B20000C150120300801200C0D012070B5044681
+:100B30000D462046296810F009FE2146034805F0BD
+:100B4000D3FF024805F09CFF002070BD3008012053
+:100B500010B503460C460021084610BD2DE9F041B2
+:100B600004460D4600260A48D0F8BC72D7F8140295
+:100B700010B10120BDE8F0812A462146044805F065
+:100B8000C2FF034806F072F806463046F2E700005E
+:100B900030080120024600BF1AB901E000BF00BFC3
+:100BA000FCE700BF0120704710B5024800F060F973
+:100BB00010BD0000A806002010B5024800F058F94A
+:100BC00010BD00004C05002010B5024800F050F99F
+:100BD00010BD0000AC05002010B5024800F048F937
+:100BE00010BD0000080700200146087810381823BF
+:100BF000B0FBF3F20848805CC865032A05D9086891
+:100C00006FF30900001D886503E008686FF30900B1
+:100C10008865886D704700005C2E01080146002041
+:100C20008A6A8B69CBB932B1012A0DD0022A03D06E
+:100C3000032A10D10EE000BFCB6A03F08073B3F13A
+:100C4000807F00D1012007E0CB6AB3F1C07F00D1E3
+:100C5000012001E000E000BF34E08B69B3F5005FE4
+:100C60001AD132B1012A07D0022A03D0032A11D1A6
+:100C70000AE000BF01200EE0CB6A03F08073B3F1FD
+:100C8000807F00D1012006E0CB6AB3F1C07F00D1A4
+:100C9000012000E000BF15E032B1012A05D0022A90
+:100CA00004D0032A0CD103E000BF00BF012008E0FC
+:100CB000CB6A03F08073B3F1807F00D1012000E0A4
+:100CC00000BF00BF704730B50468246824F4802456
+:100CD00005682C60046863608468402C04D1046853
+:100CE000A2600468E16003E00468A1600468E26057
+:100CF00030BD704772B600BFFEE730B504460D4602
+:100D000000222946204600F001F830BDF0B5034628
+:100D1000012500241148807B02281CDA00200F4E98
+:100D2000B67B0E4FB8553846867B001D40F82630FE
+:100D3000001F867B0C3082553E46B07B461CBE733E
+:100D4000044604F1300008703A2048702F20887063
+:100D50000020C87000252846F0BD000020080120B2
+:100D600070B50A480468001D0568001D0668344413
+:100D700054B108220649204603F0B5FB0422044979
+:100D80001031284603F0AFFB70BD0000107AFF1F42
+:100D90001A01002070B50446A56D00F06FFB0646F1
+:100DA00094F83500022808D08020606500BF00203C
+:100DB00084F8340000BF012070BD2068006820F076
+:100DC0001600216808602068406920F080002168D2
+:100DD0004861206C08B9A06C28B12068006820F038
+:100DE0000800216808602068006820F00100216880
+:100DF000086010E000F042FB801B05280BD9202082
+:100E00006065032084F8350000BF002084F83400BA
+:100E100000BF0320D0E72068006800F00100002830
+:100E2000E8D194F85C103F208840A860012084F845
+:100E3000350000BF002084F8340000BF00BFBBE7CE
+:100E4000014691F83500022803D080204865012032
+:100E50007047052081F835000868006820F001001F
+:100E60000A6810600020F3E70146486D70470000F3
+:100E7000F8B50446002000908C4800684FF41651E5
+:100E8000B0FBF1F7A56D2E6894F85C10082088403F
+:100E9000304098B12068006800F0040070B120680C
+:100EA000006820F004002168086094F85C100820B5
+:100EB0008840A860606D40F00100606594F85C10A7
+:100EC00001208840304068B12068406900F080000F
+:100ED00040B194F85C1001208840A860606D40F03B
+:100EE0000200606594F85C1004208840304068B1CE
+:100EF0002068006800F0020040B194F85C10042003
+:100F00008840A860606D40F00400606594F85C1053
+:100F100010208840304078B32068006800F0080056
+:100F200050B394F85C1010208840A86020680068D6
+:100F300000F4802080B12068006800F4002028B907
+:100F4000206CC8B12046216C884715E0A06C98B190
+:100F50002046A16C88470FE02068006800F480708C
+:100F600028B92068006820F0080021680860206C1B
+:100F700010B12046216C884794F85C1020208840EE
+:100F80003040002865D02068006800F0100000287C
+:100F90005FD094F85C1020208840A86094F8350059
+:100FA000052828D12068006820F016002168086014
+:100FB0002068406920F0800021684861206C08B9F1
+:100FC000A06C28B12068006820F008002168086043
+:100FD00094F85C103F208840A860012084F8350018
+:100FE00000BF002084F8340000BF206D10B12046FF
+:100FF000216D8847F8BD2068006800F4802080B12A
+:101000002068006800F4002028B9606C10B1204608
+:10101000616C88471DE0E06BD8B12046E16B8847E2
+:1010200017E02068006800F4807068B920680068E4
+:1010300020F0100021680860012084F8350000BF0E
+:10104000002084F8340000BFE06B10B12046E16B53
+:101050008847606D38B3606D00F00100F0B1052085
+:1010600084F835002068006820F0010021680860DD
+:1010700000BF0098401C0090B84200D905E02068ED
+:10108000006800F001000028F3D100BF012084F8BF
+:10109000350000BF002084F8340000BFE06C10B1C0
+:1010A0002046E16C884700BFA4E700001000002044
+:1010B0002DE9F0410446002500F0E0F9074614B997
+:1010C0000120BDE8F081606A00B100BF022084F811
+:1010D000350000BF002084F8340000BF206800689D
+:1010E00020F00100216808600AE000F0C7F9C01B89
+:1010F000052805D920206065032084F83500E0E745
+:101100002068006800F001000028EED12068056822
+:1011100021480540D4E901010843E16808432169F9
+:10112000084361690843A1690843E1690843216AEA
+:1011300008430543606A042803D1D4E90B0108433E
+:101140000543206805602068456925F00705606A49
+:101150000543606A04280DD1A06A0543E06A48B1DE
+:101160002046FFF75BFD28B140206065012084F830
+:101170003500A6E7206845612046FFF735FD0646A5
+:1011800094F85C103F208840B0600020606501202A
+:1011900084F83500002094E73F8010F02DE9F047F7
+:1011A00004460D4616461F464FF00008D4F85890E6
+:1011B00000BF94F83400012802D10220BDE8F08776
+:1011C000012084F8340000BF94F83500012825D1AF
+:1011D000022084F83500002060653B4632462946EF
+:1011E0002046FFF770FD94F85C103F208840C9F856
+:1011F00008002068006840F0160021680860206C34
+:1012000028B12068006840F0080021680860206864
+:10121000006840F001002168086006E000BF00207F
+:1012200084F8340000BF4FF002084046C6E70000D3
+:1012300070B5044600F022F906462546681C10B138
+:1012400004480078054400BF00F018F9801BA8424C
+:10125000FAD370BD0C000020F8B502460B460025FD
+:10126000002400200021D6E0012606FA01F51E68C0
+:1012700006EA0504AC4274D11E7906F00306012E7D
+:1012800004D01E7906F00306022E13D190684F0099
+:101290000326BE40B0434F00DE68BE40304390603E
+:1012A000506801268E40B0431E79C6F300168E406A
+:1012B000304350601E7906F00306032E09D0D06833
+:1012C0004F000326BE40B0434F009E68BE403043EF
+:1012D000D0601E7906F00306022E13D1CF0802F16A
+:1012E000200656F827004E07F70E0F26BE40B043E3
+:1012F0004F07FF0E1E69BE403043CF0802F12006A3
+:1013000046F8270010684F000326BE40B0431E7900
+:1013100006F003064F00BE40304310605E6806F4DE
+:101320004036002E76D000BF002600963C4E366830
+:1013300046F480463A4F3E603E46366806F48046A4
+:10134000009600BF00BF374E8F0856F827008E0763
+:10135000370F0F26BE40B043334EB24202D10026B3
+:1013600024E057E0314EB24201D101261EE0304E5A
+:10137000B24201D1022619E02E4EB24201D103261B
+:1013800014E02D4EB24201D104260FE02B4EB242A2
+:1013900001D105260AE02A4EB24201D1062605E017
+:1013A000284EB24201D1072600E008268F073F0FE2
+:1013B000BE4030431B4E8F0846F82700224E30684F
+:1013C000A0435E6806F4801606B120431E4E3060CE
+:1013D000361D3068A0435E6806F4001606B120434F
+:1013E000194E361D3060184E361F3068A0435E68B7
+:1013F00006F4003606B12043134E361F3060361F08
+:101400003068A0435E6806F4803606B120430E4E75
+:10141000083E3060491C1029FFF426AFF8BD0000DB
+:1014200044380240083801400000024000040240F5
+:1014300000080240000C024000100240001402406C
+:1014400000180240001C0240083C0140024613699B
+:101450000B400BB1012000E00020704710B542693D
+:1014600021EA020302EA010443EA0443836110BD56
+:101470000AB1816101E00B04836170470148006893
+:101480007047000004000020034800680349097801
+:101490000844014908607047040000200C00002047
+:1014A00010B50D48006840F400700B49086008460C
+:1014B000006840F4806008600846006840F480706E
+:1014C0000860032000F0DCF8042000F007F800F0CA
+:1014D0005FF8002010BD0000003C02402DE9F04103
+:1014E00088B004460027B84600BF0020019023487A
+:1014F000006840F01000214908600846006800F0CC
+:101500001000019000BF00BF02A903A801F052F92A
+:10151000069F1FB901F076F9054602E001F072F965
+:1015200045001748B5FBF0F0A0F101081548164931
+:10153000086040F2E7311448C160C0F8048000211F
+:1015400001618160816102F0A0FB064696B90E48F8
+:1015500002F0D0FB06466EB9362000F043F8102C9E
+:1015600007D200222146362000F04CF807480460DC
+:1015700000E00126304608B0BDE8F0814038024066
+:1015800040420F00001000406807002008000020C3
+:1015900008B500BF002000901148006840F480406A
+:1015A0000F4908600846006800F48040009000BFC2
+:1015B00000BF00BF00200090081F006840F080506E
+:1015C000091F08600846006800F08050009000BFC6
+:1015D00000BF00220F21901E00F014F808BD00008B
+:1015E0004438024001460846002809DB00F01F038A
+:1015F00001229A4043099B0003F1E023C3F8002134
+:1016000000BF70472DE9F05F80460D461646002763
+:1016100007F000FD074639462A46334601F0070029
+:10162000C0F1070ABAF1040F02D94FF0040A01E031
+:10163000C0F1070AD14600F1040ABAF1070F02D23D
+:101640004FF0000A01E0A0F1030AD4464FF0010A6E
+:101650000AFA09FAAAF1010A0AEA020A0AFA0CFAD3
+:101660004FF0010B0BFA0CFBABF1010B0BEA030B78
+:101670004AEA0B042146404607F0D4FCBDE8F09F3F
+:1016800000BF00F00702064B19684FF6FF03194030
+:10169000044B0B4343EA0221014B196000BF704722
+:1016A0000CED00E00000FA05704702461068416248
+:1016B00000207047F0B5034615461868446A21B902
+:1016C00044EA05401E68B06219E01868806A04EBBD
+:1016D0001044002208E0186800F5827050F82200DB
+:1016E00004EB1044501CC2B2481E9042F3D844EAA6
+:1016F0000547186800F582704E1E40F826700020DD
+:10170000F0BD10B50446D4F8080505F01AFF10BD69
+:1017100070B504460D4605EBC50304F13C0101EB31
+:1017200083010A692946D4F8080505F005FE70BD55
+:1017300070B504460D4605EBC50304F51F7101EBBA
+:1017400083010A692946D4F8080505F079FE70BDC1
+:1017500010B50446D4F8080505F0F6FE10BD2DE9D5
+:10176000F04104460D4605F08000802808D105F0C0
+:101770000F0000EBC00104F13C0000EB810607E024
+:1017800005F00F0000EBC00104F51F7000EB8106AF
+:101790003146206807F0CAF907463846BDE8F081AF
+:1017A00070B504460E4606F0800080280AD106F087
+:1017B0000F0000EBC00104F13C0000EB81050120AB
+:1017C000687009E006F00F0000EBC00104F51F701F
+:1017D00000EB81050020687006F00F00287000BF44
+:1017E00094F8BC04012801D1022070BD012084F8C6
+:1017F000BC0400BF2946206806F078FC00BF00202A
+:1018000084F8BC0400BF00BFEFE770B504460E4685
+:1018100006F00F006168884201D9012070BD06F012
+:10182000800080280AD106F00F0000EBC00104F10F
+:101830003C0000EB81050120687009E006F00F0014
+:1018400000EBC00104F51F7000EB810500206870FB
+:101850000020A87006F00F00287000BF94F8BC04A8
+:10186000012801D10220D9E7012084F8BC0400BF7F
+:101870002946206806F022FF00BF002084F8BC043F
+:1018800000BF00BFCAE7024601F00F0000EBC00333
+:1018900002F51F7000EB8300006A70472DE9F047E6
+:1018A00005460E4690461F464FF0000906F08000A0
+:1018B00080280AD106F00F0000EBC00105F13C00C2
+:1018C00000EB81040120607009E006F00F0000EBDE
+:1018D000C00105F51F7000EB81040020607006F068
+:1018E0000F002070C4F80C802771607808B1207850
+:1018F0002081022F01D10020607100BF95F8BC0447
+:10190000012802D10220BDE8F087012085F8BC043F
+:1019100000BF2146286806F0FFFA00BF002085F8C6
+:10192000BC0400BF4846EEE72DE9F04104460E46F0
+:101930001746984606F00F0000EBC00104F51F7033
+:1019400000EB81052F61C5F81880002028626870BF
+:1019500006F00F0028702069012800D16F6106F0A1
+:101960000F0028B9227C2946206806F081FD04E09A
+:10197000227C2946206806F035FF0020BDE8F08172
+:1019800070B504460D4605F00F006168884201D924
+:10199000012070BD05F0800080280AD105F00F00FD
+:1019A00000EBC00104F13C0000EB810601207070E7
+:1019B00007E005EBC50104F51F7000EB8106002070
+:1019C00070700120B07005F00F00307000BF94F807
+:1019D000BC04012801D10220DBE7012084F8BC040B
+:1019E00000BF3146206806F0B0FE05F00F0028B9B0
+:1019F000217C04F2C442206806F028FE00BF0020CB
+:101A000084F8BC0400BF00BFC3E72DE9F0410446E1
+:101A10000E461746984606F00F0000EBC00104F191
+:101A20003C0000EB81052F61C5F81880002028627A
+:101A30000120687006F00F0028702069012800D18D
+:101A40006F6106F00F0028B9227C2946206806F055
+:101A50000FFD04E0227C2946206806F0C3FE00202A
+:101A6000BDE8F0812DE9FE4F0446D4F800B05E4693
+:101A7000206807F042F9002874D1206807F07CF94B
+:101A800008B9BDE8FE8F40F608008059C0F30D206C
+:101A9000C4F8FC04206807F06FF900F00200022887
+:101AA00005D12068406900F0020021684861206883
+:101AB00007F062F900F01000102845D12068806915
+:101AC00020F0100021688861DBF8209009F00F00F9
+:101AD00000EBC00104F51F7000EB810AC9F343401D
+:101AE00002281AD147F6F07009EA000030B3C9F3B2
+:101AF0000A125846DAF8101007F043F9C9F30A1130
+:101B0000DAF810000844CAF81000C9F30A11DAF82C
+:101B100020000844CAF8200010E0C9F3434006281A
+:101B20000CD1082204F2C441584607F02AF9C9F33F
+:101B30000A11DAF820000844CAF8200020688069F9
+:101B400040F0100021688861206807F015F900F462
+:101B50000020B0F5002F7BD10025206807F0DCF8CD
+:101B6000029072E0E1E2029800F00100002868D0E3
+:101B7000E9B2206807F0F3F8804608F0010048B1A8
+:101B8000012106F5306000EB4510816029462046B2
+:101B900002F0F4FE08F00800082809D1082106F533
+:101BA000306000EB451081602946204602F0B4FE0B
+:101BB00008F01000102805D1102106F5306000EB68
+:101BC0004510816008F00200022824D1DBF81400DF
+:101BD00000F08000802807D140F60400805940F4CE
+:101BE000806140F60400815105EBC50104F51F70CA
+:101BF00000EB810A9AF80300012806D100208AF838
+:101C00000300E9B2204600F09BFA022106F530609D
+:101C100000EB4510816008F02000202805D120212C
+:101C200006F5306000EB4510816008F40050B0F517
+:101C3000005F06D14FF4005106F5306000EB45100F
+:101C400081606D1C029840080290029800288AD199
+:101C5000206807F091F800F48020B0F5802F7DD146
+:101C6000206807F04FF8029000259AE0029800F0F3
+:101C70000100002873D0E9B2206807F057F88046C9
+:101C800008F00100F0B305F00F0101208840019039
+:101C900040F634008159019821EA000040F63401F1
+:101CA0008851012106F5106000EB45108160206924
+:101CB000012824D105EBC50104F13C0000EB8100B3
+:101CC00005EBC502016904F13C0000EB8200C0682D
+:101CD000014405EBC50204F13C0000EB8200016108
+:101CE0006DB905EBC50104F13C0000EB8100806992
+:101CF00028B904F2C4420121206806F0A7FCE9B229
+:101D0000204600E001E0FFF703FD08F00800082886
+:101D100005D1082106F5106000EB4510816008F040
+:101D20001000102805D1102106F5106000EB4510B9
+:101D3000816008F04000402805D1402106F5106080
+:101D400000EB4510816008F0020002281DD12946F1
+:101D5000584606F093FF05EBC50101E025E01CE0C5
+:101D600004F13C0000EB810A9AF80300012806D137
+:101D700000208AF80300E9B2204600F0D8F90221D9
+:101D800006F5106000EB4510816008F080008028A7
+:101D900003D12946204602F093FE6D1C02984008AC
+:101DA0000290029800287FF461AF206806F0E4FFFB
+:101DB00000F00040B0F1004F1CD140F60400805903
+:101DC00020F0010140F60400815194F8F404012848
+:101DD00007D1002084F8F40400212046FFF764FCBA
+:101DE00002E0204600F0D4FA2068406900F000408C
+:101DF00021684861206806F0BFFF00F40060B0F57C
+:101E0000006F0ED140F60800805900F0010010B1BB
+:101E1000204600F015FB2068406900F4006021684E
+:101E20004861206806F0A8FF00F48050B0F5805F9C
+:101E30007ED140F60400805920F0010140F60400F4
+:101E400081511021206806F019FF002732E04FF67B
+:101E50007F3106F5106000EB4710816006F51060D9
+:101E600000EB4710006820F4001106F5106000EB4D
+:101E7000471001604FF67F3106F5306000EB4710E8
+:101E8000816006F5306000EB4710006820F4001117
+:101E900006F5306000EB4710016006F5306000EB9E
+:101EA0004710006840F0006106F5306000EB471015
+:101EB00001607F1C6068B842C9D840F61C00805998
+:101EC00040F0011140F61C008151206B70B1D6F832
+:101ED000840840F00B01C6F8841840F6440080598D
+:101EE00040F00B0140F6440081510FE040F6140031
+:101EF000805942F22B01084340F614018851081F13
+:101F0000805940F00B014FF401608151D6F8000870
+:101F100020F4FE60C6F80008217C04F2C442206868
+:101F200006F094FB2068406900F48050216800E0CE
+:101F300000E04861206806F01FFF00F40050B0F593
+:101F4000005F17D1206806F04FF8206806F0C2FE47
+:101F5000E06000F051FC0090227B2068009906F0C0
+:101F600093FF204600F0FCF92068406900F400501F
+:101F700021684861206806F0FFFE00F0080008288C
+:101F800008D1204600F00BFA2068406900F00800F4
+:101F900021684861206806F0EFFE00F0800080288C
+:101FA00018D1DBF8180020F08000CBF818000125CC
+:101FB0000DE005EBC50104F51F7000EB8100C07852
+:101FC000012803D1E9B22046FFF7C9FB6D1C606808
+:101FD000A842EED8206806F0CFFE00F48010B0F5DD
+:101FE000801F2DD1012522E006F5106000EB451081
+:101FF000D0F8009005EBC50104F13C0000EB810036
+:102000000079012812D109F00040B0F1004F0DD144
+:10201000012105EBC50204F13C0000EB8200C17018
+:10202000E8B240F080012046FFF799FB6D1C606824
+:10203000A842D9D82068406900F48010216848611E
+:10204000206806F099FE00F40010B0F5001F44D19E
+:10205000012538E006F5306000EB4510D0F800901F
+:1020600005EBC50104F51F7000EB81000079012824
+:1020700028D109F00040B0F1004F23D109F480309D
+:1020800094F8FC1401F0010188421BD1012105EBF9
+:10209000C50204F51F7000EB8200C170DBF8180068
+:1020A00040F08000CBF81800DBF8140000F080004E
+:1020B00040B940F60400805940F4007140F6040035
+:1020C000815103E06D1C6068A842C3D800BF20683E
+:1020D000406900F4001021684861206806F04CFE59
+:1020E00000F08040B0F1804F08D12046FFF709FB97
+:1020F0002068406900F0804021684861206806F04F
+:102100003BFE00F0040004280FD12068D0F80490B2
+:1021100009F00400042802D12046FFF719FB2068CB
+:10212000406840EA09002168486000BFA9E470B532
+:1021300004460D462946D4F8080505F071FA70BD2D
+:1021400070B504460D462946D4F8080505F08CFA0A
+:1021500070BD70B58AB0044614B901200AB070BDD4
+:10216000266894F8BD0428B9002084F8BC042046F1
+:1021700000F0A2F8032084F8BD04F06B00F4807036
+:1021800008B900212161206806F06AF9282204F1CB
+:1021900010016846FEF7D8F894E80F0005F038FF04
+:1021A00020B1022084F8BD040120D7E70021206877
+:1021B00006F017FE002531E0012105EBC50204F110
+:1021C0003C0000EB8200417005EBC50104F13C00CE
+:1021D00000F8215005EBC50100EB810005810021CD
+:1021E00005EBC50204F13C0000EB8200017105EB38
+:1021F000C50204F13C0000EB8200C16005EBC502A2
+:1022000004F13C0000EB8200016105EBC50204F122
+:102210003C0000EB82008161681CC5B26068A84286
+:10222000CAD800252AE0002105EBC50204F51F707D
+:1022300000EB8200417005EBC50104F51F7000F84A
+:102240002150002105EBC50200EB8200017105EB76
+:10225000C50204F51F7000EB8200C16005EBC502EA
+:1022600004F51F7000EB8200016105EBC50204F567
+:102270001F7000EB82008161681CC5B26068A842D3
+:10228000D1D8282204F110016846FEF75DF894E8E1
+:102290000F0005F0F5FF20B1022084F8BD040120F5
+:1022A0005CE7002084F83800012084F8BD04206831
+:1022B00005F0D4FF002051E710B586B00446142184
+:1022C00001A8FEF768F82068B0F1A04F42D100BF26
+:1022D000002000902048006840F001001E4908607E
+:1022E0000846006800F00100009000BF00BF4FF4F6
+:1022F000C05001900220029000200390032004901F
+:102300000A20059001A91548FEF7A6FF00BF124854
+:10231000001D006840F080000F49091D086000BFE3
+:10232000002000900C481430006840F480400A49B6
+:10233000143108600846006800F48040009000BF37
+:1023400000BF00BF002205214320FFF75BF94320B7
+:10235000FFF748F906B010BD3038024000000240D7
+:1023600070B504460125E06808B9002506E0E0687C
+:10237000022801D1012501E0FEF7BCFC2946D4F872
+:10238000080505F01AFAD4F8080505F0C1F970BD82
+:1023900010B50446D4F8080505F0F0F910BD10B5E5
+:1023A0000446D4F8080505F0F4F910BD70B50446EC
+:1023B0000D4600BF94F8BC04012801D1022070BD75
+:1023C000012084F8BC0400BF84F8385029462068F6
+:1023D00006F03BFD00BF002084F8BC0400BF00BF36
+:1023E000EDE710B5044604F2C441D4F8080505F041
+:1023F000FBF910BD70B50446256800BF94F8BC0415
+:10240000012801D1022070BD012084F8BC0400BF66
+:10241000A06A012806D1A069012803D0A86B40F466
+:102420008030A863206806F0F7FB206805F004FF01
+:1024300000BF002084F8BC0400BF00BFE3E7000039
+:1024400010B50446D4F8080505F02BFA2068D0F83A
+:10245000000E40F001002168C1F8000E206A28B18A
+:102460000348006840F006000149086010BD000004
+:1024700010ED00E008B50120034908620348006838
+:10248000009000BF08BD000000000E420070004038
+:10249000F8B5044600250026207800F0010020B998
+:1024A000207800F0040004282FD100205B498866C2
+:1024B000FEF7E4FF054606E0FEF7E0FF401B0228BA
+:1024C00001D90320F8BD56480068C0F3C060002859
+:1024D000F2D160688101207A41EA0070504984316C
+:1024E000086001204D498866FEF7C8FF054606E0F2
+:1024F000FEF7C4FF401B022801D90320E2E7484849
+:102500000068C0F3C0600028F2D0207800F002001C
+:1025100002287DD100BF0020009041484030006873
+:1025200040F080503E49403108600846006800F0A5
+:102530008050009000BF00BF3A48006840F48070AF
+:1025400038490860FEF79AFF054606E0FEF796FF59
+:10255000401B022801D90320B4E73248006800F488
+:1025600080700028F2D02E487030006800F4407669
+:102570004EB3A08900F44070B04224D02848703097
+:10258000006820F440760120274908600020086098
+:10259000234870300660006800F0010098B1FEF733
+:1025A0006DFF054608E0FEF769FF401B41F28831E8
+:1025B000884201D9032085E7194870300068C0F3CC
+:1025C00040000028EFD000BFA08900F44070B0F5B3
+:1025D000407F0CD112480830006820F4F810134AEC
+:1025E000E168114008430E490831086007E00C48D3
+:1025F0000830006820F4F8100949083108600848DC
+:1026000070300068A189C1F30B010843044900E060
+:1026100002E07031086000BF002053E7000047422D
+:102620000038024000700040400E4742FFFCFF0FA0
+:1026300070B504460D460CB9012070BD58480068BD
+:1026400000F00700A84209D255490D7008460068FD
+:1026500000F00700A84201D00120EEE7207800F04A
+:10266000020002281DD1207800F00400042805D1C2
+:102670004C48006840F4E0504A490860207800F077
+:102680000800082805D14748006840F460404549E3
+:1026900008604448006820F0F000A1680843414900
+:1026A0000860207800F00100A8B36068012807D115
+:1026B0003C4808380068C0F34040B8B90120BCE786
+:1026C0006068022802D06068032807D135480838BE
+:1026D0000068C0F3406048B90120AEE731480838CF
+:1026E0000068C0F3400008B90120A6E72D48006843
+:1026F00020F00300616808432A490860FEF7BEFE27
+:10270000064609E0FEF7BAFE801B41F28831884296
+:1027100002D9032091E707E02248006800F00C008E
+:102720006168B0EB810FEDD11D48006800F0070033
+:10273000A84209D91A490D700846006800F0070040
+:10274000A84201D0012078E7207800F00400042896
+:1027500007D11448006820F4E050E16808431149AB
+:102760000860207800F00800082808D10D480068AB
+:1027700020F46040216940EAC1000A49086000F085
+:1027800061F808490968C1F30311074A515CC84060
+:102790000649086006480068FEF7A0FE00204CE7E6
+:1027A000003C024008380240642E0108100000205E
+:1027B000080000200F2202600D4A126802F0030296
+:1027C00042600B4A126802F0F0028260084A126806
+:1027D00002F4E052C260064A126802F46042D20873
+:1027E0000261044A126802F007020A6070470000A2
+:1027F00008380240003C0240014800687047000071
+:102800001000002000B5FFF7F7FF04490968C1F385
+:102810008221034A515CC84000BD000008380240D4
+:10282000742E010800B5FFF7E7FF04490968C1F3FA
+:102830004231034A515CC84000BD000008380240E4
+:10284000742E01082DE9F047002400250026A1463A
+:102850002548006800F00C0020B1042805D00828A5
+:102860003AD105E0DFF8849039E0DFF8849036E073
+:102870001D48001F006800F03F041B48001F00684F
+:1028800000F4800078B11A481749091F0968C1F39C
+:102890008811A0FB01700146224600233846FDF74F
+:1028A000F1FC05460EE011480F49091F0968C1F304
+:1028B0008811A0FB01700146224600233846FDF72F
+:1028C000E1FC05460848001F0068C0F30140401CB9
+:1028D0004600B5FBF6F902E0DFF8109000BF00BF3C
+:1028E0004846BDE8F0870000083802400024F400A4
+:1028F00000127A00F8B504460CB90120F8BD207822
+:1029000000F00100002874D0F948006800F00C00C5
+:1029100004280DD0F648006800F00C00082813D1F8
+:10292000F348001F006800F48000B0F5800F0BD161
+:10293000EF4808380068C0F34040002859D060686C
+:10294000002856D10120D9E700BF6068B0F5803F6C
+:1029500008D1E7480838006840F48030E449083975
+:1029600008601EE06068B0F5A02F0DD1E04808387F
+:10297000006840F48020DE49083908600846006895
+:1029800040F4803008600CE0D9480838006820F432
+:102990008030D749083908600846006820F4802054
+:1029A000086000BF606890B1FEF768FD054606E06C
+:1029B000FEF764FD401B642801D903209EE7CC4844
+:1029C00008380068C0F340400028F1D011E0FEF75D
+:1029D00055FD054606E0FEF751FD401B642801D970
+:1029E00003208BE7C24808380068C0F34040002845
+:1029F000F1D1207800F0020002285FD1BC480068C5
+:102A000000F00C0058B1BA48006800F00C0008282B
+:102A10001CD1B748001F006800F48000B0B9B4486A
+:102A200008380068C0F3400020B1E068012801D0F8
+:102A3000012063E7AE480838006820F0F8002169FB
+:102A400040EAC100AA490839086037E0E06800B3ED
+:102A50000120A8490860FEF711FD054606E0FEF7D3
+:102A60000DFD401B022801D9032047E7A048083884
+:102A70000068C0F340000028F1D09D480838006885
+:102A800020F0F800216940EAC1009949083908603E
+:102A900014E0002097490860FEF7F0FC054606E0C8
+:102AA000FEF7ECFC401B022801D9032026E79048E2
+:102AB00008380068C0F340000028F1D1207800F009
+:102AC000080008282CD16069A8B101208A49086053
+:102AD000FEF7D4FC054606E0FEF7D0FC401B0228BA
+:102AE00001D903200AE782486C300068C0F3400037
+:102AF0000028F1D014E000207F490860FEF7BEFCFA
+:102B0000054606E0FEF7BAFC401B022801D9032067
+:102B1000F4E677486C300068C0F340000028F1D13B
+:102B2000207800F00400042870D100277048383065
+:102B3000006800F0805090B900BF002000906C4801
+:102B40003830006840F080506949383108600846E4
+:102B5000006800F08050009000BF00BF0127674868
+:102B6000006800F48070B0B96448006840F4807078
+:102B700062490860FEF782FC054606E0FEF77EFC2F
+:102B8000401B022801D90320B8E65C48006800F425
+:102B900080700028F2D000BFA068012808D15448F6
+:102BA0006830006840F001005149683108601DE05C
+:102BB000A06805280DD14E486830006840F0040038
+:102BC0004B49683108600846006840F00100086021
+:102BD0000CE047486830006820F001004449683143
+:102BE00008600846006820F00400086000BFA06884
+:102BF000A8B1FEF743FC054609E0FEF73FFC401B89
+:102C000041F28831884202D9032077E626E038482D
+:102C100068300068C0F340000028EED013E0FEF7F3
+:102C20002DFC054608E0FEF729FC401B41F28831E7
+:102C3000884201D9032061E62D4868300068C0F35E
+:102C400040000028EFD1012F07D129483830006813
+:102C500020F0805026493831086000BFA069002864
+:102C600045D02348006800F00C0008285DD0A0691A
+:102C7000022845D100201F490866FEF7FFFB0546E4
+:102C800006E0FEF7FBFB401B022801D9032035E6D6
+:102C9000174808380068C0F340600028F1D1D4E933
+:102CA00007010843616A40EA81110122A06AC2EB70
+:102CB000500041EA00412C20005D41EA00600C49CF
+:102CC000091F086001200B490866FEF7D7FB05467F
+:102CD00006E0FEF7D3FB401B022801D903200DE6D6
+:102CE000034808380068C0F340600028F1D049E08C
+:102CF0000838024000004742800E47420070004002
+:102D0000002021490866FEF7B9FB054606E0FEF7FC
+:102D1000B5FB401B022801D90320EFE51B480068E2
+:102D2000C0F340600028F2D12CE0A069012800D156
+:102D3000E4E51648001D0668A069012820D006F4C5
+:102D40008001E06981421BD106F03F01206A814287
+:102D500016D147F6C0703040616AB0EB811F0FD1C9
+:102D600006F440310122A06AC2EB5000B1EB004FE3
+:102D700006D106F070612C20005DB1EB006F01D030
+:102D80000120BBE50020B9E50000474200380240C1
+:102D900010B50023046804F1500303EB81031A60AB
+:102DA00010BD000070B505460B4616460024286885
+:102DB00040680E4900EA0104200CD870C4F30420D6
+:102DC000587004F03F009870C4F3423018705EB938
+:102DD000D87801F0D0FED870587801F0CCFE587049
+:102DE000987801F0C8FE9870002070BD3FFFFF008A
+:102DF00070B504460B46164600252068806A586068
+:102E000020680069C0F30E009860206800680E49D1
+:102E100000EA0105C5F305401870C5F30620587097
+:102E200005F07F009870A80DD8705EB9187801F091
+:102E3000A2FE1870587801F09EFE5870987801F044
+:102E40009AFE9870002070BD7F7F7F0070B50446A9
+:102E500001250CB9012070BD607F20B900202077CA
+:102E6000204600F045F80220607700BFCA202168A4
+:102E7000486253202168486200BF204601F094FE5A
+:102E80000546EDB9206880681849084021688860C7
+:102E900021696068084361690843216889680843BB
+:102EA000216888602168E0680861206801692089DC
+:102EB00041EA004021680861204601F09AFE05467B
+:102EC0006DB92068006C20F48020216808642068B7
+:102ED000006CA1690843216808640120607700BF85
+:102EE000FF202168486200BF2846B4E7BFFF8FFF7C
+:102EF0001FB50446002000900190029003900949FC
+:102F0000206888420CD102200090C00103906846DE
+:102F1000FFF7BEFA08B1FDF7EDFE01200249086097
+:102F20001FBD0000002800403C0E47422DE9F04143
+:102F300005460C4617464FF0000800BF287F0128C1
+:102F400002D10220BDE8F0810120287700BF0220D5
+:102F500068774FB9607800F01000102804D16078CD
+:102F600000F0EF000A30607087B9E07801F00EFEE3
+:102F70000304607801F00AFE43EA0023A07801F020
+:102F800005FE0343207843EA403809E0E078000476
+:102F9000617840EA0120A1780843217840EA41386D
+:102FA00000BFCA202968486253202968486200BFD0
+:102FB000284601F0F9FD064646B90B4808EA00002C
+:102FC00029684860284601F014FE06460EB9012023
+:102FD000687700BFFF202968486200BF00BF00205B
+:102FE000287700BF3046ADE73FFFFF002DE9F041F5
+:102FF00004460D4617464FF0000800BF207F012809
+:1030000002D10220BDE8F0810120207700BF02201C
+:103010006077CFB92068806800F0400000B102E01E
+:103020000020E87000BF287801F0B0FD0304687844
+:1030300001F0ACFD43EA0023A87801F0A7FD0343AB
+:10304000E87843EA805812E02068806800F0400089
+:1030500000B102E00020E87000BF28780004697821
+:1030600040EA0120A9780843E97840EA815800BF86
+:10307000CA202168486253202168486200BF204668
+:1030800001F092FD0646B6B9124808EA0000216830
+:1030900008602068806820F4802021688860D5E975
+:1030A0000301084321688968084321688860204635
+:1030B00001F09FFD06460EB90120607700BFFF209A
+:1030C0002168486200BF00BF0020207700BF304663
+:1030D00098E700007F7F7F0070B5044600252068D8
+:1030E000C06820F0A0002168C860FEF7C7F9054657
+:1030F00007E0FEF7C3F9401BB0F57A7F01D9032042
+:1031000070BD2068C06800F020000028F1D00020C9
+:10311000F6E70000F0B589B004460E46002703200C
+:1031200084F83400606C032820D0B6F5805F04D1A9
+:10313000A06B40F08050A0631CE0B6F5006F07D193
+:10314000204602F0E7FB0546A06B2843A06311E090
+:103150003EB9204602F0AAFB0546A06B2843A063B7
+:1031600008E0A06B40F00060A06303E0A06B40F0BB
+:103170008050A063A06B38B1174821688863012094
+:1031800084F83400012713E060680390A06804907D
+:10319000E0680590069660690790A069089006A807
+:1031A00007C88DE80700206803A90EC901F05DFD7E
+:1031B0004FF40071206801F0C9FD054635B106489D
+:1031C00021688863A06B2843A0630127012084F84D
+:1031D0003400384609B0F0BDFF05400070470000DC
+:1031E00010B50246506E800F0870506EC0F38360B9
+:1031F0004870506EC0F301608870506E000CC8704B
+:10320000B2F86400000A087192F864004871906E88
+:10321000000DC880906EC0F3034008726820805A89
+:10322000C0F3C03048726820805AC0F38030887282
+:103230006820805AC0F34030C8726820805AC0F3BA
+:103240000030087300204873506C002836D1682085
+:10325000805A8005030DD06E43EA90700861D06EED
+:10326000C0F3C2600875D06EC0F302604875D06EBE
+:10327000C0F342508875D06EC0F38240C875D06EDE
+:10328000C0F3C23008760869401C50650B7E506D53
+:1032900003F007039B1C01249C4060435065087A9F
+:1032A00000F00F03012098409065D2E915035B0AF6
+:1032B0005843D0654FF40073136621E0506C012829
+:1032C00013D16820805C8006830AD06E43EA1040E8
+:1032D00008610869401C83025365536DD3654FF440
+:1032E00000739365936D13660AE02E481368986324
+:1032F000906B40F080509063012082F8340010BD44
+:103300006C20805AC0F3803001F8190F6C20805A6D
+:10331000C0F3C61048706C20805C00F07F0088709D
+:10332000106FC00FC870106FC0F341700871106F3C
+:10333000C0F382604871106FC0F383508871106FC2
+:10334000C0F34050C87100200872106FC0F30040F5
+:1033500048727020805AC0F3C03088727020805A42
+:10336000C0F38030C8727020805AC0F340300873B8
+:103370007020805AC0F3003048737020805AC0F328
+:10338000812088737020805AC0F30120C873702098
+:10339000805CC0F34600087401204874193900208D
+:1033A000ADE70000FF0540000246506C0860906CDD
+:1033B0004860D06C8860106DC860506D0861906D79
+:1033C0004861D06D8861106EC86100207047F8B503
+:1033D0000446002000906946204602F04FFA054658
+:1033E00015B1A06B2843A0630098C0F34326304674
+:1033F000F8BD10B504460CB9012010BD94F8340096
+:1034000020B900202077204600F06AF8032084F8D5
+:103410003400204600F00CF808B10120EDE7002050
+:10342000A0632063012084F834000020E5E7000059
+:1034300070B58AB00446002004900590069007906D
+:1034400008907620099007A807C88DE80700206833
+:1034500004A90EC901F009FC064616B101200AB004
+:1034600070BD00201C490860206801F018FC012094
+:103470001949A039C1F8A0000220FDF7D9FE204665
+:1034800002F096F905463DB1012084F83400A06BA6
+:103490002843A0630120E2E7204602F007F9054631
+:1034A0003DB1012084F83400A06B2843A0630120C3
+:1034B000D5E74FF40071206801F048FC05464DB196
+:1034C000064821688863A06B2843A063012084F824
+:1034D0003400C4E70020C2E7A0802542FF05400079
+:1034E00010B586B00446142101A8FCF754FF5449D6
+:1034F000206888427ED100BF0020009051480068BB
+:1035000040F400604F4908600846006800F400601D
+:10351000009000BF00BF00BF002000904948143851
+:10352000006840F004004749143908600846006804
+:1035300000F00400009000BF00BF00BF002000901A
+:103540000846006840F0080008600846006800F07F
+:103550000800009000BF00BF4FF4F8500190022017
+:10356000029001200390022004900C20059001A9F4
+:103570003548FDF771FE04200190022002900120E1
+:103580000390022004900C20059001A92F48FDF71C
+:1035900063FE2F482F4908604FF00060486000210B
+:1035A0002C488160C1604FF48061016189004161F4
+:1035B000890081612021C1610021016204214162F1
+:1035C000032181624FF40001C16289100163FDF79C
+:1035D0006FFD08B1FDF78EFB00BF1E4820648463B9
+:1035E00000BF1B4848301C4908604FF0006048602D
+:1035F000402100E021E0184881600021C1604FF4C3
+:103600008061016189004161890081612021C1617E
+:103610000021016204214162032181624FF4000113
+:10362000C16289100163FDF743FD08B1FDF762FB3C
+:1036300000BF0948E063846300BF06B010BD00000E
+:10364000002C01404438024000080240000C0240B7
+:10365000586402404C050020AC0500202DE9F043E1
+:1036600087B004460F4691461D46C8463FB9A06B39
+:1036700040F00060A063012007B0BDE8F08394F83B
+:10368000340001287ED10020A06308EB0501E06D25
+:10369000814205D9A06B40F00070A0630120EBE7E8
+:1036A000032084F8340000202168C8622068C06BC1
+:1036B00040F22A3108432168C8633848216CC86346
+:1036C0003748216CC8640020216C08650021206CFB
+:1036D0008160206C0068006820F0C000216C89685F
+:1036E0000843216C096808606A029308226802F1A5
+:1036F00080013A46206CFDF751FD80B12068C06B17
+:1037000020F495702168C863264821688863A06BFF
+:1037100040F08040A063012084F83400ACE7012031
+:1037200021490860606C012801D04FEA48284FF019
+:10373000FF300190680202909020039002200490D4
+:10374000002005900120069001A9206801F068FA88
+:10375000012D07D9822020634146206801F05EFBDD
+:10376000064606E0812020634146206801F072FB96
+:10377000064676B10B4821688863A06B3043A0638E
+:10378000012000E007E084F83400002020630120DD
+:1037900072E7002070E702206EE700001155000874
+:1037A0009D540008FF0540008C85254210B5044655
+:1037B000FDF766F910BD00002DE9F04387B004461F
+:1037C000884691461D464F46B8F1000F07D1A06BC1
+:1037D00040F00060A063012007B0BDE8F08394F8DA
+:1037E0003400012874D10020A0637919E06D814272
+:1037F00005D9A06B40F00070A0630120ECE7032026
+:1038000084F8340000202168C8622068C06B40F250
+:103810001A2108432168C8633848E16BC8633848F7
+:10382000E16BC8640020E16B0865606C012800D082
+:103830007F02012D07D9A02020633946206801F0BE
+:10384000E7FB064606E0902020633946206801F039
+:10385000FBFB064666B12B4821688863A06B3043AA
+:10386000A063012084F83400002020630120B3E726
+:103870000120254908604021E06B8160E06B006811
+:10388000006820F0C000E16B89680843E16B0968BB
+:10389000086069028B08216801F180024146E06BF3
+:1038A000FDF77CFCA8B12068C06B40F21A21884368
+:1038B0002168C863134821688863A06B40F080408A
+:1038C000A063012084F8340000202063012083E7F6
+:1038D00011E04FF0FF3001906802029090200390B9
+:1038E0000020049005900120069001A9206801F0B5
+:1038F00097F9002070E702206EE700005955000894
+:103900009D540008FF0540008C85254210B50446F3
+:103910000CB9012010BD606A38B96068B0F5827FCB
+:1039200000D105E00021E16102E000212161616137
+:103930000021A16294F8510028B9002084F85000B9
+:10394000204600F047F8022084F851002068006803
+:1039500020F0400021680860A08800F4827021896E
+:1039600001F404410843A18901F400610843217C6A
+:1039700001F002010843217D01F001010843218B80
+:1039800001F400710843217F01F038010843202130
+:10399000095D01F080010843218D01F400510843C5
+:1039A000216808600421A06901EA104094F82410FD
+:1039B00001F010010843216848602068C06920F4C4
+:1039C00000602168C86100206065012084F8510012
+:1039D00000209FE710B586B00446142101A8FCF72B
+:1039E000DAFC1B49206888422FD100BF00200090DC
+:1039F0001848006840F4004016490860084600680E
+:103A000000F40040009000BF00BF00BF0020009005
+:103A100010481038006840F002000E491039086064
+:103A20000846006800F00200009000BF00BF382088
+:103A300001900220029000200390032004900620B1
+:103A4000059001A90448FDF707FC06B010BD000071
+:103A5000003C004040380240000402402DE9FF5F76
+:103A60000446884691461D460E9E01200290002085
+:103A7000019000BF94F85000012803D1022004B047
+:103A8000BDE8F09F012084F8500000BFFDF7F6FC70
+:103A9000074694F851B060680390AA46BBF1010F45
+:103AA0000BD00398B0F5827F04D1A06810B9BBF1A8
+:103AB000040F02D002200190DBE0B8F1000F03D028
+:103AC000B9F1000F00D015B901200190D1E094F8B0
+:103AD0005100042802D0052084F8510000206065C0
+:103AE000C4F83890E587A587C4F83080E586A586B8
+:103AF000206460642068006800F04000402805D021
+:103B00002068006840F0400021680860E068B0F577
+:103B1000006F4AD1606810B1BAF1010F09D1206B72
+:103B200000882168C860206B801C2063E08E401EE6
+:103B3000E08633E02068806800F00200022810D19F
+:103B4000E08E70B1029801280BD1206B00882168AB
+:103B5000C860206B801C2063E08E401EE086002041
+:103B600002902068806800F0010068B1E08F58B1D1
+:103B70002068C068A16B0880A06B801CA063E08FE8
+:103B8000401EE08701200290FDF778FCC01BB04288
+:103B900004D3701C10B1032001906AE0E08E00286D
+:103BA000C8D1E08F0028C5D14AE0606810B1BAF1F1
+:103BB000010F09D1206B007821680873206B401C2D
+:103BC0002063E08E401EE08634E02068806800F0CC
+:103BD0000200022810D1E08E70B1029801280BD1AA
+:103BE000206B007821680873206B401C2063E08EF6
+:103BF000401EE086002002902068806800F00100EE
+:103C000068B1E08F58B12068C068A16B0870A06BE4
+:103C1000401CA063E08F401EE08701200290FDF76A
+:103C20002DFCC01BB04201D3701C00B916B9032093
+:103C300001901EE0E08E0028C7D1E08F0028C4D19B
+:103C40003A463146204601F08DFF20B10120019017
+:103C5000202060650DE0A06850B900BF00200090F2
+:103C60002068C068009020688068009000BF00BF96
+:103C700000BF012084F8510000BF002084F85000EC
+:103C800000BF0198FBE67047704710B504460CB9B9
+:103C9000012010BD94F83D0028B9002084F83C00B4
+:103CA000204600F025F8022084F83D00211D206800
+:103CB00002F09CF8012084F8460000BF84F83E0022
+:103CC00001213F200155402001554120015500BFF1
+:103CD00000BF012084F842004320015544200155D3
+:103CE0004520015500BF012084F83D000020D0E7A9
+:103CF00070470000014691F83D00012801D00120E5
+:103D00007047022081F83D000868C06840F001005B
+:103D10000B68D8601A4B086898421BD00868B0F14D
+:103D2000804F17D0174B0868984213D0164B08687D
+:103D300098420FD0154B086898420BD0144B086876
+:103D4000984207D0134B0868984203D0124B08687A
+:103D500098420CD10868806800F00702062A0CD04F
+:103D60000868006840F001000B68186005E008680A
+:103D7000006840F001000B6818600020C0E70000F8
+:103D8000000001400004004000080040000C00401A
+:103D9000000401400040014000180040704710B589
+:103DA000044620680069C0F34000D8B12068C068AC
+:103DB000C0F34000B0B16FF002002168086101203B
+:103DC00020772068806900F0030018B12046FFF7D3
+:103DD000E5FF05E0204600F0ADF8204600F0ABF826
+:103DE0000020207720680069C0F38000D8B12068E7
+:103DF000C068C0F38000B0B16FF0040021680861B2
+:103E0000022020772068806900F4407018B12046B5
+:103E1000FFF7C4FF05E0204600F08CF8204600F0D4
+:103E20008AF80020207720680069C0F3C000D8B16C
+:103E30002068C068C0F3C000B0B16FF0080021680E
+:103E40000861042020772068C06900F0030018B1E1
+:103E50002046FFF7A3FF05E0204600F06BF8204660
+:103E600000F069F80020207720680069C0F3001096
+:103E7000D8B12068C068C0F30010B0B16FF0100076
+:103E800021680861082020772068C06900F440702C
+:103E900018B12046FFF782FF05E0204600F04AF8FF
+:103EA000204600F048F8002020772068006900F0E4
+:103EB000010058B12068C06800F0010030B16FF017
+:103EC000010021680861204600F036F8206800698A
+:103ED000C0F3C01058B12068C068C0F3C01030B142
+:103EE0006FF08000216808612046FFF7CCFE206853
+:103EF0000069C0F3801058B12068C068C0F380101A
+:103F000030B16FF0400021680861204600F020F8D1
+:103F100020680069C0F3401058B12068C068C0F341
+:103F2000401030B16FF02000216808612046FFF793
+:103F3000ABFE10BD7047704710B5044603492068BA
+:103F4000884201D1FDF7A0FA10BD0000001000402A
+:103F500070477047704700002DE9F84F044620680D
+:103F600005682068C668206847694FF00009CA469E
+:103F700005F00F09B9F1000F0AD105F0200038B1A2
+:103F800006F0200020B1204602F08FF8BDE8F88F3F
+:103F9000B9F1000F7CD007F0010018B906F4907059
+:103FA000002875D005F0010030B106F4807018B11A
+:103FB000206C40F00100206405F0040030B107F0EF
+:103FC000010018B1206C40F00200206405F00200EE
+:103FD00030B107F0010018B1206C40F004002064FB
+:103FE00005F0080048B106F0200010B907F0010004
+:103FF00018B1206C40F008002064206C002846D0E6
+:1040000005F0200028B106F0200010B1204602F093
+:104010004CF820684069C0F3801A206C00F008005A
+:1040200010B9BAF1000F2DD0204601F0E5FF20684D
+:10403000406900F04000402820D100BF00BF216847
+:10404000143151E8001F21F040002168143141E88B
+:104050000002002AF3D100BFA06B50B17548A16BDC
+:104060000865A06BFCF7ECFE88B1A06B016D88477A
+:104070000DE02046FFF76EFF09E009E02046FFF75C
+:1040800069FF04E02046FFF765FF002020647DE71C
+:10409000206B012876D105F01000002872D006F0C0
+:1040A00010000028FAD000BF0020009020680068AF
+:1040B000009020684068009000BF00BF2068406901
+:1040C00000F0400040285ED1A06B006840681FFAF5
+:1040D00080F8B8F1000F54D0A08D404551DDA4F810
+:1040E0002E80A06BC069B0F5807F43D000BF00BFB9
+:1040F00021680C3151E8001F21F4807021680C31D7
+:1041000041E80002002AF3D100BF00BF00BF2168D0
+:10411000143151E8001F21F001002168143141E8F9
+:104120000002002AF3D100BF00BF00BF2168143194
+:1041300051E8001F21F040002168143141E80002DD
+:10414000002AF3D100BF202084F83E000020206325
+:1041500000BF00BF21680C3151E8001F21F01000A2
+:1041600021680C3141E80002002AF3D100BFA06BA6
+:10417000FCF710FEA08DE28D801A81B22046FFF779
+:10418000E8FE03E740E0A08DE18D401A1FFA80F8B9
+:10419000E08DC0B3B8F1000F35D000BF00BF21687B
+:1041A0000C3151E8001F21F4907021680C3141E876
+:1041B0000002002AF3D100BF00BF00BF2168143104
+:1041C00051E8001F21F001002168143141E800028C
+:1041D000002AF3D100BF202084F83E000020206395
+:1041E00000BF00BF21680C3151E8001F21F0100012
+:1041F00021680C3141E80002002AF3D100BF41469A
+:104200002046FFF7A6FEC1E605F0800030B106F0BB
+:10421000800018B1204602F043F9B7E605F04000EF
+:1042200030B106F0400018B1204601F01BFFADE6AA
+:1042300000BFABE6C55E000810B504460CB901200E
+:1042400010BDA06900B100E000BF94F83D0028B99E
+:10425000002084F83C00204600F028F8242084F850
+:104260003D002068C06820F400502168C8602046E6
+:1042700001F098FF2068006920F4904021680861EF
+:104280002068406920F02A00216848612068C068E1
+:1042900040F400502168C86000202064202084F889
+:1042A0003D0084F83E000020CAE7000010B586B04B
+:1042B0000446142101A8FCF76EF83D4920688842A5
+:1042C00074D100BF002000903A48006840F0100010
+:1042D000384908600846006800F01000009000BFF0
+:1042E00000BF00BF0020009032481438006840F042
+:1042F00001003049143908600846006800F00100E8
+:10430000009000BF00BF4FF4C060019002200290F7
+:1043100000200390032004900720059001A926485F
+:10432000FCF79AFF2548264908604FF00060486076
+:10433000002123488160C1604FF480610161002148
+:1043400041618161C16101624162FCF7B1FE08B166
+:10435000FCF7D0FC00BF1A48A063846300BF174875
+:104360007830184908604FF00060486040211548D7
+:1043700081600021C1604FF48061016100214161D1
+:104380008161C16101624162FCF792FE08B1FCF7F4
+:10439000B1FC00BF0B486063846300BF00220521AD
+:1043A0002520FDF72FF92520FDF71CF906B010BDDB
+:1043B00000100140443802400000024040640240C6
+:1043C000A80600200807002070B504460D461646D2
+:1043D00094F83E00202816D105B10EB9012070BD19
+:1043E00000BF94F83C00012801D10220F7E701202A
+:1043F00084F83C0000BF0020206332462946204656
+:1044000001F0E6FFEBE70220E9E7704770472DE98E
+:10441000F84F04460E46174699464FF0000A94F8A6
+:104420003D0020285AD106B117B90120BDE8F88F08
+:1044300000BF94F83C00012801D10220F6E70120DA
+:1044400084F83C0000BF00202064212084F83D0057
+:10445000FDF714F88246A784E784A068B0F5805F72
+:1044600004D1206910B90025B04602E035464FF06E
+:10447000000800BF002084F83C0000BF1BE053464A
+:10448000002280212046CDF8009002F039F808B1D2
+:104490000320CBE745B9B8F80000C0F30800216855
+:1044A000486008F1020803E02878216848606D1C24
+:1044B000E08C401EE084E08C0028E0D153460022CE
+:1044C00040212046CDF8009002F01AF808B10320F0
+:1044D000ACE7202084F83D000020A7E70220A5E7F4
+:1044E000704700BFFEE730B50B46002100BF16E065
+:1044F0000A24B4EB107F05D9302404EB107403F8C0
+:10450000114005E0412404EB10740A3C03F811400B
+:10451000000100254C00641C1D554C1CE1B2914269
+:10452000E6DB30BD08B500BF0020009016480068EB
+:1045300040F48000144908600846006800F48000D8
+:10454000009000BF00BF002205213A20FDF75AF875
+:104550003A20FDF747F800220F213B20FDF752F8E3
+:104560003B20FDF73FF800220F214520FDF74AF8D8
+:104570004520FDF737F8002205214620FDF742F8D7
+:104580004620FDF72FF808BD3038024010B503492A
+:104590000348FCF7B2FB0349087010BDDD000020A2
+:1045A000782F0108DC00002000B587B01C220649E6
+:1045B0006846FBF7C9FE0021684606F015FD034971
+:1045C000086007B000BD0000402E01080000002078
+:1045D00000B587B0142102A8FBF7DDFE00BF002064
+:1045E00001907F48006840F010007D49086008464F
+:1045F000006800F01000019000BF00BF00BF002065
+:1046000001900846006840F0040008600846006811
+:1046100000F00400019000BF00BF00BF0020019027
+:104620000846006840F0200008600846006800F076
+:104630002000019000BF00BF00BF0020019008468D
+:10464000006840F0800008600846006800F08000C4
+:10465000019000BF00BF00BF002001900846006825
+:1046600040F0010008600846006800F00100019079
+:1046700000BF00BF00BF002001900846006840F066
+:10468000020008600846006800F00200019000BFC8
+:1046900000BF00BF002001900846006840F04000C5
+:1046A00008600846006800F04000019000BF00BFAD
+:1046B00000BF002001900846006840F00800086034
+:1046C0000846006800F00800019000BF00BF00220B
+:1046D0004FF400514348FCF7CBFE00224FF4C05189
+:1046E0004148FCF7C5FE4FF6FF700290032003908F
+:1046F0000020049002A93D48FCF7AEFD4FF40050A5
+:1047000002900120039000200490059002A93548F2
+:10471000FCF7A2FD4FF6FF700290032003900020EB
+:10472000049002A93248FCF797FDFF200290032075
+:1047300003900020049002A92A48FCF78DFD48F25E
+:10474000FF100290032003900020049002A9294842
+:10475000FCF782FD4FF6C730029003200390002043
+:10476000049002A92448FCF777FD4FF6FF700290F1
+:10477000032003900020049002A92048FCF76CFD60
+:104780004FF48060029000200390049002A91A4820
+:10479000FCF762FD4CF2FB700290032003900020B6
+:1047A000049002A91048FCF757FD4FF4C050029046
+:1047B0000120039000200490059002A90A48FCF70C
+:1047C0004BFD4FF4005002904FF4881003900020EE
+:1047D000049002A90448FCF73FFD07B000BD0000AB
+:1047E0003038024000080240000C02400010024035
+:1047F0000014024000000240000402400018024081
+:1048000010B50A480A490860002048607F2108481E
+:104810008160FF21C1600021016141618161FEF77A
+:1048200015FB08B1FCF766FA10BD00000028004037
+:10483000A80400207047000010B50E480E4908601B
+:104840004FF48270486000210B488160C1600161B3
+:1048500041614FF4007181610021C16101624162D7
+:1048600081620A21C162FFF751F808B1FCF742FAF0
+:1048700010BD0000003C00400C06002010B50B48A5
+:104880000B4908604FF4E13048600021084881601E
+:10489000C16001610C21416100218161C161FFF7AB
+:1048A000CBFC08B1FCF726FA10BD00000010014057
+:1048B0006406002010B500220D490E4802F0F9FCF4
+:1048C00008B1FCF717FA0C490A4803F027F808B1B9
+:1048D000FCF710FA0949074802F0FAF808B1FCF7AA
+:1048E00009FA044803F01CF908B1FCF703FA10BDFB
+:1048F000E40000203008012058010020340100208D
+:1049000000BFFEE700BFFEE710B50248FDF7AAF8BA
+:1049100010BD00000C1D01202DE9F04704460D4696
+:1049200026683746D6F8408007F5306000EB451022
+:10493000D0F80890104880450BD909F40040B0F534
+:10494000004F06D14FF4004107F5306000EB4510F1
+:1049500081602046FDF745FD0748804508D920695C
+:10496000012805D104F2C4420121206803F06EFE43
+:104970000020BDE8F08700000A30544F2DE9F047D1
+:1049800005460C46D5F800904E46D9F840A006F5ED
+:10499000306000EB4410D0F808802869012855D118
+:1049A00008F0080008280FD1434882450BD908F4C5
+:1049B0000040B0F5004F7BD14FF4004106F5306068
+:1049C00000EB4410816073E008F02000202806D13D
+:1049D000202106F5306000EB4410816068E008F0AB
+:1049E0002800002864D1344882450CD908F40040DE
+:1049F000B0F5004F07D14FF4004106F5306000EBF1
+:104A00004410816054E004EBC40105F51F7000EB15
+:104A1000810706F5306000EB4410F9690069C0F3C6
+:104A20001200081A386264B9B86930B905F2C44294
+:104A30000121286803F00AFE03E0396A3869084456
+:104A40003861E1B22846FCF773FE31E01B4882452D
+:104A50001BD108F40040B0F5004F07D14FF40041DE
+:104A600006F5306000EB4410816021E008F0200082
+:104A7000202805D1202106F5306000EB441081602C
+:104A8000E1B22846FCF754FE12E06CB904EBC40115
+:104A900005F51F7000EB8100806928B905F2C4425A
+:104AA0000021286803F0D2FDE1B22846FCF740FE61
+:104AB0000020BDE8F08700000A30544F0A31544FFF
+:104AC0002DE9F84F07460E46D7F80090C84606EB8A
+:104AD000C60107F13C0000EB8104A169206A88420D
+:104AE00002D90120BDE8F88F216AA069451AE06863
+:104AF000A84200D2E568E81C4FEA900A17E0216A54
+:104B0000A069451AE068A84200D2E568E81C4FEAAF
+:104B1000900A387CABB2F2B200904846216904F0AA
+:104B200027FA206928442061206A2844206208F579
+:104B3000106000EB4610806980B2504506D3A16931
+:104B4000206A884202D2A0690028D8D1216AA069CF
+:104B500088420ED806F00F01012000FA01FB40F652
+:104B6000340050F8080020EA0B0040F6340141F808
+:104B700008000020B6E7014600BF080900EB8000EE
+:104B8000420001F00F001044C0B2704701460022FD
+:104B900004E0501CC2B2A1F10A00C1B20A29F8D245
+:104BA000100741EA1060704770B5044600260025E2
+:104BB0002068C06800F04000C8B92068C06840F0B4
+:104BC00080002168C860FCF759FC064608E0FCF745
+:104BD00055FC801BB0F57A7F02D90420607701254F
+:104BE0002068C06800F0400008B9012DEFD12846C8
+:104BF00070BD70B5044600252068C06820F08000B4
+:104C00002168C8602068806800F0200030B9204624
+:104C1000FEF762FA10B1042060770125284670BDC6
+:104C200010B5024600230868506248689062D1E9D6
+:104C3000020420430C6920434C6920430343D06A9B
+:104C400020F0F7001843D062002010BD014608692B
+:104C5000C0B270470146086800F003007047024682
+:104C600002F114004318186870470FB410B50446D9
+:104C70000021DDE903021043059A1043069A104310
+:104C8000079A1043089A10430143606847F6FF6291
+:104C9000904308436060002010BC5DF814FB01469F
+:104CA00003200860002070470146D1F8800070475B
+:104CB00010B50246002308689060D1E90104204342
+:104CC000CC6820430C6920430343D0686FF30B008A
+:104CD0001843D060002010BD70B585B005460C4665
+:104CE00000943720019040200290002003904FF460
+:104CF0008060049069462846FFF7DAFF41F2883267
+:104D00003721284600F0DCF90646304605B070BD74
+:104D100070B585B005460C460B482043009029200D
+:104D2000019040200290002003904FF48060049096
+:104D300069462846FFF7BCFF284600F0C9FA064638
+:104D4000304605B070BD00000000108070B585B021
+:104D500005460C460094102001904020029000204F
+:104D600003904FF48060049069462846FFF7A0FF47
+:104D700041F288321021284600F0A2F9064630465A
+:104D800005B070BD70B585B005460C460094062090
+:104D9000019040200290002003904FF48060049026
+:104DA00069462846FFF784FF41F2883206212846EB
+:104DB00000F086F90646304605B070BD30B585B0C6
+:104DC0000446002000900190029003904FF4806010
+:104DD000049069462046FFF76BFF204600F050F92B
+:104DE0000546284605B030BD30B585B004464FF4C1
+:104DF000D570009008200190402002900020039080
+:104E00004FF48060049069462046FFF751FF20462A
+:104E100000F0E6FA0546284605B030BD70B585B00D
+:104E200005460C460094122001904020029000207C
+:104E300003904FF48060049069462846FFF738FFDE
+:104E400041F288321221284600F03AF906463046EF
+:104E500005B070BD70B585B005460C4600941120B4
+:104E6000019040200290002003904FF48060049055
+:104E700069462846FFF71CFF41F288321121284677
+:104E800000F01EF90646304605B070BDF0B585B09D
+:104E9000064614461D4600940720019040200290CB
+:104EA000002003904FF48060049069463046FFF77D
+:104EB000FFFE41F288320721304600F001F9074633
+:104EC000384605B0F0BD30B585B0044600200090EE
+:104ED00002200190C0200290002003904FF48060D7
+:104EE000049069462046FFF7E3FE204600F0BEF935
+:104EF0000546284605B030BD70B585B005460C4660
+:104F0000009409200190C0200290002003904FF4EB
+:104F10008060049069462846FFF7CAFE284600F0E4
+:104F2000A5F90646304605B070BD30B585B00446DB
+:104F30000020009033200190402002900020039038
+:104F40004FF48060049069462046FFF7B1FE41F2BD
+:104F500088323321204600F0B3F80546284605B0D4
+:104F600030BD70B585B005460C4600940D2001900B
+:104F700040200290002003904FF480600490694626
+:104F80002846FFF795FE41F288320D21284600F0B1
+:104F900097F80646304605B070BD70B585B0054639
+:104FA0000C46002000900320019040200290002039
+:104FB00003904FF48060049069462846FFF778FE1E
+:104FC00022460321284600F0AFF90646304605B0D8
+:104FD00070BD000030B585B00446002000900C2064
+:104FE000019040200290002003904FF480600490D4
+:104FF00069462046FFF75CFE044A0C21204600F07B
+:105000005FF80546284605B030BD000000E1F50513
+:1050100070B585B005460C460094192001904020DB
+:105020000290002003904FF4806004906946284667
+:10503000FFF73EFE41F288321921284600F040F881
+:105040000646304605B070BD70B585B005460C46C5
+:1050500000941820019040200290002003904FF40B
+:105060008060049069462846FFF722FE41F28832AC
+:105070001821284600F024F80646304605B070BDD9
+:1050800001460E480068C0084FF47A73B0FBF3F095
+:1050900041F2883300FB03F200BF101EA2F10102AF
+:1050A00002D14FF000407047486B00F080000028AC
+:1050B000F3D0C52088630020F5E700001000002031
+:1050C0002DE9F04305460F46904666480068C00843
+:1050D0004FF47A71B0FBF1F000FB08F900BFB9F1B1
+:1050E0000000A9F1010903D14FF00040BDE8F083B1
+:1050F0006E6B06F045000028F1D006F40060002831
+:10510000EDD1686B00F0040010B10420A863EDE756
+:10511000686B00F0010010B10120A863E6E7C5202C
+:10512000A8632846FFF792FDB84201D00120DDE7D1
+:1051300000212846FFF793FD04464B48204008B95C
+:105140000020D3E704F00040B0F1004F02D14FF04F
+:105150000070CBE704F08040B0F1804F01D14020D7
+:10516000C4E704F00050B0F1005F01D18020BDE73A
+:1051700004F08050B0F1805F02D14FF48070B5E749
+:1051800004F00060B0F1006F02D14FF40070ADE7A1
+:1051900004F08060B0F1806F02D14FF48060A5E729
+:1051A00004F08070B0F1807F02D14FF400609DE781
+:1051B00004F40000B0F5000F02D14FF4805095E7E1
+:1051C00004F48000B0F5800F02D14FF400508DE759
+:1051D00004F40010B0F5001F02D14FF4804085E7C1
+:1051E00004F48010B0F5801F02D14FF400407DE739
+:1051F00004F48020B0F5802F02D14FF4003075E721
+:1052000004F40030B0F5003F02D14FF480206DE788
+:1052100004F48030B0F5803F02D14FF4002065E700
+:1052200004F40040B0F5004F02D14FF480105DE768
+:1052300004F48040B0F5804F02D14FF4001055E7E0
+:1052400004F40050B0F5005F02D14FF480004DE748
+:1052500004F00800082801D1000547E74FF480302A
+:1052600044E700001000002008E0FFFD10B50146F3
+:1052700016480068C0084FF47A74B0FBF4F041F2AD
+:10528000883400FB04F300BF181EA3F1010302D110
+:105290004FF0004010BD4A6B02F045000028F3D0EB
+:1052A00002F400600028EFD1486B00F0040010B158
+:1052B00004208863EEE7486B00F0010010B1012084
+:1052C0008863E7E7C52088630020E3E7100000203B
+:1052D00010B5014613480068C0084FF47A74B0FB5B
+:1052E000F4F041F2883400FB04F300BF181EA3F170
+:1052F000010302D14FF0004010BD4A6B02F045009F
+:105300000028F3D002F400600028EFD1486B00F0D1
+:10531000040010B104208863EEE7C52088630020F4
+:10532000EAE70000100000202DE9F04304460F4694
+:1053300090462A480068C0084FF47A71B0FBF1F03B
+:1053400041F2883100FB01F900BFB9F10000A9F179
+:10535000010903D14FF00040BDE8F083666B06F011
+:1053600045000028F1D006F400600028EDD1606B04
+:1053700000F0040010B10420A063EDE7606B00F0C2
+:10538000010010B10120A063E6E72046FFF75EFCB4
+:10539000B84201D00120DFE7C520A06300212046EC
+:1053A000FFF75DFC054605F4604020B9280CA8F81D
+:1053B00000000020D0E705F48040B0F5804F02D116
+:1053C0004FF40050C8E705F40040B0F5004F02D19B
+:1053D0004FF48050C0E74FF48030BDE7100000204C
+:1053E00010B5014618480068C0084FF47A74B0FB45
+:1053F000F4F041F2883400FB04F300BF181EA3F15F
+:10540000010302D14FF0004010BD4A6B02F045008D
+:105410000028F3D002F400600028EFD1486B00F0C0
+:10542000040010B104208863EEE7486B00F001002F
+:1054300010B101208863E7E7486B00F0400008B135
+:10544000402088630020DFE71000002010B50446EC
+:10545000012007490870FBF7CFFA28B90448007803
+:1054600020F00100024908700148007810BD0000DA
+:10547000D400002070B5044605F01AFD054604E08E
+:10548000FBF7BAFA08B9002070BD05F011FD401B0A
+:10549000A042F5D34FF0FF30F6E700002DE9F041D0
+:1054A0000646B46B3046FBF7DFFC02282CD0206C9C
+:1054B000476DE06BD0F85480012F02D0B8F1010F96
+:1054C0001FD11248216888632068C06B20F49D704A
+:1054D0002168C863A06B40F08040A0632046FDF7C0
+:1054E00076FF0546062D01D0052D05D12068FFF772
+:1054F00071FDA16B0843A063012084F834000020F3
+:1055000020632046FDF76AFEBDE8F081FF054000FC
+:1055100070B50646B46B206B82280AD12068FFF76D
+:1055200059FD05462DB1A06B2843A0632046FDF729
+:1055300055FE2068C06A20F008002168C86240F269
+:105540003A5021688863012084F8340000202063E9
+:105550002046FEF72BF970BD0146886B0268D26BBE
+:1055600042F480720368DA6370472DE9F04389B032
+:1055700004460F46FBF782FF81464FF000080020EB
+:10558000019002903E4608212068FFF7DFFB0546A8
+:105590001DB1284609B0BDE8F0835022125B11040A
+:1055A0002068FFF799FB05460DB12846F2E74FF05A
+:1055B000FF300390082004903020059002200690D0
+:1055C000002007900120089003A92068FFF728FB1E
+:1055D0002068FFF7AAFC05460DB12846DAE71CE073
+:1055E0002068406B00F4001040B12068FFF75CFBBE
+:1055F00001A941F8280008F1010805E02068406B86
+:1056000000F4005000B90EE0FBF738FFA0EB0900F2
+:10561000401C10B94FF00040BCE72068406B00F020
+:105620002A000028DCD000BF2068406B00F0080092
+:1056300018B1082021688863ACE72068406B00F04F
+:10564000020018B1022021688863A3E72068406B3C
+:1056500000F0200018B12020216888639AE740F20A
+:105660003A502168886302980006029901F47F414C
+:1056700040EA0120029901F47F0140EA11200299D9
+:1056800040EA11603060361D01980006019901F46E
+:105690007F4140EA0120019901F47F0140EA112095
+:1056A000019940EA11603060002073E730B58FB097
+:1056B0000446012003902068FFF7CCFA18B94FF098
+:1056C00080600FB030BD606C03281BD02068FFF7EE
+:1056D000FAFB05460DB12846F3E700212068FFF7E5
+:1056E000BEFA606704212068FFF7B9FAA0670821B5
+:1056F0002068FFF7B4FAE0670C212068FFF7AFFAE3
+:1057000080210851606C032807D003A92068FFF7A7
+:1057100044FC05460DB12846D3E7606C032820D031
+:10572000BDF80C1021655022125B11042068FFF7B0
+:10573000E3FB05460DB12846C3E700212068FFF7CB
+:105740008EFA606604212068FFF789FAA0660821B6
+:105750002068FFF784FAE0660C212068FFF77FFAE3
+:10576000206704212068FFF77AFA010DE16404A99B
+:105770002046FDF735FD10B14FF08050A1E75020D5
+:10578000005B01040A4600232068FFF77FFB054603
+:105790000DB1284695E7D4E90412A069CDE90012BD
+:1057A000029094E80F00FFF760FA002089E70000FC
+:1057B000F8B5044600200090002600272068FFF777
+:1057C000FDFA05460DB12846F8BD2068FFF70CFB31
+:1057D000054645B10021A1642068FFF7EFFA0546B0
+:1057E0001DB12846F0E70121A164A06C012808D171
+:1057F00000212068FFF770FA054615B14FF0805080
+:10580000E2E71DE000212068FFF766FA05460DB1CA
+:105810002846D9E718492068FFF77AFA054615B1F6
+:105820004FF08050D0E700212068FFF718FA0646B5
+:10583000012080EAD67080F001070098401C00909B
+:105840004FF6FF710098884201D2002FDAD04FF650
+:10585000FF710098884202D34FF08070B4E706F0E1
+:105860008040B0F1804F02D10120606401E000204F
+:1058700060640020A8E70000000010C170B5044675
+:105880000D4615B94FF0006070BD5022125B110437
+:105890002068FFF766FB06460EB13046F4E70021AC
+:1058A0002068FFF7DCF928600020EDE77CB50446AE
+:1058B00000200090019000212068FFF7D0F900F04F
+:1058C0000070B0F1007F02D14FF400607CBD6946EA
+:1058D0002046FFF74AFE05460DB12846F6E7019837
+:1058E00000F4803098B15022125B11042068FFF759
+:1058F000F3F905460DB12846E8E700212068FFF7D7
+:1059000041FA05460DB12846E0E70020DEE74FF0FA
+:105910008060DBE77CB50446002000900190002108
+:105920002068FFF79CF900F00070B0F1007F02D111
+:105930004FF400607CBD69462046FFF716FE054621
+:105940000DB12846F6E7019800F4802098B1502266
+:10595000125B11042068FFF7BFF905460DB1284618
+:10596000E8E702212068FFF70DFA05460DB1284649
+:10597000E0E70020DEE74FF08060DBE71FB504467C
+:1059800001201649087005F085FA10B3FBF740F8BE
+:1059900020B92046FFF75AFD104908700F480078DB
+:1059A000012816D00E48006850B90E4B0FCB8DE879
+:1059B0000F000021684605F085FA0949086000BF1C
+:1059C0000748006828B90548007840F001000349FD
+:1059D00008700248007804B010BD0000D400002018
+:1059E000D80000208C2F0108F0B589B007460D467D
+:1059F000144601261648007800F0010010B103207B
+:105A000009B0F0BD35B1012D06D0022D0BD0032D0C
+:105A100018D10FE0002617E001A8FAF7E3FF079876
+:105A20002060002610E001A8FAF7DCFF089820802B
+:105A3000002609E001A8FAF7D5FF0898400A20607F
+:105A4000002601E0042600BF00BF3046D8E7000072
+:105A5000D40000202DE9F04786B082460E46174656
+:105A600098464FF0010947F23050FFF703FD002838
+:105A700003DA484606B0BDE8F0874246394630466C
+:105A8000FAF7EAFF044614BB47F2305211480168A6
+:105A9000684605F02BFA9DE8070003AB07C303989F
+:105AA000102814D10498012811D105F001FA0546F7
+:105AB00005E0FAF7A1FF10B94FF0000906E005F084
+:105AC000F7F9401B47F230518842F2D300BF4846F5
+:105AD000D0E70000D800002010B504462046FFF7AC
+:105AE000B5FC10BD2DE9F04387B081460D46164642
+:105AF0001F464FF0010847F23050FFF7BBFC00286B
+:105B000003DA404607B0BDE8F0833A4631462846FE
+:105B1000FAF7C0FF10BB47F230521148016801A8E4
+:105B200005F0E4F901A807C804AB07C304981028DE
+:105B300014D10598022811D105F0BAF9044605E000
+:105B4000FAF75AFF10B94FF0000806E005F0B0F977
+:105B5000001B47F230518842F2D300BF4046D1E7E4
+:105B6000D80000207CB504460D461646164800684D
+:105B70001821B0FBF1F01549B0FBF1F04FF47A7148
+:105B8000484301906068B0F5827F0DD12B4600221A
+:105B900080212046009600F01BF898B1606D40F01F
+:105BA0002000606503207CBD00BF019800B908E0BB
+:105BB0000198401E019020688068C0F3C010002842
+:105BC000F3D100BF0020EEE71000002040420F009C
+:105BD0002DE9F84F04460D4690461E46DDF8289004
+:105BE000FBF74CFCA0EB0900371AFBF747FC824699
+:105BF0002C480068C0F3CB307843009045E0701C1F
+:105C0000002842D0FBF73AFCA0EB0A00B84200D2D1
+:105C1000A7BB2068406820F0E00021684860606809
+:105C2000B0F5827F0DD1A068B0F5004F03D0A06819
+:105C3000B0F5806F05D12068006820F04000216831
+:105C40000860A06AB0F5005F0DD100BF2068006851
+:105C500020F40050216808602068006840F400507B
+:105C60002168086000BF012084F8510000BF0020B7
+:105C700084F8500000BF0320BDE8F88FFFE70098CC
+:105C800000B900270098401E0090206880682840D6
+:105C9000A84201D1012000E000204045AFD1002002
+:105CA000EAE700001000002030B501460A461378EC
+:105CB000521C147843EA042030BDFEF7FBFD00BF00
+:105CC000012005F0DBF8FBE710B500BF502080F3A2
+:105CD0001188BFF34F8FBFF36F8F00BF0CF07EFEB4
+:105CE00018B14FF080500449086000BF002080F3D5
+:105CF000118800BF10BD000004ED00E000B593B0B6
+:105D0000302107A8FAF747FB142102A8FAF743FB52
+:105D100000BF002001902548006840F080502349D2
+:105D200008600846006800F08050019000BF00BF86
+:105D300000BF002001901E48006840F480401C49CC
+:105D400008600846006800F48040019000BF00BF72
+:105D5000052007904FF48030089001200990022020
+:105D60000D9041050E9104210F91A821109102215F
+:105D700011910721129107A8FCF7BCFD08B1FAF7B1
+:105D8000B9FF0F20029002200390002004904FF4EE
+:105D9000A05005904FF480500690052102A8FCF712
+:105DA00047FC08B1FAF7A6FF13B000BD4038024027
+:105DB000007000400348006840F47000014908602A
+:105DC0007047000088ED00E010B501200549D1F8CA
+:105DD000BC100144034AC2F8BC1000BF0248FDF7E2
+:105DE000DEFF10BD4C2801206807002010B50268B6
+:105DF000294B98420ED0B0F1804F0BD0274B9842E0
+:105E000008D0274B984205D0264B984202D0264B0B
+:105E1000984203D122F070024B681A431E4B9842FD
+:105E200020D0B0F1804F1DD01C4B98421AD01C4B93
+:105E3000984217D01B4B984214D01B4B984211D05C
+:105E40001A4B98420ED01A4B98420BD0194B9842DD
+:105E500008D0194B984205D0184B984202D0184BE5
+:105E6000984203D122F44072CB681A4322F0800397
+:105E70004C6943EA040202608B68C3620B68836268
+:105E8000054B984202D0084B984201D10B6903633D
+:105E90000123436110BD00000000014000040040E8
+:105EA00000080040000C0040000401400040014098
+:105EB000004401400048014000180040001C004020
+:105EC0000020004070B50546AC6B0020E085E08402
+:105ED0002046FEF73FF870BD70B506460025B46B4E
+:105EE00020684069C0F3C01594F83D00212805D111
+:105EF00025B10020E084204600F0C4F82068406905
+:105F0000C0F3801594F83E00222805D125B1002069
+:105F1000E085204600F070F8206C40F0100020640E
+:105F20002046FEF717F870BD70B50546AC6B2868C3
+:105F3000006800F48070002842D1E08500BF00BFF7
+:105F400021680C3151E8001F21F4807021680C3168
+:105F500041E80002002AF3D100BF00BF00BF216862
+:105F6000143151E8001F21F001002168143141E88B
+:105F70000002002AF3D100BF00BF00BF2168143126
+:105F800051E8001F21F040002168143141E800026F
+:105F9000002AF3D100BF202084F83E00206B0128A6
+:105FA0000ED100BF00BF21680C3151E8001F21F065
+:105FB000100021680C3141E80002002AF3D100BF33
+:105FC000206B012804D1A18D2046FDF7C2FF02E01D
+:105FD0002046FEF71AFA70BD70B50546AC6B206B13
+:105FE000012805D1A08D41082046FDF7B2FF02E04F
+:105FF0002046FEF70BFA70BD00BF00BF02680C32EE
+:1060000052E8002F22F4907102680C3242E800132B
+:10601000002BF3D100BF00BF00BF0268143252E86A
+:10602000002F22F001010268143242E80013002B15
+:10603000F3D100BF016B01290ED100BF00BF026880
+:106040000C3252E8002F22F0100102680C3242E8B4
+:106050000013002BF3D100BF202180F83E10002157
+:106060000163704710B504462068C06820F0400006
+:106070002168C860202084F83D002046FEF730FAF1
+:10608000002010BD00BF00BF02680C3252E8002F94
+:1060900022F0C00102680C3242E80013002BF3D159
+:1060A00000BF202180F83D107047F8B5044694F8F1
+:1060B0003E00222873D1A068B0F5805F0CD1206922
+:1060C00050B90025A66A20684068C0F308003080F7
+:1060D000A06A801CA06215E0A56A0026A068B0F541
+:1060E000805F03D0A06828B9206918B9206840688B
+:1060F000287004E02068406800F07F002870A06AE3
+:10610000401CA062E08D401E80B2E085002844D192
+:106110002068C06820F020002168C8602068C0683E
+:1061200020F480702168C8602068406920F0010078
+:1061300021684861202084F83E00206B012826D188
+:106140000020206300BF00BF21680C3151E8001F10
+:1061500021F0100021680C3141E80002002AF3D13F
+:1061600000BF2068006800F0100010280AD100BFAE
+:10617000002000902068006800902068406800902F
+:1061800000BF00BFA18D2046FDF7E3FE02E02046E0
+:10619000FEF73BF90020F8BD01E00020FBE70220FC
+:1061A000F9E700002DE9F84F04462068006920F463
+:1061B0004050E1680843216808612169A0680843EC
+:1061C00061690843E169084300902068C06849F2AA
+:1061D0000C618843009908432168C86020684069C1
+:1061E00020F44070A169084321684861764920681D
+:1061F000884203D075492068884203D1FCF712FB1E
+:10620000814602E0FCF7FEFA8146E069B0F5004FF6
+:106210006CD102206168A0FB015003461920A9FB44
+:10622000007001462A463846FAF72CF86421B0FB84
+:10623000F1F04FEA001A02206168A0FB01510B4601
+:106240001920A9FB00712A463846FAF71BF8834645
+:1062500002206168A0FB015003461920A9FB0071D0
+:106260002A463846FAF70EF86421B0FBF1F000EB4D
+:10627000C00101EB0010ABEB8000322101EBC0004C
+:106280006421B0FBF1F000F0F8000AEB400A0220B4
+:106290006168A0FB015003461920A9FB007001466C
+:1062A0002A463846F9F7EEFF834602206168A0FBD4
+:1062B000015003461920A9FB00712A463846F9F718
+:1062C000E1FF6421B0FBF1F000EBC00101EB001035
+:1062D000ABEB8000322101EBC0006421B0FBF1F098
+:1062E00000F007005044216888606AE0042061687B
+:1062F000A0FB015003461920A9FB007001462A4665
+:106300003846F9F7BFFF824604206168A0FB0150C0
+:1063100003461920A9FB007001462A463846F9F7C2
+:10632000B1FF6421B0FBF1F000EBC00101EB001004
+:10633000AAEB8000322101EB00106421B0FBF1F0E8
+:1063400000F0F00A04206168A0FB017003461920E8
+:10635000A9FB00513A462846F9F794FF6421B0FBA7
+:10636000F1F00AEB001A04206168A0FB01510B4612
+:106370001920A9FB00712A463846F9F783FF8346A6
+:1063800004206168A0FB015003461920A9FB00709E
+:1063900001462A463846F9F775FF6421B0FBF1F053
+:1063A00000EBC00101EB0010ABEB8000322101EBF0
+:1063B00000106421B0FBF1F000F00F0050442168A0
+:1063C0008860BDE8F88F0000001001400014014013
+:1063D00077B581B0044615460298A062A5850020D5
+:1063E0002064222084F83E002A48A16BC8632A4812
+:1063F000A16B08642948A16BC8640020A16B0865E3
+:1064000002AE32682368191D2B46A06BFAF7C6FE50
+:1064100000BF00200090206800680090206840685D
+:10642000009000BF00BF00BF002084F83C0000BF08
+:10643000206970B100BF00BF21680C3151E8001F16
+:1064400041F4807021680C3141E80002002AF3D148
+:1064500000BF00BF00BF2168143151E8001F41F0A8
+:1064600001002168143141E80002002AF3D100BF85
+:1064700000BF00BF2168143151E8001F41F0400007
+:106480002168143141E80002002AF3D100BF002046
+:1064900004B070BD295F0008D95F0008D95E00080C
+:1064A000014691F83D00212828D18868B0F5805F29
+:1064B0000BD1086948B90A6A1088C0F308000B6854
+:1064C0005860086A801C086205E00B6A581C086264
+:1064D00018780B685860C88C401E80B2C88458B9C0
+:1064E0000868C06820F080000B68D8600868C06841
+:1064F00040F040000B68D860002070470220FCE7A5
+:106500002DE9F04104460D4617469846069E34E0B4
+:10651000701C88B32EB1FAF7B1FFA0EB0800B042AF
+:106520002BD900BF00BF21680C3151E8001F21F4B6
+:10653000D07021680C3141E80002002AF3D100BF7D
+:1065400000BF00BF2168143151E8001F21F0010095
+:106550002168143141E80002002AF3D100BF202055
+:1065600084F83D0084F83E0000BF002084F83C0021
+:1065700000BF0320BDE8F081FFE7206800682840E5
+:10658000A84201D1012000E00020B842C0D0002084
+:10659000F0E7000008B50D480068006800F0100042
+:1065A00010280ED100BF0020009008480068006845
+:1065B0000090064800684068009000BF00BF0AF0E5
+:1065C000F3FE0248FDF7C8FC08BD00006406002089
+:1065D0002DE9F04104460D46D4F8C87204F5307038
+:1065E000D4F8D41250F8210010B90320BDE8F0818E
+:1065F00004F53070D4F8D41250F8216005F00F0083
+:1066000000EB800104F1140000EB8100406838B316
+:1066100005F00F0000EB800104F1140000EB810095
+:10662000416805F00F0000EBC00207F13C0000EBF1
+:106630008200C068B1FBF0F200FB121080B90021AB
+:1066400005F00F0000EB800204F1140000EB820063
+:10665000416000231A462946204601F02CF917E034
+:106660000020C6F8140204F53170D4F8D41250F8A2
+:106670002100006960B1D6F8080204F53171D4F840
+:10668000D42251F822102A460B6906F50471984766
+:106690000020ABE770B504460E4604F53070D4F820
+:1066A000D41250F82150D4F8D41250F8210008B96F
+:1066B000032070BD3146204600F059FFC5F80C029A
+:1066C000D5F8040204F53171D4F8D43251F823100E
+:1066D000CA6805F5037190470020EAE770B50446E3
+:1066E0000D4630480178204600F013FE00212D4869
+:1066F000007800F00F0000EB800204F1140000EBC2
+:106700008200018228480178204600F002FE002124
+:106710002548007800F00F0000EB800204F5AA7015
+:1067200000EB8200018221480178204600F0F1FD53
+:1067300000211E48007800F00F0000EB800204F1F9
+:10674000140000EB820001821848007800F00F006E
+:1067500000EB800204F1140000EB8200418204F59A
+:106760003070D4F8D41250F82100C8B104F531715A
+:10677000D4F8D42251F822104868804704F53071CB
+:10678000D4F8D42251F8220001F0BEFB002104F518
+:106790003070D4F8D42240F822100020C4F8BC0293
+:1067A000002070BDD3010020D4010020D5010020BD
+:1067B00070B5044604F53070D4F8D41250F8215066
+:1067C0000DB9032070BD04F53170D4F8D41250F81F
+:1067D000210098B195F80002FF280FD095F801220A
+:1067E00095F8000204F53171D4F8D46251F82610FE
+:1067F0008B6829469847FF2085F800020020E1E7D2
+:1068000001460A2008800148704700004C01002022
+:106810002DE9F041044682210D4800F0A0FC054618
+:1068200001210B4800F09BFC06468121084800F03E
+:1068300096FC07460DB11020A8710EB14020B08023
+:106840000FB14020B880432020800148BDE8F0818E
+:10685000900100202DE9F041044682210E4800F00D
+:106860007EFC054601210C4800F079FC064681219A
+:10687000094800F074FC07460DB11020A87116B14C
+:106880004FF40070B08017B14FF40070B88043200F
+:1068900020800148BDE8F081900100202DE9F04101
+:1068A000044682210D4800F05AFC054601210B48A0
+:1068B00000F055FC06468121084800F050FC0746D0
+:1068C0000DB11020A8710EB14020B0800FB1402052
+:1068D000B880432020800148BDE8F081900100206D
+:1068E00070B504460E464FF4077001F00FFB0546E5
+:1068F00045B9002104F53070D4F8D42240F82210B4
+:10690000022070BD4FF407712846F9F744FD04F5E5
+:106910003070D4F8D41240F82150D4F8D41250F882
+:106920002100C4F8BC02207C98BB4FF40073022203
+:1069300050480178204600F0BBFE01214D48007808
+:1069400000F00F0000EB800204F1140000EB820065
+:1069500001824B02022248480178204600F0A8FE3E
+:1069600001214548007800F00F0000EB800204F59B
+:10697000AA7000EB8200018210214048007800F0EC
+:106980000F0000EB800204F1140000EB8200418252
+:1069900032E0FFE74023022236480178204600F02B
+:1069A00087FE01213348007800F00F0000EB8002E1
+:1069B00004F1140000EB82000182402302222E48E1
+:1069C0000178204600F074FE01212B48007800F089
+:1069D0000F0000EB800204F5AA7000EB8200018238
+:1069E00010212648007800F00F0000EB800204F12F
+:1069F000140000EB82004182082303221F48017823
+:106A0000204600F055FE01211C48007800F00F00E0
+:106A100000EB800204F1140000EB820001820020F0
+:106A2000C5F8040204F53171D4F8D42251F82210CB
+:106A3000086880470020C5F81402C5F81802D5F888
+:106A4000040208B902205CE7207C48B94FF40073C7
+:106A5000094801782046D5F8042200F041FE07E0FD
+:106A60004023054801782046D5F8042200F038FE7E
+:106A7000002046E7D3010020D4010020D5010020EA
+:106A800070B5044604F53070D4F8D41250F8215093
+:106A9000D4F8D41250F8210008B9032070BD207C2E
+:106AA00048B94FF40073094801782046D5F804220C
+:106AB00000F016FE07E04023044801782046D5F890
+:106AC000042200F00DFE0020E8E70000D4010020C1
+:106AD000024609B90320704702F53170D2F8D4326A
+:106AE00040F823100020F6E710B5024602F530709A
+:106AF000D2F8D44250F824300BB9032010BDC3F8AB
+:106B000004120020FAE730B503460C4603F5307056
+:106B1000D3F8D45250F8251009B9032030BDC1F87C
+:106B20000842C1F810220020F8E72DE9FC41054693
+:106B30000C4605F53070D5F8D41250F821600020CD
+:106B400001900090804616B90320BDE8FC812078B2
+:106B500000F0600000283DD020287CD1E08868B398
+:106B6000207800F08000B8B1E288607805F53171D6
+:106B7000D5F8D4C251F82C108B6831469847E0887C
+:106B8000072801D9072000E0E08807463A46314649
+:106B9000284600F015F91CE0607886F80002E088CD
+:106BA000402801D2E08800E0402086F8010296F8F3
+:106BB00001223146284600F0E2F80AE0607805F547
+:106BC0003171D5F8D42251F8221000228B68214669
+:106BD000984747E0607830B1012832D00A2813D0B6
+:106BE0000B282FD121E095F89C02032805D1022221
+:106BF0006946284600F0E4F805E02146284600F002
+:106C0000B2F84FF0030824E095F89C02032805D160
+:106C1000012201A9284600F0D3F805E021462846C4
+:106C200000F0A1F84FF0030813E095F89C02032848
+:106C300005D02146284600F096F84FF0030808E0FA
+:106C400009E006E02146284600F08DF84FF00308E1
+:106C500000BF00BF06E02146284600F084F84FF050
+:106C6000030800BF00BF40466FE7000070B5044650
+:106C700004F53070D4F8D41250F821500126D4F81D
+:106C8000D41250F8210008B9032070BDD5F81402C1
+:106C9000C8B90120C5F814020C48007800F00F00B4
+:106CA00000EB800204F1140000EB8200D5F8101212
+:106CB0004160064801782046D5F81032D5F8082200
+:106CC00000F0F9FD00263046DFE70000D301002088
+:106CD00070B504460D460026D4F8B802294642682D
+:106CE0002046904700B10326304670BD70B504467B
+:106CF0000D4694F89C02012804D0022803D00328F2
+:106D00000CD101E000BF00BF6888012805D1002038
+:106D1000C4F8A402204600F064F804E029462046A6
+:106D200000F021F800BF00BF70BD02460020704790
+:106D300002460020704770B506460C4615462B46A5
+:106D400022460021304600F0CBFC002070BD70B51B
+:106D500006460C4615462B4622460021304600F0DA
+:106D6000AAFD002070BD70B504460D468021204666
+:106D700000F075FD0021204600F071FD70BD70B57A
+:106D800004460E4615460320C4F894024FF4AC7036
+:106D90000551001D05512B4632460021204600F0CA
+:106DA0009FFC002070BD10B504460520C4F8940275
+:106DB00000231A461946204600F092FC002010BD20
+:106DC00070B504460E4615460220C4F89402A5612B
+:106DD000E5612B4632460021204600F06CFD002084
+:106DE00070BD10B504460420C4F8940200231A466E
+:106DF0001946204600F05FFD002010BD70B5054625
+:106E00000C462DB92246064906A000F012FA04E00D
+:106E10002246034903A000F00CFA014870BD0000AF
+:106E20000C0B012043444320436F6E6669670000EA
+:106E3000024612200880014870470000000100202F
+:106E400070B505460C462DB92246064906A000F04D
+:106E5000F0F904E02246034903A000F0EAF90148F2
+:106E600070BD00000C0B012043444320496E746543
+:106E700072666163650000000246042008800148D4
+:106E8000704700001401002070B505460C462246EC
+:106E9000024903A000F0CDF9004870BD0C0B0120A1
+:106EA00053544D6963726F656C656374726F6E697C
+:106EB0006373000070B505460C462DB9224606499D
+:106EC00006A000F0B6F904E02246034903A000F052
+:106ED000B0F9014870BD00000C0B012053544D3334
+:106EE00032205669727475616C20436F6D506F72F9
+:106EF0007400000070B505460C461A202080F9F792
+:106F00002FFF014870BD00001801002070B5044635
+:106F10000D46E888012804D029462046FFF723FFC4
+:106F20001EE094F89C02012804D0022803D0032814
+:106F300010D109E000BF0020A060012204F1080187
+:106F40002046FFF73DFF0AE00122211D2046FFF702
+:106F500037FF04E029462046FFF705FF00BF00BFCA
+:106F600070BDF8B504460E460020009000270025AD
+:106F700070880012082875D2DFE800F0C7040C20E2
+:106F8000C7C7A5B5207CD4F8B4120A6869469047F3
+:106F90000746C1E0207C40B9D4F8B802816A68464F
+:106FA000884707460220787007E0D4F8B802C16A23
+:106FB00068468847074602207870ADE0B07806281A
+:106FC00078D2DFE800F00316293C5063D4F8B4020D
+:106FD000406838B1207CD4F8B4124A6869469047BA
+:106FE000074605E031462046FFF7BDFE681CC5B2E6
+:106FF00067E0D4F8B402806838B1207CD4F8B412C9
+:107000008A6869469047074605E031462046FFF703
+:10701000AAFE681CC5B254E0D4F8B402C06838B106
+:10702000207CD4F8B412CA6869469047074605E048
+:1070300031462046FFF797FE681CC5B241E0D4F800
+:10704000B402006938B1207CD4F8B4120A696946E8
+:107050009047074605E031462046FFF784FE681C4E
+:10706000C5B22EE051E0D4F8B402406938B1207CBA
+:10707000D4F8B4124A6969469047074605E031469C
+:107080002046FFF770FE681CC5B21AE0D4F8B402BF
+:10709000806940B1207CD4F8B4128A69694690476F
+:1070A000074606E006E031462046FFF75CFE681C16
+:1070B000C5B206E031462046FFF755FE681CC5B252
+:1070C00000BF00BF28E0207C30B9D4F8B802416B83
+:1070D00068468847074605E031462046FFF743FEED
+:1070E000681CC5B218E0207C40B9D4F8B802016B26
+:1070F0006846884707460720787005E031462046F5
+:10710000FFF731FE681CC5B206E031462046FFF7A6
+:107110002AFE681CC5B200BF00BF05B1F8BDF088EB
+:10712000C0B1BDF8000080B1F088BDF80010884201
+:1071300002DDBDF8000000E0F0880090BDF80020FE
+:1071400039462046FFF73CFE07E031462046FFF770
+:107150000AFE02E02046FFF744FE00BFDEE72DE90D
+:10716000F84105460F462C462E464FF00008708821
+:107170003178884218DD307800900FE0694620466B
+:1071800000F020F804466078052807D1A04698F85A
+:107190000200B84200D106E04FF000087088BDF848
+:1071A00000108842EADC00BF4046BDE8F881014695
+:1071B00000200A4602E0431CD8B2521C1378002B70
+:1071C000F9D1704710B5024610460B880478234465
+:1071D0000B800378981810BD70B504460D4694F8DE
+:1071E0009C02012804D0022803D003281AD101E010
+:1071F00000BF00BFE888022804D029462046FFF7D8
+:10720000B2FD14E00120E060D4F8A40218B1E068F7
+:1072100040F00200E060022204F10C012046FFF77A
+:10722000CFFD04E029462046FFF79DFD00BF00BFCB
+:1072300070BD2DE9F04107460D46904600240FB978
+:10724000BDE8F0813E463046FFF7B1FF022101EB79
+:107250004000A8F8000098F800002855601CC4B24F
+:1072600003202855601CC4B208E030782855761CED
+:10727000601CC4B200202855601CC4B230780028BD
+:10728000F3D100BFDCE70146002031B1012906D06F
+:10729000022906D0032908D105E0002007E00320D9
+:1072A00005E0012003E0032001E0032000BF00BF50
+:1072B00070472DE9F04104460D46164614B90320E7
+:1072C000BDE8F0810020C4F8B802C4F8C402C4F8D4
+:1072D000D0020DB1C4F8B452012084F89C0226708B
+:1072E000204600F04DF907463846E9E72DE9F04120
+:1072F00004460D46002600272946D4F8C802FAF7AE
+:1073000084FA06463046FFF7BEFF07463846BDE81A
+:10731000F0812DE9F04104460D460026002729465C
+:10732000D4F8C802FAF73CFA06463046FFF7ABFF3E
+:1073300007463846BDE8F0812DE9F04704460F4680
+:107340009146002F56D104F11405D4F89402022876
+:1073500046D1D5E9020188420FD9D5E90201401A88
+:10736000A86049462046AA68FFF7F1FC00231A46A8
+:107370001946204600F0B4F932E0D5E902108842FF
+:1073800017D1E9686868884213D36868D4F89812FE
+:1073900088420ED2002211462046FFF7D8FC00207A
+:1073A000C4F8980200231A461946204600F098F9BE
+:1073B00016E094F89C0203280BD1D4F8B802C068F8
+:1073C00038B10020C4F8D402D4F8B802C16820460D
+:1073D00088478021204600F042FA2046FFF7E3FC70
+:1073E00094F8A00250B3204600F0BCFA002084F8C4
+:1073F000A00223E047F080012046FFF796FC0646F6
+:10740000FF2E1BD0D6B994F89C02032816D104F5A0
+:107410002E7050F82600406980B1C4F8D46204F59B
+:107420002E7050F826003946426920469047804623
+:10743000B8F1000F02D04046BDE8F0870020FBE71E
+:107440002DE9F04705460F4690464FF00009002F02
+:1074500051D105F5AA76D5F8940203286FD1D6E963
+:107460000201884210D9D6E90201401AB060D6E97B
+:107470000201884201D2B06800E0F068024641464D
+:107480002846FFF758FC5AE095F8AA0200F01F00C2
+:1074900020B1012804D0022812D109E0002411E013
+:1074A00040F2AE20415D2846FFF742FC044609E069
+:1074B00040F2AE20415D2846FFF737FC044601E06C
+:1074C000002400BF00BF94B995F89C0203280ED198
+:1074D00005F52E7050F82400006940B1C5F8D4427B
+:1074E00005F52E7050F82400016928468847284683
+:1074F000FFF777FC23E007F07F012846FFF715FC34
+:107500000446FF2C1BD0D4B995F89C02032810D157
+:1075100005F52E7050F82400806950B1C5F8D442AA
+:1075200005F52E7050F824003946826928469047A8
+:107530008146B9F1000F02D04846BDE8F08700202F
+:10754000FBE701460020704770B504460025012086
+:1075500084F89C02D4F8B80238B12179D4F8B80282
+:1075600042682046904700B10325284670BD70B59B
+:1075700004460D462946D4F8C802FAF784F970BDCE
+:1075800010B50446207800282AD11648C0F80845CE
+:10759000C4F8C8024FF0A0401249086004204860B7
+:1075A00002211048C1600021016102218161002196
+:1075B000C16101624162C1620163FAF7CAFD08B1AB
+:1075C000F9F798FB80210748FAF76FF8402200216D
+:1075D0000448FAF76FF8802201210248FAF76AF8A6
+:1075E000002010BD0C1D012010B50246D2F8C83293
+:1075F00001F08000802809D101F07F0000EBC00479
+:1076000003F13C0000EB8400807810BD01F07F00A6
+:1076100000EBC00403F51F7000EB84008078F4E7F2
+:1076200070B504460D4604F52E70D4F8D41250F807
+:10763000210008B9032070BD94F89C02032811D1E1
+:1076400004F52E70D4F8D41250F82100006A48B125
+:1076500004F52E70D4F8D41250F821002946026A9D
+:10766000204690470020E6E770B504460D4604F535
+:107670002E70D4F8D41250F8210008B9032070BD40
+:1076800094F89C02032811D104F52E70D4F8D4127A
+:1076900050F82100406A48B104F52E70D4F8D41295
+:1076A00050F821002946426A204690470020E6E72C
+:1076B0002DE9F04704460F4615461E464FF00008D8
+:1076C000C1462B4632463946D4F8C802FAF7E6F8E6
+:1076D00080464046FFF7D7FD81464846BDE8F08723
+:1076E0002DE9F04704460D4616461F464FF00008A8
+:1076F000C1463B4632462946D4F8C802FAF714F987
+:1077000080464046FFF7BFFD81464846BDE8F0870A
+:1077100070B504460025012084F89C020020C4F8BE
+:1077200094026060C4F8A40284F8A002D4F8B802FD
+:1077300058B1D4F8B802406838B12179D4F8B80209
+:1077400042682046904700B103254023002211469D
+:107750002046FFF7ADFF01214FF4B27001534021E5
+:10776000001F01514023002280212046FFF7A0FF87
+:107770000121A18440212162284670BD014691F873
+:107780009C02042803D191F89D0281F89C020020FC
+:10779000704710B5044694F89C0203280BD1D4F826
+:1077A000B80240B1D4F8B802C06920B1D4F8B80228
+:1077B000C16920468847002010BD02461174002090
+:1077C00070472DE9F04104460D4600260027294662
+:1077D000D4F8C802FAF7EAFD06463046FFF753FD33
+:1077E00007463846BDE8F08170B504460D46294687
+:1077F00004F2AA2000F077F80120C4F894024FF4B4
+:107800002C70005BC4F8980294F8AA0200F01F00E4
+:1078100020B1012809D0022815D10DE004F2AA21D7
+:10782000204600F083F9064616E004F2AA2120461D
+:1078300000F013FB06460FE004F2AA21204600F0F8
+:10784000CCF9064608E094F8AA0200F08001204630
+:1078500000F005F8064600BF00BF304670BD2DE9B8
+:10786000F04104460D46002600272946D4F8C802F8
+:10787000FAF786F806463046FFF705FD0746384614
+:10788000BDE8F08170B5044600250026D4F8C80292
+:10789000FAF7B0FD05462846FFF7F5FC06463046E8
+:1078A00070BD014691F89C0281F89D02042081F888
+:1078B0009C02002070472DE9F04704460D4616460D
+:1078C0001F464FF00008C1463B4632462946D4F8D1
+:1078D000C802FAF79AF880464046FFF7D4FC814682
+:1078E0004846BDE8F08770B505460E463446207818
+:1078F0002870641C20786870641C2046FEF7D4F958
+:107900006880641C641C2046FEF7CEF9A880641CC5
+:10791000641C2046FEF7C8F9E88070BD38B50446FF
+:107920000D46002000900DB9032038BDC4F8B852B0
+:1079300004F52E70D4F8D41250F82100C06A50B16A
+:1079400004F52E70D4F8D42250F82200C16A68469B
+:107950008847C4F8D002D4F8D802401CC4F8D80232
+:107960000020E2E701460020704770B504460D464E
+:10797000A88810BBE88800BB688880281DD2A8783A
+:1079800000F07F0694F89C02032804D12946204683
+:10799000FFF7E9F915E084F89E6231462046FFF7CB
+:1079A00010FF2046FFF71DFA1EB1022084F89C024A
+:1079B00007E0012084F89C0203E029462046FFF7F7
+:1079C000D2F970BD70B504460D460026D4F8B80251
+:1079D00030B1D4F8B80229460268204690470646DE
+:1079E000304670BD70B504460E460025B0783D495E
+:1079F000087008460078012805D931462046FFF76F
+:107A0000B2F9032070BD94F89C02022802D003282A
+:107A100059D11FE033480078C0B132480078606027
+:107A2000304801782046FFF7CDFF05463DB131468D
+:107A30002046FFF798F9022084F89C0209E02046CE
+:107A4000FFF7CFF9032084F89C0202E02046FFF7FD
+:107A5000C8F943E02348007870B9022084F89C02FA
+:107A60002048007860601F4801782046FFF730F911
+:107A70002046FFF7B6F925E01A4909786068884280
+:107A80001DD021792046FFF723F916480078606061
+:107A9000144801782046FFF795FF05465DB1314651
+:107AA0002046FFF760F921792046FFF711F90220FF
+:107AB00084F89C0206E02046FFF793F902E0204696
+:107AC000FFF78FF90AE031462046FFF74CF90548E9
+:107AD00001782046FFF7FCF8032500BF00BF2846C9
+:107AE00090E700004801002070B505460C4660880C
+:107AF000012805D1C5F8A4022846FFF772F90EE067
+:107B00006088022807D1A088001285F8A0022846C4
+:107B1000FFF767F903E021462846FFF724F970BD17
+:107B200010B504462046FFF7ADFE10BD70B5044603
+:107B30000D460026287800F0600088B1202802D089
+:107B4000402842D100E000BF04F52E70D4F8D412D2
+:107B500050F821002946826820469047064639E0C1
+:107B600068780A282AD2DFE800F01A24291F290A97
+:107B70000529150F29462046FFF7F3F923E029468A
+:107B80002046FFF7F2FE1EE029462046FFF72AFFB7
+:107B9000064618E029462046FFF7B8F913E02946C3
+:107BA0002046FFF719FB0EE029462046FFF79CFF11
+:107BB00009E029462046FFF799F804E029462046C7
+:107BC000FFF7D1F800BF00BF04E029462046FFF7C9
+:107BD000CAF800BF00BF304670BD2DE9F04705462A
+:107BE0000F464FF000093C79387800F06000F8B19A
+:107BF000202802D040287DD100E000BF2146284641
+:107C0000FFF793F80646FF2E11D086B9C5F8D46267
+:107C100005F52E7050F82600806840B105F52E70ED
+:107C200050F826003946826828469047814610E180
+:107C3000787800287AD001282FD003286ED195F8C3
+:107C40009C02022802D0032820D110E054B1802CDD
+:107C500008D021462846FFF702FE80212846FFF77C
+:107C6000FEFD03E039462846FFF77DF813E07888EB
+:107C700040B93CB1802C05D0F88818B92146284677
+:107C8000FFF7EDFD2846FFF7ACF804E0394628463B
+:107C9000FFF769F800BF00BFD4E095F89C02022806
+:107CA00002D003283BD110E054B1802C08D02146EB
+:107CB0002846FFF7D4FD80212846FFF7D0FD03E0DA
+:107CC00039462846FFF74FF82EE0788820BB04F0AD
+:107CD0007F0018B121462846FFF708FB2846FFF72A
+:107CE00080F821462846FFF720F80646FF2E13D0DD
+:107CF00096B900E0A8E0C5F8D46205F52E7050F8FA
+:107D00002600806840B105F52E7050F826003946EF
+:107D1000826828469047814606E007E08DE03946B4
+:107D20002846FFF720F800BF00BF8BE095F89C02C3
+:107D3000022802D0032879D126E034B1802C04D067
+:107D400039462846FFF70FF875E004F080008028D8
+:107D500008D104F07F0000EB800105F1140000EB76
+:107D6000810007E004F07F0000EB800105F5AA70B8
+:107D700000EB810080460020C8F800000222414646
+:107D80002846FFF71DF856E004F0800080280ED149
+:107D900004F00F0000EB800105F1140000EB8100FE
+:107DA000008A98B939462846FEF7DDFF43E004F023
+:107DB0000F0000EB800105F5AA7000EB8100008A3E
+:107DC00020B939462846FEF7CEFF34E004F08000A3
+:107DD000802808D104F07F0000EB800105F1140039
+:107DE00000EB810007E004F07F0000EB800105F567
+:107DF000AA7000EB810080460CB1802C03D10020DA
+:107E0000C8F800000CE021462846FFF7EDFB20B142
+:107E10000120C8F8000003E008E00020C8F80000D6
+:107E2000022241462846FEF7CBFF04E039462846A9
+:107E3000FEF799FF00BF00BF04E039462846FEF771
+:107E400092FF00BF00BF04E039462846FEF78BFFD3
+:107E500000BF00BF4846BDE8F0872DE9F041054668
+:107E60000E460027307800F0600030B1202802D0A4
+:107E7000402840D100E000BF00BF95F89C020128D7
+:107E800004D0022803D003282ED101E000BF00BF98
+:107E90003079012823D831792846FEF749FF044676
+:107EA000FF2C14D09CB905F52E7050F82400806882
+:107EB00058B1C5F8D44205F52E7050F8240031466B
+:107EC000826828469047074602E0032700E0032720
+:107ED000F08840B93FB92846FEF783FF03E03146FA
+:107EE0002846FEF740FF04E031462846FEF73BFFF8
+:107EF00000BF00BF04E031462846FEF734FF00BF54
+:107F000000BF3846BDE8F0817047000001460148D7
+:107F1000704700001822012070B504460B46224627
+:107F20001978587801282CD140F61C0080581D780B
+:107F300005F00F060125B540ADB2284340F61C05FB
+:107F4000A85002F5106000EB4110006800F40040FA
+:107F5000F0BB9889C0F30A001D7940EA854040EAE9
+:107F6000815040F0805040F4004002F5106505EB70
+:107F700041152D68284302F5106505EB4115286071
+:107F80002DE040F61C0080581D7805F00F060125F5
+:107F9000B540144E06EA0545284340F61C05A85096
+:107FA00002F5306000EB4110006800F4004078B941
+:107FB0009889C0F30A001D7940EA854040F080505E
+:107FC00040F4004002F5306505EB41152D6800E0F6
+:107FD00005E0284302F5306505EB411528600020D7
+:107FE00070BD00000000FFFF01460A464FF410601C
+:107FF0008058C30ADB024FF41060835040F604003F
+:10800000805840F4807340F604008350002070478D
+:108010000FB470B504460A98012817D1A06B20F45C
+:108020008030A063E0681A490840E060E06820F40E
+:108030004010E0601198012803D1E06840F48010FE
+:10804000E060204600F026F8054612E0E06840F0C7
+:108050004000E060204600F01DF805460E9820B96B
+:10806000A06B40F48030A06303E0A06B20F480306C
+:10807000A0630898012807D1A06840F00600A0601E
+:10808000A06840F02000A060284670BC5DF814FB9A
+:10809000BFFFBDFF08B501460020009000BF00985B
+:1080A000401C0090104A0098904201D9032008BD5E
+:1080B000086900F000400028F1D000200090086915
+:1080C00040F00100086100BF0098401C0090064A83
+:1080D0000098904201D90320E9E7086900F0010007
+:1080E0000028F1D100BFE2E7400D030070B504465F
+:1080F0000B46224619785878012848D102F51060BD
+:1081000000EB4110006800F00040B0F1004F17D1C3
+:1081100002F5106000EB4110006840F0006502F5C8
+:10812000106000EB4110056002F5106000EB41109B
+:10813000006840F0804502F5106000EB41100560DA
+:1081400040F63C0080581D7805F00F060125B5402B
+:10815000ADB2A84340F63C05A85040F61C0080583C
+:108160001D7805F00F060125B540ADB2A84340F6D5
+:108170001C05A85002F5106000EB411000682B4D63
+:10818000284002F5106505EB411528604BE002F52B
+:10819000306000EB4110006800F00040B0F1004F8B
+:1081A00017D102F5306000EB4110006840F0006527
+:1081B00002F5306000EB4110056002F5306000EB25
+:1081C0004110006840F0804502F5306000EB41103E
+:1081D000056040F63C0080581D7805F00F0601252B
+:1081E000B540134E06EA0545A84340F63C05A850A5
+:1081F00040F61C008558187800F00F060120B040AA
+:108200000B4E06EA0040854340F61C00855002F5FF
+:10821000306000EB41100068064D284002F53065E3
+:1082200005EB41152860002070BD0000007833EC9C
+:108230000000FFFF0078F3EF01460A46D2F8000E77
+:1082400020F00300C2F8000E40F60400805820F031
+:10825000020340F6040083500020704701460A469E
+:10826000D2F8000E20F00300C2F8000E40F6040021
+:10827000805840F0020340F604008350002070470D
+:108280000FB4F0B5054600272E46002405E0002176
+:1082900005F5827040F82410641C0F2CF7D3109859
+:1082A000A0B940F60400805940F0020140F60400F5
+:1082B0008151A86B40F40010A863A86B20F4002043
+:1082C000A863A86B20F48020A86307E0A86B20F4C3
+:1082D0000010A863A86B40F40020A8630020C6F833
+:1082E000000ED6F80008C6F800080B9801280BD13C
+:1082F000089820B90021284600F0BCFD08E00121C3
+:10830000284600F0B7FD03E00321284600F0B2FD47
+:108310001021284600F0B2FC00B10127284600F0E9
+:1083200083FC00B1012700214FF401608151001D41
+:10833000815140F61C00815100242EE006F51060AA
+:1083400000EB4410006800F00040B0F1004F10D185
+:108350003CB94FF0006106F5106000EB441001607D
+:108360000DE04FF0904106F5106000EB4410016005
+:1083700005E0002106F5106000EB441001600021CB
+:1083800006F5106000EB441001614FF67F3106F5F1
+:10839000106000EB44108160641C0698A042CDD8A8
+:1083A00000242EE006F5306000EB4410006800F079
+:1083B0000040B0F1004F10D13CB94FF0006106F51C
+:1083C000306000EB441001600DE04FF0904106F585
+:1083D000306000EB4410016005E0002106F53060DC
+:1083E00000EB44100160002106F5306000EB441002
+:1083F00001614FF67F3106F5306000EB441081607B
+:10840000641C0698A042CDD84FF40160805920F436
+:1084100080714FF4016081510020A8616FF08040AD
+:108420006861099818B9A86940F01000A861A869A6
+:1084300009490843A8610C9818B1A86940F00800E0
+:10844000A8611098012803D1A86904490843A861CC
+:108450003846F0BC5DF814FB00383C800400004056
+:108460000146886820F00100886000207047000005
+:10847000F0B505460B4614462A4619785878012867
+:1084800075D1986920BB02F5106000EB41100069BE
+:108490006D4E304002F5106606EB4116306102F574
+:1084A000106000EB4110006940F4002602F51060F6
+:1084B00000EB4110066102F5106000EB411000690D
+:1084C000C60CF60402F5106000EB4110066137E0BF
+:1084D00002F5106000EB41100069C60CF60402F5CD
+:1084E000106000EB4110066102F5106000EB4110D6
+:1084F0000069554E304002F5106606EB41163061BA
+:10850000DE689869B04201D9D868986102F51060B8
+:1085100000EB4110006940F4002602F5106000EB0A
+:108520004110066102F5106000EB411000699E6980
+:10853000C6F31206304302F5106606EB41163061B1
+:10854000012C15D1586928B102F5106000EB4110DB
+:108550005E69466102F5106000EB4110006840F072
+:10856000044602F5106000EB411006606AE01BE073
+:1085700002F5106000EB4110006840F0044602F57F
+:10858000106000EB41100660986900285AD040F650
+:10859000340080581E7806F00F070126BE40304395
+:1085A00040F63406B0504DE002F5306000EB41106B
+:1085B0000069C60CF60402F5306000EB411006615C
+:1085C00002F5306000EB411000691F4E304002F5AB
+:1085D000306606EB41163061986908B1D868986139
+:1085E000D868D86102F5306000EB4110006940F4B2
+:1085F000002602F5306000EB4110066102F53060A4
+:1086000000EB41100069DE69C6F31206304302F543
+:10861000306606EB41163061012C07D1186928B18C
+:1086200002F5306000EB41101E69466102F53060D2
+:1086300000EB4110006840F0044602F5306000EBAA
+:10864000411006600020F0BDFFFF07E070B5034653
+:108650000C4619461D6C1848854209D94FF4306004
+:10866000405800F00040B0F1004F01D1002070BD33
+:108670000026C1F8106BD1F8100B40F40026C1F8A9
+:10868000106BD1F8100B40F01806C1F8106BD1F840
+:10869000100B40F0C046C1F8106B012C09D1C1F895
+:1086A000142B4FF43060405840F080264FF4306077
+:1086B00046500020DBE700000A30544F30B5044636
+:1086C0000B4622461978587801281ED102F5106011
+:1086D00000EB4110006820F4001502F5106000EB7B
+:1086E000411005601879032802D0187902282AD190
+:1086F00002F5106000EB4110006840F0805502F573
+:10870000106000EB411005601DE002F5306000EBE9
+:108710004110006820F4001502F5306000EB4110B4
+:1087200005601879032802D0187902280BD102F5C8
+:10873000306000EB4110006840F0805502F5306079
+:1087400000EB41100560002030BD30B504460B46FB
+:10875000224619785878012821D102F5106000EBE3
+:108760004110006800F0004060B959B102F5106096
+:1087700000EB4110006820F0804502F5106000EB2E
+:108780004110056002F5106000EB4110006840F4F4
+:10879000001502F5106000EB4110056020E002F5C5
+:1087A000306000EB4110006800F0004060B959B142
+:1087B00002F5306000EB4110006820F0804502F5C2
+:1087C000306000EB4110056002F5306000EB4110B5
+:1087D000006840F4001502F5306000EB41100560C0
+:1087E000002030BD2DE9F84381460E4617464D4620
+:1087F0003478707801287DD1B06920BB05F5106010
+:1088000000EB44100069C849084005F5106101EB10
+:108810004411086105F5106000EB4410006940F454
+:10882000002105F5106000EB4410016105F51060B2
+:1088300000EB44100069C10CC90405F5106000EBA1
+:108840004410016155E005F5106000EB441000692B
+:10885000C10CC90405F5106000EB4410016105F579
+:10886000106000EB44100069AF49084005F5106145
+:1088700001EB44110861F168B0690844401EB0FB87
+:10888000F1F0A949C94301EAC04005F5106101EBC7
+:1088900044110969084305F5106101EB44110861B1
+:1088A00005F5106000EB44100069B169C1F31201D5
+:1088B000084305F5106101EB441108613079012886
+:1088C00017D105F5106000EB4410006920F0C0419D
+:1088D00005F5106000EB4410016105F5106000EB38
+:1088E0004410006940F0005105F5106000EB4410A1
+:1088F000016100E07FE0012F36D1706928B105F5F4
+:10890000106000EB441071694161307901281ED17B
+:1089100040F60800405900F4807060B905F5106019
+:1089200000EB4410006840F0005105F5106000EBCA
+:10893000441001600BE005F5106000EB4410006886
+:1089400040F0805105F5106000EB4410016005F522
+:10895000106000EB4410006840F0044105F5106021
+:1089600000EB44100160DCE005F5106000EB441002
+:10897000006840F0044105F5106000EB4410016010
+:10898000307901280FD0B0690028ECD040F63400CF
+:108990004059317801F00F0201219140084340F61F
+:1089A00034014851BDE040F60800405900F48070A1
+:1089B00060B905F5106000EB4410006840F000510C
+:1089C00005F5106000EB441001600BE005F5106048
+:1089D00000EB4410006840F0805105F5106000EB9A
+:1089E000441001600097308B83B232784846316979
+:1089F00000F0BEFA95E005F5306000EB4410006928
+:108A0000C10CC90405F5306000EB4410016105F5A7
+:108A1000306000EB441000694349084005F53061BF
+:108A200001EB44110861B069D0B905F5306000EB85
+:108A300044100069F168C1F31201084305F5306183
+:108A400001EB4411086105F5306000EB441000694A
+:108A500040F4002105F5306000EB4410016128E08E
+:108A6000F168B0690844401EB0FBF1F01FFA80F8CD
+:108A7000F06800FB08F0F06105F5306000EB441091
+:108A800000692949C94301EAC841084305F5306135
+:108A900001EB4411086105F5306000EB44100069FA
+:108AA000F169C1F31201084305F5306101EB44118E
+:108AB0000861012F07D1306928B105F5306000EB5E
+:108AC000441031694161307901281ED140F6080017
+:108AD000405900F4807060B905F5306000EB441037
+:108AE000006840F0005105F5306000EB4410016073
+:108AF0000BE005F5306000EB4410006840F0805159
+:108B000005F5306000EB4410016005F5306000EBC6
+:108B10004410006840F0044105F5306000EB44105B
+:108B200001600020BDE8F883FFFF07E078B5034649
+:108B30000024009400201A464C78012C35D10C7882
+:108B400002F5106505EB4414246804F00044B4F108
+:108B5000004F60D10C7805EB4414246844F00066A3
+:108B60000C7805EB441426600C7805EB441424685B
+:108B700044F080460C7805EB4414266000BF009C4E
+:108B8000641C009442F21075009CAC4201D9012093
+:108B90000AE00C7802F5106505EB4414246804F033
+:108BA0000044B4F1004FEAD035E00C7802F53065AE
+:108BB00005EB4414246804F00044B4F1004F2AD1BA
+:108BC0000C7805EB4414246844F000660C7805EB3F
+:108BD000441426600C7805EB4414246844F0804665
+:108BE0000C7805EB4414266000BF009C641C0094C4
+:108BF00042F21075009CAC4201D901200AE00C78C9
+:108C000002F5306505EB4414246804F00044B4F127
+:108C1000004FEAD000BF78BD0146886840F00100EF
+:108C2000886000207047000008B5014600200090D1
+:108C300000BF0098401C00900F4A0098904201D954
+:108C4000032008BD086900F000400028F1D0002092
+:108C500000901020086100BF0098401C0090064A58
+:108C60000098904201D90320EBE7086900F010005A
+:108C70001028F1D00020E4E7400D030008B50246BB
+:108C80000020009000BF0098401C0090104B0098FE
+:108C9000984201D9032008BD106900F00040002867
+:108CA000F1D000200090202040EA8110106100BF28
+:108CB0000098401C0090064B0098984201D9032070
+:108CC000E9E7106900F020002028F1D00020E2E759
+:108CD000400D030010B501460B4640F60804E45869
+:108CE00004F006020AB9002006E0022A01D0062A92
+:108CF00001D1022000E00F2010BD0146486900F0BC
+:108D00000100704701460B4640F61800C258001D8E
+:108D1000C058024090B2704701460B4640F618001A
+:108D2000C258001DC0580240100C704770B5024672
+:108D300013464FF40166F45840F63406F55801F036
+:108D40000F0625FA06F606F0010644EAC61403F5F6
+:108D5000106606EB4116B66806EA040070BD10B551
+:108D60000246134603F5306404EB4114A06840F654
+:108D70001404E458204010BD014648698A69104037
+:108D800070472DE9F04104460D46274628464FEA34
+:108D9000920C02F0030300210AE04FF4805858F8C7
+:108DA0000780C0F80080401C401C401C401C491C2F
+:108DB0006145F2D39BB100214FF4805858F8076009
+:108DC00000BF4FEAC10826FA08F880F80080491C65
+:108DD000401CA3F101081FFA88F3002BF1D1BDE874
+:108DE000F08170B504460E460025E06820F0C040D2
+:108DF000E060012E10D1E06840F00050E06000BF5C
+:108E00000120F8F715FA6D1C2046FFF776FF0128C0
+:108E100015D0322DF4D312E07EB9E06840F08040E6
+:108E2000E06000BF0120F8F703FA6D1C2046FFF751
+:108E300064FF20B1322DF5D301E0012070BD322D49
+:108E400001D10120FAE70020F8E710B502460B46F1
+:108E50001146D1F8000820F4FE60C1F80008D1F8EE
+:108E600000084FF4FE6404EA03142043C1F800082C
+:108E7000002010BD02461346D3F800080843C3F88B
+:108E8000000800207047000030B503461446022C4D
+:108E900049D12D48814204D32C48814201D20F226E
+:108EA00045E02A48814204D32948814201D20E225A
+:108EB0003DE02748814204D32648814201D20D2259
+:108EC00035E02448814204D32348814201D20C2258
+:108ED0002DE02148814204D32048814201D20B2257
+:108EE00025E01E48814204D31D48814201D20A2256
+:108EF0001DE01B48814204D31A48814201D2092255
+:108F000015E01848814204D31748814201D2082253
+:108F10000DE01548814204D31448814201D2072252
+:108F200005E0062203E00CB9092200E00922D86816
+:108F300020F47050D860D8684FF4705505EA822547
+:108F40002843D860002030BDC0ACD800C0E1E400A8
+:108F50000024F40080730601A0491A01002D31019C
+:108F600040A44C0100366E0120ABA6010048E80188
+:108F70002DE9F04304460D461E46DDF81CC0A04610
+:108F80002946BCF1000F12D1F01C870800230CE029
+:108F9000D1F8009008F5805000EB0230C0F8009046
+:108FA000491C491C491C491C5B1CBB42F0D30020D6
+:108FB000BDE8F08300BFFEE70FB4084B10B504A96D
+:108FC00002AA039800F0F6FA044602A9002000F075
+:108FD000C0FF204610BC5DF814FB0000539F000842
+:108FE0007CB50C001D461646014601D0601E00E00F
+:108FF0000020CDE90010064B6A462946304600F0B5
+:10900000D9FA002C02D0009A002111707CBD00001A
+:109010005B9E000802480068C0F302207047000011
+:109020000CED00E010B5002804DB0A07130E054A1A
+:10903000135406E00A07140E034A00F00F031B1F27
+:10904000D45410BD00E400E018ED00E002E008C8D0
+:10905000121F08C1002AFAD170477047002001E0B2
+:1090600001C1121F002AFBD170472DE9FC410446C3
+:10907000A089401E80B200906089401E83B2002209
+:1090800011462046266FB0472068006A00680068D5
+:109090004FF6BF7108402168096A096808602068B6
+:1090A000006A0068006840F400602168096A096885
+:1090B00008602068006A0068006840F0400021688D
+:1090C000096A0968086020680169D1E90401CDE9ED
+:1090D000000120680669F7683B4696E80700B84734
+:1090E000002508E0608A2168096A0968C86020686C
+:1090F00000F047FF6D1C6089A1894843A842F1D860
+:10910000206800F035FF20680169D1E90401CDE94C
+:10911000000120680669D6E902733A46D6E90001E3
+:10912000B8472068006A006800684FF6BF710840C1
+:109130002168096A096808602068006A0068006898
+:109140004FF2FF7108402168096A096808602068C9
+:10915000006A0068006840F040002168096A0968F8
+:109160000860BDE8FC8100002DE9FF5F82B00021AE
+:10917000DDE90430020DDDF840B0034318D044F6B9
+:109180001050A2F2FF3242431514119801281FD04B
+:10919000A5EB0B00401C5FEA000A4FF000064E4FA3
+:1091A000DFF83891B046504615D5CAF1000413E0F7
+:1091B000119801244AA3012801D16FEA0B010298FA
+:1091C000119AC0E90031C0E9024206B0BDE8F09F43
+:1091D000CBF10000DFE704460021404A491842EB8A
+:1091E0000450CDE9001012E0E00707D032463B46BC
+:1091F00040464946F7F7AEF98046894632463B4637
+:1092000010461946F7F7A6F906460F466410002CDB
+:10921000EAD1DDE90401DDE90023BAF1000F06DA45
+:10922000F7F798F942464B46F7F794F905E0F7F758
+:10923000EFFA42464B46F7F7EBFA04460E46002299
+:10924000284BF7F76DFB03D84FF0FF30014607E0DE
+:109250000022254B20463146F7F7D5F8F7F747FBB4
+:10926000102409E0002C0ADB0A220023F7F70AF891
+:10927000039B30321A55641E50EA0102F2D1641C7D
+:10928000039AC4F111031444119A012A03D0012254
+:1092900008430DD10AE0084304D000204FF0110B21
+:1092A000119072E7A3EB0B056D1E0DE05B4504DD2D
+:1092B0004FF0000205F1010504E003DA4FF000026F
+:1092C000A5F10105002AECD002981199C0E90231FC
+:1092D000C0E9004579E70000000014400000F03FBD
+:1092E000300000000000F0430000E03F014601F1C3
+:1092F000100000E0001D02681AB9024A126890428C
+:10930000F8D37047B400002070B504460D460CB188
+:10931000012100E00021084640F20511F7F73AFC70
+:109320000DB1012100E0002108464FF48371F7F7E9
+:1093300031FC002084F831002562206A0068006852
+:1093400040F04000216A0968086070BD7CB50446A1
+:109350000A20F7F76DFF20680169D1E90401CDE922
+:10936000000120680569EE68334695E80700B047BC
+:109370003621206800F083FE0021206800F0B9FE4D
+:109380003A21206800F07BFE0521206800F0B1FE44
+:10939000B221206800F073FE0C21206800F0A9FEC5
+:1093A0000C21206800F0A5FE0021206800F0A1FE3D
+:1093B0003321206800F09DFE3321206800F099FEE3
+:1093C000B721206800F05BFE3521206800F091FE97
+:1093D000BB21206800F053FE1921206800F089FEAF
+:1093E000C021206800F04BFE2C21206800F081FE97
+:1093F000C221206800F043FE0121206800F079FEC0
+:10940000C321206800F03BFE1221206800F071FEAD
+:10941000C421206800F033FE2021206800F069FE9E
+:10942000C621206800F02BFE0F21206800F061FEAD
+:10943000D021206800F023FEA421206800F059FE0E
+:10944000A121206800F055FEE021206800F017FE01
+:10945000D021206800F04DFE0421206800F049FE74
+:109460000D21206800F045FE1121206800F041FE2A
+:109470001321206800F03DFE2B21206800F039FE0A
+:109480003F21206800F035FE5421206800F031FEB5
+:109490004C21206800F02DFE1821206800F029FEE4
+:1094A0000D21206800F025FE0B21206800F021FE30
+:1094B0001F21206800F01DFE2321206800F019FE06
+:1094C000E121206800F0DBFDD021206800F011FED2
+:1094D0000421206800F00DFE0C21206800F009FE38
+:1094E0001121206800F005FE1321206800F001FE24
+:1094F0002C21206800F0FDFD3F21206800F0F9FDDF
+:109500004421206800F0F5FD5121206800F0F1FDB4
+:109510002F21206800F0EDFD1F21206800F0E9FDFB
+:109520001F21206800F0E5FD2021206800F0E1FD0A
+:109530002321206800F0DDFD2121206800F09FFD3F
+:109540001121206800F09BFD7820F7F771FE29219A
+:10955000206800F094FD206800F00AFD2068016991
+:10956000D1E90401CDE9000120680569D5E902636C
+:109570003246D5E90001B04702212046E26D90470E
+:10958000002060822046A16F884700207CBD00003B
+:1095900010B50648046803E02046FFF7A7FE04461E
+:1095A000034800688442F7D310BD0000B0000020DB
+:1095B000B40000202DE9FF4F95B09A468846064634
+:1095C0000025EEE1252877D100242746F94A01211C
+:1095D000039400E0044316F8013F203B01FA03F036
+:1095E0001042F7D130782A2811D06FF02F0330784D
+:1095F000A0F13002092A16D8039A44F0020402EBC3
+:10960000820203EB42021044761C0390EFE758F805
+:10961000042B0392002A03DA504244F400540390CE
+:1096200044F00204761C30782E2816D116F8010F6B
+:1096300044F004042A280DD06FF02F023078A0F1F6
+:109640003003092B09D807EB870302EB4303C71844
+:10965000761CF3E758F8047B761C30786C280FD022
+:1096600006DC4C2817D068280DD06A2814D104E0F5
+:10967000742810D07A280FD10DE044F400140AE0C9
+:1096800044F4801401E044F440147278824202D120
+:1096900004F58014761C761C307866280BD013DC19
+:1096A000582877D009DC002875D04528F6D0462800
+:1096B000F4D047281AD193E118E0632835D0642804
+:1096C00079D0652812D18BE1702873D008DC672827
+:1096D000F1D069286FD06E280DD06F2806D1ACE08C
+:1096E00073282CD0752874D0782853D052461799F7
+:1096F00090476D1C54E1C4F30250022809D003289E
+:109700000DD0D8F8001004280DD00D6008F1040821
+:1097100046E1D8F80010EA17C1E90052F6E7D8F898
+:1097200000100D80F2E70D70F0E718F8041B8DF8BB
+:10973000001000208DF80100EB46012003E058F8EE
+:1097400004BB4FF0FF3061074FF0000102D40DE081
+:1097500009F101018946B9420FDA8145F8DB1BF8AE
+:1097600009100029F4D108E009F10101894681427C
+:10977000FADB1BF809100029F6D103985346A0EB39
+:10978000090721463846179A00F080FA284400EB72
+:10979000090507E044E008E10DE01BF8010B524623
+:1097A00017999047B9F10109F7D253462146384637
+:1097B000179AF2E039E00A21C4F302524FF0000B8D
+:1097C0000091022A06D058F8040BC117032A09D0C9
+:1097D0000AE023E008F1070020F00702F2E80201A6
+:1097E000904605E000B2C117042A01D140B2C1176A
+:1097F000002906DA0A460021404261EB02012D22CF
+:1098000002E0220504D52B228DF80420012203E07A
+:10981000E20701D02022F7E7914657E00A2100E055
+:1098200010214FF0000B00910BE010214FF0000BC6
+:1098300044F004040827009103E008204FF0000BD7
+:109840000090C4F30252022A05D058F8040B0021FC
+:10985000032A08D008E008F1070020F00702F2E828
+:109860000201904603E080B2042A00D1C0B24FF05A
+:10987000000922072AD53278702A07D0DDF800C007
+:109880008CF0100C5CEA0B0C05D00EE040228DF839
+:109890000420012208E050EA010306D030238DF8AD
+:1098A00004308DF8052002229146009B83F00803C6
+:1098B00053EA0B030AD150EA010201D1620705D530
+:1098C00030228DF804204FF001097F1E3278582A8B
+:1098D00004D039A20C920CAA02920BE03BA2F9E749
+:1098E0005B46009AF6F7CEFC0C9B9B5C029A521EDC
+:1098F0000292137050EA0102F2D1029804A9081AE8
+:1099000000F1200B600702D524F4803400E0012729
+:109910005F4502DDA7EB0B0000E0002000EB0B0130
+:10992000009003984944401A0390E00306D453463C
+:109930002146179A039800F0A9F90544002706E08C
+:1099400001A85246C05D179990476D1C7F1C4F457A
+:10995000F6DBE0030CD553462146179A039800F036
+:1099600095F9054404E030205246179990476D1C44
+:109970000099481E00900029F5DC08E00298029941
+:1099800052460078491C0291179990476D1CBBF113
+:109990000001ABF1010BF1DC5BE100F065F905447E
+:1099A000761C307800287FF40DAE19B02846BDE84B
+:1099B000F08F00000928010030313233343536375A
+:1099C000383961626364656600000000303132330B
+:1099D00034353637383941424344454600000000AB
+:1099E000600700D4062708F1070020F00700F0E820
+:1099F0000223804603F0004C5FEA0C0001D097A0E0
+:109A000009E0200501D596A005E0E00701D095A06A
+:109A100001E0AFF24C001390307823F0004365284A
+:109A20000CD006DC452809D046281DD047287FD118
+:109A30003BE0662818D067287AD136E00021112F44
+:109A400001DB112000E0781CCDE9000104A90CA87D
+:109A5000FFF78AFBDDE90D010C9A4FF0000B07F1CF
+:109A60000109109200914EE04FF000400097CDE9BF
+:109A7000011004A90CA8FFF777FBDDE90D020C9B90
+:109A80000F994FF0000B91461093009211B9791C79
+:109A900000EB0109B7EB090003D4C0F1FF3B07F16C
+:109AA0000109A9EB0700019042E0012F00DA01272C
+:109AB0000021112F01DD112000E03846CDE9000121
+:109AC00004A90CA8FFF750FBDDE90D010C9A0091E9
+:109AD0004FF0000BB946109221070FD4009A4A4567
+:109AE00003DA914601E0A9F10109B9F1010F05DDA1
+:109AF000109AA9F10101515C3029F4D0B84202DA80
+:109B000010F1040F03DA0121CDE9011010E0002863
+:109B100003DC8344A9EB000102E0411C494500DD60
+:109B20008946A0EB0B00401C01904FF000400290D2
+:109B3000200705D40198484502DB4FF0FF30019023
+:109B400000208DF84B0002980DF14B07B0F1004F4B
+:109B500025D002200C902B200D90029800280CDAC2
+:109B6000404202902D200D9007E00A210298F6F75E
+:109B7000ABFD3031029007F8011D0C99481E0C9086
+:109B80000029F2DC02980028EFD1791E0D980870A8
+:109B9000307800F0200040F0450007F8020D11A8D1
+:109BA000C01BC01D02901398007800B1012000EB8B
+:109BB0000901019801EBE071029801440398401AF1
+:109BC000401E0390E00306D453462146179A03989B
+:109BD00000F05CF805441398007818B152461799C4
+:109BE00090476D1CE00323D553462146179A0398EE
+:109BF00000F04CF805441BE0BBF1000F07DB0098B8
+:109C0000584504DD1098179910F80B0001E01799DA
+:109C100030205246904701980BF1010B401E05F190
+:109C20000105019004D12E205246179990476D1CD2
+:109C3000B9F10001A9F10109DEDC05E017F8010B1B
+:109C40005246179990476D1C0299481E02900029B0
+:109C5000F4DC53462146179A03989EE62D00000037
+:109C60002B000000200000002DE9F04104460025F3
+:109C70001E461746880404D405E039462020B04724
+:109C80006D1C641EF9D52846BDE8F0812DE9F04130
+:109C9000044600251E469046C80301D5302700E043
+:109CA0002027880404D505E041463846B0476D1C9E
+:109CB000641EF9D52846BDE8F0810FB410B5BDF893
+:109CC0000C100298F7F7C2FB012802D110BC5DF816
+:109CD00014FB0020FAE70FB410B5BDF80C100022F9
+:109CE0000298F7F7C5FB10BC5DF814FB0FB410B574
+:109CF000BDF80C1001220298F7F7BAFB10BC5DF812
+:109D000014FB2DE9FC4704460D4616461F46DDF8B8
+:109D1000288020680169D1E90401CDE900012068AB
+:109D2000D0F810C0DCF80C904B469CE80700C84700
+:109D30002A21206800F0A3F9E2892A4491B2206820
+:109D400000F0C6F9E2893A4491B2206800F0C0F907
+:109D50002B21206800F093F9228A324491B22068C6
+:109D600000F0B6F9228A424491B2206800F0B0F9BE
+:109D70002C21206800F083F9206800F0F9F82068B1
+:109D80000169D1E90401CDE900012068D0F810C0D3
+:109D9000DCE902934A46DCE90001C847BDE8FC87DC
+:109DA0002DE9FC4104460D46257220680169D1E980
+:109DB0000401CDE9000120680669F7683B4696E892
+:109DC0000700B8475DB93621206800F058F97021C6
+:109DD000206800F08EF90020E08120822AE0022D28
+:109DE0000BD13621206800F04AF90021206800F0EC
+:109DF00080F90020E08120821CE0012D0CD1362169
+:109E0000206800F03CF9A021206800F072F9502091
+:109E1000E081002020820DE0032D0BD13621206847
+:109E200000F02DF9C021206800F063F90020E081E6
+:109E300050202082206800F09BF820680169D1E959
+:109E40000401CDE9000120680669D6E902733A46AB
+:109E5000D6E90001B847BDE8FC814A68002A06D06F
+:109E60000A68531C0B6010704868401E48607047B9
+:109E70002DE9FC4105460E4600270DB1012100E009
+:109E800000210846DD21F6F785FE2C460CB10121A4
+:109E900000E0002108463621F6F77CFEA06960B19B
+:109EA000A169D1E90401CDE90001D4F818C0DCF8BA
+:109EB0000C8043469CE80700C04700BF284607F0D7
+:109EC0001BFB3146284607F048FB0746284607F0AB
+:109ED000F7FA3846BDE8FC812DE9FC4705460E46F9
+:109EE00017464FF000080DB1012100E0002108469F
+:109EF000F021F6F74FFE2C460CB1012100E00021C5
+:109F000008462821F6F746FEA06960B1A169D1E9AB
+:109F10000401CDE90001D4F818C0DCE902934A46F7
+:109F2000DCE90001C84700BF284607F0E5FA002435
+:109F300007E03178284607F010FB8046761C601C4D
+:109F400084B2BC42F5DB284607F0BAFA4046BDE8C9
+:109F5000FC870A68531C0B60107070470FB410B573
+:109F6000BDF80C100298F7F779FA10BC5DF814FBF5
+:109F700000BF016A0968896801F080010029F8D1F1
+:109F8000704700BF016A0968896801F00201002971
+:109F9000F8D070472DE9FC4104460E46174620686C
+:109FA000006A006800684FF6BF7108402168096ABE
+:109FB000096808602068006A0068006840F4006072
+:109FC0002168096A096808602068006A00680068FA
+:109FD00040F040002168096A09680860206801694A
+:109FE000D1E90401CDE900012068D0F810C0DCF807
+:109FF0000C8043469CE80700C047002509E036F87E
+:10A0000015002168096A0968C8602068FFF7B9FF70
+:10A010006D1CBD42F3D32068FFF7AAFF20680169D9
+:10A02000D1E90401CDE900012068D0F810C0DCE9D5
+:10A0300002834246DCE90001C0472068006A0068EC
+:10A0400000684FF6BF7108402168096A0968086016
+:10A050002068006A006800684FF2FF7108402168BC
+:10A06000096A096808602068006A0068006840F0B2
+:10A0700040002168096A09680860BDE8FC812DE993
+:10A08000FC4104460D462046FFF772FFE169D1E925
+:10A090000401CDE90001E669F7683B4696E8070050
+:10A0A000B847206A0068C5602046FFF76AFF20466F
+:10A0B000FFF75EFFE169D1E90401CDE90001E6693E
+:10A0C000D6E902733A46D6E90001B847BDE8FC81FB
+:10A0D00070B504460D462812216A0968C8602046FA
+:10A0E000FFF74FFF206A0068C5602046FFF749FF71
+:10A0F00070BD70B504460D46206A0068C5602046F4
+:10A10000FFF73FFF70BD2DE9F84F04460D46164698
+:10A110001F46DDE90A89781B401CA8EB0601491C93
+:10A1200000FB01FACDF800803B4632462946204626
+:10A13000D4F870C0E0471FFA8AF249462046FFF77C
+:10A1400029FFBDE8F88F00001CB507F00DFB05489E
+:10A15000012100238A02CDE9001003A1064808F07E
+:10A160008DFB1CBD7C000020627573696E65737386
+:10A170005F7461736B000000EDA3000810B51468F4
+:10A18000641C8C4201D2146803551468641C14606A
+:10A1900010BD00002DE9F04F2DED068B83B08146F8
+:10A1A0008A469346B0EE408AF0EE608A1D4651EC36
+:10A1B000180BF6F752FA04462046F6F73DFA41EC42
+:10A1C0001A0B53EC182BF6F7C2F941EC190B9FED63
+:10A1D0002B0B53EC102B51EC180BF6F75DFA0CD24D
+:10A1E0002D235A4651464846FFF7C8FF644251ECBA
+:10A1F000190B81F0004141EC190B0020009023461F
+:10A200005A4651460190484600F080F82E235A469F
+:10A2100051464846FFF7B2FF002D01DB284600E01B
+:10A2200006208046002622E09FED160B53EC102BF3
+:10A2300051EC190BF6F78EF941EC190B51EC190B97
+:10A24000F6F70BFA074607F13000C3B25A465146FB
+:10A250004846FFF793FF3846F6F7EEF941EC1A0B44
+:10A2600053EC192BF6F773F941EC190B761C4645A4
+:10A27000DADB03B0BDEC068BBDE8F08F0000000018
+:10A280000000000000000000000024402DE9F0471D
+:10A2900088B006460F4690461C46DDF840900025E3
+:10A2A000B9F1000F01D00FA000E013A0824600BF5B
+:10A2B00004F00F001AF8002028466D1C0DF800204D
+:10A2C0002409002CF4D106E01DF805304246394639
+:10A2D0003046FFF753FF281EA5F10105F4D108B061
+:10A2E000BDE8F087303132333435363738394142C2
+:10A2F00043444546000000003031323334353637B0
+:10A300003839616263646566000000002DE9FF4F23
+:10A3100091B083461C46DDE91E7800254FEAD479CA
+:10A32000204608B901230EE00021C20F02B14042CD
+:10A3300000BF491C0A2390FBF3F00028F9D10AB1B1
+:10A340004B1C00E00B469A460026002F03DD5745C4
+:10A3500001D9A7EB0A06B8F1000F08D13EB12020C1
+:10A36000334600905846DDE9121200F06CFEB9F158
+:10A37000000F00D0644200BF0A2094FBF0F100FB04
+:10A3800011403030C2B228466D1C01A90A540A207F
+:10A3900094FBF0F4002CEFD1B9F1000F03D02D2283
+:10A3A00028466D1C0A5406E001A8435D5846DDE9C5
+:10A3B0001212FFF7E3FE281EA5F10105F4D1B8F152
+:10A3C000000F08D03EB12020334600905846DDE90A
+:10A3D000121200F038FE15B0BDE8F08F10B500F095
+:10A3E000E7F901F05BFC01F025FD10BD05F062F915
+:10A3F00005F0CAFA4FF4FA6007F090FB00BF01F0D5
+:10A40000D3FC00F069FA05F0BFFA002000F044FB2D
+:10A410004FF47A7007F082FBF1E700002DE9F0417C
+:10A4200090B0804600BF3D48D0F8B400046A0026D2
+:10A4300000250CB9012000E0002018B1002010B068
+:10A44000BDE8F08128466D1C4DF8204053E000BF68
+:10A45000102D04DBCC22324932A002F083F800BF79
+:10A46000681E05465DF82040274600BF00BF2FB993
+:10A4700040F2B332344935A002F074F800BF786A74
+:10A4800008B1012000E0002020B128466D1C626A5E
+:10A490004DF82020274600BF00BF2FB94FF491622E
+:10A4A00034492AA002F05EF800BF97F82800C0F3F4
+:10A4B000800000B11FE0608D020904F108014046F0
+:10A4C00000F0D6FDB0B12646274600BF00BF2FB929
+:10A4D0004FF4677228491DA002F044F800BF386AA3
+:10A4E00008B1012000E0002020B128466D1C226A3E
+:10A4F0004DF8202000BF002DA9DC6EB1304604F0DD
+:10A50000CBFC08B130469AE7F06904F0C5FC08B10D
+:10A51000F06994E7002092E7304690E74C2801204C
+:10A520006E3401082E2E5C557365725C73797374FA
+:10A53000656D5C73676C5C636F72655C73676C5FA1
+:10A540006576656E742E6300333401082E2E5C55DB
+:10A550007365725C73797374656D5C73676C5C6949
+:10A560006E636C7564655C73676C5F636F72652E98
+:10A57000680000004734010821340108F0B595B0A7
+:10A5800004460E46002500BF2CB940F27D522849F2
+:10A5900028A001F0E7FF00BF28466D1C01A941F883
+:10A5A00020403AE000BF102D05DB40F281522049E7
+:10A5B00020A001F0D7FF00BF681E054601A951F891
+:10A5C0002040606A20B128466D1C626A41F8202054
+:10A5D000204604F087FC00B11FE02146304605F01C
+:10A5E0008DF9C8B10F20ADF8500000BFA06928B99F
+:10A5F00040F28E520E490FA001F0B4FF00BF11AA25
+:10A6000021463046A3699847206A28B128466D1C28
+:10A6100001A9226A41F8202000BF002DC2DCB768E2
+:10A620000D48394642693046904700BF15B0F0BD2D
+:10A630007E3301082E2E5C557365725C73797374DA
+:10A64000656D5C73676C5C636F72655C73676C5F90
+:10A65000636F72652E6300004C280120F0B503463D
+:10A660000024012901D0022904D101F10C00C1B25A
+:10A67000581E83B24D1C05EB4505052695FBF6F5E6
+:10A68000022606FB012635441D441846DE1703EB5F
+:10A69000967605EBA605642693FBF6F6AD1B4FF404
+:10A6A000C87693FBF6F63544072695FBF6F706FBCE
+:10A6B0001755ECB2601CC0B2F0BD00002DE9F041AE
+:10A6C00005460E4618273946002000F0B9FB04461F
+:10A6D0000CB1012100E0002108463621F6F75AFAB4
+:10A6E0002560A6800548A0600548E0600548206117
+:10A6F000054860612046BDE8F0810000ED9C00083F
+:10A70000D79C00085D9F0008BB9C000800BFEFF3CA
+:10A71000058008B1012070470020FCE70FB470B538
+:10A720009C252946002000F08BFB04460CB101213A
+:10A7300000E0002108461C21F6F72CFA204604A967
+:10A74000382203E011F8013B00F8013B131EA2F18F
+:10A750000105AAB2F6D100BF012184F898100220A9
+:10A7600020B1012803D0022807D101E00CE00BE062
+:10A7700004F1380000F070F906E0204600F007F818
+:10A78000002070BC5DF814FB00BF2046F9E710B54F
+:10A7900004460CB1012100E0002108461421F6F71F
+:10A7A000F9F900BF2146002000F020FB00BF10BDDA
+:10A7B00030B5B3B04FF400614348FFF77FFF2F90EF
+:10A7C0004FF480514048FFF779FF329038223F49DB
+:10A7D0001EA8F5F7B9FD002004902FA80FC88DE83A
+:10A7E0000F0001202CA90EC906F028FE1E901E980D
+:10A7F0003749C26A904723221EA90BA8F5F7A4FD8A
+:10A800009DF89B008DF84F00142227A914A8F5F796
+:10A810009BFD28220FA96846F5F796FD0BA80FC8E7
+:10A82000FFF77CFF2B490861096909B1012100E0AC
+:10A830000021084640F22F11F6F7ACF925480069CF
+:10A840000068C169D1E90401CDE90001214800692E
+:10A850000068C4691F4800690068C069856894E899
+:10A860000F00A8471B48006900680169D1E904018D
+:10A87000CDE90001174800690068046915480069BE
+:10A8800000680069856894E80F00A84700224FF42B
+:10A8900000510D48F6F7ECFD0E4A10691269916BF4
+:10A8A0008847012251030848F6F7E2FD14220749C0
+:10A8B000383119A8F5F748FD19A803F03FF903F05E
+:10A8C000E9FB33B030BD0000000C0240FC2E010853
+:10A8D0000C060020A04400207FB5494800680028ED
+:10A8E00073D104F00DF90020039000BF4548D0F863
+:10A8F000B4000446039904F0A7FE002003F08EFC88
+:10A90000054646220021284604F00AFD1C22F021BB
+:10A91000284604F0A9FD3CA1284603F0D8FC3E4996
+:10A92000284603F0CBFC3D48006802902846029977
+:10A9300003F0E4FC0021284603F0D2FC002003F0E1
+:10A940006DFC054664220021284604F0E9FC1C2227
+:10A95000F021284604F088FD31A1284603F0B7FC19
+:10A960002D49284603F0AAFC2C48001D00680190E0
+:10A970002846019903F0C2FC0021284603F0B0FCF0
+:10A98000002003F04BFC1E490860822200211C4875
+:10A99000006804F0C5FC1C22F0211948006804F08E
+:10A9A00063FD1D491648006803F088FC1B48083009
+:10A9B0000068009012480099006803F09FFC002195
+:10A9C0000F48006803F08CFC00BF1A48007B19494F
+:10A9D000C97A184A927A174BDB79CDE90032CDE972
+:10A9E000021014488379808800F5FA6212A1194890
+:10A9F000FEF7E2FA17490248006803F068FC7FBDE1
+:10AA0000800000204C28012053544D3332205254F2
+:10AA10004320546573740000A85D0108C82E010826
+:10AA20005265736F6C7574696F6E3A20323430788A
+:10AA300032343000A044002025642D253032642DAE
+:10AA40002530326420253032643A253032643A258C
+:10AA5000303264007457002010B504460CB1012157
+:10AA600000E000210846FC21F6F794F80548206034
+:10AA7000054860620548A0630548E0630548206416
+:10AA800010BD00004D930008A19D0008039D000823
+:10AA900007A100086B90000810B504462CB94FF4CC
+:10AAA00000510348F6F7DAFC00E000BF00BF10BD1C
+:10AAB0000008024010B504462146002000F002F8CC
+:10AAC00010BD00002DE9F04105460C460027B846B0
+:10AAD00000260DB1284600E0184805460CB1E8688C
+:10AAE00010B10020BDE8F0810027B846002100BF6A
+:10AAF00004EBC100406838B954F8310020B90E4663
+:10AB00000EB90020EEE70FE007EB080054F8312003
+:10AB1000904201D90020E5E754F8317004EBC10000
+:10AB2000D0F80480491CE3E700BF0EB90020D9E744
+:10AB30002146284600F0F2FED4E700002C52012006
+:10AB400010B504462146002000F002F810BD0000B8
+:10AB500070B504460D460CB1204600E0034804469B
+:10AB60002946204600F022FF70BD00002C52012033
+:10AB700010B504462146002000F002F810BD000088
+:10AB800070B503460020C1B10BB11C4600E00B4C70
+:10AB9000234611B1A1F1080400E00024224662B16D
+:10ABA000546804F0004444B1054E1468B44204D122
+:10ABB000546824F00044A4F1080070BD2C52012018
+:10ABC000EFBEADDE10B5044622460021084600F077
+:10ABD00001F810BD2DE9F04104460D461646002748
+:10ABE0000CB1204600E0054804463246294620467E
+:10ABF00000F02BFE07463846BDE8F0812C520120BC
+:10AC0000F6F74EFCFBF77AF8F9F7E2FCF9F78AFC65
+:10AC1000F9F7F6FDF9F70EFEF9F7B8FCF9F72EFE95
+:10AC2000F9F70AFE002000F04BF8012000F048F888
+:10AC3000FFF7D4FBFFF788FAF9F7B6FC00F033F919
+:10AC400000BFFEE701460020842901D0CA1C104441
+:10AC5000704700002DE9F04104460E461548005D9E
+:10AC600038B9144818380168204688470120BDE8E3
+:10AC7000F081114850F82400B04219D90F4850F81B
+:10AC80002400B6FBF0F70B48083850F8240030F8E1
+:10AC90001780002508E000210648083850F82400F5
+:10ACA0007A1920F812106D1C4545F4DB0020DEE710
+:10ACB0000120DCE7D0000020702F0108682F010878
+:10ACC00010B504460C4951F824104A000B4951F8BC
+:10ACD0002400002100F0C8F8094951F82420074950
+:10ACE000083951F82400002100F0BEF80121034882
+:10ACF0000830015510BD0000602F0108C800002079
+:10AD0000702F01082DE9F04704460F460025A9469B
+:10AD10002348005D20B9224818380168204688473A
+:10AD20001FB94FF0FF30BDE8F0871E4850F82400EF
+:10AD3000B7FBF0F61B4850F82400B7FBF0F100FB1E
+:10AD4000117000B1761C184850F82400451E22E00E
+:10AD50001348083850F8240030F8150010B909F1EC
+:10AD6000010901E04FF00009B14513D14FF000088F
+:10AD700009E00B48083850F8240005EB080220F8D9
+:10AD8000126008F10108B045F3D3064850F82400DA
+:10AD90006843C8E76D1E002DDADA4FF0FF30C2E7D6
+:10ADA000D0000020682F0108602F010810B501466F
+:10ADB0000023002207E00B4850F8210030F8120071
+:10ADC00000B15B1C521C084850F821009042F2D898
+:10ADD00064205843044C54F82140B0FBF4F0C0B256
+:10ADE00010BD0000C8000020602F01082DE9F041CF
+:10ADF00004460D460DB9BDE8F0810F4850F8240017
+:10AE00002E1A0E4850F82400B6FBF0F10A4808301C
+:10AE100050F8240030F81100084951F8241000FBC4
+:10AE200001F73A460021284600F01EF83146204638
+:10AE3000FFF710FF00BFDEE7C0000020682F010809
+:10AE400070B504460E4631462046FFF75BFF0546C7
+:10AE5000681C08B9002070BD024850F8240028443E
+:10AE6000F9E70000C000002030B5034601E003F818
+:10AE7000011B141EA2F10102F9D130BD70B50446C8
+:10AE800025460DB1294600E00121084606F046FEA0
+:10AE9000002070BD10B507F081FD012801D1002010
+:10AEA00010BD0120FCE710B506F006FF002010BD24
+:10AEB00010B5FFF72BFC10B107F086FD10BD07F0B1
+:10AEC0007DFDFBE7F8B504460D46A06840B1E0689B
+:10AED00030B10020009094E80F0007F085F8F8BD2D
+:10AEE0000022D4E9000107F052F8F8E72DE9FF410C
+:10AEF00007460D4614460295002001903DB980207A
+:10AF000000909DE8070087E80700BDE8FF8100206A
+:10AF100003900026601C08B9761E03E014B1264693
+:10AF200006B90126FFF7F2FBB0B103AA01A9284632
+:10AF300007F01CFB012802D11020009001E0002046
+:10AF400000900398B8B14FF080500E490860BFF3ED
+:10AF50004F8FBFF36F8F0EE0324601A9284607F0EE
+:10AF600051FA012802D11020009004E00EB900200F
+:10AF700000E0402000909DE8070087E8070000BF40
+:10AF8000C3E7000004ED00E077B581B00646144643
+:10AF900000200090254605B90125FFF7B7FBA8B1B1
+:10AFA00000236A4602A9304607F0AEF9012802D014
+:10AFB000FF2004B070BD009890B14FF08050094957
+:10AFC0000860BFF34F8FBFF36F8F09E000232A465D
+:10AFD00002A9304607F0C4F8012801D0FF20E8E7B5
+:10AFE0000020E6E704ED00E07FB504460D46606909
+:10AFF00098B1A06988B1B4F90800FFF723FE0646AE
+:10B00000D4E90510CDE9006102902B462269D4E90C
+:10B01000001007F065FC039013E0B4F90800FFF797
+:10B0200011FE064603A8CDE90060238A9AB22B469A
+:10B03000D4E9001007F022FC012802D0002004B05F
+:10B0400070BD0398FBE72DE9F04706460F46904692
+:10B050001C46DDF82090002506E04B464246394666
+:10B060003046FFF78BF86D1CA542F6D3BDE8F0879C
+:10B0700070B50346B3F90000B1F90040A04211DBFE
+:10B08000B3F90000B1F90440A0420BDCB3F90200AF
+:10B09000B1F90240A04205DBB3F90200B1F9064064
+:10B0A000A04201DD002070BD0AB90120FBE7B3F921
+:10B0B0000000B1F900401444A04208DBB3F90000DD
+:10B0C000B1F90440A41AA04201DC0120EBE7B3F976
+:10B0D0000200B1F902401444A04208DBB3F90200B7
+:10B0E000B1F90640A41AA04201DC0120DBE7B3F964
+:10B0F0000000B1F900401444A0421CDCB3F9020086
+:10B10000B1F902401444A04215DC18880E88164498
+:10B11000801B05B258884E881644801B04B215FB6C
+:10B1200005F014FB040602FB02F0864201DC01205C
+:10B13000B9E70020B7E7B3F90000B1F90440A41A59
+:10B14000A0421CDBB3F90200B1F902401444A04252
+:10B1500015DC18888E88B61A801B05B258884E8870
+:10B160001644801B04B215FB05F014FB040602FB19
+:10B1700002F0864201DC012095E7002093E7B3F955
+:10B180000000B1F900401444A0421CDCB3F90200F5
+:10B19000B1F90640A41AA04215DB18880E8816449F
+:10B1A000801B05B25888CE88B61A801B04B215FBE6
+:10B1B00005F014FB040602FB02F0864201DC0120CC
+:10B1C00071E700206FE7B3F90000B1F90440A41A59
+:10B1D000A0421CDBB3F90200B1F90640A41AA04258
+:10B1E00015DB18888E88B61A801B05B25888CE8861
+:10B1F000B61A801B04B215FB05F014FB040602FB13
+:10B2000002F0864201DC01204DE700204BE700BF41
+:10B21000002048E72DE9F04105460E461C48076826
+:10B220001C480068001D06F039FB50B91948006839
+:10B2300090F82C100120884017490968814316486E
+:10B240000160681C38B936B112480168091D1348FD
+:10B2500006F06EFB1AE07C190E4800684460BC42A0
+:10B2600007D20C480168091D0D48006806F046FB2E
+:10B270000CE008480168091D0A48006806F03EFB1A
+:10B2800009480068844201D207480460BDE8F081A3
+:10B2900028000020140000202C0000208C08002032
+:10B2A0001C000020180000204400002010B50446B7
+:10B2B00006F04AFB23480068401C224908602248E7
+:10B2C000006840B9204804600846006801280DD194
+:10B2D00000F0BEF90AE01D48006838B91A48006855
+:10B2E000C06AE16A884201D81748046018480068BB
+:10B2F000401C1749086094F82C100120884015491B
+:10B300000968084313490860E16A01EB8101124AA8
+:10B3100002EB8100211D06F00BFB06F03FFB0B4802
+:10B32000006868B108480068C06AE16A884207D2CC
+:10B330004FF0805009490860BFF34F8FBFF36F8F04
+:10B3400010BD000024000020140000203000002068
+:10B35000400000202C000020B007002004ED00E099
+:10B3600010B516E006F0F0FA0C48C068C468201D5D
+:10B3700006F094FA0A480068401E09490860094826
+:10B380000068401E0749086006F008FB204600F0F0
+:10B390005FF8044800680028E4D110BD7808002058
+:10B3A000240000202000002070B504460D46206CCB
+:10B3B00070B1216CE0680144E160D4E90210884278
+:10B3C00001D32168E1602846226CE168F4F7BCFFF4
+:10B3D00070BD2DE9F04104460F4615464FF00008B8
+:10B3E000A66B206C48B9206800282CD1A06807F013
+:10B3F00099FB80460020A06025E07DB93946226C8B
+:10B400006068F4F7A1FF216C606808446060D4E9CB
+:10B410000101884217D32068606014E03946226C2D
+:10B42000E068F4F791FF216CE068411AE16021685F
+:10B43000E068884203D2216CA068411AE160022DC5
+:10B4400001D106B1761E701CA0634046BDE8F081B4
+:10B4500010B5044694F8510030B9206B06F0BCFAE0
+:10B46000204606F0B9FA1AE094F85100012803D1F9
+:10B47000204606F0B1FA12E094F85100022801D1FA
+:10B48000012000E0002050B900BF502080F3118857
+:10B49000BFF34F8FBFF36F8F00BF00BFFEE710BD3C
+:10B4A00001464A6A22B10A6B1268C2F1070000E045
+:10B4B0000020704730B54FF47053174800F0070470
+:10B4C0002CB1C01D20F00700134C041B1B1B0246AF
+:10B4D000124C22600024114D6C60D018083820F006
+:10B4E00007000F4C206000240D4D2D686C600C4D42
+:10B4F0002D682C601146441A4C60094C24680C607D
+:10B50000084D4C682C60084D4C682C604FF000448E
+:10B51000064D2C6030BD0000A00800205000002027
+:10B5200058000020600000205C0000206C0000201B
+:10B5300000BFFFF715FF064800680128F9D94FF052
+:10B54000805004490860BFF34F8FBFF36F8FF0E75F
+:10B55000B007002004ED00E010B5044654B100200F
+:10B56000A06020600021E16000231A4619462046B1
+:10B5700006F0F6FD10BD2DE9F04106460D461746D2
+:10B580009846069C0DB9246000E02760E6632564B8
+:10B590000121204606F098FDBDE8F0812DE9FF5F0E
+:10B5A00081460E469246DDE90E7B109CAAF1010011
+:10B5B000216B01EB800828F0070808F0070008B9A4
+:10B5C000012000E0002050B900BF502080F3118816
+:10B5D000BFF34F8FBFF36F8F00BF00BFFEE786B191
+:10B5E000002507E0715D04F134004155705D00B93C
+:10B5F00002E06D1C102DF5D300BF00214320015542
+:10B6000002E0002084F83400072F00D30627E76209
+:10B6100067640020A064201D06F06DF904F1180095
+:10B6200006F069F92461C7F10700A0616462002097
+:10B63000E06484F8500049464046039A00F018FB45
+:10B640002060BBF1000F01D0CBF80040BDE8FF9FA8
+:10B6500010B5002407E004EB84010F4A02EB8100DF
+:10B6600006F03CF9641C072CF5D30C4806F036F9BB
+:10B670000B4806F033F90B4806F030F90A4806F09B
+:10B680002DF90A4806F02AF90448094908600448D7
+:10B690000849086010BD0000B00700203C080020E9
+:10B6A0005008002064080020780800208C08002042
+:10B6B000180000201C00002010B50146164800E0CC
+:10B6C000006803688B42FBD30246436813448B42F5
+:10B6D00004D143684C682344436001460A464B68E2
+:10B6E00013440468A34211D10C4C03682468A3429C
+:10B6F00008D04B680468646823444B6003681B6887
+:10B700000B6005E0054B1B680B6001E003680B60F4
+:10B71000884200D0016010BD500000205800002079
+:10B7200070B5054606F010F9A86B08B9012400E0D1
+:10B73000002406F033F9204670BD70B5054606F0CA
+:10B7400003F9A86BE96B884201D1012400E00024D1
+:10B7500006F024F9204670BD0A490968096809B94C
+:10B76000012100E0002121B14FF0FF31064A1160B4
+:10B7700006E004490968C968C868034A416811605D
+:10B780007047000018000020440000200E480068A8
+:10B79000401C08B9012000E0002050B900BF502033
+:10B7A00080F31188BFF34F8FBFF36F8F00BF00BFCF
+:10B7B000FEE700BF502080F31188BFF34F8FBFF327
+:10B7C0006F8F00BF00BFFEE77000002070B5044619
+:10B7D00006F0BAF894F9455010E0606A08B9012003
+:10B7E00000E0002038B904F1240007F05BFA18B13A
+:10B7F00006F0CEF900E003E0681E45B2002DECDC57
+:10B8000000BFFF2084F8450006F0C8F806F09CF859
+:10B8100094F9445010E0206908B9012000E00020AC
+:10B8200048B904F1100007F03DFA08B106F0B0F98C
+:10B83000681E45B200E001E0002DECDC00BFFF20F7
+:10B8400084F8440006F0AAF870BD2DE9FC470546CF
+:10B85000884691464FF0000A09F1030020F00300EA
+:10B8600000F10807E86820B1082F02D007F0004077
+:10B8700010B10020BDE8FC872E1D3468B8F1000F20
+:10B8800025D06A4601A9404600F0B2F808B9002068
+:10B89000F0E718E0206810B1E868A04201D100206C
+:10B8A000E8E70198844200D20BE0DDE9001008448B
+:10B8B000A04201D80020DDE76068B84200D304E070
+:10B8C00000BF26462468002CE4D100BF0DE008E04C
+:10B8D000206810B1E868A04201D10020CAE72646DE
+:10B8E000246814B16068B842F2D30CB90020C1E7F3
+:10B8F00014B104F1080000E00020824620683060A6
+:10B9000028686168401A28603A462146284600F0B7
+:10B91000CFF8204600F040F85046ABE72DE9FC4157
+:10B9200004460D4600200190009000260027804626
+:10B930002AE06A4601A9284600F05AF800B920E03A
+:10B94000E06818B9019860600021A160E768DDE94E
+:10B95000001008440838E0600020E1680860E168F1
+:10B960004860019EE068306000980838706007B158
+:10B970003E6020687168084420602069401C206196
+:10B9800000BF08F101080835686810B12868002870
+:10B99000CFD12069BDE8FC8128B1416841F0004168
+:10B9A0004160014A02607047EFBEADDE70B50546EA
+:10B9B0000E4616B1A6F1080000E0002004469CB136
+:10B9C000606800F0004078B1084A206890420BD1CE
+:10B9D000606820F000406060286861680844286062
+:10B9E0002146284600F02DF870BD0000EFBEADDE08
+:10B9F00030B503460C461546002100220BB104B1B8
+:10BA00000DB9002030BD0020206028601A685968F8
+:10BA100002F0030038B102F00300C0F10400024458
+:10BA20001868101A091A21F00301102901D2002008
+:10BA3000E8E7102903D3226029600120E2E7002013
+:10BA4000E0E710B5024601B910BD101D00E0006826
+:10BA500010B103688B42FAD300B9F5E74368034499
+:10BA60008B4204D143684C68234443600146036819
+:10BA7000BBB103685B68A3B14B680B440468A34285
+:10BA80000FD10368D468A34202D1D3680B600AE0E7
+:10BA90004B680468646823444B6003681B680B6050
+:10BAA00001E003680B60884200D0016000BFCBE773
+:10BAB0002DE9F04707460C4615464FF0000A60682E
+:10BAC00000F00049606820F00048A8EB0500082855
+:10BAD0000ED36619A8EB0500706065603868716860
+:10BAE0000844386031463846FFF7ABFF4FF0010A93
+:10BAF000B9F1000F02D02046FFF74EFF5046BDE8D7
+:10BB0000F08700002DE9F04104464FF0000806F0F0
+:10BB10002BF94948006808B9FFF7CCFC4748006892
+:10BB20002040002870D1D4B1083404F00700B0B12F
+:10BB300004F00700C0F10800044404F0070008B94D
+:10BB4000012000E0002050B900BF502080F3118890
+:10BB5000BFF34F8FBFF36F8F00BF00BFFEE7002C16
+:10BB600052D03748006884424ED8364E3046056879
+:10BB700001E02E462D686868A04202D2286800289D
+:10BB8000F7D12D48006885423ED0306800F10808A2
+:10BB9000286830606868001B102819D92F1907F031
+:10BBA000070008B9012000E0002050B900BF502074
+:10BBB00080F31188BFF34F8FBFF36F8F00BF00BFBB
+:10BBC000FEE76868001B78606C603846FFF774FD1C
+:10BBD0001B4968680968081A19490860084600681E
+:10BBE00019490968884203D2154800681649086057
+:10BBF0001249686809680843686000202860134893
+:10BC00000068401C1149086007F098F808F0070028
+:10BC100008B9012000E0002050B900BF502080F397
+:10BC20001188BFF34F8FBFF36F8F00BF00BFFEE7D8
+:10BC30004046BDE8F0810000580000206C00002064
+:10BC40005C00002050000020600000206400002004
+:10BC50000648006830B10549096801F14800896C5F
+:10BC6000491C016001480068704700001400002072
+:10BC7000001F4FF080730360001F21F00103036079
+:10BC8000001F054B036014380260001F6FF00203B1
+:10BC900003602038704700008DB700083EB50024CF
+:10BCA000002000F035F884B245F2500084422CD0D8
+:10BCB000401C844229D01920ADF8040001208DF8E1
+:10BCC00006008DF807009DF807209DF80610BDF8C6
+:10BCD000043003F5FA6398B2FEF7C0FC8DF8080053
+:10BCE00000208DF800008DF801008DF80200002181
+:10BCF000009800F037F8DDE9010100F013F845F293
+:10BD00005101002000F07AF800BF01203EBD000084
+:10BD100001460022024800EB8102106870470000D3
+:10BD20005028004003B581B09DF806008DF8010051
+:10BD30009DF807008DF80200BDF80400C0B28DF830
+:10BD400003009DF808008DF80000002269460448B1
+:10BD5000F7F7ECF808B901200EBD0020FCE7000061
+:10BD6000A804002013B586B00C469DF818008DF885
+:10BD700004009DF819008DF805009DF81A008DF853
+:10BD800006008DF80740002004900590002201A9CC
+:10BD90000448F7F72BF910B9012008B010BD0020B6
+:10BDA000FBE70000A804002000B587B0002201A92D
+:10BDB0001048F7F71DF8002206A90E48F6F7F2FF23
+:10BDC0009DF804000C4988729DF805100A48C1725C
+:10BDD0009DF8061001739DF8181001729DF8191056
+:10BDE00081719DF81A10C1719DF81B00024988806D
+:10BDF00007B000BDA8040020A044002070B5044690
+:10BE00000D46F6F737FB2A4621460248F6F7C0FFF3
+:10BE100070BD0000A804002010B588B06946044831
+:10BE2000F7F7C2FA04460CB108B010BD00BFFBE73B
+:10BE30009457002010B50E480E4908600020486055
+:10BE400000210C488160C160016141610421816170
+:10BE5000F7F7CFFA08B1F4F74DFF4FF4006105484A
+:10BE6000F7F758F908B1F4F745FFFFF7D5FF10BD14
+:10BE7000002C0140945700200949496829B108491C
+:10BE8000496848600649486002E005490860486022
+:10BE900000214160416A21F0804141627047000009
+:10BEA0003C02002010B5282002F08EFC04462CB97C
+:10BEB00005A10DA002F02CFA002010BD204600F0D4
+:10BEC00045F82046F9E7000073676C5F616E696DA5
+:10BED0005F6372656174653A206D616C6C6F63209D
+:10BEE0006661696C656400001B5B33316D5B4552B4
+:10BEF000524F525D0000000010B5044600BF24B947
+:10BF0000B222084908A000F02DFB00BF606AC0F310
+:10BF1000807010B9204600F0DDF8204601F05EFF89
+:10BF200010BD0000033401082E2E5C557365725C51
+:10BF300073797374656D5C73676C5C636F72655C59
+:10BF400073676C5F616E696D2E6300000021416054
+:10BF500001608160C160016141618161C161016213
+:10BF6000416A21F000414162416A21F0804101F1C2
+:10BF70008041416270472DE9FF5F81468A46144641
+:10BF80009B46BAF1000F01D0D14503D3584604B007
+:10BF9000BDE8F09FB9F1000F01D12046F7E700207E
+:10BFA000000440EA19404FEA094152460023CDE916
+:10BFB000001008460199F4F796F988460746ABEB5E
+:10BFC0000405EE17A5FB070106FB071105FB081189
+:10BFD000000C40EA0140001902900298D7E70000E7
+:10BFE00070B5054600BF25B96D22134913A000F0B6
+:10BFF000B9FA00BF00241A480068A84208D11849BD
+:10C00000686808600846006808B90020486070BD8C
+:10C010001348046800E0646814B16068A842FAD16B
+:10C0200004B9F4E7686860600D484068A84201D12F
+:10C030000B48446000BFEAE7D63301082E2E5C555A
+:10C040007365725C73797374656D5C73676C5C6344
+:10C050006F72655C73676C5F616E696D2E63000063
+:10C060003C02002070B504460D4600BF24B9902262
+:10C070000D490EA000F076FA00BF606AC0F3807030
+:10C0800038B135B12046FFF7F7FE606A20F08040F6
+:10C09000606200BF0E48D0F8BC00A060606A65F323
+:10C0A0001D00606270BD0000E63301082E2E5C5555
+:10C0B0007365725C73797374656D5C73676C5C63D4
+:10C0C0006F72655C73676C5F616E696D2E630000F3
+:10C0D0004C28012010B5044600BF24B9A2220A4909
+:10C0E0000AA000F03FFA00BF606AC0F3807040B958
+:10C0F0002046FFF775FF606A20F0804000F1804025
+:10C1000060620020A06010BDF53301082E2E5C5542
+:10C110007365725C73797374656D5C73676C5C6373
+:10C120006F72655C73676C5F616E696D2E63000092
+:10C130002DE9F0474FF0000800250026304804683C
+:10C14000A94659E000BF2F48D0F8BC000646A068B9
+:10C15000B04200D950E0A068351A00BFA06920B9EC
+:10C16000D022294929A000F0FDF900BF00BFE069F5
+:10C1700020B9D122244925A000F0F4F900BFD4E968
+:10C180000423E168A94201D9AC4601E0D4F80CC00F
+:10C190006046E769B847804641462046A269904715
+:10C1A000E068A84226D2606A20F040406FF040412B
+:10C1B000884205D0606A401E616A60F31D016162B9
+:10C1C000206A10B12046216A8847606A20F040400A
+:10C1D00060B92046FFF77EFF606AC00F30B1D4F827
+:10C1E0000490204601F0FAFD4C4605E0D4E9020136
+:10C1F0000844A060646800BF002CA3D1BDE8F087AC
+:10C200003C0200204C280120133401082E2E5C55DE
+:10C210007365725C73797374656D5C73676C5C6372
+:10C220006F72655C73676C5F616E696D2E63000091
+:10C2300070B504460D46164600BF0CB105B12EB9C7
+:10C2400040F20132284929A000F08CF900BFB5F96D
+:10C250000200B4F90610884211DCB5F90600B4F901
+:10C26000021088420BDBB5F90000B4F904108842D3
+:10C2700005DCB5F90400B4F90010884201DA0020A9
+:10C2800070BDB4F90000B5F90010884202DDB4F9C0
+:10C29000000001E0B5F900003080B4F90400B5F900
+:10C2A0000410884202DAB4F9040001E0B5F9040090
+:10C2B000B080B4F90200B5F90210884202DDB4F989
+:10C2C000020001E0B5F902007080B4F90600B5F98A
+:10C2D0000610884202DAB4F9060001E0B5F906005A
+:10C2E000F0800120CCE700009A3201082E2E5C5528
+:10C2F0007365725C73797374656D5C73676C5C6392
+:10C300006F72655C73676C5F636F72652E630000AC
+:10C3100010B50246B2F90000B1F90030984202DAD5
+:10C32000B2F9000001E0B1F90000B2F900301B1AC7
+:10C33000B2F90400B1F90440A04202DDB2F90400F0
+:10C3400001E0B1F90400B2F90440001B0344B2F962
+:10C350000200B1F90240A04202DAB2F9020001E0A3
+:10C36000B1F90200B2F90240201A0344B2F9060002
+:10C37000B1F90640A04202DDB2F9060001E0B1F9D0
+:10C380000600B2F90640001B184410BD10B5044663
+:10C3900000BF2CB940F22E72064907A000F0E2F867
+:10C3A00000BF4FF40050608020804042E080A080B9
+:10C3B00010BD00005B3101082E2E5C557365725C68
+:10C3C00073797374656D5C73676C5C696E636C75AF
+:10C3D00064655C73676C5F636F72652E6800000054
+:10C3E00070B504460D4600BF04B12DB94FF4467236
+:10C3F000284929A000F0B6F800BFB5F90200B4F949
+:10C400000610884211DCB5F90600B4F90210884222
+:10C410000BDBB5F90000B4F90410884205DCB5F96E
+:10C420000400B4F90010884201DA002070BDB4F9AC
+:10C430000000B5F90010884202DDB4F9000001E007
+:10C44000B5F900002080B4F90400B5F90410884261
+:10C4500002DAB4F9040001E0B5F90400A080B4F9EF
+:10C460000200B5F90210884202DDB4F9020001E0D1
+:10C47000B5F902006080B4F90600B5F906108842EB
+:10C4800002DAB4F9060001E0B5F90600E080012007
+:10C49000CCE70000A83201082E2E5C557365725C53
+:10C4A00073797374656D5C73676C5C636F72655CE4
+:10C4B00073676C5F636F72652E63000070B504462E
+:10C4C0000D4600BF04B12DB940F2AD721A491BA050
+:10C4D00000F048F800BFB4F90000B5F90010884238
+:10C4E00002DAB4F9000001E0B5F900002080B4F9E7
+:10C4F0000400B5F90410884202DDB4F9040001E03B
+:10C50000B5F90400A080B4F90200B5F90210884220
+:10C5100002DAB4F9020001E0B5F902006080B4F972
+:10C520000600B5F90610884202DDB4F9060001E004
+:10C53000B5F90600E08070BD7D3101082E2E5C55F6
+:10C540007365725C73797374656D5C73676C5C6939
+:10C550006E636C7564655C73676C5F636F72652E88
+:10C560006800000008B504460D4616462B462246D4
+:10C5700003A10CA0009601F0CBFE00BFFEE7000077
+:10C5800066696C653A2025732C2066756E63746944
+:10C590006F6E3A2025732C206C696E653A202564F5
+:10C5A000000000001B5B33366D5B41535345525412
+:10C5B0005D0000002DE9F041002002F0BFF80646C2
+:10C5C00035465848B0F91000032190FBF1F007B24E
+:10C5D0005448B0F9120090FBF1F00FFA80F800BF58
+:10C5E00000BF2DB940F2EF524F4950A0FFF7BAFFFC
+:10C5F00000BF28893844401E01B2A981688940449F
+:10C60000401E01B2E981284602F060FE00BF002111
+:10C61000304602F095FE0021304602F0F9FEFFF7A9
+:10C6200041FC04462546374600BF00BF25B9B52268
+:10C63000484949A0FFF796FF00BF2F6000BF25467D
+:10C640004FF47A7700BF00BF25B9F8224C4942A0C9
+:10C65000FFF788FF00BFEF6000BF2546FF2700BF40
+:10C6600000BF25B9D12247493BA0FFF77BFF00BFA0
+:10C670002F6100BF2546002700BF00BF25B9DE227D
+:10C68000414935A0FFF76EFF00BF6F6100BF25462F
+:10C690003E4FDFF8FC8000BF00BF1DB117B1B8F1FD
+:10C6A000000F04D1C3223B492BA0FFF75BFF00BF63
+:10C6B000AF61C5F81C8000BF01212046FFF7D2FC06
+:10C6C00018E000BF00BF1748D0F8BC0000BF1549F4
+:10C6D000D1F8B810401A0A2800D20AE000BF114869
+:10C6E000D0F8BC000F49C1F8B80000BF03F068F9EA
+:10C6F00000BF00BF254600BF00BF2DB940F2111298
+:10C70000254915A0FFF72EFF00BF686AC0F38070AF
+:10C710000028D6D02046FFF7EFFB304602F0F0F9B4
+:10C72000BDE8F0814C280120AE3901082E2E5C5561
+:10C730007365725C73797374656D5C73676C5C6947
+:10C740006E636C7564655C73676C5F636F72652E96
+:10C7500068000000FD3901082E2E5C557365725C7F
+:10C7600073797374656D5C73676C5C696E636C750B
+:10C7700064655C73676C5F616E696D2E68000000B4
+:10C78000513A0108213A01083A3A010885E30008C4
+:10C7900077BF00080F3A01086B3A010837B581B03E
+:10C7A000101DC208BDF8080040EA00400B4D00EA29
+:10C7B0000501BDF8040040EA004000EA0503581AEC
+:10C7C000504301EB501000EA050444EA144080B2E3
+:10C7D0000090BDF80050284604B030BD1FF8E007B7
+:10C7E00037B581B0101DC208BDF8080040EA00400E
+:10C7F0000B4D00EA0501BDF8040040EA004000EAE4
+:10C800000503581A504301EB501000EA050444EAAE
+:10C81000144080B20090BDF80050284604B030BDEE
+:10C820001FF8E00770B594B00446002528466D1C3B
+:10C8300004A941F82040BBE000BF102D05DB40F209
+:10C84000AA525E495EA0FFF78DFE00BF681E054636
+:10C8500004A951F82040606A20B128466D1C626A24
+:10C8600041F82020204602F03DFB00B1A0E0264622
+:10C8700000BF00BF2EB94FF482625A495A48FFF7F1
+:10C8800071FE00BF96F8280000F00100E0B12046DC
+:10C8900000F0BAF8554B0FCB8DE80F0000BFA06930
+:10C8A00028B940F2C152454945A0FFF75BFE00BFE1
+:10C8B0006A4621460020A3699847204602F0C4FB3F
+:10C8C000204602F06DF973E0264600BF00BF2EB986
+:10C8D00040F2564246494448FFF744FE00BF96F8EE
+:10C8E0002800C0F3C00000282BD0404B1033D3E900
+:10C8F0000020D3E90213CDE90213CDE9002000BFE7
+:10C90000A06928B940F2D5522C492DA0FFF72AFE84
+:10C9100000BF6A4621460020A3699847264600BF0B
+:10C9200000BF2EB940F2624232492F48FFF71AFE8B
+:10C9300000BF96F8280020F0080086F8280000BF05
+:10C9400000BF264600BF00BF2EB940F23E422A4932
+:10C950002548FFF707FE00BF96F82800C0F3400007
+:10C96000E8B1204600F050F8E16902A802F064F94D
+:10C97000224604F1080102A8FFF75AFC80F00100EA
+:10C9800030B12046FFF702FD204602F03BF80FE0F1
+:10C99000204600F039F8204602F034F800BF206A43
+:10C9A00028B128466D1C04A9226A41F8202000BF46
+:10C9B000002D3FF741AF14B070BD00008D3301086A
+:10C9C0002E2E5C557365725C73797374656D5C7340
+:10C9D000676C5C636F72655C73676C5F636F7265D5
+:10C9E0002E630000BC30010878EB0008A833010872
+:10C9F000083101081C310108F73001080021014805
+:10CA0000018670474C2801202DE9F041044600BF03
+:10CA10002CB94FF45572324932A0FFF7A3FD00BF85
+:10CA20004FF0FF376FF000487E08B4F90000B4F90A
+:10CA30000410884205DCB4F90200B4F906108842FB
+:10CA400001DDBDE8F0813048008E38B92E482168FC
+:10CA500041636168816301210186F2E7002517E0E7
+:10CA60002949343101EBC500214601F0D7FE68B1F8
+:10CA70002549343101EBC5002146FFF749FC064644
+:10CA800006B9DEE7464501DAB0462F46681CC5B256
+:10CA90001D48008EA842E3DC002F07DB1A49343121
+:10CAA00001EBC7002146FFF709FDCAE71648008ED3
+:10CAB00010280EDA1448018E008E401C82B21248F3
+:10CAC0000286343000EBC10021680160616841607A
+:10CAD00004E021460C48AC30FFF7F0FC00BFB0E7A3
+:10CAE000BA3201082E2E5C557365725C73797374CB
+:10CAF000656D5C73676C5C636F72655C73676C5FBC
+:10CB0000636F72652E6300004C2801202DE9FF4FF2
+:10CB100091B005461E9F219C07EB4701606800EB22
+:10CB2000810090F90B006189081AB4F91410401AB9
+:10CB3000109007EB4701606850F82100216800EB76
+:10CB4000010807EB4701606800EB8100007A0F9055
+:10CB500007EB4701606800EB810080790E900020B0
+:10CB60000D900A900890824607EB4701606800EB41
+:10CB7000810090F90A101398084400B2ADF8100033
+:10CB80001099149801440E98081A00B2ADF81200DA
+:10CB900007EB4701606800EB810090F90A101398D9
+:10CBA00001440F980844401E00B2ADF814001099DB
+:10CBB00014980844401E00B2ADF816000DF1100B99
+:10CBC00006A8039059462846039AFFF731FB10B98F
+:10CBD00015B0BDE8F08F06A81299FFF701FC00B967
+:10CBE000F6E7BDF818202B88D21A10B2BDF81A202B
+:10CBF0006B88D21A11B22B8A01FB0303AA6802EBDD
+:10CC000043020892BDF91AB07AE0DDF820A0BDF920
+:10CC10001200ABEB00000B90BDF91800039063E02D
+:10CC2000BDF910100398401A0C900F9ADDE90B1013
+:10CC300001FB0206A07D042810D1C6F34F0906F0BF
+:10CC4000010020B118F8090000F00F0002E018F808
+:10CC5000090000112D49085C0A9029E0A07D0228F6
+:10CC600011D1C6F38F0906F00300C0F103004000A4
+:10CC70000D9018F809000D99084100F003002449AF
+:10CC8000085C0A9014E0A07D012811D1C6F3CF09F9
+:10CC900006F00700C0F107000D9018F809000D9983
+:10CCA000084100F0010008B1FF2000E000200A90D8
+:10CCB0000A98C2B2BAF80000014602901F98FFF726
+:10CCC0008FFD0990BAF8000001900146209A09985A
+:10CCD000FFF786FD0290BDF80800AAF800000AF1EF
+:10CCE000020A0398401C0390BDF91C10039881426E
+:10CCF00096DA298A089800EB410008900BF1010BA5
+:10CD0000BDF91E00584580DA00BF61E78030010898
+:10CD1000903001082DE9FF4F91B0824617461D461D
+:10CD2000DDF87C804FF0000B002400200E90B7F956
+:10CD3000000028440D90B7F90400401B0C90B7F98F
+:10CD4000020028440B90B7F90600401B0A9000200F
+:10CD5000099008900FAA5046129902F001FE10B9EE
+:10CD600015B0BDE8F08F39460FA8FFF739FB00B9C1
+:10CD7000F6E700200790069005FB05F00590681C7B
+:10CD800040430490BDF83E00BAF80230C01A02B227
+:10CD9000BDF83C00BAF80030C01A01B2504602F0AB
+:10CDA000E9FD83464DBBBDF93E6021E05C46BDF91F
+:10CDB0003C9014E0B8F1FF0F03D1BDF8780020805B
+:10CDC0000AE020884246014602901E98FFF7E6FCE2
+:10CDD0000390BDF80C00208009F10109A41CBDF9E5
+:10CDE00040004845E6DABAF810000BEB400B761C21
+:10CDF000BDF94200B042D9DAB1E0BDF93E90A9E0F8
+:10CE00005C460B9881451EDD0A9881451BDABDF909
+:10CE10003C6013E0B8F1FF0F03D1BDF8780020802B
+:10CE20000AE020884246014602901E98FFF7B6FCB1
+:10CE30000390BDF80C002080761CA41CBDF94000B6
+:10CE4000B042E7DA80E00B98814501DD0A9800E006
+:10CE50000B9808900898A9EB000040430790BDF993
+:10CE60003C606DE00D98864215DD0C98864212DA22
+:10CE7000B8F1FF0F03D1BDF8780020805DE0208875
+:10CE80004246014602901E98FFF788FC0390BDF8C9
+:10CE90000C00208051E00D98864201DD0C9800E0E6
+:10CEA0000D9809900998311A321A079801FB02006F
+:10CEB000069004990698884200DB3FE0DDE9051002
+:10CEC000884228DB069802F0CFFCC0F1FF000E90EC
+:10CED000B8F1FF0F0BD12088009001460E9A1E98E2
+:10CEE000FFF75CFC0190BDF80400208025E020885D
+:10CEF000009001460E9A1E98FFF750FC0390208880
+:10CF00004246014600900398FFF748FC0290BDF8A6
+:10CF10000800208011E0B8F1FF0F03D1BDF87800C0
+:10CF200020800AE020884246014602901E98FFF7C2
+:10CF300035FC0390BDF80C00208000BF761CA41CBB
+:10CF4000BDF94000B0428DDABAF810000BEB400B8F
+:10CF500009F10109BDF942004845BFF651AF00BFD4
+:10CF6000FEE62DE9FF4F97B0834615461F46DDF8D4
+:10CF700094A000201490002400261390B5F900001E
+:10CF800038441290B5F90400C01B1190B5F90200A5
+:10CF900038441090B5F90600C01B0F9000200E9089
+:10CFA0000D9015AA5846189902F0DAFC10B91BB07A
+:10CFB000BDE8F08F294615A8FFF712FA00B9F6E789
+:10CFC00000200C900B9007FB07F00A90781C404360
+:10CFD0000990B5F90400B5F90010401A401C2499D5
+:10CFE0000988C904490A91FBF0F00890B5F90600D8
+:10CFF000B5F90210401A401C24990968C1F34C315C
+:10D00000890291FBF0F00790002006900590BDF892
+:10D010005600BBF80230C01A02B2BDF85400BBF88B
+:10D020000030C01A01B2584602F0A4FC1490002F40
+:10D0300044D1BDF956803CE0149CB5F90200A8EB40
+:10D04000000007994843800A0590BDF9549024E0F8
+:10D05000B5F90000A9EB000008994843800A069042
+:10D06000059802B2069801B2249802F0F7FA064633
+:10D07000BAF1FF0F02D1308820800BE020880390A6
+:10D080003088524602900399FFF788FB0490BDF860
+:10D090001000208009F10109A41CBDF95800484581
+:10D0A000D6DABBF81010149800EB4100149008F188
+:10D0B0000108BDF95A004045BEDAE2E0BDF95690DC
+:10D0C000DAE0149CB5F90200A9EB00000799484387
+:10D0D000800A0590109881452FDD0F9881452CDA44
+:10D0E000BDF9548024E0B5F90000A8EB00000899D0
+:10D0F0004843800A0690059802B2069801B2249827
+:10D1000002F0ACFA0646BAF1FF0F02D13088208057
+:10D110000BE0208803903088524602900399FFF775
+:10D120003DFB0490BDF81000208008F10108A41C0C
+:10D13000BDF958004045D6DA96E01098814501DDEA
+:10D140000F9800E010980D900D98A9EB0000404357
+:10D150000C90BDF9548082E0B5F90000A8EB000006
+:10D1600008994843800A0690059802B2069801B2D1
+:10D17000249802F073FA06461298804515DD11983E
+:10D18000804512DABAF1FF0F02D13088208062E0C8
+:10D19000208803903088524602900399FFF7FEFAE8
+:10D1A0000490BDF81000208055E01298804501DD04
+:10D1B000119800E012980E900E98A8EB0001A8EBD1
+:10D1C00000020C9801FB02000B9009990B98884211
+:10D1D00000DB41E0DDE90A1088422ADB0B9802F00F
+:10D1E00043FBC0F1FF001390BAF1FF0F0CD1208870
+:10D1F000019030880090139A0199FFF7CFFA0290BE
+:10D20000BDF80800208026E020880190308800903A
+:10D21000139A0199FFF7C2FA0490208852460146FA
+:10D2200001900498FFF7BAFA0390BDF80C00208033
+:10D2300011E0BAF1FF0F02D1308820800BE0208886
+:10D2400003903088524602900399FFF7A7FA0490A2
+:10D25000BDF81000208000BF08F10108A41CBDF932
+:10D2600058004045BFF678AFBBF81010149800EB9B
+:10D270004100149009F10109BDF95A004845BFF673
+:10D2800020AF00BF93E62DE9FF4F99B016461F4629
+:10D29000DDE928A5A7EB0A00401C002803DDA7EB69
+:10D2A0000A00401C00E000201890002017908346E0
+:10D2B00018984043169007FB07F015900020149033
+:10D2C00000241390B6F9000038441290B6F9040017
+:10D2D000C01B1190B6F9020038441090B6F9060050
+:10D2E000C01B0F90B6F9000050440E90B6F9040030
+:10D2F000A0EB0A000D90B6F9020050440C90B6F96C
+:10D300000600A0EB0A000B9000200A9009901898E4
+:10D31000401E40430890781C4043079005AADDE971
+:10D32000190102F01DFB10B91DB0BDE8F08F3146A8
+:10D3300005A8FFF755F800B9F6E7BDF816301998BB
+:10D340004088181A02B2BDF8143019980088181ACB
+:10D3500001B2199802F00EFB1490002F49D1BDF9CB
+:10D36000168041E0149CBDF9149031E00E9881457F
+:10D370001ADB0D98814517DC0C98804514DB0B985F
+:10D38000804511DCFF2D03D1BDF8980020801CE002
+:10D3900020882A46014603902698FFF7FFF904905B
+:10D3A000BDF81000208010E0FF2D03D1BDF89C00D7
+:10D3B00020800AE020882A46014603902798FFF73C
+:10D3C000EDF90490BDF81000208009F10109A41CBA
+:10D3D000BDF918004845C9DA1999098A149800EB73
+:10D3E0004100149008F10108BDF91A004045B9DA6E
+:10D3F0001BE1BDF9168013E1149C1098804536DDC1
+:10D400000F98804533DABDF914902BE00E988145D2
+:10D4100002DB0D98814511DDFF2D03D1BDF89C0085
+:10D4200020801CE020882A46014603902798FFF7B9
+:10D43000B5F90490BDF81000208010E0FF2D03D155
+:10D44000BDF8980020800AE020882A460146039013
+:10D450002698FFF7A3F90490BDF81000208009F189
+:10D460000109A41CBDF918004845CFDAD0E0109896
+:10D47000804501DD0F9800E0109809900998A8EB0D
+:10D48000000040431790BDF91490BCE0129881450C
+:10D490002CDB1198814529DC0C98804502DB0B9828
+:10D4A000804511DDFF2D03D1BDF89C002080A6E052
+:10D4B00020882A46014603902798FFF76FF90490C9
+:10D4C000BDF8100020809AE0FF2D03D1BDF8980030
+:10D4D000208094E020882A46014603902698FFF792
+:10D4E0005DF90490BDF81000208088E01298814515
+:10D4F00001DD119800E012980A900A98A9EB00014A
+:10D50000A9EB0002179801FB020B0798834500DB8B
+:10D5100076E00898834511DAFF2D03D1BDF8980015
+:10D5200020800AE020882A46014603902698FFF7CB
+:10D5300035F90490BDF81000208061E0169883450D
+:10D5400021DA584602F090F91390FF2D09D1139A71
+:10D55000DDE92610FFF722F90290BDF808002080CF
+:10D560004DE0139ADDE92610FFF718F904902088A2
+:10D570002A46014601900498FFF710F90390BDF880
+:10D580000C0020803BE01598834527DD584602F0CB
+:10D590006BF9C0F1FF001390FF2D0BD12088019093
+:10D5A0000146139A2798FFF7F9F80290BDF8080092
+:10D5B000208024E0208801900146139A2798FFF7E5
+:10D5C000EDF8049020882A46014601900498FFF760
+:10D5D000E5F80390BDF80C00208010E0FF2D03D18A
+:10D5E000BDF89C0020800AE020882A46014603906E
+:10D5F0002798FFF7D3F80490BDF81000208000BFF3
+:10D6000009F10109A41CBDF918004845BFF63EAF59
+:10D610001999098A149800EB4100149008F1010847
+:10D62000BDF91A004045BFF6E7AE00BF7CE62DE924
+:10D63000F04F85B08046894617469A46DDE910B519
+:10D640000E9C002004901FE004A9204602F0CAF9B5
+:10D6500004442846049902F0B1F80646CDE902B523
+:10D66000BDF83C00ADF8040053463A4649464046F2
+:10D670000096FFF74BFA06EB4601686800EB810065
+:10D68000808807EB201007B220780028DCD105B095
+:10D69000BDE8F08F2DE9FE43064606F11404D6F8E6
+:10D6A000B090002500279EE006F1300000EBC70592
+:10D6B000656100BFADB1B5F90000002811DBB5F917
+:10D6C000020000280DDB4C48B0F91000B5F9041039
+:10D6D000884206DD4848B0F91200B5F906108842C4
+:10D6E00005DC40F20D62454945A0FEF73BFF00BF57
+:10D6F0004FF00008E8886988401A401C608228883A
+:10D70000208068886080A888A080A0882188401A2E
+:10D71000401C2082218AE068B0FBF1F1B5F90600D7
+:10D72000B5F90220801A401C814204D2218AE068A7
+:10D73000B0FBF1F005E0B5F90600B5F90210401AAA
+:10D74000401C6082B5F90600B5F90410B5F9022055
+:10D75000CDE900210290B5F9003096F82E2031A1D4
+:10D760003FA000F0D5FD37E0B5F90600B4F902108E
+:10D77000401A401C618A884206DAB5F90600B4F9FD
+:10D780000210401A401C00E0608A1FFA80F860888E
+:10D790004044401E00B2E08000BF00BF96F82F005A
+:10D7A000154991F8322001219140084008B9012023
+:10D7B00000E000200028F0D12E3670783178C1F1D9
+:10D7C0000201084070702E3E21464846FCF7D6FE06
+:10D7D0006088404400B26080B4F90200B5F90610D8
+:10D7E0008842C1DD7F1CB08DB8423FF75DAF00209D
+:10D7F000B085BDE8FE8300004C280120C833010835
+:10D800002E2E5C557365725C73797374656D5C73F1
+:10D81000676C5C636F72655C73676C5F636F726586
+:10D820002E6300005B66623A25645D73676C5F641B
+:10D830007261775F7461736B3A20646972747920E6
+:10D8400061726561202078313A25642079313A256A
+:10D85000642078323A25642079323A256400000049
+:10D860001B5B33346D5B54524143455D0000000047
+:10D8700000210348A0F80A11A0F808110020704701
+:10D88000105101201FB500BF134991F80811491C20
+:10D8900001F00F001049B1F80A11814201D10121B4
+:10D8A00000E0002121B10DA118A000F031FD1FBD45
+:10D8B0000948B0F80811083000EB01109DE81E007F
+:10D8C0001EC0054890F80801401C00F00F010248F6
+:10D8D000A0F8081100BFEAE7105101204576656EF7
+:10D8E000742071756575652069732066756C6C2C84
+:10D8F000206D617962652073797374656D20697339
+:10D9000020746F6F20736C6F770000001B5B3331E6
+:10D910006D5B4552524F525D000000007FB5002400
+:10D92000ADE0009C6CB9BDF80C00062804D002A83C
+:10D93000FCF774FD044604E064480468684600F09F
+:10D940000FFB002C7ED0BDF90810B4F90C00814209
+:10D9500002DABDF9080001E0B4F90C00B4F90810CE
+:10D96000884202DAB4F908000AE0BDF90810B4F9F7
+:10D970000C00814202DABDF9080001E0B4F90C00A4
+:10D98000ADF80800BDF90A10B4F90E00814202DAC0
+:10D99000BDF90A0001E0B4F90E00B4F90A1088429A
+:10D9A00002DAB4F90A000AE0BDF90A10B4F90E006F
+:10D9B000814202DABDF90A0001E0B4F90E00ADF8C7
+:10D9C0000A00BDF80C0002280DD194F82A00C0F31B
+:10D9D000800000B153E0608D20F00400001D6085E0
+:10D9E0003A4804601EE0BDF80C0003281AD194F8F0
+:10D9F0002A00C0F3800070B93448006850B1334841
+:10DA00000068A04206D03148006800909DE80F00F1
+:10DA1000FFF738FF33E0608D20F0040060850020C0
+:10DA20002A49086000BFA06928B94FF4AA722849A2
+:10DA300028A0FEF797FD00BF6069019000946A4638
+:10DA4000214600E008E00020A36998472069A8B1BA
+:10DA500068462169884711E027A134A000F058FCEE
+:10DA6000BDF80C00032809D11848006830B11748E8
+:10DA7000006800909DE80F00FFF704FF00BF6846B4
+:10DA800000BF1249B1F80821B1F80A118A4201D148
+:10DA9000012100E0002111B14FF0FF3112E00B49EC
+:10DAA000B1F80A21083101EB02152ECD80E82E00D5
+:10DAB000064991F80A11491C01F00F020349A1F827
+:10DAC0000A21002100293FF42CAF7FBD1051012015
+:10DAD000823401082E2E5C557365725C7379737401
+:10DAE000656D5C73676C5C636F72655C73676C5FBC
+:10DAF0006576656E742E6300706F73206973206F96
+:10DB00007574206F66206F626A656374206F72207F
+:10DB10006E6F206576656E745F6C6F73742C207306
+:10DB20006B6970206576656E740000001B5B333492
+:10DB30006D5B54524143455D0000000010B5044642
+:10DB40000CB9012000E0002040B13E23324A33A14D
+:10DB50003CA000F0DDFB4FF0FF3010BD206868B93D
+:10DB60003CA138A000F0D4FB00BF42222A4943A0C8
+:10DB7000FEF7F8FC00BF4FF0FF30EEE7206968B910
+:10DB800047A130A000F0C4FB00BF482222493BA0BF
+:10DB9000FEF7E8FC00BF4FF0FF30DEE7A06868B991
+:10DBA00048A128A000F0B4FB00BF4E221A4933A0C0
+:10DBB000FEF7D8FC00BF4FF0FF30CEE7142221461D
+:10DBC0004B48F2F7C1FB4A48001F2168016200215F
+:10DBD00001834183A089401E01B24548001F818313
+:10DBE000E089401E01B24248001FC183A168416222
+:10DBF000A08981B23E48001F018500203C49091FD1
+:10DC0000C1F8BC0003213A48001F80F833100021FE
+:10DC100080F832100020A0E7A431010846756E6339
+:10DC200074696F6E3A2025732C204C696E653A201A
+:10DC300025642C206662696E666F206973204E55DC
+:10DC40004C4C00001B5B33316D5B4552524F525DB3
+:10DC500000000000596F7520686176656E2774209A
+:10DC600073657420757020746865206672616D65D7
+:10DC7000206275666665722E000000002E2E5C55CF
+:10DC80007365725C73797374656D5C73676C5C63E8
+:10DC90006F72655C73676C5F636F72652E63000003
+:10DCA000596F7520686176656E27742073657420DE
+:10DCB00075702074686520666C7573682061726584
+:10DCC000612E0000596F7520686176656E2774209B
+:10DCD00073657420757020746865206672616D6567
+:10DCE000206275666665722073697A652E00000091
+:10DCF000502801202DE9FC4104460D46E08880B201
+:10DD0000CDE90005A788BBB26788BAB22788B9B247
+:10DD1000124F38693F697E6FB04700BF104890F8D6
+:10DD200033000F4991F83220012191400843C1B2DC
+:10DD30000B4880F83310806860B1094890F83200D1
+:10DD400080F00101064880F83210001D50F82110C3
+:10DD5000001F016200BFBDE8FC810000A04400205C
+:10DD60004C280120F8B505460C4600BF2CB940F2FE
+:10DD70005142104910A0FEF7F5FB00BF002600201D
+:10DD80000090002711E06946284601F02BFE05446B
+:10DD90002046009901F012FD074607EB4701606835
+:10DDA00000EB8100808806EB201628780028EAD155
+:10DDB0003046F8BD003301082E2E5C557365725C49
+:10DDC00073797374656D5C73676C5C636F72655CAB
+:10DDD00073676C5F636F72652E63000010B5044655
+:10DDE0002046FCF7C5FE04498968081A0249886084
+:10DDF0002046FCF7A5FE10BD1C520120F8B50446D4
+:10DE00000D46164600BF04B12DB94FF492624A493F
+:10DE10004AA0FEF7A7FB00BF00200090092E74D295
+:10DE2000DFE806F0051C2B313B4D57647400B4F954
+:10DE30000010B5F90020881A00EBD071491009B222
+:10DE4000ADF80010B4F90210B5F90220881A00EB01
+:10DE5000D071491009B2ADF802106AE0B4F90010AF
+:10DE6000B5F90020881A00EBD071491009B2ADF85D
+:10DE700000100020ADF802005BE00020ADF80000CB
+:10DE8000ADF8020055E020882988401A00B2ADF8AC
+:10DE900000000020ADF802004BE0B4F90010B5F925
+:10DEA0000020881A00EBD071491009B2ADF80010BB
+:10DEB00060886988401A00B2ADF8020039E000209D
+:10DEC000ADF8000060886988401A00B2ADF8020021
+:10DED0002FE020882988401A00B2ADF80000608841
+:10DEE0006988401A00B2ADF8020022E00020ADF8C7
+:10DEF0000000B4F90210B5F90220881A00EBD071C5
+:10DF0000491009B2ADF8021013E011E02088298809
+:10DF1000401A00B2ADF80000B4F90210B5F90220C1
+:10DF2000881A00EBD071491009B2ADF8021000E078
+:10DF300000BF00BF0098F8BD1A3301082E2E5C55B3
+:10DF40007365725C73797374656D5C73676C5C6325
+:10DF50006F72655C73676C5F636F72652E63000040
+:10DF600010B50389164CA4881B1B19B24489144BA5
+:10DF7000DB88E31A1AB2002901DD0B4600E04B42B0
+:10DF8000002A01DD144600E05442A3420ADD0029C4
+:10DF900003DD0A238381C1810EE0092383814B4283
+:10DFA000C38109E0002A03DD08238381C28103E0E5
+:10DFB000072383815342C381014B84685C6010BD99
+:10DFC000105101202DE9FE4304460D4617469846A0
+:10DFD000DDF8289000BF04B12DB940F2D2422149AA
+:10DFE00021A0FEF7BFFA00BF00200290A088218880
+:10DFF000401A401C00B2ADF80400E0886188401A65
+:10E00000401C00B2ADF8060029463846FFF7AAFECC
+:10E01000404400B2ADF800002E4600BF00BF2EB94C
+:10E0200040F2E27219491A48FEF79CFA00BF708963
+:10E0300000B2ADF802004A46694601A8FFF7DEFECD
+:10E040000290BDF808002188084400B2ADF808002D
+:10E05000BDF80A006188084400B2ADF80A000298D1
+:10E06000BDE8FE832C3301082E2E5C557365725C6F
+:10E0700073797374656D5C73676C5C636F72655CF8
+:10E0800073676C5F636F72652E63000090310108E7
+:10E0900078EB000810B500244FF42051124800F02E
+:10E0A0006DFC00211148C0F8B410FEF7A7FC002059
+:10E0B00000F0D0FC044634B90DA117A000F028F9F7
+:10E0C0004FF0FF3010BDFFF7D3FB48B116A112A0EF
+:10E0D00000F01EF92046FFF781FE4FF0FF30F1E718
+:10E0E000FEF768FA0020EDE7102901204C280120F6
+:10E0F00073676C5F696E69743A20637265617465F9
+:10E100002073637265656E206F626A656374206652
+:10E1100061696C65640000001B5B33316D5B4552C7
+:10E12000524F525D0000000073676C5F696E697446
+:10E130003A206576656E7420717565756520696E27
+:10E140006974206661696C6564000000F0B585B093
+:10E1500007460D4616462C4600BF206B20B93022DC
+:10E16000214922A0FEF7FEF900BFB0890F2839D15E
+:10E1700094F83900C0F3801068B194F83800019029
+:10E18000E08EADF80000688D030905F1080229460C
+:10E190003846FEF7BFFD94F8390000F03F000090CC
+:10E1A000002305F10800D4E90B21FFF70BFF0490D1
+:10E1B00094F83810206BCDE90210A08EADF8040061
+:10E1C000E06A0090BDF8121094F93B00084403B2D5
+:10E1D000BDF8100094F93A10084402B229463846B6
+:10E1E000FFF725FA05B0F0BDC05D01082E2E5C5585
+:10E1F0007365725C73797374656D5C73676C5C775F
+:10E200006964676574735C6C6162656C5C73676C90
+:10E210005F6C6162656C2E6300000000F8B5064615
+:10E220003C2000F0D1FA04462CB916A11DA000F044
+:10E230006FF80020F8BD3C212046F2F7ACF82546E7
+:10E240003146204600F0C0FD1A48A861FF202C345A
+:10E250002073607B20F04000607300200090BDF8C8
+:10E260000000208112A020600020E081607B20F06F
+:10E270008000607300BF1048D0F8C00060602C3C84
+:10E280002846D7E773676C5F6C6162656C5F637289
+:10E29000656174653A206D616C6C6F6320666169BD
+:10E2A0006C6564001B5B33316D5B4552524F525DB0
+:10E2B000000000004DE100084C28012070B5044624
+:10E2C0000D4626463563204600F0ACFF70BD70B5A4
+:10E2D00004460D462646F562204600F0A3FF70BDB9
+:10E2E00070B504460E46254695F8390066F30500DC
+:10E2F00085F83900204600F095FF70BD73B50446DF
+:10E300002546BDF80400A886204600F08BFF7CBDA2
+:10E310000FB4F0B59FB0044600252046F2F746F84A
+:10E320000746214601A8F2F756F826A8009001A951
+:10E33000C8197821009B259A01F09CFB00200090D1
+:10E3400001A8F2F733F8054601A828440AA10A6893
+:10E35000026089888180002101AAA81D115401AEA4
+:10E360000748006818B1064801683046884700BF72
+:10E370001FB0F0BC5DF814FB0D0A1B5B306D000094
+:10E380004C28012070B504460D462668E9B2304697
+:10E3900000F010FA70BD00002DE9F0472DED028B62
+:10E3A0008AB007460C4690462546A0882188401A28
+:10E3B000401C0FFA80F9E0886188401A401C0FFA6F
+:10E3C00080FA1A2099FBF0F000EE100AB8EEC00AAD
+:10E3D000B0EE408A0E209AFBF0F000EE100AB8EE84
+:10E3E000C00AF0EE408AB8F80C000F287DD106AEC6
+:10E3F000324621463846FDF71BFF20B90AB0BDEC76
+:10E40000028BBDE8F087002680E0B4F9000000EE42
+:10E41000100AB8EEC00AC54810F8260000EE900AAF
+:10E42000F8EE600A00EE880ABDEEC00A10EE100A8F
+:10E4300000B2ADF82000B4F9020000EE100AB8EE08
+:10E44000C00ABA4800EB8600407800EE900AF8EE69
+:10E45000600A00EEA80ABDEEC00A10EE100A00B273
+:10E46000ADF82200B4F9000000EE100AB8EEC00AC0
+:10E47000AE4800EB8600807800EE900AF8EE600A65
+:10E4800000EE880AF7EE000A30EE600ABDEEC00A20
+:10E4900010EE100A00B2ADF82400B4F9020000EE4C
+:10E4A000100AB8EEC00AA14800EB8600C07800EE62
+:10E4B000900AF8EE600A00EEA80AF7EE000A30EEC5
+:10E4C000600ABDEEC00A10EE100A00B2ADF82600D8
+:10E4D0009748006805909648001D0068049095F8DC
+:10E4E0002D000021CDE9021000E01DE1BDF8100073
+:10E4F000ADF80400BDF81400ADF80000608D03090C
+:10E5000008AA06A93846FEF7BEFE761C052EFFF4C3
+:10E510007CAF00267FE0B4F9000000EE100AB8EEF0
+:10E52000C00A844810F8260000EE900AF8EE600A4F
+:10E5300000EE880ABDEEC00A10EE100A00B2ADF877
+:10E540002000B4F9020000EE100AB8EEC00A7948C3
+:10E5500000EB8600407800EE900AF8EE600A00EECC
+:10E56000A80ABDEEC00A10EE100A00B2ADF82200F3
+:10E57000B4F9000000EE100AB8EEC00A6D4800EBD6
+:10E580008600807800EE900AF8EE600A00EE880AB5
+:10E59000F7EE000A30EE600ABDEEC00A10EE100A77
+:10E5A00000B2ADF82400B4F9020000EE100AB8EE93
+:10E5B000C00A604800EB8600C07800EE900AF8EED2
+:10E5C000600A00EEA80AF7EE000A30EE600ABDEE1F
+:10E5D000C00A10EE100A00B2ADF826005448083008
+:10E5E0000068059052480C300068049095F82D00A2
+:10E5F0000021CDE90210BDF81000ADF80400BDF80F
+:10E600001400ADF80000608D030908AA06A9384679
+:10E61000FEF739FE761C052EFFF47DAF00267FE065
+:10E62000B4F9000000EE100AB8EEC00A424810F833
+:10E63000260000EE900AF8EE600A00EE880ABDEEB1
+:10E64000C00A10EE100A00B2ADF82000B4F90200C2
+:10E6500000EE100AB8EEC00A374800EB860040789A
+:10E6600000EE900AF8EE600A00EEA80ABDEEC00ABD
+:10E6700010EE100A00B2ADF82200B4F9000000EE6E
+:10E68000100AB8EEC00A2C4800EB8600807800EE35
+:10E69000900AF8EE600A00EE880AF7EE000A30EE03
+:10E6A000600ABDEEC00A10EE100A00B2ADF82400F8
+:10E6B000B4F9020000EE100AB8EEC00A1E4800EBE2
+:10E6C0008600C07800EE900AF8EE600A00EEA80A14
+:10E6D000F7EE000A30EE600ABDEEC00A10EE100A36
+:10E6E00000B2ADF8260012481030006805901048BE
+:10E6F00014300068049095F82D000021CDE9021037
+:10E70000BDF81000ADF80400BDF81400ADF800002D
+:10E71000608D030908AA06A93846FEF7B4FD761CE9
+:10E72000022EFFF47DAF00BF00BF67E66C39010821
+:10E73000803A0108803901089439010870B506460D
+:10E74000302000F041F804462CB90DA114A0FFF7C9
+:10E75000DFFD002070BD30212046F1F71CFE25466C
+:10E760003146204600F030FB1148A861FF2084F8B4
+:10E770002D000021284600F0DFFC2846EAE70000D3
+:10E7800073676C5F6C6F676F5F6372656174653A26
+:10E79000206D616C6C6F63206661696C656400005C
+:10E7A0001B5B33316D5B4552524F525D00000000E0
+:10E7B00099E3000870B504460D46264686F82D50AC
+:10E7C000204600F083FD70BD70B505462846FCF775
+:10E7D000F9F904462CB908A10BA0FFF799FD002018
+:10E7E00070BD2046FCF7C4F90B49896808440A4902
+:10E7F00088602046F4E700006F7574206F66206D16
+:10E80000656D6F72790000001B5B33316D5B4552A3
+:10E81000524F525D000000001C520120F0B502462C
+:10E82000B2F90000B1F90460B04205DDB2F90000B0
+:10E83000B1F90460801B0CE0B1F90000B2F904608A
+:10E84000B04205DDB1F90000B2F90460801B00E0C0
+:10E85000002004B2B2F90200B1F90660B04205DD51
+:10E86000B2F90200B1F90660801B0CE0B1F90200B8
+:10E87000B2F90660B04205DDB1F90200B2F90660F6
+:10E88000801B00E0002005B2B2F90400B2F900607C
+:10E89000801B401CB2F90660B2F90270F61B761CB0
+:10E8A000B04206DAB2F90400B2F90060801B401CE5
+:10E8B00005E0B2F90600B2F90260801B401CB1F914
+:10E8C0000460B1F90070F61B761CB1F90670B1F95D
+:10E8D00002C0A7EB0C077F1CBE4206DAB1F9046048
+:10E8E000B1F90070F61B761C05E0B1F90660B1F9CC
+:10E8F0000270F61B761CB0421BDAB2F90400B2F9C2
+:10E900000060801B401CB2F90660B2F90270F61B71
+:10E91000761CB04206DAB2F90400B2F90060801B3E
+:10E92000401C21E0B2F90600B2F90260801B401CD5
+:10E930001AE0B1F90400B1F90060801B401CB1F984
+:10E940000660B1F90270F61B761CB04206DAB1F926
+:10E950000400B1F90060801B401C05E0B1F906001D
+:10E96000B1F90260801B401C83109C4203DC9D4275
+:10E9700001DC0120F0BD0020FCE700007FB505466A
+:10E980000C460020009001900290039000950194A5
+:10E990006846FCF78FF80348006820440149086086
+:10E9A0007FBD00001C52012070B504460D4600BF1B
+:10E9B00004B125B98C22094909A0FDF7D3FD00BF98
+:10E9C000266A206A30B100E0766A706A0028FBD1BE
+:10E9D000756200E02562EC6170BD0000E331010862
+:10E9E0002E2E5C557365725C73797374656D5C7300
+:10E9F000676C5C636F72655C73676C5F636F726595
+:10EA00002E63000010B5044600BF2CB940F2294225
+:10EA1000054906A0FDF7A6FD00BF94F8280020F0E8
+:10EA2000020084F8280010BDE33001082E2E5C554A
+:10EA30007365725C73797374656D5C73676C5C6924
+:10EA40006E636C7564655C73676C5F636F72652E73
+:10EA50006800000070B5054665B900F063FD064624
+:10EA60002EB916A11EA0FFF753FC002070BD34463E
+:10EA70002046FBE72C20FFF7A7FE04462CB91CA17B
+:10EA800017A0FFF745FC0020F0E7A868A060E86841
+:10EA9000E060E561002020616061A06194F82800D9
+:10EAA00020F00200801C84F82800204600F0A6FA1E
+:10EAB00021462846FFF778FF2046D7E773676C5F4B
+:10EAC0006F626A5F6372656174653A206372656143
+:10EAD00074652070616765206661696C656400001B
+:10EAE0001B5B33316D5B4552524F525D000000009D
+:10EAF0006D616C6C6F63206661696C656400000019
+:10EB000070B504462CB100BF1948D0F8B400A0423B
+:10EB100010D100BF1648D0F8B4000446206A10B1E6
+:10EB2000206A00F03DF8204600F068FA204600F028
+:10EB3000A3FB70BD94F82A00C0F3C00018B12046B2
+:10EB400000F02EF8F5E7254600BF00BF2DB940F2D2
+:10EB50000442084908A0FDF705FD00BF95F828000C
+:10EB600020F00100401C85F8280000BF00BFE0E74E
+:10EB70004C280120A63001082E2E5C557365725C6E
+:10EB800073797374656D5C73676C5C696E636C75C7
+:10EB900064655C73676C5F636F72652E680000006C
+:10EBA00030B591B0044600BF2CB94FF46B721849D0
+:10EBB00018A0FDF7D7FC00BF002528466D1C01A951
+:10EBC00041F8204020E000BF102D05DB40F2B232BA
+:10EBD0000F4910A0FDF7C6FC00BF681E054601A93D
+:10EBE00051F82040606A20B128466D1C626A41F8E5
+:10EBF0002020206A28B128466D1C01A9226A41F80C
+:10EC000020202046FFF7EAF8002DDCDC11B030BDF3
+:10EC1000DB3201082E2E5C557365725C7379737458
+:10EC2000656D5C73676C5C636F72655C73676C5F6A
+:10EC3000636F72652E6300007CB505460C4600BF0D
+:10EC40002CB94FF4CB622D492DA0FDF78BFC00BFF2
+:10EC5000B4F9080094F829100844B4F90010884267
+:10EC600005DDB4F9080094F82910084401E0B4F96E
+:10EC7000000000B2ADF80000B4F90A0094F82910C1
+:10EC80000844B4F90210884205DDB4F90A0094F88A
+:10EC90002910084401E0B4F9020000B2ADF8020006
+:10ECA000B4F90C0094F82910401AB4F90410884201
+:10ECB00005DAB4F90C0094F82910401A01E0B4F90F
+:10ECC000040000B2ADF80400B4F90E0094F8291065
+:10ECD000401AB4F90610884205DAB4F90E0094F827
+:10ECE0002910401A01E0B4F9060000B2ADF80600A0
+:10ECF00000982860019868607CBD000045310108DB
+:10ED00002E2E5C557365725C73797374656D5C73DC
+:10ED1000676C5C696E636C7564655C73676C5F637C
+:10ED20006F72652E6800000010B5044600BF2CB954
+:10ED300040F23262054906A0FDF714FC00BFE189EC
+:10ED40006089081A401C00B210BD0000D1390108CA
+:10ED50002E2E5C557365725C73797374656D5C738C
+:10ED6000676C5C696E636C7564655C73676C5F632C
+:10ED70006F72652E6800000010B5044600BF2CB904
+:10ED800040F21962054906A0FDF7ECFB00BFA0891F
+:10ED90002189401A401C00B210BD0000BF39010893
+:10EDA0002E2E5C557365725C73797374656D5C733C
+:10EDB000676C5C696E636C7564655C73676C5F63DC
+:10EDC0006F72652E6800000070B504460D4600BFE6
+:10EDD0002CB940F28732184918A0FDF7C3FB00BFD9
+:10EDE00065B900BF1E48D0F8B400054635B91DA16D
+:10EDF00025A0FFF78DFA4FF0FF3070BDA8680C34E6
+:10EE000044F8040CE8682060256100206060A06080
+:10EE1000E060207F20F00200801C2077207F20F01F
+:10EE2000400020770C3C2046FDF7B0FA21462846EA
+:10EE3000FFF7BAFD0020E0E7CE3201082E2E5C5528
+:10EE40007365725C73797374656D5C73676C5C6316
+:10EE50006F72655C73676C5F636F72652E63000031
+:10EE60004C28012073676C5F6F626A5F696E69741A
+:10EE70003A2068617665206E6F20616374697665FB
+:10EE800020706167650000001B5B33316D5B45528C
+:10EE9000524F525D0000000010B5044600BF2CB96F
+:10EEA0004FF49662044905A0FDF75CFB00BF94F89F
+:10EEB0002800C0F3801010BD593401082E2E5C5577
+:10EEC0007365725C73797374656D5C73676C5C6990
+:10EED0006E636C7564655C73676C5F636F72652EDF
+:10EEE0006800000010B5044600BF2CB94FF49162D1
+:10EEF000044905A0FDF736FB00BF94F82800C0F3D5
+:10EF0000800010BD333101082E2E5C557365725C94
+:10EF100073797374656D5C73676C5C696E636C7533
+:10EF200064655C73676C5F636F72652E68000000D8
+:10EF3000F0B591B004460E46174600BF24B9C22270
+:10EF4000244925A0FDF70EFB00BF0025206A08B963
+:10EF500011B0F0BD28466D1C01A9226A41F820209D
+:10EF600034E000BF102D04DBCC221A491AA0FDF7B3
+:10EF7000F9FA00BF681E054601A951F8204094F82F
+:10EF8000280020F00200801C84F8280020893044EA
+:10EF900000B22081A089304401B2A1816089384447
+:10EFA00001B26181E089384401B2E181606A28B12F
+:10EFB00028466D1C01A9626A41F82020206A28B108
+:10EFC00028466D1C01A9226A41F82020002DC8DCCA
+:10EFD00000BFBDE7043201082E2E5C557365725CDC
+:10EFE00073797374656D5C73676C5C636F72655C79
+:10EFF00073676C5F636F72652E63000010B5044623
+:10F0000000BF2CB940F27E32044905A0FDF7AAFAF0
+:10F0100000BF00206062206210BD00009430010833
+:10F020002E2E5C557365725C73797374656D5C73B9
+:10F03000676C5C696E636C7564655C73676C5F6359
+:10F040006F72652E6800000070B5044600BF24B9D9
+:10F05000A5220C490CA0FDF785FA00BFE669002542
+:10F06000306AA04208D0356A00E06D6A686AA04242
+:10F07000FBD1606A686201E0606A30620020606211
+:10F0800070BD0000F53101082E2E5C557365725C71
+:10F0900073797374656D5C73676C5C636F72655CC8
+:10F0A00073676C5F636F72652E6300002DE9F0413A
+:10F0B00004460F46904600BF24B9E922144915A022
+:10F0C000FDF750FA00BF2089381A05B26089A8EB15
+:10F0D000000006B294F8280020F00200801C84F89A
+:10F0E00028002089284400B22081A089284401B248
+:10F0F000A1816089304401B26181E089304401B26C
+:10F10000E181324629462046FFF712FFBDE8F08133
+:10F110001B3201082E2E5C557365725C7379737413
+:10F12000656D5C73676C5C636F72655C73676C5F65
+:10F13000636F72652E6300002DE9F84F04460D469B
+:10F1400000BF2CB940F23F621F492048FDF70AFA80
+:10F1500000BF2046FFF710FE009000EBD07040107B
+:10F16000A84201DDAB4607E02046FFF705FE8246D8
+:10F170000AEBDA704FEA600B2046FFF7D5FD8146B7
+:10F1800000EBD9704010834512DA2046FFF7F4FDFA
+:10F19000804600EBD0704010A84201DD28460EE00A
+:10F1A0002046FFF7E9FD074607EBD770401006E061
+:10F1B0002046FFF7B9FD064606EBD670401084F8EE
+:10F1C0002900BDE8F88F0000E43901082CC70008C9
+:10F1D00010B5044600BF2CB940F21D42064907A0F5
+:10F1E000FDF7C0F900BF94F8280020F00200801C51
+:10F1F00084F8280010BD00007C2E01082E2E5C55DE
+:10F200007365725C73797374656D5C73676C5C694C
+:10F210006E636C7564655C73676C5F636F72652E9B
+:10F220006800000010B5044600BF2CB940F21D4232
+:10F23000064907A0FDF796F900BF94F8280020F0D2
+:10F240000200801C84F8280010BD0000A42E0108D4
+:10F250002E2E5C557365725C73797374656D5C7387
+:10F26000676C5C696E636C7564655C73676C5F6327
+:10F270006F72652E6800000010B5044600BF2CB9FF
+:10F2800040F21D42064907A0FDF76CF900BF94F853
+:10F29000280020F00200801C84F8280010BD000027
+:10F2A000D13001082E2E5C557365725C73797374CE
+:10F2B000656D5C73676C5C696E636C7564655C73CB
+:10F2C000676C5F636F72652E6800000010B50446BE
+:10F2D00000BF2CB940F21D42064907A0FDF742F9D4
+:10F2E00000BF94F8280020F00200801C84F8280059
+:10F2F00010BD00009C3901082E2E5C557365725CB0
+:10F3000073797374656D5C73676C5C696E636C753F
+:10F3100064655C73676C5F636F72652E68000000E4
+:10F3200070B504460D461646E0694089304402B285
+:10F33000E0690089284401B22046FFF7B7FE70BD9E
+:10F3400030B587B004460D4600BF2CB940F21552C7
+:10F35000254926A0FDF706F900BF00200490039080
+:10F360000290A0892189401A401C00B2ADF8040027
+:10F37000E1896089081A401C00B2ADF80600E06916
+:10F380008089E1690989401A401C00B2ADF8180073
+:10F39000E069C1894089081A401C00B2ADF81A0022
+:10F3A00006980490E0690089ADF81400E06940898E
+:10F3B000ADF81600059803902A4601A904A8FEF7A7
+:10F3C0001DFD0290BDF80E00BDF80A30184402B2CF
+:10F3D000BDF80C00BDF80830184401B22046FFF714
+:10F3E00065FE07B030BD00004E3301082E2E5C557F
+:10F3F0007365725C73797374656D5C73676C5C6361
+:10F400006F72655C73676C5F636F72652E6300007B
+:10F41000F0B50A46838904891B1B5B1C1DB2C48995
+:10F420004389E31A5B1C1EB2B54201DD334600E09E
+:10F430002B4619460B4601EBD37417B2B7EB640F9A
+:10F440000CDB01F0010727B10C4604EBD4777F10E9
+:10F4500003E04B1E03EBD3777F103A46438D62F3F4
+:10F460000F134385F0BD000070B504460D461646E7
+:10F4700000BF2CB940F2EF5209490AA0FDF772F81B
+:10F4800000BF20892844401E01B2A1816089304418
+:10F49000401E01B2E1812046FFF7C4FE70BD0000AE
+:10F4A000B62E01082E2E5C557365725C73797374E9
+:10F4B000656D5C73676C5C696E636C7564655C73C9
+:10F4C000676C5F636F72652E680000002DE9FC4178
+:10F4D00080460C46164625462F6BB0890F281AD158
+:10F4E0006FB995F82E000190A88DADF800000023AB
+:10F4F00004F1080221464046FDF70CFC10E095F8A7
+:10F500002E00002304F108022146CDE90070404698
+:10F51000FDF727FD04E0206910B1304621698847D6
+:10F52000BDE8FC813EB53420FFF74EF905462DB904
+:10F530002CA134A0FEF7ECFE00203EBD342128466D
+:10F54000F0F729FF2C463348406840B932A12DA07E
+:10F55000FEF7DEFE2846FEF741FC0020EDE73848C6
+:10F5600000680290BDF80800A885FF2085F82E00ED
+:10F57000E46194F8280020F0400084F82800314825
+:10F58000A06194F8280020F00200801C84F8280074
+:10F59000608D20F0080008306085002084F8290084
+:10F5A000009001901B48008A401E00B2ADF8040094
+:10F5B0001848408A401E00B2ADF806000098A060CE
+:10F5C0000198E060A0682060E06860602846FFF76E
+:10F5D00015FD1048D0F8B40010B90E48C0F8B4506A
+:10F5E0002846AAE773676C5F706167655F63726541
+:10F5F0006174653A206D616C6C6F63206661696C43
+:10F60000656400001B5B33316D5B4552524F525DA8
+:10F61000000000004C28012073676C5F7061676513
+:10F620005F6372656174653A206672616D656275CB
+:10F6300066666572206973204E554C4C00000000D0
+:10F6400088320108CDF4000873B504462546BDF89C
+:10F650000400A8852046FFF70FFE7CBD70B5044668
+:10F660000E46154600BF2CB940F24B72064907A062
+:10F67000FCF778FF00BF2188C1F30C0105FB016195
+:10F68000606800EB410070BD963A01082E2E5C5573
+:10F690007365725C73797374656D5C73676C5C69B8
+:10F6A0006E636C7564655C73676C5F636F72652E07
+:10F6B00068000000FEB50020029000BF2E48D0F880
+:10F6C000B40005460299FFF7BFFF0020FEF7A6FD34
+:10F6D0000446254600263746E8694089384402B288
+:10F6E000E8690089304401B22846FFF7DFFC00BF1B
+:10F6F0002546F026374600BF00BF2DB940F2EF5235
+:10F700001E491FA0FCF72EFF00BF28893044401E71
+:10F7100001B2A98168893844401E01B2E9812846B6
+:10F72000FFF756FD00BF20A52646F5622046FFF7ED
+:10F730004FFD00BF1F4D264635632046FFF748FDAD
+:10F7400000BF1D4800680190019800902546BDF853
+:10F750000000A8862046FFF73BFD00BF0025264697
+:10F7600096F8390065F3050086F839002046FFF762
+:10F770002FFD00BFFEBD00004C2801208E2E010889
+:10F780002E2E5C557365725C73797374656D5C7352
+:10F79000676C5C696E636C7564655C73676C5F63F2
+:10F7A0006F72652E6800000048656C6C6F20576FA3
+:10F7B000726C6400A85D0108A02E01082DE9F047D5
+:10F7C000074688464FF00009CA4600264546FC68B1
+:10F7D000012007E0D4E900121144A94200D904E055
+:10F7E0001034401C39698142F4D800BF20682D1ABA
+:10F7F000A06868B96068A84207D84246164917A0B1
+:10F80000FEF786FD0020BDE8F087E0682844FAE7AF
+:10F810006068A0F1010A15E0AAEB090009EB5006A7
+:10F82000A06850F82600A84202D1E0683044EAE718
+:10F83000A06850F82600A84202D206F1010901E0B2
+:10F84000A6F1010AD145E7D94246034903A0FEF7D4
+:10F850005FFD0020D7E70000F86001081B5B333331
+:10F860006D5B5741524E5D00F0B502464FF4804546
+:10F8700000260027B2F5806F02D81E48805CF0BDDC
+:10F88000B2F1804F01D90020F9E700231146080C9E
+:10F89000000408B91033090401F07F4008B90833A7
+:10F8A000090201F0704008B91B1D090101F0404038
+:10F8B00008B99B1C890001F0004000B95B1CC3F132
+:10F8C0001F00DFF834C01CF8007078000E304FF0D5
+:10F8D000010C0CFA00F500BFAC19A24201D3121BB7
+:10F8E0002E1952006808051EF6D126FA07F0C0B29C
+:10F8F000C5E7000048350108493901082DE9F04104
+:10F9000007460E463C46354600BF00BF04B12DB940
+:10F9100040F2597210491148FCF724FE00BFB5F9B6
+:10F920000200B4F90610884211DCB5F90600B4F9FA
+:10F93000021088420BDBB5F90000B4F904108842CC
+:10F9400005DCB5F90400B4F90010884202DA0020A1
+:10F95000BDE8F0810120FBE76931010878EB000880
+:10F9600070B504460D461646324629462046FCF739
+:10F970005FFC70BD10B503461C8A02FB0414986836
+:10F9800000EB440010BD000010B500BF0B48D0F8DC
+:10F99000BC0000BF0949D1F8B810401A0A2800D2AB
+:10F9A00010BD00BF0548D0F8BC000449C1F8B8003C
+:10F9B00000BF00F005F800BFF2E700004C2801206E
+:10F9C00010B5FDF7ABFFFCF7B3FB0549D1F8B40068
+:10F9D000FCF728FF0248001DFDF75CFE10BD00008B
+:10F9E0004C28012010B503460A461946087880289D
+:10F9F00003DA08781060012010BD087800F0E000FC
+:10FA0000C02808D1087800F01F04487864F39F10DC
+:10FA100010600220F0E7087800F0F000E0280ED136
+:10FA200008780007000C4C7804F03F0440EA84108A
+:10FA30008C7804F03F04204310600320DCE7087852
+:10FA400000F0F800F02813D108784007C00A4C787D
+:10FA500004F03F0440EA04308C7804F03F0440EAAC
+:10FA60008410CC7804F03F04204310600420C3E7E6
+:10FA70000020C1E72DE9FF4F2DED028B87B007462F
+:10FA80000D46144600200690CCE094F800B0BBF17F
+:10FA9000250F07D05B4606AA29463846FAF76EFBC3
+:10FAA000641CBFE0641C0020059080464FF0FF39C5
+:10FAB00020782D2802D101200590641C06E02078D2
+:10FAC000303808EB880100EB4108641C20783028AE
+:10FAD00002DB20783928F2DD20782E2810D1641C32
+:10FAE0004FF0000906E02078303809EB890100EB7F
+:10FAF0004109641C2078302802DB20783928F2DDA7
+:10FB000094F800A0BAF1640F2BD009DCBAF1250FEC
+:10FB100071D0BAF1580F3DD0BAF1630F72D15CE0E9
+:10FB2000BAF1660F42D0BAF1730F03D0BAF1780F71
+:10FB300068D123E00C98006804900C98001D0C908C
+:10FB400006A8CDE901750390049E05E016F8013B77
+:10FB500001A807C8FAF712FB30780028F6D100BFD9
+:10FB60005DE00C9840C80C900598334606AA2946DB
+:10FB7000CDE900803846FAF7C9FB50E00C9840C840
+:10FB80000C900020334606AA294600903846FAF722
+:10FB90007DFB44E00C9840C80C900120334606AA37
+:10FBA000294600903846FAF771FB38E00C98C01DE2
+:10FBB00020F007000C90B0EC020BB0EE408AF0EEA3
+:10FBC000608A0C904B46B0EE480AF0EE680A06AA2E
+:10FBD00029463846FAF7DEFA21E00C9810F8041BA3
+:10FBE000CEB20C90334606AA29463846FAF7C6FA32
+:10FBF00015E000E006E0252306AA29463846FAF774
+:10FC0000BDFA0CE0252306AA29463846FAF7B6FACB
+:10FC1000534606AA29463846FAF7B0FA00BF00BF95
+:10FC2000641C00BF207800287FF42FAF3DB1002175
+:10FC30000698A84201D2069800E0681E395406983A
+:10FC400007B0BDEC028B04B0BDE8F08F0146002088
+:10FC500009E0074A52F820201AB9054A42F8201054
+:10FC60007047421C10B20528F3DB00BFF8E7000024
+:10FC70003824012010B504460121204600F075F813
+:10FC800010BD000010B50446226891682069F0F7A5
+:10FC900094FB60B994F8600020F00100401C84F8E7
+:10FCA000600008480168204601F066FB04E0054852
+:10FCB000416B204601F060FB0020A0810021E18122
+:10FCC00010BD0000D80100200246087858B14878DD
+:10FCD00000F00F00082806D0106878B10878136883
+:10FCE0001B78184050B192F8600000F0010018B97C
+:10FCF0004878C0F3001008B1002070474FF0FF3083
+:10FD0000FBE7000010B500F01BFB044624B10348DC
+:10FD1000816B204601F030FB10BD0000D8010020AF
+:10FD200070B50446A189E089081A05B205E02021D2
+:10FD3000204601F03BFA681E05B2002DF7DC217B5E
+:10FD4000204600F07FF870BD10B500F0F9FA0446C7
+:10FD500014B1204600F054FD10BD10B504464FF01C
+:10FD6000FF31204600F001F810BD2DE9F0410446B6
+:10FD70000D46681C08B9012000E000200746E08914
+:10FD800008B9012D05D0E089A189884203D1681CFA
+:10FD900008B9BDE8F081E089A189884210D1012D20
+:10FDA0000ED1E089401EE081A089401EA081002183
+:10FDB000A289206981540121204600F043F83FE0E8
+:10FDC00038460AE0E18901442269525CE189014434
+:10FDD000491E23695A54411C08B2A289E189511A6B
+:10FDE0008142EFDCA089401EA08137B9E089401E26
+:10FDF000E0810821204601F0D9F90021A28920697B
+:10FE00008154E08906B206E02069815D204601F058
+:10FE1000CDF9701C06B2A089B042F5DC2021204645
+:10FE200001F0C4F9A189E089081A401C06B205E076
+:10FE30000821204601F0BAF9701E06B2002EF7DC48
+:10FE400000BFA6E770B505460C4603E004A12846AE
+:10FE500001F092FA201EA4F10101CCB2F6D170BDDE
+:10FE60000820080010B504464FF0FF31204600F08E
+:10FE700041FB10BD10B50446204600F005F80121F5
+:10FE8000204601F0FFF910BD70B50446A08900B905
+:10FE900070BD0021A2892069815494F8600000F0AF
+:10FEA000010010B3204600F086FB204600F0DEFD86
+:10FEB0000021E181A181E08E00B9E9E70DA1204692
+:10FEC00001F05AFA00232046A26D616900F077FE26
+:10FED000054625B12946204600F018FE04E00648F4
+:10FEE0008169204601F048FA02E02046FFF7CAFE89
+:10FEF00000BFCDE70D0A0000D801002010B5024672
+:10FF0000114600200B78302B07D14B78782B02D08C
+:10FF10004B78582B01D103200EE00B78302B07D102
+:10FF20004B78622B02D04B78422B01D1012003E0A9
+:10FF30000B78302B00D1022006E00B782E2B03D15A
+:10FF40004B780BB1042003E011F8014B002CF4D1E5
+:10FF500000BF10BD02461378272B01D1531C00E0CF
+:10FF60001346194600200B785C2B1AD14B786E2B68
+:10FF70000ED004DC302B0FD0622B0FD104E0722B9B
+:10FF800004D0742B0AD105E0082009E00D2007E019
+:10FF90000A2005E0092003E0002001E0487800BFC6
+:10FFA00000E00878704700002DE9F84F05464FF053
+:10FFB000000A4FF00A0B2C46002000900126002773
+:10FFC0009FED330A10EE109A804628782D2800D134
+:10FFD000B61E711C09B9012100E000214819FFF784
+:10FFE0008DFF8246BAF1010F0FD0BAF1020F07D090
+:10FFF000BAF1030F0ED14FF0100B022000900AE06F
:020000040801F1
-:10000000C060F8E360CCFE31C39831308031FF0F1F
-:100010001B0C0C1B06060E3C070EE0031BE0C33155
-:100020003C76E0071880000000000000CAFD2000B8
-:1000300000000000000000000000000000000000C0
-:1000400000000000000000000000000000000000B0
-:1000500000000000000000000000000000000000A0
-:100060000000000000000000000000000000000090
-:100070000000000000000000000000000000000080
-:1000800030000330000330FEFF300003300003FF78
-:10009000FD7F300C6030FC7F300C6030FC7F300C1A
-:1000A00060B0FD7F780C6007FFFF00601C001CF053
-:1000B000800300000000000000000000CCEE2000E3
-:1000C0000000000000000000000000000000000030
-:1000D0000000000000000000000000000000000020
-:1000E0000000000000000000000000000000000010
-:1000F0000000000000000000000000000000000000
-:1001000000000000000000000000000000000000EF
-:10011000000800001800003800FFFFFF000E0080FC
-:100120008301C0000770000CFCFF3F00C32000C328
-:100130000080C10080C1C0E0C0C038C0C007807F5F
-:10014000000000000000000000000000B3E42000F8
-:10015000000000000000000000000000000000009F
-:10016000000000000000000000000000000000008F
-:10017000000000000000000000000000000000007F
-:10018000000000000000000000000000000000006F
-:10019000000000000000000000000000000000005F
-:1001A000003800007000FEFFFF0600C00686C3C0D6
-:1001B000011E3800700600C0000000F8FF3F001864
-:1001C00000001800001800001800001800FEFFFFD3
-:1001D000000000000000000000000000BFD520006B
-:1001E000000000000000000000000000000000000F
-:1001F00000000000000000000000000000000000FF
-:1002000000000000000000000000000000000000EE
-:1002100000000000000000000000000000000000DE
-:1002200000000000000000000000000000000000CE
-:1002300030600030300030F07F307870FF5B383055
-:10024000CC0CF88007B8C10F3C7A78360EC033F872
-:100250007F31186030186030186030186030F87FD7
-:10026000301860000000000000000000B8F120001D
-:10027000000000000000000000000000000000007E
-:10028000000000000000000000000000000000006E
-:10029000000000000000000000000000000000005E
-:1002A000000000000000000000000000000000004E
-:1002B000000000000000000000000000000000003E
-:1002C000000000000000000000000000000000002E
-:1002D000000000000000000000000000000000001E
-:1002E000000000000000000000000000000000000E
-:1002F00000000000000000000000000000000000FE
-:1003000000000000000000000000000000000000ED
-:1003100000000000000000000000000000000000DD
-:1003200000000000000000000000000000000000CD
-:1003300000000000000000000000000000000000BD
-:1003400000000000000000000000000000000000AD
-:10035000000000000000000000000000000000009D
-:10036000000000000000000000000000000000008D
-:10037000000000000000000000000000000000007D
-:10038000000000000000000000000000000000006D
-:1003900000000000008000000000030000000300D7
-:1003A0002000020CE0FFFF1F60300C0060300C00EA
-:1003B00060300C04E0FFFF0F60300C0460300C0470
-:1003C00060300C0460300C04E0FFFF0760000004A4
-:1003D0006000040060041C00600C0C0460040C0F3E
-:1003E00060C48C0320FCED0020041C0030040C00D1
-:1003F00010040D0810C40C0808340C18081E183816
-:10040000040CF81F0200000000000000C2B9200028
-:1004100000000000000000000000000000000000DC
-:1004200000000000000000000000000000000000CC
-:1004300000000000000000000000000000000000BC
-:1004400000000000000000000000000000000000AC
-:10045000000000000000000000000000000000009C
-:10046000000000000000000000000000000000008C
-:10047000000000000000000000000000000000007C
-:10048000000000000000000000000000000000006C
-:1004900000000000008000000080070000800100D4
-:1004A0000080010000800100008001000080010048
-:1004B0000080010000820100008E210000864100C2
-:1004C0000087810000838101808101038081010612
-:1004D000C080010E4080011C6080011C308001182A
-:1004E00010800118088001100480010000800100C4
-:1004F0000080010000800100008C010000F001007C
-:1005000000E000000040000000000000D0A120003A
-:1005100000000000000000000000000000000000DB
-:1005200000000000000000000000000000000000CB
-:1005300000000000000000000000000000000000BB
-:1005400000000000000000000000000000000000AB
-:10055000000000000000000000000000000000009B
-:10056000000000000000000000000000000000008B
-:10057000000000000000000000000000000000007B
-:10058000000000000000000000000000000000006B
-:10059000000000000000010000000700000C03182C
-:1005A000FC1FFF3FC0008301C0008301C000830126
-:1005B000C0008301C0008301C0008301C024830107
-:1005C000FC2F8301C0208309C020FF1FC03083019E
-:1005D000C0188101C0008101C0008101C09081016B
-:1005E000C08C8101C0838001F0C080013E40800149
-:1005F0000C208001003080110008FE3F0006000042
-:1006000000010000C000000000000000B0E0200079
-:1006100000000000000000000000000000000000DA
-:1006200000000000000000000000000000000000CA
-:1006300000000000000000000000000000000000BA
-:1006400000000000000000000000000000000000AA
-:10065000000000000000000000000000000000009A
-:10066000000000000000000000000000000000008A
-:10067000000000000000000000000000000000007A
-:10068000000000000000000000000000000000006A
-:10069000000000000000000100300007003C0003E3
-:1006A000E00700031C0300030003060300030C0320
-:1006B000000318030003180300230003FC7F00035A
-:1006C000000300030003020380030603800F0C03F2
-:1006D000C03B0803403300336023003F2023F00376
-:1006E00010830F03086300030403000302030003E5
-:1006F00000030003000300030003000300030003E2
-:10070000000300030001000100000000BFC620003C
-:1007100000000000000000000000000000000000D9
-:1007200000000000000000000000000000000000C9
-:1007300000000000000000000000000000000000B9
-:1007400000000000000000000000000000000000A9
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000080001000800370008001300025
-:1007A0008001300080013000800130008019301855
-:1007B000FCFFFF3F800130008001300080013000ED
-:1007C000800130008031300480CDFF0F80030106AE
-:1007D000F0010106BC0102038C01020380018601C5
-:1007E000800184018001CC008001680080017000DC
-:1007F000800178008001EC008001C703F881011FAF
-:10080000E071003E400C000000000000BCBC200075
-:1008100000000000000000000000000000000000D8
-:1008200000000000000000000000000000000000C8
-:1008300000000000000000000000000000000000B8
-:1008400000000000000000000000000000000000A8
-:100850000000000000000000000000000000000098
-:100860000000000000000000000000000000000088
-:100870000000000000000000000000000000000078
-:100880000000000000000000000000000000000068
-:100890000000000000000000000000000000000058
-:1008A0000000000000000000000000000000000048
-:1008B0000000000000000000000000000000000038
-:1008C0000000000000000000000000000000000028
-:1008D0000000000000000000000000000000000018
-:1008E0000000000000000000000000000000000008
-:1008F00000000000000000000000000000000000F8
-:1009000000000000000000000000000000000000E7
-:1009100000000000000000000000000000000000D7
-:1009200000000000000000000000000000000000C7
-:1009300000000000000000000000000000000000B7
-:1009400000000000000000000000000000000000A7
-:100950000000000000000000000000000000000097
-:100960000000000000000000000000000000000087
-:100970000000000000000000000000000000000077
-:100980000000000000000000000000000000000067
-:100990000000000000000000000000000000000057
-:1009A0000000000000000000000000000000000047
-:1009B0000000000000000000000000000000000037
-:1009C0000000000000000000000000000000000027
-:1009D0000000000000000000000000000000000017
-:1009E0000000000000000000000000000000000007
-:1009F00000000000000000000000000000000000F7
-:100A000000000000000000000000000000000000E6
-:100A100000000000000000000000000000000000D6
-:100A200000000000000000000000000000000000C6
-:100A300000000000000000000000000000000000B6
-:100A400000000000000000000000000000000000A6
-:100A50000000000000000000000000000000000096
-:100A60000000000000000000000000000000000086
-:100A70000000000000000000000000000000000076
-:100A80000000000000000000000000000000000066
-:100A90000000000000000000000000000000000056
-:100AA0000000000000000000000000000000000046
-:100AB0000000000000000000000000000000000036
-:100AC0000000000000000000000000000000000026
-:100AD0000000000000000000000000000000000016
-:100AE0000000000000000000000000000000000006
-:100AF00000000000000000000000000000000000F6
-:100B000000000000000000000000000000000000E5
-:100B100000000000000000000000000000000000D5
-:100B200000000000000000000000000000000000C5
-:100B300000000000000000000000000000000000B5
-:100B400000000000000000000000000000000000A5
-:100B50000000000000000000000000000000000095
-:100B60000000000000000000000000000000000085
-:100B70000000000000000000000000000000000075
-:100B80000000000000000000000000000000000065
-:100B90000000000000000000000000000000000055
-:100BA0000000000000000000000000000000000045
-:100BB0000000000000000000000000000000000035
-:100BC0000000000000000000000000000000000025
-:100BD0000000000000000000000000000000000015
-:100BE0000000000000000000000000000000000005
-:100BF00000000000000000000000000000000000F5
-:100C000000000000000000000000000000000000E4
-:100C100000000000000000000000000000000000D4
-:100C200000000000000000000000000000000000C4
-:100C300000000000000000000000000000000000B4
-:100C400000000000000000000000000000000000A4
-:100C50000000000000000000000000000000000094
-:100C60000000000000000000000000000000000084
-:100C70000000000000000000000000000000000074
-:100C80000000000000000000000000000000000064
-:100C90000000000000000000000000000000000054
-:100CA0000000000000000000000000000000000044
-:100CB0000000000000000000000000000000000034
-:100CC0000000000000000000000000000000000024
-:100CD0000000000000000000000000000000000014
-:100CE0000000000000000000000000000000000004
-:100CF00000000000000000000000000000000000F4
-:100D000000000000000000000000000000000000E3
-:100D100000000000000000000000000000000000D3
-:100D200000000000000000000000000000000000C3
-:100D300000000000000000000000000000000000B3
-:100D400000000000000000000000000000000000A3
-:100D50000000000000000000000000000000000093
-:100D60000000000000000000000000000000000083
-:100D70000000000000000000000000000000000073
-:100D80000000000000000000000000000000000063
-:100D90000000000000000000000000000000000053
-:100DA0000000000000000000000000000000000043
-:100DB0000000000000000000000000000000000033
-:100DC0000000000000000000000000000000000023
-:100DD0000000000000000000C003C003C003C00307
-:100DE000C003C00380038001800180018001800175
-:100DF0008001800180010000000000008001C0032C
-:100E0000C00380010000000000000000000000009E
-:100E1000C018E01CE01C700E300618038C01840022
-:100E200000000000000000000000000000000000C2
-:100E300000000000000000000000000000000000B2
-:100E400000000000000000000000000000000000A2
-:100E500000000000000000002010201020102010D2
-:100E60002010FE7FFE7FFE7F10081008100810087B
-:100E700010081008FE7FFE7FFE7F180C080408048F
-:100E8000080408040000000000000000000000004A
-:100E90000000000080008000C003B00C901898187B
-:100EA000981C981CB800B000F000E000C003800758
-:100EB000800F800C801C80189C189C188C188C0C3F
-:100EC0009806E00380008000800000000000000021
-:100ED00000000000000000001C0836082204630423
-:100EE000630263026302630163012201B61C9C3644
-:100EF000402240634063206320631063106310222C
-:100F00000836081C0000000000000000000000007F
-:100F10000000000000000000F00098008C018C012F
-:100F20008C018C018C00CC005C0038001C3E3C081D
-:100F3000320873086304E304C3048303834306672E
-:100F40008C3E781C00000000000000000000000043
-:100F50001C003C003C003000300010000C0006007B
-:100F60000000000000000000000000000000000081
-:100F70000000000000000000000000000000000071
-:100F80000000000000000000000000000000000061
-:100F90000040002000100018000C000400060002B1
-:100FA0000003000380018001800180018001800135
-:100FB000800180018001000300030002000600049C
-:100FC000000C00180010002000400000000000008D
-:100FD00002000400080018003000200060004000FB
-:100FE000C000C0008001800180018001800180017B
-:100FF000800180018001C000C000C00060002000AE
-:10100000300018000800040002000000000000008A
-:10101000000000000000000000000000000380034A
-:1010200080030C631C713839600D80038003600DF0
-:1010300038391C718C61800380038003000000003C
-:1010400000000000000000000000000000000000A0
-:10105000000000000000000000000000000000018F
-:10106000000100010001000100010001FC7F0001FE
-:10107000000100010001000100010001000000006A
-:101080000000000000000000000000000000000060
-:101090000000000000000000000000000000000050
-:1010A0000000000000000000000000000000000040
-:1010B0000000000000000000000000001C003C00D8
-:1010C0003C003000300010000C0006000000000062
-:1010D0000000000000000000000000000000000010
-:1010E000000000000000000000000000FE7F000083
-:1010F00000000000000000000000000000000000F0
-:1011000000000000000000000000000000000000DF
-:1011100000000000000000000000000000000000CF
-:1011200000000000000000000000000000000000BF
-:1011300000000000000000000000000018003C005B
-:101140003C0018000000000000000000000000004B
-:10115000000000400060002000300010001800086F
-:10116000000C000400060002000300018001800062
-:10117000C00040006000200030001000180008008F
-:101180000C00040006000200000000000000000047
-:101190000000000000000000C0036004300C1818BC
-:1011A000181818100C300C300C300C300C300C307F
-:1011B0000C300C300C300C30181018181818300C7B
-:1011C0006004C003000000000000000000000000F8
-:1011D000000000000000000000018001F801800113
-:1011E00080018001800180018001800180018001F7
-:1011F00080018001800180018001800180018001E7
-:10120000C003F81F00000000000000000000000004
-:101210000000000000000000E007101C0818043067
-:1012200004300C300C30003000180018000C0006A0
-:1012300000038001C000400020201020082004305E
-:10124000FC1FFC1F00000000000000000000000068
-:101250000000000000000000E00318060C0C0C1851
-:101260000C180C1800180018000C0006C003000E23
-:1012700000180010003000300C300C300C100C182E
-:10128000180CE00300000000000000000000000057
-:101290000000000000000000000600060007000734
-:1012A0008006800640062006200610061006080666
-:1012B0000C0604060206FE3F0006000600060006B5
-:1012C0000006C03F00000000000000000000000019
-:1012D0000000000000000000F03FF03F08000800A0
-:1012E0000800080008000800C807280C1818081093
-:1012F00000300030003000300C300C30041804187E
-:10130000180CE003000000000000000000000000D6
-:10131000000000000000000080076018301810185E
-:101320001800080008000C00CC076C0C1C181C10DE
-:101330000C300C300C300C300C30183018103018C9
-:10134000700CC0070000000000000000000000005A
-:101350000000000000000000F83FF83F08100C08F3
-:10136000040804040004000200020002000100015D
-:101370008000800080008000C000C000C000C0006D
-:10138000C000C000000000000000000000000000DD
-:101390000000000000000000E007300C18180C30BE
-:1013A0000C300C301C301C107818F004E003180FBF
-:1013B0000C1E0C1C063806300630063006300C18A1
-:1013C000180CE00300000000000000000000000016
-:1013D0000000000000000000E00318040C080C18D6
-:1013E0000610063006300630063006300E380C3453
-:1013F0001836F03100300018001800080C0C0C06EC
-:101400000C03F001000000000000000000000000DC
-:1014100000000000000000000000000000000000CC
-:101420000000000000008001C003C0038001000034
-:101430000000000000000000000000008001C00368
-:10144000C003800100000000000000000000000058
-:10145000000000000000000000000000000000008C
-:101460000000000000000000C001C001C001000039
-:101470000000000000000000000000000000C001AB
-:10148000C001C0018001C000C000000000000000D9
-:101490000000000000000000002000100008000410
-:1014A0000002000180004000200010000800080039
-:1014B000100020004000800000010002000400082D
-:1014C00000100020000000000000000000000000EC
-:1014D000000000000000000000000000000000000C
-:1014E000000000000000FE7F00000000000000007F
-:1014F0000000FE7F0000000000000000000000006F
-:1015000000000000000000000000000000000000DB
-:10151000000000000000000004000800100020008F
-:1015200040008000000100020004000800100010CC
-:1015300000080004000200018000400020001000AC
-:10154000080004000000000000000000000000008F
-:101550000000000000000000C007301818300860CC
-:101560000C601C601C601C6000300018000E000342
-:101570000001000100010001000000008001C00323
-:10158000C003800100000000000000000000000017
-:101590000000000000000000C007600830101820A4
-:1015A0000C2B8C4D844CC64CC64466446644664441
-:1015B0006646662666266417CC0C0C400820183058
-:1015C0003018C0070000000000000000000000000C
-:1015D0000000000000000000C001C001C001C00107
-:1015E00020032003200320033002100610061006FB
-:1015F0001004F80F080C080C080C04180418041840
-:1016000006381F7C00000000000000000000000001
-:101610000000000000000000FE07181C1818183019
-:1016200018301830183018301818180CF807181817
-:10163000183018201860186018601860186018308A
-:101640001818FE0F0000000000000000000000005D
-:101650000000000000000000C00760381030186073
-:101660000C400C400C0006000600060006000600B8
-:1016700006000600060006000C400C40082018106A
-:101680003008C0070000000000000000000000005B
-:101690000000000000000000FE03180E18181810CB
-:1016A00018301830186018601860186018601860DA
-:1016B000186018601860182018301830181818189A
-:1016C0001806FE03000000000000000000000000FB
-:1016D0000000000000000000FE3F183018201840F5
-:1016E00018401800180018081808180CF80F180CE3
-:1016F000180818081800180018001840184018207A
-:101700001830FE3F00000000000000000000000054
-:101710000000000000000000FE3F183818201840AC
-:1017200018401800180018081808180CF80F180CA2
-:1017300018081808180818001800180018001800D1
-:1017400018007E0000000000000000000000000003
-:101750000000000000000000C003300C1008181842
-:101760000C100C100400060006000600060006001F
-:10177000067E0618061804180C180C1808181818F5
-:101780003004E00300000000000000000000000042
-:1017900000000000000000003FFC0C300C300C305A
-:1017A0000C300C300C300C300C300C30FC3F0C305A
-:1017B0000C300C300C300C300C300C300C300C3049
-:1017C0000C303FFC000000000000000000000000A2
-:1017D0000000000000000000F81F8001800180016F
-:1017E00080018001800180018001800180018001F1
-:1017F00080018001800180018001800180018001E1
-:101800008001F81F00000000000000000000000040
-:101810000000000000000000E07F00060006000657
-:101820000006000600060006000600060006000688
-:101830000006000600060006000600060006000678
-:10184000000600060E060E038E01FC0000000000DC
-:1018500000000000000000007E3E180C180418066E
-:1018600018021801180198009800D800B801B801B2
-:101870001803180318061806180C180C180C18185A
-:1018800018187E7C0000000000000000000000002E
-:1018900000000000000000007E0018001800180082
-:1018A0001800180018001800180018001800180078
-:1018B00018001800180018001800184018401820C8
-:1018C0001830FE3F00000000000000000000000093
-:1018D00000000000000000000FF01C381C381C380D
-:1018E0001C381C34343434343434343234326432BA
-:1018F0006432643264314431C431C431C430C430E0
-:1019000084308FFC00000000000000000000000098
-:1019100000000000000000000FF81C201C203420F4
-:10192000342064206420C420C42084218421042322
-:10193000042304260426042C042C04380438043020
-:1019400004301F2000000000000000000000000024
-:101950000000000000000000C003300C1818081040
-:101960000C300C30062006600660066006600660DB
-:1019700006600660066004600C300C300810181811
-:10198000300CC00300000000000000000000000058
-:101990000000000000000000FE0F1818183018604A
-:1019A0001860186018601860186018301818F80768
-:1019B0001800180018001800180018001800180067
-:1019C00018007E0000000000000000000000000081
-:1019D0000000000000000000C003300C18180810C0
-:1019E0000C300C300660066006600660066006601B
-:1019F0000660066006600660E4211C331C36181E73
-:101A0000300EC007004C003C003800000000000011
-:101A10000000000000000000FE07181C1818183015
-:101A200018301830183018301818180CF807180328
-:101A30001803180618061806180C180C180C181895
-:101A400018187E7800000000000000000000000070
-:101A50000000000000000000F013181E0C1806180B
-:101A60000610061006000E003C00F800E003800F90
-:101A7000001E0018003802300230063004300C1806
-:101A80001C0CE40700000000000000000000000043
-:101A90000000000000000000FC3F8C2184618241B6
-:101AA00082418001800180018001800180018001EC
-:101AB000800180018001800180018001800180011E
-:101AC0008001E007000000000000000000000000AE
-:101AD00000000000000000003F7C0C100C100C10F7
-:101AE0000C100C100C100C100C100C100C100C1016
-:101AF0000C100C100C100C100C100C100C10180802
-:101B00003804E003000000000000000000000000B6
-:101B100000000000000000003E7818301810181077
-:101B200018103008300830083008300460046004B1
-:101B300060046002C002C002C002C00180018001D6
-:101B40008000800000000000000000000000000095
-:101B50000000000000000000CFF386618621842190
-:101B600004210C238C238C238C138C138813481290
-:101B700058165816580E380E300E300E300C3004F1
-:101B8000100410040000000000000000000000002D
-:101B900000000000000000003E7C1810180830080B
-:101BA000300460046002C002C00180018001800135
-:101BB0008003400340062006200E100C100C18185D
-:101BC00008383E7C0000000000000000000000001B
-:101BD00000000000000000007E7C1C101810180897
-:101BE00030083008300460046004C002C002C00144
-:101BF00080018001800180018001800180018001DD
-:101C00008001E0070000000000000000000000006C
-:101C10000000000000000000F87F383018300C1879
-:101C20000418000C00060006000300038001800178
-:101C3000C000C000600060003000184018600C2038
-:101C40000C38FE3F00000000000000000000000013
-:101C50000000C03FC000C000C000C000C000C00005
-:101C6000C000C000C000C000C000C000C000C00074
-:101C7000C000C000C000C000C000C000C000C00064
-:101C8000C000C000C000C03F000000000000000015
-:101C900000000000000018001800100030002000B4
-:101CA000600060004000C0008000800180010001F1
-:101CB0000003000200060006000C000C000C0018D7
-:101CC000001800300030003000600000000000000C
-:101CD0000000FC03000300030003000300030003F3
-:101CE00000030003000300030003000300030003DC
-:101CF00000030003000300030003000300030003CC
-:101D0000000300030003FC030000000000000000CB
-:101D1000C003C007600410080000000000000000BD
-:101D200000000000000000000000000000000000B3
-:101D300000000000000000000000000000000000A3
-:101D40000000000000000000000000000000000093
-:101D50000000000000000000000000000000000083
-:101D60000000000000000000000000000000000073
-:101D70000000000000000000000000000000000063
-:101D800000000000000000000000FFFF0000000055
-:101D90007800C0000001000000000000000000000A
-:101DA0000000000000000000000000000000000033
-:101DB0000000000000000000000000000000000023
-:101DC0000000000000000000000000000000000013
-:101DD0000000000000000000000000000000000003
-:101DE000000000000000E007180C0C180C180C187C
-:101DF000001CE01B38180C18061806180618069860
-:101E00000C9EF871000000000000000000000000BF
-:101E100000000000000010001E001800180018004C
-:101E20001800180018009807581C38183830183057
-:101E3000183018301830183018301830181038187A
-:101E4000380CC8070000000000000000000000007F
-:101E50000000000000000000000000000000000082
-:101E6000000000000000C0077008301818180C1897
-:101E70000C000C000C000C000C000C20182018109A
-:101E80003008C00700000000000000000000000053
-:101E90000000000000000010001E001800180018CC
-:101EA000001800180018E01B301C181818180C181F
-:101EB0000C180C180C180C180C180C180818181CF6
-:101EC000307AE0090000000000000000000000007F
-:101ED0000000000000000000000000000000000002
-:101EE000000000000000C003300C101818100C3067
-:101EF0000C300C30FC3F0C000C000C0018201810AB
-:101F00007018C00700000000000000000000000082
-:101F10000000000000000000003E80618060C060A2
-:101F2000C000C000C000FC1FC000C000C000C00056
-:101F3000C000C000C000C000C000C000C000C000A1
-:101F4000C000F80F000000000000000000000000CA
-:101F50000000000000000000000000000000000081
-:101F6000000000000000C077306C10181818181816
-:101F700018181018300CF00718001800F803F01F9C
-:101F800018380C300C300C301818E0070000000036
-:101F900000000000000010001E00180018001800CB
-:101FA0001800180018009807580C38181818181836
-:101FB00018181818181818181818181818181818A1
-:101FC00018187E7E000000000000000000000000E5
-:101FD00000000000000000008001C003800100003C
-:101FE000000000000001F8018001800180018001F3
-:101FF00080018001800180018001800180018001D9
-:102000008001F81F00000000000000000000000038
-:102010000000000000000000001C001E000C00007A
-:10202000000000000008C00F000C000C000C000CA9
-:10203000000C000C000C000C000C000C000C000C40
-:10204000000C000C000C18061802F0010000000043
-:1020500000000000000010001E001800180018000A
-:10206000180018001800183E180C1804180218015F
-:102070009801D801780338031806180C180C1818A2
-:1020800018387E7C00000000000000000000000006
-:102090000000000000000001F801800180018001C3
-:1020A0008001800180018001800180018001800128
-:1020B0008001800180018001800180018001800118
-:1020C0008001F81F00000000000000000000000078
-:1020D0000000000000000000000000000000000000
-:1020E000000000000400F73C8E6386618661866113
-:1020F00086618661866186618661866186618661A8
-:102100008661CFF300000000000000000000000026
-:1021100000000000000000000000000000000000BF
-:1021200000000000000090075E0C381818181818FE
-:10213000181818181818181818181818181818181F
-:1021400018187E7E00000000000000000000000063
-:10215000000000000000000000000000000000007F
-:10216000000000000000C003300C101818180830E0
-:102170000C300C300C300C300C300C301818181897
-:10218000300CC00300000000000000000000000050
-:10219000000000000000000000000000000000003F
-:1021A00000000000000090075E0C3818181018306E
-:1021B00018301830183018301830183018183818EF
-:1021C000780C98071800180018007E000000000026
-:1021D00000000000000000000000000000000000FF
-:1021E000000000000000C013301E181C18180C1846
-:1021F0000C180C180C180C180C180C180818181CB3
-:10220000301EE019001800180018007E00000000C1
-:1022100000000000000000000000000000000000BE
-:1022200000000000000060387E666061E001E000B0
-:10223000600060006000600060006000600060009E
-:102240006000FE0700000000000000000000000029
-:10225000000000000000000000000000000000007E
-:10226000000000000000C0276038303030203020EF
-:102270007000E003800F001E00380830083018306E
-:102280003818C80F00000000000000000000000027
-:10229000000000000000000000000000800080003E
-:1022A0008000C000E000FC1FC000C000C000C000F3
-:1022B000C000C000C000C000C000C000C020C020DE
-:1022C0008011000F0000000000000000000000006E
-:1022D00000000000000000000000000000000000FE
-:1022E0000000000010101E1E1818181818181818D2
-:1022F0001818181818181818181818181818181C5A
-:10230000307AE0090000000000000000000000003A
-:1023100000000000000000000000000000000000BD
-:102320000000000000003E7C18301810181830081B
-:102330003008200460046004C002C002C0038001B1
-:10234000800180000000000000000000000000008C
-:10235000000000000000000000000000000000007D
-:10236000000000000000DFF3866184218C218C21B5
-:102370008C13881358135812580E700E300E300CF0
-:1023800030042004000000000000000000000000F5
-:10239000000000000000000000000000000000003D
-:1023A0000000000000007C3E300870086004C0029D
-:1023B000C00280018001800340062006200C101816
-:1023C00018183E7E00000000000000000000000021
-:1023D00000000000000000000000000000000000FD
-:1023E0000000000000003E7C181818081008300893
-:1023F0002004600460044002C00280028001800169
-:1024000080008000800040007C003C000000000054
-:1024100000000000000000000000000000000000BC
-:10242000000000000000FC1F0C1C0C0C040604073C
-:1024300000038001C001C00060007020302018300F
-:102440000C18FC1F0000000000000000000000004D
-:10245000003000080004000400040004000400042C
-:1024600000040004000400040004000380010002D2
-:10247000000400040004000400040004000400043C
-:102480000004000400040008003000000001000106
-:102490000001000100010001000100010001000134
-:1024A0000001000100010001000100010001000124
-:1024B0000001000100010001000100010001000114
-:1024C0000001000100010001000100010000000006
-:1024D0001800200040004000400040004000400044
-:1024E00040004000400040004000800100038000A8
-:1024F00040004000400040004000400040004000DC
-:10250000400040004000200018000000000078005B
-:10251000C400824102410027001C000000000000AE
-:1025200000000000000000000000000000000000AB
-:10253000000000000000000000000000000000009B
-:10254000000000000000000000000000000000008B
-:10255000000000000000000000000000000000007B
-:10256000000000000000000000000000000000006B
-:10257000000000000000000000000000000000005B
-:10258000000000006000600060006000600060000B
-:10259000600040002000200020000000000000003B
-:1025A000600060006000000000000000000000000B
-:1025B00060066006300398018800440000000000B7
-:1025C000000000000000000000000000000000000B
-:1025D00000000000000000000000000000000000FB
-:1025E000000000001002100210021002FE07FE0799
-:1025F00008020801080108010801FE07FE0704019E
-:1026000004010401040100000000000000000000BB
-:10261000000040004000F00158034C03CC034C0084
-:1026200058007000E000C001C00140034C035C038F
-:102630004C034801F0004000400000000000000092
-:10264000000000000E010A0191009100910051006C
-:1026500051003A00AE03A00250045004480448045C
-:102660004804840284030000000000000000000011
-:102670000000000038006C006C006C006C006C0006
-:102680002C0098071C011A01330133016301E30098
-:10269000C308C6093C07000000000000000000005D
-:1026A0000C001C00100010000800040000000000D6
-:1026B000000000000000000000000000000000001A
-:1026C000000000000000000000000000000000000A
-:1026D0000004000200018000800040004000200053
-:1026E00020002000200020002000200040004000AA
-:1026F00080008000000100020004000000000000D3
-:10270000020004000800100010002000200040001B
-:1027100040004000400040004000400020002000F9
-:10272000100010000800040002000000000000007B
-:1027300000000000000000004000C0004000460C07
-:102740004E0FD001F0015E0F460C400040004000EB
-:102750000000000000000000000000000000000079
-:1027600000000000000000000000400040004000A9
-:1027700040004000FE0F400040004000400040008C
-:102780000000000000000000000000000000000049
-:102790000000000000000000000000000000000039
-:1027A0000000000000000000000000000000000029
-:1027B0000C001C00100010000800040000000000C5
-:1027C0000000000000000000000000000000000009
-:1027D00000000000FE0700000000000000000000F4
-:1027E00000000000000000000000000000000000E9
-:1027F00000000000000000000000000000000000D9
-:1028000000000000000000000000000000000000C8
-:102810001C001C001C000000000000000000000064
-:102820000004000600020003000100018000800097
-:102830004000400060002000200010001000080050
-:1028400008000C0004000600020000000000000068
-:10285000000000000000F00098010C030C030606C5
-:1028600006060606060606060606060606060C0305
-:102870000C039801F00000000000000000000000C0
-:1028800000000000000040007C006000600060006C
-:102890006000600060006000600060006000600038
-:1028A00060006000FC030000000000000000000069
-:1028B000000000000000F800840102030603060384
-:1028C000000300018001C000600020001000080229
-:1028D00004020602FE0300000000000000000000E9
-:1028E0000000000000007800C6008601860180011B
-:1028F0008001C00070008001000100030003060396
-:1029000006038601F800000000000000000000003F
-:1029100000000000000080018001C001A001A001B2
-:1029200090018801880184018201FE0F80018001ED
-:1029300080018001E00700000000000000000000AE
-:10294000000000000000FC03040004000400040078
-:102950000400F4008C0104030003000306030603D3
-:1029600082018401F8000000000000000000000067
-:10297000000000000000E00118030C030C0004003C
-:102980000600E60116030E060606060606060406FF
-:102990000C021803F000000000000000000000001E
-:1029A000000000000000F8070C060402040100010A
-:1029B0000001800080004000400040006000600096
-:1029C00060006000600000000000000000000000E7
-:1029D000000000000000F8010C03060606060606CB
-:1029E0000C021C03F000C8010C03060606060606CE
-:1029F00006060C03F00100000000000000000000CB
-:102A0000000000000000F0000C010C0306020606A6
-:102A10000606060606078C06780600060003000375
-:102A20000C018C0178000000000000000000000094
-:102A30000000000000000000000000000000000096
-:102A4000E000E000E00000000000000000000000E6
-:102A5000E000E000E00000000000000000000000D6
-:102A60000000000000000000000000000000000066
-:102A70006000600000000000000000000000000096
-:102A80000000600060004000200020000000000006
-:102A9000000000000004000200018000400020004F
-:102AA0001000080004000800100020004000800012
-:102AB000000100020004000000000000000000000F
-:102AC0000000000000000000000000000000000006
-:102AD000FE07000000000000FE07000000000000EC
-:102AE00000000000000000000000000000000000E6
-:102AF00000000000040008001000200040008000DA
-:102B000000010002000400020001800040002000DB
-:102B10001000080004000000000000000000000099
-:102B2000000000000000E0031806040C040C0C0C6C
-:102B30000C0C000780014000400040000000000035
-:102B4000E000E000E00000000000000000000000E5
-:102B500000000000E00018030C02CC0564056605C7
-:102B6000A605B604B604B604B604B602E4010C0425
-:102B70000C021803F000000000000000000000003C
-:102B8000000000000000600060005000D0009000D5
-:102B90009000880088010801F8010403040304027E
-:102BA000020202060F0F00000000000000000000FB
-:102BB000000000000000FE008C030C030C030C035B
-:102BC0000C038C01FC000C030C020C060C060C061A
-:102BD0000C060C03FE0100000000000000000000D5
-:102BE000000000000000E00318030C060C040404BD
-:102BF00006000600060006000600060006040C0497
-:102C00000C021803F00000000000000000000000AB
-:102C10000000000000007F008C010C030C030C0678
-:102C20000C060C060C060C060C060C060C060C0317
-:102C30000C038C017F000000000000000000000079
-:102C4000000000000000FF0306030604060406005F
-:102C500086008600FE0086008600860006000604C8
-:102C600006040602FF030000000000000000000050
-:102C7000000000000000FF0306030604060406002F
-:102C800086008600FE00860086008600060006009C
-:102C9000060006001F000000000000000000000009
-:102CA000000000000000F00018010C020C020402F9
-:102CB0000600060006000600C60F060306030C0306
-:102CC0000C031803F00000000000000000000000EA
-:102CD0000000000000000F0F0606060606060606A6
-:102CE00006060606FE07060606060606060606068B
-:102CF000060606060F0F000000000000000000009E
-:102D0000000000000000FC03600060006000600044
-:102D100060006000600060006000600060006000B3
-:102D200060006000FC0300000000000000000000E4
-:102D3000000000000000F807C000C000C000C00094
-:102D4000C000C000C000C000C000C000C000C00083
-:102D5000C000C000C000C60066003C0000000000CB
-:102D6000000000000000CF038601C60046002600D8
-:102D7000160036002E006E004600C6008600860152
-:102D8000060106038F07000000000000000000009D
-:102D90000000000000001F000600060006000600FC
-:102DA00006000600060006000600060006000604EF
-:102DB00006040602FF0300000000000000000000FF
-:102DC0000000000000000707860386038E038E03C1
-:102DD0004E034E034A035A035A033A0332033203A3
-:102DE000320312038707000000000000000000000B
-:102DF0000000000000008E0F0C021C021C023402B6
-:102E00003402640264024402C40284028403840320
-:102E1000040304031F020000000000000000000083
-:102E2000000000000000F00098010C030C020606F0
-:102E300006060606060606060606060606060C0230
-:102E40000C039801F00000000000000000000000EA
-:102E5000000000000000FF00060306060606060646
-:102E6000060606068603FE000600060006000600AB
-:102E7000060006001F000000000000000000000027
-:102E8000000000000000F00098010C030C02060690
-:102E900006060606060606060606060676064C0220
-:102EA000CC039801F0008007000300000000000040
-:102EB000000000000000FF010603060606060606E5
-:102EC00006060603FE004600C600860086010603CD
-:102ED000060306060F0E00000000000000000000C0
-:102EE000000000000000F8020C03060206020600C3
-:102EF0000E003C00F800E003800300070206020613
-:102F000006060C03F00100000000000000000000B5
-:102F1000000000000000FE07620461086108600014
-:102F200060006000600060006000600060006000A1
-:102F300060006000F80100000000000000000000D8
-:102F40000000000000001E070C020C020C020C0224
-:102F50000C020C020C020C020C020C020C020C0201
-:102F60000C021801F000000000000000000000004A
-:102F70000000000000000F070602040104010C011C
-:102F80000C018800880098009800500050007000E4
-:102F900030002000200000000000000000000000C1
-:102FA000000000000000F70E6204420446044604DC
-:102FB00064026402E402E4029C029C01980198010C
-:102FC0008801880088000000000000000000000068
-:102FD0000000000000009E070C010801180190008D
-:102FE000B0006000200060006000D0009000880108
-:102FF000080104038E07000000000000000000002C
-:103000000000000000000F0F060404020C0208017B
-:103010001801B800B000700060006000600060003F
-:1030200060006000F80100000000000000000000E7
-:10303000000000000000FC070C02060302018001F2
-:10304000800040004000200020001000180008040C
-:103050000C040402FE030000000000000000000059
-:10306000E00320002000200020002000200020009D
-:103070002000200020002000200020002000200050
-:103080002000200020002000E003000000000000DD
-:1030900000000000040004000800080010001000F8
-:1030A00010002000200040004000C0008000800090
-:1030B0000001000100020002000200040000000004
-:1030C0007C004000400040004000400040004000C4
-:1030D00040004000400040004000400040004000F0
-:1030E00040004000400040007C0000000000600004
-:1030F0009000080100000000000000000000000037
-:1031000000000000000000000000000000000000BF
-:1031100000000000000000000000000000000000AF
-:10312000000000000000000000000000000000009F
-:10313000000000000000000000000000000000008F
-:1031400000000000000000000000FF0F0000000071
-:1031500018006000000000000000000000000000F7
-:10316000000000000000000000000000000000005F
-:10317000000000000000000000000000000000004F
-:10318000000000000000000000000000000000003F
-:10319000F0010C030C030003E0031C030E03060301
-:1031A00006038E0B7C0E00000000000000000000F3
-:1031B0000000000008000E000C000C000C000C00C9
-:1031C000CC013C031C060C060C060C060C060C0677
-:1031D0000C021C03E40100000000000000000000DD
-:1031E00000000000000000000000000000000000DF
-:1031F000F0008C018C018601060006000600060224
-:103200000C020C01F00000000000000000000000B3
-:10321000000000000002C0030003000300030003DD
-:1032200078038C030C030603060306030603060358
-:1032300004038C077801000000000000000000007B
-:10324000000000000000000000000000000000007E
-:10325000E001180308020C060C06FC070C000C0029
-:1032600018041802E0010000000000000000000047
-:10327000000000000000C00360063006300030008F
-:10328000FE013000300030003000300030003000EF
-:1032900030003000FC0100000000000000000000D1
-:1032A000000000000000000000000000000000001E
-:1032B000F007D8068C018C018C019801F8000C00F5
-:1032C000FC00CC03060306038E03F8000000000098
-:1032D0000000000008000E000C000C000C000C00A8
-:1032E000EC011C030C030C030C030C030C030C0378
-:1032F0000C030C039E07000000000000000000000B
-:1033000000000000000060006000000000004000BD
-:103310007C00600060006000600060006000600091
-:1033200060006000FC0300000000000000000000DE
-:10333000000000000000C001C0010000000000010A
-:10334000F001800180018001800180018001800105
-:103350008001800180018001CC007C000000000021
-:103360000000000008000E000C000C000C000C0017
-:103370008C038C008C004C006C005C008C008C0179
-:103380000C010C039E07000000000000000000007C
-:103390000000000040007C006000600060006000F1
-:1033A000600060006000600060006000600060001D
-:1033B00060006000FC03000000000000000000004E
-:1033C00000000000000000000000000000000000FD
-:1033D0003707EE0666066606660666066606660633
-:1033E00066066606FF0F00000000000000000000F7
-:1033F00000000000000000000000000000000000CD
-:10340000EE011C030C030C030C030C030C030C0354
-:103410000C030C039E0700000000000000000000E9
-:10342000000000000000000000000000000000009C
-:10343000F00098010C0306060606060606060606B8
-:103440000C030C03F000000000000000000000006E
-:10345000000000000000000000000000000000006C
-:10346000EE011C030C060C060C060C060C060C06E2
-:103470000C031C03EC010C000C003E0000000000DB
-:10348000000000000000000000000000000000003C
-:1034900078028C030C0306030603060306030603E7
-:1034A00004038C03780300030003C007000000003E
-:1034B000000000000000000000000000000000000C
-:1034C0009F03580638061800180018001800180046
-:1034D00018001800FF0000000000000000000000BD
-:1034E00000000000000000000000000000000000DC
-:1034F000F0031C030C020C023800F000C0030403AC
-:1035000004038C03FC010000000000000000000028
-:10351000000000000000000020002000300030000B
-:10352000FE0130003000300030003000300030004C
-:1035300030023002E0010000000000000000000046
-:103540000000000000000000000000000000080271
-:103550008E030C030C030C030C030C030C030C0371
-:103560000C039C0778010000000000000000000030
-:10357000000000000000000000000000000000004B
-:103580001E070C020801080118019000B000B000ED
-:10359000600060002000000000000000000000004B
-:1035A000000000000000000000000000000000001B
-:1035B000F70E6204460464026402EC029C01980166
-:1035C00098019801080000000000000000000000C1
-:1035D00000000000000000000000000000000000EB
-:1035E000BC0718011001B00060006000E00090000E
-:1035F000080108039E070000000000000000000012
-:1036000000000000000000000000000000000000BA
-:103610009E0708010801080190009000B0006000BA
-:10362000600060002000200024001C00000000005A
-:10363000000000000000000000000000000000008A
-:10364000FC018401C4004400600020003000180226
-:1036500008020C03FC010000000000000000000054
-:1036600000038000800080008000800080008000D7
-:10367000800040002000400080008000800080002A
-:1036800080008000800080000003000040004000B7
-:10369000400040004000400040004000400040002A
-:1036A000400040004000400040004000400040001A
-:1036B000400040004000400040004000000000008A
-:1036C0000C0010001000100010001000100010007E
-:1036D000100020004000200010001000100010001A
-:1036E00010001000100010000C00000000001C0072
-:1036F0002204C2048003000000000000000000005B
-:1037000000000000000000000000000000000000B9
-:1037100000000000000000000000000000000000A9
-:103720000000000000000000000000000000000099
-:103730000000000000000000000000000000000089
-:1037400000000000000000000000300030003000E9
-:103750003000300020002000200020002000000069
-:103760000000300030000000000000000000D80021
-:10377000D8006C00240012000000000000000000CF
-:103780000000000000000000000000000000000039
-:103790000000000000000000000000008400840021
-:1037A0008400FF0184008400C60042004200FF0143
-:1037B0004200420042000000000000000000000043
-:1037C00000002000F80024012401A401280030009A
-:1037D0006000A00020012C0124012401F800200039
-:1037E00020000000000000000000000086004900EA
-:1037F0004900290029001900D600280128012801C4
-:1038000024012401C20000000000000000000000AC
-:10381000000000000C00120012001200EA00460036
-:10382000460025002900390011003201CC000000BB
-:103830000000000000000600060004000200010075
-:103840000000000000000000000000000000000078
-:103850000000000000000000000000000000000167
-:103860008000400020002000200010001000100008
-:1038700010001000100020002000200040008000F8
-:103880000001000000000100020004000800080020
-:1038900008001000100010001000100010000800B8
-:1038A0000800080004000200010000000000000001
-:1038B000000000000000200020002603AE0370007E
-:1038C0007000AE032603200020000000000000006E
-:1038D00000000000000000000000000000001000D8
-:1038E000100010001000FF01100010001000100068
-:1038F00000000000000000000000000000000000C8
-:1039000000000000000000000000000000000000B7
-:103910000000000000000000000006000600040097
-:103920000200010000000000000000000000000094
-:10393000000000000000FE03000000000000000086
-:103940000000000000000000000000000000000077
-:103950000000000000000000000000000000000067
-:10396000000000000000000000000600060000004B
-:103970000000000000000002000100018000800043
-:10398000C000400060002000300010001800080057
-:103990000800040004000200000000000000000015
-:1039A000000000007800840084000201020102018E
-:1039B000020102010201020184008400780000007B
-:1039C00000000000000000000000000010001C00CB
-:1039D0001000100010001000100010001000100067
-:1039E000100010007C00000000000000000000003B
-:1039F000000000007C008200020102010201800040
-:103A0000400020001000080004010201FE01000037
-:103A10000000000000000000000000003C00420028
-:103A2000820082004000700080000001000102015D
-:103A3000020182007C000000000000000000000085
-:103A40000000400040006000500048004800440072
-:103A500042004200FE01400040004000F001000032
-:103A6000000000000000000000000000FC01040055
-:103A700004000400040074008C0000010001020135
-:103A8000020182007C000000000000000000000035
-:103A900000000000F00008010401040002007A00A8
-:103AA0008600020102010201040184007800000086
-:103AB000000000000000000000000000FE01820085
-:103AC000420040002000100010000800080008001C
-:103AD00008000800080000000000000000000000CE
-:103AE000000000007800840002010201020184004D
-:103AF00078008400020102010201840078000000C5
-:103B000000000000000000000000000078008400B9
-:103B1000820002010201020184017801000180009B
-:103B2000820042003C000000000000000000000095
-:103B30000000000000000000000030003000000025
-:103B40000000000000000000000030003000000015
-:103B50000000000000000000000000000000000065
-:103B60000000000010000000000000000000000045
-:103B70000000000010001000100010000000000005
-:103B80000000800040002000100008000400020037
-:103B90000400080010002000400080000000000029
-:103BA0000000000000000000000000000000000015
-:103BB0000000FF01000000000000FF010000000005
-:103BC00000000000000000000000000000000000F5
-:103BD00000000200040008001000200040008000E7
-:103BE0004000200010000800040002000000000057
-:103BF00000000000000000000000780084000201C6
-:103C00000601060100018000400020002000200085
-:103C10000000300030000000000000000000000044
-:103C2000000000007800C400F2015901490145017B
-:103C300025012501A500D9000201840078000000BB
-:103C40000000000000000000000000001000100054
-:103C50002800280028002800440044007C0044007C
-:103C600082008200C7010000000000000000000088
-:103C7000000000003F0042004200420022003E00DF
-:103C80004200820082008200820042003F00000069
-:103C90000000000000000000000000007801840126
-:103CA0000201020101000100010001000100010107
-:103CB0000201860078000000000000000000000003
-:103CC000000000003F00C200820002010201020168
-:103CD0000201020102010201820042003F000000D5
-:103CE000000000000000000000000000FF00820053
-:103CF0000201420042007E00420042000200020037
-:103D000002018200FF00000000000000000000002F
-:103D100000000000FF0082000201420042007E001D
-:103D20004200420002000200020002000700000000
-:103D30000000000000000000000000007001880189
-:103D400004010201020002000200820302010201DA
-:103D500004010C01F0000000000000000000000061
-:103D600000000000C7018200820082008200820001
-:103D7000FE0082008200820082008200C7010000F3
-:103D8000000000000000000000000000FE00100025
-:103D900010001000100010001000100010001000A3
-:103DA00010001000FE0000000000000000000000F5
-:103DB00000000000FC012000200020002000200066
-:103DC0002000200020002000200020002100110001
-:103DD0000E0000000000000000000000E7014200AB
-:103DE0002200220012001A001600220022004200C7
-:103DF00042008200C7010000000000000000000037
-:103E000000000000070002000200020002000200A1
-:103E1000020002000200020002018200FF00000016
-:103E2000000000000000000000000000C701C60004
-:103E3000C600C600AA00AA00AA00AA00AA00920012
-:103E400092009200D7010000000000000000000076
-:103E500000000000C70186008A008A008A009200E4
-:103E60009200A200A200C200C200C20087000000AF
-:103E70000000000000000000000000003800C60044
-:103E800082000101010101010101010101010101A2
-:103E90008200C600380000000000000000000000A2
-:103EA000000000007F008200020102010201820086
-:103EB0007E00020002000200020002000700000073
-:103EC0000000000000000000000000003800C600F4
-:103ED000820001010101010101010101010119013A
-:103EE000A600A60078004001C0000000000000000D
-:103EF000000000003F0042008200820042003E00BD
-:103F000012002200220042004200820087010000CD
-:103F100000000000000000000000000078018401A3
-:103F20000201020002000C0070008000000102018A
-:103F3000020186007A00000000000000000000007E
-:103F400000000000FE00110111011000100010001F
-:103F500010001000100010001000100038000000C9
-:103F6000000000000000000000000000C701820007
-:103F70008200820082008200820082008200820031
-:103F80008200440038000000000000000000000033
-:103F900000000000C7018200820044004400440089
-:103FA00044002800280028003800100010000000FD
-:103FB000000000000000000000000000BB019200B3
-:103FC000920092009200AA00AA00AA006A0044008F
-:103FD0004400440044000000000000000000000015
-:103FE00000000000CE01840044004800280030009A
-:103FF000100030002800480048008400CE01000076
-:10400000000000000000000000000000C701820066
-:104010004400440028002800100010001000100088
-:104020001000100038000000000000000000000038
-:1040300000000000FC0184008200400040002000DD
-:10404000100010000800080004018400FE000000B9
-:10405000000000000000F00110001000100010002F
-:1040600010001000100010001000100010001000D0
-:10407000100010001000F00100000000000000001F
-:1040800002000400040008000800080010001000EE
-:1040900020002000200040004000800080008000C0
-:1040A0000001000000003E00200020002000200051
-:1040B0002000200020002000200020002000200000
-:1040C0002000200020003E0000000000000038001A
-:1040D0002800440000000000000000000000000074
-:1040E00000000000000000000000000000000000D0
-:1040F00000000000000000000000000000000000C0
-:1041000000000000000000000000000000000000AF
-:1041100000000000000000000000FF030000180085
-:10412000200000000000000000000000000000006F
-:10413000000000000000000000000000000000007F
-:10414000000000000000000000000000000000006F
-:10415000000000007C0082008200F0008C008200E1
-:104160008200C202BC03000000000000000000004A
-:104170000000000003000200020002003A004600B6
-:104180008200820082008200820046003A00000025
-:10419000000000000000000000000000000000001F
-:1041A000000000007800840082000200020002008B
-:1041B0000201840078000000000000000000000000
-:1041C00000000000C000800080008000B800C40033
-:1041D00082008200820082008200C400B8010000D8
-:1041E00000000000000000000000000000000000CF
-:1041F00000000000780084000201FE0102000200BD
-:1042000002018400780000000000000000000000AF
-:1042100000000000E001100210001000FC0010007F
-:10422000100010001000100010001000FC00000032
-:10423000000000000000000000000000000000007E
-:1042400000000000F80184008400840084007800ED
-:1042500004007C00840102010201FC000000000057
-:104260000000000003000200020002007A00860045
-:10427000820082008200820082008200C70100006A
-:1042800000000000000000000000000018001800FE
-:10429000000000001C0010001000100010001000B2
-:1042A000100010007C000000000000000000000072
-:1042B000000000006000600000000000700040008E
-:1042C00040004000400040004000400040004000EE
-:1042D00022001E0000000000000000000300020099
-:1042E00002000200E200220012000A001600220072
-:1042F00042008200C7010000000000000000000032
-:10430000000000001E00100010001000100010003F
-:10431000100010001000100010001000FE0000003F
-:10432000000000000000000000000000000000008D
-:10433000000000007F009200920092009200920024
-:1043400092009200B7010000000000000000000091
-:104350000000000000000000000000007B0086005C
-:10436000820082008200820082008200C701000079
-:10437000000000000000000000000000000000003D
-:104380000000000078008400020102010201020125
-:10439000020184007800000000000000000000001E
-:1043A0000000000000000000000000003B0046008C
-:1043B0008200820082008200820046003A000200F1
-:1043C00002000700000000000000000000000000E4
-:1043D00000000000B800C400820082008200820059
-:1043E0008200C400B80080008000C001000000000E
-:1043F000000000000000000000000000CE012801C5
-:104400001800080008000800080008003E0000002E
-:10441000000000000000000000000000000000009C
-:1044200000000000BC00C200820006003800C0008E
-:10443000820086007A0000000000000000000000FA
-:10444000000000000000100010001000FC00100030
-:10445000100010001000100010009000600000001C
-:10446000000000000000000000000000000000004C
-:1044700000000000C30082008200820082008200EF
-:104480008200C200BC01000000000000000000002B
-:10449000000000000000000000000000C7018200D2
-:1044A00044004400440028002800100010000000D0
-:1044B00000000000000000000000000000000000FC
-:1044C00000000000BB01920092009200AA00AA0026
-:1044D0004400440044000000000000000000000010
-:1044E000000000000000000000000000CE01840079
-:1044F000480030003000300048008400CE01000049
-:1045000000000000000000000000000000000000AB
-:1045100000000000EE0184008800480048005000C0
-:10452000300020001000100010000C0000000000FF
-:10453000000000000000000000000000FE0042003B
-:10454000220020001000080084008200FE0000000D
-:1045500000000000000080014000400040004000DA
-:10456000400040006000100060004000400040003B
-:10457000400040004000400080010000200020007A
-:10458000200020002000200020002000200020002B
-:10459000200020002000200020002000200020001B
-:1045A00020002000000006000800080008000800A5
-:1045B0000800080018002000180008000800080083
-:1045C0000800080008000800060000001C00260281
-:1045D0002203C001000000000000000000000000F5
-:1045E00000000000000000000000000000000000CB
-:1045F00000000000000000000000000000000000BB
-:104600000000000000000008080808080808000072
-:104610001818000000486C24120000000000000080
-:10462000000000000000002424247F1212127F12D8
-:10463000121200000000081C2A2A0A0C1828282A36
-:104640002A1C080800000022251515152A58545464
-:10465000542200000000000C1212120A76252911C3
-:10466000916E000000060604030000000000000038
-:10467000000000000040201010080808080808107A
-:10468000102040000002040808101010101010083C
-:10469000080402000000000008086B1C1C6B0808DE
-:1046A0000000000000000000080808087F08080853
-:1046B00008000000000000000000000000000000F2
-:1046C000060604030000000000000000FE000000D9
-:1046D00000000000000000000000000000000000DA
-:1046E000060600000000804040202010100808044A
-:1046F00004020200000000182442424242424242A8
-:1047000024180000000000080E080808080808081F
-:10471000083E00000000003C4242422020100804F5
-:10472000427E00000000003C4242201820404042EF
-:10473000221C0000000000203028242422227E2099
-:10474000207800000000007E0202021A264040424B
-:10475000221C0000000000382402021A26424242B5
-:10476000241800000000007E22221010080808080B
-:10477000080800000000003C424242241824424243
-:10478000423C00000000001824424242645840406D
-:10479000241C0000000000000000181800000000A9
-:1047A00018180000000000000000000800000000D1
-:1047B000000808040000004020100804020408104B
-:1047C000204000000000000000007F0000007F008B
-:1047D0000000000000000002040810204020100823
-:1047E000040200000000003C42424640201010003D
-:1047F000181800000000001C225A555555552D422E
-:10480000221C00000000000808181414243C224256
-:1048100042E700000000001F2222221E22424242E4
-:10482000221F00000000007C424201010101014200
-:10483000221C00000000001F22424242424242422B
-:10484000221F00000000003F4212121E12120242FC
-:10485000423F00000000003F4212121E12120202EC
-:10486000020700000000003C222201010171212208
-:10487000221C0000000000E7424242427E424242C7
-:1048800042E700000000003E080808080808080881
-:10489000083E00000000007C1010101010101010D6
-:1048A0001010110F0000007722120A0E0A121222B5
-:1048B0002277000000000007020202020202020248
-:1048C000427F000000000077363636362A2A2A2A30
-:1048D0002A6B0000000000E346464A4A52525262E8
-:1048E000624700000000001C22414141414141411A
-:1048F000221C00000000003F424242423E020202EF
-:10490000020700000000001C2241414141414D537B
-:10491000321C60000000003F4242423E121222223E
-:1049200042C700000000007C4242020418204042BE
-:10493000423E00000000007F4908080808080808F7
-:10494000081C0000000000E742424242424242424C
-:10495000423C0000000000E74242222424141418C4
-:10496000080800000000006B4949494955553622A6
-:1049700022220000000000E74224241818182424F2
-:1049800042E70000000000772222141408080808FB
-:10499000081C00000000007E2120101008040442C2
-:1049A000423F0000007808080808080808080808BE
-:1049B000080878000000020204040808081010200B
-:1049C00020204040001E1010101010101010101069
-:1049D00010101E000038440000000000000000001D
-:1049E00000000000000000000000000000000000C7
-:1049F000000000FF000608000000000000000000AA
-:104A000000000000000000000000003C427844422A
-:104A100042FC0000000000030202021A2642424249
-:104A2000261A0000000000000000003844020202C4
-:104A30004438000000000060404040784442424258
-:104A400064D80000000000000000003C427E02022A
-:104A5000423C0000000000F08808087E08080808B2
-:104A6000083E0000000000000000007C22221C0222
-:104A70003C42423C000000030202023A46424242EB
-:104A800042E700000000000C0C00000E08080808B7
-:104A9000083E0000000000303000003820202020B8
-:104AA0002020221E0000000302020272120A1612C7
-:104AB000227700000000000E08080808080808080F
-:104AC000083E0000000000000000007F92929292D9
-:104AD00092B70000000000000000003B4642424246
-:104AE00042E70000000000000000003C4242424259
-:104AF000423C0000000000000000001B2642424231
-:104B0000221E0207000000000000007844424242DA
-:104B1000447840E000000000000000774C040404EA
-:104B2000041F0000000000000000007C42023C4026
-:104B3000423E0000000000000008083E0808080887
-:104B400008300000000000000000006342424242C2
-:104B500062DC000000000000000000E74224241492
-:104B60000808000000000000000000EB494955550E
-:104B7000222200000000000000000076241818180F
-:104B8000246E000000000000000000E7422424140E
-:104B900018080807000000000000007E2210080826
-:104BA000447E000000C02020202020102020202053
-:104BB0002020C00010101010101010101010101035
-:104BC0001010101000060808080808100808080847
-:104BD000080806000C32C2000000000000000000BF
-:104BE00000000000000000000000000000000000C5
-:104BF00000000404040404040004000000140A0A71
-:104C00000000000000000000000014143F140A3FE0
-:104C10000A0A000000041E1505060C14150F0400F6
-:104C2000000012150D0A142C2A1200000000040ABC
-:104C30000A1E1515093600000002020100000000DE
-:104C400000000000002010080808080808102000D4
-:104C50000002040808080808080402000000000414
-:104C6000150E0E150400000000000404041F0404C7
-:104C7000040000000000000000000000000202012B
-:104C800000000000001F0000000000000000000005
-:104C900000000000000200000010080808040402E0
-:104CA0000202010000000E1111111111110E00007D
-:104CB0000000040604040404040E000000000E11A9
-:104CC00011080402011F000000000E11100C10104A
-:104CD000110E00000000080C0A0A091E0818000046
-:104CE00000001F01010F1010110E000000000E093E
-:104CF000010F1111110E000000001F090804040427
-:104D00000404000000000E11110E1111110E00001C
-:104D100000000E1111111E10120E00000000000004
-:104D20000400000000040000000000000004000077
-:104D300000040400002010080402040810200000F1
-:104D4000000000001F00001F000000000002040817
-:104D5000102010080402000000000E1111080404C5
-:104D60000004000000000E111915151D011E0000A1
-:104D7000000004040C0A0A1E1233000000000F1287
-:104D8000120E1212120F000000001E11010101018B
-:104D9000110E000000000F1212121212120F00006A
-:104DA00000001F120A0E0A02121F000000001F124C
-:104DB0000A0E0A020207000000001C12010139114C
-:104DC000120C000000003312121E121212330000E7
-:104DD00000001F0404040404041F000000003E0837
-:104DE0000808080808090700000037120A060A0A1E
-:104DF000123700000000070202020202223F0000F8
-:104E000000001B1B1B1B15151515000000003B1295
-:104E100016161A1A1217000000000E1111111111A6
-:104E2000110E000000000F12120E02020207000015
-:104E300000000E1111111117190E180000000F12A9
-:104E4000120E0A121237000000001E11010608108F
-:104E5000110F000000001F1504040404040E0000DC
-:104E60000000331212121212120C00000000331252
-:104E7000120A0A0C0404000000001515150E0A0A97
-:104E80000A0A000000001B0A0A04040A0A1B0000A8
-:104E900000001B0A0A040404040E000000001F099D
-:104EA00008040402121F0000001C0404040404048B
-:104EB00004041C0000020202040408080810000098
-:104EC000000E08080808080808080E0000040A0078
-:104ED00000000000000000000000000000000000D2
-:104EE0000000003F0004000000000000000000007F
-:104EF00000000000000C121C123C00000000030225
-:104F0000020E1212120E000000000000001C12021D
-:104F1000021C000000001810101C1212123C0000AD
-:104F200000000000000C121E021C000000003804EB
-:104F3000041E0404041E000000000000003C120CCB
-:104F4000021E221C00000302020E12121237000081
-:104F50000000040000060404040E00000000080025
-:104F6000000C08080808080700000302023A0A0EAD
-:104F7000123700000000070404040404041F0000AA
-:104F800000000000000F15151515000000000000BE
-:104F9000000F12121237000000000000000C121265
-:104FA000120C000000000000000F1212120E020787
-:104FB00000000000001C1212121C1038000000003B
-:104FC000001B06020207000000000000001E020C89
-:104FD000101E000000000004040E04040418000069
-:104FE00000000000001B1212123C00000000000034
-:104FF0000037120A0C040000000000000015150E16
-:105000000A0A000000000000001B0A040A1B00003E
-:10501000000000000037120A0C0404030000000026
-:10502000001E0804041E00000018080808040808F0
-:1050300008081800080808080808080808080808E8
-:1050400000060404040804040404060002251800F1
-:1050500000000000000000006C65747465720000C0
-:1050600064656661756C7420757365720073657430
-:105070005661720073657420766172007570006409
-:105080006F776E007269676874006C65667400748F
-:105090006162006261636B7370616365006261638A
-:1050A0006B73706163650064656C65746500656E43
-:1050B00074657200656E7465720068656C7000736B
-:1050C000686F7720636F6D6D616E6420696E666FC7
-:1050D0000D0A68656C70205B636D645D00757365B7
-:1050E0007273006C69737420616C6C2075736572E7
-:1050F00000636D6473006C69737420616C6C206371
-:105100006D640076617273006C69737420616C6CFD
-:1051100020766172006B657973006C69737420612D
-:105120006C6C206B657900636C65617200636C6503
-:10513000617220636F6E736F6C65000064656661F9
-:10514000756C745461736B000D0A436F6D6D616E05
-:1051500064204C6973743A0D0A0000000D0A566110
-:1051600072204C6973743A0D0A0000000D0A5573E1
-:105170006572204C6973743A0D0A00000D0A4B6584
-:1051800079204C6973743A0D0A000000436F6D6D0D
-:10519000616E64206E6F7420466F756E640D0A0038
-:1051A0000D0A5761726E696E673A20436F6D6D61CB
-:1051B0006E6420697320746F6F206C6F6E670D0AC8
-:1051C00000000000206973206E6F742061207661FA
-:1051D000720D0A0063616E27742073657420726516
-:1051E0006164206F6E6C79207661720D0A00000098
-:1051F00063616E27742073657420706F696E7465C7
-:10520000720D0A000D0A205F20202020202020207F
-:10521000205F2020205F2020202020202020202010
-:1052200020202020202020205F202020202020203F
-:105230002020205F205F200D0A7C207C2020202061
-:105240005F5F5F7C207C5F7C207C5F205F5F5F20F6
-:105250005F205F5F2020205F5F5F7C207C5F5F209E
-:1052600020205F5F5F7C207C207C0D0A7C207C20DE
-:1052700020202F205F205C205F5F7C205F5F2F203D
-:105280005F205C20275F5F7C202F205F5F7C2027D2
-:105290005F205C202F205F205C207C207C0D0A7C1E
-:1052A000207C5F5F7C20205F5F2F207C5F7C207CE8
-:1052B0007C20205F5F2F207C202020205C5F5F20EF
-:1052C0005C207C207C207C20205F5F2F207C207C49
-:1052D0000D0A7C5F5F5F5F5F5C5F5F5F7C5C5F5F51
-:1052E0007C5C5F5F5C5F5F5F7C5F7C202020207C5C
-:1052F0005F5F5F2F5F7C207C5F7C5C5F5F5F7C5FBC
-:105300007C5F7C0D0A0D0A4275696C643A2020208E
-:10531000202020205365702031302032303235205B
-:1053200030303A34333A34340D0A56657273696F4B
-:105330006E3A2020202020332E322E340D0A436F67
-:10534000707972696768743A2020202863292032B6
-:10535000303230204C65747465720D0A0000000014
-:105360000D0A70617373776F7264206572726F7269
-:105370000D0A0000566172206E6F7420466F756EC4
-:10538000740D0A001B5B324B0D000000434D44209E
-:105390000000000056415220000000004B455920FB
-:1053A00000000000636F6D6D616E642068656C7055
-:1053B000206F662000000000506C656173652069F5
-:1053C0006E7075742070617373776F72643A000049
-:1053D0004E4F4E45000000001B5B324A1B5B3148BC
-:1053E0000000000055534552000000003C550108E4
-:1053F000000000209802000054080008CC56010864
-:105400009802002018170100288F0008CC560108C8
-:1054100000C0012000400000288F000800080000A4
-:10542000585001085F500108605001080021000039
-:105430006D500108C1C50008745001080009000042
-:1054400000415B1BA7CA00087C500108000900004E
-:1054500000425B1B91B700087F5001080019000053
-:1054600000435B1B1BC400088450010800190000A6
-:1054700000445B1B07C100088A50010800090000B6
-:1054800000000009E5C800088F500108001900005D
-:1054900000000008A1B500089350010800190000A1
-:1054A0000000007FA1B500089D5001080019000010
-:1054B0007E335B1B87B60008A75001080019000067
-:1054C0000000000AA1B70008AE5001080019000052
-:1054D0000000000DA1B70008B45001080020000032
-:1054E000BA500108F5BD0008BF50010800210000B6
-:1054F000DD500108B5CA0008E35001080021000092
-:10550000F150010875B60008F650010800210000AE
-:1055100003510108C7CA0008085101080021000012
-:1055200015510108F5C000081A51010800210000BA
-:105530002751010831B600082D510108813210426F
-:1055400001035D24F41AAA0101141345A8140831BB
-:10555000A914088045122016C0012080C51C208097
-:10556000E50C6998B11334E813080C120C121812E8
-:10557000141314EA1B0810BE1A200C1394EC1A081A
-:1055800012111A3C041344F11B081822124812414C
-:105590001E8C03010820221A80181C8C0D01301269
-:1055A0002032401C4C250148121832301E1C370195
-:1055B000080A2032281EF4450108085432101EE45F
-:1055C0004B0108066C720C13FD6C1408456D1B082A
-:1055D00055041A81041AC1041AC9141A0D081312A9
-:1055E00001140202021640830440571D0201020307
-:1055F000B9071A040309041A0313E9091B08E5048F
-:105600001AA104130D0A1B08310441130A063202C1
-:105610002A40FC13AD671408A9654C08F7691C13F0
-:105620007D6614089D641B086114C11A21281ADDC7
-:105630001C1A69081ACD081C090243871125C032BB
-:1056400009041B01020B1305241610010524011087
-:105650000901042402020524061E0107058203ED48
-:105660001B0904BD320A2E0705010240072A8107E3
-:105670001C810182C41809520108A0510108480484
-:105680001A5C041A6C041A7C041A8C041AF0041AAA
-:10569000D4041AC4041E74530108A4041AB8041ACA
-:1056A00060041AD8041A84041A8C041A94041AE4A4
-:1056B000041A9C041AD004E3222213E0E71B08E634
-:0C56C0000417C6E533B4FD960200080094
+:100000004FF0080B0120009005E04FF0020B02209A
+:10001000009000E000BF00BF00982918701C08B9CC
+:10002000012000E000200C1811E020782E2803D1D8
+:100030004FF00108641C0AE0207800F025F907FB66
+:100040000B0708EB88004FEA4008641C00BF2078CB
+:100050000028EAD1BAF1040F17D1B8F1000F14D07B
+:1000600000EE107AB8EE401A00EE108AB8EE400AA0
+:10007000C1EE000A00EE106AB8EEC00A20EE800A57
+:1000800010EE109A4846BDE8F88F07FB06F0FAE735
+:10009000000000002DE9F04107460C4616461D46BB
+:1000A00026B1207824282FD1607868B320782728BB
+:1000B00008D1607830B12046FFF74CFF286000205F
+:1000C000BDE8F08120782D2805D02078302808DB85
+:1000D0002078392805DC2046FFF766FF28600020DD
+:1000E000EEE72078242807D1607828B12A462146F7
+:1000F000384600F031F8E3E7207828B1204600F0D8
+:1001000006F828600020DBE74FF0FF30D8E770B535
+:100110000446254600262078222802D1601C044689
+:10012000054613E028785C2805D12846FFF712FF22
+:10013000A0556D1C07E02878222802D10020A05588
+:1001400001E02878A0556D1C701C86B22878002824
+:10015000E8D1A055204670BD2DE9F04104460D467A
+:1001600016460023691C2046A26D00F028FD0746B4
+:100170003FB13946204600F0FDF830600020BDE870
+:10018000F0814FF0FF30FAE72DE9F0478CB0804660
+:100190000C4615461E464FF0000A202104A8F0F731
+:1001A000FAF8A07800F00F01681E814203DDA07804
+:1001B00000F00F0000E0681E07464FF0000912E053
+:1001C00004A800EB890309F1010056F82010002271
+:1001D0004046FFF75FFF20B14FF0FF300CB0BDE8A5
+:1001E000F08709F10109681E4845E9DC082F45D26E
+:1001F000DFE807F004080E151C232C37A0688047A1
+:1002000082463EE0D4F808900498C847824638E019
+:10021000D4F80890DDE90401C847824631E0D4F8FB
+:10022000089004A807C8C84782462AE0D4F8089076
+:1002300004A80FC8C847824623E0D4F8089008985D
+:10024000009004A80FC8C84782461AE0D4F8089066
+:10025000DDE90801CDE9000104A80FC8C8478246BE
+:100260000FE0D4F80890DDE908120A98CDE90012F1
+:10027000029004A80FC8C847824602E04FF0FF3A38
+:1002800000BF00BF5046A9E70146302905DB3929E8
+:1002900003DCA1F13000C0B27047612905DB66299B
+:1002A00003DCA1F15700C0B2F6E7412905DB46297E
+:1002B00003DCA1F13700C0B2EEE70020ECE7014615
+:1002C000487800F00F00012801DCC86870474878C2
+:1002D00000F00F00072801DCC868F7E7487800F055
+:1002E0000F00082801DCC868F0E7C868EEE70000E6
+:1002F00010B50446002004E03021104A1154411C7E
+:10030000C8B20928F8DB607800F00F00012801DC92
+:10031000606810BD607800F00F00072801DC60689D
+:10032000F7E7607800F00F00082801DC6068F0E76C
+:100330000249606800F005FF0048EAE74C2401200C
+:10034000002111E00A4850F8210058B1084850F83F
+:10035000210090F86000C0F3400018B1044850F844
+:1003600021007047481C01B20529EBDB0020F8E7AB
+:10037000382401202DE9F04107460C46002660781C
+:1003800000F00F00801E06281BD2DFE800F00306F5
+:100390000A0D0E10A068066814E0A068B0F90060AD
+:1003A00010E0A06806780DE000BFA6680AE0A0682B
+:1003B00045681DB1A1680868A84700E0002006460E
+:1003C00000E000BF00BF3046BDE8F0812DE9F047F6
+:1003D00004468846B8F1000F01D1BDE8F0872046F9
+:1003E000E16E884718274FF00009208F00F47F4006
+:1003F00018B100276FF0FF090EE0A06B00F47F003A
+:1004000018B10827DFF8BC9006E0A06B00F07F4031
+:1004100010B110274FF07F49A66D00253EE006EB96
+:100420000510407800F00F00092835D106EB0511C2
+:100430002046FFF749FC70BB06EB0510406800EA58
+:100440000900A16B884227D106EB05104168FF2007
+:10045000B840084008FA07F188421DD108FA07F1B0
+:10046000A06B0843A0634FF0000847B106EB0510EE
+:100470004068A7F10801FF228A40104058B906EBF6
+:100480000510806820B106EB05108168204688477A
+:100490000021A16306E0FFE7681C05B25C20005B59
+:1004A000A842BCDC00BFB8F1000F05D00021A16359
+:1004B0004146204600F0CCFA2046216F884700BF15
+:1004C0008BE700000000FFFF70B504460D46FFF704
+:1004D00037FF064606B970BD012C03D1304600F047
+:1004E00089F905E0012C03DD3046696800F094FECF
+:1004F00000BFF0E770B504460D46002D25DDB4F9C8
+:1005000054105420005B401E02B25420025350206D
+:10051000025B5220005B824202DD5020005B01E062
+:100520005220005B404281421DDC5020015B522082
+:10053000005B814202DD5020005B01E05220005B45
+:10054000404201B2542001530DE0002D0ADA54203C
+:10055000005B401C01B254200153002903DD00213F
+:10056000015370BDFDE72046FFF7DAFB5420005B26
+:1005700018B90021A181E1811BE05220005B401DE0
+:10058000B4F954100844052190FBF1F201FB12016B
+:1005900004F13C0050F821603146206900F000FD74
+:1005A000A08100B9DDE7A189E1812046216900F041
+:1005B000E3FE00BFD5E710B50446002154200153E7
+:1005C0005020005B002810DD5222125B21690AB91D
+:1005D000052201E05222125B521E04F13C0353F843
+:1005E0002200EFF7EAFE00B910BD5222135B04F1BE
+:1005F0003C0252F82300216900F0D2FC28B15220BD
+:10060000005B401C81B2522001535020005B401C13
+:1006100081B250200153052901DD052101535220EB
+:10062000005B052802DB00215220015300BFDBE7FD
+:100630002DE9F04104460D4616460020A081002118
+:10064000E181206094F8600020F00100401C84F8F3
+:1006500060002561062096FBF0F0A086542001532F
+:100660005020015352200153002009E0A28E411C6A
+:1006700002FB015204F13C0141F82020411C08B268
+:100680000528F3DB0E48A0650E480D49401AC0F35B
+:100690000F115C2001532046FFF7D8FA00230AA16E
+:1006A0002046A26D00F08BFA07463946204600F03E
+:1006B000C3FA0121204600F0E5FDBDE8F08100000D
+:1006C0006C6101088C6201086C65747465720000CD
+:1006D00070B504460D46A189A08E401E81420DDBF7
+:1006E00038484168204600F047FE0121204600F0CE
+:1006F000C9FD2046216900F03FFE70BDE089A18957
+:10070000884218D1A189481CA08120694554002144
+:10071000A28920698154E089401CE08194F860003E
+:1007200000F0010008B1284600E02A2001462046DA
+:1007300000F03CFD44E0E089A189884240DAA289CA
+:10074000E189511A08B20AE0E1890144491E22698F
+:10075000525CE189014423695A54411E08B20028C1
+:10076000F2DCE189481CE081206945540021A08920
+:10077000401C80B22269A0811154E089401E06B25B
+:100780000EE094F8600000F0010010B12069805D77
+:1007900000E02A200146204600F008FD701C06B249
+:1007A000A089B042EDDCA189E089081A06B205E013
+:1007B0000821204600F0FAFC701E06B2002EF7DC7D
+:1007C00000BF9AE7D801002010B5FFF7B9FD044635
+:1007D00014B1204600F0B8F810BD10B50446E08909
+:1007E000002806DD0821204600F0E0FCE089401EDC
+:1007F000E08110BD10B50446204600F001F810BDA0
+:1008000070B50546AE6D10488168284600F0B4FD0D
+:10081000002413E006EB0410407800F00F000128DC
+:100820000ADC06EB04112846FFF74EFA20B906EB66
+:100830000411284600F00AF8601C04B25C20405BFA
+:10084000A042E7DC70BD0000D80100202DE9F04196
+:1008500007460C462046FFF74BFD0546294638461D
+:1008600000F08AFDC0F1160006B2002E01DD304610
+:1008700000E00420064600BF2021384600F096FC28
+:10088000701E00B2061EF7D1607800F00F0001283C
+:1008900005DC2A48016C384600F06EFD25E06078E2
+:1008A00000F00F00072805DC2448416C384600F0B2
+:1008B00063FD1AE0607800F00F00082805DC1F488F
+:1008C000816C384600F058FD0FE0607800F00F00B2
+:1008D000092805DC1948C16C384600F04DFD04E0DC
+:1008E0001648016D384600F047FD15A1384600F066
+:1008F00043FD07250DE020780122AA40104008B1F1
+:10090000782000E02D200146384600F04FFC681E9C
+:1009100045B2002DEFDA0AA1384600F02DFD204641
+:10092000FFF7CDFC05462946384600F047FC05A1F7
+:10093000384600F021FDBDE8F0810000D80100201C
+:10094000202000000D0A000070B50646B56D134862
+:100950004169304600F010FD00241AE005EB041058
+:10096000407800F00F00082811DD05EB04104078F6
+:1009700000F00F0009280ADC05EB04113046FFF7F0
+:10098000A3F920B905EB04113046FFF75FFF601CA7
+:1009900004B25C20805BA042E0DC70BDD801002086
+:1009A00070B50646B56D13480169304600F0E4FCA9
+:1009B00000241AE005EB0410407800F00F0007282F
+:1009C00011DD05EB0410407800F00F0008280ADC68
+:1009D00005EB04113046FFF777F920B905EB041158
+:1009E0003046FFF733FF601C04B25C20805BA042FE
+:1009F000E0DC70BDD801002070B50646B56D134827
+:100A0000C168304600F0B8FC00241AE005EB041081
+:100A1000407800F00F00012811DD05EB041040784C
+:100A200000F00F0007280ADC05EB04113046FFF741
+:100A30004BF920B905EB04113046FFF707FF601CA6
+:100A400004B25C20805BA042E0DC70BDD8010020D5
+:100A500070B504460D4694F8600020F0040084F858
+:100A6000600029462046FFF733FE70BD18B50446E6
+:100A700008200090A189202304F11402206900F0CD
+:100A8000EDF9E08618BD70B5044600252BE004F1B1
+:100A9000140050F82500007822280CD1002104F120
+:100AA000140050F82500017004F1140050F82510CE
+:100AB000491C40F8251004F1140151F82500EFF706
+:100AC00075FC86B204F1140050F82510701E085C05
+:100AD000222806D1002104F1140050F82520701EB0
+:100AE0001154681C85B2E08EA842D0DC70BD10B5F0
+:100AF0000446E089A189884207DAE289501CE08136
+:100B00002069815C204600F051FB10BD2DE9F041C9
+:100B100004460D46002694F8600020F00200801C78
+:100B200084F86000687800F00F0088B92046FFF76D
+:100B3000AAFFAF68E08E04F11401B8470646687852
+:100B4000C0F3401018B93146204600F0CFFB2DE02D
+:100B5000687800F00F00012810D1E28E04F1140330
+:100B600029462046FFF710FB06466878C0F3401080
+:100B7000E0B93146204600F0B9FB17E0687800F094
+:100B80000F00022809DB687800F00F00072804DC5A
+:100B90002946204600F002F908E0687800F00F00CE
+:100BA000082803D12946204600F046F894F8600052
+:100BB00020F0020084F860003046BDE8F0812DE9A5
+:100BC000F0470646884614461F465C20805BB16DA0
+:100BD000611AA0EB11101FFA80F9002528E004EB40
+:100BE0000510407800F00F00092805D004EB05112E
+:100BF0003046FFF769F800B118E004EB0510FFF785
+:100C000077FB824647B951464046EFF7D6FB60B9BD
+:100C100004EB0510BDE8F0873A4651464046EFF731
+:100C2000E3FB10B904EB0510F4E700BF681C85B2C4
+:100C30004D45D4DB0020EDE770B504460D46256038
+:100C4000A86858B1A868EFF7B1FB38B1E08E022868
+:100C500006DBA169A868EFF7B0FB08B9012000E046
+:100C6000002094F8601060F3000184F860100848D8
+:100C7000816B204600F080FB94F8600000F00100DA
+:100C800020B103480168204600F076FB70BD0000EB
+:100C9000D80100202DE9F04106460F46FFF750FB32
+:100CA000054615B90020BDE8F081002331462846ED
+:100CB000AA6DFFF784FF044634B91148816A2846BB
+:100CC00000F05AFB0020EEE7607800F00F000228E9
+:100CD00004DB607800F00F0007280ADD3146284663
+:100CE00000F04AFB0648416A284600F045FB002018
+:100CF000D9E73A462146284600F004F8D3E7000039
+:100D0000D80100202DE9F04106460C4615466078D2
+:100D1000C0F3801028B12048016A304600F02CFB57
+:100D200034E0607800F00F00801E06282CD2DFE847
+:100D300000F003060A0D1218A068056025E029B22C
+:100D4000A068018021E0A06805701EE02946A06827
+:100D500000F026F919E01048C169304600F00CFB9C
+:100D600013E0A068806870B1A068006830B1A06826
+:100D70008768A16808682946B84704E0A0688768C2
+:100D80002846B84700BF00E000BF00BF21463046FC
+:100D900000F004F8BDE8F081D8010020FEB505465A
+:100DA0000C4626A207CA8DE8070021462846FFF711
+:100DB000E1FA07462846616800F0DEFA22A12846DB
+:100DC00000F0DAFA607800F00F0005280CD11FA1BE
+:100DD000284600F0D1FA3946284600F0CDFA1BA18A
+:100DE000284600F0C9FA21E06946384600F07EF94D
+:100DF000C0F10B00694646183146284600F0BCFA9F
+:100E000013A1284600F0B8FA002004E030210DF8C4
+:100E10000010411C08B20B28F8DB6946384600F088
+:100E200090F96946284600F0A7FA00BF00BF0AA162
+:100E3000284600F0A1FA3846FEBD000030303030C0
+:100E40003030303030303000203D200022000000B3
+:100E50002C203078000000000D0A00002DE9FF4F23
+:100E600004468C4615460D9F4FF001080020009067
+:100E70000190029003900021002600BF04E00022B0
+:100E800045F82020421C10B2B842F8DB002068E090
+:100E900011BB225C9A420DD0B8F1010F0AD1BE42BB
+:100EA00008DA04EB000A3246761C45F822A04FF01F
+:100EB000000811E0225C9A4202D0225C202A0BD169
+:100EC000B8F1000F08D100222254421CA25C202A53
+:100ED00001D04FF0010842E0002234E0002918DD83
+:100EE00014F80090DFF888A00AEB420A9AF801A0F3
+:100EF000D1450ED1A1F101091DF80990DFF870A0CC
+:100F00001AF812A0D14504D1A1F1010909F0FF019D
+:100F10001BE014F80090DFF858A01AF812A0D14591
+:100F20000DD1DFF84C9019F812B0894601F1010A91
+:100F30000AF0FF010DF809B001F00F0105E002F120
+:100F4000010909F0FF02002AC8D000BF225C5C2A18
+:100F500004D1421CA25C0AB1421C90B200BF421CE8
+:100F600090B2604594DB304604B0BDE8F08F0000DD
+:100F70002C02002030B502460B460020002108E07C
+:100F8000545C5D5CAC4200D008E0441CA0B24C1C38
+:100F9000A1B2545C14B15C5C002CF1D100BF30BD37
+:100FA0000246002003E00B5C1354431C98B20B5C18
+:100FB000002BF8D1135470472DE9F84F0446B4F8CC
+:100FC00034A04FF000080025A08938B92046FFF76B
+:100FD00011FC0121204600F055F970E0A08900289D
+:100FE0006DDD0021A28920698154A66D002737E0BC
+:100FF00006EB07112046FEF767FE78BB06EB0710ED
+:10100000FFF776F9834659462069FFF7B3FFA189B8
+:10101000884223D1F5B1012D03D12AA1204600F049
+:10102000ABF906EB08112046FFF710FC06EB0710A2
+:10103000FFF75EF9834606EB0810FFF759F95946AA
+:101040000090FFF797FF8146CA4501DD484600E062
+:10105000504682461FFA87F8681C85B2781C07B292
+:101060005C20005BB842C3DC0DB9BDE8F88F012DF0
+:1010700002D12046FEF754FE4DB106EB0810FFF7F3
+:1010800037F9074639462069FFF78AFFA081012D0D
+:101090000ADD06EB08112046FFF7D8FB01212046A8
+:1010A00000F0F0F8A4F80CA00021A2892069815476
+:1010B000A189E1812046216900F05EF900BF00BFEF
+:1010C000D3E700000D0A000008B505462C460CE0E9
+:1010D000606E50B101216846626E9047012804D1CC
+:1010E0009DF800102046FFF771F9F1E730B5024690
+:1010F0000B241346002A00DA53420020C8720DE088
+:101100000A2093FBF0F500FB15303030C5B2601EAD
+:10111000C0B204460D540A2093FBF0F3002BEFD12C
+:10112000002A04DA2D25601EC0B204460D5422B9EF
+:101130003025601EC0B204460D54C4F10B0040B20D
+:1011400030BD30B502460B460824002018720EE070
+:1011500002F00F01092902DD01F1570001E001F160
+:101160003000C5B2601EC0B204461D541209002AE8
+:10117000EED1C4F1080040B230BD10B504460121E3
+:101180002046FFF7B7F910BD10B5FFF7D9F80446B0
+:1011900014B12046FFF704FC10BD10B5FFF7D0F8DE
+:1011A000044614B12046FFF727FC10BD13B50446D2
+:1011B000012101A8A26E90471CBD00002DE9F0415D
+:1011C00004460F4600253E46A06E10B90020BDE83B
+:1011D000F08102E0761C681C85B2307828B1307846
+:1011E0000D2802D030780A28F4D1242D08DD2421DE
+:1011F0003846A26E9047032106A0A26E904703E0F6
+:1012000029463846A26E9047242D01DD2420DEE7D2
+:101210002720DCE72E2E2E002DE9F04104460E4655
+:10122000002331462046A26DFFF7C9FC0546EDB10B
+:101230001248C16A204600F09FF82846FFF758F888
+:1012400007463946204600F097F80DA1204600F0E9
+:1012500093F82846FFF733F807463946204600F052
+:101260008BF807A1204600F087F804E00348816965
+:10127000204600F081F8BDE8F0810000D801002090
+:101280000D0A000070B504460D4694F8600000F0A9
+:101290000100D8B11DB110A1204600F06DF8206802
+:1012A0004168204600F068F80CA1204600F064F880
+:1012B000A06808B1A06800E009A00146204600F03F
+:1012C0005BF808A1204600F057F804E00648016BDF
+:1012D000204600F051F870BD0D0A00003A000000F1
+:1012E0002F00000024200000D8010020FEB5054694
+:1012F0000C4618A2D2E900109268CDE901020091D3
+:1013000017A1284600F038F869462046FFF7EEFEA0
+:10131000C0F10B00694646183146284600F02CF80B
+:1013200012A1284600F028F8002004E030210DF832
+:101330000010411C08B20B28F8DB69462046FFF775
+:1013400000FF6946284600F017F80AA1284600F079
+:1013500013F8FEBD303030303030303030303000B7
+:1013600052657475726E3A20000000002C203078AF
+:10137000000000000D0A00002DE9F04104460D4672
+:1013800000262F46A06E10B90020BDE8F08101E0D4
+:10139000701C86B217F8011B0029F9D13146284686
+:1013A000A26E904780B2F0E7F0B51E49896B0968DC
+:1013B0004968C1F5807188B21B490988884203DBFE
+:1013C00019490988411A04E017490988C1F5807153
+:1013D00001448BB2002120E0134E36887218D617D4
+:1013E00002EB16663612A2EB0626104FBD5D104EBC
+:1013F0003688721CD61702EB5666F611A2EBC6169B
+:10140000B4B20C4A1288944205D00B4A084E368872
+:101410009555074A14804A1C91B29942DCDB024977
+:101420000880F0BD6406002038020020CC26012090
+:101430003402002036020020CC2701200FB42DE911
+:10144000F04105460E9F022D01DA012100E0002146
+:1014500008464FF48771EFF79DFB34263146002094
+:10146000F9F7EEFC044600BF201D07A91C2203E08B
+:1014700011F8013B00F8013B131EA2F10106B2B2C4
+:10148000F6D100BF278084F830500A49E1625DB18F
+:10149000012D04D1084860620849A16204E040F2CD
+:1014A0001F110020EFF776FB2046BDE8F0015DF844
+:1014B00014FB000009930008719E0008D99E0008E3
+:1014C0007CB504460CB1012100E00021084644210E
+:1014D000EFF760FB206970B12169D1E90401CDE922
+:1014E00000012569D5E902633246D5E90001B0471C
+:1014F000204600F01CF87CBD7CB504460CB10121EF
+:1015000000E0002108465321EFF744FB206968B151
+:101510002169D1E90401CDE900012569EE6833466E
+:1015200095E80700B047204600F001F87CBD70B593
+:10153000044600250CB1012100E0002108460D21E0
+:10154000EFF728FB2588002D06DD00E000BF281EF0
+:10155000A5F101018DB2F9D170BD2DE9F34182B041
+:101560000446FF270CB1012100E000210846A92113
+:10157000EFF710FB94F8310001287ED100269AE0A5
+:1015800025460DB1012100E0002108468C21EFF72E
+:1015900001FBE86860B1E968D1E90401CDE9000127
+:1015A000D5F80CC0DCF80C8043469CE80700C04727
+:1015B00000BF2046FFF7BBFF9DF80C0000F0800045
+:1015C000C8B125460DB1012100E000210846622185
+:1015D000EFF7E0FA686860B16968D1E90401CDE924
+:1015E0000001D5F804C0DCE902834246DCE90001D1
+:1015F000C04700BF19E025460DB1012100E00021E0
+:1016000008467021EFF7C6FA686860B16968D1E9E9
+:101610000401CDE90001D5F804C0DCF80C80434694
+:101620009CE80700C04700BF00BF2046FFF77FFFD0
+:1016300025460DB1012100E0002108467E21EFF78B
+:10164000A9FAE86860B1E968D1E90401CDE90001CF
+:10165000D5F80CC0DCE902834246DCE90001C04752
+:1016600000BF2046FFF763FF9DF80C004006000E08
+:1016700003907806070EA06800E023E00068C0B180
+:1016800025460DB1012100E0002108469A21EFF71F
+:1016900081FAA968D1E90401CDE90001D5F808C0B3
+:1016A000DCF814809CE80F00C047012801D1781CA9
+:1016B000C7B2701CC6B2082EFFF662AF384604B03F
+:1016C000BDE8F081002001904FF4FA600090012302
+:1016D00001AA03A9206AF2F7C1F908B1FF20EEE7D9
+:1016E0009DF80400EBE700000FB4F8B507A80090E0
+:1016F0004FF400611348009B069AF7F771FC05460A
+:10170000002000900326104890F89C02032812D174
+:101710000D48D0F8BC72EFF7B1FE044605E0EFF7D4
+:10172000ADFE001BB04200D903E0D7F81402002838
+:10173000F5D100BF00BFA9B20248EFF70FFAF8BC1D
+:101740005DF814FB0C1501203008012070B505462A
+:101750000C46214601A0FFF7C7FF70BD6C656E20E7
+:101760003D2025640D0A00001CB5012000F0FEFBA1
+:101770001449086014481549886615484866154894
+:10178000C866154808674FF4007214490F48FEF701
+:101790004FFF4FF4807212491248F2F715FE1148BC
+:1017A0000068C06840F010000E490968C860002059
+:1017B0000121064B8A02CDE900100BA10D4801F072
+:1017C0005DF81CBD3002002081180108582401205A
+:1017D00011180108F917010865180108CC24012027
+:1017E000CC260120640600207368656C6C5F746110
+:1017F000736B0000C910010810B504464FF0FF31AB
+:101800000248006800F018FF002010BD30020020E0
+:1018100030B502460B46002119E00F4800880F4CF6
+:101820002488A04200D114E00D480C4C2488055DAA
+:1018300008464C1CA1B21554084C2488601CC417DF
+:1018400000EB5464E411A0EBC414044D2C809942C5
+:10185000E3DB00BF08B230BD3402002036020020B6
+:10186000CC27012010B5044600231A461946034828
+:10187000006800F075FC002010BD00003002002060
+:1018800070B505460C4640F2FF1322462946024831
+:10189000F2F7BDFD20B270BD6406002001460A6962
+:1018A000D1E901309860D1E901035860506888425D
+:1018B00001D188685060002008611068401E1060E7
+:1018C00010687047034B0360034B0B608023136069
+:1018D0007047000054020020A802002000F1080117
+:1018E00041604FF0FF31816000F10801C16001618A
+:1018F00000210160704700210161704710B5024668
+:101900000B685C1C0CB9106907E002F1080000E0EC
+:101910004068446824689C42FAD944684C604C682A
+:10192000A160886041600A611468641C146010BD85
+:1019300042684A6093688B6093685960916008615F
+:1019400003685B1C0360704700BF502080F3118860
+:10195000BFF34F8FBFF36F8F00BF0E480068401C6E
+:101960000C49086008460068012812D10A4800683E
+:10197000C0B208B9012000E0002050B900BF5020DB
+:1019800080F31188BFF34F8FBFF36F8F00BF00BF8D
+:10199000FEE770477000002004ED00E00D4800688D
+:1019A00050B900BF502080F31188BFF34F8FBFF3B1
+:1019B0006F8F00BF00BFFEE706480068401E054964
+:1019C00008600846006820B9002080F3118800BF35
+:1019D00000BF70477000002070B506463546002EE7
+:1019E00044D0083D2C46224960680968084008B187
+:1019F000012000E0002050B900BF502080F3118882
+:101A0000BFF34F8FBFF36F8F00BF00BFFEE72068AB
+:101A100008B9012000E0002050B900BF502080F339
+:101A20001188BFF34F8FBFF36F8F00BF00BFFEE77A
+:101A30000F49606809680840C0B12068B0B90C4916
+:101A4000606809688843606000F08EF90949606841
+:101A500009680844074908602046F9F72DFE064842
+:101A60000068401C0449086001F068F970BD00007E
+:101A70006C0000205C0000206800002000204FF077
+:101A8000E02108618861064800684FF47A71B0FB74
+:101A9000F1F0401E4FF0E0214861072008617047D7
+:101AA0001000002070B5EEF7D7FB0446102C16D3BB
+:101AB00004F1E02090F8F05315480078854201DBEE
+:101AC000012000E0002050B900BF502080F31188B1
+:101AD000BFF34F8FBFF36F8F00BF00BFFEE70D480E
+:101AE000006800F4E0600C490968884201D80120D0
+:101AF00000E0002050B900BF502080F31188BFF3F0
+:101B00004F8FBFF36F8F00BF00BFFEE770BD0000B7
+:101B1000740000200CED00E07800002070B5044651
+:101B20000025D4B11248006808B9012000E0002067
+:101B300050B900BF502080F31188BFF34F8FBFF31F
+:101B40006F8F00BF00BFFEE700F00EF900212046B6
+:101B5000F9F760FB01F0F2F805463DB94FF080500F
+:101B600004490860BFF34F8FBFF36F8F70BD000053
+:101B70004C00002004ED00E00349096801600349BE
+:101B800009684160704700003C00002028000020E8
+:101B900001200149086070473800002070B50446F4
+:101BA0000D4654B900BF502080F31188BFF34F8F0A
+:101BB000BFF36F8F00BF00BFFEE705480168183113
+:101BC0002046FFF79BFE01212846F9F723FB70BD55
+:101BD000140000202DE9F04706460F4634464FF02A
+:101BE0000109002E60D0A06C50B900BF502080F3D6
+:101BF0001188BFF34F8FBFF36F8F00BF00BFFEE7A9
+:101C0000606CB84201D23D4600E0656CE06AA842D3
+:101C10004AD0A06C012847D124480068844201D0F2
+:101C2000012000E0002050B900BF502080F311884F
+:101C3000BFF34F8FBFF36F8F00BF00BFFEE7D4F835
+:101C40002C80E562A06900F0004010B9C5F10700E2
+:101C5000A06108EB8801164A02EB810160698842A5
+:101C600001D1012000E00020F0B1201DFFF716FE99
+:101C700040B994F82C10012088400E49096881432E
+:101C80000C48016094F82C1001208840094909682B
+:101C9000084308490860E16A01EB8101044A02EB4C
+:101CA0008100211DFFF744FEBDE8F08714000020ED
+:101CB000B00700202C00002010B586B00020059051
+:101CC000049003AA04A905A8FFF7FCFD0022DDE9A2
+:101CD00004101346CDE9002102901CA11D48039A6F
+:101CE00000F0FEFD1C4908600846006808B10124A8
+:101CF00000E00024012C15D100BF502080F3118892
+:101D0000BFF34F8FBFF36F8F00BF4FF0FF3013490A
+:101D1000086001201249086000201249086000F0A4
+:101D200071F810E0601C08B1012000E0002050B9FB
+:101D300000BF502080F31188BFF34F8FBFF36F8F28
+:101D400000BF00BFFEE706B010BD000049444C458F
+:101D50000000000031B500084800002044000020C9
+:101D6000300000202800002002480068401C014983
+:101D7000086070474C0000201D48006818B1012021
+:101D80001C49086032E000201A4908601A480068BF
+:101D9000B0FA80F0C0F11F0101EB8100174A52F840
+:101DA000200008B1012000E0002050B900BF502001
+:101DB00080F31188BFF34F8FBFF36F8F00BF00BF59
+:101DC000FEE701EB81020D4B03EB82004268526893
+:101DD000426000F108024368934202D142685268AF
+:101DE00042604268D268064B1A6000BF704700002C
+:101DF0004C000020380000202C000020B0070020FC
+:101E0000140000201CB5524800685249884201D095
+:101E1000012000E0002050B900BF502080F311885D
+:101E2000BFF34F8FBFF36F8F00BF00BFFEE748487F
+:101E300000684849491E884201D0012000E0002086
+:101E400050B900BF502080F31188BFF34F8FBFF30C
+:101E50006F8F00BF00BFFEE73F4908460078019042
+:101E6000FF200A4610700846007800909DF8000098
+:101E700000F0F0009DF80020904201D1012000E028
+:101E8000002050B900BF502080F31188BFF34F8F5E
+:101E9000BFF36F8F00BF00BFFEE79DF8000000F0AA
+:101EA00050002E4A107007202D4A106009E02C487F
+:101EB0000068401E2A4A10609DF800004006000E8F
+:101EC00000909DF8000000F080008028EFD02448AA
+:101ED0000068C0F10700042801D1012000E00020C3
+:101EE00050B900BF502080F31188BFF34F8FBFF36C
+:101EF0006F8F00BF00BFFEE7194800680002184A54
+:101F000010601046008800F4E0601060124A0198EA
+:101F100010700F482030006840F470000C492031E8
+:101F200008600846006840F070400860FFF7A6FDB2
+:101F300000200C490860EEF757F90B48006840F0A4
+:101F4000404009490860EEF73BF900201CBD000045
+:101F500000ED00E071C20F4100E400E074000020D9
+:101F6000780000207000002034EF00E02DE9F041FF
+:101F700004460126002722460021012000F007F830
+:101F800005462846F9F7E8FA2846BDE8F0812DE92C
+:101F9000F84305460E4617460DB1012000E000202B
+:101FA00050B900BF502080F31188BFF34F8FBFF3AB
+:101FB0006F8F00BF00BFFEE705FB06F808F1480081
+:101FC000F9F7A0FD044664B1A14609F148090020D3
+:101FD00084F846003B464A46314628460094F9F7C5
+:101FE000CAFA2046BDE8F8832DE9F84380460E463C
+:101FF00017461D46DDF82090B8F1000F01D00120F2
+:1020000000E0002050B900BF502080F31188BFF3DA
+:102010004F8FBFF36F8F00BF00BFFEE70DB10120F0
+:1020200000E0002050B900BF502080F31188BFF3BA
+:102030004F8FBFF36F8F00BF00BFFEE707B10EB138
+:10204000012000E0002050B900BF502080F311882B
+:10205000BFF34F8FBFF36F8F00BF00BFFEE707B91D
+:102060000EB9012000E0002050B900BF502080F3DD
+:102070001188BFF34F8FBFF36F8F00BF00BFFEE724
+:10208000482000900098482801D1012000E000205D
+:1020900050B900BF502080F31188BFF34F8FBFF3BA
+:1020A0006F8F00BF00BFFEE700BF2C464CB1012080
+:1020B00084F846004B463A46314640460094F9F7CC
+:1020C0005AFA2046BDE8F88370B505460E462C4600
+:1020D00054B900BF502080F31188BFF34F8FBFF376
+:1020E0006F8F00BF00BFFEE7FFF72EFCD4E90F1291
+:1020F000206801FB0200A0600020A06320686060EF
+:10210000E06B401E226C216800FB0211E160FF20A1
+:1021100084F8440084F845009EB9206908B901207C
+:1021200000E00020A8B904F1100000F0BBFD80B170
+:102130004FF0805009490860BFF34F8FBFF36F8F96
+:1021400007E004F11000FFF7C9FB04F12400FFF7DA
+:10215000C5FBFFF723FC012070BD000004ED00E08B
+:102160002DE9FF4383B0064688461D464FF000091F
+:10217000344654B900BF502080F31188BFF34F8F0D
+:10218000BFF36F8F00BF00BFFEE7B8F1000F01D1B2
+:10219000206C08B9012000E0002050B900BF502099
+:1021A00080F31188BFF34F8FBFF36F8F00BF00BF65
+:1021B000FEE7022D02D1E06B012801D1012000E0F1
+:1021C000002050B900BF502080F31188BFF34F8F1B
+:1021D000BFF36F8F00BF00BFFEE700F0DFFB08B961
+:1021E000059808B9012000E0002050B900BF502038
+:1021F00080F31188BFF34F8FBFF36F8F00BF00BF15
+:10220000FEE700BFFFF7A0FBA06BE16B884201D3A4
+:10221000022D28D12A4641462046F9F7DAF807462A
+:10222000606A08B9012000E0002068B904F12400C8
+:1022300000F038FD88B14FF0805032490860BFF39C
+:102240004F8FBFF36F8F08E03FB14FF080502D49A3
+:102250000860BFF34F8FBFF36F8FFFF79FFB012025
+:1022600007B0BDE8F083059818B9FFF797FB002089
+:10227000F6E7B9F1000F04D101A8FFF77DFC4FF09C
+:102280000109FFF78BFBFFF76FFDFFF75DFB94F98B
+:102290004400401C10B9002084F8440094F9450023
+:1022A000401C10B9002084F84500FFF777FB05A912
+:1022B00001A800F09DFAF0B92046F9F73EFAA0B166
+:1022C00004F110000599FFF769FC2046F9F77EFA42
+:1022D00000F034FD002895D14FF080500949086086
+:1022E000BFF34F8FBFF36F8F8CE72046F9F76EFA7D
+:1022F00000F024FD86E72046F9F768FA00F01EFD9D
+:102300000020ADE704ED00E02DE9F84F07468A46CE
+:1023100090461E463C4654B900BF502080F31188B9
+:10232000BFF34F8FBFF36F8F00BF00BFFEE7BAF15F
+:10233000000F01D1206C08B9012000E0002050B945
+:1023400000BF502080F31188BFF34F8FBFF36F8F12
+:1023500000BF00BFFEE7022E02D1E06B012801D1D1
+:10236000012000E0002050B900BF502080F3118808
+:10237000BFF34F8FBFF36F8F00BF00BFFEE7FFF7C4
+:1023800091FB00BF5021EFF3118081F31188BFF35F
+:102390004F8FBFF36F8F00BF0546A06BE16B884284
+:1023A00001D3022E25D194F945B0A06B009032469E
+:1023B00051462046F9F70DF80BF1010088B9606A23
+:1023C00008B9012000E0002050B904F1240000F019
+:1023D00069FC28B1B8F1000F02D00120C8F8000054
+:1023E00004E00BF1010040B284F845004FF0010910
+:1023F00001E04FF0000900BF85F3118800BF484697
+:10240000BDE8F88F2DE9F74183B005460E464FF041
+:1024100000082C4654B900BF502080F31188BFF348
+:102420004F8FBFF36F8F00BF00BFFEE70EB9206C68
+:1024300008B9012000E0002050B900BF502080F30F
+:102440001188BFF34F8FBFF36F8F00BF00BFFEE750
+:1024500000F0A4FA08B9059808B9012000E00020AE
+:1024600050B900BF502080F31188BFF34F8FBFF3E6
+:102470006F8F00BF00BFFEE700BFFFF765FAA76BD5
+:10248000F7B131462046F8F78FFF781EA063206928
+:1024900008B9012000E0002060B904F1100000F04C
+:1024A00001FC38B14FF080502F490860BFF34F8FC7
+:1024B000BFF36F8FFFF772FA012006B0BDE8F0811D
+:1024C000059818B9FFF76AFA0020F6E7B8F1000F8F
+:1024D00004D101A8FFF750FB4FF00108FFF75EFAA7
+:1024E000FFF742FCFFF730FA94F94400401C10B9A2
+:1024F000002084F8440094F94500401C10B90020E5
+:1025000084F84500FFF74AFA05A901A800F070F920
+:10251000F0B92046F9F704F9A0B104F124000599B7
+:10252000FFF73CFB2046F9F751F900F007FC0028C3
+:10253000A3D14FF080500C490860BFF34F8FBFF319
+:102540006F8F9AE72046F9F741F900F0F7FB94E71F
+:102550002046F9F73BF900F0F1FB2046F9F7E0F8E7
+:1025600000288AD00020A8E704ED00E02DE9F05F04
+:10257000064689461746344654B900BF502080F3BA
+:102580001188BFF34F8FBFF36F8F00BF00BFFEE70F
+:10259000B9F1000F01D1206C08B9012000E0002042
+:1025A00050B900BF502080F31188BFF34F8FBFF3A5
+:1025B0006F8F00BF00BFFEE7FFF774FA00BF502126
+:1025C000EFF3118081F31188BFF34F8FBFF36F8F4B
+:1025D00000BF0546D4F838A0BAF1000F22D094F914
+:1025E00044B049462046F8F7DFFEAAF10100A06397
+:1025F0000BF1010070B9206908B9012000E000204A
+:1026000068B904F1100000F04DFB40B13FB101206A
+:10261000386004E00BF1010040B284F844004FF050
+:10262000010801E04FF0000800BF85F3118800BFEA
+:102630004046BDE8F09F00002DE9F34182B0054619
+:102640004FF000082C46002654B900BF502080F3FC
+:102650001188BFF34F8FBFF36F8F00BF00BFFEE73E
+:10266000206C08B9012000E0002050B900BF5020C4
+:1026700080F31188BFF34F8FBFF36F8F00BF00BF90
+:10268000FEE700F08BF908B9039808B9012000E0D3
+:10269000002050B900BF502080F31188BFF34F8F46
+:1026A000BFF36F8F00BF00BFFEE700BFFFF74CF91D
+:1026B000A76BFFB1781EA063206810B9F9F7C8FABC
+:1026C000A060206908B9012000E0002060B904F191
+:1026D000100000F0E7FA38B14FF08050434908602D
+:1026E000BFF34F8FBFF36F8FFFF758F9012004B08E
+:1026F000BDE8F081039898B90EB9012000E00020F0
+:1027000050B900BF502080F31188BFF34F8FBFF343
+:102710006F8F00BF00BFFEE7FFF740F90020E6E73C
+:10272000B8F1000F04D16846FFF726FA4FF0010810
+:10273000FFF734F9FFF718FBFFF706F994F94400A7
+:10274000401C10B9002084F8440094F94500401C56
+:1027500010B9002084F84500FFF720F903A9684666
+:1027600000F046F840BB2046F8F7DAFFF0B12068E9
+:1027700038B9FFF7E9F8A06800F038FA0646FFF725
+:102780000DF904F124000399FFF708FA2046F9F740
+:102790001DF800F0D3FA002888D14FF0805013497B
+:1027A0000860BFF34F8FBFF36F8F7FE72046F9F7C5
+:1027B0000DF800F0C3FA79E72046F9F707F800F0C2
+:1027C000BDFA2046F8F7ACFF0028EED05EB1FFF767
+:1027D000BBF82046F8F764FE07463946A068FFF7C5
+:1027E000F9F9FFF7DBF8002081E7000004ED00E0D5
+:1027F00070B505460C4655B900BF502080F31188CE
+:10280000BFF34F8FBFF36F8F00BF00BFFEE754B918
+:1028100000BF502080F31188BFF34F8FBFF36F8F3D
+:1028200000BF00BFFEE7FFF78FF812480268686834
+:10283000131A2068401C08B9002617E00E492868C2
+:102840000968884204D06868904201D801260DE0EA
+:102850002068984207D92068C01A20602846FFF7F0
+:102860008BF9002602E0002020600126FFF796F891
+:10287000304670BD280000203C0000202DE9FF4FAD
+:1028800085B0804689461746DDE912ABB800F9F7F6
+:1028900039F9064656B15420F9F734F904460CB11B
+:1028A000266304E03046FFF797F800E000248CB17F
+:1028B000002084F85100CDE900ABCDE902403A4652
+:1028C00049464046089BF8F769FE2046F8F7EEFCBB
+:1028D000012501E04FF0FF35284609B0BDE8F08F33
+:1028E0002DE9F04F85B00746884691469A46DDE9C6
+:1028F0000EB6109C0EB1012000E0002050B900BFC0
+:10290000502080F31188BFF34F8FBFF36F8F00BF4C
+:1029100000BFFEE70CB1012000E0002050B900BF6D
+:10292000502080F31188BFF34F8FBFF36F8F00BF2C
+:1029300000BFFEE7542003900398542801D10120E2
+:1029400000E0002050B900BF502080F31188BFF391
+:102950004F8FBFF36F8F00BF00BFFEE700BFB4B162
+:10296000AEB125462C462E63022085F8510000208A
+:1029700004A953464A46CDE900B1CDE9025041468B
+:102980003846F8F70BFE2846F8F790FC01E00020E7
+:102990000490049805B0BDE8F08F0000054909686F
+:1029A00009B9012005E00449096809B9022000E0DD
+:1029B00000207047300000204C00002001490868CA
+:1029C000704700002800002070B5FFF76BF8002565
+:1029D00001480468204670BD280000202DE9F04120
+:1029E0004FF000084448006800287CD14348006844
+:1029F000451C4248056015BB41480068006808B99D
+:102A0000012000E0002050B900BF502080F3118861
+:102A1000BFF34F8FBFF36F8F00BF00BFFEE7384893
+:102A20000768384800683649086036480760364805
+:102A30000068401C34490860F8F78EFE00BF334838
+:102A4000006885423CD300BF2D480068006808B983
+:102A5000012000E0002020B14FF0FF302B4908603A
+:102A60002DE027480068C068C4686668B54202D295
+:102A70002648066023E0201DFEF710FFA06A18B16B
+:102A800004F11800FEF70AFF94F82C10012088408A
+:102A90001F49096808431E490860E16A01EB81018A
+:102AA0001C4A02EB8100211DFEF742FF1A49E06A31
+:102AB0000968C96A8842C7D34FF00108C4E700BF5C
+:102AC00015480068C06A00EB8000124951F82000E8
+:102AD000012801D94FF001081048006808B14FF0F3
+:102AE000010805E0FFE70E480068401C0C4908603B
+:102AF0004046BDE8F08100004C0000202800002086
+:102B0000180000201C0000203C0000204400002091
+:102B10002C000020B0070020140000203800002006
+:102B20003400002070B505462C460026002D55D0F7
+:102B30002B480068844201D1012000E0002050B9F8
+:102B400000BF502080F31188BFF34F8FBFF36F8F0A
+:102B500000BF00BFFEE7A06C50B900BF502080F35B
+:102B60001188BFF34F8FBFF36F8F00BF00BFFEE729
+:102B7000A06C401EA064616CE06A88422ED0A06CFC
+:102B800060BB201DFEF78AFE78B9E06A00EB80008A
+:102B9000144951F8200040B994F82C1001208840C5
+:102BA00011490968814310480160606CE062E06A85
+:102BB000C0F10700A06194F82C10012088400A4958
+:102BC0000968084308490860E16A01EB8101054A88
+:102BD00002EB8100211DFEF7ABFE0126304670BDE1
+:102BE00014000020B00700202C00002070B505461E
+:102BF0002C460026002D4DD02749E06A0968C96A95
+:102C0000884240D2A06900F0004028B922480068FC
+:102C1000C06AC0F10700A061E16A01EB81011F4AAF
+:102C200002EB81016069884201D1012000E00020AF
+:102C300018B3201DFEF732FE40B994F82C10012085
+:102C400088401749096881431548016012480068A7
+:102C5000C06AE06294F82C1001208840104909688D
+:102C600008430F490860E16A01EB81010B4A02EB5E
+:102C70008100211DFEF75CFE03E007480068C06A82
+:102C8000E062012606E00449606C0968C96A88426E
+:102C900000D20126304670BD14000020B00700208D
+:102CA0002C00002070B50646F068C46854B900BF17
+:102CB000502080F31188BFF34F8FBFF36F8F00BF99
+:102CC00000BFFEE704F11800FEF7E8FD15480068B4
+:102CD000A8B9201DFEF7E2FD94F82C1001208840D1
+:102CE00011490968084310490860E16A01EB810154
+:102CF0000E4A02EB8100211DFEF71AFE04E004F1EA
+:102D000018010B48FEF714FE0A49E06A0968C96A0F
+:102D1000884204D9012501200749086000E0002508
+:102D2000284670BD4C0000202C000020B007002079
+:102D300064080020140000203800002070B5002432
+:102D400000263648006850B900BF502080F3118833
+:102D5000BFF34F8FBFF36F8F00BF00BFFEE7FEF7DB
+:102D6000F3FD2E480068401E2C49086008460068A4
+:102D700000284FD12A48006800284BD024E0294879
+:102D8000C068C46804F11800FEF788FD201DFEF736
+:102D900085FD94F82C1001208840234909680843D8
+:102DA00021490860E16A01EB8101204A02EB8100C0
+:102DB000211DFEF7BDFD1E49E06A0968C96A884207
+:102DC00002D301201B4908601648006808B9012099
+:102DD00000E000200028D2D00CB1F8F7BDFC164866
+:102DE000056865B100BFFFF7F9FD10B10120114979
+:102DF00008606D1E002DF6D100200F4908600D48B7
+:102E0000006838B1012630070C490860BFF34F8FC6
+:102E1000BFF36F8FFEF7C2FD304670BD4C0000203F
+:102E200024000020640800202C000020B0070020AF
+:102E300014000020380000203400002004ED00E0E1
+:102E4000D85D0108BB5C0008000000000000000025
+:102E500080000000000000000000000000061016C6
+:102E6000000610160000000000000000010203042C
+:102E700006070809000000000102030473676C5F85
+:102E80006F626A5F7365745F6469727479007367F7
+:102E90006C5F6F626A5F7365745F73697A65000067
+:102EA000FFFF000073676C5F6F626A5F7365745F3A
+:102EB00064697274790073676C5F6F626A5F7365CF
+:102EC000745F73697A6500005F050000E0FF000031
+:102ED00008FA000010FC0000F08700001F840000CA
+:102EE000F0FF0000FF87000014A500001FFC000099
+:102EF000FFFF0000FFFF0000FF07000000000000D0
+:102F0000000000000200F000F000000000000000DF
+:102F100000000000000000000000000000000300AE
+:102F200000000000000000000000000000000000A1
+:102F300000000000B4440020000000006009000010
+:102F4000F000F000F5DC00085F6C697374006C69D8
+:102F5000737420616C6C20636F6D6D616E64000032
+:102F60000010000000080000080000000800000039
+:102F700000800000004000007D590008D95A000878
+:102F8000555A0008E55A0008E95900080A000000EF
+:102F90000200000000000000000000006C65747476
+:102FA0006572000064656661756C74207573657286
+:102FB00000736574566172007365742076617200E7
+:102FC000757000646F776E007269676874006C6575
+:102FD000667400746162006261636B737061636543
+:102FE000006261636B73706163650064656C657436
+:102FF0006500656E74657200656E74657200686563
+:103000006C700073686F7720636F6D6D616E642004
+:10301000696E666F0D0A68656C70205B636D645D38
+:10302000007573657273006C69737420616C6C2039
+:103030007573657200636D6473006C6973742061ED
+:103040006C6C20636D640076617273006C697374DC
+:1030500020616C6C20766172006B657973006C691D
+:10306000737420616C6C206B657900636C656172B0
+:1030700000636C65617220636F6E736F6C65000036
+:1030800000112233445566778899AABBCCDDEEFF48
+:103090000055AAFF73676C5F6F626A5F6E6F64654D
+:1030A0005F696E69740073676C5F6F626A5F7365F6
+:1030B000745F64657374726F7965640073676C5FC5
+:1030C0006F626A5F69735F64657374726F79656458
+:1030D0000073676C5F6F626A5F7365745F646972C7
+:1030E00074790073676C5F6F626A5F636C656172AD
+:1030F0005F64697274790073676C5F6F626A5F699D
+:10310000735F64697274790073676C5F6F626A5F82
+:1031100069735F6E656564696E69740073676C5F7F
+:103120006F626A5F636C6561725F6E656564696E2C
+:1031300069740073676C5F6F626A5F69735F686967
+:103140006464656E0073676C5F6F626A5F67657465
+:103150005F66696C6C5F726563740073676C5F6156
+:103160007265615F696E69740073676C5F61726537
+:10317000615F69735F6F7665726C61700073676C15
+:103180005F617265615F73656C666D65726765002E
+:1031900073676C5F666F6E745F6765745F6865699F
+:1031A0006768740073676C5F66626465765F7265FA
+:1031B0006769737465720002010102020304010170
+:1031C0000202030473676C5F7069786D616C5F67FE
+:1031D00065745F62797465735F7065725F7069783A
+:1031E000656C0073676C5F6F626A5F6164645F63E4
+:1031F00068696C640073676C5F6F626A5F72656DAB
+:103200006F76650073676C5F6F626A5F6D6F76657E
+:103210005F6368696C645F706F730073676C5F6F86
+:10322000626A5F7365745F6162735F706F7300736E
+:10323000676C5F6F626A5F73697A655F7A6F6F6DE3
+:103240000073676C5F6F626A5F6D6F76655F757044
+:103250000073676C5F6F626A5F6D6F76655F646F46
+:10326000776E0073676C5F6F626A5F6D6F76655F24
+:10327000746F700073676C5F6F626A5F6D6F766505
+:103280005F626F74746F6D00FFFF73676C5F7363D1
+:103290007265656E5F6C6F61640073676C5F61720D
+:1032A00065615F636C69700073676C5F6172656113
+:1032B0005F73656C66636C69700073676C5F6469EB
+:1032C0007274795F617265615F70757368007367AE
+:1032D0006C5F6F626A5F696E69740073676C5F6FC1
+:1032E000626A5F667265650073676C5F6F626A5FD2
+:1032F000636C6561725F616C6C5F646972747900A4
+:1033000073676C5F666F6E745F6765745F7374720A
+:10331000696E675F77696474680073676C5F67657F
+:10332000745F616C69676E5F706F730073676C5F69
+:103330006765745F746578745F706F730073676C32
+:103340005F6765745F69636F6E5F706F730073674B
+:103350006C5F6F626A5F7365745F706F735F616CDF
+:1033600069676E0073676C5F6F626A5F7365745F35
+:10337000706F735F616C69676E5F7265660064721F
+:1033800061775F6F626A5F736C6963650073676C16
+:103390005F64697274795F617265615F63616C63B8
+:1033A000756C617465000000000000000000000002
+:1033B00000000000120000000000000000000000FB
+:1033C000000000000E00000073676C5F647261779C
+:1033D0005F7461736B0073676C5F616E696D5F72C0
+:1033E000656D6F76650073676C5F616E696D5F73A5
+:1033F000746172740073676C5F616E696D5F737482
+:103400006F700073676C5F616E696D5F64656C659A
+:1034100074650073676C5F616E696D5F7461736B77
+:103420000073676C5F6F626A5F6861735F6368698E
+:103430006C640073676C5F6F626A5F6861735F736F
+:1034400069626C696E670073676C5F6F626A5F695F
+:10345000735F68696464656E0073676C5F6F626A4E
+:103460005F69735F636C69636B61626C6500636C59
+:1034700069636B5F6465746563745F6F626A6563DB
+:10348000740073676C5F6576656E745F7461736BEF
+:10349000000000003C027804B306EE08280B610D22
+:1034A000990FD01106143A166C189D1ACB1CF71EF2
+:1034B000212148236C258E27AC29C72BDF2DF32F24
+:1034C0000332103418361C381C3A173C0E3EFF3FAE
+:1034D000EC41D443B64593476A493C4B084DCD4E29
+:1034E0008D504652F953A5554B57EA58825A135CF2
+:1034F0009C5D1F5F9A600D627963DD6439668D673C
+:10350000D9681D6A596B8C6CB76DD96EF36F0471F5
+:103510000C720B730174EE74D275AD767F774778B9
+:103520000679BB79677A0A7BA27B327CB77C337DD4
+:10353000A57D0D7E6C7EC07E0B7F4B7F827FAF7F33
+:10354000D27FEB7FFA7FFF7F00006ABB003C73A550
+:10355000D4002951769BBDDF001F3E5B7895B0CB30
+:10356000E60019324A627A91A8BED4EA00152A3ED2
+:1035700053677B8EA2B5C8DBED0012243647596A2B
+:103580007B8C9DAEBECFDFEF000F1F2F3F4E5D6DDA
+:103590007C8B9AA9B7C6D4E3F1000E1C2A38465397
+:1035A000616F7C8A97A4B2BFCCD9E6F3000C1926D0
+:1035B000323F4B5864707C8995A1ADB9C5D1DCE828
+:1035C000F4000B17222E3944505B66727D88939E5F
+:1035D000A9B4BFCAD5DFEAF5000A151F2A343F494E
+:1035E000545E68737D87919CA6B0BAC4CED8E2ECD5
+:1035F000F60009131D27303A444D57616A747D87E0
+:103600009099A3ACB6BFC8D1DBE4EDF60009121B5C
+:10361000242D363F48515A636C747D868F98A0A93B
+:10362000B2BBC3CCD5DDE6EEF700081119212A3272
+:103630003B434C545C656D757D868E969EA7AFB7F7
+:10364000BFC7CFD7DFE7EFF700070F171F272F37C9
+:103650003F474F575E666E767E858D959CA4ACB4D1
+:10366000BBC3CAD2DAE1E9F0F800070F161E252C19
+:10367000343B434A525960686F767E858C949BA296
+:10368000A9B1B8BFC6CDD5DCE3EAF1F800070E1545
+:103690001C232A31383F464D545B626970777E8522
+:1036A0008C9299A0A7AEB5BCC2C9D0D7DEE4EBF22C
+:1036B000F900060D141A21282E353C424950565D5A
+:1036C000646A71777E848B92989FA5ACB2B9BFC6AD
+:1036D000CCD3D9DFE6ECF3F900060C13191F262C26
+:1036E00032393F454C52585F656B71787E848A91C0
+:1036F000979DA3A9B0B6BCC2C8CFD5DBE1E7EDF377
+:10370000F900060C12181E242A30363C42484E544A
+:103710005A60666C72787E848A90969CA2A8ADB33B
+:10372000B9BFC5CBD1D7DCE2E8EEF4FA00050B1146
+:10373000171D22282E34393F454B50565C62676D69
+:1037400073787E84898F959AA0A6ABB1B7BCC2C8A6
+:10375000CDD3D8DEE4E9EFF4FA00050B10161B21F7
+:10376000262C31373C42474D52585D63686E737961
+:103770007E84898E94999FA4AAAFB4BABFC5CACFDC
+:10378000D5DADFE5EAEFF5FA00050A0F151A1F256D
+:103790002A2F353A3F444A4F545A5F64696E747910
+:1037A0007E83898E93989DA3A8ADB2B7BDC2C7CCC6
+:1037B000D1D6DCE1E6EBF0F5FA00050A0F14191E8C
+:1037C00023282D32383D42474C51565B60656A6F65
+:1037D00074797E83888D92979CA1A6ABB0B5BABF51
+:1037E000C4C9CED3D8DDE2E7ECF1F6FB0004090E44
+:1037F00013181D22272C31353A3F44494E53585C4B
+:1038000061666B7075797E83888D92969BA0A5AA60
+:10381000AEB3B8BDC2C6CBD0D5D9DEE3E8EDF1F684
+:10382000FB0004090E12171C21252A2F33383D42B4
+:10383000464B5054595E62676C70757A7E83888CF3
+:1038400091969A9FA3A8ADB1B6BBBFC4C8CDD2D63E
+:10385000DBDFE4E9EDF2F6FB0004090D12161B1F95
+:1038600024292D32363B3F44484D51565A5F6368F8
+:103870006C71757A7E83878C9095999EA2A7ABB068
+:10388000B4B9BDC1C6CACFD3D8DCE1E5E9EEF2F7E1
+:10389000FB0004080D11161A1E23272C3034393D65
+:1038A00041464A4F53575C6064696D71767A7E83F6
+:1038B000878B9094989DA1A5AAAEB2B7BBBFC4C890
+:1038C000CCD0D5D9DDE2E6EAEEF3F7FB0004080C34
+:1038D0001115191D22262A2E33373B3F43484C50E1
+:1038E00054595D6165696E72767A7E83878B8F939A
+:1038F000989CA0A4A8ACB1B5B9BDC1C5CACED2D65A
+:10390000DADEE3E7EBEFF3F7FB0004080C10141822
+:103910001C2025292D3135393D4145494E52565AF5
+:103920005E62666A6E72767A7E83878B8F93979BD0
+:103930009FA3A7ABAFB3B7BBBFC3C7CBCFD3D7DBB7
+:10394000DFE3E7EBEFF3F7FB000001010202020304
+:103950000303030404040404050505050505060620
+:103960000606060606070707070000000000080213
+:1039700000020208020608080608080E000C060EDF
+:103980000900110209020B0E0B0C110E0F06110C8F
+:103990000D060F081200140E140C1A0E73676C5FDC
+:1039A0006F626A5F7365745F6469727479007367CC
+:1039B0006C5F6F626A5F7365745F73697A650073C9
+:1039C000676C5F6F626A5F6765745F77696474686C
+:1039D0000073676C5F6F626A5F6765745F686569D3
+:1039E0006768740073676C5F6F626A5F7365745FAA
+:1039F000626F726465725F77696474680073676C84
+:103A00005F616E696D5F7365745F6461746100739B
+:103A1000676C5F616E696D5F7365745F7061746818
+:103A20000073676C5F616E696D5F7365745F73745B
+:103A30006172745F76616C75650073676C5F616E4F
+:103A4000696D5F7365745F656E645F76616C7565E3
+:103A50000073676C5F616E696D5F7365745F61634E
+:103A6000745F6475726174696F6E0073676C5F6117
+:103A70006E696D5F69735F66696E6973686564001E
+:103A800000F800001F000000E00700001F00000019
+:103A90001F0000001F0073676C5F7069786D6170B4
+:103AA0005F6765745F6275660000000000008EC08D
+:103AB00000000000AFE000000000AFE000000000E8
+:103AC0008EC0000000005EC0000000003EA00000AC
+:103AD00000003C80000000003C80000000000C80E2
+:103AE000000000000A50000000000A500000000022
+:103AF0000000000000000000000000008EC0000078
+:103B00000000CFE5000000008EC000000003EE586A
+:103B1000EC00000AFE5EFE00003EE88EE30000AE10
+:103B200080EE300003EA08C5000008A00A5000003B
+:103B3000000CA000AC00000A8000AC00000C80006B
+:103B4000CA00033C8333CA308EFFFFFFFFE85AAC44
+:103B5000CAAAECA5005A3000A500005A3003A500FF
+:103B6000008C0005A300008C0005A3008CEECCCED9
+:103B7000FCC88EFFFFFFFFE800CA000AC00000CAB1
+:103B8000000AC00000A8000AC00000C8000CA00085
+:103B900000000880000000000AC000000003CFFE03
+:103BA000A000005ECAC8EC0000EE0AC3EE3003ECD1
+:103BB0000AC8EC0003EE3AC0000000AFEAC0000003
+:103BC000000CFFC000000000AEFC000000000AFF77
+:103BD000C00000000ACEFA0000000AC3EE3005EE75
+:103BE0000AC0AE500AFE3AC0AE5008EA0AC0CE3053
+:103BF00000EE5AC8C800000AEFFC500000000AC0DE
+:103C0000000000000AC000000000035000000AEE9F
+:103C10005000AA008C5AE3038300CE05C80AA00016
+:103C2000EC03EA0A5000EC03EA8A0000EC03EAC85D
+:103C30000000CE05C8A300008C5AEAAAEE800AEE66
+:103C40008A6C8AE300008AAE05C80000A5EC03EA8E
+:103C50000005A0EC03EA000A80EC03EA003830CE4D
+:103C600005C800AA005A5AE303A5000AEE80003CEA
+:103C7000FEA0000000CE38C8000003EA05EA0000FC
+:103C800005C805EA000003EA08C5000003EC0CC003
+:103C9000000000CEAA00000000CFA05EFFC00CAE66
+:103CA000E003EA008C3CE803A500CE05EE05A00089
+:103CB000EE00AFAAA000EE303EEA5000CE5005EE76
+:103CC00030333EE508CEE3AA03CFEC35EFC308EE70
+:103CD000500000000AFFA000000000AEA00000009D
+:103CE000005C8000000000CC000000000AA0000082
+:103CF0000000000000000AA0000000008C3000005E
+:103D00000005A5000000000EC000000000AE30005D
+:103D1000000003EC0000000008C8000000000CE3F5
+:103D2000000000000EE0000000003EE00000000087
+:103D30003EC0000000003EE0000000000EE0000079
+:103D400000000CE30000000008C80000000003ECC5
+:103D50000000000000AE30000000003EA0000000A7
+:103D60000005A500000000008C30000000000AA043
+:103D70000A800000000003C800000000008C500012
+:103D80000000000CE00000000005C800000000007A
+:103D9000CE00000000008C80000000005EA000004B
+:103DA00000003EE0000000000EE0000000000EE019
+:103DB000000000000EE0000000003EE000000000F7
+:103DC0005EA0000000008C8000000000CE0000001B
+:103DD0000005EA000000000CE0000000008C50002C
+:103DE000000003C8000000000A800000000000007E
+:103DF0003EE3000000003EE3000000003EE0000063
+:103E00003EE50EC08EE00AEE5CAAFEA00005A8AA60
+:103E100050000005AAAA50000AEEAAAAFEA05EE57C
+:103E20000EC08EE300003EE0000000005EE30000F4
+:103E300000005EE0000000000AC0000000000AC0B0
+:103E4000000000000AC0000000000AC000000000DE
+:103E50000AC000003EFFFFFFFFE500000AC00000AF
+:103E600000000AC0000000000AC0000000000AC0F4
+:103E7000000000000AC0000008EE500000000AFF29
+:103E8000A000000000AFA0000000005C8000000067
+:103E900000CC000000000AA000000000AFFFFFFF00
+:103EA000FFE008EE300000000CFE8000000008EE8D
+:103EB00030000000000000000383000000000AC082
+:103EC000000000003A5000000000AC0000000003B9
+:103ED000A50000000008C0000000000A500000001B
+:103EE000008C0000000000A50000000008C00000D9
+:103EF00000000C80000000008C0000000000C800E2
+:103F000000000008C0000000000A80000000008CD3
+:103F10000000000000C80000000008A00000000031
+:103F20000C80000000005A00000000000005CFFCDB
+:103F30003000005EE33EE50000EE5003EE0008ECCA
+:103F40000000CE500CE80000AFA00EE500008EC0CF
+:103F50003EE300005EE03EE300005EE03EE3000082
+:103F60005EE03EE300005EE00EE500008EC00CE87F
+:103F70000000AFA008EC0000CE5000EE5005EC00B1
+:103F8000005EE33EE3000005CFFC30000000038349
+:103F90000000005ACFE3000000368EE3000000006E
+:103FA0000EE3000000000EE3000000000EE300003E
+:103FB00000000EE3000000000EE3000000000EE32E
+:103FC000000000000EE3000000000EE3000000000F
+:103FD0000EE3000000000EE3000000000EE300000E
+:103FE00000005EE80000008EFFFFFC00000AEFFE0C
+:103FF000A00000CC500AEE000AE50000CE800CE5DF
+:1040000000008EA00CFC00008EA003630000AE80B8
+:1040100000000003EE000000000AE3000000008C36
+:104020003000000008C3000000008C3000000008D1
+:10403000C3000000008C300008A005A500000CA003
+:104040003EC66666CE803EFFFFFFFE50003AEFFCA4
+:10405000500000CC305EE50008C80005EE0008EC1A
+:104060000000EE3000530000EE0000000005EA0002
+:104070000000005CA0000000AFFC30000000003C2D
+:10408000E80000000000EE30000000008EA00053A9
+:1040900000008EC00CFC00008EA00CFA0000CE5078
+:1040A00003EC303CFA00003CEFFC50000000000E36
+:1040B000C000000000AFC000000005EFC00000001D
+:1040C0000ECEC0000000CE5EC0000008C55EC0007D
+:1040D000003C805EC00000CC005EC00008C0005EF6
+:1040E000C0003A50005EC0008EFFFFFFFFE50000F9
+:1040F000005EC0000000005EC0000000005EC00066
+:104100000000008EE3000000AFFFFFE000CFFFFFE4
+:10411000FE8000AA6666653000A80000000000C8A6
+:104120000000000000A50000000000A50000000045
+:1041300003A5CFFEA00003AA8008EC0000A80000A1
+:10414000CE50000000008EA0000000005EC008CA33
+:1041500000005EC00CFC00008EA00AE50000CE50FE
+:1041600003EC303CFA00003AEFFE80000000AEFFA6
+:10417000C300000CE505EE0000CE3005EE3005EA88
+:10418000000033000AE8000000000EE50000000017
+:104190000EE3AEFFC3003EECC305EE303EFC000074
+:1041A0008EA03EE300003EE03EE300003EE00EE570
+:1041B00000003EE00AFA00003EC005EE30008C80B0
+:1041C00000AEE305EC000005CFFEA00005EFFFFF09
+:1041D000FFE008EC66668C800AC00000AC000A8034
+:1041E0000003A5000000000AA0000000003A5000F3
+:1041F000000000AC0000000003C8000000000AE35B
+:10420000000000000EC0000000005EA000000000E2
+:10421000AE8000000000CE8000000000EFA0000093
+:104220000003EFA000000000CE800000003AEFFE87
+:10423000A00000EE5008EC000AE50000AE800CE0A3
+:1042400000005EA00CE300005C8008EE3000AE30A1
+:1042500000AEE805A5000008EFFE300000AC35CF49
+:10426000E30008C5000AEE300EC00000AFA03EA07B
+:1042700000003EC03EA000003EC00EE300008C8067
+:1042800003EE5008EC00003AEFFE8000003AEFFC2D
+:10429000500000EE503CE8000AE80000EE300EE36B
+:1042A0000000AE803EE000008EC03EE000008EC008
+:1042B0003EE00000AFE00EE50003EFE008EE505CEA
+:1042C0008EE0005CFFE8AFC000000000CFA000005F
+:1042D0000000EE5000300005EE0005EE300CE80066
+:1042E00005EE33CFA000005EFFE500000000AEC089
+:1042F00000000000EFE300000000AEC0000000007E
+:1043000000000000000000000000000000000000AD
+:104310000000000000000000000000000000AEC02F
+:1043200000000000EFE300000000AEC0000000004D
+:104330008EE3000000008CC30000000000000000BD
+:10434000000000000000000000000000000000006D
+:10435000000000000000000000000000000000005D
+:104360008CC3000000008EE3000000000CC00000C1
+:1043700000005A500000000000005A300000000504
+:10438000A5000000005A5000000005A50000000034
+:104390005A5000000005A5000000005A500000001F
+:1043A00005A50000000005A500000000005A50000F
+:1043B00000000005A500000000005A5000000000A9
+:1043C00005A500000000005A500000000005A500EF
+:1043D000000000005A30AFFFFFFFFFE000000000C8
+:1043E0000000000000000000000000000000AFFF1F
+:1043F000FFFFFFE00AC00000000000CC000000004A
+:10440000000CC00000000000CC00000000000CC048
+:104410000000000000CC00000000000CC000000004
+:104420000000CC0000000000CC000000000CC00028
+:10443000000000CC000000000CC000000000CC0018
+:104440000000000CC000000000CC000000000AC00A
+:10445000000000000008EFFEA30000CC3005EE30A5
+:104460000AC000008EC00EA000005EE00EEA000050
+:104470005EE00CFC0000AFA00000000ACA000000D3
+:1044800003EC500000000CA0000000000C800000B5
+:1044900000000C8000000000000000000000000090
+:1044A000000000008EC000000000CFE5000000000A
+:1044B0008EC000000000AEFFC300003EE503AC501C
+:1044C00000CC30000AC008C505EEEAC80CE03EC5C5
+:1044D000C8CA3EC0CE05A5AA3EA3EA08C3AC5EA8E2
+:1044E000C50AE0AA5EAAE30CE0CA5EACE33EC3A53F
+:1044F0003EAAE3CFAAC00CE0CFCAEC3008C500004A
+:1045000000A800EC00000AC0005EC303CC3000032A
+:10451000CFFEA300000008A0000000005EE5000040
+:104520000000AEE800000000CAEC00000003A5EEA9
+:1045300000000008C0EE5000000AC0AE8000000C71
+:10454000805EC000003A503EE000008C000CE500A8
+:1045500000CFFFFFFA0000C80008EC0005A300032D
+:10456000EE300AC00000CE500EC00000AFA0EFFC3D
+:10457000000AFFFCAFFFFFFEC50005EC0008EE508F
+:1045800005EC00008EA005EC00008EA005EC0000FC
+:10459000AE8005EC000ACA0005EFFFFE800005ECC6
+:1045A0000005EC3005EC00005EC005EC00000EE5F7
+:1045B00005EC00000CE805EC00000EE505EC000041
+:1045C0005EE305EC0005EE80CFFFFFFEC5000003B3
+:1045D000AEFFEAA0005EE503AEE003EE30000AE3C2
+:1045E0000AFA000003A53EE3000000535EE000006D
+:1045F00000008EC0000000008EC0000000008EC0D1
+:10460000000000005EE0000000003EE30000003318
+:104610000EE80000008508EC00000AC000AFC303EC
+:10462000AC300005CFFEA300AFFFFFEA300005EC81
+:10463000005EE80005EC0003EE5005EC00008EC0C3
+:1046400005EC00003EE305EC00000EE505EC000083
+:104650000EE805EC00000CE805EC00000EE505ECAA
+:1046600000000EE505EC00003EE005EC00008EC009
+:1046700005EC0003EE3005EC008EE500CFFFFFEA0D
+:1046800030008EFFFFFFFE8003EE0000AEC003EEA1
+:10469000000008C003EE0000305303EE000380006A
+:1046A00003EE000AE00003EFFFFFE00003EE000A64
+:1046B000E00003EE0005A00003EE0000300003EE72
+:1046C0000000000003EE0000008803EE000005A3D8
+:1046D00003EE00008EE08EFFFFFFFFA08EFFFFFFC6
+:1046E000FFC003EE00005EE303EE000003C803EE2C
+:1046F0000000008803EE0000000003EE00008500CB
+:1047000003EE0005A50003EFFFFFE50003EE000543
+:10471000A50003EE0000A50003EE0000530003EE29
+:104720000000000003EE0000000003EE00000000A7
+:10473000AFFFE50000000005CFFC8800008EC30835
+:10474000EE0005EE0000AE300CE500003A503EE011
+:10475000000005308EC000000000AFA00000000087
+:10476000AFA000000000AFA0005AAAA88EC0003879
+:10477000EFC55EE00000CE500EE50000CE5008EC24
+:104780000000CE5000CFA005EE500008EFFE8000E4
+:10479000AFFFA00CFFFA0AFA0000AE800AE80000A2
+:1047A000AE800AE80000AE800AE80000AE800AE8A9
+:1047B0000000AE800AE80000AE800AFFFFFFFE8026
+:1047C0000AE80000AE800AE80000AE800AE80000B7
+:1047D000AE800AE80000AE800AE80000AE800AE879
+:1047E0000000AE80CFFFC00CFFFC00CFFFFFFE003B
+:1047F00000000EE3000000000EE3000000000EE3E6
+:10480000000000000EE3000000000EE300000000C6
+:104810000EE3000000000EE3000000000EE30000C5
+:1048200000000EE3000000000EE3000000000EE3B5
+:10483000000000000EE3000000000EE3000000CFC7
+:10484000FFFFFE000008EFFFFFFA0000008EA0004F
+:104850000000008EA0000000008EA0000000008E6E
+:10486000A0000000008EA0000000008EA00000004C
+:10487000008EA0000000008EA0000000008EA000AE
+:104880000000008EA0000000008EA0000000008E3E
+:10489000A0000000008EA0000000008EA0005EE0DE
+:1048A00000CE50008EE008EC00000AEFFC80000013
+:1048B000AFFFE35EFFE505EC0003EC3005EC000C18
+:1048C000C00005EC00CC000005EC0AC3000005ECBC
+:1048D0008C50000005ECEFC0000005EFAEE50000D5
+:1048E00005EE08EC000005EC00CE800005EC005E53
+:1048F000E00005EC000CE80005EC0003EE0005EC20
+:104900000000CFA0AFFFE30AFFFC5EFFFA0000004B
+:1049100000EE3000000000EE3000000000EE30003D
+:10492000000000EE3000000000EE3000000000EE5D
+:104930003000000000EE3000000000EE300000000B
+:1049400000EE3000000000EE3000000000EE30000D
+:1049500000A800EE300005A500EE30005EE08EFFFE
+:10496000FFFFFFC0EFE50000CFFE0CFA0000EFC034
+:104970000CFC0005EFC00AEE0008CEC008CE500CBB
+:10498000CEC008AE800C8EC0086EC05A6EC0085EE5
+:10499000E08C5EC0085CE3AA5EC0085AE8C85EC04E
+:1049A0000855EA835EC00853EFC05EC00850CFA030
+:1049B0005EC00A50AE505EC0EFE85A0AFFFECFFA62
+:1049C0000003EFFE08EE30000AA008AFC000088028
+:1049D000088EE50008800888EE0008800880EE80D8
+:1049E000088008805EE0088008800CFA0880088053
+:1049F00005EE3880088000AFA8800880003EE8807F
+:104A00000880000AFC8008800000EE8008A00000FA
+:104A10008C80EFFE30000C800005CFFE8000008E01
+:104A2000C308EA0005EE0000AE800CE800003EE09E
+:104A30003EE300000EE55EE000000CE85EE00000F2
+:104A40000AFA8EC000000AFA5EE000000AFA5EE090
+:104A500000000CE80EE300000EE50AE800003EE06E
+:104A600003EE0000AE80008EC308EA000005CFFE12
+:104A700080008EFFFFFEC50003EE0003CE8003EE34
+:104A800000000EE303EE00000CE503EE00000CE571
+:104A900003EE00003EE303EE0005CE8003EFFFFFD0
+:104AA000C50003EE0000000003EE0000000003EE6E
+:104AB0000000000003EE0000000003EE0000000014
+:104AC00003EE00000000AFFFE50000000008EFFE6D
+:104AD000500000AFA00AEA0008EC0000AE500CE560
+:104AE00000005EC03EE300000EE35EE000000EE565
+:104AF0008EC000000CE88EC000000CE88EC00000E4
+:104B00000CE85EC000000CE53EE8EFC00EE50EECE0
+:104B100085EA3EE008EE00CE8C8000AFA08EFC005F
+:104B20000005EFFFE0300000000EEAA000000005E5
+:104B3000EE808EFFFFFEC30003EE0008EE5003EE92
+:104B400000008EC003EE00005EE003EE00005EC0D9
+:104B500003EE00008EA003EE0008EE0003EFFFFE60
+:104B6000A00003EE05EC000003EE00CE800003EE93
+:104B7000005EE00003EE000CE80003EE0008EE002B
+:104B800003EE0000EE808EFFE5008EFC003CEFFCA3
+:104B90008A0003CA303CFE000CE00000AE300EC0BC
+:104BA00000003A500EE0000000000AFE5000000035
+:104BB000008EFEA3000000008EFEA0000000005C3E
+:104BC000FC0000000000CE805A0000003EC03C8087
+:104BD00000000EC00EE300005C800CFE5005CC000F
+:104BE00008A8EFFEA0000CFFFFFFFFA00EC33EE0F1
+:104BF0003CC03A503EE005A358003EE00083000070
+:104C00003EE0000000003EE0000000003EE000004A
+:104C100000003EE0000000003EE0000000003EE03A
+:104C2000000000003EE0000000003EE00000000048
+:104C30003EE0000000003EE00000000CFFFFA0008E
+:104C4000CFFFC003EFFA0AE800000A500AE80000AC
+:104C500008500AE8000008500AE8000008500AE876
+:104C6000000008500AE8000008500AE80000085058
+:104C70000AE8000008500AE8000008500AE80000AE
+:104C800008500AE80000085008EA0000383000EE3A
+:104C90008005CA00003AEFFC5000EFFFA005EFFAD4
+:104CA0000AFA00003A5005EC00005A0003EE00003A
+:104CB000AA0000CE5000A500008EA005A300005E53
+:104CC000C008A000000EE30A8000000AE8383000A7
+:104CD0000008EA8A00000003EEAA00000000EEA52A
+:104CE00000000000AFE0000000005EA00000000037
+:104CF0003A500000EFFCCFFE5EFE3EC00CE305A381
+:104D00003EC00CE308A00CE00AE50AA00AE30CE8A8
+:104D10000A8008C50EFA0A5005C83AEC383003EA92
+:104D20008AEE580000ECAACE8A0000CEA8AEA800F9
+:104D300000AEA58CC500008EE05EE300005EC03EC4
+:104D4000E000003EA00EC000000A500A80008EFF66
+:104D5000E00CFFE503EE0000AE3000AE8000A500E1
+:104D6000003EE00AA000000AE83830000003EEAA86
+:104D7000000000008EE3000000003EE5000000009F
+:104D80008CEC00000000C8EE50000008C08EC0008F
+:104D9000000A500EE500008C0005EC0003C800007E
+:104DA000CE80AFFE800CFFFCAFFFE00AFFE808EC0E
+:104DB00000008C5000EE3000AA00008EA005A30079
+:104DC000003EE00CC000000AE85A50000005EECE9C
+:104DD00000000000CFE8000000008EE300000000AB
+:104DE0003EE0000000003EE0000000003EE0000069
+:104DF00000003EE0000000003EE00000000CFFFF6D
+:104E0000A00003EFFFFFFFE008EE50008C800CE0F5
+:104E10000000EC000530000AE3000000003EA000A6
+:104E2000000000CE0000000008C8000000000EC016
+:104E300000000000AE3000000003EA000000000C9B
+:104E4000E0000000008C8000038300EC00000CC038
+:104E50000AE30003CFA03EFFFFFFFE500000CFFF9C
+:104E6000FE300000CA0000000000CA000000000080
+:104E7000CA0000000000CA0000000000CA000000D4
+:104E80000000CA0000000000CA0000000000CA00C4
+:104E900000000000CA0000000000CA00000000007E
+:104EA000CA0000000000CA0000000000CA000000A4
+:104EB0000000CA0000000000CA0000000000CA0094
+:104EC00000000000CA0000000000CA00000000004E
+:104ED000CFFFFE3008C50000000000EA000000001F
+:104EE000008C30000000003EA0000000000AE0003E
+:104EF00000000005C80000000000CC000000000019
+:104F00008C50000000000EA0000000000AE300002A
+:104F1000000003C80000000000AE00000000005CBC
+:104F200080000000000CC00000000008C500000068
+:104F30000000EA0000000000AE30000000003C80ED
+:104F4000000000000AE00CFFFFE50000000005A5DE
+:104F50000000000005A50000000005A500000000FD
+:104F600005A50000000005A50000000005A5000043
+:104F7000000005A50000000005A50000000005A533
+:104F80000000000005A50000000005A500000000CD
+:104F900005A50000000005A50000000005A5000013
+:104FA000000005A50000000005A50000000005A503
+:104FB0000000000005A500000CFFFFE50000000058
+:104FC000EFE80000000AEACE3000005A3008A000E6
+:104FD000EFFFFFFFFFFC03AEE500000000005A807A
+:104FE0000000005CEFFEA00008EC3008EA000AFABE
+:104FF0000000EC0000000035EC00003AEFCAEC00C5
+:1050000005EE5000EC000EE30000EC005EE0000056
+:10501000EC000EE8005AEC8803CEFFC5AEE5038530
+:1050200000000000AEE80000000005C8000000001D
+:1050300005C80000000005C80000000005C8000009
+:10504000000005C85EFFC30005CAC305EE3005EECB
+:1050500030008EA005EA00005EC005C800003EE0FA
+:1050600005C800003EE005C800005EC005EA00007B
+:10507000AE8005CC8005EC0005A3CFFEA0000005A6
+:10508000CFFEA300008EC305EC0005EE0003EE305A
+:105090000AE8000033000CE5000000000CE5000009
+:1050A00000000AE80000003005EC00000A8000AFB4
+:1050B000C303CC000008CFFEA3000000000358305B
+:1050C0000000003CFE3000000000AE300000000098
+:1050D000AE3000000000AE3000000000AE3000082E
+:1050E000EFFCAE3000AFA00AEE3005EC0000AE30B1
+:1050F0000AE80000AE300CE50000AE300CE5000020
+:10510000AE300AE50000AE3008EA0000EE3000CE16
+:10511000803AAFC5000AEFEAAC830005CFFEA000DD
+:10512000008CA005EC0003EA00008C800AE500007A
+:105130005EC00CFFFFFFFFC00CE5000000000AE8A6
+:105140000000000005EC00000A8000AEC303CC00A4
+:105150000005CFFEA000000005CFFEA000008CA03F
+:105160000AFA0000EE0005850000EC0000000000D7
+:10517000EC0000000CFFFFFFFC000000EC00000052
+:105180000000EC0000000000EC0000000000EC005B
+:1051900000000000EC0000000000EC000000000037
+:1051A000EC0000000000EC00000005EFFFFFC00075
+:1051B000000AEFFC8EE800CE503CE88505EA0003CB
+:1051C000EC0005EA0003EC0000CE500AE500005CAC
+:1051D000EFFC500003C80000000003EEA6330000FF
+:1051E000008CCCEFFC300AC000003EC00EC00000B6
+:1051F0000EC00AEA3003AC80005CFFFEC50003AAC3
+:1052000000000000AEFA0000000003EA0000000009
+:1052100003EA0000000003EA0000000003EA0000C7
+:10522000000003EA5EFFC30003EAC503EE0003EEDD
+:105230000000AE3003EA0000AE3003EA0000AE30FA
+:1052400003EA0000AE3003EA0000AE3003EA0000DB
+:10525000AE3003EA0000AE308EFFE00EFFE8000043
+:105260003EE5000000003EE50000000000000000F8
+:1052700000000000000000000350000000AFEFE05D
+:10528000000000000EE0000000000EE00000000042
+:105290000EE0000000000EE0000000000EE0000044
+:1052A00000000EE0000000000EE0000000000EE034
+:1052B000000000AFFFFFFA000000000CFC0000003F
+:1052C000000CFC00000000000000000000000000D6
+:1052D00000000003550000000EEEE800000000058D
+:1052E000C80000000005C80000000005C80000005C
+:1052F0000005C80000000005C80000000005C80047
+:1053000000000005C80000000005C80000000005FE
+:10531000C80000300008C50005EE305CA00000AEFB
+:10532000FFC5000003AA000000008EFC0000000082
+:1053300003EC0000000003EC0000000003EC0000A0
+:10534000000003EC0000000003EC00CFFFC003EC02
+:10535000000CC30003EC00CC000003EC0CC0000008
+:1053600003ECCFE3000003EE88EE000003EC00AF97
+:10537000A00003EC000CE80003EC0003EE305EFF3D
+:10538000E00EFFFA00035CC0000000ACCFE00000BC
+:1053900000000EE0000000000EE0000000000EE043
+:1053A000000000000EE0000000000EE00000000021
+:1053B0000EE0000000000EE0000000000EE0000023
+:1053C00000000EE0000000000EE0000000000EE013
+:1053D000000000000EE0000000000EE0000000CF22
+:1053E000FFFFFC00033000000000CFCCFE8AEFC0BE
+:1053F0000EE80EEA0AE50EC00CE30AE50EC00CE367
+:105400000AE50EC00CE30AE50EC00CE30AE50EC087
+:105410000CE30AE50EC00CE30AE50EC00CE30AE556
+:10542000EFFCCFFE8EFE3ACA5CFFC30038EAC5032C
+:10543000EE0003EE3000AE3003EA0000AE3003EAC7
+:105440000000AE3003EA0000AE3003EA0000AE30E8
+:1054500003EA0000AE3003EA0000AE308EFFE00E3B
+:10546000FFE80008EFFE800000CEA00AEC0008EA8A
+:105470000000AE800EE300003EE03EE000000EE3E0
+:105480003EE000000EE30EE300003EE008C800002E
+:105490008EA000CE8008EC000008EFFE80008ACAD3
+:1054A0008EFEC3003AEAC505EE5003EE00005EC072
+:1054B00003EA00000EE003EA00000EE303EA000046
+:1054C0000EE303EA00003EE003EC00008EA003ECD4
+:1054D000A008EE0003EAAEFEA00003EA0000000010
+:1054E00003EA00000000AFFFE30000000008EFEA5D
+:1054F000383000CEA00ACE3008EA0000CE300CE5ED
+:105500000000CE300EE30000CE300EE30000CE30BF
+:105510000EE30000CE300AE80000CE3000EE503A34
+:10552000EE30003AEFEACE3000000000CE3000004E
+:105530000000CE300000005EFFE83AACE03CFFC067
+:10554000356EE5A83EE3000CE8300330000CE500C2
+:105550000000000CE0000000000CE0000000000C67
+:10556000E0000000000CE0000000000CE000000083
+:105570008EFFFFFC0000000AEFFEAC0000CE5008DA
+:10558000EE0000EA00008C3000CE50000530003AFA
+:10559000EEC50000000005CEE80008A00000AE50F7
+:1055A00005A500003C8005EE5003AE3003CAEFFFB6
+:1055B000C50000005800000000008A000000000044
+:1055C000CC0000000008EC0000000AFFFFFFFC0018
+:1055D0000000EC0000000000EC0000000000EC0007
+:1055E00000000000EC0000000000EC0000000000E3
+:1055F000EC0000000000EE0008800000AE505A30C1
+:1056000000000CFFE500008800003830AFE8003EE5
+:10561000FE3005C80000CE3005C80000CE3005C8F9
+:105620000000CE3005C80000CE3005C80000CE30E6
+:1056300005C80000CE3005EA0000EE3000EE503C18
+:10564000CFC5005EFFE8CC838EFFE008EFE503EEF8
+:1056500000008C3000CE3000A800005EA005A30042
+:10566000000EE30CA000000AFA5A50000003EEAC52
+:1056700000000000CFE8000000005EE00000000035
+:105680000EA00000EFFAEFFA8EFE3EC00EE008C357
+:105690000CE00CE30AA00AE50EE80A5005C85AEC33
+:1056A0005A0000ECACEECC0000CEC8AEC800008EB4
+:1056B000E38EE300003EC03EC000000C800CA00062
+:1056C0000EFFFC5EFFE0005EE003A500000AE80AB2
+:1056D000A0000000CEAA000000003EE30000000091
+:1056E0003CEA00000000A5AE8000000A800EE30046
+:1056F00000AC0005EC308EFFC08EFFE55EFFE53E9E
+:10570000FFE800CE5000CC30005C8003A500000E06
+:10571000E008C0000008C50CA0000003EC5A5000CF
+:105720000000AEAC000000005EE8000000000CE3EA
+:10573000000000000AA0000000003A5000000385AD
+:10574000AA00000008EFC000000005EFFFFFFE30D8
+:1057500008EA0008EA0008C0005EC000088003EE06
+:10576000000000000EE300000000CE500000000A20
+:10577000E8000AA0008EA0000C8005EC0003CE50CB
+:105780000CFFFFFFFE3000000003CE800000000C85
+:10579000C3000000003A50000000003A5000000032
+:1057A000003A50000000003A50000000003A50005B
+:1057B0000000003A50000000005A3000000003CC06
+:1057C000000000003CA00000000000CC0000000031
+:1057D000005A30000000003A50000000003A50002B
+:1057E0000000003A50000000003A50000000003A6B
+:1057F00050000000000EC30000000005CE80000035
+:105800000880000000000880000000000880000000
+:1058100000000880000000000880000000000880F0
+:105820000000000008800000000008800000000068
+:1058300008800000000008800000000008800000D0
+:1058400000000880000000000880000000000880C0
+:105850000000000008800000000008800000000038
+:1058600008800000000008800000000008800000A0
+:105870000000088000000000088000000000088090
+:10588000000000000880000008EC30000000000C60
+:10589000C00000000005A30000000005A3000000F8
+:1058A0000005A30000000005A30000000005A30000
+:1058B00000000005A30000000003A5000000000098
+:1058C0008A30000000005EE300000003EC000000EE
+:1058D0000005A50000000005A30000000005A300CE
+:1058E00000000005A30000000005A3000000000563
+:1058F000A3000000000CE000000008EC50000000D5
+:1059000003CFEA0000000A80CFC00088580008ECEE
+:1059100035A00000005EFE5000000000C000000046
+:105920000C00000000000000C00010000C0000038C
+:1059300060000000C00006000C00000F84000000A2
+:10594000C00010000C000003E4000000C0001500BF
+:105950000C00000062010000C00010000C000003F9
+:10596000C2010000C00010000C0000032202000071
+:10597000C00006000C00000F46020000C000150029
+:105980000C000001C4020000C00015000C00000162
+:1059900042030000C0000C000C0000058A03000058
+:1059A000C0000B000C000006CC030000C000060085
+:1059B0000C000000F0030000C00001000C00000B10
+:1059C000F6030000C00003000C0000030804000000
+:1059D000C00014000C00000180040000C000100092
+:1059E0000C000003E0040000C00010000C000003E5
+:1059F00040050000C00010000C000003A0050000DE
+:105A0000C00010000C00000300060000C0001000E1
+:105A10000C00000360060000C00010000C00000332
+:105A2000C0060000C00010000C00000320070000AA
+:105A3000C00010000C00000380070000C000100030
+:105A40000C000003E0070000C00010000C00000381
+:105A500040080000C0000B000C000003820800009A
+:105A6000C0000C000C000001CA080000C0001000BB
+:105A70000C0000032A090000C00005000C0000090A
+:105A800048090000C00010000C000003A809000035
+:105A9000C00010000C000003080A0000C000100045
+:105AA0000C000003680A0000C00010000C00000396
+:105AB000C80A0000C0000F000C000003220B000009
+:105AC000C0000F000C0000037C0B0000C0000F00A2
+:105AD0000C000003D60B0000C0000F000C000003F8
+:105AE000300C0000C0000F000C0000038A0C000006
+:105AF000C0000F000C000003E40C0000C0000F0009
+:105B00000C0000033E0D0000C0000F000C0000035D
+:105B1000980D0000C00012000C000000040E0000F0
+:105B2000C0000F000C0000035E0E0000C0000F005C
+:105B30000C000003B80E0000C0000F000C000003B2
+:105B4000120F0000C0000F000C0000036C0F0000DB
+:105B5000C0000F000C000003C60F0000C0000F00C3
+:105B60000C00000320100000C00011000C00000118
+:105B700086100000C0000F000C000003E0100000C1
+:105B8000C0000F000C0000033A110000C0000F001D
+:105B90000C00000394110000C0000F000C00000373
+:105BA000EE110000C0000F000C00000348120000BE
+:105BB000C0000F000C000003A2120000C0000F0084
+:105BC0000C000003FC120000C0000F000C000003DA
+:105BD00056130000C0000F000C000003B0130000BB
+:105BE000C00014000C00000128140000C0001300C5
+:105BF0000C0000019A140000C00014000C00000109
+:105C000012150000C00003000C0000132415000052
+:105C1000C00001000C0000002A150000C0000200B6
+:105C20000C00001336150000C0000A000C00000331
+:105C300072150000C00010000C000003D215000017
+:105C4000C0000A000C0000030E160000C000100087
+:105C50000C0000036E160000C0000A000C000003D8
+:105C6000AA160000C0000F000C000003041700007B
+:105C7000C0000D000C00000052170000C000100012
+:105C80000C000003B2170000C0000F000C0000035E
+:105C90000C180000C00012000C0000007818000072
+:105CA000C00010000C000003D8180000C000100055
+:105CB0000C00000338190000C0000B000C000003AA
+:105CC0007A190000C0000A000C000003B619000099
+:105CD000C0000A000C000003F2190000C0000D0013
+:105CE0000C000000401A0000C0000D000C00000075
+:105CF0008E1A0000C0000A000C000003CA1A00003F
+:105D0000C0000A000C000003061B0000C0000E00CB
+:105D10000C0000035A1B0000C0000B000C00000325
+:105D20009C1B0000C0000A000C000003D81B0000F0
+:105D3000C0000A000C000003141C0000C0000A0090
+:105D40000C000003501C0000C0000D000C000000FF
+:105D50009E1C0000C0000A000C000003DA1C0000BA
+:105D6000C00014000C000001521D0000C00017000C
+:105D70000C000000DC1D0000C00014000C0000013D
+:105D8000541E0000C00004000C0000126C1E000035
+:105D9000C00000000C0000002000000060000000B7
+:105DA0000000000000000000AC3A0108185901088A
+:105DB00060001700985D0108010000000000040069
+:105DC00073676C5F6C6162656C5F636F6E73747236
+:105DD0007563745F6362000064656661756C74541A
+:105DE00061736B002123242728292A2B2C2D2E3088
+:105DF0003132333435363738000000002123242770
+:105E000028292A2B2C2D2E30313233343536373891
+:105E100039000000303132333435363738393A3BC7
+:105E20003C3D3E3F40000000414243444546474818
+:105E3000494A4B4C4D4E4F505152535400000000B4
+:105E400053544D33322053474C20546578742044CA
+:105E5000656D6F000D0A436F6D6D616E64204C6956
+:105E600073743A0D0A0000000D0A566172204C69E5
+:105E700073743A0D0A0000000D0A55736572204CC8
+:105E80006973743A0D0A00000D0A4B6579204C695C
+:105E900073743A0D0A000000436F6D6D616E6420EB
+:105EA0006E6F7420466F756E640D0A000D0A57619F
+:105EB000726E696E673A20436F6D6D616E64206922
+:105EC0007320746F6F206C6F6E670D0A0000000006
+:105ED000206973206E6F742061207661720D0A0054
+:105EE00063616E2774207365742072656164206F2E
+:105EF0006E6C79207661720D0A00000063616E2776
+:105F0000742073657420706F696E7465720D0A0079
+:105F10000D0A205F2020202020202020205F20202C
+:105F2000205F202020202020202020202020202032
+:105F3000202020205F202020202020202020205FE3
+:105F4000205F200D0A7C207C202020205F5F5F7C6A
+:105F5000207C5F7C207C5F205F5F5F205F205F5F35
+:105F60002020205F5F5F7C207C5F5F2020205F5FC0
+:105F70005F7C207C207C0D0A7C207C2020202F2030
+:105F80005F205C205F5F7C205F5F2F205F205C20B4
+:105F9000275F5F7C202F205F5F7C20275F205C20B5
+:105FA0002F205F205C207C207C0D0A7C207C5F5FA2
+:105FB0007C20205F5F2F207C5F7C207C7C20205F0A
+:105FC0005F2F207C202020205C5F5F205C207C20D5
+:105FD0007C207C20205F5F2F207C207C0D0A7C5F52
+:105FE0005F5F5F5F5C5F5F5F7C5C5F5F7C5C5F5F90
+:105FF0005C5F5F5F7C5F7C202020207C5F5F5F2F89
+:106000005F7C207C5F7C5C5F5F5F7C5F7C5F7C0D86
+:106010000A0D0A4275696C643A2020202020202055
+:106020004D617220313920323032362031333A35E9
+:10603000323A31390D0A56657273696F6E3A202013
+:10604000202020332E322E340D0A436F707972696E
+:106050006768743A202020286329203230323020AB
+:106060004C65747465720D0A000000000D0A7061C1
+:106070007373776F7264206572726F720D0A00001D
+:10608000566172206E6F7420466F756E740D0A0033
+:106090001B5B324B0D000000434D4420000000000C
+:1060A00056415220000000004B45592000000000DE
+:1060B000636F6D6D616E642068656C70206F662023
+:1060C00000000000506C6561736520696E70757426
+:1060D0002070617373776F72643A00004E4F4E45C3
+:1060E000000000001B5B324A1B5B314800000000CF
+:1060F000555345520000000073676C5F7365617211
+:1061000063685F756E69636F64655F63685F696E1E
+:106110006465783A205B307825785D756E69636FC9
+:106120006465206E6F7420666F756E6420696E20E2
+:10613000666F6E74207461626C6500008C62010889
+:10614000000000205402000074090008D863010810
+:1061500054020020EC5301005C900008D863010851
+:1061600000C00120004000005C9000080008000012
+:106170009C2F0108A32F0108A42F01080021000073
+:10618000B12F0108950C0108B82F01080009000083
+:1061900000415B1B7B110108C02F010800090000B2
+:1061A00000425B1B65FE0008C32F010800190000B8
+:1061B00000435B1BEF0A0108C82F0108001900000B
+:1061C00000445B1BDB070108CE2F0108000900001B
+:1061D00000000009B90F0108D32F010800190000C1
+:1061E0000000000875FC0008D72F01080019000006
+:1061F0000000007F75FC0008E12F01080019000075
+:106200007E335B1B5BFD0008EB2F010800190000CB
+:106210000000000A75FE0008F22F010800190000B6
+:106220000000000D75FE0008F82F01080020000096
+:10623000FE2F0108C90401080330010800210000F5
+:1062400021300108891101082730010800210000D0
+:106250003530010849FD00083A30010800210000EE
+:10626000473001089B1101084C3001080021000053
+:1062700059300108C90701085E30010800210000FB
+:106280006B30010805FD00087130010881321042B1
+:1062900001035D24F41AAA0101141E405E010828BE
+:1062A000041A14045EE45D0108FC04290C29142975
+:1062B0001C29248113C1AC1408ADAD140820581258
+:1062C0002016C0012020D81C2020F80C69C8B1136A
+:1062D000316E1B0879041A89041AB5041AF50413DF
+:1062E000FD6D1B08410813120114020202164083BF
+:1062F0000440571D020102033D071A040309041A52
+:106300000313090B1B08050413C10A1B082D081AE7
+:10631000510441130A062A02CB298013E1681408AC
+:10632000DD664C082B6B1C13B1671408D1651B0884
+:106330009514C11A55281A11041A9D041A01041C37
+:1063400009024387111DC0320904C91A020B130543
+:106350002416100105240110090104240202052459
+:1063600006170107058203081C100904BD320A2E16
+:106370000705010240072A810724810182180A10BB
+:106380005F0108AC5E010854041A68041A78041A04
+:1063900088041A98041AFC041AE0041AD0041E8017
+:1063A000600108B0041AC4041A6C041AE4041A90B8
+:1063B000041A98041AA0041AF0041AA8041ADC0497
+:1063C000031622221E482F01084E0417C6E533B4D7
+:0863D000919502000800000095
:040000050800018965
:00000001FF
diff --git a/User/application/app.c b/User/application/app.c
index 26cabd6..f8cdcd0 100644
--- a/User/application/app.c
+++ b/User/application/app.c
@@ -2,18 +2,38 @@
#include "board.h"
#include "os.h"
#include "shell_port.h"
+#include "../system/sgl/sgl.h"
static TaskHandle_t business_task_handle = NULL;
+void sgl_print_hello(void)
+{
+ /* 设置页é¢èƒŒæ™¯ä¸ºé»‘色,使白色文å—å¯è§ */
+ sgl_page_set_color(sgl_screen_act(), sgl_rgb(0x00, 0x00, 0x00));
+
+ /* å…¨å± labelï¼Œå±…ä¸æ˜¾ç¤º Hello World */
+ sgl_obj_t *label = sgl_label_create(NULL);
+ sgl_obj_set_pos(label, 0, 0);
+ sgl_obj_set_size(label, 240, 240);
+ sgl_label_set_text(label, "Hello World");
+ sgl_label_set_font(label, &song23);
+ sgl_label_set_text_color(label, sgl_rgb(0xFF, 0xFF, 0xFF));
+ sgl_label_set_text_align(label, SGL_ALIGN_CENTER);
+}
+
void business_task(void *pvParameters)
{
+ /* å¯åŠ¨æ—¶æ˜¾ç¤º Hello World 2 ç§’ */
+ sgl_print_hello();
+ sgl_task_handle();
+ vTaskDelay(2000);
+
for (;;)
{
rtc_update();
lcd_rtc_test();
+ sgl_task_handle();
led_toggle(LED_USER);
- // usb_printf("STM32F103 usb test\r\n");
- // usb_printf("print test >>>>>>\r\n");
vTaskDelay(1000);
}
}
diff --git a/User/board/board.c b/User/board/board.c
index 88f15e1..729bcdd 100644
--- a/User/board/board.c
+++ b/User/board/board.c
@@ -3,10 +3,21 @@
#include "main.h"
#include "rtc.h"
#include "spi.h"
-
-
+#include "../system/sgl/sgl.h"
+#include "os.h"
board_t board;
+#define SGL_PANEL_WIDTH 240
+#define SGL_PANEL_HEIGHT 240
+
+static sgl_color_t sgl_panel_buffer[SGL_PANEL_WIDTH * 10];
+
+static void sgl_flush_area(sgl_area_t *area, sgl_color_t *src)
+{
+ board.lcd->driver.write_pixels(board.lcd, area->x1, area->y1, area->x2, area->y2, (uint16_t *)src);
+ sgl_fbdev_flush_ready();
+}
+
void led_open(led_e led)
{
switch (led)
@@ -138,119 +149,141 @@ BOOL rtc_init(void)
void lcd_rtc_test(void)
{
- char buf[128] = {0}; // »º³åÇø
- board.lcd->driver.set_hz_font(board.lcd, &ch_font_24); // ÉèÖúº×Ö×ÖÌå
- board.lcd->driver.full_fill(board.lcd, LCD_BLACK); // ÉèÖñ³¾°É«
- board.lcd->driver.set_color(board.lcd, LCD_WHITE); // ÉèÖû±ÊÑÕÉ«
- uint8_t hight_offset = 70;
- board.lcd->driver.set_color(board.lcd, LIGHT_BLUE); // ÉèÖû±ÊÑÕÉ«
- board.lcd->driver.display_text(board.lcd, 13, hight_offset, "STM32 RTC²âÊÔ");
- board.lcd->driver.set_color(board.lcd, LIGHT_YELLOW); // ÉèÖû±ÊÑÕÉ«
- board.lcd->driver.display_text(board.lcd, 13, hight_offset + board.lcd->info.hz_font->height, "ÆÁÄ»·Ö±æÂÊ:240*240");
- board.lcd->driver.set_color(board.lcd, LIGHT_RED); // ÉèÖû±ÊÑÕÉ«
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_20);
- sprintf(buf, "%d-%02d-%02d %02d:%02d:%02d", 2000 + board.rtc_date.year, board.rtc_date.month, board.rtc_date.day, board.rtc_time.hour, board.rtc_time.minute, board.rtc_time.second);
- board.lcd->driver.display_text(board.lcd, 13, hight_offset + board.lcd->info.hz_font->height * 2, buf);
+ static sgl_obj_t *label_time = NULL;
+ static char buf[32];
+
+ if (label_time == NULL)
+ {
+ sgl_obj_delete(NULL);
+ sgl_page_set_color(sgl_screen_act(), sgl_rgb(0x00, 0x00, 0x00));
+
+ sgl_obj_t *lbl = sgl_label_create(NULL);
+ sgl_obj_set_pos(lbl, 0, 70);
+ sgl_obj_set_size(lbl, 240, 28);
+ sgl_label_set_text(lbl, "STM32 RTC Test");
+ sgl_label_set_font(lbl, &song23);
+ sgl_label_set_text_color(lbl, sgl_rgb(0x00, 0xAA, 0xFF));
+ sgl_label_set_text_align(lbl, SGL_ALIGN_CENTER);
+
+ lbl = sgl_label_create(NULL);
+ sgl_obj_set_pos(lbl, 0, 100);
+ sgl_obj_set_size(lbl, 240, 28);
+ sgl_label_set_text(lbl, "Resolution: 240x240");
+ sgl_label_set_font(lbl, &song23);
+ sgl_label_set_text_color(lbl, sgl_rgb(0xFF, 0xFF, 0x00));
+ sgl_label_set_text_align(lbl, SGL_ALIGN_CENTER);
+
+ label_time = sgl_label_create(NULL);
+ sgl_obj_set_pos(label_time, 0, 130);
+ sgl_obj_set_size(label_time, 240, 28);
+ sgl_label_set_font(label_time, &song23);
+ sgl_label_set_text_color(label_time, sgl_rgb(0xFF, 0x40, 0x40));
+ sgl_label_set_text_align(label_time, SGL_ALIGN_CENTER);
+ }
+
+ sprintf(buf, "%d-%02d-%02d %02d:%02d:%02d",
+ 2000 + board.rtc_date.year, board.rtc_date.month, board.rtc_date.day,
+ board.rtc_time.hour, board.rtc_time.minute, board.rtc_time.second);
+ sgl_label_set_text(label_time, buf);
}
// ÇåÆÁ²âÊÔ
void lcd_test_clear(void)
{
- uint8_t i = 0; // ¼ÆÊý±äÁ¿
- board.lcd->driver.set_hz_font(board.lcd, &ch_font_24); // ÉèÖúº×Ö×ÖÌå
- board.lcd->driver.set_color(board.lcd, LCD_BLACK); // ÉèÖû±ÊÑÕÉ«
+ sgl_color_t bg_colors[8];
+ bg_colors[0] = sgl_rgb(0xFF, 0x80, 0x80); /* LIGHT_RED */
+ bg_colors[1] = sgl_rgb(0x80, 0xFF, 0x80); /* LIGHT_GREEN */
+ bg_colors[2] = sgl_rgb(0x80, 0x80, 0xFF); /* LIGHT_BLUE */
+ bg_colors[3] = sgl_rgb(0xFF, 0xFF, 0x80); /* LIGHT_YELLOW */
+ bg_colors[4] = sgl_rgb(0x80, 0xFF, 0xFF); /* LIGHT_CYAN */
+ bg_colors[5] = sgl_rgb(0xA3, 0xA3, 0xA3); /* LIGHT_GREY */
+ bg_colors[6] = sgl_rgb(0xFF, 0x80, 0xFF); /* LIGHT_MAGENTA */
+ bg_colors[7] = sgl_rgb(0xFF, 0xFF, 0xFF); /* LCD_WHITE */
- for (i = 0; i < 8; i++)
+ sgl_obj_delete(NULL);
+
+ sgl_obj_t *lbl = sgl_label_create(NULL);
+ sgl_obj_set_pos(lbl, 0, 70);
+ sgl_obj_set_size(lbl, 240, 28);
+ sgl_label_set_text(lbl, "STM32 Clear Test");
+ sgl_label_set_font(lbl, &song23);
+ sgl_label_set_text_color(lbl, sgl_rgb(0x00, 0x00, 0x00));
+ sgl_label_set_text_align(lbl, SGL_ALIGN_CENTER);
+
+ lbl = sgl_label_create(NULL);
+ sgl_obj_set_pos(lbl, 0, 100);
+ sgl_obj_set_size(lbl, 240, 28);
+ sgl_label_set_text(lbl, "Resolution: 240x240");
+ sgl_label_set_font(lbl, &song23);
+ sgl_label_set_text_color(lbl, sgl_rgb(0x00, 0x00, 0x00));
+ sgl_label_set_text_align(lbl, SGL_ALIGN_CENTER);
+
+ lbl = sgl_label_create(NULL);
+ sgl_obj_set_pos(lbl, 0, 130);
+ sgl_obj_set_size(lbl, 240, 28);
+ sgl_label_set_text(lbl, "Controller: ST7789");
+ sgl_label_set_font(lbl, &song23);
+ sgl_label_set_text_color(lbl, sgl_rgb(0x00, 0x00, 0x00));
+ sgl_label_set_text_align(lbl, SGL_ALIGN_CENTER);
+
+ for (uint8_t i = 0; i < 8; i++)
{
- switch (i) // Çл»±³¾°É«
- {
- case 0:
- board.lcd->driver.full_fill(board.lcd, LIGHT_RED);
- break;
- case 1:
- board.lcd->driver.full_fill(board.lcd, LIGHT_GREEN);
- break;
- case 2:
- board.lcd->driver.full_fill(board.lcd, LIGHT_BLUE);
- break;
- case 3:
- board.lcd->driver.full_fill(board.lcd, LIGHT_YELLOW);
- break;
- case 4:
- board.lcd->driver.full_fill(board.lcd, LIGHT_CYAN);
- break;
- case 5:
- board.lcd->driver.full_fill(board.lcd, LIGHT_GREY);
- break;
- case 6:
- board.lcd->driver.full_fill(board.lcd, LIGHT_MAGENTA);
- break;
- case 7:
- board.lcd->driver.full_fill(board.lcd, LCD_WHITE);
- break;
- default:
- break;
- }
- board.lcd->driver.clear(board.lcd); // ÇåÆÁ
- board.lcd->driver.display_text(board.lcd, 13, 70, "STM32 Ë¢ÆÁ²âÊÔ");
- board.lcd->driver.display_text(board.lcd, 13, 106, "ÆÁÄ»·Ö±æÂÊ:240*240");
- board.lcd->driver.display_text(board.lcd, 13, 142, "¿ØÖÆÆ÷:ST7789");
- HAL_Delay(1000); // ÑÓʱ
+ sgl_page_set_color(sgl_screen_act(), bg_colors[i]);
+ sgl_task_handle();
+ vTaskDelay(1000);
}
+
+ sgl_obj_delete(NULL);
}
// Îı¾²âÊÔ
void lcd_test_text(void)
{
- board.lcd->driver.clear(board.lcd); // ÇåÆÁ
- board.lcd->driver.full_fill(board.lcd, LCD_BLACK);
+ static uint8_t initialized = 0;
+ if (initialized)
+ return;
+ initialized = 1;
- board.lcd->driver.set_color(board.lcd, LCD_WHITE);
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_32);
- board.lcd->driver.display_text(board.lcd, 0, 0, "!#$'()*+,-.0123");
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_24);
- board.lcd->driver.display_text(board.lcd, 0, 32, "!#$'()*+,-.012345678");
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_20);
- board.lcd->driver.display_text(board.lcd, 0, 56, "!#$'()*+,-.0123456789:;<");
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_16);
- board.lcd->driver.display_text(board.lcd, 0, 76, "!#$'()*+,-.0123456789:;<=>?@AB");
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_12);
- board.lcd->driver.display_text(board.lcd, 0, 92, "!#$'()*+,-.0123456789:;<=>?@ABCDEFGHIJKL");
+ sgl_obj_delete(NULL);
+ sgl_page_set_color(sgl_screen_act(), sgl_rgb(0x00, 0x00, 0x00));
- board.lcd->driver.set_color(board.lcd, LCD_CYAN);
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_12);
- board.lcd->driver.display_text(board.lcd, 0, 104, "!#&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKL");
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_16);
- board.lcd->driver.display_text(board.lcd, 0, 116, "!#&'()*+,-.0123456789:;<=>?@AB");
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_20);
- board.lcd->driver.display_text(board.lcd, 0, 132, "!#&'()*+,-.0123456789:;<");
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_24);
- board.lcd->driver.display_text(board.lcd, 0, 152, "!#&'()*+,-.012345678");
- board.lcd->driver.set_asscii_font(board.lcd, &ascii_font_32);
- board.lcd->driver.display_text(board.lcd, 0, 176, "!#&'()*+,-.0123");
+ /* 5 rows of white text */
+ static const char *white_lines[5] = {
+ "STM32 SGL Text Demo",
+ "ABCDEFGHIJKLMNOPQRST",
+ "0123456789:;<=>?@",
+ "!#$'()*+,-.012345678",
+ "!#$'()*+,-.0123456789",
+ };
+ for (uint8_t i = 0; i < 5; i++)
+ {
+ sgl_obj_t *lbl = sgl_label_create(NULL);
+ sgl_obj_set_pos(lbl, 0, i * 24);
+ sgl_obj_set_size(lbl, 240, 24);
+ sgl_label_set_text(lbl, white_lines[i]);
+ sgl_label_set_font(lbl, &song23);
+ sgl_label_set_text_color(lbl, sgl_rgb(0xFF, 0xFF, 0xFF));
+ }
+
+ /* 5 rows of cyan text */
+ static const char *cyan_lines[5] = {
+ "!#$'()*+,-.0123456789",
+ "!#$'()*+,-.012345678",
+ "0123456789:;<=>?@",
+ "ABCDEFGHIJKLMNOPQRST",
+ "STM32 SGL Text Demo",
+ };
+ for (uint8_t i = 0; i < 5; i++)
+ {
+ sgl_obj_t *lbl = sgl_label_create(NULL);
+ sgl_obj_set_pos(lbl, 0, 120 + i * 24);
+ sgl_obj_set_size(lbl, 240, 24);
+ sgl_label_set_text(lbl, cyan_lines[i]);
+ sgl_label_set_font(lbl, &song23);
+ sgl_label_set_text_color(lbl, sgl_rgb(0x00, 0xFF, 0xFF));
+ }
}
-// ±äÁ¿²âÊÔ£¬°üÀ¨ÕûÊýºÍСÊý
-void lcd_test_var(void)
-{
-}
-
-// ÑÕÉ«²âÊÔ
-void lcd_test_color(void)
-{
-}
-
-// 2DͼÐλæÖÆ
-void lcd_test_2d(void)
-{
-}
-
-// ͼƬÏÔʾ
-void lcd_test_image(void)
-{
-}
-
-
void lcd_init(void)
{
spi_gpio_group_t gpios;
@@ -277,6 +310,17 @@ void lcd_init(void)
// lcd_test_clear();
// lcd_test_text();
+
+ /* SGL³õʼ»¯ */
+ sgl_fbinfo_t fbinfo = {
+ .xres = SGL_PANEL_WIDTH,
+ .yres = SGL_PANEL_HEIGHT,
+ .flush_area = sgl_flush_area,
+ .buffer[0] = sgl_panel_buffer,
+ .buffer_size = sizeof(sgl_panel_buffer) / sizeof(sgl_color_t),
+ };
+ sgl_fbdev_register(&fbinfo);
+ sgl_init();
}
/**
diff --git a/User/system/lib/lcd/lcd_tft_154.c b/User/system/lib/lcd/lcd_tft_154.c
index d0a20db..2d15f4b 100644
--- a/User/system/lib/lcd/lcd_tft_154.c
+++ b/User/system/lib/lcd/lcd_tft_154.c
@@ -1,15 +1,5 @@
#include "lcd_tft_154.h"
-#define FILL_ZERO 0 // å¡«å……0
-#define FILL_SPACE 1 // å¡«å……ç©ºæ ¼
-
-// å› ä¸ºè¿™ç±»SPIçš„å±å¹•ï¼Œæ¯æ¬¡æ›´æ–°æ˜¾ç¤ºæ—¶ï¼Œéœ€è¦å…ˆé…ç½®åæ ‡åŒºåŸŸã€å†å†™æ˜¾å˜ï¼Œ
-// 在显示å—ç¬¦æ—¶ï¼Œå¦‚æžœæ˜¯ä¸€ä¸ªä¸ªç‚¹åŽ»å†™åæ ‡å†™æ˜¾å˜ï¼Œä¼šéžå¸¸æ…¢ï¼Œ
-// å› æ¤å¼€è¾Ÿä¸€ç‰‡ç¼“å†²åŒºï¼Œå…ˆå°†éœ€è¦æ˜¾ç¤ºçš„æ•°æ®å†™è¿›ç¼“冲区,最åŽå†æ‰¹é‡å†™å…¥æ˜¾å˜ã€‚
-// 用户å¯ä»¥æ ¹æ®å®žé™…情况去修改æ¤å¤„缓冲区的大å°ï¼Œ
-// ä¾‹å¦‚ï¼Œç”¨æˆ·éœ€è¦æ˜¾ç¤º32*32çš„æ±‰å—æ—¶ï¼Œéœ€è¦çš„大å°ä¸º 32*32*2 = 2048 å—节(æ¯ä¸ªåƒç´ 点å 2å—节)
-static uint16_t *pri; // 显示缓å˜
-
// ç‰å¾…通讯完æˆ
static void _wait_finish(spi_t *lcd_spi)
{
@@ -113,16 +103,6 @@ static void _set_dir(lcd_t *lcd, uint8_t scan_dir)
lcd->info.spi->gpios.cs->set(*lcd->info.spi->gpios.cs);
}
-// 设置画笔颜色
-static void _set_color(lcd_t *lcd, uint32_t color)
-{
- uint16_t red_value = 0, green_value = 0, blue_value = 0; // å„个颜色通é“的值
- red_value = (uint16_t)((color & 0x00F80000) >> 8); // è½¬æ¢æˆ 16ä½ çš„RGB565颜色
- green_value = (uint16_t)((color & 0x0000FC00) >> 5);
- blue_value = (uint16_t)((color & 0x000000F8) >> 3);
- lcd->info.color = (uint16_t)(red_value | green_value | blue_value); // 将颜色写入全局LCD傿•°
-}
-
static void _set_address(lcd_t *lcd, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
lcd->info.spi->gpios.cs->reset(*lcd->info.spi->gpios.cs);
@@ -141,166 +121,12 @@ static void _set_address(lcd_t *lcd, uint16_t x1, uint16_t y1, uint16_t x2, uint
lcd->info.spi->gpios.cs->set(*lcd->info.spi->gpios.cs);
}
-static void _set_asscii_font(lcd_t *lcd, lcd_font *font)
+// 写åƒç´ 缓冲区
+static void _write_pixels(lcd_t *lcd, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *data)
{
- lcd->info.ascii_font = font;
-}
-
-static void _set_hz_font(lcd_t *lcd, lcd_font *font)
-{
- lcd->info.hz_font = font;
- switch (font->width)
- {
- case 12:
- lcd->driver.set_asscii_font(lcd, &ascii_font_12);
- break; // 设置ASCIIå—符的å—体为 1206
- case 16:
- lcd->driver.set_asscii_font(lcd, &ascii_font_16);
- break; // 设置ASCIIå—符的å—体为 1608
- case 20:
- lcd->driver.set_asscii_font(lcd, &ascii_font_20);
- break; // 设置ASCIIå—符的å—体为 2010
- case 24:
- lcd->driver.set_asscii_font(lcd, &ascii_font_24);
- break; // 设置ASCIIå—符的å—体为 2412
- case 32:
- lcd->driver.set_asscii_font(lcd, &ascii_font_32);
- break; // 设置ASCIIå—符的å—体为 3216
- default:
- break;
- }
-}
-
-/****************************************************************************************************************************************
- * 函 æ•° å: LCD_DisplayChar
- *
- * å…¥å£å‚æ•°: x - èµ·å§‹æ°´å¹³åæ ‡
- * y - èµ·å§‹åž‚ç›´åæ ‡
- * c - ASCIIå—符
- *
- * 函数功能: åœ¨æŒ‡å®šåæ ‡æ˜¾ç¤ºæŒ‡å®šçš„å—符
- *
- * 说 明: 1. å¯è®¾ç½®è¦æ˜¾ç¤ºçš„å—体,例如使用 LCD_SetAsciiFont(&ASCII_Font24) 设置为 2412çš„ASCIIå—体
- * 2. å¯è®¾ç½®è¦æ˜¾ç¤ºçš„颜色,例如使用 LCD_SetColor(0xff0000FF) 设置为è“色
- * 3. å¯è®¾ç½®å¯¹åº”的背景色,例如使用 LCD_SetBackColor(0x000000) 设置为黑色的背景色
- * 4. 使用示例 LCD_DisplayChar( 10, 10, 'a') ï¼Œåœ¨åæ ‡(10,10)显示å—符 'a'
- *
- *****************************************************************************************************************************************/
-
-void _display_char(lcd_t *lcd, uint16_t x, uint16_t y, uint8_t c)
-{
- uint16_t index = 0, counter = 0, i = 0, w = 0; // 计数å˜é‡
- uint8_t disChar; // å˜å‚¨å—符的地å€
-
- c = c - 32; // 计算ASCIIå—符的åç§»
-
- lcd->info.spi->gpios.cs->reset(*lcd->info.spi->gpios.cs);
-
- for (index = 0; index < lcd->info.ascii_font->sizes; index++)
- {
- disChar = lcd->info.ascii_font->table[c * lcd->info.ascii_font->sizes + index]; // 获å–å—符的模值
- for (counter = 0; counter < 8; counter++)
- {
- if (disChar & 0x01)
- {
- pri[i] = lcd->info.color; // 当剿¨¡å€¼ä¸ä¸º0时,使用画笔色绘点
- }
- else
- {
- pri[i] = lcd->info.back_color; // å¦åˆ™ä½¿ç”¨èƒŒæ™¯è‰²ç»˜åˆ¶ç‚¹
- }
- disChar >>= 1;
- i++;
- w++;
- if (w == lcd->info.ascii_font->width) // 如果写入的数æ®è¾¾åˆ°äº†å—符宽度,则退出当å‰å¾ªçޝ
- { // 进入下一å—符的写入的绘制
- w = 0;
- break;
- }
- }
- }
- lcd->driver.set_address(lcd, x, y, x + lcd->info.ascii_font->width - 1, y + lcd->info.ascii_font->height - 1); // è®¾ç½®åæ ‡
- _write_buff(lcd, pri, lcd->info.ascii_font->width * lcd->info.ascii_font->height); // 写入显å˜
-}
-
-void _display_chinese(lcd_t *lcd, uint16_t x, uint16_t y, char *text)
-{
- uint16_t i = 0, index = 0, counter = 0; // 计数å˜é‡
- uint16_t addr; // å—æ¨¡åœ°å€
- uint8_t disChar; // å—æ¨¡çš„值
- uint16_t Xaddress = 0; // æ°´å¹³åæ ‡
-
- while (1)
- {
- // 对比数组ä¸çš„æ±‰å—ç¼–ç ,用以定ä½è¯¥æ±‰å—å—æ¨¡çš„地å€
- if (*(lcd->info.hz_font->table + (i + 1) * lcd->info.hz_font->sizes + 0) == *text && *(lcd->info.hz_font->table + (i + 1) * lcd->info.hz_font->sizes + 1) == *(text + 1))
- {
- addr = i; // å—æ¨¡åœ°å€åç§»
- break;
- }
- i += 2; // æ¯ä¸ªä¸æ–‡å—符编ç å 两å—节
-
- if (i >= lcd->info.hz_font->table_rows)
- break; // å—æ¨¡åˆ—è¡¨ä¸æ— 相应的汉å—
- }
- i = 0;
- for (index = 0; index < lcd->info.hz_font->sizes; index++)
- {
- disChar = *(lcd->info.hz_font->table + (addr)*lcd->info.hz_font->sizes + index); // 获å–ç›¸åº”çš„å—æ¨¡åœ°å€
-
- for (counter = 0; counter < 8; counter++)
- {
- if (disChar & 0x01)
- {
- pri[i] = lcd->info.color; // 当剿¨¡å€¼ä¸ä¸º0时,使用画笔色绘点
- }
- else
- {
- pri[i] = lcd->info.back_color; // å¦åˆ™ä½¿ç”¨èƒŒæ™¯è‰²ç»˜åˆ¶ç‚¹
- }
- i++;
- disChar >>= 1;
- Xaddress++; // æ°´å¹³åæ ‡è‡ªåŠ
-
- if (Xaddress == lcd->info.hz_font->width) // å¦‚æžœæ°´å¹³åæ ‡è¾¾åˆ°äº†å—符宽度,则退出当å‰å¾ªçޝ
- { // 进入下一行的绘制
- Xaddress = 0;
- break;
- }
- }
- }
- lcd->driver.set_address(lcd, x, y, x + lcd->info.hz_font->width - 1, y + lcd->info.hz_font->height - 1); // è®¾ç½®åæ ‡
- _write_buff(lcd, pri, lcd->info.hz_font->width * lcd->info.hz_font->height); // 写入显å˜
-}
-
-static void _display_text(lcd_t *lcd, uint16_t x, uint16_t y, char *text)
-{
- while (*text != 0) // åˆ¤æ–æ˜¯å¦ä¸ºç©ºå—符
- {
- if (*text <= 0x7F) // åˆ¤æ–æ˜¯å¦ä¸ºASCIIç
- {
- _display_char(lcd, x, y, *text); // 显示ASCII
- x += lcd->info.ascii_font->width; // æ°´å¹³åæ ‡è°ƒåˆ°ä¸‹ä¸€ä¸ªå—符处
- text++; // å—符串地å€+1
- }
- else // è‹¥å—符为汉å—
- {
- _display_chinese(lcd, x, y, text); // 显示汉å—
- x += lcd->info.hz_font->width; // æ°´å¹³åæ ‡è°ƒåˆ°ä¸‹ä¸€ä¸ªå—符处
- text += 2; // å—符串地å€+2,汉å—的编ç è¦2å—节
- }
- }
-}
-
-// 设置背景色
-static void _full_fill(lcd_t *lcd, uint32_t color)
-{
- uint16_t red_value = 0, green_value = 0, blue_value = 0; // å„个颜色通é“的值
- red_value = (uint16_t)((color & 0x00F80000) >> 8); // è½¬æ¢æˆ 16ä½ çš„RGB565颜色
- green_value = (uint16_t)((color & 0x0000FC00) >> 5);
- blue_value = (uint16_t)((color & 0x000000F8) >> 3);
-
- lcd->info.back_color = (uint16_t)(red_value | green_value | blue_value); // 将颜色写入全局LCD傿•°
+ uint32_t len = (uint32_t)(x2 - x1 + 1) * (y2 - y1 + 1);
+ lcd->driver.set_address(lcd, x1, y1, x2, y2);
+ _write_buff(lcd, data, len);
}
static void _clear(lcd_t *lcd)
@@ -331,8 +157,6 @@ static void _clear(lcd_t *lcd)
static int32_t _init(lcd_t *lcd)
{
HAL_Delay(10);
- pri = (uint16_t *)osel_mem_alloc2(1024 * sizeof(lcd));
- lcd->info.pri = (void *)pri;
lcd->info.spi->gpios.cs->reset(*lcd->info.spi->gpios.cs);
_write_command(lcd->info.spi, 0x36); // 显å˜è®¿é—®æŽ§åˆ¶ 指令,用于设置访问显å˜çš„æ–¹å¼
_write_data_8bit(lcd->info.spi, 0x00); // é…ç½®æˆ ä»Žä¸Šåˆ°ä¸‹ã€ä»Žå·¦åˆ°å³ï¼ŒRGBåƒç´ æ ¼å¼
@@ -416,12 +240,9 @@ static int32_t _init(lcd_t *lcd)
lcd->info.spi->gpios.cs->set(*lcd->info.spi->gpios.cs);
// 以下进行一些驱动的默认设置
- lcd->driver.set_dir(lcd, Direction_V); // é»˜è®¤ç«–å±æ˜¾ç¤º
- lcd->driver.full_fill(lcd, LCD_BLACK); // 默认背景色为黑色
- lcd->driver.set_color(lcd, LCD_WHITE); // 默认画笔颜色为白色
- lcd->driver.clear(lcd); // 清除å±å¹•
- lcd->driver.set_asscii_font(lcd, &ascii_font_24); // 默认ASCIIå—体
- lcd->info.show_num_mode = FILL_ZERO; // 设置å˜é‡æ˜¾ç¤ºæ¨¡å¼ï¼Œå¤šä½™ä½å¡«å……ç©ºæ ¼è¿˜æ˜¯å¡«å……0
+ lcd->driver.set_dir(lcd, Direction_V); // é»˜è®¤ç«–å±æ˜¾ç¤º
+ lcd->info.back_color = 0x0000; // 默认背景色为黑色
+ lcd->driver.clear(lcd); // 清除å±å¹•
return 0;
}
@@ -430,13 +251,9 @@ void lcd_tft_154_init(lcd_driver_t *driver)
{
DBG_ASSERT(driver != NULL __DBG_LINE);
- driver->init = _init; // 已实现
- driver->set_dir = _set_dir; // 已实现
- driver->set_color = _set_color; // 已实现
- driver->set_address = _set_address; // 已实现
- driver->set_asscii_font = _set_asscii_font; // 已实现
- driver->set_hz_font = _set_hz_font; // 已实现
- driver->display_text = _display_text; // 已实现
- driver->clear = _clear; // 已实现
- driver->full_fill = _full_fill; // 已实现
+ driver->init = _init; // 已实现
+ driver->set_dir = _set_dir; // 已实现
+ driver->set_address = _set_address; // 已实现
+ driver->write_pixels = _write_pixels; // 已实现
+ driver->clear = _clear; // 已实现
}
diff --git a/User/system/lib/lcd/lcds.h b/User/system/lib/lcd/lcds.h
index 8163798..e6095cd 100644
--- a/User/system/lib/lcd/lcds.h
+++ b/User/system/lib/lcd/lcds.h
@@ -204,20 +204,20 @@ typedef struct
void (*backlight)(lcd_t *lcd, uint8_t sta); // 背光控制
void (*display_text)(lcd_t *lcd, uint16_t x, uint16_t y, char *text); // 显示å—符串
void (*full_fill)(lcd_t *lcd, uint32_t color);
- void (*set_address)(lcd_t *lcd, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); // 设置显示区域
- void (*clear)(lcd_t *lcd); // 清å±
- void (*set_clear_flag)(lcd_t *lcd); // è®¾ç½®æ¸…å±æ ‡å¿—
- void (*copy_template)(lcd_t *lcd, template_copy_type_e dir); // æ‹·è´æ¨¡æ¿ 0,æ‹·è´pri_template到priï¼›1,拷è´pri到pri_template; 其余清空
- void (*clear_ram)(lcd_t *lcd, uint16_t min_row, uint16_t max_row); // 清除显å˜
+ void (*set_address)(lcd_t *lcd, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); // 设置显示区域
+ void (*write_pixels)(lcd_t *lcd, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *data); // 写åƒç´ 缓冲区
+ void (*clear)(lcd_t *lcd); // 清å±
+ void (*set_clear_flag)(lcd_t *lcd); // è®¾ç½®æ¸…å±æ ‡å¿—
+ void (*copy_template)(lcd_t *lcd, template_copy_type_e dir); // æ‹·è´æ¨¡æ¿ 0,æ‹·è´pri_template到priï¼›1,拷è´pri到pri_template; 其余清空
+ void (*clear_ram)(lcd_t *lcd, uint16_t min_row, uint16_t max_row); // 清除显å˜
// 扩展接å£
void (*set_asscii_font)(lcd_t *lcd, lcd_font *font); // 设置ASCIIå—体
void (*set_hz_font)(lcd_t *lcd, lcd_font *font); // 设置汉å—å—体
// èŽ·å–æŽ¥å£
- uint8_t (*get_dir)(lcd_t *lcd); // èŽ·å–æ‰«ææ–¹å‘
- BOOL(*get_clear_flag)
- (lcd_t *lcd); // èŽ·å–æ¸…屿 ‡å¿—
+ uint8_t (*get_dir)(lcd_t *lcd); // èŽ·å–æ‰«ææ–¹å‘
+ BOOL (*get_clear_flag)(lcd_t *lcd); // èŽ·å–æ¸…屿 ‡å¿—
__IO BOOL idel; // 是å¦ç©ºé—²
} lcd_driver_t;
diff --git a/User/system/sgl/build.cmake b/User/system/sgl/build.cmake
new file mode 100644
index 0000000..602234f
--- /dev/null
+++ b/User/system/sgl/build.cmake
@@ -0,0 +1,28 @@
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+include(${CMAKE_CURRENT_LIST_DIR}/core/build.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/draw/build.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/fonts/build.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/mm/build.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/widgets/build.cmake)
diff --git a/User/system/sgl/core/build.cmake b/User/system/sgl/core/build.cmake
new file mode 100644
index 0000000..6aa7611
--- /dev/null
+++ b/User/system/sgl/core/build.cmake
@@ -0,0 +1,33 @@
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_core.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_log.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_math.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_event.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_anim.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_snprintf.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_misc.c
+)
diff --git a/User/system/sgl/core/lm.cfg b/User/system/sgl/core/lm.cfg
new file mode 100644
index 0000000..277468b
--- /dev/null
+++ b/User/system/sgl/core/lm.cfg
@@ -0,0 +1,31 @@
+# source/core/lm.cfg
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+SRC += sgl_core.c
+SRC += sgl_log.c
+SRC += sgl_math.c
+SRC += sgl_event.c
+SRC += sgl_anim.c
+SRC += sgl_misc.c
+SRC += sgl_snprintf.c
diff --git a/User/system/sgl/core/sgl_anim.c b/User/system/sgl/core/sgl_anim.c
new file mode 100644
index 0000000..7775935
--- /dev/null
+++ b/User/system/sgl/core/sgl_anim.c
@@ -0,0 +1,422 @@
+/* source/core/sgl_anim.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+
+#if (CONFIG_SGL_ANIMATION)
+
+sgl_anim_ctx_t sgl_anim_ctx = {
+ .anim_list_head = NULL,
+ .anim_list_tail = NULL,
+};
+
+
+/**
+ * @brief Animation static initialization
+ * @param anim - Animation object
+ * @return none
+ */
+void sgl_anim_init(sgl_anim_t *anim)
+{
+ anim->next = NULL;
+ anim->data = NULL;
+ anim->act_delay = 0;
+ anim->act_duration = 0;
+ anim->start_value = 0;
+ anim->end_value = 0;
+
+ anim->path_cb = NULL;
+ anim->path_algo = NULL;
+
+ anim->finish_cb = NULL;
+ anim->auto_free = 0;
+ anim->finished = 1;
+}
+
+
+/**
+ * @brief dynamic alloc animation object with initialization
+ * @param none
+ * @return animation object
+*/
+sgl_anim_t* sgl_anim_create(void)
+{
+ sgl_anim_t *anim = sgl_malloc(sizeof(sgl_anim_t));
+ if (anim == NULL) {
+ SGL_LOG_ERROR("sgl_anim_create: malloc failed");
+ return NULL;
+ }
+
+ sgl_anim_init(anim);
+ return anim;
+}
+
+
+/**
+ * @brief add animation object to animation list
+ * @param anim animation object
+ * @return none
+*/
+static void sgl_anim_add(sgl_anim_t *anim)
+{
+ if (sgl_anim_ctx.anim_list_tail != NULL) {
+ sgl_anim_ctx.anim_list_tail->next = anim;
+ sgl_anim_ctx.anim_list_tail = anim;
+ }
+ else {
+ sgl_anim_ctx.anim_list_head = anim;
+ sgl_anim_ctx.anim_list_tail = anim;
+ }
+
+ anim->next = NULL;
+ anim->finished = 0;
+}
+
+
+/**
+ * @brief remove animation object from animation list
+ * @param anim animation object
+ * @return none
+*/
+static void sgl_anim_remove(sgl_anim_t *anim)
+{
+ SGL_ASSERT(anim != NULL);
+ sgl_anim_t *prev = NULL;
+
+ if (sgl_anim_ctx.anim_list_head == anim) {
+ sgl_anim_ctx.anim_list_head = anim->next;
+ if (sgl_anim_ctx.anim_list_head == NULL) {
+ sgl_anim_ctx.anim_list_tail = NULL;
+ }
+ return;
+ }
+
+ prev = sgl_anim_ctx.anim_list_head;
+ while (prev != NULL && prev->next != anim) {
+ prev = prev->next;
+ }
+
+ if (prev == NULL) {
+ return;
+ }
+ prev->next = anim->next;
+
+ if (anim == sgl_anim_ctx.anim_list_tail) {
+ sgl_anim_ctx.anim_list_tail = prev;
+ }
+}
+
+
+/**
+ * @brief start animation
+ * @param anim animation object
+ * @para repeat_cnt repeat count of animation
+ * @return none
+*/
+void sgl_anim_start(sgl_anim_t *anim, uint32_t repeat_cnt)
+{
+ SGL_ASSERT(anim != NULL);
+ if (anim->finished && repeat_cnt) {
+ sgl_anim_add(anim);
+ anim->finished = 0;
+ }
+
+ anim->act_delay = sgl_tick_get();
+ anim->repeat_cnt = repeat_cnt & SGL_ANIM_REPEAT_LOOP;
+}
+
+
+/**
+ * @brief stop animation
+ * @param anim animation object
+ * @return none
+*/
+void sgl_anim_stop(sgl_anim_t *anim)
+{
+ SGL_ASSERT(anim != NULL);
+ if (!anim->finished) {
+ sgl_anim_remove(anim);
+ anim->finished = 1;
+ }
+ anim->act_delay = 0;
+}
+
+
+/**
+ * @brief delete animation object
+ * @param anim animation object
+ * @return none
+*/
+void sgl_anim_delete(sgl_anim_t *anim)
+{
+ SGL_ASSERT(anim != NULL);
+ if (!anim->finished) {
+ sgl_anim_stop(anim);
+ }
+ sgl_free(anim);
+}
+
+
+/**
+ * @brief animation task, it will foreach all animation
+ * @param none
+ * @return none
+ * @note this function should be called in sgl_task()
+ */
+void sgl_anim_task(void)
+{
+ int32_t value = 0;
+ uint32_t elaps_time = 0, act_time = 0;
+ sgl_anim_t *anim = sgl_anim_ctx.anim_list_head, *next = NULL;
+
+ while (anim != NULL) {
+ act_time = sgl_tick_get();
+
+ if(act_time < anim->act_delay) {
+ continue;
+ }
+
+ elaps_time = act_time - anim->act_delay;
+
+ /* check callback function for debug */
+ SGL_ASSERT(anim->path_cb != NULL);
+ SGL_ASSERT(anim->path_algo != NULL);
+ value = anim->path_algo(sgl_min(elaps_time, anim->act_duration), anim->act_duration, anim->start_value, anim->end_value);
+ anim->path_cb(anim, value);
+
+ if (elaps_time > anim->act_duration) {
+ if (anim->repeat_cnt != SGL_ANIM_REPEAT_LOOP) {
+ anim->repeat_cnt--;
+ }
+
+ if (anim->finish_cb) {
+ anim->finish_cb(anim);
+ }
+
+ /* remove anim object if repeat count is 0 */
+ if (anim->repeat_cnt == 0) {
+ sgl_anim_stop(anim);
+
+ /* if animation is auto free, free it */
+ if (anim->auto_free) {
+ next = anim->next;
+ sgl_free(anim);
+ anim = next;
+ continue;
+ }
+ }
+
+ anim->act_delay += anim->act_duration;
+ }
+
+ anim = anim->next;
+ }
+}
+
+
+/**
+ * Linear animation path calculation function
+ *
+ * Calculates the current interpolated value based on elapsed time and total duration
+ * using linear interpolation.
+ *
+ * @param elaps Elapsed time in milliseconds
+ * @param duration Total animation duration in milliseconds
+ * @param start Start value
+ * @param end End value
+ *
+ * @return The interpolated value for the current time
+ *
+ * @note Returns 'end' if elaps >= duration (animation finished)
+ * Returns 'start' if elaps == 0 (animation just started)
+ * Uses 32-bit integer arithmetic to avoid floating-point operations
+ * for better performance on embedded systems
+ */
+int32_t sgl_anim_path_linear(uint32_t elaps, uint32_t duration, int32_t start, int32_t end)
+{
+ int64_t progress_fixed, delta, result;
+
+ // If duration is zero or elapsed time exceeds duration, return end value
+ if (duration == 0 || elaps >= duration) {
+ return (int32_t)end;
+ }
+
+ // If no time has elapsed, return start value
+ if (elaps == 0) {
+ return (int32_t)start;
+ }
+
+ // Calculate progress (elaps / duration) as a fixed-point number with 16 fractional bits
+ // Use 64-bit intermediate to prevent overflow during multiplication
+ progress_fixed = ((int64_t)elaps << 16) / duration;
+
+ // Calculate the difference between end and start
+ delta = end - start;
+
+ // Compute the interpolated result: start + delta * (elaps/duration)
+ // Right-shift by 16 to scale back from fixed-point representation
+ result = start + ((delta * progress_fixed) >> 16);
+
+ return result;
+}
+
+
+/**
+ * sgl_anim_path_ease_in_out - Cubic ease-in-out animation path
+ *
+ * This function creates a smooth animation curve that starts slow,
+ * accelerates in the middle, and decelerates at the end.
+ *
+ * @param elaps Elapsed time (ms)
+ * @param duration Total animation duration (ms)
+ * @param start Start value
+ * @param end End value
+ * @return Interpolated value at current time
+ */
+int32_t sgl_anim_path_ease_in_out(uint32_t elaps, uint32_t duration, int32_t start, int32_t end)
+{
+ int32_t t_180, cos_val, delta;
+ if (elaps >= duration)
+ return end;
+ if (elaps == 0)
+ return start;
+
+ t_180 = (elaps * 180) / duration;
+
+ if (t_180 <= 90) {
+ cos_val = sgl_sin(90 - t_180);
+ } else {
+ cos_val = -sgl_sin(t_180 - 90);
+ }
+
+ // Now: progress = 0.5 * (1 - cos_val/1000) = (1000 - cos_val) / 2000
+ // So: result = start + (end - start) * (1000 - cos_val) / 2000
+ delta = end - start;
+ return start + (delta * (32767 - cos_val)) / 65535;
+}
+
+
+/**
+ * sgl_anim_path_ease_out - Cubic ease-in animation path
+ *
+ * This function creates a smooth animation curve that starts accelerates,
+ * it will be slow in the after
+ *
+ * @param elaps Elapsed time (ms)
+ * @param duration Total animation duration (ms)
+ * @param start Start value
+ * @param end End value
+ * @return Interpolated value at current time
+ */
+int32_t sgl_anim_path_ease_out(uint32_t elaps, uint32_t duration, int32_t start, int32_t end)
+{
+ int32_t angle, sin_val, delta;
+ if (elaps >= duration)
+ return end;
+ if (elaps == 0)
+ return start;
+
+ // t ∈ [0, 90] degrees: sin(t * 90 / duration)
+ angle = (elaps * 90) / duration;
+ sin_val = sgl_sin(angle); // Assume returns 0 ~ 65535 or Q15
+
+ // If sgl_sin returns ×1000 (e.g., sin(90) = 32767)
+ delta = end - start;
+ return start + ((delta * sin_val) >> 15);
+}
+
+
+/**
+ * sgl_anim_path_ease_in - Cubic ease-in animation path
+ *
+ * This function creates a smooth animation curve that starts accelerates,
+ * accelerates in the after
+ *
+ * @param elaps Elapsed time (ms)
+ * @param duration Total animation duration (ms)
+ * @param start Start value
+ * @param end End value
+ * @return Interpolated value at current time
+ */
+int32_t sgl_anim_path_ease_in(uint32_t elaps, uint32_t duration, int32_t start, int32_t end)
+{
+ int32_t angle, cos_val, delta;
+ if (elaps >= duration)
+ return end;
+ if (elaps == 0)
+ return start;
+
+ // t ∈ [0, 90] degrees: sin(t * 90 / duration)
+ angle = (elaps * 90) / duration;
+ cos_val = sgl_cos(angle); // Assume returns 0 ~ 65535 or Q15
+
+ // If sgl_sin returns ×1000 (e.g., sin(90) = 32767)
+ delta = end - start;
+ return start + ((delta * (32767 - cos_val)) >> 15);
+}
+
+
+/**
+ * sgl_anim_path_overshoot - Overshoot animation path
+ *
+ * This function creates an animation curve that overshoots the target end value
+ * slightly before settling back to it, creating a natural "bounce" or "spring-like"
+ * effect for a more dynamic and realistic animation.
+ *
+ * @param elaps Elapsed time (ms) since the animation started
+ * @param duration Total animation duration (ms)
+ * @param start Initial value of the animated property at the start of the animation
+ * @param end Target end value of the animated property
+ * @return Interpolated value of the animated property at the current elapsed time
+ */
+int32_t sgl_anim_path_overshoot(uint32_t elaps, uint32_t duration, int32_t start, int32_t end)
+{
+ int64_t t, t1, t2, inv_t2, ease_back, diff, progress;
+ if (elaps >= duration)
+ return end;
+
+ t = (int64_t)elaps * 16384 / duration;
+ diff = end - start;
+
+ if (t < 11468) {
+ t1 = t * 16384 / 11468;
+ progress = (t1 * (32768 - t1)) >> 14;
+ progress = (progress * 18841) >> 14;
+ }
+ else {
+ t2 = (t - 11468) * 16384 / (16384 - 11468);
+ inv_t2 = 16384 - t2;
+ ease_back = (inv_t2 * inv_t2) >> 14;
+ progress = 16384 + (ease_back * (18841 - 16384) >> 14);
+ }
+
+ return start + (int32_t)((diff * progress) >> 14);
+}
+
+#endif // !CONFIG_SGL_ANIMATION
diff --git a/User/system/sgl/core/sgl_core.c b/User/system/sgl/core/sgl_core.c
new file mode 100644
index 0000000..5b28866
--- /dev/null
+++ b/User/system/sgl/core/sgl_core.c
@@ -0,0 +1,1611 @@
+/* source/core/sgl_core.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* current sgl system variable, do not used it */
+sgl_system_t sgl_system;
+
+
+/**
+ * @brief Alpha blending table for 4 bpp and 2 bpp
+ */
+const uint8_t sgl_opa4_table[16] = {0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 };
+const uint8_t sgl_opa2_table[4] = {0, 85, 170, 255};
+
+
+/**
+ * the memory pool, it will be used to allocate memory for the page pool
+*/
+static uint8_t sgl_mem_pool[CONFIG_SGL_HEAP_MEMORY_SIZE];
+
+
+/**
+ * @brief register the frame buffer device
+ * @param fbinfo the frame buffer device information
+ * @return int, 0 if success, -1 if failed
+ * @note you must check the result of this function
+ */
+int sgl_fbdev_register(sgl_fbinfo_t *fbinfo)
+{
+ sgl_check_ptr_return(fbinfo, -1);
+
+ if (fbinfo->buffer[0] == NULL) {
+ SGL_LOG_ERROR("You haven't set up the frame buffer.");
+ SGL_ASSERT(0);
+ return -1;
+ }
+
+ if (fbinfo->flush_area == NULL) {
+ SGL_LOG_ERROR("You haven't set up the flush area.");
+ SGL_ASSERT(0);
+ return -1;
+ }
+
+ if (fbinfo->buffer_size == 0) {
+ SGL_LOG_ERROR("You haven't set up the frame buffer size.");
+ SGL_ASSERT(0);
+ return -1;
+ }
+
+ sgl_system.fbdev.fbinfo = *fbinfo;
+
+ sgl_system.fbdev.surf.buffer = (sgl_color_t*)fbinfo->buffer[0];
+ sgl_system.fbdev.surf.x1 = 0;
+ sgl_system.fbdev.surf.y1 = 0;
+ sgl_system.fbdev.surf.x2 = fbinfo->xres - 1;
+ sgl_system.fbdev.surf.y2 = fbinfo->yres - 1;
+ sgl_system.fbdev.surf.size = fbinfo->buffer_size;
+ sgl_system.fbdev.surf.w = fbinfo->xres;
+
+ sgl_system.tick_ms = 0;
+ sgl_system.fbdev.fb_status = 3;
+ sgl_system.fbdev.fb_swap = 0;
+
+ return 0;
+}
+
+
+/**
+ * @brief get pixmap bytes of per pixel
+ * @param pixmap pointer to pixmap
+ * @return pixmap bytes of per pixel
+ */
+uint8_t sgl_pixmal_get_bytes_per_pixel(const sgl_pixmap_t *pixmap)
+{
+ static const uint8_t s_bytes_per_pixel[] = {
+ [SGL_PIXMAP_FMT_NONE] = sizeof(sgl_color_t),
+ [SGL_PIXMAP_FMT_RGB332] = 1,
+ [SGL_PIXMAP_FMT_ARGB2222] = 1,
+ [SGL_PIXMAP_FMT_RLE_RGB332] = 1,
+ [SGL_PIXMAP_FMT_RLE_ARGB2222] = 1,
+ [SGL_PIXMAP_FMT_RGB565] = 2,
+ [SGL_PIXMAP_FMT_ARGB4444] = 2,
+ [SGL_PIXMAP_FMT_RLE_RGB565] = 2,
+ [SGL_PIXMAP_FMT_RLE_ARGB4444] = 2,
+ [SGL_PIXMAP_FMT_RGB888] = 3,
+ [SGL_PIXMAP_FMT_RLE_RGB888] = 3,
+ [SGL_PIXMAP_FMT_ARGB8888] = 4,
+ [SGL_PIXMAP_FMT_RLE_ARGB8888] = 4,
+ };
+
+ SGL_ASSERT(pixmap != NULL);
+ if (pixmap->format >= sizeof(s_bytes_per_pixel)) {
+ SGL_LOG_ERROR("pixmap format error");
+ return 0;
+ }
+ return s_bytes_per_pixel[pixmap->format];
+}
+
+
+/**
+ * @brief add object to parent
+ * @param parent: pointer of parent object
+ * @param obj: pointer of object
+ * @return none
+ */
+void sgl_obj_add_child(sgl_obj_t *parent, sgl_obj_t *obj)
+{
+ SGL_ASSERT(parent != NULL && obj != NULL);
+ sgl_obj_t *tail = parent->child;
+
+ if (parent->child) {
+ while (tail->sibling != NULL) {
+ tail = tail->sibling;
+ };
+ tail->sibling = obj;
+ }
+ else {
+ parent->child = obj;
+ }
+
+ obj->parent = parent;
+}
+
+
+/**
+ * @brief remove an object from its parent
+ * @param obj object to remove
+ * @return none
+ * @note This function will remove the object from its parent, of course, his children will also be removed
+ */
+void sgl_obj_remove(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+
+ sgl_obj_t *parent = obj->parent;
+ sgl_obj_t *pos = NULL;
+
+ if (parent->child != obj) {
+ pos = parent->child;
+ while (pos->sibling != obj) {
+ pos = pos->sibling;
+ }
+ pos->sibling = obj->sibling;
+ }
+ else {
+ parent->child = obj->sibling;
+ }
+
+ obj->sibling = NULL;
+}
+
+
+/**
+ * @brief move object child position
+ * @param obj point to object
+ * @param ofs_x: x offset position
+ * @param ofs_y: y offset position
+ * @return none
+ */
+void sgl_obj_move_child_pos(sgl_obj_t *obj, int16_t ofs_x, int16_t ofs_y)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_obj_t *stack[SGL_OBJ_DEPTH_MAX];
+ int top = 0;
+
+ if (obj->child == NULL) {
+ return;
+ }
+ stack[top++] = obj->child;
+
+ while (top > 0) {
+ SGL_ASSERT(top < SGL_OBJ_DEPTH_MAX);
+ obj = stack[--top];
+
+ obj->dirty = 1;
+ obj->coords.x1 += ofs_x;
+ obj->coords.x2 += ofs_x;
+ obj->coords.y1 += ofs_y;
+ obj->coords.y2 += ofs_y;
+
+ if (obj->sibling != NULL) {
+ stack[top++] = obj->sibling;
+ }
+
+ if (obj->child != NULL) {
+ stack[top++] = obj->child;
+ }
+ }
+}
+
+
+/**
+ * @brief Set object absolute position
+ * @param obj point to object
+ * @param abs_x: x absolute position
+ * @param abs_y: y absolute position
+ * @return none
+ */
+void sgl_obj_set_abs_pos(sgl_obj_t *obj, int16_t abs_x, int16_t abs_y)
+{
+ SGL_ASSERT(obj != NULL);
+ int16_t x_diff = abs_x - obj->coords.x1;
+ int16_t y_diff = abs_y - obj->coords.y1;
+
+ obj->dirty = 1;
+ obj->coords.x1 += x_diff;
+ obj->coords.x2 += x_diff;
+ obj->coords.y1 += y_diff;
+ obj->coords.y2 += y_diff;
+
+ sgl_obj_move_child_pos(obj, x_diff, y_diff);
+}
+
+
+/**
+ * @brief zoom object size
+ * @param obj point to object
+ * @param zoom zoom size
+ * @return none
+ * @note if you want to zoom out, the zoom should be positive, if you want to zoom in, the zoom should be negative
+ */
+void sgl_obj_size_zoom(sgl_obj_t *obj, int16_t zoom)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->coords.x1 -= zoom;
+ obj->coords.x2 += zoom;
+ obj->coords.y1 -= zoom;
+ obj->coords.y2 += zoom;
+}
+
+
+/**
+ * @brief move object up a level layout
+ * @param obj point to object
+ * @return none
+ * @note Only move among sibling objects
+ */
+void sgl_obj_move_up(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_obj_t *parent = obj->parent;
+ sgl_obj_t *prev = NULL;
+ sgl_obj_t *next = NULL;
+
+ /* if the object is the last child, do not move it */
+ if (obj->sibling == NULL) {
+ return;
+ }
+ else if (parent->child == obj) {
+ parent->child = obj->sibling;
+ obj->sibling = obj->sibling->sibling;
+ /* mark object as dirty */
+ sgl_obj_set_dirty(obj);
+ return;
+ }
+
+ /* move the object to its next sibling */
+ sgl_obj_for_each_child(prev, parent) {
+ if (prev->sibling == obj) {
+ next = obj->sibling;
+ obj->sibling = next->sibling;
+ prev->sibling = next;
+ next->sibling = obj;
+ /* mark object as dirty */
+ sgl_obj_set_dirty(obj);
+ return;
+ }
+ }
+}
+
+
+/**
+ * @brief move object down a level layout
+ * @param obj point to object
+ * @return none
+ * @note Only move among sibling objects
+ */
+void sgl_obj_move_down(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_obj_t *parent = obj->parent;
+ sgl_obj_t *prev_prev = NULL;
+ sgl_obj_t *prev = NULL;
+
+ if (parent->child == obj) {
+ return;
+ }
+
+ // Find the previous sibling node (prev) and the node before it (prev_prev)
+ sgl_obj_for_each_child(prev, parent) {
+ if (prev->sibling == obj) {
+ break;
+ }
+ prev_prev = prev;
+ }
+
+ if (prev != NULL) {
+ if (prev_prev != NULL) {
+ prev_prev->sibling = obj;
+ }
+ else {
+ parent->child = obj;
+ }
+
+ prev->sibling = obj->sibling;
+ obj->sibling = prev;
+ sgl_obj_set_dirty(obj);
+ }
+}
+
+
+/**
+ * @brief move object top level layout
+ * @param obj point to object
+ * @return none
+ * @note Only move among sibling objects
+ */
+void sgl_obj_move_top(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL && obj->parent != NULL);
+
+ sgl_obj_t *parent = obj->parent;
+ sgl_obj_t *prev = NULL, *curr = parent->child, *last = NULL;
+
+ /* if the object is the last child, do not move it */
+ if (obj->sibling == NULL) {
+ return;
+ }
+
+ while (curr != NULL && curr != obj) {
+ prev = curr;
+ curr = curr->sibling;
+ }
+
+ if (prev == NULL) {
+ parent->child = obj->sibling;
+ }
+ else {
+ prev->sibling = obj->sibling;
+ }
+
+ last = parent->child;
+ if (last == NULL) {
+ parent->child = obj;
+ obj->sibling = NULL;
+ }
+ else {
+ while (last->sibling != NULL) {
+ last = last->sibling;
+ }
+ last->sibling = obj;
+ obj->sibling = NULL;
+ }
+
+ sgl_obj_set_dirty(obj);
+}
+
+
+/**
+ * @brief move object bottom level layout
+ * @param obj point to object
+ * @return none
+ * @note Only move among sibling objects
+ */
+void sgl_obj_move_bottom(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_obj_t *parent = obj->parent;
+ sgl_obj_t *prev = NULL;
+
+ /* if the object is the first child, do not move it */
+ if (parent->child == obj) {
+ return;
+ }
+
+ sgl_obj_for_each_child(prev, parent) {
+ if (prev->sibling == obj) {
+ break;
+ }
+ }
+
+ prev->sibling = obj->sibling;
+ obj->sibling = parent->child;
+ parent->child = obj;
+ /* mark object as dirty */
+ sgl_obj_set_dirty(obj);
+}
+
+
+/**
+ * @brief get fix radius of object
+ * @param obj object
+ * @param radius: radius that you want to set
+ * @return none
+ * @note if radius is larger than object's width or height, fix radius will be returned
+ */
+void sgl_obj_set_radius(sgl_obj_t *obj, size_t radius)
+{
+ int16_t w = (obj->coords.x2 - obj->coords.x1 + 1);
+ int16_t h = (obj->coords.y2 - obj->coords.y1 + 1);
+ int16_t d_min = w > h ? h : w;
+
+ if ((int16_t)radius >= (d_min / 2)) {
+ radius = sgl_is_odd(d_min) ? d_min / 2 : (d_min - 1) / 2;
+ }
+
+ obj->radius = radius & 0xFFF;
+}
+
+
+#if (CONFIG_SGL_OBJ_USE_NAME && CONFIG_SGL_DEBUG)
+/**
+ * @brief print object name that include this all child
+ * @param obj point to object
+ * @return none
+ */
+void sgl_obj_print_name(sgl_obj_t *obj)
+{
+ int top = 0;
+ sgl_obj_t *stack[SGL_OBJ_DEPTH_MAX];
+ stack[top++] = obj;
+
+ while (top > 0) {
+ SGL_ASSERT(top < SGL_OBJ_DEPTH_MAX);
+ obj = stack[--top];
+
+ if (obj->name == NULL) {
+ SGL_LOG_INFO("[OBJ NAME]: %s", "NULL");
+ }
+ else {
+ SGL_LOG_INFO("[OBJ NAME]: %s", obj->name);
+ }
+
+ if (obj->sibling != NULL) {
+ stack[top++] = obj->sibling;
+ }
+
+ if (obj->child != NULL) {
+ stack[top++] = obj->child;
+ }
+ }
+}
+
+#endif
+
+
+/**
+ * @brief page construct callback function
+ * @param surf surface pointer
+ * @param obj page object
+ * @param evt event
+ * @return none
+ * @note evt not used
+ */
+static void sgl_page_construct_cb(sgl_surf_t *surf, sgl_obj_t* obj, sgl_event_t *evt)
+{
+ sgl_page_t *page = (sgl_page_t *)obj;
+ const sgl_pixmap_t *pixmap = page->pixmap;
+
+ if (evt->type == SGL_EVENT_DRAW_MAIN) {
+ if (pixmap == NULL) {
+ sgl_draw_fill_rect(surf, &obj->area, &obj->coords, 0, page->color, page->alpha);
+ }
+ else {
+ sgl_draw_fill_rect_pixmap(surf, &obj->area, &obj->coords, 0, pixmap, page->alpha);
+ }
+ }
+ else {
+ if (obj->event_fn) {
+ obj->event_fn(evt);
+ }
+ }
+}
+
+
+/**
+ * @brief set page background color
+ * @param obj point to object
+ * @param color background color
+ * @return none
+ */
+void sgl_page_set_color(sgl_obj_t* obj, sgl_color_t color)
+{
+ sgl_page_t* page = (sgl_page_t*)obj;
+ page->color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+
+/**
+ * @brief set page background pixmap
+ * @param obj point to object
+ * @param pixmap background pixmap
+ * @return none
+ */
+void sgl_page_set_pixmap(sgl_obj_t* obj, const sgl_pixmap_t *pixmap)
+{
+ sgl_page_t* page = (sgl_page_t*)obj;
+ page->pixmap = pixmap;
+ sgl_obj_set_dirty(obj);
+}
+
+
+/**
+ * @brief set page background alpha
+ * @param obj point to object
+ * @param alpha background alpha
+ * @return none
+ */
+void sgl_page_set_alpha(sgl_obj_t* obj, uint8_t alpha)
+{
+ sgl_page_t* page = (sgl_page_t*)obj;
+ page->alpha = alpha;
+ sgl_obj_set_dirty(obj);
+}
+
+
+/**
+ * @brief create a page
+ * @param none
+ * @return sgl_page_t* the page pointer
+ */
+static sgl_page_t* sgl_page_create(void)
+{
+ sgl_page_t *page = sgl_malloc(sizeof(sgl_page_t));
+ if (page == NULL) {
+ SGL_LOG_ERROR("sgl_page_create: malloc failed");
+ return NULL;
+ }
+
+ /* clear the page all fields */
+ memset(page, 0, sizeof(sgl_page_t));
+
+ sgl_obj_t *obj = &page->obj;
+
+ if (sgl_system.fbdev.fbinfo.buffer[0] == NULL) {
+ SGL_LOG_ERROR("sgl_page_create: framebuffer is NULL");
+ sgl_free(page);
+ return NULL;
+ }
+
+ page->color = SGL_THEME_DESKTOP;
+ page->alpha = SGL_ALPHA_MAX;
+
+ obj->parent = obj;
+ obj->clickable = 0;
+ obj->construct_fn = sgl_page_construct_cb;
+ obj->dirty = 1;
+ obj->page = 1;
+ obj->border = 0;
+ obj->coords = (sgl_area_t) {
+ .x1 = 0,
+ .y1 = 0,
+ .x2 = sgl_system.fbdev.fbinfo.xres - 1,
+ .y2 = sgl_system.fbdev.fbinfo.yres - 1,
+ };
+
+ obj->area = obj->coords;
+
+ /* init child list */
+ sgl_obj_node_init(&page->obj);
+
+ if (sgl_system.fbdev.active == NULL) {
+ sgl_system.fbdev.active = &page->obj;
+ }
+
+ return page;
+}
+
+
+/**
+ * @brief Create an object
+ * @param parent parent object
+ * @return sgl_obj_t
+ * @note if parent is NULL, the object will be as an new page
+ */
+sgl_obj_t* sgl_obj_create(sgl_obj_t *parent)
+{
+ sgl_obj_t *obj;
+
+ /* create page object */
+ if (parent == NULL) {
+ sgl_page_t *page = sgl_page_create();
+ if (page == NULL) {
+ SGL_LOG_ERROR("sgl_obj_create: create page failed");
+ return NULL;
+ }
+ obj = &page->obj;
+ return obj;
+ }
+ else {
+ obj = (sgl_obj_t*)sgl_malloc(sizeof(sgl_obj_t));
+ if (obj == NULL) {
+ SGL_LOG_ERROR("malloc failed");
+ return NULL;
+ }
+
+ obj->coords = parent->coords;
+ obj->parent = parent;
+ obj->event_fn = NULL;
+ obj->event_data = 0;
+ obj->construct_fn = NULL;
+ obj->dirty = 1;
+
+ /* init node */
+ sgl_obj_node_init(obj);
+ /* add the child into parent's child list */
+ sgl_obj_add_child(parent, obj);
+
+ return obj;
+ }
+}
+
+
+/**
+ * @brief initialize global dirty area
+ * @param none
+ * @return none
+ */
+static inline void sgl_dirty_area_init(void)
+{
+ sgl_system.fbdev.dirty_num = 0;
+}
+
+
+/**
+ * @brief sgl global initialization
+ * @param none
+ * @return int, 0 means success, others means failed
+ * @note you should call this function before using sgl and you should call this function after register framebuffer device
+ */
+int sgl_init(void)
+{
+ sgl_obj_t *obj = NULL;
+
+ /* init memory pool */
+ sgl_mm_init(sgl_mem_pool, sizeof(sgl_mem_pool));
+
+ /* initialize current context */
+ sgl_system.fbdev.active = NULL;
+
+ /* initialize dirty area */
+ sgl_dirty_area_init();
+
+ /* create a screen object for drawing */
+ obj = sgl_obj_create(NULL);
+ if (obj == NULL) {
+ SGL_LOG_ERROR("sgl_init: create screen object failed");
+ return -1;
+ }
+
+ /* if the rotation is not 0 or 180, we need to alloc a buffer for rotation */
+#if ((CONFIG_SGL_FBDEV_ROTATION != 0) || CONFIG_SGL_FBDEV_RUNTIME_ROTATION)
+ sgl_system.rotation = (sgl_color_t*)sgl_malloc(sgl_system.fbdev.fbinfo.buffer_size * sizeof(sgl_color_t));
+ if (sgl_system.rotation == NULL) {
+ SGL_LOG_ERROR("sgl_init: alloc rotation buffer failed");
+ return -1;
+ }
+#if (CONFIG_SGL_FBDEV_RUNTIME_ROTATION)
+ sgl_system.angle = 0;
+#endif
+#endif
+ /* create event queue */
+ if (sgl_event_queue_init()) {
+ SGL_LOG_ERROR("sgl_init: event queue init failed");
+ sgl_free(obj);
+ return -1;
+ }
+
+#if (CONFIG_SGL_BOOT_LOGO)
+ sgl_boot_logo();
+#endif
+ return 0;
+}
+
+
+/**
+ * @brief set current object as screen object
+ * @param obj object, that you want to set an object as active page
+ * @return none
+ */
+void sgl_screen_load(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_system.fbdev.active = obj;
+
+ /* initialize dirty area */
+ sgl_dirty_area_init();
+ sgl_obj_set_dirty(obj);
+}
+
+
+#if (CONFIG_SGL_FBDEV_RUNTIME_ROTATION)
+/**
+ * @brief set framebuffer device rotation angle
+ * @param angle [in] rotation angle, that is 0, 90, 180, 270
+ * @return none
+ * @note Rotation angle must be 0, 90, 180, 270
+ */
+void sgl_fbdev_set_angle(uint16_t angle)
+{
+ if (angle == sgl_system.angle) {
+ return;
+ }
+
+ const uint8_t cur_status = (sgl_system.angle == 0 || sgl_system.angle == 180) ? 0 :
+ (sgl_system.angle == 90 || sgl_system.angle == 270) ? 1 : 2;
+
+ const uint8_t new_status = (angle == 0 || angle == 180) ? 0 :
+ (angle == 90 || angle == 270) ? 1 : 2;
+
+ if (cur_status == 2 || new_status == 2) {
+ SGL_LOG_WARN("sgl_fbdev_set_angle: invalid angle");
+ return;
+ }
+
+ if (cur_status != new_status) {
+ sgl_swap(&sgl_system.fbdev.fbinfo.xres, &sgl_system.fbdev.fbinfo.yres);
+ }
+
+ sgl_system.angle = angle;
+ sgl_obj_set_dirty(sgl_system.fbdev.active);
+}
+#endif // !CONFIG_SGL_FBDEV_RUNTIME_ROTATION
+
+
+/**
+ * @brief Get area intersection between two areas
+ * @param area_a: area a
+ * @param area_b: area b
+ * @param clip: intersection area
+ * @return true: intersect, otherwise false
+ * @note: this function is unsafe, you should check the area_a and area_b and clip is not NULL by yourself
+ */
+bool sgl_area_clip(sgl_area_t *area_a, sgl_area_t *area_b, sgl_area_t *clip)
+{
+ SGL_ASSERT(area_a != NULL && area_b != NULL && clip != NULL);
+ if (area_b->y1 > area_a->y2 || area_b->y2 < area_a->y1 || area_b->x1 > area_a->x2 || area_b->x2 < area_a->x1) {
+ return false;
+ }
+
+ clip->x1 = sgl_max(area_a->x1, area_b->x1);
+ clip->x2 = sgl_min(area_a->x2, area_b->x2);
+ clip->y1 = sgl_max(area_a->y1, area_b->y1);
+ clip->y2 = sgl_min(area_a->y2, area_b->y2);
+
+ return true;
+}
+
+
+/**
+ * @brief clip area with another area
+ * @param clip [in][out] clip area
+ * @param area [in] area
+ * @return true if clip area is valid, otherwise two area is not overlapped
+ * @note: this function is unsafe, you should check the clip and area is not NULL by yourself
+ */
+bool sgl_area_selfclip(sgl_area_t *clip, sgl_area_t *area)
+{
+ SGL_ASSERT(clip != NULL && area != NULL);
+ if (area->y1 > clip->y2 || area->y2 < clip->y1 || area->x1 > clip->x2 || area->x2 < clip->x1) {
+ return false;
+ }
+
+ clip->x1 = sgl_max(clip->x1, area->x1);
+ clip->x2 = sgl_min(clip->x2, area->x2);
+ clip->y1 = sgl_max(clip->y1, area->y1);
+ clip->y2 = sgl_min(clip->y2, area->y2);
+
+ return true;
+}
+
+
+/**
+ * @brief Computes the total boundary expansion (in Manhattan distance) required to merge rectangle b into rectangle a.
+ *
+ * @param a[in] Pointer to the b rectangle
+ * @param b[in] Pointer to the a rectangle
+ * @return int32_t Total expansion amount (always non-negative)
+ */
+static inline int32_t sgl_area_growth(sgl_area_t *a, sgl_area_t *b)
+{
+ return (a->x1 - sgl_min(a->x1, b->x1)) + (sgl_max(a->x2, b->x2) - a->x2)
+ + (a->y1 - sgl_min(a->y1, b->y1)) + (sgl_max(a->y2, b->y2) - a->y2);
+}
+
+
+/**
+ * @brief Quickly determines if two rectangles are close enough to be merged.
+ *
+ * This fast heuristic is useful in performance-critical contexts (e.g., real-time segmentation or region merging)
+ * to avoid excessive fragmentation while preventing merges between distant regions.
+ *
+ * @param a[in] Pointer to the first rectangle
+ * @param b[in] Pointer to the second rectangle
+ * @return bool true if the rectangles are sufficiently close for merging; false otherwise
+ */
+static inline bool sgl_merge_determines(sgl_area_t* a, sgl_area_t* b)
+{
+ int16_t gap_x = (a->x1 > b->x2) ? (a->x1 - b->x2) : (b->x1 > a->x2) ? (b->x1 - a->x2) : 0;
+ int16_t gap_y = (a->y1 > b->y2) ? (a->y1 - b->y2) : (b->y1 > a->y2) ? (b->y1 - a->y2) : 0;
+ int16_t threshold = (sgl_min4(a->x2 - a->x1 + 1, a->y2 - a->y1 + 1, b->x2 - b->x1 + 1, b->y2 - b->y1 + 1) >> 2);
+
+ return (gap_x <= threshold) && (gap_y <= threshold);
+}
+
+
+/**
+ * @brief merge an area into global dirty area
+ *
+ * This function calculates how much rectangle 'a' would need to grow in each direction (left, right, top, bottom)
+ * to fully enclose both 'a' and 'b'. The result is the sum of the expansions along all four sides.
+ * Note: This is not the increase in area, th is a lightweight heuristic for merge cost in bounding-box algorithms.
+ *
+ * @param area [in] Pointer to the area
+ * @return none
+ */
+void sgl_dirty_area_push(sgl_area_t *area)
+{
+ SGL_ASSERT(area != NULL);
+ int32_t best_idx = -1, min_growth = INT32_MAX, growth = INT32_MAX;
+ /* skip invalid area */
+ if (area->x1 > area->x2 || area->y1 > area->y2) {
+ return;
+ }
+
+ if (sgl_system.fbdev.dirty_num == 0) {
+ sgl_system.fbdev.dirty[0] = *area;
+ sgl_system.fbdev.dirty_num = 1;
+ return;
+ }
+
+ for (uint8_t i = 0; i < sgl_system.fbdev.dirty_num; i++) {
+ if (sgl_merge_determines(&sgl_system.fbdev.dirty[i], area)) {
+ growth = sgl_area_growth(&sgl_system.fbdev.dirty[i], area);
+ if (growth == 0) {
+ /* already contains the area */
+ return;
+ }
+ else if (growth < min_growth) {
+ min_growth = growth;
+ best_idx = i;
+ }
+ }
+ }
+
+ if (best_idx >= 0) {
+ /* merge object area into best_idx dirty area */
+ sgl_area_selfmerge(&sgl_system.fbdev.dirty[best_idx], area);
+ return;
+ }
+
+ if (sgl_system.fbdev.dirty_num < SGL_DIRTY_AREA_NUM_MAX) {
+ /* add new dirty area */
+ sgl_system.fbdev.dirty[sgl_system.fbdev.dirty_num++] = *area;
+ } else {
+ /* merge object area into last dirty area */
+ sgl_area_selfmerge(&sgl_system.fbdev.dirty[SGL_DIRTY_AREA_NUM_MAX - 1], area);
+ }
+}
+
+
+/**
+ * @brief initialize object
+ * @param obj object
+ * @param parent parent object
+ * @return int, 0 means successful, -1 means failed
+ */
+int sgl_obj_init(sgl_obj_t *obj, sgl_obj_t *parent)
+{
+ SGL_ASSERT(obj != NULL);
+
+ if (parent == NULL) {
+ parent = sgl_screen_act();
+ if (parent == NULL) {
+ SGL_LOG_ERROR("sgl_obj_init: have no active page");
+ return -1;
+ }
+ }
+
+ /* set essential member */
+ obj->coords = parent->coords;
+ obj->parent = parent;
+ obj->event_fn = NULL;
+ obj->event_data = 0;
+ obj->construct_fn = NULL;
+ obj->dirty = 1;
+ obj->clickable = 0;
+
+ /* init object area to invalid */
+ sgl_area_init(&obj->area);
+
+ /* add the child into parent's child list */
+ sgl_obj_add_child(parent, obj);
+
+ return 0;
+}
+
+
+/**
+ * @brief free an object
+ * @param obj: object to free
+ * @retval none
+ * @note this function will free all the itself and children of the object
+ */
+void sgl_obj_free(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_obj_t *stack[SGL_OBJ_DEPTH_MAX];
+ int top = 0;
+ stack[top++] = obj;
+
+ while (top > 0) {
+ SGL_ASSERT(top < SGL_OBJ_DEPTH_MAX);
+ obj = stack[--top];
+
+ if (obj->sibling != NULL) {
+ stack[top++] = obj->sibling;
+ }
+
+ if (obj->child != NULL) {
+ stack[top++] = obj->child;
+ }
+
+ sgl_free(obj);
+ }
+}
+
+
+/**
+ * @brief Clear all dirty areas of the object and its children.
+ * @param[in] obj The object to clear.
+ * @return None
+ * @note This function is used to clear all dirty areas of the object and its children.
+ */
+void sgl_obj_clear_all_dirty(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_obj_t *stack[SGL_OBJ_DEPTH_MAX];
+ int top = 0;
+ stack[top++] = obj;
+
+ while (top > 0) {
+ SGL_ASSERT(top < SGL_OBJ_DEPTH_MAX);
+ obj = stack[--top];
+ obj->dirty = 0;
+
+ if (obj->sibling != NULL) {
+ stack[top++] = obj->sibling;
+ }
+
+ if (obj->child != NULL) {
+ stack[top++] = obj->child;
+ }
+ }
+}
+
+
+/**
+ * @brief delete object
+ * @param obj point to object
+ * @return none
+ * @note this function will set object and his childs to be destroyed, then next draw cycle, the object will be removed.
+ * if object is NULL, the all objects of active page will be delete, but the page object will not be deleted.
+ * if object is a page, the page object will be deleted and all its children will be deleted.
+ */
+void sgl_obj_delete(sgl_obj_t *obj)
+{
+ if (obj == NULL || obj == sgl_screen_act()) {
+ obj = sgl_screen_act();
+ if (obj->child) {
+ sgl_obj_free(obj->child);
+ }
+ sgl_obj_node_init(obj);
+ sgl_obj_set_dirty(obj);
+ return;
+ }
+ else if (obj->page == 1) {
+ sgl_obj_free(obj);
+ return;
+ }
+
+ sgl_obj_set_destroyed(obj);
+}
+
+
+/**
+ * @brief Convert UTF-8 string to Unicode
+ * @param utf8_str Pointer to the UTF-8 string to be converted
+ * @param p_unicode_buffer Pointer to the buffer where the converted Unicode will be stored
+ * @return The number of bytes in the UTF-8 string
+ */
+uint32_t sgl_utf8_to_unicode(const char *utf8_str, uint32_t *p_unicode_buffer)
+{
+ uint8_t* ptr = (uint8_t*)utf8_str;
+ if ((*ptr) < 0x80) { // 1-byte/7-bit ASCII
+ *p_unicode_buffer = ptr[0];
+ return 1;
+ }
+ else if (((*ptr) & 0xE0) == 0xC0) { // 2-byte
+ *p_unicode_buffer = (ptr[0] & 0x1F) << 6 | (ptr[1] & 0x3F);
+ return 2;
+ }
+ else if (((*ptr) & 0xF0) == 0xE0) { // 3-byte
+ *p_unicode_buffer = (ptr[0] & 0x0F) << 12 | (ptr[1] & 0x3F) << 6 | (ptr[2] & 0x3F);
+ return 3;
+ }
+ else if (((*ptr) & 0xF8) == 0xF0) { // 4-byte
+ *p_unicode_buffer = (ptr[0] & 0x07) << 18 | (ptr[1] & 0x3F) << 12 | (ptr[2] & 0x3F) << 6 | (ptr[3] & 0x3F);
+ return 4;
+ }
+ return 0;
+}
+
+
+/**
+ * @brief Search for the index of a Unicode character in the font table
+ * @param font Pointer to the font structure containing character data
+ * @param unicode Unicode of the character to be searched
+ * @return Index of the character in the font table
+ */
+uint32_t sgl_search_unicode_ch_index(const sgl_font_t *font, uint32_t unicode)
+{
+ uint32_t left = 0, right = 0, mid = 0;
+ uint32_t target = unicode;
+ const sgl_font_unicode_t *code = font->unicode;
+
+ for (uint32_t i = 1; i < font->unicode_num; i ++) {
+ if (target < (code->offset + code->len)) {
+ break;
+ }
+ code ++;
+ }
+
+ target -= code->offset;
+
+ if (code->list == NULL) {
+ if (target >= code->len) {
+ SGL_LOG_WARN("sgl_search_unicode_ch_index: [0x%x]unicode not found in font table", unicode);
+ return 0;
+ }
+ return target + code->tab_offset;
+ }
+
+ right = code->len - 1;
+ while (left <= right) {
+ mid = left + (right - left) / 2;
+
+ if (code->list[mid] == target) {
+ return mid + code->tab_offset;
+ }
+ else if (code->list[mid] < target) {
+ left = mid + 1;
+ }
+ else {
+ right = mid - 1;
+ }
+ }
+
+ SGL_LOG_WARN("sgl_search_unicode_ch_index: [0x%x]unicode not found in font table", unicode);
+ return 0;
+}
+
+
+/**
+ * @brief get the width of a string
+ * @param str string
+ * @param font sgl font
+ * @return width of string
+ */
+int32_t sgl_font_get_string_width(const char *str, const sgl_font_t *font)
+{
+ SGL_ASSERT(font != NULL);
+ int32_t len = 0;
+ uint32_t unicode = 0;
+ uint32_t ch_index = 0;
+ while (*str) {
+ str += sgl_utf8_to_unicode(str, &unicode);
+ ch_index = sgl_search_unicode_ch_index(font, unicode);
+ len += (font->table[ch_index].adv_w >> 4);
+ }
+ return len;
+}
+
+
+/**
+ * @brief get the height of a string, which is in a rect area
+ * @param width width of the rect area
+ * @param str string
+ * @param font sgl font of the string
+ * @param line_space peer line space
+ * @return height size of string
+ */
+int32_t sgl_font_get_string_height(int16_t width, const char *str, const sgl_font_t *font, uint8_t line_space)
+{
+ int16_t offset_x = 0;
+ int16_t ch_index;
+ int16_t ch_width;
+ int16_t lines = 1;
+ uint32_t unicode = 0;
+
+ while (*str) {
+ if (*str == '\n') {
+ lines ++;
+ offset_x = 0;
+ str ++;
+ continue;
+ }
+
+ str += sgl_utf8_to_unicode(str, &unicode);
+ ch_index = sgl_search_unicode_ch_index(font, unicode);
+
+ ch_width = (font->table[ch_index].adv_w >> 4);
+
+ if ((offset_x + ch_width) >= width) {
+ offset_x = 0;
+ lines ++;
+ }
+
+ offset_x += ch_width;
+ }
+
+ return lines * (font->font_height + line_space);
+}
+
+
+/**
+ * @brief get the alignment position
+ * @param parent_size parent size
+ * @param size object size
+ * @param type alignment type
+ * @return alignment position offset
+ */
+sgl_pos_t sgl_get_align_pos(sgl_size_t *parent_size, sgl_size_t *size, sgl_align_type_t type)
+{
+ SGL_ASSERT(parent_size != NULL && size != NULL);
+ sgl_pos_t ret = {.x = 0, .y = 0};
+
+ switch (type) {
+ case SGL_ALIGN_CENTER:
+ ret.x = (parent_size->w - size->w) / 2;
+ ret.y = (parent_size->h - size->h) / 2;
+ break;
+
+ case SGL_ALIGN_TOP_MID:
+ ret.x = (parent_size->w - size->w) / 2;
+ ret.y = 0;
+ break;
+
+ case SGL_ALIGN_TOP_LEFT:
+ ret.x = 0;
+ ret.y = 0;
+ break;
+
+ case SGL_ALIGN_TOP_RIGHT:
+ ret.x = parent_size->w - size->w;
+ ret.y = 0;
+ break;
+
+ case SGL_ALIGN_BOT_MID:
+ ret.x = (parent_size->w - size->w) / 2;
+ ret.y = parent_size->h - size->h;
+ break;
+
+ case SGL_ALIGN_BOT_LEFT:
+ ret.x = 0;
+ ret.y = parent_size->h - size->h;
+ break;
+
+ case SGL_ALIGN_BOT_RIGHT:
+ ret.x = parent_size->w - size->w;
+ ret.y = parent_size->h - size->h;
+ break;
+
+ case SGL_ALIGN_LEFT_MID:
+ ret.x = 0;
+ ret.y = (parent_size->h - size->h) / 2;
+ break;
+
+ case SGL_ALIGN_RIGHT_MID:
+ ret.x = parent_size->w - size->w;
+ ret.y = (parent_size->h - size->h) / 2;
+ break;
+
+ default: break;
+ }
+ return ret;
+}
+
+
+/**
+ * @brief get the text position in the area
+ * @param area point to area
+ * @param font point to font
+ * @param text text string
+ * @param offset text offset
+ * @param type alignment type
+ * @return sgl_pos_t position of text
+ */
+sgl_pos_t sgl_get_text_pos(sgl_area_t *area, const sgl_font_t *font, const char *text, int16_t offset, sgl_align_type_t type)
+{
+ SGL_ASSERT(area != NULL && font != NULL);
+ sgl_pos_t ret = {.x = 0, .y = 0};
+ sgl_size_t parent_size = {
+ .w = area->x2 - area->x1 + 1,
+ .h = area->y2 - area->y1 + 1,
+ };
+
+ sgl_size_t text_size = {
+ .w = sgl_font_get_string_width(text, font) + offset,
+ .h = sgl_font_get_height(font),
+ };
+
+ ret = sgl_get_align_pos(&parent_size, &text_size, type);
+ ret.x += area->x1;
+ ret.y += area->y1;
+
+ return ret;
+}
+
+
+/**
+ * @brief get the icon position of area
+ * @param area point to area
+ * @param icon point to icon
+ * @param offset offset
+ * @param type align type
+ */
+sgl_pos_t sgl_get_icon_pos(sgl_area_t *area, const sgl_icon_pixmap_t *icon, int16_t offset, sgl_align_type_t type)
+{
+ SGL_ASSERT(area != NULL && icon != NULL);
+ sgl_pos_t ret = {.x = 0, .y = 0};
+ sgl_size_t parent_size = {
+ .w = area->x2 - area->x1 + 1,
+ .h = area->y2 - area->y1 + 1,
+ };
+
+ sgl_size_t text_size = {
+ .w = icon->width + offset,
+ .h = icon->height,
+ };
+
+ ret = sgl_get_align_pos(&parent_size, &text_size, type);
+ ret.x += area->x1;
+ ret.y += area->y1;
+
+ return ret;
+}
+
+
+/**
+ * @brief Set the alignment position of the object relative to its parent object.
+ * @param obj The object to set the alignment position.
+ * @param type The alignment type.
+ * @return none
+ * @note type should be one of the sgl_align_type_t values:
+ * - SGL_ALIGN_CENTER : Center the object in the parent object.
+ * - SGL_ALIGN_TOP_MID : Align the object at the top middle of the parent object.
+ * - SGL_ALIGN_TOP_LEFT : Align the object at the top left of the parent object.
+ * - SGL_ALIGN_TOP_RIGHT : Align the object at the top right of the parent object.
+ * - SGL_ALIGN_BOT_MID : Align the object at the bottom middle of the parent object.
+ * - SGL_ALIGN_BOT_LEFT : Align the object at the bottom left of the parent object.
+ * - SGL_ALIGN_BOT_RIGHT : Align the object at the bottom right of the parent object.
+ * - SGL_ALIGN_LEFT_MID : Align the object at the left middle of the parent object.
+ * - SGL_ALIGN_RIGHT_MID : Align the object at the right middle of the parent object.
+ */
+void sgl_obj_set_pos_align(sgl_obj_t *obj, sgl_align_type_t type)
+{
+ SGL_ASSERT(obj != NULL);
+
+ sgl_size_t p_size = {0};
+ sgl_pos_t p_pos = {0};
+ sgl_pos_t obj_pos = {0};
+ sgl_size_t obj_size = {
+ .w = obj->coords.x2 - obj->coords.x1 + 1,
+ .h = obj->coords.y2 - obj->coords.y1 + 1,
+ };
+
+ p_size = (sgl_size_t){
+ .w = obj->parent->coords.x2 - obj->parent->coords.x1 + 1,
+ .h = obj->parent->coords.y2 - obj->parent->coords.y1 + 1,
+ };
+ p_pos = (sgl_pos_t){
+ .x = obj->parent->coords.x1,
+ .y = obj->parent->coords.y1,
+ };
+
+ obj_pos = sgl_get_align_pos(&p_size, &obj_size, type);
+
+ sgl_obj_set_abs_pos(obj, p_pos.x + obj_pos.x, p_pos.y + obj_pos.y);
+}
+
+
+/**
+ * @brief Set the alignment position of the object relative to sibling object.
+ * @param ref The reference object, it should be the sibling object.
+ * @param obj The object to set the alignment position.
+ * @param type The alignment type.
+ * @return none
+ * @note type should be one of the sgl_align_type_t values:
+ * - SGL_ALIGN_VERT_LEFT : Align the object at the left side of the reference object.
+ * - SGL_ALIGN_VERT_RIGHT : Align the object at the right side of the reference object.
+ * - SGL_ALIGN_VERT_MID : Align the object at the middle of the reference object.
+ * - SGL_ALIGN_HORIZ_TOP : Align the object at the top side of the reference object.
+ * - SGL_ALIGN_HORIZ_BOT : Align the object at the bottom side of the reference object.
+ * - SGL_ALIGN_HORIZ_MID : Align the object at the middle of the reference object.
+ */
+void sgl_obj_set_pos_align_ref(sgl_obj_t *ref, sgl_obj_t *obj, sgl_align_type_t type)
+{
+ SGL_ASSERT(ref != NULL && obj != NULL);
+
+ if (unlikely(ref == obj->parent)) {
+ sgl_obj_set_pos_align(obj, type);
+ return;
+ }
+
+ int16_t ref_w = ref->coords.x2 - ref->coords.x1 + 1;
+ int16_t obj_w = obj->coords.x2 - obj->coords.x1 + 1;
+ int16_t ref_h = ref->coords.y2 - ref->coords.y1 + 1;
+ int16_t obj_h = obj->coords.y2 - obj->coords.y1 + 1;
+
+ switch (type) {
+ case SGL_ALIGN_VERT_MID:
+ obj->coords.x1 = ref->coords.x1 + (ref_w - obj_w) / 2;
+ obj->coords.x2 = obj->coords.x1 + obj_w - 1;
+ break;
+
+ case SGL_ALIGN_VERT_LEFT:
+ obj->coords.x1 = ref->coords.x1;
+ obj->coords.x2 = obj->coords.x1 + obj_w - 1;
+ break;
+
+ case SGL_ALIGN_VERT_RIGHT:
+ obj->coords.x1 = ref->coords.x2 - obj_w;
+ obj->coords.x2 = obj->coords.x1 + obj_w - 1;
+ break;
+
+ case SGL_ALIGN_HORIZ_MID:
+ obj->coords.y1 = ref->coords.y1 + (ref_h - obj_h) / 2;
+ obj->coords.y2 = obj->coords.y1 + obj_h - 1;
+ break;
+
+ case SGL_ALIGN_HORIZ_TOP:
+ obj->coords.y1 = ref->coords.y1;
+ obj->coords.y2 = obj->coords.y1 + obj_h - 1;
+ break;
+
+ case SGL_ALIGN_HORIZ_BOT:
+ obj->coords.y1 = ref->coords.y2 - obj_h;
+ obj->coords.y2 = obj->coords.y1 + obj_h - 1;
+ break;
+
+ default:
+ SGL_LOG_WARN("invalid align type");
+ break;
+ }
+}
+
+
+/**
+ * @brief draw object slice completely
+ * @param obj it should point to active root object
+ * @param surf surface that draw to
+ * @param dirty_h dirty height
+ * @return none
+ */
+static inline void draw_obj_slice(sgl_obj_t *obj, sgl_surf_t *surf)
+{
+ int top = 0;
+ sgl_event_t evt;
+ sgl_obj_t *stack[SGL_OBJ_DEPTH_MAX];
+
+ SGL_ASSERT(obj != NULL);
+ stack[top++] = obj;
+
+ while (top > 0) {
+ SGL_ASSERT(top < SGL_OBJ_DEPTH_MAX);
+ obj = stack[--top];
+
+ if (obj->sibling != NULL) {
+ stack[top++] = obj->sibling;
+ }
+
+ if (sgl_obj_is_hidden(obj)) {
+ continue;
+ }
+
+ if (sgl_surf_area_is_overlap(surf, &obj->area)) {
+ evt.type = SGL_EVENT_DRAW_MAIN;
+ SGL_ASSERT(obj->construct_fn != NULL);
+ obj->construct_fn(surf, obj, &evt);
+
+ if (obj->child != NULL) {
+ stack[top++] = obj->child;
+ }
+ }
+ }
+
+ /* flush dirty area into screen */
+ sgl_fbdev_flush_area((sgl_area_t*)surf, surf->buffer);
+}
+
+
+/**
+ * @brief calculate dirty area by for each all object that is dirty and visible
+ * @param obj it should point to active root object
+ * @return none
+ * @note if there is no dirty area, the dirty area will remain unchanged
+ */
+static inline void sgl_dirty_area_calculate(sgl_obj_t *obj)
+{
+ sgl_obj_t *stack[SGL_OBJ_DEPTH_MAX];
+ int top = 0;
+ stack[top++] = obj;
+
+ /* for each all object from the first task of page */
+ while (top > 0) {
+ SGL_ASSERT(top < SGL_OBJ_DEPTH_MAX);
+ obj = stack[--top];
+
+ /* if sibling exists, push it to stack, it will be pop in next loop */
+ if (obj->sibling != NULL) {
+ stack[top++] = obj->sibling;
+ }
+
+ /* if object is hidden, skip it */
+ if (unlikely(sgl_obj_is_hidden(obj))) {
+ continue;
+ }
+
+ /* check if obj is destroyed */
+ if (unlikely(sgl_obj_is_destroyed(obj))) {
+ /* merge destroy area */
+ sgl_dirty_area_push(&obj->area);
+
+ sgl_event_t evt = {
+ .type = SGL_EVENT_DESTROYED,
+ };
+
+ /* check construct function */
+ SGL_ASSERT(obj->construct_fn != NULL);
+ obj->construct_fn(NULL, obj, &evt);
+
+ /* remove obj from parent */
+ sgl_obj_remove(obj);
+
+ /* free obj resource */
+ sgl_obj_free(obj);
+
+ /* object is destroyed, skip */
+ continue;
+ }
+
+ /* check child need init coords */
+ if (unlikely(sgl_obj_is_needinit(obj))) {
+ sgl_event_t evt = {
+ .type = SGL_EVENT_DRAW_INIT,
+ };
+
+ /* check construct function */
+ SGL_ASSERT(obj->construct_fn != NULL);
+ obj->construct_fn(NULL, obj, &evt);
+ /* maybe no need to clear flag */
+ sgl_obj_clear_needinit(obj);
+ }
+
+ /* check child dirty and merge all dirty area */
+ if (sgl_obj_is_dirty(obj)) {
+ /* merge dirty area */
+ sgl_dirty_area_push(&obj->area);
+
+ sgl_area_t fill_area = sgl_obj_get_fill_rect(obj->parent);
+ /* update obj area */
+ if (unlikely(!sgl_area_clip(&fill_area, &obj->coords, &obj->area))) {
+ sgl_area_init(&obj->area);
+ sgl_obj_clear_dirty(obj);
+ continue;
+ }
+
+ /* merge dirty area */
+ sgl_dirty_area_push(&obj->area);
+
+ /* clear dirty flag */
+ sgl_obj_clear_dirty(obj);
+ }
+
+ if (obj->child != NULL) {
+ stack[top++] = obj->child;
+ }
+ }
+}
+
+
+/**
+ * @brief sgl to draw complete frame
+ * @param fbdev point to frame buffer device
+ * @return none
+ * @note this function should be called in deamon thread or cyclic thread
+ */
+static inline void sgl_draw_task(sgl_fbdev_t *fbdev)
+{
+ sgl_surf_t *surf = &fbdev->surf;
+ sgl_obj_t *head = fbdev->active;
+ sgl_area_t *dirty = NULL;
+
+ /* dirty area number must less than SGL_DIRTY_AREA_MAX */
+ for (int i = 0; i < fbdev->dirty_num; i++) {
+ dirty = &fbdev->dirty[i];
+ surf->dirty = dirty;
+
+#if (CONFIG_SGL_FBDEV_RUNTIME_ROTATION)
+ sgl_area_t screen = { .x1 = 0, .y1 = 0, .x2 = SGL_SCREEN_WIDTH - 1, .y2 = SGL_SCREEN_HEIGHT - 1 };
+ sgl_area_selfclip(dirty, &screen);
+#endif
+
+ /* check dirty area, ensure it is valid */
+ SGL_ASSERT(dirty != NULL && dirty->x1 >= 0 && dirty->y1 >= 0 && dirty->x2 < SGL_SCREEN_WIDTH && dirty->y2 < SGL_SCREEN_HEIGHT);
+
+#if (!CONFIG_SGL_USE_FBDEV_VRAM)
+
+ uint16_t draw_h = 0;
+ surf->h = dirty->y2 - dirty->y1 + 1;
+
+ surf->x1 = dirty->x1;
+ surf->y1 = dirty->y1;
+ surf->x2 = dirty->x2;
+ surf->w = surf->x2 - surf->x1 + 1;
+ surf->h = sgl_min(surf->size / surf->w, (uint32_t)(dirty->y2 - dirty->y1 + 1));
+
+ SGL_LOG_TRACE("[fb:%d]sgl_draw_task: dirty area x1:%d y1:%d x2:%d y2:%d", fbdev->fb_swap, dirty->x1, dirty->y1, dirty->x2, dirty->y2);
+
+ while (surf->y1 <= dirty->y2) {
+ draw_h = sgl_min(dirty->y2 - surf->y1 + 1, surf->h);
+ surf->y2 = surf->y1 + draw_h - 1;
+
+ /* wait current framebuffer for ready */
+ while (sgl_fbdev_flush_wait_ready(fbdev));
+
+ /* reset current framebuffer ready flag */
+ fbdev->fb_status = (fbdev->fb_status & (2 - fbdev->fb_swap));
+
+ /* draw object slice until the dirty area is finished */
+ draw_obj_slice(head, surf);
+ surf->y1 += draw_h;
+ }
+#else
+ /* check dirty area, ensure it is valid */
+ SGL_ASSERT(dirty != NULL && dirty->x1 >= 0 && dirty->y1 >= 0 && dirty->x2 < SGL_SCREEN_WIDTH && dirty->y2 < SGL_SCREEN_HEIGHT);
+
+ SGL_LOG_TRACE("[fb:%d]sgl_draw_task: dirty area x1:%d y1:%d x2:%d y2:%d", fbdev->fb_swap, dirty->x1, dirty->y1, dirty->x2, dirty->y2);
+ draw_obj_slice(head, surf);
+#endif
+ }
+ /* clear dirty area */
+ fbdev->dirty_num = 0;
+}
+
+
+/**
+ * @brief sgl task handle function with sync mode
+ * @param none
+ * @return none
+ * @note you can call this function for force update screen
+ */
+void sgl_task_handle_sync(void)
+{
+ /* event task */
+ sgl_event_task();
+
+#if (CONFIG_SGL_ANIMATION)
+ sgl_anim_task();
+#endif // !CONFIG_SGL_ANIMATION
+
+ /* foreach all object tree and calculate dirty area */
+ sgl_dirty_area_calculate(sgl_system.fbdev.active);
+
+ /* draw all object into screen */
+ sgl_draw_task(&sgl_system.fbdev);
+}
diff --git a/User/system/sgl/core/sgl_event.c b/User/system/sgl/core/sgl_event.c
new file mode 100644
index 0000000..d8a1afa
--- /dev/null
+++ b/User/system/sgl/core/sgl_event.c
@@ -0,0 +1,437 @@
+/* source/core/sgl_event.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* define event queue size */
+#define SGL_EVENT_QUEUE_SIZE (CONFIG_SGL_EVENT_QUEUE_SIZE)
+#define SGL_EVENT_QUEUE_SIZE_MASK (SGL_EVENT_QUEUE_SIZE - 1)
+
+/**
+ * @brief event queue struct
+ * @buffer: event buffer to save all event data
+ * @head: event queue head which is used to push event
+ * @tail: event queue tail which is used to pop event
+ * @count: event queue count which have been pushed
+ */
+typedef struct event_queue {
+ sgl_event_t buffer[SGL_EVENT_QUEUE_SIZE];
+ uint16_t head;
+ uint16_t tail;
+} event_queue_t;
+
+
+/**
+ * @brief event context struct
+ * @last_click: last click object which may be lost event
+ * @last_touch: last touch position
+ * @evtq: event queue
+ */
+static struct event_context {
+ struct sgl_obj *last_click;
+ sgl_event_pos_t last_touch;
+ event_queue_t evtq;
+} evt_ctx;
+
+
+/**
+ * @brief Initialize the event queue
+ * @param none
+ * @return 0 on success, -1 on failure
+ * @note !!!!!! the SGL_EVENT_QUEUE_SIZE must be power of 2 !!!!!!
+ * You must check the return value of this function.
+ */
+int sgl_event_queue_init(void)
+{
+ if (!sgl_is_pow2(SGL_EVENT_QUEUE_SIZE)) {
+ SGL_LOG_ERROR("The capacity must be power of 2");
+ return -1;
+ }
+
+ evt_ctx.evtq.head = evt_ctx.evtq.tail = 0;
+ return 0;
+}
+
+
+/**
+ * @brief Check whether the event queue is empty
+ * @param none
+ * @return true if the event queue is empty, false otherwise
+ */
+static inline bool sgl_event_queue_is_empty(void)
+{
+ return evt_ctx.evtq.head == evt_ctx.evtq.tail;
+}
+
+
+/**
+ * @brief Check whether the event queue is full
+ * @param none
+ * @return true if the event queue is full, false otherwise
+ */
+static inline bool sgl_event_queue_is_full(void)
+{
+ uint32_t next_head = (evt_ctx.evtq.head + 1) & SGL_EVENT_QUEUE_SIZE_MASK;
+ return next_head == evt_ctx.evtq.tail;
+}
+
+
+/**
+ * @brief Push an event into the event queue
+ * @param event The event to be pushed
+ * @return 0 on success, -1 on failure
+ */
+void sgl_event_queue_push(sgl_event_t event)
+{
+ if (unlikely(sgl_event_queue_is_full())) {
+ SGL_LOG_ERROR("Event queue is full, maybe system is too slow");
+ return;
+ }
+
+ evt_ctx.evtq.buffer[evt_ctx.evtq.head] = event;
+ evt_ctx.evtq.head = ((evt_ctx.evtq.head + 1) & SGL_EVENT_QUEUE_SIZE_MASK);
+}
+
+
+/**
+ * @brief Pop an event from the event queue
+ * @param out_event The event to be popped
+ * @return 0 on success, -1 on failure
+ */
+static inline int sgl_event_queue_pop(sgl_event_t* out_event)
+{
+ if (sgl_event_queue_is_empty()) {
+ return -1;
+ }
+
+ *out_event = evt_ctx.evtq.buffer[evt_ctx.evtq.tail];
+ evt_ctx.evtq.tail = ((evt_ctx.evtq.tail + 1) & SGL_EVENT_QUEUE_SIZE_MASK);
+ return 0;
+}
+
+
+/**
+ * @brief Check whether the position is focus on the object
+ * @param pos The position to be checked
+ * @param rect The rectangle of the object
+ * @param radius The radius of the object
+ * @return true if the position is focus on the object, false otherwise
+ */
+static bool pos_is_focus_on_obj(sgl_event_pos_t *pos, sgl_rect_t *rect, int16_t radius)
+{
+ if (pos->x < rect->x1 || pos->x > rect->x2 || pos->y < rect->y1 || pos->y > rect->y2) {
+ return false;
+ }
+ else if(radius == 0) {
+ return true;
+ }
+
+ if ((pos->x >= rect->x1 + radius) && (pos->x <= rect->x2 - radius)) {
+ return true;
+ }
+ else if ((pos->y >= rect->y1 + radius) && (pos->y <= rect->y2 - radius)) {
+ return true;
+ }
+
+ if (pos->x <= rect->x1 + radius && pos->y <= rect->y1 + radius) {
+ int16_t dx = pos->x - (rect->x1 + radius);
+ int16_t dy = pos->y - (rect->y1 + radius);
+ return sgl_pow2(dx) + sgl_pow2(dy) <= sgl_pow2(radius);
+ }
+ else if (pos->x >= rect->x2 - radius && pos->y <= rect->y1 + radius) {
+ int16_t dx = pos->x - (rect->x2 - radius);
+ int16_t dy = pos->y - (rect->y1 + radius);
+ return sgl_pow2(dx) + sgl_pow2(dy) <= sgl_pow2(radius);
+ }
+ else if (pos->x <= rect->x1 + radius && pos->y >= rect->y2 - radius) {
+ int16_t dx = pos->x - (rect->x1 + radius);
+ int16_t dy = pos->y - (rect->y2 - radius);
+ return sgl_pow2(dx) + sgl_pow2(dy) <= sgl_pow2(radius);
+ }
+ else if (pos->x >= rect->x2 - radius && pos->y >= rect->y2 - radius) {
+ int16_t dx = pos->x - (rect->x2 - radius);
+ int16_t dy = pos->y - (rect->y2 - radius);
+ return sgl_pow2(dx) + sgl_pow2(dy) <= sgl_pow2(radius);
+ }
+
+ return false;
+}
+
+
+/**
+ * @brief check whether the position is clicked on the object
+ * @param pos The position to be clicked
+ * @return The object that is clicked on, NULL if no object is clicked
+ */
+static struct sgl_obj* click_detect_object(sgl_event_pos_t *pos)
+{
+ struct sgl_obj *stack[SGL_OBJ_DEPTH_MAX], *obj = sgl_screen_act()->child, *find = NULL;
+ int top = 0;
+
+ if (unlikely(obj == NULL)) {
+ return NULL;
+ }
+ stack[top++] = obj;
+
+ while (top > 0) {
+ SGL_ASSERT(top < SGL_OBJ_DEPTH_MAX);
+ obj = stack[--top];
+ if (sgl_obj_has_sibling(obj)) {
+ stack[top++] = obj->sibling;
+ }
+
+ if (unlikely(sgl_obj_is_hidden(obj))) {
+ continue;
+ }
+
+ if (pos_is_focus_on_obj(pos, &obj->coords, obj->radius)) {
+ find = obj;
+ if (sgl_obj_has_child(obj)) {
+ stack[top++] = obj->child;
+ }
+ }
+ }
+
+ /**
+ * if the object is clickable, return it, otherwise return its parent
+ * because the object may be a label attached to the object
+ */
+ if (find != NULL) {
+ return sgl_obj_is_clickable(find) ? find : (sgl_obj_is_clickable(find->parent) ? find->parent : NULL);
+ }
+
+ return find;
+}
+
+
+/**
+ * @brief Handle the position event
+ * @param pos The position to be handled
+ * @param type The type of the event
+ * @return none
+ */
+void sgl_event_send_pos(sgl_event_pos_t pos, sgl_event_type_t type)
+{
+ sgl_event_t event = {
+ .obj = NULL,
+ .type = type,
+ .pos = pos,
+ };
+
+ if (type == SGL_EVENT_PRESSED) {
+ evt_ctx.last_touch = pos;
+ }
+
+ sgl_event_queue_push(event);
+}
+
+
+/**
+ * @brief get information of motion event type
+ * @param evt [in][out] event to be handled
+ * @return none
+ */
+static void sgl_get_move_info(sgl_event_t *evt)
+{
+ int16_t dx = evt->pos.x - evt_ctx.last_touch.x;
+ int16_t dy = evt->pos.y - evt_ctx.last_touch.y;
+
+ if (sgl_abs(dx) > sgl_abs(dy)) {
+ if (dx > 0) {
+ evt->type = SGL_EVENT_MOVE_RIGHT;
+ evt->distance = dx;
+ }
+ else {
+ evt->type = SGL_EVENT_MOVE_LEFT;
+ evt->distance = -dx;
+ }
+ }
+ else {
+ if (dy > 0) {
+ evt->type = SGL_EVENT_MOVE_DOWN;
+ evt->distance = dy;
+ }
+ else {
+ evt->type = SGL_EVENT_MOVE_UP;
+ evt->distance = -dy;
+ }
+ }
+
+ evt_ctx.last_touch = evt->pos;
+}
+
+
+/**
+ * @brief All event task in SGL, this function will traverse all elements in the event queue,
+ * respond to each element with an event, so that all events will trigger and point to the
+ * corresponding callback function
+ * @param none
+ * @return none
+*/
+void sgl_event_task(void)
+{
+ sgl_event_t evt;
+ struct sgl_obj *obj = NULL;
+
+ /* Get event from event queue */
+ while (sgl_event_queue_pop(&evt) == 0) {
+ obj = evt.obj;
+
+ /* if obj is NULL, it means the event from the input device */
+ if (obj == NULL) {
+ if (evt.type != SGL_EVENT_MOTION) {
+ obj = click_detect_object(&evt.pos);
+ } else {
+ obj = evt_ctx.last_click;
+ sgl_get_move_info(&evt);
+ }
+ }
+
+ if (obj) {
+ evt.pos.x = sgl_clamp(evt.pos.x, obj->coords.x1, obj->coords.x2);
+ evt.pos.y = sgl_clamp(evt.pos.y, obj->coords.y1, obj->coords.y2);
+
+ if (evt.type == SGL_EVENT_PRESSED) {
+ if (obj->pressed) {
+ continue;
+ }
+ obj->pressed = true;
+ evt_ctx.last_click = obj;
+ }
+ else if (evt.type == SGL_EVENT_RELEASED) {
+ if (!obj->pressed) {
+ if (evt_ctx.last_click && evt_ctx.last_click != obj) {
+ evt.obj = evt_ctx.last_click;
+ sgl_event_queue_push(evt);
+ }
+ continue;
+ }
+ obj->pressed = false;
+ evt_ctx.last_click = NULL;
+ }
+
+ SGL_ASSERT(obj->construct_fn);
+ evt.param = obj->event_data;
+ evt.obj = obj;
+ obj->construct_fn(NULL, obj, &evt);
+
+ /* call user event function */
+ if(obj->event_fn) {
+ obj->event_fn(&evt);
+ }
+ }
+ else {
+ SGL_LOG_TRACE("pos is out of object or no event_lost, skip event");
+ if (evt.type == SGL_EVENT_RELEASED && evt_ctx.last_click != NULL) {
+ evt.obj = evt_ctx.last_click;
+ sgl_event_queue_push(evt);
+ }
+ }
+ }
+}
+
+
+/**
+ * @brief Touch event read, this function will be called by user
+ * @param x: touch x position
+ * @param y: touch y position
+ * @param flag: touch flag, it means touch event down or up:
+ * true : touch down
+ * false: touch up
+ * @return none
+ * @note: for example, you can call it in 30ms tick handler function
+ * void example_30ms_tick_handler(void)
+ * {
+ * int pos_x, pos_y;
+ * bool button_status;
+ *
+ * bsp_touch_read_pos(&pos_x, &pos_y);
+ * button_status = bsp_touch_read_status();
+ *
+ * sgl_event_pos_input(pos_x, pos_y, button_status);
+ * }
+ */
+void sgl_event_pos_input(int16_t x, int16_t y, bool flag)
+{
+ static sgl_event_pos_t last_press, last_motion;
+ static uint32_t act_count = 0;
+ sgl_event_pos_t pos = { .x = x, .y = y };
+
+ /* rotate touch position */
+#if (CONFIG_SGL_FBDEV_ROTATION != 0)
+#if (CONFIG_SGL_FBDEV_ROTATION == 90)
+ pos.x = sgl_min(SGL_SCREEN_WIDTH - y, SGL_SCREEN_WIDTH - 1);
+ pos.y = sgl_min(x, SGL_SCREEN_HEIGHT - 1);
+#elif (CONFIG_SGL_FBDEV_ROTATION == 180)
+ pos.x = SGL_SCREEN_WIDTH - x - 1;
+ pos.y = SGL_SCREEN_HEIGHT - y - 1;
+#elif (CONFIG_SGL_FBDEV_ROTATION == 270)
+ pos.x = sgl_min(y, SGL_SCREEN_WIDTH - 1);
+ pos.y = sgl_min(SGL_SCREEN_HEIGHT - x, SGL_SCREEN_HEIGHT - 1);
+#else
+ #error "CONFIG_SGL_FBDEV_ROTATION is invalid rotation value (only 0/90/180/270 supported)"
+#endif
+#endif //!CONFIG_SGL_FBDEV_ROTATION
+
+ if (flag) {
+ if (!act_count) {
+ act_count = 1;
+ sgl_event_send_pos(pos, SGL_EVENT_PRESSED);
+ last_press = pos;
+ SGL_LOG_INFO("Touch SGL_EVENT_PRESSED x: %d, y: %d", pos.x, pos.y);
+ }
+ else {
+ sgl_event_send_pos(pos, SGL_EVENT_MOTION);
+ last_motion = pos;
+ SGL_LOG_INFO("Touch SGL_EVENT_MOTION x: %d, y: %d", pos.x, pos.y);
+ }
+
+ act_count ++;
+ }
+ else {
+ if (act_count) {
+ SGL_LOG_INFO("Touch action count: %d", act_count);
+ if (last_press.x == last_motion.x && last_press.y == last_motion.y) {
+ if (act_count < SGL_EVENT_CLICK_INTERVAL) {
+ sgl_event_send_pos(last_press, SGL_EVENT_CLICKED);
+ SGL_LOG_INFO("Touch SGL_EVENT_CLICKED x: %d, y: %d", last_press.x, last_press.y);
+ }
+ else {
+ sgl_event_send_pos(last_press, SGL_EVENT_LONG_CLICKED);
+ SGL_LOG_INFO("Touch SGL_EVENT_LONG_CLICKED x: %d, y: %d", last_press.x, last_press.y);
+ }
+ }
+
+ act_count = 0;
+ sgl_event_send_pos(last_motion, SGL_EVENT_RELEASED);
+ SGL_LOG_INFO("Touch SGL_EVENT_RELEASED x: %d, y: %d", last_motion.x, last_motion.y);
+ }
+ }
+}
diff --git a/User/system/sgl/core/sgl_log.c b/User/system/sgl/core/sgl_log.c
new file mode 100644
index 0000000..0aa655d
--- /dev/null
+++ b/User/system/sgl/core/sgl_log.c
@@ -0,0 +1,78 @@
+/* source/core/sgl_log.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+
+#if CONFIG_SGL_DEBUG
+
+/**
+ * @brief sgl log printing function, used to print debugging information. Note that this function
+ * should only be called in debugging mode, otherwise it may affect system real-time
+ * performance due to long execution time
+ * @param level: log level, such as, INFO, USER...
+ * @param format: log content
+ * @return none
+*/
+void sgl_log(const char *level, const char * format, ...)
+{
+ char buffer[120];
+ int tail = 0;
+ int pref_size = strlen(level);
+
+ strcpy(buffer, level);
+
+ va_list va;
+ va_start(va, format);
+ sgl_vsnprintf(buffer + pref_size, sizeof(buffer), format, va);
+ va_end(va);
+
+ tail = strlen(buffer);
+ memcpy(&buffer[tail], &"\r\n"SGL_LOG_NONE, strlen("\r\n"SGL_LOG_NONE));
+ buffer[tail + strlen("\r\n"SGL_LOG_NONE)] = 0;
+
+ sgl_log_stdout(buffer);
+}
+
+
+/**
+ * @brief sgl assert handler, used to handle assertions
+ * @param file: file name
+ * @param func: function name
+ * @param line: line number
+ * @return none
+*/
+void sgl_assert_handler(const char *file, const char *func, int line)
+{
+ sgl_log(SGL_ASSERT_FLAG, "file: %s, function: %s, line: %d", file, func, line);
+ while (1) {
+
+ };
+}
+
+#endif // !CONFIG_SGL_DEBUG
diff --git a/User/system/sgl/core/sgl_math.c b/User/system/sgl/core/sgl_math.c
new file mode 100644
index 0000000..d2dc187
--- /dev/null
+++ b/User/system/sgl/core/sgl_math.c
@@ -0,0 +1,434 @@
+/* source/core/sgl_math.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+
+
+/**
+ * @brief sine table
+ * @note the table is used to calculate the sine of an angle
+ */
+static const int16_t sin0_90_table[] = {
+ 0, 572, 1144, 1715, 2286, 2856, 3425, 3993, 4560, 5126, 5690, 6252, 6813, 7371, 7927, 8481,
+ 9032, 9580, 10126, 10668, 11207, 11743, 12275, 12803, 13328, 13848, 14364, 14876, 15383, 15886, 16383, 16876,
+ 17364, 17846, 18323, 18794, 19260, 19720, 20173, 20621, 21062, 21497, 21925, 22347, 22762, 23170, 23571, 23964,
+ 24351, 24730, 25101, 25465, 25821, 26169, 26509, 26841, 27165, 27481, 27788, 28087, 28377, 28659, 28932, 29196,
+ 29451, 29697, 29934, 30162, 30381, 30591, 30791, 30982, 31163, 31335, 31498, 31650, 31794, 31927, 32051, 32165,
+ 32269, 32364, 32448, 32523, 32587, 32642, 32687, 32722, 32747, 32762, 32767
+};
+
+
+/**
+ * @brief sqrt table, if the number less than 1024, the sqrt root will get by the table
+ */
+static const uint8_t sqrt_error_table[] = {
+ 0x00,0x00,0x6a,0xbb,0x00,0x3c,0x73,0xa5,0xd4,0x00,0x29,0x51,0x76,0x9b,0xbd,0xdf,
+ 0x00,0x1f,0x3e,0x5b,0x78,0x95,0xb0,0xcb,0xe6,0x00,0x19,0x32,0x4a,0x62,0x7a,0x91,
+ 0xa8,0xbe,0xd4,0xea,0x00,0x15,0x2a,0x3e,0x53,0x67,0x7b,0x8e,0xa2,0xb5,0xc8,0xdb,
+ 0xed,0x00,0x12,0x24,0x36,0x47,0x59,0x6a,0x7b,0x8c,0x9d,0xae,0xbe,0xcf,0xdf,0xef,
+ 0x00,0x0f,0x1f,0x2f,0x3f,0x4e,0x5d,0x6d,0x7c,0x8b,0x9a,0xa9,0xb7,0xc6,0xd4,0xe3,
+ 0xf1,0x00,0x0e,0x1c,0x2a,0x38,0x46,0x53,0x61,0x6f,0x7c,0x8a,0x97,0xa4,0xb2,0xbf,
+ 0xcc,0xd9,0xe6,0xf3,0x00,0x0c,0x19,0x26,0x32,0x3f,0x4b,0x58,0x64,0x70,0x7c,0x89,
+ 0x95,0xa1,0xad,0xb9,0xc5,0xd1,0xdc,0xe8,0xf4,0x00,0x0b,0x17,0x22,0x2e,0x39,0x44,
+ 0x50,0x5b,0x66,0x72,0x7d,0x88,0x93,0x9e,0xa9,0xb4,0xbf,0xca,0xd5,0xdf,0xea,0xf5,
+ 0x00,0x0a,0x15,0x1f,0x2a,0x34,0x3f,0x49,0x54,0x5e,0x68,0x73,0x7d,0x87,0x91,0x9c,
+ 0xa6,0xb0,0xba,0xc4,0xce,0xd8,0xe2,0xec,0xf6,0x00,0x09,0x13,0x1d,0x27,0x30,0x3a,
+ 0x44,0x4d,0x57,0x61,0x6a,0x74,0x7d,0x87,0x90,0x99,0xa3,0xac,0xb6,0xbf,0xc8,0xd1,
+ 0xdb,0xe4,0xed,0xf6,0x00,0x09,0x12,0x1b,0x24,0x2d,0x36,0x3f,0x48,0x51,0x5a,0x63,
+ 0x6c,0x74,0x7d,0x86,0x8f,0x98,0xa0,0xa9,0xb2,0xbb,0xc3,0xcc,0xd5,0xdd,0xe6,0xee,
+ 0xf7,0x00,0x08,0x11,0x19,0x21,0x2a,0x32,0x3b,0x43,0x4c,0x54,0x5c,0x65,0x6d,0x75,
+ 0x7d,0x86,0x8e,0x96,0x9e,0xa7,0xaf,0xb7,0xbf,0xc7,0xcf,0xd7,0xdf,0xe7,0xef,0xf7,
+ 0x00,0x07,0x0f,0x17,0x1f,0x27,0x2f,0x37,0x3f,0x47,0x4f,0x57,0x5e,0x66,0x6e,0x76,
+ 0x7e,0x85,0x8d,0x95,0x9c,0xa4,0xac,0xb4,0xbb,0xc3,0xca,0xd2,0xda,0xe1,0xe9,0xf0,
+ 0xf8,0x00,0x07,0x0f,0x16,0x1e,0x25,0x2c,0x34,0x3b,0x43,0x4a,0x52,0x59,0x60,0x68,
+ 0x6f,0x76,0x7e,0x85,0x8c,0x94,0x9b,0xa2,0xa9,0xb1,0xb8,0xbf,0xc6,0xcd,0xd5,0xdc,
+ 0xe3,0xea,0xf1,0xf8,0x00,0x07,0x0e,0x15,0x1c,0x23,0x2a,0x31,0x38,0x3f,0x46,0x4d,
+ 0x54,0x5b,0x62,0x69,0x70,0x77,0x7e,0x85,0x8c,0x92,0x99,0xa0,0xa7,0xae,0xb5,0xbc,
+ 0xc2,0xc9,0xd0,0xd7,0xde,0xe4,0xeb,0xf2,0xf9,0x00,0x06,0x0d,0x14,0x1a,0x21,0x28,
+ 0x2e,0x35,0x3c,0x42,0x49,0x50,0x56,0x5d,0x64,0x6a,0x71,0x77,0x7e,0x84,0x8b,0x92,
+ 0x98,0x9f,0xa5,0xac,0xb2,0xb9,0xbf,0xc6,0xcc,0xd3,0xd9,0xdf,0xe6,0xec,0xf3,0xf9,
+ 0x00,0x06,0x0c,0x13,0x19,0x1f,0x26,0x2c,0x32,0x39,0x3f,0x45,0x4c,0x52,0x58,0x5f,
+ 0x65,0x6b,0x71,0x78,0x7e,0x84,0x8a,0x91,0x97,0x9d,0xa3,0xa9,0xb0,0xb6,0xbc,0xc2,
+ 0xc8,0xcf,0xd5,0xdb,0xe1,0xe7,0xed,0xf3,0xf9,0x00,0x06,0x0c,0x12,0x18,0x1e,0x24,
+ 0x2a,0x30,0x36,0x3c,0x42,0x48,0x4e,0x54,0x5a,0x60,0x66,0x6c,0x72,0x78,0x7e,0x84,
+ 0x8a,0x90,0x96,0x9c,0xa2,0xa8,0xad,0xb3,0xb9,0xbf,0xc5,0xcb,0xd1,0xd7,0xdc,0xe2,
+ 0xe8,0xee,0xf4,0xfa,0x00,0x05,0x0b,0x11,0x17,0x1d,0x22,0x28,0x2e,0x34,0x39,0x3f,
+ 0x45,0x4b,0x50,0x56,0x5c,0x62,0x67,0x6d,0x73,0x78,0x7e,0x84,0x89,0x8f,0x95,0x9a,
+ 0xa0,0xa6,0xab,0xb1,0xb7,0xbc,0xc2,0xc8,0xcd,0xd3,0xd8,0xde,0xe4,0xe9,0xef,0xf4,
+ 0xfa,0x00,0x05,0x0b,0x10,0x16,0x1b,0x21,0x26,0x2c,0x31,0x37,0x3c,0x42,0x47,0x4d,
+ 0x52,0x58,0x5d,0x63,0x68,0x6e,0x73,0x79,0x7e,0x84,0x89,0x8e,0x94,0x99,0x9f,0xa4,
+ 0xaa,0xaf,0xb4,0xba,0xbf,0xc5,0xca,0xcf,0xd5,0xda,0xdf,0xe5,0xea,0xef,0xf5,0xfa,
+ 0x00,0x05,0x0a,0x0f,0x15,0x1a,0x1f,0x25,0x2a,0x2f,0x35,0x3a,0x3f,0x44,0x4a,0x4f,
+ 0x54,0x5a,0x5f,0x64,0x69,0x6e,0x74,0x79,0x7e,0x83,0x89,0x8e,0x93,0x98,0x9d,0xa3,
+ 0xa8,0xad,0xb2,0xb7,0xbd,0xc2,0xc7,0xcc,0xd1,0xd6,0xdc,0xe1,0xe6,0xeb,0xf0,0xf5,
+ 0xfa,0x00,0x05,0x0a,0x0f,0x14,0x19,0x1e,0x23,0x28,0x2d,0x32,0x38,0x3d,0x42,0x47,
+ 0x4c,0x51,0x56,0x5b,0x60,0x65,0x6a,0x6f,0x74,0x79,0x7e,0x83,0x88,0x8d,0x92,0x97,
+ 0x9c,0xa1,0xa6,0xab,0xb0,0xb5,0xba,0xbf,0xc4,0xc9,0xce,0xd3,0xd8,0xdd,0xe2,0xe7,
+ 0xec,0xf1,0xf6,0xfb,0x00,0x04,0x09,0x0e,0x13,0x18,0x1d,0x22,0x27,0x2c,0x31,0x35,
+ 0x3a,0x3f,0x44,0x49,0x4e,0x53,0x58,0x5c,0x61,0x66,0x6b,0x70,0x75,0x79,0x7e,0x83,
+ 0x88,0x8d,0x92,0x96,0x9b,0xa0,0xa5,0xaa,0xae,0xb3,0xb8,0xbd,0xc2,0xc6,0xcb,0xd0,
+ 0xd5,0xd9,0xde,0xe3,0xe8,0xed,0xf1,0xf6,0xfb,0x00,0x04,0x09,0x0e,0x12,0x17,0x1c,
+ 0x21,0x25,0x2a,0x2f,0x33,0x38,0x3d,0x42,0x46,0x4b,0x50,0x54,0x59,0x5e,0x62,0x67,
+ 0x6c,0x70,0x75,0x7a,0x7e,0x83,0x88,0x8c,0x91,0x96,0x9a,0x9f,0xa3,0xa8,0xad,0xb1,
+ 0xb6,0xbb,0xbf,0xc4,0xc8,0xcd,0xd2,0xd6,0xdb,0xdf,0xe4,0xe9,0xed,0xf2,0xf6,0xfb,
+ 0x00,0x04,0x09,0x0d,0x12,0x16,0x1b,0x1f,0x24,0x29,0x2d,0x32,0x36,0x3b,0x3f,0x44,
+ 0x48,0x4d,0x51,0x56,0x5a,0x5f,0x63,0x68,0x6c,0x71,0x75,0x7a,0x7e,0x83,0x87,0x8c,
+ 0x90,0x95,0x99,0x9e,0xa2,0xa7,0xab,0xb0,0xb4,0xb9,0xbd,0xc1,0xc6,0xca,0xcf,0xd3,
+ 0xd8,0xdc,0xe1,0xe5,0xe9,0xee,0xf2,0xf7,0xfb,0x00,0x04,0x08,0x0d,0x11,0x16,0x1a,
+ 0x1e,0x23,0x27,0x2c,0x30,0x34,0x39,0x3d,0x41,0x46,0x4a,0x4f,0x53,0x57,0x5c,0x60,
+ 0x64,0x69,0x6d,0x71,0x76,0x7a,0x7e,0x83,0x87,0x8b,0x90,0x94,0x98,0x9d,0xa1,0xa5,
+ 0xaa,0xae,0xb2,0xb7,0xbb,0xbf,0xc4,0xc8,0xcc,0xd0,0xd5,0xd9,0xdd,0xe2,0xe6,0xea,
+ 0xee,0xf3,0xf7,0xfb,0x00,0x04,0x08,0x0c,0x11,0x15,0x19,0x1d,0x22,0x26,0x2a,0x2e,
+ 0x33,0x37,0x3b,0x3f,0x43,0x48,0x4c,0x50,0x54,0x59,0x5d,0x61,0x65,0x69,0x6e,0x72,
+ 0x76,0x7a,0x7e,0x83,0x87,0x8b,0x8f,0x93,0x98,0x9c,0xa0,0xa4,0xa8,0xac,0xb1,0xb5,
+ 0xb9,0xbd,0xc1,0xc5,0xca,0xce,0xd2,0xd6,0xda,0xde,0xe3,0xe7,0xeb,0xef,0xf3,0xf7,
+ 0xfb,0x00,0x04,0x08,0x0c,0x10,0x14,0x18,0x1c,0x20,0x25,0x29,0x2d,0x31,0x35,0x39,
+ 0x3d,0x41,0x45,0x49,0x4e,0x52,0x56,0x5a,0x5e,0x62,0x66,0x6a,0x6e,0x72,0x76,0x7a,
+ 0x7e,0x83,0x87,0x8b,0x8f,0x93,0x97,0x9b,0x9f,0xa3,0xa7,0xab,0xaf,0xb3,0xb7,0xbb,
+ 0xbf,0xc3,0xc7,0xcb,0xcf,0xd3,0xd7,0xdb,0xdf,0xe3,0xe7,0xeb,0xef,0xf3,0xf7,0xfb,
+ 0x00
+};
+
+
+/**
+ * the table will used to calculate the square root of a number
+ */
+static const uint8_t sqrt_error_init_table[32] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5,
+ 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7
+};
+
+
+/**
+ * @brief Calculate the sine of an angle
+ * @param angle: Angle in degrees such 0-359
+ * @return sine of the angle from sin0_90_table
+ * @note This function has implemented angle normalization to the range of 0 to 360 degrees.
+ */
+int32_t sgl_sin(int16_t angle)
+{
+ int16_t ret = 0;
+
+ while (angle >= 360) {
+ angle -= 360;
+ }
+ while (angle < 0) {
+ angle += 360;
+ }
+
+ if (angle < 0) {
+ angle = 360 + angle;
+ }
+
+ if (angle < 90) {
+ ret = sin0_90_table[angle];
+ }
+ else if (angle >= 90 && angle < 180){
+ angle = 180 - angle;
+ ret = sin0_90_table[angle];
+ }
+ else if (angle >= 180 && angle < 270){
+ angle = angle - 180;
+ ret = -sin0_90_table[angle];
+ }
+ else {
+ angle = 360 - angle;
+ ret = -sin0_90_table[angle];
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Calculate x number square root
+ * @param x: x number
+ * @retval x number square root
+ */
+uint16_t sgl_sqrt(uint32_t x)
+{
+ uint32_t rem = 0;
+ uint32_t root = 0;
+ uint32_t divisor = 0;
+
+ for (int i=0; i<16; i++) {
+ root <<= 1;
+ rem = ((rem << 2) + (x >> 30));
+ x <<= 2;
+ divisor = (root<<1) + 1;
+
+ if (divisor <= rem) {
+ rem -= divisor;
+ root++;
+ }
+ }
+ return (uint16_t)(root);
+}
+
+
+/**
+ * @brief Calculate error of the square root for a number.
+ * @param x The number to calculate the error for.
+ * @return The error of the square root. [0 ~ 255]
+ */
+uint8_t sgl_sqrt_error(uint32_t x)
+{
+ uint32_t bsh = (1 << 14);
+ uint32_t fpr = 0;
+ uint32_t osh = 0;
+ uint32_t bod;
+
+ if (x < 1025) {
+ return sqrt_error_table[x];
+ }
+ else if (x > (1 << 30)) {
+ return 0;
+ }
+
+ int32_t index = 0;
+ uint32_t xp = x;
+
+ if ((xp & 0xFFFF0000) == 0) { index += 16; xp <<= 16; }
+ if ((xp & 0xFF000000) == 0) { index += 8; xp <<= 8; }
+ if ((xp & 0xF0000000) == 0) { index += 4; xp <<= 4; }
+ if ((xp & 0xC0000000) == 0) { index += 2; xp <<= 2; }
+ if ((xp & 0x80000000) == 0) { index += 1; }
+
+ osh = sqrt_error_init_table[31 - index];
+ bsh = 1 << (2 * osh + 14);
+
+ do {
+ bod = bsh + fpr;
+ if (x >= bod) {
+ x -= bod;
+ fpr = bsh + bod;
+ }
+ x <<= 1;
+ }while (bsh >>= 1);
+
+ return fpr>>osh;
+}
+
+
+/**
+ * @brief Calculate the angle based on the x and y coordinates. This function is a fast algorithm
+ * implementation, with reference address: www.RomanBlack.com (Fast XY vector to integer degree algorithm)
+ *
+ * @param x: The x coordinate on a circle
+ * @param y: The y coordinate on a circle
+ * @return angle
+ * @note return angle [-32767 ~ 32767]
+ */
+int32_t sgl_atan2_raw(int x, int y)
+{
+ int32_t ret;
+
+ if (y == 0) {
+ if (x > 0) {
+ ret = -32767;
+ }
+ else {
+ ret = 32767;
+ }
+ }
+ else {
+ ret = (x << 8) / y;
+ }
+ if (y > 0) {
+ ret += 32767;
+ }
+ else {
+ ret -= 32767;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Calculate the angle based on the x and y coordinates. This function is a fast algorithm
+ * implementation, with reference address: www.RomanBlack.com (Fast XY vector to integer degree algorithm)
+ *
+ * @param x: The x coordinate on a circle
+ * @param y: The y coordinate on a circle
+ * @return angle
+ * @note return angle [0 ~ 359]
+*/
+uint16_t sgl_atan2_angle(int x, int y)
+{
+ unsigned char negflag;
+ unsigned char tempdegree;
+ unsigned char comp;
+ unsigned int degree;
+ unsigned int ux;
+ unsigned int uy;
+
+ negflag = 0;
+ if (x < 0) {
+ negflag += 0x01;
+ x = (0 - x);
+ }
+ ux = x;
+ if (y < 0) {
+ negflag += 0x02;
+ y = (0 - y);
+ }
+ uy = y;
+
+ if (ux > uy) {
+ degree = (uy * 45) / ux;
+ negflag += 0x10;
+ }
+ else {
+ degree = (ux * 45) / uy;
+ }
+
+ comp = 0;
+ tempdegree = degree;
+ if (tempdegree > 22) {
+ if (tempdegree <= 44) comp++;
+ if (tempdegree <= 41) comp++;
+ if (tempdegree <= 37) comp++;
+ if (tempdegree <= 32) comp++;
+ }
+ else {
+ if (tempdegree >= 2) comp++;
+ if (tempdegree >= 6) comp++;
+ if (tempdegree >= 10) comp++;
+ if (tempdegree >= 15) comp++;
+ }
+ degree += comp;
+
+ if (negflag & 0x10) degree = (90 - degree);
+
+ if (negflag & 0x02) {
+ if (negflag & 0x01)
+ degree = (180 + degree);
+ else
+ degree = (180 - degree);
+ }
+ else {
+ if (negflag & 0x01)
+ degree = (360 - degree);
+ }
+ return degree;
+}
+
+
+/**
+ * @brief Split the length into n parts, with the weight of each part.
+ * @param weight: The weight of each part.
+ * @param count: The count of parts.
+ * @param length: The length to split.
+ * @param gap: The gap between each part.
+ * @param out: The length of each part.
+ * @note The error accumulation method of Bresenham's algorithm
+ */
+void sgl_split_len(const uint8_t *weight, int count, int16_t length, int16_t gap, int16_t *out)
+{
+ int16_t total_w = 0, span = 0, accumulated = 0, error = 0;
+ for (int i = 0; i < count; i++) {
+ total_w += weight[i];
+ }
+
+ span = length - gap * (count + 1);
+
+ for (int i = 0; i < count; i++) {
+ int numerator = weight[i] * span;
+ out[i] = numerator / total_w;
+ error += numerator % total_w;
+
+ if (error >= total_w) {
+ out[i] += 1;
+ error -= total_w;
+ }
+ accumulated += out[i];
+ }
+
+ error = span - accumulated;
+
+ for (int i = 0; i < count && error > 0; i++) {
+ out[i] += 1;
+ error --;
+ }
+
+ for (int i = 0; i < count && error < 0; i++) {
+ out[i] -= 1;
+ error ++;
+ }
+}
+
+
+/**
+ * @brief Split the length into n parts, with the weight of each part.
+ * @param length: The length to split.
+ * @param count: The count of parts.
+ * @param gap: The gap between each part.
+ * @param out: The length of each part.
+ * @note The average method of Bresenham's algorithm
+ */
+void sgl_split_len_avg(int length, int count, int16_t gap, int16_t *out)
+{
+ int16_t available_length = length - (count + 1) * gap;
+ int16_t base = available_length / count;
+ int16_t remainder = available_length % count;
+
+ int16_t error = 0;
+ for (int i = 0; i < count; i++) {
+ out[i] = base;
+ error += remainder;
+
+ if (error > count / 2) {
+ out[i] += 1;
+ error -= count;
+ }
+ }
+}
+
+
+/* Random number generator */
+static size_t rand_next = 1;
+
+/**
+ * @brief Generate a random number.
+ * @param none
+ * @return Random number.
+ * @note The random number generator is in the range of [0, 32767].
+ */
+int16_t sgl_rand(void)
+{
+ rand_next = rand_next * 1103515245 + 12345;
+ return (int16_t)((rand_next >> 16) & 0x7FFF);
+}
+
+
+/**
+ * @brief Set the seed of the random number generator.
+ * @param seed: The seed of the random number generator.
+ * @return none
+ */
+void sgl_srand(unsigned int seed)
+{
+ rand_next = seed;
+}
diff --git a/User/system/sgl/core/sgl_misc.c b/User/system/sgl/core/sgl_misc.c
new file mode 100644
index 0000000..1f4a85f
--- /dev/null
+++ b/User/system/sgl/core/sgl_misc.c
@@ -0,0 +1,166 @@
+/* source/core/sgl_misc.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+
+#if (CONFIG_SGL_BOOT_LOGO)
+
+typedef struct sgl_logo {
+ sgl_obj_t obj;
+ uint8_t progress;
+ uint8_t alpha;
+}sgl_logo_t;
+
+#define SGL_LOGO_W (26)
+#define SGL_LOGO_H (14)
+
+const uint8_t sgl_logo_s[][4] = {
+ {0, 0, 8, 2},
+ {0, 2, 2, 8},
+ {2, 6, 8, 8},
+ {6, 8, 8, 14},
+ {0, 12, 6, 14},
+};
+
+const uint8_t sgl_logo_g[][4] = {
+ {9, 0, 17, 2},
+ {9, 2, 11, 14},
+ {11, 12, 17, 14},
+ {15, 6, 17, 12},
+ {13, 6, 15, 8},
+};
+
+const uint8_t sgl_logo_l[][4] = {
+ {18, 0, 20, 14},
+ {20, 12, 26, 14},
+};
+
+static void sgl_logo_construct_cb(sgl_surf_t *surf, sgl_obj_t* obj, sgl_event_t *evt)
+{
+ sgl_logo_t *logo = (sgl_logo_t*)obj;
+ int16_t w = obj->area.x2 - obj->area.x1 + 1;
+ int16_t h = obj->area.y2 - obj->area.y1 + 1;
+
+ const float scale_x = w / SGL_LOGO_W;
+ const float scale_y = h / SGL_LOGO_H;
+ sgl_rect_t rect;
+
+ if(evt->type == SGL_EVENT_DRAW_MAIN) {
+ sgl_area_t clip;
+
+ if (!sgl_surf_clip(surf, &obj->area, &clip)) {
+ return;
+ }
+
+ for (uint32_t i = 0; i < SGL_ARRAY_SIZE(sgl_logo_s); i++) {
+ rect.x1 = sgl_logo_s[i][0] * scale_x + obj->area.x1;
+ rect.y1 = sgl_logo_s[i][1] * scale_y + obj->area.y1;
+ rect.x2 = sgl_logo_s[i][2] * scale_x + obj->area.x1 - 1;
+ rect.y2 = sgl_logo_s[i][3] * scale_y + obj->area.y1 - 1;
+
+ sgl_draw_fill_rect_with_border(surf, &clip, &rect, obj->radius, SGL_COLOR_RED, SGL_COLOR_BLUE, 0, logo->alpha);
+ }
+
+ for (uint32_t i = 0; i < SGL_ARRAY_SIZE(sgl_logo_g); i++) {
+ rect.x1 = sgl_logo_g[i][0] * scale_x + obj->area.x1;
+ rect.y1 = sgl_logo_g[i][1] * scale_y + obj->area.y1;
+ rect.x2 = sgl_logo_g[i][2] * scale_x + obj->area.x1 - 1;
+ rect.y2 = sgl_logo_g[i][3] * scale_y + obj->area.y1 - 1;
+
+ sgl_draw_fill_rect_with_border(surf, &clip, &rect, obj->radius, SGL_COLOR_GREEN, SGL_COLOR_BLUE, 0, logo->alpha);
+ }
+
+ for (uint32_t i = 0; i < SGL_ARRAY_SIZE(sgl_logo_l); i++) {
+ rect.x1 = sgl_logo_l[i][0] * scale_x + obj->area.x1;
+ rect.y1 = sgl_logo_l[i][1] * scale_y + obj->area.y1;
+ rect.x2 = sgl_logo_l[i][2] * scale_x + obj->area.x1 - 1;
+ rect.y2 = sgl_logo_l[i][3] * scale_y + obj->area.y1 - 1;
+
+ sgl_draw_fill_rect_with_border(surf, &clip, &rect, obj->radius, SGL_COLOR_BLUE, SGL_COLOR_BLUE, 0, logo->alpha);
+ }
+ }
+}
+
+sgl_obj_t* sgl_logo_create(sgl_obj_t* parent)
+{
+ sgl_logo_t *logo = sgl_malloc(sizeof(sgl_logo_t));
+ if (logo == NULL) {
+ SGL_LOG_ERROR("sgl_logo_create: malloc failed");
+ return NULL;
+ }
+
+ /* set object all member to zero */
+ memset(logo, 0, sizeof(sgl_logo_t));
+
+ sgl_obj_t *obj = &logo->obj;
+ sgl_obj_init(&logo->obj, parent);
+ obj->construct_fn = sgl_logo_construct_cb;
+ logo->alpha = SGL_ALPHA_MAX;
+ sgl_obj_set_border_width(obj, 0);
+ return obj;
+}
+
+void sgl_logo_set_alpha(sgl_obj_t* obj, uint8_t alpha)
+{
+ sgl_logo_t *logo = (sgl_logo_t*)obj;
+ logo->alpha = alpha;
+ sgl_obj_set_dirty(obj);
+}
+
+void sgl_logo_anim(sgl_anim_t *anim, int32_t value)
+{
+ sgl_obj_t *logo = (sgl_obj_t*)anim->data;
+ sgl_logo_set_alpha(logo, value);
+}
+
+/**
+ * @brief to show the sgl logo after sgl init
+ * @param none
+ * @return none
+ * @note: you can call this function in your main function to show the sgl logo
+ */
+void sgl_boot_logo(void)
+{
+ sgl_obj_t *logo = sgl_logo_create(NULL);
+ sgl_obj_set_size(logo, SGL_SCREEN_WIDTH / 3, SGL_SCREEN_HEIGHT / 3);
+ sgl_obj_set_pos_align(logo, SGL_ALIGN_CENTER);
+ sgl_obj_set_radius(logo, 0);
+
+ sgl_anim_t *anim = sgl_anim_create();
+ sgl_anim_set_data(anim, logo);
+ sgl_anim_set_act_duration(anim, 1000);
+ sgl_anim_set_start_value(anim, SGL_ALPHA_MAX);
+ sgl_anim_set_end_value(anim, SGL_ALPHA_MIN);
+ sgl_anim_set_path(anim, sgl_logo_anim, SGL_ANIM_PATH_LINEAR);
+ sgl_anim_start(anim, SGL_ANIM_REPEAT_ONCE);
+
+ while (!sgl_anim_is_finished(anim)) {
+ sgl_task_handle();
+ }
+
+ sgl_anim_delete(anim);
+ sgl_obj_delete(logo);
+}
+
+#endif // !CONFIG_SGL_BOOT_LOGO
diff --git a/User/system/sgl/core/sgl_snprintf.c b/User/system/sgl/core/sgl_snprintf.c
new file mode 100644
index 0000000..c175539
--- /dev/null
+++ b/User/system/sgl/core/sgl_snprintf.c
@@ -0,0 +1,306 @@
+/* source/core/sgl_snprintf.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+
+/**
+ * @brief append a character to the buffer
+ * @param buf buffer
+ * @param size buffer size
+ * @param pos current position
+ * @param c character to append
+ */
+static inline void append_char(char *buf, size_t size, size_t *pos, char c)
+{
+ if (*pos + 1 < size) {
+ buf[*pos] = c;
+ }
+ (*pos)++;
+}
+
+/**
+ * @brief append a string to the buffer
+ * @param buf buffer
+ * @param size buffer size
+ * @param pos current position
+ * @param s string to append
+ */
+static inline void append_str(char *buf, size_t size, size_t *pos, const char* s)
+{
+ while (*s) append_char(buf, size, pos, *s++);
+}
+
+/**
+ * @brief pad alignment characters (default: space) to the buffer
+ * @param buf buffer
+ * @param size buffer size
+ * @param pos current position
+ * @param pad_len number of padding characters to append
+ * @param pad_char padding character (default: ' ')
+ */
+static inline void pad_align(char *buf, size_t size, size_t *pos, size_t pad_len, char pad_char)
+{
+ for (size_t i = 0; i < pad_len; i++) {
+ append_char(buf, size, pos, pad_char);
+ }
+}
+
+/**
+ * @brief calculate the length of an integer when converted to string
+ * @param val integer value
+ * @return number of characters of the integer string
+ */
+static inline size_t int_str_len(int val)
+{
+ if (val == 0) return 1; // Special case: 0 has length 1
+
+ size_t len = 0;
+ bool neg = val < 0;
+
+ if (neg) val = -val;
+
+ do {
+ len++;
+ val /= 10;
+ } while (val);
+
+ return neg ? len + 1 : len; // Add 1 for negative sign
+}
+
+/**
+ * @brief append an integer to the buffer with left/right alignment support
+ * @param buf buffer
+ * @param size buffer size
+ * @param pos current position
+ * @param val integer to append
+ * @param width alignment width (0 means no alignment)
+ * @param left_align whether to use left alignment (true: left, false: right)
+ */
+static inline void append_int(char *buf, size_t size, size_t *pos, int val, int width, bool left_align)
+{
+ char tmp[64];
+ int i = 0;
+ bool neg = val < 0;
+ size_t num_len = int_str_len(val);
+ size_t pad_len = 0;
+
+ if (width > 0 && (size_t)width > num_len) {
+ pad_len = (size_t)width - num_len;
+ }
+
+ if (!left_align && pad_len > 0) {
+ pad_align(buf, size, pos, pad_len, ' ');
+ }
+
+ if (neg) val = -val;
+
+ do {
+ tmp[i++] = '0' + (val % 10);
+ val /= 10;
+ } while (val);
+
+ if (neg) tmp[i++] = '-';
+
+ while (i--) append_char(buf, size, pos, tmp[i]);
+
+ if (left_align && pad_len > 0) {
+ pad_align(buf, size, pos, pad_len, ' ');
+ }
+}
+
+/**
+ * @brief append a hexadecimal number to the buffer
+ * @param buf buffer
+ * @param size buffer size
+ * @param pos current position
+ * @param val hexadecimal number to append
+ * @param upper whether to use uppercase letters
+ */
+static inline void append_hex(char *buf, size_t size, size_t *pos, unsigned int val, bool upper)
+{
+ char tmp[32];
+ int i = 0;
+ const char *digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
+
+ do {
+ tmp[i++] = digits[val & 0xF];
+ val >>= 4;
+ } while (val);
+
+ while (i--) append_char(buf, size, pos, tmp[i]);
+}
+
+/**
+ * @brief append a float to the buffer
+ * @param buf buffer
+ * @param size buffer size
+ * @param pos current position
+ * @param val float to append
+ * @param precision number of decimal places (-1 for default of 6)
+ */
+static void append_float(char *buf, size_t size, size_t *pos, double val, int precision)
+{
+ int int_part = (int)val;
+ double frac = val - int_part;
+
+ if (val < 0) {
+ append_char(buf, size, pos, '-');
+ int_part = -int_part;
+ frac = -frac;
+ }
+
+ append_int(buf, size, pos, int_part, 0, false);
+ append_char(buf, size, pos, '.');
+
+ int prec = (precision >= 0) ? precision : 6;
+ for (int i = 0; i < prec; i++) {
+ frac *= 10;
+ int d = (int)frac;
+ append_char(buf, size, pos, '0' + d);
+ frac -= d;
+ }
+}
+
+/**
+ * @brief format a string, a simple version of vsnprintf (with width alignment support)
+ * @param buf buffer
+ * @param size buffer size
+ * @param fmt format string
+ * @param ap argument list
+ * @return number of characters written
+ */
+int sgl_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
+{
+ size_t pos = 0;
+
+ while (*fmt) {
+ char c = *fmt;
+
+ if (c != '%') {
+ append_char(buf, size, &pos, c);
+ fmt++;
+ continue;
+ }
+
+ fmt++;
+ bool left_align = false;
+ int width = 0;
+ int precision = -1;
+
+ if (*fmt == '-') {
+ left_align = true;
+ fmt++;
+ }
+
+ while (*fmt >= '0' && *fmt <= '9') {
+ width = width * 10 + (*fmt - '0');
+ fmt++;
+ }
+
+ if (*fmt == '.') {
+ fmt++;
+ precision = 0;
+ while (*fmt >= '0' && *fmt <= '9') {
+ precision = precision * 10 + (*fmt - '0');
+ fmt++;
+ }
+ }
+
+ char spec = *fmt;
+ switch (spec) {
+ case 's': {
+ const char *s = va_arg(ap, const char*);
+ append_str(buf, size, &pos, s);
+ break;
+ }
+
+ case 'd': {
+ int d = va_arg(ap, int);
+ append_int(buf, size, &pos, d, width, left_align);
+ break;
+ }
+
+ case 'x': {
+ unsigned int x = va_arg(ap, unsigned int);
+ append_hex(buf, size, &pos, x, false);
+ break;
+ }
+
+ case 'X': {
+ unsigned int x = va_arg(ap, unsigned int);
+ append_hex(buf, size, &pos, x, true);
+ break;
+ }
+
+ case 'f': {
+ double f = va_arg(ap, double);
+ append_float(buf, size, &pos, f, precision);
+ break;
+ }
+
+ case 'c': {
+ char ch = (char)va_arg(ap, int);
+ append_char(buf, size, &pos, ch);
+ break;
+ }
+
+ case '%': {
+ append_char(buf, size, &pos, '%');
+ break;
+ }
+
+ default:
+ append_char(buf, size, &pos, '%');
+ append_char(buf, size, &pos, spec);
+ break;
+ }
+
+ fmt++;
+ }
+
+ if (size > 0) {
+ buf[(pos < size) ? pos : (size - 1)] = '\0';
+ }
+
+ return (int)pos;
+}
+
+/**
+ * @brief format a string, a simple version of snprintf (with width alignment support)
+ * @param buf buffer
+ * @param size buffer size
+ * @param fmt format string
+ * @param ... arguments
+ * @return number of characters written
+ */
+int sgl_snprintf(char *buf, size_t size, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ int ret = sgl_vsnprintf(buf, size, fmt, ap);
+ va_end(ap);
+ return ret;
+}
diff --git a/User/system/sgl/draw/build.cmake b/User/system/sgl/draw/build.cmake
new file mode 100644
index 0000000..32682f6
--- /dev/null
+++ b/User/system/sgl/draw/build.cmake
@@ -0,0 +1,34 @@
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_draw_line.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_draw_rect.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_draw_circle.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_draw_arc.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_draw_text.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_draw_ring.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_draw_icon.c
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_draw_xform.c
+)
diff --git a/User/system/sgl/draw/lm.cfg b/User/system/sgl/draw/lm.cfg
new file mode 100644
index 0000000..f37c2a5
--- /dev/null
+++ b/User/system/sgl/draw/lm.cfg
@@ -0,0 +1,32 @@
+# source/draw/lm.cfg
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+SRC += sgl_draw_line.c
+SRC += sgl_draw_rect.c
+SRC += sgl_draw_circle.c
+SRC += sgl_draw_arc.c
+SRC += sgl_draw_text.c
+SRC += sgl_draw_ring.c
+SRC += sgl_draw_icon.c
+SRC += sgl_draw_xform.c
diff --git a/User/system/sgl/draw/sgl_draw_arc.c b/User/system/sgl/draw/sgl_draw_arc.c
new file mode 100644
index 0000000..84ef377
--- /dev/null
+++ b/User/system/sgl/draw/sgl_draw_arc.c
@@ -0,0 +1,244 @@
+/* source/draw/sgl_draw_arc.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+
+
+typedef struct sgl_arc_dot
+{
+ int16_t cx;
+ int16_t cy;
+ int16_t r;
+ uint32_t r2;
+ uint16_t rmax;
+ uint16_t outer;
+} sgl_arc_dot_t;
+
+
+static void arc_dot_sin_cos(int16_t cx, int16_t cy, int16_t radius_in, int16_t radius_out, sgl_arc_dot_t *dot,int sin, int cos)
+{
+ int len = (radius_out + radius_in) / 2;
+ int r = (radius_out - radius_in) / 2;
+ if (unlikely(r == 0)) {
+ return;
+ }
+
+ if (sin < 0) {
+ dot->cx = (sin * len - 16348) / 32768;
+ }
+ else {
+ dot->cx = (sin * len + 16348) / 32768;
+ }
+ if (cos<0) {
+ dot->cy = (cos * len - 16348) / 32768;
+ }
+ else {
+ dot->cy = (cos * len + 16348) / 32768;
+ }
+
+ dot->cx = cx - dot->cx;
+ dot->cy = cy - dot->cy;
+ dot->r = r + 1;
+ dot->r2 = sgl_pow2(r);
+ dot->rmax = sgl_pow2(r + 1);
+ dot->outer = 0;
+}
+
+
+static inline uint8_t arc_get_dot(sgl_arc_dot_t *dot,int ax, int ay)
+{
+ uint32_t temp;
+ uint8_t alpha = SGL_ALPHA_MIN, max = SGL_ALPHA_MIN;
+ sgl_arc_dot_t *p = dot;
+ int32_t rate = (0xff00) / (dot->rmax - dot->r2);
+
+ for (int k = 0; k < 2; k++, p++) {
+ int x = ax > p->cx ? ax - p->cx : p->cx-ax;
+ int y = ay > p->cy ? ay - p->cy : p->cy-ay;
+
+ if ((x < p->r) && (y < p->r)) {
+ temp = sgl_pow2(x) + sgl_pow2(y);
+ if (temp >= p->rmax) {
+ alpha = 0;
+ }
+ else if (temp > p->r2) {
+ if(dot->outer==0) {
+ dot->outer = rate;
+ }
+ alpha = (p->rmax - temp) * dot->outer >> 8;
+ }
+ else {
+ alpha = SGL_ALPHA_MAX;
+ }
+ max = sgl_max(max, alpha);
+ }
+ }
+ return max;
+}
+
+
+/**
+ * @brief draw an arc with alpha
+ * @param surf pointer to surface
+ * @param area pointer to area
+ * @param desc pointer to arc description
+ * @return none
+ */
+void sgl_draw_fill_arc(sgl_surf_t *surf, sgl_area_t *area, sgl_draw_arc_t *desc)
+{
+ int y2 = 0, real_r2 = 0, edge_alpha = 0;
+ int in_r2 = sgl_pow2(desc->radius_in);
+ int out_r2 = sgl_pow2(desc->radius_out);
+ int inv_inner = 0, inv_outer = 0;
+ sgl_arc_dot_t arc_dot[2];
+
+ int in_r2_max = sgl_pow2(desc->radius_in - 1);
+ int out_r2_max = sgl_pow2(desc->radius_out + 1);
+ int32_t rate = (0xff00) / (in_r2 - in_r2_max);
+ int32_t rate2 = (0xff00) / (out_r2_max - out_r2);
+
+ sgl_color_t *buf = NULL, *blend = NULL;
+ int32_t dx, dy;
+ uint8_t flag = 0xff, in_range;
+ int32_t ds = 0, de = 0, sd = 0, ed = 0;
+ int32_t sx = 0, sy = 0, ex = 0, ey = 0;
+ sgl_color_t tmp_color;
+ sgl_area_t clip = SGL_AREA_MAX;
+
+ sgl_surf_clip_area_return(surf, area, &clip);
+
+ sgl_area_t c_rect = {
+ .x1 = desc->cx - desc->radius_out,
+ .x2 = desc->cx + desc->radius_out,
+ .y1 = desc->cy - desc->radius_out,
+ .y2 = desc->cy + desc->radius_out
+ };
+
+ if (!sgl_area_selfclip(&clip, &c_rect)) {
+ return;
+ }
+
+ if (desc->start_angle != 0 || desc->end_angle != 360) {
+ flag = (desc->end_angle - desc->start_angle > 180) ? 1 : 0;
+ sx = sgl_sin(desc->start_angle);
+ sy = -sgl_cos(desc->start_angle);
+ ex = sgl_sin(desc->end_angle);
+ ey = -sgl_cos(desc->end_angle);
+
+ if (desc->mode == SGL_ARC_MODE_NORMAL_SMOOTH || desc->mode == SGL_ARC_MODE_RING_SMOOTH) {
+ arc_dot_sin_cos(desc->cx, desc->cy, desc->radius_in, desc->radius_out, &arc_dot[0], sx, sy);
+ arc_dot_sin_cos(desc->cx, desc->cy, desc->radius_in, desc->radius_out, &arc_dot[1], ex, ey);
+ }
+
+ sx = sx >> 7;
+ sy = sy >> 7;
+ ex = ex >> 7;
+ ey = ey >> 7;
+ }
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ dy = y - desc->cy;
+ y2 = sgl_pow2(dy);
+ blend = buf;
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ dx = x - desc->cx;
+ real_r2 = sgl_pow2(x - desc->cx) + y2;
+
+ if (real_r2 >= out_r2_max) {
+ if (x > desc->cx) {
+ blend++;
+ break;
+ }
+ continue;
+ }
+ if (real_r2 < in_r2_max) {
+ if (x < desc->cx) {
+ blend += ((desc->cx - x) * 2);
+ x = desc->cx * 2 - x;
+ }
+ continue;
+ }
+ if (real_r2 < in_r2 ) {
+ if(inv_inner == 0) {
+ inv_inner = rate;
+ }
+ edge_alpha = (real_r2 - in_r2_max) * inv_inner >> 8;
+ }
+ else if (real_r2 > out_r2) {
+ if(inv_outer == 0) {
+ inv_outer = rate2;
+ }
+ edge_alpha = (out_r2_max - real_r2) * inv_outer >> 8;
+ }
+ else {
+ edge_alpha = SGL_ALPHA_MAX;
+ }
+
+ tmp_color = desc->color;
+ if (flag != 255) {
+ ds = (dx * sy - dy * sx);
+ de = (dy * ex - dx * ey);
+ in_range = flag > 0 ? (ds > 0 || de >0) : (ds >= 0 && de >= 0);
+ if (!in_range) {
+
+ switch (desc->mode) {
+ case SGL_ARC_MODE_NORMAL:
+ sd = sgl_xy_has_component(dx,dy, sx, sy) ? sgl_abs(ds) : 256;
+ ed = sgl_xy_has_component(dx,dy, ex, ey) ? sgl_abs(de) : 256;
+ dx = sgl_min(sd, ed);
+ tmp_color = (dx < SGL_ALPHA_MAX) ? sgl_color_mixer(desc->color, *blend, sgl_min(255 - dx, edge_alpha)) : *blend;
+ break;
+
+ case SGL_ARC_MODE_RING:
+ sd = sgl_xy_has_component(dx,dy, sx, sy) ? sgl_abs(ds) : 256;
+ ed = sgl_xy_has_component(dx,dy, ex, ey) ? sgl_abs(de) : 256;
+ dx = sgl_min(sd, ed);
+ tmp_color = (dx < SGL_ALPHA_MAX) ? sgl_color_mixer(desc->color, desc->bg_color, sgl_min(255 - dx, edge_alpha)) : desc->bg_color;
+ break;
+
+ case SGL_ARC_MODE_NORMAL_SMOOTH:
+ dx = arc_get_dot(arc_dot, x, y);
+ tmp_color = (dx < SGL_ALPHA_MAX) ? sgl_color_mixer(desc->color, *blend, dx) : desc->color;
+ break;
+
+ case SGL_ARC_MODE_RING_SMOOTH:
+ dx = arc_get_dot(arc_dot, x, y);
+ tmp_color = (dx < SGL_ALPHA_MAX) ? sgl_color_mixer(desc->color, desc->bg_color, dx) : desc->color;
+ break;
+
+ default: break;
+ }
+ }
+ }
+
+ *blend = desc->alpha == SGL_ALPHA_MAX ? sgl_color_mixer(tmp_color, *blend, edge_alpha) : sgl_color_mixer(sgl_color_mixer(tmp_color, *blend, edge_alpha), *blend, desc->alpha);
+ }
+ buf += surf->w;
+ }
+}
diff --git a/User/system/sgl/draw/sgl_draw_circle.c b/User/system/sgl/draw/sgl_draw_circle.c
new file mode 100644
index 0000000..065453e
--- /dev/null
+++ b/User/system/sgl/draw/sgl_draw_circle.c
@@ -0,0 +1,299 @@
+/* source/draw/sgl_draw_circle.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+
+
+/**
+ * @brief Draw a circle
+ * @param surf Surface
+ * @param area Area of the circle
+ * @param cx X coordinate of the center
+ * @param cy Y coordinate of the center
+ * @param radius Radius of the circle
+ * @param color Color of the circle
+ * @param alpha Alpha of the circle
+ * @return none
+ */
+void sgl_draw_fill_circle(sgl_surf_t *surf, sgl_area_t *area, int16_t cx, int16_t cy, int16_t radius, sgl_color_t color, uint8_t alpha)
+{
+ sgl_area_t clip = SGL_AREA_MAX;
+ sgl_color_t *buf = NULL, *blend = NULL;
+
+ sgl_surf_clip_area_return(surf, area, &clip);
+
+ sgl_area_t c_rect = {
+ .x1 = cx - radius,
+ .x2 = cx + radius,
+ .y1 = cy - radius,
+ .y2 = cy + radius
+ };
+ if (!sgl_area_selfclip(&clip, &c_rect)) {
+ return;
+ }
+
+ int y2 = 0, real_r2 = 0, edge_alpha = 0;
+ int r2 = sgl_pow2(radius);
+ int r2_edge = sgl_pow2(radius + 1);
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ y2 = sgl_pow2(y - cy);
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ real_r2 = sgl_pow2(x - cx) + y2;
+
+ if (real_r2 >= r2_edge) {
+ if(x > cx)
+ break;
+ continue;
+ }
+ else if (real_r2 >= r2) {
+ edge_alpha = SGL_ALPHA_MAX - sgl_sqrt_error(real_r2);
+ *blend = (alpha == SGL_ALPHA_MAX ? sgl_color_mixer(color, *blend, edge_alpha) : sgl_color_mixer(sgl_color_mixer(color, *blend, edge_alpha), *blend, alpha));
+ }
+ else {
+ *blend = (alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha));
+ }
+ }
+ buf += surf->w;
+ }
+}
+
+#if (!CONFIG_SGL_PIXMAP_BILINEAR_INTERP)
+/**
+ * @brief Draw a circle with pixmap and alpha
+ * @param surf Surface
+ * @param area Area of the circle
+ * @param cx X coordinate of the center
+ * @param cy Y coordinate of the center
+ * @param radius Radius of the circle
+ * @param pixmap Pixmap of image
+ * @param alpha Alpha of the circle
+ * @return none
+ */
+void sgl_draw_fill_circle_pixmap(sgl_surf_t *surf, sgl_area_t *area, int16_t cx, int16_t cy, int16_t radius, const sgl_pixmap_t *pixmap, uint8_t alpha)
+{
+ int y2 = 0, real_r2 = 0, s_x = cx - radius, s_y = cy - radius;
+ int r2 = radius * radius;
+ int r2_max = (radius + 1) * (radius + 1);
+ sgl_color_t *buf = NULL, *pbuf = NULL, *blend = NULL;
+ sgl_area_t clip = SGL_AREA_MAX;
+ uint8_t edge_alpha = 0;
+
+ sgl_surf_clip_area_return(surf, area, &clip);
+
+ sgl_area_t c_rect = {
+ .x1 = cx - radius,
+ .x2 = cx + radius,
+ .y1 = cy - radius,
+ .y2 = cy + radius
+ };
+ if (!sgl_area_selfclip(&clip, &c_rect)) {
+ return;
+ }
+
+ uint32_t scale_x = (pixmap->width << SGL_FIXED_SHIFT) / (radius * 2);
+ uint32_t scale_y = (pixmap->height << SGL_FIXED_SHIFT) / (radius * 2);
+ uint32_t step_x = 0, step_y = 0;
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ y2 = sgl_pow2(y - cy);
+ step_y = (scale_y * (y - s_y)) >> SGL_FIXED_SHIFT;
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ real_r2 = sgl_pow2(x - cx) + y2;
+
+ step_x = (scale_x * (x - s_x)) >> SGL_FIXED_SHIFT;
+ pbuf = sgl_pixmap_get_buf(pixmap, step_x, step_y);
+
+ if (real_r2 >= r2_max) {
+ if(x > cx)
+ break;
+ continue;
+ }
+ else if (real_r2 >= r2) {
+ edge_alpha = SGL_ALPHA_MAX - sgl_sqrt_error(real_r2);
+ *blend = (alpha == SGL_ALPHA_MAX ? sgl_color_mixer(*pbuf, *blend, edge_alpha) : sgl_color_mixer(sgl_color_mixer(*pbuf, *blend, edge_alpha), *blend, alpha));
+ }
+ else {
+ *blend = (alpha == SGL_ALPHA_MAX ? *pbuf : sgl_color_mixer(*pbuf, *blend, alpha));
+ }
+ }
+ buf += surf->w;
+ }
+}
+#else
+void sgl_draw_fill_circle_pixmap(sgl_surf_t *surf, sgl_area_t *area, int16_t cx, int16_t cy, int16_t radius, const sgl_pixmap_t *pixmap, uint8_t alpha)
+{
+ int y2 = 0, real_r2 = 0, s_x = cx - radius, s_y = cy - radius;
+ int r2 = radius * radius;
+ int r2_max = (radius + 1) * (radius + 1);
+ sgl_color_t *buf = NULL, *blend = NULL, ip_color, *pix = (sgl_color_t *)pixmap->bitmap.array;
+ sgl_area_t clip = SGL_AREA_MAX;
+ uint8_t edge_alpha = 0;
+ int fx = 0, fy = 0;
+
+ sgl_surf_clip_area_return(surf, area, &clip);
+
+ sgl_area_t c_rect = {
+ .x1 = cx - radius,
+ .x2 = cx + radius,
+ .y1 = cy - radius,
+ .y2 = cy + radius
+ };
+ if (!sgl_area_selfclip(&clip, &c_rect)) {
+ return;
+ }
+
+ const int32_t scale_x = ((int32_t)pixmap->width << SGL_FIXED_SHIFT) / (radius * 2);
+ const int32_t scale_y = ((int32_t)pixmap->height << SGL_FIXED_SHIFT) / (radius * 2);
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ y2 = sgl_pow2(y - cy);
+ fy = (int32_t)(y - s_y) * scale_y;
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ real_r2 = sgl_pow2(x - cx) + y2;
+
+ fx = (int32_t)(x - s_x) * scale_x;
+ ip_color = sgl_draw_biln_color(pix, pixmap->width, pixmap->height, fx, fy);
+
+ if (real_r2 >= r2_max) {
+ if(x > cx)
+ break;
+ continue;
+ }
+ else if (real_r2 >= r2) {
+ edge_alpha = SGL_ALPHA_MAX - sgl_sqrt_error(real_r2);
+ *blend = (alpha == SGL_ALPHA_MAX ? sgl_color_mixer(ip_color, *blend, edge_alpha) : sgl_color_mixer(sgl_color_mixer(ip_color, *blend, edge_alpha), *blend, alpha));
+ }
+ else {
+ *blend = (alpha == SGL_ALPHA_MAX ? ip_color : sgl_color_mixer(ip_color, *blend, alpha));
+ }
+ }
+ buf += surf->w;
+ }
+}
+#endif // CONFIG_SGL_PIXMAP_BILINEAR_INTERP
+
+/**
+ * @brief Draw a circle with alpha and border
+ * @param surf Surface
+ * @param area Area of the circle
+ * @param cx X coordinate of the center
+ * @param cy Y coordinate of the center
+ * @param radius Radius of the circle
+ * @param color Color of the circle
+ * @param border_color Color of the border
+ * @param border_width Width of the border
+ * @param alpha Alpha of the circle
+ * @return none
+ */
+void sgl_draw_fill_circle_with_border(sgl_surf_t *surf, sgl_area_t *area, int16_t cx, int16_t cy, int16_t radius, sgl_color_t color, sgl_color_t border_color, int16_t border_width, uint8_t alpha)
+{
+ int radius_in = sgl_max(radius - border_width + 1, 0);
+ int y2 = 0, real_r2 = 0;
+ int in_r2 = sgl_pow2(radius_in);
+ int out_r2 = sgl_pow2(radius);
+ sgl_color_t *buf = NULL, *blend = NULL;
+
+ int in_r2_max = sgl_pow2(radius_in - 1);
+ int out_r2_max = sgl_pow2(radius + 1);
+ uint8_t edge_alpha = 0;
+ sgl_area_t clip = SGL_AREA_MAX;
+
+ sgl_surf_clip_area_return(surf, area, &clip);
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ y2 = sgl_pow2(y - cy);
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ real_r2 = sgl_pow2(x - cx) + y2;
+
+ if (real_r2 >= out_r2_max) {
+ if (x > cx)
+ break;
+ continue;
+ }
+ if (real_r2 < in_r2_max) {
+ *blend = (alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha));
+ continue;
+ }
+ if (real_r2 < in_r2 ) {
+ edge_alpha = sgl_sqrt_error(real_r2);
+ *blend = (alpha == SGL_ALPHA_MAX ? sgl_color_mixer(border_color, color, sgl_sqrt_error(real_r2)) : sgl_color_mixer(sgl_color_mixer(border_color, color, edge_alpha), *blend, alpha));
+ }
+ else if (real_r2 > out_r2) {
+ edge_alpha = SGL_ALPHA_MAX - sgl_sqrt_error(real_r2);
+ *blend = (alpha == SGL_ALPHA_MAX ? sgl_color_mixer(border_color, *blend, edge_alpha) : sgl_color_mixer(sgl_color_mixer(border_color, *blend, edge_alpha), *blend, alpha));
+ }
+ else {
+ *blend = (alpha == SGL_ALPHA_MAX ? border_color : sgl_color_mixer(border_color, *blend, alpha));
+ }
+ }
+ buf += surf->w;
+ }
+}
+
+
+/**
+ * @brief draw task, the task contains the draw information and canvas
+ * @param surf surface pointer
+ * @param area the area of the task
+ * @param desc the draw information
+ * @return none
+ */
+void sgl_draw_circle(sgl_surf_t *surf, sgl_area_t *area, sgl_draw_circle_t *desc)
+{
+ sgl_color_t color = desc->color;
+ int16_t radius = desc->radius;
+ uint8_t alpha = desc->alpha;
+ uint16_t border = desc->border;
+ sgl_color_t border_color = desc->border_color;
+
+ if (unlikely(desc->alpha == SGL_ALPHA_MIN)) {
+ return;
+ }
+
+ if (desc->pixmap == NULL) {
+ if (border) {
+ sgl_draw_fill_circle_with_border(surf, area, desc->cx, desc->cy, radius, color, border_color, border, alpha);
+ }
+ else {
+ sgl_draw_fill_circle(surf, area, desc->cx, desc->cy, radius, color, alpha);
+ }
+ }
+ else {
+ sgl_draw_fill_circle_pixmap(surf, area, desc->cx, desc->cy, radius, desc->pixmap, alpha);
+ }
+}
diff --git a/User/system/sgl/draw/sgl_draw_icon.c b/User/system/sgl/draw/sgl_draw_icon.c
new file mode 100644
index 0000000..9f00f39
--- /dev/null
+++ b/User/system/sgl/draw/sgl_draw_icon.c
@@ -0,0 +1,79 @@
+/* source/draw/sgl_draw_icon.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+
+
+/**
+ * @brief draw icon with alpha
+ * @param surf surface
+ * @param area area of icon
+ * @param coords coords of icon
+ * @param alpha alpha of icon
+ * @param icon icon pixmap
+ * @return none
+ * @note This function is only for 4bpp icon bitmap
+ */
+void sgl_draw_icon( sgl_surf_t *surf, sgl_area_t *area, int16_t x, int16_t y, sgl_color_t color, uint8_t alpha, const sgl_icon_pixmap_t *icon)
+{
+ const uint8_t *dot = icon->bitmap;
+ sgl_area_t clip = SGL_AREA_MAX;
+ sgl_color_t *buf = NULL;
+ int rel_x, rel_y, byte_x, dot_index;
+ uint8_t alpha_dot;
+
+ sgl_area_t icon_rect = {
+ .x1 = x,
+ .x2 = x + icon->width - 1,
+ .y1 = y,
+ .y2 = y + icon->height - 1,
+ };
+
+ if (!sgl_surf_clip(surf, &icon_rect, &clip)) {
+ return;
+ }
+
+ if (!sgl_area_selfclip(&clip, area)) {
+ return;
+ }
+
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, y - surf->y1);
+ rel_y = y - icon_rect.y1;
+
+ for (int x = clip.x1; x <= clip.x2; x++) {
+ rel_x = x - icon_rect.x1;
+
+ byte_x = rel_x >> 1;
+ dot_index = byte_x + (rel_y * (icon->width >> 1));
+ alpha_dot = (rel_x & 1) ? dot[dot_index] & 0xF : (dot[dot_index] >> 4);
+ alpha_dot = alpha_dot | (alpha_dot << 4);
+ *buf = (alpha == SGL_ALPHA_MAX ? sgl_color_mixer(color, *buf, alpha_dot) : sgl_color_mixer(sgl_color_mixer(color, *buf, alpha_dot), *buf, alpha));
+ buf++;
+ }
+ }
+}
diff --git a/User/system/sgl/draw/sgl_draw_line.c b/User/system/sgl/draw/sgl_draw_line.c
new file mode 100644
index 0000000..c1fa6fa
--- /dev/null
+++ b/User/system/sgl/draw/sgl_draw_line.c
@@ -0,0 +1,195 @@
+/* source/draw/sgl_draw_line.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+
+/**
+ * @brief draw a horizontal line with alpha
+ * @param surf surface
+ * @param area area that contains the line
+ * @param y line y position
+ * @param x1 line start x position
+ * @param x2 line end x position
+ * @param color line color
+ * @param alpha alpha of color
+ * @return none
+ */
+void sgl_draw_fill_hline(sgl_surf_t *surf, sgl_area_t *area, int16_t y, int16_t x1, int16_t x2, uint8_t width, sgl_color_t color, uint8_t alpha)
+{
+ sgl_color_t *buf = NULL, *blend = NULL;
+ sgl_area_t c_rect = {.x1 = x1, .x2 = x2, .y1 = y - (width - 1) / 2, .y2 = y + width / 2}, clip = SGL_AREA_MAX;
+
+ if (c_rect.x1 > c_rect.x2) {
+ sgl_swap(&c_rect.x1, &c_rect.x2);
+ }
+
+ sgl_surf_clip_area_return(surf, area, &clip);
+ if (!sgl_area_selfclip(&clip, &c_rect)) {
+ return;
+ }
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ *blend = alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha);
+ }
+ buf += surf->w;
+ }
+}
+
+
+/**
+ * @brief draw a vertical line with alpha
+ * @param surf surface
+ * @param area area that contains the line
+ * @param x x coordinate
+ * @param y1 y1 coordinate
+ * @param y2 y2 coordinate
+ * @param color line color
+ * @param alpha alpha of color
+ * @return none
+ */
+void sgl_draw_fill_vline(sgl_surf_t *surf, sgl_area_t *area, int16_t x, int16_t y1, int16_t y2, uint8_t width, sgl_color_t color, uint8_t alpha)
+{
+ sgl_color_t *buf = NULL, *blend = NULL;
+ sgl_area_t c_rect = {.x1 = x - (width - 1) / 2, .x2 = x + width / 2, .y1 = y1,.y2 = y2}, clip = SGL_AREA_MAX;
+
+ if (c_rect.y1 > c_rect.y2) {
+ sgl_swap(&c_rect.y1, &c_rect.y2);
+ }
+
+ sgl_surf_clip_area_return(surf, area, &clip);
+ if (!sgl_area_selfclip(&clip, &c_rect)) {
+ return;
+ }
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ *blend = (alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha));
+ }
+ buf += surf->w;
+ }
+}
+
+/**
+ * SDF draw anti-aliased line
+ * @param thickness line thickness (in pixels)
+ */
+static int32_t sgl_capsule_sdf_optimized(int16_t px, int16_t py, int16_t ax, int16_t ay, int16_t bx, int16_t by)
+{
+ int64_t pax = px - ax, pay = py - ay, bax = bx - ax, bay = by - ay;
+ int64_t b_sqd = bax * bax + bay * bay;
+ int64_t h = (sgl_max(sgl_min((pax * bax + pay * bay), b_sqd), 0)) << 8;
+ int64_t dx = (pax << 8) - bax * h / b_sqd;
+ int64_t dy = (pay << 8) - bay * h / b_sqd;
+
+ return sgl_sqrt(dx * dx + dy * dy);
+}
+
+
+/**
+ * @brief draw a slanted line with alpha
+ * @param surf surface
+ * @param area area that contains the line
+ * @param x1 line start x position
+ * @param y1 line start y position
+ * @param x2 line end x position
+ * @param y2 line end y position
+ * @param thickness line width
+ * @param color line color
+ * @param alpha alpha of color
+ * @return none
+ * @note This algorithm is SDF algorithm
+ */
+void draw_line_fill_slanted(sgl_surf_t *surf, sgl_area_t *area, int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t thickness, sgl_color_t color, uint8_t alpha)
+{
+ uint8_t c;
+ int64_t len;
+ sgl_area_t clip = SGL_AREA_MAX;
+ sgl_color_t *buf = NULL, *blend = NULL;
+ int16_t thick_half = (thickness >> 1);
+
+ sgl_area_t c_rect = {
+ .x1 = (x1 < x2 ? x1 : x2) - thick_half,
+ .x2 = (x1 > x2 ? x1 : x2) + thick_half,
+ .y1 = (y1 < y2 ? y1 : y2) - thick_half,
+ .y2 = (y1 > y2 ? y1 : y2) + thick_half,
+ };
+
+ sgl_surf_clip_area_return(surf, area, &clip);
+ if (!sgl_area_selfclip(&clip, &c_rect)) {
+ return;
+ }
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ len = sgl_capsule_sdf_optimized(x, y, x1, y1, x2, y2);
+
+ if (len <= (thick_half - 1) << 8) {
+ *blend = (alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha));
+ continue;
+ }
+
+ if (len > ((thick_half - 1) << 8) && len < (thick_half << 8)) {
+ c = len - ((thick_half - 1) << 8);
+
+ if (alpha == SGL_ALPHA_MAX)
+ *blend = sgl_color_mixer(*blend, color, c);
+ else
+ *blend = sgl_color_mixer(sgl_color_mixer(*blend, color, c), *blend, alpha);
+ }
+ }
+ buf += surf->w;
+ }
+}
+
+
+/**
+ * @brief draw a line
+ * @param surf surface
+ * @param area area that contains the line
+ * @param desc line description
+ * @return none
+ */
+void sgl_draw_line(sgl_surf_t *surf, sgl_area_t *area, sgl_draw_line_t *desc)
+{
+ if (desc->x1 == desc->x2) {
+ sgl_draw_fill_vline(surf, area, desc->x1, desc->y1, desc->y2, desc->width / 2, desc->color, desc->alpha);
+ }
+ else if (desc->y1 == desc->y2) {
+ sgl_draw_fill_hline(surf, area, desc->y1, desc->x1, desc->x2, desc->width / 2, desc->color, desc->alpha);
+ }
+ else {
+ draw_line_fill_slanted(surf, area, desc->x1, desc->y1, desc->x2, desc->y2, desc->width, desc->color, desc->alpha);
+ }
+}
diff --git a/User/system/sgl/draw/sgl_draw_rect.c b/User/system/sgl/draw/sgl_draw_rect.c
new file mode 100644
index 0000000..6078ce1
--- /dev/null
+++ b/User/system/sgl/draw/sgl_draw_rect.c
@@ -0,0 +1,454 @@
+/* source/draw/sgl_draw_rect.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#include
+#include
+#include
+
+
+/**
+ * @brief fill a round rectangle with alpha
+ * @param surf point to surface
+ * @param area area of rectangle that you want to draw
+ * @param rect point to rectangle that you want to draw
+ * @param radius radius of round
+ * @param color color of rectangle
+ * @param alpha alpha of rectangle
+ * @return none
+ */
+void sgl_draw_fill_rect(sgl_surf_t *surf, sgl_area_t *area, sgl_area_t *rect, int16_t radius, sgl_color_t color, uint8_t alpha)
+{
+ sgl_area_t clip;
+ sgl_color_t *buf = NULL, *blend = NULL;
+ uint8_t edge_alpha = 0;
+ int cx1 = rect->x1 + radius;
+ int cx2 = rect->x2 - radius;
+ int cy1 = rect->y1 + radius;
+ int cy2 = rect->y2 - radius;
+ int cx_tmp = 0;
+ int cy_tmp = 0;
+
+ if (!sgl_surf_clip(surf, area, &clip)) {
+ return;
+ }
+
+ if (!sgl_area_selfclip(&clip, rect)) {
+ return;
+ }
+
+ int y2 = 0, real_r2 = 0;
+ int r2 = sgl_pow2(radius);
+ int r2_edge = sgl_pow2(radius + 1);
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ if (radius == 0) {
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ *blend = alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha);
+ }
+ buf += surf->w;
+ }
+ }
+ else {
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ if (y > cy1 && y < cy2) {
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ *blend = (alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha));
+ }
+ }
+ else {
+ cy_tmp = y > cy1 ? cy2 : cy1;
+ y2 = sgl_pow2(y - cy_tmp);
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ if (x > cx1 && x < cx2) {
+ *blend = (alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha));
+ }
+ else {
+ cx_tmp = x > cx1 ? cx2 : cx1;
+ real_r2 = sgl_pow2(x - cx_tmp) + y2;
+ if (real_r2 >= r2_edge) {
+ continue;
+ }
+ else if (real_r2 >= r2) {
+ edge_alpha = SGL_ALPHA_MAX - sgl_sqrt_error(real_r2);
+ *blend = (alpha == SGL_ALPHA_MAX ? sgl_color_mixer(color, *blend, edge_alpha) : sgl_color_mixer(sgl_color_mixer(color, *blend, edge_alpha), *blend, alpha));
+ }
+ else {
+ *blend = (alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha));
+ }
+ }
+ }
+ }
+ buf += surf->w;
+ }
+ }
+}
+
+
+#include
+/**
+ * @brief fill a round rectangle with alpha and border
+ * @param surf point to surface
+ * @param area area of rectangle that you want to draw
+ * @param rect point to rectangle that you want to draw
+ * @param radius radius of round
+ * @param color color of rectangle
+ * @param border_color color of border
+ * @param border_width width of border
+ * @param alpha alpha of rectangle
+ * @return none
+ */
+void sgl_draw_fill_rect_with_border(sgl_surf_t *surf, sgl_area_t *area, sgl_area_t *rect, int16_t radius, sgl_color_t color, sgl_color_t border_color, uint8_t border_width, uint8_t alpha)
+{
+ int radius_in = sgl_max(radius - border_width + 1, 0);
+ int y2 = 0, real_r2 = 0;
+ int in_r2 = sgl_pow2(radius_in);
+ int out_r2 = sgl_pow2(radius);
+ sgl_color_t *buf = NULL, *blend = NULL;
+ uint8_t edge_alpha = 0;
+
+ int cx1 = rect->x1 + radius;
+ int cx2 = rect->x2 - radius;
+ int cy1 = rect->y1 + radius;
+ int cy2 = rect->y2 - radius;
+ int cx1i = rect->x1 + border_width;
+ int cx2i = rect->x2 - border_width;
+ int cyi1 = rect->y1 + border_width;
+ int cyi2 = rect->y2 - border_width;
+ int cx_tmp = 0;
+ int cy_tmp = 0;
+
+ int in_r2_max = sgl_pow2(radius_in - 1);
+ int out_r2_max = sgl_pow2(radius + 1);
+
+ sgl_area_t clip;
+
+ if (!sgl_surf_clip(surf, area, &clip)) {
+ return;
+ }
+
+ if (!sgl_area_selfclip(&clip, rect)) {
+ return;
+ }
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ if (radius == 0) {
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ if (x >= cx1i && x <= cx2i && y >= cyi1 && y <= cyi2) {
+ *blend = alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha);
+ }
+ else {
+ *blend = alpha == SGL_ALPHA_MAX ? border_color : sgl_color_mixer(border_color, *blend, alpha);
+ }
+ }
+ buf += surf->w;
+ }
+ }
+ else {
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ if (y > cy1 && y < cy2) {
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ if (x < cx1i || x > cx2i) {
+ *blend = (alpha == SGL_ALPHA_MAX ? border_color : sgl_color_mixer(border_color, *blend, alpha));
+ }
+ else {
+ *blend = (alpha == SGL_ALPHA_MAX ? color: sgl_color_mixer(color, *blend, alpha));
+ }
+ }
+ }
+ else {
+ cy_tmp = y > cy1 ? cy2 : cy1;
+ y2 = sgl_pow2(y - cy_tmp);
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ if (x >= cx1 && x <= cx2) {
+ if (y < cyi1 || y > cyi2) {
+ *blend = (alpha == SGL_ALPHA_MAX ? border_color : sgl_color_mixer(border_color, *blend, alpha));
+ }
+ else {
+ *blend = (alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha));
+ }
+ }
+ else {
+ cx_tmp = x > cx1 ? cx2 : cx1;
+ real_r2 = sgl_pow2(x - cx_tmp) + y2;
+
+ if (real_r2 >= out_r2_max) {
+ continue;
+ }
+ if (real_r2 < in_r2_max) {
+ *blend = (alpha == SGL_ALPHA_MAX ? color : sgl_color_mixer(color, *blend, alpha));
+ continue;
+ }
+ if (real_r2 < in_r2 ) {
+ edge_alpha = sgl_sqrt_error(real_r2);
+ *blend = (alpha == SGL_ALPHA_MAX ? sgl_color_mixer(border_color, color, edge_alpha) : sgl_color_mixer(sgl_color_mixer(border_color, color, edge_alpha), *blend, alpha));
+ }
+ else if (real_r2 > out_r2) {
+ edge_alpha = SGL_ALPHA_MAX - sgl_sqrt_error(real_r2);
+ *blend = (alpha == SGL_ALPHA_MAX ? sgl_color_mixer(border_color, *blend, edge_alpha) : sgl_color_mixer(sgl_color_mixer(border_color, *blend, edge_alpha), *blend, alpha));
+ }
+ else {
+ *blend = (alpha == SGL_ALPHA_MAX ? border_color : sgl_color_mixer(border_color, *blend, alpha));
+ }
+ }
+ }
+ }
+ buf += surf->w;
+ }
+ }
+}
+
+
+#if (!CONFIG_SGL_PIXMAP_BILINEAR_INTERP)
+/**
+ * @brief fill a round rectangle pixmap with alpha
+ * @param surf point to surface
+ * @param area area of rectangle that you want to draw
+ * @param rect point to rectangle that you want to draw
+ * @param radius radius of round
+ * @param pixmap pixmap of rectangle
+ * @param alpha alpha of rectangle
+ * @return none
+ */
+void sgl_draw_fill_rect_pixmap(sgl_surf_t *surf, sgl_area_t *area, sgl_area_t *rect, int16_t radius, const sgl_pixmap_t *pixmap, uint8_t alpha)
+{
+ sgl_area_t clip;
+ sgl_color_t *buf = NULL, *blend = NULL;
+ sgl_color_t *pbuf = NULL;
+ uint8_t edge_alpha = 0;
+ int cx1 = rect->x1 + radius;
+ int cx2 = rect->x2 - radius;
+ int cy1 = rect->y1 + radius;
+ int cy2 = rect->y2 - radius;
+ int cx_tmp = 0;
+ int cy_tmp = 0;
+
+ if (!sgl_surf_clip(surf, area, &clip)) {
+ return;
+ }
+
+ if (!sgl_area_selfclip(&clip, rect)) {
+ return;
+ }
+
+ int y2 = 0, real_r2 = 0;
+ int r2 = sgl_pow2(radius);
+ int r2_edge = sgl_pow2(radius + 1);
+ uint32_t scale_x = ((pixmap->width << SGL_FIXED_SHIFT) / (rect->x2 - rect->x1 + 1));
+ uint32_t scale_y = ((pixmap->height << SGL_FIXED_SHIFT) / (rect->y2 - rect->y1 + 1));
+ uint32_t step_x = 0, step_y = 0;
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ if (radius == 0) {
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ step_y = (scale_y * (y - rect->y1)) >> SGL_FIXED_SHIFT;
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ step_x = (scale_x * (x - rect->x1)) >> SGL_FIXED_SHIFT;
+ pbuf = sgl_pixmap_get_buf(pixmap, step_x, step_y);
+ *blend = (alpha == SGL_ALPHA_MAX ? *pbuf : sgl_color_mixer(*pbuf, *blend, alpha));
+ }
+ buf += surf->w;
+ }
+ }
+ else {
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ step_y = (scale_y * (y - rect->y1)) >> SGL_FIXED_SHIFT;
+ if (y > cy1 && y < cy2) {
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ step_x = (scale_x * (x - rect->x1)) >> SGL_FIXED_SHIFT;
+ pbuf = sgl_pixmap_get_buf(pixmap, step_x, step_y);
+ *blend = (alpha == SGL_ALPHA_MAX ? *pbuf : sgl_color_mixer(*pbuf, *blend, alpha));
+ }
+ }
+ else {
+ cy_tmp = y > cy1 ? cy2 : cy1;
+ y2 = sgl_pow2(y - cy_tmp);
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ step_x = (scale_x * (x - rect->x1)) >> SGL_FIXED_SHIFT;
+ pbuf = sgl_pixmap_get_buf(pixmap, step_x, step_y);
+
+ if (x > cx1 && x < cx2) {
+ *blend = (alpha == SGL_ALPHA_MAX ? *pbuf : sgl_color_mixer(*pbuf, *blend, alpha));
+ }
+ else {
+ cx_tmp = x > cx1 ? cx2 : cx1;
+ real_r2 = sgl_pow2(x - cx_tmp) + y2;
+ if (real_r2 >= r2_edge) {
+ continue;
+ }
+ else if (real_r2 >= r2) {
+ edge_alpha = SGL_ALPHA_MAX - sgl_sqrt_error(real_r2);
+ *blend = (alpha == SGL_ALPHA_MAX ? sgl_color_mixer(*pbuf, *blend, edge_alpha) : sgl_color_mixer(sgl_color_mixer(*pbuf, *blend, edge_alpha), *blend, alpha));
+ }
+ else {
+ *blend = (alpha == SGL_ALPHA_MAX ? *pbuf : sgl_color_mixer(*pbuf, *blend, alpha));
+ }
+ }
+ }
+ }
+ buf += surf->w;
+ }
+ }
+}
+
+#else
+/**
+ * @brief fill a round rectangle pixmap with alpha
+ * @param surf point to surface
+ * @param area area of rectangle that you want to draw
+ * @param rect point to rectangle that you want to draw
+ * @param radius radius of round
+ * @param pixmap pixmap of rectangle
+ * @param alpha alpha of rectangle
+ * @return none
+ */
+void sgl_draw_fill_rect_pixmap(sgl_surf_t *surf, sgl_area_t *area, sgl_area_t *rect, int16_t radius, const sgl_pixmap_t *pixmap, uint8_t alpha)
+{
+ sgl_area_t clip;
+ sgl_color_t *buf = NULL, *blend = NULL, *pix = (sgl_color_t *)pixmap->bitmap.array;
+ sgl_color_t ip_color;
+ uint8_t edge_alpha = 0;
+ int cx1 = rect->x1 + radius;
+ int cx2 = rect->x2 - radius;
+ int cy1 = rect->y1 + radius;
+ int cy2 = rect->y2 - radius;
+ int cx_tmp = 0, fx = 0;
+ int cy_tmp = 0, fy = 0;
+
+ if (!sgl_surf_clip(surf, area, &clip)) {
+ return;
+ }
+
+ if (!sgl_area_selfclip(&clip, rect)) {
+ return;
+ }
+
+ int y2 = 0, real_r2 = 0;
+ int r2 = sgl_pow2(radius);
+ int r2_edge = sgl_pow2(radius + 1);
+
+ const int32_t rect_w = rect->x2 - rect->x1 + 1;
+ const int32_t rect_h = rect->y2 - rect->y1 + 1;
+ const int32_t scale_x = ((int32_t)pixmap->width << SGL_FIXED_SHIFT) / rect_w;
+ const int32_t scale_y = ((int32_t)pixmap->height << SGL_FIXED_SHIFT) / rect_h;
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+
+ if (radius == 0) {
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ fy = (int32_t)(y - rect->y1) * scale_y;
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ fx = (int32_t)(x - rect->x1) * scale_x;
+ ip_color = sgl_draw_biln_color(pix, pixmap->width, pixmap->height, fx, fy);
+ *blend = (alpha == SGL_ALPHA_MAX) ? ip_color : sgl_color_mixer(ip_color, *blend, alpha);
+ }
+ buf += surf->w;
+ }
+ }
+ else {
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ fy = (int32_t)(y - rect->y1) * scale_y;
+
+ if (y > cy1 && y < cy2) {
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ fx = (int32_t)(x - rect->x1) * scale_x;
+ ip_color = sgl_draw_biln_color(pix, pixmap->width, pixmap->height, fx, fy);
+ *blend = (alpha == SGL_ALPHA_MAX) ? ip_color : sgl_color_mixer(ip_color, *blend, alpha);
+ }
+ }
+ else {
+ cy_tmp = y > cy1 ? cy2 : cy1;
+ y2 = sgl_pow2(y - cy_tmp);
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ fx = (int32_t)(x - rect->x1) * scale_x;
+ ip_color = sgl_draw_biln_color(pix, pixmap->width, pixmap->height, fx, fy);
+
+ if (x > cx1 && x < cx2) {
+ *blend = (alpha == SGL_ALPHA_MAX) ? ip_color : sgl_color_mixer(ip_color, *blend, alpha);
+ }
+ else {
+ cx_tmp = x > cx1 ? cx2 : cx1;
+ real_r2 = sgl_pow2(x - cx_tmp) + y2;
+ if (real_r2 >= r2_edge) {
+ continue;
+ }
+ else if (real_r2 >= r2) {
+ edge_alpha = SGL_ALPHA_MAX - sgl_sqrt_error(real_r2);
+ *blend = (alpha == SGL_ALPHA_MAX) ? sgl_color_mixer(ip_color, *blend, edge_alpha) :
+ sgl_color_mixer(sgl_color_mixer(ip_color, *blend, edge_alpha), *blend, alpha);
+ }
+ else {
+ *blend = (alpha == SGL_ALPHA_MAX) ? ip_color : sgl_color_mixer(ip_color, *blend, alpha);
+ }
+ }
+ }
+ }
+ buf += surf->w;
+ }
+ }
+}
+#endif
+
+
+/**
+ * @brief fill a round rectangle with alpha
+ * @param surf point to surface
+ * @param area area of rectangle that you want to draw
+ * @param rect point to rectangle that you want to draw
+ * @param desc rectangle description
+ * @return none
+ */
+void sgl_draw_rect(sgl_surf_t *surf, sgl_area_t *area, sgl_rect_t *rect, sgl_draw_rect_t *desc)
+{
+ if (unlikely(desc->alpha == SGL_ALPHA_MIN)) {
+ return;
+ }
+
+ if (desc->pixmap == NULL) {
+ if (desc->border == 0) {
+ sgl_draw_fill_rect(surf, area, rect, desc->radius, desc->color, desc->alpha);
+ }
+ else {
+ sgl_draw_fill_rect_with_border(surf, area, rect, desc->radius, desc->color, desc->border_color, desc->border, desc->alpha);
+ }
+ }
+ else {
+ sgl_draw_fill_rect_pixmap(surf, area, rect, desc->radius, desc->pixmap, desc->alpha);
+ }
+}
diff --git a/User/system/sgl/draw/sgl_draw_ring.c b/User/system/sgl/draw/sgl_draw_ring.c
new file mode 100644
index 0000000..a3351da
--- /dev/null
+++ b/User/system/sgl/draw/sgl_draw_ring.c
@@ -0,0 +1,110 @@
+/* source/draw/sgl_draw_ring.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+
+
+/**
+ * @brief draw a ring on surface with alpha
+ * @param surf: pointer of surface
+ * @param area: pointer of area
+ * @param cx: ring center x
+ * @param cy: ring center y
+ * @param radius_in: ring inner radius
+ * @param radius_out: ring outer radius
+ * @param color: ring color
+ * @param alpha: ring alpha
+ * @return none
+ */
+void sgl_draw_fill_ring(sgl_surf_t *surf, sgl_area_t *area, int16_t cx, int16_t cy, int16_t radius_in, int16_t radius_out, sgl_color_t color, uint8_t alpha)
+{
+ int y2 = 0, real_r2 = 0, edge_alpha = 0;
+ int in_r2 = sgl_pow2(radius_in);
+ int out_r2 = sgl_pow2(radius_out);
+
+ int in_r2_max = sgl_pow2(radius_in - 1);
+ int out_r2_max = sgl_pow2(radius_out + 1);
+ sgl_color_t *buf = NULL, *blend = NULL;
+ sgl_area_t clip;
+
+ if (unlikely(alpha == SGL_ALPHA_MIN)) {
+ return;
+ }
+
+ if (!sgl_surf_clip(surf, area, &clip)) {
+ return;
+ }
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ y2 = sgl_pow2(y - cy);
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ real_r2 = sgl_pow2(x - cx) + y2;
+
+ if (real_r2 >= out_r2_max) {
+ if (x > cx) break;
+ continue;
+ }
+ if (real_r2 < in_r2_max) {
+ if (x < cx) {
+ blend += ((cx - x) * 2);
+ x = cx*2 - x;
+ }
+ continue;
+ }
+
+ if (alpha == SGL_ALPHA_MAX) {
+ if (real_r2 < in_r2 ) {
+ *blend = sgl_color_mixer(color, *blend, sgl_sqrt_error(real_r2));
+ }
+ else if (real_r2 > out_r2) {
+ *blend = sgl_color_mixer(color, *blend, SGL_ALPHA_MAX - sgl_sqrt_error(real_r2));
+ }
+ else {
+ *blend = color;
+ }
+ }
+ else {
+ if (real_r2 < in_r2 ) {
+ edge_alpha = sgl_sqrt_error(real_r2);
+ sgl_color_t color_mix = sgl_color_mixer(color, *blend, edge_alpha);
+ *blend = sgl_color_mixer(color_mix, *blend, alpha);
+ }
+ else if (real_r2 > out_r2) {
+ edge_alpha = SGL_ALPHA_MAX - sgl_sqrt_error(real_r2);
+ sgl_color_t color_mix = sgl_color_mixer(color, *blend, edge_alpha);
+ *blend = sgl_color_mixer(color_mix, *blend, alpha);
+ }
+ else {
+ *blend = sgl_color_mixer(color, *blend, alpha);
+ }
+ }
+ }
+ buf += surf->w;
+ }
+}
diff --git a/User/system/sgl/draw/sgl_draw_text.c b/User/system/sgl/draw/sgl_draw_text.c
new file mode 100644
index 0000000..c254ed0
--- /dev/null
+++ b/User/system/sgl/draw/sgl_draw_text.c
@@ -0,0 +1,357 @@
+/* source/draw/sgl_draw_text.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+
+
+#if (CONFIG_SGL_FONT_COMPRESSED)
+/**
+ * @brief RLE state, refrence LVGL
+ */
+typedef enum {
+ RLE_STATE_SINGLE = 0,
+ RLE_STATE_REPEATED,
+ RLE_STATE_COUNTER,
+} sgl_font_rle_state_t;
+
+/**
+ * @brief RLE decompress information structure
+ */
+typedef struct {
+ uint32_t rdp;
+ const uint8_t * in;
+ uint8_t bpp;
+ uint8_t prev_v;
+ uint8_t count;
+ sgl_font_rle_state_t state;
+} sgl_font_rle_t;
+
+static sgl_font_rle_t font_rle = {
+ .rdp = 0,
+ .in = NULL,
+ .bpp = 0,
+ .prev_v = 0,
+ .count = 0,
+ .state = RLE_STATE_SINGLE,
+};
+
+/**
+ * @brief Get bits from a byte array
+ * @param in the byte array
+ * @param bit_pos the bit position
+ * @param len the bit length
+ * @return the bits of a byte
+ */
+static inline uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len)
+{
+ uint8_t bit_mask;
+ switch(len) {
+ case 1:
+ bit_mask = 0x1;
+ break;
+ case 2:
+ bit_mask = 0x3;
+ break;
+ case 4:
+ bit_mask = 0xF;
+ break;
+ default:
+ bit_mask = (uint16_t)((uint16_t) 1 << len) - 1;
+ }
+
+ uint32_t byte_pos = bit_pos >> 3;
+ bit_pos = bit_pos & 0x7;
+
+ if(bit_pos + len >= 8) {
+ uint16_t in16 = (in[byte_pos] << 8) + in[byte_pos + 1];
+ return (in16 >> (16 - bit_pos - len)) & bit_mask;
+ }
+ else {
+ return (in[byte_pos] >> (8 - bit_pos - len)) & bit_mask;
+ }
+}
+
+/**
+ * @brief Decompress a line of RLE data
+ * @param out the decompressed data
+ * @param w the width of the decompressed data
+ * @return none
+ */
+static inline void decompress_line(uint8_t *out, int32_t w)
+{
+ int32_t i;
+ uint8_t v = 0;
+ uint8_t ret = 0;
+ sgl_font_rle_t *rle = &font_rle;
+
+ for(i = 0; i < w; i++) {
+ if(rle->state == RLE_STATE_SINGLE) {
+ ret = get_bits(rle->in, rle->rdp, rle->bpp);
+ if(rle->rdp != 0 && rle->prev_v == ret) {
+ rle->count = 0;
+ rle->state = RLE_STATE_REPEATED;
+ }
+
+ rle->prev_v = ret;
+ rle->rdp += rle->bpp;
+ }
+ else if(rle->state == RLE_STATE_REPEATED) {
+ v = get_bits(rle->in, rle->rdp, 1);
+ rle->count++;
+ rle->rdp += 1;
+ if(v == 1) {
+ ret = rle->prev_v;
+ if(rle->count == 11) {
+ rle->count = get_bits(rle->in, rle->rdp, 6);
+ rle->rdp += 6;
+ if(rle->count != 0) {
+ rle->state = RLE_STATE_COUNTER;
+ }
+ else {
+ ret = get_bits(rle->in, rle->rdp, rle->bpp);
+ rle->prev_v = ret;
+ rle->rdp += rle->bpp;
+ rle->state = RLE_STATE_SINGLE;
+ }
+ }
+ }
+ else {
+ ret = get_bits(rle->in, rle->rdp, rle->bpp);
+ rle->prev_v = ret;
+ rle->rdp += rle->bpp;
+ rle->state = RLE_STATE_SINGLE;
+ }
+ }
+ else if(rle->state == RLE_STATE_COUNTER) {
+ ret = rle->prev_v;
+ rle->count--;
+ if(rle->count == 0) {
+ ret = get_bits(rle->in, rle->rdp, rle->bpp);
+ rle->prev_v = ret;
+ rle->rdp += rle->bpp;
+ rle->state = RLE_STATE_SINGLE;
+ }
+ }
+ if (out != NULL) {
+ out[i] = ret;
+ }
+ }
+}
+
+/**
+ * @brief Initialize the RLE decompression state
+ * @param in Pointer to the input data
+ * @param bpp Bits per pixel of the input data
+ * @return none
+ */
+static inline void font_rle_init(const uint8_t * in, uint8_t bpp)
+{
+ font_rle.in = in;
+ font_rle.bpp = bpp;
+ font_rle.state = RLE_STATE_SINGLE;
+ font_rle.rdp = 0;
+ font_rle.prev_v = 0;
+ font_rle.count = 0;
+}
+#endif // (!CONFIG_SGL_FONT_COMPRESSED)
+
+
+/**
+ * @brief Draw a character on the surface with alpha blending
+ * @param surf Pointer to the surface where the character will be drawn
+ * @param area Pointer to the area where the character will be drawn
+ * @param x X coordinate where the character will be drawn
+ * @param y Y coordinate where the character will be drawn
+ * @param ch_index Index of the character in the font table
+ * @param color Foreground color of the character
+ * @param alpha Alpha value for blending
+ * @param font Pointer to the font structure containing character data
+ * @return none
+ * @note this function is only support bpp:4
+ */
+void sgl_draw_character(sgl_surf_t *surf, sgl_area_t *area, int16_t x, int16_t y, uint32_t ch_index, sgl_color_t color, uint8_t alpha, const sgl_font_t *font)
+{
+ int offset_y2 = font->font_height - font->table[ch_index].ofs_y - font->base_line;
+ const uint8_t *dot = &font->bitmap[font->table[ch_index].bitmap_index];
+ const uint8_t font_w = font->table[ch_index].box_w;
+ const uint8_t font_h = font->table[ch_index].box_h;
+
+ uint8_t shift = 0;
+ uint32_t pixel_index, rel_x, rel_y;
+ uint16_t byte_index, alpha_dot = 0;
+ sgl_color_t color_mix, *buf = NULL, *blend = NULL;
+ sgl_area_t clip;
+
+ sgl_area_t text_rect = {
+ .x1 = x + font->table[ch_index].ofs_x,
+ .x2 = x + font->table[ch_index].ofs_x + font_w - 1,
+ .y1 = y + offset_y2 - font_h,
+ .y2 = y + offset_y2 - 1,
+ };
+
+ if (!sgl_surf_clip(surf, &text_rect, &clip)) {
+ return;
+ }
+
+ if (!sgl_area_selfclip(&clip, area)) {
+ return;
+ }
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+#if (CONFIG_SGL_FONT_COMPRESSED)
+ if (font->compress == 0) {
+#endif // (!CONFIG_SGL_FONT_COMPRESSED == 0)
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ rel_y = y - text_rect.y1;
+
+ for (int x = clip.x1; x <= clip.x2; x++) {
+ rel_x = x - text_rect.x1;
+ pixel_index = rel_y * font_w + rel_x;
+
+ if (font->bpp == 4) {
+ byte_index = pixel_index >> 1;
+ alpha_dot = sgl_opa4_table[(pixel_index & 1) ? (dot[byte_index] & 0x0F) : (dot[byte_index] >> 4)];
+ }
+ else if (font->bpp == 2) {
+ byte_index = pixel_index >> 2;
+ shift = (3 - (pixel_index & 0x3)) * 2;
+ alpha_dot = sgl_opa2_table[(dot[byte_index] >> shift) & 0x03];
+ }
+ else if (font->bpp == 1) {
+ byte_index = pixel_index >> 3;
+ shift = 7 - (pixel_index & 0x7);
+ alpha_dot = ((dot[byte_index] >> shift) & 0x01) ? SGL_ALPHA_MAX : SGL_ALPHA_MIN;
+ }
+
+ color_mix = sgl_color_mixer(color, *blend, alpha_dot);
+ *blend = sgl_color_mixer(color_mix, *blend, alpha);
+ blend++;
+ }
+ buf += surf->w;
+ }
+#if (CONFIG_SGL_FONT_COMPRESSED)
+ } /* support compressed font */
+ else {
+ uint8_t line_buf[128] = {0};
+ font_rle_init(dot, font->bpp);
+
+ for (int y = text_rect.y1; y < clip.y1; y++) {
+ decompress_line(NULL, font_w);
+ }
+
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ blend = buf;
+ decompress_line(line_buf, font_w);
+
+ for (int x = clip.x1; x <= clip.x2; x++) {
+ if (font->bpp == 4) {
+ color_mix = sgl_color_mixer(color, *blend, sgl_opa4_table[line_buf[x - text_rect.x1]]);
+ }
+ else if (font->bpp == 2) {
+ color_mix = sgl_color_mixer(color, *blend, sgl_opa2_table[line_buf[x - text_rect.x1]]);
+ }
+ else if (font->bpp == 1) {
+ color_mix = sgl_color_mixer(color, *blend, line_buf[x - text_rect.x1] ? SGL_ALPHA_MAX : SGL_ALPHA_MIN);
+ }
+ *blend = sgl_color_mixer(color_mix, *blend, alpha);
+ blend++;
+ }
+ buf += surf->w;
+ }
+ }
+#endif
+}
+
+
+/**
+ * @brief Draw a string on the surface with alpha blending
+ * @param surf Pointer to the surface where the string will be drawn
+ * @param area Pointer to the area where the string will be drawn
+ * @param x X coordinate of the top-left corner of the string
+ * @param y Y coordinate of the top-left corner of the string
+ * @param str Pointer to the string to be drawn
+ * @param color Foreground color of the string
+ * @param alpha Alpha value for blending
+ * @param font Pointer to the font structure containing character data
+ * @return none
+ */
+void sgl_draw_string(sgl_surf_t *surf, sgl_area_t *area, int16_t x, int16_t y, const char *str, sgl_color_t color, uint8_t alpha, const sgl_font_t *font)
+{
+ uint32_t ch_index;
+ uint32_t unicode = 0;
+
+ while (*str) {
+ str += sgl_utf8_to_unicode(str, &unicode);
+ ch_index = sgl_search_unicode_ch_index(font, unicode);
+ sgl_draw_character(surf, area, x, y, ch_index, color, alpha, font);
+ x += (font->table[ch_index].adv_w >> 4);
+ }
+}
+
+
+/**
+ * @brief Draw a string on the surface with alpha blending and multiple lines
+ * @param surf Pointer to the surface where the string will be drawn
+ * @param area Pointer to the area where the string will be drawn
+ * @param x X coordinate of the top-left corner of the string
+ * @param y Y coordinate of the top-left corner of the string
+ * @param str Pointer to the string to be drawn
+ * @param color Foreground color of the string
+ * @param alpha Alpha value for blending
+ * @param font Pointer to the font structure containing character data
+ * @param line_margin Margin between lines
+ * @return none
+ */
+void sgl_draw_string_mult_line(sgl_surf_t *surf, sgl_area_t *area, int16_t x, int16_t y, const char *str, sgl_color_t color, uint8_t alpha, const sgl_font_t *font, uint8_t line_margin)
+{
+ int16_t ch_index, ch_width;
+ int16_t x_off = x;
+ uint32_t unicode = 0;
+
+ while (*str) {
+ if (*str == '\n') {
+ x_off = x;
+ y += (font->font_height + line_margin);
+ str ++;
+ continue;
+ }
+
+ str += sgl_utf8_to_unicode(str, &unicode);
+ ch_index = sgl_search_unicode_ch_index(font, unicode);
+
+ ch_width = (font->table[ch_index].adv_w >> 4);
+
+ if ((x_off + ch_width) > area->x2) {
+ x_off = x;
+ y += (font->font_height + line_margin);
+ }
+
+ sgl_draw_character(surf, area, x_off, y, ch_index, color, alpha, font);
+ x_off += ch_width;
+ }
+}
diff --git a/User/system/sgl/draw/sgl_draw_xform.c b/User/system/sgl/draw/sgl_draw_xform.c
new file mode 100644
index 0000000..660eee3
--- /dev/null
+++ b/User/system/sgl/draw/sgl_draw_xform.c
@@ -0,0 +1,157 @@
+/* source/draw/sgl_draw_xform.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+
+/**
+ * @brief calculate a point color by bilinear interpolate
+ * @param buffer point to image pixmap start buffer
+ * @param w width of buffer
+ * @param h height of buffer
+ * @param fx x coordinate of point
+ * @param fy y coordinate of point
+ * @return point color
+ */
+sgl_color_t sgl_draw_biln_color(const sgl_color_t *buffer, int16_t w, int16_t h, int32_t fx, int32_t fy)
+{
+ sgl_color_t ret;
+ int32_t max_x = (((int32_t)w) - 1) << SGL_FIXED_SHIFT;
+ int32_t max_y = (((int32_t)h) - 1) << SGL_FIXED_SHIFT;
+ fx = fx < 0 ? 0 : (fx > max_x ? max_x : fx);
+ fy = fy < 0 ? 0 : (fy > max_y ? max_y : fy);
+
+ const int32_t x0 = fx >> SGL_FIXED_SHIFT;
+ const int32_t y0 = fy >> SGL_FIXED_SHIFT;
+ const int32_t dx = fx & SGL_FIXED_MASK;
+ const int32_t dy = fy & SGL_FIXED_MASK;
+ const int32_t dx1 = SGL_FIXED_ONE - dx;
+ const int32_t dy1 = SGL_FIXED_ONE - dy;
+ const int32_t point = (y0 * w) + x0;
+
+ const sgl_color_t p00 = buffer[point];
+ const sgl_color_t p01 = buffer[point + 1];
+ const sgl_color_t p10 = buffer[point + w];
+ const sgl_color_t p11 = buffer[point + w + 1];
+
+ const uint8_t r00 = p00.ch.red;
+ const uint8_t r01 = p01.ch.red;
+ const uint8_t r10 = p10.ch.red;
+ const uint8_t r11 = p11.ch.red;
+
+ const uint8_t g00 = p00.ch.green;
+ const uint8_t g01 = p01.ch.green;
+ const uint8_t g10 = p10.ch.green;
+ const uint8_t g11 = p11.ch.green;
+
+ const uint8_t b00 = p00.ch.blue;
+ const uint8_t b01 = p01.ch.blue;
+ const uint8_t b10 = p10.ch.blue;
+ const uint8_t b11 = p11.ch.blue;
+
+ ret.ch.red = ((r00 * dx1 * dy1) + (r01 * dx * dy1) + (r10 * dx1 * dy) + (r11 * dx * dy)) >> (2 * SGL_FIXED_SHIFT);
+ ret.ch.green = ((g00 * dx1 * dy1) + (g01 * dx * dy1) + (g10 * dx1 * dy) + (g11 * dx * dy)) >> (2 * SGL_FIXED_SHIFT);
+ ret.ch.blue = ((b00 * dx1 * dy1) + (b01 * dx * dy1) + (b10 * dx1 * dy) + (b11 * dx * dy)) >> (2 * SGL_FIXED_SHIFT);
+
+ return ret;
+}
+
+
+/**
+ * @brief transform a surface
+ * @param dst destination surface
+ * @param src source surface
+ * @param area area of surface
+ * @param x x coordinate of surface
+ * @param y y coordinate of surface
+ * @param rotation rotation angle
+ * @return none
+ * @note This function has implemented angle normalization to the range of 0 to 360 degrees.
+ */
+void sgl_draw_xform_surf(sgl_surf_t *dst, sgl_surf_t *src, sgl_area_t *area, int16_t x, int16_t y, int16_t rotation)
+{
+ const int32_t sin_val = sgl_sin(rotation);
+ const int32_t cos_val = sgl_cos(rotation);
+
+ const int16_t half_w = src->w / 2;
+ const int16_t half_h = src->h / 2;
+
+ const int16_t x1r = (cos_val * (-half_w) - sin_val * (-half_h)) / SGL_SIN_FIXED_ONE;
+ const int16_t y1r = (sin_val * (-half_w) + cos_val * (-half_h)) / SGL_SIN_FIXED_ONE;
+
+ const int16_t x2r = (cos_val * half_w - sin_val * (-half_h)) / SGL_SIN_FIXED_ONE;
+ const int16_t y2r = (sin_val * half_w + cos_val * (-half_h)) / SGL_SIN_FIXED_ONE;
+
+ const int16_t x3r = (cos_val * half_w - sin_val * half_h) / SGL_SIN_FIXED_ONE;
+ const int16_t y3r = (sin_val * half_w + cos_val * half_h) / SGL_SIN_FIXED_ONE;
+
+ const int16_t x4r = (cos_val * (-half_w) - sin_val * half_h) / SGL_SIN_FIXED_ONE;
+ const int16_t y4r = (sin_val * (-half_w) + cos_val * half_h) / SGL_SIN_FIXED_ONE;
+
+ const int16_t min_x = sgl_min4(x1r, x2r, x3r, x4r);
+ const int16_t min_y = sgl_min4(y1r, y2r, y3r, y4r);
+ const int16_t max_x = sgl_max4(x1r, x2r, x3r, x4r);
+ const int16_t max_y = sgl_max4(y1r, y2r, y3r, y4r);
+
+ const int16_t center_x = x + half_w;
+ const int16_t center_y = y + half_h;
+
+ const int16_t buf_width = src->w > 0 ? src->w : 1;
+ const int16_t buf_height = src->h > 0 ? src->h : 1;
+ const int16_t buf_size = buf_width * buf_height;
+
+ if (buf_size <= 0 || src->w <= 0) {
+ return;
+ }
+
+ for (int py = (int)min_y; py <= max_y; py++) {
+ for (int px = (int)min_x; px <= max_x; px++) {
+ int rel_x = px;
+ int rel_y = py;
+
+ int32_t orig_x_fixed = cos_val * rel_x + sin_val * rel_y;
+ int32_t orig_y_fixed = -sin_val * rel_x + cos_val * rel_y;
+
+ const int orig_x = (orig_x_fixed / SGL_SIN_FIXED_ONE) + half_w;
+ const int orig_y = (orig_y_fixed / SGL_SIN_FIXED_ONE) + half_h;
+
+ if (orig_x >= 0 && orig_x < buf_width && orig_y >= 0 && orig_y < buf_height) {
+ int src_idx = orig_y * buf_width + orig_x;
+ const int dst_x = center_x + px;
+ const int dst_y = center_y + py;
+
+ if (dst_x >= area->x1 && dst_x <= area->x2 && dst_y >= area->y1 && dst_y <= area->y2
+ && dst_x >= dst->x1 && dst_x <= dst->x2 && dst_y >= dst->y1 && dst_y <= dst->y2
+ ) {
+ int dst_idx = (dst_y - dst->y1) * dst->w + (dst_x - dst->x1);
+ dst->buffer[dst_idx] = src->buffer[src_idx];
+ }
+ }
+ }
+ }
+}
diff --git a/User/system/sgl/fonts/build.cmake b/User/system/sgl/fonts/build.cmake
new file mode 100644
index 0000000..c371396
--- /dev/null
+++ b/User/system/sgl/fonts/build.cmake
@@ -0,0 +1,64 @@
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+if(SGL_FONT_SONG23)
+ set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_ascii_song23.c
+ )
+endif()
+
+if(SGL_FONT_CONSOLAS14)
+ set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_ascii_consolas14.c
+ )
+endif()
+
+if(SGL_FONT_CONSOLAS23)
+ set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_ascii_consolas23.c
+ )
+endif()
+
+if(SGL_FONT_CONSOLAS24)
+ set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_ascii_consolas24.c
+ )
+endif()
+
+if(SGL_FONT_CONSOLAS32)
+ set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_ascii_consolas34.c
+ )
+endif()
+
+if(CONFIG_SGL_FONT_CONSOLAS24_COMPRESS)
+ set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/sgl_ascii_consolas24_compress.c
+ )
+endif()
diff --git a/User/system/sgl/fonts/lm.cfg b/User/system/sgl/fonts/lm.cfg
new file mode 100644
index 0000000..a19ab1e
--- /dev/null
+++ b/User/system/sgl/fonts/lm.cfg
@@ -0,0 +1,55 @@
+# source/fonts/lm.cfg
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+CONFIG_SGL_FONT_SONG23
+ choices = n, y
+ default = n
+
+CONFIG_SGL_FONT_CONSOLAS14
+ choices = n, y
+ default = n
+
+CONFIG_SGL_FONT_CONSOLAS23
+ choices = n, y
+ default = n
+
+CONFIG_SGL_FONT_CONSOLAS24
+ choices = n, y
+ default = n
+
+CONFIG_SGL_FONT_CONSOLAS32
+ choices = n, y
+ default = n
+
+CONFIG_SGL_FONT_CONSOLAS24_COMPRESS
+ choices = n, y
+ default = n
+ depends = CONFIG_SGL_FONT_COMPRESSED
+
+SRC-$(CONFIG_SGL_FONT_SONG23) += sgl_ascii_song23.c
+SRC-$(CONFIG_SGL_FONT_CONSOLAS14) += sgl_ascii_consolas14.c
+SRC-$(CONFIG_SGL_FONT_CONSOLAS23) += sgl_ascii_consolas23.c
+SRC-$(CONFIG_SGL_FONT_CONSOLAS24) += sgl_ascii_consolas24.c
+SRC-$(CONFIG_SGL_FONT_CONSOLAS32) += sgl_ascii_consolas34.c
+SRC-$(CONFIG_SGL_FONT_CONSOLAS24_COMPRESS) += sgl_ascii_consolas24_compress.c
diff --git a/User/system/sgl/fonts/sgl_ascii_consolas14.c b/User/system/sgl/fonts/sgl_ascii_consolas14.c
new file mode 100644
index 0000000..91f42a6
--- /dev/null
+++ b/User/system/sgl/fonts/sgl_ascii_consolas14.c
@@ -0,0 +1,662 @@
+/* source/fonts/sgl_ascii_consolas14.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+
+
+#if (CONFIG_SGL_FONT_CONSOLAS14)
+
+
+static const uint8_t sgl_ascii_consolas14_bitmap[] = {
+ /* U+0020 " " */
+
+ /* U+0021 "!" */
+ 0x5e, 0x4, 0xd0, 0x4d, 0x3, 0xc0, 0x3c, 0x2,
+ 0x90, 0x26, 0x5, 0xe0,
+
+ /* U+0022 "\"" */
+ 0x7c, 0x2f, 0x6, 0xb1, 0xf0, 0x47, 0xb, 0x0,
+
+ /* U+0023 "#" */
+ 0x0, 0xd0, 0xa3, 0x0, 0x1c, 0xb, 0x20, 0x5d,
+ 0xec, 0xfc, 0x40, 0x49, 0xd, 0x0, 0x5, 0x70,
+ 0xd0, 0x9, 0xdd, 0xcf, 0xc0, 0x9, 0x43, 0xa0,
+ 0x0, 0xa3, 0x49, 0x0,
+
+ /* U+0024 "$" */
+ 0x0, 0x1, 0x0, 0x0, 0x9, 0x30, 0x6, 0xdf,
+ 0xe4, 0x2e, 0x2d, 0x0, 0x3e, 0x1d, 0x0, 0x8,
+ 0xfd, 0x10, 0x0, 0x5d, 0xe4, 0x0, 0x67, 0x5c,
+ 0x11, 0x87, 0x9b, 0x4e, 0xff, 0xb1, 0x0, 0xc1,
+ 0x0, 0x0, 0x40, 0x0,
+
+ /* U+0025 "%" */
+ 0x5b, 0xc1, 0xc, 0x2b, 0x39, 0x47, 0x70, 0x3b,
+ 0x83, 0xc0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x89,
+ 0xba, 0x0, 0x3b, 0xa3, 0x94, 0xc, 0x2b, 0x28,
+ 0x48, 0x60, 0x4c, 0xb0,
+
+ /* U+0026 "&" */
+ 0x5, 0xde, 0x60, 0x0, 0xe2, 0x3e, 0x0, 0xd,
+ 0x46, 0xb0, 0x0, 0x7f, 0xa0, 0x0, 0x3d, 0xac,
+ 0x1f, 0x9, 0x70, 0xbc, 0xc0, 0x89, 0x1, 0xf9,
+ 0x1, 0xbd, 0xc8, 0xe3,
+
+ /* U+0027 "'" */
+ 0x5e, 0x4d, 0x29,
+
+ /* U+0028 "(" */
+ 0x0, 0x7, 0x0, 0xa, 0x80, 0x4, 0xc0, 0x0,
+ 0xc4, 0x0, 0x1f, 0x0, 0x3, 0xd0, 0x0, 0x2d,
+ 0x0, 0x0, 0xf1, 0x0, 0xa, 0x60, 0x0, 0x2e,
+ 0x10, 0x0, 0x6c, 0x0, 0x0, 0x30,
+
+ /* U+0029 ")" */
+ 0x25, 0x0, 0x1d, 0x40, 0x3, 0xd0, 0x0, 0xb6,
+ 0x0, 0x6a, 0x0, 0x3c, 0x0, 0x4c, 0x0, 0x79,
+ 0x0, 0xc4, 0x5, 0xb0, 0x2d, 0x10, 0x2, 0x0,
+
+ /* U+002A "*" */
+ 0x0, 0x1a, 0x0, 0xa, 0x5a, 0x96, 0x0, 0xbf,
+ 0x50, 0xa, 0x5a, 0x95, 0x0, 0x1a, 0x0,
+
+ /* U+002B "+" */
+ 0x0, 0x3c, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x7e,
+ 0xef, 0xee, 0x10, 0x3, 0xc0, 0x0, 0x0, 0x3c,
+ 0x0, 0x0, 0x2, 0x80, 0x0,
+
+ /* U+002C "," */
+ 0x0, 0x0, 0x8, 0xe1, 0x4, 0xf2, 0x4, 0xe0,
+ 0x7a, 0x20,
+
+ /* U+002D "-" */
+ 0x7f, 0xff, 0x0,
+
+ /* U+002E "." */
+ 0x7d, 0x18, 0xe1,
+
+ /* U+002F "/" */
+ 0x0, 0x0, 0xc, 0x20, 0x0, 0x7, 0x70, 0x0,
+ 0x3, 0xc0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x87,
+ 0x0, 0x0, 0x3b, 0x0, 0x0, 0xc, 0x20, 0x0,
+ 0x8, 0x60, 0x0, 0x0,
+
+ /* U+0030 "0" */
+ 0x3, 0xde, 0xb1, 0x0, 0xe3, 0x9, 0x90, 0x4b,
+ 0x0, 0x9e, 0x6, 0x91, 0xca, 0xf0, 0x7c, 0xe6,
+ 0xf, 0x5, 0xe2, 0x2, 0xe0, 0xe, 0x30, 0x98,
+ 0x0, 0x4d, 0xea, 0x0,
+
+ /* U+0031 "1" */
+ 0x1, 0x9f, 0x20, 0xe, 0x7f, 0x20, 0x1, 0xf,
+ 0x20, 0x0, 0xf, 0x20, 0x0, 0xf, 0x20, 0x0,
+ 0xf, 0x20, 0x0, 0xf, 0x20, 0xe, 0xff, 0xfc,
+
+ /* U+0032 "2" */
+ 0x6, 0xee, 0x90, 0x7, 0x10, 0xd5, 0x0, 0x0,
+ 0xa7, 0x0, 0x0, 0xe3, 0x0, 0xa, 0x90, 0x0,
+ 0x9a, 0x0, 0x9, 0xb0, 0x0, 0x2f, 0xff, 0xfe,
+
+ /* U+0033 "3" */
+ 0xa, 0xee, 0xa0, 0x0, 0x0, 0xd5, 0x0, 0x1,
+ 0xd2, 0x1, 0xdf, 0xa0, 0x0, 0x0, 0xb8, 0x0,
+ 0x0, 0x5b, 0x0, 0x0, 0xb6, 0xe, 0xed, 0x70,
+
+ /* U+0034 "4" */
+ 0x0, 0xc, 0xf0, 0x0, 0x7, 0xaf, 0x0, 0x2,
+ 0xd1, 0xf0, 0x0, 0xb4, 0x1f, 0x0, 0x6a, 0x1,
+ 0xf0, 0xb, 0xee, 0xef, 0xe3, 0x0, 0x1, 0xf0,
+ 0x0, 0x0, 0x1f, 0x0,
+
+ /* U+0035 "5" */
+ 0xde, 0xee, 0x4d, 0x20, 0x0, 0xd2, 0x0, 0xc,
+ 0xed, 0x90, 0x0, 0x1b, 0x80, 0x0, 0x6a, 0x0,
+ 0x1c, 0x5e, 0xed, 0x60,
+
+ /* U+0036 "6" */
+ 0x0, 0x7d, 0xe5, 0x8, 0xa1, 0x0, 0xe, 0x0,
+ 0x0, 0x3e, 0xbc, 0xb2, 0x4d, 0x10, 0x6c, 0x2d,
+ 0x0, 0x1f, 0xe, 0x30, 0x6b, 0x3, 0xdd, 0xb1,
+
+ /* U+0037 "7" */
+ 0x4f, 0xff, 0xfd, 0x0, 0x0, 0x69, 0x0, 0x0,
+ 0xe2, 0x0, 0x6, 0xb0, 0x0, 0xd, 0x30, 0x0,
+ 0x5c, 0x0, 0x0, 0xc5, 0x0, 0x4, 0xd0, 0x0,
+
+ /* U+0038 "8" */
+ 0x5, 0xdd, 0xc2, 0xf, 0x10, 0x7a, 0xf, 0x30,
+ 0x89, 0x5, 0xec, 0xb0, 0x8, 0xc8, 0xe4, 0x2e,
+ 0x0, 0x6d, 0x3e, 0x10, 0x6c, 0x7, 0xdd, 0xc2,
+
+ /* U+0039 "9" */
+ 0x5, 0xdd, 0x90, 0x2e, 0x10, 0xa7, 0x5b, 0x0,
+ 0x4c, 0x3e, 0x10, 0x6d, 0x7, 0xdc, 0xbc, 0x0,
+ 0x0, 0x69, 0x0, 0x4, 0xe2, 0xd, 0xeb, 0x30,
+
+ /* U+003A ":" */
+ 0x6e, 0x14, 0xb0, 0x0, 0x0, 0x0, 0x4b, 0x6,
+ 0xe1,
+
+ /* U+003B ";" */
+ 0x6, 0xe1, 0x4, 0xb0, 0x0, 0x0, 0x0, 0x0,
+ 0x5, 0xd1, 0x3, 0xf3, 0x3, 0xe1, 0x6b, 0x30,
+
+ /* U+003C "<" */
+ 0x0, 0x0, 0x30, 0x0, 0x7, 0xd1, 0x0, 0xab,
+ 0x0, 0xc, 0x90, 0x0, 0x6, 0xd2, 0x0, 0x0,
+ 0x3d, 0x40, 0x0, 0x2, 0xc2, 0x0, 0x0, 0x0,
+
+ /* U+003D "=" */
+ 0x2d, 0xdd, 0xda, 0x0, 0x0, 0x0, 0x3d, 0xdd,
+ 0xdb,
+
+ /* U+003E ">" */
+ 0x21, 0x0, 0x5, 0xd2, 0x0, 0x3, 0xd4, 0x0,
+ 0x2, 0xd6, 0x0, 0x6d, 0x20, 0x9b, 0x0, 0x88,
+ 0x0, 0x0, 0x0, 0x0,
+
+ /* U+003F "?" */
+ 0x3e, 0xc4, 0x0, 0x4, 0xe2, 0x0, 0xc, 0x50,
+ 0x9d, 0xa0, 0x9, 0x50, 0x0, 0x52, 0x0, 0x5,
+ 0x30, 0x0, 0xc7, 0x0,
+
+ /* U+0040 "@" */
+ 0x0, 0x9b, 0xc5, 0x0, 0xb5, 0x0, 0xc1, 0x49,
+ 0x5c, 0xc7, 0x69, 0x4d, 0x2d, 0x57, 0xd5, 0xa4,
+ 0xa5, 0x7d, 0x59, 0x88, 0x94, 0xd1, 0xc7, 0xb9,
+ 0xc, 0x10, 0x0, 0x0, 0x79, 0x0, 0x10, 0x0,
+ 0x9c, 0xba, 0x0,
+
+ /* U+0041 "A" */
+ 0x0, 0x8f, 0x20, 0x0, 0xd, 0xa8, 0x0, 0x3,
+ 0xc3, 0xd0, 0x0, 0x87, 0xe, 0x20, 0xd, 0x20,
+ 0x97, 0x2, 0xff, 0xff, 0xc0, 0x78, 0x0, 0xf,
+ 0x1c, 0x40, 0x0, 0xb6,
+
+ /* U+0042 "B" */
+ 0x1f, 0xee, 0xb1, 0x1f, 0x0, 0xa8, 0x1f, 0x0,
+ 0x7a, 0x1f, 0x0, 0xc5, 0x1f, 0xdf, 0xd2, 0x1f,
+ 0x0, 0x7d, 0x1f, 0x0, 0x6c, 0x1f, 0xdd, 0xb2,
+
+ /* U+0043 "C" */
+ 0x0, 0xae, 0xea, 0xb, 0x90, 0x3, 0x3e, 0x0,
+ 0x0, 0x5b, 0x0, 0x0, 0x6b, 0x0, 0x0, 0x4e,
+ 0x0, 0x0, 0xd, 0x80, 0x2, 0x2, 0xbe, 0xe9,
+
+ /* U+0044 "D" */
+ 0x5f, 0xed, 0x80, 0x5, 0xb0, 0xb, 0x90, 0x5b,
+ 0x0, 0x2f, 0x5, 0xb0, 0x0, 0xf2, 0x5b, 0x0,
+ 0xf, 0x15, 0xb0, 0x2, 0xe0, 0x5b, 0x1, 0xc8,
+ 0x5, 0xfe, 0xd7, 0x0,
+
+ /* U+0045 "E" */
+ 0xde, 0xee, 0x7d, 0x30, 0x0, 0xd3, 0x0, 0xd,
+ 0x30, 0x0, 0xde, 0xee, 0x5d, 0x30, 0x0, 0xd3,
+ 0x0, 0xd, 0xee, 0xe7,
+
+ /* U+0046 "F" */
+ 0xce, 0xee, 0x7c, 0x40, 0x0, 0xc4, 0x0, 0xc,
+ 0x40, 0x0, 0xce, 0xee, 0x4c, 0x40, 0x0, 0xc4,
+ 0x0, 0xc, 0x40, 0x0,
+
+ /* U+0047 "G" */
+ 0x1, 0xae, 0xfa, 0xd, 0x80, 0x4, 0x5c, 0x0,
+ 0x0, 0x98, 0x0, 0x0, 0x88, 0x9, 0xdd, 0x6b,
+ 0x0, 0x1f, 0xe, 0x60, 0x1f, 0x2, 0xbe, 0xea,
+
+ /* U+0048 "H" */
+ 0x5b, 0x0, 0x1f, 0x5b, 0x0, 0x1f, 0x5b, 0x0,
+ 0x1f, 0x5b, 0x0, 0x1f, 0x5f, 0xee, 0xef, 0x5b,
+ 0x0, 0x1f, 0x5b, 0x0, 0x1f, 0x5b, 0x0, 0x1f,
+
+ /* U+0049 "I" */
+ 0xde, 0xfe, 0x80, 0x3d, 0x0, 0x3, 0xd0, 0x0,
+ 0x3d, 0x0, 0x3, 0xd0, 0x0, 0x3d, 0x0, 0x3,
+ 0xd0, 0xe, 0xef, 0xe8,
+
+ /* U+004A "J" */
+ 0xbe, 0xef, 0x20, 0x0, 0xe2, 0x0, 0xe, 0x20,
+ 0x0, 0xe2, 0x0, 0xe, 0x20, 0x0, 0xe1, 0x30,
+ 0x3e, 0xb, 0xed, 0x40,
+
+ /* U+004B "K" */
+ 0x1f, 0x0, 0x99, 0x1, 0xf0, 0x5c, 0x0, 0x1f,
+ 0x2d, 0x10, 0x1, 0xfd, 0x40, 0x0, 0x1f, 0xb8,
+ 0x0, 0x1, 0xf1, 0xe4, 0x0, 0x1f, 0x4, 0xe1,
+ 0x1, 0xf0, 0x8, 0xb0,
+
+ /* U+004C "L" */
+ 0xa6, 0x0, 0xa, 0x60, 0x0, 0xa6, 0x0, 0xa,
+ 0x60, 0x0, 0xa6, 0x0, 0xa, 0x60, 0x0, 0xa6,
+ 0x0, 0xa, 0xee, 0xea,
+
+ /* U+004D "M" */
+ 0x5f, 0x10, 0x8f, 0x6, 0xe6, 0xc, 0xe0, 0x79,
+ 0xc3, 0x9e, 0x8, 0x6c, 0xa4, 0xd1, 0x85, 0x7e,
+ 0xd, 0x29, 0x51, 0x40, 0xc3, 0xa4, 0x0, 0xc,
+ 0x3b, 0x40, 0x0, 0xb4,
+
+ /* U+004E "N" */
+ 0x4f, 0x40, 0x1e, 0x4e, 0xb0, 0x1e, 0x4a, 0xe2,
+ 0x1e, 0x4a, 0x79, 0x1e, 0x4a, 0x1e, 0x2e, 0x4a,
+ 0x9, 0x8e, 0x4a, 0x2, 0xee, 0x4a, 0x0, 0xae,
+
+ /* U+004F "O" */
+ 0x4, 0xde, 0xb1, 0x2, 0xe3, 0x8, 0xb0, 0x7a,
+ 0x0, 0xf, 0x1a, 0x70, 0x0, 0xd3, 0xa7, 0x0,
+ 0xd, 0x38, 0x90, 0x0, 0xf1, 0x2f, 0x30, 0x9b,
+ 0x0, 0x5e, 0xea, 0x10,
+
+ /* U+0050 "P" */
+ 0x1f, 0xde, 0xb2, 0x1f, 0x0, 0x7b, 0x1f, 0x0,
+ 0x2e, 0x1f, 0x0, 0x9a, 0x1f, 0xdd, 0x90, 0x1f,
+ 0x0, 0x0, 0x1f, 0x0, 0x0, 0x1f, 0x0, 0x0,
+
+ /* U+0051 "Q" */
+ 0x4, 0xdf, 0xb1, 0x2, 0xe3, 0x8, 0xb0, 0x7a,
+ 0x0, 0xf, 0x1a, 0x70, 0x0, 0xd3, 0xa7, 0x0,
+ 0xd, 0x38, 0x90, 0x1, 0xf1, 0x2e, 0x41, 0x9a,
+ 0x0, 0x5d, 0xf9, 0x0, 0x0, 0x2e, 0x11, 0x10,
+ 0x0, 0x6d, 0xd4,
+
+ /* U+0052 "R" */
+ 0xfe, 0xea, 0x0, 0xf0, 0xc, 0x60, 0xf0, 0x8,
+ 0x80, 0xf0, 0x1d, 0x40, 0xfd, 0xf7, 0x0, 0xf0,
+ 0x6c, 0x0, 0xf0, 0xc, 0x50, 0xf0, 0x4, 0xd0,
+
+ /* U+0053 "S" */
+ 0x5, 0xde, 0xe4, 0x1e, 0x20, 0x0, 0x2f, 0x10,
+ 0x0, 0x8, 0xf8, 0x10, 0x0, 0x29, 0xf4, 0x0,
+ 0x0, 0x6c, 0x11, 0x0, 0x8a, 0x4e, 0xfe, 0xa1,
+
+ /* U+0054 "T" */
+ 0x7e, 0xef, 0xee, 0x10, 0x3, 0xd0, 0x0, 0x0,
+ 0x3d, 0x0, 0x0, 0x3, 0xd0, 0x0, 0x0, 0x3d,
+ 0x0, 0x0, 0x3, 0xd0, 0x0, 0x0, 0x3d, 0x0,
+ 0x0, 0x3, 0xd0, 0x0,
+
+ /* U+0055 "U" */
+ 0x5b, 0x0, 0x1f, 0x5b, 0x0, 0x1f, 0x5b, 0x0,
+ 0x1f, 0x5b, 0x0, 0x1f, 0x5b, 0x0, 0x1f, 0x5b,
+ 0x0, 0x1e, 0x2e, 0x10, 0x7a, 0x6, 0xdd, 0xb1,
+
+ /* U+0056 "V" */
+ 0xd5, 0x0, 0xb, 0x67, 0xa0, 0x0, 0xf1, 0x2f,
+ 0x0, 0x4c, 0x0, 0xd4, 0x9, 0x60, 0x8, 0x90,
+ 0xe1, 0x0, 0x3e, 0x3c, 0x0, 0x0, 0xeb, 0x70,
+ 0x0, 0x9, 0xf2, 0x0,
+
+ /* U+0057 "W" */
+ 0xb4, 0x0, 0x9, 0x4a, 0x50, 0x0, 0xa3, 0x96,
+ 0x3, 0xb, 0x28, 0x75, 0xe0, 0xc1, 0x77, 0xad,
+ 0x4d, 0x5, 0x9d, 0x59, 0xd0, 0x4d, 0x90, 0xed,
+ 0x3, 0xf4, 0xb, 0xd0,
+
+ /* U+0058 "X" */
+ 0x6d, 0x0, 0x3e, 0x0, 0xc6, 0xc, 0x50, 0x3,
+ 0xe7, 0xb0, 0x0, 0x9, 0xf2, 0x0, 0x0, 0xbf,
+ 0x50, 0x0, 0x5d, 0x5e, 0x0, 0xe, 0x40, 0xb8,
+ 0x9, 0xb0, 0x2, 0xf2,
+
+ /* U+0059 "Y" */
+ 0xb8, 0x0, 0xd, 0x53, 0xf1, 0x5, 0xc0, 0xa,
+ 0x90, 0xd3, 0x0, 0x2f, 0x7b, 0x0, 0x0, 0x9f,
+ 0x20, 0x0, 0x3, 0xd0, 0x0, 0x0, 0x3d, 0x0,
+ 0x0, 0x3, 0xd0, 0x0,
+
+ /* U+005A "Z" */
+ 0x3f, 0xff, 0xfd, 0x0, 0x0, 0xc6, 0x0, 0x6,
+ 0xc0, 0x0, 0x1e, 0x30, 0x0, 0xa8, 0x0, 0x4,
+ 0xd0, 0x0, 0xd, 0x40, 0x0, 0x5f, 0xff, 0xfe,
+
+ /* U+005B "[" */
+ 0xfd, 0xbf, 0x0, 0xf0, 0xf, 0x0, 0xf0, 0xf,
+ 0x0, 0xf0, 0xf, 0x0, 0xf0, 0xf, 0xdb,
+
+ /* U+005C "\\" */
+ 0xd, 0x20, 0x0, 0x6, 0x80, 0x0, 0x0, 0xe0,
+ 0x0, 0x0, 0x96, 0x0, 0x0, 0x2c, 0x0, 0x0,
+ 0xb, 0x30, 0x0, 0x5, 0xa0, 0x0, 0x0, 0xd1,
+ 0x0, 0x0, 0x78, 0x0, 0x0, 0x16,
+
+ /* U+005D "]" */
+ 0x4d, 0xe9, 0x0, 0x69, 0x0, 0x69, 0x0, 0x69,
+ 0x0, 0x69, 0x0, 0x69, 0x0, 0x69, 0x0, 0x69,
+ 0x0, 0x69, 0x4d, 0xe9,
+
+ /* U+005E "^" */
+ 0x0, 0x6e, 0x0, 0x0, 0xc7, 0x80, 0x7, 0x60,
+ 0xd1, 0x1d, 0x0, 0x5a,
+
+ /* U+005F "_" */
+ 0xdd, 0xdd, 0xdd, 0x80,
+
+ /* U+0060 "`" */
+ 0xd, 0x10, 0xf0, 0xd, 0x0,
+
+ /* U+0061 "a" */
+ 0x8, 0xdd, 0xc1, 0x1, 0x0, 0x88, 0x5, 0xcc,
+ 0xda, 0x1f, 0x20, 0x6a, 0x2e, 0x1, 0xca, 0x9,
+ 0xec, 0x9a,
+
+ /* U+0062 "b" */
+ 0x1f, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x1e, 0x7d,
+ 0xd2, 0x1f, 0x80, 0x6b, 0x1f, 0x0, 0x1e, 0x1f,
+ 0x0, 0x2e, 0x1f, 0x0, 0x89, 0xc, 0xed, 0x90,
+
+ /* U+0063 "c" */
+ 0x1, 0xae, 0xe6, 0xa, 0x90, 0x1, 0xf, 0x10,
+ 0x0, 0xf, 0x10, 0x0, 0xc, 0x80, 0x1, 0x2,
+ 0xbe, 0xe6,
+
+ /* U+0064 "d" */
+ 0x0, 0x0, 0x6a, 0x0, 0x0, 0x6a, 0x3, 0xcd,
+ 0xea, 0xe, 0x20, 0x6a, 0x4c, 0x0, 0x6a, 0x5b,
+ 0x0, 0x6a, 0x2e, 0x1, 0xda, 0x8, 0xdb, 0x7a,
+
+ /* U+0065 "e" */
+ 0x3, 0xcc, 0xb2, 0xd, 0x10, 0x5b, 0x3f, 0xcc,
+ 0xcc, 0x4d, 0x0, 0x0, 0x1f, 0x40, 0x0, 0x4,
+ 0xdd, 0xd7,
+
+ /* U+0066 "f" */
+ 0x0, 0x1b, 0xdd, 0x20, 0x8, 0x90, 0x0, 0x0,
+ 0xa6, 0x0, 0x7, 0xdf, 0xed, 0xd0, 0x0, 0xa6,
+ 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, 0xa6, 0x0,
+ 0x0, 0xa, 0x60, 0x0,
+
+ /* U+0067 "g" */
+ 0x5, 0xcd, 0xff, 0x10, 0xf1, 0xa, 0x60, 0xe,
+ 0x20, 0xb5, 0x0, 0xcb, 0xc8, 0x0, 0x2d, 0x0,
+ 0x0, 0x0, 0xee, 0xed, 0x80, 0x5c, 0x0, 0x3f,
+ 0x2, 0xcd, 0xcc, 0x50,
+
+ /* U+0068 "h" */
+ 0x1f, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x1f, 0x7d,
+ 0xd2, 0x1f, 0x80, 0x89, 0x1f, 0x0, 0x5a, 0x1f,
+ 0x0, 0x5a, 0x1f, 0x0, 0x5a, 0x1f, 0x0, 0x5a,
+
+ /* U+0069 "i" */
+ 0x5, 0xe0, 0x0, 0x28, 0x0, 0xad, 0xf0, 0x0,
+ 0x1f, 0x0, 0x1, 0xf0, 0x0, 0x1f, 0x0, 0x1,
+ 0xf0, 0xd, 0xdf, 0xd9,
+
+ /* U+006A "j" */
+ 0x0, 0x5, 0xe0, 0x0, 0x2, 0x80, 0xd, 0xdd,
+ 0xe0, 0x0, 0x1, 0xe0, 0x0, 0x1, 0xe0, 0x0,
+ 0x1, 0xe0, 0x0, 0x1, 0xe0, 0x0, 0x1, 0xe0,
+ 0x0, 0x6, 0xb0, 0x2d, 0xdc, 0x20,
+
+ /* U+006B "k" */
+ 0xf1, 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf1, 0xb,
+ 0x90, 0xf1, 0xa9, 0x0, 0xfb, 0xa0, 0x0, 0xf6,
+ 0xd1, 0x0, 0xf1, 0x7d, 0x0, 0xf1, 0x9, 0xc0,
+
+ /* U+006C "l" */
+ 0xad, 0xf0, 0x0, 0x1f, 0x0, 0x1, 0xf0, 0x0,
+ 0x1f, 0x0, 0x1, 0xf0, 0x0, 0x1f, 0x0, 0x1,
+ 0xf0, 0xd, 0xdf, 0xd9,
+
+ /* U+006D "m" */
+ 0x79, 0xd7, 0xbb, 0x7, 0xc3, 0xf1, 0xe0, 0x77,
+ 0x2c, 0xd, 0x17, 0x72, 0xc0, 0xd1, 0x77, 0x2c,
+ 0xd, 0x17, 0x72, 0xc0, 0xd1,
+
+ /* U+006E "n" */
+ 0x1e, 0x8c, 0xd2, 0x1f, 0x60, 0x79, 0x1f, 0x0,
+ 0x5a, 0x1f, 0x0, 0x5a, 0x1f, 0x0, 0x5a, 0x1f,
+ 0x0, 0x5a,
+
+ /* U+006F "o" */
+ 0x4, 0xdd, 0xb2, 0x1, 0xe2, 0x7, 0xb0, 0x5a,
+ 0x0, 0xf, 0x6, 0xa0, 0x0, 0xf0, 0x2e, 0x20,
+ 0x7a, 0x0, 0x6d, 0xda, 0x10,
+
+ /* U+0070 "p" */
+ 0x1e, 0x8c, 0xd2, 0x1f, 0x70, 0x5b, 0x1f, 0x0,
+ 0x1e, 0x1f, 0x0, 0x2d, 0x1f, 0x0, 0x99, 0x1f,
+ 0xed, 0xa0, 0x1f, 0x0, 0x0, 0x1f, 0x0, 0x0,
+
+ /* U+0071 "q" */
+ 0x0, 0x0, 0x0, 0x3, 0xcd, 0xd9, 0xe, 0x20,
+ 0x6a, 0x4b, 0x0, 0x6a, 0x5b, 0x0, 0x6a, 0x2e,
+ 0x12, 0xea, 0x8, 0xec, 0x8a, 0x0, 0x0, 0x6a,
+ 0x0, 0x0, 0x6a,
+
+ /* U+0072 "r" */
+ 0xd6, 0xcd, 0x60, 0xdb, 0x2, 0xe0, 0xd3, 0x0,
+ 0x40, 0xd3, 0x0, 0x0, 0xd3, 0x0, 0x0, 0xd3,
+ 0x0, 0x0,
+
+ /* U+0073 "s" */
+ 0x4c, 0xdd, 0x2c, 0x40, 0x0, 0x7d, 0x71, 0x0,
+ 0x28, 0xe4, 0x10, 0x9, 0x8c, 0xee, 0xb1,
+
+ /* U+0074 "t" */
+ 0x0, 0xb0, 0x0, 0x0, 0xf0, 0x0, 0x8d, 0xfd,
+ 0xd9, 0x0, 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0,
+ 0xf0, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x5d, 0xd9,
+
+ /* U+0075 "u" */
+ 0x1f, 0x0, 0x5a, 0x1f, 0x0, 0x5a, 0x1f, 0x0,
+ 0x5a, 0xf, 0x0, 0x5a, 0xf, 0x10, 0xca, 0x7,
+ 0xdc, 0x8a,
+
+ /* U+0076 "v" */
+ 0x6b, 0x0, 0x2f, 0x1, 0xf1, 0x7, 0x90, 0xa,
+ 0x70, 0xd3, 0x0, 0x4d, 0x3d, 0x0, 0x0, 0xeb,
+ 0x60, 0x0, 0x8, 0xf1, 0x0,
+
+ /* U+0077 "w" */
+ 0xb4, 0x0, 0xa, 0x59, 0x61, 0x50, 0xc2, 0x68,
+ 0x6f, 0xe, 0x4, 0xab, 0xa5, 0xe0, 0x2d, 0xb3,
+ 0xcb, 0x0, 0xf6, 0xd, 0x90,
+
+ /* U+0078 "x" */
+ 0x2e, 0x20, 0x7c, 0x0, 0x6c, 0x2e, 0x10, 0x0,
+ 0xae, 0x50, 0x0, 0xb, 0xf4, 0x0, 0x7, 0xc3,
+ 0xe2, 0x3, 0xe2, 0x7, 0xc0,
+
+ /* U+0079 "y" */
+ 0x6b, 0x0, 0x2e, 0x0, 0xf2, 0x8, 0x90, 0x9,
+ 0x80, 0xd2, 0x0, 0x2e, 0x4c, 0x0, 0x0, 0xbd,
+ 0x60, 0x0, 0x6, 0xe0, 0x0, 0x0, 0xc6, 0x0,
+ 0x9, 0xe7, 0x0, 0x0,
+
+ /* U+007A "z" */
+ 0xc, 0xdd, 0xf7, 0x0, 0x3, 0xe1, 0x0, 0x1d,
+ 0x30, 0x0, 0xb7, 0x0, 0x7, 0xb0, 0x0, 0xf,
+ 0xed, 0xd9,
+
+ /* U+007B "{" */
+ 0x0, 0xb, 0xd3, 0x0, 0x5a, 0x0, 0x0, 0x68,
+ 0x0, 0x0, 0x87, 0x0, 0xe, 0xd1, 0x0, 0x0,
+ 0x97, 0x0, 0x0, 0x68, 0x0, 0x0, 0x69, 0x0,
+ 0x0, 0x5b, 0x0, 0x0, 0xa, 0xd3,
+
+ /* U+007C "|" */
+ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+ 0x3c, 0x3c, 0x3c, 0x3c,
+
+ /* U+007D "}" */
+ 0x8d, 0x60, 0x0, 0x1f, 0x0, 0x0, 0xf0, 0x0,
+ 0xe, 0x20, 0x0, 0x5f, 0x80, 0xd, 0x20, 0x0,
+ 0xf0, 0x0, 0xf, 0x0, 0x1, 0xe0, 0x8, 0xd5,
+ 0x0,
+
+ /* U+007E "~" */
+ 0x3d, 0xd7, 0x8, 0x15, 0x42, 0xae, 0xa0,
+
+ /* U+007F "" */
+
+ /* U+4E2D "ä¸" */
+ 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0x0,
+ 0xb4, 0x0, 0x0, 0xa, 0xaa, 0xae, 0xca, 0xaa,
+ 0x50, 0xf3, 0x33, 0xc6, 0x33, 0x88, 0xf, 0x0,
+ 0xb, 0x40, 0x6, 0x80, 0xf0, 0x0, 0xb4, 0x0,
+ 0x68, 0xf, 0xdd, 0xdf, 0xed, 0xde, 0x80, 0xa0,
+ 0x0, 0xb5, 0x0, 0x45, 0x0, 0x0, 0xb, 0x40,
+ 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0,
+ 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0x0, 0xb4,
+ 0x0, 0x0,
+
+ /* U+6587 "æ–‡" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8, 0x70,
+ 0x0, 0x0, 0xce, 0xee, 0xee, 0xee, 0xee, 0xe5,
+ 0x0, 0x86, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x3b,
+ 0x0, 0x3, 0xc0, 0x0, 0x0, 0xc, 0x20, 0x9,
+ 0x60, 0x0, 0x0, 0x4, 0xc0, 0x3d, 0x0, 0x0,
+ 0x0, 0x0, 0x9a, 0xe3, 0x0, 0x0, 0x0, 0x0,
+ 0x6f, 0xd2, 0x0, 0x0, 0x0, 0x5c, 0xc3, 0x7e,
+ 0xa4, 0x0, 0x8e, 0xc4, 0x0, 0x1, 0x8e, 0xf2,
+ 0x22, 0x0, 0x0, 0x0, 0x0, 0x30
+};
+
+
+static const sgl_font_table_t sgl_ascii_consolas14_tab[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 106, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 0, .adv_w = 106, .box_w = 3, .box_h = 8, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 12, .adv_w = 106, .box_w = 5, .box_h = 3, .ofs_x = 1, .ofs_y = 5},
+ {.bitmap_index = 20, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 48, .adv_w = 106, .box_w = 6, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 84, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 112, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 140, .adv_w = 106, .box_w = 2, .box_h = 3, .ofs_x = 2, .ofs_y = 5},
+ {.bitmap_index = 143, .adv_w = 106, .box_w = 5, .box_h = 12, .ofs_x = 1, .ofs_y = -3},
+ {.bitmap_index = 173, .adv_w = 106, .box_w = 4, .box_h = 12, .ofs_x = 1, .ofs_y = -3},
+ {.bitmap_index = 197, .adv_w = 106, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 3},
+ {.bitmap_index = 212, .adv_w = 106, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 233, .adv_w = 106, .box_w = 4, .box_h = 5, .ofs_x = 1, .ofs_y = -2},
+ {.bitmap_index = 243, .adv_w = 106, .box_w = 5, .box_h = 1, .ofs_x = 1, .ofs_y = 3},
+ {.bitmap_index = 246, .adv_w = 106, .box_w = 3, .box_h = 2, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 249, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 277, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 305, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 329, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 353, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 377, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 405, .adv_w = 106, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 425, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 449, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 473, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 497, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 521, .adv_w = 106, .box_w = 3, .box_h = 6, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 530, .adv_w = 106, .box_w = 4, .box_h = 8, .ofs_x = 1, .ofs_y = -2},
+ {.bitmap_index = 546, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = -1},
+ {.bitmap_index = 570, .adv_w = 106, .box_w = 6, .box_h = 3, .ofs_x = 0, .ofs_y = 2},
+ {.bitmap_index = 579, .adv_w = 106, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = -1},
+ {.bitmap_index = 599, .adv_w = 106, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 619, .adv_w = 106, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 654, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 682, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 706, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 730, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 758, .adv_w = 106, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 778, .adv_w = 106, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 798, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 822, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 846, .adv_w = 106, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 866, .adv_w = 106, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 886, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 914, .adv_w = 106, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 934, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 962, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 986, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1014, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1038, .adv_w = 106, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 1073, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1097, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1121, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1149, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1173, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1201, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1229, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1257, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1285, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1309, .adv_w = 106, .box_w = 3, .box_h = 10, .ofs_x = 2, .ofs_y = -2},
+ {.bitmap_index = 1324, .adv_w = 106, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 1354, .adv_w = 106, .box_w = 4, .box_h = 10, .ofs_x = 1, .ofs_y = -2},
+ {.bitmap_index = 1374, .adv_w = 106, .box_w = 6, .box_h = 4, .ofs_x = 0, .ofs_y = 4},
+ {.bitmap_index = 1386, .adv_w = 106, .box_w = 7, .box_h = 1, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 1390, .adv_w = 49, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 6},
+ {.bitmap_index = 1395, .adv_w = 106, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1413, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1437, .adv_w = 106, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1455, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1479, .adv_w = 106, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1497, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1525, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 1553, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1577, .adv_w = 106, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1597, .adv_w = 106, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 1627, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1651, .adv_w = 106, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1671, .adv_w = 106, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1692, .adv_w = 106, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1710, .adv_w = 106, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1731, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 1755, .adv_w = 106, .box_w = 6, .box_h = 9, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 1782, .adv_w = 106, .box_w = 6, .box_h = 6, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1800, .adv_w = 106, .box_w = 5, .box_h = 6, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1815, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1839, .adv_w = 106, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1857, .adv_w = 106, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1878, .adv_w = 106, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1899, .adv_w = 106, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1920, .adv_w = 106, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 1948, .adv_w = 106, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1966, .adv_w = 106, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 1996, .adv_w = 106, .box_w = 2, .box_h = 12, .ofs_x = 2, .ofs_y = -2},
+ {.bitmap_index = 2008, .adv_w = 106, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = -2},
+ {.bitmap_index = 2033, .adv_w = 106, .box_w = 7, .box_h = 2, .ofs_x = 0, .ofs_y = 2},
+ {.bitmap_index = 2040, .adv_w = 106, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2040, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 2106, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}
+};
+
+static const uint32_t unicode_list_1[] = {
+ 0x0, 0x175a
+};
+
+static const sgl_font_unicode_t consolas14_unicode[] = {
+ { .offset = 32, .len = 96, .list = NULL, .tab_offset = 1, },
+ { .offset = 20013, .len = 2, .list = unicode_list_1, .tab_offset = 97, },
+};
+
+const sgl_font_t consolas14 = {
+ .bitmap = sgl_ascii_consolas14_bitmap,
+ .table = sgl_ascii_consolas14_tab,
+ .font_table_size = SGL_ARRAY_SIZE(sgl_ascii_consolas14_tab),
+ .font_height = 14,
+ .base_line = 3,
+ .bpp = 4,
+ .unicode = consolas14_unicode,
+ .unicode_num = 2,
+};
+
+
+#endif // !CONFIG_SGL_FONT_CONSOLAS14
diff --git a/User/system/sgl/fonts/sgl_ascii_consolas23.c b/User/system/sgl/fonts/sgl_ascii_consolas23.c
new file mode 100644
index 0000000..dd3e780
--- /dev/null
+++ b/User/system/sgl/fonts/sgl_ascii_consolas23.c
@@ -0,0 +1,1198 @@
+/* source/fonts/sgl_ascii_consolas23.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+
+
+#if (CONFIG_SGL_FONT_CONSOLAS23)
+
+
+static const uint8_t sgl_ascii_consolas23_bitmap[] = {
+ /* U+0020 " " */
+
+ /* U+0021 "!" */
+ 0x5f, 0xd0, 0x4f, 0xc0, 0x4f, 0xc0, 0x3f, 0xb0,
+ 0x3f, 0xb0, 0x2f, 0xa0, 0x2f, 0xa0, 0x1f, 0xa0,
+ 0x1f, 0x90, 0x1f, 0x90, 0x9, 0x50, 0x0, 0x0,
+ 0x2c, 0x70, 0x8f, 0xf0, 0x4e, 0xa0,
+
+ /* U+0022 "\"" */
+ 0x5f, 0xe0, 0x5f, 0xd4, 0xfd, 0x4, 0xfd, 0x3f,
+ 0xc0, 0x3f, 0xc2, 0xfb, 0x2, 0xfb, 0x1f, 0xa0,
+ 0x1f, 0xa0, 0x0, 0x0, 0x0,
+
+ /* U+0023 "#" */
+ 0x0, 0x7, 0xf0, 0x5, 0xf3, 0x0, 0x0, 0x9,
+ 0xe0, 0x7, 0xf1, 0x0, 0x0, 0xa, 0xd0, 0x8,
+ 0xf0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf1,
+ 0x6, 0x6f, 0xc6, 0x6d, 0xd6, 0x60, 0x0, 0xf,
+ 0x80, 0xd, 0xa0, 0x0, 0x0, 0xf, 0x70, 0xe,
+ 0x90, 0x0, 0x0, 0x2f, 0x60, 0xf, 0x80, 0x0,
+ 0x1, 0x4f, 0x61, 0x2f, 0x71, 0x0, 0x9f, 0xff,
+ 0xff, 0xff, 0xff, 0x90, 0x24, 0x9f, 0x54, 0x7f,
+ 0x74, 0x20, 0x0, 0x8f, 0x0, 0x6f, 0x20, 0x0,
+ 0x0, 0x9e, 0x0, 0x7f, 0x0, 0x0, 0x0, 0xbd,
+ 0x0, 0x9f, 0x0, 0x0,
+
+ /* U+0024 "$" */
+ 0x0, 0x0, 0xf, 0x70, 0x0, 0x0, 0x0, 0x1f,
+ 0x50, 0x0, 0x1, 0x8d, 0xff, 0xfc, 0x30, 0x1d,
+ 0xfb, 0xbf, 0xac, 0x50, 0x8f, 0x70, 0x8f, 0x0,
+ 0x0, 0xbf, 0x30, 0xad, 0x0, 0x0, 0x9f, 0x90,
+ 0xcb, 0x0, 0x0, 0x1e, 0xfd, 0xf9, 0x0, 0x0,
+ 0x2, 0xbf, 0xfe, 0x70, 0x0, 0x0, 0x4, 0xff,
+ 0xfd, 0x20, 0x0, 0x4, 0xf3, 0x8f, 0xd0, 0x0,
+ 0x7, 0xf0, 0xc, 0xf3, 0x0, 0x9, 0xe0, 0xb,
+ 0xf4, 0x63, 0x1b, 0xc0, 0x6f, 0xf0, 0xdf, 0xff,
+ 0xff, 0xff, 0x60, 0x7c, 0xff, 0xfe, 0xa3, 0x0,
+ 0x0, 0xf, 0x70, 0x0, 0x0, 0x0, 0x3f, 0x40,
+ 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0,
+
+ /* U+0025 "%" */
+ 0x5, 0xde, 0x90, 0x0, 0xa, 0xe1, 0x3f, 0x85,
+ 0xf8, 0x0, 0x4f, 0x60, 0x8f, 0x0, 0xbc, 0x0,
+ 0xec, 0x0, 0x9e, 0x0, 0xac, 0x9, 0xf2, 0x0,
+ 0x6f, 0x53, 0xf9, 0x3f, 0x80, 0x0, 0xb, 0xff,
+ 0xc1, 0xcd, 0x0, 0x0, 0x0, 0x22, 0x7, 0xf3,
+ 0x0, 0x0, 0x0, 0x0, 0x1f, 0x90, 0x0, 0x0,
+ 0x0, 0x0, 0xbe, 0x10, 0x0, 0x0, 0x0, 0x5,
+ 0xf5, 0x3d, 0xfd, 0x30, 0x0, 0x1e, 0xb0, 0xec,
+ 0x5d, 0xd0, 0x0, 0x9f, 0x24, 0xf3, 0x6, 0xf1,
+ 0x3, 0xf7, 0x4, 0xf3, 0x6, 0xf1, 0xd, 0xd0,
+ 0x1, 0xfb, 0x4d, 0xc0, 0x7f, 0x30, 0x0, 0x4d,
+ 0xfb, 0x10,
+
+ /* U+0026 "&" */
+ 0x0, 0x8, 0xef, 0xc4, 0x0, 0x0, 0x0, 0x9f,
+ 0xca, 0xff, 0x30, 0x0, 0x1, 0xfd, 0x0, 0x5f,
+ 0x80, 0x0, 0x3, 0xfa, 0x0, 0x2f, 0xa0, 0x0,
+ 0x2, 0xfd, 0x0, 0x7f, 0x60, 0x0, 0x0, 0xcf,
+ 0x57, 0xfc, 0x0, 0x0, 0x0, 0x3f, 0xff, 0xa0,
+ 0x0, 0x0, 0x0, 0x8f, 0xfd, 0x0, 0x15, 0x20,
+ 0x8, 0xfa, 0xcf, 0x90, 0x5f, 0x70, 0x1f, 0xd0,
+ 0x1e, 0xf5, 0x7f, 0x50, 0x5f, 0x70, 0x4, 0xff,
+ 0xcf, 0x20, 0x6f, 0x80, 0x0, 0x7f, 0xfc, 0x0,
+ 0x3f, 0xd0, 0x0, 0xe, 0xfa, 0x0, 0xa, 0xfd,
+ 0x88, 0xdf, 0xff, 0x60, 0x0, 0x7d, 0xfe, 0xb3,
+ 0x3f, 0xf3,
+
+ /* U+0027 "'" */
+ 0x5f, 0xe4, 0xfd, 0x4f, 0xc3, 0xfb, 0x2f, 0xa0,
+ 0x0,
+
+ /* U+0028 "(" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x8,
+ 0xf8, 0x0, 0x5f, 0xb0, 0x1, 0xee, 0x10, 0x8,
+ 0xf6, 0x0, 0xf, 0xe0, 0x0, 0x5f, 0x80, 0x0,
+ 0x9f, 0x30, 0x0, 0xbf, 0x10, 0x0, 0xdf, 0x0,
+ 0x0, 0xef, 0x0, 0x0, 0xdf, 0x0, 0x0, 0xbf,
+ 0x20, 0x0, 0x8f, 0x60, 0x0, 0x3f, 0xb0, 0x0,
+ 0xc, 0xf2, 0x0, 0x4, 0xfb, 0x0, 0x0, 0xbf,
+ 0x50, 0x0, 0x1e, 0xf3, 0x0, 0x3, 0xfa, 0x0,
+ 0x0, 0x30,
+
+ /* U+0029 ")" */
+ 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x1e,
+ 0xf2, 0x0, 0x0, 0x3f, 0xd0, 0x0, 0x0, 0x7f,
+ 0x80, 0x0, 0x0, 0xdf, 0x20, 0x0, 0x5, 0xf8,
+ 0x0, 0x0, 0xf, 0xe0, 0x0, 0x0, 0xbf, 0x20,
+ 0x0, 0x8, 0xf5, 0x0, 0x0, 0x7f, 0x60, 0x0,
+ 0x6, 0xf6, 0x0, 0x0, 0x7f, 0x50, 0x0, 0x9,
+ 0xf3, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x2f, 0xb0,
+ 0x0, 0x8, 0xf4, 0x0, 0x2, 0xfc, 0x0, 0x0,
+ 0xbf, 0x30, 0x0, 0x8f, 0x70, 0x0, 0x1f, 0xa0,
+ 0x0, 0x0, 0x30, 0x0, 0x0,
+
+ /* U+002A "*" */
+ 0x0, 0x0, 0xe7, 0x0, 0x0, 0x20, 0xd, 0x60,
+ 0x1, 0x1f, 0x90, 0xc5, 0x3d, 0xa0, 0x5d, 0xdd,
+ 0xbf, 0xa2, 0x0, 0xa, 0xff, 0x40, 0x0, 0x3b,
+ 0xee, 0xcf, 0x81, 0x1f, 0xa1, 0xc5, 0x4e, 0xa0,
+ 0x30, 0xd, 0x60, 0x11, 0x0, 0x0, 0xe7, 0x0,
+ 0x0, 0x0, 0x1, 0x10, 0x0,
+
+ /* U+002B "+" */
+ 0x0, 0x0, 0x1f, 0xa0, 0x0, 0x0, 0x0, 0x1,
+ 0xfa, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xa0, 0x0,
+ 0x0, 0x0, 0x1, 0xfa, 0x0, 0x0, 0x1a, 0xaa,
+ 0xaf, 0xea, 0xaa, 0x72, 0xff, 0xff, 0xff, 0xff,
+ 0xfb, 0x0, 0x0, 0x1f, 0xa0, 0x0, 0x0, 0x0,
+ 0x1, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xa0,
+ 0x0, 0x0, 0x0, 0x1, 0xfa, 0x0, 0x0, 0x0,
+ 0x0, 0x6, 0x30, 0x0, 0x0,
+
+ /* U+002C "," */
+ 0x0, 0x3a, 0x40, 0x0, 0xcf, 0xf1, 0x0, 0x8f,
+ 0xf5, 0x0, 0xf, 0xf5, 0x0, 0xf, 0xf1, 0x14,
+ 0xcf, 0x80, 0x9f, 0xe7, 0x0, 0x23, 0x0, 0x0,
+
+ /* U+002D "-" */
+ 0x3c, 0xcc, 0xcc, 0xa4, 0xff, 0xff, 0xfd,
+
+ /* U+002E "." */
+ 0x1, 0x84, 0x0, 0xdf, 0xf3, 0xf, 0xff, 0x50,
+ 0x6f, 0xb0,
+
+ /* U+002F "/" */
+ 0x0, 0x0, 0x0, 0x0, 0xa, 0xe1, 0x0, 0x0,
+ 0x0, 0x0, 0x4f, 0x60, 0x0, 0x0, 0x0, 0x0,
+ 0xec, 0x0, 0x0, 0x0, 0x0, 0x9, 0xf2, 0x0,
+ 0x0, 0x0, 0x0, 0x3f, 0x80, 0x0, 0x0, 0x0,
+ 0x0, 0xcd, 0x0, 0x0, 0x0, 0x0, 0x7, 0xf3,
+ 0x0, 0x0, 0x0, 0x0, 0x1f, 0x90, 0x0, 0x0,
+ 0x0, 0x0, 0xbe, 0x10, 0x0, 0x0, 0x0, 0x5,
+ 0xf5, 0x0, 0x0, 0x0, 0x0, 0x1e, 0xb0, 0x0,
+ 0x0, 0x0, 0x0, 0x9f, 0x20, 0x0, 0x0, 0x0,
+ 0x3, 0xf7, 0x0, 0x0, 0x0, 0x0, 0xd, 0xd0,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0x30, 0x0, 0x0,
+ 0x0, 0x0,
+
+ /* U+0030 "0" */
+ 0x0, 0x5, 0xcf, 0xeb, 0x20, 0x0, 0x7, 0xfe,
+ 0xac, 0xff, 0x30, 0x2, 0xfd, 0x10, 0x6, 0xfc,
+ 0x0, 0x9f, 0x40, 0x0, 0xc, 0xf2, 0xd, 0xf0,
+ 0x0, 0x5, 0xff, 0x60, 0xfc, 0x0, 0x8, 0xfe,
+ 0xf8, 0x1f, 0xb0, 0x1c, 0xfa, 0x3f, 0x91, 0xfb,
+ 0x3e, 0xf6, 0x2, 0xf9, 0xf, 0xef, 0xd2, 0x0,
+ 0x3f, 0x80, 0xef, 0xa0, 0x0, 0x6, 0xf6, 0xa,
+ 0xf4, 0x0, 0x0, 0xbf, 0x20, 0x4f, 0xd1, 0x0,
+ 0x5f, 0xb0, 0x0, 0x9f, 0xea, 0xbf, 0xe2, 0x0,
+ 0x0, 0x7d, 0xfe, 0x91, 0x0,
+
+ /* U+0031 "1" */
+ 0x0, 0x5, 0xef, 0x30, 0x0, 0x4, 0xdf, 0xff,
+ 0x30, 0x0, 0x6f, 0xf8, 0xcf, 0x30, 0x0, 0x2a,
+ 0x10, 0xcf, 0x30, 0x0, 0x0, 0x0, 0xcf, 0x30,
+ 0x0, 0x0, 0x0, 0xcf, 0x30, 0x0, 0x0, 0x0,
+ 0xcf, 0x30, 0x0, 0x0, 0x0, 0xcf, 0x30, 0x0,
+ 0x0, 0x0, 0xcf, 0x30, 0x0, 0x0, 0x0, 0xcf,
+ 0x30, 0x0, 0x0, 0x0, 0xcf, 0x30, 0x0, 0x0,
+ 0x0, 0xcf, 0x30, 0x0, 0x2c, 0xcc, 0xff, 0xcc,
+ 0xc2, 0x3f, 0xff, 0xff, 0xff, 0xf3,
+
+ /* U+0032 "2" */
+ 0x1, 0x8d, 0xfe, 0x80, 0x0, 0x2e, 0xfc, 0xbe,
+ 0xfc, 0x0, 0xc, 0x40, 0x0, 0xdf, 0x50, 0x0,
+ 0x0, 0x0, 0x6f, 0x90, 0x0, 0x0, 0x0, 0x5f,
+ 0x80, 0x0, 0x0, 0x0, 0x8f, 0x50, 0x0, 0x0,
+ 0x2, 0xfe, 0x0, 0x0, 0x0, 0xc, 0xf4, 0x0,
+ 0x0, 0x0, 0xbf, 0x70, 0x0, 0x0, 0xb, 0xf8,
+ 0x0, 0x0, 0x0, 0xbf, 0x80, 0x0, 0x0, 0xa,
+ 0xf8, 0x0, 0x0, 0x0, 0x7f, 0xfc, 0xcc, 0xcc,
+ 0xc4, 0x8f, 0xff, 0xff, 0xff, 0xf5,
+
+ /* U+0033 "3" */
+ 0x9, 0xdf, 0xfd, 0x81, 0x0, 0xf, 0xca, 0xae,
+ 0xfd, 0x0, 0x0, 0x0, 0x0, 0xcf, 0x40, 0x0,
+ 0x0, 0x0, 0x7f, 0x60, 0x0, 0x0, 0x0, 0xaf,
+ 0x30, 0x0, 0x0, 0x17, 0xfa, 0x0, 0x0, 0xaf,
+ 0xff, 0xb0, 0x0, 0x0, 0x58, 0x9c, 0xfd, 0x20,
+ 0x0, 0x0, 0x0, 0x5f, 0xc0, 0x0, 0x0, 0x0,
+ 0xd, 0xf0, 0x0, 0x0, 0x0, 0xe, 0xf0, 0x0,
+ 0x0, 0x0, 0x8f, 0x90, 0x4c, 0xaa, 0xbe, 0xfc,
+ 0x10, 0x4e, 0xff, 0xeb, 0x60, 0x0,
+
+ /* U+0034 "4" */
+ 0x0, 0x0, 0x2, 0xff, 0xb0, 0x0, 0x0, 0x0,
+ 0xcf, 0xfb, 0x0, 0x0, 0x0, 0x5f, 0x9f, 0xb0,
+ 0x0, 0x0, 0x1e, 0xd2, 0xfb, 0x0, 0x0, 0x9,
+ 0xf3, 0x1f, 0xb0, 0x0, 0x3, 0xf9, 0x1, 0xfb,
+ 0x0, 0x0, 0xce, 0x10, 0x1f, 0xb0, 0x0, 0x6f,
+ 0x50, 0x1, 0xfb, 0x0, 0x1f, 0xb0, 0x0, 0x1f,
+ 0xb0, 0x8, 0xfc, 0xaa, 0xaa, 0xfe, 0xaa, 0x9f,
+ 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x1,
+ 0xfb, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xb0, 0x0,
+ 0x0, 0x0, 0x1, 0xfb, 0x0,
+
+ /* U+0035 "5" */
+ 0xf, 0xff, 0xff, 0xff, 0x40, 0xfe, 0xaa, 0xaa,
+ 0xa2, 0xf, 0xc0, 0x0, 0x0, 0x0, 0xfc, 0x0,
+ 0x0, 0x0, 0xf, 0xc0, 0x0, 0x0, 0x0, 0xfe,
+ 0x98, 0x73, 0x0, 0xf, 0xff, 0xff, 0xfa, 0x0,
+ 0x0, 0x1, 0x5d, 0xf8, 0x0, 0x0, 0x0, 0x2f,
+ 0xe0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0,
+ 0x2f, 0xd0, 0x0, 0x0, 0x1c, 0xf6, 0x2c, 0xaa,
+ 0xcf, 0xf8, 0x2, 0xef, 0xfe, 0xa3, 0x0,
+
+ /* U+0036 "6" */
+ 0x0, 0x3, 0x9d, 0xff, 0x70, 0x0, 0x7f, 0xfc,
+ 0xaa, 0x40, 0x6, 0xfa, 0x10, 0x0, 0x0, 0xe,
+ 0xc0, 0x0, 0x0, 0x0, 0x4f, 0x60, 0x0, 0x0,
+ 0x0, 0x8f, 0x6a, 0xdf, 0xd8, 0x0, 0xaf, 0xfd,
+ 0x99, 0xef, 0xa0, 0xbf, 0x50, 0x0, 0xd, 0xf3,
+ 0xbf, 0x20, 0x0, 0x7, 0xf6, 0xaf, 0x30, 0x0,
+ 0x6, 0xf7, 0x7f, 0x70, 0x0, 0x8, 0xf5, 0x2f,
+ 0xd1, 0x0, 0x2f, 0xe0, 0x8, 0xfe, 0x9a, 0xff,
+ 0x50, 0x0, 0x6d, 0xfe, 0xb3, 0x0,
+
+ /* U+0037 "7" */
+ 0xcf, 0xff, 0xff, 0xff, 0xf4, 0x9c, 0xcc, 0xcc,
+ 0xce, 0xf4, 0x0, 0x0, 0x0, 0xe, 0xe0, 0x0,
+ 0x0, 0x0, 0x6f, 0x70, 0x0, 0x0, 0x0, 0xdf,
+ 0x0, 0x0, 0x0, 0x5, 0xf8, 0x0, 0x0, 0x0,
+ 0xd, 0xf1, 0x0, 0x0, 0x0, 0x4f, 0x90, 0x0,
+ 0x0, 0x0, 0xcf, 0x20, 0x0, 0x0, 0x4, 0xfb,
+ 0x0, 0x0, 0x0, 0xb, 0xf3, 0x0, 0x0, 0x0,
+ 0x3f, 0xc0, 0x0, 0x0, 0x0, 0xaf, 0x50, 0x0,
+ 0x0, 0x2, 0xfd, 0x0, 0x0, 0x0,
+
+ /* U+0038 "8" */
+ 0x0, 0x7d, 0xff, 0xc5, 0x0, 0xb, 0xfc, 0x9a,
+ 0xef, 0x80, 0x5f, 0x90, 0x0, 0x1f, 0xe0, 0x7f,
+ 0x60, 0x0, 0xd, 0xf0, 0x4f, 0xc0, 0x0, 0x3f,
+ 0xb0, 0xa, 0xfd, 0x56, 0xfe, 0x20, 0x0, 0x8f,
+ 0xff, 0xd1, 0x0, 0x2, 0xdf, 0xcf, 0xfb, 0x0,
+ 0x1e, 0xf4, 0x1, 0xcf, 0xb0, 0x9f, 0x60, 0x0,
+ 0xe, 0xf2, 0xbf, 0x30, 0x0, 0xa, 0xf4, 0xaf,
+ 0x80, 0x0, 0x1e, 0xf2, 0x3f, 0xfd, 0xaa, 0xff,
+ 0x90, 0x2, 0xad, 0xfe, 0xb5, 0x0,
+
+ /* U+0039 "9" */
+ 0x0, 0x7d, 0xfe, 0x91, 0x0, 0xc, 0xfc, 0x9b,
+ 0xfe, 0x10, 0x8f, 0x80, 0x0, 0x6f, 0x80, 0xdf,
+ 0x10, 0x0, 0xe, 0xe0, 0xff, 0x0, 0x0, 0xb,
+ 0xf1, 0xdf, 0x10, 0x0, 0x9, 0xf3, 0x7f, 0xc2,
+ 0x2, 0x7e, 0xf3, 0xa, 0xff, 0xff, 0xfe, 0xf3,
+ 0x0, 0x47, 0x75, 0x1b, 0xf1, 0x0, 0x0, 0x0,
+ 0xe, 0xd0, 0x0, 0x0, 0x0, 0x6f, 0x70, 0x0,
+ 0x0, 0x6, 0xfd, 0x0, 0x1a, 0xac, 0xff, 0xd2,
+ 0x0, 0x2f, 0xfe, 0xb6, 0x0, 0x0,
+
+ /* U+003A ":" */
+ 0x4e, 0xb0, 0xbf, 0xf4, 0x8f, 0xf1, 0x3, 0x10,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x10,
+ 0x7f, 0xe1, 0xbf, 0xf4, 0x4e, 0xb0,
+
+ /* U+003B ";" */
+ 0x0, 0x4e, 0xb0, 0x0, 0xbf, 0xf4, 0x0, 0x8f,
+ 0xf1, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x50,
+ 0x0, 0x9f, 0xf3, 0x0, 0x7f, 0xf7, 0x0, 0xe,
+ 0xf7, 0x0, 0xd, 0xf3, 0x14, 0xaf, 0xa0, 0x7f,
+ 0xf8, 0x0, 0x23, 0x0, 0x0,
+
+ /* U+003C "<" */
+ 0x0, 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, 0x5f,
+ 0xe2, 0x0, 0x0, 0x7f, 0xd2, 0x0, 0x0, 0x9f,
+ 0xc1, 0x0, 0x0, 0xaf, 0xa0, 0x0, 0x1, 0xcf,
+ 0x80, 0x0, 0x0, 0x3e, 0xf4, 0x0, 0x0, 0x0,
+ 0x2e, 0xf6, 0x0, 0x0, 0x0, 0x1c, 0xf8, 0x0,
+ 0x0, 0x0, 0xb, 0xfa, 0x0, 0x0, 0x0, 0x9,
+ 0xfc, 0x10, 0x0, 0x0, 0x7, 0xd1, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+
+ /* U+003D "=" */
+ 0x59, 0x99, 0x99, 0x99, 0x91, 0xaf, 0xff, 0xff,
+ 0xff, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x59, 0x99, 0x99, 0x99,
+ 0x91, 0xaf, 0xff, 0xff, 0xff, 0xf3,
+
+ /* U+003E ">" */
+ 0x29, 0x0, 0x0, 0x0, 0x8, 0xfc, 0x10, 0x0,
+ 0x0, 0x7, 0xfd, 0x20, 0x0, 0x0, 0x5, 0xfe,
+ 0x30, 0x0, 0x0, 0x3, 0xef, 0x40, 0x0, 0x0,
+ 0x2, 0xdf, 0x60, 0x0, 0x0, 0xa, 0xfb, 0x0,
+ 0x0, 0x1c, 0xf9, 0x0, 0x0, 0x2d, 0xf7, 0x0,
+ 0x0, 0x3e, 0xf5, 0x0, 0x0, 0x5f, 0xe3, 0x0,
+ 0x0, 0x6, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+
+ /* U+003F "?" */
+ 0xde, 0xb5, 0x0, 0xa, 0xdf, 0xfb, 0x0, 0x0,
+ 0x2b, 0xfb, 0x0, 0x0, 0xd, 0xf3, 0x0, 0x0,
+ 0x8f, 0x60, 0x0, 0x9, 0xf5, 0x1, 0x25, 0xff,
+ 0x10, 0xdf, 0xfe, 0x50, 0xd, 0xe3, 0x0, 0x0,
+ 0xcd, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xa, 0xa0, 0x0, 0x4, 0xff, 0x40,
+ 0x0, 0x1d, 0xd1, 0x0, 0x0,
+
+ /* U+0040 "@" */
+ 0x0, 0x0, 0x6d, 0xfe, 0x91, 0x0, 0x0, 0xb,
+ 0xf9, 0x57, 0xed, 0x0, 0x0, 0x9f, 0x30, 0x0,
+ 0x2f, 0x70, 0x3, 0xf6, 0x0, 0x0, 0x9, 0xe0,
+ 0xa, 0xe0, 0x0, 0x0, 0x5, 0xf2, 0x1f, 0x80,
+ 0x4e, 0xfe, 0xb2, 0xf4, 0x5f, 0x21, 0xfb, 0x6f,
+ 0x91, 0xf5, 0x8f, 0x8, 0xf1, 0x2f, 0x60, 0xf6,
+ 0xbc, 0xd, 0xc0, 0x5f, 0x41, 0xf5, 0xca, 0xf,
+ 0x90, 0x7f, 0x22, 0xf4, 0xd9, 0x1f, 0x80, 0x9f,
+ 0x3, 0xf2, 0xe9, 0x1f, 0x80, 0xce, 0x7, 0xf0,
+ 0xd9, 0xf, 0xb6, 0xff, 0x3d, 0x90, 0xbb, 0x9,
+ 0xff, 0x5f, 0xfd, 0x10, 0x9e, 0x0, 0x32, 0x1,
+ 0x40, 0x0, 0x4f, 0x40, 0x0, 0x0, 0x0, 0x0,
+ 0xd, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xfd,
+ 0x75, 0x7a, 0xa0, 0x0, 0x0, 0x3b, 0xef, 0xd9,
+ 0x30, 0x0,
+
+ /* U+0041 "A" */
+ 0x0, 0x0, 0x9f, 0xf3, 0x0, 0x0, 0x0, 0x0,
+ 0xef, 0xf8, 0x0, 0x0, 0x0, 0x3, 0xf9, 0xfd,
+ 0x0, 0x0, 0x0, 0x9, 0xf3, 0xbf, 0x20, 0x0,
+ 0x0, 0xe, 0xe0, 0x7f, 0x70, 0x0, 0x0, 0x3f,
+ 0x90, 0x2f, 0xc0, 0x0, 0x0, 0x8f, 0x40, 0xd,
+ 0xf1, 0x0, 0x0, 0xdf, 0x0, 0x8, 0xf6, 0x0,
+ 0x2, 0xfb, 0x0, 0x3, 0xfb, 0x0, 0x7, 0xfd,
+ 0xbb, 0xbb, 0xff, 0x0, 0xc, 0xff, 0xff, 0xff,
+ 0xff, 0x50, 0x1f, 0xc0, 0x0, 0x0, 0x5f, 0xa0,
+ 0x6f, 0x70, 0x0, 0x0, 0xf, 0xf0, 0xbf, 0x20,
+ 0x0, 0x0, 0xb, 0xf4,
+
+ /* U+0042 "B" */
+ 0x6f, 0xff, 0xfe, 0xb5, 0x0, 0x6f, 0xc9, 0x9c,
+ 0xff, 0x60, 0x6f, 0x70, 0x0, 0x5f, 0xd0, 0x6f,
+ 0x70, 0x0, 0xf, 0xe0, 0x6f, 0x70, 0x0, 0x2f,
+ 0xc0, 0x6f, 0x70, 0x3, 0xcf, 0x40, 0x6f, 0xff,
+ 0xff, 0xf5, 0x0, 0x6f, 0xc9, 0x9c, 0xff, 0x60,
+ 0x6f, 0x70, 0x0, 0x3f, 0xf2, 0x6f, 0x70, 0x0,
+ 0x9, 0xf5, 0x6f, 0x70, 0x0, 0x9, 0xf5, 0x6f,
+ 0x70, 0x0, 0x2f, 0xf1, 0x6f, 0xc9, 0xab, 0xff,
+ 0x60, 0x6f, 0xff, 0xfe, 0xa3, 0x0,
+
+ /* U+0043 "C" */
+ 0x0, 0x0, 0x7d, 0xff, 0xd8, 0x10, 0x1, 0xdf,
+ 0xfc, 0xce, 0xf3, 0x0, 0xcf, 0x90, 0x0, 0x4,
+ 0x10, 0x5f, 0xb0, 0x0, 0x0, 0x0, 0xb, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0xef, 0x0, 0x0, 0x0,
+ 0x0, 0xf, 0xe0, 0x0, 0x0, 0x0, 0x0, 0xfe,
+ 0x0, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0,
+ 0x0, 0x0, 0xdf, 0x30, 0x0, 0x0, 0x0, 0x8,
+ 0xfa, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf8, 0x0,
+ 0x0, 0x31, 0x0, 0x4f, 0xfe, 0xbc, 0xef, 0x30,
+ 0x0, 0x29, 0xdf, 0xec, 0x81,
+
+ /* U+0044 "D" */
+ 0xef, 0xff, 0xec, 0x70, 0x0, 0xef, 0x99, 0xbe,
+ 0xfd, 0x20, 0xef, 0x0, 0x0, 0x9f, 0xc0, 0xef,
+ 0x0, 0x0, 0xc, 0xf4, 0xef, 0x0, 0x0, 0x6,
+ 0xf8, 0xef, 0x0, 0x0, 0x3, 0xfb, 0xef, 0x0,
+ 0x0, 0x2, 0xfc, 0xef, 0x0, 0x0, 0x2, 0xfb,
+ 0xef, 0x0, 0x0, 0x4, 0xfa, 0xef, 0x0, 0x0,
+ 0x7, 0xf7, 0xef, 0x0, 0x0, 0xe, 0xf2, 0xef,
+ 0x0, 0x1, 0xcf, 0x90, 0xef, 0xaa, 0xcf, 0xf9,
+ 0x0, 0xef, 0xff, 0xea, 0x40, 0x0,
+
+ /* U+0045 "E" */
+ 0xff, 0xff, 0xff, 0xfb, 0xff, 0x99, 0x99, 0x96,
+ 0xfe, 0x0, 0x0, 0x0, 0xfe, 0x0, 0x0, 0x0,
+ 0xfe, 0x0, 0x0, 0x0, 0xfe, 0x0, 0x0, 0x0,
+ 0xff, 0xff, 0xff, 0xf7, 0xff, 0xaa, 0xaa, 0xa4,
+ 0xfe, 0x0, 0x0, 0x0, 0xfe, 0x0, 0x0, 0x0,
+ 0xfe, 0x0, 0x0, 0x0, 0xfe, 0x0, 0x0, 0x0,
+ 0xff, 0xaa, 0xaa, 0xa7, 0xff, 0xff, 0xff, 0xfb,
+
+ /* U+0046 "F" */
+ 0xef, 0xff, 0xff, 0xfa, 0xef, 0xaa, 0xaa, 0xa6,
+ 0xef, 0x0, 0x0, 0x0, 0xef, 0x0, 0x0, 0x0,
+ 0xef, 0x0, 0x0, 0x0, 0xef, 0x0, 0x0, 0x0,
+ 0xef, 0xff, 0xff, 0xf5, 0xef, 0x99, 0x99, 0x93,
+ 0xef, 0x0, 0x0, 0x0, 0xef, 0x0, 0x0, 0x0,
+ 0xef, 0x0, 0x0, 0x0, 0xef, 0x0, 0x0, 0x0,
+ 0xef, 0x0, 0x0, 0x0, 0xef, 0x0, 0x0, 0x0,
+
+ /* U+0047 "G" */
+ 0x0, 0x1, 0x8d, 0xff, 0xd9, 0x10, 0x3, 0xef,
+ 0xfc, 0xce, 0xf5, 0x1, 0xef, 0x80, 0x0, 0x3,
+ 0x20, 0x9f, 0x80, 0x0, 0x0, 0x0, 0xf, 0xf1,
+ 0x0, 0x0, 0x0, 0x2, 0xfb, 0x0, 0x0, 0x0,
+ 0x0, 0x4f, 0x90, 0x2, 0xff, 0xff, 0x64, 0xfa,
+ 0x0, 0x19, 0x9c, 0xf6, 0x3f, 0xb0, 0x0, 0x0,
+ 0x6f, 0x61, 0xfe, 0x0, 0x0, 0x6, 0xf6, 0xc,
+ 0xf5, 0x0, 0x0, 0x6f, 0x60, 0x4f, 0xf5, 0x0,
+ 0x6, 0xf6, 0x0, 0x7f, 0xfe, 0xbb, 0xef, 0x60,
+ 0x0, 0x3a, 0xef, 0xfc, 0x81,
+
+ /* U+0048 "H" */
+ 0xdf, 0x0, 0x0, 0x6, 0xf6, 0xdf, 0x0, 0x0,
+ 0x6, 0xf6, 0xdf, 0x0, 0x0, 0x6, 0xf6, 0xdf,
+ 0x0, 0x0, 0x6, 0xf6, 0xdf, 0x0, 0x0, 0x6,
+ 0xf6, 0xdf, 0x0, 0x0, 0x6, 0xf6, 0xdf, 0xff,
+ 0xff, 0xff, 0xf6, 0xdf, 0xaa, 0xaa, 0xac, 0xf6,
+ 0xdf, 0x0, 0x0, 0x6, 0xf6, 0xdf, 0x0, 0x0,
+ 0x6, 0xf6, 0xdf, 0x0, 0x0, 0x6, 0xf6, 0xdf,
+ 0x0, 0x0, 0x6, 0xf6, 0xdf, 0x0, 0x0, 0x6,
+ 0xf6, 0xdf, 0x0, 0x0, 0x6, 0xf6,
+
+ /* U+0049 "I" */
+ 0x3f, 0xff, 0xff, 0xff, 0xc2, 0x99, 0xaf, 0xe9,
+ 0x97, 0x0, 0x2, 0xfb, 0x0, 0x0, 0x0, 0x2f,
+ 0xb0, 0x0, 0x0, 0x2, 0xfb, 0x0, 0x0, 0x0,
+ 0x2f, 0xb0, 0x0, 0x0, 0x2, 0xfb, 0x0, 0x0,
+ 0x0, 0x2f, 0xb0, 0x0, 0x0, 0x2, 0xfb, 0x0,
+ 0x0, 0x0, 0x2f, 0xb0, 0x0, 0x0, 0x2, 0xfb,
+ 0x0, 0x0, 0x0, 0x2f, 0xb0, 0x0, 0x2a, 0xab,
+ 0xfe, 0xaa, 0x83, 0xff, 0xff, 0xff, 0xfc,
+
+ /* U+004A "J" */
+ 0xf, 0xff, 0xff, 0xff, 0xa, 0xaa, 0xaa, 0xff,
+ 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0, 0xdf,
+ 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0, 0xdf,
+ 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0, 0xdf,
+ 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0, 0xdf,
+ 0x0, 0x0, 0x0, 0xfe, 0x15, 0x0, 0x7, 0xfa,
+ 0x2f, 0xeb, 0xcf, 0xe2, 0x8, 0xdf, 0xea, 0x20,
+
+ /* U+004B "K" */
+ 0x6f, 0x60, 0x0, 0x1e, 0xf2, 0x6f, 0x60, 0x0,
+ 0xcf, 0x40, 0x6f, 0x60, 0x8, 0xf8, 0x0, 0x6f,
+ 0x60, 0x4f, 0xb0, 0x0, 0x6f, 0x62, 0xed, 0x10,
+ 0x0, 0x6f, 0x7c, 0xf2, 0x0, 0x0, 0x6f, 0xef,
+ 0x60, 0x0, 0x0, 0x6f, 0xbf, 0xc0, 0x0, 0x0,
+ 0x6f, 0x69, 0xf9, 0x0, 0x0, 0x6f, 0x60, 0xdf,
+ 0x50, 0x0, 0x6f, 0x60, 0x2f, 0xf2, 0x0, 0x6f,
+ 0x60, 0x6, 0xfd, 0x0, 0x6f, 0x60, 0x0, 0xaf,
+ 0x90, 0x6f, 0x60, 0x0, 0xd, 0xf5,
+
+ /* U+004C "L" */
+ 0x9f, 0x40, 0x0, 0x0, 0x9, 0xf4, 0x0, 0x0,
+ 0x0, 0x9f, 0x40, 0x0, 0x0, 0x9, 0xf4, 0x0,
+ 0x0, 0x0, 0x9f, 0x40, 0x0, 0x0, 0x9, 0xf4,
+ 0x0, 0x0, 0x0, 0x9f, 0x40, 0x0, 0x0, 0x9,
+ 0xf4, 0x0, 0x0, 0x0, 0x9f, 0x40, 0x0, 0x0,
+ 0x9, 0xf4, 0x0, 0x0, 0x0, 0x9f, 0x40, 0x0,
+ 0x0, 0x9, 0xf4, 0x0, 0x0, 0x0, 0x9f, 0xba,
+ 0xaa, 0xaa, 0x9, 0xff, 0xff, 0xff, 0xf1,
+
+ /* U+004D "M" */
+ 0xd, 0xf7, 0x0, 0x0, 0xff, 0x60, 0xe, 0xfd,
+ 0x0, 0x5, 0xff, 0x70, 0xf, 0xdf, 0x20, 0xb,
+ 0xcf, 0x80, 0xf, 0x8f, 0x80, 0x1f, 0x6f, 0x80,
+ 0xf, 0x7b, 0xd0, 0x7f, 0x1f, 0x90, 0x1f, 0x76,
+ 0xf3, 0xca, 0xf, 0xa0, 0x2f, 0x60, 0xfa, 0xf5,
+ 0xf, 0xb0, 0x3f, 0x60, 0xaf, 0xf0, 0xe, 0xb0,
+ 0x3f, 0x60, 0x5f, 0x90, 0xe, 0xc0, 0x4f, 0x50,
+ 0x6, 0x20, 0xd, 0xd0, 0x5f, 0x50, 0x0, 0x0,
+ 0xd, 0xe0, 0x6f, 0x40, 0x0, 0x0, 0xd, 0xe0,
+ 0x6f, 0x40, 0x0, 0x0, 0xc, 0xf0, 0x7f, 0x30,
+ 0x0, 0x0, 0xc, 0xf0,
+
+ /* U+004E "N" */
+ 0xcf, 0xc0, 0x0, 0x5, 0xf5, 0xcf, 0xf3, 0x0,
+ 0x5, 0xf5, 0xcf, 0xfb, 0x0, 0x5, 0xf5, 0xce,
+ 0xaf, 0x20, 0x5, 0xf5, 0xce, 0x4f, 0x90, 0x5,
+ 0xf5, 0xce, 0xd, 0xf1, 0x5, 0xf5, 0xce, 0x6,
+ 0xf7, 0x5, 0xf5, 0xce, 0x0, 0xee, 0x5, 0xf5,
+ 0xce, 0x0, 0x8f, 0x65, 0xf5, 0xce, 0x0, 0x1f,
+ 0xc5, 0xf5, 0xce, 0x0, 0x9, 0xf9, 0xf5, 0xce,
+ 0x0, 0x2, 0xff, 0xf5, 0xce, 0x0, 0x0, 0xbf,
+ 0xf5, 0xce, 0x0, 0x0, 0x4f, 0xf5,
+
+ /* U+004F "O" */
+ 0x0, 0x6, 0xcf, 0xeb, 0x40, 0x0, 0xa, 0xff,
+ 0xbc, 0xff, 0x60, 0x5, 0xfc, 0x10, 0x4, 0xff,
+ 0x10, 0xdf, 0x20, 0x0, 0x8, 0xf7, 0x2f, 0xd0,
+ 0x0, 0x0, 0x3f, 0xc5, 0xf9, 0x0, 0x0, 0x0,
+ 0xfe, 0x6f, 0x80, 0x0, 0x0, 0xf, 0xf6, 0xf8,
+ 0x0, 0x0, 0x0, 0xff, 0x5f, 0x90, 0x0, 0x0,
+ 0xf, 0xd3, 0xfb, 0x0, 0x0, 0x3, 0xfa, 0xe,
+ 0xf1, 0x0, 0x0, 0x9f, 0x60, 0x8f, 0xb0, 0x0,
+ 0x4f, 0xe0, 0x0, 0xcf, 0xeb, 0xcf, 0xf3, 0x0,
+ 0x0, 0x8d, 0xfe, 0xa2, 0x0,
+
+ /* U+0050 "P" */
+ 0x6f, 0xff, 0xfd, 0xa4, 0x0, 0x6f, 0xc9, 0xac,
+ 0xff, 0x60, 0x6f, 0x70, 0x0, 0x4f, 0xf1, 0x6f,
+ 0x70, 0x0, 0xa, 0xf5, 0x6f, 0x70, 0x0, 0x8,
+ 0xf6, 0x6f, 0x70, 0x0, 0xb, 0xf3, 0x6f, 0x70,
+ 0x0, 0x5f, 0xd0, 0x6f, 0xca, 0xbd, 0xfe, 0x30,
+ 0x6f, 0xff, 0xfd, 0x91, 0x0, 0x6f, 0x70, 0x0,
+ 0x0, 0x0, 0x6f, 0x70, 0x0, 0x0, 0x0, 0x6f,
+ 0x70, 0x0, 0x0, 0x0, 0x6f, 0x70, 0x0, 0x0,
+ 0x0, 0x6f, 0x70, 0x0, 0x0, 0x0,
+
+ /* U+0051 "Q" */
+ 0x0, 0x5, 0xcf, 0xeb, 0x40, 0x0, 0x0, 0x9f,
+ 0xfb, 0xcf, 0xf5, 0x0, 0x5, 0xfd, 0x10, 0x4,
+ 0xff, 0x10, 0xc, 0xf3, 0x0, 0x0, 0x9f, 0x70,
+ 0x1f, 0xc0, 0x0, 0x0, 0x3f, 0xb0, 0x4f, 0x90,
+ 0x0, 0x0, 0x1f, 0xe0, 0x5f, 0x80, 0x0, 0x0,
+ 0xf, 0xf0, 0x6f, 0x80, 0x0, 0x0, 0xf, 0xf0,
+ 0x5f, 0x90, 0x0, 0x0, 0xf, 0xe0, 0x4f, 0xb0,
+ 0x0, 0x0, 0x2f, 0xb0, 0xf, 0xf0, 0x0, 0x0,
+ 0x8f, 0x70, 0xa, 0xf8, 0x0, 0x1, 0xef, 0x10,
+ 0x2, 0xff, 0xa6, 0x7e, 0xf6, 0x0, 0x0, 0x3d,
+ 0xff, 0xfe, 0x60, 0x0, 0x0, 0x0, 0x4f, 0xa0,
+ 0x0, 0x0, 0x0, 0x0, 0xe, 0xe1, 0x0, 0x20,
+ 0x0, 0x0, 0x6, 0xfe, 0xbc, 0xf4, 0x0, 0x0,
+ 0x0, 0x6c, 0xfd, 0x91,
+
+ /* U+0052 "R" */
+ 0x4f, 0xff, 0xfe, 0xa2, 0x0, 0x4f, 0xd9, 0xad,
+ 0xff, 0x20, 0x4f, 0x90, 0x0, 0x8f, 0x90, 0x4f,
+ 0x90, 0x0, 0x3f, 0xb0, 0x4f, 0x90, 0x0, 0x5f,
+ 0x90, 0x4f, 0x90, 0x4, 0xef, 0x30, 0x4f, 0xff,
+ 0xff, 0xd4, 0x0, 0x4f, 0xc8, 0xcf, 0x70, 0x0,
+ 0x4f, 0x90, 0xc, 0xf4, 0x0, 0x4f, 0x90, 0x3,
+ 0xfc, 0x0, 0x4f, 0x90, 0x0, 0xcf, 0x30, 0x4f,
+ 0x90, 0x0, 0x5f, 0xa0, 0x4f, 0x90, 0x0, 0xe,
+ 0xf1, 0x4f, 0x90, 0x0, 0x7, 0xf8,
+
+ /* U+0053 "S" */
+ 0x0, 0x7c, 0xff, 0xec, 0x30, 0xc, 0xfe, 0xba,
+ 0xce, 0x50, 0x7f, 0xa0, 0x0, 0x0, 0x0, 0xaf,
+ 0x40, 0x0, 0x0, 0x0, 0x9f, 0x80, 0x0, 0x0,
+ 0x0, 0x2f, 0xfa, 0x20, 0x0, 0x0, 0x3, 0xdf,
+ 0xfb, 0x40, 0x0, 0x0, 0x5, 0xbf, 0xfb, 0x10,
+ 0x0, 0x0, 0x3, 0xcf, 0xb0, 0x0, 0x0, 0x0,
+ 0xd, 0xf2, 0x0, 0x0, 0x0, 0xc, 0xf2, 0x20,
+ 0x0, 0x0, 0x4f, 0xe0, 0xde, 0xcb, 0xbd, 0xff,
+ 0x50, 0x8c, 0xef, 0xfd, 0x92, 0x0,
+
+ /* U+0054 "T" */
+ 0x2f, 0xff, 0xff, 0xff, 0xff, 0xa1, 0xaa, 0xab,
+ 0xfe, 0xaa, 0xa6, 0x0, 0x0, 0x2f, 0xb0, 0x0,
+ 0x0, 0x0, 0x2, 0xfb, 0x0, 0x0, 0x0, 0x0,
+ 0x2f, 0xb0, 0x0, 0x0, 0x0, 0x2, 0xfb, 0x0,
+ 0x0, 0x0, 0x0, 0x2f, 0xb0, 0x0, 0x0, 0x0,
+ 0x2, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xb0,
+ 0x0, 0x0, 0x0, 0x2, 0xfb, 0x0, 0x0, 0x0,
+ 0x0, 0x2f, 0xb0, 0x0, 0x0, 0x0, 0x2, 0xfb,
+ 0x0, 0x0, 0x0, 0x0, 0x2f, 0xb0, 0x0, 0x0,
+ 0x0, 0x2, 0xfb, 0x0, 0x0,
+
+ /* U+0055 "U" */
+ 0xef, 0x0, 0x0, 0x6, 0xf7, 0xef, 0x0, 0x0,
+ 0x6, 0xf7, 0xef, 0x0, 0x0, 0x6, 0xf7, 0xef,
+ 0x0, 0x0, 0x6, 0xf7, 0xef, 0x0, 0x0, 0x6,
+ 0xf7, 0xef, 0x0, 0x0, 0x6, 0xf7, 0xef, 0x0,
+ 0x0, 0x6, 0xf7, 0xef, 0x0, 0x0, 0x6, 0xf7,
+ 0xef, 0x0, 0x0, 0x6, 0xf7, 0xdf, 0x0, 0x0,
+ 0x7, 0xf6, 0xbf, 0x10, 0x0, 0x9, 0xf4, 0x8f,
+ 0x90, 0x0, 0x2f, 0xe0, 0x1e, 0xfd, 0xab, 0xff,
+ 0x40, 0x1, 0x9e, 0xfe, 0xb3, 0x0,
+
+ /* U+0056 "V" */
+ 0xcf, 0x40, 0x0, 0x0, 0x9, 0xf5, 0x7f, 0x90,
+ 0x0, 0x0, 0xe, 0xf0, 0x2f, 0xd0, 0x0, 0x0,
+ 0x3f, 0xa0, 0xd, 0xf2, 0x0, 0x0, 0x8f, 0x50,
+ 0x8, 0xf7, 0x0, 0x0, 0xdf, 0x0, 0x3, 0xfc,
+ 0x0, 0x2, 0xfb, 0x0, 0x0, 0xef, 0x10, 0x7,
+ 0xf6, 0x0, 0x0, 0x9f, 0x60, 0xb, 0xf1, 0x0,
+ 0x0, 0x4f, 0xb0, 0x1f, 0xb0, 0x0, 0x0, 0xe,
+ 0xf0, 0x5f, 0x60, 0x0, 0x0, 0xa, 0xf4, 0xaf,
+ 0x10, 0x0, 0x0, 0x4, 0xfa, 0xfc, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0,
+ 0xaf, 0xf1, 0x0, 0x0,
+
+ /* U+0057 "W" */
+ 0x8f, 0x30, 0x0, 0x0, 0x9, 0xf0, 0x6f, 0x40,
+ 0x0, 0x0, 0xa, 0xf0, 0x5f, 0x50, 0x0, 0x0,
+ 0xa, 0xe0, 0x4f, 0x60, 0x0, 0x0, 0xb, 0xd0,
+ 0x3f, 0x60, 0x3, 0x10, 0xc, 0xc0, 0x2f, 0x70,
+ 0x1f, 0xa0, 0xd, 0xb0, 0x1f, 0x80, 0x6f, 0xf0,
+ 0xe, 0xa0, 0xf, 0x90, 0xbe, 0xf5, 0xf, 0x90,
+ 0xf, 0xa1, 0xf6, 0xfa, 0xf, 0x80, 0xe, 0xb5,
+ 0xf1, 0xbf, 0x1f, 0x70, 0xd, 0xca, 0xc0, 0x5f,
+ 0x6f, 0x60, 0xc, 0xdf, 0x70, 0xf, 0xcf, 0x50,
+ 0xb, 0xff, 0x20, 0xb, 0xff, 0x40, 0xa, 0xfd,
+ 0x0, 0x5, 0xff, 0x30,
+
+ /* U+0058 "X" */
+ 0x2f, 0xe1, 0x0, 0x0, 0x7f, 0xa0, 0x8, 0xf9,
+ 0x0, 0x1, 0xef, 0x10, 0x0, 0xef, 0x20, 0x9,
+ 0xf7, 0x0, 0x0, 0x5f, 0xb0, 0x3f, 0xd0, 0x0,
+ 0x0, 0xc, 0xf5, 0xcf, 0x30, 0x0, 0x0, 0x2,
+ 0xff, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf1,
+ 0x0, 0x0, 0x0, 0x0, 0xcf, 0xf4, 0x0, 0x0,
+ 0x0, 0x6, 0xfc, 0xfd, 0x0, 0x0, 0x0, 0x1e,
+ 0xf1, 0x9f, 0x80, 0x0, 0x0, 0xaf, 0x70, 0x1f,
+ 0xf2, 0x0, 0x4, 0xfe, 0x0, 0x7, 0xfc, 0x0,
+ 0xd, 0xf5, 0x0, 0x0, 0xdf, 0x50, 0x8f, 0xc0,
+ 0x0, 0x0, 0x4f, 0xe1,
+
+ /* U+0059 "Y" */
+ 0xbf, 0x70, 0x0, 0x0, 0xc, 0xf4, 0x3f, 0xe0,
+ 0x0, 0x0, 0x4f, 0xb0, 0xa, 0xf8, 0x0, 0x0,
+ 0xcf, 0x30, 0x2, 0xff, 0x10, 0x5, 0xfa, 0x0,
+ 0x0, 0x9f, 0x80, 0xd, 0xf2, 0x0, 0x0, 0x1f,
+ 0xf1, 0x5f, 0x90, 0x0, 0x0, 0x7, 0xf8, 0xdf,
+ 0x10, 0x0, 0x0, 0x0, 0xef, 0xf8, 0x0, 0x0,
+ 0x0, 0x0, 0x6f, 0xe0, 0x0, 0x0, 0x0, 0x0,
+ 0x2f, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xb0,
+ 0x0, 0x0, 0x0, 0x0, 0x2f, 0xb0, 0x0, 0x0,
+ 0x0, 0x0, 0x2f, 0xb0, 0x0, 0x0, 0x0, 0x0,
+ 0x2f, 0xb0, 0x0, 0x0,
+
+ /* U+005A "Z" */
+ 0xaf, 0xff, 0xff, 0xff, 0xf4, 0x8c, 0xcc, 0xcc,
+ 0xcf, 0xf3, 0x0, 0x0, 0x0, 0x7f, 0xa0, 0x0,
+ 0x0, 0x2, 0xfe, 0x10, 0x0, 0x0, 0xb, 0xf5,
+ 0x0, 0x0, 0x0, 0x5f, 0xb0, 0x0, 0x0, 0x1,
+ 0xef, 0x10, 0x0, 0x0, 0xa, 0xf7, 0x0, 0x0,
+ 0x0, 0x4f, 0xc0, 0x0, 0x0, 0x0, 0xdf, 0x20,
+ 0x0, 0x0, 0x8, 0xf8, 0x0, 0x0, 0x0, 0x3f,
+ 0xd0, 0x0, 0x0, 0x0, 0xcf, 0xec, 0xcc, 0xcc,
+ 0xc4, 0xdf, 0xff, 0xff, 0xff, 0xf6,
+
+ /* U+005B "[" */
+ 0x7f, 0xff, 0xf9, 0x7f, 0x98, 0x84, 0x7f, 0x30,
+ 0x0, 0x7f, 0x30, 0x0, 0x7f, 0x30, 0x0, 0x7f,
+ 0x30, 0x0, 0x7f, 0x30, 0x0, 0x7f, 0x30, 0x0,
+ 0x7f, 0x30, 0x0, 0x7f, 0x30, 0x0, 0x7f, 0x30,
+ 0x0, 0x7f, 0x30, 0x0, 0x7f, 0x30, 0x0, 0x7f,
+ 0x30, 0x0, 0x7f, 0x30, 0x0, 0x7f, 0x30, 0x0,
+ 0x7f, 0x30, 0x0, 0x7f, 0x98, 0x84, 0x7f, 0xff,
+ 0xf9,
+
+ /* U+005C "\\" */
+ 0x2f, 0x80, 0x0, 0x0, 0x0, 0xc, 0xe0, 0x0,
+ 0x0, 0x0, 0x5, 0xf5, 0x0, 0x0, 0x0, 0x0,
+ 0xeb, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x20, 0x0,
+ 0x0, 0x0, 0x2f, 0x80, 0x0, 0x0, 0x0, 0xc,
+ 0xe0, 0x0, 0x0, 0x0, 0x5, 0xf5, 0x0, 0x0,
+ 0x0, 0x0, 0xec, 0x0, 0x0, 0x0, 0x0, 0x8f,
+ 0x20, 0x0, 0x0, 0x0, 0x2f, 0x80, 0x0, 0x0,
+ 0x0, 0xb, 0xe0, 0x0, 0x0, 0x0, 0x5, 0xf5,
+ 0x0, 0x0, 0x0, 0x0, 0xec, 0x0, 0x0, 0x0,
+ 0x0, 0x8f, 0x20, 0x0, 0x0, 0x0, 0x2f, 0x90,
+ 0x0, 0x0, 0x0, 0xb, 0xe0, 0x0, 0x0, 0x0,
+ 0x3, 0x82,
+
+ /* U+005D "]" */
+ 0xf, 0xff, 0xff, 0x0, 0x88, 0x8d, 0xf0, 0x0,
+ 0x0, 0xbf, 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0,
+ 0xbf, 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0, 0xbf,
+ 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0, 0xbf, 0x0,
+ 0x0, 0xb, 0xf0, 0x0, 0x0, 0xbf, 0x0, 0x0,
+ 0xb, 0xf0, 0x0, 0x0, 0xbf, 0x0, 0x0, 0xb,
+ 0xf0, 0x0, 0x0, 0xbf, 0x0, 0x0, 0xb, 0xf0,
+ 0x0, 0x0, 0xbf, 0x0, 0x88, 0x8d, 0xf0, 0xf,
+ 0xff, 0xff, 0x0,
+
+ /* U+005E "^" */
+ 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0xef,
+ 0x40, 0x0, 0x0, 0x5f, 0x2c, 0xd0, 0x0, 0x0,
+ 0xda, 0x4, 0xf6, 0x0, 0x6, 0xf2, 0x0, 0xbe,
+ 0x0, 0xe, 0x90, 0x0, 0x3f, 0x80, 0x7f, 0x20,
+ 0x0, 0xa, 0xf2,
+
+ /* U+005F "_" */
+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x84, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xf8,
+
+ /* U+0060 "`" */
+ 0x3, 0x24, 0xfa, 0x3f, 0x92, 0xf8, 0x1f, 0x70,
+ 0xf6,
+
+ /* U+0061 "a" */
+ 0x5, 0xbe, 0xfe, 0xb4, 0x0, 0xcf, 0xba, 0xbf,
+ 0xf3, 0x3, 0x0, 0x0, 0x6f, 0xb0, 0x0, 0x0,
+ 0x0, 0xfd, 0x0, 0x0, 0x11, 0x1f, 0xd0, 0x3b,
+ 0xff, 0xff, 0xfd, 0x2f, 0xf8, 0x54, 0x4f, 0xd8,
+ 0xf6, 0x0, 0x0, 0xfd, 0x9f, 0x50, 0x0, 0x9f,
+ 0xd4, 0xff, 0x9a, 0xee, 0xed, 0x6, 0xdf, 0xe9,
+ 0x1c, 0xd0,
+
+ /* U+0062 "b" */
+ 0x5f, 0x60, 0x0, 0x0, 0x0, 0x5f, 0x60, 0x0,
+ 0x0, 0x0, 0x5f, 0x60, 0x0, 0x0, 0x0, 0x5f,
+ 0x60, 0x0, 0x0, 0x0, 0x5f, 0x63, 0xbf, 0xe8,
+ 0x0, 0x5f, 0x9f, 0xea, 0xef, 0x80, 0x5f, 0xfa,
+ 0x0, 0x2f, 0xf0, 0x5f, 0xb0, 0x0, 0xa, 0xf3,
+ 0x5f, 0x60, 0x0, 0x7, 0xf5, 0x5f, 0x60, 0x0,
+ 0x6, 0xf6, 0x5f, 0x60, 0x0, 0x7, 0xf5, 0x5f,
+ 0x60, 0x0, 0xb, 0xf2, 0x5f, 0x60, 0x0, 0x4f,
+ 0xb0, 0x5f, 0xea, 0x8b, 0xfe, 0x20, 0x18, 0xce,
+ 0xfe, 0x91, 0x0,
+
+ /* U+0063 "c" */
+ 0x0, 0x7, 0xdf, 0xfc, 0x60, 0xc, 0xfe, 0xaa,
+ 0xda, 0x9, 0xfa, 0x0, 0x0, 0x10, 0xfe, 0x0,
+ 0x0, 0x0, 0x4f, 0x90, 0x0, 0x0, 0x5, 0xf8,
+ 0x0, 0x0, 0x0, 0x5f, 0x90, 0x0, 0x0, 0x2,
+ 0xfd, 0x0, 0x0, 0x0, 0xc, 0xf8, 0x0, 0x0,
+ 0x10, 0x3f, 0xfe, 0xaa, 0xda, 0x0, 0x29, 0xef,
+ 0xec, 0x50,
+
+ /* U+0064 "d" */
+ 0x0, 0x0, 0x0, 0xf, 0xd0, 0x0, 0x0, 0x0,
+ 0xfd, 0x0, 0x0, 0x0, 0xf, 0xd0, 0x0, 0x0,
+ 0x0, 0xfd, 0x0, 0x4b, 0xff, 0xdf, 0xd0, 0x7f,
+ 0xea, 0x9d, 0xfd, 0x2f, 0xc1, 0x0, 0xf, 0xd9,
+ 0xf4, 0x0, 0x0, 0xfd, 0xcf, 0x0, 0x0, 0xf,
+ 0xdd, 0xf0, 0x0, 0x0, 0xfd, 0xcf, 0x0, 0x0,
+ 0xf, 0xdb, 0xf1, 0x0, 0x4, 0xfd, 0x7f, 0x70,
+ 0x2, 0xef, 0xd1, 0xef, 0x98, 0xfb, 0xcd, 0x2,
+ 0xcf, 0xe7, 0xc, 0xd0,
+
+ /* U+0065 "e" */
+ 0x0, 0x4c, 0xff, 0xb3, 0x0, 0x6, 0xfe, 0x9a,
+ 0xff, 0x30, 0x1f, 0xd1, 0x0, 0x3f, 0xd0, 0x7f,
+ 0x50, 0x0, 0xb, 0xf2, 0xbf, 0x42, 0x22, 0x29,
+ 0xf4, 0xcf, 0xff, 0xff, 0xff, 0xf5, 0xbf, 0x65,
+ 0x55, 0x55, 0x51, 0x9f, 0x40, 0x0, 0x0, 0x0,
+ 0x3f, 0xd1, 0x0, 0x0, 0x0, 0x9, 0xff, 0xa9,
+ 0x9b, 0xb0, 0x0, 0x6c, 0xff, 0xec, 0x70,
+
+ /* U+0066 "f" */
+ 0x0, 0x0, 0x3, 0xbe, 0xfe, 0x90, 0x0, 0x2,
+ 0xff, 0xb9, 0xaa, 0x0, 0x0, 0x9f, 0x60, 0x0,
+ 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0, 0x0, 0x0,
+ 0xdf, 0x0, 0x0, 0x0, 0x0, 0xe, 0xf0, 0x0,
+ 0x0, 0x2f, 0xff, 0xff, 0xff, 0xff, 0x71, 0x99,
+ 0x9f, 0xf9, 0x99, 0x94, 0x0, 0x0, 0xef, 0x0,
+ 0x0, 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0, 0x0,
+ 0x0, 0xef, 0x0, 0x0, 0x0, 0x0, 0xe, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0xef, 0x0, 0x0, 0x0,
+ 0x0, 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xef,
+ 0x0, 0x0, 0x0,
+
+ /* U+0067 "g" */
+ 0x0, 0x7, 0xdf, 0xff, 0xff, 0xb0, 0x9, 0xfc,
+ 0x7a, 0xff, 0xc8, 0x3, 0xfb, 0x0, 0x7, 0xf6,
+ 0x0, 0x6f, 0x70, 0x0, 0x3f, 0x90, 0x4, 0xf9,
+ 0x0, 0x5, 0xf8, 0x0, 0xd, 0xf6, 0x25, 0xef,
+ 0x20, 0x0, 0xef, 0xff, 0xfd, 0x40, 0x0, 0x7f,
+ 0x32, 0x43, 0x0, 0x0, 0x9, 0xf2, 0x0, 0x0,
+ 0x0, 0x0, 0x6f, 0xea, 0xaa, 0x97, 0x10, 0x0,
+ 0xef, 0xff, 0xff, 0xff, 0x30, 0xbf, 0x50, 0x0,
+ 0x18, 0xf9, 0xf, 0xe0, 0x0, 0x0, 0x7f, 0x80,
+ 0xbf, 0xd9, 0x88, 0xbf, 0xe1, 0x0, 0x8d, 0xff,
+ 0xfd, 0x81, 0x0,
+
+ /* U+0068 "h" */
+ 0x5f, 0x60, 0x0, 0x0, 0x5, 0xf6, 0x0, 0x0,
+ 0x0, 0x5f, 0x60, 0x0, 0x0, 0x5, 0xf6, 0x0,
+ 0x0, 0x0, 0x5f, 0x63, 0xcf, 0xd6, 0x5, 0xfa,
+ 0xfd, 0xaf, 0xf5, 0x5f, 0xf9, 0x0, 0x3f, 0xb5,
+ 0xfb, 0x0, 0x0, 0xfd, 0x5f, 0x60, 0x0, 0xe,
+ 0xe5, 0xf6, 0x0, 0x0, 0xee, 0x5f, 0x60, 0x0,
+ 0xe, 0xe5, 0xf6, 0x0, 0x0, 0xee, 0x5f, 0x60,
+ 0x0, 0xe, 0xe5, 0xf6, 0x0, 0x0, 0xee, 0x5f,
+ 0x60, 0x0, 0xe, 0xe0,
+
+ /* U+0069 "i" */
+ 0x0, 0x4, 0xeb, 0x0, 0x0, 0x0, 0x9, 0xff,
+ 0x10, 0x0, 0x0, 0x3, 0xea, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, 0xff, 0x0,
+ 0x0, 0x7, 0x88, 0xef, 0x0, 0x0, 0x0, 0x0,
+ 0xdf, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0,
+ 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0, 0xdf,
+ 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0,
+ 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0,
+ 0x0, 0x29, 0x99, 0xff, 0x99, 0x90, 0x3f, 0xff,
+ 0xff, 0xff, 0xf0,
+
+ /* U+006A "j" */
+ 0x0, 0x0, 0x7, 0xf8, 0x0, 0x0, 0xd, 0xfe,
+ 0x0, 0x0, 0x6, 0xe7, 0x0, 0x0, 0x0, 0x0,
+ 0x3f, 0xff, 0xff, 0xf9, 0x28, 0x88, 0x8a, 0xf9,
+ 0x0, 0x0, 0x3, 0xf9, 0x0, 0x0, 0x3, 0xf9,
+ 0x0, 0x0, 0x3, 0xf9, 0x0, 0x0, 0x3, 0xf9,
+ 0x0, 0x0, 0x3, 0xf9, 0x0, 0x0, 0x3, 0xf9,
+ 0x0, 0x0, 0x3, 0xf9, 0x0, 0x0, 0x3, 0xf9,
+ 0x0, 0x0, 0x3, 0xf9, 0x0, 0x0, 0x5, 0xf7,
+ 0x10, 0x0, 0xc, 0xf3, 0xad, 0xaa, 0xef, 0xa0,
+ 0x5c, 0xff, 0xd7, 0x0,
+
+ /* U+006B "k" */
+ 0x2f, 0xa0, 0x0, 0x0, 0x0, 0x2f, 0xa0, 0x0,
+ 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, 0x0, 0x2f,
+ 0xa0, 0x0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x3f,
+ 0xf3, 0x2f, 0xa0, 0x2, 0xef, 0x30, 0x2f, 0xa0,
+ 0x1e, 0xf4, 0x0, 0x2f, 0xa1, 0xdf, 0x50, 0x0,
+ 0x2f, 0xbc, 0xf5, 0x0, 0x0, 0x2f, 0xce, 0xf3,
+ 0x0, 0x0, 0x2f, 0xa3, 0xfe, 0x10, 0x0, 0x2f,
+ 0xa0, 0x6f, 0xd0, 0x0, 0x2f, 0xa0, 0x9, 0xfb,
+ 0x0, 0x2f, 0xa0, 0x0, 0xcf, 0x90, 0x2f, 0xa0,
+ 0x0, 0x1d, 0xf7,
+
+ /* U+006C "l" */
+ 0xe, 0xff, 0xff, 0x0, 0x0, 0x7, 0x88, 0xef,
+ 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0,
+ 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0,
+ 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0,
+ 0xdf, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0,
+ 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0, 0xdf,
+ 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0,
+ 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0,
+ 0x0, 0x29, 0x99, 0xff, 0x99, 0x90, 0x3f, 0xff,
+ 0xff, 0xff, 0xf0,
+
+ /* U+006D "m" */
+ 0x1f, 0x48, 0xfb, 0x8, 0xfb, 0x1, 0xfa, 0xd8,
+ 0xf9, 0xd8, 0xf6, 0x1f, 0xf3, 0x1f, 0xf4, 0xf,
+ 0x91, 0xfb, 0x0, 0xfc, 0x0, 0xf9, 0x1f, 0x90,
+ 0xf, 0x90, 0xf, 0xa1, 0xf9, 0x0, 0xf9, 0x0,
+ 0xfa, 0x1f, 0x90, 0xf, 0x90, 0xf, 0xa1, 0xf9,
+ 0x0, 0xf9, 0x0, 0xfa, 0x1f, 0x90, 0xf, 0x90,
+ 0xf, 0xa1, 0xf9, 0x0, 0xf9, 0x0, 0xfa, 0x1f,
+ 0x90, 0xf, 0x90, 0xf, 0xa0,
+
+ /* U+006E "n" */
+ 0x5f, 0x44, 0xcf, 0xd7, 0x5, 0xfb, 0xfa, 0x7d,
+ 0xf5, 0x5f, 0xf6, 0x0, 0x2f, 0xb5, 0xf9, 0x0,
+ 0x0, 0xed, 0x5f, 0x60, 0x0, 0xe, 0xe5, 0xf6,
+ 0x0, 0x0, 0xee, 0x5f, 0x60, 0x0, 0xe, 0xe5,
+ 0xf6, 0x0, 0x0, 0xee, 0x5f, 0x60, 0x0, 0xe,
+ 0xe5, 0xf6, 0x0, 0x0, 0xee, 0x5f, 0x60, 0x0,
+ 0xe, 0xe0,
+
+ /* U+006F "o" */
+ 0x0, 0x6, 0xcf, 0xfb, 0x40, 0x0, 0xa, 0xfe,
+ 0xab, 0xff, 0x60, 0x5, 0xfb, 0x0, 0x3, 0xff,
+ 0x10, 0xcf, 0x20, 0x0, 0x9, 0xf5, 0xf, 0xe0,
+ 0x0, 0x0, 0x5f, 0x80, 0xfc, 0x0, 0x0, 0x4,
+ 0xf9, 0xf, 0xe0, 0x0, 0x0, 0x5f, 0x80, 0xdf,
+ 0x20, 0x0, 0x9, 0xf4, 0x7, 0xfa, 0x0, 0x4,
+ 0xfd, 0x0, 0xc, 0xfd, 0xaa, 0xff, 0x30, 0x0,
+ 0x8, 0xdf, 0xea, 0x20, 0x0,
+
+ /* U+0070 "p" */
+ 0x5f, 0x44, 0xcf, 0xe8, 0x0, 0x5f, 0xaf, 0xb7,
+ 0xcf, 0x80, 0x5f, 0xf7, 0x0, 0xe, 0xf0, 0x5f,
+ 0xa0, 0x0, 0x9, 0xf3, 0x5f, 0x60, 0x0, 0x7,
+ 0xf5, 0x5f, 0x60, 0x0, 0x6, 0xf6, 0x5f, 0x60,
+ 0x0, 0x7, 0xf5, 0x5f, 0x60, 0x0, 0xb, 0xf2,
+ 0x5f, 0x60, 0x0, 0x4f, 0xb0, 0x5f, 0xea, 0x8a,
+ 0xfe, 0x20, 0x5f, 0xef, 0xfe, 0x91, 0x0, 0x5f,
+ 0x60, 0x0, 0x0, 0x0, 0x5f, 0x60, 0x0, 0x0,
+ 0x0, 0x5f, 0x60, 0x0, 0x0, 0x0, 0x5f, 0x60,
+ 0x0, 0x0, 0x0,
+
+ /* U+0071 "q" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xbe, 0xfd,
+ 0xbc, 0x7, 0xfe, 0x99, 0xcf, 0xd2, 0xfc, 0x0,
+ 0x0, 0xfd, 0x9f, 0x40, 0x0, 0xf, 0xdc, 0xf0,
+ 0x0, 0x0, 0xfd, 0xdf, 0x0, 0x0, 0xf, 0xdc,
+ 0xf0, 0x0, 0x0, 0xfd, 0xbf, 0x20, 0x0, 0x5f,
+ 0xd7, 0xf9, 0x0, 0x4f, 0xfd, 0x1e, 0xfb, 0xbf,
+ 0x9d, 0xd0, 0x3c, 0xfd, 0x70, 0xed, 0x0, 0x0,
+ 0x0, 0xf, 0xd0, 0x0, 0x0, 0x0, 0xfd, 0x0,
+ 0x0, 0x0, 0xf, 0xd0, 0x0, 0x0, 0x0, 0xfd,
+
+ /* U+0072 "r" */
+ 0xfb, 0x7, 0xdf, 0xc3, 0xf, 0xcb, 0xf8, 0x8f,
+ 0xe1, 0xff, 0xe2, 0x0, 0x8f, 0x5f, 0xf3, 0x0,
+ 0x5, 0xf7, 0xfd, 0x0, 0x0, 0x2, 0x1f, 0xd0,
+ 0x0, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x0, 0xf,
+ 0xd0, 0x0, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x0,
+ 0xf, 0xd0, 0x0, 0x0, 0x0, 0xfd, 0x0, 0x0,
+ 0x0, 0x0,
+
+ /* U+0073 "s" */
+ 0x0, 0x5c, 0xff, 0xec, 0x10, 0x7f, 0xea, 0x9a,
+ 0xd1, 0xe, 0xe0, 0x0, 0x0, 0x0, 0xef, 0x10,
+ 0x0, 0x0, 0x8, 0xff, 0x83, 0x0, 0x0, 0x6,
+ 0xef, 0xfd, 0x50, 0x0, 0x0, 0x39, 0xff, 0x50,
+ 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0x3f,
+ 0xb2, 0xfb, 0xa9, 0xbf, 0xf3, 0x1b, 0xef, 0xfe,
+ 0xa3, 0x0,
+
+ /* U+0074 "t" */
+ 0x0, 0x0, 0x32, 0x0, 0x0, 0x0, 0x7, 0xf5,
+ 0x0, 0x0, 0x0, 0x7, 0xf5, 0x0, 0x0, 0x0,
+ 0x7, 0xf5, 0x0, 0x0, 0x5f, 0xff, 0xff, 0xff,
+ 0xff, 0x39, 0x9c, 0xfb, 0x99, 0x98, 0x0, 0x7,
+ 0xf5, 0x0, 0x0, 0x0, 0x7, 0xf5, 0x0, 0x0,
+ 0x0, 0x7, 0xf5, 0x0, 0x0, 0x0, 0x7, 0xf5,
+ 0x0, 0x0, 0x0, 0x7, 0xf5, 0x0, 0x0, 0x0,
+ 0x6, 0xf5, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0,
+ 0x0, 0x0, 0x0, 0xdf, 0xda, 0xac, 0x0, 0x0,
+ 0x1a, 0xef, 0xfb,
+
+ /* U+0075 "u" */
+ 0x5f, 0x60, 0x0, 0xe, 0xe5, 0xf6, 0x0, 0x0,
+ 0xee, 0x5f, 0x60, 0x0, 0xe, 0xe5, 0xf6, 0x0,
+ 0x0, 0xee, 0x5f, 0x60, 0x0, 0xe, 0xe5, 0xf6,
+ 0x0, 0x0, 0xee, 0x5f, 0x60, 0x0, 0xe, 0xe4,
+ 0xf7, 0x0, 0x1, 0xfe, 0x2f, 0xa0, 0x1, 0xcf,
+ 0xe0, 0xcf, 0x97, 0xdd, 0xde, 0x2, 0xbf, 0xea,
+ 0x1b, 0xe0,
+
+ /* U+0076 "v" */
+ 0x2f, 0xd0, 0x0, 0x0, 0x5f, 0x90, 0xcf, 0x30,
+ 0x0, 0xa, 0xf3, 0x6, 0xf9, 0x0, 0x0, 0xfd,
+ 0x0, 0x1f, 0xe0, 0x0, 0x5f, 0x80, 0x0, 0xaf,
+ 0x40, 0xb, 0xf2, 0x0, 0x5, 0xf9, 0x1, 0xfc,
+ 0x0, 0x0, 0xe, 0xe0, 0x6f, 0x60, 0x0, 0x0,
+ 0x9f, 0x4b, 0xf1, 0x0, 0x0, 0x3, 0xfa, 0xfa,
+ 0x0, 0x0, 0x0, 0xd, 0xff, 0x40, 0x0, 0x0,
+ 0x0, 0x7f, 0xe0, 0x0, 0x0,
+
+ /* U+0077 "w" */
+ 0x8f, 0x20, 0x0, 0x0, 0xa, 0xf1, 0x6f, 0x40,
+ 0x0, 0x0, 0xc, 0xf0, 0x4f, 0x60, 0x3, 0x10,
+ 0xd, 0xd0, 0x2f, 0x80, 0x2f, 0xa0, 0xf, 0xb0,
+ 0xf, 0xa0, 0x6f, 0xf0, 0x1f, 0x90, 0xe, 0xc0,
+ 0xbd, 0xf4, 0x2f, 0x60, 0xc, 0xd0, 0xf6, 0xea,
+ 0x4f, 0x40, 0x9, 0xf5, 0xf1, 0x9f, 0x6f, 0x20,
+ 0x7, 0xfb, 0xc0, 0x4f, 0xcf, 0x0, 0x5, 0xff,
+ 0x70, 0xf, 0xfe, 0x0, 0x3, 0xff, 0x20, 0xa,
+ 0xfc, 0x0,
+
+ /* U+0078 "x" */
+ 0xb, 0xf8, 0x0, 0x0, 0xcf, 0x60, 0x1f, 0xf2,
+ 0x0, 0x6f, 0xb0, 0x0, 0x5f, 0xc0, 0x1e, 0xe1,
+ 0x0, 0x0, 0xaf, 0x6a, 0xf4, 0x0, 0x0, 0x1,
+ 0xef, 0xf9, 0x0, 0x0, 0x0, 0x7, 0xff, 0x10,
+ 0x0, 0x0, 0x1, 0xef, 0xf9, 0x0, 0x0, 0x0,
+ 0xbf, 0x5c, 0xf5, 0x0, 0x0, 0x7f, 0xa0, 0x2f,
+ 0xf2, 0x0, 0x3f, 0xe1, 0x0, 0x7f, 0xc0, 0xd,
+ 0xf5, 0x0, 0x0, 0xcf, 0x80,
+
+ /* U+0079 "y" */
+ 0x2f, 0xe0, 0x0, 0x0, 0x5f, 0x90, 0xbf, 0x40,
+ 0x0, 0xa, 0xf3, 0x5, 0xfa, 0x0, 0x0, 0xfd,
+ 0x0, 0xe, 0xf0, 0x0, 0x6f, 0x80, 0x0, 0x9f,
+ 0x60, 0xb, 0xf2, 0x0, 0x3, 0xfc, 0x1, 0xfc,
+ 0x0, 0x0, 0xc, 0xf2, 0x6f, 0x60, 0x0, 0x0,
+ 0x6f, 0x7c, 0xf0, 0x0, 0x0, 0x1, 0xfd, 0xfa,
+ 0x0, 0x0, 0x0, 0xa, 0xff, 0x40, 0x0, 0x0,
+ 0x0, 0x5f, 0xd0, 0x0, 0x0, 0x0, 0xb, 0xf6,
+ 0x0, 0x0, 0x0, 0x7, 0xfd, 0x0, 0x0, 0x4,
+ 0xad, 0xfe, 0x20, 0x0, 0x0, 0x6f, 0xe9, 0x10,
+ 0x0, 0x0, 0x0,
+
+ /* U+007A "z" */
+ 0x2f, 0xff, 0xff, 0xff, 0xa1, 0x99, 0x99, 0x9d,
+ 0xf8, 0x0, 0x0, 0x3, 0xfd, 0x0, 0x0, 0x0,
+ 0xdf, 0x30, 0x0, 0x0, 0x9f, 0x70, 0x0, 0x0,
+ 0x5f, 0xb0, 0x0, 0x0, 0x1e, 0xe1, 0x0, 0x0,
+ 0xc, 0xf4, 0x0, 0x0, 0x7, 0xf9, 0x0, 0x0,
+ 0x2, 0xff, 0x99, 0x99, 0x99, 0x5f, 0xff, 0xff,
+ 0xff, 0xf0,
+
+ /* U+007B "{" */
+ 0x0, 0x0, 0x2b, 0xef, 0x30, 0x0, 0x1e, 0xfb,
+ 0x81, 0x0, 0x5, 0xf8, 0x0, 0x0, 0x0, 0x7f,
+ 0x30, 0x0, 0x0, 0x7, 0xf3, 0x0, 0x0, 0x0,
+ 0x7f, 0x30, 0x0, 0x0, 0xa, 0xf1, 0x0, 0x2,
+ 0x8b, 0xf8, 0x0, 0x0, 0x5f, 0xfb, 0x20, 0x0,
+ 0x0, 0x4, 0xfd, 0x0, 0x0, 0x0, 0x9, 0xf2,
+ 0x0, 0x0, 0x0, 0x7f, 0x30, 0x0, 0x0, 0x7,
+ 0xf3, 0x0, 0x0, 0x0, 0x7f, 0x30, 0x0, 0x0,
+ 0x7, 0xf3, 0x0, 0x0, 0x0, 0x7f, 0x40, 0x0,
+ 0x0, 0x4, 0xf9, 0x0, 0x0, 0x0, 0xd, 0xfb,
+ 0x81, 0x0, 0x0, 0x1a, 0xef, 0x30,
+
+ /* U+007C "|" */
+ 0x1f, 0x91, 0xf9, 0x1f, 0x91, 0xf9, 0x1f, 0x91,
+ 0xf9, 0x1f, 0x91, 0xf9, 0x1f, 0x91, 0xf9, 0x1f,
+ 0x91, 0xf9, 0x1f, 0x91, 0xf9, 0x1f, 0x91, 0xf9,
+ 0x1f, 0x91, 0xf9, 0x1f, 0x91, 0xf9, 0x1f, 0x91,
+ 0xf9,
+
+ /* U+007D "}" */
+ 0xaf, 0xd7, 0x0, 0x0, 0x59, 0xef, 0x70, 0x0,
+ 0x0, 0x1e, 0xd0, 0x0, 0x0, 0xb, 0xf0, 0x0,
+ 0x0, 0xb, 0xf0, 0x0, 0x0, 0xa, 0xf0, 0x0,
+ 0x0, 0x9, 0xf3, 0x0, 0x0, 0x2, 0xef, 0x97,
+ 0x0, 0x0, 0x5e, 0xfe, 0x0, 0x4, 0xf9, 0x10,
+ 0x0, 0x9, 0xf1, 0x0, 0x0, 0xa, 0xf0, 0x0,
+ 0x0, 0xa, 0xf0, 0x0, 0x0, 0xa, 0xf0, 0x0,
+ 0x0, 0xa, 0xf0, 0x0, 0x0, 0xb, 0xf0, 0x0,
+ 0x0, 0x1f, 0xd0, 0x0, 0x59, 0xef, 0x60, 0x0,
+ 0xaf, 0xd6, 0x0, 0x0,
+
+ /* U+007E "~" */
+ 0x0, 0x7a, 0x70, 0x0, 0x0, 0x10, 0x9f, 0xff,
+ 0xc0, 0x0, 0xcd, 0x1f, 0xb1, 0x8f, 0xb0, 0xf,
+ 0xb3, 0xf6, 0x0, 0x9f, 0xed, 0xf4, 0x16, 0x20,
+ 0x0, 0x7e, 0xe7, 0x0,
+
+ /* U+007F "" */
+
+ /* U+4E2D "ä¸" */
+ 0x0, 0x0, 0x0, 0x0, 0x5, 0x30, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xfa, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f,
+ 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x1, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1f, 0xa0, 0x0, 0x0, 0x0, 0x1,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xf9, 0x1f, 0xc7, 0x77, 0x77, 0x8f, 0xd7, 0x77,
+ 0x77, 0x8f, 0x91, 0xf9, 0x0, 0x0, 0x1, 0xfa,
+ 0x0, 0x0, 0x1, 0xf9, 0x1f, 0x90, 0x0, 0x0,
+ 0x1f, 0xa0, 0x0, 0x0, 0x1f, 0x91, 0xf9, 0x0,
+ 0x0, 0x1, 0xfa, 0x0, 0x0, 0x1, 0xf9, 0x1f,
+ 0x90, 0x0, 0x0, 0x1f, 0xa0, 0x0, 0x0, 0x1f,
+ 0x91, 0xfc, 0x77, 0x77, 0x78, 0xfd, 0x77, 0x77,
+ 0x78, 0xf9, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0x91, 0xfa, 0x0, 0x0, 0x1,
+ 0xfa, 0x0, 0x0, 0x1, 0xf9, 0x5, 0x30, 0x0,
+ 0x0, 0x1f, 0xa0, 0x0, 0x0, 0x5, 0x30, 0x0,
+ 0x0, 0x0, 0x1, 0xfa, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x1f, 0xa0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xfa, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f,
+ 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x1, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1f, 0xa0, 0x0, 0x0, 0x0, 0x0,
+
+ /* U+6587 "æ–‡" */
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x30, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xfd,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x9, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x1e, 0x70, 0x0, 0x0,
+ 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x15, 0x99, 0x9d, 0xf9,
+ 0x99, 0x99, 0x99, 0x9c, 0xfb, 0x99, 0x91, 0x0,
+ 0x0, 0x7f, 0x20, 0x0, 0x0, 0x0, 0xaf, 0x10,
+ 0x0, 0x0, 0x0, 0x3, 0xf6, 0x0, 0x0, 0x0,
+ 0xe, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xc0,
+ 0x0, 0x0, 0x3, 0xf8, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x7f, 0x30, 0x0, 0x0, 0x9f, 0x20, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0xfb, 0x0, 0x0, 0x1f,
+ 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xf5,
+ 0x0, 0xb, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xd, 0xe2, 0x6, 0xf9, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3f, 0xd6, 0xfd, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f,
+ 0xfe, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x1a, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1, 0x8f, 0xfb, 0x5e, 0xfd, 0x60,
+ 0x0, 0x0, 0x0, 0x0, 0x39, 0xff, 0xd5, 0x0,
+ 0x19, 0xff, 0xfa, 0x40, 0x0, 0x28, 0xdf, 0xfd,
+ 0x60, 0x0, 0x0, 0x2, 0x9f, 0xff, 0xfa, 0x5,
+ 0xff, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17,
+ 0xdf, 0x70, 0x5, 0x10, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x30, 0x0
+};
+
+
+static const sgl_font_table_t sgl_ascii_consolas23_tab[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 185, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 0, .adv_w = 185, .box_w = 4, .box_h = 15, .ofs_x = 4, .ofs_y = 0},
+ {.bitmap_index = 30, .adv_w = 185, .box_w = 7, .box_h = 6, .ofs_x = 2, .ofs_y = 9},
+ {.bitmap_index = 51, .adv_w = 185, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 135, .adv_w = 185, .box_w = 10, .box_h = 19, .ofs_x = 1, .ofs_y = -3},
+ {.bitmap_index = 230, .adv_w = 185, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 320, .adv_w = 185, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 410, .adv_w = 185, .box_w = 3, .box_h = 6, .ofs_x = 4, .ofs_y = 9},
+ {.bitmap_index = 419, .adv_w = 185, .box_w = 6, .box_h = 22, .ofs_x = 3, .ofs_y = -5},
+ {.bitmap_index = 485, .adv_w = 185, .box_w = 7, .box_h = 22, .ofs_x = 2, .ofs_y = -5},
+ {.bitmap_index = 562, .adv_w = 185, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = 5},
+ {.bitmap_index = 607, .adv_w = 185, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 668, .adv_w = 185, .box_w = 6, .box_h = 8, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 692, .adv_w = 185, .box_w = 7, .box_h = 2, .ofs_x = 2, .ofs_y = 5},
+ {.bitmap_index = 699, .adv_w = 185, .box_w = 5, .box_h = 4, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 709, .adv_w = 185, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 799, .adv_w = 185, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 876, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 946, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1016, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1086, .adv_w = 185, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1163, .adv_w = 185, .box_w = 9, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1226, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1296, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1366, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1436, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1506, .adv_w = 185, .box_w = 4, .box_h = 11, .ofs_x = 4, .ofs_y = 0},
+ {.bitmap_index = 1528, .adv_w = 185, .box_w = 6, .box_h = 15, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 1573, .adv_w = 185, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = -1},
+ {.bitmap_index = 1632, .adv_w = 185, .box_w = 10, .box_h = 6, .ofs_x = 1, .ofs_y = 3},
+ {.bitmap_index = 1662, .adv_w = 185, .box_w = 9, .box_h = 13, .ofs_x = 2, .ofs_y = -1},
+ {.bitmap_index = 1721, .adv_w = 185, .box_w = 7, .box_h = 15, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 1774, .adv_w = 185, .box_w = 12, .box_h = 19, .ofs_x = 0, .ofs_y = -4},
+ {.bitmap_index = 1888, .adv_w = 185, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1972, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2042, .adv_w = 185, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2119, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2189, .adv_w = 185, .box_w = 8, .box_h = 14, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2245, .adv_w = 185, .box_w = 8, .box_h = 14, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2301, .adv_w = 185, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2378, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2448, .adv_w = 185, .box_w = 9, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2511, .adv_w = 185, .box_w = 8, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2567, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2637, .adv_w = 185, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2700, .adv_w = 185, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2784, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2854, .adv_w = 185, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2931, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3001, .adv_w = 185, .box_w = 12, .box_h = 18, .ofs_x = 0, .ofs_y = -4},
+ {.bitmap_index = 3109, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3179, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3249, .adv_w = 185, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3326, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3396, .adv_w = 185, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3480, .adv_w = 185, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3564, .adv_w = 185, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3648, .adv_w = 185, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3732, .adv_w = 185, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3802, .adv_w = 185, .box_w = 6, .box_h = 19, .ofs_x = 3, .ofs_y = -4},
+ {.bitmap_index = 3859, .adv_w = 185, .box_w = 10, .box_h = 18, .ofs_x = 1, .ofs_y = -3},
+ {.bitmap_index = 3949, .adv_w = 185, .box_w = 7, .box_h = 19, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 4016, .adv_w = 185, .box_w = 10, .box_h = 7, .ofs_x = 1, .ofs_y = 7},
+ {.bitmap_index = 4051, .adv_w = 185, .box_w = 12, .box_h = 2, .ofs_x = 0, .ofs_y = -4},
+ {.bitmap_index = 4063, .adv_w = 86, .box_w = 3, .box_h = 6, .ofs_x = 1, .ofs_y = 12},
+ {.bitmap_index = 4072, .adv_w = 185, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4122, .adv_w = 185, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4197, .adv_w = 185, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4247, .adv_w = 185, .box_w = 9, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4315, .adv_w = 185, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4370, .adv_w = 185, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 4453, .adv_w = 185, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -4},
+ {.bitmap_index = 4536, .adv_w = 185, .box_w = 9, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4604, .adv_w = 185, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4679, .adv_w = 185, .box_w = 8, .box_h = 19, .ofs_x = 1, .ofs_y = -4},
+ {.bitmap_index = 4755, .adv_w = 185, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4830, .adv_w = 185, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4905, .adv_w = 185, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 4966, .adv_w = 185, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5016, .adv_w = 185, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5077, .adv_w = 185, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = -4},
+ {.bitmap_index = 5152, .adv_w = 185, .box_w = 9, .box_h = 16, .ofs_x = 1, .ofs_y = -4},
+ {.bitmap_index = 5224, .adv_w = 185, .box_w = 9, .box_h = 11, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 5274, .adv_w = 185, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5324, .adv_w = 185, .box_w = 10, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5399, .adv_w = 185, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5449, .adv_w = 185, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5510, .adv_w = 185, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5576, .adv_w = 185, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5637, .adv_w = 185, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -4},
+ {.bitmap_index = 5720, .adv_w = 185, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5770, .adv_w = 185, .box_w = 9, .box_h = 19, .ofs_x = 1, .ofs_y = -4},
+ {.bitmap_index = 5856, .adv_w = 185, .box_w = 3, .box_h = 22, .ofs_x = 4, .ofs_y = -4},
+ {.bitmap_index = 5889, .adv_w = 185, .box_w = 8, .box_h = 19, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 5965, .adv_w = 185, .box_w = 11, .box_h = 5, .ofs_x = 0, .ofs_y = 4},
+ {.bitmap_index = 5993, .adv_w = 185, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5993, .adv_w = 336, .box_w = 19, .box_h = 21, .ofs_x = 1, .ofs_y = -3},
+ {.bitmap_index = 6193, .adv_w = 336, .box_w = 21, .box_h = 21, .ofs_x = 0, .ofs_y = -3}
+};
+
+static const uint32_t unicode_list_1[] = {
+ 0x0, 0x175a
+};
+
+static const sgl_font_unicode_t consolas23_unicode[] = {
+ { .offset = 32, .len = 96, .list = NULL, .tab_offset = 1, },
+ { .offset = 20013, .len = 2, .list = unicode_list_1, .tab_offset = 97, },
+};
+
+const sgl_font_t consolas23 = {
+ .bitmap = sgl_ascii_consolas23_bitmap,
+ .table = sgl_ascii_consolas23_tab,
+ .font_table_size = SGL_ARRAY_SIZE(sgl_ascii_consolas23_tab),
+ .font_height = 23,
+ .base_line = 5,
+ .bpp = 4,
+ .unicode = consolas23_unicode,
+ .unicode_num = 2,
+};
+
+
+#endif // !CONFIG_SGL_FONT_CONSOLAS23
diff --git a/User/system/sgl/fonts/sgl_ascii_consolas24.c b/User/system/sgl/fonts/sgl_ascii_consolas24.c
new file mode 100644
index 0000000..308c67c
--- /dev/null
+++ b/User/system/sgl/fonts/sgl_ascii_consolas24.c
@@ -0,0 +1,1239 @@
+/* source/fonts/sgl_ascii_consolas24.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+
+#if (CONFIG_SGL_FONT_CONSOLAS24)
+
+/*-----------------
+ * BITMAPS
+ *----------------*/
+
+/*Store the image of the glyphs*/
+static const uint8_t glyph_bitmap[] = {
+ /* U+0020 " " */
+
+ /* U+0021 "!" */
+ 0x1f, 0xf2, 0x1f, 0xf1, 0xf, 0xf1, 0xf, 0xf0,
+ 0xf, 0xf0, 0xf, 0xf0, 0xe, 0xf0, 0xe, 0xf0,
+ 0xd, 0xe0, 0xd, 0xe0, 0x7, 0x80, 0x0, 0x0,
+ 0xa, 0xa0, 0x5f, 0xf6, 0x1d, 0xd1,
+
+ /* U+0022 "\"" */
+ 0x3f, 0xf1, 0xf, 0xf4, 0x2f, 0xf0, 0xf, 0xf3,
+ 0x1f, 0xf0, 0xe, 0xf2, 0xf, 0xe0, 0xd, 0xf1,
+ 0xf, 0xd0, 0xc, 0xf0, 0x0, 0x0, 0x0, 0x0,
+
+ /* U+0023 "#" */
+ 0x0, 0x4, 0xf4, 0x0, 0xfa, 0x0, 0x0, 0x6,
+ 0xf2, 0x1, 0xf8, 0x0, 0x0, 0x8, 0xf0, 0x3,
+ 0xf6, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xfa,
+ 0x6, 0x6d, 0xe6, 0x6a, 0xf8, 0x64, 0x0, 0xd,
+ 0xc0, 0x7, 0xf1, 0x0, 0x0, 0xe, 0xa0, 0x9,
+ 0xf0, 0x0, 0x0, 0xf, 0x90, 0xa, 0xe0, 0x0,
+ 0x1, 0x2f, 0x91, 0x1c, 0xd1, 0x10, 0x8f, 0xff,
+ 0xff, 0xff, 0xff, 0xf1, 0x24, 0x7f, 0x74, 0x4f,
+ 0xb4, 0x40, 0x0, 0x6f, 0x30, 0xf, 0x80, 0x0,
+ 0x0, 0x7f, 0x10, 0x2f, 0x60, 0x0, 0x0, 0x9f,
+ 0x0, 0x4f, 0x50, 0x0,
+
+ /* U+0024 "$" */
+ 0x0, 0x0, 0xb, 0xd0, 0x0, 0x0, 0x0, 0xd,
+ 0xb0, 0x0, 0x0, 0x7c, 0xff, 0xfd, 0x90, 0xc,
+ 0xfc, 0x9f, 0xcb, 0xb0, 0x7f, 0x90, 0x4f, 0x40,
+ 0x0, 0xaf, 0x50, 0x6f, 0x20, 0x0, 0x8f, 0xb0,
+ 0x8f, 0x0, 0x0, 0x1d, 0xfe, 0xde, 0x0, 0x0,
+ 0x1, 0x9f, 0xff, 0xa2, 0x0, 0x0, 0x1, 0xff,
+ 0xff, 0x70, 0x0, 0x1, 0xf7, 0x5e, 0xf5, 0x0,
+ 0x3, 0xf5, 0x5, 0xfb, 0x0, 0x5, 0xf3, 0x5,
+ 0xfb, 0x53, 0x17, 0xf1, 0x3d, 0xf7, 0xdf, 0xff,
+ 0xff, 0xff, 0xc0, 0x7c, 0xef, 0xff, 0xc7, 0x0,
+ 0x0, 0xd, 0xb0, 0x0, 0x0, 0x0, 0xf, 0x80,
+ 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0,
+
+ /* U+0025 "%" */
+ 0x5, 0xdf, 0xb2, 0x0, 0x3, 0xf8, 0x2f, 0x94,
+ 0xec, 0x0, 0xd, 0xd0, 0x8f, 0x10, 0x7f, 0x10,
+ 0x8f, 0x30, 0x8f, 0x0, 0x7f, 0x13, 0xf9, 0x0,
+ 0x5f, 0x72, 0xdd, 0xd, 0xd0, 0x0, 0xb, 0xff,
+ 0xe3, 0x8f, 0x40, 0x0, 0x0, 0x23, 0x3, 0xf9,
+ 0x0, 0x0, 0x0, 0x0, 0xd, 0xe0, 0x0, 0x0,
+ 0x0, 0x0, 0x8f, 0x40, 0x0, 0x0, 0x0, 0x2,
+ 0xf9, 0x1b, 0xff, 0x90, 0x0, 0xc, 0xe0, 0xaf,
+ 0x68, 0xf6, 0x0, 0x7f, 0x40, 0xf9, 0x0, 0xfa,
+ 0x2, 0xfa, 0x0, 0xf9, 0x0, 0xf9, 0xc, 0xe1,
+ 0x0, 0xbe, 0x48, 0xf4, 0x7f, 0x50, 0x0, 0x1b,
+ 0xfd, 0x60,
+
+ /* U+0026 "&" */
+ 0x0, 0x6, 0xdf, 0xd8, 0x0, 0x0, 0x0, 0x7,
+ 0xfd, 0x9d, 0xf9, 0x0, 0x0, 0x0, 0xff, 0x10,
+ 0x1f, 0xf0, 0x0, 0x0, 0x2f, 0xc0, 0x0, 0xdf,
+ 0x0, 0x0, 0x0, 0xff, 0x0, 0x3f, 0xc0, 0x0,
+ 0x0, 0xb, 0xf8, 0x4e, 0xf3, 0x0, 0x0, 0x0,
+ 0x2f, 0xff, 0xd3, 0x0, 0x0, 0x0, 0x7, 0xff,
+ 0xf2, 0x0, 0x45, 0x0, 0x7, 0xfc, 0x9f, 0xd0,
+ 0xf, 0xf0, 0x1, 0xfe, 0x10, 0xcf, 0xb0, 0xfd,
+ 0x0, 0x4f, 0xa0, 0x1, 0xef, 0xbf, 0x90, 0x5,
+ 0xfa, 0x0, 0x3, 0xff, 0xf3, 0x0, 0x2f, 0xe1,
+ 0x0, 0x9, 0xff, 0x20, 0x0, 0x8f, 0xe8, 0x7b,
+ 0xff, 0xfd, 0x0, 0x0, 0x6d, 0xff, 0xc6, 0xc,
+ 0xfb, 0x0,
+
+ /* U+0027 "'" */
+ 0x2f, 0xf3, 0x1f, 0xf3, 0xf, 0xf2, 0xf, 0xf1,
+ 0xe, 0xf0, 0x0, 0x0,
+
+ /* U+0028 "(" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xa0, 0x0,
+ 0x4, 0xfd, 0x10, 0x2, 0xee, 0x10, 0x0, 0xbf,
+ 0x40, 0x0, 0x5f, 0xa0, 0x0, 0xc, 0xf2, 0x0,
+ 0x2, 0xfc, 0x0, 0x0, 0x7f, 0x70, 0x0, 0xa,
+ 0xf4, 0x0, 0x0, 0xbf, 0x20, 0x0, 0xc, 0xf2,
+ 0x0, 0x0, 0xbf, 0x30, 0x0, 0x9, 0xf6, 0x0,
+ 0x0, 0x5f, 0xa0, 0x0, 0x1, 0xff, 0x0, 0x0,
+ 0x9, 0xf6, 0x0, 0x0, 0x1f, 0xe1, 0x0, 0x0,
+ 0x7f, 0xa0, 0x0, 0x0, 0xbf, 0x70, 0x0, 0x0,
+ 0xcf, 0x10, 0x0, 0x0, 0x30,
+
+ /* U+0029 ")" */
+ 0x0, 0x0, 0x0, 0x0, 0x96, 0x0, 0x0, 0xc,
+ 0xf5, 0x0, 0x0, 0x1e, 0xf3, 0x0, 0x0, 0x3f,
+ 0xd0, 0x0, 0x0, 0x9f, 0x70, 0x0, 0x1, 0xfe,
+ 0x0, 0x0, 0xb, 0xf4, 0x0, 0x0, 0x6f, 0x80,
+ 0x0, 0x3, 0xfb, 0x0, 0x0, 0x1f, 0xd0, 0x0,
+ 0x1, 0xfd, 0x0, 0x0, 0x1f, 0xb0, 0x0, 0x4,
+ 0xfa, 0x0, 0x0, 0x8f, 0x60, 0x0, 0xd, 0xf1,
+ 0x0, 0x4, 0xfa, 0x0, 0x0, 0xdf, 0x20, 0x0,
+ 0x8f, 0x70, 0x0, 0x5f, 0xb0, 0x0, 0xe, 0xc1,
+ 0x0, 0x0, 0x21, 0x0, 0x0,
+
+ /* U+002A "*" */
+ 0x0, 0x0, 0xac, 0x0, 0x0, 0x2, 0x0, 0x9b,
+ 0x0, 0x20, 0xe, 0xa1, 0x8a, 0x1a, 0xf1, 0x4,
+ 0xce, 0xbc, 0xed, 0x50, 0x0, 0x7, 0xff, 0x80,
+ 0x0, 0x2, 0xaf, 0xcd, 0xfb, 0x30, 0x1f, 0xc2,
+ 0x8a, 0x1b, 0xf1, 0x3, 0x0, 0x9b, 0x0, 0x30,
+ 0x0, 0x0, 0xac, 0x0, 0x0, 0x0, 0x0, 0x11,
+ 0x0, 0x0,
+
+ /* U+002B "+" */
+ 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0,
+ 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0,
+ 0xa, 0xaa, 0xaf, 0xfa, 0xaa, 0xa1, 0x1f, 0xff,
+ 0xff, 0xff, 0xff, 0xf3, 0x0, 0x0, 0xe, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0,
+ 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0,
+ 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x50,
+ 0x0, 0x0,
+
+ /* U+002C "," */
+ 0x0, 0x19, 0x70, 0x0, 0x8f, 0xf7, 0x0, 0x5f,
+ 0xfb, 0x0, 0xc, 0xfa, 0x0, 0xc, 0xf6, 0x14,
+ 0xaf, 0xc0, 0x7f, 0xf9, 0x0, 0x23, 0x0, 0x0,
+
+ /* U+002D "-" */
+ 0x1c, 0xcc, 0xcc, 0xc3, 0x2f, 0xff, 0xff, 0xf4,
+
+ /* U+002E "." */
+ 0x7, 0x70, 0x9f, 0xf8, 0xcf, 0xfa, 0x4e, 0xd3,
+
+ /* U+002F "/" */
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0xf8, 0x0, 0x0,
+ 0x0, 0x0, 0xd, 0xd0, 0x0, 0x0, 0x0, 0x0,
+ 0x8f, 0x30, 0x0, 0x0, 0x0, 0x3, 0xf9, 0x0,
+ 0x0, 0x0, 0x0, 0xd, 0xd0, 0x0, 0x0, 0x0,
+ 0x0, 0x8f, 0x40, 0x0, 0x0, 0x0, 0x3, 0xf9,
+ 0x0, 0x0, 0x0, 0x0, 0xd, 0xe0, 0x0, 0x0,
+ 0x0, 0x0, 0x8f, 0x40, 0x0, 0x0, 0x0, 0x2,
+ 0xf9, 0x0, 0x0, 0x0, 0x0, 0xc, 0xe0, 0x0,
+ 0x0, 0x0, 0x0, 0x7f, 0x40, 0x0, 0x0, 0x0,
+ 0x2, 0xfa, 0x0, 0x0, 0x0, 0x0, 0xc, 0xe1,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0x50, 0x0, 0x0,
+ 0x0, 0x0,
+
+ /* U+0030 "0" */
+ 0x0, 0x3, 0xbe, 0xfc, 0x60, 0x0, 0x0, 0x5f,
+ 0xfa, 0xaf, 0xf9, 0x0, 0x1, 0xfe, 0x20, 0x1,
+ 0xef, 0x40, 0x8, 0xf7, 0x0, 0x0, 0x6f, 0xa0,
+ 0xc, 0xf1, 0x0, 0x2, 0xcf, 0xe0, 0xf, 0xf0,
+ 0x0, 0x5e, 0xff, 0xf1, 0xf, 0xd0, 0x9, 0xfd,
+ 0x3c, 0xf2, 0xf, 0xd2, 0xcf, 0x90, 0xc, 0xf2,
+ 0xf, 0xff, 0xe5, 0x0, 0xd, 0xf0, 0xd, 0xfb,
+ 0x10, 0x0, 0xf, 0xe0, 0x9, 0xf7, 0x0, 0x0,
+ 0x5f, 0x90, 0x2, 0xfe, 0x20, 0x1, 0xef, 0x20,
+ 0x0, 0x8f, 0xfa, 0xaf, 0xf7, 0x0, 0x0, 0x5,
+ 0xcf, 0xfc, 0x40, 0x0,
+
+ /* U+0031 "1" */
+ 0x0, 0x4, 0xcf, 0x90, 0x0, 0x3, 0xbf, 0xff,
+ 0x90, 0x0, 0x5f, 0xfa, 0x9f, 0x90, 0x0, 0x1a,
+ 0x20, 0x8f, 0x90, 0x0, 0x0, 0x0, 0x8f, 0x90,
+ 0x0, 0x0, 0x0, 0x8f, 0x90, 0x0, 0x0, 0x0,
+ 0x8f, 0x90, 0x0, 0x0, 0x0, 0x8f, 0x90, 0x0,
+ 0x0, 0x0, 0x8f, 0x90, 0x0, 0x0, 0x0, 0x8f,
+ 0x90, 0x0, 0x0, 0x0, 0x8f, 0x90, 0x0, 0x0,
+ 0x0, 0x8f, 0x90, 0x0, 0x1c, 0xcc, 0xef, 0xec,
+ 0xc8, 0x1f, 0xff, 0xff, 0xff, 0xfb,
+
+ /* U+0032 "2" */
+ 0x0, 0x7d, 0xff, 0xb2, 0x0, 0x1d, 0xfd, 0xbd,
+ 0xff, 0x40, 0xb, 0x60, 0x0, 0x8f, 0xc0, 0x0,
+ 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, 0xf,
+ 0xf0, 0x0, 0x0, 0x0, 0x3f, 0xc0, 0x0, 0x0,
+ 0x0, 0xbf, 0x50, 0x0, 0x0, 0x8, 0xfa, 0x0,
+ 0x0, 0x0, 0x8f, 0xc0, 0x0, 0x0, 0x8, 0xfc,
+ 0x0, 0x0, 0x0, 0x8f, 0xb0, 0x0, 0x0, 0x9,
+ 0xfb, 0x0, 0x0, 0x0, 0x5f, 0xfc, 0xcc, 0xcc,
+ 0xca, 0x6f, 0xff, 0xff, 0xff, 0xfd,
+
+ /* U+0033 "3" */
+ 0x7, 0xce, 0xfe, 0xb3, 0x0, 0xd, 0xdb, 0xad,
+ 0xff, 0x40, 0x0, 0x0, 0x0, 0x7f, 0xc0, 0x0,
+ 0x0, 0x0, 0x2f, 0xd0, 0x0, 0x0, 0x0, 0x4f,
+ 0xa0, 0x0, 0x0, 0x4, 0xee, 0x20, 0x0, 0x8f,
+ 0xff, 0xe3, 0x0, 0x0, 0x48, 0x9b, 0xff, 0x70,
+ 0x0, 0x0, 0x0, 0x1d, 0xf4, 0x0, 0x0, 0x0,
+ 0x7, 0xf8, 0x0, 0x0, 0x0, 0x8, 0xf7, 0x0,
+ 0x0, 0x0, 0x3f, 0xf1, 0x3c, 0xaa, 0xad, 0xff,
+ 0x50, 0x3e, 0xff, 0xfc, 0x81, 0x0,
+
+ /* U+0034 "4" */
+ 0x0, 0x0, 0x0, 0xdf, 0xf2, 0x0, 0x0, 0x0,
+ 0x8, 0xff, 0xf2, 0x0, 0x0, 0x0, 0x2f, 0xcc,
+ 0xf2, 0x0, 0x0, 0x0, 0xcf, 0x2c, 0xf2, 0x0,
+ 0x0, 0x6, 0xf7, 0xc, 0xf2, 0x0, 0x0, 0x1f,
+ 0xc0, 0xc, 0xf2, 0x0, 0x0, 0xbf, 0x30, 0xc,
+ 0xf2, 0x0, 0x5, 0xf8, 0x0, 0xc, 0xf2, 0x0,
+ 0x1e, 0xd0, 0x0, 0xc, 0xf2, 0x0, 0x7f, 0xca,
+ 0xaa, 0xae, 0xfa, 0xa5, 0x8f, 0xff, 0xff, 0xff,
+ 0xff, 0xf8, 0x0, 0x0, 0x0, 0xc, 0xf2, 0x0,
+ 0x0, 0x0, 0x0, 0xc, 0xf2, 0x0, 0x0, 0x0,
+ 0x0, 0xc, 0xf2, 0x0,
+
+ /* U+0035 "5" */
+ 0xd, 0xff, 0xff, 0xff, 0xb0, 0xd, 0xfa, 0xaa,
+ 0xaa, 0x70, 0xd, 0xe0, 0x0, 0x0, 0x0, 0xd,
+ 0xe0, 0x0, 0x0, 0x0, 0xd, 0xe0, 0x0, 0x0,
+ 0x0, 0xd, 0xf9, 0x97, 0x40, 0x0, 0xd, 0xff,
+ 0xff, 0xfe, 0x30, 0x0, 0x0, 0x13, 0xaf, 0xe1,
+ 0x0, 0x0, 0x0, 0xc, 0xf5, 0x0, 0x0, 0x0,
+ 0x9, 0xf6, 0x0, 0x0, 0x0, 0xc, 0xf4, 0x0,
+ 0x0, 0x0, 0x8f, 0xd0, 0x1c, 0xaa, 0xbe, 0xfd,
+ 0x20, 0x1e, 0xff, 0xec, 0x60, 0x0,
+
+ /* U+0036 "6" */
+ 0x0, 0x2, 0x8c, 0xff, 0xe0, 0x0, 0x6f, 0xfd,
+ 0xba, 0x90, 0x4, 0xfd, 0x30, 0x0, 0x0, 0xd,
+ 0xe1, 0x0, 0x0, 0x0, 0x3f, 0x80, 0x0, 0x0,
+ 0x0, 0x7f, 0x89, 0xdf, 0xea, 0x20, 0x9f, 0xfe,
+ 0x98, 0xcf, 0xf2, 0xaf, 0x70, 0x0, 0x8, 0xfa,
+ 0xaf, 0x40, 0x0, 0x1, 0xfe, 0x9f, 0x60, 0x0,
+ 0x0, 0xff, 0x6f, 0x90, 0x0, 0x2, 0xfd, 0x1f,
+ 0xf2, 0x0, 0xa, 0xf7, 0x7, 0xff, 0xa9, 0xdf,
+ 0xb0, 0x0, 0x5c, 0xff, 0xc6, 0x0,
+
+ /* U+0037 "7" */
+ 0xcf, 0xff, 0xff, 0xff, 0xfc, 0x9c, 0xcc, 0xcc,
+ 0xcc, 0xfb, 0x0, 0x0, 0x0, 0x8, 0xf6, 0x0,
+ 0x0, 0x0, 0x1f, 0xe0, 0x0, 0x0, 0x0, 0x8f,
+ 0x60, 0x0, 0x0, 0x1, 0xfe, 0x0, 0x0, 0x0,
+ 0x8, 0xf7, 0x0, 0x0, 0x0, 0x1f, 0xe0, 0x0,
+ 0x0, 0x0, 0x8f, 0x80, 0x0, 0x0, 0x1, 0xff,
+ 0x10, 0x0, 0x0, 0x8, 0xf8, 0x0, 0x0, 0x0,
+ 0x1f, 0xf1, 0x0, 0x0, 0x0, 0x8f, 0x90, 0x0,
+ 0x0, 0x1, 0xff, 0x10, 0x0, 0x0,
+
+ /* U+0038 "8" */
+ 0x0, 0x6c, 0xff, 0xd9, 0x10, 0xa, 0xfd, 0x99,
+ 0xdf, 0xe1, 0x4f, 0xc0, 0x0, 0xa, 0xf6, 0x6f,
+ 0x80, 0x0, 0x7, 0xf7, 0x3f, 0xe1, 0x0, 0xc,
+ 0xf3, 0x9, 0xfe, 0x74, 0xdf, 0x80, 0x0, 0x6f,
+ 0xff, 0xf5, 0x0, 0x1, 0xbf, 0xde, 0xfe, 0x40,
+ 0x1e, 0xf7, 0x0, 0x8f, 0xf3, 0x8f, 0x90, 0x0,
+ 0x8, 0xfa, 0xaf, 0x50, 0x0, 0x4, 0xfc, 0x9f,
+ 0xb0, 0x0, 0x9, 0xf9, 0x2e, 0xfe, 0xaa, 0xdf,
+ 0xe1, 0x1, 0x9d, 0xff, 0xc7, 0x10,
+
+ /* U+0039 "9" */
+ 0x0, 0x6c, 0xff, 0xb4, 0x0, 0xb, 0xfd, 0x9a,
+ 0xef, 0x60, 0x7f, 0xb0, 0x0, 0x1e, 0xf0, 0xcf,
+ 0x30, 0x0, 0x8, 0xf6, 0xef, 0x10, 0x0, 0x4,
+ 0xf9, 0xcf, 0x40, 0x0, 0x3, 0xfb, 0x7f, 0xd3,
+ 0x1, 0x5b, 0xfb, 0xa, 0xff, 0xff, 0xfd, 0xfa,
+ 0x0, 0x37, 0x76, 0x24, 0xf8, 0x0, 0x0, 0x0,
+ 0x8, 0xf4, 0x0, 0x0, 0x0, 0x1e, 0xe0, 0x0,
+ 0x0, 0x4, 0xdf, 0x50, 0xa, 0xab, 0xef, 0xf6,
+ 0x0, 0x1f, 0xfe, 0xc7, 0x10, 0x0,
+
+ /* U+003A ":" */
+ 0x2d, 0xd3, 0x8f, 0xfa, 0x4f, 0xf6, 0x2, 0x30,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x20,
+ 0x4f, 0xf5, 0x8f, 0xfa, 0x2d, 0xe3,
+
+ /* U+003B ";" */
+ 0x0, 0x2d, 0xd3, 0x0, 0x8f, 0xfa, 0x0, 0x4f,
+ 0xf6, 0x0, 0x2, 0x30, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x70,
+ 0x0, 0x6f, 0xf8, 0x0, 0x3f, 0xfd, 0x0, 0xa,
+ 0xfc, 0x0, 0x9, 0xf8, 0x3, 0x8f, 0xe1, 0x5f,
+ 0xfa, 0x10, 0x14, 0x10, 0x0,
+
+ /* U+003C "<" */
+ 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x2d,
+ 0xf8, 0x0, 0x0, 0x3e, 0xf6, 0x0, 0x0, 0x6f,
+ 0xe4, 0x0, 0x0, 0x8f, 0xd2, 0x0, 0x0, 0xbf,
+ 0xb0, 0x0, 0x0, 0x2e, 0xf7, 0x0, 0x0, 0x0,
+ 0x1c, 0xfa, 0x0, 0x0, 0x0, 0xa, 0xfc, 0x10,
+ 0x0, 0x0, 0x8, 0xfe, 0x30, 0x0, 0x0, 0x5,
+ 0xff, 0x50, 0x0, 0x0, 0x3, 0xe5, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+
+ /* U+003D "=" */
+ 0x59, 0x99, 0x99, 0x99, 0x96, 0x9f, 0xff, 0xff,
+ 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x59, 0x99, 0x99, 0x99,
+ 0x96, 0x9f, 0xff, 0xff, 0xff, 0xfa,
+
+ /* U+003E ">" */
+ 0x1a, 0x10, 0x0, 0x0, 0x6, 0xfe, 0x20, 0x0,
+ 0x0, 0x5, 0xff, 0x40, 0x0, 0x0, 0x3, 0xef,
+ 0x70, 0x0, 0x0, 0x1, 0xcf, 0xa0, 0x0, 0x0,
+ 0x0, 0xaf, 0xc1, 0x0, 0x0, 0x5, 0xfe, 0x30,
+ 0x0, 0x8, 0xfd, 0x20, 0x0, 0xb, 0xfb, 0x10,
+ 0x0, 0x2d, 0xf9, 0x0, 0x0, 0x3e, 0xf6, 0x0,
+ 0x0, 0x4, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+
+ /* U+003F "?" */
+ 0xbe, 0xc7, 0x10, 0x8, 0xdf, 0xfe, 0x40, 0x0,
+ 0x17, 0xff, 0x20, 0x0, 0x8, 0xfa, 0x0, 0x0,
+ 0x2f, 0xd0, 0x0, 0x3, 0xfc, 0x1, 0x14, 0xcf,
+ 0x80, 0xaf, 0xff, 0xa0, 0xa, 0xf5, 0x10, 0x0,
+ 0x9f, 0x10, 0x0, 0x7, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x8, 0xc2, 0x0, 0x1, 0xff, 0x90,
+ 0x0, 0xb, 0xe4, 0x0, 0x0,
+
+ /* U+0040 "@" */
+ 0x0, 0x0, 0x4b, 0xff, 0xb4, 0x0, 0x0, 0x9,
+ 0xfb, 0x56, 0xcf, 0x50, 0x0, 0x7f, 0x60, 0x0,
+ 0xb, 0xe0, 0x2, 0xf9, 0x0, 0x0, 0x2, 0xf6,
+ 0x9, 0xf1, 0x0, 0x10, 0x0, 0xea, 0xf, 0x90,
+ 0x2d, 0xfe, 0xf2, 0xbd, 0x4f, 0x40, 0xdd, 0x5d,
+ 0xf0, 0x9e, 0x8f, 0x6, 0xf5, 0xd, 0xd0, 0x9f,
+ 0xbd, 0xa, 0xf0, 0xf, 0xa0, 0x9e, 0xcc, 0xd,
+ 0xd0, 0x2f, 0x80, 0xad, 0xda, 0xf, 0xb0, 0x4f,
+ 0x60, 0xcb, 0xda, 0xf, 0xc0, 0x7f, 0x40, 0xf7,
+ 0xdb, 0xd, 0xe3, 0xef, 0x78, 0xf2, 0xbd, 0x6,
+ 0xff, 0x8b, 0xff, 0x70, 0x8f, 0x0, 0x23, 0x0,
+ 0x42, 0x0, 0x4f, 0x60, 0x0, 0x0, 0x0, 0x0,
+ 0xd, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x3, 0xfe,
+ 0x85, 0x68, 0xe1, 0x0, 0x0, 0x2a, 0xef, 0xeb,
+ 0x60, 0x0,
+
+ /* U+0041 "A" */
+ 0x0, 0x0, 0x6f, 0xf8, 0x0, 0x0, 0x0, 0x0,
+ 0xbf, 0xfe, 0x0, 0x0, 0x0, 0x1, 0xfc, 0xcf,
+ 0x30, 0x0, 0x0, 0x6, 0xf7, 0x7f, 0x80, 0x0,
+ 0x0, 0xb, 0xf2, 0x2f, 0xd0, 0x0, 0x0, 0x1f,
+ 0xd0, 0xd, 0xf3, 0x0, 0x0, 0x6f, 0x80, 0x8,
+ 0xf8, 0x0, 0x0, 0xbf, 0x20, 0x3, 0xfd, 0x0,
+ 0x1, 0xfd, 0x0, 0x0, 0xdf, 0x20, 0x6, 0xfe,
+ 0xbb, 0xbb, 0xef, 0x80, 0xb, 0xff, 0xff, 0xff,
+ 0xff, 0xd0, 0x1f, 0xe0, 0x0, 0x0, 0xe, 0xf2,
+ 0x6f, 0x90, 0x0, 0x0, 0x9, 0xf7, 0xbf, 0x40,
+ 0x0, 0x0, 0x4, 0xfd,
+
+ /* U+0042 "B" */
+ 0x4f, 0xff, 0xff, 0xd8, 0x0, 0x4f, 0xd9, 0x9b,
+ 0xff, 0xc0, 0x4f, 0x90, 0x0, 0x1e, 0xf4, 0x4f,
+ 0x90, 0x0, 0xa, 0xf6, 0x4f, 0x90, 0x0, 0xc,
+ 0xf3, 0x4f, 0x90, 0x2, 0x9f, 0xb0, 0x4f, 0xff,
+ 0xff, 0xfa, 0x0, 0x4f, 0xd9, 0x9b, 0xff, 0xc1,
+ 0x4f, 0x90, 0x0, 0xb, 0xf9, 0x4f, 0x90, 0x0,
+ 0x3, 0xfd, 0x4f, 0x90, 0x0, 0x3, 0xfd, 0x4f,
+ 0x90, 0x0, 0xb, 0xf8, 0x4f, 0xd9, 0x9b, 0xef,
+ 0xc0, 0x4f, 0xff, 0xfe, 0xb6, 0x0,
+
+ /* U+0043 "C" */
+ 0x0, 0x0, 0x6c, 0xef, 0xeb, 0x40, 0x1, 0xcf,
+ 0xfc, 0xbd, 0xfb, 0x0, 0xbf, 0xb1, 0x0, 0x1,
+ 0x40, 0x4f, 0xd0, 0x0, 0x0, 0x0, 0xa, 0xf6,
+ 0x0, 0x0, 0x0, 0x0, 0xdf, 0x20, 0x0, 0x0,
+ 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xff,
+ 0x0, 0x0, 0x0, 0x0, 0xe, 0xf2, 0x0, 0x0,
+ 0x0, 0x0, 0xcf, 0x60, 0x0, 0x0, 0x0, 0x7,
+ 0xfc, 0x0, 0x0, 0x0, 0x0, 0x1e, 0xfa, 0x10,
+ 0x0, 0x13, 0x0, 0x3e, 0xff, 0xcb, 0xdf, 0xb0,
+ 0x0, 0x18, 0xdf, 0xfd, 0xa4,
+
+ /* U+0044 "D" */
+ 0xdf, 0xff, 0xfd, 0x92, 0x0, 0xd, 0xfa, 0x9a,
+ 0xdf, 0xf7, 0x0, 0xdf, 0x10, 0x0, 0x4f, 0xf4,
+ 0xd, 0xf1, 0x0, 0x0, 0x6f, 0xc0, 0xdf, 0x10,
+ 0x0, 0x0, 0xff, 0xd, 0xf1, 0x0, 0x0, 0xc,
+ 0xf3, 0xdf, 0x10, 0x0, 0x0, 0xbf, 0x4d, 0xf1,
+ 0x0, 0x0, 0xb, 0xf4, 0xdf, 0x10, 0x0, 0x0,
+ 0xdf, 0x2d, 0xf1, 0x0, 0x0, 0x1f, 0xe0, 0xdf,
+ 0x10, 0x0, 0x8, 0xf9, 0xd, 0xf1, 0x0, 0x8,
+ 0xfe, 0x10, 0xdf, 0xaa, 0xbf, 0xfe, 0x20, 0xd,
+ 0xff, 0xfe, 0xb7, 0x0, 0x0,
+
+ /* U+0045 "E" */
+ 0xdf, 0xff, 0xff, 0xff, 0x2d, 0xfa, 0x99, 0x99,
+ 0x91, 0xdf, 0x10, 0x0, 0x0, 0xd, 0xf1, 0x0,
+ 0x0, 0x0, 0xdf, 0x10, 0x0, 0x0, 0xd, 0xf1,
+ 0x0, 0x0, 0x0, 0xdf, 0xff, 0xff, 0xfe, 0xd,
+ 0xfa, 0xaa, 0xaa, 0x90, 0xdf, 0x10, 0x0, 0x0,
+ 0xd, 0xf1, 0x0, 0x0, 0x0, 0xdf, 0x10, 0x0,
+ 0x0, 0xd, 0xf1, 0x0, 0x0, 0x0, 0xdf, 0xaa,
+ 0xaa, 0xaa, 0x1d, 0xff, 0xff, 0xff, 0xf2,
+
+ /* U+0046 "F" */
+ 0xcf, 0xff, 0xff, 0xff, 0x2c, 0xfb, 0xaa, 0xaa,
+ 0xa1, 0xcf, 0x20, 0x0, 0x0, 0xc, 0xf2, 0x0,
+ 0x0, 0x0, 0xcf, 0x20, 0x0, 0x0, 0xc, 0xf2,
+ 0x0, 0x0, 0x0, 0xcf, 0xff, 0xff, 0xfd, 0xc,
+ 0xfa, 0x99, 0x99, 0x70, 0xcf, 0x20, 0x0, 0x0,
+ 0xc, 0xf2, 0x0, 0x0, 0x0, 0xcf, 0x20, 0x0,
+ 0x0, 0xc, 0xf2, 0x0, 0x0, 0x0, 0xcf, 0x20,
+ 0x0, 0x0, 0xc, 0xf2, 0x0, 0x0, 0x0,
+
+ /* U+0047 "G" */
+ 0x0, 0x0, 0x6c, 0xef, 0xeb, 0x50, 0x2, 0xdf,
+ 0xfd, 0xbd, 0xfd, 0x0, 0xdf, 0xa1, 0x0, 0x1,
+ 0x50, 0x8f, 0xb0, 0x0, 0x0, 0x0, 0xe, 0xf2,
+ 0x0, 0x0, 0x0, 0x2, 0xfd, 0x0, 0x0, 0x0,
+ 0x0, 0x3f, 0xb0, 0x0, 0xef, 0xff, 0xe4, 0xfc,
+ 0x0, 0x8, 0x99, 0xfe, 0x3f, 0xd0, 0x0, 0x0,
+ 0xf, 0xe0, 0xff, 0x10, 0x0, 0x0, 0xfe, 0xb,
+ 0xf8, 0x0, 0x0, 0xf, 0xe0, 0x3f, 0xf7, 0x0,
+ 0x0, 0xfe, 0x0, 0x5f, 0xff, 0xcb, 0xdf, 0xe0,
+ 0x0, 0x29, 0xdf, 0xfd, 0xa4,
+
+ /* U+0048 "H" */
+ 0xdf, 0x10, 0x0, 0x0, 0xfe, 0xdf, 0x10, 0x0,
+ 0x0, 0xfe, 0xdf, 0x10, 0x0, 0x0, 0xfe, 0xdf,
+ 0x10, 0x0, 0x0, 0xfe, 0xdf, 0x10, 0x0, 0x0,
+ 0xfe, 0xdf, 0x10, 0x0, 0x0, 0xfe, 0xdf, 0xff,
+ 0xff, 0xff, 0xfe, 0xdf, 0xba, 0xaa, 0xaa, 0xfe,
+ 0xdf, 0x10, 0x0, 0x0, 0xfe, 0xdf, 0x10, 0x0,
+ 0x0, 0xfe, 0xdf, 0x10, 0x0, 0x0, 0xfe, 0xdf,
+ 0x10, 0x0, 0x0, 0xfe, 0xdf, 0x10, 0x0, 0x0,
+ 0xfe, 0xdf, 0x10, 0x0, 0x0, 0xfe,
+
+ /* U+0049 "I" */
+ 0x2f, 0xff, 0xff, 0xff, 0xf4, 0x19, 0x99, 0xff,
+ 0x99, 0x92, 0x0, 0x0, 0xef, 0x0, 0x0, 0x0,
+ 0x0, 0xef, 0x0, 0x0, 0x0, 0x0, 0xef, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0x0, 0x0, 0x0, 0x0,
+ 0xef, 0x0, 0x0, 0x0, 0x0, 0xef, 0x0, 0x0,
+ 0x0, 0x0, 0xef, 0x0, 0x0, 0x0, 0x0, 0xef,
+ 0x0, 0x0, 0x0, 0x0, 0xef, 0x0, 0x0, 0x0,
+ 0x0, 0xef, 0x0, 0x0, 0x1a, 0xaa, 0xff, 0xaa,
+ 0xa2, 0x2f, 0xff, 0xff, 0xff, 0xf4,
+
+ /* U+004A "J" */
+ 0xd, 0xff, 0xff, 0xff, 0x60, 0x9a, 0xaa, 0xad,
+ 0xf6, 0x0, 0x0, 0x0, 0x8f, 0x60, 0x0, 0x0,
+ 0x8, 0xf6, 0x0, 0x0, 0x0, 0x8f, 0x60, 0x0,
+ 0x0, 0x8, 0xf6, 0x0, 0x0, 0x0, 0x8f, 0x60,
+ 0x0, 0x0, 0x8, 0xf6, 0x0, 0x0, 0x0, 0x8f,
+ 0x60, 0x0, 0x0, 0x8, 0xf6, 0x0, 0x0, 0x0,
+ 0xaf, 0x50, 0x60, 0x0, 0x2f, 0xf1, 0xf, 0xeb,
+ 0xbf, 0xf7, 0x0, 0x7c, 0xff, 0xc5, 0x0,
+
+ /* U+004B "K" */
+ 0x5f, 0x90, 0x0, 0xa, 0xf9, 0x5, 0xf9, 0x0,
+ 0x7, 0xfb, 0x0, 0x5f, 0x90, 0x4, 0xfd, 0x10,
+ 0x5, 0xf9, 0x1, 0xee, 0x20, 0x0, 0x5f, 0x90,
+ 0xcf, 0x40, 0x0, 0x5, 0xf9, 0x9f, 0x60, 0x0,
+ 0x0, 0x5f, 0xef, 0xa0, 0x0, 0x0, 0x5, 0xfc,
+ 0xff, 0x20, 0x0, 0x0, 0x5f, 0x95, 0xfd, 0x0,
+ 0x0, 0x5, 0xf9, 0x9, 0xfb, 0x0, 0x0, 0x5f,
+ 0x90, 0xc, 0xf7, 0x0, 0x5, 0xf9, 0x0, 0x2e,
+ 0xf4, 0x0, 0x5f, 0x90, 0x0, 0x4f, 0xe2, 0x5,
+ 0xf9, 0x0, 0x0, 0x8f, 0xd0,
+
+ /* U+004C "L" */
+ 0x8f, 0x70, 0x0, 0x0, 0x8, 0xf7, 0x0, 0x0,
+ 0x0, 0x8f, 0x70, 0x0, 0x0, 0x8, 0xf7, 0x0,
+ 0x0, 0x0, 0x8f, 0x70, 0x0, 0x0, 0x8, 0xf7,
+ 0x0, 0x0, 0x0, 0x8f, 0x70, 0x0, 0x0, 0x8,
+ 0xf7, 0x0, 0x0, 0x0, 0x8f, 0x70, 0x0, 0x0,
+ 0x8, 0xf7, 0x0, 0x0, 0x0, 0x8f, 0x70, 0x0,
+ 0x0, 0x8, 0xf7, 0x0, 0x0, 0x0, 0x8f, 0xca,
+ 0xaa, 0xaa, 0x58, 0xff, 0xff, 0xff, 0xf9,
+
+ /* U+004D "M" */
+ 0xc, 0xfa, 0x0, 0x0, 0xaf, 0xe0, 0xd, 0xff,
+ 0x0, 0x0, 0xff, 0xf0, 0xe, 0xdf, 0x60, 0x6,
+ 0xfc, 0xf0, 0xf, 0x9e, 0xb0, 0xc, 0xca, 0xf0,
+ 0xf, 0x99, 0xf1, 0x2f, 0x69, 0xf1, 0xf, 0x93,
+ 0xf7, 0x7f, 0x19, 0xf2, 0x1f, 0x80, 0xdc, 0xda,
+ 0x8, 0xf3, 0x2f, 0x80, 0x7f, 0xf4, 0x8, 0xf3,
+ 0x3f, 0x70, 0x1f, 0xe0, 0x7, 0xf4, 0x4f, 0x70,
+ 0x5, 0x40, 0x7, 0xf5, 0x4f, 0x60, 0x0, 0x0,
+ 0x6, 0xf6, 0x5f, 0x60, 0x0, 0x0, 0x6, 0xf7,
+ 0x6f, 0x50, 0x0, 0x0, 0x5, 0xf7, 0x7f, 0x50,
+ 0x0, 0x0, 0x5, 0xf8,
+
+ /* U+004E "N" */
+ 0xbf, 0xe0, 0x0, 0x0, 0xfd, 0xbf, 0xf7, 0x0,
+ 0x0, 0xfd, 0xbf, 0xfe, 0x0, 0x0, 0xfd, 0xbf,
+ 0x9f, 0x60, 0x0, 0xfd, 0xbf, 0x2f, 0xd0, 0x0,
+ 0xfd, 0xbf, 0x1a, 0xf5, 0x0, 0xfd, 0xbf, 0x12,
+ 0xfc, 0x0, 0xfd, 0xbf, 0x10, 0xbf, 0x40, 0xfd,
+ 0xbf, 0x10, 0x3f, 0xb0, 0xfd, 0xbf, 0x10, 0xc,
+ 0xf2, 0xfd, 0xbf, 0x10, 0x4, 0xf9, 0xfd, 0xbf,
+ 0x10, 0x0, 0xdf, 0xfd, 0xbf, 0x10, 0x0, 0x5f,
+ 0xfd, 0xbf, 0x10, 0x0, 0xd, 0xfd,
+
+ /* U+004F "O" */
+ 0x0, 0x4, 0xbe, 0xfd, 0x70, 0x0, 0x0, 0x7f,
+ 0xfb, 0xbf, 0xfc, 0x0, 0x4, 0xfe, 0x20, 0x1,
+ 0xcf, 0x80, 0xc, 0xf5, 0x0, 0x0, 0x2f, 0xf0,
+ 0x1f, 0xe0, 0x0, 0x0, 0xc, 0xf4, 0x4f, 0xb0,
+ 0x0, 0x0, 0x9, 0xf6, 0x5f, 0xa0, 0x0, 0x0,
+ 0x8, 0xf7, 0x5f, 0xa0, 0x0, 0x0, 0x8, 0xf7,
+ 0x4f, 0xb0, 0x0, 0x0, 0xa, 0xf6, 0x2f, 0xe0,
+ 0x0, 0x0, 0xd, 0xf2, 0xe, 0xf3, 0x0, 0x0,
+ 0x3f, 0xd0, 0x7, 0xfd, 0x10, 0x1, 0xdf, 0x60,
+ 0x0, 0xbf, 0xfb, 0xbf, 0xf9, 0x0, 0x0, 0x7,
+ 0xdf, 0xfc, 0x50, 0x0,
+
+ /* U+0050 "P" */
+ 0x4f, 0xff, 0xfe, 0xc7, 0x0, 0x4f, 0xd9, 0x9b,
+ 0xff, 0xc0, 0x4f, 0x90, 0x0, 0x1c, 0xf8, 0x4f,
+ 0x90, 0x0, 0x4, 0xfd, 0x4f, 0x90, 0x0, 0x2,
+ 0xfe, 0x4f, 0x90, 0x0, 0x4, 0xfb, 0x4f, 0x90,
+ 0x0, 0x2d, 0xf5, 0x4f, 0xda, 0xac, 0xff, 0x80,
+ 0x4f, 0xff, 0xfe, 0xb4, 0x0, 0x4f, 0x90, 0x0,
+ 0x0, 0x0, 0x4f, 0x90, 0x0, 0x0, 0x0, 0x4f,
+ 0x90, 0x0, 0x0, 0x0, 0x4f, 0x90, 0x0, 0x0,
+ 0x0, 0x4f, 0x90, 0x0, 0x0, 0x0,
+
+ /* U+0051 "Q" */
+ 0x0, 0x4, 0xbe, 0xfd, 0x70, 0x0, 0x0, 0x7,
+ 0xff, 0xcc, 0xff, 0xc0, 0x0, 0x3, 0xfe, 0x30,
+ 0x1, 0xdf, 0x80, 0x0, 0xbf, 0x50, 0x0, 0x2,
+ 0xff, 0x0, 0xf, 0xe0, 0x0, 0x0, 0xc, 0xf3,
+ 0x4, 0xfb, 0x0, 0x0, 0x0, 0xaf, 0x60, 0x5f,
+ 0xa0, 0x0, 0x0, 0x8, 0xf7, 0x6, 0xfa, 0x0,
+ 0x0, 0x0, 0x8f, 0x70, 0x5f, 0xb0, 0x0, 0x0,
+ 0x9, 0xf6, 0x3, 0xfd, 0x0, 0x0, 0x0, 0xcf,
+ 0x30, 0xf, 0xf2, 0x0, 0x0, 0x1f, 0xe0, 0x0,
+ 0x9f, 0xa0, 0x0, 0xa, 0xf8, 0x0, 0x1, 0xef,
+ 0xc6, 0x6b, 0xfd, 0x0, 0x0, 0x2, 0xcf, 0xff,
+ 0xfa, 0x10, 0x0, 0x0, 0x0, 0x2e, 0xe1, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xbf, 0x50, 0x0, 0x20,
+ 0x0, 0x0, 0x3, 0xff, 0xcb, 0xec, 0x0, 0x0,
+ 0x0, 0x3, 0xbe, 0xec, 0x50,
+
+ /* U+0052 "R" */
+ 0x2f, 0xff, 0xff, 0xc6, 0x0, 0x2, 0xfe, 0x99,
+ 0xbf, 0xf9, 0x0, 0x2f, 0xb0, 0x0, 0x3f, 0xf1,
+ 0x2, 0xfb, 0x0, 0x0, 0xdf, 0x30, 0x2f, 0xb0,
+ 0x0, 0xe, 0xf1, 0x2, 0xfb, 0x0, 0x2b, 0xf9,
+ 0x0, 0x2f, 0xff, 0xff, 0xf8, 0x0, 0x2, 0xfe,
+ 0x8b, 0xfc, 0x10, 0x0, 0x2f, 0xb0, 0x7, 0xfa,
+ 0x0, 0x2, 0xfb, 0x0, 0xe, 0xf2, 0x0, 0x2f,
+ 0xb0, 0x0, 0x7f, 0xa0, 0x2, 0xfb, 0x0, 0x0,
+ 0xff, 0x20, 0x2f, 0xb0, 0x0, 0x8, 0xf9, 0x2,
+ 0xfb, 0x0, 0x0, 0x1f, 0xf1,
+
+ /* U+0053 "S" */
+ 0x0, 0x5b, 0xef, 0xfd, 0x80, 0xb, 0xff, 0xca,
+ 0xbd, 0xc0, 0x5f, 0xc1, 0x0, 0x0, 0x0, 0x9f,
+ 0x60, 0x0, 0x0, 0x0, 0x8f, 0xb0, 0x0, 0x0,
+ 0x0, 0x1e, 0xfc, 0x40, 0x0, 0x0, 0x2, 0xcf,
+ 0xfd, 0x60, 0x0, 0x0, 0x3, 0xaf, 0xfe, 0x40,
+ 0x0, 0x0, 0x1, 0x8f, 0xf3, 0x0, 0x0, 0x0,
+ 0x8, 0xf9, 0x0, 0x0, 0x0, 0x5, 0xfa, 0x20,
+ 0x0, 0x0, 0x1c, 0xf6, 0xdf, 0xcb, 0xbc, 0xff,
+ 0xb0, 0x8c, 0xef, 0xfd, 0xb6, 0x0,
+
+ /* U+0054 "T" */
+ 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xa, 0xaa,
+ 0xaf, 0xfa, 0xaa, 0xa1, 0x0, 0x0, 0xe, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0,
+ 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0,
+ 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0,
+ 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0,
+ 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0,
+ 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0,
+ 0xe, 0xf0, 0x0, 0x0,
+
+ /* U+0055 "U" */
+ 0xdf, 0x10, 0x0, 0x0, 0xff, 0xdf, 0x10, 0x0,
+ 0x0, 0xff, 0xdf, 0x10, 0x0, 0x0, 0xff, 0xdf,
+ 0x10, 0x0, 0x0, 0xff, 0xdf, 0x10, 0x0, 0x0,
+ 0xff, 0xdf, 0x10, 0x0, 0x0, 0xff, 0xdf, 0x10,
+ 0x0, 0x0, 0xff, 0xdf, 0x10, 0x0, 0x0, 0xff,
+ 0xdf, 0x10, 0x0, 0x0, 0xff, 0xdf, 0x10, 0x0,
+ 0x0, 0xfe, 0xbf, 0x40, 0x0, 0x3, 0xfc, 0x7f,
+ 0xb0, 0x0, 0xb, 0xf6, 0xd, 0xfe, 0xaa, 0xef,
+ 0xb0, 0x1, 0x8d, 0xff, 0xc7, 0x0,
+
+ /* U+0056 "V" */
+ 0xcf, 0x50, 0x0, 0x0, 0x2, 0xfd, 0x7, 0xfa,
+ 0x0, 0x0, 0x0, 0x7f, 0x80, 0x2f, 0xf0, 0x0,
+ 0x0, 0xc, 0xf3, 0x0, 0xcf, 0x50, 0x0, 0x1,
+ 0xfd, 0x0, 0x7, 0xfa, 0x0, 0x0, 0x7f, 0x80,
+ 0x0, 0x2f, 0xf0, 0x0, 0xc, 0xf2, 0x0, 0x0,
+ 0xcf, 0x40, 0x1, 0xfd, 0x0, 0x0, 0x7, 0xf9,
+ 0x0, 0x6f, 0x70, 0x0, 0x0, 0x2f, 0xe0, 0xb,
+ 0xf2, 0x0, 0x0, 0x0, 0xcf, 0x31, 0xfc, 0x0,
+ 0x0, 0x0, 0x7, 0xf8, 0x5f, 0x70, 0x0, 0x0,
+ 0x0, 0x2f, 0xda, 0xf2, 0x0, 0x0, 0x0, 0x0,
+ 0xcf, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff,
+ 0x70, 0x0, 0x0,
+
+ /* U+0057 "W" */
+ 0x7f, 0x40, 0x0, 0x0, 0x2, 0xf9, 0x6f, 0x50,
+ 0x0, 0x0, 0x2, 0xf8, 0x5f, 0x60, 0x0, 0x0,
+ 0x3, 0xf7, 0x4f, 0x70, 0x0, 0x0, 0x4, 0xf5,
+ 0x3f, 0x80, 0x2, 0x30, 0x5, 0xf4, 0x2f, 0x90,
+ 0xd, 0xe0, 0x6, 0xf3, 0x1f, 0xa0, 0x3f, 0xf4,
+ 0x7, 0xf2, 0xf, 0xb0, 0x8e, 0xfa, 0x8, 0xf1,
+ 0xe, 0xc0, 0xda, 0xbf, 0x9, 0xf0, 0xd, 0xd2,
+ 0xf5, 0x6f, 0x59, 0xf0, 0xc, 0xe8, 0xf0, 0x1f,
+ 0xba, 0xe0, 0xb, 0xfc, 0xa0, 0xb, 0xfc, 0xd0,
+ 0xa, 0xff, 0x50, 0x5, 0xff, 0xc0, 0x9, 0xff,
+ 0x0, 0x0, 0xff, 0xb0,
+
+ /* U+0058 "X" */
+ 0x2f, 0xf2, 0x0, 0x0, 0x1e, 0xf2, 0x7, 0xfc,
+ 0x0, 0x0, 0xaf, 0x80, 0x0, 0xdf, 0x50, 0x4,
+ 0xfd, 0x0, 0x0, 0x3f, 0xe0, 0xd, 0xf4, 0x0,
+ 0x0, 0x9, 0xf9, 0x7f, 0x90, 0x0, 0x0, 0x1,
+ 0xef, 0xfe, 0x10, 0x0, 0x0, 0x0, 0x5f, 0xf5,
+ 0x0, 0x0, 0x0, 0x0, 0x9f, 0xfa, 0x0, 0x0,
+ 0x0, 0x3, 0xfd, 0xdf, 0x40, 0x0, 0x0, 0xd,
+ 0xf4, 0x4f, 0xe0, 0x0, 0x0, 0x8f, 0xb0, 0xb,
+ 0xf9, 0x0, 0x3, 0xff, 0x20, 0x2, 0xff, 0x30,
+ 0xd, 0xf7, 0x0, 0x0, 0x7f, 0xd0, 0x7f, 0xd0,
+ 0x0, 0x0, 0xd, 0xf8,
+
+ /* U+0059 "Y" */
+ 0xbf, 0x90, 0x0, 0x0, 0x5, 0xfc, 0x2, 0xff,
+ 0x20, 0x0, 0x0, 0xdf, 0x30, 0x9, 0xfa, 0x0,
+ 0x0, 0x6f, 0xa0, 0x0, 0x1e, 0xf3, 0x0, 0xe,
+ 0xf2, 0x0, 0x0, 0x7f, 0xc0, 0x7, 0xf8, 0x0,
+ 0x0, 0x0, 0xdf, 0x41, 0xfe, 0x10, 0x0, 0x0,
+ 0x5, 0xfc, 0x8f, 0x60, 0x0, 0x0, 0x0, 0xb,
+ 0xff, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xef, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef,
+ 0x0, 0x0, 0x0,
+
+ /* U+005A "Z" */
+ 0x9f, 0xff, 0xff, 0xff, 0xfc, 0x7c, 0xcc, 0xcc,
+ 0xce, 0xfa, 0x0, 0x0, 0x0, 0x2f, 0xf2, 0x0,
+ 0x0, 0x0, 0xcf, 0x60, 0x0, 0x0, 0x6, 0xfb,
+ 0x0, 0x0, 0x0, 0x2f, 0xf2, 0x0, 0x0, 0x0,
+ 0xcf, 0x60, 0x0, 0x0, 0x6, 0xfb, 0x0, 0x0,
+ 0x0, 0x2f, 0xf2, 0x0, 0x0, 0x0, 0xcf, 0x60,
+ 0x0, 0x0, 0x6, 0xfb, 0x0, 0x0, 0x0, 0x2f,
+ 0xf1, 0x0, 0x0, 0x0, 0xbf, 0xec, 0xcc, 0xcc,
+ 0xcb, 0xdf, 0xff, 0xff, 0xff, 0xfe,
+
+ /* U+005B "[" */
+ 0x4f, 0xff, 0xff, 0x4f, 0xb8, 0x88, 0x4f, 0x70,
+ 0x0, 0x4f, 0x70, 0x0, 0x4f, 0x70, 0x0, 0x4f,
+ 0x70, 0x0, 0x4f, 0x70, 0x0, 0x4f, 0x70, 0x0,
+ 0x4f, 0x70, 0x0, 0x4f, 0x70, 0x0, 0x4f, 0x70,
+ 0x0, 0x4f, 0x70, 0x0, 0x4f, 0x70, 0x0, 0x4f,
+ 0x70, 0x0, 0x4f, 0x70, 0x0, 0x4f, 0x70, 0x0,
+ 0x4f, 0x70, 0x0, 0x4f, 0xb8, 0x88, 0x4f, 0xff,
+ 0xff,
+
+ /* U+005C "\\" */
+ 0x1f, 0xb0, 0x0, 0x0, 0x0, 0xa, 0xf2, 0x0,
+ 0x0, 0x0, 0x3, 0xf8, 0x0, 0x0, 0x0, 0x0,
+ 0xce, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x60, 0x0,
+ 0x0, 0x0, 0xe, 0xd0, 0x0, 0x0, 0x0, 0x8,
+ 0xf3, 0x0, 0x0, 0x0, 0x2, 0xfa, 0x0, 0x0,
+ 0x0, 0x0, 0xbf, 0x10, 0x0, 0x0, 0x0, 0x4f,
+ 0x80, 0x0, 0x0, 0x0, 0xd, 0xe0, 0x0, 0x0,
+ 0x0, 0x7, 0xf5, 0x0, 0x0, 0x0, 0x0, 0xfc,
+ 0x0, 0x0, 0x0, 0x0, 0x9f, 0x30, 0x0, 0x0,
+ 0x0, 0x2f, 0x90, 0x0, 0x0, 0x0, 0xc, 0xf1,
+ 0x0, 0x0, 0x0, 0x5, 0xf7, 0x0, 0x0, 0x0,
+ 0x0, 0x76,
+
+ /* U+005D "]" */
+ 0xef, 0xff, 0xf6, 0x78, 0x8b, 0xf6, 0x0, 0x6,
+ 0xf6, 0x0, 0x6, 0xf6, 0x0, 0x6, 0xf6, 0x0,
+ 0x6, 0xf6, 0x0, 0x6, 0xf6, 0x0, 0x6, 0xf6,
+ 0x0, 0x6, 0xf6, 0x0, 0x6, 0xf6, 0x0, 0x6,
+ 0xf6, 0x0, 0x6, 0xf6, 0x0, 0x6, 0xf6, 0x0,
+ 0x6, 0xf6, 0x0, 0x6, 0xf6, 0x0, 0x6, 0xf6,
+ 0x0, 0x6, 0xf6, 0x78, 0x8b, 0xf6, 0xef, 0xff,
+ 0xf6,
+
+ /* U+005E "^" */
+ 0x0, 0x1, 0xff, 0x10, 0x0, 0x0, 0x9, 0xef,
+ 0xa0, 0x0, 0x0, 0x2f, 0x68, 0xf3, 0x0, 0x0,
+ 0xbd, 0x0, 0xec, 0x0, 0x4, 0xf5, 0x0, 0x6f,
+ 0x60, 0xd, 0xc0, 0x0, 0xc, 0xe1, 0x6f, 0x40,
+ 0x0, 0x4, 0xf9,
+
+ /* U+005F "_" */
+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xf, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xf1,
+
+ /* U+0060 "`" */
+ 0x3, 0x23, 0xfd, 0x2f, 0xc1, 0xfb, 0xf, 0xa0,
+ 0xf9,
+
+ /* U+0061 "a" */
+ 0x4, 0xad, 0xff, 0xd7, 0x0, 0xa, 0xfc, 0xaa,
+ 0xef, 0xb0, 0x3, 0x10, 0x0, 0x1e, 0xf2, 0x0,
+ 0x0, 0x0, 0x9, 0xf5, 0x0, 0x0, 0x11, 0x19,
+ 0xf5, 0x2, 0xaf, 0xff, 0xff, 0xf5, 0x2f, 0xf9,
+ 0x54, 0x4b, 0xf5, 0x7f, 0x80, 0x0, 0x9, 0xf5,
+ 0x8f, 0x80, 0x0, 0x5e, 0xf5, 0x3f, 0xfa, 0x9d,
+ 0xfc, 0xf5, 0x4, 0xcf, 0xfb, 0x35, 0xf5,
+
+ /* U+0062 "b" */
+ 0x4f, 0x90, 0x0, 0x0, 0x0, 0x4f, 0x90, 0x0,
+ 0x0, 0x0, 0x4f, 0x90, 0x0, 0x0, 0x0, 0x4f,
+ 0x90, 0x0, 0x0, 0x0, 0x4f, 0x91, 0xae, 0xfb,
+ 0x20, 0x4f, 0xae, 0xfb, 0xcf, 0xe1, 0x4f, 0xfc,
+ 0x10, 0xb, 0xf7, 0x4f, 0xd1, 0x0, 0x3, 0xfb,
+ 0x4f, 0x90, 0x0, 0x0, 0xfd, 0x4f, 0x90, 0x0,
+ 0x0, 0xfe, 0x4f, 0x90, 0x0, 0x0, 0xfd, 0x4f,
+ 0x90, 0x0, 0x4, 0xf9, 0x4f, 0x90, 0x0, 0x1d,
+ 0xf3, 0x4f, 0xfb, 0x8a, 0xef, 0x70, 0x17, 0xce,
+ 0xfe, 0xb4, 0x0,
+
+ /* U+0063 "c" */
+ 0x0, 0x5, 0xcf, 0xfe, 0xa0, 0x0, 0xaf, 0xfa,
+ 0xac, 0xf1, 0x7, 0xfd, 0x20, 0x0, 0x10, 0xe,
+ 0xf3, 0x0, 0x0, 0x0, 0x3f, 0xc0, 0x0, 0x0,
+ 0x0, 0x4f, 0xa0, 0x0, 0x0, 0x0, 0x3f, 0xc0,
+ 0x0, 0x0, 0x0, 0x1f, 0xf1, 0x0, 0x0, 0x0,
+ 0xa, 0xfb, 0x10, 0x0, 0x10, 0x1, 0xef, 0xeb,
+ 0xac, 0xf1, 0x0, 0x18, 0xdf, 0xfd, 0x90,
+
+ /* U+0064 "d" */
+ 0x0, 0x0, 0x0, 0x9, 0xf5, 0x0, 0x0, 0x0,
+ 0x9, 0xf5, 0x0, 0x0, 0x0, 0x9, 0xf5, 0x0,
+ 0x0, 0x0, 0x9, 0xf5, 0x0, 0x3a, 0xef, 0xee,
+ 0xf5, 0x5, 0xff, 0xb9, 0xbf, 0xf5, 0x1f, 0xe2,
+ 0x0, 0x9, 0xf5, 0x8f, 0x60, 0x0, 0x9, 0xf5,
+ 0xbf, 0x20, 0x0, 0x9, 0xf5, 0xcf, 0x10, 0x0,
+ 0x9, 0xf5, 0xbf, 0x10, 0x0, 0x9, 0xf5, 0xaf,
+ 0x40, 0x0, 0xd, 0xf5, 0x6f, 0xa0, 0x0, 0xbf,
+ 0xf5, 0xd, 0xfa, 0x7d, 0xe9, 0xf5, 0x1, 0xbf,
+ 0xea, 0x16, 0xf5,
+
+ /* U+0065 "e" */
+ 0x0, 0x3b, 0xef, 0xd6, 0x0, 0x4, 0xff, 0xa9,
+ 0xdf, 0xa0, 0x1e, 0xf2, 0x0, 0xc, 0xf4, 0x6f,
+ 0x80, 0x0, 0x4, 0xfa, 0xaf, 0x62, 0x22, 0x24,
+ 0xfc, 0xbf, 0xff, 0xff, 0xff, 0xfd, 0xaf, 0x85,
+ 0x55, 0x55, 0x53, 0x8f, 0x70, 0x0, 0x0, 0x0,
+ 0x2f, 0xe2, 0x0, 0x0, 0x0, 0x7, 0xff, 0xb9,
+ 0x9a, 0xd3, 0x0, 0x4b, 0xef, 0xfd, 0xa2,
+
+ /* U+0066 "f" */
+ 0x0, 0x0, 0x1, 0x9d, 0xff, 0xd3, 0x0, 0x0,
+ 0xd, 0xfd, 0x99, 0xb4, 0x0, 0x0, 0x6f, 0xb0,
+ 0x0, 0x0, 0x0, 0x0, 0x9f, 0x50, 0x0, 0x0,
+ 0x0, 0x0, 0xaf, 0x30, 0x0, 0x0, 0x0, 0x0,
+ 0xaf, 0x30, 0x0, 0x0, 0x2f, 0xff, 0xff, 0xff,
+ 0xff, 0xf0, 0x19, 0x99, 0xdf, 0xa9, 0x99, 0x80,
+ 0x0, 0x0, 0xaf, 0x30, 0x0, 0x0, 0x0, 0x0,
+ 0xaf, 0x30, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x30,
+ 0x0, 0x0, 0x0, 0x0, 0xaf, 0x30, 0x0, 0x0,
+ 0x0, 0x0, 0xaf, 0x30, 0x0, 0x0, 0x0, 0x0,
+ 0xaf, 0x30, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x30,
+ 0x0, 0x0,
+
+ /* U+0067 "g" */
+ 0x0, 0x5c, 0xff, 0xff, 0xff, 0x30, 0x8f, 0xd7,
+ 0x8e, 0xfe, 0xb2, 0x2f, 0xe0, 0x0, 0x2f, 0xd0,
+ 0x4, 0xf9, 0x0, 0x0, 0xdf, 0x10, 0x3f, 0xc0,
+ 0x0, 0xe, 0xf0, 0x0, 0xcf, 0x92, 0x3b, 0xf8,
+ 0x0, 0xd, 0xff, 0xff, 0xf8, 0x0, 0x6, 0xf6,
+ 0x14, 0x31, 0x0, 0x0, 0x8f, 0x50, 0x0, 0x0,
+ 0x0, 0x5, 0xff, 0xaa, 0xa9, 0x83, 0x0, 0xd,
+ 0xff, 0xff, 0xff, 0xf9, 0xa, 0xf7, 0x0, 0x0,
+ 0x4f, 0xf1, 0xff, 0x10, 0x0, 0x1, 0xff, 0x1b,
+ 0xfe, 0x98, 0x8a, 0xef, 0x70, 0x7, 0xce, 0xff,
+ 0xea, 0x40, 0x0,
+
+ /* U+0068 "h" */
+ 0x4f, 0x90, 0x0, 0x0, 0x0, 0x4f, 0x90, 0x0,
+ 0x0, 0x0, 0x4f, 0x90, 0x0, 0x0, 0x0, 0x4f,
+ 0x90, 0x0, 0x0, 0x0, 0x4f, 0x91, 0xae, 0xea,
+ 0x10, 0x4f, 0xbe, 0xea, 0xdf, 0xc0, 0x4f, 0xfc,
+ 0x10, 0xd, 0xf3, 0x4f, 0xd1, 0x0, 0x8, 0xf5,
+ 0x4f, 0x90, 0x0, 0x7, 0xf6, 0x4f, 0x90, 0x0,
+ 0x7, 0xf6, 0x4f, 0x90, 0x0, 0x7, 0xf6, 0x4f,
+ 0x90, 0x0, 0x7, 0xf6, 0x4f, 0x90, 0x0, 0x7,
+ 0xf6, 0x4f, 0x90, 0x0, 0x7, 0xf6, 0x4f, 0x90,
+ 0x0, 0x7, 0xf6,
+
+ /* U+0069 "i" */
+ 0x0, 0x1, 0xde, 0x20, 0x0, 0x0, 0x5, 0xff,
+ 0x70, 0x0, 0x0, 0x1, 0xcd, 0x20, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0xff, 0x40,
+ 0x0, 0x6, 0x88, 0xdf, 0x40, 0x0, 0x0, 0x0,
+ 0x9f, 0x40, 0x0, 0x0, 0x0, 0x9f, 0x40, 0x0,
+ 0x0, 0x0, 0x9f, 0x40, 0x0, 0x0, 0x0, 0x9f,
+ 0x40, 0x0, 0x0, 0x0, 0x9f, 0x40, 0x0, 0x0,
+ 0x0, 0x9f, 0x40, 0x0, 0x0, 0x0, 0x9f, 0x40,
+ 0x0, 0x19, 0x99, 0xdf, 0xa9, 0x94, 0x2f, 0xff,
+ 0xff, 0xff, 0xf8,
+
+ /* U+006A "j" */
+ 0x0, 0x0, 0x3, 0xec, 0x10, 0x0, 0x0, 0x8f,
+ 0xf5, 0x0, 0x0, 0x2, 0xdc, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x2f, 0xff, 0xff, 0xff, 0x1, 0x88,
+ 0x88, 0x8e, 0xf0, 0x0, 0x0, 0x0, 0xdf, 0x0,
+ 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0, 0x0, 0xdf,
+ 0x0, 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0, 0x0,
+ 0xdf, 0x0, 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0,
+ 0x0, 0xdf, 0x0, 0x0, 0x0, 0xd, 0xf0, 0x0,
+ 0x0, 0x0, 0xef, 0x0, 0x0, 0x0, 0xf, 0xe0,
+ 0x10, 0x0, 0x8, 0xf9, 0x9, 0xea, 0x9c, 0xfe,
+ 0x10, 0x5c, 0xef, 0xe9, 0x10, 0x0,
+
+ /* U+006B "k" */
+ 0xf, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xfd, 0x0,
+ 0x0, 0x0, 0x0, 0xf, 0xd0, 0x0, 0x0, 0x0,
+ 0x0, 0xfd, 0x0, 0x0, 0x0, 0x0, 0xf, 0xd0,
+ 0x0, 0xc, 0xfa, 0x0, 0xfd, 0x0, 0xb, 0xfa,
+ 0x0, 0xf, 0xd0, 0xb, 0xfa, 0x0, 0x0, 0xfd,
+ 0xa, 0xfa, 0x0, 0x0, 0xf, 0xda, 0xfa, 0x0,
+ 0x0, 0x0, 0xfd, 0xcf, 0x70, 0x0, 0x0, 0xf,
+ 0xd1, 0xef, 0x50, 0x0, 0x0, 0xfd, 0x2, 0xff,
+ 0x40, 0x0, 0xf, 0xd0, 0x4, 0xff, 0x30, 0x0,
+ 0xfd, 0x0, 0x6, 0xfe, 0x20, 0xf, 0xd0, 0x0,
+ 0x9, 0xfd, 0x10,
+
+ /* U+006C "l" */
+ 0xc, 0xff, 0xff, 0x40, 0x0, 0x6, 0x88, 0xdf,
+ 0x40, 0x0, 0x0, 0x0, 0x9f, 0x40, 0x0, 0x0,
+ 0x0, 0x9f, 0x40, 0x0, 0x0, 0x0, 0x9f, 0x40,
+ 0x0, 0x0, 0x0, 0x9f, 0x40, 0x0, 0x0, 0x0,
+ 0x9f, 0x40, 0x0, 0x0, 0x0, 0x9f, 0x40, 0x0,
+ 0x0, 0x0, 0x9f, 0x40, 0x0, 0x0, 0x0, 0x9f,
+ 0x40, 0x0, 0x0, 0x0, 0x9f, 0x40, 0x0, 0x0,
+ 0x0, 0x9f, 0x40, 0x0, 0x0, 0x0, 0x9f, 0x40,
+ 0x0, 0x19, 0x99, 0xdf, 0xa9, 0x94, 0x2f, 0xff,
+ 0xff, 0xff, 0xf8,
+
+ /* U+006D "m" */
+ 0xf, 0x66, 0xed, 0x24, 0xde, 0x50, 0xf, 0xae,
+ 0x7f, 0xae, 0x8e, 0xe0, 0xf, 0xf6, 0xd, 0xf9,
+ 0xa, 0xf1, 0xf, 0xd0, 0xd, 0xf1, 0x9, 0xf1,
+ 0xf, 0xb0, 0xd, 0xe0, 0x9, 0xf2, 0xf, 0xb0,
+ 0xd, 0xe0, 0x9, 0xf2, 0xf, 0xb0, 0xd, 0xe0,
+ 0x9, 0xf2, 0xf, 0xb0, 0xd, 0xe0, 0x9, 0xf2,
+ 0xf, 0xb0, 0xd, 0xe0, 0x9, 0xf2, 0xf, 0xb0,
+ 0xd, 0xe0, 0x9, 0xf2, 0xf, 0xb0, 0xd, 0xe0,
+ 0x9, 0xf2,
+
+ /* U+006E "n" */
+ 0x4f, 0x62, 0xbf, 0xea, 0x10, 0x4f, 0xbf, 0xc7,
+ 0xaf, 0xc0, 0x4f, 0xfa, 0x0, 0xc, 0xf3, 0x4f,
+ 0xc0, 0x0, 0x8, 0xf5, 0x4f, 0x90, 0x0, 0x7,
+ 0xf6, 0x4f, 0x90, 0x0, 0x7, 0xf6, 0x4f, 0x90,
+ 0x0, 0x7, 0xf6, 0x4f, 0x90, 0x0, 0x7, 0xf6,
+ 0x4f, 0x90, 0x0, 0x7, 0xf6, 0x4f, 0x90, 0x0,
+ 0x7, 0xf6, 0x4f, 0x90, 0x0, 0x7, 0xf6,
+
+ /* U+006F "o" */
+ 0x0, 0x5, 0xbf, 0xfd, 0x70, 0x0, 0x0, 0x8f,
+ 0xfa, 0xae, 0xfc, 0x0, 0x4, 0xfd, 0x10, 0x1,
+ 0xcf, 0x70, 0xb, 0xf4, 0x0, 0x0, 0x3f, 0xd0,
+ 0xe, 0xf0, 0x0, 0x0, 0xe, 0xf0, 0xf, 0xe0,
+ 0x0, 0x0, 0xd, 0xf1, 0xf, 0xf0, 0x0, 0x0,
+ 0xe, 0xf0, 0xc, 0xf4, 0x0, 0x0, 0x3f, 0xc0,
+ 0x6, 0xfc, 0x10, 0x1, 0xcf, 0x50, 0x0, 0xbf,
+ 0xea, 0xae, 0xfa, 0x0, 0x0, 0x7, 0xdf, 0xfc,
+ 0x60, 0x0,
+
+ /* U+0070 "p" */
+ 0x4f, 0x62, 0xae, 0xfb, 0x20, 0x4f, 0xbf, 0xd7,
+ 0x9f, 0xe1, 0x4f, 0xfa, 0x0, 0x9, 0xf7, 0x4f,
+ 0xc0, 0x0, 0x2, 0xfb, 0x4f, 0x90, 0x0, 0x0,
+ 0xfd, 0x4f, 0x90, 0x0, 0x0, 0xfe, 0x4f, 0x90,
+ 0x0, 0x1, 0xfd, 0x4f, 0x90, 0x0, 0x5, 0xf9,
+ 0x4f, 0x90, 0x0, 0x1d, 0xf3, 0x4f, 0xfb, 0x89,
+ 0xef, 0x70, 0x4f, 0xee, 0xfe, 0xb4, 0x0, 0x4f,
+ 0x90, 0x0, 0x0, 0x0, 0x4f, 0x90, 0x0, 0x0,
+ 0x0, 0x4f, 0x90, 0x0, 0x0, 0x0, 0x4f, 0x90,
+ 0x0, 0x0, 0x0,
+
+ /* U+0071 "q" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0xef,
+ 0xeb, 0xd5, 0x5, 0xfe, 0x98, 0xaf, 0xf5, 0x1f,
+ 0xe1, 0x0, 0x9, 0xf5, 0x8f, 0x70, 0x0, 0x9,
+ 0xf5, 0xbf, 0x30, 0x0, 0x9, 0xf5, 0xcf, 0x10,
+ 0x0, 0x9, 0xf5, 0xbf, 0x20, 0x0, 0x9, 0xf5,
+ 0xaf, 0x50, 0x0, 0x1e, 0xf5, 0x6f, 0xc0, 0x1,
+ 0xdf, 0xf5, 0xd, 0xfc, 0xaf, 0xe9, 0xf5, 0x1,
+ 0xbf, 0xe9, 0x18, 0xf5, 0x0, 0x0, 0x0, 0x9,
+ 0xf5, 0x0, 0x0, 0x0, 0x9, 0xf5, 0x0, 0x0,
+ 0x0, 0x9, 0xf5, 0x0, 0x0, 0x0, 0x9, 0xf5,
+
+ /* U+0072 "r" */
+ 0xde, 0x5, 0xcf, 0xe8, 0x0, 0xde, 0x8f, 0xa7,
+ 0xdf, 0x70, 0xdf, 0xf5, 0x0, 0x2f, 0xd0, 0xdf,
+ 0x60, 0x0, 0xe, 0xf0, 0xdf, 0x0, 0x0, 0x2,
+ 0x20, 0xdf, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0,
+ 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0,
+ 0xdf, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0,
+ 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0,
+
+ /* U+0073 "s" */
+ 0x0, 0x4b, 0xef, 0xfd, 0x60, 0x5, 0xff, 0xa9,
+ 0xac, 0x80, 0xc, 0xf2, 0x0, 0x0, 0x0, 0xc,
+ 0xf3, 0x0, 0x0, 0x0, 0x6, 0xff, 0xa4, 0x0,
+ 0x0, 0x0, 0x4d, 0xff, 0xf8, 0x0, 0x0, 0x0,
+ 0x27, 0xef, 0xc0, 0x0, 0x0, 0x0, 0xd, 0xf2,
+ 0x0, 0x0, 0x0, 0xd, 0xf2, 0xf, 0xca, 0x9a,
+ 0xef, 0xa0, 0xb, 0xdf, 0xff, 0xc6, 0x0,
+
+ /* U+0074 "t" */
+ 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x0, 0x4f,
+ 0x90, 0x0, 0x0, 0x0, 0x4, 0xf9, 0x0, 0x0,
+ 0x0, 0x0, 0x4f, 0x90, 0x0, 0x0, 0x5f, 0xff,
+ 0xff, 0xff, 0xff, 0x62, 0x99, 0xbf, 0xc9, 0x99,
+ 0x93, 0x0, 0x4, 0xf9, 0x0, 0x0, 0x0, 0x0,
+ 0x4f, 0x90, 0x0, 0x0, 0x0, 0x4, 0xf9, 0x0,
+ 0x0, 0x0, 0x0, 0x4f, 0x90, 0x0, 0x0, 0x0,
+ 0x4, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x4f, 0x90,
+ 0x0, 0x0, 0x0, 0x1, 0xfe, 0x10, 0x0, 0x0,
+ 0x0, 0xa, 0xfe, 0xaa, 0xb5, 0x0, 0x0, 0x9,
+ 0xef, 0xfd, 0x40,
+
+ /* U+0075 "u" */
+ 0x4f, 0x90, 0x0, 0x7, 0xf6, 0x4f, 0x90, 0x0,
+ 0x7, 0xf6, 0x4f, 0x90, 0x0, 0x7, 0xf6, 0x4f,
+ 0x90, 0x0, 0x7, 0xf6, 0x4f, 0x90, 0x0, 0x7,
+ 0xf6, 0x4f, 0x90, 0x0, 0x7, 0xf6, 0x4f, 0x90,
+ 0x0, 0x7, 0xf6, 0x3f, 0xa0, 0x0, 0xa, 0xf6,
+ 0x1f, 0xd0, 0x0, 0x8f, 0xf6, 0xb, 0xfb, 0x7b,
+ 0xfb, 0xf6, 0x1, 0xae, 0xfc, 0x44, 0xf6,
+
+ /* U+0076 "v" */
+ 0x1f, 0xf0, 0x0, 0x0, 0xe, 0xf2, 0xb, 0xf6,
+ 0x0, 0x0, 0x4f, 0xb0, 0x5, 0xfb, 0x0, 0x0,
+ 0xaf, 0x50, 0x0, 0xef, 0x10, 0x0, 0xfe, 0x0,
+ 0x0, 0x9f, 0x70, 0x5, 0xf9, 0x0, 0x0, 0x2f,
+ 0xd0, 0xb, 0xf3, 0x0, 0x0, 0xc, 0xf3, 0x1f,
+ 0xc0, 0x0, 0x0, 0x6, 0xf8, 0x7f, 0x60, 0x0,
+ 0x0, 0x0, 0xfd, 0xcf, 0x10, 0x0, 0x0, 0x0,
+ 0xaf, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf4,
+ 0x0, 0x0,
+
+ /* U+0077 "w" */
+ 0x8f, 0x40, 0x0, 0x0, 0x3, 0xfa, 0x6f, 0x60,
+ 0x0, 0x0, 0x4, 0xf7, 0x4f, 0x80, 0x2, 0x30,
+ 0x6, 0xf5, 0x1f, 0xa0, 0xe, 0xe0, 0x8, 0xf3,
+ 0xf, 0xc0, 0x3f, 0xf4, 0xa, 0xf1, 0xd, 0xe0,
+ 0x8e, 0xea, 0xb, 0xe0, 0xb, 0xf0, 0xda, 0xaf,
+ 0xd, 0xc0, 0x8, 0xf4, 0xf4, 0x5f, 0x5f, 0xa0,
+ 0x6, 0xfb, 0xf0, 0xf, 0xbf, 0x70, 0x4, 0xff,
+ 0xa0, 0xa, 0xff, 0x50, 0x1, 0xff, 0x50, 0x4,
+ 0xff, 0x30,
+
+ /* U+0078 "x" */
+ 0xa, 0xfa, 0x0, 0x0, 0x6f, 0xd0, 0x1, 0xef,
+ 0x50, 0x1, 0xef, 0x30, 0x0, 0x3f, 0xe1, 0xb,
+ 0xf6, 0x0, 0x0, 0x8, 0xfa, 0x5f, 0xb0, 0x0,
+ 0x0, 0x0, 0xcf, 0xfe, 0x10, 0x0, 0x0, 0x0,
+ 0x4f, 0xf6, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xfe,
+ 0x10, 0x0, 0x0, 0x9, 0xf9, 0x7f, 0xb0, 0x0,
+ 0x0, 0x5f, 0xd0, 0xc, 0xf8, 0x0, 0x2, 0xff,
+ 0x30, 0x2, 0xff, 0x40, 0xd, 0xf8, 0x0, 0x0,
+ 0x6f, 0xe1,
+
+ /* U+0079 "y" */
+ 0x1f, 0xf1, 0x0, 0x0, 0xe, 0xf1, 0xb, 0xf6,
+ 0x0, 0x0, 0x4f, 0xb0, 0x4, 0xfc, 0x0, 0x0,
+ 0xaf, 0x50, 0x0, 0xdf, 0x30, 0x0, 0xfe, 0x0,
+ 0x0, 0x7f, 0x90, 0x5, 0xf9, 0x0, 0x0, 0x1f,
+ 0xf0, 0xb, 0xf2, 0x0, 0x0, 0xa, 0xf5, 0x1f,
+ 0xc0, 0x0, 0x0, 0x3, 0xfb, 0x7f, 0x60, 0x0,
+ 0x0, 0x0, 0xdf, 0xdf, 0x0, 0x0, 0x0, 0x0,
+ 0x6f, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf3,
+ 0x0, 0x0, 0x0, 0x0, 0x8f, 0xb0, 0x0, 0x0,
+ 0x0, 0x5, 0xff, 0x20, 0x0, 0x0, 0x4a, 0xcf,
+ 0xf5, 0x0, 0x0, 0x0, 0x5f, 0xea, 0x30, 0x0,
+ 0x0, 0x0,
+
+ /* U+007A "z" */
+ 0x1f, 0xff, 0xff, 0xff, 0xf1, 0x9, 0x99, 0x99,
+ 0xbf, 0xe0, 0x0, 0x0, 0x0, 0xdf, 0x40, 0x0,
+ 0x0, 0x9, 0xf8, 0x0, 0x0, 0x0, 0x5f, 0xc0,
+ 0x0, 0x0, 0x2, 0xfe, 0x10, 0x0, 0x0, 0xd,
+ 0xf4, 0x0, 0x0, 0x0, 0x9f, 0x80, 0x0, 0x0,
+ 0x5, 0xfc, 0x0, 0x0, 0x0, 0x1f, 0xfb, 0x99,
+ 0x99, 0x94, 0x3f, 0xff, 0xff, 0xff, 0xf7,
+
+ /* U+007B "{" */
+ 0x0, 0x0, 0x19, 0xef, 0xa0, 0x0, 0xc, 0xfd,
+ 0x95, 0x0, 0x1, 0xfc, 0x0, 0x0, 0x0, 0x3f,
+ 0x80, 0x0, 0x0, 0x4, 0xf8, 0x0, 0x0, 0x0,
+ 0x4f, 0x80, 0x0, 0x0, 0x7, 0xf6, 0x0, 0x2,
+ 0x8a, 0xfc, 0x0, 0x0, 0x4f, 0xfd, 0x40, 0x0,
+ 0x0, 0x3, 0xdf, 0x20, 0x0, 0x0, 0x5, 0xf7,
+ 0x0, 0x0, 0x0, 0x4f, 0x80, 0x0, 0x0, 0x4,
+ 0xf8, 0x0, 0x0, 0x0, 0x4f, 0x80, 0x0, 0x0,
+ 0x4, 0xf8, 0x0, 0x0, 0x0, 0x3f, 0x90, 0x0,
+ 0x0, 0x1, 0xfe, 0x0, 0x0, 0x0, 0x9, 0xfd,
+ 0x95, 0x0, 0x0, 0x8, 0xdf, 0xa0,
+
+ /* U+007C "|" */
+ 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
+ 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
+ 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
+
+ /* U+007D "}" */
+ 0x8f, 0xe9, 0x10, 0x0, 0x4, 0x8c, 0xfd, 0x0,
+ 0x0, 0x0, 0xb, 0xf3, 0x0, 0x0, 0x0, 0x7f,
+ 0x50, 0x0, 0x0, 0x7, 0xf5, 0x0, 0x0, 0x0,
+ 0x6f, 0x50, 0x0, 0x0, 0x5, 0xf9, 0x0, 0x0,
+ 0x0, 0xb, 0xfb, 0x82, 0x0, 0x0, 0x2c, 0xff,
+ 0x50, 0x0, 0xe, 0xd3, 0x0, 0x0, 0x5, 0xf6,
+ 0x0, 0x0, 0x0, 0x6f, 0x50, 0x0, 0x0, 0x6,
+ 0xf5, 0x0, 0x0, 0x0, 0x6f, 0x50, 0x0, 0x0,
+ 0x6, 0xf5, 0x0, 0x0, 0x0, 0x7f, 0x40, 0x0,
+ 0x0, 0xc, 0xf2, 0x0, 0x4, 0x8d, 0xfb, 0x0,
+ 0x0, 0x8f, 0xd8, 0x0, 0x0, 0x0,
+
+ /* U+007E "~" */
+ 0x0, 0x6a, 0x81, 0x0, 0x0, 0x10, 0x8, 0xff,
+ 0xfe, 0x20, 0x5, 0xf5, 0xf, 0xd1, 0x5f, 0xe2,
+ 0x9, 0xf3, 0x3f, 0x70, 0x5, 0xff, 0xcf, 0xc0,
+ 0x16, 0x20, 0x0, 0x4c, 0xfb, 0x10,
+
+ /* U+007F "" */
+
+ /* U+4E2D "ä¸" */
+ 0x0, 0x0, 0x0, 0x0, 0x4, 0x50, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xd, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0,
+ 0x0, 0x0, 0xa, 0xaa, 0xaa, 0xaa, 0xae, 0xfa,
+ 0xaa, 0xaa, 0xaa, 0xa6, 0x1f, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x1f, 0xa0,
+ 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0, 0x2, 0xf9,
+ 0x1f, 0xa0, 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0,
+ 0x2, 0xf9, 0x1f, 0xa0, 0x0, 0x0, 0xd, 0xf0,
+ 0x0, 0x0, 0x2, 0xf9, 0x1f, 0xa0, 0x0, 0x0,
+ 0xd, 0xf0, 0x0, 0x0, 0x2, 0xf9, 0x1f, 0xa0,
+ 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0, 0x2, 0xf9,
+ 0x1f, 0xd9, 0x99, 0x99, 0x9e, 0xf9, 0x99, 0x99,
+ 0x9a, 0xf9, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xf9, 0x1f, 0xa0, 0x0, 0x0,
+ 0xd, 0xf0, 0x0, 0x0, 0x2, 0xf9, 0x2, 0x10,
+ 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0, 0x0, 0x21,
+ 0x0, 0x0, 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xd, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xd, 0xf0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xf0,
+ 0x0, 0x0, 0x0, 0x0,
+
+ /* U+6587 "æ–‡" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa,
+ 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x4, 0xfd, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0x40,
+ 0x0, 0x0, 0x0, 0x0, 0x59, 0x99, 0x99, 0x99,
+ 0x99, 0xbc, 0x99, 0x99, 0x99, 0x99, 0x90, 0x8f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xf1, 0x0, 0x0, 0x6f, 0x50, 0x0, 0x0,
+ 0x0, 0xd, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x1f,
+ 0x90, 0x0, 0x0, 0x0, 0x1f, 0xb0, 0x0, 0x0,
+ 0x0, 0x0, 0xd, 0xd0, 0x0, 0x0, 0x0, 0x5f,
+ 0x70, 0x0, 0x0, 0x0, 0x0, 0x7, 0xf4, 0x0,
+ 0x0, 0x0, 0xbf, 0x20, 0x0, 0x0, 0x0, 0x0,
+ 0x1, 0xfb, 0x0, 0x0, 0x2, 0xfb, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x9f, 0x40, 0x0, 0xa,
+ 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e,
+ 0xd0, 0x0, 0x4f, 0xb0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x6, 0xfb, 0x2, 0xef, 0x20, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xad,
+ 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xc, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0xe4, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6e, 0xfe,
+ 0x59, 0xff, 0xc5, 0x0, 0x0, 0x0, 0x0, 0x2,
+ 0x8e, 0xff, 0x91, 0x0, 0x4c, 0xff, 0xe8, 0x30,
+ 0x0, 0x16, 0xcf, 0xff, 0x92, 0x0, 0x0, 0x0,
+ 0x5c, 0xff, 0xfe, 0x90, 0x5f, 0xfe, 0x81, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3a, 0xff, 0x80, 0x6,
+ 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x5, 0x0
+};
+
+
+/*---------------------
+ * GLYPH DESCRIPTION
+ *--------------------*/
+
+static const sgl_font_table_t consolas24_tab[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 194, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 0, .adv_w = 194, .box_w = 4, .box_h = 15, .ofs_x = 4, .ofs_y = 0},
+ {.bitmap_index = 30, .adv_w = 194, .box_w = 8, .box_h = 6, .ofs_x = 2, .ofs_y = 9},
+ {.bitmap_index = 54, .adv_w = 194, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 138, .adv_w = 194, .box_w = 10, .box_h = 19, .ofs_x = 1, .ofs_y = -3},
+ {.bitmap_index = 233, .adv_w = 194, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 323, .adv_w = 194, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 421, .adv_w = 194, .box_w = 4, .box_h = 6, .ofs_x = 4, .ofs_y = 9},
+ {.bitmap_index = 433, .adv_w = 194, .box_w = 7, .box_h = 22, .ofs_x = 3, .ofs_y = -5},
+ {.bitmap_index = 510, .adv_w = 194, .box_w = 7, .box_h = 22, .ofs_x = 2, .ofs_y = -5},
+ {.bitmap_index = 587, .adv_w = 194, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 5},
+ {.bitmap_index = 637, .adv_w = 194, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 703, .adv_w = 194, .box_w = 6, .box_h = 8, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 727, .adv_w = 194, .box_w = 8, .box_h = 2, .ofs_x = 2, .ofs_y = 5},
+ {.bitmap_index = 735, .adv_w = 194, .box_w = 4, .box_h = 4, .ofs_x = 4, .ofs_y = 0},
+ {.bitmap_index = 743, .adv_w = 194, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 833, .adv_w = 194, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 917, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 987, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1057, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1127, .adv_w = 194, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1211, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1281, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1351, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1421, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1491, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1561, .adv_w = 194, .box_w = 4, .box_h = 11, .ofs_x = 4, .ofs_y = 0},
+ {.bitmap_index = 1583, .adv_w = 194, .box_w = 6, .box_h = 15, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 1628, .adv_w = 194, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = -1},
+ {.bitmap_index = 1687, .adv_w = 194, .box_w = 10, .box_h = 6, .ofs_x = 1, .ofs_y = 3},
+ {.bitmap_index = 1717, .adv_w = 194, .box_w = 9, .box_h = 13, .ofs_x = 2, .ofs_y = -1},
+ {.bitmap_index = 1776, .adv_w = 194, .box_w = 7, .box_h = 15, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 1829, .adv_w = 194, .box_w = 12, .box_h = 19, .ofs_x = 0, .ofs_y = -4},
+ {.bitmap_index = 1943, .adv_w = 194, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2027, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2097, .adv_w = 194, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2174, .adv_w = 194, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2251, .adv_w = 194, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2314, .adv_w = 194, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2377, .adv_w = 194, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2454, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2524, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2594, .adv_w = 194, .box_w = 9, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2657, .adv_w = 194, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2734, .adv_w = 194, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2797, .adv_w = 194, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2881, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2951, .adv_w = 194, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3035, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3105, .adv_w = 194, .box_w = 13, .box_h = 18, .ofs_x = 0, .ofs_y = -4},
+ {.bitmap_index = 3222, .adv_w = 194, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3299, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3369, .adv_w = 194, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3453, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3523, .adv_w = 194, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3614, .adv_w = 194, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3698, .adv_w = 194, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3782, .adv_w = 194, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3873, .adv_w = 194, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3943, .adv_w = 194, .box_w = 6, .box_h = 19, .ofs_x = 3, .ofs_y = -4},
+ {.bitmap_index = 4000, .adv_w = 194, .box_w = 10, .box_h = 18, .ofs_x = 1, .ofs_y = -3},
+ {.bitmap_index = 4090, .adv_w = 194, .box_w = 6, .box_h = 19, .ofs_x = 3, .ofs_y = -4},
+ {.bitmap_index = 4147, .adv_w = 194, .box_w = 10, .box_h = 7, .ofs_x = 1, .ofs_y = 7},
+ {.bitmap_index = 4182, .adv_w = 194, .box_w = 13, .box_h = 2, .ofs_x = 0, .ofs_y = -4},
+ {.bitmap_index = 4195, .adv_w = 90, .box_w = 3, .box_h = 6, .ofs_x = 1, .ofs_y = 12},
+ {.bitmap_index = 4204, .adv_w = 194, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4259, .adv_w = 194, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4334, .adv_w = 194, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4389, .adv_w = 194, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4464, .adv_w = 194, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4519, .adv_w = 194, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 4609, .adv_w = 194, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = -4},
+ {.bitmap_index = 4692, .adv_w = 194, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4767, .adv_w = 194, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4842, .adv_w = 194, .box_w = 9, .box_h = 19, .ofs_x = 1, .ofs_y = -4},
+ {.bitmap_index = 4928, .adv_w = 194, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5011, .adv_w = 194, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5086, .adv_w = 194, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5152, .adv_w = 194, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5207, .adv_w = 194, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5273, .adv_w = 194, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = -4},
+ {.bitmap_index = 5348, .adv_w = 194, .box_w = 10, .box_h = 16, .ofs_x = 1, .ofs_y = -4},
+ {.bitmap_index = 5428, .adv_w = 194, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 5483, .adv_w = 194, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5538, .adv_w = 194, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5621, .adv_w = 194, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5676, .adv_w = 194, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5742, .adv_w = 194, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5808, .adv_w = 194, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5874, .adv_w = 194, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -4},
+ {.bitmap_index = 5964, .adv_w = 194, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 6019, .adv_w = 194, .box_w = 9, .box_h = 19, .ofs_x = 1, .ofs_y = -4},
+ {.bitmap_index = 6105, .adv_w = 194, .box_w = 2, .box_h = 22, .ofs_x = 5, .ofs_y = -4},
+ {.bitmap_index = 6127, .adv_w = 194, .box_w = 9, .box_h = 19, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 6213, .adv_w = 194, .box_w = 12, .box_h = 5, .ofs_x = 0, .ofs_y = 4},
+ {.bitmap_index = 6243, .adv_w = 194, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 6243, .adv_w = 352, .box_w = 20, .box_h = 22, .ofs_x = 1, .ofs_y = -3},
+ {.bitmap_index = 6463, .adv_w = 352, .box_w = 22, .box_h = 22, .ofs_x = 0, .ofs_y = -3}
+};
+
+static const uint32_t unicode_list_1[] = {
+ 0x0, 0x175a
+};
+
+static const sgl_font_unicode_t consolas24_unicode[] = {
+ { .offset = 32, .len = 96, .list = NULL, .tab_offset = 1, },
+ { .offset = 20013, .len = 2, .list = unicode_list_1, .tab_offset = 97, },
+};
+
+
+const sgl_font_t consolas24 = {
+ .bitmap = glyph_bitmap,
+ .table = consolas24_tab,
+ .font_table_size = SGL_ARRAY_SIZE(consolas24_tab),
+ .font_height = 24,
+ .base_line = 5,
+ .bpp = 4,
+ .unicode = consolas24_unicode,
+ .unicode_num = 2,
+};
+
+#endif /* !CONFIG_SGL_FONT_CONSOLAS24*/
diff --git a/User/system/sgl/fonts/sgl_ascii_consolas24_compress.c b/User/system/sgl/fonts/sgl_ascii_consolas24_compress.c
new file mode 100644
index 0000000..f244a12
--- /dev/null
+++ b/User/system/sgl/fonts/sgl_ascii_consolas24_compress.c
@@ -0,0 +1,1183 @@
+/* source/fonts/sgl_ascii_consolas24_compress.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+
+#if (CONFIG_SGL_FONT_CONSOLAS24_COMPRESS)
+
+static const uint8_t font_bitmap[] = {
+ /* U+0020 " " */
+
+ /* U+0021 "!" */
+ 0xaf, 0xc0, 0xaf, 0xc0, 0x9f, 0xb0, 0x9f, 0xb0,
+ 0x8f, 0xa0, 0x8f, 0xa0, 0x7f, 0xa0, 0x7f, 0x90,
+ 0x6f, 0x90, 0x6f, 0x80, 0x5f, 0x80, 0x28, 0x40,
+ 0x0f, 0xe9, 0xfb, 0x0e, 0xff, 0x03, 0xfc, 0x80,
+
+ /* U+0022 "\"" */
+ 0xff, 0x48, 0x37, 0xf8, 0xbb, 0xe0, 0x17, 0xfc,
+ 0x3b, 0xee, 0x09, 0xfe, 0x0c, 0xf6, 0x03, 0xff,
+ 0x05, 0xfa, 0x81, 0x7f, 0x02, 0xc1, 0x00, 0x21,
+ 0x80,
+
+ /* U+0023 "#" */
+ 0x00, 0xdf, 0x80, 0x03, 0xf8, 0x00, 0xe1, 0xfa,
+ 0x00, 0x2f, 0xa8, 0x07, 0x1f, 0xc0, 0x01, 0xfc,
+ 0xc0, 0x2e, 0xff, 0xff, 0x58, 0x3c, 0x5f, 0xd4,
+ 0x43, 0x7e, 0x20, 0xa0, 0x14, 0x79, 0x80, 0x33,
+ 0x80, 0x3d, 0x3e, 0x20, 0x0e, 0xd0, 0x0f, 0x5f,
+ 0x80, 0x5f, 0x60, 0x1e, 0xce, 0x00, 0x0f, 0xd0,
+ 0x05, 0x1f, 0xff, 0xf0, 0xa4, 0x43, 0xf6, 0x21,
+ 0x5f, 0x71, 0x00, 0x08, 0x7e, 0x80, 0x0d, 0xea,
+ 0x01, 0xc7, 0xf0, 0x00, 0x7f, 0x40, 0x0e, 0x4f,
+ 0x70, 0x04, 0xf9, 0x00, 0x73, 0x7a, 0x80, 0x2b,
+ 0xc4, 0x02,
+
+ /* U+0024 "$" */
+ 0x00, 0xf4, 0x20, 0x07, 0xe2, 0xf8, 0x00, 0xfc,
+ 0x9e, 0xc0, 0x1c, 0x75, 0xdf, 0xf6, 0xb8, 0x02,
+ 0x3f, 0xd7, 0xbf, 0x9d, 0x60, 0x7f, 0xc4, 0x17,
+ 0xe0, 0x1a, 0x3e, 0x80, 0x1b, 0xa0, 0x0d, 0x1f,
+ 0xa0, 0x0f, 0xb0, 0x0c, 0x5f, 0xec, 0x5f, 0x90,
+ 0x0e, 0x4e, 0xff, 0xa8, 0x03, 0xe7, 0xef, 0xf9,
+ 0xc0, 0x3d, 0x1f, 0x7f, 0xeb, 0x00, 0xea, 0xf0,
+ 0x3e, 0xf7, 0x00, 0xd9, 0xc0, 0x08, 0xfb, 0x00,
+ 0xdf, 0x80, 0x09, 0xfa, 0x54, 0x11, 0x7d, 0x02,
+ 0xff, 0x96, 0xff, 0xff, 0x50, 0x35, 0xf7, 0xfd,
+ 0xd6, 0x80, 0x1c, 0xfe, 0x60, 0x1f, 0xa7, 0xc4,
+ 0x03, 0xf3, 0xc8, 0x07, 0x80,
+
+ /* U+0025 "%" */
+ 0x02, 0xcf, 0xd5, 0x00, 0xc9, 0xf4, 0x1d, 0xad,
+ 0x9e, 0x60, 0x17, 0x70, 0x57, 0xd4, 0x0b, 0xe4,
+ 0x01, 0x3e, 0xc1, 0x1e, 0x40, 0x0f, 0xa0, 0x3f,
+ 0xb0, 0x03, 0xfa, 0x01, 0x7c, 0x86, 0xf9, 0x00,
+ 0x0f, 0xec, 0xeb, 0xd1, 0xfd, 0xc0, 0x34, 0x7f,
+ 0xd0, 0x5f, 0xa0, 0x1e, 0x24, 0x20, 0xbf, 0x30,
+ 0x0f, 0xe6, 0xf8, 0x00, 0xfe, 0x1e, 0xe0, 0x07,
+ 0xfa, 0xbd, 0x0a, 0xff, 0x58, 0x03, 0x27, 0xd0,
+ 0x77, 0xce, 0xfa, 0x00, 0x5b, 0xc2, 0xbe, 0xc0,
+ 0x5f, 0x40, 0x08, 0xf6, 0x07, 0xf3, 0x00, 0x7d,
+ 0x81, 0xfd, 0x80, 0x1b, 0xd4, 0x07, 0xe4, 0x33,
+ 0xc8, 0x00, 0x3f, 0xad, 0x7e, 0x4f, 0xee, 0x01,
+ 0x8f, 0x3f, 0x50, 0x00,
+
+ /* U+0026 "&" */
+ 0x00, 0x8e, 0xff, 0xd8, 0x60, 0x1f, 0x17, 0xfb,
+ 0x75, 0xfe, 0x30, 0x0f, 0x57, 0xc8, 0x02, 0x3e,
+ 0xc0, 0x3d, 0xde, 0x40, 0x03, 0xfd, 0x00, 0xf7,
+ 0xf8, 0xc0, 0x09, 0xfa, 0x01, 0xed, 0xf7, 0x00,
+ 0x5f, 0xc0, 0x07, 0x9f, 0xf8, 0xaf, 0xf4, 0x03,
+ 0xf6, 0xff, 0xd8, 0x20, 0x1f, 0x0e, 0x7f, 0xac,
+ 0x03, 0xf1, 0x77, 0xef, 0xf8, 0xc0, 0x7f, 0xc0,
+ 0x16, 0x7c, 0x85, 0xff, 0x09, 0x7f, 0x00, 0x0b,
+ 0xfc, 0x01, 0x6f, 0xe2, 0xfd, 0x80, 0x13, 0xf4,
+ 0x02, 0x2f, 0xfc, 0xe0, 0x03, 0xff, 0x00, 0x65,
+ 0xff, 0x84, 0x02, 0xef, 0x80, 0x08, 0xbb, 0xfc,
+ 0x60, 0x12, 0xff, 0xb6, 0x6f, 0xfd, 0xdf, 0xc2,
+ 0x01, 0x1d, 0xf7, 0xf5, 0x20, 0xef, 0xe0, 0x00,
+
+ /* U+0027 "'" */
+ 0xbf, 0xea, 0xfd, 0x9f, 0xc8, 0xfb, 0x7f, 0xa3,
+ 0x84,
+
+ /* U+0028 "(" */
+ 0x00, 0xe1, 0x10, 0x07, 0x0e, 0xe8, 0x03, 0xb7,
+ 0xdc, 0x03, 0x57, 0xc8, 0x06, 0x5f, 0xd0, 0x0e,
+ 0xef, 0x40, 0x0c, 0xdf, 0x60, 0x1d, 0x9e, 0xa0,
+ 0x18, 0x7f, 0xc0, 0x1c, 0x9f, 0xa0, 0x1c, 0xdf,
+ 0x40, 0x1c, 0xff, 0x20, 0x1c, 0xff, 0x40, 0x1c,
+ 0xbf, 0x80, 0x1c, 0x7f, 0xc0, 0x1e, 0xef, 0x30,
+ 0x0e, 0x9f, 0x90, 0x0e, 0x3f, 0xf0, 0x80, 0x75,
+ 0x7c, 0x80, 0x70, 0xf7, 0xa0, 0x07, 0x2f, 0xf1,
+ 0x00, 0x73, 0xfe, 0x80, 0x79, 0xd4, 0x00,
+
+ /* U+0029 ")" */
+ 0x03, 0x00, 0xea, 0xf4, 0x00, 0xc9, 0xfe, 0x20,
+ 0x0c, 0xff, 0xa0, 0x1d, 0x7f, 0x20, 0x18, 0x7f,
+ 0xc4, 0x01, 0xa7, 0xe4, 0x03, 0x17, 0xf8, 0x03,
+ 0xb7, 0xd0, 0x03, 0x57, 0xb8, 0x06, 0x8f, 0x90,
+ 0x0c, 0xff, 0x40, 0x19, 0xfe, 0x80, 0x34, 0x7c,
+ 0x00, 0x6b, 0xf5, 0x00, 0xdf, 0xe1, 0x00, 0x97,
+ 0xf0, 0x03, 0x67, 0xa8, 0x04, 0xbf, 0x80, 0x10,
+ 0xf7, 0x98, 0x05, 0x9e, 0xe0, 0x15, 0x7c, 0x80,
+ 0x63, 0x90, 0x0e,
+
+ /* U+002A "*" */
+ 0x00, 0xc7, 0xec, 0x01, 0xf8, 0xbd, 0x40, 0x3a,
+ 0xa8, 0x22, 0xf4, 0x09, 0xd0, 0x03, 0xf7, 0x17,
+ 0xdb, 0x7e, 0x44, 0x02, 0x7e, 0xff, 0x48, 0x80,
+ 0x61, 0x8f, 0xfa, 0x48, 0x02, 0x8f, 0xe4, 0xf6,
+ 0xcf, 0xa1, 0x0a, 0x90, 0x1f, 0x40, 0x7c, 0x00,
+ 0xe2, 0xf5, 0x00, 0xfc, 0x7e, 0xc0, 0x18,
+
+ /* U+002B "+" */
+ 0x00, 0xe6, 0xf9, 0x00, 0xff, 0x37, 0xc8, 0x07,
+ 0xf9, 0xbe, 0x40, 0x3f, 0xcd, 0xf2, 0x01, 0xfe,
+ 0x6f, 0x90, 0x0f, 0x7f, 0xff, 0xc6, 0x19, 0x9b,
+ 0x7f, 0xb3, 0x31, 0x00, 0x73, 0x7c, 0x80, 0x7f,
+ 0x9b, 0xe4, 0x03, 0xfc, 0xdf, 0x20, 0x1f, 0xe6,
+ 0xf9, 0x00, 0xff, 0x12, 0x98, 0x07, 0x00,
+
+ /* U+002C "," */
+ 0x00, 0xab, 0xa0, 0x02, 0x2f, 0xf8, 0xc0, 0x2e,
+ 0xff, 0x30, 0x04, 0xbf, 0xe6, 0x00, 0x8b, 0xfc,
+ 0x40, 0x15, 0x7d, 0x80, 0xd7, 0x7e, 0x88, 0x1f,
+ 0xe3, 0x80, 0x40,
+
+ /* U+002D "-" */
+ 0xde, 0xef, 0x0f, 0x7f, 0xf8, 0x40,
+
+ /* U+002E "." */
+ 0x09, 0xd9, 0x05, 0xff, 0x95, 0x5f, 0xf2, 0x85,
+ 0x7d, 0x00,
+
+ /* U+002F "/" */
+ 0x00, 0xff, 0x27, 0xd0, 0x07, 0xfb, 0xb8, 0x20,
+ 0x1f, 0xd3, 0xec, 0x01, 0xfc, 0x7f, 0x60, 0x1f,
+ 0xed, 0xf2, 0x00, 0xfe, 0x7f, 0x70, 0x0f, 0xe2,
+ 0xfd, 0x00, 0xff, 0x5f, 0x98, 0x07, 0xf3, 0x7c,
+ 0x00, 0x7f, 0x0f, 0x70, 0x03, 0xfd, 0x5e, 0x80,
+ 0x1f, 0xc9, 0xf4, 0x01, 0xfe, 0xde, 0x10, 0x0f,
+ 0xe8, 0xf6, 0x00, 0xfe, 0x3f, 0xb0, 0x0f, 0xf6,
+ 0x79, 0x00, 0x7f, 0x3f, 0xb8, 0x07, 0xf8,
+
+ /* U+0030 "0" */
+ 0x00, 0x0c, 0x6f, 0xf5, 0x98, 0x06, 0x1e, 0xff,
+ 0x67, 0x7f, 0x98, 0x02, 0xcf, 0xa0, 0x0a, 0x3f,
+ 0xc4, 0x09, 0xfc, 0x01, 0xd7, 0xf0, 0x13, 0xf0,
+ 0x01, 0xd7, 0xfa, 0x19, 0xe8, 0x01, 0x16, 0xff,
+ 0xc1, 0xde, 0x40, 0x06, 0xff, 0x3f, 0xf8, 0x7f,
+ 0xc2, 0x15, 0xfa, 0x61, 0xde, 0x5d, 0xeb, 0xbf,
+ 0x00, 0x17, 0x78, 0xef, 0xfb, 0x90, 0x03, 0x7f,
+ 0x82, 0xbf, 0x04, 0x03, 0x27, 0xe0, 0x2f, 0xf0,
+ 0x07, 0x5f, 0xb8, 0x03, 0x7e, 0x80, 0x27, 0xfe,
+ 0x10, 0x01, 0xff, 0xd9, 0xdf, 0xe4, 0x00, 0xc5,
+ 0x5d, 0xfd, 0x44, 0x01, 0x00,
+
+ /* U+0031 "1" */
+ 0x00, 0x86, 0x3f, 0xc8, 0x01, 0xcf, 0xff, 0x90,
+ 0x02, 0x3e, 0xff, 0x47, 0xf9, 0x00, 0x37, 0x40,
+ 0x87, 0xf9, 0x00, 0x3f, 0x7f, 0x90, 0x03, 0xf7,
+ 0xf9, 0x00, 0x3f, 0x7f, 0x90, 0x03, 0xf7, 0xf9,
+ 0x00, 0x3f, 0x7f, 0x90, 0x03, 0xf7, 0xf9, 0x00,
+ 0x3f, 0x7f, 0x90, 0x03, 0xf7, 0xf9, 0x00, 0x3f,
+ 0x7f, 0x90, 0x03, 0x6f, 0x75, 0xfe, 0xee, 0xa4,
+ 0x3f, 0xff, 0xac,
+
+ /* U+0032 "2" */
+ 0x00, 0x25, 0x77, 0xf4, 0x88, 0x05, 0x3f, 0xee,
+ 0xe7, 0xfb, 0x84, 0x01, 0x9a, 0x60, 0x02, 0xef,
+ 0xa0, 0x00, 0x80, 0x73, 0x7f, 0x00, 0x7e, 0x3f,
+ 0xf0, 0x07, 0xe5, 0xfd, 0x00, 0xfd, 0x9e, 0xe0,
+ 0x1f, 0x3f, 0xe8, 0x07, 0xcd, 0xfc, 0x40, 0x1e,
+ 0x6f, 0xe3, 0x00, 0xf3, 0xff, 0x18, 0x07, 0xa3,
+ 0xf8, 0x80, 0x3d, 0x3f, 0xa2, 0x01, 0xe4, 0xff,
+ 0xfe, 0xc4, 0xff, 0xfe, 0xd0,
+
+ /* U+0033 "3" */
+ 0x05, 0xbe, 0xff, 0x6c, 0x88, 0x05, 0x5f, 0xb9,
+ 0xbf, 0xee, 0x20, 0x01, 0x00, 0x61, 0xdf, 0xa0,
+ 0x0f, 0xcd, 0xf6, 0x01, 0xfa, 0x3e, 0x00, 0x3c,
+ 0x2f, 0xfa, 0x20, 0x11, 0xff, 0xec, 0x10, 0x0c,
+ 0x55, 0x4c, 0xff, 0x71, 0x80, 0x7e, 0x8f, 0xe1,
+ 0x00, 0xfd, 0x9e, 0xc0, 0x1f, 0xab, 0xdc, 0x03,
+ 0xf7, 0x7a, 0x00, 0x78, 0xaf, 0xf0, 0x07, 0xf7,
+ 0x31, 0xdf, 0xec, 0x10, 0x06, 0xff, 0xdd, 0x6a,
+ 0x01, 0x00,
+
+ /* U+0034 "4" */
+ 0x00, 0xf2, 0x7f, 0xc0, 0x1f, 0xdd, 0xff, 0x00,
+ 0x7e, 0x9f, 0xaf, 0xf0, 0x07, 0xc9, 0xfa, 0x5f,
+ 0xe0, 0x0f, 0xb7, 0xcc, 0xbf, 0xc0, 0x1e, 0x9f,
+ 0x80, 0x2f, 0xf0, 0x07, 0x1f, 0xe8, 0x00, 0xbf,
+ 0xc0, 0x1d, 0xbe, 0x60, 0x02, 0xff, 0x00, 0x68,
+ 0xf8, 0x00, 0x8b, 0xfc, 0x01, 0x1f, 0xe8, 0x06,
+ 0x2f, 0xf0, 0x05, 0x1f, 0xff, 0xf4, 0xb6, 0x67,
+ 0xb7, 0xfd, 0x98, 0x70, 0x0f, 0x8b, 0xfc, 0x01,
+ 0xfe, 0x2f, 0xf0, 0x07, 0xf8, 0xbf, 0xc0, 0x10,
+
+ /* U+0035 "5" */
+ 0xaf, 0xff, 0xa4, 0x2b, 0xf7, 0x33, 0x9c, 0x2b,
+ 0xd0, 0x03, 0xea, 0xf4, 0x00, 0xfa, 0xbd, 0x00,
+ 0x3e, 0xaf, 0xdb, 0xa8, 0x40, 0x0a, 0xbf, 0xfd,
+ 0xa4, 0x01, 0xc4, 0xdb, 0xfa, 0x01, 0xf0, 0xff,
+ 0x90, 0x03, 0xec, 0xf6, 0x00, 0xfb, 0x7d, 0x40,
+ 0x3c, 0x7f, 0xe1, 0x00, 0xe5, 0xef, 0x70, 0xed,
+ 0xcc, 0x77, 0xfa, 0x00, 0x19, 0xff, 0x6c, 0x98,
+ 0x04,
+
+ /* U+0036 "6" */
+ 0x00, 0xc9, 0x5b, 0xfe, 0xd0, 0x08, 0x73, 0xfe,
+ 0xdc, 0xa0, 0x0b, 0x7e, 0x8c, 0x03, 0xd1, 0xf0,
+ 0x01, 0xfb, 0xf8, 0x03, 0xf1, 0xfd, 0x0b, 0x4d,
+ 0x41, 0x80, 0x1b, 0xfb, 0xff, 0xd2, 0x0f, 0xfe,
+ 0x93, 0x01, 0x6f, 0xf3, 0x47, 0xc8, 0x07, 0x3f,
+ 0xe4, 0x7c, 0x80, 0x71, 0xff, 0x9b, 0xf0, 0x03,
+ 0x8f, 0xfc, 0x5f, 0xe1, 0x00, 0xcf, 0xf6, 0x19,
+ 0xf4, 0x01, 0x1f, 0x7a, 0x01, 0x77, 0xf5, 0xe7,
+ 0xf9, 0xc0, 0x22, 0x9e, 0xfe, 0xb4, 0x00, 0x00,
+
+ /* U+0037 "7" */
+ 0xaf, 0xff, 0xeb, 0x9e, 0xef, 0xbf, 0xd6, 0x01,
+ 0xfa, 0xbd, 0xc0, 0x3e, 0x2f, 0xe0, 0x0f, 0xd5,
+ 0xee, 0x01, 0xf1, 0xff, 0x00, 0x7e, 0xbf, 0x70,
+ 0x0f, 0x8f, 0xf8, 0x03, 0xf5, 0xfb, 0x80, 0x7c,
+ 0x7f, 0xe1, 0x00, 0xfa, 0xfe, 0x00, 0x3e, 0x3f,
+ 0xf0, 0x80, 0x7d, 0x7f, 0x00, 0x1f, 0x27, 0xf8,
+ 0x40, 0x3e, 0xcf, 0x80, 0x0f, 0x00,
+
+ /* U+0038 "8" */
+ 0x00, 0x1d, 0x77, 0xfb, 0x1c, 0x02, 0x6f, 0xf6,
+ 0xde, 0x7f, 0xb0, 0x07, 0xfc, 0x80, 0x11, 0x77,
+ 0xa9, 0xff, 0x00, 0x75, 0x7b, 0x17, 0xf8, 0x80,
+ 0x36, 0xfa, 0x05, 0x7f, 0x20, 0x0d, 0xfd, 0x80,
+ 0x55, 0xfe, 0xdf, 0xf4, 0x80, 0x61, 0xcf, 0xfb,
+ 0x94, 0x02, 0x4f, 0xf5, 0x25, 0x7f, 0xa4, 0x07,
+ 0xfc, 0xc0, 0x12, 0xff, 0x95, 0xfe, 0xc0, 0x3a,
+ 0x7e, 0xe7, 0xe8, 0x03, 0x9f, 0xf1, 0xbf, 0xca,
+ 0x01, 0x1f, 0x7c, 0x06, 0x7f, 0xbb, 0x37, 0xfd,
+ 0x80, 0x13, 0x67, 0x7f, 0x5b, 0x00, 0x00,
+
+ /* U+0039 "9" */
+ 0x00, 0x1d, 0x77, 0xf5, 0x10, 0x04, 0xdf, 0xed,
+ 0xbe, 0xff, 0x18, 0x1f, 0xf9, 0x00, 0x27, 0xfd,
+ 0x0a, 0xf8, 0x00, 0xed, 0xf4, 0xcf, 0x50, 0x0e,
+ 0x8f, 0x8c, 0xf7, 0x00, 0xe6, 0xfa, 0x7f, 0xe2,
+ 0x00, 0x86, 0xbe, 0xc3, 0x7f, 0xd9, 0x59, 0xff,
+ 0x50, 0x02, 0x37, 0xfd, 0xaf, 0x1f, 0x20, 0x1f,
+ 0xa7, 0xd8, 0x03, 0xf7, 0x79, 0x00, 0x7d, 0x3f,
+ 0x60, 0x1e, 0x3b, 0xfe, 0x10, 0x05, 0xe6, 0xff,
+ 0xda, 0x40, 0x17, 0x7f, 0x6d, 0x28, 0x06,
+
+ /* U+003A ":" */
+ 0x08, 0xfb, 0x01, 0xff, 0x94, 0x3f, 0xe3, 0x03,
+ 0x84, 0x00, 0xff, 0xe5, 0x1c, 0x20, 0x03, 0xfe,
+ 0x31, 0xff, 0x94, 0x23, 0xec, 0x00,
+
+ /* U+003B ";" */
+ 0x00, 0xa3, 0xec, 0x02, 0x1f, 0xf9, 0x40, 0x2f,
+ 0xf8, 0xc0, 0x23, 0x84, 0x00, 0xff, 0xea, 0x35,
+ 0xb0, 0x06, 0xff, 0x90, 0x02, 0xdf, 0xf4, 0x00,
+ 0x49, 0xfe, 0x80, 0x0d, 0xfe, 0x50, 0x0a, 0x3f,
+ 0x40, 0x15, 0xbf, 0xc4, 0x00, 0xfd, 0x81, 0x00,
+ 0x00,
+
+ /* U+003C "<" */
+ 0x00, 0xf8, 0xec, 0x40, 0x3c, 0xbf, 0xe7, 0x00,
+ 0xe7, 0xff, 0x28, 0x07, 0x57, 0xf1, 0x80, 0x61,
+ 0xcf, 0xc1, 0x00, 0xc5, 0xdf, 0x40, 0x1c, 0x5f,
+ 0xea, 0x00, 0xf9, 0x7f, 0xce, 0x01, 0xf1, 0xf7,
+ 0xd0, 0x07, 0xc3, 0xbf, 0x82, 0x01, 0xf5, 0xff,
+ 0x18, 0x07, 0xd1, 0xfe, 0x50, 0x0f, 0x97, 0x8c,
+ 0x03, 0xfc,
+
+ /* U+003D "=" */
+ 0x5b, 0xbf, 0xe7, 0x77, 0xff, 0xf5, 0x00, 0x7f,
+ 0xf2, 0x96, 0xef, 0xf9, 0xdd, 0xff, 0xfd, 0x40,
+
+ /* U+003E ">" */
+ 0x0a, 0x50, 0x0f, 0x93, 0xfc, 0xe0, 0x1f, 0x1f,
+ 0x7d, 0x00, 0x7c, 0x39, 0xf8, 0x20, 0x1f, 0x57,
+ 0xf1, 0x00, 0x7d, 0x1f, 0xe4, 0x00, 0xf9, 0xff,
+ 0xc8, 0x01, 0xc9, 0xfe, 0x80, 0x0e, 0x7f, 0xf2,
+ 0x80, 0x74, 0xff, 0x18, 0x06, 0x1c, 0xfd, 0x10,
+ 0x0c, 0x5d, 0xf6, 0x01, 0xe1, 0xd8, 0x00, 0xff,
+ 0xe2, 0x80,
+
+ /* U+003F "?" */
+ 0x7e, 0xd9, 0x30, 0x09, 0xbb, 0xfe, 0x90, 0x0e,
+ 0x7e, 0xfa, 0x00, 0xe2, 0xff, 0x20, 0x07, 0x4f,
+ 0xd0, 0x07, 0x3f, 0xe0, 0x07, 0x47, 0xd8, 0x06,
+ 0x5f, 0xf3, 0x02, 0x7f, 0xeb, 0x00, 0x1f, 0xeb,
+ 0x98, 0x04, 0x7f, 0x40, 0x1c, 0x5f, 0x20, 0x1e,
+ 0x53, 0x00, 0xff, 0xe0, 0xb7, 0xe0, 0x07, 0x67,
+ 0xf8, 0xc0, 0x32, 0xf5, 0x80, 0x60,
+
+ /* U+0040 "@" */
+ 0x00, 0xe7, 0xdf, 0xe9, 0x10, 0x0f, 0x16, 0xfd,
+ 0x3c, 0xff, 0x10, 0x06, 0x1d, 0xe3, 0x00, 0x8b,
+ 0xf0, 0x03, 0x57, 0xa0, 0x07, 0x3f, 0xa0, 0x00,
+ 0xbe, 0x80, 0x3c, 0x5f, 0x00, 0x09, 0xf3, 0x00,
+ 0xfb, 0xb0, 0x01, 0xf8, 0x01, 0x33, 0xa3, 0x06,
+ 0x70, 0x1f, 0xb8, 0x0e, 0xff, 0xdc, 0x15, 0xe0,
+ 0xde, 0x81, 0x7e, 0xa7, 0xf8, 0x15, 0xe1, 0x5e,
+ 0x25, 0xf6, 0x07, 0xf2, 0x15, 0xe1, 0x7e, 0x0d,
+ 0xec, 0x0d, 0xee, 0x15, 0xe1, 0x9a, 0x13, 0xe6,
+ 0x11, 0xe8, 0x19, 0xa1, 0xb8, 0x15, 0xe4, 0x15,
+ 0xe4, 0x1d, 0x61, 0xb8, 0x15, 0xe4, 0x1d, 0xe0,
+ 0x5e, 0xe1, 0x9a, 0x11, 0xea, 0xff, 0xe2, 0x9f,
+ 0x20, 0xbf, 0x03, 0xff, 0x9b, 0xfe, 0x80, 0x04,
+ 0xf9, 0x01, 0xb9, 0x82, 0x3a, 0x00, 0x4b, 0xec,
+ 0x01, 0xff, 0xc0, 0xfd, 0x00, 0xff, 0xe0, 0x47,
+ 0xc8, 0x07, 0x10, 0x07, 0xaf, 0xf6, 0x1e, 0x77,
+ 0xc0, 0x3e, 0x7c, 0xff, 0x6c, 0xa0, 0x06,
+
+ /* U+0041 "A" */
+ 0x00, 0xef, 0xf8, 0xc0, 0x3f, 0x93, 0xfe, 0x90,
+ 0x0f, 0xea, 0xf9, 0xfe, 0x00, 0xfe, 0xff, 0x0f,
+ 0x79, 0x80, 0x7c, 0xbf, 0x61, 0x5f, 0x20, 0x1f,
+ 0x57, 0xb0, 0x27, 0xf0, 0x07, 0xdf, 0xe1, 0x00,
+ 0x7f, 0x8c, 0x03, 0x97, 0xf0, 0x02, 0xaf, 0x90,
+ 0x0e, 0xaf, 0x70, 0x09, 0x7f, 0x80, 0x3b, 0xfc,
+ 0x40, 0x1b, 0xfc, 0x60, 0x12, 0xff, 0xff, 0x48,
+ 0x05, 0x7f, 0xdb, 0xbd, 0xdf, 0xc0, 0x17, 0xf8,
+ 0x80, 0x38, 0x7f, 0xc6, 0x0b, 0xf8, 0x01, 0xf5,
+ 0xfc, 0x85, 0xfb, 0x80, 0x7c, 0xbf, 0xc0,
+
+ /* U+0042 "B" */
+ 0x2f, 0xfe, 0xeb, 0x60, 0x01, 0x7f, 0xb3, 0x2e,
+ 0xff, 0x50, 0x17, 0xf8, 0x03, 0x3f, 0xf8, 0xcb,
+ 0xfc, 0x01, 0xdd, 0xea, 0x5f, 0xe0, 0x0e, 0xff,
+ 0x19, 0x7f, 0x80, 0x34, 0x7e, 0x01, 0x7f, 0xae,
+ 0xd9, 0xfe, 0x91, 0x02, 0xff, 0xfb, 0x94, 0x0b,
+ 0xfc, 0x01, 0x1c, 0xff, 0x90, 0xbf, 0xc0, 0x1d,
+ 0x3f, 0x65, 0xfe, 0x00, 0xe5, 0xfd, 0x2f, 0xf0,
+ 0x07, 0x47, 0xe1, 0x7f, 0x80, 0x32, 0x7f, 0x94,
+ 0xbf, 0xd9, 0x97, 0x7f, 0xa4, 0x0b, 0xff, 0xb6,
+ 0x8c, 0x00,
+
+ /* U+0043 "C" */
+ 0x00, 0x8a, 0x77, 0xfd, 0xb2, 0x60, 0x06, 0xff,
+ 0xbb, 0x9f, 0xea, 0x05, 0xff, 0x48, 0x80, 0x48,
+ 0xc1, 0xfe, 0x70, 0x0f, 0x9b, 0xf4, 0x03, 0xf5,
+ 0x7c, 0x00, 0x7e, 0xdf, 0x50, 0x0f, 0xdd, 0xe8,
+ 0x01, 0xfb, 0x7d, 0x40, 0x3f, 0x67, 0xc0, 0x07,
+ 0xe8, 0xfc, 0x00, 0xfc, 0x7f, 0xe5, 0x00, 0xfd,
+ 0x5f, 0xe7, 0x10, 0x09, 0x14, 0x01, 0x7f, 0xf7,
+ 0x73, 0xfd, 0x40, 0x12, 0xd7, 0x7f, 0x6c, 0x98,
+
+ /* U+0044 "D" */
+ 0xbf, 0xfd, 0xd6, 0xe2, 0x01, 0x5f, 0xee, 0x63,
+ 0xbf, 0xdc, 0x80, 0x0b, 0xf5, 0x00, 0x8a, 0xff,
+ 0xc4, 0x17, 0xea, 0x01, 0xd9, 0xf4, 0x17, 0xea,
+ 0x01, 0xc9, 0xfe, 0x0b, 0xf5, 0x00, 0xf7, 0xf8,
+ 0xef, 0xd4, 0x03, 0xdd, 0xe9, 0x7e, 0xa0, 0x1e,
+ 0xdf, 0x5b, 0xf5, 0x00, 0xf7, 0x79, 0xdf, 0xa8,
+ 0x07, 0x0f, 0xf8, 0xaf, 0xd4, 0x03, 0x9b, 0xf4,
+ 0x2f, 0xd4, 0x03, 0x0f, 0x7b, 0x85, 0xfa, 0x80,
+ 0x4b, 0xbf, 0x80, 0x0b, 0xfe, 0xdd, 0x7f, 0xd6,
+ 0x20, 0x0b, 0xff, 0xdb, 0x48, 0x01, 0x80,
+
+ /* U+0045 "E" */
+ 0xaf, 0xff, 0xc3, 0x5f, 0xb9, 0x9e, 0x0a, 0xf7,
+ 0x00, 0xfa, 0xbd, 0xc0, 0x3e, 0xaf, 0x70, 0x0f,
+ 0xab, 0xdc, 0x03, 0xea, 0xfd, 0xcc, 0xe9, 0x0a,
+ 0xff, 0xfb, 0x42, 0xbd, 0xc0, 0x3e, 0xaf, 0x70,
+ 0x0f, 0xab, 0xdc, 0x03, 0xea, 0xf7, 0x00, 0xfa,
+ 0xbd, 0xc0, 0x3e, 0xaf, 0xec, 0xcf, 0x05, 0x7f,
+ 0xfe, 0x10,
+
+ /* U+0046 "F" */
+ 0x9f, 0xff, 0xc1, 0x3f, 0xd9, 0x9e, 0x09, 0xf8,
+ 0x00, 0xfa, 0x7e, 0x00, 0x3e, 0x9f, 0x80, 0x0f,
+ 0xa7, 0xe0, 0x03, 0xe9, 0xfe, 0xcc, 0xe8, 0x09,
+ 0xff, 0xfa, 0xc2, 0x7e, 0x00, 0x3e, 0x9f, 0x80,
+ 0x0f, 0xa7, 0xe0, 0x03, 0xe9, 0xf8, 0x00, 0xfa,
+ 0x7e, 0x00, 0x3e, 0x9f, 0x80, 0x0f, 0xa7, 0xe0,
+ 0x03, 0xe0,
+
+ /* U+0047 "G" */
+ 0x00, 0xc5, 0x3b, 0xfe, 0xda, 0x40, 0x0a, 0x3f,
+ 0xee, 0xe7, 0xfb, 0x00, 0x13, 0xfe, 0x81, 0x00,
+ 0x91, 0xc0, 0xff, 0xc8, 0x01, 0xfa, 0xfe, 0x40,
+ 0x3f, 0xbf, 0xc6, 0x01, 0xf8, 0xbf, 0xc0, 0x11,
+ 0xdd, 0xe9, 0x3f, 0xf0, 0x04, 0xbf, 0xfb, 0x4b,
+ 0xfc, 0x01, 0xe3, 0xfd, 0x1f, 0xf1, 0x00, 0x71,
+ 0xfe, 0x86, 0xfb, 0x80, 0x71, 0xfe, 0x83, 0xff,
+ 0x08, 0x06, 0x3f, 0xd0, 0x06, 0xff, 0x28, 0x04,
+ 0x7f, 0xa0, 0x02, 0xdf, 0xfb, 0xb9, 0xfe, 0xd0,
+ 0x0c, 0xd7, 0xdf, 0xec, 0x83,
+
+ /* U+0048 "H" */
+ 0xbf, 0x60, 0x0e, 0x2f, 0xeb, 0xf6, 0x00, 0xe2,
+ 0xfe, 0xbf, 0x60, 0x0e, 0x2f, 0xeb, 0xf6, 0x00,
+ 0xe2, 0xfe, 0xbf, 0x60, 0x0e, 0x2f, 0xeb, 0xf6,
+ 0x00, 0xe2, 0xfe, 0xbf, 0xec, 0xce, 0xdf, 0xeb,
+ 0xff, 0xfe, 0xeb, 0xf6, 0x00, 0xe2, 0xfe, 0xbf,
+ 0x60, 0x0e, 0x2f, 0xeb, 0xf6, 0x00, 0xe2, 0xfe,
+ 0xbf, 0x60, 0x0e, 0x2f, 0xeb, 0xf6, 0x00, 0xe2,
+ 0xfe, 0xbf, 0x60, 0x0e, 0x2f, 0xeb, 0xf6, 0x00,
+ 0xe2, 0xfe,
+
+ /* U+0049 "I" */
+ 0xff, 0xfe, 0x3c, 0xcb, 0x7f, 0xb3, 0x22, 0x00,
+ 0x9f, 0xe8, 0x03, 0xe7, 0xfa, 0x00, 0xf9, 0xfe,
+ 0x80, 0x3e, 0x7f, 0xa0, 0x0f, 0x9f, 0xe8, 0x03,
+ 0xe7, 0xfa, 0x00, 0xf9, 0xfe, 0x80, 0x3e, 0x7f,
+ 0xa0, 0x0f, 0x9f, 0xe8, 0x03, 0xe7, 0xfa, 0x00,
+ 0xf9, 0xfe, 0x80, 0x36, 0x65, 0xdf, 0xd9, 0x91,
+ 0x7f, 0xff, 0x18,
+
+ /* U+004A "J" */
+ 0xaf, 0xff, 0x92, 0x37, 0x7b, 0xfc, 0x80, 0x1e,
+ 0xdf, 0x40, 0x0f, 0x6f, 0xa0, 0x07, 0xb7, 0xd0,
+ 0x03, 0xdb, 0xe8, 0x01, 0xed, 0xf4, 0x00, 0xf6,
+ 0xfa, 0x00, 0x7b, 0x7d, 0x00, 0x3d, 0xbe, 0x80,
+ 0x1e, 0xef, 0x40, 0x0e, 0x1f, 0xf1, 0x49, 0x80,
+ 0x55, 0xf8, 0x1b, 0xfd, 0xbf, 0xf1, 0x82, 0x5f,
+ 0x7f, 0x51, 0x00, 0x00,
+
+ /* U+004B "K" */
+ 0x2f, 0xe0, 0x0e, 0xdf, 0x90, 0x2f, 0xe0, 0x0d,
+ 0x5f, 0x60, 0x02, 0xfe, 0x00, 0x9f, 0xf4, 0x02,
+ 0x2f, 0xe0, 0x02, 0x7f, 0x08, 0x04, 0x5f, 0xc0,
+ 0x5f, 0xe3, 0x00, 0xc5, 0xfc, 0x1b, 0xea, 0x01,
+ 0xc5, 0xfd, 0x7e, 0xe0, 0x1e, 0x2f, 0xfc, 0x80,
+ 0x1e, 0x2f, 0xe6, 0xfe, 0x20, 0x0e, 0x2f, 0xe0,
+ 0xaf, 0xd0, 0x0e, 0x2f, 0xe0, 0x06, 0xfd, 0x00,
+ 0x62, 0xfe, 0x00, 0x17, 0xf9, 0xc0, 0x22, 0xfe,
+ 0x00, 0x93, 0xfc, 0x80, 0x02, 0xfe, 0x00, 0xd1,
+ 0xfc, 0x40, 0x5f, 0xc0, 0x1d, 0x7f, 0xa0,
+
+ /* U+004C "L" */
+ 0x4f, 0xd0, 0x0f, 0x93, 0xf4, 0x03, 0xe4, 0xfd,
+ 0x00, 0xf9, 0x3f, 0x40, 0x3e, 0x4f, 0xd0, 0x0f,
+ 0x93, 0xf4, 0x03, 0xe4, 0xfd, 0x00, 0xf9, 0x3f,
+ 0x40, 0x3e, 0x4f, 0xd0, 0x0f, 0x93, 0xf4, 0x03,
+ 0xe4, 0xfd, 0x00, 0xf9, 0x3f, 0x40, 0x3e, 0x4f,
+ 0xd0, 0x0f, 0x93, 0xfd, 0x99, 0xe6, 0x4f, 0xff,
+ 0xd0,
+
+ /* U+004D "M" */
+ 0x0b, 0xff, 0x00, 0x76, 0xff, 0x00, 0x2f, 0xfc,
+ 0xa0, 0x11, 0xff, 0xc0, 0x0c, 0xef, 0xb0, 0x0a,
+ 0x7f, 0x7c, 0x01, 0xba, 0xbf, 0x10, 0x07, 0xd6,
+ 0x78, 0x03, 0xb5, 0x7d, 0xc1, 0xbd, 0x33, 0xc4,
+ 0x3f, 0x43, 0xf0, 0x33, 0x82, 0xfc, 0x83, 0xf0,
+ 0x2b, 0xd3, 0xe0, 0x2f, 0xcc, 0x3f, 0x01, 0x3f,
+ 0xbc, 0x82, 0xbd, 0x07, 0xec, 0x01, 0xbf, 0x80,
+ 0x0a, 0xf4, 0x2f, 0xb0, 0x03, 0xfb, 0x00, 0x27,
+ 0xd4, 0xfe, 0x80, 0x21, 0x00, 0xa7, 0xd8, 0xfe,
+ 0x80, 0x3e, 0x8f, 0x74, 0xf9, 0x00, 0xfa, 0x3e,
+ 0x17, 0xe4, 0x03, 0xe7, 0xf8, 0x6f, 0x80, 0x0f,
+ 0x9f, 0xe4,
+
+ /* U+004E "N" */
+ 0x9f, 0xf2, 0x80, 0x62, 0xfd, 0x9f, 0xf6, 0x00,
+ 0x62, 0xfd, 0x9f, 0xf9, 0x00, 0x22, 0xfd, 0x9f,
+ 0xaf, 0xc0, 0x08, 0xbf, 0x67, 0xd7, 0x7c, 0xc0,
+ 0x05, 0xfb, 0x3e, 0xaf, 0xf6, 0x00, 0x2f, 0xd9,
+ 0xf5, 0x0e, 0xf3, 0x02, 0xfd, 0x9f, 0x50, 0x7f,
+ 0xa0, 0x2f, 0xd9, 0xf5, 0x01, 0xff, 0x11, 0x3f,
+ 0x67, 0xd4, 0x01, 0x1f, 0x25, 0xfb, 0x3e, 0xa0,
+ 0x01, 0xff, 0x1f, 0xec, 0xfa, 0x80, 0x53, 0xf5,
+ 0xfb, 0x3e, 0xa0, 0x10, 0xff, 0xdb, 0x3e, 0xa0,
+ 0x1a, 0xbf, 0xdb, 0x3e, 0xa0, 0x18, 0xbf, 0xda,
+
+ /* U+004F "O" */
+ 0x00, 0x86, 0x77, 0xfa, 0xd4, 0x03, 0x8f, 0xbf,
+ 0xdb, 0xff, 0x48, 0x04, 0x3d, 0xf2, 0x20, 0x06,
+ 0xff, 0x30, 0x02, 0x3f, 0x00, 0x39, 0xff, 0x80,
+ 0x1d, 0xe8, 0x01, 0xef, 0xf1, 0x97, 0xf8, 0x03,
+ 0xec, 0xf6, 0x4f, 0xf0, 0x07, 0xd7, 0xee, 0xbf,
+ 0xa0, 0x1f, 0x57, 0xc2, 0x7f, 0x00, 0x7d, 0x7e,
+ 0xe7, 0xfe, 0x00, 0xfb, 0x7d, 0x43, 0xfc, 0x80,
+ 0x1c, 0x5f, 0xe2, 0x0b, 0xfa, 0x00, 0xe9, 0xfc,
+ 0x00, 0x1f, 0xfa, 0x00, 0x27, 0xff, 0x18, 0x04,
+ 0xff, 0xf6, 0xff, 0xcc, 0x01, 0xc7, 0x5d, 0xfd,
+ 0x44, 0x01, 0x00,
+
+ /* U+0050 "P" */
+ 0x2f, 0xfe, 0xea, 0x40, 0x01, 0x7f, 0xb3, 0x2f,
+ 0xfa, 0x40, 0xbf, 0xc0, 0x19, 0xbf, 0xcc, 0x5f,
+ 0xe0, 0x0e, 0x9f, 0xc2, 0xff, 0x00, 0x72, 0xff,
+ 0x17, 0xf8, 0x03, 0x9b, 0xf0, 0xbf, 0xc0, 0x1d,
+ 0x7f, 0x05, 0xfe, 0x00, 0x09, 0xdf, 0xf0, 0x97,
+ 0xff, 0xda, 0x40, 0x5f, 0xec, 0xc5, 0xca, 0x80,
+ 0x45, 0xfe, 0x00, 0xfc, 0x5f, 0xe0, 0x0f, 0xc5,
+ 0xfe, 0x00, 0xfc, 0x5f, 0xe0, 0x0f, 0xc5, 0xfe,
+ 0x00, 0xfc,
+
+ /* U+0051 "Q" */
+ 0x00, 0x86, 0x37, 0xfa, 0xd4, 0x03, 0xc5, 0xdf,
+ 0xee, 0xff, 0xa4, 0x03, 0xb7, 0xe8, 0x40, 0x0f,
+ 0xfe, 0x50, 0x09, 0xff, 0x40, 0x3a, 0x3f, 0x40,
+ 0x2d, 0xf5, 0x00, 0xe1, 0xff, 0x10, 0x0f, 0xf8,
+ 0x40, 0x3d, 0xbe, 0xa0, 0x7f, 0xe0, 0x0f, 0xaf,
+ 0xdc, 0x13, 0xf4, 0x03, 0xea, 0xf8, 0x04, 0xfd,
+ 0x00, 0xfa, 0xbe, 0x01, 0x3f, 0xc0, 0x1f, 0x67,
+ 0xb0, 0x17, 0xf8, 0x40, 0x3d, 0xde, 0x60, 0x0e,
+ 0xf6, 0x00, 0xe3, 0xff, 0x00, 0x53, 0xfa, 0x01,
+ 0xd9, 0xf2, 0x01, 0x0f, 0x7e, 0x20, 0x9d, 0xff,
+ 0x08, 0x06, 0x3e, 0xff, 0xed, 0x20, 0x0f, 0x0b,
+ 0xef, 0xe3, 0x00, 0x7f, 0x9b, 0xec, 0x03, 0xfe,
+ 0x1f, 0xf3, 0x88, 0x95, 0x80, 0x3e, 0x5f, 0xfe,
+ 0xe0, 0x0f, 0xc5, 0x37, 0x68, 0x20,
+
+ /* U+0052 "R" */
+ 0xff, 0xee, 0xa3, 0x00, 0xbf, 0xd9, 0x8d, 0xff,
+ 0x94, 0x01, 0xfe, 0x10, 0x0a, 0xbf, 0x80, 0x1f,
+ 0xe1, 0x00, 0x87, 0xfc, 0x21, 0xfe, 0x10, 0x08,
+ 0xbf, 0xc0, 0x0f, 0xf0, 0x80, 0x06, 0xfe, 0x80,
+ 0x1f, 0xeb, 0xac, 0xff, 0x60, 0x80, 0x3f, 0xfc,
+ 0xc0, 0x1b, 0xfc, 0x20, 0xff, 0xe2, 0x00, 0xbf,
+ 0xc2, 0x00, 0x9f, 0xb0, 0x0b, 0xfc, 0x20, 0x01,
+ 0xff, 0x18, 0x03, 0xfc, 0x20, 0x15, 0x7d, 0x00,
+ 0x3f, 0xc2, 0x01, 0x17, 0xf8, 0x83, 0xfc, 0x20,
+ 0x1a, 0xfe, 0x43, 0xfc, 0x20, 0x19, 0x3f, 0xc2,
+
+ /* U+0053 "S" */
+ 0x00, 0x14, 0xef, 0xfb, 0xb1, 0x80, 0x0d, 0xff,
+ 0x6e, 0xbb, 0xec, 0x0b, 0xfc, 0xe0, 0x18, 0x48,
+ 0x1f, 0xf0, 0x03, 0xf3, 0xfe, 0x80, 0x7e, 0x2f,
+ 0xf5, 0x08, 0x07, 0xc9, 0xdf, 0xe9, 0x30, 0x0f,
+ 0x0c, 0x77, 0xfb, 0x54, 0x03, 0xe5, 0xcf, 0xf4,
+ 0x80, 0x7e, 0x5f, 0xf2, 0x80, 0x7e, 0x9f, 0xa0,
+ 0x0f, 0xd5, 0xf2, 0x86, 0x01, 0xcd, 0xfe, 0x4b,
+ 0xff, 0x76, 0xf7, 0xfd, 0x00, 0xd7, 0xbf, 0xee,
+ 0xc9, 0x30, 0x00,
+
+ /* U+0054 "T" */
+ 0xff, 0xff, 0x8f, 0x33, 0x77, 0xf6, 0x66, 0x20,
+ 0x0c, 0xff, 0x40, 0x1f, 0xcf, 0xf4, 0x01, 0xfc,
+ 0xff, 0x40, 0x1f, 0xcf, 0xf4, 0x01, 0xfc, 0xff,
+ 0x40, 0x1f, 0xcf, 0xf4, 0x01, 0xfc, 0xff, 0x40,
+ 0x1f, 0xcf, 0xf4, 0x01, 0xfc, 0xff, 0x40, 0x1f,
+ 0xcf, 0xf4, 0x01, 0xfc, 0xff, 0x40, 0x1f, 0xcf,
+ 0xf4, 0x01, 0xfc, 0xff, 0x40, 0x1c,
+
+ /* U+0055 "U" */
+ 0xbf, 0x50, 0x0e, 0x2f, 0xf5, 0xfa, 0x80, 0x71,
+ 0x7f, 0xaf, 0xd4, 0x03, 0x8b, 0xfd, 0x7e, 0xa0,
+ 0x1c, 0x5f, 0xeb, 0xf5, 0x00, 0xe2, 0xff, 0x5f,
+ 0xa8, 0x07, 0x17, 0xfa, 0xfd, 0x40, 0x38, 0xbf,
+ 0xd7, 0xea, 0x01, 0xc5, 0xfe, 0xbf, 0x50, 0x0e,
+ 0x2f, 0xf5, 0xfa, 0x80, 0x71, 0x7f, 0x57, 0xb8,
+ 0x07, 0x27, 0xec, 0x7d, 0x00, 0x74, 0x7d, 0x1f,
+ 0xf9, 0x40, 0x24, 0xff, 0x20, 0x4f, 0xfb, 0xb3,
+ 0xbf, 0xd0, 0x01, 0x2d, 0xf7, 0xf5, 0xa0, 0x00,
+
+ /* U+0056 "V" */
+ 0xcf, 0x90, 0x0f, 0x8f, 0xfc, 0x0f, 0xfc, 0x01,
+ 0xf4, 0xfd, 0x00, 0xff, 0x8c, 0x03, 0xdd, 0xe8,
+ 0x00, 0xcf, 0x80, 0x0e, 0x3f, 0xe0, 0x09, 0xbf,
+ 0x40, 0x3a, 0x3e, 0x40, 0x21, 0xff, 0x18, 0x06,
+ 0xef, 0x30, 0x0d, 0x7f, 0x00, 0x11, 0xff, 0x00,
+ 0x73, 0x7e, 0x80, 0x51, 0xf0, 0x01, 0xc3, 0xfe,
+ 0x20, 0x06, 0xf9, 0x80, 0x7a, 0xfe, 0x00, 0xff,
+ 0x40, 0x3e, 0x6f, 0xd0, 0x8f, 0x80, 0x0f, 0x87,
+ 0xfc, 0x5b, 0xe4, 0x01, 0xfa, 0xfe, 0xbf, 0x40,
+ 0x3f, 0x97, 0xfe, 0x70, 0x0f, 0xf7, 0xfc, 0x40,
+ 0x1c,
+
+ /* U+0057 "W" */
+ 0x7f, 0x80, 0x0f, 0x8f, 0xe9, 0x7e, 0x40, 0x3e,
+ 0x4f, 0x94, 0xfa, 0x00, 0xf9, 0x7d, 0xcf, 0xec,
+ 0x03, 0xe6, 0xf6, 0x2f, 0xc0, 0x0f, 0x9f, 0xd4,
+ 0x7f, 0x40, 0x09, 0xcc, 0x00, 0x7f, 0x40, 0xfe,
+ 0x00, 0x4f, 0xe0, 0x02, 0x3c, 0xc3, 0xf8, 0x01,
+ 0xdf, 0xe2, 0x09, 0xf2, 0x0e, 0xf0, 0x4f, 0xaf,
+ 0x80, 0xaf, 0x10, 0xcf, 0x09, 0xf1, 0xfe, 0x0b,
+ 0xf0, 0x05, 0xf9, 0x75, 0x85, 0x79, 0xe7, 0x80,
+ 0x2b, 0xdb, 0xd8, 0x17, 0xe7, 0x78, 0x01, 0x3f,
+ 0x9e, 0x20, 0x0e, 0xfd, 0xc0, 0x04, 0x7f, 0xac,
+ 0x02, 0x9f, 0xf5, 0x80, 0x1f, 0xfc, 0xa0, 0x11,
+ 0xff, 0xa8, 0x00,
+
+ /* U+0058 "X" */
+ 0x1f, 0xf3, 0x00, 0x71, 0xff, 0x8c, 0x1b, 0xf8,
+ 0x40, 0x36, 0x7c, 0x00, 0x59, 0xf4, 0x01, 0x3f,
+ 0xe8, 0x06, 0x2f, 0xf2, 0x00, 0xff, 0x90, 0x03,
+ 0x9f, 0xf4, 0x2f, 0xe4, 0x03, 0xed, 0xfb, 0xfe,
+ 0x00, 0xfc, 0x7f, 0xf2, 0x00, 0x7f, 0x6f, 0xf8,
+ 0x40, 0x3f, 0x3f, 0xfd, 0x40, 0x1f, 0x17, 0xf9,
+ 0x7f, 0xca, 0x01, 0xec, 0xf9, 0x07, 0xfe, 0x10,
+ 0x0c, 0xff, 0xc0, 0x16, 0xfd, 0x00, 0x45, 0xfe,
+ 0x50, 0x09, 0x3f, 0xc8, 0x00, 0xcf, 0xb0, 0x0e,
+ 0xaf, 0xe0, 0x7f, 0xf1, 0x00, 0x70, 0xf7, 0xc8,
+
+ /* U+0059 "Y" */
+ 0xbf, 0xc0, 0x0f, 0x9f, 0xf8, 0x0b, 0xfc, 0xa0,
+ 0x1c, 0x3d, 0xea, 0x00, 0x8f, 0xe0, 0x0e, 0x8f,
+ 0xc0, 0x0d, 0xde, 0xe0, 0x10, 0xff, 0x8c, 0x03,
+ 0x37, 0xf8, 0x40, 0x15, 0xf2, 0x01, 0xec, 0xf9,
+ 0x02, 0xff, 0x08, 0x07, 0x8f, 0xfc, 0x37, 0xee,
+ 0x01, 0xfa, 0xbf, 0x3f, 0x40, 0x3f, 0x87, 0xfe,
+ 0x40, 0x0f, 0xf4, 0x7e, 0x00, 0x7f, 0xcf, 0xf4,
+ 0x01, 0xff, 0x3f, 0xd0, 0x07, 0xfc, 0xff, 0x40,
+ 0x1f, 0xf3, 0xfd, 0x00, 0x7f, 0xcf, 0xf4, 0x01,
+ 0xe0,
+
+ /* U+005A "Z" */
+ 0x7f, 0xff, 0xeb, 0x7e, 0xef, 0xbf, 0xd6, 0x01,
+ 0xf1, 0xff, 0x88, 0x03, 0xed, 0xf7, 0x00, 0xfa,
+ 0x7f, 0x00, 0x3e, 0x4f, 0xf1, 0x00, 0x78, 0x7b,
+ 0xd8, 0x03, 0xea, 0xfb, 0x00, 0xf9, 0x7f, 0x84,
+ 0x03, 0xc3, 0xde, 0xa0, 0x1f, 0x5f, 0xd0, 0x07,
+ 0xcd, 0xfc, 0x20, 0x1e, 0x1f, 0xf2, 0x00, 0x7d,
+ 0x5f, 0xff, 0xdb, 0x7f, 0xff, 0xdc,
+
+ /* U+005B "[" */
+ 0xff, 0xed, 0xff, 0x55, 0x51, 0xfe, 0x00, 0xdf,
+ 0xe0, 0x0d, 0xfe, 0x00, 0xdf, 0xe0, 0x0d, 0xfe,
+ 0x00, 0xdf, 0xe0, 0x0d, 0xfe, 0x00, 0xdf, 0xe0,
+ 0x0d, 0xfe, 0x00, 0xdf, 0xe0, 0x0d, 0xfe, 0x00,
+ 0xdf, 0xe0, 0x0d, 0xfe, 0x00, 0xdf, 0xe0, 0x0d,
+ 0xfe, 0x00, 0xdf, 0xe0, 0x0d, 0xfe, 0x00, 0xdf,
+ 0xe0, 0x0d, 0xfe, 0xaa, 0xa3, 0xff, 0xb4,
+
+ /* U+005C "\\" */
+ 0x0e, 0xf1, 0x00, 0xfc, 0xfe, 0xe0, 0x1f, 0x87,
+ 0xf4, 0x03, 0xfa, 0xbd, 0x00, 0x3f, 0x1f, 0xd8,
+ 0x07, 0xf6, 0x79, 0x00, 0x7e, 0x6f, 0x90, 0x0f,
+ 0xee, 0xf0, 0x0f, 0xe8, 0xf6, 0x00, 0xfc, 0x3f,
+ 0xa0, 0x1f, 0xd5, 0xe8, 0x01, 0xf9, 0x3e, 0xc0,
+ 0x3f, 0xb7, 0xc4, 0x03, 0xf3, 0x7c, 0x00, 0x7f,
+ 0x7f, 0x00, 0x7f, 0x4f, 0xb0, 0x07, 0xe2, 0xfc,
+ 0x00, 0xfe, 0xbf, 0x30, 0x0f, 0xc9, 0xf4,
+
+ /* U+005D "]" */
+ 0xaf, 0xfe, 0x26, 0xaa, 0xbb, 0xc8, 0x03, 0x6f,
+ 0x90, 0x06, 0xdf, 0x20, 0x0d, 0xbe, 0x40, 0x1b,
+ 0x7c, 0x80, 0x36, 0xf9, 0x00, 0x6d, 0xf2, 0x00,
+ 0xdb, 0xe4, 0x01, 0xb7, 0xc8, 0x03, 0x6f, 0x90,
+ 0x06, 0xdf, 0x20, 0x0d, 0xbe, 0x40, 0x1b, 0x7c,
+ 0x80, 0x36, 0xf9, 0x00, 0x6d, 0xf2, 0x00, 0xdb,
+ 0xe4, 0x01, 0xb7, 0xc8, 0x03, 0x6f, 0x90, 0x06,
+ 0xdf, 0x26, 0xaa, 0xbb, 0xca, 0xbf, 0xf8, 0x80,
+
+ /* U+005E "^" */
+ 0x00, 0xc7, 0x08, 0x01, 0xfb, 0x7f, 0x84, 0x03,
+ 0xcf, 0xf3, 0xf2, 0x01, 0xc3, 0xd6, 0x19, 0xe6,
+ 0x01, 0xa7, 0xc8, 0x0f, 0xf0, 0x02, 0x2f, 0x90,
+ 0x0a, 0x7d, 0x80, 0x17, 0xe2, 0x01, 0x0f, 0xf0,
+ 0xa7, 0xc0, 0x07, 0x3f, 0xc8,
+
+ /* U+005F "_" */
+ 0xbb, 0xff, 0xe0, 0x97, 0xff, 0xff, 0x04, 0xc0,
+
+ /* U+0060 "`" */
+ 0x0a, 0xa1, 0x07, 0xf8, 0x83, 0xfc, 0x21, 0xde,
+ 0x00, 0xdf, 0x00, 0x67, 0x00,
+
+ /* U+0061 "a" */
+ 0x02, 0x8c, 0xef, 0xec, 0x50, 0x09, 0xff, 0xdb,
+ 0x9d, 0xfe, 0x80, 0x01, 0xa0, 0x06, 0x6f, 0xf0,
+ 0x80, 0x7e, 0xdf, 0x30, 0x0f, 0xd9, 0xe8, 0x00,
+ 0x5b, 0xef, 0xfe, 0x40, 0xaf, 0xf5, 0xcc, 0xdd,
+ 0xe8, 0x7f, 0xe2, 0x00, 0xd9, 0xe8, 0xdf, 0x80,
+ 0x1d, 0xbe, 0x88, 0xfe, 0x10, 0x01, 0xef, 0xf9,
+ 0x03, 0x7f, 0xaf, 0x7f, 0x6f, 0xd0, 0x06, 0xbb,
+ 0xf6, 0x02, 0x7d, 0x00,
+
+ /* U+0062 "b" */
+ 0x2f, 0xe0, 0x0f, 0xc5, 0xfc, 0x01, 0xf8, 0xbf,
+ 0x80, 0x3f, 0x17, 0xf0, 0x07, 0xe2, 0xfe, 0x00,
+ 0xfc, 0x5f, 0xc0, 0xb9, 0xfd, 0x22, 0x05, 0xfb,
+ 0x3f, 0xed, 0xff, 0x60, 0x17, 0xfd, 0x20, 0x02,
+ 0xef, 0x52, 0xff, 0x40, 0x06, 0x8f, 0xa2, 0xfe,
+ 0x00, 0xe4, 0xfd, 0x2f, 0xe0, 0x0e, 0x3f, 0xe2,
+ 0xfe, 0x00, 0xe3, 0xfe, 0x2f, 0xe0, 0x0e, 0x5f,
+ 0xc2, 0xfe, 0x00, 0xea, 0xf7, 0x2f, 0xe0, 0x0c,
+ 0xdf, 0xc2, 0x5f, 0xf5, 0xdb, 0x7f, 0xc6, 0x00,
+ 0x5a, 0xdf, 0xf6, 0xc8, 0x80, 0x00,
+
+ /* U+0063 "c" */
+ 0x00, 0x8a, 0x77, 0xfd, 0xb2, 0x01, 0x27, 0xfd,
+ 0x9b, 0xfe, 0x00, 0x17, 0xfa, 0x40, 0x32, 0x00,
+ 0x2b, 0xec, 0x03, 0xf7, 0xf8, 0xc0, 0x3e, 0x1f,
+ 0xf0, 0x07, 0xe1, 0xff, 0x00, 0x7f, 0x7f, 0x88,
+ 0x03, 0xf6, 0x7c, 0x00, 0x7e, 0x5f, 0xf3, 0x00,
+ 0x64, 0x00, 0xa7, 0xfe, 0xcd, 0xff, 0x00, 0x64,
+ 0xbe, 0xfe, 0xc8, 0x00,
+
+ /* U+0064 "d" */
+ 0x00, 0xfd, 0x9e, 0x80, 0x1f, 0xb3, 0xd0, 0x03,
+ 0xf6, 0x7a, 0x00, 0x7e, 0xcf, 0x40, 0x0f, 0xd9,
+ 0xe8, 0x01, 0x3e, 0xff, 0xb7, 0xfc, 0x80, 0x5b,
+ 0xfd, 0x79, 0xdf, 0xe4, 0x0c, 0xf9, 0x00, 0xd9,
+ 0xe8, 0x8f, 0xd0, 0x0e, 0xcf, 0x48, 0xf8, 0x00,
+ 0xec, 0xf4, 0xaf, 0x60, 0x0e, 0xcf, 0x4a, 0xf5,
+ 0x00, 0xec, 0xf4, 0x9f, 0x70, 0x0e, 0xdf, 0x47,
+ 0xfa, 0x00, 0xcd, 0xfe, 0x42, 0xff, 0x10, 0x01,
+ 0x7f, 0xe4, 0x09, 0xfe, 0x9b, 0xfa, 0xa7, 0xa0,
+ 0x01, 0xfb, 0xf5, 0x82, 0x7d, 0x00,
+
+ /* U+0065 "e" */
+ 0x00, 0xa3, 0x7f, 0xad, 0x00, 0x21, 0xdf, 0xea,
+ 0xcf, 0xf3, 0x80, 0x2f, 0xe4, 0x02, 0x4f, 0xf1,
+ 0x97, 0xf0, 0x07, 0x47, 0xc3, 0xfc, 0x80, 0x72,
+ 0xfd, 0xcf, 0xff, 0xf6, 0x4f, 0xe4, 0xcf, 0xcf,
+ 0x1f, 0x40, 0x1f, 0x93, 0xf8, 0x03, 0xfb, 0x7e,
+ 0xc4, 0x03, 0xe3, 0xef, 0xf6, 0xde, 0x6f, 0x98,
+ 0x00, 0x63, 0x7f, 0xdd, 0x92, 0x20,
+
+ /* U+0066 "f" */
+ 0x00, 0xf1, 0xd7, 0x7f, 0xb4, 0xc0, 0x39, 0x3f,
+ 0xdd, 0x79, 0xca, 0x01, 0xdb, 0xf2, 0x01, 0xfc,
+ 0x5f, 0xe0, 0x0f, 0xf2, 0x7e, 0x80, 0x7f, 0x93,
+ 0xf0, 0x03, 0xfc, 0x9f, 0x80, 0x1e, 0x1f, 0xff,
+ 0xf8, 0x01, 0x77, 0x67, 0xfa, 0xef, 0x50, 0x07,
+ 0x27, 0xe0, 0x07, 0xf9, 0x3f, 0x00, 0x3f, 0xc9,
+ 0xf8, 0x01, 0xfe, 0x4f, 0xc0, 0x0f, 0xf2, 0x7e,
+ 0x00, 0x7f, 0x93, 0xf0, 0x03, 0xfc, 0x9f, 0x80,
+ 0x1f, 0xe4, 0xfc, 0x00, 0xf0,
+
+ /* U+0067 "g" */
+ 0x00, 0x15, 0x77, 0xff, 0x8c, 0x0f, 0xfd, 0x73,
+ 0x9f, 0xee, 0xe1, 0x86, 0xfb, 0x80, 0x51, 0xf4,
+ 0x00, 0x1f, 0xf0, 0x06, 0x1f, 0xf0, 0x00, 0xbf,
+ 0xc0, 0x18, 0x7f, 0xc0, 0x16, 0xfb, 0x00, 0x53,
+ 0xf6, 0x01, 0x37, 0xfa, 0xe7, 0x3f, 0x88, 0x02,
+ 0xdf, 0xae, 0xfe, 0x91, 0x00, 0x93, 0xe4, 0x03,
+ 0xf9, 0xbe, 0xc0, 0x3f, 0x8b, 0xfd, 0xd9, 0x9a,
+ 0x50, 0x02, 0x9f, 0xff, 0xd0, 0x0d, 0xfa, 0x20,
+ 0x10, 0xbf, 0xf8, 0x77, 0xd4, 0x03, 0xdf, 0xe2,
+ 0xdf, 0x90, 0x0e, 0x8f, 0xd0, 0x6f, 0xf7, 0x5d,
+ 0x5f, 0x7f, 0x18, 0x00, 0xeb, 0x7f, 0xdd, 0x90,
+ 0x20, 0x00,
+
+ /* U+0068 "h" */
+ 0x2f, 0xe0, 0x0f, 0xc5, 0xfc, 0x01, 0xf8, 0xbf,
+ 0x80, 0x3f, 0x17, 0xf0, 0x07, 0xe2, 0xfe, 0x00,
+ 0xfc, 0x5f, 0xc0, 0xdb, 0xfd, 0x00, 0x02, 0xfd,
+ 0x9f, 0xec, 0xff, 0x50, 0x17, 0xfd, 0x00, 0x04,
+ 0xff, 0x09, 0x7f, 0xa0, 0x03, 0x6f, 0xa1, 0x7f,
+ 0x00, 0x75, 0xfa, 0x97, 0xf0, 0x07, 0x5f, 0xa9,
+ 0x7f, 0x00, 0x75, 0xfa, 0x97, 0xf0, 0x07, 0x5f,
+ 0xa9, 0x7f, 0x00, 0x75, 0xfa, 0x97, 0xf0, 0x07,
+ 0x5f, 0xa9, 0x7f, 0x00, 0x75, 0xfa, 0x97, 0xf0,
+ 0x07, 0x5f, 0xa8,
+
+ /* U+0069 "i" */
+ 0x00, 0x9f, 0xe8, 0x03, 0xef, 0xf8, 0x80, 0x3d,
+ 0x5f, 0xa0, 0x1f, 0x88, 0x03, 0xff, 0x87, 0x3f,
+ 0xfc, 0x01, 0x9a, 0xee, 0xff, 0x00, 0x7c, 0x3f,
+ 0xe0, 0x0f, 0x87, 0xfc, 0x01, 0xf0, 0xff, 0x80,
+ 0x3e, 0x1f, 0xf0, 0x07, 0xc3, 0xfe, 0x00, 0xf8,
+ 0x7f, 0xc0, 0x1f, 0x0f, 0xf8, 0x03, 0xe1, 0xff,
+ 0x00, 0x6b, 0xbd, 0xfe, 0xbb, 0x97, 0xff, 0xf9,
+ 0xc0,
+
+ /* U+006A "j" */
+ 0x00, 0xf3, 0xfd, 0x00, 0x7d, 0xff, 0x10, 0x07,
+ 0xab, 0xf4, 0x03, 0xf1, 0x00, 0x7f, 0xf0, 0x7f,
+ 0xfe, 0xd0, 0x05, 0x5d, 0xec, 0xfd, 0x00, 0xf8,
+ 0xff, 0x40, 0x3e, 0x3f, 0xd0, 0x0f, 0x8f, 0xf4,
+ 0x03, 0xe3, 0xfd, 0x00, 0xf8, 0xff, 0x40, 0x3e,
+ 0x3f, 0xd0, 0x0f, 0x8f, 0xf4, 0x03, 0xe3, 0xfd,
+ 0x00, 0xf8, 0xff, 0x40, 0x3e, 0x3f, 0xd0, 0x0f,
+ 0x93, 0xf0, 0x03, 0xe8, 0xf9, 0x03, 0x20, 0x08,
+ 0xff, 0xc8, 0x0f, 0xfd, 0x9b, 0xfe, 0x90, 0x01,
+ 0xdf, 0x7f, 0xb1, 0x40, 0x20,
+
+ /* U+006B "k" */
+ 0xdf, 0x20, 0x0f, 0xdb, 0xe4, 0x01, 0xfb, 0x7c,
+ 0x80, 0x3f, 0x6f, 0x90, 0x07, 0xed, 0xf2, 0x00,
+ 0xfd, 0xbe, 0x40, 0x11, 0x77, 0xd0, 0x6f, 0x90,
+ 0x00, 0x7b, 0xe8, 0x01, 0xbe, 0x40, 0x3b, 0xf4,
+ 0x01, 0x6f, 0x90, 0xef, 0xd0, 0x06, 0xdf, 0x3d,
+ 0xfa, 0x00, 0xed, 0xfc, 0xfd, 0x00, 0xf6, 0xfa,
+ 0x77, 0xc0, 0x07, 0x6f, 0x91, 0xff, 0x98, 0x03,
+ 0x6f, 0x90, 0x2f, 0xf9, 0x40, 0x2d, 0xf2, 0x00,
+ 0x3f, 0xf8, 0xc0, 0x1b, 0xe4, 0x01, 0x4f, 0xf1,
+ 0x06, 0xf9, 0x00, 0x6b, 0xfe, 0x10,
+
+ /* U+006C "l" */
+ 0x9f, 0xfe, 0x00, 0xcd, 0x54, 0xbf, 0xf0, 0x07,
+ 0xc3, 0xfe, 0x00, 0xf8, 0x7f, 0xc0, 0x1f, 0x0f,
+ 0xf8, 0x03, 0xe1, 0xff, 0x00, 0x7c, 0x3f, 0xe0,
+ 0x0f, 0x87, 0xfc, 0x01, 0xf0, 0xff, 0x80, 0x3e,
+ 0x1f, 0xf0, 0x07, 0xc3, 0xfe, 0x00, 0xf8, 0x7f,
+ 0xc0, 0x1f, 0x0f, 0xf8, 0x03, 0xe1, 0xff, 0x00,
+ 0x7c, 0x3f, 0xe0, 0x0d, 0x77, 0xbf, 0xd7, 0x72,
+ 0xff, 0xff, 0x38,
+
+ /* U+006D "m" */
+ 0xfa, 0x2c, 0xf8, 0x06, 0xed, 0x30, 0xfb, 0xdb,
+ 0xdf, 0x6f, 0x9f, 0xd0, 0xff, 0x68, 0x37, 0xf9,
+ 0x83, 0x3c, 0x3f, 0xc8, 0x0b, 0xfc, 0x00, 0xbf,
+ 0x2f, 0xf0, 0x01, 0x7e, 0x00, 0x17, 0xe5, 0xfe,
+ 0x00, 0x2f, 0xc0, 0x02, 0xfc, 0xbf, 0xc0, 0x05,
+ 0xf8, 0x00, 0x5f, 0x97, 0xf8, 0x00, 0xbf, 0x00,
+ 0x0b, 0xf2, 0xff, 0x00, 0x17, 0xe0, 0x01, 0x7e,
+ 0x5f, 0xe0, 0x02, 0xfc, 0x00, 0x2f, 0xcb, 0xfc,
+ 0x00, 0x5f, 0x80, 0x05, 0xf9, 0x7f, 0x80, 0x0b,
+ 0xf0, 0x00, 0xbf, 0x20,
+
+ /* U+006E "n" */
+ 0x2f, 0xb0, 0x7d, 0xfe, 0x90, 0x01, 0x7e, 0x5f,
+ 0xdc, 0xf7, 0xd0, 0x17, 0xfc, 0xa0, 0x02, 0xff,
+ 0x09, 0x7f, 0x94, 0x03, 0x67, 0xa1, 0x7f, 0x00,
+ 0x75, 0xfa, 0x97, 0xf0, 0x07, 0x5f, 0xa9, 0x7f,
+ 0x00, 0x75, 0xfa, 0x97, 0xf0, 0x07, 0x5f, 0xa9,
+ 0x7f, 0x00, 0x75, 0xfa, 0x97, 0xf0, 0x07, 0x5f,
+ 0xa9, 0x7f, 0x00, 0x75, 0xfa, 0x97, 0xf0, 0x07,
+ 0x5f, 0xa8,
+
+ /* U+006F "o" */
+ 0x00, 0x0c, 0xef, 0xf5, 0xa8, 0x06, 0x3f, 0xf7,
+ 0x66, 0xff, 0xa4, 0x00, 0x3d, 0xf0, 0x01, 0x27,
+ 0xf9, 0x41, 0xff, 0x00, 0x39, 0xff, 0x03, 0x3d,
+ 0x40, 0x38, 0xbf, 0xc1, 0xde, 0x60, 0x1e, 0xff,
+ 0x0f, 0x79, 0x80, 0x7b, 0xfc, 0x39, 0xea, 0x01,
+ 0xc5, 0xfe, 0x09, 0xfb, 0x00, 0xe9, 0xfa, 0x02,
+ 0xff, 0x30, 0x04, 0xdf, 0xe3, 0x00, 0x37, 0xfb,
+ 0xb3, 0x7f, 0xcc, 0x01, 0x8e, 0xbb, 0xfa, 0x8c,
+ 0x02,
+
+ /* U+0070 "p" */
+ 0x2f, 0xb0, 0x6c, 0xfe, 0x91, 0x02, 0xfc, 0xaf,
+ 0xc9, 0xdf, 0xc0, 0x2f, 0xf9, 0x80, 0x2d, 0xf5,
+ 0x2f, 0xf3, 0x00, 0x67, 0xfa, 0x2f, 0xe0, 0x0e,
+ 0x4f, 0xd2, 0xfe, 0x00, 0xe2, 0xfe, 0x2f, 0xe0,
+ 0x0e, 0x3f, 0xe2, 0xfe, 0x00, 0xe5, 0xfc, 0x2f,
+ 0xe0, 0x0e, 0xaf, 0x72, 0xfe, 0x00, 0xcd, 0xfc,
+ 0x25, 0xff, 0x65, 0x6f, 0xf1, 0x81, 0x7f, 0xb7,
+ 0xfd, 0xb2, 0x20, 0x02, 0xfe, 0x00, 0xfc, 0x5f,
+ 0xc0, 0x1f, 0x8b, 0xf8, 0x03, 0xf1, 0x7f, 0x00,
+ 0x7e, 0x2f, 0xe0, 0x0f, 0xc0,
+
+ /* U+0071 "q" */
+ 0x00, 0xff, 0xe1, 0x3e, 0xff, 0xb6, 0xb5, 0x00,
+ 0x77, 0xfa, 0xed, 0xdf, 0xe4, 0x0c, 0xf9, 0x00,
+ 0xd9, 0xe8, 0x8f, 0xd0, 0x0e, 0xcf, 0x48, 0xf8,
+ 0x00, 0xec, 0xf4, 0xaf, 0x60, 0x0e, 0xcf, 0x4a,
+ 0xf6, 0x00, 0xec, 0xf4, 0x9f, 0x70, 0x0e, 0xdf,
+ 0x47, 0xfb, 0x00, 0xd1, 0xfe, 0x42, 0xff, 0x20,
+ 0x02, 0x3f, 0xe4, 0x09, 0xff, 0x67, 0x7c, 0xdf,
+ 0xa0, 0x02, 0x3b, 0xf1, 0x43, 0x3d, 0x00, 0x3f,
+ 0x67, 0xa0, 0x07, 0xec, 0xf4, 0x00, 0xfd, 0x9e,
+ 0x80, 0x1f, 0xb3, 0xd0, 0x03, 0xf6, 0x7a, 0x00,
+
+ /* U+0072 "r" */
+ 0xaf, 0x30, 0x8d, 0xfd, 0x60, 0x05, 0x7b, 0x6f,
+ 0xd5, 0x3f, 0xca, 0x15, 0xfe, 0xe2, 0x00, 0x37,
+ 0xe0, 0x57, 0xf1, 0x00, 0x43, 0xfe, 0x0a, 0xf7,
+ 0x00, 0xe9, 0x90, 0x57, 0xb0, 0x07, 0xea, 0xf6,
+ 0x00, 0xfd, 0x5e, 0xc0, 0x1f, 0xab, 0xd8, 0x03,
+ 0xf5, 0x7b, 0x00, 0x7e, 0xaf, 0x60, 0x0f, 0xd5,
+ 0xec, 0x01, 0xf8,
+
+ /* U+0073 "s" */
+ 0x01, 0x8d, 0xff, 0x76, 0x20, 0x0f, 0x7f, 0x5d,
+ 0xb7, 0xd8, 0x23, 0xe8, 0x03, 0xea, 0xf7, 0x00,
+ 0xf9, 0xbf, 0xce, 0x20, 0x1e, 0x9f, 0xfb, 0x18,
+ 0x03, 0x8a, 0x37, 0xfd, 0xc8, 0x01, 0xe3, 0xbf,
+ 0xe0, 0x0f, 0xdf, 0xe2, 0x30, 0x0e, 0x4f, 0xf0,
+ 0x6f, 0xee, 0x63, 0x7f, 0xcc, 0x11, 0x9d, 0xfe,
+ 0xea, 0x30, 0x00,
+
+ /* U+0074 "t" */
+ 0x00, 0xcb, 0x20, 0x1f, 0xef, 0xf0, 0x80, 0x7f,
+ 0x7f, 0x84, 0x03, 0xfb, 0xfc, 0x20, 0x1c, 0x9f,
+ 0xff, 0xe5, 0x3b, 0xbb, 0xfd, 0x77, 0xc8, 0x01,
+ 0xbf, 0xc2, 0x01, 0xfd, 0xfe, 0x10, 0x0f, 0xef,
+ 0xf0, 0x80, 0x7f, 0x7f, 0x84, 0x03, 0xfb, 0xfc,
+ 0x20, 0x1f, 0xdf, 0xe1, 0x00, 0xfe, 0xef, 0x30,
+ 0x0f, 0xeb, 0xfb, 0x00, 0xfe, 0x4f, 0xf7, 0x66,
+ 0x39, 0x40, 0x39, 0x2f, 0xbf, 0xda, 0x80,
+
+ /* U+0075 "u" */
+ 0x2f, 0xe0, 0x0e, 0xbf, 0x52, 0xfe, 0x00, 0xeb,
+ 0xf5, 0x2f, 0xe0, 0x0e, 0xbf, 0x52, 0xfe, 0x00,
+ 0xeb, 0xf5, 0x2f, 0xe0, 0x0e, 0xbf, 0x52, 0xfe,
+ 0x00, 0xeb, 0xf5, 0x2f, 0xe0, 0x0e, 0xbf, 0x51,
+ 0xfe, 0x00, 0xeb, 0xf5, 0x1f, 0xf0, 0x06, 0x2f,
+ 0xf2, 0x87, 0x7a, 0x80, 0x0b, 0xbf, 0xca, 0x0f,
+ 0xfe, 0x9a, 0xfd, 0xaf, 0x50, 0x03, 0xef, 0xf4,
+ 0x04, 0x7a, 0x80,
+
+ /* U+0076 "v" */
+ 0x1f, 0xf2, 0x00, 0x70, 0xff, 0x88, 0x2b, 0xe8,
+ 0x03, 0x9b, 0xf0, 0x00, 0x9f, 0xe0, 0x0e, 0xcf,
+ 0x60, 0x0b, 0x7d, 0x40, 0x22, 0xff, 0x00, 0x68,
+ 0xfb, 0x00, 0xa3, 0xe4, 0x03, 0x0f, 0xf8, 0x40,
+ 0x1b, 0xe6, 0x01, 0xd7, 0xee, 0x07, 0xfa, 0x01,
+ 0xe5, 0xfd, 0x09, 0xf7, 0x00, 0xfb, 0xbc, 0xbb,
+ 0xc4, 0x03, 0xe9, 0xfc, 0xfa, 0x00, 0xfc, 0x7f,
+ 0xf2, 0x00, 0x7f, 0x6f, 0xf0, 0x07, 0x00,
+
+ /* U+0077 "w" */
+ 0x7f, 0x70, 0x0f, 0x93, 0xed, 0x7e, 0x40, 0x3e,
+ 0x6f, 0x93, 0xfb, 0x00, 0xfa, 0x3d, 0x87, 0xf4,
+ 0x00, 0xbe, 0xe0, 0x0a, 0xf4, 0x0e, 0xf0, 0x05,
+ 0x7e, 0x80, 0x2f, 0xc8, 0x33, 0xc4, 0x3b, 0xfc,
+ 0x41, 0xbe, 0x00, 0xaf, 0x34, 0xf9, 0xf8, 0x0f,
+ 0xd0, 0x04, 0x7a, 0xcf, 0x8f, 0x68, 0xfd, 0x80,
+ 0x17, 0xdf, 0xac, 0x27, 0xdb, 0xe0, 0x00, 0x7f,
+ 0x9e, 0xa0, 0x9f, 0xbe, 0xc0, 0x01, 0xff, 0x80,
+ 0x2e, 0xff, 0x20, 0x05, 0xdf, 0x60, 0x14, 0xff,
+ 0x88, 0x00,
+
+ /* U+0078 "x" */
+ 0x09, 0xfe, 0x10, 0x0d, 0x1f, 0xa0, 0x16, 0xfd,
+ 0x00, 0x47, 0xfe, 0x30, 0x08, 0xbf, 0xca, 0x00,
+ 0xdf, 0x70, 0x0e, 0x6f, 0xe1, 0x8f, 0xb0, 0x0f,
+ 0xaf, 0xf3, 0xf8, 0x40, 0x3e, 0x1e, 0xff, 0x20,
+ 0x07, 0xe1, 0xef, 0xf1, 0x80, 0x7e, 0xcf, 0xcf,
+ 0xe1, 0x00, 0xf4, 0x7e, 0x85, 0x7e, 0x00, 0x72,
+ 0x7f, 0x8c, 0x07, 0xbe, 0x00, 0x21, 0xef, 0x70,
+ 0x09, 0x3f, 0xca, 0x00, 0xcf, 0xc0, 0x0e, 0x9f,
+ 0xf1, 0x00,
+
+ /* U+0079 "y" */
+ 0x1f, 0xf2, 0x00, 0x70, 0xff, 0x88, 0x2b, 0xe8,
+ 0x03, 0x9b, 0xf0, 0x00, 0x9f, 0xe0, 0x0e, 0xcf,
+ 0x60, 0x0b, 0x7d, 0x80, 0x21, 0xff, 0x08, 0x04,
+ 0xff, 0x80, 0x13, 0xfd, 0x00, 0x61, 0xff, 0x10,
+ 0x03, 0x7d, 0x00, 0x3a, 0xfe, 0x00, 0xbf, 0x80,
+ 0x3c, 0x9f, 0xc1, 0x1f, 0x00, 0x1f, 0x77, 0x9e,
+ 0xf9, 0x00, 0x7d, 0x1f, 0x9f, 0x80, 0x1f, 0x8b,
+ 0xfe, 0x60, 0x0f, 0xec, 0xff, 0x00, 0x7f, 0xb3,
+ 0xe4, 0x03, 0xf9, 0x7f, 0xc2, 0x01, 0xf9, 0x3f,
+ 0xce, 0x01, 0xe4, 0xde, 0xff, 0x48, 0x07, 0xc9,
+ 0xfe, 0xb5, 0x00, 0xfc,
+
+ /* U+007A "z" */
+ 0x0e, 0xff, 0xfc, 0x00, 0xab, 0xbe, 0xdf, 0xf0,
+ 0x07, 0xc3, 0xde, 0xa0, 0x1f, 0x67, 0xc8, 0x07,
+ 0xd1, 0xf8, 0x01, 0xf2, 0x7f, 0x88, 0x03, 0xc3,
+ 0xde, 0xa0, 0x1f, 0x67, 0xc8, 0x07, 0xd1, 0xf8,
+ 0x01, 0xf2, 0x7f, 0x88, 0x03, 0xee, 0xfe, 0xbb,
+ 0xf2, 0x0f, 0xff, 0xf3, 0x00,
+
+ /* U+007B "{" */
+ 0x00, 0xe2, 0xae, 0xf8, 0x00, 0xc5, 0xdf, 0xd6,
+ 0xa0, 0x1a, 0x3e, 0x80, 0x3e, 0xbf, 0x30, 0x0f,
+ 0xb3, 0xc4, 0x03, 0xed, 0xf1, 0x00, 0xfb, 0x7c,
+ 0x40, 0x3e, 0xdf, 0x00, 0xf8, 0xff, 0x40, 0x3a,
+ 0xaf, 0xf8, 0xc0, 0x30, 0xff, 0xd0, 0x01, 0xf1,
+ 0x57, 0xd0, 0x07, 0xef, 0xf0, 0x07, 0xed, 0xf1,
+ 0x00, 0xfb, 0x7c, 0x80, 0x3e, 0xdf, 0x20, 0x0f,
+ 0xb7, 0xc8, 0x03, 0xec, 0xf2, 0x00, 0xfa, 0xfd,
+ 0x00, 0x3e, 0x8f, 0xb0, 0x0f, 0x87, 0xbf, 0xad,
+ 0x40, 0x38, 0xab, 0xbe, 0x00,
+
+ /* U+007C "|" */
+ 0x5f, 0x95, 0xf9, 0x5f, 0x95, 0xf9, 0x5f, 0x95,
+ 0xf9, 0x5f, 0x95, 0xf9, 0x5f, 0x95, 0xf9, 0x5f,
+ 0x95, 0xf9, 0x5f, 0x95, 0xf9, 0x5f, 0x95, 0xf9,
+ 0x5f, 0x95, 0xf9, 0x5f, 0x95, 0xf9, 0x5f, 0x95,
+ 0xf9, 0x5f, 0x95, 0xf9,
+
+ /* U+007D "}" */
+ 0x5f, 0xeb, 0x30, 0x0e, 0x3a, 0xdf, 0xf2, 0x00,
+ 0x7d, 0x1f, 0x60, 0x1f, 0xbf, 0xc0, 0x1f, 0xbb,
+ 0xc0, 0x3f, 0x77, 0x80, 0x7e, 0xef, 0x00, 0xfd,
+ 0xbe, 0x20, 0x1f, 0x57, 0xb8, 0x07, 0xc5, 0xbf,
+ 0x94, 0x60, 0x1c, 0xdd, 0xfe, 0x50, 0x0c, 0xdf,
+ 0x64, 0x01, 0xec, 0xf2, 0x00, 0xfb, 0xbc, 0x03,
+ 0xf7, 0x78, 0x07, 0xee, 0xf0, 0x0f, 0xdd, 0xe0,
+ 0x1f, 0xbb, 0xc0, 0x3f, 0x7f, 0x00, 0x7d, 0x1f,
+ 0x60, 0x18, 0xeb, 0x7f, 0xc6, 0x01, 0x97, 0xfa,
+ 0xcc, 0x03, 0x80,
+
+ /* U+007E "~" */
+ 0x00, 0x36, 0x61, 0xc0, 0x30, 0x90, 0x83, 0xff,
+ 0xec, 0x00, 0x9f, 0xd4, 0x3b, 0xc8, 0x99, 0xf8,
+ 0x21, 0x9e, 0x65, 0xf6, 0x01, 0x67, 0xfb, 0xbf,
+ 0x00, 0x54, 0xc0, 0x34, 0x77, 0xd0, 0x80,
+
+ /* U+007F "" */
+
+ /* U+5010 "å€" */
+ 0x00, 0xcd, 0x68, 0x01, 0xeb, 0x80, 0x0f, 0xfe,
+ 0x15, 0xf9, 0x80, 0x72, 0xfc, 0x00, 0x7f, 0xf0,
+ 0xbf, 0x80, 0x3d, 0xbf, 0x51, 0x1f, 0x00, 0x79,
+ 0x7e, 0x40, 0x40, 0x27, 0xff, 0xff, 0x00, 0x7a,
+ 0xbc, 0xcb, 0xe4, 0x0f, 0xfd, 0x40, 0x1d, 0x5f,
+ 0x20, 0x1e, 0xfd, 0x02, 0xf9, 0x1d, 0xfb, 0xf6,
+ 0x00, 0x9f, 0xec, 0x03, 0xcd, 0xfa, 0x05, 0xf3,
+ 0x9e, 0xc1, 0xbe, 0xe1, 0x3f, 0x82, 0x01, 0xed,
+ 0xfd, 0x02, 0xf9, 0x37, 0x00, 0x0e, 0xff, 0x7d,
+ 0x80, 0x7c, 0x9f, 0xed, 0x02, 0xf9, 0x00, 0xc3,
+ 0x3f, 0xf4, 0x08, 0x07, 0xb3, 0xfd, 0xa0, 0x5f,
+ 0x20, 0x02, 0x8f, 0xf7, 0x47, 0x7f, 0xa9, 0x88,
+ 0x00, 0x9f, 0x5d, 0xa0, 0x5f, 0x2f, 0xbf, 0xee,
+ 0x70, 0x09, 0xb7, 0xfe, 0xc0, 0xbf, 0x2e, 0xd0,
+ 0x2f, 0x97, 0xfb, 0x50, 0x03, 0xc0, 0x04, 0x4f,
+ 0x8c, 0x0f, 0x01, 0xda, 0x05, 0xf2, 0x02, 0x01,
+ 0xb7, 0xc0, 0x3f, 0x08, 0x03, 0xb4, 0x0b, 0xe4,
+ 0x1c, 0x80, 0x2e, 0xf0, 0x0d, 0x06, 0x01, 0xdd,
+ 0xa0, 0x5f, 0x27, 0xf8, 0x01, 0x7e, 0x80, 0x53,
+ 0xf8, 0x01, 0xdd, 0xa0, 0x5f, 0x21, 0x1e, 0xc0,
+ 0x3f, 0x60, 0x08, 0xfd, 0x10, 0x0e, 0xed, 0x02,
+ 0xf9, 0x00, 0x77, 0x01, 0x7f, 0xd0, 0x5f, 0xa2,
+ 0x01, 0xee, 0xd0, 0x2f, 0x90, 0x02, 0x10, 0x5f,
+ 0xf7, 0xda, 0x88, 0x07, 0xdd, 0xa0, 0x01, 0x00,
+ 0xe5, 0xfc, 0x1b, 0xfe, 0x30, 0x0f, 0xbb, 0x40,
+ 0x3e, 0x6f, 0xf1, 0x80, 0x23, 0xfc, 0xa0, 0x1e,
+ 0xed, 0x00, 0xe3, 0xbf, 0xf2, 0x00, 0x65, 0xff,
+ 0x40, 0x07, 0x76, 0x80, 0x4b, 0xbf, 0xec, 0x20,
+ 0x0f, 0x27, 0x7c, 0x80, 0x6e, 0xd0, 0x08, 0x7a,
+ 0xd4, 0x03, 0xf8, 0xb0, 0x80, 0x3f, 0xf9, 0xc0,
+
+ /* U+5030 "倰" */
+ 0x00, 0xe7, 0x40, 0x0f, 0xa9, 0xc0, 0x3f, 0xf8,
+ 0x03, 0xf6, 0x01, 0xe1, 0xfc, 0x00, 0xff, 0xe0,
+ 0x37, 0xb0, 0x07, 0x87, 0xf0, 0x03, 0xff, 0x81,
+ 0x7e, 0x31, 0xff, 0xff, 0xc2, 0x10, 0x0c, 0x5f,
+ 0x60, 0x91, 0x1d, 0x3f, 0xd1, 0x1e, 0x00, 0xe8,
+ 0xf5, 0x00, 0xf8, 0x7f, 0x00, 0x3f, 0xee, 0xf0,
+ 0x0f, 0xc3, 0xf8, 0x01, 0xfe, 0x7f, 0xe0, 0xbf,
+ 0xff, 0xfe, 0x21, 0x80, 0x3b, 0xf8, 0x1a, 0x23,
+ 0xff, 0x88, 0x21, 0x1f, 0xee, 0x00, 0xc5, 0x92,
+ 0x01, 0xcf, 0x88, 0x01, 0x8b, 0xfb, 0xa0, 0x09,
+ 0xff, 0xd2, 0x01, 0xcf, 0xdf, 0x88, 0x00, 0x9f,
+ 0x4d, 0xe0, 0x4d, 0xfe, 0x47, 0xb3, 0x00, 0xc3,
+ 0x1f, 0xec, 0x15, 0xa0, 0xde, 0x1e, 0xf8, 0x04,
+ 0xfd, 0x10, 0x0f, 0x15, 0x60, 0x00, 0x43, 0x78,
+ 0x0c, 0x80, 0xff, 0xff, 0xd6, 0x01, 0xed, 0xe0,
+ 0x08, 0xfb, 0xf6, 0x23, 0xd9, 0xf2, 0x01, 0xed,
+ 0xe0, 0x02, 0x7f, 0xb7, 0xd4, 0x03, 0x1f, 0xf0,
+ 0x80, 0x7b, 0x78, 0x1b, 0xfc, 0x83, 0xde, 0xa0,
+ 0x02, 0xef, 0x30, 0x0f, 0xb7, 0x82, 0xb8, 0xc0,
+ 0x05, 0xdf, 0x0b, 0xfe, 0x40, 0x0f, 0xdb, 0xc0,
+ 0x01, 0x00, 0xc3, 0xbf, 0xf1, 0x80, 0x7f, 0x6f,
+ 0x00, 0x78, 0xeb, 0xff, 0x5a, 0x00, 0x7e, 0xde,
+ 0x00, 0x8e, 0x37, 0xfd, 0x66, 0x6c, 0xff, 0x74,
+ 0x20, 0x07, 0x6f, 0x1d, 0xff, 0xdd, 0x24, 0x01,
+ 0x8e, 0xbf, 0xf2, 0x00, 0x5b, 0xc1, 0xdb, 0x28,
+ 0x01, 0xfc, 0x2d, 0x78, 0x01, 0xff, 0xcd
+};
+
+
+static const sgl_font_table_t font_table[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 211, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 0, .adv_w = 211, .box_w = 4, .box_h = 17, .ofs_x = 5, .ofs_y = 0},
+ {.bitmap_index = 32, .adv_w = 211, .box_w = 8, .box_h = 6, .ofs_x = 3, .ofs_y = 11},
+ {.bitmap_index = 57, .adv_w = 211, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 139, .adv_w = 211, .box_w = 11, .box_h = 21, .ofs_x = 1, .ofs_y = -3},
+ {.bitmap_index = 232, .adv_w = 211, .box_w = 13, .box_h = 17, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 332, .adv_w = 211, .box_w = 14, .box_h = 17, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 436, .adv_w = 211, .box_w = 3, .box_h = 6, .ofs_x = 5, .ofs_y = 11},
+ {.bitmap_index = 445, .adv_w = 211, .box_w = 8, .box_h = 23, .ofs_x = 3, .ofs_y = -5},
+ {.bitmap_index = 516, .adv_w = 211, .box_w = 7, .box_h = 23, .ofs_x = 3, .ofs_y = -5},
+ {.bitmap_index = 583, .adv_w = 211, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = 7},
+ {.bitmap_index = 630, .adv_w = 211, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 677, .adv_w = 211, .box_w = 7, .box_h = 8, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 704, .adv_w = 211, .box_w = 8, .box_h = 2, .ofs_x = 3, .ofs_y = 5},
+ {.bitmap_index = 710, .adv_w = 211, .box_w = 5, .box_h = 4, .ofs_x = 4, .ofs_y = 0},
+ {.bitmap_index = 720, .adv_w = 211, .box_w = 13, .box_h = 17, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 783, .adv_w = 211, .box_w = 12, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 868, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 927, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 988, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1054, .adv_w = 211, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1126, .adv_w = 211, .box_w = 10, .box_h = 15, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 1183, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1255, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1309, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1388, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1459, .adv_w = 211, .box_w = 5, .box_h = 12, .ofs_x = 4, .ofs_y = 0},
+ {.bitmap_index = 1481, .adv_w = 211, .box_w = 7, .box_h = 16, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 1522, .adv_w = 211, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -1},
+ {.bitmap_index = 1572, .adv_w = 211, .box_w = 11, .box_h = 6, .ofs_x = 1, .ofs_y = 4},
+ {.bitmap_index = 1588, .adv_w = 211, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = -1},
+ {.bitmap_index = 1638, .adv_w = 211, .box_w = 8, .box_h = 17, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 1692, .adv_w = 211, .box_w = 14, .box_h = 22, .ofs_x = 0, .ofs_y = -5},
+ {.bitmap_index = 1827, .adv_w = 211, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1906, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1980, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2044, .adv_w = 211, .box_w = 12, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2123, .adv_w = 211, .box_w = 10, .box_h = 15, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2173, .adv_w = 211, .box_w = 10, .box_h = 15, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2223, .adv_w = 211, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2300, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2366, .adv_w = 211, .box_w = 10, .box_h = 15, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2417, .adv_w = 211, .box_w = 9, .box_h = 15, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2469, .adv_w = 211, .box_w = 12, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2548, .adv_w = 211, .box_w = 10, .box_h = 15, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2597, .adv_w = 211, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2687, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2767, .adv_w = 211, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2850, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2916, .adv_w = 211, .box_w = 14, .box_h = 20, .ofs_x = 0, .ofs_y = -5},
+ {.bitmap_index = 3026, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 3106, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3173, .adv_w = 211, .box_w = 12, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3227, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3299, .adv_w = 211, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3380, .adv_w = 211, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3471, .adv_w = 211, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3551, .adv_w = 211, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 3624, .adv_w = 211, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3678, .adv_w = 211, .box_w = 6, .box_h = 22, .ofs_x = 4, .ofs_y = -5},
+ {.bitmap_index = 3733, .adv_w = 211, .box_w = 11, .box_h = 19, .ofs_x = 1, .ofs_y = -2},
+ {.bitmap_index = 3796, .adv_w = 211, .box_w = 7, .box_h = 22, .ofs_x = 3, .ofs_y = -5},
+ {.bitmap_index = 3860, .adv_w = 211, .box_w = 11, .box_h = 8, .ofs_x = 1, .ofs_y = 8},
+ {.bitmap_index = 3897, .adv_w = 211, .box_w = 14, .box_h = 2, .ofs_x = 0, .ofs_y = -5},
+ {.bitmap_index = 3905, .adv_w = 98, .box_w = 4, .box_h = 6, .ofs_x = 1, .ofs_y = 13},
+ {.bitmap_index = 3918, .adv_w = 211, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3978, .adv_w = 211, .box_w = 11, .box_h = 17, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4056, .adv_w = 211, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4108, .adv_w = 211, .box_w = 11, .box_h = 17, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4186, .adv_w = 211, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4240, .adv_w = 211, .box_w = 13, .box_h = 17, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 4309, .adv_w = 211, .box_w = 12, .box_h = 17, .ofs_x = 1, .ofs_y = -5},
+ {.bitmap_index = 4399, .adv_w = 211, .box_w = 11, .box_h = 17, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4474, .adv_w = 211, .box_w = 10, .box_h = 17, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 4531, .adv_w = 211, .box_w = 10, .box_h = 22, .ofs_x = 1, .ofs_y = -5},
+ {.bitmap_index = 4608, .adv_w = 211, .box_w = 11, .box_h = 17, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 4686, .adv_w = 211, .box_w = 10, .box_h = 17, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 4745, .adv_w = 211, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4821, .adv_w = 211, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4879, .adv_w = 211, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4944, .adv_w = 211, .box_w = 11, .box_h = 17, .ofs_x = 1, .ofs_y = -5},
+ {.bitmap_index = 5021, .adv_w = 211, .box_w = 11, .box_h = 18, .ofs_x = 1, .ofs_y = -5},
+ {.bitmap_index = 5101, .adv_w = 211, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 5152, .adv_w = 211, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 5203, .adv_w = 211, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5266, .adv_w = 211, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5325, .adv_w = 211, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5388, .adv_w = 211, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5462, .adv_w = 211, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5528, .adv_w = 211, .box_w = 13, .box_h = 17, .ofs_x = 0, .ofs_y = -5},
+ {.bitmap_index = 5612, .adv_w = 211, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5657, .adv_w = 211, .box_w = 10, .box_h = 22, .ofs_x = 1, .ofs_y = -5},
+ {.bitmap_index = 5734, .adv_w = 211, .box_w = 3, .box_h = 24, .ofs_x = 5, .ofs_y = -5},
+ {.bitmap_index = 5770, .adv_w = 211, .box_w = 10, .box_h = 22, .ofs_x = 2, .ofs_y = -5},
+ {.bitmap_index = 5845, .adv_w = 211, .box_w = 13, .box_h = 5, .ofs_x = 0, .ofs_y = 4},
+ {.bitmap_index = 5876, .adv_w = 211, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5876, .adv_w = 384, .box_w = 25, .box_h = 24, .ofs_x = 0, .ofs_y = -4},
+ {.bitmap_index = 6116, .adv_w = 384, .box_w = 24, .box_h = 24, .ofs_x = 0, .ofs_y = -4}
+};
+
+static const uint32_t unicode_list_1[] = {
+ 0x00, 0x20
+};
+
+static const sgl_font_unicode_t font_unicode[] =
+{
+ { .offset = 0x20, .len = 96, .list = NULL, .tab_offset = 1, },
+ { .offset = 0x5010, .len = 2, .list = unicode_list_1, .tab_offset = 97, }
+};
+
+const sgl_font_t consolas24_compress = {
+ .bitmap = font_bitmap,
+ .table = font_table,
+ .font_table_size = SGL_ARRAY_SIZE(font_table),
+ .font_height = 25,
+ .base_line = 5,
+ .bpp = 4,
+ .compress = 1,
+ .unicode = font_unicode,
+ .unicode_num = 2,
+};
+
+#endif /* !CONFIG_SGL_FONT_CONSOLAS24_COMPRESS */
diff --git a/User/system/sgl/fonts/sgl_ascii_consolas34.c b/User/system/sgl/fonts/sgl_ascii_consolas34.c
new file mode 100644
index 0000000..b524882
--- /dev/null
+++ b/User/system/sgl/fonts/sgl_ascii_consolas34.c
@@ -0,0 +1,2048 @@
+/* source/fonts/sgl_ascii_consolas34.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+
+
+#if (CONFIG_SGL_FONT_CONSOLAS32)
+
+
+static const uint8_t consolas32_bitmap[] = {
+ /* U+0020 " " */
+
+ /* U+0021 "!" */
+ 0x1f, 0xff, 0x11, 0xff, 0xf0, 0xf, 0xff, 0x0,
+ 0xff, 0xf0, 0xf, 0xff, 0x0, 0xff, 0xe0, 0xe,
+ 0xfe, 0x0, 0xef, 0xe0, 0xd, 0xfd, 0x0, 0xdf,
+ 0xd0, 0xc, 0xfc, 0x0, 0xcf, 0xc0, 0xb, 0xfb,
+ 0x0, 0xbf, 0xb0, 0xa, 0xfb, 0x0, 0x46, 0x40,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0xc, 0xfc, 0x6,
+ 0xff, 0xf5, 0x6f, 0xff, 0x50, 0xaf, 0xa0,
+
+ /* U+0022 "\"" */
+ 0x1f, 0xff, 0x30, 0x2f, 0xff, 0x10, 0xff, 0xf2,
+ 0x1, 0xff, 0xf0, 0xf, 0xff, 0x10, 0xf, 0xff,
+ 0x0, 0xef, 0xf0, 0x0, 0xff, 0xf0, 0xd, 0xff,
+ 0x0, 0xe, 0xfe, 0x0, 0xcf, 0xe0, 0x0, 0xef,
+ 0xd0, 0xb, 0xfe, 0x0, 0xd, 0xfc, 0x0, 0x35,
+ 0x40, 0x0, 0x45, 0x40,
+
+ /* U+0023 "#" */
+ 0x0, 0x0, 0xb, 0xf7, 0x0, 0xa, 0xf9, 0x0,
+ 0x0, 0x0, 0x0, 0xdf, 0x50, 0x0, 0xcf, 0x70,
+ 0x0, 0x0, 0x0, 0xf, 0xf3, 0x0, 0xe, 0xf5,
+ 0x0, 0x0, 0x0, 0x2, 0xff, 0x10, 0x0, 0xff,
+ 0x30, 0x0, 0x9, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x60, 0x9f, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xf6, 0x0, 0x0, 0x7f, 0xc0, 0x0,
+ 0x5f, 0xe0, 0x0, 0x0, 0x0, 0x8, 0xfb, 0x0,
+ 0x6, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x9f, 0x90,
+ 0x0, 0x8f, 0xb0, 0x0, 0x0, 0x0, 0xb, 0xf8,
+ 0x0, 0x9, 0xfa, 0x0, 0x0, 0x0, 0x0, 0xcf,
+ 0x70, 0x0, 0xaf, 0x80, 0x0, 0x0, 0x0, 0xe,
+ 0xf5, 0x0, 0xc, 0xf7, 0x0, 0x0, 0x5f, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x5, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, 0x0,
+ 0x3, 0xff, 0x10, 0x1, 0xff, 0x30, 0x0, 0x0,
+ 0x0, 0x4f, 0xf0, 0x0, 0x2f, 0xf1, 0x0, 0x0,
+ 0x0, 0x5, 0xfe, 0x0, 0x4, 0xff, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xc0, 0x0, 0x5f, 0xe0, 0x0,
+ 0x0, 0x0, 0x8, 0xfb, 0x0, 0x7, 0xfc, 0x0,
+ 0x0, 0x0, 0x0, 0xaf, 0x90, 0x0, 0x8f, 0xb0,
+ 0x0, 0x0,
+
+ /* U+0024 "$" */
+ 0x0, 0x0, 0x0, 0x0, 0x88, 0x10, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x2f, 0xf0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x4, 0xfe, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x5f, 0xd0, 0x0, 0x0, 0x0, 0x0,
+ 0x7c, 0xef, 0xff, 0xdb, 0x70, 0x0, 0x4, 0xef,
+ 0xff, 0xff, 0xff, 0xfd, 0x0, 0x3, 0xff, 0xfa,
+ 0x6d, 0xfa, 0x7a, 0xb0, 0x0, 0xcf, 0xf4, 0x0,
+ 0xef, 0x50, 0x0, 0x0, 0x1f, 0xfc, 0x0, 0xf,
+ 0xf2, 0x0, 0x0, 0x2, 0xff, 0xb0, 0x2, 0xff,
+ 0x0, 0x0, 0x0, 0xf, 0xff, 0x20, 0x4f, 0xe0,
+ 0x0, 0x0, 0x0, 0xaf, 0xfe, 0x56, 0xfc, 0x0,
+ 0x0, 0x0, 0x1, 0xdf, 0xff, 0xff, 0xa0, 0x0,
+ 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, 0x92, 0x0,
+ 0x0, 0x0, 0x0, 0x29, 0xff, 0xff, 0xf9, 0x10,
+ 0x0, 0x0, 0x0, 0xe, 0xfe, 0xff, 0xfd, 0x10,
+ 0x0, 0x0, 0x0, 0xff, 0x25, 0xef, 0xfa, 0x0,
+ 0x0, 0x0, 0x2f, 0xf0, 0x2, 0xff, 0xf1, 0x0,
+ 0x0, 0x4, 0xfe, 0x0, 0xb, 0xff, 0x20, 0x0,
+ 0x0, 0x7f, 0xc0, 0x0, 0xcf, 0xf1, 0x0, 0x0,
+ 0x9, 0xfa, 0x0, 0x3f, 0xfc, 0x4, 0xc7, 0x53,
+ 0xbf, 0x93, 0x8f, 0xff, 0x40, 0x5f, 0xff, 0xff,
+ 0xff, 0xff, 0xfe, 0x40, 0x2, 0x9c, 0xef, 0xff,
+ 0xfe, 0xb6, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf1,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xd0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x7, 0xfb, 0x0, 0x0,
+ 0x0, 0x0,
+
+ /* U+0025 "%" */
+ 0x0, 0x5d, 0xfe, 0x91, 0x0, 0x0, 0x2, 0xff,
+ 0x60, 0x6f, 0xfd, 0xff, 0xc0, 0x0, 0x0, 0xbf,
+ 0xc0, 0x1e, 0xf5, 0x1, 0xff, 0x50, 0x0, 0x5f,
+ 0xf2, 0x5, 0xfe, 0x0, 0xa, 0xf9, 0x0, 0x1e,
+ 0xf8, 0x0, 0x6f, 0xc0, 0x0, 0x9f, 0xa0, 0x9,
+ 0xfd, 0x0, 0x5, 0xfe, 0x0, 0xb, 0xf8, 0x4,
+ 0xff, 0x40, 0x0, 0x2f, 0xf7, 0x5, 0xff, 0x30,
+ 0xdf, 0x90, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xa0,
+ 0x8f, 0xe1, 0x0, 0x0, 0x0, 0x7d, 0xfe, 0x70,
+ 0x2f, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x6, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x1, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xaf, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x5f, 0xf3, 0x7, 0xdf, 0xd8, 0x0, 0x0,
+ 0x0, 0xe, 0xf8, 0x9, 0xff, 0xff, 0xfa, 0x0,
+ 0x0, 0x9, 0xfd, 0x3, 0xff, 0x60, 0x6f, 0xf2,
+ 0x0, 0x3, 0xff, 0x40, 0x8f, 0xc0, 0x0, 0xdf,
+ 0x60, 0x0, 0xdf, 0xa0, 0x9, 0xf9, 0x0, 0xb,
+ 0xf7, 0x0, 0x7f, 0xe1, 0x0, 0x8f, 0xb0, 0x0,
+ 0xdf, 0x60, 0x2f, 0xf5, 0x0, 0x5, 0xff, 0x20,
+ 0x4f, 0xf1, 0xb, 0xfb, 0x0, 0x0, 0xc, 0xff,
+ 0xdf, 0xf7, 0x6, 0xff, 0x20, 0x0, 0x0, 0x9,
+ 0xef, 0xd6, 0x0,
+
+ /* U+0026 "&" */
+ 0x0, 0x0, 0x18, 0xdf, 0xfc, 0x50, 0x0, 0x0,
+ 0x0, 0x0, 0x1, 0xdf, 0xff, 0xff, 0xf9, 0x0,
+ 0x0, 0x0, 0x0, 0xb, 0xff, 0xb6, 0x7e, 0xff,
+ 0x40, 0x0, 0x0, 0x0, 0x2f, 0xfb, 0x0, 0x3,
+ 0xff, 0xa0, 0x0, 0x0, 0x0, 0x5f, 0xf6, 0x0,
+ 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0, 0x6f, 0xf5,
+ 0x0, 0x0, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x4f,
+ 0xf8, 0x0, 0x4, 0xff, 0x80, 0x0, 0x0, 0x0,
+ 0xf, 0xfe, 0x10, 0x2e, 0xfe, 0x10, 0x0, 0x0,
+ 0x0, 0x9, 0xff, 0xa6, 0xff, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x1, 0xef, 0xff, 0xfe, 0x30, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xbf, 0xff, 0xb1, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, 0xff, 0xd0,
+ 0x0, 0x1a, 0xa5, 0x0, 0x0, 0xdf, 0xf8, 0xcf,
+ 0xfa, 0x0, 0x3f, 0xf7, 0x0, 0x7, 0xff, 0x80,
+ 0x1e, 0xff, 0x70, 0x4f, 0xf5, 0x0, 0xe, 0xfe,
+ 0x0, 0x4, 0xff, 0xf3, 0x7f, 0xf3, 0x0, 0x1f,
+ 0xfb, 0x0, 0x0, 0x7f, 0xfe, 0xcf, 0xf0, 0x0,
+ 0x1f, 0xfa, 0x0, 0x0, 0xb, 0xff, 0xff, 0xa0,
+ 0x0, 0xf, 0xfd, 0x0, 0x0, 0x0, 0xdf, 0xff,
+ 0x30, 0x0, 0xc, 0xff, 0x50, 0x0, 0x0, 0x8f,
+ 0xff, 0x50, 0x0, 0x4, 0xff, 0xf8, 0x32, 0x4a,
+ 0xff, 0xff, 0xf2, 0x0, 0x0, 0x6f, 0xff, 0xff,
+ 0xff, 0xfc, 0xaf, 0xfd, 0x0, 0x0, 0x3, 0x9d,
+ 0xff, 0xda, 0x40, 0xc, 0xff, 0xa0,
+
+ /* U+0027 "'" */
+ 0x2f, 0xff, 0x31, 0xff, 0xf2, 0xf, 0xff, 0x10,
+ 0xff, 0xf0, 0xf, 0xff, 0x0, 0xef, 0xe0, 0xd,
+ 0xfe, 0x0, 0x45, 0x40,
+
+ /* U+0028 "(" */
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0,
+ 0x3f, 0x50, 0x0, 0x0, 0x3, 0xff, 0xd0, 0x0,
+ 0x0, 0x1e, 0xfe, 0x10, 0x0, 0x0, 0xbf, 0xf3,
+ 0x0, 0x0, 0x6, 0xff, 0x70, 0x0, 0x0, 0x1e,
+ 0xfd, 0x0, 0x0, 0x0, 0x8f, 0xf4, 0x0, 0x0,
+ 0x0, 0xff, 0xc0, 0x0, 0x0, 0x5, 0xff, 0x50,
+ 0x0, 0x0, 0xb, 0xff, 0x0, 0x0, 0x0, 0xf,
+ 0xfb, 0x0, 0x0, 0x0, 0x2f, 0xf8, 0x0, 0x0,
+ 0x0, 0x4f, 0xf5, 0x0, 0x0, 0x0, 0x6f, 0xf4,
+ 0x0, 0x0, 0x0, 0x7f, 0xf3, 0x0, 0x0, 0x0,
+ 0x6f, 0xf4, 0x0, 0x0, 0x0, 0x5f, 0xf5, 0x0,
+ 0x0, 0x0, 0x3f, 0xf7, 0x0, 0x0, 0x0, 0x1f,
+ 0xfb, 0x0, 0x0, 0x0, 0xc, 0xff, 0x0, 0x0,
+ 0x0, 0x8, 0xff, 0x40, 0x0, 0x0, 0x2, 0xff,
+ 0xb0, 0x0, 0x0, 0x0, 0xbf, 0xf2, 0x0, 0x0,
+ 0x0, 0x3f, 0xfb, 0x0, 0x0, 0x0, 0xa, 0xff,
+ 0x50, 0x0, 0x0, 0x1, 0xef, 0xe2, 0x0, 0x0,
+ 0x0, 0x4f, 0xfc, 0x0, 0x0, 0x0, 0x6, 0xff,
+ 0xb0, 0x0, 0x0, 0x0, 0x8f, 0x80, 0x0, 0x0,
+ 0x0, 0x5, 0x0,
+
+ /* U+0029 ")" */
+ 0x0, 0x10, 0x0, 0x0, 0x0, 0x4, 0xf5, 0x0,
+ 0x0, 0x0, 0xc, 0xff, 0x40, 0x0, 0x0, 0x2,
+ 0xef, 0xe2, 0x0, 0x0, 0x0, 0x3f, 0xfc, 0x0,
+ 0x0, 0x0, 0x7, 0xff, 0x70, 0x0, 0x0, 0x0,
+ 0xdf, 0xf1, 0x0, 0x0, 0x0, 0x4f, 0xf9, 0x0,
+ 0x0, 0x0, 0xc, 0xff, 0x10, 0x0, 0x0, 0x5,
+ 0xff, 0x70, 0x0, 0x0, 0x0, 0xff, 0xc0, 0x0,
+ 0x0, 0x0, 0xbf, 0xf0, 0x0, 0x0, 0x0, 0x8f,
+ 0xf3, 0x0, 0x0, 0x0, 0x5f, 0xf5, 0x0, 0x0,
+ 0x0, 0x4f, 0xf7, 0x0, 0x0, 0x0, 0x3f, 0xf7,
+ 0x0, 0x0, 0x0, 0x3f, 0xf7, 0x0, 0x0, 0x0,
+ 0x4f, 0xf6, 0x0, 0x0, 0x0, 0x7f, 0xf3, 0x0,
+ 0x0, 0x0, 0xaf, 0xf1, 0x0, 0x0, 0x0, 0xef,
+ 0xd0, 0x0, 0x0, 0x3, 0xff, 0x80, 0x0, 0x0,
+ 0x9, 0xff, 0x20, 0x0, 0x0, 0x1f, 0xfa, 0x0,
+ 0x0, 0x0, 0x9f, 0xf3, 0x0, 0x0, 0x4, 0xff,
+ 0x90, 0x0, 0x0, 0x1e, 0xfe, 0x10, 0x0, 0x0,
+ 0xbf, 0xf3, 0x0, 0x0, 0xa, 0xff, 0x60, 0x0,
+ 0x0, 0x8, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x50,
+ 0x0, 0x0, 0x0,
+
+ /* U+002A "*" */
+ 0x0, 0x0, 0x8, 0xf9, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x7f, 0x80, 0x0, 0x0, 0x5, 0x0, 0x6,
+ 0xf6, 0x0, 0x5, 0x2, 0xfe, 0x40, 0x5f, 0x50,
+ 0x3d, 0xf2, 0x2c, 0xff, 0x84, 0xf5, 0x8f, 0xfd,
+ 0x30, 0x4, 0xcf, 0xef, 0xef, 0xd5, 0x0, 0x0,
+ 0x0, 0x6f, 0xff, 0x70, 0x0, 0x0, 0x1, 0x8f,
+ 0xff, 0xff, 0x81, 0x0, 0x18, 0xff, 0xc6, 0xf6,
+ 0xcf, 0xf8, 0x14, 0xff, 0x70, 0x5f, 0x50, 0x7f,
+ 0xf4, 0x8, 0x20, 0x6, 0xf6, 0x0, 0x28, 0x0,
+ 0x0, 0x0, 0x7f, 0x70, 0x0, 0x0, 0x0, 0x0,
+ 0x8, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24,
+ 0x20, 0x0, 0x0,
+
+ /* U+002B "+" */
+ 0x0, 0x0, 0x0, 0xcf, 0xd0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xc, 0xfd, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xcf, 0xd0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xc, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xcf, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc, 0xfd, 0x0, 0x0, 0x0, 0x46, 0x66, 0x66,
+ 0xdf, 0xe6, 0x66, 0x66, 0x4b, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xfc, 0xbf, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xc0, 0x0, 0x0, 0xc, 0xfd,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xd0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xfd, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xd0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xc, 0xfd, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xcf, 0xd0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x11, 0x0, 0x0, 0x0,
+
+ /* U+002C "," */
+ 0x0, 0x0, 0x56, 0x20, 0x0, 0x7, 0xff, 0xf2,
+ 0x0, 0xc, 0xff, 0xf9, 0x0, 0x9, 0xff, 0xfc,
+ 0x0, 0x1, 0xef, 0xfe, 0x0, 0x0, 0x8f, 0xfc,
+ 0x0, 0x0, 0x7f, 0xf8, 0x0, 0x1, 0xdf, 0xf1,
+ 0x13, 0x7e, 0xff, 0x60, 0x6f, 0xff, 0xf6, 0x0,
+ 0x6e, 0xc8, 0x10, 0x0,
+
+ /* U+002D "-" */
+ 0x99, 0x99, 0x99, 0x99, 0x90, 0xff, 0xff, 0xff,
+ 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xf0,
+
+ /* U+002E "." */
+ 0x0, 0x2, 0x0, 0x4, 0xff, 0xd2, 0xe, 0xff,
+ 0xfa, 0x1f, 0xff, 0xfd, 0xd, 0xff, 0xf9, 0x2,
+ 0xcf, 0xa1,
+
+ /* U+002F "/" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xff,
+ 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf,
+ 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f,
+ 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e,
+ 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9,
+ 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4,
+ 0xff, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xdf, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x8f, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x2f, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x6, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x1, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xaf, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x5f, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xe, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x9, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x3, 0xff, 0x40, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xdf, 0xa0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xe1, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x2f, 0xf5, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xb, 0xfb, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x6, 0xff, 0x20, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+
+ /* U+0030 "0" */
+ 0x0, 0x0, 0x3a, 0xdf, 0xeb, 0x60, 0x0, 0x0,
+ 0x0, 0x9f, 0xff, 0xff, 0xff, 0xc1, 0x0, 0x0,
+ 0x9f, 0xfe, 0x86, 0x8e, 0xff, 0xc0, 0x0, 0x3f,
+ 0xfc, 0x10, 0x0, 0x1c, 0xff, 0x60, 0xb, 0xff,
+ 0x20, 0x0, 0x0, 0x2f, 0xfd, 0x1, 0xff, 0xa0,
+ 0x0, 0x0, 0x0, 0xbf, 0xf2, 0x5f, 0xf6, 0x0,
+ 0x0, 0x0, 0x9f, 0xff, 0x67, 0xff, 0x30, 0x0,
+ 0x1, 0xcf, 0xff, 0xf9, 0x9f, 0xf1, 0x0, 0x4,
+ 0xef, 0xf8, 0xff, 0xaa, 0xff, 0x0, 0x8, 0xff,
+ 0xd3, 0xf, 0xfb, 0xaf, 0xf0, 0x1b, 0xff, 0xa0,
+ 0x0, 0xff, 0xb9, 0xff, 0x3e, 0xff, 0x50, 0x0,
+ 0xf, 0xfa, 0x8f, 0xff, 0xfc, 0x20, 0x0, 0x2,
+ 0xff, 0x85, 0xff, 0xf8, 0x0, 0x0, 0x0, 0x5f,
+ 0xf5, 0x2f, 0xfb, 0x0, 0x0, 0x0, 0x9, 0xff,
+ 0x10, 0xdf, 0xf2, 0x0, 0x0, 0x1, 0xff, 0xc0,
+ 0x6, 0xff, 0xc0, 0x0, 0x0, 0xcf, 0xf4, 0x0,
+ 0xc, 0xff, 0xe8, 0x57, 0xdf, 0xfa, 0x0, 0x0,
+ 0x1c, 0xff, 0xff, 0xff, 0xfa, 0x0, 0x0, 0x0,
+ 0x6, 0xbe, 0xfe, 0xa4, 0x0, 0x0,
+
+ /* U+0031 "1" */
+ 0x0, 0x0, 0x18, 0xff, 0xa0, 0x0, 0x0, 0x0,
+ 0x7, 0xff, 0xff, 0xa0, 0x0, 0x0, 0x7, 0xef,
+ 0xff, 0xff, 0xa0, 0x0, 0x0, 0xcf, 0xff, 0xa6,
+ 0xff, 0xa0, 0x0, 0x0, 0x7f, 0xc3, 0x4, 0xff,
+ 0xa0, 0x0, 0x0, 0x4, 0x0, 0x4, 0xff, 0xa0,
+ 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0xa0, 0x0,
+ 0x0, 0x0, 0x0, 0x4, 0xff, 0xa0, 0x0, 0x0,
+ 0x0, 0x0, 0x4, 0xff, 0xa0, 0x0, 0x0, 0x0,
+ 0x0, 0x4, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0,
+ 0x4, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x4,
+ 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff,
+ 0xa0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0xa0,
+ 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0xa0, 0x0,
+ 0x0, 0x0, 0x0, 0x4, 0xff, 0xa0, 0x0, 0x0,
+ 0x0, 0x0, 0x4, 0xff, 0xa0, 0x0, 0x0, 0x28,
+ 0x88, 0x8a, 0xff, 0xd8, 0x88, 0x80, 0x5f, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xf1, 0x5f, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xf1,
+
+ /* U+0032 "2" */
+ 0x0, 0x17, 0xce, 0xfe, 0xa3, 0x0, 0x0, 0x5,
+ 0xef, 0xff, 0xff, 0xff, 0x70, 0x0, 0x6f, 0xff,
+ 0xa7, 0x7c, 0xff, 0xf4, 0x0, 0x1e, 0xb1, 0x0,
+ 0x0, 0x8f, 0xfc, 0x0, 0x2, 0x0, 0x0, 0x0,
+ 0xe, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, 0xb,
+ 0xff, 0x20, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff,
+ 0x20, 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3f, 0xf9, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xdf, 0xf2, 0x0, 0x0, 0x0,
+ 0x0, 0xa, 0xff, 0x60, 0x0, 0x0, 0x0, 0x0,
+ 0x9f, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x9, 0xff,
+ 0xa0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xfa, 0x0,
+ 0x0, 0x0, 0x0, 0xa, 0xff, 0xa0, 0x0, 0x0,
+ 0x0, 0x0, 0xaf, 0xf9, 0x0, 0x0, 0x0, 0x0,
+ 0xa, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, 0x9f,
+ 0xff, 0x99, 0x99, 0x99, 0x99, 0x92, 0xcf, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xf4, 0xcf, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xf4,
+
+ /* U+0033 "3" */
+ 0x5, 0x9c, 0xef, 0xfd, 0x93, 0x0, 0x0, 0xff,
+ 0xff, 0xff, 0xff, 0xf9, 0x0, 0xe, 0xb8, 0x76,
+ 0x7b, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x6,
+ 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfe,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0,
+ 0x0, 0x0, 0x0, 0x5f, 0xf6, 0x0, 0x0, 0x0,
+ 0x2, 0x8f, 0xfa, 0x0, 0x0, 0x1f, 0xff, 0xff,
+ 0xf6, 0x0, 0x0, 0x1, 0xff, 0xff, 0xff, 0xe7,
+ 0x0, 0x0, 0x4, 0x44, 0x69, 0xef, 0xfa, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0xcf, 0xf5, 0x0, 0x0,
+ 0x0, 0x0, 0x1, 0xff, 0xb0, 0x0, 0x0, 0x0,
+ 0x0, 0xe, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf8,
+ 0x0, 0x0, 0x0, 0x0, 0x3e, 0xff, 0x15, 0x97,
+ 0x65, 0x68, 0xcf, 0xff, 0x50, 0x8f, 0xff, 0xff,
+ 0xff, 0xfd, 0x40, 0x6, 0xde, 0xff, 0xed, 0xa5,
+ 0x0, 0x0,
+
+ /* U+0034 "4" */
+ 0x0, 0x0, 0x0, 0x0, 0x4f, 0xff, 0xd0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, 0xfd, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, 0xff, 0xd0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0x8d, 0xfd,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xd0, 0xdf,
+ 0xd0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf3, 0xd,
+ 0xfd, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xf8, 0x0,
+ 0xdf, 0xd0, 0x0, 0x0, 0x0, 0xc, 0xfd, 0x0,
+ 0xd, 0xfd, 0x0, 0x0, 0x0, 0x6, 0xff, 0x30,
+ 0x0, 0xdf, 0xd0, 0x0, 0x0, 0x1, 0xff, 0x90,
+ 0x0, 0xd, 0xfd, 0x0, 0x0, 0x0, 0xbf, 0xe0,
+ 0x0, 0x0, 0xdf, 0xd0, 0x0, 0x0, 0x6f, 0xf4,
+ 0x0, 0x0, 0xd, 0xfd, 0x0, 0x0, 0x1e, 0xf9,
+ 0x0, 0x0, 0x0, 0xdf, 0xd0, 0x0, 0x5, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x5f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x32,
+ 0x66, 0x66, 0x66, 0x66, 0x6e, 0xfe, 0x66, 0x61,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xd0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xfd, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xd0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xfd,
+ 0x0, 0x0,
+
+ /* U+0035 "5" */
+ 0xf, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x0, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xb0, 0xf, 0xfb, 0x66,
+ 0x66, 0x66, 0x64, 0x0, 0xff, 0x80, 0x0, 0x0,
+ 0x0, 0x0, 0xf, 0xf8, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0xf,
+ 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xb5,
+ 0x54, 0x20, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff,
+ 0xe9, 0x20, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x40, 0x0, 0x0, 0x0, 0x25, 0xcf, 0xfe, 0x10,
+ 0x0, 0x0, 0x0, 0x0, 0xbf, 0xf7, 0x0, 0x0,
+ 0x0, 0x0, 0x3, 0xff, 0xa0, 0x0, 0x0, 0x0,
+ 0x0, 0x1f, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x3,
+ 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf5,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0xfc, 0x3, 0x97,
+ 0x65, 0x68, 0xdf, 0xfe, 0x20, 0x5f, 0xff, 0xff,
+ 0xff, 0xfb, 0x10, 0x3, 0xdf, 0xff, 0xec, 0x93,
+ 0x0, 0x0,
+
+ /* U+0036 "6" */
+ 0x0, 0x0, 0x0, 0x39, 0xce, 0xff, 0xf0, 0x0,
+ 0x0, 0x3, 0xcf, 0xff, 0xff, 0xff, 0x0, 0x0,
+ 0x5, 0xff, 0xfe, 0xa7, 0x66, 0x50, 0x0, 0x2,
+ 0xff, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf,
+ 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xfe, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xa2, 0x8c,
+ 0xef, 0xeb, 0x50, 0x0, 0xf, 0xfe, 0xff, 0xff,
+ 0xff, 0xff, 0xa0, 0x0, 0xff, 0xff, 0xb6, 0x44,
+ 0x7f, 0xff, 0x80, 0x1f, 0xfc, 0x20, 0x0, 0x0,
+ 0x2f, 0xff, 0x12, 0xff, 0x90, 0x0, 0x0, 0x0,
+ 0x9f, 0xf5, 0x1f, 0xfa, 0x0, 0x0, 0x0, 0x5,
+ 0xff, 0x70, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x4f,
+ 0xf7, 0xd, 0xff, 0x0, 0x0, 0x0, 0x6, 0xff,
+ 0x50, 0x9f, 0xf4, 0x0, 0x0, 0x0, 0xbf, 0xf1,
+ 0x3, 0xff, 0xd0, 0x0, 0x0, 0x5f, 0xfa, 0x0,
+ 0xa, 0xff, 0xd6, 0x44, 0x9f, 0xfe, 0x10, 0x0,
+ 0xb, 0xff, 0xff, 0xff, 0xfd, 0x20, 0x0, 0x0,
+ 0x5, 0xbe, 0xfe, 0xb6, 0x0, 0x0,
+
+ /* U+0037 "7" */
+ 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x23,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x28,
+ 0x88, 0x88, 0x88, 0x88, 0x8d, 0xff, 0x10, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0xff, 0xb0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x8f, 0xf3, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1f, 0xfc, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x8, 0xff, 0x40, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x7f, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe,
+ 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff,
+ 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xe0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf6, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xe, 0xfe, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x7, 0xff, 0x70, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xf0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x6f, 0xf8, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xe, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0,
+ 0x6, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xef, 0xf1, 0x0, 0x0, 0x0, 0x0,
+
+ /* U+0038 "8" */
+ 0x0, 0x0, 0x7c, 0xef, 0xfd, 0x93, 0x0, 0x0,
+ 0x3, 0xef, 0xff, 0xff, 0xff, 0xf7, 0x0, 0x1,
+ 0xef, 0xfa, 0x64, 0x6a, 0xff, 0xf4, 0x0, 0x8f,
+ 0xf6, 0x0, 0x0, 0x5, 0xff, 0xa0, 0xb, 0xff,
+ 0x0, 0x0, 0x0, 0xf, 0xfc, 0x0, 0xbf, 0xf1,
+ 0x0, 0x0, 0x0, 0xff, 0xa0, 0x7, 0xff, 0xa0,
+ 0x0, 0x0, 0x8f, 0xf6, 0x0, 0xe, 0xff, 0xc2,
+ 0x0, 0x9f, 0xfc, 0x0, 0x0, 0x2d, 0xff, 0xfb,
+ 0xef, 0xfb, 0x0, 0x0, 0x0, 0x9, 0xff, 0xff,
+ 0xf8, 0x0, 0x0, 0x0, 0x6, 0xef, 0xff, 0xff,
+ 0xf9, 0x0, 0x0, 0x9, 0xff, 0xd4, 0x7, 0xff,
+ 0xfc, 0x0, 0x6, 0xff, 0xb0, 0x0, 0x1, 0xcf,
+ 0xf9, 0x0, 0xef, 0xf1, 0x0, 0x0, 0x1, 0xef,
+ 0xf1, 0x2f, 0xfb, 0x0, 0x0, 0x0, 0xb, 0xff,
+ 0x32, 0xff, 0xb0, 0x0, 0x0, 0x0, 0xbf, 0xf3,
+ 0xf, 0xff, 0x50, 0x0, 0x0, 0x4f, 0xfe, 0x0,
+ 0x8f, 0xff, 0xb7, 0x56, 0xaf, 0xff, 0x70, 0x0,
+ 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x0, 0x0,
+ 0x39, 0xdf, 0xfe, 0xc8, 0x20, 0x0,
+
+ /* U+0039 "9" */
+ 0x0, 0x0, 0x7c, 0xef, 0xea, 0x40, 0x0, 0x0,
+ 0x3, 0xef, 0xff, 0xff, 0xff, 0x90, 0x0, 0x2,
+ 0xff, 0xfa, 0x54, 0x6d, 0xff, 0x80, 0x0, 0xcf,
+ 0xf5, 0x0, 0x0, 0xc, 0xff, 0x10, 0x2f, 0xfa,
+ 0x0, 0x0, 0x0, 0x3f, 0xf8, 0x6, 0xff, 0x50,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x7f, 0xf5, 0x0,
+ 0x0, 0x0, 0xb, 0xff, 0x6, 0xff, 0x70, 0x0,
+ 0x0, 0x0, 0xaf, 0xf1, 0x2f, 0xfd, 0x0, 0x0,
+ 0x0, 0xa, 0xff, 0x20, 0xbf, 0xfc, 0x30, 0x2,
+ 0x6c, 0xff, 0xf1, 0x1, 0xef, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x0, 0x1, 0x9e, 0xff, 0xff, 0xc6,
+ 0xaf, 0xf0, 0x0, 0x0, 0x1, 0x22, 0x0, 0xc,
+ 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff,
+ 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf3,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xfc, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0x20, 0x0,
+ 0x16, 0x66, 0x8b, 0xff, 0xfe, 0x40, 0x0, 0x4,
+ 0xff, 0xff, 0xff, 0xfb, 0x20, 0x0, 0x0, 0x4f,
+ 0xfe, 0xdb, 0x72, 0x0, 0x0, 0x0,
+
+ /* U+003A ":" */
+ 0x1a, 0xfb, 0x19, 0xff, 0xf9, 0xcf, 0xff, 0xc7,
+ 0xff, 0xf8, 0x8, 0xc8, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x7c, 0x80, 0x7f, 0xff,
+ 0x8b, 0xff, 0xfc, 0x9f, 0xff, 0x91, 0xbf, 0xb1,
+
+ /* U+003B ";" */
+ 0x0, 0x1, 0xaf, 0xb1, 0x0, 0x0, 0x9f, 0xff,
+ 0x90, 0x0, 0xc, 0xff, 0xfc, 0x0, 0x0, 0x7f,
+ 0xff, 0x80, 0x0, 0x0, 0x8c, 0x80, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
+ 0x0, 0x0, 0x0, 0x2e, 0xfc, 0x10, 0x0, 0x9,
+ 0xff, 0xfa, 0x0, 0x0, 0x8f, 0xff, 0xf0, 0x0,
+ 0x1, 0xef, 0xff, 0x0, 0x0, 0x6, 0xff, 0xf0,
+ 0x0, 0x0, 0x4f, 0xfc, 0x0, 0x0, 0x9, 0xff,
+ 0x60, 0x1, 0x4b, 0xff, 0xc0, 0x3, 0xff, 0xff,
+ 0xb1, 0x0, 0x3f, 0xfb, 0x50, 0x0, 0x0, 0x10,
+ 0x0, 0x0, 0x0,
+
+ /* U+003C "<" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0,
+ 0x0, 0x0, 0xa, 0xe2, 0x0, 0x0, 0x0, 0x1,
+ 0xcf, 0xf9, 0x0, 0x0, 0x0, 0x2d, 0xff, 0x90,
+ 0x0, 0x0, 0x3, 0xef, 0xf7, 0x0, 0x0, 0x0,
+ 0x5f, 0xff, 0x40, 0x0, 0x0, 0x7, 0xff, 0xe3,
+ 0x0, 0x0, 0x0, 0x9f, 0xfc, 0x10, 0x0, 0x0,
+ 0xb, 0xff, 0xb0, 0x0, 0x0, 0x0, 0xaf, 0xfe,
+ 0x0, 0x0, 0x0, 0x0, 0xa, 0xff, 0xc1, 0x0,
+ 0x0, 0x0, 0x0, 0x8f, 0xfd, 0x20, 0x0, 0x0,
+ 0x0, 0x6, 0xff, 0xe4, 0x0, 0x0, 0x0, 0x0,
+ 0x4f, 0xff, 0x60, 0x0, 0x0, 0x0, 0x3, 0xef,
+ 0xf8, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xff, 0xa0,
+ 0x0, 0x0, 0x0, 0x0, 0xbf, 0xf9, 0x0, 0x0,
+ 0x0, 0x0, 0x9, 0xd1, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x10,
+
+ /* U+003D "=" */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x45, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x50, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
+
+ /* U+003E ">" */
+ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xb0,
+ 0x0, 0x0, 0x0, 0x0, 0x9f, 0xfc, 0x10, 0x0,
+ 0x0, 0x0, 0x9, 0xff, 0xe2, 0x0, 0x0, 0x0,
+ 0x0, 0x6f, 0xff, 0x40, 0x0, 0x0, 0x0, 0x4,
+ 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x3e, 0xff,
+ 0x80, 0x0, 0x0, 0x0, 0x1, 0xdf, 0xfa, 0x0,
+ 0x0, 0x0, 0x0, 0xb, 0xff, 0xc1, 0x0, 0x0,
+ 0x0, 0x0, 0xdf, 0xfa, 0x0, 0x0, 0x0, 0xb,
+ 0xff, 0xb0, 0x0, 0x0, 0x1, 0xdf, 0xf9, 0x0,
+ 0x0, 0x0, 0x3e, 0xff, 0x70, 0x0, 0x0, 0x5,
+ 0xff, 0xf5, 0x0, 0x0, 0x0, 0x7f, 0xfe, 0x30,
+ 0x0, 0x0, 0x9, 0xff, 0xd2, 0x0, 0x0, 0x0,
+ 0x9f, 0xfc, 0x10, 0x0, 0x0, 0x0, 0x1d, 0xa0,
+ 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
+ 0x0, 0x0,
+
+ /* U+003F "?" */
+ 0x6f, 0xeb, 0x72, 0x0, 0x0, 0x6f, 0xff, 0xff,
+ 0xa1, 0x0, 0x27, 0x9c, 0xff, 0xfd, 0x10, 0x0,
+ 0x0, 0x2c, 0xff, 0xc0, 0x0, 0x0, 0x0, 0xcf,
+ 0xf6, 0x0, 0x0, 0x0, 0x3f, 0xfb, 0x0, 0x0,
+ 0x0, 0xf, 0xfe, 0x0, 0x0, 0x0, 0xf, 0xfe,
+ 0x0, 0x0, 0x0, 0x3f, 0xfc, 0x0, 0x11, 0x15,
+ 0xef, 0xf6, 0x0, 0xef, 0xff, 0xff, 0xb0, 0x0,
+ 0xef, 0xff, 0xc6, 0x0, 0x0, 0xdf, 0x90, 0x0,
+ 0x0, 0x0, 0xdf, 0x90, 0x0, 0x0, 0x0, 0xcf,
+ 0x80, 0x0, 0x0, 0x0, 0x9c, 0x60, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0,
+ 0x0, 0x0, 0x1, 0xdf, 0xa0, 0x0, 0x0, 0x8,
+ 0xff, 0xf4, 0x0, 0x0, 0x7, 0xff, 0xf3, 0x0,
+ 0x0, 0x1, 0xbf, 0x90, 0x0, 0x0,
+
+ /* U+0040 "@" */
+ 0x0, 0x0, 0x0, 0x18, 0xdf, 0xec, 0x70, 0x0,
+ 0x0, 0x0, 0x0, 0x6f, 0xff, 0xff, 0xff, 0xd2,
+ 0x0, 0x0, 0x0, 0x7f, 0xf9, 0x20, 0x4, 0xdf,
+ 0xd0, 0x0, 0x0, 0x5f, 0xf6, 0x0, 0x0, 0x1,
+ 0xef, 0x70, 0x0, 0x1e, 0xf8, 0x0, 0x0, 0x0,
+ 0x5, 0xfe, 0x0, 0x8, 0xfd, 0x0, 0x0, 0x0,
+ 0x0, 0xe, 0xf3, 0x0, 0xff, 0x50, 0x0, 0x0,
+ 0x0, 0x0, 0xbf, 0x70, 0x6f, 0xd0, 0x0, 0x8e,
+ 0xfc, 0xad, 0x8, 0xf9, 0xb, 0xf8, 0x0, 0xbf,
+ 0xff, 0xff, 0xc0, 0x6f, 0xb0, 0xff, 0x30, 0x6f,
+ 0xf4, 0x1d, 0xf9, 0x5, 0xfc, 0x4f, 0xf0, 0xd,
+ 0xf9, 0x0, 0xef, 0x70, 0x4f, 0xd7, 0xfc, 0x2,
+ 0xff, 0x30, 0xf, 0xf5, 0x5, 0xfc, 0x9f, 0x90,
+ 0x6f, 0xf0, 0x3, 0xff, 0x20, 0x5f, 0xbb, 0xf7,
+ 0x9, 0xfc, 0x0, 0x5f, 0xf0, 0x7, 0xfa, 0xcf,
+ 0x50, 0xbf, 0xb0, 0x8, 0xfd, 0x0, 0x9f, 0x8d,
+ 0xf5, 0xb, 0xfa, 0x0, 0xaf, 0xb0, 0xc, 0xf5,
+ 0xdf, 0x40, 0xbf, 0xb0, 0x1e, 0xfa, 0x1, 0xff,
+ 0x1c, 0xf5, 0x9, 0xfe, 0x1a, 0xff, 0xd1, 0x9f,
+ 0xb0, 0xbf, 0x60, 0x4f, 0xff, 0xf7, 0xef, 0xff,
+ 0xf2, 0xa, 0xf8, 0x0, 0x7f, 0xf9, 0x5, 0xef,
+ 0xc3, 0x0, 0x8f, 0xa0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x5, 0xfe, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1f, 0xf3, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xbf, 0xb0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0x60, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0xa, 0xff, 0x92,
+ 0x0, 0x14, 0xad, 0x0, 0x0, 0x0, 0xa, 0xff,
+ 0xff, 0xff, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x4,
+ 0xae, 0xff, 0xda, 0x50, 0x0, 0x0,
+
+ /* U+0041 "A" */
+ 0x0, 0x0, 0x0, 0x7f, 0xff, 0x90, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xc, 0xff, 0xfe, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0xff, 0xef, 0xf3, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x6f, 0xf5, 0xff, 0x80,
+ 0x0, 0x0, 0x0, 0x0, 0xc, 0xfd, 0xe, 0xfd,
+ 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0x80, 0x9f,
+ 0xf3, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xf2, 0x4,
+ 0xff, 0x80, 0x0, 0x0, 0x0, 0xb, 0xfd, 0x0,
+ 0xe, 0xfd, 0x0, 0x0, 0x0, 0x1, 0xff, 0x80,
+ 0x0, 0x9f, 0xf2, 0x0, 0x0, 0x0, 0x6f, 0xf3,
+ 0x0, 0x4, 0xff, 0x70, 0x0, 0x0, 0xb, 0xfe,
+ 0x0, 0x0, 0xf, 0xfd, 0x0, 0x0, 0x1, 0xff,
+ 0x90, 0x0, 0x0, 0xaf, 0xf2, 0x0, 0x0, 0x6f,
+ 0xf4, 0x0, 0x0, 0x5, 0xff, 0x70, 0x0, 0xb,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x1,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x0,
+ 0x5f, 0xf9, 0x77, 0x77, 0x77, 0x7a, 0xff, 0x60,
+ 0xb, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xfc,
+ 0x0, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xcf,
+ 0xf1, 0x5f, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x8,
+ 0xff, 0x6a, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0,
+ 0x3f, 0xfb,
+
+ /* U+0042 "B" */
+ 0x9f, 0xff, 0xff, 0xfe, 0xc8, 0x20, 0x0, 0x9f,
+ 0xff, 0xff, 0xff, 0xff, 0xf6, 0x0, 0x9f, 0xf6,
+ 0x55, 0x68, 0xdf, 0xff, 0x20, 0x9f, 0xf1, 0x0,
+ 0x0, 0xa, 0xff, 0x80, 0x9f, 0xf1, 0x0, 0x0,
+ 0x3, 0xff, 0xa0, 0x9f, 0xf1, 0x0, 0x0, 0x3,
+ 0xff, 0x80, 0x9f, 0xf1, 0x0, 0x0, 0x9, 0xff,
+ 0x30, 0x9f, 0xf1, 0x0, 0x13, 0xaf, 0xf9, 0x0,
+ 0x9f, 0xff, 0xff, 0xff, 0xfd, 0x50, 0x0, 0x9f,
+ 0xff, 0xff, 0xff, 0xff, 0xc3, 0x0, 0x9f, 0xf6,
+ 0x55, 0x68, 0xdf, 0xff, 0x30, 0x9f, 0xf1, 0x0,
+ 0x0, 0x8, 0xff, 0xd0, 0x9f, 0xf1, 0x0, 0x0,
+ 0x0, 0xcf, 0xf3, 0x9f, 0xf1, 0x0, 0x0, 0x0,
+ 0x8f, 0xf5, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x8f,
+ 0xf4, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0xcf, 0xf1,
+ 0x9f, 0xf1, 0x0, 0x0, 0x7, 0xff, 0xb0, 0x9f,
+ 0xf6, 0x55, 0x57, 0xcf, 0xfe, 0x20, 0x9f, 0xff,
+ 0xff, 0xff, 0xff, 0xd2, 0x0, 0x9f, 0xff, 0xff,
+ 0xfd, 0xa5, 0x0, 0x0,
+
+ /* U+0043 "C" */
+ 0x0, 0x0, 0x3, 0x8d, 0xef, 0xdc, 0x93, 0x0,
+ 0x0, 0x1a, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x0,
+ 0x1d, 0xff, 0xfc, 0x98, 0x8b, 0xff, 0x10, 0xb,
+ 0xff, 0xc2, 0x0, 0x0, 0x0, 0x60, 0x5, 0xff,
+ 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xf3,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xfc, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x5, 0xff, 0x80, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf5, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x9, 0xff, 0x40, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x9f, 0xf4, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x8, 0xff, 0x50, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xf7, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x4, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xf, 0xff, 0x20, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x9f, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x2, 0xff, 0xfb, 0x10, 0x0, 0x0, 0x5, 0x0,
+ 0x5, 0xff, 0xff, 0xb8, 0x88, 0xbf, 0xf1, 0x0,
+ 0x4, 0xef, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0,
+ 0x0, 0x6a, 0xef, 0xfe, 0xc8, 0x30,
+
+ /* U+0044 "D" */
+ 0x5f, 0xff, 0xff, 0xfe, 0xb7, 0x10, 0x0, 0x5,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0, 0x5f,
+ 0xf9, 0x55, 0x68, 0xcf, 0xff, 0xa0, 0x5, 0xff,
+ 0x50, 0x0, 0x0, 0x4e, 0xff, 0x60, 0x5f, 0xf5,
+ 0x0, 0x0, 0x0, 0x3f, 0xfe, 0x5, 0xff, 0x50,
+ 0x0, 0x0, 0x0, 0xaf, 0xf5, 0x5f, 0xf5, 0x0,
+ 0x0, 0x0, 0x4, 0xff, 0x95, 0xff, 0x50, 0x0,
+ 0x0, 0x0, 0x1f, 0xfc, 0x5f, 0xf5, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0xd5, 0xff, 0x50, 0x0, 0x0,
+ 0x0, 0xe, 0xfe, 0x5f, 0xf5, 0x0, 0x0, 0x0,
+ 0x0, 0xef, 0xe5, 0xff, 0x50, 0x0, 0x0, 0x0,
+ 0xf, 0xfc, 0x5f, 0xf5, 0x0, 0x0, 0x0, 0x2,
+ 0xff, 0xb5, 0xff, 0x50, 0x0, 0x0, 0x0, 0x6f,
+ 0xf7, 0x5f, 0xf5, 0x0, 0x0, 0x0, 0xc, 0xff,
+ 0x25, 0xff, 0x50, 0x0, 0x0, 0x7, 0xff, 0xb0,
+ 0x5f, 0xf5, 0x0, 0x0, 0x8, 0xff, 0xf2, 0x5,
+ 0xff, 0x96, 0x67, 0xae, 0xff, 0xf5, 0x0, 0x5f,
+ 0xff, 0xff, 0xff, 0xff, 0xc3, 0x0, 0x5, 0xff,
+ 0xff, 0xfe, 0xc9, 0x30, 0x0, 0x0,
+
+ /* U+0045 "E" */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xf4, 0xff, 0xd5, 0x55, 0x55,
+ 0x55, 0x51, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0,
+ 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xb0,
+ 0x0, 0x0, 0x0, 0x0, 0xff, 0xb0, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xf0, 0xff, 0xd5, 0x55, 0x55,
+ 0x55, 0x50, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0,
+ 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xb0,
+ 0x0, 0x0, 0x0, 0x0, 0xff, 0xb0, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0,
+ 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xd6,
+ 0x66, 0x66, 0x66, 0x61, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4,
+
+ /* U+0046 "F" */
+ 0xef, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xef, 0xff,
+ 0xff, 0xff, 0xff, 0xf4, 0xef, 0xe6, 0x66, 0x66,
+ 0x66, 0x61, 0xef, 0xd0, 0x0, 0x0, 0x0, 0x0,
+ 0xef, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xd0,
+ 0x0, 0x0, 0x0, 0x0, 0xef, 0xd0, 0x0, 0x0,
+ 0x0, 0x0, 0xef, 0xd0, 0x0, 0x0, 0x0, 0x0,
+ 0xef, 0xe5, 0x55, 0x55, 0x55, 0x40, 0xef, 0xff,
+ 0xff, 0xff, 0xff, 0xd0, 0xef, 0xff, 0xff, 0xff,
+ 0xff, 0xd0, 0xef, 0xd0, 0x0, 0x0, 0x0, 0x0,
+ 0xef, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xd0,
+ 0x0, 0x0, 0x0, 0x0, 0xef, 0xd0, 0x0, 0x0,
+ 0x0, 0x0, 0xef, 0xd0, 0x0, 0x0, 0x0, 0x0,
+ 0xef, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xd0,
+ 0x0, 0x0, 0x0, 0x0, 0xef, 0xd0, 0x0, 0x0,
+ 0x0, 0x0, 0xef, 0xd0, 0x0, 0x0, 0x0, 0x0,
+
+ /* U+0047 "G" */
+ 0x0, 0x0, 0x3, 0x9d, 0xef, 0xec, 0x94, 0x0,
+ 0x0, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x0,
+ 0x3e, 0xff, 0xfc, 0x98, 0x9b, 0xff, 0x30, 0x1e,
+ 0xff, 0xb2, 0x0, 0x0, 0x0, 0x41, 0xa, 0xff,
+ 0xa0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xff, 0xe0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf7, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, 0x20, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xef, 0xe0, 0x0, 0x6,
+ 0xff, 0xff, 0xff, 0x5f, 0xfd, 0x0, 0x0, 0x6f,
+ 0xff, 0xff, 0xf5, 0xff, 0xd0, 0x0, 0x1, 0x44,
+ 0x48, 0xff, 0x5e, 0xfe, 0x0, 0x0, 0x0, 0x0,
+ 0x5f, 0xf5, 0xdf, 0xf0, 0x0, 0x0, 0x0, 0x5,
+ 0xff, 0x59, 0xff, 0x40, 0x0, 0x0, 0x0, 0x5f,
+ 0xf5, 0x5f, 0xfb, 0x0, 0x0, 0x0, 0x5, 0xff,
+ 0x50, 0xef, 0xf5, 0x0, 0x0, 0x0, 0x5f, 0xf5,
+ 0x6, 0xff, 0xf7, 0x0, 0x0, 0x5, 0xff, 0x50,
+ 0x9, 0xff, 0xfe, 0xa8, 0x79, 0xdf, 0xf5, 0x0,
+ 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0,
+ 0x1, 0x7b, 0xef, 0xfd, 0xb7, 0x10,
+
+ /* U+0048 "H" */
+ 0x5f, 0xf6, 0x0, 0x0, 0x0, 0x5, 0xff, 0x65,
+ 0xff, 0x60, 0x0, 0x0, 0x0, 0x5f, 0xf6, 0x5f,
+ 0xf6, 0x0, 0x0, 0x0, 0x5, 0xff, 0x65, 0xff,
+ 0x60, 0x0, 0x0, 0x0, 0x5f, 0xf6, 0x5f, 0xf6,
+ 0x0, 0x0, 0x0, 0x5, 0xff, 0x65, 0xff, 0x60,
+ 0x0, 0x0, 0x0, 0x5f, 0xf6, 0x5f, 0xf6, 0x0,
+ 0x0, 0x0, 0x5, 0xff, 0x65, 0xff, 0x60, 0x0,
+ 0x0, 0x0, 0x5f, 0xf6, 0x5f, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0x65, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xf6, 0x5f, 0xfa, 0x66, 0x66, 0x66,
+ 0x69, 0xff, 0x65, 0xff, 0x60, 0x0, 0x0, 0x0,
+ 0x5f, 0xf6, 0x5f, 0xf6, 0x0, 0x0, 0x0, 0x5,
+ 0xff, 0x65, 0xff, 0x60, 0x0, 0x0, 0x0, 0x5f,
+ 0xf6, 0x5f, 0xf6, 0x0, 0x0, 0x0, 0x5, 0xff,
+ 0x65, 0xff, 0x60, 0x0, 0x0, 0x0, 0x5f, 0xf6,
+ 0x5f, 0xf6, 0x0, 0x0, 0x0, 0x5, 0xff, 0x65,
+ 0xff, 0x60, 0x0, 0x0, 0x0, 0x5f, 0xf6, 0x5f,
+ 0xf6, 0x0, 0x0, 0x0, 0x5, 0xff, 0x65, 0xff,
+ 0x60, 0x0, 0x0, 0x0, 0x5f, 0xf6,
+
+ /* U+0049 "I" */
+ 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x76, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xf7, 0x25, 0x55, 0x5e,
+ 0xfe, 0x55, 0x55, 0x20, 0x0, 0x0, 0xdf, 0xe0,
+ 0x0, 0x0, 0x0, 0x0, 0xd, 0xfe, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xdf, 0xe0, 0x0, 0x0, 0x0,
+ 0x0, 0xd, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xdf, 0xe0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xfe,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xe0, 0x0,
+ 0x0, 0x0, 0x0, 0xd, 0xfe, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xdf, 0xe0, 0x0, 0x0, 0x0, 0x0,
+ 0xd, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf,
+ 0xe0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xfe, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xdf, 0xe0, 0x0, 0x0,
+ 0x0, 0x0, 0xd, 0xfe, 0x0, 0x0, 0x2, 0x66,
+ 0x66, 0xef, 0xe6, 0x66, 0x62, 0x6f, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0x76, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xf7,
+
+ /* U+004A "J" */
+ 0xf, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xf, 0xff,
+ 0xff, 0xff, 0xff, 0xf4, 0x6, 0x66, 0x66, 0x66,
+ 0xbf, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0,
+ 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0,
+ 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0,
+ 0x9f, 0xf3, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xf1,
+ 0x36, 0x0, 0x0, 0x6, 0xff, 0xb0, 0x4f, 0xea,
+ 0x77, 0xbf, 0xff, 0x30, 0x3f, 0xff, 0xff, 0xff,
+ 0xf5, 0x0, 0x3, 0x9d, 0xff, 0xd9, 0x20, 0x0,
+
+ /* U+004B "K" */
+ 0xaf, 0xf1, 0x0, 0x0, 0x2, 0xff, 0xe2, 0xaf,
+ 0xf1, 0x0, 0x0, 0xd, 0xff, 0x40, 0xaf, 0xf1,
+ 0x0, 0x0, 0xaf, 0xf7, 0x0, 0xaf, 0xf1, 0x0,
+ 0x6, 0xff, 0x90, 0x0, 0xaf, 0xf1, 0x0, 0x3f,
+ 0xfc, 0x0, 0x0, 0xaf, 0xf1, 0x1, 0xef, 0xe1,
+ 0x0, 0x0, 0xaf, 0xf1, 0xb, 0xff, 0x30, 0x0,
+ 0x0, 0xaf, 0xf1, 0x8f, 0xf5, 0x0, 0x0, 0x0,
+ 0xaf, 0xf6, 0xff, 0x80, 0x0, 0x0, 0x0, 0xaf,
+ 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xfc,
+ 0xff, 0x70, 0x0, 0x0, 0x0, 0xaf, 0xf2, 0xef,
+ 0xf4, 0x0, 0x0, 0x0, 0xaf, 0xf1, 0x3f, 0xfe,
+ 0x10, 0x0, 0x0, 0xaf, 0xf1, 0x7, 0xff, 0xc0,
+ 0x0, 0x0, 0xaf, 0xf1, 0x0, 0xbf, 0xf9, 0x0,
+ 0x0, 0xaf, 0xf1, 0x0, 0x1d, 0xff, 0x50, 0x0,
+ 0xaf, 0xf1, 0x0, 0x3, 0xff, 0xf2, 0x0, 0xaf,
+ 0xf1, 0x0, 0x0, 0x6f, 0xfd, 0x0, 0xaf, 0xf1,
+ 0x0, 0x0, 0xa, 0xff, 0xa0, 0xaf, 0xf1, 0x0,
+ 0x0, 0x0, 0xdf, 0xf7,
+
+ /* U+004C "L" */
+ 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0,
+ 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0,
+ 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0,
+ 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0,
+ 0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf8,
+ 0x66, 0x66, 0x66, 0x65, 0x7f, 0xff, 0xff, 0xff,
+ 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe,
+
+ /* U+004D "M" */
+ 0x5, 0xff, 0xf1, 0x0, 0x0, 0x2, 0xff, 0xf5,
+ 0x0, 0x5f, 0xff, 0x60, 0x0, 0x0, 0x7f, 0xff,
+ 0x60, 0x6, 0xff, 0xfc, 0x0, 0x0, 0xd, 0xff,
+ 0xf7, 0x0, 0x7f, 0xcf, 0xf2, 0x0, 0x3, 0xfd,
+ 0xdf, 0x80, 0x8, 0xfa, 0xcf, 0x70, 0x0, 0x9f,
+ 0x8d, 0xf8, 0x0, 0x9f, 0xa7, 0xfd, 0x0, 0xf,
+ 0xf2, 0xcf, 0x90, 0x9, 0xfa, 0x2f, 0xf3, 0x5,
+ 0xfd, 0xc, 0xfa, 0x0, 0xaf, 0xa0, 0xcf, 0x80,
+ 0xbf, 0x70, 0xbf, 0xb0, 0xb, 0xf9, 0x6, 0xfe,
+ 0x1f, 0xf1, 0xb, 0xfb, 0x0, 0xcf, 0x90, 0x1f,
+ 0xf9, 0xfb, 0x0, 0xaf, 0xc0, 0xc, 0xf8, 0x0,
+ 0xaf, 0xff, 0x50, 0xa, 0xfd, 0x0, 0xdf, 0x80,
+ 0x5, 0xff, 0xf0, 0x0, 0x9f, 0xe0, 0xe, 0xf8,
+ 0x0, 0xe, 0xfa, 0x0, 0x9, 0xff, 0x0, 0xff,
+ 0x70, 0x0, 0x57, 0x20, 0x0, 0x8f, 0xf0, 0xf,
+ 0xf7, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x0,
+ 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf1,
+ 0x1f, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff,
+ 0x22, 0xff, 0x50, 0x0, 0x0, 0x0, 0x0, 0x6f,
+ 0xf2, 0x3f, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x6,
+ 0xff, 0x33, 0xff, 0x40, 0x0, 0x0, 0x0, 0x0,
+ 0x5f, 0xf4,
+
+ /* U+004E "N" */
+ 0x3f, 0xff, 0x70, 0x0, 0x0, 0x4, 0xff, 0x43,
+ 0xff, 0xfe, 0x0, 0x0, 0x0, 0x4f, 0xf4, 0x3f,
+ 0xff, 0xf6, 0x0, 0x0, 0x4, 0xff, 0x43, 0xff,
+ 0xff, 0xe0, 0x0, 0x0, 0x4f, 0xf4, 0x3f, 0xf9,
+ 0xff, 0x50, 0x0, 0x4, 0xff, 0x43, 0xff, 0x5d,
+ 0xfd, 0x0, 0x0, 0x4f, 0xf4, 0x3f, 0xf5, 0x7f,
+ 0xf4, 0x0, 0x4, 0xff, 0x43, 0xff, 0x51, 0xff,
+ 0xc0, 0x0, 0x4f, 0xf4, 0x3f, 0xf5, 0x9, 0xff,
+ 0x30, 0x4, 0xff, 0x43, 0xff, 0x50, 0x1f, 0xfa,
+ 0x0, 0x4f, 0xf4, 0x3f, 0xf5, 0x0, 0xaf, 0xf2,
+ 0x4, 0xff, 0x43, 0xff, 0x50, 0x2, 0xff, 0x90,
+ 0x4f, 0xf4, 0x3f, 0xf5, 0x0, 0xb, 0xff, 0x14,
+ 0xff, 0x43, 0xff, 0x50, 0x0, 0x4f, 0xf7, 0x4f,
+ 0xf4, 0x3f, 0xf5, 0x0, 0x0, 0xcf, 0xe4, 0xff,
+ 0x43, 0xff, 0x50, 0x0, 0x5, 0xff, 0x9f, 0xf4,
+ 0x3f, 0xf5, 0x0, 0x0, 0xd, 0xff, 0xff, 0x43,
+ 0xff, 0x50, 0x0, 0x0, 0x6f, 0xff, 0xf4, 0x3f,
+ 0xf5, 0x0, 0x0, 0x0, 0xef, 0xff, 0x43, 0xff,
+ 0x50, 0x0, 0x0, 0x7, 0xff, 0xf4,
+
+ /* U+004F "O" */
+ 0x0, 0x0, 0x4, 0xae, 0xfe, 0xc7, 0x10, 0x0,
+ 0x0, 0x0, 0xb, 0xff, 0xff, 0xff, 0xfe, 0x40,
+ 0x0, 0x0, 0xc, 0xff, 0xe9, 0x79, 0xef, 0xff,
+ 0x30, 0x0, 0x8, 0xff, 0xb1, 0x0, 0x0, 0x9f,
+ 0xfd, 0x0, 0x1, 0xff, 0xe1, 0x0, 0x0, 0x0,
+ 0xcf, 0xf5, 0x0, 0x7f, 0xf6, 0x0, 0x0, 0x0,
+ 0x4, 0xff, 0xa0, 0xb, 0xff, 0x10, 0x0, 0x0,
+ 0x0, 0xf, 0xfe, 0x0, 0xef, 0xd0, 0x0, 0x0,
+ 0x0, 0x0, 0xcf, 0xf0, 0xf, 0xfb, 0x0, 0x0,
+ 0x0, 0x0, 0xa, 0xff, 0x21, 0xff, 0xa0, 0x0,
+ 0x0, 0x0, 0x0, 0x9f, 0xf3, 0x1f, 0xfa, 0x0,
+ 0x0, 0x0, 0x0, 0x9, 0xff, 0x21, 0xff, 0xb0,
+ 0x0, 0x0, 0x0, 0x0, 0xaf, 0xf1, 0xf, 0xfd,
+ 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0x0, 0xdf,
+ 0xf0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xc0, 0x9,
+ 0xff, 0x50, 0x0, 0x0, 0x0, 0x5f, 0xf8, 0x0,
+ 0x4f, 0xfd, 0x0, 0x0, 0x0, 0xd, 0xff, 0x20,
+ 0x0, 0xcf, 0xfa, 0x0, 0x0, 0xa, 0xff, 0x90,
+ 0x0, 0x3, 0xff, 0xfe, 0x87, 0x8e, 0xff, 0xd0,
+ 0x0, 0x0, 0x4, 0xef, 0xff, 0xff, 0xff, 0xc1,
+ 0x0, 0x0, 0x0, 0x1, 0x7c, 0xef, 0xea, 0x50,
+ 0x0, 0x0,
+
+ /* U+0050 "P" */
+ 0x9f, 0xff, 0xff, 0xfe, 0xb6, 0x10, 0x0, 0x9f,
+ 0xff, 0xff, 0xff, 0xff, 0xe5, 0x0, 0x9f, 0xf6,
+ 0x55, 0x68, 0xdf, 0xff, 0x40, 0x9f, 0xf1, 0x0,
+ 0x0, 0x7, 0xff, 0xd0, 0x9f, 0xf1, 0x0, 0x0,
+ 0x0, 0xbf, 0xf3, 0x9f, 0xf1, 0x0, 0x0, 0x0,
+ 0x7f, 0xf5, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x7f,
+ 0xf5, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0xaf, 0xf2,
+ 0x9f, 0xf1, 0x0, 0x0, 0x4, 0xff, 0xc0, 0x9f,
+ 0xf1, 0x0, 0x3, 0x8f, 0xff, 0x30, 0x9f, 0xff,
+ 0xff, 0xff, 0xff, 0xf5, 0x0, 0x9f, 0xff, 0xff,
+ 0xff, 0xf9, 0x20, 0x0, 0x9f, 0xf6, 0x65, 0x43,
+ 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f,
+ 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf1,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+
+ /* U+0051 "Q" */
+ 0x0, 0x0, 0x4, 0xae, 0xfe, 0xc7, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xaf, 0xff, 0xff, 0xff, 0xe3,
+ 0x0, 0x0, 0x0, 0xb, 0xff, 0xfa, 0x89, 0xef,
+ 0xfe, 0x20, 0x0, 0x0, 0x6f, 0xfc, 0x10, 0x0,
+ 0xb, 0xff, 0xb0, 0x0, 0x0, 0xef, 0xf1, 0x0,
+ 0x0, 0x0, 0xdf, 0xf3, 0x0, 0x5, 0xff, 0x80,
+ 0x0, 0x0, 0x0, 0x6f, 0xf9, 0x0, 0xa, 0xff,
+ 0x20, 0x0, 0x0, 0x0, 0x1f, 0xfd, 0x0, 0xd,
+ 0xfe, 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, 0x0,
+ 0xf, 0xfc, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff,
+ 0x10, 0x1f, 0xfb, 0x0, 0x0, 0x0, 0x0, 0xa,
+ 0xff, 0x20, 0x1f, 0xfa, 0x0, 0x0, 0x0, 0x0,
+ 0x9, 0xff, 0x30, 0x1f, 0xfb, 0x0, 0x0, 0x0,
+ 0x0, 0xa, 0xff, 0x20, 0x1f, 0xfc, 0x0, 0x0,
+ 0x0, 0x0, 0xb, 0xff, 0x10, 0xf, 0xfe, 0x0,
+ 0x0, 0x0, 0x0, 0xd, 0xfe, 0x0, 0xc, 0xff,
+ 0x10, 0x0, 0x0, 0x0, 0x1f, 0xfb, 0x0, 0x8,
+ 0xff, 0x60, 0x0, 0x0, 0x0, 0x6f, 0xf6, 0x0,
+ 0x3, 0xff, 0xd0, 0x0, 0x0, 0x0, 0xef, 0xf1,
+ 0x0, 0x0, 0xcf, 0xfa, 0x0, 0x0, 0xb, 0xff,
+ 0x80, 0x0, 0x0, 0x2f, 0xff, 0xe8, 0x68, 0xef,
+ 0xfc, 0x0, 0x0, 0x0, 0x3, 0xef, 0xff, 0xff,
+ 0xff, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x18, 0xcf,
+ 0xff, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xd, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xa, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x4, 0xff, 0xe5, 0x11, 0x5d, 0x30,
+ 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, 0xff, 0xff,
+ 0xc0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, 0xff,
+ 0xfc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4,
+ 0x65, 0x20, 0x0,
+
+ /* U+0052 "R" */
+ 0x6f, 0xff, 0xff, 0xfe, 0xb5, 0x0, 0x0, 0x6f,
+ 0xff, 0xff, 0xff, 0xff, 0xc1, 0x0, 0x6f, 0xf8,
+ 0x55, 0x7a, 0xff, 0xfb, 0x0, 0x6f, 0xf4, 0x0,
+ 0x0, 0x2f, 0xff, 0x20, 0x6f, 0xf4, 0x0, 0x0,
+ 0x9, 0xff, 0x50, 0x6f, 0xf4, 0x0, 0x0, 0x7,
+ 0xff, 0x60, 0x6f, 0xf4, 0x0, 0x0, 0x9, 0xff,
+ 0x30, 0x6f, 0xf4, 0x0, 0x0, 0x3f, 0xfe, 0x0,
+ 0x6f, 0xf7, 0x34, 0x59, 0xff, 0xf4, 0x0, 0x6f,
+ 0xff, 0xff, 0xff, 0xfd, 0x40, 0x0, 0x6f, 0xff,
+ 0xff, 0xff, 0xa0, 0x0, 0x0, 0x6f, 0xf4, 0x2,
+ 0x9f, 0xfa, 0x0, 0x0, 0x6f, 0xf4, 0x0, 0xa,
+ 0xff, 0x40, 0x0, 0x6f, 0xf4, 0x0, 0x2, 0xff,
+ 0xd0, 0x0, 0x6f, 0xf4, 0x0, 0x0, 0xaf, 0xf5,
+ 0x0, 0x6f, 0xf4, 0x0, 0x0, 0x3f, 0xfc, 0x0,
+ 0x6f, 0xf4, 0x0, 0x0, 0xb, 0xff, 0x40, 0x6f,
+ 0xf4, 0x0, 0x0, 0x4, 0xff, 0xb0, 0x6f, 0xf4,
+ 0x0, 0x0, 0x0, 0xdf, 0xf3, 0x6f, 0xf4, 0x0,
+ 0x0, 0x0, 0x5f, 0xfa,
+
+ /* U+0053 "S" */
+ 0x0, 0x0, 0x5a, 0xdf, 0xfe, 0xda, 0x60, 0x0,
+ 0x3, 0xdf, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x2,
+ 0xff, 0xfd, 0x97, 0x78, 0x9c, 0xc0, 0x0, 0xaf,
+ 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xc0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, 0x30,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0x60,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, 0xe7,
+ 0x10, 0x0, 0x0, 0x0, 0x0, 0x5e, 0xff, 0xff,
+ 0xa3, 0x0, 0x0, 0x0, 0x0, 0x6, 0xcf, 0xff,
+ 0xf9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0xff,
+ 0xfd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x2, 0xcf,
+ 0xf9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xef,
+ 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xff,
+ 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xf0,
+ 0x11, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xfa, 0x5,
+ 0xfd, 0xa8, 0x77, 0x8a, 0xef, 0xff, 0x20, 0x5f,
+ 0xff, 0xff, 0xff, 0xff, 0xfd, 0x20, 0x1, 0x7a,
+ 0xde, 0xff, 0xfd, 0xa5, 0x0, 0x0,
+
+ /* U+0054 "T" */
+ 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcb,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x46,
+ 0x66, 0x66, 0xef, 0xe6, 0x66, 0x66, 0x40, 0x0,
+ 0x0, 0xd, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xdf, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xd, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xdf, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd,
+ 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf,
+ 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xfe,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xe0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xfe, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xe0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xd, 0xfe, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xdf, 0xe0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xd, 0xfe, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xdf, 0xe0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xd, 0xfe, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xdf, 0xe0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xd, 0xfe, 0x0, 0x0, 0x0,
+
+ /* U+0055 "U" */
+ 0x5f, 0xf5, 0x0, 0x0, 0x0, 0x4, 0xff, 0x65,
+ 0xff, 0x50, 0x0, 0x0, 0x0, 0x4f, 0xf6, 0x5f,
+ 0xf5, 0x0, 0x0, 0x0, 0x4, 0xff, 0x65, 0xff,
+ 0x50, 0x0, 0x0, 0x0, 0x4f, 0xf6, 0x5f, 0xf5,
+ 0x0, 0x0, 0x0, 0x4, 0xff, 0x65, 0xff, 0x50,
+ 0x0, 0x0, 0x0, 0x4f, 0xf6, 0x5f, 0xf5, 0x0,
+ 0x0, 0x0, 0x4, 0xff, 0x65, 0xff, 0x50, 0x0,
+ 0x0, 0x0, 0x4f, 0xf6, 0x5f, 0xf5, 0x0, 0x0,
+ 0x0, 0x4, 0xff, 0x65, 0xff, 0x50, 0x0, 0x0,
+ 0x0, 0x4f, 0xf6, 0x5f, 0xf5, 0x0, 0x0, 0x0,
+ 0x4, 0xff, 0x65, 0xff, 0x50, 0x0, 0x0, 0x0,
+ 0x4f, 0xf6, 0x5f, 0xf5, 0x0, 0x0, 0x0, 0x4,
+ 0xff, 0x65, 0xff, 0x50, 0x0, 0x0, 0x0, 0x5f,
+ 0xf5, 0x4f, 0xf7, 0x0, 0x0, 0x0, 0x7, 0xff,
+ 0x41, 0xff, 0xb0, 0x0, 0x0, 0x0, 0xcf, 0xf0,
+ 0xc, 0xff, 0x50, 0x0, 0x0, 0x6f, 0xf9, 0x0,
+ 0x4f, 0xff, 0xa6, 0x56, 0xbf, 0xfe, 0x10, 0x0,
+ 0x6f, 0xff, 0xff, 0xff, 0xfd, 0x20, 0x0, 0x0,
+ 0x28, 0xdf, 0xfe, 0xb6, 0x0, 0x0,
+
+ /* U+0056 "V" */
+ 0xcf, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff,
+ 0xd7, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, 0x5f,
+ 0xf7, 0x1f, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xb,
+ 0xff, 0x20, 0xcf, 0xf3, 0x0, 0x0, 0x0, 0x0,
+ 0xff, 0xc0, 0x7, 0xff, 0x80, 0x0, 0x0, 0x0,
+ 0x5f, 0xf7, 0x0, 0x2f, 0xfd, 0x0, 0x0, 0x0,
+ 0xa, 0xff, 0x20, 0x0, 0xcf, 0xf2, 0x0, 0x0,
+ 0x0, 0xef, 0xc0, 0x0, 0x7, 0xff, 0x70, 0x0,
+ 0x0, 0x4f, 0xf7, 0x0, 0x0, 0x2f, 0xfc, 0x0,
+ 0x0, 0x9, 0xff, 0x20, 0x0, 0x0, 0xdf, 0xf1,
+ 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x7, 0xff,
+ 0x60, 0x0, 0x3f, 0xf7, 0x0, 0x0, 0x0, 0x2f,
+ 0xfb, 0x0, 0x8, 0xff, 0x10, 0x0, 0x0, 0x0,
+ 0xdf, 0xf1, 0x0, 0xdf, 0xc0, 0x0, 0x0, 0x0,
+ 0x8, 0xff, 0x60, 0x2f, 0xf7, 0x0, 0x0, 0x0,
+ 0x0, 0x2f, 0xfb, 0x8, 0xff, 0x10, 0x0, 0x0,
+ 0x0, 0x0, 0xdf, 0xf0, 0xdf, 0xc0, 0x0, 0x0,
+ 0x0, 0x0, 0x8, 0xff, 0x6f, 0xf7, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x3f, 0xff, 0xff, 0x10, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xdf, 0xff, 0xc0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, 0xf6, 0x0,
+ 0x0, 0x0,
+
+ /* U+0057 "W" */
+ 0x4f, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff,
+ 0x53, 0xff, 0x40, 0x0, 0x0, 0x0, 0x0, 0x2f,
+ 0xf4, 0x2f, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x2,
+ 0xff, 0x31, 0xff, 0x60, 0x0, 0x0, 0x0, 0x0,
+ 0x3f, 0xf1, 0xf, 0xf7, 0x0, 0x0, 0x0, 0x0,
+ 0x4, 0xff, 0x0, 0xff, 0x80, 0x0, 0x0, 0x0,
+ 0x0, 0x5f, 0xf0, 0xd, 0xf9, 0x0, 0x1, 0x41,
+ 0x0, 0x6, 0xfe, 0x0, 0xcf, 0xa0, 0x0, 0xaf,
+ 0xb0, 0x0, 0x7f, 0xd0, 0xb, 0xfb, 0x0, 0xf,
+ 0xff, 0x10, 0x8, 0xfc, 0x0, 0xaf, 0xc0, 0x5,
+ 0xff, 0xf6, 0x0, 0x8f, 0xb0, 0x9, 0xfd, 0x0,
+ 0xaf, 0xff, 0xb0, 0x9, 0xfa, 0x0, 0x8f, 0xe0,
+ 0xf, 0xf7, 0xff, 0x10, 0xaf, 0x90, 0x7, 0xfe,
+ 0x4, 0xfd, 0xf, 0xf6, 0xb, 0xf8, 0x0, 0x6f,
+ 0xf0, 0x9f, 0x80, 0xbf, 0xc0, 0xcf, 0x70, 0x5,
+ 0xff, 0xe, 0xf3, 0x5, 0xff, 0x1d, 0xf6, 0x0,
+ 0x4f, 0xf5, 0xfe, 0x0, 0xf, 0xf7, 0xdf, 0x50,
+ 0x3, 0xff, 0xbf, 0x90, 0x0, 0xaf, 0xde, 0xf4,
+ 0x0, 0x2f, 0xff, 0xf3, 0x0, 0x5, 0xff, 0xff,
+ 0x30, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xf, 0xff,
+ 0xf2, 0x0, 0xf, 0xff, 0x90, 0x0, 0x0, 0xaf,
+ 0xff, 0x10,
+
+ /* U+0058 "X" */
+ 0xd, 0xff, 0x40, 0x0, 0x0, 0x0, 0x3f, 0xfd,
+ 0x0, 0x4f, 0xfd, 0x0, 0x0, 0x0, 0xd, 0xff,
+ 0x30, 0x0, 0xaf, 0xf7, 0x0, 0x0, 0x7, 0xff,
+ 0x90, 0x0, 0x1, 0xff, 0xf2, 0x0, 0x1, 0xff,
+ 0xe1, 0x0, 0x0, 0x6, 0xff, 0xb0, 0x0, 0xaf,
+ 0xf5, 0x0, 0x0, 0x0, 0xc, 0xff, 0x40, 0x4f,
+ 0xfb, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xfd, 0xd,
+ 0xff, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xfd,
+ 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef,
+ 0xff, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5,
+ 0xff, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x9f, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x4f, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, 0x0,
+ 0xd, 0xff, 0x5f, 0xfd, 0x0, 0x0, 0x0, 0x0,
+ 0x8, 0xff, 0x80, 0x9f, 0xf8, 0x0, 0x0, 0x0,
+ 0x3, 0xff, 0xe0, 0x1, 0xef, 0xf3, 0x0, 0x0,
+ 0x0, 0xdf, 0xf5, 0x0, 0x6, 0xff, 0xc0, 0x0,
+ 0x0, 0x7f, 0xfb, 0x0, 0x0, 0xc, 0xff, 0x70,
+ 0x0, 0x2f, 0xff, 0x20, 0x0, 0x0, 0x3f, 0xff,
+ 0x20, 0xc, 0xff, 0x80, 0x0, 0x0, 0x0, 0x9f,
+ 0xfb, 0x6, 0xff, 0xe0, 0x0, 0x0, 0x0, 0x1,
+ 0xef, 0xf5,
+
+ /* U+0059 "Y" */
+ 0xbf, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x5, 0xff,
+ 0xc0, 0x2f, 0xff, 0x10, 0x0, 0x0, 0x0, 0xd,
+ 0xff, 0x30, 0x9, 0xff, 0x90, 0x0, 0x0, 0x0,
+ 0x5f, 0xfa, 0x0, 0x1, 0xff, 0xf2, 0x0, 0x0,
+ 0x0, 0xdf, 0xf2, 0x0, 0x0, 0x7f, 0xfa, 0x0,
+ 0x0, 0x6, 0xff, 0x80, 0x0, 0x0, 0xe, 0xff,
+ 0x30, 0x0, 0xe, 0xfe, 0x0, 0x0, 0x0, 0x5,
+ 0xff, 0xb0, 0x0, 0x7f, 0xf6, 0x0, 0x0, 0x0,
+ 0x0, 0xcf, 0xf4, 0x0, 0xef, 0xd0, 0x0, 0x0,
+ 0x0, 0x0, 0x3f, 0xfc, 0x7, 0xff, 0x50, 0x0,
+ 0x0, 0x0, 0x0, 0xb, 0xff, 0x5e, 0xfc, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x2, 0xff, 0xff, 0xf3,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff,
+ 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f,
+ 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xd, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xd, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xd, 0xfe, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xd, 0xfe, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xd, 0xfe, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xfe, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xfe,
+ 0x0, 0x0, 0x0, 0x0,
+
+ /* U+005A "Z" */
+ 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x8,
+ 0x88, 0x88, 0x88, 0x88, 0xaf, 0xfe, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xc, 0xff, 0x40, 0x0, 0x0,
+ 0x0, 0x0, 0x7, 0xff, 0xa0, 0x0, 0x0, 0x0,
+ 0x0, 0x2, 0xff, 0xe1, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xcf, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x6f, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f,
+ 0xfe, 0x10, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff,
+ 0x40, 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0xa0,
+ 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xe1, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xbf, 0xf5, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x6f, 0xfa, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1f, 0xfe, 0x10, 0x0, 0x0, 0x0,
+ 0x0, 0xb, 0xff, 0x50, 0x0, 0x0, 0x0, 0x0,
+ 0x6, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x1,
+ 0xef, 0xfa, 0x99, 0x99, 0x99, 0x99, 0x93, 0x5f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x55, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5,
+
+ /* U+005B "[" */
+ 0xcf, 0xff, 0xff, 0xfb, 0xcf, 0xff, 0xff, 0xfb,
+ 0xcf, 0xc3, 0x33, 0x32, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xb0, 0x0, 0x0, 0xcf, 0xb0, 0x0, 0x0,
+ 0xcf, 0xc3, 0x33, 0x32, 0xcf, 0xff, 0xff, 0xfb,
+ 0xcf, 0xff, 0xff, 0xfb,
+
+ /* U+005C "\\" */
+ 0x6f, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe,
+ 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xfe,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xff, 0x50,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xc0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x5f, 0xf2, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xe, 0xf9, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x8, 0xff, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x2, 0xff, 0x60, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xbf, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x4f, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe,
+ 0xf9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff,
+ 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0x60,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xd0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf3, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xd, 0xfa, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x7, 0xff, 0x10, 0x0, 0x0, 0x0,
+ 0x0, 0x1, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xaf, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x3f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd,
+ 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xff,
+ 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x70,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xe0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x28, 0x81,
+
+ /* U+005D "]" */
+ 0xaf, 0xff, 0xff, 0xfd, 0xaf, 0xff, 0xff, 0xfd,
+ 0x13, 0x33, 0x3c, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x0, 0x0, 0xb, 0xfd, 0x0, 0x0, 0xb, 0xfd,
+ 0x13, 0x33, 0x3c, 0xfd, 0xaf, 0xff, 0xff, 0xfd,
+ 0xaf, 0xff, 0xff, 0xfd,
+
+ /* U+005E "^" */
+ 0x0, 0x0, 0x0, 0xdf, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x7f, 0xff, 0x60, 0x0, 0x0, 0x0,
+ 0x0, 0x1e, 0xfa, 0xfe, 0x0, 0x0, 0x0, 0x0,
+ 0x9, 0xfa, 0xe, 0xf8, 0x0, 0x0, 0x0, 0x2,
+ 0xff, 0x20, 0x5f, 0xf2, 0x0, 0x0, 0x0, 0xaf,
+ 0x90, 0x0, 0xcf, 0xb0, 0x0, 0x0, 0x3f, 0xf1,
+ 0x0, 0x3, 0xff, 0x40, 0x0, 0xc, 0xf8, 0x0,
+ 0x0, 0xa, 0xfd, 0x0, 0x5, 0xff, 0x10, 0x0,
+ 0x0, 0x2f, 0xf7, 0x0, 0xdf, 0x70, 0x0, 0x0,
+ 0x0, 0x8f, 0xf1,
+
+ /* U+005F "_" */
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xf0,
+
+ /* U+0060 "`" */
+ 0x48, 0x84, 0x7f, 0xf6, 0x6f, 0xf5, 0x5f, 0xf4,
+ 0x4f, 0xf3, 0x3f, 0xf2, 0x2f, 0xf1, 0x1f, 0xf0,
+
+ /* U+0061 "a" */
+ 0x1, 0x6a, 0xce, 0xff, 0xc8, 0x10, 0x0, 0xbf,
+ 0xff, 0xff, 0xff, 0xfe, 0x30, 0xb, 0xfb, 0x85,
+ 0x57, 0xdf, 0xfe, 0x0, 0x41, 0x0, 0x0, 0x0,
+ 0xcf, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff,
+ 0x70, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xf8, 0x0,
+ 0x0, 0x0, 0x1, 0x12, 0xff, 0x80, 0x3, 0xad,
+ 0xff, 0xff, 0xff, 0xf8, 0x9, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x86, 0xff, 0xd5, 0x10, 0x0, 0x1f,
+ 0xf8, 0xcf, 0xf2, 0x0, 0x0, 0x1, 0xff, 0x8f,
+ 0xfd, 0x0, 0x0, 0x0, 0x3f, 0xf8, 0xef, 0xf1,
+ 0x0, 0x0, 0x6f, 0xff, 0x8a, 0xff, 0xd6, 0x47,
+ 0xdf, 0xff, 0xf8, 0x2e, 0xff, 0xff, 0xff, 0xe3,
+ 0xdf, 0x80, 0x19, 0xdf, 0xfc, 0x70, 0xd, 0xf8,
+
+ /* U+0062 "b" */
+ 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f,
+ 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf1,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x9f, 0xf0, 0x5, 0xbe, 0xfc, 0x50,
+ 0x0, 0x9f, 0xf0, 0xbf, 0xff, 0xff, 0xf8, 0x0,
+ 0x9f, 0xfb, 0xff, 0x96, 0x9f, 0xff, 0x40, 0x9f,
+ 0xff, 0xd2, 0x0, 0x4, 0xff, 0xb0, 0x9f, 0xfe,
+ 0x10, 0x0, 0x0, 0xcf, 0xf0, 0x9f, 0xf3, 0x0,
+ 0x0, 0x0, 0x8f, 0xf3, 0x9f, 0xf1, 0x0, 0x0,
+ 0x0, 0x6f, 0xf5, 0x9f, 0xf1, 0x0, 0x0, 0x0,
+ 0x5f, 0xf6, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x5f,
+ 0xf5, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x6f, 0xf4,
+ 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x9f,
+ 0xf1, 0x0, 0x0, 0x1, 0xff, 0xb0, 0x9f, 0xf1,
+ 0x0, 0x0, 0xa, 0xff, 0x40, 0x9f, 0xfb, 0x64,
+ 0x36, 0xcf, 0xf9, 0x0, 0x8f, 0xff, 0xff, 0xff,
+ 0xff, 0x90, 0x0, 0x4, 0x9c, 0xef, 0xfd, 0x93,
+ 0x0, 0x0,
+
+ /* U+0063 "c" */
+ 0x0, 0x0, 0x29, 0xdf, 0xfe, 0xc7, 0x10, 0x0,
+ 0x9f, 0xff, 0xff, 0xff, 0xf3, 0x0, 0xaf, 0xff,
+ 0x95, 0x57, 0xaf, 0x30, 0x6f, 0xfd, 0x20, 0x0,
+ 0x0, 0x0, 0xe, 0xff, 0x20, 0x0, 0x0, 0x0,
+ 0x3, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, 0x7f,
+ 0xf5, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x20,
+ 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf2, 0x0, 0x0,
+ 0x0, 0x0, 0x8, 0xff, 0x40, 0x0, 0x0, 0x0,
+ 0x0, 0x5f, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x1,
+ 0xff, 0xe0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff,
+ 0xb0, 0x0, 0x0, 0x1, 0x10, 0x1e, 0xff, 0xe9,
+ 0x65, 0x7a, 0xf3, 0x0, 0x2d, 0xff, 0xff, 0xff,
+ 0xff, 0x30, 0x0, 0x6, 0xbe, 0xff, 0xdb, 0x60,
+
+ /* U+0064 "d" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf8, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf8, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1f, 0xf8, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1f, 0xf8, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x1f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x1f, 0xf8, 0x0, 0x0, 0x29, 0xdf, 0xfe, 0xbf,
+ 0xf8, 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, 0xf8,
+ 0x0, 0x9f, 0xfd, 0x74, 0x57, 0xcf, 0xf8, 0x3,
+ 0xff, 0xb0, 0x0, 0x0, 0x1f, 0xf8, 0xb, 0xff,
+ 0x10, 0x0, 0x0, 0x1f, 0xf8, 0xf, 0xfa, 0x0,
+ 0x0, 0x0, 0x1f, 0xf8, 0x3f, 0xf7, 0x0, 0x0,
+ 0x0, 0x1f, 0xf8, 0x4f, 0xf5, 0x0, 0x0, 0x0,
+ 0x1f, 0xf8, 0x5f, 0xf5, 0x0, 0x0, 0x0, 0x1f,
+ 0xf8, 0x4f, 0xf6, 0x0, 0x0, 0x0, 0x1f, 0xf8,
+ 0x2f, 0xf8, 0x0, 0x0, 0x0, 0x7f, 0xf8, 0xf,
+ 0xfd, 0x0, 0x0, 0x3, 0xff, 0xf8, 0xa, 0xff,
+ 0x50, 0x0, 0x3f, 0xff, 0xf8, 0x3, 0xff, 0xf8,
+ 0x59, 0xff, 0x8e, 0xf8, 0x0, 0x8f, 0xff, 0xff,
+ 0xf8, 0xd, 0xf8, 0x0, 0x5, 0xcf, 0xeb, 0x40,
+ 0xd, 0xf8,
+
+ /* U+0065 "e" */
+ 0x0, 0x0, 0x39, 0xdf, 0xec, 0x70, 0x0, 0x0,
+ 0x0, 0x7f, 0xff, 0xff, 0xff, 0xd2, 0x0, 0x0,
+ 0x7f, 0xfc, 0x53, 0x4a, 0xff, 0xd0, 0x0, 0x2f,
+ 0xfc, 0x0, 0x0, 0x7, 0xff, 0x70, 0x9, 0xff,
+ 0x30, 0x0, 0x0, 0xd, 0xfd, 0x0, 0xef, 0xd0,
+ 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x1f, 0xfa, 0x11,
+ 0x11, 0x11, 0x18, 0xff, 0x33, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xf4, 0x3f, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0x32, 0xff, 0x90, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xf, 0xfb, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xbf, 0xf1, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x5, 0xff, 0xc1, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xb, 0xff, 0xe9, 0x54, 0x46, 0x8a,
+ 0x50, 0x0, 0xb, 0xff, 0xff, 0xff, 0xff, 0xf7,
+ 0x0, 0x0, 0x4, 0xad, 0xff, 0xed, 0xb8, 0x20,
+
+ /* U+0066 "f" */
+ 0x0, 0x0, 0x0, 0x0, 0x18, 0xcf, 0xff, 0xda,
+ 0x0, 0x0, 0x0, 0x4, 0xff, 0xff, 0xff, 0xfe,
+ 0x0, 0x0, 0x0, 0x1f, 0xff, 0xb6, 0x45, 0x79,
+ 0x0, 0x0, 0x0, 0x7f, 0xf8, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xbf, 0xf0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xdf, 0xd0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x3, 0x44, 0x44, 0xef, 0xd4, 0x44, 0x44, 0x41,
+ 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
+ 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xc0, 0x0, 0x0, 0x0,
+
+ /* U+0067 "g" */
+ 0x0, 0x1, 0x7c, 0xff, 0xff, 0xff, 0xff, 0xc0,
+ 0x2, 0xef, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0,
+ 0xef, 0xf8, 0x31, 0x4c, 0xff, 0xa3, 0x20, 0x6f,
+ 0xf8, 0x0, 0x0, 0xd, 0xff, 0x0, 0x9, 0xff,
+ 0x20, 0x0, 0x0, 0x8f, 0xf3, 0x0, 0x9f, 0xf1,
+ 0x0, 0x0, 0x7, 0xff, 0x30, 0x6, 0xff, 0x70,
+ 0x0, 0x0, 0xdf, 0xf0, 0x0, 0xd, 0xff, 0x71,
+ 0x3, 0xbf, 0xf8, 0x0, 0x0, 0xaf, 0xff, 0xff,
+ 0xff, 0xfa, 0x0, 0x0, 0x4f, 0xf8, 0xdf, 0xff,
+ 0xb5, 0x0, 0x0, 0xb, 0xfb, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0x90, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xf, 0xfb, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xbf, 0xfa, 0x66, 0x66, 0x64, 0x20,
+ 0x0, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd4,
+ 0x0, 0x1d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3,
+ 0xd, 0xfe, 0x40, 0x0, 0x0, 0x2a, 0xff, 0xa6,
+ 0xff, 0x50, 0x0, 0x0, 0x0, 0x2f, 0xfb, 0x8f,
+ 0xf5, 0x0, 0x0, 0x0, 0x7, 0xff, 0x85, 0xff,
+ 0xf8, 0x53, 0x23, 0x5a, 0xff, 0xe1, 0x9, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xd2, 0x0, 0x3, 0x8c,
+ 0xef, 0xff, 0xda, 0x50, 0x0,
+
+ /* U+0068 "h" */
+ 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x9, 0xff,
+ 0x10, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x0,
+ 0x0, 0x0, 0x0, 0x9, 0xff, 0x10, 0x0, 0x0,
+ 0x0, 0x0, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x0,
+ 0x9, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, 0x9f,
+ 0xf0, 0x6, 0xcf, 0xfc, 0x40, 0x9, 0xff, 0x1c,
+ 0xff, 0xff, 0xff, 0x60, 0x9f, 0xfc, 0xff, 0x86,
+ 0xaf, 0xff, 0x19, 0xff, 0xfd, 0x10, 0x0, 0x9f,
+ 0xf6, 0x9f, 0xfd, 0x10, 0x0, 0x2, 0xff, 0x89,
+ 0xff, 0x30, 0x0, 0x0, 0xf, 0xf9, 0x9f, 0xf1,
+ 0x0, 0x0, 0x0, 0xff, 0xa9, 0xff, 0x10, 0x0,
+ 0x0, 0xf, 0xfa, 0x9f, 0xf1, 0x0, 0x0, 0x0,
+ 0xff, 0xa9, 0xff, 0x10, 0x0, 0x0, 0xf, 0xfa,
+ 0x9f, 0xf1, 0x0, 0x0, 0x0, 0xff, 0xa9, 0xff,
+ 0x10, 0x0, 0x0, 0xf, 0xfa, 0x9f, 0xf1, 0x0,
+ 0x0, 0x0, 0xff, 0xa9, 0xff, 0x10, 0x0, 0x0,
+ 0xf, 0xfa, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0xff,
+ 0xa9, 0xff, 0x10, 0x0, 0x0, 0xf, 0xfa,
+
+ /* U+0069 "i" */
+ 0x0, 0x0, 0xa, 0xfb, 0x0, 0x0, 0x0, 0x0,
+ 0x6, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x7f,
+ 0xff, 0x80, 0x0, 0x0, 0x0, 0x1, 0xef, 0xe2,
+ 0x0, 0x0, 0x0, 0x0, 0x1, 0x31, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe,
+ 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0xef, 0xff,
+ 0xff, 0xf4, 0x0, 0x0, 0x3, 0x44, 0x48, 0xff,
+ 0x40, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xf4, 0x0,
+ 0x0, 0x0, 0x0, 0x6, 0xff, 0x40, 0x0, 0x0,
+ 0x0, 0x0, 0x6f, 0xf4, 0x0, 0x0, 0x0, 0x0,
+ 0x6, 0xff, 0x40, 0x0, 0x0, 0x0, 0x0, 0x6f,
+ 0xf4, 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0x40,
+ 0x0, 0x0, 0x0, 0x0, 0x6f, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x6, 0xff, 0x40, 0x0, 0x0, 0x0,
+ 0x0, 0x6f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x6,
+ 0xff, 0x40, 0x0, 0x1, 0x44, 0x44, 0x9f, 0xf7,
+ 0x44, 0x43, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+
+ /* U+006A "j" */
+ 0x0, 0x0, 0x0, 0x0, 0x3d, 0xe6, 0x0, 0x0,
+ 0x0, 0x0, 0xc, 0xff, 0xf1, 0x0, 0x0, 0x0,
+ 0x0, 0xef, 0xff, 0x20, 0x0, 0x0, 0x0, 0x6,
+ 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x30,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6,
+ 0xff, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x6f, 0xff,
+ 0xff, 0xff, 0xff, 0xb0, 0x1, 0x44, 0x44, 0x44,
+ 0x4f, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff,
+ 0xb0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfb, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xff, 0xb0, 0x0, 0x0,
+ 0x0, 0x0, 0xf, 0xfb, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xf,
+ 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xb0,
+ 0x0, 0x0, 0x0, 0x0, 0xf, 0xfb, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xff, 0xb0, 0x0, 0x0, 0x0,
+ 0x0, 0xf, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfb,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xb0, 0x0,
+ 0x0, 0x0, 0x0, 0xf, 0xf9, 0x0, 0x0, 0x0,
+ 0x0, 0x5, 0xff, 0x60, 0x2, 0x0, 0x0, 0x1,
+ 0xdf, 0xf1, 0x0, 0xfc, 0x85, 0x57, 0xef, 0xf8,
+ 0x0, 0xf, 0xff, 0xff, 0xff, 0xf9, 0x0, 0x0,
+ 0x5a, 0xdf, 0xfe, 0xa4, 0x0, 0x0,
+
+ /* U+006B "k" */
+ 0x4f, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4,
+ 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f,
+ 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff,
+ 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf6,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0x60,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf6, 0x0,
+ 0x0, 0x4, 0xff, 0xf4, 0x4, 0xff, 0x60, 0x0,
+ 0x3, 0xff, 0xf4, 0x0, 0x4f, 0xf6, 0x0, 0x2,
+ 0xef, 0xf4, 0x0, 0x4, 0xff, 0x60, 0x2, 0xef,
+ 0xf5, 0x0, 0x0, 0x4f, 0xf6, 0x1, 0xef, 0xf5,
+ 0x0, 0x0, 0x4, 0xff, 0x61, 0xdf, 0xf6, 0x0,
+ 0x0, 0x0, 0x4f, 0xf7, 0xcf, 0xf6, 0x0, 0x0,
+ 0x0, 0x4, 0xff, 0xdf, 0xfc, 0x0, 0x0, 0x0,
+ 0x0, 0x4f, 0xf6, 0xbf, 0xf8, 0x0, 0x0, 0x0,
+ 0x4, 0xff, 0x60, 0xdf, 0xf6, 0x0, 0x0, 0x0,
+ 0x4f, 0xf6, 0x2, 0xef, 0xf4, 0x0, 0x0, 0x4,
+ 0xff, 0x60, 0x4, 0xff, 0xf3, 0x0, 0x0, 0x4f,
+ 0xf6, 0x0, 0x6, 0xff, 0xe2, 0x0, 0x4, 0xff,
+ 0x60, 0x0, 0x9, 0xff, 0xd1, 0x0, 0x4f, 0xf6,
+ 0x0, 0x0, 0xc, 0xff, 0xc0, 0x4, 0xff, 0x60,
+ 0x0, 0x0, 0x1d, 0xff, 0xa0,
+
+ /* U+006C "l" */
+ 0xe, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0xef,
+ 0xff, 0xff, 0xf4, 0x0, 0x0, 0x3, 0x33, 0x38,
+ 0xff, 0x40, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xf4,
+ 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0x40, 0x0,
+ 0x0, 0x0, 0x0, 0x6f, 0xf4, 0x0, 0x0, 0x0,
+ 0x0, 0x6, 0xff, 0x40, 0x0, 0x0, 0x0, 0x0,
+ 0x6f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x6, 0xff,
+ 0x40, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xf4, 0x0,
+ 0x0, 0x0, 0x0, 0x6, 0xff, 0x40, 0x0, 0x0,
+ 0x0, 0x0, 0x6f, 0xf4, 0x0, 0x0, 0x0, 0x0,
+ 0x6, 0xff, 0x40, 0x0, 0x0, 0x0, 0x0, 0x6f,
+ 0xf4, 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0x40,
+ 0x0, 0x0, 0x0, 0x0, 0x6f, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x6, 0xff, 0x40, 0x0, 0x0, 0x0,
+ 0x0, 0x6f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x6,
+ 0xff, 0x40, 0x0, 0x1, 0x44, 0x44, 0x9f, 0xf7,
+ 0x44, 0x43, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+
+ /* U+006D "m" */
+ 0xaf, 0x60, 0x9e, 0xe5, 0x0, 0x9e, 0xe5, 0xa,
+ 0xf6, 0x8f, 0xff, 0xf1, 0x9f, 0xff, 0xf2, 0xaf,
+ 0x9f, 0xb5, 0xff, 0x7f, 0xb6, 0xff, 0x7a, 0xff,
+ 0xe1, 0xc, 0xff, 0xe0, 0xd, 0xfa, 0xaf, 0xf7,
+ 0x0, 0xbf, 0xf6, 0x0, 0xbf, 0xaa, 0xfe, 0x0,
+ 0xb, 0xfe, 0x0, 0xb, 0xfb, 0xaf, 0xc0, 0x0,
+ 0xbf, 0xb0, 0x0, 0xbf, 0xba, 0xfc, 0x0, 0xb,
+ 0xfb, 0x0, 0xb, 0xfb, 0xaf, 0xc0, 0x0, 0xbf,
+ 0xb0, 0x0, 0xbf, 0xba, 0xfc, 0x0, 0xb, 0xfb,
+ 0x0, 0xb, 0xfb, 0xaf, 0xc0, 0x0, 0xbf, 0xb0,
+ 0x0, 0xbf, 0xba, 0xfc, 0x0, 0xb, 0xfb, 0x0,
+ 0xb, 0xfb, 0xaf, 0xc0, 0x0, 0xbf, 0xb0, 0x0,
+ 0xbf, 0xba, 0xfc, 0x0, 0xb, 0xfb, 0x0, 0xb,
+ 0xfb, 0xaf, 0xc0, 0x0, 0xbf, 0xb0, 0x0, 0xbf,
+ 0xba, 0xfc, 0x0, 0xb, 0xfb, 0x0, 0xb, 0xfb,
+
+ /* U+006E "n" */
+ 0x9f, 0xc0, 0x6, 0xcf, 0xfc, 0x50, 0x9, 0xfd,
+ 0x1c, 0xff, 0xff, 0xff, 0x60, 0x9f, 0xec, 0xfe,
+ 0x86, 0xaf, 0xff, 0x19, 0xff, 0xfc, 0x10, 0x0,
+ 0x9f, 0xf6, 0x9f, 0xfd, 0x10, 0x0, 0x2, 0xff,
+ 0x89, 0xff, 0x30, 0x0, 0x0, 0xf, 0xf9, 0x9f,
+ 0xf1, 0x0, 0x0, 0x0, 0xff, 0xa9, 0xff, 0x10,
+ 0x0, 0x0, 0xf, 0xfa, 0x9f, 0xf1, 0x0, 0x0,
+ 0x0, 0xff, 0xa9, 0xff, 0x10, 0x0, 0x0, 0xf,
+ 0xfa, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0xff, 0xa9,
+ 0xff, 0x10, 0x0, 0x0, 0xf, 0xfa, 0x9f, 0xf1,
+ 0x0, 0x0, 0x0, 0xff, 0xa9, 0xff, 0x10, 0x0,
+ 0x0, 0xf, 0xfa, 0x9f, 0xf1, 0x0, 0x0, 0x0,
+ 0xff, 0xa9, 0xff, 0x10, 0x0, 0x0, 0xf, 0xfa,
+
+ /* U+006F "o" */
+ 0x0, 0x0, 0x5a, 0xef, 0xec, 0x71, 0x0, 0x0,
+ 0x1, 0xbf, 0xff, 0xff, 0xff, 0xe4, 0x0, 0x0,
+ 0xcf, 0xfc, 0x75, 0x6c, 0xff, 0xf2, 0x0, 0x8f,
+ 0xf9, 0x0, 0x0, 0x8, 0xff, 0xb0, 0xe, 0xfd,
+ 0x0, 0x0, 0x0, 0xc, 0xff, 0x24, 0xff, 0x70,
+ 0x0, 0x0, 0x0, 0x6f, 0xf6, 0x7f, 0xf4, 0x0,
+ 0x0, 0x0, 0x2, 0xff, 0x89, 0xff, 0x20, 0x0,
+ 0x0, 0x0, 0x1f, 0xfa, 0x9f, 0xf1, 0x0, 0x0,
+ 0x0, 0x1, 0xff, 0x98, 0xff, 0x30, 0x0, 0x0,
+ 0x0, 0x3f, 0xf8, 0x5f, 0xf6, 0x0, 0x0, 0x0,
+ 0x6, 0xff, 0x51, 0xff, 0xc0, 0x0, 0x0, 0x0,
+ 0xcf, 0xf0, 0xb, 0xff, 0x80, 0x0, 0x0, 0x8f,
+ 0xf8, 0x0, 0x2f, 0xff, 0xc6, 0x56, 0xcf, 0xfd,
+ 0x0, 0x0, 0x3e, 0xff, 0xff, 0xff, 0xfc, 0x10,
+ 0x0, 0x0, 0x7, 0xce, 0xfe, 0xb5, 0x0, 0x0,
+
+ /* U+0070 "p" */
+ 0x9f, 0xc0, 0x6, 0xce, 0xfc, 0x50, 0x0, 0x9f,
+ 0xd0, 0xbf, 0xff, 0xff, 0xf8, 0x0, 0x9f, 0xeb,
+ 0xff, 0x96, 0x9f, 0xff, 0x40, 0x9f, 0xff, 0xd2,
+ 0x0, 0x4, 0xff, 0xb0, 0x9f, 0xfe, 0x10, 0x0,
+ 0x0, 0xcf, 0xf0, 0x9f, 0xf3, 0x0, 0x0, 0x0,
+ 0x8f, 0xf3, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x6f,
+ 0xf5, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x5f, 0xf6,
+ 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x5f, 0xf5, 0x9f,
+ 0xf1, 0x0, 0x0, 0x0, 0x6f, 0xf4, 0x9f, 0xf1,
+ 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x9f, 0xf1, 0x0,
+ 0x0, 0x1, 0xff, 0xc0, 0x9f, 0xf1, 0x0, 0x0,
+ 0xa, 0xff, 0x40, 0x9f, 0xfb, 0x64, 0x36, 0xdf,
+ 0xfa, 0x0, 0x9f, 0xff, 0xff, 0xff, 0xff, 0x90,
+ 0x0, 0x9f, 0xfc, 0xef, 0xfd, 0x93, 0x0, 0x0,
+ 0x9f, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f,
+ 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf1,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x9f, 0xf1, 0x0, 0x0, 0x0,
+ 0x0, 0x0,
+
+ /* U+0071 "q" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x39, 0xdf, 0xfd, 0xa9, 0xd8, 0x0, 0x8,
+ 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, 0x9f, 0xfd,
+ 0x64, 0x46, 0xcf, 0xf8, 0x3, 0xff, 0xb0, 0x0,
+ 0x0, 0x1f, 0xf8, 0xb, 0xff, 0x10, 0x0, 0x0,
+ 0x1f, 0xf8, 0xf, 0xfa, 0x0, 0x0, 0x0, 0x1f,
+ 0xf8, 0x3f, 0xf7, 0x0, 0x0, 0x0, 0x1f, 0xf8,
+ 0x4f, 0xf5, 0x0, 0x0, 0x0, 0x1f, 0xf8, 0x5f,
+ 0xf6, 0x0, 0x0, 0x0, 0x1f, 0xf8, 0x4f, 0xf7,
+ 0x0, 0x0, 0x0, 0x1f, 0xf8, 0x2f, 0xf9, 0x0,
+ 0x0, 0x0, 0x7f, 0xf8, 0xf, 0xfd, 0x0, 0x0,
+ 0x3, 0xff, 0xf8, 0xb, 0xff, 0x50, 0x0, 0x3f,
+ 0xff, 0xf8, 0x3, 0xff, 0xf8, 0x59, 0xff, 0x8f,
+ 0xf8, 0x0, 0x8f, 0xff, 0xff, 0xf8, 0xf, 0xf8,
+ 0x0, 0x5, 0xcf, 0xeb, 0x40, 0x1f, 0xf8, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf8, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1f, 0xf8, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1f, 0xf8, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x1f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x1f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f,
+ 0xf8,
+
+ /* U+0072 "r" */
+ 0xff, 0x70, 0x6, 0xcf, 0xeb, 0x30, 0xf, 0xf7,
+ 0x1b, 0xff, 0xff, 0xff, 0x40, 0xff, 0x9c, 0xff,
+ 0x86, 0xaf, 0xfe, 0xf, 0xff, 0xfc, 0x10, 0x0,
+ 0xaf, 0xf4, 0xff, 0xfd, 0x0, 0x0, 0x4, 0xff,
+ 0x7f, 0xfe, 0x10, 0x0, 0x0, 0x2f, 0xf8, 0xff,
+ 0xb0, 0x0, 0x0, 0x0, 0x44, 0x2f, 0xfb, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xff, 0xb0, 0x0, 0x0,
+ 0x0, 0x0, 0xf, 0xfb, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xf,
+ 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xb0,
+ 0x0, 0x0, 0x0, 0x0, 0xf, 0xfb, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xff, 0xb0, 0x0, 0x0, 0x0,
+ 0x0, 0xf, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ /* U+0073 "s" */
+ 0x0, 0x4, 0xad, 0xff, 0xed, 0xb4, 0x0, 0xa,
+ 0xff, 0xff, 0xff, 0xff, 0x70, 0x7, 0xff, 0xd7,
+ 0x44, 0x57, 0xa5, 0x0, 0xef, 0xd0, 0x0, 0x0,
+ 0x0, 0x0, 0xf, 0xfb, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xef, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x6,
+ 0xff, 0xfc, 0x61, 0x0, 0x0, 0x0, 0x7, 0xff,
+ 0xff, 0xfb, 0x50, 0x0, 0x0, 0x1, 0x8d, 0xff,
+ 0xff, 0xd2, 0x0, 0x0, 0x0, 0x3, 0x8e, 0xff,
+ 0xe0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0x40,
+ 0x0, 0x0, 0x0, 0x0, 0x5f, 0xf6, 0x0, 0x0,
+ 0x0, 0x0, 0x9, 0xff, 0x44, 0xea, 0x76, 0x55,
+ 0x6b, 0xff, 0xd0, 0x4f, 0xff, 0xff, 0xff, 0xff,
+ 0xd2, 0x1, 0x8b, 0xde, 0xff, 0xea, 0x50, 0x0,
+
+ /* U+0074 "t" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x5a, 0xc0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xc, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xcf, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xcf, 0xd0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xa0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xfa, 0x4, 0x44, 0x4d, 0xfe,
+ 0x44, 0x44, 0x44, 0x30, 0x0, 0x0, 0xcf, 0xd0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xfd, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xd0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xc, 0xfd, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xcf, 0xd0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xc, 0xfd, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xcf, 0xd0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xc, 0xfe, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xbf, 0xf0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x8, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x3f, 0xff, 0xa6, 0x56, 0x87, 0x0, 0x0,
+ 0x0, 0x7f, 0xff, 0xff, 0xff, 0xa0, 0x0, 0x0,
+ 0x0, 0x4a, 0xef, 0xfe, 0xc6,
+
+ /* U+0075 "u" */
+ 0x9f, 0xf1, 0x0, 0x0, 0x0, 0xff, 0xa9, 0xff,
+ 0x10, 0x0, 0x0, 0xf, 0xfa, 0x9f, 0xf1, 0x0,
+ 0x0, 0x0, 0xff, 0xa9, 0xff, 0x10, 0x0, 0x0,
+ 0xf, 0xfa, 0x9f, 0xf1, 0x0, 0x0, 0x0, 0xff,
+ 0xa9, 0xff, 0x10, 0x0, 0x0, 0xf, 0xfa, 0x9f,
+ 0xf1, 0x0, 0x0, 0x0, 0xff, 0xa9, 0xff, 0x10,
+ 0x0, 0x0, 0xf, 0xfa, 0x9f, 0xf1, 0x0, 0x0,
+ 0x0, 0xff, 0xa9, 0xff, 0x10, 0x0, 0x0, 0xf,
+ 0xfa, 0x9f, 0xf1, 0x0, 0x0, 0x1, 0xff, 0xa8,
+ 0xff, 0x30, 0x0, 0x0, 0xcf, 0xfa, 0x5f, 0xf9,
+ 0x0, 0x1, 0xcf, 0xff, 0xa0, 0xff, 0xfa, 0x67,
+ 0xef, 0xdd, 0xfa, 0x6, 0xff, 0xff, 0xff, 0xc1,
+ 0xcf, 0xa0, 0x4, 0xcf, 0xfd, 0x70, 0xb, 0xfa,
+
+ /* U+0076 "v" */
+ 0xdf, 0xf2, 0x0, 0x0, 0x0, 0x2, 0xff, 0xb7,
+ 0xff, 0x80, 0x0, 0x0, 0x0, 0x7f, 0xf6, 0x1f,
+ 0xfd, 0x0, 0x0, 0x0, 0xd, 0xff, 0x0, 0xbf,
+ 0xf3, 0x0, 0x0, 0x2, 0xff, 0xa0, 0x5, 0xff,
+ 0x90, 0x0, 0x0, 0x8f, 0xf4, 0x0, 0xe, 0xfe,
+ 0x0, 0x0, 0xe, 0xfe, 0x0, 0x0, 0x9f, 0xf4,
+ 0x0, 0x3, 0xff, 0x80, 0x0, 0x3, 0xff, 0xa0,
+ 0x0, 0x9f, 0xf2, 0x0, 0x0, 0xd, 0xff, 0x0,
+ 0xe, 0xfc, 0x0, 0x0, 0x0, 0x7f, 0xf5, 0x4,
+ 0xff, 0x60, 0x0, 0x0, 0x1, 0xff, 0xb0, 0xaf,
+ 0xf0, 0x0, 0x0, 0x0, 0xb, 0xff, 0x1e, 0xfa,
+ 0x0, 0x0, 0x0, 0x0, 0x5f, 0xf9, 0xff, 0x40,
+ 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xe0, 0x0,
+ 0x0, 0x0, 0x0, 0x9, 0xff, 0xf8, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x3f, 0xff, 0x20, 0x0, 0x0,
+
+ /* U+0077 "w" */
+ 0x5f, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x2, 0xff,
+ 0x63, 0xff, 0x50, 0x0, 0x0, 0x0, 0x0, 0x4f,
+ 0xf4, 0x1f, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x6,
+ 0xff, 0x20, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0,
+ 0x7f, 0xf0, 0xd, 0xfa, 0x0, 0xa, 0xf9, 0x0,
+ 0x9, 0xfe, 0x0, 0xbf, 0xc0, 0x0, 0xef, 0xe0,
+ 0x0, 0xbf, 0xb0, 0x8, 0xfe, 0x0, 0x3f, 0xff,
+ 0x40, 0xc, 0xf9, 0x0, 0x6f, 0xf0, 0x8, 0xff,
+ 0xf9, 0x0, 0xef, 0x70, 0x4, 0xff, 0x20, 0xdf,
+ 0x8f, 0xe0, 0xf, 0xf5, 0x0, 0x2f, 0xf3, 0x2f,
+ 0xe1, 0xff, 0x42, 0xff, 0x30, 0x0, 0xff, 0x57,
+ 0xf9, 0xb, 0xf9, 0x3f, 0xf0, 0x0, 0xd, 0xf7,
+ 0xcf, 0x40, 0x6f, 0xe5, 0xfe, 0x0, 0x0, 0xbf,
+ 0xaf, 0xf0, 0x1, 0xff, 0xbf, 0xc0, 0x0, 0x9,
+ 0xff, 0xfa, 0x0, 0xb, 0xff, 0xfa, 0x0, 0x0,
+ 0x7f, 0xff, 0x50, 0x0, 0x6f, 0xff, 0x80, 0x0,
+ 0x5, 0xff, 0xf0, 0x0, 0x1, 0xff, 0xf5, 0x0,
+
+ /* U+0078 "x" */
+ 0x5f, 0xfe, 0x10, 0x0, 0x0, 0xb, 0xff, 0x80,
+ 0x9, 0xff, 0xa0, 0x0, 0x0, 0x5f, 0xfc, 0x0,
+ 0x0, 0xdf, 0xf5, 0x0, 0x1, 0xef, 0xf2, 0x0,
+ 0x0, 0x3f, 0xfe, 0x10, 0x9, 0xff, 0x60, 0x0,
+ 0x0, 0x7, 0xff, 0xa0, 0x3f, 0xfa, 0x0, 0x0,
+ 0x0, 0x0, 0xcf, 0xf4, 0xdf, 0xe1, 0x0, 0x0,
+ 0x0, 0x0, 0x2f, 0xff, 0xff, 0x40, 0x0, 0x0,
+ 0x0, 0x0, 0x6, 0xff, 0xf8, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x7, 0xff, 0xf8, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x3f, 0xff, 0xff, 0x40, 0x0, 0x0,
+ 0x0, 0x0, 0xdf, 0xf4, 0xff, 0xe1, 0x0, 0x0,
+ 0x0, 0xa, 0xff, 0x70, 0x6f, 0xfb, 0x0, 0x0,
+ 0x0, 0x5f, 0xfc, 0x0, 0xb, 0xff, 0x80, 0x0,
+ 0x2, 0xff, 0xf2, 0x0, 0x1, 0xff, 0xf4, 0x0,
+ 0xc, 0xff, 0x70, 0x0, 0x0, 0x6f, 0xfe, 0x10,
+ 0x9f, 0xfc, 0x0, 0x0, 0x0, 0xb, 0xff, 0xb0,
+
+ /* U+0079 "y" */
+ 0xc, 0xff, 0x20, 0x0, 0x0, 0x0, 0x2f, 0xfb,
+ 0x6, 0xff, 0x80, 0x0, 0x0, 0x0, 0x7f, 0xf6,
+ 0x1, 0xff, 0xe0, 0x0, 0x0, 0x0, 0xdf, 0xf0,
+ 0x0, 0xaf, 0xf4, 0x0, 0x0, 0x2, 0xff, 0xa0,
+ 0x0, 0x3f, 0xfa, 0x0, 0x0, 0x8, 0xff, 0x40,
+ 0x0, 0xd, 0xff, 0x10, 0x0, 0xd, 0xfe, 0x0,
+ 0x0, 0x7, 0xff, 0x60, 0x0, 0x3f, 0xf8, 0x0,
+ 0x0, 0x1, 0xff, 0xc0, 0x0, 0x9f, 0xf2, 0x0,
+ 0x0, 0x0, 0xbf, 0xf2, 0x0, 0xef, 0xc0, 0x0,
+ 0x0, 0x0, 0x4f, 0xf8, 0x4, 0xff, 0x60, 0x0,
+ 0x0, 0x0, 0xe, 0xfe, 0x9, 0xff, 0x10, 0x0,
+ 0x0, 0x0, 0x8, 0xff, 0x4f, 0xfa, 0x0, 0x0,
+ 0x0, 0x0, 0x2, 0xff, 0xdf, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xbf, 0xff, 0xe0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x5f, 0xff, 0x80, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xf, 0xff, 0x10, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x6f, 0xfa, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1, 0xef, 0xf2, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1c, 0xff, 0x70, 0x0, 0x0, 0x0,
+ 0x7, 0x69, 0xff, 0xfb, 0x0, 0x0, 0x0, 0x0,
+ 0x1f, 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0,
+ 0x1f, 0xfe, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ /* U+007A "z" */
+ 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x35, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xf3, 0x14, 0x44, 0x44,
+ 0x44, 0x6f, 0xfe, 0x10, 0x0, 0x0, 0x0, 0xc,
+ 0xff, 0x30, 0x0, 0x0, 0x0, 0x8, 0xff, 0x80,
+ 0x0, 0x0, 0x0, 0x4, 0xff, 0xc0, 0x0, 0x0,
+ 0x0, 0x1, 0xef, 0xe1, 0x0, 0x0, 0x0, 0x0,
+ 0xbf, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf9,
+ 0x0, 0x0, 0x0, 0x0, 0x3f, 0xfd, 0x0, 0x0,
+ 0x0, 0x0, 0xd, 0xff, 0x20, 0x0, 0x0, 0x0,
+ 0xa, 0xff, 0x60, 0x0, 0x0, 0x0, 0x6, 0xff,
+ 0xa0, 0x0, 0x0, 0x0, 0x2, 0xff, 0xf5, 0x44,
+ 0x44, 0x44, 0x43, 0x8f, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xb8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb,
+
+ /* U+007B "{" */
+ 0x0, 0x0, 0x0, 0x17, 0xcf, 0xf9, 0x0, 0x0,
+ 0x2, 0xef, 0xff, 0xf9, 0x0, 0x0, 0xb, 0xff,
+ 0xc5, 0x31, 0x0, 0x0, 0x1f, 0xfb, 0x0, 0x0,
+ 0x0, 0x0, 0x4f, 0xf5, 0x0, 0x0, 0x0, 0x0,
+ 0x4f, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xf2,
+ 0x0, 0x0, 0x0, 0x0, 0x5f, 0xf2, 0x0, 0x0,
+ 0x0, 0x0, 0x5f, 0xf2, 0x0, 0x0, 0x0, 0x0,
+ 0x6f, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xe0,
+ 0x0, 0x0, 0x13, 0x49, 0xff, 0x60, 0x0, 0x0,
+ 0x8f, 0xff, 0xc5, 0x0, 0x0, 0x0, 0x8f, 0xff,
+ 0xe9, 0x0, 0x0, 0x0, 0x0, 0x28, 0xff, 0x90,
+ 0x0, 0x0, 0x0, 0x0, 0xaf, 0xf0, 0x0, 0x0,
+ 0x0, 0x0, 0x6f, 0xf2, 0x0, 0x0, 0x0, 0x0,
+ 0x5f, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xf3,
+ 0x0, 0x0, 0x0, 0x0, 0x5f, 0xf3, 0x0, 0x0,
+ 0x0, 0x0, 0x5f, 0xf3, 0x0, 0x0, 0x0, 0x0,
+ 0x5f, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf3,
+ 0x0, 0x0, 0x0, 0x0, 0x3f, 0xf5, 0x0, 0x0,
+ 0x0, 0x0, 0xf, 0xfc, 0x0, 0x0, 0x0, 0x0,
+ 0xa, 0xff, 0xc5, 0x31, 0x0, 0x0, 0x1, 0xdf,
+ 0xff, 0xf9, 0x0, 0x0, 0x0, 0x7, 0xcf, 0xf9,
+
+ /* U+007C "|" */
+ 0xbf, 0xcb, 0xfc, 0xbf, 0xcb, 0xfc, 0xbf, 0xcb,
+ 0xfc, 0xbf, 0xcb, 0xfc, 0xbf, 0xcb, 0xfc, 0xbf,
+ 0xcb, 0xfc, 0xbf, 0xcb, 0xfc, 0xbf, 0xcb, 0xfc,
+ 0xbf, 0xcb, 0xfc, 0xbf, 0xcb, 0xfc, 0xbf, 0xcb,
+ 0xfc, 0xbf, 0xcb, 0xfc, 0xbf, 0xcb, 0xfc, 0xbf,
+ 0xcb, 0xfc, 0xbf, 0xcb, 0xfc, 0xbf, 0xcb, 0xfc,
+
+ /* U+007D "}" */
+ 0x8f, 0xfc, 0x81, 0x0, 0x0, 0x0, 0x8f, 0xff,
+ 0xfe, 0x20, 0x0, 0x0, 0x13, 0x5c, 0xff, 0xc0,
+ 0x0, 0x0, 0x0, 0x0, 0xbf, 0xf1, 0x0, 0x0,
+ 0x0, 0x0, 0x5f, 0xf4, 0x0, 0x0, 0x0, 0x0,
+ 0x2f, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xf5,
+ 0x0, 0x0, 0x0, 0x0, 0x2f, 0xf5, 0x0, 0x0,
+ 0x0, 0x0, 0x2f, 0xf5, 0x0, 0x0, 0x0, 0x0,
+ 0x1f, 0xf7, 0x0, 0x0, 0x0, 0x0, 0xe, 0xfc,
+ 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, 0xb5, 0x31,
+ 0x0, 0x0, 0x0, 0x6c, 0xff, 0xf9, 0x0, 0x0,
+ 0x0, 0x7e, 0xff, 0xf9, 0x0, 0x0, 0x7, 0xff,
+ 0x72, 0x0, 0x0, 0x0, 0xe, 0xfa, 0x0, 0x0,
+ 0x0, 0x0, 0xf, 0xf6, 0x0, 0x0, 0x0, 0x0,
+ 0x1f, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xf5,
+ 0x0, 0x0, 0x0, 0x0, 0x2f, 0xf5, 0x0, 0x0,
+ 0x0, 0x0, 0x2f, 0xf5, 0x0, 0x0, 0x0, 0x0,
+ 0x2f, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xf5,
+ 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf4, 0x0, 0x0,
+ 0x0, 0x0, 0xbf, 0xf1, 0x0, 0x0, 0x13, 0x5c,
+ 0xff, 0xb0, 0x0, 0x0, 0x8f, 0xff, 0xfe, 0x10,
+ 0x0, 0x0, 0x8f, 0xfc, 0x71, 0x0, 0x0, 0x0,
+
+ /* U+007E "~" */
+ 0x0, 0x1, 0x67, 0x40, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x5, 0xff, 0xff, 0xb1, 0x0, 0x0, 0x39,
+ 0x90, 0x3, 0xff, 0xff, 0xff, 0xd1, 0x0, 0x7,
+ 0xff, 0x0, 0xaf, 0xf3, 0x19, 0xff, 0xd2, 0x0,
+ 0xaf, 0xd0, 0xe, 0xf9, 0x0, 0x7, 0xff, 0xe8,
+ 0xaf, 0xf8, 0x0, 0xff, 0x70, 0x0, 0x7, 0xff,
+ 0xff, 0xfd, 0x0, 0x1, 0x10, 0x0, 0x0, 0x3,
+ 0xcf, 0xe9, 0x10, 0x0,
+
+ /* U+007F "" */
+
+ /* U+4E2D "ä¸" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xe, 0xfa, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xef, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xfa,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xef, 0xa0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xe, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef,
+ 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x33,
+ 0x33, 0x33, 0x33, 0x33, 0x3f, 0xfb, 0x33, 0x33,
+ 0x33, 0x33, 0x33, 0x32, 0x7f, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x97, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x7f,
+ 0xf0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xa0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0x97, 0xff, 0x0, 0x0,
+ 0x0, 0x0, 0xe, 0xfa, 0x0, 0x0, 0x0, 0x0,
+ 0xe, 0xf9, 0x7f, 0xf0, 0x0, 0x0, 0x0, 0x0,
+ 0xef, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xef, 0x97,
+ 0xff, 0x0, 0x0, 0x0, 0x0, 0xe, 0xfa, 0x0,
+ 0x0, 0x0, 0x0, 0xe, 0xf9, 0x7f, 0xf0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xa0, 0x0, 0x0, 0x0,
+ 0x0, 0xef, 0x97, 0xff, 0x0, 0x0, 0x0, 0x0,
+ 0xe, 0xfa, 0x0, 0x0, 0x0, 0x0, 0xe, 0xf9,
+ 0x7f, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xa0,
+ 0x0, 0x0, 0x0, 0x0, 0xef, 0x97, 0xff, 0x54,
+ 0x44, 0x44, 0x44, 0x4f, 0xfc, 0x44, 0x44, 0x44,
+ 0x44, 0x4f, 0xf9, 0x7f, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x97, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x7f, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0xef, 0xa0, 0x0, 0x0,
+ 0x0, 0x0, 0xef, 0x94, 0x99, 0x0, 0x0, 0x0,
+ 0x0, 0xe, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x8,
+ 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef,
+ 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xe, 0xfa, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xef, 0xa0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe,
+ 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xa0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xe, 0xfa, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xef, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xfa, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xef, 0xa0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+
+ /* U+6587 "æ–‡" */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x35,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xf2,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0xb0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, 0x40,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xfa, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0xca, 0x55, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x50, 0x1f, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x0, 0xee, 0xee, 0xef,
+ 0xff, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xef,
+ 0xff, 0xee, 0xee, 0xe0, 0x0, 0x0, 0x0, 0x3f,
+ 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xff,
+ 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff,
+ 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xfb,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xfc, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xf0,
+ 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0x80, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0x60,
+ 0x0, 0x0, 0x0, 0x0, 0x6f, 0xf2, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xfd, 0x0,
+ 0x0, 0x0, 0x0, 0xd, 0xfc, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xf4, 0x0,
+ 0x0, 0x0, 0x4, 0xff, 0x50, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xd0, 0x0,
+ 0x0, 0x0, 0xcf, 0xe0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0x80, 0x0,
+ 0x0, 0x6f, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x9, 0xff, 0x30, 0x0,
+ 0x1f, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x1e, 0xfe, 0x10, 0xd,
+ 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3f, 0xfd, 0x1b, 0xff,
+ 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x6f, 0xff, 0xff, 0x90,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, 0xc0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x6f, 0xff, 0xff, 0x70, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x4, 0xcf, 0xff, 0xbf, 0xff, 0xd6, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x4b, 0xff, 0xfe, 0x40, 0x4e, 0xff, 0xfe, 0x71,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0xdf,
+ 0xff, 0xf8, 0x0, 0x0, 0x8, 0xff, 0xff, 0xfb,
+ 0x50, 0x0, 0x0, 0x0, 0x5, 0xaf, 0xff, 0xff,
+ 0x91, 0x0, 0x0, 0x0, 0x1, 0x9f, 0xff, 0xff,
+ 0xfb, 0x62, 0x1, 0xaf, 0xff, 0xff, 0xe8, 0x10,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0xef, 0xff,
+ 0xff, 0xd0, 0xa, 0xff, 0xfc, 0x60, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5c, 0xff,
+ 0xe2, 0x0, 0xc, 0x93, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x74,
+ 0x0
+};
+
+
+static const sgl_font_table_t consolas32_tab[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 273, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 0, .adv_w = 273, .box_w = 5, .box_h = 22, .ofs_x = 6, .ofs_y = 0},
+ {.bitmap_index = 55, .adv_w = 273, .box_w = 11, .box_h = 8, .ofs_x = 3, .ofs_y = 14},
+ {.bitmap_index = 99, .adv_w = 273, .box_w = 17, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 269, .adv_w = 273, .box_w = 15, .box_h = 28, .ofs_x = 1, .ofs_y = -4},
+ {.bitmap_index = 479, .adv_w = 273, .box_w = 17, .box_h = 22, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 666, .adv_w = 273, .box_w = 18, .box_h = 22, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 864, .adv_w = 273, .box_w = 5, .box_h = 8, .ofs_x = 6, .ofs_y = 14},
+ {.bitmap_index = 884, .adv_w = 273, .box_w = 10, .box_h = 31, .ofs_x = 4, .ofs_y = -7},
+ {.bitmap_index = 1039, .adv_w = 273, .box_w = 10, .box_h = 31, .ofs_x = 3, .ofs_y = -7},
+ {.bitmap_index = 1194, .adv_w = 273, .box_w = 13, .box_h = 14, .ofs_x = 2, .ofs_y = 8},
+ {.bitmap_index = 1285, .adv_w = 273, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1405, .adv_w = 273, .box_w = 8, .box_h = 11, .ofs_x = 3, .ofs_y = -5},
+ {.bitmap_index = 1449, .adv_w = 273, .box_w = 10, .box_h = 3, .ofs_x = 4, .ofs_y = 7},
+ {.bitmap_index = 1464, .adv_w = 273, .box_w = 6, .box_h = 6, .ofs_x = 5, .ofs_y = 0},
+ {.bitmap_index = 1482, .adv_w = 273, .box_w = 17, .box_h = 22, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1669, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 1819, .adv_w = 273, .box_w = 14, .box_h = 20, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 1959, .adv_w = 273, .box_w = 14, .box_h = 20, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2099, .adv_w = 273, .box_w = 13, .box_h = 20, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2229, .adv_w = 273, .box_w = 17, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2399, .adv_w = 273, .box_w = 13, .box_h = 20, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 2529, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2679, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2829, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 2979, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 3129, .adv_w = 273, .box_w = 5, .box_h = 16, .ofs_x = 6, .ofs_y = 0},
+ {.bitmap_index = 3169, .adv_w = 273, .box_w = 9, .box_h = 22, .ofs_x = 3, .ofs_y = -6},
+ {.bitmap_index = 3268, .adv_w = 273, .box_w = 12, .box_h = 19, .ofs_x = 2, .ofs_y = -1},
+ {.bitmap_index = 3382, .adv_w = 273, .box_w = 14, .box_h = 8, .ofs_x = 2, .ofs_y = 5},
+ {.bitmap_index = 3438, .adv_w = 273, .box_w = 12, .box_h = 19, .ofs_x = 3, .ofs_y = -1},
+ {.bitmap_index = 3552, .adv_w = 273, .box_w = 10, .box_h = 22, .ofs_x = 4, .ofs_y = 0},
+ {.bitmap_index = 3662, .adv_w = 273, .box_w = 17, .box_h = 28, .ofs_x = 0, .ofs_y = -6},
+ {.bitmap_index = 3900, .adv_w = 273, .box_w = 17, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 4070, .adv_w = 273, .box_w = 14, .box_h = 20, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 4210, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4360, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4510, .adv_w = 273, .box_w = 12, .box_h = 20, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 4630, .adv_w = 273, .box_w = 12, .box_h = 20, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 4750, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 4900, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5050, .adv_w = 273, .box_w = 13, .box_h = 20, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 5180, .adv_w = 273, .box_w = 12, .box_h = 20, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 5300, .adv_w = 273, .box_w = 14, .box_h = 20, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 5440, .adv_w = 273, .box_w = 12, .box_h = 20, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 5560, .adv_w = 273, .box_w = 17, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 5730, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 5880, .adv_w = 273, .box_w = 17, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 6050, .adv_w = 273, .box_w = 14, .box_h = 20, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 6190, .adv_w = 273, .box_w = 18, .box_h = 27, .ofs_x = 0, .ofs_y = -7},
+ {.bitmap_index = 6433, .adv_w = 273, .box_w = 14, .box_h = 20, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 6573, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 6723, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 6873, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 7023, .adv_w = 273, .box_w = 17, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 7193, .adv_w = 273, .box_w = 17, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 7363, .adv_w = 273, .box_w = 17, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 7533, .adv_w = 273, .box_w = 18, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 7713, .adv_w = 273, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 7863, .adv_w = 273, .box_w = 8, .box_h = 29, .ofs_x = 5, .ofs_y = -6},
+ {.bitmap_index = 7979, .adv_w = 273, .box_w = 14, .box_h = 26, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 8161, .adv_w = 273, .box_w = 8, .box_h = 29, .ofs_x = 4, .ofs_y = -6},
+ {.bitmap_index = 8277, .adv_w = 273, .box_w = 15, .box_h = 10, .ofs_x = 1, .ofs_y = 10},
+ {.bitmap_index = 8352, .adv_w = 273, .box_w = 18, .box_h = 3, .ofs_x = 0, .ofs_y = -6},
+ {.bitmap_index = 8379, .adv_w = 127, .box_w = 4, .box_h = 8, .ofs_x = 2, .ofs_y = 17},
+ {.bitmap_index = 8395, .adv_w = 273, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 8499, .adv_w = 273, .box_w = 14, .box_h = 22, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 8653, .adv_w = 273, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 8757, .adv_w = 273, .box_w = 14, .box_h = 22, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 8911, .adv_w = 273, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 9031, .adv_w = 273, .box_w = 16, .box_h = 22, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 9207, .adv_w = 273, .box_w = 15, .box_h = 22, .ofs_x = 1, .ofs_y = -6},
+ {.bitmap_index = 9372, .adv_w = 273, .box_w = 13, .box_h = 22, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 9515, .adv_w = 273, .box_w = 13, .box_h = 22, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 9658, .adv_w = 273, .box_w = 13, .box_h = 28, .ofs_x = 1, .ofs_y = -6},
+ {.bitmap_index = 9840, .adv_w = 273, .box_w = 15, .box_h = 22, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 10005, .adv_w = 273, .box_w = 13, .box_h = 22, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 10148, .adv_w = 273, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 10268, .adv_w = 273, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 10372, .adv_w = 273, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 10492, .adv_w = 273, .box_w = 14, .box_h = 22, .ofs_x = 2, .ofs_y = -6},
+ {.bitmap_index = 10646, .adv_w = 273, .box_w = 14, .box_h = 23, .ofs_x = 1, .ofs_y = -6},
+ {.bitmap_index = 10807, .adv_w = 273, .box_w = 13, .box_h = 16, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 10911, .adv_w = 273, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 11015, .adv_w = 273, .box_w = 15, .box_h = 22, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 11180, .adv_w = 273, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 11284, .adv_w = 273, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 11404, .adv_w = 273, .box_w = 17, .box_h = 16, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 11540, .adv_w = 273, .box_w = 16, .box_h = 16, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 11668, .adv_w = 273, .box_w = 16, .box_h = 22, .ofs_x = 0, .ofs_y = -6},
+ {.bitmap_index = 11844, .adv_w = 273, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = 0},
+ {.bitmap_index = 11948, .adv_w = 273, .box_w = 12, .box_h = 28, .ofs_x = 2, .ofs_y = -6},
+ {.bitmap_index = 12116, .adv_w = 273, .box_w = 3, .box_h = 32, .ofs_x = 7, .ofs_y = -6},
+ {.bitmap_index = 12164, .adv_w = 273, .box_w = 12, .box_h = 28, .ofs_x = 3, .ofs_y = -6},
+ {.bitmap_index = 12332, .adv_w = 273, .box_w = 17, .box_h = 7, .ofs_x = 0, .ofs_y = 5},
+ {.bitmap_index = 12392, .adv_w = 273, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 12392, .adv_w = 496, .box_w = 27, .box_h = 31, .ofs_x = 2, .ofs_y = -4},
+ {.bitmap_index = 12811, .adv_w = 496, .box_w = 31, .box_h = 30, .ofs_x = 0, .ofs_y = -4}
+};
+
+static const uint32_t unicode_list_1[] = {
+ 0x0, 0x175a
+};
+
+static const sgl_font_unicode_t consolas34_unicode[] = {
+ { .offset = 32, .len = 96, .list = NULL, .tab_offset = 1, },
+ { .offset = 20013, .len = 2, .list = unicode_list_1, .tab_offset = 97, },
+};
+
+const sgl_font_t consolas32 = {
+ .bitmap = consolas32_bitmap,
+ .table = consolas32_tab,
+ .font_table_size = SGL_ARRAY_SIZE(consolas32_tab),
+ .font_height = 34,
+ .base_line = 7,
+ .bpp = 4,
+ .unicode = consolas34_unicode,
+ .unicode_num = 2,
+};
+
+
+#endif // !CONFIG_SGL_FONT_CONSOLAS32
diff --git a/User/system/sgl/fonts/sgl_ascii_song23.c b/User/system/sgl/fonts/sgl_ascii_song23.c
new file mode 100644
index 0000000..f415d6c
--- /dev/null
+++ b/User/system/sgl/fonts/sgl_ascii_song23.c
@@ -0,0 +1,1740 @@
+/* source/fonts/sgl_song23.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ *
+ * Email: 1477153217@qq.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+
+
+#if (CONFIG_SGL_FONT_SONG23)
+
+/*
+*.box_h: 24 pixel
+*/
+static const uint8_t sgl_ascii_song23_bitmap[] = {
+/* */
+
+/* ! */
+0x00,0x00,0x8e,0xc0,0x00,0x00, //....+@%.....
+0x00,0x00,0xaf,0xe0,0x00,0x00, //....%@@.....
+0x00,0x00,0xaf,0xe0,0x00,0x00, //....%@@.....
+0x00,0x00,0x8e,0xc0,0x00,0x00, //....+@%.....
+0x00,0x00,0x5e,0xc0,0x00,0x00, //....+@%.....
+0x00,0x00,0x3e,0xa0,0x00,0x00, //.....@%.....
+0x00,0x00,0x3c,0x80,0x00,0x00, //.....%+.....
+0x00,0x00,0x3c,0x80,0x00,0x00, //.....%+.....
+0x00,0x00,0x0c,0x80,0x00,0x00, //.....%+.....
+0x00,0x00,0x0a,0x50,0x00,0x00, //.....%+.....
+0x00,0x00,0x0a,0x50,0x00,0x00, //.....%+.....
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x8e,0xc0,0x00,0x00, //....+@%.....
+0x00,0x00,0xcf,0xe5,0x00,0x00, //....%@@+....
+0x00,0x00,0x8e,0xc0,0x00,0x00, //....+@%.....
+
+
+/* " */
+0x00,0x03,0xee,0x58,0xec,0x00, //....@@++@%..
+0x00,0x0a,0xfe,0x5e,0xfe,0x00, //...%@@+@@@..
+0x00,0x3e,0xe8,0x8e,0xe3,0x00, //...@@++@@...
+0x00,0xae,0x80,0xee,0x30,0x00, //..%@+.@@....
+0x03,0xea,0x08,0xc5,0x00,0x00, //..@%.+%+....
+0x08,0xa0,0x0a,0x50,0x00,0x00, //.+%..%+.....
+
+
+/* # */
+0x00,0x0c,0xa0,0x00,0xac,0x00, //...%%...%%..
+0x00,0x0a,0x80,0x00,0xac,0x00, //...%+...%%..
+0x00,0x0c,0x80,0x00,0xca,0x00, //...%+...%%..
+0x03,0x3c,0x83,0x33,0xca,0x30, //...%+...%%..
+0x8e,0xff,0xff,0xff,0xff,0xe8, //+@@@@@@@@@@+
+0x5a,0xac,0xca,0xaa,0xec,0xa5, //+%%%%%%%@%%+
+0x00,0x5a,0x30,0x00,0xa5,0x00, //..+%....%+..
+0x00,0x5a,0x30,0x03,0xa5,0x00, //..+%....%+..
+0x00,0x8c,0x00,0x05,0xa3,0x00, //..+%...+%...
+0x00,0x8c,0x00,0x05,0xa3,0x00, //..+%...+%...
+0x8c,0xee,0xcc,0xce,0xfc,0xc8, //+%@@%%%@@%%+
+0x8e,0xff,0xff,0xff,0xff,0xe8, //+@@@@@@@@@@+
+0x00,0xca,0x00,0x0a,0xc0,0x00, //..%%...%%...
+0x00,0xca,0x00,0x0a,0xc0,0x00, //..%%...%%...
+0x00,0xa8,0x00,0x0a,0xc0,0x00, //..%+...%%...
+0x00,0xc8,0x00,0x0c,0xa0,0x00, //..%+...%%...
+
+
+/* $ */
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x03,0xcf,0xfe,0xa0,0x00, //....%@@@%...
+0x00,0x5e,0xca,0xc8,0xec,0x00, //..+@%%%+@%..
+0x00,0xee,0x0a,0xc3,0xee,0x30, //..@@.%%.@@..
+0x03,0xec,0x0a,0xc8,0xec,0x00, //..@%.%%+@%..
+0x03,0xee,0x3a,0xc0,0x00,0x00, //..@@.%%.....
+0x00,0xaf,0xea,0xc0,0x00,0x00, //..%@@%%.....
+0x00,0x0c,0xff,0xc0,0x00,0x00, //...%@@%.....
+0x00,0x00,0xae,0xfc,0x00,0x00, //....%@@%....
+0x00,0x00,0x0a,0xff,0xc0,0x00, //.....%@@%...
+0x00,0x00,0x0a,0xce,0xfa,0x00, //.....%%@@%..
+0x00,0x00,0x0a,0xc3,0xee,0x30, //.....%%.@@..
+0x05,0xee,0x0a,0xc0,0xae,0x50, //.+@@.%%.%@+.
+0x0a,0xfe,0x3a,0xc0,0xae,0x50, //.%@@.%%.%@+.
+0x08,0xea,0x0a,0xc0,0xce,0x30, //.+@%.%%.%@..
+0x00,0xee,0x5a,0xc8,0xc8,0x00, //..@@+%%+%+..
+0x00,0x0a,0xef,0xfc,0x50,0x00, //...%@@@%+...
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x03,0x50,0x00,0x00, //......+.....
+
+
+/* % */
+0x0a,0xee,0x50,0x00,0xaa,0x00, //.%@@+...%%..
+0x8c,0x5a,0xe3,0x03,0x83,0x00, //+%+%@...+...
+0xce,0x05,0xc8,0x0a,0xa0,0x00, //%@.+%+.%%...
+0xec,0x03,0xea,0x0a,0x50,0x00, //@%..@%.%+...
+0xec,0x03,0xea,0x8a,0x00,0x00, //@%..@%+%....
+0xec,0x03,0xea,0xc8,0x00,0x00, //@%..@%%+....
+0xce,0x05,0xc8,0xa3,0x00,0x00, //%@.+%+%.....
+0x8c,0x5a,0xea,0xaa,0xee,0x80, //+%+%@%%%@@+.
+0x0a,0xee,0x8a,0x6c,0x8a,0xe3, //.%@@+%+%+%@.
+0x00,0x00,0x8a,0xae,0x05,0xc8, //....+%%@.+%+
+0x00,0x00,0xa5,0xec,0x03,0xea, //....%+@%..@%
+0x00,0x05,0xa0,0xec,0x03,0xea, //...+%.@%..@%
+0x00,0x0a,0x80,0xec,0x03,0xea, //...%+.@%..@%
+0x00,0x38,0x30,0xce,0x05,0xc8, //...+..%@.+%+
+0x00,0xaa,0x00,0x5a,0x5a,0xe3, //..%%..+%+%@.
+0x03,0xa5,0x00,0x0a,0xee,0x80, //..%+...%@@+.
+
+
+/* & */
+0x00,0x3c,0xfe,0xa0,0x00,0x00, //...%@@%.....
+0x00,0xce,0x38,0xc8,0x00,0x00, //..%@.+%+....
+0x03,0xea,0x05,0xea,0x00,0x00, //..@%.+@%....
+0x05,0xc8,0x05,0xea,0x00,0x00, //.+%+.+@%....
+0x03,0xea,0x08,0xc5,0x00,0x00, //..@%.+%+....
+0x03,0xec,0x0c,0xc0,0x00,0x00, //..@%.%%.....
+0x00,0xce,0xaa,0x00,0x00,0x00, //..%@%%......
+0x00,0xcf,0xa0,0x5e,0xff,0xc0, //..%@%.+@@@%.
+0x0c,0xae,0xe0,0x03,0xea,0x00, //.%%@@...@%..
+0x8c,0x3c,0xe8,0x03,0xa5,0x00, //+%.%@+..%+..
+0xce,0x05,0xee,0x05,0xa0,0x00, //%@.+@@.+%...
+0xee,0x00,0xaf,0xaa,0xa0,0x00, //@@..%@%%%...
+0xee,0x30,0x3e,0xea,0x50,0x00, //@@...@@%+...
+0xce,0x50,0x05,0xee,0x30,0x33, //%@+..+@@....
+0x3e,0xe5,0x08,0xce,0xe3,0xaa, //.@@+.+%@@.%%
+0x03,0xcf,0xec,0x35,0xef,0xc3, //..%@@%.+@@%.
+
+
+/* ' */
+0x08,0xee,0x50,0x00,0x00,0x00, //.+@@+.......
+0x0a,0xff,0xa0,0x00,0x00,0x00, //.%@@%.......
+0x00,0xae,0xa0,0x00,0x00,0x00, //..%@%.......
+0x00,0x5c,0x80,0x00,0x00,0x00, //..+%+.......
+0x00,0xcc,0x00,0x00,0x00,0x00, //..%%........
+0x0a,0xa0,0x00,0x00,0x00,0x00, //.%%.........
+
+
+/* ( */
+0x00,0x00,0x00,0x00,0x0a,0xa0, //.........%%.
+0x00,0x00,0x00,0x00,0x8c,0x30, //........+%..
+0x00,0x00,0x00,0x05,0xa5,0x00, //.......+%+..
+0x00,0x00,0x00,0x0e,0xc0,0x00, //.......@%...
+0x00,0x00,0x00,0xae,0x30,0x00, //......%@....
+0x00,0x00,0x03,0xec,0x00,0x00, //......@%....
+0x00,0x00,0x08,0xc8,0x00,0x00, //.....+%+....
+0x00,0x00,0x0c,0xe3,0x00,0x00, //.....%@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xc0,0x00,0x00, //.....@%.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0c,0xe3,0x00,0x00, //.....%@.....
+0x00,0x00,0x08,0xc8,0x00,0x00, //.....+%+....
+0x00,0x00,0x03,0xec,0x00,0x00, //......@%....
+0x00,0x00,0x00,0xae,0x30,0x00, //......%@....
+0x00,0x00,0x00,0x3e,0xa0,0x00, //.......@%...
+0x00,0x00,0x00,0x05,0xa5,0x00, //.......+%+..
+0x00,0x00,0x00,0x00,0x8c,0x30, //........+%..
+0x00,0x00,0x00,0x00,0x0a,0xa0, //.........%%.
+
+
+/* ) */
+0x0a,0x80,0x00,0x00,0x00,0x00, //.%+.........
+0x03,0xc8,0x00,0x00,0x00,0x00, //..%+........
+0x00,0x8c,0x50,0x00,0x00,0x00, //..+%+.......
+0x00,0x0c,0xe0,0x00,0x00,0x00, //...%@.......
+0x00,0x05,0xc8,0x00,0x00,0x00, //...+%+......
+0x00,0x00,0xce,0x00,0x00,0x00, //....%@......
+0x00,0x00,0x8c,0x80,0x00,0x00, //....+%+.....
+0x00,0x00,0x5e,0xa0,0x00,0x00, //....+@%.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x5e,0xa0,0x00,0x00, //....+@%.....
+0x00,0x00,0x8c,0x80,0x00,0x00, //....+%+.....
+0x00,0x00,0xce,0x00,0x00,0x00, //....%@......
+0x00,0x05,0xea,0x00,0x00,0x00, //...+@%......
+0x00,0x0c,0xe0,0x00,0x00,0x00, //...%@.......
+0x00,0x8c,0x50,0x00,0x00,0x00, //..+%+.......
+0x03,0xc8,0x00,0x00,0x00,0x00, //..%+........
+0x0a,0x80,0x00,0x00,0x00,0x00, //.%+.........
+
+
+/* * */
+0x00,0x00,0x3e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x3e,0xe5,0x0e,0xc0,0x8e,0xe0, //.@@+.@%.+@@.
+0x0a,0xee,0x5c,0xaa,0xfe,0xa0, //.%@@+%%%@@%.
+0x00,0x05,0xa8,0xaa,0x50,0x00, //...+%+%%+...
+0x00,0x05,0xaa,0xaa,0x50,0x00, //...+%%%%+...
+0x0a,0xee,0xaa,0xaa,0xfe,0xa0, //.%@@%%%%@@%.
+0x5e,0xe5,0x0e,0xc0,0x8e,0xe3, //+@@+.@%.+@@.
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x5e,0xe3,0x00,0x00, //....+@@.....
+0x00,0x00,0x5e,0xe0,0x00,0x00, //....+@@.....
+
+
+/* + */
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x3e,0xff,0xff,0xff,0xff,0xe5, //.@@@@@@@@@@+
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x0a,0xc0,0x00,0x00, //.....%%.....
+
+
+/* , */
+0x08,0xee,0x50,0x00,0x00,0x00, //.+@@+.......
+0x0a,0xff,0xa0,0x00,0x00,0x00, //.%@@%.......
+0x00,0xaf,0xa0,0x00,0x00,0x00, //..%@%.......
+0x00,0x5c,0x80,0x00,0x00,0x00, //..+%+.......
+0x00,0xcc,0x00,0x00,0x00,0x00, //..%%........
+0x0a,0xa0,0x00,0x00,0x00,0x00, //.%%.........
+
+
+/* - */
+0xaf,0xff,0xff,0xff,0xff,0xe0, //%@@@@@@@@@@.
+
+
+/* . */
+0x08,0xee,0x30,0x00,0x00,0x00, //.+@@........
+0x0c,0xfe,0x80,0x00,0x00,0x00, //.%@@+.......
+0x08,0xee,0x30,0x00,0x00,0x00, //.+@@........
+
+
+/* / */
+0x00,0x00,0x00,0x00,0x03,0x83, //..........+.
+0x00,0x00,0x00,0x00,0x0a,0xc0, //.........%%.
+0x00,0x00,0x00,0x00,0x3a,0x50, //.........%+.
+0x00,0x00,0x00,0x00,0xac,0x00, //........%%..
+0x00,0x00,0x00,0x03,0xa5,0x00, //........%+..
+0x00,0x00,0x00,0x08,0xc0,0x00, //.......+%...
+0x00,0x00,0x00,0x0a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x8c,0x00,0x00, //......+%....
+0x00,0x00,0x00,0xa5,0x00,0x00, //......%+....
+0x00,0x00,0x08,0xc0,0x00,0x00, //.....+%.....
+0x00,0x00,0x0c,0x80,0x00,0x00, //.....%+.....
+0x00,0x00,0x8c,0x00,0x00,0x00, //....+%......
+0x00,0x00,0xc8,0x00,0x00,0x00, //....%+......
+0x00,0x08,0xc0,0x00,0x00,0x00, //...+%.......
+0x00,0x0a,0x80,0x00,0x00,0x00, //...%+.......
+0x00,0x8c,0x00,0x00,0x00,0x00, //..+%........
+0x00,0xc8,0x00,0x00,0x00,0x00, //..%+........
+0x08,0xa0,0x00,0x00,0x00,0x00, //.+%.........
+0x0c,0x80,0x00,0x00,0x00,0x00, //.%+.........
+0x5a,0x00,0x00,0x00,0x00,0x00, //+%..........
+
+
+/* 0 */
+0x00,0x05,0xcf,0xfc,0x30,0x00, //...+%@@%....
+0x00,0x5e,0xe3,0x3e,0xe5,0x00, //..+@@..@@+..
+0x00,0xee,0x50,0x03,0xee,0x00, //..@@+...@@..
+0x08,0xec,0x00,0x00,0xce,0x50, //.+@%....%@+.
+0x0c,0xe8,0x00,0x00,0xaf,0xa0, //.%@+....%@%.
+0x0e,0xe5,0x00,0x00,0x8e,0xc0, //.@@+....+@%.
+0x3e,0xe3,0x00,0x00,0x5e,0xe0, //.@@.....+@@.
+0x3e,0xe3,0x00,0x00,0x5e,0xe0, //.@@.....+@@.
+0x3e,0xe3,0x00,0x00,0x5e,0xe0, //.@@.....+@@.
+0x3e,0xe3,0x00,0x00,0x5e,0xe0, //.@@.....+@@.
+0x0e,0xe5,0x00,0x00,0x8e,0xc0, //.@@+....+@%.
+0x0c,0xe8,0x00,0x00,0xaf,0xa0, //.%@+....%@%.
+0x08,0xec,0x00,0x00,0xce,0x50, //.+@%....%@+.
+0x00,0xee,0x50,0x05,0xec,0x00, //..@@+..+@%..
+0x00,0x5e,0xe3,0x3e,0xe3,0x00, //..+@@..@@...
+0x00,0x05,0xcf,0xfc,0x30,0x00, //...+%@@%....
+
+
+/* 1 */
+0x00,0x00,0x03,0x83,0x00,0x00, //......+.....
+0x00,0x5a,0xcf,0xe3,0x00,0x00, //..+%%@@.....
+0x00,0x36,0x8e,0xe3,0x00,0x00, //...++@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x5e,0xe8,0x00,0x00, //....+@@+....
+0x00,0x8e,0xff,0xff,0xfc,0x00, //..+@@@@@@%..
+
+
+/* 2 */
+0x00,0x0a,0xef,0xfe,0xa0,0x00, //...%@@@@%...
+0x00,0xcc,0x50,0x0a,0xee,0x00, //..%%+..%@@..
+0x0a,0xe5,0x00,0x00,0xce,0x80, //.%@+....%@+.
+0x0c,0xe5,0x00,0x00,0x8e,0xa0, //.%@+....+@%.
+0x0c,0xfc,0x00,0x00,0x8e,0xa0, //.%@%....+@%.
+0x03,0x63,0x00,0x00,0xae,0x80, //..+.....%@+.
+0x00,0x00,0x00,0x03,0xee,0x00, //........@@..
+0x00,0x00,0x00,0x0a,0xe3,0x00, //.......%@...
+0x00,0x00,0x00,0x8c,0x30,0x00, //......+%....
+0x00,0x00,0x08,0xc3,0x00,0x00, //.....+%.....
+0x00,0x00,0x8c,0x30,0x00,0x00, //....+%......
+0x00,0x08,0xc3,0x00,0x00,0x00, //...+%.......
+0x00,0x8c,0x30,0x00,0x08,0xa0, //..+%.....+%.
+0x05,0xa5,0x00,0x00,0x0c,0xa0, //.+%+.....%%.
+0x3e,0xc6,0x66,0x66,0xce,0x80, //.@%+++++%@+.
+0x3e,0xff,0xff,0xff,0xfe,0x50, //.@@@@@@@@@+.
+
+
+/* 3 */
+0x00,0x3a,0xef,0xfc,0x50,0x00, //...%@@@%+...
+0x00,0xcc,0x30,0x5e,0xe5,0x00, //..%%..+@@+..
+0x08,0xc8,0x00,0x05,0xee,0x00, //.+%+...+@@..
+0x08,0xec,0x00,0x00,0xee,0x30, //.+@%....@@..
+0x00,0x53,0x00,0x00,0xee,0x00, //..+.....@@..
+0x00,0x00,0x00,0x05,0xea,0x00, //.......+@%..
+0x00,0x00,0x00,0x5c,0xa0,0x00, //......+%%...
+0x00,0x00,0xaf,0xfc,0x30,0x00, //....%@@%....
+0x00,0x00,0x00,0x3c,0xe8,0x00, //.......%@+..
+0x00,0x00,0x00,0x00,0xee,0x30, //........@@..
+0x00,0x00,0x00,0x00,0x8e,0xa0, //........+@%.
+0x00,0x53,0x00,0x00,0x8e,0xc0, //..+.....+@%.
+0x0c,0xfc,0x00,0x00,0x8e,0xa0, //.%@%....+@%.
+0x0c,0xfa,0x00,0x00,0xce,0x50, //.%@%....%@+.
+0x03,0xec,0x30,0x3c,0xfa,0x00, //..@%...%@%..
+0x00,0x3c,0xef,0xfc,0x50,0x00, //...%@@@%+...
+
+
+/* 4 */
+0x00,0x00,0x00,0x0e,0xc0,0x00, //.......@%...
+0x00,0x00,0x00,0xaf,0xc0,0x00, //......%@%...
+0x00,0x00,0x05,0xef,0xc0,0x00, //.....+@@%...
+0x00,0x00,0x0e,0xce,0xc0,0x00, //.....@%@%...
+0x00,0x00,0xce,0x5e,0xc0,0x00, //....%@+@%...
+0x00,0x08,0xc5,0x5e,0xc0,0x00, //...+%++@%...
+0x00,0x3c,0x80,0x5e,0xc0,0x00, //...%+.+@%...
+0x00,0xcc,0x00,0x5e,0xc0,0x00, //..%%..+@%...
+0x08,0xc0,0x00,0x5e,0xc0,0x00, //.+%...+@%...
+0x3a,0x50,0x00,0x5e,0xc0,0x00, //.%+...+@%...
+0x8e,0xff,0xff,0xff,0xff,0xe5, //+@@@@@@@@@@+
+0x00,0x00,0x00,0x5e,0xc0,0x00, //......+@%...
+0x00,0x00,0x00,0x5e,0xc0,0x00, //......+@%...
+0x00,0x00,0x00,0x5e,0xc0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xe3,0x00, //......+@@...
+0x00,0x00,0xaf,0xff,0xff,0xe0, //....%@@@@@@.
+
+
+/* 5 */
+0x00,0xcf,0xff,0xff,0xfe,0x80, //..%@@@@@@@+.
+0x00,0xaa,0x66,0x66,0x65,0x30, //..%%++++++..
+0x00,0xa8,0x00,0x00,0x00,0x00, //..%+........
+0x00,0xc8,0x00,0x00,0x00,0x00, //..%+........
+0x00,0xa5,0x00,0x00,0x00,0x00, //..%+........
+0x00,0xa5,0x00,0x00,0x00,0x00, //..%+........
+0x03,0xa5,0xcf,0xfe,0xa0,0x00, //..%+%@@@%...
+0x03,0xaa,0x80,0x08,0xec,0x00, //..%%+..+@%..
+0x00,0xa8,0x00,0x00,0xce,0x50, //..%+....%@+.
+0x00,0x00,0x00,0x00,0x8e,0xa0, //........+@%.
+0x00,0x00,0x00,0x00,0x5e,0xc0, //........+@%.
+0x08,0xca,0x00,0x00,0x5e,0xc0, //.+%%....+@%.
+0x0c,0xfc,0x00,0x00,0x8e,0xa0, //.%@%....+@%.
+0x0a,0xe5,0x00,0x00,0xce,0x50, //.%@+....%@+.
+0x03,0xec,0x30,0x3c,0xfa,0x00, //..@%...%@%..
+0x00,0x3a,0xef,0xfe,0x80,0x00, //...%@@@@+...
+
+
+/* 6 */
+0x00,0x00,0xae,0xff,0xc3,0x00, //....%@@@%...
+0x00,0x0c,0xe5,0x05,0xee,0x00, //...%@+.+@@..
+0x00,0xce,0x30,0x05,0xee,0x30, //..%@...+@@..
+0x05,0xea,0x00,0x00,0x33,0x00, //.+@%........
+0x0a,0xe8,0x00,0x00,0x00,0x00, //.%@+........
+0x0e,0xe5,0x00,0x00,0x00,0x00, //.@@+........
+0x0e,0xe3,0xae,0xff,0xc3,0x00, //.@@.%@@@%...
+0x3e,0xec,0xc3,0x05,0xee,0x30, //.@@%%..+@@..
+0x3e,0xfc,0x00,0x00,0x8e,0xa0, //.@@%....+@%.
+0x3e,0xe3,0x00,0x00,0x3e,0xe0, //.@@......@@.
+0x3e,0xe3,0x00,0x00,0x3e,0xe0, //.@@......@@.
+0x0e,0xe5,0x00,0x00,0x3e,0xe0, //.@@+.....@@.
+0x0a,0xfa,0x00,0x00,0x3e,0xc0, //.%@%.....@%.
+0x05,0xee,0x30,0x00,0x8c,0x80, //.+@@....+%+.
+0x00,0xae,0xe3,0x05,0xec,0x00, //..%@@..+@%..
+0x00,0x05,0xcf,0xfe,0xa0,0x00, //...+%@@@%...
+
+
+/* 7 */
+0x05,0xef,0xff,0xff,0xff,0xe0, //.+@@@@@@@@@.
+0x08,0xec,0x66,0x66,0x8c,0x80, //.+@%+++++%+.
+0x0a,0xc0,0x00,0x00,0xac,0x00, //.%%.....%%..
+0x0a,0x80,0x00,0x03,0xa5,0x00, //.%+.....%+..
+0x00,0x00,0x00,0x0a,0xa0,0x00, //.......%%...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0xac,0x00,0x00, //......%%....
+0x00,0x00,0x03,0xc8,0x00,0x00, //......%+....
+0x00,0x00,0x0a,0xe3,0x00,0x00, //.....%@.....
+0x00,0x00,0x0e,0xc0,0x00,0x00, //.....@%.....
+0x00,0x00,0x5e,0xa0,0x00,0x00, //....+@%.....
+0x00,0x00,0xae,0x80,0x00,0x00, //....%@+.....
+0x00,0x00,0xce,0x80,0x00,0x00, //....%@+.....
+0x00,0x00,0xef,0xa0,0x00,0x00, //....@@%.....
+0x00,0x03,0xef,0xa0,0x00,0x00, //....@@%.....
+0x00,0x00,0xce,0x80,0x00,0x00, //....%@+.....
+
+
+/* 8 */
+0x00,0x3a,0xef,0xfe,0xa0,0x00, //...%@@@@%...
+0x00,0xee,0x50,0x08,0xec,0x00, //..@@+..+@%..
+0x0a,0xe5,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0c,0xe0,0x00,0x00,0x5e,0xa0, //.%@.....+@%.
+0x0c,0xe3,0x00,0x00,0x5c,0x80, //.%@.....+%+.
+0x08,0xee,0x30,0x00,0xae,0x30, //.+@@....%@..
+0x00,0xae,0xe8,0x05,0xa5,0x00, //..%@@+.+%+..
+0x00,0x08,0xef,0xfe,0x30,0x00, //...+@@@@....
+0x00,0xac,0x35,0xcf,0xe3,0x00, //..%%.+%@@...
+0x08,0xc5,0x00,0x0a,0xee,0x30, //.+%+...%@@..
+0x0e,0xc0,0x00,0x00,0xaf,0xa0, //.@%.....%@%.
+0x3e,0xa0,0x00,0x00,0x3e,0xc0, //.@%......@%.
+0x3e,0xa0,0x00,0x00,0x3e,0xc0, //.@%......@%.
+0x0e,0xe3,0x00,0x00,0x8c,0x80, //.@@.....+%+.
+0x03,0xee,0x50,0x08,0xec,0x00, //..@@+..+@%..
+0x00,0x3a,0xef,0xfe,0x80,0x00, //...%@@@@+...
+
+
+/* 9 */
+0x00,0x3a,0xef,0xfc,0x50,0x00, //...%@@@%+...
+0x00,0xee,0x50,0x3c,0xe8,0x00, //..@@+..%@+..
+0x0a,0xe8,0x00,0x00,0xee,0x30, //.%@+....@@..
+0x0e,0xe3,0x00,0x00,0xae,0x80, //.@@.....%@+.
+0x3e,0xe0,0x00,0x00,0x8e,0xc0, //.@@.....+@%.
+0x3e,0xe0,0x00,0x00,0x8e,0xc0, //.@@.....+@%.
+0x3e,0xe0,0x00,0x00,0xaf,0xe0, //.@@.....%@@.
+0x0e,0xe5,0x00,0x03,0xef,0xe0, //.@@+....@@@.
+0x08,0xee,0x50,0x5c,0x8e,0xe0, //.+@@+.+%+@@.
+0x00,0x5c,0xff,0xe8,0xaf,0xc0, //..+%@@@+%@%.
+0x00,0x00,0x00,0x00,0xcf,0xa0, //........%@%.
+0x00,0x00,0x00,0x00,0xee,0x50, //........@@+.
+0x00,0x30,0x00,0x05,0xee,0x00, //.......+@@..
+0x05,0xee,0x30,0x0c,0xe8,0x00, //.+@@...%@+..
+0x05,0xee,0x33,0xcf,0xa0,0x00, //.+@@..%@%...
+0x00,0x5e,0xff,0xe5,0x00,0x00, //..+@@@@+....
+
+
+/* : */
+0x00,0x00,0xae,0xc0,0x00,0x00, //....%@%.....
+0x00,0x00,0xef,0xe3,0x00,0x00, //....@@@.....
+0x00,0x00,0xae,0xc0,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,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0xae,0xc0,0x00,0x00, //....%@%.....
+0x00,0x00,0xef,0xe3,0x00,0x00, //....@@@.....
+0x00,0x00,0xae,0xc0,0x00,0x00, //....%@%.....
+
+
+/* ; */
+0x00,0x00,0x8e,0xe3,0x00,0x00, //....+@@.....
+0x00,0x00,0x8c,0xc3,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,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x8c,0xc3,0x00,0x00, //....+%%.....
+0x00,0x00,0x8e,0xe3,0x00,0x00, //....+@@.....
+0x00,0x00,0x0c,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x5a,0x50,0x00,0x00, //....+%+.....
+
+
+/* < */
+0x00,0x00,0x00,0x00,0x5a,0x30, //........+%..
+0x00,0x00,0x00,0x05,0xa5,0x00, //.......+%+..
+0x00,0x00,0x00,0x5a,0x50,0x00, //......+%+...
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x5a,0x50,0x00,0x00, //....+%+.....
+0x00,0x05,0xa5,0x00,0x00,0x00, //...+%+......
+0x00,0x5a,0x50,0x00,0x00,0x00, //..+%+.......
+0x05,0xa5,0x00,0x00,0x00,0x00, //.+%+........
+0x05,0xa5,0x00,0x00,0x00,0x00, //.+%+........
+0x00,0x5a,0x50,0x00,0x00,0x00, //..+%+.......
+0x00,0x05,0xa5,0x00,0x00,0x00, //...+%+......
+0x00,0x00,0x5a,0x50,0x00,0x00, //....+%+.....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x00,0x5a,0x50,0x00, //......+%+...
+0x00,0x00,0x00,0x05,0xa5,0x00, //.......+%+..
+0x00,0x00,0x00,0x00,0x5a,0x30, //........+%..
+
+
+/* = */
+0xaf,0xff,0xff,0xff,0xff,0xe0, //%@@@@@@@@@@.
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0xaf,0xff,0xff,0xff,0xff,0xe0, //%@@@@@@@@@@.
+
+
+/* > */
+0x0a,0xc0,0x00,0x00,0x00,0x00, //.%%.........
+0x00,0xcc,0x00,0x00,0x00,0x00, //..%%........
+0x00,0x0c,0xc0,0x00,0x00,0x00, //...%%.......
+0x00,0x00,0xcc,0x00,0x00,0x00, //....%%......
+0x00,0x00,0x0c,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0x00,0xcc,0x00,0x00, //......%%....
+0x00,0x00,0x00,0x0c,0xc0,0x00, //.......%%...
+0x00,0x00,0x00,0x00,0xcc,0x00, //........%%..
+0x00,0x00,0x00,0x00,0xcc,0x00, //........%%..
+0x00,0x00,0x00,0x0c,0xc0,0x00, //.......%%...
+0x00,0x00,0x00,0xcc,0x00,0x00, //......%%....
+0x00,0x00,0x0c,0xc0,0x00,0x00, //.....%%.....
+0x00,0x00,0xcc,0x00,0x00,0x00, //....%%......
+0x00,0x0c,0xc0,0x00,0x00,0x00, //...%%.......
+0x00,0xcc,0x00,0x00,0x00,0x00, //..%%........
+0x0a,0xc0,0x00,0x00,0x00,0x00, //.%%.........
+
+
+/* ? */
+0x00,0x08,0xef,0xfe,0xa3,0x00, //...+@@@@%...
+0x00,0xcc,0x30,0x05,0xee,0x30, //..%%...+@@..
+0x0a,0xc0,0x00,0x00,0x8e,0xc0, //.%%.....+@%.
+0x0e,0xa0,0x00,0x00,0x5e,0xe0, //.@%.....+@@.
+0x0e,0xea,0x00,0x00,0x5e,0xe0, //.@@%....+@@.
+0x0c,0xfc,0x00,0x00,0xaf,0xa0, //.%@%....%@%.
+0x00,0x00,0x00,0x0a,0xca,0x00, //.......%%%..
+0x00,0x00,0x03,0xec,0x50,0x00, //......@%+...
+0x00,0x00,0x0c,0xa0,0x00,0x00, //.....%%.....
+0x00,0x00,0x0c,0x80,0x00,0x00, //.....%+.....
+0x00,0x00,0x0c,0x80,0x00,0x00, //.....%+.....
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x8e,0xc0,0x00,0x00, //....+@%.....
+0x00,0x00,0xcf,0xe5,0x00,0x00, //....%@@+....
+0x00,0x00,0x8e,0xc0,0x00,0x00, //....+@%.....
+
+
+/* @ */
+0x00,0x00,0xae,0xff,0xc3,0x00, //....%@@@%...
+0x00,0x3e,0xe5,0x03,0xac,0x50, //...@@+..%%+.
+0x00,0xcc,0x30,0x00,0x0a,0xc0, //..%%.....%%.
+0x08,0xc5,0x05,0xee,0xea,0xc8, //.+%+.+@@@%%+
+0x0c,0xe0,0x3e,0xc5,0xc8,0xca, //.%@..@%+%+%%
+0x3e,0xc0,0xce,0x05,0xa5,0xaa, //.@%.%@.+%+%%
+0x3e,0xa3,0xea,0x08,0xc3,0xac, //.@%.@%.+%.%%
+0x5e,0xa8,0xc5,0x0a,0xe0,0xaa, //+@%+%+.%@.%%
+0x5e,0xaa,0xe3,0x0c,0xe0,0xca, //+@%%@..%@.%%
+0x5e,0xac,0xe3,0x3e,0xc3,0xa5, //+@%%@..@%.%+
+0x3e,0xaa,0xe3,0xcf,0xaa,0xc0, //.@%%@.%@%%%.
+0x0c,0xe0,0xcf,0xca,0xec,0x30, //.%@.%@%%@%..
+0x08,0xc5,0x00,0x00,0x00,0xa8, //.+%+......%+
+0x00,0xec,0x00,0x00,0x0a,0xc0, //..@%.....%%.
+0x00,0x5e,0xc3,0x03,0xcc,0x30, //..+@%...%%..
+0x00,0x03,0xcf,0xfe,0xa3,0x00, //....%@@@%...
+
+
+/* A */
+0x00,0x00,0x08,0xa0,0x00,0x00, //.....+%.....
+0x00,0x00,0x5e,0xe5,0x00,0x00, //....+@@+....
+0x00,0x00,0xae,0xe8,0x00,0x00, //....%@@+....
+0x00,0x00,0xca,0xec,0x00,0x00, //....%%@%....
+0x00,0x03,0xa5,0xee,0x00,0x00, //....%+@@....
+0x00,0x08,0xc0,0xee,0x50,0x00, //...+%.@@+...
+0x00,0x0a,0xc0,0xae,0x80,0x00, //...%%.%@+...
+0x00,0x0c,0x80,0x5e,0xc0,0x00, //...%+.+@%...
+0x00,0x3a,0x50,0x3e,0xe0,0x00, //...%+..@@...
+0x00,0x8c,0x00,0x0c,0xe5,0x00, //..+%...%@+..
+0x00,0xcf,0xff,0xff,0xfa,0x00, //..%@@@@@@%..
+0x00,0xc8,0x00,0x08,0xec,0x00, //..%+...+@%..
+0x05,0xa3,0x00,0x03,0xee,0x30, //.+%.....@@..
+0x0a,0xc0,0x00,0x00,0xce,0x50, //.%%.....%@+.
+0x0e,0xc0,0x00,0x00,0xaf,0xa0, //.@%.....%@%.
+0xef,0xfc,0x00,0x0a,0xff,0xfc, //@@@%...%@@@%
+
+
+/* B */
+0xaf,0xff,0xff,0xfe,0xc5,0x00, //%@@@@@@@%+..
+0x05,0xec,0x00,0x08,0xee,0x50, //.+@%...+@@+.
+0x05,0xec,0x00,0x00,0x8e,0xa0, //.+@%....+@%.
+0x05,0xec,0x00,0x00,0x8e,0xa0, //.+@%....+@%.
+0x05,0xec,0x00,0x00,0xae,0x80, //.+@%....%@+.
+0x05,0xec,0x00,0x0a,0xca,0x00, //.+@%...%%%..
+0x05,0xef,0xff,0xfe,0x80,0x00, //.+@@@@@@+...
+0x05,0xec,0x00,0x05,0xec,0x30, //.+@%...+@%..
+0x05,0xec,0x00,0x00,0x5e,0xc0, //.+@%....+@%.
+0x05,0xec,0x00,0x00,0x0e,0xe5, //.+@%.....@@+
+0x05,0xec,0x00,0x00,0x0c,0xe8, //.+@%.....%@+
+0x05,0xec,0x00,0x00,0x0e,0xe5, //.+@%.....@@+
+0x05,0xec,0x00,0x00,0x5e,0xe3, //.+@%....+@@.
+0x05,0xec,0x00,0x05,0xee,0x80, //.+@%...+@@+.
+0xcf,0xff,0xff,0xfe,0xc5,0x00, //%@@@@@@@%+..
+
+
+/* C */
+0x00,0x03,0xae,0xff,0xea,0xa0, //....%@@@@%%.
+0x00,0x5e,0xe5,0x03,0xae,0xe0, //..+@@+..%@@.
+0x03,0xee,0x30,0x00,0x0a,0xe3, //..@@.....%@.
+0x0a,0xfa,0x00,0x00,0x03,0xa5, //.%@%......%+
+0x3e,0xe3,0x00,0x00,0x00,0x53, //.@@.......+.
+0x5e,0xe0,0x00,0x00,0x00,0x00, //+@@.........
+0x8e,0xc0,0x00,0x00,0x00,0x00, //+@%.........
+0x8e,0xc0,0x00,0x00,0x00,0x00, //+@%.........
+0x8e,0xc0,0x00,0x00,0x00,0x00, //+@%.........
+0x5e,0xe0,0x00,0x00,0x00,0x00, //+@@.........
+0x3e,0xe3,0x00,0x00,0x00,0x33, //.@@.........
+0x0e,0xe8,0x00,0x00,0x00,0x85, //.@@+......++
+0x08,0xec,0x00,0x00,0x0a,0xc0, //.+@%.....%%.
+0x00,0xaf,0xc3,0x03,0xac,0x30, //..%@%...%%..
+0x00,0x05,0xcf,0xfe,0xa3,0x00, //...+%@@@%...
+
+
+/* D */
+0xaf,0xff,0xff,0xea,0x30,0x00, //%@@@@@@%....
+0x05,0xec,0x00,0x5e,0xe8,0x00, //.+@%..+@@+..
+0x05,0xec,0x00,0x03,0xee,0x50, //.+@%....@@+.
+0x05,0xec,0x00,0x00,0x8e,0xc0, //.+@%....+@%.
+0x05,0xec,0x00,0x00,0x3e,0xe3, //.+@%.....@@.
+0x05,0xec,0x00,0x00,0x0e,0xe5, //.+@%.....@@+
+0x05,0xec,0x00,0x00,0x0e,0xe8, //.+@%.....@@+
+0x05,0xec,0x00,0x00,0x0c,0xe8, //.+@%.....%@+
+0x05,0xec,0x00,0x00,0x0e,0xe5, //.+@%.....@@+
+0x05,0xec,0x00,0x00,0x0e,0xe5, //.+@%.....@@+
+0x05,0xec,0x00,0x00,0x3e,0xe0, //.+@%.....@@.
+0x05,0xec,0x00,0x00,0x8e,0xc0, //.+@%....+@%.
+0x05,0xec,0x00,0x03,0xee,0x30, //.+@%....@@..
+0x05,0xec,0x00,0x8e,0xe5,0x00, //.+@%..+@@+..
+0xcf,0xff,0xff,0xea,0x30,0x00, //%@@@@@@%....
+
+
+/* E */
+0x8e,0xff,0xff,0xff,0xfe,0x80, //+@@@@@@@@@+.
+0x03,0xee,0x00,0x00,0xae,0xc0, //..@@....%@%.
+0x03,0xee,0x00,0x00,0x08,0xc0, //..@@.....+%.
+0x03,0xee,0x00,0x00,0x30,0x53, //..@@......+.
+0x03,0xee,0x00,0x03,0x80,0x00, //..@@....+...
+0x03,0xee,0x00,0x0a,0xe0,0x00, //..@@...%@...
+0x03,0xef,0xff,0xff,0xe0,0x00, //..@@@@@@@...
+0x03,0xee,0x00,0x0a,0xe0,0x00, //..@@...%@...
+0x03,0xee,0x00,0x05,0xa0,0x00, //..@@...+%...
+0x03,0xee,0x00,0x00,0x30,0x00, //..@@........
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0x03,0xee,0x00,0x00,0x00,0x88, //..@@......++
+0x03,0xee,0x00,0x00,0x05,0xa3, //..@@.....+%.
+0x03,0xee,0x00,0x00,0x8e,0xe0, //..@@....+@@.
+0x8e,0xff,0xff,0xff,0xff,0xa0, //+@@@@@@@@@%.
+
+
+/* F */
+0x8e,0xff,0xff,0xff,0xff,0xc0, //+@@@@@@@@@%.
+0x03,0xee,0x00,0x00,0x5e,0xe3, //..@@....+@@.
+0x03,0xee,0x00,0x00,0x03,0xc8, //..@@......%+
+0x03,0xee,0x00,0x00,0x00,0x88, //..@@......++
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0x03,0xee,0x00,0x00,0x85,0x00, //..@@....++..
+0x03,0xee,0x00,0x05,0xa5,0x00, //..@@...+%+..
+0x03,0xef,0xff,0xff,0xe5,0x00, //..@@@@@@@+..
+0x03,0xee,0x00,0x05,0xa5,0x00, //..@@...+%+..
+0x03,0xee,0x00,0x00,0xa5,0x00, //..@@....%+..
+0x03,0xee,0x00,0x00,0x53,0x00, //..@@....+...
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0xaf,0xff,0xe5,0x00,0x00,0x00, //%@@@@+......
+
+
+/* G */
+0x00,0x05,0xcf,0xfc,0x88,0x00, //...+%@@%++..
+0x00,0x8e,0xc3,0x08,0xee,0x00, //..+@%..+@@..
+0x05,0xee,0x00,0x00,0xae,0x30, //.+@@....%@..
+0x0c,0xe5,0x00,0x00,0x3a,0x50, //.%@+.....%+.
+0x3e,0xe0,0x00,0x00,0x05,0x30, //.@@......+..
+0x8e,0xc0,0x00,0x00,0x00,0x00, //+@%.........
+0xaf,0xa0,0x00,0x00,0x00,0x00, //%@%.........
+0xaf,0xa0,0x00,0x00,0x00,0x00, //%@%.........
+0xaf,0xa0,0x00,0x5a,0xaa,0xa8, //%@%...+%%%%+
+0x8e,0xc0,0x00,0x38,0xef,0xc5, //+@%....+@@%+
+0x5e,0xe0,0x00,0x00,0xce,0x50, //+@@.....%@+.
+0x0e,0xe5,0x00,0x00,0xce,0x50, //.@@+....%@+.
+0x08,0xec,0x00,0x00,0xce,0x50, //.+@%....%@+.
+0x00,0xcf,0xa0,0x05,0xee,0x50, //..%@%..+@@+.
+0x00,0x08,0xef,0xfe,0x80,0x00, //...+@@@@+...
+
+
+/* H */
+0xaf,0xff,0xa0,0x0c,0xff,0xfa, //%@@@%..%@@@%
+0x0a,0xfa,0x00,0x00,0xae,0x80, //.%@%....%@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0a,0xff,0xff,0xff,0xfe,0x80, //.%@@@@@@@@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0x0a,0xe8,0x00,0x00,0xae,0x80, //.%@+....%@+.
+0xcf,0xff,0xc0,0x0c,0xff,0xfc, //%@@@%..%@@@%
+
+
+/* I */
+0x00,0xcf,0xff,0xff,0xfe,0x00, //..%@@@@@@@..
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0xcf,0xff,0xff,0xfe,0x00, //..%@@@@@@@..
+
+
+/* J */
+0x00,0x08,0xef,0xff,0xff,0xfa, //...+@@@@@@@%
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x00,0x00,0x00,0x8e,0xa0,0x00, //......+@%...
+0x5e,0xe0,0x00,0xce,0x50,0x00, //+@@...%@+...
+0x8e,0xe0,0x08,0xec,0x00,0x00, //+@@..+@%....
+0x0a,0xef,0xfc,0x80,0x00,0x00, //.%@@@%+.....
+
+
+/* K */
+0xaf,0xff,0xe3,0x5e,0xff,0xe5, //%@@@@.+@@@@+
+0x05,0xec,0x00,0x03,0xec,0x30, //.+@%....@%..
+0x05,0xec,0x00,0x0c,0xc0,0x00, //.+@%...%%...
+0x05,0xec,0x00,0xcc,0x00,0x00, //.+@%..%%....
+0x05,0xec,0x0a,0xc3,0x00,0x00, //.+@%.%%.....
+0x05,0xec,0x8c,0x50,0x00,0x00, //.+@%+%+.....
+0x05,0xec,0xef,0xc0,0x00,0x00, //.+@%@@%.....
+0x05,0xef,0xae,0xe5,0x00,0x00, //.+@@%@@+....
+0x05,0xee,0x08,0xec,0x00,0x00, //.+@@.+@%....
+0x05,0xec,0x00,0xce,0x80,0x00, //.+@%..%@+...
+0x05,0xec,0x00,0x5e,0xe0,0x00, //.+@%..+@@...
+0x05,0xec,0x00,0x0c,0xe8,0x00, //.+@%...%@+..
+0x05,0xec,0x00,0x03,0xee,0x00, //.+@%....@@..
+0x05,0xec,0x00,0x00,0xcf,0xa0, //.+@%....%@%.
+0xaf,0xff,0xe3,0x0a,0xff,0xfc, //%@@@@..%@@@%
+
+
+/* L */
+0x5e,0xff,0xfa,0x00,0x00,0x00, //+@@@@%......
+0x00,0xee,0x30,0x00,0x00,0x00, //..@@........
+0x00,0xee,0x30,0x00,0x00,0x00, //..@@........
+0x00,0xee,0x30,0x00,0x00,0x00, //..@@........
+0x00,0xee,0x30,0x00,0x00,0x00, //..@@........
+0x00,0xee,0x30,0x00,0x00,0x00, //..@@........
+0x00,0xee,0x30,0x00,0x00,0x00, //..@@........
+0x00,0xee,0x30,0x00,0x00,0x00, //..@@........
+0x00,0xee,0x30,0x00,0x00,0x00, //..@@........
+0x00,0xee,0x30,0x00,0x00,0x00, //..@@........
+0x00,0xee,0x30,0x00,0x00,0x00, //..@@........
+0x00,0xee,0x30,0x00,0x00,0xa8, //..@@......%+
+0x00,0xee,0x30,0x00,0x05,0xa5, //..@@.....+%+
+0x00,0xee,0x30,0x00,0x5e,0xe0, //..@@....+@@.
+0x8e,0xff,0xff,0xff,0xff,0xc0, //+@@@@@@@@@%.
+
+
+/* M */
+0xef,0xe5,0x00,0x00,0xcf,0xfe, //@@@+....%@@@
+0x0c,0xfa,0x00,0x00,0xef,0xc0, //.%@%....@@%.
+0x0c,0xfc,0x00,0x05,0xef,0xc0, //.%@%...+@@%.
+0x0a,0xee,0x00,0x08,0xce,0xc0, //.%@@...+%@%.
+0x08,0xce,0x50,0x0c,0xce,0xc0, //.+%@+..%%@%.
+0x08,0xae,0x80,0x0c,0x8e,0xc0, //.+%@+..%+@%.
+0x08,0x6e,0xc0,0x5a,0x6e,0xc0, //.++@%.+%+@%.
+0x08,0x5e,0xe0,0x8c,0x5e,0xc0, //.++@@.+%+@%.
+0x08,0x5c,0xe3,0xaa,0x5e,0xc0, //.++%@.%%+@%.
+0x08,0x5a,0xe8,0xc8,0x5e,0xc0, //.++%@+%++@%.
+0x08,0x55,0xea,0x83,0x5e,0xc0, //.+++@%+.+@%.
+0x08,0x53,0xef,0xc0,0x5e,0xc0, //.++.@@%.+@%.
+0x08,0x50,0xcf,0xa0,0x5e,0xc0, //.++.%@%.+@%.
+0x0a,0x50,0xae,0x50,0x5e,0xc0, //.%+.%@+.+@%.
+0xef,0xe8,0x5a,0x0a,0xff,0xfe, //@@@++%.%@@@@
+
+
+/* N */
+0xcf,0xfa,0x00,0x03,0xef,0xfe, //%@@%....@@@@
+0x08,0xee,0x30,0x00,0x0a,0xa0, //.+@@.....%%.
+0x08,0xaf,0xc0,0x00,0x08,0x80, //.+%@%....++.
+0x08,0x8e,0xe5,0x00,0x08,0x80, //.++@@+...++.
+0x08,0x88,0xee,0x00,0x08,0x80, //.+++@@...++.
+0x08,0x80,0xee,0x80,0x08,0x80, //.++.@@+..++.
+0x08,0x80,0x5e,0xe0,0x08,0x80, //.++.+@@..++.
+0x08,0x80,0x0c,0xfa,0x08,0x80, //.++..%@%.++.
+0x08,0x80,0x05,0xee,0x38,0x80, //.++..+@@.++.
+0x08,0x80,0x00,0xaf,0xa8,0x80, //.++...%@%++.
+0x08,0x80,0x00,0x3e,0xe8,0x80, //.++....@@++.
+0x08,0x80,0x00,0x0a,0xfc,0x80, //.++....%@%+.
+0x08,0x80,0x00,0x00,0xee,0x80, //.++.....@@+.
+0x08,0xa0,0x00,0x00,0x8c,0x80, //.+%.....+%+.
+0xef,0xfe,0x30,0x00,0x0c,0x80, //@@@@.....%+.
+
+
+/* O */
+0x00,0x05,0xcf,0xfe,0x80,0x00, //...+%@@@+...
+0x00,0x8e,0xc3,0x08,0xea,0x00, //..+@%..+@%..
+0x05,0xee,0x00,0x00,0xae,0x80, //.+@@....%@+.
+0x0c,0xe8,0x00,0x00,0x3e,0xe0, //.%@+.....@@.
+0x3e,0xe3,0x00,0x00,0x0e,0xe5, //.@@......@@+
+0x5e,0xe0,0x00,0x00,0x0c,0xe8, //+@@......%@+
+0x5e,0xe0,0x00,0x00,0x0a,0xfa, //+@@......%@%
+0x8e,0xc0,0x00,0x00,0x0a,0xfa, //+@%......%@%
+0x5e,0xe0,0x00,0x00,0x0a,0xfa, //+@@......%@%
+0x5e,0xe0,0x00,0x00,0x0c,0xe8, //+@@......%@+
+0x0e,0xe3,0x00,0x00,0x0e,0xe5, //.@@......@@+
+0x0a,0xe8,0x00,0x00,0x3e,0xe0, //.%@+.....@@.
+0x03,0xee,0x00,0x00,0xae,0x80, //..@@....%@+.
+0x00,0x8e,0xc3,0x08,0xea,0x00, //..+@%..+@%..
+0x00,0x05,0xcf,0xfe,0x80,0x00, //...+%@@@+...
+
+
+/* P */
+0x8e,0xff,0xff,0xfe,0xc5,0x00, //+@@@@@@@%+..
+0x03,0xee,0x00,0x03,0xce,0x80, //..@@....%@+.
+0x03,0xee,0x00,0x00,0x0e,0xe3, //..@@.....@@.
+0x03,0xee,0x00,0x00,0x0c,0xe5, //..@@.....%@+
+0x03,0xee,0x00,0x00,0x0c,0xe5, //..@@.....%@+
+0x03,0xee,0x00,0x00,0x3e,0xe3, //..@@.....@@.
+0x03,0xee,0x00,0x05,0xce,0x80, //..@@...+%@+.
+0x03,0xef,0xff,0xff,0xc5,0x00, //..@@@@@@%+..
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0x03,0xee,0x00,0x00,0x00,0x00, //..@@........
+0xaf,0xff,0xe5,0x00,0x00,0x00, //%@@@@+......
+
+
+/* Q */
+0x00,0x08,0xef,0xfe,0x50,0x00, //...+@@@@+...
+0x00,0xaf,0xa0,0x0a,0xea,0x00, //..%@%..%@%..
+0x08,0xec,0x00,0x00,0xae,0x50, //.+@%....%@+.
+0x0c,0xe5,0x00,0x00,0x5e,0xc0, //.%@+....+@%.
+0x3e,0xe3,0x00,0x00,0x0e,0xe3, //.@@......@@.
+0x5e,0xe0,0x00,0x00,0x0e,0xe5, //+@@......@@+
+0x8e,0xc0,0x00,0x00,0x0c,0xe8, //+@%......%@+
+0x8e,0xc0,0x00,0x00,0x0c,0xe8, //+@%......%@+
+0x8e,0xc0,0x00,0x00,0x0c,0xe8, //+@%......%@+
+0x5e,0xc0,0x00,0x00,0x0c,0xe5, //+@%......%@+
+0x3e,0xe8,0xef,0xc0,0x0e,0xe5, //.@@+@@%..@@+
+0x0e,0xec,0x85,0xea,0x3e,0xe0, //.@@%++@%.@@.
+0x08,0xee,0x00,0xce,0x8c,0x80, //.+@@..%@+%+.
+0x00,0xaf,0xa0,0x8e,0xfc,0x00, //..%@%.+@@%..
+0x00,0x05,0xef,0xff,0xe0,0x30, //...+@@@@@...
+0x00,0x00,0x00,0x0e,0xea,0xa0, //.......@@%%.
+0x00,0x00,0x00,0x05,0xee,0x80, //.......+@@+.
+
+
+/* R */
+0x8e,0xff,0xff,0xfe,0xc3,0x00, //+@@@@@@@%...
+0x03,0xee,0x00,0x08,0xee,0x50, //..@@...+@@+.
+0x03,0xee,0x00,0x00,0x8e,0xc0, //..@@....+@%.
+0x03,0xee,0x00,0x00,0x5e,0xe0, //..@@....+@@.
+0x03,0xee,0x00,0x00,0x5e,0xc0, //..@@....+@%.
+0x03,0xee,0x00,0x00,0x8e,0xa0, //..@@....+@%.
+0x03,0xee,0x00,0x08,0xee,0x00, //..@@...+@@..
+0x03,0xef,0xff,0xfe,0xa0,0x00, //..@@@@@@%...
+0x03,0xee,0x05,0xec,0x00,0x00, //..@@.+@%....
+0x03,0xee,0x00,0xce,0x80,0x00, //..@@..%@+...
+0x03,0xee,0x00,0x5e,0xe0,0x00, //..@@..+@@...
+0x03,0xee,0x00,0x0c,0xe8,0x00, //..@@...%@+..
+0x03,0xee,0x00,0x08,0xee,0x00, //..@@...+@@..
+0x03,0xee,0x00,0x00,0xee,0x80, //..@@....@@+.
+0x8e,0xff,0xe5,0x00,0x8e,0xfc, //+@@@@+..+@@%
+
+
+/* S */
+0x00,0x3c,0xef,0xfc,0x8a,0x00, //...%@@@%+%..
+0x03,0xca,0x30,0x3c,0xfe,0x00, //..%%...%@@..
+0x0c,0xe0,0x00,0x00,0xae,0x30, //.%@.....%@..
+0x0e,0xc0,0x00,0x00,0x3a,0x50, //.@%......%+.
+0x0e,0xe0,0x00,0x00,0x00,0x00, //.@@.........
+0x0a,0xfe,0x50,0x00,0x00,0x00, //.%@@+.......
+0x00,0x8e,0xfe,0xa3,0x00,0x00, //..+@@@%.....
+0x00,0x00,0x8e,0xfe,0xa0,0x00, //....+@@@%...
+0x00,0x00,0x00,0x5c,0xfc,0x00, //......+%@%..
+0x00,0x00,0x00,0x00,0xce,0x80, //........%@+.
+0x5a,0x00,0x00,0x00,0x3e,0xc0, //+%.......@%.
+0x3c,0x80,0x00,0x00,0x0e,0xc0, //.%+......@%.
+0x0e,0xe3,0x00,0x00,0x5c,0x80, //.@@.....+%+.
+0x0c,0xfe,0x50,0x05,0xcc,0x00, //.%@@+..+%%..
+0x08,0xa8,0xef,0xfe,0xa0,0x00, //.+%+@@@@%...
+
+
+/* T */
+0x0c,0xff,0xff,0xff,0xff,0xa0, //.%@@@@@@@@%.
+0x0e,0xc3,0x3e,0xe0,0x3c,0xc0, //.@%..@@..%%.
+0x3a,0x50,0x3e,0xe0,0x05,0xa3, //.%+..@@..+%.
+0x58,0x00,0x3e,0xe0,0x00,0x83, //++...@@...+.
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x0c,0xff,0xff,0xa0,0x00, //...%@@@@%...
+
+
+/* U */
+0xcf,0xff,0xc0,0x03,0xef,0xfa, //%@@@%...@@@%
+0x0a,0xe8,0x00,0x00,0x0a,0x50, //.%@+.....%+.
+0x0a,0xe8,0x00,0x00,0x08,0x50, //.%@+.....++.
+0x0a,0xe8,0x00,0x00,0x08,0x50, //.%@+.....++.
+0x0a,0xe8,0x00,0x00,0x08,0x50, //.%@+.....++.
+0x0a,0xe8,0x00,0x00,0x08,0x50, //.%@+.....++.
+0x0a,0xe8,0x00,0x00,0x08,0x50, //.%@+.....++.
+0x0a,0xe8,0x00,0x00,0x08,0x50, //.%@+.....++.
+0x0a,0xe8,0x00,0x00,0x08,0x50, //.%@+.....++.
+0x0a,0xe8,0x00,0x00,0x08,0x50, //.%@+.....++.
+0x0a,0xe8,0x00,0x00,0x08,0x50, //.%@+.....++.
+0x0a,0xe8,0x00,0x00,0x08,0x50, //.%@+.....++.
+0x08,0xea,0x00,0x00,0x38,0x30, //.+@%.....+..
+0x00,0xee,0x80,0x05,0xca,0x00, //..@@+..+%%..
+0x00,0x3a,0xef,0xfc,0x50,0x00, //...%@@@%+...
+
+
+/* V */
+0xef,0xff,0xa0,0x05,0xef,0xfa, //@@@@%..+@@@%
+0x0a,0xfa,0x00,0x00,0x3a,0x50, //.%@%.....%+.
+0x05,0xec,0x00,0x00,0x5a,0x00, //.+@%....+%..
+0x03,0xee,0x00,0x00,0xaa,0x00, //..@@....%%..
+0x00,0xce,0x50,0x00,0xa5,0x00, //..%@+...%+..
+0x00,0x8e,0xa0,0x05,0xa3,0x00, //..+@%..+%...
+0x00,0x5e,0xc0,0x08,0xa0,0x00, //..+@%..+%...
+0x00,0x0e,0xe3,0x0a,0x80,0x00, //...@@..%+...
+0x00,0x0a,0xe8,0x38,0x30,0x00, //...%@+.+....
+0x00,0x08,0xea,0x8a,0x00,0x00, //...+@%+%....
+0x00,0x03,0xee,0xaa,0x00,0x00, //....@@%%....
+0x00,0x00,0xee,0xa5,0x00,0x00, //....@@%+....
+0x00,0x00,0xaf,0xe0,0x00,0x00, //....%@@.....
+0x00,0x00,0x5e,0xa0,0x00,0x00, //....+@%.....
+0x00,0x00,0x3a,0x50,0x00,0x00, //.....%+.....
+
+
+/* W */
+0xef,0xfc,0xcf,0xfe,0x5e,0xfe, //@@@%%@@@+@@@
+0x3e,0xc0,0x0c,0xe3,0x05,0xa3, //.@%..%@..+%.
+0x3e,0xc0,0x0c,0xe3,0x08,0xa0, //.@%..%@..+%.
+0x0c,0xe0,0x0a,0xe5,0x0a,0xa0, //.%@..%@+.%%.
+0x0a,0xe3,0x0c,0xe8,0x0a,0x80, //.%@..%@+.%+.
+0x08,0xc5,0x0e,0xfa,0x0a,0x50, //.+%+.@@%.%+.
+0x05,0xc8,0x3a,0xec,0x38,0x30, //.+%+.%@%.+..
+0x03,0xea,0x8a,0xee,0x58,0x00, //..@%+%@@++..
+0x00,0xec,0xaa,0xce,0x8a,0x00, //..@%%%%@+%..
+0x00,0xce,0xa8,0xae,0xa8,0x00, //..%@%+%@%+..
+0x00,0xae,0xa5,0x8c,0xc5,0x00, //..%@%++%%+..
+0x00,0x8e,0xe0,0x5e,0xe3,0x00, //..+@@.+@@...
+0x00,0x5e,0xc0,0x3e,0xe0,0x00, //..+@%..@@...
+0x00,0x3e,0xa0,0x0e,0xc0,0x00, //...@%..@%...
+0x00,0x0a,0x50,0x0a,0x80,0x00, //...%+..%+...
+
+
+/* X */
+0x8e,0xff,0xe0,0x0c,0xff,0xe5, //+@@@@..%@@@+
+0x03,0xee,0x00,0x00,0xae,0x30, //..@@....%@..
+0x00,0xae,0x80,0x00,0xa5,0x00, //..%@+...%+..
+0x00,0x3e,0xe0,0x0a,0xa0,0x00, //...@@..%%...
+0x00,0x0a,0xe8,0x38,0x30,0x00, //...%@+.+....
+0x00,0x03,0xee,0xaa,0x00,0x00, //....@@%%....
+0x00,0x00,0x8e,0xe3,0x00,0x00, //....+@@.....
+0x00,0x00,0x3e,0xe5,0x00,0x00, //.....@@+....
+0x00,0x00,0x8c,0xec,0x00,0x00, //....+%@%....
+0x00,0x00,0xc8,0xee,0x50,0x00, //....%+@@+...
+0x00,0x08,0xc0,0x8e,0xc0,0x00, //...+%.+@%...
+0x00,0x0a,0x50,0x0e,0xe5,0x00, //...%+..@@+..
+0x00,0x8c,0x00,0x05,0xec,0x00, //..+%...+@%..
+0x03,0xc8,0x00,0x00,0xce,0x80, //..%+....%@+.
+0xaf,0xfe,0x80,0x0c,0xff,0xfc, //%@@@+..%@@@%
+
+
+/* Y */
+0xaf,0xff,0xe0,0x0a,0xff,0xe8, //%@@@@..%@@@+
+0x08,0xec,0x00,0x00,0x8c,0x50, //.+@%....+%+.
+0x00,0xee,0x30,0x00,0xaa,0x00, //..@@....%%..
+0x00,0x8e,0xa0,0x05,0xa3,0x00, //..+@%..+%...
+0x00,0x3e,0xe0,0x0c,0xc0,0x00, //...@@..%%...
+0x00,0x0a,0xe8,0x5a,0x50,0x00, //...%@++%+...
+0x00,0x05,0xee,0xce,0x00,0x00, //...+@@%@....
+0x00,0x00,0xcf,0xe8,0x00,0x00, //....%@@+....
+0x00,0x00,0x8e,0xe3,0x00,0x00, //....+@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x3e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x0c,0xff,0xff,0xa0,0x00, //...%@@@@%...
+
+
+/* Z */
+0x03,0xef,0xff,0xff,0xff,0xe0, //..@@@@@@@@@.
+0x08,0xee,0x50,0x00,0x8c,0x80, //.+@@+...+%+.
+0x0c,0xe0,0x00,0x00,0xec,0x00, //.%@.....@%..
+0x05,0x30,0x00,0x0a,0xe3,0x00, //.+.....%@...
+0x00,0x00,0x00,0x3e,0xa0,0x00, //.......@%...
+0x00,0x00,0x00,0xce,0x00,0x00, //......%@....
+0x00,0x00,0x08,0xc8,0x00,0x00, //.....+%+....
+0x00,0x00,0x0e,0xc0,0x00,0x00, //.....@%.....
+0x00,0x00,0xae,0x30,0x00,0x00, //....%@......
+0x00,0x03,0xea,0x00,0x00,0x00, //....@%......
+0x00,0x0c,0xe0,0x00,0x00,0x00, //...%@.......
+0x00,0x8c,0x80,0x00,0x03,0x83, //..+%+.....+.
+0x00,0xec,0x00,0x00,0x0c,0xc0, //..@%.....%%.
+0x0a,0xe3,0x00,0x03,0xcf,0xa0, //.%@.....%@%.
+0x3e,0xff,0xff,0xff,0xfe,0x50, //.@@@@@@@@@+.
+
+
+/* [ */
+0x00,0x00,0xcf,0xff,0xfe,0x30, //....%@@@@@..
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xca,0x00,0x00,0x00, //....%%......
+0x00,0x00,0xcf,0xff,0xfe,0x30, //....%@@@@@..
+
+
+/* \ */
+0x08,0xc5,0x00,0x00,0x00,0x00, //.+%+........
+0x00,0xea,0x00,0x00,0x00,0x00, //..@%........
+0x00,0x8c,0x30,0x00,0x00,0x00, //..+%........
+0x00,0x3e,0xa0,0x00,0x00,0x00, //...@%.......
+0x00,0x0a,0xe0,0x00,0x00,0x00, //...%@.......
+0x00,0x05,0xc8,0x00,0x00,0x00, //...+%+......
+0x00,0x00,0xcc,0x00,0x00,0x00, //....%%......
+0x00,0x00,0x8c,0x50,0x00,0x00, //....+%+.....
+0x00,0x00,0x0e,0xa0,0x00,0x00, //.....@%.....
+0x00,0x00,0x0a,0xe3,0x00,0x00, //.....%@.....
+0x00,0x00,0x03,0xc8,0x00,0x00, //......%+....
+0x00,0x00,0x00,0xae,0x00,0x00, //......%@....
+0x00,0x00,0x00,0x5c,0x80,0x00, //......+%+...
+0x00,0x00,0x00,0x0c,0xc0,0x00, //.......%%...
+0x00,0x00,0x00,0x08,0xc5,0x00, //.......+%+..
+0x00,0x00,0x00,0x00,0xea,0x00, //........@%..
+0x00,0x00,0x00,0x00,0xae,0x30, //........%@..
+0x00,0x00,0x00,0x00,0x3c,0x80, //.........%+.
+0x00,0x00,0x00,0x00,0x0a,0xe0, //.........%@.
+
+
+/* ] */
+0x0c,0xff,0xff,0xe5,0x00,0x00, //.%@@@@@+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x00,0x00,0x05,0xa5,0x00,0x00, //.....+%+....
+0x0c,0xff,0xff,0xe5,0x00,0x00, //.%@@@@@+....
+
+
+/* ^ */
+0x00,0x00,0xef,0xe8,0x00,0x00, //....@@@+....
+0x00,0x0a,0xea,0xce,0x30,0x00, //...%@%%@....
+0x00,0x5a,0x30,0x08,0xa0,0x00, //..+%...+%...
+
+
+/* _ */
+0xef,0xff,0xff,0xff,0xff,0xfc, //@@@@@@@@@@@%
+
+
+/* ` */
+0x03,0xae,0xe5,0x00,0x00,0x00, //..%@@+......
+0x00,0x00,0x5a,0x80,0x00,0x00, //....+%+.....
+
+
+/* a */
+0x00,0x5c,0xef,0xfe,0xa0,0x00, //..+%@@@@%...
+0x08,0xec,0x30,0x08,0xea,0x00, //.+@%...+@%..
+0x0a,0xfa,0x00,0x00,0xec,0x00, //.%@%....@%..
+0x00,0x00,0x00,0x35,0xec,0x00, //.......+@%..
+0x00,0x3a,0xef,0xca,0xec,0x00, //...%@@%%@%..
+0x05,0xee,0x50,0x00,0xec,0x00, //.+@@+...@%..
+0x0e,0xe3,0x00,0x00,0xec,0x00, //.@@.....@%..
+0x5e,0xe0,0x00,0x00,0xec,0x00, //+@@.....@%..
+0x0e,0xe8,0x00,0x5a,0xec,0x88, //.@@+..+%@%++
+0x03,0xce,0xff,0xc5,0xae,0xe5, //..%@@@%+%@@+
+
+
+/* b */
+0x03,0x85,0x00,0x00,0x00,0x00, //..++........
+0xae,0xe8,0x00,0x00,0x00,0x00, //%@@+........
+0x05,0xc8,0x00,0x00,0x00,0x00, //.+%+........
+0x05,0xc8,0x00,0x00,0x00,0x00, //.+%+........
+0x05,0xc8,0x00,0x00,0x00,0x00, //.+%+........
+0x05,0xc8,0x00,0x00,0x00,0x00, //.+%+........
+0x05,0xc8,0x5e,0xff,0xc3,0x00, //.+%++@@@%...
+0x05,0xca,0xc3,0x05,0xee,0x30, //.+%%%..+@@..
+0x05,0xee,0x30,0x00,0x8e,0xa0, //.+@@....+@%.
+0x05,0xea,0x00,0x00,0x5e,0xc0, //.+@%....+@%.
+0x05,0xc8,0x00,0x00,0x3e,0xe0, //.+%+.....@@.
+0x05,0xc8,0x00,0x00,0x3e,0xe0, //.+%+.....@@.
+0x05,0xc8,0x00,0x00,0x5e,0xc0, //.+%+....+@%.
+0x05,0xea,0x00,0x00,0xae,0x80, //.+@%....%@+.
+0x05,0xcc,0x80,0x05,0xec,0x00, //.+%%+..+@%..
+0x05,0xa3,0xcf,0xfe,0xa0,0x00, //.+%.%@@@%...
+
+
+/* c */
+0x00,0x05,0xcf,0xfe,0xa3,0x00, //...+%@@@%...
+0x00,0x8e,0xc3,0x05,0xec,0x00, //..+@%..+@%..
+0x05,0xee,0x00,0x03,0xee,0x30, //.+@@....@@..
+0x0a,0xe8,0x00,0x00,0x33,0x00, //.%@+........
+0x0c,0xe5,0x00,0x00,0x00,0x00, //.%@+........
+0x0c,0xe5,0x00,0x00,0x00,0x00, //.%@+........
+0x0a,0xe8,0x00,0x00,0x00,0x30, //.%@+........
+0x05,0xec,0x00,0x00,0x0a,0x80, //.+@%.....%+.
+0x00,0xaf,0xc3,0x03,0xcc,0x00, //..%@%...%%..
+0x00,0x08,0xcf,0xfe,0xa3,0x00, //...+%@@@%...
+
+
+/* d */
+0x00,0x00,0x00,0x03,0x58,0x30, //........++..
+0x00,0x00,0x00,0x3c,0xfe,0x30, //.......%@@..
+0x00,0x00,0x00,0x00,0xae,0x30, //........%@..
+0x00,0x00,0x00,0x00,0xae,0x30, //........%@..
+0x00,0x00,0x00,0x00,0xae,0x30, //........%@..
+0x00,0x00,0x00,0x00,0xae,0x30, //........%@..
+0x00,0x08,0xef,0xfc,0xae,0x30, //...+@@@%%@..
+0x00,0xaf,0xa0,0x0a,0xee,0x30, //..%@%..%@@..
+0x05,0xec,0x00,0x00,0xae,0x30, //.+@%....%@..
+0x0a,0xe8,0x00,0x00,0xae,0x30, //.%@+....%@..
+0x0c,0xe5,0x00,0x00,0xae,0x30, //.%@+....%@..
+0x0c,0xe5,0x00,0x00,0xae,0x30, //.%@+....%@..
+0x0a,0xe5,0x00,0x00,0xae,0x30, //.%@+....%@..
+0x08,0xea,0x00,0x00,0xee,0x30, //.+@%....@@..
+0x00,0xce,0x80,0x3a,0xaf,0xc5, //..%@+..%%@%+
+0x00,0x0a,0xef,0xea,0xac,0x83, //...%@@@%%%+.
+
+
+/* e */
+0x00,0x05,0xcf,0xfe,0xa0,0x00, //...+%@@@%...
+0x00,0x8c,0xa0,0x05,0xec,0x00, //..+%%..+@%..
+0x03,0xea,0x00,0x00,0x8c,0x80, //..@%....+%+.
+0x0a,0xe5,0x00,0x00,0x5e,0xc0, //.%@+....+@%.
+0x0c,0xff,0xff,0xff,0xff,0xc0, //.%@@@@@@@@%.
+0x0c,0xe5,0x00,0x00,0x00,0x00, //.%@+........
+0x0a,0xe8,0x00,0x00,0x00,0x00, //.%@+........
+0x05,0xec,0x00,0x00,0x0a,0x80, //.+@%.....%+.
+0x00,0xae,0xc3,0x03,0xcc,0x00, //..%@%...%%..
+0x00,0x05,0xcf,0xfe,0xa0,0x00, //...+%@@@%...
+
+
+/* f */
+0x00,0x00,0x05,0xcf,0xfe,0xa0, //.....+%@@@%.
+0x00,0x00,0x8c,0xa0,0x0a,0xfa, //....+%%..%@%
+0x00,0x00,0xee,0x00,0x05,0x85, //....@@...+++
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x0c,0xff,0xff,0xff,0xfc,0x00, //.%@@@@@@@%..
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x05,0xef,0xff,0xff,0xc0,0x00, //.+@@@@@@%...
+
+
+/* g */
+0x00,0x0a,0xef,0xfc,0x8e,0xe8, //...%@@@%+@@+
+0x00,0xce,0x50,0x3c,0xe8,0x85, //..%@+..%@+++
+0x05,0xea,0x00,0x03,0xec,0x00, //.+@%....@%..
+0x05,0xea,0x00,0x03,0xec,0x00, //.+@%....@%..
+0x00,0xce,0x50,0x0a,0xe5,0x00, //..%@+..%@+..
+0x00,0x5c,0xef,0xfc,0x50,0x00, //..+%@@@%+...
+0x03,0xc8,0x00,0x00,0x00,0x00, //..%+........
+0x03,0xee,0xa6,0x33,0x00,0x00, //..@@%+......
+0x00,0x8c,0xcc,0xef,0xfc,0x30, //..+%%%@@@%..
+0x0a,0xc0,0x00,0x00,0x3e,0xc0, //.%%......@%.
+0x0e,0xc0,0x00,0x00,0x0e,0xc0, //.@%......@%.
+0x0a,0xea,0x30,0x03,0xac,0x80, //.%@%....%%+.
+0x00,0x5c,0xff,0xfe,0xc5,0x00, //..+%@@@@%+..
+
+
+/* h */
+0x03,0xaa,0x00,0x00,0x00,0x00, //..%%........
+0xae,0xfa,0x00,0x00,0x00,0x00, //%@@%........
+0x03,0xea,0x00,0x00,0x00,0x00, //..@%........
+0x03,0xea,0x00,0x00,0x00,0x00, //..@%........
+0x03,0xea,0x00,0x00,0x00,0x00, //..@%........
+0x03,0xea,0x00,0x00,0x00,0x00, //..@%........
+0x03,0xea,0x5e,0xff,0xc3,0x00, //..@%+@@@%...
+0x03,0xea,0xc5,0x03,0xee,0x00, //..@%%+..@@..
+0x03,0xee,0x00,0x00,0xae,0x30, //..@@....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x8e,0xff,0xe0,0x0e,0xff,0xe8, //+@@@@..@@@@+
+
+
+/* i */
+0x00,0x00,0x3e,0xe5,0x00,0x00, //.....@@+....
+0x00,0x00,0x3e,0xe5,0x00,0x00, //.....@@+....
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x03,0x50,0x00,0x00, //......+.....
+0x00,0xaf,0xef,0xe0,0x00,0x00, //..%@@@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0xaf,0xff,0xff,0xfa,0x00, //..%@@@@@@%..
+
+
+/* j */
+0x00,0x00,0x00,0x0c,0xfc,0x00, //.......%@%..
+0x00,0x00,0x00,0x0c,0xfc,0x00, //.......%@%..
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x00,0x00,0x00,0x00, //............
+0x00,0x00,0x00,0x03,0x55,0x00, //........++..
+0x00,0x00,0x0e,0xee,0xe8,0x00, //.....@@@@+..
+0x00,0x00,0x00,0x05,0xc8,0x00, //.......+%+..
+0x00,0x00,0x00,0x05,0xc8,0x00, //.......+%+..
+0x00,0x00,0x00,0x05,0xc8,0x00, //.......+%+..
+0x00,0x00,0x00,0x05,0xc8,0x00, //.......+%+..
+0x00,0x00,0x00,0x05,0xc8,0x00, //.......+%+..
+0x00,0x00,0x00,0x05,0xc8,0x00, //.......+%+..
+0x00,0x00,0x00,0x05,0xc8,0x00, //.......+%+..
+0x00,0x00,0x00,0x05,0xc8,0x00, //.......+%+..
+0x00,0x00,0x00,0x05,0xc8,0x00, //.......+%+..
+0x00,0x30,0x00,0x08,0xc5,0x00, //.......+%+..
+0x05,0xee,0x30,0x5c,0xa0,0x00, //.+@@..+%%...
+0x00,0xae,0xff,0xc5,0x00,0x00, //..%@@@%+....
+
+
+/* k */
+0x03,0xaa,0x00,0x00,0x00,0x00, //..%%........
+0x8e,0xfc,0x00,0x00,0x00,0x00, //+@@%........
+0x03,0xec,0x00,0x00,0x00,0x00, //..@%........
+0x03,0xec,0x00,0x00,0x00,0x00, //..@%........
+0x03,0xec,0x00,0x00,0x00,0x00, //..@%........
+0x03,0xec,0x00,0x00,0x00,0x00, //..@%........
+0x03,0xec,0x00,0xcf,0xff,0xc0, //..@%..%@@@%.
+0x03,0xec,0x00,0x0c,0xc3,0x00, //..@%...%%...
+0x03,0xec,0x00,0xcc,0x00,0x00, //..@%..%%....
+0x03,0xec,0x0c,0xc0,0x00,0x00, //..@%.%%.....
+0x03,0xec,0xcf,0xe3,0x00,0x00, //..@%%@@.....
+0x03,0xee,0x88,0xee,0x00,0x00, //..@@++@@....
+0x03,0xec,0x00,0xaf,0xa0,0x00, //..@%..%@%...
+0x03,0xec,0x00,0x0c,0xe8,0x00, //..@%...%@+..
+0x03,0xec,0x00,0x03,0xee,0x30, //..@%....@@..
+0x5e,0xff,0xe0,0x0e,0xff,0xfa, //+@@@@..@@@@%
+
+
+/* l */
+0x00,0x03,0x5c,0xc0,0x00,0x00, //....+%%.....
+0x00,0xac,0xcf,0xe0,0x00,0x00, //..%%%@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0x00,0x0e,0xe0,0x00,0x00, //.....@@.....
+0x00,0xcf,0xff,0xff,0xfc,0x00, //..%@@@@@@%..
+
+
+/* m */
+0x03,0x30,0x00,0x00,0x00,0x00, //............
+0xcf,0xcc,0xfe,0x8a,0xef,0xc0, //%@%%@@+%@@%.
+0x0e,0xe8,0x0e,0xea,0x0a,0xe5, //.@@+.@@%.%@+
+0x0e,0xc0,0x0c,0xe3,0x0a,0xe5, //.@%..%@..%@+
+0x0e,0xc0,0x0c,0xe3,0x0a,0xe5, //.@%..%@..%@+
+0x0e,0xc0,0x0c,0xe3,0x0a,0xe5, //.@%..%@..%@+
+0x0e,0xc0,0x0c,0xe3,0x0a,0xe5, //.@%..%@..%@+
+0x0e,0xc0,0x0c,0xe3,0x0a,0xe5, //.@%..%@..%@+
+0x0e,0xc0,0x0c,0xe3,0x0a,0xe5, //.@%..%@..%@+
+0x0e,0xc0,0x0c,0xe3,0x0a,0xe5, //.@%..%@..%@+
+0xef,0xfc,0xcf,0xfe,0x8e,0xfe, //@@@%%@@@+@@@
+
+
+/* n */
+0x3a,0xca,0x5c,0xff,0xc3,0x00, //.%%%+%@@%...
+0x38,0xea,0xc5,0x03,0xee,0x00, //.+@%%+..@@..
+0x03,0xee,0x30,0x00,0xae,0x30, //..@@....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x03,0xea,0x00,0x00,0xae,0x30, //..@%....%@..
+0x8e,0xff,0xe0,0x0e,0xff,0xe8, //+@@@@..@@@@+
+
+
+/* o */
+0x00,0x08,0xef,0xfe,0x80,0x00, //...+@@@@+...
+0x00,0xce,0xa0,0x0a,0xec,0x00, //..%@%..%@%..
+0x08,0xea,0x00,0x00,0xae,0x80, //.+@%....%@+.
+0x0e,0xe3,0x00,0x00,0x3e,0xe0, //.@@......@@.
+0x3e,0xe0,0x00,0x00,0x0e,0xe3, //.@@......@@.
+0x3e,0xe0,0x00,0x00,0x0e,0xe3, //.@@......@@.
+0x0e,0xe3,0x00,0x00,0x3e,0xe0, //.@@......@@.
+0x08,0xc8,0x00,0x00,0x8e,0xa0, //.+%+....+@%.
+0x00,0xce,0x80,0x08,0xec,0x00, //..%@+..+@%..
+0x00,0x08,0xef,0xfe,0x80,0x00, //...+@@@@+...
+
+
+/* p */
+0x8a,0xca,0x8e,0xfe,0xc3,0x00, //+%%%+@@@%...
+0x3a,0xea,0xc5,0x05,0xee,0x50, //.%@%%+.+@@+.
+0x03,0xee,0x00,0x00,0x5e,0xc0, //..@@....+@%.
+0x03,0xea,0x00,0x00,0x0e,0xe0, //..@%.....@@.
+0x03,0xea,0x00,0x00,0x0e,0xe3, //..@%.....@@.
+0x03,0xea,0x00,0x00,0x0e,0xe3, //..@%.....@@.
+0x03,0xea,0x00,0x00,0x3e,0xe0, //..@%.....@@.
+0x03,0xec,0x00,0x00,0x8e,0xa0, //..@%....+@%.
+0x03,0xec,0xa0,0x08,0xee,0x00, //..@%%..+@@..
+0x03,0xea,0xae,0xfe,0xa0,0x00, //..@%%@@@%...
+0x03,0xea,0x00,0x00,0x00,0x00, //..@%........
+0x03,0xea,0x00,0x00,0x00,0x00, //..@%........
+0xaf,0xff,0xe3,0x00,0x00,0x00, //%@@@@.......
+
+
+/* q */
+0x00,0x08,0xef,0xea,0x38,0x30, //...+@@@%.+..
+0x00,0xce,0xa0,0x0a,0xce,0x30, //..%@%..%%@..
+0x08,0xea,0x00,0x00,0xce,0x30, //.+@%....%@..
+0x0c,0xe5,0x00,0x00,0xce,0x30, //.%@+....%@..
+0x0e,0xe3,0x00,0x00,0xce,0x30, //.@@.....%@..
+0x0e,0xe3,0x00,0x00,0xce,0x30, //.@@.....%@..
+0x0e,0xe3,0x00,0x00,0xce,0x30, //.@@.....%@..
+0x0a,0xe8,0x00,0x00,0xce,0x30, //.%@+....%@..
+0x00,0xee,0x50,0x3a,0xee,0x30, //..@@+..%@@..
+0x00,0x3a,0xef,0xea,0xce,0x30, //...%@@@%%@..
+0x00,0x00,0x00,0x00,0xce,0x30, //........%@..
+0x00,0x00,0x00,0x00,0xce,0x30, //........%@..
+0x00,0x00,0x00,0x5e,0xff,0xe8, //......+@@@@+
+
+
+/* r */
+0x3a,0xac,0xe0,0x3c,0xff,0xc0, //.%%%@..%@@%.
+0x35,0x6e,0xe5,0xa8,0x3e,0xe3, //.++@@+%+.@@.
+0x00,0x0c,0xe8,0x30,0x03,0x30, //...%@+......
+0x00,0x0c,0xe5,0x00,0x00,0x00, //...%@+......
+0x00,0x0c,0xe0,0x00,0x00,0x00, //...%@.......
+0x00,0x0c,0xe0,0x00,0x00,0x00, //...%@.......
+0x00,0x0c,0xe0,0x00,0x00,0x00, //...%@.......
+0x00,0x0c,0xe0,0x00,0x00,0x00, //...%@.......
+0x00,0x0c,0xe0,0x00,0x00,0x00, //...%@.......
+0x8e,0xff,0xff,0xfc,0x00,0x00, //+@@@@@@%....
+
+
+/* s */
+0x00,0x0a,0xef,0xfe,0xac,0x00, //...%@@@@%%..
+0x00,0xce,0x50,0x08,0xee,0x00, //..%@+..+@@..
+0x00,0xea,0x00,0x00,0x8c,0x30, //..@%....+%..
+0x00,0xce,0x50,0x00,0x05,0x30, //..%@+....+..
+0x00,0x3a,0xee,0xc5,0x00,0x00, //...%@@%+....
+0x00,0x00,0x05,0xce,0xe8,0x00, //.....+%@@+..
+0x08,0xa0,0x00,0x00,0xae,0x50, //.+%.....%@+.
+0x05,0xa5,0x00,0x00,0x3c,0x80, //.+%+.....%+.
+0x05,0xee,0x50,0x03,0xae,0x30, //.+@@+...%@..
+0x03,0xca,0xef,0xff,0xc5,0x00, //..%%@@@@%+..
+
+
+/* t */
+0x00,0x00,0x58,0x00,0x00,0x00, //....++......
+0x00,0x00,0x8a,0x00,0x00,0x00, //....+%......
+0x00,0x00,0xcc,0x00,0x00,0x00, //....%%......
+0x00,0x08,0xec,0x00,0x00,0x00, //...+@%......
+0x0a,0xff,0xff,0xff,0xfc,0x00, //.%@@@@@@@%..
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x00,0xee,0x00,0x08,0x80, //....@@...++.
+0x00,0x00,0xae,0x50,0x5a,0x30, //....%@+.+%..
+0x00,0x00,0x0c,0xff,0xe5,0x00, //.....%@@@+..
+
+
+/* u */
+0x00,0x88,0x00,0x00,0x38,0x30, //..++.....+..
+0xaf,0xe8,0x00,0x3e,0xfe,0x30, //%@@+...@@@..
+0x05,0xc8,0x00,0x00,0xce,0x30, //.+%+....%@..
+0x05,0xc8,0x00,0x00,0xce,0x30, //.+%+....%@..
+0x05,0xc8,0x00,0x00,0xce,0x30, //.+%+....%@..
+0x05,0xc8,0x00,0x00,0xce,0x30, //.+%+....%@..
+0x05,0xc8,0x00,0x00,0xce,0x30, //.+%+....%@..
+0x05,0xc8,0x00,0x00,0xce,0x30, //.+%+....%@..
+0x05,0xea,0x00,0x00,0xee,0x30, //.+@%....@@..
+0x00,0xee,0x50,0x3c,0xcf,0xc5, //..@@+..%%@%+
+0x00,0x5e,0xff,0xe8,0xcc,0x83, //..+@@@@+%%+.
+
+
+/* v */
+0x8e,0xff,0xe0,0x08,0xef,0xe5, //+@@@@..+@@@+
+0x03,0xee,0x00,0x00,0x8c,0x30, //..@@....+%..
+0x00,0xce,0x30,0x00,0xa8,0x00, //..%@....%+..
+0x00,0x5e,0xa0,0x05,0xa3,0x00, //..+@%..+%...
+0x00,0x0e,0xe3,0x0c,0xa0,0x00, //...@@..%%...
+0x00,0x0a,0xfa,0x5a,0x50,0x00, //...%@%+%+...
+0x00,0x03,0xee,0xac,0x00,0x00, //....@@%%....
+0x00,0x00,0xcf,0xe8,0x00,0x00, //....%@@+....
+0x00,0x00,0x5e,0xe0,0x00,0x00, //....+@@.....
+0x00,0x00,0x0e,0xa0,0x00,0x00, //.....@%.....
+
+
+/* w */
+0xef,0xfa,0xef,0xfa,0x8e,0xfe, //@@@%@@@%+@@@
+0x3e,0xc0,0x0e,0xe0,0x08,0xc3, //.@%..@@..+%.
+0x0c,0xe0,0x0c,0xe3,0x0a,0xa0, //.%@..%@..%%.
+0x0a,0xe5,0x0e,0xe8,0x0a,0x50, //.%@+.@@+.%+.
+0x05,0xc8,0x5a,0xec,0x5a,0x00, //.+%++%@%+%..
+0x00,0xec,0xac,0xee,0xcc,0x00, //..@%%%@@%%..
+0x00,0xce,0xc8,0xae,0xc8,0x00, //..%@%+%@%+..
+0x00,0x8e,0xe3,0x8e,0xe3,0x00, //..+@@.+@@...
+0x00,0x3e,0xc0,0x3e,0xc0,0x00, //...@%..@%...
+0x00,0x0c,0x80,0x0c,0xa0,0x00, //...%+..%%...
+
+
+/* x */
+0x0e,0xff,0xfc,0x5e,0xff,0xe0, //.@@@@%+@@@@.
+0x00,0x5e,0xe0,0x03,0xa5,0x00, //..+@@...%+..
+0x00,0x0a,0xe8,0x0a,0xa0,0x00, //...%@+.%%...
+0x00,0x00,0xce,0xaa,0x00,0x00, //....%@%%....
+0x00,0x00,0x3e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0x3c,0xea,0x00,0x00, //.....%@%....
+0x00,0x00,0xa5,0xae,0x80,0x00, //....%+%@+...
+0x00,0x0a,0x80,0x0e,0xe3,0x00, //...%+..@@...
+0x00,0xac,0x00,0x05,0xec,0x30, //..%%...+@%..
+0x8e,0xff,0xc0,0x8e,0xff,0xe5, //+@@@%.+@@@@+
+
+
+/* y */
+0x5e,0xff,0xe5,0x3e,0xff,0xe8, //+@@@@+.@@@@+
+0x00,0xce,0x50,0x00,0xcc,0x30, //..%@+...%%..
+0x00,0x5c,0x80,0x03,0xa5,0x00, //..+%+...%+..
+0x00,0x0e,0xe0,0x08,0xc0,0x00, //...@@..+%...
+0x00,0x08,0xc5,0x0c,0xa0,0x00, //...+%+.%%...
+0x00,0x03,0xec,0x5a,0x50,0x00, //....@%+%+...
+0x00,0x00,0xae,0xac,0x00,0x00, //....%@%%....
+0x00,0x00,0x5e,0xe8,0x00,0x00, //....+@@+....
+0x00,0x00,0x0c,0xe3,0x00,0x00, //.....%@.....
+0x00,0x00,0x0a,0xa0,0x00,0x00, //.....%%.....
+0x00,0x00,0x3a,0x50,0x00,0x00, //.....%+.....
+0x03,0x85,0xaa,0x00,0x00,0x00, //..++%%......
+0x08,0xef,0xc0,0x00,0x00,0x00, //.+@@%.......
+
+
+/* z */
+0x05,0xef,0xff,0xff,0xfe,0x30, //.+@@@@@@@@..
+0x08,0xea,0x00,0x08,0xea,0x00, //.+@%...+@%..
+0x08,0xc0,0x00,0x5e,0xc0,0x00, //.+%...+@%...
+0x08,0x80,0x03,0xee,0x00,0x00, //.++...@@....
+0x00,0x00,0x0e,0xe3,0x00,0x00, //.....@@.....
+0x00,0x00,0xce,0x50,0x00,0x00, //....%@+.....
+0x00,0x0a,0xe8,0x00,0x0a,0xa0, //...%@+...%%.
+0x00,0x8e,0xa0,0x00,0x0c,0x80, //..+@%....%+.
+0x05,0xec,0x00,0x03,0xce,0x50, //.+@%....%@+.
+0x0c,0xff,0xff,0xff,0xfe,0x30, //.%@@@@@@@@..
+
+
+/* { */
+0x00,0x00,0x00,0x03,0xce,0x80, //........%@+.
+0x00,0x00,0x00,0x0c,0xc3,0x00, //.......%%...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x5a,0x30,0x00, //......+%....
+0x00,0x00,0x03,0xcc,0x00,0x00, //......%%....
+0x00,0x00,0x3c,0xa0,0x00,0x00, //.....%%.....
+0x00,0x00,0x00,0xcc,0x00,0x00, //......%%....
+0x00,0x00,0x00,0x5a,0x30,0x00, //......+%....
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x3a,0x50,0x00, //.......%+...
+0x00,0x00,0x00,0x0e,0xc3,0x00, //.......@%...
+0x00,0x00,0x00,0x05,0xce,0x80, //.......+%@+.
+
+
+/* | */
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+0x00,0x00,0x08,0x80,0x00,0x00, //.....++.....
+
+
+/* } */
+0x08,0xec,0x30,0x00,0x00,0x00, //.+@%........
+0x00,0x0c,0xc0,0x00,0x00,0x00, //...%%.......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x03,0xa5,0x00,0x00,0x00, //....%+......
+0x00,0x00,0x8a,0x30,0x00,0x00, //....+%......
+0x00,0x00,0x5e,0xe3,0x00,0x00, //....+@@.....
+0x00,0x03,0xec,0x00,0x00,0x00, //....@%......
+0x00,0x05,0xa5,0x00,0x00,0x00, //...+%+......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x05,0xa3,0x00,0x00,0x00, //...+%.......
+0x00,0x0c,0xe0,0x00,0x00,0x00, //...%@.......
+0x08,0xec,0x50,0x00,0x00,0x00, //.+@%+.......
+
+
+/* ~ */
+0x03,0xcf,0xea,0x00,0x00,0x00, //..%@@%......
+0x0a,0x80,0xcf,0xc0,0x00,0x88, //.%+.%@%...++
+0x58,0x00,0x08,0xec,0x35,0xa0, //++...+@%.+%.
+0x00,0x00,0x00,0x5e,0xfe,0x50, //......+@@@+.
+
+
+/* */
+
+};
+
+
+static const sgl_font_table_t sgl_ascii_song23_tab[] = {
+ {.bitmap_index = 0, .adv_w = 192, .box_h = 0, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*( )*/
+ {.bitmap_index = 0, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(!)*/
+ {.bitmap_index = 96, .adv_w = 192, .box_h = 6, .box_w = 12, .ofs_x = 0, .ofs_y = 15 },/*(")*/
+ {.bitmap_index = 132, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(#)*/
+ {.bitmap_index = 228, .adv_w = 192, .box_h = 21, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*($)*/
+ {.bitmap_index = 354, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(%)*/
+ {.bitmap_index = 450, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(&)*/
+ {.bitmap_index = 546, .adv_w = 192, .box_h = 6, .box_w = 12, .ofs_x = 0, .ofs_y = 15 },/*(')*/
+ {.bitmap_index = 582, .adv_w = 192, .box_h = 21, .box_w = 12, .ofs_x = 0, .ofs_y = 1 },/*(()*/
+ {.bitmap_index = 708, .adv_w = 192, .box_h = 21, .box_w = 12, .ofs_x = 0, .ofs_y = 1 },/*())*/
+ {.bitmap_index = 834, .adv_w = 192, .box_h = 12, .box_w = 12, .ofs_x = 0, .ofs_y = 5 },/*(*)*/
+ {.bitmap_index = 906, .adv_w = 192, .box_h = 11, .box_w = 12, .ofs_x = 0, .ofs_y = 6 },/*(+)*/
+ {.bitmap_index = 972, .adv_w = 192, .box_h = 6, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*(,)*/
+ {.bitmap_index = 1008, .adv_w = 192, .box_h = 1, .box_w = 12, .ofs_x = 0, .ofs_y = 11 },/*(-)*/
+ {.bitmap_index = 1014, .adv_w = 192, .box_h = 3, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(.)*/
+ {.bitmap_index = 1032, .adv_w = 192, .box_h = 20, .box_w = 12, .ofs_x = 0, .ofs_y = 1 },/*(/)*/
+ {.bitmap_index = 1152, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(0)*/
+ {.bitmap_index = 1248, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(1)*/
+ {.bitmap_index = 1344, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(2)*/
+ {.bitmap_index = 1440, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(3)*/
+ {.bitmap_index = 1536, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(4)*/
+ {.bitmap_index = 1632, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(5)*/
+ {.bitmap_index = 1728, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(6)*/
+ {.bitmap_index = 1824, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(7)*/
+ {.bitmap_index = 1920, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(8)*/
+ {.bitmap_index = 2016, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(9)*/
+ {.bitmap_index = 2112, .adv_w = 192, .box_h = 11, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(:)*/
+ {.bitmap_index = 2178, .adv_w = 192, .box_h = 12, .box_w = 12, .ofs_x = 0, .ofs_y = 1 },/*(;)*/
+ {.bitmap_index = 2250, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(<)*/
+ {.bitmap_index = 2346, .adv_w = 192, .box_h = 5, .box_w = 12, .ofs_x = 0, .ofs_y = 9 },/*(=)*/
+ {.bitmap_index = 2376, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(>)*/
+ {.bitmap_index = 2472, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(?)*/
+ {.bitmap_index = 2568, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(@)*/
+ {.bitmap_index = 2664, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(A)*/
+ {.bitmap_index = 2760, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(B)*/
+ {.bitmap_index = 2850, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(C)*/
+ {.bitmap_index = 2940, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(D)*/
+ {.bitmap_index = 3030, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(E)*/
+ {.bitmap_index = 3120, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(F)*/
+ {.bitmap_index = 3210, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(G)*/
+ {.bitmap_index = 3300, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(H)*/
+ {.bitmap_index = 3390, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(I)*/
+ {.bitmap_index = 3480, .adv_w = 192, .box_h = 18, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*(J)*/
+ {.bitmap_index = 3588, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(K)*/
+ {.bitmap_index = 3678, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(L)*/
+ {.bitmap_index = 3768, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(M)*/
+ {.bitmap_index = 3858, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(N)*/
+ {.bitmap_index = 3948, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(O)*/
+ {.bitmap_index = 4038, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(P)*/
+ {.bitmap_index = 4128, .adv_w = 192, .box_h = 17, .box_w = 12, .ofs_x = 0, .ofs_y = 1 },/*(Q)*/
+ {.bitmap_index = 4230, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(R)*/
+ {.bitmap_index = 4320, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(S)*/
+ {.bitmap_index = 4410, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(T)*/
+ {.bitmap_index = 4500, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(U)*/
+ {.bitmap_index = 4590, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(V)*/
+ {.bitmap_index = 4680, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(W)*/
+ {.bitmap_index = 4770, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(X)*/
+ {.bitmap_index = 4860, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(Y)*/
+ {.bitmap_index = 4950, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(Z)*/
+ {.bitmap_index = 5040, .adv_w = 192, .box_h = 20, .box_w = 12, .ofs_x = 0, .ofs_y = 1 },/*([)*/
+ {.bitmap_index = 5160, .adv_w = 192, .box_h = 19, .box_w = 12, .ofs_x = 0, .ofs_y = 1 },/*(\)*/
+ {.bitmap_index = 5274, .adv_w = 192, .box_h = 20, .box_w = 12, .ofs_x = 0, .ofs_y = 1 },/*(])*/
+ {.bitmap_index = 5394, .adv_w = 192, .box_h = 3, .box_w = 12, .ofs_x = 0, .ofs_y = 19 },/*(^)*/
+ {.bitmap_index = 5412, .adv_w = 192, .box_h = 1, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*(_)*/
+ {.bitmap_index = 5418, .adv_w = 192, .box_h = 2, .box_w = 12, .ofs_x = 0, .ofs_y = 19 },/*(`)*/
+ {.bitmap_index = 5430, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(a)*/
+ {.bitmap_index = 5490, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(b)*/
+ {.bitmap_index = 5586, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(c)*/
+ {.bitmap_index = 5646, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(d)*/
+ {.bitmap_index = 5742, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(e)*/
+ {.bitmap_index = 5802, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(f)*/
+ {.bitmap_index = 5892, .adv_w = 192, .box_h = 13, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*(g)*/
+ {.bitmap_index = 5970, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(h)*/
+ {.bitmap_index = 6066, .adv_w = 192, .box_h = 15, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(i)*/
+ {.bitmap_index = 6156, .adv_w = 192, .box_h = 18, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*(j)*/
+ {.bitmap_index = 6264, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(k)*/
+ {.bitmap_index = 6360, .adv_w = 192, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(l)*/
+ {.bitmap_index = 6456, .adv_w = 192, .box_h = 11, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(m)*/
+ {.bitmap_index = 6522, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(n)*/
+ {.bitmap_index = 6582, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(o)*/
+ {.bitmap_index = 6642, .adv_w = 192, .box_h = 13, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*(p)*/
+ {.bitmap_index = 6720, .adv_w = 192, .box_h = 13, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*(q)*/
+ {.bitmap_index = 6798, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(r)*/
+ {.bitmap_index = 6858, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(s)*/
+ {.bitmap_index = 6918, .adv_w = 192, .box_h = 14, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(t)*/
+ {.bitmap_index = 7002, .adv_w = 192, .box_h = 11, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(u)*/
+ {.bitmap_index = 7068, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(v)*/
+ {.bitmap_index = 7128, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(w)*/
+ {.bitmap_index = 7188, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(x)*/
+ {.bitmap_index = 7248, .adv_w = 192, .box_h = 13, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*(y)*/
+ {.bitmap_index = 7326, .adv_w = 192, .box_h = 10, .box_w = 12, .ofs_x = 0, .ofs_y = 3 },/*(z)*/
+ {.bitmap_index = 7386, .adv_w = 192, .box_h = 20, .box_w = 12, .ofs_x = 0, .ofs_y = 1 },/*({)*/
+ {.bitmap_index = 7506, .adv_w = 192, .box_h = 23, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*(|)*/
+ {.bitmap_index = 7644, .adv_w = 192, .box_h = 20, .box_w = 12, .ofs_x = 0, .ofs_y = 1 },/*(})*/
+ {.bitmap_index = 7764, .adv_w = 192, .box_h = 4, .box_w = 12, .ofs_x = 0, .ofs_y = 18 },/*(~)*/
+ {.bitmap_index = 7788, .adv_w = 192, .box_h = 0, .box_w = 12, .ofs_x = 0, .ofs_y = 0 },/*()*/
+};
+
+static const sgl_font_unicode_t song24_unicode = {
+ .offset = 32,
+ .tab_offset = 0,
+ .list = NULL,
+ .len = 96,
+};
+
+const sgl_font_t song23 = {
+ .bitmap = sgl_ascii_song23_bitmap,
+ .table = sgl_ascii_song23_tab,
+ .font_table_size = SGL_ARRAY_SIZE(sgl_ascii_song23_tab),
+ .font_height = 23,
+ .bpp = 4,
+ .unicode = &song24_unicode,
+ .unicode_num = 1,
+};
+
+#endif
diff --git a/User/system/sgl/include/sgl_anim.h b/User/system/sgl/include/sgl_anim.h
new file mode 100644
index 0000000..2981031
--- /dev/null
+++ b/User/system/sgl/include/sgl_anim.h
@@ -0,0 +1,392 @@
+/* source/include/sgl_anim.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_ANIM_H__
+#define __SGL_ANIM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include
+#include
+#include
+#include
+#include
+
+#if (CONFIG_SGL_ANIMATION)
+
+/* Forward declaration of sgl_pos sgl_anim structures */
+struct sgl_pos;
+struct sgl_anim;
+
+
+/* Anim path callback */
+typedef void (*sgl_anim_path_cb_t)(struct sgl_anim *anim, int32_t value);
+typedef int32_t (*sgl_anim_path_algo_t)(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
+
+
+/**
+ * @brief Animation object structure used to manage a single animation instance.
+ *
+ * This structure holds all the necessary state and configuration for an animation,
+ * including timing parameters, value interpolation, callbacks, and linkage in a list.
+ * All time values (act_delay, act_duration) are in milliseconds.
+ *
+ * @data: Pointer to user-defined private data associated with this animation.
+ * Not used internally by the animation engine; intended for application use.
+ *
+ * @next: Pointer to the next animation in a singly-linked list.
+ * Used internally by the animation scheduler to chain active animations.
+ *
+ * @act_delay: Delay time (in ms) before the animation starts after being added to the system.
+ * The animation will not progress until this delay has elapsed.
+ *
+ * @act_duration: Total duration (in ms) of the animation from start_value to end_value.
+ *
+ * @start_value: The initial value at the beginning of the animation (after delay).
+ *
+ * @end_value: The target value at the end of the animation.
+ *
+ * @path_cb: Optional custom callback function to compute intermediate animation values.
+ * If set, it overrides the built-in path algorithm (`path_algo`).
+ *
+ * @path_algo: Predefined interpolation algorithm (e.g., linear, ease-in, ease-out).
+ * Used only if `path_cb` is NULL.
+ *
+ * @finish_cb: Callback function invoked when the animation completes (including repeats).
+ * May be NULL if no cleanup or notification is needed.
+ *
+ * @repeat_cnt: Number of times the animation should repeat.
+ * - -1: play indefinitely, you can use SGL_ANIM_REPEAT_LOOP
+ * - 1: play once (no repeat), you can use SGL_ANIM_REPEAT_ONCE
+ * - n: repeat n times (total plays = n)
+ * @note Only 30 bits are allocated; max value is 0x3FFFFFFE.
+ *
+ * @finished: Flag indicating whether the animation has completed (including all repeats).
+ * Set to 1 when the animation ends naturally or is stopped.
+ *
+ * @auto_free: If set to 1, the animation object will be automatically freed after completion.
+ * Useful for fire-and-forget animations; ensure memory was allocated dynamically.
+ */
+typedef struct sgl_anim {
+ void *data;
+ struct sgl_anim *next;
+ uint32_t act_delay;
+ uint32_t act_duration;
+ int32_t start_value;
+ int32_t end_value;
+ sgl_anim_path_cb_t path_cb;
+ sgl_anim_path_algo_t path_algo;
+ void (*finish_cb)(struct sgl_anim *anim);
+ uint32_t repeat_cnt : 30;
+ uint32_t finished : 1;
+ uint32_t auto_free : 1;
+} sgl_anim_t;
+
+
+/**
+ * @brief animation context, it will be used to store status of animation
+ * @anim_list_head: animation list head
+ * @anim_list_tail: animation list tail
+ */
+typedef struct sgl_anim_ctx {
+ sgl_anim_t *anim_list_head;
+ sgl_anim_t *anim_list_tail;
+} sgl_anim_ctx_t;
+
+
+#define sgl_anim_for_each(anim, head) for ((anim) = (head)->anim_list_head; (anim) != NULL; (anim) = (anim)->next)
+#define sgl_anim_for_each_safe(anim, n, head) for (anim = (head)->anim_list_head, n = (anim) ? (anim)->next : NULL; anim != NULL; anim = n, n = (anim) ? (anim)->next : NULL)
+
+#define SGL_ANIM_REPEAT_LOOP (0x3FFFFFFF)
+#define SGL_ANIM_REPEAT_ONCE (1)
+
+
+/* Animation context it will be used internally */
+extern sgl_anim_ctx_t sgl_anim_ctx;
+
+
+/**
+ * @brief Animation static initialization
+ * @param anim - Animation object
+ * @return none
+ */
+void sgl_anim_init(sgl_anim_t *anim);
+
+
+/**
+ * @brief dynamic alloc animation object with initialization
+ * @param none
+ * @return animation object
+*/
+sgl_anim_t* sgl_anim_create(void);
+
+
+/**
+ * @brief start animation
+ * @param anim animation object
+ * @para repeat_cnt repeat count of animation
+ * @return none
+*/
+void sgl_anim_start(sgl_anim_t *anim, uint32_t repeat_cnt);
+
+
+/**
+ * @brief stop animation
+ * @param anim animation object
+ * @return none
+*/
+void sgl_anim_stop(sgl_anim_t *anim);
+
+
+/**
+ * @brief delete animation object
+ * @param anim animation object
+ * @return none
+*/
+void sgl_anim_delete(sgl_anim_t *anim);
+
+
+/**
+ * @brief set animation private data
+ * @param anim animation object
+ * @param data pointer to private data
+ * @return none
+ */
+static inline void sgl_anim_set_data(sgl_anim_t *anim, void *data)
+{
+ SGL_ASSERT(anim != NULL);
+ anim->data = data;
+}
+
+
+/**
+ * @brief set animation path callback function
+ * @param anim animation object
+ * @param path_cb path callback function
+ * @param path_algo path algo callback function
+ * @return none
+ */
+static inline void sgl_anim_set_path(sgl_anim_t *anim, sgl_anim_path_cb_t path_cb, sgl_anim_path_algo_t path_algo)
+{
+ SGL_ASSERT(anim != NULL && path_cb != NULL && path_algo != NULL);
+ anim->path_cb = path_cb;
+ anim->path_algo = path_algo;
+}
+
+
+/**
+ * @brief set animation start value
+ * @param anim animation object
+ * @param value start value
+ * @return none
+ */
+static inline void sgl_anim_set_start_value(sgl_anim_t *anim, int32_t value)
+{
+ SGL_ASSERT(anim != NULL);
+ anim->start_value = value;
+}
+
+
+/**
+ * @brief set animation end value
+ * @param anim animation object
+ * @param value end value
+ * @return none
+ */
+static inline void sgl_anim_set_end_value(sgl_anim_t *anim, int32_t value)
+{
+ SGL_ASSERT(anim != NULL);
+ anim->end_value = value;
+}
+
+
+/**
+ * @brief set animation active delay time, ms
+ * @param anim animation object
+ * @param delay active delay time, ms
+ * @return none
+ */
+static inline void sgl_anim_set_act_delay(sgl_anim_t *anim, uint32_t delay_ms)
+{
+ SGL_ASSERT(anim != NULL);
+ anim->act_delay = delay_ms;
+}
+
+
+/**
+ * @brief set animation active duration time, ms
+ * @param anim animation object
+ * @param duration active duration time, ms
+ * @return none
+ */
+static inline void sgl_anim_set_act_duration(sgl_anim_t *anim, uint32_t duration_ms)
+{
+ SGL_ASSERT(anim != NULL);
+ anim->act_duration = duration_ms;
+}
+
+
+/**
+ * @brief set finish callback for animation
+ * @param anim animation object
+ * @param finish_cb finish callback
+ * @return none
+ */
+static inline void sgl_anim_set_finish_cb(sgl_anim_t *anim, void (*finish_cb)(sgl_anim_t *anim))
+{
+ SGL_ASSERT(anim != NULL);
+ anim->finish_cb = finish_cb;
+}
+
+
+/**
+ * @brief check animation is finished or not
+ * @param anim animation object
+ * @return true or false
+ */
+static inline bool sgl_anim_is_finished(sgl_anim_t *anim)
+{
+ SGL_ASSERT(anim != NULL);
+ return (bool)anim->finished;
+}
+
+
+/**
+ * @brief set auto free flag for animation
+ * @param anim animation
+ * @return none
+ */
+static inline void sgl_anim_set_auto_free(sgl_anim_t *anim)
+{
+ SGL_ASSERT(anim != NULL);
+ anim->auto_free = 1;
+}
+
+
+/**
+ * @brief animation task, it will foreach all animation
+ * @param none
+ * @return none
+ * @note this function should be called in sgl_task()
+ */
+void sgl_anim_task(void);
+
+
+/**
+ * Linear animation path calculation function
+ *
+ * Calculates the current interpolated value based on elapsed time and total duration
+ * using linear interpolation.
+ *
+ * @param elaps Elapsed time in milliseconds
+ * @param duration Total animation duration in milliseconds
+ * @param start Start value
+ * @param end End value
+ *
+ * @return The interpolated value for the current time
+ *
+ * @note Returns 'end' if elaps >= duration (animation finished)
+ * Returns 'start' if elaps == 0 (animation just started)
+ * Uses 32-bit integer arithmetic to avoid floating-point operations
+ * for better performance on embedded systems
+ */
+int32_t sgl_anim_path_linear(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
+#define SGL_ANIM_PATH_LINEAR sgl_anim_path_linear
+
+
+/**
+ * sgl_anim_path_ease_in_out - Cubic ease-in-out animation path
+ *
+ * This function creates a smooth animation curve that starts slow,
+ * accelerates in the middle, and decelerates at the end.
+ *
+ * @param elaps Elapsed time (ms)
+ * @param duration Total animation duration (ms)
+ * @param start Start value
+ * @param end End value
+ * @return Interpolated value at current time
+ */
+int32_t sgl_anim_path_ease_in_out(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
+#define SGL_ANIM_PATH_EASE_IN_OUT sgl_anim_path_ease_in_out
+
+
+/**
+ * sgl_anim_path_ease_in - Cubic ease-in animation path
+ *
+ * This function creates a smooth animation curve that starts slow,
+ * accelerates in the after
+ *
+ * @param elaps Elapsed time (ms)
+ * @param duration Total animation duration (ms)
+ * @param start Start value
+ * @param end End value
+ * @return Interpolated value at current time
+ */
+int32_t sgl_anim_path_ease_out(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
+#define SGL_ANIM_PATH_EASE_OUT sgl_anim_path_ease_out
+
+
+/**
+ * sgl_anim_path_ease_in - Cubic ease-in animation path
+ *
+ * This function creates a smooth animation curve that starts accelerates,
+ * accelerates in the after
+ *
+ * @param elaps Elapsed time (ms)
+ * @param duration Total animation duration (ms)
+ * @param start Start value
+ * @param end End value
+ * @return Interpolated value at current time
+ */
+int32_t sgl_anim_path_ease_in(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
+#define SGL_ANIM_PATH_EASE_IN sgl_anim_path_ease_in
+
+
+/**
+ * sgl_anim_path_overshoot - Overshoot animation path
+ *
+ * This function creates an animation curve that overshoots the target end value
+ * slightly before settling back to it, creating a natural "bounce" or "spring-like"
+ * effect for a more dynamic and realistic animation.
+ *
+ * @param elaps Elapsed time (ms) since the animation started
+ * @param duration Total animation duration (ms)
+ * @param start Initial value of the animated property at the start of the animation
+ * @param end Target end value of the animated property
+ * @return Interpolated value of the animated property at the current elapsed time
+ */
+int32_t sgl_anim_path_overshoot(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
+#define SGL_ANIM_PATH_OVERSHOOT sgl_anim_path_overshoot
+
+
+#endif // ! CONFIG_SGL_ANIMATION
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif // ! __SGL_ANIM_H__
diff --git a/User/system/sgl/include/sgl_cfgfix.h b/User/system/sgl/include/sgl_cfgfix.h
new file mode 100644
index 0000000..d361b7a
--- /dev/null
+++ b/User/system/sgl/include/sgl_cfgfix.h
@@ -0,0 +1,230 @@
+/* source/include/sgl_cfgfix.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_CFGFIX_H__
+#define __SGL_CFGFIX_H__
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief sgl config fix file, it will fix the macro if not defined
+ * @note please add the macro in this file if you want to add new macro into source code
+ *
+ * @description:
+ *
+ * CONFIG_SGL_FBDEV_PIXEL_DEPTH:
+ * The pixel depth of framebuffer device, it will be used to define the color type
+ *
+ * CONFIG_SGL_FBDEV_ROTATION:
+ * The rotation of framebuffer device, default: 0
+ *
+ * CONFIG_SGL_FBDEV_RUNTIME_ROTATION:
+ * If you want to use runtime rotation, please define this macro to 1
+ *
+ * CONFIG_SGL_USE_FBDEV_VRAM:
+ * If you want to use full framebuffer, please define this macro to 1
+ *
+ * CONFIG_SGL_SYSTICK_MS:
+ * The macro should be defined to the system tick ms, default: 10
+ *
+ * CONFIG_SGL_COLOR16_SWAP:
+ * Its for 16 bit color, the color will be swapped
+ *
+ * CONFIG_SGL_EVENT_QUEUE_SIZE:
+ * the size of event queue, default: 32
+ *
+ * CONFIG_SGL_EVENT_CLICK_INTERVAL:
+ * The click interval, default: 10
+ *
+ * CONFIG_SGL_OBJ_SLOT_DYNAMIC
+ * If the object slot is dynamic, the object slot size will be dynamic allocated, otherwise, the object
+ * slot size will be static allocated that you should define CONFIG_SGL_OBJ_NUM_MAX macro
+ *
+ * CONFIG_SGL_OBJ_NUM_MAX:
+ * If CONFIG_SGL_OBJ_SLOT_DYNAMIC is 0 or not defined, you should define CONFIG_SGL_OBJ_NUM_MAX macro
+ *
+ * CONFIG_SGL_PIXMAP_BILINEAR_INTERP:
+ * If you want to use pixmap bilinear interpolation, please define this macro to 1
+ *
+ * CONFIG_SGL_ANIMATION:
+ * If you want to use animation, please define this macro to 1
+ *
+ * CONFIG_SGL_DEBUG:
+ * If you want to use debug, please define this macro to 1
+ *
+ * CONFIG_SGL_USE_OBJ_ID:
+ * If you want to use obj id, please define this macro to 1, at mostly, the CONFIG_SGL_USE_OBJ_ID should be 0
+ *
+ * CONFIG_SGL_HEAP_ALGO:
+ * The heap algorithm, default: lwmem
+ *
+ * CONFIG_SGL_HEAP_MEMORY_SIZE:
+ * The heap memory size, default: 10240
+ *
+ * CONFIG_SGL_FONT_COMPRESSED:
+ * If you want to use font compressed, please define this macro to 1
+ *
+ * CONFIG_SGL_FONT_SMALL_TABLE:
+ * If you want to use font small table, please define this macro to 1
+ *
+ * CONFIG_SGL_LABEL_ROTATION:
+ * If you want to use label rotation, please define this macro to 1
+ *
+ * CONFIG_SGL_FONT_SONG23:
+ * If you want to use font song23, please define this macro to 1
+ *
+ * CONFIG_SGL_FONT_CONSOLAS23:
+ * If you want to use font consolas23, please define this macro to 1
+ *
+ */
+
+#ifndef CONFIG_SGL_FBDEV_PIXEL_DEPTH
+#define CONFIG_SGL_FBDEV_PIXEL_DEPTH (16)
+#endif
+
+#ifndef CONFIG_SGL_FBDEV_ROTATION
+#define CONFIG_SGL_FBDEV_ROTATION (0)
+#endif
+
+#ifndef CONFIG_SGL_FBDEV_RUNTIME_ROTATION
+#define CONFIG_SGL_FBDEV_RUNTIME_ROTATION (0)
+#endif
+
+#ifndef CONFIG_SGL_USE_FBDEV_VRAM
+#define CONFIG_SGL_USE_FBDEV_VRAM (0)
+#endif
+
+#ifndef CONFIG_SGL_SYSTICK_MS
+#define CONFIG_SGL_SYSTICK_MS (10)
+#endif
+
+#ifndef CONFIG_SGL_COLOR16_SWAP
+#define CONFIG_SGL_COLOR16_SWAP (0)
+#endif
+
+#ifndef CONFIG_SGL_EVENT_QUEUE_SIZE
+#define CONFIG_SGL_EVENT_QUEUE_SIZE (16)
+#endif
+
+#ifndef CONFIG_SGL_EVENT_CLICK_INTERVAL
+#define CONFIG_SGL_EVENT_CLICK_INTERVAL (10)
+#endif
+
+#ifndef CONFIG_SGL_DIRTY_AREA_NUM_MAX
+#define CONFIG_SGL_DIRTY_AREA_NUM_MAX (16)
+#endif
+
+#ifndef CONFIG_SGL_PIXMAP_BILINEAR_INTERP
+#define CONFIG_SGL_PIXMAP_BILINEAR_INTERP (0)
+#endif
+
+#ifndef CONFIG_SGL_ANIMATION
+#define CONFIG_SGL_ANIMATION (0)
+#endif
+
+#ifndef CONFIG_SGL_DEBUG
+# define CONFIG_SGL_DEBUG (0)
+#elif (CONFIG_SGL_DEBUG == 1)
+# ifndef CONFIG_SGL_LOG_COLOR
+# define CONFIG_SGL_LOG_COLOR (0)
+# endif
+# ifndef CONFIG_SGL_LOG_LEVEL
+# define CONFIG_SGL_LOG_LEVEL (1)
+# endif
+#endif
+
+#ifndef CONFIG_SGL_OBJ_USE_NAME
+#define CONFIG_SGL_OBJ_USE_NAME (0)
+#endif
+
+#ifndef CONFIG_SGL_HEAP_ALGO
+#define CONFIG_SGL_HEAP_ALGO (lwmem)
+#endif
+
+#ifndef CONFIG_SGL_HEAP_MEMORY_SIZE
+# define CONFIG_SGL_HEAP_MEMORY_SIZE (10240)
+# ifndef CONFIG_SGL_FL_INDEX_MAX
+# define CONFIG_SGL_FL_INDEX_MAX (20)
+# endif
+#endif
+
+#ifndef CONFIG_SGL_FONT_COMPRESSED
+#define CONFIG_SGL_FONT_COMPRESSED (0)
+#endif
+
+#ifndef CONFIG_SGL_FONT_SMALL_TABLE
+#define CONFIG_SGL_FONT_SMALL_TABLE (0)
+#endif
+
+#ifndef CONFIG_SGL_LABEL_ROTATION
+#define CONFIG_SGL_LABEL_ROTATION (0)
+#endif
+
+#ifndef CONFIG_SGL_FONT_SONG23
+#define CONFIG_SGL_FONT_SONG23 (0)
+#endif
+
+#ifndef CONFIG_SGL_FONT_CONSOLAS14
+#define CONFIG_SGL_FONT_CONSOLAS14 (0)
+#endif
+
+#ifndef CONFIG_SGL_FONT_CONSOLAS23
+#define CONFIG_SGL_FONT_CONSOLAS23 (0)
+#endif
+
+#ifndef CONFIG_SGL_FONT_CONSOLAS24
+#define CONFIG_SGL_FONT_CONSOLAS24 (0)
+#endif
+
+#ifndef CONFIG_SGL_FONT_CONSOLAS32
+#define CONFIG_SGL_FONT_CONSOLAS32 (0)
+#endif
+
+#if !(CONFIG_SGL_THEME_DARK || CONFIG_SGL_THEME_LIGHT)
+# ifndef CONFIG_SGL_THEME_DEFAULT
+# define CONFIG_SGL_THEME_DEFAULT (1)
+# endif
+#endif
+
+#ifndef CONFIG_SGL_BOOT_LOGO
+#define CONFIG_SGL_BOOT_LOGO (1)
+#endif
+
+#ifndef CONFIG_SGL_BOOT_ANIMATION
+# define CONFIG_SGL_BOOT_ANIMATION (0)
+#elif (CONFIG_SGL_ANIMATION == 0)
+# undef CONFIG_SGL_BOOT_ANIMATION
+# define CONFIG_SGL_BOOT_ANIMATION (0)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !__SGL_CFGFIX_H__
diff --git a/User/system/sgl/include/sgl_core.h b/User/system/sgl/include/sgl_core.h
new file mode 100644
index 0000000..b0a9a42
--- /dev/null
+++ b/User/system/sgl/include/sgl_core.h
@@ -0,0 +1,2164 @@
+/* source/include/sgl_core.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_CORE_H__
+#define __SGL_CORE_H__
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* the maximum depth of object*/
+#define SGL_OBJ_DEPTH_MAX (16)
+/* the maximum number of drawing buffers */
+#define SGL_DRAW_BUFFER_MAX (2)
+/* define default animation tick ms */
+#define SGL_SYSTEM_TICK_MS CONFIG_SGL_SYSTICK_MS
+
+
+#if (CONFIG_SGL_DIRTY_AREA_NUM_MAX)
+#define SGL_DIRTY_AREA_NUM_MAX CONFIG_SGL_DIRTY_AREA_NUM_MAX
+#endif
+
+/* the ASCII offset of fonts */
+#define SGL_TEXT_ASCII_OFFSET (32)
+
+
+/**
+* @brief This enumeration type defines the alignment of controls in sgl,
+* i.e. coordinate positions
+*/
+typedef enum sgl_align_type {
+ SGL_ALIGN_CENTER = 0,
+ SGL_ALIGN_TOP_MID,
+ SGL_ALIGN_TOP_LEFT,
+ SGL_ALIGN_TOP_RIGHT,
+ SGL_ALIGN_BOT_MID,
+ SGL_ALIGN_BOT_LEFT,
+ SGL_ALIGN_BOT_RIGHT,
+ SGL_ALIGN_LEFT_MID,
+ SGL_ALIGN_RIGHT_MID,
+ SGL_ALIGN_VERT_LEFT,
+ SGL_ALIGN_VERT_RIGHT,
+ SGL_ALIGN_VERT_MID,
+ SGL_ALIGN_HORIZ_TOP,
+ SGL_ALIGN_HORIZ_BOT,
+ SGL_ALIGN_HORIZ_MID,
+ SGL_ALIGN_NUM,
+
+} sgl_align_type_t;
+
+
+/**
+* @brief This enumeration type defines the layout of controls in sgl,
+* i.e. coordinate positions
+*/
+typedef enum sgl_layout_type {
+ SGL_LAYOUT_NONE = 0,
+ SGL_LAYOUT_HORIZONTAL = 1,
+ SGL_LAYOUT_VERTICAL = 2,
+ SGL_LAYOUT_GRID = 3,
+ SGL_LAYOUT_NUM = 4,
+} sgl_layout_type_t;
+
+
+/**
+* @brief This structure is a structure that describes the position of the control,
+* where x represents the position of the x coordinate, which is the row coordinate position,
+* and y represents the position of the y coordinate, which is the column coordinate position
+*
+* @x: x coordinate
+* @y: y coordinate
+*/
+typedef struct sgl_pos {
+ int16_t x;
+ int16_t y;
+} sgl_pos_t;
+
+
+/**
+* @brief This structure describes the size of the object, including width and height, in pixels
+*
+* @w: width
+* @h: height
+*/
+typedef struct sgl_size {
+ int16_t w;
+ int16_t h;
+} sgl_size_t;
+
+
+/**
+* @brief This structure describes a rectangular region, where x1 and y1 represent the coordinates
+* of the upper left corner of the rectangle, and x2 and y2 represent the coordinates of the
+* lower right corner of the rectangle
+*
+* @x1: x position left corner of the rectangle
+* @y1: y position left corner of the rectangle
+* @x2: x position right corner of the rectangle
+* @y2: y position right corner of the rectangle
+*/
+typedef struct sgl_area {
+ int16_t x1;
+ int16_t y1;
+ int16_t x2;
+ int16_t y2;
+} sgl_area_t;
+
+#define sgl_rect_t sgl_area_t
+
+
+/**
+* @brief This structure defines a 32 bit color bit field
+*
+* @blue: Blue color component
+* @green: Green color component
+* @red: Red color component
+* @alpha: Color transparency
+*/
+typedef union {
+ struct {
+ uint8_t blue;
+ uint8_t green;
+ uint8_t red;
+ uint8_t alpha;
+ } ch;
+ uint32_t full;
+} sgl_color32_t;
+
+
+/**
+* @brief This structure defines a 24 bit color bit field
+*
+* @blue: Blue color component
+* @green: Green color component
+* @red: Red color component
+*/
+typedef union {
+ struct {
+ uint8_t blue;
+ uint8_t green;
+ uint8_t red;
+ } ch;
+ uint8_t full[3];
+} sgl_color24_t;
+
+
+/**
+* @brief This structure defines a 16 bit color bit field
+*
+* @blue: Blue color component
+* @green: Green color component
+* @red: Red color component
+* @alpha: Color transparency
+*/
+typedef union {
+ struct {
+ uint16_t blue : 5;
+ uint16_t green : 6;
+ uint16_t red : 5;
+ } ch;
+ uint16_t full;
+} sgl_color16_t;
+
+
+/**
+* @brief This structure defines a 8 bit color bit field
+*
+* @blue: Blue color component
+* @green: Green color component
+* @red: Red color component
+* @alpha: Color transparency
+*/
+typedef union {
+ struct {
+ uint8_t blue : 2;
+ uint8_t green : 3;
+ uint8_t red : 3;
+ } ch;
+ uint8_t full;
+} sgl_color8_t;
+
+
+#if (CONFIG_SGL_FBDEV_PIXEL_DEPTH == 32)
+#define sgl_color_t sgl_color32_t
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == 24)
+#define sgl_color_t sgl_color24_t
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == 16)
+#define sgl_color_t sgl_color16_t
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == 8)
+#define sgl_color_t sgl_color8_t
+#endif
+
+
+/**
+ * @brief This structure defines a surface, which is a rectangular area of the screen.
+ * @x1: x1 coordinate
+ * @y1: y1 coordinate
+ * @x2: x2 coordinate
+ * @y2: y2 coordinate
+ * @buffer: buffer pointer
+ * @size: bytes of buffer
+ * @w: surf width
+ * @h: surf height
+ * @dirty: pointer to dirty area
+ */
+typedef struct sgl_surf {
+ int16_t x1;
+ int16_t y1;
+ int16_t x2;
+ int16_t y2;
+ sgl_color_t *buffer;
+ uint32_t size;
+ uint16_t w;
+ uint16_t h;
+ sgl_area_t *dirty;
+} sgl_surf_t;
+
+
+/**
+* @brief This structure defines an image, with a bitmap pointing to the
+* bitmap of the image, while specifying the width and height of the image
+*
+* @width: pixmap width
+* @height: pixmap height
+* @format: bitmap format 0: no compression, 1:
+* @bitmap: point to image bitmap
+*/
+typedef struct sgl_pixmap {
+ uint32_t width : 13;
+ uint32_t height : 13;
+ uint32_t format : 6;
+ union {
+ const uint8_t *array;
+ const uintptr_t addr;
+ } bitmap;
+} sgl_pixmap_t;
+
+
+/**
+ * @brief This structure defines an icon, with a bitmap pointing to the
+ * @width: pixmap width
+ * @height: pixmap height
+ * @bitmap: point to icon bitmap
+ */
+typedef struct sgl_icon_pixmap {
+ uint16_t width;
+ uint16_t height;
+ const uint8_t *bitmap;
+} sgl_icon_pixmap_t;
+
+
+/**
+* @brief Font index table structure, used to describe the bitmap index positions of
+* all characters in a font, accelerating the search process
+*
+* @bitmap_index: point to bitmap index of font
+* @adv_w: advance width of character width
+* @box_h: height of font
+* @box_w: width of font
+* @ofs_x: offset of character x position
+* @ofs_y: offset of character y position
+*/
+typedef struct sgl_font_table {
+#if (CONFIG_SGL_FONT_SMALL_TABLE)
+ const uint16_t bitmap_index;
+ const uint16_t adv_w;
+ const uint8_t box_h;
+ const uint8_t box_w;
+ const int8_t ofs_x;
+ const int8_t ofs_y;
+#else
+ const uint32_t bitmap_index;
+ const uint16_t adv_w;
+ const uint16_t box_h;
+ const uint16_t box_w;
+ const int8_t ofs_x;
+ const int8_t ofs_y;
+#endif
+} sgl_font_table_t;
+
+
+/**
+ * @brief This structure defines a font unicode information, which is a collection of fonts
+ * @offset: offset of unicode for unicode list
+ * @len: length of unicode list
+ * @list: point to unicode list
+ * @tab_offset: offset of font table
+ */
+typedef struct sgl_font_unicode {
+ const uint32_t offset;
+ const uint32_t len;
+ const uint32_t *list;
+ const uint32_t tab_offset;
+} sgl_font_unicode_t;
+
+
+/**
+* @brief A structure used to describe information about a font, Defining a font set requires
+* the use of this structure to describe relevant information
+*
+* @bitmap: point to bitmap of font
+* @table: point to struct sgl_font_table
+* @font_table_size: size of struct sgl_font_table
+* @font_height: height of font
+* @unicode: point to struct sgl_font_unicode struct
+* @unicode_num: number of unicode parts
+* @base_line: base line of font
+* @bpp: The anti aliasing level of the font, only support 2, 4
+* @compress: compress flag, 0: no compress, 1: compress
+*/
+typedef struct sgl_font {
+ const uint8_t *bitmap;
+ const sgl_font_table_t *table;
+ const uint16_t font_table_size;
+ const uint16_t font_height;
+ const sgl_font_unicode_t *unicode;
+ const uint32_t unicode_num;
+ const int16_t base_line;
+ const uint8_t bpp;
+ const uint8_t compress;
+} sgl_font_t;
+
+
+/**
+ * @brief Represents a fundamental UI object in the SGL (Simple Graphics Library) framework.
+ *
+ * This structure defines a generic GUI element that can be part of a hierarchical display tree.
+ * Members:
+ * @area: The logical size (width, height) of the object, used for layout and measurement.
+ * @coords: The current screen position (x, y) and dimensions after layout calculation.
+ * @event_fn: Callback function invoked when an event (e.g., touch, click) targets this object.
+ * @event_data: User-defined context data passed to the event callback.
+ * @construct_fn: Initialization hook called during object creation to allocate resources or set defaults.
+ * @parent: Pointer to the parent object; NULL if this is a root-level object.
+ * @child: Pointer to the first child in the list of children.
+ * @sibling: Pointer to the next sibling under the same parent.
+ * @destroyed: (1 bit) Set to 1 when the object is marked for destruction.
+ * @dirty: (1 bit) Set to 1 when the object needs to be redrawn.
+ * @hide: (1 bit) Set to 1 to exclude the object from rendering (hidden).
+ * @needinit: (1 bit) Set to 1 if the object requires deferred initialization.
+ * @layout: (2 bits) Layout mode for children:
+ * - 0: No auto-layout
+ * - 1: Horizontal layout (left to right)
+ * - 2: Vertical layout (top to bottom)
+ * - 3: Reserved
+ * @clickable: (1 bit) Set to 1 if the object can receive click/touch events.
+ * @movable: (1 bit) Set to 1 if the object can be dragged by the user.
+ * @border: border width of object
+ * @flexible: (1 bit, in uint16_t field) Indicates the object can expand to fill available space.
+ * @evt_leave: (1 bit) Set to 1 if the object should receive "pointer leave" events.
+ * @pressed: (1 bit) Tracks whether the object is currently being pressed.
+ * @page: (1 bit) Reserved for page/view switching logic (e.g., in tabbed interfaces).
+ * @radius: (12 bits) Corner radius in pixels for rounded rectangle rendering (max 4095).
+ * @name: [Optional] Null-terminated string identifier for debugging or lookup.
+ * Only present if CONFIG_SGL_OBJ_USE_NAME is defined.
+ */
+typedef struct sgl_obj {
+ sgl_area_t area;
+ sgl_area_t coords;
+ void (*event_fn)(sgl_event_t *e);
+ void *event_data;
+ void (*construct_fn)(sgl_surf_t *surf, struct sgl_obj *obj, sgl_event_t *event);
+ struct sgl_obj *parent;
+ struct sgl_obj *child;
+ struct sgl_obj *sibling;
+ uint8_t destroyed : 1;
+ uint8_t dirty : 1;
+ uint8_t hide : 1;
+ uint8_t needinit : 1;
+ uint8_t layout : 2;
+ uint8_t clickable : 1;
+ uint8_t movable : 1;
+ uint8_t border;
+ uint16_t flexible : 1;
+ uint16_t focus : 1;
+ uint16_t pressed : 1;
+ uint16_t page : 1;
+ uint16_t radius : 12;
+#if CONFIG_SGL_OBJ_USE_NAME
+ const char *name;
+#endif
+} sgl_obj_t;
+
+
+/**
+ * @brief Represents a page object in the SGL graphics system.
+ *
+ * An sgl_page_t encapsulates a complete, renderable UI page or screen.
+ * It combines a base graphical object, a drawing surface, a background color,
+ * and an optional background pixmap. Pages serve as top-level containers
+ * for UI elements and can be managed by a page manager or display stack.
+ *
+ * Members:
+ * - obj : Base object (inherits sgl_obj_t), providing position, size, visibility, etc.
+ * - color : Default background color used when no pixmap is set.
+ * - alpha : Alpha value for the background color (0-255).
+ * - pixmap : Optional pointer to a background pixmap. If non-NULL, it typically overrides 'color'
+ * as the background content during rendering (behavior depends on flush/render logic).
+ */
+typedef struct sgl_page {
+ sgl_obj_t obj;
+ sgl_color_t color;
+ uint8_t alpha;
+ const sgl_pixmap_t *pixmap;
+} sgl_page_t;
+
+
+/**
+ * @brief sgl framebuffer information struct
+ * @buffer: framebuffer, this specify the memory address of the framebuffer
+ * @buffer_size: framebuffer size
+ * @xres: x resolution
+ * @yres: y resolution
+ * @flush_area: flush area callback function pointer, return the finished flag
+ */
+typedef struct sgl_fbinfo {
+ void *buffer[SGL_DRAW_BUFFER_MAX];
+ uint32_t buffer_size;
+ int16_t xres;
+ int16_t yres;
+ void (*flush_area)(sgl_area_t *area, sgl_color_t *src);
+} sgl_fbinfo_t;
+
+
+/**
+ * @brief sgl framebuffer device struct
+ * @fbinfo: framebuffer information, that specify the memory address of the framebuffer and resolution
+ * @surf: Drawing surface associated with this page; defines the target buffer or area for rendering.
+ * @dirty_num: dirty area number
+ * @fb_swap: framebuffer swap flag
+ * @fb_status: framebuffer status flag
+ * @dirty: dirty area pool
+ * @page: current page
+ */
+typedef struct sgl_fbdev {
+ sgl_fbinfo_t fbinfo;
+ sgl_surf_t surf;
+ uint16_t dirty_num;
+ volatile uint8_t fb_swap;
+ volatile uint8_t fb_status;
+ sgl_area_t dirty[SGL_DIRTY_AREA_NUM_MAX];
+ sgl_obj_t *active;
+} sgl_fbdev_t;
+
+
+/**
+ * @brief sgl log print device struct
+ * @logdev: log print callback function pointer
+ * @fbdev: framebuffer device
+ * @last_tick: last tick time, ms
+ * @tick_ms: tick milliseconds
+ * @font: system default font
+ * @rotation: buffer only for rotation
+ * @angle: angle value only for rotation
+ */
+typedef struct sgl_system {
+ void (*logdev)(const char *str);
+ sgl_fbdev_t fbdev;
+ volatile uint32_t last_tick;
+ volatile uint32_t tick_ms;
+ const sgl_font_t *font;
+#if (CONFIG_SGL_FBDEV_ROTATION != 0)
+ sgl_color_t *rotation;
+#elif (CONFIG_SGL_FBDEV_RUNTIME_ROTATION)
+ sgl_color_t *rotation;
+ uint16_t angle;
+#endif
+} sgl_system_t;
+
+
+/**
+ * @brief for each child object of parent
+ * @param _child: pointer of child object
+ * @param parent: pointer of parent object
+ */
+#define sgl_obj_for_each_child(_child, parent) for (_child = parent->child; _child != NULL; _child = _child->sibling)
+
+
+/**
+ * @brief for each child object of parent safely
+ * @param _child: pointer of child object
+ * @param parent: pointer of parent object
+ */
+#define sgl_obj_for_each_child_safe(_child, n, parent) for (_child = parent->child, n = (_child ? _child->sibling : NULL); _child != NULL; \
+ _child = n, n = (_child ? _child->sibling : NULL))
+
+/**
+ * @brief The macro define the rotation of the framebuffer device
+ * @param area_dst: destination area
+ * @param area_src: source area
+ * @param dst: destination buffer
+ * @param src: source buffer
+ * @note it only support 90/180/270 degree rotation
+ */
+#define sgl_fbdev_rotate_90(area_dst, area_src, dst, src) do { \
+ for (uint16_t y = 0; y < height; y++) { \
+ for (uint16_t x = 0; x < width; x++) { \
+ size_t src_idx = y * width + x; \
+ size_t dst_idx = (width - 1 - x) * height + y; \
+ dst[dst_idx] = src[src_idx]; \
+ } \
+ } \
+ area_dst.x1 = area_src->y1; \
+ area_dst.y1 = SGL_SCREEN_WIDTH - area_src->x2 - 1; \
+ area_dst.x2 = sgl_min(area_src->y2, SGL_SCREEN_HEIGHT - 1); \
+ area_dst.y2 = sgl_min(SGL_SCREEN_WIDTH - area_src->x1 - 1, SGL_SCREEN_WIDTH - 1); \
+ } while(0);
+
+#define sgl_fbdev_rotate_180(area_dst, area_src, dst, src) do { \
+ size_t total = (size_t)(width * height); \
+ for (size_t i = 0; i < total; i++) { \
+ dst[i] = src[total - 1 - i]; \
+ } \
+ area_dst.x1 = SGL_SCREEN_WIDTH - area_src->x2 - 1; \
+ area_dst.y1 = SGL_SCREEN_HEIGHT - area_src->y2 - 1; \
+ area_dst.x2 = SGL_SCREEN_WIDTH - area_src->x1 - 1; \
+ area_dst.y2 = SGL_SCREEN_HEIGHT - area_src->y1 - 1; \
+ } while(0);
+
+#define sgl_fbdev_rotate_270(area_dst, area_src, dst, src) do { \
+ for (uint16_t y = 0; y < height; y++) { \
+ for (uint16_t x = 0; x < width; x++) { \
+ size_t src_idx = y * width + x; \
+ size_t dst_idx = x * height + (height - 1 - y); \
+ dst[dst_idx] = src[src_idx]; \
+ } \
+ } \
+ area_dst.x1 = SGL_SCREEN_HEIGHT - area_src->y2 - 1; \
+ area_dst.y1 = area_src->x1; \
+ area_dst.x2 = sgl_min(area_dst.x1 + height - 1, SGL_SCREEN_HEIGHT - 1); \
+ area_dst.y2 = sgl_min(area_dst.y1 + width - 1, SGL_SCREEN_WIDTH - 1); \
+ } while(0);
+
+
+/* dont to use this variable, it is used internally by sgl library */
+extern sgl_system_t sgl_system;
+
+/**
+ * @brief Alpha blending table for 4 bpp and 2 bpp
+ */
+extern const uint8_t sgl_opa4_table[16];
+extern const uint8_t sgl_opa2_table[4];
+
+
+/**
+ * @brief register the frame buffer device
+ * @param fbinfo the frame buffer device information
+ * @return int, 0 if success, -1 if failed
+ * @note you must check the result of this function
+ */
+int sgl_fbdev_register(sgl_fbinfo_t *fbinfo);
+
+
+/**
+ * @brief set framebuffer device flush ready
+ * @param none
+ * @return none
+ * @note this function must be called in DMA callback function after framebuffer device flush
+ */
+static inline void sgl_fbdev_flush_ready(void)
+{
+ sgl_system.fbdev.fb_status |= (1 << sgl_system.fbdev.fb_swap);
+
+ /* change to next framebuffer */
+ if (sgl_system.fbdev.fbinfo.buffer[1] != NULL) {
+ sgl_system.fbdev.surf.buffer = (sgl_color_t *)sgl_system.fbdev.fbinfo.buffer[sgl_system.fbdev.fb_swap ^= 1];
+ }
+}
+
+
+/**
+ * @brief check if framebuffer device buffer need to wait ready
+ * @param fbdev point to the framebuffer device
+ * @return bool true if need to wait ready, false if not
+ */
+static inline bool sgl_fbdev_flush_wait_ready(sgl_fbdev_t *fbdev)
+{
+ return (fbdev->fb_status & (1 << sgl_system.fbdev.fb_swap)) == 0;
+}
+
+
+/**
+ * @brief get framebuffer device buffer resolution width
+ * @param none
+ * @return framebuffer device buffer resolution width
+ */
+static inline int16_t sgl_fbdev_resolution_width(void)
+{
+ return sgl_system.fbdev.fbinfo.xres;
+}
+
+/**
+ * @brief get framebuffer device buffer resolution height
+ * @param none
+ * @return framebuffer device buffer resolution height
+ */
+#define SGL_SCREEN_WIDTH sgl_fbdev_resolution_width()
+
+
+/**
+ * @brief get framebuffer device buffer resolution height
+ * @param none
+ * @return framebuffer device buffer resolution height
+ */
+static inline int16_t sgl_fbdev_resolution_height(void)
+{
+ return sgl_system.fbdev.fbinfo.yres;
+}
+
+/**
+ * @brief get framebuffer device buffer resolution width
+ * @param none
+ * @return framebuffer device buffer resolution width
+ */
+#define SGL_SCREEN_HEIGHT sgl_fbdev_resolution_height()
+
+
+/**
+ * @brief get framebuffer device buffer address
+ * @param none
+ * @return framebuffer device buffer address
+ */
+static inline void* sgl_fbdev_buffer_address(void)
+{
+ return sgl_system.fbdev.fbinfo.buffer[0];
+}
+
+
+/**
+ * @brief framebuffer device flush function
+ * @param area [in] area of flush, that is x1, y1, x2, y2: area of flush
+ * area contains the coordinates of the area to be flushed
+ * - x1: x coordinate of the top left corner of the area
+ * - y1: y coordinate of the top left corner of the area
+ * - x2: x coordinate of the bottom right corner of the area
+ * - y2: y coordinate of the bottom right corner of the area
+ * @param src [in] source color
+ */
+static inline void sgl_fbdev_flush_area(sgl_area_t *area, sgl_color_t *src)
+{
+#if CONFIG_SGL_COLOR16_SWAP
+ uint16_t w = area->x2 - area->x1 + 1;
+ uint16_t h = area->y2 - area->y1 + 1;
+ uint16_t *dst = (uint16_t *)src;
+ for (size_t i = 0; i < (size_t)(w * h); i++) {
+ dst[i] = (dst[i] << 8) | (dst[i] >> 8);
+ }
+#endif
+
+#if (CONFIG_SGL_FBDEV_ROTATION != 0)
+ uint16_t width = area->x2 - area->x1 + 1;
+ uint16_t height = area->y2 - area->y1 + 1;
+ sgl_area_t area_dst = *area;
+
+#if (CONFIG_SGL_FBDEV_ROTATION == 90)
+ sgl_fbdev_rotate_90(area_dst, area, sgl_system.rotation, src);
+#elif (CONFIG_SGL_FBDEV_ROTATION == 180)
+ sgl_fbdev_rotate_180(area_dst, area, sgl_system.rotation, src);
+#elif (CONFIG_SGL_FBDEV_ROTATION == 270)
+ sgl_fbdev_rotate_270(area_dst, area, sgl_system.rotation, src);
+#else
+#error "CONFIG_SGL_FBDEV_ROTATION is invalid rotation value (only 0/90/180/270 supported)"
+#endif
+ sgl_system.fbdev.fbinfo.flush_area(&area_dst, sgl_system.rotation);
+#elif (CONFIG_SGL_FBDEV_RUNTIME_ROTATION)
+ uint16_t width = area->x2 - area->x1 + 1;
+ uint16_t height = area->y2 - area->y1 + 1;
+ sgl_area_t area_dst = *area;
+
+ switch (sgl_system.angle) {
+ case 0:
+ sgl_system.fbdev.fbinfo.flush_area(area, src);
+ return;
+ case 90:
+ sgl_fbdev_rotate_90(area_dst, area, sgl_system.rotation, src);
+ break;
+ case 180:
+ sgl_fbdev_rotate_180(area_dst, area, sgl_system.rotation, src);
+ break;
+ case 270:
+ sgl_fbdev_rotate_270(area_dst, area, sgl_system.rotation, src);
+ break;
+ default:
+ SGL_LOG_ERROR("invalid angle: %d", sgl_system.angle);
+ return;
+ }
+ sgl_system.fbdev.fbinfo.flush_area(&area_dst, sgl_system.rotation);
+#else
+ sgl_system.fbdev.fbinfo.flush_area(area, src);
+#endif
+}
+
+
+#if (CONFIG_SGL_FBDEV_RUNTIME_ROTATION)
+/**
+ * @brief set framebuffer device rotation angle
+ * @param angle [in] rotation angle, that is 0, 90, 180, 270
+ * @return none
+ * @note Rotation angle must be 0, 90, 180, 270
+ */
+void sgl_fbdev_set_angle(uint16_t angle);
+#endif //CONFIG_SGL_FBDEV_RUNTIME_ROTATION
+
+
+/**
+ * @brief register log output device
+ * @param log_puts log output function
+ * @return none
+ * @note if you want to use print log into uart or other devices, you must register log output device first
+ */
+static inline void sgl_logdev_register(void (*puts)(const char *str))
+{
+ sgl_system.logdev = puts;
+}
+
+
+/**
+ * @brief log output function
+ * @param str log string
+ * @return none
+ * @note if you want to use printf function, you must register log output device first
+ */
+static inline void sgl_log_stdout(const char *str)
+{
+ if (sgl_system.logdev) {
+ sgl_system.logdev(str);
+ }
+}
+
+
+/**
+ * @brief get pixmap bytes of per pixel
+ * @param pixmap pointer to pixmap
+ * @return pixmap bytes of per pixel
+ */
+uint8_t sgl_pixmal_get_bytes_per_pixel(const sgl_pixmap_t *pixmap);
+
+
+/**
+ * @brief get tick milliseconds
+ * @param none
+ * @return tick milliseconds
+ */
+static inline uint32_t sgl_tick_get(void)
+{
+ return sgl_system.tick_ms;
+}
+
+
+/**
+ * @brief get last tick milliseconds
+ * @param none
+ * @return tick milliseconds
+ */
+static inline uint32_t sgl_last_tick_get(void)
+{
+ return sgl_system.last_tick;
+}
+
+
+/**
+ * @brief increase tick milliseconds
+ * @param ms milliseconds
+ * @return none
+ * @note in general, you should call this function in the 1ms tick interrupt handler
+ * of course, you can use polling function to increase tick milliseconds.
+ */
+static inline void sgl_tick_inc(uint32_t ms)
+{
+ sgl_system.tick_ms += ms;
+}
+
+
+/**
+ * @brief sync tick milliseconds
+ * @param none
+ * @return none
+ */
+static inline void sgl_tick_sync(void)
+{
+ sgl_system.last_tick = sgl_system.tick_ms;
+}
+
+
+/**
+ * @brief reset tick milliseconds
+ * @param none
+ * @return none
+ */
+static inline void sgl_tick_reset(void)
+{
+ sgl_system.tick_ms = 0;
+}
+
+
+/**
+* @brief converts the color value of an integer into a color structure
+* @param: color value
+* @return: sgl_color_t
+*/
+static inline sgl_color_t sgl_int2color(uint32_t color)
+{
+ sgl_color_t c;
+#if (CONFIG_SGL_FBDEV_PIXEL_DEPTH == 32)
+ c.full = color;
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == 24)
+ c.ch.blue = (uint8_t)color;
+ c.ch.green = (uint8_t)(color >> 8);
+ c.ch.red = (uint8_t)(color >> 16);
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == 16)
+ c.ch.blue = (uint8_t)(color & 0x1f);
+ c.ch.green = (uint8_t)((color >> 5) & 0x3f);
+ c.ch.red = (uint8_t)((color >> 11) & 0x1f);
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == 8)
+ c.ch.blue = (uint8_t)(color & 0x3);
+ c.ch.green = (uint8_t)((color >> 2) & 0x7);
+ c.ch.red = (uint8_t)((color >> 5) & 0x7);
+#endif
+ return c;
+}
+
+
+/**
+ * @brief converts the color structure into an integer
+ * @param: color structure
+ * @return: integer
+ */
+static inline uint32_t sgl_color2int(sgl_color_t color)
+{
+ uint32_t c;
+#if (CONFIG_SGL_FBDEV_PIXEL_DEPTH == 24)
+ c = color.ch.blue | (color.ch.green << 8) | (color.ch.red << 16);
+#else
+ c = color.full;
+#endif
+ return c;
+}
+
+
+/**
+* @brief Inline function that converts the color value of an (r,g,b) into a color structure
+* @param: red Red color component
+* @param: green Green color component
+* @param: blue Blue color component
+* @return: sgl_color_t
+*/
+static inline sgl_color_t sgl_rgb2color(uint8_t red, uint8_t green, uint8_t blue)
+{
+ sgl_color_t color;
+ color.ch.blue = blue;
+ color.ch.green = green;
+ color.ch.red = red;
+ return color;
+}
+
+
+/**
+ * @brief init object node
+ * @param obj: pointer of object
+ * @return none
+ */
+static inline void sgl_obj_node_init(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+
+ obj->sibling = NULL;
+ obj->child = NULL;
+}
+
+
+/**
+ * @brief add object to parent
+ * @param parent: pointer of parent object
+ * @param obj: pointer of object
+ * @return none
+ */
+void sgl_obj_add_child(sgl_obj_t *parent, sgl_obj_t *obj);
+
+
+/**
+ * @brief remove an object from its parent
+ * @param obj object to remove
+ * @return none
+ */
+void sgl_obj_remove(sgl_obj_t *obj);
+
+
+/**
+ * @brief check if object has child
+ * @param obj object
+ * @return true or false, true means object has child, false means object has no child
+ */
+static inline bool sgl_obj_has_child(sgl_obj_t *obj) {
+ SGL_ASSERT(obj != NULL);
+ return (bool)obj->child;
+}
+
+
+/**
+ * @brief get child of an object
+ * @param obj the object
+ * @return the child of the object
+ */
+static inline sgl_obj_t* sgl_obj_get_child(sgl_obj_t* obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return obj->child;
+}
+
+
+/**
+ * @brief check if object has sibling
+ * @param obj object
+ * @return true or false, true means object has sibling, false means object has no sibling
+ */
+static inline bool sgl_obj_has_sibling(sgl_obj_t *obj) {
+ SGL_ASSERT(obj != NULL);
+ return (bool)obj->sibling;
+}
+
+
+/**
+ * @brief get sibling of an object
+ * @param obj the object
+ * @return the sibling of the object
+ */
+static inline sgl_obj_t* sgl_obj_get_sibling(sgl_obj_t* obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return obj->sibling;
+}
+
+
+/**
+ * @brief get child count of an object
+ * @param obj object
+ * @return child count
+ */
+static inline size_t sgl_obj_get_child_count(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_obj_t *child = NULL;
+ size_t count = 0;
+
+ sgl_obj_for_each_child(child, obj) {
+ count ++;
+ }
+
+ return count;
+}
+
+
+/**
+ * @brief merge an area into global dirty area
+ *
+ * This function calculates how much rectangle 'a' would need to grow in each direction (left, right, top, bottom)
+ * to fully enclose both 'a' and 'b'. The result is the sum of the expansions along all four sides.
+ * Note: This is not the increase in area, th is a lightweight heuristic for merge cost in bounding-box algorithms.
+ *
+ * @param area [in] Pointer to the area
+ * @return none
+ */
+void sgl_dirty_area_push(sgl_area_t *area);
+
+
+/**
+ * @brief set system font
+ * @param font pointer to font
+ * @return none
+ */
+static inline void sgl_set_system_font(const sgl_font_t *font)
+{
+ SGL_ASSERT(font != NULL);
+ sgl_system.font = font;
+}
+
+
+/**
+ * @brief get system font
+ * @param none
+ * @return pointer to system font
+ */
+static inline const sgl_font_t* sgl_get_system_font(void)
+{
+ return sgl_system.font;
+}
+
+
+/**
+ * @brief Set the object to be destroyed
+ * @param obj: the object to set
+ * @retval None
+ * @note this function is used to set the destroyed flag of the object, then next draw cycle, the object will be removed
+ * the object should be not NULL.
+ */
+static inline void sgl_obj_set_destroyed(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->destroyed = 1;
+}
+
+
+/**
+ * @brief check object destroyed flag
+ * @param obj point to object
+ * @return flag, false - live, true - destroyed
+ */
+static inline bool sgl_obj_is_destroyed(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return (bool)obj->destroyed;
+}
+
+
+/**
+ * @brief Set object to dirty
+ * @param obj point to object
+ * @return none
+ * @note this function will set object to dirty, include its children
+ */
+static inline void sgl_obj_set_dirty(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->dirty = 1;
+}
+
+
+/**
+ * @brief Clear object dirty flag
+ * @param obj point to object
+ * @return none
+ */
+static inline void sgl_obj_clear_dirty(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->dirty = 0;
+}
+
+
+/**
+ * @brief Clear all dirty areas of the object and its children.
+ * @param[in] obj The object to clear.
+ * @return None
+ * @note This function is used to clear all dirty areas of the object and its children.
+ */
+void sgl_obj_clear_all_dirty(sgl_obj_t *obj);
+
+
+/**
+ * @brief check object dirty flag
+ * @param obj point to object
+ * @return flag, false - clear, true - dirty
+ */
+static inline bool sgl_obj_is_dirty(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return (bool)obj->dirty;
+}
+
+
+/**
+ * @brief set object need init coords
+ * @param obj point to object
+ * @return none
+ */
+static inline void sgl_obj_needinit(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->needinit = 1;
+}
+
+
+/**
+ * @brief check object if need init coords
+ * @param obj point to object
+ * @return flag, true - need init coords
+ */
+static inline bool sgl_obj_is_needinit(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return (bool)obj->needinit;
+}
+
+
+/**
+ * @brief clear object need init coords flag
+ * @param obj point to object
+ * @return none
+ */
+static inline void sgl_obj_clear_needinit(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->needinit = 0;
+}
+
+
+/**
+ * @brief set object hidden flag
+ * @param obj point to object
+ * @return none
+ */
+static inline void sgl_obj_set_hidden(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->hide = 1;
+ sgl_dirty_area_push(&obj->area);
+}
+
+
+/**
+ * @brief set object visible
+ * @param obj point to object
+ * @return none
+ */
+static inline void sgl_obj_set_visible(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->hide = 0;
+ sgl_dirty_area_push(&obj->area);
+}
+
+
+/**
+ * @brief check object hidden flag
+ * @param obj point to object
+ * @return flag, false - show, true - hidden
+ */
+static inline bool sgl_obj_is_hidden(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return (bool)obj->hide;
+}
+
+
+/**
+ * @brief set object to clickable
+ * @param obj point to object
+ * @return none
+ * @note if object is clickable, it can receive click events, otherwise it will not receive
+ */
+static inline void sgl_obj_set_clickable(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->clickable = 1;
+ obj->flexible = 1;
+}
+
+
+/**
+ * @brief set object to unclickable
+ * @param obj point to object
+ * @return none
+ * @note if object is clickable, it can receive click events, otherwise it will not receive
+ */
+static inline void sgl_obj_set_unclickable(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->clickable = 0;
+ obj->flexible = 0;
+}
+
+
+/**
+ * @brief check object is clickable
+ * @param obj point to object
+ * @return true: clickable, false: unclickable
+ */
+static inline bool sgl_obj_is_clickable(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return (bool)obj->clickable;
+}
+
+
+/**
+ * @brief set object flexible
+ * @param obj point to object
+ * @return none
+ */
+static inline void sgl_obj_set_flexible(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->flexible = 1;
+}
+
+
+/**
+ * @brief set object unflexible
+ * @param obj point to object
+ * @return none
+ */
+static inline void sgl_obj_set_unflexible(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->flexible = 0;
+}
+
+
+/**
+ * @brief check object flexible
+ * @param obj point to object
+ * @return true or false
+ */
+static inline bool sgl_obj_is_flexible(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return (bool)obj->flexible;
+}
+
+
+/**
+ * @brief set object clickable
+ * @param obj point to object
+ * @return none
+ */
+static inline void sgl_obj_set_movable(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->movable = 1;
+}
+
+
+/**
+ * @brief set object unmovable
+ * @param obj point to object
+ * @return none
+ */
+static inline void sgl_obj_set_unmovable(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->movable = 0;
+}
+
+
+/**
+ * @brief check object movable
+ * @param obj point to object
+ * @return true or false
+ */
+static inline bool sgl_obj_is_movable(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return (bool)obj->movable;
+}
+
+
+/**
+ * @brief update object area
+ * @param area point to area that need update
+ * @return none, this function will force update object area
+ */
+static inline void sgl_obj_update_area(sgl_area_t *area)
+{
+ sgl_dirty_area_push(area);
+}
+
+
+/**
+ * @brief move object child position
+ * @param obj point to object
+ * @param ofs_x: x offset position
+ * @param ofs_y: y offset position
+ * @return none
+ */
+void sgl_obj_move_child_pos(sgl_obj_t *obj, int16_t ofs_x, int16_t ofs_y);
+
+
+/**
+ * @brief move object child x position
+ * @param obj point to object
+ * @param ofs_x: x offset position
+ * @return none
+ */
+static inline void sgl_obj_move_child_pos_x(sgl_obj_t *obj, int16_t ofs_x)
+{
+ sgl_obj_move_child_pos(obj, ofs_x, 0);
+}
+
+
+/**
+ * @brief move object child y position
+ * @param obj point to object
+ * @param ofs_y: y offset position
+ * @return none
+ */
+static inline void sgl_obj_move_child_pos_y(sgl_obj_t *obj, int16_t ofs_y)
+{
+ sgl_obj_move_child_pos(obj, 0, ofs_y);
+}
+
+
+/**
+ * @brief zoom object size
+ * @param obj point to object
+ * @param zoom zoom size
+ * @return none
+ * @note if you want to zoom out, the zoom should be positive, if you want to zoom in, the zoom should be negative
+ */
+void sgl_obj_size_zoom(sgl_obj_t *obj, int16_t zoom);
+
+
+/**
+ * @brief move object up a level layout
+ * @param obj point to object
+ * @return none
+ * @note Only move among sibling objects
+ */
+void sgl_obj_move_up(sgl_obj_t *obj);
+
+
+/**
+ * @brief move object down a level layout
+ * @param obj point to object
+ * @return none
+ * @note Only move among sibling objects
+ */
+void sgl_obj_move_down(sgl_obj_t *obj);
+
+
+/**
+ * @brief move object top level layout
+ * @param obj point to object
+ * @return none
+ * @note Only move among sibling objects
+ */
+void sgl_obj_move_top(sgl_obj_t *obj);
+
+
+/**
+ * @brief move object bottom level layout
+ * @param obj point to object
+ * @return none
+ * @note Only move among sibling objects
+ */
+void sgl_obj_move_bottom(sgl_obj_t *obj);
+
+
+/**
+ * @brief Set object absolute position
+ * @param obj point to object
+ * @param abs_x: x absolute position
+ * @param abs_y: y absolute position
+ * @return none
+ */
+void sgl_obj_set_abs_pos(sgl_obj_t *obj, int16_t abs_x, int16_t abs_y);
+
+
+/**
+ * @brief Get object absolute position
+ * @param obj point to object
+ * @param abs_x: point to x absolute position
+ * @param abs_y: point to y absolute position
+ * @return none
+ */
+static inline sgl_pos_t sgl_obj_get_abs_pos(sgl_obj_t *obj)
+{
+ sgl_pos_t pos = {
+ .x = obj->coords.x1,
+ .y = obj->coords.y1
+ };
+ return pos;
+}
+
+
+/**
+ * @brief Set object relative position
+ * @param obj point to object
+ * @param x: x relative position
+ * @param y: y relative position
+ * @return none
+ * @note This x and y position is relative to the parent object
+ */
+static inline void sgl_obj_set_pos(sgl_obj_t *obj, int16_t x, int16_t y)
+{
+ sgl_obj_set_abs_pos(obj, obj->parent->coords.x1 + x, obj->parent->coords.y1 + y);
+}
+
+
+/**
+ * @brief Get object position
+ * @param obj point to object
+ * @return sgl_pos_t: position of object
+ * @note this function will return the top left corner position of the object relative to its parent
+ */
+static inline sgl_pos_t sgl_obj_get_pos(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+
+ sgl_pos_t pos;
+ pos.x = obj->coords.x1 - obj->parent->coords.x1;
+ pos.y = obj->coords.y1 - obj->parent->coords.y1;
+ return pos;
+}
+
+
+/**
+ * @brief Set object x relative position
+ * @param obj point to object
+ * @param x x position
+ * @return none
+ * @note this function will set the x position of the object, it's relative to the parent object
+ */
+static inline void sgl_obj_set_pos_x(sgl_obj_t *obj, int16_t x)
+{
+ sgl_obj_set_abs_pos(obj, obj->parent->coords.x1 + x, obj->coords.y1);
+}
+
+
+/**
+ * @brief Get object x relative position
+ * @param obj point to object
+ * @return x position, it's relative to the parent object
+ */
+static inline size_t sgl_obj_get_pos_x(sgl_obj_t *obj)
+{
+ return (obj->coords.x1 - obj->parent->coords.x1);
+}
+
+
+/**
+ * @brief Set object y relative position
+ * @param obj point to object
+ * @param y y position
+ * @return none
+ * @note this function will set the y position of the object, it's relative to the parent object
+ */
+static inline void sgl_obj_set_pos_y(sgl_obj_t *obj, int16_t y)
+{
+ sgl_obj_set_abs_pos(obj, obj->coords.x1, obj->parent->coords.y1 + y);
+}
+
+
+/**
+ * @brief Get object y relative position
+ * @param obj point to object
+ * @return y position, it's relative to the parent object
+ */
+static inline int16_t sgl_obj_get_pos_y(sgl_obj_t *obj)
+{
+ return obj->coords.y1 - obj->parent->coords.y1;
+}
+
+
+/**
+ * @brief Set the alignment position of the object relative to its parent object.
+ * @param obj The object to set the alignment position.
+ * @param type The alignment type.
+ * @return none
+ * @note type should be one of the sgl_align_type_t values:
+ * - SGL_ALIGN_CENTER : Center the object in the parent object.
+ * - SGL_ALIGN_TOP_MID : Align the object at the top middle of the parent object.
+ * - SGL_ALIGN_TOP_LEFT : Align the object at the top left of the parent object.
+ * - SGL_ALIGN_TOP_RIGHT : Align the object at the top right of the parent object.
+ * - SGL_ALIGN_BOT_MID : Align the object at the bottom middle of the parent object.
+ * - SGL_ALIGN_BOT_LEFT : Align the object at the bottom left of the parent object.
+ * - SGL_ALIGN_BOT_RIGHT : Align the object at the bottom right of the parent object.
+ * - SGL_ALIGN_LEFT_MID : Align the object at the left middle of the parent object.
+ * - SGL_ALIGN_RIGHT_MID : Align the object at the right middle of the parent object.
+ */
+void sgl_obj_set_pos_align(sgl_obj_t *obj, sgl_align_type_t type);
+
+
+/**
+ * @brief Set the alignment position of the object relative to its sibling object.
+ * @param ref The reference object, it should be the sibling object.
+ * @param obj The object to set the alignment position.
+ * @param type The alignment type.
+ * @return none
+ * @note type should be one of the sgl_align_type_t values:
+ * - SGL_ALIGN_VERT_LEFT : Align the object at the left side of the reference object.
+ * - SGL_ALIGN_VERT_RIGHT : Align the object at the right side of the reference object.
+ * - SGL_ALIGN_VERT_MID : Align the object at the middle of the reference object.
+ * - SGL_ALIGN_HORIZ_TOP : Align the object at the top side of the reference object.
+ * - SGL_ALIGN_HORIZ_BOT : Align the object at the bottom side of the reference object.
+ * - SGL_ALIGN_HORIZ_MID : Align the object at the middle of the reference object.
+ */
+void sgl_obj_set_pos_align_ref(sgl_obj_t *ref, sgl_obj_t *obj, sgl_align_type_t type);
+
+
+/**
+ * @brief Set object size
+ * @param obj point to object
+ * @param width: width that you want to set
+ * @param height: height that you want to set
+ * @return none
+ */
+static inline void sgl_obj_set_size(sgl_obj_t *obj, int16_t width, int16_t height)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->coords.x2 = obj->coords.x1 + width - 1;
+ obj->coords.y2 = obj->coords.y1 + height - 1;
+ sgl_obj_set_dirty(obj);
+}
+
+
+/**
+ * @brief Get object size
+ * @param obj point to object
+ * @return sgl_size_t: size of object
+ */
+static inline sgl_size_t sgl_obj_get_size(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_size_t size;
+ size.w = obj->coords.x2 - obj->coords.x1 + 1;
+ size.h = obj->coords.y2 - obj->coords.y1 + 1;
+ return size;
+}
+
+
+/**
+ * @brief Set object width
+ * @param obj point to object
+ * @param width: width that you want to set
+ * @return none
+ */
+static inline void sgl_obj_set_width(sgl_obj_t *obj, int16_t width)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->coords.x2 = obj->coords.x1 + width - 1;
+}
+
+
+/**
+ * @brief Get object width
+ * @param obj point to object
+ * @return object width
+ */
+static inline int16_t sgl_obj_get_width(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return obj->coords.x2 - obj->coords.x1 + 1;
+}
+
+
+/**
+ * @brief Set object height
+ * @param obj point to object
+ * @param height: height that you want to set
+ * @return none
+ */
+static inline void sgl_obj_set_height(sgl_obj_t *obj, int16_t height)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->coords.y2 = obj->coords.y1 + height - 1;
+}
+
+
+/**
+ * @brief Get object height
+ * @param obj point to object
+ * @return object height
+ */
+static inline int16_t sgl_obj_get_height(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return obj->coords.y2 - obj->coords.y1 + 1;
+}
+
+
+/**
+ * @brief Set object border width
+ * @param obj point to object
+ * @param border: border width that you want to set
+ * @return none
+ */
+static inline void sgl_obj_set_border_width(sgl_obj_t *obj, uint8_t border)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->border = sgl_min3(border, sgl_obj_get_width(obj) / 2, sgl_obj_get_height(obj) / 2);
+}
+
+
+/**
+ * @brief Get object border width
+ * @param obj point to object
+ * @return object border width
+ */
+static inline int16_t sgl_obj_get_border_width(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return obj->border;
+}
+
+
+/**
+ * @brief Get object fill rectangle
+ * @param obj point to object
+ * @return object fill rectangle
+ * @note This function is used to obtain the inner area of an object, i.e., the region excluding its borders.
+ */
+static inline sgl_area_t sgl_obj_get_fill_rect(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_area_t fill = {
+ .x1 = sgl_max(obj->coords.x1 + obj->border, obj->area.x1),
+ .y1 = sgl_max(obj->coords.y1 + obj->border, obj->area.y1),
+ .x2 = sgl_min(obj->coords.x2 - obj->border, obj->area.x2),
+ .y2 = sgl_min(obj->coords.y2 - obj->border, obj->area.y2),
+ };
+ return fill;
+}
+
+
+/**
+ * @brief Set object event callback function
+ * @param obj point to object
+ * @param event_fn: event callback function
+ * @param data: event callback function data
+ * @return none
+ */
+static inline void sgl_obj_set_event_cb(sgl_obj_t *obj, void (*event_fn)(sgl_event_t *e), void *data)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->event_fn = event_fn;
+ obj->event_data = data;
+ obj->clickable = 1;
+}
+
+
+/**
+ * @brief set the radius of object
+ * @param obj object
+ * @param radius: radius that you want to set
+ * @return none
+ * @note if radius is larger than object's width or height, fix radius will be returned
+ */
+void sgl_obj_set_radius(sgl_obj_t *obj, size_t radius);
+
+
+/**
+ * @brief get the radius of object
+ * @param obj object
+ * @return object radius
+ */
+static inline int16_t sgl_obj_get_radius(sgl_obj_t *obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return obj->radius;
+}
+
+
+/**
+ * @brief set current object as screen object
+ * @param obj object, that you want to set an object as active page
+ * @return none
+ */
+void sgl_screen_load(sgl_obj_t *obj);
+
+
+/**
+ * @brief get current screen object
+ * @param none
+ * @return active current screen object
+ */
+static inline sgl_obj_t* sgl_screen_act(void)
+{
+ return sgl_system.fbdev.active;
+}
+
+
+/**
+ * @brief get active page
+ * @param none
+ * @return page: active page
+ */
+static inline sgl_page_t* sgl_page_get_active(void)
+{
+ return (sgl_page_t*)sgl_system.fbdev.active;
+}
+
+
+/**
+ * @brief sgl task handle function with sync mode
+ * @param none
+ * @return none
+ * @note you can call this function to force update screen
+ */
+void sgl_task_handle_sync(void);
+
+
+/**
+ * @brief sgl task handle function
+ * @param none
+ * @return none
+ * @note this function should be called in main loop or timer or thread
+ */
+static inline void sgl_task_handle(void)
+{
+ /* If the system tick time has not been reached, skip directly. */
+ if ((sgl_tick_get() - sgl_last_tick_get()) < SGL_SYSTEM_TICK_MS) {
+ return;
+ }
+
+ sgl_tick_sync();
+ /* If the system tick time has been reached, execute the task. */
+ sgl_task_handle_sync();
+}
+
+
+/**
+ * @brief Create an object
+ * @param parent parent object
+ * @return sgl_obj_t
+ * @note if parent is NULL, the object will be as an new page
+ */
+sgl_obj_t* sgl_obj_create(sgl_obj_t *parent);
+
+
+/**
+ * @brief free an object
+ * @param obj: object to free
+ * @retval none
+ * @note this function will free all the children of the object
+ */
+void sgl_obj_free(sgl_obj_t *obj);
+
+
+/**
+ * @brief delete object
+ * @param obj point to object
+ * @return none
+ * @note this function will set object and his childs to be destroyed, then next draw cycle, the object will be removed.
+ * if object is NULL, the all objects of active page will be delete, but the page object will not be deleted.
+ * if object is a page, the page object will be deleted and all its children will be deleted.
+ */
+void sgl_obj_delete(sgl_obj_t *obj);
+
+
+/**
+ * @brief delete object
+ * @param obj point to object
+ * @return none
+ * @note this function will take effect immediately
+ */
+static inline void sgl_obj_delete_sync(sgl_obj_t *obj)
+{
+ sgl_obj_delete(obj);
+ sgl_task_handle_sync();
+}
+
+
+/**
+ * @brief color mixer
+ * @param fg_color : foreground color
+ * @param bg_color : background color
+ * @param factor : color mixer factor
+ * @return sgl_color_t: mixed color
+ */
+static inline sgl_color_t sgl_color_mixer(sgl_color_t fg_color, sgl_color_t bg_color, uint8_t factor)
+{
+ sgl_color_t ret;
+#if (CONFIG_SGL_FBDEV_PIXEL_DEPTH == SGL_COLOR_RGB332)
+
+ ret.ch.red = bg_color.ch.red + ((fg_color.ch.red - bg_color.ch.red) * (factor >> 5) >> 3);
+ ret.ch.green = bg_color.ch.green + ((fg_color.ch.green - bg_color.ch.green) * (factor >> 5) >> 3);
+ ret.ch.blue = bg_color.ch.blue + ((fg_color.ch.blue - bg_color.ch.blue) * (factor >> 6) >> 2);
+
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == SGL_COLOR_RGB565)
+
+ factor = (uint32_t)((uint32_t)factor + 4) >> 3;
+ uint32_t bg = (uint32_t)((uint32_t)bg_color.full | ((uint32_t)bg_color.full << 16)) & 0x07E0F81F;
+ uint32_t fg = (uint32_t)((uint32_t)fg_color.full | ((uint32_t)fg_color.full << 16)) & 0x07E0F81F;
+ uint32_t result = ((((fg - bg) * factor) >> 5) + bg) & 0x7E0F81F;
+ ret.full = (uint16_t)((result >> 16) | result);
+
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == SGL_COLOR_RGB888)
+
+ ret.ch.red = bg_color.ch.red + ((fg_color.ch.red - bg_color.ch.red) * factor >> 8);
+ ret.ch.green = bg_color.ch.green + ((fg_color.ch.green - bg_color.ch.green) * factor >> 8);
+ ret.ch.blue = bg_color.ch.blue + ((fg_color.ch.blue - bg_color.ch.blue) * factor >> 8);
+
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == SGL_COLOR_ARGB8888)
+
+ ret.ch.alpha = bg_color.ch.alpha + ((fg_color.ch.alpha - bg_color.ch.alpha) * factor >> 8);
+ ret.ch.red = bg_color.ch.red + ((fg_color.ch.red - bg_color.ch.red) * factor >> 8);
+ ret.ch.green = bg_color.ch.green + ((fg_color.ch.green - bg_color.ch.green) * factor >> 8);
+ ret.ch.blue = bg_color.ch.blue + ((fg_color.ch.blue - bg_color.ch.blue) * factor >> 8);
+
+#endif
+ return ret;
+}
+
+
+/**
+ * @brief Fills a block of memory with a solid color.
+ *
+ * Writes the specified `color` value to `len` consecutive elements starting at `dest`.
+ * This is equivalent to a memset-like operation but for color values (typically 32-bit RGBA).
+ *
+ * @param[out] dest Pointer to the start of the destination color buffer.
+ * @param[in] color The color value to fill with.
+ * @param[in] len Number of color elements to write (not bytes).
+ */
+static inline void sgl_color_set(sgl_color_t *dest, sgl_color_t color, uint32_t len)
+{
+ while (len--) {*dest++ = color; }
+}
+
+
+/**
+ * @brief area init
+ * @param area : area pointer
+ * @return none
+ */
+static inline void sgl_area_init(sgl_area_t *area)
+{
+ SGL_ASSERT(area != NULL);
+ area->x1 = area->y1 = SGL_POS_MAX;
+ area->x2 = area->y2 = SGL_POS_MIN;
+}
+
+
+/**
+ * @brief get pixel of pixmap
+ * @pixmap: pointe to pixmap
+ * @param x: x position
+ * @param y: y position
+ * @return sgl_color_t: pixel color
+ */
+static inline sgl_color_t sgl_pixmap_get_pixel(const sgl_pixmap_t *pixmap, int16_t x, int16_t y)
+{
+ SGL_ASSERT(pixmap != NULL);
+ return ((sgl_color_t*)pixmap->bitmap.array)[y * pixmap->width + x];
+}
+
+
+/**
+ * @brief get pixel of pixmap buf
+ * @pixmap: pointe to pixmap
+ * @param x: x position
+ * @param y: y position
+ * @return sgl_color_t: pixel color address
+ */
+static inline sgl_color_t* sgl_pixmap_get_buf(const sgl_pixmap_t *pixmap, int16_t x, int16_t y)
+{
+ SGL_ASSERT(pixmap != NULL);
+ return &((sgl_color_t*)pixmap->bitmap.array)[y * pixmap->width + x];
+}
+
+
+/**
+ * @brief check two area is overlap
+ * @param area_a area a
+ * @param area_b area b
+ * @return true or false, true means overlap, false means not overlap
+ * @note: this function is unsafe, you should check the area_a and area_b is not NULL by yourself
+ */
+static inline bool sgl_area_is_overlap(sgl_area_t *area_a, sgl_area_t *area_b)
+{
+ SGL_ASSERT(area_a != NULL && area_b != NULL);
+ if (area_b->y1 > area_a->y2 || area_b->y2 < area_a->y1 || area_b->x1 > area_a->x2 || area_b->x2 < area_a->x1) {
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * @brief check surf and other area is overlap
+ * @param surf surfcare
+ * @param area area b
+ * @return true or false, true means overlap, false means not overlap
+ * @note: this function is unsafe, you should check the surfcare and area is not NULL by yourself
+ */
+static inline bool sgl_surf_area_is_overlap(sgl_surf_t *surf, sgl_area_t *area)
+{
+ return sgl_area_is_overlap((sgl_area_t*)surf, area);
+}
+
+
+/**
+ * @brief Get area intersection between two areas
+ * @param area_a: area a
+ * @param area_b: area b
+ * @param clip: intersection area
+ * @return true: intersect, otherwise false
+ * @note: this function is unsafe, you should check the area_a and area_b and clip is not NULL by yourself
+ */
+bool sgl_area_clip(sgl_area_t *area_a, sgl_area_t *area_b, sgl_area_t *clip);
+
+
+/**
+ * @brief Get area intersection between surface and area
+ * @param surf: surface
+ * @param area: area
+ * @param clip: intersection area
+ * @return true: intersect, otherwise false
+ * @note: this function is unsafe, you should check the surf and area is not NULL by yourself
+ */
+static inline bool sgl_surf_clip(sgl_surf_t *surf, sgl_area_t *area, sgl_area_t *clip)
+{
+ return sgl_area_clip((sgl_area_t*)surf, area, clip);
+}
+
+
+/**
+ * @brief clip area with another area
+ * @param clip [in][out] clip area
+ * @param area [in] area
+ * @return true if clip area is valid, otherwise two area is not overlapped
+ * @note: this function is unsafe, you should check the clip and area is not NULL by yourself
+ */
+bool sgl_area_selfclip(sgl_area_t *clip, sgl_area_t *area);
+
+
+/**
+ * @brief merge two area, the merge is result of the two area clip
+ * @param area_a [in] area1
+ * @param area_b [in] area2
+ * @param merge [out] merge result
+ * @return none
+ * @note: this function is unsafe, you should check the area_a and area_b and merge is not NULL by yourself
+ */
+static inline void sgl_area_merge(sgl_area_t *area_a, sgl_area_t *area_b, sgl_area_t *merge)
+{
+ SGL_ASSERT(area_a != NULL && area_b != NULL && merge != NULL);
+ merge->x1 = sgl_min(area_a->x1, area_b->x1);
+ merge->x2 = sgl_max(area_a->x2, area_b->x2);
+ merge->y1 = sgl_min(area_a->y1, area_b->y1);
+ merge->y2 = sgl_max(area_a->y2, area_b->y2);
+}
+
+
+/**
+ * @brief merge two area, the merge is a new area
+ * @param merge [in][out] merge area
+ * @param area [in] area
+ * @return none
+ * @note: this function is unsafe, you should check the merge and area is not NULL by yourself
+ */
+static inline void sgl_area_selfmerge(sgl_area_t *merge, sgl_area_t *area)
+{
+ SGL_ASSERT(merge != NULL && area != NULL);
+ merge->x1 = sgl_min(merge->x1, area->x1);
+ merge->x2 = sgl_max(merge->x2, area->x2);
+ merge->y1 = sgl_min(merge->y1, area->y1);
+ merge->y2 = sgl_max(merge->y2, area->y2);
+}
+
+
+/**
+ * @brief sgl global initialization
+ * @param none
+ * @return int, 0 means success, others means failed
+ * @note You should call this function before using sgl and you should call this function after register framebuffer device.
+ * This function is unsafe, you should check the return value by yourself.
+ */
+int sgl_init(void);
+
+
+/**
+ * @brief initialize object
+ * @param obj object
+ * @param parent parent object
+ * @return int, 0 means successful, -1 means failed
+ */
+int sgl_obj_init(sgl_obj_t *obj, sgl_obj_t *parent);
+
+
+/**
+ * @brief Convert UTF-8 string to Unicode
+ * @param utf8_str Pointer to the UTF-8 string to be converted
+ * @param p_unicode_buffer Pointer to the buffer where the converted Unicode will be stored
+ * @return The number of bytes in the UTF-8 string
+ */
+uint32_t sgl_utf8_to_unicode(const char *utf8_str, uint32_t *p_unicode_buffer);
+
+
+/**
+ * @brief Search for the index of a Unicode character in the font table
+ * @param font Pointer to the font structure containing character data
+ * @param unicode Unicode of the character to be searched
+ * @return Index of the character in the font table
+ */
+uint32_t sgl_search_unicode_ch_index(const sgl_font_t *font, uint32_t unicode);
+
+
+/**
+ * @brief get height in font
+ * @param font pointer to sgl_font_t
+ * @return height of font, -1 means error
+ * @note this function is used to get the height of a character in a font
+ */
+static inline int16_t sgl_font_get_height(const sgl_font_t *font)
+{
+ SGL_ASSERT(font != NULL);
+ return font->font_height;
+}
+
+
+/**
+ * @brief get the width of a string
+ * @param str string
+ * @param font sgl font
+ * @return width of string
+ */
+int32_t sgl_font_get_string_width(const char *str, const sgl_font_t *font);
+
+
+/**
+ * @brief get the height of a string, which is in a rect area
+ * @param width width of the rect area
+ * @param str string
+ * @param font sgl font of the string
+ * @param line_space peer line space
+ * @return height size of string
+ */
+int32_t sgl_font_get_string_height(int16_t width, const char *str, const sgl_font_t *font, uint8_t line_space);
+
+
+/**
+ * @brief get the alignment position
+ * @param parent_size parent size
+ * @param size object size
+ * @param type alignment type
+ * @return alignment position
+ */
+sgl_pos_t sgl_get_align_pos(sgl_size_t *parent_size, sgl_size_t *size, sgl_align_type_t type);
+
+
+/**
+ * @brief get the text position in the area
+ * @param area point to area
+ * @param font point to font
+ * @param text text string
+ * @param offset text offset
+ * @param type alignment type
+ * @return sgl_pos_t position of text
+ */
+sgl_pos_t sgl_get_text_pos(sgl_area_t *area, const sgl_font_t *font, const char *text, int16_t offset, sgl_align_type_t type);
+
+
+/**
+ * @brief get the icon position of area
+ * @param area point to area
+ * @param icon point to icon
+ * @param offset offset
+ * @param type align type
+ */
+sgl_pos_t sgl_get_icon_pos(sgl_area_t *area, const sgl_icon_pixmap_t *icon, int16_t offset, sgl_align_type_t type);
+
+
+/**
+ * @brief set page background color
+ * @param obj point to object
+ * @param color background color
+ * @return none
+ */
+void sgl_page_set_color(sgl_obj_t* obj, sgl_color_t color);
+
+
+/**
+ * @brief set page background pixmap
+ * @param obj point to object
+ * @param pixmap background pixmap
+ * @return none
+ */
+void sgl_page_set_pixmap(sgl_obj_t* obj, const sgl_pixmap_t *pixmap);
+
+
+/**
+ * @brief set page background alpha
+ * @param obj point to object
+ * @param alpha background alpha
+ * @return none
+ */
+void sgl_page_set_alpha(sgl_obj_t* obj, uint8_t alpha);
+
+
+/**
+ * @brief get parent of an object
+ * @param obj the object
+ * @return the parent of the object
+ */
+static inline sgl_obj_t* sgl_obj_get_parent(sgl_obj_t* obj)
+{
+ SGL_ASSERT(obj != NULL);
+ return obj->parent;
+}
+
+
+/**
+ * @brief format a string, a simple version of vsnprintf
+ * @param buf buffer
+ * @param size buffer size
+ * @param fmt format string
+ * @param ap argument list
+ * @return number of characters written
+ */
+int sgl_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap);
+
+
+/**
+ * @brief format a string, a simple version of snprintf
+ * @param buf buffer
+ * @param size buffer size
+ * @param fmt format string
+ * @param ... arguments
+ * @return number of characters written
+ */
+int sgl_snprintf(char *buf, size_t size, const char *fmt, ...);
+
+
+#if (CONFIG_SGL_OBJ_USE_NAME)
+/**
+ * @brief set object name
+ * @param obj The object to set the name
+ * @param name The name to set.
+ * @return None.
+ */
+static inline void sgl_obj_set_name(sgl_obj_t *obj, const char *name)
+{
+ SGL_ASSERT(obj != NULL);
+ obj->name = name;
+}
+
+
+/**
+ * @brief print object name that include this all child
+ * @param obj point to object
+ * @return none
+ */
+void sgl_obj_print_name(sgl_obj_t *obj);
+
+#endif
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+
+#endif //__SGL_CORE_H__
diff --git a/User/system/sgl/include/sgl_draw.h b/User/system/sgl/include/sgl_draw.h
new file mode 100644
index 0000000..718bc21
--- /dev/null
+++ b/User/system/sgl/include/sgl_draw.h
@@ -0,0 +1,513 @@
+/* source/include/sgl_draw.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_DRAW_H__
+#define __SGL_DRAW_H__
+
+
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define SGL_ARC_MODE_NORMAL (0)
+#define SGL_ARC_MODE_RING (1)
+#define SGL_ARC_MODE_NORMAL_SMOOTH (2)
+#define SGL_ARC_MODE_RING_SMOOTH (3)
+
+
+/**
+ * @brief rect description
+ * @color: color of rect
+ * @alpha: alpha of rect
+ * @border: border of rect
+ * @border_color: border color of rect
+ * @pixmap: pixmap of rect
+ */
+typedef struct sgl_draw_rect {
+ sgl_color_t color;
+ int16_t radius;
+ uint8_t alpha;
+ uint8_t border;
+ sgl_color_t border_color;
+ const sgl_pixmap_t *pixmap;
+} sgl_draw_rect_t;
+
+
+/**
+ * @brief line draw description
+ * @x1: x1 coordinate
+ * @y1: y1 coordinate
+ * @x2: x2 coordinate
+ * @y2: y2 coordinate
+ * @color: color
+ * @alpha: alpha
+ * @width: width of line
+ */
+typedef struct sgl_draw_line {
+ int16_t x1;
+ int16_t y1;
+ int16_t x2;
+ int16_t y2;
+ sgl_color_t color;
+ uint8_t alpha;
+ uint8_t width;
+} sgl_draw_line_t;
+
+
+/**
+ * @brief rectangle description
+ * @cx: center x of rectangle
+ * @cy: center y of rectangle
+ * @color: color of rectangle
+ * @radius: radius of rectangle
+ * @alpha: alpha of rectangle
+ * @border: border of rectangle
+ * @border_color: border color of rectangle
+ * @pixmap: pixmap of rectangle
+ */
+typedef struct sgl_draw_circle {
+ int16_t cx;
+ int16_t cy;
+ sgl_color_t color;
+ int16_t radius;
+ uint8_t alpha;
+ uint8_t border;
+ sgl_color_t border_color;
+ const sgl_pixmap_t *pixmap;
+} sgl_draw_circle_t;
+
+
+/**
+ * @brief arc description
+ * @cx: center x
+ * @cy: center y
+ * @radius_in: inner radius of arc
+ * @radius_out: outer radius of arc
+ * @start_angle: start angle of arc
+ * @end_angle: end angle of arc
+ * @color: color of arc
+ * @alpha: alpha of arc
+ * @mode: mode of arc
+ * @bg_color: background color of arc
+ */
+typedef struct sgl_draw_arc {
+ int16_t cx;
+ int16_t cy;
+ int16_t radius_in;
+ int16_t radius_out;
+ sgl_color_t color;
+ uint8_t alpha;
+ uint32_t start_angle: 9;
+ uint32_t end_angle: 9;
+ uint32_t mode: 2;
+ sgl_color_t bg_color;
+} sgl_draw_arc_t;
+
+
+/**
+ * @brief icon description
+ * @icon: icon pixmap
+ * @color: icon color
+ * @alpha: alpha of icon
+ */
+typedef struct sgl_draw_icon {
+ const sgl_icon_pixmap_t *icon;
+ sgl_color_t color;
+ uint8_t alpha;
+ uint8_t align;
+} sgl_draw_icon_t;
+
+
+/**
+ * @brief clip area width of surface
+ * @note if you want to check the area is overlap with surface, you can use this macro
+ * it will direct return if the area is not overlap with surface, otherwise, continue
+ */
+#if (CONFIG_SGL_USE_FBDEV_VRAM)
+#define sgl_surf_clip_area_return(surf, rect, clip) do {SGL_UNUSED(rect);} while(0)
+#else
+#define sgl_surf_clip_area_return(surf, rect, clip) if (!sgl_surf_clip(surf, rect, clip)) return
+#endif
+
+
+/**
+ * @brief set pixel on surface
+ * @param surf: pointer of surface
+ * @param x: x coordinate
+ * @param y: y coordinate
+ * @param color: color of pixel
+ * @note this function is not clip, you should clip it before call this function, and the coordinate should be in the surface.
+ */
+static inline void sgl_surf_set_pixel(sgl_surf_t *surf, int16_t x, int16_t y, sgl_color_t color)
+{
+ surf->buffer[y * surf->w + x] = color;
+}
+
+
+/**
+ * @brief get start buffer address that to set pixel on surface
+ * @param surf: pointer of surface
+ * @param x: x coordinate
+ * @param y: y coordinate
+ * @return pointer of start buffer address
+ * @note this function is not clip, you should clip it before call this function, and the coordinate should be in the surface.
+ */
+static inline sgl_color_t* sgl_surf_get_buf(sgl_surf_t *surf, int16_t x, int16_t y)
+{
+ return &surf->buffer[y * surf->w + x];
+}
+
+
+/**
+ * @brief get pixel on surface
+ * @param surf: pointer of surface
+ * @param x: x coordinate
+ * @param y: y coordinate
+ * @return color of pixel
+ * @note this function is not clip, you should clip it before call this function, and the coordinate should be in the surface.
+ */
+static inline sgl_color_t sgl_surf_get_pixel(sgl_surf_t *surf, int16_t x, int16_t y)
+{
+ return surf->buffer[y * surf->w + x];
+}
+
+
+/**
+ * @brief draw a horizontal line on surface
+ * @param surf: pointer of surface
+ * @param y: y coordinate
+ * @param x1: x1 coordinate
+ * @param x2: x2 coordinate
+ * @param color: color of line
+ * @note this function is not clip, you should clip it before call this function, and the coordinate should be in the surface.
+ */
+static inline void sgl_surf_hline(sgl_surf_t *surf, int16_t y, int16_t x1, int16_t x2, sgl_color_t color)
+{
+ sgl_color_t *dst = surf->buffer + y * surf->w + x1;
+ for (int16_t i = x1; i <= x2; i++) {
+ *dst = color;
+ dst++;
+ }
+}
+
+
+/**
+ * @brief draw a vertical line on surface
+ * @param surf: pointer of surface
+ * @param x: x coordinate
+ * @param y1: y1 coordinate
+ * @param y2: y2 coordinate
+ * @param color: color of line
+ * @note this function is not clip, you should clip it before call this function, and the coordinate should be in the surface.
+ */
+static inline void sgl_surf_vline(sgl_surf_t *surf, int16_t x, int16_t y1, int16_t y2, sgl_color_t color)
+{
+ sgl_color_t *dst = surf->buffer + y1 * surf->w + x;
+ for (int16_t i = y1; i <= y2; i++) {
+ *dst = color;
+ dst += surf->w;
+ }
+}
+
+
+/**
+ * @brief fill a round rectangle with alpha
+ * @param surf point to surface
+ * @param area area of rectangle that you want to draw
+ * @param rect point to rectangle that you want to draw
+ * @param radius radius of round
+ * @param color color of rectangle
+ * @param alpha alpha of rectangle
+ * @return none
+ */
+void sgl_draw_fill_rect(sgl_surf_t *surf, sgl_area_t *area, sgl_area_t *rect, int16_t radius, sgl_color_t color, uint8_t alpha);
+
+
+/**
+ * @brief fill a round rectangle with alpha and border
+ * @param surf point to surface
+ * @param area area of rectangle that you want to draw
+ * @param rect point to rectangle that you want to draw
+ * @param radius radius of round
+ * @param color color of rectangle
+ * @param border_color color of border
+ * @param border_width width of border
+ * @param alpha alpha of rectangle
+ * @return none
+ */
+void sgl_draw_fill_rect_with_border(sgl_surf_t *surf, sgl_area_t *area, sgl_area_t *rect, int16_t radius, sgl_color_t color, sgl_color_t border_color, uint8_t border_width, uint8_t alpha);
+
+
+/**
+ * @brief fill a round rectangle pixmap with alpha
+ * @param surf point to surface
+ * @param area area of rectangle that you want to draw
+ * @param rect point to rectangle that you want to draw
+ * @param radius radius of round
+ * @param pixmap pixmap of rectangle
+ * @param alpha alpha of rectangle
+ * @return none
+ */
+void sgl_draw_fill_rect_pixmap(sgl_surf_t *surf, sgl_area_t *area, sgl_area_t *rect, int16_t radius, const sgl_pixmap_t *pixmap, uint8_t alpha);
+
+
+/**
+ * @brief fill a round rectangle with alpha
+ * @param surf point to surface
+ * @param area area of rectangle that you want to draw
+ * @param rect point to rectangle that you want to draw
+ * @param desc rectangle description
+ * @return none
+ */
+void sgl_draw_rect(sgl_surf_t *surf, sgl_area_t *area, sgl_rect_t *rect, sgl_draw_rect_t *desc);
+
+
+/**
+ * @brief Draw a circle
+ * @param surf Surface
+ * @param area Area of the circle
+ * @param cx X coordinate of the center
+ * @param cy Y coordinate of the center
+ * @param radius Radius of the circle
+ * @param color Color of the circle
+ * @param alpha Alpha of the circle
+ * @return none
+ */
+void sgl_draw_fill_circle(sgl_surf_t *surf, sgl_area_t *area, int16_t cx, int16_t cy, int16_t radius, sgl_color_t color, uint8_t alpha);
+
+
+/**
+ * @brief Draw a circle with pixmap and alpha
+ * @param surf Surface
+ * @param area Area of the circle
+ * @param cx X coordinate of the center
+ * @param cy Y coordinate of the center
+ * @param radius Radius of the circle
+ * @param pixmap Pixmap of image
+ * @param alpha Alpha of the circle
+ * @return none
+ */
+void sgl_draw_fill_circle_pixmap(sgl_surf_t *surf, sgl_area_t *area, int16_t cx, int16_t cy, int16_t radius, const sgl_pixmap_t *pixmap, uint8_t alpha);
+
+
+/**
+ * @brief Draw a circle with alpha and border
+ * @param surf Surface
+ * @param area Area of the circle
+ * @param cx X coordinate of the center
+ * @param cy Y coordinate of the center
+ * @param radius Radius of the circle
+ * @param color Color of the circle
+ * @param border_color Color of the border
+ * @param border_width Width of the border
+ * @param alpha Alpha of the circle
+ * @return none
+ */
+
+void sgl_draw_fill_circle_with_border(sgl_surf_t *surf, sgl_area_t *area, int16_t cx, int16_t cy, int16_t radius, sgl_color_t color, sgl_color_t border_color, int16_t border_width, uint8_t alpha);
+
+
+/**
+ * @brief draw task, the task contains the draw information and canvas
+ * @param surf surface pointer
+ * @param area the area of the task
+ * @param desc the draw information
+ * @return none
+ */
+void sgl_draw_circle(sgl_surf_t *surf, sgl_area_t *area, sgl_draw_circle_t *desc);
+
+
+/**
+ * @brief draw icon with alpha
+ * @param surf surface
+ * @param area area of icon
+ * @param coords coords of icon
+ * @param icon icon pixmap
+ * @param alpha alpha of icon
+ */
+void sgl_draw_icon( sgl_surf_t *surf, sgl_area_t *area, int16_t x, int16_t y, sgl_color_t color, uint8_t alpha, const sgl_icon_pixmap_t *icon);
+
+
+/**
+ * @brief Draw a character on the surface with alpha blending
+ * @param surf Pointer to the surface where the character will be drawn
+ * @param area Pointer to the area where the character will be drawn
+ * @param x X coordinate where the character will be drawn
+ * @param y Y coordinate where the character will be drawn
+ * @param ch_index Index of the character in the font table
+ * @param color Foreground color of the character
+ * @param alpha Alpha value for blending
+ * @param font Pointer to the font structure containing character data
+ * @return none
+ * @note this function is only support bpp:4
+ */
+void sgl_draw_character( sgl_surf_t *surf, sgl_area_t *area, int16_t x, int16_t y, uint32_t ch_index, sgl_color_t color, uint8_t alpha, const sgl_font_t *font);
+
+
+/**
+ * @brief Draw a string on the surface with alpha blending
+ * @param surf Pointer to the surface where the string will be drawn
+ * @param area Pointer to the area where the string will be drawn
+ * @param x X coordinate of the top-left corner of the string
+ * @param y Y coordinate of the top-left corner of the string
+ * @param str Pointer to the string to be drawn
+ * @param color Foreground color of the string
+ * @param alpha Alpha value for blending
+ * @param font Pointer to the font structure containing character data
+ * @return none
+ */
+void sgl_draw_string(sgl_surf_t *surf, sgl_area_t *area, int16_t x, int16_t y, const char *str, sgl_color_t color, uint8_t alpha, const sgl_font_t *font);
+
+
+/**
+ * @brief Draw a string on the surface with alpha blending and multiple lines
+ * @param surf Pointer to the surface where the string will be drawn
+ * @param area Pointer to the area where the string will be drawn
+ * @param x X coordinate of the top-left corner of the string
+ * @param y Y coordinate of the top-left corner of the string
+ * @param str Pointer to the string to be drawn
+ * @param color Foreground color of the string
+ * @param alpha Alpha value for blending
+ * @param font Pointer to the font structure containing character data
+ * @param line_margin Margin between lines
+ * @return none
+ */
+void sgl_draw_string_mult_line(sgl_surf_t *surf, sgl_area_t *area, int16_t x, int16_t y, const char *str, sgl_color_t color, uint8_t alpha, const sgl_font_t *font, uint8_t line_margin);
+
+
+/**
+ * @brief draw a ring on surface with alpha
+ * @param surf: pointer of surface
+ * @param area: pointer of area
+ * @param cx: ring center x
+ * @param cy: ring center y
+ * @param radius_in: ring inner radius
+ * @param radius_out: ring outer radius
+ * @param color: ring color
+ * @param alpha: ring alpha
+ * @return none
+ */
+void sgl_draw_fill_ring(sgl_surf_t *surf, sgl_area_t *area, int16_t cx, int16_t cy, int16_t radius_in, int16_t radius_out, sgl_color_t color, uint8_t alpha);
+
+
+/**
+ * @brief draw a horizontal line with alpha
+ * @param surf surface
+ * @param area area that contains the line
+ * @param y line y position
+ * @param x1 line start x position
+ * @param x2 line end x position
+ * @param color line color
+ * @param alpha alpha of color
+ * @return none
+ */
+void sgl_draw_fill_hline(sgl_surf_t *surf, sgl_area_t *area, int16_t y, int16_t x1, int16_t x2, uint8_t width, sgl_color_t color, uint8_t alpha);
+
+
+/**
+ * @brief draw a vertical line with alpha
+ * @param surf surface
+ * @param area area that contains the line
+ * @param x x coordinate
+ * @param y1 y1 coordinate
+ * @param y2 y2 coordinate
+ * @param color line color
+ * @param alpha alpha of color
+ * @return none
+ */
+void sgl_draw_fill_vline(sgl_surf_t *surf, sgl_area_t *area, int16_t x, int16_t y1, int16_t y2, uint8_t width, sgl_color_t color, uint8_t alpha);
+
+
+/**
+ * @brief draw a slanted line with alpha
+ * @param surf surface
+ * @param area area that contains the line
+ * @param x1 line start x position
+ * @param y1 line start y position
+ * @param x2 line end x position
+ * @param y2 line end y position
+ * @param thickness line width
+ * @param color line color
+ * @param alpha alpha of color
+ * @return none
+ * @note This algorithm is SDF algorithm
+ */
+void draw_line_fill_slanted(sgl_surf_t *surf, sgl_area_t *area, int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t thickness, sgl_color_t color, uint8_t alpha);
+
+
+/**
+ * @brief draw a line
+ * @param surf surface
+ * @param area area that contains the line
+ * @param desc line description
+ * @return none
+ */
+void sgl_draw_line(sgl_surf_t *surf, sgl_area_t *area, sgl_draw_line_t *desc);
+
+
+/**
+ * @brief draw an arc with alpha
+ * @param surf pointer to surface
+ * @param area pointer to area
+ * @param desc pointer to arc description
+ * @return none
+ */
+void sgl_draw_fill_arc(sgl_surf_t *surf, sgl_area_t *area, sgl_draw_arc_t *desc);
+
+
+/**
+ * @brief calculate a point color by bilinear interpolate
+ * @param buffer point to image pixmap start buffer
+ * @param w width of buffer
+ * @param h height of buffer
+ * @param fx x coordinate of point
+ * @param fy y coordinate of point
+ * @return point color
+ */
+sgl_color_t sgl_draw_biln_color(const sgl_color_t *buffer, int16_t w, int16_t h, int32_t fx, int32_t fy);
+
+
+/**
+ * @brief transform a surface
+ * @param dst destination surface
+ * @param src source surface
+ * @param area area of surface
+ * @param x x coordinate of surface
+ * @param y y coordinate of surface
+ * @param rotation rotation angle
+ * @return none
+ * @note This function has implemented angle normalization to the range of 0 to 360 degrees.
+ */
+void sgl_draw_xform_surf(sgl_surf_t *dst, sgl_surf_t *src, sgl_area_t *area, int16_t x, int16_t y, int16_t rotation);
+
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif
diff --git a/User/system/sgl/include/sgl_errno.h b/User/system/sgl/include/sgl_errno.h
new file mode 100644
index 0000000..9bc1f1d
--- /dev/null
+++ b/User/system/sgl/include/sgl_errno.h
@@ -0,0 +1,170 @@
+/* source/include/sgl_errno.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#ifndef __SGL_ERRNO_H__
+#define __SGL_ERRNO_H__
+
+#define OK 0 /* No error */
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* I/O error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Argument list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file number */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Try again */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device or resource busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* File table overflow */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Not a typewriter */
+#define ETXTBSY 26 /* Text file busy */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Math argument out of domain of func */
+#define ERANGE 34 /* Math result not representable */
+
+#define EDEADLK 35 /* Resource deadlock would occur */
+#define ENAMETOOLONG 36 /* File name too long */
+#define ENOLCK 37 /* No record locks available */
+#define ENOSYS 38 /* Function not implemented */
+#define ENOTEMPTY 39 /* Directory not empty */
+#define ELOOP 40 /* Too many symbolic links encountered */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define ENOMSG 42 /* No message of desired type */
+#define EIDRM 43 /* Identifier removed */
+#define ECHRNG 44 /* Channel number out of range */
+#define EL2NSYNC 45 /* Level 2 not synchronized */
+#define EL3HLT 46 /* Level 3 halted */
+#define EL3RST 47 /* Level 3 reset */
+#define ELNRNG 48 /* Link number out of range */
+#define EUNATCH 49 /* Protocol driver not attached */
+#define ENOCSI 50 /* No CSI structure available */
+#define EL2HLT 51 /* Level 2 halted */
+#define EBADE 52 /* Invalid exchange */
+#define EBADR 53 /* Invalid request descriptor */
+#define EXFULL 54 /* Exchange full */
+#define ENOANO 55 /* No anode */
+#define EBADRQC 56 /* Invalid request code */
+#define EBADSLT 57 /* Invalid slot */
+
+#define EDEADLOCK EDEADLK
+#define EBFONT 59 /* Bad font file format */
+#define ENOSTR 60 /* Device not a stream */
+#define ENODATA 61 /* No data available */
+#define ETIME 62 /* Timer expired */
+#define ENOSR 63 /* Out of streams resources */
+#define ENONET 64 /* Machine is not on the network */
+#define ENOPKG 65 /* Package not installed */
+#define EREMOTE 66 /* Object is remote */
+#define ENOLINK 67 /* Link has been severed */
+#define EADV 68 /* Advertise error */
+#define ESRMNT 69 /* Srmount error */
+#define ECOMM 70 /* Communication error on send */
+#define EPROTO 71 /* Protocol error */
+#define EMULTIHOP 72 /* Multihop attempted */
+#define EDOTDOT 73 /* RFS specific error */
+#define EBADMSG 74 /* Not a data message */
+#define EOVERFLOW 75 /* Value too large for defined data type */
+#define ENOTUNIQ 76 /* Name not unique on network */
+#define EBADFD 77 /* File descriptor in bad state */
+#define EREMCHG 78 /* Remote address changed */
+#define ELIBACC 79 /* Can not access a needed shared library */
+#define ELIBBAD 80 /* Accessing a corrupted shared library */
+#define ELIBSCN 81 /* .lib section in a.out corrupted */
+#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
+
+#define ELIBEXEC 83 /* Cannot exec a shared library directly */
+#define EILSEQ 84 /* Illegal byte sequence */
+#define ERESTART 85 /* Interrupted system call should be restarted */
+#define ESTRPIPE 86 /* Streams pipe error */
+#define EUSERS 87 /* Too many users */
+#define ENOTSOCK 88 /* Socket operation on non-socket */
+#define EDESTADDRREQ 89 /* Destination address required */
+#define EMSGSIZE 90 /* Message too long */
+#define EPROTOTYPE 91 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 92 /* Protocol not available */
+#define EPROTONOSUPPORT 93 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
+#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
+#define EPFNOSUPPORT 96 /* Protocol family not supported */
+#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
+#define EADDRINUSE 98 /* Address already in use */
+#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
+#define ENETDOWN 100 /* Network is down */
+#define ENETUNREACH 101 /* Network is unreachable */
+#define ENETRESET 102 /* Network dropped connection because of reset */
+#define ECONNABORTED 103 /* Software caused connection abort */
+#define ECONNRESET 104 /* Connection reset by peer */
+#define ENOBUFS 105 /* No buffer space available */
+#define EISCONN 106 /* Transport endpoint is already connected */
+#define ENOTCONN 107 /* Transport endpoint is not connected */
+#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS 109 /* Too many references: cannot splice */
+#define ETIMEDOUT 110 /* Connection timed out */
+#define ECONNREFUSED 111 /* Connection refused */
+#define EHOSTDOWN 112 /* Host is down */
+#define EHOSTUNREACH 113 /* No route to host */
+#define EALREADY 114 /* Operation already in progress */
+#define EINPROGRESS 115 /* Operation now in progress */
+#define ESTALE 116 /* Stale file handle */
+#define EUCLEAN 117 /* Structure needs cleaning */
+#define ENOTNAM 118 /* Not a XENIX named type file */
+#define ENAVAIL 119 /* No XENIX semaphores available */
+#define EISNAM 120 /* Is a named type file */
+#define EREMOTEIO 121 /* Remote I/O error */
+#define EDQUOT 122 /* Quota exceeded */
+
+#define ENOMEDIUM 123 /* No medium found */
+#define EMEDIUMTYPE 124 /* Wrong medium type */
+#define ECANCELED 125 /* Operation Canceled */
+#define ENOKEY 126 /* Required key not available */
+#define EKEYEXPIRED 127 /* Key has expired */
+#define EKEYREVOKED 128 /* Key has been revoked */
+#define EKEYREJECTED 129 /* Key was rejected by service */
+
+/* for robust mutexes */
+#define EOWNERDEAD 130 /* Owner died */
+#define ENOTRECOVERABLE 131 /* State not recoverable */
+#define ERFKILL 132 /* Operation not possible due to RF-kill */
+#define EHWPOISON 133 /* Memory page has hardware error */
+
+#endif // !__SGL_ERRNO_H__
diff --git a/User/system/sgl/include/sgl_event.h b/User/system/sgl/include/sgl_event.h
new file mode 100644
index 0000000..7097e8d
--- /dev/null
+++ b/User/system/sgl/include/sgl_event.h
@@ -0,0 +1,220 @@
+/* source/include/sgl_event.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_EVENT_H__
+#define __SGL_EVENT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include
+#include
+#include
+#include
+
+
+/* Forward declaration of sgl_obj and sgl_page*/
+struct sgl_obj;
+struct sgl_page;
+
+
+/**
+ * @brief Event type enumeration
+ * @note The event type is used to describe the type of event, such as click,
+ * long press, etc. The event type is used to distinguish different events,
+ * and the event type is used to trigger different callbacks
+ */
+#define SGL_EVENT_NULL (0)
+#define SGL_EVENT_NORMAL (1)
+#define SGL_EVENT_PRESSED (2)
+#define SGL_EVENT_RELEASED (3)
+#define SGL_EVENT_CLICKED (4)
+#define SGL_EVENT_LONG_CLICKED (5)
+#define SGL_EVENT_MOTION (6)
+#define SGL_EVENT_MOVE_UP (7)
+#define SGL_EVENT_MOVE_DOWN (8)
+#define SGL_EVENT_MOVE_LEFT (9)
+#define SGL_EVENT_MOVE_RIGHT (10)
+#define SGL_EVENT_LONG_PRESSED (11)
+#define SGL_EVENT_OPTION_WALK (12)
+#define SGL_EVENT_OPTION_TAP (13)
+#define SGL_EVENT_DRAW_INIT (14)
+#define SGL_EVENT_DRAW_MAIN (15)
+#define SGL_EVENT_FOCUSED (16)
+#define SGL_EVENT_UNFOCUSED (17)
+#define SGL_EVENT_DESTROYED (18)
+#define sgl_event_type_t uint8_t
+
+
+#define SGL_EVENT_CLICK_INTERVAL (CONFIG_SGL_EVENT_CLICK_INTERVAL)
+
+/**
+* @brief Event location structure, Used to represent the coordinates of an event,
+* such as the click position of the mouse, the click position of the touch screen,
+* and so on
+*
+* @x: x coordinate
+* @y: y coordinate
+*/
+typedef struct sgl_event_pos {
+ int16_t x;
+ int16_t y;
+} sgl_event_pos_t;
+
+
+typedef struct sgl_event {
+ struct sgl_obj *obj;
+ void *param;
+ sgl_event_pos_t pos;
+ uint16_t type;
+ uint16_t distance;
+} sgl_event_t;
+
+
+/**
+ * @brief Initialize the event queue
+ * @param none
+ * @return 0 on success, -1 on failure
+ * @note !!!!!! the SGL_EVENT_QUEUE_SIZE must be power of 2 !!!!!!
+ * You must check the return value of this function.
+ */
+int sgl_event_queue_init(void);
+
+
+/**
+ * @brief Push an event into the event queue
+ * @param event The event to be pushed
+ * @return 0 on success, -1 on failure
+ */
+void sgl_event_queue_push(sgl_event_t event);
+
+
+/**
+ * @brief Handle the position event
+ * @param pos The position to be handled
+ * @param type The type of the event
+ * @return none
+ */
+void sgl_event_send_pos(sgl_event_pos_t pos, sgl_event_type_t type);
+
+
+/**
+ * @brief Send an event to the specified object
+ * @param event The event to be sent
+ * @return none
+ */
+static inline void sgl_event_send(sgl_event_t event)
+{
+ sgl_event_queue_push(event);
+}
+
+
+/**
+ * @brief Send an event to the specified object
+ * @param obj The object to be sent
+ * @param type The type of the event
+ * @return none
+ * @note This function is used to send an event to the specified object, for example,
+ * if you want to send an event to the button, you can call:
+ * ---- press button case : sgl_event_send_obj(button, SGL_EVENT_PRESSED);
+ * ---- release button case: sgl_event_send_obj(button, SGL_EVENT_RELEASED);
+ *
+ * @tip: You can also send you own event to the specified object, for example,
+ * The MY_EVENT_TYPE is defined by you, and you can use it in your own event handler, for example:
+ * ...
+ * sgl_event_send_obj(button, MY_EVENT_TYPE);
+ * ...
+ * void my_event_handler(sgl_event_t *event)
+ * {
+ * if (event->type == MY_EVENT_TYPE) {
+ * // do something
+ * }
+ * }
+ */
+static inline void sgl_event_send_obj(struct sgl_obj *obj, sgl_event_type_t type)
+{
+ sgl_event_t event = {0};
+ event.obj = obj;
+ event.type = type;
+ sgl_event_send(event);
+}
+
+
+/**
+ * @brief Send a motion event to the specified object
+ * @param pos The position of the motion event
+ * @param type The type of the motion event
+ * @param distance The distance of the motion event
+ * @return none
+ */
+static inline void sgl_event_send_motion(sgl_event_pos_t pos, sgl_event_type_t type, uint16_t distance)
+{
+ sgl_event_t event = {0};
+ event.pos = pos;
+ event.type = type;
+ event.distance = distance;
+ sgl_event_send(event);
+}
+
+
+/**
+ * @brief All event task in SGL, this function will traverse all elements in the event queue,
+ * respond to each element with an event, so that all events will trigger and point to the
+ * corresponding callback function
+ * @param none
+ * @return none
+*/
+void sgl_event_task(void);
+
+
+/**
+ * @brief Touch event read, this function will be called by user
+ * @param x: touch x position
+ * @param y: touch y position
+ * @param flag: touch flag, it means touch event down or up:
+ * true : touch down
+ * false: touch up
+ * @return none
+ * @note: for example, you can call it in 30ms tick handler function
+ * void example_30ms_tick_handler(void)
+ * {
+ * int pos_x, pos_y;
+ * bool button_status;
+ *
+ * bsp_touch_read_pos(&pos_x, &pos_y);
+ * button_status = bsp_touch_read_status();
+ *
+ * sgl_event_pos_input(pos_x, pos_y, button_status);
+ * }
+ */
+void sgl_event_pos_input(int16_t x, int16_t y, bool flag);
+
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif //!__SGL_EVENT_H__
diff --git a/User/system/sgl/include/sgl_font.h b/User/system/sgl/include/sgl_font.h
new file mode 100644
index 0000000..9775a4e
--- /dev/null
+++ b/User/system/sgl/include/sgl_font.h
@@ -0,0 +1,66 @@
+/* source/include/sgl_font.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#ifndef __SGL_FONT_H__
+#define __SGL_FONT_H__
+
+
+#include
+#include
+#include
+#include
+#include
+
+/* declare all font */
+
+#if CONFIG_SGL_FONT_SONG23
+extern const sgl_font_t song23;
+#endif
+
+#if CONFIG_SGL_FONT_CONSOLAS14
+extern const sgl_font_t consolas14;
+#endif
+
+#if CONFIG_SGL_FONT_CONSOLAS23
+extern const sgl_font_t consolas23;
+#endif
+
+#if CONFIG_SGL_FONT_CONSOLAS24
+extern const sgl_font_t consolas24;
+#endif
+
+#if CONFIG_SGL_FONT_CONSOLAS32
+extern const sgl_font_t consolas32;
+#endif
+
+#if CONFIG_SGL_FONT_KAI33
+extern const sgl_font_t kai33;
+#endif
+
+#if CONFIG_SGL_FONT_CONSOLAS24_COMPRESS
+extern const sgl_font_t consolas24_compress;
+#endif
+
+#endif // !__SGL_FONT_H__
diff --git a/User/system/sgl/include/sgl_list.h b/User/system/sgl/include/sgl_list.h
new file mode 100644
index 0000000..7bb08dd
--- /dev/null
+++ b/User/system/sgl/include/sgl_list.h
@@ -0,0 +1,307 @@
+/* source/include/sgl_list.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_LIST_H__
+#define __SGL_LIST_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include
+#include
+
+
+/**
+ * @prev: previous node of the list.
+ * @next: next node of the list.
+ */
+typedef struct sgl_list_node {
+ struct sgl_list_node *prev;
+ struct sgl_list_node *next;
+}sgl_list_node_t;
+
+#define SGL_LIST_HEAD(name) \
+ sgl_list_node_t name = {.prev = &(name), .next = &(name)}
+
+
+/**
+ * @brief foreach the list.
+ *
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @list_head: the head for your list.
+ *
+ * @return none
+ */
+#define sgl_list_for_each(pos, list_head) \
+ for (pos = (list_head)->next; pos != (list_head); pos = pos->next)
+
+
+/**
+ * @brief Return the next entry of specific node.
+ *
+ * @entry: specific entry.
+ *
+ * @return entry_type: next entry of specific entry.
+ */
+#define sgl_list_next_entry(entry, entry_type, list_node_member) \
+ sgl_container_of(entry->list_node_member.next, entry_type, list_node_member)
+
+
+/**
+ * @brief Return the previous entry of specific node.
+ *
+ * @entry: specific entry.
+ *
+ * @return entry_type: previous entry of specific entry.
+ */
+#define sgl_list_prev_entry(entry, entry_type, list_node_member) \
+ sgl_container_of(entry->list_node_member.prev, entry_type, list_node_member)
+
+
+/**
+ * @brief foreach the list inserted in a structure.
+ *
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @list_head: the head for your list.
+ * @entry_type: type of the struct.
+ * @list_node_member: member name of the list_node in structure.
+ *
+ * @return none
+ */
+#define sgl_list_for_each_entry(pos, list_head, entry_type, list_node_member) \
+ for (pos = sgl_container_of((list_head)->next, entry_type, list_node_member); \
+ &pos->list_node_member != (list_head); \
+ pos = sgl_container_of(pos->list_node_member.next, entry_type, list_node_member))
+
+
+/**
+ * @brief safe foreach the list inserted in a structure.
+ *
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @list_head: the head for your list.
+ * @entry_type: type of the struct.
+ * @list_node_member: member name of the list_node in structure.
+ *
+ * @return none
+ */
+#define sgl_list_for_each_entry_safe(pos, n, list_head, entry_type, list_node_member) \
+ for (pos = (list_head)->next ? sgl_container_of((list_head)->next, entry_type, list_node_member) : NULL, \
+ n = pos ? sgl_container_of(pos->list_node_member.next, entry_type, list_node_member) : NULL; \
+ &pos->list_node_member != (list_head); \
+ pos = n, \
+ n = pos ? (pos->list_node_member.next ? sgl_container_of(pos->list_node_member.next, entry_type, list_node_member) : NULL) : NULL)
+
+
+/**
+ * @brief reverse foreach the list inserted in a structure.
+ *
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @list_head: the head for your list.
+ * @entry_type: type of the struct.
+ * @list_node_member: member name of the list_node in structure.
+ *
+ * @return none
+ */
+#define sgl_list_for_each_entry_reverse(pos, list_head, entry_type, list_node_member) \
+ for (pos = sgl_container_of((list_head)->prev, entry_type, list_node_member); \
+ &pos->list_node_member != (list_head); \
+ pos = sgl_container_of(pos->list_node_member.prev, entry_type, list_node_member))
+
+
+/**
+ * @brief initialize a list.
+ *
+ * @node: inserted node.
+ *
+ * @return none
+ */
+static inline void sgl_list_init(sgl_list_node_t *node)
+{
+ node->next = node;
+ node->prev = node;
+}
+
+
+/**
+ * @brief Add a node to the list tail.
+ *
+ * @head: head node of the list.
+ * @node: inserted node.
+ *
+ * @return none
+ */
+static inline void sgl_list_add_node_at_tail(sgl_list_node_t *head, sgl_list_node_t *node)
+{
+ sgl_list_node_t *tail = head->prev;
+
+ node->prev = tail;
+ node->next = head;
+ tail->next = node;
+ head->prev = node;
+}
+
+
+/**
+ * @brief Add a node to the list front.
+ *
+ * @head: head node of the list.
+ * @node: inserted node.
+ *
+ * @return none
+ */
+static inline void sgl_list_add_node_at_front(sgl_list_node_t *head, sgl_list_node_t *node)
+{
+ sgl_list_node_t *front = head->next;
+
+ node->prev = head;
+ node->next = front;
+ front->prev = node;
+ head->next = node;
+}
+
+
+/**
+ * @brief Add a node to the list before a specific node.
+ * @pos: specific node.
+ * @node: inserted node.
+ * @return none
+ */
+static inline void sgl_list_add_node_at_before(sgl_list_node_t *pos, sgl_list_node_t *node)
+{
+ node->prev = pos->prev;
+ node->next = pos;
+ pos->prev->next = node;
+ pos->prev = node;
+}
+
+
+/**
+ * @brief Add a node to the list after a specific node.
+ * @pos: specific node.
+ * @node: inserted node.
+ * @return none
+ */
+static inline void sgl_list_add_node_at_after(sgl_list_node_t *pos, sgl_list_node_t *node)
+{
+ node->next = pos->next;
+ node->prev = pos;
+ pos->next->prev = node;
+ pos->next = node;
+}
+
+
+/**
+ * @brief Delete a tail node from the list.
+ *
+ * @head: head node of the list.
+ *
+ * @return none
+ */
+static inline void sgl_list_del_tail_node(sgl_list_node_t *head)
+{
+ sgl_list_node_t *tail_prev = head->prev->prev;
+
+ tail_prev->next = head;
+ head->prev = tail_prev;
+}
+
+
+/**
+ * @brief Delete a front node from the list.
+ *
+ * @head: head node of the list.
+ *
+ * @return none
+ */
+static inline void sgl_list_del_front_node(sgl_list_node_t *head)
+{
+ sgl_list_node_t *front_next = head->next->next;
+
+ front_next->prev = head;
+ head->next = front_next;
+}
+
+
+/**
+ * @brief Delete a node from the list.
+ *
+ * @node: the node of the list.
+ *
+ * @return none
+ */
+static inline void sgl_list_del_node(sgl_list_node_t *node)
+{
+ node->prev->next = node->next;
+ node->next->prev = node->prev;
+}
+
+
+/**
+ * @brief Determine whether the list is empty.
+ *
+ * @head: head node of the list.
+ *
+ * @return bool: is empty.
+ */
+static inline bool sgl_list_is_empty(sgl_list_node_t *head)
+{
+ return head->next == head;
+}
+
+
+/**
+ * @brief Return the next node of specific node.
+ *
+ * @node: specific node.
+ *
+ * @return list_node*: next node of specific node.
+ */
+static inline sgl_list_node_t* sgl_list_next_node(sgl_list_node_t *node)
+{
+ return node->next;
+}
+
+
+/**
+ * @brief Return the previous node of specific node.
+ *
+ * @node: specific node.
+ *
+ * @return list_node*: previous node of specific node.
+ */
+static inline sgl_list_node_t* sgl_list_prev_node(sgl_list_node_t *node)
+{
+ return node->prev;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // __SGL_LIST_H__
diff --git a/User/system/sgl/include/sgl_log.h b/User/system/sgl/include/sgl_log.h
new file mode 100644
index 0000000..569f7d4
--- /dev/null
+++ b/User/system/sgl/include/sgl_log.h
@@ -0,0 +1,193 @@
+/* source/include/sgl_log.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_LOG_H__
+#define __SGL_LOG_H__
+
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define SGL_LOG_LEVEL_TRACE 0 /**< A lot of logs to give detailed information*/
+#define SGL_LOG_LEVEL_INFO 1 /**< Log important events*/
+#define SGL_LOG_LEVEL_WARN 2 /**< Log if something unwanted happened but didn't caused problem*/
+#define SGL_LOG_LEVEL_ERROR 3 /**< Only critical issue, when the system may fail*/
+#define SGL_LOG_LEVEL_USER 4 /**< Custom logs from the user*/
+#define SGL_LOG_LEVEL_NONE 5 /**< Do not log anything*/
+#define _SGL_LOG_LEVEL_NUM 6 /**< Number of log levels*/
+
+
+#if CONFIG_SGL_DEBUG
+
+/**
+ * @brief sgl log printing function, used to print debugging information. Note that this function
+ * should only be called in debugging mode, otherwise it may affect system real-time
+ * performance due to long execution time
+ *
+ * @param level: log level, such as, INFO, USER...
+ * @param format: log content
+ *
+ * @return none
+*/
+void sgl_log(const char *level, const char * format, ...);
+
+
+/**
+ * @brief sgl assert handler, used to handle assertions
+ *
+ * @param file: file name
+ * @param func: function name
+ * @param line: line number
+ *
+ * @return none
+*/
+void sgl_assert_handler(const char *file, const char *func, int line);
+
+
+#if CONFIG_SGL_LOG_COLOR
+
+#define SGL_LOG_NONE "\033[0m"
+#define SGL_LOG_RED "\033[31m"
+#define SGL_LOG_GREEN "\033[32m"
+#define SGL_LOG_YELLOW "\033[33m"
+#define SGL_LOG_BLUE "\033[34m"
+#define SGL_LOG_PURPLE "\033[35m"
+#define SGL_LOG_CYAN "\033[36m"
+#define SGL_LOG_WHITE "\033[37m"
+#define SGL_LOG_LIGHT_BLUE "\033[1;34m"
+
+
+#define SGL_LOG_TRACE_FLAG SGL_LOG_BLUE"[TRACE]"
+#define SGL_LOG_INFO_FLAG SGL_LOG_GREEN"[INFO]"
+#define SGL_LOG_WARN_FLAG SGL_LOG_YELLOW"[WARN]"
+#define SGL_LOG_ERROR_FLAG SGL_LOG_RED"[ERROR]"
+#define SGL_LOG_USER_FLAG SGL_LOG_PURPLE"[USER]"
+#define SGL_ASSERT_FLAG SGL_LOG_CYAN"[ASSERT]"
+#define SGL_DEBUG_TRACE_FLAG SGL_LOG_LIGHT_BLUE"[DEBUG]"
+
+
+#else
+#define SGL_LOG_TRACE_FLAG "[TRACE] "
+#define SGL_LOG_INFO_FLAG "[INFO] "
+#define SGL_LOG_WARN_FLAG "[WARN] "
+#define SGL_LOG_ERROR_FLAG "[ERROR] "
+#define SGL_LOG_USER_FLAG "[USER] "
+#define SGL_ASSERT_FLAG "[ASSERT] "
+#define SGL_DEBUG_TRACE_FLAG "[DEBUG]"
+#define SGL_LOG_NONE ""
+
+#endif // !CONFIG_SGL_LOG_COLOR
+
+
+#ifndef SGL_LOG_TRACE
+# if CONFIG_SGL_LOG_LEVEL <= SGL_LOG_LEVEL_TRACE
+# define SGL_LOG_TRACE(...) sgl_log(SGL_LOG_TRACE_FLAG, __VA_ARGS__)
+# else
+# define SGL_LOG_TRACE(...) do {} while(0)
+# endif
+#endif
+
+#ifndef SGL_LOG_INFO
+# if CONFIG_SGL_LOG_LEVEL <= SGL_LOG_LEVEL_INFO
+# define SGL_LOG_INFO(...) sgl_log(SGL_LOG_INFO_FLAG, __VA_ARGS__)
+# else
+# define SGL_LOG_INFO(...) do {} while(0)
+# endif
+#endif
+
+#ifndef SGL_LOG_WARN
+# if CONFIG_SGL_LOG_LEVEL <= SGL_LOG_LEVEL_WARN
+# define SGL_LOG_WARN(...) sgl_log(SGL_LOG_WARN_FLAG, __VA_ARGS__)
+# else
+# define SGL_LOG_WARN(...) do {} while(0)
+# endif
+#endif
+
+#ifndef SGL_LOG_ERROR
+# if CONFIG_SGL_LOG_LEVEL <= SGL_LOG_LEVEL_ERROR
+# define SGL_LOG_ERROR(...) sgl_log(SGL_LOG_ERROR_FLAG, __VA_ARGS__)
+# else
+# define SGL_LOG_ERROR(...) do {} while(0)
+# endif
+#endif
+
+#ifndef SGL_LOG_USER
+# if CONFIG_SGL_LOG_LEVEL <= SGL_LOG_LEVEL_USER
+# define SGL_LOG_USER(...) sgl_log(SGL_LOG_USER_FLAG, __VA_ARGS__)
+# else
+# define SGL_LOG_USER(...) do {} while(0)
+# endif
+#endif
+
+#if CONFIG_SGL_LOG_LEVEL < SGL_LOG_LEVEL_NONE
+# define SGL_LOG(...) sgl_log(__VA_ARGS__)
+#else
+# define SGL_LOG(...) do {} while(0)
+#endif
+
+
+#define SGL_ASSERT(cond) do { \
+ if (!(cond)) { \
+ sgl_assert_handler(__FILE__, __FUNCTION__, __LINE__); \
+ } \
+ } while(0)
+
+#define SGL_ASSERT_INFO(cond, info) do { \
+ if (!(cond)) { \
+ SGL_LOG_ERROR("ASSERT: %s", info); \
+ sgl_assert_handler(__FILE__, __FUNCTION__, __LINE__); \
+ } \
+ } while(0)
+
+#else // if no define debug mode macro
+
+#define SGL_LOG_NONE 0
+#define SGL_LOG_TRACE(...) do {} while(0)
+#define SGL_LOG_INFO(...) do {} while(0)
+#define SGL_LOG_WARN(...) do {} while(0)
+#define SGL_LOG_ERROR(...) do {} while(0)
+#define SGL_LOG_USER(...) do {} while(0)
+#define SGL_LOG(...) do {} while(0)
+
+#define SGL_ASSERT(cond) do {} while(0)
+#define SGL_ASSERT_INFO(cond, info) do {} while(0)
+#endif
+
+
+#if CONFIG_SGL_DEBUG
+#define SGL_DEBUG_TRACE(...) sgl_log(SGL_DEBUG_TRACE_FLAG, __VA_ARGS__)
+#else
+#define SGL_DEBUG_TRACE(...) do {} while(0)
+#endif
+
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif //!__SGL_LOG_H__
diff --git a/User/system/sgl/include/sgl_math.h b/User/system/sgl/include/sgl_math.h
new file mode 100644
index 0000000..9252ae7
--- /dev/null
+++ b/User/system/sgl/include/sgl_math.h
@@ -0,0 +1,188 @@
+/* source/include/sgl_math.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_MATH_H__
+#define __SGL_MATH_H__
+
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define sgl_min(a, b) ((a) < (b) ? (a) : (b))
+#define sgl_min3(a, b, c) (sgl_min(sgl_min((a), (b)), (c)))
+#define sgl_min4(a, b, c, d) (sgl_min(sgl_min((a), (b)), sgl_min((c), (d))))
+
+
+#define sgl_max(a, b) ((a) > (b) ? (a) : (b))
+#define sgl_max3(a, b, c) (sgl_max(sgl_max((a), (b)), (c)))
+#define sgl_max4(a, b, c, d) (sgl_max(sgl_max((a), (b)), sgl_max((c), (d))))
+
+#define sgl_clamp(val, min, max) (sgl_max(min, (sgl_min((val), (max)))))
+
+#define sgl_abs(x) ((x) > 0 ? (x) : (- (x)))
+
+#define sgl_pow2(x) ((x) * (x))
+#define sgl_pow3(x) ((x) * (x) * (x))
+#define sgl_pow4(x) ((x) * (x) * (x) * (x))
+
+#define sgl_is_pow2(x) (((x) & ((x) - 1)) == 0)
+#define sgl_is_even(x) (((x) & 1) == 0)
+#define sgl_is_odd(x) ((x) & 1)
+
+#define sgl_swap(a, b) do { (*a) ^= (*b); (*b) ^= (*a); (*a) ^= (*b); } while (0)
+
+#define sgl_mid(a, b) (((a) + (b)) / 2)
+
+#define SGL_FIXED_SHIFT (10)
+#define SGL_FIXED_ONE (1 << SGL_FIXED_SHIFT)
+#define SGL_FIXED_MASK (SGL_FIXED_ONE - 1)
+
+#define SGL_SIN_FIXED_ONE (32767)
+#define SGL_COS_FIXED_ONE (32767)
+
+/**
+ * @brief Calculate the sine of an angle
+ * @param angle: Angle in degrees such 0-359
+ * @return sine of the angle from sin0_90_table
+ * @note This function has implemented angle normalization to the range of 0 to 360 degrees.
+ */
+int32_t sgl_sin(int16_t angle);
+
+
+/**
+ * @brief Calculate the cos of an angle
+ * @param angle: Angle in degrees such 0-359
+ * @return cos of the angle from sin0_90_table
+ * @note This function has implemented angle normalization to the range of 0 to 360 degrees.
+ */
+static inline int32_t sgl_cos(int16_t angle)
+{
+ return sgl_sin(angle + 90);
+}
+
+
+/**
+ * @brief Calculate x number square root
+ * @param x: x number
+ * @retval x number square root
+ */
+uint16_t sgl_sqrt(uint32_t x);
+
+
+/**
+ * @brief Calculate error of the square root for a number.
+ * @param x The number to calculate the error for.
+ * @return The error of the square root. [0 ~ 255]
+ */
+uint8_t sgl_sqrt_error(uint32_t x);
+
+
+/**
+ * @brief Calculate the angle based on the x and y coordinates. This function is a fast algorithm
+ * implementation, with reference address: www.RomanBlack.com (Fast XY vector to integer degree algorithm)
+ *
+ * @param x: The x coordinate on a circle
+ * @param y: The y coordinate on a circle
+ * @return angle
+ * @note return angle [-32767 ~ 32767]
+ */
+int32_t sgl_atan2_raw(int x, int y);
+
+
+/**
+ * @brief Calculate the angle based on the x and y coordinates. This function is a fast algorithm
+ * implementation, with reference address: www.RomanBlack.com (Fast XY vector to integer degree algorithm)
+ *
+ * @param x: The x coordinate on a circle
+ * @param y: The y coordinate on a circle
+ * @return angle
+ * @note return angle [0 ~ 359]
+*/
+uint16_t sgl_atan2_angle(int x, int y);
+
+
+/**
+ * @brief Split the length into n parts, with the weight of each part.
+ * @param weight: The weight of each part.
+ * @param count: The count of parts.
+ * @param length: The length to split.
+ * @param gap: The gap between each part.
+ * @param out: The length of each part.
+ * @note The error accumulation method of Bresenham's algorithm
+ */
+void sgl_split_len(const uint8_t *weight, int count, int16_t length, int16_t gap, int16_t *out);
+
+
+/**
+ * @brief Split the length into n parts, with the weight of each part.
+ * @param length: The length to split.
+ * @param count: The count of parts.
+ * @param gap: The gap between each part.
+ * @param out: The length of each part.
+ * @note The average method of Bresenham's algorithm
+ */
+void sgl_split_len_avg(int length, int count, int16_t gap, int16_t *out);
+
+
+/**
+ * @brief Calculate whether the x and y coordinates have a component.
+ * @param x: The x coordinate on a circle
+ * @param y: The y coordinate on a circle
+ * @param xv: The x coordinate of the vector
+ * @param yv: The y coordinate of the vector
+ * @return 1: The x and y coordinates have a component. 0: The x and y coordinates do not have a component.
+ */
+static inline int sgl_xy_has_component( int x, int y, int xv, int yv)
+{
+ return ((x != 0 && ((xv ^ x) < 0)) || (y != 0 && ((yv ^ y) < 0)));
+}
+
+
+/**
+ * @brief Generate a random number.
+ * @param none
+ * @return Random number.
+ * @note The random number generator is in the range of [0, 32767].
+ */
+int16_t sgl_rand(void);
+
+
+/**
+ * @brief Set the seed of the random number generator.
+ * @param seed: The seed of the random number generator.
+ * @return none
+ */
+void sgl_srand(unsigned int seed);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !__SGL_MATH_H__
diff --git a/User/system/sgl/include/sgl_misc.h b/User/system/sgl/include/sgl_misc.h
new file mode 100644
index 0000000..5447606
--- /dev/null
+++ b/User/system/sgl/include/sgl_misc.h
@@ -0,0 +1,53 @@
+/* source/include/sgl_misc.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_MISC_H__
+#define __SGL_MISC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+#include
+
+#if (CONFIG_SGL_BOOT_LOGO)
+
+/**
+ * @brief to show the sgl logo after sgl init
+ * @param none
+ * @return none
+ * @note: you can call this function in your main function to show the sgl logo
+ */
+void sgl_boot_logo(void);
+
+#endif // ! CONFIG_SGL_BOOT_LOGO
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif // ! __SGL_MISC_H__
diff --git a/User/system/sgl/include/sgl_mm.h b/User/system/sgl/include/sgl_mm.h
new file mode 100644
index 0000000..c7fb148
--- /dev/null
+++ b/User/system/sgl/include/sgl_mm.h
@@ -0,0 +1,112 @@
+/* source/include/sgl_mm.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_MM_H__
+#define __SGL_MM_H__
+
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief memory monitor info
+ * @total_size: total size of memory
+ * @free_size: free size of memory
+ * @used_size: used size of memory
+ * @used_rate: used rate of memory:
+ * | 8 bit | 8 bit |
+ * | int | dec |
+ */
+typedef struct sgl_mm_monitor {
+ size_t total_size;
+ size_t free_size;
+ size_t used_size;
+ size_t used_rate;
+
+} sgl_mm_monitor_t;
+
+
+/**
+ * @brief initialize memory pool
+ * @param mem_start start address of memory pool
+ * @param len length of memory pool
+ */
+void sgl_mm_init(void *mem_start, size_t len);
+
+
+/**
+ * @brief add memory pool
+ * @param mem_start start address of memory pool
+ * @param len length of memory pool
+ */
+void sgl_mm_add_pool(void *mem_start, size_t len);
+
+
+/**
+ * @brief memory alloc, the function is unsafe, you should ensure that
+ * the requested size is smaller than the free size of memory
+ *
+ * @param size request size of memory
+ *
+ * @return point to request memory address
+*/
+void* sgl_malloc(size_t size);
+
+
+/**
+ * @brief memory realloc, the function is unsafe, you should ensure that
+ * the requested size is smaller than the free size of memory
+ * @param p the pointer of request size of memory
+ * @param size request size of memory
+ */
+void* sgl_realloc(void *p, size_t size);
+
+
+/**
+ * @brief memory free
+ *
+ * @param p the pointer of request size of memory
+ *
+ * @return none
+*/
+void sgl_free(void *p);
+
+
+/**
+ * @brief get memory monitor info
+ *
+ * @param none
+ * @return memory monitor info
+ */
+sgl_mm_monitor_t sgl_mm_get_monitor(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !__SGL_MM_H__
diff --git a/User/system/sgl/include/sgl_theme.h b/User/system/sgl/include/sgl_theme.h
new file mode 100644
index 0000000..79e40c1
--- /dev/null
+++ b/User/system/sgl/include/sgl_theme.h
@@ -0,0 +1,79 @@
+/* source/include/sgl_theme.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_THEME_H__
+#define __SGL_THEME_H__
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if (CONFIG_SGL_THEME_DEFAULT)
+#define SGL_THEME_DESKTOP sgl_rgb(255, 255, 255)
+#define SGL_THEME_COLOR sgl_rgb(255, 255, 255)
+#define SGL_THEME_BG_COLOR sgl_rgb(0, 0, 0)
+#define SGL_THEME_BORDER_WIDTH 2
+#define SGL_THEME_BORDER_COLOR sgl_rgb(0, 0, 0)
+#define SGL_THEME_ALPHA 255
+#define SGL_THEME_TEXT_COLOR sgl_rgb(0, 0, 0)
+#define SGL_THEME_RADIUS 0
+#define SGL_THEME_SCROLL_RADIUS 3
+#define SGL_THEME_SCROLL_BG_COLOR sgl_rgb(100, 100, 100)
+#define SGL_THEME_SCROLL_FG_COLOR sgl_rgb(200, 200, 200)
+
+
+#elif (CONFIG_SGL_THEME_DARK)
+#define SGL_THEME_DESKTOP sgl_rgb(10, 10, 10)
+#define SGL_THEME_COLOR sgl_rgb(50, 50, 50)
+#define SGL_THEME_BG_COLOR sgl_rgb(20, 20, 20)
+#define SGL_THEME_BORDER_WIDTH 2
+#define SGL_THEME_BORDER_COLOR sgl_rgb(200, 200, 200)
+#define SGL_THEME_ALPHA 255
+#define SGL_THEME_TEXT_COLOR sgl_rgb(200, 200, 200)
+#define SGL_THEME_RADIUS 0
+#define SGL_THEME_SCROLL_BG_COLOR sgl_rgb(100, 100, 100)
+#define SGL_THEME_SCROLL_FG_COLOR sgl_rgb(200, 200, 200)
+
+
+#elif (CONFIG_SGL_THEME_LIGHT)
+#define SGL_THEME_COLOR sgl_rgb(189, 212, 243)
+#define SGL_THEME_BG_COLOR sgl_rgb(255, 255, 255)
+#define SGL_THEME_BORDER_WIDTH 2
+#define SGL_THEME_BORDER_COLOR sgl_rgb(0, 0, 0)
+#define SGL_THEME_ALPHA 255
+#define SGL_THEME_TEXT_COLOR sgl_rgb(0, 0, 0)
+#define SGL_THEME_RADIUS 0
+#define SGL_THEME_SCROLL_BG_COLOR sgl_rgb(100, 100, 100)
+#define SGL_THEME_SCROLL_FG_COLOR sgl_rgb(200, 200, 200)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/User/system/sgl/include/sgl_types.h b/User/system/sgl/include/sgl_types.h
new file mode 100644
index 0000000..9e5303e
--- /dev/null
+++ b/User/system/sgl/include/sgl_types.h
@@ -0,0 +1,337 @@
+/* source/include/sgl_types.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_TYPES_H__
+#define __SGL_TYPES_H__
+
+
+#include
+#include
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Get the offset of internal members of the structure
+ *
+ * @struct_t: structure typedef
+ * @member: member in structure
+ *
+ * @return offset of member in the structure
+*/
+#define sgl_offsetof(struct_t, member) ((size_t)&((struct_t*)0)->member)
+
+
+/**
+ * @brief Get the address of the structure instance.
+ *
+ * @ptr: address of the structure member.
+ * @type: type of the structure.
+ * @member: member name of the ptr in structure.
+ * @return pointer to address of structure
+ */
+#define sgl_container_of(ptr, type, member) ((type *)((char *)ptr - sgl_offsetof(type, member)))
+
+
+#ifndef SGL_ARRAY_SIZE
+#define SGL_ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+#endif
+
+
+#define SGL_ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
+#define SGL_ROUND_UP(x, round) ((((x) + ((round) - 1)) / (round)) * (round))
+
+#define SGL_UNUSED(x) (void)(x)
+
+
+#define SGL_POS_INVALID (0xefff)
+#define SGL_POS_MAX (8192)
+#define SGL_POS_MIN (-8192)
+#define SGL_RADIUS_INVALID (0xFFF)
+
+#define SGL_AREA_MAX {.x1 = SGL_POS_MIN, .y1 = SGL_POS_MIN, .x2 = SGL_POS_MAX, .y2 = SGL_POS_MAX}
+#define SGL_AREA_INVALID {.x1 = SGL_POS_MAX, .y1 = SGL_POS_MAX, .x2 = SGL_POS_MIN, .y2 = SGL_POS_MIN}
+
+#define SGL_WIDTH_INVALID (-1)
+#define SGL_WIDTH_MAX (8192)
+#define SGL_WIDTH_MIN (0)
+#define SGL_HEIGHT_INVALID (-1)
+#define SGL_HEIGHT_MAX (8192)
+#define SGL_HEIGHT_MIN (0)
+
+
+#define SGL_DIRECT_HORIZONTAL (0)
+#define SGL_DIRECT_VERTICAL (1)
+
+
+#define SGL_ALPHA_MAX (255)
+#define SGL_ALPHA_MIN (0)
+#define SGL_ALPHA_NUM (256)
+
+
+#define SGL_STYLE_OK (0)
+#define SGL_STYLE_FAILED (UINT32_MAX)
+#define SGL_STYLE_INVALID (UINT32_MAX)
+
+
+#define SGL_COLOR_RGB332 (8)
+#define SGL_COLOR_RGB565 (16)
+#define SGL_COLOR_RGB888 (24)
+#define SGL_COLOR_ARGB8888 (32)
+
+/* the pixmap format */
+#define SGL_PIXMAP_FMT_NONE (0)
+#define SGL_PIXMAP_FMT_RGB332 (1)
+#define SGL_PIXMAP_FMT_ARGB2222 (2)
+#define SGL_PIXMAP_FMT_RGB565 (3)
+#define SGL_PIXMAP_FMT_ARGB4444 (4)
+#define SGL_PIXMAP_FMT_RGB888 (5)
+#define SGL_PIXMAP_FMT_ARGB8888 (6)
+#define SGL_PIXMAP_FMT_RLE_RGB332 (7)
+#define SGL_PIXMAP_FMT_RLE_ARGB2222 (8)
+#define SGL_PIXMAP_FMT_RLE_RGB565 (9)
+#define SGL_PIXMAP_FMT_RLE_ARGB4444 (10)
+#define SGL_PIXMAP_FMT_RLE_RGB888 (11)
+#define SGL_PIXMAP_FMT_RLE_ARGB8888 (12)
+#define SGL_PIXMAP_FMT_MAX (13)
+
+
+#ifdef __GNUC__ /* gcc compiler */
+#ifndef likely
+# define likely(x) __builtin_expect(!!(x), 1)
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+#define sgl_weak_fn __attribute__((weak))
+#define sgl_section(sec) __attribute__((section(#sec)))
+#elif defined(__clang__) /* clang compiler */
+#ifndef likely
+# define likely(x) __builtin_expect(!!(x), 1)
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+#define sgl_weak_fn __attribute__((weak))
+#define sgl_section(sec) __attribute__((section(#sec)))
+#elif defined(__CC_ARM) /* RealView compiler (Keil ARMCC) */
+#ifndef likely
+# define likely(x) __builtin_expect(!!(x), 1)
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+#define sgl_weak_fn __weak
+#define sgl_section(sec) __attribute__((section(#sec)))
+#elif defined(__ICCARM__) /* IAR compiler */
+#ifndef likely
+# define likely(x) __iar_builtin_expect(!!(x), 1)
+# define unlikely(x) __iar_builtin_expect(!!(x), 0)
+#endif
+#define sgl_weak_fn __weak
+#define sgl_section(sec) __section(#sec)
+#elif defined(_MSC_VER) /* MSVC compiler */
+#ifndef likely
+# define likely(x) (x)
+# define unlikely(x) (x)
+#endif
+#define sgl_weak_fn __declspec(selectany)
+#elif defined(__MINGW32__) /* MinGW compiler */
+#ifndef likely
+# define likely(x) __builtin_expect(!!(x), 1)
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+#define sgl_weak_fn __attribute__((weak))
+#define sgl_section(sec) __attribute__((section(#sec)))
+#else /* others compiler */
+#ifndef likely
+# define likely(x) (x)
+# define unlikely(x) (x)
+#endif
+#warning "Weak linkage not supported for this compiler"
+#endif
+
+
+#define sgl_check_ptr_break(ptr) if (unlikely((ptr) == NULL)) { SGL_LOG_ERROR("Function: %s, Line: %d, "#ptr" is NULL", __func__, __LINE__); return;}
+#define sgl_check_ptr_return(ptr, r) if (unlikely((ptr) == NULL)) { SGL_LOG_ERROR("Function: %s, Line: %d, "#ptr" is NULL", __func__, __LINE__); return (r);}
+
+
+/**
+ * @brief Run once function
+ * @note you must sure the statement is thread safe
+ */
+#define SGL_RUN_ONCE(statement) do { \
+ static bool _run_once_flag = false; \
+ if (unlikely(_run_once_flag == false)){ \
+ statement; \
+ _run_once_flag = true; \
+ } \
+ } while(0)
+
+// prototype: sgl_rgb(uint8_t r, uint8_t g, uint8_t b)
+#if (CONFIG_SGL_FBDEV_PIXEL_DEPTH == SGL_COLOR_ARGB8888 || CONFIG_SGL_FBDEV_PIXEL_DEPTH == SGL_COLOR_RGB888)
+#define sgl_rgb(r,g,b) (sgl_color_t){ .ch.blue = (b), \
+ .ch.green = (g), \
+ .ch.red = (r),}
+
+#define sgl_rgb222_to_color(rgb222) (sgl_color_t){ .ch.blue = ((((rgb222) >> 0) & 0x03) << 6), \
+ .ch.green = ((((rgb222) >> 2) & 0x03) << 6), \
+ .ch.red = ((((rgb222) >> 4) & 0x03) << 6),}
+
+#define sgl_rgb332_to_color(rgb332) (sgl_color_t){ .ch.blue = ((((rgb332) >> 0) & 0x03) << 6), \
+ .ch.green = ((((rgb332) >> 2) & 0x07) << 5), \
+ .ch.red = ((((rgb332) >> 5) & 0x07) << 5),}
+
+#define sgl_rgb444_to_color(rgb444) (sgl_color_t){ .ch.blue = ((((rgb444) >> 0) & 0xF) << 4), \
+ .ch.green = ((((rgb444) >> 4) & 0xF) << 4), \
+ .ch.red = ((((rgb444) >> 8) & 0xF) << 4),}
+
+#define sgl_rgb565_to_color(rgb565) (sgl_color_t){ .ch.blue = ((((rgb565) >> 0) & 0x1F) << 3), \
+ .ch.green = ((((rgb565) >> 5) & 0x3F) << 2), \
+ .ch.red = ((((rgb565) >> 11) & 0x1F) << 3),}
+
+#define sgl_rgb888_to_color(rgb888) (sgl_color_t){ .ch.blue = ((rgb888) >> 0), \
+ .ch.green = ((rgb888) >> 8), \
+ .ch.red = ((rgb888) >> 16),}
+
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == SGL_COLOR_RGB565)
+#define sgl_rgb(r,g,b) (sgl_color_t){ .ch.blue = (b) >> 3, \
+ .ch.green = (g) >> 2, \
+ .ch.red = (r) >> 3,}
+
+#define sgl_rgb222_to_color(rgb222) (sgl_color_t){ .ch.blue = ((((rgb222) >> 0) & 0x03) << 3), \
+ .ch.green = ((((rgb222) >> 2) & 0x03) << 4), \
+ .ch.red = ((((rgb222) >> 4) & 0x03) << 3),}
+
+#define sgl_rgb332_to_color(rgb332) (sgl_color_t){ .ch.blue = ((((rgb332) >> 0) & 0x03) << 3), \
+ .ch.green = ((((rgb332) >> 2) & 0x03) << 2), \
+ .ch.red = ((((rgb332) >> 5) & 0x03) << 2),}
+
+#define sgl_rgb444_to_color(rgb444) (sgl_color_t){ .ch.blue = ((((rgb444) >> 0) & 0xF) << 1), \
+ .ch.green = ((((rgb444) >> 4) & 0xF) << 2), \
+ .ch.red = ((((rgb444) >> 8) & 0xF) << 1),}
+
+#define sgl_rgb565_to_color(rgb565) (sgl_color_t){ .ch.blue = ((rgb565) >> 0) & 0x1F, \
+ .ch.green = ((rgb565) >> 5) & 0x3F, \
+ .ch.red = ((rgb565) >> 11) & 0x1F,}
+
+#define sgl_rgb888_to_color(rgb888) (sgl_color_t){ .ch.blue = (((rgb888) >> 0) >> 3), \
+ .ch.green = (((rgb888) >> 8) >> 2), \
+ .ch.red = (((rgb888) >> 16) >> 3),}
+
+#elif (CONFIG_SGL_FBDEV_PIXEL_DEPTH == SGL_COLOR_RGB332)
+#define sgl_rgb(r,g,b) (sgl_color_t){ .ch.blue = (b >> 6), \
+ .ch.green = (g >> 5), \
+ .ch.red = (r >> 5),}
+
+#define sgl_rgb222_to_color(rgb222) (sgl_color_t){ .ch.blue = ((((rgb222) >> 0) & 0x03) >> 0), \
+ .ch.green = ((((rgb222) >> 2) & 0x03) >> 1), \
+ .ch.red = ((((rgb222) >> 4) & 0x03) >> 1),}
+
+#define sgl_rgb332_to_color(rgb332) (sgl_color_t){ .ch.blue = (((rgb332) >> 0) & 0x03), \
+ .ch.green = (((rgb332) >> 3) & 0x07), \
+ .ch.red = (((rgb332) >> 5) & 0x07),}
+
+#define sgl_rgb444_to_color(rgb444) (sgl_color_t){ .ch.blue = ((((rgb444) >> 0) & 0xF) >> 2), \
+ .ch.green = ((((rgb444) >> 4) & 0xF) >> 1), \
+ .ch.red = ((((rgb444) >> 8) & 0xF) >> 1),}
+
+#define sgl_rgb565_to_color(rgb565) (sgl_color_t){ .ch.blue = ((((rgb565) >> 0) & 0x1F) >> 3), \
+ .ch.green = ((((rgb565) >> 5) & 0x3F) >> 3), \
+ .ch.red = ((((rgb565) >> 11) & 0x1F) >> 2),}
+
+#define sgl_rgb888_to_color(rgb888) (sgl_color_t){ .ch.blue = (((rgb888) >> 0)>> 6), \
+ .ch.green = (((rgb888) >> 8) >> 5), \
+ .ch.red = (((rgb888) >> 16) >> 6),}
+
+#endif
+
+
+/**
+ * Define some basic colors
+*/
+#define SGL_COLOR_RED sgl_rgb(0xFF, 0, 0)
+#define SGL_COLOR_GREEN sgl_rgb(0, 0xFF, 0)
+#define SGL_COLOR_BLUE sgl_rgb(0, 0, 0xFF)
+#define SGL_COLOR_WHITE sgl_rgb(0xFF, 0xFF, 0xFF)
+#define SGL_COLOR_BLACK sgl_rgb(0, 0, 0)
+#define SGL_COLOR_CYAN sgl_rgb(0, 0xFF, 0xFF)
+#define SGL_COLOR_MAGENTA sgl_rgb(0xFF, 0, 0xFF)
+#define SGL_COLOR_YELLOW sgl_rgb(0xFF, 0xFF, 0)
+#define SGL_COLOR_GRAY sgl_rgb(0x80, 0x80, 0x80)
+#define SGL_COLOR_DARK_GRAY sgl_rgb(0x40, 0x40, 0x40)
+#define SGL_COLOR_LIGHT_GRAY sgl_rgb(0xC0, 0xC0, 0xC0)
+#define SGL_COLOR_BRIGHT_PURPLE sgl_rgb(0xFF, 0x00, 0xFF)
+#define SGL_COLOR_BRIGHT_BLUE sgl_rgb(0x00, 0xFF, 0xFF)
+#define SGL_COLOR_ORANGE sgl_rgb(0xFF, 0xA5, 0x00)
+#define SGL_COLOR_DARK_ORANGE sgl_rgb(0xFF, 0x8C, 0x00)
+#define SGL_COLOR_RED_ORANGE sgl_rgb(0xFF, 0x45, 0x00)
+#define SGL_COLOR_GOLD sgl_rgb(0xFF, 0xD7, 0x00)
+#define SGL_COLOR_GOLDENROD sgl_rgb(0xDA, 0xA5, 0x20)
+#define SGL_COLOR_BROWN sgl_rgb(0xA5, 0x2A, 0x2A)
+#define SGL_COLOR_SADDLE_BROWN sgl_rgb(0x8B, 0x45, 0x13)
+#define SGL_COLOR_TOMATO sgl_rgb(0xFF, 0x63, 0x47)
+#define SGL_COLOR_CORAL sgl_rgb(0xFF, 0x7F, 0x50)
+#define SGL_COLOR_SALMON sgl_rgb(0xFA, 0x80, 0x72)
+#define SGL_COLOR_LIME sgl_rgb(0x32, 0xCD, 0x32)
+#define SGL_COLOR_OLIVE sgl_rgb(0x80, 0x80, 0x00)
+#define SGL_COLOR_DARK_OLIVE_GREEN sgl_rgb(0x55, 0x6B, 0x2F)
+#define SGL_COLOR_FOREST_GREEN sgl_rgb(0x22, 0x8B, 0x2F)
+#define SGL_COLOR_DARK_GREEN sgl_rgb(0x00, 0x64, 0x00)
+#define SGL_COLOR_LAWN_GREEN sgl_rgb(0x7C, 0xFC, 0x00)
+#define SGL_COLOR_CHARTREUSE sgl_rgb(0x7F, 0xFF, 0x00)
+#define SGL_COLOR_YELLOW_GREEN sgl_rgb(0x9A, 0xCD, 0x32)
+#define SGL_COLOR_SPRING_GREEN sgl_rgb(0x00, 0xFF, 0x7F)
+#define SGL_COLOR_DEEP_SKY_BLUE sgl_rgb(0x00, 0xBF, 0xFF)
+#define SGL_COLOR_DODGER_BLUE sgl_rgb(0x1E, 0x90, 0xFF)
+#define SGL_COLOR_ROYAL_BLUE sgl_rgb(0x41, 0x69, 0xE1)
+#define SGL_COLOR_MIDNIGHT_BLUE sgl_rgb(0x19, 0x19, 0x70)
+#define SGL_COLOR_NAVY sgl_rgb(0x00, 0x00, 0x80)
+#define SGL_COLOR_TEAL sgl_rgb(0x00, 0x80, 0x80)
+#define SGL_COLOR_DARK_CYAN sgl_rgb(0x00, 0x8B, 0x8B)
+#define SGL_COLOR_LIGHT_SEA_GREEN sgl_rgb(0x20, 0xB2, 0xAA)
+#define SGL_COLOR_CADET_BLUE sgl_rgb(0x5F, 0x9E, 0xA0)
+#define SGL_COLOR_INDIGO sgl_rgb(0x4B, 0x00, 0x82)
+#define SGL_COLOR_VIOLET sgl_rgb(0xEE, 0x82, 0xEE)
+#define SGL_COLOR_DARK_VIOLET sgl_rgb(0x94, 0x00, 0xD3)
+#define SGL_COLOR_MEDIUM_VIOLET_RED sgl_rgb(0xC7, 0x15, 0x85)
+#define SGL_COLOR_PINK sgl_rgb(0xFF, 0xC0, 0xCB)
+#define SGL_COLOR_HOT_PINK sgl_rgb(0xFF, 0x69, 0xB4)
+#define SGL_COLOR_DEEP_PINK sgl_rgb(0xFF, 0x14, 0x93)
+#define SGL_COLOR_PLUM sgl_rgb(0xDD, 0xA0, 0xDD)
+#define SGL_COLOR_ORCHID sgl_rgb(0xDA, 0x70, 0xD6)
+#define SGL_COLOR_TAN sgl_rgb(0xD2, 0xB4, 0x8C)
+#define SGL_COLOR_WHEAT sgl_rgb(0xF5, 0xDE, 0xB3)
+#define SGL_COLOR_SAND sgl_rgb(0xC2, 0xB2, 0x90)
+#define SGL_COLOR_BEIGE sgl_rgb(0xF5, 0xF5, 0xDC)
+#define SGL_COLOR_IVORY sgl_rgb(0xFF, 0xFF, 0xF0)
+#define SGL_COLOR_LAVENDER sgl_rgb(0xE6, 0xE6, 0xFA)
+#define SGL_COLOR_MISTY_ROSE sgl_rgb(0xFF, 0xE4, 0xE1)
+#define SGL_COLOR_SEASHELL sgl_rgb(0xFF, 0xF5, 0xEE)
+#define SGL_COLOR_FLORAL_WHITE sgl_rgb(0xFF, 0xFA, 0xF0)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__SGL_TYPES_H__
diff --git a/User/system/sgl/lm.cfg b/User/system/sgl/lm.cfg
new file mode 100644
index 0000000..705cefe
--- /dev/null
+++ b/User/system/sgl/lm.cfg
@@ -0,0 +1,117 @@
+# source/lm.cfg
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+CONFIG_SGL_FBDEV_PIXEL_DEPTH
+ choices = 8, 16, 24, 32
+ default = 32
+
+CONFIG_SGL_FBDEV_ROTATION
+ choices = 0, 90, 180, 270
+ default = 0
+
+CONFIG_SGL_FBDEV_RUNTIME_ROTATION
+ choices = n, y
+ default = n
+
+CONFIG_SGL_USE_FBDEV_VRAM
+ choices = n, y
+ default = n
+
+CONFIG_SGL_SYSTICK_MS
+ choices = [10, 1000]
+ default = 10
+
+# this value must be power of 2, such as 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536
+CONFIG_SGL_EVENT_QUEUE_SIZE
+ choices = [16, 65536]
+ default = 32
+
+CONFIG_SGL_EVENT_CLICK_INTERVAL
+ choices = [5, 100]
+ default = 10
+
+CONFIG_SGL_DIRTY_AREA_NUM_MAX
+ choices = [8, 255]
+ default = 16
+
+CONFIG_SGL_COLOR16_SWAP
+ choices = n, y
+ default = n
+
+CONFIG_SGL_PIXMAP_BILINEAR_INTERP
+ choices = n, y
+ default = n
+
+CONFIG_SGL_ANIMATION
+ choices = n, y
+ default = n
+
+CONFIG_SGL_DEBUG
+ choices = n, y
+ default = n
+
+CONFIG_SGL_LOG_COLOR
+ choices = n, y
+ default = n
+ depends = CONFIG_SGL_DEBUG
+
+CONFIG_SGL_LOG_LEVEL
+ choices = 0, 1, 2, 3, 4, 5, 6
+ default = 0
+ depends = CONFIG_SGL_DEBUG
+
+CONFIG_SGL_OBJ_USE_NAME
+ choices = n, y
+ default = n
+
+CONFIG_SGL_FONT_COMPRESSED
+ choices = n, y
+ default = n
+
+CONFIG_SGL_FONT_SMALL_TABLE
+ choices = n, y
+ default = n
+
+CONFIG_SGL_LABEL_ROTATION
+ choices = n, y
+ default = n
+
+CONFIG_SGL_BOOT_LOGO
+ choices = n, y
+ default = y
+
+CONFIG_SGL_THEME_DARK
+ choices = n, y
+ default = n
+
+
+PATH += ./ include
+CFLAG-$(CONFIG_SGL_DEBUG) += -g
+
+
+include "core/lm.cfg"
+include "mm/lm.cfg"
+include "draw/lm.cfg"
+include "widgets/lm.cfg"
+include "fonts/lm.cfg"
diff --git a/User/system/sgl/mm/build.cmake b/User/system/sgl/mm/build.cmake
new file mode 100644
index 0000000..46d5aa5
--- /dev/null
+++ b/User/system/sgl/mm/build.cmake
@@ -0,0 +1,52 @@
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+if(${SGL_HEAP_ALGO} STREQUAL "tlsf")
+ set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/tlsf/tlsf.c
+ ${CMAKE_CURRENT_LIST_DIR}/tlsf/sgl_mm.c
+ )
+endif()
+
+if(${SGL_HEAP_ALGO} STREQUAL "lwmem")
+ set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/lwmem/lwmem.c
+ ${CMAKE_CURRENT_LIST_DIR}/lwmem/sgl_mm.c
+ )
+endif()
+
+if(${SGL_HEAP_ALGO} STREQUAL "bump")
+ set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/bump/sgl_mm.c
+ )
+endif()
+
+if(${SGL_HEAP_ALGO} STREQUAL "other")
+ set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/other/sgl_mm.c
+ )
+endif()
diff --git a/User/system/sgl/mm/bump/sgl_mm.c b/User/system/sgl/mm/bump/sgl_mm.c
new file mode 100644
index 0000000..a0eeb67
--- /dev/null
+++ b/User/system/sgl/mm/bump/sgl_mm.c
@@ -0,0 +1,137 @@
+/* source/mm/bump/sgl_mm.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * WARNING: This memory allocator is not support free operation, if you free the memory, the memory will be corrupted.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+static sgl_mm_monitor_t mem = {
+ .total_size = 0,
+ .free_size = 0,
+ .used_size = 0,
+};
+
+static void *bump_mem_start = NULL;
+static size_t bump_mem_offset = 0;
+
+/**
+ * @brief initialize memory pool
+ * @param mem_start start address of memory pool
+ * @param len length of memory pool
+ */
+void sgl_mm_init(void *mem_start, size_t len)
+{
+ bump_mem_start = mem_start;
+ mem.total_size += len;
+ mem.free_size = mem.total_size;
+}
+
+
+/**
+ * @brief add memory pool
+ * @param mem_start start address of memory pool
+ * @param len length of memory pool
+ */
+void sgl_mm_add_pool(void *mem_start, size_t len)
+{
+ SGL_UNUSED(mem_start);
+ SGL_UNUSED(len);
+ SGL_LOG_ERROR("sgl_mm_add_pool is not supported");
+ SGL_ASSERT(0);
+}
+
+
+/**
+ * @brief memory alloc, the function is unsafe, you should ensure that
+ * the requested size is smaller than the free size of memory
+ *
+ * @param size request size of memory
+ *
+ * @return point to request memory address
+*/
+void* sgl_malloc(size_t size)
+{
+ uint8_t *ptr = (uint8_t*)bump_mem_start;
+
+ if (size == 0 || (bump_mem_offset + size) > mem.total_size) {
+ return NULL;
+ }
+
+ ptr += bump_mem_offset;
+ bump_mem_offset += size;
+ mem.used_size += size;
+ mem.free_size -= size;
+
+ return (void*)ptr;
+}
+
+
+/**
+ * @brief memory realloc, the function is unsafe, you should ensure that
+ * the requested size is smaller than the free size of memory
+ * @param p the pointer of request size of memory
+ * @param size request size of memory
+ */
+void* sgl_realloc(void *p, size_t size)
+{
+ SGL_UNUSED(p);
+ SGL_UNUSED(size);
+ SGL_LOG_ERROR("sgl_realloc is not supported");
+ SGL_ASSERT(0);
+ return NULL;
+}
+
+
+/**
+ * @brief memory free
+ *
+ * @param p the pointer of request size of memory
+ *
+ * @return none
+*/
+void sgl_free(void *p)
+{
+ SGL_UNUSED(p);
+ SGL_LOG_ERROR("sgl_free is not supported");
+ SGL_ASSERT(0);
+}
+
+
+sgl_mm_monitor_t sgl_mm_get_monitor(void)
+{
+ int integer = (mem.used_size * 100) / mem.total_size;
+ int decimal = (mem.used_size * 10000) / mem.total_size - (integer * 100);
+ mem.used_rate = integer << 8 | decimal;
+ mem.free_size = mem.total_size - mem.used_size;
+
+ return mem;
+}
diff --git a/User/system/sgl/mm/lm.cfg b/User/system/sgl/mm/lm.cfg
new file mode 100644
index 0000000..1632170
--- /dev/null
+++ b/User/system/sgl/mm/lm.cfg
@@ -0,0 +1,66 @@
+# source/mm/lm.cfg
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+# Memory management
+# Description:
+# - tlsf
+# A dynamic, fragmentation-resistant allocator designed for real-time and embedded systems
+# (e.g., RTOS, MCUs with moderate RAM). It balances speed, memory utilization, and low fragmentation.
+#
+# - lwmem
+# A lightweight, MCU-optimized allocator (developed for embedded systems) that prioritizes minimal
+# resource usage (RAM/ROM) while supporting basic dynamic allocation/deallocation.
+#
+# - bump
+# The simplest and fastest memory allocator, often called a "linear allocator" or "stack allocator"
+# (though not to be confused with the program stack). It manages a single contiguous block of
+# memory (a memory pool) with a single pointer (offset) that "bumps forward" to allocate memory.
+#
+# - other
+# Other memory allocation algorithms, you can implement your own memory allocation algorithm.
+
+# If you want to use dynamic memory allocation algorithm, you can consider it as an option
+CONFIG_SGL_HEAP_ALGO
+ choices = tlsf, lwmem, bump, other
+ default = lwmem
+
+
+CONFIG_SGL_FL_INDEX_MAX
+ choices = [10, 31]
+ depends = CONFIG_SGL_HEAP_ALGO
+ default = 20
+
+
+# Memory size is Byte
+CONFIG_SGL_HEAP_MEMORY_SIZE
+ choices = [1, 10000000]
+ depends = CONFIG_SGL_HEAP_ALGO
+ default = 10240
+
+
+
+SRC-$(CONFIG_SGL_HEAP_ALGO == tlsf) += tlsf/tlsf.c tlsf/sgl_mm.c
+SRC-$(CONFIG_SGL_HEAP_ALGO == lwmem) += lwmem/lwmem.c lwmem/sgl_mm.c
+SRC-$(CONFIG_SGL_HEAP_ALGO == bump) += bump/sgl_mm.c
+SRC-$(CONFIG_SGL_HEAP_ALGO == other) += other/sgl_mm.c
diff --git a/User/system/sgl/mm/lwmem/lwmem.c b/User/system/sgl/mm/lwmem/lwmem.c
new file mode 100644
index 0000000..6773933
--- /dev/null
+++ b/User/system/sgl/mm/lwmem/lwmem.c
@@ -0,0 +1,1439 @@
+/**
+ * \file lwmem.c
+ * \brief Lightweight dynamic memory manager
+ */
+
+/*
+ * Copyright (c) 2024 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwMEM - Lightweight dynamic memory manager library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v2.2.1
+ */
+#include "lwmem.h"
+#include
+#include
+#include
+
+#if LWMEM_CFG_OS
+#include "system/lwmem_sys.h"
+#endif /* LWMEM_CFG_OS */
+
+#if LWMEM_CFG_OS
+#define LWMEM_PROTECT(lwobj) lwmem_sys_mutex_wait(&((lwobj)->mutex))
+#define LWMEM_UNPROTECT(lwobj) lwmem_sys_mutex_release(&((lwobj)->mutex))
+#else /* LWMEM_CFG_OS */
+#define LWMEM_PROTECT(lwobj)
+#define LWMEM_UNPROTECT(lwobj)
+#endif /* !LWMEM_CFG_OS */
+
+/* Statistics part */
+#if LWMEM_CFG_ENABLE_STATS
+#define LWMEM_INC_STATS(field) (++(field))
+#define LWMEM_UPDATE_MIN_FREE(lwobj) \
+ do { \
+ if ((lwobj)->mem_available_bytes < (lwobj)->stats.minimum_ever_mem_available_bytes) { \
+ (lwobj)->stats.minimum_ever_mem_available_bytes = (lwobj)->mem_available_bytes; \
+ } \
+ } while (0)
+#else
+#define LWMEM_INC_STATS(field)
+#define LWMEM_UPDATE_MIN_FREE(lwobj)
+#endif /* LWMEM_CFG_ENABLE_STATS */
+
+/* Verify alignment */
+#if (LWMEM_CFG_ALIGN_NUM & (LWMEM_CFG_ALIGN_NUM - 1) > 0)
+#error "LWMEM_ALIGN_BITS must be power of 2"
+#endif
+
+/**
+ * \brief LwMEM default structure used by application
+ */
+static lwmem_t lwmem_default;
+
+/**
+ * \brief Get LwMEM instance based on user input
+ * \param[in] in_lwobj: LwMEM instance. Set to `NULL` for default instance
+ */
+#define LWMEM_GET_LWOBJ(in_lwobj) ((in_lwobj) != NULL ? (in_lwobj) : (&lwmem_default))
+
+/**
+ * \brief Transform alignment number (power of `2`) to bits
+ */
+#define LWMEM_ALIGN_BITS ((size_t)(((size_t)LWMEM_CFG_ALIGN_NUM) - 1))
+
+/**
+ * \brief Aligns input value to next alignment bits
+ *
+ * As an example, when \ref LWMEM_CFG_ALIGN_NUM is set to `4`:
+ *
+ * - Input: `0`; Output: `0`
+ * - Input: `1`; Output: `4`
+ * - Input: `2`; Output: `4`
+ * - Input: `3`; Output: `4`
+ * - Input: `4`; Output: `4`
+ * - Input: `5`; Output: `8`
+ * - Input: `6`; Output: `8`
+ * - Input: `7`; Output: `8`
+ * - Input: `8`; Output: `8`
+ */
+#define LWMEM_ALIGN(x) (((x) + (LWMEM_ALIGN_BITS)) & ~(LWMEM_ALIGN_BITS))
+
+/**
+ * \brief Cast input pointer to byte
+ * \param[in] p: Input pointer to cast to byte pointer
+ */
+#define LWMEM_TO_BYTE_PTR(p) ((uint8_t*)(p))
+
+#if LWMEM_CFG_FULL
+
+/**
+ * \brief Size of metadata header for block information
+ */
+#define LWMEM_BLOCK_META_SIZE LWMEM_ALIGN(sizeof(lwmem_block_t))
+
+/**
+ * \brief Bit indicating memory block is allocated
+ */
+#define LWMEM_ALLOC_BIT ((size_t)((size_t)1 << (sizeof(size_t) * CHAR_BIT - 1)))
+
+/**
+ * \brief Mark written in `next` field when block is allocated
+ */
+#define LWMEM_BLOCK_ALLOC_MARK (0xDEADBEEF)
+
+/**
+ * \brief Check if input block is properly allocated and valid
+ * \param[in] block: Block to check if properly set as allocated
+ */
+#define LWMEM_BLOCK_IS_ALLOC(block) \
+ ((block) != NULL && ((block)->size & LWMEM_ALLOC_BIT) \
+ && (block)->next == (void*)(LWMEM_TO_BYTE_PTR(0) + LWMEM_BLOCK_ALLOC_MARK))
+
+/**
+ * \brief Get block handle from application pointer
+ * \param[in] ptr: Input pointer to get block from
+ */
+#define LWMEM_GET_BLOCK_FROM_PTR(ptr) (void*)((ptr) != NULL ? ((LWMEM_TO_BYTE_PTR(ptr)) - LWMEM_BLOCK_META_SIZE) : NULL)
+
+/**
+ * \brief Get block handle from application pointer
+ * \param[in] block: Input pointer to get block from
+ */
+#define LWMEM_GET_PTR_FROM_BLOCK(block) \
+ (void*)((block) != NULL ? ((LWMEM_TO_BYTE_PTR(block)) + LWMEM_BLOCK_META_SIZE) : NULL)
+
+/**
+ * \brief Minimum amount of memory required to make new empty block
+ *
+ * Default size is size of meta block
+ */
+#define LWMEM_BLOCK_MIN_SIZE (LWMEM_BLOCK_META_SIZE)
+
+/**
+ * \brief Gets block before input block (marked as prev) and its previous free block
+ * \param[in] in_lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] in_b: Input block to find previous and its previous
+ * \param[in] in_pp: Previous previous of input block. Finding will be stored here
+ * \param[in] in_p: Previous of input block. Finding will be stored here
+ */
+static void
+prv_get_prev_curr_of_block(lwmem_t* in_lwobj, const lwmem_block_t* in_b, lwmem_block_t** in_pp, lwmem_block_t** in_p) {
+ for (*in_pp = NULL, *in_p = &((in_lwobj)->start_block); *in_p != NULL && (*in_p)->next < in_b;
+ *in_pp = (*in_p), *in_p = (*in_p)->next) {}
+}
+
+/**
+ * \brief Set block as allocated
+ * \param[in] block: Block to set as allocated
+ */
+static void
+prv_block_set_alloc(lwmem_block_t* block) {
+ if (block != NULL) {
+ block->size |= LWMEM_ALLOC_BIT;
+ block->next = (void*)(LWMEM_TO_BYTE_PTR(0) + LWMEM_BLOCK_ALLOC_MARK);
+ }
+}
+
+/**
+ * \brief Get region aligned start address and aligned size
+ * \param[in] region: Region to check for size and address
+ * \param[out] msa: Memory start address output variable
+ * \param[out] msz: Memory size output variable
+ * \return `1` if region valid, `0` otherwise
+ */
+static uint8_t
+prv_get_region_addr_size(const lwmem_region_t* region, uint8_t** msa, size_t* msz) {
+ size_t mem_size = 0;
+ uint8_t* mem_start_addr = NULL;
+
+ if (region == NULL || msa == NULL || msz == NULL) {
+ return 0;
+ }
+ *msa = NULL;
+ *msz = 0;
+
+ /*
+ * Start address must be aligned to configuration
+ * Increase start address and decrease effective region size
+ */
+ mem_start_addr = region->start_addr;
+ mem_size = region->size;
+ if (((size_t)mem_start_addr) & LWMEM_ALIGN_BITS) { /* Check alignment boundary */
+ mem_start_addr += ((size_t)LWMEM_CFG_ALIGN_NUM) - ((size_t)mem_start_addr & LWMEM_ALIGN_BITS);
+ mem_size -= (size_t)(mem_start_addr - LWMEM_TO_BYTE_PTR(region->start_addr));
+ }
+
+ /* Check region size and align it to config bits */
+ mem_size &= ~LWMEM_ALIGN_BITS; /* Align the size to lower bits */
+ if (mem_size < (2 * LWMEM_BLOCK_MIN_SIZE)) {
+ return 0;
+ }
+
+ /* Check final memory size */
+ if (mem_size >= (2 * LWMEM_BLOCK_MIN_SIZE)) {
+ *msa = mem_start_addr;
+ *msz = mem_size;
+
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * \brief Insert free block to linked list of free blocks
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] nblk: New free block to insert into linked list
+ */
+static void
+prv_insert_free_block(lwmem_t* const lwobj, lwmem_block_t* nblk) {
+ lwmem_block_t* prev;
+
+ /* Check valid inputs */
+ if (nblk == NULL) {
+ return;
+ }
+
+ /*
+ * Try to find position to put new block in-between
+ * Search until all free block addresses are lower than entry block
+ */
+ for (prev = &(lwobj->start_block); prev != NULL && prev->next < nblk; prev = prev->next) {}
+
+ /* This is hard error with wrong memory usage */
+ if (prev == NULL) {
+ return;
+ }
+
+ /*
+ * At this point we have valid previous block
+ * Previous block is last free block before input block
+ */
+
+#if LWMEM_CFG_CLEAN_MEMORY
+ /*
+ * Reset user memory. This is to reset memory
+ * after it has been freed by the application.
+ *
+ * By doing this, we protect data left by app
+ * and we make sure new allocations cannot see old information
+ */
+ if (nblk != NULL) {
+ void* ptr = LWMEM_GET_PTR_FROM_BLOCK(nblk);
+ if (ptr != NULL) {
+ LWMEM_MEMSET(ptr, 0x00, nblk->size - LWMEM_BLOCK_META_SIZE);
+ }
+ }
+#endif /* LWMEM_CFG_RESET_MEMORY */
+
+ /*
+ * Check if previous block and input block together create one big contiguous block
+ * If this is the case, merge blocks together and increase previous block by input block size
+ */
+ if ((LWMEM_TO_BYTE_PTR(prev) + prev->size) == LWMEM_TO_BYTE_PTR(nblk)) {
+ prev->size += nblk->size; /* Increase current block by size of new block */
+ nblk = prev; /* New block and current are now the same thing */
+ /*
+ * It is important to set new block as current one
+ * as this allows merging previous and next blocks together with new block
+ * at the same time; follow next steps
+ */
+ }
+
+ /*
+ * Check if new block and next of previous create big contiguous block
+ * Do not merge with "end of region" indication (commented part of if statement)
+ */
+ if (prev->next != NULL && prev->next->size > 0 /* Do not remove "end of region" indicator in each region */
+ && (LWMEM_TO_BYTE_PTR(nblk) + nblk->size) == LWMEM_TO_BYTE_PTR(prev->next)) {
+ if (prev->next == lwobj->end_block) { /* Does it points to the end? */
+ nblk->next = lwobj->end_block; /* Set end block pointer */
+ } else {
+ /* Expand of current block for size of next free block which is right behind new block */
+ nblk->size += prev->next->size;
+ nblk->next = prev->next->next; /* Next free is pointed to the next one of previous next */
+ }
+ } else {
+ nblk->next = prev->next; /* Set next of input block as next of current one */
+ }
+
+ /*
+ * If new block has not been set as current (and expanded),
+ * then link them together, otherwise ignore as it would point to itself
+ */
+ if (prev != nblk) {
+ prev->next = nblk;
+ }
+}
+
+/**
+ * \brief Split too big block and add it to list of free blocks
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] block: Pointer to block with size already set
+ * \param[in] new_block_size: New block size to be set
+ * \return `1` if block splitted, `0` otherwise
+ */
+static uint8_t
+prv_split_too_big_block(lwmem_t* const lwobj, lwmem_block_t* block, size_t new_block_size) {
+ lwmem_block_t* next;
+ size_t block_size, is_alloc_bit;
+ uint8_t success = 0;
+
+ is_alloc_bit = block->size & LWMEM_ALLOC_BIT; /* Check if allocation bit is set */
+ block_size = block->size & ~LWMEM_ALLOC_BIT; /* Use size without allocated bit */
+
+ /*
+ * If current block size is greater than requested size,
+ * it is possible to create empty block at the end of existing one
+ * and add it back to list of empty blocks
+ */
+ if ((block_size - new_block_size) >= LWMEM_BLOCK_MIN_SIZE) {
+ next = (void*)(LWMEM_TO_BYTE_PTR(block) + new_block_size); /* Put next block after size of current allocation */
+ next->size = block_size - new_block_size; /* Modify block data */
+ block->size = new_block_size; /* Current size is now smaller */
+
+ lwobj->mem_available_bytes += next->size; /* Increase available bytes by new block size */
+ prv_insert_free_block(lwobj, next); /* Add new block to the free list */
+
+ success = 1;
+ } else {
+ /* TODO: If next of current is free, check if we can increase next by at least some bytes */
+ /* This can only happen during reallocation process when allocated block is reallocated to previous one */
+ /* Very rare case, but may happen! */
+ }
+
+ /* If allocation bit was set before, set it now again */
+ if (is_alloc_bit) {
+ prv_block_set_alloc(block);
+ }
+ return success;
+}
+
+/**
+ * \brief Private allocation function
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] region: Pointer to region to allocate from.
+ * Set to `NULL` for any region
+ * \param[in] size: Application wanted size, excluding size of meta header
+ * \return Pointer to allocated memory, `NULL` otherwise
+ */
+static void*
+prv_alloc(lwmem_t* const lwobj, const lwmem_region_t* region, const size_t size) {
+ lwmem_block_t *prev, *curr;
+ void* retval = NULL;
+
+ /* Calculate final size including meta data size */
+ const size_t final_size = LWMEM_ALIGN(size) + LWMEM_BLOCK_META_SIZE;
+
+ /* Check if initialized and if size is in the limits */
+ if (lwobj->end_block == NULL || final_size == LWMEM_BLOCK_META_SIZE || (final_size & LWMEM_ALLOC_BIT) > 0) {
+ return NULL;
+ }
+
+ /* Set default values */
+ prev = &(lwobj->start_block); /* Use pointer from custom lwmem block */
+ curr = prev->next; /* Curr represents first actual free block */
+
+ /*
+ * If region is not set to NULL,
+ * request for memory allocation came from specific region:
+ *
+ * - Start at the beginning like normal (from very first region)
+ * - Loop until free block is between region start addr and its size
+ */
+ if (region != NULL) {
+ uint8_t* region_start_addr;
+ size_t region_size;
+
+ /* Get data about region */
+ if (!prv_get_region_addr_size(region, ®ion_start_addr, ®ion_size)) {
+ return NULL;
+ }
+
+ /*
+ * Scan all regions from lwmem and find first available block
+ * which is within address of region and is big enough
+ */
+ for (; curr != NULL; prev = curr, curr = curr->next) {
+ /* Check bounds */
+ if (curr->next == NULL || curr == lwobj->end_block) {
+ return NULL;
+ }
+ if ((uint8_t*)curr < (uint8_t*)region_start_addr) { /* Check if we reached region */
+ continue;
+ }
+ if ((uint8_t*)curr >= (uint8_t*)(region_start_addr + region_size)) { /* Check if we are out already */
+ return NULL;
+ }
+ if (curr->size >= final_size) {
+ break; /* Free block identified */
+ }
+ }
+ } else {
+ /*
+ * Try to find first block with at least `size` bytes of available memory
+ * Loop until size of current block is smaller than requested final size
+ */
+ for (; curr != NULL && curr->size < final_size; prev = curr, curr = curr->next) {
+ if (curr->next == NULL || curr == lwobj->end_block) { /* If no more blocks available */
+ return NULL; /* No sufficient memory available to allocate block of memory */
+ }
+ }
+ }
+
+ /* Check curr pointer. During normal use, this should be always false */
+ if (curr == NULL) {
+ return NULL;
+ }
+
+ /* There is a valid block available */
+ retval = LWMEM_GET_PTR_FROM_BLOCK(curr); /* Return pointer does not include meta part */
+ prev->next = curr->next; /* Remove this block from linked list by setting next of previous to next of current */
+
+ /* curr block is now removed from linked list */
+
+ lwobj->mem_available_bytes -= curr->size; /* Decrease available bytes by allocated block size */
+ prv_split_too_big_block(lwobj, curr, final_size); /* Split block if it is too big */
+ prv_block_set_alloc(curr); /* Set block as allocated */
+
+ LWMEM_UPDATE_MIN_FREE(lwobj);
+ LWMEM_INC_STATS(lwobj->stats.nr_alloc);
+
+ return retval;
+}
+
+/**
+ * \brief Free input pointer
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] ptr: Input pointer to free
+ */
+static void
+prv_free(lwmem_t* const lwobj, void* const ptr) {
+ lwmem_block_t* const block = LWMEM_GET_BLOCK_FROM_PTR(ptr);
+ if (LWMEM_BLOCK_IS_ALLOC(block)) { /* Check if block is valid */
+ block->size &= ~LWMEM_ALLOC_BIT; /* Clear allocated bit indication */
+
+ lwobj->mem_available_bytes += block->size; /* Increase available bytes */
+ prv_insert_free_block(lwobj, block); /* Put block back to list of free block */
+
+ LWMEM_INC_STATS(lwobj->stats.nr_free);
+ }
+}
+
+/**
+ * \brief Reallocates already allocated memory with new size
+ *
+ * Function behaves differently, depends on input parameter of `ptr` and `size`:
+ *
+ * - `ptr == NULL; size == 0`: Function returns `NULL`, no memory is allocated or freed
+ * - `ptr == NULL; size > 0`: Function tries to allocate new block of memory with `size` length, equivalent to `malloc(size)`
+ * - `ptr != NULL; size == 0`: Function frees memory, equivalent to `free(ptr)`
+ * - `ptr != NULL; size > 0`: Function tries to allocate new memory of copy content before returning pointer on success
+ *
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] region: Pointer to region to allocate from.
+ * Set to `NULL` for any region
+ * \param[in] ptr: Memory block previously allocated with one of allocation functions.
+ * It may be set to `NULL` to create new clean allocation
+ * \param[in] size: Size of new memory to reallocate
+ * \return Pointer to allocated memory on success, `NULL` otherwise
+ */
+static void*
+prv_realloc(lwmem_t* const lwobj, const lwmem_region_t* region, void* const ptr, const size_t size) {
+ lwmem_block_t *block = NULL, *prevprev = NULL, *prev = NULL;
+ size_t block_size; /* Holds size of input block (ptr), including metadata size */
+ const size_t final_size =
+ LWMEM_ALIGN(size) + LWMEM_BLOCK_META_SIZE; /* Holds size of new requested block size, including metadata size */
+ void* retval; /* Return pointer, used with LWMEM_RETURN macro */
+
+ /* Check optional input parameters */
+ if (size == 0) {
+ if (ptr != NULL) {
+ prv_free(lwobj, ptr);
+ }
+ return NULL;
+ }
+ if (ptr == NULL) {
+ return prv_alloc(lwobj, region, size);
+ }
+
+ /* Try to reallocate existing pointer */
+ if ((size & LWMEM_ALLOC_BIT) || (final_size & LWMEM_ALLOC_BIT)) {
+ return NULL;
+ }
+
+ /* Process existing block */
+ block = LWMEM_GET_BLOCK_FROM_PTR(ptr);
+ if (!LWMEM_BLOCK_IS_ALLOC(block)) {
+
+ /* Hard error. Input pointer is not NULL and block is not considered allocated */
+ return NULL;
+ }
+ block_size = block->size & ~LWMEM_ALLOC_BIT; /* Get actual block size, without memory allocation bit */
+
+ /* Check current block size is the same as new requested size */
+ if (block_size == final_size) {
+ return ptr; /* Just return pointer, nothing to do */
+ }
+
+ /*
+ * Abbreviations
+ *
+ * - "Current block" or "Input block" is allocated block from input variable "ptr"
+ * - "Next free block" is next free block, on address space after input block
+ * - "Prev free block" is last free block, on address space before input block
+ * - "PrevPrev free block" is previous free block of "Prev free block"
+ */
+
+ /*
+ * When new requested size is smaller than existing one,
+ * it is enough to modify size of current block only.
+ *
+ * If new requested size is much smaller than existing one,
+ * check if it is possible to create new empty block and add it to list of empty blocks
+ *
+ * Application returns same pointer
+ */
+ if (final_size < block_size) {
+ if ((block_size - final_size) >= LWMEM_BLOCK_MIN_SIZE) {
+ prv_split_too_big_block(lwobj, block, final_size); /* Split block if it is too big */
+ } else {
+ /*
+ * It is not possible to create new empty block at the end of input block
+ *
+ * But if next free block is just after input block,
+ * it is possible to find this block and increase it by "block_size - final_size" bytes
+ */
+
+ /* Find free blocks before input block */
+ prv_get_prev_curr_of_block(lwobj, block, &prevprev, &prev);
+
+ /* Check if current block and next free are connected */
+ if ((LWMEM_TO_BYTE_PTR(block) + block_size) == LWMEM_TO_BYTE_PTR(prev->next)
+ && prev->next->size > 0) { /* Must not be end of region indicator */
+ /* Make temporary variables as prev->next will point to different location */
+ const size_t tmp_size = prev->next->size;
+ void* const tmp_next = prev->next->next;
+
+ /* Shift block up, effectively increase its size */
+ prev->next = (void*)(LWMEM_TO_BYTE_PTR(prev->next) - (block_size - final_size));
+ prev->next->size = tmp_size + (block_size - final_size);
+ prev->next->next = tmp_next;
+
+ /* Increase available bytes by increase of free block */
+ lwobj->mem_available_bytes += block_size - final_size;
+
+ block->size = final_size; /* Block size is requested size */
+ }
+ }
+ prv_block_set_alloc(block); /* Set block as allocated */
+ return ptr; /* Return existing pointer */
+ }
+
+ /* New requested size is bigger than current block size is */
+
+ /* Find last free (and its previous) block, located just before input block */
+ prv_get_prev_curr_of_block(lwobj, block, &prevprev, &prev);
+
+ /* If entry could not be found, there is a hard error */
+ if (prev == NULL) {
+ return NULL;
+ }
+
+ /* Order of variables is: | prevprev ---> prev --->--->--->--->--->--->--->--->--->---> prev->next | */
+ /* | (input_block, which is not on a list) | */
+ /* Input block points to address somewhere between "prev" and "prev->next" pointers */
+
+ /* Check if "block" and next free "prev->next" create contiguous memory with size of at least new requested size */
+ if ((LWMEM_TO_BYTE_PTR(block) + block_size) == LWMEM_TO_BYTE_PTR(prev->next)
+ && (block_size + prev->next->size) >= final_size) {
+
+ /*
+ * Merge blocks together by increasing current block with size of next free one
+ * and remove next free from list of free blocks
+ */
+ lwobj->mem_available_bytes -= prev->next->size; /* For now decrease effective available bytes */
+ LWMEM_UPDATE_MIN_FREE(lwobj);
+ block->size = block_size + prev->next->size; /* Increase effective size of new block */
+ prev->next = prev->next->next; /* Set next to next's next,
+ effectively remove expanded block from free list */
+
+ prv_split_too_big_block(lwobj, block, final_size); /* Split block if it is too big */
+ prv_block_set_alloc(block); /* Set block as allocated */
+ return ptr; /* Return existing pointer */
+ }
+
+ /*
+ * Check if "block" and last free before "prev" create contiguous memory with size of at least new requested size.
+ *
+ * It is necessary to make a memory move and shift content up as new return pointer is now upper on address space
+ */
+ if ((LWMEM_TO_BYTE_PTR(prev) + prev->size) == LWMEM_TO_BYTE_PTR(block) && (prev->size + block_size) >= final_size) {
+ /* Move memory from block to block previous to current */
+ void* const old_data_ptr = LWMEM_GET_PTR_FROM_BLOCK(block);
+ void* const new_data_ptr = LWMEM_GET_PTR_FROM_BLOCK(prev);
+
+ /*
+ * If memmove overwrites metadata of current block (when shifting content up),
+ * it is not an issue as we know its size (block_size) and next is already NULL.
+ *
+ * Memmove must be used to guarantee move of data as addresses + their sizes may overlap
+ *
+ * Metadata of "prev" are not modified during memmove
+ */
+ LWMEM_MEMMOVE(new_data_ptr, old_data_ptr, block_size);
+
+ lwobj->mem_available_bytes -= prev->size; /* For now decrease effective available bytes */
+ LWMEM_UPDATE_MIN_FREE(lwobj);
+ prev->size += block_size; /* Increase size of input block size */
+ prevprev->next = prev->next; /* Remove prev from free list as it is now being used
+ for allocation together with existing block */
+ block = prev; /* Move block pointer to previous one */
+
+ prv_split_too_big_block(lwobj, block, final_size); /* Split block if it is too big */
+ prv_block_set_alloc(block); /* Set block as allocated */
+ return new_data_ptr; /* Return new data ptr */
+ }
+
+ /*
+ * At this point, it was not possible to expand existing block with free before or free after due to:
+ * - Input block & next free block do not create contiguous block or its new size is too small
+ * - Previous free block & input block do not create contiguous block or its new size is too small
+ *
+ * Last option is to check if previous free block "prev", input block "block" and next free block "prev->next" create contiguous block
+ * and size of new block (from 3 contiguous blocks) together is big enough
+ */
+ if ((LWMEM_TO_BYTE_PTR(prev) + prev->size) == LWMEM_TO_BYTE_PTR(block)
+ && (LWMEM_TO_BYTE_PTR(block) + block_size) == LWMEM_TO_BYTE_PTR(prev->next)
+ && (prev->size + block_size + prev->next->size) >= final_size) {
+
+ /* Move memory from block to block previous to current */
+ void* const old_data_ptr = LWMEM_GET_PTR_FROM_BLOCK(block);
+ void* const new_data_ptr = LWMEM_GET_PTR_FROM_BLOCK(prev);
+
+ /*
+ * If memmove overwrites metadata of current block (when shifting content up),
+ * it is not an issue as we know its size (block_size) and next is already NULL.
+ *
+ * Memmove must be used to guarantee move of data as addresses and their sizes may overlap
+ *
+ * Metadata of "prev" are not modified during memmove
+ */
+ LWMEM_MEMMOVE(new_data_ptr, old_data_ptr, block_size);
+
+ /* Decrease effective available bytes for free blocks before and after input block */
+ lwobj->mem_available_bytes -= prev->size + prev->next->size;
+ LWMEM_UPDATE_MIN_FREE(lwobj);
+ prev->size += block_size + prev->next->size; /* Increase size of new block by size of 2 free blocks */
+
+ /* Remove free block before current one and block after current one from linked list (remove 2) */
+ prevprev->next = prev->next->next;
+ block = prev; /* Previous block is now current */
+
+ prv_split_too_big_block(lwobj, block, final_size); /* Split block if it is too big */
+ prv_block_set_alloc(block); /* Set block as allocated */
+ return new_data_ptr; /* Return new data ptr */
+ }
+
+ /*
+ * If application reaches this point, it means:
+ * - New requested size is greater than input block size
+ * - Input block & next free block do not create contiguous block or its new size is too small
+ * - Last free block & input block do not create contiguous block or its new size is too small
+ * - Last free block & input block & next free block do not create contiguous block or its size is too small
+ *
+ * Final solution is to find completely new empty block of sufficient size and copy content from old one to new one
+ */
+ retval = prv_alloc(lwobj, region, size); /* Try to allocate new block */
+ if (retval != NULL) {
+ /* Get application size from input pointer, then copy content to new block */
+ block_size = (block->size & ~LWMEM_ALLOC_BIT) - LWMEM_BLOCK_META_SIZE;
+ LWMEM_MEMCPY(retval, ptr, size > block_size ? block_size : size);
+ prv_free(lwobj, ptr); /* Free old block */
+ }
+ return retval;
+}
+
+/**
+ * \brief Assign the memory structure for advanced memory allocation system
+ *
+ * \param lwobj
+ * \param regions
+ * \return size_t
+ */
+static size_t
+prv_assignmem(lwmem_t* lwobj, const lwmem_region_t* regions) {
+ uint8_t* mem_start_addr = NULL;
+ size_t mem_size = 0;
+ lwmem_block_t *first_block = NULL, *prev_end_block = NULL;
+
+ for (size_t idx = 0; regions->size > 0 && regions->start_addr != NULL; ++idx, ++regions) {
+ /* Get region start address and size, stop on failure */
+ if (!prv_get_region_addr_size(regions, &mem_start_addr, &mem_size)) {
+ continue;
+ }
+
+ /*
+ * If end_block == NULL, this indicates first iteration.
+ * In first indication application shall set start_block and never again
+ * end_block value holds
+ */
+ if (lwobj->end_block == NULL) {
+ /*
+ * Next entry of start block is first region
+ * It points to beginning of region data
+ * In the later step(s) first block is manually set on top of memory region
+ */
+ lwobj->start_block.next = (void*)mem_start_addr;
+ lwobj->start_block.size = 0; /* Size of dummy start block is zero */
+ }
+
+ /* Save current end block status as it is used later for linked list insertion */
+ prev_end_block = lwobj->end_block;
+
+ /* Put end block to the end of the region with size = 0 */
+ lwobj->end_block = (void*)(mem_start_addr + mem_size - LWMEM_BLOCK_META_SIZE);
+ lwobj->end_block->next = NULL; /* End block in region does not have next entry */
+ lwobj->end_block->size = 0; /* Size of end block is zero */
+
+ /*
+ * Create memory region first block.
+ *
+ * First block meta size includes size of metadata too
+ * Subtract MEM_BLOCK_META_SIZE as there is one more block (end_block) at the end of region
+ *
+ * Actual maximal available size for application in the region is mem_size - 2 * MEM_BLOCK_META_SIZE
+ */
+ first_block = (void*)mem_start_addr;
+ first_block->next = lwobj->end_block; /* Next block of first is last block */
+ first_block->size = mem_size - LWMEM_BLOCK_META_SIZE;
+
+ /* Check if previous regions exist by checking previous end block state */
+ if (prev_end_block != NULL) {
+ prev_end_block->next = first_block; /* End block of previous region now points to start of current region */
+ }
+
+ lwobj->mem_available_bytes += first_block->size; /* Increase number of available bytes */
+ ++lwobj->mem_regions_count; /* Increase number of used regions */
+ }
+
+#if defined(LWMEM_DEV)
+ /* Copy default state of start block */
+ LWMEM_MEMCPY(&lwmem_default.start_block_first_use, &lwmem_default.start_block, sizeof(lwmem_default.start_block));
+#endif /* defined(LWMEM_DEV) */
+#if LWMEM_CFG_ENABLE_STATS
+ lwobj->stats.mem_size_bytes = lwobj->mem_available_bytes;
+ lwobj->stats.minimum_ever_mem_available_bytes = lwobj->mem_available_bytes;
+#endif
+
+ return lwobj->mem_regions_count; /* Return number of regions used by manager */
+}
+
+#else /* LWMEM_CFG_FULL */
+
+/**
+ * \brief Assign the regions for simple algorithm
+ *
+ * At this point, regions check has been performed, so we assume
+ * everything is ready to proceed
+ *
+ * \param lwobj: LwMEM object
+ * \param regions: List of regions to assign
+ * \return Number of regions used
+ */
+static size_t
+prv_assignmem_simple(lwmem_t* const lwobj, const lwmem_region_t* regions) {
+ uint8_t* mem_start_addr = regions[0].start_addr;
+ size_t mem_size = regions[0].size;
+
+ /* Adjust alignment data */
+ if (((size_t)mem_start_addr) & LWMEM_ALIGN_BITS) {
+ mem_start_addr += ((size_t)LWMEM_CFG_ALIGN_NUM) - ((size_t)mem_start_addr & LWMEM_ALIGN_BITS);
+ mem_size -= (size_t)(mem_start_addr - LWMEM_TO_BYTE_PTR(regions[0].start_addr));
+ }
+
+ /* Align mem to alignment*/
+ mem_size = mem_size & ~LWMEM_ALIGN_BITS;
+
+ /* Store the available information */
+ lwobj->mem_available_bytes = mem_size;
+ lwobj->mem_next_available_ptr = mem_start_addr;
+ lwobj->is_initialized = 1;
+ return 1; /* One region is being used only for now */
+}
+
+/**
+ * \brief Simple allocation algorithm, that can only allocate memory,
+ * but it does not support free.
+ *
+ * It uses simple first-in-first-serve concept,
+ * where memory grows upward gradually, up until it reaches the end
+ * of memory area
+ *
+ * \param lwobj: LwMEM object
+ * \param region: Selected region. Not used in the current revision,
+ * but footprint remains the same if one day library will support it
+ * \param size: Requested allocation size
+ * \return `NULL` on failure, or pointer to allocated memory
+ */
+static void*
+prv_alloc_simple(lwmem_t* const lwobj, const lwmem_region_t* region, const size_t size) {
+ void* retval = NULL;
+ const size_t alloc_size = LWMEM_ALIGN(size);
+
+ if (alloc_size <= lwobj->mem_available_bytes) {
+ retval = lwobj->mem_next_available_ptr;
+
+ /* Get ready for next iteration */
+ lwobj->mem_next_available_ptr += alloc_size;
+ lwobj->mem_available_bytes -= alloc_size;
+ }
+ (void)region;
+ return retval;
+}
+
+#endif /* LWMEM_CFG_FULL */
+
+/**
+ * \brief Initializes and assigns user regions for memory used by allocator algorithm
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] regions: Pointer to array of regions with address and respective size.
+ * Regions must be in increasing order (start address) and must not overlap in-between.
+ * Last region entry must have address `NULL` and size set to `0`
+ * \code{.c}
+//Example definition
+lwmem_region_t regions[] = {
+ { (void *)0x10000000, 0x1000 }, //Region starts at address 0x10000000 and is 0x1000 bytes long
+ { (void *)0x20000000, 0x2000 }, //Region starts at address 0x20000000 and is 0x2000 bytes long
+ { (void *)0x30000000, 0x3000 }, //Region starts at address 0x30000000 and is 0x3000 bytes long
+ { NULL, 0 } //Array termination indicator
+}
+\endcode
+ * \return `0` on failure, number of final regions used for memory manager on success
+ * \note This function is not thread safe when used with operating system.
+ * It must be called only once to setup memory regions
+ */
+size_t
+lwmem_assignmem_ex(lwmem_t* lwobj, const lwmem_region_t* regions) {
+ uint8_t* mem_start_addr = NULL;
+ size_t mem_size = 0, len = 0;
+
+ lwobj = LWMEM_GET_LWOBJ(lwobj);
+
+ /* Check first things first */
+ if (regions == NULL
+#if LWMEM_CFG_FULL
+ || lwobj->end_block != NULL /* Init function may only be called once per lwmem instance */
+#else
+ || lwobj->is_initialized /* Already initialized? */
+#endif /* LWMEM_CFG_FULL */
+ ) {
+ return 0;
+ }
+
+ /* Check values entered by application */
+ mem_start_addr = (void*)0;
+ mem_size = 0;
+ for (size_t idx = 0;; ++idx) {
+ /*
+ * Check for valid entry or end of array descriptor
+ * Invalid entry is considered as "end-of-region" indicator
+ */
+ if (regions[idx].size == 0 && regions[idx].start_addr == NULL) {
+ len = idx;
+ if (len == 0) {
+ return 0;
+ }
+ break;
+ }
+
+#if !LWMEM_CFG_FULL
+ /*
+ * In case of simple allocation algorithm, we (for now!) only allow one region.
+ * Return zero value if user passed more than one region in a sequence.
+ */
+ else if (idx > 0) {
+ return 0;
+ }
+#endif /* LWMEM_CFG_FULL */
+
+ /* New region(s) must be higher (in address space) than previous one */
+ if ((mem_start_addr + mem_size) > LWMEM_TO_BYTE_PTR(regions[idx].start_addr)) {
+ return 0;
+ }
+
+ /* Save new values for next round */
+ mem_start_addr = regions[idx].start_addr;
+ mem_size = regions[idx].size;
+ }
+
+ /* Final init and check before initializing the regions */
+ if (len == 0
+#if LWMEM_CFG_OS
+ || lwmem_sys_mutex_isvalid(&(lwobj->mutex)) /* Check if mutex valid already = must not be */
+ || !lwmem_sys_mutex_create(&(lwobj->mutex)) /* Final step = try to create mutex for new instance */
+#endif /* LWMEM_CFG_OS */
+ ) {
+ return 0;
+ }
+
+#if LWMEM_CFG_FULL
+ return prv_assignmem(lwobj, regions);
+#else /* LWMEM_CFG_FULL */
+ return prv_assignmem_simple(lwobj, regions);
+#endif /* LWMEM_CFG_FULL */
+}
+
+/**
+ * \brief Allocate memory of requested size in specific lwmem instance and optional region.
+ * \note This is an extended malloc version function declaration to support advanced features
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] region: Optional region instance within LwMEM instance to force allocation from.
+ * Set to `NULL` to use any region within LwMEM instance
+ * \param[in] size: Number of bytes to allocate
+ * \return Pointer to allocated memory on success, `NULL` otherwise
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+void*
+lwmem_malloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t size) {
+ void* ptr = NULL;
+
+ lwobj = LWMEM_GET_LWOBJ(lwobj);
+
+ LWMEM_PROTECT(lwobj);
+#if LWMEM_CFG_FULL
+ ptr = prv_alloc(lwobj, region, size);
+#else /* LWMEM_CFG_FULL */
+ ptr = prv_alloc_simple(lwobj, region, size);
+#endif /* LWMEM_CFG_FULL */
+ LWMEM_UNPROTECT(lwobj);
+ return ptr;
+}
+
+/**
+ * \brief Allocate contiguous block of memory for requested number of items and its size
+ * in specific lwmem instance and region.
+ *
+ * It resets allocated block of memory to zero if allocation is successful
+ *
+ * \note This is an extended calloc version function declaration to support advanced features
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] region: Optional region instance within LwMEM instance to force allocation from.
+ * Set to `NULL` to use any region within LwMEM instance
+ * \param[in] nitems: Number of elements to be allocated
+ * \param[in] size: Size of each element, in units of bytes
+ * \return Pointer to allocated memory on success, `NULL` otherwise
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+void*
+lwmem_calloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t nitems, const size_t size) {
+ void* ptr = NULL;
+ const size_t alloc_size = size * nitems;
+
+ lwobj = LWMEM_GET_LWOBJ(lwobj);
+
+ LWMEM_PROTECT(lwobj);
+#if LWMEM_CFG_FULL
+ ptr = prv_alloc(lwobj, region, alloc_size);
+#else /* LWMEM_CFG_FULL */
+ ptr = prv_alloc_simple(lwobj, region, alloc_size);
+#endif /* LWMEM_CFG_FULL */
+ LWMEM_UNPROTECT(lwobj);
+
+ if (ptr != NULL) {
+ LWMEM_MEMSET(ptr, 0x00, alloc_size);
+ }
+ return ptr;
+}
+
+#if LWMEM_CFG_FULL || __DOXYGEN__
+
+/**
+ * \brief Reallocates already allocated memory with new size in specific lwmem instance and region.
+ *
+ * \note This function may only be used with allocations returned by any of `_from` API functions
+ *
+ * Function behaves differently, depends on input parameter of `ptr` and `size`:
+ *
+ * - `ptr == NULL; size == 0`: Function returns `NULL`, no memory is allocated or freed
+ * - `ptr == NULL; size > 0`: Function tries to allocate new block of memory with `size` length, equivalent to `malloc(region, size)`
+ * - `ptr != NULL; size == 0`: Function frees memory, equivalent to `free(ptr)`
+ * - `ptr != NULL; size > 0`: Function tries to allocate new memory of copy content before returning pointer on success
+ *
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] region: Pointer to region to allocate from.
+ * Set to `NULL` to use any region within LwMEM instance.
+ * Instance must be the same as used during allocation procedure
+ * \param[in] ptr: Memory block previously allocated with one of allocation functions.
+ * It may be set to `NULL` to create new clean allocation
+ * \param[in] size: Size of new memory to reallocate
+ * \return Pointer to allocated memory on success, `NULL` otherwise
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+void*
+lwmem_realloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, void* const ptr, const size_t size) {
+ void* p;
+ lwobj = LWMEM_GET_LWOBJ(lwobj);
+ LWMEM_PROTECT(lwobj);
+ p = prv_realloc(lwobj, region, ptr, size);
+ LWMEM_UNPROTECT(lwobj);
+ return p;
+}
+
+/**
+ * \brief Safe version of realloc_ex function.
+ *
+ * After memory is reallocated, input pointer automatically points to new memory
+ * to prevent use of dangling pointers. When reallocation is not successful,
+ * original pointer is not modified and application still has control of it.
+ *
+ * It is advised to use this function when reallocating memory.
+ *
+ * Function behaves differently, depends on input parameter of `ptr` and `size`:
+ *
+ * - `ptr == NULL`: Invalid input, function returns `0`
+ * - `*ptr == NULL; size == 0`: Function returns `0`, no memory is allocated or freed
+ * - `*ptr == NULL; size > 0`: Function tries to allocate new block of memory with `size` length, equivalent to `malloc(size)`
+ * - `*ptr != NULL; size == 0`: Function frees memory, equivalent to `free(ptr)`, sets input pointer pointing to `NULL`
+ * - `*ptr != NULL; size > 0`: Function tries to reallocate existing pointer with new size and copy content to new block
+ *
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
+ * \param[in] region: Pointer to region to allocate from.
+ * Set to `NULL` to use any region within LwMEM instance.
+ * Instance must be the same as used during allocation procedure
+ * \param[in] ptr: Pointer to pointer to allocated memory. Must not be set to `NULL`.
+ * If reallocation is successful, it modifies pointer's pointing address,
+ * or sets it to `NULL` in case of `free` operation
+ * \param[in] size: New requested size in bytes
+ * \return `1` if successfully reallocated, `0` otherwise
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+int
+lwmem_realloc_s_ex(lwmem_t* lwobj, const lwmem_region_t* region, void** const ptr, const size_t size) {
+ void* new_ptr;
+
+ /*
+ * Input pointer must not be NULL otherwise,
+ * in case of successful allocation, we have memory leakage
+ * aka. allocated memory where noone is pointing to it
+ */
+ if (ptr == NULL) {
+ return 0;
+ }
+
+ new_ptr = lwmem_realloc_ex(lwobj, region, *ptr, size); /* Try to reallocate existing pointer */
+ if (new_ptr != NULL) {
+ *ptr = new_ptr;
+ } else if (size == 0) { /* size == 0 means free input memory */
+ *ptr = NULL;
+ return 1;
+ }
+ return new_ptr != NULL;
+}
+
+/**
+ * \brief Free previously allocated memory using one of allocation functions
+ * in specific lwmem instance.
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance.
+ * Instance must be the same as used during allocation procedure
+ * \note This is an extended free version function declaration to support advanced features
+ * \param[in] ptr: Memory to free. `NULL` pointer is valid input
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+void
+lwmem_free_ex(lwmem_t* lwobj, void* const ptr) {
+ lwobj = LWMEM_GET_LWOBJ(lwobj);
+ LWMEM_PROTECT(lwobj);
+ prv_free(lwobj, ptr);
+ LWMEM_UNPROTECT(lwobj);
+}
+
+/**
+ * \brief Safe version of free function
+ *
+ * After memory is freed, input pointer is safely set to `NULL`
+ * to prevent use of dangling pointers.
+ *
+ * It is advised to use this function when freeing memory.
+ *
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance.
+ * Instance must be the same as used during allocation procedure
+ * \param[in] ptr: Pointer to pointer to allocated memory.
+ * When set to non `NULL`, pointer is freed and set to `NULL`
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+void
+lwmem_free_s_ex(lwmem_t* lwobj, void** const ptr) {
+ if (ptr != NULL && *ptr != NULL) {
+ lwobj = LWMEM_GET_LWOBJ(lwobj);
+ LWMEM_PROTECT(lwobj);
+ prv_free(lwobj, *ptr);
+ LWMEM_UNPROTECT(lwobj);
+ *ptr = NULL;
+ }
+}
+
+/**
+ * \brief Get user size of allocated memory
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance.
+ * Instance must be the same as used during allocation procedure
+ * \param[in] ptr: Pointer to allocated memory
+ * \return Block size for user in units of bytes
+ */
+size_t
+lwmem_get_size_ex(lwmem_t* lwobj, void* ptr) {
+ lwmem_block_t* block;
+ uint32_t len = 0;
+
+ if (ptr != NULL) {
+ lwobj = LWMEM_GET_LWOBJ(lwobj);
+ LWMEM_PROTECT(lwobj);
+ block = LWMEM_GET_BLOCK_FROM_PTR(ptr);
+ if (LWMEM_BLOCK_IS_ALLOC(block)) {
+ len = (block->size & ~LWMEM_ALLOC_BIT) - LWMEM_BLOCK_META_SIZE;
+ }
+ LWMEM_UNPROTECT(lwobj);
+ }
+ return len;
+}
+
+#endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
+
+#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__
+
+/**
+ * \brief Get statistics of a LwMEM instance
+ * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance.
+ * Instance must be the same as used during allocation procedure
+ * \param[in,out] stats: Pointer to \ref lwmem_stats_t to store result
+ */
+void
+lwmem_get_stats_ex(lwmem_t* lwobj, lwmem_stats_t* stats) {
+ if (stats != NULL) {
+ lwobj = LWMEM_GET_LWOBJ(lwobj);
+ LWMEM_PROTECT(lwobj);
+ *stats = lwobj->stats;
+ stats->mem_available_bytes = lwobj->mem_available_bytes;
+ LWMEM_UNPROTECT(lwobj);
+ }
+}
+
+/**
+ * \brief Get statistics of a default LwMEM instance
+ * \param[in,out] stats: Pointer to \ref lwmem_stats_t to store result
+ */
+size_t
+lwmem_get_size(lwmem_stats_t* stats) {
+ lwmem_get_stats_ex(NULL, stats);
+}
+
+#endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */
+
+/**
+ * \note This is a wrapper for \ref lwmem_assignmem_ex function.
+ * It operates in default LwMEM instance and uses first available region for memory operations
+ * \param[in] regions: Pointer to array of regions with address and respective size.
+ * Regions must be in increasing order (start address) and must not overlap in-between.
+ * Last region entry must have address `NULL` and size set to `0`
+ * \code{.c}
+//Example definition
+lwmem_region_t regions[] = {
+ { (void *)0x10000000, 0x1000 }, //Region starts at address 0x10000000 and is 0x1000 bytes long
+ { (void *)0x20000000, 0x2000 }, //Region starts at address 0x20000000 and is 0x2000 bytes long
+ { (void *)0x30000000, 0x3000 }, //Region starts at address 0x30000000 and is 0x3000 bytes long
+ { NULL, 0 } //Array termination indicator
+}
+\endcode
+ * \return `0` on failure, number of final regions used for memory manager on success
+ */
+size_t
+lwmem_assignmem(const lwmem_region_t* regions) {
+ return lwmem_assignmem_ex(NULL, regions);
+}
+
+/**
+ * \note This is a wrapper for \ref lwmem_malloc_ex function.
+ * It operates in default LwMEM instance and uses first available region for memory operations
+ * \param[in] size: Size to allocate in units of bytes
+ * \return Pointer to allocated memory on success, `NULL` otherwise
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+void*
+lwmem_malloc(size_t size) {
+ return lwmem_malloc_ex(NULL, NULL, size);
+}
+
+/**
+ * \note This is a wrapper for \ref lwmem_calloc_ex function.
+ * It operates in default LwMEM instance and uses first available region for memory operations
+ * \param[in] nitems: Number of elements to be allocated
+ * \param[in] size: Size of each element, in units of bytes
+ * \return Pointer to allocated memory on success, `NULL` otherwise
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+void*
+lwmem_calloc(size_t nitems, size_t size) {
+ return lwmem_calloc_ex(NULL, NULL, nitems, size);
+}
+
+#if LWMEM_CFG_FULL || __DOXYGEN__
+
+/**
+ * \note This is a wrapper for \ref lwmem_realloc_ex function.
+ * It operates in default LwMEM instance and uses first available region for memory operations
+ * \param[in] ptr: Memory block previously allocated with one of allocation functions.
+ * It may be set to `NULL` to create new clean allocation
+ * \param[in] size: Size of new memory to reallocate
+ * \return Pointer to allocated memory on success, `NULL` otherwise
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+void*
+lwmem_realloc(void* ptr, size_t size) {
+ return lwmem_realloc_ex(NULL, NULL, ptr, size);
+}
+
+/**
+ * \note This is a wrapper for \ref lwmem_realloc_s_ex function.
+ * It operates in default LwMEM instance and uses first available region for memory operations
+ * \param[in] ptr2ptr: Pointer to pointer to allocated memory. Must not be set to `NULL`.
+ * If reallocation is successful, it modifies pointer's pointing address,
+ * or sets it to `NULL` in case of `free` operation
+ * \param[in] size: New requested size in bytes
+ * \return `1` if successfully reallocated, `0` otherwise
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+int
+lwmem_realloc_s(void** ptr2ptr, size_t size) {
+ return lwmem_realloc_s_ex(NULL, NULL, ptr2ptr, size);
+}
+
+/**
+ * \note This is a wrapper for \ref lwmem_free_ex function.
+ * It operates in default LwMEM instance and uses first available region for memory operations
+ * \param[in] ptr: Memory to free. `NULL` pointer is valid input
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+void
+lwmem_free(void* ptr) {
+ lwmem_free_ex(NULL, (ptr));
+}
+
+/**
+ * \note This is a wrapper for \ref lwmem_free_s_ex function.
+ * It operates in default LwMEM instance and uses first available region for memory operations
+ * \param[in] ptr2ptr: Pointer to pointer to allocated memory.
+ * When set to non `NULL`, pointer is freed and set to `NULL`
+ * \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
+ */
+void
+lwmem_free_s(void** ptr2ptr) {
+ lwmem_free_s_ex(NULL, (ptr2ptr));
+}
+
+/**
+ * \note This is a wrapper for \ref lwmem_get_size_ex function.
+ * It operates in default LwMEM instance and uses first available region for memory operations
+ * \param[in] ptr: Pointer to allocated memory
+ * \return Block size for user in units of bytes
+ */
+size_t
+lwmem_get_size(void* ptr) {
+ return lwmem_get_size_ex(NULL, ptr);
+}
+
+#endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
+
+/* Part of library used ONLY for LWMEM_DEV purposes */
+/* To validate and test library */
+
+#if defined(LWMEM_DEV) && LWMEM_CFG_FULL && !__DOXYGEN__
+
+#include
+#include
+
+/* Temporary variable for lwmem save */
+static lwmem_t lwmem_temp;
+static lwmem_region_t* regions_orig;
+static lwmem_region_t* regions_temp;
+static size_t regions_count;
+
+static lwmem_region_t*
+create_regions(size_t count, size_t size) {
+ lwmem_region_t* regions;
+ lwmem_region_t tmp;
+
+ /*
+ * Allocate pointer structure
+ *
+ * Length 1 entry more, to set default values for NULL entry
+ */
+ regions = calloc(count + 1, sizeof(*regions));
+ if (regions == NULL) {
+ return NULL;
+ }
+
+ /* Allocate memory for regions */
+ for (size_t i = 0; i < count; ++i) {
+ regions[i].size = size;
+ regions[i].start_addr = malloc(regions[i].size);
+ if (regions[i].start_addr == NULL) {
+ return NULL;
+ }
+ }
+ regions[count].size = 0;
+ regions[count].start_addr = NULL;
+
+ /* Sort regions, make sure they grow linearly */
+ for (size_t x = 0; x < count; ++x) {
+ for (size_t y = 0; y < count; ++y) {
+ if (regions[x].start_addr < regions[y].start_addr) {
+ memcpy(&tmp, ®ions[x], sizeof(regions[x]));
+ memcpy(®ions[x], ®ions[y], sizeof(regions[x]));
+ memcpy(®ions[y], &tmp, sizeof(regions[x]));
+ }
+ }
+ }
+
+ return regions;
+}
+
+static void
+print_block(size_t i, lwmem_block_t* block) {
+ size_t is_free, block_size;
+
+ is_free = (block->size & LWMEM_ALLOC_BIT) == 0 && block != &lwmem_default.start_block_first_use && block->size > 0;
+ block_size = block->size & ~LWMEM_ALLOC_BIT;
+
+ printf("| %5d | %16p | %6d | %4d | %16d |", (int)i, (void*)block, (int)is_free, (int)block_size,
+ (int)(is_free ? (block_size - LWMEM_BLOCK_META_SIZE) : 0));
+ if (block == &lwmem_default.start_block_first_use) {
+ printf(" Start block ");
+ } else if (block_size == 0) {
+ printf(" End of region ");
+ } else if (is_free) {
+ printf(" Free block ");
+ } else if (!is_free) {
+ printf(" Allocated block ");
+ } else {
+ printf(" ");
+ }
+ printf("|\r\n");
+}
+
+void
+lwmem_debug_print(uint8_t print_alloc, uint8_t print_free) {
+ size_t block_size;
+ lwmem_block_t* block;
+
+ (void)print_alloc;
+ (void)print_free;
+
+ printf("|-------|------------------|--------|------|------------------|-----------------|\r\n");
+ printf("| Block | Address | IsFree | Size | MaxUserAllocSize | Meta |\r\n");
+ printf("|-------|------------------|--------|------|------------------|-----------------|\r\n");
+
+ block = &lwmem_default.start_block_first_use;
+ print_block(0, &lwmem_default.start_block_first_use);
+ printf("|-------|------------------|--------|------|------------------|-----------------|\r\n");
+ for (size_t i = 0, j = 1; i < regions_count; ++i) {
+ block = regions_orig[i].start_addr;
+
+ /* Print all blocks */
+ for (;; ++j) {
+ block_size = block->size & ~LWMEM_ALLOC_BIT;
+
+ print_block(j, block);
+
+ /* Get next block */
+ block = (void*)(LWMEM_TO_BYTE_PTR(block) + block_size);
+ if (block_size == 0) {
+ break;
+ }
+ }
+ printf("|-------|------------------|--------|------|------------------|-----------------|\r\n");
+ }
+}
+
+uint8_t
+lwmem_debug_create_regions(lwmem_region_t** regs_out, size_t count, size_t size) {
+ regions_orig = create_regions(count, size);
+ regions_temp = create_regions(count, size);
+
+ if (regions_orig == NULL || regions_temp == NULL) {
+ return 0;
+ }
+ regions_count = count;
+ *regs_out = regions_orig;
+
+ return 1;
+}
+
+void
+lwmem_debug_save_state(void) {
+ memcpy(&lwmem_temp, &lwmem_default, sizeof(lwmem_temp));
+ for (size_t i = 0; i < regions_count; ++i) {
+ memcpy(regions_temp[i].start_addr, regions_orig[i].start_addr, regions_temp[i].size);
+ }
+ printf(" -- > Current state saved!\r\n");
+}
+
+void
+lwmem_debug_restore_to_saved(void) {
+ memcpy(&lwmem_default, &lwmem_temp, sizeof(lwmem_temp));
+ for (size_t i = 0; i < regions_count; ++i) {
+ memcpy(regions_orig[i].start_addr, regions_temp[i].start_addr, regions_temp[i].size);
+ }
+ printf(" -- > State restored to last saved!\r\n");
+}
+
+void
+lwmem_debug_test_region(void* region_start, size_t region_size, uint8_t** region_start_calc, size_t* region_size_calc) {
+ lwmem_region_t region = {
+ .start_addr = region_start,
+ .size = region_size,
+ };
+ prv_get_region_addr_size(®ion, region_start_calc, region_size_calc);
+}
+
+#endif /* defined(LWMEM_DEV) && !__DOXYGEN__ */
diff --git a/User/system/sgl/mm/lwmem/lwmem.h b/User/system/sgl/mm/lwmem/lwmem.h
new file mode 100644
index 0000000..db96bb4
--- /dev/null
+++ b/User/system/sgl/mm/lwmem/lwmem.h
@@ -0,0 +1,160 @@
+/**
+ * \file lwmem.h
+ * \brief Lightweight dynamic memory manager
+ */
+
+/*
+ * Copyright (c) 2024 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwMEM - Lightweight dynamic memory manager library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v2.2.1
+ */
+#ifndef LWMEM_HDR_H
+#define LWMEM_HDR_H
+
+#include
+#include
+#include
+#include "lwmem_opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \defgroup LWMEM Lightweight dynamic memory manager
+ * \brief Lightweight dynamic memory manager
+ * \{
+ */
+
+/**
+ * \brief Get size of statically allocated array
+ * \param[in] x: Object to get array size of
+ * \return Number of elements in array
+ */
+#define LWMEM_ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/**
+ * \brief Memory block structure
+ */
+typedef struct lwmem_block {
+ struct lwmem_block* next; /*!< Next free memory block on linked list.
+ Set to \ref LWMEM_BLOCK_ALLOC_MARK when block is allocated and in use */
+ size_t size; /*!< Size of block, including metadata part.
+ MSB bit is set to `1` when block is allocated and in use,
+ or `0` when block is considered free */
+} lwmem_block_t;
+
+/**
+ * \brief Statistics structure
+ */
+typedef struct {
+ uint32_t mem_size_bytes; /*!< Total memory size of all regions combined */
+ uint32_t mem_available_bytes; /*!< Free memory available for allocation */
+ uint32_t minimum_ever_mem_available_bytes; /*!< Minimum amount of total free memory there has been
+ in the heap since the system booted. */
+ uint32_t nr_alloc; /*!< Number of all allocated blocks in single instance */
+ uint32_t nr_free; /*!< Number of frees in the LwMEM instance */
+} lwmem_stats_t;
+
+/**
+ * \brief LwMEM main structure
+ */
+typedef struct lwmem {
+ size_t mem_available_bytes; /*!< Memory size available for allocation */
+#if LWMEM_CFG_FULL
+ lwmem_block_t start_block; /*!< Holds beginning of memory allocation regions */
+ lwmem_block_t* end_block; /*!< Pointer to the last memory location in regions linked list */
+ size_t mem_regions_count; /*!< Number of regions used for allocation */
+#else
+ uint8_t* mem_next_available_ptr; /*!< Pointer for next allocation */
+ uint8_t is_initialized; /*!< Set to `1` when initialized */
+#endif
+
+#if LWMEM_CFG_OS || __DOXYGEN__
+ LWMEM_CFG_OS_MUTEX_HANDLE mutex; /*!< System mutex for OS */
+#endif /* LWMEM_CFG_OS || __DOXYGEN__ */
+#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__
+ lwmem_stats_t stats; /*!< Statistics */
+#endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */
+#if defined(LWMEM_DEV) && !__DOXYGEN__
+ lwmem_block_t start_block_first_use; /*!< Value of start block for very first time.
+ This is used only during validation process and is removed in final use */
+#endif /* defined(LWMEM_DEV) && !__DOXYGEN__ */
+} lwmem_t;
+
+/**
+ * \brief Memory region descriptor
+ */
+typedef struct {
+ void* start_addr; /*!< Region start address */
+ size_t size; /*!< Size of region in units of bytes */
+} lwmem_region_t;
+
+size_t lwmem_assignmem_ex(lwmem_t* lwobj, const lwmem_region_t* regions);
+void* lwmem_malloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t size);
+void* lwmem_calloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t nitems, const size_t size);
+#if LWMEM_CFG_FULL || __DOXYGEN__
+void* lwmem_realloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, void* const ptr, const size_t size);
+int lwmem_realloc_s_ex(lwmem_t* lwobj, const lwmem_region_t* region, void** const ptr, const size_t size);
+void lwmem_free_ex(lwmem_t* lwobj, void* const ptr);
+void lwmem_free_s_ex(lwmem_t* lwobj, void** const ptr);
+size_t lwmem_get_size_ex(lwmem_t* lwobj, void* ptr);
+#endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
+#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__
+void lwmem_get_stats_ex(lwmem_t* lwobj, lwmem_stats_t* stats);
+void lwmem_get_size(lwmem_stats_t* stats);
+#endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */
+
+size_t lwmem_assignmem(const lwmem_region_t* regions);
+void* lwmem_malloc(size_t size);
+void* lwmem_calloc(size_t nitems, size_t size);
+
+#if LWMEM_CFG_FULL || __DOXYGEN__
+void* lwmem_realloc(void* ptr, size_t size);
+int lwmem_realloc_s(void** ptr2ptr, size_t size);
+void lwmem_free(void* ptr);
+void lwmem_free_s(void** ptr2ptr);
+size_t lwmem_get_size(void* ptr);
+#endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
+
+#if defined(LWMEM_DEV) && !__DOXYGEN__
+unsigned char lwmem_debug_create_regions(lwmem_region_t** regs_out, size_t count, size_t size);
+void lwmem_debug_save_state(void);
+void lwmem_debug_restore_to_saved(void);
+void lwmem_debug_print(unsigned char print_alloc, unsigned char print_free);
+void lwmem_debug_test_region(void* region_start, size_t region_size, uint8_t** region_start_calc,
+ size_t* region_size_calc);
+#endif /* defined(LWMEM_DEV) && !__DOXYGEN__ */
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWMEM_HDR_H */
diff --git a/User/system/sgl/mm/lwmem/lwmem_opt.h b/User/system/sgl/mm/lwmem/lwmem_opt.h
new file mode 100644
index 0000000..8739238
--- /dev/null
+++ b/User/system/sgl/mm/lwmem/lwmem_opt.h
@@ -0,0 +1,156 @@
+/**
+ * \file lwmem_opt.h
+ * \brief LwMEM options
+ */
+
+/*
+ * Copyright (c) 2024 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwMEM - Lightweight dynamic memory manager library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v2.2.1
+ */
+#ifndef LWMEM_OPT_HDR_H
+#define LWMEM_OPT_HDR_H
+
+/* Uncomment to ignore user options (or set macro in compiler flags) */
+/* #define LWMEM_IGNORE_USER_OPTS */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \defgroup LWMEM_OPT Configuration
+ * \brief LwMEM options
+ * \{
+ */
+
+/**
+ * \brief Enables `1` or disables `0` operating system support in the library
+ *
+ * \note When `LWMEM_CFG_OS` is enabled, user must implement functions in \ref LWMEM_SYS group.
+ */
+#ifndef LWMEM_CFG_OS
+#define LWMEM_CFG_OS 0
+#endif
+
+/**
+ * \brief Mutex handle type
+ *
+ * \note This value must be set in case \ref LWMEM_CFG_OS is set to `1`.
+ * If data type is not known to compiler, include header file with
+ * definition before you define handle type
+ */
+#ifndef LWMEM_CFG_OS_MUTEX_HANDLE
+#define LWMEM_CFG_OS_MUTEX_HANDLE void*
+#endif
+
+/**
+ * \brief Number of bits to align memory address and memory size
+ *
+ * Some CPUs do not offer unaligned memory access (Cortex-M0 as an example)
+ * therefore it is important to have alignment of data addresses and potentialy length of data
+ *
+ * \note This value must be a power of `2` for number of bytes.
+ * Usually alignment of `4` bytes fits to all processors.
+ */
+#ifndef LWMEM_CFG_ALIGN_NUM
+#define LWMEM_CFG_ALIGN_NUM 4
+#endif
+
+/**
+ * \brief Enables `1` or disables `0` full memory management support.
+ *
+ * When enabled (default config), library supports allocation, reallocation and freeing of the memory.
+ * - Memory [c]allocation
+ * - Memory reallocation
+ * - Memory allocation in user defined memory regions
+ * - Memory freeing
+ *
+ * When disabled, library only supports allocation and does not provide any other service.
+ * - Its purpose is for memory allocation at the start of firmware initialization only
+ *
+ * \note When disabled, statistics functionaltiy is not available
+ * and only one region is supported (for now, may be updated later).
+ * API to allocate memory remains the same as for full configuration.
+ */
+#ifndef LWMEM_CFG_FULL
+#define LWMEM_CFG_FULL 1
+#endif
+
+/**
+ * \brief Enables `1` or disables `0` memory cleanup on free operation (or realloc).
+ *
+ * It resets unused memory to `0x00` and prevents other applications seeing old data.
+ * It is disabled by default since it has performance penalties.
+ */
+#ifndef LWMEM_CFG_CLEAN_MEMORY
+#define LWMEM_CFG_CLEAN_MEMORY 0
+#endif
+
+/**
+ * \brief Enables `1` or disables `0` statistics in the library
+ *
+ */
+#ifndef LWMEM_CFG_ENABLE_STATS
+#define LWMEM_CFG_ENABLE_STATS 0
+#endif
+
+/**
+ * \brief Memory set function
+ *
+ * \note Function footprint is the same as \ref memset
+ */
+#ifndef LWMEM_MEMSET
+#define LWMEM_MEMSET(dst, val, len) memset((dst), (val), (len))
+#endif
+
+/**
+ * \brief Memory copy function
+ *
+ * \note Function footprint is the same as \ref memcpy
+ */
+#ifndef LWMEM_MEMCPY
+#define LWMEM_MEMCPY(dst, src, len) memcpy((dst), (src), (len))
+#endif
+
+/**
+ * \brief Memory move function
+ *
+ * \note Function footprint is the same as \ref memmove
+ */
+#ifndef LWMEM_MEMMOVE
+#define LWMEM_MEMMOVE(dst, src, len) memmove((dst), (src), (len))
+#endif
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWMEM_OPT_HDR_H */
diff --git a/User/system/sgl/mm/lwmem/sgl_mm.c b/User/system/sgl/mm/lwmem/sgl_mm.c
new file mode 100644
index 0000000..c648fbd
--- /dev/null
+++ b/User/system/sgl/mm/lwmem/sgl_mm.c
@@ -0,0 +1,137 @@
+/* source/mm/lwmem/sgl_mm.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include "lwmem.h"
+#include
+#include
+
+
+static sgl_mm_monitor_t mem = {
+ .total_size = 0,
+ .free_size = 0,
+ .used_size = 0,
+};
+
+
+/**
+ * @brief initialize memory pool
+ * @param mem_start start address of memory pool
+ * @param len length of memory pool
+ */
+void sgl_mm_init(void *mem_start, size_t len)
+{
+ lwmem_region_t lwmem[] = {
+ {.start_addr = mem_start, .size = len,},
+ { NULL, 0 },
+ };
+
+ lwmem_assignmem(lwmem);
+ mem.total_size += len;
+}
+
+
+/**
+ * @brief add memory pool
+ * @param mem_start start address of memory pool
+ * @param len length of memory pool
+ */
+void sgl_mm_add_pool(void *mem_start, size_t len)
+{
+ lwmem_region_t lwmem[] = {
+ {.start_addr = mem_start, .size = len,},
+ { NULL, 0 },
+ };
+
+ lwmem_assignmem(lwmem);
+ mem.total_size += len;
+}
+
+
+/**
+ * @brief memory alloc, the function is unsafe, you should ensure that
+ * the requested size is smaller than the free size of memory
+ *
+ * @param size request size of memory
+ *
+ * @return point to request memory address
+*/
+void* sgl_malloc(size_t size)
+{
+ void *ret = lwmem_malloc(size);
+ if(ret == NULL) {
+ SGL_LOG_ERROR("out of memory");
+ return NULL;
+ }
+
+ mem.used_size += lwmem_get_size(ret);
+
+ return ret;
+}
+
+
+/**
+ * @brief memory realloc, the function is unsafe, you should ensure that
+ * the requested size is smaller than the free size of memory
+ * @param p the pointer of request size of memory
+ * @param size request size of memory
+ */
+void* sgl_realloc(void *p, size_t size)
+{
+ void *ret = lwmem_realloc(p, size);
+ if(ret == NULL) {
+ SGL_LOG_ERROR("out of memory");
+ return NULL;
+ }
+
+ mem.used_size += size;
+
+ return ret;
+}
+
+
+/**
+ * @brief memory free
+ *
+ * @param p the pointer of request size of memory
+ *
+ * @return none
+*/
+void sgl_free(void *p)
+{
+ mem.used_size -= lwmem_get_size(p);
+ lwmem_free(p);
+}
+
+
+sgl_mm_monitor_t sgl_mm_get_monitor(void)
+{
+ int integer = (mem.used_size * 100) / mem.total_size;
+ int decimal = (mem.used_size * 10000) / mem.total_size - (integer * 100);
+ mem.used_rate = integer << 8 | decimal;
+ mem.free_size = mem.total_size - mem.used_size;
+
+ return mem;
+}
diff --git a/User/system/sgl/mm/other/sgl_mm.c b/User/system/sgl/mm/other/sgl_mm.c
new file mode 100644
index 0000000..9cf4001
--- /dev/null
+++ b/User/system/sgl/mm/other/sgl_mm.c
@@ -0,0 +1,141 @@
+/* source/mm/other/sgl_mm.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file sgl_mm.c
+ * @brief SGL Memory Management - Default (weak) implementations
+ *
+ * @warning DO NOT MODIFY THIS FILE!
+ *
+ * This file provides default weak implementations of the memory management
+ * functions. These functions use the standard C library (malloc/free/realloc).
+ *
+ * To customize memory management for your platform:
+ * 1. Create your own implementation file in your project
+ * 2. Define the same functions WITHOUT the weak attribute
+ * 3. Your implementation will automatically override these defaults
+ *
+ * Functions available for override:
+ * - void* sgl_mm_alloc(size_t size)
+ * - void sgl_mm_free(void *ptr)
+ * - void* sgl_mm_realloc(void *ptr, size_t size)
+ *
+ * Example (in your application code):
+ * @code
+ * void* sgl_mm_alloc(size_t size) {
+ * return my_custom_allocator(size);
+ * }
+ * @endcode
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+static sgl_mm_monitor_t mem = {
+ .total_size = 0,
+ .free_size = 0,
+ .used_size = 0,
+};
+
+
+/**
+ * @brief initialize memory pool
+ * @param mem_start start address of memory pool
+ * @param len length of memory pool
+ */
+void sgl_mm_init(void *mem_start, size_t len)
+{
+ mem.total_size += len;
+}
+
+
+/**
+ * @brief add memory pool
+ * @param mem_start start address of memory pool
+ * @param len length of memory pool
+ */
+void sgl_mm_add_pool(void *mem_start, size_t len)
+{
+
+ mem.total_size += len;
+}
+
+
+/**
+ * @brief memory alloc, the function is unsafe, you should ensure that
+ * the requested size is smaller than the free size of memory
+ *
+ * @param size request size of memory
+ *
+ * @return point to request memory address
+*/
+sgl_weak_fn void* sgl_malloc(size_t size)
+{
+ void *p = malloc(size);
+ memset(p, 0, size);
+ return p;
+}
+
+
+/**
+ * @brief memory realloc, the function is unsafe, you should ensure that
+ * the requested size is smaller than the free size of memory
+ * @param p the pointer of request size of memory
+ * @param size request size of memory
+ */
+sgl_weak_fn void* sgl_realloc(void *p, size_t size)
+{
+ return realloc(p, size);
+}
+
+
+/**
+ * @brief memory free
+ *
+ * @param p the pointer of request size of memory
+ *
+ * @return none
+*/
+sgl_weak_fn void sgl_free(void *p)
+{
+ //mem.used_size -= ;
+ free(p);
+}
+
+
+sgl_mm_monitor_t sgl_mm_get_monitor(void)
+{
+ int integer = (mem.used_size * 100) / mem.total_size;
+ int decimal = (mem.used_size * 10000) / mem.total_size - (integer * 100);
+ mem.used_rate = integer << 8 | decimal;
+ mem.free_size = mem.total_size - mem.used_size;
+
+ return mem;
+}
diff --git a/User/system/sgl/mm/tlsf/sgl_mm.c b/User/system/sgl/mm/tlsf/sgl_mm.c
new file mode 100644
index 0000000..89b851d
--- /dev/null
+++ b/User/system/sgl/mm/tlsf/sgl_mm.c
@@ -0,0 +1,128 @@
+/* source/mm/tlsf/sgl_mm.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "tlsf.h"
+#include
+#include
+#include
+#include
+
+
+static tlsf_t mem_tlsf;
+static sgl_mm_monitor_t mem = {
+ .total_size = 0,
+ .free_size = 0,
+ .used_size = 0,
+};
+
+
+/**
+ * @brief initialize memory pool
+ * @param mem_start start address of memory pool
+ * @param len length of memory pool
+ */
+void sgl_mm_init(void *mem_start, size_t len)
+{
+ mem_tlsf = tlsf_create_with_pool(mem_start, len);
+ mem.total_size += len;
+}
+
+
+/**
+ * @brief add memory pool
+ * @param mem_start start address of memory pool
+ * @param len length of memory pool
+ */
+void sgl_mm_add_pool(void *mem_start, size_t len)
+{
+ tlsf_add_pool(mem_tlsf, mem_start, len);
+ mem.total_size += len;
+}
+
+
+/**
+ * @brief memory alloc, the function is unsafe, you should ensure that
+ * the requested size is smaller than the free size of memory
+ *
+ * @param size request size of memory
+ *
+ * @return point to request memory address
+*/
+void* sgl_malloc(size_t size)
+{
+ void *ret = tlsf_malloc(mem_tlsf, size);
+ if(ret == NULL) {
+ SGL_LOG_ERROR("out of memory");
+ return NULL;
+ }
+
+ mem.used_size += size;
+ return ret;
+}
+
+
+/**
+ * @brief memory realloc, the function is unsafe, you should ensure that
+ * the requested size is smaller than the free size of memory
+ * @param p the pointer of request size of memory
+ * @param size request size of memory
+ */
+void* sgl_realloc(void *p, size_t size)
+{
+ void *ret = tlsf_realloc(mem_tlsf, p, size);
+ if(ret == NULL) {
+ SGL_LOG_ERROR("out of memory");
+ return NULL;
+ }
+
+ mem.used_size += size;
+
+ return ret;
+}
+
+
+/**
+ * @brief memory free
+ *
+ * @param p the pointer of request size of memory
+ *
+ * @return none
+*/
+void sgl_free(void *p)
+{
+ mem.used_size -= tlsf_block_size(p);
+
+ tlsf_free(mem_tlsf, p);
+}
+
+
+sgl_mm_monitor_t sgl_mm_get_monitor(void)
+{
+ int integer = (mem.used_size * 100) / mem.total_size;
+ int decimal = (mem.used_size * 10000) / mem.total_size - (integer * 100);
+ mem.used_rate = integer << 8 | decimal;
+ mem.free_size = mem.total_size - mem.used_size;
+
+ return mem;
+}
diff --git a/User/system/sgl/mm/tlsf/tlsf.c b/User/system/sgl/mm/tlsf/tlsf.c
new file mode 100644
index 0000000..13344ff
--- /dev/null
+++ b/User/system/sgl/mm/tlsf/tlsf.c
@@ -0,0 +1,1265 @@
+#include
+#include
+#include
+#include
+#include
+#include "tlsf.h"
+
+
+#if defined(__cplusplus)
+#define tlsf_decl inline
+#else
+#define tlsf_decl static
+#endif
+
+/*
+** Architecture-specific bit manipulation routines.
+**
+** TLSF achieves O(1) cost for malloc and free operations by limiting
+** the search for a free block to a free list of guaranteed size
+** adequate to fulfill the request, combined with efficient free list
+** queries using bitmasks and architecture-specific bit-manipulation
+** routines.
+**
+** Most modern processors provide instructions to count leading zeroes
+** in a word, find the lowest and highest set bit, etc. These
+** specific implementations will be used when available, falling back
+** to a reasonably efficient generic implementation.
+**
+** NOTE: TLSF spec relies on ffs/fls returning value 0..31.
+** ffs/fls return 1-32 by default, returning 0 for error.
+*/
+
+/*
+** Detect whether or not we are building for a 32- or 64-bit (LP/LLP)
+** architecture. There is no reliable portable method at compile-time.
+*/
+#if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) \
+ || defined (_WIN64) || defined (__LP64__) || defined (__LLP64__)
+#define TLSF_64BIT
+#endif
+
+/*
+** gcc 3.4 and above have builtin support, specialized for architecture.
+** Some compilers masquerade as gcc; patchlevel test filters them out.
+*/
+#if defined (__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
+ && defined (__GNUC_PATCHLEVEL__)
+
+#if defined (__SNC__)
+/* SNC for Playstation 3. */
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+ const unsigned int reverse = word & (~word + 1);
+ const int bit = 32 - __builtin_clz(reverse);
+ return bit - 1;
+}
+
+#else
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+ return __builtin_ffs(word) - 1;
+}
+
+#endif
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+ const int bit = word ? 32 - __builtin_clz(word) : 0;
+ return bit - 1;
+}
+
+#elif defined (_MSC_VER) && (_MSC_VER >= 1400) && (defined (_M_IX86) || defined (_M_X64))
+/* Microsoft Visual C++ support on x86/X64 architectures. */
+
+#include
+
+#pragma intrinsic(_BitScanReverse)
+#pragma intrinsic(_BitScanForward)
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+ unsigned long index;
+ return _BitScanReverse(&index, word) ? index : -1;
+}
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+ unsigned long index;
+ return _BitScanForward(&index, word) ? index : -1;
+}
+
+#elif defined (_MSC_VER) && defined (_M_PPC)
+/* Microsoft Visual C++ support on PowerPC architectures. */
+
+#include
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+ const int bit = 32 - _CountLeadingZeros(word);
+ return bit - 1;
+}
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+ const unsigned int reverse = word & (~word + 1);
+ const int bit = 32 - _CountLeadingZeros(reverse);
+ return bit - 1;
+}
+
+#elif defined (__ARMCC_VERSION)
+/* RealView Compilation Tools for ARM */
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+ const unsigned int reverse = word & (~word + 1);
+ const int bit = 32 - __clz(reverse);
+ return bit - 1;
+}
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+ const int bit = word ? 32 - __clz(word) : 0;
+ return bit - 1;
+}
+
+#elif defined (__ghs__)
+/* Green Hills support for PowerPC */
+
+#include
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+ const unsigned int reverse = word & (~word + 1);
+ const int bit = 32 - __CLZ32(reverse);
+ return bit - 1;
+}
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+ const int bit = word ? 32 - __CLZ32(word) : 0;
+ return bit - 1;
+}
+
+#else
+/* Fall back to generic implementation. */
+
+tlsf_decl int tlsf_fls_generic(unsigned int word)
+{
+ int bit = 32;
+
+ if (!word) bit -= 1;
+ if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; }
+ if (!(word & 0xff000000)) { word <<= 8; bit -= 8; }
+ if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; }
+ if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; }
+ if (!(word & 0x80000000)) { word <<= 1; bit -= 1; }
+
+ return bit;
+}
+
+/* Implement ffs in terms of fls. */
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+ return tlsf_fls_generic(word & (~word + 1)) - 1;
+}
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+ return tlsf_fls_generic(word) - 1;
+}
+
+#endif
+
+/* Possibly 64-bit version of tlsf_fls. */
+#if defined (TLSF_64BIT)
+tlsf_decl int tlsf_fls_sizet(size_t size)
+{
+ int high = (int)(size >> 32);
+ int bits = 0;
+ if (high)
+ {
+ bits = 32 + tlsf_fls(high);
+ }
+ else
+ {
+ bits = tlsf_fls((int)size & 0xffffffff);
+
+ }
+ return bits;
+}
+#else
+#define tlsf_fls_sizet tlsf_fls
+#endif
+
+#undef tlsf_decl
+
+/*
+** Constants.
+*/
+
+/* Public constants: may be modified. */
+enum tlsf_public
+{
+ /* log2 of number of linear subdivisions of block sizes. Larger
+ ** values require more memory in the control structure. Values of
+ ** 4 or 5 are typical.
+ */
+ SL_INDEX_COUNT_LOG2 = 5,
+};
+
+/* Private constants: do not modify. */
+enum tlsf_private
+{
+#if defined (TLSF_64BIT)
+ /* All allocation sizes and addresses are aligned to 8 bytes. */
+ ALIGN_SIZE_LOG2 = 3,
+#else
+ /* All allocation sizes and addresses are aligned to 4 bytes. */
+ ALIGN_SIZE_LOG2 = 2,
+#endif
+ ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2),
+
+ /*
+ ** We support allocations of sizes up to (1 << FL_INDEX_MAX) bits.
+ ** However, because we linearly subdivide the second-level lists, and
+ ** our minimum size granularity is 4 bytes, it doesn't make sense to
+ ** create first-level lists for sizes smaller than SL_INDEX_COUNT * 4,
+ ** or (1 << (SL_INDEX_COUNT_LOG2 + 2)) bytes, as there we will be
+ ** trying to split size ranges into more slots than we have available.
+ ** Instead, we calculate the minimum threshold size, and place all
+ ** blocks below that size into the 0th first-level list.
+ */
+
+#if defined (TLSF_64BIT)
+ /*
+ ** TODO: We can increase this to support larger sizes, at the expense
+ ** of more overhead in the TLSF structure.
+ */
+ FL_INDEX_MAX = 32, //MAX 4GB
+#else
+ FL_INDEX_MAX = CONFIG_SGL_FL_INDEX_MAX,
+#endif
+ SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2),
+ FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2),
+ FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1),
+
+ SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT),
+};
+
+/*
+** Cast and min/max macros.
+*/
+
+#define tlsf_cast(t, exp) ((t) (exp))
+#define tlsf_min(a, b) ((a) < (b) ? (a) : (b))
+#define tlsf_max(a, b) ((a) > (b) ? (a) : (b))
+
+/*
+** Set assert macro, if it has not been provided by the user.
+*/
+#if CONFIG_SGL_DEBUG
+#define tlsf_assert SGL_ASSERT
+#else
+#define tlsf_assert
+#endif
+
+/*
+** Static assertion mechanism.
+*/
+
+#define _tlsf_glue2(x, y) x ## y
+#define _tlsf_glue(x, y) _tlsf_glue2(x, y)
+#define tlsf_static_assert(exp) \
+ typedef char _tlsf_glue(static_assert, __LINE__) [(exp) ? 1 : -1]
+
+/* This code has been tested on 32- and 64-bit (LP/LLP) architectures. */
+tlsf_static_assert(sizeof(int) * CHAR_BIT == 32);
+tlsf_static_assert(sizeof(size_t) * CHAR_BIT >= 32);
+tlsf_static_assert(sizeof(size_t) * CHAR_BIT <= 64);
+
+/* SL_INDEX_COUNT must be <= number of bits in sl_bitmap's storage type. */
+tlsf_static_assert(sizeof(unsigned int) * CHAR_BIT >= SL_INDEX_COUNT);
+
+/* Ensure we've properly tuned our sizes. */
+tlsf_static_assert(ALIGN_SIZE == SMALL_BLOCK_SIZE / SL_INDEX_COUNT);
+
+/*
+** Data structures and associated constants.
+*/
+
+/*
+** Block header structure.
+**
+** There are several implementation subtleties involved:
+** - The prev_phys_block field is only valid if the previous block is free.
+** - The prev_phys_block field is actually stored at the end of the
+** previous block. It appears at the beginning of this structure only to
+** simplify the implementation.
+** - The next_free / prev_free fields are only valid if the block is free.
+*/
+typedef struct block_header_t
+{
+ /* Points to the previous physical block. */
+ struct block_header_t* prev_phys_block;
+
+ /* The size of this block, excluding the block header. */
+ size_t size;
+
+ /* Next and previous free blocks. */
+ struct block_header_t* next_free;
+ struct block_header_t* prev_free;
+} block_header_t;
+
+/*
+** Since block sizes are always at least a multiple of 4, the two least
+** significant bits of the size field are used to store the block status:
+** - bit 0: whether block is busy or free
+** - bit 1: whether previous block is busy or free
+*/
+static const size_t block_header_free_bit = 1 << 0;
+static const size_t block_header_prev_free_bit = 1 << 1;
+
+/*
+** The size of the block header exposed to used blocks is the size field.
+** The prev_phys_block field is stored *inside* the previous free block.
+*/
+static const size_t block_header_overhead = sizeof(size_t);
+
+/* User data starts directly after the size field in a used block. */
+static const size_t block_start_offset =
+ offsetof(block_header_t, size) + sizeof(size_t);
+
+/*
+** A free block must be large enough to store its header minus the size of
+** the prev_phys_block field, and no larger than the number of addressable
+** bits for FL_INDEX.
+*/
+static const size_t block_size_min =
+ sizeof(block_header_t) - sizeof(block_header_t*);
+static const size_t block_size_max = tlsf_cast(size_t, 1) << FL_INDEX_MAX;
+
+
+/* The TLSF control structure. */
+typedef struct control_t
+{
+ /* Empty lists point at this block to indicate they are free. */
+ block_header_t block_null;
+
+ /* Bitmaps for free lists. */
+ unsigned int fl_bitmap;
+ unsigned int sl_bitmap[FL_INDEX_COUNT];
+
+ /* Head of free lists. */
+ block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT];
+} control_t;
+
+/* A type used for casting when doing pointer arithmetic. */
+typedef ptrdiff_t tlsfptr_t;
+
+/*
+** block_header_t member functions.
+*/
+
+static size_t block_size(const block_header_t* block)
+{
+ return block->size & ~(block_header_free_bit | block_header_prev_free_bit);
+}
+
+static void block_set_size(block_header_t* block, size_t size)
+{
+ const size_t oldsize = block->size;
+ block->size = size | (oldsize & (block_header_free_bit | block_header_prev_free_bit));
+}
+
+static int block_is_last(const block_header_t* block)
+{
+ return block_size(block) == 0;
+}
+
+static int block_is_free(const block_header_t* block)
+{
+ return tlsf_cast(int, block->size & block_header_free_bit);
+}
+
+static void block_set_free(block_header_t* block)
+{
+ block->size |= block_header_free_bit;
+}
+
+static void block_set_used(block_header_t* block)
+{
+ block->size &= ~block_header_free_bit;
+}
+
+static int block_is_prev_free(const block_header_t* block)
+{
+ return tlsf_cast(int, block->size & block_header_prev_free_bit);
+}
+
+static void block_set_prev_free(block_header_t* block)
+{
+ block->size |= block_header_prev_free_bit;
+}
+
+static void block_set_prev_used(block_header_t* block)
+{
+ block->size &= ~block_header_prev_free_bit;
+}
+
+static block_header_t* block_from_ptr(const void* ptr)
+{
+ return tlsf_cast(block_header_t*,
+ tlsf_cast(unsigned char*, ptr) - block_start_offset);
+}
+
+static void* block_to_ptr(const block_header_t* block)
+{
+ return tlsf_cast(void*,
+ tlsf_cast(unsigned char*, block) + block_start_offset);
+}
+
+/* Return location of next block after block of given size. */
+static block_header_t* offset_to_block(const void* ptr, size_t size)
+{
+ return tlsf_cast(block_header_t*, tlsf_cast(tlsfptr_t, ptr) + size);
+}
+
+/* Return location of previous block. */
+static block_header_t* block_prev(const block_header_t* block)
+{
+ tlsf_assert(block_is_prev_free(block) && "previous block must be free");
+ return block->prev_phys_block;
+}
+
+/* Return location of next existing block. */
+static block_header_t* block_next(const block_header_t* block)
+{
+ block_header_t* next = offset_to_block(block_to_ptr(block),
+ block_size(block) - block_header_overhead);
+ tlsf_assert(!block_is_last(block));
+ return next;
+}
+
+/* Link a new block with its physical neighbor, return the neighbor. */
+static block_header_t* block_link_next(block_header_t* block)
+{
+ block_header_t* next = block_next(block);
+ next->prev_phys_block = block;
+ return next;
+}
+
+static void block_mark_as_free(block_header_t* block)
+{
+ /* Link the block to the next block, first. */
+ block_header_t* next = block_link_next(block);
+ block_set_prev_free(next);
+ block_set_free(block);
+}
+
+static void block_mark_as_used(block_header_t* block)
+{
+ block_header_t* next = block_next(block);
+ block_set_prev_used(next);
+ block_set_used(block);
+}
+
+static size_t align_up(size_t x, size_t align)
+{
+ tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two");
+ return (x + (align - 1)) & ~(align - 1);
+}
+
+static size_t align_down(size_t x, size_t align)
+{
+ tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two");
+ return x - (x & (align - 1));
+}
+
+static void* align_ptr(const void* ptr, size_t align)
+{
+ const tlsfptr_t aligned =
+ (tlsf_cast(tlsfptr_t, ptr) + (align - 1)) & ~(align - 1);
+ tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two");
+ return tlsf_cast(void*, aligned);
+}
+
+/*
+** Adjust an allocation size to be aligned to word size, and no smaller
+** than internal minimum.
+*/
+static size_t adjust_request_size(size_t size, size_t align)
+{
+ size_t adjust = 0;
+ if (size)
+ {
+ const size_t aligned = align_up(size, align);
+
+ /* aligned sized must not exceed block_size_max or we'll go out of bounds on sl_bitmap */
+ if (aligned < block_size_max)
+ {
+ adjust = tlsf_max(aligned, block_size_min);
+ }
+ }
+ return adjust;
+}
+
+/*
+** TLSF utility functions. In most cases, these are direct translations of
+** the documentation found in the white paper.
+*/
+
+static void mapping_insert(size_t size, int* fli, int* sli)
+{
+ int fl, sl;
+ if (size < SMALL_BLOCK_SIZE)
+ {
+ /* Store small blocks in first list. */
+ fl = 0;
+ sl = tlsf_cast(int, size) / (SMALL_BLOCK_SIZE / SL_INDEX_COUNT);
+ }
+ else
+ {
+ fl = tlsf_fls_sizet(size);
+ sl = tlsf_cast(int, size >> (fl - SL_INDEX_COUNT_LOG2)) ^ (1 << SL_INDEX_COUNT_LOG2);
+ fl -= (FL_INDEX_SHIFT - 1);
+ }
+ *fli = fl;
+ *sli = sl;
+}
+
+/* This version rounds up to the next block size (for allocations) */
+static void mapping_search(size_t size, int* fli, int* sli)
+{
+ if (size >= SMALL_BLOCK_SIZE)
+ {
+ const size_t round = (1 << (tlsf_fls_sizet(size) - SL_INDEX_COUNT_LOG2)) - 1;
+ size += round;
+ }
+ mapping_insert(size, fli, sli);
+}
+
+static block_header_t* search_suitable_block(control_t* control, int* fli, int* sli)
+{
+ int fl = *fli;
+ int sl = *sli;
+
+ /*
+ ** First, search for a block in the list associated with the given
+ ** fl/sl index.
+ */
+ unsigned int sl_map = control->sl_bitmap[fl] & (~0U << sl);
+ if (!sl_map)
+ {
+ /* No block exists. Search in the next largest first-level list. */
+ const unsigned int fl_map = control->fl_bitmap & (~0U << (fl + 1));
+ if (!fl_map)
+ {
+ /* No free blocks available, memory has been exhausted. */
+ return 0;
+ }
+
+ fl = tlsf_ffs(fl_map);
+ *fli = fl;
+ sl_map = control->sl_bitmap[fl];
+ }
+ tlsf_assert(sl_map && "internal error - second level bitmap is null");
+ sl = tlsf_ffs(sl_map);
+ *sli = sl;
+
+ /* Return the first block in the free list. */
+ return control->blocks[fl][sl];
+}
+
+/* Remove a free block from the free list.*/
+static void remove_free_block(control_t* control, block_header_t* block, int fl, int sl)
+{
+ block_header_t* prev = block->prev_free;
+ block_header_t* next = block->next_free;
+ tlsf_assert(prev && "prev_free field can not be null");
+ tlsf_assert(next && "next_free field can not be null");
+ next->prev_free = prev;
+ prev->next_free = next;
+
+ /* If this block is the head of the free list, set new head. */
+ if (control->blocks[fl][sl] == block)
+ {
+ control->blocks[fl][sl] = next;
+
+ /* If the new head is null, clear the bitmap. */
+ if (next == &control->block_null)
+ {
+ control->sl_bitmap[fl] &= ~(1U << sl);
+
+ /* If the second bitmap is now empty, clear the fl bitmap. */
+ if (!control->sl_bitmap[fl])
+ {
+ control->fl_bitmap &= ~(1U << fl);
+ }
+ }
+ }
+}
+
+/* Insert a free block into the free block list. */
+static void insert_free_block(control_t* control, block_header_t* block, int fl, int sl)
+{
+ block_header_t* current = control->blocks[fl][sl];
+ tlsf_assert(current && "free list cannot have a null entry");
+ tlsf_assert(block && "cannot insert a null entry into the free list");
+ block->next_free = current;
+ block->prev_free = &control->block_null;
+ current->prev_free = block;
+
+ tlsf_assert(block_to_ptr(block) == align_ptr(block_to_ptr(block), ALIGN_SIZE)
+ && "block not aligned properly");
+ /*
+ ** Insert the new block at the head of the list, and mark the first-
+ ** and second-level bitmaps appropriately.
+ */
+ control->blocks[fl][sl] = block;
+ control->fl_bitmap |= (1U << fl);
+ control->sl_bitmap[fl] |= (1U << sl);
+}
+
+/* Remove a given block from the free list. */
+static void block_remove(control_t* control, block_header_t* block)
+{
+ int fl, sl;
+ mapping_insert(block_size(block), &fl, &sl);
+ remove_free_block(control, block, fl, sl);
+}
+
+/* Insert a given block into the free list. */
+static void block_insert(control_t* control, block_header_t* block)
+{
+ int fl, sl;
+ mapping_insert(block_size(block), &fl, &sl);
+ insert_free_block(control, block, fl, sl);
+}
+
+static int block_can_split(block_header_t* block, size_t size)
+{
+ return block_size(block) >= sizeof(block_header_t) + size;
+}
+
+/* Split a block into two, the second of which is free. */
+static block_header_t* block_split(block_header_t* block, size_t size)
+{
+ /* Calculate the amount of space left in the remaining block. */
+ block_header_t* remaining =
+ offset_to_block(block_to_ptr(block), size - block_header_overhead);
+
+ const size_t remain_size = block_size(block) - (size + block_header_overhead);
+
+ tlsf_assert(block_to_ptr(remaining) == align_ptr(block_to_ptr(remaining), ALIGN_SIZE)
+ && "remaining block not aligned properly");
+
+ tlsf_assert(block_size(block) == remain_size + size + block_header_overhead);
+ block_set_size(remaining, remain_size);
+ tlsf_assert(block_size(remaining) >= block_size_min && "block split with invalid size");
+
+ block_set_size(block, size);
+ block_mark_as_free(remaining);
+
+ return remaining;
+}
+
+/* Absorb a free block's storage into an adjacent previous free block. */
+static block_header_t* block_absorb(block_header_t* prev, block_header_t* block)
+{
+ tlsf_assert(!block_is_last(prev) && "previous block can't be last");
+ /* Note: Leaves flags untouched. */
+ prev->size += block_size(block) + block_header_overhead;
+ block_link_next(prev);
+ return prev;
+}
+
+/* Merge a just-freed block with an adjacent previous free block. */
+static block_header_t* block_merge_prev(control_t* control, block_header_t* block)
+{
+ if (block_is_prev_free(block))
+ {
+ block_header_t* prev = block_prev(block);
+ tlsf_assert(prev && "prev physical block can't be null");
+ tlsf_assert(block_is_free(prev) && "prev block is not free though marked as such");
+ block_remove(control, prev);
+ block = block_absorb(prev, block);
+ }
+
+ return block;
+}
+
+/* Merge a just-freed block with an adjacent free block. */
+static block_header_t* block_merge_next(control_t* control, block_header_t* block)
+{
+ block_header_t* next = block_next(block);
+ tlsf_assert(next && "next physical block can't be null");
+
+ if (block_is_free(next))
+ {
+ tlsf_assert(!block_is_last(block) && "previous block can't be last");
+ block_remove(control, next);
+ block = block_absorb(block, next);
+ }
+
+ return block;
+}
+
+/* Trim any trailing block space off the end of a block, return to pool. */
+static void block_trim_free(control_t* control, block_header_t* block, size_t size)
+{
+ tlsf_assert(block_is_free(block) && "block must be free");
+ if (block_can_split(block, size))
+ {
+ block_header_t* remaining_block = block_split(block, size);
+ block_link_next(block);
+ block_set_prev_free(remaining_block);
+ block_insert(control, remaining_block);
+ }
+}
+
+/* Trim any trailing block space off the end of a used block, return to pool. */
+static void block_trim_used(control_t* control, block_header_t* block, size_t size)
+{
+ tlsf_assert(!block_is_free(block) && "block must be used");
+ if (block_can_split(block, size))
+ {
+ /* If the next block is free, we must coalesce. */
+ block_header_t* remaining_block = block_split(block, size);
+ block_set_prev_used(remaining_block);
+
+ remaining_block = block_merge_next(control, remaining_block);
+ block_insert(control, remaining_block);
+ }
+}
+
+static block_header_t* block_trim_free_leading(control_t* control, block_header_t* block, size_t size)
+{
+ block_header_t* remaining_block = block;
+ if (block_can_split(block, size))
+ {
+ /* We want the 2nd block. */
+ remaining_block = block_split(block, size - block_header_overhead);
+ block_set_prev_free(remaining_block);
+
+ block_link_next(block);
+ block_insert(control, block);
+ }
+
+ return remaining_block;
+}
+
+static block_header_t* block_locate_free(control_t* control, size_t size)
+{
+ int fl = 0, sl = 0;
+ block_header_t* block = 0;
+
+ if (size)
+ {
+ mapping_search(size, &fl, &sl);
+
+ /*
+ ** mapping_search can futz with the size, so for excessively large sizes it can sometimes wind up
+ ** with indices that are off the end of the block array.
+ ** So, we protect against that here, since this is the only callsite of mapping_search.
+ ** Note that we don't need to check sl, since it comes from a modulo operation that guarantees it's always in range.
+ */
+ if (fl < FL_INDEX_COUNT)
+ {
+ block = search_suitable_block(control, &fl, &sl);
+ }
+ }
+
+ if (block)
+ {
+ tlsf_assert(block_size(block) >= size);
+ remove_free_block(control, block, fl, sl);
+ }
+
+ return block;
+}
+
+static void* block_prepare_used(control_t* control, block_header_t* block, size_t size)
+{
+ void* p = 0;
+ if (block)
+ {
+ tlsf_assert(size && "size must be non-zero");
+ block_trim_free(control, block, size);
+ block_mark_as_used(block);
+ p = block_to_ptr(block);
+ }
+ return p;
+}
+
+/* Clear structure and point all empty lists at the null block. */
+static void control_construct(control_t* control)
+{
+ int i, j;
+
+ control->block_null.next_free = &control->block_null;
+ control->block_null.prev_free = &control->block_null;
+
+ control->fl_bitmap = 0;
+ for (i = 0; i < FL_INDEX_COUNT; ++i)
+ {
+ control->sl_bitmap[i] = 0;
+ for (j = 0; j < SL_INDEX_COUNT; ++j)
+ {
+ control->blocks[i][j] = &control->block_null;
+ }
+ }
+}
+
+/*
+** Debugging utilities.
+*/
+
+typedef struct integrity_t
+{
+ int prev_status;
+ int status;
+} integrity_t;
+
+#define tlsf_insist(x) { tlsf_assert(x); if (!(x)) { status--; } }
+
+static void integrity_walker(void* ptr, size_t size, int used, void* user)
+{
+ block_header_t* block = block_from_ptr(ptr);
+ integrity_t* integ = tlsf_cast(integrity_t*, user);
+ const int this_prev_status = block_is_prev_free(block) ? 1 : 0;
+ const int this_status = block_is_free(block) ? 1 : 0;
+ const size_t this_block_size = block_size(block);
+
+ int status = 0;
+ (void)used;
+ tlsf_insist(integ->prev_status == this_prev_status && "prev status incorrect");
+ tlsf_insist(size == this_block_size && "block size incorrect");
+
+ integ->prev_status = this_status;
+ integ->status += status;
+}
+
+int tlsf_check(tlsf_t tlsf)
+{
+ int i, j;
+
+ control_t* control = tlsf_cast(control_t*, tlsf);
+ int status = 0;
+
+ /* Check that the free lists and bitmaps are accurate. */
+ for (i = 0; i < FL_INDEX_COUNT; ++i)
+ {
+ for (j = 0; j < SL_INDEX_COUNT; ++j)
+ {
+ const int fl_map = control->fl_bitmap & (1U << i);
+ const int sl_list = control->sl_bitmap[i];
+ const int sl_map = sl_list & (1U << j);
+ const block_header_t* block = control->blocks[i][j];
+
+ /* Check that first- and second-level lists agree. */
+ if (!fl_map)
+ {
+ tlsf_insist(!sl_map && "second-level map must be null");
+ }
+
+ if (!sl_map)
+ {
+ tlsf_insist(block == &control->block_null && "block list must be null");
+ continue;
+ }
+
+ /* Check that there is at least one free block. */
+ tlsf_insist(sl_list && "no free blocks in second-level map");
+ tlsf_insist(block != &control->block_null && "block should not be null");
+
+ while (block != &control->block_null)
+ {
+ int fli, sli;
+ tlsf_insist(block_is_free(block) && "block should be free");
+ tlsf_insist(!block_is_prev_free(block) && "blocks should have coalesced");
+ tlsf_insist(!block_is_free(block_next(block)) && "blocks should have coalesced");
+ tlsf_insist(block_is_prev_free(block_next(block)) && "block should be free");
+ tlsf_insist(block_size(block) >= block_size_min && "block not minimum size");
+
+ mapping_insert(block_size(block), &fli, &sli);
+ tlsf_insist(fli == i && sli == j && "block size indexed in wrong list");
+ block = block->next_free;
+ }
+ }
+ }
+
+ return status;
+}
+
+#undef tlsf_insist
+
+static void default_walker(void* ptr, size_t size, int used, void* user)
+{
+ (void)user;
+ SGL_LOG_INFO("\t%p %s size: %x (%p)\n", ptr, used ? "used" : "free", (unsigned int)size, block_from_ptr(ptr));
+}
+
+void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user)
+{
+ tlsf_walker pool_walker = walker ? walker : default_walker;
+ block_header_t* block =
+ offset_to_block(pool, -(int)block_header_overhead);
+
+ while (block && !block_is_last(block))
+ {
+ pool_walker(
+ block_to_ptr(block),
+ block_size(block),
+ !block_is_free(block),
+ user);
+ block = block_next(block);
+ }
+}
+
+size_t tlsf_block_size(void* ptr)
+{
+ size_t size = 0;
+ if (ptr)
+ {
+ const block_header_t* block = block_from_ptr(ptr);
+ size = block_size(block);
+ }
+ return size;
+}
+
+int tlsf_check_pool(pool_t pool)
+{
+ /* Check that the blocks are physically correct. */
+ integrity_t integ = { 0, 0 };
+ tlsf_walk_pool(pool, integrity_walker, &integ);
+
+ return integ.status;
+}
+
+/*
+** Size of the TLSF structures in a given memory block passed to
+** tlsf_create, equal to the size of a control_t
+*/
+size_t tlsf_size(void)
+{
+ return sizeof(control_t);
+}
+
+size_t tlsf_align_size(void)
+{
+ return ALIGN_SIZE;
+}
+
+size_t tlsf_block_size_min(void)
+{
+ return block_size_min;
+}
+
+size_t tlsf_block_size_max(void)
+{
+ return block_size_max;
+}
+
+/*
+** Overhead of the TLSF structures in a given memory block passed to
+** tlsf_add_pool, equal to the overhead of a free block and the
+** sentinel block.
+*/
+size_t tlsf_pool_overhead(void)
+{
+ return 2 * block_header_overhead;
+}
+
+size_t tlsf_alloc_overhead(void)
+{
+ return block_header_overhead;
+}
+
+pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
+{
+ block_header_t* block;
+ block_header_t* next;
+
+ const size_t pool_overhead = tlsf_pool_overhead();
+ const size_t pool_bytes = align_down(bytes - pool_overhead, ALIGN_SIZE);
+
+ if (((ptrdiff_t)mem % ALIGN_SIZE) != 0)
+ {
+ SGL_LOG_INFO("tlsf_add_pool: Memory must be aligned by %u bytes.\n",
+ (unsigned int)ALIGN_SIZE);
+ return 0;
+ }
+
+ if (pool_bytes < block_size_min || pool_bytes > block_size_max)
+ {
+#if defined (TLSF_64BIT)
+ SGL_LOG_INFO("tlsf_add_pool: Memory size must be between 0x%x and 0x%x00 bytes.\n",
+ (unsigned int)(pool_overhead + block_size_min),
+ (unsigned int)((pool_overhead + block_size_max) / 256));
+#else
+ SGL_LOG_INFO("tlsf_add_pool: Memory size must be between %u and %u bytes.\n",
+ (unsigned int)(pool_overhead + block_size_min),
+ (unsigned int)(pool_overhead + block_size_max));
+#endif
+ return 0;
+ }
+
+ /*
+ ** Create the main free block. Offset the start of the block slightly
+ ** so that the prev_phys_block field falls outside of the pool -
+ ** it will never be used.
+ */
+ block = offset_to_block(mem, -(tlsfptr_t)block_header_overhead);
+ block_set_size(block, pool_bytes);
+ block_set_free(block);
+ block_set_prev_used(block);
+ block_insert(tlsf_cast(control_t*, tlsf), block);
+
+ /* Split the block to create a zero-size sentinel block. */
+ next = block_link_next(block);
+ block_set_size(next, 0);
+ block_set_used(next);
+ block_set_prev_free(next);
+
+ return mem;
+}
+
+void tlsf_remove_pool(tlsf_t tlsf, pool_t pool)
+{
+ control_t* control = tlsf_cast(control_t*, tlsf);
+ block_header_t* block = offset_to_block(pool, -(int)block_header_overhead);
+
+ int fl = 0, sl = 0;
+
+ tlsf_assert(block_is_free(block) && "block should be free");
+ tlsf_assert(!block_is_free(block_next(block)) && "next block should not be free");
+ tlsf_assert(block_size(block_next(block)) == 0 && "next block size should be zero");
+
+ mapping_insert(block_size(block), &fl, &sl);
+ remove_free_block(control, block, fl, sl);
+}
+
+/*
+** TLSF main interface.
+*/
+
+#if _DEBUG
+int test_ffs_fls()
+{
+ /* Verify ffs/fls work properly. */
+ int rv = 0;
+ rv += (tlsf_ffs(0) == -1) ? 0 : 0x1;
+ rv += (tlsf_fls(0) == -1) ? 0 : 0x2;
+ rv += (tlsf_ffs(1) == 0) ? 0 : 0x4;
+ rv += (tlsf_fls(1) == 0) ? 0 : 0x8;
+ rv += (tlsf_ffs(0x80000000) == 31) ? 0 : 0x10;
+ rv += (tlsf_ffs(0x80008000) == 15) ? 0 : 0x20;
+ rv += (tlsf_fls(0x80000008) == 31) ? 0 : 0x40;
+ rv += (tlsf_fls(0x7FFFFFFF) == 30) ? 0 : 0x80;
+
+#if defined (TLSF_64BIT)
+ rv += (tlsf_fls_sizet(0x80000000) == 31) ? 0 : 0x100;
+ rv += (tlsf_fls_sizet(0x100000000) == 32) ? 0 : 0x200;
+ rv += (tlsf_fls_sizet(0xffffffffffffffff) == 63) ? 0 : 0x400;
+#endif
+
+ if (rv)
+ {
+ SGL_LOG_INFO("test_ffs_fls: %x ffs/fls tests failed.\n", rv);
+ }
+ return rv;
+}
+#endif
+
+tlsf_t tlsf_create(void* mem)
+{
+#if _DEBUG
+ if (test_ffs_fls())
+ {
+ return 0;
+ }
+#endif
+
+ if (((tlsfptr_t)mem % ALIGN_SIZE) != 0)
+ {
+ SGL_LOG_INFO("tlsf_create: Memory must be aligned to %u bytes.\n",
+ (unsigned int)ALIGN_SIZE);
+ return 0;
+ }
+
+ control_construct(tlsf_cast(control_t*, mem));
+
+ return tlsf_cast(tlsf_t, mem);
+}
+
+tlsf_t tlsf_create_with_pool(void* mem, size_t bytes)
+{
+ tlsf_t tlsf = tlsf_create(mem);
+ tlsf_add_pool(tlsf, (char*)mem + tlsf_size(), bytes - tlsf_size());
+ return tlsf;
+}
+
+void tlsf_destroy(tlsf_t tlsf)
+{
+ /* Nothing to do. */
+ (void)tlsf;
+}
+
+pool_t tlsf_get_pool(tlsf_t tlsf)
+{
+ return tlsf_cast(pool_t, (char*)tlsf + tlsf_size());
+}
+
+void* tlsf_malloc(tlsf_t tlsf, size_t size)
+{
+ control_t* control = tlsf_cast(control_t*, tlsf);
+ const size_t adjust = adjust_request_size(size, ALIGN_SIZE);
+ block_header_t* block = block_locate_free(control, adjust);
+ return block_prepare_used(control, block, adjust);
+}
+
+void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t size)
+{
+ control_t* control = tlsf_cast(control_t*, tlsf);
+ const size_t adjust = adjust_request_size(size, ALIGN_SIZE);
+
+ /*
+ ** We must allocate an additional minimum block size bytes so that if
+ ** our free block will leave an alignment gap which is smaller, we can
+ ** trim a leading free block and release it back to the pool. We must
+ ** do this because the previous physical block is in use, therefore
+ ** the prev_phys_block field is not valid, and we can't simply adjust
+ ** the size of that block.
+ */
+ const size_t gap_minimum = sizeof(block_header_t);
+ const size_t size_with_gap = adjust_request_size(adjust + align + gap_minimum, align);
+
+ /*
+ ** If alignment is less than or equals base alignment, we're done.
+ ** If we requested 0 bytes, return null, as tlsf_malloc(0) does.
+ */
+ const size_t aligned_size = (adjust && align > ALIGN_SIZE) ? size_with_gap : adjust;
+
+ block_header_t* block = block_locate_free(control, aligned_size);
+
+ /* This can't be a static assert. */
+ tlsf_assert(sizeof(block_header_t) == block_size_min + block_header_overhead);
+
+ if (block)
+ {
+ void* ptr = block_to_ptr(block);
+ void* aligned = align_ptr(ptr, align);
+ size_t gap = tlsf_cast(size_t,
+ tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr));
+
+ /* If gap size is too small, offset to next aligned boundary. */
+ if (gap && gap < gap_minimum)
+ {
+ const size_t gap_remain = gap_minimum - gap;
+ const size_t offset = tlsf_max(gap_remain, align);
+ const void* next_aligned = tlsf_cast(void*,
+ tlsf_cast(tlsfptr_t, aligned) + offset);
+
+ aligned = align_ptr(next_aligned, align);
+ gap = tlsf_cast(size_t,
+ tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr));
+ }
+
+ if (gap)
+ {
+ tlsf_assert(gap >= gap_minimum && "gap size too small");
+ block = block_trim_free_leading(control, block, gap);
+ }
+ }
+
+ return block_prepare_used(control, block, adjust);
+}
+
+void tlsf_free(tlsf_t tlsf, void* ptr)
+{
+ /* Don't attempt to free a NULL pointer. */
+ if (ptr)
+ {
+ control_t* control = tlsf_cast(control_t*, tlsf);
+ block_header_t* block = block_from_ptr(ptr);
+ tlsf_assert(!block_is_free(block) && "block already marked as free");
+ block_mark_as_free(block);
+ block = block_merge_prev(control, block);
+ block = block_merge_next(control, block);
+ block_insert(control, block);
+ }
+}
+
+/*
+** The TLSF block information provides us with enough information to
+** provide a reasonably intelligent implementation of realloc, growing or
+** shrinking the currently allocated block as required.
+**
+** This routine handles the somewhat esoteric edge cases of realloc:
+** - a non-zero size with a null pointer will behave like malloc
+** - a zero size with a non-null pointer will behave like free
+** - a request that cannot be satisfied will leave the original buffer
+** untouched
+** - an extended buffer size will leave the newly-allocated area with
+** contents undefined
+*/
+void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size)
+{
+ control_t* control = tlsf_cast(control_t*, tlsf);
+ void* p = 0;
+
+ /* Zero-size requests are treated as free. */
+ if (ptr && size == 0)
+ {
+ tlsf_free(tlsf, ptr);
+ }
+ /* Requests with NULL pointers are treated as malloc. */
+ else if (!ptr)
+ {
+ p = tlsf_malloc(tlsf, size);
+ }
+ else
+ {
+ block_header_t* block = block_from_ptr(ptr);
+ block_header_t* next = block_next(block);
+
+ const size_t cursize = block_size(block);
+ const size_t combined = cursize + block_size(next) + block_header_overhead;
+ const size_t adjust = adjust_request_size(size, ALIGN_SIZE);
+
+ tlsf_assert(!block_is_free(block) && "block already marked as free");
+
+ /*
+ ** If the next block is used, or when combined with the current
+ ** block, does not offer enough space, we must reallocate and copy.
+ */
+ if (adjust > cursize && (!block_is_free(next) || adjust > combined))
+ {
+ p = tlsf_malloc(tlsf, size);
+ if (p)
+ {
+ const size_t minsize = tlsf_min(cursize, size);
+ memcpy(p, ptr, minsize);
+ tlsf_free(tlsf, ptr);
+ }
+ }
+ else
+ {
+ /* Do we need to expand to the next block? */
+ if (adjust > cursize)
+ {
+ block_merge_next(control, block);
+ block_mark_as_used(block);
+ }
+
+ /* Trim the resulting block and return the original pointer. */
+ block_trim_used(control, block, adjust);
+ p = ptr;
+ }
+ }
+
+ return p;
+}
diff --git a/User/system/sgl/mm/tlsf/tlsf.h b/User/system/sgl/mm/tlsf/tlsf.h
new file mode 100644
index 0000000..2f17485
--- /dev/null
+++ b/User/system/sgl/mm/tlsf/tlsf.h
@@ -0,0 +1,93 @@
+#ifndef INCLUDED_tlsf
+#define INCLUDED_tlsf
+
+/*
+** Two Level Segregated Fit memory allocator, version 3.1.
+** Written by Matthew Conte
+** http://tlsf.baisoku.org
+**
+** Based on the original documentation by Miguel Masmano:
+** http://www.gii.upv.es/tlsf/main/docs
+**
+** This implementation was written to the specification
+** of the document, therefore no GPL restrictions apply.
+**
+** Copyright (c) 2006-2016, Matthew Conte
+** 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.
+** * Neither the name of the copyright holder nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** 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 MATTHEW CONTE 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.
+*/
+
+#include
+#include
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* tlsf_t: a TLSF structure. Can contain 1 to N pools. */
+/* pool_t: a block of memory that TLSF can manage. */
+typedef void* tlsf_t;
+typedef void* pool_t;
+
+/* Create/destroy a memory pool. */
+tlsf_t tlsf_create(void* mem);
+tlsf_t tlsf_create_with_pool(void* mem, size_t bytes);
+void tlsf_destroy(tlsf_t tlsf);
+pool_t tlsf_get_pool(tlsf_t tlsf);
+
+/* Add/remove memory pools. */
+pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes);
+void tlsf_remove_pool(tlsf_t tlsf, pool_t pool);
+
+/* malloc/memalign/realloc/free replacements. */
+void* tlsf_malloc(tlsf_t tlsf, size_t bytes);
+void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t bytes);
+void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size);
+void tlsf_free(tlsf_t tlsf, void* ptr);
+
+/* Returns internal block size, not original request size */
+size_t tlsf_block_size(void* ptr);
+
+/* Overheads/limits of internal structures. */
+size_t tlsf_size(void);
+size_t tlsf_align_size(void);
+size_t tlsf_block_size_min(void);
+size_t tlsf_block_size_max(void);
+size_t tlsf_pool_overhead(void);
+size_t tlsf_alloc_overhead(void);
+
+/* Debugging. */
+typedef void (*tlsf_walker)(void* ptr, size_t size, int used, void* user);
+void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user);
+/* Returns nonzero if any internal consistency check fails. */
+int tlsf_check(tlsf_t tlsf);
+int tlsf_check_pool(pool_t pool);
+
+#if defined(__cplusplus)
+};
+#endif
+
+#endif
diff --git a/User/system/sgl/sgl.h b/User/system/sgl/sgl.h
new file mode 100644
index 0000000..b6a3961
--- /dev/null
+++ b/User/system/sgl/sgl.h
@@ -0,0 +1,65 @@
+/* source/sgl.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_H__
+#define __SGL_H__
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "widgets/line/sgl_line.h"
+#include "widgets/rectangle/sgl_rectangle.h"
+#include "widgets/circle/sgl_circle.h"
+#include "widgets/ring/sgl_ring.h"
+#include "widgets/arc/sgl_arc.h"
+#include "widgets/button/sgl_button.h"
+#include "widgets/slider/sgl_slider.h"
+#include "widgets/progress/sgl_progress.h"
+#include "widgets/label/sgl_label.h"
+#include "widgets/switch/sgl_switch.h"
+#include "widgets/msgbox/sgl_msgbox.h"
+#include "widgets/textline/sgl_textline.h"
+#include "widgets/textbox/sgl_textbox.h"
+#include "widgets/checkbox/sgl_checkbox.h"
+#include "widgets/icon/sgl_icon.h"
+// #include "widgets/listview/sgl_listview.h"
+#include "widgets/numberkbd/sgl_numberkbd.h"
+#include "widgets/keyboard/sgl_keyboard.h"
+#include "widgets/unzip_image/sgl_unzip_image.h"
+#include "widgets/led/sgl_led.h"
+#include "widgets/2dball/sgl_2dball.h"
+#include "widgets/scroll/sgl_scroll.h"
+#include "widgets/dropdown/sgl_dropdown.h"
+#include "widgets/scope/sgl_scope.h"
+#include "widgets/ext_img/sgl_ext_img.h"
+#include "widgets/polygon/sgl_polygon.h"
+#include "widgets/box/sgl_box.h"
+#include "widgets/canvas/sgl_canvas.h"
+#include "widgets/bar/sgl_bar.h"
+#include "widgets/win/sgl_win.h"
+
+#endif // __SGL_H__
diff --git a/User/system/sgl/sgl_config.h b/User/system/sgl/sgl_config.h
new file mode 100644
index 0000000..b281e21
--- /dev/null
+++ b/User/system/sgl/sgl_config.h
@@ -0,0 +1,23 @@
+//****************************************************************
+//* lite-manager *
+//* NOTE: do not edit this file as it is automatically generated *
+//****************************************************************
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+
+#define CONFIG_SGL_PANEL_PIXEL_DEPTH 16
+#define CONFIG_SGL_EVENT_QUEUE_SIZE 16
+#define CONFIG_SGL_ANIMATION 1
+#define CONFIG_SGL_ANIMATION_TICK_MS 10
+#define CONFIG_SGL_DEBUG 1
+#define CONFIG_SGL_LOG_COLOR 1
+#define CONFIG_SGL_LOG_LEVEL 0
+#define CONFIG_SGL_BOOT_LOGO 1
+#define CONFIG_SGL_HEAP_ALGO lwmem
+#define CONFIG_SGL_HEAP_MEMORY_SIZE 10240
+#define CONFIG_SGL_FONT_SONG23 1
+
+
+#endif //!__CONFIG_H__
diff --git a/User/system/sgl/widgets/2dball/sgl_2dball.c b/User/system/sgl/widgets/2dball/sgl_2dball.c
new file mode 100644
index 0000000..6c91d8f
--- /dev/null
+++ b/User/system/sgl/widgets/2dball/sgl_2dball.c
@@ -0,0 +1,122 @@
+/* source/widgets/sgl_2dball.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sgl_2dball.h"
+
+
+static void sgl_2dball_construct_cb(sgl_surf_t *surf, sgl_obj_t* obj, sgl_event_t *evt)
+{
+ sgl_2dball_t *ball = sgl_container_of(obj, sgl_2dball_t, obj);
+ int16_t cx = 0, cy = 0;
+
+ if(evt->type == SGL_EVENT_DRAW_MAIN) {
+ sgl_area_t clip;
+ sgl_color_t *buf = NULL, *blend = NULL;
+
+ cx = (ball->obj.coords.x1 + ball->obj.coords.x2) / 2;
+ cy = (ball->obj.coords.y1 + ball->obj.coords.y2) / 2;
+
+ if (!sgl_surf_clip(surf, &obj->area, &clip)) {
+ return;
+ }
+
+ sgl_area_t c_rect = {
+ .x1 = cx - obj->radius,
+ .x2 = cx + obj->radius,
+ .y1 = cy - obj->radius,
+ .y2 = cy + obj->radius
+ };
+ if (!sgl_area_selfclip(&clip, &c_rect)) {
+ return;
+ }
+
+ int y2 = 0, real_r2 = 0, edge_alpha = 0;
+ int r2 = sgl_pow2(obj->radius);
+ int r2_edge = sgl_pow2(obj->radius + 1);
+ int ds_alpha = SGL_ALPHA_MIN;
+
+ buf = sgl_surf_get_buf(surf, clip.x1 - surf->x1, clip.y1 - surf->y1);
+ for (int y = clip.y1; y <= clip.y2; y++) {
+ y2 = sgl_pow2(y - cy);
+ blend = buf;
+
+ for (int x = clip.x1; x <= clip.x2; x++, blend++) {
+ real_r2 = sgl_pow2(x - cx) + y2;
+ ds_alpha = real_r2 * SGL_ALPHA_NUM / r2;
+
+ if (real_r2 >= r2_edge) {
+ if(x > cx)
+ break;
+ continue;
+ }
+ else if (real_r2 >= r2) {
+ edge_alpha = SGL_ALPHA_MAX - sgl_sqrt_error(real_r2);
+ sgl_color_t color_mix = sgl_color_mixer(ball->bg_color, *blend, edge_alpha);
+ *blend = sgl_color_mixer(color_mix, *blend, ball->alpha);
+ }
+ else {
+ *blend = sgl_color_mixer(sgl_color_mixer(ball->bg_color, ball->color, ds_alpha), *blend, ball->alpha);
+ }
+ }
+ buf += surf->w;
+ }
+ }
+}
+
+
+/**
+ * @brief create a 2dball object
+ * @param parent parent of the 2dball
+ * @return 2dball object
+ */
+sgl_obj_t* sgl_2dball_create(sgl_obj_t* parent)
+{
+ sgl_2dball_t *ball = sgl_malloc(sizeof(sgl_2dball_t));
+ if(ball == NULL) {
+ SGL_LOG_ERROR("sgl_2dball_create: malloc failed");
+ return NULL;
+ }
+
+ /* set object all member to zero */
+ memset(ball, 0, sizeof(sgl_2dball_t));
+
+ sgl_obj_t *obj = &ball->obj;
+ sgl_obj_init(&ball->obj, parent);
+ obj->construct_fn = sgl_2dball_construct_cb;
+ obj->needinit = 1;
+
+ ball->alpha = SGL_ALPHA_MAX;
+ ball->color = SGL_THEME_COLOR;
+ ball->bg_color = SGL_THEME_BG_COLOR;
+
+ return obj;
+}
diff --git a/User/system/sgl/widgets/2dball/sgl_2dball.h b/User/system/sgl/widgets/2dball/sgl_2dball.h
new file mode 100644
index 0000000..e41b647
--- /dev/null
+++ b/User/system/sgl/widgets/2dball/sgl_2dball.h
@@ -0,0 +1,110 @@
+/* source/widgets/sgl_2dball.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_2DBALL_H__
+#define __SGL_2DBALL_H__
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/**
+ * @brief sgl 2dball struct
+ * @obj: sgl general object
+ * @desc: pointer to 2dball draw descriptor
+ */
+typedef struct sgl_2dball {
+ sgl_obj_t obj;
+ uint8_t alpha;
+ sgl_color_t color;
+ sgl_color_t bg_color;
+
+}sgl_2dball_t;
+
+
+/**
+ * @brief create a 2dball object
+ * @param parent parent of the 2dball
+ * @return 2dball object
+ */
+sgl_obj_t* sgl_2dball_create(sgl_obj_t* parent);
+
+
+/**
+ * @brief set the color of the 2dball
+ * @param obj 2dball object
+ * @param color color
+ * @return none
+ */
+static inline void sgl_2dball_set_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_2dball_t *ball = sgl_container_of(obj, sgl_2dball_t, obj);
+ ball->color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the background color of the 2dball
+ * @param obj 2dball object
+ * @param color background color
+ * @return none
+ */
+static inline void sgl_2dball_set_bg_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_2dball_t *ball = sgl_container_of(obj, sgl_2dball_t, obj);
+ ball->bg_color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the alpha of the 2dball
+ * @param obj 2dball object
+ * @param alpha alpha
+ * @return none
+ */
+static inline void sgl_2dball_set_alpha(sgl_obj_t *obj, uint8_t alpha)
+{
+ sgl_2dball_t *ball = sgl_container_of(obj, sgl_2dball_t, obj);
+ ball->alpha = alpha;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the radius of the 2dball
+ * @param obj 2dball object
+ * @param radius radius
+ * @return none
+ */
+static inline void sgl_2dball_set_radius(sgl_obj_t *obj, uint16_t radius)
+{
+ sgl_obj_set_radius(obj, radius);
+ sgl_obj_set_dirty(obj);
+}
+
+#endif // !__SGL_2DBALL_H__
diff --git a/User/system/sgl/widgets/arc/sgl_arc.c b/User/system/sgl/widgets/arc/sgl_arc.c
new file mode 100644
index 0000000..7dd76ef
--- /dev/null
+++ b/User/system/sgl/widgets/arc/sgl_arc.c
@@ -0,0 +1,119 @@
+/* source/widgets/sgl_arc.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sgl_arc.h"
+
+
+static void sgl_arc_construct_cb(sgl_surf_t *surf, sgl_obj_t* obj, sgl_event_t *evt)
+{
+ sgl_arc_t *arc = sgl_container_of(obj, sgl_arc_t, obj);
+ int16_t tb_angle = 0;
+
+ if(evt->type == SGL_EVENT_DRAW_MAIN) {
+ arc->desc.cx = (obj->coords.x2 + obj->coords.x1) / 2;
+ arc->desc.cy = (obj->coords.y2 + obj->coords.y1) / 2;
+
+ if(arc->desc.start_angle == 0 && arc->desc.end_angle == 360) {
+ sgl_draw_fill_ring(surf, &arc->obj.area, arc->desc.cx, arc->desc.cy, arc->desc.radius_in, arc->desc.radius_out, arc->desc.color, arc->desc.alpha);
+ }
+ else {
+ sgl_draw_fill_arc(surf, &arc->obj.area, &arc->desc);
+ }
+ }
+ else if(evt->type == SGL_EVENT_PRESSED ||
+ evt->type == SGL_EVENT_MOVE_DOWN || evt->type == SGL_EVENT_MOVE_UP || evt->type == SGL_EVENT_MOVE_LEFT || evt->type == SGL_EVENT_MOVE_RIGHT
+ ) {
+ tb_angle = sgl_atan2_angle(evt->pos.x - arc->desc.cx, evt->pos.y - arc->desc.cy);
+ tb_angle = 360 - tb_angle;
+ if ((tb_angle != arc->desc.end_angle) && tb_angle >= 0 && tb_angle <= 360) {
+ arc->desc.end_angle = tb_angle;
+ }
+
+ if(obj->event_fn) {
+ obj->event_fn(evt);
+ }
+ sgl_obj_set_dirty(obj);
+ }
+ else if(evt->type == SGL_EVENT_RELEASED) {
+ if(obj->event_fn) {
+ obj->event_fn(evt);
+ }
+ }
+ else if(SGL_EVENT_DRAW_INIT) {
+ if(arc->desc.radius_out < 0) {
+ arc->desc.radius_out = (obj->coords.x2 - obj->coords.x1) / 2;
+ }
+
+ if(arc->desc.radius_in < 0) {
+ arc->desc.radius_in = arc->desc.radius_out - 2;
+ }
+ }
+}
+
+
+/**
+ * @brief create an arc object
+ * @param parent parent object
+ * @return arc object
+ */
+sgl_obj_t* sgl_arc_create(sgl_obj_t* parent)
+{
+ sgl_arc_t *arc = sgl_malloc(sizeof(sgl_arc_t));
+ if(arc == NULL) {
+ SGL_LOG_ERROR("sgl_arc_create: malloc failed");
+ return NULL;
+ }
+
+ /* set object all member to zero */
+ memset(arc, 0, sizeof(sgl_arc_t));
+
+ sgl_obj_t *obj = &arc->obj;
+ sgl_obj_init(&arc->obj, parent);
+ obj->needinit = 1;
+ obj->clickable = 1;
+ obj->movable = 1;
+
+ arc->desc.alpha = SGL_THEME_ALPHA;
+ arc->desc.mode = SGL_ARC_MODE_NORMAL;
+ arc->desc.color = SGL_THEME_BG_COLOR;
+ arc->desc.bg_color = SGL_THEME_COLOR;
+ arc->desc.start_angle = 0;
+ arc->desc.end_angle = 360;
+ arc->desc.radius_out = -1;
+ arc->desc.radius_in = -1;
+ arc->desc.cx = -1;
+ arc->desc.cy = -1;
+
+ obj->construct_fn = sgl_arc_construct_cb;
+
+ return obj;
+}
diff --git a/User/system/sgl/widgets/arc/sgl_arc.h b/User/system/sgl/widgets/arc/sgl_arc.h
new file mode 100644
index 0000000..abdf233
--- /dev/null
+++ b/User/system/sgl/widgets/arc/sgl_arc.h
@@ -0,0 +1,149 @@
+/* source/widgets/sgl_arc.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifndef __SGL_ARC_H__
+#define __SGL_ARC_H__
+
+
+typedef struct sgl_arc {
+ sgl_obj_t obj;
+ sgl_draw_arc_t desc;
+ int16_t width;
+}sgl_arc_t;
+
+
+/**
+ * @brief create an arc object
+ * @param parent parent object
+ * @return arc object
+ */
+sgl_obj_t* sgl_arc_create(sgl_obj_t* parent);
+
+
+/**
+ * @brief set arc object color
+ * @param obj arc object
+ * @param color arc color
+ * @return none
+ */
+static inline void sgl_arc_set_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_arc_t *arc = sgl_container_of(obj, sgl_arc_t, obj);
+ arc->desc.color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set arc object background color
+ * @param obj arc object
+ * @param color arc background color
+ * @return none
+ */
+static inline void sgl_arc_set_bg_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_arc_t *arc = sgl_container_of(obj, sgl_arc_t, obj);
+ arc->desc.bg_color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set arc object alpha
+ * @param obj arc object
+ * @param alpha arc alpha
+ * @return none
+ */
+static inline void sgl_arc_set_alpha(sgl_obj_t *obj, uint8_t alpha)
+{
+ sgl_arc_t *arc = sgl_container_of(obj, sgl_arc_t, obj);
+ arc->desc.alpha = alpha;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set arc object radius
+ * @param obj arc object
+ * @param radius_in arc radius_in
+ * @param radius_out arc radius_out
+ * @return none
+ */
+static inline void sgl_arc_set_radius(sgl_obj_t *obj, int16_t radius_in, int16_t radius_out)
+{
+ sgl_arc_t *arc = sgl_container_of(obj, sgl_arc_t, obj);
+ sgl_obj_set_radius(obj, radius_out);
+ arc->desc.radius_in = radius_in;
+ arc->desc.radius_out = obj->radius;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set arc object mode
+ * @param obj arc object
+ * @param mode arc mode
+ * @return none
+ */
+static inline void sgl_arc_set_mode(sgl_obj_t *obj, uint8_t mode)
+{
+ sgl_arc_t *arc = sgl_container_of(obj, sgl_arc_t, obj);
+ arc->desc.mode = mode;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set arc object start angle
+ * @param obj arc object
+ * @param angle arc start angle
+ * @return none
+ * @note angle should be in range [0, 360]
+ */
+static inline void sgl_arc_set_start_angle(sgl_obj_t *obj, int16_t angle)
+{
+ sgl_arc_t *arc = sgl_container_of(obj, sgl_arc_t, obj);
+ arc->desc.start_angle = angle;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set arc object end angle
+ * @param obj arc object
+ * @param angle arc end angle
+ * @return none
+ * @note angle should be in range [0, 360]
+ */
+static inline void sgl_arc_set_end_angle(sgl_obj_t *obj, int16_t angle)
+{
+ sgl_arc_t *arc = sgl_container_of(obj, sgl_arc_t, obj);
+ arc->desc.end_angle = angle;
+ sgl_obj_set_dirty(obj);
+}
+
+
+#endif // !__SGL_ARC_H__
diff --git a/User/system/sgl/widgets/bar/sgl_bar.c b/User/system/sgl/widgets/bar/sgl_bar.c
new file mode 100644
index 0000000..65f272e
--- /dev/null
+++ b/User/system/sgl/widgets/bar/sgl_bar.c
@@ -0,0 +1,123 @@
+/* source/widgets/sgl_bar.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sgl_bar.h"
+
+
+static void sgl_bar_construct_cb(sgl_surf_t *surf, sgl_obj_t* obj, sgl_event_t *evt)
+{
+ sgl_bar_t *bar = sgl_container_of(obj, sgl_bar_t, obj);
+
+ sgl_draw_rect_t desc = {
+ .alpha = bar->alpha,
+ .border = obj->border,
+ .border_color = bar->border_color,
+ .pixmap = bar->pixmap,
+ .color = bar->track_color,
+ .radius = obj->radius,
+ };
+
+ sgl_area_t knob = {
+ .x1 = obj->coords.x1 + obj->border,
+ .x2 = obj->coords.x2 - obj->border,
+ .y1 = obj->coords.y1 + obj->border,
+ .y2 = obj->coords.y2 - obj->border,
+ };
+
+ if(evt->type == SGL_EVENT_DRAW_MAIN) {
+ if(bar->direct == SGL_DIRECT_HORIZONTAL) {
+ knob.x2 = obj->coords.x1 + (obj->coords.x2 - obj->coords.x1) * bar->value / 100 - obj->border;
+ }
+ else {
+ knob.y1 = obj->coords.y2 - (obj->coords.y2 - obj->coords.y1) * bar->value / 100 + obj->border;
+ }
+
+ /* set knob area */
+ sgl_area_selfclip(&knob, &obj->area);
+
+ sgl_draw_rect(surf, &obj->area, &obj->coords, &desc);
+ sgl_draw_fill_rect_with_border(surf, &knob, &obj->coords, obj->radius, bar->fill_color, bar->border_color, obj->border, bar->alpha);
+ }
+ else if(evt->type == SGL_EVENT_PRESSED ||
+ evt->type == SGL_EVENT_MOVE_DOWN || evt->type == SGL_EVENT_MOVE_UP || evt->type == SGL_EVENT_MOVE_LEFT || evt->type == SGL_EVENT_MOVE_RIGHT
+ ) {
+ if(bar->direct == SGL_DIRECT_HORIZONTAL) {
+ bar->value = (evt->pos.x - obj->coords.x1) * 100 / (obj->coords.x2 - obj->coords.x1);
+ }
+ else {
+ bar->value = (obj->coords.y2 - evt->pos.y) * 100 / (obj->coords.y2 - obj->coords.y1);
+ }
+
+ if(evt->type == SGL_EVENT_PRESSED) {
+ sgl_obj_size_zoom(obj, 2);
+ }
+ sgl_obj_set_dirty(obj);
+ }
+ else if(evt->type == SGL_EVENT_RELEASED) {
+ sgl_obj_size_zoom(obj, -2);
+ sgl_obj_set_dirty(obj);
+ }
+}
+
+
+/**
+ * @brief create a bar object
+ * @param parent parent object of the bar
+ * @return bar object
+ */
+sgl_obj_t* sgl_bar_create(sgl_obj_t* parent)
+{
+ sgl_bar_t *bar = sgl_malloc(sizeof(sgl_bar_t));
+ if(bar == NULL) {
+ SGL_LOG_ERROR("sgl_bar_create: malloc failed");
+ return NULL;
+ }
+
+ /* set object all member to zero */
+ memset(bar, 0, sizeof(sgl_bar_t));
+
+ sgl_obj_t *obj = &bar->obj;
+ sgl_obj_init(&bar->obj, parent);
+ sgl_obj_set_clickable(obj);
+ sgl_obj_set_movable(obj);
+ obj->construct_fn = sgl_bar_construct_cb;
+ sgl_obj_set_border_width(obj, SGL_THEME_BORDER_WIDTH);
+
+ bar->direct = SGL_DIRECT_HORIZONTAL;
+ bar->alpha = SGL_THEME_ALPHA;
+ bar->track_color = SGL_THEME_COLOR;
+ bar->border_color = SGL_THEME_BORDER_COLOR;
+ bar->fill_color = SGL_THEME_BG_COLOR;
+ bar->alpha = SGL_THEME_ALPHA;
+
+ return obj;
+}
diff --git a/User/system/sgl/widgets/bar/sgl_bar.h b/User/system/sgl/widgets/bar/sgl_bar.h
new file mode 100644
index 0000000..74d98c9
--- /dev/null
+++ b/User/system/sgl/widgets/bar/sgl_bar.h
@@ -0,0 +1,204 @@
+/* source/widgets/sgl_bar.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_BAR_H__
+#define __SGL_BAR_H__
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/**
+ * @brief sgl bar struct
+ * @obj: sgl general object
+ * @param track_color track color
+ * @param border_color border color
+ * @param pixmap pixmap
+ * @param fill_color fill color
+ * @param direct bar direction
+ * @param value bar value
+ * @param alpha alpha
+ */
+typedef struct sgl_bar {
+ sgl_obj_t obj;
+ sgl_color_t track_color;
+ sgl_color_t border_color;
+ const sgl_pixmap_t *pixmap;
+ sgl_color_t fill_color;
+ /* 0: horizontal, 1: vertical */
+ uint8_t direct : 1;
+ uint8_t value : 7;
+ uint8_t alpha;
+} sgl_bar_t;
+
+/**
+ * @brief create a bar object
+ * @param parent parent object of the bar
+ * @return bar object
+ */
+sgl_obj_t* sgl_bar_create(sgl_obj_t* parent);
+
+/**
+ * @brief set the fill color of the bar
+ * @param obj bar object
+ * @param color fill color
+ * @return none
+ */
+static inline void sgl_bar_set_fill_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_bar_t *bar = sgl_container_of(obj, sgl_bar_t, obj);
+ bar->fill_color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the fill alpha of the bar
+ * @param obj bar object
+ * @param alpha fill alpha
+ * @return none
+ */
+static inline void sgl_bar_set_fill_alpha(sgl_obj_t *obj, uint8_t alpha)
+{
+ sgl_bar_t *bar = sgl_container_of(obj, sgl_bar_t, obj);
+ bar->alpha = alpha;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the track color of the bar
+ * @param obj bar object
+ * @param color track color
+ * @return none
+ */
+static inline void sgl_bar_set_track_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_bar_t *bar = sgl_container_of(obj, sgl_bar_t, obj);
+ bar->track_color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the track alpha of the bar
+ * @param obj bar object
+ * @param alpha track alpha
+ * @return none
+ */
+static inline void sgl_bar_set_track_alpha(sgl_obj_t *obj, uint8_t alpha)
+{
+ sgl_bar_t *bar = sgl_container_of(obj, sgl_bar_t, obj);
+ bar->alpha = alpha;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the bar direction
+ * @param obj bar object
+ * @param direct bar direction
+ * @return none
+ * @note direct : SGL_DIRECT_HORIZONTAL or SGL_DIRECT_VERTICAL
+ */
+static inline void sgl_bar_set_direct(sgl_obj_t *obj, uint8_t direct)
+{
+ sgl_bar_t *bar = sgl_container_of(obj, sgl_bar_t, obj);
+ bar->direct = direct;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the bar radius
+ * @param obj bar object
+ * @param radius bar radius
+ * @return none
+ */
+static inline void sgl_bar_set_radius(sgl_obj_t *obj, uint8_t radius)
+{
+ sgl_obj_set_radius(obj, radius);
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the bar value
+ * @param obj bar object
+ * @param value bar value
+ * @return none
+ */
+static inline void sgl_bar_set_value(sgl_obj_t *obj, uint8_t value)
+{
+ sgl_bar_t *bar = sgl_container_of(obj, sgl_bar_t, obj);
+ bar->value = value;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief get the bar value
+ * @param obj bar object
+ * @return bar value
+ */
+static inline uint8_t sgl_bar_get_value(sgl_obj_t *obj)
+{
+ sgl_bar_t *bar = sgl_container_of(obj, sgl_bar_t, obj);
+ return bar->value;
+}
+
+/**
+ * @brief set the bar border width
+ * @param obj bar object
+ * @param width border width
+ */
+static inline void sgl_bar_set_border_width(sgl_obj_t *obj, uint8_t width)
+{
+ sgl_obj_set_border_width(obj, width);
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the bar border color
+ * @param obj bar object
+ * @param color border color
+ */
+static inline void sgl_bar_set_border_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_bar_t *bar = sgl_container_of(obj, sgl_bar_t, obj);
+ bar->border_color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set the bar pixmap
+ * @param obj bar object
+ * @param pixmap pixmap
+ */
+static inline void sgl_bar_set_pixmap(sgl_obj_t *obj, const sgl_pixmap_t *pixmap)
+{
+ sgl_bar_t *bar = sgl_container_of(obj, sgl_bar_t, obj);
+ bar->pixmap = pixmap;
+ sgl_obj_set_dirty(obj);
+}
+
+#endif // !__SGL_BAR_H__
diff --git a/User/system/sgl/widgets/box/sgl_box.c b/User/system/sgl/widgets/box/sgl_box.c
new file mode 100644
index 0000000..da2dbb8
--- /dev/null
+++ b/User/system/sgl/widgets/box/sgl_box.c
@@ -0,0 +1,265 @@
+/* source/widgets/sgl_box.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: docs directory
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sgl_box.h"
+
+
+#define SGL_BOX_SCROLL_WIDTH (4)
+
+static void sgl_box_construct_cb(sgl_surf_t *surf, sgl_obj_t* obj, sgl_event_t *evt)
+{
+ sgl_box_t *box = sgl_container_of(obj, sgl_box_t, obj);
+ int16_t height = obj->coords.y2 - obj->coords.y1 - 2 * box->bg.radius;
+ int16_t width = obj->coords.x2 - obj->coords.x1 - 2 * box->bg.radius;
+ int16_t scroll_height = sgl_max(height / 8, SGL_BOX_SCROLL_WIDTH);
+ int16_t scroll_width = sgl_max(width / 8, SGL_BOX_SCROLL_WIDTH);
+ sgl_rect_t area;
+
+ if(evt->type == SGL_EVENT_DRAW_MAIN) {
+ area.x1 = obj->coords.x1 + box->bg.radius;
+ area.y1 = obj->coords.y1 + box->bg.radius;
+ area.x2 = obj->coords.x2 - box->bg.radius;
+ area.y2 = obj->coords.y2 - box->bg.radius;
+
+ sgl_draw_rect(surf, &obj->area, &obj->coords, &box->bg);
+
+ // Draw scrollbars if enabled
+ if(box->scroll_enable) {
+ // Draw vertical scrollbar if vertical scrolling is enabled and showing is enabled
+ if (((box->scroll_mode & SGL_BOX_SCROLL_VERTICAL_ONLY) || (box->scroll_mode & SGL_BOX_SCROLL_BOTH))
+ && box->show_v_scrollbar) {
+ area.x1 = obj->coords.x2 - SGL_BOX_SCROLL_WIDTH - box->bg.radius;
+ area.y1 = obj->coords.y1 + box->bg.radius;
+ area.x2 = obj->coords.x2 - box->bg.radius;
+
+ // Calculate scroll bar position based on content size and current offset
+ // Use elastic_scroll values to determine content size for proper scrollbar positioning
+ int16_t content_height = height + (box->elastic_scroll_up + box->elastic_scroll_down);
+
+ if(content_height > height && content_height > 0) {
+ // Calculate the scroll bar's position based on the current y_offset
+ float scroll_ratio = (float)(-box->y_offset) / (content_height - height);
+ scroll_ratio = sgl_clamp(scroll_ratio, 0.0f, 1.0f); // Clamp between 0 and 1
+
+ int16_t max_scroll_pos = height - scroll_height;
+ area.y1 = obj->coords.y1 + box->bg.radius + (int16_t)(max_scroll_pos * scroll_ratio);
+ area.y2 = area.y1 + scroll_height;
+ } else {
+ // If content fits, position scrollbar at the top
+ area.y1 = obj->coords.y1 + box->bg.radius;
+ area.y2 = area.y1 + scroll_height;
+ }
+
+ sgl_draw_fill_rect(surf, &obj->area, &area, SGL_BOX_SCROLL_WIDTH / 2, box->scroll_color, 128);
+ }
+
+ // Draw horizontal scrollbar if horizontal scrolling is enabled and showing is enabled
+ if (((box->scroll_mode & SGL_BOX_SCROLL_HORIZONTAL_ONLY) || (box->scroll_mode & SGL_BOX_SCROLL_BOTH))
+ && box->show_h_scrollbar) {
+ // Position horizontal scrollbar near the bottom-left, closer to vertical scrollbar
+ area.x1 = obj->coords.x1 + box->bg.radius;
+ area.y1 = obj->coords.y2 - SGL_BOX_SCROLL_WIDTH - box->bg.radius;
+ area.y2 = obj->coords.y2 - box->bg.radius;
+
+ // Adjust the right edge to not overlap with vertical scrollbar if both are visible
+ if ((box->scroll_mode & SGL_BOX_SCROLL_VERTICAL_ONLY) || (box->scroll_mode & SGL_BOX_SCROLL_BOTH)) {
+ area.x2 = obj->coords.x2 - SGL_BOX_SCROLL_WIDTH - box->bg.radius;
+ } else {
+ area.x2 = obj->coords.x2 - box->bg.radius;
+ }
+
+ // Calculate scroll bar position based on content size and current offset
+ int16_t content_width = width + (box->elastic_scroll_left + box->elastic_scroll_right);
+
+ if(content_width > width && content_width > 0) {
+ // Calculate the scroll bar's position based on the current x_offset
+ float scroll_ratio = (float)(-box->x_offset) / (content_width - width);
+ scroll_ratio = sgl_clamp(scroll_ratio, 0.0f, 1.0f); // Clamp between 0 and 1
+
+ int16_t max_scroll_pos = (area.x2 - area.x1) - scroll_width;
+ area.x1 = area.x1 + (int16_t)(max_scroll_pos * scroll_ratio);
+ area.x2 = area.x1 + scroll_width;
+ } else {
+ // If content fits, position scrollbar at the left
+ area.x1 = obj->coords.x1 + box->bg.radius;
+ area.x2 = area.x1 + scroll_width;
+ }
+
+ sgl_draw_fill_rect(surf, &obj->area, &area, SGL_BOX_SCROLL_WIDTH / 2, box->scroll_color, 128);
+ }
+ }
+ }
+ else if(evt->type == SGL_EVENT_MOVE_UP || evt->type == SGL_EVENT_MOVE_DOWN) {
+ // Check if vertical scrolling is enabled
+ if((box->scroll_mode & SGL_BOX_SCROLL_VERTICAL_ONLY) || (box->scroll_mode & SGL_BOX_SCROLL_BOTH)) {
+ // Update text offset - determine scroll direction based on event type
+ int16_t distance = evt->type == SGL_EVENT_MOVE_UP ? -evt->distance : evt->distance;
+ int16_t new_offset = box->y_offset + distance;
+
+ // Calculate limits based on elastic_scroll values
+ int16_t min_elastic, max_elastic;
+ // Calculate content dimensions based on elastic_scroll values
+ int16_t content_height = height + (box->elastic_scroll_up + box->elastic_scroll_down);
+ // Determine maximum scroll distance
+ int16_t max_scroll_distance = content_height - height;
+
+ if(box->elastic_scroll_up > 0 || box->elastic_scroll_down > 0) {
+ // If elastic scrolling is enabled (any direction limit > 0), limit to boundary plus elastic offset
+ // Apply actual elastic limits
+ min_elastic = -max_scroll_distance - box->elastic_scroll_down; // Allow scrolling down with elastic limit
+ max_elastic = box->elastic_scroll_up; // Allow scrolling up with elastic limit
+ } else {
+ // If elastic scrolling is disabled (both values are 0), limit to content boundaries
+ min_elastic = -max_scroll_distance; // max scroll down
+ max_elastic = 0; // max scroll up
+ }
+
+ int16_t constrained_new_offset = sgl_clamp(new_offset, min_elastic, max_elastic);
+ int16_t offset_delta = constrained_new_offset - box->y_offset;
+
+ box->y_offset = constrained_new_offset;
+
+ // Move all children vertically
+ sgl_obj_move_child_pos_y(obj, offset_delta);
+ sgl_obj_set_dirty(obj);
+ }
+ }
+ else if(evt->type == SGL_EVENT_MOVE_LEFT || evt->type == SGL_EVENT_MOVE_RIGHT) {
+ // Check if horizontal scrolling is enabled
+ if((box->scroll_mode & SGL_BOX_SCROLL_HORIZONTAL_ONLY) || (box->scroll_mode & SGL_BOX_SCROLL_BOTH)) {
+ // Update text offset - determine scroll direction based on event type
+ int16_t distance = evt->type == SGL_EVENT_MOVE_LEFT ? -evt->distance : evt->distance;
+ int16_t new_offset = box->x_offset + distance;
+
+ // Calculate limits based on elastic_scroll values
+ int16_t min_elastic, max_elastic;
+ // Calculate content dimensions based on elastic_scroll values
+ int16_t content_width = width + (box->elastic_scroll_left + box->elastic_scroll_right);
+ // Determine maximum scroll distance
+ int16_t max_scroll_distance = content_width - width;
+
+ if(box->elastic_scroll_left > 0 || box->elastic_scroll_right > 0) {
+ // If elastic scrolling is enabled (any direction limit > 0), limit to boundary plus elastic offset
+ // Apply actual elastic limits
+ min_elastic = -max_scroll_distance - box->elastic_scroll_right; // Allow scrolling right with elastic limit
+ max_elastic = box->elastic_scroll_left; // Allow scrolling left with elastic limit
+ } else {
+ // If elastic scrolling is disabled (both values are 0), limit to content boundaries
+ min_elastic = -max_scroll_distance; // max scroll right
+ max_elastic = 0; // max scroll left
+ }
+
+ int16_t constrained_new_offset = sgl_clamp(new_offset, min_elastic, max_elastic);
+ int16_t offset_delta = constrained_new_offset - box->x_offset;
+
+ box->x_offset = constrained_new_offset;
+
+ // Move all children horizontally
+ sgl_obj_move_child_pos_x(obj, offset_delta);
+ sgl_obj_set_dirty(obj);
+ }
+ }
+ else if (evt->type == SGL_EVENT_PRESSED) {
+ box->scroll_enable = 1;
+ sgl_obj_set_dirty(obj);
+ }
+ else if (evt->type == SGL_EVENT_RELEASED) {
+ box->scroll_enable = 0;
+ sgl_obj_set_dirty(obj);
+ }
+}
+
+
+/**
+ * @brief create a box object
+ * @param parent parent of the box
+ * @return pointer to the box object
+ */
+sgl_obj_t* sgl_box_create(sgl_obj_t* parent)
+{
+ sgl_box_t *box = sgl_malloc(sizeof(sgl_box_t));
+ if(box == NULL) {
+ SGL_LOG_ERROR("sgl_box_create: malloc failed");
+ return NULL;
+ }
+
+ /* set object all member to zero */
+ memset(box, 0, sizeof(sgl_box_t));
+
+ sgl_obj_t *obj = &box->obj;
+ sgl_obj_init(&box->obj, parent);
+ obj->construct_fn = sgl_box_construct_cb;
+ sgl_obj_set_border_width(obj, SGL_THEME_BORDER_WIDTH);
+ obj->focus = 1;
+
+ sgl_obj_set_clickable(obj);
+ sgl_obj_set_movable(obj);
+
+ box->bg.alpha = SGL_THEME_ALPHA;
+ box->bg.color = SGL_THEME_COLOR;
+ box->bg.radius = 10;
+ box->bg.border = 1;
+ sgl_obj_set_border_width(obj, 1);
+ box->bg.border_color = SGL_THEME_BORDER_COLOR;
+ box->scroll_color = SGL_THEME_SCROLL_FG_COLOR;
+
+ box->x_offset = 0;
+ box->y_offset = 0;
+ box->scroll_enable = 0;
+ box->show_v_scrollbar = 1;
+ box->show_h_scrollbar = 1;
+ box->scroll_mode = SGL_BOX_SCROLL_BOTH;
+ box->elastic_scroll_up = 0; // Default: unlimited scrolling up
+ box->elastic_scroll_down = 0; // Default: unlimited scrolling down
+ box->elastic_scroll_left = 0; // Default: unlimited scrolling left
+ box->elastic_scroll_right = 0; // Default: unlimited scrolling right
+
+ return obj;
+}
+
+/**
+ * @brief Set the elastic scroll limits for up and down directions
+ * @param obj box object
+ * @param up_limit maximum pixels allowed when scrolling up (0 for unlimited)
+ * @param down_limit maximum pixels allowed when scrolling down (0 for unlimited)
+ * @param left_limit maximum pixels allowed when scrolling left (0 for unlimited)
+ * @param right_limit maximum pixels allowed when scrolling right (0 for unlimited)
+ * @return none
+ */
+void sgl_box_set_elastic_scroll(sgl_obj_t* obj, int16_t up_limit, int16_t down_limit, int16_t left_limit, int16_t right_limit)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_box_t *box = (sgl_box_t*)obj;
+ box->elastic_scroll_up = up_limit;
+ box->elastic_scroll_down = down_limit;
+ box->elastic_scroll_left = left_limit;
+ box->elastic_scroll_right = right_limit;
+}
diff --git a/User/system/sgl/widgets/box/sgl_box.h b/User/system/sgl/widgets/box/sgl_box.h
new file mode 100644
index 0000000..7a18043
--- /dev/null
+++ b/User/system/sgl/widgets/box/sgl_box.h
@@ -0,0 +1,189 @@
+/* source/widgets/sgl_box.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: docs directory
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_BOX_H__
+#define __SGL_BOX_H__
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Define scroll modes
+#define SGL_BOX_SCROLL_VERTICAL_ONLY (0x01) // Vertical scrolling only
+#define SGL_BOX_SCROLL_HORIZONTAL_ONLY (0x02) // Horizontal scrolling only
+#define SGL_BOX_SCROLL_BOTH (0x03) // Both vertical and horizontal scrolling enabled
+
+/**
+ * @brief sgl box struct
+ * @desc: Container for scrolling child widgets
+ */
+typedef struct sgl_box {
+ sgl_obj_t obj;
+ sgl_draw_rect_t bg;
+ int16_t x_offset; // X-axis offset
+ int16_t y_offset; // Y-axis offset
+ sgl_color_t scroll_color; // scroll color;
+ uint8_t scroll_mode; // Scroll mode (vertical/horizontal/both)
+ uint8_t scroll_enable : 1; // Whether scrolling is enabled
+ uint8_t show_v_scrollbar : 1; // Whether to show the vertical scrollbar
+ uint8_t show_h_scrollbar : 1; // Whether to show the horizontal scrollbar
+ int16_t elastic_scroll_up; // Maximum allowable upward elastic scroll offset
+ int16_t elastic_scroll_down; // Maximum allowable downward elastic scroll offset
+ int16_t elastic_scroll_left; // Maximum allowable leftward elastic scroll offset
+ int16_t elastic_scroll_right; // Maximum allowable rightward elastic scroll offset
+} sgl_box_t;
+
+
+/**
+ * @brief create a box object
+ * @param parent parent of the box
+ * @return box object
+ */
+sgl_obj_t* sgl_box_create(sgl_obj_t* parent);
+
+
+/**
+ * @brief set background color of the box
+ * @param obj box object
+ * @param color background color to be set
+ * @return none
+ */
+static inline void sgl_box_set_bg_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_box_t *box = sgl_container_of(obj, sgl_box_t, obj);
+ box->bg.color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set radius of the box
+ * @param obj box object
+ * @param radius radius to be set
+ * @return none
+ */
+static inline void sgl_box_set_radius(sgl_obj_t *obj, uint8_t radius)
+{
+ sgl_box_t *box = sgl_container_of(obj, sgl_box_t, obj);
+ sgl_obj_set_radius(obj, radius);
+ box->bg.radius = obj->radius;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set border color of the box
+ * @param obj box object
+ * @param color border color to be set
+ * @return none
+ */
+static inline void sgl_box_set_border_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_box_t *box = sgl_container_of(obj, sgl_box_t, obj);
+ box->bg.border_color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set border width of the box
+ * @param obj box object
+ * @param width border width to be set
+ * @return none
+ */
+static inline void sgl_box_set_border_width(sgl_obj_t *obj, uint8_t width)
+{
+ sgl_box_t *box = sgl_container_of(obj, sgl_box_t, obj);
+ box->bg.border = width;
+ sgl_obj_set_border_width(obj, width);
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set box pixmap
+ * @param obj box object
+ * @param pixmap pixmap to be set
+ * @return none
+ */
+static inline void sgl_box_set_pixmap(sgl_obj_t *obj, const sgl_pixmap_t *pixmap)
+{
+ sgl_box_t *box = sgl_container_of(obj, sgl_box_t, obj);
+ box->bg.pixmap = pixmap;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief Set the elastic scroll limits for up and down directions
+ * @param obj box object
+ * @param up_limit maximum pixels allowed when scrolling up (0 for unlimited)
+ * @param down_limit maximum pixels allowed when scrolling down (0 for unlimited)
+ * @param left_limit maximum pixels allowed when scrolling left (0 for unlimited)
+ * @param right_limit maximum pixels allowed when scrolling right (0 for unlimited)
+ * @return none
+ */
+void sgl_box_set_elastic_scroll(sgl_obj_t* obj, int16_t up_limit, int16_t down_limit, int16_t left_limit, int16_t right_limit);
+
+/**
+ * @brief set scrollbar color of the box
+ * @param obj box object
+ * @param color scrollbar color to be set
+ * @return none
+ */
+static inline void sgl_box_set_scrollbar_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_box_t *box = sgl_container_of(obj, sgl_box_t, obj);
+ box->scroll_color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set whether to show scrollbars
+ * @param obj box object
+ * @param show_vertical whether to show vertical scrollbar (1 to show, 0 to hide)
+ * @param show_horizontal whether to show horizontal scrollbar (1 to show, 0 to hide)
+ * @return none
+ */
+static inline void sgl_box_set_show_scrollbar(sgl_obj_t *obj, uint8_t show_vertical, uint8_t show_horizontal)
+{
+ sgl_box_t *box = sgl_container_of(obj, sgl_box_t, obj);
+ box->show_v_scrollbar = show_vertical;
+ box->show_h_scrollbar = show_horizontal;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set alpha (transparency) of the box
+ * @param obj box object
+ * @param alpha alpha value to be set (0-255, where 0 is fully transparent and 255 is fully opaque)
+ * @return none
+ */
+static inline void sgl_box_set_alpha(sgl_obj_t *obj, uint8_t alpha)
+{
+ sgl_box_t *box = sgl_container_of(obj, sgl_box_t, obj);
+ box->bg.alpha = alpha;
+ sgl_obj_set_dirty(obj);
+}
+
+#endif // !__SGL_BOX_H__
diff --git a/User/system/sgl/widgets/build.cmake b/User/system/sgl/widgets/build.cmake
new file mode 100644
index 0000000..2ddb1ef
--- /dev/null
+++ b/User/system/sgl/widgets/build.cmake
@@ -0,0 +1,54 @@
+#
+# MIT License
+#
+# Copyright(c) 2023-present All contributors of SGL
+# Document reference link: https://sgl-docs.readthedocs.io
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+set(SGL_SOURCE
+ ${SGL_SOURCE}
+ ${CMAKE_CURRENT_LIST_DIR}/line/sgl_line.c
+ ${CMAKE_CURRENT_LIST_DIR}/rectangle/sgl_rectangle.c
+ ${CMAKE_CURRENT_LIST_DIR}/circle/sgl_circle.c
+ ${CMAKE_CURRENT_LIST_DIR}/ring/sgl_ring.c
+ ${CMAKE_CURRENT_LIST_DIR}/arc/sgl_arc.c
+ ${CMAKE_CURRENT_LIST_DIR}/button/sgl_button.c
+ ${CMAKE_CURRENT_LIST_DIR}/slider/sgl_slider.c
+ ${CMAKE_CURRENT_LIST_DIR}/progress/sgl_progress.c
+ ${CMAKE_CURRENT_LIST_DIR}/label/sgl_label.c
+ ${CMAKE_CURRENT_LIST_DIR}/switch/sgl_switch.c
+ ${CMAKE_CURRENT_LIST_DIR}/msgbox/sgl_msgbox.c
+ ${CMAKE_CURRENT_LIST_DIR}/textline/sgl_textline.c
+ ${CMAKE_CURRENT_LIST_DIR}/textbox/sgl_textbox.c
+ ${CMAKE_CURRENT_LIST_DIR}/checkbox/sgl_checkbox.c
+ ${CMAKE_CURRENT_LIST_DIR}/icon/sgl_icon.c
+ ${CMAKE_CURRENT_LIST_DIR}/numberkbd/sgl_numberkbd.c
+ ${CMAKE_CURRENT_LIST_DIR}/keyboard/sgl_keyboard.c
+ ${CMAKE_CURRENT_LIST_DIR}/led/sgl_led.c
+ ${CMAKE_CURRENT_LIST_DIR}/2dball/sgl_2dball.c
+ ${CMAKE_CURRENT_LIST_DIR}/unzip_image/sgl_unzip_image.c
+ ${CMAKE_CURRENT_LIST_DIR}/scroll/sgl_scroll.c
+ ${CMAKE_CURRENT_LIST_DIR}/dropdown/sgl_dropdown.c
+ ${CMAKE_CURRENT_LIST_DIR}/scope/sgl_scope.c
+ ${CMAKE_CURRENT_LIST_DIR}/polygon/sgl_polygon.c
+ ${CMAKE_CURRENT_LIST_DIR}/box/sgl_box.c
+ ${CMAKE_CURRENT_LIST_DIR}/canvas/sgl_canvas.c
+ ${CMAKE_CURRENT_LIST_DIR}/bar/sgl_bar.c
+ ${CMAKE_CURRENT_LIST_DIR}/win/sgl_win.c
+)
diff --git a/User/system/sgl/widgets/button/sgl_button.c b/User/system/sgl/widgets/button/sgl_button.c
new file mode 100644
index 0000000..57c6436
--- /dev/null
+++ b/User/system/sgl/widgets/button/sgl_button.c
@@ -0,0 +1,121 @@
+/* source/widgets/sgl_button.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sgl_button.h"
+
+
+/**
+ * @brief button construct callback
+ * @param surf: surface pointer
+ * @param obj: object pointer
+ * @param evt: event pointer
+ * @return none
+ * @note this function is called when the object is created or redraw
+ */
+static void sgl_button_construct_cb(sgl_surf_t *surf, sgl_obj_t* obj, sgl_event_t *evt)
+{
+ sgl_button_t *button = sgl_container_of(obj, sgl_button_t, obj);
+ sgl_pos_t align_pos;
+ sgl_rect_t fill_area;
+ sgl_draw_rect_t rect = {
+ .alpha = button->alpha,
+ .color = button->color,
+ .border = obj->border,
+ .border_color = button->border_color,
+ .pixmap = button->pixmap,
+ .radius = obj->radius,
+ };
+
+ if(evt->type == SGL_EVENT_DRAW_MAIN) {
+ sgl_draw_rect(surf, &obj->area, &obj->coords, &rect);
+
+ if(button->text) {
+ SGL_ASSERT(button->font != NULL);
+ fill_area = sgl_obj_get_fill_rect(obj);
+ align_pos = sgl_get_text_pos(&fill_area, button->font, button->text, 0, (sgl_align_type_t)button->align);
+
+ sgl_draw_string(surf, &obj->area, align_pos.x, align_pos.y, button->text, button->text_color, button->alpha, button->font);
+ }
+ }
+ else if(evt->type == SGL_EVENT_PRESSED) {
+ if(sgl_obj_is_flexible(obj)) {
+ sgl_obj_size_zoom(obj, 2);
+ }
+ sgl_obj_set_dirty(obj);
+ }
+ else if(evt->type == SGL_EVENT_RELEASED) {
+ if(sgl_obj_is_flexible(obj)) {
+ sgl_obj_size_zoom(obj, -2);
+ }
+ sgl_obj_set_dirty(obj);
+ }
+}
+
+
+/**
+ * @brief create a button object
+ * @param parent: parent object
+ * @return object pointer
+ * @note if parent is NULL, the button object will be created at the top level.
+ */
+sgl_obj_t* sgl_button_create(sgl_obj_t* parent)
+{
+ sgl_button_t *button = sgl_malloc(sizeof(sgl_button_t));
+ if(button == NULL) {
+ SGL_LOG_ERROR("sgl_button_create: malloc failed");
+ return NULL;
+ }
+
+ /* set object all member to zero */
+ memset(button, 0, sizeof(sgl_button_t));
+
+ sgl_obj_t *obj = &button->obj;
+ sgl_obj_init(&button->obj, parent);
+ sgl_obj_set_clickable(obj);
+ sgl_obj_set_flexible(obj);
+ sgl_obj_set_border_width(obj, SGL_THEME_BORDER_WIDTH);
+ sgl_obj_set_radius(obj, SGL_THEME_RADIUS);
+
+ obj->construct_fn = sgl_button_construct_cb;
+
+ button->alpha = SGL_THEME_ALPHA;
+ button->color = SGL_THEME_COLOR;
+ button->border_color = SGL_THEME_BORDER_COLOR;
+ button->pixmap = NULL;
+
+ button->text = " ";
+ button->text_color = SGL_THEME_TEXT_COLOR;
+ button->font = sgl_get_system_font();
+ button->align = SGL_ALIGN_CENTER;
+
+ return obj;
+}
diff --git a/User/system/sgl/widgets/button/sgl_button.h b/User/system/sgl/widgets/button/sgl_button.h
new file mode 100644
index 0000000..0d3bd12
--- /dev/null
+++ b/User/system/sgl/widgets/button/sgl_button.h
@@ -0,0 +1,193 @@
+/* source/widgets/sgl_button.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_BUTTON_H__
+#define __SGL_BUTTON_H__
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/**
+ * @brief Button object
+ * @obj: Button object
+ * @desc: Button object description
+ * @desc_text: Button object description text
+ */
+typedef struct sgl_button {
+ sgl_obj_t obj;
+ sgl_color_t color;
+ sgl_color_t border_color;
+ const sgl_pixmap_t *pixmap;
+ const char *text;
+ const sgl_font_t *font;
+ sgl_color_t text_color;
+ uint8_t alpha;
+ uint8_t align;
+}sgl_button_t;
+
+
+/**
+ * @brief create a button object
+ * @param parent: parent object
+ * @return object pointer
+ * @note if parent is NULL, the button object will be created at the top level.
+ */
+sgl_obj_t* sgl_button_create(sgl_obj_t* parent);
+
+/**
+ * @brief set button color
+ * @param obj: object pointer
+ * @param color: color
+ * @return none
+ */
+static inline void sgl_button_set_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_button_t *button = sgl_container_of(obj, sgl_button_t, obj);
+ button->color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set button alpha
+ * @param obj: object pointer
+ * @param alpha: alpha
+ * @return none
+ */
+static inline void sgl_button_set_alpha(sgl_obj_t *obj, uint8_t alpha)
+{
+ sgl_button_t *button = sgl_container_of(obj, sgl_button_t, obj);
+ button->alpha = alpha;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set button border width
+ * @param obj: object pointer
+ * @param width: border width
+ * @return none
+ */
+static inline void sgl_button_set_border_width(sgl_obj_t *obj, uint8_t width)
+{
+ sgl_obj_set_border_width(obj, width);
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set button border color
+ * @param obj: object pointer
+ * @param color: border color
+ * @return none
+ */
+static inline void sgl_button_set_border_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_button_t *button = sgl_container_of(obj, sgl_button_t, obj);
+ button->border_color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set button pixmap
+ * @param obj: object pointer
+ * @param pixmap: pixmap pointer
+ * @return none
+ */
+static inline void sgl_button_set_pixmap(sgl_obj_t *obj, const sgl_pixmap_t *pixmap)
+{
+ sgl_button_t *button = sgl_container_of(obj, sgl_button_t, obj);
+ button->pixmap = pixmap;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set button radius
+ * @param obj: object pointer
+ * @param radius: radius
+ * @return none
+ */
+static inline void sgl_button_set_radius(sgl_obj_t *obj, uint8_t radius)
+{
+ sgl_obj_set_radius(obj, radius);
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set button text
+ * @param obj: object pointer
+ * @param text: text
+ * @return none
+ */
+static inline void sgl_button_set_text(sgl_obj_t *obj, const char *text)
+{
+ sgl_button_t *button = sgl_container_of(obj, sgl_button_t, obj);
+ button->text = text;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set button text color
+ * @param obj: object pointer
+ * @param color: text color
+ * @return none
+ */
+static inline void sgl_button_set_text_color(sgl_obj_t *obj, sgl_color_t color)
+{
+ sgl_button_t *button = sgl_container_of(obj, sgl_button_t, obj);
+ button->text_color = color;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set button text align
+ * @param obj: object pointer
+ * @param align: align type
+ * @return none
+ */
+static inline void sgl_button_set_text_align(sgl_obj_t *obj, uint8_t align)
+{
+ sgl_button_t *button = sgl_container_of(obj, sgl_button_t, obj);
+ button->align = align;
+ sgl_obj_set_dirty(obj);
+}
+
+/**
+ * @brief set button text font
+ * @param obj: object pointer
+ * @param font: font pointer
+ * @return none
+ */
+static inline void sgl_button_set_font(sgl_obj_t *obj, const sgl_font_t *font)
+{
+ sgl_button_t *button = sgl_container_of(obj, sgl_button_t, obj);
+ button->font = font;
+ sgl_obj_set_dirty(obj);
+}
+
+#endif // !__SGL_BUTTON_H__
diff --git a/User/system/sgl/widgets/canvas/sgl_canvas.c b/User/system/sgl/widgets/canvas/sgl_canvas.c
new file mode 100644
index 0000000..b75109f
--- /dev/null
+++ b/User/system/sgl/widgets/canvas/sgl_canvas.c
@@ -0,0 +1,67 @@
+/* source/widgets/sgl_canvas.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: docs directory
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sgl_canvas.h"
+
+
+static void sgl_canvas_construct_cb(sgl_surf_t *surf, sgl_obj_t* obj, sgl_event_t *evt)
+{
+ sgl_canvas_t *canvas = sgl_container_of(obj, sgl_canvas_t, obj);
+
+ if(evt->type == SGL_EVENT_DRAW_MAIN) {
+ SGL_ASSERT_INFO(canvas->painter != NULL, "you must set painter function");
+ canvas->painter(surf, &obj->area, obj);
+ }
+}
+
+/**
+ * @brief create a canvas object
+ * @param parent parent of the canvas
+ * @return canvas object
+ */
+sgl_obj_t* sgl_canvas_create(sgl_obj_t* parent)
+{
+ sgl_canvas_t *canvas = sgl_malloc(sizeof(sgl_canvas_t));
+ if(canvas == NULL) {
+ SGL_LOG_ERROR("sgl_canvas_create: malloc failed");
+ return NULL;
+ }
+
+ /* set object all member to zero */
+ memset(canvas, 0, sizeof(sgl_canvas_t));
+
+ sgl_obj_t *obj = &canvas->obj;
+ sgl_obj_init(&canvas->obj, parent);
+ obj->construct_fn = sgl_canvas_construct_cb;
+
+ return obj;
+}
diff --git a/User/system/sgl/widgets/canvas/sgl_canvas.h b/User/system/sgl/widgets/canvas/sgl_canvas.h
new file mode 100644
index 0000000..3a92f6c
--- /dev/null
+++ b/User/system/sgl/widgets/canvas/sgl_canvas.h
@@ -0,0 +1,97 @@
+/* source/widgets/sgl_canvas.h
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: docs directory
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __SGL_CANVAS_H__
+#define __SGL_CANVAS_H__
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * @brief For example, you can use the canvas widget:
+ * void painter_func(sgl_surf_t *surf, sgl_area_t *area, sgl_obj_t *obj)
+ * {
+ * for (int i = obj->coords.y1; i < obj->coords.y2; i += 10) {
+ * sgl_draw_fill_hline(surf, area, i, obj->coords.x1, obj->coords.x2, 5, SGL_COLOR_BLACK, 255);
+ * }
+ * }
+ *
+ * sgl_obj_t *canvas = sgl_canvas_create(NULL);
+ * sgl_obj_set_size(canvas, 800, 600);
+ * sgl_obj_set_pos_align(canvas, SGL_ALIGN_CENTER);
+ * sgl_canvas_set_painter_cb(canvas, painter_func);
+ */
+
+typedef void (*sgl_painter_cb_t)(sgl_surf_t *surf, sgl_area_t *area, sgl_obj_t* obj);
+
+/**
+ * @brief sgl canvas struct
+ * @obj: sgl general object
+ * @painter: pointer to canvas painter function
+ * @priv: pointer to canvas private data
+ */
+typedef struct sgl_canvas {
+ sgl_obj_t obj;
+ sgl_painter_cb_t painter;
+ void *priv;
+} sgl_canvas_t;
+
+/**
+ * @brief create a canvas object
+ * @param parent parent of the canvas
+ * @return canvas object
+ */
+sgl_obj_t* sgl_canvas_create(sgl_obj_t* parent);
+
+/**
+ * @brief set canvas painter
+ * @param obj canvas object
+ * @param painter painter function
+ */
+static inline void sgl_canvas_set_painter_cb(sgl_obj_t *obj, sgl_painter_cb_t painter)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_canvas_t *canvas = sgl_container_of(obj, sgl_canvas_t, obj);
+ canvas->painter = painter;
+}
+
+/**
+ * @brief set canvas private data
+ * @param obj canvas object
+ * @param priv private data
+ * @param none
+ */
+static inline void sgl_canvas_set_private(sgl_obj_t *obj, void *priv)
+{
+ SGL_ASSERT(obj != NULL);
+ sgl_canvas_t *canvas = (sgl_canvas_t *)obj;
+ canvas->priv = priv;
+}
+
+#endif // !__SGL_CANVAS_H__
diff --git a/User/system/sgl/widgets/checkbox/sgl_checkbox.c b/User/system/sgl/widgets/checkbox/sgl_checkbox.c
new file mode 100644
index 0000000..4398e28
--- /dev/null
+++ b/User/system/sgl/widgets/checkbox/sgl_checkbox.c
@@ -0,0 +1,190 @@
+/* source/widgets/sgl_checkbox.c
+ *
+ * MIT License
+ *
+ * Copyright(c) 2023-present All contributors of SGL
+ * Document reference link: https://sgl-docs.readthedocs.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include