From 73b2b0ace6792e81e24f25f57b5447ba0cec8bc2 Mon Sep 17 00:00:00 2001 From: Ronil Mitra Date: Mon, 16 Mar 2026 13:30:59 -0700 Subject: [PATCH] Implement connectivity check for analytics endpoint and update URL to localhost --- pros/ga/analytics.py | 34 + pros/serial/devices/vex/v5_device.py | 3 +- test/.gitignore | 17 + test/Makefile | 47 + test/common.mk | 309 + test/firmware/libc.a | Bin 0 -> 1200014 bytes test/firmware/liblvgl.a | Bin 0 -> 8100082 bytes test/firmware/libm.a | Bin 0 -> 504240 bytes test/firmware/libpros.a | Bin 0 -> 4581104 bytes test/firmware/v5-common.ld | 226 + test/firmware/v5-hot.ld | 33 + test/firmware/v5.ld | 33 + test/include/api.h | 80 + test/include/liblvgl/core/lv_global.h | 266 + test/include/liblvgl/core/lv_group.h | 245 + test/include/liblvgl/core/lv_group_private.h | 75 + test/include/liblvgl/core/lv_obj.h | 486 ++ test/include/liblvgl/core/lv_obj_class.h | 72 + .../liblvgl/core/lv_obj_class_private.h | 78 + test/include/liblvgl/core/lv_obj_draw.h | 113 + .../liblvgl/core/lv_obj_draw_private.h | 48 + test/include/liblvgl/core/lv_obj_event.h | 198 + .../liblvgl/core/lv_obj_event_private.h | 62 + test/include/liblvgl/core/lv_obj_pos.h | 451 ++ test/include/liblvgl/core/lv_obj_private.h | 88 + test/include/liblvgl/core/lv_obj_property.h | 209 + test/include/liblvgl/core/lv_obj_scroll.h | 290 + .../liblvgl/core/lv_obj_scroll_private.h | 50 + test/include/liblvgl/core/lv_obj_style.h | 318 + test/include/liblvgl/core/lv_obj_style_gen.h | 875 +++ .../liblvgl/core/lv_obj_style_private.h | 95 + test/include/liblvgl/core/lv_obj_tree.h | 237 + test/include/liblvgl/core/lv_refr.h | 68 + test/include/liblvgl/core/lv_refr_private.h | 75 + test/include/liblvgl/display/lv_display.h | 629 ++ .../liblvgl/display/lv_display_private.h | 183 + .../liblvgl/draw/dma2d/lv_draw_dma2d.h | 49 + .../draw/dma2d/lv_draw_dma2d_private.h | 155 + test/include/liblvgl/draw/lv_draw.h | 283 + test/include/liblvgl/draw/lv_draw_arc.h | 90 + test/include/liblvgl/draw/lv_draw_buf.h | 356 ++ .../liblvgl/draw/lv_draw_buf_private.h | 53 + test/include/liblvgl/draw/lv_draw_image.h | 129 + .../liblvgl/draw/lv_draw_image_private.h | 85 + test/include/liblvgl/draw/lv_draw_label.h | 145 + .../liblvgl/draw/lv_draw_label_private.h | 68 + test/include/liblvgl/draw/lv_draw_line.h | 76 + test/include/liblvgl/draw/lv_draw_mask.h | 56 + .../liblvgl/draw/lv_draw_mask_private.h | 51 + test/include/liblvgl/draw/lv_draw_private.h | 196 + test/include/liblvgl/draw/lv_draw_rect.h | 174 + .../liblvgl/draw/lv_draw_rect_private.h | 39 + test/include/liblvgl/draw/lv_draw_triangle.h | 67 + .../liblvgl/draw/lv_draw_triangle_private.h | 43 + test/include/liblvgl/draw/lv_draw_vector.h | 489 ++ .../liblvgl/draw/lv_draw_vector_private.h | 109 + test/include/liblvgl/draw/lv_image_decoder.h | 194 + .../liblvgl/draw/lv_image_decoder_private.h | 142 + test/include/liblvgl/draw/lv_image_dsc.h | 141 + .../liblvgl/draw/nema_gfx/lv_draw_nema_gfx.h | 122 + .../draw/nema_gfx/lv_draw_nema_gfx_utils.h | 125 + .../liblvgl/draw/nxp/pxp/lv_draw_pxp.h | 75 + .../include/liblvgl/draw/nxp/pxp/lv_pxp_cfg.h | 104 + .../include/liblvgl/draw/nxp/pxp/lv_pxp_osa.h | 62 + .../liblvgl/draw/nxp/pxp/lv_pxp_utils.h | 84 + .../liblvgl/draw/nxp/vglite/lv_draw_vglite.h | 86 + .../liblvgl/draw/nxp/vglite/lv_vglite_buf.h | 124 + .../draw/nxp/vglite/lv_vglite_matrix.h | 78 + .../liblvgl/draw/nxp/vglite/lv_vglite_path.h | 97 + .../liblvgl/draw/nxp/vglite/lv_vglite_utils.h | 179 + .../liblvgl/draw/opengles/lv_draw_opengles.h | 45 + .../draw/renesas/dave2d/lv_draw_dave2d.h | 105 + .../renesas/dave2d/lv_draw_dave2d_utils.h | 45 + test/include/liblvgl/draw/sdl/lv_draw_sdl.h | 87 + .../liblvgl/draw/sw/arm2d/lv_draw_sw_arm2d.h | 589 ++ .../liblvgl/draw/sw/arm2d/lv_draw_sw_helium.h | 60 + .../draw/sw/blend/arm2d/lv_blend_arm2d.h | 937 +++ .../draw/sw/blend/helium/lv_blend_helium.h | 1313 ++++ .../liblvgl/draw/sw/blend/lv_draw_sw_blend.h | 52 + .../draw/sw/blend/lv_draw_sw_blend_private.h | 92 + .../draw/sw/blend/lv_draw_sw_blend_to_al88.h | 45 + .../sw/blend/lv_draw_sw_blend_to_argb8888.h | 45 + .../draw/sw/blend/lv_draw_sw_blend_to_i1.h | 45 + .../draw/sw/blend/lv_draw_sw_blend_to_l8.h | 45 + .../sw/blend/lv_draw_sw_blend_to_rgb565.h | 45 + .../sw/blend/lv_draw_sw_blend_to_rgb888.h | 47 + .../draw/sw/blend/neon/lv_blend_neon.h | 1301 ++++ test/include/liblvgl/draw/sw/lv_draw_sw.h | 204 + .../liblvgl/draw/sw/lv_draw_sw_gradient.h | 203 + .../draw/sw/lv_draw_sw_gradient_private.h | 50 + .../include/liblvgl/draw/sw/lv_draw_sw_mask.h | 185 + .../liblvgl/draw/sw/lv_draw_sw_mask_private.h | 157 + .../liblvgl/draw/sw/lv_draw_sw_private.h | 68 + .../liblvgl/draw/vg_lite/lv_draw_vg_lite.h | 90 + .../draw/vg_lite/lv_draw_vg_lite_type.h | 73 + .../liblvgl/draw/vg_lite/lv_vg_lite_decoder.h | 47 + .../liblvgl/draw/vg_lite/lv_vg_lite_grad.h | 69 + .../liblvgl/draw/vg_lite/lv_vg_lite_math.h | 76 + .../liblvgl/draw/vg_lite/lv_vg_lite_path.h | 128 + .../liblvgl/draw/vg_lite/lv_vg_lite_pending.h | 83 + .../liblvgl/draw/vg_lite/lv_vg_lite_stroke.h | 84 + .../liblvgl/draw/vg_lite/lv_vg_lite_utils.h | 188 + test/include/liblvgl/drivers/README.md | 1 + .../drivers/display/drm/lv_linux_drm.h | 46 + .../drivers/display/fb/lv_linux_fbdev.h | 52 + .../drivers/display/ili9341/lv_ili9341.h | 94 + .../drivers/display/lcd/lv_lcd_generic_mipi.h | 242 + .../display/renesas_glcdc/lv_renesas_glcdc.h | 57 + .../drivers/display/st7735/lv_st7735.h | 93 + .../drivers/display/st7789/lv_st7789.h | 94 + .../drivers/display/st7796/lv_st7796.h | 93 + .../drivers/display/st_ltdc/lv_st_ltdc.h | 65 + .../drivers/display/tft_espi/lv_tft_espi.cpp | 110 + .../drivers/display/tft_espi/lv_tft_espi.h | 43 + test/include/liblvgl/drivers/evdev/lv_evdev.h | 64 + .../liblvgl/drivers/glfw/lv_glfw_window.h | 108 + .../drivers/glfw/lv_glfw_window_private.h | 70 + .../liblvgl/drivers/glfw/lv_opengles_debug.h | 40 + .../liblvgl/drivers/glfw/lv_opengles_driver.h | 92 + .../drivers/glfw/lv_opengles_texture.h | 66 + .../liblvgl/drivers/libinput/lv_libinput.h | 101 + .../drivers/libinput/lv_libinput_private.h | 83 + .../include/liblvgl/drivers/libinput/lv_xkb.h | 64 + .../liblvgl/drivers/libinput/lv_xkb_private.h | 53 + test/include/liblvgl/drivers/lv_drivers.h | 77 + .../liblvgl/drivers/nuttx/lv_nuttx_cache.h | 41 + .../liblvgl/drivers/nuttx/lv_nuttx_entry.h | 112 + .../liblvgl/drivers/nuttx/lv_nuttx_fbdev.h | 55 + .../drivers/nuttx/lv_nuttx_image_cache.h | 44 + .../liblvgl/drivers/nuttx/lv_nuttx_lcd.h | 49 + .../liblvgl/drivers/nuttx/lv_nuttx_libuv.h | 66 + .../liblvgl/drivers/nuttx/lv_nuttx_profiler.h | 39 + .../drivers/nuttx/lv_nuttx_touchscreen.h | 57 + test/include/liblvgl/drivers/qnx/lv_qnx.h | 86 + .../liblvgl/drivers/sdl/lv_sdl_keyboard.h | 46 + .../liblvgl/drivers/sdl/lv_sdl_mouse.h | 43 + .../liblvgl/drivers/sdl/lv_sdl_mousewheel.h | 43 + .../liblvgl/drivers/sdl/lv_sdl_private.h | 49 + .../liblvgl/drivers/sdl/lv_sdl_window.h | 62 + .../liblvgl/drivers/wayland/lv_wayland.h | 142 + .../liblvgl/drivers/wayland/lv_wayland_smm.h | 105 + .../drivers/windows/lv_windows_context.h | 134 + .../drivers/windows/lv_windows_display.h | 127 + .../drivers/windows/lv_windows_input.h | 83 + .../windows/lv_windows_input_private.h | 65 + test/include/liblvgl/drivers/x11/lv_x11.h | 81 + test/include/liblvgl/font/lv_binfont_loader.h | 61 + test/include/liblvgl/font/lv_font.h | 324 + test/include/liblvgl/font/lv_font_fmt_txt.h | 224 + .../liblvgl/font/lv_font_fmt_txt_private.h | 56 + test/include/liblvgl/font/lv_symbol_def.h | 357 ++ test/include/liblvgl/indev/lv_indev.h | 422 ++ test/include/liblvgl/indev/lv_indev_private.h | 137 + test/include/liblvgl/indev/lv_indev_scroll.h | 65 + test/include/liblvgl/layouts/flex/lv_flex.h | 102 + test/include/liblvgl/layouts/grid/lv_grid.h | 99 + test/include/liblvgl/layouts/lv_layout.h | 67 + .../liblvgl/layouts/lv_layout_private.h | 58 + test/include/liblvgl/libs/barcode/code128.h | 47 + .../include/liblvgl/libs/barcode/lv_barcode.h | 118 + .../liblvgl/libs/barcode/lv_barcode_private.h | 55 + .../liblvgl/libs/bin_decoder/lv_bin_decoder.h | 70 + test/include/liblvgl/libs/bmp/lv_bmp.h | 43 + test/include/liblvgl/libs/ffmpeg/lv_ffmpeg.h | 97 + .../liblvgl/libs/ffmpeg/lv_ffmpeg_private.h | 51 + test/include/liblvgl/libs/freetype/arial.ttf | Bin 0 -> 311636 bytes test/include/liblvgl/libs/freetype/ftmodule.h | 33 + test/include/liblvgl/libs/freetype/ftoption.h | 964 +++ .../liblvgl/libs/freetype/lv_freetype.h | 127 + .../libs/freetype/lv_freetype_private.h | 151 + .../libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp | 201 + .../liblvgl/libs/fsdrv/lv_fs_arduino_sd.cpp | 192 + test/include/liblvgl/libs/fsdrv/lv_fsdrv.h | 72 + test/include/liblvgl/libs/gif/gifdec.h | 71 + test/include/liblvgl/libs/gif/gifdec_mve.h | 140 + test/include/liblvgl/libs/gif/lv_gif.h | 104 + .../include/liblvgl/libs/gif/lv_gif_private.h | 57 + .../libs/libjpeg_turbo/lv_libjpeg_turbo.h | 48 + test/include/liblvgl/libs/libpng/lv_libpng.h | 48 + test/include/liblvgl/libs/lodepng/lodepng.h | 2105 +++++++ .../include/liblvgl/libs/lodepng/lv_lodepng.h | 48 + test/include/liblvgl/libs/lz4/LICENSE | 24 + test/include/liblvgl/libs/lz4/lz4.h | 877 +++ test/include/liblvgl/libs/qrcode/lv_qrcode.h | 85 + .../liblvgl/libs/qrcode/lv_qrcode_private.h | 52 + test/include/liblvgl/libs/qrcode/qrcodegen.h | 324 + test/include/liblvgl/libs/rle/lv_rle.h | 46 + .../include/liblvgl/libs/rlottie/lv_rlottie.h | 58 + .../liblvgl/libs/rlottie/lv_rlottie_private.h | 61 + test/include/liblvgl/libs/svg/lv_svg.h | 334 + test/include/liblvgl/libs/svg/lv_svg_parser.h | 84 + test/include/liblvgl/libs/svg/lv_svg_render.h | 98 + test/include/liblvgl/libs/svg/lv_svg_token.h | 70 + .../liblvgl/libs/thorvg/add_lvgl_if.sh | 13 + test/include/liblvgl/libs/thorvg/config.h | 15 + .../libs/thorvg/rapidjson/allocators.h | 693 ++ .../thorvg/rapidjson/cursorstreamwrapper.h | 78 + .../liblvgl/libs/thorvg/rapidjson/document.h | 3043 +++++++++ .../libs/thorvg/rapidjson/encodedstream.h | 299 + .../liblvgl/libs/thorvg/rapidjson/encodings.h | 716 +++ .../liblvgl/libs/thorvg/rapidjson/error/en.h | 176 + .../libs/thorvg/rapidjson/error/error.h | 285 + .../libs/thorvg/rapidjson/filereadstream.h | 99 + .../libs/thorvg/rapidjson/filewritestream.h | 104 + .../liblvgl/libs/thorvg/rapidjson/fwd.h | 151 + .../thorvg/rapidjson/internal/biginteger.h | 297 + .../libs/thorvg/rapidjson/internal/clzll.h | 71 + .../libs/thorvg/rapidjson/internal/diyfp.h | 261 + .../libs/thorvg/rapidjson/internal/dtoa.h | 249 + .../libs/thorvg/rapidjson/internal/ieee754.h | 78 + .../libs/thorvg/rapidjson/internal/itoa.h | 308 + .../libs/thorvg/rapidjson/internal/meta.h | 186 + .../libs/thorvg/rapidjson/internal/pow10.h | 55 + .../libs/thorvg/rapidjson/internal/regex.h | 739 +++ .../libs/thorvg/rapidjson/internal/stack.h | 232 + .../libs/thorvg/rapidjson/internal/strfunc.h | 83 + .../libs/thorvg/rapidjson/internal/strtod.h | 293 + .../libs/thorvg/rapidjson/internal/swap.h | 46 + .../libs/thorvg/rapidjson/istreamwrapper.h | 128 + .../libs/thorvg/rapidjson/memorybuffer.h | 70 + .../libs/thorvg/rapidjson/memorystream.h | 71 + .../thorvg/rapidjson/msinttypes/inttypes.h | 316 + .../libs/thorvg/rapidjson/msinttypes/stdint.h | 300 + .../libs/thorvg/rapidjson/ostreamwrapper.h | 81 + .../liblvgl/libs/thorvg/rapidjson/pointer.h | 1470 +++++ .../libs/thorvg/rapidjson/prettywriter.h | 277 + .../liblvgl/libs/thorvg/rapidjson/rapidjson.h | 741 +++ .../liblvgl/libs/thorvg/rapidjson/reader.h | 2246 +++++++ .../liblvgl/libs/thorvg/rapidjson/schema.h | 3262 ++++++++++ .../liblvgl/libs/thorvg/rapidjson/stream.h | 223 + .../libs/thorvg/rapidjson/stringbuffer.h | 121 + .../liblvgl/libs/thorvg/rapidjson/uri.h | 481 ++ .../liblvgl/libs/thorvg/rapidjson/writer.h | 710 +++ test/include/liblvgl/libs/thorvg/thorvg.h | 2182 +++++++ .../include/liblvgl/libs/thorvg/thorvg_capi.h | 2508 ++++++++ .../liblvgl/libs/thorvg/thorvg_lottie.h | 100 + .../liblvgl/libs/thorvg/tvgAccessor.cpp | 91 + .../liblvgl/libs/thorvg/tvgAnimation.cpp | 132 + .../liblvgl/libs/thorvg/tvgAnimation.h | 54 + test/include/liblvgl/libs/thorvg/tvgArray.h | 209 + .../liblvgl/libs/thorvg/tvgBinaryDesc.h | 106 + .../include/liblvgl/libs/thorvg/tvgCanvas.cpp | 99 + test/include/liblvgl/libs/thorvg/tvgCanvas.h | 165 + test/include/liblvgl/libs/thorvg/tvgCapi.cpp | 871 +++ test/include/liblvgl/libs/thorvg/tvgCommon.h | 96 + .../liblvgl/libs/thorvg/tvgCompressor.cpp | 481 ++ .../liblvgl/libs/thorvg/tvgCompressor.h | 41 + test/include/liblvgl/libs/thorvg/tvgFill.cpp | 256 + test/include/liblvgl/libs/thorvg/tvgFill.h | 118 + .../liblvgl/libs/thorvg/tvgFrameModule.h | 68 + .../liblvgl/libs/thorvg/tvgGlCanvas.cpp | 96 + .../liblvgl/libs/thorvg/tvgInitializer.cpp | 185 + test/include/liblvgl/libs/thorvg/tvgInlist.h | 117 + .../liblvgl/libs/thorvg/tvgIteratorAccessor.h | 49 + test/include/liblvgl/libs/thorvg/tvgLines.cpp | 249 + test/include/liblvgl/libs/thorvg/tvgLines.h | 66 + .../liblvgl/libs/thorvg/tvgLoadModule.h | 113 + .../include/liblvgl/libs/thorvg/tvgLoader.cpp | 441 ++ test/include/liblvgl/libs/thorvg/tvgLoader.h | 46 + test/include/liblvgl/libs/thorvg/tvgLock.h | 77 + .../libs/thorvg/tvgLottieAnimation.cpp | 98 + .../liblvgl/libs/thorvg/tvgLottieBuilder.cpp | 1378 ++++ .../liblvgl/libs/thorvg/tvgLottieBuilder.h | 54 + .../libs/thorvg/tvgLottieExpressions.cpp | 1298 ++++ .../libs/thorvg/tvgLottieExpressions.h | 171 + .../libs/thorvg/tvgLottieInterpolator.cpp | 146 + .../libs/thorvg/tvgLottieInterpolator.h | 51 + .../liblvgl/libs/thorvg/tvgLottieLoader.cpp | 407 ++ .../liblvgl/libs/thorvg/tvgLottieLoader.h | 86 + .../liblvgl/libs/thorvg/tvgLottieModel.cpp | 424 ++ .../liblvgl/libs/thorvg/tvgLottieModel.h | 685 ++ .../liblvgl/libs/thorvg/tvgLottieParser.cpp | 1405 +++++ .../liblvgl/libs/thorvg/tvgLottieParser.h | 124 + .../libs/thorvg/tvgLottieParserHandler.cpp | 241 + .../libs/thorvg/tvgLottieParserHandler.h | 206 + .../liblvgl/libs/thorvg/tvgLottieProperty.h | 935 +++ test/include/liblvgl/libs/thorvg/tvgMath.cpp | 108 + test/include/liblvgl/libs/thorvg/tvgMath.h | 228 + test/include/liblvgl/libs/thorvg/tvgPaint.cpp | 482 ++ test/include/liblvgl/libs/thorvg/tvgPaint.h | 152 + .../liblvgl/libs/thorvg/tvgPicture.cpp | 238 + test/include/liblvgl/libs/thorvg/tvgPicture.h | 250 + .../liblvgl/libs/thorvg/tvgRawLoader.cpp | 88 + .../liblvgl/libs/thorvg/tvgRawLoader.h | 46 + .../include/liblvgl/libs/thorvg/tvgRender.cpp | 100 + test/include/liblvgl/libs/thorvg/tvgRender.h | 356 ++ .../liblvgl/libs/thorvg/tvgSaveModule.h | 49 + test/include/liblvgl/libs/thorvg/tvgSaver.cpp | 209 + test/include/liblvgl/libs/thorvg/tvgScene.cpp | 87 + test/include/liblvgl/libs/thorvg/tvgScene.h | 235 + test/include/liblvgl/libs/thorvg/tvgShape.cpp | 411 ++ test/include/liblvgl/libs/thorvg/tvgShape.h | 407 ++ test/include/liblvgl/libs/thorvg/tvgStr.cpp | 248 + test/include/liblvgl/libs/thorvg/tvgStr.h | 43 + .../liblvgl/libs/thorvg/tvgSvgCssStyle.cpp | 271 + .../liblvgl/libs/thorvg/tvgSvgCssStyle.h | 40 + .../liblvgl/libs/thorvg/tvgSvgLoader.cpp | 3917 ++++++++++++ .../liblvgl/libs/thorvg/tvgSvgLoader.h | 74 + .../liblvgl/libs/thorvg/tvgSvgLoaderCommon.h | 577 ++ .../liblvgl/libs/thorvg/tvgSvgPath.cpp | 577 ++ test/include/liblvgl/libs/thorvg/tvgSvgPath.h | 36 + .../libs/thorvg/tvgSvgSceneBuilder.cpp | 888 +++ .../liblvgl/libs/thorvg/tvgSvgSceneBuilder.h | 36 + .../liblvgl/libs/thorvg/tvgSvgUtil.cpp | 76 + test/include/liblvgl/libs/thorvg/tvgSvgUtil.h | 36 + .../liblvgl/libs/thorvg/tvgSwCanvas.cpp | 118 + .../include/liblvgl/libs/thorvg/tvgSwCommon.h | 593 ++ .../include/liblvgl/libs/thorvg/tvgSwFill.cpp | 790 +++ .../liblvgl/libs/thorvg/tvgSwImage.cpp | 164 + .../include/liblvgl/libs/thorvg/tvgSwMath.cpp | 329 + .../liblvgl/libs/thorvg/tvgSwMemPool.cpp | 135 + .../liblvgl/libs/thorvg/tvgSwRaster.cpp | 1967 ++++++ .../liblvgl/libs/thorvg/tvgSwRasterAvx.h | 214 + .../liblvgl/libs/thorvg/tvgSwRasterC.h | 169 + .../liblvgl/libs/thorvg/tvgSwRasterNeon.h | 184 + .../liblvgl/libs/thorvg/tvgSwRasterTexmap.h | 1214 ++++ .../liblvgl/libs/thorvg/tvgSwRenderer.cpp | 859 +++ .../liblvgl/libs/thorvg/tvgSwRenderer.h | 91 + test/include/liblvgl/libs/thorvg/tvgSwRle.cpp | 1134 ++++ .../liblvgl/libs/thorvg/tvgSwShape.cpp | 675 ++ .../liblvgl/libs/thorvg/tvgSwStroke.cpp | 913 +++ .../liblvgl/libs/thorvg/tvgTaskScheduler.cpp | 235 + .../liblvgl/libs/thorvg/tvgTaskScheduler.h | 117 + test/include/liblvgl/libs/thorvg/tvgText.cpp | 115 + test/include/liblvgl/libs/thorvg/tvgText.h | 189 + .../liblvgl/libs/thorvg/tvgWgCanvas.cpp | 89 + .../liblvgl/libs/thorvg/tvgXmlParser.cpp | 595 ++ .../liblvgl/libs/thorvg/tvgXmlParser.h | 64 + .../liblvgl/libs/tiny_ttf/lv_tiny_ttf.h | 98 + .../liblvgl/libs/tiny_ttf/stb_rect_pack.h | 633 ++ .../liblvgl/libs/tiny_ttf/stb_truetype_htcw.h | 5598 +++++++++++++++++ test/include/liblvgl/libs/tjpgd/lv_tjpgd.h | 45 + test/include/liblvgl/libs/tjpgd/tjpgd.h | 108 + test/include/liblvgl/libs/tjpgd/tjpgdcnf.h | 33 + test/include/liblvgl/llemu.h | 438 ++ test/include/liblvgl/llemu.hpp | 373 ++ test/include/liblvgl/lv_api_map_v8.h | 328 + test/include/liblvgl/lv_api_map_v9_0.h | 66 + test/include/liblvgl/lv_api_map_v9_1.h | 90 + test/include/liblvgl/lv_conf.h | 790 +++ test/include/liblvgl/lv_conf.old.h | 341 + test/include/liblvgl/lv_conf_internal.h | 4078 ++++++++++++ test/include/liblvgl/lv_conf_kconfig.h | 266 + test/include/liblvgl/lv_init.h | 55 + test/include/liblvgl/lv_version.h | 66 + test/include/liblvgl/lvgl.h | 195 + test/include/liblvgl/lvgl_private.h | 125 + test/include/liblvgl/misc/cache/lv_cache.h | 237 + .../liblvgl/misc/cache/lv_cache_entry.h | 114 + .../misc/cache/lv_cache_entry_private.h | 50 + .../liblvgl/misc/cache/lv_cache_lru_rb.h | 44 + .../liblvgl/misc/cache/lv_cache_private.h | 201 + .../liblvgl/misc/cache/lv_image_cache.h | 82 + .../misc/cache/lv_image_header_cache.h | 83 + test/include/liblvgl/misc/lv_anim.h | 525 ++ test/include/liblvgl/misc/lv_anim_private.h | 56 + test/include/liblvgl/misc/lv_anim_timeline.h | 136 + test/include/liblvgl/misc/lv_area.h | 254 + test/include/liblvgl/misc/lv_area_private.h | 115 + test/include/liblvgl/misc/lv_array.h | 205 + test/include/liblvgl/misc/lv_assert.h | 87 + test/include/liblvgl/misc/lv_async.h | 61 + test/include/liblvgl/misc/lv_bidi.h | 83 + test/include/liblvgl/misc/lv_bidi_private.h | 101 + test/include/liblvgl/misc/lv_circle_buf.h | 191 + test/include/liblvgl/misc/lv_color.h | 429 ++ test/include/liblvgl/misc/lv_color_op.h | 82 + .../liblvgl/misc/lv_color_op_private.h | 39 + test/include/liblvgl/misc/lv_event.h | 224 + test/include/liblvgl/misc/lv_event_private.h | 73 + test/include/liblvgl/misc/lv_fs.h | 258 + test/include/liblvgl/misc/lv_fs_private.h | 63 + test/include/liblvgl/misc/lv_iter.h | 120 + test/include/liblvgl/misc/lv_ll.h | 169 + test/include/liblvgl/misc/lv_log.h | 162 + test/include/liblvgl/misc/lv_lru.h | 83 + test/include/liblvgl/misc/lv_math.h | 181 + test/include/liblvgl/misc/lv_matrix.h | 129 + test/include/liblvgl/misc/lv_palette.h | 68 + test/include/liblvgl/misc/lv_profiler.h | 172 + .../liblvgl/misc/lv_profiler_builtin.h | 85 + .../misc/lv_profiler_builtin_private.h | 56 + test/include/liblvgl/misc/lv_rb.h | 66 + test/include/liblvgl/misc/lv_rb_private.h | 54 + test/include/liblvgl/misc/lv_style.h | 640 ++ test/include/liblvgl/misc/lv_style_gen.h | 694 ++ test/include/liblvgl/misc/lv_style_private.h | 39 + test/include/liblvgl/misc/lv_templ.h | 37 + test/include/liblvgl/misc/lv_text.h | 125 + test/include/liblvgl/misc/lv_text_ap.h | 49 + test/include/liblvgl/misc/lv_text_private.h | 273 + test/include/liblvgl/misc/lv_timer.h | 210 + test/include/liblvgl/misc/lv_timer_private.h | 81 + test/include/liblvgl/misc/lv_tree.h | 105 + test/include/liblvgl/misc/lv_types.h | 381 ++ test/include/liblvgl/misc/lv_utils.h | 68 + test/include/liblvgl/osal/lv_cmsis_rtos2.h | 53 + test/include/liblvgl/osal/lv_freertos.h | 105 + test/include/liblvgl/osal/lv_mqx.h | 51 + test/include/liblvgl/osal/lv_os.h | 186 + test/include/liblvgl/osal/lv_os_none.h | 43 + test/include/liblvgl/osal/lv_os_private.h | 47 + test/include/liblvgl/osal/lv_pthread.h | 57 + test/include/liblvgl/osal/lv_rtthread.h | 54 + test/include/liblvgl/osal/lv_windows.h | 54 + .../others/file_explorer/lv_file_explorer.h | 168 + .../file_explorer/lv_file_explorer_private.h | 69 + .../others/font_manager/lv_font_manager.h | 106 + .../font_manager/lv_font_manager_recycle.h | 78 + .../font_manager/lv_font_manager_utils.h | 59 + .../include/liblvgl/others/fragment/README.md | 0 .../liblvgl/others/fragment/lv_fragment.h | 297 + .../others/fragment/lv_fragment_private.h | 77 + .../liblvgl/others/gridnav/lv_gridnav.h | 95 + .../liblvgl/others/ime/lv_ime_pinyin.h | 121 + .../others/ime/lv_ime_pinyin_private.h | 68 + .../liblvgl/others/imgfont/lv_imgfont.h | 63 + .../include/liblvgl/others/monkey/lv_monkey.h | 117 + .../liblvgl/others/monkey/lv_monkey_private.h | 43 + .../liblvgl/others/observer/lv_observer.h | 406 ++ .../others/observer/lv_observer_private.h | 57 + .../liblvgl/others/snapshot/lv_snapshot.h | 101 + .../include/liblvgl/others/sysmon/lv_sysmon.h | 91 + .../liblvgl/others/sysmon/lv_sysmon_private.h | 91 + .../liblvgl/others/vg_lite_tvg/vg_lite.h | 1387 ++++ .../others/vg_lite_tvg/vg_lite_tvg.cpp | 2854 +++++++++ test/include/liblvgl/stdlib/builtin/lv_tlsf.h | 97 + .../liblvgl/stdlib/builtin/lv_tlsf_private.h | 53 + test/include/liblvgl/stdlib/lv_mem.h | 156 + test/include/liblvgl/stdlib/lv_mem_private.h | 39 + test/include/liblvgl/stdlib/lv_sprintf.h | 45 + test/include/liblvgl/stdlib/lv_string.h | 166 + .../liblvgl/themes/default/lv_theme_default.h | 71 + test/include/liblvgl/themes/lv_theme.h | 108 + .../include/liblvgl/themes/lv_theme_private.h | 53 + .../liblvgl/themes/mono/lv_theme_mono.h | 62 + .../liblvgl/themes/simple/lv_theme_simple.h | 67 + test/include/liblvgl/tick/lv_tick.h | 85 + test/include/liblvgl/tick/lv_tick_private.h | 46 + .../liblvgl/widgets/animimage/lv_animimage.h | 129 + .../widgets/animimage/lv_animimage_private.h | 55 + test/include/liblvgl/widgets/arc/lv_arc.h | 247 + .../liblvgl/widgets/arc/lv_arc_private.h | 64 + test/include/liblvgl/widgets/bar/lv_bar.h | 162 + .../liblvgl/widgets/bar/lv_bar_private.h | 66 + .../liblvgl/widgets/button/lv_button.h | 48 + .../widgets/button/lv_button_private.h | 53 + .../widgets/buttonmatrix/lv_buttonmatrix.h | 202 + .../buttonmatrix/lv_buttonmatrix_private.h | 57 + .../liblvgl/widgets/calendar/lv_calendar.h | 160 + .../widgets/calendar/lv_calendar_chinese.h | 68 + .../calendar/lv_calendar_chinese_private.h | 53 + .../calendar/lv_calendar_header_arrow.h | 49 + .../calendar/lv_calendar_header_dropdown.h | 62 + .../widgets/calendar/lv_calendar_private.h | 70 + .../liblvgl/widgets/canvas/lv_canvas.h | 185 + .../widgets/canvas/lv_canvas_private.h | 52 + test/include/liblvgl/widgets/chart/lv_chart.h | 358 ++ .../liblvgl/widgets/chart/lv_chart_private.h | 85 + .../liblvgl/widgets/checkbox/lv_checkbox.h | 79 + .../widgets/checkbox/lv_checkbox_private.h | 55 + .../liblvgl/widgets/dropdown/lv_dropdown.h | 246 + .../widgets/dropdown/lv_dropdown_private.h | 69 + test/include/liblvgl/widgets/image/lv_image.h | 310 + .../liblvgl/widgets/image/lv_image_private.h | 66 + .../widgets/imagebutton/lv_imagebutton.h | 121 + .../imagebutton/lv_imagebutton_private.h | 58 + .../liblvgl/widgets/keyboard/lv_keyboard.h | 183 + .../widgets/keyboard/lv_keyboard_private.h | 53 + test/include/liblvgl/widgets/label/lv_label.h | 238 + .../liblvgl/widgets/label/lv_label_private.h | 74 + test/include/liblvgl/widgets/led/lv_led.h | 99 + .../liblvgl/widgets/led/lv_led_private.h | 52 + test/include/liblvgl/widgets/line/lv_line.h | 118 + .../liblvgl/widgets/line/lv_line_private.h | 57 + test/include/liblvgl/widgets/list/lv_list.h | 85 + .../liblvgl/widgets/lottie/lv_lottie.h | 102 + .../widgets/lottie/lv_lottie_private.h | 60 + test/include/liblvgl/widgets/menu/lv_menu.h | 213 + .../liblvgl/widgets/menu/lv_menu_private.h | 84 + .../liblvgl/widgets/msgbox/lv_msgbox.h | 141 + .../widgets/msgbox/lv_msgbox_private.h | 57 + .../widgets/objx_templ/lv_objx_templ.h | 81 + .../widgets/property/lv_obj_property_names.h | 22 + .../widgets/property/lv_style_properties.h | 130 + .../liblvgl/widgets/roller/lv_roller.h | 133 + .../widgets/roller/lv_roller_private.h | 55 + test/include/liblvgl/widgets/scale/lv_scale.h | 258 + .../liblvgl/widgets/scale/lv_scale_private.h | 82 + .../liblvgl/widgets/slider/lv_slider.h | 149 + .../widgets/slider/lv_slider_private.h | 55 + test/include/liblvgl/widgets/span/lv_span.h | 284 + .../liblvgl/widgets/span/lv_span_private.h | 68 + .../liblvgl/widgets/spinbox/lv_spinbox.h | 164 + .../widgets/spinbox/lv_spinbox_private.h | 59 + .../liblvgl/widgets/spinner/lv_spinner.h | 63 + .../liblvgl/widgets/switch/lv_switch.h | 84 + .../widgets/switch/lv_switch_private.h | 55 + test/include/liblvgl/widgets/table/lv_table.h | 214 + .../liblvgl/widgets/table/lv_table_private.h | 64 + .../liblvgl/widgets/tabview/lv_tabview.h | 115 + .../widgets/tabview/lv_tabview_private.h | 55 + .../liblvgl/widgets/textarea/lv_textarea.h | 353 ++ .../widgets/textarea/lv_textarea_private.h | 75 + .../liblvgl/widgets/tileview/lv_tileview.h | 86 + .../widgets/tileview/lv_tileview_private.h | 58 + test/include/liblvgl/widgets/win/lv_win.h | 74 + .../liblvgl/widgets/win/lv_win_private.h | 52 + test/include/main.h | 80 + test/include/pros/abstract_motor.hpp | 1182 ++++ test/include/pros/adi.h | 1383 ++++ test/include/pros/adi.hpp | 2036 ++++++ test/include/pros/ai_vision.h | 502 ++ test/include/pros/ai_vision.hpp | 600 ++ test/include/pros/apix.h | 901 +++ test/include/pros/colors.h | 204 + test/include/pros/colors.hpp | 190 + test/include/pros/device.h | 92 + test/include/pros/device.hpp | 206 + test/include/pros/distance.h | 160 + test/include/pros/distance.hpp | 247 + test/include/pros/error.h | 42 + test/include/pros/ext_adi.h | 1330 ++++ test/include/pros/gps.h | 884 +++ test/include/pros/gps.hpp | 937 +++ test/include/pros/imu.h | 974 +++ test/include/pros/imu.hpp | 1077 ++++ test/include/pros/link.h | 421 ++ test/include/pros/link.hpp | 283 + test/include/pros/llemu.h | 55 + test/include/pros/llemu.hpp | 147 + test/include/pros/misc.h | 876 +++ test/include/pros/misc.hpp | 616 ++ test/include/pros/motor_group.hpp | 2423 +++++++ test/include/pros/motors.h | 1381 ++++ test/include/pros/motors.hpp | 2477 ++++++++ test/include/pros/optical.h | 506 ++ test/include/pros/optical.hpp | 468 ++ test/include/pros/rotation.h | 390 ++ test/include/pros/rotation.hpp | 394 ++ test/include/pros/rtos.h | 1188 ++++ test/include/pros/rtos.hpp | 2121 +++++++ test/include/pros/screen.h | 791 +++ test/include/pros/screen.hpp | 717 +++ test/include/pros/serial.h | 410 ++ test/include/pros/serial.hpp | 344 + test/include/pros/version.h | 23 + test/include/pros/vision.h | 851 +++ test/include/pros/vision.hpp | 787 +++ test/project.pros | 597 ++ test/src/main.cpp | 94 + 551 files changed, 154926 insertions(+), 2 deletions(-) create mode 100644 test/.gitignore create mode 100644 test/Makefile create mode 100644 test/common.mk create mode 100644 test/firmware/libc.a create mode 100644 test/firmware/liblvgl.a create mode 100644 test/firmware/libm.a create mode 100644 test/firmware/libpros.a create mode 100644 test/firmware/v5-common.ld create mode 100644 test/firmware/v5-hot.ld create mode 100644 test/firmware/v5.ld create mode 100644 test/include/api.h create mode 100644 test/include/liblvgl/core/lv_global.h create mode 100644 test/include/liblvgl/core/lv_group.h create mode 100644 test/include/liblvgl/core/lv_group_private.h create mode 100644 test/include/liblvgl/core/lv_obj.h create mode 100644 test/include/liblvgl/core/lv_obj_class.h create mode 100644 test/include/liblvgl/core/lv_obj_class_private.h create mode 100644 test/include/liblvgl/core/lv_obj_draw.h create mode 100644 test/include/liblvgl/core/lv_obj_draw_private.h create mode 100644 test/include/liblvgl/core/lv_obj_event.h create mode 100644 test/include/liblvgl/core/lv_obj_event_private.h create mode 100644 test/include/liblvgl/core/lv_obj_pos.h create mode 100644 test/include/liblvgl/core/lv_obj_private.h create mode 100644 test/include/liblvgl/core/lv_obj_property.h create mode 100644 test/include/liblvgl/core/lv_obj_scroll.h create mode 100644 test/include/liblvgl/core/lv_obj_scroll_private.h create mode 100644 test/include/liblvgl/core/lv_obj_style.h create mode 100644 test/include/liblvgl/core/lv_obj_style_gen.h create mode 100644 test/include/liblvgl/core/lv_obj_style_private.h create mode 100644 test/include/liblvgl/core/lv_obj_tree.h create mode 100644 test/include/liblvgl/core/lv_refr.h create mode 100644 test/include/liblvgl/core/lv_refr_private.h create mode 100644 test/include/liblvgl/display/lv_display.h create mode 100644 test/include/liblvgl/display/lv_display_private.h create mode 100644 test/include/liblvgl/draw/dma2d/lv_draw_dma2d.h create mode 100644 test/include/liblvgl/draw/dma2d/lv_draw_dma2d_private.h create mode 100644 test/include/liblvgl/draw/lv_draw.h create mode 100644 test/include/liblvgl/draw/lv_draw_arc.h create mode 100644 test/include/liblvgl/draw/lv_draw_buf.h create mode 100644 test/include/liblvgl/draw/lv_draw_buf_private.h create mode 100644 test/include/liblvgl/draw/lv_draw_image.h create mode 100644 test/include/liblvgl/draw/lv_draw_image_private.h create mode 100644 test/include/liblvgl/draw/lv_draw_label.h create mode 100644 test/include/liblvgl/draw/lv_draw_label_private.h create mode 100644 test/include/liblvgl/draw/lv_draw_line.h create mode 100644 test/include/liblvgl/draw/lv_draw_mask.h create mode 100644 test/include/liblvgl/draw/lv_draw_mask_private.h create mode 100644 test/include/liblvgl/draw/lv_draw_private.h create mode 100644 test/include/liblvgl/draw/lv_draw_rect.h create mode 100644 test/include/liblvgl/draw/lv_draw_rect_private.h create mode 100644 test/include/liblvgl/draw/lv_draw_triangle.h create mode 100644 test/include/liblvgl/draw/lv_draw_triangle_private.h create mode 100644 test/include/liblvgl/draw/lv_draw_vector.h create mode 100644 test/include/liblvgl/draw/lv_draw_vector_private.h create mode 100644 test/include/liblvgl/draw/lv_image_decoder.h create mode 100644 test/include/liblvgl/draw/lv_image_decoder_private.h create mode 100644 test/include/liblvgl/draw/lv_image_dsc.h create mode 100644 test/include/liblvgl/draw/nema_gfx/lv_draw_nema_gfx.h create mode 100644 test/include/liblvgl/draw/nema_gfx/lv_draw_nema_gfx_utils.h create mode 100644 test/include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h create mode 100644 test/include/liblvgl/draw/nxp/pxp/lv_pxp_cfg.h create mode 100644 test/include/liblvgl/draw/nxp/pxp/lv_pxp_osa.h create mode 100644 test/include/liblvgl/draw/nxp/pxp/lv_pxp_utils.h create mode 100644 test/include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h create mode 100644 test/include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h create mode 100644 test/include/liblvgl/draw/nxp/vglite/lv_vglite_matrix.h create mode 100644 test/include/liblvgl/draw/nxp/vglite/lv_vglite_path.h create mode 100644 test/include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h create mode 100644 test/include/liblvgl/draw/opengles/lv_draw_opengles.h create mode 100644 test/include/liblvgl/draw/renesas/dave2d/lv_draw_dave2d.h create mode 100644 test/include/liblvgl/draw/renesas/dave2d/lv_draw_dave2d_utils.h create mode 100644 test/include/liblvgl/draw/sdl/lv_draw_sdl.h create mode 100644 test/include/liblvgl/draw/sw/arm2d/lv_draw_sw_arm2d.h create mode 100644 test/include/liblvgl/draw/sw/arm2d/lv_draw_sw_helium.h create mode 100644 test/include/liblvgl/draw/sw/blend/arm2d/lv_blend_arm2d.h create mode 100644 test/include/liblvgl/draw/sw/blend/helium/lv_blend_helium.h create mode 100644 test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend.h create mode 100644 test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_private.h create mode 100644 test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_al88.h create mode 100644 test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_argb8888.h create mode 100644 test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_i1.h create mode 100644 test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_l8.h create mode 100644 test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_rgb565.h create mode 100644 test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_rgb888.h create mode 100644 test/include/liblvgl/draw/sw/blend/neon/lv_blend_neon.h create mode 100644 test/include/liblvgl/draw/sw/lv_draw_sw.h create mode 100644 test/include/liblvgl/draw/sw/lv_draw_sw_gradient.h create mode 100644 test/include/liblvgl/draw/sw/lv_draw_sw_gradient_private.h create mode 100644 test/include/liblvgl/draw/sw/lv_draw_sw_mask.h create mode 100644 test/include/liblvgl/draw/sw/lv_draw_sw_mask_private.h create mode 100644 test/include/liblvgl/draw/sw/lv_draw_sw_private.h create mode 100644 test/include/liblvgl/draw/vg_lite/lv_draw_vg_lite.h create mode 100644 test/include/liblvgl/draw/vg_lite/lv_draw_vg_lite_type.h create mode 100644 test/include/liblvgl/draw/vg_lite/lv_vg_lite_decoder.h create mode 100644 test/include/liblvgl/draw/vg_lite/lv_vg_lite_grad.h create mode 100644 test/include/liblvgl/draw/vg_lite/lv_vg_lite_math.h create mode 100644 test/include/liblvgl/draw/vg_lite/lv_vg_lite_path.h create mode 100644 test/include/liblvgl/draw/vg_lite/lv_vg_lite_pending.h create mode 100644 test/include/liblvgl/draw/vg_lite/lv_vg_lite_stroke.h create mode 100644 test/include/liblvgl/draw/vg_lite/lv_vg_lite_utils.h create mode 100644 test/include/liblvgl/drivers/README.md create mode 100644 test/include/liblvgl/drivers/display/drm/lv_linux_drm.h create mode 100644 test/include/liblvgl/drivers/display/fb/lv_linux_fbdev.h create mode 100644 test/include/liblvgl/drivers/display/ili9341/lv_ili9341.h create mode 100644 test/include/liblvgl/drivers/display/lcd/lv_lcd_generic_mipi.h create mode 100644 test/include/liblvgl/drivers/display/renesas_glcdc/lv_renesas_glcdc.h create mode 100644 test/include/liblvgl/drivers/display/st7735/lv_st7735.h create mode 100644 test/include/liblvgl/drivers/display/st7789/lv_st7789.h create mode 100644 test/include/liblvgl/drivers/display/st7796/lv_st7796.h create mode 100644 test/include/liblvgl/drivers/display/st_ltdc/lv_st_ltdc.h create mode 100644 test/include/liblvgl/drivers/display/tft_espi/lv_tft_espi.cpp create mode 100644 test/include/liblvgl/drivers/display/tft_espi/lv_tft_espi.h create mode 100644 test/include/liblvgl/drivers/evdev/lv_evdev.h create mode 100644 test/include/liblvgl/drivers/glfw/lv_glfw_window.h create mode 100644 test/include/liblvgl/drivers/glfw/lv_glfw_window_private.h create mode 100644 test/include/liblvgl/drivers/glfw/lv_opengles_debug.h create mode 100644 test/include/liblvgl/drivers/glfw/lv_opengles_driver.h create mode 100644 test/include/liblvgl/drivers/glfw/lv_opengles_texture.h create mode 100644 test/include/liblvgl/drivers/libinput/lv_libinput.h create mode 100644 test/include/liblvgl/drivers/libinput/lv_libinput_private.h create mode 100644 test/include/liblvgl/drivers/libinput/lv_xkb.h create mode 100644 test/include/liblvgl/drivers/libinput/lv_xkb_private.h create mode 100644 test/include/liblvgl/drivers/lv_drivers.h create mode 100644 test/include/liblvgl/drivers/nuttx/lv_nuttx_cache.h create mode 100644 test/include/liblvgl/drivers/nuttx/lv_nuttx_entry.h create mode 100644 test/include/liblvgl/drivers/nuttx/lv_nuttx_fbdev.h create mode 100644 test/include/liblvgl/drivers/nuttx/lv_nuttx_image_cache.h create mode 100644 test/include/liblvgl/drivers/nuttx/lv_nuttx_lcd.h create mode 100644 test/include/liblvgl/drivers/nuttx/lv_nuttx_libuv.h create mode 100644 test/include/liblvgl/drivers/nuttx/lv_nuttx_profiler.h create mode 100644 test/include/liblvgl/drivers/nuttx/lv_nuttx_touchscreen.h create mode 100644 test/include/liblvgl/drivers/qnx/lv_qnx.h create mode 100644 test/include/liblvgl/drivers/sdl/lv_sdl_keyboard.h create mode 100644 test/include/liblvgl/drivers/sdl/lv_sdl_mouse.h create mode 100644 test/include/liblvgl/drivers/sdl/lv_sdl_mousewheel.h create mode 100644 test/include/liblvgl/drivers/sdl/lv_sdl_private.h create mode 100644 test/include/liblvgl/drivers/sdl/lv_sdl_window.h create mode 100644 test/include/liblvgl/drivers/wayland/lv_wayland.h create mode 100644 test/include/liblvgl/drivers/wayland/lv_wayland_smm.h create mode 100644 test/include/liblvgl/drivers/windows/lv_windows_context.h create mode 100644 test/include/liblvgl/drivers/windows/lv_windows_display.h create mode 100644 test/include/liblvgl/drivers/windows/lv_windows_input.h create mode 100644 test/include/liblvgl/drivers/windows/lv_windows_input_private.h create mode 100644 test/include/liblvgl/drivers/x11/lv_x11.h create mode 100644 test/include/liblvgl/font/lv_binfont_loader.h create mode 100644 test/include/liblvgl/font/lv_font.h create mode 100644 test/include/liblvgl/font/lv_font_fmt_txt.h create mode 100644 test/include/liblvgl/font/lv_font_fmt_txt_private.h create mode 100644 test/include/liblvgl/font/lv_symbol_def.h create mode 100644 test/include/liblvgl/indev/lv_indev.h create mode 100644 test/include/liblvgl/indev/lv_indev_private.h create mode 100644 test/include/liblvgl/indev/lv_indev_scroll.h create mode 100644 test/include/liblvgl/layouts/flex/lv_flex.h create mode 100644 test/include/liblvgl/layouts/grid/lv_grid.h create mode 100644 test/include/liblvgl/layouts/lv_layout.h create mode 100644 test/include/liblvgl/layouts/lv_layout_private.h create mode 100644 test/include/liblvgl/libs/barcode/code128.h create mode 100644 test/include/liblvgl/libs/barcode/lv_barcode.h create mode 100644 test/include/liblvgl/libs/barcode/lv_barcode_private.h create mode 100644 test/include/liblvgl/libs/bin_decoder/lv_bin_decoder.h create mode 100644 test/include/liblvgl/libs/bmp/lv_bmp.h create mode 100644 test/include/liblvgl/libs/ffmpeg/lv_ffmpeg.h create mode 100644 test/include/liblvgl/libs/ffmpeg/lv_ffmpeg_private.h create mode 100644 test/include/liblvgl/libs/freetype/arial.ttf create mode 100644 test/include/liblvgl/libs/freetype/ftmodule.h create mode 100644 test/include/liblvgl/libs/freetype/ftoption.h create mode 100644 test/include/liblvgl/libs/freetype/lv_freetype.h create mode 100644 test/include/liblvgl/libs/freetype/lv_freetype_private.h create mode 100644 test/include/liblvgl/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp create mode 100644 test/include/liblvgl/libs/fsdrv/lv_fs_arduino_sd.cpp create mode 100644 test/include/liblvgl/libs/fsdrv/lv_fsdrv.h create mode 100644 test/include/liblvgl/libs/gif/gifdec.h create mode 100644 test/include/liblvgl/libs/gif/gifdec_mve.h create mode 100644 test/include/liblvgl/libs/gif/lv_gif.h create mode 100644 test/include/liblvgl/libs/gif/lv_gif_private.h create mode 100644 test/include/liblvgl/libs/libjpeg_turbo/lv_libjpeg_turbo.h create mode 100644 test/include/liblvgl/libs/libpng/lv_libpng.h create mode 100644 test/include/liblvgl/libs/lodepng/lodepng.h create mode 100644 test/include/liblvgl/libs/lodepng/lv_lodepng.h create mode 100644 test/include/liblvgl/libs/lz4/LICENSE create mode 100644 test/include/liblvgl/libs/lz4/lz4.h create mode 100644 test/include/liblvgl/libs/qrcode/lv_qrcode.h create mode 100644 test/include/liblvgl/libs/qrcode/lv_qrcode_private.h create mode 100644 test/include/liblvgl/libs/qrcode/qrcodegen.h create mode 100644 test/include/liblvgl/libs/rle/lv_rle.h create mode 100644 test/include/liblvgl/libs/rlottie/lv_rlottie.h create mode 100644 test/include/liblvgl/libs/rlottie/lv_rlottie_private.h create mode 100644 test/include/liblvgl/libs/svg/lv_svg.h create mode 100644 test/include/liblvgl/libs/svg/lv_svg_parser.h create mode 100644 test/include/liblvgl/libs/svg/lv_svg_render.h create mode 100644 test/include/liblvgl/libs/svg/lv_svg_token.h create mode 100644 test/include/liblvgl/libs/thorvg/add_lvgl_if.sh create mode 100644 test/include/liblvgl/libs/thorvg/config.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/allocators.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/cursorstreamwrapper.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/document.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/encodedstream.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/encodings.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/error/en.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/error/error.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/filereadstream.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/filewritestream.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/fwd.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/biginteger.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/clzll.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/diyfp.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/dtoa.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/ieee754.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/itoa.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/meta.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/pow10.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/regex.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/stack.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/strfunc.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/strtod.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/internal/swap.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/istreamwrapper.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/memorybuffer.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/memorystream.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/msinttypes/inttypes.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/msinttypes/stdint.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/ostreamwrapper.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/pointer.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/prettywriter.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/rapidjson.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/reader.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/schema.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/stream.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/stringbuffer.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/uri.h create mode 100644 test/include/liblvgl/libs/thorvg/rapidjson/writer.h create mode 100644 test/include/liblvgl/libs/thorvg/thorvg.h create mode 100644 test/include/liblvgl/libs/thorvg/thorvg_capi.h create mode 100644 test/include/liblvgl/libs/thorvg/thorvg_lottie.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgAccessor.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgAnimation.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgAnimation.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgArray.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgBinaryDesc.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgCanvas.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgCanvas.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgCapi.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgCommon.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgCompressor.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgCompressor.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgFill.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgFill.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgFrameModule.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgGlCanvas.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgInitializer.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgInlist.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgIteratorAccessor.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLines.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgLines.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLoadModule.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLoader.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgLoader.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLock.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieAnimation.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieBuilder.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieBuilder.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieExpressions.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieExpressions.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieInterpolator.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieInterpolator.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieLoader.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieLoader.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieModel.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieModel.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieParser.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieParser.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieParserHandler.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieParserHandler.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgLottieProperty.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgMath.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgMath.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgPaint.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgPaint.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgPicture.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgPicture.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgRawLoader.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgRawLoader.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgRender.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgRender.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSaveModule.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSaver.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgScene.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgScene.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgShape.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgShape.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgStr.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgStr.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgCssStyle.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgCssStyle.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgLoader.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgLoader.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgLoaderCommon.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgPath.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgPath.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgSceneBuilder.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgSceneBuilder.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgUtil.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSvgUtil.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwCanvas.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwCommon.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwFill.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwImage.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwMath.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwMemPool.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwRaster.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwRasterAvx.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwRasterC.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwRasterNeon.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwRasterTexmap.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwRenderer.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwRenderer.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwRle.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwShape.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgSwStroke.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgTaskScheduler.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgTaskScheduler.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgText.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgText.h create mode 100644 test/include/liblvgl/libs/thorvg/tvgWgCanvas.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgXmlParser.cpp create mode 100644 test/include/liblvgl/libs/thorvg/tvgXmlParser.h create mode 100644 test/include/liblvgl/libs/tiny_ttf/lv_tiny_ttf.h create mode 100644 test/include/liblvgl/libs/tiny_ttf/stb_rect_pack.h create mode 100644 test/include/liblvgl/libs/tiny_ttf/stb_truetype_htcw.h create mode 100644 test/include/liblvgl/libs/tjpgd/lv_tjpgd.h create mode 100644 test/include/liblvgl/libs/tjpgd/tjpgd.h create mode 100644 test/include/liblvgl/libs/tjpgd/tjpgdcnf.h create mode 100644 test/include/liblvgl/llemu.h create mode 100644 test/include/liblvgl/llemu.hpp create mode 100644 test/include/liblvgl/lv_api_map_v8.h create mode 100644 test/include/liblvgl/lv_api_map_v9_0.h create mode 100644 test/include/liblvgl/lv_api_map_v9_1.h create mode 100644 test/include/liblvgl/lv_conf.h create mode 100644 test/include/liblvgl/lv_conf.old.h create mode 100644 test/include/liblvgl/lv_conf_internal.h create mode 100644 test/include/liblvgl/lv_conf_kconfig.h create mode 100644 test/include/liblvgl/lv_init.h create mode 100644 test/include/liblvgl/lv_version.h create mode 100644 test/include/liblvgl/lvgl.h create mode 100644 test/include/liblvgl/lvgl_private.h create mode 100644 test/include/liblvgl/misc/cache/lv_cache.h create mode 100644 test/include/liblvgl/misc/cache/lv_cache_entry.h create mode 100644 test/include/liblvgl/misc/cache/lv_cache_entry_private.h create mode 100644 test/include/liblvgl/misc/cache/lv_cache_lru_rb.h create mode 100644 test/include/liblvgl/misc/cache/lv_cache_private.h create mode 100644 test/include/liblvgl/misc/cache/lv_image_cache.h create mode 100644 test/include/liblvgl/misc/cache/lv_image_header_cache.h create mode 100644 test/include/liblvgl/misc/lv_anim.h create mode 100644 test/include/liblvgl/misc/lv_anim_private.h create mode 100644 test/include/liblvgl/misc/lv_anim_timeline.h create mode 100644 test/include/liblvgl/misc/lv_area.h create mode 100644 test/include/liblvgl/misc/lv_area_private.h create mode 100644 test/include/liblvgl/misc/lv_array.h create mode 100644 test/include/liblvgl/misc/lv_assert.h create mode 100644 test/include/liblvgl/misc/lv_async.h create mode 100644 test/include/liblvgl/misc/lv_bidi.h create mode 100644 test/include/liblvgl/misc/lv_bidi_private.h create mode 100644 test/include/liblvgl/misc/lv_circle_buf.h create mode 100644 test/include/liblvgl/misc/lv_color.h create mode 100644 test/include/liblvgl/misc/lv_color_op.h create mode 100644 test/include/liblvgl/misc/lv_color_op_private.h create mode 100644 test/include/liblvgl/misc/lv_event.h create mode 100644 test/include/liblvgl/misc/lv_event_private.h create mode 100644 test/include/liblvgl/misc/lv_fs.h create mode 100644 test/include/liblvgl/misc/lv_fs_private.h create mode 100644 test/include/liblvgl/misc/lv_iter.h create mode 100644 test/include/liblvgl/misc/lv_ll.h create mode 100644 test/include/liblvgl/misc/lv_log.h create mode 100644 test/include/liblvgl/misc/lv_lru.h create mode 100644 test/include/liblvgl/misc/lv_math.h create mode 100644 test/include/liblvgl/misc/lv_matrix.h create mode 100644 test/include/liblvgl/misc/lv_palette.h create mode 100644 test/include/liblvgl/misc/lv_profiler.h create mode 100644 test/include/liblvgl/misc/lv_profiler_builtin.h create mode 100644 test/include/liblvgl/misc/lv_profiler_builtin_private.h create mode 100644 test/include/liblvgl/misc/lv_rb.h create mode 100644 test/include/liblvgl/misc/lv_rb_private.h create mode 100644 test/include/liblvgl/misc/lv_style.h create mode 100644 test/include/liblvgl/misc/lv_style_gen.h create mode 100644 test/include/liblvgl/misc/lv_style_private.h create mode 100644 test/include/liblvgl/misc/lv_templ.h create mode 100644 test/include/liblvgl/misc/lv_text.h create mode 100644 test/include/liblvgl/misc/lv_text_ap.h create mode 100644 test/include/liblvgl/misc/lv_text_private.h create mode 100644 test/include/liblvgl/misc/lv_timer.h create mode 100644 test/include/liblvgl/misc/lv_timer_private.h create mode 100644 test/include/liblvgl/misc/lv_tree.h create mode 100644 test/include/liblvgl/misc/lv_types.h create mode 100644 test/include/liblvgl/misc/lv_utils.h create mode 100644 test/include/liblvgl/osal/lv_cmsis_rtos2.h create mode 100644 test/include/liblvgl/osal/lv_freertos.h create mode 100644 test/include/liblvgl/osal/lv_mqx.h create mode 100644 test/include/liblvgl/osal/lv_os.h create mode 100644 test/include/liblvgl/osal/lv_os_none.h create mode 100644 test/include/liblvgl/osal/lv_os_private.h create mode 100644 test/include/liblvgl/osal/lv_pthread.h create mode 100644 test/include/liblvgl/osal/lv_rtthread.h create mode 100644 test/include/liblvgl/osal/lv_windows.h create mode 100644 test/include/liblvgl/others/file_explorer/lv_file_explorer.h create mode 100644 test/include/liblvgl/others/file_explorer/lv_file_explorer_private.h create mode 100644 test/include/liblvgl/others/font_manager/lv_font_manager.h create mode 100644 test/include/liblvgl/others/font_manager/lv_font_manager_recycle.h create mode 100644 test/include/liblvgl/others/font_manager/lv_font_manager_utils.h create mode 100644 test/include/liblvgl/others/fragment/README.md create mode 100644 test/include/liblvgl/others/fragment/lv_fragment.h create mode 100644 test/include/liblvgl/others/fragment/lv_fragment_private.h create mode 100644 test/include/liblvgl/others/gridnav/lv_gridnav.h create mode 100644 test/include/liblvgl/others/ime/lv_ime_pinyin.h create mode 100644 test/include/liblvgl/others/ime/lv_ime_pinyin_private.h create mode 100644 test/include/liblvgl/others/imgfont/lv_imgfont.h create mode 100644 test/include/liblvgl/others/monkey/lv_monkey.h create mode 100644 test/include/liblvgl/others/monkey/lv_monkey_private.h create mode 100644 test/include/liblvgl/others/observer/lv_observer.h create mode 100644 test/include/liblvgl/others/observer/lv_observer_private.h create mode 100644 test/include/liblvgl/others/snapshot/lv_snapshot.h create mode 100644 test/include/liblvgl/others/sysmon/lv_sysmon.h create mode 100644 test/include/liblvgl/others/sysmon/lv_sysmon_private.h create mode 100644 test/include/liblvgl/others/vg_lite_tvg/vg_lite.h create mode 100644 test/include/liblvgl/others/vg_lite_tvg/vg_lite_tvg.cpp create mode 100644 test/include/liblvgl/stdlib/builtin/lv_tlsf.h create mode 100644 test/include/liblvgl/stdlib/builtin/lv_tlsf_private.h create mode 100644 test/include/liblvgl/stdlib/lv_mem.h create mode 100644 test/include/liblvgl/stdlib/lv_mem_private.h create mode 100644 test/include/liblvgl/stdlib/lv_sprintf.h create mode 100644 test/include/liblvgl/stdlib/lv_string.h create mode 100644 test/include/liblvgl/themes/default/lv_theme_default.h create mode 100644 test/include/liblvgl/themes/lv_theme.h create mode 100644 test/include/liblvgl/themes/lv_theme_private.h create mode 100644 test/include/liblvgl/themes/mono/lv_theme_mono.h create mode 100644 test/include/liblvgl/themes/simple/lv_theme_simple.h create mode 100644 test/include/liblvgl/tick/lv_tick.h create mode 100644 test/include/liblvgl/tick/lv_tick_private.h create mode 100644 test/include/liblvgl/widgets/animimage/lv_animimage.h create mode 100644 test/include/liblvgl/widgets/animimage/lv_animimage_private.h create mode 100644 test/include/liblvgl/widgets/arc/lv_arc.h create mode 100644 test/include/liblvgl/widgets/arc/lv_arc_private.h create mode 100644 test/include/liblvgl/widgets/bar/lv_bar.h create mode 100644 test/include/liblvgl/widgets/bar/lv_bar_private.h create mode 100644 test/include/liblvgl/widgets/button/lv_button.h create mode 100644 test/include/liblvgl/widgets/button/lv_button_private.h create mode 100644 test/include/liblvgl/widgets/buttonmatrix/lv_buttonmatrix.h create mode 100644 test/include/liblvgl/widgets/buttonmatrix/lv_buttonmatrix_private.h create mode 100644 test/include/liblvgl/widgets/calendar/lv_calendar.h create mode 100644 test/include/liblvgl/widgets/calendar/lv_calendar_chinese.h create mode 100644 test/include/liblvgl/widgets/calendar/lv_calendar_chinese_private.h create mode 100644 test/include/liblvgl/widgets/calendar/lv_calendar_header_arrow.h create mode 100644 test/include/liblvgl/widgets/calendar/lv_calendar_header_dropdown.h create mode 100644 test/include/liblvgl/widgets/calendar/lv_calendar_private.h create mode 100644 test/include/liblvgl/widgets/canvas/lv_canvas.h create mode 100644 test/include/liblvgl/widgets/canvas/lv_canvas_private.h create mode 100644 test/include/liblvgl/widgets/chart/lv_chart.h create mode 100644 test/include/liblvgl/widgets/chart/lv_chart_private.h create mode 100644 test/include/liblvgl/widgets/checkbox/lv_checkbox.h create mode 100644 test/include/liblvgl/widgets/checkbox/lv_checkbox_private.h create mode 100644 test/include/liblvgl/widgets/dropdown/lv_dropdown.h create mode 100644 test/include/liblvgl/widgets/dropdown/lv_dropdown_private.h create mode 100644 test/include/liblvgl/widgets/image/lv_image.h create mode 100644 test/include/liblvgl/widgets/image/lv_image_private.h create mode 100644 test/include/liblvgl/widgets/imagebutton/lv_imagebutton.h create mode 100644 test/include/liblvgl/widgets/imagebutton/lv_imagebutton_private.h create mode 100644 test/include/liblvgl/widgets/keyboard/lv_keyboard.h create mode 100644 test/include/liblvgl/widgets/keyboard/lv_keyboard_private.h create mode 100644 test/include/liblvgl/widgets/label/lv_label.h create mode 100644 test/include/liblvgl/widgets/label/lv_label_private.h create mode 100644 test/include/liblvgl/widgets/led/lv_led.h create mode 100644 test/include/liblvgl/widgets/led/lv_led_private.h create mode 100644 test/include/liblvgl/widgets/line/lv_line.h create mode 100644 test/include/liblvgl/widgets/line/lv_line_private.h create mode 100644 test/include/liblvgl/widgets/list/lv_list.h create mode 100644 test/include/liblvgl/widgets/lottie/lv_lottie.h create mode 100644 test/include/liblvgl/widgets/lottie/lv_lottie_private.h create mode 100644 test/include/liblvgl/widgets/menu/lv_menu.h create mode 100644 test/include/liblvgl/widgets/menu/lv_menu_private.h create mode 100644 test/include/liblvgl/widgets/msgbox/lv_msgbox.h create mode 100644 test/include/liblvgl/widgets/msgbox/lv_msgbox_private.h create mode 100644 test/include/liblvgl/widgets/objx_templ/lv_objx_templ.h create mode 100644 test/include/liblvgl/widgets/property/lv_obj_property_names.h create mode 100644 test/include/liblvgl/widgets/property/lv_style_properties.h create mode 100644 test/include/liblvgl/widgets/roller/lv_roller.h create mode 100644 test/include/liblvgl/widgets/roller/lv_roller_private.h create mode 100644 test/include/liblvgl/widgets/scale/lv_scale.h create mode 100644 test/include/liblvgl/widgets/scale/lv_scale_private.h create mode 100644 test/include/liblvgl/widgets/slider/lv_slider.h create mode 100644 test/include/liblvgl/widgets/slider/lv_slider_private.h create mode 100644 test/include/liblvgl/widgets/span/lv_span.h create mode 100644 test/include/liblvgl/widgets/span/lv_span_private.h create mode 100644 test/include/liblvgl/widgets/spinbox/lv_spinbox.h create mode 100644 test/include/liblvgl/widgets/spinbox/lv_spinbox_private.h create mode 100644 test/include/liblvgl/widgets/spinner/lv_spinner.h create mode 100644 test/include/liblvgl/widgets/switch/lv_switch.h create mode 100644 test/include/liblvgl/widgets/switch/lv_switch_private.h create mode 100644 test/include/liblvgl/widgets/table/lv_table.h create mode 100644 test/include/liblvgl/widgets/table/lv_table_private.h create mode 100644 test/include/liblvgl/widgets/tabview/lv_tabview.h create mode 100644 test/include/liblvgl/widgets/tabview/lv_tabview_private.h create mode 100644 test/include/liblvgl/widgets/textarea/lv_textarea.h create mode 100644 test/include/liblvgl/widgets/textarea/lv_textarea_private.h create mode 100644 test/include/liblvgl/widgets/tileview/lv_tileview.h create mode 100644 test/include/liblvgl/widgets/tileview/lv_tileview_private.h create mode 100644 test/include/liblvgl/widgets/win/lv_win.h create mode 100644 test/include/liblvgl/widgets/win/lv_win_private.h create mode 100644 test/include/main.h create mode 100644 test/include/pros/abstract_motor.hpp create mode 100644 test/include/pros/adi.h create mode 100644 test/include/pros/adi.hpp create mode 100644 test/include/pros/ai_vision.h create mode 100644 test/include/pros/ai_vision.hpp create mode 100644 test/include/pros/apix.h create mode 100644 test/include/pros/colors.h create mode 100644 test/include/pros/colors.hpp create mode 100644 test/include/pros/device.h create mode 100644 test/include/pros/device.hpp create mode 100644 test/include/pros/distance.h create mode 100644 test/include/pros/distance.hpp create mode 100644 test/include/pros/error.h create mode 100644 test/include/pros/ext_adi.h create mode 100644 test/include/pros/gps.h create mode 100644 test/include/pros/gps.hpp create mode 100644 test/include/pros/imu.h create mode 100644 test/include/pros/imu.hpp create mode 100644 test/include/pros/link.h create mode 100644 test/include/pros/link.hpp create mode 100644 test/include/pros/llemu.h create mode 100644 test/include/pros/llemu.hpp create mode 100644 test/include/pros/misc.h create mode 100644 test/include/pros/misc.hpp create mode 100644 test/include/pros/motor_group.hpp create mode 100644 test/include/pros/motors.h create mode 100644 test/include/pros/motors.hpp create mode 100644 test/include/pros/optical.h create mode 100644 test/include/pros/optical.hpp create mode 100644 test/include/pros/rotation.h create mode 100644 test/include/pros/rotation.hpp create mode 100644 test/include/pros/rtos.h create mode 100644 test/include/pros/rtos.hpp create mode 100644 test/include/pros/screen.h create mode 100644 test/include/pros/screen.hpp create mode 100644 test/include/pros/serial.h create mode 100644 test/include/pros/serial.hpp create mode 100644 test/include/pros/version.h create mode 100644 test/include/pros/vision.h create mode 100644 test/include/pros/vision.hpp create mode 100644 test/project.pros create mode 100644 test/src/main.cpp diff --git a/pros/ga/analytics.py b/pros/ga/analytics.py index 6f786105..868d0795 100644 --- a/pros/ga/analytics.py +++ b/pros/ga/analytics.py @@ -33,9 +33,43 @@ def __init__(self): self.uID = self.cli_config.ga['u_id'] self.pendingRequests = [] + self._connectivity_checked = False + self._connecitivty_ok = True + + def _check_connectivity(self) -> bool: + """ + Quickly test connectivity to the analytics endpoint. + + If it fails, automatically disable analytics (like --no-analytics) + for this and subsequent commands, and persist that choice. + """ + if self._connectivity_checked: + return self._connectivity_ok + + self._connectivity_checked = True + try: + r = requests.head(url, timeout=1.0) + self._connectivity_ok = r.ok + except Exception: + self._connectivity_ok = False + + if not self._connectivity_ok: + from pros.cli.common import logger + logger(__name__).warning( + "Analytics server not reachable. Disabling analytics for this and future commands.", + extra={'sentry': False}, + ) + self.set_use(False) + + return self._connectivity_ok + def send(self,action): if not self.useAnalytics or self.sent: return + + if not self._check_connectivity(): + return + self.sent=True # Prevent Send from being called multiple times try: #Payload to be sent to GA, idk what some of them are but it works diff --git a/pros/serial/devices/vex/v5_device.py b/pros/serial/devices/vex/v5_device.py index 6ec6913d..a594d18c 100644 --- a/pros/serial/devices/vex/v5_device.py +++ b/pros/serial/devices/vex/v5_device.py @@ -33,8 +33,7 @@ def find_v5_ports(p_type: str): def filter_vex_ports(p): - return p.vid is not None and p.vid in [0x2888, 0x0501] or \ - p.name is not None and ('VEX' in p.name or 'V5' in p.name) + return p.vid is not None and p.vid in [0x2888, 0x0501] def filter_v5_ports(p, locations, names): return (p.location is not None and any([p.location.endswith(l) for l in locations])) or \ diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 00000000..e303e2c0 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,17 @@ +# Compiled Object files +*.o +*.obj + +# Executables +*.bin +*.elf + +# PROS +bin/ +.vscode/ +.cache/ +compile_commands.json +temp.log +temp.errors +*.ini +.d/ \ No newline at end of file diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 00000000..ece80655 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,47 @@ +################################################################################ +######################### User configurable parameters ######################### +# filename extensions +CEXTS:=c +ASMEXTS:=s S +CXXEXTS:=cpp c++ cc + +# probably shouldn't modify these, but you may need them below +ROOT=. +FWDIR:=$(ROOT)/firmware +BINDIR=$(ROOT)/bin +SRCDIR=$(ROOT)/src +INCDIR=$(ROOT)/include + +WARNFLAGS+= +EXTRA_CFLAGS= +EXTRA_CXXFLAGS= + +# Set to 1 to enable hot/cold linking +USE_PACKAGE:=1 + +# Add libraries you do not wish to include in the cold image here +# EXCLUDE_COLD_LIBRARIES:= $(FWDIR)/your_library.a +EXCLUDE_COLD_LIBRARIES:= + +# Set this to 1 to add additional rules to compile your project as a PROS library template +IS_LIBRARY:=0 +# TODO: CHANGE THIS! +# Be sure that your header files are in the include directory inside of a folder with the +# same name as what you set LIBNAME to below. +LIBNAME:=libbest +VERSION:=1.0.0 +# EXCLUDE_SRC_FROM_LIB= $(SRCDIR)/unpublishedfile.c +# this line excludes opcontrol.c and similar files +EXCLUDE_SRC_FROM_LIB+=$(foreach file, $(SRCDIR)/main,$(foreach cext,$(CEXTS),$(file).$(cext)) $(foreach cxxext,$(CXXEXTS),$(file).$(cxxext))) + +# files that get distributed to every user (beyond your source archive) - add +# whatever files you want here. This line is configured to add all header files +# that are in the directory include/LIBNAME +TEMPLATE_FILES=$(INCDIR)/$(LIBNAME)/*.h $(INCDIR)/$(LIBNAME)/*.hpp + +.DEFAULT_GOAL=quick + +################################################################################ +################################################################################ +########## Nothing below this line should be edited by typical users ########### +-include ./common.mk diff --git a/test/common.mk b/test/common.mk new file mode 100644 index 00000000..6b6d2167 --- /dev/null +++ b/test/common.mk @@ -0,0 +1,309 @@ +ARCHTUPLE=arm-none-eabi- +DEVICE=VEX EDR V5 + +MFLAGS=-mcpu=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -Os -g -mthumb +CPPFLAGS=-D_POSIX_THREADS -D_UNIX98_THREAD_MUTEX_ATTRIBUTES -D_POSIX_TIMERS -D_POSIX_MONOTONIC_CLOCK +GCCFLAGS=-ffunction-sections -fdata-sections -fdiagnostics-color -funwind-tables + +# Check if the llemu files in libvgl exist. If they do, define macros that the +# llemu headers in the kernel repo can use to conditionally include the libvgl +# versions +ifneq (,$(wildcard ./include/liblvgl/llemu.h)) + CPPFLAGS += -D_PROS_INCLUDE_LIBLVGL_LLEMU_H +endif +ifneq (,$(wildcard ./include/liblvgl/llemu.hpp)) + CPPFLAGS += -D_PROS_INCLUDE_LIBLVGL_LLEMU_HPP +endif + +WARNFLAGS+=-Wno-psabi + +SPACE := $() $() +COMMA := , + +C_STANDARD?=gnu23 +CXX_STANDARD?=gnu++26 + +DEPDIR := .d +$(shell mkdir -p $(DEPDIR)) +DEPFLAGS = -MT $$@ -MMD -MP -MF $(DEPDIR)/$$*.Td +MAKEDEPFOLDER = -$(VV)mkdir -p $(DEPDIR)/$$(dir $$(patsubst $(BINDIR)/%, %, $(ROOT)/$$@)) +RENAMEDEPENDENCYFILE = -$(VV)mv -f $(DEPDIR)/$$*.Td $$(patsubst $(SRCDIR)/%, $(DEPDIR)/%.d, $(ROOT)/$$<) && touch $$@ + +LIBRARIES+=$(wildcard $(FWDIR)/*.a) +# Cannot include newlib and libc because not all of the req'd stubs are implemented +EXCLUDE_COLD_LIBRARIES+=$(FWDIR)/libc.a $(FWDIR)/libm.a +COLD_LIBRARIES=$(filter-out $(EXCLUDE_COLD_LIBRARIES), $(LIBRARIES)) +wlprefix=-Wl,$(subst $(SPACE),$(COMMA),$1) +LNK_FLAGS=--gc-sections --start-group $(strip $(LIBRARIES)) -lgcc -lstdc++ --end-group -T$(FWDIR)/v5-common.ld --no-warn-rwx-segments --sort-section=alignment --sort-common + +ASMFLAGS=$(MFLAGS) $(WARNFLAGS) +CFLAGS=$(MFLAGS) $(CPPFLAGS) $(WARNFLAGS) $(GCCFLAGS) --std=$(C_STANDARD) +CXXFLAGS=$(MFLAGS) $(CPPFLAGS) $(WARNFLAGS) $(GCCFLAGS) --std=$(CXX_STANDARD) +LDFLAGS=$(MFLAGS) $(WARNFLAGS) -nostdlib $(GCCFLAGS) +SIZEFLAGS=-d --common +NUMFMTFLAGS=--to=iec --format %.2f --suffix=B + +AR:=$(ARCHTUPLE)ar +# using arm-none-eabi-as generates a listing by default. This produces a super verbose output. +# Using gcc accomplishes the same thing without the extra output +AS:=$(ARCHTUPLE)gcc +CC:=$(ARCHTUPLE)gcc +CXX:=$(ARCHTUPLE)g++ +LD:=$(ARCHTUPLE)g++ +OBJCOPY:=$(ARCHTUPLE)objcopy +SIZETOOL:=$(ARCHTUPLE)size +READELF:=$(ARCHTUPLE)readelf +STRIP:=$(ARCHTUPLE)strip + +ifneq (, $(shell command -v gnumfmt 2> /dev/null)) + SIZES_NUMFMT:=| gnumfmt --field=-4 --header $(NUMFMTFLAGS) +else +ifneq (, $(shell command -v numfmt 2> /dev/null)) + SIZES_NUMFMT:=| numfmt --field=-4 --header $(NUMFMTFLAGS) +else + SIZES_NUMFMT:= +endif +endif + +ifneq (, $(shell command -v sed 2> /dev/null)) +SIZES_SED:=| sed -e 's/ dec/total/' +else +SIZES_SED:= +endif + +rwildcard=$(foreach d,$(filter-out $3,$(wildcard $1*)),$(call rwildcard,$d/,$2,$3)$(filter $(subst *,%,$2),$d)) + +# Colors +NO_COLOR=$(shell printf "%b" "\033[0m") +OK_COLOR=$(shell printf "%b" "\033[32;01m") +ERROR_COLOR=$(shell printf "%b" "\033[31;01m") +WARN_COLOR=$(shell printf "%b" "\033[33;01m") +STEP_COLOR=$(shell printf "%b" "\033[37;01m") +OK_STRING=$(OK_COLOR)[OK]$(NO_COLOR) +DONE_STRING=$(OK_COLOR)[DONE]$(NO_COLOR) +ERROR_STRING=$(ERROR_COLOR)[ERRORS]$(NO_COLOR) +WARN_STRING=$(WARN_COLOR)[WARNINGS]$(NO_COLOR) +ECHO=/bin/printf "%s\n" +echo=@$(ECHO) "$2$1$(NO_COLOR)" +echon=@/bin/printf "%s" "$2$1$(NO_COLOR)" + +define test_output_2 +@if test $(BUILD_VERBOSE) -eq $(or $4,1); then printf "%s\n" "$2"; fi; +@output="$$($2 2>&1)"; exit=$$?; \ +if test 0 -ne $$exit; then \ + printf "%s%s\n" "$1" "$(ERROR_STRING)"; \ + printf "%s\n" "$$output"; \ + exit $$exit; \ +elif test -n "$$output"; then \ + printf "%s%s\n" "$1" "$(WARN_STRING)"; \ + printf "%s\n" "$$output"; \ +else \ + printf "%s%s\n" "$1" "$3"; \ +fi; +endef + +define test_output +@output=$$($1 2>&1); exit=$$?; \ +if test 0 -ne $$exit; then \ + printf "%s\n" "$(ERROR_STRING)" $$?; \ + printf "%s\n" $$output; \ + exit $$exit; \ +elif test -n "$$output"; then \ + printf "%s\n" "$(WARN_STRING)"; \ + printf "%s" $$output; \ +else \ + printf "%s\n" "$2"; \ +fi; +endef + +# Makefile Verbosity +ifeq ("$(origin VERBOSE)", "command line") +BUILD_VERBOSE = $(VERBOSE) +endif +ifeq ("$(origin V)", "command line") +BUILD_VERBOSE = $(V) +endif + +ifndef BUILD_VERBOSE +BUILD_VERBOSE = 0 +endif + +# R is reduced (default messages) - build verbose = 0 +# V is verbose messages - verbosity = 1 +# VV is super verbose - verbosity = 2 +ifeq ($(BUILD_VERBOSE), 0) +R = @echo +D = @ +VV = @ +endif +ifeq ($(BUILD_VERBOSE), 1) +R = @echo +D = +VV = @ +endif +ifeq ($(BUILD_VERBOSE), 2) +R = +D = +VV = +endif + +INCLUDE=$(foreach dir,$(INCDIR) $(EXTRA_INCDIR),-iquote"$(dir)") + +ASMSRC=$(foreach asmext,$(ASMEXTS),$(call rwildcard, $(SRCDIR),*.$(asmext), $1)) +ASMOBJ=$(addprefix $(BINDIR)/,$(patsubst $(SRCDIR)/%,%.o,$(call ASMSRC,$1))) +CSRC=$(foreach cext,$(CEXTS),$(call rwildcard, $(SRCDIR),*.$(cext), $1)) +COBJ=$(addprefix $(BINDIR)/,$(patsubst $(SRCDIR)/%,%.o,$(call CSRC, $1))) +CXXSRC=$(foreach cxxext,$(CXXEXTS),$(call rwildcard, $(SRCDIR),*.$(cxxext), $1)) +CXXOBJ=$(addprefix $(BINDIR)/,$(patsubst $(SRCDIR)/%,%.o,$(call CXXSRC,$1))) + +GETALLOBJ=$(sort $(call ASMOBJ,$1) $(call COBJ,$1) $(call CXXOBJ,$1)) + +ARCHIVE_TEXT_LIST=$(subst $(SPACE),$(COMMA),$(notdir $(basename $(LIBRARIES)))) + +LDTIMEOBJ:=$(BINDIR)/_pros_ld_timestamp.o + +MONOLITH_BIN:=$(BINDIR)/monolith.bin +MONOLITH_ELF:=$(basename $(MONOLITH_BIN)).elf + +HOT_BIN:=$(BINDIR)/hot.package.bin +HOT_ELF:=$(basename $(HOT_BIN)).elf +COLD_BIN:=$(BINDIR)/cold.package.bin +COLD_ELF:=$(basename $(COLD_BIN)).elf + +# Check if USE_PACKAGE is defined to check for migration steps from purduesigbots/pros#87 +ifndef USE_PACKAGE +$(error Your Makefile must be migrated! Visit https://pros.cs.purdue.edu/v5/releases/kernel3.1.6.html to learn how) +endif + +DEFAULT_BIN=$(MONOLITH_BIN) +ifeq ($(USE_PACKAGE),1) +DEFAULT_BIN=$(HOT_BIN) +endif + +-include $(wildcard $(FWDIR)/*.mk) + +.PHONY: all clean quick + +quick: $(DEFAULT_BIN) + +all: clean $(DEFAULT_BIN) + +clean:: + @echo Cleaning project + -$Drm -rf $(BINDIR) + -$Drm -rf $(DEPDIR) + +ifeq ($(IS_LIBRARY),1) +ifeq ($(LIBNAME),libbest) +$(error "You should rename your library! libbest is the default library name and should be changed") +endif + +LIBAR=$(BINDIR)/$(LIBNAME).a +TEMPLATE_DIR=$(ROOT)/template + +clean-template: + @echo Cleaning $(TEMPLATE_DIR) + -$Drm -rf $(TEMPLATE_DIR) + +$(LIBAR): $(call GETALLOBJ,$(EXCLUDE_SRC_FROM_LIB)) $(EXTRA_LIB_DEPS) + -$Dmkdir $(BINDIR) + -$Drm -f $@ + $(call test_output_2,Creating $@ ,$(AR) rcs $@ $^, $(DONE_STRING)) + +.PHONY: library +library: $(LIBAR) + +.PHONY: template +template:: clean-template $(LIBAR) + $Dpros c create-template . $(LIBNAME) $(VERSION) $(foreach file,$(TEMPLATE_FILES) $(LIBAR),--system "$(file)") --target v5 $(CREATE_TEMPLATE_FLAGS) +endif + +# if project is a library source, compile the archive and link output.elf against the archive rather than source objects +ifeq ($(IS_LIBRARY),1) +ELF_DEPS+=$(filter-out $(call GETALLOBJ,$(EXCLUDE_SRC_FROM_LIB)), $(call GETALLOBJ,$(EXCLUDE_SRCDIRS))) +LIBRARIES+=$(LIBAR) +else +ELF_DEPS+=$(call GETALLOBJ,$(EXCLUDE_SRCDIRS)) +endif + +$(MONOLITH_BIN): $(MONOLITH_ELF) $(BINDIR) + $(call test_output_2,Creating $@ for $(DEVICE) ,$(OBJCOPY) $< -O binary -R .hot_init $@,$(DONE_STRING)) + +$(MONOLITH_ELF): $(ELF_DEPS) $(LIBRARIES) + $(call _pros_ld_timestamp) + $(call test_output_2,Linking project with $(ARCHIVE_TEXT_LIST) ,$(LD) $(LDFLAGS) $(ELF_DEPS) $(LDTIMEOBJ) $(call wlprefix,-T$(FWDIR)/v5.ld $(LNK_FLAGS)) -o $@,$(OK_STRING)) + @echo Section sizes: + -$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT) + +$(COLD_BIN): $(COLD_ELF) + $(call test_output_2,Creating cold package binary for $(DEVICE) ,$(OBJCOPY) $< -O binary -R .hot_init $@,$(DONE_STRING)) + +$(COLD_ELF): $(COLD_LIBRARIES) + $(VV)mkdir -p $(dir $@) + $(call test_output_2,Creating cold package with $(ARCHIVE_TEXT_LIST) ,$(LD) $(LDFLAGS) $(call wlprefix,--gc-keep-exported --whole-archive $^ -lstdc++ --no-whole-archive) $(call wlprefix,-T$(FWDIR)/v5.ld $(LNK_FLAGS) -o $@),$(OK_STRING)) + $(call test_output_2,Stripping cold package ,$(OBJCOPY) --strip-symbol=install_hot_table --strip-symbol=__libc_init_array --strip-symbol=_PROS_COMPILE_DIRECTORY --strip-symbol=_PROS_COMPILE_TIMESTAMP --strip-symbol=_PROS_COMPILE_TIMESTAMP_INT $@ $@, $(DONE_STRING)) + @echo Section sizes: + -$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT) + +$(HOT_BIN): $(HOT_ELF) $(COLD_BIN) + $(call test_output_2,Creating $@ for $(DEVICE) ,$(OBJCOPY) $< -O binary $@,$(DONE_STRING)) + +$(HOT_ELF): $(COLD_ELF) $(ELF_DEPS) + $(call _pros_ld_timestamp) + $(call test_output_2,Linking hot project with $(COLD_ELF) and $(ARCHIVE_TEXT_LIST) ,$(LD) -nostartfiles $(LDFLAGS) $(call wlprefix,-R $<) $(filter-out $<,$^) $(LDTIMEOBJ) $(LIBRARIES) $(call wlprefix,-T$(FWDIR)/v5-hot.ld $(LNK_FLAGS) -o $@),$(OK_STRING)) + @printf "%s\n" "Section sizes:" + -$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT) + +define asm_rule +$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 + $(VV)mkdir -p $$(dir $$@) + $$(call test_output_2,Compiled $$< ,$(AS) -c $(ASMFLAGS) -o $$@ $$<,$(OK_STRING)) +endef +$(foreach asmext,$(ASMEXTS),$(eval $(call asm_rule,$(asmext)))) + +define c_rule +$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 +$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 $(DEPDIR)/$(basename %).d + $(VV)mkdir -p $$(dir $$@) + $(MAKEDEPFOLDER) + $$(call test_output_2,Compiled $$< ,$(CC) -c $(INCLUDE) -iquote"$(INCDIR)/$$(dir $$*)" $(CFLAGS) $(EXTRA_CFLAGS) $(DEPFLAGS) -o $$@ $$<,$(OK_STRING)) + $(RENAMEDEPENDENCYFILE) +endef +$(foreach cext,$(CEXTS),$(eval $(call c_rule,$(cext)))) + +define cxx_rule +$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 +$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 $(DEPDIR)/$(basename %).d + $(VV)mkdir -p $$(dir $$@) + $(MAKEDEPFOLDER) + $$(call test_output_2,Compiled $$< ,$(CXX) -c $(INCLUDE) -iquote"$(INCDIR)/$$(dir $$*)" $(CXXFLAGS) $(EXTRA_CXXFLAGS) $(DEPFLAGS) -o $$@ $$<,$(OK_STRING)) + $(RENAMEDEPENDENCYFILE) +endef +$(foreach cxxext,$(CXXEXTS),$(eval $(call cxx_rule,$(cxxext)))) + +define _pros_ld_timestamp +$(VV)mkdir -p $(dir $(LDTIMEOBJ)) +@# Pipe a line of code defining _PROS_COMPILE_TOOLSTAMP and _PROS_COMPILE_DIRECTORY into GCC, +@# which allows compilation from stdin. We define _PROS_COMPILE_DIRECTORY using a command line-defined macro +@# which is the pwd | tail bit, which will truncate the path to the last 23 characters +@# +@# const int _PROS_COMPILE_TIMESTAMP_INT = $(( $(date +%s) - $(date +%z) * 3600 )) +@# char const * const _PROS_COMPILE_TIEMSTAMP = __DATE__ " " __TIME__ +@# char const * const _PROS_COMPILE_DIRECTORY = "$(shell pwd | tail -c23)"; +@# +@# The shell command $$(($$(date +%s)+($$(date +%-z)/100*3600))) fetches the current +@# unix timestamp, and then adds the UTC timezone offset to account for time zones. + +$(call test_output_2,Adding timestamp ,echo 'const int _PROS_COMPILE_TIMESTAMP_INT = $(shell echo $$(($$(date +%s)+($$(date +%-z)/100*3600)))); char const * const _PROS_COMPILE_TIMESTAMP = __DATE__ " " __TIME__; char const * const _PROS_COMPILE_DIRECTORY = "$(wildcard $(shell pwd | tail -c23))";' | $(CC) -c -x c $(CFLAGS) $(EXTRA_CFLAGS) -o $(LDTIMEOBJ) -,$(OK_STRING)) +endef + +# these rules are for build-compile-commands, which just print out sysroot information +cc-sysroot: + @echo | $(CC) -c -x c $(CFLAGS) $(EXTRA_CFLAGS) --verbose -o /dev/null - +cxx-sysroot: + @echo | $(CXX) -c -x c++ $(CXXFLAGS) $(EXTRA_CXXFLAGS) --verbose -o /dev/null - + +$(DEPDIR)/%.d: ; +.PRECIOUS: $(DEPDIR)/%.d + +include $(wildcard $(patsubst $(SRCDIR)/%,$(DEPDIR)/%.d,$(CSRC) $(CXXSRC))) \ No newline at end of file diff --git a/test/firmware/libc.a b/test/firmware/libc.a new file mode 100644 index 0000000000000000000000000000000000000000..8c5d072863e9558cc6ff573a4729169196a405f4 GIT binary patch literal 1200014 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 iq$PmtKZQ2R*Ky=;XL@Hl z7ICP396QI6zBqFHtB&EZ&FuoV2VmknZcPdMAK1R)cjLTozb?m28%|8EEey(1O-2}W zF~4?@rfH+JE66+G*bau;ADZz7Xz-D)2d@zyM+|{FZ>F)2@Ndr_=Oop<&*RYi$Ja(+(H)U3?r-GvQIb_{N;fR3vAdQ*C$-Y z3IS&2%zZ+f2Y8~n=4q3jHDA*H`}_0;m=?u4`-Gzi{1WmIGt=q4)P-(x7ADOJXg5xL z)Jk5@ujep53{EZAjVr^O{m9!MBU2KzYM5P!97UQ8le~!+Y2U5GnQCj8r}rh3jqAwSCc9-nJ{kH@jTcgjlnWAB)W2Ngf|8N+o{{@BNkxXXX+ zGhfkRLp65T_%-xXZ3=jhm(1N`IvL~VGP0@uVO|cm!TRBrRO^SIuf!f|-{xQgJ%YINg`*FRDY{@F zOusGt7bMCbwZxHB2O-^qcUgx+%8oAO!jtAPjLH8rzmj2HG1aSI&%6U=kbLne~H923zl?!%rD(U5VFSl;)sYlRw1Mp@Dc< zwR5aI-nwKs3aNjpfquAU1@Y*0ZHa;I<9rBZ(S|d5ukXXFmtg+f&xHdQv#}b~$EFGm zZ!@9M{O!@&hw;7MU_x!9`P76l?9YDF>hyZxAzIj|MM(-)6I__@XE~J&cv<0 zq%DsNZT0x?n^XNy8)zQ_XP8Vrd74ixAw@IsIQ4DF-F~<>OL?8r=GPYq%Y_r0Y`g^R zFX%2AMnW9ee*VSXW%l&LjVZ*<5Aypd1JCu6fyW{491r3N_hv%MdAbIX$@;=0C zp|l*gQwGnVnxf`o6Ak^GxG)kj#V@#op3}F@n0}@^KX=}vDDcG<*Dk_)N$y-sIosUS zI<)A6BcQWy>EQ&>I!H#1Q+pS;2eQdN74FgG01JyR$%JCkTs&4pNW79?) zp7k$km~7xi)E+(yeZeihFSik^x;ATa)<6fs7%S<01KcBb5&h%16ITdL-=Y4efFe8y zulMV%rY{@Gd>v;3W8+x{d1R#g#Taj4rSDUhIZxZc_q`Z{Uoxa<$1%Mbny?Q<1$_EooXAjd9%l`5W)Y-Z%mD?6#J5Hk}w z5So$R39VRlVx5U&TAlEW=HhL#XC15yQT^u$u@(vxT5YVJbJ;MKPwr5h%LY%rKv?5@ zs^PMM&mSVdRVvh-52Yf!iOQz6e(kmtmF8Z=@e*{rsGBb2P6`lOLr7|bwk@tj;-PQ) zE^OjX9x9|KEt=i$b7c|b)p7a8u?a%gA_1exT3B>sl9uCf+2FvNWZ>2=n*Gfcs+Kc@ z;}!f_tziJ4!=u`Npw@$_7c)W_Ba{fep@&DRFdSCHM_uJkc51fSBM{nDBFAPs@%%^A z1nB(|ch(2ud7&9~xkFe{6Xq0?wu##5&_^D^tO(j3QWouLrE0le@52436Pq|*?#*Ku zznIwcyw(gWbraBU6a5LJ6GLa;VrhduA(wcbg?bD9JKH)@8v}W+pA$8@?`L#17XEUJ5){7_X zFSLWb3r>Oo4IEd~+2ld)m^(0(UG*AL9H`~c<{|WbOQ2tUQtR}(i_rU6f5W9A3bKZ4YKTKT7oMj}4e_8mA*oJy?XI)^wYx)y zeb`~6w%RuL$KH0O21!e)A*8X?5Kc-B()vQ65u)T@JbC~z+Xzvb=b&C4H1Y1@OYIPmVxfb`fGOwfbWBb(be1+ z=0dN7zSn45YM7H`BP=!e!PTkgYC&MBK|mnXf>MJIVjlN}QiCs=z}DYvGn=uo1{)zc z&DaEh&vVfX?&cxpl^W)oT`e@bTEw_2HHZj(k4LWEb%N0J8)ox@0K#I@KM}M%>r`r( z0j_89OAUOpOK-Ew3FHLh+a$yScw9>jlS!#ziqpFtHu6%#RKz~;xRn~Ffu8BSlN~mS zQo~HdzVNu08lD5)&-3YfeCpa=2MB@VFjpaG8-4E-fgTU^#N6TrJF1~423qE*q5lQ= zX*Kk@6wur9F$iV_LAy!Zi)IJh>6ZX@3(-CStbw~ znhn}i$nUhbsU5){&CF)^7>T}9))O91%ufbWo z^SXcsIG_5@zxlZLMU4 zH;<{wJGBVAwD4-3{c;|RI3T!x(Ql^=B$%@nU)}`21 za{8V>@%^!EjLzJLaOg{zzKy_*xMJ#{j~GHu&4gD?p%k?LsPnI`f2fq58bs1sb>w|X!Ci8exxH}-0{?mPugs8kSl*7rAc*xPl}!ZoS=cW7-N+5C_` z{9}R5BikSR{5i93C{NwCPpVU(w17!FCCHF_JZOW@Hpu0ymMR_RX~#qNG`)^>r46SR zQirKCOLdzJPC=(T1Xfs|j)azfQV_QOCfB5WyY7^nja$InMtCR%%eipd)}7^c@$B3= zPjNk>d!HZ6>>6)dxzkCVY0ISCFwLB=8DF6-7|ED0cLX+lad$GL=oCy* zJp0as;ETJH>}_4IL&z@r?2uu~LJW?<)b6JtuBJYsgR9Psi5rXbb#3*zf1LxaeAoLr zH&po24LfD>ENv}lq95j^ zG=A6DsV+tdxk>ij4qJ=|4u8A={dJGY_qG1qRDv=0Esf$SZp2K3)_Je*%!b)_C@$nC z_c1~)mbW?Jq9NeUyS?;;qc_bF>V!>)U@oi<#w&frOiM~!_q5q@ZQJY!tS0Eu4|XiW zsa48PK^XV9dJ5mc9wndAx)yc}32kAdhjmc(oJ+UuCO8T5eUCS|$2tp~U>_64hvhyX zXP{ZYxr~L5^ac*>rkU$VcU$w*K-A6YzDLO4aW|K{k=Z1)5OxYVl2fPOJ9G9!(|QxD zb1E3jXRf;KlQ_=so%5{=tP1Hh)LPuLiE~ga@W8;jvkYS#!*|N3O*@XdtvA*|7=Lru z?QBQSH0G|`?rWH@F|v=HPn^q@Ftdqp6|QMc(S;2Z;Q3wQ64}8%BQo2*+jn6c`a3fF zmF6(^Fe_>4UeM)!5o?cgOPv7oE{~n(^mjbVr6?{FChj*3!nkGODj0knc?GtGHfyZc zS{2djsA7mye@D+%c8)yX4?pO-<5%s->z+n%RHieo|Elw+IERL%7vq-;vtT%9)dlSA znTdn*sknyP1=ij6O?J)dnIs;!2MV`VpnsU}xv&QZ^~sRI03?zHJZ=vZ)EA6g0p>ENN4i`*ZcmfHSsu#|mpPqpDc`q8eD>|! zb5zHCe_!VNt2@6RX92r_0^9EC(Vsa_hvHbyxII#Xg1w>L{D6nJx`2W|Ja?BLLh#HR$_wD(GJk*ugBd8;3DRAD7!%@K)~p2P zhAyDsuZP{`VS|nZP_WwG-QF}|$%;^f#~K+7KOG=>794b2+=JHlpz&-T3n;&XB>*G6 zs|SsHomoKpeJlYO=_5U8+&jSn+MiY(LLyKJ?I%dXx|?6q8{|(9&}_6I=%;udrnxu@UQMc7Xpnete5*i ze%aK+en$^_k69k;;(oYWgPA#3GDsR7h08qbLDT5CG}v4huS%7hY*R84KrTuJTk#Sz zOf1u;EqPpAqEecoQm2>&Rm)8Vxl*Z0F*B3WQcX;?%4{%i)?zpA#igiJv1Dbk7B=Ha zr64X%lB?0ENQ;(6C#zIM$#?`DP=Q>u)2gMgkq@sC2P#^d5QVHHxi*<4fwB!UJEcO&?yYAshR>`Bl(zN!)EPa8#6!;cX0JRBlJYSlU zDo=&OwbE$T0DeWw)8bMYr63xYsGa~wtI(##%acev`$eksBsqlLbcMTAnvxW!?Fw~# z;tGrh{CtxhNIMsJ?4UtMjAv|lfbop&x5$SDnqLu5f&Gb)-geIt@;qXY7n(8d@3(_S z1M`6$>?a(980;O)eB3i;2bKR^GZrBRxl}Wa^@iPa(>^hj+k!N>-)+YAW{mBr-2lvM zfI$v|NbF{q!w*<&mWwdU$;@;#;+ceqFuZ_6&EdxUZ}%Mhg~n`OV8-tvhRWv>;#q{; zH1i!%USK}E>jU@SAni-Y5;N8#2L7vv{Y?8f@jJjv=6gm09`0(oYYF)nZ%FgZ_Dnnh z-^I*l;uF40Xts|)JlnKib38Cpf#w6=iu^f*L{p~pivf)3mj&1kBE1;#Q22ue;(73& zAH?%vA17eca|tl&X+i!1IOB{M!tpC&h#Z;*4DoG?7{d)1-3$KRMGX9@h(T^XVhFziF@(DaaUg*| zQhG^=$;1AYbRF_0ce13rxO(-03x1AY_fk%YX1G~kO!L$iqM*L=XA zBMse#e;^I`KGN`A-y;q9SHKt_w%|A7;egTJ4KUh^kPqL#)QmF`gIt~&>k-5Ey<(TnI4Df4*4S(G3eQZ7~#1cY|A_o5(5kvZ|0X!TE38)}k z$ZXDt@mtLFB*gYmjhpE>#IPS&XQm4f_k;K~(=Q<&Xz~a39Y-3JUNYNXMm!8&P#(}8 z+fObu6I0DJmLIO0sXU^61kxUG&xqMR3$Z7pubJM8*bDNlnZAS=BEf+R7~DG{#*g_! z`-|Cq08CX4t=70?(`osxChNC*j=Stk8wdVB_TB|Ps_NPwKaZKoWHN?<1Px(;NhV-O zB1|425Lzaa;ebHpAzH)-0|7gcs7Sz4A9X@dgRh2!+9U%u3brT+Nr0BuZBj*Recg$V z79_N(A`#-fzX?Q`g1_eXUFV!Vb27#fz248|_W$27+0V1~Ywfky-h1t}WkCWNfIP9u z^1ezKo8mMURy&QaRXUbBcI zDWRP<N560SaN|r5M8hEY(exPIXgQEPhVae+W2kgxiiErJ*1BF=fc`fQqv5 z;ICP6%6};xX=>TwqW zwD7(JJp7m8Q8=r|BXDcs(fFdV%?yKAh5#+R#370dH;hM_wA!_#Za6QaY568J6!-B+|Ca4&>X8 zL{twOeykp=kxo?DKZJt61JZ##4;z*j*_v#)JxDhP^L!e@iN+B;>PN~G@WMuiPTk9Z zAe1=?x3%e>L}Soeks0R1-TjFUTf|&SrhZ&5dqn5b@>7*mV2w<@6+KLM_v@ti;>Y98iL-UCS*@iN zlcbd54-q%SJzYLAamqLOb1V4N*C0V6WZGIk#MwszWL6+|Vt*}U%l>OeZbhmjc5#J# z{`gRWMLC_B-pE6?AOy;a z3vuBUYlcEpACf7f-!a`N7P#b}AE*=${C)#tw4 zr0aB<^<8{?8q&YmStyS5rG=i<8S}36sCr;vykl>*2^zupjFMRttj(2VBPHPf&hK{X*%b&N$PE3y)vW;aq{rkW%s6&bS!9 zOW^n}-pqIDd0*4))3XFTM2Z?%>tE_D;B7vkOAt^COG*V&@@b)g_0Cq&zGYtKLrSSQ zn=I|~Gx4F1+$4v>Lk>k-(px%G-3MLUAVFLsHHCzRx+cB~cMakIso^>)@xl|b%#$eB zm9Mi`Y;ZRx^SP*}?RiLLqup$3`!)PTKJQR+qgGD~2|m`AT>;^tqsZSCmhSxkYbC!C*2d|rYEtRzVUT}$l(I^MGcQ41if&AS?(2-G2XFp^wu(osvlMc9^Z04@! zul_k?N@z@9DYb?y4TrrWB$GcMEwMFuYtt6j^UYUCWw;lTUO(ca-1hv?m0Vn>WLO}N z*9=L7%zEL$#)_+D|4W@ZlU_>S9RM5&Hx|rJlmB2ykRfey#k8%krb6x`KVO3Pj6(hfD+R3GxQ!5>yw)BJ=~qg5sbzFeW*>NlKUYgmmqDAl>!5E^$D7 z>!B`Tz_37G$l9*!oMrqS#^!*)zL3yPE>r6sH)1T*Dv&XPR1jw)$wc~Qq9=5;y@Grb zJ!h5nDCBd@==&Pz2hR=-a`2f~wNk!fJ74?+WTq^wjmVX-AYC$d8g$vAL>V&4!~BOV z(dKA3RS21512&1xXgKhxFpD^s_1QKRgT zV5KrDRO%?GltK@OR^;vnl}aIM#pi%hrBL}pu;&J zO5##$r7I<)U(rX7TshvcBk+m$pzG?^l;RwTsPJ`iAHtPQr3-YRM4+b~-W-%CRmLTP zx*_nZ&R9cp({Gw`q(61YR1+tM+fFv4b z536SOP{w(Fc!sz(+#YiZI90E_QvxRniQk7dOn6^woy#kbSL8+(dm>Xk8Q# z(5lvfO3C#v`s92;#p~+JxOAzt-XqomMqGlwW~#Y44)>XcJoIYFSYHt2`5~)^7QYv= zRPF|bnL$C#ptTiEVrM}-(Pzk2){C7^gYKC@&wf87d~Od}J-TOicIo2n7Ziow_YHygJE;0oUWJN3(gjfRrX~2%1g`NH^?yhI7gP^9V^rdX!E4D z(&)oT`T_J|XyK7A!#>-^9Y0-Iq5!;H&uD2Kh~jgE19V2Kt+&D{BSJNFM%z1{t$36K zq*twXJX@)-cvDooiGh}F(i_qHdvjELd{jIZG8#jAA9{apk?+t_{ix3cnd^^yKzbp1 zrymrFgiFLuVek0FsCe4Jju;WEO>EDF4YBNwuuoZYTpQ)b_IlV*`s>0zCH-9Zsr)qd z2BH0LkBX-~4T`5RMtUahkBWa>ji>Q72qy-$QStR^JdLYCX#YmlPiGsXSAy331fRyh zApCn<^%KqyLi-$npBXB@axR5)Bb+2b-&N5)B_+#>RxOebm2e)${G>2KK8I3IZE*gh zp3FqfqZAz!%DGhW-KEP`()kchnHJr1-yJw~QqHq*W)(jBB7oY+UPoBr6Dv71a+0OM z4 zp7wRgru`}kCt6G2JIS_Ve_pj;S8du?Ghu(&MK;o{Q~lFb|9I8*srDh&{)lW0)pKMc zKe`W2-%lnR<&*1y`pEgCJ~JrY)#yq!y_^ry|BC!bA5S)hf=#sv$4wdPInpR)Z-L-j z34V&Y-;NCq+KZw6_Q_)DI<`F3 zAJ797Rxvhsh~_fG;1wc33$G3E(h)}R=vxNwcDS|hlCXgkL>My+-a-Uu;pu?iHiQv8 zDi?#d8g4B-I*Z(jFlHFMdl8_8mj-w=?g$=+Rv6yXaBJc10DuyNF~i_JjsPvZ$$&@Y zB6t{@VR$dXt%a9_aXy^_RKwuC0KXQV8}KF|jNri;hSvhO7M=%<+kh};7(AkJT6hlv z2Gs6Tt9NkEbY zK{=ymd&ty|lqcYY%^T?a6JcMZ>;n;|O;-X2GeuJm<{X=wm(8>l(~jw-_Db#5s(Q9q|)ccf+3;xPS_uIIu4@mo^TViLQE;I&0 zhq9lbm1Gsksc-WILM;Whhr}4J>vtaA>Yr&?Ks^tuj9KDzD}%;k1YN$P>>N0PZ2ig_O2_BdJTr0~#XSc6Ly8C$CzdX#N44U-fW_>b|mdd$OLSa)$Yu2R`W;L;!NF5YE(i147ZL%%7d_=OH^ zo}uSbI_jjhlPSfUJCyqxH)8L_vIi|vde|!z<7PvCikqKkIW(}qFnV9JA*CgBXdua> z)4f~TS0j8|+rVW_3E-R6J6!pJO6gVpxxZN(=qt9R}4?=qQVO z7LF)=n1%5+!7YorBaX_$Oa>g6>v~*UPGxprr6#&+=v9vhx1yvWndsi%D}<0iAerah z@kG@lhV(va4Xwx7{s8qE>9nAEh8da{(wGM}`J>mr)1uFQY`*eu;#xV8EEkT2m0KN_55{o(gxROt%!c$Scbh7{Iqi{`I#Yldb!SVgnQJlR7To!CRv||(J6Al;Q+#@h#_6cw9bhb#Xm9} zpuiiY@rRvo&>X2XG$*n-jdB_Y_{yAf2VQ~0q(k#ho+`>u;_ey|bb=!QU!&>%H=^TV z(Mh~KMdFaOy)-5&qwkJ9%W^@~_9(V&zK-suAePdxG5mGu`b(dQhDGOFk1%FfFVo(j zHs256XK|F4xrt_L>DmH}VWQha)6j!*I`T9645w_4;IB<_%6}QWX!`5{JfdR+PfMSd zz^|o~A^7`4CmmEN{Aim0XLQnme6{loeMTmlPOd<@l}eQSm!$)p9QRG=bI3l!gP|}58=~ej`DUc^%joLsc~IAVu2nfE>-^fl{J8tJ|&~nmot5eG%dprC4}gY z*06hs)HGBl`MnRBXQk^YjA@mxswi{<$VBr#@rU1>PNhX`pHTt5nmLK?l#noMjPDJE<;yY@`Ky)Pi6)eLTxgJGM<*|g zb{mIK*?51Q^%>XjV_nJV!-R>*TSy^U4ma0Xz`b9g%W1;Cg$QlET&Awm4Bb^v|6_fV zwYgM!Qc4X8lPg`RA>G@jTQe*6bjW!W0A_P=Zy=PoxV+&tukn}M*rev)boES`A28#E zq~9-x*3Z`WO}wqf37rX(7rVL4m94LwH3>vB$uej>apPxO2CXMc zq4mV0YDbClbYi!LdSIZN%QzgEW92qbjxn7+j;j?*hPV%abKE|{c5!W@y z7dq5h?G>*!?x&nx8(hZ&Hi>kn6s>s9n!3UfGURieg$ms}`9;3N9rU_MBqzR(@+y<1cu2z>?Jn&GuNr_}wkKSpj$8H$QVU*C!J93ze9Q4u z0<@|Ko#nd2p$U9VqW~j|=#Ar2RzjbQ zrKIF+3=cg#v!F{R1$I`+*{cemMhKOoEPCWp}X9>JB^x%;s$KTXnSSS(feQ#+(eSu<~-hK+goUsZd+BbsWZ5lS76~ zGo(*V71X$oSUqOG&eA#X0TCGgh{5iiH^ws%hP%-mm@1kBf*wOo&&pM(@vN7CiCp*xl(6!OxeH?E9jgYa`v)kC! zGf~#Om!g+upDrH4=f-yN257m-HU>u+f5YX-=|1*u8`6_fHI&MLd~<=77mR18hDJLw zy|ToqN7p$`y#CrPp~Lm=(A9I$HjnYPi@=fT1vgBeWShNumF=E8Y`CMj@(#SpY@^Mb z(lIvMb$1ux&S>c}Ilxw0eE%}y%TUhQI;n7ZeDNa<10>Qy64RPn5tBLl^bNu@%{sfQ zsIZ7pi;;JJ;!Q2qbv_dBxl_zJ#_{=o3AruK3&I5+H50KDEL2~2LHK*?)Rr?`8FUM- znJXDPA2*(r_@6HzOo48#Q@-_6X;=Oe@8eVPVp{6#)32J7niC|_ehm#nzM`q6ZKUB( zXt(7SO}(pauveF}7j)u$U^_5{-%PlzYv*$yr)#!l2!Wxe%>&N2Cb$tEFLsSEi@_0s z^|akQp?QiFHmW%jP;AFF0X;?0t{pFABL!?yPogg}iD{&JsM=l=kxAlIjt_wo7c^;4VAt=z?L z{)==BEjh!wc*(mVw~f1INo&&=+&%l6E2X$&{7AI8IC2S{87y3i7I*OZNacX8q&n(@ zI@j$1!9V--Yoqy*F6m~g*kuzJKn9Nwj^J+@_>^-_$Zi>3=)~U{?w>c+cMO&QkI#@| zOK!o-+ElOVgIL zWo|vjrBd1i>1yoKi}IKhYiUn^z^*@oQZB<9`7%xh zO9ZKQDSd^Qi8n8O8e@R)*#~*r@`fv*jeS%FSM{g;h3$EvE1~nQ@Cdj0qma&$7rLqv zIwc!)+0d-5&kLC?FG4H*<31X3dTGLLUGb=j>vum_@nb6otu^B4*{7$)J0-{@n$6H{ zH$?jL5n)VXGmhjiBc>b#>`Kzk9th|#ug6Il(9Abpm3k#9_diE8LjG(EZWY8G#l~$N zKOQA<%<~!{>3yXo!Tp5mnxmstoqlw(b0WYMm&>We3Z%}R=XC&|=o@1$r7k(jL7p@v ztOfAxR=Yf>+gH<^&*#!C?}XM@P>0#5S2O2NFCOB(LB>}mxsH?^G%H$o2U2rBf#Xy^g(CKn}gU;gz$8?Fo$>^n?v9Ajo3A0sz@Yp6XOy<)-BgE0tyn&mXw}w(3_R~6X7Hn!O2XPtAHgyKz z{p+N56{k3RqV$V~WZV(aRqADIH&zloYbwJ_YBk9!M{ysE+x0Y^7P2>i%KtY$?0K*d-WEU4rQ?Xsaxk zI_CJ63SEtux%lXwkWdL3WBspjH${W1BSP zP$~=2GT2xy7;EDmBE6Mys}p29Vf9rq#dz0EIU^_H0sjtL#)T~viz{$bM2vHf3MD%X zoioHODEqG~Dm#v!GUiZT@8d?s0WACrhC}b^#RXH}IXYi5)DA~$;B>5d3#7bBW|+^v zV#7PQiQ#WDR|%QUGcWk!Kmpb_94A*>|*b6l_vr_+|odC;$E**;w!9r+K%bqR4q z%kx*$Z4z6>f~ixFB405>@+0SjIpQ@xJgNhqMH)1P$)InhlSu?&OQ+sgG~}I-+h>tE z2))1DwXZeCUt1xLjy+0J%#e20l;xVEhFYa82H?_sNVw0FVyd&DkKeMLN@%E~l293# z%rli`|B*PqxsJ|N^LEAId%esD>g%#Pw6*Ye#NcHNsue*x+7bKgf~g-L-GY^Xze&iP za_*L0gSHFRdjBNgx}o;0m#fZI+r_s(!EdNu-Z)RGJ>`@ZtwB=65V{7rV;?|7lp$zf!3H-Jiwsu0G5 zD$J4Vg_b`ah^yTPU8}lcQ&mBua>f@fdvct4lc2y4SF#TfpNy_c@ljgbu zCuM~b3uN<^y;~dj8D?g|Q4pUP(Xxe;%*FAEy<|z-kmjrBou%?|=L%@{diRY#y#5-F zNz)im*psm4jD{;*Z;DSWi0hS()}>PweOQI@Nw=BsFkc+>V--MK*t^=jDUz#;Dg!ik z2{YK4t4)(P?Nvc8J6hM3e3r(Ny^B4qKF@{S@e_pK$S1zck8!f0Uob3^UZ4>zM~O`Jcv*%0sk*}D*l8TPc(yGh5S4!{_jzKk|}0}$~PE(3Zi-sLVu5piqBQ! ziAD@Ue>SVy_qy4WvwIOmXST#bX?F=p?_~2Q^HxhNHU|-$e?eCo(u#Y?K@Bt^hpm7b8L@in@l6y;H+Pyn^^o}#-J zmoDe-T3)(p8I(S)zPqIO?&Vs|OH6rFlyH7TlwYeGDlE$1OT$JlZBWoY6(!2A6;|k_ z(n+h6Ly>(}WSr@YkYwoT+=}dVs(l3Z@R5qH3X*Z3Md6s#8ps}vJ$&>J*(A$JGVO^J zo~i0E8l|QOQKJ5*?<>h36Zt+!{;?d_4V!f5fK8Nj=X^=w4&VgAMSMDJil=-?w~m9t zvz0lT@}EI|Zo_ zB-_uBjm`VF$p&1~^+xdCBOCdiR^jDQ`H=2*vJo!J*dTp9`6nr|sPz5s$PfE8*&uqe zMA*o0DcMMuhU$k_^tDElXqZB%5NDW1wpcMLYF@ik{0#u$Q}kD-%7S8iXh16KJtNaMDdz7EIisH zfxQSwBv>=hwSi2R8q)#P`@YRr^#Jvb?{y798S+}-y~ngRMx&xlIscAOIyu?D;9Z4T zKnZ4asv`?_EPhVaZyv17iG)6shJHY0`HmRS3bVUne6VP~XNJL>iU2J9rg!4TGx3(TF zI9m=-fNB`LPvO_XvtoXjgD`3r;$SHq;nhX_wD2nN(K>`N!{D7qfEHc};8_qx@KDq+ zJjN@r`X-`Ni7#S?!K1qhT6hlvo)3u#9&yN&j><=KCY6tYsD~gC^(!+B9^o#fV`c}^ zwQB-cI=UaG&G$>>TaS+@-(>t)zSkig@?3!+**uB)VI1?oW}wN|bSHNh>4NxhIKu7t z5j<)q%9GUrPHqo6f$pX;!<^LD+H{-H7&o&>#4#t%j3;I@!8q8Ll#LtT|F>LsC2qSyVH(7ryuw{2pu2Z-3{Mz~df1-gOb=7ee$kF?h#|`s?dt)+kQf zpX4Tbz)Tt(kpF&~pBitQ30>!x>l!;wEimCM4@yRT9x)92ln`2D_l{?yg~c1A;t6WR zkjyrX;fNv188M`{T5CuzHPBqf9co{aS0VglhRTwTAK{h~Z{Wa|h7H9NPet+6AGC&a z!)8XVit#d6|t6#gLv$YB|z#Ni8s( z1_#Vn!qFHs1}U6clG4*yHi0n7JR%4;;S|Z=Q2FUTDb<&F#5~nMfoy8VZ^g5*dPW$W za6L6aYBk3!DJ>l%H_~^==z#r{`-kdJhU%p?jBcbLklc*Md|f&$bL2L^R62(WPn)lH zJX8OX$-+-dcekR$s886OO6jPNUHDP?7(6H3eZj+WpclMD8hG?AgLfm`T6nYICmdjg zm2WNrwB`Fi1CPqZ;1$75e%3B4R6i`)FnIUENBJ^C=_qezSh~9qpw0Jlr1#y!6*UA#WCU;@voe`V`yxZ$MqEd!o?XBUZFh0FVe#Zlw@K#scym;$n zJ7<$jdc-J5#{4u#_l{>2Nl8I^PkP4_Rfw3r?p4vaqwzv*PjfKMQOruPB=#be7xj<1yCja(sYW+;9J^S~xQt>u^@e`H!#WL6`yboh3avR%j~GtA8L zmZ3Uf!;7uSl4Ydyy_b+YLP=BnWMo16MYod;0#u^fgqL*pY7p6&yNNd$o2bm$4%kH7 zY3{z0YTXjf%@@ z{$7J7WQL83ECguhsUxB?f72MCH1wkp;Kq+|mW`Gja1;JA!{9j)poK?kCiY3Fak zSuMOb;3s@%hQXtGUJEY-c?CY25BBaie~O6x+V9`DU-!Wz_9xuJu}njgX#e zw0nnm)1`)KcDx$*e_G!^#g9yF)bC#IE!uyl$L>v%=hcxOdb^jqn*I*MTb&ENT*igg zI`5sHVN$Aho_C=q)m!DQ)1*HMNwM~?=seTno)3jBi0}QD)#bjPqy~;)rQ)NxNo!~> zB0M6z_Tfi!3(-_&2(P$R%K4B&=~a(H&E+vmZ_TelGO}fQ3%bha?YE<+ERXMQk#jlG zNFTMSYG~||iKdaCp+nf1rZn^;TI9ly`ihx7a5$I;HiH+v#tCWQX=&tae50j7C*bc7 z4YC4W1JV*bBf3NRvhr$a(A!8yZO;rVdo&F)f*veliD0vIph0=pev`F94pS3y>9xU= zQ8XwX)N}&g)^mEVkVsR)-+Su4mPX>PyL)WjZPRSfa5_Pjn&X;fO$yB`rV&5#b$s$D z#NnAe_Kw{gh=#mMV~xIHhWhk!r6W{M>IbR^-Ma)^r7;ZClpvxjz2m=1XEYxJ=S;o! z>IipeAC>Z>HX)vs=#Kp05eUyJoanAzS-MO<Wv3M&|hl__yNm!X=1sbKx@lYtpH7G!-+fx3dtSH53ZOLQYTUoA}5;zXla z8Q_%9WBW=+G+jH+EASDGLmK1Qst=Fz>)_Uo^G)#gXPke4boKaA9`yUValQ)q(q05J ztnAU_yao~4JrtG>{LOfE(Ik)GOP<9!a{8^;EG>$^p*0qb@}rH>+t7RvF%0{ZkbkyDqWbl{MpAZm z)HRZNT%+!V;hS{)zQgqqI}VaHKrCCb`bUs}gR~zvreNL=#w=d7YGv_~)vK0iCl;k@ zU;FoRS|7PJrDQ!r^g}z|cVGa~SZ8CC(vhF~hm9>bWgW5fEi(*W^!kY8uh=}U*$%1kn(Szt#Bqy zD+ed>x7JKaRQ=FRlaAYwqd8fJ4ao>Z(-#^$%n*O4;VW)8y(?c^D2SV;IOtnus6Q{) zwH4tl^)=Op)>hg%M44?6p&H^pddJfY7cqV5sG+qO!KXGDL^I+l8AEz6q~tJ#kL_#S z6|T>n#ai)ae9ua=LR4?i=E&d~Zso2~+W z>Jw&Ix_ks^=^O2bP?Hn=(DE}xj|d(!HE_&g9@q@tOt`i1EP!W27{SB#T$n$ib(xkw zIst!w=o{_-1dx{IQ5tiUFV&0kWIQ9B+~-KwpZy;P%2z@ksD{-M{1H3s?H7NPGd@>U z6MN}(ke3=bY7d(3)UK6kC4a+=(}GwDtzQ0^q-J4M+Ge5k$`MJ;{3y;YJY%SyeR{eW zTW!3^oi*X*B18H+r(#k~ouZ(ta-JzJn`YdC8+h>RV$zKlV}3n2ke(spFEz&2r zWvGjp(7Y6HtfV#n5OZ)DqnuTX^gLB%Lqt8!Ge^1;P(@yneb)7$T*wHN#wd_LNhnSbJUlngSWvLIGq&~4WQw!Urlt9v&j5YcYA4ia84COM;wMiXGa_qz1Q+FviQ|8mx zqLj8cugQZupaS|u?jat%qOZ!K*5K??hL@i(1m`DcgQ10xT{zc9d5lnF>3b!9rW*f6 z+hZLGl2OwpTfcRiB=x&Z9`3$x*HHQ1ty1c~%Jo{ut5Y97cl)jd(28+DKKmIbw;J7* z)%)?{myo_@$Qra*99nK@YcetNcjEuLocXDRJr88}W!^e@LHy%&v-n3I!<4ZQV zW0Vp+fG^b&JbjX|rRQAS&V`@>3hvy0O#G#Avc(835*N9P(6wlkyw9ijbB>A6JlLVM;{r`R z{Ks}nvp+2}K8wwH#wU|D4=crBZZH{o!R@ZAEge3T@u5NG@+5Bbq&3 zjrrlONO^vHO#jR4`&bJ*)cK37F<=h9=H6!|FTTnvH%c#G9u;C28pAjXC8)18GV!Q1 zZ&ST#jcikr%70~^XG!VOMfaB8vvSp^jgcZ#Y>78tu9_#d>_6#0ARFc zmhTe5J_N>s{3MG>wuNjk95&UTh;K-ygZ3jR%{Ss#!%s{1F4Mol-W%a0^^2BQB{^4S zSkDqqtK}K#egJ(-VU&h`#4=6CkKi%06tLXP1DnC4FfF_w;1M2B7-i4k-3Ygq2c`FV z`@@5_BV7Z&1uBHg$lz;v&`RVx25FdKWshECQ{|SiM6g-9v3Pg&o9xl$jO)J~g!^lF z&@ymZ{)X$ogI23NC|&?H9S>FdbgfNYI#Uwq)rVdUJvh;s;6&rViN=DzP&m<8l@l!~ zn+i@ePJ|zvXxv5p&l6Nm)L1zRoamQjF6i|UYW7WYVQ$EVlwr%6kIVLf-p)NvIwx*! zJqivY1MgUJwoLG#qoA{57&uU&I#YVVweY9_ZCOwW=QGr8OMV`DG0O1vC*B$y?F?3e zx62z^1>P=B!`ls8tMk{p@|ppMcsu=sW*vCMwB{dxw5NJWuS<%DxNdqwl}BAMhw5H% zO*}&1+2q_3j&-+kV?G0~H#{&`N(HwUXErK4a~w2rg?Z-Vn6X6vO;Qy&+dEoQy_wz& z&uwnIhqn_X`-J^m*{6aXJ^~OQpo%O|JoOdW{uawyx7)o)Z|jrVf2;0#^cl z1|>Fu%kOTR1>RHuZ+ffDo4zFJW$yG-a8tyc>KS)h`T9vd!`ghCJ5?GQu&6v1tr$+p zJl50TOmA~P-2M4Z>X9F}8fr7V#FO6a&P3gBa~n1Y)yGew?tH4WRZ7Az|NCK^b_z45SN6Y|MK=b$)ZBK>yQKcQWf9rM_)US59|DTlQt&ZEl zA1&YIz)IppnR}XWQo+FAVq6HFaeOuSMhmT{-Xc!4BAHA7qV0i>JChIK{ZeP}ecyF% zVFUC_wO=QRmEbd5jB9{HZy|l$&Q8#v^ltDic|*mT-lJ(s_su(Xwd<2J-0^FM5f8f@ zU)}OyGI!0nwwWhsO!S-^wlgw9dd}UmQ`nqvQsJpvj4lZ@};YW|eQGmY+iaGb;y;s%h9{M4qe?TobP z)1T^UslBj@hC0Hit&#=!WCcC}S7rjIfKP_nrP9sr z-xJ0OGi6RQUF9@s4Ro$;!>5K?mn4D?a_O^<88$!DA;LdhF74=JqF<u~={xV0s(9*9x&g|UWe#_Y!6-GEL>p?PZ<~?)^MYsJ1tjQJqpJKypAzi1? zuwq*L9^5%G<4&fT+sjL98`?tP%{3_nIi-k{Up)s-*R+8Z?t*yZTA`fBQ@Bryke!`I z+L53Z>eW{u1V^~QOa>fCR3=jDsqvPlb{g=B@3)+k3ej~d2Pv|qXi&pkV+vokEqv@<6U=#lRGa7xl(%eh& zh`r<42vI8D7tJM_M|h#o)UV!uNL4#mX$GbEUzikcgB!jPW-5L zoG@BOVOm-?3$%jKMoPnInG0^}Z-z-8xT&9*Veq2)(WQV#G%=di{t#h|4iSt8@hc&R zY8bp5;MbO~1n_JKi>9?p5%%9rYx9u@Gpy{ z@~QlnXzp122%o48Wt!WI%~d_UX|9&tU8JS}^#$F;Z!Bmnqq(xa571i5hiGp!&6Q~_ z2I4IG_FL0jRz?lYjTGu%lIBw1GQ%(?n&y)3i2l&rTLH+%fWc<)qG>MCNF(C=LvyvX ziouJfxvKz=^1T$z4I)i{_*>FRMQMS4GEB;s@Q&!bmcONYA(Ifs4B9qA= z=~TH;l`*+z?4|kJ{>x3_O<*#;_}j12+=8#6xds0}%|+vhG8K~BQT`+L>V1mW$>*Ap z6bwU^5Td!JNF-dBrnw+(G7V)km*^Zbgo8HbfldA~_z^xuXs(9MRWPeJ#qG`IhWTBf z=>G)0l?$s;$gn6}pzn;@US9hN{h_zCpU@Y*El~TKVbRyoTUv8#c~ZK^-xs~5eF8>{ z;FNh>EuCW6JU0s7*X<`PK{_puOEmPmrneISlNna_XnITg3GzmnnvkUfk9+OJZ?d0| z*Z+IU^ZTH;<~{cWIhSQGm$s>4_;z6f_}jM(8)kP4_x}62o_lpwF;z<>{RX@ORXubg zou>(Y>k2ER=`2p#<>i{?{RsJG8p~cln#HAUZWys$s3bnwP-*lsNDRh1AxjHhr)XiY zhRLw{-Up^Ro*9~-)jftnx)$`b=z`Mw8)5VR+uY!<`EB6?ADW&P6E zelU%dzV?IN2>-9|Pb^}kLBS&YG7J1y-4Ax6?U-ToF`8edJ2{NrQX2Y^U&4>@fYEQF zwX^VJhQV_oKuf=wF1=`eIeI_11>f~WzlqLk;gK#q8^WUbmG_%B%m#($>Rt{Fx9DEvykfOw<6xP_ zkI>R&g8!fcuXP%wUp8=Qsgy?x%R{%pxM7(54ey7%R$V&gir5V-HzfxJzGb6W9f9tU zXAkNN?H;t2e&3F`@L66VJxW8Td6oRKDEh7ahIoze93ekr^R!rqZ;I#}Jg1@_8D6$$ zfQ0K2!$z7C@?Y5-p|JrN(OfM&2jJNd7CoOt?|BE2W(|JK zFnH1XFLN~Ts9dakOW{V;3iiDhh3(ILQjc^N{D6MpI$PkTIsjhSG+>?}d}Icn$R>I| zS%HsMu|%+0y0N*}W`7fz;q1I?`#qm*R0`T_|HZgRlpK2#hwp2CB6U;4AxH=JIFdcX zjt!G$2RU(QHEyoiKS>rg$ZLd^SR<^|RmW5dFWR>2t47o*QXqxaL(NavGd+ooxJ{Ir zEUyfMZ-p0L}IPhvBl%B8-P4B6mHwssg=ZKzDyuB)<1 zF;%pVu=UEv?isA+Lu(0TX8Ed23E?X<%G{zW=hX|qPYZ6WC6>}!0<(m!fRrl{E;BAj#}q2Jw#;(r_cCw`bP zC7S+ELm1%-!z!ZxUi_G0*jR`FE&V?Mcr{3|z z-K$GVMk{Y&o27E;4-JE*D|Z=FCrEJ{xD=CouVTyk;Rf+TdokTh4Ll0EAKQZ86?)yY+Owe-}0+;>hHZZJH1H1u`>tz2;HK}vjafyDiy9un1DaH~&* zEO@Oiv2J7r9~kaF-C^+Sq~GARWM|OtNb#Dn4&ZmrYoh z!JYZ7@2{T?3O+3E<@Rzvk^k=HZjtS|;w;#!xiR>gF5bdL|D!K@|9gXVXd?q!t zh~LY7F1uq4eWiPY&qWIQcM-1Tus?@?p6>g)--zTZ;)}WUa@nrO_r=_nE{9-B;cSVx zW5HkKY~+v4IDgbw`LhoDnkPF%e__yuo1XSHk9HXAOx5#T#wrTa$zcz67*n~F39^Jd zZy)ZyKHP2z0fYa|Q{051ek)!~9$Fof>2e=w#@nwZYgJ-fjK9zwQ_W>P+&y=fRlZIB z&ZBXD|9Ua##4QhJaKU3SHPbNb27eY;oBYxO89tZ(AFb5K?Hz`VT;?Z%Yj!>r+T&3A zCbn8%&D(X=$4?D4i<=fpf|M9sXUu6eZqjXDIuwW8XOFDg9Gb~_cZ1t7z7ulz_#ECA zlksLq$I(01S9HzffG;VypTa4nWZxHogYi2j72MaKm%u8Z|kzb9=Qth}wenY*Ut z%xjNuX`^sM=^BhH8e@f4hnoxD{pdEAu}#;d(-{H=X>eWA_CYsu8K1Z6pHXh^9C)NC z(|PvjBR5->uMD`E!3A%4G`3R7LEdNBl(c>DOB`O~wM$B>buMS{jz<9@^~`+x=}+#} zZ9si2)NW%Q#f!#1{f57vEX*`)6jA2mXszmX3bbo>5I^ow=MNEqDg3R;AsH6kd$m!I0#cv);WSBkv| z#5&d3|M--8s}ODWEXwd^x!Pmm%{X~9W}5K2GSL-kheOS2-M%8Ry5&q!d0Ka+N37J> zxK2}F8KHd!J!s=>&ftyZiReFFH5V)|ccfl%=Bg|8l~0APN{Ovpds3`3Y(%-lN(0wb zRc@-Y3^Ub<)uzfs@9fhj))Y!yX7jl-JD0j<2d@#8T)mysjf5$Ce4^i!rQph%F7VLM zoFMvVoqOl{x6i$OJ;qAIYUy}rLW9`tyF+>r<0l?_?e*`3(kj#16QM=IDHY-KQbhPQ90*j6W_ocAZj+=I%MWs1%Moy&t_-z-R8m2t}_# zx5VbPyq)?rwyGAmQz(yL`I+^$EtTgb&@=4^^&Dh30v#6ui>tN z=A(@Gswv$SI|i-cGNyE|+acDux_wK;s-K>q67upqu;v8S2o@f=< z_2ads8qq%ox1B&gfWOY*qw9#4I0Y{FXt~Z$G?{R6Ym?qzI5i&knb3NIf{_><8EC~! zW&Oql)7F_P7j~Fxrk!($mC)WX$8a<>IEapik!x3OaG4eiN6a zLI53f2FI_HcIq)Qbk({#ag%^P#;lP-^MyrvQnEI4w%E#tyTzAj?f{niX#RNk{KXwY zs=3ONwODGSH=>N-IE|_%MGsm6_w0 zYthE^V!4UF+f-&oy{2@(w!@}-FW!AwZRyN5wEJJt4vT@cAFr)y0`FA$ z`ln*833MW1*pmqLmksj9)DHCg@v6BV;;U91G}h=g>Eznh?Lb}R{aj0yxpMUJ4|>(p zASpE*a-7dW4KvvBc+?Yhp4|+%&gR zEhDq!!{-<7Q09HJJil=1%UjKUn*a1Q)K@giK79TMJ1kj$3BT86uFN=oMUA$c=1K!J z(kLZO>Ssx>ZIyciEv?yd(QvggAv|k!G3Ekg>xq&VbE~V zeZ`JgQ2#02W!u>-&$ytT^AD)svo<)@%AlJ8{WUdqpxQzog<}UI_W6UBtf6%gOieqE z{?r3E^@OjMQN3FQeA-QfV@eOO{-g5J{K%#6(6q`n^qY*Er?_?W&BN#Gw`=S4OsloF z=lnAVrJVtz5R4I>rwdm8(dfu^Nb^qfIzx#6-kDah&XH*b{Stya^v#f-9ceq}+B*Nx zI@iADWJy=mb3XYX=v$R^(&SGXW|Ap{33J^{pVdn=qWRp+m&K}^KGpeYEXSe^goAu8 zQBKfNdn|ZCYAbQmlafW|1gCUgc!{%_acUtRBx=)hzUP35uWmc2z^BoX>>YoC(W#Fx zmKN<0{kLPBWR|5hnJSf8wCDT}4vKZSch!Xx;JUf6OJG;&on5*zQ(a8$An(8x3r;3W zohQUPHi8Trs|?bIh|Ng_x0Wc)_0Ff+f1|jWS_E`$6gNsAdv#IhunVK7$#Z5iuj~`IR=`Z%HJ(b&Y z{=xl8+c}Jb!7mL_=Nf$_@8E*le6fDw*j)!uZwGoVpUOl#uR8EAN1+vmMi_C5-`_Fw zgjx?@@I>4uT7xNlzC~W6^_I+!7}v$e5vK?4(gp6)Mcf|v#BAt_h&O@jd;X$m1_#M;otwC!3fE^8FJk3& z(Kv9+MZv+l?HA(D7M}k7s+0@yA%Z0Ho)<+6ctxJ?tmJPA^NKFeYaUDJ9pWA1Z8b6K2`2F{NW;%d0>jH|!r5 ztz2~v62YnHK_=Iai%R9tQt~K(itf4lKKRtsT^SN7dqwBjf7Ua|@Moph!=Hc635 zb-*UsXp-Tl^GCWjMg3tK!f`v%iIhGb`?scK*dTT$Y|3vV8{xkr+sbj>Wa9wDhz(^5 zPbPaf-UCzpcaV*AcLKFcBd}LZwvFR{s`@tprN-hcyB@X!_8!&0Pxb!=Hs$XFs!=)D z!KQM)0-M6I%8>1J*c6`yo8n8<@CMa>Q?>u1+TCQMK4xr)6PygymS9tPX27QM%u)UG zRsW-~DSeY_zkxL zo&2cNo8*T*19?+BZX_G&-zGa1?FXbcq5a;5P2UG#)AvME1pGmla-?hao82G2XX)Zq zi^ud5Wb5P6`N&WJnz5(q!`ROP!lU4Sy(~Z$nvrN(4t`|v@Ea?;ls`aiIsON#&CYn1 z!k+VXvVrIIg|kHRS(<-HL<4Eq(ZWYY$C{W&vA90XiN zr7#rax3LHw)r(*QUf8&S$8UsvN*&3IYdc^UlK6O&9q7Z%igz|5|=kYf92YSx!$ax&HOyvZ#T|g{-n!ve4uywaEpib|K@u6 z?75yKNocVA+dzr0=D^kcqvtr})wuM|0C8u*4omTS&|Z|@=$R_MXASY@8kZ$tkzP3! z|9hd!884>15^}W9E#gzSkZTHdZFmJ5^s+kmZ1Vqm2f@KR1CURSlVWk4Qr=M3D0Vr8 z4K6XD$SCmskCt<`g`T9M%q;NlZ)}SqabMGUk&M6YRiHhiY{O5iU!LY zu$z-UE)Xx3Nq9qbFy!oVwz;s!ceSp|X)KqlM>C*(hia6%-0qzt4U~T5$%LM+3yrR+ ze1O6~Sw6;nby1OLcjNX>ecW@)he@|gP4Rs4{!wX$`XyHb$T`r0Cd_m%@!0XME1j=w zSs&Y}=TeL7JL5RMwlHWDx0G@A!)P~xs-&TER!SWW!me3&A6(M-ce7)&ZV`5@x%q|N z+zqqtc%tm^S!W)Xg;R@1pODrpHKwLWF z$oz_ZpZJ;@QlVcX(6>&09{&Sju}~+MrARF0?vl$#-KGIAS!+#*_e>26`g&%R&03Gx^|u__k~M z3cci1((=J}^t;kitsM_6r@njckq4Ilr6S4u(?%{$KcXHZ?8cC83ZIwcrM}Db?s2^e zonGCo(;ank4LCro|L=T`UvB>%Guoi!HR|%OY-6l7t%THbCb!YG$Dt8u0}%Gsf9<(<7)g z$4@{FK=|Hh=CeQVg_)xt*%GO%1$FfxCC<9IpcP+Euzc7-a}~AR)F7`{$~OElrEJb8 zv}ODEGPV*G(?W|)C|d)13i~CysFo#Tu4tzIA}IAzO-S$tYoL!#AAYyfhh3?E^w9nd7i?H}(3|9WVEOTiXDjx)CNw8` zE$`1hcdqnV7kB3Qbq_2zj&J0YUZ&Kw2zl0*bdhDJL0aStr#ZGQ;ae8+t@`yWo} z#EV{TWK5Sg_F@s`u+7B&4~##6i$@CuYWm^ju7rNBU?3q zq+;3yt&q>DoWUjQj9oe-+SJC4 zWaBdU;1x7(;NxtxgZ9v_S34eD@}GteJ~(h^Rt)wl@((PT-drBy>fidn3oQSMk8;}r zzm;-y5Y|mO&+lTiUQD~V*l54FWMX?p;ltgZyi6El8Cfqq98T>#`y&-cH&rlPNen^{ zeDjw}7?g{P`Cyt)i?bYX=OzW`x{dNUoN|8hPI<)1bIirX7UZhboC`i#PV-HzT=NTZ zuU=R#)Akgi7H9zr(TAUu(UCU(9%r~lk}1p? zj9pk~FlQ~zcHngI#UhL@%U?q!kHvv{h>j%8G?kAO zN~5Iz$K9F0RaLG1fA2GKI1HkaA)prliAg+ymWs&{ac4G}TDR1aLAy+;sTqmMVN%O( zAx8^1<~6fkl*w$k3@Y5}ZMY2=N^fOaRtTwO2RV8u4gSAp?Y++=HoWiu^Z&f>e-}Py zt-bczYp>y1Yp?yR?`jvef<8}WkGeXQ%5+XJm8C9E1+M6B%#KdPTqtIlc`nLe2`_Ex z;XS?ESv`wpy`i6>_mz#hyudz1$S{v%N1qSUp5=A?giASFlDD;TV{xUrC0muylFo&N zt>nfTEW1lva;Oea%?s?5>wuwmEqY2yd7!exx=jBoxRx>S8ys0Ev{kdM=h5luIYD@OM6iPcikJxqwY)vhW zXDBEUwU}z7Tr(p)k}jmx$@P-1y_BXyP0Rk4MmlAjSl$%FEQ>+?Gy0vpbVF}%DXTe3 zvF0SEQ{CY#MMY$R@l#1lb|mSyphuzK@Vup5RFd`fTBB5Ve$Ekf-1MS+rsIxper|Iu z({V#t?RgG5PG7VkM?2}~jJ=$m^<|{xB8q;_dCjO#&4-o?*YgwebKdFmHy$_gVJ)d4 zVToz|&~oqeP1{w@bQEbhO%b$QJTxDtMy>GZxktrMRmKemD|NK~#mW3Nh*N~<` z?S+ncp|~YGit34(YRR)DO^7$iI<>}8Pn4{dM;AVt0}3+t;pV4UU#QLWr+V_xQ>Z7w zIH$e-QpVH_ZRX1yOF3%FQ20*Gxs>yiQJeZ`&K;HzU$mk!e$u6k52+VN8db%fNFzV@ z8jDsvyPf)l4{LwU2~MpHq+EP{RzT}BprE$Zg2BwGCW!GSSsQC99j`j+g!NK;dbLPy zPvIE%7)zZsJB>yLY*{Ta7>~TakNS&DHXhMpJfd;`13S<;4e5Jn^j}5v|-{SzdA}hic~(>Z8^9S^NCBMEaug1lp=tKYuQ{5xox8 z5AnUj(0iyPC~s=kCyU?gZBrJb7E+nwd#F?+pX<1sI#ZYi?do6lDV`{~yC^uxI=uEk ziZW8!5uK^R*A~8TY7T5(Fe3WAX290nQi>2S)qmE<&CLv^?^<_tQJXEW-d|6xAPG`# zBS|)8{WD!HecpJ(`J&IykKXvG=c7KO2EHvhVK39!g_?p39{XqnU0_|ZPaGK!*tE@; zbLI#Sc7A$VHTN{jkvx3SJKLVkO-);u$(>bc{Zen}+K@Fl`%*>^J3l#{i~OQ}6}K*} z8Rym7OF4e21GXnyC|w3iUm@#3)t~fnWt=6bSghUe?{)1#gOCoYQ&;q%sNG2y{czU3 z57od=>_hW&LL$U^eS(cmp=-1})oP55lC00{MV;A&yXw%gdFaKmvBEzDkzHOUOvxBZ z(@31R(1>@tdDLIxDprcz*b{u-NEVCGK8AW;13wLUXh@-c*T4}W+3VJzSE=6((b1-{ z$c43BB>2NrkEmx#vNr6!l%q-sNc|Ud1dY}36|Fcir!raAFVHN0q+?Vl9lf5;uc5ID zhdXes-BWW|`R~KM*=RAzwi{n9RW0)c=s&7CyOsqdS;y{e&dv(vLPA!m;+xZ-BFz^H z&BwmG-&@p@Bld*Uix1dtXr!Kv`o8(2XIbxA77>Ga3+2Yv-96WNUKfhrp6|d$YAfE- zKZO+mT8nBlz1Q%UGNxqE-Xpa=G5l>&H{!jPw-ik)nl^3ggW|Di(=_q8jvbQ2A=b)2 zuXer>7Gy(DjI~Z)hVjh%R1W+U$`>jPUY~!0#xs;FEgkP5Wo5!?wdYZ!Pq_oy??p-} zekED|R*km{#fXke+3?}>a{IGFSMI+FqXCVwN9DQtNDQ>nJk-db%z%|G=r<$FC|~I6 z&cI7K!6~~_`fV?g#R*&UNU53dQ-JZcZnd>7?d1zxL0iXIydBb^`36|8VcXoqa9Ltd|!8ry5eXfT0Y(=A5yjY;O$eZ&BFKKvDW>|wj6mhd#p9} zVT{zHls&xiQihiRtGEf+Pe<^Cy=p+~<3fJ=I(xlYUo<(VFj0kLF@jZ}lzlnNF}mi54|<7dC!gv>?=ZY7+0eVEaAXRF zqZWwqJKC6Mk!vr{-Wb^X67}#u7p7x0{TXJQCS%N8TDW*5X-m?gq&=ZgkqRvGp;oIW z`>a3LQJbQgv-vO=h7@R9QYlCBksDK5rsX)s9e>^z0>1^#SC5ZkI)Iom4lnnZeFURP zMS(S-VJ~J*u4(uwOD?s%+{$FJhI5v4g;Y*nLUZ=e%zvEbl%}p}Im;*q+TQ8Yw++}n zZ7L4Ft{wdbN8v(R(8r*cFRP`#vB3Id?USAKK3y?u`o;Sipk;fs+B?o{=H++l>DGDh zeW6cy0?ufU>6yvn?Z6i^SMlBQ!0zaMZ z%f(&nNX)4hrezPd5_d%|-h^JgrDj)Z}OM+qSpTsPR^zKb1=D>wVPfH{^~Q zc@0acUJz?M7kjZ|!1i%7jo47T8|mM78+rWupN(?)=vt7&oZ6I;^Djk2x}FGM}V zd%2Ug58>#|6mQ|^4baOE$H-Q!#RIkptmS;wx2s5g_e;8x0{J* zH*8*s^)nwEuhw#CzE!^Kk#24*>=0TmrCz;ExN+014GplMXfX#4O~L!Z@QqzmM;lw| z8p_iv+eSa>Bt17S$vO@_*4r%yu@9VBrqiv@HiV@1+qTiwA!1Kfo1AP3QJ{5&pml{% zzeck!N!EQe%Yw=}=`Nzqce&4LZo=hGxkSXd2x>j$7?p}WZ86P?U~a%E_c0=(bRqXK z=evqD2y4p&w#b%P!K>@EhxW)m56#g#&YW3=8N*!*ktq_{knUAOexJX$Hw zyaYcsnv>ty2M-NOU`4%h0KP2+f#?=okfk2%}Y%*Uee*~nF3#wRQUR)fh~j< zU!rudVerNmDqj$!>Dv^2`*OBZiG*7|s_S0BU2eAK&L?H=UnI|FA6ECqv>ufnkLo9J51i{P-HX0w(|M|sv_3TnQar3T&As2v-RS0i!_EDk zo4do!eca9ct(*IMH@D5r&1{045N@yvN>5w8?18L27y&I={qXX?EL)R7b~*T+{@{vL zWb3nf^(q9&%_VQyuxB;HL%@e@bzr08x^J5sDdG=U5mEd|#~K(2JZ1l#Z~ENNLW<$mOzDKeBpdT812rm~JUXih$V*kzEfy)iXO4J;@M} zF+p}K*^+xF$uXjxkq+O^r^7uSiYysY4|zYGAB+8MN#Z)%50}CPpgrm$IIe;u{6CZ2 z#6=i?9oiS99gXAuf+`Gw*a4(S?@@+_pXQBrr?)v~q z+;;=i6uHUXiR_}@B?*76rx?FCB*h;NsT+s;l0^7DBoXf4B#~}!9VF5nOcLofNbW9@ z2^^wyF;;{Aps;yq6?7VDRxM0If}7wA2@ezGLj zl0>{@&qV&D7pWX>CwnEh*O0{heTU*cuy+{-sfSFK+=ArZ4@u#^A&LC3(D^9Xm(h7h zvK=9Nt#FcvcNa;7|5=jvL#dMgOOW(D`ylCg4w65Nb~;JM;r^(w6mBs|#8)P{HAoY= zBOvL%(U5fCspLjH)5#5)4oUYtCds9+L815>At~HJND6n7{1Gl3HgV)12}%A_Au0Sl zlK*1KKaJD_}bx4!JmA{@y&n-ikZ~|I;VGvkJ2K?w-~>j zix*it#}; z+2bq4Z;B7G5q&#jtraaEWy(_dP*sSO=oCa=VQ;qf4ekHA|> z3XMPNpTe7^t_^=aJ++=(Sd0@RAu7So6j^@F))A(WSm$#s)-Y(EJ0@9WMT3$s+KG}- z!6*rTHI8PKgi#VD;as4>^0YBGkDtVa(RZuA_N~xsY0XePKWR@-h;kwJ%d7_>VYsDR zSi`&zKvC$Y^ zC}x6gQC#9DklQl`goLe6cgKQ|pfbni(Ob951VRFAK_;^qem-ne%0fm%I2TAPg!fK! z*GHM7EBS;dun;DseAepOqxFp5Isz<&1c`-kUqdw3KFzR9!1{Wbg)qbN99RfO z0#l+Oxw(8obh$@Nl!@zori89lneSyp1V!ayMnvc*BEkekMInd?i$o#*qYcN=I3O3n6HkW-d(?*@6BtmjgLdd~U%Z0OC|_}aO) zEh3w~ z>Q+@zZg0c7!0{Ws&EVKN7z{ZTf;VF@d|f22luIj=?ESB>#a*v1y)6a)~sOV^KNUDnd|+gnCb$3Cd*7Hha@ z-fLjs#{$p>z?RW$_a)NCB5JeTIL`9yMql%M*f@rw_0W2GAJYs=Fjm)bG5@mFTMG1$mW+p7~~#0yU7ga78|5KAt!yit^Q=YLjm{)dHRA5?0Jo z-Ks*p+FKeZcr%*83RjvzjyIzj7|-u40S_ZiBqwYESH$Q19oJB;)nCuY{I&0nG~yO0 zP}h90-qs6JXQKM7Xjho|1k`7wn72G#iYHen%&HyF2$*X(VV%7S77LcyMHJRxnN$2> zUrO7D_#*LP-^8}}PkGxJ1;+DhOSDzqj5s6eSQT{a5%3IR^C++W)ft@mEKjF?ZZcH#*^Mv>R9RSZF-7bmrK_{YtKXuJFa`N)4P%j zRqtSQf$dl$>$NSpu5YCt_X|-9ZRh`5sR5DorwiK^yLjB;{@CVJP%?tnVv`-1; zl=oK7Qg}#JL3v(+l!TUgi_{j00V20lD&2#vAz1OM0t4ioB9R$^^{wgs4l5To|YvDigJe0qeu?v6E6x>uT0OLoOv!%CZF#DMbrP z$_P6p}Xu%7jlSCTB_t;&P&-uy{a8QGt>I z7Koja@{)s+GEStVywWqEfR#$)vBT5OaXFiNX4fYXOy`D>tW`S)~B9_>$MgR$N0{F zhewPqrR_8~L+TIpT<;f!)LZ#g-aeXoEY9*mA!3=NPW6ZpQsXfe)aofL*Sn=~1Y+=r znUSi4FNdBaWG|iJQwwalPS40iR(8lwncAWV_ltW7J77C_578&)$bEI#SOMjrf^JfY zJvLYvGM8i~;^svzi6iG@z$GcLW;dXB2Sp)@_lxT~zDtM|Zo?OPUcV}UjRK9-YvXDK z*J~h6r)Oh8=%-zi;F;d(wT z8nwf(^2uc77pjW4VYl+H(&3f<6*`KAkE+CoWMuY{{U=~wMb!L}eB_CB_TUI|b z%6Y76=si)4v`V}ajMu`4ZO3>Gqg6w1d$E{Sv`=}ws+a4H_zk+i`h6XxG^YAgw`=V< zDftI_3aIKj3W=`zaz&yn1dn8v`4A7H;yz z+f9gOMx4P?Rh$OPExq!u7`gbj-V>IG-uWT)V;M1AZ$N3lxw5Im{kmq;{&Tav66>f> zC8mMOJgS-)7SvDn4_MD}UcPpQN$R-}FLh<_IWFeHIfEDJFcrprqlkFKzF4P$(G(!W z2%3}fdCqdjrlCUWx!qo)g*l^tId?Mu+H+-d`p$I+sqR~O?rSe4_5D%Z9T(4WK~}ga zPVI5)xit1GxC5c1k9Y(ejd&(dcsn1qo53$9>pJjM-iki{gNUj-M@MYM_yN8b+owd0 zz^a+Tb?+U(x!_S%i-P=2zUCnbf9*5s=Z_v`qNjagQ%tBQMy-V*T<K0QSWeF8!! zhSYo#IKt#-9#O@|1g3bE8+sqb+tl!?;VE9=Lxp18qp&Cx82_wRnY_$C<>Gr5*==!_ z`!|B7=1ts^6>T(XDQ-rYRieydhGOhB!xCsz?eMo4c#t=W)NJfh4x+~jZpN$;LUk($ zRp=c{3UxD8AZB>S7g%rJ*W0D4>VO^mBSosJd62piRn;?~%d9B!mgq7Aww?C7yo(Tr zHmNFRpk{1ij3=r=|0cTv*6-4&Q)Tw9B>LR^LXQb!EFS!v%sczEiK-p*&nVRXSkb_H zqx`*9ujT2Auv`b1ZYjo~ahzpDkQ-RWZf@Mxx42Me*61H^z7Cf;y#T2p{A*^NeEkFwYr_p*u$*1w7GPT(#wZ z?F-a=J~Xioqm1$(aA>~Q57+k+lj7%k??$lDTewy*8WA! z+ixpql{qw?b`DL9;+2n0g&o9a3B*=c9f65<&01;+vnL_n{(DliwReikrHD;l@L|YZ+rYOMsXo* zo&cjbxpdhm4m3|1!9-)8fa@J7^fP`JJ{X@jiYy|un`sMb)L;=g#uo#&k6gyNu-n63=&Ac{n_44k zY4#{Y_!C+zY&b<9pKjmBN0(_hh1-*=Yc?v%h%uEYIVb9u-!rTvuWg z{!|qvl!MxNwu5Q|y%`WCG~#RIpfo!)40#YL&*m6Buull(!BFJEi_Oq&BQ|x4?U#Bw zaa=ZaAC-H|-smbX^WiQ@yTOWZd?Urh+)kjR5K#bHJPQj!@S|zujKcm$7RKjvwIeaFK zAnQtKHlVfG$LwW#Aj}u%7h$F~uUMW56nm($A|mChw($wNa)oIe*i*$jac=$NZ>l&;uPsDuk_e|H-{-+}TJN8kIJy-oeLuMVT7 zF7w`sy3DK4H~4J*sgn!)6XQ~GY=0M;!Q?FeS@fsvUZ|V5x6>Hqppj;>btbXqvKq6^ zYsa7V(Y$9En_Vx#3hxCaUR7L}+ElYZocBVj4;l8d0@O}LIrRv#<}W%pj?GT^nr~wE z>^jq1WUa?~hqWh^m>m;Cs=~aGNBy?!gRXtesp?T+_tE@g?10y%He6oa)dzjcQcrzT-3nD^>vuJGL5kqkzbh87{iU> zq61oIu$6lotdr5AzG;?Pi?QEUao8~zNc>u_GMfL}VCCw4q?GAQtHUV8zDVCME%I|0 zcYE%j_ho0MSHJDu7Ma3J>k~MvbkUVf>vr|KvsfNK`V`ankw%X?Fse>AlV;HsYr?3N zkgwXbqRZF(0N%Ir>LY5XE$}AAm_OBEZrpT_;Ajh|*}`WYj~=Dg;21qVi#hZN^WK2U z%7LXt3HF>o;Oy zaUcKVaW+nzwq^7S$wte$qIH43(T4NGihX*v`eGEx)t}{kM+zqynqxdM~3WEBrFOvW6U{Vd#gFZEI*r1RY$P8vKBLB zw07uSMrsav+1IQ{^fj5f{med9rev=7Uu;g8AL3)ywtATq?b0~ae7{Gg-fn0w>On4N8GqOB6VYX(ndlz>agGz{zuA zS5n}_*)XEO_1hjjEVk%KBaIfK3l&xPZaJG~&QmaRj#+86vGiuOSuqAf$w7*YxcGLG1HnSmqPcewvIj+I=3Zwms z0o$GyJUQupJYo1jmH7+2w{F6FYhe?Jq-ZB*#nA}^2Qi-nhIVX(Svb(o@jXxWf5(m)3>T9?NUUM4l( zm&Mss(ka6&+)TU|TP((_>+2-jb+ihX>FzP7D1S#*pjXTrhzV%jg0F?tQyb4OEF2+h z!@DR}kLZUB1JIvOB;Ro?Iq$tdF523m$n);uz0Y@JZSK~Ai{DkNca9YFA)`}h#n#Ko zmpTGd<_8bhjyL*LQ926sZ=m$F@dFo6*6Bn4+E)b2Xwo9ZiUHe~jl%`j0`aa$eekqS zS$`QU|H8K>AJfQ`kWQ*mRG-A!l-T45vj<^Fdlgt;sOvvy%eEYea3f}ep`PdY0UxaeRYe1 ze9HY$ibq>qpYS1kVO#}%Av6oVvr@09M(;u8cCvBkb2BlcIC~dngv%aBU$rGU5^IrA zqKCPdxnJ;3T7ST{rbVtTy0U)TCwME9$4jIqmQl^S>UUS_x47u+4kc=p7iyIbb*taD ztC60g-?pRC+nk$sjX>|%-lk-q2Ghx82{!yQCqk z#m}4-jCQGrFpnyyYd@}C-K_{4foJ`xHKBx~YFq2)}gFEHizd`g0dO6+M$Y)|lAn z!}1y9QnViMjb<9=l*He6B)pNbncj{*N8kLGm zI^Wo2&0Ni$zTwGUGbZBdv}I}OSsV|uLr#6exEY*A=P^Uedn$CWcORzm=daDOc&ISF;k*_=#U;RP5KrP?vPyCs#F3or zaN?JmOO)Jn4<2hD$TsR-$&b!c_zm_jrVMy;n$7z;tnQrbCZtk^i?u~BlDmV8_Zti+F zcaxjD&CUI`o4ei3{h6Ell$)Du&c!`u2gOi=MVUZA%8B&PB>Lxi`saqL^C|5c)?SSs z`G1L7Nw)3aP{JlXZ>2N9a_O2CX=DuV46=lQIfGT=*}NwrqH)BMgd-VpJjz^v z)I-iAH;n4;CO707Na7^!N9CaK!_aiej@chgR)+?(7?OC6sgT5Le1P1jZrS99WE@Le zHv&zF?4Z{{Qv4erDgH+C597Ftl8i$epuHK%Zk+aJEFm|-Z6-HlGbDu{rh$xr{Wk77 z9`?A^kb20uxF^{OFC>ZQTq?P1VI)cM5WkY$S8^Ye+!jcRmvJj04Ty`}casc?pN#WWgc}$X4NV={MlCJBQ+zK>Qa!-V$>(V8;8P87XeG-z= zdl-_=Ysvl_G6Is$M?=#2iIRJ=hjM@rWV;`xb?biRVz@ZUjh$X6wIqvY0+Jvi<+5t8kl2}yfr&LRIu)CclMI+v3_WS-<+ zFS!pu()GtA|1Tx~RsQ02Ya!{nT1fW%=m1FG4N3K7Atcq8HzfZ^fIbjY8SUdQoDeK8wuMXV_;X0MM!j?&mbxN#~~^G zzNqWuZ;+${_a2YBtbx=+`jQ*!ei*qSkKkFz{TU>=za%%peM4?YWG|baZ zD_ktX(KYc>1QZ|XUHO3OW9M&`q@2DyxT!yu4^%gH%*MYcI?ljc9QPLVU?d_zGeyrW zj#en_68zD9p|aVL8|pj;a*UT&;;eJH^;Zd3DuokcgKk2&xv~S2o`a4;{5hxZ`)KjL zls@vOaFo7s{2}k?_Ut&0_$J8?NJP(ZsgoVn&=e1}lP9!4EO=<`&G#wiqeI_GH@Cg}4p0 z{}~705tujs?s#ABoh(&c}-NS~aX>v3U{M4zPD zVtQ`ka^^3ir=#as)y_{eNmS0q8I@DjGccJCsp{ZEK;?`WoAC>v{bBjbEyG9>3_f_}@w=I%*gb1ushEDDXkP}ohS^-J#1lT?m3ODxXOm<#%$ zp3cyI4JgSFK9Q9p$QySG66-MXRQs{65g=v$gOM^l=Tq$9WP1LY#iM%PqJda{OyEp*8!Nqhp?8ztH=iOGi>kqh_L8>nW)^4PT z3;CACE?Bv>6#r+Hf4cze#0+09ISG`-9&k2M4okbk^cBO{Q|ze&jg2QBI6@Y z&0u`Q{anwK!j&K-E-_xt1|M<%Y!)k}bw;nZ@iu`U2hQc#5!mkqB&kikh$D7WVvb%D z4CYY!Gu;WZtc;zmyY_`XyuD3A2cKH=Oa`DrO~Jd;sU%nH)*hMer4w9G4gw zFT#L%u+T4!F+|4O)yK$XL~7wJ3ysyu>W@P*MJ5sVa!6`o&MPUG!TC$fpn8h8M1p87a^#i!2C63KU$a;B#}Go0}<#@-7%0N76do-D2EVV2Xpma+CBw`9g!v|I$D;i zV$_W92^t7vIS>_uGxg<$fq^9ETA{GNXCNubT2V)K-a8AyLrLLpT-}ra{+u;1Kb!ID z7_(F6)m8ib;hafZWsM7I@QS^+uuQ|6SI3*JkJklabkbsyWpmL zus_9ex}5EQ>fSRN&jRbEx@CEO5&pt9R&umwkXRD?HafQy9a>6!R{~gT-y(eGI3MgT zq}2!(73%kkdD>RR#5L^tE87vr%Ke&p1#4%{HKRu=d-;yVE_c-8jz2kS6INtU+7#hG zo*IhYY9-5E$^lp*z`EbKkw{<~*k&_!;*|Uhv=}vK$t)p1>NnC#<$Bc2>QVScsz>YV z9DLX$>&LY%tR7v-hfTWpRxN6g6CXCo+5#WOht1+cMegP$Fl+F=oAF__Ve8Ylv6r*n z=}Xy9^`{!OXJ;*HPdsYXN{|!1JbF?!AScF(oH^7WFy<2MdAw%1_v8HZH?N=T7=t)jWwXxT! zHlAs}oCbc+{`FZDqQH8*hRBMSvOhho4I#GT7OcIfV0uoy2&Vgt}H& zyDTr4)inj`8gH*_(>wj4%p6bC8qcVM!KWcmt=jYK0k-Qk@~hj*JpH<;=BC# zVwrQ7-SAkqavC4Yo#!@w^&M=OUd59q2-bU+zH*_y;4sM4jjK1euCUgxY8Ti(^SUQm zJ9Pv%XEpMcU=)5j}i$X7TUIs znZn_WcHty8$MQIum`$|MhGLRQ)-yH!u&ckOqa|lb_TlWl+-NY+5_6s>1{!*!2a7|| zA4irX<`4xfF?V_f^#h67m$QEeoRw0OLSK6Oas{h}X;EcnVjAT+wo0$_%D>-jnO*B>wF2jB98q_=MUglz2w>}$?g1Qr)w$HAHROLdil|* zS;O**lCwMJ2^&&(3-=43_W6~W@g14ddI|o*W9gcc^bOV2$DQ0bE4YKd9*n>tvtV~j zba?uvzPBhflb@WLN~G_wR2mVB-{AF4VVRCAziAJJHRS@~vFvhTYSz7o_m|vPglTEM zg7&Ne9PtW)2wL-`vDovoY#onf*I=ACEo=12G3ubB>vBI12!MFlDc^W}l%*3~8OQ~@caGjYzHN!uqieZP>ovDd|oENA9E02o`x8^N6v3f}WV3wz7EjXiZEBzQN~b7|w4f z`c_?f^Z{7a>?+3E&tTs2m2wt(p5aCOjb1$iiG8{A*w~bEMcW#)vcNj6HXnPE8!ShP z`f|C@DWIA44_%1BbU&J-vIbB-6=+-er~+$f1C#Q7= zcMLzBa)a;I;A;N{kFd*KW7J6(?riYsUYGkQ@)XvdQM3vXIe}OxC%!9E;VUYS@R#fP zgf9+!+a;G1m60|s$@XU5C#S-YhK@Q)!=Y1RE#L|Ytnb!^!y3ykBE`CE>C30S!8*Oe z_3Lsd6d%7XqdAlM=EL>Pnf%n|)aI@*oc~)L7l*X2R<#BT+K4pRXoXw%FHO2&s(Umy z+?u+E82O-=L$|=vLC9YU>Y*~AwNfCxC+oZ<+s3-ST(Kvm^&LfZ#iwXIn$HM``PpP~ z_e?$2?0?p6Wup@=MsXq(rS=PSnEWPsk&UuwUyRCpY$<1XyO8K;*MNgcb%;pNN!Fa|OW=s_+LW}W|TMKNUTEm3A>?v8v0_ddsUlBHBMq5MHRI&T! z=ct8Csr>Z(?1EFQM@!w_Dc-FS_n`YFS<|bhuO|V$MaIn4X`0DZK?gA2m~th}>3q<$c0R$iKQjS0|`W4$q@Vd( z2zV~}$K$ani-Mw4Fj@_J0dIc&ww}W^p!c0StcWw5pHv7dkGT8{j8N+m{)G4Tvh_=2 zg)a_#IkQ5DOA&jZ*({%5O}2HAPULS~pG*DFi?BUja*E;@UZ{*a+3|H}hDYQP>|PFH zWn#k~%r8uCXv&uLOCN}pG#cS7J`%5TYL3XO9Izd35iADHfbFZs$8sa>jP6MducSn# z#&@$aH4fNnS`KBYCOFQ&xi1o}tIckqPESsH_SRD}^O1<9BO05sFlQc$GGp}W{H!+u zcXj52A{hXRq&7h;6=gF~E8{V8xxXtvXG2yCm0&_X%Ij#OqZTJw??5fse%RUPDfm3; z;!Y|T^RTP_xp5yxR;#E?js}bth*CLEnC-;V z#15U!d}uhvY3r6!PXKaX3&-4i7`ZOA5YJnUdnF!TpC$7bldMOpi9-5uV-IMD2N><} zEYS}4FNE(0jr5DGw223uxU}Dvba-m^_T&v0+v;P5{@fe0#X2Fr>(ru7^xIxJJX*ND zGe)>Ey9VKE>-%$qrLl{1s9h|clGa#++i#~3(0MkOGcunKbbuJVgt@-C+06*2YUMRoY;n@Tlc`1#!62bwW&Yl zi1hR@tObAHn83!ho_Se|hg!5)`|+8PgYJr}?g@-frFWzDF}2dC=U@j?FJ2#n%=Rt91ubypU!{ zCO&W9`((QHPWbF#{Q)0t=!*bX7qhK+uO;oyBc;9=ms~IknAM=3V3+W|P>InjjTptz zVlwIb5QVgx#2lvQwbE`9CyXr^Rg&Eng{N_4C+lfK1&Y}dyGf9q-5Qi4+#+mADHHe! zY)^?$^b?B29GYw5!k}&SG)8!=W__-sF0QSiy11HlYzDh`fo8Q}5$1La0yq{znQ#kc zAUOR7HZ-u*PUI7Aokg^F>Yr$wt41yGIuV$+5BoCxaP$S}wk(idQ?O6O`lSU< zy--gF#dfA!n|WvF;bqMv>Qs>KHD>H4NFe$2G)fJ|H09cOO#)MG8mIyPbwTfz;s`MK+|iQhcT zDSt2;X$TcYc3;X;B&4*9`%TPlqBLL1QpW6-o_lAOwd${)-Mp^cuY z!IRzs<#90*8V-%Vxts7pHY8p7}%k|KP>o|%i?VEt#!jlj13aVDwr_rBR9uVPa* z)7Pj06SPmQcv41!{!g`~qVH~wLxm-5&WDP9^Oe6XI=SZ2*>}cOG#Sng z@%(6fkCWYWzisvpY~uL}CpVpsr4NDZ5YNXsx#|2GCpX>S58tN6L%jbvCpVpc5;h6) zd3-Ww2Yq5ATP){;Y^PlF!~MJ?C+Irjo#OK<`vysMfo!9k>j!;zlx@E#Jh^Y7AJRc? z`VK1}I&Ar~uUE=26;^sEFxu0`$SG&0nxVf9$-0!%#KX!8;b8~mPxxaUF z+uYoj-Q4Ic?FZ!t*=E^spw2r4V{>39Feqc;v2aA-{9~H}+u@;CV|%(2J?$_)XSOE; zcrqgBlGQ}{bT$2QBA1Gr5I-OhLzg1GtJkb#rdc9Zl<`1;36n!S%slMSP-Mw8{1H#l z0688NJOxq@xsd$v5uD11?4A_JOR_%+l;mWRxNaNTCp(XJNHPR+dBe^$2QhZNBQha;JAJ?BDiR(ht;&ls1BE3(L zM7nm69EHbyFD`cP334KED5GV_>&p8N5_B?HnWY6;v`NMAD z2>HY2=ri(%+)4IZ6rN-ZSiP`GqVq;bIv-AUScvy}NiLRTktFw!M0($nBq<1bjyRI= ze?yYTNg|%9Lm^|4Zj#}!%OZ*UAC@H9aZ$KiCApg<&L4-Qd^-uLhqRFYIM@qGc35$e zoDNC$PRWpD?X28&8C^^g&tFCo;lGjOFtXc%|8&WI%PPrqvg1N}j3iOshe@Km+exClzago|{R1Eo zUlB=!uOJEkVqp}u>6nN=Pxedv2daXdzfF>8%Iq-UU+R11gTm2qGydp$1ODikOXaTQI5b`K(hfVL zH2j7dwA(>#MqH>m_5; z_NyG>#wSdka6Ma9ApQg7<)rv2@e|@Fg@jCqC(|eCU%meNiP+J3!bCavZ`(KBBPP_v zzG>xazQP?=ZhhSa&0}govzIds7u5Sc#5zsP$25U_r>Y=ZQ4Ls_M%QI}O=7sp8K zdrTqJ6+XCfs#4`fw%0(l>OP&X-wdiZ)V}2d-77cC7kdoM{0Q3n|6ks}{JbP-yi0YB z>JsJCFw|yLGy6g3s2$4(xt;4Yxo^ZDT~GNpjMFgwJ$|x-&U0&*W;tx{*KkYhZVZf; ztW8_JTslq8M^d28Zap2UG|cBJ`#y$;tS zYp85x-Ap=sF8<_$@|g~*BhEUqOd;kqwJ{1qf21RC!k=?|C2&){kqz2$wfVIOy<%KcvGG^pl~=as0Lp52wO*vQZt5 z*8G2qYaHyvHCAu+_*JfP3+8TB*q3J_=Dm1}sz_~Kxcn8^!?wd>VOC)!mYbDsQdg2y zY^ar+x215-1J9@wJ%7VWR0n`))vzom2g@r)r6o{-k-O!P@sAObwI+|N5|SGk zA-T?pknCYr3FkmaZg3+cdzv)mDwBhd{1YQ2KdZ8FHm;2QYs0p1be}fyO3UyWZ99@Zn&y@i(J0by%!T z>Z*Cm|BV{;iSZr{-?MU)a~gMo*fhTAIaR@h#`-e+`v%Cm=Erxa`JTm_)aHr@X$-?# z?r!zn<^gW=YlCo`HG^`SRm2Sb-Q4EdlHbQ|-cn)&XXS}vjh);4Ehqz@!|oyWs@&#l zC2sQ~aGO2B6BfD6MsS<8PTXeXIlg?{+b|fnc`@TQH`uw&9)oh5lLp~7H~c2IxmDse zYn-^vJ7E0~-JssFi{<{SDECm%yQg=FbkGn`&nAO2L?u!NTGsnlWjjAzq^aVf+s>!| z3fp;s6WjUKLI>MfV@hRgXOy~S+$NRz1njM%HhG&9>-bOy?dnQ~vs@cwhV$im%5!3D ziwx)c?F{Gh^>Qf|*hXEI;q3okU^o|8AFKcU4Ck-vom&ugkOe1Iq(XcS+m9m>!}&nb zYj%cnNAd4rICH(hn`DObwvxfP6e25u>s@STIM*_Uv!Qn-F?uE1mcJ9j+0dK0NhEpw z8pFB3`U|7{(Nhq^xuKUc(tCx27{kv9M@@t`4G7X7oG7SjJ&qK%5KWFi$%~yy(HX&r`vZqMR#1&K)ft zoY71r=U_C?{}o2_EIXt5bkRsbGbp2Z*eN1Zdq{-pCyIwB{5kDDU3&-$d zR2Y3}TYa_`SbOV#`No->T!TBxvF<>uE3d*$e#nWNtg&;GKS1jbV>HaSyM8ZydR2`` zpI%-g)29b)nMeigwLtvo0b3ezBqRd$q8gDvjh$+xFvQ**u-(z(piuu@>`bB7fI>av zS18mPTs;A72T{)!*j8S_H;#1S8~;9?>dMGFQsZD8|27wYe66caeXT~MONDlNx{!OKQzscCe`8C8Y&S-H>bHBvYqgv>CrpJEfrk1O-i>b%? zJ?vr{8CPx41MRXvWsi~5WASiDk}%OxL#rxuOc4spnZRK z@$c#T2N;Q5?E8sbtZ`u%k84&{z6W;k{6W~oYurXc$5>1;)qj!L#Y?YX7r*AjE=H|! zVi#9SY5g^J@jfa3Q{Clw^C+#xJ`znL-6;~gw>}_IhTm+wI-U4}6P;KC5)fGLoxhKp z`BACJ&1~EFYuwD;8;P5FJ4*FRZf1e)lfB=aieLofrF#7S$g+xC-Vz(`&`}|kw$L{)ez;;WsbMLaj`i7m1|7?>+A{}dfm2}+IN^>Mv z-!BMU$4xRL&_Uciq8WQ+o+g+PcbB`&e{8TC8$=%ZfbA!jzHftdwf)RjEkvr8DZRHh zaG|$!V?~0U(!1U*&bu3E^d?ezA1QRE^p>|evvDjW^qi}Z?hfJR4FFw z!(fko1tqt#(=}g5*z@(%Mps5Ijq}^i&%nBn!5O*9!Nka&Tk2rst|+}4BbS(_oF%?E z19p1tC9WjRfsMK{Dya~0c5D#BsdXa}PBp(tIQ`);F?PdGq2~W8k9REgX`hPm@&8Xd zmKZIy7`6P~9ZLpm=0>UafZgSsCYd!{(X0q1wlEmiVaCoYS>T;US*s8WoQ+LgSl}PS z@>kjg>nbep4b~IlE&*VHE2D#JJWga1Gn(-UqewFrdnlqAx1ImqNHpV@MdtAp zILRVxk#eDAfExnsGvj zNHZ=kA=aTQ&3KPQGuF7!j1{G{*5aWO2hI3i%s-ARk@b{FGxjKUr5|dXXvR5*WSVgR zsFs7#j29mIEt+xtK35%~s+0M>&%5z^Ka%*p%MMAk$v9vOYjm)DHDLMreer7~-(GI>-)pO&1^0RD^w1;>X_&3qmfTtXuVA> zq~j)*IB31-U%MzZ7Y<*YzNtKpR>0Vs%24~9q(n`wIp`qVKUeZc2=}iP|53ty%5hpL zNql>aop0}T1>b%y3*}6=f5VM#KfzA7_jjV(htmEyze=~?V6_p~UlFrc{!&1r6MApk z02^f@ylc#L-B)Mc50kk2>!dzWrlN1KzF$L6CQ{LNcMnF&_6I5ZlTP%kE>!IS+lOp6 z#Fb4gml3h4zi{ihpQ(|l)&sWiW|7nERjF+evQxk4;Maj`6=hNkMg(A zC8RZqXB>6okP|WgzAo468umH3&Y1PW8{d~8H;*5b-262oHxJm7n#4F9b@$1AGP_v= zc5}-AXm;~}%_`OSNXBmNFe<9Rxd*v9fRUSJ-tLlSjYMzW={5qqMtWM2-rR5N#M%mx zZalGNa60pNMrV$7>^y`%%DbD9j%l>V zJz!hhNb}qD)L_U;9OwDqINt`+vV-HSW*p}oSaB$mdBrDv?F!2AjCyym z99k%ols~Q;*CjKkKQQ8J7#P$V7Y6m+O;_Va#}2}c_PBx@{d+jgQ`|Vs;z*_67SQBM zj2-~#*TI7}OU&p2+k-9y{y9gJy>#F&1f(UrTb26tIA2zU9XW(UieV%yW~&T?+6T_dra-)wc~MQgx|PH9zF z&0qex$F?J;$Ia@kN6Ogf>95^ljy}&Q(*N#KS0pdrkFRS-Jiu<|3k#DjJl60Wz9O%~ zn#nI3#kx$~W|8vzWv5JXj%akJJdcvt&S$%b?L38XqpxdG+qu!>yU0F(2+`3XNNcw0 zf5WEH@|uq@LZ~~x=C-eX_>))mau4D0#{;T)lSfTZ`55f9apv*5z7Zj3vOLSPvuFPF zv`1Z^zhCfPukt&r#&pG2%~lomTk9W)7kIN`uV_o58SU|f{F{pmz`jre*B|Qh*9TNA z(j>Rmu(Z{%wYhr12lurcqVJ!w5!D}MRo_b1MA8u$c9nHiF05+MnVezOirbxCziO)) zBHswI41Y6x{Y%uPs*TD`u=q^z-R!yE*Z+U>dM(+GjV#*8G@5MI#6!iw44T=U$!=sd zv+0!Gk@yiVI`FRwm@`-QHQ8qy@FyOQJCU2#gWVvV5rvwYD!IwNjfb@x*}M%SgE)4G z;oo&~lPw=PsazDWh@h=s1Xl?Rp2Y-g6vEoOM0#>QcIqx0P6J_h(#A&r5Zl){kX4qGQkWkel1t&X1nC z!0r6gZtfS{+zoE-W;gd6ZthMu_gOc$kG<@~G8pdW9_{9iaC7V3+&8+pXSum=gPXiW z`(Y1kkLgGdPeY)#s#zbsorH_Cx4cUjtM zm_skiczD(7thLMNUW5gA515wm(8F1z~PT%tXi|;!F2I$F0;hthjuZ)cE2q}=ycB|4?K|j@ajxn$X(&`7$T<}$|(fpOzU-GNk(8@ z8RYouM4h3B+(B*_$?k$A4)S40TDNruWl!sOLSZkf^T+xqlDPgUk}wY6CCLLMW5DAk ziJMrJqI(+D9j)^+K+-xdf!t88bI1+37Lvk)55(@D4N3Rk14;3JBgsJMFXB>Txr~cINQW8C(iaos3%(21+#pXA3Bn7zY0n5H9}H+ zZIb&f$=wG@@n4TPNLnOG9P{zlLJvXeA;Tqiq~yLGlEUwizN{iWm%ruAu*en{e%6StiB z<*DQ!A#%%Ueb_E3T(cytlAMFOrkjBBC5d>-N#eQ#BypXUWIXz5TE7PW0Fnu?ork1+ zS^!D;uoLUp$h{kq+_jQ>zvS+Mr1;-L8R#ZT>(=0w`Q)Q97@&4@E6G@nyN4w1TMbF| znAS8=Jw8Bg)VbHm4cSR<-0wSbL*`)(61mqylKTK8-S-1Y(waJQN0Y>JtdZRNNFrUd z_Kwa+NHSTHnOjXytPPYGoXDO|UQS(A z+$u5Rb<0+*ShhM&?^skQ_hJ9**P~F8^7um)X9ud@pltP9;7{S8cG;1Ke}hrZ@_{D7 zj+^i=st;#iF07l2h7M4P;~uDXjF!c*b{eE}eA^J$VCz=yLpbO7tZ`x;qHzqGojtxa zZt?9$d}Z*H4>^4+;o%&gH*{eL{3t&1m(y2@-;_RdZ|pFHi(w?E{e9sXcsPffdzElC zQaJhgRD|0lJ0R)4bo>YYoYNPJ^y%S8>4Q48r>_yel}_twum|z)T30g};r8P~s0biY z#Q5ZAhqwLsE|TMF=)t5z{z=z4hg*#Fy((5t#A%b9Hm!P8HWPb)$#ddKtdwKa3vs^)jtS z4{5zjvr%3z^A>#z^=!kRPtO`17dC1i-0Zvaho^%Qd`*GnKKPD01hYk&?V6pR_kA!! zoNZ7F{@7)fdv+HX^PHuPt(1Aq=wCH9nr|PSa;95@l`^lNRcZ~EzZ+>!?OXIC1y9rJ zyfwj?jfhunRhRPSF0Rkwz(`l<#&98E;Uw~xxDaxCM%zC3EPJ{;Ebqx~rFo_$M5#1|+VZPV+RkCIo`p)vS^U9gg zDe?CF9^S4ogJU!~$Q+E>wjh&7OmfO+*lk*?3ofU%Gc%>NGm{#EVa;H$WTPH&p+VBx z8IQ_9>?2AgOlxP>=(@TcK2**om$fru&GNw78CtVdW?Y075cgs2jF`eoteY8zdRcJc zRkm*Ca6M;9Z`Evr#eDm?`oH$Qsu$~p4*SyaVJg#!(?Q@VAs`<2yWesGeII zgja>$M@pXSyM@bqg*ZYq8w|31h(|PdP#h0}lTXhr9O~*AFru*UGd(HS`+c!@#paj! z_~F$Q4(-23!QX+M%*Ajjd${+C8+)*qj>W%NUGY{R-7CGAj~|)Bu1X~qpBN)u$MwEc ztTZoXYh+YaJ6Py=7J6IEbchBY!l*mE!FWu3I@iSlwuR~6

0qhPSt?8C z!;0lpi4xzo{J^b0S%N)Wu?EIks;dy`wG@|bCzW@>#^NCCkoS;kD_vw2}6-Rh4^H zsp9c$EM2;Cb-4oVVn3U+rS`Cjt$x^DS9!|IO#1?gs|()5>H;s*ykyUEYELTGp1wRq zc{dZ!P=)({hP{$m{weRxoZqL7ft@4MI+S|{K_fM0C{1nWCy>2SsN z9+F0$?{Dq34~J9D%>Vy9&-=d5^Le)(e*3rf+H0@9)^A<*THm$4zaF|W+)%#1Ht=Ut+9AAWSN%Jf%xNomqD8{xRw-G1g?9vi3l4513 z$ms}Us3 z^Sragr&4NEOWJZxxu!+V z_J4_7-}w?Sdr}imgV@iJA}?=I?_7zT*jh@6O`q}wed=nT8m}GWC;b|(QEqD@d@4Wb zi7d#E^=?<&)HQPbIH5fS`&efdsL?L;_wbxm*${4x)yEb*$%mz=4|3#2Ygjg=sdeCa zt6{pjg3@iok=3LgMM4dkn;!bZ}4B!kDk`BdO$m@k9cWVyJ&ps(sL^`spsBW zzx3R#`os?@B)@*qkHW&* z_(|sr@hu%T?DqE3c|X-i?14+g153{>4}?ud2r+dXibed4YCqG@v4T>nvxRoyJ*rbq z;N4o`06{X@vu(T3u=*7$?LJVtb z)RnMGxg5mE^~z>PYa_2g60bQES&*&d5_b1hS5huncrH!u!CnqKkZbC4i7l3zq`WR>ztdw1ucWO=zW9eaSbh{;*SNLi7SvmGeZ=`n zn|GCFr-qe=UYfgPYmxt7|9>s{^Vfd40f@U1EZ9rY;63@0HYw zoNCvb2f9M`E#xgatq!=Y-Z+0!EtNpy^uE&pyKa;^rD91;@U7Ctgr`#bg_g)N+7fMc z*4E4IGOaF>R~RJL)BV)W_}Z#~dHbC9(O|LjEsyOQS9Ma-B6dpLyd>Xp*ZKt(zvHg> z`S$C5``u!QFnuYOD#TKbeG0ir*Ak)58!>?7gRsePi^J zfbOFlp+1B1#uNu7O&_ltedAiZYdG}_&I+Y;*Jh`Rzn|iJE#6?n>1>l4JM=2MPHj22 zaP6P;=0vl!{G6!q8WOJ?=v3F3W3f6bLg7?6P$bo%4Xm++)}*wwhe$M+SJ(z?tT0Yb zmqy=o2I*r9%&as_qXRAH(X`^%!%jS{9~w|DF>fV#@^Qp#bl za#61#9&L9p7*#~CNJlyJ*=>m^OPXgT@Nc`nBe*QEmKh@w=r@HHQwvJ(yVr#*_uBDV zpSnsF<%7NgwaZE@rAC$AUmfU;9?4p7@3-zHOF`V!gPovzK#i|h2CaCHu7A7Fr$&s7 zYt&Q*W}^>nqFgc9bQT|&&?JGIYJKS{8EV9f;Uys9X!k#bQEmG0K=46d87PpF(JMe=&9G{s_X zF2Y?A11sbnBHkT)j9ctC76Gwo1sk{XidLWMThNE|*{-fW?&WjxXI`q0sBd6F&*0aD zE)W0UK=QZqnuPFc`FDm~u4#vK?DD>sQj^j+z$QfB-sxLKWs|Oq$J&>xTYo)tv)PP( z*-d7-r>BadcTn37wnrl0D6baTRjBoU-lt_aa-{2gsm@CZ4RNI?xW7l7Zyl0T2&)ZS zxD5eK+|VXQP&=rt)KpYqMqep;h8nL}dcSD!U~94G!-(^xLu#8(`7R)KvkoX$8UaKp z)g${3sdol}TJ;vh5n%v5)qe3$2;;A<<0X{Q z3iK@Tj<+1*Zw6$mrOmKQ-mMwon9wJGNG(zSVY9=y&#+5df!=-eh;z;%1$#>S$YysK z%ALJ3E){#7xA@l>tM{H)8J02IvJHu5pZ&x}K|Lbi(Nm6JJf1?mBJ`(bF13q(2K0{h z46A+7(-MU9JB3iWccfPjEcAK9y=F`Be=Ifn$4B2ITRG^R_nkwk6r|bS=tZOV?S=cxIUu;!Mr<#xpvO2>E~` zLNp&?WCG(H!~{^S9XdJUj5$=XUyD^5)2(-h8OrfZWvT>z=KM(=+y9{tQr`XH%Rcx* zs=-GBVbXnSG7EgA)!17 zWiBr?>O6W7j$>?k_>5k}8R0m_UiXa8*sFx&NXC8idSq*aAj9{S%s^h+MP=*lZOJUkB;e`#khtdg#Duxa|w)zVR=p*AvE2ue(ihx#KZL_l^6n?Fan727BR-sTd1$_#q7A zM*$;affx6$^T1_{LNNGy{%^uyQ2j{rw=^d;1M{#2kY>nI(osyP%+Z|s%aF9!a1Zj) zV1gZBvWe#P%_MRER+8bEqvmoS$q3BtqG>1jHOWZq!HTMfFb!{$#C;!-#5~U>l2d_! z&_iC0hoOiQ#=}4odLtyo=Kv(d=K{Ioc?p>BC3zDhU0()C*UP#4U%4FM(ic?&`Dfhk zkP>v-Gw=pT+B0w&*H>_TDq4oUtA8$omKH$c*y`$^LA zZl_3x{5#j}T($L%K+R za3Gu5If@QDe###e7s|4K=MUM>!b@PG$Kg<>UyCgr#p@dfr2X}uA~m#ns6hE z9ZPR|E`?3cRBQ#O!kjAwFiz8%d?=@MpSwQ`;`hGd2~zQg`SWZ4EA!`bXJ5m&vHbV* z=SL&h1INst(|q_7(wSyeQ&Q%QtB;-aQ-Lwv^f_i5A1r!CBlPzcrC@K!NbC{0Z^+m5 z-cXi#r$+2wT}&evy8a~sja|^_f4?*+;Y*8gOCKAG?k>zcHe~7sA1r=B-GzBzP-pYn zxQ8*QU&?FA)Agr{G`oFtAh-xjXR+6HT*@N`bye!6Ou;_6XiDrd@ThlpfT`HUq@K!| z)F*f_sb2*?8jX2}2amcQD^!Hov!`3~6!yBWIxgi3F`~WRN_w8=5C#U=e^nSk>inI&uSE1haLFT&u#-l*H>&p4ZFp&S`r}+O@@;*G{BUC#7%FknX zo^pK{hOC^E+z$hH*XdkzbJL+9dtP_fzr(YiK}F;4wio&t{FLV&!}+fe<}v)XL1!yK!|vs$Hd7DSh5M75ZW5E2UG6eerOf%rl?QdFCgA2k!2lO=g%j4CxA$ra)S`^s&U23DlOy(~WJsXRu!J}FEmKKi7LL#LN?Qz=*C zyJlM|#+6l58~VuQD~xEr-;k6ymH0zrm$VlT3C)_5E5R+Vx9-7tQf3?D(^l@5@V5H( z+ZZpmia)XJ^p)Kai#9vHYgk=ij9Mwl{OmuBjoOPC-IFqsookw?Zjt$*Hh@7h+40M! z6K8~Ws?RB|so-{3o*21JjG2QO=^*I}%;^aJ=eiiW_M2lyF2lhwdMXZ{d21b zR#{Ud7{sQMy*7j0xPTbl6LkG)f)^NfiPxRjz=)H(=r+v6fRnrJfl*d>*=ltC*rmR* zC2tX!$kSBvZnX-p`!dGs-d9wZ`&Ozrf8C+jwBei!AxU|!o_~e&v6nGUE{pyB63sO- zC)cDd?CRP%oO71>^W<$eZY#_k4|Z-5?B2mBMuOR0C{!#~8bRU~8(~;w9$|@umk!;Gb(6#N5YZu%^!j$Ecr!GE z{ifc?#$#11XP(&7mKzN|xmSlYRta2V!P!=O72E&&wixj_c+-djvn7wxo5p#Q z9qsj{DcVn>vuCo9g#FQJNS##Tb(7yQyT{GOc?o!%)eVjHs|&K@$F-;0^_o<>2IZxZ zxaY5Vqlape7jQM7T~*<#=(>7RXT_Q5Gi(v2B|Gk}x0>cLCb)TdG}9p1 zzb$RcCL2CoR$cZ~3Z+!whs3^DogxhMl^)3z`}Nv+nR^A9CynknT{NDy5rQO74a=2Qb#T^su>^;DGlAyL=p3@=RvQ z>dsHxxaMRYPUKDbLMbUPL6UPwD=h@S{DnHga6DtxNW?HGw=}Zl7v@F4r>@^Z{PGK_ z9PGYc1inRxdTz*KK^m$<@1t2B^_Ie1b=VnA+F}6 zoXgq7E#I0$%!xI`&pOqM@+{tB|7EFcUxg?`BhJ}vZdNv^+M?9?N-5E!l!#}j6pc8q zV@&fw9dF4z^QaG!9oID$=8E&F#r1Ct?JW+wvI8}{B{OU@>c0)F1Y*zeE=hXt%xK@s z*+Kh~Bs&a1FwJMrr&cGrWPaY{z65ZCe<-~vfdke4vDMw`WSe`ti0o}m$pYBh?Xb7+ z(k=Z9OUc?I>&V)O5BBoNyu7xY0<^k<{cy>5IR&};v_rYa%l4yurlNd;tB|bjp|Zuo zKz+#}R&UasdY~!FM7p2ud;wS5a^~f|h`Yd5nFFp$J#5e@&N`Hf)b3u8d7KyojotOc1~gU5@8G%u{{D`B*FJ_@~PyIi_T-t@}{- zq8FW}UKK_)FAy#>1Hn-rd>brFgW5M-)ft(sup=t_9wkbT=2E>YTdY#=?!XMR#V(Z; z<_4$9Z(^|*mb{v(N3W-iv216S7Us^&(IggT>|&XtdK z>*mPE)$HKPs3=xWf9m=nAd1Fy5li}w+1S(SeKG0AG$D2)_9xM&wV-u7(ur@9@@{RX z^n~R75vBX{sDHeR<+EhR<-Oo0S6$JWMCmKGfV(zkP4o3hc`tgY`@t*O-&_=d@1h5a z8H?^3Dow}E`plubzX>VKos?RaiuLKVpBnoLlG)lPmbdgNE{WewEI-t*_is4e+8627 z@=+A}JbU{TR`BM|DD=LT+Kt}C3jTawq}KKkv9zL3wvJf8(FgL*;Jn{YpA_P~!1W#6 zK3M|CCYZjfq#Lt0H z5TES0f3L}OiIqYPtMiA^TQ;X%%5iTWC-Cx@eDRija=+zLx_i$h*|8YzmvZF3OJOc% zHhro8LS?WmSDgJhl{`V_Nfp3hFjWedjtvEu2T5;8nK%n;eo}({8fB*Kg~Y-NzHJ}0 z0d?oS^zSkrR@AxR+qT#z6p8cwIB&OQ@Hy1Jf^e5a7CK?b_h^`1?|-TTcZv6c7c;E+ zUHlC$-w8%mab{AUU@BXTx;4TVrNXp^ak9oxy|yuTl#Ny0Xi5`$m6kFLeC0?n;-^K5 z{k4erX_FoA)GBEvx0C5eGZWJ6blI-5gRGqlVD02C>|D^Y_w`);>`UqUFj60mFinG|8zdv)aBWy&QV48?Wu@AMlq8_Dfdu)Xrz~kjBaZVj!KdIYaGWo2)HNN>n;_}Ia;^r;d70|Nd+YX7TaNywxiJM_xrrRl zX7)zQ^!L-ZNOH?zB$jibr|(s8`d-_fM58bI!ZZQ>skZc_^ft5_x3y*JmU7ndxlOO& zYjbwfqd7|L)sk18BG-(9{mCM-Kp#or9WOYuF}E8Q7IiefSN`(7?7XAh*st=R-GLT~ z+iODStEtq^ZFU^2kI2>l57AuT+(Z4qs>R6{m(5%u1}u zXAWm;W{#G&?Tq{Q>9$$Yt{&9Ls@LvuU-(k|rH0{9+r4z?+L z>20WYceJ?MUR<3c_(we(+?LOjB_l(0u_`Q$0Dy4zGYSJ3A&jce!XfJ3PFKKNU zaTcMMCm4Oev>dEk@a^{vhx5w0<(|Jc6gvPPVxt*kxzb{H%T0FFHwv-mUA9Z(C@;aU zApEUQh$8He5Vyb)(pU#u?tFc|8z1{w#>d{<;$8>X>g1jZaT^QhdtTkv4Yu|dWw!Q* z-o)6zEoqmX|7fSP%g*!drx4eFf+hXp5o#+Zvp1T9wlLYTy-_uBL&jR+66)x~Xbow1 zYh^6uvhyp>xxNlxm-6?5QWj3Xj#9)p*Nnf{fQ_5j)=Hc8`&04~_8ZWKX|UqNXhF)g zpE#=;F9M@-d8CWZs>WXZ*SHij!rp>V7w5(8H%VHAX;#9F6oD3FVMdxHv3m5{|18gQ zHrC&!_(hd^Z_#hnZSyMAKCXE}{Ur7ZN%3n@gXg(ft$I%3d8RoN<&bc)*iT=|c;td5 zgP%U-&u{w)DLyyyGh7c=JVVkPhdbVc#`cwi=5iML`If4;u;-c<8~l7z{`?LL?gr(Q z{E)}=mFXEdf{1B9L3?f7LczocNWScQUY)2hG7?s?>FmzR;z~b2PVk=;ELpR%kR0Q zs+iJG!=;`}UoMSY25}k8CE;`EJ`wahg30FmX&(QPBN#edglEm{bk;L;E{tC~J z!CWipEhG^Stfyt~q#QKdXl*RFiC`Wl4LaSQiOxT?{>mL z;g`krY_5L^N#R~3iSUB`WVwtao>Rv4uyBK|cbaobTgNvtFT`U`J?)T+6U5? zkwhMC~51JD6pyXo~1ocUkL&Hy|L!xL47Opp=%pOHPBCF7Qm4B!b80O18yqySZ3BQMg z5?(6K-NRdhx(>yKg-3BAe-z$5__>GIgYaO+u0sj$4!F37SB3D%)+l}yjuPHOICl?^ zHW{OLRt_b+2jJiyUb98Qq!{3*ws@b|8wKq}9D z2Iub2r9F!*aHID?73X^HD>zrXVZKbjXk7z0-txSwZMQa|E%x?$Vr{iT8@@w(GM1DQvf&BWXRYrad<&Pr2=H(OeYjN>dYo6fu3&fWbf&;K3n z|0UjCc{a%h@!r42PkHV?aNdC5G5nJ8d(=7shK`F^$Y6Wd-!fXusrdRZYs6-S@pT>*j@-K!$pl3q*)!p*^@*h*@ZV z6mx%9$g?2d7 z%=@WcWIw|_X`(J=(CmIS&8r!ob>YWmmV7*PlU2r!(RxN1J2n+*A!EmAM;IaY-FBL9 z`Uc~_7T0*PiN=3{9jii4zR@t5VGJaP@QD1JFN&3U3UyRlhB2}&^Ub~hpjy@llrt1M zW+h`64(3^T?#h^!xrLd8_@TX1kmC%~lD#b{Zzf?{Vp}l>u(1DUKqCP8!!cQM9!FZ+ zfXN!p>%u(U@7X+^kI%Nig`eRM#%0LwC+uq+EXDl5^23y@cu3eVm{ zwduDlYh|>ZMp^_U%T|WQT3xJlL$YME6lu$kVYTlvLbBYV>(5r#%1D+e&kZeGhICWk z10;)R_qG=1tEb9exh~hI2nYt2Ysvg|IAD zgk^E9>YuQUYUre_lQa~->`emBPPT;KZM#_#gutEaio)kTGQFQtmttvi&MmXzxN5`nNqZ8`3Fa;#J{Th0~lu7~#v5r62T zl~TV}FT z-B{Co*Euim&5ot@D+`QMgQUlLs6JW(Ejw-;*8A(dB)bN6(QgUGHf!}ygeI`iPB*OU zMx6uHXmmXg*KvaV>aA3lS#kd@J(n`R_4>ofd3m#RSQDHyFLOzI$&k?8aB>ZLF<)%` z97I{;@LX6t}bHp)W^5TEz&4XQL*ggi?7%J(6W=ksiau; zaNf@d&1jL)jIj*OIFwKIl#FJ)t!@j@j3yVF(ZtY<-{%r0Lbj6;r)o6*{EfHp+FQ?R z?__8An0F4rJ5Os1qME;z=8&fee(j;JN1j7^U z-se@mIPzsV0ET)Z{55b-J_-WcGPt2wOh8>~I@B+E@9114 z9m(vFy0Phn?xUn!!anUUA(`yhw2zQa6FS@S=H?#B9m;pZJ;AyjEQvrlngOh5Xm;?L zr2GY$RQD$3exLhI$YO?i3TPe5mmGFh%c--I(kaa;y^*S3Pf}_>Bt&|j7u9WPW$kTg zln0ZfGVCHl>76KT$~tydyJ}PB<+Pszy(1X)l=7;d$1Fq22il(ymkRV-DtslrjJ1)R|r#O4!km$cy5)*;k(i4uPt~f1QoRgL& zM8De}nf5hmV|kZ2^P$M>(L2BFh>&8X71Cq571F$%yAbX_^Iw(br~66z^D51Dsfr^D zaTvezW7+rpeNVyuy4jNr=hn5MwO^Hx1jj&R@!|Oj+MC9(TT;UK4UCM>p_RWOWL9Xl&ohsCM1Jn`k3ja;P3j>sEShGGgwE zw3^-s?e9)%9J@0Pd~1DB+mWt4{LzLyO#9g120MNT)1n*&S&!!E+XJN5 zoK(D(zCA{IG`%$)?QQ1MeYk^mp98A#n<9;)JM-0VyB`$nZ-S?i-iF?!w`AR9uh>%H z(F-#z1FshUP5azO8Cs$Lo017bnEkbXp9h>S4 z8L~3G1o*lLxmHZdL(lP^q|C4ICHPv=EBJe`=pb1A`Y#wSZESz-!cm_s-v|b4e|vFK z{`Wu-CZWu%ZHdsTS^gwDW;ChL16tgqj*ROIcezG2ZO9jamzmq7LSMqv7vZ(}+r%cq z4~F#V;6JWOA334#(L9YKn9^*szFnM#{fL?SET9Vlbx?M96J+4ojkMN8m|4B6*pNXu zORb(TBM-KsXRGEYOy*;_XhW_SFqRuKHZW94ber-u@|~4^abgX^V_AazauMNPe%Cbm zy(!q~t1&ulS6P?Gmq_x(ztoQX5=nOa5iay4QkZXYeTj52OeK2!qPpOHhA{h8Q(?X& zeV-9F`Pk5`X5@cVrR3L5ZAiWcPH+v!38pdk#rWnxy0)>OZ7SaN6;{(X>6$5h>j*eVEuBBKY=N4ZrpbUCCf)CRhON|jzmfYxpQ+;Bw8!*sm%86BiWb zJ_fuiTD7#w9{Fi9=8&G}Xq=m;nK?J}p|B_D+ar?t(;RV#THzh*tEqDT=CZTm2(9sm z#rIVB7%U;#&O1k_E?JIiGTuw-QRhS# zM&(oRA@EzN!vXhc)v9wI6d{A&=`hGd@1$&+{@0Z zju6@^>UggiC5ukzIb;JjUBGHPcS~q4P1sUGh4>kD}#S*^3s7&mZ-j}M;wp05lx1BOVR>sEe z3BAD$87tUL#R`5@Stmw)XNx_6k3wB`9(nyx4rZFrhKMsMMuj0)dW|E@$Xf7UluHXr(KZqnDkZw~v;a1&*h|xb^t!qb|vg8esOUV_Z(dCJ_?>J!P+M+mzKEUEJvI{En-9zdWRdb zsQnpnzJdMsNEahXYi*-_*G>R$H{cQ^9yjTSl^ zalYO{SiOn3H}J^3+-FiYU7Xl3UAmlqU9N10ayh7n9bR_&zCKwJdt#;Qa_itv+i*EQ z%!S3IG?#sScUTz*yzKnubqcezeLC*hbn)-?a+q>EFZ=%TuxyPqnl_5~OUk?^?Y1Vt6gSZ3GRoG74{EEj@e0IiUspRX@}dUh5>g^huv2Jqw&-xpWd= zYJzzpLiGk-Q(Ma{ewLVc(_&gDNVPrn9JP3wS62wuiUjJu`RFCo6LvR?yoj~gg83hP z`t0BK!Dg$%fIIJ(DDN+iSQamEB(hao=nadoq&1IbiSuZr3*#XPSobufM_rh$SI4S5 z5p%P$8b%%$M7?Vz>nqHki5ix|TNE~wzQAE%BO_&4KSpj;)}FyQmMt|YS4=`Zh@PRv z-e}d#F3f!eYafK9rRQp~*RvRT1IB%XNV>YmidF|LBaLKP2AipkG|$To1(Nlx!K3OD zY71hp7DjFrVyinhTh{bS>Ey{NbUuf)+dV-E30akQy^RxjXahqS7v|9>2wJY5df8NJ2aU2l;^i)M@%}o9kg#-u$ztrU`O($oGHgrqlIk*GtLQ-*(gKbdRrmH^rCYZ=s2Ac4!5_ z4%k6+?4rl6ZM1LP*!KmP$?c$htl0AjhXc+ zxI)QIWr6mIOJF|bKQ!+?*F*oAhkl=jp5vjf_Rz~c^yfVE7d-SgJoG<#=qEk&&ph;A z58dvef9Ij=T(&3U4gx&%i5_~ShaT&p&-Ty>*Q*?qzU~+X(tnBTpQ&!sSg|F5_|qmq6IC_}6ZlNWS^PwhX2f0=aLKMTz)-On(_ zxSz1abbm8R+;0HZh3;DdN%6P|lH&0!>1JSLNrw!BEz)%pBwb%lI^1t39daYTZspgj zASv8WNlpXrA^I5)h zF?cU7TS($P7`7Ph8-RPI>pMu|K878hjdUR_@Jz&$B%c2Wm#0X=pI4A9?<9%qyC5lD z2@_1|%6KTR1^$q(BmA$q93p?ni|@%FqyVfX@gS}t34awNk$%TX;yIslY3GvgyyPCl z3CW&}dkVH7$T=zm6k^2=SqhUu}w~$1~=qB#|2uY+%ElJ!z#N{v0S)=D|Bni7~ zB?-GbP7-$4O>!QtPlUvMpOS?CizMMbAAK@o^8F zf@7c|>2UXl#|e|+&M?sMk7Q&zl8i~xRVI#shRxo@^<^Y+^G2>)Ng^&)T;EAD41fMR zdtnj+nm3t0vKOY?RX5Z#zr)Rip`+y{*bOr63K>5CFT_TpiWAUOy87(1aE@$q9jHdx zb;?Kb=f$sBAgRBv9ORFVCHT?(7X0XlhOOL*n^5fWWgy!d6}wFQ+{3dYEV@@Yl<@9{ zgL`;Zlp*|Q;i1}cVTB*YxqEnX@DWAkq#R0k55d7byjlcCHcjy(ck-vl?+N_e!&`yy zC~cHO32!SL+`~KS79M>^DdE|0PT{HWqoWMrA!%F(J(G_8_>n*5sE5CI6$MgxZUfHU zpL+_=wZM(u168-{xkqrWmb;5M!&($1$~Ejv{-Zq0J#KWRo)QlaL$%D}NzX+U&z_0! zTt~eLb+{4;T$NLbhr7SvX=s~Wca8d+kvMl|f()Pj&oI=931;(uh@oCXl@iQO&bMgP zRpT*?C$Bq2lPI8CWO+*IF&n>Y@tcDms%0S^zYP4yPP6b^iQg*x==e{=SO~u<_$|UO z6~D#!N%+yxe8Ey^|GlsDc=MH#R=V;+d5C{agx%yNOgq>f7cPWPOlxW14?hdzS9Yw7 zN$Xf}dU4Es9a7BvPIY+mh3kEEbr?ykjFz~_n64stjSjq5-+ky+WvmVj5h9``pR}&C z0YPGgu)_;%8J9-_s=S-+udj-Ev%}A(+egn9D^%gyebJIo5g{p09@cr4-`TFSefAMO zU7V;q?cGkVDj#rl{-sZxr3!zskM8%Y@(1(AsD`P?=XVKQGx z^H~Hes4%^+^CF&e@Ip5WHL>gKyy6sXr#Z?u4Gb)C#VMCM<`TnK!oFNXT0l)el`X_r zV>6CVqqkPxBCylX7MeXVwW?2u-qWs{A0nB-gx6KB4_*$orq;r`SOb&R657*cM$QyCF#jT_am0 zNe7BKJE!_CpZ`#_*dd#{%$2H@;=WNm*)Xu;z7uD4Mj_m{VoI$(!dN+JdpO%sKt`Kr z*bX04_NpaedxR7%P2NlSqBfVd$45@C)Ptw-9*h!;c59K2bE^Ioh@v}+p2zZeFYs?J z!v3Ol-Qw8-IPMu@L!i_N+-YK=h0xgjJ5KG*oD2 z{kGqvzB^VJ&=nCn>@$^C)QTUozglr0lMky(A+4&X@V88L4_4=l{YQ6<{@a4{H}KoS z{weNX@epPGW0(H`z2ZZWTiE@xRPz1(s#&T$VD$TN|2oYh>KoLgeGF#RVHV<-IxWtB z+izA2;f9D6K&+^S#hIjg$2vb5xBWMLQ?j4J?*_ZcP}Zm0spq_vLi9rW!L0|~SXF1c zv8tMzezy8AI@QTt*ei8aiLPp1eI)pS8ipL^FTQ!f=dGNt(ii0}tIf<aAe+(e3YUyF-x_)5PCMD>8U1JBd_G%gneD3%u}1}1t}#MXq^OVxsXM{!v7v{z%QgsT^Zi3z%CVYMgD z#stDH1?+hxz#_q*O7h;##ZQJV=9HgcS`69A$E=)h*HC8$K!-%%t?U}_w`i+wPYT{@*3S|v}MNm?g-8n>}lJKwiS)$G)4OIem)b6k@Iwz_ql^L#!I9S1iYO%j9ZR?0wSZV@k!(_t&A84o?Gj{l+tlEMsUWCtDu@fV_0`4HgZaKSmlFf zNVgjD&O{JL(>*aL5!*`T+67FIkwHkOw;U|12(61bp7XNC`G5#QhMn* zo7Q4iD}#B)?Ph5bZ)NmVgyEaS(!L}+xH3eVWSfGzJJ}K2K(npU4dV+)i)y&RVa+wM z*olU)GhxivW=C*?DKe}wh`H+xM#%g)?{=#DZm=5-E3-ATyx^8iZVq9?4R#B2`@RRc zAy972C?$&utB{#ML!`TiUpUEFVF2r|&u2(^lVG})=Z3-&yR^d)`%u52vf2x_niF3G zm$6_9tA4Ff=A-onzh3~X*PquL0sFmeVj^r3bEuy;c-y+p#;8=#sV>oWj@#+|LSHDA z`LBy;zqhjus;fUdW2_b;zW8RZkM9ojPkanJ)lyi+j+7JMMED#X$Sj3rXpP$!+f@d{ zZwjVfP`56ol`wG@``24krh+M9)h&#p&b!h*CWrbI8+4TX&<2I@ugQu^q? zK&fHpqH`)S2AsgcG~f%T<7w!XTI@ZgA($73rQ0WLDVEHU0Tr(`zQ*1sw#KmCfBOWK z_`rb8j{F9yi~L!QwxNh@ce5j_L8;|7JAd6^oDpMVT%4>w5VU=I*A-Q#!NWPn`k`cu zIv`Dy;-#Q+EwP0r8)pP}i8GC;NspfuR#1(5s$FK|9BmigMw#C17_2uYBb5VoNd z{$xc@@JUt=+TSXQv5Dbg0>S}4L+Q`xVkvB;FG98S`O>blrfcd_tOJh}Pp-pNGww?e z!(%Ie`oO(Zmn&_>2PMG8$8B~_Xo#^H;}#BnTzr>=kTpl~qZC053$YRdHIwl=W1M9$ zc8i#Z)QElKtRT@_fY)+nf7i5qbKSU8SA+L7CSjp;rq77Bi|QX$zXmPXpNj*teX0Y} z{&eLnX-1U2ls0NZsO{P8JY28558^Q+X#32r6K5yhey0?)>qE)!d1Dmf@dViFyM^|q zLBUG>%>w)=f57I-@&|0LS#tgmo9i^Nxh`XEG^OkmSFb2s(w*L zEj0O9l1Awz48B`Jx%%K_%2&ajQzRy8X8Wb-Vwa}P12epSCixWxZz;O6N=($nE=g0t z6+0gLOsCd7L7%qSd7Ve>4%W%BGxw+>jWejUk200Uv$SOS%GyjyQM_BNF)FB1wsEAP z8MzvbT%|NrQ5*)kZjq+#lTkC%n1vVDF$-52XAoOykZt1gpGqOSo|HuMyi{E@Qo%|V zPWKCgn@Yl}S#JdRU|liQrSI4IAU_Va$*CH|>Rw9MJ9x~4Y_x90^Xd|}tG{bA#>Lo1 z-)kyy$tsq*+c*{X7T|qgrzo?`O5b-`DaA#$)6w;TA$7*fv;s`sV{gL8{f z*ZEuQ*A!2z_DeNXUktf9^bf{HgdZ;n@qS%YrW082OylaEDbM)THX**Yy#Y_y?2M_C zOZDHaEcbON)jGeOc&jH-rk_*F^g`GwFVm0En=577oe#NmAEi?`$~46ct7aO3B6l`{ zZ`D189%8=ys`vDYc>3HA-5jdf!@XlTKzj(DQ3X+?khcW@WK*SXIlGzvuz4?f^F$vh}7I& zk{-9zZdONB2DRTASr8eCHuMI&N=N*v30tn(cY~v7LwMba`V(ixTbnN|@yUt|0-LC* z&QOiqt{gAvtCmY@_RZlX?M@Nw*;@l@gmC}uXm&Tk{mf>4YCT-BEHUFVEC8U=U> z{G2x9m6au5QN3&QrQE7-n*o=MHi;Ois)q&XoYo?qT8)^^tIgR@~U3AZZPp&i|r%twx^*PLZ z3U+&u?SK%W?Lird9C7YEgnHD(S~G#QW(-}+S~LD76I(&8*#{*kY4)`x;nfCU=zJDo zKm5IJt(u9qYJz*KHWQX)pt6jbnOZ!#JioX%>x^+bERdB0jQe)Zrbi^T z-Cq;xjlRdaK<_(-qAb#o=H^?^sWbzfjpx1m3^hy7HL3$DWu97Zj3PbVriA3XgIYQ4 zAa4C({{|t5h_?{PdNG2DkcEG<8g_=2mx9fh`aGg^Xt43)rP9aLmxMmq1Mn# z0p-Lh>kUrXYdg?hR^kk7!b)#(#Cg1B@?NBtF{WBfh^<%>CWcdut}(`x%k|1;XDjcm z1iEVO4YdI_IVO{`18sZHnEBUCSPeZ3J+5+k-my*tzQX(?_krF#(=1VHBh@Djbeg9TQj+qUkd?cw$N{whV`HP~KibnBajtH0x3?=h$%4mq zkgX;6dDj%KOww+4nh*R4te>-1x79Mer%O*!#lbrS=PJJ7d z-OY}j?As?5YZ{-c9UbSm?5uCs&uKg_sB4VoNTlz4F9~^5Q3-bQ@vxh_`s7mk9a52% zbRbL3F59Ml{cF938c_->7h*;(zP?xfE~MDeC|L^n-Hz5plWJ=$p&F}%XG0+W;Z#HHDQPJ zHnJDgofg!cmPfFnG^&}Jjysn|NZvSUa45jXl>b^U;MoPg~(l}|Aw0l@} z{nd80Msxl-O<-tE2$+u()B6Rn6}!Ga+%IUsbTdd_l6!_hWSF}2+^uS2E?#rm zb;;eqwAzlsdZl0Ei?9|?VPQSP!a_J&+!wW6FAQr_Q_j7;R&~Bu_0stil{o=vJe?RB zS~_;29oTbTuNjFsc&XH}^xTRde9?f@ybj-Tuk`CR^gVaf{$SCh8pLg$G^C%dv=ESs z@wSV14T+`>>6Lz8UjggVY7r}n(eH*;cShUQTJ8BN?eb7t2)&hISUsQ{79(C7*3C4e z-lL~?xkdkD{%gp;e$TLOif&kc+j8u`kM}(H&X_mwojz51p)VHf-4=Ul3611{FZqbU zb~o0}9s{$2zP+XYdenJ_(yR8~;IOVmyV>N{Zf>V`Q(r~xrjMk4&QMJ?CdNN%yrdSi zoPR5!yEQ1|{$O5DE)A#>vjevu4>RnnhnpDrV#>Sii&*Iw?0bq-*WEZ-&01I1vMxJ1 zFt1c;S(BYB>dg^%V7CIjX~sTtB3i_xRtagYszgf|Zo9HZj15T*sIUxfED69DaX@82 z4Qk!YMGor*uz6R~=!rbe7GyKnRYE960R($i5oSUn@nwp-?w*z)^uqNh6*F3?|LOka z_{*+4U0+KdN+Hi0ulCzD5j{%X6G1!Vp6K$?uaoOx(fE4w{5sj>_$zAGm_W1C+xPF< zwRfz-w4(zb7Kc|qja~Hxdzm!`a~xEgTz2Y?T#w#OoI0!$WkXGCWd$$)%Ch#OkgGpY zM<^qT8hkl>BR4;M9qEt;-g~rykM)G?a{nS4Er)XLFSnny=zER!_BJ^-G$=KYt##~` z2O5-?VPf`GJtt5;S0R>5y1P(v{hx0<@2l=YX+1GiYNc8o-{_{Alz_^X_7KS%yxf0l z4`n@x%g&}FyiT%?ID4tqUX$!N)DTvIaiE&d4m^?4e(`y%m|Dl)mEQBoJ~=I(c|GuX z8ey9w$y`I!P73yqOPVFav(v#urS8_I9)ukpFD9#;Cy9L5kd(>dENiMJ;U6^8Hd}4p zba4_!Y>}P@8yhv&)tnfbzq_&syTKnG`^Jv?02@7fVm7rLu^0j0{Q!kcBj4$(4}Rxo zy6pVT;k#TTfz(QaXRN{BCigqll|dEZb=2#mQe>#kiquz88IpUR@;cHLbzV{xVx3SF zP^0uYN1SiBdZ8sx>J6-kizFVcH?hW1pD=Rq*uMCEkMxFB8<5vSN5XA^)zv9S2d*g! zWc?`m?(j(ss8n|ZqKpfJiA4dn3h9?qBF}xb4x>gW8RIJ-?j2t}p-Nmdv0AXtE?FOZ z;%rFnUD8!#@vQzvy}LV-S)WzXck9kub>pjO&C02E^l~toOy~6Vd%T@EMZh;dFSg?I z_VHEN0NFggd{V7GO*Ab@i>VULG3B~w`s%Qp?h38Jh<0FQgK-P`E#R|?^XZDIib=(n z>BFKKoYrISRD`>3wvhy#8TN?eh8@31VaWn7jm!0pm zh40LoE)1T-T06`^*joA}|4@9}SnOY+oa#^?2Ud??gx>hzBz)0hmz1JFTR>$Y)<53^ z>ya&I)s$|$k9WysXXD{OjJ;U~Cu4MjtSz828EdwFIVE^!U{z$n2>K2sm@lBQJ?p^9 zB7f;AN!Kl2E6&0w!L;D^B8*?h6vLJJHrcn!IRj})0p0kO3y)XGc4dE2C~~G zhq+Fvc_w8WZ1;tZI15^gG**i8{}1ckVF8ui6^8N&<*4(8%g$Tc?hf|r7yaZ`-q-iH z!>SE2cC}7-zDD-}Z&&qbSGBBN)&8Jeh5rJy!|-1P|4O^6y;?i0e|UM%%_+v2d#G;W z=VNqbEU_WU6=~g89;%OSCV`cxZJ!C7VSqm-l~>N2csLautxzU=%(TVVAY{VMVO;DE};GXd2)v>d@ZCZ;0ybSH*Z91Yk` zwU%solY5Z2m~T?rxy$HP-x@}BTthEbT}9BWng*?)x2xB=ymh&>YRVsaWlPtzQ{2hk z<$g)BV@o5Y*Z4F6Gae((_BPKN_Db}(-)KY0-u)!T!IF@l`MU$FpG=9yTJy`!;P$cQ z`m4RMHR07Utd$sXHnsfJ99AISK#0lcR7XrejK|{}joQTT4;gJMvx6j>OEFfaocnSe z)$1o|RVufx5$7*jbv3uH{sikAJNH&TZqqLK_Qc+D)(TyAzI$l7)QS;|7X>BNsI%;_WY(k}>I>?6BXNTg`OY-kiMP7+~xuZ>P85Z^F`0VLrr|l3~!e*zb ziSq6Qu5_V|l-tWyJ@gjz4oa`1>QLw*F_LBo&Ym&YROpY%x%cH6ovm1s@4B()q2R#n zcl8BU&yn=_hM;*f%#KFPLhm4;!XK$o*7|RF4Fnl0L*vB%ou3K!{m=Y-aX(ERih^pR zpYJ$FQ`zo_A8{^F{9@>Z*dhDxcGKzlyRKxA zub*<$>3X(7zMGJS^t?50I^l!pu;BN@wO6G90Y|P*NZ*$au5Aw5537lZ}ZSU_0W4fbd4)- zWV8tbB#m^M(&szUrI@T*;Db%{vj8kD9G%zU?tf8ey{AqAfNFl~9in?D`argb153jxd zf%F0j$;HiZ|GHnTTe<$>HS_?Fby~FU2~N0cUCtvbh5J{n%71uW_K$eX%ztp*N_U?K zl%)arMMQD!2Z8@^)fm_w@>i}#bv+ z(Un4iJBI`-H-xi)1^GzpSB{f}PMJ&V01S|{4#5wS)*(=xG6R5S;*2mun#g|)_FN~4 zbuZL*8SrO5$vEt>4><#C40c1BA^lWvk4IfX66*pskpwW1*7?wS23n^>>nUjcjRD}- zPr3X%NdRF(P)Cu>g`D9Bj3J~MaxLjt1M&#zkZipT0JUDIx(xu%hLHq#b{0v*cLhnr z?;=S6YD>Lj_oqnWJt|1zJ@$}@Uk2Ik7X@;ct8GxjC&i0mNKIDw?ct1!pnTT;IcWwl_cSo9-+7zk$nD zkaS-zB;B`$>+8Ax3M4)6uUzg#70dDolH&6LBwZikG6-o**J)3Gx*oyxsa(GslKl6O z#5>GGB}D140Fu(-Wzu0UwWLE{;Q9d9ZvqgT>}(k%+1W23DLl3wXAWP71D*Dtr}ZdD zNkTuxr4i2{{dSV`fQ9C|l_VO|_aN!{e}<&zPYr^Odt)HYkYRWyigzz0z2`an=sg`= zAL4pEt#`q5o`NKM+W|@T*2~=qq)*oiAjv*yJq+3B4swsddLNS0!L2|Ng=Byv{QJ>5 z7})DnlC!}9K$7AE$>IY^@v)+#LV77A=?5U`{^ML~LS=nEmv?gc1W7!96)J4zsPsttfOVW{dy`)nfVxbMiHwYaC@*fXL*ApP=`fSp1 z-#pSG*OHFsJwiI<4oG_cS4hsrdP|ZB?*eyUVSVDNN zgwd*53C7j>DGshykUckRWyZt5M2nLCz)B&0;qsf~)7P(Go0IYI`jzYOX8-X4lVEK) zsy22Y`Ntfn;@J_7zjUswllUorSHlmA?!Wa1^Jn3~OxQu;mGN^DsKVKg@{pdZ#P2Z9 zhm=ThKM;ZiKV&(R5W-H_i3Jj7hMv3}7R75RessI?Tv`j71zkCm=RODr_vZ%V#q&*y zFZmrw%frw8xu@~mH3)>BOV6Y5NN&Z?J-pILx!(k5c91_hit%#~@1_~DJyUon3a;?} z2YcTF7iE?H|GqN=a{-4ztq@2D#tRqG5zJ6b2E!`7tS#jxrtJcwj$8e*c5Q>M?xwA6A{m>%0Vg48<^O%&%P=$PYQOFG-+sUU|L}Qv z=A8Gu=RNN^&v~BbT%PB72EVC1RG$wuD9;NkKmvdNoo6 zP^w=ue*4#N3F>D=8r2UZ&R4&8@Ec852*8KKC=V>y7o>Oj*Ntu}#z0RR4-Uoeu@uJz z(!swI$-dxCz_&?-AXWNF_3+QP1@-&0@2SCj(B(<{LApGtlLb{C{iXdO><~J|r^}u=wJ zeE$u8CH19-_vJ_ZOKmU|7(w)23WOU#EnlGcBwUoA+Gr?Ij)$#-(~uRuSbz`=vMgpI zX#zr`>SA4Rxm1SH%X37Lp!62aks#BZoxA z{fJE9-^BxrXd3D#YDWsh1N{4z+MB|7T>dl%hhzAB5P$hTp?pN|X5#WM??%MYUA`cd zmx&br@>CeF^gNYEb&<-u9lxnODJ;Yfs9_By0VL8^N&O*Eo@4@;QXiCKO$QTk2a?7uGR-=F`JXd?C7V306JNFkaScwZV3(tX0B!9X;T zcrEptL=y>0fp8;UiU3mFh>P<3(L`Q-oK|LtBnrCZ{>uV>4!8u8C~B>v5QKjRJ^a4D zyU)+%k46pur_n;PEkiU@q6-qO$wnIWw}eSI;Z}iFXaO*oHF%?(89FI z=|c8P)575b(GHLgb+1VhVs#VAge)&5LX;?1lt18MvSj5U<@3C<2j4q8@Swch%8lSp z6*JD*!ssU5e#WhPjTv3tba}ahX)2Zhe1Y&GOY)grxRBgV2G}MTKX^Y|TX-{n|EDU4 zLNxOW62=QjL~{f0OCv?P|9zTEbd>Oe+KA*(EVuXq-5cwR2{f1F8Ol#>Cdi@70|ikj z8Yqd9i$p{`JNsvW>t~~9f+LA0v^H>c&L@&Z%S(NHPvS>QN|GF$HRU$wbl@d|2 z|CRLDgf^3cggw-k{`8G(UtNg)<{%&Sy@XXnW9V5aNadN3;9nlu#<~#wU4(p8o)l{E zW4;stl*%JI?Oz_**3u&_nEqOj=1+e;h+mE@nt)1BUZ9?j=Me7GJN;$RD7-fdX;P5t z9!!79cGpTN6QGn2^f&zn(cf!CQyZ5tKd-+4{VgQ=%b&E_+N9;6**O|#8}#$M?6T0Z zhQ8tY7@pp;P8M3W@^WQ)0-b5&&rxW~Wjp7c9e7N;rJ?W2gTwfIu}y`b$;Q`0IFwNM zToW@IWiTq7r(#lN<)P(5X~z&_Vab5X`)8$H-DKQP?d>lI>;2m7X8g|5>Pi)B{&f9DK2Lb5d<}BI-YaX?hW}LQHht@0kT6?F`B&BtsGTln{UCYp<-F`X zB`7`%al%t-Q;Dwo3)9OlAWcg!dyy^5c-<#j~DM7#rs5u=zcI?;Q0Xt?R4D#m-xc>h4R7g_|dq+Ps<05s^Z)S(AA(b7UF)kbU$0W@|U>(Q{@%34l)>| z(Icb~uL!&^jXLQ*jiA9m>nenYglp7B#4G&Ujqo`EmlP;YbeQr}n~A*O{vaV=ivM#d zU&i9#lc zwn_9?k_9Bp+JZcU3sR8E%R+)be>jNp2>XKR`CUkpXdRXDcU<%7hZv;ti0=EBM`va9 zNDHRt`AGAp=hIR6<yVE(ag) zLq0Pu8fSFTI3W5kVb^CcuDZ`6qA;!3AeEG|kB#%g8Bz|NI>&HJ?TI)|A23O96FCdxGKhQaQ zOrLpvMc;OzbzesCvB1-AY^Gsi?>q5(&+?@YKeEiaf{y+2^olF58@euJy<&rWBUUzlvNXq^{$CEwAsnH;rSH7ZJe2XN z6$m@{pay<=1`s75A+-Tve)^-*9N$}hJfidO;`>IijU|dtvgi_AQjlmwFwG%K;sU$Y0H3DHEWSZ{p-h#vep;(k6*VE-x*Ym;~Y&AeVsV%)FZ0YzecJG=;-& zWMlTUBfGy1KN#yRdmy6y8ZHXH0R^wj+bsqQqpyhBZcffInB`5NF(q@Yc1~@T!QRT< z(FL)xuJ@Ov<=hO#*e&j>V4=W~y&kqCVxe_Dv@Mdi9p>2$d#YBpjA+*O4XiWXTb7sY zvB|dELyk}2-tMGyIhVfMkeinC%iIGo2J_423EaNUIIG~9_Qeh1@wB4%P9LKu`@t{T zTQ5M<{CU#rXxnUUY^ich=-QBViuLjh{9aAMFErZNY)tHbs&iMO(}O|6av|lP$y4;b z7m}yq2MgoJ1&u!`&^SqxB7hX15fo>ZFZa!*1$j)2lUmrX9w7ZKpJEkhO_49GW%v42 ztwb#?VQdiXq%{-`+Mm{=HTc-g1VPYi31We9IN*;W&q>w%@kr~xZBAuGn-HDwr>$=y zE(HlosBisg;Y%_>P79{3!SY-mp7Wn8N#$h)m3J8B5spxK{r%9p&INGDCk1K?3cku?3{{K1zA%}z;1c5fb za36k|aS?t?I4?LIaDey7$+~j4l!x+55dVv#wnA9Daobz{T$(gg86;c z6Vyg>OzFCGe*e1g84mFsJan<;P=uKczVZwYL-`J{8RO4r4H0&Ya>&6hypL z3Q~F5Nbu*QAEG>o21qo4$`77X>_gh+@I5c`HQ~Ax-=p=3%UQ>uInPDr6jOd6jk)Y| zw>SQaG-eO;{~nDA+&`DF4TyknA=#dI3A$F?4_ENM_b4v~!biyF(h9;Lk&#jYsLX!{ zo$QP^7Ri|FP(C&@v>!^Bd`O2;FDz{a0(MXTShLP$-_nTmA?I6TuX6Lp!J6PaXp0VKJk*;5$h}S z$~Y#z;hTuZ)s9UYH06r2h>B66@{hu-WIJ@vnjzg5HDidbefLyU+ErwgS9TEB5Jz}L zh~wS9Sex>>WLQHbPgsoSUE2ii=YF2Cl-0HHj1}dqkERt7Hf@CH8S5Q*#)^V>30nOf z0nb>!wuQhmR)}LcZ&&rRwTvO(GG6eEHA(9Tb;!yUledeWv7WP$XRLKHCyrE=@c*66 zuX$*ctp;4q+=c%|7x0WlPXzu|vVrm7*bLwOR}{hbC|=3x#2nLPI<^2Qx8U75GMTKM zkIi7M%*%X^<9Oc6Y=de$aJ&hM@kM{(4h~FLJu-$WF=wFO}k-Z(w9$$e6sK5`@Gl&zetJ2GUsP8 z^p28Zc2ar{U-o>IS16Q6rNb^E?9r14DXP(Pya%bH#m7#Cq{^!{!Xl(IYEe`O{MHnC zSM5?cqsj)qpW0_H@6iZf>v_CH9puqSEqXMnw##7e^mL!zral(SVPG#~uYbP&8 z(Q6ZMf{#`VWlklxc%sZ<>Zx4wXskl?@+5PH!e0jCNm_eFJ^3Wkb8<%$Ka+X4PgSOR z=2)Mu44$5*WJWWdvNai4=bXgN;TZm``OJ|aqNgXBLvCbxX0Cm?OQoE}xpm{d>Rcv= zpQlu_mh5VJ7Oqia^k_TP&c#Ve-jCI_rD|tVLjwF*kpxX zGM<)FqhUMul;f#}3{F-qe|8l2^54|FKdMmpqZ&Ay-WYFDJN9?PTP#U~zMAsjziCg0 zn)h9!6n)o>f$y3S(RYp7@gSbKkDd@cKG74^9dR7|CM73f94=TRjDPZ76%Jg1rJ$GVTaZk56Veijr0bs!_qOVfiOz+ zq4>NoKjui&b|3=26jL!{W}fEPvW*Jf$5jN6rzMsljuBi0Usk4Y zkE@Ih!2-P&IN@)BUh+AWQDRJc3jRK2)ofBTJc9ufF@E&L?6{{I*i_iptWfd2OtdD` z`wpm3nB%<;8il_qruxeHdT6WVP8IK;;N?3?}mm!>P^olHprYrqo@R;fPxn|UIBKHEPc@7p||4H2xm4fYR zp>F;4fpweBz5P$?W(um?r?77vrK8%Vb_CY?PxT`zDSdKK`s=nyUa)FA;uxE%Gb)qb;r;PM>4jG8Mh{Fy5765QXQ>U>)$6W9P4&8z z4)Vy8nvlak1&=&Y`l8;y*9X?U5Ox3j1mT))0)5|LO_DEy9sj(|1Mwj%sLd~g4+2M9 zY}alhynyYVHfHQCCx~_k{#VrSzjDMz9w|tMBA*o7Is{KEzZX+mZ0hO|@~~oiA2f%2 zwx}zRLuP{aQapzR>ep>rSUi_iJ9&%ei4BuMf&I(hB9`=|O|YB(*oiQ3w<7Q8`fE>M zgz$b<$U}*8OM06`Ph;V84)fm(^%ii)5O~@MfrpZ@*gzaZ{@nK1WYyZIYvG~fX81xo z*wbtiJd|)AHk6rQ^7IsMZn&0{JtKdHTAjwc$urEZdIo+($a93>8{cYIS5aL-`7+ey z@GU9UwVB!??qDa;4;5%bor^ew%rK7I+@Kiy?kQC^q?efky|25rBPGyNNCNLEWYz^d zg&ef09GmOziIF+oIv4y~Wbkz7aToceFnK<+3!W~%7UQ4V#g;c;(c$m8;!pJ=kBMgz z-Dlsehn@WVeVxehpb5SY&@!M??z8vS7j{T;fR^`oLec=yup;la1{r*wsNm%$(`AYy z+}1dw%u%@{72H;=sWusI$;G`^+1AJkV>~lnR{?zhnYIExX=JvZ>xyM#Gl|~Y0gdJW!F;WS$df_2eBYGYAk2?Ck zS@1e?u&(KIRl3oDT29|wH!7Om4KI2Deet_iLGto&|rx@bj??em-6i{e0Z;K?HgENS`fu`M43@J#NI; zae!QPAFF?hd!;)(gn^fjZ8pJcM}5ES{s|s=XlU2A&9jBM;2aTO-$Q z?++gv-mhIMdHHzD&&$W`zVPwmxb2;r>$KI2V$cg{QK#-0TKf5H*e0)OCU0g*ncl^9 z?6m{EX4eQ%l}zuxotmvQXNlt_+86m5$w2RG{Oo0*_v03l__o6b25`_}X&2;18sY91 zc@?}=PJ*NjKhURKl59-agQ?ZTrENpHcc_?njC%)1{JcyBtJ{U}EJ3pNW37^RDQ&Ab zY6}N?r@0`(#(ny#79OqKXSV_?Ux7t;O*gCIy`-Q$U+$N^4GZnz;a!#C+q=SLg0B=U zY`TZ?tr+^fR>Tv3LaXD6ZTu5bJBE%A?bp6_N9X1S)bJ4%uyaETgV_Vg#7IdS=(V@V zs`R48YB}WXB+M)(aFC4f9fnr=-Ykyh0{j+4E{g_U_fOsE2%@Hv`twWw#9U zzS^R4%Acjy`;P2{^JAT-vKZ@a9cpKuC7kSu$G}T1e5g{ssm-ACd9tzDpvCTv3Ech; zMRmAgnE9Q~!MCEXo2fsQEzpU@n!~?x>GAx(a)sl0|Ff&(5tl-qj`n^=m#WvO)+*P9 zt`FIu*eKt`pTRh;kbSKoGuc1YGZ=J6bucKfzvCYi3@u5~dXf+Xy{7e2ls`4;i(uU@ zgozuB;#UZ7(~6QzxLD{>(EFNk2|>tzKRX!b>w`0{{`XaW@f7in36SMiB*g>(vaKEX zJ-!F|OwyU$!6#@%b1=yH6-xhjm`_iO`gkb5ht}1kfF%BWr+@qoDFR6MbA#dqLGfil z@yCPWn}Xuc2gP3riZ=$u_Xfoo(j69-v%hCu8OD=S$*Paff~3!Kg!oByv*2sZ*!{>^}t|4lJH6lh2J^dd|bAv}EX>GuJWz0*QKvUmEh z7+)pE8v*J0qar*j-ajYaC!IceJ`|9iPY0y@q1c2YJGOK-iR{>}q&S{=jN*V6oK@1q zGt5SUXs>wGneLATr2EqV`R^lWz&NJ+D0?5>2h78!58dBE5beAQgOOmh2=@|1`yL=T z8g?HsK&bqofK>i)^sDSj@q9b#^ux}#Kd>ZsMec+^Ouc{^)j&*^Y^3^7UP|zx{*Sif z^Y7JD!O-y8E~WAF5-uqy@Pn?Ka8W*>GaruN{}Li%Vn7%1VJ`loyLp;U38pI;<~SY% z8U)x(U5q%DhvCSF>A*#k_?v)K-U|Ho&qsEfO_V_lQoap{Q$8u|3(7~|Kw%9o|N7~{ z#OO1qew0r6sLW?@ffN)1@Zmd@cR737lffkCo=xktTv)dvjAluFix0uK(4oEr+o4lK)*m_* zwqEdsEyt|x`u5iDF%b{76?4&nRxr`^;-rN^z zrg9(N&5YjJtq7^%cc9qGQT%#mvSn}f8}K>pZ6`U{wbQnTvb>K>e!x>LI^Te7{(&716Vm)4z>upptO(DENAsc%f4-`QOS)IT(< z4B7SJNu9FDJ8svf@S=|ShwKe*TxTRwM)E0daQez)k;k6yk9yD*vFuw7}E>TI`H zxl56eW?pVlq%Aiyogyxr9P0TsJfbqYYPyZAW;B)g2B+u`x#AxuF%yy>#PwLgJda$H zk%v02))_wOn_lM18*s9J-9$NymjcbM1F<{g%Fh>-lfUj?MI5w@cUJx=)eDw6WK@tY5UO zw%T+4xVzP|vr866&(wB-uFgtu&*w^J4f$Z+S93MZmIeIN&1Uk#HnwrKmFWsoN125d zGMzbL7hBOqTe(UYrG^>eYlAGIw+BCOMvKqKoHwZLl>h4radA8zx z#k5rOGK(U0nYq=vtYrh%RruPltE}uKCMn9jaTe2)v$nN>O>JGgsvtUNwPn>}IYzY% zUdPkj?3ke*R%7y$Gyn0NNVo8G1v%nfe3$!q8g?ci`c?coHZe?E;}?hAlwruWIZo zKpwf!9}3Qlv=xo9Ev@${Qn5#0+;3&CJJaH_e!6?Lb!V4co`H44^8@{sY1XLdN_ZNJ z;)=6}d~iFn()umm@50yI*^q%gk*i(SDDw+Bv>w8w>~CLfJ%?VEv#Sek$yvSFg;M}g z?(*z|o+WGg@w>>oxPfT7Yw_J3Y)ZB#OHFM#f?tUqw&v0N5gr?@;@VeTg0!Z-&>H*tjc7^6awWB7p&c!Gc+K%K1biNc^>s+& zJ|j+z^`8*arj|zDd0eK!jA=P_(=NlNs-?;|A%fUV6S98YT=#;27wZqJk<(8o*Ct2^{ z_H1};u|S8X?oP8*(TMd?;MQ(ADEo0+!ANEIe9gGzPx=y?65Qj)EVpEPo2<8Tnyxh= zG!hQj{3&fscQX64#DpV%{gUTv&fj zJC^7*KMITstIsa-KCz2x^?TwS{FxiNm-=l?)9KC;*r~X>4Ry*4cPrvlaSL*u%)X*M z(aStK&!Y?btdmCJkhVmRO?|!BHuYmFfwx;X2~WGaRS|zYN+qxBB&@&Q3nx16a@Z|W zg`va;qTGq-gMIBSe*M}C9yZl4UgVurzuZ#S!E+tCkL$24;5u8usZE|=lvEMd(X7tx z&kd$Kox2&wrZT;MtX+*KHHs*+%X+S(-x>oNOEmDt2BJ0NItFEpX~6O702~)`9}{NhaSZJ>v@bUd0bgRU7*J##@llYiC5V5j@*Vxpmq zwKkp)_2p5$ifS_o^yWQ%p=Epe6gBOjo>7*eL_L>RgX^V~Ob0DgY36;k(T{S*mw;;4 z=*_6bXj5OJQQgg|GYY_kuw$ZEuP#_-k#~h?{*lilB^(3)nTC20XCAtc6L@o}9UK8P zaG9N2jmG+~?EU!)P?wp=`C?Z{SW8!31n6cwlVtLITD+>DKaWjawRo9@N&48=+VtE# z_GOlLJL%gr#ot-!>oRKvE?dlV2VLznd>wdfnPYtw&tv&-<9V#RczOZ!j>7`E!ro$m zBlKGbzwA)o@EYms_McqIw=HP?4Ugrn%wrO9YR5)3Na0&|V5fiUw(Y$5`-_D42es`A zdOzBBwG|vmGgt@d{i`h>fD1v=l7l_;IWPuZ4Pw)4Ggus_E4@{K$7dO1iZRD>#HR zQ`=Dva9K0ZyQ$THv2~`kKR?x~$mq|Ls5*V!*al%n5Z^G!k77Cw^`+Mg^!~1yr_$!+ ze>$?k@eK=NhM70&*wk`rIRi!k&f8^rm(_iTmXoBFBJc3VfnJMi821Szkxw9h+<{-= zHBR)7AYBm`P_yB9+STzbn{~a4MzC*;c6YZ(iMcnQU zaX34++dg+UJ()Kv?W^OXxef)r#M=pEPm$*GWvR`aUd3OrTavIsMTBJWT< zp>H06lY)1*@qK6e*@p+El%F=xJG<4N@;+TlcwN!D zy5PHlt8=Qjh@iRMU2QvO-6PKL7PS-2q?YSuvJDk(;vjQ4VMc#$LjNL8$*5Q1PbGb7*Mqu<6dEJd8JTlBX zT#ZxnB^j)*peox12_u)UM;Ny%KhgqE=h(wL;_~kW!j9{94fL*Wp<0~p-Hf^8E$Nc8S=X)P=C-}xUjcIsRPnhAIvy1p=m|SNb-a#|*^S!g& zpPULyzh%}FXLY+s9%9pGV5U9D4Vk1FUb*;&fkw>IAo1RAH*0&nW-$YA? z^5qLL`Y){(OZTxz;}>X8jqKl0b*QaLe{6!^ed-@N$1VkmPnRNq6u&+werr&CQBZtw zQ2hR&cyUmCV^F+2DDDi3zZev642lbTY<`w~;lng9clo_btt;V_ls3<3501Z&%`_{# zhZg28zL(sQLc<()mm%kU_t8EZoN}&s;34`cIwqC&$8ZPkN8yi@HsikUomA9HXN0{t zu^cK!d`wF5e+m5-eBNoWK>aFyYtUbB5*&uTCW1&Gj*g^s!Y{Hxv_ym!5t5!Wr5B2D zg$P%QkbK3`eVYhNMYvvsPl~Wigj+;dDZ;HHtPvsUjZt|!L`Zvr6mJsYUJ*8naGwYd zittSlzAeJTA|!nmD(6EH9uXng@SybLB0M3&FGcuw5qd=E6=9zUzY`&CicmS^H-jMA z(;`TIF9?z^AcDh1NOsXF9xFn<2uF)BL4@R&g7T5C9)goam@dNUA~cCGM}(wDOZiFH zjUerB5WH1{WXp%*q@PaEEW#xsw21IN5f+MYg$P%Q@G%kEL|7`q^&)&ygk>V!BEm`$ zZWUpT2wxK64iVOiut|h_Mfe9m!sGc^SDuJ{nOgykfKLDtUT-0Y`!(YIm&E(2*xb=z ze`^jw>`g8ti2a(!2u5KKi6HhoKNj!biMFA==Q4swf1Mzn|B@i>LxEhD!5<%pDognU?74K(b6OG~z6GZ;K1kujKv7C{X;-%_alJR?k6c7d)POD=FxMt z1i{d73&$wMy=wIB58JDje6LI6J8it;XJzxYYyBYuFP!Iw+#rSj>WD9;xj!?mK!o}gD&~)0g+VfgCx1s4OE`+=4 zbXjynHTHQznZ&*B6lm#;FgLq*BTv?Zd)w|!GPlh*IxFd}HZEy;yF9Mx^z1NY9Zo_z z61b2$26`t?eJxu}^9ybQ*8AA!5DP5}ZI`b!Vy*T$o7Nd?iOYEnrFEayotx68bXH}D z{@JL%BUV`vRj71s%Kr9)&`MoZOf(apz=fHQor)aJRxn#aF~>YV5Lu~i^6X!l^m?1t zsjQ`UvlX(qklF-}sfg#KH}@+;%NDwo&QCw0x3eRpx4qpSS{cSE%irr{C(Ghq=%nYh zl@U1ed49lqnhA@j#%zy2(X2nM4?A<3iNTX$R8N^(Tg4i}%+hQyH%aBbnu~OX9G7yW zw<$RN>A0{FoO$FwP9I#2R!r(U-5K_CoCP`5JR%b!4S8T37AV4KveMOJ6axUF(dojL50%WD>T! zWz(ZMW89aYveU7874w_ebM1;Wd6!N8*G{eT&2Cl^mlJEA-MJSvpzrvw9re<@rEL4? z_n7-#kG{VNmxKp2KJUjR;TGK^ydg+|?h!5$q>zA%em{ikKJiKfq(FE{fzCvPa4BEQ zHZ^>c@_1O8VTTHOVc`|3c%37rd{jBLy{IF_&&&c%>G-PjkP_*TU{$N#Tl3VC?9><+-?%yj(UDOk(2X5TA>CMD>~3w9kV6IC*hQgi_qeqh=*6ZyzW?vCO?3Jsd<&DpdMfR68X3bi zW;Q;%5s2#&`W;-%XS&;}$no>FAsV|PMO5BrB$&Aa2WmA=j(L2!pLup4C>%I&$ zzZgj)c5Z1x<+|Nju`=Y+`{j}aemsF)~?gI0r9?P3fG zpo@bo5WbD@R>I06?`w_W+ulE^bN=<~m&254;adzIrF;)s#dG@Y7@fm=+8je;mpSvu zn!TszY@*-x?#D~Vc=W2~?yQI`PnbP7WuC_<*E@#07aCR?;vCQukt-e0H%(^Gj4i#o zey-QP44Ngo;9KdIrqgr6mKfAk3dhL0u*wJr<1ldYXSF;P)K-Ub&DpG{u{Z*!^^f(% z)@aLzSt1>5#xOIT`48!ikTJ<`_c8k4_hghL$E)#Mp=Zy`C>dYNdai&*fj$EL=;<%j z1!;roM2+8P*QqO+go8cP?SXo%g8r|`W3)#@W0duLSghmf8`Tv`Xy<6-hvR=_eER1) zoYfEC5?z7yt^#HP>&dm<0^Q#d=&tHyk`H*3?)}SLv8tv@a&;W*)#$$b>ZER0_=}S1b!EqJ3h>G~H{T;c9c=^!s z7tpthQ^I-8-`}p&Ip;JQv7f1f=I?Uz#*;LLRGQB^bi5X8xTwYYKu^pD&DO>SjBP#L zXZ*%CX%x`?ZP08TV~KWDb?A7#+abK(t)_8|Md$c+2d)1N4E$#i(e;(MsND=$1;;w# zHld|w`RI2NsJD@e;pw;B7{+V2#y}6@{6LB2Dn~RI;~WDziam}7+6%~Q7{+V2-py;b z-hr>0i~XD1I->bpMc$jCPaEyHiBGp_=0Yb=&k&B)l@K;W2Wd*{DxmY66#gmjNzdp> z153~+haNsLEYIzwlAdhdT4P!r#t5U2uBvNflbhl9Md@G-7!lCl6{t?+Zl#k=14boe zdfg35Xjmo4WQY?b3TYp*Rr!2p3{i|jb|x{?`-cYExV;^^DklD(ujht^ZvjsaQ*V`X z(G^>=-~Cz-o$DcMN#j~qPP!ea;TY)fB}BPrL8p&&*wv-rUdn^GWcrn3+P;uR(>Q!- zpl-DeJT$so4NPlxlg``0p7CqcTSX0PGp}Ji9_8~I)*~@GSQ&8BV_H+p84VauL+cvr z_-{z8R+kSi$JmN2^4{7&v@3$AfM$La(jKcs6^nWwYS2wgaDL`S9r=CiVdcrkuBbc= z{h#r+-JEXp1a1VR$6;mA+sxEWgdXW69q8`iQ_QVIpO3i1yH(-c$A~YO_>l=37*4D3 z-SxUmwChma#Ezraz)Sm0*pXnT6m`UIyg#dPM=H7Hkc5Er$EZmjD0VW1*(J5YuGfjM6#e!n~*A$;W;+0mNaTKRQirDI*FqYCo1ZFtzN1x-ZODn zdBU+dT-4LM`8FT6O*dNg+z3u+@2kZ2K6r{*BDA;4*n@XSdb0G6>1gTn9YR}o9*uhL zCbYKwpSJZw^?_|2Beu2W1hvhm=UCVi0VibH6ylF~FSRmbI&;5WnarGNwXbD){6n#7!W-cEh=z(}6Ac`V4Qn4&c+ljoVI?)j=)e@yD+BwH(?s6nzz{dQLZbn8Vk8 zM)Xnw_H?NIWK@HmV~L!Et?4_d1)X&~uF7;1JC6=?HgVL38#vZDEk~Jv79hRzLVB7x z(@+v!#p@X-Vi(p<)b72yF!Xk_OK8zyJUyf`9~5gn%t<4J+X-PReo@=}??CzVO>xNjXZVTZc`Zz$@WP$!JfFrus%8K1J!3$<48_}o@II6kRv zMc&Pg%H*QnrpCZF+Q{ci-}xd=I2QH3&={G*Q%nZ<#tbVno%v&6O~$CU@st7-({yIP zSQFsjEb0NmLF%*%-9UGt;jUc+t>i++V=sw@hP%4@Q)svkoV~rCxa-Yd$(bVW zE%mj>1E1Z@mu!NZMHU!<;!A(>? zPa(RemPXV3oFBP>ar?y;r73#a>+96j&KRdI!ch$k_h?QD8M~dd?)~c0(jM4m zHdu2p;jG$2cIu5iog@js@)O>pb|@WWBcw^B5z-i5uv4IVufdi9S@DRpGjT>v$_c_ z#KX3as1ZMRol4S(ZzfvgFAbQ^l$7Axcuc>Z3)@OuN^jGR3x!M|@xsCqVXOhef9a3m zq-`sG&neK;hfbPr4;4wP8&nR}>H-aU{u)Dcq`W@ZgHn4@wM z%9IHLM>=KO*`*ADb~y8HUrt$rZVg%ryYDHWXO&4gsPjXt5i`JqgfiyLwZ)VVd@QBj zofCuk#Q1&3bmJ2$dFssL=E!5ZF~gn#MV_u35AG~+mwSmn2;3!br2cA$ZhHDo;##`# z#9dfpJh)1j`9|Wa;3(IX3U6HB8M_noPnS@|rY2U*iDl!6_b7A;Wda2(>b+N#kRp9N zCUZxGljwe8_0^V0=dB$^$otgZ(Y!ST$arOh2}Rz1%(!$8ZG|*~W;GXM78YpJ!N}Wm z0G40f({4-*$Ls>*hPQN8V6U%p#sKGi7|$4#6@wTxvRPS8<*6$o#5d5ab6B&_-a&kk zH=~h>Pd|xO*fPu$K% zdEU2=s-kZUn+ffQ9e%Q*UX%?Pf7$TEVm3`fd=wH9^$X$o6TO`{6S5;<c|%{PZ@YC5Bf-M<(T(GTR+j5)qLO9&wzK^&OxgSv4d6@PHFF`Z=~@t+GllP z2)C51F3cXsTT6KMdsY`7>SjVNZgt_Hr?Ys_?!wF6ig1)QYYbo3(~{+d5LjLq4IRw> zkeoov3&0iL@67UvcU%zt&f0M>r&kn$Qy1$L}->^l+f}DxS*}c{zTbnghER zSvyodo&58?`wpPR#ktI|Di+cYjVtuod}XrGYvJg%cU#F)2EJi>eO*j+D7P6lU05!< zjDc0EKkpFMEr?6e8Y7+arg8M{j?v(0@`M_LP6IHA)%YOJNDaiK}- zXJAt!o~W-jPoi8NVFgwl>b0SB5Xa(@ZQ>}+DdD1lC6jHy+1pk zcHV(=^@b8AS>o9qmN+K#*OJwbDe8GTBvF%9e0 z8NdaZLwBWPl=I4JHaR*cqQZ10tRw<+?g&RjHMs8LnO@r}tY0{2eMMLYG*~nq8N*=B zuEdVr2?OTApk>L;ml~HU%+U|_++RGZYQjl+`cJk5>;@36IN$sA{$ZG9sL)sL7QEGL z0-cfRbth(HT`ff(O+H}d>uKg2s&%Y)9|Sb@?6k?_rPWD=A)-R*IN#f_pPvu#v)4gv z66i8vR8jBR+Q6P%)*xZ)qpdN#)e%mxIx-v9MrLDl&jOq!SRHw}J3O38dZ=BnIr2)s z>~2`U2np%h7IL$n%@HMUEkij;le0)Q^Q+gFFHl`5zho;zIY!y9{kddwc}YbiQ}k0kSjad^MW4?QymixaStJALrC+4*0LKDV?;^p(q*h zP1#B&J_j6qG;Ai(toeNJY#NU|Z(qn+bXG%nQYkJv<*_Rukc%d5sBH79*S$+|n_I zufAB0RV3i?P{%fuOe?EPux@l4b`rF(oOYp68CI!quyG^nDQCYP&llt5bOYRj+rma#iYqv#-}*W%ao#%`6|k!|zru@C9)WRh!Zy0nZ8n%Q2u$qg>hFwx`t5UK*VlcY;dQbwoZ#xSY-j_TEU|X0T(?#HpVd&t1vMkB8*! z&1PUljOgbyScehTcd|#alWn|h7+O14Z+qhGZ|hY~&=iex19_-XRlkdq&kpl7b1C%GN&#QJf#vX^tvsgn#O>%w{X6< z&4qOo&`o{?Lgd0!C+5s98?B=luwS~hndMP=z0qPLOXubN%g1N zOWgKs%Y#vo<+pW)@s^KBpIC!-_z<>~iaB9qEjXzHB}%UmVslUawCy0B#TLa(?eNl& zHHx+Jb+CVwtxcERtkDk73X`qk!Qj~*24OSKQC;xt^-S&fkojRD3pCl<;~{bltI>|n z4xJymfD9?&xu2>nB`tlFF9_$XeNmhu!f~bmTS|lX=zLFz?|c@uqYQDqe+I<;1KBzX ze4mmr_-DXf%lo*HQmEY)NfAJb)AXF3{uOQPEAWT`z(%K#_hyy6x>BjA@5r+QNyP_Gv9n*b?22awWB#q_sC zxCGxo&Yv?*!g*l~Ps*Pz!dn69eDgv;dhTv9o+rki0i^tI zig10nP@g9OsXhk*>He1@R16XBs{rZ#P%(a`7@q@3`OP9+DZ-mTL?+_88J7_kokyOC zGsbsN9B?hg(Ux>Bnc8T!bd0iG7)Jz_iw z1caWu8Ibbb21xmO#Q0e;9*@JJl-jB226ki5N@rNmn ze5)u9xC4;NeV-u8{f;2YjRsGk`l8twnO;06jL`zu$XzTa$2Hf_Q`+vg-8k(QynIKPmm@GmG zfGqMM4*%&l$RQstmTw&HVwhbr-+1Jq@=|e8pz_x9zl47vtNb}{>L1D{)o&kulkScb zC?5qAE_5dk0hm7YwFwZY&P!^PkLooKm;ZZ7A7u&Bq(J%TD#Ydg-Y9%{8E{AnR2GH% zaQVMC9SxvI0rXzVLuC;x#YN@eb$r+nH&|Cnkji@+zy0%ld69gzVm^A7LPC6?d_(W0 z@G>s{`oY2lqemLm52V;vzu)0EK9N3~5A`VT8Yu!ub)w*3H;SJ?K0O}9P~^}2(|hSR zy;H&!{A3j9k2CZ`3{rU*vH|&4qJD>@On_28oTa~J63);|;ZkSmr%s(B9=*TxS^Bck z{0js8{M?JAF}SFIm+-fRf5Q3W^;|>Ghj+a=N{ZOE()FaVJmhxHEsQ{1C-MCm%c!oZm?9;bNCm6Rk!8> z!8db_3-8A_0Nr`ZZYa-?GAH9#EyOO2-T zk4wKd07)KkN6-Pw;ytp4s4+CcU51CA)6GA>-S?-Iq^FxRB67 zxac}b9s+K(_mge68aksCvg^H*Dp)2OyQ|QGy;gQ9H?~uQ_(;T;!mb;zQ&0FuI_y*` zla%RI?*dL4$-bKcdh9qG3>;G!6=^sbY&>_8R%QAZ|Mp}gZ{_V=Bdom1s4QBk4eys5 z&Ys*~pcuW8gD;uB$p<5j2jb_<*e0J{x5{F|ECENmj%GnefW|M`cB8bvbz+r|x6re{ zKt6g^UKUQp>f(h`Tl2o?41@h9S7V_?7q^t#caq-qC)j$bZ|u(>LMy(>bKJ$iam9x> zDzmz8wQtAo{=BVJYuE#LzLBgvv7Q(kwTca`;^bS&f%3@06SWkb30cZDSyXP-lqXM0 zb)omH%G1PCo#-1|^R{)e$&?CtNUA6 zddT$VHtO{PrE2D_pQSdE)vo^h*Vn^hS2kJfx=OUz#r7<*t0sM$H?`ng?&@5X<=gxX zjL<@?=NER^3K(|IT4jrZeUz!NgBEXMQ@_jIXYJ3^8~$KJem@InLK~aTJX?(3&4c~a$VM!y5t(F!zycr zRTo``bx$2vJWKn*%}ld3lD7(Ren9xHw;IU4fkuIR=GYu|3X|e$cUgDmtg?O{4Qmb9 zE7+LL_B?LOfTfipZ(9S=z5d02>|m3#JXtKYCbcSba&QvdJK6_T^y7!sI!~ z-)pu0sdJfy+Tre`5O-*|idnfB9^dpT_p6rlyt|TC7AV}=7KO3Td>3rLHib;fh5e3r30E?(UrHA4RuvpN z#X75_XIMVzOD~)E)pm_!!*EVJVapxZFPX!S)|tSTw;Ozxq-OM6KZP}?keoMmud@C| zv|>2Thbbkq!arC5dwEk~Jw&qp_iDY1>|lhD4MPb}rxHIExSET&nqVvG<25(!&d9%+ zTUl^Btd#s#w3+f-Pz!;EeS$hmbnK4ZC;>D~3HxY)6s+G`(2`uZ+B(g8D%vI5j@p>b z^xVEqz`%aX3(yK!y?E^jqLUlz3oT^NEz6?$k#FWGoZ2=!rt>>My*MyVRszL*KC(W|DA1GzKu zBurS%_Yjo?D?>>+$EYyLSwInaBJmJh-v0#OUu=eBP1-z9pfszw$wATA@ zV|u^!gO+LeAvvwPUBC^2j-*BJ0S!sxs(~2~gN6w9Y6S}No4RTFpdcYSveBt0Ucn@_ z@?(Xthu*gb^h}{|>Xf)3oxZKBL)!PGqD=4ebuYl$j(e^2Z0p)V?$denSm)p#naT4) zDV4F$$6cx1o9ij4Sew;_nZb_xw`n{yx9>?|i>|eZPb~qF|H%Jb z2``uhO!uElwkw(Lk4yH7x}1->e|P#|*xIidjjg+OZGXW(U<ux4gZit9H$`w4BVy zmnCm(m!m~uI=e;=^ZX-XUE6x@HrTw%@-{8GeIzh>=x*TqdiOByKt5qTjk--7+f}0Z z7S^*&XI``U=tCIM2Y;KAo5pP#H*V{4Ayia|Mk6hJkSs|0;A7ISi`{392l9rt;hXt6 zl|%ur-(7V9N{`t<_oy|Ca5{k62J>!@yBL@!yRzMt|9JklmgWNBpMJ;e{`~EsWLJ{u z{$sI0Y3d#cdz55VQo^KuOC7Ags=HpqDf`D-G!rHs8|^i(AdLTDR*|=8*MYouNLJ;~ zh|-<3Z?81}XXkH1Vm=xUTay2<2-YMMb2iNy+CJLLtk8`;-WeAf&f`Fi*Eadj^fZ5J zZ4#bTO?dC=2}w(|Yj zZw=)ZVNROq4c)m4d{rH$gC*aA-Zx#-@}nWe(OI^bI(EuH?>DWNk2xf-6?xC^NG^1N zYhn!X78f^X7o8nl=WqAx>N>Lf747QFXCYOSLHl`tup-s3xLq6A#R zOKrP%Of5(-_vas8zj6H*NWdz=>LPEi?u(KcWUnryKW`^v|(x3mD&4@1} z3C+|uTCX27t$>~Uq3xXIPVUhH;;OM_pK~`ylk5WPfHi_$K$GhZPVKV`s0e#au&o%! zB;MH0&TwEXDfCRzt;FpZ!8RbUS+otv7L)X`fIFAJvVckcM3g>0=B1Cr#FLG%MaSC$ zqj}WD<&PI(C-9yfbORub3$FOMcjZlYBJa*Vl9sy?v;pU?kDnSBpDBioTiMU8-_3G|{se}g#kB;@92j+?LQ>NQreoA-K9FR$T!rQkCb=R#1USxVx8d|IxLvsNW zub4!XdbRb9=oYK8XY0-7+4DSM>}a?0n?2xtl8n?0e1ztI$2lHLpuKp*bgcF+YavGoXZ`=lQ)ac zSp`g)ny()VJkha}rxqNxv2i!#^yi_qjMs2?avO2dhe=KldOZVJ8-re#&y7`ajOSOy z{rOdp8-~~i>88mOYRBl0!3km({V0E}>qXJJq{*|BBof{VD3kngfUGiyzjL^gzVbQy z^nCixMZ0J&D2!aeDqQj|vffBzVe|S{>t22|2-X`nLq@%`cxr)a3O%8+>=x&O@OX;U zR($7Xo679}o#*oQ=N`5V^j_hjcNW+WSeXekym9Kea;$z?>>q5atmpFd@sC5&Azx%9jSuwB zX+5|2JWdRPJBLj=L6}BZ=Z|T$;xM^^_y?^xOoaW&KzV&k2TzU7*LJLjURI{}{kq$@ z(i5MYlApR6mKya3G52D-bN0Z}BaNR*j3WcAJwD-m1-1Y`YJSW*El;o<30YFK_V|Ri z3il2*6OSgo%#Io8ecr_yq&UqepLM|sWSQ^=>Z#jyz0AGSc^GeuExY<;aTC0K#mj1^ z;oClQa7H1F{THFXxQ)hs9A;_IKrwkVSi3pL%P;49 zxdW&jZ_{xx&U(WiV>6_51t{v$^Jw9S<|hiOxpOo-EPH`_I%ax)gHEtLd89>@Y%#Y? z6D0SkN$_h1d9w?cJxQ=WSU^x+}E#KV(YqW4B8`wO}*lK(nKzOuf9Bcd$%Gq6BLi(=O4n1 zswDdh*sC0vN?5$JD@0w_wI=Lm9rT7wyy3m}*&R!jcYefUEJogEuKv7?eDqjafA0C- zDenHfE!;3r8`!Sw{S?-PC0oTau%@avpYMIt{kHPj4>u^U`Dor(ryhJAYgP-8`r?7O ztEcB@jwu6aLfr6!1+GSmB)`ULYQCq98h z{UkSpYstMIzx7R8Zff4+9jP4Q>+ep|d(QV39&mEso*0hR0-UdJd`VgK&CJF}ebzFY zd25-F#^IfsXh#_Mpkyzzz_pd6P$SJtg|?S4hoputFxGzFOzV;7dtcudj1Oef@_o## zX!IZOzFQwW`p@^iv5)v)f9|h%`a?W$25hlIBI%NcW#mVhIatpOKThSJf#uA*>g&3+ zvIjhJIXkUFCF_@`Ey@AcyHr0jd_Ob9KZSmF&ibMqJ+{xk?1}ZnKglX*5^5ZX*Yq8u zeBTjGb49FQ&{z@5JKw7dC`(QCl%t+9Hp8ico<@9FmrVX&uj%KYSA(tam%1Ob754c2 z%2LnMJPUSoTLdiVKbhq*vFCfoANW`8j#gq{`+{fRaZ}gnCubB^5{?Xyc>>4 z_yu?t@QVpMeS-;fzAZ3+2y?~YZT!M!hF>5%quA>A3!(h;WbaW3|A)PI0j#RH*2njG zC5I%$BchFfcu07JS2#RHf)YZqMWuqTmZB|54qzS_Qyvxp<%9%`Vl^7Hyi_XIBF~`W z4Fn9e+-iG$BpMVI6fF<|wI?=8AXNU}H+$xseKw(_>iu7D?{AWQ)?PES*PcClX06$? z)~qqoPbmc_@{|6D(7l_}=fgfk;Y_a#6~egw8xs!Iy$Db-LJtU~gelP8EtFNnThpn5 z3k}V-S1WiAn`XWxYa)G6H9u71sC>cAvda1Xk+H%&p=wDSski|{HcB$L$bE{U^U#a z3U930)8TYgQ*KsG-dMxNX2L(KbhJ7J#%glM#A#;VtA*Kx3ZE@JzG^T#5q<{Q2I=20 znGi-3BMFgs4Ksuf&C4RNx0Beo(?sC8XUO%Y!A#0t&yVz?&s5{GtMBs?JDK?y&V@G}X65;jTLEMW)ed)ba(CPX{l zC-I|z1H7=01M~sj2|e6ad5cfMki2FGq&se?$3DXGK&m~?YVH5fc?LdV; zRpfsRwsf@jTLDPhzIuu8mADfIIi%Z(5cgRs;j4tGpHmVa4n{7XS3=qyGJgjc((w8x z2=P4I0cl705+LmecQZa2cB6!#*B!QkylyTb%3n!{>+1=TP9LmH*9n2omH3d3MtoNc z7Fdp(BwR&^>)(K_AFn$lp@;T`zVL=Jvz~(Ldk1=#TZ$idYK_+{vM*P5PD_eAKX=Wv1f=Z_*jIFb_5wPbfFsz+4vvJKQ@X6f zPHDQ*p1gjf)8O_MF^^pQNZi9Ncna+jhz@>E1s zIN>Su8R;pseKB>oOYE_>SlhkgH`X>uzzOzofNy9i`1RVYenM~2ctzyjHx@iHHP-e@ zDE$klUeEmd#`chm?QVa_R)9NP>WH-+u~*wG?8IJyr_g3mwt=o#oIexx6k0$}p~UGa zGzy+Vd%{y_&)loAqg7dheU(G{B%lWVFZaHHw`aVO1x=T2wlCjuA|5)F(_atVe0AZQ z(f0Z$peNSvwJ+=-O6s5yCml7>Uz}ufx_r#5AR^8>(LnaAN_gM=o)*-6GY6) zWw(nfmbFK_qc75^746{PH0lvPg|l6chW%)V7Yh%>fo=PnlPlv)G1M?U6mY}8r(@a0 z;?Am-)}bXn8n`7&YwTU@3ejGMCp^D+xpTo+Pi=a{IqIw5Z?dCAtDteYsMsz`;`umw zsg|MzlNS%$s3oOj*?M^@M(XYgXT|;_ow{8dERE`47qzl$XXN>ND!c<;`@GgO_A%Qa z&-&;-)DqcXdjwsV18uw;TBy%xpW5HwUKqQwWJ`y&wn6rR(S5K>q64|La1Q3z{{H;J z0PgKv=v?`sxWkPLZG$e)5R@k%Z;?UG$onw%)^ncctc_ZE2|R9LweG_GM_hxR!n*F2 z37s!?!AsbJraX8+?Nq@UaxZrXFR{_^=#gBhdfS4gt2aeIKJD-d*Ql>@H``aO7H@+s zB@4UgdCx;#1pB~0YorgvcG9D0S+P_2J$k6vxr{zVx#OM&|IAvl;hQ5ZxUd+WBGDUv zQM_W~k91pi_an|nmVB($Z2r3z5X>EXhkR`g4y?XTj9%)Yhf!FsYQbNZI#=9?+Spfu zT?XB-Iw;Zl1ithvPS%~mgN}1$wC*3^gx}#i7Twjwq5O-kq=lIlys`908)zfrg}uT)1G!5QB|7>^zE$D;tpIl`0 zP{SLj6W%~~C~u$z^aiT>ui*{US+N1$KzqXT=kKuw7j@A$N_YdExv6JvyNbsTUAU1? zW!UXFo;3WY>S7l8eE4r3qz~7%M@5hHIfVC5!xK?SZhLtDJbz_R;r(--@cubRdjFiY z5xXSj72zqa4%*sHhYwQbTF{gW@1LHEDTmrU-eK+J&+}vXc3{`h*|{oK_rR~_E@+B& zefg^r=PJDSsGE-3;?jci;K`A_#2F3U*+M;NZ}<8U_kZ4|+qIF;kRJdm+vfe3a^^Io60R-H5Z}X+d$u6>Psrtmsc#`n5sJ;9;sid5B{Xx z3WK^G`VTGmS#gJ4*YfkT{`{lsv)Wa>b`WVcw&;z;Y-=8i|5A98Mr%&~z}l8Ct&=_9 znHIcsQ7;`&vedow6zXd_-#U2h)j^MV>u(&q1$xx}b`K~ipF!*s%J1nQ_*nA|cCK1p zVe3~_W9v>S>B64LwqDD@Yuq6YGpgwg;IS2NA2K-2g5$?GdQ!sP2b1?t#CrDRz#83? z1exmGg#&&CuJoiN><1?Tf7x|J8$&JuzXI?@8Rnt1kGgH6=gKsl&*Vw+q#WM28k*G- z-8N{T!Dj;CGw>5hsY(h9j&Iu-dHq!zo$$umsoRI}5R_c0r7SqUF`{(6_s1>Ur?1wX zk9v|~9xu_I^plCQ!8f8P+iRh+8GcE_)Hk5#E@=7@%I8TE*EYku1ALAR##`w7@(~Rl(mM^rTNw1^{)^ZBOxj|O5YM@013f@?8tCcYu&)AZ zA2RfE_+jV`|5g8WM1vp5P6HPlzsT}z_u&a*53y}{QuvhNHZfrTK0W@?HTrqKQ6*vv zVLjSs|MU947~W6~ezIGX>!%yc^}qi}{7>0JtZ#sAL;HJivF8c46iCBhX+Y~a7oPB7 zCy?6i5o1r}j{+A5(=c`RZomWIh0YZ#;k&Tr>+3enh9@WFIM2wN7Cg*+utEDUV0gB9 z6Lie!ugdhD0s7`UhTY=m!|?Yq_DOiBa?y8TAolQ5@agJx{b}bZEOiWikY1~JO@clN zmbdQIcIEICsKLgBeh29d*vnDU+X3e)5Bv^R)%;lB_2u3GxKEz)5)5x-fqrP!*faQZ@qgv%&l4~~UoI#C^qm<3JkHgu-#si_n@>LQ=&U0MFu#8bW4KtAAxzmC6D zw|kVlbHzq`cjs>e4@lBd+!ecP?0EB|j@veOSlbmc?Y-(^z5Q36?wPGe`iV;xe&RAs ze&X<)!eZskz@}raXy+<-MU7_%o^m9pR8(_6-Lzo)g|Zg2at|TqmubNk$anZV?o;#i z?2W4!x1dYS2dMuAO?@H31gB2ade?m2XJc@a5qm9kFCX98xxB{n5d8d|r}sMAFl*tKb``cE*h{j)T`~8NlJTAul=ASG zI7{pEMV%AAD%`NW9#O4%J>|}2K6v@-@Tiu2bEkqP@I6JQhBEd^P-? zIah5urbYXbP~MSRQjN!@??`vU;~L-8OWS$f>EoAgbFM;7+!)o*`6xV>bw`=R-Wk1+ zXTx?rzw%A@D|mVGR>C^L4L>&r+BF3V_BRhX@H+g_B*8!3ay=bh-{SQF^iMagpYSQS zD#AbAHtfoLXQLK%cK>vDza92Ycg3ZkqxTea9#g*QqLgpCD2s2ptKgfC>jSpeK7sGL z=NeBtVZqrwJrnlv-L-z3;g|0B(l6b$Z=X;9T$f*E_~#l2zg*++ggT)9M6=ENs{Z@N zI9RWx1z!vp9=A5M*mL2nDk|#OvZzO-x2ksVRuw0_RmGj*ttv9V@K)u1swJ*xT#I{} z^3e4slZURW;GwIR{#3*3s7-h|f%jFkDu)x^rM#6ZJ@ohUBzhNop!ONn^xS&eWv7pC zuI>!303THWj>u0RUnjn1P9Ohd8%9gcVj++1HOANi^8eY99B2H-4gdEiwyBXU-@bDt zyq*V-2iiC8b!&+n)9M%t#8tYnUxWRCbJ(a(Giy`zKKej?qOOT=voT#=u#<0mZ$I+F z2hvLI%Z~%k9CJr!>NOtrJS}lh7Cfi-zM-yNh4W$T9=i?Wpl%;L=Mg@|=Af-USuHsO ze8b*Stvtzovu#oW{X($~vHqWFvH!Vu&=D7RYay{D%%j06I?R4norbjC3a)!b6KtPNoV=| zE~k(GyqdK|ucqw5s4tA^epZ_TzI_$e2-*)sXROWaB33qG=N$RHn%W|x;PqxE%)kyIz@@19c3gp`43Og`% zpCncQ^ip-Jm=xw3l8zQ_f={1MHROT zhqm!^RsjCVe08}kM<1^+(2b~v3_#s?CCGos-@+XQbI#hEMQ zOD7GO4Kt^#j4yE*!N^bDs=}FG6e4S+2TXWBnKKQLzH!WfzI?pq2;kDd;+9vaz2mE>T7n$YU;6w*Qy2^JbW@{FnUsgpDUmo_e4?aCi2BJ*guq`U?5Sxx2%!l3 z3n3H-du2S<^kAa_=zRfM-WMglUE&7-SuU^JfN6ltp8?4H_sIBN6233tmlDQ-MezEb zfb>_=2ax_shDm&c#HRr=-zo`TlC8Ar0)xRMHZ@5XLXN48N;pmXkH^efOpO+Bp_}-Mjc*Gx) z9{6dLM+GNNc>EZL4M!9XhP^my@m^KH>lWc^{GthIX##`I2VSZV{hP8B-B8eC-l;gu z^w#1%ldr45dopC>Fw+a5y|A5-9=bq?-kmrnJ={u!-Jq8y&k0od?!~z|pYwv&^R1Hk zcr8N)@=Y;L#jh&gGGONNEkpUdh-3L;aWEh6{VWc!wITo!)`DJJ^vVa2j~AjVY9KA> zq1%ajB03Zfz+R$=4<>^;Cf;)@d5VA z;SLR2u;ab4u#L~a+QhqauJHfE|Bsxz{l;Dp4$NZ=uItfnLhaSMv1T|OUQ(76m!@ad z+VpD>cehySd9r{r*dHz42HF>3{!Zxm2A%Z3*F44dVRX+uS8Qo1NY1ql)`H&z+*|l1 z(_GMWnc*9S81*zc#p)hTeRP+<*S*p_yb^2KD`8=Mt=8|wI?}qk;KS&>^}Nd}SAG3^ z%@c)%Irb7A+R%XK@dU8O`nT|Ig6Gk0?sEv-s-`Dol@uqjU6pYh9G{r5Zpy;$w0M={^JM`*-a{Ffat-q!okPVu%@ zLf_i?-sIdb%CzpTOIKsZt6yw^25FRSNP^H<_04@D{f}smO?6|brN>%e&YvCIbnLKt z$J@}BK@+}z7JRj0Q#tPSq`X%xzMA)LVw+fw@8-8RsViPTObUSMb z?RCLI+t6@}9njX)knfJz_0|Y zx!DfS0K-bP-f6*{MP>Axu8{iXban3bf-ACCbhEjIczTo;oCc2&EqOM5L>^Wj_I*jNV|uCX zXQJNv>R04eV;wk3idAYk+Y*aT=Ki+RT>5-~e~hwB?aP&mP8Qg}SuV+_&UFs1_J4lp zCr8~;3z~u(S;OO@A1=}VamaYXhecd&@AfrggKqcOpc84RV~<TprUM9=I|Piu`YH-Mf#|(@7y%Ez&$uMXSwDHt@W9XxYYcLfG2An z{J|urarS9P_WZmxpfDbLiyH4w>z1G!?@zV2G2p__m)h~xy2-cZ(9_|&;iXLp(hJNi ztfRDDX|LX%cXUe&{LTEeQz}+keRG=cE;UcSz4Vscc=7(`L*2Z*pJ#jw{~NT%;hT86v_-5j?l1koBp*Y9n_dg9o* z1ufa*k1nx=Ywz`qh|7Db*;(nyx{ID);!ozI*2L;!+mN|fNr`pDfh)2v(Fg0_WSz>_ zp}Sh9W1aB<*MSV^rffqqv7T;uiKl3Vds`H7w>SIrte8C*7_37h} z{+F#9<+wKXr07wGjX`$Fyu6e730b8H)p>Odc=q$E{0o{^Z{V}Lg>GwmPD0HkMGKl9 z+mHZT4V(uSG?nAr2JO}K(uANLayYm2=#MVRnv_*?5S#;Rx)yJ^s{lq>!5Jk6rwX9` zK7=%KuQ?kSH(j)CJKDA_qHWKozA2(@yV16Pe~9^DaS~hQ|81+S|FJ`3o7~`g3lEj( zu7gI-2hPZ;fmZRMFsG|-bl@p=2WEDKrvYcLzH9X4nqEDf#}+%rHdRhrt6!q48m8Zj zANNg$-wa2vq*qC=UQgs1;r{!j8-ZIyP(B4haF#kdTY9DrKUH|Q{VMb862#8Id$8gh zeYHzB=}F+xg=~`vbuH*K_vBB|J7uL7R9?kC?L7~^1ftS{zeWx>-ovFO)zX{5OJZGT zOMaKmu47NTxUxI7Ag1ro{XLtq?z|S>1lDIhT$d^CTB-lBVMKwdb*2wK(ZQGMKi2S^ z>ykYe!K(m#3M9Fck}_6iURdWz>e-~-nd;xyFfb~9PtRb$p57D~w#P)lxZ2(K&-*gr zjfBr-jJMc_A8bek?}V2tyayc~2i(|yZ6^E;^h9kxUtbA71dt96vvinUD>M!Zmr*vv z&dYAeJ{xCof{%=>r53kQtQw>)^t0k_`iT6A&?$X$dNjDqlCXyu$cJOwTJlOV-rh1V z4?Y*1lE*m4Kt7DoSEaYcU;a{z-je4y=8U}{OSKH!P~Q1v_?x1R%&~q6ET{xU8>EHs zT~L;};OoC^46ne%+R%;OtX+pr=5^Y(U3f`YvXQ)M`k`(4Zqz6w=C!A?x8-Pku}&SM z(>YkDKB{Tox`5!<%{k;ci;BswE6VE2R$(2rC-(yK9Ko%hT<>UfyXO^*KU!up#wgSe zE?qybU`?|V>!@4k#~>E#(|zRA^We!~Ux3eYDnBKIbznn#ytH;Jd`3N3JX~;!mi)`H z4m2&exETA;caDYp?$o&o{G|+Qi7C0KFXZ(tIkutd`j6^P=4(mkcfKI&evfTXc_uv$ z;5z7UM>S<`JcU)G#`;o@mF8|vJ;bMcs`ykMpEGxzA(yxoUkjdJJP*(LJW9T=ECX^W z!FbY{%Q8oO-3QO)#7@}*>UHx;ZA0c2(6`pUz(*)0{k8M6t8&Pt9uM&T zHCUZIs;PHGEx#2wTP=UKuC-eJc%7={d044#+;?BV+ua6#Ct?JXy|U9vPjz-n{xa~E zBz=gkgRgtUXvSR)eQ9-S{_l=O#X7Juw#x7qk*M{#qRuu_wKg>x@fVNV@-Do1*>sLZ zK9r-8{c<#tq5mVNQolm@J~)}54lfWppT%xT@B(o`)`@2 z)qdlxRKs80sHU~+>0je_)s!5s+W2NUUZT{{Yv)NXTF*gmr3Lq6H9n~&``5U7P?aZ zxPkX!t=xwd`dAlV`}z?r@!o^mbGH>-k#h;Wft<>NKM=P=yxX%6P6GPW9e@p!cC15J7mr8!)U zHjzp$xlGSLM9uVqrU0~`=WU;#r+Qp@tvBnz298&u!QGA(?dd18=4O}U>WuA_@YmOh zIt%POI5wE(K7IUG@a8f%`!RhfYXZ!QnJ1W@ znH+Ld)9kfd(;G2jS2cI~`1C5(Qr91zm)B7rk<*ehH#_feOI`);Mz0)O4psX*>c+^4 z?Q%iW3s~bl2_@y)anELsKSnjhZ4R#91RmPZo zr~it4zQJnD1Ps~E+GZ^eKrQ#Ix&&?ik}9ug`zO&t$D$^niAB2})%41ylldhHC*f;w zA=ZQUJ8*ZwGgu9Nc=InHv(>ZFSA+VVGw%D%@%L*;BUazq0BI}qnx3srtkI`Nv$WE^ zCB0zKmKf|A@2uSUsV5D2Yhb~CfvucZL63WZZCPaMIrO8Ty$Dn@3;J*I>MqdqDVj;P zhb7GAB3)LwVn%ZQGQu0i7rZq<^YD;VuGV6}nVy*Yo+o6Tk zly1_r*1NUcNlZ(^LBOGL^;?F!bn#Zdg5P?doP-l3yh*}|65c9dmW0%o^ZHx~r%On^0pn*$I7hAkidUn#8DB-OVW=S|j!dwZbOIRe~ED5&*vOVu31OthOxMDm03E%)Q>Pdh; zz?{jt#Vpqis8uSIsKZ_9Q9>`BV zPe(vL&mf5pllZN~asMphfO7y@zNZL5XEEgMfLN?s2lN37y*;4N+XH@zc;+7ocFXc+ z5aPO<2+2nXdq7W4h;lzgh;r>9M83}?-Ve0+9NdqG=?@Sh{Ru+Qc}?QYGQA_jE%T2h zME*x4zFXqlmxuLDy8zPBC4MU*%KIQ8u6stpT0+osL#fI5k%Y)MQNkS(9v}qW&j>*` z21-lfUP9#0C&cx;Boy`qDE|TC$p5v>*AoJd`NjhB{fq3C%#e@BV?BqYv#WSEcr zZJfj>5TcIfOFTe`x>zRhRfH(xzh=)6GFdQ5rZa37gpe}XF+_;5uz7>9ickVAWX}M* zqiK0_QsC!>3*e_r&6#~0%#^ZkpQ@#dzTw9y*|TQN$jg~MYwAoCy{!SSK?C~?*$Z&o zVGc}VK(iP590D`e7t2!tRK8xo(CtFH?6cA1JF?!FV@egA@}wUix~G;V@lVknD)BCv zm3esZepll#(@TazeJtWsQ1mhpVWzhXd@~twqzCpBqW5#0o9PvS9 zM7~!Q0;ul09Ovfy265js#PK=6Rzmk(hjX+67E^=`u-`C``PID$RoR&FAoA5B0=E}? zJ@US!&3mdgg;VW?3&GzN5#Z{S*O~K?&u|>4g332w$l!thihaaD-yq)*VIXntb@xlV zi@SyFBQAtR)Ko?YLSH078V8mqYzjhQcFZptb2b%?haJJU?y z+>w~eQ#;d8+YJr1cP~~OcQ1YzAFy+a)0?y#XmbI33oq;~=-(WATN~!8us*2K>0YVN z^JAwP%($iceV7L_=0%3q^+*{TvbM>l6eW;gp*x(JjHA{>AxO-z@Ucs0x z^9mAj>5^h=h1&Tvh zSD^H;uJ}*x9V4tOo=4;OGpf^k{HB#SrdObGwB<0aI%ilZ%rIZd6b`|k%M`cE9{-h{tw2YVnK>b`e_UN(;YIG)AvTO5kcv&iSi zHB$jqoVq{bA9W4ivlR9Y?{8WLdxwvty+ir|!~SK|S23H_+?cb0Eii0tF}g7sGyVy= z^9q!`#fN2WvA8(8>8RP_!b_?TqXf%0J%JKD!4g3Cz84l3?}jWc-U?Y_T&yNh1sw~02Y=JKPUX&Kct6Z4sD)s1x{a|U9ishUAd&98!XQVUKj zt!jk7py1!IKfDWjz8JeITqv~ETJY;dvBw-PE#(fet3svzO=vHcYN4a%y>3a>7%5^3AS?jL_x4E|s@R!>q#)^}6LhGJxD{;_SY4BA>NBFD(WIt^8x+6SwhtMa!5=Zog@LX3#X3>^z*=q|L6P-HX`A0(LL%xj9{Q zPvZ6*y`jo~ENawOf8W@WpAz1$r_xzJ9eiivz1Xj(vL)xQhcbgU7c|G>P4#QQ+r$iW z%{qd}e2D~B?h+$hhBoa>D!ksCXR zZO=J%*w!~QINAl9gQO~dR~_%ukqWDWsf%0k`*ZJ^z9al;jbARlP^`bYoi+zTqhZ(_ ze7@)|;l=!Q_)&f|!jJN(uYbDfF8EPyiSVO5s%hM&dDy9jew17CgvCMJ2-t1(fLyW- zotyo7;FTk>!)a@P{S~kp>xzOB!`@(*>j1P;skR{*us3*Xk$MN*xd$t_78&*i>&{_s zFhbbH81@F`i?AC?K|orv)e8tLi5n z_0wDIag^3ru$UUVk2cV+HQPy*Xn&JYH}q=VTHX8^Z}ZH$d1+&~ZsxL9(riPyyV0J2 zw?|88mlEDVJwL5jK3Qa^#C1g4u{^Lr*|Cg-HHPiVFX0FOeX*O-Upvhcy)L=ayu7v8 zha_1qNl(pd|MuKP|J+BE6Sm_nvk&+ptg9@PG~S`iY9bTyQNelK|6fO4cIhh47;Bt?rYG_8NGkGa@?J{her+b%U0spRd!i_cy1F_CC85+I6{a zk9r466WU$u)ML}<3cIYGQj4~;?ib*s1Ht`XLFwLYcEcjm86ZVtPo9=s>z+JQ78x~( zF@j@F2K8$*yp8O zj}v>moX9!}@8|SPt!e}|D)#I8On{9_hu{vZA>uJ!yTtZ8&HBgq@ZV;6{)+YoQ!LXz zHQ_IY&QFKV3>wz!T{a{B?AOnozAzm--;}I}b>$N!EqOhfyt7lYVcCRzUC8UTl%;h# z^se5(NPkP7yYcjJ4eQgdSXk8vtD`SZmd@;oRnoJ$=fIFsa)t#>uJt1dF356)_IJ4! z`@5XXtH51qOSQxkxkgJom47t)Cb6%}^(E`0wZ`jO-Pa`wE#Z{h*X2Fz>vF*{w>>R* zU!Yv?(X?y!h@5qDXP3uIxwFffhN{M>^X{q}AB=WC-q1H{)}9`a63Y;4Kd%t64)-Gs zuBO#F&tcygXKlV~${zOOY{*krlQw@u-VR8>HOK7sd3kQ^d9pokUUrYBpx<4SsE@(j zU>}*(lKsmD>=OpfH2l)^xw_8PbO6*2+yM_iB^(=b)! zO)S^8R$*QFp#43XvS#aOx6h<6tuyZUCrW%_!N#<~ClUf*G^~Rq)rGL6I?4T6U`usD z#uMos>v~|sLc7lo8+u2z7p*3FYV4{bJnT}=N(juJzoeZ{kCd@&sM z%UW<}u^~glHjN!ZHjTa3-E+n+DWjUYtW&$BczeL|#S1IOg8G0h@np_+?vQfCv1BdU z_#+eiws|xi^&a-pjOtI5Rr-h$lr<0dA=AmVsSU92pHlo5>FB7ZdcNfPto=&~s(p0}1 z$r~K%g|*~R^U(K4HN7ZyG0_rXsWOmvY}+m-E3k_R-y`m}!Zu=$iCt-MrLYlu6cQ9OLZWVH^Kk-}I7_PewBBMq?UhXjH)GT%?#-P=rqs?A z&)Sk#U-noTcQR4-%a6ed_l>o%Umn(yy+sRK;O<6TOWtF!OoD|McWc3u{v*2{?Pl^e z-sg0{*ukWd_Yu#{`}knf)cXD8aHHSJwTYp*@qVb7lg`7;%J zR$egdpeD{?FX(Q`9&m7?plHy(!q1&bF5H}`ztNy}D4C10P2Z-T<-7)rWWhqh5EVcRIx*YRxV>)uM%26x}+ zz8>~9FJ)rX$z4mL%1$3o+OA5HTCl#+9_voMI5*Wl;1y5?A!Bh`QC5Gni#6h5l^=ulzw4RYs>HxF{(j(ORu z^aOl!ojyKto3W2a)L`znv1?n{#%e)RfB0{3Z2vU6Z~e2;y|Hh{G49(@c|G3TlU3L= z8oP=*mXsVa@6_?=I_}i*$o9ycI!fUyuK18@Y1h59J?|emBm6tFlMj*J>Em+*wG@4= zu3=V#mR7H9+6cdKyG^@v(9WtFvU8%evr>C>+=l&fqL=WUOhT=CUNUU0%;@gHwz zyIrQA!py|3>Xn^F6l~AF2mH5D8{xlG<2yCv(p{TIh<;s?@Zlj!--`5mzHZn!vfv-N z7{!I^dqev1z1ZVqr;+~dMoN11F1|Vb=1w)&q@MTnoxDS={ySJB^O~}nkp=gBUA@sv zvn6*``q!XZxf9Y{+l7PIphw1>J|5hz%JSQdUG&zjdUR)IFb!7M9jn4NTK{ggUe912 zy;WPU@E#gP%G!%M78P`y{6AYS>KdFDYb+VRUsvck=~U`AQ6n~se@KH?_V1#gpuBr${P`)Li(#j;5M=HRVD$@mMpS7 zN`qwNp&yON^w5n(2HKKEriTh5)8j4m1BI(8(6-DR9MBZ?LA4C4B>qbaKF@+Lw%|)F_(luj76AbKq|y2S#JU$nF0pyEkQ}7HP(2 z*ufclo`g3+FpTC7do{k%Y4(oFn0U2?G+AN?0c00}_@?xKzSr60VYPwS-SgxK_dq5>`t1f`nBP z?vQYogu5ktRl?UKtd+1{!o3pilkk9q2POPe!p|fOO4uY}vxKK4q|*HV?ePMOdsz=< z5z6g3w`a~H^i1;!>wD*??(Z2sem;~E7882+%U<1|9 zX{29Ci1Z1By^Xz9*qKm z(zi>`D1+`C!tUsw65kCtpg(Lj0DXY*(MJAsLX@M35akwov*5Z1h{J&D1wxef4ViB) z#5waVB^&^mN{D>B36bv;LeM)!2s#PS9W&n$!XB_~0OWJz0`fVkh@(6^h_hTV#&xu> zi}9h}!2WsNE<(^-(H{9>?EVCx5Ac17e<<;0K<2*z!vfaFVnUQ>7a_`Vm=JXA=NWic zLgfDmA@V&Vaj{2BfABTn^uhBfAbs$B!SsQ69}t|RPg^x!H;WK-%LwuQsw93;raR9! z@(&|K{^=5bLgMtT!g4fAsKd^M`Bo7kp8ic({#ruZ=L?BPp$?edQ^Ln2{EQIScg5h5 zQ0(ynI0rcEe?B1V|9++qg6$+B=)6yed{G!H5l@sbg|HWF0SO1gHc!Uq0&;Jc>44nZ zrHJuEpwpG<5C__TVTRq04={!D;WBBH2ZOtG;9Y5WhhWZ^0G#nmVty1$;64e7+oeqt z`P?{(Pas6%e2E7LVe7R_;;RTr{M+~#qD7t(mSG=5p)F=26VKRTCY)?C+*6UJC}GPd zrE`QSpSm^j8u$D^xIfL+cy$nQ=iHwrU*-e56M^kxE!w0CPI)p75UfW_llTs_DehZ^ z?u9Rfu)W$sob$elUK41I1+IdkcMl@W^y0t^k`YIGV2St|G~lCvW_lyhMse#mcF6X?XXTnS z_A?dOmdy1*Tvv&J#B(jU=7*2R8B=G>NP&0CSs^UKr(zqHNws0AmEpaSx2G)TlTsFs z1dM@foI;3k(JuhIqEdwH#8`&UM|<{vO%^KqboFrGpA|W}rl^1QX3YExNuj>lO`fa% zdbWHRt_VJLu6#a8&wO9D0Toos>4yk256eP-O_p)Y!-ITr3=YLtaH_4wF`OqdD0-uS zo9Xczh3$xOEQ_Ky0q1yzA^;Kg;O@4{FLC1J214FB>-8;GXBUmF8L@gb+`RhZT9zR;~Bw+9+7a zc*L$>R|?&PAAYyvy!)el_2sZj?It~D|25yG58m=|o=;zPm6lv3_IFxyU#F$??< z-r{Ubb1YA{!*34f{k5bdOcr(9qA>pyf1#H6RPhJVUH2IK>@ZidUbIu|^M+x8)Popf zcQ%A~;?ern)cN5p`}2Au?ubm=*U$~+VD4QZ?Y~VI-aBg0EhBiZnfL5Q+UR&ssdJHI zF;+WA%zyHI{!sZZ+g&&qFH+&;zme&x_Zd0JkIjMe#$aKhZL&VdpCR%?f%VWQgcPq z(Yb`EfW;D)6M~s6BgBAj10e=#FG%mziIeZ! zA;-R*{0hI2@JE(>>VMO9QS3J=sNUEQ5oQ^*0fHe5aj147FPM)#F#`wNy6UCPI2Uak zkU`N)!?~GW91{56NY5L6o(fFI^js(q=eSk{;$sy8NIc(yKLDKlgztcIw8E0EO*49p zl%oQXa&&t3Z8L@REaERTYEuY*H6w2peN@bxIdy6Qp%9)piS(rZZJbsZMTwM)ELIG~W9COL`d2)PK7t;)p= z#8XbPzQ2oHR26KJiz4d#`_lWL^MCF`-LS1GImR(WEe;h7R%-YyGRvLSZIp{n5a)PB z1w}6n5oUT6Ty2qy37|JY5d&28ta32{30|b1OD^VuUR&hiYUInp!M6R+6ct8F{x(-Opd+L(ga=Wi^0 z?nIpSUbL;g#O2(x>+fk7BX9aA*o?d? z=iW2s(Y&%w2&Ujr^Jv$Jd9<6w?+;b>aBLM0s`VK$t<9mat*{O7IVoGf-a>)r<~eTS zi(tG~e%^|Up*C>**5}R!;r^UEyN(c@;8sHLcJVFpo#)QP zqkL~)89$_XGro5fRBP#n2s7`aADd(u$2>gP&NyyR`~#=rdy)KE1w}6v5oUVyW5c$> zIP*8gIN)GUMF1kahTpdEKJxGb$jkW&(&T*=eb5U9+Gga2uyEO}ypJ{rY(FZfXH?$= zm?6GnMq9oK1`RS?40z8yZ}#c8=6!*)^1i_TG2X}b9}cSZ88NN#J~clz1zE`Z%;NyI zAFpw#_$8ih!FinuOxLCvEkklYwvvAv{wE&hd*gsVtnsAzJ*rk?<$?6!)fx{Rjn}UD z1Dn7y9If#{&Sjc;;2h9XJj%=iDZl=^dEj*1Lj_fKD-Wb@gZd{GR6fN6#q?(zc;KMH zL)y#(*BXQT(D=^-4IlQL@xrId=m50`(PQhc&V?To|C(a0_tgE*u}ga7tgXc~Oatxj6f z$9c@d)T_FTu1(BK%t~s~az1cARm}CiIa%5s@6>Kw>o6g#dq@lE9yIUHPlLtrd0NVe z+DD?>=VE`^r1&g%&9!+OJ8S)yWI6YJ-q62OR0cNF+5d4~U;VcHL3)~A1--`K_pP~a zOfb!XwGX~E#ia5vJo7)cZ;$Yca!K#tUR&bJU#8jrlJ-vY(LITI?>UWr6l9=l~y!CPA*@80PwcfZJTcUw71Deg!5`*3%2X^5-Re8TxA zu_j#2j;Wb3lKYuL|KD8k8TsYj;~{mI!1VhR0!aK}3;u)! z*Nj~xjV~I^Or4?jIqNQy-{tGZAZi&r%)D*-Y|N5L`|v5*v$C;U<*%}*7fd!%w52FJ z^)g;URP5d|N)i6viXJ$cJ>157*6NJg%G1{1<9k0MG|m zN*wcIWyAp=Abt^S2#Eu-99^O818HH?%y&#Z&=83aC&V{dmc*wJQaJugHh#*k!SqtX z6JX)ZKf`gdQop}J%n#{1ZX_GM41B)~)-g;L-T~h^`yli1AfAbXm#f}g1f&SK3X0xn zM3~1gxuEAo9O>~|Mek=gH`6-+g#A$kMek-rnCX>)UM}KDkL6PI@^MajDsb#nst`a$ zkL}h>F9>=*#E~93k)ro2oSVm3r$DbQ-~SfjE+V=UTdXj|-kxN6EA$Lbx zaK8mF08VfA5IvN$(1Okz7|t{nUBsv`&%VV)tVhvY6dRz^t2!Fk3B zgy=#!gkTIsgpi30)Df{}sUsQ($o!KCk$*ZN@>8}lzmS!vbR{c=j08Rs>EA^+#9Bhl zn4}-4@m~HE>%!1x*sCgmeXWHE*P~J=bZOu9v+l6V{ov&sg_=e^D-PND0-ap zG}GhyA|K*NkJl=CH{zW1R2U9qqCx-_z416V)2lL-&nyG8kPk_0ULur(URz|=tH|fY zfuWkayY ztddHl!SQ6RZanR)JQ)b4wc}T-k}008amxDOv_of}q%0$sXD92!%3Knqea^}^e~LK8Q%GYLjtrj2py-jmn&}M(Jul)&&&)Tc05`L&D&TG5n?dB`!RDu) z*@JW5)66#yps>Rbr-CZGm2XZ&`S>g(Ow^)DOLW?SrXqp~9SrmfFy`!Sz- zRY30oFVz=Gi|p%b{e>SyU$w_}<#@f_fm=HJvyyTLWc1BQf|r_aPT$!%rPiO@4Re>B zw-HaS_UG0&Ypb7!zs$jUOt(((fkdx3-<&Sh{keVg>-FI}{pY=38`o%a^~n0&u^87a zo%`s1K}}1VcQdW6+wB>vW9IYT@tGIm?porAqW7b}s$YZejxVJh_7@Fn?t9Ypg2XBt zc!zZj{=)tEK3Q|$GHCwA4D7v{x9BRva{Ft}1ByMow5=EDTrorYGw$StYtIU0# zcmPL6ytmZ7D0*?!y{xTkT+&&LsHWv|69Q-#>DuL@+uAG3pern2t<>PiJATdcBgEf{_pGATL0e3UU`aIhV! z5mZMY=C-crS-%-R1wFn)tL(FWGx$KS2>Db{^sL_u92j|#$twG@5QkfZNUR3Ew#YvE zwn)QqF4>m=;=jf{RKO)7SY@9VKLb9*5 zwV9qRqoH*hSUZs`E)3SO)AJ}Rihdv`@20F@76S#8WOX)6p`nD zJ=0V%>-0mFC!AXi2h~cAn15z>!RMsB;5c3dus_YK5J2MT7JP~Y*TB!&f(*M0aUSs{ zVVw;6E}9wM+Pr4-I^eWBWBVpA4-kUK^O?wl+0VcInoZ-uzQ3=IAC}$41E?DnRI9P_ zUe5J%yufic^Y9?=9gRcr5u9qfa17yz42quB?qW6Qu}zU4`L?3R_h{yoO~Bj2EBm1k z2auP2K$TI^H&_r75aMv(>Bgz}Rb{vG%1Y$>XLc8Pg;S;#wSiX-9WuPlyz(`SJrF{? zvOBh0#yI+{`t;Gc;Te|Y=}z4y)^q+gH~Lzx%{11me4Oh7<^-m8&Gqce#Z78)xVK(g z_`cLJ*f557!_I)bk!Sxb&9@czb?(B^|8x72B)$LV&h?8b1Ap@boQ)mND6#f1a*LHR zw$Pb9bmn-t|A~**X+5xa`YkG-cH*IX&(Cr;-m3N1or#}hxf30TnL4e9@M!C7oTwel zF8$oSzV!1L?DC8?FpbkSXXAXEJMnkZ+9mD!5?*qV--g54xEnP5x9x6zZNl$vGxF|2 z-dsoN=ZUz!d-d+-QlAlj5b^bK?!?~u?&jJF9YDt}=s3T6tY~-hKHu)E|Os?aFHG75tfV{m#$qOVobC&0C{&JXgp^CeDSPrE{*pil^0J5CBkHp=)`^fn>d-dj>Lv!12Nzq?v7~k~HFNcdSMW-Iv z;>vO+_14E^jc=-*5$EfnuNLK2ttwLzB48Ygs6s-CEi3Z1*z-W0~`B66-bSmWNRd9A6DcQW#! z>4)YHASxo}ABn5LF{F7MnFd@p_F=v;#@K;5LS{1W=y-PtZCA{))Eqw!c~l_J3az!$ z<2$-0xLnse$HaGc-PF!?v)lEPXxC4pM#m4gm&A8ZkNQc}Por*%x;egMdenrd>(y4x z=JN47WpsQ(NmQw8k#n)*UY5hFZU#u+it=$E=}EHuWBC~7XXd#Tr|eXLGC)4#^>6$! zUdYw6rH!T__yO)Ay&J_M-)G&~A$iU=)IVleAc-ZRw`$!mJ;xB5Cu=GGxP2g>oKQsnI@lmGK*XkPMmx@ z_8X-$R^b4Zs+^E7gI1j-NdF08&j-pE0NBxOq{{IFDyCLfIfzN@By-I&?g>y zIDO)=r*`c}o`d-Q#<-ro3CSVo8_z2td8HlkBPARJ*cIudL!XEOVlvW7hkSE@&(L%E z0DBT2Xsi?U0U}Bp0AfP`eSjl~4>s0H`2aJBBXKO#0Vfg%yS|k;;9S5Md~7^G2xUT* z#A_uke6u1w8SS?#(%C-;;9*!VK0vmAmfyp86o${ia*A^ImgNRyzajk_m=D+eg!up` zF&@uN{=jmqBD`GAM*`nP97JCQ<-9wC7uuIqP_uH-?Z)UFdrbFlfEVSoV-7uljRcE zOeda9h)fw0A4`avuzfH+i|{-{e?)u^aTI#DOn;T|Lc^yo(?2B+`%5?43-LHYC~dhm zm3S9I2rITH;zC|S9A!v+Ea9af@~!MK1p|%bNa2~}NG=Ma!oMgM<*t0U=a2CO< zOw-qjH(7E-x^!tZQSmEtqM379;!QkEq|in;1$P&MAth(#Od``Xb#^A}Hm>?UHhAV( z1g}xFd4Pzy5#mf^=!S#mYOZ1kBTYf&Lo*TW_+0tW&Cj?m`-2Kjd4ldD=1bBfUWrbL zE+fjrJUq}P#2AQWVBck!fFq43GAMdi18;{TO~!v}qQ`3$y{R}i(<=wwTKTdOZ>HzP z93RWm4F{p3$1#?f-Ui^U(VLBUGreRJJ@O+(?;#7lSAnyCs-T{C2_nq&=zn)L;#fYg zju5@)aBeOi{ZH>hoC=EGCPbL&)q)=DhV;lMRry}VxtSjKcIG=#LD72&5oUT>C{z*R zNY8^q(W}R~nVuI7jOABB(W^y-nI88$NI)Fvk$)?CjW{>c>vtAY7Z**;T-@dh_`b9~a_cg2v^X(kpv}-E%iHdi7ubE>T_?ImyL5IT|>=KvLXI#(| zHzsIzxNEL!3S8-~ozsVBTA`!1Zy#q(mi~l(ezR?W*5^=N=FxaZQWk01u`ix2etc7D z5oY0fIK5aS7yni(x-7O&6&B(oG}pv)3YZ_@+zi`6IH*=>#Bh%nb8u+UqL1-0=YdsJ?v1W-OgP``k4G#XN#s>XR7pyZS%h?o4aj2kbo%(W9 z*Am}DyjBI3FBK7dZ)q~29v87slSlE5F(1#z;V|=zgTULuGdNCOjl8@E57KLmXY4>e z48KD`mEFoS=zrkWP_FPZDxM)-jh%bF$K`Feo#mPugb>f*dXM1N^MtRlsF1I*t7~1- z|0Z|%O0SJwF}~@8nU~8rdsp8FnBNxj>roZzEIM@N4xP2DP@c#9g&#>Pt=@Z_jb2Cp z=RPU^UGWjuLFxx$F0A(p4G^updhGGS_gGMP<sLbyKSp{Zv#+>Gr%<;dImwo%S9jqhrI&)iRf1rF;fp~X?01`L%UE=KbDiEiRRt4gj3IQa3odwUf z;KdevsRe)Bg4bB^kAb6Wig6_Emm4hU+BDHK4c;!!jR`M<$&=e-nv7YD=yQ5CYh{Kk zaw@PbzC)+cSDLtCs8c{q`gvo?x>$GQ}ET=sK-yzql@ZE9k=Wsx-{Sm-v+&&GKV=x7((OKceOKj;`8pKulR#qsXZe|#Aomu*XhJ~%<9Vh3|) z#(N%grpG5-9q&QzIOP5V`}q%5zOt=_gKFtU%zwxFnjRp{cEdWOeClu9O8l~IYSW5l z7U$cKe_D&hepI_`b}%mi4KEYBB5&W?n`=Yvf^8UYm(HGrbAG&3#GH z8*QO?6X>w0=$o7dRTk0(L|ul2z1PDk)j z_m=d6PS5AS=Z?Mpsr$-Z7w$=fUmbqgo-y&BpTvOI$6h6VBfkUkkuNhouGFyzRzPsL^Hbr|89CwQ z`G?Bq*$%_Oc+m>~E^FjjXRUolnJq%t4>)#Gfq1q;0Ey?}U>j%MQZC#9r~=a=7ue$E zcMH!c6BM*4|G$lMWqkS=E96NtQnK)ykn&>$A-*5R5kjs^BE)wCgL!>CWgGMBgvihD z1?JBoM1HFr8i{zyr8L6tB8QAxF-svn%fID#pY2Ws)tdVug6%v_CQ!fO#ko}mjX@mS znv!YDa6TP}3W}a}ygw22e8@z4yq5VWqqQ%XT^nE3gBa91Xf*g2cEsr340!PURn>o zdN(9BX*WJq?4P#WIiNmScdY9sq?NzWrPE%Uvvr<5$$B)TN4e{KTy=2IO6So%SQj%i z*s#)hNSu8k=irQdpyThAj*vcKOnh>I zkRUgTU%o>X{x8nYv2I$EE9S8$+jehNNr1$!wcxi~@Y%rGj#;OaGvxG;Nt+#|M z;OfDdvu0pX4(-CG-6{P0w=!4tU1g4Cr6u1#Wyn}U$dG#oAw%vbgbZ0lC<<)MNs-6+ z@KDIo>YUQ|C}S+^DOpGVo-&4QPzA-q`ys+CW0JwIk`Z?<8M6<0+A^m!0rXn?&aujv zAn37esG!Pcl`*-X=S8M-$r$Rz+ahD=PmOCi**?`Xvl&`t%xcJ(dl9b!E)l^hV<-cQ zR3<=`PstcgK(|HrJjmB}|I}6Z_D6`2G4LZW-rnM9E~$)LRfYBb*JF>j_WE*o)-rsF zO_dVnf}qWIRb9Dj+@9Y!e_Br&Ls{dW_Ehl-=eYXYa@X9a4fqf2^rppZ*MEvtFwWI0 zqbJt9te>~%sssF5N`mhJpPrhLB-V#$$#>RWk+JSrbj)qJ-Ev3h$@)(-kG*|^{;H5G z^+&WpPaTV~=VUqX>n}{qdOzAFB$r+K5lF+@PWT;o=wau!Jx@AoAhR@glayJMhyKEc zog4P7a6TteK5AIz+_HN8Cj>S0q zS=VoY8DQ<1d)3{X@p`kfeEjqE&7SgZIz1@(@Y}JnN7n8m&Y$v0{kd8q&R1TNu^Xv5 zS-ZBK?sOO)59pC?&3(&VNqeG?xixM1>SHk)^9SIQ!FZbepzJSvRlm0(r|_NVXnb!z z>T=?V)pwjjT(_&Uan*eJyze%6xW+}y{Vl}aL!9~3DlX7tbVKrs@6t2;CJbRqkYP6( zUwVA^(sqm7i=*$2Ds$cEyx*||-*{umZsa*+cPsuAtQPFwMVwC#ZKEfQLnhD8o04~@QILoa%PA-;W&8|6$at2W_;Z91 z}k@j1juv#q+)@D0<>!9{`Ix@(=W&#DX7Ct7exfF9YkzFP3XK&NP}adY6W z`NWWILN)BqUF{y51M2O<)~#%vA^)QQ+Vc|MmeetxFcj2qlIi> zY@suI=*&^U-SV8m4yFNiFoqQj$4s`m^{x@HfQjaqq=a6LdhUs=j|EM0HdFSG4egPu zd5zrOB>2G}u%Kz~X4X$ytx+#)?i(L$*A8FTm$5eHNJ(#{dEMrEnX;=v+18NCf~FsD z)&}gW9WTZ^eZ{ZV?N7~G`EQF^-gdRd7d@YUyQJ`(gpK&7H}0Iy@A@|TVe*M)WBjl` zr^k0Gjb0SB*mbY7%yFL>OANP{$HaF@kHzLo_(fLsWfi*MdYJ7=MoY^8Y7^MA>zqJ8wkoF1chqr z$w}BEQUNa=ujPaQJ&{`qQJEROHV8UU{hUB}XXIi_#df?^gUbALMkndi&e&=74L0<% zUgo8(ZzIKb8rtZjt?%^v|JT~j-fM3T<^XX_oq3Xd)^$I7?X}nXKhL_0118<(7z^EX zf$*T-aaADv#(;Ziz-_i|$p7I$_)`J*-v`{3?LxetGG2)85b^>4YV4AF&1gCtVmQ?a zb0&{=seTD(!lpZm$I(XIg>pl!sPhh|4Jt(^Gatv>yECguV?L=$s?{*ERpd^b%La?bP2 zheGx$%?U^kO~ilOG4VKSDh5+n!{RWB6`A(Sngf68a`R}OlJ0iwtRY>tKA!p;@kWSw zOqznr)Zbo({?P-!p#C-+e!N}uw<*wjh~GlOuMQq2Kb{T4??`^Um+`0%2FJ4JfL{v! zLc))IK_-oveDlTAs)*iinaUB#2h{o{9NkBgU(AM(TKSzVQya#CaZ+|Nd~6a*s0YxelmS<%0P~`41>{iDfV5 zy0m<+hMVPx`A7L^Ez_k)HT1RJCmJw)NJXH8bZxko#bhczC{q}RNq&?Y5E;s3I?Oh5 zgX30sd(t@TB+zRidubZB(b|!REjic+v=!r9Nj z-{hA9Ki(h2*=ylPenRVESs@OXlD>tooBYz?7lU6AXBWfI#M!su&IV^=NJKy4qS$>P z&T`IBCVoMj-Hdo^z)MKp(ZyNJvd*S2eOgWS^D}qjnIIp|qCLgEhq7)n@%@FE_bdZK z{LX(2?ID&EkE8@?pHt~qC8tdNs^`F;-5b+Xt$gl16d&>NJ<+&Ods4PB! zbZ(yLd<=7sa;0;^KZu2uxQEzSMf0Sw5YVS*|9fbtQ#Wi#2(?<}mEecg37i*p!sse< z?4siwFW#pRkGL{aytu>9e6CqC#6AV_Oq_WKA69USad^>PkBi@2_|1ep6AlLZ3kPtM z;41GGe$*q$Pv{z0E)fSzNnfzPumE*FhVUQ`rr>AdU_0EIaEs5>umKC`MO@k7;4`>! znz}>(NZNxqNIkqIL%gZAwQ)y*%&NceMD}Ry&VYm1ORZvTTJ^5YEbaHQQ@W0IQAE`Pc%Zo=+y0p)!^cgWvj@M_z zGQzweMpCyFDxw8A!=oBJl%z{*h#Hcd2mzpE9b%iGpWK{hj%K^^=l3#oM%Hh-<1|kR zC!O^9kWw8s@v+28v)oH*31TI&C=*r&+vanS_m#MWgkK#zOza&GewnZ`*fw8*`x3$o zrtk~4&51=Zga@&53H(f~d<^bvu<|X$%LXgiuXG{e3b7uLf>=2Z>1)+N>Q~~4&d5Ve zveOv_T8BO#oa0EKOgdwv8*6hzb}>=&n6df-b({WSew%LA=aGtgEMFc;NzpzZrf$eQ z$*dcyuj=TA&apN6{2HYj(kB3UDzTY#Lw*DL2QjY_{==agI;k@dPo?f-iFann5c?G5 zqlr(f*O~AxlWxfGFC_eey5Sq(mkIBJx*_p1F3eyGzo2eNT{DL8Al{|mXX4#DxU<2# zPQ>fS#d1cTd@kRMc>;be?ZI=i(G7|3E$&^O{tMl(rbZ7AXQdm~Ov`><%}rWickzz< z_jh3LVr*W}#(8H2HqMmp-q_h@f6^}P&pT~W&zRO<2p2f{&&EX@-@ZKY#(W8%sBH<&itf_9es;DEmy{p6CWp^Yuca`AY zw$)budu^w?Pqg}@8|K<&&7pRt;DIfnUF8Gqi&GCKSKPVxC_`o@Ne)KwF{nzAN$aDV6SA0M{9nRnsdK5c#p zqrdWwGt@chJePbg&OiS{e0?8J*4c?QL}w!ptq$w_+8(QFR?k)TH`0$Jo0_Y-Cfl)e zE;fuFCd?XaP%4QnW^GDzNrnU2% zM@Hv#V5Z*aNC!?fy>wvo6U>!=X{bn_)%Wo1Vw94Hae~oYCnqb?Iw!9{E?SfS*8wlL ze$w;BKIVLVpS43yqT8Fs7cJR~d>@DSn-QYF2xl-RY<>w{nl2sq^C#x?>3ol1&cjy* z&U~T_sbuKhEd}K`!#!4k(fgTwx0G(PFYDuc2<twXB!uWTv5@YW5(ty- zM8G{a;9eMTHwN4*0&dHh8Sk{E{4?d(-j0SA_M=7LySvG%GY1dG%GKPU)jfNh0qP_p zJ$a6E=T@%97Pgo}wgTI?s^;06rAuMnhBV}3py6$r$k0KW5EPZjDE8ssKocGLQD8pD zdZ~+Z9^ERM2xosO!`X*P_uo3^3y%LQG@&s6j3yeHO2v3&%yAmBKTP9F?ohy z7Cm7K^32p@*5zn9Oh3lqMZM-STrB58mw;DF9597nJ?tjGx51C)nto;<*EMj1MGFi? zyWz-2@90H5&T~icQat%w;g2AfqIhnm_7jSYPd^z%yd~~k-aAS=>-NSKS@q4&a(7x7 zx}C*w1CXnCaF4a~4-eMo+M97&9`uUQx28j%DZ-fvd$)wD^M3O5ZwupPIPWerJ>1iM z+2y~)q?6C2YnPY)>cE9*>w>or@Qk~`jmPer5L1uQKS>xkTyA5Yf7a6!`On>Wl| z)*e0WU@z8j+>JS&GY;aco6eT!5$h{uD(>N)Z8!!d=aDL`yf08IHVbxycFkQC?hl2F zo|^pZ-B^1W?$zhy25Bu-c-6ST~Fd2ap!ZIo(C4UM$i1P_2U=M@_+fCB%#CVh^%yX7Qkz+A9D&ZCqehGM({9Xk= zwjIci_X@vjVHa5dtJ=FhMT}XCv>}7f78K z#npXh)+;^}{9G!4W2@`((jJs|MM%(^4DlR!hjY@KIJ7YIeqk5RaJuG()_EIrX8Giu zwLffc?9}TxFX*{Ktw5vKL8Pke#SHx{G2^>%j&xmN^xjaium}<@S~uoO^=rnt3vu*39DkgV+P}j3 z;E~iI?L*n-50{!O;r>vbC&fC3s-fnSQ?`xMQPnT&$jR<^!+fPIqnr>TKTFjPEy-xr za%>H($~LqR^T#;8*dp_Q&`RR*YEC;%$SmRsWflR2GK*yHcQX%e#=n6k;;*2I`0HsR zzG?>nM5Nz@m`a(&xhAI|vz%=4B$j%WkEy(3UJ6NRo&pb39&jJW82p0rirDf~VMyUFiqBYmu4j7ReexDdqRrKlbJ zvXNIWB3=v^ik|zXk;OElYVO?*<1Ggv&$}9HynDtQNVQi>2egb1d(`vGBpS2@x zAfLRdQ={LW>?lraAHJtKFNkg-ep}Pcd>E!^Lk& zJF#{WOdrPi*;V!neP?EzT@fsLF_994z=QbAtYCkp{p;tHJiSvn(X)b z`e6p_6OBCTXynD~S}ubg+f@%uy&jr+^z{fd^>B**qFZM(Ux?q*#K%gwM=CykSp720 z1LEUEm_jTwRk--QnJ2_YbKV%k6+YtY8``Ko9c(E#(?Iu%qn0YPl#l>eQU{cILYyH&oUvn zNu1+15fXkJuQPG;c=IQl5Kl0LJX&zYX>mySErQ$R$1&R&{DQd2`%T>319vvK`6}Y| z;~EM#saqxyPe{@p#Lam~Uz3ScCPlEO$n z%3OcLvMSj5Az@@7<$jnn1BXw;99jLrW(kqf6~s!e70-l~SK|9fS>m@lo{l*eVJ5b* z0YQu=wy_-Yx#ZuBi~NL$y>W5Cl=Lly-Q-scelhq3v6AB`CRTnJI_6b)hLEH^h?O&u zzPlt6Oo<1qyy%3maz^%h{f*a|<+iUm_tKhF++|f^CdB-Sc0pID!m6+?$m^=d9zIs} zssqvV9rhN?#N7SVm~^B%{u9wMi_^LX`G%ggtA3Ju$-$otS_}5rq0gM#kgIm~t1taj z&ojyBU}#K5PuzYiIdA|miW2txU)GJeUd@JUd+Na>c{%?wh#vm4+U!S<5AK=$sUF;ESrrv6n1S(^Pi@(m)79IlMneC- z?hcFH4B- zHgUkDdvm}|IkIHwisqFvaZcPm+2B)SEoUYiH1DB1dHpdmjdtqM%SDTpu358cwRHi~ z$8)V~VDemR)@#nKW808@yxSe~MVb)0Kc)#izTYw5qlrv?pC(?IdO!PkiF2niXU@%* zk7@sIfq)_MNlI-{{%~*D1qdhRGY&7x3+dy4RZ#-GW{Lx*@T-H}loxxzk7bg6ru^YI zH|51T@XJQG=KPi-Tx`Ee8ihajxzr6g(C)fCIS`Z=ow#XnhIo({vo1P;{@7U;%Bs(y z#}C=>1M>*mtJ_usV@%mr+9Y$(@0`&opq%>%sOqhu3tT2)9L`-De72@|KX02#m zwbXztI)O)SEmdW1A_~GV)_?VkVXXdY4mCfwNQGK?NypSh!RtSkGJL#vpTd32v!UX} z5hwUu-X|nqC|Li~xQX$kZb|)bfS;t5JSdZ5v^XUE5^$UKzXdl*{WROdAiB`7=MT)temv$m{qfxT&-rqL z`*ZF3o~Cl(-H3>V9pyffd6vPr`)ET9(T3+E;Y;TA{W;!bkGnHcFR2j!Q;E~iq z?L!&o4;OTiaMnnVDC0zbXMRz}1=k8zdeIf0To7;*-&u#4my~JN%Eskbb|PnTE?Voj z*~PtVZEK^NlIAY#ThzR^v9Bd&v2?uC0F3Ka~73C4@EalJF9QSx9oTk~& zt>g{BfqLyJ$Q?7?UI#aZFTF$#pAZ^JGU#pOn~;>QDey4c0@oNA&p5nTvN*oSvLL0d z6b_aPA>mgK50hUj`0;+0UEVAFC^N`Uh=)Q_K zFis9~+bXA_=6^bdIt9=A<^B6d+26yA;{vo=tp2aIEm!lNA4PBRpJ7*ay;J=7eHH7h z>be8d(xFE~<=QXTZr?}Q619t;{luZu8kUsg_vmxZD(sN`Y3I(+#G|jFXWZ(>rDM16 zgF6@Q-0-2?hRTe0Sye}0yJgjWtN?!{w_>1e;lmq3y}NQQJQ(The?F$#O1bK((S}Ri z`!B{*%bln4e*aUgsy#ja=iZkgwY=}1zK2vRtIaX_Os0HIAMRIkw2#-8VqFp9S>DOQ z@m@=+zAzTXk!|Da#{8-JMMRbaloYe ze+1n3!_D+CY%JdA!9cj>)N0I&!3>gl^>O}8vnpG0FsZ8VN1Urj=l5`3yOP8B$P4I3Lzpm=1zvB4626HMt|G&bF!~7Zj5$_$xzu)oy5Bh^2 z$70CuOqyq)ElTrDjK$D&3e{9h@??pO!(@G%DD%vrR}{ld{h@&-+$;xSg8T`c@4b3S zV{79D?w7m(-)!0iwZ;r0H^}gFa{Z5AkC=k&LUz07D%8R*IsmLH?-_nME}9ZX9gX!@ zh~J1r8EVS&1qgT%e*AV6V~mHQX5Ea-Xb1eta+T20xefz|rZt zytD`PjRi>G-5KJEzOklxRcm&8s!z{)ZBBadD^7_HXrz;Nfy zgV7_A&X&upuG5}|bPadovi4&QRyz9VhO`$mqGCo7llg46`=%K0HW7ArPj#$Ox;Kj6 z%*zUkk}u=L?eG5MchH3J&5x*3@r&A`8zOgvH-=^xj=wjjt}u3a;dtCp#5=lq%O8zg zW?F^V9`ws?sd+la2kouSd}Mpjl*=rG6}V6|RUZ`Fdy`=oVz||!OOu}esT~w(w=Hw+ z+TxQox_q;}M^)S0CzEoX{(yL2JFmfUE4*eUJ|Vou<_LPv1UFG$BhN|R@WJwk8as+1 ztAqs4Sbt1BTY!&1e3iD2;2HCr-(E`5HL$b(2noLgJWPJqfgkaf{CKbMyB2ox6Iu^T zt2kf^Kk8y8Klb&-;75K;r|?@0J7A{;hN6D_W`nm?NCe}en7QxFvK+))&Y7Yi#-2vM*514^`E-|65vq9ZX#Qz=u&v!UF1^IQzV!6e#zCw5YBjRdfmN`lF>T9{wgUUQ(xTK^Endoskg^DR3}f~rTXrRj+W*G1sg#Cx z_PXiP@tpI)cm87^zq=_bdxi&fL6*G^w8-(#9?h8fq6h)eF15rT%yj% z{>eY12~A-$O->X8nd4;3;AVW{8{>bOCgR^iQ`#c{9Mv9yzDC`c?UDq|Q;=^uTMX&O zSNWLAHkK11Da}*hVakqn2#6T`g0d|MKjO5=wijW~#P754H~DeiQ5=3j*+!WqxDTs! z6C5d89Fp{X4sMg*AtQaJY-4#tP>bCE9Qb7;+tePbh>N1JO%k=+Z};*uk4Q#KfbGp=X4A4`VrAPv!~nb`ne>hFb(#Oz<}#m(%@$x(@m};Q^>rI(??K zuYkV~bFG4t8l=w;e@OH2A>c?FyD{atl$I&TV;{cY12bL_|7OFF-(K*K@@G6QA>mgC z50l^9xG9rv|0jq?enJaiiHifK@VgpzlOGF941P?XiGNGrHu0|w?riYy8N}_J^%dMMG5HRU3aIwzLwC%i+u^1u+ z@wo+lCO+qZc_uvNGg;<@67cAU14Z!z@i~s0l5!JF@*xHB`Dw&!Qz80C;z2*1G3|u( zQ&|Ww^w@g0ejy(|N9;U%M?goNkk&qYR}(Mk79!S|Zr1ma+JC_D36G@2XdmLDKU_+# zgtL@;WUjMi9uOBRyC-a23SRV)%{nQ7I=7Ln9qaPDRMHEExgCtX&NpI!% z`4HFG1{0M@f&CDWa%8QsHS2(stSQKM6Waz+7&2kym59f3A|);XJIjoa@S6({lOKU8 z6IM1Op5O?1EWj0~#UbIh6mFAWwrgzLa9=i9c_O;(d?#%*B<(@0Jl+~xPnXSd&BR67 zj|;BQndM?7=OMAa$M@#|F}Gj_5_^kpSsp5rnKmySjwW6@JZf5AL%1UP@MGyn`%8yI zY?dMFEhN=;(pL4$TEcMZ>@-DQ&4j%hmypyZ>N}=< z;k;SK<#)r7f$CFXz2tlsliwiRs?5S93BPM$H~BpVe*EU-#~R3Zv^$iFp9G3Sm48cw?in+ngWnO1`ZBGYQPoY?t|$1kkKa$$r! zTT%?&R(M8dmMi}_FXrwok^a$<(bb_Io;xLSPoHZ@xme)tNZhDSsq-4^LJr}x^c-W zj=dX@_VDP*FXDtKEfK$qleM(%nP>NI*^{d1&x`D7eBAYYLhUQDQ=RQJp^NWQ-ye&3 zr*A#pH@cjz$*H{?-aBS&mSst(6qcAcXrgQwa@84w9l0`;P>Lk0bD6^^%`BfD>4G9| zwx|5zf)+YPrnx-CaUs@|m^fh4JsB6D&!0^FOdRVHVtiX1FzIIBtq|QQaloW|dBD9c z;Kt?@s)jXLE7ZhSH5;~hWy`H=mM&^(#jt{V&J*{IQ*qh9wM?Jr1ivq?xD_kOojW)M z6M@FDDwM!7q1If`0srPz&8-SUrlLSmZpL8}`z8WhmcgVv{W8p{c#%684s$cz_z1+7 zILvms@fo($4Ra?<%GbwfLcTsj6Z~GLiI34s6LOZ{g>sb7<31Oaj=PFx9)3LtszmU|HDey35kjOOY`)536aUCv`-vYRGWuV2A zX`g}JyOW=n`wZKrc9sIJ9kv~Md z6fP8Jb@91HxPmfr3YfRSUkJA-BE}%dCGL^m>bkrva%Ch>WXncI*38IyF4Hqw==)@3 z-hQ?VLvij!gdLgG`RIB3MOHeiF#_St1GArv^-hR&KGWIg?28xwk=pj6-0+BB*rQV! zk6@l;n)6u(f0hsC4dn!JN{D3(IIc>8p7W_41ZwoEHLqF@oAz>%n%K@yoN2x%^}0;+ zJz1|g9ucQW<@BU55}P0~rAU$olTPA>4Iw|e_6GBY-^s*Cv&>6L31TGAJR~LtF|r}R zZw}lsTtdPx0S^#K;~bmU2c&(tZp^B7JKl5=@EbV&tmEm04kAd|KA?>&N4nAQvOK zSDm0CM`v~G;n?%{_|8HK1NnmL5F;x@eK6;u^Xsfp`MGs@q0!;|NI__9bbRQH&?h6s zp|e6Iq0-RAaJjsn@S$n?MXjTMFvB9gP<}I=c!?A7NgRep1M}9UWavAHaVAmsWt)&` z5DYWRJ-=-Xmk`~+B=uDkW@)<*pMVq$2U2L_K4(k?_c z?!kv+9TvO!3LOuBf;t-aF_-#m>S$Mjk%qTH1<3V%~q zO5wSzLqd}FAYMF;fGDoW6|;LL>H zarc&r{#4}d4Lr%nqHa}ymVUv;PRtCqOYBhl8-viNsD=4se&GBM>gejcp!&k1%M1Pc zgE6mE7*4;t5@G+<^eyI1CVeXgf0ha65B052!4z_^OO+7Ox9Fh0wQTLurCQyhj}OjN z+0CSHvEF6Ux8m@pzD4nHO8S_^zy9W62yNh&N06TRx zA;u#ma1n=SlB&Ru-*G5?Ydzu+LxqH2P~S>`Uks6k(zjkfoNVy(eZ=d>HI%;f4qkpb z;t4S?NJ0EeA$=m387}bzKe0ztcI#_uYqRdRU8jNG)weW$Mu47qI0f}*`@EA!LtW(< ziR1~WbC+%2uq}E~ z#yT0U;la#iJf(j55BBNt$F0#tT@@JV^Bb_JaRH@PFa3HLhqK z*Xo4Y6=vUeNb!Cby!jo>cClGzZ$Oxw@3u&t?B?%hVfbu4pAU$BlUfNgQgNGg%p)o7 z+J`!%KU`{^g!@Cy{ot4f#O*UY=1Siv3%Do2&9bTEkFur(!Y!VKAsb`L!5C(*ope;v z4^jPyuCamGJr{i0&q$hzeoMY-9A*tnhR>skaO%Y7oIZu^0Fs&XKlwJbyG5Oc@si-- z1No0?43Bb<-%v^i^Xw*ELQ<-xz{A93&Ovn&m-@Pp zq&qGD7IX(OR-`_{tKt7B=c1?O+#x?1MPuG3m+IHrP ziMet0DE(6f1LsD!4YdZHWlTu-Qx@n|>&IE=K2mX+Wx^vVq1uPI><^ckC*jB9GV_+@ zgZW5Y9;>6OUzS1Ul@Q&Na5290XIi>6DRo*|eL#z)>&lZFwpf6dxSwN3OdZFLN?;OW z$v+d;&VfI%cOK1?##)^^17{^c!v?e?31|5|g`|{Bfd|V+!U^D+I->hBj^G%>`HiLY z5MyJwgoNKE@G$u;0Y8?opf1gE8}buc4@;{!U<$wau$%l=fL{!LL0vipKNDyB;m!tU ztB?rBMUneJoaNj@%6}nAdk|;uLA(};1XJR!GyC)8YE;+w?OwY~Lqk1OnE49C5AMFdx%CqCoe+lymv z7x%ohCLcMFEDcX9ZwL>DelV^ibn*Sk-@Z{jq3~$9Fm&-_$%pv-+R}yt$ILxoITP9r zi#ykVb}9xVupgCW*&`{X+K2Pii~t48WZYesI5~J&4O^@FG9*r`^=kIF4+}QAv9cKl%~C_KlFl6Z}}pEj_d7 z%bazgoSHjyUncVe_TIY|~YvuVNqNF>PGpr4ZkDq}JDbNu)BRRA|o+ z8u#EkvA(iy3enG6tG|F&Zj_x~x8bWO88Uq5F6ajh=fusCq>HG$bTU@H3hS>~SJNn$ zteaA=q^{P%PwE9(G~kNS;*jtQj$^doCO((^h%dq~IF7LdVcFFE-H6wTi)BpGDE!U3 zKM&6>MI0eXd$8`eAt2K@2G&|#H0=b|TFtu18TO0~UH92X2=dkaaW-qe)cj-nx6HcF zvAdC4_nj^r^@5&8shyeXKEEBagYU$;&o+n_ReF*v7APy{qpQ!_U z7&uUlX9!8!gE+u>*^Lqjro;md%sL?)kZIIe;K1AZAwC>{-d=tdSNwE+Fa{9+Mk)rd zE_);;O#5WQ0DcQ*1>cDnVB)r501rc=7A87?<91Pi<$G8$KprrRATW}20aKpH7Ybs) z3Vf7I7%K{f&uY5-pq#^0w!ChitdGzq zGvP$dCXBzut?~yN7pKk|bwh8(z}zNstLTql?Zx#ykw?Q=aj0YO-BMh?XT$8L?5FtL znx61Z-up_cM*( zKENk&mE`v`j6GHvW#(%rG|9r^O{4D2xhwh?kah+C!9KqyYJq~_GKa2dLLP7Q4gQM8%gqR5AsS# zN_SA+y$>OjMkHxhG9JHO5|?qi)eFZZ@Dmb#pM{4h@0K8dWjUzxvVYx_cSYgskSp&v z2PN<6h#lWQe&RD-cbD((e2%N!<0YxHUq9Q%iA|9S9mP1a`sXF#t)sTi9|*7cpYQ!) zO|&DoBm8je(VT7P?9@12U;13v-4)fT@%zHNtn!kUQb?V6BBb`@F5sTr>corq{!id3 zc5pKs5zJw=yX+p=S_OeH#+hTU^ww$eamhU+gsWY7C zoUNV{*3ZFPa!4lRR; zH5|@<-aLNe-iTeeIn=~Wy>Uk#w)G|kk5qXA*fL0Ji1wm9@rO(6RKi*7JmS0+2NqRd z4do57MTm8v3Kz>S^NsTjr@<6rxV3hb-W1yz2N0(k5j8gU7JuLHDQ-{TB4(os9<$dJ z{n=+}&P!=<+;eE2^jPU4Ne+^!a9NE!i05#2P>dw3P9e{Pq~uJ2hl#DP;zO{MP;X%z zUUb{ISPrB_5eL(_goIxb9wxs-;3s3SyjS?iI&``JeOOw>;l!i!T3jZ-LGX*gkLhE& zgdfYNiT&(n$)>II5aRXYUe+6VXO?R|)5QM!@Z4@RqFb-$G?+HY0v?wt5&cq`6I_<_QCg~HKox!V@o#NSZIgzcOI7~WN? zu)QduF}IM|u2ypw?FXlMR^|Pj=R6v2=a~zm+Vj$a=fdNq!J_V$21~nz7xB9&q0eq$ z-X0IXDcc=9#+<=TK;tCv`�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 z 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 literal 0 HcmV?d00001 diff --git a/test/firmware/liblvgl.a b/test/firmware/liblvgl.a new file mode 100644 index 0000000000000000000000000000000000000000..e339c94086dca43efedfafbac471f61aaa596b95 GIT binary patch literal 8100082 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

aU{; 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

VEnsqhiuUxaT6{~>ha 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�(^4YwK;ls!V>TKYl)FsSwrk1+t@4&td&|9YsjrDCGQfFX9h;T)LC~4wQ z$^}R2*}xB2CFofLy^Am2Q{`J?@YnkuLD`I6?+5Bb9w?qUGj2V?i~5rXcv4^_b9jm50P?^?c!fOB zM)29sDG1&{@Z0Ar2v!qZ{Q)asitG_^a{zk;PZCVu_Z5WB1svpAg5yBp!(1Aq$HcWA zwGF+VAo!r!cue3ZaiHhI!N(~#c$sJK?DYthEDk?O04mm@3`Kt9xnqd(Q6F-^ z%wE4A=u-}e|4iYh?4Ce9^sTGyY7&;;-}ZMuoZZW9d)e$hLRqbo6L)W{ea%zh+KFu`~Hod7NL3H6xeZ|Ia|Ad zXSCzJzqve@cgO26KuwSHZ2eB>2k;-yxBUb61hTYxe%s&oJ%KZed({Pq8GG+~{}16@ zp2z)1cA%P9Gs$=`muG{BtnI5w{D;{0=V1a+IduE}2RoN5t7t z^Sb^7hfkkkzj(O6RL}swKeYT_7c1vg19SO-xje)ICHsBUd;9})c@#9B*fssW=kha4 zU_WDzcdrACG?IZm{((JyXMg(Rk_QI% z_`wPB#L5GG@A1#^J{nPR(nJwi7h2G#}+?b?9b9?*LR)(1YF-vAs5XZ}t=`_zx#lZf5xp9zQS zv?Dz8mH)A4{+@|*uYVNw@Z-@7a3E*?2J1{n+Gsogd7!Maj;0>HSKw``1G2!UQx+(~rodLTivG?H-U>hQ zoE_W^fAO3hychAZ%`slCbm_f`*!u%shui;^I|KQBpnkO25-SVrLP1=nJpr}9LMRFD zbxojeS>Vv=1$Ye!`6%}Yd|Q}P=jgye$^w)dEu$L0{j3Q@Gw(HZ9#LRTT|?vg{)K_V zox6XKu(GBuBCF`^4y+A)iq{4lSwJ_1fjxqOGXsb3nSrGk-SwmSW9-^MIUK&N9pRa; z{EuB5_)DB?17qV{8(0m0yATiOx;T;3r(S?C`1~Na>qjRwRvzf<%m8MZ%`MF{r+{k=6RvtJK?hU5Qpq~Sk2e3X+dSL4VC2{W+ zH1xMu@CH&n@*@1KmgHlv;J0|il)j4Kvw5ljX9n&k9EeWgKPxJSaD9MZDOv_s2@Ys| zpryXSSs_Q| z=V*|aD;ybj5TY%`c7lO3g`ZNr!c~~ZeiHi!k0IW8_YYREbIGIoTdaIA2M#xCNBHF{ z|6|t+UX63TpeWAuf&;m0Xo%#2ppzQAUa%YG(#QV6j1u>zA)FtWQCd2+sCY(EpX&uv z#e4sHh1>g+5B4L$>MX%GB?piXo@OST?SIGz|Deei`~|^p?@$n==D^5Vf-_+1ahBi( zdNF-JRS;4~70j_lQqnO=7NjX(hB+=Z6R#su(@}VqxUk)1;U86r2L1CSMX{y;yvuf@s=3*c~@c7$iX@;_Eq*dM2?a7>)C!a4A_ z3-R=~w@{A!lE3LkCpA`9*aLsP$qL{won13#Or7RzEyN)!9O`q2%;BLscUS>xhtau1 zr)-swpo>{GpXi;14-yERV3Y)00`3mMVf@8HQ(H$@nCTmk2R_yEfZJ%%F9&3Sfpdpo zLuwYrw(wEwD*7~@JLDNl{q!XZ?D}9?pls%VEMR@my1|G127yCi8SX?7R?cGn5VAno zOf3s20t2!@eN#nk$GY`1@@tP;*M3xIWBpOBjcu*@Yubyahx6Bl^Otmn^E02eoAFI1Lp~NI>K~0i3u; zz)wqXp5Rir8RkJ9B&Y-hOR1HL>mY$DOvU@9Sk)LE#q4`>@7~zI3Qn%C>GXA&?+9Il zkLWUr?3Y9pQ-4=7s9@ZMa6?6|ba35zITYz!=}Uj<2(c4i*v3&JI=X2Gl;Kv+(#!h_6)!d_`A&Y6)6jRPcTyy2q>=Yo)_$szn8?V zZ@}LRf3HOvT>iclhLM~_>j(V(SiFP3uSQ0|-;Y%g?53sPZl%c|%%>@2Z=fj@2SxOUvOL1y&*u_%`_^}dpn-y*}mvD_VLf#2l%(sWOUm(82;VpwmuA%@*c~- z-vj??ha34Qd8p>2vHbf`-!<5Rh~nYje?*$7gHAs>AF=#97Y<+0j_}M^{>Sp~8{*{O zuftzFI)o?2$-no)Up)E&y87hb#l;84zo*7MKTq$Ee}5JQIdZhObY1>k4_ol>!3u)p z@!;QQ(d6>)vuO$i7Xc0_|6YK|;<`S-`ErgUo8sSXxJzX%_Izs^8tc0CZ9<2Vg{yOM zF3&oG56DI4<{u=M^eE3hCh~5H99di(jTa3~KSv55?@=kp0LR;p^PK(wFLzpvZa*J2 zFAsrtd=k8z_v6OP%TLf938>2@mY0u(!&dDm{%DNl<+sGi%ioNXm-8FHU5KZ@^Z5JV zFP{4Vw)D-*r}p}7e;;%4Lw{dj6>|Ay{PV$F{8tJ>9R!~(_XXZXli&V=g5U^3NC^ty z<(!#Ecsa`pYwf=$n7&&Tgth<;1RRO!mpb9>OF92uoH1BAX#VWZze{h6Dmh2}w-CrU;0*;ZhK56XGgk4>+ak zc5TNq9yr?(rG8y`k#qYK;rl?-+DS*`cwjgZc$1q*@YBdUay;;Sl;eQ_`tNAw_Mhkb zK%Lu3N95Z4(a!$MFDe{bs8;2jpJT7hyPq3A_Oti2sOI)lLvuGcw;u}IHgkJ^JEe7Q zzmAm8%e8^l@j!rip&!@N_RqQHuI=2uxoS=G%0~C&fXC`>gFSVy?+>#HTcH2{aCZOs zChSoSf?D&xRX8*Ef3KH^s)p3v6K;Orn$aEe`)0n#5&fm+G+^hrgjcZx!CzM|GGRkA zx(#(5jqiB+^D2=|aKnx4&-twVtC-)fL%7k-@29tuj>!JJFA})LO{AokWMqH7H_HC} zA5qTli=&+1e*iulFB81ns7ChZn~^V<2f13y4UcMTYbtB%8df%|o%P4=&)uVZj@_RZ zx6_}8?WN-(J3W^n$^{Z_%_mN~y>-RDwc8Em0sG%$jf9l9;3z0awb$pnCBdx;t{J7$v9At#4fXaCg4cgKpAX5{ zFTHPI01fRM+wJ_n`w7S6*a)pN{@zBSK2R4Wqi*4@W+mzZG_Ual4l* zk8^9+Ot)X)j%IJ&bqFk){{GL97q+X5f#8bl@7WVw6A}>`c}Mp5Pe$3_Cq_AcpAuz% z&v8`}BQBR4)yV#S7x<3S->+F-DKF7s3V-bWz5pxzypG-9f53vrRyt?QnWOm;(+XOk z)24%=p3VQq^YLSV|4dlv)yvX>cX9D zZyh%LZ_d`;x=GzXQReDS&VKpp@E!d%wWPHVJf8kKn)&(L=x@G?`S}^>38Lw*xtFd? z<%sj+)}_e)nr~8_=Q>LMk&NuGZ-}zLel^PZc_7OE`X%tiwv&#?{(8w#`fIGW50lMt zsuvFS*Z4SZd+)s$o_uoDd+DaMGe2L2xCZ;{*Ff}~kDp5=1(=`jhY|DhaRkGDQGxev zf@N<~5Y6-V1LSl*x`%1{4?rE~BK)b4@HwXGbt{{j*QhzVGLGK2C41Pg8+&P8uEyB{Z5DaL1GPjXmG!;6RvPy zet*9VaS5HTcRY6wE2iLF_;|(v(L8q_gns8@1bwV|J9kP&GjBfxzG&v{_aWS9#sP0b zUNrOelhEm3AH_J}P?Y0}$2b5z4{Fo7xY4C^X+&NBgX4gr zuXY?T4*Ak{J%G>kk9$2pEd*dt!9w_I#{urg$f**oQ+!UzgFSli!E;+1EMeUGIWdsI?lpn1yfh}dVs5g9piwGaR8rLIXCC&k43 zTn{MzJmY|(g2Jf3sdvV)o(phMrYFY%+a%ps4|objblvJy9K(Kvl;ORfVA)(?!oIyI z-pi9O^PR7R8GNj8oa2D0kYH+jIuO;veKj2lc`i`1qGDOq7yfi0iqSxLz#U_Pj`Q(Z z7o6+MIuqAf8wl4#_61+&d-)yD3D5!}&oL)em$SD@2msx9{kNYJjKpAo&G?u7oPh74 zQRf&gSG+hTAsu;k9=oKOxZTUmm&pABqu_9h>j-8Vc}MOScqz)~1btC3(L5(u0=|6+ zClPl%Zl=SJn@{iDvV~F0hC_SLPm&|}o&n!co)fqm^rPG_Ff8i*edCTbE_fA@?D-IW z7UAaA<~ad-bc_o=_j3Y1e85J5jS75Uz;lA}kYs8+*zZ3Y7vNL7C(=`b_NV+&3`3lB zc042aT7NUo83#D3(9!>YJVL={ka$M&6PA z|A8p`|IShN|8t`3|I?6Ojtkt&jcR27&;1ie>HkkIP(8o%^X2as9EYg?fB$>{uR5(< z^#zUqqUnky$d0vujJ8l4ME8D-}*j|i~&RkJDv}8JRfl8u+%>G&mGSPqFV>} z@}3V2E^KccK+E>t8~EbS?OOz`xB@pXtONW^f&1P-__=+2#UQ%p1J1d9Y5_ow?>o-t z1E2HUzR2eT4UP3nYihsHbNl{X{~pCKAtXk}dL^;r?SZfU?E!au&suV#yd&t01ws@J zaqn0c_iDi6+D<9n|ZJH zQcExfSfe1CJ%dk>Q#Wo_;8O~Fd_#dzkYs8n;Ww(i0mxIeV^HO-Qkd30j2%u`@6)zt zYh?~&Y;VMX5O`RC6Ht)5<2`}8raa`yooy{|vM`F>bm&jFX}>$fnFa+D|w$$?j!_jSQ%tXoNy86E>mOm$e5VLIpe4{F}d?YyLT3(HJ1w z`98-096z|1Th}7T0G#h%=Q@I!M&6NQfL}#92Iv~)7~u2l1x$4lA#o!aIR-e|d>>lUKI^ySSo8f?5K%P-xQJ24g)zWB1-|73!+uVI_YQ((uU8Pw7~mOl z>V{e;(0yw`9p@NeEF_p3XZ=yl_t6Xn#{etpS2lf-=LQ~Q0N@7K(fgm+y+1UTYAe@? z)c?C0_*Jj*cbpgKYLA1iKJ^31vT;X<#o=s0y(@sd>xV4li{`w*z*p4w??$-Mto5_+ zKa~lR%S~fs-#-`**Se12rIB}J-~UXMeSb=neg6#b?L#<;xZ`mnS?#_D$aR)z-UHy6 zsJ*p*^!+Ex;=Nh}IM)0h`~PI9aO}Q+#=j{-uPpA%{gK#c)hZAH!L7z=zo*8vL9_gswf|FWM2aK0PuSYQg` z=U#4oiyR9KgF`gW{SQYu7D$hBEbw{W1&C(v-@c=c1&WK>`)2Rap9Oq@X9D~Qx!?19 z_*o>yfU!XM*}=bq!+&xnz%S_Ui#!ux90ZygcO8E2u>c=6*RMYIIN*P$Z$HL}B$yx- zr zSDzpJ=3gNO1?{~Hi01%N@B54HOdzfWTq4nT=k&VgG1y@H-wJ|ZKd-=h7s0YOD)6#P zZe0?X=UB>Gz_X-u<2D7pa{$M=7BC(XKF66rlBeofKrnxm;3@L^C^F; zod2DXLdOW8VI48U06d{Df)A5dA$2)@1XEYum*MIA*z_t}2`f))f;>WrEf4Ww% zNc?xK5ugP`UZ7i1*U{$w|Lrw`j_(FI<#4W37To@(uK&h&13J6Hf$k6{a*g2V-wh~s zH~)w47d+}3!52L);4^|RZd@R11pkZUf+aOg4Yd_fd}TPwK|-s%wgUiV)7H9UT+p#r z(Arph+2ev%h3yy@d|lTII>rSj%D7-iLA&n}9Cch!5cNBRbB^^M!JBBK)O!TqlEw<_ z1y90=DL$s!d}#2J0`CtAmVKcDFW>!aT`xETRO@q$Wpyiy*5K@* zr7P>yxj~`l2X&k$#9HBA|LwH`S6%tMy5swT^($6Xp{nPNnKd=9qPe*dpIvC?Ay&~} zoK0~K=n*eRoBwAD-&eg(a3Y)|JYDjV;LfijpC62X!_BUv@R5vse(++H&kwRtFe4bC zT&`#$LSv* zcUj;I=-S&GV4+<2TqeADI?fdIvJwWb|MU#uh+OS>pP=JhA@!t+jXuYNk>?2C3A?^Q zt!wSWroqnbAL-0VUNmP5@*R4HlYpBV?S}gem_y~g4Vrtz+{<-~90QyP`w3IrL;&4% zM2-QDey-4vA)jvy;67S7_Spi_oh!tFz#>V(|Lz!IEMoXM&J{v47#st*(;*hk2|NNg zMpx>l@&x^8K}Y}p#r6NLDs;^MznGx;@?H78VwRr6dF+V8D82jey zfoiR{o;9&-bBnd{vkyQ0Y*>Sq^S1+9-YW!#oiMzdMA z=4wCxF#X*>PMX9f1&f=8?@Q~0!;w+@mDC|_F6s|Ss1{`z_!Mlj^s zdz-Z}_l+ZCJY`x=>46JswA@n;ytVG_>YbjxhsNCerETSM{>Hz3=+0=|?o* z@-1n_KYib4jve3q#bGLx9K~6!ex2AdFOQ6Ylt;BeFC7S#cT@GRU!T+BkN3T+`xwfc zmb7@{uV06c^BBdwdvD*kysEKIn_IWMu6}i0fJFJy`o)r}`YZt-;y*pH z?4rHf%DR{_nSBj?+B-dEKYK&F zX+YV`vOrnyBPC%<%_~SvQD={Qphm}o|*qjfZUm#^k1=qJE zHayajrgiz){E#7UDkDYHd1X$Sfuq1vma~Yle*6vnwt-Fbx4h|ea;g|H#P1&@HBsWP z<=k*k>pi^e>eoG!OWwOY%QMjk=-<}1+e#O=zOFsW@^c=;(d1lv@A7P%Hh0RDKtny& zoT?hNhKlCuK<20bEwwRCO;wG}RZ9XD&4H>l4UJVzP59yhinu9|)2FGwHhpDtpnhp! zMb(P>#gMMXnUQ%E!g990QWRiG((81XKy2(sWwS=E~I=6Y1e#iCTy zr#x+0?b@Z9Q#DyrSv6H?{2(Wzqx9|Oy>VL?Jvb}N4BR^T)``aUTPN$dHQdbGPhXF_ z*2qfTO|y;MD>>plKU?MH`DKe9ym9ivtQ`~0fU*4s_}T$qJH(fh-)UJ^S%0Mg-U>+M^mjKt^3O_?PU`O2rBAo`3m$1%RIs!A(=G7@ z7fpV;MN_|4!OoU6=)>88%J+5iQkWlUSyymrODEuZU}w0k3_Q}(P|$nREbaQ1wFSnJ z45ReT^Hct`&ODN7b|3pn^D0%h%nW<`zW44&Jgltbuz1|DG5MP5N78)0kF_I=aq^D- zWu7wM$Hse#x@Pf~?=M<}7GvN0K5g+PO{Z<;7QJj!*+9hovG;vOin3$PoO^I?+2Sp1 zUv4bbf35eK_EP_94S70o9DQjy;}7~i_P+n!>YD1qT@TI}c*(sRmtXS!#vhz>Z?idY z&2xYJi+RLIOHLbbj=#)vC4G2y=w(Mx8=ZVBcX|}U8C$g83D9JR+j%Zr^cOEw(mjzHG08D<@@@U#u@fjEqCq#J-6h@8yo#Q zCYRaQ4lBD-WKTKZv@dZx&&Wz(J=@+H8soJ33(C+A$1!y~U)Hxz|KQR_KY9jpqP9Ir zY1F-{KVt3U_@}#54K*G!G6DBop$Vtq=3c_xxXW>?tG9vjb>gh$JcJftT!Fo#w53mh zKE%KC`qFoP?Rm>*J~YX9lCSZ%Nyl zS5~#i^KGrq?y{JjKPWxtUXZMx>s!|NQ-5%M%c_9UH+ehSQ}d3N2?fc!uWwmh(D`E{rSr#T--LHh zF$z^2u5US|KpR+cYV2j;x^QWM(9OEVsYyus#2vF~>s%beJImNu~NAo4Cs{v+U@2maN5M?Oo7atdHSsU7%z4ziGxo|+4>nvparzM7&_BG^8k?qz z7fIf*oKN{+#a&FXce_(}ygT*5r+jecosYDfQD6=%eopJ1Rr9As{>iB&y(^sdU_n`? z>WgD{4o6GG^l3T2KltNuo}Dr8>M=g(qi?Wh`+cw7f{L+8s)qxg{n3}1tbD}pG+Xqz z`0b9a{p6rN^tIQ1|Ax0H6B1L$UEk6aaO6JzeAm}lZ}&?-x%aNXM)oxL@&g7t91fPN zVIcY|7*$tRE}t8!UA3%MjUUlt;X!W5pc0>mtZ1&%&cp(y`&?`IH}I6U=Tk{IjU3aS z5_dTc(f0eie978xdH)1kzwY}u5lfV}qmeNBcR7^|x~CDxgnC!dYG7B6oW0+Rf%&Aa zOX+Ob6Yw^X_hASzPVTl=S$Tg%A1QcxXiV*T8Lce)7IMWP2FCPmH!3UdhY;!a+5F<# z2+QWfCvT;R1+BCcK97vQ4?o^6K3H^3okoktY4JC51X9^bd7I;4&Q4oF$5&`E3XwMl zrEa8oAsGwOw!=Kq@-D;>#5&w17nI*;O@>GBTlle8^(aKT;{*8VIu>DNdrtHH9)w{b z_MS81A3(-w#xTU&Q=WDhgk{vlf~bst3xv<;j$cnz!u#NgH^w7)&r(JB6aPuJWeJS5 zaZ@5kr=Ds>>EAUjK-@gvR4MFa{D~ngS48KuB~6Pp&x(}qAv?PogOH7$x-Od$M!NAs z@C@EFy2=oc7AUU-#}*g`3TmVp7w z8RsKpUq<)0LHLXfh?1{Yb~180-YB6}KoNc;jcl3OBjJ*!6>mqrPu6?g#=t1Q>sCZL zJ!XNgg@JvF6`z=eU9M7rO^1(|(^Qn>jehVKb9zz*?EJ<=OebT`Q1MSQ_?exUZ)7ip zOIIz~A3LBBkxW}tsKpLcg`uUbg?W%NTWM>GwAfr__NA?bIZv76HE%VtJ2u~BG~y}2 zyBBeZ>+h!`+NZ$+)ngK@;%CF$gEb+3V;|qY#=SbxKBtQ8CYi55r2Db|fhe5#cX`!s7EBy_ThkALkn=FeT|LJYjA`aQsHc0DZ-G$oK*BXSf>1SO7*M3$b ziZj`oj)eF%?*IfJ|Cm|MaN-jdFxwNq59Wl0j-qJUimFXLwb)y^cR=6!%}vr<~<_AmS>0n|k0 zE&|pg@R&LNp0KvF@H3!@4C+UfpuG!uYmY)!c*|K@^V0a;VS6fml9)JZo=Jlv&wd<6 z`y}}BUIO;S+^p4L7=0Nm{JQZSnC<2GQHtW}_Y{oQVZ=bQevUlXt=mvwhV_5=wX6yx z!e@PmkYlV^@Wfi5fIZIo1=v4>c$AoDsChB$PO&`W>=qbGegkgL_!P!x4AvMlPg!TS z8d`E!&&g~tj5VMW&AtSd_P6nq#H1Vyve2a2Y%J_YU>v}zW_Sf zmy|vcAtheO`s1{7X<8x^p43YzV0@ZNc~U?{+)^n|%2b4{Ql6BhT49e$c~Wnu2hzN| z(R?KhGLImTc!r=#G%0^QjFt~&saZ$xqg$o;HLOfjIDGqd5mQ@io(87mw4@R50F9+6 z$D~mzE}HRklylM;DUmyow4`xTA{$6lbfy=dF%~(Pv{ZEn@y4YTTBF$f#vhT>Nwt}b zMv7*?gTTEBD9fZ3<`!7RzmK2f_@oB*YR31O3u}}V&A0?{PFkBr2P^S1uqBP-AG)fhy=}hCM8^ME~IFRL{5EY2=dPu$tYf{1Zc)7^mAQ*I#|XH z%$%FDhlB7LiSUzjt7Oi9>$_SBB5Cmp%=Qf5GgjSDbz^o zXH30yJxa;89zYU2*0(9jdWW&Ku7sx;YcKL9)_MW)i?gaA0Uggx2*Y1s&IpDw^S%sm{$b{if;^*I$nzFL)U01A&K!gb&Kv~kA7efbXYX7D<{#J756@j^ zp&X0-<9$B^Vf-Du{<2v1WSa2~WuK}_-7=OTZT<=IFTl=cWFr&&lhjxy-gpIJVWgab z2>A_GaQ~FlQ$VB{HWM&4br}eZTIfD4bqgTfNTHwUsk=c0j6&qRe`ezUfyg%M5I_H{ z)Hgun7Edvuj-z zW||!UJW{s%~Yh*V6yz|C*YhM?_ZFC0ygesxhzzfr==}v zT&4L>OJ&YkMqe~I{?ogY%ct2K*B8>-p8!Qh<_X?hovV!HkivB}Z9`JaLw8J{3Dy}LAj zpCC4R4^{6hgB`D)t_Y8DJ3Q(=72z|cLuK>~>5y#fDbRZiG*TM=o-7(_$QR&1ROo8k0PL|5aFOjKW$j_$^O3h1YZ9>&c~PL3kd zjfqTde?{~(63I3|5gEp3bQ!3KUdAg(wmwJ^0i%Ht%~eFEk%r2t=P4q~D5ZdWMf6s4 z0=+;*G+WIH^g0b8P*slBYCP~=cuy`!r@L}`98pyRO0Cl*#585RkJd$W zcaqVI&Dae}>I7G+)~O$iDW@ymGh2BxAl!e2;$83ZhBQJ0pGNk@oxY1srEHp1`@{@% zOe9OSvE7jYda)71`6I7gEa~gMjr<d1~kJ3x%4Yc6auaSwU}KQoxH zM%=Zu;RLXPx$qs_+i|BHMj%5CHOsjl^xe4Adm{W1hAL}g+thSw;z)KRCDfpO8v zlZKz!UC=GHae3N$JQ?PE-OFON4?#_Y4!B)5CdYkY}(K zw-s?mz6#!xrHedQY|qG1K7hH@d3l zF>4XT^LiKdyD_gI%(r#bF~m$q`~O$rIRobR#r{I@d?5BehMa$j{W?_BPxV+vBW43q z{h99Ps7199&maO$N@I4RTkBysL7WA1y3>}#JcICa#h%SjzGI)-twuA9?zza3)ELS( zjn1q>xat)P_&TIfj=-F%n zJ2T27^r4J$XC`ZeK2_Osm1%^&f?{GA-%*luPBlvP-ifqNNA^tAWA0#ZFCrb6=xXh0 z$UU7j4e_6>cXs061@WJv_oJU~cvh)R(>t*vjG52cq<39|sKsoA#cEx(iZMeWca50O zMa0%RW@H7VeoLe(Nn1lCT@@nf>JUjche-OaV@~b1T-&2}V#ImbR05k5*WAU(nx0M$ zo-aArGb9IlN)A$Cdg=?AQ%YfaN$y;T63iCG;5@9qoRm6Uc{KtX>?n+8 za}H{Aq>{e?8T-7_=FzC6eW1g_mEbYGZ7x9?wYV&&C$R(%4q3Qhqa} zJ1O@d8`bFRABYKCICg?F*}~~=3&)m=kM`I+c8A9x7lgCrVvk53^lGa4n&{O?~^L2=@(T2KHe=@0;=(Z2Nr#6?`lu7q*(snq{-94Lt)2xTlk{g~I~e z`gP}bL%BfQo&t({8oB*5+*uU6XBfr44Dtosg%rPM8pU&l(t^7ugSlM=!>1VWxVs}T zt*8n@Pv~Sb688(l>*g+u=dFkhwf^Q|)RF>-xh0ME zTG`{!OnoJm4>av6-1>E|qX@Iu#;@$dCjL|eax(5BJ{nlto30x{uEX7vmGBC+7V>SF zw&Bi1DztR)^yJ#exw&t{cq{C`hdUtvH;&J>%xwHryIdC(ybI$!;Mhy9zQW}hB!;pXR-*dZoVdQB-k6kswGz@CG|+IQh+!Z%UA`iunT9Ir{pSpB-JPJkJM zSoJhOu?6eJO}s0pP<<~ z4WXFo3A%oIObO~r?C)UvG@O5mJN8)+8Ib)Zi0*U2>-#fobQJnOVe5MrL|+gA++F?! z!rZoZgD(bwl)`2-ZeJ%5^I@1vA``?nVW=dL3t}q_To~?hG6-|qH5+{6VfYbjxDw!- z3F0*vo+nWYf)A`ZbH;CWBaFE3JLA(tE zpD4s$2Z9d}xt`aZ{&Nn)=5iQrf)w9xL7WTcwYUer1mZ?U_hlHahRs&ozPCZ#4Z|I{ z`+o@HcEkmKwYxDG@qGe|C*iW6tX?$BTt#>Rx93M-;|TXkut8z1ZAXw(arnZ(;5z5~NH5-)>z2!^|HcfT9beL3*>4yZSA`-(w$Ff`F{`$|Cc zhoJ|FDIh9fI30J+0uaxFs|ynC`vwS3*U!a0co~RSD7G4gM`80I?k>$B%x&M<&}E}C zpnhKl!|&mw){(CP@h=b`d#>e{;yI$O^?6oBiMuw4M>dAPgN zVc2!BK|lC?bZ^|k;QX>g7V9OM@bMHJxKLYxJN8i!n_<{Q;)fvk$oX>IzTbe@3&Wkb zmZxi^jCOLDN~Io^XWdg&_fbZ6-@I?Rl%K5vK?AZ3) zDRyf3t{1=;VyVUPQ+@Qp(qE&5EW$5se(iYB$7!B#!iqB96B*7Tjk6jCXZmB@I%i8J zFneUR%r@u3Rr6eiA0}{g7!OAsjEOHt+DuP@;mE3R_?&biW-68EDp4h1p{NT(SvUj% zk2}{$mU=vW@UX9BxT*>^tniI4@)1N>5a?OC#E_P zOC)o8c*G#Dr)#6KTB4ev!yEZ~WgAx; z#{iZJ4Ff}RGt<+ro0FM?+-PRrXR-JtmAQGyO369qd>~V&j663|qAK|=8zLFPR)DyL z#=X$>7Md4DVN4S4U?&ym|CGLF+OAR#iBl068WA8}vmB5q2a)gC3jGBSLMKIUN z?&N!>Dx~4bcqW+&J?)V=w@b3_hjNS%)x|7eBq|chcND6!HaZo>ITBU#lrFA5tD-9j ztq0f~6f8+ql}Zr_ZEP^(k!#GQ&`9HhYpUo~hDs)kS2-g!oarbFN>KS6>i<+$&`o+b z*2xLsY^?!d@*K3669b~=i6{}`$HdIPN7olxd-PozrCd$8nhW&#R$Ze$ zUpcAX+roHgt~F_jt~zVYvr#b{U^WKmr#XCElwBO5MrEpwldRn9mt4qUPEf1vgr0=_t*td5ERX zz5|_vx7of*KdFyf4k|ME5l`s|JG~NqDyv|sTFPiUi%2(GOKV|OyOnCQRlf>7obt4cKj~2pPkQ$HLLK({ zp71G$Cw%+kLml?VKNU|02~v`yv}q9%dUgDD@sfOp1Ce9KbA)1PaI)ev^wX`308D{H z7L13i-%_uhv!1tDEYDll#KHEaxQpZU)3GoH-}v)TcSYH*qpydp4`KnE;$8(e*`m2x zGpbc&XA3JSH(H&0A`U(C93rm}L}95zlztE8X?;)sk?znx(jTP7gZigp@u_|hE5SwB zh2n7RGH#>AZN_V2@tW}lE#5G;m=4Dlb35zWcJofLxYPV0Eq-V|DHczfNalPb^9tMX za)o`F2Nsuk4tpJo!`^3NVew4t2eFO?^Fo=J6;7@#feHJBA=$pt(&t$BSZ_kntd`j4 z<60}x8pWiVo2N{)SvOcmEYxRamggho_M`#p>&$oH3fh-}$~4r($Qy)W(>#MQbLWm9Ya)0gZ~fKTO0K&;s1m6Y&qcS;WDSC#l{AQ_%~Xy$?%_?5@H2LA14P` zL00}G|8|AsAH}s=&vCMKjuQ$)YWETksvup3?S@2kJJTupGnau_wpkQ%vwjIR^b%yA ze0P)N;eoPW3M*<5|X0@ zC=N^WLWp;`wERqphl{V$b0na25}wla)2zpgt4!66_&Os$eCQRVFx&D!7Q#;^5eVyr zju_EYCmdMMaje;#wtu-%a`MJf9n%1Z7?6+n=hr$!Z9Rzkt&(M1^=p}B*Xs9)#eMoi zw0KB=Oe~nF)-3aUQzaaufce(##;1n#q(}f)K`m_%{7#vLpDPX273napR8E^%D>fU4 zG2CDxpqI*;{el&fVPY*MXO67y~xZw;Pw)YyoXXgceRjU~u)VDi`2_iLGipv@rP)Iu}A8vjC4-`z;Px0FXY{k?vLo zPZ@@;mi8D&osSv&4Rh5RFd8pWEs)2<&{&mpK1=g`*1a%$oda3xiCN4L-vqc1*Jm>t znrD(~*)lSku+J;KT|a~Srr(HeInbmX%~>sU-3X2JEkeW+U4_;?Tu?<7x3KJaqh-ZG z_u{e?!RC;TS#FNGywIQP!0U-a&XE@cdAXq4*&RLT9xj_6Rjyi7ZI$cr9z`w}PbpWG z3EsU@rN)lLvYur-@{#qF?T%pgD91_2^Lwm)?3a+0FTxI;ugXf8UQsO5po<@wTi8qA zX*~sC&T#S4X`mIe=Oe{B6w$WaQ!NiKJ2zeMP(1b2ys@)@LiaX*(kr{M-v zWRTD5JVoQyR+tUTtf?C2*y$SpBPHlHG7fL z0tB0=*)tToWu?5NqaAqB#@1+MvtPH4SQ~9?m%R^mEChN&i1D2@`#nXbVO;ZLbWli@ zwm|(ZQNLH|3U-+ao{HDFr`}Z0U;phn+3Kyy{ObA@RrwXQEA#X4Ev=3L}E1}iaROT;Ryf`AA zg@f}3=M}oi)$&|ZKG^xHYCiKjKQAwTMGdwwwC{WrYx-JT-&jRl(pa(j->^mDe2h4_ z&iRW`U{(JnsL&X>p8gFxW9G6EaW*(|29HwPISd9>uzX3?(u$R}&fz9adDU!l%Hanu z$$~(IfEg?>qoP0t54Ip1x(QIsYY=F5NHmof!eQkYXkg8dMI#P}eDnXAb`$FX7!5`y-h?Os0fn?#Ub*&ME z5sO-I$G0kQ$OcHXj39BshhxSRNV8S5YhplV+o`Fx?(yf@DWmLeeeHhvd3Kz~JX`k! zY};cd1?*T4m^}GlO0{D=X2VFkKWw_@fylJeV2tsMh8NvV8$|b*K$>0T@!MUp?4-Pa zo!~Lo1i+SRcbfJZPV8`XVCfhUEj`!$>FHG#;u~)5jDW)gaPRK`KikP5mbp8fx9oz3Qk_yeN z`z$wAlk6Uuw%!ZBEWCV4RS8NMnYX~nJ!IA>dnThgA3S4J@p>7*e0wm`6*Jl%%yP^s zumdQx_}+HzNNY*_gn zP+E!9dXjB>6xp$mcfNuyZotJ8QJv)6>aLIvM6d7{L(?VwzH;Nuov!h2fQ`I+Ski zTc4L_cQN-tGdnrj$7(VNb`I4|$r@#+3nnW(U+I8X9?}@!EacCv&_KJBYIlaB*5o+}A1U>Gn%$pS08y&mkF?{>lc_D{ggoj! zOM8@RKUnj#z&2pCos|LGEII=-Rdq>6JYmd*Rfc0^laxkdmffj3m6bBj?pk6GPPaS3 zii||00a?o!qRpMyHJ9*4rdG;hHfKCW&1QliIDfWn-N>YxJ z$Xr3F{W4tXj_{F6co(pALm5p54hYz%me>Q*VUcAQDu*l`&v!qqiirUpQv^5jJhQy?fwtG2+M;$<$5Su4$ z!YJaT*7gZ5qddCDe0-h03n6FPF}W&}l0D|Vdcd>5vyeIIJIqGrZ9IZfy-E_(uoPBB zss+>+S|AR_$CUV2PdA)A_5zX1n>jOlHHE&pt zJm@6)@3zg;>~YY`d~}qkf%z&;1qilVI>cwC;qW}>3);OHzo=c7ZJVPH6K#dKO~XA=T;XF{H1$x($fa!Bxe!~O<&^B9Wx0@jCEq{!wN z^ZxZ1iBPZFB)kL(f3`K@DIW7qmGED!&r^vd#Q_bwG&Wn19J4fN!-lIHgR8MwFXBDs z?~!3>NYNs*9N{Sg_Nizum{FN_XHZECSU@nunK!V7WNJ7D$dp_xa%DaDxn$jPbXjpL zj}}V%F6_p8^s-0h*#q3!o-7t> zl9Oi`Ie@P#szWXZX6Y2^w7qdGzeCL>De=tVM6K{EJ@mKh>Y ze;-~4W{zu7`yVzYwN`$m2A%R)biw%G^>4;!q>Z*C{Z*SyEn|w-CK<6v1<6j=@Nl?h zc-TrH#t7tmT~~TY4VVHhHHJ0!tV16}?G-_Ch=RpbZJvnvxdpsQXHdLT~W8BwyF`Ugf+{mo68s1Rx~x0;{e14$-^=y zcc#ysQ$D?{eCqhA%nTLBWmV1PPHZrXbEjxp*k{2Q$2A&%*J`T}2+m~G!n|qa<(Qui zE<)57uS9xRG@xM4u2SicfG2Bp_+UAbt745=YdvPVO^f*{BIk6g+N!!`&DH9BM$85) z8kN(aC=miC|VcQX|W1Oktbi z8&iZZP;gk*L0MJTEM8uRlPKG=6}Pn-rW6-B8$6&?TT;`A@~Cf8D#*x{*R5R9#^=Q1 zf&y)&n~T67ICoz8_-W&)Bf&Zl$+KYA zsinhkY3eLYiV#(qIBi}zRD8@-xHK0IJ(^ZdoI2*z@mh0LZLO+d!6VFCPnHi;C8|Hv zcx6+ylp2axrLwkasiXIfz916gXU)=7Z3(6iuj|y;uBuw16j#)yX=SBzE}Aq%t;=lV z>KCu%r>>gv=Z#*r3JJZ<{?X_{(Im8$Xw8SPe0Suat?zbT1ulL~~@ z85|3TCJjwTxm2Cup`xZyt5~wC zqHb|j`RbY_&DG#*ZqjP2nt5I;GlVU7SaUgh-l-Z7az%7dW2&pz28Fe@Zu5i$xYdzu zcUTj_mV5jH?F2orA9~nOv!<#RtuERo=OkK|V^jI+>MCX>G6X6f(K2KCSY>ILI!zlh zXX3o^Un`R8HET)r~dHs!3DzhN{ns#a7EnwyHuJo9AFZ z9HIrZSKUvu$a9rgDYjC$#)>*DEwUS?g2~l@F@>4OWu&1`KL+(@?R5 zhYB;MPUM`r7uIdNIl}(Kt?nx@l31(Nsr*rC5uH$BtHueV38y1fU9#KGh3VJAxeJSe z)zH-=)g!Cwy9{S2J6&=x@1;wagW-b{(Wb=}Xvf{QAS{{ASg*ht7$JRXy;wp)c{oLd z1VD#1rlY(8BP3OIw92*6D5r^SJ@yjnT3c0t-c$M1mR6t#S%Ot?ju4y_hbx(?31R6S z!!C{ubZZqEH-6egG>vWo!WuIS2&kM+MMjLB(S_4Kqmr-DR!fVh`f{gtc1C#N7OGv> znyRXnv(_M}ut+)GE`~c$r6u(%E0LX{N{Dcs*iM~3ZhZNyajJ5u(hLr+oIJ$93ujm} z#=&aV9MOEYj$*@NFtNC(fd1GtKpoq}5bkIog4I;1n3Gx*X_L|esBpQX3ND}9Whrje zHnlAeBps!J;cQcNePeTgbx1V_O-KSqzoBVyIv||T%?AV+^C2fyU68|3BgcNKNnu+Q zteq9k7*i@m#M!Blg)*_Iom^;ZHB4m-Ixv)NFo)cfJ4&F{H&nUPi?CduyKvq@&3(ob z*3Gt&#PK+?Mh#flt~RY)yqM$AnmXux4Mq*f4nC_=;{c_xYPjUsHEVb>Q?u9^nbY@5 zH2UQnYG{@9Ys#xpgP5UGomFjO=DGC~6FIW2RxN>Z@~o4mVWYV=`Bz+AEP2E9D?lujB3R-rb7 z6^!oNw=dSz6hh-8wUG80?}$SqF}vk-E0}!Mb30|DlGBc&(wEa~o?X>gk4CF?&g9fx z6%S_wI$^#V@3I;-sn$NkEo_`9<3DHmDu?J(0i*_nX#k~h8tSTMSl`Z%OoV;#nXK)8 zqQVu!=u4v`65G$ndE>{c+5UQX7qiZDghBIo&`%#&U1V=-W9f!WT- zkW_s&%@3$dhi$N_b95c5g`OKTp!OPC)%tUS zvqT2#D=OAt_<>dn4TBmmNbCB=e65O`Vm`x#rK@#`@d;W0w0m)!;yON=Y@FrFpg8Iu^l*}MQQU|tZL7(WJ&mvdYpK<>~fP3*eabAf%Kb&+{7IO}7d zee!2dJib3sD~;0zh46A0PibQI=9mk77kV%9Tx?%rZ80xZvP+E9ViU8$&lh^#i@SZ= z#BFtyX)zC zhLxpf>jU(0h)~28YGY~deirJCrMgfOn+Mc`^q`$7+p1g(6I%-KDyH(q{5C-Mavc>~ zVN`qH?am70P&;#iHtl`GGhBYG)(6~-HOtb#tICw;?y|yO`(S>fSizTx-`2}iN2P_* z3Ce$~4d2gey-Y1BB7N9E6mpqbatOt}MJW;TxOJ=bGI8#0=w%`|!_(JE`M)YyES-Yi zU&by8q$d#S9pT{>ppeVdx<-WGHN=(i>mEV(hzP%j^1nM6zT?hKs?O!O-yT$x9$J~W zFr~VdtvOpz@#dVOvy^=9K6Ng~|0mds;?ie`i8+gRgB8CY^~AY)xCVu$hBFgFE)(Z1 zgzHmAh%3_@h@dkg=y2aA!VkSnq$l(;mG-sTm|DM90wy!8B_TZ^!acP0pgZ3fX}!## z_BwW^R@CYUlc^O((8b!a5F0e&@689r9l55j&R>E?ri%~ zpuf*XxIY&`zaso>`%<(X+6NKtpGDAq1}+!l$JdkGi}b_@nqvUB2W0oCzM0j!Mv&dC zWiJVx5x8A(USY6T&MRm&7PlIUT8)F%m{Z1G<>jhrE?-%<8dIzC#SIPE%%mnt=?uyp4{+;i30qj)W3Uxg+^NyArFi8~=qbdpPMd6?5oY}+ zE+UHh4u}WAs{}8y0%FHwBe5X+V$y6^h)N!Cme6eLXw@7z&7 z4>ceT7d%7U>jW<&mZJUv4ZOj5jo@`e%7w2LG5nEYKZ%I&s)cSOg6~3NDc<-bj?=X73(Y>r$aK!7V!qrb^aFxC zWy(O|?h|^y;FE&S5TRTLh*R;sX0d-x@I}Fw1YaehImW(cm43bl!T1j%BHnxzf%!B? z=rzPKh#wJcA3o}!u!L9&JtM+>m)IW?G;D{jyC4s7qJJLQ#QZowoQ8u|h%7fC^MPAB zi53z0;Uf;ld+I>?A5JU-AFcse4r(RfgV7kulYxLEoPL|g`c0&Y87DjS(-@9JVZ@#) zNcWQjM+!pql>KzU(*jc*co+tP%!K(znE6Dzc;rvkW3BlhA{z>oyL3Uo`XT2k) z3uX$k{?Yyv!6||Z1(ymo2~y9=e}$l`hoEm0`lo_Cor!#Z5TyQ-{!lR4aA>|^M|7Ycq`@OHt2f`1iEVLb%@D8X96HG&%idHN3d zb_m`i_rU4J|XyP!IuR8D)^D07abn`;T#u*nSyzOBLpW1&K0Z_tQTA-c!}WEg0~3n z6?{bSX+a(t$?#tld{^*O!8nX9=-ySZk6@8tiQp8$TEWW%uNQnk@b`iSCfbzSQ*f{# zzgR;1a={IP-xIu>h{3?qM0EPU6g(vEzZd#t!Pmr|$N7{0eZdy7*D;x+y)DRZ8!`M& zLU$9)5c^!gk%DE!0!^Dt#Q0>6*q0L_cd;P9+(o&o1viQPg@Tug{nbM65WG?B_XvHb z;JrlT!xMsk7L3JG5bZMr`w31YB7U=oh{rdGh+l=^Qn6ntxLI(!;0;9Ze^>BUvA;*? z9|=Ar_D=}?l;AJL{&}JQAowRD;`=W_e~Lrr3(gU261-Ayr{FHZ2LzuJ{F`7Zj(Fkx zr5h39j1oLUu#Si}U_G$_^AIBVA0;B6o)>&g@IAp#1!L13zRrSKf_Z|&1BO5j;=ua=~i_zbE*# z;BN*0B=|SMGz`?4U-^O~1Wy&5Em$tNTyVAE6@s@4-Xr*k;FE&CA{OC%J)!?4=E`R7Mwvm8SSmmiv_ER2yZhH{&oxAMTE}%MCd1ph|e>EF9`lo@KqxGza#W}f*%r3 z#$*X~lJ2oY$Vn7TB_f=jMDX<`g0Dc_iv>?6g0EC?o?y9P4H5p&CPMyt!SluaGQq0_ z_XyrA_^{vs!4HXuhtUIf7Uru&&|Qd--$O7U_5+B;s24(y7Mwr?{}jQQVt=~O<$~2j zgi}XEI@XK*Cc#Suza@AT5q#GReY4;m!8--_3GNsCh2TNK=LP>D_`2X*g8vfK)17q0 z3MLA65$qwDEtn%%C^$rLv|y>=WFpc%lZf;JuL}NE@Lj==1V0t@;!y$1IZn_|gq&`IeZ_u&;9#*I zDRhb8M8T@7Uv zpnHa3vEXdM6@nXxX#c)NM7w=0F;mlS7WaLEe-Qgug^ugx$WIf@6Ff<9s^FPK@Jug z*iUevV6osZ!7)U{cbd?%1Wy#<+qoJaQ2D)e!-uM z{qKn2`=j7{;{Ff8&jd}BDbpJ-=ojoJ*i$fz2zlcLCkvh_?v;Ye1?vUZ2(A;nK=2a5 zD~OPLhu{-}uLyoBm<}GMw?7f_%@rIf_A`Z^D|n`0rQmYGdcieB-0O*udxh9vDfk_+ zzg6%)v424D5hCtGg6|0Wdpq_+1?LN{A|fs8gx)H6m*D>i9uj??)7NN}s*J%UdP{(*@4{0!GEF0 zkuz0rmEie;I|QE=oXYhx_*)@(f#5E|9||58{HtJBu6M!Tdcp4q-Xr*P!IuO-5RBzI z6Z~Ze76|fdSF~R$sMf(iUnI0z?*jd>(0>#3a{UPQ{5mzUQgDmlKEXc-^246wp_!QTtMEf@n`qMWXRLj)%ZE)e9mT*!C6AhKUGhB(h3S@xJ#D7_32 zp-xORYc!l6ig7*miQt(fL?+Jb? z$mf8Rmn}G0aE#QGQ;A61R3hR(hlu!`PK3YbsqaWdBJjf5p)&>$puoyYlHB)>19N@N6x+6a4TRJ8m_MnABqAK)7uF* z`55j>k>{p&ms_FW#>*AG-Qf$Smwfb3S-jkEzZDVg0fg)7X;rr@$!QK z=3sisNB@+?%MCXke4*j`&T36>hVao}ks~h{?taJ%4cZNNd<5UKV8W0vc)5HFBKUp> zKI)TuxqQnb_}&7atE1#~`MB?cW`MdrI*L4g<M-zJu;t?XHM$FTMzKSlBV#9NccW zKZ}r8S*mFzjwto(%KIt!LesHvi!*knyaBjfdCy14`!3}1^J4Dh8V^Uv+Y5R7z(jfM zTU>eXM98zo;mgk<1?S3pGeTa&rA|62FE2#iM#C~#@w4wa z=MI^AGd4{#+zf5gv`x}Blmcx@(k3)*I;W+DLYk&&6KIo=q!Wq;0WAo~q=FzIhz~)u zA}XjnDmXreAE0O%6dtHW@L?IAMp5{EziaPv@3}Vt@&AAS&;Px5l5_U7_S$Q&z4qF} zJ!db#;eQZOa(!VZtWJ0VxL#RwQI+`hBH)e#$pXZ1oFl#{Zk7pr@$2ZhFkk2)L9FM^ zhTjkOBIv90MR;(0Z58jk)^^tp)WvYkJ+Yx-e*N4N=gxz_zP{e~T+q;f&N`Fm17%N{KW3<&Y zjIZlPdUnLRMq)h&yu&I^j!hemRZkn9iT#tW+P&QmL{`>UMB40F;M(v?h1kVV_PU498gpJQJk5H@({=1O*h))W7dxY>)#{CY`J!I?%Y~;6o~DxyA3i+Fw}1!s zj>HL?^ZU0?%WS>6^;4~*t=k@$v$CmTj+8qa<<3UAvrV~O4@_U#TrpkJs*yGgY12$v zuobUuY@2_41&-U=N=*y;a3(w>gI&eDU~4j*ex-Vy&~c?Y^+)!obUq4?pty8vEtZ!2G*M zU+%S!e_-j-WaDea+plh(@#ts%^Ro42up(XY|G-{V$fAZ zhMiB6Vs3i4`=*k-2#x@?a*=9P1c;MR;2fy4^@3m}7?c^io_u$d{_GtNOE z9DwB_E7+6y8$e|Qc9Q6w5{RaqN3dO)N0|TCwBjH_y%JKl1%Aw2=VaW6wEO_~EraJu zpdgQ*67I<%qYDFk!8zDJ`8i-M4y-1+fsDT)OU%kA){|BBV~C89+=2)3$md|RQk8L| zH20VA7l$_20|z&It|drL)})ewSetqO)dpB4HA$_p)m zx02l=fdP_+a8)_$@GV8Ero9ZR!e<6=BOImES;WUZEJ=KPOt)s-4o6*?D@;UM7`M79 zdI2z88u<+Zynq6czlGycZCpB^&{6m@a9c$UKyeX$jkwiKBPdwlE}Bkn9U?KBTR5T( zU`xmwOz5mtxYKFX`BH)dA0~Olc)Sl$Fg1~C!S9k3!+RVkv;jfp)CL6g01%>z$zbOp z=FB-r&b1;3;g6n!$Nn^m2rue6b<-uFN~qo6z*=2^NX-8&w*-OxOW7tr!Tk`UJ_?-s zI~X+;MP%ZZ3eb|Xu0ZuJOPxQ3Ef~0Z+su=o{3`(L@X?N2T@bDWY)vZ?xG8)(ZYw8- z2P?fBNfT83;Croj_C6ruZyU5?dG$6JOLRu=Jc2mk1&I`1OtvDda`fXUd~uMn$m<#0 z>ZU1ZefMV2vbdJKUdE3RZ(M9s)b#{>YT!T&b4AO)7Taj zYNbuc8EKPzD?-*6ZABe9xLaAobQ539cE1ijHY_6VFF@*E+*#~{3xsK(MetVKbI3Hb zyWiG(?Q_VZ=46S^L~ekS^B3cIy<5~;AF(29`6I)0!NxFe6PZ`ZRg2JWb% zXrT`8Y)CWNMy8|fYPzt{C#Den#tVZ91DBz=xy`U=ffK*riXlzEZ9r|+F&(D;;P1Za_;K-!!1TP>VQvMy4E5R35^7)ufs z7)!MUM*b3R#gYv#;_Y&<${0z6qD(ftSm{~4tP+kIuv2055+hr(nM7>|b2@0TX4G2A z21h-bu~Y?~xN%b2WSr?)R7@vO!loj=?2KDhot2bHTU(v&83>(YEH`5FBAFo1ZX=sW z8`u=`#l9wHi1i|m@rqk3A>5vk6UsLPpCc|UR0SNLF*-)$GRb0tuGE+8ls2lh8pMMU z^Ns?ev_(e3tTQm$G1$aZU4a8VS{8iLuTT^Wyt3k6HcgY2d2DGl$I9{`e~8U=|CEP1xLy@JRB>Al!Z&;auRPZ z&oGvgo@D+oBg-%?h@k-4Y49uz$wNS2hKXW^D(07!*i3-VZ1hEWSv1qLlAEh915ImM;mPw6zo%S4O3AidtzXgnNNd2zPG>w4{2jmGtI zVBC#gP4Ic$(_MjpV@-FKwaPD9RwJee7%AoXj1uR1?dTLoqQVwGS+(_xGwMy4Ud9$1 zhF~lVEQOVgchIJoeR&tNC}IsJaaia7PAfeBw6z-^Z1gTnW3p#U=3T(ZTVuw?+s>)& zW&>e&h_4p-tg}G6##x+!4##n8#^Mabh`EfF8Gw5`vYyEq?<^+RYe5e}sx}q_VS(Ro z9!96?6PprtX(*lvQz~O;5XM1LBI z&_+L0xtnoH47(UObX<8RWEzsuSIC*$#Zrboe_R_iP{E2ovWb@^$e2f?7cf2JE)jaP z(TX@Nno3R8L^dpPQ>&7kGuiM3Nn%y<^Yd`jdekk(LHaQDk&cthb9v6W95C+)2AVK% zcy#;9_zCBKy<)-h3%jnZL}Pf|}DuoB>wN zsSUPk0|SNjV9brtxQ?>LScZMxA~`KR!_KOu{SsKrsVH-6#B>hWgCpgqp#a!taD&r% zSbr|e=+G?2hiUEr7UTUb@@I=pl4MRqs->Iz-FW0#7s<_c0&bpN%@&fH(H015NJ_*5 z_l$fw<~>9^2y?Y}1-y0IOG1rT1Lzak+lgfb&D8|$rLb}Wm`v15)wwm`kCI0W?>_mf zgX7Z^)hQ>Kt_ZB?8bMBO=y)aMNOrX{g*&hYs{2E3s?DJ*<0%0L6pTAgm7UM)nK(Z! zp=c*Q6?ww5&u|cC(jlS~9HrMFCx?wcVsD{2WDt9>JbRGa&nc%pYCRwa?g7A0ZOSRJ zzFO!L2~$o}lan6f$34p1U*^XUP#-_*83o85_#RM#pK5SiT<2VURH5vE^SF8d=tH}G zMQY?v&@2{sEfENV-gmi4RKR-cB0@o@%!yWxp>#>1yY(gvhsiEA=O?zlg_)9BMv7x98vl{1!clq`rLPE zwF%RCBsiEaXJbk)7<{+iRsku8+v+3CAu1{7LVCiJ=nLjYDetYmcx#RLk5ku2ocd1b z+zDe9JCaT**M}J<>=#T}nI;$n0Ezxylb}TZnC7XeiMeHt#7tx|WX29~E~#hS74 zz}xEfD}1q>%vk@vw5)JbdY+dEw^7nj?uIOf^m!LoNd7RVqW_)GX7uQ$YhxY9 zU+5B-D;uq|;}LHB^g?ViVe&sKo5Z#8c>*=&Z)%5_~V+2)tiHm_I+I{Cp|@ z;&>_f)(qpPOe^^rD4vM?lM?~>cvfR_`Tm~3^rDpViUdB$AlyG?pzVejx$`pK+0?$6BuS(A&?)bA6r>Eebo&uj* z-!i9~^4m=Zq4;x`>w zgo{4PLI2geSsE+~r%QX~$?yT(glD_vp#NQO!qkmCyYY)A%y^#F_&pPDlyH&tlnJv< za?t*-nJ{~H4$i{F8aIBiJZ}ueUV%PW(HmTA=O@le^c|a+bj0F2j?ljG>RpajOw7W^ zPcX-$=B#;qZ1P(z{%NfrcA^=&Hz)Prl2-{uU=7baq(t%ck9ybw&hf5YSEc}McjZB8u823!$ z_8GU|xbHXag~t7uafKhqf13$^-nd^i?zfH0-_BXilg9n6abGnqw?Ua6H11^MRvNe7 zxQmUu!nmg!cZYF@j5})FD~$U&<9@}s-!|^!#{H#nUoh?;jr%v_Mgp3?0^?R1cdl`l z8F!O$2aL;iidnB)jQd67{+n_6ZY|S)W!zVd`)A|+-MF@`;UdPJWZZn?PBm`1ajT8H z*tlmKSI)9Sc|3!WFB#>Ebbz(tHZXx#T3_jcoc zkuK!;0TX_NE`;-O6Mly7$(Hq;aersxU#44OS${QQ{FW&!7x!8de})O~po`AaZ^9p=3%obbML)mOgyrlx(D^ln;eOM^f7gV6XxyKg z_@gHLjB)?n#Pg*b>Jd4c4)}x6c`T=hF7TEbm+wU}o@Z2&?l!u}x50$Zq6@lrneZOE zfWMJ0=)Z$5^xb_X{I7I@|6${P-^4#=!cQ3YDHH!26MoUS|6$_)Y{G9Ems4Vvmqr)* zc9IECp^NfLj62J?az-BF8yJQ%T1*%DPc!K&jk}gE=$A9|;C_f<@ZoB@DCb5KzQed* zGOm293-}+I@KbaF{~Hs2g)WrmmalrXECit8ov| z1;6C1PqIq5!Ps%INz{7_ zmUp5&p8hUWCty-Oeg1#-f%N~1uc7t#h8Pa?3m$N(`}`Nvc$MR(A1Yt2cY>RNR196o#lADl^%V6N1UI&Lq7U4kmk`hSL2Jf#~+Z! zdUzMhEz2K14nxI8GK&-kFpToVdBwFsw%rZV%su1|J-`9`!sX?A7D*8ZKTB!m%F2#mg&~ zb4-6dw)yJ89bT{8Uut~u_TXng9uDF|P_CaCI4}H+=P~IXeSgt#ary{H`pOKPhnwdi z`RN<<(N_*wkG>WtNI#!{WAGVtaay_d_v0G{K9);9SNiasV(Xu|Hr_2@oNz7V8zVk!SOtPe|@h4NoLWgWcymxtU?J4w)0Pctf1Q*G2aV_Yt z??TWwh!paV>q)|~zifdAtY(s24YBw3o%kT&jvz08`)I~Zd{Nvi(XWo@BaMPyyDS>{lovRwks1-P8s(pPm%eMKN;!NK#7a* zH~6oK-e-6({eilYdv%;M2T%m()^s_h)8+gw0HAUct~M^znxtcUS6u2#!Y?x}e@0_? zy>Yi0cb9Sdjl0*ltUdQk|GB-j_qcfP@{TRjr;m3 z=8Y-v%KH0!dd%geagK!MkhunvINlzD%Xa7R#GA6fan#ELul!~|ogQ;}X{!uM$$rVPUOuLobNKM*N9X*0Y)z=Ot=)QAg->fyk3IO} z*vGCLtE_nGfuD~RUUS`8Z2Qm0iUVz}^ICb{iQD?XtN3Z`(d)*_=Uvq7JhbMG(c#aI zRm@wx?BcQV_1_sQ+#VWJXFhdI)wDeJ^WT5CZ*J>y$#)%KRCVxGl?IsG>{pfj^t~4& zuJW<;S-`dag~!&l1}m1gh8D0C;`vZ3(gTHG4pd$|Rypry$3V%w#CAsO*~>f_7ck`k zq~G=k)3>if`n=Xnl5SP%RO0&8u|Q49W1wL>%Ti1J#IkXU=$((Dj<+G_HLT;h))hi) z-PbdHkzxYvW~?9JVU*W*m7vY+ZZr z_08(270Z1t^k(2sclWA!H%+;5%Y9?ckslRxxBT((+um>2{1Gi2I36quq&;`2aG87f z_=C^)KDzaVLu1G88Oy5Ad^O9;U0HFNb#0*XGrg>{RsDxY@9v$y>{Go@9~v#PU*2Z@ zCJq@+f&8U`94&eZ(9tt~>ZAYg-OlJc&eV)KQB3cq?TBq39E|l1$NC3GV*2&!9pr)C zJLmVu*BolS>hTy^67gWqg^>6wd`sS}0|-rZdEOk=CdbA~>) z^!3r)mya!dy)pMiJgwZ{;(5e=9?wzxS;pJXFy2-TPv3j=m^I_6W6rFa$E@=0tI}Je z&*dJsGb#^cKXzl}<*icEi5ZaBPoU+#)pDGr&E0?SW6eMKl{MpyW8ZpJO$t2r$mIbjmpo(NxaPQu+_)@oil&d*Q8oYQvBtWYty3P; zd4sRMy~rxRqS*od$g9Nv(_`DV7LTbvj=q#-T|S1n5AO6ad{{O23!XNw9AaHsq ze>!%3Yw@wGT8n(L>h-xw&tu%fUvfqxHIT!lAL+Z~@MvpBYeDM`t?r{%%_)yrF_D9d zV&w~^W^Suh{l=qj_FnW&D|UWwr1q4{0xy3zV7+O-zV6VsUr&#&d8sm2wT2&3_u8+9 z?eIfwR-`t4*_xMfb8jEraIo^i+=DNSUh|h=wCloa{t}AacHv*&KdtNG*Ovxv8-D(M z6~|TJ`Qgq-RqQ**vRl7*jQa6Mj~*Q>wA!R>tNJ?(#U3Ba7=8Tx*9IGYe*IW_?9`gc zM~{wKR~;P-$0}F;mI~F*8B+yv% z>Bqc$1u6L)lkW=2HyVBZ7;?r?LUjFEk*!wE=%d!mQ{VW&m#!bfS6C+lOMUt>>&?LY z+`p)d;bUi7FO1%l!uP}XIHQK$;_T?@9@r!2o8eryyWX~{+V))YwWr>;vMc5<+qiT8 zp&Rb{=8u2%%G=wj6U*b1{~dcHB|OREeVEaF#)mB@96Ae8IZkLPem2fg;nOi~wWq-! z&}T*EsNf@$5H$nCcfgz##fg1DpB0r8aBGT@Eaxlev!ZeWp~K9<*Kq^-tf(Bvy%f^} zyMR&ptSFS24We?w?qW>HPtmLH`g=f{{i8fUy;wAd{t#v(wmv*6@?A!hW07F%6Qm-) zKtw$s_MI%yJ4*_a8e5+w6@gG&HeXJ%&4E(;u^O=Tfl`rtRLQ=b5$p3G0N^6WejAe= z=NFS%bWYg$I@7+A2|g~#olf8o))4NNBA$Rh`6WP!Lub$t+rw_GPtwgIdFBM8bPB5dvkt^z#`QMjs*K8 z(5PC8?VPmVpr-f~9Q5N1t9gi9ZrP8rHhr-r0MF&_WO1nDbMQ<4(8hu{fXq^l04Q{Z zAam3kXwcBs$&W#@!m1iI2<@J9ARqHbbtUkJMkZa2Kvb2Z6+@qyM2lN_Y9?ARbf*Mx zLRB-$anFg}%QBw^{*F*t6QXpPF{zEE$cIqHl%InDM|}cVLNlb&VO0+HhGrXfTt(9A z3_FCh1rk`OzKMx!XmQScC}6poin2ndN~PP?PZ?O2$rfCzeua93+9j~gvj2=maCaB4 z0y&d^0=C&F9SVc;eNP62+2@1-xsdTy?nYO$|W=Bj;qWBj&4r0i}_1B~TFM>kN@SIj4ewh3ZD4 z=%4&46k9Bnj0{L6W7e#1qg)(-_BoImA-%c$HLfsiszM8^GN4Z@p4tK=mTCgIX(dz6 zLBLVZL4eXqi$07%SWSm$rIl6PjX;Ka6Kqe5Ng%3D09(__t7usv&ze<^vQAS|`EK9j zIY2$D1qI@qwMs-pXiYZvO`t7K-+Uem{~?&1zGZSP@>=SBU~Bpr!to4M4)&&>Iq6NL zL{$U~N#82f$y2`v@#$w(arswhrA0GpD5%i`bFGY7!c8lB5dPWXccKU8Ss8Q0AC4Y` zzgGMimc1NgXVlpwBSH-JM^H%S%;1dRob0hnp^F=(v&bRT5I6ucT&3PJ` zvYeA-L|6%2xz1t0=Q*!|!hGl7!M{n)x52cia|Uo`JGTKo-T5k>8O{&z%yjMq=VHz% zij6rR$Ftnw`Op>4cBraK=M5;$D(5gro#qSx=X9qP@iUwqXsQ_wEzV{;Z=m$3WnYcL zvL3eo0xHrnCT(WBWPTsjnY2ZkC2URW-f2xbgMBO<&in?@Ogd9iqS0yltx0DwAsU<3 zYfU;^y!Dx%fUcO-sbLy3X{KV*HXT}vPDKP=HjQ|=&x3Av846r%{}oW_t8>;N;BLYr zOjSvl3^c$KAd@Zo6+F||M)wiueR$+iP6LFr?2X`7`udz}nD$9L1OY`?(hY*|V!Tc7 zh<=?w-@+sB#{`fERjcKef(tHR7PWIJnVa&SC+IOe!mJ!cGeD2V=Te)wp8*5yHzC#0 zDVg^mLgXU5l;(S#I)p8!678UzdI(#@-l7T@&Lwi@7BbgN*F` z7s9V-*f9IR)C@?BrSeht?1M!QK^z=)E)Zs)Ux*14x`fS5w(MEOS1|uWZ20Wa|Aar< zz59GC`@+&2z*zaLK4*NpPvJZh1*|RHx$Qxl{xz8ebcJ}qRAwm^G;<9g;GFJ#c2Q|w6RN-j| zIO;A|`^Kp>wHsFRz~byrPrd?y3`J`!**8z-A=puMIY`dFrRWC;&wC@vY|UITc?7ZIfw5 z#eNW?pIxW>{jZ6nKKdghx{u-!=7`N(3yw%vjtcP2bo&x0!R)!wKNI$Ec;vBdd~i13 zr_G*MQHW@_1ds4n07X6osIlc?**p|EdtuIE0yX0?mu1+$XY7*b2F7m2L+IEAPk;~0 zrAXLBm%TK4fIt`Ekw@kUfawMcDJE^DHxS@vJi=ecgSQ3}Dx^v-TgpDn3au4z`&lw& zQ4W%}&>{inB=E+z>_JFr zPJ=xNpfs#%9JH#MLdq5kWtMtB7@E^$TI6yD9^P|G%4AsJlUM>Ng+tv@FbFQ!lh?*!hXRmq@UguHiE3W}U zIW$nK$j49ecz89F6x|@`E%hBT=%$%WaMUnFE$7y%egwjb=B9K0#jx%^R{Ac@y3AKF zuI1b#fyh&Q~N!eL8anQ9K}_z|EF>E(&(@L7jajYxoVDlnT+g z#h)etR}0a<#1N>QOMxkX6)c9Z+?Y)p;At7T6>r0h4(%AUax1kUMEm-!+$znuC`rkk zChQ5TOVCYor%NEB%0Wr)3<;#kA}6=Hghi%9*l^{}v_FrK9R)Y?O7kWI+AYRoE<2X} zP1H9p7Ny;9cOD*ji}8?Ygk^IYlV2I0_y z3JHWQmuT!hFeSgzZliw`qFYcEr2%mFMm+L9hev=9%k8EvcpTzZFjFQ_b`-cKPmMl8 z;2#k9D1qgn2Z#-zUAS9VaUyz)gKb_sAIFHHoHNkU0q2iEXFDsI=|IE6Fi8l=3WZ$5@|me@CQ_hHE7-NnHpP7p@aAjjDqrdak78DgIs>)SnnAlS*PWaulp9irKU>pB9}ubu$q?4E{_l79uP)h?uD* z1;g`v9@WI#=)e)@vhXFCbBh3*mB9K|V7=!+5vtDk_5(7m#m zm7zY3YK88TwNO;?71_{Nbwgk+1kQxMX5Ymkii=CmLlM#Kdv{vJrLvb{sgI((;d#0o)`L`@Isz^gS4m1Cx)v&A{~w~6 zW@iG-9Rzpm9U!pyBXh1rMEO2EZpU3QhoGof1N%^EO+Qw3^K|hyNWN=pP zsE>lSl1d4L6(<8FRaul;w8K5crP34BYXe;+9~fH?*>D@U2-WHS`|pIg?f5IuvG`r^FjPCgo4?D zbZ(~qUQ+4s?7czz#@b#e;&AAf=9a1BrEb1{If4X#TGEug)kVPNysTcAuIAWfj)$K zFJ`O{h(A1-4jHL}fA)IFR3l?G(40o}iP&5j7Kag=*fP+2V6yyWg5@5-GkgzxmnXr& z1Q=wcyzA49mEnI*7FxKxMR0zFu|#6cdjaHSp7|sr;v1X+;?q+K4#i8YInx1^emISz z?i&P^(Oq`prhfr#SRKe<7G4~D)lGBJVpE5Db|R&gD@bYwRLQD+80po4M#kY_+WC*5 zZJtw;e}N>MtMS5puw5)8Vc}5Ei1mW!-`xWVnL-F`H9$fdc$&ZyD$l+VQN@_JKcVJu z#Z%0A`xEM9A}kz2u3ws5)4zt^bgwQ6Y1Ve!>L%_$PDSo}RXuahMdVD}%RUY&)xByl ztGNpie6MKg?j8cJCThO&@^RcHC!_fLG?7mr{6of-K#qT?M649@{~d9atb0imlKT^t zL!C{;*|;sM%`0nVAp*Rlwf4{AOgCRO)rUtSgW-qGZ6%`Xv1Ow7>A6 z^#RT6!UNU^wJ(bs+@rd&t#bY>Ks?g5)6oAx>-6723AC$t|KQ|G-E9pKa5gfRxm%PSriJWCZM8rc2_1{XE>Fgxhp2N*2Ui(!Gw`n*RkbEKN=NF01hb zUay~V7kp`|p4&(>s8Q3@sg&*+RH!)ioBpf}3{@Gbgz#DG0GOp@OQ-sajCcVNIcm;R z@K+yX#A*~#ph~&zlC=f=pR7u#gR_1K@(WcVr%O``aX1{tuu@uVMo{ups?ukfpLwc$ zd8VmCE;V$XnO+`bV#y7v{x{6@ELeSllGS$>r;`h`AH3y99qu_G#w|x-?sws9yAcrT z$!u0m-5x_ua^cAaGT{WSEuUPVeb%$GdoiVGsC&?QLADELz6DBuE8gmM zV42D3>Psb*YpZ$~5k=?r9JF33pvEW~wEn28Uc{=u?$umC#ypU}_(1+HATvLMGTy2n zGkGmIj?Q&wkX?Wm4+T&+JyD6lku|t;0c#LN%e{rhF8d19_MPiF5k3!5J-EwS(GYj; zVC8N_kUN`Y{|06G`8kYw48gDCo^%JA=nHxVgo!{0?nz|DVPVA`2=a%L7`H3GEPCKNV?mp`wQF>F*;quw(x>3n*3#$1D@{NEM zR8G`Dhboa?2qa$*CJag6;k1N^3pmW+Od zJ5-3ktML4ufhq*%qa)42U00951wghAwFsSnz$V15$6eKgz`r7;8uxE1klKof44!C#iOkP0FO(Ag~TO9(uU+>hc8eG`E{z{BHBLf=QgLa%uX0bD1sZ8-)8tUY*s zIZv82695t1(xesel;W-=fUjN2P2H|*VWo!GfMZI>UZdz3>L!AeJq4j!eJZ;L z&p?@vyNpw~)tk6Wei4FuaZh5uS}Q-yKY`#68TIo*G^mU(_2@grxTSk+knX|P6)wgt z-J?Tf`kM&eLn!uz)1@!)bdU_(lRD7Vwn%4Kf*_5stZG7u+0&4AA!b)+O`$sZ2I4rm&3PO0#IP`uhi)x3z`^>_95~n%bcZPz%ePbl!7DNmp z}yHeQb`nn_mn7ZAre=n50JkBkHR ztnB-cLUwk?p*2ghA4LME`upQqtZbSTW86ng+z1f-0dbt>|47H76RUN4ae>*Hoz|~{ zo^>DHx8litS@{A@l5nyzaz} zH*%;|&jM36;to-fUJ1`-3`|Af4tQ?CEuHg0c)p4I#44mzTL75`&r^u`G44=30`t%l zYH-(`g1`v?xpD?l8WC8B*fqGVs&<4{!&8I%btKoULqy=}ouRF8&jQGqxT|^)=mi8v zfS(b`PDF6H--+8Q*nvk}DeeT*lGWit4$}t!Q;)l51OXQCLAW19_Dfm7Aq1{LDmtpw zgxZ8IMZ_nNavko_bqL%I&%fZd3a-TCT}neLesN0}-C2k(fbU(n$zZ2gPQq{9S;a_p ztGt4AV(Wmid#@} zPf90clf?c{ibW;#se~~fR>Rm!A|W}6Z~Z2)nB zs5FZCDHVyOGjBsutd2XuE6mWpz~GzM=GKXt5WI}(u@b|KXC%tqIC*oq+LC@cgze=e0GvhJ5VdW)FAAy<9a*j*pAOcB>zu-3_dM&wqFbEe*$B-(IU{bL zijj-98*50+U~-khkW;CY1?y7{G<3CS6QVXrStbh5O8z7t6*)`@!Cukyn!t&-I5o9_ zQ*Uu<=h>0BZ*fjug!smGn6DC8wzh-S=tgJB3bhe9P;QmP1@cF%@Y_WTs|KyTRz;<{ zP9aorixVh_dI??}F?r;Qov*`zBu4mC*EtzFRcRYr*z?B)R+;K%1nO^bGCDG`mt^0e zEr1o@;&gOm#e=c^7Rcy097u-Ih=|Mza&GNdi-@XuJ)i5(NAujLzD4t5kE@#khywsF zuZif7UnYMsa~3Z`mPL!epynZlhhXDlqjR0Qi_Tr@K4QEN?|L!q2kLQMz^^6vYjtq| zKoI2I&~Np&78yPnQ_hU6%j80Jt3w#oLB{VLB&&kHn0L)Oa*LX&Mh_rvOl8%@eR5HUV>C$11j*aLgK^f z6{((=`ilB1qyMUIm3n#6w+4P3K=h9Ty1FJBYr4eck>d_oC(XPCRd)A@CpN>x%(zOK zD3V|zuLBEotnQCmnw`L4q4WMx1t(rW5Ysitu~_Qsg{bY`hi2G!AEeF*cCc0ef|Sl+ z5fXRaEV54wK`elfc_H|^a9L!pHNR@V6Rfy}Nmj63($c`Mv>bc*fW%5)39gnD>E<-B z7R_^qt%hm0IC+Ier!YS-d=?J}JH~6B`V#|JZ*^Am!rMDQ@B2RiaRH;k*8wJ~wj{ip zb&bCuc^wFobE{v{5ba$-4O0!I)pbPLEE;$hy(8$OYXKN0%&q9C@kTMZoWOxX$Eit= z>y*kur+Ir)aO76y5688O!O%#KHa4U5=9{In->gv3T221fP^@Fc5-O{*Fj$%4EZm$D zLlPgxqY5m5m-`!G!4ZBAUMDGdK@Cr5F zD}kr{)+L>%oKaWW#lt|?U@3wq6~UI^X6Je^k}A=R4-kN-CMjK<3eVlD#Qmr>PR zqwcfe{F^;S=f}=#jt;no)j9U@+<|Y4XWy)OjlK>j0yF9r#-yDd7k9qjpln zzd6TY^DvG(SSpCmhjGUbsf%qm-#`vHN1W#!wJ8n<67)o2QPy5g6s}$?GlbGxoG+@c zsnobbfhz;4ao-Dk%}I^>hVx8nob)LatEW@)#5ocxgvwADzv*CC0uzFw)fhxJL2x^q zQS~8Zk9_bJRNxT9*QsCA`L%jZM?a^YXZRI0M(5(dtsHT*-uCdasY0vKew&bZX1w=H z?c?*hI8h!sMbrvKiy)_qme}WkfF-Np-vlDoIftO&nS31wOO7?yD`?L7nDt%H$;4Jn zCXO)S2#MS3JdZ($;IF_%>?`Uug3kr`YwGd<@Lf)_6U~O^*dZ*bRi`_P&cWmSn-rd( z!`uYU&(+`H2>E;%*anOli~8|6A3*B>^kEJi0>Dw$v0B-=uSaM0*uxDobbt)(!W=0= ztA`sguH{r@9n8H>`C|GnR!Ja&6UA~r&B5<2N!hbXQ?s8lI$?GpOrwZ_uvncve5>P} zGXnp}1%a#EoeM@)Q1*vJxe@XYDsXj@($d*)=Irfe{H%#u-_BXvMobHT$l){4&3EaaOP8fr@K2IBfMC)BS#^br$O_;yi^AeW9y;DM#{8&IQe`fQp z$KmnT#BK}$tcM+^$a2}9XdNeOg|qf9yvD|4-l@bHb;ZFki2?ksU|Z**4uOAo!dBvxs{ft#Z~woj-|oKcb-TK|>$-;a z%;_KK@0runwY{%y?)=*MwR7wG`nz}U-GS4HJYSMI;`d-Ww|iiyhhQ}4_AXdFFtK7h zabfS0`yU`@@_QgPVda;=_#YVV+Wju2Cg9%%$g7y22I3y+>pu6N%=S-$vy|Ok2k{om z@O#J!`@|H4?R)!nkKi4ciJO2Zy$by^6&QXmP5<6#eHY47S*)uRx5Ct!IE4jTY@Cs1 zOd=CTnz6Hm+&Iv?wih~$=ahK{oADzBLM#eN&`BoXvjD9lNBZ{k4EbWA&CI!d$OmQa z<-;qyJ}4hTBmfe>Y67xrsHY17{630+HV3W!-2=M^hTksK`y7*fF0!{KvR6%%{a#zL!(4W$>sGi07t@4t zPE3e_QSUt1QI5LNdQw$f?uN=}j5^ny8_afRl)H21xBxAvbL$q>x@t0D?Q>$eZUIs= z%YzjY`P_O?QBVtu&-OqJ$n4@;w-!;QweEsgZA#s4j}sSl)9r_?MT^`VshizMGt_gD zf3`c>J_%LG%gxObtJ)zN*e(}tM1uE7R1xzm0(FaX-9pe732ueO?OZpXwW)&_`GfXM zk`X1Sebon*TL_;WBr9#irv>eQ!#OoDiY-}aTsjimC6=Jm>)o6(H@6KDTXLnmOesIt z%`QWkbwWxuqDqmeXt7&b<`&htrE^?k%se|-mn(?!0TTmEp`8_T^Mm%@MebAtOV4np zmb#_&?$p_cEqBWim(M(e%?vg%?+Uk|!p$vp3+KAIC5S8+YuPNkK!EDpw5mAqxu|;P z9H|Gg!u8CN*9jQ~x4OBrC&W=mT=v>U`0>^+fp^mGHc%q9BIc^{K!C~FmMe>A`zXy{ z7vzB*LHnTQt2)8Wwqc9houS)P+h?zJi-OG{XO=rVSnH;jyR*wEUghO(4yi2{-lD-! z)LwTwN?TBc;_MP~!QNh*>oy^7dTlI*aDKev#X$w(%nYtF?NH~=2N;+R6xnV~xjP;0 zQC`bT1^+lxE^9%byFFL7sT zyXW=jOvz z+S6CKxpi*#R0zlkutqO};+{a6hCe3mRhWtE@QHNm@Ni>pJ)8hIKVMwsvPA+hw-gQ) zQI)umMY=JzB+SWE{-~(}LHoRzE1fK63W1;tBp=WW=(@_C#z4?+Ug1i?$gE=)|Cfb} zV9tI@t~(2;E9%@?W#|O#ER)H;te~A;>qZeIgY4c~_OK!d4Y-7=2yL})ySPd#-EvJ> zf;qwzU=SvG%&ARgPA!>}mc$&CJ|T15$#szUxh^Esuws$B*$}|0yi+`?*p4iy;)z}r zvw|~B-OxDpW>FtCUgf|Aw*tc5GG~^1Vr2=+tOuLOr>uCpPgu2y+WkFOjY4VXs9fkP z>IVBeU^BEdl)e4+4{U}%2+dII=GiZ>*C2uV!$q~Tf_WH<*v+Q~?Hizpv+QF~y%Lj+ z&JnGX%%4OG)njO$JC%K{BG2@!s&>?kvY+1WP9~-btz>|m0|w$N+{o;tcsqB|VraGv zD}pOx!7XmYP9q0ZY!T}K|1{*98grwyNuvUXujyLhLpM>^moEWeF7%kRBGT;)svfQM z0`?%3jBSvh(+pDT0!YmcPLshQJGfWI_(Cm^HnuA``cO4ZUn08ML!4db&Ot_KjX10x zsff}B@g%^0_yR>&v}-I7O;XyQr&b2nLqMZS+>!?L((|D@L#x1k@lI3Vlg&Cfv3zgo{Tw&vm-I8Ha9fQonPY4WCPS|+UwoSlOMK5-jA^N0RH#ar{`4vXnA4ktA(>%w?D@tLO8lREl>l0&`ToxI_BV8jV zLeFcpiTR~XOP9BFu5a1UvVK!b=h8K+mvydL$=R;p*(Ij1b`A{f=^D}St!q|ybhfVQ z=I6+PvmfEKenb%H2riEF8JR=F zENt2Orqeq+nl`NL?AWrlrL%d>`eiNa4L0Ed%<6h}<%xCI(7@h7U?ju(`uj$#uHCyk zS;}x{7gl$^qWvWygU2PaDC&gS_x{fA-Ce`OJ;O-Whn)jRR|FBAJNNc?cXnC{Tk|8m zSi$u73=dnfNCVf&YHP>Pz+flI=-xg7`x+W7e|?jiWX-CzXw3~R%b2lsL+7eB%h0~d zfD)@B9@)jJ<4k!WU$69}wC?SQ>hC!KKJ@MC9ntmZ>_#gMj~oPNyk-*i5AE&m@9W<+ zjsx9$y1>bUgA_C^JAFH_UhWz~d!ahpyRe<1*}Z$WHN1EG;DHGmtYdv!)9TaOTPz%S zxU*+ysAq?6=e=l~PQ0?uHbSfH={nFk+;@JDsV6Gk*}i7!N>tn|=eh^>f_hJE*mh!- ztaD@lBn|cL=plD$Ne+(SW@SBaBW1pW7m;ERgNvx&NRMtG5V^2((Av>8(xvGEf9KBw z0A*|EFldJaSP=1n-TP1#5&YDCvSs6@&J7(+>pQIBgAg5b*o3?bX<#QfDJ?Sr$5v6; z*S9R~(0tq1wR>;Rur<=#v!|yMMwJKR?Znz@i+$ccht;-6>U61={kC4td?!3I9Y$o@i4|H#lmL`bh0?(V|Ja+KI{`bDdf`p%BF z)msRWq+r&c*1T}xLWsnUo&y%d0=h%=1>00_ba)~T>GyYE(&2Ud!LB~!6MZxUIq%vr zQMYSiQ70@ofi2lHv=72F&@X_pF@X-z2{qEc!`j`qvxmr~zZp&2*S~WBHQj+?1_pbe zBeq-YBv$wCfnkwC-Nm3eAdGv5M+Ugl0Sy3Q2PUmPOpgbB!+X)J(p_~Ar{u3*)6vsk?i2nwAyjE(Evs3}S<7Tmv@E9UnDsd{o2usD*JZvsxHKgp;Tf zy-d?BZwl57i^rxmVmyHi*w=?@?~zvG{*oRuh?wTmJptEB0I{;8BrJqJ=pTSu@$pke z14MX|eOmjLwaeq9xQOASCY+V4kFmC?isSSAH)QRg!J`8L-s*oLt;b~foMR{(8>fv zwn;02_#|d-)|zKwg3!KUX?NXQrF-^J5lboCEpMbsLV}4(LQr?~U{o47s0B4HYW#+H zM-K)ba+bYH56q_Zq}m%hI@h#zu4-8&g|P2pCM6X^P3JDK2DYCA`O%}HH}3(;9#%g| z3|dw%)7sd~VJ2Wk)B2^pqT5z)>cs4?X%(hS)SCx8y@|p4_7)Ck9h_2bT-|~BS1JSB z#&`U-@g2Wye8+EFh@pR^w-eSdFkRpYv+iItQ1L);sr0U{1`L7i=JPp1a*T*Kj7@ zLq-mafK3MndxiIym&tMmZ8k92g=sw0mQP|iPPVODYZ$1fLgT2|xO(O4HK(t((AD}d z4Ts2ByD%1aZXX!wg_7F`J&8JSkw70^p=8X=pNYyj_ObanXX_+$HlDkgX~4EmcsYW4 zRc|U8U#pH^{I;xLujjTYLsj#d&7B*TH!WLpx`ky2S2VgVY|H}|p9e+E#&L4Prqj?K zoJ>IvdlM>emiCV7Yr-I$E-g6yWY)|QQ1=2@Hy%StLfSV<7DSdGebV?#@a9%m?B zxI1}d!uy6FHmeTZcfE8(xWfE1`1eM;@$&pj6Ghx2czYAI-ZV}ClGBUT&T2JqBVE;l^ z`lczsfzFXVgVYA`zUHm*!3w=n@k~c^G}C?EC@|K_D2l$}PE@tKr*~jCc2bB>cT-OS zfDCc?b(p_)LI-1}z=c0+J8tD=c6Map1zk1N$u%yfh{G5lxkLpb(Xq0nAWPnJ^?0#! zn2TOCR$PI04q)xt*N-G1}a@IGY;u$ z$yhIfgz!$$U9=?^U%sHi(tP8)eaD(Lo$XLIEtX6jEHm_+-!n8|LE4A>;;^9;O2YCM z99-zi+!oSJY4HXRZcm7UH@hpWi^!ROtV-=bt2fP^r*#^|(-Qz|dl#08V(;sJs1-ca zGes}SmPK=02X+u;1prAN_Kk1cEK5jAVm7(HWo-*)mCFQ_3Uz#cT)k=DT+GU4sNmKS zW!B?87jN9=^JIklA1@56TUwTNZfaZF(Y6Yri7hKG+~aF?-}ad7*7OaX*ST|d*RJ^3 zE(=rku-)kJoFwQOM7+~d<6&hVU*U*GHOphXPtrGFc8!E;Z~urB3$E`HeV^hzp0Dj~ zSW>ZL3UA;+N1}4sJE+$??Cgk*E14AKFMO502RKf8hOJ$)bRh?aJNNg>@)P5HSKn@H z{}6O3N8!X8o8!g&#H=f&(c7E0U?l(*g#krsBGVjF5uQP%(TBm#Bq^ALi5t41M zA>wPR2}DJ2b9A2G*0J1(40-OYIAnvyTZ{{Tljgm$BN6YJviD&1>zRgh8Cj@_G<5C7 zKC+e^-{7#UWpx|06IZ0NVozwU4Q;Zgt?7Sf0+w#v(6MHf2pop*R2f*?-qf~Q&z)qE zfoX-ev4%Q|0D&XAu6n)IvkM&oqNleKy`CMPT6t4w3^#fdj!#_3G&7s`Hq>RIi8&b< z(%&~Y2!)2GgL+H}##_k@k)TL^=z;VnmPgocL3|ukZygabZs|x5c!`d<{B#+26A>M2 zHg;Iudx!KeyL0zmu4lacoH%B^*42|Ukc(d;L`iUcq&G&eTJJh2n^b&Z3~Jfzb#k&0 z@6Oy__O@=lMoAJJy^lFwpqgY)V}kgGc;hDHN#54f^+Cx)UEEuxvNhADq;V~2RPeSa z6Wm3X#Fn-0RSCno;FR7e*Ar9l1rZB*yC$uXuSrb zZS+>Lr$BsLF=%IRx67guu&AkqF^A?}ip1zK8t2I^U3zk?x@l-njB}q3tP?RG>+6rn ztHac84~ISyJmg;LTxNfi zkbazeFW;Y!@8>sVb2hnreoUCSY`i3!Tz=GAiDZ^f z84Vzv`T04hzVPC!@3Mspi3r=uO(~D9lelcW_?lc^zQymTh@PAb$cwRlcz#ThxM(OY zxjr}n!*|)%lob3^tU;s`Kl@Gq>CAsJZhdKZe(~&unf_TX2zdWxTXH5+Jj%9;Q|Q4d zL%z$l_|atIvT=G^a{bFB|4>6pjJ? zk_n^RB0S54v}0T4DdCC~`YTe>t5WE#68Mg|JovQ}&r}EVtqG}%vahiehuzj4FApxz-9Q)xY<0Tkf9vN4^JlbE~eL} zgcqiS8&kq75oQ#}h#Zba82J5r*RVUAn4Tqmu&o-gs&@ENd{a)&I%M6RI%$hfp#4kR za8(5JG=NH5;mLn zV+X9WdvFl@TJ@}2;+K=;Uo^a08{)ZIGe7Av*E_C@k!JSNiNO5A>@7t7I1}4D9$M3A zHQtcbp(AS8v3Yr6e7ztS!t6_FP`MmC=w9`I*?SN8sH&}fc%3tSCNmj&6EZaE5D*om z4NXOXXQB)>{^qD#TXYI4j zWD-E{d*Ao{e&7H5eLI=+?6UUSYp-4B%sFcdZV~)kFo3q?be`9B^Tl2oY)y3*-w=q| zA)F2Ho(8jLf;>O!GF1$=hCJwIar!)1%wztrUGO9$rpzKn#BXCf6V?y~e`dr2P{|1T z0QxM`PZs2PP@hJ$l<`D#J;q5yd^Qft&8BB{3~4q)%earHnCb&{?t>9IH8wGC{d|2=wf;^{kdG85+CHT8w zqo9}T&+-eZlUxx#TEbHV*{UnrGi%rUN6XpU~;~@1s@gU{=xCD3w|WX zcAq(Zk6@KxT+qkujr6X9{RNK_oG5sT;5@-|1uqg@C&;HLF~55RpAh6jHaNamaGT&a zf{xL5FiAl{}> z`~!j=1p5i53yv2&S@3kh#ez=>z9#sAV5K0xv&{AI3APjLBG^-~uizlT5rRhxjuo6F zc%tA;!8w9w2xbYME4W-xy?+dOR!jH_!D|F>5Zowuhv0pJ4+%aY_>3T1v*mieELbA= zxgeiL$?5#oG-F6`gy0E+%LT6&d|Hq#TXR0Pf5O;Pu&>}C!4ZPT2u>E9C3vRbd4j71 zuNK@O_=F&zn#kq7Dfpe>&w_P=E{{paR$Nv61cwQ-opO#pQE;x{Lcx`SmkX{JyhHF2 z!OenO1WN?>3jQYO_nPI65KS}uM2)C7!mA*wV&nXql_6(5WGZilOUh{!|5*y zz9#sV;0J(39b>mPViR20>P&RUlIIL@O!~sf_#Vx%O4l?rJCWcg8cjZBUd|L1&!CwR;g0+Ipf*SU& z%$JXtX7mg4>E|5oCYUDJUy#o{=k$?+V+1n5}!w+sFt_^V)pAYL<4`P&Po2@VzHqaB(534(va9-PBB3EnDrx8Q?*_`cwGf?a62tSWwj;3W zvEXXK^@4ne1oL@W@IArL1a}H*xGlwWse(NO2MHb{I7Kj1kdG|leCG?U7Q9yQ7QqJv zpAvjY@Lj=A1>4PPH zxZu$eKb{e~I$h%V2odJHOz;B1wSswqH!vdKMn;r#x8OsP{+QrD1)mdqjS>026s#0X zg|&N*A0#+MZ~-IgS19o_$LLQk@Qyu-;?-{1WP6UTM7RlxJTk^1vOZ}V)^}o z-30p!9wT_7;2gm$!OI1&7rafdNbohm4+QrKHVZn@*H!-#94Rx77WV-p z{5~V}{jp$~#D6Q{9|U(x{O=O360DPWzU|F??1COf=%s^%y9gd3@kdH{u;6im;{_)( zBL55tX9}Jw@mUf+NAN> z!5YDyDJK08!I^?f1aB04LGTB`c6|Se%Mm<5@NC8-vCkHKT<{IS?*xwum~^uR&lX%R zc#|NX_00U#eJvo=O!`UY@6O!6@byjgzmW9ffsE*v5KZ;_F^tF;W<(^is&<7Ks=tHO z+{ZJ5?ij(zjG#YNaFO6jM)Zp-1^+I1r{Kekkn2fC==h(E7*AUmQP``DA>2o1M0p=D zqMTAj@XbR7IX|Bm%lY}7HqL(^_ZQ@!#QgyIvl)@!>IZeKC*;R%4$}W3dI6t)5>|Qv zztIv_dI8@|3D0E&|1}a`%NW98eiFWk5#<$0Sk(t|S4emdBg&`Y7hiS(KQuiYPtBRQ z)bimy!c{a}Jq|d05#He&K56#M;fPzfXgDVgKh%%0m9Cr>-H75&f14^fjp z&62}?VtDei3Gz6rJea_JY2@&cq-v*xK0NI~z3Puh4s7Abi9VNEf=@n z6HXW3P$1J;;S&-Rriatm@!Sl5?$s(}u3;<(wnEBT$a6WC1q!QJ+_U?uxlT?*7|V#F z=X}g3Sw7BpDEW9TNS1FA!pY8(?;%9OpO9}c!dwo2*je&D0DrQ4pC`$O?Mp(wGWeM{ z%gk;CKFMY4D%O0qgz2pCza-uQPGh$lpJe%%Kg))#jB=KIAAr#IdtjA8*nn^vraepLwyf z>TwL{lFJ=>c}qXQ&oYT}7n}SN^#}?-#S9lqj5CGK3iIAS*&$iEYfQR?d`!pk;U^L0 zEcw=fE?K^DN%G<6f`okENx7DuL*VzM@M5s|@iSk^{APe(SERF^d4Ff=dAsnl#Q(tZ zfQB8Cm9rxr{zN^Pj_bj^*jeSWf|AQ!oKz3oCQg*g&jvAX{tm{j4B_KUuex#?fB0D- zMytLlm}v44XF03fvk;eD?kbeK9zZ3UM>7A7B^u(nC!SLcKn?U{zQG5j_b?3 z*jeR1)27^LQhoaf9p?)`?&Nyh4t~jY{VjelhTp0lDcE$TBR|)pUlKpN@B_JWm6n1e zY}Ml!lP*yYrek@S7dxxmQJ_oK-#C=ZV~ES;IiBe_-_kbaHh`ZsXCOJjkDr-J<~IZU zto}Dh=$PMM+wikvPme8m!ddmWxeZ+^=q%Zp*rF?JL)QUxT#n@|y64-_^#GkUXE3cr z_mR+9`GjED);9$bmOo9zs3`; zIE!vin{scz-5g6?E{`p%-J)&yHB82HmKHOh#jl|azr}Z%Yb*2PJ%Gh86&@=Ov&o!- z`>E^^XQlZ-m#mkk!S8O+FhAZCSp537;dkUzjCp()vz)~*tqs4aU={`u^BaSY#czc0 zp+}0#9;%uZ4Vh zh-dl6;lp&?ANd(Rs5%#35naVGiz3d_r?C!Vi5(j>o^MGv4_6BL_2@ zNh1;GsE=$-t$6$~3uJJSJ<9p&>om9B)}*<~#Wx!g&Z`*-KRh;SR>7DJYK)Vi;}SPw z92dtwe@KNC6~b}sd49)_31kD;n65i)G32aQ$>yag$q#Qd-at)enNDhE5BM1el89=I zRyP!?v3 zg_S?nij~z)NNrH{N2fsFP-E82fre>m8${`55RDj%wdlPW@}PpzD27zb6bd&yQFa^| z%pp`2b2yAf(&JEmT(3nbdQ-fq8Hsf~!K%Js#G}pV_lI@d4$ub*K8OTD+E7*$-6zVj zpm`95Mnuc96o^J1rEqRD)4|6qoALf@qP64j!y$tb2|@7EFegOGz~F3DLno$V)ENe< zjXJV^bRFu5p&z1Mpcx*brc0D%MF_T1YMZpSK_yVz$V52N(Nv78Ew=@nx|o^ORgEjO zj)o13ftH4%nz$1+#+#ZNP(RIwCWP{0(O6R>JZ875H5~RR=9^}2I9nAnt&2CrF=y6V z4F^?VQdLt-GiQo|In>Gn1gN#rlu%b@qnSnj3`B$xJO|!i<841uSW)Ist4odD3*7qRrNMoGa9>r;!#vH z+8iZ};TYLFlj>byOF%H`SsU z8h8#m~os4XB~28hH$N;xO#Coh;Gd5 z1KQ7>yol5~J11xrd2*~*Ch4Dy=5LrXk8Uv6E_-F35mSo`I8KX+M_7-V_;yTg3gCsnd)Dt9F%A@ zkr&$HiI#glSK&`ekcN}>iKXJ&Bn%0AQDHwjM|H?Aa?V)Voh#+{EaAoFbi%f^<=(4PPYem?c~; zgpZ_jr_)2mB+7Mr5MD?X=oDmJK_OiST^?oI>>i5W3bX+Wu|>tSV|x! zSH{b=T!r}(|Ck2;7?GP8u`_s9Gvz2@#4hhc34bm8e%CU+UdY{D&vbcQ1|6^Gquv_L z(Zj0#EA+6N!`JCWC`Y4v^=zjD__SW4(%;oXD*XpNWYZD}f=`p4uK0AYRXUiy zzb)V622Qe>^k>?#-F)cgrM9q(`QC`I2YTHs;dg9iJ-@M4D1Gd=RjTq__K=cufIaN< zA^$9UiPGPB_B^K>49H6vK8({7+FXa)#`7q^IGFtOGcd!uj`EoFcy~^fbEgMJtdCp=){6-1C#)$dhN57fR9|$|$pg%5P(k&N!AYjV#Nr1d5 zNKZ|LKEP*eD#}GY)-s}>Y!duh&>1x2M++`uM0pPcP5z~VcvnivIiVfWQICt-nfxDY z7xeNtnJ{eV5e{wG>DQiiP2WjWG?0Au?34F>pEuAQy6L-L!;5|7PA|eE&*c8$?fC=R z%{-l)|H`95_l_Dcf7}nx;a2;gTlIWTyZndf>Vd0BTR(kin0$l0K{27$E-h2R+$($x^EDrQhMszQdPZ zv6T8vp85G@cj+Ne({(iV`)6^*|IsI(y5Md7eA0^$@RL2C9^qR#dGs7?tB`%iv)V3a z(J~5j$)isJ?GQpFy-|3kL;h#%$egTI!iWHQ^XMPs%cG4uzPR~^3Q7s{4d2)Ei9Y*_ zw(Ei&+2krDM+w=skJLW(rQf_QmP@{LqUR}fM_EsdL@4q5Y|=g-N$)J!k*B}@d9N^? zk6#L&dT3=3uM&*2Z+q_b9Y1fO&&XcF+{Y6=PFe-IwmmnV&L2jX`F^WDpJrZ06FeWk z(|ud^o%H-&^r7d~zw<9b`mSN$htJ0XaXv0|{utaN57L?XexD9GAM|D_m46c!a;A{w8DBeA3Fkr16N%1VI{66~m4l3d~Tj z(scG6)wr9U_;+d*?j6~c^kgdCLzVYXYC)KqXN6LOX9X*1IhUylmP>3$A#&dpC0l({ zX37&)Wy@AqUbcO8r9XRhrADg{pwL}ZRacgp<|(YI^sP&yo)BSTkfrr!>z_m1Q`X?6 z9Yzjwd~8R4B|T9|XI9dSvG1kMoIvl>_%KsKby~%lcvk?*8y41{*%3y!eyT7jN+LV;}v^A9}RHA6)PEPASp9$UpgS z`2G^AeE`|-;86s@xYxco5%NaJkqffdjtdj!SEKJ z_5WZPzb)(ck*9xl4=TFnp8Vs}dwi0uQAPJnRcmPH&`mpgp<7p=Zcl%y)o8nVk@qhL zv|T;#|AJgQ3KvlLdi=;qliH3>CJvpC3uJ509 zeHfsE7gNz&_z$%6DeHPlT|ham?+a`+qx-h!P#ph1{drpY_+Av~MXC57M!{ZM1^=@w zL8`F+w2Ei=6(A*`_M*1y3rhPTq*b2<9+y)uaZkPb>RV}{tl+XS_K5f)_ZydmtsM`Meapz*Hzv6?m_MBD5`U@ zQB4zZJ2K=jzL``_Ss_XbIVwo2rnAXa5IU*CWmIpD(~z%SMn3XrL0o9k`t|EO{q7+B zoU?vCx)`|QxB2r(-ex0DH>&hV z`S$X>%`fKieEvAbW#PU-6xg{ht8iU-pS$LD+NafTqpj4i85OU~D8xMEiQN#%qzjC9 z6g$*yJu2rg!qltOh?cE0b{O@;ny7fYubws*=EP5p)McO&HO}LWN3wC(FI}<;hH-sWJLIbk>c-mzb-1BWw62b{S94E!9y!;CP_B`k zbkRVYOq!DA$dyS{*Qy+ zPpS>$r2^vsxF8vM3}YwRuTRg?%j3~?y*{IHMnTXKH>Q%lWJ&uzcz)h6FeMp}1lGYfV!p^}<>PY8Nl%qmh76RWR)xZ!z_yZ!`VdJCVclcoFj0CWMfI-X_#)>SP18GHU#QhFS6chVj5I z%4yU>lu?h=bzGk)b;sg~n>vva+Gu1?G>jgG(TH2>J60OeE6*^p3yeJK0EJ+r<=Xb_ zwHs$&V$}X-7-ypq_C<`dFD$R!tCgOSNw=;CO=>(7ebjiHQo$t%{_!kan(%2r%yYQS z6s7=oyLQZxo!`hWZ#1H*MyXMPJ39w^np2IJUd_Dm1(O(T!3@L@{m`D5UVZgdCiWH5 z-qNDLTI0>VrAGN$!>BJc9$ahW?k&v@tj?r6pkZdYIU60#fC4reM%W3KH33|jY)h6b zS>%VW5po;NPK?oOnOu9Hde&;?nLTSMql}zUjH?oI;%AV*AaO!E4X+_R0@#h-i;nJY zqO3x4a!%Ia#xM#)SyYfo_q`r{HHUe3IKKXTaORYs9FO2f*l$=ej{ft>a?_PDuS;A8oa10Ve-1x6W-Fm`S>vhlTI2=2~BAiPnn9R-J7q&U}`k?pof^q%J7 z7}j%t=$}g|2QUK`FIcnPsPh`JHQ2WEKG2bk=R<(pGMgjWv^l>tyC9EBPtU`9sOUF( z$}Vy=Ox)#&1t;!}1!*EaG!`GE!qMi{tom?_D3mvaW0Taf8Vq++~HAl5-DVm$I%ILUY#sMmhVk$#t+XH3Bu7YA^#y~5^ z(;e^aebr&ie0_@%9)~VUZp>pjMtNS~^5-IX-+iM;F8(N}Uqol^I0;F04cj&v*G~Ky z62v!Rm?S({BBI6#OO{OJX>Rn?DNtjdK7_6w57qYR6HmjiY`~;o6hQb!qb>!WPyxo} zI^$k+#?Q}Ny?XU5B%#$I6auTbiHkTi?bK6GoybY;;Gj?p6od>T2cNok%Z=EA`1!_T z5u@?c0*;okYuofNVKKzeDFvBAj6YKYV?hQ}yvh#1imCKyHum7}HfsZ&FwO0mdfNX;}@A2HIrx;jI&qCfH%E8a1-u)5OjmT>hsw)a0uhN|xRf7v*!Zqfj=j9X` z#?otWE1uW&hC_VJL1}Ik9K{B@$I$qbYf9_=oG`AokK>KlRSxpR|53V2nQI%v>~8{p zsL#whFNi?_&X~$BL0g?!T?c&} zVLmELw%1iEzbxjhKMvDXwz02x)28xikI-#o2Zi>MY7D)g2-N1(y!@ju71SBwG~>u- zd)=1hl{p8ThSSI|uFSe)bgAB4GqWVc7++64;+X7tGH*ZjqdsX+TJtgJNS)!S&dJGH zcVt~%eQQrYBvsk47^|Z0;%fmmH}qJff~fe%&vD@{RE%+HUN*DO&lmI27Ci(XrbUdb zzhQ{O)wzwvoMpy(+=J>}+E9+}on>4dF)qAiU4tHpm;Yeo>WDOUYvsm|Jy)FhRQcGh zHyY(X{E9fN?5#h=V5j)wf_o`Ja#i}!bvODzXjHCiy62vIC?~`e>3rGig(Rfe+21)0 z3hucNF`GObhT{8U+0X}d84SNma~2|GTLZs7r0aMU<(>sf+e65%AKNvPqjU$qyJWir zT=e6*oui^$VUAMo%FXP0DM#5IA7iz)t>KIr-EL4(u5TSkaXW5BDK59`dqj4zJJ`Cp z%kG+hG+Q@3E@kW3z86xQPvc^Hfg`$h;OW)*I!8Q_f=j5wRQB`phqitlPv^vMIpPGC zb!dn4**_lg+0r{+0e@G!Z4to!WtYbQF1P&zPOE|6acPf15XRXRm-a_Nf_~03KZjqx z0)FR$l#5X<(peMEtd6%JVAnrF8O}v1k0ap5eQgBJ_5TWj6umpAEKz}=dj+SQ=VzJq zLU$o^SgJzW!}`lyv>|BYo>*`*se9l>U8$eEL3 zL)H*={2G~#*9QK`j9A|Ge?yJBx_X46b3Fu|xsK>D0Zd4L8CO@&Zs!2(`n!m6_3FM3 z0k_`Ck3d?#M-fQT-(|9p3Iz3^T?q87|)E(1V{-w9YJXR6&|ivA3!-1Ae}4qs4ThGh2wC4EQzMKE-q)vpmLUC9^p4E`FN z{A)&%XNXcB`7eWisPfzWYetc0nDV>*m%%?=`BTVNh+Li#HWtIl99)_^7g|WsxVgM} zftS!bwAY~v(oTddc!m#3)3s|*x>M_yc0*vQdqXHMTW^ymHb1hAN4jy)n3Y2fVAI*_6tPlT;()}FdcWHVUt?S_T zjLoj%91zGts&)jlLt3-yDjlF3T^oX{U8`l;w42Zx9xV(ldo>&DQR|1sGRXD;5}e1_ zdVs2j-8t29GdxG+fxc_kgw8ys$=B6+9FJ%HDTJJ39qcE)gsH~`cnY)Y zYfyx9yb3t=4jh=E0&e}UsE>1^|6d^U>K(b*unMH;3s58Hq$9W*0k<1h=VWuPS>wlH z&E!1MwH%Q_{YzwZp47E70v*ZGkM*+;5;&*ZSZYznj6f#hH2#sDw4;?ehJ(MZJpy&u zC^Z$NE0Jht;qA(&G|v~piSxKHgH*2YO$ieAk%Q+C#~OG$@ch}rfgE=t-0K#u?iP&& zOR+zO4E__H{Ls60G%L?@4g^2|9>@cU$nzZ%St!pxnLXLbbCL33fAz5<#xGuMAs8)4 zo((Hk4`-3qcVu&$q+iK_8#)~Y$?@(C zY7zLm3b^&|9Jo;_CPlxKYk!jp_{mns%Dve(92}g?5;eOEzZ#RigA2Y#F(ADkVgmOM z;sm=MV<`*!r6S&f@F6HSfV|UV@WAGulNqG32DGjt zIKjaaC&0U-k&EgA^Q+9gDo-?+8uuHC8*XN_Rbt{l6g--Rh~(X32;wY3<6cFr+ws{ z!#Rf__Fa1?PLQ138WWwvu4Rp=dV1TTp0k|&LJ3(zY}+Qe^zIIVztf-;rA^E6OUpKalNCNTW@WwgZb-S(YHHjKA$SE zw?_lN6uUN|x66lAQwomrgQGiHsDP$T@4zXkowNbnOm8qj)H^V}gIR97-VkmC1Zdwu zvjwbj+?=xm=VVVuRl(j4QzW#E$^%VxZm0DRbU>AQ1cF_#-!CR0@kvGbf_8TYo!NK^TckPKP@?mH4_?5C$bWtDh~D@u1)M_ zwGCH#oD#p!!O@VaBR=SjaA^4?cRqqP^`?ieH3$3{h1lGo7vaC{5#~vUf#Ln*l}nbL zH)0A7KpSx?jv*Rh8s?v~D(9kw=bbwOhb`e)-HV6g2;z%JEL({anpUhB!GU3`tfPL0 z;hpA7){NlueOBhIJa-ry{0HedD=q=c3vl2Q&e{Ecu*8cmyZC>lv=z%1jX3X|bK2BX z9dk6&sxA$;eAc;YBlslv5qMthf@Sy?bNFOF*uWxVk#kWZWS$jc)Pf`Zrun-*LoUu`(_?$;Mgf{tjM`hr|Ja1f%8gDU;VOqT4A`+Fi4sPW$_;A=+ zo0CG#vm*I)IK`H44J2nyoPW)!d>$vO`ygS@IMqB7_@Lve&BJ96bC4p+QHoln4z@JU zlx=kYB+g33k&v@zPMVvZr4HpyoMhMb#I{Kz50Yt;I*6{-xo(rx8Fa0q#;CKb*Kqd9 zlV)el%$PbYYxbmBC*n|1K1w%nJfIwsr_RQ0bxPhPIEeTnbpUg2&c)04&^qRoIcfIX zEc0x`tP`fso-_9#`PA9bmI}l|NmfhKsuQ8xR&)Bn)tr8CHPxZI2W1_dblR+H7OTlu zw47UQolbsGW_3s(4-)gVyw>M*ax*0#ot)5_d8~VKcQTKZ;Zyxk#PpeyPMkLR)VXsr zW@XKpi&Jj-kk2`DrcF(ZkgUWJegBu91I$PI!XS`3_%V4>;KSV!+sdZS!ELJ!gFpJ1 zqg!>(IcLnAIc@Ij=~E`DQ%qGyo5`nS9@J=~N4K20*y>n#X)JZlchXt0R%dLPO;}3n zR3A0=R9$eOV$O<7an!I{8TjC4Yl>-eCS_ZR)Jet3-J#84yxcDiKF_dG0!7pPO~+%r=J%tNa(Avv9?^l+1mtfDghz}A4yF;9mIp&~Za60W69P@riaydZNJm0caF|7}1$EFd(Y1w&8 zarFEpi*nVBr#jE{xzlFO;UU*b(dY0%Q3qGpJZzRFQF-S~n=x$)A5YzKye1oAG7pe# zIh@#RwU)I>m6Y6+R?X&|IyrM5j{BW84d=zgo&T4y^cWA?$Cn{+yv z1ua{gm4g$V)tRoycktvh<)mp-PQgLgvr(r>JPRom@Nvt~joGf&ys3d(sC&qzVub1Rpbiu-wc9=eEDrV2Q zhw3dSPL}ERV2Kmm;?E9#h6$^4`TTk%Z7UU9+EO#WwQE?lblEw}SDp()c8BZ-b51+) z&NrgfNB;7Zn&`Pn;!+(F`QRq7<{4|VBPRj#%-lun%~Q-Lsok3T7K1sR zyZ#|WoM)~nYEemSd}r}yTWu>2o?ui(xHVLFX% z_$hFlqz?pY_?|jh!g!_uVSGLZWY?IElZgDo~E7=`J+b7SD(mn|A=zEC}<6Eh9EdrdSnoh?!EwC-0Q4{dSwLH`dh9O1^~DhyK=K z<>6HM+HHLy;p($3S#)302k@`_KPl@k=d+Z$F8F$MW`Bn=f?klT&XeO18=Hv0i zwrf=wKWpJmjk0~+UJxu)xI1HS+=Q0!FhL$qdLN>&;55NGg7XBI2rd`oal!en6ue3B zHo zeTaUOFu#_~{P6CqLa$&@u(RM1f_(%B3Jw=kXJ3NP@e&RTo*+0waJJw)!LtPy3!X2S zD|o5kTEVLY*9&eCyj}2K!9u~u1)mmtPVi;HPXzZ0vVAeuM>oNNf)fQ73+4$vCRiqD z2>NixmHD(693(hG@MyuYf|CSK6r3qINAL{6Y{5$e`S)Hf=Mljo!Pf;p68uVVk6@Kx z3YJFBkM~v;juD(7I92du!KVe^75rFGojnOY{Ie?a`$;e&*dT~^_*J@B@Cd=df@1`y z3C&+Ecl+_XM+0$qk_sNJ<2@_ciXxA;{=tBdW7dl_zb};!E*(d3tlL= zTJUzkhZr&cD_i&A_W_5o4(yV2eiV-9dA!4`%J0mG$vs`d{74@^2sc^68H`vT&X@3N zMywxeC42)T))jRICd#{y!>H>f#{PI#UFbd%L^mOwpFRAq*f?jq$YPnXsifElFKx=6;_Tm+W{-OWf#&qMm8x)cAWp% zi1b3sV6@nj=3hwr1cOLx7{8k{GynD9zorCyf zek+pXW4SDT=Kj5Z+ zm;tSNd22uN;&E!;lUvTBn+8vExxdY9(I0uzz(haER%GTi~_WxbV%G|LM+qsJZ_YH@#RXY{CJjv1rK|J=^#JEyZGbXYs1 z{HX~{Stfo*i$ltAplM9Z%mDLCY|{{<6t=0rHLB}Qdki^i6AanrO)J+7BXMj$49-PO zaVPGYV^zNKO`%4p^)OwOTXEpbl(j6iP)+ z>XL|lZ#51;j2X5OrPcgi6Gd@&^$}(-ljzCegxXu2M_L|sM%nxrLL_g;|K>a=C(0Sa)Ng;ZzB&?TqrI1;>3eS?)vG8C5M)$E;xTl=}w6u^d{WRhMtE zGm4f?=p9BHS%oY&$dyo-XizrW88wH{{+QDVBfofdw+?njYfy@ECsxV27hdkx7m#jeixVE@ozR;wr+?wG{R~o z9*0HiDQlOp#s(xp1E^k2+-Z+C5;`s#&c2`R=pBgH#jAN*@UbyVIDWO%oMN~q7|mdA zz`CQESPwI%u%O8UAl}5*2r)+>UlZ0>r3Fj~_-1+NzGU7GZ0So$HAN9-&twU>!YnZ? zte6#69iMD=Om-;Ki76=Rw&@YW&XXVB^ur|%0SWfHnyEJKj5lg5rki^NG~tZG!Y52P zRmV*`qm8h32<|AtX^+=ZZHyXgjiy*rGj36^(s+2=n$Xy=*anQXL+*lOm+M(?wxN;UNoO!#pm((tMQQ!j>v|rTe$;lXB132pc`XC#tf-m z)lJaUxOyb~@U&fDlG4zk+ztmhWndXyNADJmI~{D1wY8nmy=^1{1D=J{Or-3C@?wH+ zm2fre14DM)G^*V&7}4Nt;gz#;281f34g6|njcHe0Wk74HuBYsbVlcqYDEPz9s4_hs z;jW4ig1qJ$@ZYmD%46nA$OOtG)#N zVgO=FPr(2{pTx*+R!#pWC5T8#-)DGuU)BFh>+Xq(fyL*GvNOtSCYqb~2Q99KnW_jyjWMVe6gOrBUfY}T z7LHSM@;mZSPZI$3=CvD(2doA+@s5$#J>DhhytRVCRBTGPCt_|@>miJTa*@i;C>uHE zvQdn(N{Xr}5nJSe?*I>4iB_|@U5#QS)M{=gw$d=!FEM7mBz+2_ww65qe>C9bZTEG!CN+_tC<3CrmEj zzJc2fz87e@cG!iabsFq00t*C-C4IMqZF)9r-{M79w&Mvr5%xYgyd3cyzEKB%jHx>r zVOR1|9dfwvk}e~*?4=U^SvSjZ+j3JOB*JUqJ^m+CYn~wM!>>=1?HRw@$A?l^k2e1pu^gr8keO_QE zhe>~&BdGMb#8IT^{?1{@@t&hZh4(q2ckuT*g9-;b^He#rocT)5%bj`t0McJ^29^GP zaF)0{DA(nxQ2H2x5zg&0(Pip+i3(HfuP%_FT{hy2B7Pe*Zgr)*?7HT@69_%gW>-4f zv!qX5&=11DBJ9Te(7~Op(ucakb_c@K++mK7UEnt9^WCsBi}(U}uFc_($4ZzUe0C#V z2mbCZO7Xcg>gWMIaG0kMujj*FDTlpUYz2_{-R`Nh+mZgT2l63(E5Z)c^Ism*KI>jj zk+P?1^Oh<5k%PU3O3o=>#KT_9a<;pPe0kn5+HpLYwgT~bO7*QBOb2SVFzbXBkPalOU{#s)gM=poxCfK^tz;{09$Ej`s#%_p*7zLh#XrNq z;kV@J_v4nwUU5g7g8Uc?Oo@0upp@VeZ|G9G#x=QwPWKK8k>|ao3t%1b&64xTJ0*WG zP1lM}gh9c}pQQ&s$20;%nf8(e_+9+<5ZQjn3u?Q2uE|?YJ*({pI+SKR%fB3=7Lsve z$9D2wShc{D_hL%;^OW$5p1k>5l{a@eRr|94>L{6MtC;C1`KvFx3J(|*x$l3$*Wg}z z2NmM=LFC7c$5hhy$9HLIxZhX_qZL(tTV6&??=u*d5Bax+7dYBcMBZ!)1Y!J^hiyg8f+hv{<=lpa&I}l0%v;# z$x%W2k1))Wv;fp{ThLs)qu@B5>;(o}l>3ZLSAe(t2|FSJ(ss=~i z!5S0Gbbrw|lorC#AaG)HXK-(dw_<+UKiFVLy|+XfBoo zyfay7K4;lhx-S^GYG~nzprb61+an*g!9o)=yH-F8)e{#Es&JGxhg^}jox3~jyqkR2 ze`;&?8sC&q@J7gyyXcg%BjOLyEWHr*A-!;><<;^sf@NbkE=Z^BbbX&`L;dYj+Xi|u~br`>8+pX?7)O^`m}rPYCmoG zIjhK7h@6~D4@38_|DKINPC70-^1*R8O7P{qk004XEAc))rDalNf27E{t6j(Hlw6{h zi;d>c)^>x-wvw%KD_(*xhH;vg`W#ukmFWGg?K&NR1*2>l8+o3xZW~h(0CRf{A*3=@vC-tax=)Zp zh-3*4n+|G_;l4jQP1fyWb_Nh(N#yQVfx|!{Q6N3*wqt7)4T!fUf55o@r9OS$PmbGa zIXil3pDfirXd?4}mVfpuj`HWWl56``Iyz@ z+8hjKrRXIzc1>}RJT-3=!tUHwaH@Ina(h|Li~bpzH80|pdd-V49gGVU_c9n2XVTW! zs!@Sw@bTww-Ky83GC5yug_R_f@)c^hg&d7XZOlfc9aXcCkHG!B!tMtV zZ4B}R@-tzY3EE=hD)eW&3qmQG?xMih+%$}b3C8DZyM_ zNNKs06{H`%MV>Msy@S>9GJn=`wS{W&r2umCnOXSfrA|rU9YSA^j-&hW5pk5zvyfAUtDrD z9#}xh>EzDi)qsr|Uk^)TC;?q97fTlrCg;aXi!OH-El>KtytIh#G&sWOpy|jni z{{(R8f@qjm-*5Z9%~eG$0SJAjmSokg+_o?QTl{5J;MVa~XOX??a)i$!TUFqeVTk_; zpD*a=j(Zl6b8CG6Z_MDAz7OlgzmQg%eQ!How%@4nWy5e{%LTc11s)y;i@16<+FD`Y z;qlda@sH4-UYW9JY@rifEJ^w+qM`khpAKZ}m3v@(H%!%l;Q)X5YE&-}mVfeR(nXK} zriU^4w!ZYK_BSX^giVEneT92`MS)XFXn%|XZ+=62^aHT&zH?8)?Ja-q!Jh-44Q=lG z<4=?k^gI~0Rnp)0V777pv&CEZQ~6tgJ>5%wqBQ8bN(2LhSc`#&C*(nEm8RD0m41Xd zesB3ZfdieZe`6+ut1!oNqgbDxzTUrZFKTA~ zc_MFJ&}ZQl*eS(tft{z*`n)tFUg%)UmE}fyODk+@rFeA`4&-st+$3LUA zo%Y}H&=3Xk(355b|IsU~{hm+mDy*`F^u9lPElmtDZ*;X?TD7Buo`6N^nZ3|GF^9Tw zTgp*Jj-lCf1a20t!^Tms;W^?y-m+lFvJp49itRfcCH&_s$;fsqpQ8lH#V;hgPl74A zo_zju7uxFGMW#O`?~{=4XYWzB++66~YRkKJvF+l#Yn_;6`^5c)#I8L)wzUS)84;{6 zu$hQ!su8<(Bc*;7B3$z@6}4P1FV`pLVei6*eItz#BO5!9K~FHFE#=rzo$~YEK7Fp- zP=fh)MM|`;UAuLqC8gL8TYeR9(wOw+bp^;~G=Ru}OkW8V{w)WD1Fd5#f=K}}`}U!;Gqe z`ivO1>@fOS9LFq)UnnwSo9hFy;O1%=|GNjIu3TJ3rB?RC&&sKlrI~35QY*8n*5##E zy6cNWsg-(jX)sWsMK_1FpuH&zQ;M(7-xSm~m+9rv(pZSx5%f!R-5@U1aS~tG)kBUc z<+0J}O5+tdMsu-I*Tcwl8PB?mkZ$Cfely;ru}vbq9ib(r?{rVdk$cssi zHm7H?CVQ1c)@Ree8(}uG2Fo%Vse}_STb*Ttw$7k#kyvhlE%NOH@!~)oc5=qLT;9?y zgJqaa|6l>JrHAEDdfbTDkgJ~U?yjq7j(qb>JiSS2{SMLkVA3ONVBFJk<>=)ubozBD z2+Y7|cqM_rmI^C{uYk&iPvs_%*`bR{q;KTHR130)o%2&%22;BYK`^H)hU9a8@AH+& z>3gVZH#4c+{jP+-iPN}HP;$ZT9t1bMfWcgpD+a029GlNjiyxmOMsruA?g+NDnyr-^ zI9-7@Vv@i$3fqnAON*Hh6Gj+OrQkIY4d*qmwJ?l4woRJ85m~wGR5zk=#zT^-oJWeA zFsC%bwA(6mD)G^5Z@M6u6EEmu#0v`W!3Zpf;4=)LU@1PnII4ah%AgbYk{S!+Y8Vf} zi`^=FjaVkUhVd+4l%ZDTjfE`&rd8RFVGgu8p1wIg(Wp-~>LIFOY-DTB=m3AI0k-~%_8QFwUrm21$26!^bVwV%w>Fc* z2&?~0n~_PrD2@%lCxt&~3~wfgY!YcD`Z-gk`OlfWnJmdNG&K3amMD^q3lEEV>y4Mz zr*Wb6_q}R-_iDO|O(KBNrVyGBhDDc{WY1t1wIfWnXAJC5so=*=M0L zFk^ReZs|^Z!5e1OXEf7@X4>35!btZSnXdRc96VWGLKBRgcycT{St~9?#`%#VH)mv* zQK5kJFc9it=ZGnwh?=6%k+C7bje%IC5a4T8X5Z~bNk$aG@|c4yk*?#VVke~;Q4EWG z9JBN3I(+els^IGEYq&FA4{D5NRYdBWXx-sP^b=!Iq`Z-a&T34}N5kj4FhMk|Pc8h! z$SW^z1WhmVXW-NlEAIgI4CnDV92R@wgJ1poICOxMaeNwI%?K-*v#1sOgo|Kn>hC!=5LC#`Y8wiXK z?`I}S3j#A)gbOAs&W(Az0#}c@fDhxLg+|B3k8eU~X4ug)!rF$N-BF8(@dJ{1JY}O) zLyA;x3X}%51xED`SZLDof%iY+R5^cZ~*&WuQkr+WYaB7;u6O}-NyffgnR>y}1BQ}8PGQlIZQ8W?Lc1}a*$9M{YoTw+Macx8LiQ!wDUb=7KA%+bby=!Oj&*8g1J!1t$%8jRnf zzwIw=FbYcwSC6nl4JpV{)DYc(0snK$E(4KH)swnLD&QZajF2A>p6R%WfaO!E2HOf% zei>nwFXv8Z^TAs)i_z4}~ks$pd0vnC1*WA0S2`%|YD5ygWqj{82o z1HcL~@@$c&IepJGc9&x@C2jMk*^W2jFW{lyu4(=8I=m0 zUjmMWaqiWtFM(X_Y8tq>sTt)raj3df?ZFMVal& zJdY7PRL~8X;10_}5t*0%7*24Gk9qvyRoEbEMFrcJ;<^;i4DA1X$Bsxz!FJq4Ll})T z)`3kJoaYTQBMlQ&u{1h_2bbfqklm;;%2JHVjM~&Ms_$qRQ9o&1(?lbCbMwS_D5H7A zu3Il@O8vEJdV|NPEU4D7I^hVTr_gci>vPGs%`m=y_cdj&3|-#M-qh$IcfsQ*k0Fsg*)Zb~7(^S$}eVFiKn zA|>Gtwph-#Xn*mT1b=R^oL@USl*RHbUa0VY+G07|W&CegEYD$C#bPd+R;r=axzy2bM0%HmA6?_u`2Ngd`GcVR zPc4?S5#`V!ES9f8xree??m%m`wphLcwfJALSk8wGv{)>^3IhFq-(oqxE!xIn`7*Tb zAuN{9hjvI~W51d<4p&{9i)(9(<)@*syc)kT`NtN^i$U@4TP!!2+Ok-_0YxM%mJi~< zpIa=yj%S|#VTa*@qnT>E6P{08?vSuFpOd!HwcqH>CRbIm+ZY&%cXya>i;_}md_otSblcJdA5n}D2DjPES8U1EFW$Fbj)J8 z1!xhTTQ+xo*)enGhi6^2tY+hh?6(_MTr+FwM~SZ_zIH|R+F2`W<{TsOHPuTu%mVb| z#LJhiTTa4;%Qs$i8FcBoWtX1_EXdWz&RTlpRW(PhU$N}Syo#&BvntkyXMvA!;;OY9 z=Ux+@wQ}XgwadgL{Va+KC3~e9FV2r|T)PS5ud_BR#c1q$ZAx~`VtH;)8?#uxJdDX# zHD<9~tdS2|s=}V`K3OrA3qsB?@tA4z+@d;p%(Qv*|}_&1vQbJVzDx&Jcu%H_s1^PkvW`P?yk<=3KFVz>7Oo8Dqm zzQU=~zhTpRYJ2sWCX$fC!5@bLuYBVwfa(5^+bh4W;_qv({44MabEi0n58v$7 z=Fa51PpkOIvyOw0xHWvN?=tJ?pjotKMCA)D5i42!G_QZchaVIwq1W-r=O^)hW_#t^ z8He;+)nZInCSE+Zr-XQ4Trm-NE36&Bq1$}-_Y_=x;u9f;05`Q+R!i?rFGTy&71JYnXS zI{~?jZm;~i%EN>9%1NA4R#ukhA2Xk{xkn#2cVF$5&#%(m+N-^C8ISJc-@{&c zzVLLjImzk>f-X>=l!Uvx909kh&k->E4!*WE=!&#W$HAye4d`$hYkQcl!mJ}6KUKo< z!xL?QSjT6az+O3Av9#)SiA7iWzJAVGKXu8)uwC1u#11LWuLi_kIsCHm z!F()~WM#Sso%MT69rcQ`3^kuC;@@X`M>SQF_(eDgzm` zR}Q$rcv3NADgxB3ute)fXT*{yDR~`L9XZxEHM&)&1hZ;?tTiKZG1;ttkZ2d!HEbPF znAO)$YaP2f(lpnhoGJR1=R97-KI8&+eTM_PulhHX(j_r5o5Eb@z`$^O<#a$VJt>3v zbW;}@1b&0^M`9DBW{F+fax-J@I!*6%kZl@=_s*H#naYvsd8Df}{n z_R6KY-cqDXIeA&rBmGS?od(T#db;~$);hFUoas)q82em^#i1}9-IKzuaVDwK$(+4% z+d{17E}g`7D@~^`u4}Cq-ETNpja$X|BCa_4XXWac%!#B7Iq9<2=^kOl>X21OcXE!r zVJeSFaLK|tpte_T4-)&&Vy`@v91y#$x>FoL%#D~w@728CPJ6xBaKK)9kC|~Ku#fEQ z&xoCDmMhvOeMfOH*Z#IHF5ZaUM2}p=Dta~C+4jnvD&@$U*oM}2!|5n?Zkbt%BU{;s zw7_M~EJp|{yO{xP5I19Kpsh=&p;iVsF)#;KBr!9K&Cb3I8q9 z%K=2U2A$S67>d&qFY`v@!d1{7h{+aD*6ws4R<%)2F$Qlrt%C%aS*NUO44h-|92^B* z1mbU%aX$em&&+4jm^*h34jvp54T zchc#1dffSf2?j*f#uv!#97yO}I&+FFyj3{BssLjE-(S5G)&VLr=6 zg{__QLF*FoWlU`8LH1U?0J2HhZ1=HC_W2}juskwZZ#LV9y>c)hutKDrHDe5EdM=0qXa^HKBnOcax~~&B4)lhi zj|)FLf&+WyNvtz_xuc<9h-UzTvWS6vN@K5lAj>>xd*$4cw7qh+u$;Z}z6=|IK6TCB&|@mC zdoD7tZyq!kn+EFSGvS5_jWgSzu^-X`{Tr?dn$GL zGdxvA0pfKYtNeYQ7A?=WJYn75{$AqrW4X6X$8Yl@ciMjpd*MRg_J(vjlYI$)0R9!e z7VJx7NWoX5<@2;Jq|<%=GA)mz{noski@k4=^Nl*LGF!wxxW{n(#E;!>?3Mq*U*&T< z4F4~o$Vt6~g*+cnGRQ{94=ZT!``K?lS3Z068FqfgS$4_N7+3bX}_e1^I`KzZncfp(vt_MVk^z{ofXbvv2)g)MG3`KK4s zKk}Cswz;wQt!^yDUOVaEDQxrlK>+$~VMAdN`N=};)k6;~B0XSc&MvCd^)4^M&N=#c zb5WVgfqvd;$A4KA_W97mCyLtL9=Gy5S5)N!%h>sHkqQUoCal{Z?Ng}Hl15yrQc%HH-ysOdErQ5A@%QtN`HdWt$x-{C!cZbm~QbudPXQ% z4BuemUy2%@D6IQMLDjfG-Cs)lwxe1hzJt5qqsF#3#3#(h6TSvb-a=bvB`Um zU_ruA?a>MSpIW=k-6|FjbuFs7@q~xckXIq@j>Bxihl)f2>5}v%U*&1jlj#Q}Yv0(Qj{(X~Bg({8&8l2c54`NQ! zl`y)vc)Y>C9;3^Z@U;Z1KBd%`)lJ|3wLcp<=j8`Z`En(8c9g4U03C44rAN>h7 zZLPTB?44Hi>QS`oGzXmXFgDOLJHq%Q%GEBw7dk|5tdP?VRjT13b#}H!Rs6iZp=g_m z&gI3^n-yVIcz35#zblQXV9kpdICrHk=ZUcOO%+cq_`Uk^@PA$m$Zr1p4J{ZIAi@Y|GMCmTFgT6Nz7ajCGVHK;CmH2PtS*x>#8V9f3;?Jn^XFm}sY>`IEuDIB|%a#52OWVrpFfhDRIXgZ53tv+1 z*ju5kn0Wd2f(37VOWPU_Y{LLlgg=#Vb>p3hubr0a&_ir8Z$arETeh~PxJp&4?cpO^ zFiEpRy>!aiZPBnQS<{q zLeZ0X^U5SFE*F;@Y4AA&a>+m#n_8X9+4O+tl^fNRDl%{~ky|#bm5EF+LoI+rhs6%9 z*wWW7P{(`t27+tiFGQ3&@$S(6e^JI?{ky;ZyM}_gM^9~P`BU+PPF2{l`UFp#^0pj* zmL^A?;FQEOi$jl|y5+Us6x8{5-`3h-uz1D6#61)nro4eo~I@CB^?l zJN5`S&zoO+4HH|Vysb#B^{ZF(6zou{tfY#TD#AHWM|FlFMUYG?0{gqw<^`v<*1*l% zg{NK+@7sf(M9EliT62vqO!K{)7c4kg3do0e%jS9W!nrtkr;s)e%1{7vW|ni%QP+ZBS~~Ep zJQ7w92Y*&ybwaj|S{0R>m8+MLmDi}v0sydib_?D+ERXtawPj=!yo$$8fH$oXPXc@Y zELebyO_@D9&9j^%TaPX@?|i9IRcyJnw5;e0JKMhHX}{rCV{iYL6{&l zZonL>Z)Y0z^#cUnpkJH)T@1ePRR%xpKaoQDZdg}~IPOQ1VluMzt5*&vk!7?>q*u^Z z5ta?i@~sprS4#3^>5Wkfb|f0BlLF(#Uw=AG$ZfgEK1N?48GOVh{MP5+vvU!ZA6FHO6=xErRT#VV<=^}G+v=?NTOqWbOm^251sn^>}9C*-{qf3w}Jd4zKR=GFI`! z(q2?=d%N|<%6a7IEU8lE9m?0n{(JKqs;GvY>5XqbMol%$1xfzD~uayWK^x(k(RzBu$h4YzSRG2cy9|9epa$ zrfS2rVW@QcTdK5Dm6oY3dfVG6U3Pc9K_#&j$*f249QuVDg{)u&lDuuff-^~V(zLOQ zbk0Jxg;uH~)Tv=H{CUBGV0vj&f#%&|vdTMuP z$&C{`D?+Z$lA04cU9smnAEqmVpUvsA=4a08dMu=VN7@bYk#O@f7k52Gp1M9$DO$QPK^En!Blj=6p<8WES48k4 z1fB$K(tLw9MYRhZx?vs5jSeZ^7{-?074RsmzU)_*i zRMoVhwimw96$##{(^Bzey~@+;@B27rVdIaB+LecYzkKaB=lz+wp}~^;@a9yw`8QX! zJ;vpL!FKcM8TPqHJ#0HwuuYrp=6*zIg!d!QqEE*fshP)pO3TB>cJ=U-r`02^RjT>L zSJk8AULwD|=3!2f99!r^Tax?5{v1dxeD{qrJ0GLtD)?Ep#jtwvVJ@4h@SBYS05d%D z&=xxW(@Xc-aXlMbH`Lc4mRb%{qe~`WE;Er}vH4e7G{;V@6- zk){osW%_FMJPJQOvoghcuJxo3&i+H2&&quIu~1+eLk=`ro;$W{Lf_Gi)fC$O)sS&T zybS9pYnE4Ec0b#$p4UC6+1+!l+WOiPEXDlKlNg8lF=C8^EIS4XU7VEyLv6 zcs<)&uu7HBL>r!Xh@HTsnc@}@bGXA6UC^dltDK3FveIvHdHzrDgB`($yZzb14ehG9 zT3vT1PjQWg8BuP~eA`t;nfFzHTWLi7WN@B4rz_Im$QHM2Yc(UUb*t^>V9ctdwn~rfFkMGiX}^SxBePI zngd6DVxt@Dp;)FZA&M&%FK&u))vOUxMRdZ&d+0**8s_31>GhY?e#__?K;#E&K$M>PoOU?bw zs*(Z23~lYGZifVWo9ZCGWNQ_~lWwZx$<&vsZKG0AUy1a-zQb$Yrj9Uccqrd(4xpc{ zSXn2-u^^0}a|LFj1Pjd;4!LJzX67mjPrz)Cn&yu%VSFGKcPq@hoTx~VS?0nRY_S=s zFjF&{&2BAyv(pa(tr>4nm7g;I>drAkuQo-9z&7MOS?JatZFT&hjCm`2v?KPwEU~s< z(SOpfo7t$$CD?t=Mz+3IPoven_Z|UHbNw5#fG{hJEX?O>1@OMwY$(d76=qF9M5@$0 z@eu1aA$mZg6B-a}qq8AQpJjAZj0h9C_Rbq$Iqc4_@le9>@?G*Lt@nxv)a}1ho<|;e zQunuRHTv9bL1n_2WW*Bni4wGy~r zh?}R3Tg~69xLQQ=>oFIYQ&*Lg8L&(mJ2_4`mlc8opt!87bBqY%`vn$%j)?=1AsoW};M~Uev2AM=0G7pm|!1pXc znkr%~p?)2TJuhilypB??y%n!F+f0oNIx*0E1`1sM*V$&9hepHdu!pOZt4ygmCGE;H zfLEI=Y4@9WO?Yq9oe~(>-Ww8P>EXG=Qzs>h+mu5;LR)_hcTH_eDx zpfoyBot18_ZepbyC&I#YTb6&H7IwIDW~m(YDrf7@eM$%`ZC-k$*G`SQ zrJ7QIpo}gkwRF{-Cr3@gu#ZD@!CR;6$xBAotTmo;nPTM>#f1kE&z;{epS-h9_tZR5 zlTKq?dEYqN$SXD&Df|-^SIc0(ZjUmiD}{xjIOBrlLY&Rn_y9a=lObmetSqz9|I=w^ zWrZ0A_yH^k)8A??Gn36G@Anp)z0=HdV=2G6%^Ba}DvPpN9cA8eg;wY@Vwu~8q3!+< zwgdG&YU0WW5m)?P4*c5)O+j_f$(9k?+VkT%@owdPz|D?an+>57oGle*L!sHOntG#V zm4MZF%sAJb3dDJmoOX`b&c#Nv>>cj=%_^@YFk*}Btymd)WssuXNo^J_H0yML#U0iG zKvp!ZPwUwfkP6O9Ifz<{Mer{0(PeX1F|)mtjYHmfvB7o8yS#1aQwyq^8oBrYht!=?N$&O_Ux=4{A@ALPfYu2f`on6DA=vLe4LyOvT=Ttk#?y1*46|s z6gt##rC+Jj0aZ$K`mQMfXF*4qPAU0)f4?ey`;kYew?o86zcOJ;;(SlD>3=~&ano#s zkek`Q{pXMm=9+YIHhtR}FNY*F)s&TN#7tR*vLg`P3ZbAe#r&0&8Re>R?VX@S%01%2 z1xE_s?922{T;4rGxI4rX75Q&Xn>c-OC0rSBXjqF-pWdjYoid36Pa?#Kvp1bt=7{wx zcPzV~sJ66$7RUx9>%P`BzXNeR{CO#_T>pU=@=(GNdpdqXhY?E#+nc7xl4@(b7hm0q zu296ITR%N6h#%Ex56`Dvtp`JP7j(MJUcY<;%k1#Iz?=Nbgs*nh<^Yp`8hyRb_x*Zv z;Gzce9=7T2#mRbl(;*Qq-R}{hvu4744Xldk#RL)Wz1z3{z7mjT_MST|^n_lO;kHxJ z%flTPp)Ph+M8&0u-A-;0xN2;%>HxmY4CNRpg)$=NEUGNC{4Eb{Wpr4li_ zG(N@*J&c?uT_EQb9!qxb4(C#Z7U`rNI^UWPKoN%BI^sGnJ4KUU{jna}Kg(PmH?s?w zo+Hf%n@IW75^M8)M3>T@B6b(3)xgU!*|LBh zW2R9B)!c|D`;5H5Rn8VXeSvW;iT~_8axx_>?qaGUH`6?SUYN+&%+x2q;b<~{+h1&c z$xNSlmqcEhArU!}iOBh^BS)Vnk%;s|R(Y+Qiu9BQaZTbG^+`083$@9-HB&647i*8w zU;s5LN)m5$@loNJknmRVEo=_6)4}Y{V3+b)8txbEy_h`%_gyK6OQj3TUY%MrE}agP zwNEVyrFjO6XS4CN+3`tVO=C1|c768n+kah~Hk*I{$Ro|ar(BpxQ)#o6O|^CVi0igP zy3Gz3+a|=zvn*sX?bK)_57Xoa4bm+5V?x-pM1Uq6jq4jfLL6bK7PJq5ptboCZ;@mu zV!##Y)yx9?36Z0hEO7{v&TiSMO65}32|9ym&Ye+$|A8Q>`oAPVX=QMoxnz#C?>$H68{;Gm7C3Nu|G*ZAUBga?XpjVTvhA>6c$w}H1C*yJrk=OBJfRo2!2%) zx%66tU^G=$lKTar7wc(x!`Rd9n}d(CGEiUT;R}T`XhoMwX!6cwW>Ei zAUzgmx3YK6)0NG+Ulm#m`L1j(;I%j}Q^g;gbBIf@?sFTW&Q?sMSKmndCPS-4XDCOURX!mmCDs({ccC8$4}ZxG2HC9%}7<`0#=6JCs<&t zfu;=TKirDA{}p62LyEZ~*3=D^BItB*%(9jlxox2VS*I<2a-D^+_{ufr_; zMNh1%v@=zE>F5z%jNKPk=@rnE2D|%VOl=+DWkUX6`kxN0wjs!Qc$l0zp|Qvo4Lc8Ni~$SJLcg`&fxy zkV#$aeS`N&vHrs~TBFUU6Gqp~P(W@Xr5%OlR~9T-Xda~bn)26NTtHAVq114Il+}`y#&euA`D!WUa?7t)EM%361HPz}yiN*ueeOqS#q0CFMB*fu zTMW~AUEWo0ihnSG6uw%koHHkW0zRG>@SJ}eK*}ZbV5aAje-?>+pRnhW!u51mIYbhk z=)~KIxEx(bZV({lizIng6unJ>LdP(GlshD6RnenTztPty94^-}<2#NWwBWg-@Lm%4 zbL<@;Wj|rDcG3ZmDe}v3<*6=oQZ=k5?mIxr4rb0f^?+p%m*Y1u@lHFimWa=>UlEa# znRgQ@bnKR5VI2uMJ}f{=Cq4CjGAK$~==g^Nq&$g!`AeN!A)e>)yoPVz0a8xV70$)? z8Q0?bji2Ke7!AlbXjlL#vyjOICEc3l5K*}*Jrod9?;}G|gRCS+7R}au% zne{Cieo80SHB>mZkBf%{ehQ{ERK z<Q(p8GRSFyvrP+v%6gq|hq|BiMo>Q#7=9;2atCuU! z$GumQ7;-#IRnO^@_a`z@xo3)eCU{9Y!zsPCpoKhV2P^57@jn5O!cT9N=a-`ZqVRAM2LV!gL=BZs`42~A=nHD@3r<7+)VNPzDJ;Th7FJ+5-=v0N(Mhozy+@%Mc9s$a^F^-?-4E# z*}Ut1Ux1Wpbo6%5`vRnhaJP8g7a(N|({{fnA0TA|L-}of%6kB$yy6)NkaD4KBtXh4 z-yQ%d*ZcMXAmv_}w5L7AbjKwdr)#Zvde;{ZkshX;!6_Vs4%9FBvB2?xj|R?|a2yHF z{qqv2K+60vfRsEN(*LIbQufI{zUarYtCrTRAGDHx+Bu7( zi!WRpJ@uS1B$Y8FmE|ke0k!b)MN7h`&b=@^hNN=-MdzHeaPfI(oO<%vvSKPvK5udK zoRiO3B#~1qhHW+T=a0Uo&ZpA(3!|qkIs0rCjfy$=d2^BRpb_*H`7jqNui6mZaLon^ zQck17tXr|Zdd<}H{amM1)?YUdJ{Oaf?X>-`gwB(`-E>afM#_HwK^&6J1 z;~1&FCVIKzh&c{9h*+*#x@JxFGC5V2ty#K$eY9rj>UGhpm#*0eKp6~As~EXrE?9W# z;)?SIw-@`|ipt$Gy5ZUyWU3q4q}HrhxglyXC9h`n+Er={AjLY`N6ysAV*n}o8XTnFRo52grF?^K4xskyCT6`3FV*Y2wN72WdKJ-?N`XrJ6oRQmj?S~ARH^)bK z$1e0xz5pnczq5#QOtsSw;sv|J_vcl)P+qu;bMP`;*W=p`I)5U6OO^Bk?05;U(Iw7W z8E;cq==gy`r}HINJ3h;%b8Q;2=|Y>HZ_^8Hy3(ds+VonR-eA*PZ2D!Je#55s*z`V| zK4#Nao4#n%cWl~k(=mJ$Yu>Pdq~~u8AH|Zx7(R+6hcSEVwcKfarwc?!Q(eDe9NAs*tBb2)y?NXX|m6MmCP6Mn)c*T3rs z=kt^JKQlhc35-MfFXNCqV{RO85zZe+1DP_GoXg2y3gwq8w*^(N z+3vy-?cV*VA^FLdk8|x_IAR~Iu%T)mDWBOr!v z2VF6^1$oYG;eMzT-@3AlPh*4H`juCPgtR242Frt&B3KNsikWjaTvHg;b*HJ>F<1n{ zg?V9u0~t)n=r;KRX@3qM<=wnO?_~2<8g`C`vV0=Aq2_ZL1^bMTGNLaz1`fB=$MD>l z{+AtIH|Ffc^tDgzR2fJ{zV%0%N>5~u_o;x>B?8o}1Ro`p!E!m-`5ncK#c+q^E3L0t zbwDQL6a*5OcIK6NbC}*zn6JL}(OUe?c#7uY^1FScKjgeV#6IK-?Xw7*_xuW5e#j~^ z7W44QluGvZV~5_79LYdyV3~t#`awCTlOOw$DZVTb>7BHdrFlItzB;Y(QN$d1&hZ05 zLCe9xhzfQ@67=M1`{(`Hev~2QbbBp)lx}C%(J9jGQk~gdS#UYXAudc(03Hw!o)%wP z(7(r(Y`ANDl%e)%M!Ja=b?RpfF%~UOw=JTeuXMq37?zg++MB{ixX}(KRlVzgJfh42n49T-4K{$ZGX4GFqsRit z_5&-xmIYrRE8Mz2T9*p;qDv0F84u}_Ed_f}mS##s2Fx0U;V^s@mzx8IHhpYCsRFli zR~DlR8E2+Xye!J9d~OEbnek?N4Z4}()smbk4qp-pV0!x9tTPQRLb6YQ71+!GukvI% zRcBiDb(sC>{sF#>Eub=tO1b)(>`s+QrnCLY{-o;9B*9fdjSJI+DFIMaZzkoYg|3Xl z4FpZUFJtUXxs&NW)!&28W>WnO#^(jFt0U>@ji>s0x?~U2bLz~v9aL5n$-_s1KZ_ir z<2o=BAEiLK1s_FNn z!)1}GXp?h#D(mwOAStI)ciAo(8_^?@Wf#&rkp?YEGD6g9&}nUhp*R@H%9g@u;VS4- z#H0eTw^O}LIO-|jGnPvOh$10o7O`T<9Pk>AkD`mbMJDJU-HgN93_dJAia@l`HQ56O zP!PLI#NJe?K4cshSRLDC(xz-CE;Ottlj(OBxjcZRIKA=%fI$~3L<6%E11t#H$GMme z*0&a-l$2|$+Lg)n>J}uD@7||E-hF4VmJA~41XRt9i31Zz5UopskHQJxt3vD=8XqMy zAWLu`yCe@}f>Evp}b zvS_F+ffdU3XP5^KsKPDDDZjg86Xb%T?>D`uBIjYZ^2^m#u4)+$OVJ4Fl5?;4C<%E& z7s0b=^llCgfW%ay!wC4eN(Y#Iy*21me(qq?Au@)KG9-%+912t8Uk4whQm=WXDqYS( zgJ=JU$L%(}B`OjC&p|C!34cLIWgk#=Mc^Q?TKMe>cm^Lgs+e)HJN^ro#qV8LLnuVQSGczYiV98j6L+{UfE;?<4SM{?ddi9liPw5s3jENYdB87$ zzU`?hETsK;UR5OJH+mCVeqR93#0Q^Wc3;SWsPW)LsLKK^T0VCNstO8e z_nm;o;ZU;+E8TA9WpSY;=dTc#`FXGqIq>V$rwaKwFK5%Ug^hmjQ3_rZd=lj5DoP+v zLq&>^Kk?N%uGII6z{?^2$D&3zcpoZV6r!Ihb6l`p%VTY@MvuQP*x>RMXEXN&+x56# zBi#YNcrXzv_8V$mG3B9`6qgkUzb_W+_AotTDz5);j9}QInsLam_CH~?B^d35OB5~Hk zw{1FgKjwjQ-`vkiKWKkzUcRuu757eJ9ORczQiZ(RGrv5EeCi)O+2Z@T$?zrqB6uVP zAxHK|@JNE=Rpy66iWNE(@#BxN&B-D-8Y! z`Imr05+r@QP~x*^ShQh=RWC6^6%^7=<-u0D7MqsMwEFX{nJP4XyqP)a5aa=$Er-x9 z-_N8W&JTb0E=F(7wgjc8j-#H*?Jgw)d2jpWF3%@kx=+b-s{tw>aCC`i#1Sn^B#& zQJWLVI8R!C!sp7km;Z)e&xL|z%8?+lRqSA#eB6H>^IDnuqEslT@iwyMU&}{(mzZyb zJ?UR=X$Wq+R)vb|$SCT;bH+23yghHtMkx0wF2dKkyS(aJZ%64{zieuB-fupa$Hn2S-q%gS0u_K zs(zP~TW@PkU|?lybHo?hRrWoa!1eUJ{`xxgg1a-&Qe0CWiH55~wV-fB!{w3Unm~)Y zQ@v1LR=Ca60ZPYP0FB&-vH$y^ZyCLwj>2u_W$H}j*>HE`kzmKvrox}S@>b<)}4Ut@$|GZ3~@i)aR_)v-2I&j_M3u zL>Jc8;^r}*=~B@$_o$xhu}qCO^Yzw-!?3GGLtc4j*2Jfx4!O7RmKxE|me13C`ZsMl z4XsL6<2g2M+RA_mUuD9$hP&lj4IqkgT_m?rk37hfFOMi+SM!s%q||jHx0QC#<6sMI_z86xulxsNJ0SkNwraDpZ_}o9JtA3xiNSU{B3!o8Zt*sIpf8h9 zUc;O*ZvqdjE@8Ny^wmv`H0JMMTD+a!zHy&w!9Gtm8w9> zbyJ&KV?GZoM5aywjF48*N|@4au%)(4l_X03JfXG26*qsFP>wkT30es@;%zPS|KL`! z!~Qnbzi&@FL!@CC0<9a2DdVk@wtIqQQv4KUT;Ju~x--=LGhT1}8%AehKSgX!f28L( ziZ(A?vgBN0VTi$N(QXho=%$L_E}H_CoLhHbx2emq<*jh@Zv~8q>Y_#IP0fvmqNT+B z^iD7hw57wR=#i+XQAUoz$0M)Hq7l4FPi0`J+^O>qzW&$zaF5a?@Bu{5;81j<5y;K!dGS2}lp;uv5Yuq^A1l6N@T`Ktaf&~?g zTDhA-f1sqJKWdt9N8J5OJ`syBCL@WtcU9aNJ$Ky4xrY5YbYE(&KK1{w5%u|CZeJZ5>cO462T3y-ylAAQ6!m> zAa70yp4lTpE$S5cmbQs}tG^igp_#B{^(@~ukD~n zrY!pT#UgCD4S9A?)FRE#?n;3uSX0>QOO4$No0Kq1sI=+o1MyB8FS#?cn(>i5v3Hm@@bs4hW zpGo(1yhl*9(4UZF?GNe|1YGAb?`a0j;jzrWF#wvZE|WvNutnZ0fnwuFy7wc)Iwi7v zN?#?o6}(8vV2hk|s{VMX<^YNu7r=%mu40=tZ80)>iW^WR<~k8*SKe%c;)>R#3V+lN z5D@!v$>J`7Qu~9d4fP9JPHp)2>OL8K>8G(r`4O5g`YmQOKikH@GA$|)tD|3Ljnc3k zDjrty=cDol8BaYEQKnuA(OG9wE(G3`tbs!5nGtWnZ?3Ho<8e)4Rl3c1SKbx7`UNG( z-z8)BcFN6@aW;hnv!|p{Hfmp208Z+iiU@ubp~%7(-=7%GFJ}fb2AC7g4P;Mi!PCWk ztYhUu`D8o6wTAKPEAc9HK`vpN+%o-%sOj#j+}q7gu6*R0>IQ0-L|{&BZ#!a^ZRSZn zl2IDT%McN8#9A3;h*Q^SP9D7rxa(2=9lfhLDf6wq-40~)Gs@HUSyfn75-tw~>b{{| z?b1nbGsYn|=bIo+)v2e@b>1E}(TJzh@fc=K-#O*b&QhRY2-J2unp4$bZaj>4$U8Fo z6IK7tHSx0gMx<09R^ASB-Cb6Qv^Jf)S<0!8#UED{&tKPF1hU)&*=;Hqhd?YTQaquG z=dSD4Wk?vdY>qd-+vm!B;iWHElDlGr6V`_a*RjptE^b zs6O?@jIW>5pSx4ZHDvXZReaO1z?K6$sa2o%UwL=v+dP^AqV`_?`x2Aaww#pK6E)Om zLQQ?TUQONMOH2jFWL6h{31;op?`SUbbsD=v_1M#=u(z*1&uu;-dmF;^nP1)7`rG=p zdJsigRP@3Qd73c#=rH4#KD$s^>HjFvy3NOD@A8@7r*@sHJ{<@JsW)Pvl2WIRM>j-* zRWipNGRHmE97{;2xiXttt8_WIqIIcH#LDU$R8dPk$HAytSFg1b!RKi#6Z9QXrdRe* zCQ&P`U^MiUDARXGZrz)YOw_;IfTp9}^g92)k zSgO3Ts0C~xz#Sbu{0YL}uC|CAORK6wZ2P}Q1^J^YPX=u={2KL$ek!Wize5E%4O)t; z-05vRyq7Um-4r%`cO%YDygXrse*R)Fz0~mysg{t zD6XFsr(8>`2kx$+5$u@mx8!1Ju1;^V0Ul!OBiek@w7)JnKPr~2kLpoPOXZk((f;q) zrAoRr)JQHxaw&6EPjtVIQT~S>t8+F*c*Rgs!(K!8fDz=|5MeuN^pg8n1D(U2_`3R8 z;eYf@3n!d$*&##9@l-=mq1+FK*j%W zO?RCuZ^X^dQBY&#V5x%X0De8GN$=Gp*V}?(sd{Ba`9Y#j^@%oSh<1+ ztn$riO#^01(`K{fphmf~q*W^^MEPu!DBF5UqFU^_F#Eiy9i^5!Vz zZ>B?2%pNm+l-VN(d5^+JH>a8za?w3<2h21@+-5o^xliBC61WQn743K+lvH=fbAGg~ zx}*GQ?l>LQ9o*Q9%t&>I->j+VQ`H@+wS8+sXtb-jMQCXcl=>yTO`1tXceN~D)s!gC z!pm(oddxp@sWQX7I(*?Vu{e%}c&^u!ne^!IDy6Kt`9C#5wS<;Ypo(v~h>m395mZ53 zn=G%b*cN8;!w#8lbAX*e6w9Ky^jx`IJy$jcpI9WvmlmvchT3($TvpDe#-avjj%T}hovW4P%G^x+a}i& zoDOuYULX>Rv1vR!5X9Jdwb?F>#;g@E*sEOcMyCunywYVq(5T*W9aDZ|86e_B{GRrNdNi+RUE9J2&$OpG7C#f-y=bgXq0uM$C+|$re+o zo{k9Bt><|pCFljfB0@{M&CHB23#FZ*3ZIC%)%?X37>_n*#%QNfnPK<6FIEjQxK%a~ zcIKQ6U^C=m1SQWZ12|^B(=n-Qm1w1`p>243`hI%cBxd_xlrDbAfsZNY;HZ z0#f)bySltq8e}Lu`qyp`*KD{GpYl>x!4-%L8YG{D5p;209~hX<+gMD1sK!%1hyX_yI4lRs1dDWi?)2 zwzHYw*1Pa;H@{PAg6bhlz_BHJJA82PFt&5z&oa%3lRieuDX@SKnlQ{YNo=8bkqYs2 zVHu4uuy|R1{cW0>W{ptRcSI92iRh#{=cN$y8H<X=?`gk;s>tVFAbRl%xmGt;a$ z%lwM~U2c?C-yR%vAF>S}_y=nfDZPNtwil(~715gR4m01Fo z)6oTlyK;r4nr4s_&n&%2lo6McMT6TsEwokC2h|cj+t|K@CRuRWH56Mkp;0_!+p--> zC$1%zpQE{SiX9k1S7QljsgVFLmIecbq;N9UNdfjXGDZferVgsq$7?YMFnAo&*`_^$ zEwVb>SgYjtq|9JIS93o=E$coD@mc*Jg`Cc1>4}^E-5ONRw-ev1p3PcAo-H^zu4`uP z`k&R97r)>Xzt4Q3QhE_f-_$DFTg!priu30Imf@B<5DhEL7S+^WXtGt+eZ$Q9IB?B6 z5M&6Dg)WmtVc%{kY*$BagA8*`+!Cf4?EvMn-9cs@AY1xxaJ8oS{4M66$#BJ~zDO_6 zDdy^(F4Wrfn%bH*>sn2&3^m+++Uw1>BGPB+kV}-LsUHA6Rm)bv9fKw5le7IKnM-w! z`NWMzGigeFGL{Yj2qr;si|q56o%0Ea+iFOtIVEu%t%-ba+&Y*{ar9MlW4n9)R_m=4 z*p)VXWw~7Q^p&I4Y$??G3lF+0e1g_ZryX5je`R;#o2N`kgQ#>!a9v(I39r%CSPns3 zxAU}H_dq>w5oOlNM#c`yf|qNDnYm`Oxu3a{o!s%)ifovjTuq=m=TW}goFmi`@BS3& zlsi|-dKOi zpIae`jULivbgr%^laLf%GV?&X!e1)l2HTWKy_}jjDHFCRLA}Kb{m>4+;$#c5o(Be% zGIt$pwyuY{-LXQ7qx8}h@!yBW%tR~$8X+1fC-!ice~q+w*?z&U%XA2>)nb&IIss|5 zNq`J%={V!o3CmXBsY?v5scIG~ue=nXc*;@FD_Uxz`>!|4M8~BgPz`d_K*eepQXa-H zuG4(jX}H%cWo6W{0kp;EWjW@%f?eh95Sfm(vivr~MpmICu8DOM;P2Zcm$5mRy>TdY z$uE<-LgjFF#4>90PAaYpaep_>qOhJ?;2mX#i!-qVB&+}k)9!xxwmqptvHXW= zE?}3Tl&|h4UmbM@1A|%m*Hcz48j(QG4K`snpCitu8Xa_jv@QWpjFS#JDNaoWucw`< zIYKk)mMIn2X35JmtL&7lRF-M5&R_x^xss#^clM$j`8LyeG;fiFY@A(o>@{wwuHgK1ky{*;*xvEYd zSjKIIyOEQ}h;yWd+>P93_MR`r`MXv0d95!s=kT-l3km#EK$>U1$9SIt%&qDHH{ zNYw73!?PhPR374V=7mM9uAo6^4g2Ayz9qQ&KXGH&9(!r~_CJ{0>M8#t^3RE=(?ZJV zbj-8s`yXhv&Nsay3k&V^ZBK`c8A2utzOEyl;^Zwdle5kC3Nz_6d$uN%M^_|UTfTH+ zAQMkH$Jg`FvW;DyYXMtAJToq|)r>uT(eZ&y({st=rlz81(unoJVXE2TjHhF)j>)mC zd~K&zwurcvLDnX^c`Zzm6G%;yfvtBAY)usR*Wc7%zfZ)jU{$v_VT*NbqebiGffdJD z(J1swQ?0qGr<*mz>*;Turl#JcWUB1=sI=P7m)o9{V@fQ_Ij7_5l^3fdJ>S_FXRj-R z(&DmmIZnp2O}yTU(X-h*xMz{XyPhylBdt;-%vC5aG?Y73V~9&0XEoTG2;_A}2s2-Q zaUf#WYu~hdl0UekOK@8xer|`$X|uCk{`w&|y^#J!qN?Rxwj2pwb6l&*-@Z3BcgVoR zO|ppD?#&$<8ctng=5EBpy;(q587>L$e<&~Er(Qxzi(lfbg+pj|2=VP6V$N$wA3}Uv zPD$r4s6K@F_6$E$8G-nAfh4_!H-z}6(QGzL#X-ckgqua$j;^ebC_y*)th${2BBh zhxqno!lNU;wbRBR;@j1Xco6ZeOmbFg__vVnM#VKF-5+isfrm~q%&g^?iCjsFc?CVLNxu+ce=2{6bh2c0BS?r6o|2gEl4 z&>BR1%kq0P@AR2cm0zUa>{IG2zUm8WkMJMAgX}533k7P;@lGLk)r%$_s@sau;X%Z= z|Du%d;$p$#3OQEO72hQquWq7aI}Cl7&Kw|zZ`FtVM?4RwqHE?T|B+gFs_0t6N9nMu z=$g68KTC&wMb{FZt;2=Nc@MSr5%KL(`eGRSBQ%F`C#`#osZ{nFW%xehLSbawfnQ*( zLYP70W=f7X4y1!Q#J69f5BnJhGr-}9Z?h>MFiyrVG#29*8Bfqw*f_jMd`7LN8yCW7 zhH(+?9&GF)JkvOpwhl4gB7ZpI+kNnVPsF#EsQBR#-_Ax!0#OSUF5+8DhXPerj4yfY z$6^`<@ofh!{^Jqfo<_X;i1=nA!4H7=_8`+yIBP}$4IFqSW8pV77cjeSe${8=IC%~Y zM#(kiA|1Z;i&PBbaD0bxGQP_Qh*l3nd^LNzeNtz6I#$R`2^FzRA=3kG=1U_;x+Rdc>QL__max{3$=>JrLjC_Krk+Tj9?~ zd=nhW4gNh4-@fF}A- zKheyx%3Y+$|e1EhXQev)9}h3Bh}3+x@>coLmH+bBOEhsGx` zcPHrX&)74WUQOhKHsYB1Ja+|Ar&^BhFjB!HR-wTv{j5Ri&p^FJDo*1k?SctJYLswsg(;8>-hWUA3Zg{pwYhRc}~7yJlVW`qI^Fv0}ew zO{qj?ZK$qZgCYI*!C$)yloTxe|9@<8{k7}=A+4=heOc+MWy?yJuDfd1+Um6{X02Fy z+3HdYsRzj{TeA@`g4wxHDaF@Zy=qPAvg&m!N@ve571*=)$j%2pk@A94)2YNZ-3=RLYyz2S1uAxfD&FeIcF|LwHu%h1cKQB5mVB>EnV_9D4WtCwS^ zn+DbZ8lhQTwshSnY;xsRUxoT#wsFIT>b3l??P`qz6wQaXIA#p-Z5RyG+_`Ea^Auga zbi-1$X7&0F(KRd9uG(<9x^l(3wKfoi4Qw%FFx@hYJ`5-%hqAPO^=AakV&mGSYgVsX z3l5WJYymk5dWL2zuLkmAJ9Jq=(~w+&ybwr?J&-vrT5>^j;i3h~DqT|z9tRz#){3OHm+s=qwO#y29;pLKPiygXgaFw{@W*xqFmabitfG z6VI5haak;|Ej>NCsUHR3WRG@_lb$YJw_>T)DUGHw40q4Q2wQx{qKm9)mx*TOuO6;e zLntjYu_v%h<#`LwKObBf8q?cG^zs!;|D^%lhE{;cL!i?%PEKwc%uTz6YPE6g>Sf#> zqI%8mInx?k<>+IMmia#AQ$GI1o0VF z0~akhM-A<&vMcKP>z6GB3@M+>GUjvSGCBF|ouTXoF}aGcl}WM|xSJ6y?4 z@Uo@Lt`v5A!W5l++#bzXAUmTMx3(O${_^T|8^XinpiN`vjuH(Tb@>XBidw(%vYKmz zo8Gg|SiJC@^Y_@7EL5aDda_6(I1Sc4f8p7HDzSd8=0)Y@tcl7AWB~$dd?^dcY3RhV zus_D&-B|i4$mm)y2JiO21>S9NbNI&txs7~WEzNC_Bd_0jQyN2j8$)~>8yqf$)UIpo${_dNdrhB`$P5qx4^X-_y8|JXfb~J|`og0(n zj$yuOOs4yobHQeM%%-h2ebJ`x*tFlKW0-H2yv8u!EIG*E@kD>dFyAaWjA6dna^Q#` z!+iVK#C$tu4D)Ra^NsUfzA+NvBd(=NzW8Wic(LW{KW@t{{yaYNY~tV}?m|BDC-9t; zvf>u;$>;Zcl~Q5S4&uWXO9uI^BAm}}4e|WjbB^CK()0QCR}J+~`X%LrTKD&%{z?3w z8S^c))atj$g|A}{j^i!D`EvP3V7|$-T+T^b;znY=Ejnr6FyAIKjw&Wr#v#9r$<4<| z%(su8v2U1f{;(y|!r#mB7DVfk4n&LNho0@d=!Z9szsa|P@Kqe%Jmk314_ zN6_Q$b_9(=G3Gz$#tp}O^Vkq=NjF*yxCuBTAhBo;d?`(S(hR)FU}c~%KnqbXi|J7h zT$4^`fhR@H#9$E&T<3)e_5;`>ST2kup!x*!Ed{j3+j)iF$_Dac`7kpDGU%b^bEN|N zjQKXAFF6Jdj}t%;<;nE^#Q~&2nl~wa{{2;fB~p+9WIq zNelB${{Y%%`EHK2O^pQjOgMf8lSvEKj=)~oKOWRYULU646y{|K_OsPHufLO|xp%P= zHVjoodHsle$OY}Q2+X%6zs+JaB4dHP8Az&u-d=#;EXk4lKA3MV0aKGnk!1%X+=sw? z6GWE2Y#+*ybb5TC{Qwu%3FcdeNV7wAWZ%qU`JEhDbmUN|d3o49_`PSE?ItP*ieVKkU#TQ541M@8E9P6Luu6AQ8sIsrtoY0X|A*WV=35dJCXGfzCKy^8^KGC{ zz;bk_CW%;?1*g4){+cTA12l$7-%c~_dD zL}R`Q{L^q}igtPU#=njEmKMx6Q6e)dFhqlxZ%GCNs#UHslOULHeea3+CWCZe(HcI2hjp z^G&u%Eg()KMTz6->dpfbX=a>L)7MO3T{!~vl$a$z0 zQ}9m4?@3~?xDTYnjOPsjrg}Hikzvn#hu@%Bs%K_PQ*QeZ%k{y+B41U}ND%>VWFout$0naOYr%%r(NVbYv}2p>qCx^5yADU9qJkrIJV7}+u8M#{X9iF?W;*xLSN*?F z)!Ut9CL`mn`uYF=A8IC5PhC$vRrS@9%xl%F)1Z?iN}6D*BTLGd1i>B7_u=N^U?rr?fFG1;J}5X`syG}70E%3D=#HaPi8 zerjTD3L7RG3_euABfA?#cEEfCV1*J)m{A76o^XOSStpopMRVAnzgG*W=mM8hAfKVM zE4_Jk(J~mJDw3O5;+47uhk^N7^GXTHj2hst?UIp2Y#hBfAYZNt2|At^Q!wX#znw(n zh!rxHsEYZ9SXF1V%}lZx9l?B)!Ue&612I#omN4RAW$mr*@-C0{9^ z%Clubu+(LbDe@*nylyxV21R|lVRwQE2qfvBb>yDUj{-Uah zluFayh(9pn4SPfEQFCr-L@?iW53?Y|(sNRovm;e2VH*E)sXSp?n5%55SE(@n7*VMz zoI&Xm%s1XZSHXM(Qx7!6(u7)SG2a-#8Cin6D3ZHBNgJ{}N;Rd@gkZkSSj@NCiISQu z%uGzG0%(y2c(aUs=X5Y{T*s3*9zZv}Q_O%(sAx)3|NK3DB z8s^&$L$d1$F^c}bgZVb(8XT~(>K*QaqCtPa3GS!*!u32yU#H@AbxXmdQt^fc;wLz% za6Ony|KSXJJ(Ro6i3a>jo#G=VRK*!59t86(xWv;X7+sz>dZIobXP;9%!vV0xe5Xkq z6@G`OEf89&%eU~mr!ai~J$*63oKxrdz&a!RrVng3 z!cjNs9Guzm=m$!l2_FaN|$;Z96LheM^@vQN{0o?bcAQ)$(9peVB2$ z04z7@|9!#XNImiTP&8aecvh&Ru9onNp<$E%a;PsN<&UfB@yqy~UX!S)fzO7T5#)B% z6Ey?$$5Ff2#+Nh@USDg=KU5nt<9SG(GVQIeBOX?@b z8&pjV+x&eEL*UtZfN&bDt!3QC8WQ2Uh@)Df2@}6EDsclRR98p-WE4z4;s-A2ko4l! zOA_H)%HO{P>@>p1m&E*mrRAb;X|zuGyhAY62-huD%a+tSYSU866K-AFVfgL8%(Pd$ z(uAt`;IdROK>i<=As_A4GCtOqdJmM*3IyH+F`ms2jdmyLgWFXGfcSuoegAK9CJ z2&UP}F2VHEx2`0g`tMz3`98S{zQU(zup!Kq#t#Ui#LtWo!uM%6JbxdX|1jZFFxbx9 zHz8PY`hGWDvY#z~i-bPqzkfd~$J_Vs+HH6E9dtmVakphWBppDz@V)6k%GD~*W;Z^@Q~6x!2oz=N+1;tEc=k zhuU)29%jS()mEOq)nLyx>e406j0b$SHX|S7@xwS_SUIO0Zo?rreD4u9{=6GraU^lt z+v}*ohR8Cf)JG`t9DB5tbL-LMGyXRoWBD(8Lu~0X`1W2h)qVCv`zhneqsLmKYI*H+ zXX5Fatv$Cs75YQh=N=9XVzaq6X~l1d2ZlKUkE+kgV4hL7o~3DY|h52SJe(-s7DRxNb`3dkCE11 z6#tCe0MFyezV?Bpw#cAr|NfYuc(oT)!;o^a1FHMQ8_K-J`2G5+=p_^v_w-XwJ^V0b z67_?=De%4kkSKt5!C|pAMM6sl92y3=sH44>l==f$3oRXd`@ug69tij+Ac=Lxd8co( zjgKrN-3#=?w%I-9?j7#1$nYN!$EQ-Ymf zzT(7i2@*ifFv&eO`5sC$d;%9xOL7Cr$vA1g2VYLeAfcIf!=vy>a8l%pgO!Ey@cHD6D!@bfkP9-IG@daRtxw zgAybc6_~m-s#cEm7JsO_eD??#6~jS83cMFwSPH6MspA*rQq6IeOfenyUo~Ci#(pSSjV7g-7qu1I) zqJ`#qU9JeKlmK?s(xY@d&5Lj+e8rOvEGb^-RF3+~pZs7c%E$+2n)~=M?6;|MLBPt82bepoME_Ht&C9$7rvNNu8MddCM=#Ou@MXt*IbG0clHh+Oo$RAVAjT7oL{rNx^2{K(IW&XrS9H;MP z3@%4dHMyhKsnLO207-dWM}NeLGc=#N|Xc6ymj!1ks+az9t$e4I0+ zRP)>_3SIcJ?s_{0ctom+*EC35849hG_Kber1!3Kh1dfj4KPCx4J-u?J5WNq*>zr%~ z4q~kXvr63)JwEqspdWn`zVg3kwg!f42P2!oJyI`3Qmqs$sc$wV+G*u6^_k|lOEe`~ zOx7)tloT$j7itGVoJse8c^I1juFPJ=xZoLCXWB9(t$%P>DD?98Z6>LEzyuK;lQ6)= zkho{+MkHuWwRRBH4a>(Ef|qC@|9Ybe(`#QsA4f+vY}kORZk2+-6r>1SyUc3mroIV% zx>q$lx#0%g(L__tBjSgR-#jSk z+@_p#@h&}}(%)9jS5!Nt_+Zp%n0=TQvn|f7g-VVsX6oD(g~1PDpiUERur7TKOeqXb zUP+s;&pWa)h9@MVTE1l-y|^?Ztq8qFZ;0AeU#=9c)UB|xt5H&Mopp z5M=0U$0)Kj3^V^UyI!w3H_7E{OE#excz8!NglZqAGjz3ih)$0Oq|+VP84r@K+FZ}5 z`wQkE)=LhxjpW&KluA>{J_H{C5R2ojlZ(}n*E-lvVra$;RWj8wKr=&PcSGZp;xj0w zdq#0mV|dJ_-0}eJG6r(^P|_$)bV;m$`12#8dwR4Mvz(DiG>IQJ67_aL`b~}I&5%4N z;t5t4{prK=F_83#W9P;@T7=I;lfJ!pO;aCFK(FFGv_|JorE(IM4P9^@rYXix9#RBi z(%^hH^w=zbqVHG%*l=S%&%@uQ=_G;);ui{7c36}&@I5JH_Yod5Y; z)SzQh`9^C70qbswHMOZHgTpE?EL|DnK)CN)5*)KZA_IW$2~|_PCD+AsTRjc4be!9G zU3u-yo8LIzFu+XUMaFApPsxt6(|l??*+wDrP#_r3Rr1~0mty`>@yj}%q~WrksS8ac zQ_S(T46AQiX21Jn-3E$NGV_b{xPRhufCv@H&vBJ`s(+$pT6uobFa$&N)%6+%p-hGp z8MlQ=YU;ydCgzc$?4O(aR+he8%GdHyVXlw)3*?1U^HUSbj2nTlW~wHtvQOVbPySiJR99^4sh!;* zA5S#(sI=B+bw6~K$kWtk#M&W{c2*4{UilTobFzbo=PQb#Y4{1^siL&gI@sT(Ru-M? zQ~g=l)Niu-*>eyp4OEN!@5w9QJv@AvQQzKU_@l|(FSA3*3G_J0%j{=m@bglxu$b3= zsl3B6dDi6o|MFZIq#p@n68bOy4@{ocyZKzuVQFI#jc8LV$I%nO6q9YMv2&AnDtTL( zvYIa{sN{2DK+&hvDk-2^heW43`{s)?N1v1ZGb7UFFXwM9WWSjmNRII`TNLML7FA~- zdjg#mL)v;ROrX)XHsSpj6V5hc_FtJHUcZicdi60w0bgR3l)j|fL@RSq(XwfyWuF%< zo0Vy7PxW@G)x7oQ5`uW z0e*8|LixX<2cdgYjPP{wr7xAEmw^QAs{c+GgDk-GH+!51U+hfqoWB##H`AWNjICHbb+ePJ)i`00<0gDF0{~?+A6z*>b6}l2N_H-AJj8us%fLl!=BqXvk9t| zzG?mXkD+FA$dJ$O&COAoatLa!gH{2!D>z66^|6tb-?7zq$Jtwr*BiTWxFIjMBXen; z316urlxw;tQW;{Aq)WSPDS7L3%zF-{ zx?z8q*2B!MF7du=l6((59PQ^d;KBl3)TVb(j)~*FBf#arh7IxM(^rTz`g`4_%s9JA z`zzV8@Gu2hI+|Ugt66xH!U^NBSsszoH@A*iY^aXrLjNfE!^x-9vp1SD5BFB9Pn~X3 zzSdsO6@X95lyg6}wYm;HXG6!q()=gc#CxTA+&Jhx~Eo`#i(=F)A6?!fM6^pY!Uz zIy5(=2U_wz9;tkKilkM#Pi3bSrB;I+$CvPkx93CHB&nDi=^rymb$TxyRZWaUdbF1j z+8^tq18(p1P?L^HBk38yjfCngM^&bLr2@#pbfHWyQj$&wN(l&c@Z%+(ip2TWB}|C6 zxkKM-F?z1sozho+N_5<~1TTs=Zm0!~-@q`BGX+EP{`f8w9=op*IgP#ZqC&j3zl+Wm zqbIuXP0uyi+8R7h>zKV8q5h0AEOC1EET3@U+|~h8+$OWVz=dvBAF>PUF#UY3?KE#( zpJJ47?d8KWtWc=l(g7X)VgZ~qV>!^N6UvjF;YITQoz!hUJt=RDe}1*@$Qm#!J+-%9 z_N}B5YNjS-fqm=>?AN6YX`_i$?f}wc81DVNw7+Hh#BOdenl;9Dp{v>0V-vO?-FY3Y z_IP_DybTnyZG%Slkxn>u6PoqF&@;f|>;l<;?b@L3SiANl(tos0I*2Q;lf|%|TlZ7+ z*Sh)3(6<)1Mi{O#neq%`fSa`5?CxM#$v*x}kNiw{dPs_^+H$nrRh?D&h<^0Zm{LD{ zG&cqt6r!D=mA{z{GT9USxlR(To0s^8N*XQk8wGUJ|A;*BgT5HlvJ7$SG=2Ws()WRa z;?vJl3>A=bpE~&znv&bGETy_fU4k9O+;{IoVBN***Ix@2xSC>OWm=|ynUt}}j0(mW zr+wXr8H_1Ux*XM?)5ULQFf;nRUdk8v7`Vgv=(eY5@7*!Vy3UgjJ0pK1%A2c>Fg3P! zAK8=@5RtSzIj14auZsz&o4~_JNupsyaH5pW!eb;D6;2~9Lna7Kn!q=0g8Fe2v~+yN zGMA|{Tx<(OhlS^S=Tsx+lOx;uVMe#4ABnw10i-v{fmJ8~eNw8wue~EnOUROr1I>l= zmb|mIBSMXE=`q;dEF_rM&jhVVD|u4vHHq9QOoc~m@4e-vsD_MzS10=8LXN06#oPO! z%y_iZq;>68E8y+n75N4haMPx*=A<25S^xG5OX*m}QYjB9Y5v+!m`PbF1!8Szjna=3_4$s5hIr{?Lk~4D`D-a6n0&^8*@yeFFSAU1;mY;Jq*j;Z-K?Uhr{_p zu=n24JB;C&#mCsj>}`C8UFy~vU-b&DLiA1C8#`>6 zE4LZKECVRG%t!*E{-YaeKC6~E=S?>(r)*pst%Me^UU6G&!1w>ev9ctPok&7ylHhg% z!e2|E`lS(E<;$>d+;o4`d*`N`7~eidRQL`yn1jjREgXPzgJl3wEU}bye)>^y*K?FcLl&oCX7F6e4UaMJ#Bp5D>QRA=Vyg3HiI^%ZW+i&@b5%6B}sRRM;MiOUZ5WZaL zf&z-CU14J0#ywHh*Kj8qZq?|P4L=$m1U!e;R8ePJm-mPE0lBBnZ+}1_PQpUO@m6l(3 zjfotlzmcUeE)H1~94L=?pEXtibTAsQ>gvtSbpEP2 zYn(KPa}p*%TW0y50j)WQ=pOa}a~1>zwj5)Cb?HlY>!GB6K+-d7^=zmdL(@Rq^vQ&0@_=?bRi9>Uz8}3B9p)!z?-0 zFUpLaZ@g$-rY91D4v}lda z_Vq(^WQ~+^#*WC9MctO{#nN|seUVKGlbz7M7QwSaxLR`ge+1TI0?{t}%$Lh9(iUFew+z;I(jhO)NXiM!a z3(@(??fqpe%W6HFOZ5++i37QtGd(D$>f}6#UfR8$qVnKR6xU)6*D*PRmW$q_#Zd*H zA7?SO@afxImtyeg!}e~0Pl6M~Y)HRA-E%nn3J-DZ%-1D^{e+!eZa8zy`4T^79S{E~ z-M;&pkYW5^htsqtnk&`-ClML;oP;C1zCl)Ij1?vu>4g{xNoVZ!)@Po1CO50-1?MO1 zorDq0lnrOybb~Zch56ynI!(Nc0g?2)a!gnft(9`0Ki!6qdZt@^Y?dRR*X_HHx}NJn z+`rjmUCdfSW@1ri`Z2dM3zx{m>?ZBRBkRzeP+A>MaCtDXW0FPp|NzT$g$xCUeByz(HY zRA-O)!Oh}V+~-W%XMUJ3ZGvJ8%t*^jj*&o`v2lATqBWBBxJW7Kb74T@^R03yWkqZmF<~H+Pe90u6kB4B(Ot4X;Sji2 zLVBE*kQ2WdCe9r)LJSe-I$YVd%Ia(}as4ZkO@V$JpLm=$8+q&Yn@LlL;HSQg0n9zw2ct#o$t;$>&*&^Hx?fd;h?r1$JL*htn>Uz&uo!lZl zQ_hxhTe(+Hv&uh&U3y;;U7}yiG+b`L0!bhTE(s;6%hZJPk-~8sEHk7%KaSL>9-A+Q?lt4uYL0=w`u(?uK2H%f?mvjCU5I-mzVgS zQtx@T{7_8o)yD8=rK)UKa%)q5)*jbXmW|8PZN|@`Jg+oKiH|$l2I6;?U8cqoSJShV zVV85kKsDJMH%UU9tczCc7wtxE2gILjkee~%^tiplA+GKAAr_)n)sV&J_R%`4?&G}=J z<7Y9)e%C3doL^xMikV_#TTg$Xf2=h%-aOl0(j8~!rkXI?!=6j zx_?#q%jvZP4)j&;ti9%-}#?}wtl^B zu*YoZ^k3~S#^7)x8Qu+uW?b5yLCh9y(~dHaf@G%GYOBv_z1DtSm*xjGMu#Bu8mTWt zHRaWa?n+^?dR7-%q?VxnmSA)Fjgd@ws?ria+nTkjAp5B;jyv(RA@KMvAbU^0{x5tX z^L&s%D_xKr$WmUDX=q4&BY$$D?j;$GVE7H!E};j!&%t0uZYIk6>G9PtF*H$ggfZo% z4k~(rgt#7a04k?=7RQaL%&8MkwoZn%clc+K$&3wn?A`M7)n>EAz)QLRMUXSq$CD=L zbL6J;Bs*yM-U{Ux3n|WzeLS&8sPrhmtq`J4N0WAEN{_Z1Hh3#5#OR5-{HVBJvLXhg zJZ`0_C{$%9TmTc@M7t~NIV=3SM#><^LYU}2hotLBpM!~BPf73XK9b(B2g9j?9{-0VeuH^1OT2;WaK@1=GM? zc-~$~*khS!S>ORl_|Gt2Y}s0&pP)AjV4~YaRu?9E9rEoACc0hn zo#Sci0B195aG;Yz=7XHO5%VBt5dKS?he+X4`3y9@_Q&24%GQPJ&N+yhq2Ea4Jq9~A zq@owBQ+4l^-8>WuJx@pL-e+>6(dc?r_W{X>#`w`^-MNO0hmtU!gNgn)0?mVou4lLw zfr);a7XSV*(VH0FU4)5#QO4ojje=|LAI38uQVAG2-$%uhSyz5B75-r{WgMl--U+L{+y(;J7`h=ed(u6(;&cDgCC%(-iP|uA_;-2__QoER)EICKB@e zlbDT``o}3&>uE$g0tpiddp;?arveil60>nqy$peKUH!$EUZ?`620uh%)bj*sfw%0j z8<9o;b7g#%F+PjJL<^v+a?ZtfoU_f!5qS5%FHH1H(%qjrB3M{1F;)Gk0TIwSS_ZG? zvj{*00(lrjRpT=$z(oI!L1pw*&6f?q%aJBb7BJC|!i^bR3?}+6vgTl-Wf~$)W(kEG z%{)Y6W*B{D9wPggh~Lb^PGF*UXJlUuCi-mpQh|xyh(-bv{eJo#Im-LbbhWNAa=c(Z zd;W}9g^B(sy{f`Q`=s<*S3}ZLtO67L2^j1$O!PN}=jGmh>IC+Hi~l}`sV*AnyiS^5 zEsbnw6uflh`ItmLy^hav8hl!r7oevZJMtbh6+W{teMO_6Z`pq)8i^D|!D--e> zO!R9o(dsprXoJ)&K*O)WM1vw-1!x9bSr82+{u)g5-wr1F*wy-;1-Qef zw4QnTns>#M26#A`1g1_Pt#?4FTLevaM~LJ#N9|bgSk=Dn>ZE~3tzzz;x#o;hPo4*E zEjXvI!9%|W554Z%D=rY2-@~rH$b?tN4qGSqxAWuIUa=n7@WZY-@BGUyy81Oh=mk*b zXT1A}!vzS8dh8Hn!F&S*VJEwVN$y*Tyl?`eAr9g>|fx#l(G=+}^=(Svus z`&7}i9RcRgXg%X(Weu#^j|@cnYk<(#T;FjKEA;&K>yqo$Wf!fxCV9bS=Ushu^78XK zIxfB9VpTyUZNKXB^R6)ix7fk+tTR}wXP@zx4Mp3TC%;qd#JbDQyZGwrmNp-w`&f0= zr59hay$E84uAeX41sp_~V`C)NobjF=EDPrU=wpsvbF48$?U%J*m0V}UU*yDmP6gK) ze$|8T8Ddi2zPK8_1`{22miii<<<9QjJ)AwA70%wyD&M|*jPN>Vt-1W?x^}*spZ0$f zPV^_=z_l>nOgX|8_BEVn`E=y}Q=DiyB<_EqlKZM8r)KwvV{Mxokz_f+T&+HI(N$Mi zE6AhETqOD7^Deu#lCp@UG$j|aU)Nr7=>_c^>*XkwG$(%}$3nw59|?NybpIMowE8^j zQ*c|q6?vScIg!tRcMA)t-hfB^2@oG zQLERSdHU+}uHnY<{A;hF{H{7wh;y@i-@>}1+^`Z<&inh2Ahdi%Ox(`O9Yh{#@~Y+H zlo5U&{=^Bt{S9S3zOP{1q4=n_N|+d+RG0B(O=yu@%E+IzcP4-H`JF=?^{%=KzcWag z&o6wrQZdqmpNv6;-^I}L`O&QV>lO%Hh2I6x^Z6YLzlwY!SB2k4q383H`2Wo~(QE04 z$S>nk&tIhv6R0`Keoq-zU-`B z!-;;=*>-+KCUF({w#SLSizQeYKg@2m-R*Ir-vz&2!HNFy`}kR&OoZ#CUHRJ{Ct6*) zYdF!TQ118&Gnbb{g=b|=O8gU)>mp%qXw1IpN0hLJzltq@R6Z8Sh!C!;jLQ<@^UK}K zxa$I@)D~+9^&n+ob8&KL#f{qH5%)q-xt% zPeaf@?uk0}UN+IHTjniSX@~$Irs5XhL<2^MEAfKcf&?ZeDS{0O!k~IeVEY1a1>v&J z;6!gT+18twM?+2*N7T4!(+R7ol8Y1l=Xr(xSPIXJsqwi;olNdr^OcOSw=(~gl%0j! z$xPIN8Z3zQ~*>6`bfA5JHPekAf4OV+x&|%9WlkvxLbpdz+*30KZaM+Ouua0!*w!(aJ@V zZB8`}h+%^PS_DhdCR%02f`AHJtu0{ZIJ7s*$j(6|B4_r zhz2KG4AG)E(Zwl)6J4|#=;{(`XhbTO0e@Cr(EFwhPV{(@Z@G?IoM_Nzfr~Z^1Dt4h zmkMH&Jo$nwQS0XK2bDAl5pI{ARjZv9r^$H^zS3cnW;|Qj_~zB*;J;FS428BoyU zGtBi^X?$W75L@qZ7bki;KQUg#iGHb68=Rd`DDDV2(a#C8>C44j=|#cUTIS+Jm&+4n zYjs2u^fb)N1$4nQJ64*U0(;uvL{9>*ng==+bi+x^y-_XECD0%j)g`Yv2F&S_+fzGL zc4sh+NQYgVXm_+k@s&RSY%nPGwUbl%e0{+Cyupd~l_muzx`cqLHo(MgE7lYzoZ{qU ziC?$Kp5m>Wofw~~RnChggA+YFQ4sXwSq7yxSlUJfHMvz!6(*-S8(5rZ5US-1)*vp= z7RpmIle26uvw3O4X}}g4oapK43BidjfHUn0Oikn`>q?$2`M_*pLQRbq(Y)CydIp~Q z%WCUvXyT>(d0Jsk`Pm!*-=Hd5oM;$}Gl3USMza#j#_Bjm>BR1Y`3Vynim;fk zh_&WOW9nOPtKdYVv@xH>iN*{xY@L_?QuwfWF$=LVKVgoR<>`txmk3oBqk`&q56PEm zYo?KAAx`uYa>!cf#0nWpG%Hg&OAk@2sxy0>YawV*R<;x_$Q!Id=$5J_DiHf)e!R$j z`LYsRaO=PxHVbf8&HDH?qToaW{aY@31gBd)k1Ecp@+fRA2s_&PKf;NI3G56`^t9ka zTaifGtnw3#@yqbF0x^+5SJNGEqHCk2(v&ai4^I2)eKo=P1Jl?bkmM^OEC`uUPAb*< zcC86Fv!%UIERCBMD*P+qt5leOjHpzR`J6?ayaDeNI}blZksLs;S%8@IMhrjJ5}fF1 zw$WV`DJndyV|f%ywWZRy;6zV5Ai+A`nen2U$WMKBoEK?9`{hklbGDV*1}7TJ zJZ~H*V2Mp?eJ{df|BdRk0YQ|KGuhPH`v^ z2c9l?zRT56Fc5G;2dQWz!oB9FRYy47s7j7A99=^EI%m+}-EMZ`K5(K#f8qzFfn`oH z<{1q5m#HE@bmf<#D%j!as{;?%dxxjT;6&f!83+bEj{jbXqryM%M1wVry4>h(s|R;l zwR^z_CcMSl1->wb*9(p?;gP;ny~y!zKAXP9*A@;FKgK^&C*ckLVH1DWZ_|$mz@Ohp zy+y)^DqR>ba(KQdVbJm2@5WyaSpLTb2O1l}4}K-s7l{Hf^!`w+p+4eK-w$<|{_k1S z#Xxw}M`}{_b%YPs41kO5QIXn?29c|yHW8KbkJQEkUc%v8@Ri|nAU}JR^pDpK*Gc(@ z>SD_p2;*T}{xjjBXq5Vea7QFedTaeqbjcD`8m{j#@uMP)JNX+TgQlN(}Ls7I3Bf3;@oe8;~XYFv@9A75f3*G zNqTWzV_$t8(&0mJX= z-AsGM$4m&0^X~Cbko+@tM?Tv7dylD?-#uPeU#Hbcg5OO3*Y}7TIk)UV zdV?;m-Lu2g`^cUuD0+GCo{FEidWsL3IL2}Xdf;>XjVn?{PmfxW2!Ipqd(#Tl*tlGk zB6|_izpqKSOqI{y+s0@1HhQnlTWQN3xypwACUA)+J;>&V4(?h4 zZgcs8gS*0Y%bfCohuEgxkJy$H(r2`HH2byr7!)O=2*~2JT zr#vUEw&B-TQx5sAZMJgN#jX6$5H6?Q4-U8dFFJw{`Sv~1#vhY#iPGzivh|8bb%i68 z?>^d=d;2jqta*c#=X-BZjk}S5>#>Xne2za(?YSrN9P&oOdgVOohV94O_|iAo@Vjn! z&I!m#dq~jazuTF8@B;pJLw%3K!tg|V9F z2Q&KNsFN+1^iZg{d?b(xk4tWNQv5*q!%`mPi3Cr@AJt_7|AfF0_(y7{9sIyd_-6me zVH07!wWRxi`xAiJ`TUiqgM{07>QYa0o4ywBHXt4nK3)QnP~K716kpZD?>pn((b^#j zJ+fqz0St38#U+1UQKs?|b$9J=k}2|%M~thF5jJ(S3Lv(s8^mux%rVs*3k)j{C!9_D z{ZXk$IeqlgU+2~m3{?H>N92gz+N1s;Tsq99Qq$(WQ-UI-?EqwqEQKf_j)zU{=Zz3{6 zk^VS^RZWjNu%_qy1V6NQJe(4vdoSL4f3Z#rkc(kyc*N=isd~joF;~m>& z1a5Dbsh#$Z)eP2me0kG%vw9}@ZBm|xL6G4wuO8@+qD_ND@dBxOf>H2DLARhe!!>Wtsr957uIjPnx*Fgp+7@#j^%uI$Z zcQF>1RCBBo3OJI1hAp0c3IbABR zX5cy)mo^FH+M1w6B+_GtB2D&{A4%a(iYyGIglZ~2`l#p_j^%-HvQSj#E5E!--a{v^ zOH`h2b7^bZ^cCfLqW!BgG4PIB^;TZExclPHZUCid>HoLqF}E1^G=TR3DsH#(wlW#zE@s|N*CH+p$nt!U9{RK zem34113pgJS~$a&A))(Icpjci7;2d&1Aj$Fq)#dr!wZ;B28^^BK@$!Xqw27U8fGUn zEtyPK|4Uz@^>ca6QX)`3&(k>(!7BKRO~cgJ4QQXYTw9>ljFSZ_bx;K#FMp30)#P4I zsDOT&R~0vL-;`-f(rWWiJATV(v!qOf^wa5ACP5#5YK0k*dSh*xM&PUZdsITLC`SY3 zXLzl$_wMpTQC0hV11nH+t+T6f`_%cXR?1z#5cC2zmnkF;&i$E}(EgOf?tFse+e%kL zU#5lUaYh95vO7%$u)E|9V`sS z*Q!bNr$|qDggKs6zijA;48wU+-PzDlPa4z@B0U154j$)|bwl1#RCP{!Cjceu%-=d) zzGo25K1TE0d{kOo7; zj)n}%l@Hx*!=~8*N)CuJS{r0u#wM%zX{LyGXJsj)db?cU&S5}~akW!9l=ZtRQrLKB zHg9ZZ>$owK{V8KWCnR!6(Y)-m6s6e4$4gPk2^CDSh7pM9lRaCB?`@u!4`8VNp94AnVZ+h0O#!wMJM>yoj^CNBWPX$k_H73k&nTA7eJmu>Q9h z)a2qAA15cFnMU&kB}ZEmK-=g;_iz z-O;OMa58_Xn229xuxd27!+&|D?u7cvqZ!djvwgps$G%lR7XC4ay0z$53d8g>BX!-3 zjDOvXMCt&Q8C7+3Hy5qNK1W8ySGhfPoJhW0My_0G1#2i$iiV|FOs$$W6Nu53IcOa- zv)TTuzdRwYlFRTsEYn&rR6nH6iP6Iw`38|Ht#iF8TI?^6Zi|9IuXDgX2d5+D zk?^>KPUlq1V1I(B>h0~5sFNFo6(8lX+=3m!3%R!j$T zksLQO+r8OLOnOkJ*~#|EEP3?hGMT&}nh0+-HZxmiBGfU;_gy&pa^6LPodgvk6frFS)MEJV4gMoXcg9ZLrj(4C(l_xzYqZk<% zzjjjmI^#Esn9H+$W}p>o`2K{MLPmo!3;k*zc#CdH%XT1*pGM9Hu9U5H_e_9(B;Pk=RkQrr%Ne9T<;dO!pPHI zkRrI#a^DeK^U7b_NsRTQk7RqKd#lF8=QJl>?d=i2enJHvmxDm2^q4%D#nkRRm`Quq z?g#Xh66w@WCD=JWm@5;oJDX00crfGiI8*-}zKt>gu*c)NM;(_ff6Z(HI{(8*v&Bar zc2BqVjQhXv&B!(n$pPI{+O>#PrshG}(foPyMT<|U4)!hl@K|JoIVy4R2u{O*b==;koFWY1q7yWY8GwZhWjhRDA(lo& zYm%u?cla@Ra#F>DG;bz*N@WwU)Q6Z(cIE~t#Th&%!7AM$LAqC}28(_~S1n__k(74Z zWNFm0M!Y(f93rE0(2O->Dtr|~+}%Se92h4VS*F06^eMktTFsk9OOZQA8C;e!I61qB z>$a(jMH^(#(Fu$y(0NjJrL0*o_PCIl4(X=I7RPsTZIWS5i>h}(==NWU-)btaGH(dI z%J7`c=`-?obTuYzZWoI(AR={x(^hri#voK z|EqeGGmsY7!b#qcs>10GChDz2O5N(^(P3IWqJpEUJyzeR8oFBJs%Dsy9N5GeG@64z z0@MbZMJz%RF9soOkHoep~rw zrtqHfO{|?iecyw{^Gd3_^mw7< z7p^5y-I|i{@|KzhrIw||QidoKQ%TAf?&gDV--D$N@rx;RwD@3=hl!Z#?-I*eKhm&y z$&x)Mnq^?88lLBEwri}#713TF<1Oot>6FOE^G+c9gld23=PDCpg`gh12mGJ(#y+86 z^-pBTiu}c#$e+|AXF!{=&>}xin#1%$OTU8JmZAKEe9wcrSC%Ou=ReNPhfVr)@d4cj z%qh%x^kmx*jZ2mmfLKx@0!yyt zUiLE8l9Tr?x9InvA1%Nx_XwX=Qd0SJOghv#)bgFeBL4?kzIsoo!=EX(c}v_hY~-(_ zr4aRUkKxnHSby9BVd-Re+F{du0pr3V1~*W+CVO@{Db;cZ%I_`dM{+|g#i*0{tHvEQ zE8RpdSbK4!!KRzlv)PunbzAN*tM~E3-K<`eyxpwcnpa!Btaer} zD#OaB!wl~ZzF9tI0p=?UP-NT50<3Y%*aa(fS-iN#mNr)7UyHfvmU6-WlLS=b555GB7&uWAb15&QK(Yw2#jGA-2Z!X^IN3&6+>`YT03m{v!s$mdRnq*{m@=2_{ zPO)t@46)OL#6Da*rkd{L8okFiquS2`mOakbTps7*;#rjS2r#7g<8;vSALFWJ1LIP^ zjgJ(b9TdybVg6`_V>y4a^Jn8|J+~G89qoO@lI*lzBSoFq2f>-+j*a_9l})fjdb_xY zOu{RZn%~bZkyI|Zr%gYx1=7#{1QIib0&>R2l*L!=c3ZdSfRHpHjT`&1issNR_rIzIp`C1k_T=QzIl$H=Pfe?e8#jKVg&GC*CJx#^N0EH_ zx&NGDZshE=MUdO(r$c*~$K21UwQWb&{}Xi?<{=XoA*=s;+f?$;YBe}>9n#TiIz%Q; zd1}>cOQ|P1?<^cRem|FsJ%=m#1@z@FMT0LKKNv}<=bM!JenVXSHuU4ru<9+wwQ-SR9(Svb_uCOG_wJgC#0d;ZjQh2_G`lLve;xC^TbN zDd!^(xHVQu8_Qa#+X?l0riIfO_upAVf$VWR$ub?Dn3O<=#CdM`h9%TbB@Z)dq7*!S>XWz%^w*(K%7!(mIzmS8lHE9KX3X z=GvW;MVhiMtMdjzh-XV(GPiId?T%DN&syXZQAF2~X3>9&i`AG*1CP`#SE-3!Rrmp$ zyJKr}X>;<;)vZuxq+E(G|F{&RXDOe7N)ei*RDjDOWs*8|!X|O3oUlo9_nweavgid) zM;4vEkZ%);%LSW+Su-F6Hqn$4@?29&1v;SjNOZHZoh%SV18Su%bn1e`Cp2I}JU}Bn z`ADkM9cI%F*mZO*xKr(QR3-H#gIR0=eSX(-P&9(&3m;b-GU^hVtnVfp~&)^k^Ex z1*Pes)GdVA&6;(|jZC?Z|g|1E_* zw`u)7A#h6#BcWJ7)-eYuOEGF)LOF_c_igEY_osx*^)oVY)+Ma=5*cj9dr0iW7|>0~ z+Akm#?eZ|&B(}U$4|5kIno>=hD>qknj^A7xs{7xiwd+{>j@k>9BQp~+jYdABHz@=a zSM3MCdWouwQzlXMmSYW8Go7^7?+~FVnk{zgZZnoX1U|z8>;(06=-1rv)7@G< z8jH{5^cK>lL-Yi^TZ-yDSdrG<-;Fkt1u)JZq(jH2BBM#*ws3- z8d&gda*F#BQO5bn3<_r5nj^C2xp!aWMi{{kOU@0(UrPnI<&b(Cd}O8J+TduqWtNyp zlq9qK+*L=SB>mIIjW@MU?74B{e^RZq-w|1dz(-!GUo_s2>A{>3? zD#19Wn&JNs!9bA}=GT3a>Cqhdb8N%7Ad_$QXXtva7VPR^=!^B#qc>iv8rTse&A_yi zKZZC-;9_<`foX4i-iV{X?{s)9;`*&GnqTIL_pfJ+Ee^Bc$Y1E&O zx{fCq2vez))Vf|)R`3U30iaFh+NgS`WSVtK_!pcsFhG9$lu(0E8NlFwv5}4j^-$Gl zwvqWAX&210Z)*KAX0K1_fe%O}mL4qLr}++sQg>3(z!#e~9emF=yw!BZlhdcJ|CrSH zOD-#!oEVM8@0G<>BOc$Qt9WduBN9<2R|2B8+SLtGd!z|FjZ;aPA9BSf+M1PMq{)KD zs89MpZkD=6Gzk#VayBv(pX-TIABjl`Io9xi6&K2ss=?seilL5B$&kpK8wgLi>^<48 z76uZhuHl@TX%P|;L(@Ss=7>4i(%0H+l9l!pd=_xhBqwdMEuEDj>KYEZ9N$d0Jvn&O zX0O{MqzsNLi5;|%5m0g%Nh7zRr8`vxd?6>S#R1BBtfj+hg+U1r118wE5raQXU#Qm4|0+HEh9=deN=E58~XW}tv{kw~k6G6Mo6k#-n9qJ?cS zjc4JS=S9TAQw*Cgb@nz9S+K&b&Tykozm#?=_l_#iM%&`jrMM;N2nBF(VewhQf<2KU zd#cHT>Z%asHg^%|Ld=xG8>C_P${bj~KCZ+| z3w)G#)Sfm~A!dXS>-Y~N(1R)Y2w{qe`jPBL9D!WtmqR&DL^V!CHEy~>R1Nt*fU6f4K2 zPB|tFN-?-~%5!LTynr7zMwn*Bd93=$R+=ygvJm5jVsXO&#}NW3MhFgmY~oO6$JfQ` z(WRigl7-7#^9=X#Pgix zk`2tcam{SXyGFcW{rYbG(E9bMoI6-m8!(e~Qzkh{CH1|)2E%e!I5){AAkLge47HE= zZ?&+;w{*FTb#*;WXWXO-kAXh_LJPZA z=of^E;jOsogjC*awMnJm;Yxxc-<@*>Oj$9FUsn|2T^E+`F;rcz?(ls!xAhAqf#J{h9Awtz13hz0WGGy?pb1B`%1eiE8P-TN4)z#T5&&RIIB4C@PjoBEo zbVT2=zq`|kFl_!&$$(>Dg)1Bfm`EN@%~R4KnqjzRfCiRHPgp}V`xR)oikX?@@l&{V z69`YtmH4_#b|u{-gQX`{h%W9Mu(bY0uf^0{jxJPdb*jm)#`yx-D7UGyaA>zm=b=iqLAXe@)IzVwpwp)k#f{6 z@0*jla2iKntYNopl&kH^sYzUeu~&ww%IC^#^;2wpn<)w}TLe|INf`h-B`K_DIn7fl z!mG4JshiOgCvt6 zi^4W)PIgwZv?~}%uBgft{wq-{y7;x++X1`0VZ+CX^s}Yq=!eXMOzjpqibhN*qp^8-rqG%ozUUt)auSzo+TW8AI%>j?WTx`8(VE! zRauE_VaQU_f_3KGxRr=Q({d>8F$u!LjHppg!!{)xj4M=#zkO(iOxP|wpet{6ob5;1 z2pO>U1ggDqV=9ZdWJ;1`6V19diS?2s1H;$j_u}?s350oOO&CI^`_(C~3RuP`*{gzo zx%k7_LUD!l>(ho<=AW677^HNaMt4SV}C)kR{Vq^Cdm&s^(YL zo8N^sCPQ@Fx>jqbh^*%9OLK9#FBC02gk#)^a+vbLIMHd=9dp1s7EPChNF+hQZlMZM zC`_H!zlA_IwSFmKD0TLQF-!0|6*q~Eg?4-!+dA1Bg~Md-*PUkj7|>ln^mSu0vw!NJ zWDEz`Ms%rHY^a~6?NgjX8VNY2##q_|dhPu3;Dq~?8LWcYSKvI!DE&$q&PgU*I4em? zYCR|xZNi@u`JHt!_x4jbhc<26)Yb#h0K<<XNj55{z8Z@o+Y4RJ=IFWO z-(B*p793}SojMnL`I+Ckwe{Sgai?|oMUdeO=W4BL>(yFf@Qiz*k|#%{itDTp(_S~b z9DfeeA?{lz>W)q!ra99UmSvfM!_!2c$JqB7Td%u5@LShB@N3HqdE!c06I8vqcIRYK z9EH~)V_F_nxZIHkR-*wNVm#CwvWu|Go-q>U+JodtbA-?n*3b@@IcHh9hVv%l#gd{ftXB4@)^!lQ2QxN)t4$O_$fc88WA5TaCp;x)x(COnYKB zApUE^hL{lSapJIP8BFdLA?VIK$}yMFTP)GG>HC)GGKDE4%gPj9l*m-FU~UU9N_>Rn zz3E=E)Zyac%$K@^sIiAS70l^EOcMHOQcj6x&g2}~BtpnCNg9Gt?=-}SYYoLt_nMSZ zW%pN(33k_I@3c0Gqhrz(Vb+YCM5cP(6dnQRTz|zzw^SC6=UU0Fs)a7dhTys>{c!hx z^>0Y?6F1#Gqb7VK{^3Yl!wlvx(W=_{8M^xfZp!np{e|`myVq`7D;LF6o-zMOs4F55 z~ z*->nP0h=$?;x6gcMVCUs%n+F9K_-8H?)&3$vqKacQYbZBj7~KWup^{wRJTjCZqp`- zvhXDL@9RDz%D!n+ml1ToH^)rKIrp)cA*q*hfnh5%bb&MMTM{h-fk@B1*_k#sm?o86sk(kgU{d#{Wn}my^4AOe|cExvBgVEn9tP;JaCKPY|lP zqt?A}I)Yy#SIQs8O@`g#_l~n1rrtDezF(W1jT)78y&-arJZh_CCG%10u%*UfK^=o@ zP~TVKM;I8dt=zp3d;FgHoqup%gr{ozVT7sc>>D$oI_huc&M}YlaTV>B zvrPP37uV>K-l@8=EBG|GU1!G5T&??>cuwIFn{V35b2nO*m18lt3+7rUg+K@0d4C&$ z^4z)U`vhmN|0rX$e*IPW#!b_daqhv1G6C1R#gN3f#5`iXKEAw4ld?{~t{nLr5H3Ue z9AdjIjnbF1jT~$f);SkeC{MPcpY**#c2=yAr>C2dld_)NK)2mhDK}uR>Y((%jWLr; zGXv2IB?mBSNYmBaol;J<9E-)RVQyVq&CXQPh@|U;FTp{=J%1(4Swxa?QFB%`g}7^wLJMjvV6~tP6EQ4g zC@lk`a$Ks2TSVN0nWC%ZAs;toz7eGL@XD!3+Y=$ZQm0<1PjUNXqdd?_)bjj$_%B+f zGr>FMP*V9K8v+OUv#xfOQ-C3B85;RbDUOxt-m*35XxP1Y)1!Q&=@DU+)_jWTI@WZ> zaS)$fXIz5eX)~PgI$3+Jd%q}@xIfkM6rdcR(7PS&HR*{J#W}U8VY*+zYUOdFI+sw?RkMo3cg#CUc~d9zQ>0p z$>-nfA?Ze`*t(~Dy&&idj`#^e{+nqf7z+M@#NB;<0k9+l+vt|BLJ7oPXK zlCZ}zQP{u(lJK8lyx6j}Lcc<9y!$tvEtyYC!uv(mLzjI}Xn6y=H{STq(0lm2=M(sz z*!}AS!I1Bhk|*Qu|L|UiAWUEnyrpkNg8c*U{SCC|^U#6!hp(nb$|EBYNH*R?#OE2N zjllWgZx9K2K8zo@sQzUNggtS|S!W{A(7#B|#q}byr!Uke94;|2=MK;P(&Puj(!u2( zdFN^1Lng9Yy}+FWE?;^qqqc{~BP_1ieNTeD<(=;;&~9GH8dHtiXzGp5!7m6Sk$36O z;Ic<>uLNW6IfgL{?!DKEFj1ZiesJZU7ZCV7KO-f$YDFiJkcZcfs9@9nUn3Is{9cO1 zOeE?lqqD(%_Lr)Ss_`=+e!}K7y#v+(;lFeX*?Wi1>6Nx#VLC$Z+5I4jDo++kL+_2q zJ{9)-gi@jRHB68b^;}9)=>10eM$e-#41Hk#S#tJJbkd~nuQ!9I>aT}B z)X={A>yA)0hZ#Cle?9bSLx+|3d(^6F_KFw*;Sh8}@;3XhBhyve6}b=Xa2{YR{ttC; z0vOj(r3=^XO)aU_YFY9c$7(yyjxBjf;w+9NFL6X{N!YRz1ED3$vMnO3g(NRw2on6v zOc+Sy0RQlS2@(M&GYmn78I~bG$iM&zWFm*+S*2 zW(TtGqKf^$XJWr-*snr$hgA0Kscn2JXaa1q-yk`mQ0RopzMC1LaOjB2ev?Ft{l~yK zJECby{Y?-EUxAXmD&@Wm>dLNl{|A8gNfh;NMukhIdVj@&*COGq#3h%X1Qu)ZBI2Qv zAu4643PnlOhD$yz%p)HUcE5*tyBEBNd8cp@1~fX!Hw>PEdi~X*(~a za_vL!dXp%jO~rR*FoIm`4bTpL3z|ltTuCt&DDSgKxvBBsQFjkez9lH`{SvU*pbp10?sj_-W4I-$}ynTE@hCL@@!^r`h`VN+L(O187_D0ry&P@R222_Q5O~(hw{D zkT6iLn}7-a!`002@Rt=T*u6Rz3BT)|Ogw5D^D(milx~dwpV`dEB!SNv9cXS=!P7E$ zKID&4o`01r>tX++l>6T$<@zWL59Pe8A&Q%yvkiXP{cg%ufZB9FTWxF}1$UT!@Eqj6dP4>-H6AEG*sH2|hw>#Y#jr-Dy{@+6cjfn}vH!l2N(cS(o!8^@i+8V6Jh5r0jtSCI z4uU{h_33Qo+ryIA0^6UpkQt^Vd*k(iHSeNEq@7t;qMZ$a)!~$^;eVkn+5>r-U}Z4~ zg5L_#c{~Y5+P{eNSoI;`g3tKqf2KW$_WE={U~`pn2bZH0@C8wK@TTmWvv15U&))=u zdr=w!#l5OLA2Q{t?3EtId{+n}W3|f8zBSt&g#D$n$jQD3OfrQ%#Le1BZY!;uz2xs& z0^82Fva_Yam6;a!1w7WRD>Jf@tEC_=2ORzBLIo|WJfAta3#}`c>S!oMv@%$puj|cQ z3E{XhUXX9OgHAnumds~KMhc{XE4^AI^o*2&rWWN{mk0CFq)URK#aM5f7NSR%p!Hz7 z^a^NhSw32H%Ti2Xi=BpKlkM_!EnqH7Nr#rfUyB}$noE|ld|^6@nh9@IJE#PxipiC0 zt&*iq->}iQi1@4Kq9IiQ{$Py===rqpW+dI}Ag(TJGKjC|As`!n*6hQnRnd{?(fT5s z5mezIJf86$)ehpqidR?P4#Q)YY#Mlw65_OSRSpdJHlgq{`+cd zy|?whq_)O}14W1H>Sncb-G;Rr)~<7!tJXTPB9J#8KipVU7j3C8TD!LBXanwIE}qRZ zr5!Rt9tiac7vr2x46ew*`a`wH8rvc~ow#-F5suABYuiEGz#{?wjyOmV$H)X9hYViGa77l} zClaZ1#hY6ij@P!;BLjXvEdvO+C?INE>T8j}e1SwAj}1KxsD+pg+J^yUQweY)_M#!Wy~Zpj(`Cu^XBW)}MqvVg5X6Ez%rqZD?zNc{>f8 zVco1jPOaX$cTaWYuE=fWyZ2Pjk!Szj{p(ZZjRi%fkEp9}MMuqUeEGV$sJV@=*tc#j zvV5b8Kw53l(pion%yX>WoO5huM;jQcM3hPNDyuNt-#^USO zZ49qDTGxDRGyED35nNMyBhrVEZmN$qtvS@Z?s}#hqqS{oFtKh%haLo??Z~mC2LNkZ z>W*y2)O-AfHMQ3sZN9d(zV6zzf``LvDqF*A;Da_FZaTL9WO&V?L&uux*zIdTN{H-3 z9JA@^V@)SuEo*SZVIz*)+)`#p!5_K451Z5;$A!WjwYVXPi@6DU;o^f7h<< z)w|2L>a)wm&~}xT%c<-$hDG_tjWP-@+F7^l-MJG3jWTXnpC;q9kD-)CVm%_IEiLt} z(Z=I&D>7dkICd!FIG#g|$6AjV8`FI}L!yd(>*ZkNl*7V|(RL)#7KPVu!Q4W-XlRWz zH`dnGABi@i=jZ4xb$%k`r9B(BGQ-=*Ae!$q$9Zk8V(%_Bqs7`iw${})*3USo-ke82 zqeW#qH_6aQwMdVzXmfo_EiHsCn(Gb^VH6ywt-FW)D!sE~=l-hOQyy;9oI$RSub-b> zI~mn_1Y;mPLl1I9WW-D*;={dXExjupMeNzTrRuIoMPDW=~W~Seii5g61*aD|UxUt>UVwfq5klI99cT`kvQS+F*(~6l^Ag+EM>k!vI4_?Ol z41vlw;w2jlR;~aKMx>nXw5_`n?TXsU(v$ctiibMh1Sj=vyQirh=ibh~*DP`@f5z$pYiFk;W*E$# zeLLpQkkO!T8O?kWjbl?n%#}sUqtRK zufE-MXYIk`krS+QhOO=0ziaHQIKZrSlxQD=@0>l*xCl4jqr;ENc!m)*i-C zp%0Ge7Qo3ibFEF!bZ@#8X0nm-T88!T?0PXHz*5U(@{zk3%!D-Zd0h5gdiIc6CAEsE z;9`5{{01Wpq28sxXV)x?l1+NrOY`HY>eH97O0VBi)y!BjI_rH|hBP!C$1Mf?Di#6Q z_mHK)?3!_-RE!_@ZryrQ_^Ps&qhYQItDUVBy)xWg-?%P()s|xojR(WrRl#y`{l=@W zp1o{TWjEnQtd`p?iZAmk?+t6pa4=>@ncvEEWw`^^0#AXp&|2(XVlB0nS<9^zo>h2^ zaE-N%8$+`~I?AI4?euInZ*g5#wroqzQX2fS{}>$ zX3_i9<%Z(*TS%WL?+6h!fZJ#bPXcc-`Bwp2xJ?C_1U})nc$=IS+(^%q$FC|)KF=w( za2!;vN%OTP3%9`c&PanOEx2c%Nd@_5=X0-oI=CU<%=&ZG`%L!R04+X$Neg(MG>d+A zerQ%cTRk1z&{ukJ%jv+=7`OC7dYTW?r-NHzQ#38O@kly7xM$VwR?F1K48dx^JoNt; z(+W_!AI?gr{MqbzVfDf3Rnv?m*Yw0m*Vmf1uYh}$=>hBbQo+pQ5-+;2o^>DN_}dxs zrKFy**iJ3woHFyQ^4NSAc9mhi%5^0l@&g((bzN%kmtc#X_(j+(C*)2GA-0vJ9J)#J zF^HBE52KPao@!yEM!8n;L6(MKA?am=E3pS{(rXOF8+?*qYT$MQ_ZWDWfrkvd$3Tt? z*7J4)-)rFe4g9cy|70Ma;gkNW2KE{FGXq~RaLhm-Tn*_93|wm9H3nX9;8p{x47}UG zHye1uz`r)|{RVa$_++;1RH zVk6&U2L8Q)A2;x{fnPE3I|ly9z~2}+XkY+SBl#5?xXHj<4cunnYYqIgf!{Rny9WNi zz+V{ntbuU@#|*Tv#mxG$3|wyDH3n`naJzxK4U8Cg)WG)`_>h4gH1J^qKVjgP4E&~n z-!m{~;0p$h8|Z_BqkKyZyurY22ENX~HyL=3fqX53<=$stmw|jWfOx*QLHI2Lzi;46 z22L5c5S#3z+hE|029_AO$H4stMhvVs@E!x-V&Dk_KVaa;2;u)9H|Zw`F%SI8q~nC} z^O@MTryPq2;oOT&dNU#B1-^d6{7OR14{tW<6NH#Q_~sw;-%W^l?f=}fP28TxO-gN5+!1-GbPTP zM$;)|{mqU1bma7Wj>+BOHH~y8`58I$-IL59m}fPRUZ-AGI3;E+2ORYDDr6=`-)ZSK z9K?g8!`S;j6opnKUVGp`Oa1Zm+*;XeK-)BdYz>$=)T;1Y_9*Yl)!MS%yVlmWVQUc& zqo9jFHo%0iuH@?$I&3u10nB4qi9g2SZY5ld?n>msOkRonI=@Dw z(^t<9zdGR4`SCNjOMoLk%H{CW>-XvQGR=DmC$KJtzsFyCy?pPA_Zm)c=(ui9r~CFr z=zcbf?g$ouS2@f8op$^P@$_~qK|3fv+rc%X(~jREo?h=MWU?(zaQc%(>2y5rlJ{gz zaH0!l(M@4t%6mB{kO#xHhEAvOqrts6CK^pCfo(O4j_0R z0k<#h;5cAg9bbT``tfn}FC!+94+HNo)9LPqUha1?k>^B<)^A$3K0F=P-LP@vhT?TM zth+88URPXPoOZo_3fSEcweU4=Chf|ovq)*r%sGsI23 z+3)%d5|@4wmm2&rSeEZY0{q(uTwcB*XSp)|hQQ;!Q$Pl7%JK_y%b&3ZDYt$j-|}Se zmdx^do+hyT;+-s42U5zKeox9Z^Zg?C^!r8PyL3OK83#&l#~;4mjO#1EzLUBOO`lZP z>-Q06JqJ$hA@ixm+=n=VnTt-9l6_OT2oagQ($2Bo!=C3!PWmJ1KWdklEs|=@7O&<> z8U8PQkop(6?KfjQ{h!$Pg8`=k_w~|)yjPuuz$?mWDcXOU<44ZC`)czoC}}AO^vnEx z2;Hd*tT`_bV!13(_Ci3k(xk64u*ksc4cu%XeFV$jVIW64(=`TiEx~k?fyWGFt6g*- zuXfG+m#}bz*y8^Ho!-;_6$ld?-%dR;?#u%hqkFY$N2eb0d#jTGbn2bGb}WV~y&w7P zcY0O+(H3sOpHl`=^%?wK!H5Y?UIo%loLN7>AJ=+LaPnRY1iD+5nv5@@BG$utGw|os zdpF`v8ANfWfKug*nBe3!AkDb57PtElsj!*9vU7?6vX4^+pQ3UI z48qD&S!0a<;dkx@{)|C)J`Q%JW}UFuop7Rre*J+BHI@N$nok?Yjwv-cK_Dq& z)YKG?C>~MYQ^5Jbbt{P5YS94sc#Bb7w&Lw6% zWJp`{<*?Dy)jMV6H%m_9W#KGY99p;E6F~F)Q$yc%XZfv3*k1tuey%11IGDtbN-boM z7h>-^phDgZDo|MA5ES?L2wTw#JnfhL6%rN~drLvSIikm6ZS~OhHn-B$En9q%eR{0+x`L zMQmac;tnTyJU0&1m~Z?! zSTTO+g|XmK!-ML@(Xr9t$q{>e#D(Tj96m^#4pS7hQuKUz{Rb;M6`- zZk$*$%?UAzj3J=Zix5mrya;L!#c=}0oMby`k4}1(du$APH;o*Im=hSABg0UM777nq z;GS`^s2rMuU#5)b1QG*0FXhGLr02I&Ui|W8;`|WC*YCJ6Nuq*ea%yDA{<%|?7)dI@ z2wDy`q6XbZ(|IaZzTOvOM-Bk(gjM+jq7|lTgGjxM#d|0{pF{p+oRA6X$Y%Dj!6HDNTz$wqv5H6Dm z7^@2S)dls3$?VBNYjS94D%T@(iaTfY{NPAHS-(km#uKAz?EJ(8h(}RHAam*uD4>RZ zZx4?TUBF6x675oGQ^pWF`vo;MHl7$B85&i?Q={Y1fwC5iBM$uN$c4elF+XZ}anj`< zK0h{;Gv)gExPNT?yc!;W%}$LCqh*2Y#B=I*qnU%xjtvdGI0PRied?L?yE(go#Kt|h zF$(a9e+XFYb#$0`9ZMFX^gFruNh>B4vJf0;5CXFv)ME%vWzgSV;T^*)ny}yo7W_`r z%Jtb?-V>xkdR7XlBlH(Wv>7=GIu)3XXZ=_rkTn8Ld3Xe8DmF2m+KaF8u~bt|L>UEINe($T~MZIEDH0Sv6uz1AcBiA*P2}$%`i(iP6OP zxSC8R+#|HCUqXwRyIw*&v@?Jz#}i!H{;@$;Sd^Kn;2Z&wV5}EJB&2=@i-L}yRSD=z zhpCC=1e%jEsRH>^Q^Vf;4F8BXIPga>d!+l* zbn`^M9vLtV%xvQ@&I^e#bZ~lsXUS9$lQbBZ2^KEc51$+wc4K{V!R>Pg+&KwYFw`>) z0Ar-VO{j!VC5ETa4>G@CmE@U%a)vPRz{5~)16UAYW_?KoF*Cp^!4F`vq(!j9JoKiR zU(!c{Zrt-6v}C{~0AxZkQ*xgFy_FZhQaXg*7uO)znGXXr%5rhP&gIMSXJ%z)We0MC zxuLwkg8YJo+^}7=c*)YmOPBI*835qorS40XUwY|^!tlyfm*HW>cMR3l!&(=KTuErW(z6aqGd*&OD|mnk=(0S zTn?G8y84=H)oaw6wME72)^Av|apQHxYarJ3H*C6b!%a8ceA6vg5{JZgA$A23y7+5&4cwp&3 z@xToOHw|nZXdGx8_?Lm32Tu(?H2A*3_YZzx@JEBc9^8Ds`uwMc7mS{Vg*u@bixP%r zpC`{!t5i*9MuwGjv+57!JJ7NtHe>Ow4ea##jfU1Xn|!v>I!+?p!=LFa-UEb?>l2xpUw+ovC5snXlcDTWdHH#^`doJLg4{fpS|6y% z3xV&K184K|kiH`)6v_eoa!zS3;nl&81vEej+@#B`3S@)NKj)UBJn*5? zAnCh91B>zjx8!O1ujdsPVC(>@RA?z!}=FLQBX^81&b4HAF*iqk$fVBLzErHgW0>ii1O1MVm+ z%?*OzBZX4mB%W0WzmJB`X8Mu;y)fjs(nX<-WPHIVU&AR#&b%wQv#g zzp$z_2S0#T*_Q#oz@B{HWgSwk|FUL(#$s!7-Rj~DH|(=|b+g}(_Mcvj{`XiJPpl4Q z`LnFdfz_unyk5(bSgn>US*j9OUjc~rSyuusQc3(aThiyQ>Imfl|JJLKUZN5ozDC0@ zUyFVK-LGGx)9$rMgKlIk(#zBo99|%huk7w(wO|3@9qW*f@}29E54yt}z!&Ka8`Z+x zMegK}0T-g&@2&#`-?P_i_{AG^{u?)`g^L&2$^AE~+?+*L@_7SK+@$H=bTc64x`%Jp za-6zFttecAiT74@$)$ibC8!sCkCcKgh*L5Re6S33`8dF8ij0v2AL}(xrCd z+3oPFDEH&rP!9MX?9lZ+emh`+vL7hdg#xiqz1>Lg1|S7I}}oOhKa)s`~YzXPYcfZB5U(blzYm4>YF&UaSPK%%wsU@t!Z&DJ(6 z-&gJA`#~W*XMtOilsDRpW3f-72|RK;`<#lF;v{-}mEaWrx7XkWEqq|3n+MXW+z#LZ zRB6sxRZ_!DzZ(lsq6v7a?W{&l$UDl ztnv-wGaQ&mCKPc)%v9Ex%IZgEDgNHoRl`gymvNG|vOb!81aY-C`4zhuu;;WK<;sKV z<#gXZ99q~7eDoZ237DPemELpdkGSK@h=~x;e*1NO&!|s_aWs4&5w=xt2R>{1{G^K4 z;EsvMJ9MKe`@D)ygsmogIuGBUwC#`eo>e!-67N^prOJf%za5PpAC1yIF71ZoT59RqGwg-Y1P%OdQPzpToDHbc;tcxl%Pi`9#mU22n-Ilwa_$BgQ)Pl z3SLmzV=8lk85vVt72}FHFu)@hG@$J5Kq;WXL2(DrjZ3)lW6$sE_uI)tDL#&OT4msD zmEy?fo_|xn2f0um=uF7!W+a!LGv^v*<1f7FrFinC-_Fg|n43HLhI)o_`wLG+N;!f z&q|uZ+u{wJ?rt7{j%_uj+q-eeVW-O`nd&@+D2N}he~jY%M&Ped^0^Ifw?o;Oi}|Y(3{deDxVkXPagCpm>ocjV zJN`Aq-GX7%IGGLTg}WPrU`8#I}D8 zpcd+L9bI+}QvrR)6?+H$b>)Swi9H*;67uEcL|B!_==T_MCN=CiC(x&xq;!=^#n=ae1TC8t*QkflP>R%xPQsuh%&^Py@_HZ2)6KA_94KX^`w*KCcCy9t)l7Rp^}YiQ zS2<#RDqhOMGN7Q_bs;25@b%1(E13jjmbfBD+i^sN!)E9_OFz3}A~IRG`t7!S9v}UF z)zir*$l|pzo_QhPtPiQa@hz7fhodiMxkAk=+RudQ>3&1}C-4IwhIpeer2nvX+NFI{ z$mu)ND;7J@$<8kstYk-34&*Se7oX((1`d!cRuPl~8SMTiVH^X&FrvYQ%JXPt=V0Xk z3dBzlc@;=h+;Sfs0Hl{%Qrs1uRJjv!!)Lfrb^Wk`&18EMbFDn z%)KC>@PgP(=lPPv>(otlxAX{vU;MQFlTyr)a*Dfx|G{AQ+wW96lc7R(YF{_pE|}@I zM=xk3KK>07e7wF71^!_IQ)TiKInuxSt8!4X3^UUxKQ!{_y36};EFunHRuVU0uvnPH#Y|#xIf)D+<89tY*9zF_^*WCdKZ9)eY+%{d`Y(_^}w=EJzB2YAQ? znkW{a_$`-iBTV|+Fn83L2(?e{&hMF&cm8??KmwBzqV|3!^pGx@WV}+0EGTiGCc3?u z88bqL_!<=x#ruR98ySz;iGS2&o%VM=+-G+n;firN^fq__asjLHU#c7q1%&=00v6MBojYe3AvYn$X*oy&9K5JqH0Y%-EW_F+uujt@{SyK zFhWG8HMFx|lCsoeEOu&Uy6db?JM>O@hadQVenUAF<uwmQRyMU6F7 z3DeNL)y8__DV_7m_FMY(NR(N;y<$N%!&rupG(gF zzh4~mfZW00v!;3N188T4UMl}_QK_l(?CYVPiQK8Oo9(Iyr0rH$$EIp@yL}k`{a_o# zPzLnEdl5!3Z2@|yCBRCq3fueL;=S7YOT@#s|2l4$5}!K)QBkPJ!Mik}fU%a)CCvBaO1qsNSN)(B?y(o;x){KSfiqC7^K`BAZeGf``Z&-#lt?? z3pCfrgd|nxs3a9`n`yl`ubsJQ!x=GVpZ%!VXQmw!Q^z;?Me{3cZTTfSsiFg^fr;6T zI{OWz!PwdGdK*?zk|@UH)^|af;n_FnpwZc&{B#y9)yX;haq4^-Y% z!4$7)_Tr@XOMh&3gm4^&I7WC5?J>V6e!AQ~CyvLBd4*zRCbb`m3`jCHf%QwWWSkyy zH9qOzPUeX)S@GsZa#J>UktEm~*EOGpil`yiw1#5PP!)>&(HiQPWi$0St)U=C7R(T* zX-|dG0ll!NcKZ{nZjWie)XEHM73BtK-z>X8%sTbTlKM@l#`;{Gp&n{fD1 zxBcAuO>yj8vV9n{*4yGQz!c=>QZyRXH-}gr$Gh3&=%6eO^-X`_7%(0?jOArNVsv_L znr#smU3~K`6Yd6<1|HBT0(i)Tgi#nWw_Jr|kcN3!qV<6Rg3InQtF~-g7ywtP86Xzx z$3>13HPzxodvUk9(kY#=iV&Mf*>G!LNE7dk_fxcxh*&sG!p<{_guX-ogxmrsgl2l1 zqjY{K4^axwb7u~8Ae6_`I9i3K1HxYHJN6452n+EFja^JS5Mp}|8+Ael!oFr`?AN+| zeSMf6EW4L9MnrDv8sQ z!!(c65#d=m%D$vbRboEehVAMH0{f{Ls!$(FQw$ljpamgvK`T3Gpamg<6@M6n2tJ;) z!jL)?mlFsBG_AucAb9JJ<+eE^<}??sdDJgLr?#DluBu2kUm8n=he^Vf1%j+pXl|#O zQn6=J~G5`*Xfg?{-qC}S75!$63_<@Q!@kz%*B(;j^=j=SPN@juFf z158KD!6`*e^@d>E7a|ZUr$2ZW7SiEIcl3tvs*(%7z9*cCWMxM#vU2+Mkw03ce!En8 za0hE)Xu;FJL$+>{q2T93SK=6Qu+|1qIHYd))TereWkYQ^IucU3!@Z}lZ8zN40Y@|3 z`78A5@TK;5W3gfG0SAX;kOkr8!P}DDy?q#>{2F_2A79Xv498$UR=hjbkHXPGS&|eE z2^VZip+LobP6Zed}SOJ zBRnRaLvK5vOKM=~*aiJ~-W_ggnl<2l{TmqW^0j#!h@jU!p_BXj|{YnhxhDCu`h&_C$EG-5tZY z3i9>|Hy~$tKNsd$i*<0aR!%4Q=tp&b{F%|(2e3()!_k5^*ceRXIcS>dlFHro8gvp} zOf$eMcf2Np2YpOV*k=2_22;Y|PbhIXc88dCXTMOE49*z*gC@^VnsUbR7@o1(2gFA{ z2-ftG?^AcfN1_YpBhNy}$gA;@#?v-yzsoi{1|$7BC&h91NUrv3(O2Wu&VW^?FJ+V2UQPkj<;DKglD^~@Lvpm+>Fi{gtFbs&78F5_ zFf2fRvKye&wtpAG{`zC~8Db+toal0ggWn3fdj?COX}iYyt9asl@QA2#`ojKw6~3__ zWh+OmDlE4+q&}K>2mP_f&ZUp89C)QfkYteojszT*f&pN~2TCTxo|rxru4_Qu5&!*q z8^#Petb}EzZa*XY(eS_A_wb?=Rox37z1@6vj_N~rrcF=9RW|0>eiT8l?-o7z@iPsE zBD+IiFV{mohgO`2kRGG6BNHODlQbUYil^@mzP5=@Ds?5jQz{D$ zY47%rA(yMEq5-U!x;i2#8Msh+MwRsUR&hOsMOV%R)^6cRAqGF2rFtN%Ws9{`(*O6O z{uLOb*vLTIig#d@E_WAwr?GznL=UMvdV!zAI|?XoQcygX2?Z*_tnUnq;XiI8$kt_d zyo?q-)FP-vi>Dne`bCRqR57?m`=e(7RJ?J97WEAVT0t$s@v{hPW06m|S}`7- zJw4#Uq94mM){Pm4GtCTO#o^nZQC-Qf+)m8M6H1ip`V}UNr1JC)v_CrW3je!1f5ZXS zfkqGDUWEM(+2;G>Fz{nO#8H=W6F46YaWM2wyIXbs7!z0D5AmvSFkzqaUWnFQlI-p8 z#8JUhVKiI0dMCpxzWK&qJ*?DELHc%x@%B$E_1%(3t{L*glcfreUaf;xd^BSJz@G9a zq!0_v2(G_+-bt6oXon1odZ|sulNnRd0(Rf(N@DB!|Q88k507r>Z*B@gUPQh=9){s}M@S z2lT)ofIdB*PJ`T3*>s*SQ&&p1beYrJQm}1X$jt_9+g65F^|Sp5Jh@sQo+-&!j{nu; zkJnto6C@v(lUJz*3B6cFRcaoSua;+eS%)9tf33`438(4`;IY0F`cgYWoXs$`=+I}w zcj!QL$n`Tx2zsr31_?o9;WCA|rjB9dZO}YLbjqL=&cwB!A``Me27>0z41?AgPL;^e z)VhR&hTD8fm>^QdEO)UL`yOD1-Q34E;VDgperG{m*7z0DlYDstr;1KuW@gQR5+P)S z;c-Zy_%6T2|#f1r2C2Q0Q5exUqSR8<;lp3L{OpmA0 zq?ZLrif4LV=`y6tHbZ7K0Rrf@AP!!rREP90!6tFI(jEg3gkPgTg?+)xI36;4?PMiTI)J3K4920us8yQQLmjA?bbojpY+y2y zHB6n0;W4X}ig~51b{mUCD!Lgg+>by0<&awT_~XW^GJo+4ZEDENy@+D}&)^^XMGUU$ z7e8e~5Mz)Yk!N$ppXrfc9GCbxII2aHr?JBIn&EUnt z5r->lYeHTe?-!?x7{BwfX#f!VEygotEB26h=XMX=erWNMrdtJ~o5*gq1zitJ^XaLR{91GSbj#i(@GC z2+FeqU5AesBdRWwD`PrXj}k7YuAmi(+E|dF)oARi3V-$Zcjx{&vP%N)YA7W><)DGO5T9y5!@W-jHSA%XGmUQgCYjd1*5!&=ItmX zEE$z&SWF>nk9qab=qIYXQZIbkQ|=9AGi51&hy*vTo3&KDrjOW!ZGT5Mg*ndA^NgR7 ziGne@5*I-iFXv=V8J0FrZJ~x_5@D9iv054T5Y2&4T(3;MxrmpVUmhSXIEsfjnx@07 zI9Zwyb0Qd(>1{!|z^`>-)6HC?X+#kk#DEotn1cl#RYdfdX}J;z&VDP%e8_Q%{Zu`} zDQBJuMUTY0|FjgJ-NYZ(M7bj5rIR8(+1KcI1kjig@~#oJA~(X6T?3{FBb@^5m}(_>i1IZ=TrmTn$-K&Z%2~6_%xuV(y$(Qx>F&_!{|m0Y zDH%We9_}tMyu%}%y6xr!dpZJV6Q=P)HN|=d2QEyvze+ZAFi4C#nvL!Kjo}(Ia9)t; z6!g?04K%As%^8a`vVvbCXO5bv9oJ)U7)uS@)P0#(bps?aAtD|_5|!HVGG2n>hNcM7 zWLOB+B5LB=2}nx=#Ohmd6Sb$f8*Ku9yX8b7SSo4{V991eVtR^6OiP9;Jv15#)BG?@ zoO1B~xzq7DB`dy43SqJKy;~uVU;oo2G+9|ncP&Y{7jQ@Dh zAq6;NsH{m|`QetZM0&dkxS1+`o#0ioe)Ub5Ks72`uKF7?Oe=S4*_&a!E|9&Ld2|S{ zYjxU%CB4HD~^u5@!yNFq`)4Vt50NuoZq8}U3T*S z-TqN$%jX(!fDC2`;^!C1pGpsSof(=%c&{VP(+OO2?5S`nfk>8}ELFEZZU3P~W6>tP zH$7D<2-%wW!uI=Y`?Hd^dPPGZllwLfg%Rs`7^^{9=!F#SmJ01tFd*njHI=H@u)jKT z|cItR`%Z6OR?%&b&(b`)~dIFzzT#fE?hqOMdI zxZ^$x#TFhk=Af;ZF}>K*aIu^%w!} zBW|^S6+oU$_xOQo56TdY&rd)}rRuA?+O(dB@idzXu`D0=RB0MF6j@@*uC=FJ@nkW0 zvXW;kieUd5f9Oqk6fFaWHOfG?beSE-{DNL8q_@#&dpMOV?=4BH$Js_=hn~^|h?!^) zho4}3cmu5DwYz<{S%N(2RF9Ul^dw2Bb_Ca|A~@q!Va+J_;`8UHA?^NA{rLU&13iCu`JHMm@;I5y4tx$MBr4}K&yAV}3W`3C!pAbGoKUm&H~8ZtI_ z<5z(@;OG(y2 zqy&wW=>Gt6%5zfQ)^1Df`Dn=@k7*8K11bN?mYF>ebUDWZ0~7>hN*F`&@6y$N1z0mC za@lYcM8Fy=g~V=&gLFoZ=%<>FeY@c|FGxP^pq(X@EWo%LW9Wc&>e$4zX`fdq|1f%| z&P`o=Q?ax?5N!9DP?*Y=by6y2BFSmWkZ#aLuXmdJwG$^Iv$-%m#ozu*_`^k6=nTt| zZNs{0Mou40V-PzxO)2x5&YZRTJzXM=M^cuqI_rBJraFwP-+;@ByWJ;*`mHpX<`ST^mN0iOMa z`|k%4+=Do%GlaMyVEr8RFgXP9*S64Z7RK4;S&TgUB1MV#3yz^MlXyzdtf4#heTiUT z+VQdb+mJxLr@CZ}K!|a+QX^@O1IE>)kiXSzKslU&q3teaaopj+FO>o*Zyn+34-jlK zl9eeW`3X{Z3gwsXzuzDM5Co~Cj>_gk4xhZgqf?VX9773Foq>rMMM5AF5+H~|@DisJ zjH7_ViQ2EzNHWp{(mhf_&t05YF+(!2Cwg@BlzB^yH%{6)13yD!GD8CiYtd40f#ADr8&6R3|>;<(D1x8CfZLbmU8&&%bB#{^b3=Ob+7%la-}`Gg@Pe2!>fg zLt-Xo1Xjv`+JWb{!x&IIv^OIwy;Lkck?wVz2MfX^{c_V(IF-C(diA8<2u?H>h9+|D zmZFX=@5$@*>k{sC}|+hK`XDYPhtH;!U7=xGIw|eFXj0lco%?xsDDefWKRE@q|?79>GbdXNvD5J?q6{K zs#KUIq_j7csn>=VO-g&Gb7!$)^3UjBhp%{BCxORP$>QmRx)M*^(vt8e=^i9_;ih!Y znK7a=e`=^*fGW%7601^dG%VLk z0s9A-Xt+cu>Sp<1GnOQ>tJE82Iu+cLn4Y+8VM5jz7C<#lO5cQY4swDUlSz$}AnZyn zjdWf}=eph-PyQpLa)(51Vg1Y%K&fo~V5UmS_SpbpW8i|x1o!s+L3_#`Sd?MgEA6pN z+ZxHh?`-X7G6xFrnE!9Ev6^8uN9^%-*)N)h9GTp^90+Vr%qhY^bJ@3S0P8DiA(K6sHoi$shK*Ja6xw^;;E%4RwL%#k4?gp z$5ivsq*S61MI003GgiA_lXad(!YnX5Z6<0Y17(ruaN4!QZ&vIN8{7z z)A+m+O$4GjG`b@+AAM_Q;@Q(Q`c}>0>5@%d3d`c3{gajr@!7%EOBM{t4&=eSoPe7@ zcic&cY9zA{D|cdb<`_)7hRxI^&+yY(yfxJ&N0hHd7F8ucA=H>HvzVmVCsD>`B}<5# zCgxTJ`_HhNRncrQbaqO}*-e<$KsB@ZqG#%XEutqdBLKhe8}<(bPvv5Fz(hKo2>gi7 z!We(=SmzVEsFeTjyu?jqNvHlXzeY*7qGu)0!#g2^8$>3^rxD#c;p1Mwa|!WUO(98#3UNnZ?L|NZ~z&|44cfAu=UwzIW zKoD@%qjujRNre0lGUsp(Wp;J@A0~$*lCmCgeSuZJIlu-kblpUL_ef$<&cW6?JI0`Yjnz-UZJ9u_WV?Qs~^Z1v<-Ee#xz1 zqFg`2HRIBybpRgM*MZ4cv8){lziVL*5{0WjfkeRd9Ld6x2)Q=+kyyF954ZwVa0aP6 ztisoUwU7K4ECyn^|E@09^#Z!Xzkl(SAXTnEKvMtf@i{wk9D|kl-;g_uoRDihuKqWQ z^aU;pdh*}Bny0fZQQ4u)Ykmw)IVabt%xgt?D(7CrUn6l(&dK#EbB)CPIrk#IR^kEW zei)@Pi`*2$M-Ca5|8Zy`V6nThI)YzUCL9LwcWuLoQI@a$Nn^ zE?hIMzr!^PKg7jC%Q^$f1s2ClzI7d1SYSN?dst`{p@F$p4=^FC2G=}`r@3cax8fSG zUWaRr#p9#G*40pM7-_tOZ&iTLD(gYidzr=auvS}}P}k+wFOh$Rl?Ms0v_1vOE3JPA z|2*q=Xhlf5D^Nk!*WCl4%?@PWMHTy>VPd~%*snr$hgA0KscpaC?*n!A8zcv3u$)lY zcQYdt4job1{Drv+75m=-#@P`~Q|kXX1j??_DQs$GL0#Fk?*9PrJ_&m7W>mP;{Ug-q zuUPO}B)pZl$RU_wOs!)&X=@mQ_JLTDJj@`TPlF_^x+f0v4BeeA~PaAhP_spzv*9K#4BJ(cj8<+aiu> zmA%AwBgeDrKauj?>}6cJvcc7NOOP(iru4GSGJtZ2>P$V)wf0anv*$)8xAVpj*NSN47s?&4!6q91!)r~JQUs|G0{9P%DVzcFB#;r!S79x zFs8ipAKsIQ=F@*pb5P#DM|uVA%6HbHU;)o3Q6OiBFP{>WQF)o4fdEJ#0(l^j%Dh4_ zI9B^C*(;CA{D4HfDsz$0_*CYT;D#PlnGJ+EDNkklgUcJi*8k7Q3a*eLP=GT+q3mFx zqyh!f55cgg(Ifp3Tqy~!^h0o!cx<2aL+~<5WGMHI&`t0)Zp!Rq4O*qaqTt8biXrrw zvhGD&EDOzmN*|>~EBD)3^G5f5Aj&QX-kgtCxw0UCaI;9GT*uI=V41OyD@eV~Sjaih z25T3wh~Gs9!9y~A1YCuvEZ87qAs3YyY+Ok(7ASe0(ftT{9(DHs$Uy{ z0{c|(Nl-or#6ot!9d|1q85B|j){-J-c`7p*amY~VGQ_i5(5$hX zMZ{~etfOd3D42!`(oznBKw9!#(Y-@B4f46&b~F<9fbX*v&hN52TX9f z6xc)Dtc~Qh(z@A8{;nmk?R+acTPj?cX@MUOt-5t(MmBP_6vW}+E4M#gsGwz)=QAgF zp>^d_9Sx<3RtC%Sb-j5jAzTpzSdeeIgHAnumds~KMhc{XE4^AI^o*2&rWWN{mk0CF zq)URK#aM5f7NSR%p!Hz7^a^y_vV64YmZg}&7CQ~eCfnudTEJYEk`66{zZN|hHJ2=9 z`NDJ*H51;bc2EgW6_YF1S|v-JzG0(p5%E{eMMJ6r{J|O#(DP~G%}Bb{L0nzdWH1M# z5dIWag#Vaqiy9jaG#)?PSac}b)TWA#M32@N)ixe0T3Z)wI@EBuXlwLfebL_5`j(=@ zjnM^=s;D4>W+ZuJIUH9<8lA($G}@-&kYoy{-QxwLyVJhwJKQwR7EuwHwy1 zbDFExI!L07ML0I{XanwIE}ng`rS^nFMkw9%^5n0Q8@aNUKe3o2+@DaKO)sj0 zA=JN2;b_~D`j*xr^xn~E6Dz}igNq)3T^@&NYAiMSGK?;wxf2Zs57)P$g2sk}n$>~Y zmU-AXbPY#g{s)e=wMCnhYCIkx+XzH!gDfqzZISgG*Vb`xMGn>H+iFpvN3_(Y>L73{x!zV;Q60H$S9PTNuIk9v zU1e297sZk4auL?ZI$Kp`>*mN*wtg;Z<6P7x6+P4%ImwJIWxFH0Dz|Nq>@KU=u{}*{ z3TxzscWzNy!;yxjgY_rXFrN1R9Ehb+*ZDOPxYLd_wU`m zKBWRdK19p6asd z?UAb8+xP6*zKxaXF?XcC7TQInJ1X{ux30e{tmlUC`r`E)i?3g|F}&tzUGuTca9?fp zC)d>8i1Z<(o9d%YYYsK9yPoOBXl>gX%%7Xlbq9fHJ96yk0l?apx+9x0!ydn3P3^Tu zo3CxHue&y_;NkF^%GU52xSGv}n~tqN8D4Yf(6OdEcJLaI5+eH$hh}>ESknpE#hSL- z1C1D!99!$Ihy0GMI~|R22JEq>hB_<~A~Lk+_HEhj9a}bCcl~u#R?0Z{?BBI(d-d+} ztz|n=UPfH~LG2+NyW3S(UNN^1H*VaR5@UwbCFwCsM6PFi^rX^w3hD$1+3@7gm* z(e&G}iP;UVD61~tx1DGyyJ!2(?OUrctabJD3>-BP&PLi|#Ik13UeasnUFo!J&)zLn zcSR~HE4C}4VRtyaOtUoZ*|Eu)#cr?MJxAW%Wp^rFQNzIqrvr{hQq47lt+#LAddK!{ zk=MyyzsHcH$WwM@5n>)zdabl+XPSGJY!DciCWy)s*y z=;27&&Z^tX)PdSo`di#SrA%vHFZE(0k74bS4q)+pyXtUsQ5J&9hK)T#YsfXC*zmeS0e~Snrf6d9Dr} zkK(L-4mH*u#t4{aW};`pVtRVHHs54}SpY_d=>hGLyBN%VwAXpu^j&(!kSQazyr|&4 z$IkhUM1-fVrH^N~QdTRRfgDZh0hX#heQm4s!Y)i>POs(V_pO%4M8<+qfr ze)V2ey{dZk>eZ|2p6+p`1skPWyv_Q;3(t+8vSQD!IGx4y?oo42=tZLP#AR_xx*++gx7=Ds%kgl5kY-Mg<13)5W2eFND+_ zi}COZN3Xs#9$FPm$X}#RvN_hgiTNif_wn5UY@!|92Yi)HKSlUes0%C}6C9glUkGB; zJia{<)nL=_#s=6?rD}u4KLO}q1AN0c9GQF}i2VK#Fs#)rjHhm%BB#i&pefinCUrxZic{kC&Sh%_1Cz&~Ej|d7YpxJkQtO?s2*Dj1}pV#W+Zz$X{$MNgf{Q%CCp}s1xh`0Cwt(perTKa4pu#-Lw zN9BY(XCcI)vXsLxNjfGG=TiVmAUN)6;g|+L66S3z1HnS@S%mX(0&Vfd7IHo@f4zmP zEWFIZD=pk=;WZX=Ua;IdEWE|S4_f$93;*51yDj{-h5Z)(-oir`j#^j*Q$zk$7S6Qr zGz-tN@Inh4Eqs%OS6j%t!sPQW7JkseE(^bD;SVhQrG<}Kc*H_&VR^vtn`z<67M@|@ z3Jcd+_+|^QvG95e|HZ=FEc~s7hb+un7=lS<`}zCyMk%en4Txa2x7QWfS%@$s5VT*;=TKF~#-(}&A7T#*%?G}F2!Y&IxYvC6y{IZ4L zu<)lAK5k(d6rcT^Y2hgr)>$aGJCNRHao!DM{sR_j3;BEm>60xy)xsJJ&$RHB7Ot@H zVhb;^@G=XpvXIYbk?(#BKWyQrEbOuHTNeJv!e3kXsD+0uEXUGFe$^J9W8wK0uC(wq z7Jkvf?^*a`3x8qZgBCt!Vamc$3mqIVv%XRb=U8}}h38nf%EEOPCM?`#;msC)z`}pE z@J$iguTi(uf`zL^%DZQ)7_FSSq}O+mhEEPjK9w^`U};TJ9Z zhK1j^@aGotX%5zxwQwqq*omKE;VUexv+yztud*;75u3Rs*aj}y z(@eq=cS#(-jQVqUry_o0VLivWq|2*7bQk$?DaTvX$7MKCp665p_Ki z4f}AIh+9#R#q$kNA^4Si*usS67P^3G4D<2FILxht6XjckRH(^w=HoVm`~vu6AisqY zGZ&a+2`|SLs;%k;Q|cZ##Po^SZsy@1>syCEKR@~KPT+p;+2ywhbU(iVU;EfDm!I+93;iX|J%t-s7sH3~=dbtFa(rS)Qq0B8N59#h z?*}Ky_xlO?w!;BD#mCR>$FD*2_ag#FjqRsg=rg+gcoK1cy&XtoU)}1?B#9qz~+_XiA`1=t<3tT{WyC9 zzcc;`zJSXF`P}I03HgF=H~KfR-c`uwuearng8aB^a^-jB1b(x@Z?`K9U%h;i7XR@L zKND_xCw?cvfv|yT{Ayw_ zzBUlJkAT^ie#8LTSJxIGs_y#$#+MNrTz=eP`tw~6x!mX`BF&A~EIa3{v*LxY^z7x! z&!}B`Htu%Cm)6$S`mSd!UmnN3GSV2DN?TX0xyU@jVk&o_;VxfN8sRe`gpJKQ1@pL4 zT}y&}u0QZ7kh#>5oAAfrI7QzT5ZOf#2>(t%aW_FI+$NxSB|$`(JCWimfCbI-_)e%8 z>W;L~{RB<~$^{VkJb-cvPe}#FKV1|oJY96chj&(iLr~S>`rHric)L*lqI#Bj8ezhX zVDB)P_c5N=89(_Pdw)kL$C5qva-=F3$;8^8>#W$ES|8^okN@ViaI=THg&Q(|r}tO? z*B$y%Yw_oXm*U*dAGjfH1fc%Fr{15AIdh3hPAvXH(6(|23A-$M2}K=biJedhlS zjw6~)i%Gq3NAE;FA?3(??mBRyd@s~@1WO6z_f{JxU|kFoeaBj?vp0gyaYt1Cs0**c zpIZh|^(FkB%!mzc+FIaloJqgHAAM0bxM{Be0mH58ZNfdMjPW&bYhAp9$n+ZlX;ix^F_h16a2&0?iG~!#}tj91G7E;91f0@def+Umwaw z@dtNP`f)s8pb8ztR@4h_Qz!ZYeaQEIFIPbp@C9CRhOF)8^0)T|R-#om*_J&&UqI%9 z=L;-G*}nr{;GF071&&?Ig>o$Uc{vTN@E^Xw3whS+AHKj}$rqq1BG3;1!x#7q50N0l zfA|9b@CE)lzQ8M%*^Rz91JCUXEIY?|4bOcpu=Baj1yWG#x%c97HU1dj3w%mIM0~+O zmHF~td8{>N#-OY?}(xIN9^?ODMD<@kr6@Dki? zf_3_P^Apx!k9s58&AmIK@<(0xYo8hX0+q2I*85y%2J4Z>4enlh;+a7`5 zn|NmM*z-Iyc=_`@GuZw-&kXpy#zMCfwrxZwo*DcB`QCq=d^O8nai(4PpO>F-=JKV> zP5$Th6Mk{OROsD5n5X9YT42rz3U_%`dbU0F~R7T~(xMcFfq-B&!j}ZtaxiT3w zrUupb6=muG!(L~x`empnN%q1SH0F>pd#-1J~+IEwC-W(K|;tSEKT(4$KH`?*R-RV>5TnK(!u zJsIbGQB_qGL06Tqa&js-k{%9HIR5t%s)tarJoiS2^{BLW;}E9wW*-^> zX}EagA!sq)m4UesR!5#yPaGXSdL%ulM+W(jGAj*^8=j2HE1glJLqpom7gIxk)!UZf z=l`sfMaQ>$q>w|>S!RT>Cph)Sori)Ih0@R)icpAP>qQ>2PhW6us?em%m4HjhmCd}eUK_uB7c z<`sGlF`@?lNRYdxc9r5?8$;ooKAKVKOiqoV=~4$6 zE|=4}w9&u}Miv2TNYUidxh#f0G(|%wxl)xml*S78Ou|>O{G-7n%FnFo=g z<~T;@^SNhp#_Ak~F6u!r&yO9!v|-&(Wd;ssM~`Mk)o^xTOr=LMBT$Xp0L;Cp7ImrW z1iBQOLJkF8B8FgwDrbx_d&mwC^G`)ghpBw1Unvz(8gSHDXYOVnfe9b2O@)2eaYP+>jc2c5DophfqbdEc2Lp zY)qvd)rUt12I2Fh(JzHQMFud~kE_hkXzs|-fgyDyGc*DjC};X8;wm#dG&uNddbkud zJdqBT9)5OsAeIUIe57<}^jUS}P&$*%3?D(yq7}J^)FVUX&nAachn^UK4U;hqr%Qt) zK=3;Td=K6cEv0HBgrW{d9Rns-hi@~Z_m{=p!V(7y3Rwt^bcCq5Y9=n%M^q+4ds|yH zj8!z}zzj@(#Fw6&e4!7+j6GqXy|7IimnTP~0@VqhKb)%Fc`7CZ?KnJ@f*tX! z1Pqi?ze#5gNex8&;W-LC&!~AY{IHgzDl<6D zA$^V-4jQgA4B&NC9ZqMX*~~Le&dCirWlqQm9epOPo*fxH^o$xEPN%c5!z!nXRdEiU zkuT&p@dvSb6e{I{QV2*FHA5dpv9gVhC zS_X?HHG;YkrZq*^{4>F{{bBz8MwAaO0NR8(Y@Wb-_)pH%C|v0(jJ}u#lYiVzOha-4 zJj)9d6-P=+OG?YiE25RLN#&ELR85_V4AZ91m^ppsO#aOR0GvKEID5|Ax$~;y^B24f z8=R9)UbJYDT6FR$r=EQBX{Rm1ztdm7m~Sho#p?}AmX_FxUnH2=Iwj4UJf*y<3LK}h zdDCXu_RO6-4NVFzoOcr1bjqoxosQe(ia%22>B=;7F5TyqquI)t>50Q&*eH#Or|wC8JJpx^PU?SBKSvR^9hg2abD(zM?16I!E*#i7uy5cC1Ft;Xargs=Z#(?K!?z#)_2EYjpLb;a zk-Lsg9y#Lk%VO3z#Ui1p0d<<{D=R5+$}dx~sT}KCr)%=0xlVRbpmFAmsg8PCu%oJK z8otpIY%B^P-=t8yG%_cUey2c{J{(fzc=cQ9E5a?4qR~L;W8niu;SwkN<#1bBNzf_o zBaU}M{xsZCS}{lG-d&`sCWCK%al9;o`fe|-pEL>Z;z;eJ7+@+AtHSH6)YnT4{p!-T z$&-N3EgO)02g(|!5Px@h+vLf}UtaOe4I%KaMGgNq zRjTT_vz_#xVgpmBPu1$zlX|92nHp4`lY6FCf$v+U^v#$Gd~H>{Dh4=Q6`N8Cc>C1a z=}g}`t!W1HFPYw05(2z(dQ)W-e4d`(F_rYM%s4QK`7fQ>HD@~Dg|kflve~sWr=xss zcF)wwpnr2t?aUdooXnBA2L$h)2e~7CV|CXg_NzMHH+>4m=ka)xwDY&~`{vIFefi63 ztEvEt7Pd^8ih3Ve*fWLl>^ccQVVDz42TtxNjn2vEzJD@tl|E%r+oWhkAoT7#y=>fux3lVZR(p4w71X&U5xTGQl7z&~?ZM``&q zrA|G)hxGKLr?*takpK3VH$}pLKYn>zq;yU${kp{%C*YHpG(|#y=P&80o)ZhGc{Run z_=%d>6!JT{R_aS10wllBEp03>Mf%86v@eF|K9{wWmt$5xzN}HoZ9AhcHaVu%$Qf$( zY^3)u?}+h5^shS;^l3Uh_pGkUDEPkrthUmUIZnFlY*iA39L_wOxJrNJ?3PKDVJGt2 zvpdSmN}aOUIV~l{MNZL4=cswr)jC^ru9`P*I_B>y0cWfH(N`J#lJmQ&rlQ}=>ws6Q zY=DS}#F5^8IEl z_=4ZO#`;-RbAq|EF0G$6JFYU1tpfz#%hns%cezRb%@y^t=FHalbyxOHo;2IZpL3Og z^ImWA-TVf?VikGn4W=D$c~jd-CxidD6Mgd+qJM`rpx!wu*RiR7)~rb?xNEb4ui1ip zXy4>*rd`);H|>Ab)kZFJcN+fh+XV=Ii<=Gp(H20I`{P?oxwH57O|C*cyY`uUv1<+d z%5|na=iZ>^#gTs6KS3Vg)BZNpJ4fX|^$x%)ihM3 z>u1fVcCxR%$?$*neWsoLw;&yI{pVW^|0mmP=T(DmccwGlnQk9z9c>+L9%&v<3^xol z9IZQAH&`=hJ|uhkSNe0w{MtvWhgJ8_bYp3@a!7Ue>Bf>wS)GZ$^88V=xP=^c!bP-?sm5_+3REFHmdz)?gNEa=~}V1Zt@pul~oz`YU1V*m=> z$1*|qC&k8NU^6@0NMyUq;DR8q-N|~1s^Gf~RIMN~6r(~3mhk$dK7>4hBs-CfeQ|sHM*Tm`#@ApL>z``&JaG`i_J}$ku9&0iA+#1%Oo`!7C2Lg>o>ub##8Xg; z9LBHKqnFE&nf$HHqUs(7pMZ`tUaWtjTgpe&RsRn3jrx14y$^5qH{%f0@$N5&g_Wup zb}(v2%{qIEP;KP^iidP8g3J|YmWpEUig-EWojuaIC?pli;|0-ZULES5M?LJX7v1UZ zLVQX3PINMiEEvKstQ6KzxuLnX;Ty$ULlHEiE^dlUsmEek8;2P zN~6;+JFb8pe6wyMO(ncf)i2f=)&orj<64PzXV1i!$wEKCwHTmf+z+CA94^TW%vR>5z>QvLqEExk^_)E zGO#h7=y^NlcPIZ4Cyi;$gS;%mvgE-Ak!SKDRM(yKPNCTlAGD1HvPE;K965<=+H7bTL#5oLU9^|!BnAwTeE2L_fwD!xH{g4R8 zTr{s3ql}R38^r7C+ZCi%S39Kp?9PqjmRv0xKrnU1c@~kNlPiU zTT(fSl)<(K<;2K?vc%e6uQ5>9E@q{fGL;v^t&*b9Nb839&WIz@iiT9PQFZw^de8&w z&oLpXT(_}PJs8X}$|Qfshm%%n8Z9)z^e1SC3v3L5^Ax-!OduIS55VF{KwUC49b*2Z zKtd)bSC&S@fi{zYR#`$XKCp8S;^rfq9eCvVj*p^AeUj+3+i_9N?lcuA1Bn$b13eIK zVdmznO8pYBRX5dX{rfNS1DvNzyTCN?Ps#j!ab{C+jDA>;v5-M&qI&=6j{bva;aChW zV}_KhU^|T(dV1_hp?TDKTk6nTP;x)n{|Q5>pStc7dI+q#Xk!kxO7qL~7Q-tsRxLvt z)LmxO68Lyf51LY@8!Jqa0~mesz!Z5onf@H9p*zJdswR%`9|q`5b)I_t3H?r~#nFeW zMFU&Yju4_c9$t^)?z~e;EAj>`hzw=ANnlVP6sWrGAi*URLWBz*gFCldttLe69QV|* z-^!}Nj*c;3DEW%}^S^6^%Js6*=uA@IbA2~@*P5^8)aWzT0wy9Q>p|~exk#u&$6B*! zLvP*a0Yd}-1cCj&>W}%~Z(z1_{+Ry(a$)>zO0WL<_5I*oq#wW>z{nYu ztI3ONA){v`U#jtaB(jL=17#w+PCXFRnHBux=YaXr(-0!TUfe;gMFgLy*c@|Q@rT{% zRq85xjU5OlIfl6p#&72QZ+-gnU(&fag^57pJN?_{3uv>`_&QU&zBJhb;xS=vCZdPh z^@`q(KcBBGU969`>P!0%7iY00syqzu^rZMWcA?J_ot~uN@PWGjR)Je}{(~xvPm(rb zS=GOeA;H>ht$#(Vs9&e+0fVrH?*io4e7{0?O3J8R`0Kqms#ZqP8*9-+co&1%suH1|RwA9E?O8-rGB6I<;{G6(7-A$W6AKmE^cxm_Z$e2Yoy z&)*(bRd0hGLkJt7g8iewLbjDKu0R7+?ZC>oI;oMaQ-2?R#DhVGPt|%*HQ*zC{otGF z98mo&Woe{mFAcl{pT5E!T9}PiP#~fK6+O~`i`a`gbgTD@ELMv)B&z-a6&Y#oQVE&H zbk$mKOk?)dGqHU@6^|m(_;IC3Y`-=OW8KBX6mB^V)eT^oivw#$Vk(Ye4V)|qSe@nr z+%k6R4_(wdroY!Z#Ma8N4P#G-l-@p^nI&`YQZrM(Vn4gU#S0;KdK!u=p-Bb}Ci5Sf z@0`^Q(MT||1y2)#H>dRP_qZ5p@=~x*LL*GT2HP#~U|$=vC29)am#H`!N2Egkv0SyqP28ISy z8m;1TQLMXI5Q1(}DXditiJVGgO%zLw=LQz(z9hNjU^46nw)6EWIf}||h8JmUsnefP zNfARp57-qwsx1j~#gbab45_L+AG5r&abpIxejM!IvvupXo3+O)Icf`nt6`5ki%mDc z$&zaDy|y?TK1cURyRPrmM=X1+S<-s_yGH3+_)h)IXBacS++(t|<-Z9>r3+e}fqYMe zp7omfdR~24+cnpCUc#aVYH32kE~k((XPE@MOF+CpE95Jb6;Dn|6zV9{i?*a~Td?%n z_7&QU`F*$M?pykH=yve2{mr49$@Cp}eDr?y$Vd;yvBw>XX5D5*is==%0)*@75}_O} zG3rSg`sfl%^_#5teZ)deU-1IZLPcKfrb)hbQp2<~o)PJhs}}=FlCS`?UkDv;Tb?(R z;!r9Vj^P98H@?Re$@7P%{tp^HdUyiN3444C(qy~SQ&SmbSHQN>CqhjV?O^s8Rv$i5 zW@C5$d@3sseLVHdXJd#MrH8Iksko*28T6V;KOLK)ZexsQw}f7_(x3JjSLqwZT%~Uq zbG@L3F<0pu#&7^7Vrdw2>qX48B@Aatl>Wc)VM@2nX*Qpe7yYmzEZ65*5%&+i6eK%* zgLYUo*neIWF7=YIk4t}jO|7K?dw&0LR)H|=f|+Pm((GQ_UrNwvnDq`h@X{T9q&yeL z{_a4z&fby2$zwO#fMq0fxBe}RwkV&I95L$WBu5R2uC5{VV}+7jj0g#fgdz2Eogqmg z%w_iLAa$EHE_tL|%Ys;;d(9~hr|+4Xb{4av7JC5lLgo_gwJP8xU_bPbt+5=7rfI}H zSV7ZNe5%-xcnoStJ`-q@Y+hT~ax+aub$`uNV>I3b5hIKy1?aZq0al9;(rM5dg!2mzNT^W4A=k8`#*Y}6 z8%Yfr&-DoDdpvR?e6!Z;OQHnhl1-Hqq&q`;Z5I$B)YLJQNg=0gr>LNnPHtQN)QVT3qwR_<q{zRI*|U$RRV zZkD-bx`@>>;LOlOI)_T)j8$NHyA2ShYOOl|jhp&0yldDl9M7mA&L}vyL@_}c@gg_f zamStd8+Y7sJBpecw*PA*l}3>vOlybgGJh*lmp!*hj9IxybW3Xnl7dJF?NM=O7Ndz_ z#m&2Vh*Hx*Zs7^%r>-*Hb#$Tdi=HmkL4_B&QW9%m&Rfl$mIf@WFb!QSpQM*#Zp6S2!pL)pfp@E{F=6(U4*8v)M0t*uJ2t=Q_~ISVOM zXG{`q*P62mObS+v0(Lu`N=gabJuoF2M&#Br&I(M4QoWERSiqFfeR9Tx0;WV_L~hlx zfRrfJu@Fi~0Vx47u|y{dNQne`07MF~1n=acgeia$a@dX%Qh+6Rix-$FfD*5y4G8K_ zn-Nj%X&KsR-V{KJkx@I2$Rxl$MFG;g458iVLWO3N5CV4Z(=G+dO|~L^z}}JKad<+< zk+B~wDWPC_j81C@1;~?kjjp#hyo&TgWoA%RZ>HI32kbvRVFoxSjV1=m5jQa$QuUcw zbFLpO5pYWnEE&W40+x(nHoy!b66Voo1uL0HW?2Q53wy3jRErT~2 zXIm%~D+p+goe-d=%svw_!<#wnjAHBs6EVyZM!d*s*(Ba+k9s{{DqxSrA-XQs1Zi4R zQG85RcQNs@_S)`6+<{Ek=^3yS5(h+G!qje|s3UgF6Z(hJqL1|2rsljzQtMq%*W~c! zi=lh)-T7R_O98g5v#ibCe`u{VE@ZXO+`6~V4A{H+_HhDO$~f}|tYc%I1yIe#NL9nL zK`6@$uul*uqZ;<%0@Yxq)%cq2BMJ7Q0k`HFPHiZ&k?sj<9&FY6*I3L?x&pdgi7|VL zzyp^z=PYYX%=em>=qADjGb4N3>CgrAOwO*7bbxlG@~Ax3)_g#okV-bG=n!T#hC3_I zMmaiOLs4~iwD$ot9DdLQ42Og{R1>-VEO)1Z7zsS5bqF_b-pur2On|3u`~)o1`Iy?J z)-bqt{JSYxXVOgF7`T(UhhR<^F4d!POtPV7T91f+ophpiD8Xj8>c-UA(yDGf6igxO zZ*XpKi$2uSJk-F<3@&|8#&wm*kR57@$THHa#O z^Z~m}rVcl-Nto|P3K28*Nb)ilin|Q6I&%}wknzM4E6t(O5%l7B_2f1Ee!0C^gappT zcKy^%N!=nF%`g@#(fEs0BE!6}qSpNM8dqJm*?zj4&n+hpNq~>bmy5JnU{LRUaTZ0u z?%YIbY&CzLa7r@&Y367Jt4v)6TfC>^mwDt9~chQFPIquouphV|(7KI=Er7*daL5#!!ru4nDW zBUZJB{*qnQDfdGbxKqYDaxcgE3-qWzpBiZAWWqs5we)bV9_9pAa0uL+;u$k0QQd3o zo*p%pvradNl`O>`idunvTR`VFIA>b>@}RO;?tyV`$qZd;6PSLRW~D;LcJY z*9bv%=OLZUM?R*}h)x#G*JC$xw;X4<)A#wq!245A)nfv;f>9bCjDG5)Dc#YaVcU!K zkp>y;?$HL3enX~#jmNWgX2w?MOg%3iE`GdB4|L|8kJgeengQqUd0Zfc{tj9g#9 z2Ra4S0YQ#VK`3P>K`0{~IdJgaLjvw)aByJtf0p3HZ$Nk3VK(KSWG|)`nL0^6P=|)` z_=5z@DN`-#d8lFR1^gSqV{pI06#jPp2jD%@34IwB)qR*+bKmtT-L5}(gU-hq=t09M zJiuGgZ4I0n|9i zQ0PDrjOC{$)VCQxE5T~ zjUIsa3yR2c_Gtx4u@jkUyR2rptTs`ac3DmMmQ`^Eyk)hT&?DdgJlZhQtdBO}_xJw|M+(xQz(v?1Xc4l=<9S@T zvgW@IyO4q;bQ6}Hf4w1j*zEYu#5|3&bE=yQGZj6Bc(up@_OMyGiao!Y5~F1AB})i(uWZhJD8CEZB*9s3U|gt4s1A$o)rPDccZ9jAD4$ zQ=E3xNGpnUQ>XZzUlSg|@Ok{FC~ z)|P0pF3YKQZdEkP;KA|$TaXy#WNAGjPt%v>xHIF=ADWLs4lT$YL^2-^YCp{Eo#-VV z8A1;12xY_9fIUg0N*oQdli2NbA4CNmyrR|`7?Toh_KrV4icTcZzB&rFa}1{;AmW7194H3#m|30Su=jz^nnf&-wiREeEKy|A zKo+VdA8V&zc=HmKpl5B0XCrbbf}?9Zu#Z%n{n(q6u^mkHk>Ve3X(z|q%w2H72rwA+LBu?&1^2O8*i}FI zR?}@RG4;%8oNYufe-MsZaF#r*)W;m=Ov^r2j`MladNFitTpz*lGIWp2p!eeu!gc*p z!>9##Z8T;D&cZMfk2m6xe$jF$3A!MMd&iGpY~b)T!WMp4Iajj*l{81k&+PG$M%Lx`L2ugr zY$-CtGsA(avCy{aF);r=I<_W{QgvMo^rnhOE3y}*;B&3O3oI~DJ#{^J&NJTu+j0E{ zyl#y@nM?a^%aIJ-mE>u6+#(aPnP?VnI|7n%gC3!+lUJ4&->k2isByHuq_a)%r4a^@ z3>$+&c(~HNktMV_Kw+f45c=XDZubzr494LDRubyf#%FDt$fQj@tG{_SV-lXaOTaJX z`QO(|eEqA98AYM5uEcsHKiUFw8l2PwRL6L*%)kd+rMQa{c^11&Ne%1#vtSj{>AM*2 z23c5130y2^AF8jtT7P!|!zudvTP4BI`6D-b_5S9@=V&DBb<3h6{geB>R%L%8oO5zy zmz4OjMFM#F@&bJ)y6=WI_1lxLyY5;Q!Y{TYY@{Aw^I$`sut$d5CB1006C4_0IZY5t zD}p@kr4zXt=i0nj1rc7NW=!bdq8o2~Z!GL;)}9HCIfto5ZtA;PmPXBlzg##8mlgJ) zI$zHzAOVK35CTnwIAV3Vm=DKL{>+EgaawwTvl=+?Z5@E=Z{3-ldzeT1$Ft;Sd+}{Xdgs)tUL(kaZtT<&O=w*QbB+v%je#Yih~YO6j55~Z zFxtwPVw9l;=FCJ9vr)#BlSFD8W5UI)4Mev#8%+SFyxQKvDtxtZ#+cehlU{9mCC1wN zLMc;QZ;wV>+<`^2%c4+|!%agsst+sk&i8llek88u1@q6afCXJ#{&wJqFs+*t!tAc z44KwP&_8>uPR2dZTR0#R(6?H2M$WUuZ-Ms1$C4kcOb0xGT%CYV-@(NwPuUmT1e_`% zycr1$oHqzgyI|RR!EkwfN^9{8T*BmWBj{2M4Bq^cduj_Lw6@^b&?!41I^R@08Z+M& z(k;!>jNxJ)$Y7wna1bY19)dYR0r^6_&^=PyOwsR6dZXky5KIEHr`>?LT9FkvN)0W> zYiI*X5yp*GX#^Suie^A{#Az=opj}9%V}i_-Bb~ZBz&}}U3qRt9^e|-XIV!v(DX@nO z3jq)D6cD<04L%esBl>ZZA@>ehQt!asXofcRKGes+UixhApOG^%^FX3QikVArCHm$M z%YZCj8S_ZzVa`FyZ7u<=&&5ITm~cRj`Us}CZ}D;jk~+IEr86F3Eoa?gl(IY^?-8}1 zCeso+wQiiP+t^R31Onh#DV@dXD13RuG9ZB7#Zl9;WIaGF#{(23V9s{K z0`SjW%sP;BxL-dINJ$1bc`$CHOL%ny`1S=`jFV|-u^EsEhu#fw%H#Ni&t3O+<|^dC z8(aUn1c-sAkUbI~nQg-@O*GjHY-*E-$z-G`ZQ$zG=OSh``N!FbIv3=q7tBvPpImO|qA0rnpIj^LgEM(5)edk&Q{#@c@42 zzl4z-FR;D~Jk=roC(noydmf>qy{XriZ2~GOufNwH_*0(1$1LTZnCW7J$Aaf42pD`D zI3>(XcPY}j25%i{HBV8byjhKBKBa`GJ+O8t(_ohtvTJ9VWMSIF?4)5$WL06h7|g~x z&wnDNQ$N(Nf3b4qg+yRgR^oP;X%ahO1_gG3p#ubCuCs=~eOp4JmXLwhoAeVT{-Oy5 zaTz}8&H_J)4bfEkLcRqpDukCUmH5eDc<`QjS*VG=mihCy(O?3bZA*7x*M{AjTVt-4 zD97)ft+(Jh1T+ZvP82y!ick_}eLjykb0wA@VNG{-wT5XM-K(@n*Yw?(8cRaKp0<+L^{40HA1Ku@DO6X-s|g>yOu z%~C4#=$vbS|CX3ain<0aoKM6Jr$~}ok{7}fJwS*FZvjzG|67IYOLFNqTn1LIT-k~! zD?%TnUO=K0p@jm}t`-CB)wY?KZMQ^iAyO?L6E(a{KbX<>h2%=xBUSQ0kd}mjfIjMx z%k)8)48JB}plPLc#y z21J^TScE=77DDqb<{rO?V#=7ARG=iWBe21Uaj|E#0!BrZoKZ55XhY~Wtd|F*2rNH@ zRte*n#O6XWkWdZ|b#k=CrGa7vhZ5c5lQSMW!cR`DKnA!2OdZ9MwM*dRlFehPb=W0< z1Aa$~yLBD`w;#)S1H&WWvVwp{H zdXC-4IVmP|!IalZ&)8zHF1MRJqFqQZi8T1$q6{ifD`&Ut1XTZ|5LnN+&^-^zn)gor^lYrRnO&E7^5y1>d6J$5lVxl#$<0eMdW`c+Wjf;ZDn}uGrGA3N>Bu2Ar zR(~pmyYLQM@gvJ&_S}TFIyc6p&jwe2f#MBsHg8&I&G>2kZGE8HWKH+$Sg(n`SC4YK zA`D`gG>U;oq_JWKk{~uZ*j=okYmBG6Og>rxNi!P}NCrJ_k}iio`ptJU60#erP^?ZA zAL@W-9z<44^oWTCQyNbKk=B48;7E+lkclJeW$y3TQv) zk{c>frZ()t4|Xi9;EpVH7Fuz~J@mn1JJaZ>rym(w>I!KLG;*6@akaV1&&~3`W={ z?h4yt<5kZH+a?)dyQThbB#E%yE{m{TM1*Y-2-~R_Z4a!hUy{QJ@I>}#v-$BKVy$Lf zGBKVJn3!(zVwiH423zFD#=MyBacMg1#dK0Qn?|sX=Z?L@EivqIX>?=!rH^pQ*SazM z^wH3Au&gHb9k=!3BY@Uyyg0;4$B;(9Remukarc7ah0vbyp;&$T3Q6b$)@mDy*q<&J zOAs?Pcpg=YNvva%cv`^SRTb_u!aS2?4pN<@i_uLorbZ}eaIcr7`P&>{=&ST0g?H@< z@rbOaZhDWpx^TpDk7=8Cb*^{sumQ&X9-@9|d=29;Z_^}|Ou&p0u+<+4CEbQ#{#((w z)$?V%45jvd2z)8oWdp)|$dNP0n5WDy3Sz0Jza>Wm=J>469gx2~V$K8VOiQtK$j4ce zQj4TU6Spr2hU;y5iUyfTjT=Eb4COD6ywsu-k>hm5Ks<42J9f6OgDQAMz3D2i=w3$w z>vmmalAu}xg{0oXp8YRR;%^GTkbtKuh0u{I#I=UV3t{}S@v1@serh+JKetM1O@JTP z{B;{o_Pu^-!1Np-(S+H5{BJkvgOGC}ytrN-mR_=p2&R|#2*gcyy_cSl4bI!87Cu!Z z!5%m9)lMcPFfaf4WqhpX=R)9Ks1Y$*suogu?GM!za`McI)~!~BAN-&UREO-SKo8K@ z?dR0w_zehQSk4V=t3l{78>Lt!;(gt?w1ro80yL7H93!+C%OxNKMm#QHXkw1hI$X?M z6CI~TU~(y;pOXnD5Dq*T9(iapMS4gIZrkIBXEnf;A=KJTAxFMCH%?KW)sWb{<5n8 zzH4dih&LfV3(z(mCkP?{ZgTD23Eu5`r05T~$11!lckOZj` z@dHNf04S2-1W2_=MoHerlXJJ0mx>2g?4BW)4;7ClOl!) zL}Jp+b6xpALNO>3$%O~@lVHP<>Ndh8IrvW)|27c`^lp5BNG6`?K_srMy}b5UyB^NS zYvL{%^kSA0NEX}~L&7v^vxycY3g_0AlJW##2{I7%77hH;_i@m=jKRA=@HuaLbFjfw5St9>=vt$dLUO0v;@R40eam9*7#?zHvOoLV})R~ zC<%(KzZp>sLki%CWU*#Kwsxj|={FPwS?pA(k?0?ODnRP*mFU-Y36Nm3-q^E4r#{z@D1K+iFhE@`os0g-z3Hv7X;3%)0P zwU=P6A5)3(`qqk>>v})={B@jMbMcPDZ{GH zB=pIl;t*$NJw8c5rt@?QEbdWd4^0D4&|z+rw<3db_85E5Tr-BnAL7W`xzLZ zG6eQ07bnABqJ50nV0%DI_n6=d$jTHB9i5 znBXQc;j_S`6cW-jjV#54E?Jq8BndJ_p`MZ;mP^;#1e4Us5)82Oxn{630WtRlt4!)q zSJ(ulF7jd$33&Z-?ysNcHGZx>3f87ys6Cf(8;{z@xa(n(X;!OAGR-ncZhIxkZ7-9S zCf)WTDJKSitzeRyU?!#85lQM|9to{p4}rSx;xtKx9-h`>D21#0hV=r4YhZ^8f5B|n zWQh(!oyH1>bj(}FW_1{CLoDW6)iI-ShE%8X_~)9nZsuy&kLs~b*AEv`U4DVa>3D}} zf{=pm!fzkcwYE`0!U6}98(t)75*9stqsYe#uaE_)zsE{#?pJFgOaU@&F;6k+UVDr$xpHgfux!LE>1XiVkVmy*v|cO zt(&z$__|YzUL=E?Y%ouGEo$yt{HW1I4YWtqE)gU5|5(U(kL%F!ZppY(^cCtQ9}q zjEM|%LOV?KZ-w$no;^}8zy7f?i585|I5f550&9i~?j&C3YA0|U!Qxt0QK|JnaW(#t#fO4xx_rVR^fy7+|5Gvj0LmTXt!je$fzoK(UY74p9v^Jv7 z+vz(H?IU`sK-_PV1IutPB3<&_6|Ic1`Flx}&5QINh(*06!EQKOB?%WZF+wid!iv1R zG3mHqu9f^Zi^)byzBFP9r+xDy>)bTLzzy#%pm2@MYz(~b-O^0@M_eYy#0%u=K`-(`vEaXqmh-rOhQ!$7P6 zQJC`}=`jK3v6nQRUnUQmEoeo~O4ppg(BxvC^{9ph`jhlgf0AzYmBQY{wK*t-B%>0F zQ(v|%fF?A%5yImo;j46or0>YIBtwLQ_7KL~*;SJ&NloZGk>eyiWFL1hb^Tl>y)C74 zNfy$>DFODv(^At51{b<_9sw^zOJ76?_*ks0^>f#C zer$X**7%bkh`%_{dU)X>FUH8YE+6$tP3!q*_(I%&D;DCQ^(ll0`U`QyXaWCB=pL7b z@0IvNi(2bLA65VD^m;g-MQZ@JkwC}jVkPBC54|7d%Y3mn(qrM`|RMNezt2 zENy0tr$cBnf*d&YGIoHpBx7xiF(SSL>;igBQjoDce*JixXKL^{85>58-vjKRrzlPI z5E=MhCKK?}^q)TXU=m0dS;_)stRQkov!t=o7}@_eN;cK&d06ft8Jp8#5{q@-@W6WL zuEOTWvrMn?4(t-1mo~@RC?rp@MVZyH)$K|BJ;y4qSL2`%v@ z>1-h>eAiuFUebWAOG@c?Em#ouk`R$6YD^LkthBbS7nGFrmzsnJ2ji_Qj{yHe+%bcR zm|IQ!cuDLs1DmXzq{K0+Oqgt;fW)W|!<(6WSijGUKQ)D2lAG2_e(q69w=lOmIZ3e- zM()foQN~8RHDZ0_0&XV6fz-GNGs?UWLJP14H;JwECW@$PtDD4zc=JWnDCs8g(8S|T zZT4EhDO#usM-lc&!jv5UC=0z#FAO$&QTEe3X)YeXe6(X?=(Mw4=pmGB^Kzicg?WP` zBX$?TJv%ZdNcVoD)?Xj19!&A-3u#|mq8a!ebB9zl-k0}~ld2EE_~Ye-c(`XkRrjg> zm^vOI$FJ(5NZmnvv6n?A1QPhG?G%5;jsKFPOC{qDUVJ^wNzEJ`!d`{x{~w?5<(H+_ zE!4|S9b14^;&`>(+nY0e|1bUfZy|>?-N+_cXu2Wz`r^-_f6||`uARoAe)brNbx!Eq zbNqlJ5I5ZIHPq`rw@~4vYkwuZn6(wA(G01o&t*WnhtOp4R~l5z9Y}99sB61-S=3JB zceto%QJ~X9^d8#Zi{ zFC>dxoK6g5v$uc>EtJyV;g^W9WZjHUg3AK{b6^;_FPV`-c`Oh0h;P83Z$4$?g5%ty zU-Izc&X6TU4*ge>pu=QqfRQAJSA*1NNcensy~Ji{_mL&lYO|~JA26BF4>vL%7JZ~3 zQj_8&JwMOQN^22!5d%3Zn#PkVL24OKqPskSKUUdsQ%}gcC>0kHg_ujUW(CIr6cZbBH5hdjm++s5-Y*#950=V`GC9nwe0emqHJKb|DAe=#JH z{rG|+d;j}zC}=cdynO!Ol)ZI$51PIjEi_|cNh164xkUCah9t5dU(hdmYXJVw$euQ* z;Q2_m$CEspQ^@7noEJ*+Y)+w|8Ex2`HZ%IT{-2S(*JFtsr`sa?@wr6yFNP$tA7Ah| zH6EAr*S7bCR=sW9^FpL!XWUdsM=bb7I4B3lkrFf(1AdaDKl5hKF);}x{O+vhm_$%9kZZ%xU|A1*hvV>u|GG zZg|v<6yVRXK5|bo$GRbWmK&ZH4;up3%PC98RG>Fo50dKa;8lg|1<0kQFpXRyKEw<6 zXWU){uf_yPZtJ0bA2L-cE z<$n-qfNP7|^C-fThY@<051H-F2v0j8j#koD9jQSi8ndQ0Y@KkD51xA(u}^dz}We?Kqfppms0`}Z##%u+uNvD z{?~&)q65xQgxm9O+#DqxAbAJw8cC7Qq@G^AQRi{wz@#zUjKz)2geld5`KvCU zH_!{2?Gp-KW^>e1KxL$TX!x7&8GkB3Q7kI_;_1C+GTJss%~oD!3R{Z!UEaMFL*$)} z@tHWpCe!Fz3@A6;us}9b8*IrV5+Ajha5laKrj^ru)aBHn0zbzBLXumZ=$Yv3Xe;Ov zI#72fV}(N-1x&R?2lCrz!k$p>L@>~c&F&ooV=EdVlEk#`pGUs zUt9d=(GJp!b zK=NW)!`nzed80DN9NC773p#$0a^xCF8$BZ-NV}UdP1Wk?=2U>&vHH&G_5UzF=+D+Yz4; z3T^}l{c8GW0E#1_e_Dpexcv4%-ED{w?qg zR(W+fJ2*A4g#4}%WLm}My_;0guF2;>YBK^;$zu2PnE-PFQ^}#ZJcy!kRW%)j&UH@t z6B)6+lfMVTjN;k#ka^%N$gFtI?DN4y1-^l6@!Xl4078N9fl@qgRx6N5U}^=B>V=;M zQXY7g+2Vr40*fL*<}d6Atx8pW71(Q?>Px}8i2Ns)fiNd>Whd)8gyD!>HGL7Xsz3ze zA9;P0)2KXfh{zi%k0K=&*a1@Hjnew6z!1tu-n4KGDKk`AtmL%cfK$cwOI69~B0N=b z1L7~2c&Os~WvXPc#3L0qAihN6sk05jj5=RM&dE*)4V>bfi5^xt{m_T0 z&RH0WN~ar?nA3#oBxecompLnNEqB)ATHzcMgjhVbU6s9AqP3CzU|g0kdFmtoiUyT684Py} zDj=@14Z;5b2>%d8!{?#GnZe(o#>m>quK^Nnz@?HJDB2W8Bt#*jscb`IteKhi;WC99 z7Gh4^H(=Vj$u~2t0~cXHrIU2a;8BP-vOdJR=N!%@C?K`Bbj+Jy4OPM{T|8_uJIQI(=a(F9VR zH$XbdITuoKoOQScoU3sSIrA_m5$6_+Mu~F;q+IG;Ksh>>fQ~oC-G_vtvx2k1Vs@x# zW%&Jw%;`mrqE(aGqPctbU`}5&jdNO+%_w>W=X2l-z=~cOW*plc=6+R_CM*=V6;%|S zCrDA?R3hgK5(&H&{VA%exF6X{168cHUXb#@$Izpq6?52)Xk;m_MHd)bbA83O9h+6r z#l_cv7z_LgMT=fNV;Ybu6<$dBoC^6Atq!u)Rvc@hjcAo~9ukzZ4_C+81^xl&VTdEB zDl3t7H*$p7_>jaz^1P@pr4=TFN_O}bFAHNhZ{RRqkLVQI&jJS({xI-)eYh0;!C}M7 zL!Uu`ii?Y;umxvQcqRXa1^__>?LmuF$tR$e9J5RHo%LoyE0`GSOH9HI-vVi(Cc zL|-OIu?p5hHqn;{+2$hFU_=_NiGGT`7-R#S*P$W}tZZ9#G3-(bnsM1Xi+=8>>!5Tm^0?a?{i^(DG0~ zp%>Bj2@(m+B670`raaKg-rpifg$fQ+xbF`x0f!>8M9=<}gA$m-R^A~DRA3V*(T|_X zgis*IR(36{1QH3ni^%6}XTD0-cbU#a9w39e1u5x>ZER^#(H@yRcSMqG&sQYLxij)P zw)-1`1wH}AL%HxmG$ojX*@}KMcoW-Jh1$$GRaQq=0da1SahfaR)W&hL>9Oh2w=@06 zxG0B)*>OGqr3pA+1m~dhOH>zfW+FB0a6%QS=ns+eRuHCs29bFmP(@@=O$j(NYM2nF z0aZ~p?Q1|MG2fl4=rf3yQa0b1avJG28wc(WZnpDO(NCCd2rS-QHJx;uP5Ow22{%U- z4Kf>rdv(=GLC|fsAA)k4n+=uDLcDZ8y7ktoX{4KMrTfs8+x(O$HDxn0NUy$Friw0O z$Ga^B~IN;cWl_{ zS4s0197{&4s_+MGM8L@V!qq^7YBR0@Cljr}EOanSu`nnHi*3!$9UFIEyKQI9)@JN1 zYPL7;+ETM&=l+@{o0@lT-Lb9a!sg9eYA)ZqWlznvoy{9J?7VDW^PUacw$$w1v2A1X zzP(FY_B8LU*|B@?z70Ef)(}~|ueo{WrtKSc>|VTc$L{^t*KF9cYw_;p-CGuK*|2d3 zvToYBA1rrm*tC7e?k#`A8u#9?_peeL1X#0e)20diTzbZmGnOoMyQ`MCF;Cu`n)hs} zS+b;N*ADDrPMo}X&xY&VY=kmQe?I#QE>yw__L7 zf8+jr`O?`+=VVbbmdw#;5;k-U#577&zb-gq@~z|D#`**z#Dh3? zY>4}W0U8zpwdRV%g$-*O)+H`#Sa->a^@-KXmn~EKA)CbJ4f{5zojdmKOYGdTd)vP4 z>Y6Qkb|*IN+^~0V;#!!TEqfIPBC&1f4K3Rf8+Yv6wV{Poc%9$6XUmqvrj2Uvj<;?} z>{I)9Z`iqG+wLu!4dX;&KO}n&5`-;}2K zTzJWfMk|im#QN21uTqJGZR(mASm>)yomOt@ghy2K?7D_14f ztyp{UDqpMFSlezG=sn5^8Ex6T<$A~y>JN*(CDGEncgMaRP;c;RT(J%vxcsv94VNS? zTD|VF^~cnF)#X<$^F&~EB~cjKEqgH}6T7+k*lw;qwwr6OSb8jR^>USfz>V(8u((6M zbIaC!R-G^mEga-y>OF@onUI(C>YLx(S0WkyLxnli(T-!WdDc44(^-bBqn6{{~< zaq+4PE?>XCVQu2F^()q|N;Ixpb=hUBR2zPgZSlnod*h2?ZO+@ad;hZQ zd&RP)6q#qku!!v2p4iungBXF2`*Je;Y2YfE^RWF{sDITd)eg|G+vol+pu<(k~|zFckHRv)^NKjJ-*nh z8`d4u-gPTpr%XjVHYd1HaHcZXvFdT*t5;q4+EptP>(HkaG-4u{-TQa31>?=Gtmt4e zPUpFX!V0ciFLv6~6RAyv_1d)!7pUV*1h*ICbwjMladbvjhU3u1RE%rT>gBby3Ui&V z;^u^uGlO>Fx`s7tV2{|b@$DQ}e$6@K>>H&f^_oGtpke*1)%Fd$H}8a(s*DC=Gqk7B z-wQ8acbOTI6AOFg>dRJKum-}OC`}ApV#S)qSFce2AA4^C7+F#657+H2d(yMdz|5q9 zVTVcBWD^o_6ju^KQE^GL%AN=U?rDAc7hFhi{ky!E;QAg<&A2Z-=;(7nKr*PHh}Z$- z$u@Lml1ZjJ-Cf`BcdF{%+no%X$mjb$&P;AqojO%@>eQ)Ir|K?!<{6jKz+%hfYfKF* zr@iiRe|E@ne{TP!7oQRE^|F&U!T7#rF>N{NL~E@Va_p-`uvOgDf7ay} zV=2C@R$ z5@Stel`<;;9ksLjFUQ)&QVVuW@a-P+MHW}xqNFMG{P?I@jb z_7#0sE*QnvzTvbt1oO|R$C>@_=sS-iMW2<6PvBD+pLpPm^DlLdvD3M#uAc^*gVA$_ z!7a(gkiorWy=df0wTNfrEQnDF=Q`K+@3kjmvc681i3w>X)54{<9NS_tU~ zsOR&K?ALbG(KDWEpajY^k*eG=> zb<&GobWCc$6E3|tMNjcH?kL6hi>I7((IKh*PQ3j5i_T8*R0U4tp@;9kf2}jAPB;b| zu`_twqU0wL;zu5Qf=V>jolx&JL>i;b-qP4|Z-uuiy4qXg?dGlZ*2nh5ZG;27O*|N? zhA<|kw&59<0HWOIh9IiU`IAH8tlmW>jAE;cQ?C%j)LNV3=@rgiLwP*4O4QIN)ZUh& z{aVs5QHR>}6n4=bZUny2ruReWVV8QMP2&j$q_Im5K@{m~e(F_^&HpBLz@BPUXV~<= zA@r~VerHu0L?MWRJ`7QAqeBqo4mt!;@K@b_i*j!=y$5t2Z@+{9x07n!w@~WyR#*!>6&m7%^WvM=xPBeZH7S!eOPr@t+C-gHayIRC)n^58@|Pc7uxV0HvEtc zKVieWZTOfCD>jV5q*4xzHcZ-Zr485Ga8DcVXTyy)JluxI*s$A%FR|e(ZFq_eUvI;= z*zjx{USPuk8(v|<_t@|QHoVG)*Vyn=HvGH|M{W2u8-Bxv-?8D3ZTK4-{>_F>P<+Z^ zjScs+VV4c%eh2b1HvLr_Zn2@ZVH3_~X!G?UsgZyl>VKbISrrT|Jlnsx!;U*it+=kz<;V*1> zs||l|!+UM`KQ_$UaHkDDoG`P!MjP@bEYknHcY_4F}=oyN7`_c4PR};x7hGP8@|(qpRnPG4ZmT- zAKUPkHvF9pAGcx2hAVK!&h`(p;n6mf$EJWk)u#EF8|nINc#aJ(wBg%qc%=F83I&i;D=NZDz^8q{7zmg%0d#6nw#}MlRpT1#!4@0aE7ufWb46%Oj!9V6- z%@FI#H8%YPhUn|{4EI)w4~voR78^oMRD@3+ZoKTB7vq!=;oC1Y;dw5Gv&^@vjdDt` z@l5ROHeye>@zQ=GHo7ITdKnE<_$MD>WU!v&RMOQIAl)Kgm9yBQUPZ8oHxO>qxD~EM zjXU7bffrJZu}+HAcQ)=Dy%opp=k`M?5RZ{rZF!fn}$ zxz|=3PdMdO8_#$3f&3}B804#E|xt-2+JXQF;-d?NBq8ve1pQ}9RrTz&LQpx!>X`c4KW zT;EqvUkW(ZM;W;K-imm*zKf6!d(W=Evw#oR_wx{cVZ_7j4kMF& zap2@nqA*=EYzg;d4qS9;4P6P2Dfe;?SO?)iOJ`Ex>nln<3ftqr(d~;!xF3H-KhhXj z_JcmJ>&KBb^(DrX+Ttn!or}J#hVHJ-M*nKteKF|5?QZ%_AV2P!T)VHYsqb;rcZm~5 zsNJ(I9p?$*P2b0Z>Kq6Q$QB;^Yv?}zv+56RJGyrug1I~3%1?ssSeLMMF-dxV3=v=Z z-%4eG;64IoU;2?m$i6yTfT;T7FEGB0SYSN_?l8l2uY_E#a+%0;(T+opKI({60EZlT z_~D0j9&+R%N2XGTbar-zt}i(J@D%Qp5l2Wj4!-!6FEJ0XutnCnpI5o$~6Xa<9Jb zV5FkvfqXAk$1RyxAG@7_SO0DaBL9IvdBI~+k?O~bqQT=uyL@`*#i${wx^R8+r+55a zXn0XQ)I5$*a~s${8Ror;g*R*jvk+bTywIZe#n_-ks6GDa-8yz`M}-1!1WAn^s4Y4ezTdkx(dtlKXE&H-uo_g?&A zEPP*pXGKrN7kCZm#!S5*wKsm0!M{T1kCAxoD00*=p&9o7U0Rx1vWH^ z$Kjs~tXDW-55azji}fkPk$M8am!U}N!*Pco>WUx~|Cml+6*vNmjO?b8(~M8v8{565 z@!{Co$m#@lCJy$Bmt2%#v&u_yrV*}KQI!(76w5Qj6>(c+j)A0vs#sKWIG_0mUiMYZ zOFT7`NGxlfMai6Go6Do2IHFU9zp96&O>d>j&*P5ctWu>rLqxxw=a$Kbhy0jY#!d&# zyNs3bnqIq%1z`;@E?5aa}Pbki4WK#W^VM!fbC?pc|s(_x{M~sD={r!$0{;c+5 z6U)@yH{U&j=I&N?(~xxt+Ll1<0qib*GrZ?mVMbLd;D<7vQS)kgMs44^bqC@ixp`_% ztSFk4AWbQes36#(c%_Ebl~h3ng~x2{m{OHU38YX3N%2xHt71V?kbOxNp$ZPljFbvs zH($y_8D6dyKXqp_;tDXOx9h-as#D|Wt^7UX4F%ZWMMl%myq zdid>>O}a^6QeHKBq1a?HZ&oznHdPib}|n(=Zb22dww3{ER%Sn z?8gcy@HZAvx6CeEGXIcD%&7;;g~T6=b*ka9xktBRe%-6~z=(pRTrN&+)wc*aFAL@s zdJZw7h44s_vO?`@uGFdNM5(f^s0ziBnggTrl@dl4b zORIOGOYv2#A6@idxP z(o&pMlRMR8xys|STc_Y36woh)-Zk=*1NW)o^lT}=eJj4+T%6tk8Q_-oEaIv-Gd(r+ zNMWWKEj&<&Hb4I8%+_Va=qL)X?Bvwbx-|&f_d7S<=Mj{0{*x;F*gC$kB{eZn! z6&q=9kFJ}+Dq4!b46MD^Q6s#2<*P#}kna*`FDz?SG$k4ps7~VLGxJN6Q;<|5AuL;} z??aF^fC9!6O>=~&(L<<}4|g+WEd+$HL&go0k+n`0G1;den+GYMJ9a!=#CmzRnqoZy zbF=fJdKlTdVzVkumu7dULb(*1q7nGb{7y7idJz36NnbG6XG_)Rv$mpL1a^OiNsz?^!#Fu!EJ_;92gDNT7TUOW=t{%}D(vSaF@N7UR* zp)g-6poL0^){-Y{!;!k1q2;0-JdLo}ZafO`4$~L>B1ixS!(4k4X>Cg`XR<2sTX4RTC{M!uy!c}Xc zyRTihZhd=dk3ILogA04_v+ut9s(ts_Z~uMvIpBbO@$bNc4(4mfo%n81!yygTtv%gT zEq6-TTe_@y`EpdXg6yr_&GNHu-Ab?&-LQUd@U-9l2OOvlQU`DBz=`T%2Ooa;5uFEv ztrr}5)X|3>bIh^Fyl{Wm{p0>l?oPWoqv7)jrlj_ z-<&@qe^&mS{Q3Ed@^8yuk-swkj{G(GPv-w`{tNjp=KnQ+UH(h?FXz9K|6%?|`J3|N z`Jd*0p8r+;=KQbox8@(nKbT)WwPI@3)S9WzsUxS3nR?OGMN@B|`p>Cjw+(N*cH1Ym zeRA8Uw*6t-1KW<<{+jLA&n%tW9?Ubf*>-odA%TZ9U!jt%jg67E_o`kDtWrPl(kqwm z>6IFz>GkXIQ0e8d&8t`M=IL+7hwEaX`)NGYT)#)O@Zv-#La*@aM7p)LRW%=2H?@38 zG7|r8U1xow(VM@cZc9sJG*UmwG}Js_x4AjFXQia;)#{a~cWGm9OC#DFYTUehIl`-( zhLD|_@(JHy7dv_?a>fBB3wi@-l zY4`DUyCHqu+SKah2*0pya^*6FSFhi)JM+Ka-o1|Wccwa<;s}@TF|ag=dj7n}BqxO` z?U`Od`bYLk@3|J?OZPVP=k3$Iel5!Xa$mLEO5pF_uY3Kv_1^r)4(OEh$bpbM@;`S_ zYQ+l3Vf5h4TGD-YBCS9c{F6T3&$m%6$eoA)dg zF6qX20DtKT$;KGMubq(GC$%i9?m7|l2tWFw$(1Wm->I9Vy~5cqmUar4zhu0%3Hg6{ zNpk6uWlCjEnrv-dg?o=LO-s4EUYc6Ia+y|Ne_1-U2lDTG`Q)B#cSpGIg~;Dam3CZg>b<8Q^`hMMZ_Bi=-Xm6i!DX5D z6w?3aa)hY&Ggq4MYwygouR{Kw@6NRExrZ*F`rgdSi3y2J80-8-jA?OHFkZ# z@NxbJ)xjNm>-mWfXZAY);U7POc2VyE9|zqs6+8VJ6Mke!9egnOTlERU7ru@y{rT)? z)P}uLZqw&X{jd1~Lh$#Me>LgvjUYt14_;@=UGU}1%GIFX=c|V9im#jSm;Yh-nfgz) zVV`~U{Lj7xd7z#jY(~3#s`7Wgi*S{S{P_DO%>K}Xzxc5UZ@s~Uciaf;jrJ}Y&$O@I zJ2HRi&rJP4`?=w>|5u=c{3m{G>i_RsJ2&i&dOP$M{BPIeZF;l(A8pgat$MgcXIk_? zGykWXbZ;a7cQ@!x{CB2WMXtb?V8;jfVa}=gt=-uf)m4(q*tF`HH<#_IeSQR&qPc8S zZG|CTUN)>6KFyjY#<9lR?})a-QBWiB1qeEWFaB8XvV)F9j%x)Rb8^sDkhmJ$hMQ#a z3DLa$&L@K2)*!w^UH!R{3O=iyD}3&AWF4Qc#g|D<>2{j?>=sExbuaF`&YO%r__{)g zAVKDY5{aQH?1D%MkZ(N+Wn0kRbod+7oeiJ+y#Dp)KKE~6;98UjcO#~|gKqS1N3Q)6 zYCW0j*ntaRY!W9GR^-ieeEZR11Bnm1STkRC5O|_k7e{Gi9GN7Qd zkc#UxH7;Yc&dYBGu73(D#WGnAj>L%Smrjj=B8DODkdC>`=1LNzu4El`!6-76IYJc$ zG_cJ{H8CkE`2aRP96h7nl>Y-TiHXX!s%xhjDW^B7^Bzxo9m^Sc(?(OFH8S&Eqn^8~Y3`{SyhsH5@Tl4tI+CdbqLqzMpK^*8# z{G0i$UqxjXN`>x{oypFOP2=D85&qjYv<+rdjm(RD8X^7;n2I6Hn>@dMy&YpQ36@9k zar6Q3K%P><;~@AP0$(H@fx0kcnt1ksbfjlFmaoGPA;=I+KrVwIZbv%}$nYqXp?Pp1 z^!4b5$FF&3i>!!0aNUa`97U(MVBEHuO#YBVZYP9`@yb#Np+BaHXFljy8OyOe8EFGk zePA?OkSw-GR@gou*X;+fZlt_{mibh!duV2N{Cvf~LB(DP0iy@#XBmUG2C4r>-%9zc z{!V)(ojWl*o5-MCY;$#GNF5G(K>bw`fVU|VX)`1KWC(oBT43jhjeHotr>@KQ-unks z^Azh~gVJp5H|cgg-KFQ+^^RyBpEBQ!-wUb3&(F`RwjJ{OX7g;tT%x!2g1AS|b?BM+ z;{%54)gLzDAcl#MGm|q4bs@M3)e6xPdNAUI5ey0;&((_dVO+vSJ9FCXyzMump|Z03 zS03jmpbq0lXr`?IbXd_1VYmr3Of=|>plg{J;{XDvc>u>mlbzx1HB3wx^B1uL=9p-K zB3Vd$OFx>Hc$_n^BHRthII+KVT7Unr(>1y2qH1Guz&V%@(M0hJBK)*G0Y8e-V0r4G z`!p`tX1xXeltdf!REL#RLT~S~{Kh#rMj&xL6T*gQLp6lz4Yd~HA;cN@rBywd{Gu0M zwY>nR1mQZ=W0knc$RUf&oxx?vk|mmQc&;w-Z{#aKOrk;aD+U;C_jUhKbg1&_Ltl`E zVKCYO*F&kxMY>~FS7~>QI5|??lE>vBWn&X4ArO-eF}l&Jy~3{&behbK#vzfmZEal+ z71OR-{C15YkL!vp*l&CW3cQ>$nM3*k$Z*M$B*wtN9DNIc#bR6(1n?s{2Fgk*SemQY zDzlD*A*)5`^ss5I%Pfpox6PVE@6F5Up64)a>0H_yB1XQiX6rw1IAG^5u)V(lYHXmoX|EXQsWIn(2MyzW|DTPaiW0qWs zyTF_#Css<)*brc2J}b)0mq{lu;g2lzy4PX*oj5pY#~pSZ+jyziz9vp(t}1MU7G;Q4 z#`HX{f{vIr1Z^g}pp9LSo?UPIhoI<&4DnIa0BDrDO?)h1_bH>HWdhbcLR==X#Wm=k zib}AZQPT*9BV%J+wheIoHPEiRZLCWlvcyDtSlh3O@0WTjhz?53xlSA2>nl5cPJz-Q z(DyeGcas8U(2W$#n94|YlipTe76wN2<_=x?+KGo>gI^VKiy+p6XYwunJ?Sl zX!S10=|{zLH#UH#%5GKCR2u!MJ(gVvW?FPHDGg!BXrc%nOtOVRzspTN>nhNqc0CaN zSbpoL=uFP;Mn=F#kG@#z#}V(2;_?eTtF3hkEoM+>oi2LXXcK z0J7ESHg{3|wm5jqvd&|48GL7@A(_&HXv_8mVvtQso+!e$MPgI=f((BbJW$i|5uGwI z4=QY8br^@M(L2uaaRz{XUmtSL4#wSBLxH9Y73NIF#>VV&ssc-Z--5E4?f&!~@oRyMar_%G z68(mOc0F8Y-HlukMzNEXwCN0f_k}Tvq+ZXb@VYixhd@OWO@J<>)H+?h zOhqozl~kiquY@j9yo7o^-DhRlp|5Zf(S-o{0iSY5vk@^?2}pMS)#Cl9!5x1ET~j0n zvT+a?U%ke=zcW%X=}#zc*d!9B(zNI~xa&%2YW(xDv4qi(OT5>~EE&rOZ>hycatT z!aH3ZuF{O{rfT@5jg9E9NR^lrhSA8!v7P89j*OZPvd7;SGKj#kI%s%D771Cukm&w-D4^`*PS2M=r3Q;?2=knO(Hz>I-xt#vM^9~K?y+?FH@Y%X zL=9;kfJJmAt-K)(5}cT3r?7deu*EK2L{n3(5O$BTy|gefeF#L{U>A!#NZMyRFok%S z0N^=-(wCvy7Hd(#3x05<3#{af!I52?z7)fP18FG)UQkOr?A!?Y0cb@nQQe7iEiA)C z$VuWLd}y2(O207zo5^k;>g}KuSK${mJL@ql^bY#8zBQ-s%j@5Os-CTg|N0&DUH_Ec zbP82|OaG}`#cnE*haTxMTXHa1>2y&W4mpkT@%{R5DJJ$Cb|~2XKV5O|M{>@q#xP~k zCg3_pf?Ky=%4Dq?WGQH|gNq>?rBSyYf?0q$;)DsAgF}XKyOv;yVivt5K%-&2 zL%NTPD9DIQRY2kCiZNq3=nKZlE<-IGLaKm3f{gbY1q6a~-=F_joI0JChCH}1!OjLE zz`mSN`BN|EfkbhEu5{_g0eQLz*3*S`+W~Z1TI|>3z5_g=eRRFv=A$7(M~y=Phvo*y zpd)Y6^FfmkS(j`6{Xkc2^SH%gnv7!kc9lS#x461t{0>8%0?7B#UHUACuG2dl8jJlh zi{3Y{hfOc(l%P8fGL93udBBQeU(8oz+W;E_kpKpWHBs3L_iO#D7j3wZKShfP^g9;X z4U-VRB+4k>QctRhKxJbZBV?h`=?>DZ990YLp{eA!XO=rWVLXfv(}(K`*B@>-%n$h7 z$@=iA@}x@ekPvWy{w@6msjO^A*YgcEZZ1OJr02Q74fm0ZW<=CFo`%=L~rB z8?eS=PwM*cDh>U02{nS9tDm4Z>L+mCmkbj9Ivph1^k|TP&IJiLZ9xL(QbD3Br>aa< zZB^}rIcUTP`?ZC+w*9H5gC|7NIErgqjp-Tim^sO(CXhAGi^+vmc?QmJc8fH zXB4wMCtVwQ+Y`n*zpkgnm-K;# z<(5}V)Ebs+kr01`jG;nIz?)Cqa5_CsXIScR6UH|z2lB_ghouIV)PZ3MwyiWQzvIHhDEbsbyfS;HT=qKg_!!j`+)ITvF7?z3oz_1|h^NG0QKc0sN!+yPJuQ%lB zK>7Wp17PLwJ>ik^`O_I8?dyQwWJf)s=X^H*A!w_#U1-t=H0eV%IxP&N!_OUqev<>T z*gfM*njRFOvLN(0=d$!e0Cv0m4-cK+HBnOBKYF@QPe&7{9__k#!t$)1q>l>dG%hR8 z{9m4{{2)-1gf6<-o6z&lJTPj}IM{I1vSl~uxaOuol*&W}9n<3Y5{+mIjS+35q()R0 zJfLAlMnS+z&H{r2jN-tD%yu*0g~)kYrx2yZNjFN1M5o~rVpGrjdVs0U5mBR&vXaz#8tn*%Q&O^l;C*9B$;P1%+?!Mf*vVsOU{VeG zJ~@~-DIhzjS~k_ECty!q%I=GDY@LmXKH8Ky|HmT)lBZgrSJ-{p6yr~xN(q%%JkA?{ zm}F`(fQHa|zk;?ZDQF{nL1PQ*sAsbxK4aH&GF)O!;j<6ex-r+-TVrJFI2#Q$i~~l{ zpkc)DYM5Od)?-U$(a?t-4vh)3-J#Wp{++*+Oz505;9eg4F*{?ZUe2z=_&7B7V?G-5 z*GFUif@8C9u*Qdf9tn_dwl3{o;S)Ty~g!vijD?J)XbR^Asqw z*pKLeU^(VCB3P)o$7>fu!j@3`4&MrhP=jS3>K^n!@~X>K*IC_Oh?gPsJ4WPZo<>0b=m?>}6@ZJ%EQRI=01?wys5ieUkr>#{K%bebrRofrjY zNp=F!w1m$}lr@F?Nu=H7 zY;)zFSk9?B`h;IQwreo=u4x_+>Ti=6({|JZ#Z#7S_&1)D0nl9o8KzWZOj7fmlESlm zH^D;+9ay4e9@iw&Hor%M^cb2afrI5qC;vbR$KqQ5-sYk5kMY@qE@|PPMT=8Uti^Y7 z@C7)^hPIz}&P1CzEGCNER4$6?Jz%jgklS6^9R3QFPpxYxws3RUdcBGz~j_l)^|$f?dA+ty8!!U{eDH!(IN}TIq`^PSzOJCo;O)JnpXFC zgR#jy#`@c7l@li#JtBR=1S7_=ruF54@-VZ|A{5e{Pji054YiFlaM#lBM8;=e+*4g# zT~ajh2H=>htm_bnwxPQ=3+3M#I_1w-C^!qeX`XTkFoXtt7-8EEBEl9@?vWn<;J!;A z;ka<;wDo$j&DMlRIZPFJ(7+bOQerBG|Ll&}b9UiufZ%P>4sCbMd_=(%t=Io;iqiA8 zMRRj4B1V?9MZ0uzNLrPL8>DE19_NmMM>Q#G4aJt9HD*srnxZ`z9=YiuC8br~i;}w= zQqmMfNodw6TxYb&wRAK5&?E;Ecc)~yQ8d{|5qN0Iltj^4B@N^0RQGHTiuR!p$Jmv` z`oFvAI*Rt$!HMZPBjYCh6X!*=V(3^BP1`mx@twg%UP?02s+BfO=(s_FVG$3D8g79f zvC4>d63`R+DAtO1p&L1?fjMl%I?T4Ck=62C0AS|T7&T57Fx~@$chhVrqg0(CYjg+o zC{C^L1l$W@n$u{mk8&r#zi|(CdwCG# zpfvz_p3C-Pki9m&5H_i417u%r7D+G0jFn=x?Jfs;w99mk)!~T*T|Cmm<8QTDL#v}p6-1N1NdHaujcUc4Dp2&8OiAQANL&=<7TL!8BfOcccFjBpe zPS{E8o(OkOh^sz3Xl>S7EM&#*t46Gqajdwtp@GLw%bm+$Hd)Z zN!r~z@U+-X=FO`&OOa6^1xl#;p-#0=9-8)66oW~g zWWZ9^h?xZ)7_PD2yYnnJ%hixDi*@fuS6+D~jWb`(^7L%GhyalekrkF>gK5#T&3ybN zl9N;DAH8Fuf_hG7Ex*G`?_HQLe+|w;)}Q!IZh?V>o*5GF*FDAqm@IAu0g6eOwObj} z72cFW&m-^Em1L7VPlDNo2WO0h!rIkjElh_V&e}$@dOV~{^@R z?3L)Ceu=d(=<%Q(unr%IhI%a1{U~m%TQlnvgNN>;q2HpWXkJ>MORCjuoh&_uo1pBb z@cCdHt4Vy5$0*YG({Tq##4p)Y4{Qr6m`|hhOYcnLU8tQfm%{Lf?zX;blOAt3oJaMx z9y@;d9sMEzT;>M-SiiZT=<&D~45DE)Te!CLH0}K2=u`UBbD#r}fuT7(`4-cMJtHTPGbhr-^vQ zqw=E^?Vu?R^Rn5-o<0gs=s)&;)`jDLZi$-kd>#QCW3BJn1Ev9UMYIl&U}a51S?slB z%<(2dmMa|B&^PLFMzB&?CffCdhWuGZsdJNf8m&jq;5pC4y}fKy08)5n|5^HVDO}9C zM7#LPZ88mFw`YJ~2-vFw`P^TP6~Sp^EUiZP-GIEVK=v9M8NW&YF&XH@vk>F{z>MV( z22x@T8agMjF^(-`P2!*+=1tJ_5qGel5Q9-A3b7t-)FWFF-69U!CWqvVb;~<{h&=#{ zU%^z!R#FN*v~9q_#k7)kF#&r`3=7Y88{^$`$yJzmq!Yt4Uuw#(rD}7Ie;Mztz>QQ{ zEo;OeO`}mIG@UhT5DswhmKCaFHCyZ;VE(w(1Wskvl)*%Flz3t>D}scGP@GehCrPNY zltK(v0j=wQQTuZJ%9eyVVQKRa`NZ8Y499+s`OPd%uw#UnYyD{~*sAt-ZmBLX^FkE2el{f4v!S4M$I_tVvwWE7#|1P!U4|d9^vs=Wc8JAALq4j9$MB+Y0sa0c&q~Tr$#U-MK`!!W--=;4tF+Vm}>eBNk;|SGiGC}$N(pCEn@Z}+Sm#_5<4hTgzl1{rwqQhV`|mB z&w+jpKs_^L;19wJtLtM2$L8AE!+siOGTg3{S!jeD;WePcb#U%*KxoeVy1-6u29@Hg zBQgtecqIZjB+MZpsQIQoj^*sBBC6xDBB~oRN50wFJ~G;myM-dNIL=IZ+4h_r!Zvf< zg^iSK{NRL`3D@Jq1sQgt091IG0k_{<7}$wy@8)&sVRKgR<fY%`>R%l!p zfCSLEurb2M$wu6i%j(V!Qy1P>cXtLwk&R&zMKD^j8z7l$cI|Yn>_N)l{waL zmo8@67o!O&^Y9i#1Mk_(;<10pNDy4txEHkaU=lQ0Qyj=m2^L1R9ryhU-jK7i5UXq>`g+z z_E++~NbLVjc8;117_*fOihSfAlHfNQMZwr{Y&a{-(Utik04IkLv%UWX6|Jcw2Ec-3^U zpG>r~YfqsTX-$r2go8TrB3zNbuD|0KzeSn_yR~T7E&I6tNnA2bmALjz39~)eOiAG3+^BsP*fY8xD&;yA)2gC zdlv)~OLC5ahOspV@o$L+x+GpJw;Jg%*lAQ@R%Tt=tQhJ&LE2#GIS0Uc+JYovHJICK zFps<%6CgxW##wn4<_9U{hAVX}z_ebM`+PMPfo7Bx$O<3~`*Q9jS$GCp<1Q>qz3z)7a#iTK#QieskUI|mXk1sv_qLAIg-tIrZTZB0>raMRSPx57x3v(nkmsk;(}nU`C_}bYE$4+}v0%Ig z7mTTqXZSjZip$B64VYt7dZ0^!&;^gO*1)rcNq2=Rz6A04WJ925)p{FdJrwUpsS+OI z@nKeC&t)&F+8RXj)%=8*-DPxP-=!B-@-hAThmFO8UR3MGE?IXO?;CY78`cL-qs0tq z@dW}pSb04kBoPCNv8xVC61N{WI3XEz`3Qx?_;nWRNE-iU5kAR;I5EIFl4fUSeUdC1 z%&?pz5!*{!?2}-LH$*-OJWasP5Q(@Ms3{!d_TY6^Rgq*9Qn`2numd)Ql8Y-VRS5sA0wkD}d;~ouS}{ zFi%lC`(?n>Y&mZY0dXjR&Dx-^a$+8^*9QMa-qJSh80-Y#foKX5)GtSmu`xts zgHCzt$~`wSu<9@(ako%ls5$( z0$ACRP!dsmXuKN1?|~WMeK7%UdjXX+KItGZ6BSGuqhMM@y_YZtEEvN?R2`Rzy)v!kj_mRMk@3&_Z4ou)DBF?Wi>j!wcoIP;?8Vi@tuR zdI0!krGy(JjF$ys!aE7hny0S}3slNgUlqpBL^5&Z6=CG@8Y6^>6PlCQ1i&3seP()F z;t_CFPQmb+VItPc0*6uR3lT4xXiacD6oS6fWUJqnG z;aWty<1nRTh*(0bdF2!;_^r%tQ)3@lW(9vG-^Q~Uq8(-hu+&lpZD(x)NXf(WCd&`7 z6v0$7z%vO`J(1Fy9tCc*-TM*S&3?TVhKdz97(n7aeBj^o%wk8q?6hj=q{$9o)O>8U zC%}lEqkLF#0OLfd@V>Byuv2+sBp(+#LpW*YA1o(9YOEmA{|_bXV(nYZVr>TjXOY0s z7wTYU29YO%ci(Ws53BNJW~IX@@dY#gt1;2T4m+CC_~c=SSwk?vqyal*F3HezR>sbt z?eT5M?4+$gd?HH{TFVA}nGKp+>|#f>wSxhPQbH6Wv0iw_uZ58z=fqnxuLm$ZT+sm! z$`!MAXs4TA27?*hTdm_Xfn7G!1!t^uu_q3T6XlU=iqV$sA;~Z=(~O%YRj^~I_-5Ro ztHL2sKIVoRklT-I0>V38|JR4gIx&fJ;qcb1$6Z=N%nkr1Md2z7A9u52OdGpJf-d8K zQEo}51xB>^NoY82F$i)r;M}@w4scOfGSM*ZMEL**ZJZ7JioqPLHUqG&LBm9%@e~?P zG48{NE@3IY8BD)laB;Gabwe8%Cekg8gBB^QkC?t@8-ML0xGnJol$F3QWDfy#H~h#%R(#iIncEs zn*tyL{jGFkjDQ(&B$#m+2)hye!HFB>a2Zb`8)sJrXMaO0X8&ib-?^`RD~PsOKxE1p zJZcff3Sbbe3A$$Mt=F?AFk^Lj!ZHD$+!k_}HY|vy8i#2$+6v@|DJ9BlXrAqB&a@!9 zg}QTk(jZ(7OR244AuG;MD!0&u;t(XW^4^LO&LiRXOU9kd3ozwpiB7m2(U2gEc|jIZqoI^ag%dXJ zEw)?ExjjLsKs!A403s%er?LZ_)9Stuk^mVf>LMK_C|EYX7wiKhEG>f`vnkHhVP zaIqR))4ZK+VG7zUJmP6VhYNScx{y{;Y_E+}K<>nYx7Ha2XVr4_k%)-E$J}}XO3JZn zWLO-y>LCPj5=cO3tbGFzRtiJK1v8{Q7Fn%k7P*){TE(sP1j@aAzI1G4N3IqV%-K** zsgv8zFpTrHt}5vCU3G^Bhj9180E}^VD=)X`Zs%P+;MU^%?1r+!-yRaET=r54@dkn; zvKeU85gCt}BtFpt*kPj<0>%wc>GUSBp%#$68WU?RiCN8<@XYFEcNLaCR4QZQPZLA` z)Q69m4pd)r)k(PgeYKb!3&&L0h@2Ae6!R?ya1&h5Ep+H$5kdEZa}|v3s3T&NDVyMd zk5fZTJ9FB_yc`pwhH8*;J0m(IUX~0aayl4+Vz5bHB{0yYA{N^0j~Wtbvm=+vDl#7> ziYGMS0s63I(2r_;Y$!e#*3~gxvOXt{P&B`~V&O(z@M|kh=q;9CjhArvI+lUy4)|$3 zCXT24AdS_xOKJe!nCA!j0h8jL{!228IC>~J;<=r1TL;RTk*u6nS7Y4ce#Lm+8=tzU&n z2W{GPxjR%Jam8e~JP_8&xAX{pF9bo_dE@~m1BxI8Ti9EjX4k^`=vqx$k5}j8$0MpC zSj`Q-HovC)&g%N-tJ|;TuZDlS<8Tbr^uIr)js80{{ZWhNrrV;$%QR@Q{Xk5U&k3@UVl9I{fjmm?KlCDK^4}98(AbL8e+)sy5z}-O@ zdPAo_#A6$9aX8U!u7xKB#JoLvV`c-ap_5z?>v- z9T&}%J%Pai#TjX~3EU5v)xMh%j`QD%V&4Z?SExxI1zXMGCdcyjtRmsF5KyP-FE`w_ z9Uyy6u4=%O^$p*(32aTfO%$}I*EDt(8Hhr-H!Q z{dU*jaNS^@RDQMcuNj{K+w76w%vbLDP|~I(;1A;wz8@eXS;62^_Su(Xkejdg2&wID zKl!l8PFD67Ak9*(`VjrCRK+=H&Yp<7L#gFZepVw$;_jETq>P;H(Lw40j*EXQKfTnB z1WeI71ajzwaI-9%JIs;HFbMmA?3IP@KDq9|?S_+q<7qWuSftXKz(*GVlPbrcgO}}Y zeKo7oj3s22Pq-K3JM2ML(bmXL>0z;Gu*lNrq&zKH;q7lgMvdSKXQd0lobe@wU1x-0 z^!ge--|hEWo|}PqJV??P&!TdaZ}5n~-;Bzwz>PF+KKEU0-i?e}YzXl(ldxDd){tV2 zQmo{NE`*j!_d=vBQUi1pGgH2V?4%KIe}t;KLo4| z!ZZvCl9%`U1#qH9c;t$A<`4vXec7p(dO>#}@a{apoDhq{DIS*by;vC;eLzLvOmdI| zyfBJiH_L?SBPakyi&)-%E8|*b6{?YrYCmRCj!!OipdM;D3UZ0HjAleDIhN2LZYXvK z8C6~;98Xx$OP*=h3EnDh#vX_d;5a_dj81XgSUt$G@kDhK2m^9CfeyF#?671fe)qXo0FN2&PW;hL>95!n+PpLi3arW@smm!dsYVTw z*L}YDm&%_%jR-|%OjVG{SQI5i2GwXqMyG0Uk{q;lt~T#vqXxBTRW-v-OD)KU(5w>{ z&H`7x;WXpy!elLSJ&;DFLpdWr>SPFkXoNUDT8)%}_gz1m*CUj6s2zPykkw3?!LMPe z-4IrHYQ!Rgp*K?veVnLb3X3QeG3)e5n(qU$TPQ;^&I5_!IRt6Pq%Z^|^EjIX+L0g$ zk^aVDjK~3dG?X%gocpxt=DcXLL6RXZ0@#ZJtkc&giBT(4%M|P9?2<`l-TKf@Pja`h z(hiC0^5r8YB1{QGT93QploU3v0^QPgM#s$)|BNP;8eu5v+izklWGlkA1@ac@_(YNq z)fp%r!gX9=TdRwO!r8V^!bRtdzPO|brz5VR5Pn##`dlr1P*nqZPz?>f!EpFC`?iWp z^MIw62#nsZ-gW);*MHeiedPKv+Hf*sNX7htNZ7-IY|SR@gyVtU7f zL`pLIB-)D#Acq2NsP0DV#(Yfh8w}JCU`PUouq1v#FEG}^c%#%YSVH&lRZ!7p4#2dX zC1r4-IIArJ-J)US_%vRQj@4@b0ub^(E82Lw_&R0Fd|yZjoMT~w5_sX?-hhe#ewwy}OBV7BnqB@wAy zxH2^utRNU29dgy08m55sd&YP?)G_(Jn^z7?VYwWOcsLEI)za727iy2Ju|3zIbS&W4 z#{B-+h$C>J>#$E}GW={S5kK2Vtb}I$0bw4%?>Ebavh8V^pKWUJOH&f4A(Tyms%)id z^eGTw5IcA=uK}~!_&EU`W0>PWNBrjrx+R-4ALzWW&r7GJCA!VWN`<5)y5C2qL2R&C z|1WW95?d_m7QoV#788e!`g?-ax?KqR^fV&Pz5ood8k%8b9S(I37-CF0M(6KBw;t&Ve~_$|Cbw&$44V_M>rwz;sT6a zEEnLPM_38uY9&$btHtc<2_X#LnzS218+y5Fw?NKIGF3!$462FfJLoVGNves2Bur#T z!bFxNAaW!Dkx$|iNkeSR?NGR+Il#;yeDSv1CW!j;ZMOxdr{ZOHOTNAQ@4|>Ro;Eyp zv3C#hqIZZrN%l!XE=6_TRaaf+Ty{Z8x6O)X>F{}JS5XxVy%H0lQInZ}Hgxifg+!8|M*kG4!^vaGSYqZCZqY{VAUMr(&lp)vyW0ye! zk&kIlw8h9rzn3Ty^hw^FECeJl^4V^liUEO>kJJMKUp{M14Ng9$p`tGzxsieELV^f1;<9ErH1Iny8;94v-EoV1eyp4x=Fvv_{zAxok{ahpm`eX)l7<7 z+cIgS$Aa==X7Zu520=JU0{I{_%3)rDG>vpdQn+M!##Ei=X-znvZ>3eGaZ|A>jlJK~ zO+RdVd^K6Ey~+Cw(>s%KBM4i*+r5}z(j39KNXDdPj~zwe^47 zo#fec<+C3b@`e4$8N9o0>vu5|j)rs%n1|6&HP|1}vOhnyB$=x&U;A|JliuVVt1chx z=c=21)>0GI?OA#G$S38uw*0fk*e)unm5@O)@Sr>!;2P=mu6ZapR3=tD+Yy&9A#T-TeXN3V zt}6Mo6AOwz#m)BNSbR6VNR%vL8cj1{yteYUqLYtvUk)})Hv^l;zB=JGPn+?T? z#J31OEAfoPa}w{AxJ1o%#~3p~+!6Aj=PYZ?n6djD#y86&3XI{dYT%gfl&2I7deV6@ zNT!uPn8v#|Ub)>ds2-4v3PUAl1Ymuf4w%2J%p=~H%DBJY6lVGv<{M&pYMzW#XLy2?Gy#OrUb?&)ltBP)D zeQJ(Z;e(N)@nd^gcCoaj_wz{uc!Kn;bTKvZ`|_#8?oKTQroX}L2VN;4`4ezyE`lBPunw?`gBifp_) zI~U2{Gs+K75>^l~TLO&PwNfAKY|2J#kTaV^hs1BqxTu7fjaBJaYJF)4aScTm9Bm!X zWH2Y(6nC25VY2;cm~&~fK?$sY;lUi82#siDyCb(1^abfHe2}J)LdHu*Ct%l{iUhJpxo&4aZ5^AHmkX-n*1U=wb8aM@jj2AcX6Tb6drj-m-uW z`F+(il7dh3&{bpnEbqTxl`C8|QoiaVd=MW;E|6x=6g+3dcncU$T;ec--^<0qgh$rk zMpqL;ee#xYRCUba=5|UAZBy<1^||o-0X`F`aUoEBc5LdK-}Dmwl}&?ln_hu52~m44 zZCW+QHzb@?{Ny%UokDX@K)6_qpsxnjSPN)cI%7w}b;gLtB3-XVJQi0i9*cBx6oK1~ zkP~=q!_bJ_LY#i>BDkmYy%);&dF#*P|>adMIl%?*A{WK!7+hZpJm;}{e zkYsEicpSlHfGAiO1c^Zp`8|T7MXNC>?6Wh$wyqRV>X`qMhjnv;bGDfo;v$9In*cS= zsDmCU*z1xE1!el|(1NO7Tm&`g2qY8~`Wym5B|`{Pef0^lv>5W5NX~+zRpkWLS&i!O z&vkt~q-&4Jd{ngdG#WW8o#|6ide!u+S+{di$J_2eN@PQKk&l|R+0=L&Q$ZF|p)90A zS^AD}mVc`f6#^zK;W#{=8*cDRk!@FMRzzpBo)4au1S(_3kk8bia{eua95tBN5qYE3)Ry&-#*(%bM-u5RnD@ID`4qhtGZMM{*J` zgXKQP%I5BgihW%0Y2z4u*>Bt2Dani>x0v#=%6zNzTfqJKxchE^$?W#SI=}rV57yMiCRHW|^BZD`BRm zy4qb3$KOq|1;jE<7SwD{iE3+pTEtJt^Wq(>#iD~H^O?cWh+K75UfwZv8n{x0Ih z*|0pDbr>yJ zfR+0enFZ(}bYX!nV^yY>*l0m5_G$49;{O-?f)LBmQ$h(p8p$o7%@Q+@it6Wmd3Q!442N*Z(um}G$UHZjren|YfvBKP|6 z>w6BO*CNK@!Rf9ZcUV=&76yTy#o0i2fYzl>l>@qRRaOUY4}B505Rn9Ywi@z?e(0l%pv}f~0kw+V1mcBgb0$_>H=5#6>mq0mPp+f`PQ1NB zTk{Jb)XG>|a!)OGoPl6hmoiTZxd}<7-GPQLAk*O>$c;DQxYf`18A`O3L9)Q#!Lz6dd zAB&S(P0QO&7sAVm4vyKVou62%Y?xx(Fshh4m7W)WM{J3jIf^SBQAw*4kDC? zP2@B+mM0$2i!3OKBrBYigvfcH|H)@NO&nJ_&KdBNxETvD=I2Q0%R8CW6+ZKnmS}K! z(x)vZ0$Rpu4-03XDpQD&G-IrdNMfECA!j$Q9H@sW`EdNO*fJVUq^y4L~>XWs(>?hd;z8!MVcC_ zEHPD7_Q)mU*A@A;K?Sa7B!7oNO*$gfY*7A+#b)qV%Fosk$7@+=AO~bmX z>LJ&6*lLvN7ckXrk*2ohe;SN24q*ao+j5f03n(3} z&iYtE8`=Pe*sy!ZQeLHVS**hn@1o|#+1LfoyXc^g&QwVwK$C@Wqf@(-vrp}KM+o9Y z&>X=<(3wTitCt=1ICf-EG0Ec$9e78~?SvFfTUBA$nZ5)gmap-X)(#;|)Zlp0V+^Nypy zk2__Ut1d@YrI_ei;Fou~{fAH6Wt{iWorW%Wl*n!rpH}Fg5Ui;w%7D$QqgxH9yxIJae}JSc!zaU&65Z^k9HY!l;mp*PVD%U{RLKN0aE@_Nv+3mAV7_=|Qfe=p*z zV^Q7+jNP@0+rGN`*oTWp~Gds8DW$Yv^x|qG(DjUxh-) zc>6ubipcNMUjVVXZuf4;Jn{m_tZwb@$D(-owAQt%rFm>y98$_Z$vZ4iv z_6=V_qB-&llBFb(jO<&F#2yff+x zUy$N7f-*V1m0POj$Yap5`Zu=CASW3)AE^2_3HQq*J5av<%^M2HS*@Cq4F~)YHMP9s z5Y=#?2v4=V6Y+y29&35Wp{n6viPyKh6Y-4_Z&uM!lxpaRl8ppwsPpQ_Acba+!_}B+ z{SmaoyAiTb-kZUT=XGIxBHqu?dcs>F1@^OYgcj>hUixw*;yt*uQ3FMr;)uj3WUxve zdXxPmdOI%5s9`Zus^~|VcgoU_GH)0cseno+`L==^Al~}dBsY`j`?xHlKE~v73t}q% zO0W_CD=yK8k*+^&`8^2Yleo08bJVgJBc{GMr(Jv!?MLsya5NvhXCoTe?JSh9^CE*7 z-FO8hjH)E|ZS6y@_eMxZdB;F1o_7ka5$^(AW8Mz(=6wvK(cqm1DK~m2QjXpR43<{W zn~{-tL3DRe?H)^PihmrDwOLRkUc8hXt-I_}%;}e`5y#&If1 z>KC@sgvBD)pozqBl1N1MXX1EC)JNWh{v^6uZUjc}L4z&p%rwPO7^Q$YkU$6ivKz^-3g`tM~@WM?pS`mqp376~`-Ed%=~r92v@c z1+JcVG3t+a_d^^})z${mOF$7L^D&8uAM2s;R zht@qL5tngj-BT=fLdKzWFG(<91-t& zYP5=8ieYX&Jo;V`H7##Fb{TpVso>IjoN%Ker=nM_Cs+;Hjntd0hTKWAGgh)ledKMZ zp!Hl?KAI!#{||d#0vP8}-9Ni4$%iaiiSJVz;v`OjEhRQdAS99#JBcB&gzW?Zg_Uoc z*p~2-14<<*g|wlOISQm45~c8OX@U&2|Inte;wBJ~!%cv!2qc8q$;y^&%d6GS|Mz?I z=KH=~DHrAHzkRm8nR)YO=FOWoZ{EyzEE=ocA!IfD0U%So^9-_ax+#AQsRSiny(`fJ zRK;u*FaI2{l{MAvw;~Z=$wqFUelFrB{$3{jdd4zvUKTg#MfKlEVq$zQ6L*MUro`XJ z-oH~4RVHzQ!u{LCQq)kvD$%p|b5P=gZ1^szz{EEJQ~jZHnNb!WC70ccrXn#h{#GXb zk9Ot`R{crWnTg+JH}8?eqyse@+wfz62W9fyH8DeeJ}X(V4^R9*36jM!2*$e{d)!mh*VjWAK59~$rXD~xc zax@MuSn@WASuy9JpXmjQk^!&Df1xaXu;4UDa7H}{s=roE<8ePKa`r`x#|!=vxatQh zXn#V>;jF&c9ur$^64moD2yv)i^-C%*t$cCi>S>n%k(e1lpm@1iJqyOWdZcmF2OM(R)-n=WGny+-d01OXpw- zo8>!F$!h0ErGT|8;0`^5QivQ>%nfr`zBY=YWRlCx)f56m#pD@FV-0is*s#+t74}~+ z77ebZ;}6;hz{p47^++bnW?bX3k?JbU!Wd>L76uc;Vq3R!$HtvEZ`)b7wG}&yy6vsI zw$yFdxxa4drqvUT&8y6g9D*;BV|XY0ldJJ;=N-Lqlamb$$=wry(xr8~ zc3>Ct^x2#DY`DdfF_d9?X7cA*8*61NzhyDc+;35wU9Z~&McDETguxrN|B7qf2)(=+s_C$l=rdIGG?Kez$L4KY_Mw5DJ2tzjHg4E6PBorx$1bS<#{K*D zweH3mb#sc2}V|)ZTrYv4KYd zixA={K^A*~fzFrP?pbW$7lZ%wuB*>UrReOr(LyC2B_0wxNG4STk1KmzLp z5}R6gw(bd1!gmT==73lvAE^@y2uihXd_5>&>JXQ{ZQX@F+)AdgJ^=~wAdVdy;t^p0 zhlRjgdqe8VrfZwlrmkvQd)!`{8An_+Uc>@^sO)V7_swQWyr+_7)hhBh`4bbjleEn8BXHk!RV-nb>T&+Om5 zVdsu*ySHq16{k}BA=yiiA=UC|AX->xS(>>!c5gEj_ZVhxy#9vNsx>Q(qi$<^^5!61j2|Vv*tyeXzS)aPapEiJ+_-`Zn$79a`kePg20{b%CPt$-??S$K2;|S zLmLNqOuLtmQ%(}c)YxHKhYqh>C8D=&Oi(k&0k3+pdjUVqUA%acoX zZED+p87$boEw?V&@M5I5BE5S{>+U66+b+0>>7A_`_AS8@dKrdpGZ6c>@87i%;f6h% zwqJ%t_U4P1Y&d^c+xdI9Y&t(ua9eUo)86C~SewhX?cRUkt;r=@x9;D)i37X@qzsY0 zm9sON-oN`6=*5zK8#eC5#N^z%;3Dwvb=?m%<{7a2ckkE)KOrTvd+gY*SbOyqm%Qkr z7g1P&a<04ay6aZ0U%UFs71t6kigw+K)oaEM+VbV1?@v2eS6zSYwU|=maoL3t9z$zF zE|p_9_oOd-w(M=)c{2=%tPHfT-o$L(xqt6=)iF25MK*2C4HsTONd%?|Ys0?nseP@m z?|ZO{P%n1uO||XZuxZQo)}0vnF>-TO&Pk8@tOlgWuE-?Xvt!%#anyRO&aJurx`_Rx z{gd*0H*MIt#YAh_1dT487%Q&5M5ad2BR9WV+qPgygNCq2V-4R{%z}*@Hr>SPWOS~+ z_QvLGyyahU$(UxS2WV(qa%W`B-tCwJ$s#%I*|2*XbjvLoVxhKgp;Q8)7OlQ!@BWQ# zVh2T~R5=GL z>53&|869BX-*wkt(fq2^nx-|YjL>k9{Mb`j)gF6IEiQIV)7mlou3hm;;~LtrIYs-= z2}r83>T%^YtFCEP53e*tKIu|k=0_eD=Ru$E1Dc!LtzEi zt`|EUD3q`zQhoWFrYp=iGsbtfSc$}%jH6t#GK_;?K1N8Zm)F-D%yqhon^RKGjqa6e zo36bU_J|!T=Ci0n*IrU&-&nu2>qhg6ruEmD?HhJ)-U%<&I90`FXiwPRE3aR>&W+vE zkIKr`>sDNGEk>nOni%2Kiffy%Sz$JA*h>S8EmNRcC9K@AYOP6Kf!&w!mN1w`vfOWN z-Lq>$$k*yMD`9-skEd2wU!m4|EXRTVgj>axt(*4m!cx4q?uJ#b^7|V|eCHOjEZi1} z*h@_c)j@BIGGsP6vn#8VTLI{(ZEoFXob4U!$Y6Ve`$YTgHsy^*7#dV>nTrdTeaHHMN~1 zMW2<6Pv}!PpSW$qjy>Kn_BvP8^&4QEFnWI87TY$sx2zY9++xP@jJ&CFD&bw{(*9k) z29x!bvLug{p|>dB+1a{t!#2!-an>tZCV0=Gf2K>2Ov4rMhfCYVIspa50z#9+T@2Po z>h3ru`&DjDkwqo&E!J@FA#TN33n3k$+-1B=TNYP^Ym}F&n`}YzQODLeuP)Hbas7R9 zPIm0Z24@G%C0qk;chzw$GBemH)#JgrE3bS>a`B2iyOQ)2*ZZRs=P$0^vh#xE;w$#= z*tt2$Qx!Oo7cM{d+)`)Ktau4FVjFneVq&P%lwZ7Lg{hc4Va3GQr1<2-l-TKI(_=GY zvl6pob7FI2^J5FkUVz&O=fzg?V5k(LxH5CpM)MQg=|&)7+zFIN;k4dIB}`zmi*v6C zl$rUO;`tR$Un6-ux2hPjrY3!3D zkifpVn4gKJN%QZ)9yn$un+=-&2*Mclz_%5pK@@=m=%bL}Mmhos?x7=)0Dr~pSDANf z{+}a^@diu;a6_qtzBIq4B%i$wApv zttZS}^HI%Tgzz+s|Gg1;iSgIU%)$AE<_cQp3CqI971b)iH4j{q;J%4m4@py ze3gb{#3&w8V+k%0aL^Jr)xMz!}Bz} zNW&{NY}W9#8opk`TQvMD4d0_-w}$_r;ny|%frgK1cuYg9;gq=JYmSCzYq(6q6&kM9 z@O2vAq~Wa^{*{LB*6=499?`I%VHr#+jHhlcOc@ckNoSi^tR z@N*h|RYTslX8Rcp`G^$Lr!=g9fn$1(h8JtNQo~nh_&N=5((pD7->qSnhIecD?;3th z!|!SMl!kc?XW*2b?Jv{t#Tv?kQ^2p&G#_*$T}s0(8s4Pg8#KH{!}n_VQHHSp_i6eY z46zP8qUkI{*m*u;$NFb7gmJIe^kodOF7Wvq<~K3K`tW*9-@*{<2Os@o{$Df1x^kzc zKgbY${UpP)@Y<2$zo{YA#KigR;nKag?ZP=B!hL&OxZTHanz_#`m2-ln8?m=rie2H- zJ*`A6^-E&$G8&}_4oRZOa6QMlq^~PP`bEAdXS_wdh+rIVAljyLD}0F(cfg}VFQgcw zPKwmG8F!Ah;lO=sE2JXv4I4M^*>bZJjAG;v0ey2x+45@~Vl}uiyNkPRvvkGU>y~cV zhZ9HKje;zmD?o+dSMqra2g^0|0rLoF;E!>bTY;yeI|sQ?lV_#lPK5Qv@kd~NizMbQ zFvkKf#1*P-8YP7%IN~w!iO4r;_{a9v;xAes{Sv5m0KUF8z(ngCLVZc#SRZBJ>)VES zw7#84N4;lX-zMOr^-agaN%YxRANlh2IsZNEFVoypcwk$E_u((vE+4$&Uc-Z@qu(5* z`})(+{j`K`I~>5pzA}WqA3s7o+K(5aALO6?pwH<0@f*aW?H)iT`{KcmCyAnTQ(#ND zC-dN=r;h1tS=Ye$)&R05@GG<4=F^6G$Jb1cu5Q+9MywXf=iOg z3+n6ZBiD8Gz+Y!uIbWlnTPURv*tmN5Fgx%TnI5&8r_oSsZJ-Q8VyF90x73}AK)BCIc6VClO z6Fl%-FADNtbp(NDlp`tXf5h-3XWVnO@f=F(1c2*W98J=k#!)rb1%`4Kf>6#vKy-%U zxn45APQ!~dyi7yd29gK3S|Lb;Kj>iZFiSv^93%saM_ET@9^xtK-p!&P2dYGG}u%}fI7pm zF{4p0C_g(V$)8EK zyF4C=Bbpulg?UWcjLk7mj^LE>xH0($BShaGiK@JLEX90^CnhKLqVx3o;PJf z!-HiMPLxseLtnLq@t>O?Gm2m39v-f!$Qhn`JsctWQefi*`D2=g$8k60`(OJ0Ae#Gu znRpbkj=*WtJ`+iqg)&z#W6FjHO`!mODC0phVvY`)fy0M~5EsdfP;<(1qDd8`$yZds zqc=l_S8CYAycw23L1(37#uVatkU|xNgqP7#lN**4WS=)VsDcL>-25=ueKP+flwq)< z>NGP@7&e7RD)MCyQ<@p`@W?mvrr%VZ?&d?Cyy%YVQt{^)eFzS-+(-kf`(Uc7iLNMCNC&A{4oH;h|YFJtBvdY%JAXgHv8 zkpi`=3a>>StH>9!(C=K{oWRT;DddlX#hihz(GU$nvyLARWQ0LDiJ?7`&*uyIVW)vP zj4S|ZNO9(e^SR-iDW8i^=9qky$vrweIc6R?UU9t4`& zzsf!K_%G1E^7Dty(Oe;SJUjIGV@FXs&ms6;Zd&!R$MHI^>Cfk?zB&xl4~H{3*v#)4 z-2D;eM)Qy7oz*!4VHci4<)bH_#I#}CzswyzGID$%ciar-4xcc?L%AWSM*c9&y{Hy- zY3|eLQu$og5b6?B0BqU;d3MLC4m&)^KU3*C?3}U5RpmKznC; z8$6nQ>ha;hDzwl)Tvm1D@xjA0a*3}DRUJG2xOwu?;oL}W@JT4)wA1rHG!Gq}`uO(; zpLn$YFl?BNX~l3=*$@&(3b2*&xM-=)?Q*PsG86M+b;Re!?tcW{+mv{GSR6Ci#BC9zuK1>0^pOGo2+m#vwh19zv}G_yJ?6kbnkac;X#V(+86M4-WoZPyF>(^k=uYLZnO>XAJvp(qvN}6)-o$Cu z(69g&FNAPMmd(e6pdFu$o&tu$IS7?x{fz>9e#T17}Q*gQUzee~Dn#NhDo2<))Q7bcs@`Jz*Aljp?GV)cmH(}#S;2$3&phCUp}%65Dx z55M3Trb)EG4_K+#qG9S1)Ff}9LGy+WA1RwK!9Gnv<9}f5C!eY?6c21 z?;QL)|AkBV@)7oFXHL36)XcZ_{KHc2jIek5v?kncS+HOxSV}BfcoukC zeC~PYn-`iTOY7<{xNzB$<;!1GzXWVubnzuGUiOlgT>6rio{Qb-W&cI)L_JeQyVtlm z2*w6awgi2>To#!7a;&weZW%j~1s=>szcW(~|4s2{j^ z;3WfB4(uG*H}Ee5mmWQE^j$~aee^v?-+S~&M}K+rvSaIyeRAmZlgCa5jF?_MFzTIL zu^?_}n(EWfDday{d2sG*)LT(?sJe22F`uX!m^l;Sqt*QqE~@FBI~VyMKF#5OcKX5D zvyeV-`oOH22zSirox}9KGY`&Y`ot{MKQm^ooQ-gPEcfx*;A2|6{MB<1R>dd&kRj4{ z%pI6H1MU3hyq0s%IV(1N=fcJXwF|6iPBt!_gIBcgJ7Yllf907qXUs?XCyNfvoq=%j z*)4OXBYfdG{R=6de_h;>Bz^69EmO)7Za=SM`st`=*ZIBkiU08nduNe8x1|2;g$VDd zbM&(>=su$sT{~w% z!u<5oj`<5w|DBiBEIA+fg@%E-^N|1c75#JO13&-D#<_EVf5*yZj7Qn<#jBj0-*;6r z#>oudcy;rv(@#rO9J|^~pPn$IHP@Kgl@(=kF1Ti3*0h;%6JOmpZx%l1v+ZSvX3l^d z*SwtRnEC9r9kXX5{qgIP)it$vmwZk4yjcrl!zY>==gk29OJ7l6IUyN0cfX>gvTAXD z_~6>^+59X}`TF|Ga)j&FH=ef$hbfusL67ijH?+)|h5EkyO4PqFF+Bf9hOy!OuWqTS zLVnq6YNk({iACr&2Wo2O;eOzs)kwMbzP4rN?3vbl=yd~UE<*m|mYSI}5zgHJ{6ahY z){TcyE@swks;QoGPJH;X%>$KXki#9DnKr}ww_yAy#w)+LrMITKI#zS$)&o-}PK-~y za;sUq_*^q`%MOGK@iC>F5H2#KUAtZSWLw9)`SVSzeGk%$%}CdNv-s@Av61)RYL+Yk z-51~F@W1#Aq*4BDZ$bJzlY8K8kaN=5DQ`Cm7a~0J4&kyB>iyu~qF&VZtxj|1 zoU_XFfB!CX=9wsW+j|kB-t7BaxaBUFzx;#d%(E8R(eHfN%$cz$K6*`;3%}Iu=q~vf z!ilExD<5-wZ2N?{aM@xzvgwm%NgcwepF+E+H**klGfi2`XI%J;&zcJ_1b?x69bY&8 zJ3{bv+kcwH=bmdvzLYj+E<(ANeF^lyS9}#A(trMSgeZ6S{jOZu17^-Vw3Gafqx;z* z7k=P-j-N|^XcnJ$p3U9!6UYPgl>ZFvo@GY=A%k$PiNEj>7yjR0xv=rqF8tMBN-YR z?qbpEfIWT{I2%dz7H4V0!Dq3hbb~fr$%e~q2Py;z+wJO63fq%xqvW{KY3}L)Qo2gz zNkmUSuL6^`w@f@6I{v1NEqtSqr02U1@WFv5?F&4%I%}WEoWhr=58xw=g=W+p$49>t z`~WfQo&_<2cWrVqze}f0_JD6iPqY|)MW^^7aAh!K^UaDzg|?t*e4`tQkCP|=g~fMC zyzC?7OGiaCLjA~|{@3`A#-VO}2)S42Q8(%pJ!O+s)(MYI_SqzzdZMfCKm~tp3FrwJ z$Bca|(fAFjM)ZC3pEJX0e9qZi#-<4eF`5~P6l9+7k%zY`nF=C<~@561RU@g_ly%Z0E)bbTt-KRtkpkeepXs1zyF zGBexRZ~XKl3_&+yrk#_r7ILh0l?M5a+!aM76*7fE#>vayjCABsge0s6zJaatK7ntB zzs}Z|E4lmf>j|^a*2F(t_&1a-%h=II({n-;s~d>;$|QPlFkw$^%dm37LjJ6AJ*IKJ zOM|=tJjNW)An$dIt1Ln8bV|5~20+7ohg z)bk_c(56$b6n-5!gp7geM)4|TTKfyG-;^Ew7%~J%rM-YmZNdMbt*NyqYZ7Ul;O(?9 zRWhvLl*%(n1)3g3VxlH`IO(g@UbNDZcCl-KYUuYot5X8MT{|P|8x@1888npcYot=B z9lx$B5nNsfHb-k*3X|~5ef)0mggwSI*prY2vZ`%!EK7cwRmTsM(o`|46W<$k79CmH zQ|MYZD}v2H{dL-_K8m4^BLl!EE9+6l=@1fML>I+AS783*+w2)zc;6~~pgz}!0{)wm zZ3}2iz%<}9CYHgLKlbW}3qRe63K!H%z5dcZ+CJKv=fBhl{^gqZ?-ZA=O50Bx2hsIG z%n6EY62GfCm7Jx>Ll>}!~mT%nT^ zQdVk_`lM!Q!yVR0yG`Vvn!E^C!kyBM#`^&SoFOO9Q#Q|+7hH-}unglc_UvFYv z#Gk5x&)hKBX@4P~tqy;Z(#0S_r;6ND6Onl)OzdGD&IywJp=(#kVgeE3UU$41p zE1)IKw%son=+)fVf`RUyYVB!K!>BnwpJW4oTmRC9WgH&DBsXWNHXVY1YSg<(4+dGl zo0M{IDJJ_uQ)P@mlmbfvX(%NjMpY!hIdzdrDm0;%>P=`xj|BRlCxn<-6GSHXLQ|;P zggQTH?cV3fKxqkaKd=+1;e;v}8G$<6=pryq4*X)1;JhJB;LG=3iif9iHlCQEqcVyv&Z&`tBxdK8g?GppVuQ ztv}jsl%FV{Mf_LOoZw*?_RIAb(;EGS$7m0$954U^?w*;*Z6wK3#=K1BnI^#pc{!El z^?i5U^+8%?C>@5Z{7)bnd;P=q@LS1qyoVgxPb1ncFPG(F^@t-~!!C3}CV?)VLTH37z&p z25t5Dxj@IDQ7O~Uiu9bMgE~>%Bl~RL{ix61i6s|NoYJ92V*IGr1rUT$xbv>29&a4j zw*$)NBsX=KN{MPQmI%AC(3>I3uA7;FiFVXQSjf5ANMnIfFFrvt+bKdq6 zCmXd!%}(^){t@r_7gp&gYE>u2rlx4*R= zBJwcQ?qdjx6Rehy^{dA3GLg|{QKx61C>r;ZfCH?{Aq|%9n$&wEM-)^r0F(XVr%szA z5XaF)tL<;@ddFr_94zvH(KjHY&hb!a;S%OR+l*h`7tRQ5jt{wNNEb9(8P2Z2&XYl1 z`sgT}G%#I+YC9M&G)lC`_E)-J7QWWnmRdA>k8a~Ef{Tt*!;D~a{qo?7>Ui_*4`#1MRx%wL8!zyYH$_$Q|NF-X}j`PMNf8oaoW zue@Rq3se0H(P_aNMQ)3V1<%aD)jddoZK=h9Ann z^c5_m2O5cX*^}+AgW&vBty7rGF=@c?uj^wkvjq$t+9dn{QP+===^W5=(X(75d|%WQ zUv&j%cVMq8Lwj8vDpAVI(!i9o2m`c{I@=9;fGIqe-G)zl0O`U%|8-iF2TCWy0El?6SP{t^`8P_4B|{MyGPFjf9OQamf%*n(zD_IdKWd*-UN|bfFB5cOKTaakk&wThy2Ly*VpOi1ix)}{Q7-tjzu9XVVgXaaYpx`rA zf8aDo=mx%7>oH$;Fe2Nf4do!Z0yJbB=C+9jzn;6zp z>Gw-O#c4b%Tp(B8DL5?02bZFVSRxog2aTLq zPki8mNF`G?--!CVptpJhh3nzjQU`QDDG{3S!1u@oX1*?1XK=eq3ByT+J&Th9cP|=) z{m|INAcpzhsD(QNTR+8HIb-gAAgS5U7R0q~PVEPk7y|3iD1Kp3V`#EPqva2GXbeH@ z#?QmWd0U7u=FgnS3U2I}Q=Y+?eCyj;j8KhI&a?LGYu4&>s-oQvIz? zCfZ$37Y2L+w?^ouIHAT-ckBf<4K$Y(vR7K1vH3Tcz7f+@Kwg$^sSN02Jay^9s?!eB zXwt&(Ns!^TAkJ1A>44={#9j{kK`hM83D%#ozXWZ$Sh%_o(~i}w{8@;`K& zO(+^uhcb1Mp;r_Z*by{DIMW5VdPO=rjgBhNmni(~+hC%`qxfE^z-UW|GO-=sv4#6L zMlhTRIuH(v84dp>gmxM2AdU4SnDIcC!>4u{;3)d+Lg-Wg4YnKZbC8^D2LtB`NX93J zi!l_Z1%uJ+$#ENxj#Ry-E7(v)FhQ|OCuwvr_5w2SsG`Fq-6HQjIE;0H_+U$+{)l&j zy(gc6+5m9ZP%Qt;s5t2*4b~#p6pA^M*Aob!iTdoDLVgB1BX?2} z2UKt%vY~Y87q|Kufqa-gdhi}FP&Iw7VcCBLY!q53HV@s=`2|n5^fRDlS)CCyYU)mLgt?`7G)~asQ%y59CrTGZ_$E zoIEuZk@c8yu;C0sr#;|2P=6A>Bjh@q&k-U2mdN+>hplh9r6y>75OpfRI4Kb6$M3gn z=vj*UZoW5Y-M-VeZiho8#Nc847>5DyfsoJrYqAYzW_nexu5G*P>!6uc+N;_KPGu(Ywmw|W^O-Tvd@#P>&2DoTMTr#kwBs-E(;r%<5!0c@! zo*CFobDIw6v&+yGcNC6;bav}O&9L@Ix(h?U?IUQf!7(|tZ0Cb@X#1hk#d zcuC@fq#2ufOeB}&A~>0+f-cEDV*~d;E{UL~uYlGx*y{SelEb z&`gkvp3BbM=T^80;*;hU=~R$p$*`JWO(PogrHiHbd89E8L4STH@ z71|6l&}Jj*$NPMd%{8`&X;g(%e;K)muhJs4^!VJ)@gUO;IPy-qZDlW#mjj>c!+myVy|9q?`eh_;!!w=9+&0xa z22%EJuR<_A0lL9H;L#9yfbPN8OD$tvcrLWSj%t&mH@~@Q{)h=l}lY#O#!IHdxV8*)Do};P*?a&s$TG`+K>goF_1mxL58ik zzl={+(a?EQaDrTHTB-ONGCn;p2ZSxG{DJmA3&TX=&{NtmWo@f#8WGA+Gn4bOPf zw(wV1u}Mbh_%WVD{f{{}5!(ro>%%894DzH^nJv$qqWQMJ0UrRTe`={$3tw%H>g-Q}s>8)iqAOS$ z4IWGPj$`p$&p<>9Q{ZN4J)EoUUv~H|dk~KX^ROU}M`*BBu=#(!9n<5KiKo#Tfu`c+ zF3P!t`>41R^|^Y)G7ih@@u!R5#+AbsaJ}o@ES-R6didYClf-y(zzMR7sUhNf;Kt~G z+YIbef>os44u|*uiNS;Su} z=6@+B);IqXI@t}>5-KO)0OES0GTO{IUsbX{lcxcyoG}+HTfH7Pv~mnn8LVpZh9itrjnoVNdlAX#`h?r|YmLO0i2%jPsgCV@|M93x-K`8c&=0{sDlW3)0NO;tDU4LaIw}$0H@mSE>{7|gQg8vJb{cC z8Cj-|a==Y_#(OMU?MGySjH2_Urh>p#fGxfdwMco$kQLO59Lq&#P~KJG$|LV6*+2tb z)D~AB3dEb2SmDYrzM$zvEzn}fqlXQU10Ej`Y9S9PFBPO!QLyKc@=}48mkOjjDmdiJ zvjSJ16{P*L)Mr<@6&4)SdX1XEcT3noRPaM`CQxUy(m{41rabeVj-UQQXAtfa8&R7QMQlCx7bE|{zk zG(>!ebbX?2G3U^#0YQU}2J=WxKlr#J&6w*9A|t@4VuI#Ge7H0DEVFw?uQzj-w5uxr5CZKB&k;;kKZivvygk#d|rAzBws0k!Q$@NC0!belp zAgUz}4D&+vAb7)~ODq*k7TdFv2>45^Ob_|wg$}L} z0-^xvU~Kwq8{YDAS!DO9f9D;j$@WxxIBqeFK*19l(;gfw6Nj90Xo{~<4~s#ABP@5&I;*31-WF&7)ef(pDswri)~6@ zRjk}eMRP(l`uHEBvF1o)2Yeho>-BMHtiS7g*Snemv01w)5V(=sAuL;Q)b;;+QV3n-gF@ z8aSj?pybygOcTmhP{?W41|KLcCA#?9b_XzZqZor4M5frrR%r*{!H}q)7*+zFgb(&q(y1%g8~|Nc8HRH_@YL{DN6aSqDTO-7m! zcIw!-+gz2}C3OFz-rK@qdLXxy{YS4fXflv-gZ&s~LcoT#){jT0?at^ZVF>-$fs1Zz znjJA1Y?pDyH;}+l4@W-@mCDg^Cgf|$s2GD`L$oQs#~#^(K?hpme~A#WEU7V7jOk)b zd?EDxCtL6&Ew=WpVl(E#H$&H8EgCNWDy|01%KQW%i8{|TWn!n3c>cK z*8WQLi{i=_0^P2Ppd-|Eti;I}8#n)^LL7D1xfv2elh85RFzTi-_>)^d1%^YuFXv3r z?hviLoa((Z?%;G@A+yzX;3_}`o6;>&v<@xcgWSCD*2ewG6SDRm)HwkJ?5e!@hPK;S zDDlRJ-J8+DYJhngEP20EB$m2|TBz@B?O+6NQ{!kf%^2om3fGalAdz3&ji8em4QDJ*Syhcj}5W;zlI;gYnoM`01s6ZD_j4ZRnwskK8XCt3(X31L512av<=Ud|FgpK6!Duc>HoZA7{8Jx8s6a zu?5QwLADYHC0b|y4dX`my_?!+v+3ZW>_gd6KI;Rxmi_cISK?R*sYmy7hw-3+0JuEE z_3Xt)SyZVEO6grThJKfUyDY&rqtov7t1_ezI0_B+U)`MLe2lux2UKJ{R}D5Ba2|Be ziWz&zsB72+HO5#tFC7b=Y&hV&kD^0}6Y}hva}IUIela(&Kw`f6eHI4U&9DxlU*k%0 zS60Ad8>=w69t2tj4NETeaBg_fc}zBu112bUd`VQx4HhvS7vl=zgQ`h#bY;eFpelZ@EMdjp+{Ey1B|xIzLq|GyaxhK;Xa7$f(tcRHan#c zkOP{G?3qn@xRqud1TL~30tWvpXx15SI;3@+14B;GBEV>^?Pm1;Thp?0Y4=*ieU3;I zlFa!pL17rXGqNP`ge+I9W(wvvx`&ErRdmM{*@#8=XOV4Ncc@j|QPsuh5N=8mn;vwpQyRrT+B%qnE&lG;j4W*lGg%++cgaR=?-g;{v)-0}D zuo}JazC>@Ms^uIqWJC5}K>%P?pIgfqoCehNkBF6}8I`GA_Qs5x-$Zx$NrayD0ztq8 zlG3Ku_ST-N2L>NrMWs)?gH}w}O$*P%t)#SQ;@``@n1|+sXAWD*4a8d-{vq~*HNsz- zo)e&x-3AJe8}EPfK^56CWT30E#Fu@_{v_F@)a`bM_*p!TIq?TWb_Tp|(`6AmlvdRR zYd1kz2yn!vy5Veq#_-88ZsF{SSQZap{e2d*uLbT3;VY;n-p5!+19fZl!*Zl^BDkS8 ziJxD0ODv3WuRcz}>Y8DYo7tMlpw&93G;+UNA0?G9eCcedm5J>RNIS*lX%|(_j|a9@oJOB9 zwgOG+;4*<*fE;20tVg{Xh3dP$b!n-z@QK~|u!u<}Sv`r%?6E3W3})^CF}PDP(Yb=C zyq_4{`-r=Rp+OFWXgu)Ho>bYz-!%iIvE;T(@3O;PoH=q2rj~t26Ak31f(O`@6cxTq zDqn?|LaCPXzFnsPLc7h%GT2#AC53i4iTIEs z>=p)?o0(R3xnIyZWgu( zK7%3F6D9dZF`l;~US?sL6hy|@{08Sn#hbH_7>-gKkKQM^%V*bMBq0>uT>C9s_=i)vGj*IYH1=XAo zmAP74%ZkxD&i3*`E%jrD;=VV4NnI886TNq#ma@Z)2m~)!?uR z-fIeeYaMum;W%dQ%!A-Lz{P!^E}<&>2>g6Y8p?i)l@gaLe%POuA zOG}o}Y1!ODM=m&R;}<;g?bWAmxiH~MWaQGBc!9IR_m!ojkAK!kbixeJEh~#o&3v@bUH%ztm zj1HGn&r1Y{cCBPQ7ul zmA~=&_WO`k=@^l}(y<(8%*WG>@pLFb{{+7?@7xr*)_1XuAt*oyrzCm`9&ah+{_r?q z;v`*}07lQd571%eFi?=C&TIHHg|A~ZUzB%8eT9$8oaQ@RArvI~N9gZ(yo|^5Gxaf= z_djXOny_`G3JA=ACAVxN($ z{HMt=WUaw#lR<58^9qhItgRIc$qgAi4NPc6MZ!1!nFk{&kfC0o6FFg^ z`k+Lp)#0f6{Gm)IAjQ#zt>-NRvZOfdzikJa$N}YXTrdw!b*JM2E(Mu2s64bR^9Gw# zmL4}1qXgRiXnobF%j0VGP>48R7VV=`vW?*gizgGi^&MnW+CZIN6N$opo$rP?o&|wR z8g=--DGp~N_5fwj?TL79Mxkblj0f0&Sw^L5AVE#_!rqp$|E@2*1c`oU7yM~c8OY?k zrwidJ;WysHD9dnAZSED=ooM-`eK6|NPE zEVKnEY~?>p%AYhwP>3d0t-qicgHxUBaWqi`X_UlliUKRMQ3OxYpFgS`Rs4k%{55Pv z3oA@NhG)4Q{K|c@8E*MQim~<{Xs4WT1QAZIS%qwY5}G1&nbV!o#lw{A26BbltWpF}wIQ4~Tq`c5U7Hx6o? zf*Ft%SAQ7`=2?ShBEqU}Q9s&FB9KKo)F2pWc-ZZ6gfor^#}Tygm1&(Ej&TOfq)$eM zcDHC$1*S-e0!Uw^CW!@?-x`%h$rAM)N6FDnOy zVsN?`k;1Ggg;a-I^b7Uz3{rsa%J%5fa+sK}3H-Mqab>u5%D3ELLKx;4?OU#dY^Kk*beqP0#jMtKm>v4|0LWb9Gl6=<`FsIrV0NYF1Vtuz&v;)+`LvF55jM}Gl>3HkyG)k+jm4t51MqnF6{v} zf0g|TTF(ZEAX1Q1lpraQM=1*2WeK40E)|Y$o_xlG9^K>tmNx8NOh{a&zGnOBaJ-gmn}d=Rxm^+ zIT|e6<565tQi9`7HGnUsh;y5tPh7F+P0YZP(ZF%w3N5U|H|4fI2Z%C89xMhOv@0}Q zZo@$T+V8{s=>_>wvlTx>O)b~vHdh;R3mMd8VRxL~=weMAHjjRj*~v5k+zq&*Zc!(0 zs+%!Hw=+#hTz@^KMkwd+PXN}rBqJWGJ`Sfi!uXPw`>1jUpOyOMmN`zQOXAhrV@F*YSBv2|JlX)S_X9g(S z#mgTRGC}KdYeZ7QGl$S|FLu=RjYtbO+3*BAB2w*$K$Fg7{WZh6KeuxYU7athJQ?ZIe z!1DF*l6y_chMGEn;{}w@*c!Z37a_(ro115TZ7UO?!3Lk$O@WURC4`mYgYkt zca)p3I*w6M@NxpV*+|Waj2s9w;_>kSD^sH%ghx%SO$X=!a4?AW@~CDwz*^W!9H8@& zs~#&-lPs`N&!w~!?iSHkBoge%bz zO>4X_Qg4_Y|74PhM08w4So!(}35za+W5{s$S40sePHh`QoUd`R4T;?0S7#J~_yKTK zTY_r=j^~_FXajDlLwqK!8NI+YN!%T5F-mVMBe;W{s1Dx3pBx2nXoCG&*5!dLBy=b@ zf&t;Z#0ptJh#v@awXv|Wb&xKLk|~ZAHM!aXI#QH*GDjCsAPXS%4Y;_!{+DsCXU}%+ z8%r?W-e7P%9dfMpe9yCtFfek0!;mJ!%%&pM?XrQ<1qrzDbBmTP6t(I_y|1Pnd4bI7 zlRK}H+3sWvb6TK|Sr$e@AT0@faF(-|;0%HiDruj~a%Z67DIVSY2A?JU2nea=(1QR@ z6VSvDW-GM+o`5`*I&F$e>pB)MrIND|Ta~%qY znlJ=GH60j`gR!*c)kDts-0b!Y)6hsXk2MViM5GM}-doejRGV5&#+}ewC5lTorCWxQ z1U&?FJFr}mS%8Xr?C8Bo#ulw?WB`b*04E(1g>A>;<%WU=B%_sz7WfPuh;Ej^VoHz_ zUL?%$YZ5cWbt4rrU|k&`W2uiL2+ze(0;_;_044lBS4wd2A%!GEJY?#HgS7p? zefKqL;tnXnGs3lnj^g~L;78gO&q2y3qeRm5yCRsWf_W^05roYLHo)6ozas>xBXNs? zlytQKJ=&->c@lY9o49}^(A+J!-*@S- zp%z7W5_b!nNUi0|oZO4=sHuB#?Q)fr&sO{dgobZZ!5GZi=Xx8jEM8 z2ag1^=aIDQ(!sz>Pz2mPW!w>nTj--2{x1myF%VG;Cz$`Xa>+RU4|#9Y{=gw{(ym7N zxUX#}a*vQT*g8kp<{{#t)SvdTw20`aX zYi9B0YzX((#8!w3;<9q(qTmRmlMfi_VYc(S)WhqMx}1*?b;qzF7m)3ZW?1YC!;^iU z$odRhNQN0agAX!zfTC5gzUD}VZHZ*yQ;NSA$fv_I58VHOH+49?dHH>x(^zp(zP~ulvnP%~ z6c)H+@(4*u4FB`^--zdNFEL#nOf0iDps zNbKHmI=e(|3O8q7Q?N}_4dI5ZS4uJFl#4N^jDLt2XM?JKAEF0^nK;$$j}|=;@Suks zWT!=t2GI@|Gx1ED#!7+-qe;c!8+{tZ)bvqwQ==SGjdEl9M~iAV)8L_3IA_cm%RfY{ zD`<_%;M(QQDviNI^D)!@U6t(EAht4CWL+kXUjp41OboRjEh^XmOnnqX>lhxCF{cTb z#y>rhGWm-0-+;NC#NNh3y&^aPr7earh~n(=Q|VIlr%N%PcGCH8Bf6(!w*fsZQU)G- z_eO`_#O}Dy-KEB!SHvD(#ty*AG4dXRK#R``=~9YMf1wyt_^9XcqPrh1{Ol9OeK0Rp z>QhmCc_ygi2fnm1FBRm^BriM;>IAm12VTKnFuTK%%e`DTy+rez3ng}2JT5)8l!+_Y zV<@)>EQq&3v|#C#G}v6yZQ+P!p^IqVa1-#) zvcE;@=rCOleZcJ~`^6b^FLxkg(3LvweAHul+=%007J{D#H<2rzoKK?rX{1KcFRs84 z1DQvUQV3*`kh9gKiS7804ZM};mky%+vo;b>Qa0|iwoRh#ppXp%QX-LGC-F&9cEI}v zCeeqKee&DVtH{C7pAjuE+AMXsOW8*h`<@6A(Zn0SW1sxy-T=A#KoBjCG!>sEg_#(~ zUxleij4}(@jo{t3AGZw00iMo^Xv+TPVf*C0D?$=EuWvE4q}$NFNas4y(8qeTfB5an zu+SQhJn}GOg_a;okDLFk#>93qORXdF#evHwNm&kVBAw&;1=N=y^UC|`m?RnGG@4iL zLl&amZ6hW5YLnZQ;+$)ldgQbtryIO~(H(fD4u4r}#VQw2@9b9`xgy>QBjA zoc4ADg*^x>brT2L=%xl5V1)A5W0zy576?(-E`(GsvJI$r69^1Q-$ni+&Ox1UNxdH; z6TX#2_?2$JAyhAvj0oF;yWdW7-8G9hC1RqzKx%Pl&RMVq60vUg%om}(Jsv++XqXL zk_Ox3&pRlZ6Z6<&iJ#Ym$coGl!$cTEr;9x`m&JMRls6=0EImGhO+aI9C-RqIYt%{90Et>;8Y_V`HJtzcdXB%3y zSfCpmI2lqWlHe08uM~wI(OeKN#_Xn{DaOTcABR+0HGF3}*n~>4?0OA^@>1y}!WY`eK zu-2nt?tDYAc-m`Z=GTUc>?xD=Z@&m@`BSyy!9f||F*$hbXFPiSawU4BkVyJi z7

_S4&h>h{v1MV5H5xh@kbAty~G*N!Qtf4w-iBwn^Z0*^5gb=#wGrab)-koB$U9 z+Esy34cmg5i|u6EAy4=v4bv-$La_{ILOU`a{sCQci9I zUPyKl%VdP-SO&N@>VWnwjVNH)xdx0DlDq;S)OLyB@`#I2_}B~5 zgzq+<2T2y30JbgS(V9aUKjxbB0jk4r6~p*CG=|KKr;|mxdscD1@TK!L#i*1m!K5%D zi)er-#t>125kwT@5D^R!6k1R-5ySNUJw_0+A5e@#L@e9H%V|G0<52 zQf>r86+W7dU__^BHGC;S^vcrY>Jh{joqsAAMT8iS2rvP{V?u;tA_#|hO9m`>7fM>s zMi7oBitrd;1VWHfK^;IiOoYN=iV&nJMgUWSFmVjUbAYEiPYVw&ODcgMQivJMA*i0%jCs zANU#YR#*b4*I0`sHCV7TBW+KBpGG{_#RdtQvB0)51A#*a8D<@O(1^f;mOxT6JUT4# zhtHUFxQ1L!dV-yga)pm&G6O+z2K=-UWZ>-`3L;tpqWhG*^+1^-V;_flrF)amjZcfq za0yIBS>BKmZww_o47+`swJgA@0&q*6-k5UgAbD^v8yIP30b}k6ZgPCgxvSys*b%rZ zifDl-7IAzuw*=#pGn0%Z`q)_UmZw25dJv`LN>)UuWJQDlF0zRVaXyxpmw0?iLp+5z z2J&Mt|BLv8Ngx>Wu*G~s827PfczPGgGxwvaL17TfjB<_^0oGhOkBK0;}=g)tOiq#d)iZ2Xz{VA4DV~ zgQ>&~L=cGnx5vqgWh;}eAMRUy^v$#B_YXfLLz6A&BcaM z*c{|oWC*z+Fbd&{F^pu{)-lq&|MyjQzxPIxIYO@A{?p*sUDegq)z#J2*PAE)A;Lad zSD#tNK}CGa4PAW5toXnW^1Z8#M-J7jh+32cI#g?yRhkaT#4Sno8%8AYZYO*ae8=lc zJp>Un3CYYL_qq$Hj&USL1l#j0WqO($9vxQ1rI2SH)UyeOC~jeELw1mhOhTmf><)@d zQeBJIbGw#_M4p~KB45uPtO7*7o-L85XVbdJte!i;(hya%v^lUw51?1Hp0x`T>+IBL ziQOoK@J8t$W_Wx3S8ry>m4%B!gR~|U<&k0IvNW>d5SI@0T$bt;9M`9=gBo^~`648XGx|gMw z_TUmG4OaLIrd*!r@NV`IPjUUg+R{}%?3oHPT)|7qJo<>Sb|5$*Nd;(niHQU-@_iWm zNLz1k^(L1zZGl3gF(8@(2yp;et6jkaDP;VY;kwmsUlW1}PR`ZDfP~fQ00umcm39aQ zxo)On90~6=vq?ae&4q|Rio|U6FTeZ>viK8+hm+Y1(=l~s7KTnJYaW(!oQfb#C-u@5 zz=&7!W>sdilcXa+BI~%U?&3zodS*=s&ts1;Ov&`-n*uyuASqYPL7EryTKJXL^le-n z$e( zU54$RJ*x64U-l2peO4z=Wm+cY4Q7uXA*fTY7*F^BzDLuMjT~0a(73UOg=rg3u(L|v z!&g!=%<#gH%1Hqj){&qyHHP2;{RbV0{Hn*O-d<=8`W23tr7Twcz773cd!0_bnGnug zJvQ+;Q}!VSg^ix`sXy>9p#{UwX?C&=31HvveHAHy{PxEKz@IkRGm+hB^+eoBj;azu zX?9y^HiN!bmt`ZMIvHE07QMkVOFL6a%9vwbd%dpdj9)c7P{X}m_!+;g>5N(po$=Sr zLTA=;!*rDOs>0O8DEoq2#RFNL!LI8M+F{lgHn5RR`K9WD3yAK(9!~Caw^0BRd+U@6 zLQyTGoj7o9PlyR;ZRuNrub^NC z?eq$vZAQC9RR*{6__Jp|8H~Ly03})jfb*%$`vV|v!u2(fMsf|;1F`QtaNym7(aXHu z5Xv4}FopB*1fxFEpe@YPlv0QYcW{YBK8b*M_#_7Nyd-ZDa(PHazIuTZ2F>C9?8??~ zy^*CK3T04j2MvjF9@wWG)Z!v#NPw{^#>_Y<6$MD#gX2l?>mozU*!OHE<+sRksZj`| z^@u+TncIl4Buwkz^D~IQ1PK@M*|NxjJ}8Sc%YWqp^lVku0{dlJ_&Bp^Iyl z_R2|oRcCq61UfJ)p!2d|s$ENE(K8eH?pf4Ac*mndYWBy4%uT@AjjuoD*!w4ceQ6wl zlM)_$^lHu>9>O?*3Ll}p49-!!pgnY#2b*ypT6VAtmd;sksq5Sf=uW~IUlu~M$uK1~9kqO?3IgbutWKi}@HIW$2tXn2!_N{LFikqEkKW5W&se6B?Lj8d0%YBIWHm0x$K$x)oWN44_ob^QPzDj^ zbR7rR(q$=B$AClXgCNs@fNVnmWOfilb`V5%7MRWk%}N#|`ZRnbi`W9pm0%HOKvg7yqw!iBfeFWm34ifZJ+aVJV&jw zpSJwWV%je>Y;szBlu7ADmUr6n$j=_JBtJ(zvJP|I!+TiXIsYp)$<%)q8mShAhcK-{Uibf`K4Yz!)>e&uDXi8(VJOeV_=>BOVK-#$tjy?c@0E*|#@J zI+V=B)UvNK?YtGm8Ga?Lo@?J358N(}#H5gU(D&F7bby{#B$N8kVf6|0#n3&h$pT1;ea`D%lg)u-2GO`xumMDpgiM|=Rz)#o_N+FsJr{xKu3mN{ZB9L8; z3{S5CyzCEaf(S1?^NU*b1`)WM@^7hP<9AM|MgnZD$)>a8UX{#7Sm?Ot?=8l}gUCqR z3oJiQx+8dfvCos&OSIu&>|_~WdD0V!my&Tqg2GKwBKwerL^_z2(VwKm;#%^YgcVx; zycwQ~yo4#?!CnFxV|d-g?`oUsa>qU+)l7V_qb3c5=1_G)=286cbJEbPoHzSj?WgX5 zfd6+au_)N~8tUHk$4kgCmN>D5vBW=XhOxwnb-YkJ*w*aucS{T!gGvA8eWK@2O@DX? zV=tUB-Y0q`#{0xSN5*)c=+*H;?Z~!5LVvf!zosRMFY)iF{Qh_e89|?z#VY6%|6CbC zpO{sLv8$7|%W71hSI>PyvEpPTkt@`A{jgAEox)p?z_P4lr3*xkX+IW+&eBnk@0uC$g3uLQZKMp z=S<**-r1j+yomYU@FYc)ypS?cFp{py{_A6>-I>Zf{7%b5pF+8rR*mppjrzU7wUA@9 z0}uT&bTw1m9emPEWMem~H-3lgrEIr080_vy#-D?5a6p-D0(Wcpxc)E@vz;U|Iyn{* zx}AE$8S42&6S6DnofOVBaEyHdxNcmh@iw!rhc5s%A={0@qzB7T6fm;+=O*2D`~$p0 zRaEgJGhM0SDpke8?*9-(zNvexTHrdsV2g`&0XdixOl4{X#_^4?G1+5L^X-yMHM0ro zcY+@9K(Upv3Z2`k+EojZ-5UIvs*vw@jo=O)WqTlbtLlK{3D=GBFJD#2caR3LHXobP zgI}7AMcJ?#$THT0qonx)_L<%IAr|3L$D7@Bl?L%Ku1DR>PZ|t_3hv~$*FWRIMgnts zCcFG5&2lpjAGCY0bs)yP^U}i!|13eLz7eSZq{+7Iig>x472q!ZNRrH=lsk;8u*Yz4 ztGRUJ1QA_1%KngwnBw35V8-7`o=-1SVrz#>oodwuI|-_53Br80lEWqtuw0kbxra)_ zBJ#n^3lsmKz#GOm7_vi)HwJt>?ZXTV4@um3q~OLOYe_ervO{oagdZB{B@lwA$!+%= zWS>vhhTrZAWq=U%8f2YENLe(}uSMh&WNQ|krW}uB@d-E}YsQt8iYDU34{Nm43o`bs z4gW9VTBHrx?I@cBXXZTQ`0Z7-mN0-5Kb+0a_eKFa@4cuXPS0Xlb;zF|8_&;P)n=77 z_xiqVD26wVef!;)O6o;DauT*pCjNmb)-n!ng&gO4Nu}Ry^R2-vIZ9rW6wr&YNeW1Y zEifdnLOf{5z{wV9AHk5@~ehCl<8E*4b&dqElgG>V7LpH)XxD3Ztp>g(Vedgbg*g37BQ>gRZbu9|f- zQ8|&H!uG=ZS+I8YdjysDPy{*okq@Ajy!^c10y#4$vVGTHkmp^3yl`a^9_3RPASd@u zJi`A)#H?v&5%FCjzEF%uY}(~a{}QbUFD`!_Gan-2U6l0|({5z?Es!r z0px@VP&RjC@#g{LhwAanZ7g{P1jV82P`jPrLO%c|Z^4`v0QsTmB>*ZG-vOXF z^aGN`1c-)~3~3)Z>hKeY&mdHL6Nu&yKMj{NIpE&-_u{g^tr zzLama6o-z$%JOe0JBFNSXgg5(uNUddL&s4*{|$?WkuysbMGKbx8k|b@pQQ@U6y>Rs zTakW+q;pF4pREd(NjkseR-~6px>$ufQL3OaOfhoFA9=4V&Uc{; zJTbJ478eUY;g&thi-o+VB{>WVpMK)Er%N-cCQ1)oLE+fnZ+&VxuV zb}m9)r#inw{%KAG5-xGR49X?WN5FrI^9WiIRpGU$pzxk>A83n;i>{@L^B*K|ooF~; zMK^6xMb}f?`T6-HU{iF18uQmq{RaS%T0F{VfnrS&Byy-^h)NmiqD>^)i^nut zSPm&w_%`OPn|d4b+VKzuG&;#Q4DNz@^EX5flIXwim_~cdk;hMvQjs+fBl0*N;XeS* zzoz_QM3G)R%GfwsSq>ALUxdRh(u?}T52HJZmn|wp1#>o`e4Z0(LGMN~D4|UycS&g+ zxy}vHj&d%9Rvc#?o+0N(Jae4ml+C#vy;0y?11%Rimr{?;Vsw_P!uKL0_q_02P|eNB zy*%<>B<3YRk-KUtC7QoyH^%gP*6o{B z?iG1A0T~Vb5=C>boHYYLxr!{Nehx!|+|^-9ZPc-*v<^5YL(!abW#sGx|B&+-)Dc!? zWgy*!%p3}zBPr25A1bl{$OsvfvB9@{BuuFY{YPX!lGErveGV$}VZaN1fZB5V912#P z^EnhKxgvKOB{-MLEBFiq0DuJKfkdicj$p#7;45UWa#X=?NkmjZq0r>2f}epKdQcUd z0hK{6^g@2=yd7YheBS>^SnM3N!jfMPzWDPS|BtLWm7?f_2>7zJQfyzp^3t2Su z?*w)%q!?3Ghu;Pyi0~Oi?Oz9`i zU`9@8j8b+kE(4GsdOLwHn8w^j)?d_($^UOQ^UDGhv`05KH>=WvGI&0gpQJorlPu?x z`Cp*i-xetJDHtBgMHWMpa1w5-^gH4AP_}Z^ru(U^qI4Ai=T_;b`O;6V>?e~Somu); z=KmBA<T;af$c;FgA#koL{V^!t2gLNxAyMn9Tr#Mj2Ao-y z%!tr|s#1#fUjV0&?vpC_b4V9bH~+M7De;Dk9rs&HcCpI+8Oe@=#VLzs5^u<)jSx(@ zIVyL6WK?eDqEo}b8?qk*v(%EI(m6;M?nASx7tJ7ElNG)OO?h1qQ%XzO3<7D@okc2l zJxiVmY}2CY%rGU{8-F-u**l?TgPDSM4xO?%=E)lS5_M6!c#0-iI0po!KP;v5_%Rr1 z|02#~(K~=Ey+4=!$M+oC>x=JE&gm*#IuD%?g87wRSaea*D~nc7y8wvri~s_~BWm?D z$W*3^7UnROdzv8f7OSG7ONzp!u)iRSlA@cyq(In1+`<*)w$QmKLjIvyuFm?cZF8of zMX#ETDQu=~NDbH^C4ZpQmus-ffM$_f(?y zb~f!|W%%FVnl{2NZ-!}VEH(N(j83AtTeffB+PD`L?AX3pv)b6OdlEL5Zu?G{|HgfL z_crZPYRAoSvW-Kuy^v*h!`}Fcs^yzFxZ;}|w>0eAu{XZ=*5<}N%eQfC#`o;qj14>h zOhQP51Zj*+@Udj@LWV1{;64Gccj6oOZHYJU-hOk#-bQ4=?*}q~fQtg6VRvH#0L&Kv zHZ|>N+U-FicN|-0k61Jx;E4$YrJ6S02nx75q@`_JcA^dYDKzFMAfXe_Wzt=te_z2fY%)jsGZzPVv@x5x_u7(}k zx9)1(tQp7S`=HqikRfb&G!QH-v@Ffs?Yp)rs(XU4*Ij*0eAU{^m8NcP0!IjrQjNRz z?!Hy+Xxg=U!{9VdYU@Jh~J)VPCGH%HEp70po-O3t-NB@rB`p*P`ft1 ze#6QQtKxO*R;^#Z>T*`5huyZu251+RUa|J-*kxy58`IN6?Ch$uS5%#M){5A&otv8X zT?`Mlw{icnhF1dK0(e(r)2?M(n$J3q@Q$X2y~{9#UW~5W48-1T`*v>z z-hBSDhBJ3IpSh=T)0u&STVu;=_r#XL+g!YL*S@p&$Cho`vTxTWcJMNgGDh|mj?N&w zZ`Uobi)DKoHtxW{I~uyj%{v-4HEwI#fu5hBH|^!L_Gr(>fn@m=8AQ9cZ{0SDSx>aNwO3yi@SpU5Qhv{- zh8>M6$Ym2Odi=mxx#j{H8eWU^_-bly#FPdLVT&d@zAYF98yhy=M0V0USFE|N?n>+V zS6(oo8rlIWnv`5S8MS8{#y~7f54#(7ZG~;=Nkcr;wnl12?b)}nSv;N?&*}}Uu3A4q z(R9hMiSZ3yyK=+oYgQ30W!JA-v+A-97_qu~4tfrVIOiH|F=AQc=O*d3U{~6ft-t!x zx@+TWYuBz)Lc{K`y-c$-p4ZxBcCjmK*G-Uj-OAS~UD5W8?aqyY}t$M9pGDY_{8#86B*%1_$R*c)@iW#7}z$C0!u8 ze$Cq2OVuPJ#wsD(h{T&rVq7vaOoA6zktNXT6;)LVW1UOI&2cHG`~0$XwQJVEAF*NC za%PoZb3vAW^Q>3*@ujsJu2kC^c5U8)RjSgaip|h&zrB}Ty>7kk(UW(<<*V1PymSq^ zV7xZb@9~vu>aJX=Ha6^`gTe;mYUcKPv4>#J$J~Qpw~k5 z$eu+6#2w!|+Ka?rw|c{srk5Hv-yFYXLN8u@-8I+w!&jTf#-{!8ZR{zoSvmRmYYM$4 zZf@AV+b)bJ9UIrcWuf=%n7321_IOy{k}oQ`MNP6YvJOa_gk3t1Z{O8xF<4(GQ}RR| zTK8cWJ6m=%Y{dweWWJ)m!s^*ypP4C0hT%%AhsW28c>)HA34|_(yBN%mwB1P@`L%jZ zkx9i{Tdd{YLzWd2J%lubdYAqlU$ZP#I7eBn>cQq!A6(cfy{hxchSk6V-jo+@(wvXv^gFmGkPQxGZ)7dumP%AM)X% z=PbxsglmMQ&gDE9$_hb5j_S{P6+g^vZXkq}K7O(&9M#*T#9{1oap)BYIclDPczA`Q z*FYW*t#ZfF=c-c;MI9t@)D(5Lf%~wDc5n~)Dg&R6*uf_CQUmh^42PTKKnMfQmM34; zn*1+g1MH|m)nMRHA$G6e%V(?o5Qe^jA&kq7ULnTF;Y{9GKc6F&n-<&1gG!Wf6j zQV!iD`4~hTPaznUz_`=GF^vi>;x(3z!9w6Uj2Ger+Q7?9%<)9}8WXQF@p=B~(#+r&#ve4dFf zGco@JC+Xi{;u}qTi;3T5;t!g*)5PB~@sCXW3ll$S;-e;ZOXjfsz#IAh`*xKy^Q(8N&_&oJ>k6E8CH=_X!o;uR*o(8M(+ zezl3$n0TFuuQl--O}yE}H=4NF#5bGxEhc`ui4U0geJ1{piT};SohJUgiSIP=f13E) zCjMU&KV{+~7(Vqd+r+1vxZ1>W-GTg81AorMhfM66xCqCsnE0nAe$d3cQzgGAO`J0Ekck}}Ff+f<#PdwN)WjEUBmWtU;oPeXd@*Cp3w-&8`L&EOKip{G zTNq>h;Cp|}e-C5KEAKP##~GuoUu1kL-qJMqpO_eCqC$M}aQU8FcjAx`@!s7!-eyxc z%G|4#%OSz?jo8>N$ChyU?j|CZ+bJ=78Vyo-=O#g|=c9PG^nQT(eBA8?~ z5Uf)#D{P5z%K?k_S0ULLvq%wsn{jQl6{qc6nxGX)H*DOvyYXhN7=w`$1hh?qvfnpp zs8!)sb|<&mYWd1_S1oVYi{nOIML`!YHo%0iuH?%WI;=3UjhM%<5dWBlyOnS+mngkLwbcw-+qG zwZH`VJqUg=;K+|Uu>7_n9ptwIaB%f(`E3F|$nRJ{KFVeJ>GiwcUc%f{*uc6NK8%0C zdimBB_Zl`>Io{Yj!AT`_zK_hdHMQ`Q!MVKi^S@EECY#9UKR2tMvs)s-KQvXk1VImEL= zn!!f<)!U3Yk#ViI8581hve^7cNnSacS2BF~j>yy!XAnMr2L8K84V9}I!zHLRgzV$z zsq^6F=M@yu)eEaoT1Acx4n(LN^@L@I_`yJ$$rx z&QpLp_8%CK( z4?^4{=_4?PfxMEbDwP>hnclo~mGiJQ#8p3S4kwl?O zByfoO%E9aJK855{HtCs1IrL6E3hF$HV*`dqmdWRV146!v3=BZ;rjbWb$BALppE?4S zXray%UpR>BelNW4IX0s_{kY0Ip&lI@%)5WMKovfH;;F+JU%ytTp+`Y9Ha7g+VfP*( z=VQXSLd&5>)DUbDDKiwZBvYXJ^U|5ruo@grs}mgAne=gpIILi6bVLKNtmDT$9ibBj z(Y4Q{(;ytu7C1~>Lj%*IRP_7E(1?o6%|I#X5;gqzV4 z)Ny?H1We_4c;Glp*95OFi!d<@z1X15>SWaEEM-7FFk3wyB!h}ImPrd#>adFRmpJKO zrTT}}6RBsF`u*?|Pxh*miYyxhE;D@mxnoZ~j!b9(U2y+Md0GEcD)fwcG(B8$&md3_ z4m~oAL#z80eib9ajisMVYp-({pZCr@3+7`dj$qiJKK0n};lt_Uso~>lVC3)#H8e1c zKLMbiyb|A*=AFcrB6G>Xw?Cpq~Cs=J4^u&tjc5h<2&rW2)#dI{UY3xc_+iNa}FEIx^fp03E1M z>^RbDc%c8eXP+D#C_xR64&{^_ern+GjN$M-$4dH-Kc$X5J~W&jK6(U3SUxTNp!#)x z^vMSXo__q%!|-A7F)*>Ak_ZZ`XEHGN5PZJ`@P~iE>?b2JEnX)i^D_O;9Q?W}G$@PO z;9Oml5`D-;?M1Ol({s3mtbO>%B_G_Do_<=cZ3_uvMCk^x$Ba`H&=~Q4kd9NEt z&zSlgG?kZU{VU1;W1K`l!7{Zc>SvesqlLYQZTLA8#zRQQb1i_umY{77eO82La52&HBbmTcYfgfP{=vV1pv_m@ssPcF^ zuz_LK&l|X6L;w>!IY&Sw80)hl5}M(p_>;#%qG>8|nhlh{kFDxp1 zE`MJBv@)*bZCDyRhCy}Sd<+Qs@!8t>=v-qEdbz6Z9ZEl*WDVnk?|3FH5L`ysq9nv` z)rKR*c}J9sRhigQN{wIujy$23!tujf9#_N94$ul;pavt-BFmix4iAl#j|@K%8V#kN zbIP1ZDAM=Dka}|9xyPSW#|MT6Vb`c3Q>Y5l+4nMO4*cgZd-#=dLh%Fg#mvx#*gNL7q&7u0hE(SRB}j$wR4 zr3+R1$T0e0gub<)U*!$s$8LuqD?AMK_V^GSfr25<9!3p0U_Xq>k`_VR$fGw!)2O!W z@Jrr*kpUJbY$L`n5D33~C^WwuOX+#&eQ^zf%|1}jC?}-CIgwCqUOs-|R9IA8Qd$@#oIIyfycu(hJoD$zfJouR3r>Yh zr=PL(O!W%2YI`(m#V=DjSw6*~dq0HK zK>!1T^&aXHnPhfXyf$@h>W0+oQ*TH$q&B4*Q`=KJQg2G#oVq2oKlQ%U2U8zSeLVGv z)F)G)PJJfz+0-4WZ>GMLx;xdK`d;e$sUM~8P5n6a)70-%m~Z-~_s#5^-B;Cje&2Q`0k{CNu;b#*8@XVw``dSy=iDGLEt8FK; z)WYrsu?4Q`U392o&Vn4ZWpVw2xu_?7>cK_x0e@vlY~BpSL#H2{!}!vr&9QmNfAY-O zBGT_zrb;4+zqzb^`ZVx)aCsHV=cw&feY2(`z5_2H#1Oyp98F(%Zp|q%ls|l4-GbS` zH(XG2%EHB=k*{6YF7VPo|m6|?1tj6xV zs%my|ZqA%TSH)(R&kU(=tnHjPD;8Gg)u~xCpvQAwOW09gTX%5wOu+xW{!r!(bahn35wW-0gd z=2mzce1T+3_o=7NRO-81t7gtb{KIX)SGYs}aAWWEa+IsOsk^lJ^w3ajM|*JudU)rK z?$Q#p|G>`XS<~}FMZewIIi;-BiLTmJRZ@^2%HO_A!9}T&xx3ZUrD)$>dl8?e#(r~) zhHw4H-g)yEDCZS#0lZYDKh>g^o_?k?GV=DC$|}(P%e#R;Q;kgd7r-b#<-HpIXgl=0 zP`Lx|Z-sAEZumpUKSQM-{)p!L=6?fUlzZkA-HYcgiHweXs(bONkmK~vAO_#3?$Gh) zzo7H~>p!{|FFDN}`?ou5=FB`bG6Qzx?DqV&766t=dQ;z-LIa|@xaqso`Gl7(pP}rT`A}Td~Q05 zdY7oNeJ2plRiTx`IxZR2@ozFZ{+#nR$$wK0V$}EByzebucxGtiGlkz1dG0Q8mY#`v zZJRQZxjAE%v`zj%y}w=udLyV8GVIr2Hykf&Bq7J@I{+EeDkiwJ(!EHUNpI# z5qB8Boovs+C-17=<}m(rMx|Tt;6slUZk@sxa?0Eq^|24AKsdh+<@gsc@n<2972|Jv z%^j*L#cHxQ3ppk0t*)hy?$8e>7W|V3hs+8yKk1DnLL#(EWlXt%T z;9476rAu0ni2FLBivs%tJu&;Kz0mZq@&ica7iRXiy zMT^dKH!fPVD0ytrq8N(mdZijb`m3h))52wxBIF*z6QPpp<{bNd*IKShBKBKz(!9K^ z<`sC&LrP9ns_1mZ+VP^rY<_geGFp8NAW;;{y{&}SgE%Y&nB~8%5z%*wV5?^ zfm;u#%d7--y**f!G3d|M+Rxoe^OS8Yvh&|5RPv}`hneuw(veT3+-JX8#j<%RY3*no z`mV<`9KDC{-(-3+kIFYp+uYF_@IS2w0`ogAtSjdrG>bkr_2%(YE+(DtBHzPeuhryA|WaFm#oye5lS1A0Y$I^da;2#ZFs@-4XMLbnz&k;#yZ*sQ6g5G$b6(j zj0z*G6Zodls9G)qH0=Hka0x&DTPrmtX=ov#O70W z=JUalpZ-ONh}CxV!_Zj)MjQE*zzC!Qq?6dph9PB#RDi2Hw_7>M0aF18irlAfg~MY7 zIa_K3f$twn1?aUWfr#9lxdS8kck&%IPhY5@X{;`iGUJC8ltL>ZaW*Jbo543=n_B>oB#A+Q3~(~DFoJ%&;#w6z#5L8_ZiX+c*XQf0EWK?USq!=kOg zvI1~tUV;O+K=(}oPO}9TuPdO^NAWrB7!a%gA&k+MsY0T|w9R?1`)ja9Sp8_`-k7BD zm`jT?zC$^Bh_>p?A~&-!)Z(&r2$lRQUf7a0Nf-5q$dE*YOc+S#rA)omR7AcR5a;}EXQbaw(G)L=CCO0CF*#>=ECAQEIy zL=*yALQ`}3DQ^{qmte(+esjyeK&Su4Onh8f!g1hx@g|x8_>gv?DDQ&*b&q_G4fqEB z1w-6D)jeA4mb?A6ZrJUs=A+VuK~`p*kF~O9C`rVR(_oSqXE`p0MIlu#4XK4qLbr7~ zQ_-0UMJ`JgP|zZ_shB-oNvCLK6p-0Ky7h8x(CsR&vUf>hh@YuqZsmA(miw3Qe4YqLPLtHHqlLOv;&uG|{$G za6)3**=raGs}@!)>{*diDV0kpsi%$h&rA_l7)cW#Rta0^#ZiHy_-F|5`A19K|0x-X zq(-nT`D8i)Ml%G?76+iZlVkVwL^B97aYC2oa^1;gptOw=B)dz$PZ+*n3+QcIf z`eReoVy$>!sb@kUH3MIdOSpJ!dO3CYWec9I>u`^z+(G=`<{r;?`|{j_SR!I22v69A z5!A1)`xwH9J19&#_*C!xJ}mEO8NLOHPnKiQ#pXO)N7e`z9EeGb!O^D^O6-y8I0p#B zqj!*>00QH?6)IAI9W7fa~iXk#e#J@fPBahhl7vUXMGb_xPh_sR1};k-GOF@Ja6 zkzS+eD|HFG(RFz(7Dk+b&!l>=5cx*WxFxQ%}Cv3N?B|-AswU%mJRX@))kQ9cu=;W z%)zz<+nCjM%3*a9)RhYA(AO>I9oIb?e7^avyAm>ym;DVtue{HF_VZ#6=1bwN=z_Iu z3j!7&O^C*lcpQSScfWyESqlvzo~Z#HmZX^1UKL{!+gO5Inu0A(|6ZdiVC~L zp*IH;uVAxH%7m?fHoKDHNVMY>N$U=fH2z;HtY<8TK(fm(7D&o!LQ`iYJ&Aif;hi2g zV?Ms$3JsW$&a)}kJ=o%<1L!{Gqp`%ap-rRx z{W3W4@hifb7gCxK=ni0#tSIk5t7LY`hpnLsh87tkvieb~S{s+nTA({$XW8zTEObDO zWhIMF$qU0AoL=~_mqKFrHO5#I{NtnbERTSW(g}H1Sa1FEv${;(eH`y5fNRo6m)Spp z3bb$B@F`H04tgc4({aDw^1LC)v0Z1W3j^M!$NlMD|M9LEvr2W1Pe+k9m1j_LVT|s^ zyapxJ;6uW$`z$I)1HBKEw_+>V!3=k_hJ|u&d(?gA9ZVt2_;M=qmmu% zg!}7K_n7Qo-AoNMqz`dix2_CR_~=G;DyXW^K5?P7?pTRQ!e1Qgv3gFp@3FegbJII?U-J=QPQVQI3k&zW6sm7vP+(Q;!igp_`WKhnO zC?w!GXq6a`THikw`Tjl>u*MF*yDIG3iakE*BpLVF75labCm6F8Cj1Vqw2G#wj9CIS zrQW7n++Le3wdxmR((OQAk3ZQ|`$MqM_ADsEZ+|6DZ`fn}dB()?o9W`60Wt#D(AIRI}x}S@wQ@bccr8^oUE$l4jEh9_Nd)|5mB6<@a z#9L$~gm_0QtePNVG-=h>!HWZ<_$Kt+0@wWvs^A!pLM86lzwiGtM62-^V;Q8?tbn*m zU3Z_G`LQThsq2%Ohc|)(jZKkgggWAM&rl=D(T`H)bzH)K8krcnF$mj=q)e!=Vm>qD(gaZ0VR~xfQxNdjC9f`q%B+(iN7616aS6sKl zJrol8T(^uk;vK17VHKGnFxBhL7)2*@wv`det`|bKp9HHKfuAp@*l2}ieLDV z|JxcCKsgrga*vYP%VCHeIvHYr4#AtTM@RQST?cvBfL(eBDQwdVedS=HvtnL2Vp2O{ zw+!J9*a#E3J#de2L*kWaf4T;V9Z38N8V-F5i93Mc(%<|k`)YTDBnZ`Rx=yE%n|Zq= zoqs}!A871rko-eT(z8y9=#EJ)?N)wTnQ(R~!@ zF}Y_zfueWYHS9gmTC&OY_#h!?0=kjc31r4pvSZ*l4S_&hIhK zq!=QoIunh%?gv4(%XQle^nwBdxmUf0W$7dPCC0<^&rEvQT7No8c#9^xo<*rPZ*2#= zZZ^ESJS5JM>J2jPAyv}tG)VY?m`TcQl}?AYY&OUj5#iR=1gto05~Hieq|5ArgbNOD zU^!hfcW9c>_W#9S9ekH9%$Oa_Um4&Fj8$_Q(&p&^1oLEqiD<_gzC4DvmadK_IFT+8vKvt89q6o@VuD@t)tJc; zJ`G$5h51i~VPXiQz^Rrr76=FBDCk4c@-Coj;9z2MEs~IXIa1f4QO&hjmf-XTm5G}wfeAL*e8W2`~Op=z`Z z`E?*e{fKeTD>`VCwKKc)AQ})WaJyxG{lkXsDR-AU^19Rr)PRanA;XY#K9AGJfaCCT zF`4(k6k@iIX58&QQ;)plXfsIo_P~UY)#oM`wox+)VY*5qXL@;96O8?94Da;5#Tzna z?ITBAtsbG8m85)F=|_E>3T?+q<0sg}1VhSpokpUky@5{*R{ldl@>(zr!U;EN`HIJsOak?ow6k;ujd58c=x5oZm8(3k&{lYCe zh>jqq?Tsc%RKUjRz#S2EgU0EQPl;OCI2};53c9JYFj#j658Tj1+>hAvYEWU@)uBbv zOG^U))ofO4k~_1>FGJr3x6@2@ik+8ubAv!3WqRTZV(o2f{(JLbTK) zYe6#&Fzv0B$CnKa@Bu8OeE?>n1-*p}>NEf?C@+CpJpkx_AHX)w2e8NY0chR_vU0Fr z@^jkU0S`buhXN9~RRP(Kpw@p5GWXVKAP*O@wGb^)E? z+`_gcKvIQ2&Cx>*A*WSJzY%x5O>PDm4D-GRo5{o^&4+kA4-z&OiU$rvKo=N+@L7o7IULiO^&**_H%W{bwzQK!&e#{n&Dp;AGHMM*IgaRj0Z;%IyW7V z79CUPmkeW6_?bB=e`w2EY0%S94ip4kb-2&qIOe~T&>p(ZSG*hmfkcO~dNkZ*+WE@M zbOV1SD?3Tn3}5x-3u^sOj5V?zM-`JNAJTt5{Ih>X8LYV(y|VG&^2BjRUnrTaKGy_b z|FW74w8DsRa-|x{zV??J^RY{%P4V2 zvA+Jk?DOj|G%`O;8h62F!!PK?&R1Co=f?L|`O6dKB;EV{iMa>2m!9qSps1H6=KwY< z!S$HU>JrIJR);JLO;(3iug=n&Xj7`iI5Np<;e?MMrJC$shgoqf;JvK4w|hfYtvM-^ zQq^cB_V^4PZVv#nTogxeu4^unI)Jarqhb)4Rl{c|A!OCaRc12)AgS~D+8cFf3cUFc zle&<@eIj@Ex?NnQK}xF)VBw=}7FOrS{VZ%?kNR0oDyaD|4i~&qfg(Qr|1Xhtfw3L^ zrGwqB0(y_daW58Q$LQd2L3_|bT=@gG!v|;_YIjHv8j>Eu{^kY?Yr@_%iSt3i-X6S7 z!*AjPP5nNmjeRB)nH2G4M)l6=B>Ew6cDjTtoymXR3JhQ^V$Bq|I&C zFs!GBXBZi*{8=8OLSP53Y7ajUH^qj|W2)Q55rF)gs$HACA-^JCIN4MZz^g%C!xIgU}KLuzOSi z#33S21I8<8z;u`aGz$Z076N?SY@r2cPwH*11}a^#G7Z2=?zi={L$&l&I*0qtRu8~1 zhv}IdbPxQ91u#J!@&F8Uyu50s>SEZV2Y|(Z2f+DcW?3?xF5c?_axehxv_lj*kn?k3 z3qAlA0RYP`uMC$`0RZ>1mK!aPO_UXrcMAz{CpaVMJD$L5tCh6ySqR>0R#s{}tvC&q z#q}yCE3pujg9A&Lj=!db4i9FnYUxP>D@2?%jb)t@pg(E?t4oF9(%xamBt>b-TA6aB z^aa+f+&~`xazq{Hj4tp4mkIV>N3!(EE>9Kn&8Opr_>G$Vs=#>v*a z)y_^iU6?ezDG(NFGdNeC@G@Ya{v-zl_!*UMpJ!>%!fd)J3Bio45CBf35_nP}{pZS%hVtmoUhV^tn-uAWW0L8=7Jx=bXhXI>1N@%A z=m0qeL@_a;4)H0*MkEH;_!Gk5o>4|u_BkPjg4`2XmdMRIEevCB$(q$$cta34Gc1PxtT5|J zGReUJgTeVyC*58+G0}!pA~%m1f>aMfmz;J&8~R8v+~a0AhOiKnpRnBkjmv1AN7euI zyL`r2j&4bZ5k2M<_U975CfR)86$7kMO}55@Z#z?;(V$dx56&KY4p{_zVEWy+bIh4w zD(bYb%1NT0OuYx=heyc_-rDVu>YsNY*Z;)_vVY=^e)Go?-s15FSv6m}FhlWweq-`sHUo=}Hg~KJ zlo#-~aGdZMBHfr9GLqy2r?Y{yb&I@LwCf%*^?Hved@bdTn_Zxg_Q zuCc1-Z?T+R7^WBs?$}Sil$1?f8|!CiNACM{5_?;O^D*Wg-i<_3W99kQKzcBkaVvND zcf0alpMEdG+tGuCzt0Eo_Y5fEg;kQ2jWJ2_a`OK*z_)=4w=d!O+)B5%%lH8f@k3Ze zQUM6K>-Fcvq+9PT?lAGhu(+rass$MG@Fp@mLP^F=@+J>m8Vno@U{|Jb8O+x7J6SZG zK%VRVLfEJfU$ewz7RMBvhz%|7!KT0zhj;lfaf7c8_{|L`Ckw*Pn=w?)rbs4f&U&^% z@^*6=!%@>?85RrHhIa#z;nl{f5NvI%3c;(*sMFSl^#HSNZBi9LQ=6^|Fs_hDrK>_h zFX&BGfTgxvT@^rG8+4B}Lj`vewWcb-Y+I3?PjqeQix^26SX*#Of!c73rt|nrxgYkb z0+{DwlV8sa9V*Z}y%s>+VUOoE4sG+R0tyQYD$omDR7vnn%71~Xn(s!(bUtjPN~iF9 zTL1FiI{||`jJ09%k`VV~s&>1*#?s6*5B?;}dOQd$ zSfFq(Qo_RUke|Z}56uE+7~tWsn=}t2qwr_~3td{X;F6HH!hCyzbXIb%RE34c7#1Rj zun-=mJ>&rvvZ@4Oo>d@tXcof5vH*`x&4N5E3-XYkxk8Q}_k7EOZ87!+$$IQKgcZAN z2tp-(9@i@=ne*+y@A0~kp4pl#%++H-9<91yrDq^Kc(E)Xhp_}um01>Oi)MkfL!B<} za0n)BF?l_jZ+%E;qGr*yWCwX}w;R${X$ZzKxWJqo00U>642-R0aLIz5h#hAv3({`JIxKKmr43MHCTan+JmvGm zs&4_FeKvR#%UQg)XEqL#A3n!4oK!PCiWx`q_G(DajfsTOfwt5-W*~Rr?EOSx3%A@M=*D4$v?OsN8pi7;kcN{FQW!fu)yS@%r z=YG_>*3vFg7vBs2deNV`9eo1lQAZoGQTxq-2`;mQ~bv^#C?R#voCfmIgwmZGw?dRHJ z{ty2X84-xf&KjNaig}*`hVB+n zqitw2m*VY?UU;YQF=R2oIQqPn{a#Fv-^>Y-B9C3s!9pmEwMG?Ei9t+l-ALrXkL%h> z-MVVMb7@HzYFlyKqxw}TKCz;i82WM#@beRn+*U)T44K!;8-k&v)Fhv5;SYXz3$88_ z7U?M01ri>^BFr8Ak2|>($mNx~I+F^~=MP=pBvWD4g|^wL25&HfoI&0mzWz~RIOv_g z55j-yFo<86@f-$p9ojCD(&7;(-(}$_9PH8Ni>vcCIn{-fDC_>~IoE;FAUq<&uP`>( zGLfFnQ7RYw5z-wJVfgq-ytm*Mv)}k zIMSj)Y*FfwuBW_MjrMwrn@aasrByP1mx~JlA%Vf90}E>ZZSpYREbrAcIZOxXO=lI8 zk8yy)-_(nBoRtUbPs+nrw2Yj1wNvE3A2R=Eip|pPIv8m0L3KLxP_JuuZcJ*OaK(#| zA^u{fa4aWFIQQW%fl()xe5@y@2kn$oY1&3>*fkFMgMf^%eDT(r8OD$C>eRGpCEfTT zU40fdKx?;dpbGHC5~5kkeUSTRse|9a3P=Wd+-J1BYMC@bJ6ykQ_+FaVVl4wY!wRGR zeCg1eQ)AzV3V)}Il07NuxEAuWkbz@`oi~bfrR`Ltdvr@-d}BFQ0X^=R_XF1ocg#~b zex~nf5oZvd%3)-l&QWg=AEXcR@$_DqU2jmHEIFYp8=Ioohd~kIRof0usb$Sb)Fe z2|+^)3+N;g^^%@Px#R9rF+gvi$ADz+kuTC7585Bv>9op8AYr^dUg5p{QT>|&jJ89< z3XeZ$@`C#^57kK((#vBtsLhPb6G$RFd>}oNQK<_H@vwA$AC%|%%Yksu$w*&M+D0CkMuXXviTj!(yGavmFOr?od)6TxyQ z@G3SJ!(LXaV^u(XlNk61JD=T|+SzG z>YzerY5#sucTx>{O$)pv?Fgw6443Rfp1=coI<$R@Q-%?VlqJwtC|!n=ifb)Elul#lZ)O;KhR*Hz-%1 zCIJ6J8&Avt0sHyuZ#=niwj0k6GOahBPv}K6_3$~^Ebu1$nbNfL)%V@wrm?bzxB42i ze2+VdVFCc}RYW-p*RZ>3#sCgN9BsP*q5|~dX(m){6)zhA!<5kUe?bH~R z_RxEW9l_J@qSd~ zeKSUN7%%xkJ6Y7sFoxMh!e4KDY+eoEmbP2k4QE=f!q6YqSohvG1Y9je>_sAuI1@u+ z)_s|8LiA1~sXKgZ@vof3=SkvXzdThKww8kBP_^-=*q4==sXO5gV+M&qayao}G#3su zoZt!$ojdy9Jog&rVw2$xBvl(z_%J7u_*^g!&ye&lU%T9z7E?7QME(?$tf?0MP@DQg z;Qrb!zv48y9w-?>-fS@6?!YJWfx+)gn9(6qON;2WLX;22=oIWe%~PZfT`QZ^S|(gk!f`YD8|N%u=$0==PQv8SHmw%iQ)nvp9vN34^#>72+H( zm1?F5)ZHU{u3{sgLp?W%$|~L4MT9&K@(Ssg7WXt^T1*R<;~SM6#UIH7&q|6O5evYh zi~4L6rBZ9W2$b6`ed*PKjxB{g_`Pa#Ay$jw9!Isj`zz2bXM+c zp@XX-3c30Q4_ADoW=LlArCj9ttg&%;1S@sAW3Oq}z(8yeH8?trEkZ zApVX?3@QA{5WNOM`B&K1VAN5q65w3)ni^2GFxL2_e?JY;J2euFy_QwFLoW7?4EU-e z-leB9p!_kYL9~$LqM!5&FOD3KX?yDtX7Vykn^s&8jKkO>n$~RJk%8)}vPO54ZXm7c z5LB$|=BHQfH<5s3re3(kshKX_4>G#VY^DFufVlzd5-xFJT%p+uV`KdKa5bgvLKq8I zw6g=;i%m`Zb(`jjj3UU>VPr$A4jHbLz-p7&=SfexTrjW`$s8LYc%_8E)S}XnW_#`P%UzmjX@T7o(@`*jo%?h1RFGC3w z`fp5NyN>ireR2-qchI1o4q5ngxMNk4hNM??(Dk9^bg(a#bC6ye00utzz|l10+2f|M zkYejawaj^C5@$hY@LMB))jWacnhj&y6t(YecR=97=O}RffpDP^vim(UxjB4S4X+yFq_b!&bFeRU> zJR^Ce9#9i99>DB0w(okl>q;08{@hss9ZLj1Oln44I#eb@F44(8P(>r9a%_@n?KlLm zX@KA3RJEh9yr-|}!Z5|ybH`#3`jeR-g5aWuYiK$3bWyk!;o1S}#6Mo745>)+S0H*( z!MXk?ls_wk-oll4cF6f8xZ63_WX(tr=XnLeUO@dYa2C|Txjv;)c*YElRd~UW>MA^} zCf()1lF+1;*+|V5^HNsOr12mwVFU<}j=d9(WE^RFqoQ{e0W9esY9RSI(jRFNgQOYx zlR)E0-vL;M0BNtq1-WKCWKe*=8PY4>^KM^RMppBuA7Ydo%F?nfb0t{4YEmp|BxI4o zUL}CkId^@Nt4Z4oHYVSbHC#Cc82act5Hx9pq}>rrMG~|CaY>Iw4I?A#tB4)O0zn5& zs=~KF^3aalnJQZI^`S)hNz0v zCpx*V41^f|el%uqtl|QphHc6`XH;M^eE6Tu2Lbn+oKbwn#cyZQJ@T_27Y--5N=ag^ zgmp7(4^pD`mxAnuNd$}6S=|SbUOOfrN51%F)5}y=%6*70YKcM~mRDHsy6d|frbZ-> z4-zjC`M{zjuDkvm9q^Hl-HVI`PY{WfOh67DxIGJb?*Z7|%T(Q@#UH-1AAiR2U4O-?Gb1i9Q2Zs4la166E6(43>yEOAg8W^cg zrxrm+@EYWS18>3-G2ol(CvE$r$g9ZZ$!vu@`2UJR5)?io?`1G0A)QA>>{ibHfI^xl zwtd4y6ilsiA{OrsO+eBnCy@34iG4~|(8imE;@$#*yP-hPgt$cx1|iJEf+#Z_PDU91 z-x^EpbM!WZrfPEJ3}wcRPgo12*=+k&CxO(YJ|Vn4f{^-zs)b0B1_)(qD5L>Gy*LMH zkWlX;aa5T_Xi0^&-)e3+bqK1b%_4n5%N2HlR{Oz_1_>=`HlYz9n^2REC&Zp2@Kq15 zF8oj?<^f(}=U2U?B%&UOR3!Ct1LmZD&xM=Z+DWe+W6x=jDg08;fP~xxAIueKtjmA` zxo;EA{@$!k4$5Z9{k_gJdnflPmf-eA=UONLA}^3Dke90=3mS;>Bj`h2BbjZ2k;Q^q z77$AVJ;-m7a3ZMlzWO3s^jMOGAd7BM!ay1n4T+qR`?jP|ng(`b$LY7ITRFEiv+WFi z3a?ZB>>C;xe5PEtCI~Z)4T?R$@v|l%^FHWN&ia6%a}roH8OnrZj71Q7O?X1XJPAQT zG~k#)a-OIslA~sHP^y%1b|{{%wrXAT+^<<7j$GW~it%0^RQRoK zVC6^37Kp>PRuQlvi6a0GhJzM?m~gkkLszeJ*mcdSL-&d$1_%XJ;Mr|ava*9N=nhAz zJPB=psPiOZ?J3M3Cawdr8p!{Ty)OZbt19?J9*K(#cn zEeLLtv`rUCo7ko-Zizm9f})Ab!{-A{d~Q$0m*~?c2$oyqcV;S!`X2rtr_DX*Th2M(`ObH~v)nuP@&{?;xt5%L?a9fa#m*BDJa zD&K5`eWzMW5@(W!WECat0ErSdOzBbOH+}dRSw=?asL+Vtd{?LXn^o!?g1&*y0bge3 zz-L+97&0>6b<1;NIUCa!nW?N~b_txL9huciD1js^q8kY&$}Bu8bK$5wCbE-|S=xb9 zdo`rEyu1XZDoK;%BHXcZ5$L7_o3k`soCYfOjhD;OL-aqy>54GA<(zI#;3%X-C9Ft3 zK4Kw|tnqK*iHH-4c8cwQ24^Y1i+$#wdNto@Gy74|z@HjsY`WU%WOtJn6Jm)(H6j~? zSD}HBFV7~Wjc4R#_4Mh|W$avj>p$=Cqh2Z$PQc8`CRL~D{GI%fad`(o;}Fk9qtfN- z&VYvxCaJajemB>{s=0%%;AE85u+C8z!UoA z;&I?}CD*N8t}LJK2eET7uK4c-PwNfoLZw-$ot6;qpyRTCB~{%)sWwXK@aEtB?sxnN z0*yc{3yNA8B!gVK=T(?0SIL!r&i@NYXVRpptdO;n)R!9RF1sC+mP>4$UM;A{XB4SR zsjt^!Rf{3L)s>VUqi2uRFxsphquP-pzs2aW+Kigj$EaETjFL5jQL-9FIkvC>z|(d5 zfKVO$z)=-qv^UFEnbk|9_>^Xp6uOd6YxY2uYEj#MA0d4&oYRXBW1a5PSs8l5ZnP}3 zjJ6=XA2cJJINN<&dj?K}%{pPlLjiTbY)3J)4&!Z|7cOCpytG=``ID3qO`hBf<7S*T zct}chsFE_zg!MkaZ-kh@R6!`_kjjdvQx`-|q0+<8SKA?)c)SHU@0(>o{$fl)R7|;7 z3_np#jta%71)L(ni%>zC#qh$ZgMGfQ7+yR*Pg_y7UNm)ZK`5rjU{srspK@}@mQM3#vbOIYF1i8=!&cnA5zDl!s_+dIlOl0FVM#dih zD+52+?UzGCeHA+8k89L2+mF>BI3(53uO>NM|L}tEkZp_{ z^(~*d7s)=HcFM~;wbm+(GtHlQw!_+jD>cb#yv0+qeW=fU^uUWR~*y)Y>;JgeN56AoH z%U!Eu`f0b?XVZ(Z1hHXy{e;)2{UZ2qxriGEOFvfkvVzE=+WO<}wfF@w*s$H{x&$BH z?tjVfyGo8<@G`wTCySHxuZJ`fW(ChlX(VDS^Sq@X;kCWt%)-98qbnnE`20hhkk4dI%xWhVZv|JSSr7m9APgih`U`j9#Ya{ z**!S)_Su=!jrpLIGxpp37y$Ij%K`iy_u*mZpbgTW4-b3C%9h?@u8dTcyBpp7Z95{hn18bZGa+)Gc!ptJBcptyyn zPHMndLhs1_sv;uW1FG&p9<@#ZgTl9yn$1u7Xm~I`CN}IZ%tOXz9Kmx`(m7D2EMHIt zDnFl=PZiXaDxe0gcQv2u9M))J>QeyD!zw*|P>(Z|p1JgAE=bzqv6~bs%E^ug(kl&< zop|@xZ74f^h4nmuOumng#-JHr=xFtU62P09vV++fXOjLj>2;YX9{gD)4<*5v7Dgg>JTC6R!X4fvQ0cix>eoSaav(IXw<-KN9n=f*z&hM#e4pp4Hh0>E5 zK^I0+i|oKi*tRdcMC6dS&*xM#*Zv|e-8uO1BiQV4Jdn+rib=U=KOVIjV7<^7Se$e6 z&{GVpu3O{r7J0i3Ajwk5wp8c@*rEY=1q4$KpH`TuOrE8xT{RyHSXnD5Bl#5$sF8y5 zJn~3Z?`~uHGr&jP7h7#1kAXXk}Rg|J2$K5gsxMQ+MRX_X* z`8Zq;@-x*M5@O0K$>(7x1tU15FcZ_&31c3Z|53g&2Mp_zhD0*%)uf977!u2;NpVmN zseu5UtC<0nODRU?>ST(_)hz*;t5*S(Ymx?tGzf$YL`rIaNM0b47hVdOxrf zb`7!ctqNii9UyRElD2e7(!DB4>UNMK@!r-bN*;k|65m&o+Mo`@3dyLKyU`=jB=CH~ zbS2)9IPKnhTU0NH?un_?siXXRExTbhSipbz`N?~X`YkF+O>VT=N(jTB^EFt;xT7(H zFbB9+PRV56iw|B|67bqz+WVsxRhVJYpLemD+_7?IvzTZeq@b(gmMPWurmu4W`u~;VNk6D7ZWT=3Z>=&Fr zm*Xo5nfxkHeQGhO-L_Sd?qkDbOvo^KcBYupHB=J^#WWJt2rammNy(J1_E>1yn|X*$ zei%5EuS*nMvCawbL9^G_vh=ZM!F6mV!_wQZ>U8aLmNofYyi(y~M;maz9!M4lf^Soo{ zBTL@X(}`yIt2pTU4tRvPj?VnPK&i|i%~zF&$e6E(GUn@{wE21%x7$j~q&8oRpu5FG zy~<=pu%{Gbz8>oDR!`b|y{5R@d_9ylUk{_qm+V%BO!IBlJ3%K&Pl3Xda;R|KyRk-( zG5`mhYQ;idLXxD`&x*v)2k{;mxezLmPm{282c&X=R%4UMnR_IhS9!Tyx5Fm6T{g*m zz{-Wyk(3ant02Wt015AfmqF@gZKxs+*mc!ZSfpxO!b(f{bh*_o+IW~;;{Z%9ReTT^vM2NIjMXVJce=j4 zG!@4RucVX-&EWEGh%vf>QM7S2p-Q6U=1gKMBubkfAvMaS4W10NqmqFYM@X!?xW=n}o z(cmG%Srr@?!OWw|{ifadA2Z1U^Kdt5P@kibGJ7NsC2^QcfmIAorIRiH3rRLNS+VGb zXvbLwavnx{+#LAdORK|dmZ3+=Mrox%9tTQ#O1DW4dZNZ8)o_h=F}>$+R$j7O*G zWJjkvz4R+a5lS{&5$t1RvtEg&r22&SW|6csAG$-zRJH z2kUmdCXmPRhaBCK-FK;Oec5;Z~f|*|FJxi68f$zSAC#Xlb4vhfHQV8d5`-jt#nbHLYn*FfuYbN|5o>$cJ zlMpTP{>-o}hJ6lqE8Qih5NqW~h>uU{rql_weCkRNG;Z#a45?Mm09QXQr&(~&YyBu3 z@1$#5JxopuLU!!*E?5deuT_pKL8|3yu~M##X^l}ze6Y`6ire&|M7ccm#^lZg4XBE- z22BuOH9vyN4_a|A)X2W$E^AN>?{w2Rk>%_iq%K~Rl0qH&qhjO+Le_*5Ddf-|^$7 zs73^S8`H_mIFaGIJbI@!dwEz&m7v}S{3s1IfTVx#r*SGKhb?cXFTVM!|Awz2cwsI` z(5G`9sRSPisq{!>DdVx%F`h0@dHHyF^csr2rwSw#`iqyop_`J{yD2)E^cYpay{h-_ zfSZZb$d&Wa)tFbAC%qg+;~q&$AHMI~F?ptH?YpG(andA@L6vJ2s$l6~kNUb~5>|{* zM0Uc`lb9XS@YymaN{f@y(;l!D47`BFl4C4}Y|VrqMe-_+SKtYlQYA=inRM^AlsMcP zA$NZ*Ad&P4>XAiAf#MLp4w4+D1L`ohN2uIwAhGlqq0CG2HB*Y)z|zyRC{WDEbTX&$Ufg;_T(JzFaK3YIh zcCYg}^>2Q&Ota=+@DPU_VyS^EIpN+9awtmpB#ZKrzQs;sD`X%q~W_5r?;mF zbH+|VfCc*~Z+@=P2WtS;cIdPnmqOB9?W2y@TOpgD%}95WP3T1iee2l9qhf>(8^vik zz4^{k7%%4?H>-#n49ZR}MslJk1Xyp6Xa_h*bAomQ&EruvWcsYQV#IuX zn1>0u03g{*{# zttzeih#j*vE|^>cMsEbl`-e&udhE9FlbY4cD8x;8dz;@2GJ)i5Q7k3`l9ogM0AXAF z7(n#n?(Fc6nrxgO6aKg#rnQ2%V39OPk%1y%{V2ltQH=4SB*sQ5jD^w|55<^okW0`t zGNy~oMxi7|4l0RK7z?E_9?D=0%EM@sg;6MWTU|M&~8iKtF+oc}`~ zXaQ==Wnpv@o##1NjpUfzH<7v#%aCr93`8N4ac2N4O&%h7K27f!I1iD$=|ipG6a^E8 z-U6XG-ezbY22xNxOpMKI4Qiqe>*W8Q=Sj#+-S|W<)^qJvXJG+FnP8P2WjOQcv<{I~ zrm)))phaM(x4luBgcGB~lbBe55>!x`0C6UbMyxX-$(bzD|4^n+w_p`^Qk=!FIq-?s z?Y5D4_|*|fWs4VwQ%5E&aQi^9GtoeP7ysuawVlay4sURfNr$Jsbz`-vNt4D5i78el zOw6i4rifCV1#yoeNs8$7Na!ujr6^*xdF1>O)J&vGk{~;PRGE!s%*0bt_{5BO&Xso* z-)onktynDrB&k`8YL*tjCp6M#)i|@XpaMK(S~slRLK%`Zi)Qe+?3fR1^sQKKOh(-Mi-O*Wpb+FMI1QUaWQ{ejR8B$k&dC~M%RwkX^Z zc^^S?_DEz1*&30Qs*?8!oOe@EmFkY2^4&`aM-|A^df8Cc8692hW1tS18tBS~$I6`c=6P zNy7f-{YtTh5?E<1=nYn6zYG&^MadX+yiL(fnQ`CUG2tXg9JP-kgBaGU*+wq9naFKb zbXB%4Th-F(x*y-@%8g4i5l5hKl*1Qw+}nmFAN1aeU69&xjZjO0YA2LD6NWem7%a36 zB6kF0GVNb}gtp>_iPrrT#ylq8OcCw}ba6XaVhCn}YM0j$nn{Qm_w_0^#YCC)*{Upw zi&JOY7L#{RPBQQn@*-GgosPc8WDZ67B{e=aYuBjGPGxs6lP-;iE-)WU5}He^k_;pA z2Vz`lr|b^A^w6+*-NBO*v3cDQ)NEdNNXrD9*BwH7=?A>-Kw~SY_A&kXtwYp&$=1P# z5qf{Zl~&6=kMbvhUjF$Pb%%MbDzN(il`!MJhiWMHhY9Mjmgrn*jdJ@;^633);sthSkHk*~CGe^4>z9W|GS=$dWcp>`O|3GE6Kg z?PWYBM)khR^uM5je(7Gg2jKfCt_fKW9N$iTXYY2==gj;z>U|xE$ppC|Fd!w^R9=XQ z3sWOV=5AwDKyRQC$5f5ZLKDdNKtz3DhG#CZ0AAWih#NyCh~pCuEf5wr4Soyhx^$QQqYc$)%Dq z0!qpZ?U@Ms?KhfsYNoMDr&)0+CYn5!OO&dP7id)yrI>0+n+ZlKCiW+4!J?RA#3a*- ziFKvs2*pHp1J6f6x31h|(<(><)#_(*zrC9}jzT+M?aPQJdB_iXNtGI$pNSd~voan} z{FeBz{jegZl_spr_&I)N=*>jv8%#F-UK`-FwICzq{V#+_R(tU)pUlvmiOAKuY!#%k z^ELi2G|^w>JL&a|zVJ8gV7%ltBVa{h2EI;|tEHr0&oyyB%+T|R9LVt;xKp5#Iq>P` z9LOQwf@Kh@#j*?xf2U9ldyh0KoL|tL0bi)bpl-`3;8D6gF-~tF@&exOOi~WXNa3p$ z%h#>@8Q;@|r7N|+z#hR&n`Z=Nl8 zx=m(E{7mG1rP7y~uq`k%-wa8}bgh`4OW{QO+lB5NMW-rqAdd&LSyM4QH!9!dScxX_ zjSJ2ypXJfYmD8Z!vC4IY-VJndz9Lm&4MQagiZWCxA+>9-kdShQaS6#Hb+`6#HobIJ zUZhuY#w1PYnQkI{Am&><9QN&&2lYmZbNAW%FSlAZh-ltz6@mtR=b9brnMb0~8j4p3 z5W0Ki4+ZvE;szstM&QDSZi6*b9724D`}fm&BMczUt~2 z_#bBa5moA!DUUu9U2Y9fZPQ5>kT1#+{q>l%^P|$cSjqNneSNNanx6mHt&lvpp7nIp zq-CPmH_`})QQDuuRF!ou`&ta4a+_-gH~29NwMlAVEM{=c5@UH1gE7tpRjHsIlchK1 z)NHRRhmbOGnX`i{tkC69%osbHI%#dUnQDkjPcuxAlSZ%2)Iv;l2hiai0ykeXb`YjS zLlm>*zL`RvKR4J+yj`{@3FR++WxG^(l`k7L&nGu6Z?YChe^7^2R@O%X{-QzZ>9*)H z*_?$*^=6^on^jVmFnec}$h19(ed>^)D%xy1pEh|D6p<>xV@)uGY6Ys25?**KmRTOe zsem^oM4lNaRziN$8f9gK5fRV8D6lP&8$Xa6ZNG2R$AL!x(0Sch0`W+QoE;ofg z1ja+sPOLe4At^aTgGYjfu*QS)I{}+uPUAHbVY;5f^_mAr?S9-`TXAUfujNLiWZeK-i zd`%!{27cy9Oa5o$@K>s{=`)kc|JkG^BtfH%L7INMYOg4n{5nQv%r|e5NIkX5a`-+O z5iB7b8tWX!y~+aZ3TH27gWU!x{Vwr`Y%iw84JSNK^MhwOxoLu0PR`P>jHSWIR(g~U zsz|lc!D$3^2-uPgPN|wKEW1a2P;avE%$DW-`%o;t9`Jj5 zoZ^`ITz3m&^+gvI)d-FiR;fml6xJF`L{Zod%_U=nCDm9#V$}-D;3bw+V+V;P)!0E| zYitzKjLn!i6qZ$EvomkMjiEGSTXJIkssRhl>Atl)XQSP2hH40($e8w+7v~aKx@U*e zJQRQSmo}*75msV1isw*M!b?I8x-}&{h-{b`Y?v5)Fc^F=82qsHmQa+B;62|aVekFY z5|&TC6K9QV10^{;k^#HC!+A`TRjhyApwX|wS`#w~=b^chp_*nXQ9Y&QfX#%eqoZsz;KupYm8y*@kvEi&8eEP{U3=35oz z*?;@Mjkn&ffKe*3oq_c2F{6R_NW=u>wjWJ>pwoFHX)=d}|J>q!-s z1Nsk@&WF;hs+POyO3j8NT#F)>r%c&G#BGY0rn6AI$Oc|09k}y1)wy}-9Ih)TiMNa$ zIZ3SbSS}Lpm`(TiI7m5JOEc!+JuOcZz6=Dg;w^=E4E!uuqX%25K*Ed`3oDb?d@^R^ z0{_lpWnO-ze~Xbxpwm;)osDJ8Nl|hN3UfRfr7UZ! zNhCU`$7@GU__zC1HES}COvvaD{eLFY6{sqAChVe4RTCW={}nSitNwyEIkYPA1*3>8 zwX*iGR>)l35hL_4QsUQ}2X&pYb4UH>HC`4nQ0ORUIBfj_*3a-WNRnqP#7>lh@_)jX zV`!-9LZ2=3dN#K$bEcfOtQNt!Y?(9VwB?tdDYq?iO|Y=+QR8cq-P*l{Mj%DJ zYRhu?yb}F#rS31?g~pbR`^mOtlPSxVO{Q$WY%*op@?VxI+m=mDFWe^2mSaK%ok_!9 z{HiT`)4(gomK_$V#_J}}FP9R@w+hs@oFkLA-3|&vzj$vOQjt(za|6Rzj{ZEQCp_^|FDj#LLK} zZP_YCCtp^Z{(Ppt<28oXij0^1xY~~}Q2bOoWKjx3ZZv#eV%G1Efs%E`3x_UzyiKc2oNOdq)aC#ZF0Y1-Jo5B!<$Ns zfm4Lfo&pc_hne&o4rvo^+C1=?0JgE6NPHGEmv39MB#>-0$_EE@$AeUX2FOrBZ!sgu z$D@pBHO&g7YkS}RdzudpfG7{jXD0ef!9X1P zXHgEpjNnn_4wNwh8j%OI?qr5Z0qvaf7+7X}t4n9VJ#k77l+tx9iYiEESAGT>aAlt0 zq0vu50{*hNjVno0KERzFkue@2J!l$E!8%8&nRw`sKg8ApopnTTqzvX3Al(PLao_19 z4AXZzIdtImP&ZOBb%aLUM(`p1Y-<;a1q@Fi{Q(#VCP>F^(!3?m)&~f>W~Dv`=Q? z-JW(r%X^Foq{dnamV?>prZfe8tg7$#{x|Y-2!1FDb$>giK#H6Nq$@AHi5{|ksN6%q zwNXe*4F61IDP!Cr@^T9@o{s^^y8$KnaP2lJosbWmX^7+dd=LRc)~`~eOU-%DVyb;s zgtY!0pjRF=*x*5&g2T$dyac9U4BwM5loNAMhAgSP0(Z6JFt}#E`H1QUgRn=8s(u>F zuQL5*D#)R6Xw?MtUEBaN0Vk4y>C3v~Pa_H4Xaycyj`!}Ab?fZ0pohhE-}a9h#&=8C zrg>!CE&W>-GMg8i*}RO*%dRkp&KnVryg>kobODJF`rcv8GJ5^hOiyF6?+ zIV;BUT0;_mR9I_|KuC$rL^3uDN!V;8uv2}tQ>pAQ4Yr#xbRn;(f``merf)Cv{~u=w z>4JmRcF*!Hr1x;6jihNmGrOLTe5%twQqDlC$u48V$m_aHPIV)}t{ojH8<2s77fnC( zkN!u{!FyVcVW*8C?{HV|@B*rDX4 zxGh$mVYvY0Wudfqorhnih>@X4$fTz-%=18EIU(1?NN5Vl6CsL{sl}tv@+(4=T(nqMAG+$K%3kj1I8j&gUN41hknq|&h<&-IBt}dqJc+AbbS2f(5 zA;WkJ=aGwN(4K)V5IkM;;?j`8K{9(}-hSC++NRzC>(;xUUq>4YkOxI^O3)AP zaRfxUZJ2V~FcogYAp2l|F9?tSE`g_=+~C5h( z==Q_?6@IwIzb?ln=|YQPyoSv2<%Pn&9Qg`!92j9RTi%7+VCthAlWW))CZ z%+sq*<>6!_M~G(Nj!wkG%)-ed^t93-99ex>h@VZ6Y{A72x_HTqr2zAta0j5^O-KjM znz@EiksHAo{4BBu&Yf9Js6gl`6cGF-$_<=9i;gAp1NoJN8p9=U<;)uhl^6PPfXbqb zRkLnoRQ}_bne!u|kD-?QNd9kuoSqljv#$y4`4@v0EGxie>g4&Lgzv&7_$@-roU(!t z_Y>kvg}B6~V1F!vkD)ceMN{8E#K#HIK(d}aSir@jm68F|5Ni1Hqr@dZTr zk-Ya4jT9ZaVa^f=6P}67_B>q{DA6Jb)I70BIr|pZZY%d4WOH5#Cn# zMF5dN4X)w3qG!NR7`T)uI~j;Z{)s5Nib&=_N2G&F*v*jhuYr50%IgZLfztxZAxrpr z2BsJ7IIvxW_f9?!TALYomSosBV-`x98=xo4!VQH%WQ~cb4l-TfocTv8h~%C8eIRD$ zpY1Lr_z`E%!7j6y`<9$fS1&DxGAFYtX}^5@TP1`r8MD*{lu=<@&y1K%gM7z5G3 zqzHfoi+X{ZDyDu0(CeJi*Q4k#l|T9UdU!kO;n^uSkXR-1`(alJo&FQ?N zn^uYm%Qzh=x*6%^oGui>4&<6p79=skR6@QJ>4X*v9qO)$EyZ`kI-L8V3*j_E7ROnF z{s}mDq4uydjWe8yYs9I>b%OI@Tqioapv+?DGvJ);SC7t@>~G_b_! z1Saa#;5x}!4*mjXEv|*mR$Pmm-=MCTvjobG0TyC`a|y~>=+vX$)103py~w!`buD%d zgMPXbf`n%{UjyeEP7lhTGAQR50;-!G7=-6c$`VDvtb|fNNR95fRJNS&-BGw~;Y3t0YdiAiJApmu-B21iq^X3@D2{{byb0P7 z&LU{VaW29&;B3V;&v~9?b8bU#OmMD-mM1!wkRF{y=qy(R9|R$MPH+ymX6J?1g+7eL zoNjQ0*H0#i<{sFOF@4!|8q=a+X83#>&w;N33SStaG>&+P`=VlUVR?a%po;Js2Eu_Q z1YFEOB=B~$CtOkVQ?N}8Or>fo87K_AA1w;6olDIqjzn+`Um|_YO+~x*>=5D0^REXo z8h8v@!&l6l4q&PXEh7C)fqudpf+V$4$HwAnNadUXf^go7tK+-@2`88o784#uY3M;QVF^?Q zxzG!d;<@!GHgXq8#q)UxOvT0vwHKE%R5+FUp*Y5B%;SD2Ucf+z`=NLtd+adxL-A=0 z#s7y`Eipq-jFk3Y6Zv@mY zATcJ3(4PPWzf5KB4R!(*o{8+CyMZl;7B}AnAh3=qxn=4Sq($Hp1l&4p6(r9K2(+U3 zgA7ChvkCYRE2c1TJGK5c28u-RBq{g9!R06+Ohuw)pPWdB6ecM@#RXuw08H_nONfvc z7$+$^7L@>q1l~))msDduL`8o^HYRc(74S6%CbUJjH8zUkE*?CeiX=#$|6r2y>ByHz z?t2&td8lRF~%jK@B-OAaGa|{|KCIK+OLF65pJK!opNUDe1tOSw^G~ zxlmC|!hIXyB;x$E2!9FbiKLwe7cC{cVxzA6y=Ge@!apUp=TXGo#WM)6*r=5uh{mNk zBK$nDk$P`lyqNHc?MJ|zt=UlNT%;!+M8j@fJe}~8ZQ|?Dn9tgnVzQN;V2F{lcNK{6 zRh08A0QW4OMg*0U`eW4@%ic%ga62bnfOcMT#-f;!b-`C*h|V=F9k#K4~ofs z{1^pE55w-`w0{7u_>nMqAkTM5zt7%BIA@Ar@mzF600vlmLBWLu=ND|4avl)D=@tUn zLt?`e$W$T<7UWSXd^#iY7m0#`iwlCqut2+rqJryD$OJAP;!a#mr7dtS3{m-knXv9D zPC)@zxL|^V@(S~uix=bDVH(zPDVix6}&muxKr8bQ;6JrXxY{6=AIcWnr zBmBbUPQ@(UN!0p_xE-fuqao*1{J|^{U;dSUEV3Sd{yJ2r#S#ABnvgO+w_U+uWtL)N-9d%__9jM!1wyVBjTW$T8riT5s zyXwjg?Af)gq3OW##{CTk%J%F#&{SJrUq-;PriO<4?YnFD>|0j9XWzk_%4+xTUAC`b zU){30+HHHly1o7&iribfefOSyb^n7k9=Q3y-=sDuux!`%?HTP{v1<9M~Gn*FfWn`zOmu-h3)cu*v z4Nbf2_8%xi@9k~aN0s5f!ZmDzUEToGlvvW}pDE}Rn!9n&j$L(4sGxq&4q4Q;+Wk3- z(R_RM!u+=#Y-(!QCq(@XaVjXpm4)8LBlsM}e4u)ZnYbaP|ff#tht zY{m~X?Z93h031EiU_lxq6Xj?&cmY)^NN^SasCVMq4(^OM?%#7mZBrcxm;fvS5O7*R z)b6jV1%QbI!1jjvhW!R&x#QS98)nwLRVHQ<18cL_%Yt0ut&$ z8k;wyEoA_Q89{8kI(})@#;VQn%c?eCxpr%O!|IhQ#X;yMzN5COR@Cn~&=jw)+qbJ} zx46D;|GxP4`q~2r;y1wM)EyA$i1@Dhn;Un>x9w@#TiZxgn8xqiUso63zD*q1^Y*%U zlQ_7qwtmm9eRVrz!SVP(X!bl1xL7(Ruro6+f$ zA_PaSx_wRiZx;0p`*y|na&RB~AL@?L$qedYMKy`-kof?WdRf(`t?|pQ+#26{&DQv( zSFWvA>L`zI-LUCe5sxcbGqtsLMV3r!S7xJDXQR#&4Lc9SZz94aYd6QQtXj7|zIpAY z%hy{{ldwu|IOzRCDjBlusJjXJg!#i`*Towf4(w^#1M@~%)oVAS0atC=T6JaovJIQJ zY|X0q+N-WzX;h$WCGK@?-2rq-W-~WrH*-UFGdEqmA{)73wTMIE(ssF9beGrH?QBx! zgl=f0PR^?LJd%_Ki4-cko3^0ATh_~7;+`g*VZ`t8o6}y*b`9IfGEl{aE7xAW{*tS< zZmrrB-?DY>*7fn~&Fi;pS-*}dlf!OzT`jbWN-y7ZRqWE0*Tm%X5L;Qka&`GRD^|yr z?cLsZa1A_IQ{7F=YR?C}6Y##ehJDL+Hm*2_;QEHzre&By*P!cm0MWGj;NESBYxi&8 zy#|x)4d*VaJ!@~{SqJL2pJip-6g{#Cn}o%II~>{d1=``G8xHeJ1P1!=;#Cd>^@yW>p_@bCLE zi;!LHIS_BGuiaj^yP+OEpQShH<)rq=o|Oaf`4t{S`}geHox`lNZEn+5S6cp){2%8( zu)VgvPS~Yvhec-&jI|rjp?24iRz&9VwM;8Ab2>h7a9bn0 zMz*pITi0K?C96lscf)uxHM42$)(uy$Cp72XvVP6W>&|X}w?`>NnjAvR~z*wekA1T~W0;OWw_E-ymc~dv?TWN}w@G zT-g?L=@siQeck$X@y%${T5?ycf_(?~k_3JS%X2ph@eKo-E#dDrZ)J~cOowY@WxZ}w z)g>aw*wC%;n+yAm9A?CGKo0!sthR4hU0yCQs%cTUBhL9`r(L?aYU4(D9%`6hPG5sI zp6ByqR6f@$JL!_DtyhTMwflC|V?8RQQDWP(-)rxsS8d)RyX4f$UbkV(+DkS<*_qlz z$HmuftiEEc*j9UhTq!n3#$qx=xqAI(5x)fcETMg#88AGt?`+t=x7L$u!=`m`vs-gn z%jK6Sznm?xF$-@~xUOOQ!M&Jt50qWK{u;fLfyV3WNMx4Qr(&%w%PISYrnTs3+P!D{ z_511$c*`fBb!@r%a-#zufrpNCyF5$D8GsgQI~opR?xI}TZ8N>V>XLH@&k1rZL>}4L ziPebAK9kNN{)P=(uTXtgyW@uVjahwr)wNe&>y1ijG}{_(itncWqctl{KHi!_u8A9K z_w3gTV{M7Pre6(Dgg({oLQl!kkzsjD<)V@sMUIt`_AAm*^wK%AeOGP55Pkzs$=N#8 z?n5tjcGlPK!nnvWUy&Qa>e*YLsVRsD=US|XGwa1X0kgyeLXL=bF_<68qI3A?Yvi25 zlZsheY@)pfFDtVB1~-KC&i$QPGcQ$Wj?!9{L(o)jFKmTe)fv0Yx!&i+$)0`K;Ov1D z#nOPbyK3R+b3WK8;b!;cmtJ~7?98?M_r_?YxK$se$o1mpy80EdGcP%~r+!C_PF1jo zT)BG5lFY@VSbG6BVzqSKA{@Gb9y)i~S`nU@zc%7b2uutXI+OFJI@6pP!I{o1XSOrf znV+{1cNCU7>*!#}7i>hH7;tT3khZy22nu=pq)|Av*GZ0p*y-XJ%nEs8u7c?B3TLnu zjSj8C8T?_fSaEy{=fsYfBvvZ8ADd_gw*)Uz@R^7mY*H^#Fx~QZXp?M(AYi{d5mBY+ zU&9925feqNffBonohQeFj+!69DKpGh1kS*TGsVhG1M?Jq4o=z$KOJZ06w^5i#W-f>e0cDI z=@>*bo&qo`hH-lf$220aknU*77)3BVo8kpHidOJ471MYk{z?_ESMe4VU!&rkD!yLD zG%hILyH$Lfia)O6e^K$jshDo&6aRNr+^gc>sQ6hG534u~S3~?$RZO>u2wtk{|4 ztBS8z@l7gzzluMm;$N%ySrw;MoClXm?VhOOsEVhnc&>^Us`yM5FIVwu6c$VRQwSYe?rCoqT&t}e^JGEsrVZzzDLDB zQSlKK7r^jI53^K!riv?6%(pv0Z&C0URD4Lqu8IqA+)Cw4R`C)Qm#O$QD!x#~YgK%? zimz1h78PHs;u;knR59K6rFuT6;w}~6ui}SP{7V%-sp0_@7h-Cp{G}>BPsJCjc%6!0 ztKz#<{CySwSj9hA@$XdpClx1EJgi~|2h3F8L>13f@lq9^r{eW0-mK!diubDcLn{8L zia)91PpkOzD!yCA^ehV1`>2W&Dt=bQBPtHV!4cmq6`!l(bt-s5TSia(~} zb`{ejPgLGLD*l0rf2QJNDjrkuG#s%L|0)%qui^?7Z&C5JDvqnTPQ}-&_-!htM+m9B z+g1EIisAq7SMWm=V;*=?!2=Y-&lh0HLHX#h5SkxWD!77T%nR!j{CbKpKh!JuW{NR? zyj#H^q8Rf^n}R=0G1__;#fydby23xKVwi~t&@+h358S*LhlGfm_RDy;PT?rCNi651 zgXP<>v0ILf;`03sgjlYpME^8ubC}~08|lsGIF!_7c}P9U`zX04bss~H)qq{6Tvq5D z8Os5U_EsT&j9R2{c{_01Xctb~cQ!yPoUYxrZGYVjQZWj{=L%?>1o;#|rJ+`VyRv&} z11^@Y-F)Tp+9n(~;#L%N@nQo^2z+kv;s+hNH^a_REq`rT_U!L+B)f$E}gJO1o?=>aU- zYv`c)Xx(h{{qPigzsca+jRoMDx-i7L9lu1{ZpS;(4w9erLTg6dj-yE1^|paXZP7vZ zCo$Q4h43Y`C(}VECui`DVPQ&pIURKBEXAksUq9Os&%yWTp!v=~!fwa=(2g2(EVYBy zyt*CdW|a3CAbzb20iRB8$l$y2d})7~^{xk>UGI}udHSR0kafM+WR%y6^7d(ESoQ8u zd^AodjIVLT#ncfhfXp&BWbj@1I!9clnG_H4-h>OrZlfl>2YeT5K=BbsyrvJ4z7KpY zK+rw{ZlBvhKJa65spI5#OC!IFO$!(P>odPnWkKVtFdN62uYuHCdP4z zxPcJr5&yuG0OpZ}+=@R6juZYKN0Gf01w!d zM##7eY>tcR2F8oJjY8#Q-vMGwHrf==$E$o{CaUd)PLt)ic8=RX_MK}kO&#!hcVhld zZ?3-L4*ke#@u$OI_Ye6sn&#~N8;1-z^V9N>e>-Sa-j0wuF@1yT@*6cj^&tVZvmeA z9Z54MUxc*IgQWO({GCn-6*O%VV4Wt?&+$j+b2@0+Yk@#_i%Lbf8C99xT;xfbXF--l6-4w?^Zfpam%oAByd0Dgj%M3&=) zzj!Th&R=OQK;>jl`i#j&zq%H9DGyq`x)%5wtp&(t5y%g}x)%5g50Rk5SJwist_A)! zYk`&JE6hp&rvU0)V5NN`Ak%yck(1W2Iy|Wp zGJa<0adDXI#KHd2QQUDH6e9IQi|M~ceF{75k!De&z3Me#UO1!GnvfM|$fD_?lE@4+ zuVnbhCqvUp0w-}UH4Fdl5koV?tl<(=8UT54jaY+c6JisK=m7;TDv%PP<0o=)!{#7e`@fMSWZ>U5)c39!vm=9Ct|`e=-LWX zXZ))L;gnmNLMSveAkt~bLpmN1qvF_rc<#uN0i;=TqhvXuVYZ|Q@uVV=G_%r`ENo&* z3~{H>gBa8>A<}^qSYZkb(PeB*3=c5`-KWGbOhE_k+|)^kdo*n2q|)|8Zwc9O^n)Cp){Mk;UwKgoOiSAEDh`qSg$xELrr-U}-hd1;J=h;#G_ z@%XX+V@HRcNe?^|fJnVmJ;!Iw z80{006XNl)laYspCyK&9o_O*|A8v!vrgjWWV`Ib597*59>~zT*S7VI3-SCWRIp(gAfrf97_puL<6v_!9k-Vbi(uK+NV;fR5~>zEpQk; zi!dR@y_p(HjSP*5aA_J!NtKAv4R-3`RVT%<;q>s}GsmAidZ&O$mrm6!-HaA@oS^CJ}k*9GVt5n1Qrb< zErthZ05(L$J&2|uBf@(|qdv=+cL8G$0689qi?hmirK?+qLt z#(en`@r*JJ__^bwJOGm-IdQl|q>iNq2gJ}=D)bCl)_tSTqq@{@(T)_W8Do7gMJHV^ zHmI{)6oMQyM?fSP>(eX}p#KyDPeR8(5h>_PhT#)qC(xXtllVdQ@bJ+Irx#6nWSIER3PBq-fwjgW1FOr?z>5&Sr)-3}R**97u_$ zQ%MXHJHt=tXpeo-NirCiNlL(iVkeJ06~g-D=}=*4Mrc+F_67AEMKmBz4x*hWM5<7X z9vwzMjF4}gcnq(j#8Z4nAS*l!>Fw}PlIFwTin+t6ftG5+m@LU6sKX-UP0=(Syo591 z5Zz^@0$}6p%}dmStcQLcSTF-i=@@#SU4zQ9#AMY8CqVb^@S2UtgozU-78Dj0mqaHO zPM$J#8kyAe88c_im^F+3W+Os8V^(m^+JPk{_#iyTf#u?&_)6ZOT`squT zo`HX7oxO~HgeYTQk-n{7$DY$6EvgV|C;<<^7F}WC+|*vH`$YXAo<_PA0{76{wVq5z~m-tG~Se-2Myt zFYT}IZ|eVQ|Ahl>10Nmu*ucjJJ~8mifhPvm9N&8UD<>uo9k-08pN_5(`U>;$P~?rG zXL3<-aO$I?XF+VCBaR0S&6~5_8I6Y;&paLQAM^WTrKbhlyou3?A@H3su{>I^EN`f^ zpc1h&G^4P5%9JT$(!+)QbEZ!ZhQC|XH!;6BFp?~)nOqzS6ihA#oF5Qp757D_El;P4 zqarqUVL&`Rsb^BrLLq)QxoysD#P6Bf$nk~KW3f`y``VcjpEtW>-W>4v&gq&v8~9u2 z_0K1GYboI!QMv%-&kl&UQ@kKBa%_Q=qi-SNlHi2*pC;iO7q!fpg?eJAcdS@`R$yp+ zN$j-63th4Q?CM4H7KTK8dDp^Hl)JCI+p&qBh4_lqE%Rq0?t4viaSU{Eo;ZW} zpF6*=IE46;3p!>_Lpfi%uw~(Vz+YI?GMD(*R2*8i2=QmvO8$>rT7BkXX) zj>SOV{>EtO0^mRK=C;y#DEB>Y73h!9(9LnF=Qr09EQYpj6LY6e4d$0`7c*z(iSe54 zhvpXLhvt1`d)M3<(AzybdSY`H<%#y4jdNxK{^c%$1LFQYHS=ZzF1fxxI%Sa%b@j0Y zb508kUA(U=HVgcsv8E`0aZtRsv7;!uJT-LuZEf>r1OI~qHANxBv8JAtXU)zNRX2bi z@h5I(EPstItk>Ma`BE*1 zX3w4Nie2xGopsi1JRkJFmf5orKlT1Yv*(?b9(wWvV%7}gE4j5VTD&YU^x6;B6o;UP zdq3D0EkXN>ZtI^jb3&l#=G$UZqtU>Wk=vpr6D9;FEc~!2FJB=>zw=SVXy5FALcCOr zPyCdGue(z$Sg=qycYFqLxfq@EIZ?j6+!?+8OX8e!!1wE~O8m85fRTUkHzoXqyP@aP zg}e7VV$mYRv+f6dIcB^EWVu_uk8)Ao^$&`r^Un^Cxetk@OIM1KS-ptQ65}0@B1ZX> zACvSi{z@!8d#O8q$#2E{*-HcCJANQp$1rQ{tkFQ2sf`#5w1c zyQ4P@qTaK`*zH5$n=L|jkI4A(6!;+DCj26X+W+rC#K^Zi;*_sg;f^K>ouy|%j-63w z=~CdYo{AXogEJ5#-=Aj7e3#94=EqRaWeX(VIg4d{`Vxora{O$keC0}aeo0IU39h>fAa;1=Zj$98X50cE90lu$+-Rs8TY@=xo8dQyRq6?x~M!j`pYe{{2#u7 ztI0W9%TjJ8UIS!S$<9PpWPZ7R% zk#M^T@g0d?x1#``kLaY2eGH3sw{ZeKHqq+V3jnBwkcH z*zUSFE89QELJmB82BKD@haB!Q)4nR_Qbk>R+* zz2kU{*}cu}0Wj2!1x1Pb4gdlGru`DPb|GqB7~`tt_t)CN#33MGKiwx0-38%>mtkU^SmtX0j9z zbo03sz`FT*_LB{9WGTCEx#h#|QxNY~cl4H9KA_*{t{RzsK^W!BhD@Z+;!wp6DRes& z+`tVfc3TuI8&cxdC|EYcQU~{=rw-YVo;u_gP>ecMLyS78)CSh5DnIP|2=vP#opC=t z)bn69mlwi&bSaFM1N6Qg@mbsqmjt?&6D9pm&136tbD z(kNsS6%J!+^MtQJCY#jZkxE?X*tDzLO_!S{>dM@j!CE?73}2iakLw^uCEn|6LZfgX zj0!c#e}PJm#sCO$1$}4f@mfyPg~ia2Q4}LyEGc+PwJIR=-LyFhZ{~M62NJ062}ur6 z58@49Zu%$s1^DhlXL_C;z~S}2td9fQ)rP-*hP8c7r?UgyJWoZEmRA=+hqmZ*8! zTHv$N)!d+B;|8eNKc!|ltWt1WEb=~YWJGn<>K9OL@DS7cV zCaNdNo7!eMm2f`ArBL(Pt@U!j?Xs+HmQMl+t|TmdEBBoGyj&^g!>6Ab$x)yQ5JBeBXfz;wu3|i9z(6mk-kBK6 z9mi**G#TEG)+Pj3{b!Uu5Agt%2RMQYTu2Ak2e=nw081e-2FX*G!Ia|C5DA`uCQNiO z0EnJ+M_h3Css;h3PkhlLiUVHnPI{!JkA~4(sJczUoA`TOWeRp$ksJC!bfjE3*8)ls z+>JyUCAsMp34+^^q>zfD{2ud4{BJ_hNz!EC?Fsj}FGeZ#Gg*&yb=?xTKj{|JrO53| zq~U^k#|zz_?y&+~QVuPw@GZ6)s^<_*=dj@k)LtMP$(H)bOF#_tYNdh;-4v=|dKGC3 zMgzE$@-r()E!6qw9H_9GmV@Ae&SP-Ew9t}v(m*RUodi}gFt5zUCCI{Lxm<;;joG9O zQXH043Q5aZC8}%%H%PWkHj`Rh!JXVmDn&L(S-|~R#X}+Cc5u6*q!KbR?sIe{k`>Is z&6icTlP|Z#lErE18}YOp51S;}foupDFO!Uw3|u5Pm<>@#yEk%8np|qgVVhjTdC43xv^j*?S8%eIybK4AoNtq>6`5SH4EZjN zWDW@$q8vPO#3olNas`b>4in^TMd>6tFAi0?$>mvO+6Jp&CNyaMkiz-MF@^NV1!gLO zuhHZNo@R*GM~$@GjimKH-Ukn9+ zp;1-@hu;E+fHEkcd522DtwOgu5ckyH>OS9WngZ1iwX@4+-U_l`Uak>X=8jqr3OpqQ zPJb!>8vM1J-3zsCz%RA0MQ#4pf?L@wX#x|5ttGz(F~;504ZDy96mZ(ARjXY#j1sBkze^zaj^De_-7ZZgKgsPIC5R>;4u1robOpE? z!waT-!&PrbbeulLh1rPbBlJqQS|T>n$eB<>1e$@2f8d$ChOu-B8N&qt+pQra2lQj5 zN^$`vjpdFpXv}hYX$?B|#$AT3)s+9~IhpH6j5l{CQKs5L#HRnNZXTorbx2 zqM+$sQN5n$BGXbkQw+OaHyzX2=UGc|Ob_EW;rUf6I9k-g+y}&5ZZ!i6^)!OUw&-SHA?>Lh-S&tfRCpek_8gwxppr(z)v3oUFvvdsrI;e2 za{wyMGvJOznU;TywW9nS-YWhP=_FOgR;$0Li+dCvQPNCt06MK6Ln}P_gypJe33^=o zt11H8>|JtUTq_%gK7s#paY2F|-AFdCz*;`BR{ z?z3u`F@p5aBU5~Zmou9+LfEzqu+wwhL~Za^1_V}E_72cDw% z8KAEd0eAZ=ZuVDP<*yjuqpw7X_ueb}5H`?)BI0T?K{s^)M8ji<1h$M^u_Eh=HMv*K z@`}vf-pd_#-Ank}#m(*sd@i|EX2#e~_c-mpM*g%Z|V270kfNhi;038GW^xNBG zgn zTx=fZ%kjG_IgQKoyOQbOyiY=TC<-C{9s*4nl>n+_5pv)W@a-+D-q20XsLXYTqloE| zCmOepQknx4Z^4p=Q# zxZ0ZnU+GP*arXp@uaSIcZh71tkpL0v38w8Jl2kj4p{2yA((JawCf>=;nQOP zXsFr%rEXdnpcT>?fEv2^s%jPr8fsJ0u|32L;2RCy)=Y*f4;e0~r^WzOr3tOJF&N!~ z{35IDwWWCzi_ok+ZHeaA0ascso(p zuv=*UbcfdpX9G~xa3Jp2srCR?ZZtb7ZK7L|NiB$=q(cO+bVS2r2_Dh0$;sXm=|@2?_i+6@*XB z-GznG7h{~JZI}BSUTXn<3-gUt63OY7nRp7rLRy6$kf6eEMa8sko>ZFMbR}>C!ycbt z(uOq;ZNh4!g(&18M%evHDB<>Dn94Lcvg%HwjZSw2q;g3^SN0gci^5#!O1fm~(gEar zk{E*tkYdn&YBRpyMg}+Nd8E5(Zrub13LUMa%~_ltua*@#*CpI%F`HOhZ1w_5Jc^8Y z5V7EVut8+@u-12f;wuGaNjrAF!9A*@;`~2QDd;JlijZSFIa3> zKx{k$@mDB1bPyZ16o%~c5b#s*1SqPpj*Z81b znTjy1qZHY}mYH z@d~r60L@g4v?q?NJzI3jps`4wLn6v>ic?xT(UsxX;Q#9dtK1iqVVhTNFR$wu?sbpG z6agi$#sTg{YtkQ+_zS3IKagqG-$;ysz-NHh88CKTS7kUesXG>fq+9i|o%9$e8`mQX zt46_G1-?xkdVZNV2iHg1J-ILpu7+1TT;S-v!(D2py82afKN7~6pIXaY4?Yh zF1!LQ7=+hK#lTC0z9W!OGaCRQ-cM+Rq_r4F)^dr()%Hk*ltTp!^Ddo+{Azvx#vIeZ zGxWOSQN;w`ZKvhT2paI7{dp=T7iaj{J)6qxZN6_mFlmym%<#TYBIYqf^o$P_)&j>3 zrPG^EX~C?t2eNMu{Fbqp$$`YVcj9#IN84=_y71psUmf-IiyllUtY;6%M)S$|m$t52 z|8^u~?@?jsw8vyC9hj1whj}ZYW>v6kG%Lwo!$4UZ+);{P8EWCc5G^sU!A@Gt zC1{%DP$khPy8Y-1g=TKA5XC*nWy?GMR7$g~a*!oyHdA#sq48h?%Uz*I6IL2Phul7H zrMV@JVGcBIR25T8Fr78Bd~u%nOWc|Xyy8p9eGvHv*mA2ImHMu5U6@L++xy2bMjlGbX*oaQY?ajXH2U=>@39E69Q#snlE7Iv1q zAskdyq_-842UgzLtZhW1XiuVtjKq|pYvHY85~3>~VwEW;AknlqgTq$)8NxM?f5Uvy zLI8&%m+V7cB?g0&EUww|E^3p(hAEjU^-f4a5=b)BJP@op)89}1 z;R9!^t+m!VV_U0M?WDH9*4m%m(f(U&Tb;r8`v$bN59tJimCF}AVxL1$8Mw!wPCvy$;}M=p zIufRKK$vtR2?l-Vivgi)QLfYZzdls~FRHopZvb5x`CL~>q^;d(l->X;h>TlIaD<rQzWeONqUKCc6C*#65Ygs7Pvl|o{*<-|AwgGg6BqO| zK2#2g7y>W0cmrzTWXbG@h z@n0c>o37`e&OMxVQ&a+}SYtV15Qi8E7@}wp!xl0i031p&z?S!=7%VRem!udFOsgq|!PG35fYy^@fOn-NAQGo^fWu6r7)Ij*DTbx+$B+U0 zk-Z@URJuR31K@{3OFlcMK3+m`6vI^p!yLzE#pS$m;p|1`)1i*^X#NXL;i>TqM;j6} z`QVW-(9B7iNQw;vaS$qUe%Pf%TWQC6jVR$fCUmFANcf68%fo{_-xp{a2FXK*BRpAJ zJ)#cE;L&auoEKO(?hk+mgYvwDnSkjq$k(mXD-e zm=sCwrhmIb0sOF|_U}+d5re+FWg>$3&UHeT;BW7d7X`TS>;bo2@Ri1?0N3CTvKj*} zZaA-2Zh!6SWLDPHbx-u13(Bd5 zxfbtB@dHlD1Dt9PaB5os82TpN1Dxs);KFpAEXIJj;O@CiJg5Pt~GUq`JZ0-8R#C{~J_&&e1;WX;3pF+y&g2CBm8sdc{D`DI8OhGyWwJUcrzp6volEuQ5B|NBdMkKHGsm4@0ImCR%R4EyI%qV&e% zgiq+#HiDVhkF8b$;#?B$)T%s(cq-)M9@~RG5_%kn%K`=-2X;f<1cW*V*dwDZx6_Y; z#c6ahq2eNRECCC3Y@rkIRBsyA1rbYxry};JlYIS+;d|0AdM%8+c|cX*g9SAliB`0NGY0q4H#TPXLCTN6KpN$7u(@YT)9dr7{s0d zvcN_0g%j3_?C!M_bIdSyL0f}i3;FbMt=-1=e884tP)vkmg{&|&zj1iQzf z1XG0B7Rn0Zc%o6hq{Z6~k2x*IgWtU&hK~m1I>z%vlRV#sJiHXa91i5LmwjnWVOmEd zkrVCEx2FRPs~|lNOs`77XPuhEcA8{^mbj7-C2El@M2+DDh3Kz=l<03}mFPmT5yfU! zb9PYUpNX9scY9dYlrLVF*@)Df!l>w`Ly0bwDv@`!5@D6dr@9QwMr6+GVk6RprxGHk z!B|3!hUtE;CYM$?l&h%$J|T)yo=E3Am=NUxIU!OhNobo1>l>5XNp%b4=Xq5?M}z}1 zSxsKpB6%XFPDsSm4~Tr8q77nq9$c3Kx1df={}dmXL4on1JARzKq$S1niWoU3*wv}5 zUJNyMd-^LV4S@@0@fWDjZ2&09(fXj)Wu6Qsm@XNv z+{o(l7vQXd!LGi(q~jq8egT9HpkBqUxb9DZ4mLEeVW$&!n8ctb5Imo@w;t;AHUsK6b1XQOSQ=7(k&r6V z5K!C=&_iXfDO^vJizvz4j^2w)h!O5-j75NM@2Pc*>_sq{^Kqr^LkpNc&Ov!w!4Tgc zOeqa24fChMh!_|Tvv-1`dcDpO=IXssLs)qb(^w~sabi|uiY8MLXkHCB1_*4=sGLt& zBeEzc093F!lkk%#zN#yo6V?qSI#W>tmAFm9vXvyp7U`%*VMyILzFv+Wd{NfaBJ?=B!T0@m#)}a2mcspvh4&Q$s$fvtQjJn z=~5<$omAYRaA0o!0gyj0J08u^u|rbA&k4FTtZ%?KO%FK?!)E+j9nYivReM=Un~?O2b6a&{rD8RIB+2ax#O3zowEs(+Jzp)E!Q8Y^TN?fwkn6VF(O^ z>PDE8@((>HrbRsKZ|7wu#@~LGl5KJw>QnF)syu%1T+-?~;aT>QY02*clJ}MbEWQyZ zKq<)w?BIigSS9Gj(vT66cq*yZ4$>wEmax>f`JF^P{ux5_9|^I<2n2QJ{`itJUifgR*WtNhUY+bz7%Xso!t9@PU|gn%!4f(kln6s3AsS=gdN`;9&)uV?b{*_s6AC>>Fcg6` zp)0hMRfBOB~=cB`_Q0MZj?_^R5_^D0g6*@Ivzsj zM6#&nmBUzzTuLKl1xnW9RnK7iHS=J!2@>uHG%mnQ9_v2qMLc zsGL`gjZZ<12}+}KUNun;6KsGK*r?)F;|w~0S<*oYE$3C^ESS~b3j+npdDTR@9yjrN z_%-DT)@FhzKLPRUm%$7{^ReTTJ*_s$N;OdWSkSGdSVO^nP#oVhH~&5@MVxoQsDuj# z!E&Cj$2UnTlr!tfjhKLei0e=9vE~(8AJjKy<$1oU(Ud#s_mSng8GA5#FuhkFeo$-FSvKwwKe*gP*vGus^ z>{06(UA$L1q23#EhNRYgYF zY2B&eXS4P9ym{d0U2G13-z)F7x!Rg^3R2*g51$s?A-@EFv4&tglNmro?7x^{WoOnj zEm?6=vMWC`J^QIHprdnCI=?77Y7HHr!&v$`mxph!J?6O}-WM&Lsj$v6M$5BUl0B~$ z@Hw0W7Hrr19KJJIUocCD*S%G=bnSIN(*Is)axZQSiDNm-lXhO&x zZis;%wK;-X|HmdV){O&pNH5eOWI8@r)~|#ez@9h$&if|$yVgT64b$8*Y<-&QEFSEr zn}XlniEY&ZnK-T=FsLgcf2v9RjZGOcs&Our#aGKkjeY^3JBQqWc(y|a@wZRs(9M!W z4*YFw-Z5Z&b?RneIYwW^9D{dqLyzL}`+Q*PTEyqD3q2@L zCYHgKym{i;Wk?e+MOC#)OF><-#WbodRPa=mWUc>q$WbI_OjQhnr)mPwLoS4r`q z4$&pBmFWh5=(8fSZg=t~>Zu{&x5@tV*Q~7t(^U4M4pHMGQ5@eHqlP^S#PJ|B?36)# zQH{7hm`WxDLR_hDNV|JxM_D}jbfCb;R z!e-HpB;iZTNqS&9{yVH7nqD=D(BMR6k7Nla`wfYtCA-YPMk(r{ih5?5O(`N1;DpJIH{QJ{CkuNx%OMYItz+^~WdTa9o zY77;=78TzDnm_%^>#HI{eyyLSb{|Ad#~u-c80v@HJO2LC_rH$_`2FvHPb#{;yD@>R zXEG{^ZuoNi6NL0}I?TyphMCGj&bQZ?O-4u>Gytp7A^2B3`=-;+d?#^xJL6csG72w^ z58;OLE-`fxKKDs?v%?^BXwYwIuxj}O)S zT@=KB%B^-$G#Vf3jNPHT8v<%v*_q%jhcLV6Dg@ApcrTUy!g+-k*OB8dlH*g-L0)!| z#`KU}DHp~C_!?H7G1NZcv)JQRF!;8GW&>D*hmcvSN`x=~OKv&pG5{*CgFf(%79_14m2Uph^sIine>_+w(Y7^(?5QF& zVe9o*W!X{Vj|(wtK&$c@hk|s z#9#>S9gk-O&oO%i?Ia27hM)GZ^6PxhvFG(Y$1uI^=}(AW+#3zYcXh|{d*GTqSQN%_ zId=Ve?Wq4muV5Dr>l2a^3OgE3bs!hfM#@&uaq1Nk{%>0ZN)S+DjCBrQ8T+&aPJG`UtW5}B-U^^v;6cZ z?n6K=qrHAq0;^osbGg!iz|$(Q>YY97bbyn~HmqPvdbf=d*VdbT)OK|uIo{qUwealP zR;^UHuDd-h7G7^?za_>#{C%z(+MQ5IX;xb{{^zkyL``}=5ihwK<6~>`1V)mHYx2w} z3QR}VWH?XC^{|DYKVA4)`+IFDH`m2h?;_qGVyk++<9deH>+v%%5HzLMo_Qp5JUZyosXC7Dr#Ae znLW8AX~?ca#GMwvSFrSU$W6&bEF)D&>d`WPcxj&7CbG|W+k~MEZkr(MnS0yxue3&~ zuI9K0(-%g3qd-HLpnZVkwyA?NTkIE4seM2j%y48DD%=h5+I4rL7xN=!Y};H^qd}>byeh_@X*aV zG#`mZ@hPbb0g*qter271RaE0*)90~MagjQ?4&W8jjA)Jz1l1ucBM{BL$;x#Io&9iy z5TX^6{3@tMNBwJ0&wIb%d!Xtnr(rTD|K z=XV_UhM2#s<5I=VJ=*?P6pQ#8MaRDbF9+*S!7aGs%_o)GAAmEsYvusqrERQ=d`Zz`0j3Vyn z2ALuKm{WUL%RlVl<=s^RybIF`PG>hpAOvqk;jgS>%GgL?b+{i}GP5uaWfPd2c3dcO zK6X0gS~*P6NIN9Ay=bIQz<#+ltm{1n#&itWK@C3O=>oJ=PKBs127zgy9c0UVLpwu& zhU0zsqCzr z{rjnWd8Nnf+>B06O5eJ9)u~UEQTb<`YKA($hRt3ejmGa)hlZY2=k`tfK`Yp_oD$?T#TE6g%@S3<=Y+kJc5(!l~gtuC>4*b%UcSya3SD2a^W_ zwRq0tgM_A>Vj7G`SXlJ48 znCq43>3UVD%beC;*{%S+!aUbr^H_#EKsP*C7sen{29Q?xIh5RInxHs_c6tqDut;_h z5{-tXEzn{9Ub^d;@{Upl8t)LWT}Hi|Zi@svGMlt!>TrG;m_A~AbQtUgWl?;PNDMpA zgJ?t5RM!~gj6p&V$`R(1x!zK`=mKx`an7Y_&R`~VdjKN}lq9|qyjWeDa5a7a3}qqV zqaIK2Ns}e0UDc>82>7bHkCNfp<}-w0h{T9u2<^J^c00Q$=#3^|zYA~zC65XTVk|0x zj+%PK91{vf^}pyiONLlrIulQun&3f5ZspgvP7-bKMv6Yd6lP31OS2dsm!?9r{k4+1 zoT{Y~W{Wctrq^B8EC$OWbp(%eVF5GL>4jk6JRYMy*J1T=QPE{ZXx?W zS&xjS`X0SeJg!Im*P>RxPL{`=iCu@qiHp;W(icxlyy($EN5*gcA`=}DDfa=4u%t6H z|9ad?$iBg(VBS!)^%i{}0t9o?67U0=?`kEn87C6%3!bu%-lg$>_CX`g${!+MiX47Z z_yO`U;zwzo&XRI+lL0B!L0cEB>tv76{y8BIEZA7n3zxmp)R$J za0$)q2~@+0vUrBbR$&X1GGk$lIWx|P+6uSoG~HLgVwObd_&fAL++`ImsuIH^Xx)$U zY?;HppLL`QN5xaE@k1R~v-92Y$YO?zT0HwP%=C6ncJ>!xp;MNH*Py&Ndj3bzL{zwQ zPEMf3EpLIys0ee-fWJ!q2NBB;c9lls%F!I2=J@WaM780ckBgr#otfN+I?>T{^(oD3 z`N=8UGJK zkNCSRu(y3RD*T4oAxeM5sqpHb4&^YP1<^i0dV13b&<;l>l?t~Ii4SJ}JCv_(b97Yj-|9A1z+w&tB$}oW#0u@tkY_Ck{Vf zyN_1?`S|Cv+Y>b|^U0a7-TCws{Cs{W#Po;APoV@e-@KS_9_gj^=c7_RCF`pS&hQK$ zrdb2BbJFoV?eTTdw6S0F*&!2-9y2(f{Q2}TgFfx;IiH^M^=m#mJZ8gYD$XZ=K7HoX z|CxfHuV3@oA!9B9U+|4QEY2u;O_?Qj=WX-t5@96EY^!mwFd7G>BW1T4Zt-rwE4y8h z28}=&roI5h;^Sc79_&rJMYu@E`L@e75=tM%HH*Us>~b!&3L(2}BdkKeZu>5&5V9Ly zDunEER*gla6nlj8Fq5nWQtC71`UQ%+((H0CCl$Jt?$~+R5+uEv7E!oiNK(R{st~aI z7Fa1{4=SYCg9>SOU%_9Pd7>@!&Us^ zVk$i+fl6f_{Acm0X<7XF2)ABy4uSi^dvN*Z5rE^n$MIntgz>_oM+h9(JwoAc5SA(m zKgg>XK`4B{Ud5j)JJ=z3U!gA$XcYnVraM6B+)WTRmp#JGZHI8MwW9LG0G--^>%M*C z#P!yF1I2gW(LF--rw}zz0xLq{8EJ(a)?ZZ&2!mbs%MNx3J)2N}t#U{tNq-bEON91M z5VKVeYn9$XM^_mG(O`0+i@7;~FQ5LA*n%HTAC(DjFha)XJt-*k2RGmWIvRx;LfDma z@W)p`G<@+!#~78Sd0%7ro+R2=wwrl5yJqe_~;bisp=x;wBM-NVG=N|&)ATYC-xyi z)zEu*$1hPsE<55f#CSRK^q`j~Xnla=_~ll5jDcOkal+3I?c?S7K8i{3WWBE)A7g1e zt}x@DEyV}C0cq5YBQG5vq_(|jJnwIQ-i?n+BmTgA_(V>>8xYDluoNHKuJ^YhP!A@0 zN+bNB34TU1@AD`rNWbX+e6STHu>(7&Y{$RLyi zZR=JyS@6@)w_f*lwkg`MHoKfkLnR5f ztQ#eXDoQQB4wO0mBydA2oZf&U;@Asv@Czm(e`X+CpvpQA=Y4Iuw<1 zu!v0JrwybLwH)#PamSx}^8RjD{8wnT!vXipTmUpn6BO%)A8_A|z8hG#%*j{M*9b?S zpmkTo_lWcq?-q+`@=OuU32Q-)FJd6=BU)6%Op`QB^nMoSLC+&Z;(B9~`3mB#C?@UB zX$pMM?Pay|g}S2Sfo?0rX;X=MLP{BSo?)10(B>K9$hYa*Mh=IV$9W!gbp1?tUUKam3v%yqcCPs#~4|%O& zu@FCG+(&CO$buv*Ki|u4AeE-Ys@Q2akg7uAT9qXwgEx>RK`qRSaeih<%P4NZyJnza z(=;et5qrpzQhpF1bUVY%;G`CpQv7}4RxDK7J5MU0VLnb9=L8)knZnIU_pSu zF--?ChtR&Fn*7jZVh*9iP(j&6hYr(0X%AW>gvRt~suJ)yqHBFW7urJ2qggm4FF!sA z^Yw;*8B%z@!i~#FH2K5Eg&8}ji(#u1J8b@hGWSP?UlUWchgd25Y4&81_;}h(nQdzb zB=gk&DWm~(*%m(EWiOv$@K3sZ2Gz#y z)9;EM!sTvorX50ax2JG%)=~XoB(oi_I63JGo;|aFPuP7VXA1#)szS&fR7kN071Hd! zLWbQ}$g*3726n5EuR;oxeXYZ1o@ldqpN1mM|OR^mtc2JNH z`S27VQ9M*>s--cH2b%lS82=j6-NksSkZ}-ljYah#-O;A&%*XHK*VF6{nsxSc2+J+t zY)_%T86_!s`%qaX64H38QnC-%b9b89>#Et_IH2mD8T72YL?U+uQ%(Z%qXC;l%IgY9 z+!mWe$a7}^Wf*o6v+@FoS$TSWBN7|r$z}qZ8@Xo)^<#6UW1~DTF-M+BY}C(7%#&vl z(Y*)Nto%9NK1Tik_eX`lI;)i7dw>ZU*VY^Xj|fDKm9Rle3jyR zgbi<$MTKord`R#`DZh&Xqv)jq2%eKH_M4`wjiASk;OcEu36Y$cheU{c=mkS8=LP5f zLg<$Ya%kRb>@6StKew)Xnc~NBIDv|i+Eq3`x%cu*fhclj>z(zb;uVbhsM+AQo%ccEJbH$-xiu z3c3-`i1m=-|9sWv+uqk_@;SfmQ+(>-+9>dQO-`@zBI7_|MEIGCu{8yWMfzJ;LHuya zZN>3-dzEmGaFqo=D&@cIfS@&*U+rUK-*vx~W2?}H zasgpHvcvM_a4e!=j66er;hothd?`6nCm30k5st57*r$~IaI6!S6i+zr0gLgR8`w~( zlPOGLt@yLY@tS>z9_|x&N(VETLCi4EfI`GOtNYTJXq0~%AW3K)U!Y20>8V7J1P7kX zjtQ8>4Yly~+N2KUK+OGVOh4vm8Z(M}wlt;(SB~`ng{h8jaW{IJ*sV|#PAS`mE;S)W zFVs>PVM<|yDUBgh8bhWG248W_V50FPhGa>NaA8j)&M>F(@-;sV@|G_@Rp)u90^A(e zzErJbDrKt$Go?74KDA&zcp=OE0fs0)cZOjCR10=Bs3f(pml~3DwGYsKHerK<^9i8;mCaGi^)~Gqgv8&O4fSusZZm15~Er2jo^u%zMwr^|&zZ1?Ast5G{Awi1FU~4|m@ad^^HFe)p;G3p2OY}{ z$~;2}6A#Vf0BFy=?J#bWtWXWkCVnj*r7ntS=v~yWU)p}RZwk7wHBo64yRGzeU^Uei zpExG_dj+ZHLrMvDFx8cN{t4@)!+ zI47lHca^3>Rghz+~e*>yljbQL0&Rx+sExfm3X_Qn0x1y4ERAs2;}R!fYR=MH(~in~Ula|7FdE@8K1dx-W5XRt3xEjgvafTcFKOXGEra-M z2IjIpFqlT}PwkUI>j?EifRw*Y;OflQAR&xee}(gQ7>)Uc+s}fa5_i@4jr`z;)el3V5y>X@*};*s?7B& z94*lCaetl~*egGa1AfKGsch130=U~9f+%eTOf}hkO&B{)Ml`a4g}OFspbNDM`b9)R zKez%WCKj+?<(TBaQAi#3M7A5cCBX572&$Y<9A-jZPH<2>ajGw}@cHQ!_=6PmBm(JX zQYYhsqgVu`Z4|sigM#mlQ5iWaiyw zL&kO~tu-8St}l?_ki0JU$s^;3I&zS~3X*X0j~Q4Bk@DUg@hPN*@(j{!ljbzrWRUtW zDT|a}_isSbHjPNwCI>lJ$w8*CH5`M!zV4t$o#$3h-Jh7qT$S>a&+8_gC99gaRR*aJ zm`3IfhdFhM^Mg6#p63j1$q!XJnB!o1u9)kzdF~A>1WEPGOqtxtH4N5TX|m|G$aFvFU!dUgb5&%@*9Npo4`epFW+hPlPv$HV#3X`gmIob3hcj+q$3vi z?_hy?PA78jF>)_4@@_D`C9^O1Xq88}g1}aOMsClQ%!3bBvCkQ^&Er|y6u4<^S49rQ zyVpz(w1)&9jC)g5ed{5i%C&I-J`{?AI%9!kfVlezn5k+Cob5<~@jYp9?&S~>B%Umu zlJsAxR_4x4fp?{poJn_KZ>oa_)7>9Qf!vq`q6Si+ylj$C(}Njf9@eTd2ZOqS+dl<*aK;dO>=TJ6HAyDcITlt~7R1N5ehAQldB2 z-jI3R4IBo-r{FGO#3TI{5jA9sFO=X;0yjjCx$2}ccQ=Tsi!y%+*d4Okcld%^Yo%(p z({})%&_;!NS^##`9VxGI7 zPOZ~f`hpBYuT4^ zQIp&=b9!|-(sBrNPtauEITt3uRniGLq;-T~v*PJPIF0JMx!O;_P3Im0F2u-m_mO4v znL(Pe!4l=&_{e3K#(t1V8Z$QDg9VQnS_1;U0tcqzdl5EV>h`vgxAeSi_-HjDRRMTX zHvmr(-}I#6X9mf6yjaw|$|;U*7FEYK7ZL*ZHb_q&f`nqzDyq`%p~pLd+y^^?T;*#& z__cC;#a?F>_@5pe6PiW@S<6f{b{WRUv_ zYP^;8M55}l_&XK%@~4E~VRFf`jME7fs1d>NsL$MFf5!S)fx1cJ*}GE;V_?#qY}p>~ z;Q@bLNEMRgxFc`m0XOS*`K0LcJ4h7fcwnjI(4rja*Pd|{stFE%T9*m%_ue}xMO+&i zPC%-v1$-u#=z_{6d4YASmIz!b7^pF7Bv`K|#d~cOO>^K9<$agkBi^LT-cW^U5rh4R zJ_m)N@L~rN3L4$;Zcw*iU|v1vL61TWsMMfX{UNx_?`MZn?UL&NcHlrYNh!C{XRRq` z^D;_x>U6MzT3Hu$XP6wvj@-{{urg9O9ir$QMapM-62a$cMr@dR(BQ@I|7m8zjt@w8 z@;{D>4|U{Ii0!u@SkLF+aP{SrfSm*t9yw3K(`Eg=^nCg#$sFXUaQ!EydNqgbEikMKxkzfS~0qSudT zb?Bp$YzSzi^Y~Gv?152yRH72g7Ap%srD=+FAP&(mm}<=UO&X-d`iR@jS-!;DBh)EU z2kqE`TvH`#mja(p6i}KiqoA=0(3pF@qr+ZwkZ3KA0P2)YTCkZE>HDw@2E47 zV$nB6wO1%0#r@d9lzZm{IBJD7L8^9i%-z0G-k?y?29gZG&rKJZ>w14;Ym7L;SXC4`u8$O^s{S}fO8dH5fj+D*JqV=8S{Q* zuHq`IBY4O~Sm(py2;rF~_F_pKi!G)UfFmNXS>L?F#}0a2Pp zDRkM=xDd@1#SxqytZ!c~v?(Di1+w8-ulsU5_r3Q}v^ql2E8>DA5#e(IB3+~&ep;qU zfanN($~;ekBlwk|kp+v>NF&x`7KFA&muiP9o|Y+8-IUGX0g6|5G~$VoAsfr5b)#p_ z1G5~Hq~#mMLS$dI3gI?Zi{pKHG#SFcZv!5kJg8U>kXH23XKy2|M_R)Nb{g4KcQou> zGRb;ChQ16*u1>7x-C5eG5s-zBOg8DkNA9@eZDc8@E3yaTLDMK?dQlB&nO@XE!*)&g zZs}g=t*xUaH`>H3Wi`I;s?qLV;#?XPTG@rGuot>4FhnIKSIsWvD{xT}5KlOYi)@_t zvM#6GlpRLub8#k^NG=8r_@7~khn&!*QcK=8b8NmB<3<}v-X(OC$n=(F$<_gXTWUSP zGWREcQZo^*7yS+nbDPxG1H`ab9bb2J4F^s&Sx>xt?M0_!r7w8z=JM)x%V3b{HR(9H zbeMI4l7*z^XjrxV`!G<2QtF;I6}|}=j2{{B%SXNk@~5ZlNepRo9Z3%W?Rs&*8Ry@# zvl?c1yXJYH`A->?Q{Ju3s{~x`69?smnHrxvC~0nprg((uqR`ueI`w!gfRf^T`&Trb zTLF0IiHQ)DsOp&Phm%K7?x~CWGNW5U`pL{RrkO3LHnV_p-=)$}(PLaeRzZu28ztYO z;!dMG;q$N9;kZ={2EOYG+;Pd)d9S`9`fqozlI~N;INMRE1A%J9cR{KOz9$mb0wd72 ztwAIK-=r}n?AS)~Z%ZPv8woo?NJY10y}*w;>1;uFIbx>for18BVTu_DF;W%-=j;gj z$vz@1p&T*rLHVn3sdjtFzBlU5=qZtAhK7Ryz=2Om-DJOuhD+H&46KIpcJp?=TP@-2 zObJZcaZ#+=s@nkoU9kcMa>ji=Kj{^H8~m!#4`uYcffK)#`l%0UGM2(90Q7wGB99&R z%w_YAVI^ah)i&yBsmhpU zb&M$mgz?*HslqthAtbMWKzHf%aosXTPBA27HAb6h%IXwsoR@hjo6y)_HsF7m1N~X^v9*yF5|5cgRNr8Q6!&Is#ImmNt7pfzfx<$ zipt>z(NV1`D`PE7lGfEF0a&bnz6?;P$wt_1ui0L^QHQ}ci0|GZ3l?Wb9S4?Wa0TXc z)G8KkmNByKqCb$#zYHy$^0%I~k4d}H>OQ5m{FWmHb%}DVB;*himX#yKgyml#HPgqm zR$2R`sae~mspFY(NmGY0n1jKXrm0zf0M(}%+Z+-hharwalJ0RghHm<#sB;~hIZSd^ zk`Yu`K6_o|y*eU#d*>Ls>=8UQS55`6=T)$?T0;e4Z>->t zc9{yso~_{7Gkx&v=?VdRszSgXR!Ff26;kX$g=v}~NqT(-(Z?&z>$^`~)}h&?!&p9|+PclZ zr_Q{JgyXa9p8jYH?nigC_2&DL-m$0jM}5@@hyNV>j}5sDo#@i1DvcyH>FjSbP|O4q zSwg=NvUs;;+Mgk~>F?*Uqt{H(ltWlfO_}84I-vQ%&+e9#z40lF)70NbnJ|A|(d(|H ziBTu1Bf&{&(g^!9cs)+1&L74xs5Sbs73`7ty$yK%v3)-Q0=kH56r|6dasNre!{4MVa@$&S8h?A!6 z$5!;|zdOy9#-a5X8RUVjf5x_*y^$f;@wZJoq)6(GiZv;isg((svfWnNEmFHM;bZoV zT5`8bCdZNE8SAirhGZ0XScnEas}%fmh4e8zIHmfgg+I7*tc8*SdxlSD4w^bNO!A`+ zvHsZ;LE=N7^-mJ`(h6de4d0MHHUG5}A!Q^$dfPt~ zBK^X4AgLZa^0U`FArr~>3zCr(nZ84D$S8V6U6|yU zV1MR(phBTYCqvdJ;V+ZOXUc-YN8y+D$OL?azU}4ENp8EeIF8!?%wy}2At`E4?f@JP zoXL4UM0(Z`=~+`q$C^UAFBGJa7Aw<8`4wQdvjj;sucH(o%YtRa0I2~cgCwXa;B=@| z^&?1H;J=@h>@?zsS8kE)DB_V{WvO8sCgc%6ceEf#J%JBXLCVC=;^YRf0ZCRMyAn%qSArOT&jhEZ_7z>DC-a(*-u; z8F~Qdc08Kz7fZK40%UIW+=lq_Q-ezK#JxfJIIo*&W%8hU4l?(OF!z2i?{e^4(Mx`} zF}-^_r=htV+~Y=#=SVnMJfktuwokWo#B`5&M4mCGORq=ft@%GB1mZ*{_Bii8Pi7eeM`ty8;V+3Jk%k7Thn3VA4LTX4k*+-mTY>w;epb!ca7t}_0VH<+^tA*4lrTxu+aw$ z9yhpb@T9?#&317k8Kf!ST}AHq-BozZcUR%e&lLYW>8{YH+*<+49rp&WRRe`Swi`vV z`@+|*ff>P_NIhY|D+n&th;?sI0x3*Wj%wE{6%XqK_n>}F1FgB##`;4J(l3*S*X>o1 zgVv%^z!M2OZ#2S57nz7MRvGZtye>e z^uDfFLygEeIqLx*a^hIn$QjF7FUuLU1PrjyPDqq-;bShK5oQF)VhJxx&9&_K& zGYeT4bu-GVduNa~{;9}izV{2}bY3T2aS_G&ry$)e2V&4qhpZz(HXK|%do+HMz?Xdi z(tOz$a*$0Q0P;U7o`r>$I&iq!=nJrgn&8|aUN3VE1##RVixqEZ$q zVXGLjpOrsD)p`j?M;fdEG zPFxm($J0+Z=`dl)yA!aIUzy-joAF;s@b29Psjxl3$78;U@OMeT(d7s z5FWafZiJB(HvuD*=OMTaWI)y$SSPYc31Y!CNePuSl8_J@R(D5eu%ILCLm`_))Ib&s zSO__IAv9VLoE*wV3xY5V!cd+ltYLm8rRi^&$dtGa0>ZGKz?H))s>Pz)waW-!u(&Y_RB+LQvO>ZCuicHeDu94d6Q?~X% zJ2?1Ko=2n#r1It_h4cWaOqq-A4DyMmdPi~!Xp7eF)065{eO%V?mJbVFa)|V0QV&0Z z@=9iC!La;repL^dGv%p=@%H(z7$t%nc9zY1a~U6*gE9>J#RI%=xPlGQ7`ZB3U=3o*X{wJ)1e(=4s`2q~_#8C5QSt9xAN%b?u6&{N< z!cO|K6X+4C!jU$^$D>?YIZrmOLmAQEFy$k z>T?4joG$ah=H4_afJ*e2d1^O*=6lniHa?1!`uYP4^E@?kufEPR1CEO4e)s)sc_L87 z7fW2uJ3$SuHa!tu^vOCQUHIuzwo%cYsy=xMo4odlKd`y7>efX|nF9)hrbQZYKsaq780Bfwmr`|}aE z-X6!l^V%>CqSD_U_5v+_sGXAMP50J?H1|`a={RO)iTDrdH(7Mxmxr1|>TCsFWm2!{ z3|>HhO1!kJlDe11;SFI~a(=YOA7n=I7z;4obkOfFRRnk9XTI1a1wNC{eI#pCs4?V< zdHFbotMCJK>sxu$B3~5fp{5gg+tItyz4D+i^frn9>nj~y+ICEgvJbg8LH9+!rf-E#w4v4kbYoxiasBPb{Y!x%~w+_8OvSAJdS&@eDysRQ#fQR!g6vd}&V13j=$ zH!)Bbm;)l{fp*qf&X*3xhorIld67z!?2kU8&n5S}-t3RM^snFTErN$>Km2Brg+5hX zFuF2znA?y?Sm0#xZN~}zbut*5+SB$d2mhLUpdzA&j9H~mC8R4{nE7lak zr+#k$Gtr^`LhA6Na6M+zfBp5VJOYJrsfchCB-iDk0B3R6FS*0M!K82?DL!$f+=fEM z9!t5sK|c)CQ;Ph`GC0~9b^Nt36zC>weF&C6z^i^1jv$}m2FV>_jBAkQ^E!(a0q0ah zTm_L6bTVLKQC9BOdI~#B#)foN{09vznk7HqY&J$qwBn`)&klOY@Pfw^M?D8ni5e71NS7RuPH$o#` z2|0Kn- zNS>#vQj@A5QHgJJ4Y97TdO*)vKl39AVp4TT&si0})eft2FV~|{bX;YJRS$rQQ%(h$ z`FYT);(Hi??IaYtivW=%1XhK7N#1V+A_d7+jni)>SXg&e<53miJ}arJ@wCHhE|q=N zhoO$9>t-Y$UaQ0R=wYl8R%WYdO9lg&Hwww%=Z#=cIdAln%6Xm>RL=9dq;lGD=Ff@W zWyl<{l=p;mTT17t?A|Y{g;jjnW@r+wJOu?myQ9NI2JW9V&GdmXstnn>bw_SvqBJKHsV73vJJI>OA+Zr}B4Ca}w~m z7q!4!h2gJ-)p&cS6?mH#B-%$>sJV(tbQNfuR7+N&P z-&%nB3&<_LRRfCmnYl5uYLA!;A4zKJGG>WAvtU=8|6` z@jFDknYx~P+|4Y%9{QEKmb?Mw6PrpmB5V4_i626?ptb4Eq@9B1n{R#gImlX0!pE_{ z0u9b=dG*&&F8(pfEx)pO7Zi?)v_wmF$-4kF6^}yQmKzuUF@VFECi!{Xu% zXuaho0XkZLo0QE*Q|IDX>lZ0ui$H}xDBi;+Z(hs}9$#EedAA5~!qFRdZHQX7AA2FJ zc2e%1C0kj5j^bIZ08T%161XMN zlD`1-%EHoDL39h{AG-*MQ(CVdWm`YNaJ1fV;#pvgiuXa&)>pT2leD<_jRgRHx&3FL zbQHG&)%q)<{gUDXsNedlXFdeVNztN?qn`gQNILqq^P;0(AjXT1z8&RrrQCG%ZRbZv zEt7KV(YK?#T*`~1(ic(dsLm4AXrY7!h1PLcVR3=OwQ#8IQ}B+$XJCt{FaTW&g>H;b zvG94c-cq<&DzHzjh1>CYRN*i2xv($-W40Ck0-VPdmO;Ve3NJ(tmlP)9562f?gbubB z#)0W5^x^ZE!Y_e;QQ>BME-t(QpGOz&MO)>H!L?}dqU&km)>#5Kh=p6D zjtw_Oi(XA@x3;z(gqTIYER>Fpj@L$uewBoda>tfv(QBmG)w&0Q7gd#~()v44Xi=X+ zy;12!FxR5>rT-6EGu^fMA~bkXsRX!n&9Scl(A_#C@k0vVJ#G~lr|`w)Jak^V`$VyUH^oE!=`pRZ7l&S5<7ey`CvE~Z^Z0S6n1gpvMxTkB` zo1uaPfwwEq?*`k*$T7BGwK$K1h5UAc9tv(JqwMUCiZ(^zCd4gDQ zX0&M0#fwU9@W4>S(Ti?@kfTIA)LpoO(oQeDteNtQC&9aqD=b3LQeEmhLaorn*mN{nJE6m}aTb#PYOEStuB?(^o`S&>FBA@n$O4=kYeZDQ!rQrR>y6uP-Mp>y zrhc3bzZw`)6UM#+xl-@zwMgc{X5rh-qg8k z>*gE#ckfz0u(N+x=hhv&cCX*It&_mA-TnRBHf&kHb;q)8TX*cat#kd(?aOxb@7T0# z)A}2?f_1~TJrKEl{e~@DcWinJTikW~t|z567_f8mh7Fm1o_E3W3znbfx*IKbC2#Ky z{W~{xE??fceJf5h^OHC3T>o0f#$1N!@a&IL8l|$8$5_oN_ZX_P>zy0m2%8R5xqtVT zO*?mWV)VB6?_gv2XSn_w;g`3^Mg!ZnZd6e>uHTs>#_?_4 z4)?!t&+gs*JECaYtyPMxLbct{W#{_c)fE>m-@wUL-MHzd^?SDMuI|2lVAHPUTR1nX zyLNBHVIBY$G?c-DGG->^I5tE9lL``o1ptmt^~OCnRR?x%y>dTGy9J!`9%_pH5o<+|$X73ZHH?SXBo8`tk%A8p&ZYj<_qrX8Di zZ;5W%v~x#w!?yLic2#dh$l0_j!a!6vZ@Yb9OZCRBySJ|&U=zOcH|^ZCsk-6DXxG-) zZL02$_Uu@{ZR_S8n>MQ8Y$)q=>Su?hTHS*oxDXPgecmU8t%y)IL+aKYnbmRKRWH4IWv|(-tGaIWnj4~O)pX68b>(>tI;}jv5w)Tbbz#(h)2`}mBwVs` zZT0G&%T`s_u3U4)sz7ThYkDJ+?~HUbpv%Thx54n3CkXAEsssJIw(j1Fc>r0xE7zg} z*Iu)(=j!U^tJhw$uA$`{uD#)WZvu0wYT^T%c40`e-CW(+&DD+FTyx!djmXt2qACoo zPAcx&|G-W|fYTj5KYA(6BY_PTR38_HUqP zpo!I2ue@T_CD*Q7*R!U2&AOHAR#kh~uDa%$RhO|bou6Aat%r5d=oM?OEnj;6^<`a0 z%I9~TzoP3!=dCC&+rD97&qWAzyEomoZ2e0B-voHarv4qvZW=i6MTEEYuiw24YwblC zx{W~W-m+)=jmX#U+_2>$tj4##c-i_FY#(^Ru1yd#ybNLKqRl(@oPS$+ z*-ba?*|C8GybP?&LB5I8IE44?crE;5+3xi>Zo>@b+&b??(BJvG8)(ckVE63Ux&a%C zs)T{Yv0b_Lic2nh;fr2KV|nMi=7y`UUbSxR>PuH%MZ7rL)hk!8X&kf_E5zUD9jwc* zz3M7VDe8E^`GJl}*rArDvCci|%g#-^`nTPRNFz%K1F?%mH*MRqYm51qj&UmZt-0>} z^Jobl!?1|#-csG&kA+|-mK*xT)?L+sZR*4Towy`m=;&8ZwA0GKqF> z-Ml5ots8xA&9zqtftK-4>hIdHe%q!fl(GRHot+pfuewmChVPNiul|8eSo`21>``Oj zy9u-4#`PO+p*R_xE3Ues_e!@!th}(H8TtVl%4OFe6Ybi9IZ#g7VdwfCo8eo!x=4iD zvWZrScI~-wKq8(v&+2unuD+(h&ZC=-D_4|wd&G!n6cVCCp{-b zm5Y*kjCfXd5tC61htl=znrkoVy}r7pXU(cecsLwxlQqrLSCdS#>S?w31OsOt53mc50B0o4R)AZFU+I;L?cTwsxI_ zU+*WPgP8D@YkDq;awdZ7TiQ1yNaXm81pFNQiUx&NujuNEFon5Q+*p-*I+T~L?YZhI zgc)`>t!HWyUv*(BY*D_nt3!85&$=t4E$eq|+=g9hq#lUF(9Wd4mtMQ}8Xc(lhv2f+ z*Q~tcDhvUHry9p_R##rtd*#aL#`U`xH*sY0ew0z=x>akV>LoaRMJ~Yk*&(a=P5nE! zuTS(^z2-8+)OC42bj2kWgc~*X&XODzFYDj1XFFEdU7gphy55~{VDW96sIq9AGO@Fk ztOsr{v3twb4Y%yrv@6*arTpNU>#p#g{iW6GuC!5Fzwy@UYa2%K+8eIBA(@rx9yj*iR^7sp;#QPv zO0reZJ@LT$tvlVu*!f(l>(?O?Vf0+Ma4W3_GVEF@7md6&%GvO^xS}rMcEs8KUAqR8 z^_OI&ZM2~aA8rqG)3)`SF#~dzA%-Drij!@Ztt>JPS7Mu+Z5QDm4v2MufrzIVEPM3b zocMgbE)}v?_$|X4o;_r@&=?`4Bec7WceZ8OfpF<@R@KSon-BM^k#5$!U*>M(WzVs7 z2M#z}5k#@#^SEpK!PHF0L8&W>uDJBlmzK|7xpRA&8^Cq$Dn++}Yd38>uYC3;d$w-d zSmvz?_J-%LIOm+~9x+<^QXItA^SUJ}KxWkZ;$L@VD)9gvq!RQ?w|{i> zn?`><@&X^k1PM=;GW=P3M~2Q`C#jVA!fy%BIl@$uE5rm-iug!9Nu>yvq(Lf0xS|YF zDbso>dRFv7qo0ZV7>xg41^m?R>lxV3yX>+3%#FzgN#~?p5hSaj9;#C_Gyz;B6-*F{ z+zC+ddBH1lWN~pJrJvV2|0Ln+_u$+%SS?^yhzt8g6^2J4^pKST_EWg0= zm6ory{56)}V)<>BzuEHNwEWwa|HSe+%bO5Vsn0^oJ1jrJ@>487!}7B&UvBvd%U^1F z#q!H7zsmBpmS1oAYb@Vr`OTIOSbnSJuebbvS$>D*@3j24EPtQnW0wE1?7Fm9(c_Vmm|tl5D$C{d6yU1{Z?pV$mcQHb zG0Q(;`KK-ag5_VceA@C^%TK@+JKJ4h`AaRYSia8kS6kj^`AwE@vwWxJw^{x>mj4lR z#Q)D4%;)JvtONgI@O{h?=NDtkK|M}pj^KWQ!4>9M7gia(mO0jk?FPS&Io6LsgWtg% z>xw+9hrACEMqfX{{JBx|N#pyH<#3az$d?e8@49_E?*5SP-l_Q(SHcbD?r6DO9W1{Q z2fO7s5-#7_PsDP!B&L_qki%bxgvew)$6ce7l_1?BpQ7X~>M4et-9Xr;ZYx}k%yz(` zlU+y}W1AF_w-JwxHsccgrhZsO%Ij~uap$I6)i8#U8wB)CK{@YR8D@>}RCYU$+R^fr zYp-6uem8Cr@hA$mc%%s~gncF7yU?`4a+i_DbUOaCjBqPyKEAU+g_}GqACDoFSHyoN z$~#j^`hjpP>0ErmwWEqah~Muo$exILlZXG=-dg+*<#AsE_x8!jTLVle@4b*$29EM* z11E1Y%Ave%fWzIhleYo*P~N8k{iv6dr~CJ$zl3?FaEWa(y$AopcKHGp&l)Z{KJJ@C zzAwzf_uUNN7Hj~|cEXUmetZ+_K2umP~j{O*PkoPuxVD1h$($~TFG6xtRLGt=BM7iU43(*h|JVzkx zOFuXd*jE<|P>e=?uMq8L!4l;#9fSWNUj=r#!x2Gq#m)=PKmWpVlFobaiWL`ho%iDN zyUOMBy1K&87p+(U+)G|^zH;|199(tP<@yc_Tcpghyj z|Kbk;oJtS51OJ%{g_h4r*2;NbC^mmvvIT$2tf_fWvIUniYZc*z)&9?6q)ifMeTBbY|CmoAs9@*zxY?BQ;W_5M2N*-rR4TBOPJp-l^qmCh4$@$3-;9Fj|CIt_RHJ4g|T} zfq?0B!=G(=r{yoQoZpsUJh_GFLH-qi4U3#@^_g7JNbx@3cg8x^tV9C+8 z0%qCm0agHbpCcNL;O-3Hm$6=74xCHm;r}<_KgPoE0hR!GBzu5f@J*mD*EDQ1r5|~F zfDUvp&o0?Lz^A}>C*-)~x`aKz3$e8O^l*EC^JQN^_J`jC^gi4k;78C#_5g1+wXg^H zJc?Mow=*j?e@C(fMjH zAH^PE*VgU3_Ux#hx1ze?=3DfQ#K*J=$jWJ4?gi6`KC%mVH1AD4{dNKHTDtE4&)$~+ zMpa~M*RATl-JM>u5|R*Z7D5&R31JBkNC*(wWEa5&0wEBV5DZ~eA%M6qC^{;*ps0hR zAW=|oBMLgshyxkHVQ~~?BqI6@1~sFM`M*=Qy0Z|UzW2|2@1OV6N#AqNsZ*y;ojSGL zd#le?pMR-!Kx>~x9cWy>xEA=oym{o1v_FzDz1`1@Sz zwLniK;F3G=p;P*{UJD%jm1_ZdUi53$0uz4aS|AMd#qH?8$FFMZwLmraer7F@of%jO z;CkPGKLEtG?g#wy*8)}0y-?|owZMZo#VkIUKwvF!BViWnIU?ftd8ct?OXivKe=0g=~|>#EPc z_wZK2&K@#kEaV^mH^>6F@0vFc;=D_jm*8*7?Z9W_LnYBP>RuBB}<=5R8 zIB4En2|OEUC+`NTfenCk{B<9V8(=JKF*0KD)%5Xc*pP^E(`WJM^eElu(s>Z%`#c`T zQwjHQj;nf~$Hn*rMaR7dpRQYi$^q>j3oRKWyc5tD#4L{kx`Ma`s}kL3f`*VqYCa&@DB=pq+mTD$#+>yJK|oVwC7+zs@G&dYL{7xzDD79 z1A6St{wUGm2Ahel>p@QgqP;lA0GaI`ub+Yl;UeWs zRp|(3BJ-^QB)`5@;g15sEhy-dw4WJ9mNnKjdd>fwy868byg3N*Ro?_atoE|H-1^2k zFU#F~p4E9951a?3F1NbTo0B6bRaEEX)HRCpUT<}-Kwbj%2M*NZ3zpoR^L07(2OtMX zo&4nFc)fLXbfgbabMW!jK@)rkN*skTqTq;sDTC7Sre6Hz;IEF#CKUoG>4@soH|Cyi zJYd!f6y(koBqQ(-DJCa$C)uJJX#pY_z137#NB|qMR-<~b1=R;!;6>r0+B}6pOvxrU zaw>5LNEMR^PLszh&(y=zz+?z;HWBM73;3Zr1-EQ$gat5oNjpGaX}>1*sRUwbG%G_1 zUa^d-x=GHYHK$F!s9w1v0K%GE@HR}R8kT_Wd)bYX-#b#CpM`(N;XfBY8p9k1TzUVeU;oBrv%97 za$%cR0;CHNH*5l7jalap5C$_zZk+CI^pd&oUx#y*5HMFjH&9ww%wJ9`P8bKR*_<qVlbY?}Ml3!Aj>VZN7C#^~`^CDwYU8rVMLDW;$3|-FO17(L&JrF?tHBX~-{~sg- zyeiOz&_sa`&f#y=RjH3sHtMr}0%{ZZG$Ih5i=nGgFN0l4JJZEc8x&%CfjJJL?g5*j zayZXD(1;$9gWi&R00oedn!63oO`DKVX;Sar`f7M34wMN87U0JTvQq)l*3C;oVc=x! ze6A|34#nXV_Z0$yFe=omtYA0Y-)z;UT(V4Lr4bh@)#vV4u7*CT`Wf=#zj;gIJdhgD zu9enGapd*;2{HJc2)WQo_(z%M363bnEK8Nxthb@WCa-~#^^IN{1gqgPG!m-OUOJG! zQ<}yjRnegSp_R_-a!rlSduf2dKPaHnr#UIWgju7JW)4y9s?K6$pS@YGx~%GIa+3^J zO~D`i+eN}@?{xYDx{FtHj9r$R#Nnw=t3iED7LONE5gxs`V2 z3M(Y2kdQjJy^DubVhZRgB&2S!{tjh{p_I`K38`CbtH7n(ty@rvZnvF6IVvP1(mW)g z5<*o-NTFemnTiH!+XYtf0TEO*$ep;Er=mgH4pZWHq^61n`5vm=6b*77l2tTF-ER4S z(*6MwqCqA?4_hb>UV*|94e|iac@I+ZDi_5%WBd{v5Dk(75?MIyfYqnF9s^?MXNaxX zO_gx*KcaL*gCxXf|DIB2xk+b4gZv#yD3KVVK~f2UXpj_}&L0iZIRihJMKnl?x)sUS zlZg54!cbBm8stw9WU$Z@WI{B^6A)x0Y2FCf4ACI_!QA{NoFf`!9|&Rm790@`lA@_u zI8BI%2Du!Foe##dP(*{o3J<#9M{I^fe4I8lBN`;d;R|D-6jut-AV)&9jpTc;Lo%X4 zZlJQFAq3GN z6cWv8MuQ~dF{c>~lFltoGa4kF+nr`KNIFL}$d$;2Xpp3ajU>QLX>&!8KN{o<@D9yE zdla=l>o{oJQ7+fAsFgGIQX3!{VKzyEx^&OO-H>AZ4&Ha0B0-?zfNO_23Ze!f<|Ew z6SeLrtCRLU(vvibqSaZW{g9otc<33dQG8HDgS;LEAQ~jD5SRiju6uUu2G{_-9tiy3|QyWTeVo={gMrL9X4u}Rxk(sO%64FN=W+6@{?xVDE zAvaPQg@lv>$mwLd5-=TxMKs7~h>5lx_~^d6MII<5B(qW*SwF@>>;{f#kRJe8DI}zu zszY98p%YV{mAakvI205kVRl4=w4#9aS0KNx@j6u8`gi0oT?Nq~uRyByEUd${XTYy% zdvW9%1t+v<50P%#E3mIa+bJDvJ=sx913RKYevbr1gQN(HG8*K~IElukEk%PQjr`Fd zsZTQ(qCrxB=GOv4G)OvUd<=2tcxVW-@UIBzFA<&7wsu5=q!c?JNhRgF{{SS2k0T^c zA};QNLWl-Q)$rJlkm!7KtXb+*(I96c$;VG1E22RL13@&%j%1%j&;ZdONo!?}k)9Et zX%y&|$@rw2_L1y4<8j1q{3x*IY$RGpd5b)gmZt-g@hz<+z)cmtDZoN!%u3^jl|t~qNYh2;68B)`A_c@YErPPx`6*Zd(ICn6 zfoPDF$H$+?5z!z?4Mc8ixEU?qy!7M zk-au0J_E$gZzqwzRfXk~g1?hG`RuU}iD->fvSXdcjMgYsf6$JbLlmu%Fhpytr<&}R z7)5KWKt8Jh;o^0SD~Q%ebB~S2ZPSj3*7yk!Z3{J|_7!+E?Kfmcm5ykQ6pB&HA@|S@ zz_yz9DbBgpfGP}75_ych)Wmx3U+8QDdJxN3?fpngV(jqZW4 zH2x4|ZHGhrmx^-e-@hMlp8uM-hcI;@Ld<_(#KYDRX8zeB4KI*?F?8X7N$A4XcD@*^ zFz|abf8?pakDw8!>E~hdT^KFzSH~FqFAFGW zMyobM2tvh+F#}r$SI2&~|LrjY!<%m5;LH;E%^}_AX)9)6OMacjsr-BBmLVQ_byc{X z?uX(RoY@LD<>3}%vk%1xY$>mGx}#M(?mjmA{PORY>6a-@A0dBr*&O#ZAvpWx7=EEL zS^#BA#Ft|3jUhyRNZNcq0w|?laQ%g8_gBZ;yC8F5S=e;>ipR8pu-bn9p9zKsoj87& zO?U1n-cck$Wpa+qlah`n5=6oaY)ptdfn-IBe-xr1P9-jXzBPnF`KTaG8QD6r_9lRPK5OHz>G8!L15nf2QR7qk zv9D9oa}>N(!O05FRB)k!l?vXW;2{NT75uw`jSAA;ek#|gV6cMi6zrg2f`Tauc2lsY zg8dX6sNf|EUaH`D1t%*wRl#Bf=PG!Of=d*J@V5$XRS^48 zWj)_f@KXh`#n-gEf(Z)tRdA|;^n8@;v`N8t75qU#9XHu2-K}7vf~g8-DA-HE90lny z73CYM;3x$rD0roU3lzLt!ABH)M!{VQzNO%w75rGiFBP<5jHdFiA63FE1?h1m(Q_3X zqTp{8d_%$CD|k@BqY8ei;28zaDfkZs>1AUiKT^RY1$!tsP{C0OUa8=01#eRD4h7dM z_@IKD6x^ZU8w&nOL3(sf<$tc=w+hnONAz$7yDHdE!J!IXrr>l1>0v14qi1&nA5gGL z!2=4?yYVRfxPo6R_^pCJDyU&vBR-pgZUyPVGSM>>>`xHm^yLblK@j6Lz0r;MZX<}n zdY!@_CWtayrfzC5j z!i`vXm166H|3hi?{ZK(aUwu;Bu}eM!A56OdKz{mk{&l}st^i*(3ZgYTh7(y2TH{h( zn>8ov0XyFUn*T$((Fa3U3%(<;%eOMcJox##Wo2b$8cm;H`n_^y_sm{qtdn1kUGim` zEbC`~qeON2b)R4SjglSfO*`sj=Qg3iK6YJbR=Bg>W@8$LX}fOI=s~+3^RfneO1c3k z1h>WmT5McH6H1s0h@V4qawXlW@hm{_v7Ur$nxz*Y=R)fZXovg(M2Gyr3ZhR-e2jt< z0Z9+U&yn;Z1!pT*rr;t4uLb0&0OH=*1s1H8fL6#~OX;ZI%?iJRaL}=4m-4Y@m-r?H zpHlEy1<_Yz`Yr`uS8$(#e^l_Gf*$~q-hWm2Nriu*;8{igUO{ZEmGTAJg7k7Ih-(0e zhbtJZU>qRHPX;7AVi%Z%h=DEna{#Gb@)Z3Nh2vVmZnH4UXriOh#}Hiz>o`EPmo||g z%D)QG3cOI^GgUfbXiIyR5w2^jLZu@#Bj{XPNf3f>Q1n|B{VqToc2nO=bjZbT$|R(a zlO*Rc1)oy%-zm6_AoSUx@LdYN3P|$aQ1ES{L(aP@{QyDaI}AvE{TGG*6%cNre@qZ| zV~zU{3xuxDI%MP?LMU)%r31HCIV_qs9;R9~BUdy%*L+KfMWdsoIRd$H`3HLTIQ21uXV z2Y~5(#@iWt*|j+z;r!a1k6p9yV~KfsUHb=bj4Z_V^u4aEEOsq;1iSvO75`}H$TGjI zZ_KIwG3TcPxyX>Qw|8azy!r!WtkE@KFMce9qYL7CALw0;-@l*^=cN{|jJ+uG_Zw&3 z@nBUYC}92l$3MNg^latt4}5gK;VeYeLj#DF+3OF?q#};zR9~ADi;N^>FFPQ4aC{He zxGQ$gKh9R}otYDvGjlHie9p_dp5MQ}uDUQI(xr>~tgJfUH7{l~zMZkOcl~vHy)QuP z6`40xx_YCy>T7fBmi8O)c4pCeKHdGdyP|G zE&MU3em~S)N=h>1aAo|MlTp3Wwx(g)T}P&^L4E75JCO5H#_#XC@>KQPM^4TwJdpFT z`^5R8$n!CKvoqePZajZtuPx(GY{{-S@?Yzcw~Dpc%1@hiJER8TdL3W-h;HZzOEB|?LiWN}Hzm=cfwcTPX{~;_0{9E}qW3X0$cf)pi*sb<3Tlsr~tL?4)d9c$zVJkm=HQRbC|1ns>-1He# z>5*IcZM1&WYM_`Vw{UXJO|7KSEghTYh6uaXlLTqB&pSxF26T_s2%Zq_O}JO6HXRbe z@B(Mr%KtcyUhP9reA*p225Z^icWQJ4%B4-g(XHj6-i9_2b}@i6Y~`o*SG@Kf=n2|A zAw5Z(fY$PF<@Z6)V9gE+w(?(#0$Ok7e+(Jh-pWt!VgIGA{F`8&rmg&+ zLZN0``Hzw43%BzB7Uci>t^8wP*k8Go|F^Ks-Z;^1pR{k%*@$YWspN(1sw(^gH z)WBB$GlclJ@-HRCzmy_LTLF4yK({+p4&H2Jtd z+XeYtOULoQb}N5pQYNget^D=qi_AeUK!8#>fhtgmIf^9(Tlwi-5Ok&EpkG&^eVK#q z20=+1$!c z7Wfrg`N=i|e%)67-)hab@^6Ivo!SLk`QO$2Tlt@$CTM#r|3GrFi(C2QFemqM4h!YD zv-AJwR{ml*f?#r0uKkGLMIanJtvK-2T5l?97IOUJR{o1y`McrO*~PTyo;Fek_TB@h zX92D0tZTQ~^NZ#!no;b3t?4gjFP*)x=zrB#e)R@{i#z!*?&SCH5Nq>ArxS+ZMXpov zdL#Kl+t&Lt2e$FDclj#j7VkhEc;VZd2ey2(>&1QhQ>CG0L{564M(MO!v*jk)zz;*3 z-Xn}gxNxtv|8>3Chcg?Qi>I1zvBj3{f6*6c(94VEyL|mSi~QTsY1ff_-E~VJqZbCN z*INgE4l;i7rI!wwFb?m-mTwJ~n+z`xpG=9ib`MzKC z*Ei;?sMSl;+ujT%`-@Z_FDNgYM=vO+c}Ttw+W!Nene!GcEcyBO29KK9J(IRv1=_!j zSF6unICa6iX+^~)W%Ka9?Z5^tzo7!pxi9Y9A2(s@un9vh9e;t1XlFnh-ekT3Jix8C z8OSk9I??zcBk`8*A%j^{R9brf-BkM3mN{BVFKMx_!0*S+o5er$nlGJ~FFg-zUI_3P zS4{P9!!5F64C1or&g5AE}A>P7%zzQduxlg+>f7lN!tms6X2zYvu6}Dngh(?wru_^L%kZR z&FOFOu<--)N1{U(l}sx~4-Cv6v!T#Z`Lm_KNa}CApY8WkFCR8x=+uED#|$0#^RLnJ zj|tdRJ8j0|sY|FfE#{Pq`}jvU+tZHe8M8B%eKe?)%_}R%j96Ye4ddAbhMPoFIX;vS zn94_u#zI}r;urp!L9T|Ff4$JU9po?iNL*k*owsa3NmKDn?-|7lH_cU3z%yGc1qw)o z2^r>EVD|jQ)8@^_pkMs+bNH|x-8268@8hSvMNJ<|;BE3mZ)+caOMaahD)TA2&4YdX z=?bTPTC|TJ`%2`;l!yD1%|5h`zoop^>5f+EbRV_p^FOhVzrQLz5s>!r)807$$A^=7 zegu&4fZsM7aS~^+z&fGDA|tT4VCJ4jzt8*g286Y}aP_nQ+%Eo$d-&;bDQ>@Gzud(= z{H7f)?%_A>aB&a6X@`q@_)R-p+{4eh{+f5i2d1XxZ)Xq8ZvOYK|7&jH|5w|;e*%jV z+E-3%Dm;smUs_RJiZ7-;JeD>;lK`5pyNH)Q!|>+MZ4_~LY_wR3RCGSda z+xz!-w&F{}hIF#C|Kr!M3WVnNt4l?FK_lBV-@m^PxIYh0*&xWH4LJUfKkXn0bdJjq z`FS>+vANi<;Qvq>eUB^X=W7?=_Wu39fe)r#03bhCgRh?-0rZzk(C;gh`~di>K}7NY z?*9Er@Ryq?gZlX8p?Xwq;L`xRoC{!07~V48*89dXyLazR zZzVT=#k)tZs*>6S_U|WYowUm3Yi!l^c`SbqAHm|UC|+<0+v8Vj`}XaXtCz30wL847 zVT&)mE|jk>X9eCUx6SBsW6!jq)&7XYB%F!#b zR4v)4%SMhg7L?)I7dLzGxPP-vhMxY~La(Gpa;MLKTbOdpaV1Z^IG8 zUqhl+83si%ZMOm*E;8jT@*V z)q!-(-n}TE8!;m~3}fp%NZn(G65UczxI22pviNqxgu&OhNA239c44Y^AI7sd;@Z4C zz923xY-mEAE(YPdxtyrRbULyG@9=~LT0&8|XT*tVM!~+*j)c+YDi@xdZq~bbMF#_k z#kUK-ej5Y@iSFyP8Iq0cpcROrj@^*FhrVnN<)IJR!MD>@U{tMHKCOPWSX1tM%_{4_ zlK*~i&GH$NMjCxr+mvTZr8Xk6w6)KX3~j-nIu0q#?aZnM7PiD!O>2n{Y=Qf|Y${z0 zqETi{Et=lfFk65cO1c?z4}~91+HD)b4coB1Zw7|2^}4jMQNZCFc_lyAHuVWvS*q_A zt&&x-r7g>6%bVl&s)G%?m`Ne~u&V0W&C^-c8!hx@RodF->GrD1hD2Xee!@F7!&y~j zD|vY>@W`rl4No)b-AytgVcS7=Da}$N^C3uoYo6=?k5{&CW43;nfXc4=|>1upCN*Sv3nC1#IewboBgl4JD(iN- z3vSx3#aW~e_^Oy;+g|tDeV+?9zktW{tvBKO^_o2l7V zCgcTvk7Dte%C{nSvu-s9je>)I!T{n$#2wX{lAeO0NtL^ zD;Hoa@{O{}vg71&LGkw8rnma>1+DOmR`>$U3$g=9zxrKe$DJj+9V7C-nHVn&J7ya@ z#$!9iW4juUt232<~&dlgA>3^hHf`KqEVT?6wT z=Fx_oA<3bmECt?z4^D@T3q2A%VsGA2oAOpeMrja5Gn&o}C%_lI~bvOdqyWP$o@US2u>wo9XJCB@N)(n>#?{myR7*$gd1 z);^)Er1+UCb4|1cYa*%(OW21sl6kI2tq}Iyv{L8LaE$X9V9|`ss|U!MpY>&KGCiUwEZ&bMeX2(81>U$zsddLUHJHgti9b z!o3ZN8IR;!K4hu8_KeG4pKm>OZ^P3WH0R#{SW?Q8_a3a2)F;b-Ak^o0nR8a^9*hK3Q>3 zLsIp&GoP$DHN=aqNa6dG!&iSjzrAJV8s?fmLuctUCxRthjRx*Ek3H z;-0|zlPqiMoV`1_w0nV1)-1WSiO!N&o*VI8(Q=+5wc_pUi_@OJ7*t(U$w|>)T37EwcRWRVC7Dwt@v^EP3uh;=Cze6m+YB z&vYx6xY_FV-E&J9&hqPoqB*nqijwX3Y(! zBGq|)&5BbcrGKtnPw|>8x3)?=k=E+%`mv5RMW%C`b7$M@Knt6BRE1Q?Y7udej zh;v@Q7j3_J{@hWW$`%&4^7!4R$1gztXLWB>nj=7V6-(GW6M3`JUx~tXTis2WrA}q7 z?+$h^UAvn+T|b;z8lVg;RPrkF>J{>&(lR=xyf?qTV<=Y~A@N42st=Sn(m-`2iTUP<{c ztc=+UjrnC2MtSk9*$Z(kUp#|NB3h>z#u99#D53L(v<0xZ+^E0?24i_~dD(?5v*g9I zVks#r?+Sqn+2miAbOB2XNsEh>r0Es&r^>qx3rVDT1&CfV+EQ@acJjGZtKOdd(51=6 z2*y@-?JBbRn&ne%d1n```k-O|>Ro8dyt=YgVek+)Ug$&V2}`xKtTS;w+>n&Oo!EiIuuzUGu{!M7Xi0uuU(H1Ia1BcEZCiv&O(k>J|Z7XJGv)_TT3A3+r>JPX5NM4^;SH7COIj`=hw2bY+6NOQe^%3 zlISR{pT1tJ!;kM%^qRk(wr1*}UJ0soy>%l?a~#vw=Y3NZpMz`jKDam1PuAM{$O&n? z8}oyXTQ`nAmtNi-HqqAiz#6l=VVnYT0YCP)st zY8_eyT|zd`y)B>DoSeHpUz4M!b>qykgd%-oQ4!gDU&Fl_uUEZLl~FLim|Az~3oNdr zv?BhLoU;!h)$;U|K?Q?C4EoPvggYDlQT#TOMd@g1w67@$?Fyl8Z-#2-f!8U=&+N; zMKg)7THX)aTie`AoHh5TYcJMq<+=6S-Z~wSf9UEOiFE1}LIJ}ul_4!FM>yI zH$CX&!6yItt6Hl;@;Z2ofUo(EKffD3gPiNI`dZE47vopIcbaFCCMODQ5BwG9j^v;k zQ;K;sN9Q9|J8PZEdW)2^wQH(^lC=V#qWZ`2O_;TZnk(1j4F_4m+~WIdqmwfV(xip` zTz7!0vvH=`tejUDv3hmwQQK#S&DBv6)f=R%(&u9@JX zx>IWu*3e8D+^o)*H>>k9DRmV19me~$<~lP0cGnf?2UYY;kkUihsxh*Wt zozUUN(^aM;$LclP93-HJESS8dunsf z@on!GI8TJODre=n@3uP6YEH7>#vxxH|F_RrYVa}Bnj2xw+O4f^`H|%R3KEZQHFNFx z?$8BX?@F$Jt3A~4YQ~7&*|n~fW{d3Qq+`4)B5nP9y-rBrZto-idt!BR< zu9fGiw^C^-rN%V7vGX&wXNMZY{b2iZL6y~X^``DBnfG27;40l+VBYOEMnsja&bREL zCoux60xhk_ksIfq-92#D6wJ)=1?|vMo8?&E9p|PUcJBUcrcpMgiX~Bc(k#-UDfPZ8 z&xt{050cD;L9?pzj~zTY|6z%poS9JeaQ-I;H{*ygE@AVm*7v)zaepte%76FPK9nR| z3Vgfu5tE9uUo#3)nzaV*Km?uzP<`nhZ{U7rIi7tiE}mMvxOjdA?!ix8GP|N=>LNVe znM!-kX-AiTDcQu=M5Vj;W>$KuW`MbgTvWCQKTQZEOq($yP*f8&@C-oSQ*DD@G~IkS zGj;l+ii$F<63feq6lGyidD*;q*brP^wq)wG`Ljz=36-RtTs7x5pETgtd`*SSD4thb z(F`{q5wRsR=vVQYykm1^F~U=I*ofy(iG2`;(Er>JrtD<5Rc8ZOY)|Gt^JE{@D$;1PRaR!8@kPyihToFJ9c-O(IVd5}!aO8&WPe5CVF`a?r;o&1=$)1}~QO7_JT`g&2 zG|w5>$B}QMV>Qnj5;Dj{$7!C)1Az`U(eaw+`y`-4B&tu)JQEtEv;wf(9PGN^t7(WeB<78!u%wHKP_lc0)yx^XMC z_ASF9V;`JDf5!>xjF?SCy^E;3QF%Q)8q}GwFB0`h9EQGzD#wVRMEe{o%=sb=AC%^< zM{!JCfeb-iC1MfPuy9bOMC>BM2Be2XT;eO-9u4X(5uf;ukiHTL3!kxIHVf+SA>|{* z^OTYwJ_`!Oh+TvXl87M&qmKj?NF-6LjR!J3`nxzZf%vj3kTFIKXkEm7_)pM;kR6bg zA^L{`nIw@Op3C8eL6h4#p|4i0dFBrQdWDI;p^4-9K(C7Z0uuXpK7~Dlu9hlk2Q?3V z)x?6PNYq}Vc^XNr>1OItO`L^+f@ZXT0`|=jpHcC%yhq?DdCpF`KuX-76T+Pz^#V3q zW-H{*Som|$9BG0X+)1x@4JvhSbu(7Nox|WnL1m#XU=`dsk+204TgRQZ!wrHeLN-9p zXSs7`7O+JwJ9^%B?tBf8a)TC2YzKF`sg;!jG)YYJM;bp;${f&D*bOF0ZN);#CIiIAA z_lAU^8caABQuXf-=>y-j2q%Rs4%#4D?ZO!hI|n^1d#p>~t?JXa;juB7!4@N( z1r$$E+yc6Dm~Y%cmdN(V5%m66=WL1O3B-6~&N)HtF@Ow~LyL2+tng5#SHV>F*+wwbiP6#YF|G;A zNHxmux-8;RNM>RTT*-BX6lM|MqTa5n+C9+@8O0pbz%|c%s1tyA2_#pA_bVViu@Qa1 z^_W+~z!E0*V_sl`6So!hZ|rU}6=taCeNH4d1fJvfObI z?;*u5PQfGG@!@|5;)qRxW4b$;zBeXzGCaVYWMX4u!{Ng2&L%c4_9dw3PByXev6<)y z?i3T7AnwQnmL|Q+C0v+7++8H%6XeY9uCiibvT5DjBoZm+q8Z%X!`v7^Vnis0EO$@o ztcLgroztByWhV*>$mZ@RkxpVbh648hi6n`mi9iNQq_dcgc5<8ZMY8xI4~RJ*q>3XL z6x_q*@X;B;R#Om{7y9sfqcnSH>wo@xB$2yQR2l<#JVB#Us2e!g3jv)n-H+$xa_QAUN{CXpVZKNWhrta7%P zhJNU~Ln1jMjWoDZB6)(=J-)jnGFW_z{^PsHwgI{g6*~q3xlg8y@yvr)`+j3K+a~Tg zOFG;Lu#kiwshBj_ASBUy zg|z)%@P?SZ!y>F`ypSZ*_TtWXAe|-R5(T}1q{u1I$NC;e8(pGB+t3yn4?#@dMQA3( zH0%I^j}|*Iw?N^T&`EP~F5ZBLgidZ3jFOnh#_$t*g_25|gkC8%@rhCl(xF#LF9;JJ zXcBsL;-8QQGu}((XoZZu0^winIi)e8zCtyE{qZ^Vl8|jEM6jZW+NT+ zw+xUH#1fqQXl-U*n1r|Y&=|^}fM&t`1O$fgsc5lKz6i}2##dwI5X~uE{Yri%+S$%u z>xq>K|CZXE|Go>B1w12kt<%0@pn-n zFVk;>V@6CAk0G=EeiUQvV#B`2x$Qg-!>D)adC1z%@VVgtwh$bmXII?gI8W(HRod8rD)|T;!pffpkIoJB1RK9AkE$JsQN+Qo z!FdqB4gJl@?}tzq?+poVJ|C^`;pO1*@+)9m9}gZ#e)1Qn9>O*BflxjGeJqUEV;~CW zjWBKmccSL)_>bU>!SI~uw)F^F$ZdEg#^Y`L5Xxp1# zhR&bO3t_`Pya=lFD!W_O7{@tHXfo=nMdw4-ER{nHl)Cr{z$mU#sRB zruTuM_ScIXP)*N{iuKS^k}pGtWxNI*N#ir24Chb4bp3L5m8D%5q$dNn6yx zS)zK#KFq@B7B6E_J=HiGieVzEmm2YIN9#rPb{|L4KDq3T>LZuEAz}ksJ*ux9VMAf8 zWMKV-6{7WUv}06%-y)pb=vplLRvawya2L*)jaJ$=(n9|;P1Tb_H{sm&Bo1NqNZ)}I z3mus4kONGM;c>oczPE_!k2plr8b)?K3$ZhOD{SH`_MIYzGsHkENQ*p31{*Dt^pS82 zUy08J!`p&!h^Ez#O|`y#ru~$q+cU>qwKy4$DK%` z(a*O?nhE12&KJvbPNSc1i9EN^=;vE1&vh&&VP)SkF#(yUe1}eK_pNi%GJ1FE`-8&My;GOPKVKg)|@pT4}(GszXpI}1w7>W4AWpG^gScyamih}4KClNy& z83<&&M3Ti46z-lNkqmKvK9I}8sF-XKM;99tC6Xg1q9NUvOC(Q3qA$89No24XfhpZR zSt3KlUBq@pD2?GG#W;v@UnxajB|gD8;Jzxj9!k#;f2S&#w}(nZPm(rOvdt4Q=-}=` zc@wEZE=b(d<=knh7M^!85V(s>bf54Zd-vv^qn|ZrqO}Um~8`& zxV?G;P48Qe^C;0_y5k^DL^k}iLy;Uun5e>_&|!u-sD#r#hYrOOLARa)OLv$l9z`B= zfay@_p&JPNMRaYvPbQLvfH_Fzd>UFv=V#EDZTu%3?K~K!aqvVOgZMJo$HP~koEX^^E^49WMYi;@nvYwV4eqlCm)Zai_gT-%|DT|!AmIC;QMim;|AuL zc>W~hC-7r%*F+wH*`O1zfRU5o#dc3 zSnP{vx!B3(=)`i1X0j_9QHI?fOZP@&uapTsU+xliHPL-WZV8(r&oW}eG0DVEH97KP zCr1M-G_f&EUk5E>r-|*bnXLvnZJkltRDCI$G;~x*4lfHCE^M%TdJz-tr&JgM~2GgrCEE-+nKOjCT zEG7ZTU5p3Hp_0f)XE7dZ|ASQgCit+iA<_rCTSOH+#n>3#6Np`W3Hurkx0?vWB|4GZ zN7}6g;uB7|i}7gG-9W;`->9;iB3}X$DZ*e-mA~v zHfSweKTKSOQcvAZK2jX}E#>$D2dNUZPjkHokm2Tbjsn@%5r;79H`H#;M9cneYLP_j zFg^&@ z7|usvz!<@gqAnx(Zq)ixz65jh7(Nl_WBKK1q;dQyEW^h0BhYyQUy8wS5~s$S%*$b` zEBN3v#;)Y=qam;2XJMJE`5^S0Df|sgoKyL`kWr)%>q0YYp#)yf^U2 z(6Vd!N`tW*`DxVXCSKQxv77lyXnPBv2rs&ozYd*m<1|X#&R;_69lQrTvyo?@WgC_M zCd7L_A^#nKau|OTR?+xpumR__9`fJg(8$8AsEw6pqs?`GJ9682FsyFpPe3mRUxfAv z;^Q!;IQbB?ByK2_LxF@0L0!Y_CkZ`0HZb!Bw5!H5Q4=hi?nE;tWQ(twxcYmth-(uD zMaHY(2^y#Q1-y$#rbY&4N?@tnVzKzJ3*s>t5uE%HoWoDA!T{{-FVd+ndiZ9eN82`fLTI{eV!Y>% zR4nU8#omF6Yy2%)>~rVw_`Ad+s2@P#2i6F^uFj6iDP{{ z9!1!2h^B|t7P>sL(7Mwi@2cuCN#GjiOD3*#;>z}OsnR+{d8UBGPvlZ*w_t+Nco>E- z&eubEEG+BLLpvo2$`{F(fhno0UPC#q?m{_UjHVp7qGNMj%*kx829uHQz%b(DR%AB# zMoa{G{5i<3>^K4r&U_uOBw%!$OCYb~wFD|Vz7HK5F_y?1YDrglXm11`l1Bwxg;AdK z0$AI^Q)K}^VD9npx(F)Z9T+5!KaBCFvg0$b5z{(ughq^atiyc7M91&Z#LUw1aRT;^ z^q>biEJABShb&}+4zI(|xJ`s>d3-cx`~m7h0)FTTXFz6VEFu$OeQacqY+Tjg*Yb2? zFyr6kNhLZkw8BR-YV+j@H_n?U7Gr;oq}UA&zJ!m@IAc-_<0tbZkLhb+^rT8b2976x zr3d{qALA9z@oxb%G~vf0J*`}d2^bv5P&b@rpcT68lj`0jd zK7Jp@Fvf3(K{fsd7y{n4Ars?_A(D|C~_NpBZ@_YWRrDE;u1^5^;(9 zQS;Pzxgz$7S}>=YZWSgv!)H?yWlAKo)uNjEPD<}2=0J=-14B&eP3d3aJpK?4=kb+& zLZH@Z9UL?gidSLlv^Z}J@-cB1T{m*2E zl)X!|V>Tqw1Hmpa(eqF!lk;pB^+1s6ZaWsPv7!K6L&u@gJ$U+P-kC7&0 zA_*NYeXK+@5d~G!$4lq7h#w#`eS&aHK%)37 zjFWEOBuN&V;7aM{L#r-g5D73JT4jhd9mv&EKo9X7Drbs(?3gE3K;860nKD?U_<&3c zp?kJt!~l$1>C@$-{0SnfCy*J^IVOodu|SI3QQfW*Q&H9QnNpoXu@!?+dWmG4A@ zs5i-6ulcDKdeCm6CuQbshL9LouvodJ`bDCIPE)mM zer}6AqoonE(am}9t7yQ;rPooqe1u5P7@4;g4xChXPe2$gS(x_`XrA=_mR8iq2coLu zUk^~Jbk?s3j+o@t4hP7z8G?nZfv({nNV}Y&Bzio|LV94_3jc$wfQA{wLI-Bsh#Voi zFa(9)BHK8Qk|=}u4AdKo^;h`v?tUus-T)s7uNc%scz_5`P4*Kk(k()kK(+84F4D7% zl4NPg@1t_QL7JN$!`w(@`9!B*HB|G(Xb%%bKB1BR(eIc5nQJ=&WP0Gjyc=On-;aL` zP-%|}^S+S}>h2Q(Ds6CK-rrzo^BwvzK&4hyE>MnE^Hm39Olnr97cU%TzU`d@RC#IR zJ&Hc=dpg@s#jhzD`*oVk{tl68)y|SDx`JG8l0R-De-G0n zt}@B=KuK}G(+=dDO|ly~O)?pbwd*bYCV{B36}%%cVnklkg9v5?dQy$vk&ZMxKuw+i zM@kxKc95AwmR(Xhr1!@jxJQ$`gs3!ou;iyPUiivP=JiA-Gh1YnB|nK4NJ=%+=%$Y; zNOq2pcTlutbqL)gI}k{^3?*AiabO|uU`^V+t90bADP4BbrV+zCswWhQr)wxvk&r9k z`R zh4~V<$)u%$q><^EB->?3Q-{!sJFLP^CU}%M`!Oj28@F} zroBr9(?{$;nE^0m7hRn}hDv&mbEwjtLaKuwv(v^RAxJ-21?^r(!8 zaxvEdJs;;u#h4*q(%qkvh-6q;dr2Qa;|WXp0i@sR?i5UVooPFq_FKIhRkZVBI?bV0 zOr&!9fWeAk2X{TC4$tUvytQrE(&s9CwTHaju|A|-hqvq9 z$n~gvRE@c4zv1nA4i$@0nPCQEIaJ7|_UTB$yl+N| zvl=-2OD^K%AxYE5@I^R|^vgvb}Hbd`EJt3GL4r?=Yx%dmF=fT=66Jc3&H$l5XchlIX zks_v;EA(En<6pWHem2rfM%glepZ3tB;B%2BM(SONZ8%a2C^;z?Lw&feza0=1uE!Ba za22elMX6GgoG7iv>i!|XR%4Zdg3slF?TA&bW`kFt6||!!!jcLNylv0wrd!*ljytV= zq>fn?RHH|%p;T8bm(pn)Ehs(7Pw`u7oDQW?pCyIkc%9XKG9ctSYj+ZoBJH)pYMN*Z zDSLxeu7Z0!3f|zTE}-0Gl@FeSuk8usW`)qxaqSkXd_2zbg6Y}4cBhG&roP)MpRk)E z);AY%Z*vj%DG_WG-9w79LR;J%nHxnc_ z1K)1YF=8%i+tC_MTlilG?PYu;eh;rSOqGrTKa8&fKESBwTQS2jGH^M@f9ata%!>7d z^v1g-P5G`ilw7g`S@Mufe)FVCCfX>_$ldn^Xb@&*S%l;XD$9{TGP6zxjeMT=c@pz5 zzx)!#Y$cr_C%VkJK|K$BTm&~=JgF|wYNdvP|Zy+045p%pv#82bve)A(j)psn7- z2`%0usxgRMX$?OP+zC3~V9z49qjz3q(s}|Qa8iZAv{T8GIbBx*e+OG%F0VmP;cDWCTxci2cL4%R;IhZpr*k~DKQ2Tt; z;vZx2r~~O5TLq!htx10+p)tss3>kDmYxe@_fs^j|#u1l01(aN1{qY_B9uSfs*n>z* z)a~*)u?ktVv5?F#D&V z(*3QeB>XTCS~|=n;l$(TqA92Hq7&rX`_&;B`C?!Zqk0F1@3O@?2J z<9HhO`Spxr3gg#Xv7oTQD>`Z22= za*5POk@_-ggd&Ypq#n$g2om+VVv}UfN?Lywl!^rE(^OmZHzKT)%yocM5+RHXdjYj&Hqh{BoPGX zx5glit`fpf9N7u7C>u?o<4lf3aM0C7_ZA%Hs(@L$AeF92#`vfK3T@FtBpF!=9f!vIf<@j0;AvaxNoKq_FV2%$#q6;m@=l+uhoY1wH^(UN=b_pnkymc|Su7Vh< zgmpSjC^4@o(RxrNj+eBt+F)k=K(WngVsrdWu|eEA6hRjP*4J@DeeW(atL%G0D(_~M zmz+5pH0pfx7!f*YnQ#_GA{1-5o|ur?7)->{hG#5tT6zsUFX5X`tE(@-pfSwE>|2ZD z-W=HQ8Bk9k`9pl;D8ao8lplf7TeW46C$nXN*E9s$58b1ZS?^Tcd}Q+^Ee{T>x_O~W zAmulKMpO4PNgJ!>(db21eM&J0(FTA2P>2NNc^d~Z%oa0`G|UOmz6R~pX0lI#M(uI1 z8SPmm_HRuzM>S}&htSwc7q*TMaYEON>`Hd-&a6)< zQl27Zv!ES{L>%apRs%ZGif4|=LSr+HNm%#vKnh&}-=tD#6+YHKsN^A$E}Az65*Z>n znbo7`d(;GE&aTjonq{A)QG*y*|A0si`d5?KwAQ%-31pzN%_PhLjT$5fo!^v79dj6d z(y5qLQ7q|RtcEVNxQoHqc{bB7wa6uPJNmf;kb$&oS6(tL0)ttP6iiE(S>(O=lx0kt zXr7waPQ)dzor19|7w1Vc+hIW}+|kg5#Fq%U7&XP0haPMO8DWx`y^ z?}xp#8-$O>iXI<8TJXYTQ0@>R@}5hN(*e@UBElq{50L8oTy7MdvXE(=Ea9|zVtIu0 zQV2_0h!Nu$cb6*#kMU;pKgMPKgZIHfv{PK(a3uv#^JWTu&833DLD673XEL#*tZ>F2 z;qEt;*hhG?dOyO=ddusLObF+|4JW?Qx_87*GeF0v%c0$CDTj7R7<^PlHA_nhvouCA`GuCA``KKBouG%$HB z#C=mLxO+Qv&HOGXWJKSDyPyz(zsJj+xQi+PMK1(}?v8FsBJE1A4Yfssn&p^4{39?# zf+|3rRDqB}Np_QfZ0S8&ZgUam3ZM)+4r;%+(bj%6wT-p^N0k45+_SH)By=~O%iluy ztBm70!O_$JYyaN}^H`a*!&)HGcBtHgL2^PHbrEJ)3vgF{a0PeJh%~H4cscI6Av2Yd zF42n6PTU)zn$T@A>NOylUz9kJT1?k?HxfH>2hB*l7A3t80IXj$y)U{LDK$vRi`7{_ zeJ^F26qWaxrRFzfJ+rq2BnvJ1CP0z`{dbPNl+`KFB78`>bNy(#hX ze>6hZn-X7vqU%lVh|qn}LC3J5t2AZI-cSS1UZm~*LWJ(3R4u6!f{L2*31V0E<)js6e9|C@0X zr0&!p1*td#YZkY|nqV19V&i=oWuaZ&#@qi_H(oUxk83EvGCMN-R&e-Rx*z?qHYI*e z0GT^+d#66s0<(dhirUmVPA*>p>dwJEo994kQ(Nid*pF}bZ)eQjZ=q2B77**P{aHU`>kSE6D#8?n)kfY)*-Dkg3^p?Owg81j zQekbxlmH1_6Y5VU$k5+OvtbjGxsr6PlWctGtUX~_3$J-3~zPRzVSibl?T1j744WPjC(w z#&SLzfZnM^lowwZrV&LuA!KBjuie_)XBIuY(HNS87!xH^eF*a#Zyn#gedX*Hzwx%Q zTX+|kSy|L$DgTe-IbBI%Ui2aq$Sh)X!~6WU}^4m zdSc9Vpu9b}3jwFo3l`3KhFSD)_<4)uRZ)CB@(Q2c;)#7pQQQeKIhhLk_w~>dg8wdW zIqNwH+&SE$yYKQgv7Y~c@au4&eFHLHgbdJ&cYBote-zQ5#J#qs13eU2J^9Vx?QU;z zEnqv3Af+oz_M_zcC83Z){Z>-1mIfC%b|Y7$17V<;qV-57291Rqf+Z0Y5wRNrOk}{b zK8d9R;KFNlt&jMXC+`dE`&zG#GWT^5|IfJbbt-7Dn><--A~>tyoq8q&zscJ~@LvM- zIRU4i{!BLmT69joHSa9A#-+ibNj@wSjl8&KslS?#6o!SrCiE;JKd z>wZ=UzF(QT8=yM`{2g=P81?4K0lEnL;Sjt-u@3^YPrwI#jJ4ie`Cv)}en$wtOZCqU z0KHzoKROH3Zm)u$RN+;N+dJj$wX~n_iEa2cfZl^!Mv=Kl{L73H6Z%dft zHRvDf5;-0WbF7P+_2p16>%2ztf@R!S4l*T&bmCLbggI7tGVDWio;!;m^<*}3T(CHc z@!u;Y0la48#%NfAR8j$zClT*zx7;oBRuJ?H;OwVx&u)Trmw7duK>ruQzr;O2mBs-Q z>ZMZE%c5ee(cu>L!emb@Jc@UvxA;CFFQ9r^2aq#yi<%*rAA#L30Ouf)3m2lPRoxV> z0vweJydzJ5!`_n_?_YqhhGVz)q$~w?^UU%0#OUm%Z{pwQ^ANG=xfA|{FEFR}vtnS` z@4;~T!dk9mw*Wx{?#)ak18~?IK!dRa>q_oTNb}4QV?YN|9mhe3A zL8Io+5>f@PbEF%L;Jj}73{T8HI)I8%F0^r~;7m0ugIZ+a7J;lJV8P+j`0HRAm_I;d zupKYlY_Qd4n}mi(CpO%Xkf-4>LA(cD-n%jqy9WT~oqFd5#vGucnh>|f8&SuP2SXUux8{p5yUBFF%eR#P9_gVr&Y;o}yd@$G>@+9*R?3Dm{Ir9*~ZFspAcfi)- zHoPkU2DZ^a4lwqJgW)=f(}l|Qh~qB4*CpU6Z*)YwBLPR@<0in5#c)N97LFQY67K;y zz!}bW6F_W|(5pe9b>iH^%XZw}sk`@s^6vl>Px1X7?zK#hTa5L9NA0>0?Ee7dYq*Q3 z!CpkhE^+7Un_1LMW04V$)hi%*;F068T1N*cukEIGKT-O>;V$?G1XiO- zPshEM!1+|et=Jgm=>bR=ZpqV!mmKatSB1X6u?mN0t^z%^ytd=^PGt{*f^CSp38h~{ za@r7h6fgXY&{_iLR{@UJAk6b~fcz}X^GCeAfcwu?;qt$+3Oi@6f|y1izaI+UJ9SMT zsQyShR3t`@1-M&2i$Kd$_!%PPH(1dpGgkm?2f?ZsQ9_sp0sMB{>j|5>qj?MMF-m%1 zeu&>67B(FM>XnFm5>WgWY{5bVeukG}HIe=AKb2&sBUzq{D;$&nex}(_?J%ZR!t{t=BQAc$GlGm22QOFZ` z@#ODR|5S3tB`EU_M6Ln_%SqBr2yDa4R@_y;0%*y-h-pV?7w(dGBX9*?1{wG;0-1l|o4@4y{w4|GMa5-H@+7E`zbQCv7I2BgwDPIFKCNizqH*-fN>k$6FCaI?PTk z-^~H}i!K8B9?aLzfb>t0{AU4^L5bgrN@OLl4*$H({G3gI`U?tXDR2SMC~FAZWQt0W zz>-uNP#~8Om!iP!7o)(RA@DU6_Ep@4YcSpjPwMc(I&=s!vOU;`C@vZwR{Y#M({H1u zY!o)ijN7Q2Z4|cC+=3|b@{~rg&4M=}jy3yG6h~qK{B|Ue*vD-GYxXeW*g)TjfK5QB zIvM{9iG!)1HNh7VM+(!Z7b;5%ziy)z*eFm)k2s;$+NkqP(QgpNmW|nl^mDm}x*WV~ zMYBYX>?MHx$sfMv9iHaHba$7WFtIn zGn}2s@H@oGW`Pt$Otud!!HdLH+nA!q@RIC+W(yaRF9dBV>?1Sg_a(2n465PPi2N;B z^-J6Z*CMcZE_`&js|Zx`2E^<^s1^6Q4zOYXUZ3XU|gOxWSU%`IFz6)Ud?%9r31ge<2z7KE6RK&Hl z_o2Ng$hw0N&2Nf^5zQ8$KsF)`pdgAnWgkFFBR~dGqmnlv;=@4vLEI(pLEtlZ`4j_> zAi&R?J;A^i5cnouzQ(}Q2t13IpWqgnp8!VBa9{0R!OBK5iZuTg$-l;3K$`t|0Kr{F zsEGEbka0Tg!KV?;0|onm%1Ttxj}Z5qR8u#+741L-bp`>bj!p0oP;;PppJvOSgZf49 zcZcsRa}|CRxein1|Fg~hvzfDh(9Pb&?7_1(*UHO;6t~cixVbK8uEJj-7f(F|+$2Mq z`)1Dmh@1Vjl6?(wiEsS`Uby-Add)5q+@B$iyQk4O+>SPePM;EQXUZ$Nq8IH^huBiI z#cbRKs}Wd%mqlzG`b10G5z~xNBkqzz2z20OFYe%Gpdztlz(Tpo8_oTq3)0ST{y`EE zJcL}NXQk#MjlqWzN1d@H5%(10SeLd$99MV^obSsx^L(FRsdKK;xu9m+GFZVKV0D+(4<(mxjBhXoH%y!%X zzvf6i`9n(vwb*XNQBVGt#HpSfN1W(M?sTGNUwAkY(BKxtQ6sNU#NCcK)^EFwBX91t zdAk#EZ$%un{?SAn_eoI~Uz3P?#NxX>##i_l;zSqo>=!e3mk7gQjCThOe<%W~W$%()9M%?uF3MR+-c zJJ6 zx51vX)WT~QqAk`KzjR44)NTo0&MSUN@wvsVTW&*Z&^`h2t1uoAo7L~7T*}fxTE&?De2QmV2I7aYYrFRRhqKtXgaN zrbYbT1OBL`xcK~HzZ6rZYEWU@W%Z&g{GcFYHL6U;*eb7yc#DXbw`T%n0&4A2Z)16< z_tD0HR3EJJ4h08_iEUjq5|TApFU<}*Hbhx^79=uMQ;J^UEuuu>lSftpz;Ucjl_OZc z2-{1FJ)$K3I-$d9wX>vNQUy|+6-qW0OZCnslbCZe<<=H-j;*uw1q>bzX~kNXbBk?V znEgEI8&w4%pI(ySQ!KCb`9g(iZ;fy#I0ZF%wg@(SVqk04GW5zSv>3Vqnr}Ogv@}eU z58Gaiwz8ldZ75Z3(suQUWr1*@$|udu$}EYmBu87=7%&~#ondvbe#)F(BA-DlxvldJ z5n)_QN+Qf_8p{ z8+mZ1;sQ1V{*(f`57KZU8$f8gXs&lgX*s&(X{9|2=6Yr5$QRq5iZSpKs9s3Ir3+%U zAuXL-g=$^4AWzBQBX4o9*#^Z4BNj!OKE_iEU35A(MTy(khzRQqjkk0hzptwgAu+Fu`j*kbnk-n z=@)z5j0zJf5m$M!cffe^*Ap1q;DL>kQ^=QESQPEZyH67J$D*zRNYz);UU&K{>93{{ z_-gv;bRq{rKSC-dE(Uf*=7Y$bHnrGnz4;~&zi;wC=%Y-enhed1wDHqpzccrx{oB0s zBwnPj42F6n6$5?owIPY$khoNO4Bxm+&#ROt>fw8WtQNm%e5$JUzI4$E?@;>0wdt$O z>G!3tz0*sd#EVJ!ekz3uXDnp8$an&KFn!{bH*0(S$`kmiY5J7+s8@o()u!;-m4&}r zb=rM!Mge!2uT%4NURrtF%-dL5v2KlLD$7rp?JKvhTDE1?ed(KkfHh=cCZp%rcA@6G z#!;K`YmfxKn9OBDZ>nT0f#tq*YF^3J$q0p=6xfUdn^|0vB;h_2cm*tOHh6%q80b5S zOZf$zh%RL`nqA&WpkF{547TwAID+u)J0LO&QNfIXeb^mV$!S4XE zFJJZwQ2&A-%(9U{U^0+jG}A3{UH%u`^*4nq@8%S`PyUs8RtrQ0(*<5v`qIOs?{GiD{i6uq2~C(;f-dD??8#s07k@EuD&n*aPZ+kU$uw)L_j|7p|`ymNlDhdAW09B@H>OM z$+o+LQvpgm6}%lGEkk~7$1Ouz*zdLCMqS7wdC6#-xAJYjl48Zl+5wy0_h1CxJ8H=1k?0OyqP9kF^@w3SGy zT!X%`W*y$vP1*toV<9R)OvM_o2oM(#B4)jXm>LqLUB@k((bD250vP7a>S8 zr6RN0E?8pTpI%ezAHVLtbnPywC|BT3v#__I8Lt(QEFlomG8;6`&L&k|7VFRHb3~=5$B{v83(_PQY3J22sEGU|E2Pmv%#{m~XW`;MlShQRGy#B8N#(pmlx=5Qit6K10F}-|BMT8WNf=O& z%o&l07YihcH3^h15Pgs|Khg`uk`aNnb%`)pG{TMT;N|w_M1kq%9n*O^AMH1PJH%H( zLx~0`g)bsZ^c57PTaxsZ8CW!(2M^yQiP?uJs6qqgGV$pJ2q|KT^ zTxNEnPC}1OoKeI=&i>C6rOafT{J$)d*)7FV#bs!xWm!}#TRWYAbmBdMNyO3Zv`m*PS&1x)%dQ6M)w}SvYY*P` z^ykx9KzK0I=H|m%yVB2u4QC+V8J7XWWw%f{f~*m5G63)00qPz8kvnP9vE zN*cx(n8Wr}jU>%(b4$Y{m00@ESPr0*wH3BlBJlX1UMim+K{utAcgOQVpM znHnWT{{L&zVj`1omLKOqNY6WtHa-4QyuDPc?2mg-pfjeQ@P5S^?yu6nrF{K1{S%np z`1vXA>z@Xf1S&cNLbxU7FiGmOI(kmwaF<-PwFk52-|U^16liK38-A_}lP zgY2_YfD7LxlQf}DG;S9(=~J`bUSg99m{6${;w_`IjWJA~@0|5yAs%<(pJu&7+Bu&W z@{YoEzGc=QXGar^%t{oIHk-YR(%;BDP>9FB6h2+-VHw{PydBkE=wVL-t_+Wirtuj_ zOyADiANIk_Hzaly%6cI6L`t*qqyEhi#40RHAs-O0*^P9Xni;N5r*Sk{`14fi4Zc(; zv_hpg1;K=_JAHTR9xC^HQui|SRO)sgkK6s%QC+>xe*;3uQGkDjHaomdtt^+Q)7S#v zogTr|uv=&08d(Vrj9@yqpT(FAmrL=lS3q_6sOb9wt~8TB=t*2dM&E}WE3sDf6g-0H zK$Ka*r|}BAf&_52H!Jyo_GttZZKhn7m`%ZV5j6|BfQ+E@bg&G*qb5|6T#_7jSdn35 z8msx;=?gCbm6r_TZFm%KqvKlf+X2w2oWC2doDcye>&7KO7^}kNRliYgKVSH(B3ncO z)2)D;Of9D1Y4c&UVfx|14;BF-WiPxkn2G__@F4|UfCA8K z)ReT?_@Er^OV{;-@BQO=8^4Xy`P+bC`e;LVtDS0rx3(Xn5;9#NnR=p3(eOifTz32w z1>cA)jr)*g-{r~a^m2gNiHFz)`#=dG;HSftSu3dv(EtnWa9pq(QSiT+r_qcm4;%^f zg40tjS}44z+IY>=hk3w0E9{fAabC0aA=^UuDpj4~S!?0kbU1V6a^u5rm>xdE`0yE) zA3hgbd^_wjq@TW3URn7?-?Yy#Jrfn+$W_gxI&3d`sFzXLY(9S6*pHYqrw4F8i9?Fa1#JUs5KpPBpsJ#G!`$AA)0Edf}UpY~7*h z_KUez%IxWMQ5mMQ>B@!aWy{km*G`W&!9jrpd6{%UDS;O+N#hSWW{NjKos{=Xkp6z~ zFsh)zl^iHd@Pwq@?#U=BC<~u5h@)*zpD* zpNf-er_yDO>1#iYJvUZn(pyEv;Ca1h&7(@1(?^C%?*-i{6FCJ*JsU5a;$`RsbGL%ah$IOY8pmddH_P%dt7V!W?rcs0W zo~o(t8yz_^G+5I#ic)(f2F7a!her?h4tGtCj`t1@)JzNw9v+>Xs2&?1od9(clfA>k zH4JQ+9336*JK8%mvSD~=Wa>ms@A$C|Bcme&8wPq04@DI@*4uY>Xjz%bp}s3-fctCE{{`NLtO~*S411CEsy;}n^fe@mPV^4{ z56Fn|{0*7Wx}#H*6Mton8NebYMqK)fGNWpu=J3?e@Ff0iWV+aesK}u|ll<2-*ThwS z20>VPGkiQJ^{DQnZbWEea(rlHu=*&CKLl|A4pAqE2Xcc0BZ!49o{ZI)T>rq4-l^fq z+~mozfeFOHjzF&dp^-@hFu>v+Ab7{{itHg66t_h-Ha>K`cX9v_(AbEx-7go%mfH7zb%;En) z5>Q%B@A!D{$!TDSm?Qayhw-ZQ8yp{<8be4~*E>GY8)aiVB2X4n6D0}7QApe9sL|Sx z!UREDnc-2k8uqP$>b}w8(eWrWbPOX(4xe#Cj8Zo`k>iko@H~ZQA537xjssv(ApsEV zT?9o85W;>EgpRPC_0={O!f=Wqi83=b%JfKDqW8(+3CaO>Y7hscJa^<6ywUr1RwqnGHT;Fi-M9i9F0~9rMH8=*0nB&HOa<&%)pm2V$BI6f&LG78r+AYD^{@iS^ z!atD>YS#tpYlF4^$!egj3D%+nqPNfTiVEaoR84uXK2vUCQWca?9eDnC zXL~6x56Lf#aFA6vtqNSO3G-&E5gG~>1A72Mgf#wScH=iurBoKjDQ#UU@ehC%{vMK$ z*$q&C6X;)*nY-d#;J65HUa&wAA-G)lT~)JkNtM+5G{jYv+Y6Ph2&(+6vq83w#k1+F zQ}gpEzaPASsIdBFRoP(H+@LhGjO|~>x)uTfUz{epU3ktGLk_a0Dp&{vo?o~d0Tx*5 zzventASf-f$g;%d{}POvgGQ;53?-R8!QAQS;cX*L6x2)}v2W1?63ePDgoMpKoi*0t zw>quz?tJhHl33-yz;_hZpLi-~g867Zj8xUd^GSuF1k4g)$y8^i$h*K>2?{r`p4n7E zUUj~h#Jijj)9L%)e+A6fXMm}3>iL}+VB9)<|F3}g&wQ9AGtvBfJ`4rcbLsj0UjcKy zpVu}s^5>=`%!}~wwfQjUjOfKKL2pR{Rf#h3_Bc#@r@~aRLZ@egsw(MK)Ob~4hpf^L zsX?zQo7dnEY5uU^c&AfVf=q2t4iwNDnJhJ(m(6S)JOuII69gNk6Z)~3P*DTuY?29o zB?twgiciG2)}j8McDwG{xJ^BMy|rlp#a-~ zS>j67k@HR`tb^;Dii;``Oi$%8lZE%P> zwi;g$0sqbmycG@+&%J1#tmauZJJoNu z9_~tlairQNN{FPQ2}0XJN6{LTyf`TFPoQPM3~IKLOl>9$5%MxCf|7L@TeD8{J|v~g z2S901us!gW1O+Sc-99PoTt2`ue`yv4`vcX2GT0i-IU^|J5Q6^DCVG9&-eBQ61Xl!e zP$ILspm3l45e<^5W)&)usX$zcAqwdnT}4#=iR$uTndI0e!oQp;;8h81mTIW) z1sF|E=PySmmUt!rQkiw~n{^uaUNxPhN0$?#3YsC9Z`Fas)PpFM(((*MdO-nnOD?<3ILN&|HBUz|#C^+CyaEfAOXD*=)8N74Scflm+Nj#T#M4%@+HzLbL;< zx?E@p&0Xq9&_;QuPMBYvSMD8RXogKd@-2(VC_i&AeP;zg?=82KOK{lqUs}HT^5#DjkH}cORY!La_F(`WP_+XiT2Nj20#Tklc~VO z=5&OrP}E}7X33#gr_=`)3TGaNr? zhk`}(C8991S}b}Fra@(}h{%yHBl~F@?r;LQ4P|3emGRH754L2yn$xR-)6{G($SlIA_fKYn_S)byrLrC93(g1z&kWY6 z=3>NPwT6}pe}c?Wp#qbwZKSt45HTlbYl4*k=aeU!eAb99RVchy3E`Mor{wdsHm@qg zk@4T8YDigT6+X4Q4m{M93q0vSkRoN)L8NZ406Hja%z3L$4^{(tHD`o{HTVcE=xjym za!_7QP*SxuD8#gpV~Ztnd9a*}ss$hhgAL3%YlCJcr5n)=fS=us1H<|~L7`t~dC8_L%$zSs&k+Wx^2i1|5kgOBW@NR9V&QfHYhldp zK()9?EJxzAHS<|~WCI!fvykl?F)ZhzvS$EjE++rf4kEy;&dM1vZk2&}t73eKgK?|H zxGjN+AfVCz$GO4`IKjegiGeIV0ghpdA zJs6wStggbVC>iA17Mz9DjWxk4za$&1_K#c3XlwGnA-r`1qh8`cA6b~f0+c0%#x zVy~fp!zZzhY7>lFjcF@$oNZ%jMZ%fFmS#No4Av6CHXr*Bf?$5E6?Q{tR$4W_N2njn z24dkr05|Fz&Dj;U&qD#B++r%3nwn(gA^O#rSkRO$$@ot|RM@=ADY9=jqc8L-k{o1w zJzCda38U(<_O&c~d40y6*WF!2y(~?|`PLqM zqDtho37t37CZ?c96z|btSLQGxuxOmT+9T{pYOND?)1?E_l&us33SkEleNC_n)hNuu zz~n?KF)pnJWEHy%B~txos{s)}NpOx>CQXZxSEo$U-|GXKrf69z3+RmPS{+VHf^D%H zh8L_tHL+DVXqPg0hDZoXqgJ#Xl}34%-1gh*DSnBTgb%GecnP}HoMm8nRj>xRF~-d- zYuc{6k=l^gRzO@>4;K|0ylg|T5OW81Nmyrd%hP_az<>R5R5&z>1~VQF5Z1~6QK1Kb z#r|uKXQQ}ZL&ZZF(rIM;^i|9#I39y8QXGw#ORUoQ1iBU0*Zq%T+X|7Q$9%E?G06G( znQ~^4w9Nm2S1pBp`Pyn5&eq!q6p@*Z^B-Xda1dNvn++DNM=3RIxpL|kBFOk(x~je& z#jo@q0pucfr#k6G(&y>}4g|32P${s8jlW=huzLB1D#UQ2Sr*K##YAT{8lbj1b6*g= zJ}6W>4C>B*T*ghYqjY?faQW6fhX(iT*>j;Zx6F}c#FozapdF7q8qTQEne1zh;s2x< zZ?J4I6&2%ZRuyHEB2|)^AIza{+bDe$bI4lubxs~RRRb{}E*av3BL5TDJt+N>g`@52FwxnNi~xeo zncHEj`*o_H>3M+)hF}-(_J54Fh3K(k%P5TzARCU?Fh*<~D^!otD}%-BgG!oSHQ_YC zK5Ik2!TFr|sUDB#lANoPw}s#_btuEsjkCAulx!Uad!|cq^vdpGW6{}DR;y+uyu7f6 z=J{VWuMkZ-7kU8>3K?Pk{%X&E8{Hojl0@sZnr@H<%Y!PKOH~}A@KmEVbcUP*Q%si| zRwGqINtgwqV>l+m2qCO$Ms^Rd2;9a15@e2xrdtHdS-Hwq2;M7^3KaxznhE3~U;v`( z;G!zE3^xRITM@SvlLiO@D(-(QfScX_yf_!CB#vw+Q|8mSgm&{kXs1Wy9qXx2PQEKb zJD#l(`h%clsSGmytFDHgfIrCpJ<8D7h5ijNDI!e<(+dC)))!EONNY{7?ew4v;8nrE z>A?sTnPinU1OL;=%fh2EL!;?}Tq*?A@L50)i2p|P@*Rk*+K4|?f+#KxvbDhu_H&E} zm(_g=ii7TLehVCG9;bV+UCCs)KmBV9xFep^`tI00T1iK zTC5BPmIQN&VmaM`L>1KPGgF<-_#YxSHqz6Q@!x%o=Zo`C2eKFKC^~fpD*v6=Kslf- zx1sH6z}G@0RZw)WID*df6~Es02h$Obn)EN2`_G*+%VH{?%}Rou%(*X3k*V`N3j#3RQr%Dwxl4*@?0xb2_qRg&1?N zXXpCcc4xM3_2E29*f7v1k6fp2FaT5o0Lv)NS;7aF9)D=?GQ|f`j!zlOm|%BO5GTuFDXbkxD`*KronRKnc?|A$zPU6jX45 zVw{WF%>0UkEe;<=4dt2BDv{^<%wR@_3M@6Vs73ylO?^<~-vR{X^yV*v6CWu03 zTRkGOkU2;?&$^?a#1ZaiNo%H-KArt2H){wx!aYqoq8;e-D7&u}q zqXq1jp#S@m6x8K3zDvqIZ$2&L1y&*H_$vKeRa>w<_7!kwq3t$boh8-55?X({yi_BE z1M$Wrd{JhX4506~mO4aqL%r;MU?m$_4_bIuMj?Y7`@%7vc5|NaAa~Pl=~oTRNdXfN z6fK2@P)7*|rzseieI!ua7SijfU{vSt5sivn7*cB)W!NOn64e)E9s!?p{xabAWxon0 z2y7&8Nj6xh`xUGYQPyr?o2(V?P+e>dHUJXlAlmIDYOojvjd&}p=Lr54RT1bIOLuMV#5aENgJVCn~>PH zKi9IqrM)}1zoD(CCD*j8p?zmdvpH%vb}_T;Btzcu$z0!I#ix6juIe3{%#9BW5A;q9 z5K&k6p|+M>Tf?D_o^B&M+QLnLOx@FRD2IQE$mNbqjr8SmjB4s=>*&nw=;++r(4A}D zR98DwWF2X+o2Mp6$FSjQv~OTy0viwwHVh;mV? zYzHKj&7BPga@`GGdve`}_O;|1J35N&|E_!WZ)p{LTU$O&*SjW1oqdN@qsb$D%Xc?rAXq| zw4=QfDmBF11+rSuT1`D&Y)rQ>BzJZ*qt<=W=vKGfOAjgF4@PcUCp)s}X! zEw{I$8Hjt@+G3o08#?#2H0PRI+FH6>+jkN#XqNq>Ms_Y@W8nC)USXWd9dhh!ZO?VK z?%dUF`o|$D$#_K^aW!odOE z#43mzns&A1I$OG0I`^aZbhJ0;I`$A$wtj-AQ7)B3gPnbox!%6Xq2oi7CsmqyM+S!z z{byf8GwJQw+b(#xjdKDe_M@Lcj%|gs%H1soyTPKSj!x6pJJ#C=lqQnks21Iw4eed* zWVu}}!W^VPAcg6j%`8Nvfc4`4ct#|%*eM)4$o2P5_JXC@R%z2U!^FTyzo9U1+{~KF zUTN^?IQrDoNPlh&4K;!-%u@qsx?XJb9W(>Itk>LGS_q9gVwl z`#M^oS!4e1XlvM+Yi-}((%D6!Y3k|hYTe(Gr~##2!nS>*mh0Nnav*mwQE-0BA)}&6 z-I(O&*eF^Dn^t>ACfHr9QXUpXp+$5yG`IG2X~nf`MqCud*4^2P5ut5Hq7Jk+ckeRL zi$?~=$03>`A=0si`txM>I8L)bje;wxojSGKtHy9+J6jr>MY$+}ZLRGsIW6f}?}^;R z(A9~)vbW)&O#>FlG&*9gt)mH=!;Bq0IWg4NJDiJ@cqr%N1II>>4~X_UX;S5pHt#>`D5NrxhqXjhK=89N>& zo_!l#AR3IW8tTUwH8~0uJU-Mvz+{4|N>fg@wKPD0VlB@6wj-jeqDGSgkrLD#GH~td z=z@+!uU39SNY1JQFbAX~6CeOe+-fS&MVw?5%eEb46xP5=sHKsKA=P9;w;pW}IJ?t_ zpX1@U==G?b5^~eJw_&GrZLw@vpXr6~N4e10Y^h;kmMFT3ldy`o@n6Q}c%+fBVnFy{ z+d3+$2m?({ zNASGv*VWY70m0V86UwznDx!hdHXFMSMl|i-qQ;P5C4hEoEcpp}YHMlV2^|}?BrKAh zP}xdwUbU4JkyhXh&&IG&C_tQ(fF{IvHaa|&ufXD3N(nN^F;!xWz7aJXb)hQO*Dm1}CfG|UGced>4%!#eX!MUsT z!WI@Fl4d7zLnB87a3H! z3G}Oh9EQT)BLjw0vSXNZzy{+;K7=TasG>Y%#E5&4&J1z2tSOBax7#=z{l<3(FolQ9oj8iZk z21f?^vpA?cZgdQp7&?P7tC_;7iRvt5RX|&%T&|aAo*`{R z$4PKBz+m3iv`5q>V)OKWgN!HnQ6l>JQJaV^KWd8^Q)8Pohz0_Ninz|?q}T@^M{7fyPKH_a90tL0nkFO}qxlHB zsmiOJd&O1ZWKy~$AVoN=rHY_!FCP0t=12&nUx_)Tz9n)NZXlUu67Tc@5TjGfqda5O zjAIHuHDRY~10#I{;48m35V2Ij*)>BwK;xOz@uX-{DG7;rqTddWRdOcViJ5Ez%q=r9 zFmMH10i+N0t5<|2LX(R_3{&8ErgjviKng{VhMh(S4?Av5QcLNSC3H$oiu_NL6%-fO z0*0(1+dzgiS!k_D3!(KmYc>NXFbx!Op{o=x5nrgVq_T|4t2IaChPHjX8ccF#=*%@l zFCwS*VVI#Xxtd^$8rrj}v?%1Uz(xhjV8r(5g_opvc&JyLo@fyCYKW4V0K+gk$Y_r# z;y~{e@VJC7HWl=)T@B6fnJD?OpaB-1;Bc6=!zvwD^iCb6NW-!NxO8PJl{)XV)# zCvWY%6TCtX4X2&-|KJ9>m|vm{IW-Iri*0BkHvn@>hMTCOq7!z)xf4Q3uNPlTJk&;} zAhJbTT&><*OIt%%cWVC(k*^*Y zmw9q1Ha##QcI5W9?3HSuX7t2Msmu_Wwj7Nj7iQ=J2Y|AK$`PfiYlLrLZm1;SEsCoz z{-EXtdbh>>1UMD-aB9R3(~nODpq0dL2>_?1(V^q&QPjk?0vzoeTbQjJoOLCCUXj}ck3c7UB5GbY z!SmFe9QvCY+MD3yK&g36+&bMVP}G(j8zH7Xm<{0J-k3BvWl?+iWwRW^%9GyKPO92 z!mRMK0y>!H`i92)Fe1^_28TaH9}T2jlU~|J%g%KPN~CpgGF=Q&oieJ@U{|mvkFK47 zGL;&2=|yE6M90UZAPOG>#hjG0`P5}dMuuz{hqoSmg0c=mBi50{W4&=eR7$BA2PQ79pBJqjzDktGfk`O=OA9gJh$GDnizCgl@aymRN>DUErUaPE0%y z>6|a-jWg{N7pmoQL~<7@*c~}MnPa1vInr4pmh1%eJ@9%p_B7J#h}^ad(g&_%_~?-% zl#dg}zMKS)*{(EUowdEh5F~wwJYl`Up2b-rzHXD_>Yp72Wc>g(5*7!o1XAsTjy$c? zhItOHdPq}ZaFFFiN}hb-!uHj0AY`K^m9iKb(2b;lidq&Yrxk?p6i%XsEpgLBXj)p@ zp=;p-gQ|oJ*cPXgOo}mws8KjBvEV_Q1dF-3D-zaRV{7-`hJ9Gqg9o?^13|=O2uExI zhrE+viB__XQo3@Y;ue}7IylMD(Ix1jc|*94d#-3YJEG8e(Yklvw7T}R?`iKikZ{^! z5k0Z?K{F34noxtv`^uts@!|Rm;FsCU$mev0W8~ zhz9$!T@eeH%3VTQ+S({BSiZ#aS657eRZUt1Hf`A>jwQXcXmStlav`IUe?T8WLm`s!M8nSyAR~L2su|j2MoEA)WH-wXK zFo;c_uk{kr359O8Do4en`c^v{W9Z;epZbUReK}QAktVRhwYOt0_Ga|#)j{uy0rAEp z1{h3zJK9w?Z4Y+*lR12|2Vd=qN9NGMG=kMrb$BLM1G)CBjvmxct1Z6A&Xx;$s9DkJ zxp4tC(m_I&*+sd?JemU!JR8UO9VIboWsR2|@d&iTgzUFK-nfB7r&eT$VA?P!e#!hI zbR{1pYd7R?PM40w+c!Ffg)G^iGCGo@MwA^PPzBOoGzFxMVT%OEf7C5cpNTh`F8`>~ zw0S}u2UCtTg&I%BR=6(@PaQstkLzI*3dcwKUxmw2O~e*xn!Y`trLz-bo%RMyNkhxs zF;N>k4(4?37WXeGDB8Ag@x@gI#q6itpAZqBSGQ1Jr@2b$iBO@_c5dpxva}i_Ix5hDUj z)%`0k!qc{fMm3==C9-8lSQ`0kt#(3vImM1yY6oW7aKzZCeE5*y`M~~^xPpo{nw%s& zq%G}D*yz%UDdoUGVhy>yXK%iJ-DPH2`31u$&DvyI1J(RgxCia7h>?M-#D>ygS?BPf z{ii)tdZhGNP^`4+lq2%kMDgN+lo3FzDcK|hU+u^s@B%1L%ntP&5>tl42sw&5hdDF` z1KG|LiehL#S>Jhrb>Rry-O6Rbh^3gX*`b*OHWz3p2G%o#Hvp;(CpPd{p;k-LZfXlz zh!1&!li0IHA+(Fuq5cAY(Y@eRib{{U%<-XXUxQ3fuuP7@5YVd3pjD`26Dy&4>}hC& zc8UBRp?i(C6?26&h+?%O7+L9d^&ldLDw^H>2tE&p-7m~(z$w6pzKYMmbGS6xI0WGUmQj?X;$o{f)b7;;mv)1Il)daDiDWK^raU`P9a-K1YsK(>|kH z6IK)7k_=x#s#+yuk;bRtg=94{LhYPnQqr0vBtC2iH!d1C2iFrfsVXmZK4a%9;+Fxe z^lyNG5j5d;!N!U?Dn3{2!h-jOeI4r);2}KMI#6@kVq&B9@YICe!w0l9LIkPm(_QRZ z;3_>`vbhEzN))+vcnS;E(c;LF32wPj%Y+(~n`I(q$^6(${0o*{y(LwzJLH(a{|E5+zAge#s;!&ce|r+zE!ADwuA=SdQ9{u&IZSY)=-%zWJz zS1PiJw2sk)8xEJ`cBwoq(gj)@nqg$4W-z_;j2O7TurNjZ)27@qm~;J)+I6y zW;b+9WH;cmxLXHDrs_^)Hyq*4dG3bU08l=We1s!qGCVbM6~uUhtguLDab_0c_)sT^ z$dGnRQC#_&UI%f}_jyJ>y`wY{;&v6CDa=l|uyvmm6ks@@iV{%ULbq0M-STjXLuYI3P18hP?^$w>oQm&}{rTTNwWb~9+a_7?1B+uz!R zO#;xDnB+%Ttv4KEiy2sQXAk$Z$ID0iTKB^j<+`V3qqruClbSlY5gYw5EsizGwiS4PX!)UtNK=Kg3B%JF&_x|uE?Ygfuhbkc~W3J5hY zIMXG(OnqR^NxSEC2QDdV$F8V6I+7ceSY4XSs_pd*2RE%M#&Bc(aqK=pO;irz)uo*c zvgJRq9hQzt4qq{JLpyjM<&8&WP88_;Ld~caDQTz!*}y#@!h^(6V|_G{#D>-@BAmWU z>g=c!ZY02Xf&nZq1#hl8Dmw|_nCTrFHdl>ffr%U>@bLFG8!b@^cybr&%nMz zb~ZZ$12`ng3{bb|fruG&fVF|+q7$cK?C_-wu|^%nGP~-jW=S5(1hT|b9uqR@+7jtvv28i0T>obyZ;^nsN*;A1W4Ahr1Q*L{L^@*hw1JD6~DQ*KoB9J`XLf_QclAH7h) zhM?_(lcKX7jK#_p?Q>2DrAqYMah1A%K$r7jdJm0^pnuC;Lxev%A(!8IbXklZMx7_K z&BB(V^vH6CRGZQZTRw89CZwma2PaX)ji91N4q9_6)P}K(E#^%qIh4F;dH{Dt|In!2 zwl9V=h9G#tlEV<4;9wasXbO!fI26N>KeoBCaya&{W%(WU`7Zu^`0LOGL{k7!EpleAXRT*aSg7 z${wVsUq^k2?lK@rdM0RSh686I*!FMkQt^%%ZNAwjH|rSgD1*0^hD~ zpBhnzziN-ey}HhypG-UDe#u-bzcAO^6LnaF}gO2I{bjEwV{b0cD+S zKxhmRH`z2J=S0Lw5bx#al5sDtxLq1nDG(;JmT={1eIO9nQ#=e^$_-D>DI3c5<>;lM zFRu3p7hzRHu>=tp3a@Y_=?Re@A^ZLETEMC<@tEtouFMV$Vo{j(j_Cf-5QwZlXz;K! z@nD@0F%G9waa}pL)<%vyIX!S-y^57+6rM)13vWn>I1~>?GY75&K{a|EhYz*~A zbHXUMBd8cfx|#`crcGDt&Z#xwwmb3Y@{dE3<%%~6hAdBeMfHi9$Hh;uNoC4T>5-l7 zMYj@?)SanfkDI*-j54uroPCICczJx(HbTtlqPCIB4HIG&O z+$WxY5C%1}J#p6oac&?&2XS@Bar=YLKSX`;ypVV%99~-=ezfC|!=9)BbS9b+GKshx z-av#!%##blI-^AWV@<3bf=6B>dcjW8J%%5#}+l?u_{@fQ9Z2ZA-FsnQELYbY~6x469-Ph6*84|JuGAWMalZ?YQ_24 z_E2aJ zn8O^cbxy~_NOtW{M&yV-3>&Djcs%nh-_VlE^SQ~Qf*fkIJJTnwz?KU!Fynqe-(Iv! zUPpG3qAcqrvnRspfiTtU>@x{ZqqS-%o2u2g&;p9{2KSyr`*9dK>DLf10k%(a&4=@A zQOPl{RX@<>%hk;>-E=Vtc3MuQRvtzhexAq z)ifjraqu{w)7F z4?e%TO=q6z`u^lEOaFumA7i|xbaqMf7p4Xm{{|I*2ozoXJJgj?NdKm@p>*L5soT6u zi%JU`pZZ*>X)JCi#eW6m<->n339c~f19-9dUPj<#8T`vp-r=<#FTlt$^5B>!nU8;I znhaq zt?ierH~%Wu%2ivD3hplZ%#-mu1+LIU z8IQUnIA=qH$rR0MDDVnXMgDAWUb+IG+gji+^cH!Gy(QkV^m1>dx7KUs-?Qdl$(XeH z#h;R?_!qKd5dYf7KT(S>pa0{QxP1I4A?wRrtY-@0Wr=kDUvCw{v2IA`rTWpIDr>Zl zKldYieBsaj5|?iZ9sGsTe^@@-IfZoQColEF9~>qwpMUk2xO`BbUtY5H_+Pi-pI2)p zAOG~1U%xq~2}vxUvYSFW@wMUBYmT|pzTqG809Q)T=<@l`f{Dw=KL_U1LroT6J~)|Q zeuWuAGLaH8mEbgU`TQ@z#O33^1oQFZzXcPQpC_%%zsMtNV%CpGaX5ZPDJu}a# zA8Q?7K6-0@`N`hT@|HQ}EfaX+)+@jEzR89O^7H|nk3T=;n-vcJ6#~B|!m=WI%%we9Q^B?^bHRF4NiKs6RvUa)i~)J9ef*| z^g1VemV@ssC;e;(-`P(3W+!}(gYO(C{agp%xlTG2V|@AMB@Vuq#EE$G%~mITzJvdK z$sg$P9aR6_=X>stiIO#hbd^?@= zT~4^w!Pn}f?{V<$anfVW#suH&b@1(V;5!_A9Zvc_Cwzf}?*b>i%fZ*>q<1^v9tU5K zlYYR#cfd(M=!6eB_zpSg7diMYa?)wR#FuX_aqwLdC*sXFIR{_PNx#eq_d57`o%B8j zU!RlCQ7pcEGvMGGh!gSVn?VQPpp$;o2@g5=IC{mGZ?16gT@feZ%{RkN_?Uz5n3F#0 z;2U+)$DHt$4!$d$^a%&wgp)qygpWJ;jyvfm9DFC7^sAllOC5YKb<$tv;Cq>qeytO} z&cSz`lm2oC-^-o!S2*EUI{04cq~GY^yU|I%$qB#8!S^aB{nZY>S3BvqIN{eg_+I0r zzt+L`S|>fUb~M^I|I5Mmza02G9DH{;>74P!mv3I@;Co%1h&SK7-of{JC;bgh`0pHi zf9IsX(ZTmdCp{efG}<@+;NbfQ2mT%h-#t$Hy-xT(2j6{8`uz^R`vpF>r|x&)-{OSd z>fnE?lm2!m{0^tQcS!!&9(ad&o6W)bj%SL!Bm&>OGZ{pCy~`>8T~7LgPI(VH>F;sE z?{)CK*GYfK!S|5BZ;GHEir)C*n}?n72ORt#aMC~I;Qx@5{t+kqQ3u~go%BZ>e2*AX zNT$-#NSQ|@e{97(;^hCh6aIu#-Y1;&PdVj%O5oQ=P@giNweOr6d8Wu|-_JyleDTer zPI-?y>7R4T`YiXob<B|>b!uRG;^-AVt3Q{Fe6^nY=}-*WJM%Sr!^gYP>6Pg&RNJLU!ZR)(i% z<~sEMt4-C1Z@%l4_gyFbdro=ZGryiiyvEQHO_}dW{@7~%o|8XpJ&pFwe>mm+hXemZ zr@S9Z3$Q%;=2GT|l7CAo%%5KjK&99yM{n|D_^Qo;hL8bkZB0aJLigbHc}+@J$F4KlST8^D^^B8`k!Dx%r?CXC?hc z^937Le!SXzH!uHd%`a?N>vM-G3>3f0&+AQ<4KERVZ!~Awu=3{~)0!8)-}KtBw)Z>C zNgGyqdC=gf7U`H=aplm2rjJc|X}i})8f;aVr$ z;Dmde@URoU(FwoV34an{w%2yt^USBr(@y%o<)welyx^plSbItHKWEAIQa?&4n!ryelKXAf7bHav#XfM(~ z*9o8Lgtt23Jx=&yCp_weU+#o&bHZPdiojlpGZc8 zf3^{2-IzeLF@fitdNMNr07+3gRT|I7?>l@=A^VAX`JgX8mM7UR3Pc($bX^@)O z-50f*{m44Q$-SlFRy3kdZpN4I5!&-lx|_}(EsP3}PXcgHS`^I^#a=(mGE<5)c3cXnnW5f{e$jd-H}A(qIGL0H)2c&X~*ti`%$T+gy|M{er*#Oc?5)@@ezAr|8 zVsV;*QQ^Tb{Wfw0O@7R<4>@@bIS-ZxM)M+UyV%bssBjUfjR%eS@Vcus6p+0C^UA}k z;x5}c^Wx*)m5(?4u2U@DVT|@t{c<2sX;7L)x`~F-m^h;oqfC5d4tdDw=p3aD$H%}T z{s~y(o7fDK7x`Pykzdc2CcX)y5sAa5wh-n{?jl9>bP?hgn4JW0KXE$VNmRj$|F}R| z<{kjlt>`=gi0pB@CXa6*L4!i3Y;&Cfmb=;WAZ>)=v@$JtVla)3OHM-ZjLGy*xrOaM z{nQLk(!`i_Z?{_#PvJ36g&~H4qK--7DF*_vS@VzQg!18NMB4`v1CZh;yX>dhq)hyE zLiA61q0B^GSYGtBW7r!)7^^J8fl)p~3y1w=oE$4jWQN>^$NS@o zO~c39lCT42j_6i$7$=b6Iik0^Q47aivTac(O*%7bQEohuJX(pJR|xB7XJlKel`-Xu>5d)Oc*|_$x-^C z6CQTLS32S2PB`375#qnzNx#tv-{OSB<$vU-NEY2@`Hm;AwQN*gNSF4w-O9}!o>_(H zqB}kDO&7gRrqle+Q2-cWS4>;j)899W1*hvqUZNv1BJL#Ws!jHw_ zJb4M14}mAIy|Ij!*WMS}di`^Zhi_}c#YyC+oD{vqGn??F+_Qfzd$VV%`FyL*{|o}W z08hCudb`SX(K{?3;ryjYGQOS9cY1~*RrD^;P;`pk?U`{tAN0&ke7?=%{XPP`fS2_v zLOapF$Ml7KzQ>bw42D^+qW3CY3~yoheI7im3cm}_s6YJ}0bal>`U3qyWfZFJPfnTr4DI1%ieG4`#BKMk8*V=ITBT)~5`$ui3qK~UQ7Jb5#b}9Pgi;ORzgK|bXF6Q$xOE2^^)WU*gxy`%``K*R<96rZ32T}{GVKOr7e-4uP+GoRxV{qGxmBJez)&~HU4 z4Rig2;kA4MKi7ImcRin#7>5~;^7iuyyhr#%dBZk*E1$^!2%n()D|`aaH~9R#XTEQr zzvA;T&%D4V@MN$qz-J|&z`w+XH}P2o`LWM~HvLkYe!Y#qjZZ8Fz1fBzvd<^^1ipXf z6ZpSt!(gLXy9$-(g?3nm2gmnSe4;%#bTXf`2lDM^81>x8C&HK7bjmNoqKA-v!iI0R z>2I*%Px1-=KgK5-=V?B{pP%uG`bm4@IgjmuXO>TtPZEiLJD-nxrrSOb+vnAMqTcW2 z^NY59@%%Q!PXNDtzQE^~VE2&UPhx!I^UKhOd_INp`264KuY7(5`j^jt^8O#n&I3M* zs%zsjyD6JSLI@BbK!5~x?zv^|l--@NT9fX6vhSZYUW8yzO5m0zcuXz*|gIGw)Hag6EF_Qk8#{#oUda)C6T^{ zMEVBufNi}m`KVY(exmUUy9~s^<8Tg%L2kw?+Kt~IV7pEwGi{5X*|Q#Zkr(0ojl}+* zPY$-Nh0;Gn;zP`3l9!85id(_h&ur@*66JhLVn01bW}&?~-dKMU^$U`y-vko%GvoJj z9KR@kfjCIC;}R13@OjOQ=WUP|9VqCWh5Ef)HN(*GuD(Vh|2ri7?ImGPE1_f+yQ+J!{y%d5~nzTcP7rr*rwtad*0oZ(Vd;$8|`S?9F)(_9vdlRY5wJ zy4}y^N0^pxIKI(Bj&{zUNlYO|<~-rM#_{hPWm|QmH~wMQLNe!L=Hq-!b{DS{$A}Ze zo5fioPw|;=q4>DCTHGS;77vO?#nYmNs?iTmIY@FcShJ@E_inE1OGjd_gmloe};O~h=G z^C#^FiPwrZh_l6fk>3-b{WIc5ahJGHJR}|$&xlc&+n7ID!lijRxW zi(AAu#gD|V#h=BqVgLtx)1P7$v98!c%oTfzSBvAsS>glYQt^3lkGNm_R6HbpD;^UI z#b3pb64S(>I8S^*d`Wyod|iA~d{6vP{7gJ7{wVqqo${-Qmxx2e2gHTq z5^=e>Qd}dh7dMHoiMzyi#J%DH@u2vPcvSpZJT3kq@ElP|Rlf_iAikKnR6|=?B?;_7Mk)L&R&uapGigx_GNNN4!VO7Z;1m#K*-|;`8DLaf`TJ+%4`A_luv3 zhs1BiV`8EBt9VxQmDYF^ONl9BMKN8hEjAW|VsCM%I7z%)oGUI8mx?RIRpRU7o8tRo zf%ubnO8i4iOm^x~M{F*35POJMi(|z_;ui4>(Z;n8$6IBwj@Vh8D=rmRiLZ(8il2(# zi6_N>#P}4aoC;zsv8k9XUM3C{M~PF#S>glYQgM~IQQR$lES?hiC^*qF72y5i5%6VlA=0*hFk8wi9#3E@BU{uQ*5? zCXN;-h*QNI#XRv2@jh|B_>lOh_>{Os{80Qw^p|()oh;T7FBb=jGsS1bkHnwEQ{wO9 zKVnp>{EJn@x?&44SL`KTE#4r`5$B1|ikrmU;wRz}u~7U=jIH3rQ(nvv8;kA4u3~?2 zq&P*KDb5k|#h1hb;-6w^+yLPCYA*H@?-1vUo5VxnF)^`{lfRufUVKj6B7P`-CVnM; zCmt71h`)({iT*UFoER}tEGt$LtBJM624YjOm3WERQS2)A6#I!+iNnP);zaR!@g{MW zc&B*3xIlbZd`x^wd{$g1ZWLb?cZzR|ABZ1|Ux;6e1>#TQDe-slA2G7B)2?x1X|cRm zS*#(}5gUmYiEYI8;-%tcVsCMPI9MDhUMpTF-XPv0&KB<$=ZcHOrQ!C;lS-DcZOv&;2P{Oc2Y66~wAyO|hQXSZpC)EOrn(i`~U5 z#4E+2;wW*vI7OTx&J-7j4~vh9Pl?Zp>%@)XtKv@aZSe!~WAO{|8}U!kuIjW?K&&R# z78{7o#B8yf*k2qeP8Mg1_lXaSE5#SZ?c#gl=VF0)T5MCziLE9TdBXy~O_FU~#&5t2jrzN6Z%& zi_65v#Z}_-;!EOIai{o>_?7sbcw9Uo{wDq<`fE7#i4haUa$;pML#!t@5nGAb;-%u{ zVn1<+I7XZ--XzWu?-v(~kBO_qb>bFrr}&;&Im4+>bFrxj+84q^}SD)Cw|PrP4TB0ep?Bqr5z%Bw8a6>-UlMnSAB$g$QMH|N%ZTY>1F?-bNE|Cp6X%HY#7D(v#ZBTH;(qZf@kjA@F)CB> zi0NVjv9)-q*hd^HP7rSr?-Cb@kBcveTgA7<1L6^}Q2bkruj9m5QOp#Zi@9PiafmoU zyji?Qd`Mg=ZV-2fd&NWIN%5>0sO!X2L+m6D7iWtPi?4~FiNA{}^&CHS#h^G!yhU6f zt`@h62gD!6==zSo>S9wdR~#r#67Lir6<-qH6~7kGipdQe|CwSdakw~DyhmIrt{2}H z4~xHvr5ZYZGsKI;uHq?95sXNb3pPl>OHd&C0qj2M%p zc*R_CpqMA#Cq5)TC4L}&A^spHG*;XsJ`7Bge2LhFtZG{WB#$6R;QI^Wct4x=NyNQGTrT|@ zakKcQ_@Q`M{7L*%jBe`0RaUGmW{cg#YsBf|?c#iKh4{SqiujiJvG}ccjBIFIze|p2 z=F}@7CXi^aRLN;#H4^z6D!rBT7mGR4UnaSy*q21U!QvEgzPM6+L;OrUDMnr7Boo@q@N-A7V$Re@0UDJTrB-cah>!piCaj-vs3Bs zOTSBGcp#fjon5_Y#po+aKx z!e749mrDPbxJq0jt|Q@R8;N}1h)1PAL!uwfijgfGIYul+B7b?wmBb7Z{^~0IBI#R+ zIbu-kO2W?o68WZ!cZ>7IrQ!!7zrafS6tTA0TD(lWM!ZR!B`zXSzlX)ArQa%kBAyb< zwsOjAK$f$trjomoxK`^ad5q+VlJ60hi7$vd#XaK3;!h;@gHvQJd{3seBPWoEx3pMJ z`f8GEigl&GNOCK&9SMJ3mEKqSf#P7LPZnpB=$HFQ#PcAD@|TKFlJNHo3A-)Qzb5XK zevjn6;%DNQ;x{Dx{38A>Mz?YFNn(cBKx{Ae5l4$t#GA!@@kw!`_$GL>ym}@wQbc`A-t@{v$@T zckB{L=*x(y($|n&TdXgAbMgv&uS0TB>0QL`(hrn;wKz_kBwkM2oD_5-*d!zvMyUQ0d1>o+Mr`{Y-KIzVAz- z+$AL1;Th>SNPdm1Zdq?hexHQ>4@H2JM%mC6MXZ?agPM0$0}wZwYTH<#R6yhM7u zz{=zsApKS1FzK%&zqPDeCErb=-227(r3FO%@Ml{{ow?@B&EBCgNHucSXF`DgJIiF{|pgdk*m zNwN$HePt5uwVEOG%8AXQh9M z+-F()NR)q&eAluHB>zP2M%j;t`)D7{$_F` zuCF97R{9cgx%AJH>n&@GB{mkjii5;iB;ve}ya(f2@=6l%JR`1^ z{uT0e%X&xh$4dW9{7U*`WS(XHE;*vB<1ZkVB2jJ%d6Q+;kla|z7K7w8%eq4HaB;FY zoxBe1D|wOlr1%Uu&ayU3ep5UkeocCW?5Aw*Ck=sP;4gs zCFE83{et8HO20}RF8u_uzh&Jb`7Wj3C(f7t5wa(q+a-CU(q9p`OaBgu-`RdZ!v1R# z^V13G|0H|h`CONQs83}Qb*wMBwTKsZoAmA^=BleDj}vbaXOTFE$d~-6_?-A6iF4&0 zlJ|;ViO0z1mi3F|Kglfo=HPM=@s%afz7@nO($|sPKx{%HU#{d%Vo&Muj#QI=t@IPc z>C)dS-Y0#&xJdft;1)+$zqN{(f>OzSk{znbMbwt4a8IL3~~MH^leF{o*Gi z?0*t}72~lFu%4Ajlvk5P{pyjhZzgsjVK;z;-Ehg{N!Z^Y-a;bZ10>EjmP>wyMEy64 zyTl`6q4>90xtC*KS8OTv6DNuHh>wYz#rMUd;$LFz-tZfb_hX5div39R!;KzvYKP9on*af|e?iEoPUiXW4(FCfd{Jd(uyY`c#m$BAXdG%^L}{o*Ag zu8+HrY4{zXI98k~-Yza8QO}3Pr^vdNwMp_;@eS$UC2>6cT>3-e5vBhm{z?9T^ZF|s z|H)z{v8tF!!mgp1BYjZpF7_7tldvBr=7|f%RpM6hJ@IStSMoQ@is|dbl^~WQp-&UD zq;Dp+lD;d6ez}tDZ(AcJPb4w!XGqQ?;qNi>Z_8RwqMctBw~0H&JtXY*i{DFsOgtt2 zCY~i>U#cI7c&d=NUd)u-ghV`TC3hfUKa7mDt?Nm|Gef*hyhEHz!fuhcTKeb2m&GmO zHWK#xNW}9siR;|sl7Ar)&p(o*a15t?O|m(DKS?5t@M$;@#r?;$m@$_ymc#Hb~wizAF80@iXyf66O3!BA$Q5h=Gou z@?yGJN4!|JYegPd|x#d=~#u`h`@28x5FpCaBVE)~~^+r^K>FU1pLB+hZ! zZ>7ZQVsr5lv6I+S94Jl_r;%u{+eyTEw>V#1EG{Ks_oU=i;yMy>yd&-a~(Y`#vMSC~g$DlCXP2^4sEm@qqXRiMURXh{qlZ;{JLZiFitrNUtfj5-$^n zij%}?B+9*=arz9haT?hxM3vRUYB6t$2kvnH+6f(?kpv^F53DVmlF++&Evb ztO+DOKYc>nCVnpdEaFzYu|pRcP7t3Ew~9x_WS?VKMXV!UB=R{OEVrxJPc*;phTiv6p)&L^L3-Mee68Ha>i95wl$a`>qle`_}#DaOaJ|RcpJ|;N~`AHlDZzpkXxRS)R>RV(M z?pKQy;~crZ*isCVxZiOtiTeag$QqXQocMuwNGv3Aof?Cc*Lyw1yT#YV55!|+8tyxj zb@3de1c%w=54bKA=ZJH~$I0I;%lyt0{E_nCmX%q`VPA2CcqfVTc)YLN@Pzn}*fJ4% z?1ayW?}_Gjj?kOmGlJ%Kj9~2~$39!^E}GvRBHjGH5PVGfHR2BOfM|XP2)i?qE0uQq zb`uAP6U5n~`JEo}EtmYPxKZ38z9)Vzn&0QKJjoHsPI>0{dC+G_?kJky>qcL*kAHV>^~2Y<8VGi zUgx}Tg!ie}QoafI9mqV(+D>BsdyBlsvi6d5F)qo4c-|C={rV{RDDFd(PgvF&auxn@ zUVqNA0_1u;5?(9wg?q{v`IFAtVYN zO=3TpL}EXgPGWz^BQcNOMPk0qCsFuAWL1nW632m6B#sYjN%Zd~67#}#5{17-VxGco zX!@lB34b+7yyjTK8`943)@cy1br zacG|Rf^k@#GR7gF=f!c@kiMj&665f5665e|68-mb07UN$MQN}~T3lIXv;Nc7)X68(2c5{UjAPQHu&BGG^5_=Ns5zf(v5wJQxh z`Y$~hME`9d3lR_JbM)V668-lkiTXGrv4-EtuMZ$~8%{TE#o zME`ZK2crM3A<=(h>VxP%xUqbANKz_^e$0@ZNuo`gNp4BPc#z~FB>ERkZt_ne(a(2D zzK=wIKO}h>nT7pW@&*$9zg@DKciL)RM?4=1ZM|F3>clywfDchh;mmnU^q5 z(j{k*7%y3pn~@kd*^+ZfjGrEo`;Zt%LnMzNQMpNyr;->~d6MUl7+?947m^rf%OyWa z=4swSeKt_WxZAGuT_nceUdbPkb2U%F{#(imH7`LvOBv%bo%d^3stYm?-y zB=)nTl7A$zznzhMmc)LSf_;qsQ%UT9R>LVX#!nqO44gXI;b?bjDqbmIH8c+lZ#WDu zTWN?_tTd#uq5F(<^MV8O2AYQLdtKHLNkfMfYr))()tC{}OSJNoQS94niY~Bt^I}Uc zA^WZM^E>V1We>C7U#<6kp6 z%@TT8z4L0C3)>>h;DQFYAiaoM7inXLM<|6)t2fWS4{zWiEJ`ZjoF7`9Uxr?jQ)~%t zdP)AhHs^cSOLvO(?xvUI-L(lD3ZXXOo@!pMQ&hhfVO5eJ_su>3>MCSdlDBj3&-qt> z9@COMdSAWsuRhN=4jbAW6RJcBDebsYTYo?l02TjM_zc+aNbxt z&$uM7-q&uGSbau%o^f$rr-Z$;t3p+pK&;qO zy*4G4=d~-g?NHu-m@Vk)UuFxMod4RflKbI8^WtJO1A%WcD|rw1n3d$o`?9kVBc#9c zj7##$H>LfnH)B+i7tJDkz1qJz^V-Mh^I#$K`Iqzj~CHlJ1 z^89^<9p!m}T(SF2xLry6&IPu`osgJ!eEpYm5@YxuPD^C>Z^3!qj8|fX&3o}mY+hFN zoYnbF%bnUuE3O;QS(Fs<`Bvd&44piDw0YZEu{H6$ps&Qbgxi^t%)8J=PWHY6HN2pr zOp2&aac1XN=)8C9g_jgMXr6CXL}4XZo?jk2(EFmkVvD@Mu%uFpG%l`SzU1#e6l=`> zTcIJ-^NaMp8nE~h&$lY6zzZ#lFRzGK5f)o#uiv8b{nwa^%X@y5p7#?L8a3pr;NcBtV@U%~-~$rltKnme4-B1$g8;{2XIcYwhdEV%%^NRwv&R#KR$ zr#YRo^ptAB9(BUNaH5rOo!x zVZ$bmoaRj(H*xs5F;k}MZndl?51oKhYOmSk38OAB8#iVG27!|WcXq9Yc(LgCk?#4w zqrYbI(D526L#IxiJO-B@aQxpFd@N?+uDcbbEX~5QGL1_$tlY-O1ZFADt~OEwSpUtg z7i_}ISbSC-caEB)bP6ti>_T`-Ny1gzMe zbeoYZi+0TKmgjOTbl!4Dpxh+rSZ=iJnQtdn`gYr|54Q2KU1)LrfL&5 z#y0)A^FV#Ri-9<*aT^u@(3_b9f#<=*V6N4)HquM(WmcN45!_&H@?v*r9_ z8drYqN4oVb#P$fR?&6l)5k}r}??btrV8r&rN5Y}{j+H;RzJ2K2v$*2Jj$Np}v}4@# z#l>seY^cJ9YSmQBACYYdfB=Cu>s0eG|=Lf+Y@%)a!;e& z>9ApcQ~+tmc(0W|z$}B@4aqE%3%^%^?NEJb$Ncog#Vz+<=)L8RyX4${lqNgo``Gap z>W>kS-L~`kdm+r<&G5&0gY~H5@%OI$0cM%*Zb)|Pal)|+)q{47hrYPD_4o;TZ#@=z z>QPO0%+~@FAAP(1k%xTsA-jv~uMF(G{+{&IqXvxK{@{Cx=nrnpvc}zz?AD{FV;8Ci z?HCVzadFGN40hgfw|eSPOLok+Naecq*Z_Z=FWklTcU_pjJ@9ABMPQjQcI$Dk{JG(8 zcQ@qFt;Y+FU8o+kqd)rM;+FetSh*j0>VdCxgv$L)<+}BF3;yucmC)jb@j+O82iyc% zy7B!I7T>3euYv5`_)dhy_pK+sMzD3;r5ZNq+l}uq{JGn7>4w4gMA6QbzjrrigvE_7 z+p!C^-%;4H{TdsqbM4m_cHVJt+7n+>*dp2Fo2YW#nD~7KcbhKVFh*I;9qwJWkQ02NY z2y`z};65z-i-(8CDQU-^`jV}gv-hLb5iLbNl7+-70U#QLU<&VC&xbbAk z&XxInAMb*g%);Lpc;llT%i&kWxVZ844vTN9C%(&M$9!|b;#&@XP=yvZ9=>mlF}U)| zV&Z$ku?zL@D#h1b9^Lr(o;Gj$&GE#Cueq6eFuwgN7ck4(V&Z#Cc5Zwx7ZcwJ$1W7# zCdJoV{@wWaUN~=j3qA2&0bANJzI0qXuwC5vwigp$IoY}K?Jg$1OC7sVd~Yefekg;B z8(#<5dEF;@c~K^u@)EhwrWP_V1^~#P@hue6(XZR~m2U;(IhKz73xE z@HNFy`yB|2?{G2k?FozTXfg5eeR#kb27-%wb({mb|3dHc5z z{@lK%L%01hWarAi78750$1c>rXB6LX6WzJ?>k2z>|9<3&Z=@%_ys-Efcv1093yUwx zZ3vaiI&$HA0KM%OfE`rUD3f|FzQ>^S#`mo!zA>`BZLdADbLF&R z;``mP3$-8Zpt7zFi|-dGz44v)#5dj(Uws&P`!}PQ_^Qj!jW4U1__{lGq4;RW_$G$M z*A;g7v$9=%`*Y_*_!@4g{Z^`6xBXheUq$61+<2yk`AhNmd{B_aPLLA*>;DOo8c)JUmp&Yn-+V1I}d_`Aky8%jfcNO!(XUfn!#TtWS$T4 z`j+Lg9?A0O=6l=?2x(kcM=q@$yHGuzgdOwK7Z*2MbJ%&y9ptG8zV;j{m%oGaj+ZrX z!21yH;>L4zSbTinwRdsj8x~(c{@k+Nc)EqfmsCuAGs5Dd z9pk$@EI$5T#2eo-Pki@!;#;F~-T8puvo31|NaWQgE=qb|^kx2eJL;$=HoA33lH2 zwtC`Q09!Y{pyMxejO-78-uqH+d$pCFEAxHw-o=e?bXa_}V|fbeC@wxsoVdot$ zXW@_K@;I}?)vPJ^>8K~ zX<_?uJs~@HJ~#@yqV6;B_h8=orl8z(W6Gf#b=ksb4Obo_<-Egk;6MZ58|k)12o@*2U98{g2d_%apW8rX1g zzFbdy&&!VStyZ~ialBq{Nk>{-f3w5<_3^axTG+bn{FwZ?^%(6smOr;1Z#Z_L zcBUQUp)W3OxqMHsx1FbY>hYrNm@hHWX(P9|N!XZAM_Sx?3c~!&fxk|$;dprobn6i* ze{McswCl;CTaN~gU8o)ruwy**#l@{h9oTv6vBy)7O|oOY>0$MVhre!gq{a2uGtA#X zPd&E4)~&|``E%>hznFR~a_mC&pdI6(FD`Dm^TNu_=x}a7e^qwO$M+($jokhi0)N?% z-Np6C_bz+er5XHj{INf_fo?rMl|Q#0%ZsUpFX{aKmv)SYzPPyM{vB5CI8Qxx$d380 zaQubpv8tGQWWvr{kDER9*yZupRsP(194)3E)5GdPJH|s_T-_8i>b$oFn_x|^?2LkkI!jf|GM?aVj-Tz-9LVE>_X#;b~L3gE^a-32rKujryhG` z$9(+Vt#@3tgfbg?cX9pk{mv6SX7pe#CXi8sP z+;Rtom79xlQ8hE3_sNd=wyRvXKk}fQ3cb6y{^o@F>jQtCU{nKveF(bscv=43dYon< zp2e-lNyjc!58Ba`zPPyM{v1~BGEY4Y$d37X;UwMLA7`O#O-EYXci$5ZJIDUxIEuo|iwj9#0likNu8as2;RqJoLrIE%*Jfa+~3c3+}i&EIZ~a zUFQ7$SOb59pm!J7-^nn4x$u_>Bi7>^(5*+b{JHfA;Ck4*xcyPfu?y9Mc8rIJoWevvRm#oVf9FYKkvO!*I)ZEe>cM)zk|Sf6nOj%l0UZ|XK+5~UEF%i za_mC&pdIT$UtHXBZwV{+bnsk%9FraMy{&THamAY!qun4p{vHqW7jY@}bJgQVkH2m5 z=eiipLEu^3dVKHLh3Y{&#zS9R+W-`b$&UH>d>Z<0f|bi881eYxE==Rv zNp^01TVfs=K?hpga``+2?>HEQa!2EyG5hT#Y-z`A?c~p`?=ts`8}i38xeRgaLiME` z^V1g>w_H9?$6M~MuIK9ei|m+hwaRtt@g)4Y+w|wgb8DEtkKm8_Sr7coJyeg!9b zOfmI%$FU35V~y%TUtHXJ><%mUpr;;x$c}N8D|`NYumS!S(vcR|--$4PKf+%oY*>%8 zpxYnu^5@p0Q$^R4L$^N~J9eRZ(2nuY7Z#tXszYO@xf)VRsV|D9st^B$5xT~0YJmA=c>OnikLtk9na_ED`FKVb?C7te$6q9N z1~(6V9K}twH|x9J&ZXI~^S1Lx3!P_o(O;U!UupT{oWkV=T%0uR;B50h%i@|AX7^1Z z-n~NuEv{Xiu=p~QaGipCUGCz}FEzvBTeuj{Ce!gU-4kDP*g-wX%|E0p-nHclAj{=K zdYaW*2D@~8nJ@zhc~_R@zsM(u-5hle|Ux%cf8mUXb;iP3dBR~p^>Oy=?) z#y)d%_tSYjo$d6^U4wxWcHrUQ*9E=?75DlZRNiYhIK6Mhn9t9oW;M?BEx9sxLC%j~ z_?Ilm`QhM|74JUw!*#Qd9htP^_z%}DKYnD=T{(w7KU7d{?B{3Fv)-;$P=H)Xu{cmi z%wuE`4_n9gPO^^=@vj&Y0d3@h#<^}vUZw4oB9|)Ney70NX6s0`_Ju&+zqLv71#MF1 z|Jf#)|L-;#iZ)64&u#KGtkX=J^a%DilX6MK0@EU<#(uO&I<-}cZ;^Kk&To%X?c;;# z)gpuCgH=o~cG`S8r_;8nIa_m9ZEK7E_i?PudIbHD8T8jn*vHa_ywa}2iI1)Nc_*LF z!;{eJZ`$T>_GHr00;XA+g?oLOR^hxnf99CIHnwKxS+yDmtr{3TIhjHH??k)h#{<4# z=YBaDfBt^$GlNY`=@kz9GCS_|XI4SZmV2#QPOj_H&dX<8HM-|C33f-Wi#p4fzkg2u z_EzSGeO99<_pU2oKV}+_WvWL9t!j3@Bjp9Tg%+B~d^;;WaXjGnAOCPl)bZg_?Q-8N zm@wvC&Zt~F|Fwdj$8ZEVxtmwC^It09e&ficFYq0S(fItBqI};{@cfu_Iq7?9LBp}! zI5SS7vk8 ztNsbU6r|?%?lAjLyU!QpcOD;6=2U@|eiA;a-hRBN@v(L_#{H>FBZ83=tp>rp`Da#T zrAFuM%|^)!&(zFgw1LgLekg}Gr*S(f=y2hgRhR){3KL^CpNLQFy$?MVyX#E<<=L-% zGybg;Bm9}c-W{&%GW$hogNT zJu%*@H)*dKUw3xaOf!6ZUhtzcdFi{(3|jtrYG!a=&ZcdTANL17I&)XL|9HTjm(#cN zTSmjt)WO7S*RU{_+;-esu=#{Paj&8swEXAIkB6cSdZK;eyl8WR{vadH46Yc@S~LmT z!Q~^LE^y+<~LZyU#Xb?(~yGZ|~GT4i!0gFD8p z5Bf*Wnb2W8jy>0u$?Y%_U$HN|VODL-12{^|c<+bUrth6e%AbJo-!d3!=CH`6@Q=Lir!DD{Hd_s|3s2-Z77@Yg3Y;zf(xgH= zF|f_5kyPkQj9%bh>TE|O1{S1jYl@ajDhwn>EJzPJlGAEd=AeB}{-}J1?or#yoT!vM z?Ohy2{-Aa0t~{JRoVq*c`Z9V+#dYyZ26oIlnV%O}l7sDcPgwRnIld(a zw>=*8SNF|l-iRfiZnLW6!P-l~8WHm&7eujkryk9-8bvR?{!6Rg4f_I1YdE?6OLC@s z8L_m?x`d@ycAW4zj>+{dIX(G>1bRl=CBKb(Vff+npjDf#zbQB?*u7)qKKAW{pINn| z9$Z$?N>QUVd(tL-9nUB>o$w{vd+inl1$OP@Xu0k>e|a5y@I&yh86IYTX4QBoIJclZ zJj9qjaec%rOHVMTUYJqsPz^H=9gYnh> zz<+=BX$4lj{JmC;QqAsg;II5&E6CdynSt@%{#|g^{m3_vufezi`j+m zYs^GpR9l7PXVsjTr}-pr^Q&EWb{28sW;_VAwAoX>nMlo&oQQ2NcRey{)?sIE@nvS= z_}UuB*UR>;#{SKDG&5*7W(z+9dDodd%Wl28vtzyM%w0Mv_%hodUoP_X-RI;QGsdwQ zi(H3CJrc?>$9lcMv8XfFv8apLgML3Ocwr2WkSvR5XpU9%@gdQf!5L{rTjRzmw0y1L z?yiU|8{1i1 zEIvYNC7vC-c3EXMk2V%K_JmUI%33}ly&B7muVz)xGVRQxnRQ|%_VBzLE(&hqh>YdD zruNS7kvk4j)j#rnPy8eA4@Wz``fSW;KAn}kf-&pEOollv&d%hF7Wgyn&*>eyo=VKj zK9yM8$rFiQ-@lJz3j2wf!#3i7g}v=V^H!^1WM~_Y`F$4W={Dxy>h}DY_11#A>;3B^ zPINM@kK;~{tYBneVx+%8S94Am9dv4g$M6Q*1Xqm93R*Q;PglPqy8pK5V+A+NjvhX~ z|F+uLY7b51vG1<;MYC12g8jGEgfyT6kJ%qrax^4sv;uq z!~LDWr&M*Xu)wIIhvG`GTp)5(9|+HFbFh#Io46F z{Xa45c-&iw8c>m!wl#Urq}Bo4`Klk?xHMYCKN5bTo1|4X7qC~NQKFkBHNjPHgrASt zk8W16I#L4unYaj!zNlPn2=V?o%+oslTR2bhH^Mi*qT40@gPScW{$~(F^d)8DVV2?V zodO{{iN$0lMB;yR`%>E(V-GtaJ{@9?BlfftM$<_LN9<)Me2<2X&UM7zc0x5e>S)BM zK6U~xtD}QX>OebTCYn0>Qb)YfP8d)bVkbu&gqE0rV56=~X2F4E6caTlnb*mIMd+re zA*EMwdjR#raGiq|;+ryRR|-Je3ss65k;YeK)Xt+>9$F;onkxMKqW1lWDKL<}$EERQ z8MRL1cEQ0w#Xrzc{%bKt0%>LWWfjZc61f6ZQ)}Q8_XyJ_fokRWx`BYd9!sfS_C*LW zRr2|XQB8)^qsnnO4AkOw&nn3n#DUt}?o}n5`b=*3u5v%!*5P&^e=ppn4Ad*ddd2&{ zKm!Eo8zITR62mOe&~#Ob>9;^5Bc%HO=E!Z5QV)fv`R_!>2QEq;h`7`J{SaxOWddDi z_&I6v&Mf(H3;L)(A(hOfi4Y9NX|lRoBWSpGzKQ7=D}>Me>rxE zz;$ISB4xXO0c$$B^pA-8Q!7vbkw#5Q<2T@IuT4kF6YQ?3mH1WinsNA7iys>FkGXja z?k|;{HgvKTbBk#U%l{18KIYccXW%HppMwUEnOWss_Mv|#B8{1qnt+PO`}tu+%x!5W zkdowYhJa&cS8Rop6n`_+IA%^-1qi98nPYA@uG9QIQ16&K%HNJW>HdwVL(H9~Ei(Mi zV;slaWrR%sH0+}>cdM1mmu~MdLY99s3%%C}&HM$ZSIm8;Z(I61qfRmR8=bNb@G?WfUwA<^hj6)Rm@`3gZ6S?LK0d%=0QhX;Y;`d z9T)SEBR=j+Xht^=JK_^QE0BX$j9Q+~ADq>Gic{YE++9{>+yO(*3ugp`vT4ZQ@b2=-O(V(ug^_ zPO0s1mX#2L5TolF!Iy6*9OJxH&k^U_32$Mqh_3I53+;qgu!BZ7Fk-}FOgRCF4V_fn ztZV-)hfha4ErsvxO7twtLzLbuA145umU~|zqsmtmR6H?X-RQ) zV>qFfo!;1rtLNsxc6}#H+38KJxCUlBP<95k8=CES>`u7JAJ@qL23^sEbBKt$tkmTg zfOcEn(zGjK=dtbU5TeiaqoE`04cy=CBdD9-egz)l?agS)MC_2TkL&ACLgrY`Y>vB_ z-lb;H-S_+i#eNEoFwefk5!}~57zu%o(6%uH%J8K(v5WEVBJTZ9VIzwFtXTd^HZVLL zMnjWcrqL_-SC4yK)VD~FqPZ3L0;4KsWYQ-zI7kET=uzgMF^J_(9r%@QMkoD6D<8_O z$9>gUSpg(jG1r>3KpommC{q)uv32p!#KgT zcBywE*?M{GJWc8HB*L#;xQcpytUqprWTX%ERz?LD?!`*S@k1JrOqX zb|QA%B>NDKNu}+R*iN>)V&^Jje}n%i_EyAO*3L#z`q@L`@k1r1cu=FR&` z_GU~BY4$1DSGEh`KiysgeKnh}N2qR(ho*+T90NAPo`=9|+WFWGYT2z|U)z2Q)hY1lenmtBpMsscr4%u)Np~q6OO7>4-nuZiWBt?S&{M$L0@Pa_t)U-_fp( zb_?2Hp-np3(-CK9I|4Cxv71KVhoSc0s7p6{D{6h2T@78*!+sdsJ?-tt+sl3lJ>J`n z#i;9J@4$ZAAMdQgYbEU8&{hNS-bVbi&#s968f3@8^Hui87#3IC$KiRfeFT1n*k2=c zs67Jl53?(w+~IZ}{*SP0qLr?(Z$NCLZ2sJKwEYd*c8vWT4!2|N9r%B(eI@*iv!~(z zc)KzDPq3$;juY(%@PCq>iCov&Iru->9)Y%+V(-9Mnra`y|6A;~7zwx9tFS%O-hu_Al7J z*G@xJ_u1W%dcVCCz5kDW6utA0RX(Bt#!+JRQeVNq-i>(ihGOKf?aA=!vn!%c{5D^v z5n+D`eWd*%Y@+NN5K*+<9?=Et-_Q~_1#q5V?qdGK7;o`tf?*?gTydAm^tM|UsuZ3X*s`0VS-|h_$4eYjvzoGpl>e9&eqm8rdc_^{5 zy&IY)HeW;5)INzlrkVXaYJHKt8*SX&E`?}Y*!UTY=x6}?g!(s$F#BEMu~0h z{~@-E?UxW+JG&)%;}Uy5G}-po=%4oX9^}nQK8W_T^5Pnsir`=1WrUeH&Cls3Ej4j^ z3{M38m&0q~j3l0ISXIWsVd9OP;FecOMRUdo1Ge*|(x*e!D4ZhJ$rGc4CJAA{4BAwM+4I-p)t5WnY2f zaWs4t1tit=k3VNszZB2&?N!FAEdsOcerRXR(VNhGNm+i*O=&4fO=HTV$^E6!zDdo@ z>5x^HPhw5FNGBRc&FtI`PUg+R_u5-45KLT8xOg3!>E@a*bx{&mi-CZ&$b^x z5I*}YC?ahB)-qr}#<1)Y*iN@o(IMIPS`5&<iM{(FEt+;pL2UW1*BFsPu zSaGuv0lFJiFnf6EL8W+2YA0dev+XPsd_HEy2-|0Z=g;Mn?A_Sw((z7D2LB7jYhH2- zw3lTkCo&jcavwVNCtr*HvLcde5rO2=s3q#RlR>2?zmIIF-x21^i(8H9&Qzi;n~s(6 zv->T?KGB4XNI%1fh65|^UOKYUt+@BhMxGV-joGm5xV4xFu=wKMa5f_19!WQvK-^cR z2rDUWtD{Me`@q@AwgR!(&r0X{*{ZR;rjKoprj5N3USoL;ly-BVTO_Z({J)|h1DB`p z+|%+$z+<4h5d!}2u`>jE7$M2uAIX89Mo9JZ4IzPEMo9NpMqGj3M#%KnLS+MejF9EO zhbdR2u=tk#LhML^zD8*4uZi9X^fN-X{{%WF(BBBTe*OqAFu(|%{8=;`ScZFSH~(b} z^h)D;kiR~fJTR#A9z-?5pT;~_o6Gsp{vaARFxZ%l^Yc}Efg$Fif2z3%2n;i35!?L< z<1rEf!yR##KY^d@2Symte#@Wm9Qr#j(h)Idr3C_`B6%6=AC7$>Fs34Rd&{4O@e&wo z{6|=^+Yx7(yU+s3cgC~Q%V8g7{xMD~wkk$w1O6&2{qIy>-^(+wN<7M9OD{@ zCuHA+@>fRZMe%)}R?8PqWD}cL7ypEkIliqjpQE{xH^+X8?XnnZrev$k1jHLRJ%$m~ zqqZ7yT4ipl zH`}&-Rc1HJj(^l>GtOzR$7cM~M%y~1ZNOLd#68C^14WsCp(;4l zV#i0Z$*oxKCuR8N&Ey+RAJ1eS_OVswBqo)VhNepV%A->yo?Ms<8>^!qdqC+#J8EMn zk+;XJhE4I$p6N?sq4qLNHx;>iK$FQvsmP%Yp)HduzK*_t(8UOSG1MRoq0op=;JGeq)6l_1>E5#aA_yn=qa~+}8Xp~lGy7h>!0)5mOfp;UBt;`As zFcaX$Kuzi^)MuU*jsWj_0TIo@$|T*)H0D94+u!7FYK9R44{5FPFNfVHcNCbUQU z>hq{mF%>f@go~XNN9az$ie=Gl=EA78kDFZLF)Hk3{n6i*`Q-1`zNTz?9vtGaRvtfQ z0(9B5u89?G1>Ml;&|PMnL2g0a#A~KNH;}rXSTDmGa~QqX)>n=VHWuQXVrF7cTw zqWdA=P93Y+-qEdt{2XgX>FXG!3g2`8ob^mv4o1pWVZEV~Q1hS~|*8F*+kBLBZK)lxqajo{?yM z?0?ZWBa!>P$;||REW03OQ3D>rc&LlV|MtG}pCNa|^U%&l$+NIVJON=YHtxq7PpeX! zq4CY@6WtI3Cq)wio%*KZe=j>5`jpWyYK;w_`MzV0uVPcwFk%+8xO-#XM;S2h27S&L zd=c6gu$nRGbH*UQ4Y?4j8G{kd7)-#_!29NA3`RR+ zD+_Wab=)~)99Hqvu#XfKANHdrIlAausY zrC8%T&~p=c&W2Fb7^IOIgFH093x~yx!Pb2E(I&eFMz%A5Zn7J2{;b1kaEop3owq83 z)Cz^M7@qIil{r!1KrkPDY9E$p1%E}$+CJMHx@gb|ZtZ1p)ey9qmVI^;y6p>fFRU>& z(Yq0j`zeq|QRm0`W29~FDn1Q)1$F$~Aj&o~B_D&di@HD!3@0b=0mytzQOxV8W3p|o zO!!(mK6)o+HT;!vbn%#9_;{N5%G@1Z#=i=7=?#dp7L--6#_(jIqHRw6`a`~)x?|8) za&)|q=6k~1&d1c4X7gz6o7X9ZA8u8)&Fs1pseIC0+oK7*4t6Yh#3aKa+ct;DpO9LB zHRdUt1GaZ`iHI?VYrhQ6v&OC|WWHlO<~Mli;OK@!9zY%MI0x-y9*yTgo=e?c)Tg^` z&K6ffUV^pKlySIWW2(b5{sTre8Fz1tid|9`YfJ$;sE=)q=3OCQinY>|skr50%tk`w z-L^_ohT;B;QQZx3HrAM*k#n4rb0y@*v8J{~gIry4hsHOrM|3A- zbjSY<+>h-nOzytG1n5&fs_*;Xhj0ltE~aN%C0g*@ z1yU!h_0zED4uUJc#nZ+NJK`cJu0Tp}tPyn~48;a-Psh`sR5mmWYe+F+je{P6EkUWH zu@Q-TSZt8$KQOS((2j$vvGlzL!gOp*qi1?lKS#qm?HjR1=3lf1TAPn!({LIri-s?zTl?T~R z-Qp%V&fkM$-o;086CKUxkPfgo9%WeEnviQN@<|o9JEU`t`BpR^i+Wyh8M{%NJDZ|o z_iH2a7&dtNUM1aa1mupHw_#>f)$EMyT0Y#s;t}^2?)*T6on=Mh+vUb@3+0(=#$mP< znWltZ-UOV}*!a+0N#nzkd{!hL&TIN$Rw&7e#1Fa5)yyJ~?pEkHyRY`>?t+e2DzAEU z`Oxt?WuHg)5Oh2{`Oc$z96Db6{C-Xs{S0)R7}b|Jw(;2-XDuw%vD(WfSHq6PL&e!f zyr%dWy>bj|<4M-p_PpTXhbMott1xR>JiQ)-430OnC0Z{UBj5T6r{!Ly)#+XIo_)kz zO(ESpRoh;640)Sy>N?Vl$C4`Wos6|HuTYNUaz-2l@hYsPr&-^dW5%Np9>SWGfts8& zs?88zq|Fq3DsjrFPDA_|tCdwT4R?-NB2R~K{HmoAr!;1XrBKCKtVz6%y51ZcdDUB$ zDi$!qcxwvLd`PzuR(a;czaLb+X|)ZiSw=MpA}{w+FGp!XtVhwJr7_XoW2VgcNO}Nk zY0Sp=8V#TB^*GkZu`p(*JdO-(wd`b~WsmMQ=y*x^Nl51zzB91@Jpcn|6oF2WQ=$n%1@B` zG1iC;5DKvI9fhYMoWcfg=vk4g@Q>qX5;D2H-_ysy4kE=J6W1fHXH@A~d3kxaVrq|! z|L327syY=x<8dgq#acRpO*PJX(!^)sROKwnC_QDe^_0=1K*OKAMy8^hxQBeDLa&D| z9XjqIr_Sl3xr4ItoVMXHMf*MCv#S1ye;=aABwl5{U`oh@_YAD1r(5fdf*-oH#A+Ie zU!B1nT>M{`a1%0`M(T*v4p>bi^~6SZ3T&jI*cgn}G858MnBwLlliS(ZaKnaMEuEQg zOv6n^3imQM>f#%26)f3s9cr?frdqF>m?xmju~<0{Uo)E9Al-^J@_A(72uno>@}4v0jkDe}-WS93d{f?J>wTl)w8^ykWBZ=w`V^KXWXcmN1w<6BQi;f(o3D8-6w1|4U@|DDrCbH?QD zmrxb#b{qgxVVcz|4L4S>Vb1dHWjvCbDXF2k;r$vS--6Xl5Y5a4@iD{?sA6N~n49YV zgLs@Owp|CKipHHrKh`9ka^@OU6^N-+@f@?G@zoAuOR6~R`kBdw-!ke=6?fPEMs*X! zDOB-PafCUYeiY&|tf{*YL?1-IC==;CL+fPD>Yhc~)6BvXw9ZEL3B(VvUd;0|X0y$I zO#jxU$$e^Lpz;)ruSMroxj98Eg$-VOhtAI4N47V-W8vJ{SzVr-@tW1Pw&Q=NDnHUC z&&?{pLwT&`+^i-xYG940kvTWZg47VJIX9yNzxi#P&du5&r4?3lZgwd)I%19g6lS4w zGmgZff*OaKU~grQ{s@yuizBdel{siBb86NLo_b(4r)F1UV-VJO8ktkGF_8Enf;ly# zgJ^sp$eWbr)NCqJCSx_HW_j4S6>B^VLZ@aN+(pHuQ?pczbNAE?la`g51qDa%ZwRn6 zuS#s^UOCP`Gg>3foY(}l5zS}n^TY;Y+CTLzpl9?9OXoDbqOP~h*^N1`>7nx)t19mz z4zJ@(qXW&LxF1p9jg?dFl}57y(j!l1j^ERY6ux6C zXKXg6yNh{ur7jxHHvgxh$y>*KUl09KfP^pL`!lSGry&$z<2$TPdGX7eFcXk3kw3{j z1?>r}k*~oKXWNUA5}GS?sInrPAP?_Fbaqp5FM{WB=grT)8*tHl?x2PfBJ?TBI0)B_ z^9>dn357ZDVxc_H@;2LYkK41*op-z}!mXLZJE zojc}+wtDO6i`I0utjMd8m-A;MC$Bjfxl!Tt4C%t^7*_f$w1?sLC3t(|Fw}d>SJ8+WF{s7doxyZoUVY4 z@)UTSu7i!*SgpwF_{WM->X}3jXcqy?M z1@lvjTSBS0e+8X;mS(K6!@!&^Z8iJ>C%yhmyZjyqeom>4crp%658l77cohF24Cco? z72d+3%U{>Imx3?-2Ow2fPTqrZa#r`|tnSU3p`7VU5&lXR$a`YdSl-GGEUh|ATiJ_c z)tF|j;s;Gu`m|UKRT}eFt1(`l6Ea@jQ^t=w##3=Ge+i9w$JZDy$qgAV=`G`Bj`4Pk zhJ`fd0m>LJY#%aS*h9vP9b-P?avF_!;cSejbqg6!yHdu}9pf7j`6L?i^4}Ow>KZbh zG*HHq9b-Q1Z7hvDyT)VB8IN_1#~I@;oR_#P!zi$qafXg~8>)5*IE%mpG<N`x_b_Z8#A-aeg^edE z(DySqJ(!Qxl-d+c-w3OT=W=Z1V(k`-G46UzjDwH|?F6iesSw`8#x@EyA^d`kAFwv% zM?ZrQ$t8`EG6q5ujt#7dQy}o$@O;itvs)lEL$J+ZnuBRC@m44nA!Qy-?}e}$8$7c! z_y1|?v&O@Ci?7kAjSwjB|G$Fd%~;L-|2MJ0186+0bpL-uG%u$wJgnN;uras)gGl#V zH$!~I*90#Hv&`*(K0;_O9rO18A#5C^V_NC<|A^>rMLTW}n`nF)%1qLn3HZU_|8e)` z@l{pV`|vsUoO5$Cha@B+gm4oAgeeID5iw|H2nk6@!sK)b5J)g2X%ZB00H><0S`cfM zIN(slp%txGZM9f!)mpXS&{}P42P+7E`-M6bYpcKK*?XOPPp)YDd*9FJ{o_5KzR_HIXW;!p7s*R1O-Y z!dAujJ4pWAcfyCR3VbyKpT|}zBp?xo{{&KnRrtp78CQVDafA3MG^0|3feNEKLl5tu zsKxs>P!1b-!b3%iA|;VAqZEyK2PhZ8CzDS^Vmu__(3o6-#7dl;h5woLNW1|udPG|( zt~Ma!d|cT`(&b3-X_%|HUT$}rZ+aC3QJe9PgU_R6%+2_pfM2 zLUzn&_@K&RkDv;vs^MP7rQN<0zQ>w)Lt!7tUdF#t;deNB6aNXM3ah}KrLR((X6^f3}m?}6A;e$i)lo`W3f)kjCM?5P;VV60c zM>uR^j_@5}Rz^V!@;H-#u~PA&cj~yip{6N8+)d?s+WBvog?N^U4`=x53}4oTkjY9! z&Ybv@<4=mOOXCvBc8uw1zRX7}Ga>nW^8#~AnhEB9$KZpln20e4_XILLnxV?C8Lll4NPWObqiNO9RJ@r3ONWCmE5 zH#1e$06u9&=BcAxl_rj=ODh{i`P0Xk)6-ha$10u0nalFb<<8Q0W{-p*0k8TQ1x9@Q zDe)FYi%i=*B`+o(`e*{uXT_T%%v3*5M=9CjwZ@n-INBh}0GJZGLV697lV--pN0^O4 z5v7QiCO2%Fyu`Y+#60tCG|E_-jg*5Y z@2SJCTd;Q?;?OitKDOMVV&08WRRkO1wo1r{wv#Jcg@AE~E zDAgty?j|$h;Rf22GkNMZ<_VO$PI>yQa04jIov1t{FUhs+Y*&yGXn6|ade}+vCe1cS zw-9?mUgE@2!910FvL`o%WxV2-DNj+ezkP zJ1HG!>Hjp%#fB-bf$;|w$yC4EYQ5E-y24y;ujmA;&i74oxn?s*(ICp(zE@0hiOyu* zHitOd_dK3N#qbHxeP(uH2h3KOAsK_+Wy2Aqyy{lal2`r26FG=zXB;6j|G(6 zYNr;U_BrJ|Ew9FD^=h83J{zZJUuyccH(+iUIizGdY0?YLMfRLZo>o@lwEBFWo`0!n zE<%C8{rJc*Tk#|=7H5cyxCr_6In0i1DjJY%bspUsXre2Q*F;www~3hh#U=uS|I|bu z|Cdd4@OVx1^6{GJXPzc{;&@H;#IPp1<^QsYR?^TbyU;{kTmSExXfsQ0-unNpiRf-< zI(X0oxZ8y1{qS&~csTRji>zzHpDpt=`(5iD2XM%FpK!$aJKdIp|p1 zcW(jt^M0P-a)4d=NB(eA`mx|f{ddAU>^psTv0vQfyWbB7Vpo%^aTFl#2uywd7A4@Y zd{8gZ{emT?Dt;*}ku}-ET}iuS8wx(Q#olKA#Ee14b-uB1V36VP`NAb^+;l{lb=LMh zTkLh~(I)Fz5D6BHEiWs;xqtMnnD?T0T2^$ym52cAw!yP>MWEkgfZE$({j*V&fu+s1 z6U?P{LNe4%UWv1nJvi&>Q}KXB{Cu3u#uosV*hOzxN{Y{{uiHGK=n;z9pqNbxD5@zQ z-l8O=cETltcC#~HRIY0O(|j7_PiS(O3Dw}xZKrF^SM>QW!XwK;{;)-S*m}aEQCW$O zs{!uRO*We$4NhQ5WzEe>a7F_=E1#cFn=hNhm(7cP<}&+Y-!>nU+k7wh5Gcbji7I)@ zrli6ksZZ;cdm2Sq=3?J2h>oUw)_Pf;xSB>4&UzZ%78OTIA;~hZFAqQO3+n*?6Z0t( zD!5|!uT@u+!=N>Wzk6Mm*_WH;MZ95nS=0q!v* z@VY7IbTBJGX)wUR5hE1frl>*T*Ay8n=*YP)NYPj@U@9JpB1XborE0MHk=$aO6brGhyS~I?L>oIUEL=#}6BiFrkCw4irD4io2ZqcV!o-nkDVl#!YCMr_FS0#iSeKYxgeG z#*L_3RT0VGj8@#di}M{}q{%O4;Jetoi7j=Ld8-+5LVdjr)7iFuTv0iiJeJ|UX zN++8NmP_rsOvL_hyn{kf6pKOeEGg_~L8&wha9bW-O@}ZsN>m6#xI6EQ;qI8yGa-sL zVQh4`!<3Uc=x`?I)WHhy4rh{TQ#nUAq8x=_h(VMKQy|Kzb5J14kwWo9lvC%rASGf! zM7b~pqMS=Xqxm-~n<;0^a-02Pl_$<9uAhSNFYb{I?y79I%2Ue=IxV~sx0{R)^#nP< z3C!PpiZ)OVNm3O1z=z0A#VM$H17@m!*PRo{Et1|oEFE?+5yExw(&X(m#(vJvOKx0 z@GFk6Kv^DrTJC|S<&8z{ubhgh>IlK=SOCpky1 zCHN{Io5vMrLOHU^*LkznZA8|_J*shCvOOjj)AlRo!C~14%|pyS1bcZo{L}mwv;SpY zHB85=eBY<)-}n7&SoY6+&ocX2*vrf0*SZDcC&xxJIL&VBAjF^;Y1M3pX><|URnG zT>*+QfN==rmW#VPQicZn1HPk09$S6avpuiJdXve!I2&4G@Af^Wl8^a*gd}Un;opo8 z8$lRzuhf`+JXrTRR*4NQN+Vq6tucx36I66YUbD(m@txBmj5)kBm#TD=b66O|5(~#M z8zkx+*_aXWCYTz}3^~`?TRqw89N8EN^x>*}trC}|?WCDdssI~P!qzgmWq?DMiX5^6zD+@UiK*u8>$os`S$~35_Q+b*%X@1*+2fupa9z9^{ z?kPG!Qi_vuM`EHji zpz6-I3nm-RJ1R3^w_(NVlq+h*C@#TH3flRF`dL8R_?u&2=fBBsI5aH2hi?ZGl=ur= zrha&fotj~1W!pKq_5?hlar{fJ8MU}cc6KfnXVIBCxu^)O!iwTj?5uLb;rFMMCaHGr ze8c&nsyE5*-wC;2QF3E9CDl$>5(EqE2~)qA4|O9N29oU5bUQov#Z1HD^Y(0%IBkMm zl7xD>3k-)}?6!>@J9h#eUBhvePr(%$Zn9LWOnvU=FS5b=)aUbl1$+F)dDz9bjEUgm zGe1pAM0Z!SEeK~0^sg%J?poP>&f4zcuAbE$=NLu6Roxp_cZBm-_4aod#htzDJBr)8 zHxw7G>g`$6wYIpb7c`3pI{J&(cK5Dq?`|FJ?QdV(Q9RJKc4hD2Kv7?R?*MoW47PW7 z7c((!u(!8+RcCuw&$RBYo(&s|+xyo~>*?+3nAXw0vMXHe`u0_wT|NI_);O?f;7iml zE-ETs-!-u6IG4Z5S}eA@YoM>YebZNPpk3X|#5KJ=gQ{eI`?+rZaVmC;X#tGxb3*DY zG_b0_x4XM&6@w=-@%&F{U~p4+M`&$FPf;gBnKxJGgjRQ~Y2VO27#iHv*D-)R_y|g^ z##;-KK-@zS_Y!V?3WL7>u5;Q4JHkwL{gGVE*g)Cd)3qKXx>$REfBPn+;F7%5-_ahv zqy*KnyHc*|?e6Ud0X7#vt+WV}cbwCqgwvc<)wqTygS2osk7zpB-w}~AQcox%YJ}G1 ziyVB}&EQut(QAHWn~sy_nEnxEPHw&9_=}wwzv)avZ#9b?)0$L-JZpJby6tl^tyj+n zb-I)7H_K2i-r8fC$j`R+onM4>qIHi|q|(1XzsTCml6jyV5o8^H>wZO?X}u9<5=8b~ z55;cWizRcNpGp}}(i&Ull=w}i7C5nfYh{@;86qa+Ie064EEpsp70=6MNajV7%OHP$ z5JQX4_W7-NjYUqPzcek)8QJON`qP{-W1W%EITtKOqHLm-XgbNrA2}9uc{nwlv1DE3 zj6hAJkQ{;RATYhi2^R4)t*8uTt$y=34D+3-AT2F&rWQG+L1&C+g(-#&B_&l{?377j zni8TIMaqhtTupqYCSI#SWd@xMo>UPv@Y#rZk!HR4|EgKPbHVUtecz{>^|}jmv;Nhm zoAtH}j?=7|C@bH%Da<6gS>N&f|Fl^bxJ}rmng?ojYtD^sO>|;Bx}bX&>n}+gskn*n2hj6F@CGDOu6OOaI`6#X>AS$v+%*dYuzO(v0#W z+w>It^f(1Ck%IpoUhopt_|PXw_r^ER3wP<`s(q)e>D~_04O9D87-t;9;Mi$UJWnak zHil(I@m2qg;;$S>{`*D#*M`e~|1ia0KTg4Wq~LFc7raL)4mV9Q9p#}Cu=RjZ6crc$ z!U07McTP+m4WH&DHYo3=$2-|@Y7qE~k?kMh#E)|_f^ev*7#}CFD_}I?h(OxdLPg8& z$E^6^GToc4UXC+nFskAY47cJUCq>n)##xTH`6wP!MDyo60e`xaI2ETQIOVI$l+9Vm zRJ4ZUpRR@;_@~1BQ=A})^Mwcef36yEV*L%_ZafnOPYycSCCGvFDN%Zm*l&U`1qG7P*D;b8LNcUGs}Qt)>)|b!JFwS{ zw|;FQ(pmSO&%lxAH2SUA(SJ&;`_AXETWsw|3Oyk<%_&6rQP%fB7;n95Y4Q`07wbP2 z#Z0HL$cbl}JVY34H~QuY)*B#m{N=caI`2dlN8?2Qa{mG=8v-Ks#rdr+Obis8|L2Ct z1yk1$r$!kf=+AUjeO9UZqll_MSE~M4WfWVFDphgMFrw{~O511tleUj3ZJ)Og51}Yi zuA<9yn`9{~G3aA9ltKqpXUW0kdhWwGcnbS$G3Q71nADtw_E*NL*X@nAP+ptKCT7@` zs0=HX79o)Z;>@6v;h&>UF~9IrnC!3M!a(eDDfX8KkIMz`C-cryu!|_YG3X=|mlZp4 zlxG@RSWH@U%{X1qbdsz-Qea4BZ;OWsPvNC>KL(}|W1aM3*bZ?ZnKQm5HLLx@g+&Vx7tttp zn>u>_=0fGquq`J_X_Q{BWm_*@7_<^3xMPYu!0|>?{J>Npg5#4S^Iib=Jlk?I)6q}V z`1NeK3dZpXkWpG%B>TkNG&lr$d9vTy3~O1j3t%i0fs0cO`k?Zrpfdwz@GVdUIM4Qv zSeiH1Nvq>%pP28Yjd2pkp~z+Q)rr=oB4;A_)FbCCup{S$33@iq$%OSjCLiJX{W1s7 zTXEh*uRdPxshkI>MZ(T4LA2&b4#%LL>m>OTmrujl1fHEVUCyBLT;^JFLG%}P)+B2^ z*;`2qMnZTF_^x(n_T(Z5&#pqVdLrq{=`xyXu0-4~P{q%3Qmu{DrcjZj(>_dAMUrI> zT>=p$tJpb}IxgT@anKoEydV#xhb1!W9e6aY9vquD6BAQr z`)4|_dS0w1>{FZ!=1zxz<=TSKY9g}iuxV9_A+sKr5SSA5h)GX`whPjklm%{*M4 zj_E}j8p~R}fDIQlb0}i4)8p+}C#GIc^x1(M)sW25pMx=3qkBerBj*5#)@O{B>0wGt zDvG?b3dfqhO%*>;>A65p?-V<$b%81t%PSlsI-Ti$^Ae|+X+4uix&RmIb)G+wI;3KL z!}7yQZHSc0b53A{QBeXu!l5My9@c7;>^+2tI^($RcV-2hrR282IROpIGcK%(!N;uE zY`ARJY%)0Oc1Bpk?|{JF==*LHxJpF7{I4-fZ=l}<{rlbFlleuf$~ zidCy~%y;~2)fkb?qE;ivt!!&N#|52pI(u?G0)M9UCWqtbQK#}tM;%CU=Y1?~vMg>Z z58aDWG43%tPgk6n%WK1kK?`5;_2aOaU|FAmvVNAFyb^~<&T+Qq9i>LT9T7BLWh~H%1YLcIzAyBSTy;=;KC3!;(Ka2Wb@S${ z+O@vbHA;3^KWx;>d7*_BpoCn_WU6+mAyIqJ+U|}BS#w2osH&-9@xn%9pr^f08Dv#^ zU;C=A!A%jWww8*<*4n0)g`xR1s%Eyq^jTo1+ZtQ-=jcj0+Lh>?9bIcX2Myd(8N@A- z4yf0T&G)rNM|*$wrcirdU-u^C-1e@)&;}56<8pUL`+yQlE7V%mQd83yTHM&s1Odag z*8VcDrLH>E(zG;G(NH(9ky5HQpt^9P{`U19gB{9bVw{$WrJ=Tp*7{IIb+y+-V#~^= zHnd$t*)V(j7-guUrKMsyyk!9G@wE*d{a&NgEQ5PBHL3<@o2}_?Ukj5!9=BD{zRGd5 z+z~6b*4HczEsIncb!9ni+1CpjhX(uGdj{6@_OFi+w^UTuEp9c`?Sp|xc7(^$y6QIN z@w`L`Z`vH+6M>O9m3@s$g`zsG3u)}ct2@n`>L};t2gww z4|etTMCc+)wN_OiR2<)C>XMRJ>(NkCv82X`^mp>}_(F3NIw_1hqtx446%7p@x~9dI zsIID^t_nRhB2QCuh1;k3IwyvtRqZ{iyH?}A5viIg7ldjXD(0!U(Odx@k+O9QE9ODz z8g#d&mJm6K?ey&|uj9~Tl{<$Gwh&!8stv%ru{yM{san+$uDQ0MW?2Z-jc_rTuc{sa zwLjD$MrE9pUH3pKaYw6-FawbV4% zRJ27nZi0b%+m#+L%tE>=c-nEfv5~%syI-`28_>gwL&RIaJZ;@n#8Ns7h`x4x;Jc2X0#o_g1axlGf#oRbLdLx=sn8X{zSeHAqPJ zI*bY?I>3e^@g!`+mYUj@5aUQSo4mE|G}V@M=oU*<%W6{_yjQ8~XZtN~MJH9QgTUyf zRl|7FGot8cGOa~zX~NjG93!b4#Pyh};(6H4ZIns}STT(nlGL5oa8N=ZX~&(|O`(DI zH5~@-Z+EX&BM66P)$$ncF@PKEaZf!`ziuek;$O~oqh^cfz_CsOAd)1H?jwL;Mz}2Q~Ti#p~9>ui>R6sv@fb#H=Ux3!*Xpiws8P7vRn4!ds#ng}***|j-`;udHZ(1bC?TDm){;?**F2_fZmMf+(<i43?*THOmu9-5QLc} zgj6#HG{M5wh!k`M9ZtLhknSr`6)~g=LC)9&Pg`v;Tq>m_G4Omvob|BhPW0(NAf;nplfpn21@UQKQgM*@!IN|B9k~&RaaHfhVt$--)*#3ctDl( z9bK84L{wLBrmto^pwt)KF@kNf8V_|Kd|-fXckLmwpOu@aOjvp4)S-qZ4454~ktGU( zd}zKNX|yq_DjKV58pulq5cQ0Q?u?v4;{h4(LvV8-G4bK=H$&`-I>nft5$Eiu2R+7E5pELXLe1g4LH9Drc=<%V}W(h2`TSHB) zau_ij=9PLn9JaYQ93mZzLn}kz;gJn0^+oKX2U)BQz(~!?H0SwP=e5;fQuhT9a92OW znMRLaYWkyDwL%Ik=OXjIu&nb?!Qz%0G-lBX*3NE5SNwBb;{d&*XfXaoyz zq2pQRc<1IGh3eWCVkNqe%b3=dDq{_tFQis%Is$L}LXPt8aDRwI+V*aYcbM^M+=La= z>X1y?!+z)nf<_f@MIu$3$CI#TSGw!Y7mkT4!qzu7RYrvOPJ+T~HadvAu-0N~vKp+q zWx|Asdf4x=0E<{n^;NZU=IHDVwp@6l!>so>jVRMLpG!vFuS6qRSxd{S#g04ZdQIUr z5L}KE8{O@dG-2nEIuV?g}USN7mvaosk#^jR~_r5T`;0yHm-(#ox|mL)Y@K6 z5nE~&EvAEiv42Eb4|9$680|tT;Cj6XVFJ-tigI?M7OL$%n-Deh)=b2*4E=^`OTC2l zh~>@z*yRyn8C;kYO@BLV0FMHH}qRym6%LaF=J4 zrE&4X;Uh+*6L@-Gq_ZrG?1O0LdKD0!F`;F2K9`E&F2{C*p(E{v;T`)xbkK0C>Dm28 zL@qVUA7)`4P}=Iajto0FXHxnCW0YRk$`+e$T+cR@w6)~J9Na0Oin6+z$_ntu z+&9SXfr_-*IdF=4Y5>;@Hx`waP+O$3I~vZdYsA`8g&Ad&RU0s`SRa!4vsdnL7}wk& zNo2py>k-^2k|np-Kx%*;zEqd_u*{>~Agd?Aec`^$kgasotM(0ePFv6Iz+L;j$HjEU ze6}HE;)K%O@}c+3hR>IbJ<8j-io%@VI{<(`OXTD4HHDEh(K@GHd$G;I#Ft`ZmnPbLxW~8>h9Og!CGu zdpdf1rmg9lK8xw@-uA(1*dLgS&4ks+80_4zekHKIe^uvPd@taf6Q{LLS>HEhpkvh( zPrMg`uX}TGwJ& zV6WCeRL^t5Q$O7>oWsbBKxeo;yS5e!Nbj;^_=V+0AGUeC^EX{we0>2i1 zvuV0WvEk#H%x-CHcTyH{Q8(~!l37c*RcQODKCIfOdU1i8tlY#+JlcezUvBxREefcgB=vMiwMPY$M#|JRF2OvYn&V#u;;eyNvG6;tHn6@_pcX*k zZX^TD(z>?!ys^d|D$ZNf$FOlu_Bl7XHwGYOG!sly)kv?mQ`G%dqp$0n-a*e-x~h9u zZQznBdv~b7P&>JjWrK(4Es^FddFT{ePw$;77lu! zTTeW+x|n%<;oE4%QJ#)(H>vxxtTkFuHHnPaT<+0@$7eMW9Cn98Rvfw)tnNLxhmE3d zrPED^FOPTRaicw2XMO1k=QM%CZHQtsffpLx*K+1wR6TB zd*Z=fL(2UUj%>a<=yiC-T729XLjd>guao^7kJ!)@P_jM;b zl3XthbQ_=nq#QQ^hN-VLk&P~4D@?q0mF~=kBe)V@&ATLO^8rL!alJFhd%fX(LGL6} z=@Gqy6Fr;Y9Xte@VFKbt1@5(l@9Qgh)rP*7ocGbfi`e1zQv)IERWho`rSA@^epI!% zr4_r7*ti+Cp`bbm9`0!14kzy7!QIuco6&R_T|$i$L}9bzNcI zXew>J^d+FLIv#yx(roKOO<%z`ZK+$d2Hyp4I44f4F#K^b6#+BW7l#LO@#S`Nq?u`D znWM~XGsn!e^UVTtvRO?nhacV?+c^5U_bMKM^Cs~HWA(+_aGs@J-V{zEW%C8;subJU zhxGW!Wt`c{#_k&!nD!ocMWQzeelf$^1n-!Rx*i+FKh~H63QEm7eE4dydU;G(4Sdzu zbKocHJt=fb8(a#Q3(b|#2GSVXnoLR=mDE=d(u4hK^&s6lma5LlO1D?Y&@XBY;VHw#` z{Ifk*S$|Fx|D34nxl!q{QT)b6UC)c+mlt(?TvWOsik~-1P`(LK{3a;+spy0HnBbl$ zw4%6K#-ym6Nm2Cl#>ipucQ8GNrGND*oMRd6&5^@0_)d|?VX5CH@}_4+5;(Jrh-dJE zWtc2a}TDsxd|ZCcSfZjj!HilmHtCi`X5p0So9Tk7sldL zM30G*X8cVxGL0Hul!Nu36_p;0N?#e3#!ElK2g^SgmHtIk`YoiH#h9K7|NSKDx*u{e zi*Y^G$TP-<`--;D^r&=oRQj~2^w~(0ALD*1{PB{g>)(n>bKLeWW3Z}HxC>S&f zR(~OX0acC3Uzi_Yot#yBAv3 z#~b@4-bsl&ap&U(YQi685q>hjYX|-KG3SM9Ifp8bbJg8z@#rGe$j#v|UXT?U^>In{ zE{l+cGmj&?eq!efOBH=H$1U&KXN;0rH9+`j3)f=mp)3^E>P6q6@hBks3&>Hc4bM}y z9wHH6?l`#3F0);?5+U+fPqhW_Rtu|Pn?o1{@&2ZA{bO5k6}oQ|Ynfk(w|x++@Eat= zYW(gju?9adEeJ3sUH581SkDnhEB%jIdQ10?Wy^OAL;M+(n$M5J6 z{dh}{;P;8B{AoePGV1ZZ;6I6|Ckq{z`I80b2+kK=LWF*dRiyj6Ac`B4-65RDVcH!+ zk>+Sg`xFu(X9=;~FxC+34WozHfZx3%Vrc&caiNaUadrCFT&T~x%!iWcthb3jwGC{> z9Gi%8Wkk^PjZ)P2Dk5IxelHRHA0nc@mxE)jhGMg$+mMCS9D98{nhI{~NUN0lfC zkI54>(ixzdvd0;M>jbYS;+1mB?yaboX`s?$3Dy>@7loDGfl3dcvOCIgnj5#&Fg6om zw@ZnTSLp?LuVcF0Fm542zq^Rgubg^R;+K|)%kVpoMDXQ%I+?#q@^?!<#4;vN;U^C0 z!`Vz+o3s7V3tqu_4AM+Ki1d|mJz!4Cx0E7egx741Ymxq_1g z+3w7rC)gmkOz=#>EDyjJj5!TSXt7kpOmRlz?B{*U0Nf-$z1FF|mO;4Hx^ zLA<$K>2apuI>B=VFBRM_c#GhDf{zLQT<{gaw*}u9{6x@?v5|I96ATJY6D$*~7d%aH zo!~iw=LudexI=K4;P(W7B>0@*Yl43g{F~sv1rrdfDBozo$%1nP=Lxn7t`J-=xLNRW z!AAtS{3qXB!2-d_f+d2p1o>h;(pL)37iZ?g6)E91=kA>2yPPGB6ykLHwCu~en;?T z!8-)+5qv=K5y2k|{#5We!IuPI75uH>+k$@; z%oCg_I8AVd;7Nj~3f2hL3oa5|DtM;gD#0$nUcn85{1I)+cah-bf>#Uf5WG?FR>AKI z-Y58=;G=?13O*zF3&CFrzApHd;GYB!2>y@Y2ZEmnelF->B1^gB1xE;G3XT!vk7|={ zlHgpyD#1FzCc(vmrwg_Vt`%G_I3T!5aEst&g5MO}F8Ccm{)RN=xkK!IK0}6|51g7hEK`RPao}Rf1iDy@DGA&l9{z@N&Vc1$PMED0r*jcLnbgVNOpzNrIyVs|4!=n*&FZhh$F9cr^d`s{h!T%BbSnzYfK#Jx+R&c!F6v63&CkoCLtP-pfY!X}|c&6ZL z!LtSX1vd$96}(*V8o}=f?h?F5@FBq;3;s;-CBa_{zAboA@TlNF1ufiWpj{IMX9-pb zHVd99xK8j~!Ak|V3*I7lpWtJHKNoyO@NL2O1wRqwuhvkWG{K-?vEV6!3kBB*4hVi- z@Gik;1>Y6qO)2uv5S%JlDY#6qM{tMW_XJ-O{EOfxg2}kuLcZe#PZnG!xK(hM;A4U> z2>wR!9l@i530O;$?2|?2lK(YHZxGxp`IkxhO2O|44hileqQ3hi z{ea-ZMC>CxDc7Hu{1*lH6QS=PP82z^(|_4ShfHNkTv{~}3WCio2^ z%I%W$or3pD{!avdCHTHzAX}G9B0{cQBJ|1^oFZ5(IFmRB@)IeiV5j77B%=KJf|m(i zDR>QWj$sTDQT{Q(7X^P$gxwAb`bX>ZNWlWZ65@U zmi!weeUspAl7GLX_XzG4d`9pU!Cwo$MJ&UWpQSJ%BrzQUtBK-5$ zf^Q4{MeraI<&R4GBf-yz;Adl_p4XF!;FBhZ-;z-2px}5S=t_www^;CW$v>Nj^1Xr^ z1%LLaE!GC}VJ{J{m~9wWOZq!R z@EH=kSMd9SKNj38_%kB-ye#Qg1pg%XSHZ(X&>bN{htDM)o3HCj6ig+8E=STq!SRw` zEa@47vn9V$(zSy1lD}Be%LUIOqW(ciZxsBx;5P)nMFia)f{zNmA^4u)$3)0$j03`M zw%`cCk%GBI@GBs~-)2buiGt;V)q)EJ7YQyUqWsqchXfxaqTWXYpAmdc@I@lZ{Za5k z!PEjR$7mwtA5R3INrJNk=Ll92!KaQ0`Ikxl8G;>xU4s3B=LnupMEPxk_X@ryc!-Gl z|0eh^K|Z9!e20kgqXef3Rtug+1l?JJ-GY6B8;B@>rQpqi-xqvd@OOeo1QXC_XrB?p z5{wIy=Dl3jS0p$?^5;srLaQxLopANqVhdx8$EA>CJ*$B>zfDUoCj87EBZzA($3O;uNJ(X2)dhy;CsL1?-6`l@JYd^iJB>0@*n}P=g|1CJu)O?x*Hwp4N zG}gCGa7gfO!H0Awr+Sh~FW zRY6>zA?Z^D7YHsTVk{UG+%5Q=;BN#!5=^u;{Y1g#g4YWEOz>}lDX<0k&lFrOc&*^w zf`1VV`Zaxn;2Obi2;MFDq~Lpk=`p$-e_K)2Cs;06FStZ-rJ#B~1oCZ?^reE|5*!lT zE%=1s%YttS{x5L?p2rVp981i`eu&_$fe&wb!}axCbA*gq7UDY#7VYl1rj)$<&n z|FNWB5`07OZQ?BK2TJ-wLG?Ta%8iWE^-U5yS+G{HMQ}M0d{#=jSMU-+^;`t_-6!e2 zM8v{h3my>+#OwUAg6eq#(48jf^99v&0LZ^z(r*Y_@Llpv7R(l$AUIvHOmMznt6)fQ zo!|z+iv+I`yj}2zf-eaEPVk`Mhk~CA#wBX`Mi61IY)Py8+(=KBw7Q?2hUYJt2JRCa zO48}ek~QuWRQEeUcVCLmpNT-ma!rC42|h3QvEYnUO?R%~^@8^bJ|XzL;H!df3my{u zSkOeBtT$0`g5WB_3k0_d-XZva;Ex2K72GfQd%=T(9}1#7D?37M6-Tp(ur*vw$x%o| zzky4reuE)I^}BN76ntlch>I|hUr`)t6^CVp&$luZB_*6xN9TpIw_aY+fx|9ex&mtn8@%d=V$M3L^?<@<5@`;Ss zDE}7YFUqUuw^05Ti3dNRf1~^%BFeu(e?ocO{xp1Z^>-`DN3{des@=eEP_Azzg6~a| z-bDoe$0Yp(F=!a?NctcV^%=AS_}N6%TO#S1u6>FIHm%2tW{e`d&QxQkdxqEH3>ro1 zT^U6y2k@J-c%6F@GmF0X^_!xKmW4&Q)V}gdDOg%lb*Hx)mQHM~e zI)?pjK{Wf}7mvevI6;&F@GX(!d>hC8uFmlU{Vz%=p^s1Jep4k{i~m4<9JT(7633Ne z_;+{ylN?dh|AidKDKT7*=r0C+sR&;n{HofIOFX>ds4okBX}!^OUsdh#XjgZv+^`mI zwWb%{Qk}Q2T-nbb!6ql2gBQy1r!b_q3KhQQj~6F<$@=kg5z%D$mFo_dF=Bv$U(R07 z*Q|KUt>Mow=$^=T|97q2FbKx~{ejz&3`yZ{JF-hX1UO@tMUj45*{r!;2YilH(`N`z}^g z;DrRsyY;!a4td^s%TaF%@>nmX(&2i4h;#DBFr$w7yS%?OqUCTvo?^JwuM`HM9+*~#^>{3b-y`LCX2%r@bS}RaqUgR}gSC;{$vt%Z z-j=uC-M>V?bacH%o_hZf#qZ+fxL1qo?%~$^W)#0=`}J5xJ+K@J>v1%S-<#mq?=}wT zTz>rim{-1C;K%R$kzc8Yp934XWsq$&oM9MS++cvTd(8x$m)|iAJmt7few+i)lx(*V z!jCfZ_$4MGM+@{hKgo~(IZ<>^VBuOz0y$i|NkZr5+c)Anv93_a#AS7i$B9?I*{>SL zR$QTcv+++l%E#}^!8Cn1RmX~*n#N7Ltcf188aILNDYP%gkaGN!Ukd(NC-{YrGj`z_ z1y4bjAIByy-D8limQ3Vu=`hJ()7`PLXjM^faS+G!6KBqxQ8N9+(iu1}DJk)M&YC$h z7(B7Gtm@E)?W^o(_I?mRKIn=7&m3b0d7Fx z*t6%}t!bT$9yCujrlhSf-!y`K^Dgd8?QA(V&gh$G&PZEvap#C@zFGOvTSrxiJ$v?S zjd>(1pLJS$&OBy+s`(g~`j9{BOY*b7B!BdA^JhO|jM4aEYHj>*+W*w0dAwFmGt6#vmIeq7`EbvZGc{Qf|==QBy`EMReF&0%( z(yaWgwMJp{{uTA*e~(XHQD+5xJ3{p){tf(-;}Z z{_SJ)AGCMuI?(i?F+xjV6h5$zHA99EwnK*WVCv&YmpD6|p}@`;j@czIKKPx=%>55_ zmejttF}3rjA8a*Sj!i5N+{;?dcraM|#yoon7BGUfH_W3wY~zJv3BkY(@q3;;c;s8u z$M>me25T#hWi`CFal{eR%--w2(a!fPk7A8ku)6uF?_zzm@>qI8_Fni^eoVfW(MuEh z=aok*j|Fm4kJ&ku$5ImVz|V*C7mlTDr7UlvEw)wqe$R7XEnDVINMn{#rb8QJhEk8% z$q9SSyrv_cPajonObTq@`*Fbo7aXvMDF302sYiUtw1>UV8M-Lz#>!Lw(f2_5P*$~1 zwaH5d(uZEjX6tmRK4xMTF^*1!V>2cS-u$hsJN4h`eC!)yLMYAO$!!KZ9I*$H*gQU~vD){EAv# zHa&m*Hvcv^HGZ45P3Nbed<@QCJC?PL97^(I(3i%`)tUJhds5@KZH<|~cWHI7_VH@c z-g6jxnkYY7l}|rTc_Z)Q+L@?X*HsZSep__;oNbRCHIk?AOFY^gZz^5L*_WTNZTvQB z#uWN&RU*=)9J}v^N_+ox$EK8|9kH$R_Zj2H?3nQ5g?~&BmmR4zb<0LHz4Acf(Z2W> z44@QE?Y*P3xHj?Vb%C6{+1L1veqMS< z=jdy8R@S_l_@IC2^K4kUBv|`aOzZ2EaLj#X?Mv?&KbTWHMPiQgN3#fgtT8)Y-)~I3 zy_58**Fa`)2DcOJo#tf!{y)Unuf285C^@FCDYDnkS5dXI+gPYslCUGeo(@5BX~SH^x_w zt-kdD)AyWz+Be$pQNZC1Y=+*4N&e$E3hMXO7pW;6A4+ISAHC@7;Qs8fgr@>K%^6vcLp}nImmEcF3w8yJM2{O{X^N!Q7!_v~~J^ z=LXW-JI4%}lVST{`H_tm`EE2Ol^+?rh%NbQcJj?^i-YfG*Xhxjp5?E7=7X(P%8tSZ zbMGA`Twgt4)?SpaY4Wx`^$;dVM@lYoh6?@^iE3YcmM)hW8?$R$j%AI$y0ZL;bl><9miO-;dkafawprO@uV06F zA@boYrZ#WeR+;zYZS&V&Ea#cqG)>Hrr>Zh{{@|z)8o7Vsk*DVM9$8U!Yi07jM~`j| zonC+Y-sg^PSsU}wmWeSRe}3-Ls>?sMW`Caf+~LkFKg#J+6OKGp%Tl+X)DKZ=Axb@a zbjuq5M_VTNKmPojzN)RCT63PteCqJJ?6jetuJoN_Z@p#oeO%XwNF`BUp-|d zEo_WiP&-{T^bP&~*w(FS%0_ed#SLleA|B-BX2lQHVg`7_ybRQ)YxY;4Se9`_twKEh*SoG?&=YbFj8`^Kg^VMH?mCPGglZwQU2N$A zw4O>`R6F&+{Mv6Hu!e4^zWZ<>=H&z9;pg=AwCXF~WpqCE!|C69>Db`b)BbAg9edf~ zMRdzO4@})^)!Pf+TEBCJk^kn3zIn!8uQzkfobrf~uSeb>=6FvYOer_%VTx|gp50sf z9}QO#!C}=gy?e zc_^A|`fnbC)CLnDQ?j_u$@MvJ;$EuLg-uT9q*3ctR?Ig@^~WjrSeUhyS+;X&9#V&x z)ii2{%8Hp=fGYtf4|AUdw!_z7m*0jf&MBj@zmlHHrKR%+ERXzIX^l89d>kL;{BW+u zQqNzI-p=#i_;EfpZII`4FrD(3q+gEndfRyzWn+GwISr}YfPF8njW8*5U{+E-G%%mW zeR;z?5lWg66ov@QvACz~oIe@o%d=0#c_ClGl=bmM?2yM!&jF3~a6VS0r8%Ewp|G_A z_KKa6@=gp^tkx=QK*r*WUZYUj;!Dk9PsnhPNU+AB?$|jAAD~EzwE}C^*i(}ECX;mQ z9mo)SY8t;bS77}cJ7%%vDXgY&)b-G@g13{+W^>d_SnpS=#3FOlzrdhMC0fi;H^BPU zD$#0=dI1b-nDDomqqy9!RaZ_kN8Jz0&r^xh%~1!j+dp3=u+(=BL!rRwsZ2Xdz&db7 z>H(flhtPquMks^t%)|K#ef|V#RtEV7p+de^XwrVR{ZXvc1FLiR9-&EFXheSVG_WRj z3p17kkzr0pMrY18WMusq7H){E9Sa?;Eab=4jXWUGOj@x$F{gx8P}A#2&~hs zTVTn!*CIX zwAHFb;?7nrGT(4sqpDrODIm|PK)d9`x9y;4EFZr(gJ1GAtRI3X{xrqRwyuF!#h;P6 z2DiBbRsuAL?@msH-zHdocwPKp@&qJOtn2X^e_Qe#K)Urluk2QdEW^11ej8X9#w)jkP{6wX6!1@8q8$VUdv6!M2i#e2Nvs7ZX za;f;ask@=Td}}q;IaMj$V0FMj-g{zh_GsmD@lYypY(Y5^2^JrIObn_-iWP$xkeF9+ zHm;-_(+{$tYRnuzbj+GsioB$8Z8*0A&^@Ujc^k+KD;1uZr0r~5x$u&t3CidJ>q>ZT z(nOU=umW)Uq)Dm=r5Mu(gJ3<+9Ni9flb(Rs)2rA%_2$@($SLF#ds*Ly%sI)+o@I^S zMPnu}&wNH{_B3*mPjmS~mgLiwEGgF2Xw&2~ly9V4d~7lK%z|%2$}A%_V2@>6Wo|U= zplTZ?YuhCNN42QoL|yhxoV z7*00KXBS&X!K9EJ^pKGTjWswqCz%UtIKzkYH2*_-je}Sv|%nO5% z)^IME1QSh4`5rDizd=>0WhoO;z&{lq1!efKS>EQE;h&FBOa^9-heaxIo@%A7yZ~tZ z934Mxl?ob$^;h)bwACtMX7X2m(>hebhcP@Em)2MdQAW#`wl#?{-CTgqXqYEKZ_`vS zv@i?NWBuk&(K}n;G~_Fel+N(d6sIg60jVHfU1&Jo5^4kbH9t#*=a8ghHrqo;(4M zF`0|t2NO&a`4i3A=&=*c523~glMmXb7|vgyOxn}dm4MWQ^ksDFao3{Hr!UtX$0%L3 z#z@x=9te!%FrR+9x|EVqdajXvraljrb{gqt>GP6tKg|GDNTbqIX8sg>6flU` z%59vd;fTpCsS|l^Dn1kg#uas47@UI2liN}nNVEta1??nI9~=S={{Z@npD$x`7T_#- zN&2}YJs%&52XLKX#^#CU=jW*7zY+1yxg35ua#Z4N$k5J_k(=})sLfxYVGQ$Y1$2(L z&@evpNi;2-_a~4gW1Mvth#db+oKFtEgY&G%V2Ol`bF(mHTAxft{>IUK8?Hu(x(IHZu{rBvBm#!>9@;cxN=^aFWL-ZIdSz_A3g?-tx;Gmc7v+|~ZWzbVAaus%DiKg|Gvf-CNXYE%8!$4yk^Tl`NwNM7i8HQB*@;As6@ZB|u1RHg3L4JY ztaEDq&8Vl4m1TVlznPkG!$}ay8bUY9xN+3;I5(_$@a~MAS$|N1zXlh|7#htNECsAC z7&+tSOy0Fiu=b$`XWWw6ibRU_D7+@))@)AQ(=8jWoUtqGG9cSsaid?Q@OcgMs-^+Fh!scHE&5Mk1yk+Aq*ijYyPL&pVV zQj)R~7yW#ZRU+qB{MW9d{43Y={Q!Z<*@B>$F+GLP+4|Wa1#BA+ox?X3Wt8Ugg;oBC z@sYRyAGCx08e~u(hVukfot^p`iTH}D3fAEyz)3PrNjb#a|HX%r<1?Jt{J{DFR(6)A zfv74a8A|%osVR-82&5zY3A7n?xg{hx0UwEt_~5@LQc@_D{A?-bUsR}BkvspSQI@2f z&7ytyD4@l4F~vX?bN-CMEaUW)?WDS%RBVc9=FTN_=@m*&X9QiPBbP6g@;{FcB@&y- zEBB)`+}RTklIVX(#O}l9^RQO2Kugg?r|Qql1c5&XABj`&!GA@Ll>>Y74X~J>Be-)r z8a*>Ny_V$l_^4nnc5a!1++fNX%x%XeLRoq$ zXjsdqB9WKQ3$}H5G7|YJ5itB@(2*17((Z7A!f++>UOPZLY!9(PjmvDmkW! zslynv9L^9l`D8|($$QuNW-eqKXFi9fD=>@GIb8l3loQN%V3&#JbktjD9)O=sGVefJ zPd0xAji#8_U`U;6K8c)Z=C5GQ|3lrIz}Hn(`{QTdbMDR9ByEz8X?xSAX=$6JGo^G& zo3u@vCTWHaOqVo68%UFoq=iChnLz}khzJN&5s>L2@~Q$Nq9RXuh$x~6iadXah)h0F z5fOgh@7n8}d+u%V_xw+v&p)4>``zQ(d#}Cr+G`K@+&N}EN||d;gL|Gi4-8mfE=21V znj!SjV)Io9*>R=^>VApYTY+>F{*1QNn-R#h(ab_AP3C9dz$Wuum~qX9 z1GmN8fjYOEA3=V$nxDeG&D;xKonZJq_!CVH`s*a~Z>agn<^Tlo6f-izaS~=SXr5}0 z1-IMHJNVpgGQq13^ErHWnrFbJZu5Gnsue#7*W zW)jrE73L46#8!aNNDsY(R~Y2+Em`IbRN67EAYn`ini?^?zz)}V zD8@4$$VJWHkS1pMWws3SEifq4B(f;P_raZQa?k-e<_~2Q_*?v8H7nMSM5JbiBDA&7NRB zfhLuhZ$d;SnzzxBlS~!rGueC@6yjzl(wCZAv~G%lJVV@{0b9!qUpO$$@N4Vk<|}CK zbn`YkY=-$EQXXSo1^Z^2H7I?S*@;qSoA=SR73NxWQl-g3NR=su=*%&{K#6lr8(KHd zoR6-WZ_Yq53(W0c%_An1>Lu(o8{F)n*Tr!m4SbF<_kY@)v+X=oIk3GmfV3aTDOrsIetyaW(9I z3q(uy7H|>jOzi}{lC!Nf|M{sMs9(uB)`w;IPeG#OTz3L;S@kt>O5RuDG1sshGaoH8 z<~Y8hCxA?j;Y$m!6q}4% zPMqUzOO~@R??smLW%QXbP2en67ksnU#KkVx3|gCIc^T+h(~W96W&>o&n7@EJ(*6=c zIkDR1nj-oEM$*KZiIb6Z?61+~3ntd`rD^VHh|9z^*<9&3?v1GJ#IniLt2sh4olov$k(5Zbtj@O6B`Pzho{8l zH`pdN7Jdz$xceFjY|8r)JZ0`V7+({c3;znw3^#+-Y!TA4W#43Co2-rJSS#lh6z1{6 zi522A#wLgb&x%Qetl~WK&56CmSaua_YGeO|a3_`vzeKD{iLmw=XMB$lPK?gjG(Rz0 zm84?rv`}Kc8%~I_!J%}Lgk9vssO%&O*$_%%OS_q|tRVSfW9^dk8-6yv&MlNpyd>|$ z*nhE~B082_#b;OLQ8Acz&<~FJ4Mv(V)sT{id4)?0(+thxna^NUM9r}nOEJ@h?#nPW z;8>=a3;E45=VVY$Po7RW?L`@o(-%=n_A-~Rl8bTMFm@3JT5Jd((I!Z~J5}~mW8CbF zZD$ns`K->Iv^MrOYb4iV^9PX{9w&bn#FYY@|80y7P;m02>_5kI^1sTuW0xU+@&Yr5w~->ZRw3}~N}$8BYkKtf|yO<_B4MZG=qF!X4qSqL#JFimJ}+}s8|w9@3w zhnkp{g$g-l+DmajWZG=-#BrzXs04V^W)U){{Txhi3a0h3Qt@fufU0y>PJ4m*&dXm9 zft5!5_f$I2h=)mnb-x+(k=@C^BTh$wlRpNU8zh|kh2l8R$zLxH$K?NU5u=<)e(YFr zc=_v~F7TI`e@KdO3i2PYj(GmrHfp64{T6sT={%QQjd61%#v9hLpCdHJ9m*J$V6+uX zn!KohqGfePyd>{rJ6}8{?p(_A0`bJ%Z(<6{T_~P1_ZlWU zcFGH=&J6eDh43sEEi~JSLVldw!-&be3518#;S<@}q}&2tZ9q~+Wvo=kUE9G(Yc(>>Sa8!B@S z%T7Rndk7+!^HtjsPV^_>OwQL_zKd^E$<&E4blI5gyStsKlXPG9Cn#^~UOaYl_To5+{hxxWU9veNu~)WLC2o)6EI+&{zZxu3%{ zT{cxbnQk@GmX+mEV9^E7R>C*UCB0FZ(+r)!27fdtdTO`?7mp{r-zEud6x!o9@<#xAjhC31*EVsLLv)xBgg>t(cJ;xo1 z;aPsN5Ln=z&vH(YqlA_2V%F_ciK%h<{oeBSQCFb`O)kIGUA|pT1zX*N=#TPFk&LZw z37gP0hHX2^EoC{~Qk_#>17?=*lw_Um64ts$JUd;!s;vCdJTJS?LTQx`i|4%p zzKZ2cX-DKQ0CS^rS$e;Q?L^Pbx=GHngagb!e_+uh$)zGtmE8JOsRX!6x2gR zZj$OeZwjslt8N)d3+EM6Z~%4t<`^pCv5|t8p!vT&aU2+07AaT(9y}-1W<&}`g22zD z2D2jt6u93@%$$f5qdXoHfds{hkTHrlr~GyIZiF^1MGuz0S1}3UqdYT~@56JSf_$2B z#XJFU+^?cxX1sWe+l^>5K|GOpxT@!v64A_N?9>Rfm6>RLh@?cqyD7r($Q8eA|7q z`$a#*dkCT4Szx&{tFa8zZJYb8Adc+zb`iixXY>#*W&*5XmQ_T+(x$$BS>oC zQIeJBJ1~DD&2Ci?$0Hhz`vc^4`W8d$&E|WN`Q(G!n@;%`Ap|qd&Sk5*nTQ`wY>7cT zZh=yte!!d?1ebr)MT!Gi%>HQ!MafS2qY!5AED60U2%Z0DXbbO3zHQL^U^G6M$(jFs zaLBvlxzy0gU7$O?$OwrygakgE%4Zln(FVIykWnf(|0z%&b>cA$2o86=FCc?mAkeVh zIORn%u$-w4wb&2C({0c{VsXYp?LB2xHwcqE$+fYY=?gWGLm4kpgKAN{Zt#H~j$d3-SAUh*?42Ln&cS#H`JJKVy~S972MK zX^QN|=O#19$pjULJ^1fIgp-AiaNesmP{fmy>mPr&~$9w$bQHGek_V$T^2Hf&7cF*j8sZ3W*+^PHK*@juc) zrQoUHvCDI2iDZMnfnje$fj?*J8OGP{bTEvX>p8QXVIRQHbJ>cGg_sD;G**DGFW7-+ z;g0qJge_s%1@Q03Q`Lk_HMMY@;5&xZ;k0DHXg15t2-7$ndrfRQeAC(X$=!4=lJK8X z=PxtWEWU6gx*MLY;<*PLfu~PAU!iBYDHG3K)Y{9&A+Q>A3cYyXFO)+uc~vWW4@+I3ZTZ#!|EAB&o``R(fA?9>^H?M ze^Ksk=mc|(nZTU{{>5k>K2{IEkpnmWe!JPIe+Ii5Wm?SnIRsUPt;1uxxZ~49`r6-Rs9w>ZZcSO^c$ZAboF0 ztCqvNm_euD<4plO|)wLzJB?$mX%MaiXS}roz7?-CcN&uZQPk%sI!_<0IQl>54nf%ZPX$&xH9k z_IEdp!+~rH%*tgLml+!oj9m!lL!`;5h9?i6Y&qcqNiA$CGggo_aXeFud{9MQA`vR;LQ76O`T=3^?dqdQ`n-RvBL^D^~E&c(Q|M%qZ^ zTrcWk&ZR3e>Q03V2P~r@Nt_ox#SZyQ5%<|;;P#;|y?7SOy~%?sV?IkKG^|jC@2o^V z6E#!bV2gSYycZeH#FLSL=VCZ6#FN8h*?SSf7F_{PvWHM__ux9vZjNM~kC?SDp}`-3 zoR+rvb@=^~i{Gw+lp__?51u!Q+aX~YSy1{{qnNAkWc&juZh_-QJUL91U5sd!J02dt z+&v(PsT-y8TBB3E9l5|sCnCQL`eyM%q`MD+_k+xRcrpgyc?6D!@#JtvEc-HqkS=+5 z6uOw*aL*DSG^l+$CY|!J7^g)qrDn%M^P$qEEzAGy>Z49!c>qymvE*@7upug1CtK z8=m7IL8tJwq_d%*?;m+uoQ-+pK+)fk`I|DKa^*b+PbMXvCT#?%Rq``w4PA!@&DAj5 z`DY@&g?1>$c;p-z;H;#RNu%ig>5kJGkdSe9^#P>!4nDp=#vIc>!jtnP8a{_d>T`a`j~DpyE$C$ABnRdB4tlYJ6A?!ns*WcP^U&I5UT zh4nT>wcuHHAw0iE$zvc~d6&U+CPMr1eTuSk0?M^3*zvNnUd_2-pkb5TwvBzHaZa^5_6s*!gYo)eeB<3u5EfW?T-UXB0~ zoG=M&jv*%Ej7CoLX*2RJR^?a()1q&|lQ9dPQ{gxTkCVyNrC|g6C{F z&cc(!WZ8d5h_Lt$WKChQ%%PFY)6n<{cOVsC@(^(O-5+~42-E`kW*LcjCmiD)ynlZTCITYaksb!0ZLO1ey@v67JAT-02;&ae zvLKA|W2JsCQnj#Y4@*gCK(n6;ocO*3qGG*%Ad(9wej+jF9f)0$9+R8FDubn;^J740 ztOSB_U-bi((Bg850kdswEqQEeptCrWy)WrE+1bc6dk0^$vl6v3Emim6ofrV)k(#qo z9wr*n8HSk8Kp2fG>t~B0{OEwg5GPK0rv_;e=fXa*d`4@ormz^_La~)a2V$&_`ITE;jtjb8O*@S z`-qe|gN=ZP)_e{V=?n%w55jk}IztGY;@4N%Rf^;M7ra+a`4lO8&^BX1Xf&RT_mH9t zjwz(fMA-$Rj6nH{bjq-iAV#K^l*b{}HE=|nH}UzY=HHX@d<0g3Pz9ch>F^v62d|pu zFj4jjpYo0HrPNs|*C4$3PHe^94+o|MJl9NbIS$00K;Rk>sv+fv;Aw@UiIkZr?^%TG zgs&4%-plapgX1iE-h}6BIIh4m;Y?J3q$9XHfQ}hu#vEDj;wKV(Y_M#u5&#;KUdsO!d$dp4?4V|EsOTs;JB59nMfAxLU`TL z3D0wMeD@;W?)zNX`h61S`2I5J{2K{#e18Luhe(*4L&@>I=jeoGcvB_qLwv-!AD^F! zmtr0emGlJYJWj$?Nk4&uM{PMwlvGI<9i1>WQs!;=;F5762COm+HAL)@&Be*E<$Ra$*O3?Wv%cuw?v&qIaVI=5K(YDM3`@gV@%K0c z1jXXpUg+j<%ekZQUue{ect*Pwh#sE*5K{3=J|7`W4m&Q5qru1&%{4m}yv06aLNo~+Zikm|?b zRMs+MGr&gYi->+FC7O#CwsJXm>HHPZ>8v(f83?DpHxWN}f>g@s>w=bc38xREmiOWr z&7B$3wS-$UyixpfJi_Th@NgKJK9?+a^hD^9%@5?ilpBJ4#O)em@SLLiHSvlHDRRn%DWA>8H$w&#@%AJhUWn zOp+w&n3g2TNSLG>Ch7SkzexM=p2!%A9}OEJiGXA+;gMR7hbjGUkQem2{oaJECqY+vxR-3u9r++efO7PZ-K zh-^xhc0=S;zqHT!*+xQvMLr#w#13x{vVA(TKAG*)k!^mq&-mGH&PKNLA`|)5i|d1I z=S9{fvz-^&;%B?S&&Ds5MK+l@yXr?lwoRrXnQfCf+0WKul#?e`AlnApr?G0kZ5zy* zWVQ{a&Cj+`vn_aOB(gmz!sXx(q6{6w^HCY&ktZeldkB6P&uB_pNmo_ zK?{E3Uo04g{DM2mQ1GK^1@j2n7X0X17Tk*hb_NAMx|s!k0)GA$0bBgozgTb`3f?*e z1wWWp@asXr56bAf0|nd~6#SqJLjKVEx3u7g|HXpW;R4}JklP2SK4@c?P<=!mkisTP ze?B0EOxfccmN8j+7Y5h8Oir82Ccn3uOtH!DZ6Y&}{63p}8m5oWGdYc6oBZ>ulF2{6 zNt54dlV4e`8_nF=u*t6tQNPxwew|Ie9}?F|>fB_p$vZ_fY-Kt{Bv6@doBR|s^%N%O z0g+99N+|g$e)3aoa{eUW0w(AAm`%PQ#F+&?XBOGyUvMFgOujuxUKvVW=_j9KlfQ+O zGnkyGU6%Tcl}XObXjIP3w8?)8H8X|DdAMeiPZ9NLn>t0bCz@JjlXF|Ggvn_O+TOPvuxdCUBkCv+#mip)ht;|?SehTlddZ!n;HAp=%7b?j+y@I!IO7KQO zxNGGYH$mf)k7H)Q=qSm7fY&*ZvHLmOj6leeoa1wj%c(0|j2JKK)D>b=aC9gfTY>pb zPN~O;jHolWFf!)rtHxkDU1!cU2MYNM8(G!~8)gCHK{+SKv>{FI0!t{$0;p<_%J~@X{gB7RBr!r?=xW{Ze=Ldwqq@WTDv{9%8iH|g+Vk^gElI1+ zBEF^^Uxy>RQ!Bby`vW^2wl^d?o#+xjD=IOfP6o#D92o3?r5sA!iHBg?kmaO#ff>h! zuF(367_$N4x~^O(y-;23us|H{Nc&4CSc%7-Xk+Xkt0_goDs+1-D^gduU>wKhnjD%!7n>Ox#g%dmnPX{O~BLLMjNwT&5R3NWJAtBAsgzy!~4hSftqI~&LN zV^YQyzJ%zD6f4*$BPg02!cD>$RXi&oB3QzsW=?Zh>cUNK2}i`GjMf~fd0Uti&Rf|c zobrZyI!tIQk_Q7&rEVMhfQhiz7x01pt--iG(N98VokVfejyk#02@fB?D9mu-8rT{q zn0D#7zB~?a=XqEQQOASJ{-JazV0=}l$;*nHHVHghSW4y3(Uan*|veZQ8Q3x6(nf;*gQxG&|2I*|3)DAjYp@(X

=z|9w!P^b_JH|qjpHm6WedNkP# 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 z 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%0A`=!jxm%7=$-a<_^LKl_zQ3?)_;i5e{ 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 i_#4409{@dDKE;-~|&9j0uvv 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

}g_2!m? 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

lL6|zvU;1LwF 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%0D*Mw~5{eM;6 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≥*seuq2nAE#%Qg(W0Ppd5(Vc`~Q+kXp}sScesSnID)_%{buUyjLrJ22niP<399~ zPDxe}%^SA|a0SYSp2Kau9t5y&bi^FadIq}SrI3f7(UjX8uJJBDaw;vr8wkSw&f(r3 zt5u8zt(%skvxHT#_0wDpsSt*QyB|(6Fsi(fo}SAo7EoDz-RcA3kfH3`>+2igiE4|E zbvQS3li=uLb7r2Kq9?*k9iH;c?e?g@!PVVw{)C-6JIBH3zM*5oc@Yi!Po@F=^1t@P=6SQ^5-N z2#T?hXSwR8*7en%t#x#SI#@Mi;s_wh991aGVaCFItA#DgYTZML&|%G}K9DnKv|eqm zWQ(Lsbi$w0+27YG#*_GBRVqd>Kb!zv;4lO)hjR#O-cc~^>#OVFrqRKHRc3vKCaEeKC5i-w2HYHaYSuZ@qRtUY3}#rh z;c1#4FLY4t=N>%$j>$#$0LIX9l15&(XH;i7B+GLh{7?jiN?M(b0N7QmTX(L$sk*(R zp_a5dL8@EmN$iN~bmob`#0-nth=^s1>TpiTG|YpAW};Z=l-Pl@6-1>SHNJ7$T+9Xn>xQxK8{G_G5>VTx z7LGKtIjV5iRyWtyH^qzM+0UGHf6J88dxR;pdK~?WNpHhgTdrZOE!VJ&1B(}2L6BiE z)?KbY)1||Cr+F_P&MHpmPWaXZs?AP_i}7A%PK0cOW=S*jf~P_ z?N}3@r{jL{x~OW?eFtRba3@8~TMC?=Os)sQC+u+xqmCMG^e}OdjU8u=2O5>i?t{Gx ziXDm#W89PDWVHxR!2O7?FR29EfiXHW7fZ|TIO$|G{Zj3sI zoepVQ53NN_(Az1lU7c5oiD^e13b^M$YqI1OydHOc9rb$G78xWi-@~;p_fM#tqed0b-eSl`kp;a<~=UU!7@jxG0%_BYZ4bg7qZq*Yyp|FjN zS%^(5uvO#k$?W#BRVUnQ+lL4D(QcrP0sY1%sZrH+1}4Vz2X;+3uc}3h=$v8Nd0XY& zRT-aHf8S2rO^I2CN6-i1#l+Pn%?jL6=Pq~5g_?$rjn%EVrGkIC9cmhLp=QbM9q1~D zq-@39>+yh!A5haiL=88!#%-=!xnAMe{=t2h<6a|oab$(vvqgn)iqU5H)V+K$%U0AJ ztlbgn3pDBYUK%#Gj^XyE=Ei1T%-b#_?7+Fi34Jcn{GnNEtg#Px34v)D37ik&SCkVQ z>y(WWE!0E}xZXCs^b^~hdJfe^XCLFE7QV_khG?_KxzF$|BYJkSeb=h%!8=F*y?MAi z!2tlBWLaK+hk_^f;5b@A!43}hsqb++&#eQ4*i7V%g<5qwWEt|dTjb3(l{t0T2zH9C z7Mr_{^}N%psmDFIj7r}vWBSW+==By()`%j}Q5YFyc!6zNr6}|x0PNV5P!-swn{kA; z6=_`8c)QI|r|eRwD>R{@&KlOW zcxuvPAM5SwQui7(3d*zVRyP@Kys>2?Vre$X{VkSFZVC2f;XKT^C?F=1r<&?^UMI9k zy}E4(Ls9zxZjN8;q*eFT+2O*zW_&6+3>Hq+n0NM+$zzpgCiiMk@{XjfM90GVpa_59750w z%@(jNreWoRfEOu1D2v6`fHw(;4a;MmnNS57D85NtJLI}><0&@R2+UP>+@LuCv5mHk zZrcXt_o|nO4s@AiJ6yH8#Hiw)75RCkk7L6->f73|%cDyPQ@f^ROHL2C(HNk+jn)o@ zxuYJ74VT&xrv|YDbE6yq*HG)&32WaBwc&~YEsS9aIkSw3@iJWNU{mM;*Iky5VoV?^ ziwxPZ-V>+N&A0~;(=Bnoh0~Aduu|*yMO!#mMK0i2heh^P33Dl^j{u{HF^cz4?Ajl& zNTVPs-D%NVSE1QOnN$g4pg}A(U@APaCgu?LT{xwnO0)G!jF?QJ-r_)}cxnMR;aUj2 zcq8(HpIms@Ri8n4aS3)C_kqL>v2NQlxIA%~#-@;LP)~kp#S-bb9qXHG5mLnieh;h{ zTd;Z4#`u}0-764I0Pb=%qE9FoN~8uw)gbB+iisLkf{z>nB-#)aH-8}%dwb+RdEgKIEjZbch z!U0)G5^*DI%^1*OAf##+@fS*1q29Kjjo6$qu7&nH1{3yCea4)0arMIoBwkn<7mfqk zvzlrw5yZciQYWMEkiKRP-Xigo!tTYHdX&y*u{7jWd%6omO^FjDx|Y=TWhg4f8m(#q zRnfdc8=7%(+#$87PE@PZ#CD=9GRMXXZ+zz%49XjQi|~Xxxx0>FYTl!)-LS*J2c2CN ze_1kGm3GCLpc+l+E@B3dnb-q4(YJ3j@kn-lK%C*DG=bmFc(qI7 z`xW>X5zxyinTch;5@ICKMGF z(a`2p14F!M1m5jNvt9s+(Jz$4j}EaZcTFCDz_fI1w||Zrb=w`Q;^1T`LwvAu>~ZudFN(Q^hEbLXEPz)Cm&4-Cu^cq&RnNV~g~I5W zur-))ylB!6<5CkwL?i^_b}%Nl!`#dKv;z8RUMe{S$YT@13zMcHF4b7Le8ZwyqKD6$2ee`>-{mbL?7;8&5>2b zJT(7wBV;4w@KPMP%{HtG(mv=C+vS=!FA;MuTs{m19;52@oJ;#95-~0XZ(Z}I(%Q-` zrTY5((#nd;WfjYpEGu2SvukK{C9bt0go``RL4G^(13iNSi?D!&*%F|ZQ% z;@tq`cZ}}bh7?x7j+OWkf?a1X?p(NYXd&EI3!Q?!rHfleN*Cjmx+{AJMl1J}F5bR< zbU>Uii$O|f4A9%T_q+Mg0XVt37mLj$3o>!?5I3N@1V#FEBM?0s-p*z!MK?4W%?Q06MjlC1?nz3Fm2iz3V=Sg9A|Ds0d)e5> zh?+N7E>X9O_2rRL4))?jR57D3h0j&c6B%BdMCu4Z6AW0Dy?P^JYSgI{6VR5mYhh!% zR}$d{t%$7%FcRMYI3-tRLs+cV?G_5DxoG6k99MRtbDdsjypmp5*;QtABRdaR0TtU^ zkHFE*4Yi2v(c4UoXvBs8r=Hm(tA8)Fz+nmD%gxo(ce!6e?J@T+YIc z?vAt^x<;S)!VR8Uy<&C5?-I3abiul=x>ZzE6avpH0MRRWEJ_~Uuq{?MV+y6tA;jWF zJ&CLi9?s}1j;#^#-+^N|tdA9Ks%_pBp%G`pz?zJVNRY&t z#zwF+A?!zXR-nv%%IFZppSNnDi;XN-x2a9<^(7<`+p_2dy%RCVT9%+}on7JO>`j7G z54IFJ%z(ylb@vX5E`rCfv#%c_j-wx?FN#!)M&1rL2xL9H&xr9*>#Scp90C|@mWgrzdQYL|%`wX+~`;du59hK|J5k+H^vb zO(&Sf-N&5N)xN+c3HLr~CNIyCJ;j)2HJjS`>=J4=W>9o4qN^9&)oW|nIU_bEEggEM z<)MP1L4+#ph5H02;f30Q<<=j0HP)|V#jqY?Dj-hl?cI~MQ4C(G0G|v=?M#fGH zd)?V>#cM|MM6P3?vdDT}euz%NS+9;lNta*fOmo7<@Z=RX&mEVS*<2Q( zA4CU^$0(#$iOh-r%EXY&J9+ z6!A^utb{XyLN{l-TIpe>a!|*kv(3<2tkH)vfsWlC@*s-KSA>Ox&kU+yt%GrhK&!QQ z1`Cf_psle7E?G8s+?}EknL1(2z4`)GAh127-N-WJ;^^<$jsShRj&67ZRD_|+2}G=sW0@@wPPcLyRl2$J!-$71bVxXSRz6Xd!AW8^gLr)_LS)yZ&gl9J#BYXU50Q0(r|Bd z18=NPLVGMWEKCqiSu}FqM??mO@VY&kRPHD4g`%@~#8!??wFcG2x@zt&@z9gm;KcTU z-e(^mjJ5QwGb4AQco?D`kq6NA*mF4MB)e4Ih#}7xl-S8In=c|>ah;Ec6QPRb7F^es zJ~~Jp2!$tFpQmOl1NWB5Wy<;nyfL9UTqjX8+?mBp;;D(-i}uH^U{^(ihj-;zc*>)#+X)->#gR`uy^velRckvk~w>EwU;d!S6$>6 z2PLTq{*?4I|9F2!YNmgJKg*x(pPZiO&-WMjbv~%$9~YAL-uS(XP4RaKolnY>AJDRp z6n}-#`K0hegzP6vQ9c6XOC3Ca`}!2*-?r5#eub?@@lR&MLWzoKK2B z;OBf&_<6o~{rI^)=aceIPt)e z&-tX#lX(46&q$Wy@BTTT6n^)w)X96uv-~R-ruf&Ly!0m>0?zinXueV&p-H8_GaNkW z_gFQd^&N2X#NTC?z2fh6^29H)`bY5I8mu0$-iT z*Cg_FiF|z`zb=t)NaPz6`HhKuOCsN#$e-_h!+~(xzL&`VB$5ABBA@aj0LxEIsuyM_@{1DrRf&8@ zBHx+F4=3{1B=Vn58x#3U68WJ-{`y4zU?TtNME+}u{Pz<1pC|I~B=XZT zasHo{$S+Og*Cz6t6Z!r`{^~^jmPGyz1RLG2PY)*ixTl69g6Zx+s@{cF-FC_A>C-Oy($;|%GN#s{2 z@>>)6kwpH+ME;IM{@z6Xu|)pGMEMbNFF@%MXsB7Y>2 z|CdDm*NOb`)|SxqS(eB*Ch}d0{DDONQ;Gb8iTw8y`JX59{9*U-Lw?On8!j-;&6GA(8+4ME-?D{te{09(BD{d0FQO#{SZQ81o6?`9saCb7p?to1gG5hcP=b zZxw-j#SSB-%o`=>qbvAEiZKP@e`h};-xq7c1(v!0mWW?C;c&I-#B7&Ilu7am*gRGn zy;B4Ak|uh;r2){^H**v9gQ1;FW7ZJPq;M=l*=qX*0j=kfGU4DZib{}e-g-$$H zNFnchD2Udl#^7BP*JJ@lFRF;YUe$d!Igk<}5cNM9$^)LePbr{)>$XNV_AC+dW3K{3 zh(6F1b~Os?Lm|G;fngq&jr2q_2rhzHUK%#I!9wg+_-aXm4jYXsNL>G-OuR!$4|qsW zaLQ~)V-t9^nJWM<0AkEs)LpGuV`axc8Eh?&ri9##g)pJ#g>O9~L?}y%^0BwMMAYmo z?s}bW=*wSBEn_$odo@fF8-I5P8X0?eZy_4(8g?>zlO9UBZ_vo)#FvLBZ5cnD>l)&_ zD`oM=6~>qsj8lu4pdD6epKm4Hym>edG_Q~Zad=y89vA{7cI6VHoqJcsNA&TUB|KtG zC-ezc3sx0pvl3K=TueQOuV(<97pG&?cP@IuY)sLx!kzkXjd>p@$lSZoFb*gQX1r3I zvhb}bh?EtGxwYT<&S7MfC!)inAASgX6)`L#hzjvRnedW74mB~@wt7<9cj`oynjq>J zncj%WiwMWUJ zRPSNK*RjV@_OZ<|-~!FKF*h-K=WRqWIMz<|;|eiMp?)SFM|PH=%K8`%qk89+pt1VR zbemT_#84*40WjKkg&v6l%GGS5M>+Fxg$hFu@6s)>#fWp3Hw-0tPdwWtqn_OHF{LMv zX^p|JH~B40cj^5B(_xdpis^38yTzn;82H^LeV8fgdx|OOUNG=i4g4(wPs5mJz0;V2 z{tT1S@5O$uWs34`27U=s&|hZKT_!zX(t{?w!=!hc^s6TQwn^#dVm;5B^d*zNZqm1z zqCZ*qhe$V_Df078y27MuO}d>a=!Q(X&!jh)^cIsIGU;bb`c;!2G3gT~ecq%$HR-D+ zrGF~e<9Y8e-3und-xKWfydtLW#k~vD{Wwc9eINMB^a`Bgm|p35vzZ?7yi%s`_q-~k z99Jt-^#4MWZa3+$Ne`IxBTPY0KNackHt7QZ4Dd z`DG?uW6~y*ZZYY0lMb8ofJr}M(nBUaY|{Hp`Y=y~m^vne+*hzF^XqP5Qb?d6mibrZGkT zN=-_C5%cGobgfC-OnRwF2biM#0h7Pcq_>&$E|cDC(uYjSyV>9>&-*^ptFc~~UgLSM zGQAdZ$n-kgVZiSaTn{;9dIRJSDchUR6#c6(X_ZOWnzYTNmzeZ2lkPIyt^eU6yWK#Nl zSnhKs{i;d7ZPI6%qP>?){wQy*k4Y~yDevTi4|v`VrXR!| z8q*JX-hQSxLe7|e82n-ieRLz!k9giqOh4**2btak{lWBR&%2i?Hk13A{)Oi~gp~bx zk}3N4W0QZ=q$TkC5I>tK@MoB`(xg=;UC$JB7nyX2Nv|;JL6d&Yq+er-`W`ju^9KH! zN&m;dC*wkq^_H5nf+@;XnRJ7JZ!!69lMb15ze#T}=|Pj;#T514YtkbI{-jBtH|a|z z{S{Ntd$@CCI@zT2O}fma8%%l$Q}pvPlQMQ9IEeXU`Z3HO(_1lrOh4{<*D%HYaRXEA zA2%|+4fDwKFENiyKjC?|G5ssgJH+%5)&0f)^15EG4 zd^7#D=N(~sm*+jq6#Lp^OtG&$$@FiahnRi_^ceEV7zaPp&GPwM?AQ2Ga+tn%;6JP2 z1J`2v) zlytN4wFLMxn0`g?{#lNn1*o|3OAA46=7Axx+|8&2DVjH zRP5i+bI#{ZZib+K|M-3X`rW)T?|aU9&U2pA%go%7_bbCD8OGV9TDScJ?L^$*R^gLq z59Gfnw^xXI`cAlA5(A%t-9miqV5;zGd}dAfPmHHR=$R)(de!uApj)lmAh$-`(5KdG z<uv;(iwGP>6Q*oe=Fx)>&aYP`^Uxn=C~7xx#;9y()yBCgF3)pKzyPsP)q>^apW6 z{~JQs>vDn6p9nfom_A{nVW{;F(kqwn=MAG-_yYQ&@I}}uMEchVccZ+7c$4}K;U2?y zU-&XUGa-bWyuT)L{n2McZnzNPV}uA_Bt$-{h5tnT2$2u9jzRi&iu)DAQ0o`82ep0y zUladVvCbF1hIEDS|AO?OEr>gooGQE<Do zjHnQ}`@?P_%BMt#@|!38w_&LD1XwF>eAJnh#O~d#L{nh#c{+H7KD*DU&P+@y9 zKM7G^_tRhAZ<6|o@`6Y&TZr@vgh;1Di16Em=uB!|0RMl9`%d%=A>_Xn!aqI~e2eP< zxYat~ZRAV*;m#65-&7&u7Ya8aze0qcB1HI|pkoBm6Z+5@ls2sdHfA%y(TLe!_c z&m-lYC`7rY2vOf^{)gOnaYOD{hRc|DtET5PD>O7d?LyLhkQE$o+%i z|6=$ahJVWNujwBXuJ!a0BK~k8;-?9rx0vDO3|}fld#$ItjqWvcUntyxd5Z4)h3}xf z3g0!1z4U)yh;%*`A{}o8h;r>Cg#JV!>`4*+7xvISneJ@57YX;FoeAGVxd`7kjPn@& zH-=wF_uqvdaK4BB-Qq^N9}9OH#zEn8hMwPHpEnY2*f&uKyRwDPVw@AA9%_ZC2Q|M# z-zsr`sONRDU*>1gFY~j=%X}LKy*q@GzVJn~Q{f9}r}Y0(xC`@R6o~dTR*3M4Ld2UV zM7$0m?7CR^G}Z;ej|}5sA>wTlLVkx3a=V3)dqW7h_l2zjf(N7bF`!RnCAwP@Z5LVk9wrM9 zV0;pyK9&lRUcC_Un}x7%l@RgdGhdEbhH-)vuKd~!Kh;kh-ggv>!y{LB~;#CWw_Y@)0SuceC`-Lc%4~6Jop9&$L*cZe& zH$({cC?WEZCVU;`BSikngvjq2;m4SFg~-=NA@X^v5c1oFub_VlKf(AUgkDDi_yYQ) z@G;D1WQy=bsE9dBe1TmX80HKNph4y9qg3w6>2y&9IbkNE<~{@H>$vJH0yP^qs364z?JX} zhEE`6KOp|-;)=?=QIv{1NGu7I8&#xuh%`*?jw6%E z;p7Bz23ba)K*~9)<37`c;tgZzj*M9Lmg z?1&);k*VYqvWT2d){|}IU&z0ba_%X5ZzJy~pCn%(-z4{w-;idAjvq<(BZrgY$ZT>B zxrkgwc9N%)7m(MGcaRT~Pm#OHx5$slZ%GFRI#q6@oOg;lg*=ALB}>W0$!Exy$#==m$it*NQtOE$lgKo(keo}_km@`X>93>v z0#f!%V%OcII=6)TS-M{(-y;u_Ka<`l9ltj@giI%=l0~HKrzE`^vW+~Ql>L>2-$>p^ zK1IGr?j;Y9he#9q9El%A%Kk~*BgtdPT(Xp0Og56M$@S#9PRe5-Ig}hprjy5zQ^*{0COLt)D6XZY1UF1vT>*QPHd*lJ~ z3(|@GrldEF97|3oi^+v#J=spKBd;Z8|0?==W8W$qP0l12la1sm@?7!?@?r96@&M_@ zhE?>Yk+aBoc%mCI^s7#GDc{O<>c^i2bxrKa$e1iNZxr=;>e4TuY ze2+Xp{*U~I{DJ(9bPv?!8cy~i`;r66q2x$1ojit|LgtV&$vI>Nxsddeb>s^2L~=EG zDtRV(E_o4o1$ixb6L|-D5BUK3DETD$Ecrb7GWl=v9r6S66Y@*)Tk2@<&p>qAzxP$Otl)Odto5 z$>b<9gB(vzBj=He$r|z$@(gkVc@cRnc?bCbxt)BG+)ExH50R!%=O>CBK&Ft#khx?j zc}bFvcO`i}c?-FTypMc{e4KoWe2#pPe3g8Y+(&wc&`vU*>`(g0;p7-{EIE-pmdqn( zk!9pOaxqy=HjvF^2YC{?jy#(@pS+a3ioAimmHa!onS7YsMm|mMBzKdqk$cH~?Hsj3N7wiR2J6g-j!}$jM|jSwI$(<>Uf#30X@nCtJx? zj3dX8W66o+bh46cCQl|ekXMkmkoS=X$p4YwkUx;Wk?!Hzu5hv!*_RwhCX=JdvE(GO zgsdb_AnVB%at(Ppc^-Kg`FCX8B6vf zhmfPmEOHuIK$emV$SQI<*-oB9o<&|rUPazYZYFn;FOjd4Z%Yc?Eehc^|or+(o`Yen1{1ejjgXAw{*cfe3Uox4@B#$L$lMBc?vW+~AJfFOpyq$c2+)lnozD0gQeowkn zwOw&!5}8g;BWIHf$z^0Gc_w)Yc_Vob`8fF!`6l@hIVnxsQ9xFZOUaewN#r@?<>XD| zz2xKMPV#l~eez54XEHQhr{9MhN{%IS$TG5#Tt!|*eoP)BjSQ_ff=nQjN&L#JTCYwe z3&~1yDcMA>A=i@^lbgr~$S29?$$yg{kYAENks+DdjyQ5KIhve6&LB(4{z^t1qwVTXrjX;wJhGfzN;Z?Hkmr$Ck++i% zl24O+$al%l$sbAYcx_J~GMOApW|Jl4VsZ_64!M!MoxGcTfP9kNL%v6TO?oG2I|h-H z$wg!N0`uWMLED4Po7QQMm|e^M7pQz_`}EovW`5Pyq$cGe2e^vjL6n{d}J0`NG>K@$+hIw;G%`LG&yRG1*G4C$A#!CbyHXk%!30&ei%7$qe#1vW{F!UQ0enzDj;W#?90E#*vj|CwT?AiF|^5hx~;cIA80TMjl7j zk!#5d$eYNA$k)lk!d85(egTLvGFAxpKw*<%B#|TNKUP?cXLXaa>0cqlTv<)`N+IH( zNUmb|nGC;>{+E&)$y>=yLg;&pd`1YnUJ_zVc$e-^g-GWM@*Db_3$=VSIY0=x!DKT1 zGw9ADC($3ju%hG($vO02K=)#@ivCS>x00RoUq|PSAS$kfX?B$#SxuJejjCInUhm(`Z3UVcR zI(Y@TiTnro3b~*BiHxq%`iGJe$zrmK>?AKDZy~pluajSr&RVUvFFBgbCM(GX@Ql*K7U#$W(GBxtMGv&nGvM zkCD5{56JJy@MT)RkIW(q$!c;Hc`122`4ss&d60B9XuS#K7_xv|M7EG;k~fkMkk65C zkzbNdjET}N2a=g&K3PK6kgLgygjkbbLH8!|333Pd7WpOVUC#8#OmY^vglr?vCa)py zCI3nOoBW#etkC*>WEMGxtS3(+uOja!caVF@Z^%f@T~ba-zqgHDDBgiRaCD}lpLH>=rkK9GRLw-fNu?7&k`;%#8E;)~EAvciMlUvAtksp$W z$=DXHe;7HLEFqVXr;rzuw~|}QSIGV3k7N|qYGVHoatb-0TtS{mUPazbZYN(SKOui1 zd!0!8$!xNcY#>h|FD7pzA0=NP_mMx5(QR6P3OS8Dj>MyKRsPnJmy&mokCS`I56Q!1 zuXY`O6q!dZAe+c_WWNrre+W6AEFw=J@e6<|ALo--kekSVkgt&Y z$sfpwP95JzW|1?=MPxI1I(a#HC%KJ$g?x)VNd7=ZuF~lxk)z0QWC1x}h_+Howvwj` zF{YhC_l4vZ@-g8c!+2SUKK?qnm*L;g{XO}!5c2V>H3yO-gh)R_I1E2oC4|1&0P7s#RwCy|Dk)d5c<-|Ec$2D zoktc46Y#wZa)VIp6OM*`bl)Wu`^X3Bzn$)9$X!Cj`+)SW)%s$DnXr%U(L%A0%%Xob z-Fak@5b^Lc*ovo;SCZR=uy+T!hull{HV{6+F!F_N!$8weyqSET9AavJ_5IR3e2-Jy z$Kw0&qWz5_PY|LV zokU(MM0?mlekDx6_oZE$Gli&+Hu8EQ%5x{_k^Ezhj$t_+IYlTP`rmJ+(1XQ}{t}5MAh1K|ubTo)`)%OITUwtnC`Y%Dl5dGf>pP!$R1VAngtM6NRu(o-ZlxF+$jxM|YtR_EyrpKnT0l_n{%bLENz4 zNNZoa5>FuqJK8iGtUGyts*$FCzcH;Ek2p_jt7}RV&ouiJ=+kn_=cLI4!>fA;lNdU@ zv3AW-!j;Buj}DawKrgFmHG)<5EYw39M;GilF?llnA10=R{!C&4L6un06ZeCY2@dWd zfu2N^>K>ooADlqXLOmpNbitkrO@0+1II$xNUJ3P(*wF=hPE3An;13g1LVqT)fS^iD zKLOYFD+a*{9VyU5B0URPx#|8)+uAzyRPEq&P$)gi^^n}}%J!UU*Q3Y(FkzeMpGn&; z-Xa4=+7aeShGmS&Ov|(lBt44tRMFkbMVH>6vP^zTzH8t*B0YJ!@E?|j68bZ#X+d2A z-G2&0nNV9--HAsvH`ljdSXK8`)z$K|)3(s2mKymj1dg_p!b7Q-)phe~YhHGQm^|y+ zQjC%|(rQ{(;)e{Ff32#%t!gENWK6E==xA%i?*l;bpTA`O#?)cRx0)USxGa1A z0w24+Y@0suxAJj4?(O*)ew2Ld&~kx%q(DyW5nXaw`FI-l_H@f^=|)ga;>9CTdp{8%yg~xTn0t8 z2)8avpRAwk`qn|84?dU$;dmaeVw;B2*UCD>6VJ&^HP@ffV=TY+Ula>qQL*zuC z=#tCI$M-?$Znfn@#uO{vA|wdW!1%HU`g-agKFHb2Wv5NwK%2hl)Mw>m|55TG&&@=- zfqZ<-e26Z&tbEi4rTZUSx<1ND{^dF7_Iwf~0_4OV(IuCakC!25FF$W_*La0(NFd$87?|z(@Ijwdw|0H9 zU$yH?fIg9ve8?DY<)b(CL0nxEkCG30{wUH7F!7>th}C#fv{LOW(^u`Wm25;!AyG;@`^0cR~5M{3!Vtrqd1NL*zuC=#tAyHwicP z`e?P~L)HLRx@B6QF;>OKa~z@1(ji`wNBO^za@M%E5pwcdgw|!n>BNma-E~O!&M=){ zY?A}&UO|0Uy_Jo$G-*nja>?_ha39F8$Vq-hmt0o5j|ZijGQX=IO{Sd0i^AD}=(h5) z0Q!2Ww~vDKO|c7+B7CF^^g3?_Vl&)2NO_UQ|a-9#kk8mbuU6x!!P`XQzu5XI2w_FHY>8=UVcj7I0 z2BBp<spzlme8EEOdCrF$3Dc z6{K$+^eu&u=)g zkh@9(d0AB>&q=elzkRT8J7mPZQv6%_{SI;%vRdJ#u6P`Pp}7PuOSRDI8xmLsIhlhi zaNmJ{(HDb%NfY`4SM~(c7#JRK2I@oBjCQ$=I0%+!KwFoUuC>8Tt4V7~_xXI86SA_# zWn@k`CKLA=85y?M@mX0u-?+?i0$fYOPRlPYFilI7ly6EPeMx6)vr5e^&c@Rk zTOV>2WH&?>c(?ra{SUtlZ5X;`WPz{XiH}>e6K1wPp#+W1oBzJ9^&xjbR6|6;xQ20C z{&skX?-h^Z_3)*?egDmGNd+kd!v;_}Hub<^J#ii~(EB z(>HH6)@#lBbs}_2I4s$cqVBW}6IINK%8E_iE$ecYwn|rk{>|%5+r9T8i4B29?-NGh z&q$@`bS$~;e^Sm^{`>kuRJtjT_VPJ5pK#dq8LW8H*=YFgIqb?95OKj_Psa7QtNA9x zxc;ykjP_j*znX9QW-Ixh#7<+qW1XePZPPR3)Xj(Ee1=c7Kp$fMp(ds4?f!Vyq+zOV zG3)>u;=p7qLC1!4AKfFoA!niSMYuv1ppiTK#-g#0?3)d9B23TQ1K{h#6ob76+_ zWfY0R>v$Kho@4ri z0TGS}3<#dd5gzD@akQgAJjX`M1Kr{suVP&AOpn`zcL$OkSD;Qj*)ft#iboz$MXSwNl4Ta>%)6NRhBX1CR@|Dw5X?o;Y=AHr_y2$j% zqij4gwext>vtKe)sGW;V6c18zA0I0TJEzEfwQoGoYZzX_k3|-eLk1tfy<-vzHpIu0 zI1zOkG9+R!^6PS3jj9V7svKU&TSzWsctlp9Btnj1NemLP@v&8^BwWK1l#@42yFM_SHE3e) z`ax$QnUv3wVxluN*_(v=bZkTsg^pIaHXM_Yuh2B*a5;7&vCvHA@H$>WYYNR$jtGZ5 zXC_n^Ta4pB;+U*L;-hO@8;#Iusw5H|@-q^lxxKfbi6%PaJ)O`Q%Hea|gaQgJP>y8B zmtw)J0jWqX#o@)#Rt&DvT+0AgsL%Tv3C`XoO3raO~VPBa~%mmMO{&}oR2Cp>36LY~5~)uj-%TRlHKwaDyX6 zewU&p?tFN4I6`iOqg6RBc7*&FeWxS#7xd)29U-#)?TlCkHJcqF&!OU0DaV73kfA8` zQ&kh$>IgZ2I{b_3_S+mG!%_FADaUq4$S7ogopLAu_C7s2uwo zA$OplFYbL7!asC)CZqp^UaC|&_w^0wKz=Td{SF2g&JcOh`<1czFxuq|8HoH|qvX8K zkcW}0>(#&%;lwzAB6l|=$^&D=*P+CV!wR-ZD}59d9af|ojNy0^LSe-!j!V^8SZQCW zv3SR^$W+)u6_Vh{g;&@TGTX!lQ;NN1~$=y&)=DIeco8jncLy8_o|<(C$?O!eD+cu_?R^jWaoV(L?ZX%tAYf zUL0{1G@=E;C)ywXFdQz&dw7kmj(8sMI))*)(RHdIA{@oYQ*=E`MV>1ey-d}GW25(S zsEKaSHFLA$LQHYd%Of6zXK%+QbkXP)%F!pfw!OxPUKzU{9Xi1wkA{nGW=5osN4KbA z@fptdk(7I*?b>5-oW@Ql&U%S}%qjPax@r|WN~=Q?EBlcqzj!MQ;ug58tNlsCX$VtBY0FA2Q{ zWTK%venq|ZN*r(=O3-k8hkENZu%A5c)#X@^M0*YD|2!OC$57;`*WhH?v_&}NvDLkN z$`Rw(gO<`ODR}_$A8#a#N42=~%|sd4!sRh&@v%c?K5=Y9_G6Qyvms_UB9Tt4Zfh<_ z35Lqp;i~Mtj(#Zm*b&MR;YdI_u_M*s7Gor2OOu>!4!!~EdWp{PzGy~?aSJ{d{a-?5 z+`_(VR6Z_1i;Y`EEs}EF@hasQhadTfTdZ12yh9!K5R-b;=J*LrH-Q481X(; zCr0#IBR)ypx(w$dX!P+zoRU~vO#CQWnMSY4G~&4wiC&BQFeCn8ZgZ_(I_3JJT%c`HY3j=W^c40 zubGM0P_q%QVdj_U98umwK3+8knd%l3HfmI zZ+ML`pTKLR*^D;pGcQ9e`OL@hnq)fRGsH|q@eVa_f;q|N-LPkvc`>SaS!m8fT71;=f_iLdo^XaGnkwaS?qNNK5lhKpy%o)NR)oP*ZO#`WDG~yoQjf;n-@O<0Mw zhX&*@Pe<*z%%5@ZHS;hegqrffwJ`HhSQ&20X9ZC^ucH8>$2*rn#b{S_p8G$z86&?3 z7M&j}2Bo&QVfHBKBeRDQmk>Qk=0k`4fN1m-x7-_!Wmw8bPu1h7<9^g^^fcx0I7-BE zta5lAbu#-+k9-+X!W^T}uA;M*Bf`-KeJ(mDQL+)`{Sj?2I#>7EHPOo&YmMlcArB)6 z`z2&0x-g*{j(Ef6Mlm>_Mv+DrImPNevY5LJ7Adpb>P{7@ycn)Vgt$8KqOu};6)hrn zhD*jp*Y&uKlsULdgW-A{?zDH&|Dv~+b^+~R8d?+zrhJ8WrzG=LqEO5F&u|c zdi|2(CBWs#L*DugQ4TK}5R^G9P?Y_KIzN{CRYq>><#38aAH20#L8|HIRXqs1|sX5F{bYZ6{57l&;Z=&kl<|DA)V@|=07GlZ|EPBoB zAQNg9!9UE*L30W>kAa#9^Ct9wNb?RD5oOMo24O}*LyQ@MlIdlhCW)KV;1g%AM84zA z)o(*X)B>3FcumjDDscdit9WL;nEtN~D!&E`gqb<_47gAafNgA8gJ> zx<2!e8ZmD~qZwl2)Ey({bXbyXzJdE;=32-PH&>&Lk1*Gvd8C*>L)%F6Hr$Ug<>#eF zn|o1IW6bLypK3NDr)lQr@J~1EVRMEVg3wHJB}!?mDUTx^XC8!PmKlb0k1;=k|9Epd zY@T4Ahu4YbCY0nPa{z3ZY;Hm56!VSV*khWfA$QZvC}=p=yahhf&3P!vY%>CqIp#9N z%8hA4y7-OOAK-;bL0!Co)}6S@c@@ehE+KJ^?7tkX$b9137+HiE-lt(*;z_!*Z1kQ9 zEr};<7naHEP|%5|Ix7%Mj}&3)vR^TyV3uKK!ywZ<7sHFg913rzxd%n;GN+(*y3L#L z>M<{dh7hw9_ISIL|{744mq8AlP{a6bw8rW)kjQ@=H;XvNCt87a2U=YVG5agB9lt zX$9pmwIbRmq8*kfQyi2cM=Rz%Qaa`nP>fTW4QOP8$Hd6PyInU(Bw1{_<;8HxS(8&9 zZ#+0P<}neFM|wxTWC^%sOkub2E#3vA%@}0BG`~a?hq(h;a+y(RC|+{~1Y^u4XmCFB zYWQcH@8fk{%oO+_)_+lCh9jm)CS7ODhiGSpE9P;O6qec7iYq2&9?Ug-F}EQBBRl4F zGypV)JJG5n7h#D=QHm~XtW=-jGQte84ew`#eSoTg0{pC)C^CHb%_W$G*!U4Cbz_)e z@hCZ5jxhNRWn8YXb*M00-mu}4F5-txlMw;&!^-qcw&8pYW#?Pxlmc;9pm`y%+ekUH)1I>JG+fDW z`($w^XD{+ZH8`Ke%lv>dQjSh^!;ljd!zDqk3lV#WJh8ja#0Xgeo+CoC@G&xSQ9?tP zc&-*7m2&1tG>m~RN0eB-+0tf=eGdI{U~7!Dxgi%K>X3GI|B6V+i{To9>KIyqSj*v3 zA1F7kt46zy>S!>QXNWq)Rc~HKwNx)RmQR=T32C=OFOU`jItY9VN#8yn_zd*BpPYKMy{ zr^9bG{*@`U$A~Epz_|(k@lr6N{XYClik%qKFcOIkM@_BoOc=UIl`bUp$Ih;sh^C03fcQx$&omMD;orPYs$N-}=941W z3&Zx{Uy4BWn=p(O4*bWOQdcRbWJt_c(lv1RO2jq&Cu`cu2q>ymrNvn?%RdLwbGPzK3#}}HXny1Cd zZSSl=DoL?LaZIL<7*V7I`lgxF`=O+?A>!N1jP+zEoTQAz*H%<1x}_8`0E*%>%zmfg zzCY}@qCqj5S4XiVNr3YlL1k4`}Q(p zQ2N7JO=#}e1ct-b6jhaOT_aMSBZs4rjf#W5spxB?`&tDbE`ek0tpmfKy)x19lof1| z)B8#MbXFY7M&f65&za6wX226tUD+L*W~h3zl>(*<)(^T|AQn1+y;iX{E;Is_I9~3h zHVr@enp=%J(v9>b!zsM_nPski$>v;F@(A3GNC^u}ee#yAz5=4hiD;#W9!F6qw3iDipk{l;mv4zy&K@y(+(9nMX?gk{<5_2UEGAnIS7$XuXMfQhzh;bZaFinXu zSH+;L8#>*&Hk~?9LS0xdmbs$(m}N&q$o{@iRgv8agH-ni?NK&zF6ytuIcfW{cRo|rgz#r3gyLC`Du zAgjNtCQ%XBx@5+XD@8+14RY(F+mf^>BfVU~%vQd70mNHlHg2pYtrpvZ)N6`*?W10O z>eXd?jaT>f*KFmJYkZ7+IE_xU6^Hp#R3x?FS##?M8Y- z%gVa+s;16#d`+UczHwRljF#HE^ttVIZRyLJTB@s>Dmq%)s+QHIw>K`UZs}-GYi(<3 zPj75)@4&Z*(#4V5(bCdX(@@peoQkhrbgoISYFnAw+|pc^T31!w2+^9RPN-a2Rns8f z%=mwoV*A?vZ}NvCOkY-06O_-)acSeyGOg?yY1Um(iKnNfrPs8y)d^QN;*FIf1tqu# z@7l)p)~2epJ%s4Gv}>lUc-6L5t?nU?Wy4W|f5)`nv7C+S$SfUcp(G%h>Ra&9nLiW3 zmZhT@_xp+bPFei9h<})G5wMEYo;@pKdJVcjPc?gF`hT{r|5V8}HrLjzvW&wvl3%Y& ztC2y$Ut3pS)!EeH?^xSf*PhmZ0|LX}-cgHBG{J$B0^CCc_ZZtGD#ftYg9|%Ve`{Og zs;Z7UNMOvNUrke0d;1X~%i3BxTaWN%UTyvu$)HDCCX`}0qr)bFGXZ$kt-{y3Y`)l& z!MCGvWnG)i7waSOZKzvWXY<8AAHLH1kOmG+;E>GduP+8?Nlfuqch=kDYYVE{+N#z< z0anaVV2Qy4=LYboYOAY)0~-K1YFe6F+5)cDs;0UQRcbo4aU}*>Ki+8#L{_cEmLfJF z(9+Zd0bTeiqXCz)Jm6AA0~Za`LkHa04nc|JR8#Y(<}uwN zK71Zc`$#CNh7I3KB zJ=PQNjvYh!IJY}Bt()2u%Rcv{Bpn}i!3xt8=Z;8qPk}~9s=TB*%x)3WtcX5$Uoj`$ z9fBm?o(zu<$xBAu$V7VgOiWaf`a;l53eq=C1@-PJ=;=V#t)zT-S4rjAOmh3gy1_n& zvzvK4kBF0Giz5YfWSrec#QEcNUOOVrP-J14==UL$`fiGQsF<53rkcJ5Zu9XVYxf?Z zWf-)K2xw7vQu5qp78NnNL28Sv=2QmQ$QxS()!I zD#{VF)y!?_%f5nXQ(&A!&ZvM=o5{aRG^U8DP`^!ozDh<_PF+{YjtWvQ` zb7%PrigRW%Voq*xzSWsJjJn!JeD}Yp&R9{`)-1MESGCuP))}S6rRDyD((*YumHv`> zV>9i>%`DH)FA*iy(BZE~=knK7i%>x+jGS4#u&mIEo|9?d5d&Jdz44^FZZWHx8kaRo zR2ir;)$7=v)y$Y%QCT`CP$YV=?l5YqTB~XrJJw1hT^93lis$D0XB6g?%*@Xd?{1kX zQdtR<%FO(V%DLtF{@l5_QZfN0C}w2RKewc~G$+qrQJGU-X;|6C?9$d)tMb7C(Qm7u z^8AAG{E9-Op{lvIsjjWPOXtjdR3APk?yo3XWKRmNfVr50I{Z~N9gVAyCp9Zbabexs zQHMm>9IU+KE6e_6O>0{lWC%7oo3Yw$uB%mTsinT%zs6{mr$ESfZs?h$vALnHja9DH zu5A*vN`GUGOct4T$5;bPH%v?FE8CE7Z9y}IJiaoHZ%E@&399}25#BLwti23o6c!cd z`SbG8m{A2tzjk>i^3`6`*3#7Eud45WQmAg}ROO}`Z)Hx!Y=7m#vV4C@X-U3O-PBoU zpd2KQlwhF33Q!@HMI|$h`j(o`c4;}Quo0+h_oKL_SGBeqh~n>P@i(qu$ z^tZG%E^BPAYO=?yC@r2_SyWmQsOdob+4&2*<#2vcp0t!qG&59>(NNd8tO4DpuHI;C zK|5${X;wW*&yN23rq1>T|LUs74wQx6SXHWXa`Y%+jVlZDi;GL=OLE;h1-j@FUSrXq zYU|qMi|Ht;#+nt)7_W{L%M!1k8Z6Gq%`Y~Z{i?Sgp?IRsn7>93dF-?m3rl8*D(#d` z!RvG7F_z4VC?X7h+e)+b(-SRm(<+JnI zKcp$kT6Yazo6#+>L2ao~O;~pjbgoqh>c|`q4br}?ayxRMEt-=v(>AWmD4mDKI-@Xu z#%yWX^>uA^%{6uCP_k1~la6}nHf-qrF3aVvx?m|Vmw}E*@A*ZQh5np!l#rpDqV78= zS!?prtJ4lNWb{X?Yv`4nzg3b6s8qJ98LF+Wy`^bYU9DQ{+IHW0==Abfg!c4#`3tN~ zs^RxbBT*&PUe{DtgUx?8^SefJJt44-m10y^UC*ky(sG$I)FgzV$Ea%VXvF+frA9fs zoy9o|OXo@t?ZFdcrZu#*V|d260&~Sr?<3S`(yaxR&&)jrzih%88}+2dwbquVMm#qQ z33L;lTQa+(bbg7^QPpT0U1k&)%|L_dW)4RYHJJu=&p9&G<`z}X$tg4Bfggc>s>>xX zaIncsFSfVdywbUtD*aZXQq8J^byT&l&~kwaWgEdZEQ1=5)(>PVvNv-7?rscVTI{;m^g9PER8F#W@v~Mcqah8CX!Z!5Nk|-dfe!j?c_V zEvh{kCkQo*V&X&Z#K0bu=lZ6qW$miLTeYmG$mVvV!J6p0ChO|Pj+J;qQlQ{u>0_-H zPz*IF4MPpPdgu=%79_{nw6?KL8LPI6RjsW}Yl9{N$-S+=qo-hP((Yeb)wTj1tQMu- zAxpnNaj5xBhNXay8jbZDsHzh)tBRx6KYBCUVYIKn+^3$J!X<<1>{5oxEXlj*>V9Ui|pj6LM8ohZUjjG}bm-6ev{&1`bZMVqZ@!yF7nJCHgT| zb5g>AO0;g(EGZj6Je3FdKnd&S@Bg z@t~j7s!4Fy!`)oh(wth~nmJzFSh;kh;uvxo%BdC}9Sxl;tHG+anucjOs9ZH6wQBUr z*3s>CHKT12m-$jl+kL4x`@860)|i}^pI_!Ln_FIn`oxM8=CvEG4QS(mW+1h!^s2Enuc)F7 z<1-cyYOOY>G!L~jx42kz>h3-xr(_0}C+aj zY|zVbJ(%lK&}SslA7Filnq0cd14B)lUzIbCsXJO$%3y)#ndwfTR$Ep%s8unn3~KRu z&PVDPMs@yWC)l-^t}HLoeE}jteX(845W}T2NC&gd?~Y6b1*!+{BNrVN^JYqYv^Qc{ z^jj4K4S~{=RR|XC^ZoORDvG$r3ItZ5mTXy4C0&6HLp_R0MqjCyZpB@cm62iD+*Y@; zWfc}QvP_nB6V?INGC&W*YIUJ&4})4+dFc$S)NKs`3(QJY)!mXroQ z?B=aBsEIeIUglvC!kh&2wLE4kS%t`M5)*Y`RcLhE5bGHfi!WW3fl``_g)aIZs>;5* zhmh15CM-M`N>U2Qs}US&Vc{1rATPh56kBK{4mG-`%0sAnY&6A1*nvUJ8hyF2OrT2z#~k_d&{Zq)E4xpJ9fll|=*|$_1ah!q znutsCX7vs=N^tom%~>s?x-ws!pEECCopx}hJF*?;WOXY-t}f=3&cUI}+&M;jXLakE zt{PBXEl}QSDTLz=l&@O7+UtUfWKRq4o<^sUNy7O9cdmJ^&@sdZnV=2Q_Lx%n;18k?byd*n#Kk5L92GwcYU zs@qTjxv|`8Vp*h*g=Ct8iJXzR{tx7|tMs{_>ZVWc1#+-M#BPYlPDzf?iE`B^Q0>iCt^T$4Zh~E!%+D+J;sr5vXDKM2 zTT$qrpHqaBJ9P%A4vX44m2#_ps0DT)3Kt&w@ItNec~Wy^^I2exWFlrQrLo`la{(-e zc&g_HQc|@MIDhS$(Dl54MP5rY9tFDAz+*?z4)ES}Q>|J`D@mRWcS+f7R>v*J&BbY` zVXMwSKgr3P=PxY6$uz>?JthZ~@gUY{mS-HI z46yM=@5QOIy!|MB3U4(vs&>Mf;cQmjvc}(_*Ohv6(TRgMbq=a~zpZJA1w9SGWjNd| z!Vp(mhaTK1rw5W=*Bog`8mo_JPIDK|TZmyX&~CaiSb^P>ZHIj1F$)aoR(M5OSy^4t zQP6%>(z>-)SLt@C4(Ii`i5v*26IVH}_sd?f>-5oB-Gm*gr zJu-a;)+c&-(8Fvwmis(D4HfNIO}p3!+q9^K8TR#Zj%rwkNXrRl=ISIxW><>G- zj`-=oC-wo&!cKpVCn7)W7TovIvbA~jm; z1u;Tw6Qx>7=U`LP?TBy2!kiNIrUrH)H7jt)Q)^dPR#Y-u&d38>Yre58e)up%O*?o`MFfEGW)jfGwuKBp=K8@*FJTP_{gl>uMrc)?-5yID^rxP-cn7W;p~$ z_t$5&Iw!WpC+l9n?V`@}G3ueUt9KYgf54E6lAN+KwVbgJnrrmwm~0PMi&=7nFC&)T z{c;DW-U#Yaq~Ec^(YIP5Ng_wKfv)v(AYReTl2W`gqYvAp6x2dSw@96@a=gKiBTL$P z%uUr*H7n4Cn~;B;;vW+ z7(M}F-Kt${_W?j3_vj^XZJzZfQp8&gCM$8=h0Q(QXz*vMvAvrfER8rZ@|~Nm`qQ(cOp#rF_Sz8Npk-S@ zk^Ou_k8?&}D1n^nhN9HH^w-f6MpL}8thg)N_Mve?V%Tmh)`K zg=TTs?j6rQ6J_M!GcSS9CW@?lZqX)poEF2!o+Xf%d@wyH%6lgCys|;$Nvw@>vOfdVI z{mn#kkZXvUY>qPX@R6yY%kJYczWU7`j1Okmo%lQzK3-+J@E{YLOFp>iQeOd*SW>qR zxbcy7+a;yhbvfmuK(@a^j;@-Sx|N(Yh`tJ{Z;AKJ^u}fPfR9mFgajPe<7>C)Q58q$1 zT~1?gkiNl6zN=L5O#|EIG?Ie!CD}qHy&*y2LxRGSgVIY5N-sG`et3|+;X&aeg2G1x zg^vtMZ)8wd`wVyT2OjvLE$nQbX`s(Ge}=%S0L`3#<(DTX3DlJE}80gC(FAos=~_aktNJ|F&L@wWrCE{Xpx{v}*SzF73v zue-Si;G45LT;`Qn^cSB9^OE@EyM-qkrQO^kjb(IaLpB!QJ3AvNJ|2mx(wDg;7WExi zGhz8;-x4Qx7|FGEADrY^=O=!@nr!^~4I+O{t9)!toxXP+JmADhpSWS&BRfE~6w(JC z!7C(v1_3$iSlPa8>M^a%fYtgORGgB?5eNV9*Cus;%e~7lupJIaO5(O%AN+e*wjC+W zlglFm^x;D{|L!YO1a;e*_8{7IGJ{&fSD~zFvJ~ImgL@FC#ZlJu1%GK@VaMq<8&;v$ zG=s_|Hsa&Mx9Y0Ya`o5;sV8CN8oS4bIG#QiDx9f_x$DF42sJdaT1A|E4n zk^dn-CJ&LAOq3mwWPfr5nMLN1rKI}pHrT&{ZuJ{(aGy>0<>XD|z2xKMPV#l~OY&zj z6dhU0rw=)l%pj+cv&e;H11Zl?m-y?+%gCF_`^atNF7gfX1M(pG3mJwnNc8q4lgUi- zSaLSGfUG0i$kWL4$*ajb$w$a%$d}1?$^Vf*k|7ui#V+~!yKo4ZMouPYl9gl?*-V~H zZXmB9Zzk^}pCEUUuaobSUy?tQq4+w8*dSbd&y78Z%Gpapx6^d4j@y=W5`^xjP#Q$$kpU}@)Gg}@-A{K`7HSgDGvq_J3c3W zB*R0se_t}0%p{K`XOr?&DA7|-c95r&*OGUV50g)myUDl6Pe^%Aq3HEsD=Ca62a%)6 ziDW)mPWs6vaxJ-mRF58l-rMPZhdmaIyswMK-Q6MYMgB^LW6dpk2a&P{7xyA^8QDReLEc8*MQ$M}*t52Sl2Ig(5#k0Ga!Ipj=o4p~7i zB>iL^xq>{ATuq)zo=Kid%A+R5?kmV^$(zVK$a}~K$VbU1NqI=U=y{%$r`?PD-{d>w z2jnN@m*ltPPoz9@LgI&zkz^d%j~q-6BS({&Pp2 z@<$R!rb@qulxIszdU0fbGKrKYhf8=mIi8$G$^*3}d^TB0o-<$ZN2)zU7 z9!w?+5&u}SMhLkEA=cjOgwV5|yo|h(yiN$Y&E(5M#D7bejo(BTBK~30je}=#hmui3 z$c-fB2N5Lx3?cUUi-nM1O0FbNBv%O`cL{lu5b^I4W?|kGBK}VDb@EN}T_NPY6Cxgt z&JBE@*61fhyn*B>GL0N3gxqW);>{HfH;iV6w~?ojXObI)klQFkyxW9HhVdZXPmwQ? zuL*H3^8wul$zMq)4lo=j+e9Jk^^vJ$COKXRxmn~Aa+MHvoG!%N@HZj!TtnW-@J)2z zL*6fh{EOrpB$}~mPpDGGW#kz`w37$PeZp+R_=W5x=Le|AG%{C+dhwI(LX`K#Ekxroy z>6Zy%*8(BzT`J7x`4aSEcvN~(JxZ^<^C5bN388ni5PCC(&^tj0y>db>dS?isw@8?c zeh0&)+;$7Yp(g}{y-S49dzlb=?-fGtE+O>(B81*d*=Ip-oe+A}J`H-~4Y-S04$wc9 zZUm`xmeO4-M0)G!UN1ztchY^g5b1BFdz%n;?4l_lH8*b(rp-g|JVacPIAX z_ePYRS#(bnW<%)z=C{v-e&yVL{;ht!H|ST+j|f*k$!znroskFs{_s(xdiVk2-;wP8 z6VU3U+B#+rPOsZ3a^Nt&r(FGxWcT!xVMqUAWd`?gCQ%XgXd$Hjg(2f;d}(2kNS-&pwLWG%tptAIedcHyHW ztlzl!<8&$ar;@eF9+_(Qw?%$8;ULjJO1lT~qb1+Xfa+hoGz^kPXQ;Nt1 zep9m&Zn48fNsEPW;|NgA_YzbFL2U8Wyf3zhoW#2n|91Np!<~YE>$2==fQMb*Qs|TT zh4>d*`ZnO+o{#l#+b=60_ruek50Mi+@-LU@lj~mm+tY2ZwtZw>S%z^@Shk@&arA@jLCAGg9Cfq(0=>>Hxf4b;bG2uL18mt2HhtK_2lQ1@pA}E?Z@&<%uJu|jkPnfQe26Z& ztbD8sN_V@hK4h(I<>MZvYqk4*HXXPPwDVgiXW93m1lleHtLu3!7qCy{#6B$D)MeTC z9OUffyvJsrtYIzteqg$meV;Q-YwNP_OUhaH9kc{U1glGapbz%}`$SIc8=!*&<<}c> zcKi0(?2}I+S@y}#UWsnYK538f)FrU;E59*r*LTpSPuA*|zAEYi)Fsbi?x{V?Z-U$N zkpPF}!}`RNmF~Gg=^Asp`q2=`Tj{>9^#$_bgT9{f@lcSy1n84~QHcL!n?8A86eGUVbUIe8?DY00fo75cK_Z(Wu>w+88J zu;n8S!dAKLqCP90yuWV0Eazb@7s!Xmi9MoAE-N30g3?`MOIP-oR=SnA5#3fkw!)Ds zig;P}$otUt`rTmDHx9CvK6zhS^jYzK6o>7yoF{9!Kt6s(faF7T$tC*aT8$ffx>woK zl{JCLNxZwYKHTZc1q1fs?7_OMbngt(cPI3DaD5ZH%s>$3Fi4brz6`j$dS^vRh4 zf>pVE6{PPV^pzsax-5PF3(^UT+OH zeL0Y`^!1{?3>6#aAn0T_*cNu8PyQ2w3zVrxdm#&Y}? zfu#gt)-9T3H#z*^s8Il0tjm&1&&nJ>-q&^g(Qj3cA2)8|pZ%@svM*I?f#0e=2A`&U zVRq^#-M)-5>& zmfmcn+&%tB2kw9z;(A2qRa?v?ExSG!zqT}Fl1j-K(mkcjf`1*5ux}4sP5aL**a^#E zE$#6kMltVA+%Mq$I^5Ut-ZjMg{&|cag8Z-Ca}F(bf3?*KT^{HNg}m4O)t(UJva7Z% zLJAugyY$e;A(sQWCmq`Ogi(o#_3Udgw;EUg+Z zJ!G!~aoJ1KYG=VEoKtZ5{(J59FFUX#rcd zOY8IG23q}*B-Fnx5+N)Q*I`15j7A1{m4lKwWEf{GFhlp5m)(1>afO$bi3cJbPrUlY zhFk8t<<*yyjraLps`kHJU)>s6OKtG6#=kv|RFn6{qOZUD#Z?nu^49su<2Ao|aqG?Z z23vpmYUJ(F)_1A;Klf^qIlhUUPonJ4@2F~h{=A2O6IipT_rV>luWmV`PVinYSD{g3 zytw^x<~aH1;G*ka^%)4aT>q-S?s|L(u&&j7Khu1`26X}6pPIkMlRu>M=OBL=`7O!M zTIPGOA{r|StQfFt!9pG7ssma1%hFWGb$R(HuK?xw+*)7oU=?YsIlw9g zmS3?y5OmsW<-=AyJfMrp*p*MptV*ze^X2zmNWQgu_-0H0?f1lZ`+vYwX0Nw>gH^Aw)&grCu%a&3Vh`4OjdeP(HUKN; zV$Bh(z*Fh5!7-+!d85v?3Ar{SSKj-5FZFx4U*`kDTbufwW?6ne8PjFV(#+9Y<=Z*>B)yZaRH&?F;9%5^yi)!M}jGX z?>L?wC0jH%8o-T4a3d}}#2C$>tn=l+ORX<>N>r4vq)_=&2UU1^tGe6WdKtzk<2YU! z8a2BfW2pL|S=ZWvT3e0$_h;#k+O3ZpqOr_H&{yUaufAMYz%|3wEaCoVd3{{2zmjX< zImQ&rb%R_x zMzD(X;oe?avK2@rX5clrLIWSd`p;foT92qe0sQy&X{Ccqw*22jTwpb$PA@wuQNjOV zj?(njPm(kUx=s%Ms=3mE>Xc>!81@2@)u(zUhnhsl|u{eMoQrOaQFI(3h1N= z{5#y(zS6=D+!uchmj%289zyxPWZ~JozZ;8NUuDrK?<=wX^{ps8&in6|2;OPtkIhd+ZR1RG-PI((Ne{MK54jSAdthF4%^9&A!zml?hV><%_7 zaE}@O4SdhR76Aj@X1En)1Y1?=*=G1}O95_G;9Jb_>)?NIn*!mt4D^H8z*`Dfao|DT zpPMiIHBn`tH`xyAiqF8M;AV7hWoY5Q$Q27tu252QC6okE5xE_0_gPCIHlalV;7jZ% zBUBZ+-{neZt>((jU}0!oL6dMLj%q`vMgI&EO0Bn{n$UUy65*@CqR{Cv_8nFv;R)v2 zpg_wEZzL6G2pIR7;oDfuMgdKn+z7lDLJRs6IpA!;ou*+Va~9r+dutj4AtxEVw3MZO z57p(A=g$XMB9@IDIg846ph0o#`*6PHRF;hZD3UJCsTSf(qxWNPDrcGc=Ic|@QE)$J zxq^NbeHsPjtWeO?(QQirtyIvjjlkJOplEQx2~bf?QkLF?_9g6aWk{Y78AeZqmrK(P zi$3b`N&$S<1$h8g2@taAl?vAj5V6*RmayVo+}ccFgQOJ2`r*9^ZxVKtS}~?H&Up$u zE(xoMK$8GT>o<_;aH{~7*6+aJ@b-Cs#z3vM-VQ#6cO@5q0V}NW3IN>&_k(A3)^kw+ z`vs^EpN;_+K2VYidd-t&_hO5s1~7Bl3Vn&tgg`f0p%KVvc)H*#pz|&( zR0ow1o{5yA=zCEn2|Fav{Z{BProBxh=0Ph|&h}j*D&dP(=E*0pc6?!kaJA7QA zhpo_DjEwMQ0)5j8t%mf4FBj+$EA(sTd%Hl7S)skG;Rb0{x{KJ5xgzo5vZoX!Nhs!_5u@K(4N~W z&mX;l_}n%TB*Xd{1Ut7~^7y1Db304elSNh$s>nScDW%q#;9l;z0#sXh=#bpO;xC~K z){CmmJt+OL(fSwY$sHD8i*-K)E%*HJPr=+~8JD>iNQ1W-fo)(_U^w{?lJ;X<5|Qpc zNPy&z>@9AEBpcRlh*IQiDa>bm2JMcVQ^Et-A?wFzL1ZNF6HxyV>&KurGM)Do0C6h{ z7DPUr_XL0<>py@Txl@2rBd`-q2%MiBM?D2_n&4Ba3tw~VOiF7Eix1*ND$4Fd(|p#C zmH=2HjSgAWXhvj(X2)O9eUVzt4k2xw0PAJ0h-{J(x6R`APUK8!bi4H^W}Zm1$ipt{ zc`zW-F2HUhFc-xIMiOCYwSsz#?4L*Hz6U}e)I<|=J}2z>CFCHwu=FC}`lOm@dGRli z60+{cP>NQ}$wf*|Gz^)HE>>cj`=Uz~ z)NOqmBR;xZ1S?{l1n;9O1c+OdvI^H(ectlK>MP_ zu@}8i#@Uh3~{z zRs`iKx+B(2pfPWea4{ZDvVcm-W1fg!gm&jGR?vryKm=kLm`vQsTF*vntK;)dL$_J) zM6bpZWfw!Jl*JXFFIvhcEsrmd#)d>J;tNGABGyMBo$+M+SD0Vo)_qYO z@rn|j6fd=2f@sDU36QYvCUT_!NiodgindB4a2@y^n4Y%{sc@&|B}-G1|xh{8z#*BOBcK*T=^t=A^)<{Enq>!dJKvq|MEm7fVlMs zusHwibNN~FBI^nen}0>39YCoxF#k#^I$_a#%)hGSL6nxXt_JV&uNJmeTD!rT{A&cL zww^@O^WUMxmS5S;zgB=c>%Up)I|Zn>{)3fXC(K`Or68R7*9)-GijsmG1lVHnd%gKL z3eapV#wgFfIrtE0+h#q3v6BBDN!bqR@hzYQqXlcAg-WekSj3nX6HciGrPBX!E(_uK2a>e3Q;T}YZ{yjR>nUM)+DV84835Lu%X&| zVikZT0<5sEL3ah0ip^ga{svS|aG3zsO=kGC3V_QMc(WP)2F6Qpg#vFe!=Hfk1#1NK zz1IwXjs>k$sUI+ndDnskfemK$Bxo)s;RO#vYDW1Bh5_Rs%>15Vztmt&7Slzm1e4W8NU-D9~aie#(0C z(7vKMi>gtoH2^Nmsm$ZkP=@tulr~3=WS?~fvdpOx-iNHeK#u1u5g=l%Tn=EVSP^)C z(mfETz*ckKS`@c%5@gRCWk>HY7q%m&m=f1jOgpChtUWL*zhir-rKGV+ufg`tv#IqbIB5u+q2-DJd$8YSg&i*K}U zLL*BmY}Qsxyux_NvK%fVV@FmQC3=w%JBs@iDogChYNMn^?nAMoxL0e3h!I!>E|%2V z-(gWKA@CsjxO8cp!yvE=;$6Biz7p|R*+M;WN#-x+g?C1<6Ib{IZd-)h+i+iGLJ=5c z)q#5f*i&esVLw~PYaLL^>~G+@#(o!uWV_vl)Is}fRClS(gNg6A3o%YUW&ae{N9+?| z)wA|F=#|&)U#-T~D74FZbEw3vJ5XX-pNv}rCNO}0HHc&QW`j{SpvJcm$U&pZ25r)! z2|FI6ooRoM3dAl3vrT&yOSCV;1QxKbC`6m=_u(3{KZ$FO{Uuz(_MfQQ?bR#L(RKp{ zWug5z@Qdt0NX8udqajRP_7@83M&Nr8y|S;^ zzX#QYk-7VGC}mMT>NEF%l4K*fQi69qRY?mo*?SaaLHriIO6@hQRM}{#yq1KIe`$g+Pt#p z-H1?fkysGp(~b6gj6%cy7m`go2ZCwYYcZ~|tho!cBo^6zAO*g*8u!bRO}H<34V;K1 z4$C8st&rQqk$D!P3~LkAMB?b&2f$CCWus#g$4Y+%AY=rJKz3qz;_b};@M3g);`smI zKGrvK%t&0e;6_N6VO@&ePFyJ+;j{QuP2y?+LZZSF*9Z`a@tb0aYm4|OX53l_iWAqx z|AuxaEc#FqH;4}mxa4uE$G;LCk*^ZddI544*t!b1tKz>W?w@dpvu`|j zfy*GHiPaS`L}jSK$@NvMz}1=&-9i`bxD zf*#mNrtFJVx%og{x7}T1@U5g{1|j=g6a?cR)oKoZ;s^p6h~X zQ?OB)HrB-;uV9k^0jnDwQLtG6SemG};LPaHkR@zgMqrBo5$pUUfQAIy5sTJ9gbEtf z9Cai%gl`EIYz;nxq`0*KGh)HEQg&I95&SSFi@*obyn;5HWQ$aN1vf&LU+zSu@nQsT zMN06a#A93Nzf&l@gOizDeFV30n#Ji7jNoqpN1E8)FPc(i2^uwjK~V_}x&$uESbpFU zXtepscnxFel8SG_MO3O0r~~&GB*YtB7+J6|=NOW#ljyJoY8hx)pTi8kpuC6)K5IRS zT2LWC$Oy8WKm#rd7TImQ=Q{%yR>t3l``~T3#OZ7D^8%wa41^!zvT&))CV}l>QvQKL zJ}(>m7A|>z2HKO%zzbaA7*v5@Ll*LT;=du%A8?6t;ibkt(T%``Ngxcw!x$jJJY3>j zfcxbl2tlsx0-vt~*1>okvDOl6i-TnZI#Epi1(FuHj@6A7?kC<`aS@uhh?5eH!0*=} z{X)Sl4CPPfd7Rn& zgz|67eGVp8*j34KCu2@N-{6X`LYVG1N%24#XB<0NL-r z)M41U3pvs*gr3Jj>_QB2>#a7Q-qpB$v0mcx+_+)4KuMeSIbe@vr_eZ`-HT}?WZN)h z^6c-B<3`{d^ptghy$snlM67W$=LGJ`e}>U8W2!ZB`IRW`u&E}x@)*SMh$-VFWX$_1 zO{|LU=_F0f{pS>GW=eI8g zPQbnaqz3JGfz*(FHIzY)J%#(Qy$-eH+9~9U*vC;q)IN;7G5ay#>>q(ubL@{`>=xVSLxfB0<-jbp=Rr@G*-tRr_%MTjn%UrKCf)r??s1WRJ;UkSFE?^B0*ELDRv&QZbVZJ`y2?9X+MB+fx8qO zs%WscAURM839V?Je+2ghE70fl6)h`Kp*43c;#|h;<<(s$xgsQ2=p^9@>ib!aD#IS({kn&ca6llv>+BOGQWFO8^qq>tIJk zXJH04lAu=(~!p!d(EWt)0*V6?>%U72z*8BEXVuhnqk&zksi!U~HM9|AIA0 zRzi_m8>2VheyfP+ycHCR^N_`|cVm><_P;^MeD3F-7zu+(SfZedcbm_oC<^w=RO*7*sVbf&+&&zJ|eL*bV4y)8+#|5JSFi zWYI?Z8%Pe!LmL%NBLTmjNMIOVkYxsuB1O z@>ebrV=Bn)oxnqA(Bc*Gvxs~Sk%x%PixK3WaG(c+Y;jHe2x5Y7!zF$_E`s2v@vd7@ zwIKF6#M}SCKsM~-P!6X34EST&hoPx#`(^UY2z(t(tg5tGglc`&lGrbqZ!f#qei#kL z4)2E%Q?<-o4_g4ZpTmnkN%0lR#j*J4{!^Ms@CL;1J7CreOXm6 z{xc(X!N5_YYOP*_RiT8cb!rV}RbvEJohDOsT=qz+PM1BB0_)4*W7P(6BNZBfYr(Xt zGwc!+9e68Lbk(N#)wmB{hfAE>(|);p7?bkSoWqa+!=CdI3@O7mXCH&moLVpo?aN0;pnbi_hW5<`i!l#fxC8+k zu@tP3M*NaR7@+--kPJ$n!Kgq1M*im@aVWybZxZC=M*e=eG0gn0u4NKlF!7|i@#Sx- zlbBHcPo)YYp8tDwlguAiNn5b+1}B#sx5-s;PA~cCx~*VP;A3cW_1yS1;7IU#T;kkn z^~;5Z8mwS+Pq3D#d>`7;mb42D(9?3|M_CQ6G%|ob|LEr=&5CD*DlA3BYm0LvO09b!;dyHWNLX({x98OhkhFe< zp`WM5XQfpGcITZ|aTmn3+PVgFXWn|5##Z2H5^Fu(ZUohZMa$>qoC)?>GswI=Ar%@H zjm+iq1u(5+=#1qH)YiB4J^~A+mGI--55ZiXv`rLH7+*0j=N&AGFF#q45Sk3@Hps(@ z`NdD5N}qKYajv&I`&*N^@WcVkUMGS3 z%_@QW;70HsCxLs-;zU0hQxK*Sn_hOem*hjiTPh7ze!0$OA}g)vxDDJi8! z@Od;dP=^s)v)Dcp#RNVD-B)vU&6jas@d;cW$A1xY9kfzm>B{*zd1#4s7kIt0Jn!Qm z!myUD22c^9JHlsu2-#OI5+G!K8WgRpjPa}wdSMPqS-IF|frX*kc{!U=Qmn7ns7=h{ z8p{xSsCK>x5+zOJW$)6OpIS3v;1vR3T2 z{tNA>>lfkJZ(R;;RyR<>ww+_`WIcmI&Uw}h7+iNy(E6>%Fly`6QJaHSNfN*XvfDgj zJx~i^M9?O%paU>gOtmp>-NE*Z&*32asP!`_y1I!u97hjYKR|ljWP;m9-?UaR&y)a9 zSx-SF*G&uXYG@(JIV|moo1rT(tm=*y&;yq+L%$+}j|r4CLkY-Y-No}bDk{y;_aUZr zm(@G~Xrmc=h|rZ~eAD7xX2^yh)V)K#r`7z78R{aPUn-$?F114Uk~a{)z-V9@1orT)LCz5%HAT@ zx8C{@DvRzDV53EMVe~8kwpfiA#nJr&G+Qr|oC5-EvywRg&Msst+pT{=UZQW2qR+8j zz|;{vC;!hNy5D+`dDQX6gBCtnYeZ9mHewB6{726dYj#@pG^4%Z*YcgT!#`(>`V{!E z9sVycAlfgW`As|gZp^^Z0R`f5>B3NS$j=iV)*6i9=I8R5aNFLmPvk!12jt*K?E`~(p<7=>}uUGfi zLnWuc2g-4K@3%hde?kk}2Y z)qN0*I-^A052NWD&s6uvQ069$lgP#W8Wq0_v~Aw3?r(;IJ5!Yzq%S8@0m0d#2{{8I z+ptI>o`r%NOV#}yn4=msAx&UuQ-zBE8`#&Z<4=P|Ye}g1Z==E%-O!&yELs*we1NYQ zHRmK=0SyK7(YRO5&C4*zt)vg}XU1u38FEV3+)@%p{netw%?43(FB^rAm{mE9kKucB zhPfop24EXLhTPQxM64W0l(|%Z(%1yBmdSl346Z|lxmQ8UeOh zo6$UTr2yU5QH)-*R)F)Y{m>F-od6>iy`|(VQ;VqZXQt<@jQjIAtzidi&n<*?e% zGEFW*MDT+)=(`PK+1l`ZHyb^ZM((!(x1RTc8%y7&k^2C~Uu)_$H&%+tJpv`v+FAsn zJT1)Kfx=sxmSx4hl84ygEpF`VC>Cc93lZDA&yD5Yw2@l}%dB<(NLFk;Dcg6s8>?st z!?0=XzSWIYCG5ozYTb2@8>?{t2$r;Nc{nR}En|CsniV^WDYA9*i*Bqcw-6%Q`qn_5 z(_-1_$o&v|dU?W)Rkf`nAC}=$!x`K;D~8y&Y;$8(x$`mcwC11d#;OtyK>fGYO}nvz zTk{Ew^h-?M*KC8h9g*AIkFyo4PPn*S_ZW+}pxmujM>sQlfk|?a!h@@zmMd>T4NH2= z038TFcM;?;e(s-;R=Mu4jAed5&))bqBw6fBkms$(q}V9tPAS&Ny$qFA4lG~<1>UH9 z8RKb@&x&zPwwBRlDmO;(wzq`18r#8Gnw1cRC}MlgVFXi*6=u0%TxX8D#jU)bBR^~b z56)lw&D(y2#3~*QLiBRh$pvc!{~Yw5@x(TmmuQ&5LcfH+Y3|DTcl%>T)txnWVs2*{ z9G;oc#u+Ctotk{5HmuzsZg2b1W=s~-2aOl1*peNH--`b#e5}TJVJ&%cA;1Cr=kn0+ z?+S>255P|{iqACsUTnhe0sJrgeFeCXuiL5c%w5(r;?RA@NyMG&iL2LflREAg@LF}= ztI}~f?HbQ_Hg4FB|LGQDn!ByTsHDp}gv^6F{i|-eQHw$)&o5LQ8DuI3`7YPx{wZCT z?>fX$$|7qN?Z;5~ZtDmN|9~!Ng-)54lyv3f2wS+t&1v`^)TJG8<4~Hp%J6aSWlJU{ zLASxIGklNfgsa?I4BvCQ96h9*DDNt}#j7ML_7+2uHmL=t891 z&6_I?-w8+GygLJhGX6WA@~MoJi&!U4R{37l$v?x!m4ac671ce`;ebJQ5u>Gyln zor(^jqG^rrL?(g=w!LK&gzLD*_^pd!_-;lV+x(g*?xPwnd78rqkYdlAB(Lo)8&T4y zG)99LLvcmP@kx!)=S8q*PLM4M;}MNVXYUzo_U6p_#?*+RO(xyaSmkS zNC$A_5QhgVN!_T6WB6{<`L1{4*z+Qp((`xd^t&_C(+c=ro&Md7bQz73{~?|JM{l}4 z;}MK+YmE5m-sVdUN^+ji2&*y>ghYEAMeAve(3OFpN)UuU0f7x4bP?ckf+^1Kz0!?i z!)45JN{H*^k9(6d#BhPe_*N#y3nFFGZ_6~sZ@n0*3MGacfFSbkB4BvxO!GH**&$<| zbnzh$lD)~BY|lK*TA9wTJF&>!Zo1(+qVrtn#<8hsHNr1IG0&B5y5Zw-YS!~HH!hur z1O9|g|GGC_(;*#yk4AVQ6Tvf%Kd&(&XLwqwMS~)XWFKFKMbeTkj^TS!=iB1OxjiQ~ z!*e>l*PEUpaxZI)D>5-eZz`GdVWwfdx4IY@r-&m<9(3cuO9YBw%jGdtsKoxaDLt`(ki#-K(xoQaU3@A%y< zHt&O(IIfmKvhNa&^MytW6zosIjWn{N2-(s}YWISo#CC)xU- zPOm#PU5%oLHA1%+L0espGJj0t9LdCS)gzL9Ki4?7X5zSwdqJl^n3?W2?q#I2agVs^ zhA)6FW!zJqxB?ybvL`NyI5NKwR({&uo;mev25YZ#Bp$_<9J z(GPx^x1EOt)e=4~R#%pU{}Yy!5C0|iVM%)iSC9(Lliwefa9Tkw~K(T`Wg*oeSW*xcL@=IDltx^A!FYYXO{#8kzWBC8_LOJH|)VO8q!?Pdn1kctl?(N zMCLq{e&gCLx@;PLG5n?MByQ%i><<8uWiJ4lx0o_c$hvHMnnna`RE6Kq!m*Gy-hH!E zI1Rw{PT{otnpyZ4b>SCf6kcbP@tcEg;Z%paF{c>w!`pEz6gtzuvcugcQ=eOs7!q{~d9px!H|#XyzCanv=L8%{?v(o`Of5(9BPJ z(nobkI?>mGIC`_*=f;ud)v!E}KTYBj@iB=Y=29`tpHBO4x6arQJP(cR`6!?#gmKjOjW zaAOZW=f(k9i7rx<=;DSwWJAo=NH=o0oRaRl2{-Jaq$lwMPU2^9Lk4Z~B%X8>qou&p{mBx-YtMM27qvL;}6Q;TBm6*)zapT=HFmoP z`#Qvt#6bu9K~ZWDXKG?L=$HrlE**D+Cyq*$(*1EaPPg$;d@!*m#H*qIxS*4(bqWmwEB0O>tJReg^k(j z!7e}?9q~O5_G5w#hL>vW84otMT)qhG8{9Y+jX}&sj8Yc3p(y@`ivhzFab)kqZX9z_ zSs;OO|KAx2kc@sLaJ2nRCD_w6e$nQaG2G5a8e0*CCsdCF-!$UL(P}qN(8;2Uk;Dy( zGbCxZ3H$OY9o6AR<#3@Q^nVdI9A_7}CBY+zIFfm#8;8i8wa}&P}Ovvj8`ez0$eiSGy&q&bi^cWF=-JZlvT!ePiUnCK4~S z4>pr{z&FCmA-h7a8oozCQWPxgRB;%KW#=L%{pUo131@7YSqR{v0B#K|%3*@hr!B_R zNinA04=wQ?{5QvuT7dr}Ourpg##iUkA5QRoV)vxAb%SiSF02yqAc^j=YsrYkJF;y15F2)ube&)WYNt3CX{_n+fe^=8e zT*b6%8iVb!QPMD0jXl2>tH|akP0(@QVyz>ciHTy~xBQtEuDk&)u~u2E*r>wayp2|k zIQkJS8D2r%f55+r84)Qt%P|nk@b`t0iMwR?p&GVNxuR!~LLPBf?K`KWz}_{u3-@ex zN*zhyh8;>uZy!MTJg#!1v58Gvj;2YomRoD2SzEDZvfOH9vl7>%zn5FPrHO{wW>}?{ zlp;^muwxr?&&WMJx2J|=`R z3V{&iY%`b_irSkJ&Ak9=xhu^x%XFRPfhA=d%UDIE-c$COh=g!va;Ju%XE4R+j@cjAas=_Yw z!N%OZCHu?G1G#6F`&svbwNfQM+i1tgfuuCId@jl^kF^zof8as6u*E5iT~=Y5iUo_x zk-ru(l`fA_BN?Qayx5IKcc-JPguGluoo>MrMY4HD`J*Nqp`)wa=qC)-wxz;kf0}{I z<`^s*!shKiY^dqVh4OUA*Q~^$0&=Ge^_NE!RTzXT(RV0R=+8F`0$WOtN$=K@@t2!r zN;2zQ2*Vw;g*IgM#A>Hj=^&QwEo@D`xj0sc&Yc(ATas_a(XsWqzeCWN5O6Sa9S7iP zB^i>l-YbYWYEhDwG?ABh20&@+kHjz z5jB5-CrWbbOd(_nT@lMpbt=$U`Q~n4{vos5cjzeaj~*ks+5o)WckDzI2`8ee5FM+k zz;Faz2hF{{k(;CDUZ+qulvAQO5%X*xPF(Hs#m~Xr!6z(SpSFI-;CI#^EhM~R z-w-v=RweW5GYSz~_)OS5OP8prod;^?{UQg|{vzj@u%@;CPUCis#=u4G^3A(8$2{P> zHs=>PM73mJ^LAu?D2(Wb!m0!vjhvxMTuz3~ZUd_j`32S?@EJc00sn`g8#0QyGv^u> zb4~aoLWolgv+8U&kkC7GJ`x6lGNZdyG%E^;7sIN*-Mu&W@s?I^k%}fM0m43fI&YsZ zF3c(N!KWaZX!jObb-Wi$!daNN08`TF8}J$AxfL@Hc;ozFtv@Ec5F%C#WJnf_L}ZCU z5@K_G)7M?%);6t8e%D0%&TWz&CwA(rqKev;b-1kFGUfiZI0NDf%?@Pxn<0 z=*g)-4Hb)Vx43FHnRQWj6Ll|9cWYEfGMiBOX2R`;}L!B`(m45{&om;_aFEt2a3xvrP%GhyQo zb9m(TPdI2`ng77d3hSC3h`)))Yimb_dq)lpjnqyb92gy#svR948#h+g4v+PX%=8ar zr>XPM81GuCJvcr(P}?&yQ@gTnd~9%dsJ3Ywx%N&COx6yKjQ948?3o^) z>=_!Uof;nM9iN_BIWajth0>>{dqzfT3DiuFkB{^n>=_=b85tg%Ia1p*Ia)I|J~mJ@ z(9=8Y5;EG;cW`)Y;Qz-Or;bkje^MJ5UOUv+m(|WyYgVpVxyotoEIlxe4w{^*9ULAR zNDUmB7(q8ovLAGp%#wpWHA{5=@YKXe&(T>@vv*j{>h%hv*dBa;SG|9$NC2j z&5})|=TtFsN_&H3Mc^#Ook}@NAlZZX%HsbjgQux)TD!w=hTclvghy{qos-ci@P9>Z zcFh9!VT{Pw1Zm?_JtO}wOZvacK0Vxb!T(hTh~W6l^wj?7!r|fRzJqUq z(AP6EFxLO3mGIl1J(B}HZ&J#1Pw&WViqxSKgRbv_H|Nac_{hk>o3-`utbOm)fJYj8 z$9pFG--O8i$?=K)@x!x8kW&gK*~!^-p_8tbT5SpkBSg0j|a+wiXVhBy);}(aJuWO^BMBJ~}e6 z@*u6iRR6$W&& z_%d;tDr}r0c6xYpVA2x{dy=uV8a=UCuOYT)Yc>Z51}4H0l3vMvl>0Pwg07#SaO@8v_jE;Kv}D>Q}o1G*W#M{uiJCG2n^r91(`O$a>UARtBZAf*B>2PEjO0t}xV zV3!?;fg=bp(#3$_Cj=xN1PJ@X3fsjK#sg9epB|Z_gu(v{G%`FjI0}h8;_b%ylE|*{ zG*b5>8tI9|ngzuOr>735Mti2bi3=r>6?$^0iWL_;(MiEo3jvU)I$BL50LvxSJ82-Y zLPhpW;(n3bt7!mWr2<9i16(Yiqv8>Pr5DI{6gnc7s0gZWK=7O**-_SrSSk@pH3M8G zAQUm~m&?7Qb`b&Rv9LrbSwz%Ggs4zWpWuEx)n)mtjs9q$_CR1`U=y(I%dPExbCEyi^niWkB`dvo z*E3JjzgCsRJpNdRKOd#B7<16SNg-@-5q6-!hQOvae|QV(F#Qpg0(ysrh647FOx78; z??XKq$(z&FK7*9_D>B(+1;1!&qS-8nVDfJH)_&fxg@KcO+%7i zlk|rJ_Sx1FGc&(bQ|r&E@h{x$&shP=4*-A2AKpC+o{)q3{NY`hsnU>N8Y@}HotLuz zGI;9`ug;DFRsQhWtXQ|nGc*2hS5_i&1nkqK8J(xp0Fudtgd`7VC%fee+9}kO`@VVsriHjOCiVO#`7zm$!VAV!zH5@BGD?Q-u^Krl- zEgxg4Hc-1`2kvYAemKH06y0(8Ss9lyEd3BB4ncpQTtBjXxK)MFX1(3;lCBns6rAX9iZH@^TdsSm@6$ z_wPis9jM8~$q5wi@E0P#xjBo_q>n z*AZ2DKviv32>vl8?ME!)hNy?OiA z%vSmAt@h8}*x3p4u;4?Q)y(emP^1X+UWGrOQT!oyzIE|Ryjt_K_R5tCGB+s}ekzUf zT|xP@M)~f=rfzS*)Aqos<$+b`;nQbpEBbQFvcT$12PAQOl0g!+9=A8*F*(4VIh*s+py&z(_ zO`YwXU8&a2uAL3tskVBY_?jhhwJ|l(GnSef8=jaLm?nvEC81Jf_@!hiWYBU>O%4oB z4on?1hDV1|2M2oKMNn3|p%y27SPD#IjhaGcv0kTXx=tGtJ<|t4H|uWf>}qc5O6_TD zZb@}?cC;AM3};c1I@mMTkA?b_acH1#8kb2_Ic1EDj}5`99l(l=6|tP=u7yc!2d1WHCb5zko-|U8aGkSw)qSn)d-rThoz>9Rooa3CXxp>R=pPs!8=l50 z0@RNWu>s_(THn#AM0t|~6JT1Z4_?x&g7$PbbagXw7s6E2-aXx&J5g}gp6;|bO&fU5 z8omvz11HB18#D0sPQr^12|I`-#TY9@0nKfDcC|MgNOiSzkoh}1!Ti>}?d|CrcQ$nG zXlYJ0x3sr(x8bOctlhL+8FX!=$RE{(Su#~$k806Kwg8ROE&?qzZj+i@T07AMh&7^` z8k)AXfSNrmUHc&KogK}o&K)9gVp~r^2q${_Q*04RRLfOH!e1$kgTn%kX(CCMreGo# z>(i;8zUkpZ!_!BVjP&(P^z;FO9B7e3#SjB&d{;9Xh2<_^S5IMBwN475Llm8L2+bdZ zGjL`A($@n=!jLi0GdXfJ)iW_Ma@087gVxRfVFbw|13gm%N{Gie3P+4FIJ7{}Bv!jZ zEXG!!h^%zu&W5%QqnCLmdM0~D2d3ebN;An7>W1cKuu8Su8FUaI@ZiFkfytwW46MnS zu`v<{MsOWFIMOqOW~57FXSNsz2Zo0ZP8);hz+Mh)CGaC7s`M#iYNmJM2yTVB6-_g>&t*dkI)@|et+?-k-0i?x=GB!OvK@3*`iD)4fXp``gQsm)#)snA< zd3#I4z7``rh?!rnydh7ZetN(iD=LR@c2_3`Zhy~ok75j@Zp~^Sv-yKlAOJ&0%Q1wG zWr}8m*J~P^d1z;9RXt+V5wqta)w+Y{om0XtPxA?%Id8Wok z4xw9F5evx}*a!CR10$({un(t(l&jW71YFfKH8V=WSUOavB9O&p$F8g}h!0O5@FP8N-w-Ozu=Fs6sp#K7e6IBTLm6;->vC(X#JcOR_RKXAYNdts9+H|Q8tpr(F}qL{3Nre;Yir~B_3Nc&M+}T%j2M~CGemz+Q&%TsO!@Lu zgI(UcdKLsZlWIoKN?z$&J!gsAA9e-(L;Wx?IN4)J&N9n1kh-<&)*6%Ju%9^MsSGC% zVSJ8{Ne)yheVVC6R8Q{PbD*Qi5EBY26VnQ&NoYSzYM7P#Fh^2}Djv#oEs8eHy{2t# z?RsiNm!Tq=xs|UetyZA=N5=b7#|9?H(HK{Xx>{PhQlgru+xN7c-NF)tY1;l99vd9z z(D!yDH4}F0r^iQGQX6LNeQM&81_`UiCkDpID!Q|czLD`M(N(}!B8I89OG%6eUd_@x z@R}^RUUNaFQ^+ssCyORhQ1_ru8F{*&X_(Ex^(^LSy1AWD83$Ob*7_Zt-Do~+E_aq? z>y;Nz_^7N)Ws}J?oEAG;UYf0HAf@HpYX%Gt4u}>Np`F(A9d`u`oLCrvbU?c~lZ@}g++I00R2q^!<~-CV6UL%s=LH2 z6${rj$}nrE`er7lFf=Je(7dYgGh;ZMF*eYjq&L%0+G1*WbOM`Rz*7!mWkD-B=~aV# ziu2R7$L5q)w+8?b5+@uW>Y+B10pZ3&o8u(5`iRf%Lvb6dC4i5`LPZrj=7QOa5sI!h$f z!J`)+LV~&# z7V7yHXz39^H@lwy-F7+BohgL7I@>zB6%$)KvC7=qeqh%&cTKpnVQUM_lF18Fz0w!1 zq_noT?1wC;I$E&M>S}1(VGP3#nCuywGA3aZ&rE5H{G<3JYq5{=QUw6T9ZQxR2YGB|3G93eOxL+Cj#DZ#(#az?guCzIM5FL+x zHL!u1I&4sNI6|j*rq!A3B`XWeSyN9BU^WpuJ|)ZPbPF(<8#HM^f^^s+_LM4a+88(j zdzA`U_T{n_loal@PsRF&fbZOcW{qHV3oQVKLWf|@fJS9-gmXnh`z|~>=N2(DMSY=0 zbC!i8TE^ub=J{P+olThR4ak;O0aSBoA@0HArDtTgMrBYcSsh0MJJ>6|hX_-+fgGn-R)DHWxSj!-IpyD9k<4qe=(JE%&NZ=v}=U>Vw5`s@S8G$tcy# zez+AT$B&}9im^&uI-1*>8fd*rCvi&=?j(2>Fi&a5I32LJJJs2m+S#&GC_@=^(MZv0 znRV9HuvBE#OBaZ!VTa4kz=E5AJP{i9U@$gOFZW}Y9QukYm{~a7fQS2#MU&IkA-NlN zs#Pvi+#VD=R91rqR0sSh;9<`QEx)5FXGJRvHM+2TQBy-x=UzvJDHYMw(9zV=p4l|V zJK!#gGKN&!sZ&|osZ&{7J!#F%xE`xn_^+V(u;dtkbURimjSAI!j@5rk-uk*as18_A z9JxTJ>|^hc3raAb_U?!*O4RUC^U6T~u;A)lNo^!huZhpYIcHX^wENv92kWTpm3@Mw3Mt4JfgL9PvIbk%yYVI#lX=S%x5kY%54b47B!+8-Q{pF zz?}iu6(y|pY$Bzw+DLKS2)TXdODYi_Biw79Ypr7~X1Xe0X_N7i21T@m0Vw zfuqndQI+{{_#mkDREEBWM^t+@l!nFta7D$LB%sC|<2J3PMTFTeG91;RD2z*pxw6Jl ziq>LWyR_}xbxP~^cI@crJgbB8N;rh#)Q*+|EYqF%2;ek>E*8Nsyr}3j!?nsq!J@22 zWnOS__VgnYbJC}4U>4D~mfJQFM7n5Y!u8JBMAN9CDR zO9-cr=*xC1*wcN0ZX>-3foQK6Ml8t=Sg|g;mSU3ZXeR16rNLb+k9a^+O!SEUQDy=3 z(a><8TEX$KGMbHS?kLes*x9)gJ0yE|O4_c5)G8=e;Q+rjpyqL|_(T?@EG6WQ1u_O# ztMUMNAXlApS+I+SWXYdNg>uY;I5iG<)!u3GM2}Cv z;V2tN<6|l66xqRnEh(a?Qb7F#b}~4Lfb|)gLp(2Z47puN%S(wcT-S;w5ol<3rCyXZ zq)Z@A6f!UM&h++zpF?W-L!XEAlG`}x^jY==TDrQR*HL+vMc3H5KecCDLv!a@20YE_ z_KiaiQ-w~Ut;lsMoA>P7nr=%*Qyr1_cq){lr9VJPrJjj8_rbX$D`{miC*2i1m)qXO zJi00^R3cBxI+4Yj*x8t}++Kd;**CrKr1UA8<{g$@ZCkf>vsu~0My5t|y4quM%+M@e zwl_4wmQwyJ)rD$6IX+CZeE=tr*}WX%8TGV64W1_)A&C9TUN3{Tn?&T0c3&uCslJBF#qnBMXsXXNNKb2+t&64R?M*WsXDXT;OS z;`rq7(C`?nQw%NWbE9|Q*zf?}(n(`RG>2E%I36GfXQlSF?P;SeL)x*a0Lp>p*_qkP z{m1q;Z2PhuvTzn#!#hfFQZK!);hA4CZ+Pp}^MbPdP`{LzUVLf81=T3|l8qN3M^Emu z|0%l(;=ajdCbvJh3_=0U09K23_J;UDuo#l{GjghhlK8h98$b!RtCQ3Oa8APtp5aVVk1G3HwTqs%X+8cq zKfC<_=78@wVNGtrgW5N6aC`*TE-};;>*ymzE)EvMMF*y)u&mW5AROYsM!1L6A{*JA z1E?;G&=asX^wL$0p5ZY(%%w+1@643mGe%}km(m$Z^0ra5!3J&;%XXcZ+BhSCwIJ7Z zQ^w#Fx9%`BUHdNOj2*T`7B;FxrM+bTSv)p$Ho~zE7AZfvV~tIX^-N$66DjH+pW(9) zY7i=`nWI1vhduR%z3ttGUJoQhN3j#R&$lfz7Nnvl^~yzZx`VOe7uqR>?|L zX#};ee~K27Lkx1l!PwfdH`%m$e^Na{nOt4By1s7Rs`_NjXy3%lCU}N1B5Qh12RsOP zY+!t>W^iKFI>O-JbPXOe-GpB0N5u5OnbBT^m;?@P!h@)XPOIrzK02{{YM^hqC*x4E zrgJJ;gC{#S4UNsLK9Z~%9Gn@0j~+z>l_8P`sr0?@%ox^V{WYSx)WI0{z=dqr$QE^D zTlda}T_O=`7*LOMGY01xsKx0<;nd}EPpK_cs0mJ>>8mI}-zd zlY?=15_1Xng}wWmZ06cJu|#|D^cgIq3q`)269f&-`%>`gh*Jk#^H?9Eb$Oa$c=AFy zEkh0{2SYDrAUX5Kc?LcKYzV32+=&={cH* zo>Z$bp<<-TLMeMmplviI%&O`sD8GKKg26cGLmro!nSh{hZ2*SJek&BUj04e^)n3V%W3mWk7n?JMjJNYG^hNYp$gGL^>5! zsE2NJ1){rImYT<%E|N`hbtp)VD9Wu%xHORGQM4mR#;5EI(xTMDs+|DJtFI0*YC~L} zl%X*UUyE+V>Cy^45jO7Ka{zniC`nH`X^RVeft9J(UrRTF9B`Q!$0GJ9cWq$F0Yh{M zEIJ{8t1>h_EysFY!mSDJ)Y2J@aX&mZh8r>WL~z`5u}X(z%9(N$(~F_j572=eJ3=^` z<>`{fy*Mz`;S6GB`f!TRB#Gk%gJEWLEN#HasD@c9ug*AEOI;2}+4ysJ64bEEV2|1{PO0Y0J}GBj zwW_7p6dMfA=|iPAwzhO*&$zu+oxo9tIlzNc4KbM`a2A@*H>Ll1cu)?90AGz)#e7Wn z8Ny9T8W|YGJ`10hWST>d*iN#i;fSdsN*|nb)lhn%a0+y1P+46zbcl1=d34RuREJW| zGjcknX9iZO8vgVu!1`4-Gxo2s+Tz}f*sFTbH@9@O(QIL#V0#ve`&C{b%UdE&Q8{8E zG9p`$={>qVqMF%mwX}4$d89L)-Z+)v>RhvE9<2Tp$(T&AE6zh*Ly9#&IYg0(xRi_$C-!=AD!tZ622QCw>f8phNRL7*smc2krPpG-!Ap2*$#mDDgeTACfDxVXt}v^E&D+kBB_tZ5 zM^!fuaLRciSA%5AgbXCk%UlDfy;$uGbdEeIqB&+U2%NQb>UVqs)(U+rQ7OKCr9A^`0BCVEE*h>F5-oIUW>Lm@%t)rmju znP}&;k}q|rk)suZUCunX-Z7TxkiV@B=ifUV$s+TV`Qq--d51uIOKW$!X^v^=9q;K> z?@3q|>wWlH>wyfn22jK$D?O%aSEe&onK*e$;~6NT3DUy=jdo6FqEV-+JawvWmUvlA z%o30BoPGjE^V6AA9j&9q9u=!I@wA||Ye_7{sSB|EsE%(bsTLLGIoSi`^od#kXobj_ zcrwvQb?BEf7!;!(R!S++g^Pw}%+Pxe>^qQYd&v_$&=h>)fr~ID1IVYwuhIu1P6+RhGcca1>i&GaYv zjxD%LR@X0Gn(a2h!{T`11HLr=`s;XZ?&4S^>b|>-50djeXHBuXD{`(3T@}1KaE<>R zzH9AwS~r-7!m-N6N5Av!Z+-I{U;o;}F{3fp&bMQgNoLYNz8kF}7JoZFJ98y+?0WQT z4}X;}_+x#}k8fj5IsihxKdm7adOPs9h93obV{Rh@yg$MH@!e`D_X^*Y_Eo^+!}{)z z?^|n(C9eow8N4cRwf`F5JM3$L(-1popKpa@$ws{MqG1Ejd-%FBe7+I4{?lq2j6gWp z5HfSDupKcAd`0FQv&1en%gniE!d&31Fe}YvW;5OflJ)b(_>7lc_a@`nJTHhhg~+q{ zZk)|`hj@NAULS&&Tu3hR-2#laICy?O;Z?nxO{HJ#fs?>Kf%l52A6`e|`Pu3nhHi|F zH#8(&h&QOz^Rw|Tk<9vY_>Kmlk9}+LT_c{KZGgF+pN*bQdf?2S=UeJxS>?wBAFt8S zKT1pbXY&Oco*zDUpH)7&m;T|quUX|6s`niOg>q)`O(341jn{r8Juu!Hn*rH)-A86R zUjO0w*^tsqew7M7-s+%#UMXh#`F7y+&&GQ{l4%fk{7yvrXQTAY^5+YF-0gprp76lw z+^i2T^YHv^L_2vsv)NS?~|D;NND!f6s!0 zW;%lOmt?_JS@8NScv}{HRu(*z1@oic&X4uom<97A49<_~_hi8*vtWKi&-oGmsVw-< zS#Zds@`zuS1uxHn8?)ffESO&$aegfC;w<>xS@4}%@JYZVk@HRg^pCu4To=glp3lPn zOBT#;BrrecpaP6{z8u{7G5=DX&UvT+qjh6e`pzu4Ckvj)g0ISg-=78FnFXKBf`60+ z|2_-$d8P=`&u^MJKfrRbBVI!P@W0Kospcc-P@66v#nNX_uhxv+YbUph;M z7nxWY54Or{{nE(Z9eUtqJGtSc@SY?P40*o*mY1?D$T$sy}IhvEbsw+d5z z6MRTewoNldNIZS0A~RMyda|SSL&ll7`uRSR>3SJF&kVR_yV9AKSS+q*p%VLn8D*u9 zz|en^mFVtEh~M3LY|*WhXCU>CAmY@LR~^F5Mv*iYo^GA?+dKK(y|pxkT29MDsu?-O zS(g3OKO?n^J_9-JMahWPPshzdm)=yJ4cjF-O{1KodZYMRN>BT2Gb)hLaB534A6CfB z!8gRY&;1}tc5vS0L2#$6S%`I#=#j~&M3^T{RPQG^HBmWwGvYlD9r>iBIM-p3GY#$FxLrX>C~49~!~<#hZf zb^QH0{-ln7M2Al^M7}?1_%$7dVNkIAVjWg6Bt1Ip*74`*@O&L!qSJ5EFl{-ObB7M^ z)#2xL_^=Ki)!{F6_<|1c1s=)&nhx4rkB17ckx2jkU*EtNizF}CcL#~Idjj+iWZo-%R7;ZM? z+XvQ}hS5xT3qA$Mu)#3e88#Zmc?_HIj&_F4hQZHJSuJ?$9>Z3{IF69@-^vj6eMEG1P9{JIXmuft#HkY9IV{?{}dfi1&w=IXFYhwB&uuT{fcI;3sIczywi`HpLtpVT9K zn+|DH5&n!0zrqmteyHK6b@-wV4cIhHk26F*evgPDZ7GHubozD;@6%zg4##wOOovzL z@VyLC?wuOGUxz1k_=pal)ZsHae32pYS@2shjOj4J5cE{*uwI8-bUHpcF8KXAep187 zb$F8wPaw3m8pcN%Vo=}75DUq>7;eY+>=^FA*RL418^%e7I}PKT3_I{eB8Hv#QY6D& z_yQNh-G=cyhF$oc8AHg^%MAAz#;Xjw@ohhbdojrA%YhO(gxdvZ4}Y%RiZ4+B%?R(; z`se`k0O7NhURt0RxXT<@2=Hm=Qr`Jn#)S-jh)4Gt;d4~_g117>053R~iNGVkUrOOE zgCl`aVc=CU?7=ru5W3}-1K>~B$8zbt2=}SAPdI_`MYtcI<77C1PpmP-Ws>2LVH{xy zyyFakcP+z%&`%73cP~Ta6a6?0c_n;4zH`d(0`QsP2)@X~5aqnW5anSJceLeFGG|s`V-|(6GlGKpQ!&GE})*8HjE_08PLNJ^sZ)z`uX`y;TJ>liy`^N5cG?_M0@znOw#{ehJg8* zE!Ho35-``QtoLc1{u)Ej9io0gI`tzz6IaAAfc|2*QRzj}x0!gLYdb^GwM)bM86H-8 zFpN$+U&kNP@fU0O8ivSsgNEPB5d0Lq2!7tFuC97Gs zzz|bH3nc*(dNu705FjB0;_q{2 z&b?a6hBxmYzn?z#eeTShIdjgLGiS=(z1t4?2{HM*mI4$EV(zIu#@*f#( z4wZH>hBL-6P9p4p|1eHr%wsHOEF}crg^Y(2o`~^)ziHVDX}r2{Yb(GnZ4qKnM=?@d zp)`$qyuVVedu%gsX2JP|jI$Z%GcIGSXQYrseBgQ#VN!`Osl<~Q&u6@t@mj{486RYP zlJQN(PZ+;tr14JeMKh)`(zvJm*^K3k4U9)J(s(DjO^l~9UdVVgiD1Il z8TT{NxTk!2)h=NSBmIsjr3)G7Gp=A<%Shv%=!O}$F`marKkrH9H!|*Ke2no$#&;O$ z7wd?g;sIe8#t&f}V+La(;{wKIjE6CHFb*@G#CQSY4#qnf_b~o}k;XN(`vD`3XDJWH z0bx92CSwufLdNBcYZyBiY5ha>Phq6>52deRyo2#!MjEG7{u<*)jNdQ{j2kMCU`%1m zWt_uEXGuiY%-F_w4C9H6=P}aR5z*hwcpu{vjDKSMfbna_1B^bzY^qP|9>Qsi^wZvy zu3~IvY+>wU+{$e}cpT$djF&K8$GDU6Va8_|Ut|1`@oUBdj2;9$k}sYyld*_#A>(q!wTxYi zql~98UdVVg(;4S7E@fwYJeKiH#!DEl zWxRv&A;zZ}|IGM4K-MRpD~4T8YBHUBK3C-V=LnT<8h2}K4=csk=Hj5jjg&A6BGdB(po?q~d#5kK-N?cirjVVuoa z!Pv-n6ywp1n;1`H{59jXjCU|T$oLfFpBUd`{2SxH8C~H@u2{xQ#u9Csj4g~^jD3v5j9VB_WIT=W9L5V7FJ-)n z@jAwv8SiAgm+@J~4;c+CjL8l$j2Vn`8H0?+GHz#lmhlJ1=xD_!kr6-iD*0wH<}sEs zRxma&9?5t#<7UQF8Lwizh4DVdml)q>{DSc(M*5*>(l3rNgRzit0pl{p!x-Bck6}E4 z@f^m>8E;^`h4Eg-w;11N)bTM2k|T$4A!8fksf>3sKFatJqX!!osvpldpK$}@wTw40 z-odz=@j=GDj88H?$M`biUl{+!NWU9P?WQnJW1P)c!MKv~D8>zpr!!v8NCzmy&&!z3 zxR7xb<9fzE#%+w}GTzSk0OQ+?2N<&wRXb&jD;WD2?`C|I@j1r7FnX~;BsrrP6Btt& zOBok3RxmDOY+zi?xQ?-naSP+=jK5~w!T1E@vy3k>zQ*_#;|GkNGJeVU9pk?lMUv9T z$>?K@W=v#EWz1sCWh`Qx&A5QEoUw+np0Szn2*wu1F2+8_Va6?tCo-PKcn;%*jF&QA z#dsa#&5U<4-oyA1<713ZF+R`u3gcfG-(mcS@pHzn8UM-n6QiE2?CNHWV2ouxwBZbu#)*qDf-#3NpK&H*9b*&Y;fyVeeT-WePh-4@@fyb47$0DKlJOPBcNzbO z@drldWF>D5V;W-{J{CrL^e_%Ejxrw0coO3ojOQ`_n(=bRYZz}}yp{1T#y>N@!T28I zCyd`RrUsN;^B8Lx`xt-AxP$RV#@iY1W_*zG6~@0XzRUP8#siFwG}W$`F^zE^V>M$l zV=Lnz<8h3;86RZa%lIVYbBr%DzRvhIvmJBVEax#F)l7jd2F!e8x(~ zI>y5o*E4QnJf86s#DwjV-{mR<7~#oj5Umnj7KnbFdoBrJmXD_k1;;Q_&npE7$Y*3T*-`68D}%r zGOlIpWE^JP#&{m%6^u7B?q+<9@dd^=7(ZeB2csuT$&$k@ktEaO>>monbKcsJuy zj4v_1#h5ouwLgckig6X=dd5D+t&C?dUd*_I@eam^7@ubRGvoV=Uo!s4=+0Gg#4%#f%FXmoctpY-Q|cJdyDn#!DHm zW4x2`A;zZ|UtxTQ@pHz1GV0TnoPNd>#xlk_#u3Jo7=Ok1TgICh?_qqL@sEseGJeYV z4@Ny-wI9it!Z?Gmg7I+1LB`V=uVj3f@fF5T84obV7N~Y|8Os0-v&gy6fJ5if$3>0!n*7%yPl$+(a49ma1MeKS=3>5OHJhcgZ{p27HA#)lZ+Wc-oQ z4_!#UOvX~iwTxRCf5mty;{%L;W&DXTFjMg>XFQB?E91qCcQgKp@t=&IS*m_6V=d!) z#u3Jg8Si0yjq!8F1B_|26~85n?TlwK-o&_v@kPe38KX*7{aK8MGxjt7it!G{7Z|@{ zjGUwD7c;J6>|#8f@g~M+7(Zt`z(}8=p?+G(*vL4UAJir(|U-6m2*u=P*@k+)$jBhf2#pqw4>K8FKGj3tLobdt1=NaE){EjhZ zq2e=>v6-=l@p#6o7ThGbnDZ}V+`)JQ<1K`s|2^YdjPDbo z{jUh2=eLYMF^a`1-ylT&RK~fCiwIGF1tIFMWIUYlD8@EI)IW~#QpPI@QU4Y~)W3uA zKE{U__c1=r_&g!_?PvTCV^o>S&tsg)Si{)HxQX#X#w!@_V7!m|Wt`7g&$x!Mm+^GQ z^BFH=+`)JY0#$}9$F$M|4HLai1TM5Dc1jbW1|9npWn(;D1)VquEImV9}J^AS{iyvCPd?iGFE57KJkKew@r_B7&FV5wcHLl2~uWq#-qKs;&@}Bn1 zKT|F_j{8yweT|2{csG&tp@|OB#?KR)jUDofREKEq&~%4x^5#-WAZymh>X6`WHN@wYx#JQ5xur7v|cCu z?yBl1`nk~_e2ox{|J%PL5DNUK*h7CM3al%Y(I1ATq(i8Ze?Lb@!_|fV{~H~}?uqTv zJ1NXRJKy91-T1$l(|>wUeZCsYT8(JvKee|6|A`+$s{AVr;YAsy9YMGEcogzN+pT?6#bs)jSexzMi2G1I7Nc+q^2|R|o)eG}%5NR`1&~MlDBt9F74Adz z=%mI%{!BfdL>}%fJ-R_hdJr%AGxc~J_o3|`7ovxk>8M^jm=SN&59l+M2-Vh~$?tRI zgz`HV{HQ+ZflzPh;bVTL{-^$o9&;3(r3cXwKjKAyX1g;%7uxQ{A$njsvf4eJ+cot# z7yKqmPU>RH(=vhI_25VI7wHj=|7L$2$NbECw}Bto&HOXv+o9+zJ?>{ch!_2tbXQGi zcTY&WaZE@0f6ncidh7*1n(xg&li%YL`28t_AL(Q2@gDOt_4pqALjO=K|H43kdrJ?Z zBYB7y{h963+92-@Z##kr^+yW+oBV2- zA3*-K)8Z%O&(woH`yQ$X(UBg+i~h`Z2PU+8M zk^Qpp-)#4}3H*LUpsO~S0nK*lJCmV$*fH?Q|A=2U{+s;hI|61MWNQ^c^*t@Rr$4jo zjS2kbgCDIEiQiQGH~D=tf!{6Q_xD&3@Sn-=%L)9>1wUFB6Te*iH~Af4epE((SB~QQ zb6BgIf5eae({~yOO}dM3#rcs*#57bM&va(do1pv3OaQ4}`ill#sQvapzV*l_`Eaan z$(IQ_{2N4;{Cn;;O~dh@^+#>eA0bq+{#>`?7LGXsK>b4P`thII1V8J~b&sY!8#3NZ zeiSo9>5{*|+#ix*(iM~xmCg)|{T0nFDVb4NG<#-oAb=k&Dh#>KDk%vBX3i?6BK)ln zI}vXv6~g31I^;+_OyNdek#`QYmdMd&V)e0SxvOgWr(czMt6uqj_sRqR{LcZS%Jo2T zRpPt%)dZ?2t>r9x@t&GOdB3eHuuDsKe4Qf#Re^U^-W@eW<*aJhwWLawP`duxZN-kS z2gPUmZ{)h`cg?9%HBMb(yfhcIwc_DVzA6LtqgR6l)K027xJ#s&bgq}EwOV0voKyAq ze#%*l_P^bKAxr3jOw-;ypHt4Nox9GH{AwjX|E~IPx2M0i|5TR4R;A^9_mbj4e81d( zGS@VqgOW>WUjMBI9oC35_aDm?XYMMNa*r=JQ;R{}E{@qh$kc1lva*6nv0ZAjet(bE z;$qNHE49#wq-k6B#QrueP2kpE*uS20c1r7$_NGP1#%4-!H&c7lx9?xY^_*3UWlggc z$d!KK{#r|l1gZC85xu|Ks&SKS{pZ@+CN)uQ&0n@*|9p$rn!8OKI=(*6AUP>r!cxwy zDylLiRMs6!jg=@%nkAGvQ#|o;rX`z}Q}LqN6KF;DGo{T|imT@QY%6bmEJwkAdBHpM z4oNAj$b;{zS-NjyJDQSjgXCua6fARmeX(f$IN#F31q=V<<6NuupsY<}OZ6`Gr)mH6 zW$%5Q&XlHK)O?)EIcpwDvAAeCCw{x>j!B$$!rPyHDZwgrp^eW!j^#Aby6=dxN-3Rw zM}$>+$4eNYCy@bcV=D^8l#l>-Nb9J~ojY&arY}ca5w2Yqe7{{AT&iJ}VV3RO=DNow zH4W_YS3UfRYcaHbl+aJPpmgmLC+*xRk1xz>n(H32jenO=d>^KQL(vW1|f_NwwL5od1q4n8C_m)?FKR7Q(>Tw`VVU(oa`;9Z>yzey)xcI#9 zMd5kh+q9f2?Q-H|10_jB_o@!AX_T_3h1RxnZ3k)_s4cj5D2cwj)@dF*-lfMS?C0baqP{q8X!$VY*n*#evQNnQB8M zFtxRf(>8%?C8E|O)G{P@Xe})>o;I0jQ$RZzv`(hA9fCH%v}vGC2dxXztO=3Ev`45_ zGr3L{>P$f$_c)7$Qsyw_R8UR>W!N~Igi_`)<#bTygVF;z+C$_xv{eeZRuO6yqn7s< ztWv_XGeJ8Gw7y@kN-5LM0qtDShC`a;LZmUI-<%negMO6Oorn%ed2tA(ojqrKpUv0K z`+h+oJg)q_?-v&4R7H%l6!|H6Q2n<*9HZ{)9?;}S5*ZkE;?(cA7e?;<>S1$j@XbqK z?jIYoW`NjvtAE=ui|}1uO~|ETZa-GzDYOElPst>hWWZRL^Acpm+MTy!QD?k|m7+d1 zele8@V;;_SjpwnH(sL75$t>4gFS4>d$eNwdNm(|>{a8sEODStk;ue|Z%%O_(fhT=M z!nu@XcbpJF);W|_pLmVTayDh4#N`MSYFeJ%LGSZUruC&kpU}6*M9~7xcqatA^L+(LC0ML!FzGsPu1 z9&j%9Q!_d4r=fzgEPOvT(;(c3qobTlRC1+o(-(=H7YL#3kG~+ucXdDqm4I33?j-w)_eV3p~qcuR= z-Z*;h;J?uWpxI{a6xTbiMP@=5jn#orA zG7%-Sq83W4?0^Wa*}iWeLV~ym&A3WsBH8@~G;_@fr@pgk!u>qenyZpF;XaO}m?x8d zyKv_~de?lJ6fw}ui!F)Kp6rHY{jZ@f0`AoFaWCG^#BL?vivlxE&{rbeX_2SGNL~@? zLLwvaE-2&|^r3fmX5uSI#K?OKfm3q$;fO*|{D)qkS zA?#S)`6~4Rd_M*fbx!^*q{s|Qg;VNbnXY;`thfYQ(Xd>pwI+^%uwnT!VHYPyAW9B1wwa@1ICrN#hOg(LL zjiM*QPL`?XY_8Q*?-ZGO(dN2=S~yi|^e3A;2Zxbirz!W@8|QwAY=62+J{ISSh(_{U z>635TToiP|ekD`y!WQHx7sUGDn;+WTL5zg3izHY5-FVlrRPo{{J6hIs*EyvArBQP+ z9PGO56!>P?6_V7YyWSwDxJm{uFJ7|zDx#9noqPnk-JcJSt@TuWM&3(@7oHmFNSYXh zV|!|49lPvFPklV~WQ;frihJGWbjD?(3rb~_^>oYrm@lT- zQPLw5i^T_UG|$mteX%(1kwen6K`LCW8LMC_qbKkW673^glD$nw!2@J{Z*$!3;H-(a zU?cD0l9^q+4!ynW;@7|!F7X~T^Y%vgr%)J}8ingf#8f2wVg*d#-4U?>i5T$_mE0r~ z37WA0Di}uxjz&BFJc!ohP5qbEWtyi zv;sDV6b)bAg`rC2G~rz!M_jeI7v1AsB$cie@4znCZxWpeYlzi#2LrAziy%5@$ zrQEK;(~m}dQ&eiDrw%^k%T}pIkCV!BRBDyyMq)ozrJBToY@~9fV|fKlr@lOyK%hkr z`0}MrD$x20WFkSt!+m|lG239fWbrO$5#LPdrvXuoap^0Syfejb5iWf5WFkxajYMB4 z6H~;6ScLe>WFlK^5lE<6Ge;~bK|;-n)5KErzHga~9C;!g3kzST^DG2_Lh)COT;B%g z1CaMN5sUcd>ytxuw^)sGUw_mKknMi44cP3|m{zml1n#kiW@S-0#;wLX7kC#$t;zta)$P*F< zp{QN#!8nLKaWV}xm-q}JBl4t#SCH_EdUS2%$;tO2;TK`(rpQw!9Y7*Rj6m4PQRa)-@58zU+5GL^j6=KeRrRpjL=c^ytpehXt7 z8b+q>Z@QxKXLDi@YG7;yapYe<8 zi+U2FJwe<+Ec)3^XiAM5kbM%+jN1{~jqQOo5Y>MVM!hRK=}HoNE-Vn8obWXUy5?Dc zUWiVSrb-BSswg#CrbMadGfYv@YD|eanz0$<(zq$}CgMjgzAAC19svrG1%A$eTx4kC z2TYvKG#O>=GO#$)WngiMM_@T;rvDz8CLn?sdd?}*3_0Q%IGHnBCi28p@L}gvx!f;w ze={A4X)R8DyH6 zi3VcTNXC4IDzQ_f?OkFf{5UpSCcI(|dMb9RTt)b`Nu}hHOGQ#4*rl8Su_ql%9lczn zE=5iptr-2QAaioun%_{1g$2l68-I_~EW$wIaOO+0#2q1J@r!%}pSX3>cVfgfkR|TO z%rhWmf)?qDPjyqb`8I3u0ohHOZ;KY6CU5PUQ4J;I({*Ysj_4x&@zdP27VvE@(&BlO z;M;=xJXOWFxmb&zF7I8wEx1>E2d`$VhZW-s^e2fGaWLHIQNLx^aga0(CblZ)AwNl zGxP^xey9FCt}gvuT;2LNxQ6LJAvA>RO?lv>S7A^_>oJ&zV)SPbXkzudT$s9a`o_Iq zw}EG*z7O;s{WV;@`e(TM^vB@_0sU??8_=J|HBFB|kEiPem`pPCJ7J1UJs)Pt(*Fv5 zrsy9apl0jE0lLyVS|asRFf#o(>VWGdKCXXa=`?9lcr_Z;XFxGcKPHTHlHWGg3t&QB zAA$+(`cbIu(2oXhL*E1Maq7Q?$GY?jP|K~;lfE$hIK&x`z7NLr>bd9;pI!p}!u3~B z8lhKU?E3ZZkQ1pd!H9^`b8wB;cVMg>(2TnZFfI!9J>VDVO(mZE03ls251n!(9U%++{>huPBPrh>nB1)$CGQG7v#_d33Mz`lp4VZfr1dJ*pc#+D zI!P^h6WVaTgqluzElIvH8J!qc7xg-2(~*!ITQa6ZL3lfLy=KrGgW?+eKM|1)y&Fz( z#!e?OnsGMzFs?C*US{H)jEiJIp+}Z81Nur#T$6tx5tZW-zKRIsg?0)!ltF(vz33q0 zdIasb)iFIp+K-Eul%q&wryIr3`2^MJMxPiLBibe>`ff*t^4FBf;g5h?526P&eK3Ri z_Bad}o8F4v!*=UR$dZzwUj`!M+G5;K3%rVZe;F*{P1zI%vx#Ahs+7%1zkxwD(TMPs zvSm^=5_Yi>qcLS`!Uz&B&B%q=DY?n?#uR@!Ib_N9dJz3WPP5k}(QYsI>OF6=S3Q?U&RMZs{nH$#-)p{wX@kg>r$K-pc2EElribUNMDmT5pD`i9WUy0}) zBBJ3#-50`I#sVb;k)#a8yW!f-a9q6fx*Pg0$u%b}Ae?8zVrn=>Wrx%IZSKoMODR-b+yQZs5x%hn26n&I-=$|=w1^i;2JewExE+6Azsu1nJ~m@ zB<4byaEbfTZqy>*8>kW{9-+iyned8#2aqUBCOyJEkHCeZmZ-UNv#+bCU5i@k+=L>( zxE+2JRh>Xx7Na?@#3W`+%0gC+PGU>1YKAO!63Z^{WJse6R*cAW&c?+{y3o0zBB47R zf|FH)xDBV}`WOezc|6i#)uitpA)8zQr6x~~xdr*oJ8{V({>Hx$(IyA{dnxw`T*6<( zMTS((ms;7yHwvv)cGmZtD$PKd0IE$L=kN%wKzQRSyM4L;deG5(;d5olubVZK1E8(`Z zh>RSS{(@yE?l;PN8!aLuH_3ZDEg~Z~%Xh-$@N+kkM>E00pUFr|(PIge|pyTN~xP?J|`1zc;h zkiPHICVdT`v~3akpHV%IYC7pKEXqzJJv}{~4p;OMIHsoW#L7tMSHL?k3qx03zXAio zuAczy9QsM1G4#tIs#8A+qPq0oV1T>zHr$8l^maXu{xYoP)t>?fpZ*|?L;Y>gMCkdX zh~736Cesaca+JOXtF36gR;RV*GnnRLbqe%xa+MXYCxJ3SpN-g?s7FJn516< z2T#`N4WcRfImH+%dOqYy)qezsfKK0>PScm#Y4v#o6w1)w2+->D(@0u(1lRR*wD~P)^l*Ajvd+H*#|IXJDB;{Vf=Ox;`E9=j%<7yg)C9=N9UtXt7AA_i+{L z>ky7-=nuh&`21F$rp?q7z-N~J77RRF{}HuH^_yVBIr{%V!nyjge0;)8r*}xt*E=y& zF3_KVYzy_hu?bV(6`a+O`OKIXF56mQR4crEkd{X?U2M8; zffX_e^+d4dc4mhEmfG1PJ)K@Aj-!wg#NLcj{iHFf1>sK-6}_BY)9ICrLjMxnLAx3j z$|%!sM6q!?JT#*sXtN2clMD{{m8zKXoLS&Pqhkds;vPU%I~8b7x^;eJ5|dUT z#B#k8LL7x+*%~PvLMKV6i!|q4lZ4C=LZVuu16-*L*+rGA4fU~RHQK_3RFlaAV2nKn z`pPc`& zm%a~U&8d*=pR!nfgKmlxV6*=Zl7Iq7+;aUM*T+33Fz1kOuv z3EzQ>B-M;%xXsFt3nV8!N;3Y9(K#j0{|NG(zsDu~1zhZO(VX1JIHZ< zh)ejlxJUv!Ey!7m?8)Kuj6?Th-q7@Opo`EWF?enIu3Tj3MUV+cE%c(d>`a|lDDAVe z!|4f#eiL=G?!*|ygXCi5WKYxc08Et^PLD?PYto6T8evB0D=`#cqkmzrWf$s=D2|ND zp5cBKH=-4xBD+MM)!}JE#}+MnrW~6taThpb&yoqRXobzPXUl2VFQ3O`&ymk#qQqyg zWAyjqMOIdx8INxOaYoOSle>c6o7;bWVCAPhY+I1d$u~xj zuYX2`dK@e!^f%xJSmi=UyIu-qT>1)>`t@}%SU{&Q1}@gKFo|u8IUh=D{+MeB0x@?I zERK1UU|Y;CObrJP@T{7%)OeAa$%O}M5xoIiVabTCh-YM`h;B57VlCo7GRLk(6p)8& z4lUwY@PT4l#IZKIacL3jApy8R1vz8qtP7_PQ0Q4RNceS7&882?S^5g}wo8vk9P;Zs zFeU;zEwmQvcOzhLi#dc$?iv{2@_BIf7F8-GN-x(P&VQALY2;|y3bXPZt|4O;-~<@|NlQW(hC37w}- z@_z}7IKRauoF41i<%Jesnvm4J z4nJN7ZF2+qBos$_bJN{d;l?-AKB(npNN?4AJ^fm4X6$3=KfAAW5C!THAs&CAr*hR3 zLbq6k@?7OnBCW-k6>e_bQsSi$VC!^vQ8o!wFpCa)>cKHF`G^i0c(_fawAKE-;XL0eYTo zza56NPsK%Z{%97^vu#z7DGOqemNn=(w=BS!Fm59gytlfqz>U}qi+gY52kEsC!F#(D z&MunKW!^hv!X;jVq~5#a(`v6+4aK~><=K#5Y_%hCkLnA}$beUR@70%38_D@8ZV&4D zT1Pvz{K@8NJ_2=qs^1O!+QqGy?eYVDqH>An(8c*_GT{{`dyq(%hu?lNgdmcy95hCJ zgE5$&DN7PG=YHsK^kLBFXX(E~tHuY|BIKVjJqIiU^rE#={7;(>D*XC#LP3gqBhumq zC|Zyf5e^|V;VecX-7Ak6#2-<;AVVfx;u}a*kQp9@ZbdK52A6^?oft;C3X|M7;KtY1 zsud!HFF=}4G_K6GGZJy|~)RGIBiy2Msg@6Um`g%>474eU*&7{Wy>*_-H1 zNJXop1K9AXD6cL0Y5^Z*#;S z(HTYRF-D$9BnIj+MxmfzpeQ<0GAI!@K=z`e**FZ zL93z-^2v6uc(eeCUP(46ZX&h&<0x#5h=)m^fmj-Z*Ncx4=!ynoX&l`z8gVTeN~T9t zPm5-%Gb|JDioYQw7mdio_pTZeXOq;&FIurcvjJc zGIhUj6_d?=BU5{X>tiarJeE9guW)UKRg12alD#fmTQD^gT^&iQ<`0GIT$1zQc#6&m zHrHF!L64;rLx@b9tBXwXXUQ|i=F*7Et5TLc^=YA^Pi0x5O>>fmrX<6soYPU)Kxb%0 zpXs}h8+Hp!Q1t!u*~kxIX4B}SS8|x7YJn#}H!zkCrw>ipw*_!f;fBhbGz&!@=c{$l zhbRQS!rfOFL(jD|u@5Hn)ysrSoCEXt8f3yRdSP+jN|{Iy-x)|W%0xhXUxLIcnaB}# zNa|~ni9&H4tmbQuq4r9}Khc*Z>8L_R z7vhWWXvyEMIUfTHC#?aT^c>nr&(NK;a}JlE#H5ed*wqSvUfUN=AHuZDO!|V&+x27o~`qVwRuQU7Gx0u$Ub` z6|&^WcrHq1$lHzsHj(M3eBW@}kS4PHq>Lu)@Gdb$CcNS_a)E4_ND%bvZ6Ze|GKKuw z;8d9?^tJc&X=0j8%ojgl7>it)s1}!F=!oeu(IkEdMV$%<@9o$*Guq6@1RKV#*p){aH2u3q@Al}nF`wdgMq1*^;cVdc`Xq87am%f{+8 zUigyYt7xx_M(*l#D_8MdiWNb1Q>m4!Xpe^PRX5aGxsrCqIWSVvj&jTSwLj8=5OqNVk|mT))t)|}y`C@=~AVwV@m+*t%?%DEQ2a$1Bz8|Qfz z0R;(s72S!Q`K;BHOZDya`4;<*0I`jRm(*;PY+vJAi zV#?koYyShoY1t7j+J)RgxwM?pqDOqlZFz_?s6@-YC=I_GD4w&}l{|oY;x+*~^~HK| zWeGfeCVl({*}2pvZPeh_^7oRo@I{DK80s1^rMb-}8r;|EH)vCCntl^P7e>1_6P`0Z zTPwXB(};LpHbcMHC9eF-Z0xW`y0z!0(5`AZsx8I;srX4=?fIExn*k&{@IR40So=~G z(cg;Xjg&=S8F*QJ))&b=`0s#AXk=IVxHKBKjUW&4Q%gnO!y$Q)P3FDCc^g5ugzJ7Z zmKR^mbdEK+p>CvCubGUG=E6A6BPM82BUdT3@@!(IZ4<)w>CC}#5m#Gbk!X%9xmu@{ zhidrzNBk{jt$keU6s91}Ugo?@L-O9|yjv|!n&a=B_h?9-4W2*>(Wfw#LTFJR-3zu} z6p_LHW)*1;`q@k(kC-uz{5jNZB=sEmTq(mM&>ZwxJE~M+<;gZwC9>8sCRk$;XbyaF zLbl!;l1EDxV)QF3Pcr(7TGtoP&(s_zaII@C3e9l=*VaT6vO>6x>EVFpCL38BY)*c?DC@A$W+R$WGK3 zFN75vxZ%kbh307IT8pf_F$JW*3^GA5l)yGxV*1loEDM>&hjl zb1!C!$3rQgwDcJwxRwb%3?>JL_sfLAT!g;1LE|;$zSH6i_m0d!=%t(E9Y-ss7&FHxniFLk3fnkF@sZxG z*rb$v!7PXF7ddZp2;IA!cWy`?{b)AT-5!!hKcG!{yF>Em$FwQ$>9M?|WX|LM)tpCS z3QqqB)6p(Dy&`sMB(Jz~bRkyU^tpMlt9V-ghZz{82T&^KrU&KR6o)K)KT4Z74>Kf9 zGJ-CvsruuN64cMAMnO6#0{B0_8HpGwq?uK0bNsm!6g^ZGrFrx zamYr?A$?9rt2XxmHDl5mDo&M%C7RuZfMU;fkg2~@CCbz=-`U6~Q@iJlX@3#&NR4zWPpRR+N0}v) zxvIcoaxd~pt2(QK=6D2oq*a%dr?hfB$xKe1z=UQ^Qu1PzuaD4F`UNsc$(t-Ln&VsK zk&=&Fd8U%|N=S0wKbx#IM;u}=>G!EctT`qlkMyHo#U2}VMHqD`p!%_@fZTsEvPiY5 z7Om!}MjolQ#L8pU>bQRMSp9xvkyb~mEPdp4Xf=XN(&_|@f#x_4d8E~4R-UQVsVE`O z-)VB?*0v*`RNH6O&>Zw(eNyc$E02hw+D>Nj-2^7|rXkYLy}-1E=J*rxNWXL|k6V0` znaouMR{#Hqd{VMrsm&z&c zhLF4}H*@!9& zewc!JVh6UC=r{ZqSAGs+IsaTI=byvT%4+;y=tpT3{=Y}%=VNjAyGgW*8%9|l{x9m$ z#Eo$WKyW@%=iz_SWF#Kqwnj%F>@;N1E>cV1gxkxk$&h3hSCSg>BnaJT>Hiap&XAj3 zr0~HvBB41@%Jyq18@(m%a{Sj8dq6B!_ykRVWwfyqE3#;3r!9FJGTVx5G5R#xd(I+} zr`;WgbEI!j3Ob*rhtKuQ^UU$oM9W`vttd#)|C38rhl;rLIsB z!>Nqqh>#+}Wd3NOhkHDdD9uGhkZ7A3MCX+}0Aq1+hB z6LQ98Y97x*j~m4gfnr%+ae zhtHHeQ=(xFvcY7jWm*y{r-j!E&8h1zGPlv5Ven0A^)eRQ%&RL(xzN+Cip8;q9h z#85VK$TegYENGdf98zrhc`2eOx>4M}#6z{#c-DFjlfuro@|)wwau-;JKB%FE9zh&P z(M51KYg}+Ui$etr$R^4{#X&#_wL}0W*KS1wao~diJ zI9u_@V1%S2qS?Or5|?OJ97C@1Ikz2;U>oc%FD~9GVzqtRd|VoOaT&Q%;JRJxCb(bx z2vB_KYS%od;o0q!nXY7HUFH-`n$TRBc(hjy+}rT63(O#ywwc!;pZ*L=+c7Si?STx` z&&af6^?!{jgJYvC9NL6WvX8ubf>nto6NssgnkUq1uVpXu9U2GQ(ELEXZ7V z>K>0V|_z=e+f=#ORz`lFeL{>(JZZ1jif)*semR=3O9->xOw1DSM^ zif{kAB*e(;89T^1w1wK1o(A(46yRoacK)#@O zxL~-aZ?G4y-!16rZ|fax@0eJgpI^{6Fw{{1?CZf-91FS!`Z@|)dPfWJF5mvnp00xO z0n}<9?iecQ>K$lp>0LE4Fx1l30nS~m10%!vgF^$u;66Npw@nvNV*1FyKyO=jOHcoF zydQXUb3w~c-}L^0{*LJ#Ev-G4Abl-u-Sqn4|NmMX-ZK3ENoz29L04Pb1U-vp?#UcLX1P zJJ=c~;mS^!l7#S|;8%7Ah(o^}dAi~9nG_s=X>BGu3h*x=7j0T2-v@}H;%WCkF zGj519SjZ!nVlhZ?)nMM|mANnV1jHww7xkj7~b(w2FU zg98cV$Sy}}l1#}CLn_Inw&-L>Af-BBq<5G+4*MstpbiLj_Q69phjwdsg74u50YuJG<2dtX1dC3 zp`Of;_iE}uGE*hxM1f?MOq$aIGN#B3a}q#Cw#uN8k5rDL=KzlkoXtT^70!{w@gR~2 z-nh?|_hzU@29EHgNmO7)1|F{=Lxy3buvtY)se&XoU1-po@4ibAT#*7Sgkj~1d`Z{QI($S;? zFC+#Lwvo>Z;c!I9IB>4vNKA8xCu!$9!VUdV5NDt;k_zWL`~cg0qA>#b#sY_1e?SQRg%j3< zawsL*fMezuKY7TAIn>YyfQ~vZ%8H8wA)DQGV}u)S~B$0PbBq1 zTBEYqWzaQDA6zq`X!Pf+6^uHmtpK+m<{e%r*B3%VR(W#cOpIKpZt z1<*F9vy`Wv}24qDh;wInc#H}4`lNh3!BQN$K1bR-*SKf@81EbWwn6vd8Y zw%a6$3mrcFoD;z~X2EhP<sBVWL8qINFgwE$CbF9kFyX-xh|h$HZVw+(U@yBWkLkMHmj) zMmR&wr6~N_1HS^AVdN^!TEo_^4py$NtZNFcE~{;>43<}y)h(^8(7Jk4*vv|wwgmSvh+jkaO!H-e2z z5S8WfWQ5ixBidlgNH^rBwj0W7E1Q}sgG(Cg53AFp4(1Xv*xl0Kj;-6Uwy~pa1eYQD zB{{8kpuY=imJY1HsTE>U(O7m^u&Hd-@?g{22JotHtf*|%dV9LMM_3ZsC0cjOuv)ND zrK(lIRh5;?acR~sx>_=9Kdg=V-R)= zw&C<_0;5$;WsOag*#HcdH?L}{UjfFAtD45V55Cq$izIl}(7+~b6sLeg^y_a(W7*hG z4T3>M&8mjlvbDj+$~xF8xT3zIGFa7ITRYa`in7M#l@-B?N_0?7-BL}i*V(l++Vawm z7E&)_lfQwgP4KOf5+$hW-`bj`)lI>rjg^&kQdG5MVqdbftf;K2hgNWQ;#XE)T?qkK zRW`21D5$Ti2-YvB%5uj6J7Ett5^QN3>DkybvPC&VTgzZe8&c?M_8l-nPfPt8DhGdik_nxKp+7c;id#`x*$}L6q=5&;`*A!p+5zut!M3qW>u4G3-4bjW9PHhq zZEEQm366rG7sb6DEyEqkiTh~?_GmX0&5yizWxr&}e@@$pUlGrlhmCr3=c8aidhnjfdjMV`9O=D$Q#afMi#Sr78 zuVr&^xM!;zlCU{?E?8S%4kywEySEJYVCf$;2QdvZxtSX5XbaMh4JzRe<&_mRjg{q1 z8l9VyD#7;Ap_Y-JfqqgQhgj@FNGOYuo#+=eM+OFo!U`rh=|IpK835T3&cMiVak9oy zNDbE7%Cgm!+SpK}`n*Si%Rs`B4(0Kd6{PhV>M{K2cSDu(aI6`{ASM+%hamvsJG&|z zhunZ6MZbY9_i^Of*kX_rnI;a8+9>1vJWCd>7|5juf9_=Fui8~^r zlJpSHw1Ofsb)Ir5HOoQI0ivy6vMg9tTedW~s;;b|p$r;Ot_t13RW%4lOX`~t-n1Uf z0l~qJp`HP1iH_0GwAHOrjR{V?8co(WYQtOl;ajk|jIh$%$U=4A(a|jkAf$3KktIvzQtPagKo@IqlME%9tv(^>s^w4H$ulrRai&$}-u&xc+Wj zx}>zURBE2?l{L|lHPm^Gw5wW1s+E_ViO0N; z)>mw1HJ--YU9MzgEXVq;vqMH%>ANFZcLy!_=)70M^XguB3xb?E(WnDkX?^9zD)^&6 z`tZ~o@p%jUUz!vvfgo8NmC4cMu(p_Gq18pE2B`mxS}=BoST611+qt`ZY< zux)f`7~_(B31L^MJlc;3^8Fp{0XmJ+Lf8I8rw;to0$F)Ws~X|MG;587tmg&?hI`aR zNb4Y4*bEN9*d&P+Vz7cLUoJ-=b)(#7$aRa=d*er+3^?Pnr0a~&DxoIEXO)uZR$#!U zKsqI@xBIX;)uI!>lpX9UZ--qB%v z45AB50zBscb9tsJ&3&k43$6HS%4*e$lUfT7(BcQnRjP}1L_hpab+8mc-AWVkWDBw} zzo%nTUIkcsnLZ73gt%TqeNA1HGGbLdHjztf*EUpJTfP-#SkZ>quY7G;9i=Ugsj979 z19ri>N^Geb%gUE)Jy;CjN2Z6hAuNAKhc#MYZ0H|ozaoqlDK7Y6=Y* zbJAGj9H*|VsRnB<2%tK=5$o16TK^AsbZnpwz!2=g&!f{b2BJc6k(;*i=Eku_W%q#E z8R7v}aFa&C!*oDpKMrW}S)y8_ncHV{E3evva_2mz0sS;Kt!*HJ?7WTCYl_{7*0C9@ zR`L!q%b>a0l{5cXkI6Qy#i}$p_H6L^6|10KFSfJ@46rSN2{sBSA7>ca4V2Y3RF`QM zi_u{UA!>k6SnuU3wG@Y;v3xLB;>BE)yA+Q>#@>u(GynRZ~ql z(JFUS!-lq)O_Vvosx{_dF@3WNl-0bK8l(#2x@?VFP{~lp=O1)5(*apWrKr$@c1P_! zot;`AmW(nSkHDDNKOV#l4lowi+Ht}#G_VDFDg(>yB!sUiFQb*N>@0eMgo7v?Fkmuc ziY5%dCjqh69bY~%CHLKwVc9u zJ06lEywNu35SA=!ltyQ9YU*U|vK49{O!QVy$u+CoHfjhgI8uSFT6*Dh?OTH8o>v-9 zYs8*M%_QaZ&1S??Jyl*-S6*2=UNwqZYTYog-)at?^=b~D_3$0agDRF{%Zp7Vq5!rg z9q@3HlT1&m4&|BV?%<%hC545EELdXEhz7ZwX{<#FEs%TV=0y!5H3d-!QV;5RDM1mh zn`)cSn6X7udmM^Pm}QV0xBBHH1k{k>2{8`AfL>QXdv^*j=6bt5SSCB2-HIC_; zD%D}y*c5^Gz#?>=7DU+QGY_<^f{0R^w_KLc2d!jrBEYJS`3PRWjW&q1NM5D$S^6x6 zK+V`DE@@suo8*DcP8zA3&6_Q-E?JOPCKC=7)t;4o5-m_5LO55ag9yE3k8u&KmUe^K z7onq|vFd~g8^g|_fvp`lwUA5BQM#dpvpUo~h#vwX_Ht#VV}?iP-~Fnl9W@TIDdyw+H@HEDcgrI3qysA&oD`Z%TeZ~K)D3Av8bj~nl$6g! zR7l2eRJLNIy%$_rE(4_ zad3I%THGSY(A615be;o8!UN>r21c?rjlLFLZU8R_U& z_EzXLPPRZu>64R~B4%SWRpTH&xTJC^jw*?*`p^yw$9+ZT++#*;T1$sd{EPzGq3aE~ z60O53*dk|dCf;VuqM)ZjxRVc`sU-tqS65G)+6mG}USSZB zTHeBnt*BptM=H%LWLZO55I;Gt>_V?^w4RfwwOmO2HdiP8IImSF3!xq)H~o#3E1M~3 zU>`wqCNxtcN1l<(8Cz~0XjEa@*GC`Tk?R0D31-8}Q)F`ZPK>`{^V!J3%XdE6lAqz0 z%WhgvkSQrlQvkuTs7sy}jF&>4)I&Hm2;)q+xB)u7-LQVphlUhexTd|q%QX3>X8`mhcI&Qtya$gYtK&`^w8};`biC43hMH3Lmllt){G`9txSyQo)qxZaxVqFfWn8zf zZC+bUJuuc!Aty3apgxksLm6r+C%|5zzP7okroJvTI+~jBvn4vFqy?bj&6_(_KjcXm zdzD(WaHK`M<5ia0!qG7UqAcWy4Jmj#4nbf`<*yjSwE8eNAP{++!ezA>%hDIsks3O; zM|}_%l%@jI3G_T~ts1uKiw$T2e0kfZR&*g%WK=*opVx(ySbTU@Ixy7J)zgm^FvcyW z2d%YZYfs0}47oazF$r}oPo}{JFFP!_x@J`kEs;oJJm65msE7wUlUJI;H#9dkD8jK$ zr451_dms#%urUFJw#L(mT3(`MYE4;HJ_3?qix&p+d8&MTK@%`>8E0mC-a>mRFfgT1 zrvlVZ^2`N0D!Cb#l4B{O+FnwIM)43lK(Pds&Bsaf92R2<2jy60kJ9mioO0x+Mb*Q3 z*;TagQ0+;P*xBTBYJNnG=2UJ?9S)P5q=52MeC*=t;{}v0yNi!k_)tVy-3sI8GXj;Z z3?-cu8CE+y-8a|Kx^RNM7|bKRZOANV5^6) zzd%pmbGu|;oZhx|bPx1m?MxJE&NgG55*Hs=#X%v=9K>#!KW1SH4>RImO6}cI-TW9M zn+OXQ-VCcj*3*w~5b+>t9UbPU)u=~Pue5~nxN34{Sb!c+%cqEP&5jQsV24S&#bK>; zn4TzN1X~NmpgCGd4Y_Ah997tpPrl{3&;KLuO~C7_%C_OX&z!NRNt&i@(w?O0+zf5g zQlN#VZQ6#8bfSeqNZNFO4k1Yg%2Z}hK#)Nu83h4R3j%_I77+zrL{t=B2Si0d^i@#A zg1+$I_geSfXP=#be4pQYUEg>8`%2EepS7O#ta;jd?dRdsPCU=|AK!aR@1E`LU6>M0 zliILjClB1)ZfBR@tR|Z{yq#}ewP>aPB-9gN4jSOGIJS~Vir+5OY0*BrnMc2jwZ*Vb z*$1qo*{XAIn(}Z}h7xiX0`b*79504V?j*cvB{AQEQ z7X%KT&SUe0XJBSy6l{)o=cPrkb|ZY<;|aiQ$tPkqIy}V3tbsQUc$NEo!6E7+Va4}gpd&9lC+2SC9JoSo~Rd~>achp;VVAA)~<2@6>n#y~ynT;v1%jmn7 z32wd2S``(E4xQU$nJqh?YZ6CIu$<7w;FG)WDHBOtX!Co>hN{I%uU;OPTrHL+qiM(b}Tm_8mvTkZ{(mKq<3z|UT#C3 z8K_L74K1b2JMr1AD;GB}Gp)l8JA4SpuRn2$f@3xx%5dHaJma$Oa4|A?FSN{{5nSS# z*~V+pnm1J`O^v4e1kZjgSv`4@-T(O8OjaMB_%B&uwz9TnazmUxHrBh6s_Kqnu&t2Vy z=R@Z45YI5^#P{rH}fX}># z#Sm*+t$kFawXT=DLmHj7z_W0+g`T$Eo6SolY**X2Y(;fp!N_ireY?ldYM^+&!RHTp z$m6{Vf`2#z&1+He*<%5|guoF!J31l_-e+Z+&6P8MviBabBZm;fmNVV-u)zKXPkEL# z&vkaIRLJMG0dux2y8^Y}S12Yk4wKo=xL#eEx9Da)fW+mD$Xp%Ucj(63&y~qN&$4J5 zGu_U-SmaVrtyGT#>{EVwzEKNjW$RFrEzN1OSFKo!m+T0w`6IhLLgip<8hm)mhY03C zOxF(VVo$}!0}E9?-ZjGkmR}}PZov2|VnZjN6XSW`Rxsjg2_7xnVIS%ECunn#cSL!dSLmmb7v) z!D_%OS3EkL6eK2_>Njr@v#;4!n4y-LwA(oEm5r$vuVDL@pgpB*1`f0(n>0)gcx zRpwh+F8oc~?C#uzbJv_Y&4V^OgkYJAM;c}&fWZy1nq|D%zJS#F3Xj(R-9%x6B?m~fOA z&p7;yn+&gs;*^_Rt~2GB`LJZ-(H^^S)p4iL zrvuE8cV^o!2(!~|vqx@y$8727!HDhj+VvnItQ0+h_6xzLOs~ffl?`JLZy<=NV~j_3 zuI@A3;lM9W)|lG#+ps;myxra3s|j|AL8+V`e<#_t_Ru(7i5p^lj%0%-O6t_(DSuhi#LwhZWfy?PC+KN12Z;u+TFn75s-!jK<5+ zf>xYsU*feEwlwoKraC7$gAILA%eDE&2G6=uZ14+JNzZwv02cFf)E=oq zUG!-6i)|eanR5LL7SrFeO&jG9IEdMIlxsGJ2>Nk1OZ$G@(QC6GvZ#o?8PXeD)RYmi zJ@U>)upZx-^<2-%cvoo8W@%B#m;ZrtIbhBno&|wim}ciaI<&`nISZN5#o4dDV_%vdrr#i_#lUUxlby8;RY^W01kf9bOJgAu5G;Un@ zfdxM0#pn7ktM{);=&?+=j>lpQZ=`@;=IK9@e5)XMlXt7=AM!N+*9BE&XeCR zc4iltupToNS7kf`NQG9-#i?@AH4wK z`RTTQQ6W}yaoKtC^J5o8FNAM%@tWu}ZhmoDb3rpSwL0xo7Ue*5B)(TZq^{XXp#~QWBqFp)?WUNAz{ni^AMdh^0JQj zc0O=Lq2(br{yf7Eg#)^v1tM@o9crD+UQyIM)0@56in3P}dIfUj7xR02lYh302=xvG zt|(L;E^~)8p;n#KYK-?kRdldC};>=Q7B@_^@n1Hz(w1v zx$#vPetd7QE7+Que&}NeTv2Fb$dwNb4S_4_RE6YM8Gb4iw->ZA1g>a^JBpr|D?bz9 zW_ogcqd7f{{;aL+6{RkOz!jzPgTNJ~#)H5WrGA6J6{Sjpz!f!W!Ltrgs5XE)0{>#| zFYqZS3&s7hA^PMHeR_z#AVgmoqCXd+?+ek7hv*kW^lKsd?GR06*WShSmxgGXtM)GX zPYuz*A&LGgL;f2>^ywj*R$RS{;i-t)yGY*~qN#k^yXgOXh<-UlzZIer5ihi@ufZXD zT!@|(q8Eo~8c$#poFhswUY!~8zcfVO5TftT318}bM>OY_67=6+g!q3ef6gx@=zs5p z{0scPXY)5AL^p)!mJq!rM4ud@&j`_1hv?6R=to2J3nBUsAvzM6GFZPAA-W+%&kfP* zLiElM{izUrcZjB~VDDo5zYNiDhiEQ(gO3)WOv#dVDOKAGV}^RTW!~U%ZHe7g_MMvd z%*VO}K06do_EW(?AoGNnQglR9Uj9=KJTIf#sq7X$dsGgrIZv~E+G;_|2FZECO0Jx* zMvX?aEOYP`GkC*Kg7JhW_$u6Rn6L27J_2OUVGz)LpH_G-xkogzuO|>F_t+gALa&$M z()Zy;=z$P;a$^W@dOU`3A?6-2X5`-S$84>5F7~C5m-p;9PHk;wRft1od>z)dzKfsW znOB3sCKfnHi)ielGrw6`(!9>-R~lYlCi?_IJ+@5A9TV!c(gT#E%+&%S9+mS zWI6n7VSbXbX*Uhei!AHxKfcV7L03KB3Pwq1eQ=#CLEkp!$OxUD$_9{!J%rO=kp5Cn z{aF4dG6=*c(EYujhnII=ijNUYGh}lxFFbNTzJ_{vjFud!I#2B%y=t^pvQ}*wGGnqgfzNAzRjZd zioQhjwW9A4J}md|2wxEXTK<0#&FvNCmI-Neg7HokaxFo6k^D~-y;ZnNNV5>+yIgpa zkd_`OpKApA|4>Nd4W!=?a(_k(7zc?kjzA+05mo}`+Q^a6`b?aK@**~4Z%v$y^#XAY z(oaNXRS;XCQJy#t%BhL-VJnY_h3`aSD-5U+kAg0A;zHQUAue)YaU8f9Yh)nP&9w#7 zxly=F?iUEJkvrEA%A+X_U8z*x@+)h$x>MiIDd>BIMmG_os-E_dF5uUXnZeE#v5dzq*1A+|8*dpq<6wz z6>%5ROWY09JV3Umdx?8&e~cthf4Ihvwdl342)52eaEhQ2mI#qlL$kfp7-J1_3M}r( zo$ZkPQ2A$Yju1nOp;rspRmjJtLqygMvOSVMTlgvARl?hZcMHEJWIJWJp9^0XzAa?? zq(Aq<#A@Ma;UU5~!ezqag>07$w_A9g@CxBgLfS_lAKNGKY2i!4*Mw}B^ruooBIg%k zt*}wZ_DOf{QHg7X8-+bWwoCeRZ%Vvg_<7+2!pDVdpXB?ckXG+VvwafTK8fYRkwP;s zzmkHMiHw$+P&k=q~c%$%c;X}eFgwG3q zA^d~z@4{%(rY9||5{?%hBAhEcTG%E$S-4wxp709cO~Nk-9~M3-{Gsrd!aoY%6DCqN zeI>#X!imB|h4X|fg&o2!;hDlqgx3l06n;f`K=?i3Plc}u-xj)gHeJQSVZyP(slwU9 zrNVW>Ey7*GbA?w3KP$Xj_>k}k;q$^@2;UI?T^P@|=_?i12=vFayh3=J@Jqt43!f7HSomwN?ghj6FxG~wC83x$^ouM}PVXttnaG&r3;U&UP3$GR4B>bH49^roB zL&8Ue-x5A0d`|d+@TbC8gufI1QTP|(LE-ztSfwqed|_HxF02&R2*(QRg-yc4gtLV6 zgo}jBg=>T-2sa2%5_So92~QWEBfLm>neZy%^}<_(cM9(n-Y zKv<097i>>sgmuCx!b62e3R{E=g+~jI5gspGFWe&BA>1YWl<;cdjlu_oUl%?ud`kF& z@D<@7h3^Uzc;;#PyD%fH6CNgf=6qX2w2xkaq3l|8N3Xc z6mAr574`@(65b~KvhY#i)4~^pzYz|rvFWQ8juF-grw9)f9w}@QE)*UuTqA4~ZWL}4 zo+G?Sc!ltK;qAhEg%1k9A^fiJW#OyBH-v8r-x2;(7#XR05Ecsu2`hyoh2w>jgwusb z3g-zI3s(!eYr?mM?kF2?v2d7htZ=Guws5KNcwx8jEa4@>>x7>dJ}P`# z_!Hr8gl`EKjkf7oE8HmT5$+RSD!f7XnD80li^5lhZwcQQ4jg0SsS?f>E)}j5ZV~Pl zUMsv)c)##~@O#3a3SSexEp*4KyoJMrV}(x5f`yM*ToFBg7Rc#rU_!fy+I zAbeT)2jM|se4I^RiExB)qL6mTIgT$7t`=?(b_@3jFB9G z;U&Twg!c%a5I!%go@nE(6CNsT5gsi(UbscLQ+T%UQsH&NJB0TM9}_+;{IT$N!oLXL z7v|U5bd?Khg!RJ1g!6>Ug(nD467CY7E4*CzfbenQbHbkq|0ayo+jI;NRtm=prwQi^ zj~Dg`FBaY`d{Fow!e0shE-Y%W@r@K7DqJdDC+rqpD!fbh4dDyIH-vma%zl&+&JZ3W z+$KCzc(w2g!bgSQ6aJW3<~Xm4ev^p*w}tN#;UAe~u}V0Vh;+;##_|502;McqO~R9f zT}1Hj6@8}gT)AH=`U>GSM995I_zmF?g})R2Ss0yc`3DQ3jKPFIOt?h2N!TSkPk62H zUf}`Z&xC&#rl(lBwZazRTH!X~r-Zi)pA`P5@V|sbC==$hL3ot#1mT&&PYdr9epmQ= zVZl@@XM}K;@I>K0;cdbvgufNOD;zpa;V*>;g@uP% z`J;sm!a2fq!cO6-!cPlt5bhU#Tlli@9U;$vG2bJFhYObqHw*U(uNK}dd_wpW;Tyu} z3@f)>I9@nMxLSC!@GRkV!uy0z3SSn!Bg~(vbPEp`E)#ALo+h<}=JhTL0)tA!^DPZADx5Uvd8u!tDHx`g)%zbE83 z3~V=pg(HOx!Xt&p5s{Bx;pIYe9s}u3P#)&iwB%M0;hrHP9f-o@7g;fK(EUujMZzIO zq%%WAI4tK)I4o04ICTA-aPz@Ke)FCJ_vZ|>{ErY(uCEc1-qj^QM2;jl5saZGT?jWz z^jspsFB83z2k7$a&|m{Ey)5C$@jVZQ{1) zY6D00!%_BS=qINBnflEfk6(x52q)C=^b^g8^7R{&4t4*l$UL@>5nqtC-zd#N@qZPe zW%?M=Wf?bgcI>3$W~e`{xA*NG9kfkhnx%EY$#kCGS5p-i6nw+(T#&7M`=&l@JR|N2 zMh9@}@nJs|cm%_3q%AUAbF{>@1>XZe@W;N;9UTlmX3SxrCjJC2`thp9KkuU?aD5mb zw(#bh=fC1x1io;*YhsjaFYlIPRv!LmS!bu~PMnjB;4Cv}^6)=}|JnGbJb0Pw5>J3= z`tj<(KkmEEF%-rk@G-o{?%@e=3&wlm-F7@?yh-sh9LKC+KCXfQ40-+~o;?J1;LE&)a)HALL_r%Hrh(dlvV>c=sUQG~5_(q4*eX1Ox~3 zu^$44!`-{Qa(xdDL3tNJ9_Ind!_e>NW02%|;hu*)#^+sL`VO;vem;H<52lB*czJx& zz!!}7mO#9ip8R;vRlJ--dA$k&{nZEO;Gn#RAIGzQ@pWiPFA&>LCcX{%j49R;XAdmIp<>Pmf=jCHA zBoAOOCL(Zo`PgUq{CqI6%m-!h^73&y_=5RZb8ogCWW>jCcPn1pnk$7s zJF!0WE-&6YLh?349^V%*9{|5x9t_DlV*$oiFHzw0O6b7KBkP|oGLo+RdF zte+nya0coYSKO{8#^U^alM`F$)SP?p(aetyKAefneFDE-^9>h%_V3@nFS+nX2M=T- z_oe59!*Q#@o4ykK&iHqq2j@3~yy*vH^FH|d`yV*N(vQ)7|Ngu7r5Er>nHs6CHIEtALc~eE1etMDbAH| zzvjnrkGs!Z_{6~jPHr0M_U(|{W(@9e$2HBP@?wlARac|BstdCtE2XAV$qT`fiX~^E z*dm|8jxI88@GSbci5JifBKr|4GNEFHaZ1fCflnkpcmN#BP|J}+his!yBx%kfeUd^J zSL~xxEPe{+#K>BNh%6m)rEyB~#91m8@6JbhVsWavD!mmxk*m-WqGctln8@vDQqhW1 z)T2={r>+Ol@uzXd7LiKV@~|0F{;mR*SZQWn(kScJ#5V?P;O2P&0{-Hx~- zM}RB7cIXhKkDFE}auRY7KVhH|{TMP5-%!aJzo<3|&j-L0-#C0e9Y!<%&m$A@&6WIq zuHYoh?u!!h_>F@5C5TG24$3P4x)V`ciA4h{AuZY+ z4wOLhNR#PB?r#x)a&8eTZ<)IbnNBV;#L-UV08$;_TFFtpXf^yJUqao)w^x?Zp^0_* zJ`x=7s^m9)1#{3ZDpJEQ!M*zmqDze^ehq;fcOW=Z8AHU}|A5R?b?I@Clrp8Csxb*E zbg!h($fBPiNIK0^{Ha=ocW+4#rGQa}xYa3ZM}iM?$9@*^3}9phKR^*wh-afd z^D2k!M{vje4QeW{YRHd4#N2mKgn7eOmd1Qm|Af1PsRO2b05p!GubJsGxw?dQ*mE!?jhts z)OArq^fwS<8e60X^-(-7{Y56d3nGhWq+0;-qwrIBEPkSO{NWu&2K=Vn)GNsUfHvG0 zuYl`-eeCP8?;{&dtR6XYW2jdr5<44lC1T&jeKPhXWF-}Q9KU(7-{3btHXk`Hj{Oo+ zN@6w0T50TkR99K-6_o0r*!SQvAeO*=I>!1N7>l#@#P}gxVQd0^i(+Y1O(w=8+L_q% z_^pmzjt*WEn~LT-GS-23Yh#b#epHOd^GC$mQ8O3of0LyV4Ffr2SHUt`*lsGpJx4UuveqU1_0vi&}vRs%{tQFbq6rQJu+OiC_E zcY&yM-(sAXm9P_JoX8D`r(|NyDTrqPBP;kV@;I^N+9D*${VLOX-H;ni!ui=*$@LZY zn}qXhcF7IHUSz`EQ7Dj-&kjBaqR?G{NJ?%RJO)vw-NVRs^Ux_E%G}4{Uvf*uS`ZcP zb*Pq-TPx23QR!Zdc35&-v5FS(0MU&PN~#u0glb#g@d8+7HTMJ63T#7&ex zPTYKs^$8|+PWm@wdL2K7EIh-YZqS8lC}|ze(I=jVp9H@);=g4wsW4fJv!){4CzUKS z?2%o}-0Jj^3_2G-g)DI!%m}dkj9*Wb9GC7S*Gc4JRfL5{p5l;pqDg1u7S=`Q@Xs*B zjrcK1Vl@TR{ddqMCy#lQOplX^-G|i|5N$>Rn~G!E{JIDKf$VRR{R8~)->^GzPOb5+ zXqR!$d6BzNY^9ZEy_Z*5I)dYf%g>xk?IiEGZOD6Rbs0S{PJ))*q?#Ean;*$2_3 zBcnrkzZ7E2YSWu=AK!|fLVgGp<&P8R&>R_yIw%`whN;MTD2PGB(pQoBIx^o)X7i(J zK+I;uD6dJOBgSqA?Zm!@B)G9(Fzqq!yP~ma5EP4X)QiU!qWLCb8&HAC*e(Q0#V$sm zyx4Gr&5t!BR6*Rt5NvnjZvh7ngn;M1^}N za#6md^feHb?sg=vd}(PMg`IJKi_TMibn$QywJuvl`SQ|vAjZ1gsFCs&M)X9pd@EmN z7BY>tgH3^~D1V%I2XYc;7R=nkgc%Pr?MGQ^PJAYPSxro-^|iHloagbG91lA*yoR7r zdN^_3#(OCKegJ}{+qk%4&PE-l zPLnuy8Ifj$89Xh`{E z67_}{;C=z!I@Ms3n09ADWNMP}DRbAMI#ZL4Pld~`v{F+HQR!|#@uZpzk#RfF;8?^G2Jx(iB9C7jOftlDNKFYkYQVy`V=xdq|(HP^#=kCsWOD? z4nU<38D7F+F6M4V?G71XGKuxaSCQ2rnP>w9B)A#kb~5@T8wNMCPJEB&!L6nB;Fi~k zU*UOhn`u0p_&vDIt4Mxf5c21K3TaE;t8Hu#N;dgLldqV28j_Rzk|9zq4kS3q`^{dl z&|QOo$p_4$CGED-=RsS3PNV>_CLfA^gHcottvVl^`Os$W3>|JZI*$7^ie%`B^fTa# zxi7(cXeLdrl>0P^YC{yd4QMh$Ys_{c?LLP>9cr6YnOlvJLu-vsg%kfiVvjt6A{{y^ zS`7h_d`h{n?lwT?6Zp9w|J8Nig3iy1VO4(y=_WDa4XYmTpDZDF84@(CrjRpV%$Dp?b7Wg%1k}36A_-M%O^uCpQy2`Y>|S%CdowylmECJLx^a|k z)$v9^le?b82_@f0JhR+R6lB$j#%HcOg^{+Gya1nNZZ!pTq&cgubT2~fR&6lxtZ|#^ z(>a)VTj!pRtX6F_$vM%@V}3Rpwhb;9npIm2vDuxPC~Cm)v9xl5^8Q&WNwNN$!Oo8_e;uB9feqoIYN4Eo9b4k}m*$Y^05iBv(M%PfQ9X zMv`oBzc)UO5hu>}So9)f#`(-7auy5djp#VIj^tO6RR`-n3-^J)LxVdBTx`;4j5odr z#|kv#lWMvBcb7Q>sZ**m!11m)I!Bx58Q@4Eu`3M60wd!xq_=ikkK?Ww_8J_(Z-kFx z413`>y4P{nme7mO!Epr688aR~d>MHnyoYRY*8LUtkt;S2+2b5S#AW8m46pqp>eRe!_r_@mP=6B(bMz#}=`J(D$C}_y1Czw77XR*zC4T@}!p|`q>47{L9XE(P>qEvO zCt7@1!Qlmm7POX5M}I+5vJM#A;!Z0nIW`uqmGF)aa0;qpbV>|z#|&vLb#a?CLaM7I z1(lepbqWfODBxG_d8KYafr+6ykIeaCP6cBuD0QR79!rWWg%r)3qEbXVV+d9YG53h- zWI?stT53fV(|f>Zlen~>hw9?i(xL)ReFN*=BZnX()h-h?X2?LdBr&UEuaSyp)sqmq zbgBtmW-?qIKRnJNz=GeTuR4uzS#jk}EEOw^OoInG%sgr)&fIt&kqR_Au*#)+L~ALX zhAwc8zTs=?$RZBm%)Ii|p65z%|> z0@tQ?9Bc2Dx|6#edwq!@`X&Gi1b^LGH5Hpz?gb^WGdQ9|ET#3*41x>8_JtXJY?>cC?A^ zDh7^3q8QH{2}r^xnQ~Xg@baP88F6zgm7nOsnY7BAWBG*`!qBkUmm|2HOT@nsXwY_3 z-m(Ys;!weBfd!xT-06HM{=MwPIsC-%z_4txIXL1}U<80T^IK?s`J@Gc?XNQj7S2bmr@>gD-nzAcL|w0^3cn7=jdt#7p#J;qJGOV$Q87GN*Kgekk=tMz zgQt-iHt*Qh*#L`+4gb?I!Xm-{NNiiTbTn*Qzdn>tYnsr@u2b*b<&<|reSO2WEj{b| z@rDt@PI}WY!bf<2jL=>rM5?#^2&twG^i66oEgvS$bN`66GAkY%(Mt^T&|u88&=r3> zdfK=CTXH^T;E&11Bw3p}IAGVO9=*bWX-Kw&4%mEvCFze~WVS!T+muqzN7ea9rv+aAX!%oHXbW2&}TgYGT?#m7$g}V4+CuGF#{2SAl8va6TyMS2{>Rm%)d99VSUOP zFM;twxLDCUdfGVdfX0-7u+|b#Hbod=DRC)67ZaiLE79W-XCKkpA1KqWFW9kAuo_fnO0Dj3C@w`NJJdNAI(fmw&L>+<+ zFOBDw#z(*{FVPS$!gCcywR2&8)%CTM!HZuw%Z0R{blW6Qg`#N zEr?(n6B|gxLJ}dPipF@KEr+f?<=`1k_9M(%8Kdn(WBe{$cGkk6BYS{0w^TT-977aG zH@_$YX4(7(fmE{z*gWDSHjLj{>%SQFm?hsxQjS?~%kJ4oGzRGG$$XjOq-}6xjuzu( zz|JHhvXyH>kYXz_=9bX9Ho#ynO+IDI+&7x$TNw|RK(jHFl+$XPjftyVrzXl|$@Fc1 z&C|2-p?Sj!FN)h5c+IiN3jx0EPv0CmCNY{MgP%%-s^{U5Em9L2BY!WoM6Pp4B(Vt?mn;sdAG`(^u51RPw z)@!Jkjg8=Jmox^c{mHT$X61c*%fXLgRKCX8c-ErqCX|J(XibGdv%-CQdh6n5*nqcU zq0HTwYPUAc1C7NPE{CFjD>~e=Wo*@^-(;Rf^sErtrG=SVQ^Em5qFhyFO)+oT*xAn* z6g2qFkB($Y6!t`sJuBTC5q)csY|W+y&CC(ZK_@=qFlNpW*jQ*qivct8WXzieSp8nb zQta$SM|0X{W21((;Px$DU1;s7Y-|9t^|ff}oQ1Fn+SSgkLaBD8*XwNS+_nS5)ZWf+ zQ?9|3F{NHPo6#L5#gIW0uXa$ObFeYk$~CgMZ1g%Kocq@9qUPBxivlU-G}y8xU>$wV z(p5`V!jd852$+wyD@5Bb`osj|)a~8sZrwCY?hlRD4yfs1*u2W-2?xry;Aji3z9}`e zy}V`4%4V9SHoe^|MHY*(>S-D_%}AQbfM-L(r5NZ^a5 zy7oh9>>hN$hW)mUTX(eg)?pVu6M5YLhThFPw{-wv^kMT%?9+E0QrA9VTh|1bKAaE; zxG7V&6xQw0zGrUQzH{;(7`orMbGtEmA2fE)_8g?GwU0VuLWLIh0>%f?PJL6Eu+PvA zv#$6J)Tyy9jWXg8;Mr1_gbi(zS+jl(%2)?Pa$ewkpfX1BVse8`k~X{C;H1ciWp&!` zR-p!$Yn#xd%dafEdgwcgtz88phZr9WBc}Y$t?f8w1Ish89N!L$Cq13$LyRYoSQLky zSaPOrQ(AUZ$h8^E!k|U@zO4+VU2Xd^0XFQ|*@3~;6p#6k%vih+SXQY!(#monbr+tfM zHM%f7*ka5Yr8h9xEN@xX0&CxM1J9QFw~NiT!GRD)H)%c^q$veEsAJa+54Z)l5Vp31 z=4Qc=GirM6(Kz~r>W!Y*YIJiUgEUb#Z5J-EJZ*+m4z&z}vAeHP=`KuKH2Le> zqh*;{GrK#s(dHCdE|-Aji(dFK*T_FyI%y7COUrOl?TXFh&kFO6#Yn%{bq;Y0X}`rftQ7=DF6|vR~wZsoO3^ZCjYr zx6Lj!Tb+J9RxVxIwg`1#Oqu7*DXmSD8`;Xkj*|lgV2nE$;Ngevdevcc?R{Ce_sIsKKz^0{`}-qF>LxVboE_vmTEq5%V_9db-7vPNRfrZKRN zv!foCw0(2ecURKdWZ6vzG?K!ZgnkQezeIs*v;IzzO8_%m1#GRG9^yASQrIQnDw_Y)m7YaoSV7s>nKfrH5gzP@B)@Ik{Iol&^)yi8*2OGLp zGT8+;I{S8h2Mk-)=>6zSs6*eFwVMBjZzy2i8!6q^zG(~BOKbsVN-*OdLSY78kIkkL z$m!T8+ROtJW6+m%Z8tkP`<#xQJ?P8y>r+`xO-+GeIcuKYrdzu(B#UheZK%7qZO8Vu zQ=L6Qf-|32F<4AYnGAk^3vPOc|1=~VKbHWosJ(n;j`d-T>sa}0+p){^0Y59=Vsls9 zE>)C?YUg${)N=WWwN%y+a_*+b7E(W5jLps8B;#IlRkrEMhIw!M7Q4UVyuc>KMHX8# zZ%pCZo`zx84*kX;IatvuIEA53(IA}N-H3p0b`iikZJW8$F$*W#_%*$7y0EvZdOQ)> zf?c@TC9^pD4sJ_YTIRN`Zk@BTb#b2xUxdMj2Cl8iYt9MGG8$c{7mFE0nGWXBE1IAY zXFZX!wP7ARk9_?vQ^c;bF?K>MbzGZ8BUVd?U_H)L-cXL52h-SRI z2*$(vFx`9@9RDx1yUn-p*(+wg!_Srr-Z=%X{_JSuOIPIfK_-suD`+R4sMZ>iy*>+|qMPWGam?BGSa z*tzm~79e}kE_SZ`3d4`rVY=8#vsZt1v2*1Q%QEARcCmBiSB2zzU&GsA{n^FNm7fX8 z=UJ=l^?!q1Y}O!NqoQPaHY(7wIGLPk#1)+D$%6G+R~)N^6a1_WKgF zhYdOY6;4kMjq=36s})_XvAHW6gZX;;+4&xeh!3@}8hEv1W+?k?0zv)9xSq)DJ0I&M z+KgkgZ^mmpUJRS7$#F8c@!h?K0eAN5{Hcb^8SixgxU;p=ok#ETr#bd`j3?J?%HU&r z_2rtgZEy&?drif2ABU4*3|G%`wMdbqd6X|Q5r?9Pb+Xe2_eS|MspOj@WZjTnEj(V> zA?ynR%<$O!{ec{iAzZd>p$kSWoPYKI})X_lqQNl?=eoapIg~ByL zW7iGt{NjZEJmpHfRCtrn*mZ-uvFipjcHMx+t{d=W@%=&guF%+bgMU6c5akXNjuAEq zn}th+#|gIx&l27)+%J4g_>Ax+VHMAYA-;OyVZsjKZs8fibA=ZRKP9|cc!Tg(;pc^4 z6n;hci13@jCx!nZ{DJUAp*h2bbpA&4?}dLB{!RD~p^Gyo%vVxaBrFvU5sna!5>60K z7S0o%AUsQWiST;ieZrpz{~{cWWed|WTX>4_BH?AitAy7J&1WtM_eIf<2#q~Axc^YJ zvF8T*zeK+)GY!tV&56&gEekpGhCmxZqi`H>Xke^dC5@Snm6 z77g^z6J~^?g~nbQ{O5{3O31IS815M1df^V?X~K(yR|{_wep&da@M+;sgufBKDKz%e z5Fbu$n|KEck14kF@xt}OEy5kbox;=`VG7$S@(&W$2pfbmggmQHzSY9@!Y<(%!cPc4BmA83KH)cn#_kv7y(Id#!oLVV z5Eho%c!vl_3#SNY2^R~G6>bvt3eOf^CA>*^kI>iwLwX)1U4wMV{beH7+3$(wwv%6* z3?YukR|mox;zW$IqKzFe_!~Q5;BTip@FXEW;UoPiBI3QCh_-UK=m&@h|FG~exj!ZP zS)s8ThHyWV{~v{a7p4#gn@&V|n*9gjz{e0K9V3VcH;M@P6NvDiL_|1#i^Oooel6ljbG-n5 zej!Ev&k(_1#`zrl{6dfXs3s@UpmZTzt!R@jgl`gU(git-L@y&k-sz(E5h3>y(U%h; z|9?+kuD6Ti#t)s_vQJ2UwbX~ zTxkB-*4mGKfb2`bi+;SS@y~l~-OTl2d}H8?W$?e`V;>F2%W=oMuvIe`hF>nHomqy$ zoITUZpA4Ej{AYZ#@lSaX{PUvx;6*=P9r(w+uh)`%4DZF~;R$dH#=8&kV!2`T4`NvI z_9?-$d%f|z74CaG;3{P3Sym%9D?%h3gn|0eqKIa$9*s#mw1ANUOw`1gFnAM z$j9_h7B4R!2`~lY-5J`=*9-=0~X3-Iq-n8g5~q`K|bb#vUqv%9vh1Hr9eI~Rr&E!&n;zhZszqW{)6@5$=e%}_j;f{ zm>=>n9al=8myb8$7Q7f2uZJw3pAYgeJZ16n;=Ml<@0)>qa7^*yeOK{%`8Wu_{_^qT zkUTzEX1uJAs(`#dOP-ex+6)L@9$5+o-23?;ALUUNFE1Yhz!z*+Da4zGKjY1akKqon z@^ELbLde_73eyGBTvI~wDj=^B8K%4%{CnjxCnRqVK1RJCZrxoKrg>Uu=>|Z@ZExdQ{Y0GjF;_}ae8w!Zk@Mh*sp_m&&!j?F*C@w8R?_$ zP4Dvf8gO=MS|)q_OZ~M?jfYG&>?i(9{j~>{nb>^&wX2+!PS=AUjC9{x7js4z&CAR? z`{2Wkj~{&CMCz9v2b!3fH@wZ* zH1OP|IY7Zz^l6##O+2_tnKNwxW&{nr@W}elpOGfI~ zJ#g@Wv{StgdVAM3np_z7{rj?%)#E$;K?kM8GNLS&&10`mxA``4-krLyPZ;FG*Q!fh zz?VYv(&d}yCayyJjBKWp)#aP#re>h&M;4(UL=LIg$bgYJ zHM2(6K{oXIo@$(uM(@|1n2n&<_YykA;vCu|B@DQ9$j!znISaeYyj1)G#4^(A^^J^1 z@;sHkf91VZ>05FDAtGI1jAlxY<^5W8D`@uJ#``8D0GfUG@ji-lL>tSl#C>fn!o9GR z`sSr#hcb=Z5D-dzYalCqAp%ZJOycb1u7qb|a^&B_0 zD>2`a$GP#tn1ltET<1EGEyzs#xDrMj;j`O#M`j{YR5A=d={kt2O^)~l?%liLnarpp z(#TG-rtn#0B1GoT`$z4GBq3E17Icg0E?khZOxD(N?%O zQS@{}RK}@`CwXY`-9%ji1J|IPMlZP8J9YbE3jv0n@%aEJ(5DWFod?`2d zA4q&;5bmI|_dPnC&Su7%jQ0*pqr6K#fNT19h+s|X^yA@~+=b6FQfHX-I!29L>dcBm zAtvVD0q@jV!;b}#a=(Klrp~Uo5k#TO7dfeOD))g%yIk3(&K>#`h%%Q-)l%nG-UXt< zG>X*uMs%h7E&5zAxC}lSmv6dK7n5HOJ$cqwYbaX*3IM0LqNxW(Kb!6i{MXa^;`Tsb6a z(^TD>aWi=4l^CtEp-$q&7?sTy_$S7hM%@_yHRLD88zOSK8>hbN!~{!z+KpdZ0CJ)w zuX5w(Bf*I}L&mOg+-6pTPcadY))QHaXCuENn(0) z@XGNi(HN@c@vDJW$`PKguIEyCvqS%YW+qhug*~MZ$;vK@sw9@NcX#u_{~g0 zgCS#2MdI^N8hMSDd=?dU2Dsz*4j&4M={<<>(frJD%phl!{OUC8%5jfIp!}Kv>@Mq) zJn@`gTl!T5e86qNZ~mwvZipXtMpJ!gyv42DOle<(w6cPc58>XW*2{w00Y+De`xayt zjIv4KTT`cCv>{S%292d)j3EkL8rmorm(K>2c1lx)BiIO%dz`|IsdOiKs#92PZlQzh zABdo^Cd$Z4(}m+X+9sjNxp0EVi~EU|ISEb9g>~jWm4qhe!g_NLwP!p+P}mTqLg2_9 zh`nfBni)$R0cn`ymLjhu)b3kaSiI(TVA*=)w|K2hyfX~da4biyRH}^QeDQI{Bb^=w zoyK%eXNEzivAJt3`vM$_+bqYdG7c-nCt3MlOhw8b(f@hq4V@4#bB8k(i39M< zb0hU|kIX`ZskNmn|HLT#RQ(>FO}L5j$4L~RG$LO|{!{Jg7BU@$pK_);%2_T-b|>;3 zq$<^!-bjX%$#5DO%#UG6umMGQfF!j!eF?d)AQy*G!-Zu5sxfu4@r!iAIkmm?0rEY9 zACo2ytm556-ct;3X)4uA1+=X4)Xt(GFg3|jalgylM_A>l-R3^VDo^b(_X#KREJ`AE zYV-w&9ZP+nsnq2KoZiQcg^1J@8A^2$?B)p?3n{G_u!jSadjJJ8;M6p`ic@wyTn6kd zI)HokmNKdi8*rMXZgnCDAbP+V(V5^$L~)u{e{G!hMKU*QUHI&NVDyq!oPUihI<3ctgy8Y|@cQYTfo z338ou;ct*XCsWA76V9x{#rSphrGCNSj_ah}CKG1a)Jo>Vi8-lXnwu0R4LYFXrTB~p zBAnEBkPL)&Qa>{{j+=S_$;K5)QPCl;Sc)$VaHUeOBd561sW$79Np;(sSx$s%&C~m$ z=d(mu)(Q5z1QoC*I0+BG4XGM9ijKoaAW%t-@#pAT&hfBvpT{FJxh|`huLGCmPGtfT z=D0<4S>*E;Q_p_sVaL4~=+*yOq$!DZjEoG#WK#s$I0b{(5@wMUR82k^!BM^sq`78co(4yB1w;FnY zE`ng|7ITlLe!YR?;lolI9rSURKs6vdSh9119?Hu=Z0j9XMn}*yvJ0}8yOW#&N5Pvl zil_>p`pY$X`$n!~oOvIhalMJkx!5!%FrwEn&yPct$>7BknZb+Ucs~A31}|X-Zvk~9 z{+&S&AjCPQEt6!2b#EMkN46&TIg=Rt5jcJY|0ekP4E_qJpW=T2`PuK4IIC1}VAc^J88Qf@scE_#hz_N~5hyTR6*cL4G7vgzIL$?Y|AIiM}| z5tP}>G@xxvc@|Fai-n+bj?7%%pMcQH7ZsXSrmRB#gQ$cF5|XlV+n z!-RYqJWt>s4*mj%7$=VfFYQ%mw|ihcL=hKysyNqCB2a-UR9@{0~G%O#|hzkDR7EfDN6) zR;a+kiTOJ6zZ9%0x!LGVCNWEEn3x|U4xVT=PiOe*3IyS-f#}`I zNSc?%<&o6AF?WT?$Qc-E>nPqCfTyBn_CbiC-cT$toUC5N=@5zc^H~QB^ir+q>4b#t zrK~r!SYq}__}Vt9Vlzi;X3A*fMAOL2s@jC{E>HC&R9Q;xVu4Y`Xf#w-m-()RCOD!f z@-%xE2h=lGC&oaHB(*aRkPb*{uT1w*)H%?qiX>x+)x}vF()L*v$`p!WP)Idrt~SYX zPxt3wqZiWGtZ8*vRs_Q`l|e<6L*mfusay~BG=~l|1y^01qt3I^6O*FWPb##uxvk3T zG#&11u&kceT57dwjtB-xH*;LDWZ47UBMJ&o?ODB`6Pld)BB_ORqEhcG@w9oaV~ek^hjbfq%#e(c z-{2R3QH$D0vbD5n2t`ful#)*Nl#)&f3J6w86TerdvxgK$wgm@yDV21t}Y=$c* z_J3EJa)RM27VDFu5A_Tr_J1Sf$IPf=kE8NzVR`lSzf@R(q~;@&`9-$)i^^lYYzgH< zEInjsusUox`{^t~5{k;vexOknEy=LvCg$IWCD@k!-P-h141Kk+!T~mG1JWOnwFEMh zD2#SJ;DSHe^^y~_>|XW)85`g(m#1A4+-%zX$Bt6@Odw^6Jj9w;(KlJ#`Jul?!4ox_ zc&*-DTOAURhG%+sAZ%>-A#gfmZotU~z^}p-Bfer2M)`^j9}lPTheW&2x*41D|Mdv4 zta1}vVqhbW*i$)W9Pl*dYdpOY<+8@ch|x^fGT~eyM`d1Iy6`gD0CFA5%cK7lW@B)i zqY=&XfFCqg477488xIta{;z z)XzhtY5~vv-$|lTnH-Xf&3W!ydkioCp7vkt&H_4T(S;EK-K=hytdd#`0gAeQGY5MR zRu4m#1w&vkbpf&1p3;Xp2oM^ZKSLRnzt{(WfKm#0*n2A$yI8nj4uG%GFyRM8>TqvU zYIs3~qK1o&($9$v5m2Ce6|}_0OI^1NT6Cd^cCQ<+7!!|=jF*gu&e^@0c${i-E2`op z)RfyWsA1v4g=@h$Gaj$259yKpyb)Dq)YiHa;>nRvSX&v-8=RPtNi3vt*$Rj_lp1cS z`F5m31-qH}7=uVe;t0rXh{q4F59zKw!lsaVcGL0l#!NkUs~bR-)<^J)HlXSEJ9uHs z%#@bKp}L<5PL#$gMwpvSeGcpQebz+C=cm38q8PxkKxX12Gf10BUtO-CU;FG~LI36Z z*tF)V1AhA>egBd5Eljwf6rQ6xLpJ+*UYzyxl@MF48SC4-+ShOCHR>;x&OWMb-lFFD zZ7b$1U%F^f+nfc>txKGa&b?bYyQerk>$`X0_zQK|P@M?XrC2>0Q~?CV6@KXXEh|>8 zTHew&d)4gOi=gzc%~MO~t9LX_+?=(65=oGiSvH=>dpj*l4CiPFCP?v~Nrv|kmIDK!_ht`xm$PqC&>+=@1tZ8dq z(zc}Kn6{P6o98T)au=v+>2NwXY%%KTy!1nL%eF3PlcXwDs^<)rLa+?m7C?C#A~(vj zycAIz3{}r;-;^;wRFD$X#{#vJzJ5F^>p=`i?^dXRG7>mmAiP!NgR~)^?9dyxwo_~{ zCCzhJw=HO0xf0bPg)vmJ66Bb(sCCZ5W|p)!pg@EaU$OkG1{tf^#80bNuw7L0XR@Dj z1gNL0bA4NTZ*Mnc+F{Emp|Q78gM(P0%cKK}H|@vxxk{4%A64|o=5E!bS%t??A?4MM zDFM?Q`B_8f9uyI(E?5<6HZ6;qSFCKE!*E795n48NA8y&c9gV`Mv~hf`HGao~@`%9!5AKK7aZPzk+ z-mtT~y?4uw?Vh^J4bJ9vsIhDBKAB3LI?-9SY~N&BuV&6y!^p*2ZoHD>tU+HL=|X$9t(r}X=R6E=kePtirROxDweXXm^H`K6{aKP z3`Aai?xunsXbNH&Pa7;oPq|_g+NEwwg?vVlmtR{gt6P?=^hQpjfDFq(^e<>UqBOth z_(|`l?JQl=HgD;iRVy@NceHmKHG)>_Vn14$0)^`3&DIT?W^jND^i{8tgGu5!rC@3> zf;X>hT{0hvWw&g#x~4m!3AAsXp@mYT4~o^;UogrGtq#zvs&mBUuUJrq&?E)YFO=Md z5*h(lKs9MVv63m|6%1-BT@@T?H0+dtQZdWDoV=}q&P?>P01rzpr#S|T!mv;2E1^kM z1SO4TnDnbRN0QZfwPpKeDCo+We%KAn`0pj8O>=b{#%}8T3Z`Kh6n(B}qf%p^n`t)H z(L<+j2S8ul#_7}!4Px-LB4S3^a1#0^lyY-b(AK_@s>{{vrHe{>YE7ot-Aq(=rcl8d z&G4Zaz^F8%w%jgg-ZJXIHhXfRF&CP^C5TDR&iBY{&&gZ5tSU4=gKQ-^gEuMWw#4DOSO=s z`e<#8wB|DtLa+_4Skk;~nYYgHMq*Fxcb8vnSQTv9wIi@vupO`+s*Eu!w42syT9p}a z_n5VZpGI^Ev^9Tx+&~rKW+n*Fw5{`(EX69-PMTI-YWEK4_2cBl{<971x^Ax8s6sMp zrRhU;+uF`+^eUPZt>3YudqXy@>;Xm_n^I~gLvQ71G`iWbPd%z-s+KXRQ%$W|avKGRUPq_!?2zrp<;~t4?S0jKUTa`6vA=EZ+_Gsi>Jjr^M|%&n zEMmja;|-UlZ1$j*%*xZx1H*dbhNn}}FAJsrnAVjG+M1!}_!vadz5z9ylSt|NpP&pr9=Cn!4{=KmzkN3Z`k>+fTk z;X#r)1{A?l>@m2{UNL7ph(*3b3@4*3KkF&N$2ozkKmC3TpS{e(WS^vdzu*;xyxjQn zP5je+rhMlx-Q(;I(#=!U*(;h;lYAmwWWr}T7%F>3Vd5z_z5#|m+tzRbBydsxU+{`T z6IpKlN`l^qzbqs_E18Vc_ZPgPI1`gA&zzC*S)$N9kegn-I1OA;^L2C9A?j3y$ThzP04!VF6vAT$(tJT=T|h@ zD~c}^bLC}w3b~@_ExGCQdXJS6&H3_<{4+xGW@IBX^1}V?$dLc6Q21FP|Jfm$qe%9O zIxSfOcTs14h;9wh3q$nc5N%Fj`EF5XiGR}4}KxdY7IA}W2uLR@I649IsOE7-4 zi65ll*(QI^jU^Zl&JX$Dk`sQU^Joq|*5S!w2C?!dIMrYz1h?Nb9Tx&k{~$Li9|d1B}7KkAKz3bW`m8z_H?h~*VG z`9a!WX9pd<=O971>^{@3lfz5357*zx=U;pd1!;Dd^O)zlhHNL?j>H+)V6LpzGhiTr=;y$5)eRklC; zzWXibq@A4fLK032ArR6aV1NK2#6y*?A|i$+EkdM;*kT(QI~HsxD2j-PsNmpOz`5!$ zV;L+n!$p~KYzT}R3(8gR_5b_rz2B3Q2;$u5f4}=Z&-a}tZ`NLGuf6tKYp-42{Wc8H zTxAhbe?pF3Vyu4uEADUTrs)`cWIkt6^06vHxLiUst%Nj{^tl>RRpJ+Ec$tPbYIv)L z_iOmDhTAoKLBlsS{F{ax+bQ=O4f&1+;>j9jXjrIWg@*F|uizW5@zXS%p&@VFrksm4 zyhg*@HRN5{%-^oziyFSA;rkkXp&tlvrvR1N2AxLm`lG`v~E zwHj{L@M#VC7!KvVrQv%TeyZVj8u}2pk7W98lR`(LJcp}@M;Zj z)$l$Iw`ll`hPyTVvxe_$_=SeNW>38mHO$knTtoRjSmZZq{9Fxh((oP)H);4A4PVso z9~!o5_@jorpPlt~(y&^?(Hc(CkdKm*Z>fftYskBbNav$>gb!;d-@i(^K1J`UVLuH= zX*f&6t2Mk$!v{3np`m==D&)PXarwSg;72tc!~n$l(=_a-;h7pG~^?Vq)*lG0u67}aJz=DX!x;)^1ZAmmy8LO z17kv~S`6EvJe2>wMn{~|)HCvMaE@;$Jl z@nnw9e@N3G(eQCie})k2lD9Q|uZH_|{>K_Wq+zS3A0h0H2k#OAM;k`6h8cv=H(%pj zH0-YFy)=H3hP8x{GehUkA?#upm+AbgG`vRV%lFNqzB@Gi9!=k%@l6^&MhH27(6E&d zdL1DQL2sNeNxe19AVhvhAp9g1<8%`gc!_433H5cc=tdI7Le!<#gGR6|U^h8U&J z<2fF2kAnQDTFNUSL_L*+Al48<&pJZr50^?i#}dMRoPtQdG!nvJa|nm%bw1?dkq;?9 zi;(d_2>B2x<(CoysUn1Y?vBxqd>^+hg#1+2GeP?YWu+g0*OCr@@zjU;jfALo ziN==`qW&v2zLGGc-jPWDJBUM{9XkJ6Lg=+yqVazcLf@kr|A7#C z%lL$RzT=Jh|F_={>s{rF-ibNJ+eeSdcI=ms9-DO`Kc7|}y}MJ6%b-=|Rq9o-@-3** zxj%VdZTrk)RQ*#1@71aijntmZ&zYw=jv+p3+e6zZ@$M%zI zcvbf&K8n&&?FLB|fBG6;&mmDvKdAuQVUZo26ByIRcVdg$^B$|#cKc5!sJT7wiED4q zuN;FLSboxq-d@)U{1;(6p(MRU_RHi&Gk5e5t8DY(&)3_=_w$}+S}U<$Y$Zs3mRpO1vbm1r?>ZcqmLosr z@!p`MNY;ETcej!kv7;I|PH7@PPoE_n@58a{oB6g6E@+gZx&yH=NN88a7Wk-hQV>t!@Wqa*03W%51*#yQr z9pv2y@w;M_ z?dgtpD@GoT1UaHlZ3lT9qvYj*&$DBymIokz%P2hR=b_gqzK9)si5vByEdD$@_>#bA zJ9b3Xo3Hs;?tNXaXGaU}JeFr%72@#h*sJAv<@j39=%0u3dud2V z>{tne@+gZx&kh@W(e>_$vZGk@vD`o!w=2`|et4tVbE#R1=rLV2E_pCS_V^UwlSZ^X|WZzzwl z`19<@Ln1m3{HT}XAM5R<`B;u`o}_Hgj$J^!G{_NsMs$#u8D&Rr@UdRXYu55SJ6`q_ zM;?D3x=!&$?AVPAmZvQKD38B2NJQHain5~y`Q&4{zbJVT-Sd0$9nont~S}N;EUF;GD<&$PDH;<>@85XSMR$(IPZEt=J8jm`FbkU zIH>E@sFXq8fgR+14PueU1PHa{kJpQ$^{az^-aK6g4)W2iGqpS<+LO1ggS-bJ?^I71peJul2YJJWt34yi zLoy<7TL*dHK_1^%>is-M4bMuW8=ypr3z)VeCRa?H!}}7*`*G56#|;r2J*}{Dtq32Or;UfUPcr z*Zx^A$1k>7R2UgEu^8vO!MvZRDnmD#Z#VSgHz~cJ$Hz0jMKj80lrO9Z@fUfAd@rOc zD=VY^_o=Q9h5GjFSq&n7Cw_-~U0Bu3X}Fn-+q^}Bc4N471wzFr)*t=&7#Bioi)hu>PfcV{5H z{qT&$F^6Udb6-ir-w&*=e|2YFW=rP21IoIsTQ{`?x9>R^7}BYeQJVhFlSj5)n!fMa z`iyrTN4ae~%|fHlEO^Hla!91y1YHVRGeydfmZPI8%~0?;>&Ujn9~@YZ|L-68H`IS? zz3*MK@Z$q0Rq){fqcA)Cj{`4A`jP!94cFEm*=K}4kTvri@xJY2<@@f{`{%W{@ostF z_T=NxQ;tIq9*3TEOnTYDqhsuFV%W&PNxpU7$anSo=Z*Z!BPmCxF4J(`VK+{_rM|Ay zBZp(-*5U2WSDYLQr|jdK>#yjv{&1{CpHH8AW-z;aP=rKj^u-lW5p*IMy8xstr5hL)O;kK54yC$IfG- zrDpq>udiNYbh)}PKK#PLxCt*DOeicXNE>;|%oh$O7S1fZcIGO?N?~iFHKf&VU550S zud5fw&7uu6=8OEsS)uUyS+{~d>nl6uN;E{&&R4O4q@%wGO^+ zt1lb~r+Hp0sok@szTci7<~@ZN-o0}J`oMOXdhp1$rOu|}h8_*faUWKBHQ{YC_W{Hw zYZ@G`k-i>`b{JQn(*B!_n#`SMDB+8c|Fwg{-z&WTpld#NG&S_vLF44;Qt|Z5W!f*B z<60JPuPtz3MO_uS>I-a{_FAg0K((9Qpjr#>eY|N*Yn>pqBwV_mWvsAy(_qP063%HL zMR5(*T)7dhns!|M3tW^`l31#;VO{->ouRPU+WZ{xA@$}>ZyxYc?|I|ECKKbp%B^m2`9_1%Z98+|AICdA|Lcg^;M@a~=Wp+)TQ zo`dlzlRKT6J!~h(5u^K#o#M#0MSHT1k{vti>bI4|?T@ZK6z(#^i-cS1-Tmk@y}IkZ z`RRdw?u%tF>eVfLL|VicIYxa|hq7P!#r4gKs?WFIldp98=Yhlflm_2K>Z{pqhZDj{ zGKxBW$%6VE^Kmsk!lvgHWB3BxZ#s8oh|eYU3w4=^aQYT9ji%rcV@&p*w+{w-qo;%( zssG(qgT?Nh4!me~5AG4&YxWr3hwQNmi-()H)O~qd&n_bczV1<^zwXic+}j6}em6DC zJ^Ytt@rQ+PSv_GgeQNTAPS{Wgovr!ghXe*53~F3LCdET@}gg z7XJKzaZ70!a+8_!{(L8F>JlFvFmChc_kk|LUmj53Fv(ZlL;m0Th&V?31b#Li{E>Kg zFsfyo{YIe|2VWd$r8R}!!m3r&Sn<<12>fguwAJ%bR6Q;tfRdG8S`U1_kM(}5`w!dq zMD1^MbKapY&b}9>!)u(S&-?lS`oei%Nh$muiD(LLyQV&{=gOx0>NoDp4>thr0KBH& z-h;2Sj5KGmBvZ{p>By~H*I^E69s1PP=Z6JU8BBMW>ZAejW&g3)TtDGxmsVqE0v19;ad6+#J0^6%NiW4Bi*P3(Bftq8 zC4bq&lv(oT8?g_oan0S7t;dPjyR+}QJG;|evA4wCeRp=;EgbRp`Rcy7t7ZSe*xi9cb|JS1k(z+q`RBIU}EBCCM|IoRtwJLj1_MuK3ZN}F>apby7 z>%O|VC8gD$7{4;je zrsd7DjdI?7$9L(G@3!l?N6s!j>vxd;5EmwvtcvEO0Lrk`HeN%;xkLc|zrm?!6$Zeh;w)cdjeHG7PL z!hD69C6|7^bIUCU*2At#zy9r(RR^%T#5%#WxV9v}`mT^8%Ss$2Hf%A<27SGLivcMz zdWRxsC&JL^eAVG`Z=Etds3Jb8rc0Am;@kW8PmETPERyHus9FnA+n}$n*rN1klQ1{$ zvjeJRm!`p4pXju^sU;k%HslwljC^mDH}ZX656N%QsmJQMcG$7AB0Tiu9Xp4HuSP_BT+H#xGVQI6 znfA(`f>Ni1Psaa~!&jj!`9*KlXPgG*WoynOh%u|tX?*r0MZtPDY;U3M)+S%rn|<~l zjc;LZ%-SC-y%@X6Yk}3DSVr0-@6WpeF!tf~^J~H>4Jo&LF#pk`Q(96QQg2aS^m+;V zOPk(CmAA?#-Lv6TXnbl|X@3>8+j!WC*?8E9c^dU+N9u3uc}fFS|Jw)S3Y7*ksKHI1 z2JR#E5nEIoWN+fyR;>y-I;wSM-;Wr-jN`3adgFUmIJ;`KL^I}ow`uxU^|DXkn_#`H znK)Ccx)$efm^+&NVY9o7**{@VmTtSa_pF9cm}enp1-r>e_2w&jH1b6;)`RoDAx+oT zi#M)lx}`pDkJYpbbNRJsFLR~^%I=*)&NOP4QQzt^XL)nZ)|Pcgrv#((jQMSOby4Y- zsPwL=w9ypBAC+#2O2ZGvuCE5S`?lAvd2Qvk{>PMdd81DqH7X>Z5XbY;e4=K_LcDZl z?(7Aj`~e|m8iN<(?L>I*QE1wd(5&Unc;mxjJU5S}*5Xh}m&M)S7tE!Do$$)7={P@} z`*iNex-aJ^=M1+(;+C9|CJqA!W9z@<=;my4^-RaOP;;KM#=!a81BV-Jg|~z!R~k=L z%MsoUCw{lGmF3;xA7qL*Wf`jRN1=KV&oi=}w`rAN47cauXD-34I$Dr6~3uZUXk`HX*S$o-n?Q_(V`b(Q}yAYn=$7A;={_*QL*JH)x zeXnigNmz~Mj!eOq9=qb5<52>#Y~KxKxOnCFZ9q94|V#Qwe5{I|MgKmtf^APXcu z=3$j)R)gf{t=5+MUR#!MCS&*C{{>0vdu>_5_dPaJ{Tam|sqeLA+0GVh=lSzVQr~Ms z#lg<3*jb3H8>7_s+Wf!4Ca0a6j7#14$Ox`*+LB{J+J< zm90M2=AVZvSGM|8TUsj$onrgnfe7a>R0I{->%fp<(gL?npc3|oUKK#ZChXGUqb7d^ z#qDRM1Nct|t2-{~Lu9A%!4?03A`s5V<_BZbPQkyfd1%`nzN(Q>#@UyPOXEFr-r}W9 z=Q;S%*DLrs9AZ27Vz&+>}{dB&8iIaWUQglW` zDc_)!-+-;ismGmkzPcc*DM{q5k-ou!y{HE7bWgP5IA6U&$C-(nDP)L3$D4^`&@8?N zg-$RN{|nC-`A(K7zV((k5HhfzAVp0!6JPHFbf`klG!wVMW4>Vu#q~)4VHoJ1nM`hf zKB{r2B-6wGzI4;nq+LwEj0ScaRr+f3Ob_vMpJ^B3U)RBKago3C0IaQ@188G^NPFuy z42y#Ja@;^@JKrPh{Dl(nJF6kXUmQOKIm%mp{XID6*A&nvnGZ6gIxj&r|49jKsZ6H_ zs`1xIBq#CLaGk$zfQsT}gNf&|R6m6ZGx1BJ{UwU;!6kNuCH`88@_TT8J~iRa%oz=Z z)2MY>fKiYSkGpen&IX}t5H1@P6aI`Q)q@^0JWYPi#`!zyjTt2y({?^Uv6wL#-4P9` z&IH&JbB4^xbhe>=Vx~%@#0ho-a!z_`5chb<2#T4LoCT!T;p0Ftb0t#eWK-I_*ykXv zK}Jx_eEDIxVTS((^aOWah)?m9J3} zh_<-ST9r4UWLzkdBSWQQ!mn}p5~+4Rj0aL6ks9Y)6pSmBNUd`x438_40_vO=m>kzd zA`Q+sM0%Vud065wB3)G=Hj2cj(A04yDr%>R#Fk{B-Bj)jk+=qZE3UgjXA0+iG66k}j-6zXS|)WG62nq9_+u?O-?!uTND za1go*_#`#H@OGq~zQyQ{MTt*BEyG!WCXMeRtFRq>#m|T@mWbck2cN_%E8?A9EYnQ} zOVAj2FT{*AJFf@mx)Q^BPQs)wkaqqPahGsL#u_P^7kLsUOJVV{&V(~%ok8bS#9G1> z8TF~oX4IK*RuLZ=$~5x*fzFJf%;iQPBwcG{USI_BWfD>PBZ4_lV6n0^^5q8u-8tfB z;^SX|Qm+8gJyeNIeEcg=Ce!{*eEcg=F4OUbe;~%vK!uf$!fBMCCY3<1z<&Y}E|fBa zyuCu4-xW#mUkD0IJb`Xtiw`i{I-&__S9FF(KCvB!`^8L-8lndVl2~yo<3^l~h>I5i zI6pytd@>;T<&i{j0A+*XCQP15qBj~jSsZ}3Qp9?+MyiM}f>MT`Uoi@dwB|!0|1R`~ zMDobkuEQ#QYUquL> z;5k+?$|$pgEdh>hB7*~ixDiU2;(0I$v6f?vNaPeK3h>`AM&o~sn1=tcVsjic6pe6D zvbY-3QpA4nr-~(TM4H$J#S=v_;v*L;NmS5#I{|nq`W5bi*``^zrO? z@f?Me!;@zO;$q?7r@?H9mB=*3vuHgbCLp$KF^J1G(I4g~idQi5!N5WASMq%8ElATc znghcrqZ9ra;&T{oib9wr#2*kpmPmw?Z1FrA#4-F$D3*M_l>uH|`l7&6mM%dZhB%`; zOK-JmYVTM7qd76=Yb#MkciRH}0WRbiwxC


Btv21+ubw9A|CupJM>$90QoOclU$v0$^J+?Pr$CrF#HqEdmbx82GFyEgqk^qAEnwx56+X_>DeG#G)B(@e%BD#9L@&S1iW(>J#sS z?iZipKjI%z8Y`;0Kt-_(E)0t2pnZ}!8Lm$jHz4p*L=KuVRV;&-(!@|yl`cL5XQtSQ zAs|Z>p!;TvR)j<+vA!F|P_Yg&bH$I)Atbt^RKEBe@mC;HKq(Z1QCE@R6H{G83A|h^ z&POd>#oeg4M7)N&x`}h(s_vo=7L|%W!CgJXHK3G<55Zq4=AxD=aW2w5MS3Epc<~ji z>n$qK>ubbcA-}H(fznUpbj5XS;YTplik@)Q0Pzq!Fi_kD{p-Y&_&->jhg#}I68d0+ zcnu@f$zn6YI4s_P--d|<=s8@>fj35oc=Yj+;v@v(C~*m_K1F;BZO4j}kRB%zp%{t(&7u!VohQcP{~|E~;k#IjguP3|Z2Z4i3`aM+M8qO}spt*wwTQRi zvCG7h@apCAo77i`ooMkZMSq0mRU#hU`B!2wEV^2p4SQFL>!Ihb#W2`=jaZIWxK{A_ zvFk(ua<3PI(fU7%foR7cjrcSukzpfkq!a{Rf~MkkP}&eXAi@+2AXLj+nq#W@r zLL^t*fu_n67k9@dsNf^rAyEtdd~qY(R3M-T!uKBNdWQxga= zSWI)`>1ZE2bMDM4Bj!9gW%+^hG-4J>B;I)p1!ES=bCRHQ4O|$rB;G<*sp_0$sa&09 z8vZ)ONX#-T5A6OG&@;7Ao;Kz;r-l9lP3rs;!I+kxNj(gwu>we;9FB7w=wYN42RKWF zoRgW;RgTE{&OBJ1R+7TOy~sHWCDTgfxLxVI#xgx5Qtj~W$Fwq8rp8%-7ECLb()v56 zpdr&LBvR{)L!72nChS7d0nQmzro0|jb(+z_X|)oW=!`-~OB*01PI7usM4c>i zhO>bc50-3GoSV^`(&{DB=-f|ah(u;OL(!&b4HB8-bf--xOKD9wVWYWW>n=Kne$KB; z&%GV3B>kP9r~SPpgpL=ImF74fLxXg+QVuy25RmEW9Hz)gMwF+kbC?q6eFSy7I#cT* z8!WwxJdLV$dLt&&i>32x}P@vQo3R3OBE!Yh{e z4#9}k$zRZXSw&VMSmSv$x9a1DZ-{Wkbpv<|37@G`U}>kIxMDY#T| z54$*)Rlz@?nJ~5*!G~pU_Zz_ha3aRdi0ml=ZUTuIgp?_+mfC-o&!L%L9`uXuXs4jy zbKxN|4nt3!_)RHBkAhp^3&SiZpfaLhBKwk6upjMc*aa&I`~{2PC?i<#Dtlh2;9L|l z>I!mT2nL_?;XY}^JMfw`;yH?d4}znl%Fy%^3`-DT1S`X0zJm%Wc~UWw;^TD(ln z14BFqan*dCaszz)RFuI>hTvBtP4O0b7Z#&@MMtN6>wP$JNFl81R44`HK*I*^I9c4W zvnbh!&ja4T%_c?UA`eS(;Nt@LXZF=!1TJlX%dps6L{65pJ_Mt6107lV*AVh->xN_H zZDXEgZ8}C?`sGj~=XrNeBu}PzGO47q3M2jugh_fm+9YS4dw{IuGScG_q={#`0dxZ^ z1`%O#U(9+GSt>)dd7eO{bTZJKOU)}Hl=OLUOGZEUHd3UUQ|OzF8rhm#No{L^Qoa}_ z=Qi{A9<$WPNPiR!m;J5#w+NYi!bpD({WQDPW$#z*Ajv6f(QdhYx=`adbP4NKB#iV% zL`B*IZdX#ct!BxT^gz6W-je>GkeS!Z9YzM(s+*Jz1%HikmQtS5VD;Y2dLePq{;wH z*$U>=%aeJ!@*%0R<)m&4p`cOT1;b8Gt{FpnzxNo7@(+-ild8zc&{Ky>6?$!8wOdXK zTe7Xijg+Hsb7+`s($UPPb1ZK5>1LP?M+auQOMY55S_;4QobtHeMCe>YPGv<6H0!)l zD#`N{P37IzoiB@Rh3Zd5sOj+-<}x?9uaUwL-(rv%DQgksnSYS#eZVaKGvbHC{PNz= zEPI$K=Z7DeC;LUpm;#6|PvAa(XN+H}9k}e3U!FHoR$(m5y-q4MocS`ykMU1Fz;EQA zBo#fIoYdGTpBgfZf|)`JSmp^ZQWi4+&xqX%mQ|$6j>vz;$(O;L{7NaOd}9%m?ykDf z)8vyaD`U9yR^VAdbB`qR-=Fahr?WQxapNkb4qndMlEhi7)nmdr6k0HAVc<+qQ+i_L zOIa`5AsHQCdwedMGi6f}olw$7<+g3-KGIP`NR?euHeAh(5Q$ILC&)H{4$U~sH9NtT z#LZD;^*CtnBtG7fAQV*ak#4uR&~R*>z&-zFU9nrko!Dh2MgDyYCwkUzl@`@3?(xW|&K zqTZ;L@2ZG>ALg!Cw9|m|IkCKRYdG`rhk!BewX&9@Ys6dwDqlZ#A&!`ffn1NouW@9P zD{wm~VpS9OQe_`C@m=4ghG~woh7Bk(O?+3k7CCvZoTQ{$2IsW3R@U2;{RyaRA?hB= zeh0{-Nbp@5+2jfw0fn+T<+A_(RCYaOp9B?3kT4Bawa&__#3Uax5mY|z!bf9bh63TU zC44_xHn{@RwBGQ|ab(vaN6H?E1WvedK=yT>>^C6lPoC_*Be9>d$rX`J?T)Q?9dhza zs4x}@Q+{jxJ}c`J%FYAz5JX{Fh}Wn9`3{M1DEoBq21>Qw6M-CC_Fzx;OeAosjsvnA zFoa0i@ra&S98xyl|HfxGvdI;ZJqO6o$o_Yzuna81ScLx%SlR0+`x{XCCGH-SeGte% zB>GV{xdK*S)s`!cD;q_Oy!H6sf`nyUhW`&***{SBE>Oop)M(0n5(uB?n?l*-3cLmi z18v!Wz>;w?7ouiUHsj<1B$iS(xxBVaX1}Ct?5eQc)*)dU zck(}+D;;|+%KVx_*l2enaXW>O#dB=(13;7zqhc09b^(TJyxa(fxh6N{_1^_n7xv%B zQ2Y@ba&$OPjSepY--RP~cQ>?w8Xf)}IKMm|3jv^Y;S%L5;0H;275)5t)z3SlvNRmA z9FSJ%z7IT%qi!0?mO+620Cqi4E~jQ-0!FVhd!j?DEOcor_BKox`diti;J32#!H<+} z_A=}RNON*&k!8o*=NnbUZCz zq)mVXDTwTBNDBHO!cIY~VuLR9tu93FCqTQP8q1%MvV&X(ckR#F5JrL35%tkPC!+K)4e}(jt;ZbEtj- z=oa$bgOCRCEUq?w55m9Uh`k;&)M=_w_5t5Z+UZ63+PR{A1pEWi*m#o_?F-)vi^)mR_}JTG90=QVOvt4O1b737xn_8gr&y`gjf(vWe3#%*VOwhT=Yr}% z5crOy+>Kb@o2Aw%EXMmup288E+XMYWwKsP_`H)!b?U@+%73~Aye<$r$3~d#P_AT(Q zNV^+xQK@KgP}ql~WRcNRQF4LtRgyM>Ot#*RLR62Hgd85sO2bCv%C>u>V+Qn-Eyt_d z?MiTBXS-S8XqV9k89Xh>h-9cp`Vh3zDB48LH>i!4d=Y5mGvYtQzlv@c8?vO68K35w z-d#K=XQ{EFJB%vE(Qk%fcCzHve6gyr9|naSWw}^2rQbBe>}<(<9>l6Su}2`UKxGbO zNxB7XX)v<>5>bVN-Ks{euU1V_-su^_GT|rr6Cl#Ck!8FH7sf(Ael>G$mMMUOpjOAC4icse3EcJwnh}y$E~p>o!*QIIz_q07(5GByd;{7p~Wo2d`T2@ zIi4UD`n`~QwW_AwswUrK2&O*@xgqQ0(EO^9{`WDoUlVdU?8|~>Z-@+@e){;1!u^^) zvBEI^rqhEkLjGN+r(oKBPp3aZ`X4&YA^me9+tBw8fV-A%T@U{_irUhv z$iwp#M-=ch#b;tBbv6A<3>|)v$`_FOUPn4XC^-wk6VT}c=zEDe&CsnBa*Nw{05W@O znFqi>Nb~#?^H*3X-JXG$hN^Vf$4PO&nMS1{~FxxQC7U?_*_N_ofH;Mqy!=wYI z3F!b-hgM~D&C&Hz{yZhqsO-#4IAgi4keMsI%sY|k`x6G)%S9d=jn2GMNN2LlRk}agGk{u1?l43wRv>w+9lWdG|S7X#!gBb8mbN9n3xiXU1m?trk$D>WTrKl#oHRebzi57z}ABUXu?o&a_ zTU=J-NUnu2?gH4SA;BH22O%>u;+Q=RyAc`O@!A!gVZ{b5qp%5C+#>^j%zEoVvutDW zMj+$N0k|GD0xsdHDp+usYrcn>O0SE}o}BYuLH#e_$Q{Y0+Qnu)l{L^_Uz7M3oRWfg z2E(lu#GW|h!Z;3NrCR;=i-0$i z#twLsqFn*}QqoGH$|^uGPjy=UZ~EHW^vmzP(UqdFy%1 zOlDtbVpc|${*7Q|bvH(&81^}!ajCaHinanY?ub4cC2~C109PV|Tg-op${6RIk8{x+ zR##~ht^vns;OGz?%u}m-wxnF$XB%mZj;dFSv5Jx*a|gjmFI7CylmktBaMwYbP^_-sU{mJ5jLm=%v9C3 zMz>l_x0BSCFc@$(2lCep0-uV3NoF}?;7PdhF&sv>b@-3lhppkzM zxL%d~T@Y`hI?7)g;U8sIkpENg9+dn|nAgG``TrE*4=esygrJMV82WpRTXoX7e}YLF zS7(+|sL|~dL}))Vl?yWdlyNy&*(l@snI|!p`O5M_3hVY5l&$W_KPtjsZT2O91CBb$ zpMiyNc}IR;*HZG!&1&-V)#qnP{+ltrmUQIb9N{l9<-X}9;N=|-M%AU=uwgHihn4X2 z7hoO6^Ajdp@cjD0ryKGZ+BxR4s~j~<|znKMjB=Tb>Xd_oV1h9ox1>xW(8H^-5qa8;)YeiJbw(Uz;V3Ku1NU+D_+`l14cGLSAviuq9=>vg%r%u&&{!^fKbN%+ zLD>N~a(Fwf`MIoo7Vv2}x^VUVrCc^%3G@;iA+E8$k(1T~K>05ALJWh)tohS!>g94q zqpUf(r&sfv`LugG%JLoVIlLv;e6yMz<6Yo;ambqgENlKxphrl;V;ja_Wz9u#P=p6} zvfh>3+Vg5zspm7(msyR)Tm(C6T!{Br0*g* zMqwjpY`2cS{e2Qv+{nWh)sVRc_q1x?z9dg_{)F29fFp|<(bpYf$X%CfRDwIiVszS zHi@)LfnSKj#$iy%A?T|d0^_+P5-Mm4acXD02!?iwXdbm}LSUU4!1K}6io>wEhWsk9 z9`45Gy&tvQfkSEV@L+22Ht;{=>iAKBM`OH+}Be|-%?7YN5Q6g9Lklq z458AO0AGSbD!p1Ny$9&aIHb~dNe%spIL{@CO5ZI>&w%tej)>Bypf;^ZMCmz-M(^t` z8#lhA(l>|HwzJp%h)$*S^@UVA8#N~5P)c9lpGuz$d;kvR{p(L9tqJ%X9IE{xOp}H@2lPoC(vVqF>mxuvB8i5aBS{-m zaCHnv#E@yIO~-`o8M3sE7BS=|MT?G;$sG(ibri;CbA-GXfab6ln`<(#p2~R+lbtz2 z4oXfcZeD~2T{sDxA~y)SfmDdY#xQH#mW~Ai%0Maa)Ig36UUb3~gLfoorHvj>V`^?S zQ+X=QwVPZ>;8xmtE+jg0GY7~xxtX)f5MP?&((&EajOR+^K%QrCE;l2Gb$Rf<PoK^2lb0oDPGr7r7kkVZFOB_p6b3s&t(UJ?=LANmY9Pzg8(u zN%}vJpt`GlrQGmWmEP4r=e9!lKO>diH9`6q^cWnlbj`n3>0nfvmyh$X_LY7Rsr1&t ztdw7SE5@NLy>%=r9SWRxU7^y||5~MWm@zmm^0yj?x#k&cx5U(eG!p_Fam1VggwL%l zB{CVvIwbBQG8@QCNbJPnE&=i}5+C9yz6?n5b^Lcb|J~1jTkx+hE6bME@&7U$M@7OW z)=6Psq3q{4WHmtyIJ{R|Do}t#hzM0HL!uN%G3yMlF0pDdbT1SaPfyW!RIE&k=K8yZq%Sxe__NvFsL^6S;PY z4H8@@Z@Fz*cpPgfjn5|D?GSWhGu$g@cNmPj`szenOF zBE5n91Bt&A84Lsuvm0L%IR%J?+3rUoX8_3pl7_>b1>__oN{O5YWC0RQL@ow$F%st! z`8AOHkhqh`Z9w)S!Mj=9`+&3}fmh2IeR@&D`5#WeQyN*TusVqO8**ZDuA46T=uqb6#s@YF^M@8P%yKKw`ftlAT{V)g z#6R8%W#53rJ|z5ul%S=c-31zNu_}zvC>#x7*bg9!A%C*Yl3RM#s@6*o^VX_$ml*Pq zXWrdq^Z9q){WV>)`g`J%5@?qUMP>mKym#uVXgR#ppS%n?yuB=W6B1XGcQ+Ee(Eq&T z9fy9w4u;G9<^*v8yNV%Jfd4bF(YRzj<0-IShx;m!AxI1+vKPo`Bu3$|`6-@HAa69vD4B-+E@-?dZ+aUo znXi1N+mk;=f^IJ~FrhysH5n&s=XH#?4KzDSxrcz91^K75!XrTVOu#Z6amgsQP8+Zc z?A5%i@g5TSgTd+p!h4afVYy@=wI4x8Uhq)Wbqc&%u!deG>MAc~@)Bd&-Wg$&-5 zNJd!+FOP7m;ScqYTLk0*$XtgbPzgkK(f%@lo*72sX=H83;f@FL8WOLN_bkcMdWky+ ziG85(DQb5Kkbfd^h)4?%7mHmRhkG56G9*e#m;{}8OXUu!tklb%2^xcPpQh=c+!_f= zdl5L;UGTOLZ8i*rzwOn?;N6>Lun1rAyh4oBO&AtFSKr5Lr;(}nK3K7Ls^~P{ssp^i*o6%OY8sNgaK4G~`d-G;XZa@}ms{3iyCS>tS`ou_< z5%&aWj90G@_2rfF=Rq{(|5y_jokYwJVGR2(Bc~HQl7_>51IR!m`VsjXkO@ePA#xbV z93*Dq2z(2~T6M=I0ZYz^w_XxRl!>jExSf!=7(5rSP*)(Ukhq>mFCZI`xSz-%AUlwF zipWSH|Axd1I0B~w;g}wnArq~a*e^owAF^b~yv2sP*Q+e0z%mf2`^=8~5$*2+ z2erRcb3|#s0a-mmFg&`joae^NId6iTVC~IdI|UM+@hWbGQ+9yZ1H}E&W%XUQ9Mp_B zKDx*o{27S4(zaO}Ud2$s8=r$iBTX9zU1W26v1`a1d3hr=D3QGbIW-L6l7>Gt9u}Zy zL5f_<>_H&Cio+Pdd%yT|ahPj30Lq)bK1Jq1GK}D7Gn z2PDfehI4ae7%s(Lnqng9Bp|C_T>rSfal=z;z~WXLRd`_XH}$a9SIx|Pv%kY!EOOGL zn4y5v#v0p>RhN%b^Skv-y&8n2~=8k&j)Qm~_<{8fE zajdX&G%L>GJfB7zk)LA5#Yv^|V_2p@dI|0-q_ZzKv*?r}Z6ca3u5Z5EH7m(XcIz@% zNY`|cO(3&iuGXlS4T1B36w?ZL^8J)w;&Dgo->pqP$n<)21>HNeC8DY{;&VspqnzHO z9JTe!7mNl93FTX?vMdE&ti?E49#u**sA3hW7{f9@p}lRDaV8~HMeEnm{+^y&l|=}? zUJ=)^aCICS=hO@)dq+nAq7s($G0ow!=bV&}XsQ6EMyex2x}zuhM%tPFiE8P7(yO`~ z2&mBCa|PNfqobHw)dqr%nT{p{|A2BR8SV6evTx?QUe6jNW6A5gEK*0iho@9$5gFXx zhoOAww|Z%BezFRAEU%=i*aPzW3{M%9#YSmJGrP(-I=S5F*z<5Y8iyHqXgl}EsHT+_ z41-pFHKOE~C`*RZ-L!-bA3>S5SqlQ}VeLk(NOZjAIAHx+Bh{9ykw=#2tEG$Hp*3 zXAGNipoSd%f6Q1Ud8PMgG% z9%<4PkfuzHCQWTN$3q+S`|oJs!j;fG-JD?e9EN`*M&aLSjphU`vkhqJ2{0&Org^G8 zb2d`5SDQ$#Ht)ogX5VS9Beu?5Pi(!p378@HY?hq1P)(+&Tx(}$BR3nF6EP7YQ!(%i z$;N%pV2BNZA((2OW~ZjR%{*UNYp3U!W5MaC7RfeNnQN(;=@Peb8{JsjmyFtM)6eD& zC=N?wQVl;A*G8<$fFOw>1IdBN@N1bGQzgc>Wl&F-xNTUd%<`+EGut?jGF{?P98iFE z=~@Ljl$}yWEM!38mNpLXOH2u0jSNpO79}1fT$uiK9XNQ9GRejG7Z0+ll1Z^k z-!*O(bwzc>G6?Y!KbA9uzZqwkd4pi980cT3)5wCZ;h%6c$E=#@Dt5&(Ua`;t)#mAv zhJsVus1tGeY)_noeOpyvURzclHkX0=d5a7Bi7RzB+BFOdMcgyij!i~KPfm{-nb^lB z*g1L8q`VrCYUGfkE^w_i5XDiy{~HpaIj^iuRG#mNWDmqCsO*>_W!h*YgBa_)pRP9% z?n+#4PPCU_h}4BwGQjzZsD(HHQMofxX1tvUBAXnXve7Y2!SBtoF3`B5MuU=ej*J1& zIACbn6zy2IvW+&;WL)_f{TNK~Kca*jF>5@9GblUWE**u`C{;vHbtvJl!#{RL zyuv{yoo1tFC*9#x=p)y*%Q;pWeo_*Bi;Y!{ZVs8y|F90mXnVdPabWVNHONHK% zdl^z?h=x<`E6qEOV|2t%nQs}t0rozHhj;Sa#-Y#oIs!`PwWotcj z!(dE9WHQQDWHchzHf)&GtcDjm8R=yzou2DO+Z@Rj+r}2m@q!LHUhLW(+f^GUof&(a zOxY8TSMvWInRss)t)v%qQjO%2$bU9IwKLW(EQ&JGE-D7Q`e`>5qGc72Zc*~6ZW`&R zg=k2{q3ms;!T?BfdX2VqoNMDK{^ zC8)7v3VQ04vynQxF{*Cq1uZv(YVlPiRc-Y~e0sIR67z&|uzZKZMdKU0ns=(2IJF)kH;Pt8Co zBQvU=h(9!|TsWm-I0EZ9&FVFNJBe6YNjYu9h$l)*l8sb{O6!K8(jg5|mD&wc_0XWo z=n?_c7^p+tbwfmREsAuDL|*J1Gbe&X5}>LESWAhgM#3aw_`jfoG)_&%HX3#@#%W7AwRJ)o(r!Z>!t=Vb%Y;HBZmK)^#BBvvqOHcCK+^b$CzKTJ?x^-0h?W{SgyMBKmI;MM6b+96 z*9fV^@ws#bx@EB1wA~oYnlZUd z|NmD?Cc(W)*kO$9hR{Q{kpzb)6=Q8#yjq^HMSCdX-6S+7p8Gx3u2f9zmr1$_k`Q)D zi_A&(BE@9M8~oSuJdDw^!rM5&H9OQh35=7LvB5k(>f@@+98{HqyGKFsld??hTd1Vo ze^8q_@=U9zUJAPlz-t=;>~s2m%wB5;viz&+ZZ(;v7Az6OPDLcyZYRSJ|M+*ubqpbt zIqpvzo&Xmn)WC%`16f*o&>r}_3EK1KmsT|OORL2Oxy63ji6+17{NRB6gL9o5O}@^3 z-lY)tckRf(bAKTD2X~V{ntPM~k1-(sG3K=x81q_;vZk#?{XCOUr^bNEKy0JkDN~QF zzu11SIO^-MnTBpQ-)m>+d)8+b$e&r;+8MgdIYdJbIp4J-f9GtbMVsBN?F`-O9wPaW zdq+D%@9^)Sp*v!pp`p*jD7B*uXi5I8Ig3WVc9qJQXTu%Tvbt9jr0#cOG{@ zdED7X>=U|YEZlRK3+yg@GY#0i?)}8>cOM}3fV+j*7Pt!7R`*waV88NT%K*OCe^(64 z#jK%Y*2LTo4Do)V-~X0oN-y_H=@)7o(+_U{OnfI~kM`eyj7T%eOB*0~P^R3yvaB2i z7NP8tmE3(=X|6VT@nf}#ZRb<%UFQ23_w4rx#sd7)be9{=yb|(H^K+6ex9+gOx5m1c zV4byvV2icOlBe6~D{sqM?iC2SUs+!wuBjLuiybT`d4pkmu-U*lT;9gw^No$gop`2? z96r-$#VvW&xYg{{MUF%u@|HvPL;hU8Pr=6b8phdAiBE)AV^2vv2WoE<9}Cn1Jo0l@ zuD}e;Eje5GF+lq>J+!V7>NlQ`@pzkf-eW>xKW}LC>P2d$tiuMM9cwQ(I^$|lzO%^a z(}kL=`rI{=ClFX>EH`p`6|KNdd`>3}twE>Ru0tZ2=`1#w$jnm|siga?EY=6=ziVDY z_0`XPUDD+>sUj%(NAoDJHeipP_n;bjY3*`fT<_~n*4xNXcdw+%B|s5^yr`@6p#N_m zqZgyNpSLnXwpSVNOw_x~$yPHucV#t!%y!ddW&ld`z|6+dyvI;^$3L2xk_yrk$tgqZ zb?$UiQpV<~9 zyf@FE>xEATjy5*lrRQ}Amv2VW#?^Y74s4@kYoEKr+Gurho8HeG)Uf+QlV>71+2d?( z<3!siFJ06|tCySdFnwhkt&ft(8__VV(MTrU;-yCN1x9+R+RsQ{-j-~RBnyS?9~;1* zsr=9T)960>7eaVvnhnBfcD&pex>7{Vb&BO>$s)(`ALJ!amWv`@F1(0(Q*z4IX!X`W zZV7guvN}H96DR3<1vuo!nonkos#0m6>~d1({S=6#U+}IBD|7@OX_w!(qWkfXTT078_uMt ztfr_eaITQ3u-%~Humvz6*lw)htcyzPb(p>2LkIKz1{aHMSh!$T*{o^P=SCDcciN0Oa~J$SS>xgh7XOdf2bWgNo-w0?omIWc zdzDvt=KkUqU`w1kckzs46p#({OIwn1X3kyQ+%)Y1nOrpO{9}lWih`fdr3@V-9V8z| z*(k{!%CZ1S=PX>XM9Mm$YQI1LS^i~BX8x-+&s{Kc)-qQ0FE@oOc?=i-%Q}1BTQYaX z{A0*FzT0&$;87~?8}}G6kjA6SXD?oILDQ_WXU|$tK8F+a*)wOIGi_7oaSrOfBf_=}V~zg;nHScn3hpM1_v;_-vAi6BYaAVGM7@C7qU52#ph02G6#sVkD1z)DwhOLbw!!B zXx6kS9|mP*3?m4^>j0>@8ZUrz&c-*iBRMLdSjhpx*?}lLM0{+x&1YLq?_uT z%ybVYXJ9F6sdAW|Q-)*(l4eALDq)g0XouIYiUYMU9a&l2ZxYp#5 z(_N-mSd=>jSLrGrlf9ih7~%s_ zD4XPD=Yx3wk}1N1QPEuMVB?9oHvA&4TYnK3HY1KxW1H@ez$~Rzxsy@hn4O)Bd?&NQ z$>;aPDzQ=xpNfSJKyP? z?^L5VRyZm2F90n9> zW#}5q%8`skJN9sby`0oaCz$7?Ryir?SMC+M&H)aZ+DQYc5HHn$vvZJ{kM5e5%Y>68 zHJej$24q(`PHDNoXLF{_Y7hpdmXo$REj%t=a{_aoYXX(XBO zK#i=xwpQCCSW;GSAW}hjM9A$@(QNDBv1+*8)-@c6)F8VdtFR_|R@m0>WF-YDvX-aY zYO%6RYc@5nP+oaSd*zJ?3;m%pw?L;1*}_4`ETr9V^u7yGp=!T~%4@XB5vPP?{B>me ziDexosXG~U=wXQOL{w7fj!Ky$`>Ep&l%a^35y9r5cbM+T_MP;P2Fqg5K~~U7uauKb zJ_cVmrDH$(o5!j;O`48jbgGc*FPt0)qNKILbOsjF9~`p*RfkY62|4+ZzN7loPw4|4 zKSwiPts@6l>RvYx^L~yRqM@7PlyOOcp^Hn3BBe^(e_2H>IMh6<^5v}HM&<@nO`dJz z)i<7fDbi^v5&JL~NF58ceF@IMF8>48W&Z-}+O+=}6Q$EST6cY90!A2DgwQr74yUYr zID95U3E{xOG9l!|b>TvT&Dt6MPpoo$rB0P}45mm7l{HM4k|D)Ou(Hp26vfgo$yqbY zomw62P*Ff2MV1zWUc;9C*0Bacu#N4k`mUx`X~t7?<(OjQeF4b}(+|FN)unJQt*? zrGm-$M3@iIYY8lyKoQ-Y0s?QvogzZ^Op!s1$x6df za_r#H$BqzW*C=35lS}ZnvE~`MHcDkL<7gRIk2!e-x|@nPh9>&Za*TUcEEY=~3_0h^ zB`@kqad}$ty=m5laK2&v>JtBlaviD9fJm%ziXp^1C5nNfZn;~Pk}?^B%>kW}lg||3 zAg(E#xN;<|j9R@k(OrYYK`HVCD*^T6L`fFlii@Jzf7@V{>Q2(-SkI1f`Xf8D7Ef0? z{X09E)M|j!R~HGx)jUbT&>)j#OhHYBxrt6?l}hG1m4&h-Pwisdo^n;3gY{`wtQ_GX z8p2TpFawDMC%%glR}0%lV)98D;gsUkDJC5zV5%7D^kuandnT%|Lv2eNUV3Ua_Llx#RxD}obaQk|Y?@kE}I7CMbm zqY9@CCgxDd$#7PZliSrvv@XEu;1EExH)N&B^((E&bAMDw$$4Cd%ezi&D^;|g8u&a&I9ti?{nVgecorC zGiT<`WrCrRPt8iuTqi`+S)K^)G9o6DHp@@MD@68cEEds`HeZOPCPI2FjSe+4B`#2n ztC?^WSH+mitu7~HF7z`o{~pT;pYwEibToqU@}jto#rh%#4bO{!oRpQ(A&f9d`G@ZH z@p@AZ9u`1xppd&{30^3~;T9Qa)%}5IFN+78<+LA|g?^Z4E}_|o>|@@we?D`8+;=oD z=y{c#gL9184VV=@+4uo}C#Y#>vT0HJ;Y-Zm$edtn#8iOUnlMG_1A93sOHHvy(nKZy zEHOo4T=$e_4kg>s{0}n_Gs0%*jWM51;xj{2odY-K%_%p_)p@uo9c1QMf1Jyosa5MQUWftm(>jZPcYxnxv*|SX7^t)B3eXUPqeIEC0*fVjB936Oabby^4&7_OV z>w#7@m)FPQ^4f|RtE}D$XgD`|?2u^ASQfL1V>mB5XhQT@ZbuDfze9aahz_!%v3VS9 zS`nkj7{S6eC3{wLGzW&5iW8IRF|;`ZmjrCVlhNbdXa*CU5zRb?*AhA%oNTTtqS0Z| z{7aeg96_%1xz_M+I=Yh9!tA}qZ5!tUjW+`CIIVf z*hAoerQXJZ-G!JC9bh*Wuqrbp)GmZ6A=-0EV(pv0{vP1eB1*Q70#aXFs<{HjBOg&;Tf6x zeRk=J75#XB-D=jXh#Ecc5e6@;JZhQeClYC&mS#v_t7GMbhOAfj~4keKayuNl$5)e@g>x+{OC?f`rBaS z_)s0`2PR2#s)p#a_%{0%?0q%*|bD=8I^`Qe1bZ zL1sHG7iZM5#;F-*V->T; zY*c?VFFG5GP@K>(B4&;^KH|0j?-9frSJ$s#r;7)q?z*SlQIc6FUo>%)tEevbhy8Sc=tDE{rWGD{^AIfq|PzvG%%k zt70a{g379*;;LA6Sy6GUqOzix&f42O>&{!Vyk&Kaw;*}rgLjwKHMYkPU$=JUYWxt8 z_sJA47F&;7Uo&8onV5Sw_>BAACa-m|I@}Fwh&zCrP_d@EwGFEq+tx8n0q%#>XInuf z<%_CIW2fbp)x=85D$1%$=|H2o>9x9f9qzd~xG!(r2)c$F>T7YIsttG5!nUew@~cdZ zE(BwRi>hlX7r=H^wF$JjF37K%UtAO`DlRXsDXW-E%lN$`bC1t4_rp*ZZMdUE+qR*Q zVs2SQtg38osj*{gyr{S&e^GhBFaj!(CED6gSui)YARkHL$3kXgZg1i4qP?FOFD^q` z>)Ptp*mB}#9&45LAGftIzlgnJ(SizwSs&Qq<;5j6PV?Fr`&NBjYh8VF`+1I6>CURP zEz3=Yjpw$v)y38|pC2$;Q+ z$=)qR&Un0`5hZ8{Mm9AzuWV{})*@$mY-_)|u&TJYBDScayb|T{+sjt;+^VvoSXJd| zwscHn+L2Wl@36SR$h($tlSNher^RaWtLMk^i;9A^uXZb_tU))Rekhls>cUulRaO2{ z#>Iz`)mL+y`s=jrikG0e{aeGCT ziwfXLVR>00CI*Jb`+^zsoLCv0Fefiv#QwzT#*EY0n&yVq7Gy+4I*sP1kG9=7pz7DR zwefyFY6YTKS8MQ05j<;e!4z4ywjQ_N8&|TguWZ9$f~m@ad9jl6{JF8}iu{EO^Wi8% zgVVXXw^tvWa*Y$VeaaT(&n-rKTi+`e=6e~_CH(fq`bGwr<~2_~wClvCLe-ti>;g4w z#v+2O^#z#Q{Js~QJgp19^CjiQOJdNiK*vW9D4ZYkBH;uREV4a8#wI1yg90Zzcy0jC zpajmh<&_n4V+*T_t1$(m#0!h_YnU>j)vD$e%$PAFUM6qGwhyKFK7doUS)Z?*KoGl7FJ>2&aYUCF`h6);{A>jyFK3^cW+GD z<_Z@HC#QlLCrmpbSf%V$apyF-x3#p_wKun{jh9}NF{fhN@ohsdu3lPENG(&OqOz*k zVmtn<_g+~M5jRy>T2`);DonLDZ)j!wy+Z||}^9u7ZOHnRJ%sO=aT09xKwy_}(E4DTkZ+S~w1AJfCZ05XJtd5UC z#+ntbu_+Ez89S2eC~Y;Rt> z(zHlZGv?$*EH_yp!IOk$8gBs)|IGv+oL$Ylh5?RVwXi(Du-GoQ+FM##+QdcDx~95@ zmUFbM@++^(^to7daYc1mP1)kIn!s7v7%wTWJncwhiOu3wvMBz$9cWc^l&WVdEHXqf}XxE z?nZTKei4?n))SapxsttaP2IWiOuR`96Bn)`16Mumb!#U(EHARg9N<-#H;LEvA-~Jtz&zE>1%Vb^rp}LK(upDtQgZ~O_@0(SSz-F zVTviPiI*|3CW!}{IkE_=k1EHWLt7mU1hp=*OXwv_>=}B7)76y~)cW|sHHmT|zl+V#3uH9Bo!jXhb~nk(np zxhS6(vStyE!EYx>b!+w)JFlw;#Vf}ydRA4gMC+r-8IMt~Q}<-NV`!Uf&h zb-Y-O1yAjE#f)La^8_<9XK|dXu=K}i0WDoesJX(TG)beWSC^yE<`L&!*tkakEq~SK$T4xQu5tdSlJ6HhX%^0ibOC$qRnN7UGUa69XSxo<)h^Ra zlT{a*?GEEg;zb)SnUR}=AM(RBT??)NIS+Z`!*50nR-CR-L8a*9>P5`c_7{95p_P@a z1~n@-YuhXtY;Y-dV`_@+hKVh&*G_NQXA0f$hnhwQSX^L26g46h-%-tY$km$QYH6=n&9?CkVu z&L0VV57Q9V)cJu+g}`E27k)=nu%You+gf{ zzZT%BP^aV;Zz}ckOU&PxPq1RPisCJ3u1s)sU4-k9mezH#dR$SNnh1?pUjC{m@!5>4 zR5Mz_qjpin{EEuc%=~QI9b1!TlJqYWSq3w=IozXYwZp_V1o!=zSKzXl!^gj}Hq$ul z7kCcYIkFxrh4x0SxV$>CJp;a3AA;8%rgXT>#T5e20_Y{Uki^!d*>2O=x5=9oid9=X zzM;cSQLD_}6f|61Ue2itdvh^tJ$OEF0ts{ha{}Z<&-I}{-)lR|>>xwgJesZrjUA9? zdgexDxZ!F_xm9K-HJtBTunCLHrGT2*WezM~IigI(QYUb_#*B&$mI_=Gz=4Ftj_D1Y zowUiwYYYwjc&TGIJ44OM*{|(9IJ#m5z3?Xu&0Y&C7htz%(E_a& zc>Uy8bpck3F##l6kRi(922%K$gJ@MC%yjQUF60a3RjeNo$sZ>RX=WD z;93kFx}~i>&%d7IHdpY{F237HU*ipCH%06&2ZMus&Tq1C7ceKVfDwD=LKhd@6lgY0 z#dVfxRol&Yrm(XFm*7lpOQDky1N@9|O@$>SMwGp%w!PL~@Wg$$+4`HJflI35ib7mV zSJ~B~deF+Y#zwQTVw<>P(SpRqN;UhR8QXqOjPG{X3DD2l&Q+XJmS}sSv7y;qu0kcD zEtf7@I@!8$uElxG#%`Qoi4dp;tkp3+vCsK8r2PEQUF=0*O<8$xWy@m= z@DrNFePU0uYYN@+@`{WvTw;F4x&?J?@7aXsPEKUi3-irM!=8K!{Y~G566cp=_m0(3 zw;cCIOa^w95Nt#Q+kwiZS7$??^Od)K*cQ_jBsWgIb(h~&DlrCl2_9QqR$a!`jJXi= zHbDISF>L*nVfsYP_$d>XW86PuhqYI5eg&GVF0(YXy9bC!C@uGxd3r{HZ1u0hOjVC> zouW`UH(~w10XNooDT$Qk)M#@p$j9ohW$ns54pe-36)Vm4CYilVjIRb^$J>;$fq^b# z@6PGQ9PHciR8~=4j6H97WUuGU&4zgQv<-`j!nFo>oTz9fuF#!81hWzBd7Iu_>sn*k zyF&&57OY%fSWj3}qJ)t=OvLn!s*9 zn!aj>5Kn-mI5CBKKJFjlw8?&pji2?nPKfc2gVWxGlL<^WHMYgODV759j<~*+dz{|= zVEAEN!xz#T>zi@zX*YM>yc-tbp@I&=Wri6oI_s}nTi43fCR@CrWj#j*FF{OaRz;g; z^0yWI`sRtU824R+b&9*ml~}ze-kruGWU=F4fY4Rk2V{N;=LDFs?&{8)x8AgYoKL(v zMc%nhOC)arVOmk+F}}xw`?Kb*u{C4XlA3kwT)}(a=F(Ev`c@ArEJSgY-C~NLy6uIr z*^`9B^vdjwqJ+g&*bg=nL%d6RSI0O%bKTnBVwc}e{G8`a8nz3YwMXc_rhgW(p7|4Q z=(bEltGQ%gWpK>IyPJA)HGIi0vNOH8I1e(2HJygmA_R5@~? zQ?YoGxgPdP%$tca6S&&M`id*vxfP4@3MVhgv)=;Gn>=yy)QQt3P0bs(roMIk$@uzk zd*iv|>Q02b0`l6%mbK$nv`(5vd38%&`#5Y7pN#$E1_ZP>tzWYoL=82ajPKHKm_Dv< z%$n9Q>l*9F1QM>y8&|n5Zydgwd-BS)>nER^H*N(Vtl+(maZn`@y@I1PD6e084kmL?h>aN-0a2OeQ#UZwxl@&nkn0#N6icx+;YMClr0%t`;;ug{YSsvF)aO6dBXHx zv3RoCQ?Yq*ovSM`Gj+zN^&>h;Wl0IP=7RTDy}8gvEOpkeH5ZZG3+J5W`Qq)N*m=+9 ztFf%C?UY%EO59-1zh<$4vA{h`v$Qe3@%znjuj2Q77nUuqOzX=icwEIRbG*aSn!WA| z&Z}lgWmaxDUh~P0h(1$!rHMKEAqhB zG=eF{6C)pns< zhGi9{#Z_fy{lmV5+bQ;bp*dUI`-SGCc4F)#Y=)Shjk)=Y9VnboY(Mk1sjRZE7d}gv z)33kPWorcMpM_X5R#jkqi6*d1GWKZiiUEDrzuDEib}iN@cvh>$-(RykN#1$QY=GDi zU>-ElUI@NvZ#qMu4ht6Hk(vr8ext(o+N(s(dbV}67PeazP_?0D6^k*3inx)Qj}sfa zN5b@Hx8N9ThZ=7@=?w3WDp@|QtfrKY^6*|6S0zU-O>k9+%SOjrTiDYgYG*_9I=lwP zY$t?`;#$c}`GGg36t!T-8Fto9SX{isdx4DEaOS?Tod)SJO@(?+P1Pdv)Sa&8IoX(< zV6$swmKCP@?NZRL5Ra%4dkYOW8dzF$?}`@{p-cbxB^#IacG(jc%$#@PQKV&=V^18N|d9uK~Zo)AG-aKO1#QSu9yXqMuI}V%Itc+o| zm$Bvog-<=et?*4(-C4#ogdHX5+U~7$rX7$-#Y*E+Cb&%Wl{J|tM8gD-Iv*p^99oJ0t z-j$HIlC&LwJ_Z*IdUPe;k$Dvd9ots^^G(|MLxkUP%{eCVaTyb27Hh!;2v6omB%JEh zqids(%lTB0pP@F>xW;3LGHq|y2ex8aLhVv}>wW8KDKDN;a6YZ&TZ_BT3tQ8W8WHva z)b@WDb%@<(qsPoG(FZud8?+dSriOIm!oR%>7pzS)_ha5msC?Y~$CESuLyV@h)$t8t zULyI`#{uf^;2^Ixb%8rN@jG4GG~jsQ*#JF0xIY4GW-Jyis;b6)BJ;otw@7_AH4Wot z8yXOg>0q-wxP<^czimp(@XTdkv!Bz8ZX^3wR=A#A5ZGMi-7B-nYH|#A%f$W@xVL0` zK=1)CtYEbR$dOKVQ%4SdzA%2liJ(BcD}KVl5kdBv~;mqBqs!xO`SL~-bw7h zBrqT3)BcKCbm?x0-y_sY=DA8gP!|=pPQ1sl{goweK|)mz zBI#t$Zf%=}OVf4QytdOmw|3VjUU+$qe9^bo$>(9wkM~wr!FE5~L%b0yh@}|gU*je}1D|>#( zas>0``wk1T`ff_u9KAI8vdHDo%g-uJD#=1c25s?;l=;w8T_%;KWo75%6;LDxH&58BWxcbQl2 zJWm1S8#D8>@-{^`<6Xg*q11J0S-nu8pkM4i0l&`d%CDp8<-vw`bmbTOuy?RNgLOI< zazR$|CbuGOPnJ`dUVy&~J!SAUyu7Rc})P7cW_AvqlX|61l7 zNWaRzU|Zh?{m?il$eOW{!ysY&?S!14)hpg_pp`T?t5?BWws!MRf`WNC(s3u^V|4ns zd?zKXTYjqBJt-}c;r2}K<@R>_MEbh@-2U!B7cT{Mhqbc*i#;iE^tKPU7~$@8$Tjw%|!bdX1<|)&S^;rt<6`9GBkcf z@Lsw^`*=@X;E3Suaf$YG9R8+Z+&c zV2%E>=f#hR(=TKnzf2rBBF=!2{Q=J9h>zPJ5YVRmV?*+wko`fS_`Hz)Jm>BN`*|V# zAt8Ba$o|k!{P2+d;m%9Yp#PijKgk&$(my^Vj||x#8HyhrvOn5+4H~r1b83<^I;78; zH-1E%aUuKqd3vctoCzWO6P#Zlj`nT;pJ39j_DxRkKk-AvnG}*Ihw|gQjpIkenHtJ( zs&fF*%#Y{vB*X`gh%+rHBERV&`_n`5Cx+~w==>8JwEqzPCpjmE^k;_TSt0wgLh-Xh z_Gde3Fi!h3@IT3!9nzl@lJi6M^F#54A^U|!KRzl8L;A%bxg=!2Botp7vR@jCpBIwn zhwRM{#V-iiTM&w`49N>a_7;ZXt3vjwLh&^rc~Qt-@P`Z8KTiwkFA3RSf;Yt5_S*-| zBxi}S$1!G)CC+d*E)Kk46z%*&^V$0oaro-*_z`i=2>D}w+1S&-tD{5tpXo&zMx0nk zt_|6%4aF}H*;^ipZwSeaA$yIX_?01hD?{q2sS$XhqhS@_aKC|E-XGLCD?(q4|GX$zanJsictKOA^ED1y{kg;*M#g{6Ns{`jEZrL-99+-74atv%>^&BWe>`OG z@lgB|A^FLWy(dHQPlx1ZLiV3A>ACi`$1~2!I)B>hsvmd}h7sr4ko;UI|K~#SFNEY5 zL;1gG(%<20z37xG{{aYdotOO>euy~V56Qbi`R@wFhtr44^TUw-o{;=X$o?y#_*X;n z>mm7#ko;yyek&yJ4aq+X$z1iskBIa0xPVU)Tn$vK{uq&s|7V5dj*xtPNZuZj@hcks zL3{i;C-0#AW=MWNB>y`krzd%-t$%qTd3s1Lg-jE?Qtjy!I*UW`YeVuT$-|(ZO3rT-0M|4b(nYX$mi<>k(B$=2RV=OoG8 zf9vV2cKG{J)E{f)vz-`Z?_m9|3CZV&MKo><@2NgiS34yR2rv+e0@cCL_|V&p5FyAtBBalV%zU+=t`Am8l#F+slF z`Co#3r_%$5>5t9tZf976e4lfoSb{^>kiz-U`JZ3dy~?dDd+G+n*Y;VYILNY4{Ep?_8SOmd>ztXPEgSFmGrc z{eiE}9_PYMH9q1JkK)Z??*YmqW9--bJ59vr89R;ez6Jo7brYSrnfq<#0SY9d?}2Br z6CbcJnoNS5(cWu%_zZ8{Lc)U~-kYMvPxfv<+9wG8@Jas5q{dIgNBc#4`+#GtzO@w( z@J{TcApCw{pm_FCpg@4$=!1~>H;pOqJu`6LOY48hTuDO@;du|F^1gfE9W_!8Jd=YE zbDQ0}jqTMW4WM%H@RE6s+6yKTuJ0Nkv8izc+6TIs>WFWPDN`FB{HCo*YaU~iA^Qkz z{B<2l8TZ3$iNr^(1F22NH81q>9vwp@Z{P=XaC_8z5k(z8F(&@FRbqJDFui8}{&!3R zilzg_`+|8_fY&pO0A1FRePYNw0EQ4Nv1fYUV-18H@kSf_7-9VBP%AUFd0z$W#Y613 zb?Bh|hC3SDKK~qe$(mg9A7zxhjx}L>yh50T{eB$+j(iNx4>XOVuPY!hUKW0zDO~{AI0^0uPPM>*+C-tHe z^sRTcTbL)AVA$^_=sD(rPcI<&YPEo#nT6ty&QY5cZf9cq#VKjWgV97@)(i|if)Y^o zV?rrxe+?)md=c35;fQxAFtcDeDTjvx!#XKbCr?8ndya`CzOlhTtKQz?71KV=W%T(i z0rNPY(zDy?3pW0D_Wyr8e}5D!!J_#yoOg!x*E0XJA)|RSoCjpC7t(Y$aCD9dJu=*E zrgfr!Y!~`Ny9gf@56{5Iw0;imWP!&yP98ZNKd(!Uah%B{Ry5q{Ps6VcEtGt&WWX6c zfq!wJ99%P`cbF*OB?8W97Mh1=AAXtoo^GEDNSkNxN2lRt$wa96 zez6cdkdDi?v<%nW5lzdq&%GpN$$wTR59pct&UT%XAf~}tQ~n~yDSeh`Li;3AphAwTCVGyMdBxz+ezqcB$4iNh2Nm?dnA9C?CCns zOMVSZYR2`hxR*SLKR8CyIFCSiO?$)dIS3xa&V*xhn`KasRlxGi0e!u5;(Dfh$EbY0 zRX#e;1NmhDgHXRbMqgxL!iV6aZ;zdU2lUf`w1L)M+Oe*A4kT@m>y#rr=_<#JCz4G_ zvi?c-bFx-s6;o~!SwzaMBI}tl$0bRZ$qq2>IM=z7%yZ3s#I(V#?Vsp}`xrh1<-xzS zq41OJ@8WlzLEO}7BZs-p{p0}G*+W9x>|gzLXr}IyK~2*Qq7p|5_6H-$0H- zxybRZ^9+e{y+xv2eGLSQ7KnH1as~4-)gzJaUZVtWbQL;xADA zm5RTgoaZ>-CE?$05|#J{Il*;)LBiiZlDLU-(8#FoDCEhgZxZ?Q9Krmjk;C!)3d#IQ zq~rB$+9b3iiFEgnm`8SyQ(WgMa;ocmpFF{JzCgVW8s$2(QQkqQe;%XJFU*1dISn5; zK1)S2J}^$%{|2Gnd5pfz!1U)leDwRdw|xyeJVxJR$$rmcw6`7X$&c7@KmPHM{7gvp zwllr-yF>A>gyc6u@=rrDJ39~0-mk4lc^E!&-Wp97qaTxKuh}NtvF8&^!kjvJK5G!q zCre!WJi~7tGrw`(x*Fk0khh38k$=M<9HZa2WWGc2k@=1!k*_)5BHvjiT=O^VvppEU zoP-}6NNnDAkY%oO2gv;HB9Z^So}_;}4wo2=pD3b>8kyx{IEIR0rFe!2 z*G>3Zaie&Vc%5kK6L#3;XzxLhJMffW7JnkLsTuwU5k)dGmK26K^%!ERGsM(mh@oc4 zeR`&^5M$yh@mz7Uc!T&I@e%Pk@kip%#Sg_pqLXCv>md#j$BDDVa&d{+AhwDd#cRad z#rwr4#ogjh#COE~;%B0Zd4%tcHk@%^|g(dYe#s1<* zk^7a5pDoT47mM{`tN1PPO7S-FUU8@RlK6)BOYtKy2m6xD_YCno@j`L4c$Ij)c&m7) zxLtfud`x^=d_jC!d{z93_;c~s;``zs#6OFN#D9tZ6VotpvK+^X6U15KX=1CmLEI=_ zEM6{NE8Zk-74H)77atLy5T6ylFYXcF5ci6|5Z@I)6h9XKDt;z@F7nY&mNP}n5POP! z#X;gQag2D1c)HjjUMt=y?iPP1?ic?eek%T3{8EgjS^qM`;o=x^k~m#FSu7OiiS=T$ z*dlHauN3bUpAdf}{#^X4n3-<;L;SAzl=!^3Tl|suruZ}QSK@EQkHkNT z2gQGiUx-P#reVFNidkYWvA>unju6L+lf@b0Y_Uk3CoU8hi_662Vw1R5Y!}ZLJH$)H ztHm3{+r)2+_lggRJH=u0KXhS(&o7cUX76Ss>y z#h1i4#9xXZiHF4hiRn2u-@f8-ak6-dSS~IVo5XX(P2%<9x5bCWXT?{?=+Zr;8_xg<_ewP+Tjvi{BD26|WO-6Ymxu5}y>`5ci6|5Z@I)6h9XKDt;z@F1onj zH|G(thj@&5tT;>@BTg1i6br=pVvTsFxI%0Z&lN8cuM}?-?-1`3zbif~?hy}){}jIv zBfV|8dWcmd_8Cu;yiUAMd|3R2__5dn8y>8m5#kwQo4855MSNU*O?+Scrl+8ZZU zh_&KI@lNqE@fGn8;um6WUu$oISShX-uM+PTzbC#W9uV=>Bs(6(d19@2j(CIkZSi^W zH{v1jzhZ8GYj>1bBrYVeMqEYy({WnFcEw*TUaRmM#Cyd1#fQny@%fr@@^kEiN$x8SCSm7z^04DfSNKe^NGuf>kkC7wM7nQ@mni&3 z66L;Cyi2@Se2_%?XGo;~wfMfm|3)JHr{WhPZ#Xa{a?gS6&}GoOs4N9W{bVVek9V5Ad$XI ztW&dem=MfU=cZ$2kJ>u&m^!G{r zmH3{*KbHK7cu3)2NOo{fg7%{%>|{&sCH7PJQ1T$|XOi%1Hrb4QQ-v>)+@Sc2#BJhZ z;v3>e;$bl(&)S_r!jBWl6L9~GgnvuKGZo(~d5ySH><~ATtVhW=i(3_bpX3L{?<)K` z$uEgNQ20+Izb*bk;lGpo2k}n||A*v%i~m!2_rbP2nPN{8ejY1%usA~DlO&%Yo}}<% z$z@`N!k0=uQ(Qr!9#@MU3g0ANsqp*6=ftv`0q-7Li`>H{a=dz64Qs<@Z-d3B#~iH|A#dCA`we@LQyzb2a<=Ku-+J|%zaIR7R8h;`B!D`%3>KSrD;o+@q> zw}|(OFNyDqIb&f5_1A}dAJ2V}DEBmRrsC&Ho-Zy`_%g}0Vxz)a$iHDek$j1GgLo&2 zeC`(SSNP+SpBA52_-o?N75+={U4`$L{AckXiSne315uyHknksuM177Hr-~<$&@UA0 z#S6q6#0SI|#7{}oU-o#*0pvc^ABpmvB+gO%eDbGwu0!ExiLHwNCiw=w_pk7+;$4b= zn0y8I_Z0qyxL5Ii5f76uI8H9k5%i;vcq|EjN0QH=yb7NyE>Qdu@^Qymr|@&cZz=wA z@)3LwLE#UGk1GC2@&U*BspO9p|B3i_g&!vG!T6mB!mn{8{GB9DSNO@~oml57e3`gL zJX^e2yi~kJ+$w&Dgq`n^$nQn+Qpfp);@=V9SNxwO|5g02=uSd9_?beo{U!Gj`;o9a zN%7Oj+wk0%;%mgEif@qIB%ULFQ@m2VR=kl!zIRH#TfAT4J0(9QK1U+|pNRX#|A@Jh zt-ZeFMVJRjly90iQ}HE|=ZW~`1EY7QxST}#^GW!3A-U0UZdd%B;ysFgRPy8E%i=5I z8zj>IScHkyhrhmN`72?S$su&gGBm2i`lp~pxxeN4E0U2zQsauuDDn{U5t@P-z<5J*rxD} zk~_rBB=Wgkd{lf*{51)Cza>w1oWmsi`9gH3+4u|+;o0JG;!trU2|JS|PZMVChMdhs3-_8ui`Ft12{mHemU{8)TP{H^$V68fK!*q7`!-O7DQ*gHY25Kkv_ z9A`cGPsce=yg>0+O1@USn}q(Gia#JG&9L^56Y+Z zZD}V%>@D^ahlnG@3E~uS5ed6zh%E|VCvFrw#4E&W#9PFz;P2#iSi{dNd>*CME zUx@FEzZX9d4~qX5|0|}Y-h{ zT;W%Xw~(ms?UEl5A0d(MRq;dd6Y(En_fxFiFtJ3e6zj#+;-%ts;%(wC@ip;n@y}xV z9P4La68&eOI9wbhP8O$$Gf9-AQmhwOi|fTJNYukEBZgghVjnS2943wvCy6JC zv&FgMe6dDcBG!qG;##pyJcmU2uN1e7FN*&s9u(7yto{fQKapV4FA~oZTg6Qz>gRIt zdhurQ+u}Xq!{TG&&&6MgABZ1`e-RIfpNsz!yA|8~)5Req$~#RwRcsS46CV(NAigIa z7IRCio$+F!*eG_04~Q>{zZL&0=FGKrhKdtOth4gT-MD{1qW+eM%gJA3eI@xk@j~)* z%>Ux$;?-hr2l45c7sPGiPsM+erKlIz@-*=R@mldN@w=jVZXD@emHadD1M$z|f5glr zYyVhrf_RE}su&Z`63-W}7Vi-G{T<%Vc||nOheI~cg@bt!8-JR31&Ouzx5X#L*Tmn5 z{9X?A{x1Gk%uTl8Cx}bLwc-`xHj&@Ip`Dk=sN?j&e{zvnE3OjFbJX~J8D;D}+%LW$ z?iJ1R(uhASIU~jD4-&_a6^?U?SWRMW#P>Fk-x1#=_v5}{H_Ma7CUKp(NxVgTK-@*X zkNOrzrCPa0jEQaH?c!79KF4{RL?<-Q?_ysmy*uPru>V88;5fzPGq|oHAIJ40iG7`| zEb-mJa2jt z`Uhn&HN$c|xzTZ!iXGy1@*KzcKk@iXE1xNv=lu|Gp2x%W^MzT62hHM+sd7k)d(LBF&I_|6WL_GL?@t@*@xi&nd7g&S+NU@NF zjaug$WeH2E+!yy3^~+sO2tO90N)D~?-qX~?iW83bB?k4L&fpp zOtDg2Bc3a6Ca=PMbg>0KQZ~=AfG2G9zr{wNg3@}Pof>0Nwi}tiFVvT zq8&GqXvd4mi_rcg+R?0|;Q!5((T>|lwBy|*+VKGr?f58(c6^dVJDPPC+Hn_UwBsw} zZpZmCiFSOOL_7YHL_5Am?!$EniFQ0dq8$&CXvftlAnI>^HxTvr1&R6_k_w{!N=ek; zS`y>nCKBVod|wCS;F9i;QGb`EfvCS8u)%SV&huL-^5J<6^*1&PWc`t-Kl9u)>aTY; zWYphG67@F#d9(fwlc>M{<9P`6_aE{itb=(zLj7$gQGXxx2T^~G13=W@izMprT@v+Y zo-;%J_2Ybo`kO|g{;J6r&|W0!&&-RczlSKJ{$3?fe}5!Vf9Clw)L$Ozg7xRCiO_a><*|R-sB%AMlqFv4RJ)z&haJ28eisyUy*v_v>ev`Zi^PA*%NwoW6$zPCY z|MCb3dkabQgI3AyB>F>#OsVwK6w~UpH%Cx$BJee!Q=hx2OAcvk&SU z57^uE7QS$X!KhB`hogOS@%Qj`W-$=kh0&0PS5X`d!FK|Njcb@CsC1G;S8663zDAJw znAhZmGf0f=#PpF0#;7R|YYWqk_rAig?M`(%$)Za=-~B-Cg=Q|g7l`e|dM6qQwQt`K z81~((QN?y*w-b$^UHitb`0E0@$lwUIu5;>CHJoMq6@f>|Frakw>_Up+%*^@X$g_}Y zhW>gQN6*IBYT>DEeDF<|JPA%3KgluYAd`PE_K3MGF|w0fk5mX3D)a`%qf}#9vyYS-P*%<*~yybu}R&kwbCpc-UBk@<#yY#XX-LBm1RJH4x>|EVC>c4e+B1#$x;?gA)G}#Xd zE^efy>NYQ=w)NJ~xP1LeyexP{3oiZ5=ep&~+Zs0nV^_D}McV7yu@++qq-Cb*grGLO zlQyijx_K>nwoL+mobmN7YxooQK~pQ*>efJs-LbA6ul`=XzP*wAzF+qk07YysnZ0_Z z;a*zsU>uLZ_|MPSYB5JwddDL+75~3VZyI#M`F_J#wtukYWR9`;OFd7%!3O((8OLKD z{^N7&#YV#3DM&xCbz=^XC6KU<>dY~r*t`6jy+83w$k?7W`b@VL|AYSB0l5|by~FdT z0Rch(GCYT*=!v&jJ>Ng-F(3Zt;rYk%1^xRZ;9r{bnC4Ubr)~PogL{$K?)4APzdZ;E z+WP|bn4aa$z<=gT`2haYo|kS2g}~v7yoZ5*emRCgV0zl(;gy5_1oKTk7_a9Z(qp=_ ztv$aSV3?=Ua;qt16#d*IabP^SB{e)2M4Xa^SY3pYML<>y3~0F3Rz}kiBJra^wZ|EkiB-;n}c|c^WpgK*{hH} zFCFhC1P`wq{Oucj_RB#%_AA=r;gzE~lj%0y=Q1hhv&xSA$xlQ zcvsJ)Wby!}Diu$X*fbO@tE5!8HK$rM+*+o|lf#as>~s92Z(W zzZ@T{9Nv0@_IU8Ohl1s350qm%;;F}c_gH&=Ie1U#A%uH}=g%D>dz)ZyA(U8-6Y<}( z_q^9#T=aCqhT(CYc+pndv7TRgmEeCKDd9Qy+0m?b@?8;Sdw!S=Wp>1NQ74$q$y z=mqV41bZW)!*a~Vf96Yje1|mcdFkHu96}fmuN-r%o?i~?F+FYZ@RH36<(u*M`1r_| z9@BLwU$0+%1Ot6(NQYvGmG2QQ!uUC#_$W1h)!>iY4LiUPaFAq8_M=Ab$<@lxSdFfU|4jx`P zl8_-j`{ke>{h=)$UOE03%C{jV*F-})Jby+(FW9fz1Lar%U9TLa zvgf6Hw~KO|9V!R)=nrl2@XE0!l0>8@~uTY``;4j(cf{h=an}Da`5o_Uxn54%S%0`r!5{{zVi?s%y$?r zNU{;ne9w>`)7@_E`TdW-G1l32-l~wjsj%nG2WJNCT_<~9Iocox53d|ASv|iT?U3mY zZSnBR@f^Z~4Jw>juWh& zUygU7M}KIGhgXhC2n?2^Jy4ED=`r1<)}CLEk6^E}adc+L-ll-Pl>vKvH!*$n%E4!v zf`?a*`>dW{4(cJup)DR>IqnYSds86av!us#f4BDhawJ0@NJBb2fA~)0V7=T6drZ%M zx*GqPFJ->dI9QH61_lnV9N932&we?mM^)P5;gy5$JPzjjNT3`o(qp=%)}CLEkq8`1 zLpr>2Obyw4F;I@Pq3e~SQue%bd?q}2c;#rfdVV>mM^)P5;gzE`l<%HEIohSibk8VX zZ+t96Ab%I!J3My>dJvdtNz)1usIO=au6pR?ja7_2>_6@$m9} zJ(O?5KjZV&dD3ILtTb!eD+iyYt3|kXc>eq;WUn3e@}R_Wd=vk@awN;1m+tB=$}!UF z`Q@M<{h=)$UO9$A4_P~N7>MJhKshde?B%;ARF0cqZ-hx<|9JkChV0!7d(4;R=)ix^ z9^ZA%I``5&-$gktw|ag#UQ{_~i-%W^O`&`r36$d!>CulTm9N(xdtlGAL3^G*4~G1E ztqcG5h5Vx)^Vv*eI6T{XL;k%O@b5C|F3Q-;UHEsd)${$M9`m_| z#&CGH+o2cq@7;iZ*GZ4*9t`>SNf-WoC*Sc1xgKm^ z>e0Wut$Tj^CPOdi-`IeE+XMbhxAy$@9odC{J+HiTcySpxm?saOAMx2QFZGz7ws?5??hEDn zQJ}ofNssB0;5Ti1H1V<3A6?ghM~Bt(%S%0`r!5{{z8gdNu09-}pLa=*=^hT{+ZXl*(2x!<-|vU? zra%v02k{S2@9mJ@0_b5V_=l(Wk@UQJJ{@|V?^LE9|NkpwuNHd4sG!43^C|R#^}G?~ z&4Ui>`4#-99?P4JcJh3H=G4ZcX?4262mw_*Jy(W8a1?)A4?7iIKIBNz$L5F9$F=TJwB-ecZjsES$ zf3KeT8wgA@QR&CyBz`^G!#fzq{~aN{U2v+zQ<4t#u92P>mHJa$hkBg}f!@a}pcm{1 zy{5S4`!w{A`*EIsTcH=hJmlHC?dSNOl_!AAlLzUIamxFkx4ReSF?{|X{?i^znLJ_7 zKW_RM-^)fn@D9%&x-awfkDKs2j}Os+4o?pcuPm=?8(%-ZWkMd0Nz5P)( zLkscX$d~{6-a`jrE;7cXqs7>ompF@9Y?N;9%kHJMTQ)(Ge}_QF2Vlz>;SVIX#Yf zJHMoF2`rz;oJW@IIh?U&dM!Wam*ka@dk#2D_8dsMqTkM!K0bKKZ<_K-+$kBma+|g{ z?K$91npA6jPTE1;!6lYSJ2J~CSAN#fmbAmu=x)LqhB$*q8q2P)P2IQlJEp9rT3F^s z`*ye`*-uAG8JlcUHrH^O$ zt%mEh)Wv{A$cXgV~_dr_h;Q%5QR*S|6oGmp3hJXd%o9wniT1PMQd%~uE?rO>S06uawp4| zSNG{FNzlm)hW~JlJEhmIjy1c_YMskAW1nPQSUc`sXI1OmAFeezYdi4S)7g6qAwl%7bot z9;`C&o`O^^F542_l6l*E2eJldZyQnxZA-Z*2|LqMgU@mYDZt0-y$jI*RcH0*D^UvG1H%I=wJhF9A(v%?$ z+Zz^|F&Hhe>?pBmF74Phe+T?3N?BC0@9^p^$FEAg@wr1^o^s*d+O^K@y9cEH$2mx= zXzW*4;gy= zkhB}UHb~pHYzw`r-uvnk=MOrq;I#ak4wvUWUl83ps^pA<6G~n`)zq(O zQtg3qs zriSYM8v3xlzG2P&rSp>y&50%-Dor_e|6Qws<+!Ni+WjA#6%2`#+_gVe^636aO|SQN zCylC|(zN~0-6K^xl=)e@RLzSO7llVEq@3HS4 zNU2`7W$qn!V(vV)WKH&F&}-ckweqC}3rl9d!*rE@s!hG~@PxDPD&Dc{u99vCyLF>K zQ{HwblyB>`%Q@aX-Wl`Wfux~*ce%&s7A9}aEsWy-@O?XqhrTnqB=f->GZs1yy2&3s z(d`9i?3{y_b>uuW=fMju;Ql8Q#5(=_Z#f zd+=g23i_E`ov~Birmeh3esXwA$0mI0_n;je!{ycFlHm{jS!CagPZ|wcP&YO>& zG6U!MPxCWM#+NcTcjTP6?aY*-Gx>n=(UKG2_WD6Lg+`isqDQ2ZyioASu1IaST06t# z4#E4O2D@9VlszOlAmt3{R^o2)&f-PI?v@?9ib`HY@0nGy34ftGHtC%yO#=o@sZHYe zxyT*w?oA)x?d|BHS?5~-w<`@L=%{|E{_FH3ux*fs=ZuI*@5VW9g2ZNHM`M9== zzQ&-+e%ua4F7t4EtxsyS_wiVWCP$m`7;=<9losuqTL6W=JMbsEkCyUsEBN_^B>WlH ztB#*v!4*+-Y;L>xjLXaD#9o)-b4hZv5hhZ8(Ptc_KB>vM$RpdO*WIRNnMY0MjfLQ@ zL(yC(`X-9s?W73T$`!4`;ib(UTcR zcOaW?%X+@Y&wM9Cw{PT_)>w*0>{e?(|C&0>^Z1j{eXH@OUr$u&unG@w4OUmbv40*3{c}#VZ6_ebwVdy>GXBsg(*-d+hW@Z`D#pA?L z{w!~|hJi!i@F+G?^byo{x2Azp5YX?N=nmy+C8~ie=dZjCZ=!XBQ#FhH;gbca>H;4D~`FhCmzBw-6yT7=YtStMS8$~ zTC)-6M0ibBU?+mXE6+JPT1pg+tDK^9m!xk@Eke@F4VWv^zh$gBkz-Kr=@<0<9Qh!DMSahNkP&$jT`2wHf%y=!BR|79O~0i76%cww?m#Q1ZyMMPp|5c?eX}t=F!Eja zmVRlU|AXng$O<%U`emlAhD9#LSWLg%2qPnfsNVD|j4(E`l4iefcK1e&-Fxc0$H+soNk#E`Ul#USIx%pA+fGgD}MOg@KXFG59lv z+M+wrhf`qXuDl13W>hmL$s3PDz>Zk}si=$8QD*#4 zOlyGWsiTdMw8c$}qNP&DSn&ootqtC%jgG`3>6dBzNSw@UJhO9F+s_rj(;Xirs-%AfVrS$7A$l4Nd(O zgvbXloi(h-?J(*@_#3BL!%as`jJ&75WatRI&1Y$!3C1*EJJ{oN8DOS8&M=u~M>e6a^;l*`Zm-CB z$h60q!@i9)eVzWPk>l8fGS77)wwavF^PGrnq+}=hCycJhkO(vDpB)*^(^}@albpyH zQ@hZ`=dtE(H;qjCAWf{_W4Zy<4BT1b5gf3WcQ1DdAqqxjrE zlD+%@7~wD5WY?R)h}js)vK#Ek%xr6HaIzbXfI<2=I#2eB$a6?zPy5*&S)7~QtsIB$ zF<2b9?kVUKN$w(ymK3)fXYX!qjOTE-4S&14oAEcza+a`7 zhmAzmIZJH^!PmG}I61a`Q&Wd=ZIN?^iOS9%e~y!Lrv02ZzRAh?hW$KoSQ}0jIWa5E z8Fmb%S}QHYG7PTd)J6D+OaHz(=bwulO^?d?W}rvqY&7~ArW@yct2ec>`DSz{=YpQ! zg3t@?2`Tkre4ZP<5$@+)7?}y7?fgk6P=ZZem){XBdMHGZ42a9WSzzotDuU%97b*$ zW|<`SCbUMxiGB~I&8?11f|63yXKiDOXOO^gSD@p%?sC*ml6%f*)PXw#BRAFk9B23* zZZ@o$Ndrxx^4*%_q%(nrXa!%6c0eI}+)hj&QB6%6~ECE|k zrOa{f&*MbcfhNm!tI?Fb+-0bx-fkhXI>x;pntk0{Fi`rr{7ujP?jO*J2Dmw>{(V6x3mbpJhZOlW{p~c*3@UYyy3#DG*4n{5u-LvueRCg@wSGl{;yQ|&rz~>s5 zzmmDcy$0b+-Pci9r@Nbx`x)*>Xvk&mRq*^wcNhBeH(Wl8A9MMurnT-TXw5qJBh>kF z_e11c|Nrs!Ch&DtRonPE_uP9kwMm<)>3oy6>6oD-ZD~u>ByH2CNt&UPz$H!6HjpME zLkH{x6fA>4p#oy11)(C8K}1DCM645&fWWH=DxxTeiXy0>@IBAk>zsS;ZHm7C@Av=C zFDK90Yp=cb+H0>pp5fZ7V6j$v6|B0+{sDTg&GwnlZHs*oY};<dlKYy z*yZ@Y)qWrHJMC9c#x9$`ciC;f4;{|8`7N^^`!$rJ*B*iL_Stjrf4BWMn%N%vUGxZh z?KLRZK6@r4TxgeJ_IHsz9ceGN@5cZA_TNymm)Px~Uur*%5`D@Zjq)C_--foA*&pHh za{Eo_e1&}@-1AENSE#8^+Zjmpk^NiL&PP@ z`(9N40{b$XjbSHbF0v<~O3tuLKv`^a9#v*HL&B1gJK?z2zO=6(0+j;$SHeTGw>h^% z{}FlFJGlCAdLcA>=aAhj?D%}h%f7(O(~gcm4E?e{X+pPHA+#SWd$-e!RLL^;<3c-m zBL0mSmDu3tkOn7DFh1B zIWj~X{u*7*MCpa|9lpMjGbxK5`grFR^bR>wrLQh^9%q_q5}4(5KtxWFq?zk%MXlu& zi?q|7&m!lX5(zADCc-y!O2tMC9cvr{GbPO;=S;HAk`bZ8u~Dv^*^*{CHWCn+lgn{8 zv^P1W?mI=UPL)_=8KRO&ZjB_M&OERaB>a|jNZvrr_ibAAF3$XP6D z);qJ9ahb54>9AUImPp_nr+|TS3A8$opq1oQNMMWeDW<6uX&qMR9B78SaAUxpM>`L{ z7XH_fJ9@}x;ge$Y+%d-JgL`{gtlWs$Y?RD6bMs}!8FBiNCRZ2D4!`T1J6jPAlkI9$0ngK7(D-|AtOhlSz3{i3z5uPJaQyl7F|hJ1i(U+!uzBU z`~i9-w$fIL%Fy&G%0{D33ql8ou+rwp#Xj)Jg=ME*jRuJ$kanB72&OHVD3s*1T5~ZZ z?Yf9iB54nri^W#xWmt09K8IFa_!69R*h~Dqf@JRMCd<`vRt`6F%={{EZ2CF0(se9^ zeLiey+uYc|)Uq`nwKmRKjA-SZkj`BJ`vI2Q=I@%?_G^X0`yLu--eji((F?aic-~ZI zHcfU%xxE~u0$3j5avC>AgF@uY&Psj|;p!Xl&t9Axq9a&~E{WisM0+q7EPo-ltbNjF zqYl#^4JV^*n6=C+WKQoum8X3W9_x|0wP&Rt4ubrA_;io_EU0FEl->!OrhOw^@5OP` z&`SRrij;O=xZNYa0jib$0%|?&OW{wtWb2Hq6wV;7B!T~|WPY?c{Y@w`Vt)7wBuja- zN5Owb%pJtQBc#Smk-j2=%K3Zv1(!KUXSEjbjn6JS%+1ob8AT0(M!U~}mV1795S%B- zZPwre@Y>)Z(fkP9IJYT0hH?A{QzJ6{06bu1ad^I$gjZH_Gcrl%2Mb0<3RW|Y|Ey&0 z_ho+zwVwJ)Ix}EbV{+ndgXS~``Q_XezSfJAE72nPG88wP&oYl%FD3XonHXjMu>!30 zPUtjxW|-|utQ3^dPnugYd(!lcaK)Uyf;Y(^FapWy9sRNg!oe26gcB7RYF){Z%i@C^Zjp*|$k4Kx54Qf+YA?EWy8F#OynV(gvAm6{^w-xcrzoVy7ZfV~uR~)QDx> zA7}t|0yi1$`va4i$yj;g@&3Rf##pi?JNu~#nA`@w?6F=Rm?^AhgJNGESWJVB%}C7Y&5Rqmb(GI2gCI8Ke@n zc6JC*%NoU<{XKykN}P`HWYVbk-hfPMOV%Kx ze#sF!Bgc!GBjxu8BCLl`;k+1USuL#DA1I=lx8XdBGlllqZuIyL!r#I8;9ceodY?nw$V}zYfW)h6+%Sh z1^n9(7|Q%dBhlG`ELt}*3t~1Ja)duN(xTVbqOr8<^+6&6uVrsG0aO7kWN!^* z(?qcUPm%XX=wey7!dvXa|HNQY+6K}Ds{1R@U&1N29&L-Qv%vikX_Pd^7F+KEZ41s6 z)>y=rsp$&{KZ`RzEuTvRnI||0kMBz1FB?y=WirDL!0w8F-~qUw67z~ANNU_589cA_5#9OKBs&Lk2=#HOI-$|ejJ=BQ{ixD z+Zl8Q-ikeqG``7tww*`XE`+;DE5-N|#Ts-H_fi{1@O% zDHvy2KR2}75atI5QZ7e+zc92+R9!00l&28!zR8a-ZI_ZZ1D%=`kosyyxC!U<+d;~Y zAd)|~zSWk-aWx{Yz!_PI=G0|qWB9o4jyb5ob$VgV=)qMn(l;~xM)cFW3@`oX7N)-o z1=yqM_qpk>@zQ@ESL}=~M*2~GTf436Y-y1XA???3TGJoJzruV-=L@CBjHDkU<_VlB zf5rfN%pS(7{4K(-;++080gQ&ID6Xe|H&L2D+UzoYstu@Cqcb zMj@L~{805nhGQIJ$Kp((*&jAEz79W=smAPwU(*`a^uOZY8wD_811|CcqhwKd@b`Q2 zuSB(v3S@Da>KuG>S4t`jG&zvVfqxZbEW??<3|(?jAfFQh=itk`@*hOkdU{|q=N8Vv zD|gSJdyj|Q*PxtakP2jp=itM;umi#^6pG-|W2knmKlb?1rP)! zBo|>A1%@-gaHgBb%e(Mg1&HH7+#a8bQ40{oIoOph|CPI~B#ykCuia~it{OCwt4JeQ zSe9qqbSIgEGgfAblDcXlLo4HgQq(A{Y+Ez&e}bJ?F%CWEAyC^;Ni8_T2M{S`l7E0}7;q6kf{}#|Qs=$RmEU}j0f1#asgrZwO+674$Q1n^^4&dTa ziY8ZP7bqecr5R9kJLnl-D}jx0VOx#(zr-H)Pl|p9)axMWAVr@*;0P{0PtoMcd>IrG zeLX@aYi%?Cj7z|DGcFv98I{|44dWr~2&i{L&>fU~9Rl3^eSnh5m3fyd`8I?GkX#OO zMjlFb92btfeNtiP-c89fK;>f<-=^e31fIgh6O_Dzk{7w=xPM^Di$Tu#9kTx>E*zO| zRNBLnCP0{tq`YhTA|<~Imfzsw*OdGz@MaEnB|nPL06Ld}oN*VJPT<0kw-1-wp}CZN z0@Oc4&>wMzA4K5axcC64mGK(-#M^8*g!N?vKW&e>jtTgUq-693VV>`RB^wu+IERue zbFgc^<4Ae3DuLvQ6ir?32~ZbKBA&NHCtO{|Legl8rY=)(F$t%YQ46sgmu>5H1Yfd; zk0}IC2dHxq&zV*@ia-S}mf##puFRdTF8oQolXc+_>{?0exH*@e0fBV=e$X(cTb$f4 z_0ia{xEN?wnluqkTdX8H8z+;yOcaS|J|by3qPWyJ7>lx!>OkcBJ z4&_2xxDwRWh+c*>%pYnyh>K6*wCb1u%2{@b9hxy2&4#>7$YUi{;2-xPxDmzbF~h-J zE2&x|TH_)XTT@tqr;3C-#Vf0n6cxqZtFWN}^9xz+gH=ABU?2V-#7Obpn8@ONCk4L} zg;R?67K`^TLVv_*73NIB%qW-JN<6SOMBN3koRs9R&SmlmpyuP0&Z;S^!_P}sc)-G!5H z-pS$@{zH$j#QTxQ;BjV9*7nDHv0~br^O?t!NXm~66!2lAn`g1U-azoTI32hgjwyNUD_|azagN2Ah0kkS`%2hLG$FWJNX>Vy6B?D0@IP2+~GeEE{^g5P(b@K6PP&^0J zIz-pt9Lk8?d{CMZ;!}WVdDZyGcJvOoy_Pox_6vypyr$*9Fi}O5Y%4d*w6>(PRZJ#C zd1BCCn&>H85IvCHc;~7Uaq_)7`!E#|yLC$aAApMcaTaj@qjNTk`$YtAA!!9ktGJi* z1cKkgDR%3j-Ts8on>Yu}M~ZdmVB)F^DzSGo{xNQDz;5sb&j|!}TXY|kan>D3Uc@)L zxv3+c^Ro|kV*(;7Mx|=`UN?JWQ86l2TZ|w-VEqN%Yvd?0(r0Cn)54@YKuSBmRPED-Bf=>4K51Ea+MQolWI|5aV)Pz zfm%1O#hPj=hsR@d8BX`5_YE8?XOc;x-m!Y7mnCwcnpipo0x!;bCckvidcf18r%ejHNkH%upD9nE^bVMLuIi9hw9t}*J}cHOzW6{ z3oVmi-HKR(b?e;(8#KYMQKot(;C$C4sIQ78s9)zMXfz2LdQoWSylm%L@K1Uftyet9DsXLvUPXW-&A1};Zn zBQE&8gYXRqT!@R^IOlOXFqiV=KitW>K9I6uI@mZbxE?Hrn1=I%TX1m%r!|j?EX9TS z&pE*5fx&-8wJ3< z*h<=mSl)j+9v3SMZ6_6_N@C%7-|F!=1~>Uli2Vy%^Dkqu)}W&x{+vym^J8cSCD6}E zX$HYHywU`AAf^;C?D-=agDLc&xyl{KY0c#b#)BP_eYlNY#^GxcY&ssNj9ittD8p&Z zy%@bHj}tiU!(2FouL5Z!BG1Md{u}~V;$j!h++zs*8W+F9IsYpN%>Oq2Wl#nvlzt{C2;`2$W7Q!o^+jdLiu=2KQKW$+=A^Ks@<*6p~s0cX>b2+$mzIR7~tvCo3= zbHw})Szkfm&$##l1HVVW$;2Ku1Ajwc7y?;1b1lq^rs85E1A`D)h>O!1$U|T`E|%hy zos0@D(JtIC>-m|)1N%EDG=u8$6L zg{^P&9cFjoMENq2g#o@i~RZa=^+YIPVCjjgbz+TFNDQ{XaJ1{ z87WW=Ov!!?(u?gghP&w|4qq^wIc1Etr)SmM4=xEc4O^FQuMe$FBN?w2Ey_lq=nDq|ri5Glt{N2Oa?2i&SHwHfu(BQG0O) z#!@pb%yJe;f`oF8lfrBLqAyCQ5mfjD<pGhI!`a2VnmEVU!oicW9MqIrc=6S>(?#KRj``Kf_|b zcff_9aETE}SIZw9&s{2IN$|qy^atiRBh990Ud|Nv&QEf!JB!LxiBHdt7az&DnP3j9 zMN4#=TOyduSD?AYa8bYR^E{s=)#tVI=}+jw{gr`70i~$hkAQWu1YB zfSIprEAb0vZv6HPmp+_Ufej6LF@M#&Oe!hCC`;I&v2=932$>A_{JmnRJs~{{K0Y$N zY1mMkFEUlC+hc0B6pbF$u&fYW&+=gjzF%eA#*8cS(Kt%Lw{n=<8l=Tm&$5tX@6c9j1Cbmt*FH02)X*wBUIv8}pb@}yL6VR^)j zmpjN{$g~@RnZsg>s$gCLCi5$vr0hm>A)8U&|Jvzvm`ZcRxLPnF`1FboBqF(3s4Z##Bl@IB}G5a9XH zdm-n7iX*}ILjMdo-MIK?==rcvo)7;m4358r{~nfzzlZlHOT^2`@5==X{{JQ;7KM+* zxFxte#lbB<%{+_=gd1_K4Rbv2{KB!DOtmbC#f9v81R#jBDmBGVlbwUt>=Lp>t&yl{ zu+p@99OvMnUBP>t2OR_-be;t3prcVDe^>C=f%lSl z5o7)4Nvw~9^}w#+^MT)k^#ECuIlTwSi`>`{pg!l1z^&cUO*f>Rdb`eFMK8?qj;AG3w{ znEj+}H!u-%!x84IutChAx~;i|M}ol{ZF_z2H}>mH^}79f5TX6yYr^(=bQzX|T}(;m z>9Qf1dK;bUHv2x?UK6~}ewm?b1N-1&!AFD71zED7^fe~o6v^%|nGf5ylKEEq4jaw< z4*Pi$uL`^u06ZA{VbG@cXnwOK8QvucW<8FQ+_)=vY2Z5SDh00#d>_WW(Ns$KK4Dt~ z-S4r#k0Q9q9})Uudo2`wEoYe30o1|b-Ok3Nbsor9oxPBj{UTqf_x6y z67{tGk{9)o{gyxKsB_$LQyq66bz-U1=HXwV6Vp1r$XEa$t7*c-KXxcja(cg&*=yxy zo2^Q;n4BSKk>NO6&ZJDCq5XwpoRiLl6=>UmBJZ#tq;*hSIl^y?MtGGbSlDB)3tnr( z4I1GK_dE8w7#E-330m1~dfC-5V$U{SZo86}bVX5Kc$P3m0@IHKBgGK3u9cUqTX4DM zN}Gwk7I-XRH=4}(WWTnD2%XeWFN#se2vvH1J~tA?s;DU#9%Qc;lZ9^*<+D-T=j`9B zcUxgTrol0*F8B-kLvaOacCAp8;bF-`*a@Q1d9 zoC)U+TI>X!I(tKK+cmbm0Ru@gS45d8D)KPbC~nYBW^X)*WJj+-1~<=T+h9i=L_T!ZYG4k$Hzs0tMvS@bfNnCONERxeVeK zA_iW3-vbdtv`BIdejfe_#HfU!*3XcNW}cb{C&(Ka>^{2pNN}WZyFSVw|`GJ@U2jDjF;Y+}rsV8Rm$2YKp`tAk&-$InNDV& zBIU`E|92^UsncPC^dY`{gG2H_%8PT%1grd4X?%Hz`h$FV_^onsq%WmZuU|XHxyH_b z17t`fyb||rOzo+$KQ`q^l+ZLLx88kXM?$RE(h|iEoKm!M)mjSSOIzWRt($SRd5f>y z!7UhNgjuy5gS^JzgCz0o)GJ{H9-62S0pZc;p z|9H!9irn%$60C3J#KdUMo;rxvEwZ z;P4r++l<+`nmxy7Hzsh+I}efb79~b{(YeqocZ|=X!7=lYtvS@{b70mv^Eit(g3PVI zIQJPi7fnACD$JaFvI;&ehd_-X*?u*$bJNc^lar}x)Z7Ahy5dp_W+tjy3RO#IQdN`T z0IHr!8&x(8Wy2{@Cq>2szr(|5gP^kx$H_1~Rv5-VeMK1s0i%|}XO^zO)r#Yof*EV# zzveLl;zumS6lduMTx|eLY_6y*<4}-sOEE!MdKRwE0*g#nMUuzTK$gbf(&d<`E(c58 zc)2ui&$hF!-OYwg>1f0N=$nL%B*p>o|!$b2(gQ96? z!cu46DC{~aV+Km21&?EO;dj0J?1xEy*#0&qcENAkCJ%QghZ*Sw@Dmwh`8GeSc9CC? z-~syqf0(NH4oy;xJgQAPSD^zomM)E0x*UyD=%}mby;SI46&_Q_$o8+%$HQ~>*@w8~ zxzWZFD&{=OTL28=4g0!aN;iCU+kQ&kZ(q&@!{zp;8M=z;>w<^un_L$T7fUKx=Pqz- z+${2ClC%c-aNZH-T3_efi*<@0J|{*SC4LCL4xxz)6v`|=c?T$%dEmb~i_Bju5SAG! zd`Pb0LzwL{8+W2A*M@u!$nGRqt__))xn#Kp8BO3Q$Qb>s2Y{G?;@||)9HSH`DRQ5Q z$8iJlC;>0oxOi+Z;QhMbxf*um&{ud2G9XXf@G?`wE~aYO#X=49#Sb1Q49Nf2VR3iA zEo3&Dg2BRRR*1qd&katR6r6wEk1aEEI1@Hm|kzQa0H65LMUEIGlSVE2)n=d;%`z)*x2W&1j9i*=7A>w zaMMEmPm=%1^8dKJPjBT(V6Ob%ApaN1|8wQPNj5~T`MYzjpiH?o|5N4K{4bR2TT=v1 z*w&NShjpw=FuM%cAEXcF@{+9$r;Vo(N;=v%c5K_+QL??gb#q%^ZwViwD=um8Z0YE4 zZ5t@Iq_~)WEnPkMh4ufEkqNf8_qGr>b#?X;TYH+fyL78$OV`%6lID*768xNd=ce|} zCFNbnzNxpZr(|TD}&Yu?!IDY~_}Wea~n{{LN$y*qpVf5{CsSF*XKC83Sndbr+1zlA$Hbz&eLFkaqMO?~i??v(0JXWNtr-DyPtn%4P0jrsebK(1 z-EF;~p(8|sR(w|!0W@J;g9X=^qadZrhPJNKyL;NVHTSiF!^mciEgj9hz0p_<#v^c3 zZ?NIvDXP%fz7+u@hcVHu&AsRO(qK#h8#)Ic4fk!Bw5O+eC(>ecQmN66{ZtXprh(AX z)zQ_15K4zo`&P8!Xlrka7r(K+wH*PIv)IN9wQXyYa{DCrw6)L@7_i*DM50GRadB;m z4rOs|l%yHDyJ*n_vv?G*(4d&YvRZtl&5%4PNG%tWP_1SxPtz~0&^B_kkZ(p+|o!f(&p3H zS&26JrOTR)*z{1^_)rq9Sqc@Q{L0Yau}sQhki11KgXr+OkX@2s-uGZ@RIqJlGvC3X z>_S-M0%YxEM?%?74+YRl&Nm!8lr=RpVtOdUd1_ZAlq+1wg|=mG8R6Ve-W0ve3FS?b zl&ENu;6lUX3OYJ>LX@uxlx0X(mh=2B8?NEpMF!`EU39jUQ0t6PXli`5|4A*7ogKnG z{*XO6lr#bP)EEn_z~xG*#Zb6fOTTEK((jYfqwv|{U-rn*=n0|HMWNADzBE)SDwjY) zR;ZLVT?l2I?eJnJB@!CP`eY?7LfM_?pi#DS?_Ls0VWY>XVK%Ch_DPbe|1!J+4hnJb zzcIpRe6}Q<6$#~yrHh6_rJ^t$IV+TRx}i-+zKAM9{YB!O=4LHGRyK4%hOuUVI%D_@ ztZe+v>8@CUT$3Py0rxkI8)k5M!{squT@&k69s7GU*tOK;{Nn{VN2+a@_=PUS6 zQXY4uWQ9shGGtW}z*n?=oxrm$Q?@YScIW_1KZ`NZ77*gZ33>HD#J>@Xr>~w}9GXjo zv^bH_a)g}X(Aj{{0{)BOU-F8OjaQoDGWwi!ny9j&q1=_yirL@L9MeN1Mx#;+ve;js zrx@nky$9x&=(C**B9T1&14Dk;h9MmkTbSAou}+#&__65*(1% z?Qta$eHX$-6qp15$dWE)TozpgY89igI4PS#Ls8hl;r>tvJvKy9@N0XR(GchJc0|L) zZWzMGiBiAtloFkeDeFsnif5Uwp~UEQR15K%#~&$nI&CMDmQkM1DbF)L9+<+%agTDm z;Nw8PdCuJuF~a$Y*g_2lFAq9sj$aV&ES4ec6hlKdg%iqhjv4EPvS26{A?(nDOm8G3 zR44-#Y|jYgjiLoLW})IDX{N%lA~cAMW@MWUYZfgC&0i3jo*x=z+Vm*ULgB*DNWqmv zR@@n(A|X^~qxq(wiyVn2Uqn&Pwg|cq^f4SOGcX(^JE@USQ)y`ANTeI*_7I^uBp5n2 zRF{wcE5KZk6RH6>NHrvd=B^5jiiGAy_&+6#fK+@qFO-aoF=ntgsxdN5f|T%voKUq9 zQ7s}?tqQHp53L%@|07O^-#Hfs;C^DSEB4S`Mmz7Y<%ko5Uf^80XN7pp-=vgUCEyJe zm=1-*^-49P+uN09;edWwp%KPr8R3l3sBxi;X|ziU}_)s%-?LT78{ z73^nFMNUQ}v>KPN@@m?81#@-MBcW9wjsQgPe;r;J$MSpN3@xus(e9)oaB2pu|F_~3AXj0Hp0 zWrxCrhJ|xRqn)Ga>%a4c5#p~*!kSvbyEGmwb*{O`fu8ciOt|}_UO=941g5ANJ`0$)MiH-h+Q!# zRa-)jF~fp0su-hgD5ug-{+5u-6hgpoUlC=XTYCt$?Hay`xnZyjngdzd~gTw1F$C@w~7bT%W zA(Vt*UkOh%7-rkZ6T6KXAIe&c=D35T8EpH&5_EStq5P?GN$Y}?#V!yR3pF>+<*4q$ z(5$e%Ff@KFuJd^v8c+8slsr?y(?jE#Y(r@LG$by-{8!V@mX2=p!qCVfs+JW>S(U}v z%qY%gN@mbcaj_oF2=gpvJ5C62?HuqsRV%b`3qvf_(6BRf!N8h0ST?XvWmaR|tf)l7 z$p0jLJ1aYf-M|Gfds-nKkn=j)js^-jsc62YLs=*dDU?(i%H<@jK>Yx14vMpv9mlzB zB$QqvZvNd}96g3P4`Xh?rc7@_Un?!+5zJ>z#~8t&7%B9P?%=^QF6=*tIp2-3Ii1B$ zW+Wm5q%=WkRN#F`dGCwyQe+&@)5`NzkB5zQsPlwl<_lll6~~Szd0<@`w>E3lmB?ak zNO1(K09XXQ4TjTaY^iEUB%psH~4RR8>?)YiesMEtJIU2jIg!8@oE9+!?f@(SGc9%vDjF zd%F6&aoyh8+TMaai5<}`7B>8%l-?U{#%4%sEK6)VM7K0|wsy4j^fLVtYzQ)AW2dFn zO%2PVYs;z{qf4u5sv4G4e_6RlJKB4(<>Jd^J8ae6)(pErBdT6jA6-=oy&KlAT227M4M`=Yf%EPN{ls@)mK$S>uc9W z%c`rE)vy>+RkRTN6!vKAYwNMPdfKt=)ZEwJ)fw|p>^pHEi)lCnqm5+^E2Cu< z6@HUzg)OOVME%E1<>g(`P#!I-uP<94i)*Z02cN91X{0e&@=YDhn_;C`X7razUjonW z4J#|xM%SG(W<4dc4rt4**ipAO^)$C&7ZF>Ky>4!%4Qy=gZ5v3=+Nz31X)02w8`~~u zZ|j*U?&Gx>={~qyCY33j4zk;Z-F#%?6{5bfhRwgevaG^a_Ufvd%BaZ$oUYHWQxba< z8l<rYT>>^U)R=HiK;8h)>M+k^q;1~>w!6YdQB(mbCtSU^aHKUea+F{_6yq3 z)%4Arfx^fxYiC;<`!UZ_W!1jUrJ}ZJ36w6ct|~{@5v!rvx-tgh`h)dNG$FeoC}paZ z72nd|(*u`Ar`dy`wY6<)OZQIt_U0aZIu1f=m#l~`tu9*@ZKx@$t1Cl(r26}7b!WG% z>}kb6O-)p-DqB{Gnl;K$Gt=JP+LIk`;rBXHcQl&9Z1+ePsi>R1~hRvP|si zc4=l{6)$I+xQeJ>wq)+yxg?vi_*$sAm^-X_4Aqr2%h1eP+j@OwMen_=-gLyZ^>NCg zo2#v^b}P!{QCDAE7cHw6P3q^vt;h>Yd881pe@u?n6V!neN|%>TD+%ZeJvW>dQ4foaZURIY1XbhC}1WvGV~#_ zsW0jEy^+YXr_7ABK(P@J-*}AjV{m4Kh>dT|-D*8KdOSiMFHG+G$JxnACblwQtQQ5AZR_M~(-r6R{ zY~~%^C~h2Wvo^N(ZEfy0cdPhvJyi92hVtc=Oqp5VJ%%4H@sX-G98DOlr>aF*&oz5R!b$K^N6;s!zcLdt)zh%NtOB!8 zqYu|KW)RUbyRF!a-zZXVOOGz<+zGSPPkbNK-q|kZH5y`tQa8|~K`MV4rodF(YbU0` zM=Pt#8XBvlV>VK%Ftd`DU)dNdsBcyfBTDHjF#gL}AnL^i1X0b5c->a-mgd&3?U>NP zKUyu!Ok%xHT(zt-L+D&2Xh*Hfq{;KV*o=;z-dI&Dlli#xs8-8#;%4dC(bl<{E79f- z=_8Df)Kp+0*JzY>hjmjI%+K^arhRc1<#u6oGk1*&l|)nn9JjpDKT^r;w4#hlPIm_F z_PHhtuQcxXNAK}^ZT4kx4nZrjO&G7I>1D{kV8#Io0~-~Ht5%u1M5}8tBZ63IJV>R( zYgtWsrOYzptX6e$-&b{V-&Zw@`NSvmO?K!;(Irh)7%ng^L<3h5fyb!I}WV>uingKzrr*36E(tYbJ~t7)@s0K=5WP<+U}kAA-s-eU@}YapKUJF`+CICou)| zO${+|tP?-B2%GlV^?C@S}Z7*QQO}YS`iSF&f^9#Yk&= zKZc^--u^b(En-7dzd=@>LYPuV(U`D2?&|JEd+*2QkG4T+eR0DgW8(YalZ@C@v$Cdk zt@KTv_10FFt&Eiqn{U1au;yhJn|Nxcy<3J|%UG40RLs=3uA`r#0MY{?t0k_sW(a9P z7u(k+eTG`dv>(s9{>ikNh-#e=$X5yLpi;3V6vblJGcsBsdKb=3y}nB~OX9aFr8nZ9 zSE9ummvc+TG{R+@O{_gGlyo8odA>0TT~1?VeGRtf@T8G(C9g^7 zIJc^H6?&njRhAi(IG6TJ;?|SZiQOQQee?es?uSaBX?&1-WZu4<(N)$L^_8oewCTn* z0$EpaS*Z0KKf8}@F1R{iMcafftlGj%ax2&G(%Hze&A3RsdJRoWxcrp~l{^>O+0tf` zxLd#$KAIloW&<`IW1AGFFw$3IvS@}{F03oDsf`IdJguvzFXAl|z>DcXY{h{6KeiQY{ZJ>^mi`g10J|!w zOy3T)S96K(Aze560M6YKM{1Lv zz^s#H^WIY)t39-IdV_akp%+u9Hg>LpzGVOgCesx+R#p2aK%8=$2=?4&BUiW6jfH%> z)mrJY=68LHMn{ItNmL0Y{R5Pc{YOJx*~yc@vTC%pw$}E(W{l?8&M?amoj90& zlw&>W4t^ z2(vJ&qpNdsgssT89Oj%B1~;{Yr>W`B?zV#N!N*+N+)2@!DA2;xUR6y)rP+DZVxw7X zjq17#;>>DIhD=>{YZLHxSg3)-C)~*Kvd~F`+1>a1+N!d3?kxx~d$yE$k-GsPT5*El zt@FTYRL}((+jS?Z*|d5Y1kFy1d4ARyh(oHccafD3cIPqZ&b-{p6dtM0QPi^|aBu7}b?a8)GewE!y30clVTyt=v&TZ%i7i%FKo~ zHRFWaTudbBRHL%qEcRoQ8nbsKdqH$SsWsUQ;vE`edE;;H^2Ur&h9={$w*$_BfEDh) zqtnvwcgtAW5^h0wotl4B+p~`PO9NEEz=FO*2XF5lkvD`_H_D!7Tsy5!t9$W8g+fmd!58+J+ceZtP7H#UD zK8N9suI9cXY>h3%PFgDneOvmsZUi>>v}{?3*CDo@R@6LoYxmUNww9^BgqtHpwY`xd zJX^kSb7%jI9g(6!UMcHl>l>ZX}**R*WgOS+cCm zS0Aj|7*ni=gJIydAWj0>KF}%sQ6Ns)u25FroikaFvIRh~!ml4iLF)K8d(CFTPx#2+DcCnJL z*U6mDWpHCb-Y&oFXg5-Q4?dW#(Kol1T6Bwxi36U*z+Ld3c1-eI zb8*Y8zk|abXWF8@^i$j2Cr!NOkPF59@c<2nvu`k6Olnsm#3!tl%dm; zDR;H7!+>7ixS_i*VVKp!*~^=|9?d;l%z{Dg7Q~zA=Zz0*t#@2!&V7eaOeafw+1b#E zjOh#MYvLlZSDdK5xl4e3RH`al_24kp^s1F>3>wZ%Bz(=2{ZH)fHG2$iXfU>4hOQpl zw@dM05^e{|-jBK(nZ>K*85t2T^%B4H-lvaG@%H}~ZfZk0BUzt#FpUmWnTPWZZF6T| zI|h(uc?5&G(0`>v!WJiXsc8y|(K4DfqG?rPC4U3<-JOLo3=`GBlPrb}kA9&E^B$n2 zjV(uZ@CI+|xtI_|wTExsga=^UX6;r9M<=73JVYi!%x=1MiuXrLjI$QY4z}B0lICrx znx0TZ$pT@Ah!*2w?$4qpZWm)|g?kfbt>m82jY4!b2^wTcGG7ns>$=BX-Y2#&%{F2oVGMo!MObT-q$J_>7QQT(OC>!AMCG zeFS^qRU7aa6}-ePg1-xe=}d!?F$G;FjTuvtw^78X@>G`?2Qv)!5k;iR$h`sK?<-=i>VJ^N zbVBW&o4R5*{<#<7t{}Z7)Bxqy85QeaXHF=%DXKiJ#TH~d!zAW<)mzsYMORkJsBGfh z`3mKFmX=)>Zltc%8|=O3VIN-Z&FfAi)kVg}wM(KcF-Q84xrrFMddVcHPW9Q?Ey?R%LLOgduejH8XJ5?plz=v+j%jZWXmGx|m zaE;sOzOHXpy7g@x(<76X;9c3)2;bbt@^{9p$&(Y8!R9L%AK}1*{kzf!4fejK!FOu; z#f-A__i!U4P;4dq`b>R>5 z+8<8j=SM*N@rhx)ARQN<7%oKoG@R~nYmj=6-=A_x@})_i3Lgkv7QEcK0wr9Mejph5 zS8DqBC25OYX5a~&OVT6z!>PWTlV=aNN7$q6F~I_RygkLP;3qNS z4?iVn{pBNnEM9)}2k~;dywdH_9KP=EI~;z51YxG4tpf-XV+Rc6I~?;3B9G$W{rIt7 zh!^s850B#DHU4;cDOLeunIC;Tz}NhJhr`$6eTReEjF<1PeSSYAJwblD_&VjY9R>JC zzVC4K_a9u6V+~D^kKbnS9gdZiAV15hKs@Ci#~DC8^}7wHIq*>v-{Dv}z7X}zO~@}d zAwDl5zdYfOwQ+xoq`VOc=|?8W$1ex?4hO$95nmtp$pPQtB&2q%NCG9|<7WN^3Gxc$ z*OO=;_9+3W?N|~guGe7t2?_Ei#F%mA;Mc9<^_`dyKRF>hB|+Ylg!pL*^8CF4^D9o^ zFG-MxAC>SO4t^9oUcc$SSjwB35T2DFZ&pJ5oCJCN=uhl$yl*oZnq$pNkT);Jj4Q`F zJwe{-3GoXO!V44RElh|%BSGF73Gs^)!et5a$`azs6XcaA#Iv=<4#%oYkXIRt#Fb+$ zOOUrLA%1y6xGF(jRYLsA1bHhH;;R$Fs}kg`N{FvbkXM@!UzZSGogmNsn4w|A&z~g7 zlh0LqG93BMTQ3OvG$qK3ea(+tjHN5yQ_OvwLC3tu;v{7(P_h-dmoahl^y_d?LI&Q1tN6Y`5D#5X5| zHzx3JOo(qy2yaRVZ%zoeCxp*S2yaaYcO`_+PY8D>gnO;aeH6~8KARA}FCqL`LiooC z;a?_%-$@ALRcr5Heq$5DvlGJnVzqmapTCPv5=XL3{NI!izb7GlNWd%e3a;lifx>XBwI4KPPC| z@SkBV&@ktonO3>AIxf7-+N5F5t1_*X*0#8Ct@UXQb1s^R_WK2d-Ge&Zmk@q3A^gjP z@Lv+bcn{V)C@(u9JTW0WFCko;5N=NhZ%+vCNeEw&5I&j^ekdXQR6_VS3E{scgv|%? zO%Yi>{;;}xFg!aUygVTsO$h6jhuIb68a}oyVU6#z#(U51$a>SeW$5mdkm_C!v|WmY zs%#AS9`QGu=<-CN#+t2PcTH>d-Ed37yiZ{6XGUAPyYbbhQs%||uK1TqL^pRk%v%_5 z^S!u0-Q0z;n~|rlZ1{S~yfW(37YW;Id`{Fa!Q0RAh;s7{q4*sUiaF^CKybzAazhY7 z*PiBaG8N=0>snxd`-9~1Z(I42dT)MFDe}nm}$UltBR3zqD znR+$G8erfW6F+5)LGqO{9=~qIW6F4gq%X#0>b3ZlDaAFwF$eJv#}s#I2R^QXy!0g! zZ85#11HY6P*or96PVUkQe4J}|ba#maI`#JGoG|bJoyU}NgI<`K@o?kasl6MnH_=|a zI~8{0&rFDKj)jwPnR*027(qOWZw3=@F?(#Rml+HLsbcD_mh3^Ke!;S;8NN;H@$>lk zXyrSqc#q=4ihm-4e-P$8OrK3enA=RLH{)kf6?Z9Ksdxtw`M*!Rou4TNB7FrB>DDOj zQ+$+o%(6IlN&O;zd6#Ui>yT5pr6I;J=XwJ|0sx8D#xQecZ?S z8REaJ^?~}C#PI#<&tEY=OUrUKk`COc*sb^|knI5~Sz{i6{=_Z#hhs{oLDydbUp4JK zFje=i(75QI0SJ?J)vxrO_(?_5_Za<%>^F$?o4_voQXmlvCpIC{OBGL3T%=g8SgUxJ zBFn*aEC&%;3&J#l2Nc;~FdnWa2-6CFQ}O$X&nf;w@h!#o73q(Zlc_jdaf0F;#d5_u z#j_O8Rot$)U-6*g&5Cy^epB&Bia%BSo#K0n{30gx;+lXsUa?e>YXQ=iD>f>&DfTGt zRlHL1vx>(QzoN)?LwQdrzNGku;y)CV;Q!cA=;;V|UEB;+^DB2hK#wbozWV2f9#ylDvd+^)D=@nXfx6t7nNjN)O%uPQ#I_#MR`C_bh56UCPl z-%M4E!wL2*p{7OBB~AwkYmV{Ji216<<*Nlj7eL-&f>qGv>pe`Xmlg%v8)% z9HTg1af)K8;vB^Vic1uiE7mABDsE6bM{$#4hhmT74#ho+`xP%&yhibQ#lwoXD&C=Z zkKzN0-&A~5@%xHTDn6(9Q^j8>{zmal#kUpTQ~Z}=Aj8-bKdWv0R54p|gknUoP;r{# z48^&MixevqS18sgu2DQwaiiiE#ZJXO#S0YoDPF30rQ)@UH!9w&c$?y#iuWmgP4QvH z#}t34__X5liZ3btO7V5Yw-o=X_z%So6@x>JJyR8jDCR1TQY=uMq*$ytOL4y9V#TG3 z)r$3s>lDvcY*jp0v0HJQ;x5ID6b~p~rFcm3CdIEPenauwir-UwLh)I}|51EJ@ioOa z6#uOFuHpxZ_E2NDB*npsS&G9I$0|-xoT@lo@ifJSisgz`inWSOil0zyR@|((Rk2rb zr{Z44OBAnAJg9hs;^!5=p!g-ldlkQ`_>kgv6n~)jl;Temf2R0L#osFaLGdq&e^>ms zqJxDa`^^-^486BUaTXDZH9JVUWkv08DB;<<|36)#adqr-6`xUjMe$9=zbgiFj6OpZ$0*KKT&B22u}5*Q;+2ZG zDL$$AoZ`VHPpMJw6vg3+qZNx3rz_4O?!i8jhAS0UD7{I;>lM#ddb@_VD)uOSw}vlN zyj1B2HT)UHo0NXLhQFkEkJ7)P;cqEEru3&Y{H)@ON`FF;XzpNbzUJ!P!1 z(_qC+;vUNyt>JvdLZwgF@NC8TO0U##m12$3*K7DJ#f?huQM^d;(;9zJ@p`4-qT$;W z?^OC%HT(_5N0j~}4L_y$oYG&>@T-ci6L(qGpEdq{rGKdCM2sCWh-e3SiUo=#8b6;1 zKU<_&uJl?W(yde6sCWSp{CgDl6QReaiLm>PN91(`RmI;Cq1Q(mcJdL1KFLJnpQYhpild3(pGZW0r9|*8R;*L}1QBwgimgiTQ`}F4 zoP!#^MZ@1!{EcF`!0=5}T&{SQ;ts`6E8eI0oZ_Dp|3-wq!Er{fWW}M1If^5Q;G0B* zepQOKN{MEctl?^OCXiAev5;tv#`P<)1n^uHh?{fCOd@rIsF zMEX3%e8mZhya&njbBRd5PVsD|cM_4lNAZ)2dlmN+k^WjD(%-N6pwfRxMEWNcUr_v+ z;xC9u{}vJH2Td@TNd&!si1dYuC5kf@7ZQ=KoCy8~rLR>yN3m70od~||M5Mb>@n)sp zLqvY}D?X(7ZN(oEk?zMt$oZwxUsHTb@omL-iQsbzO}ep)GZmL9ZdBZ@c&*|W6(3Uk zvEplre^(qd(a0}WJWX-2VwK|Aiu)7~Dc+&@u;MQif2Wu}3G&fyvxy6r)6>->G;b5ps_ZCtKD%8h(%nxeqHoq4;CPR}^1We3OXuZxdl}-tc4k zpyFV~p^77k;G0RrS*_Tn_$eavI!J7`tUHO2caP%3ijOLOp9ubEh-X^X8%qD9;s=T! zDTbyP{u0G`#CprBCnBFUimi%U6g!E?X9sZ=^i%q06u+SOMa8>`;Qu;tIrLNd^NPP# zd|mM^BKY4Umg5(6rvjl*mSVo*1jVUD@Rt%7q5o6*D#dz@KU2f!D0V9LC~hYr{nbRs zJ4BpkS$AvvmleOJ@sDcwgyM6GFDm|=i1hCeA@3i=Sy(Sl1EM@RisKdWOS(coP4RTa zD#cZb^+d?~godMvtxDgj;qw(QAR^y=MEKh^N183#dkISBMm#n zMvr77(q(EmS8=@JB*h{k*;fgaAS17hBep2x>ipLedq4**ZYw0(L zDBm9y-&1^F(V1@IlN5(2W-E?X%vYR3gxpfa3Z*YsT&>uoh*toGzfEzc(swIfs(88L zb&5AA9#y0{!@{C1LbBBq4zMwh~jv~BE{*7^A#5< zE>m2o*r>Qpv01TAv6F~=`-sqUztRsV9#s5{;!Q;GeUXTCKTv#1>8}u>|Er2`D*j3F z9U{_OvrYPlVj&T9d<0+8&sQv0T&7q}1mAih^53brSLs(1k^gmyhZT=1-cCgN`-w>Z zwBj3zA8LHs93v+~F`EefF^V%3mnudTJBZgnFCzM@-HI0}UaB}0CgA=N+*t4&#XiLY zL@?d1_?Y6W#7&sD*#>tjzNq+T#k7ElAFDWD@jOL7i%&T(DE>`xtYheWZjJF>iu)8l zulS(ii;C$%!(XAeTk!$KpDVtjI0AD<%9rO%fVXQnD{ScV6gMhfqj*g5VZ~<@UswE> zB7eP|^2aOkx8519QQV~1qqtk~GQ~rRM-}f<{JP>}icc%b^Bj;b&vO9ZR{DpEDaj`P z9L0#@RKWA`13Pb&UdQSRf9$Np(L_<-9LZ&LgQag1fXqWC@$V_+!PNEB;RL9Yy?@uIMvTu}E==BA-j9zAcJfMA)^Th&J>|BJ6r05q3R5 zgk7&9!mfviu?-3) zGwv5L3_H9=gr0|>8})mH2>o)yKm`HLcb~O_n==t5&BI_20}mS&sY!am!Mx8 z5&B(9gnsuCp`Y|y&~GIBA?UZ52>qnrf`0oLhJHUHLca}}K@p9oFzs zVzc@K^tq2=*zIMF{}mDTvx@OSI(%Rf*w#Q-6!|1_ojR|9I1}^xxLk}C z1}+C>pKK-XbuZti$4*g<0a;I7mQ%9(3#1?NIYo|c?5Q*HbNJf|Eqomo7-`%da#*0zoP z_yit5*H&zTL6uSb|fa3f0AAkTz#&=wO`)DkjL~a2kFe0;rnn> zo||qTuKkBwj+a36mt!BoOix)n+;Y5#Yk$5ceC5D0-pe-vVU+Eb;{dKH&pljy$mEyz zyssSTV0O!qtMc4*EWiI?UOeU)KCeE=$9yS^hg*&r3HiS4D+iVaUcOv=QMOx-8*zOc zr+c{a>J#L>1$o_IVtr)cbj!ha`6$mVN8+c@7{`NaIQ)6#ARo&?Sv=f)Zw1|NzccTN z`E#!FG2J^xo>va8HS#D(4_Dr^3GzB1k9;f#(JjXtD$gxPE5iQ64RS9M*IqfuM}6G9 z-F%b4=P$>8Upd&PxcSx?d0siVCYtNZ*wtrpg1keJ$9!21JQn83FOj)?Lx-Iq0A*RPI4-UiU!!`0{V1bN4O^-%z3*DhaF zd2YI}d!Yi|ay)JLymBNXOnnNJ&n?H}p!>^l!dH$7zI;ca1E*}a97B)}OIzm%25YCmV>f*xaHt?VEp;M>?_9<q-8*As- zdhqgnL-Td(gYT*jG!A|*LEisi?@hp~DzbLrU3>2{4>_4f;AA8~5|R)G8AAvGWS$fR zWk^6E3=sl?jS>)TTd_5O2muv^wsB|~8e1H}p`EqC7F%1K{Zyp2V@qpVZTa7~cI}gs z2!4I<{r~^D_j&GqPMxZ?YSpS$t5%JBs08q1zHA>QQT*Oh{A}?*vjd>vWtYQ%pa@6G zK|1myFJ5*z&a}%nBdQ!_ijL{VSo|V()eL?iGE$c$f1P9Jt*Q(F^ZQP*yu# zWJ00%+2vSb(M8HZI?6*{ybvv~+IIPtMU?|vJ&}BOs(kJGaDyMmN&B+p*`nxdI01Cg zmo49;7F|R>(ow#CiWt%IdI*7Ny;MfYHvkl*W4cc)ei1#hJ)g~9PAEECzCP!W&xL)r zXgeSs^BDxki}~_0Ko>3Fq$v3YBi@#;kHs${Upe?;yDxIt@)RjL8=i0u`7UfH-y|j9 z5XI4!Z(=+7YNF&D3R+vfYgN8>{Z2oJe5)0mE#KmE$j5tO(fX@X@(pVz-<_a~)?a;; zd?TXdd%c}}E5Q%jrjg5*=f!sN@!k38%eKES+sU_H$v09F+xq*woqX$~e6_@lo7yIEn6{cs) zGgHyo@U!QT?|O?a(te*;@=a7cZT(#fx@h@!N6E+g7PkKWr1FI)FMh*dx6MS+F=Agk zeh0y?0g7UOkFDbfzdtH|b~)NPe|Z{CKZFD!H}?M$GsA?8}Zj-j3h;cdYxA# zWo3j)ae5oCncg)xheimS6U&evDG#&Z`v$liWzx$>`^?rt5BjUZRiVr?-~Mq?Y3zY*pEQz#z`}Q=5s?dYRa8j667G3CZD;E7Q;%C>RlFxDBQ~QJHxDH_3cW6RZ zS@K(uvqL}p-2iO#4AS9t)qt79bd86?9Kv}DklurT-BN}zM!3W1H66NR06bkj6?0zd zEXL?A`RtDTK+WhB*1f}YtVbsLhsa+aoBB(Ma&b1`a64eb_!yOgM>6OJ4I?F<^G^L{ z5F0rO@_sr8bfX}C9`WxmT%7O=gi}q2+Y}I8=ht=2sc9bo>7N6F0!PWS$Wde<(ovdm zoSlqV1dO9cXe!EX3a+&sWods!j9a{de@D-x_u%<~2hi95GQ5!BV>*t3F~vxeAW9*g zV^BOlQIjM1@l{88h}q;D{7R8y@E+zeP8d7Mu0lfNg|Ua_93r6!!nln*DkU^g7`%(` z7)r=FNf?}0IjUsbMZ(z3bi*VxO&DX{fQCy5w{Z1gD5NInMAqic@DoHVC8B}y@5%WS5dKSmD06hW5}xoNxg#8V z6w#U(%9_iJ%C zRa|U*2VzH8hV`3;aTybJlh8(CJkFd7B(zx={4kQEkdV1W7#w;WMKTUgRHVJesv0UX zt_M5+x1dRIWxq+$`B;N1CuTJAL^<&9$_*YN55bAGD^CJ$u?fswoh9HGd)xrJc=<)B zkQQ{iJF!H*m0Fn9qxn{8nGBeCtOA7YEQ1*ZL+-9LX5Y#Zt(&4N(F!D?Z)K@g$dKE& zs#Ggt$gk=3s1A2`gKKOjKM;$SpA2C`gAsP_0F6WFaVVDaIKs|5p}}B^XC*Z)b_4LN z3bAgq*d?I3g7iCMy+Hhe!8_5MQ6kTkMm6Z;#4zBzS*$YG??JA)k|4QorGQ4)oV4dS zvk-XSbhbg)1keaqE(FwFpF$?nH3CW9uCCx8a`6eiu#4YEDtGk(p9aqnB!zar03S{F z$N|>yyi4g!&l*r@ZVx}#q=h^;f~OYtJjA$i51(z(8cc(pCeZFk1c}V9$c`E|*T{fd zGlvm@>M*aBfv{%Y%iOdE%{(jv=z4#}q9MI`yA?3amt}IzZN6s(LgqiLK-hGkpt#C4 z{R@PA4aQ-_#PiSh*LNY1liit9hMq zB9SKG^p6oEIwd(+W-VquBD{V3kWePfC`YunkDtKANOBn!!*8egn&;cJZdQ&Kvm1ZD zZ`ZWNc9_Ck1_YQ#8l2d18U%^#rw8<kbJ5_QCa2Yj_Cx|t7>3~+JeXg=RSpAkfT#b~}va|CSFC1b$}Ut}ZfkuZ{ZM`(J= zRVh$5c)I&$x{+ySz{=GhFN~niCk4rL3nUA~Ba{BAXr=MOj_@!drbrA*RWfHfJE!(f zB{q~NGmDktW_lFsK&GgLBypw~nCbGNgjNPYroaQ|HkV!_;s=2b3@%Z0mh2K8jLa04 zUi9RLDw3h$;o?fMCZ36tV?}N-9wko?PDVI{*c7DqP1run)KAXD5ca zps4MWW?6-S32cFL(EQYeie+En6yr>1nm1xRci8dp6^UDnH{Cwa`I5vWGbt6JRGGrE zYdb|WLl2U8Qhv(S$tGiJ23QzwFmwCGI4uV_t21hqjxC56G#I%O5wc4F(ue~LC5 z4c^ec1`l0)9}H-i@S-iDYt+P94-}M>>8R5sag%uQ-1(PwAA)BBx=+Sw+ubi+xMcRM zg%j(SES+`fobJo!UyAdXmlfd{^JU%VFUAuR3m0}LP*`stIaP=o&&yYK=Q&f0mn@!B zI0uI&gS2|#aw@{vSzm7Fx183;JiXt(m{94j*^^pOL^$Lx1j)#r5?0 ztb>jJZ$-hftaWKcbK&9avz9N!v1_a9<}53kN3+BOF*R5X0DzT&-j0H;0^%2<>z2-6 zfzxb3f$mS?tk0#l#-MQ^MjpfnI@qm*=F9?so&n^ir(epQ=O+0^liLxv9?F~&Yb*E)Q+56-Q-6sHB(QIl=b@D#eLQ8;G# zf)Nu(;Aq=(9S$q?FoVx^v`H=x(ZgYNV}@QhL!PB)D?0jH@^fnD%d^AVq>L7J1`nxg zJ(ZS=JhW|`x*cvk9)9W4S*uWr=u_yTPr$ZLzpO^eXbO2;p*)%V+#QZQ#8j>0BQ=hk z)N#1VAb>#sQjhP<^8ivx7@d!OME#JF+A{lWaPqP&!um*mn*_s#PMkD(!q6G&P|p8D zkAhzgJ(ToslbuL3a!M_3Q#3%!n0~>tW(gJFIINO3gwZbjE&SF3KqfD zudK9K39u+slWY<+G6T zT<&G_mMpDrD~#1jt7o^-KbkiVJ0CO5I^KN7Puj@vp+iPW?X(`*tz@!#%g7-T(dC$U z)>Bk%4JvI#J@6WJ@`d%(Sv0esJ)t*JkF5vJw?&oNr5!SA@WhEY`Eu;!aWg81R?Vmy zJZd5idaho&WZ^=29(9{ySq~Jm#-m$m)Ttu%^X4p?g9@BCXQ}GH?Bdx?90mg8<8y2{ zg#3y*KYz@!ZAz9>*`2_omTB{%j$v-?WZ9-HYvdW6faLUMarGQ4qt=7!D=^bRq;=AI z#4u&I*`~C}Pnru29TBoG1Ka3YP-n#2aw5-VJPvimoTba`=4Bgrbh4j63sh0IubL5K zh7X-EViHBMPeEp9A`gj=X0F=7P}D3=g|<51nkCC|z_cb0){x_wEUg;ZamY)gS8Bs( z%;0h3q?KD`sKa5*co1=UHRh7-56c}f3}+h;onduRntbs9a@u`4PWr$w&^l*4`x)rf z>S&Nzt8h*%=O(rtE?YdSZbsV1TSOAv0Y z!}cnkG-2{k%{sxgjUucQ=y^sn>NnDPT8ENIb;@&qtwyTaj+9v*)*NYhO6I6j<)e8 z&T}2y7r_6fXNYp=gKH(0g=dIn!*9J>*JH$;?F`YpR$_$YdMtwB8KQ0ZdE|ZNRz2}f zN$YjCGeq0+=jyTb;u)gRm!ZY9xo?e4gy?9<&pR%y7taWdzKk|C$nqvdM+1&tjWXU| zrCMZ0o2N<`j~A?>E}r2TeHmIkGK4z!DB`&P?|>eevMY{n|r>a<#q(&C&Ydb*9IZ6-PPVMjkb_Nr}{rqWp*Y1`3} z{49KAG7u3^&2FPpWA_Q=@j}h4sg9kj!bQ&I30qqj-Yjbm&kJLu?denouCCa;kyqIA z^jz*uARdb~Ne6Qwe;peSY$rOZo40-GGe7#Y0B-Xj3r)w?688m(FIIkU<+EOiKVSLd zm4AWqYm`4<`Ijqyweqi5exvelQ~o{5e^B{PD*u@B-%$RC%KuXN-z(n@W1?J%%Fj}M zcjfn2{s`q?p!^!;FI9en^5uJ*;3wb9gMY8W%l9$?Kd0b7EB|BVH!GiK`cWRQZu!Z| z&ryDf@&_t^r1JSJBh&E=Kl=5`U#I*=<=>|KyOjTc^5r=mNXK1qrsus$`bU+2Lis0^ z|Bdnu!=ei*zk~9*=g;)Ll|NMZ6O}(p`SSY%pu0-JJcEzvZdE>?og}m#S%6~xl@_PoL=Pdy8c}@9mD*s*Of2{n^mEWxV zZaz=(7&Plf6@m(4yk+(*+(C6B7N{lRel%c7b?G$KIn(ghrAak7+sm< zU#9%o^g(y6@{ygUqtoMIv8HmpImeN_M&hfg^IVdA9L#cRc*8MYCDT1HR#U}dM7o${;@_f1f`)(9$CF;U3 zAg|8&=NJrglNaqO`m*UbjxtO;=0!R-ANxXgEw2LnbJkfdAx(Q9M6~%#ICNRkF+a|` z$j?qU2I1(-&UXcn2uGf+8wZ%_$%~imFGV;y-{z=%(L^KpK8Y}S+vS*oFx#Si+5C9B zI+~xR+F+)_la6vc1V?^$IqDFOz8J^r1RTPVa*&ScnFlXB-!~DC&Nl`5+WPY=I;Q(K z9C??*@mdLI^B~MPx)A>8+wyU~lLKd8b{akf5}j{;RCzheCmr)GQ2gxlI}zY>i1x+2 zc;&a_R}Oy9gGnah*jL*8`n2QcLMDbSEa+^0=eMKt;x=s);_b_(t3n{U9PY5D;V1KD zUux%jNjrYK!7m^2_GRoG_CMt^H{U$y_P-ef>kk{v|N#W%f6?pFKjVm-207{zDIY}-d0h0G+djq z-zsf(^~^}Px;kITXCSK&J-lgT`9H>#ZW>{P^-UW`3OEgpu|Iw~SnA8YU-W$K(~oLJ zkB_Qf{dAtjxS7@S9=>Me*wd4iu9qo)iInS+a=l8KU8`kk-Q0(@+y#>UH`VxFbY{5f zli5uD^no})@i*g{%}s=hB{a4flWyRMDa&$HSrmjST!<6H4?DJxZ4T*7S9y3^szarX zrYy^HMWsu~x>}}Wis6U9NF^`t%@hl>E6r`b@7>LmKs)6z%x#`c)wMlZ zl8fzpw^#bU!ow+wCe-Bl>P!!#Qgn43b2WLky_V+M?%6mkEvweC)w3;jV@#8%jNPhj zbTnzFTp`grzB1S(wX=O&WnlZG70(?LJ)Nhnacb|Iz5Ls~O-+@~?eUe)O?97IS`1eu z?tA>R=CMd~SUcPk4Tt^75V%X=cwJ?A@_*mngod%-oLQ=6du!ZPjV+boCr<`@Jc+hg z{k5jQG%fwS*3Nm@Myl&A!Xg%(zQ5vkBNF5TQ#KF zZL9}O{9OyC@7XumTJ|n!f8F*lZu-4rPw#|HGTbdHOkN>rt-FyfJBnK@ zu#TI{m9@}@oe?NL%Y`s)oc!Df@2Y*Y!u=+>**sQJPd9zEVC?6=^4>6FVoMjz^Of+B zUd#XbXmu?t%*T5Ct5f^x`G!lJPk*iDmVfofhM~<3j&SXHV(=8yQ2d`yih_6N1-GYG zR#(O~#%xR2okJg|w zuEc2WpwIr=G@MQD!$?_@y)(DPEpEGZ>S&#DYNiplCr+jbY>#h>+jb<4c>UB&-M0>}JB@5E2D z7d~3C=Ja`cQ<}puDTjxmOexK}4Cx4&GGrp;mLazz`%~6``JUWsqOH=ZlkzB=ONt6J zMYQFGKh?Bv&)98Y@1Q=iE!?!vtTGy%_fRs+=Ip+ccBv~HjnBFo{h?Pup{#}|C^l~DSBzx{&H3Z3iliis=NL+|I<#8%>Y^R8O-3CkX- za3Ahe)u$>(wv)`-e&VGm;*=|H`_R`;iX+G7?Ky1T=4`tE@Li`I!Mjd5gUc#E7<%Zi zxXp|H@zCL2z&dW*1K$%oU3pE#D=h^_UO!w>xiK|VsW8?CV@LG~Kt=ByG*=PtaNKnz{#$cFEY(x;RAR6Tv_E~B*S z_6q0ihYqJz-BEGqa7vZFeScbMrLWSpP2Xf}k4bY^_Nz2Dndob&FQd}2DSP2<72acP zL5aoF9FF6G?|=K=gNO5j!*#d zs%LFsYq;=a%MeSCCd#TG)54E`)^as1?q7d?ucho}Ew_8sgB8wWyK3*NXg>PUf{87i zwJ$#XXo2f1;T};XdQNP~m$l`7*oE20u&U2KZ5=y*2i=pC>#ZTMo7m!}A^yW6tc8&~ zoxC`{);$P4Eu{vj7boAMxy-83f%~a9#-6QyFfI?dX5an8gEF1SPdipDLyjuTPcJm9 zIv;zwcG>u^*Ro-qIbbqoM8*59nNMhcw|VI+@lFWa{MFU9Z%@;EPjh^6{Daz( z{Z{@T$oaYeKS?u$dW|nEdQ&U>_^22VSNOr3V%Nl$+-B`C*YNz7$6!oAMj+hY@!Pw^ zajn%pj_?O6ek}ZwLeJ6CLf6p_h5J#W)|@|B&>FT%n7Pmq)yAnkt@+=Y$WK0|-;*zO zVYf}zv8dWwkzM1F<6sCgwsA)K!{HjMq}dBWv2;_#pwlb&&aN$Oi4W_iU!1LVU30o_ zueeui%2u^4Fa1w3j_Vt8RvX*ISmHvP3a^nJ-GzT&J@{uD$xb`leeT7jvL&*)>0W za&@iNZP4j|Jz$l|sVu4JVGAZ@w63#cnVK*nzyE+<=s0Q?t~veo16ux|({Db&65LfA z-;8&Jj%}()KFTpaJ|vpQiM9JhkAJG31MA=(n=0HYHWnrO=GY64)5p`QvT7duM9Xeg z@>%)E_A&Brc=Nr_wC3vu>p50!-B~-cb`$1NqKB5f4K=&tu$G-≤i`VX-XjIFxqK z>C5(t9@{FmBJMuWG#|6dJLglo1g1=twNQWfF7Ok5vub2|DX-RL(CP7ev-gXBn~?S& z$KL;RS8a=$ds{NBt=d!(IyS48IcG0KIiY1M-=2H#!n!THW>dvK{`}0R;o3BDE#{C$ z$f{K*W=3~o)@fwiUa{sI)F8th#VNmAfac8>vu^0T$18&GjBg2s8Y{df*3KJI*;wIx zyH%H3m+ePIkN4V0({N5{zI>onnk(B$leG}iXz>Teey(R=-O%mKH-C8`t5!ed59+6$ z74Jfp(U2wPuM=8&h3`7$*4I^dPFz249i*9EyK$Ob-pPAKKYd{Ofp=y7?)#nDfRP|P z3o8pPvjHKLTdgYC=OGR+aSAQEAC%8#;5ioisTR3jpD}B34R`kI@xatFxhR(_f32c^ zaS8uQ`PYMgW&GnB=vm3-g%7q(A#tg{d9Tfix$a0MS9RQSvm`#4bgED#t z2f6o*_Zb7ZD2BJf0>_KM{bVx40w;*TXlUMBX@L_(z)MC$C5U$#1GEQkl@)uD2)qCz z@D8)UX(GT=aJ<7U5U(}5Vj-+&S{yTW6(SqY^tfh*>xjQ3_6WmYfTd@q6~2x%v%@PO zbqc?d)U_Pi$nkaRi~<-uO41ir+IknMd|Cbtz?sJHU|GIw3Ahb@k=vK&zY{T*wtPL6 zw$jL;SKJndt%+!1WTU(=)f@7-9zy%i|7R3s4W9c^NZ+ z=z1J>GRj}|CBnw7!23re-plrA908?&l&oUY=m4Gg$0qN?#%_X{&{gcfVaQFPaXN^OQ77~o5KDD-bo&8?Ml1y*Gf$d*Id`4 zC3qHu`I=Oci^vIF^dZ8=YLqcB-QOt7^&%JsW+dzdU>d*0ZgpU`{}}*oV>NgL=E%zM8xLj! zm@9!$?hJ4VTpBn6f%KiZ@nknoLgFqX4_!=Pf&U=l5)D2T5vY|wQd$k(%LpurD?%|- zjPuE2aq`8;DMOYyutb(Qj8`wg&$Bh}OHg!v4;JNm4mXiJJHuy)_%}P8##|uwOksPaePm3*0OMJPg)b zC_%ie8dy(8MOG}{R&`Bf0S{&WiQ>P6@(d4lszMRd_+)J`9F)7%Mm97P%uHK~wo+gq zffme)^}%+EjkVnXWOuwAF=fVjca~^6=Gp>eSW2{U} zgYQPhSedwu+aXbmm5JZ@C)0G1Mjg`n@K}hEqSI64{Cl+AjL;OG{9trM6AMjE&XSz> zKp~-vq>z4@XK0$tGi0pGMa*<*APELPlNGu+XCTs~XkoXb6Du-prRE6Biqq0o;RR(G zG&L8`q;X^!%q&G#c*xO}-ET6Chk*rAWiex{g8_cBidExJZWm7=tpvsk>25 zPUPTf%EK+TE+JaF_qW8dL&G53GYjFJ2#1Zh*(cx|gQ3f~YS}{gDk6Xy35c|%b857> zITFzM1~Q`N8uufOHLS%o1lh-kCs2Kw_yC$0;tLSzVm(^CQ}C2;mq^0DTXey{NA$

byC7)(6h!;mFCPs|lNxva69Xw;jSkU{#Z2bELPkaanzTX;_ z?{|mA&B#1cltb-V;$SJ}AtDj=kt0^3PskMuQJy^UOW-?;>tTSMMJXhV6%WBoLy(Sz zdCK?y`EXZ$o76$gr)aD=iqJtqM(3!|8)uVemDMg@dW-&aRUEtaSv?EBR+%Gd&NIF z90?ufd`5GXAyuH4F%vAR0+o(q@Q1yJOanvZuzMbE9ckE-U{8nxodf5w7c{fPVf`7<(G80k5Q>Fn(z#Ir&tgD7y{Ro3n59gS)0TP)M%aoyJ zWM=YD^Uem+yBL4NSrm?w7Kt1&z3e)?TY&7#@uZc5<~<15QgmXM;6DL~>tKeOSb}O5 zVlRwT7n{OJBSv?DqBYl6XdtoF;2{DkUC&@=ABew$_?lQt7GfB}x_A)j3`{3cp^1GB z0U|3!Qm5byrkI4%X(Aa6h4@_#Q#7Cg!{QAzu}sai0gXB-&*%YCFFRr@aq^hp7AEcl zQcXBzb`=m=7lmDAcFR%m$rFvbNOs9ngHJKVW#Fd?7utmoV^G6r%_{)z#x#aCqZ&$2{&gD3y*+B?FV&K7N@FpMDY>_FL)6AJiltA}`Y~S@+FO6f zhPrjFMX!^5zi|lYs^tBiazvfCc=;kN`GD-N&#S{XlaqfhCmX}0xCbq9T~8Mw;e$pz z5~#92=JcZ~#g!QQHSrueZy`KTkS?6)K@9OF>cbR#9?&69m9p2p3T?|J_%$H6;J1D} zf~TW<#Rr|)e|Ck!LgIUfA1gjb?Z=5SSWUcmwU|9Hzuk~1rXZ^%aW5!S!~p{8QOdkq)V{#aGBHN6bSV<%$!S!sH1za_KDI zLcaMT6?*L=9_fP7R=kZ8brbhNUj^cIU<$>DsFq^!XXH{MrXgG^VxfRCaR#O9DLzHo zKH{}}C{%O=rmxrz8}BC)U`_o+C9G+H_yaUBP>h58pxdE> zUty>cPeE_P#aPHWLi_-2oG&^!I2EWySw@M^Q0md*B2>vZ@f^bA#b3c;g7^q_JyARj znJ0-SV3SisI`W+={tLRgNaTm{SphKw^)+4OLGp{mOR)M&1i!Q}Lj)knOtBW)o+awh zerAhw=&D*gi2oWf649F;&R9~PaKDC=ZlZx@C{MXf`4p`fX_m~lRg)TBjCSS ze2X$J5pj^eP9!1KWr833z%#?p)iTi;<*gS(@PDPa4DIYH5kPp2=mG6D2%bE&R{Rnj z`Z_TU@?R}p!2f!2Givr4u^0Gj#S19WFU5G2_c}2Ua{fwGpcA}aw$Md=feqhatKqYQaK?FuDp|Y=AlpQ37>il>~MU@iJ(f zq6?Jn5`|EZTU_O$5oaLm6(djqKCusl_lr_+2#B#LWKb+bmBff9m`g~U24$?+45i13 z1PB^0E`bsg#O2_eC_Kn3N&J9fCyN)Lf)sHx@=6trFw->gIf|Vweu*Mw2tFj*L41jd z>?oco^>LYeShv$hZNYz(t1!X^RKXU9Z9uaH|Jc50o7!KVI67zv67v;!n zuvi3BtB7$y4_ZU01rewe===_dnXRi?4!Oz`;= z{uM?V^6_#39j;3ae+hEK1=XcyrceOQn9~D5w(N-cjZy%4L5>e$V-#aL%dR-nU~yCP z0|6i)uk3mZvBiiXgsOiCD7j(2Lnwl zmWmo+%x%~~||mvhfFYt>XP=bmZSvZ+$e2-2)N8g5KSg{5_m=iF3s=Byj#WGO!csO)E|0oXMD}2hL-OdL(kvWmM~do8YIZikYhix{yu( zz!8*GT&f#gNjxBfdKssAxy9kSkGuyOXAqN;2fQ`Zr)LB&1RzeLt>P0o-S8)Rf|qW` zX9X{3{4RDnq6&>th-_4~9iNdJ1AWIL=L(pOh(iw8DT5S33_&lV3m*4uioLLJw^)Uo zL!ut6F`+=&%0&gr*%0#zl4_xt@lb>oj+sTTJmxZb4KW#L?`O`aL8jv{=WEPn8QXMd zA2I--h5m`2j5-R9BqJ0nG!UhuxS^LZn4oECp)TNqQAZ2?2`wAKXrTun0Y(%QL4JCw zFk*31~5rLDPRYEU02A5Y{%`Cdmaj`9tMk)vClikgvym`>HP5U-F0WxomhrKB&Q z!v+H_#INyzg%;w6Ly=kw&6fd9gckN7M$M^1eo*9$Lg1ck-unIykQ|N_bf-oegp@3e4=6V-a-l@C6J=PTF zFk(mv5M@$^?I@&|$i8xym%HR9CDgpDiR1>aDUqB;Yu-k{{g~zt2*~NWQ%kuU;R`lH z$6`=A@eZ1hcHyN6iVF2@tn^ztqwe zF@Hw_8RFj*Enzd#W({>Sbs0%z;sJXx9*5V6Dq{GDr9Kpxz7{+)FLho_v@B410?Ov7 zab8UfH`~mQnL*n>t+*$&9L^IS;+rBo)31k~)B8H_kFZOajVev=<0tRuh;3C}`d?tx zS+ksP5lv~e^yScA+M+COB$(VJHf4zC?_phz_MSc?jM>#hXIE62DgR`_<-)wJgeJRG z&CBhsboRTcyPYGMNOF}Si|co2I|<*QAsC&d#_C8U70>0oQv9PZtjqz<4UA(!OgWVx zh;37fwH|+&J)FO5OF$5l6XcNoAUc7x3$vafflQbF1sXtVebyVqNWz4yEX?wj1u5a* zh?S-^pl=2gy$ZK#fsvIbAA=A|W^fNugon^x^M*SoK^NCEp4pf(M0IQ4e$a0*d+=}v z%NFjoxoE|I2ZwNig?>DOPJb^K=vSPt+ZbtNTEcVCtFh8SYyLZBLHPC2&J4;{_>j39EW4=cHIoam=^ zNuy0C)++ybkUr(!SV~&bik$w z#|=4AODxO=@P-8x)zr<`#9J1iT~x_pG#atw%?o!2F%volz8!e`q0uO1(L;zq2c>nW z1E!MIiweZ{7#3SopyW-K1V-bbHTjfpvjyvo!`&3>7E7l7Anya0HDB9eNL5V)G@6*p zwQZI_ivcYlW}en$VXgtR7S7GLk+)m89e}qI_ZT{k9Tx8QfZ1T&Cm`%?7VaqE7m2GV z)U?|z+}{9yLflE%%pDdkh(had?l;iw?6h$G0rNnjpPyaC{H1eU`ENf!SlFysvHY@COX^EBjMj({Q0p%u3o2}{CYwjAhn z;L!l*m=Az&HE)0m{sMpTYn9AZNXdS&oy=sI+!Zuq5HPfxkwn~XB)<>_vr3@10dXsw zqYnVSf3gcMNV52Git{9-JPYT+SQxAozt-qu#a{zk7pql#NhE%? z(aVbOho&noSMlQ`@s}ItS@Dl!&Lftp_{$>kOYQvGc*G(V-x!HsWDK;@A47j3=BfDo zk@$Ib{`1g#h-wvoED~RB^t941L>DhEwt6J-LnQuUOTMDZH8I2LJ+y(>LDXX70`zWH zhgob4W`~)%XjUB*ZA|0MQmfZ4Ro$ZOsC!!Ji_j1DvVzl=qEK_e$C`&~{doV5u$-@E zVGfLN+1qIMyd{c3!+?xCcpJ3C9H4SI-h6~weFrX!{pNOE?zixSCKFC}gFAHDHS<}4 zRN}bDa)&PWSjqqw!R3D$(6qaB*|{5y`&P@|^fxwqWVL%YD(|^v_3{W$XJ9iwS` zEZi>uFCm|6gSh{q%Pj($AkMV|~=ZeF^vz;@D9?X5o^drx-ZdQ9o|sxCzI{ zFbakukEG6s`~+jfD|!N-iMa$3Q<&fofbaF#kD=^e0KS~K-vDqL>73!-40r=^+=6f! zlJ2*FcM?*W#-Cd_S2P%rUZHl9-CB<$Kf?|^9JOT>Nb(?L9Bday%hd_1*8Qex3+IO{)RCv3S=bG`=T0U(dt$fL;O zT_CwV{H=w=2Z&k3%7HnO7n1ot2L;zBkufR~i}cn2*npbRv1^T{`iP#e6ow)PKt4Oe zb+#M;xl?Sy1xY3cKq}I=9!cAbQ~KpplPCvX4uKmGFtE1+-jC|ZuaY;1z*w+~fs;dE z2L#gLf+Ukepya*r9J~jUHzylSl6P0~eoRm7iiw<@Y~+I#AKj6YjWPsyb2dmaIoXiB zcbBdL|_<`>r$>elH@_yhPyoUfUKYz=q zUK2R7N|po1QISi!2cmGjfaAc*=hIrNPTJ=vMA16lwW8QmH0J~$X&qnN$lWlROMs+x zB%=RqWnx)l1BpV!0Mtu!Q5#MU0$YR} z1il5#<9~YAVag<*JklGd6yO`BS_Wo}S022uJTVV5Bk;ElkBZ4==xv%fcFWIDWt-?LdJK^#& zP&AAV+Cvb;?S$U%7fH>4_aTx`qBwIva5Zw<00OJ7*^e|%(VPW{;qv8f6(gH1V|=3! z!?loAUC3n~5YVUg8c2K2)}9t=%tLQPx5t_Ili>e};)2pS**uy4y9j43H3S^jl&J{_ z+<}0W$H{FT0=!u)3;eQ3V}bdE%MmzPo>#5%yaMw`8 zO>2^RFl(O##T)}-_9agisInTmtX$rOe}iRZ<(j&z+^+$DMO*_qKEEF10{2J2Kfo1? z0HaI5Bx|-7(q%QoxG|{0Y0l}0qi&WW-qy`*;Hd6vqi_p><32)DD=xK8(K%Nl&fuMl|_l9ws*iyoc zh`a&LU6zTP#(FB7<5s|1;8Gt!A`Xn2?<#~i&$lYnp5to;g^=BiV#z$0S$X~jN$-R! z=!Zz|1G|?8k+GioGC1-1q(8vP{MK6e9S8hpxKy49VddvX=q&k-HKrS-3 zgwlL}1CHB8stUDa?tHMJ2<;nKmuM3Htsr-B@%}OLdlxRq7*8!QX8`>R&a)Cg5=WF#&O9EXs1T5;3a zC)A?OS}a^t=Qi>OL@nxxbRR>^tw@)MPTVeUmC}KNwX#1!$g4nz4IwzO<9fTtze)^Z zk6(=V0yw$pag~_JO^?xlN5IK`8(*pCw$CiU7sI7`!G?RdsUa26%5Fx@ERcD?T#?73 zVl}EP5arBcInrGQC-Yb!CNYoAfPW1q^H^-ZTmu8>^&iqT|x3E&Ihq;%yLyVZbK633;~5FwXWHv{JLZF0#~Y2oey zyc5nh9E@ypUxje5Lzn`T3b_FbP>yV3#|ySNrIt8+rusgzq?z}!vVIxx^Ke?PonX;b zByr8k3*|$J{H3ZyT`d+TLCQ~(NESsF3n%oZ!)fL7AU-FX*5D&{;CWT6X3{O~W`n8| zT!%S}LD!F?03YP<4<{LRvKU?rcq&{rhcGrRWf0aW954v(QUcV!32;6X zPiqES_94shKVGk2!;u<&l{R=KyF>)!dpKeT=_)xR<{Hb~zK}haR(X3OR#`QXl*eU*vr-vdsB$#uE30 zcxx{NmHz?_`Uwzf=s+OEJXnPk;)x<^U^94cfb0E7L_aZ(v5x|L2u=#|6oohe=yff#L#a$+MPGU=tVyPA64)iiB$c^WED|j~=@d|}S2XeU;ycc3!VFhpK2J4a*6FV7p zx5f(cenf-38_{Ly5^R!PEzv_`C+m2uOirs}x%qXi72Jcx&L+8Q61x|{%~o(EGP%_X zHbY%alD5n2`o-Axmf@kXU*%$VT~5Mc=U@!IL(ZjQzeo9Y%HYs0^^36iwp&h@z)rhl z5yozDp}gry7)nCzCG|#C@y)6WW$ihFm}Q`1MzalFBv(ycfXasB!?hakp*oNRZ80*D zXtfm0hu%Qmd1YILL1`H)a?tEUBKczg#sZ|2qYN-ZI4&gdDJTFFc<(Zi9hDg;q;eDa zY>*kR06q?6CJ6aFkd|?K7eJcg`9y@LCMsKbVz_GMiMNuNzs1vt=4skI-#|a2H|QOB zTh{o-<_XO32u}bPl4sEhO<$)c@%E&aF@ovFi!l2*qo|K6A24HD(~TDw+vz3>mF^-~ zi9S-5VQwVdNKw_AZlsuOryH%(buWjh9$;Z^MH*@R`T<$&9I8@3AWPi^5+1ZN>i#0? z`FfB z!b-5Sf~Bw$>>O|BaFIOoF{k;hqT$AuVfjS;0kBCL)17WL<-+E`9?5y|I10WO&pz6bO|L+6M#Z8)~{1HWBBzm53ga5HZO;ClekZ>OL( z)QvrJxmJ>cRY4K(a(RHdlL2QX0(@HK2{1x81;Vl%Yg>oUx40oYu%ZVTIplZvPkgH0aa zV*uK0u*%z_y1O&*rR=YtM?lvG;QzA3{sY15S3stLPYRr4HGn(>a>$rOo-M%i1k@eQ zvkSm@1V$6s2Vf2Yv*6_ZDp{Ly#bD|p`8p(*`>QJvzXDF~udYX69b9k z{8Vb|W-dG7HxaLEi^$&)86T7LXrONbqZ`S&9Kd!2wvjW*;x7V*`gpfJXKPUF2;5#^Z2b!!+?S7=f z@S6M&)*|mf$D+TBfs-5X9S}%|3zAITfu7`ZBV`*!Tj~(yAWEjDx%X#i&yaPz$QVPp zsp))h$|GxPx(tC*vL;zX(@AG%9i{1xlJ{FklwfIk5SR=gS894B0wc(k1QAW=oQtc{ zG>1*z64JF(NVY8D3?=5R?F+za5_$91_G|=Zk~fLet?fxZeya0q%3zN&t`mC1IuJPF z3J0SW!a!UG9(<9_(+$8a2;4xR7l0=b;A6j@!2te(z@G_>0`LU_Ckb2#AQ+E^3+I^) zARmDoxLJzx=Zf}*os&D%e9murBuc}3_130)T@>zm z$Tt#n>sxWzTY%%^g^;;*1je|_bq=p1aAL=7blHwKfC^z+>4kHA1fVwpd>g~h8Mj}) zr_JyFPX}rW(a8Y(Is7ZZ-ypI~B2W2$7yM_9fMj$Ts29P>EUrah9b7!Q;`xYpGR7ve zpS(Tfc^hImzx9y!Ap{N(U><)$;1xLe+(ejJVS640IBGa;YB4%AI7! zyGB2PQzTm6aTtymR%j}8YsEw=bR43}kf<;crKL^+j*kdB??r(3Fwa+!jl(tHA>jD1 zVN?!eADKP50f-&{WG!;`)Dgm`z{%ND1p@uy{?|9*V9?QvGVMM;-!M z1jv0D0)ya!d``wsM)DRPE%J6q5K&u{q}c`F&DMg*=#~MkatnhO+B}MI6Q-$-GN9^_ z!2;%34q!I|I|z&dz{k>`gY!%Q@J|Fz!Hp*y+8Oq&A=Pn7nVF2uAUMf`AIR-XfZXRI za0y(H#C|ezW+5rJuBJhPND*+JEk0b=3sEfH^5`hu+RSFxd-h^+Gn5y%5yXxJl+N)K zP>sm+S8${L1OQXK6Y!n}%!h3}CjoGS_yf2>WI!9R{zLGwSt{vMQ?QnVbC3t$AuJ_8 z?t>8+0Ouzs=$3nSye#uzAL!Tx6c<1jG0i>zTM*#$+n&b(JcYm$aLG)WA=7@&CjXTY z_ybcj!JCMG4NkK90fBGef+X{kg{*3|Yt>rS?749St978NoYHatu{K~>(!YRvMCiPb zD3OXEc9~m`Rt~p2069}pD(SOOn4fUVjyf1PM-@*gEVrGqVF7tQ5sQZ4@bfsvO;=sxoyR-JC3ym1!_- zaYV05iI!$dM&K#T_^TjSX>@&Mim5)U!g@qk5R3}tEVHtp;xhwnPgm~QR*PWUOXX|T z69tMcT5r2VQmd*C`^Xl7)2CID&WjcSy{LV~FzE$oKk~vK&GjjI!`DZH@*^Fe9Q-@rSl3fvMXS7{k z(fS{wS{v9VbWROh_A@rZ7tJ}-gt9VoFt7G0TV)R8+mO(LGSSmah!yS6_@3B$#`h%a zjPJ>L=t?h$6bBtA`<)Bh9`!v1C~azy7CEzv>!d}`jmvoientk0{=a0tYHrWnvK3!7tYk~$8hNeGJz%u$~SaRCbFW^sZjz9v){x-o^D#gS-3g)MY>6k3KY zGz(%=%dmxJ8NB2TCNc~(R-euM6B8mqqjC5h05lv-1>3TwX{=gvhxw{`6ajGuyjLB>Sn0~)nfL?%>i&B1j6>Bu z7;cae(z^N>jT=^*16xe`kveuZwNgOd7VHdmH5zYTZ5DqH!keQA@0Nrns@8N#LRUwl zar0_3=UotP2BB5X1CmSwnHFa>Ze4AryoUI#HY4XhWW1AlaK1*}Z#FiXVluE0_gU!J z#3QuhOz&n|jzpf8NCzG=b^MyfX0dWAG)e=R8L@M*{jT}GBO3j_;}Iv&k2s%@&Bzw$3FiS9 z&<9-Cx}&MDbsup9eMG52QLEC+TdP*H`$YeYmivwIgCWNKjB=c5h*YgF4i+_Cc1%wQ zV>uei6GB?q8{%CW+lS(B7W#z#p)TWpZR|5-V7>XGDFe?sessvdZs+|j8Tgy)F*gH0 zBSYILr`3IjAbluDOftKU!QX_ZsQ;(L^8&!j;xB~W6n~}nSMeG~3-dMoeHQqAeZ2u_ zy|D%5Hn$kfgqn@737s~+BlMkdCtKp3=DjAMd(DG{4w{dlpTggh4nR*jPP<`xu=W4w z`rk-oG*RA+@QLx1TsXNksj3$>3zR#77-bXAQW>3uA}6KFByK*C2^ElX3xeoR$OxB{ zpA})>FwQiBFu`D~MO6dzYKt|WE35$)>Ez|yDw9}acR4zh@=EkXmBZOhv|dg=Ag5$Z zG3sLPFel8D-UflLiExv?LuUYK+$k6lIwCvtOMF)$EJrCwcP#)DpC1`#<~N|*XZ#VM zs;s`s3UWXLX@VIcWw$SpK%>_MhYE;UQDrQH`Bx3M5|2T|`H^C&@hXU%f>|(`{8Cs7 zaw6wE{F(SZiybve8j-sz&|bZ+06WkstQ4U7Bss>Uu$fysPHJQ#OB0XAj5j?gU_@e- zAc7-_!pWY$pgogFbQaiT{$GO^9#95hyS%4Y;wP2)|SZN%Y^>X#^o&4ta$ z^hOK9nVgdHr;##gD}ikHNziLj4*29uLBZ`yu?RteP!cQ<6yr&8fiyVza+p$n1yc#k zsjR*v15<{KGFj7dHdSVindGc2Pj=O|`lAGvb<-x2iIgZmjr>njqVbrqanVYOV(Ue@ zyfPBi)NhY=hnx$mJkOpoB2ou1?$9xcvDq=JwGA^96CeH=Z>C8ad$a+K>@Zr3)&VWm z;-ly7DTEBdFD0xTvDsX$D}o(wx5+`IdkAY8 z7Lioe=+E$p5XyPJ)ls$23p9RYss zJG#YjP)@7tCXB@a_8ueDQ12%?EbbHCBC|_ptuP`&%aQPB*|N@_m%_hja5?v)@i#-i zlJ_bQVWO)vwO<>UIj=G0?C8oJYcQU=%Mej2M=eRH$rsR6&*Q*7Xw&gJR;v5fn6K;K z=*E@%kVsxQql6q~Kl3su4z4j@*1rUWTI(XuF|8EOfMWL=^BMgUP;g=Ca8E)kmXrv} zo@uTm#zPgjH4NfIYs~xgS3!)IYXvEwWT&EGJJU{cwRIZvTjO%HvLD3#I+k7fe@tm; zZgNAa3t++4APJGJ9B?Ob&l>Y){dV1jfHNB-?(O<6Y(ks6bP9(^OE@gxxzdZS%Y9to zv_ZlgfW)rB|Dc_4>7|AaO%}Ncb6qSv-MGPl{cQ}?C;%?!9{iyu9DK;+4i14>Q#mb& zPggFed2B%-X`8@Y*phgm)mqs+v)Q7GB;!BMszXQ||e zN4HHgD3b@}q$>nOsH=OKCZ7ek!|d7}6J$t@9U7UyD`~yh*`si{RFmxi)9&#Ymu`=V zBXX%6>7}E|QTgcc^83o+2=4*6u7K41*AE@|LmoasR#)uIVr96)_zTHB zGPJWY0MfLvT_?jz)QC3ZAzV}WGjgYsE_exha!%twpxjgWa)&lIJq~OFKICAlan%g_>a*2XIWa~dj{BLgqfwy zPG)FD#zLN08QE4I+RWKp_^5r8bpdFey5I5(zpg5)k zx^WYo8#pIrU}?Tae)?sP^)&+N9D&7W#+>=Mn{UL0vq#m5o631d1+(NRGk@$i3-q%m z7pcxQAyjf1M~(5P|Guw}EH_R?xPjM@k(HaC?kqaxs&dO8W`h}njlXb${HTY(%a9MN z`H+lDnP5uXRPbYwzqYM-#g4Y30bm#cWZ*NYYcs}8&@L(@j5D@_Q6z)$=1j&=Gc`>w z7vE14{osK|+Vu5T5P&|?h%vyQQMzH2ym&&G*GvnXW3)G?u#3fY!2C^x%aWN}c)YxD zMb>CukKt`q$XqBh7gW4FuD3>We1f;09KNT`E6>8bd8S+EAawSg_?RXEzZvnIjNH78 z{CyF}y%`=cO+cwT?mlxL$9+a#e#TLw9QQ$ElYtH}BPTy&R7u9Xg&9khp{1oe8ULfk zIPTBne=wvUg+-s^{z39HjM#A#9QSYXlQlRacUZ<_H_C=jX@D-BnmN0 zHsf>@dQi7v6pmv!X_nM>vS$Nr2V)DuC}2nOQ!-B5?6{pK>NuJjme-EE*V6?0L*O+j zBMzatHydL#BcA8DkDL2@Vj1_x?#*yqoC8CqK^>EXJb2~~60?z8xPFL$cBFU01TpOLqK>=Rm@+c&?9l zYeQY1ZLIRl-yDbE!HhXi!W50XmpcU0Pcy+piX$KP^V3dIaeHS=$IjNa;*R!B9cOIm zC_b~jbxT`cZ?XN!Y5hudQBg7eZ|Ul3``?FP$Q|vyE#zkW3>Mki(|l&ozPGOx@&DhK z?G$hA+R;|r+_AH`2tUEKxqVA=#A3xKhtMaOlivo@t+A9s44y5kz^#dpc?;&jhv18KhvbWv$gFEFQ@)L zi1^QfsuB$l*p!mfafW`+&vu4IEnHf{60apDd;4~Gv?aH+brx;qGzzx8eLd}+TVTW> z67=MI;Ew{rfcZ$WwQY0r&W^rh-|p_VUf5xxg7B^FoqaIG@k&5nE4<(yeLG}%-Y~zC z7cEdE>1TnP^CQKh8 z0KR>H!7PEL%?gU^?qV^e@>;oSEq1i+fMcrIJ(aDiY8iasppuO*+1JySDm&JTK=$Ng zdf{TOg3uV=-;ZJ&bOesdjTqrZ;^PvoJ2_sw)EyPa%P0k|8!wJTU_T;(!5^D-M|;8c z!`jVvkB$#>#}vZbDtd~>;LDABe*VNA)}u$dLt>A*^gY6j$7B1>inxPgzjl|n@z@<_ z6}h>wU%Ex^hzT(6J1gOih&|~-hj<~>$&0wTP$RDh)4&KVV}pv^OxU>bW$s`wGvQ{( z3yR%w#;zpIZnUwR?T!IQQNR)eD~K3T_!E1Kezf|=VR~gPT+N_6|j%RE{-!v%V3`$ z`{!=vPdrhS5sAkxgXj@d0SUhDEav){cKMGRRHmFsJ_*OE6Bz`rFyqq;rpseaaLa3p4h`^F0Z%J0eA~U!P|JQ;BBA zJ2*D6D1k5t{33Sv7~(OOsfjaDG%9vhVk-VILL@LF9{cY3^p%MHJmm|)t7CVaUj+Lx zv8&IgIGmu)h{WE&B-`2*#U6;5h^>(QMhFsc_4$#YcT;vtY+C;7Je!s;rqXg@DlOkb zT7Gg~BKEyVf=uc6FQsCkpNM(=(okiSu+;Yw`~7)E(0XO;pp!5f-*A2cJ4ykKOBnOY zXymq=^yS{b&XJw(@Fnh11#V`Ed(;Gm9-+Rj#E8j_Wizfbi`x z-I1|VS%+#yl;n>v|GC4cOQAb#!bI3Zw_)+&^iaHX%NAyUsdq1&&DuFEc1y+*cO*4l zm2WEP@6M*Oj26v<^{W^GP&aQyC&Wtpg72P4_i&Ruyqxl2dWn>X&&kKDzK^0n1aS4r z&5ixVfmX=C$QE~QJofqXmzX+{x5XVg%bkk?LkrA~&rNmS>utR=9eF&T9wxBvxz-}$ zE~FKza+x8z{&+0A$YnJ^juzn8gwgO~*PIP?Fj9?BQL-b3Qt>1xmaanhf|2c4S8B@A!w*p!xfViw6STRi>Z5hnd+$J^1^(2|$A6K29xXtZ5M z$Ao*V#Sjd5>>aY>wI`#|p<5|*$BuW07ofK&K%y`PkB#-1k#_{#>9HV|gM-$LsVM${ z32byl@zJu#t+0}18eMGdCo-h*U244<_k=sCz_jAXM7J_6+@#_H8_;I|Bt$(D{Q`vK z515P^_n0^$A6*1b>}71CCc}1wn_c1-EJDy?`f;ZK6jVF{)ng7KMGx`?3@0V#)^rXD zOhsb32{a>?$tqJ7&AbF5Y{fFA{%`FmjumjRVaoq3*|YCLVe#)0L=qdGK=m2n4k>m= zO)x1KZzDHtm@cDc!MYfpBGK%$uIlPcb}42?hl=LLC$oDQ;<{53Xb&tiPS`*@o?Utt zyMf`c!wja1GKn9f2sCmvbq4qoc!Y;cz|)91Q5W8EQ3-9aVpkeSwMxtkN) zWoC}Z&3tPY&v(a9b*C%JVh46Jiwj~0 z;tAW&JhAKiX0^TS_#Zz^68Y1L}`VEj9TT zndN2{xRHqoHxr{9X8-7dF==KiVD_VbaZ6wv&)gdk`+}K9kB`0N<>u#2ZbG%#%O)#x zV>g~j))Y0Gg)ek;)+Di2`gvLyt;ZMMX1~;ag zWA!OEO??P@0`x9L?zlPb5RS;jP?^o^1k=nCi9&by1b1A4JKV<0wkJ#awM}uUxQt0I za!s+>)dM2Tj@Q`57_*)=@r3w^Ze&Ce9)}0>@;97ub8do$j)`0eCOb%HF--luzT|sl z4o70o;FLys!8{1b6ox{mrWdm+#QX}@9HEQCR zoE38rfYk( zu%%i<8AhETXR)fr5foE)e1gkr8biCuF3>G|Z|HUGMc=nHo29wi{W*zh;Vns4#U$+_A1A+u{eua+Y9a zw7ZBi{wc0I&lEIQ{9JOQSKWOg`lNg|WGs4f&0JtaY7%&&m5V;=cvHx%;N3-0H?3+s z?P+AAjK>$a?r5`%Fe|a72-E3l3_Hw?ObXS2L+r6wp@zAmF#VtDjw)dVFT}jZG+y>s z=y=RTW;DF5vbSb{M-4T*D5)BH8TKFC5&0wGF@_;+P?=p&44Mj&#Y%Pw)nW!M=aDZ*AQ89Ju8m2PQHVSgWC%$Lp$YRgq^ijt)!Q4FFb! zRR;V66=PRmp@Llg@92_LrkaV4nUY+EY5OUVr4-dzL7WgF4euhdA+d|kTf#gU8DAfr znMYA?MK;5AlAFCK9=i%V4Dk66_{@%d^1LM&qcI@QXRQ zGmF;zRc3`cp~gLGCUUwEJ@5zy}!paGU{W`POc6Jm3@@LYxbgYJzembjUXEp-d2DCS#B-HGtWG;=DAu4Q<9Dby~e z2S#&rDw-OsT(H1OxI;~9_$Ohue}LggsGT&M8DGL(ZJo`OU0YsI-Ce-=hhw3`&TmAK zJB8jbFb_GwT?`vc5>KMd61Q#{ykTO`)EtjnuB(|8GoRqxKZZj@$o+Z9`m<0*Bjd53 zpNADQJi#r0NlICPtQ-3Y5+Af?iup1Sr61C6nBtW6?+oOqfRI z=PY+uN zxKk$Lw%GL4!{g;6xYSCxixTeggqx^wM`IO<25(k%P@=ZLJ;5YomOFB(>3wG;+|!HP z8Aa~VMQ$sd*1IceW}%aHPfEBOVG+fL>G_wVD|#;Uwz>bW^quPK%SFGh>+znhr(+gu z6kV~w>RRodgoWBNs#+ITwJ0=>d_FY*nSJWj%o{9N;^|YX=RI%vrfp(W<_7zwElK|9 zdCl5n<=V>HrsUevnl+Wl@|C5vD=I6Ttw}t#?AqDq*hdX`&eGQ0%f|wIG?U!YvAcUK zZhP>=DcR@jXx^1PGuhdd+=8F5fxyP54K=H}C9hNhWDk zURP7skgTd}SY6tbte!WgWFX5qj(Oxs@moFdc*Nb7?CoxDX>*d^W0k(<-tABWV$13p zDk>Y2jnx&E$=bTwN>Bav-egZ(cN?_DV~*xc9c`^l3!m*In>*UKbRsnJ!#)%0-MwQ| zSBFU`RNje)T?^sN$jsvz+~di6l5zGXoALasHKhn1Jtem`ceZx4_4G1K8J^5jEt|tt zHESAICfAi#Hzlj8YpWYqQinD^H%fN2_c9}yf;CM|b+yQqhU)dn@}`EGRMu2BRoAYdGWeYc^SIA3&&pK53}H(YAy!n^CL5|(tTYjZ3K8F`+1c6Nmu$gf zYCq8xl~r}n302A$Q???xx)gGtXgy;!&$;l7(mrRTjd`kP^TWnmUs}N`vu1UzgAcnV zx3;x!+1lr{G@~B0_w9DPJWs{Z)KFU6$m*3`S!vXTR6ZbMEO_MJx7A_6&OQ#2*oqD< z&ahGADHnYyjzBosbfVUz($`qtP+3`N;kWgt^V zOuf_A+TMo;v8j58$Ax@CnG#*mP`WPJRNA;IS&AAE$Uv1tSskj%>QtKj*eV*!lcfy} zr5jRiO_l3W>*{Kom_}yA=8onqHivEHG}WLo5WvsC##NQ;lIxG?vccJm_OPkBWxKPv zr@0076i=Lco!*_Bx_5bz*-E~txwmZ~G3%-;noL^=KGwwJTAXp|+1Y~QFAQY0Y^bbd z`);T#tq3Hprnnl8 zRPAakFGW{pa>rzGMP)hqwMMkwRh3OE5pcyy#>pNKoor=8Dk(LUrE4phL3~DQx|6ix zVA_bRS5HE9Q6Z?EEjngn%g&x2_Emk&JurGjOBZ{{pu4%1&)9eF z=wzMV($n0^`0L6}OjgyDu1Gf4me$voLOa?9`)O5UFDKZC2Fj^=b?J&q6u4EE>FC|s z+}d>}iVH)M>BddrnR5<-c4-=qX=pejb!I9jR-@zbt4gq&L!?l_9s)ozdv;qbeEq9x zD%U3wxE8GeB-oxP z(0(^Co!(Fe8P-EhW$g;I!q&FlK<1;TUeRE?-a1ot{nVk`tE;Io#R+L%&uS~ermh|g zJE*g*f#zP{P*LSwe#Lo3uVQ|cx)Kcu|!M19;aj1&HE}81dmCG2VFkwNT&}L&qn?vGk-A&6@7G(e4 zv#KGEu!cvlB?@5Wx_a9-BgWk$xMncuj@{BJ7$)|*++XzdX21vXO>5@ zso16x}%Kb(o{_z0-`cDUAEac=qhoDY73_xXec~3WplZstEJi0e)I=x zYMPRDrjucB?9aKXF%lu;Hq>i^i+X{AZo%j4HOyhEixYA!+c7Wo^QE+*Jjt#zy|E;l zq1w()94zf@Yfaz;X%FjEp!K3!rDl*gT7(HpS0|e%)iQhye~zV;{*j8Wwnh*JVgf5KdWQr+kqkdgRF&SX2*M;PPG zTFO?N#+9WNnC9EauxvJKF1yY^(6o-3;~frX`;AnY<#i)=zSXh`BQYwjU0OT6Ej?O~ zn`H`g_B$_5P)p6A5~#qKE10V2w^Q5iBr7qKXsRwxCE8Xu^fr}EsZ<9hXDQ3n?AEb! z2eZ;g@9&Krjcdv{E%K^FT6V9uQ#1LEfQm7n@OVSio-e9f*R1{&EkV|1e@a2 zWSmX3sk*M#>1J0wK$+9dR+QR`>hjViOllAr&PATp*3)IwK?!>+e)#P_f@mV@3u;82 zFIRtL)iEoEic+rh&AJ9+tb;cPV0}t$HsBW&(rSR2)Ucr=&hO;{P6ZT|TC3YE@E2g7jk8N9$MkelBakOshY&D(8 zR#U6&(RCCbmN{)bT;^y7!oJ&7ks6L3fq8JsQaw4{&47k3>`V+neO+6&a45%X6KMBb zJ+|Q83Vl#*k|(ZN*IM zH<%Cn&7N@Upgpn!T`1CQLwGgHIGKeJ)u~(u-z%roLdF{j`;~HNmDDfo zYid{3)~z#JO#bk_uCi2%RJH-^#Rm3Cb~JCtW+H|m&5OJ#W3VrBa8$p&+q6O_wM|LY z0-FMC2B;aPSA_~?4o7~BTo@gLvXU)Wt#khpJ)5%9Hfq1F1(!W`yG&JKK!26UVpJWj zk+4f*Yb@KZS$oX(qF`6i+n>a8$BcVSmp3r*DovkmS|Oc6RTu%d6oZcr^MG}gPA^&@Lk5>x;i%jjaT1J(zr zW}3nN#VnEV+5*;L@{19ny%UqBcFd=^9$NEbWn_7%L+?YFQ4SNvunA|iE8Wes{`)3|q-{BY2r?cipU={q4Nv~odv;-t__ng))An?9UEGM@g^=d~Cm(Z`zC z=sH{QK!N*fh$dCBx3`%#&1?+szxd1Dw7$#iCvgA8&rmbKV6A`&3G8exaRSDOYysLA zcF=ueca3`=?BD(1wh?%fNlc;BpEHURIh zj-Dl$S-}xq%`j^dmzE!1y-!uut?hVP(#g7E_uc*aiuErli=Rj3b=Y>XBQY9sS5IHU zU!-y*4z5@IT;r1*^j0m~F;5RHd^Lde%MPwEr5Hu@b7w!{chhzy9c;XQ)epBaGkm9t zP+_!!;Ff5+snnRB+SZYJ^kG(_*ciYDgr5-_PWx%sZ$iuwdL6OX+W>ghNAK7UhSII>2tV7Dq;FYzg4HUqU;di2ev&qd+7D42Onv5W5b#a zb10BGq6Mm-Xe>t1ud~(o4$oKp-tzZj^Ysn|88?Cact zVVdvAr9HI@JhM{Owo@iO9W~G5Qn{5%Fb9N2%uEj%&r-QphKw|m3@f(`Yu=8o&MgV{2+X;(4wW-?|LIW@i)nb!0ECG! za?{(qvzCD-XP?pP@vL7bt81~P*@UOjeBhlb_tXH%2+R-_dIIcAfYzzUgu&fjK8H$e zJo~w4X4hu3n+36ZwkZ$%GA;z#Ow^78yB0I4F;C<-wfAudF`Dea3*nBbhs>Z;9=#X5Yq)@|vmjc4BiI4=7oOTDx{~Np13$lSn*dDaH0H zEmCuvN<6Rc?n$0G z`kX*de$7nKJfun$5BosxL8Uio&;bvdJ!baL`r>7?&BW3*O?4?LaHp!KT%b*AK4iA4 zvHh)0;+>eob!z%zJhA$u>CQ>bKvp`N_O`&mpV@J1c zbo?nhf4m4jKlDSW2{j_pQnL&mV2;CQPN<@gY7Vy`kt}&uYR=9%nA?HGU(fn;+L|V_ zxfD1rV|QW^eOhl6=9L^b zdtPGJj+XA7OR)e$>zmcQ2?7JGzhUZEHC;5O7OkR$Xsm7T)<@x}|gHoLz}on|Ypx&je<{D+%Y# z><@zGot@o0gR5GDjz!tr%l#Z%iTfAM95eg1Er_cgo>|cpg8Ol1%86YdGd`vF z%vDv`RSj-9d0n=3*nnp%<}n+eaa5nEc5FtgKLj?DDa?bJ8h?^z zYpPj}Q`pXwFta)_CuHiY*Vd&e8g?=dZEaV;*2}rJX^Gy(7RQP*JQ25}0`kx=$I^)+4hd1_# z6ji9jE-2II$8I(Q=BAR&^7EcE2Kq#^S-YaN-r3&P)2XS3buO)~UQOi!{SG$+y+MrK zPHNEM+>d(^OiZwQG}X~|Wu|*WcfwM!XXyCMTH`XG0wOGSqmjwHV^4#dwmu9vI`W3p zr8G-ctZA_O-R7wz4riDqpofa7WOLfKMtdYw8NH&JeQ_*crReUVU#npw77p+d*xa-6 zrINWpb9&B8bl%Sf4IFQ?du<=~ai8K)PT|89(1Rt3XDMa_*z0S(FJQnquy%n@w(K*# zql$j!cw1ezTYxodgk8n^&#b*e6wrZ{4G(1P(`GXfvCo#xtv0J{|8Cl;AB{QEfPKk8 z-8K&~yk`Wq;(9xpRstuUnt7{)d)n~4vUh8!Rmm~jPlk4EyycJ=qpupuuO7opLoJqe zXes_v)b`F!)Fr#cq7@JiWof4kk9bXG4dk&M5?L;($!>BrCP&rvH5*JlR%f`mr)!68 zkzUnJ=|1pAUaFU|hp0A~^9HC^shaB*q&jd_QFHV}`)*Lo+E&-D#eAlM)3;I#qLh&~ z%-YRiTKnCDRw(PLn^y9;93GjO*`WE8HZ8-d93%ZeVX;UxgH+%~w6BZL6>azJ#T2TtO$}?zbUZCx_8}~0KTL%8MANoe zfA+&gF)NeulTmjHsV`dyVDzL z7|DrsGs0*@_thvTeHl(#;mXG6o}smGS31`O`9F;CvC3_@oIrQ7KgqoE#q;< z1n0v1)4wJqjj1OVT-60s_ZA}BPx7;j?KilEW-}!9nAL2t_{YgKXYm)cwyCnYL7-`R z33>qL*;K3-zA9(6tko9%-+?7cc zjyD8LNvpou!Nd4nzDlR0dbi_2AvWte%?i(sGwhqq)K;7L%nsz3eaXW1ueKH_Gwiz{ zYc{OiU=Dz(L*x@KE)SEM7^Hcwo>x*rRc+bWj>D+my>)ls;iX?Wc=$K9*=EzC!Z&BF zeUDnI`8($R7AT+0!x!o^&*y2u|?^rx`!}3JaMWVolM8E$86( z8_UZVC#IG5>_~8h-{gJT(XR6w+B#+@rj_l)8N>v?@`%O%oO#oyhc^Mt&m(_;3$KHn zlRJ2b!*6wY7eAg`mYcOVdSxWdo*&aK%^h}Sq%t>yA4v5seq6UKckTMmgO#wuFuUsQu^`XH2>m9 zftfen#gDrxpQ@ig(k6QjAaz7ueH=fRbrE7|$a&(?M}C;=l;MMQY5t0=zr7h3#V&@w z#+)ZiE*XEpxcJ>#$n*TA$*6)`S<3CSk18X9aNbpjn^KnfMUhoGET{58r9?3O8SoP} zCp-b*di*QPO?*6SZ{|hui``2yE{%NxX-W&jJPYR2zf1qtfNXv!xh!{Fy5!Q_l1(|e z^r z=i9~jb-utA!>0@JH9ixH^(6{3^E7p_)KZsz>%+H*;lqrxeG_jo(@ZfZJ0vgLnFk-# zlKnvx?!ha@PcjCs7;-XQey|4dtG}j8@I%C$p`rMOI;X&u@v)zY!kzN?Nn?8rbv#W~`f zE0aacF+XA#<^9Y<7AN$s*|EY5uCgvpUjsC`*f{^@zko%;N{7KI5;DhoH;9u04 zWWwK%dwa1IQ&-HHk}}{f=1dL6H#OuwEfn80<3H8Er%H|iV-COnow{Pqu_5`#rW|n> zb7qC)&kDI0hs-4*dF(w>SIn6cl7|sKaK%h(OIgI6`5}4pQ;xWcISWGa7KGdvh0KdX z^4QU(u9&kVByUN|5qB|XS;%}sNZtt{_tKEO(vW+3$XpSUR}pfr3d!SWn7U%l%9H_j zF{e5tuR7$uDkN`J$bEIlTpN;C8*;A?$*T{!H-yZMA$g4<_cbAT-fwDHZ!yRIJgpZf z=Bx|Jvp?{ha^Db=x50BVj5!-a=95G6P7b-B8j^Ra@!#b8I@Q19P0UG#%%_LspB{4G z6q3Iw{1tvE>;Kt+nf?7eet&P>4+P9~|7XBVz26O(eNniHIXi+zm^(xIcZS@%L;81z z+%fh0OeA z3Gbr&nIZE9A@k)S^Q|HCgCXd_NB}(F;TFp9`7y z$vheUhhw((T&vD+9ne*K|%qJ$IpJIIMSMo3)D3zIO(mV&Ji)7}= zn}?soxg^bfm2-#8g~q+!`I*cB{I79dPBU+CvhWdk#>e$!o^z@*O=hd#CTAtg-o^af z7&3Q+%$J1Bp9`6951H=|nST*7|1o6#N64HJ_q4P1cXY@+17@a=D~~*<+c{BYt~2wT zozAw9|L`s%o`Qz=6;r#P&g4F4vj5V1>IoZPu)_`%-o59~i1haHeUGA&eu8u+r-;W) z;p}~oWdNUn^K<>Ac&C!g_NqB%Mn(ER2Min#m7_T^^>1E1NZU;{yNHb3ywB;sDQS+A zBwM=iYI2WBVQ34VZ@T!N&1;nqp;P6!^B(r%R`1QyIqjJ{Q{!!_+wFRI@nZ2DwA&6B za~vV?$o}6x&`sqDQlpY|6DBU@;=f!; z6_GW3TgFQ#^Cp#aKl(IxKhOFd08A;y0A7~*{ymFS1pSVB1cG^o0$>$>94KF@%(jm; zV4YUO^b|_I?Xk$fdn#%6CVQYD6;BspHvPl4YH9s^)80R{K2V_W(YUam{%5~G)Q9<` zLf97-QL7yA1boQ-!({knn3gxJEd!kar2U5_lzyb3dG{`yfB}y1v;Np-!)H6p`&1(` zukQIaOkMi3Jl~1&+Q$~KvPW}LXRNH5Ud&7Tz7N{i6a28E8i6xqX`ald3*?7^?8`{7 zurJlp%KLZ(EK}<9bre{nVId?b?XX>=SUiNTua_+=hhlJe6#NUaph#43> z>7FMh#ChU!62G#tlKh6_)RW(IoINDs<$N^fHph8U(TCg-y_;r~uPN7uVZb$Gx+Ue8;Fj_ilki_b!ha3< z1B4@gXtLU*2VR|=NAL&N3~&1ma^f)O{7Cx#82JEm^fCH^KUQvD@Q384%F){%gMAL{ zna@Yj{U`W?YeuOh!;Qji&TO0R2_UZ-RhD!ggIl_@zD(F>?Psh?xts7mlRXo~3*k5~ z&-uCP4Z<&n*$=-423}tLPgvuOjh0@#zP{e}4E*z&(P~M5yk@jp(roe>^{WY1ez|w1 z+<7;nFJ(6Q^DCP_)Yqib(`R?c->+@{=RD(JM;qxw`(ReHJ)3&*O~;{XY{yrCQ7qf9 z5w<%uO|`C z^lOM`E6va2C!9!_`^Y~y&Mxu=yVt~eem~4C$3M{?a$X@{M8A!8&Gz(N5}A>eVa*jJ z%so(H!fzbsujFLMIZUGdvmf#6Ir7I`s5iNE*S5@z%TxBeo54clrTP|q3C}@bjE=MY zWHfHuXY>NK&(9j)P82l$z%2R)2a`z8Fq!kkQKIp8qr+bcbE03e{S$eV%wx!#Y`-17 z*>TwA(7i-lATATj#goLf;wG_M+$kanM&74HQ*R;v7MZ^;qRTb@9v0Dbj2TtQ@Xz8Q z@dI&4#JY3;hV5bd+{}q`#zMLg?d3A zEpi;DnZJBavL2JQ;zn_^c&7Mq@hb5P;_c%1#7D%ZMEpdmk^j2Ly;H`QjrvWF5~qoa z#ARZg$bB06KV9q)cZ(N`*NQib-w^K=e=Pn={G<4W$o(0{!wOCg7mpGP#bd;UBHJhZ zpCq0pZWnin7m3%3UlPA5J|_NJd`Wymd`sky0Wv=PteMqQ94~S%N%sX}g?N&9nz&uu zC2~K9;XW&VMf{HVi1?)Vs`yVahCYMghl%4w?#mc`#1-Ot@l>&0+$mlteoDMi{JQu( z@rU9s#OK6U#ea&iOshwUc$Rp%_+{~K@dx7b;y=ZIiBWWHOjnkeE9Q%1#Dq9ioGH!` z7mCZo3h_j-UR*1lB5o45ik)Jgc$T&?}{AInQxh5LYykj6z7Nw#bsipc$(NMZWBKyUL@WmenWg%d_sIx%)$hM zdd(9{#f{?W;%2c!>=Ac~=ZSm8%fze1&x$vSw}`ii-xR+i-YXsueu~Y05&l2~D z7mHVj*NE4PUleZ@Zx{E8-xco{e;__4J|X@}{GIrs_!sf7;@`!?;`?I8P@Atg;xO?j zahzBvP7{m7dE#PmxmYFEhz;U;@iehj+$MI5XNc#B7mAmPSBjq&KPTQSepS3vyi2@C zd{BHud|Z4|d`5gu{FC^K_&4z_@m-M%0M^sEI8mG;9xKik7l=#6aXgfKs-jACC(KWi6@Aa;wteZah-Uo*dn%zUE)shZ1Do|67iGbwc-up zP2yL?JH-9sJ>n0;(qZ#@u%Xm;z9ABB7Pgm=#wuVBUXy5#FNA}al802@gnhZ@oMop@eAUY z#jlIs67Lr86CW0TEWRlIMf|Jyck!_JfjAx;6U^sH;&icCoG%_PmWnIH)ncQ#QEV2s zie2Jf@iOsR@ka40;y1HV)0ra<6OR@rh*QLw;#_gD zSSqd*>%{e9v$##{70(eb60a1m6K@v3F5V^HCq5!RA^uK`W8;bCH(1OQM~M@}DdJ3V zuDDn%6<3ON;yQ7wc)$1)@&?EG4f&YkJSY3Z;>6KbulZt)c$&CZ{Ji)L@iFmt;(KBV zHqMyNlf;jS*NER19~FNi{+F0B)`lM=&KFmS+r_KIuZa(ezZTyV=1X07mGKD`^5*vpNTJvhs5{AK@)6zqr@rVa^I1Ks<@d%esqvGInKGVzd*c9yi&ZDya~_y zNQ65e{z&$}A(5}Y7he`%5&w(431=}$gddZzOpvgjO(Oh!ahX^qt{~yBiA4B5@hsV2 zP9prL#OuWy#V?Tv|4kC%pAdf~`#+Ni|El+Uy zh=r4E{Keu5@g(vys7EsQkO*@biTt=y{Gxb^_%#ygyi4ZqiucL>M>0Py{zCRIh;NAR z%Kd#YHrdL}B@us~c(m+~5f_Ln#C75(65%$B+hu=-%x8(`%lBd1#bGsM%xUhz`#PVr&!8S$_< z_82RtfJ8pdA(8Im#1q7FaU}_VYf0#Prg*OGuOt!v8u9buP2#O2!rw(A{L|uZW&aw9 z@P8BE7T**3V3*-@NrW#J=gYo|MEDcMMsb~Z3W@OBNQA#c{Ji)r@p175@h$Nv^g#?a zpF}wyPo9tXWL`re{te<5al3f7c)qxogq%;we69Fp@oVCpB>a6(=KI8-lSt1CGQT9g zLPD>9iS7(*9xu)yA#XkjeHV$#WM3`wYO#TYyrkT>$-YzUmHQ{fuZj1FPm2e|_r#22 zt=wF3ED61)lF)00SS z#1G^?c$RfPnnd`qVgU&~isZgX_DjVwx!1{kqwG%;TV&rUbB}l?3Aq=DH;~Z(77}`X zgM=RY#qY}fA-O*;`zOSwW&a16|0EtH5ziqpyU3dJ#Hr%(Vkrqd8c4*yRyrJc^W)+l#CODKu?=^WcnpbrnMJxdeZ0|-bljzYck&`k9V`VND=gIyAnajnK#5LkZ5^~QZA?F-&qvL!=?l*{El>2Qm-zn~w{k<|jDE?IZ zh4?EHau1P+Cv%?V2yvo#tXL|p7B`4(;x@9%aXwBWKQ0lkko#w4{+xJ|>~E9#PH{g8 zIgg63k@> z#J_)#=EOkXYw=XCuDv{j4iS5*(Bl{FU}P!<-UeQ_@vD3Vy}2UiSQSZ(D&0M^5uH* zOX63=+e!HQ9*JV%XNrW#ISIB-XiSQf67IBN%K_dK4nRkm9iWiHY60a3+BoW^&B*K4N_TLi^h>wUr zA>r>C65-w!|3~(@C%_(h=80p)iQ;7PCd}tZgl`l#$i9_C_^sl{#GT?<qZjcGnQM9BoS`3SSU^vi^aL(5^=d$Ev^>ViW|iiaf{eZ zLXUH0zCgT8yi&YQ{JeN83BB)@`TOESvVTl`O3Wx#`bhK-V`ZK!7Kzp3sp7}Pi^MOH zSSx&oL_XakJ}f>eJ}W*azC|M3yJAk64WBC>EshlziA%*Q@kFsvTqmARLjGnF`FW=7 z&ldNJmx|Yr@PEB{r|kEM-xnVcA1C4e&*BH-m~v}hBrXtFiCakYVP}!Zuk*x9#LLB} zNcek~T!rWM71sZ7af~=YJVrcLoF^_6OG(ICK_Wj+lKmR-G;x!-UF;J3NQ66&gq)ki z2go&ee}P1LekDFH{!x5Q{G0f;_@0F^&%Fh-@le_UfD49#dMdDJi zN<2|)BoS@{iF9p~eW!S)c(%BQguly3g!`WOtoSDRCC7P7M3XnqTc(Oj#U`;!yjVn% zjQ{V5Pl^8}4vkp%rJ{Ks0DF_oGIxl(#E*-g5 z;(T$Pc#dek2Uh4fKbQFp(VW+Z{RuHECn=sIUM=1xJ}f>X{z?2V(VVx3yvz(MFHf8x zP8a8k%f%XT19`sVd_mmfTJyKX%D6Qj7B9-Q=4-@T#r@(B#V15_?i=#olKBI1SeBJ@ zoY*3o^Vjfyw#-+GH;7*q9}u4r|19#8Z%oh8;v{i4i8R%Uo5VB7F<8%w<~%ga&&&J) zc@>_==U6T!u}_l}&lRs0zbx(}+fn}FYh)|RX^`b)@^bVa;%VZ!WYTfIBt9y>Dh?V9 zckD+Lh~?s`;>XF2*iRJi6Mrp6hQPfF>jSY({0v!&^{e>27|(@0)~GYYauT|;Jk!Oc;x6$q@f~q^KKvIu&O-52u}8c_{G#}M z@k#M{@oh0JoJeARQ7)SEYpbwtOEdUg@eg9oQP%z#aizGET;n+AJQw(c%>NV% zkGAgSJQdux$b1dihxxepnmA^ZwVyARiESjtwd=$mioX^AM?|;iL_d%9Ac_73)~0I=@N%T86lbu*6l1TSH66v{zME`hzyxhLW&i)O}-RPSTXNp)(8T$<)L>luR z@fz_P;-lj4#J`FWj-SX6^PV5_VVuU(V@1C2&HSknz43et&B!nFULSb1%-*CNc z)sZkm|EEak{|^%SC)m!Q|27i(-$O!wbN&(fn{$cK|53It=;yD33CbUk)8^4OLp{?jDV zc|hhzNTl~oncpH&ZuzVyjE_Y6&HJZ}k7ne<61guYOVM6sK7~ZS?2(!8LorR??E8H^Er=%+009k?~`RV?~^j~ih6hNz^`9{eLa?2y*u+^lOpr0GDVy4 z>G-0awvHlN7KOj%5%>gDQE9{KBKT?E^xX#7)_`uWv zx_q>711t6s!*(&p`ehM6hk}pI=;Kz*?b$`M|4o*r`*#LNO24nIq{LgfACk4<7>-!F z!LMz7m>y|<2hPScz5Dq$1#G^=WWL=MjxXRcfb@{7k;Ph~FZBd|1t=`{2)+i0(}%|C`x_vg z;a(-p?-675zgHE`;eo`ZJb%Ra(*qn)iSXy5K8h~=!hA%P1`Ic#X8pg$^8?4cO>DBtwrFZomwsZ&f_H ze`rtI&;Lir&VFG&B<10+*nN~-9WabZ@sU2Q8Ll};^fy2X|E=Ev^Vxj0?n84|z6OXf zJgfwK4j3PsRq#7^;narZ_4EG`bm$l6L&}x)AWf%_5J&$ocA^{jOlwh(wF*vdWfe}P z{mh@KPe<_KeaF@KX>HrIa|^zAxVg(IviHrKHubcfVcWU2>FC1m-S*-K3j-mV@uN>$ z+S06gI=A%mW`46+f}y;F&(!YVuOtRVZSHB_(PrySb02hEOu3CD}2xqo5#XfCe1v+-}aF=1coFOD+|_n*SQ z4EPoFzr5tMf+Xx!j`KOOYP@RY^NOUFof3dVa? zARU9{kKsGI^|z+X__fq=Yx`1R7keG&2{mlrSh{etm68Hg8K zTz#gVvv)4*Fv{ zD2taDFZU6H>Dc#5syxQYAHzkVbFe)4lS|y&@-9yw?l%VI9e})gcw#yx;Gb6>hpm2o zdGNbS!OIg}Xyf(ML4Wj0S-iY-On|>&yu)5irK3Rp7_K*zj#gM6fW3El@>YiAB_MAh zJTV=U@Xt#}yX1N4pG+kJmzR!DTYr8!=#TnP7B4T}tKg3!meUf~dc^CskEt+w@%}~e zdc{8zfr9Zh~+fkx+f6te33(dFv$43wI|21uicgpR)e^bkHC5p)6irIxY{z`)nZI#q!5+ z?3;3tnD2rXWJx`{{TY{-_US@$%A9 z0Dly*oR+u_2jV>eX0JT1w(|UX^;ZP)`aXv9^jQ~@m-U*Bm+hl8Any{%^TOre{6X;Y z(($nM=ci*Z{4pJr#mh^_1EF|_AzrV2RLCF09gFdTvfD0)N!Ui`z@bN$?jekA;ZWOGh>Qd+|OHN=GZ?4OAXH z4-=HP67m=?%L9*pe0krNJTDy=LSFFl(($_W=ci*Y{81id@$%AfFcfb+;`P!|D}M~v zgg?RZxB~JDDM**6&qVkOrsH(TV|b>c9{;?2;rA3N&kOfW$O~RxI?lKL{B-a<4CPT4 zFE1TD=M#)~E8_Li(I|fmcdwP_*Q!gu>)_MNmt1%X=JO**&@V&&JpCR!f__V^KVLukqkbE#dVbm$!XN&3mdpOq zfPP%tdHUU|c+u?4^(5r2*FE8-w>u>7`hdJs<&S!NPV&5T@cWFx%c}=ZSbu&x=#Swk zi^bY283FHkl{=Og5@5CeMH^<8J^{bJ7n-CW-ProAggGfK0 z?+NJFDu2}P%8-6dkT=kHv?(O-G05}!zs&)8Z2wHJm(Ld-AsuXA@aLz4-@Bwfl*P+S z$DN^gUqrlKdux|JhU2sKU_M^~^YxyPfV^iz^4^5JClQeS#`b``!|)eO$7Dttxah{K z(8lYhgZ`)wW%2SDO=s{c;AU*Ow;gw^I^5{o?Q!%;#4E`ke{Co_>q1Jinfv0(p~s?QGf8xLW?ac`Ls! zI635xb>Z}oyjw&5JpE3Azo34H|7zDLEVr}q&(rV1ki5qrkLzCV^5mTtl9%|e)Ozq- zc=qIdRr0*>FGJotRh}u8-djTQ)pi{wB#E?RZr@fwMwbV|y3l{R3f}~=x8^V7t&h^z??j#}OG(DJeahbB6&9%PJP&)UD| z@ZA~4Jziz~{jejm>g288{_mTMw>-s|+^U7fJ)>&K_nm2{KKWk9OTfb-DAi(WtJj@xg) zos#$MyKPVR-F0s*FU_bru#J8`{mya2ZoZOtU*7IkwcPisR|ijOTt4^B^UJ3__33x! zmM|SJZhLjq1Fv*1kI#m`hi=(E=kU~F(bq4I-E!sCWw}pX`%ZKiq$I8`%ffwZ81wbT zZPP1^?++r!y|n$?WiLPb%Y)9;cMf(def##^z9&*O?C#h~#%#+sQ3Y*vQO`jW@ycg( z)a+s3X*`@!cX?SE{=W0nsfROGQ48yF-@cpo4Eql4A{XyDJSVZ|@LcAwaiv>tPfKw} z`=*XFwsaKZDKs90^%i@Lq&Tg?IJIkPY7*wBw%U4}t?gU3cHm!MTWg|VX@YJ}X>V^^ z4=tMe5^cM>d)j(?+q*g!C#Li!rcLRc?o7P9`TN+0UU@Ni_(1s6M0GOG3*K5oxY{9RD8 zyug;*^r{!PEia7Br}WHOZ$I_WU8Pko9RAn7j6?6_*!ECb<+Y4>Rp~gl;_|VPLy_#r zqTk>3$+88{W*z!qw)OX;Ly_1EhY##?UXNvE{Jmgw^4&`hJI6d;^}VvJ*E3_kziax_ zFC4!0sz(n+GV9*V&ze4~__wwlzG&)C-9JC*y}m5=plUH`BJd>YjretMUt0R%IW`&!){g<4tN7@cst}&mMhZRn~j%&G`j1 zziQn~N*_8nUA@3d+dht13#%p>Kau&5oBo1%_${;@&c7C{s(Y)UXV$B4mO4`gS3Ue{ z?i!?SSjM3x@rPd>Ja@Y32a4;aBi9}|aBNlGo4a!Jr!4<_!KjtvM(;1nT>WHxdg-(4 z4i_XAPK#7k9nL8J`%_a^C8{1dJdUm4gN#GVBQI{^-HY4m-pcwI@0>}6h2yJjzWjMx zYl3!>D%%IrSBB9wQ57+KahoM_tS~AUwxchZ)|jYz;FUK^A>kqSy;#|WhYS8V^1axF zk-5LWtFYqkgPW?peejh`+hGUC8m52WzB~6E*w($m-tXH}Qj)r#7r5WEJ!O9&aNm8m zi@ss7$sd*OQ%)kW=kz_@5BzPL?dc-wN6U9bcaTw#I9k0nUNoFkMFv&3+Qw#HaE4Xfem4A)I-4FHekt)2aF$L$Iod}0uXW^+>)s3Hz zL62Y7Ttq8f!!t7fR)8N!$;uoJm*LUOnUFs`lJ(h4gq{SK*z}`o;dgi>ega%vcCE2v z`QAS~yQdez>Mdv(TQr*ErOOYC##WEoL+1>)6gs*4X;nA+T4R;@Do$z-&vM_uF4m$9 zw;d0!7k`NX_hFilk)Kz_`!le5$QU((n;`BK6nVzv{H?tII;IdAGe`9Ceih_ol;mH6 z`{Og*wFu!pbM#c0hG%8)>$*cCR55;BE{{-0hEIYa@(H9V;OZqI_fhItAIa`O-ei_p<4KWh{?$cpAcM%L89 z_rk^IP}Y3q&}S&%xV+a*4rL?StOY|bhjd0o>kv)WLSq=0or#cHi*l)4)QM#C^Y2-U ztuY$O{soQ48{@EyNOlRuEHTCi4$`}~yGTLnIG!=j`wk=|vM2KQpQC&!AUiSSuc$jX z^pEJW3x@N9-h-nbpwVPc8vQ1wqr;;7hIsbm(Zf;u^G)$)PczDo8dQauZuSh!#87T8 z4q8rs$6C`L2aQEmXV0{zKMk6V&7tffYkJ9X??Va4w~qTNHOfa3)#Ox}HzS{feNOdA zuG*bwFVdV-V=7NZ)chc0-OA2@Yr}(x+DRLmM5#E{xO?(pf zCj6j;k?cf&h891laP)bQoDuyz(l+QAqd->lAvBCZGo{)mQ4oWQr5ZmGJm@%MSZJ#M zprv`YA%d0BaZqj02}XgM=x=DKFgaBpJ%nm8sKyvha@^I(?s(_8=cw8b&>F`LF5vT{ zXbYO`;6fALiJr(hHpv(=qLZ<77(998)5xzZlg`0YjLYEYvq<{jsm3rYx*-9>F?kap zKY!3_RNTSSY*8H;v>GWLJl&ce9@K#fF<1ru1IHZ+@$pL&JD^0~vB-1BLGY`22Gy? z!*~;9RASJ{Xrx1|fXKo@e?;~SnP@BeBFFsz`4GQt^1mo=K8kT(=EQG7{pcWe0tr*K zo#=J!O$zb`qc&$m`EwVUg(HVU_pIm(^fr0eCm=KtT?O~dsiyT!i>^ZcWFBJ-Gou^P zP%@{RKBOc&mtEBiV~AcA$-Wr{o_VY_UK7dwBx*+HOl$mfB>P3iHp>_@J{!sIqo5+| ziua&h{>DiB-iZgG@<{5v~JTvd^*>fZy`M&%A|9;>8&Yovy=AC!mdFP$FyR%cH>p+=-*BVq-EQ^h_ z3f+jhmQ`vR;v80^NAXYK`%uz1|AbIHFOg*a~a#2=b`oPyzu zJ43iI<#A`4lygEa!Mw(uWh^;Al!uhZojv_ykf}iBMRTXpY%-3h+?X*Fm2p(%mYB=1 za(6PtQiqA<<>by~cbIWx0qTrLi|hH8IOE7dm0M=6qZvnWU2d*3l)D7V%B^rdgvjH` z!5xHk<;}_Y9JG@1-}GfCf{_c~{TlxouI&&Ye|F?-l#RXx;w#M!tCg+*NujNSuhM_xrS2j}J(U$fujdd$ z@5Fyp^K(n7`Xc!yD+D8 z{S5vy^vn3q)O?9Qrsp8pm|lbb63xe?O7%^s2GjI)(8P4T99o&7H-YC&eHr{`>DN#v zX6Z~wI8L8N>zkw8KftW=zu|loet8+=chP{-S3*hScUzNG(>nL5@z$84(R2=g#-C|| za&o2}R^!jM*Rg2_)cAAkb!GY-G^*p-= zi0hP>@Hgvung;J`6ra*GawwQq@&b0qAKMx z@N+*6E1EFP`3kPBc}-lLH3jyf_i#k0A45~6^*v~wL;5KG9pxT||HKu}8;Fs@M%6|u zn4fi!(OS_aDBX+#*7_CbDXjliLQA|EWu2kVW|I12#wwpf8=0xxC`_(ku~Pv*%c-z4 z>kH)62}Vkr2VnFnRF;sw0-VD7I`lA6-3V*T)*++-d*Ut*h37d(<2(kk{zM*Y5P+Iu zGNEBbA^j-osH0EACc~N^#d4MVNdy-jcJ7PEzA$SNY(%d@8cP2RInw%BNRHYVL-fL9 z4wq~5+`=n%f-E!#CSQ1E4r?`fn}H5hcvTLc3v@zv;=k}j4vP-0+2atr@M>ok;^bu% zzR!G8>^CT@!fT6otwKMAJcZX4kvwf$SI?j-e18$M;p|H1cMJ+YSVXZxXR4`8_b!~1 zW`Y)7;JK)8g`agg;k7!WuwSS0J7Tk2QD7t5G`wo|X;2>4#wx$-`d(hd5#WsT7XtGQ&)`s5FZsB>e^0uhREHHCo>V zkC6U4jK|U3gdwaK!{}W7b4l&e30jBy;sA;4@G2BbM{^J+PWGeLmzb*ZJ_N&|d?eO8tJM zxIn*%+%42=QEeCLM^UI%`qR+$V$F>Wmgv8rGAz{}Lw=X(A3z(+^(ByMgc6eUL4B^?202mDofX= zagF|(w-C}+JEdTq!pThv=UjQkX?<_N$BgFE`pp1Ng?@(=(gw0Q4Gw4YbS+S6=Nki$ z!m&`L4H`#A=ouuKHe{wSIiXgvA2y>oJ1a{YF*T$B1A`I-9dd3&I&LQPF=?8a)#gx;K#vDU{-dr;h9+JlnNV<^|+#ynQm>B_A^ z)Z!*52i)@J7dPMUb8QK7ZL?f0qn(CPEY!lpcbSmsHoe^@z1gXYN)d9#1U8!PCNu^g zLZvA_%i&faDU{nbtCLH!I4#wU2vzzOn4Z=XnZ9y=4>eAipYz|0pmAMb2KoF`DV(jl zufP=2w7*fP zSXwj&s7`y8@s35$fWewf{1+<}GZBRph^(RqW4wT*myMu0nM>AehmrQ_!sInl(r0Z12tUC zj7QUc9RuW~IZ!ava35>|YIu@xOu4rMV-*e?yS#A8RL+<}G5nRp%rs1e>R~1&B^jRs zc_^c+FKJ`H!un<%@Km%zjte(BV#=i#kOVu+^sAy=)W$DU^6kJDDz;;3DUeiS=M( z#Eq!6{2;7eJ-!NFmLh9B2xFhmV%+oL8#aGWGjd8L$}8(a@Sa|t$z{h6Go0BBvwyXt z&aCCAgfp(np!XO2_>VDu)>*Ks8DC2yGk);QuvYmWLxfnz(>^bgRu;e1I&+45Gid+L zpvkB$;TPcwQ?g2x|3Ng>d1p?C!H0hiALAV+xxEsqXHofLJ!?s21SRt@jZfv@$69zv zn;&F+7hI3-Y1SorKfRfCOaP#w$t#X{bSkS4nVr1Mx9+_BqD<{$K#XWfscW%kYt4$7Vgq=1?f`$~k3)?YneJIFRdW^sF`;_C|d z6*Qhf! zbJjVWW?G$boE;8>q00XSG*@uO)qW83r}B40+=BX3zAs1ED*uZpm8mb??fbG}RQZ2I z%P_0=yS}frj0?dx_w`gde#s!~+l!WO`u1FYB#oz)hRaR?drRRGS^kw!NbE?7Ph?B@ z2w26oF7XVvg&NZ34^cwm$57y0MOws1if+{`2yX5&m(AU+dJgS; zE?c`>^)g=9u(8v(>P>W1b*S65x!9{dWiHnJ7OK*pwV6>m960Dh0+ES`(M))~BFAHb{PCS06NuQ}X2r^OW2AK}y|FGWi*y&GPO*t$LkzhB`j zV&S!EGXzTqbqdbHkArlFHmkfbxQpqRi#oeo7qP}v!OcdlFdK}{(8a7=+u*LlS=7^| z_GmM(ITy|YI3uudQ=dKz7LIP>PB0NxMb^Ae2mE628xOy)i{D|;&4wQ<_YVSot?*+r z@QU~yqMd{eI88m8qMKNcPQv{` zoTeU?*n0FMxW9`N^=N^uGu)RajI-!m%tFlgo;yI6;hc94DhrKALrfHwyB_wKeHfnH zL#h>LHa}i<02h04PQbNdD-EHY;hRIu(g^kGr171kc`K%&RLHFie@)u`D!KK*^D0EX zoZQZV<1@JU6df&a{1-01O9ux@ui@fPIM*|NYy>`q4*DgW^B;x}8yKXVdW&#tsNmGsi!=x^1RVhvDKIX+^_$ zaX(v|yKe7=`zoBpY`kgm5n2Qg*O2yKqo(IZP#C8^c@hyO zvQ_!(TFS|lq?Jxt*LQv)y{q^pynZxe+{l@G4 za9)eEq*GmQJU$D@M@Vxi8sSeGuT;!XQgG(*-q3#;<^{OQ#krvfxq>mNA0v^RbCJ2n z@|mv+gq7ipaFK@N!5@{ zu41pph}?rfj^3{^f!jleQdHy{@Z&)G6Y&TUHh*6L-CY5{XW++y{*SF+%2Bm`$^{DT z)^@#~IeHJ|eo1IvlXypa6N3L6!Bj;y^hC`aj(Dob(3bfc6VentqDGW(heAko6#p$) z7#>ljY62%PWJD$-9urme2$DSyX{c(P`s9phVy@>cVzE}ENSEQ9@@bN7Vg2T9zFvBL z0mX1$2b+vL;5?0UV+@YP;9whRW4!~$dVh-0$8qvIv}S&j2`ZR}UIcLhP5MC!jB0?u z&_!Ug)n0{NXPLc9hqsFS#=2oKh4Brxwu})f>ui+D0Ci8IQ7ZrK$|@tUZ;`lNu1dw zaBvglui=cXfP-&3aW~~yEgW2&`z;;(zH$aeQxTk7%`BjJ9XOgH@Dh$uc%W>M2K~&? zV+pdw_iD_bqy-m^ba1#bfQw!_IFPv(7gysngOg9=;&z;75n&8-S^82bHfzMWlsnGy zRC=~@vWlsUOkAu;Uzxr5q4EQ`YU%rfB<>fq%YE! zSf975klxv@T96l-_?30&$#Sa5xCO)%QWBX}Xw$%lJ(;};HqWRAF6B*1r(nFEWhBD0WL657x)dpj;Ax@+JtvibFT2p< zO^Vt?hb-w^-pu7Vog1kxxWI6pf^rYyrW|5baZQwX$(iyL8A_!HjR?565Y##f z335#LG8U9_hL>v4bEcsbd%={1nYUuhHsxDVxYCf*l;)H}?Npb$yd-m0VK7H?6L@3D zK3OlwYt~;~m)n|Ky1pd<~34123E#X(6+ zmel91MUi4=!B%F0U)GSzFYAT%c&8wbhQBBvb`EnFE726D%F`{PWzjAcdzmoGM!Qjt zOa!G`TCSLGUlxsU**HBTD-ZTKDXVSbIL%q;axqaf7AqDTQ(K8T1l$j|Q+@TR_an_pbrnA_R?QVU#ZiAS00fmjC z*^sW8Wu~){jO+8N3Ms-SKN7Svt1xEdt`7=|&Vc4G#k)ns2vBcj6=x%*?nmq9ngKH$ za-g~47&=Wih0|8(*6@nzG{5CP6|TNmw<>fn=J*Fl(TG)pcA4H`W3USkW6IkWp1xPN z89)97IW0rrvNcG4%^p&Ol2TI|L+!A0{w1fv;d02gYy&EK%5mr zBC(mcn)wZFB#Txd@T=P6K~7=Z+iVI?cy*L04D?kJLv~{if=T#6{g6h4hxEfHhMgjx z3O}r0WfG2!_0LB{o=sFU)eGZ+!pc+O`Q^^}`c$}lp)&wjxSTFYLEAZ@5aw6vmhi3m zE)Dpy{yqTQqAY{lFxCuCDU2I&L~N;q!{^@|La~iQHpbpB3}nh82$P1q8s(5 z>6>Pr3P(~?2Rw&i5~o=hr12a{G?h1o(%yQj$nxdD6;fclnGi(&$1KgFa$$fRM(#|ejxu<^eL2JI*Ux;q-wj6J(s>l=R_%Go>hPXFRazoIERO)g9_o-20rb>f)e3 zt|9MA(rCl8#(Y?RBJ_??v65tJIbNIyNj1^Q?2 zK}(x46CULYQ3RX!lHlB7X#B`YG=Jec^qquz^#j^D3epGkkI~G9f2^O-&SAKp&`;6* zlzxR|ujtpc;rP1#FqW&3baWH`GVCR*LKw#HHTiHtHv1njfmrBVa4MWN3GL0K`6-7~ z?5HX|6|St(yTYqB!}BtIE!(1N^>x}0{h&TYzf<}S9XX;7Gr}EMzKq;c19nO@4yLNAiq$>j&M_-=@6n^pU9NTNvVR})|7xzho{U#)Oo?4ljP=*I2o|p z3=_v|$Ps6|#PJ%Vq&QI+a@52TJ7zk~62~)b@{e#f7^bM<%+i2dK>;QsaB@&+NlfI6 zLYU}e=llbwgvygC(1MI+k%F7&IMQGviR?`KmkOS#19Y1eDdQ92EGmtmZx z`-A)!&Ir2x5w?l+egcry50Ruwm-YEx2!7Y3Kx~zil#w8lK$b?QXm!c|FrL+F3g_j& zO{wIeRBT|pRQ&pq2cxxtp3#z{lxH5Qstt5TH`b%myb&>NbAkFQ#~#5y3fdml-mIh- zhSBC=E#bjY9*=7CZx>&A`Kq`*&hLh;LQnW8PH$-Kdc&WLDdB}n@c1vnFoq516oiXQ z!_#Lf*A7WSVXVGj4G8xM&Ho>@fhO~RvH9mxDwcB0f4=$WDjSBDAp@`47-8dhyZ=`8 zjT|gUs7ln;kp5d%CK^4{?4cs)cY1MDl~?rib@q;Qb-(?)rRC)n_;vOVb`uZw40RIs z_4f@Ex!HZte`vT1Z>g$^1N{fPD>`~dDzJ-b-@cyx6}A0Hqz&(#R_yQX-`mmKGTcAd zvA?@wsAvD){^6nWfx-SE2s1R?(c4==N7-5t(( z>OEu_1b&{aboC4k^mZKe%w!A(w4O1%X=Gz~Cnq-siJ$b?jFUM~w6O*L2SrF?Fjnmt zL&|p%V=OLA=>JY8ltljsUK-!m+kNDpm+5Uv>Rocu)7RB~$kXsYm}u}L67LXYsJEvJ zjS1AUw*z}6dlh6uiV3g)@-#fA|5RhpCItB+jjzS0w%mQTa!1GJ+;3rDpKvxDwZ$DLMuklr# z{z2bmO0>OesMC+w+lx!9Dzp2!=b))01dq0Wp~-|#XEF@@9wiScwEvBUzBsXqg^*I&()C}H>K3o zQ}~}6DRDC++F&-&jZ_x6i*bn3+?mAqSs8Cothsxb`<|1vgTZW5pjDNUsge!Nk z2|0wxYB*Hx>JspAj>g;+;cQc=aFK%L5^=H^J>vg`oI@I)p+)q~hFNG=$iXNlF8vQf zlpey5i@6g@%8@{cTN=?ZcTt5~I@LItnj6{b&SfeLFK4(LS!3jwND=8==&m+|3q-s{ zZaUnP7#xYYOBYp4F=C}hoDAgH>4%^*jDR}gT%g_3nPirimzO_25{p4@(M@We zC}O3XI$9?S-6GV^Ob6vOtK2Pe`pezI)ozhB0~&=J*+K~9%I4PO5Jl-a>E-SuLwJsh z`!sIm5;xa5QeIx}B482qVC(*7+DrkG*({9#h!8uYd~LjjtwJeoaougG)5zK+v?)ba z1TQlh%>vkLE_c^Zt`R!!+evOyh+#FE<4PndQzZvxcMA7pn9V=)vNy#3->nC102TD6%D zYo#+7!xicc$_pg<&POk%O+?B;SK>UQ%T2sbUR)l7PsI5xjK#O~vPgjm{h;BR>HH3j zS1BuMY&E2$O4CuEd5{rREi1AB9S$>I;g$i7MK~9fyHl#%Vv`Lzter3hNYKHc1(|}Y z38n57T3n?&f&LY4K1s^pQ&O>ezaifhS$)Qqt!L~e-gB&DPUWW7Ykv5Hqe6o$_r&Gqe5SJ$55=i zTFzs}{p&l1USjF#3$S#)s-g$z?>wyR#;{;K$ZzHhf{_F8H$FN{dWlhm6$@ zt+(!IuiH`A(AvJEW@}qrd+ny0hK+UW)q!?9cTwI~UK9vx8@Dz#w{K`{-d5AvUSGAa zaxBkKN2HSx3#u5HXyUj^}E_@TbsAG zZ>nFvzOF&N)A~-*#$ZV)wzSqXw^EEIV0&#_OKamcNYLEUN&&p#s`@Ye{DlI%A;LEbUZbKu|Mmd9l znIRynG=WeO34enrJESOOYr6!;#`A=SrkRe2fNR#V>)VDFb?4b){4 z@pC306hyil-0$n{*l%@hi^XKjSce~h8$AV7fv@p&V&-UNR%?vR%wGn& zJKOnDAmrg7R_6{drqLR$&!hm^&8)PmyS;O7Jh`oPH9Jf`lPZd+feLJDgi-L5qU}RH z7j!EW!J>shUDaS$xp;{-wyoQW>bteR76wB9gyP@bwxive9t5;z&d)k^jzC3y&~L{e zoQze!t!880I%D^Y(8?B}jx5`on(JCx9t0b<*6qSy<4#J^w#}GE z|^v%9gawS56uBzrE5^WECmu+dWs^50Zf)9S^j z-CEPq(!Q~|v8@S}bwhi7!=}3CdJ~*bF3lU)EnBuM&a$Ppxe>+cTT%ZY7F;;*hN$rL z8oi)gHj1y$QB9U9KQA~T@fxPSc*$ZWzp=Rn%}RZ9`;NNi1aa!>8rruu*037;3f-1#3DE5 zo9I==q!YcCF-gB2+lSQ;qaAd`2RjDOW24&L+dZ66!cu3v@dM(U-7u}NqgA-RzJ)ev z`UdpieYjI$N#DK!3Pz#Y(BGT>gW~(zFfC7gLwiFV#uCjnwOdpVdVhQjZb%JwboD^b zwrA+>>+EhHGHdJ*)iw&oxDpi6P}5qEW*P~I{h;5iVIxSh@zjF&V#Oph{d#?C-L@8{ z47=(uqmBf&Y~5?NHf^e5grwHZSkcgd{=?KV79U9xZ%&)hr0#64X@aSsqPEy^6xTyd z7iF`7~YXHrWA8g7H$Sa#~WP4$EJQ684kXbMsmzNF=;VF8Cc{HCM&;LE1H1ka z^uNi?1S_r#=gp^{lQY@Yu%)4KXM-}+4#xKDm%{Cco&jrb)tO&|25rV4Fv)RWT7Wj0si?+~w;rSu)nLuZPK)kt#FIhO{4ZpziMTn6O`x zQbgMtw_(wtZJP;es%gg-^U~&X=)@K{F0L8rHP>x#qoKDxJHg3A0_VOJXL94y|hcpWN9dFu*){fDiRDRS~SenZVxbh^k-f^D0Dbiz2E zeIS-5xV9mif^z_6hR1tH_U^^Q75fucDon8^HSX&gceS@{s#)K-lhP%$73S;oCeG;Y zLlzZG8~nDRra6|TCAg{+FbXde0}VR~ROsvmhhzTO6h(oKE27ahm`!VwEQ)A5IQ69W=YU1~J1K|Xl*xj~!p&0>ocMP;2?Y5(MN+op!vRegX zxPyT~YkgybUnBPp_i--8i7lrOKB>28<9pa?l~-o4e2f>F2KDTcMBwdrg&*0iYd{8_`j>hr3M!GP;Lt_Qu5hgFX9u`p_H8YJ#bGrkgY?bJC-t z8gTGT?NQ2sPLn^sd1!>SnT3NL^)2*hK9m7i1+uyf8#;On)W7D9# zNnc=YU<=$XJ<6)1UzGI?Ep=EKgam$z<*ma(h+uhgRsb(QCRD(Fw5=gNP50Gf`b}^0 zA8++g{@zg3pGjCNHxpO;h=bLJO>6{1BTh#;l)1Z&`M`nh!MMd>Z$C)HRYJ2wbqEik zVFZn3L@ovln7OUZJG!i<=EhpABvJmrJl)oGzjJN(jLGZ2hWb#Aj#y=P^^ed}6B*Q^ zJF!a_e&#X%Z^X#P&P;98gtp7mwXsq5SzZ^Gpl;KHqe6CI{C9+jHk$5=G#nN%*v#}3 z3IvNd(*Gt(S<}|qh=l=}(~k@f_X}gQpFOwGl?1T1jsz0gd^6oZzt@ScNJvOLO>g{; zZU-E^mIW&$cGWM~8-uT%T}ji2l4C}C%{+CC4#Teh+2v(VyhWpz{u_2I2y`lT9d%300XArsjw6)g9Y9QoRXnbHk2>b`=s4u$?v?!*~cLIWTL z4o0J!>IRIrM$kf=KHFAjv0{JL1!J(afKMxN0${8Ky%sumiaD$f55h{}>-R6TOMlwz z8OUN|AbwS>S-%7KPFlUG3LZ3S??pGm;Vjl;FmLXMyDy=#A62H0V14jbj&aALxqXqB z#1fN)->!Iz(|&KUwZ5Sa?K2o84-yc-9AL5z*?GlMKm*PNJFJJB5|%YO+YNh3F0E9< z9X+O^*mPSkN=RIGPfn|5cW^;9aNEhh6GUTJR;dnqcibQk^@C2+-hg5Agl^4iTgv z(O(Db>FYxeVHQ&Dcu8?kPTk6AVlNadn&!ft=d0L$np-C{fc?0G!hX}YEfk7B-$FrJ zrPnv?z~b(D-khjGJ2OTJZ>YETMiT0hoq@(zc#Kj!(~@z-&id9(V2W9R?JrE{p3rGv zAc@c?m<5t*i zjK?nrxn<@XvKbiFH0-9#@v#PV$#@t)V$9cd?g;L#%A~YoA4Zh{v-gYL&gH;njP8hQ z7-$RY&CO4*ma_fX*E5KzxHo#D5W&V-?$4M4^@nVJR!jxr4Yzo&o!IKwR@k!^(-4{7 zF4)+&Ha0QU#E4b&vUUrhn*xo+UJR1rfilVE-AD33n=pC=AoosL;NDGJpZO+^oN>E@ zw-tTQc(ypYh4*NiH3J8`w&)9P#g!Ey#PU~9F`n8s_5hss^f~`C>Njg&Y}eJk-jSgL zZ?jy?rO0?|Y0@;KLYq46)}Ih1X2>*j%uq)s+YZxnfPy-!r52b`V~e$I%`J8vb+jE} z+Ev%Q1NSv;F^;haE8&Z5+soD3u5K&>j&$NJisTuiJQrY^Lp+2KY{J;UK^OS^mn`Tb z&}fNkC1&NqRNJ5-CEm31R_*-u7YX{5UKK=)t=2Tx`hgX^G(JX)zujZLNihR(wxnZ4^`*9^@3h}|n?v=0;8HUU}%r-T-+ zZTAjS2NFE%tFS=i=h_;(NowH0(ZHIVPqC$Lx5A`_L-RhY>-s&4KR+DtCWwgQ4;i>D z3%A^dlYRz9+_8U1c~e3X_%&r`{d%^viLHZpnq}mKDS|9Vs*Sa^D`K;21`ozKKyLNk zxv|6K=I-7FvDxcJpsW~QzromfVbz>D$zy1~uf!Mh-ok+g1TW0OekI;3Sq$5QvnDI& z^6+uziqLgB;hU&@rK={Z;PS|E_loe9&Q%QeUf)8H*;=MHD|(#%)9E3{#X#^p9=^i4 z5@BbhJ^Jl$J(#6xxeG!tKIK>^@q;q)Rk6CP@NvBfv2X;#7{7*L>qduFo3MiG^!BXq zx<|7TWa1uQ>#}BFo_0L-is+RoS4B>^SBI~0-b>kMBc6A>ii^6eg5!}Z+$+OZIVTVv zIy>#rhaWOoSeH&+dPf)+|F`a7-de#gpf^>s0v=|WLSffBrQD@uHP|yKr6#IVLuq(I zGdG-%9p@%G1=z5-NEhoV;Zi+a&(-UZ*`y=r6IL(36%5AH+Ce8?fH2Po`+g2zi3l8y z3iGu96KfAJ1a}M=Kd71b;n>#=eGdmuz)$mCyucIjfy2S85V3$8d-AB6a8pX!WQeay z1P({hvf_t>Qc2_=EG52;mzBgn%j}p+{!KVT2xt6FK1*YUzRTge4}rtMYYd6$;kAaq z;ovodSip^~d(@e5Gdl|&O_F*uRyEN#iGm_kFE#rry z&W<~9<*4=~cSn-DGs)eZHnCoPA6#cC9=r?rP(nt^Os6{&orHI4l?K;Wv`Pf1BifGs&ImfUz8uwvhUk~(GD zzl35YZQ#NDWH!FF$hwDl&d^)fP9_fCpGH`MqL|JY${cHEji~-ZX}C@x@$?k9+X9mK zJ%EHX<8LV>cvBSKq#H}bKq+~T>oEO<#csso4Q~;R-0WKj;z3$2HUtS0o}C~=#xkDf zPIiEm+-T-1oVmqAF21eMBKcT>y^EO~@;1e2%sB8UYI3wOi#Q?4Q55FJLNcG^<*@{v z8_CU`Qv2=&B2x`^i5UF_+Q777Y?3Rul{kVw9N5Uy9*1muoQArLlCAAvjVQjzyE8!vRZAyaeNdGi1r^FQSZ<5F{(86NOw z-!O%NIOfi=NPi}gb^^PX0z;UtR0>uJE)%3&p)PzX2I%vtfP)A4Pz2^@E)nuq6Cw0w zBJy`Y+^30Aptv2)Q4m`@Q%G1rf^rz2F-}@QtGLq<=mUZjP_gu7&)>>+A$BAj!kLVt{uU6_=U}&HH_(urS7|MMH@c?}kK)Z|yvb@qx;}6H&c8gv*AqZeJ zg4lP#xGxvHUhw0BpBDU@;KPDH5&W&-Yl8eX3FY8tf{D`vD+E^xZWP=l$c@ZNf4<f-eaEMUdln^5;jqh$VvMg8a4y{rT+^Vw>Pz!2!XG1^LNI z((yYN#7_x+QSbr5?+J1|PP*R-zAC6;==9GLoFq6~aEahL!3M!I1rG?02wo=me!-K1 z|0>AuM=-r_3O*+IwBYlCuM0Y^rOy%M7x5UMeHL-4V4Yx#;9kK#!7BxC5WHFNbAn$J z{I=lZg1-`cS@2E4)QC-gg5Wg4O2O5Fn+10Yb_os%@}n2b#|H#Y3-W`b^#2dRrv#rD zd|lAN(lP0B1m_Aa5v&z#6YLP|6MT>03BeBuep2vG!TSXNQ}D-vzZQH+@J+#VG@O)c zvfv!SC4#krO@jPF0O_w0{4c>@2)-ehooeaE3r-R&5u7DhCb&p&x!_vCI>9Z1+XZ(D z?h_mmyiV{_f}a!oqTtsA`Pn$;<6DB?6?{zaCxTB4{#x*P!9NMUCipi&oo4x_2xbcA z2^I=Y6`UbBPjG?YQo+@NwSx76{8RzuZxcLIaIfGY!4C+2MetjKj|=`n5SzakekFn% z1kV@zq#(cP%5)zP{GQ+wf`1U?_MN255X==U5S%KwTCi5IUa(QHP4G;?4#E9`eS%jB zUMqNm;70{d3En378Ns^*zbp8d;7N%4x8a;3ibADQf-eZZESQT40pnK-ZV+q~+$Go{c&^}(;Dv%$2%Z%Dq~INbpBMa+ z;5~v52!31e5y2k{J|Xx^!RG}3B>1}En}T7?X_=pN!F<8Vf-?mx1eXcc2yPZ^5j;z< zTd+^?u;4MlYXmY15W5Q?hC735TOR!3?QE-po zPXwP9{I%ep1>Y2O##{cWg4u%O1t$qs5--Oy8scsy?!(9a#C=%sCc(P|9~OK@@GZd^ zn1~wt6Wk$qK=7#Gje`Fs_$|RF1^IPb@|iHv;(S4V+K2wT1cwE$5j-vUWx+=TeNh8TJS=!Q5p#$Siu>b4$bGZm?c&dGmeK!i!LJh$@0-LvrG6;>{Gc@H zo|5q23jRs(FGS?;Eh5HH6S3ex`bmQG1SEsJe7Az5*Nd$epU;`2H&XMrFg69eL z3my@?Q1A-Ds|Bwkg3nFj{uja1M5OmM!S4zFO7PEu(aE60n6Hos`ZB>9!JUEwf|m>4 zEO-|Y`ujQ&>t{bD(hdcGDdE2t_e+AWi9Z)cNgo!>6`UYAQ;=)8q^lqzon?Ys14I~J(8nTiFBM!R z{u{)-S#YP|nSy(Wh<~oQ`vix?{~~c;DtILk`MrUNcpn%4n+0ztBK!ftp9sDvh>aIb z_*B7a!7~K=1P=?oSMZeJ7X^PJ__|XCIzgO^j z@&A~(KOuOF_LXKrb$XQJU-%Uj14=OkL-$g`u?jdfl_d%)u0lGnS zgotuFMnpNDAfj9`WHEM%VT_57Cd}Xp@vkPrPB#)E*ES;LY9T_d-9*R*Rz@yU44sdF5FytUM9B4CBINo25pvx`1hci&D{SCRBGUg5^@j9+Pel4xz>n$Q zNksZ@5uukQ89=0e6A|gxWdV`?_1QqA|9RpTe3G7s^j{z%{b&vl>CYr0eM}=&=zM$M znsQW%yNZak5Y>dY5+TX-Bf)nj_H*`j52z)lO)b1F?HI|wE4`7xf2PHI z4>md3(F9|pH8zn+AozHUJcyK>#8@O_B=UA-qmto6Mbwnp`b@o3YDtvulIR%JW2PN= z0O{Ql50d@^sV9(QN8RC$@}O2IpkEZ;lWMGL3(6M+>eIVMc~_l{O2l$cs&W57I)h_p zBJc#=yNe$nepkU0X#W9)C(@4=Ht=-lI|~{hd`BS@=-x%Z1lpt~F{pd<(3$_ZoM~6z zp`?NTS#Na zP_~4p4&SNO8BP2yRyIZiTMq&cOqWYN4mLI7tF)F=%0MdkZ;bTktu|dSX zevAgpb;sVleEm8Qik(QgRh)Q=$|5VjCT*tU_MU5{YRYM;mLC?Jc9gg1wYPNymXi@`Q3>#n2&2b z!Qs!tb3Sda{d~L+0gTTyczF5v8Lorr{&yfB8A8W+OAw#DJv-pI7{g}&@c2dGALN&D zxlNb(z*NJeOMZM#l>EH>KTAj8@SJ>p4?jO2q+@*Y;^C#c3;w}$^O3Gs9+-ak>3+`g z^Yih0xGy%G?4Kvki6nm0!7m09<^#9re15kGKQG?7-UVoQAlMvyju1aTAHASsKFEuQ zmyZWQ6wJr^Kt6EG%TG54@yXjOk72km?ehCSQLB0jD{dlK5Q+eoUA7z!JaD zk9r_KFCL$p3?5!SK56Ove0&LR@*^)EUOqkn|6o3j2l5dUI>!5(<>!~jy>REl-#g$m z$0JGnZVcq36cnCbUItw-A6%ab9$r3Tj-m7OK|0DqUOc>f6oW39kCTCX%n&-p+hX~t zg^Y~jr{Kpn(L0zf&%1=qv%mFlS9?T2FWn2_A58bNm)o_P1E85LbWHaS;fLhRaUAa8 z;pO)kOXug8bc|14JiK(d{uWI4*~{bY!91a3yc|RzZ!f=G&%@6@y!@UgbY6b12NB<` z^A0cFmAD9|`zq4C9z+Llmg6KH)9ny`UVb0;7$A&?$NB@7&d)FD7@xd&c+sxKMKImt z$K&~3Aasn!^~7L)zYq6V`Q`Jkr1SFoIOtx5+dJSi$FsNyrhDUYyLQI>R^cQa(~Sr} zKfiDX4==w9EnPgna5Fx6@$k|uhkr2L;w$3$#d46JZkOff=i~cudpyX`ljjVf^W1zM zH+XpRov?Jie59j%%Z1qEeH{Kl`Q~2{mv1F#J-ys(`T6oa1-Hk8EIoPd5<1WQ3%G-a zC*LnEoi88hDBo%!_IN)H|Db%Uu87OG7POvxeBL-{2hSm%$Ac_Ac`}5~bN?Q6!NZep zm8J9LBOT?d5n_+`GSCI(+ZvFs7POvxgGute`Zn?%NRsc3w~_A?N%E17^3^5D_pv1T z&blJ5KaMp$`JPCUj|J`Jkt{uZeP8H2cNp&A;pva-`MCD=M>@(^FT@`22kY_< zT3(9l%LFdh)r*9Qk^Bc@X@j!|fd&KMlHIxjhxo^9~Su{H6&%FaC4jw||D`vT4yZ zHHqJ=;CBKAcK~6#aC-bIlK3@ZV)bvHP@wblSCd5d_ewk?gnJI&;nA&5O83G~C{>Nj zGu<UsUmHr)fD z1-2TqS4@0T$S)Mk!*VemuK!~tL!&l{5H zDsV4iL!8W~J1ulx&=Jsml?>!yx;##TE|}l5J_%3I9RPIW^yK>-=rA4_fR{Ncv0A|X z$~!#PM9-EP)(g5A?4SqN!#K&0YGRtf@x}Wt!u;103Sk~U&e4K&XWfFa3S{vPkFKI> zVb$VT{8+HGs%lZ?f~AYAVlix1Um5scQU$+-mDsn|9DC9(!N!YPdz_f|Y(IUbv&S{5 zxpu5E8}etHSM>0?RU>iej|iV!hQAvOAvoyBBe>K$dYBM$pEZ#3HA2|E#z4v>LewzV z(Ud)KIboMuujz0K=dn5({wYC6Q8@vjF9MXFuF})jq?-ri$LSeadAOXEl`|2sC4}n9 z$7#zUpj7xZ;&e=}5Ym6k$^=)Fab#Y<(^vA$w~_rf#Ig1|OAKcV6h9pE#&^(-o7I7X zdzmG?p&zdUW_%JtKbr~q5ZLAla$Sb*A|fhfiMVGA;&!zOUn0n{IO*35ay&+Nv)~@V z{epdhBZ3gY-24Bh??L|~3)1*toLzjj#BaaI%o_&(Z>=e_&kfol+xZJ{dWRQ=p-)0z zS&gRk1pHX;Y-M?}?Zr?af#2uho{7^tJbn%E@U9v5I8F?~{KE^|3?G<*s+JIMuFrHa z%=FXcc*l!F(%<83;e{MtSP$I1_Qo1(;keBUlrTDnljxpBhceb!16?=!Xn$-l7mj~q zY;XW{4sze`JH_tEQ!uE*FY$iKVgpoD$1LmCoJ}GO6l>@LZ&#N}0mK4GV-rklXAH zVG}F0UQL@;>dB}|?|bfz>S+wQU)}Gim$vR5pNW3q*gxE_%RaK$5V`*_I(P1KTegN@ zEs3pJ9jlDZoEfuT=5ZMMElBoT1;2%=20QfPdj!~YbvV|2#M~Ujezz-PGlpXIefXk9 zPnTf?kFK&AU1~-bLLhME-B;X64OmU_>iWNgV&M%fQ=YsleO~6zoDbeq>YQ+5nf0L? zGPh`)3Mc9Q{yR^bH~uA5nYuZxUaxF^V_IeD3HQ$Xo~x{m>t`9#!EoC@PRrGu{~A8l z*L}FFJR!TrCo#7HFPmAcuRs6RMoMw1v5biMPci?;kGLn0htuJg-&)rG*As7i_2u;J zjGs;3GF&>j-idwh`Oq2qhGOKRSaP9CDowmg>n1;T&&xVH^?vu|w-z`4^~9^6yDMXQ z>4rHQmYHxZbb3|Rmae<9>gR4~d1HEI7T`E>-4(rGPyfa5 z;`T9S{y*;=(;IT`b~Z65VUtR1L(YAkqVBx&j$`&IDF5*!^Jx-{1=;rmo?6=6(Ko_x zCT{57J7_Mp@jDZ$1{*x}s%;%d)#ef01Km8*dsNko?8g@7s-=5ixclH<>}uYK4WWq* z{fDf_`tDA9;f-(0tc{i#8x`T$uCu*iJ2V+*2~M`@Tr=jH0o(lbIJe;(>);%{OQ{&? zdHe{^&w2BQDL0@tO@0gm4!+&Vme4z*(UeEg=tjdSYa^h?&cS%-ZDKWoqdM|ogt$-R zIyA3<&3sfx3&A5Aa`}*^`westq2+}K84^mFNw2@tYg@rFdWGHDXnx%&QVcZ~-e9~^ zP9T+N)a664Q|(m5eHsK#elGh&_jL&E6y$B>^$!u-nV#Rl>v2fdnV-l0!refc%KWQv z9ScXJ;bEkir72%{32y@G*;J$c3L1K?TrT&7S2%xQ%*T;5M^^ak8uxyt-BO| z;k~it^yNc*B^O~fIo+Ka{WTovQ8063#Vyfl7-XPKyG)MaYWPWnfsX; ze0Vn_y^x75&UhA(lg@QBcS-IzFvw3o23g&unU5f(AbleW!d+$@#W{NszMPY>kkUDS z0j@BPkj{At;;f`2C#-Ykfov5WIv<%EM?w0E|HQof0ns)KF;#fTcJ8fxz{6+ zloby57)hfBZLH`tT8jP{hY*_2*=l_~@)pv3=i1Q+sdhb`Syyf|1d7gex)DJl&;L0i zPeWX#Z|0wV0!0_r9F#^iU-Qk-Gr_{uDezC#oe(G!ibD#~#SU+$rLm;as_>V~qH$PQ z&K~@!wAb*T%TlqPFB;D@xZU?b+SJK8^KhM3iN9QKOyU@VtZ*6Prk1{dTBFT6qP_|$ z(%QU(uU~-`IQm-TGpyUe#nu0gs1eOKc~kTt#E9w?YM=88+ z2Yr^_3sq$6Zm2Xz{~g@M=~+l6S3iwddHMOzwGePIU6esHAh*hAAk#3=$ z18zn7MQCD@=Ke6ndOj<<-icUK^!p*hRQ*MS#`J~oFVS~{PpQrZhiQ5_{-^8n;4?!% zivO892kFkzTpygR8=>|&dMo(P)!)YdJiQ4i&evhcS*ABbwsOs#4lDGt2(8rIRbheN z1fPZaCFFFGz7^M1+JRJyHQ&KrqFKY2>fb;c%k(XvS*}@lD>QdjSgG^CXO%u18d$9( zNNbIrj96>+G*DLS41Eta#rxC0|8Py0^PR1XZ zXgFg98<=Ru_vo3Eu>i@cSjJ}_c{Ngd*>;7vae5Cc277zGg3SB9GXMSmfvSqFTA% zgG$qnIeb34@T2fee}c86Faow2MZBCA&YYUs2$9oye>O9g^#GGekHIIiB;yVyIUSE3 zsmxO2K-K>`Vr5Qqrhp=w5pC_ws(df5br0p$cR(RpKL)~({yd7%(YHd5FbW8ewZvgn znvqBPnG;x1VdiWW?}kr)8C>aV<|#zh<>POIm!(MII&$`kpTfi0Lp^1-L;KmwGU)hU z^o`f{l*0(htj~g`4Xr~fFn=nggd%j!@Pn9ek;?of#LT(MFyoB|$NW8lXew_etfZ;3t& zMt9NIG&`AtxExoW$xiGC^ko(uHbM>wRmyMSnY;TBeh}q!jIb$>ARo~)9I&;qzQhQV zJ_4g(=S=Z^*|XXfyZ7 zu@TsjIsTtY`8F~ctv}NbXJ4gK2BFuS?(=QbLK;_C%!;yDOlT{P@Y z!-4wFF$i;E>iYzhO(l(A3I+5q_yL^yt*}&5uwRg9U8EieR08hnG?A0VEqx?zM)? zBcS*WPG7k_DCDHPf#P1ONxJpNb-zI*C;m4w-?q9Kf$+{nYTiqib zOCgG)1Z0G;oD}AWi6xPaoUoJ+QT4h~g$EJ9wsM{X9A*GxqI`!Dk!w+mxIQ5wijdvz zSVc%(nIgPXuu-R~-ALm{APCuUW{aA!FtGx(e+nj+) zZaFZ7Mck}cNFL4w4IA_sK^hFm!UG6kC$L-sXbnf;$3CMufq0P$Uxom7F#`z!&{H#W zd<{a`H(i|&xc21lS&Ey61wu zdI&VkBQ%G^W-BMFnC(S9UTC|x0A=E;`aH1Pq%YE!G6F{>feP#OcbcRGs6fj9C z*J}$Uq$Dz{a8)6xqwyPlsa1?vqHWC3#IJB$leBD=UJ@pw^vnR?Wso7ma7GWE8Q`2g ztFS)Lvd#+YH6 z*7YV+`6Y-}fkelbYfs3M%vpuwbZ(@&-~vND!G(n;%RiBdxl9*cg0u^e!BGT-Cf8I~ z$&&iKwNMNC1}Iidl3bPKt#p^i6;@38`n;;b5Qwl*qbCirDJq*1zj4|&ah&GO)2Z>B zr!goL`6$UlKGM@|IZ-jCGm+-BJRS7Iycq&ZQBvhIs?~*>o-qH2=D-_~jLJ#QVl)xyE)^V+O zhfnA)1HgetgtbK^xmfQAU#9QWnoTE<$OQaJ;1RtueBr0H-f2VFHHR@}ZVFdcSwS@V zCe$_aAHRY-!iRRkD(tr15V|204zG&h;*1;g4LZDPT`I0uoidJfo1*^prp7H2_n%$eaENd=44f-x+Dy}odZLe6LgvRVZ{ zn6L>kfWK$u;)vh_f;3I{_%P4+_|~A zS(~J3nx^ednx^TN+;mM>vbSl|CQZ`~3TfJ;w2-DTNufo7%31`mEFx-=MZ|)D1wldK zwIU+2i5mhcg8H+98=F{{7k=OG^PHJG_cjGw-rxK2|M}17&YU^VbIy6rbDm|MnLBe1 zLM;qdZtp`V_uk%0BGZT5@Nm=d7wN9um5d43x3jNjI>VfUbW86ph}_Yo|3CIc75$$s zac~bl9P-NV-M+c^j8l6n5!1P+vZA7L$M(T3$H_iUvdcxdb!XoYA-@N9)87XhqJi$* zg)pjgk3S4KeC^}Qtiek6u{E5%4~Wdl!=4uFXBY?~-pE;wQc@ zko3P7W-fj%*0rk_Q5p91_Y78S z0znm87Fx8(DPVqRd8i^3JGI4NNF1-JHnbS_MNXkkSajm4E!!Z!(s8CQ#A_N##TB>$ zh?9%V5zgq!3bH$6wCI>KiLla{q>Dx*$e>zg%E!?T?dOrHf#^t$>Wq@^w)q&S=A@%cOvkTqjkRUKz@B3dW)8p_nci>uT0qmwaBlUyf+74UH|09SG{p z;GqKyn%c#9p9x`7<6%e>B9zuItzEgKQAgQLAorrGdPOnRZ{zBv34ug)=;+$I7GLn* zwW~L*tWPW*1+H1KGOj>8d~R(+gDKlY&qY{l1QIr(!Wp^ND;q)BJ9QLxL=V~3uRk#L z@`j14?FBkztktHL)^(k0n^!keO&OH>Q&%q}c1Pp-j!wkpUa}IAh?_d%#UjdZTYGDL z<7!`o-{jD>dc^DSCVWxO1fVwm-fFJ|T33{6{>o+WTpdWooj7!WTT|1P+PcP;PA%R9 z-Hz*_4dx4!uEVP9(7ueM150=n)@_J@>MI-9A=-3p{c_6$|JmNRt!H36{Al!Qde__t zyu2C>AXXXZ*?~WUO)Qt5?l`q4-RQ;m#wdbOXXEcA@|{4e2Kw+Of_?|lYo4SC(QYj2 z+J?2AXjR>)aVg%*j1-qFV%3_))w*#!eRPar-TgcZ4_SPxz>;|9TC&LUxOD7j7#ha$ zidfyTfibS*gF(VM*SEK}v~)@sYEQxvD6*!#5ut?Ze4UC;8FYvn6UWArofy>IOKxag z1LjUQPVz3OSvALW1z(4(UDMI(Q?tIku@SwrwU*-smG=6P|GFwsW{}OWJ@EqDYu9zM z7ct4JOH1vB)-}nofF)4}nfCR|b?vn}R=6=vVwmp#&=*2I>!5GDrtS1%!<&jqb0?S$ zlSM0ffH4$Xg3ApP!N|0sXW)cE!#Lj{_63yE%Mbb-=s}z^e`_^1wbmnIdxOQm>1O)S z*-3&EXW#nTmGzA+mY#s9Z+uQSlW?bQ!sKD*>u-oqzf=!0Q}x=G7Eg?sAy>E6);D(6 zwzsZXi5|!|jgzGrPPbqC`3+oLjh?%Yzvu-o@qKMw4 zE`du@t-f5xn^vw2dPR-k@OY8yjCh%dB)0vm9xML#wO2MK@U_}><}wry02W^(dok3& z6z@Cl9>zX?!Qs^B^*>%VwA;-> zbPx0gNYe&)1JIL-3CS}B1ajtDvyztunY*BAd|{%ermZ{l$nq&CS2gM8%_qhOj?|ME zG;`;%8Gbr;;D)~w?>FlC$ZO<;p@Jnrhj&3stTmoYrL+xf$Ny6glb5l9>czl zRo}R>1J^mvIxV&S!Rjp=+~)AsP1K5sGAZMk6Lj>X=!GO#>RP~R^w)Tve^HJ*mo{8b znCa8WT(;^OJJw;WFwbiXcRX@YJ6uL1)o-ph*E;zQM#n$Yc1!GMUfnwD8kZPxzLDS1 z+F|L(0iFGFljAP<;>xV7ZEJHc>Bp$gq1wV5B)7YpTP5A|eRk4g%iK$Osr9@S!UDGu ztKRM&cLL;;9VgLqpl=PV%h$J0zQu$8#?ZHJNN#hnYRA%c+X2icYyqC6}z% z0Sy@JLkTy33G*8US^V+j@Lx4~V$JwnSBslRGl-Mks^yY9(RTViT3=7S0mm5^7v3|) z%bM4%v|U&^uBiM*G4m;Im2ubG(Ts(PYf-!#;LTt01~+#YD_U1z(5zXJ&;j)l%B*vA zm!Q71jH_FsF49KrD8GHRZ*2IikbH%dM)LZqQN5$Rxy^UcgE^D6ZC#mYqr{sJ6W`Tq z1wC%P6*cU#rlq5^b-91^>)~Yab??L~x#nf6(M@hlJd<_}_Q>6iN79V$zZMO$x>3&o zQlLB~NU*O|e_eCOQY>gu7$(H7ZoCtXo*KWvna;`trn|P+cl`c-@$dPvj1TbM!G`Bj zAIiiF0_A+VFB|_EsLd=mKXid}VelgR;=tu9(DT%{ANkh9-{c=z3ExZe--FuB^b70@ zK~-JY3V_tdu@)^z;W!QBqyq%JddLHNRyi$WJW`+}F)AEDg(NM^L|smH$aD8*-5 zb$Fg><+)6N{5PU5GkgJPt$*j&aNa*zkpJ)h7S7S%sIv^(GJt2YQvu_fqy2{b&`WTv zDx8!4F!li6e6Il{PWuMA*UrzB251f75aNpV`>XWAVH+ej1miZ^p zynnAyo6V9J15^oL>hrH3yoKT0Y%|;JOEZ^UwsBeB!dHI??PQ|}Q5M!zCo zF8TRILwvJg&qRIsr)qq&t!PqyG@gkwJHf*O@zSLHiAngRBz$rbp4b|;emO5rVq2AQ z1ZQ@Vb~bwR***%kHea1`H{zdn5kTS(CgD#d;lE45-$=sofZp3EkMFX%8*%zMb2s9P zlJHeYcy|&$l!RZJgnvE>e;^6xn{)2Q@?S{8|CEIDRa$o=J>!|W8}Sp8@MTH(Nl7?g z3UfE|e-t>2-Mr@?qxLbo=L8)$1M7J!SxcoNZ^SJMj!7m_oc{93R5n3%EETc zZ99wf-BA0an+1s^B-|58n*UKbl9Hdk#P7YmyI9v6!`>VEiazEUfM(!ruSe7;pMc>; zK!1eZxvTF?+>mx|>F>vbBW-tc3#A_)BtEYZA$7ban|vr^>)FlxL+9FF2VSS%r$dbq#Ezq z5uaz)Op*D&{~OLh~J41TQ()5npUxZjRu^=XT;XmURkYtz~T`1W_+xz4=x+ z(qMchMjG*UEz_GM9y`jphB(T(fpCds-A)KO_YgwPVZnb07{Fi3&l2LVR$Uv)^YbMB9hMjOZUW+Ac!FMf$D=e#qaHVB!0u11y-7RpNK-MFG%TPZd zEoc)FAQGulbk)+e72?Vg{AD`_INQuh{6R*Gvh=emaw;M=15icafVzY#BhI!?l z=`qQlEf8Hy(=QdcR^Z73Hw)|+$d}S7=X`6W6)=!~Jc*AMI91?6fpr3x3S230jlcncy9LreC*@rr@FN2E3;cw@FABU@;MW9x zL*TasJ}K}A0-qE3qQIza%Hua|EO({A4uK~M+$3A@ay>H)L+s+B9Q(Y zDgPRQ2L#?E@Swmu1>Pg@s{#)Td_>?A0>3ZtS%LId$#Q-r@D+it3Vci8-vtIRut*;k zsNr)|cu3%v1wJ6~A%Twyd`jRC1wJqEC4s*c_-BDxxR%fkBL$8T zSS)ao!07^K3Y;hK1c6NgR|xD7c#^=)0=En77kH+?a|B*2ke}>QuTKiRN#GX*-XoA- zx{>Y?f!`JQtU&sAWd17x-w^oU0(G2t6Zz9BO$IgUl#nEgt%@!D)@5(-xSENTPdI4qZ2j>>=k&i!0QC^yG+vkK;Rz)@{1p) z^ZP?Wezr-tTws^LO9kF2@IHax5y+1+$@eFL*{KFE6WAnhqrd@y{0=UFi>8jpj@!>G zi35H@@^2LUa{_OZ^m_!qPvC=+{%yf^oOZ~0TGF2h||u5QCznL-$z&pdkg%uKpjUM={FMxJwI0C{Pd{c zBe;G;f3FZ&BXE_#9RklHM7w`Vpk9vy|B>K-6gYtv{g3B8j13{ERCOz@S& z3hKusz91_9$&pz2&jY3!{Tu*5KgS_-H|BBUyufoz3wpy)PuN^KED`jxf%l@D20HTK zmR)a@hb5G^F^@avQ$o&b-0+A={|BWJ955~EZ5fVO%IJBB35VyKXF!yXDNEB){ub<% zhv`ypQ6j$0MK3}c&OJZUq$59NadXQ(59j`Juf;PeOnZpj+Rkk+|C>0(8rL9OwRW52D;nNTYmQ{=9O3hjYqx>&yFd|HeFSqi}+sS6|Xm zZ_484mdoc9{&K@;5VyX#Bzxs9HuAjswn5$;Ey)~^t@S!r=-m49dUn`H=a$QOE&g%~ zP%iDl`tq9W+Ig4AbF0bwegDRCxm|1M;`Id`>q}YO+;Xo@DtEuHzIj4NzTZl@Zavx{ zkJnyzbLD*{N!|^RM>^IcAG=$Rmqeahk8Q`P$4C%>)T;;Ss1IdvbIaxbFMj*o=c@-U z&tAD)XF#6UU-}^rOCN7z9=G*LbmxK&U%`5tOLw}^x&5BcMYtw#H_~zE^B_V1y#=9o zOwI}1dYlCUe?1;WJvJeq^3A84rv9Hwk~a$iNhg-%FBLh0fH2G@Khdk!H zo0}H`onOCeAukFd%A1Vcl{YR)-o21VUs>+v%A?aSzr6c=@}~OaO%Zu+U;5a1co%U8 zIp`>l`|KpTk}At;Lb|)TbahGkZ3EpsE)gK>!EJGpe$PU`8l0Ai(ci@zqjwx7GAV*N#(Vly=xwN;*8jg*%2IO@i3Ez89Y?+ z5W}Hr9uL(#%;jMY59FvKM-@4$$WcX(Dssfg5hF*895Hgl$Ppt)j2tm?#K;kgMXKh_ zo5w>n4|92#!^3PIX7MnShZ#In@j#Aha#WL}njF>Ss3u1>IjYG~O^#}ERFh*aIp&gM zE;;6sV=g)7l4CA8=8|JBIp&gM4mswKV-7jykYf%x=8$6!Ip&aK4mswKV>UTvlVdhH zW|Lz!IcAe%HaTXKV>UTvlVcV+W|3nSIcAY#7CB~-V-`7Pkz*D)W|3niIcAb$COKx3 zV-mJ-kD7kO7fbGUtN{pKR3%qks%c2O-lRBjWp9^t~G&@ z0O2#Y{}`XS{&yaz)1gDR?d`vp9C2^7R&h`~^BNzo^}D-^1G{4jmeFFe#{Qv)>*sb6=?s=n8h#L_{pdsZy?n#=-<#Q#w#*VQ$9wNe#W`yoY-+oUFbc26 zgsefou0j8Uth>9>-tK?&u8-I5ft~%`JJ0NMX@-N{xYXg*MEna5e=&IQ;`(hJ{U~Pi zv0K9Uw;aptbRTOlwb<~uLyCmDt=p2R45xcp~pZiep^#i`1_EN5^z$m`V5_n z)rR#UDXBghYt0V8w51==VG~ zep^HQ<4XLth8{z);WSFeaE14#rS=j#>>gI42u5Q9ol<)tNZL z-^OoIG(5Qene0n=zM*hBh|=jkF}DYov(T$31s+`MnK}c9qEsZ%gX`~sq&^5S@ZidI zp_RHF27m|Gj{ym$YIkZAG!jm|9irjE^=9Oxr*gpy53YXz$WHBI&YYYqaP$2#FN;>=$I&euplWzI~&C7TF5xMm&#*+L@p;2NSgD|m4I3lejC z*pesXEVwTkL3-|=QE+4o&d`8OC^tP%p9daB^&+gkF+spF`(ah|Gn!e|**=tf8g&9x>F@xP8Sig%ht>c`Mz zteS(|aq4;KHeTI}+^BjT>BZ_U$SF~Gq4Wvr0OXXavyn1Uy#T|OsZXNBNop?A%hlCL znXJA9`BUIwmmXB#g3M{^LCBo0@<3Uk4nt<8`Vr1!>J6kzmU!n zGY><8m3k{uBH}L;-q8105!YX6s25z33HCLhNGIdS8XVGQP+0M$I8_tH2k0oS?xu5e zjVeP8DtK119B1k0s!#!JY4c!3_&_A>TngFF7<{IChChRkk%1~NAdzsczBKzMis@RZN$a_2EimmB^T#Aa1wa0cDLRNBPm2(+o7mDYi>LMQI@vh-a^xCTw1 zwJPUoBy%@hwl|p6kpm}q)|Y9f`BS3pC%)*mGveR{3uSWP1x0eEocB( z@uTIm;sWH&#_oIt6V1nTop|-xz$996zfKwix&wO#K6bON%;X5T3@BeC%ILPP)@Ho{ z$N}uyhM&|nyay;Rb=roX(l-1)(1)3H6STOlfRn;ZluVbg+Px-in2Id%bQh$dIM~Me z()i?s1C-7mjm?a?Xiz$Mba~4`M-y&{)8%hM8i%}<^&!;m9GvI}Nb0}|=nSyRIg@FX zqfqO0?Aj`OwFwHr1jlm5Dj(KKF`!ehYpa~EtZ|{0*B%e8pj%)4ueXh zzWdWNlQZ3IDEt=e+5G6HX9-8n6F?uvuG{={UAs4dzRDyHlbt$A_gIM517Jue6#*^4 zuH6{2mp>v34IwQL8gTgk+)IPoM0V~XWN@N5nw(LB3{EcTXdJg0ry%WbP`DyjjOe*$i*P!jCi`AP{A{0gA{qLuSiZ2Eb@S#7+!B-DJ!@h2NwCQ z#7v|@Wq*;IkisIlE--Dx>Z8bBWKco~?P6+)4A=3aNPw9N`1kNU(1GSSo+nGs!la^> zg2w#mp$?43^=kwjp)Os(hOI`{H0&cTKv_%MI9>DF-iKXJoXd49(r@{#Olrj}(vkZt zr14dodzkbAjDt0rieBLlW7nR9dHFpo`s)@^G1T5v!gN_u{6JIaHjhFm+$35@yhI7^I2a;JpCc|4EF6ht@hhM zk7Czdl#75prZm^!eovcaoNu^>Fxmi7@5j@ocE6b9FcY2z#mT02znK#EuNh8uzG&QJ zrY8H<^ts&hal}1PrW+TU87Tc2Z>}_U(KxJ`^?N9&S&O`;k;Vr4Cl==*Y(($ z=X&fM>A9qgyVK04`$_S^i4~vgF|&9i-HI0Y9CX5+ryFw6^_*E4_nbM#c+Mg8&mnIn82M<*s``Q2%jdG0j% zQkv^lkbM{Wp;O|%2i^|5lU*8yFc6Wc-D$2h?lduOJa?KQPOU-q(qLejcAyD)oK=OT zPJ3AlN0Cyh+HeQWEfmEeXcf-xx2{&Q?r zER0T1WE`;GogrHK&y@r%!(7&6Ky$N+skGsG(a3ygKV%(3CGn5lgT?)RX zD@0_7Z?cH}YFr1PCGoUs*GuIzou=Ja=HuyvF(lIT7BabkB)cRS^aE|j7%~u?IM8;C z<%b~*hJWfIi?X3 zctYV}d6L^BfhQcP{zsZ7fj5#@{g1R#0&iY^%|Fv%2{Q64;D}b*r($NxRe^Rkl{9AJ z;9V2UiM`w4&6e3Laqt$ZHNnEM!wg=`1}H{PbYV_(d^m|sraCLqkB-wX9VeVd%yqOI zPLHgLW9eBAu&acdBH-Q^vukkwu>NtSPTC#q5GIzPJ)qrVXq9#lem!Map-e4F&(mAo zIi*ae>8ZWM^?bWDo;J<%e2X+}QWj>zARKJ33073$41ZgU&< zd@JA&xk9swmSkNktZ~J)>*iG2(+YD%R1%0ueRwY-E}-+{EyZ&F84tZ&dmEEukty4L zf!zXQ0yhby2HfzMzPDB2%)PYYDvSFblyqxX`))YdqVk$CUH`JMVSf z1^-Vv@BNSU!W;kVW|;R3-AsJ$i`kAIYyMrXcKMwuJkDb5qgeg9DKPY1V7RlvIo5~o zrjYC2*8L|69C*qA4o_v*r!K$!G!Ai%NaDx!sv9S9bwUc3u&z(s|C8Vo*BLX>QDb<7 zFWNEMpKT}_s!VcmTL~w)+HdV5p+Q32{*vT_GEY^;3nN*pZ=j4a79jC-mi{Q|= zB0<(iy}G?0S-NIXXOU~zk&s;yvd>biTT%^6ik+3?rIOApr))BO6+5TeXGNX-Qb$do zYvBY<4tuq7T<^HCxOd!mYdlIidOyyNI-^miX*|-Ea0;yDgvxWBs6JUP2{Y033SNqx z>9A!q5JaJ#UzvZv)vkFTw|6@NZhGu+&(qotXFlyKYT+YI9F5XfDV#xpDDG>CPH&EJ z;^T9^YaHSH6K;0@MZdbfp{YOA-`PKeNVDFD*1j*wy*j@i|GDN%^>=fOYbqRfNod>^ zc|LHVm*1z^`|)?{IkyFG{7d<`?_}L9CSwbH8q&$7KEVIddpfy|Q+vMX$mZEZ{NWmB zwqE&(ZfoIVQ9A}UMJKSoFGsb~MG~B0{-^tA{Rh41x>u37;l+)Z_|Em(!|PX`YqrF! zw${}h+5zxzzSev)kLNVjKWy|>E3Q$)ur6M8=kwH0Wao6@jyq4yf6nKt=_67B<2$lZ zyZUsCHXg2edV97YymVY?dW6+|eE9C|bNgyafOE=s_wK4axT2cwLcsO3@981l;{FkD zuAXgBKR9rfMG0!;xz6w?j^n*G*)!|A`Cj!FB=F0(eMox>^Td1IOZOpfylXcaiJm!p zeo2q>$v0@*9tr{$88V&y$DhFkTyFboia3vPZ;Q+Bc)GPH=l_uKnG<5tHETG+}g$ z8_|E%`KR0dSk#M7p3yot@6o|B;^Xyy+efNsnBYXm8y&9SRM)oJs_~`JaokRt#?icV zbn5yIG|B%v&PIKGk*kH_-GquMw)f$4xb1Wy?Dqm{I!3q8xu<6(=|KOgM^6;*jVC=y z61`eVmpA?>{eC+=J&coNGogEKI{i}R`!ctGif6|Ed4HYIFy3igr;)=gqL1;(>DA2` z_kYd9rZN8UTxGIv40gKr6USCHKHC3f|Cpu;-Fam=S4>_X;vD?%_kd~MneqF;jPiMz zY<%`so0)w<@Iw0{_@3PJly*;PSy7h&kk93OG=0O-@R=QG&JP+7nQP!1Q#;Wt^~u?! zX%hTx_PXvi`R|sy@p+%?3)9cf=YKvu)<%pXd`b2{%4gynlGd?mu zECR4a!S;Xf9S=x_v7<2PEGlvlH~cn zMq~c5J}y~)yg%}#;P^J2&&x!8`JZfj8_wq?>1TN)@;;{E^nvN$Y0a}hw|Hz(m=Ny5LIg#R)LKbnL`IGALke7>3JZp4#)X!2D#cVqr(N%(n5_@|Tb zyOZ$8lkg+JnZ$W82mO<8g}WQeD@nqu1!qf-z}Ji?0w+J`%N%_DNMBm+Mt;6U?QX=s zl7xRJ33q*Bl85xXn0Xhiq$SGn++ga}n0rg}KAmF9@{UWZxNAk;F}yzqnDJGUca!8L z@lxyF=t(gN3u;Ll_J+!L)BDf)i}Y-lylC`Q7-1ZHwU0T_R{sL!F{R#3Bx^q zL$XJ&3-!@^+9WSOz~tp6wer8s!K9~^d6M&PMN&QAU4glGWM#Cey!$kNRk!r|pYI@t zoyT{#kVt!slS}*+W6`%I`#gPHay-(vC1-5^&+kXNbsTOr=I?I$*wp1NH{}LebgngpizRL~kO4p+m%KI;YQ0*` z_uI5Huc_pNDXhRMd{Y28t_=rlQzjZnIoty6MsLrjBrbEbBYppH1rvZUt~>~7PeQ6p zUy>z+_`sG|N~XsI&K3w0>-41p`DPR8_^LVKW`X?z@p`yUKVP73f6!ec_;mtr6?m_} zZwP!+;0prZ5E#TofaUS}MmR#?Sb-G+`CSO}8w9Qrc#6Q&1@0Djp};EzUN7)=f%gl1 zMBonuz9{ey0{NQUweL)j%6u4aADuL?+^6M(nZ4r2yz}p0V zU*NL>Ul8~!fv*UBRp46!|1L0K8~I^@nF8|!@*8xP9~D?8aGJmw0;>h`n{d)M2wWzR zz9N{uR^Uc~n+4LR1M~X?4hcL<;9h|j3A{|;l>)C7_!)sW3%pI>A%R~O_<+EN1U@S8 zDSzJBa!}`;J+utJjCw_DF5#QLzwG{ zj}urauvOqDfgcojjX-{*NWO;zYTt~&{~);b!3ew*7cA1v7kHw;eu1A7cu3$Q0)Hy- zb%9~LbwD}%Mvp$bN(nK^l?$9M`EvzdAh1T#mkGX7;A%-fS@14_TP3|;@F9VFB>jBB zweLohf0?9TBk7+Kc)g_GD)=1&?j79sSF;QbH6aRO%u)V?Q?exl&rgeZ4AA+GCt38Bvg0xyyLs|44+D3O0a(r=M; z?TZrW_Y1ClPy&BU@TUa+fDq;J^Fx;NlE7aRqWr%K%)|wsc!|I{0&57t-$;l)+adTV zgpjvc;0FZm638zl$#;R^`viVe(mx^irv=_1>9+}fr$Bz)$#S*tO28Kd|BJv3tlgNe zeNJMGP7%D85Hza=?-jUL;3o({f1Tj>5MqBsaP3PHa^E73#Zn4(mNSJA^{OJAh^3O? z%LrkQl>%2w`pJTK3EV2_{elk(+#~7d3x2Uc?TZrST_gCX1Ztm@C|~=WY{9o^Ob7l$ zfxi)mNYgsKkPvbv5@MYf6MQ})^j<7*g}_w;*AjyMR6>+^RZCUB#` z9Rm548{6+mfqxRH=X0cw#m;>FLC{3;nG1M3(*eICkl$4i=Z9Cc%R2%AEc!@C)wCSm zzp$QBLg-gc2)$#3;M417$bmUEeI6m`L89rSgh0v&K|hTU^zE!a3cH&S^mSr~%Lzfx z4|z#nLkM~;cec5oBA+f7IF|65pZ5s?;F}1c=U%}tAcVYwg5ORExrYURm=N;+Lwrc~ z^j2t(iO2KhXq+A*#Pqw94da~gcoIpfi%j<3m{e49_Ao^ZN1{b1KIlpI_L!7AjNoA? zj^|f0{_sFtMJ83_-JT}MI}q>FyW}w?d6s;)G7_IyB%9(N;2g$G{|NVS-CVw#5c5Fh z|0CWkF(+eMz_e{%tp~(qCt+hAw_@x($5f`b&DG~~Nbt*B3VAh1 zV?D4$^5i{&bALT}&*|UXdc0=nyn2w1`cM`(w;sR8xxd_fzIyPw=hlN?$@}Z^G~~r7 zNH(_~1t9XvyB6}wLBo1vVRz+Ki9DCjQ%K~oEN&f!&Z`IMSP#nL=GLPvsocZ9dhofG zTkglDT(>>K$k;?dvbp*UCdqpm@>pNigV$?U9^--G=k=>?u0lxT#yoC!7&@;Wq+>lO zi<`@KE9m_8<3m)pU-6$hw_JYZL)mUU`jNr)jJvt=_+N@&UN+>Bj`bLg-IaIL=;zgA zpDREFvMg?urd+Qcq+>lOi<`^FxF`N{%YF6Wb4s_|8d!v+^xqC4V_mH(y<uWdClaA%mFQQu~ilB$8OF3|5bMuxb$-5Tv z4x<3tuME2@@1!Jo*JJQ3bCm_1D{n^<-OK36xp(3N*~lDut=@qRGXC-3Scc@5}vZrf0-D{p_2yc;0T9p}@1@(w1+I|K6e z!Pf5P%HuObf4e>HlZQv?UVZNodF~wgb}{Z-liH0kzn(-_4k1l$p@5{}&iFTk?$!^w zU%3b%?aYnW0l$6}wh8HM4?M#6^m`6;`1K=6Zyit+f8ltWTNa_OdszEHN3S4rkUMjgQfl$9q;k-6rVwvM<4<(@QnH=QdcerDA6#{A$jf1rMB6b7#*U z-rwe|IaSrOqTJrw-{z*zYBfE7n>*l%w||LI{m`L9dmrC1<}UTxMvFf6{ORxIS8w>& zFj_W`jt05`La5Hxz33;{huDvhQ;gOOFM|YxWhU0;BQ{7XYH-8 zbKS>{>$n=8$ad(C;NI?mt}_vlJ6-|g#o!z9!b9oMEOYtEC7D{Y3}}`C%`!x@Z}>_r zZz>jDSZYjr8+6NLQ8hfscIejN-svy@xpi;T;T8a-1JIwe$y-8E(`5_;mF1PdylI9 zq5kKNyfeW)|7QR9z4X0D?L&_rF_PYy5bfX6|L_rGfJ0vl?9GJ_$-}yxqD=v4lI?kz zgd?JZYVYA4rpK}$|M^~P!nb#XnlhTKt3Gj8wXWF*cL$q73(}{q)z(?H#%#4?QpQZ+ zAGQ0fPg~LF@7@eIZLn?0<~OpUfOTUsH@`8eX3HDnH`#|?eenFg2Xj*g6d^Nq&bPBJGzDjqdRsD4n;TjMDguUbg*kj40RBwkY-!c!JH04bBe_ zqs8|(*;n9k)vI^y-LiYqB@?%Y7GzDeUO%{(Bck&b*}_#-dAHoM>$;=qhpp&!M>Af$ z?r7%TU+z1jAdx$g^g=f1V)i`Jw+9kC|<`G~g3`MM1-C*q9@Z$8Ht z!94>W2Ip-rzf+sul+v{A{?<3YI$%e~FON0{u8N|EMA7n5Y5DEAs_(Hfs2{9cr;!G-1=V7?%&fZ1+6;a=2&0 zE^ETWFRPgkzZ}9I!Jgg|Qr?>&C>c{EIvNH3!?etMVrdJXQjvOmYw~3 zI9`28e7fWg$E0KsZpF3K3|gtcyMV(fSkn~qo?q!@)BKO)4~DVrSjPM=WZpt?nKQyE z^gNXjOrZzL3>E%z0oZJ;nS+x@Edf=A3jMhdNwIt+O)cP6G9%zj!h*)R7`NiVd82pe zq?B5$cbyMHNYMD7%?RqnrBj@Xq}I__kt&!H!SX00?A(ck;sWD;cHxc4ah`#mPF@Zd zXwI!@BBvl1?}J!b_v=ik$K**jQq`xDS4Jge|?$O+q%VV>~p{M&$}+gG4=;rYhvti6>yi?gmk zljPYSg81+WxgP^rsr@P3UWIG2SxkBONs`q*Mitvs_)esS>om4Xh57ezxL#xJD*PZy z4>xFRwF;jH8-yE)g*sIDNvIxf(s?JU@K`ilc!|bNQsF`tw^U;rVS(R6m6Vfmh&!jD z?NT=8{DS8fL6MYGMrgyIf_sFNP3D~U*D0H$o1j@%D-Jol2`Wt;pMkDm{{*&3jf$0S zg0$3<^dF&;LEB-@1dW94GANWJOgzK?C(K- zYPCj+!uybvI*)q7IdAyK=&PyoH5O3e99TVd0WrAe4If4ssSAnGKdYLqAli?=B%B>EPs+BU1xU!b3pHqoG(CoMn{its%_HeS&$6EbQKUsT zX3(xdN~Cqv9*E1cN1;PSHt3uJ`!)37$SE2rw<{n$vNeA^2tifqd%1+vhd96-)? zjnvp5gWV&iMY>Q$}i=>Dj9hrN0B`q?G!G}ZbAD+?R1zw zT&DX%x&02R6`rJ#Y4&Umk;$3t&9U$!6flM7f&D7{IGLtu>`E1GLu-VmX$*d`#z%ln zCl6*-WC=mVwDxO}UJN>r<;m0Yx zl34Ij_$Gx?=`oGrQM7X@EBC-yzI~X(5S1Uw7=H>Yw|&Q{Rz@_NO=S9hMzQYu8|_0# z$|%Ww3RIh{$zfD@zAC2+#4IvKpF?v@J_9Y@sEYO?A*UTC%gdZVdV3yPF|#yl9hfZp zr)cubiCXEP9Yw7(%QOyToQ;x!KuMIGLyKuClVHy0kc-W{A^w&#+^8> z9-LR`^K{GUM(bo(+Uvorhn#a7Og3V2_8rhV^i`zd^7|Cj$@&tDv2!;65zzhxiq6@h z$D3t;8@)HDTO%rc0H1H>^k@VP`g7PIXRG~n@&a$PTv{eHYM-$m)!3!`2(h8`$wo&&VWX2%lR3{`Jhct)==Yv zpQE6+soIA`kS0Id2(p|`l%I2seICfn)jDTyCMQ%i4JnrT9a>DOGMom~L+D!}H4n`O zH|iY4Y7CC4Y7veR^)Tk0Om!j0s#=foa@9giVR@<#5=N@C*$q@Vrkreb4(LayanLhO zRpFSf8gR_O3J$$keH#5Ns=kI}u{sYmD^ZVP;7m|IfexkWd`O$9a?ydy)ZLIXN%61$ zNopSEsu3!NRaUm;WMj#Y^N@WPO^}|up1pG9!|2Sp8%#I1N-%13PvlSxhevWrkb9EO z$<8i0)5<-W8QIa2ZC36n`ZPB3`{eF4G&Ljn7Dw(TgSA=C7L=XaWnYM5atm_LszMLa z10wf>z5$W@Ax)pIM`G^TBT1EQKLUf~o}(wPJS+4qlp9)rj1!z6!PdFw+HXQ;7Cq&M z=#w+VP`e>s1wy9*%}{{_$PaNehBz741oQ4n{S2rp`gZNG?$+JDqJL<>`jRf8_I4O7 z@1AV-YRef9Tjkwr4}jb>eBJ}0(@+z&1G$#6p_x*Y8c<)uJZ7tAs1#JcMPoRs4D)PA z{gx{g)r-apt21#-RdkRVQ6(rKUF`-r%dFmHv;E{^&OXjP) zQGo*W3MfabpFzh$RfG;SMy-G%Me0I~zp?5yP(~HsKPpxSKwqM2a6Umjhn6W-Ki1u1 z7ih}V4UjWQr9pnV>Od_fs}G{8Q&a`yOjU=V$u#v{q)%5ZNQo)N->p)8=xQ_6+sK`z z_*UX`Rxp%%KEUX zMeCfWu1CGjSG!=P3)FTnT&QwUql?sXa9yna1U>huyJ7Q7)Ewyc5!D0g33pw>T_$_6@&`Rxq(g8IM>e}iP=mbIa05~1B41^&y z0|rV_uRxQq`XSO&)hj41qAq|b)6_>$C0v1C0*EZKzrqr^xD8eEFph_%pbpVe<8;V} z{3W5QslZz_XUaMrp+^c|Jcbrl%BiqB6v2HHG=VNw$}A`eb*z+jmnDGU>w z3>AXB1F;HAa2!3D&6N4f;sLQlV6Z7yqY8(Li_jK13svM7NZ&{bJ$o0QgUaO0R*}b$ zJm@8l=lj7~Ph7=>Z740+&ch1#%o=|?*zDMy%>M&8gZK0BDh^iRSJ1l)&&%QE<0g&)ct5vhCU}Rs1ZZqrN*7#BojOyCNEVe?Bi+!u`i!k`8A7>Id!_Bga zFG0u2N>v$rl(>yS3`BjnNKTDkFu(6>gM^gE{B#4*A< zCEDQ28L# z#R3YuI>46C=W~yPY94zTP)r^$F>ibhsudJ72Y3v7L;<-&<&x(_;2qc}keH>yWo8;Y zTq^BMbHYaSEZ#rO_%X`5NtYJ@p*rw5NN2LVo78-kr`o2nq?^=AmZVl$vlwCKlcp1b zL%(vM4wS(%W6nhS#AlH9A?&-cPu+%;7*o`$shj)zfh}M!Q0@6#MSW5&CH6_|AIEN$ zZh+{EwKA-dI`Dl+&1a=9R^=@I9;DumJ^yDg&c$jG$IZ`x{}_AZNsQS`mA*y!Z{UB! z&c&Z~0uHGtO^>&$ArY2f%!pL=Pfv9Jd4v#$~#0w=+z; z@v9$(f{5@oYL6OyHzpN+(aNw7k)L9YJWJ{Om2Uw58uo^JqqulegR^<~pmJ`>LvMQu zsr&$l4~mK&0>YJqgMHK{ka1F=6^3wJrTxqY!YwdHDe~CoUxf(dtC@Z``gUYU!TG;< zc@LZo*pftTI~C=Ys;4# z%RdkNznI2{Op}$q(XNBR`TdY?jcKMe)&XCQys+>6B`W_$c-W zyLrr{eGK>|Oyg~EmD0DtUjqJl>|+n`74^^JWU#jLul63hqGX z;^#4p0A^)hjzc2_jg8^Jo21#zFx@gWN8~J{7X@oHpH(iz$!aYJ>(x=bF})8|_fSk9vYK5no77l7+WiSK zexSt^f?121(+fHdOs>`w2j?ihV*VMulxYi`!9E^1^IV3KKwJg%+W@Dg&|^HX;L<11 zPxHZH<}7vKAzT=Bf67;->`&>KCmD|>pTjR-E#QT;2{=PRh{A7R?} zF>j1gQ%UyyN)2{hoC=>yp? zQMu*V^&yb~_%AvTx z6`L|y+;{cW^LxnUcTJg`g}<*S;a>y&1@;mByR9GSTXq|4e@4paZIC$&``gfe1PAa- zQR>8~Mitnt(Kq9O1ZxO~%xlmwUoPULv;diWHnZgHsBycXU{g!IJf-LW5*RvU1@@wk z0XYdLygDu=Mf0sl30%=V>P{eBz@fL8elBx)Bhsy9_k!vPoTySBj%NH9O4k>Ltq|0W zU0)amaKhWkQM8PEVZb1f3j_bP8I^}DuF+V|natuyQtiAR2K0IYLy6D0mNPz*dT0bk zgUUiZO=~_hlkGB(=6!@~6Km36k#`SH^vA#I0LQ9s!Fwi=@_dN;AolXFLEJsF?g!m% zKySg`!Z}^tv(z-%kZ!X3bd&LOE>R3_d^b)Fb6jJ|y9UbcQN?K_yR;rV*qeGoOp9voUauN1&YIpilw(XaJ-b@-^ zbxvQ;i%vIW@gpj2h@CV;M>dVC)KySo8 zmKVxJ~o0(<6<&}}}VlNgV# z2>Yn55X$vATlp-Uk7oB`b3KESMsQO9cmex$HHhb6w?;pY16BF6OK?j8ZC8&>evM^~ z{tXV9*o%>>CEPKZ(|H>*Td-&U0eN~h*OMQ+7@uPd*TLpo22!@&$(q2w7R%=F(o#a~ z7L%?-l}|*HwH~`VFo>5hb>})!uOUxExtp+;)AlDWVpshP&?~X)N&0+{n@L)Cu1+%_ zAop?XBlr))X8i>1HK2dQ?oHdJU_55p4unsBziXz{DNvX9HPuEC*QnVsq;d70T8$Il z51r&?(n>?<)D1#{vg1LGWWr`;^n{&nWzi0k=3|Ol0tRazc6A^%Dz;go*Q`M_=3h~# zG&c5<8El=oNScm4?M!RQ3GC~9PQHl=+pHzam~b5s-twfO=Pv2wjnZSl9>Jcp%+>a6 z(f0f$a({+Blk1}uddcKqEyA!x+Qh50i3@<{V^5uiVt8e|c>J&?UUpm)WAaM4FwOza z8^IfmAXyyjK@n}p;hp1ClA}W~>HKy*<*g3vp`;)e52@@}Y^h%eF`6O!6r|~v;xJ-M zy%W!zJ0O`>^^HNy`}$T8N&4Msb%4`fRJoXz;5BWr{)2lt&_-GUz18BK zWiMFJ;Ii;Gvz*+TjKUzXc#q0)49%<+FJL|j+@T6NFWL8kb0sAsWf^bmTlI&^cc=}# z!EeKI>5D3#cmCF@moSsq&3X1uz*5!?@6dL08T&+8Z%-f2XS|AYtNjS31a7DpdQ{O- zpxsb)6ZX|X%)uYV$=TSEdu-^ZD2^fpduK5h>K@pIr+68c#?^`gzqMgWh;U|G}k<1)6|+#6fiC^A{CZwcv9gL8jqM2b;DE@d)YeD zQ**8|EQ>r&~tz5rp>aXC8PRy?Q{Dd)LzP>o!UwE4$|3|kNn8Mbh?9;b^;EL^Zmrw`q;}bm znq7u}Y(@jl8ai;+ak;|jEFsby!uza5{(QCG!o?I@h-lEtkHoIOD#-n+a4^3h!^PGj zAs8%}pXp0jgST^(9o|ZIJKS=;ho}xF9e0yTErezZS0V<{$~K&}ZNu5N({XlsudfAy zz55h0_Nk93WPL>airBBzuZjIy?GFIkAGnfDe`VlxVy_4O4$LcC$|^%R@UjNAKG^V9 zfYNa@i2JPTgKv?#oo|jEcl&>(Z3uS+Xn;*<(C#+_Fd-lGgs|2^Vh0k}|AL9Sv6MP4 z)YU+Ks8=&a5WXoG$wyboFSI{!E<*Vg;e37rlN;J_+SZ|yJJ#ZSpSoNz<8t*G1@trO zCZ#iPQa2O-s(M&wKdhcnYGd#j^@6fL1d%VO7m2^fwpoX^d5y%csn?Z#CURd_e?>Bs z(a)`XN9lH^mqyTl*##`Tpa@M>-hji#Q;45(4o=Uxf$e>Zx=kx^n|eYakqVIF1+@=% z7{PskI|E+)tPrQ@ApW~v7wotvfaCLl7XY+%+=D~{oWcNFO*ph4R5(7S?uMA)vw`Oc zo)7#q5E#nVEFt#lAl?yZ3l_{m7c&(?8yQoFL%Xa&tK|A%I09=#a$Gd8NX}pa-K3Xm zF?wFiN$t1N;gZ)XygrzdAoCVOHW21#qy`jgh~##JM66J0W)a;BDO9s^w;ES-a-Ia;Ed z1c~h;(M^KH_C$g1^+;b(v_xC3S*0^@jhUe(x=E0@S|qwjkht373>_-PK>|^BB%4Ik z)|a%fKa(@naWko@Wa?@ESxlBpa}#r6v0NmsNla{KA`6jP>y~GPVyLGh;bFL~)ty&@ z+VNtx>@hQ}y>4R3m@7mZW0vU%)?CR!d!@Ra*QndoSBZU99R>!T@HU9oJw6ovFRBx{ zqWda!MURdih}Uv&Mp7Y0H;Ogq)W8ZqLCU}^B+I!vnap~VnukzKNQVj?iL;UUe(RA= z$aDZdorw;`Yk_wWc%O0-3e}?-SE}`xL@#AUFIAWMFYCd})LY0kJieopRg8uy?!bK0 zabj?n6}>)qqTzP?`em4zk$btiQkncK)iqkYOK=UvCp2p@`f~AG3C-#&S58B`dqyKW zYhm|5Fc=QwWP_dw!e^wK^L1CL;CToW>O-%_n#G46#JrpX;ww5rsc)91{(T~54|3gx zrq8{iUX{pTx|)1c*!Pkg#|lbrtlYuHY{+oUYJh+v*g+@ zov~k?7#w;*DgBg9#Gnh5YeDnTPV@Ekb~ny;?`1#Ts~%$WJ*1vuKgH5+6An?BHlQbO z@YWz9h`-9#24izVXJE?5+&!lzQq^yjRu!E=tmPCv?DWD2qXG0_>(^`{%m<tgjNk(e!!($kdtu*PC=1GrOWwlum}elWTBRvp%`6C-Inh6}1G< zD)L~E)`PoVGfH35lM@s+)02)-Tm<1ovl4}er$Bh(npZR{g2bW<$ga@q-9DW4?eh-? zS1UkaDTF$B7_dHAq1U&4I1?6EsW^|Y6rg_>=%ALfaW=aT?IA4gEOrbF!uSUBD=>Fe z%*Gj5*10S)IcpA)-^We{iRfdlMJkXlGom)#iHR0LZTQqqmfWMsi2lPdA2*W-*K?Gf zfeMmkK#G}pb(GLBj2Fg=gQ8qx={^zk^Ce#t5;Cs_r&((SwG$B#E8dhC(cTplM@^_-*S3|Bd^GEZtZ1u3y3fQC<*V2D$HgG|8VTy-vnI(P^p=P}X7%y!M%F=-KS!tK zS>MCIt+xI%_I*YkRE-ZM_^tvqvkH~bwBR+{g+Dl0&-qwCZjp5V7- z=RnUt#YE;E+XuH0Zr#~8M92@z{ON;3-O$2{M;@s_bfvA^Ppz!q+1*pQ2H$B{p4z)} zb64-`p`8QNX>j|gn|BTkR`d_-97IJ1hq`)uD~U`W+PSlL%eJoVeball_wCwU*)_0Z zdf(2zp6NYZo40#)-q8iO&V4=q4@+b$)c=Y4!ETkOZrPGl&#IXfGb^gx>i$dZHVpH> z)EBz95BB5xL$@0YBc8ounB?R1&-bK!PXelv+|{*uaZTBQ|7khH_5OdWFn1{Z+k|S3 zw_uF);GY)yY3Gztv4u+rp!oBob8u)+Z%^l`J$)71IPD{KaA;tA->E=x7jjJCTFmeu z=!O#p5a7CkbHujAIj&sb9op01GYAYbn#k`T*nS2gE+NfGXPMe(SZ6#3mj_U@w}1?P zy9wf>z&aF(x@~=_cr1!kQz>6Eu8&CW8W`x>19^Dx=*q*Nfk?=d?4B+lm~xTZyOZ@b z=Ue!NyN8(~5hc@O)CL1)s;Ir_12d(dayT~?)ttcmN&+>?(F#KYJ&9&Q+)-MF3w(`UHO45>ljvvKKneiB=$}LKXTLS^eex)>0u=;fySeYWqy3Q5p4?!FETLX(2%NC?~(3 z_FL?vehqCh;s#W8nbtxBH4dP;C|pT#jqdca*U|TaKh-lIbH!3%5+B7&~hNoa8hbHT5~a$Geg>*daN+FG-MY( z6B}Pyfj{a&!^4cC|jmC~5aY(~6vuN%{t(lq#ZXN0TR;BgG7`%7rL+aX=`#4fpu zoJ_kJ7ZPPJjxJ0X5BPtK0~$SY1UhFi3QxFp>ft%;wL4c2MANPHa5Q7kf0?JzwRjo7 z`f`|yI@;em80-WDM$OR1= znFCW#$Cb{gN=}AIz(s8&RxYC!Ifb}-tX!D1Qn*;Jf>_n4lY&7%ULWmDJ%G=Q>Uoz2 zSg6McM-awMrITi#1?w^ZA;tIT1ziSJB`C7k{QmrC5B$Ff4N|-n$v{pE8>1Z-`?F-oso zJEJO2Tf4G(MQ6jB_S%l-)|Hm$fyOn1xd#}swsiG(ZP`AwC(gLEv3beTj$@=ZYuT-J z%Mfz3c1h=w#?>8b+8aCT*3{LtG?Kclw!Ncs`O4NhYj8^!?rC;gTYI}s9gGX^Xs=zl zx~a8&Md#|}jq5tsA2(-%wXLhKySHaxkhXAD*I|?UA$bS^WaBpSg^y+`o?s01peb+~ zzt!=zOl^C8XM5|Kl?{yzRzf82zMkDaGBj}WirOWO2&QT}Mr&JbT;ICZ_J+px&UMWV z9ZOk~_KJr>w-4g3qU#JOjyt%-h_+t8p&+p6TJaXXYiP^1&Vil}?1HN=YoMpA`!qQ9 z>KxoMu(P+fvui7y?RDZVf9Ec(oQ~MsQM-D1XUB%N#?F81spHV+&CZ+WG%y*!Y{rG5n9ervz z;DOWTRaexPSI(SSzYq^=%z3D_U9`SBH>P&YlKCIGnd zFOLTrPObi$^!e3wRrRIwP<X(RXT4PM5Z`=S5di7pn&qK z%JLbd)bpbKty#9_l4TujA={!AZB6UeENjIk^m&yFM)1aTkh3z9-3tb!KtrvbuZ$Ds zM?_9zQ*ob4r+1wNSyI2Md(2vRU4UnwPL!g98qBOl@8hp2pI@u=2unhI}LRI9#KJv0BmRFU+mCmc2C-6y0@{EASfePtE zS%ogTz6`ejg2n2tzh>tAS+lw853MrJT}hvzuP#?QaQEETahYyb&8*7Vb@OKh*_V~p zR@!}asP<$HySkN;c_`Ea*__gf`m&n3x|$G9+-^8pOVP)3?b!u&H+r01+7eQ8Jh}(! zE--Y{P{#AVKsB?&=zg)!Ab>_ai;S)sb$vbc-9=-y&$4BxyA5<`&3NtSn#PV*%a)?I z#w3Sk5NlUqP{fR)b*)g_spyy+JGgJcn|^fWb*(KJcbAeS&*o*Az|@t_o~Gw$S{0r~ z@=QcG9Q`d4Rabr5z-+XZ^Qgn3o=nY%gAHeS3#KSbRs`$N9t_VkUEh9S+U)th@{tRC z`tFKvWZ}rsg=33G`|{T`wXd6u{uZAS$!{Ew@N$G(m$kL#FK;gzOX1aRjh*?p12q|z zSc-_w=5=e902@1+nkVBP)%tPyjd^R@^VTkF$_vT3!k1sO)|Zd%^2sY&*NxoZ%U`~H zU27A~81g|%h~(we7DL19S}(>Zl#h?QtX`&OvVqnzzZT=*Xn~nqBc^FI1A$$zk6phS zThgmh&3Fy+vX1qrBsG7~h7Zh`f>TrU9r#`>rXu7YG^U3(s;cUWipsP0KO=*^1a)5_ z9^Kx&5gYtGnG%@PYA;b8oRU-BM2_jv)GD$hfk44KiN#SwyaO)YPpS}8zr-R<(% zXG6Lw)o0M`1v3U32ul}=buddk**VBcJBM<|w$>HCz>@7uk5-hFG0fBJ=2eIJxDpTJ zE-J2dDZWI!RIM3MDeG2u!pb2gg823r!nf3@05x63*o2;?-d{ZrbEPv&#fXFs752w} zNFz1aBh9SzD|#Ih9DHiaOJ|Y8d&V}wn+oi60Ce|w8-={jNM;8_fJ>=-# zu{|iltkMN%%rNwfv$ncItpfV6S~!1Ui2Q195Y~WITt#VZRdC6pKVKYD)wJFu5dz-C zJ$=n=J;+m9SgoChu8GDO)PT({;7e*q$5a%rHeRy~Q?lk|9WAOE3iVE8<;lvYkt1Zd z!2K`XhO`lb%asKo%N1I%^O8Q4SdG}ai3Vyj$bh^UtEk!HzkFSKs41{sudS`0SyMg( z>l}Q)xW1iw3$63&7A*Hd=HTjn5>#pnsnDPY>51bSObmzv`EAH|l0%COSicf0rpBe1 znVdO!4QR#?)ZeIj@8d+6tCkhhr2dTTXo-Q*_u@wMcGyg**K?*I zai8&_o<}B9FLZ4Hjd|qk^PXK*ogtp6tc5KVYL|-^WN~qvGH!If_gn$2vlL9`c)69 z-K?y1UQkSJ9c`Fkw-4(CdIn|TGgsQxqer4k)1xT9@=hH4SP$u{pW=-UY_FlQs-7{} z^XdwrtV%qxK~OS#-sAVzVhSI!Nbj4lkd|ARBA+3EUbdDN2RTwzle0FpwRJ326NIoX zPR}JtEByO5stAwQ)YG&cuXx9ed!=JYPepx9pE*KsVS{IK&}pcRAhqD7wxArJT)edr z<9Sdj>i>BcPj!vBeSU^6)ykA%_SM^jYS}@Z#+jLl?FsYR*2ebwkmaB9O|pdQCPJG` zpCT6M7Er7^akvr{p=zph_CmeadPbr17oN9Jtia9sR-q)bTTQ6-xC2w;E-a&`BdV(< zb^*sLtvIi~s=BTYdzVxtc4tCevfidy%gup$3-t4Wg}tsLc9THc)-9lNCWbML(5>_W zesHyC^!0k{1v?}3M2DV#aEZ#b!aQYWX<6mW5UJF}P!I5UdaR`hmZx3SjSy6EgI-!H zd!50Zrq-Rdh*~kxg1@yjDQkDEYr->M^-W92A|XDfHuH3|QF~0b2DX`bT^k&%LS!WO z#Qrq0(0Cl$1MwP)WI}O$e4u*t=+Pq3t%q@Am(cPlr}Ed#u4AuT(%7MAa*eCon;XTF z#Ypty1`L&PW5>;eL8^fBsCA~BQU*rjPzeLEUAHmd^*&4669uwdn`1JZ=7 zQ&BPWu6hs#N>if@=x1Xy9|pwa23eHHhI#@`#Ayo)X@QnOzO8opRHqeSSUbCP&K!GF zi_50jo_5_nUC#!ZcI$Q5l9tXj=!|Giq&6=Dx^Qz<)flt}T(VwG+|gt&wzt-`cZar( zphpDnhiI=P69u|}fb7@`ufgpQy-7vNss($fA(XkWFNm3-9+d-v2B+84updM{sG9kx zed9Anp_ys|p_@5+_Ru0qF&t@i@myyszQ|*{kCyyQsmo~-&fb3O5glq5|iR(6XL(^eB+4N+g&6sgRK*5xOKSepzIb{p9a-X8@kF; z#KEpyTsmf8;v>5gYs zV)&fL_mjl5^70A3oYIapKHAc$vmY7O8$0ustuFHAl&x!7jZZ`2>0#{lj2xYt8@}tK zUi^Z8vOA5t*qc0fivk|e3mka%u1^>b5B7OVot}&@^SCz4n~Xl+eWWMl%RK3uBd&H{ z6|8uCmujl2Dy3r2A}QAU(}r>hW!MTy0%rZb7b^D>4qF89@HHY66XIJ3B;Iq^;utjF7-V^Dv#_W)vM70h*rVM6-8{9_b-@IOCDyWnBcQ@J6BiRWDV@~7usgNLc!^As9R3@a~D zvh)+x ze2v#TpnUybdUmp@zDR6`NS^et@#MCP28YoP3FFt-nkIUUz8pe(5t1i2jNh;@e)NB5!NbIh9{cheuIMuZ zB*Oz&bYY5uu<(d5{v*QDi^BL9g{6-S3y%upH!3WBOc=j0Vd>O^1rJk<3*$E~n20M= zj1LP>2;)CN<-Z_6H9@^?mx6fd2mG-vkU|$`pRdqTcyd_zlf&qzhLtx}(Fbc?rw6r~ z8kWB_EL;{=URhXruw_w#DJsLtuT=TB1#(r2dcM}}zc!FU7p9mN7On~_zbY(!dRTeW z!_sGlg=dBFn-!K`6UMJ5EPYN`cy1WKzW?!Vig5kH>o>gr3GWa4z9hlK{{jZ0d zOz<%E3+w_BrU-f(MVjKmK$;HQwV|U;(HNHA6c%2l$`7_m-QI)!U3mLm5te^>Shz*3 z42g-u^%Y^^TM;&JdT}OTJo{N#y83^0j-&i<@pU#Z9`^YZNcp$oOh7C92528dZ&4y2 z6!wLM=^NqpLFr{-;aY?#ifSSOmr@ z>GZm0in3ICj)=!Zg~IQu@Nkhy6Bj;6{^GE38Pn_hMdCaTyFi;D#)xJPZ&2Y0;?l7E zH*h-5BNOnY$GgMQ=`(2dLFLoCl1aWjI1|ucyvbqelM=*q@p%}1w21^hDF2|a@Yt~M z?6B|(gsHqFoC%^vToRV97G3s#YS98rf0Hw0ohq_BMfTDl9X3+zB`h`&^_sO{RPYja zYwg&g;AJ5$)fBg0-)63FYH!ECQK>y}-od2*EzxA2Kp2b< z++7aIt~ShqVR{IGH+K+8cd%*i9hZUKnzQU<2GZ0{4v4k9_D#D$1Tm)v$`BE<7PoVU zMeChJJ2CK38RZSVV@HM15*YEMXvqDq0A+Abyl=twCIDgs#gK?0@hm14Vv~f38Qk!s zqLsR8mqzc-2e$8mr4os=VW&MleUn z4stNE&%;WHR>cMOde6KOrH!o2p?CGEfWDdZCbb*Hde`pXh{4=6M}yQkoZJ>#lmG+#eF)HD^S_SeyP<@G7-mn65vG1N66HKZxC5`UChW!!j$y?b zm2oI+FX(JO<-v5@9)3iTT`mBU{tb*v31N(84#TuUuEe{IIbPKV(&r&O@OJ#*7-lcv zP#)PW@(#R_m~fX6e4?uE}3buTt=Qe~%&RZCF5}q%_ zogBWGutmRoo8svhwm>8CjmBlUxWx5cJf3Z+wnq0%-AK`Oe6u(}VOGtAD!Zbn{lgg#{1JkOG;tLtaF-~Hf z&PcOgqPvih+6jf*8No`0VM2vl8E<2R2~_-JjK5@jh4CH6PZ*Cgo@R_k{ZVqwmGM@_`xzf+e3tPQ#`hQxGk(QrO3jbvTEy4KNS~0PFwLKEe1K##b2Wvnao(uSj||&IG=GbVmV!*D-Emyp8cr#`_ufFh0ik6yq-$pJV(TIO9mhV#Xe>#$Pc0n(=wYml9@fEMfFB&Sad&xPb8@MtX5Rm9v5IYQ}EH`x#$ke1-84 z<2#HWF@C~$gpt0tO8mcKJjG~ubbJJ33}X_bpK&JRe8!6yS1`6SZe+ZY@p{Jl8TT+g z#`qNDFBzX>{2k+~jBhZ$$M`YhVa6{QzheA1qZzC9i)4&vOk>Pq9L_j~aSG!!#yN}& z8J94wV(etRjPV-AZH#*vf5rF>;T8CD5QnWemXmQXV+o_5@j^y=hc4CUEsT#d{(Q$w;~b7(%;9>*r5xYJ;kAq#2*K|P##0>)7sKZV0(jMF%N9*56ktS5vVO9?xLSjX`j z8Lwo#hVgnr&_BTVEMY3Xl|=}--r?|H2(g}~uR>G$aYE!XlXWe@h-ykLhL527UEe#@cS*}?>PMshv_@@l>R=)|Bb^(7{B27 zZ#euNqx9->q6t^xJ`#u13Bk|DIG7M}Oe93!8HAvp&*6H)Dy&~P+(roct2ultA?WYn z@PmY)|2gA6LeRfU2)#ccEXSvO2qA~jPot9%>G2#+X6(=L;~1+MYYB_-GB!f+X=l8Q z@e0P97b-<7tkM#zqzKPa%X{X^dHf z$d^M1e;Lj3#f+tlm5kE~L3chO@@-_ioa1jI1pgh3^fh$~-^2J5Lgd@e_!%MOa?rQo zfN_k;ga!Dv3nB84WE{uor5vtgoX+tJ8JjqM1>c<2<7$py&*4iLuVuWEaR(vz-^t;78GlL$JN$z2HI6^T_zuT^!Qn3%dpSOK0P;iM zL`E+m_+>JdGhW2Fh7fXe5c=?)U_#`-nei4*znjDNGd{raPY|wxyc~Xx(_dhGlkpwK z4+&AumxSm~3~U%v{wP9(lL-f59Ov+0LeP(AEMvTY@mfO2e-oh><1ZoPf0*%?jK5)g zh4BxJA2NQ-_yyyajQ=78e*-eneGw-i!f}KsCyB8i$7gYPDC1bh35-(-A?JKT=)05< zd|NrZf$>Vlt%RVzpYacjpD_M|QNTt-7fA^Dk_a&;&EjxAA>=J$EMcr*tR@8gB0|i& z*Kqi9Lh!qb@fVCA6OO_>lMsAQF#eknk9nzhOxx7FbsXbj#>)sXPu<1%G-16Ee`5Te zG1)-;0wESK;yV#4{By?V8BZ~~Xnz>=`Ggo>?_m6ZvE0=03mCUEj;DQ4&~IaWit$s% ze>37cSc+~Ac8Q0(u!HD1s7Ka9(0{|f1w8MiY& z#`qrN=Zr~Mvk-j-<9Nmj#<`62aX0CMzKm)g2;na|?1)CX7jiMKVpRJhh<}B{pE5dW z{f_v4jA}mu{;l>IfXgTz{(B`OszbqMlKN@}CWaAnGE7-)|*c%J;Xx7t;mBXE0+CA(&5PoWXcL zV-sT=RQ^^%l>a0l%AXto^a=4OA<8$%&rrVF zS4R12-x%fZB!5Er4-umLw+T_c@*9+YsRv<{zk>D)Q2wt8QGOE1u~7&VrRH6QYnw94;Y* zJ~KHyhY)&Qz~Kf$=%?=If!_@jhEUIO`U`~6_frmkMhLxC|3~Fhe+T_V!P<>$@PFpO z&JK;u_7z@A(J2bls|yO2;6DZnO6ScgKwRUJ0!k{tlMZKjRH&e1*=nY2S-RmrQigE~ zd9di*#f1|6U}@omVTJJvsLoxGP4I(-1c=(mR3TOgK50b8Eh;Dy$~Iv_1gU<&z@bDx zC`=#1vk7EBZu6f+vg!VVP(iZ)C{|z6vseMoL!G-SNHHS#kHy$TXDfjJC+a_xVpIL+ zqHM}@HVpL~5#BSd-tYCpvY$yBrU4QBpowgPAC%iB`azNP6I}mUUZ(p&Ui9SGf99mA z!X4IrPV9%A)u#CY-wBfZplSM&g<0Qz9PQk`6QKCPLV{G`$_5`_`yq9MR6n3_DA5l} z6Ha)B(jjm9`XS9j$$qfFK9A#_n`7V!xgYkN5HfAez+VCtbMxGfpDi9Ug zXLH7o5l=m^r=(lDY{|M6cr0^y8wN{t-MC~)$FlWcgpp9k;Gfdzy(bt$gK>>`&(#XN zWho@8qjkj@WcV5hzMrDmKqP@LoUEZ2nuX?D-a-G1ugpoW6>M3ut`m&^+XGu70@DNa zj2z{mIZx<8X>?@Zq-&D`IL<|fX^(n7>p#(r1zmW#n3e<%`+7Lj*(GPJ=*ZP{f%+gi(t&uyIccwq2<1Xa>=(y-+nlWj>@I~mmq$&zHd<=acRN(O{@vsa$MJ2Fj(q7~*Z~@gV|VBWxeGJe^_uMuT4th=|`noVFe} zGe0}u8}`2lO}zI+BNY(P8V+A9SJRZVD-P2-8u%8qF_I zAO8kFn+Nf;#i(RDI~*7whzN%*U%RFY$VYTkPL84q@?MSjQ2A~Mk#87iZM*!M%eDQ* zg)p^s`>^G?J&fO-;O7Mq`3sFLHoqsCpPlbxghLNo4|=9E)XqdldJr!D zA|JLU6dmQ8t@#DyJIVZr7ag{}Dwxg=|N9*Bt<-b@`G}6n8Kbxb<)dd@L*;ubL_XRt zMzYFx1D9)$3l_p1%!`2RLg(8|XWMxL!W)Qy4+Pcm7%oD~{S@We{p18t5FN?;3NDDR zt?x0L0pjSe>*GsJ7tojJC_nL{!_G#}+=iAr8k^vDKRKD{DBncvml1DUk6z@XKHolU zd6GdF%C7?a3PD7EKNTmHOZ<&J^e#M{=R3jD?rBR*_-B0&(!@57LK zn+{r=A3Y0A{Oo*}pF@xHG+jWCF4lv1(P8T`FRa|?%Y*(mi|I)JEnF@@9b3VV_EGJ_ zmgh32v%`0uL%yGAx`2E{N9EKoLtDOkK^JP5^bq;xg4VXnOJU{y1pM&WN#L;S_x&)s zeW0`FYD8?){a+Z}tDs8_a0}82#D~_$C+8@ao*gGT+wXf3#$Vu|G&+YcoozodN_K!M zSZ|r23$@E|*u@7r@_U*G+IA^peuz>>HuyO+>`+jTDPjC(g5NVxnD{NiY4e*M#&1|I zbV6IO57L2-hA_Gdun)e=UIZZBrn?}lTI za57ykW%*T@e48O36-4r_z-h}z?Eyo0JEGJPy#`~H9RO0fbP$FVBdS1G5{Y{>h{q7C z_{9OqmqVuxTQ3%Z{_n;K+KA*2>-00Dx z3X8^#8H?+}!orZ>v7<*LG;(y&c%=D!4Us>toar|Vn-l4f6VQjsnWX<&-J$nFazsDF zYeYP4WS;)l_ovOh7xr4GSenhUE8^+ov&OeS9pg8S4|f*&^H$aFa~v;rQtqRx3jLq# zd-k*T5`^|sjO7o7^P zcke@8aZgA4t>eQ*QU=j^Gpysqg04j7(ySMb#AiA(UO19C>V+f8nQg~J*$YQfN12H4 zmlcWM{)xBrb{1wGi#5xS8RlkO$33h0?&&(~%Yw=HBZ9RcYSwl7+Lrt9?!UH_2VZHf`TR;(cALnXcCbY0@ANnCE1XgC$u^ntUP`w@nfBu6OuZ( z&=~X6vM&!gk6!KATLF8O@2PYhnxo2{(qQd<_OoMK#NhusT-j?)Jbt)T#TPd;?~8^! zmGh#NJRZms1$m+Z^8ED;V-oRtr0kjqzV!w&p$3`3k@GA*$sFe_Dj&EuY^(TGSwQzj-Xe zH1ZZ7(llL6+tgB(S#$EFp=7+L{Nt zPl;pTFk!B;=X3q%`tLpJ5``6F8~7d5`E;%pmQm?&v&_5wkjT(7WwdqqtCY0PfF90M zj&ELs7R14Ul4n)u>!bY#R*+=!HqrgIZby$>uy@>9?MhZXv=@)>MjFSxj-C^3BxX(Do#9n9V{Md_OT5Y?3CJzAxXMhqVPQ91{&#L(y6{}6k8r=bQks*yUe3+{%BFX9vfkvK- z!iCOV*8cKiaVFvl&7Of3R?msF$Zpv)u_95~Ga8-{)s4Q$^!i;&Zlid}wz1n>J4x<{ z9*2K%g)u6=yKv z_~GVZ*FM_&>%#ugH}?Lf@Zn2_-Zt*G8+%U_l4n2Kd)&9Oxqn1t&w~A5H0O2acjs-I z*E>YS+;-rENVJY#WiDL(!RnHcdIqIM_YA5KSvz52Pfx+^=Iy(WMwxNl zZ}qm{`+Q~QyHP#vUEO6v-haL_`_QW9+TI~PYQek81{}=q8U0`tJUdD*uJG;1>^624 z^z2H@*kSBStnfXQ)$KZddek_jeZ!o$P`Eca%(?!mm zi91N5$ey|W16~WV$Ml%+eu}%bH}1KJ?W>w2cD;H+q+3UCh)(FP?adS)_Ey9>dOqx( z`CLibg7Qa>8iv+s_fZiU-LtDAuIIJhXYO4%(CWFqY|IDG92c=85B^-Zcg1!`^>mkg zbR=Qq$Pb`V95gE1UY30@;*MJMjooE~4w^mZS3a}p7|&*`d(vHez&uSdROHR2zPLYFwA$k9*pzqTH5h0Y1MT&jMrGvX1;I8^XsZJVSQm zbgAXv24C{{(JRX9%E}L#!;%h~1$lrYa z2~g&Ld@x6i=DGeCdqtNW|K(v{+jFXRa~c}`#t@Q8+hh2?9Dl(Iv^6E~t2Z@C~MO$j0{=+k(hVnC{43AEvA?O!I%vH3%${-h2?+uF!)?SrPCbbk*;cd9DH>P z2KfywYcaMjrFi(w)9{l~R&LU}fBwukW=6&&#)-0}2bM~-__z|X+LcSqW&b){w(P*N zlZUTdW-dQ|*fHa-Ok=zBS=FN3QnrwLgLO!J>Dar+=%U(+d+NZ6=d2sbA`Uj5IACIq zHlqu%#F?(!rzzUK_jX;?dVQHZbfC4n%slwqk+cM&(5WQ^2r=mC#(l0CuV>k>i*36}>V(zOH_f^f_vCby85K~evI5dQ6u-y3U^=nXm54KjlDC9nl5`kV$s`g z9TDSJwmjG(kD5`j6%QYE8Ijvv7&D@`KXBA-L~VB;jWA-iXIyrDM8AXa#|)Ia$iFq> zwIhRv*5T^&mVpn>@xOLt=unZFv167RNsXSYCn6u3j(Dnt%*zsvMaQNcoEtI6KXd{YX69puN@iEf8c`|-Ltx1>%C=f&h13sH+Ni*F)EJcN23b6GyK{Pmj9~5 z_c!aY=;Xo3hcjBVwLUr$IqnXw*~h02>7u%OaqrVrF-i_2XY?UW=j1-tD6ssMhm?Ok zNWV=jK7Y<#|Cg3?D}@|9SG8w~`DyuYJyw?d{@^xaa#QQWWibbHx$YZVbz2mfS(phf zTTZzvRc)Z%`6Na&W0?DpudO4l$Zr%oP6?ml4=JxFa~?n|*rj|t3x&26Ex-P2qtqIL)l?2;zlz-$r zWY6J8V*ahu4m=qLstDC;MKI)BhpH_10t}gQq&5ux7O|6XXZ}C^eetYeyl!_%SqcF#f=ozu&uPrjK zXvdiMoS2b}{3!L9bUF^|ynDax`g*;)HzM-w_<#m++r0bSn5V>kd(|mN&lCQ&DZKi5#j$Khbi4}i4EQWl1*wq6` zzTR2U)Uva}-LvPY>Dt{=*qyal;KOPb#hD$V_xLG~*=%=E- z`FZ93ubUtLOKX*%dZ*ZLuRo>bDyhhMaKyGENHgqqV;t3%)pJM1;ltD;evGv%byG60 z0}k?x8*tu^lh#7oT6SGJ*njOY#Ia5HvPFJ- zm6XvoeV{m%pn6m4yKRrU%D-XYc=WuwzczB7*>CvlJa+%??CGE8^Veb)O48@23Qg)X@mj-JQ{PQ(45D z%Cj6v@GR2j)4v-IiD(j+$A!f;-06KNNA)}VF_!-L9c0k1#HO}XuE}Y%FTfXz!VecNjLiC2zh20+n*R8=T8jAue zSeN#s?4B}zl3K<37N;l%3lpUs21GrCtbyKk@U9af`A%y#9>te;v-~8PuKGf0Tb7>UlwB9ZGie5Z542n;*&qM_VSU z`OIxO&8plrb9#pfJwI}y%naRk9vswz{SaARk<#t!N!qci|EP*oXqmhNTKX1MCLOGW z*DS7#Bd&Ku{3#pHw$3|Niq(6s8-zSNI|f!4`(<|~@(e_tft*KVWi_m5-m=fv9QOp3HM9ZymZ~rC`9(Ixpas#W ze#MI?x@5lLpq5?gI2Pxq{QP-G=BBJG`bTFT8z7U*cXx=a!JVHpjBMLg_UU`mdb8q; zQN1Dijc2Ss$bdNZKH?y|wJZy6-ipGf9oSEd_P6Xy#17|$2?*RHSxx~O{6rS@G5?S0Vd8uWC_z9?Ag7agWA5-Y0k zm2uRjB`1U#)v4B1M-{ho@}srYkHIez(yvP}eQxk`LwYx)ceC`7S0qGV*AYRhG|kNx z3~0~IRn%su;^l#C`ypElc*THM40y#buj{e0dH=~JCnCgw6A_t9PQ?0vKI911S&@2v`#j$2Ij>Ic}#8tV^zq_I7vMkJ_o7Opc2Cv%<@7ujLVsGKIKd?{n zpc8d#p$BW(SMufK&@y^PG;A1+lA=*kG?%mk56vvP>?-{F{AI@sxo92jfav{#kgDlZ zH+%P(T|r-sg&zA7JW3DRjrV}N$F8A<8A|RM>(cfOSL1-hd_1%9zx7SizY@~FNOd&h zY~D%Ilk8sXv#WbXKj@o-o_=p1`O}ee_|wehiry?A_E6gHEbDz&WWA#9L9i{dP6XDG z;cdFFJ>pQpv5r_}k673v7WRl`do(rwZ*zHXhVL)U@RidaH|Mq)$|^bjzrfSN+v^$S zpuN`N`%k_#>(+MqmMrt(<1F}u)4aO+x`lHp>ubwP>60sXRwdAn^n)y4cX*X7UdZBw zEMArcyD)Lau?WM=jXaoyIy{a#ls?-B9q_J?n=_hAdwsqo&3|bw!=B~;tGwhtb{`W1 zNlwG=XY)a;?Upjvd(|i_voPKt^gk%}I}T;^&pdnGM`4#QwBOG0FK;M6W|>)?L0R-%|7>OLJ)@i<=PZXt z1Xo~u$ng(BIr9IZ9O@fg&}1a+8Ud?Dz^W0jY6M%g%HCxoL2;a67mNcoj|u1C;rcIl zl(Yu-1l!SfWOXPcL_Bz&{C1p0rv$no2?NcV83*w<+!!87|3!s=-K#%?+DTCIfoCHd@V*aWSVTDQEgxPwbbW>pujk95LZMqqJ~%zSK+yyA%-h53XgC+n2)@*OO8aTJf&I17`yaXsI1j|Yp0Kc+$@lxD3&q5Ta~!!_1321?1VAit2WLjgm$ z$u_PDW`BVDU9fS@jaMvBX5)Hc+C_*@o`s*BA(?n&*j+ROa#-ykbdOA@w-pKN$1taR zR9qA6Xj!-7DHr$Xv{guPSwm45?lCFt2t-@-$_@8~XeW5ZS@d2y_mtROE~_{is?hbgj%kB+iiNy(2u=^-vbzP9~ zEnWYT;xCGSk**t2!L9~6BWIXU=jmE=hkv_K8JmiYZ zjGllv%X$@c6q%(0E^8ckL=K6rL5j9kSnuQ_uso$a0VOHtiE2)$LST~hJuDa1q5>sW4slx<=|DLZ%6Xzz zDRWc__aykgYo+fi677E=MqTuv&2Tl9Kia1_3(E~LqBHxA182(`32%-bsswOZ&%j5c zhqGu2XdclcShNq}2GL_xpjdfg^yGx6P(YRS7l;-;RS7WDT7tr&D`LnC=2-NK%IKLY zFju&jk%O#GzZDe8BvbKF)Pnn3Jg4buP5&81ltO)XH2N#oy}tjUh#yf$;mSh9p6r(q zk@E}ujCK#AcX3$bVR^SNz7br6<%mTfBjE^4Ygy0Z*PWUCdnn_weoyY49XAY>=(9ee z&S;2oiX7|K;Rp;>f#KF=u!%cYxp`sy^CZYH6_DGEczOkmJ5L9981dQJ2oBf5Ta5TO z@kFXSUj?n(jQ9h@s6eOgg7-Xw=H>cL7QHqkndHt{2CF2+WF$Hv>I0A}CNnk;4k#>o zqisx<3Ru=k9|GBNcO%YaU4rD8!OA0}eOuvJF+;R_cKJ@isxd=#=nCIIVTPC-9lFvt z7ox=E>d;lbcVUj0VLG%Koj8o-dM=Az$DDHAr#2B& zmP~JtGw(IypU*+CJpH!_8hA5!*?aKB2}aI5NS;jM7Z*eBvUa$BrIFr*h@7K&P~MaE z1g@>E6-&mLMe}~yJ&0DPy}*SqsDFWU%^r{j6u&5 z=Wjul9=jk4*0oxO2@$(6^;5<9BDhoRBBemIDl>MmDl^XdCKD+as5Y5o(N}6>FU%G& zu2&3onS-b;csB^_VH|;g!n;wJ8S2s!ZhFnGnQ2mCAkCi7q=UVsR8d4aL|uY377frG zYK|q+ICB_{Sl$gq!pyVT;(EB|>)kL?nEC43<=u$u0(BjYW{R=M9AP#hb24$z%1gl^T1KFa#tOF^Qkv(P4}+6C8SOMK zH*OzTc<3$Hn9M(|`ae7p3o+xD zs(|6`ShiHeFH-@DNe&z_ez{4auv}dp8Y*Nf+NhAfg991zDvY&K(%U(mG9QXZ$P)az zWG#N(ayfn@ZZ1PN^+<4}cazj8vet^j` zyz@dheo~j2j^v?^q^mao)liUhjT#EjleagDq%Cnxa1_(Zv_QQzj;xL@qN^W5*P2z7 zH#+Ht1C)0U%$#&%8eI#k7#^NE<+2!(8C|4sM*ZBTb35SY%MSZ{o~E z8xt5;uYvz1Jz{P~)cID@6YeOqkLuQSYs8bPYpHI>f7t&#;TWv3V5JYFPibl0S;G-{ z+Wa%}vFg8ez7q>gzej?Q-=X0fQoT%H4uug-Spa{r-}cSg#!aFb~HQ&~?B1x~!94Vi~m_1tF3+={8 zdeLpMoR7TY<>zp}3GyZ6nkb(}>LmGZn0c}s1q)1(FG151`7wS=!VBt5Eu4xf}I$f&4Qhzfk&M|BK{34*WZaoD7}~@<~{`QQi&C zOXM{uw@GHgVoPNYD3{9@(P6ES)sUoFz69I0$P?&HR!SEvyh?tI_|=j=n6XB7!!=rE zH)^U)K8D|R`2}S7k#r%oLp}{H*2@0Sw^NS8?`5(V&Fpe%;QGh%G)nK1ZIJK^8INXr zrSu{1Rq_t}ZkC%+vscSX#9t%n<%e734CuR6-ja=fl8{;8bDew(GG8w@Lbe;E6R9`K zEvWs|@)6X|Y2n!gA^Ka;R3vA5ZUB|M1SSyjaj-DtcCeQ6PME`#C!v@np8`9F+yWY> ztbte&at%auN%}t*x15dZNa=#1qhvC2Ma$jb5F@kU5FYt+R7tFS0qznfKLTaE^dKfd z9)Vbiax9FPB=f;JS<)M-Q{-LXpDI_vX}t1ZdF0~sM%Xm@8r1GD?}4!CvOmflAlE~I zfie{|gX9cw@X2UYZH8=tnKJ3siE#JZQDNC~J=m^?WJr3{xQ;`8M#sH6gkJM&_MJO)06av@4AlJth-k@An|14qg2xzqr@hog^? zw}8)Bc@?A`Cl8`g70bP_#(4P)NH{_M9h4L0Mp%B5r0*S0mREr16zN5kOqJ&$rbMQp ztWx*Ps5VQ! zgeq~!f5Hiz@=dr%guDsu(j^O^j9V6>y++Et8C3nB;u@2)YVeGjY<@t6(F)fy8$UzS zqgtOpf||icwW-|=VeLl=QSGtk!w)QP%hDnd^&>Tsx)2yCqB>L{+IkxWMy*xr*f?t= zvG0s_L8TnRQ2{5)*2|1l9NdNQnvLI6rPf&#)Lxa1Ija81x8!+lE{>Nm8aMm3GYZL zP~0Y3o8TlVBUE6LbvryhrBKzyWa|(rJY|&1GsP+F_~^9png&&DkgKRSK&P=lT@J2a>D^rCM%8$tX))a ziORFkvZ&xvMRtMpDV0^G0u5Frk(H~!QY!}DmQtYt%~liTsZ`unVN%5P{!mP<; z=bF?V1P931_?QJg-se`<<97y-Jj})msb)Btd0;w5FnBmrJD3_Y4N-4Cap_fk8 zH8k2fik6$2tx}5BgdugXwrTuul$$yvSG%rr#Wk&tSm;fNE(NRMQt!i!VwTFlKzZ5 zXdfb}M#WenX$iF;Op%gy!3)q(L=wG#53NKb{Tq#x78y403p}(hC*KF5AqPNPDc?ow zvE&p;iHSLE6({NQ4?Z~xgeCHFbZcF?SCao4xgVe#5HfcN+Kn)Ce}*P2tla4Yu3Y-& z5tc4rl2E?f(a0uBauZRx=t$no0+140U{a+7y_p)BMN*s+8InFsyfI5ms-+G^_(al= z)J2y_x<*|HBPkb##vzlY=nE^UFi*v}lFIc(Tv7=-2^_wp79CR}+y`MvZfgsgbk9tG=7Fi0KoYb16odCFLKe z`t;&x3aqBspvBUc!5X7+51Hu(L38{A}77utd{@7aDt%6Dj3iJgj57E!7n z;v_s5q1codSSE3qN}pnnNIbY8~q8YsE1KHcA0NHNa=z*CtejvmZA61D>+1Z9Wo3Y<$RuE$g&O^O&t`(Tg}Pfv(OWybY{{k z=yi1Zjl<9ZmN}16j4Ge5gy&N#`Y>A7AZ?Z?Olfq@rPKGg2G%%-+A+Ei3JMQ(q3N~6 za

_5vb^yQ(@l`2AQ{(B9(im>;jpuz)73XYbo}Rs3Zp|u6{&%D^yH-&3T=jLlKB_ zdfk26M&rIfw6axs52Q-_vGH>|TBO_q!)08VK+C!}?N}{q8>}K`R{Lm4PeRcf?OCXk z8L(@Q66$-3Rjnzd4Ti{E>mmCj!3!O#5vR0gBDNrg?)!|USY>gVM6=i3h5l#I-O8)z zUH962<&VI=c%-V4V$=_{YT==`NiUuSm9yGBUy$)npmRyyt?HdNY`IMONJ#QS@l?v) z!PuLjO6FK4$v%ozjY$bP{ud-9SfK$xPUB8`n|lmxon|_6Nnog?{%atH_G2?0WwakV z9&trDW14UqEz>dQTU;;4xq#vt5z|0i9z*CMoY8-Sg@-s2nh-}F%zlcy1MOg_L(SQ~ zLinFJvsy%sj-fAD($_2#rXiYc2k9if&=ue`(U%G8d~T!u z+?XRbAg&B?)K7h^ka#&u5Qv9Gd=K-@w0c-$ zjiZKqDZ&@yRPOsDUBEVk>GjFkbhE0{Qa7v2?JsZ2&P4cPE1C8K&F$}QivBbY-z&BH zQ8|x-{yxfcEoe4bUg`qP?Y*0_>oHsCvb@yqB79jkeOGU@o&L;a*)KtstL^m9E{`Tt zZ_ygP4}O2d86AbVtvc?X2p`2c;RUGqq7Ut#=i@JmD1NU*!0T^M&*UYb)7oog@BUN3<);s5LKTT8J> z`wi%6XdR9`NHe!Ta~WC#X^b`}T_wVNnJH%56rWwLDL@E{c45-J4;q77GzHq1B6#L9 zVfv9oW90RHlZeGUC4sq~GykkF1v0xfb7tLU70+NsVZz^4U;n<&XM?=!K-6HXz_D>>=zGn2L<=@Rh$ITuEXxpo@ZRX`+F5+X>ePSAPi zzTreSYB0l!Mw`@KN`{p~4JDr%h>>AUpcdk!R*Tih4L|5l7QFWQ?@bjX~$rCcKo{QztW;Gf*cp zhOb|T+++FrakQ6le7z8kKY_2Qdz;ADv(X?Y@%0iPY^2*@k&}9;YTbH@oR`2$uzOB z%+_(M5MD-c)P8Gp-1P|4{&4i4;R>~8I^Fes3gJBz_W}l&IvsZu;lnsbS+G_P%I=0C zqN^ZDyIH7i6{DN_9t5sT5YS*jo%%-nVyxM7IWkT{d^0kBP8KA`yWCWcXKvqlxw(Ne zy@JHP8C~}yiAI=^XdWbX65BZFLSw=Zh@#luuDzSsx+Wm;+1Ym%*9p>>PeTIct0mCMG~#9h6j>_xf*e__$vvC+kiM)B-Mq)ZARQz zs0eyyP_q>#jbydRd##Q$w{NAnLx=`6EvMo5ZkqtUVD3RA4ad&~IFXxF@Ni5Nv{<3x z_-#AeXNdeIB564OSD$R!p6GHw@d7AlI8H#z>0@zWPC{MNf;>kjS(pc5Hc^FG8i}Wb z#=5RVEDyzsj#NT*h>72!&pjYJsNYdD`vY=la40z-$E%@)=Jqd2HDoxcyLd_JVTHPi zm!;||)DZKER6|TEhLzW4%pvf1{u%}Ufv+Q6ct;suQ;&E^28WwB_?mjaH}y3QH*fJJ zhMTvUg8HI&q#j9VoB9K(wqcz#+J4A1v}65|R6Evc1@dQ(r#lQE>+6yxl;osN@~={j zGFVYiH`>b~G4cFNA#RnYL6%RCL>jlsQM9Zbu#7INX>ps1mq7_*myD+sxbrRuaF0x; zm2s-F<-JnfSx_VH{n~sb$EehgBQPGxlrKJ2!j0dH977@bGMCcbX zg(?68*jq>w_IU5(Wd-f;hr8|dClv2keUvdiKq81^J7@5?> zDO)mh4)!S^ajoQR+<3+K^FhBznQ0D^j5~j3n`x08PiCUmEdCLvGSebCi_G*dgiqj9 zW~$d_ib4%V;50GKQ`>{vxa`j1XgWrPa6ulGpo%W0$SO=S`yskQsvQ@ki!z)LBA*Ma zkQ1rEL10Yx4OM}DUEnB$M^GI3V3l^!X$Y6&q^)-~Lfr&L(KHL4shxB&66uB;<_NQN z41JPo70zgypU&2C8xUTP(@Y1OB^Xf82OGAS+SIsa2FAQV9I1jX7y7Dxb#ov=M2$vV zM+1Ib@J2y>wPusZ{j|V4kkHRawJQh;?C6vJN5DcEe2N^~iSloSFxyE;>Q_p%{!b$O z7*2e=5mhl(M$wK09g}bxcV1DzEXK+rV(}(OU%{z1jmFC9v}xpkP^S^6Hg&cmgWh;? z(U5eGEs_cHocl8njkic}fkSPK5LdM^k|dHzq=NU+3lxM4OONp=eG9a(c@QiMrxLb6 z3wt5L=i~f;5O(B$FYMsrNEE5sK?7tr?)=6UDN7C`7o>aem)as_$#SyaZxDV8XDr>y z&60Dd2EIi2?>Lp1?n2w9%5BJ|?}9IUAbjg-$bT)W@+s;i`b~$R_hASHJ2yHMp*j?{ zJC&^L?iI+^h8)<;LzGPGxeh)^8=k4LFs4UacQJ-OloeD}V^O{IKMFAzGMsYW zx5#)cf|ufqrMZbyUUUR;e?pl46Cn20!E~!UhvJICvH+*jI2UEy0S4Rs0RB>#}1{y};u z|L7-@$$o=x!hn1VC!Wf|Y22ATij8{8Q2u{E)Z2+u8TFK*{Qo0_-=sJg^^`G}jOvZX zb_LGZ>6lQQGA<+o)*@VuGt6a_0Z$uhl5`!C>8UO?8zuvuhD>L1qwn!H&vR@Khjl;w zic#`^GR5F)a)dadwBD+;o`nuuxzZ7>^)rxZ4^E}^5v}#N2p_|#{N{);hg2Me(z9?X zzd2$wQrv9_Ux)K-YJZ{C{wtFIh%?YTd=0CgMeTq5*J_&;D47g69GVcPFuyq-&I#n0 zIV`~st$F&jBo_Q%h;=bW3{OwH6OZPS}H9Z1_G4e6W?8Jo0e zl4fX|GTf#~+6K}jFG(k6eHAMrQUye;wDOSG#}5z@0Tsmo!2!{Sh=}NqAMy}=s5tY) zC;#tv?R|!Onj-jl|NsAY+LOE29@buK?X}lld!2pmeNhSJ0TkbZ+Y?F}s!br27s9M? z%BV*L5GhlL)*}J-xD1o4v~@@bpUpZ4c+aq%BunPTG-C?+ocHs^aLI-FPBb%5Y+A0F z|E?(^xSxUAAK@0}ziU?0;1o<&0I=T{CQA!AMVMFzJJYZX7v44z%Sz#Dfsp@ z76%4u?gT^q^|KR;M!}&r=H+D>#)C3g=d}cZl@Ln$_+QaiA!XFPSsHxB?yZpybzR@ha}r zP5^&J;&t39Ljba{^GU}Yqp_mr4&Ec!FQ`GMvYN&Z!ONFT=XGM^pmPfu$324*pJ>pF zk$)CBe(oK}@#O{TK?wo?q~k>4DlNym)r@Zf4Qp|W9Pc*kD95V+AHC+2AOzv?7pVOoxMyrY@kAUJA^$8Ke(LRWSo+8m1nbPH zB%IeEZu7(v42!G)A2XLxgJU`93wQlRan`P<{}VYrn89<)A2Yl7`b#N_7vh!$?WCH= z?SPw^N5wy7$`0`|z@xZD5^K?qn*Oq5x&@MY3=)O{aC4}9xw$LVu7bQ~q5cFj;}dU( zU-&Xw$Bv*IIuhw`zWL^r2tlcYp{6)Vk|~~ROraPqxSA5V&YZ&OU|xzG74f*vT+bcF zYzbFiXI{t>v0)!lyyH+1c3krwEWw(Np~e1=cuuTdqa}OPl;Ha(Ac~LSmPvQitY0;87ekJN|-(zX13%+#X0I_wmll#MwI%Pux%r}7`}L$9ZC3r{;0PcH+04!6+n`wC)X5=!l7z<%Z8_8g^3 z;GMumT=2F@_4bx&HIM-}nG$|xC~23%jnxVEgHI)A?9f%vBV8yJ&%#8>n2N_V%4nd5 z{6?~Q;=T=<^31%+S4ePLh!9s@3M?jJ!G4Pg3Dq1{_edHeENRCo$^ z<#}7MTSNt0{=&Q)3r**$^-z*gl$apwO;k(W17I?MG~6-B#`r9aBqKqL?8D+o9FXVu zZa`beNKU_0q9U#NPgUL-QGm0L6s(V)_hQW@M98x>66+(%r5mK1FiH&9-!~-+pNEkQ*jKyRW63&;H@zbTOP=;ZcgF9aqrKdO2$_)X&ka-LfKi$Q} z?@GnX%9K znPglCfG^p}b4$yVysrZO67wk66s3w!1AdBm1y~#>sd_x1^b_2xA3(k5G4Trc-11e4 zYF9vFrML_D#Qawhb>9fEmRSsIz9v~00PJQKW0=2_tTBMY%zCTSarsmLb=pmCwcFgp{W=kQ0txq61j#TgT5u};yjmeH zS?MFOXWoW>0s|1yH6fy*i4pzqtcd*is1RMK5#6Z~CGEQ-vFAgG(ovmzRm?3TZ3qCL z$XN%G;A6PQ6%v}+wCj;a@mV(`!3Tl==@ohp0#Bic!R08}p{c<$Lia)7Jt*Q+ynL_7 zNP8A}yLJKh?~oWk!ulH$d|bHEtK~f|Oo#CK$nQL_$cR-UkEe3M6zm<&>Cw0;zljq_ z{H9sP6i(9Wy->X;y!bX82+ZEu_3rF_LgL%M2CkQJtJ(WRE7diQKJ#(QwDkSH*eqb+ zh=I@Wus<0RasxY)vxA}0GOC}$nulEkUls%(1$ZM7EW2zGCIH(Kg?S<$#43aKDLGH~ z5Gvh=dr>`f-Tc(*ucOxUfS+OBVf1Hys*!m-4E7h~36YB9)ZqO+STv4y zGH)AT9?%tXt`TzH1o&s%%8a8gWyZJA^8iL8A}3!zu>mFG?v+827U7;jAxyN(Y-A&? zXrbBs@sOgSCN6p4@owN3{m+5^BfYE=p$@uz#zEZXiH`!UlER<}yAvcd;?C#6U2|~d zUr_48JPS({vmw9cho>;%cpxEJy38O+v|oMRsY{6X9zkq#vhfZxU~1ZJE|~juy%*^$TwJMN7Ln=H;&x`_)NlfQMp&Ls&Os< z4mdLKji8GG+ZmL_1gfnxl`<1e&Bi-mNLR1Nuy2&tJJ3viV--(gQLyOBg}}X0jydcF z+8*4?>3eOGr}gg#_#WI=Dq8V%ksHwll2zjY?Fj@}V_B%fmrN*mN~!8u7~05}&1t^? zVEq&=#qUE-9Zm2OzG4WVgKtGlJ7`3{YEI?b0Y=qDF%)by<9x@?n!4F-x7BR%+if*3 zaNBjb?fz{6+HKbTwRr6|n+<-u&1RR|Zj0M)MG4x~o73fuce+4|&U&-nZ&z=2y6raV zb}d_@u;XNo7u+)_{2OR3CLnU3FnK$KcMA6+VfH@Z^(%nCh`aTmaX%T393PiQ$od?S zFH$XEwfo}M18dOQ-o@DCv(u7hm;eq{xk9?Qqn%`~J7}C1S+31T2d7xQ+pB)6 z#;<;AtFC^Vs{SiX$Xi(bm{c-%4aH1FogS*9L(2=p4Q^KC=es_{fA8&wiUH=pUvYL)H$UYQdd)BY+Pg z@h;pcrvSW!#B;dI?*dT%ApZ0a2g!l$#*LRBGNjqeIN|}g1>q<$S3eBfD$C; z6L=lKdL-81&a%;M*z+>3yUhs#s10dNS31Go)q z1O8BXeuR3;SbE+*5mHzF;1{{x{zWL_yqOHas8+BK7LLdH`-n7pextk4#r;Uofm;)- z3}@a*`-ZNP_PkCQi}@-_C!jdAAdBA;2BuRA@Oc#EUWGe_qjxhBHxO73;7%k?6Q}|3 zAQC+5ZoR5|{dBlj*@V!tek)kQ9V91|P@IJXh4O2!h9{H)6j3OXK%bVE7D}uHMPuO8 z69{=UEX+^Ybya#T)PW!FmKy!Mvw2ULAGCkGvT&OxK8-f1HzA7;6duQ&bq@eex7+af zcc$A0pyQcBUi(sr?(qcBU5>0*fa)dOsn-BVF9J&3DK`SBL!t(E`E3Bo@8O>>;LjW) z$`MpQ!rvPs8F#z5wxaeH+=A;0B*t-jXvIik|zLMhumv%XFUsm=P*-#hQvpa^AX&0_#V^-)W@SQ-2WDtR)~hF!^pi0 z#kb*3-3{PrB)*5cgtbyGLC!0HUc#MnHGl{__16g;2XGF6LfrC#*!MBIZ?wB3Y{;=W zD#KKCldKGBw*vL(F8ndlK%ub*gKd=~!QI4qsgA?SJV&|?nN)=i4~JpxLmmyu%8 zKNy+xo9&bpau1?-1b6Cg05>7=A>1Xbm2w$!_yr*UhCAyR03JL}xdDl%kn=s}o|4?t zSESs9#LtoQW85hZ0w|n^lY+QYz6PKJiB__f{DE=(&)Lj6+hQwEJm#|jWCCK4fi=L2H@vF@H5<%bhG||67@G7pTCT({vA6WL&+Pc@?W@9_X0?PyXxT1x)Ok}^S256 zG^wLW?6x?PFC)=%e}e@ux56J4T}K#$q1tD4wn?O_ygn#P_)VnTYYmq14cCcc6BL2knb=b+N+c&*( zZ)v*_MYKde@rsPt9^^49r-m6qsQg|bmVO8e$3*b=QIvlnvLfR=j0+c#Wf+rlIY>VS zP>V!02kDOhI7nG$5fd;O8A!CEXbbL?82~Oog5O_~RV-CtKlpWFW5^k1l_~&yi}F1L z8UcJ9iH{QK0B|1?_Yk-c0AFzUI)RG-{0NC35I6+j*GT-5z&``vxm|uIPs#@YWB{0i z8$V|PJB7q-0{;qN6%tDcdz{kNUeRkjF1hVdTG6Ues71&XNWU-ya(>ssVd&wmui zy9IfCG33`OPv%eT4rKDh5H%ra)!cVUu$UW_d~Nbxh})FE4?(^UN7hWHTU3maUto}b zjyrW40KQuCN8DLU0q`~8thJIjc121P6IkO++$miEvXRIjunWLKB#H?P0$7X0DguWA zY(;`!4wrHiz#b&Hf~R~Cz~xBr>r7H^0l@Y8dIEO<_+Lo;D}nm}d<%&$;m&#l0F^82 z+me8z^+P273q^ls-Jbz)V7e{bi+=-vud%GY041*h;6gkZcgkM@tU+Qafmksd8YFsf zFU|vSBig(V8=)+QMrjqS7oy4t??bMrue)%ZzQTz83592y1$;egD_=USN&#|A?njAt zfyNu#h1|DlYT3Ze2MsSs$NFJ|ef%Z9x3f@}{WZDld6cEKqih#d^02N{2pJ&Q27?Rd z-#*Stu~WJ%kWa+wb+7XsD$6GzipQ*JH=(t>?sY3&^N< zp@_47rdNc=J;>v%FALq*UmZ*#Sv1~;@XglibqDHJjA`X^PSZR$#>ln#_ij%QP! zg7*ClB+kX8r;(u7egg)M-z2h15ir)@`9LGW$3H82N#eEwH zVz+?XJn<&5NR0P$P`uCLp27SHV!RbRlgKL_w|Rn-LCzm?gT`0JA(O zpjjxxTXvV5SLT|zU?c;1tJBt`tx9Xk<>7kAF`AGctz>?oxyE4uh^jP}=0>JHSThYh zs^)M8rUn{=3&*dM)@ZN`aGZolW5{p}E9PO>nVFM~v_hMmO-8Zbxh~EU3cyBokmQUs zzC@eDPMUHnXE3~<+hkm2=91w&VHmnFWxg;qwbWcc!)15DjHcYG8I-{^w2narn$_vR zPtX&|4D$PKa|YST7s_>^rfjBdt}9GQgPc?=;+&P-mFj4=Zmc^ha780MX=HO|n@e-s z&4+57u4y|8&2DFV8u7(LOk<=9O|wbHu&5B+l_6)YFyaoHMp*3jBE3>T^E7Qzu`s$| zMz)y~-7x(U5eC+Ww6t|;JO{ZT*Gx+jmI^14hK0GNmFechm~)N@7z0p}W_Cd{7RkUR zOJ{K!80wnF>iBj_k-p}?G)PAp$0JBcSy0k&`#AhmZOr+KQlJdhJvR*}RdS;2qtcTf za{>}v=J%GiD$MnAS8~CjSP|p~f!AD6UxnGWsuXfi+FO{BEWOo~1IbvETqlmfLT;7h zil&j>xD4%DRW$;IE1V|Tg%&HXQ#48bR8EWaLB)jPW5hS43Et`;Z)ZrdMy6?D%vJDO zU7K`J5K1}gJS}JE^}@TSO3<1H&S*UgHgcvjm}@ka8tZ{zD3c1)Bm@@bsi}i7j;J2h zp>TOqF6$w*GR0gViq`DXoKG?)`O|TWH-c&gq-`&BNK#8!PC*T5O%@i_yiE%mz2_~M z5m!RpN^Nv?r9Io6mzfJ)pPAV;E!*T9WB9&cQGb}-&ShdWx?q+d>234D?e=NzjF6Gr z5uB88o+^!v+61uwow$wjD4%4LgSfU3s|^mTUJw`&89t>M7Y6Iif*ngF*Hg821?832 zowgm+_9W-Qh=7)sMKJHObODeHD7lu!unCIgo1J$4(MYOy;Q6GggTK1kT&%5g?=j78 z`yTUNF0}WWM1+CT%30`-rYXmE}BWqy3w zeAKkYO_#rDo75;Uci070Anh9Se$>*<)khQ#2#{n#PML9Yn;l<_)Z$B!y2=FRHv6b~ zjcFoqf=kmabsw;jnVABiO+n^PjKf)K3Jw>GtW!U4FrRk=LSbEmy792_+}U;Rzt|IXoSCISP*G2S#6p4np@LJ#c(O+(AfbpTDnMLOsspm4BgP@4=%gK~i5^s`nnyidfw!Dg=MQG=_^HdIY(N~i zqI>X1WB-e39e?<8`>M#7qD)9RYB1cbYv2bVkKc8<{U`H&)VRy5q0}RidC(X!W*xu% z@@SDFX;#)jzqk+6xx8mpCQA4s1x^zU3Ngs9=sRIr)KYlOJoV1}al8Kzdz%7}I zFjG(1W)WHz#FLeW>6KrKROw2jRt_OG^sFs&Bz8SoMNQ5{d~$za8`nWW?HkOe9IdA) zcu@)>P~XTE*6|aUW9EI;VS>%%ik3@%c5KXmjG`qVF)elcH6yB_wDQ#BkAgo{w)_uv z08|L>6$I-ryVw1}vW`D-xz-VMf4>xAifpr=Fkhq%e9`{e+shT$nV>Gfs;m8)`?nz5TB7DmRt zIdTj6za{cj1wR&fEMo4oAB%hm-P{fe@J~0p4|Y=uXg=|c=}_W@Fg_7ezIZQYV{?b@ zG?YATWlb2IXf*(LloM_6Ry!8QK*r}HU~q_(*YxKXpAZ(HqXvzy0`Z5$46vr}r^ zJXOy^p0&=+OO<*;8`PMsBGLJhCpKWZECjK|%z-|ehDv60@)ez4LRCDyWaeo@&2UYf zw6ueyi$)N+p4v%;%;%+Br-Q!qc%Zc%FG5yPRUk_>a9d=8^Gs>sj#s?OM9d<&*8ezO zqSrLb$~GU`GhYls15yo5Ai8PSnM4Pg<$&;<`LNRS&qeCo2BaFKh2}#upgwe0S(u<% z^D!0Crk!oJp)3D23EidkP$oj~|2M6HuPCwKf?7|uGHyiyIod@lA=;Gzq|Svxa`}<^uDVY#T5TQb612<+n5UJPAv{fx40Tv)iuGanhTTU zefH_R0!>$}3^rZaHc`_F=Ji61$wF!BjtQCuheY=(!yzWY6?A+BWUqR4v(PjsdfhY% zaYm)7D?>Ex&`sSeH0{u0ipE7m)4veENNvJG zV-F4^HGFJ>4FDT!GJV@o0-2Ny!gdU*CR#GAn{?@h%7BniR}S-6LNqHIgISI3$ZGFQ z8G%y$6O^iR2fnJ4`V}p*cc^Z3>xsHZhrH6~6Q3)u`IX43lrG$?#vWw#C|o)(pm^YO zK2U4bD}q#tWYgfA*4+VFPeg=o=gx&V&lM4GMr!lhwaFsaM#!~sLYsVcaf)GDHYU@VY2eZqaJKi$jEvuVIPtK0H3|gYvxC$bJJs&J+<1xWtdxJEAOugwHf zUJ4>q8eLlGz7#s7+PLZ?gsVNCOf~Tx!bEsv__j&53Z2l#&IvSD5u(ZP z4U_B>Ix#srw}ap9($J+{Ei!tEku7g2ke7PR! zuz7QYgX;2$FtS@otcBZFk;=lU_!FEL3qa$7+Zd+2&HN-oi}#rCW|)r~Q60RCF#Z%N z6>mxesls>M>!)X?j=|?ZFlMfO(#|YR9lO$nFlA%33$aMuNrg>W3EA%=oQk64OEWhe zG)yl6JveTMg+Vr4a6Rp|i;#EGex&xlYMs6LROrjp670B2Dv+v>y_f6~Eg~^pZ=AKv0EU zX!VuB3fe`xAdVj5L03>yq+6t;?{sOQtppznD0ffS5P8@^;~fa+pII27#zxn6l8YB; zd1j#^O!u0Lwz+wMUhO>WF_US}1?{R1Xcyy)I}+@Kx+1^<;Yr|6gQRN zqk3|7_FV}jpt+Y|hb*1qQ&a@eSB%1%jvn+>LkUhd%*S}(iNH3ybg4D+nqe=kn7I^! zP&3a_)@dyXo%`KpowkleJKRPBH3oxbn_5NyR zWT`}$*j_h5q^B7|Za%?<{e<}t47=Bu2@e6DmC1t#i4wVUrlu8AYDL>^s%l^@6rrq?HfK`|&5NL%1i~i;BRno{ z9!#d<@Qmdc#pU-UjqQDuUKgaN+PiuN zZn=+#xRoKu5h^YU%o%&+nX~n%Di;H7v9xgYXyjB<*Qdh7SoI!N^+oe)+pD3= zajuAF;A$I8=v}$$TmQJeA@VlZ0wx!*=A^z$!pPspLdxsL+9ClGp~sN zgsAbHU9}iR_O;0NWEh<0hq3?rJbqC^&vpn;&-dtI3@cBDjKuIuWUt6^iu=sRA|3>G zctvxBtcX|tLZo;!!@d)zsB~IY#RO4xF<_A){M6dz*nvKVa{~CdzJ1?dFygN` z_~31~qr3dp3$5d?UT&X%6BXXH_{52?|8T$kB(ped2FC?w>hd;J(wTY2I6~0vGR*^KSphtOu z3zUjNYe<#kKu>Sx<{!9?=$8Ru!lDm5^OvqsisnnM*eeW&mQ|EL$)hF7Qxd$QC4S!R zSnX71g`fF4PJ3{W%-Cf%>&xz4yFNB@^e!7FO(W#*`{+(8Wf)?7YlyRjSG3bF=4vK+ z=LhrLxq-SmKj*M<=t@Kru-!hSx7&6kPjW9!&gIV3o(i4UOD}&;NYk>-4I>YPQ;-_7 zXHjy!gS7Cw0q&A*yhi8Zuk=8))L#&+GH6&flwFLz;%CA`Qte;!^X_wx%|&1LGhc(5 z)AJ`9!A@U`;ALdH^DRebLs_3ewkw4q$rj-}hU{0|X(Ig^(c7eW6IkAK6IaWd%v(5T zZZV;ca1X6p=vm)lJ*Lhd#`ylswYH3MYzXPU$T=j%!!v^FBFxu|o`bwGF<*{wUSnob zuhkXhS9IC<9mwtW74VX_+Q)d{u>)r%AK=-e7bDm4P$Rwu-)(>uLR#QJ-F6(PyOp(W zjoeG<-U!-s*bhXg9;)efai-89-8+&*lGELBB38XyND8}X;#9GWSBf>#dD2cv54a?% z68;9a53-qaJ&;%$I7*W?uDgNW{T64%d>Q!Vic9L;iw+Vm_j6Ez@=g9s@9*M=jkL~E=5%el&@-J@&Vlszu176TaPc) z@^a~=tH7&HeaQDs1Yz#rc)9i6?G3$PUT%9gf0yLK$=09B3>n5%8r~K9bm?|KT{>%Y zJ$|G>M(&AbCl47gf_CaPrhPr;gW*uLIDl#wJa5Vl!*Di9PSlR2+UZ$#P7cDNhI5f* zMsVWPj>Qb;B>`i0PN(5~L)TBuF&w@Wj0ubm?1Bn=-Sf8L%#z|vyX`9UR;tmYrsANZ z!8h+!b=!`m8;%O57&z5xIM?fEhdF zpMNd-+8`M6;orG5{?fExGf!n0&bOopoo3ouUo!3AnKyw@E}K}K>@1HD^p|Bge1l4O zBGN{vGNg=SxHxMF_#0w!qxP&T?5p8_`5Eg5?Soz(TR`eBn6KFOAM8_(;oK!wwb?%Z zLc?jtL_&DMPR&A;(Qpf~={Ae}C0RY&EYFFC5d%Go73#}sLbsjC#AO4MIPkNT?!s4<>g z!ZSz>5PigaBQpaIjTmE$uZeFtDjOWwJ$P{MVA-L8zPaOMB_g0m2v1CC0{&4E87X_79crqyK{3 zp3(ju0I>J~#>PhnhV}x4ZBO8Px_b@`jwi;CjP#Eo4+b3-`UZx^0l?fKjVegPbfK+V zE#`GLGCFXuXS^RZR97URcd%z{Ea8_-lGVK&I8$^oB9E1uO5?Bn~tAczvck8*gW`}_AJ4Pomtk&a*5GrkXiqMuE*n0#rD z^^Oh?l5l@412Tdar182O`7K?pRF0?&&}3t^vm*{xeB@(UnQA&tu46{Co%}+_iLOO5 zH)3Il30A@e=q$B-M1QtfC)YIda*5Bn#Ed&>(HduRG}lR+1JqV(X)}^0atc+>Jk*=w zIE$P~QERvq`6g0jXvNQUPC7o*;&8Siwizvzzj3LMT;NPvx4BI>UK=fqmf<@H@vEoV=(tY8Dqb)2&IRPTtH#&h$zrZ?QAIeBC-Uc@Hs0 zbK^;vZ%cK>QtC{?i;Q!el(nc^p6jH5uhoT4W(mN;Jb;R`xO}cP$%|qLp=R5PzMFrU z8;Lvf_<`!Vc}fsgHsnb07{F(%qWJ-v@%R|v%8A@%yZ^|T2g66m&jiV-^wzbEY{5=Ca@hX z6mEzZKW^`{F$d`Y8yTQG7x-or;#)IF!xAUE%$b3l3N~_kh-50wo93$Lw}8XRbEZYJ zoctmPb2CT5)laY1N$Tf>wR|;rX_DxtjD=aS$w?`4GNOwdXPSeTi%U69&P*`26j{-^ z?ubPxlnRW7)l!B03TTPxq>$}0C!b=Ngc$=alwK~3a@OQq-#HS8&MmY)6RmP#W|Si% zSRos*ND!5#S>HNB9#Cy&)cUNh_w6I4)Yn3QR3Phq^iCpe3&Zs1gQdtVv_3FN!GAo+ zPG(x~okVJia#1PI`t3ntg?_sz-VZSVD4c^jg)$_l>!1fGtqKC6c9~95X{ocd)LB^Q zY@OpQEOWLlai+ylTIhg9XM3rWQRr-+<4i*Wd6U+QrZQQ@#&Kt1+^ItIQfGUWQ>3aA zd7)E;@~xYkX#yb)p7N-V<}@cYYF$(%a~{IYBN?U6qHoFsG|~S6-dO( zoGCP%h0ap60DDX04)T_&ymFOS9(SfxIOVfgFE5wY65W9o^Eq@*aiKGv>euZQ1DaWg3@Th140i>KOPsk@ zTB*}(9YKFZPA>^yg>sQTm5`&rnVRc#AO)6Il{&3EoRx*n44Iy}Ftypv>~3csboyLp zGUhco$^iS;kecLq(5A`A%ZfWw6^CQ6|B^CQ4lRteu2iO|EE1c*73LLs1j6j--dtxH z(%JKzmFJW>bLJqcP)t8RSE6KD+*uiS=CH2H$S!y06bM8eT#Q8r7K$_4`uvqJdqh0f zSy(WKA2VkozmP@?pO}{T1UZjm2ikuB1`na=255b}(s9ywTr#OqOOMqoA<|eVs#X`ukG8kiL5o$-G z7QQWwpH)uo0+41EZpsydI=2dtvaNGV&zdYs=A;|sqw^W)ZpuYwVINhhODIxw zuMF~xGN*D4ph8(&{Z;dE1L_Z_PFcLE<(x^;!ZNPHrD8z+s^8UBVTIslVd#n-vxI-K zUUKr%338&#-K8~Gc%}biMwMH_Njw9Cglg73Fk{))Q&%vr8Abrl_ppw^xdd+O2UoDl z|1z=0K$*UJ1*n^e4kj&*i~Yc&olzErsdFX)y9G-R0|7>AvF#*VkQZZ zWy$wvKF@mEEn`dgA{n`YDZ=%I#=x{vO>tU$IlSu2fh?P|U>PeYfxKwmCM@{*(P@rz z4!et1EsR=-@nh~H2!V#l-D~C$4z6sUJ zL!PrUX|Fb68BYE@og@JfuDn)SJT#C;NdO&rF{tKjM}}uES;%!V4$At)NzHYPpN^Gd zg6`MIw>v~1fF*FO-{V_RDCWO{Znw7nEc*Ky(RdtwIz7Irkyw)BjfZH8LeN7I2i1)7 zG0UCli$O2-v@E32_~AmgEr&dZK$4R80VvYIX4M72NGLI<59DI>Gr?h&>h8 zQ%}h8{+xvx?(8^u#n+9N%Fw`#g2KTt=72ZTf`bA@=&0f(7DK^A+{r6HbI1dOsnKt_Zmn2;*n^U|GYclC%$cRUQMJG<m_B&>T}Q)&d*n#9-%12c1Wl zi3KRbK3cNIWklea;!~}+u<3blL;0V(Hc-K)JDh1{DkUT07ZB$bXD;hRt?Bga_LVBo znl4(49#r8z)B1{X@8Fe-bN9%VRne+wS-05DxaYE|oj5`OuC1gTvan{t%BIprn@+my zk;?Sg(MzL(V$Va@?e8RuxWQoXf@tXsM*uc8J2U4vchfny(8+-R z$(}4Kw_R@RUG&vq(m>( zPNha5m9*==O0XzYup~bKT?}-A>$MK|=c#anbcPJrYAYx16j(!W2`x7YFiqQSJ|^zk-?%%FXfT_--9>C3v77i*^)7jH)@wwSebVqGpBtDV>#PPcw}8T(Lk zrQ69Dql|6j^r(eHcc_tWy?R-kF$o9}Ih=vW&A0x18F!o0t@l}CXptAU{@~$K1b|W9 z^8IMZ?E}Xb(~`xo637s@(wa)2%>|}Z(P)fwSnq}dB5^_rbPwvl*rML#P0qO@`zmKr zE0$MyjjN*;+-h!H)ZX@=;?895N*A8vOv5UmA`EG8+NRAE+0tI66+6>r0iso)@)WCK z8HK>sp229DW_0E(awl5BshUU5xlv@KIGNk3JusZs1}wzjKt_ckv|g5| zB7Fg94hh-=t&*S(K938#vP9*|szJ>=b3(wti>g8>GHtMfLO6gXN8*9hQf_g};!X`_ zCRVl@u4=OBSM8j0FpR5U7rK$(tdMY~VQIp=CRL@*9K9eCF*fJGCwqHn&s;TPw43X4 z%l5KUXHJDPV-_+t3%gEqy|fT_2BcIuvtY=paQpzMqt+NA4w6DpjGrXRDgvcIg!z+r zx3eCpflW?+nKQsifbrn6IBBkvFK!ANMZB;)0)l!sk^w<3N4>oW=+AcwXFGd|eGvwz z931C5Q`HhU84e$;zG$iPLm0!zjnab6re(`zh=VDpqI6~Lh0iWkpT_wPI(kQwBMAmpNr~oDGN(?QyzForXfE0Kqhpg3v($DilF& zi=3jx^qt^f6%dz-S7amdC2I6T*eL1|chE8wtyk%bPnl4UCR=N2xpfG&&URHO}hnwC223)S!|g@eC<&|2JC@0B~ns+`(@u;7G2zyCPw z2mL;V*d6HPthHXm?@ue^gh{%{I*FoK93}bI|2a$ou@<2~*^7^*&@iu$PIW5a0=}aV zpo4EhgB)Rp*D6EJ)mVa}p~%`KL}eII>xFLqoiG|Ff!-T8A<6AUM)V6}D4L3#nFY>l z`OA@=jb%I|dN<=Z+4RISq64hQ%)(-AT3~O0g^Ig?*t(qsbDUf{Q-yTVoyqh;${bqf z!Z^cYCv!37vz;w-ow*1G6*`6cRG_R#*6(as7Ukj9Y2OPoY8e`@L{Jy*%`$}DB&?Rp zhztM;8^Vc0cr8yN_0<&ECg=zKlm$zWC{wB>PB6oyjEPGer_9N&P$ne47=9GCqscAPLU!QBUr z9CGt(GR!aq%eMtxowFRS+F_{woP|u_b2)Wc+`LlZ<;;g{41@}*T-(M|l20H$fvLTT zcJT%DS4Q$-g4mi9<1Ej(xa!MFB4z>p2o;zfDnhx_R9iS>LI_7lKOeIY#HEpSqD#eh zNTG}iWsGFQfan_44jVy6cnY0KbD(4(ERRjBkxkHtDNfcZ#BKPruhhxvae7R+6Ccb&w)x30q`2Y9Fqxy=*ds zp`-_wjG&1$v^|VFOOS&ZrJW=Cw_NX?GPUlWwY>}K>sx*?CMAR=rMDf|D8$9%4 zDHFs!Jj!I8xIRX$+Zdp7qg6j<=*s%!l~tvYw4@$?_ZB_=Ju%3X<$@lyJ{s)oCF$%0 zJ4vlfHWXFztgb*HdVh`fIfvT>KN@${K& ze9dRW6Q)Q|aii3d-M=LtP+|sdLNTZBYCUm{(cho<&ZK$btcrz;uJJtF^^}y-lc@Dz zkTJZNhVl747{h6cub5^eJxNu65+Xt3l6s)t%Jc-L&peC~{Mvc!9$R`o1cFcJY^F!d zu|uraf$JGE3cq-Zjzy?%r6FGLd4Uxw8ZRxy{4nvX#fg?kU`c4=v#|h$XD2XOGH-+k z3=YoQCJ-vj@CY?m@3gq&6+#}=hU5<43-8mnWRPI6$7E?tplq&4&?9|$wP-^mad>d% zLLBr!T$Ber0_3=4!A3aKWUlM60&S%s;%*KTS5BROCyL@Oj#OPthC-P$5=GF9CtXjc zh=y&p*fu_HQ<{^!cKyr$J*3N4?Ihtm;R2)LK?ILu_k@A-@ayl@TN zy*DvD(!;ZR>eOS;;eoNlxY4{VQNOLer8BXuy1A=9QQKJEva!C-*q6Xz+2I3H-qG3J zT%TyJ?r!bsG!ltD2ZnkR2{x>4ZEkH(G_35G~ z;|Uz59_SxS4D}zD0v<+`Y&lN4uYX|gzHuV~g5~Vyc+c3yir$*m_PYA^L`PFyeWInc zrQQH*>geUzk^Q@e2NOIdPEzXHtG6dQt2;I)I=kEI6RI6a=o=UXszl-dNLtAh^7f7n z9~eOz$F~#gYb?=&lc;?@0XPGi*w-`EH`qT)!6j;NyxSLFLvvS0V`6)CQ)i-~simo- zk^S`ZlxJdaU<~J74dJ5q!06cU=$J2uG05Q{&YAZob{|O$^o0?2bXK=_8Ur{Y%LDe{ zsSR+VwyUGFbqhLb@96YfY^iSFTwj-{t8cFFY--uaK1Tb;8x zf^)A$TXh|krfW+JYbK93&RLJ|(+H>qBcnKP+}ktK(>pMJ#Bc@g>2Ip#bm`< z?lIQ#$rolj+nZn-nkPiPy{WFV(ZGo9=^q{K?^6@@0JI=Uquc9SIB(nQtLwUbGMbxO z>Jth9I#pb5sotTpI5VjyV=CTwlGdp0z?YC@{ipt(b&;J>xxzv4Kna4JhBa6`*qW;BfE7iM>4| zKCrHRA}os)(f`#MXi#iXLlE+MeE@4Ak&6sHqkqL zKp9(Qfmi^`GfHa&Ljq9Dn&Mohs!FonVRinU1cfwU3oU7TeQl@G13fZqqh0_Q>FGnq zg9r8x(IW31?GbC%TC*w9&|JMS(a}=f)>aLki8^S*^*l&oL)l4x(Gc;|0tbe_X-oCS zdJ-hd5ao6z&D%h3Ydb{*yF^lhi;W^%Fb2lco#Vc?W@l0HswZABF&9(N7R^*a)% z+k#034XoWvV!TqdcqW!klv%+{t!=F>8xw8q^&POYV63gax|4-TI8mFv^k5Wv$S^*QjmG`i? zL#hS@(@8lhDEH?l--z+aX|Hc+PjF3;x!TdRvmQbciHZ%!Y-_1YY-xq3gf*zCvkAs5 zgrF5Rq#M4FyJ#w}NY>9Il(yG7Jr#Iro`Ha&pbI(H-%D~lLCd13oHxGgV;t-oz&gHf zU=YRuHpw;U>XjXsN!NE99~gwUh2CVU^JN&HOQl>~&!I*x{g@_Q&7FzX&Bi_|RuY{D zMr3B}$2)tz@T=Qv6SNWshVahbP=8;XLS?&veqvVhMIp|SM52c;>R|~31K`k8_1ebz z+RaMSIj=a{C{CKB)iTqQvnqTNu~5P@+jnNO$}_W8!uJ`2-j80)g|&aMe;hAUiDQto zwrC6E`tRThU5HfF{0dBBF;$qZ9UY0b=IUCp$7)Wti!vlS>RURfD@~n&by`|AG`DUi z8&K^b$QIIarF1~V#L-o%s#mW-w@K!jNW6ij2$eYvI9DCD)t#M~w4Qm;{zd;#FP3R} z0}xVIbSu;xTlOzTS~^Y|fR<`ee>74vxgDNTH62>CNw!y9$OilOgce54k#h1BRea6O z(Asl|LnoeMQ)m5_4nm4Js+|yW#@KRuQr+CvSPl1FDQalNmAT{*jD-P4vlgp^k6ipg zG7i%?Fob!=Z2}k?;g)M0cwu_Q5-3_a8msHz*(!3dy$dW1%3nF;O2eI>%7N(JZQ!ji zy(bih+M^17VOzkD!HZ}x34vi3z1awVnnZhZNX_U(eRFk3XOq}mH7HH+<+fqz>!|Pa znG84!%nS)h2H&qN5~+hzAVxc&P&L)ZT~^M(&Zbt`AGs4ry)0=Q z;Q+In;I11gvm>%c6k?F>4w;+5A`b2lv80@PH>=dPy{duo^_{$hZ4%##&SR#?nZZ4Sg> zaKFhFfsD!WgLRP09o9tB#B5LB#HmU&w<^Dk4nd<*5WT8bx75}*8~Yh!7**PvB<7|w z?Rith8H3SOd1ls1W-0!u>xr7KCM;TT6zTsM-nNFd6e*(JvahbG$L8DsJw1c+Lal3Q zbQlNY(>rnm6W?2gnJ}=h^p76IS|RkQo<+Z!t2@u!3`wSJgS3A<-ZL&e4&?@E-BexpMmMFWt5Y9ipz5%`L6lC4i#nMl3O~ z^Vg#@g22!nXpYgWCYznJS%}HfQw$wPfVzBY-cDZ&&ky>B8kL$$|<&q0Xr{8 z&yLPUhM|-h@CFM}N$%wlMdXr<7qz)b2sD*oE#{Skae*UoJoa2gvH^s^KPI97_4l4{=Hv z{z+o>u!`GiR)HdEQIUNs_wt^=#7@KW#`=#u#U57;zlNgA_1xg7p2=#!r^775Hi}NU z7yuPNk)(EJcdHGM(gjLu&%h{x)ymTKLN?fMDQm)hxDrurpe^Ks)wJ$NDBsd270bQ5 z(qk?$M(pvFBnDSk-3@4<7B=nhs<7L_)EXWgk9#{e)P-N-Z{oNwh1Ed7jUoXC&p6Wj zG9x$*lmdAp#qFaz2~abv^0Gz|MTlnvJK!>SSnxG5UYx=wKs~CU98i%Vu>nyy*i@yZ zzWYTMT;~mS)f|-hA`edJ(E9?^s}(ama!{3#W?%KL+_1ga4vPP%%38X%B>N&A zq)?14t(IEjkfZFo8<QW=-|3KQBp*pHdub?Ng( z1KiP89q`B1a>BYvj8->eBKP+VjQ7BK!s7;f*$Br?)=0gFQX6JyTb~*TD3<#qflHww z&N}8;(x|pVYTR`vwl#G$Y0t!SDWKa;$~t;lkmOkDpqCnP*@%f_>FxTHIAB1T3qBtU zj`keHQ!WM?z^AOM3NQCigTq66fl+l};`5oJ}6%Jfq*;8%mw z)Y4H8zlU-axpcMF(P5R?Rc%vyZC5k;MyXb9FR;aaJ?rK^CQ^%+LJZ3Nhdn_B;!_4c zQs_xgyhJxnt$NejW=`Y2p0Ry8l*-7Kcvs>ZNU#gExQnN9KID;@XqqBP;gcl>&uOq4 zQ@ap?IRJy4;6nssd>T;!t&&&^5(I@v{Am6r)A=y>P1W;Vh^CVz8#9>k>^=y%=t0>92bRZ+Otq? zQ^|{Zw4+=fiUR1=V{@ge?lx5|`6^HRo6wUU#z2)qi0ZphXJ1FyYhdfQ&rIqm|*cl&Kix}Z}|KTM)s{ro- zJk&otv}Di7(&dB)hkM4CAiTR4gVKkL@qGvO@5X1(Xz#wY_@=glE0**u+CQ=g;q66% zhI`{nTF2r`@GVtq_YNJXI2>QHhvy;22Y?z?`HA8^oXJ7>z|bMsg(Whd$BeUngI<}- zG`?O7@(Vc}viYl#ji8~oY=bgoy$L0z3y+8Kpx%8FgT)O7y?_4*9-@0%AofR$KgWSp zhG6u$^LLH5_!_~W3LI~?54uqeT`(dp#Y)>*g*shX?hf!6BMCCfEK6E&TDDcF2V!U- zp09X_O6BP1(`ED*(uC)GCMjiWLjz)k!H2xAu~r4$2>0Vb8C^wXUqLX{*NeQUIiu`M z;IRR+m5=O8O&c4M1tiMO!@nLlC|(4eJDOYao20Tj2CD=u)&R@@Vf`RW@gm&IS%$Wz zZLLY%go`916%I}|Jk=o_>%O<*1B$Kv8 zU01t`#LBZPJUW-Tp&vn!JPyJNVf0LgrK7P)MZy$9`e|K(s6EWBIATCy$h6ah2CTNb z7uG%u{Q5wU{fJ(7J&OJ1y4!ce!?NMBrIk7mV(|nWIKkwdh#`+F%Z)?sX|Ut~Q^2CQ z;T+$nK&=p5prGh)=x6-$m{D94^_WqT8mU?~#0T>Dl83|yoMAmwvk}HhYpEM;Q_bLT zA{>l%qqRI6A%iV=ScxYk`e8hSqVT#%h|(T;Y#@96pf1QsIQIdQ9FX!TcO_24 z>`_j&_FX1D??D;+QJU1$vJEi=ajmPd(6S(;Ck;*Nm`akZ#uE`fVP`;*O*~7W{if|r zosB%Q#HWMY9-QgRVgCwGA(=kkgRC%idjYmEZtMwVMKc1{Iq?0Zb;G>}7{wVY+g88B z{o+~nqn9<&1Z9_Dbtia)qMi%lVFg)`r*WQ)J-y)$lS`v=S7e-({?PJi-A1dxP`0&W z(>lTPA2(m@xEhj;SikTXr2!`z@%Ucitp*}{hj98(#o&ijgi2XwgltrXWCVoIE-w{JG{3@qAXI*(=vxp=fI0?4{zbk&y(f(mc;L0n^<1Ly&5W z)rL}pv*q%7Fe&E3&Mi9q_=1|GA}K8aNh3QP^JoHv$@nD!F+CAyTX3|#7^Ld0tb8#9SAlRAh&9Vu7VOpQj;Jnib znRS`=+476s%J}3DNTB{v`#sjxk?YLX)F&VN`lFdf4ZiU?2`_&zqB=8n6m<;#j(~gF z_+IOp%<`kL_oQ4MeXn!OexG#>>O@*nGvh=Oq=CN(A+*&e(-zF%;3CE+f0Uy(v-s$w z_r$JFd2jTX^FI3;>;1r9lew}jHM6+p$!~w_o8Nd`6CAmaSz)?^xEBX--;Qr|u9*mT zb>=IP$UTB8NIQQBq(<{!9>BvN2C2zhcr^MR=W6@C)-h0bUTWs_nkPNFhBDbUC^P_EEDj6*cP8YVenO z;$HlLk|2z)`A&juz(Icb!yna|)2}nzGVP$;UX}5la7-G9^#BCx^9N7rCX#ba=9jHV zyR_JVzTAsHjB=K7c_?z3RF8a=A4y|>CNDvG^T$JqWluGySOb z9?`RSe`b2klbjK_IF9bsh=jAHi`s7OJ-^H8Z_Bt<9?)9G5n!D|~JD`-Me9ekE@Ax(bQv%(!dMU=y-xT$8pr z2*3~p@$X7*x65mW{I^>#C_iuhY)u~LV196%ZS)h=uNtApv&%*`f0ac}*cvA7kF#P) zHGa!3r8;I#ilpMpq;l*$bBa05nr_Z8^UYaifn8)4n3;l0*Q{4V3c-Xo8oeehA9Tvhd3V^F4?O7=XZK8IwZz zCK>0T-0u&+UJ$q}gEQK{EKrw>KPYwnYD;Daf2L87=ETpr77?z3__(6@mxb@^PsY#h z@Aogu$PMAoHTXkk#7~`$pgee4#*`ok`lg2PyFWFhs#!@|Lw;t2`kP@4p(^|1S{*?- z>3vl-$KM&ol{!tz`DUe8goI_x41$1Xh3E-dC)O_r^#q z2!COyd~OK;T;sE-L83V_kx;2+%nP-jAHttJdKOmdWc^)e{8;0sKN3k=$;od?2>+rG z{zakkB_aGvWGsC8@l!&9%QDIW5c?|+;ion5FUzP1;jb{Vft>j1^F&Y{ysRYaN&L$~ z_?HE%qkKgO{|c$^+rAZ{`l~|l>JWY!Hvh5=T1fx0jJ2Wu)=K-^y((*sA~J_72RD3T z4M`U0U9S@QuVriq^}iuhUK8q%me{{6qs|AAvS2NeHHg;3zbs>;4%C?NI5I*&5j&38%*dD^Ce#Fu*r$_8x7OZKq{MFA$x-~50yb!+g+#>n3jPpbA z1tEMFgvt{kcvlGjE@|)kIlGM2dcE)Lb-AA*NM__;dymt~BE@Q)Y? zjh}mi2+BF$`0YM@sroMjV3zlJZp4UNQ9dnWGz5=@=ot%@9|+NNAXI)R1RoCJI~*#% zBm`d?!hfl>|EpK)Qe%k1#YG!y8viY6_m5>H|2U~-ToLO33b(3!TE zacfe4|K*i1VHqC^!58dsQ-Tnm47nS-zTO12Cvp9 zjjw9?O-G(-{K+d}!ZQ9f1fLG|cREylXQ;nBrGBGV>rUgzB>niKSHgs4+!ccF4)u3; zsQgo*{yru3{rUDOZQ2$>Il|LHl?@_5=<<)xBi0ZXa_4k@r!h~f!7J?rS_4jzF z{F|ZvzA5#6ui=|Uw(d{a&)(&}5$f-WQ2CRg{+^Wj{&+rV%u3?#*P-^`3&H;$ z>hIq}<=+qW_x(_R-!~Q{_4lh#`yYhhXF~lw6Dof;)ZepGf1y|FS))Str`Eq$y%HuY z;Qv36%F6jM~y2?O2FVsFK1Wz&fQ{L{Cg~Wv+_&^ALR|vj7 z1m7HjKN*7W4Z&Xt!QT$S&xGLr6M}yef@7A;jf%0&3BgN4aAOGG8G`qQ;3FaU!y)+J zLhvIY_(vi5Hz9bEolO6<5IjEwFAKpnA-EMV2c7;z4&q^nQ2C({`~eLYqkcB@{RCjP ze@NP|HSW>yL4j+G$2Gh|;6~#)4HpZ%#rVC3siQfFzf5)%K0edSLHwjp!>9)MJY%(n z=_BMAyNoUk^I2YwvBww%>|WH@BO&-$2>wtAzC8p#5Q3iy!7qm3KZf9xs7sB~xBL)% z4q(bp@pr&jtzkar%P}rBT0-?N2*G=G{XyW!G2Ufdp<(*qImXq-hc#R$@cWIsHQXui z^~U2#P^xqcO?nX`!c`Cfuh;<_0xDv|j)Gm3i|EB( zuwc8QqJW~JqM{e|_xYUp%x1C)c)$Puys~-EbIx;~a?Y8uyR$Q8PL92fsbVFsn8NiL zyoVMVx)x#bPF2cJm*rJxRq2wo@(|nMDi-&al6m+!K>2!p`FcTT_nJ5NdRBXllG`)x?+PMq z3JQH~uov^}7IgHjckr#Z_pSTlz|T|4+xlWE@Ws@*T*c?r=hWxZ=hElV=g{x3+-_Av z!kZ#QuKKY*Dmi=NT;7tyD&ulD_m_+q6s&V7?Ny-=y}JRSSU06|b?k+E5sSQu53eIa zoqi)tEnUiuRqq$T6&m=bxOZ)wJIT=^GQHj3s(ZK9VR89X@+_2>xIZ-Ywb!pGJjeEK zL#VEN;i%`(i$quH`AqqK7ll$gH6uTu@?Xcu^@`Pu)9P1w-DA1FS51A51MaBdle~-m zRf+2x7gVqv5f~T+U80BncYm|WEGymK0D9%+HX4Y&*4_nvt}*_G&)!QbVxA@LwPlg} z2bQb4zrU-X>%SnoLPgXiu8}%U$cipmQl(2)RJ`1`f))LC!~b(TUTz5;bZO)VPY`vN z6s)mp-0QdPW&0>`C3>>Akf>Nv@pg%*i~hlnD@PKbZ@TdP;HiQ^_cwqj(wKWUB6NG$ zyCWFt-2&f@8QeCJpJ+iW|9Oko+JE!Phz>6}BY~ibjYQn3UeLv-QqoplYc=y+gM8z~JX|u3O%?g)7mj^`slis_5Q?t?!hgs;} zbHzRPOdQU$Hpj{J&R<6udrlfDPqNjHgYp_!O&n?LwM2=djMI_wXyfo4iR8DqiDQht zCWP`?l%ZFu@^eU(hrtH0!zDM(!rJG#eTtmq6Jjd-9^t2YwlKrb6$9Q{R`KjzgW%7|+&iFs(p4fE>;l`~(?pUvX^BsL0; zC(E~yecbsQ8JB)2&^gZ;Z(z8t$%4P3lzVG? z^X37Q;evJ???@b_EX0EHR3K75*_PUJuH`ZqF3{tWJIBJxSy*Kpm^w}XlcN=hIPxX8 zmt074u(9NxXJOmtV3qBQ#8INnAMX;W@dB`5y~{u>0BNZa;E+wBw8IX&|b(J=y&#wx_~UkB^TzgpkgdFwgnS)|!u!dK@efPx3JV)oB32VG(f;|L#$L0V zc&V|URVS`AcDxfWGY-1ijzdop<90fU@tH)ncdtn#7gE05IP1s>#(tK>^4BR}VVr#= z^5_1U;~c}dV8`z7;3SU)W_Tc~sXKHorMK5QZ}9}bde|0juL3uC}5jWdSC zcCnPiB)@~ixIaN6PJTv5`=67D_iGaI{zxL;-$}$9k8=h3&m!SJn`FO}==b&{;wd5# z&*>!Q=QtAmwSmO^MeF67jajXFZ&!V@SpiQw{!!NrEN! za+luzDY75)E;;bFuWPU$fGYPlNYP2eB~pD-uVU2bDofF&mXY8 zJBWkZeGFOV?r$h_z6N??ze=uk=Pi#5Tyk%6$#}z9Wjr=6_~D_8{`!*eHv**HF(mAk zk{jLait<#-ry9H8Z-91Oa&NP++ixAL(mpmZYp0MzyRPI$$0?FrOcq5QZ#JWl3*z+b zRJmW@D0{G51oc17oBJ;9-(T@2tp8h0c?)L)Sl@CuMxcJ&v83*jy zyu3KNsr`1hIoo48I}NaX#FN-Qxa97#u=ef#Zmssi>bJz3G!C#^VH{qH8i%g3_j0*C zdwhqTA{1517ws$Ldy0GB80k0fD__JNMtg4@xqaLILcSH+!`@K(L7aBpba9U(5qo=4 z$p!Z60iHd^RbgJhP7&&9$Bs{D<>h^)iuT@ouzF};VH~65D#ZQ>_9Ah71%Zn%FFXI+ zJMMOg{ejI3cI-Sr97CbbIBj0uICOIRp#j=)$^F))-)<3#n5R9jg59~0X$OBczlD-7 zl)RMeXq*+~QTMnNvG0Aw>C4~FHyA6TzSm!n?f5{pd312MzlfdVQ04+V-Z)H!$hc;b zXjf&N?TusOL|i?g*8q8ylI`&iOK#8|Cx8C7U$I~KpZc?%aY|q(GERyAKkc=RvX@qF z&znEZ;g5N@B9S-arOcEl+j&`_`Iq(ov3urC4oup^y8)P0zSbwHCTAU`%7VUh2-o=uy5w8Jud{_Kj{9ZgRCg8l1?P`gQ#eA`cc!oGu zoGD%?UM1cn-X(4ocZjcvABl&=U&Yvv8&A3z7CVb2;wi@&l4{YFBUHquM)2nZxU}6?-cJ79~K`Mw~Nn&5lrZQ|YH1L9WkN%1-H1@RT}E%9sdi1>?mTnwbT{T45#i0NV-F)TI}TZwJO zLb1D8ES@e76weaJh!e!A;%u=@{D-(y{HJ)OxJFzn-Xh*1-Yaeq9}}MucZ$2k*Tr|l z55;}rSK?vuNAZ~Wrx=6p7I_>=6jQ}oVm&ciY%b=B?Zqx)kys-37YB z#X!0nS9P(z*ijrUP8H7+mx&w1`^2Zjm&6Z5gA29o_=u@uZ82MHDYh58i6!D#aiTa) zoFkqmULam9UMgNCUMH>>H;MO%Tg1o3XT=x9SH*Y5|A+^~BjRsj03UQP|0FS8tS>ed z+lYnYsbW8IxVT)rOuRT-!1%|J_^@K4`v7H5eo#2ds1#OK6M#RPoTM0+j79^xqR0&%r?x42vUQ2a$q z#s^Te*IMi$4i(G9E5uFWHt`+tkocFFQP;KGLF^|^5$B7SiMNVRi91Mqi2fltz&QUA zzY~8H1Nb17^&v4`%o6L9$gjENR$_t5yGkw+&kzTT!%4IsPnO_14icZ&%~AP3NcdkO zE+-N9jp73&KF{1vqW!-mza@Soenz6**WyoN4BE0hOUxzl>O#U^vE(zv5#kaOao;9B zA-*KOD}E+^EB+?N!YA9;6dQ^y#ZF=`agca{xJJBHypvqvIM0#jujj?xs^25|eeq+J zACUZwctqt+LpQ!uu`UU_4aFRlw-<}Wq2eTQ4vBX2#f2(gF8NaNN)qFKtK{3oN5sd( zr%CkNE8_bk^8QIo3cGS^@l0{Lc%^u^_@elc_+K%#k!z=|*hicut`Kh(w~23&i0_d2 zix|ju%TvTAVu9FAJX>5St`Jv=8^q1xHgSjes<>DDQv6Z;Q>@n5ji-s&R_rdGE{+#x ziHpSb;@#p7@l|oJxL^E1{6kF0asAg3n~R;qZe(}I8BSvUj225(KSS~yu}tMF#A{T3 zt+-a@w@bcTd{lf=e3r!cy(IZH@oklVBKb4%E0zBs`DZcM#Em;n%n)mf4M_NDA-T2K zR^{C!pDGR#hl!&|w4W}Xr}9PO5|v*q-Xh+k`Uk{ERK8vEzr+_+{+8r-#Sckrr(dZ4 zJC*+^{;KjoQ#b#Rm_#DpT9WIC4ON~iIZte-^6rv*ihWc*Sn^roXcF^fs_N&f{Cx33 z)n6yxMk1bvCBG_uBOX(Id^6W>GcjN6EcO%!if57NpL0me+v(zb@qF<@5_*@Dh@+G)oU%DDh?B;iIH8pxLCYQyk5Lbd_vqM zzA1hz9uyOEUAwi!Y%x#lB9@55#mVA)afx`l_>B0P_@n5wbp3@$yqC+6940X?IbwUU zQ0zt`|Gtv@i(|x6ajsY`gclx zh(umbiqDbIe^>QilFw)yH&n^=gsGuPF(;`I5Vk$gfx|B@x#Q z@>5(NEcp@=`CKMmt@4{B-z;uY`TZoW?|Ybpo##o;7nOe^`2hJ6<_n29j*;;HC%G5% zrjsjYk?>znY^3s5lJmtPu~p*^w2MLNyO1aavKu;(wRiR6p_fIgnY|!hDk0Z5$7av zn##*0FBDgbSBk4i*jrEH`p`Q_*u9rT+)t6P`>go9>OT^{B@y=@B-+PycI7k@an~gg zcQy$>t;v^h&wmnj`-uZpKV9-{alXozNM0shs`53GZxGk3{7w?r%ic@E-@nCANW}ZC z>VK7Nx}Y5KCXuL5BhjuGiMZ#87mJsY+a2dN5_#MyJ}N#b?iODa-y&h}BNEpS@00wE z>c1C{lCU2-1w=fxNa%+p=aT5x_ToSic1M$s;rBg~&m$4vB5{ezFOz(gxJKn0NL&|v z8wopGN%((W<*!M8pWNs;pOJ{;APN89kq==$NRICc8UB;SG!lCCB!|T&DsL}#CwmyD z4+(n%NX*BvB<3CE4c}Y zc-oMNrvnN7?qVNtyts%&yer6?9Oo7i@op0DR{dk*zf}H$__E61mHdHtNc>j(k%XV) zBrXa~?BV)J5pzh?w~^dV>`Ef8p5j?5A0eFWyI@zn&)H{{_i!km#om zB!5bx{Xy|hm8TTB?XpPN$tKt0`en&&Nwhmf9IWyQB>c^kynsC2ah6K{Cy92~i1&zF zN%Y4X;ydJG$N7%L`1~jaPIcvwm?72{8<4QmLUL=dt;)NSy^M3J#m`j!jpXmeqbmPX za-b*dqu=64#G58LL#(6n9Ldea)++BL`4q8;#CQx7=Zcq!YsB^97V$}Or}&EaiTD$V z`4#BJ7xvF2bHrz z#ka)6VqCFnr>>YIwif$}W5kst`g;v|p5xq4VjQ-JJH%b$OCU(3J zlki)E#C{-5BCi~=h3Zcghme>L6G*h5Ne*|Ml_dOKMGkhHyGhu&PkdT@PTWO8|8>c4 zi=T;Kir3 zB<~jwsr)Chk8zHXuv`5!*KSQQi$r-Vv4hy3L_TMeh-0ESRrME&mx$|0^!vRe{B4u` zEQ#aVZpp8c@OMc3o`j$OlJN7F7=t#{YfGYEx{}z&`$;~Fg#IXTnm9|GM?!x&xe%W- zNWPndy%)t##XrSN_+))Y@l0{Hc&WIGOhUdS;&@QpN}~O|Mz(UCq%++5>S7}j<$Xwe7B))dL{9XK0j5`y0$Tvw$7qi4hViU0=3Atr6F%d@~9E_lu8;Pm0fxX!oJ`vzR*2Ew3$Ri(SRu;t&%4r;_k9Q#?;xBrX&G zDPAL9E3PFG$0On^;ydE^V&WiIuaVe6JWZTJ;|hZ2W{|L7Tg(=liY-a#b(Y*sED=u^hls<)QWEWENj_IxE?z3GA`#CG zB=ql6`Mu&+@p17P5_&I4eo1^=d{6vT{6aiP!q0IrbBHTvi!H?>ai}<3TqbTJ;r}5L z{kBznM)f;Y|F+8C6F(Kd5D${D^MmA{#kira-6XNT*htJ3^TbZ#DPpnMR~#e`6UT`Y z#2MloaiMsjc(u4jTrb`#ZWiws9~GYzcZx5HZ;%*=cS+>`rOFS9KZ?JI|0SW9FwAY2 zE9R3ZFCsAx#o_>Qka!jey-6heULtvo>TeKlRsEgflPcdXz9_yd?j>RGCo$zLSI!hW zknr1+M0_RUnW`TqPE+|Tae?>`aU}^qw~Nn;{}w+J4bJ7LS5NFD4i?W5{~=x@J|w;@ z{zp72{w}8AT$6d!5bKH!#V%rZv5(kK94n3&r;D@2^Ti9q72-;9wRpXFi?~U=Pkcyx zLVQMiL3~MkTYOLaRQy6bEFKYm6aNrHBi;T;6zh=~?-r6;?3e+;=STl@o{m7xJ!IZd`mnm9ua>N{}4lCkRQge zCW$;V#juzowiXM-E+pFZCo!(m#H+S07&~*>+RN6^?VExLSNr{75_^#s*ydIwJ4) z#_P-M@9x2CCD#wS678i*(khsohtN0Fy>wrS>E?bcpym8`6G7azd#Gl0W2`I<)Co@F*duGV{ zDF<;sibR)}i=T>}@t&9UQ^niKSP;vZrf z#*q3=#M8;Q@O^{$l=!unPy_WZjL&z{U6zWg#I59Qj&ne)li|u;$(zux;zIFyai{o!Xn)TG{nT1+yL@u7 zP zhvemsQ!U$NZ*j1Ak+@6zRxD}k>R%(S6CV)Y6%UEQ99KVA>@S`#-Y9Mn_lO6@>?Use zq2f&OGVw|AOVM6;j=Y*+OqgGhSSl_NZxNpmcZqL^ABhLWu7*y&fEX zVp_O%Yl!x`aFlnKJXo9}E)nhZ;Ly8Y@+;!+Vkp9p?jb z7ruvY>9U;|av=9}@2kq~54$D1J!12*$A6?{kN5c`woOcNyImHM*e?5$*e(Z>s2o9d z*Zu#Bb>F{!x=$GPD+^fL$?68&^o{7sBy94Jp0?R~HyM$9G0*IMu`th?P%d?acQ>^Bng>@O1YEH(&Yo(&Iy=x2N1CiL@0%IN3LaUlBnS`z(i??Z%su9pBA{ai$% zpC_OV`}v5JieiyXXk+E=U@{M{cL}ag?|2=GWxj(VrDZ+^?gb_mb#m`@0?V^M9K|{tDyC{V4kRR}%faHWx%cC$t37&v%jN=K}Nv`}r9X z{amdzh<+YNqMsL$=x3zk1ctizQ)hoe-OBkS`VL)Y<-R2PY^LP7B*p<_NI zw~@$cx8zqz7~dy(KZ$Y5F(CZg{S?Nlt7N->!nnO{s`^{Me%=4Yd9=P4f%_~C-xIN_@LXA^YL8XxRrKV4 z&ejQCRZu#auZoIuIIwxMC!g;=zGVK{cx1_(iJS%nc?G_)j@EFZ1F5V~MG#dhdD&K+ zOcUnJn>2ae+4dn$6`tc2?YYu4JaNk^Li#_pt~yrE6h2kz{}yM}t^Su7Pu$YR=X->e zeaKCv!K$oKh1aT;PTT=yc!HaqTzZz<-;NWrsMM&6Kq?K<2^-qrDm~{dI*`f=RXD9$ z$;;l|Y$v*p!iu(!cq`UdVZO4CyCp`-`KTT~rmFI$SV^VQ@K&L5vJgC1zRkUY1^=_L zPM9l=R8agoj}?`x$lgBe>u=I`9|(5RprrD5;rP@l4l)z-KVN2Vs@eTv zq_PSpl@%&ZXZJao(Pkq%8dX6pk#~}KD(Ia!q$stMMOB4r#bNM2>hFX@Q9J{DlLbQ)sJfZVS ziYIejSvhLfbBl0yJ|~&-?|z+=MHH=9u@~4?k>^3;E%AvCdC__&^H`PcNxbqY zl>eJwtNA~Bj%Zi(%@K-Zd{W<)HBaWdYVC@?*)!!&(mZL>KDCp1jj~A9$}Y>F#(DCN z_Urwf(+av#bDTky*S9^%M32(^U&Cwbp5UM846c&Zs=LMa$kCHKuAumL9aBlU@_6`E zkjcq5xr&<=eQrN46)Q9PNoiqEk9+qX7Vs8>$o#1Fqc;m|R$lQjFgR8Q8_ z-MvH}BA<_~KdOiy@I@7I3y3OeSGlNt<)RLii#k>=>QuR?uyRr7%0+nWeWkz(s))a! ziUbO($e^H#6bh=yp`eN+3aZGWpo%mKs>q{l6?wF+B9FFJ1(s z>vl#@nmpmWDR^l3Idkv{zFi+bVFI7??yJSey)&oHFT+_3C!4hFry&)J=FOf`NzFbO zUQG~@gOC4a&6>;;lX6q%%o{&zvb(z;Usg76+Jy7UCeO#$SpV~aOO_mbL*azfqJ30L z)^TZs7uWHXja^Qphpz~oc)b2jZ#ZlKWjE+tU^ok7Zc*`yBzl_?p(C-#F>9-5Yq( zw%33Cv0hakx1!u{Z>ld3meVioy?__(d3lV&x_@CE7ksT%A&)VT*`BtzczOJQb-&-a zzC4np$9AW|us@GUD4U6ww|Mb1f|B3fQrH^^CH4#R_VPe+g*@K$42kr`Ws0j884v0) z9P7OU9`mIwE}q|^DEIrF3cucV zR8M+r_qb~>lE)Uv)bkdIc3Bi_)q)@@N7*zr9tyJR1A#4U;{Xu?xS$_b=Xf zT;u9R@}M5$p)D?69#=rm?{}>)kEYUNJ3brEpT|DfEA*V9-V5V}D0`b>Zx!k}9?gCB z_Q{^tj^FkB7teGo%CR2FgL;gIwzzoB3|9Pk6yhQ)Z(iYYlgKV;M^%gIl=cDYE!rq%uVjkR=pxVaqAKCNTeawTJZ}IX7;u;35NAjQ^K2?d#f$M;-6;^O(`Gpqf6NBHvSB0aWSCclw>Kq2?v-opOl>m})V`-6JWd%{x!J-@d{`JD>C zQ&G=+yGf6JpOZZ=-*;H(Tj-O^m#$u9+^9!Y+T!B*{VdAwo4$ODq{nvckpOLbd3=n* z1(3bPizf~W{{Gtsd(EN5JbHrkOMAJp=d~NmM!v<%gV)?)J(9;z=&?O*aq;pP66H6( zSNZ(wEj_kdD!<;ije$L$KX?oM^7WGR0K3eE-UzJ|p5IMTezV}$%eSxe==V9<^YYz& zf_%Sn^&(utRCBS#5`v{P`3-8Ihdn$!iy&XdVYHY zVUO)OZalZ9U&^gy&ue#-jeHAzaT)3AMe?8?+tU^oFOOkSen{NXbzy>m_) zWbAzXS9;#O9|66tRM6u2eKpGOM)>7%m-D_9^!)xHdtUz6ogm*Zl0ehQcu)^btt}wZ zm%KLEpYNN#d?)(+_H*q;^4$P?4QWV=m+xljdHFsAy~C{3;^oU{mHPeegWqG&VZP^p zUcR@;o|o@tzFG7wp6NGSy-2>)W4^S-#q;}0l;6F@<@@Jp(qp^&h?};(Jhs5zW1cgV zd+~7l$DdP#7ng&uw-RI?Ge9qonzHA$JI8xt$wpW_)0~%BkK{2GdW?s*xOjPRd+__6 zi~CM_=Q*>b$982=dCY~qsn|z&i)U|8l)a^}w-LcIkGW9x@|Z4rULJchJWDRUJg#!} zB6(1c@z53*&+lbXe#3ps^WghT&+l9E>y5`g*z;`Ao)^#kQTFm-kA9iQc|LppmOZcC z{uAVJ*wu^VK|R`|EiPUR2c!HJ`tn#PJ+`Zs+&>I^{^JMxkFOEZ^YV>>5-$0T zES}$d==tYCU-(@KE#`Xx==I+jvghSnFEe7wu6U;TOk1o+@}(Z*rY$a>-+57f-}L3X zM0#wuPJX?7b6~GJ4QZiYzP^#3mv4LM`9JsZ{O*YIyAOT`qCNAy81(Y}O!mBdH=ZEh zWNg=H8p)S>jGMN&cz)xd=kMoyd{E_WZ!4t7c4J(7k^RPI*y~F}T0DF0qU;sHULkat z$3Hzq3q?cUG}^@_Mae+!>(Q=59%=<+T!B* zJs9P;$d|`j>9Jigjz9i94#OUXGO~E_WJ1qB9s_;$)i7k&C+ALRr2fY*Ld<*)qai7H1_A43cZHOk@27&#7s-Qq zjEAJ?0NHQo6p|;vghS-@C13h@9IVJ zpdRC)EiPUjd!qcl>C5AB>9JidKD_bgaRl~CQSL3CJw7AaKOXyFuP>B1zE6VQc!Xuo z%VQwFAoVTu#f8s;#(E?V>Me=>gb;R$% zD8DOx`R;_S*Uvp`R2;Wt*kgR&;^mP6J%9hLg*|Wn?SisrkI$}VtX>{tPLRiBS1*zW z^_T~3aq;|)kMjGbFOPpqkL{k3UvE4n!QN7ody8l9>L`2rV6QKfI36#7)T2E-Q#k0qI()h=t z5cZ0o#5`UHy*ygWo;M!->wA`5(ifLeu3jV$>MM&s)G^w@5n{Ce}M81_6HsE+J+-iwN_?+N0I#pe%*H4-27=;w19!{XUC z(DV262w!~rrN?$NTzir2cOdNbq#-R{f8|Hnn+ki)p~Ly|6-d9dH(vIh`TZ(N@8J{Z@fq}N0NaKy*s1y?mj_$Pe$oI2R&>uk;RMewJ5zk(8H-t zWbyPqi_-h<1o8bGr57KrI^P6z7Hxa;B^!EG&A<9ldYzzGRX-O*>74<+s`Bj}r8fb3 z{#~?}@5m^J?Q%Sf`&N{?>-_J< zw0Nv&z8h>wkM836{UOTl)N61)j>Nd% zP4M|mz((!0p@ltua|#C-^P;Mc-B zzWPMzEziLHr#&UG%f8(Kt?wada*ijeH z*YyODKDm(IK7;ac=xxLfH4_!XWsm1a95Y|{I~zLU`M^BzY4PlF8}#e#-e{b25sSBY zdiJ{H$rEQxn6of%V&0rK1)bWrZ``}W~*`_B1=0G86ki+cAj zF~+mR9GXY+p`Ut>T5qxKEt=zV&t6Wisc;sCHgnoZxt2R40^h*v_uw5_)0 zwrNh2(Ats32IVQM1I5+W)+sh!UOSX#(l%GWDRs?jhicaNT9w8_kfN6JxSNk+RX*OR*k` z?tvD$CCGkhXjN#l+XJVSWMsQmYM{?JIjxBfE4`)X{m(5ay`VIn{c>sDycFeRt*XacPF)VImZi;0zd2Ap?+`Ss zb|3hAj(x*r%Y$)CO-bsb!M=_ANg=OJJ-NI)K>)+owbv}NNTQ+%8 zczjuS@A4#k}cIr3bw}ESgynNZ1O*ftMQI0*=Og~ zz6lGTOzSryJMFY!IB;!hKZBQp7vul)0RMk`phcu@W9&^}(Tp z7I7o!Ew$p~e!!Vtt(dsYc!Lmn8S61EGK)}M%Y<&mp&_&%7Ghdv4Y5V>I}%XzT^L23 zvd&>qAok+MD0&rN=frfby~q~DUDXUlr!+^=fUGN76cfu!?m{hb9vpLK?OSb8-03(a ztQ8+S7ll1yV)?_GB zC)f#N7GIP~H_a1fA@}%GQ}!~(fhOT%D)w~6K_;OIPATGhx#D1x@HOKocEuqkp)K3? zwqj_gNobG+vBa$%WfH!_aK`s>#nC3=e%AJN#WCoK-5930(KYBel#9gT#?&~%^=r`+ zapTf5p%ap(CvQVtMvzk>X@(VQrA?YY(Mg(BgD09< zL4F08G&}Pvc&}%(OPXV|3*!Om*lOa|Hr^6~~&;@D5=UO4K$|Q_oT}xM7V-luQY~_mAL8Q0V zR*bp9B-}`=d2TJ<(S&l)197_=-hz-DyoA&9_Q~1rU_A{tM{|-Jr*LoMq~Xx#BWPE-lpC!w0jpOKzg;t#fT)x zTVqzsslFXQlzp@l6j7q}te=ohZw4 zvf_gcISy$HonYAZyOXxa2{y8;F;3_(`XZPeq_eElU@rHUX$uRSU`tOI>#bbnw1sUk zwe5O*+9Isy+4W>6^alDr*e1xUscX|hs2lc_)mx-;j>fe_K`j&i1Tv|egY~Rn>V#4- z$cr9RCsx}5B`3(cRHsg|f=Qbe3YM0!&&iS{h!v zWlRvm957q(KV)Jtr{hc(_vNM~{wJ8>_@8Jnuuh7>`v<3nxfe}qn%>Y)H)n>iDVYz@ zZPm?Qj9#kg4*fLK2l`276#gfhS@>Vg9@xTW1@yzF8#a_i<{WIc*=99bH8xLR;Bw4X z%=adyS0g;R)l9-Zs+pON1e%$F@SA4-4gFLn)Ez?V&frY;M{?Q-j&Gff=z_G7?p$%2 zPdvv-bH_S9z77vyX`^jbYHIWIowTv;dbs&iCvBX&o?qv6bZFYyu2fWK6J}dlsVfb1 zLSJE?r;QI5!BgDh_;+et3Y^F7KtIIs7M7s{*aT{{&fbH%a4HTcwM?Kr$Bg^OxPRlH z+xbb&Qd+~0;Z$|Z2T(NT2mHqY00v@A3;d5apCi8na|gECL^Bv2m1MTT|6fjMZW9O{ zgNIsWbOqK|bmr>6BQmJHcNu5=mX% zZ9jMcx-+Sp6+*#M3f-*`AABFXt)w2+UPY6{;3pJ{tdJbM8BryjT8~+z)Cph?CG~XY z-NLjf(~>9ioDZqI(nfZZ5|6=Tpc*z?QQ61|eGjBJ4f2}fIPOB-#u;a%G{iJ9{K(xg z)exXDUt;P7%rg9kJKoN7QCFHWzH_Ly=j=*kDUkOLt<* zHPpSuT7L$clQH&2{pK>5jWK`baJKcwz*jd7u>D}u+Jvc>F(Wv<+{WCL*Jz_YbRDyj zt7bp_nRhYqf@Tuph%pD@I@SqYhCawRKe)cU^@S*z8Q0Wd8o?2DuEn&e zN527xF5~{-sVHij@o>URV5`~Z&2lmxvHR;*bMY(ljIH)Gp`8tPn;UNEN1SwLJR019 z2I~E1Lf2#0ZW>_Qb<8r%G-JA<2LdJ&$pp>AD2XxcvG<5Irz4?|`2*!~=2DDPym=iZ z3Fcu0n`knilWbOF1X9gf#GPjN6;%!MHOgz6doexJ&1IN78D=p?v6dN!y-1eHgMMvu z0XDii=27%$U2_X|g!Rl;j9YzE8~Wu z9n1&lj6(ArBJ6Bt!)6!LA{P&WH~rAItN9iB-3)(P*4^BR4X4OFi~pyZu^85#W)s>L zn{>45ZN{Ly#Jqs)`kF^z|1|SHI{0++0lf4x%h4PC&GX1{fZ2tuW}sP!!|5P15c-1+ zK4Eo+n03f~s2PL-8(}`imN3#B3*&2c(;e}QHu>m{F{TAtjWwIm&*MxF*gxBxg4|2Z z+4w)+%tQZ7FpE$-(JV&KOfv04xS-#xLT^toyl{M~S&LkznQ<7e>1ICu&oEaamzm~n z{GVmMLFBUyFR7nn&cy$@=4)6!*TkTI=9!N$3+J1k5L=nK0`V+17s1*R^9M99GD9%d zOU-VK-Nj}C`h1yr1g(~v87V9JXkKbK*H@bKfa6?dZb#&on^)ld z3Ud{5ywbdnUcJf`AgaGi7JBb5CvHDXr^axLsFj^^I{ceI;NCHFF|@{vw+F1+a1%5; zu^wZ}&^XqV!d%E~gSj|!7#8Bqsc@EH&PwGZK7z@VWO#q{WYZEl)l5qaSc=(;T}O5E z5j~poF$`&jzh|vs7Q%i_^8tn}-8AK1(ENl}wajTqCetiNI9VnL{o1Av%IlbyQC`=q zMtMDxiEgTIc)d^qa}9>Mp=pTD4Vw_GH8M*unX*kEWYpMvY&hM67|14u&l+iJE=G>c z%sCjy=H`5~ZDGQQE!Q+hR4vT_XtpwZ%0_FGjokChacop=OgsiG-)x740`oocYHN5$ z_;%)9Ottm~;bQ|hhIl%fSK@FbiFpHqQD`1PtIlR?W4kfH*C}QIe04RAV85Gr5wUeQ zpCghUrapESMW&|RB-SC{o^^jmpF2yFOQDKELC^O4)XbEna%93xKZ#@3_xb{n%u4D1ph$aWVWse0|~2~GmC7Sk-<+e&oWQ7YGZ=+sn*j9rNJH8;4^z!VNx(1ot9Z_g{i^bnERQ% zt+km>Xc=Z+W=Sv$8nxNaSwpkJJdoJ_&hq;EE5x1E*nYB6FZc)o&C0RwiNnDRM3Cja zPs<68Lj+mw`?Tiv7@p;hM5|y&OpvVRHtIIPJs}7!tk5>N3j>ywYhx=6zMBofebdy{ zo_l7w@0yD2xo4L9wyD^j5oEbz)Hlex9Aver$#bvMg8eajv+^@|>UMf?0mCUs=lNg1 zgpV=Zvf5_woGDluNca^4lhrPRCtbmbfrQs6YGBR@B(%dM%j)Wm)09B)J9bRBdhC~h zP8>g+2;IaSx(8RHruIW9cMtWovs3s+-h7F@19p&@7RD4~+60_9e#GSNO6&9qor-!> zfC?wM2WBq>Cppuu1f1lf7!pL~Brk+=je5?{rT$5`dVeB^} zw#TIK^Eq=PqcHZNU#3=L?wY%xB;M@74j|S17rT$J*#YxK<~oeb(z;n;STS|ya_b7z z<(I8auB0XqJQk~>0Xu%0P$=_p+qP3G8Lw{(WJk4DRBrkDSVv;%&&8zZbOU;#Zf&l{@l($@yS4|T7q=7tTHDX| z_}OR-Yn`}xSZ&RZ^ysA04WTPK>FE5?dVe0IJ+I zYV~$%RL2ppLGSqEDCZ>-G2CT3HF_Y22Geb6f0nXZRf$Ns{*ZX;O<PAey4H~!Z-651YBd_4kfFh2AKiy4QL zk&Us)nw9+xOZcf_j9q(zBOdoOreclN*f@e0CG1B*2va1+R%H~Tv|+apKdZJe#@Is& zMJJA%S;igMyJii~?o0(+oUs_bGw%ouV~O=-*IZA$axvop3{LQd&;lyl#8Bwd{&O;T zseZ$Dp*5^y;;ui6P8@fK8E>LNW?43miZQmh#ydEd3C~ZVtLIp1=Shw4(4x_@8ho4Z zDNF6-u)&YSU^q2;V+LW!~eI9%?#*+`^r%-oYXar_{v z2CwHx+Gy?dW<&d~zQ)_=^;!?xIWd~0ZfuWYwbt#n^xX2&$t=A$jc0ZIoz?3aI1FAw&)#*ui}-*#|C|uWlwNcA6%061-keL`}uot_5Q_qn-TRN5|1u!!$W1za84XY z+h6c%!vkiFEy_e?O}z3K!DPtTkBx(?KVF>Q7)BC|JxB#tU$>+UZ)uQXoA4P{&Di9P zX3SQORxC*=f{Y=;4jKPGYVak-CUy+Ucmt(V@QUTr?@q%?AH1qjDRC-Ff=D4g42j!C zzzhtO;r}3$A25Rh@uN_laxY@b!-|1|^Pg7TF$A$MqHHMa45s0yAe3Td91T+`@okh? z!|fqeWf+c~lzI5y6)QnZ5NBU)et{NyHOgkd4j-)*y9~nlSUHb|sg$@5CDw3HNL3lm zM|sLrY`1-}5~TIdGQX$cWhmpvGE4D_T>#-~tXzp#H7X@ujS_2kAf(EMO%aMq-i7xu zSh4@GV|L8v^-FM=kL7~_Z-T8GY5WTacVdN4^-BD&7w|byuflFGgnI{crlUI85C8UO z-a?DdqKvnQdXN_R2JsoJJcU;^Dkbv7+J;+Jwb|Y%P6;8WC0Gdz$G@-Y@k-~|Fv|W7 zGcV9?I)rzzvWIr5l-SDah82)1gc~gCmV-HAdZHqQ9dR{Q0?g__{lN`jjD4^VhW>+> z?St>Iau}~_R4VU?>mXHW8C~HH9d{9d^YHIr-TP^oL-!jD{YuLmy0{=#@Tx|o@}au} zQk9mAP?6FJ4Ijixkf|MN5W+z#b`Z*Hz)&g;a&OOfiw$U*N{M4pVtaWTq$(|+ii(t% zq4q3Rg4g2TH(BFpc|Xcp!cYrZ-V32KR`~sEH7X?@@htCxRF&mG{8ZGW+yuSXu@c;b ze}}W4q3NwC<2Q$VYIN+~5C&sqAWc&#@i~;(px=R1wdrZ7N#VoI@GK`Mz)txy_8Xc` z$BuI>ERCk=cnCAFG7T@M^T*hvyF%UUfD|-!O2SY%hQbA?E~EZo2+Odt6fb)gp2&|w zxciDPLBk56V0i5ghFeqT6sX}UMJMuQbAf!JwcA||DyjHeupd}Xliw1HkHw=8D$uEilI=|3pF5t{woQjV6B^fd~3 zx-(nN?S5EWovYE-;Bzi$TIp6!^sJMzq?{$#B6=Lt;uyvg$&b6*-yd@>hd1h-`H%qX4bGv;A?Ler-cTBpx- z%(hxQO-r9R!7-24=7~)v&t4v{%X6^IzG2+7DviUR$>a5t?kbPdPr0i+K0lMrlekQt zf;{Jz^3-F8yUJ6Jf4Qrl!`M!Dm8TfbyQ@9mXP33$^i4<9uhwKvxzog^5w6#=Z2R}?x)d8*(y z43P?aIu+xz=z=P~LqT!E?ZG=u)6K0nLl|U=a6&R0Tg##p`yK~s@Qu(H!G?`bMrqn1-!Gs6p^!)NF<;uqahd(g|B5O2kc z#->|iuRwYpuUu}od~cM*jddp+f1cyz;T1>G)By(9Xi~#YxlP!0%nLr zZ0NDU)1Yp*^+z>~}_d~et_mmPQo61@a3`_`m~-I5=I zcn@Al>>s`#zRC6PWjBbEOyd*JKH|G*#pg8chdy2!sLv0acqGf==CCx-m-DO%KL}kK z7|u6-O&8!Kk?#kc#(fcbt3c*{tn&b6TeJ$C7HQEcFhVWz)M5)h8EERZ;K{gc(KOI6 z(xPc#lv*@biw8oO7=cFI2k~Uswg?9XL|TLcW7HyBE%-LPpRrN#w9&TcXG$V1`k7&B zF~Hb7vI`pEN0-ckCvEkaci@p?>epl5fk%c=KYf7{*jCGJ@CHWVE;iu#qub!FUgZt$ z8tgULtOk!_JU6ldPqEwv8+(>F*f_{*ut^PyFf!}dfG6s1gLS@;)(dLBaMUoPf+o5AxIgdLtT9Xw45Q>ho*-;Edk(vy6U2up{MyF2!DA9du*) zRsC*w+l5!`ObEQv<}B+nc~wRh<3fXYM(7$$rT~LK5I+0m70MWCwFYa+63%Vip!fFWDd= zA&E)YtV>*QucBy6tyWyxg8Eu;N2}mktky!SzSgButy0A*sBcBB<@bGNo^$TG7qtDo zzt8`F;O2W~=9y=ndFGj!XXb45Y9Dcnb2WnVK{uN+u0x;`Crj~57)IbpoctQU3D+Pn z;m7zBPx)zoKs$opFXOJmI4_yJ2(sVcCz<>UC$!NRM?@2dQvz{lbVC6A5{T0}oUF!g z-kk`H2i?Q?eVLEc?TGj#Qtl+u`w@5yCy!F#2?X}x3PeLiRX8c9KneoOak7*GJ_LGk(u3cG z$q2~B^fYjG(3Z_3*(Deg2BxtQLBlS}Z6BO?6iRBv+@7>zh0mpPaF%K)iI#ufd5Fwo+SHBV+etrKo2K9-3BNcZl5109OhzB3VpHN$Voc-auZb~v%g{8VD}fD>D}jxmoJT(O2RO;ZuNEUi!c0WWfowDIODIEN5l-kPx0sJX zLJ~{|8B5?fhPZdQG;5UuT108I*V!7PjqxFl7Fz2|hB?YL z(nbRZJwc1fGKk1iC2&z6CsB4TaWUN(xud5M1C$V>i0JxptSsJz#)}cnU>rYM6el%^ zN6TWGQBK6>jCan8u|?yh%MbzNh^BTNCnXGp$14daJ!>QpOrRFQ{9#u-ni;j6NUeLZ7)4ev zsfzCLzzH5cAaUF#|0(u-*ojUN6J!GwgejMdrO=E)$#K=D0TzW~AurJt%Zf>}oiNHL zt)?VZz$`;nGS%KBxPgHRtxh7XoFarenVyBlD?}}3$O4F6*7WM6Q%8}aXDZ#1^<>3O z7&Ss9x=Pc|m2%IDuv@3H+u2Hu;r2F%4NSEdiD2h6*Pfc?3NL0}47vwVlhE@=h;i{r zu*r=0=F}0wi|%tOo2f_BO3^1#4?m_*t!$cB$-RYCwZO7)X#~o`%flnh9#a8&EnwA- z%3c~{cFW2bL4s7pVBD!Dg;gg_8$~6Y79&h47Z$L{rmAXA!VKf0oeV|NTcMqrfiv^K zAVKTl7;KHi1VpnDIHE^e3!B>{m5atXgGM>S@vbhKG{}XAN+KeO)I}ErnDRAU$6k=4 z&6UwQ80aq{`q}e|SaTJ~Xvz0!T`UEy^kyE^J?k~k@$}+}x5@0Ftdf)l7#KbX`L*LR zT{IK@QY38E#hI#{)spNM0g}HtK6Zda9j*&xf-LD54zbvH#qklqOuaUg`k+IcVLa=2 z7htCTER=dL?(Z}nbUg16%UCkVc3&vnN!wnA^G1h${l4>!yBtr;lMv~XCy-tWidW7z zZgku)PeP5&&z7|_Sx!6pe$sss}CNDUIx;lENfO!!~VN2Iw-TizZ|GES$}f zIfUF#x=qp9nf}`xHUVTeGVB64Leia>s3fz*_d*zN0mLdO##wQRosS~rdM2R~Nd@T2 z1(L=Toywwvss24Xi!>JH#jZrjE4y&kH7vff=mZpS;u)N;fH+>lQ0HMC*{K+)WPz*kkb`~q^Pu$WRI2E<-qAdIUZC&=C)V=rschDx@viuc z#^}$)rIL#oeW_zJ#%yD=V+&c)7KbV$qnkdjs4=X?~%);vP?l4 zQ&c{) zIek4U(2h@vX9XBOOQklU)DI~1f%q69nZq?LlwrFNOHg4CMd6%h-%?2+4P!A+bM{H{ zJV<~h)?73{@|fQ$XIRAbhvM9L&PLK*6N;<1CN~!?YdN<8Js55*0Tn%slblk3sZ#Qw zB_-~+M^#)tHJk54OfuRF!z76>X9JAh@*Fk6sWls5WHe_3%pD|l8V~#OTv2ZzeiRLA zd5&oCCgDRPwG62Ql0VTJsbxqdkoY`*AioSD0R>YXVyzr9gakTVpWzQzIZ>)yE-a}> z5`h|)LY`GA;^;_IAn%8fVNw+iGk#cx)P)5)4ROH67idjy&6z9{4a4QtoO$MXtP$@u z5|cIgN(l&uWWy70co9=3X&iAC~+jjB^g}NMy!&7<~jp&B?S{TCvB>PgiK5}(oj0hc9I75GP^YT@iBpJcbNl^ zKg$wOGo+WB=T^OGI1FPs#-};SG`LvO&BZ2-hic5l-e8Law?rt(NYB)qs=6o+#40{b zbJBK-tQo~Mp+TtpZv>VOMWk&)W8m?|$(>K|vw@xAhI+yM_NZ)Rb#Y*I*mr%D&zq!uEld^=71%E2X&mYsXj#=!IM}tSwQp#!pnsrm z5F!i?;lsv-6v!Xy>+5OjZ0YLF$JZCvZYXRSSd-t|*V~cb(bC#wNxP<{t+T7Qe^MG=4^gIZZMQXw1ETple;rPzNX!Zz{2kzUCSXrFbMY$qh1W zJ|HWZ4Fb_JV2W+ag6$P4=s?Rxkii2+h!_N0*OD}GGNPw%70yu&B)0YS^bJ^{t~D5u zf_OmRqLoc%D*!_=a>?%@chX>vKxism3}ttBeR$RU+^2qb5+q_%>}-0$9xsybF;-K2^4WYr)QkgT>zH)xpSRSqbRR)gyfSggbV*Dvn$CL#^hDW1o0!B zBNrA>*~!jym+%=5eV?Pi5c;F%%UHwV%+jB8Kq{3E%7rdr2$#P5eBm64Q-?EM|Ame$ z&XM{X=TW9?#EsVP(5+1Ri(nS3KkV><_P6Kz^oMYUA{C>z&m$(O`eDt?pucdzT>TM2 z+A)c?T&Rd1xX>h`5*O+(X{b3}w;L-3dFVnZwPO4t7?QAH?$XPVAgi!4#B`40S!=S? zdzb2ob15CV7~w+!PM2Pyh#s>F_Dv&2hZ8-gDXKjoD!sShL}q)L?%og`b1PIb|A7g1 zg$N4tM=uomK8?y`s+XDS&;_RGzJfF*6;u3JD1kn2wY|4oO89pMz$@(=Qft4g7GFkt-6foHt?@FQ;g~G2BqUH=~5j!lq)6ZQx z-lv}{##5O}Q?H({YIui5BpXbB=llX`3b&IPL*{qRhf%}s5DsO2`+TW@&ZK$EoY;4E zj?8u@jv=AQq@6R!pbDJsB4t{Xu*}p{mUBEPQk150=u{~v8>h}3=h!jM?6J-%h?D0d z#!{JPcSLuar>ybP3(=a=93kUEDo)?4EtPVX54ZQQLrG zbb%Bpr_h-)R<>V?OE?^1z5SQ6wwW*mwsl+BNkVJ< zQiG2aFj8qnSqXIu2&G3+KVAz~N6;)e4{kgR0LpQV3jwMT*MCDd9Z=1mwckR6%+ zAv0a2GLb&?&qI0ia|_1n=lZOMrmRnNk7wXgTE^!)WoM_>UcIg}DI%BCJ(f+B_&MClrNe0s)`a+_2#`-{fhDqx3 zIYqKFYIZ?{ZOw&fnAB)4@;XNr`J|c(5lV`r+(!dE(T#xE#lQroJBLb3btX``vBj#t zO-5XfGX@fjrk>#{a88gYRJRdTtbg4s_;hLR2&<^;Alr zp+99F3eIvm=M*?%!urVHq;%9p5-_FaIK^a=ZWK5`0{NG;U4$t*$?3$%Fd89q!mgqE zf@yw17|X9DOR8~_&moXhvp87U;4cqWEN!Z&Ef3cF%QZw*EUu_+3Rc%H_SaOG`hj=%ikg~WL*0^KeO;qA(9+(uc91ekA6v7l3k<@Q+X@kb^!kjoz3m+X zl60uEtF61YV-PIhV9P|5R#ro{x2UeXBDkozrm4EVW|uhyXbZLs;T;+sJsoS{g$K#xln{gcEo~j4DmPRF8iEZKr#DwLN^7tc(b!zp)Zkyx zRK2)@DlMI5r9*p9XsD>K@XM@9hYPBzYoLrOe{E$&IhI0L=Y$khRbg74B5pu^V9@9^ z<;y};WtGaF8=LCtwKnXW;19M&2G+J=*Cg21s!_*k>w$)X{VlS0)RmnU4Al55gZ}cx z!K&(}Caz6b|EgVFEKN(VT&L{+TTE~{%G zp_f#bH`#2bp$=VFRw7Ifs9F;;Lw~Tuo}NBwKXOq<9UST$8ffVqTnQty_$zCwt7%?T ztNLol{;+Ffo@3F)3I`>Kg3Eln;h-xYy1mjTPYD>s z{j}X+Dg%3kLw#%dHPsh;x(0`+S!8p|g*2_+(Jm)eoqCMibwZNtlb{;x=m}Z_6qHfs zZ^RT(jqcb~a}wpC1)Hic!BLk17jrRgy_3|O>W~KGLCZ-E*k+uXihvwj!v{Y(OUg0N z8ktmsayKJW083d%+CHE_%K)}GR6SP?blAohj2zXA{FN2Krs^7dmtBNO5EG;|=W!Rc z&%Wk}1*@0RsE!tCn6fXCa%|(Izq}lcs|HC+D^Rc8LTZB{*tON(VGd*=`;azGL+!$# zGHTWN%sv$A;DKs6&?^0qc|shF5^yM1_2Qkl*e=E#!d-Z6Z%dDi4z{-pwP=H#E$w~l zgMBMk(mP}~h6)eOU5Z(-vEDD82&-?@_?Oi+HwEQP9T{mGP@#J{FTjE{>U67mHuiU7 ze`sh;OTTHqavEywSu2~&;-xwt4F<}6u@W%ER#rro%#kHD3t(^x)r4k$)%uMM3vAKk z?qF)QD~UFWFr=X!l_gLqjd%xnu(A3KIoVkwXlF}rdr!x}AgrykWiTiQrFL}5o{k}G zHHA1>UKq7@f6D+l50>$S#-{q}#dS@=rQe;jjPk2~KP1O;>MbW7b3;tkOcZ8iv}sCK zYIf-*75;^xLP=99Q{T$L;0BHUZZzA7JSP&u^h)d%k(P>~vayjZwX>rI(}&h+&KI)R zV5AvX(*p6!a1Dbd1&n8{Edy#Av2BQMQOiozkS86fBN-{@SJTRZ>;{Lr zLs?x@Q{5u1YcSM6vQMBk(jRQ=>z9_V8eO_R}gpw7*Yfpw4$OmSX1XOS3aE_CTPx;on=Ua!_rH`0++6)067qZRlj;#iB!{x z9zf&bN;9*%Akfv@HAFQDjRkUAvE+oE+6Ee)GaIYRZGKE>X{Y+UrL2%eFJp_A?-sYx zLn911x6*%6Ba>VTs>;#AP}z|+YAc&7Yc3;iO0|}@625P1OItTp&YB}>afa1_oXt=0 zaf9??LbxZeXX*YauCl8(`5PC))0b_aJPllkp;l5Of$ELyH-sAj3`shaB!(OjY`QbM zno<%uOtN+5lm*@xsIcTR*ZNeNRpDl=8Y8Ah87148^VP|29-c+^3so<(YgX1a`xcZe z^{MNgzLKJnX+_hEr}^^NwDqr@hwF%Fq5PIv2(LuAx1+B&e`SC1bPD(MwG8Fs+VDJh z0quww>Rh{~71%P+);SMXkJrt}Z<)NNfAU~Q+hkkDRlfYXL0>+uSUNkae{f zP!?eQz}-e!zHAy>t4pUJ>%|ajIU5CP)DljWZ#p4z>4-Kuv4^1?nj=t@dE)|d(*1I(w3I@<0p+N$HKQQLnoKFu z-w;+V?K6>jgNv&ht7T`Vv1gF96j~QTM{+e9Bu^I%m9}as{K_GgwGJC#<@(5S$7rF% zBl=)(OFx_udq~dK_1F?4@2p}0t)x+eZIlbjMFsmCNIJ2-7b9C;c)eJki|Q6(_pW(S zNHNk@NmVo#gre2b9wO8>lA~YUv`p)0?~#oSk`9HHJj#x^rKo^{ZN}g^z+f#aXN1 zu(?Ui%o;8kEBAsrzS=%QS!P!Vpf^;(uCbKtZR_COCHq3urWZ&d8|h>&i`pzIN857K zhKbU=Y_ZLX{k7G$rjqWVrPsz%U>OG`XlErQ^>?K0SY8g!mhR5Erh6st}0(er5 zv^UgTA1tp3U_7g;Xi!V9F!`|YDyL<+DTtXtexoV?J62X#;Ty4 zMCIzY9lJWTTqcLa++~x!#J-gv>r)OFvmw|_n`UGLVRj-%O}i5xR2v@V(ocCbD1wXu z-c^vC8>+HuRMjacYz+yp=IRB0xfdWymzzvw*wMo5i;WN~>*B^`wYCLU$gP03XcLPz zM7iA1ZVXMuYCD4%DT@vBqva+LlB`DN?K!xq(z8HPsEvdE=BBz3BXb)m5WwofzLW@0 zkc%zZ1ahschI`Wq57t&R!vi|$R!9Z;+SRhoa&+?7F4JH_*b55D5Na^0Jh`+zXk2XU zV|yP9b6TaKf!1Md8NQILYsOG(`RbN#{8+QWBGL4=8IZ&XciTgjM!Q3*MwSMpmm#~! zNtSE=^=vS^*O49w3MkCh#*2#xQOA;~zNu71G4payyMBWz+pEkj+rZS4Rx5H73? zfIam<@-SHu(#;NY2q;Clxa)8u-^s4mP|5z9`YK$|3EN!RU@}$0Dlb?1@Q^xu0I4j) zg&F@$xfREI8LC=XXkZbnnO#(Aig&T(XbM&;GPDt8EtjZXkww*DVMV^O9AvDyMS48g z3~95ki`BJ}C4Q{>RO3Mt>bj5I(NSBBG*+qGgP_v^+KjWB1S5&LN@51)I?kGLl<3?U ztyPJty4-JP7f8{;Y-wt3sKv~PX5&jS8`re<^;lDEXn-=8;d1ho>oPSmhUBZNgF|6@ z+=xEWX;7D?P7?ne%QpWs5)31(T&kQTpIqsx`q?ikU{zsWJqc@Ky6^$PxcX|F5^HlT zGsrtp*A#>F&J;OAwD+xrKNiXm8i2_mH23oqGdRf7k>=%5sCy{uI9aP&8Rf(v1z6kK zzadl}c%F3RmOY+I)1-}1hLcUN0e?+nMW|tix_a!FJZ+a>xNG=pajA`%h4rQCX+=d8 zsfMGbibZm8V%gOd8#TxTv9Btx&zdW{FgEgPDeX*zCg89k1tlmk*vgx0c{jk?P2lS~ z&}6vRMH3z@WbK+>8Xs2S3L)>-gQe6gUs}et6uG+Af?tgyvZsa(Q0Q{B*K2O$*gYJ1 z9l?@R?sHkgaA>>;VvVv$&2Oxx>ZV2hde{e+*Sv))wYjjiuI#%Suc@I~ZZ#;S*oF?i zw#sSaR zLGo>7nbtUHeOC=!r9VIeFKDdMhKE#DOLY}qEpedb&=e^rH?@x)#2`ae33&lfH#{~u zkjl$H;bvE(Hp496i>|1twozp+tdOp7SSD;E6{%$62&r$BT$Ub6PmQte{U~$RHoZSXGaP4KV6W4!wR$40nD#;pdRYtimA_ocD2orx< z^Rg0+u7^;HqU9N(5uM(CgGD2zgOmA0p$)1=_^BuE8OzIoDrp(6A=8!9@Fr=*&gjAl z+MsQ&l-F`C{ZsSFy;RDfngBwfE(>rq*i?Z{a$K3ORF{Lp>WI}8-Fjh}x>~8CRU(y9 zi)BAn%$6psF*W>J2G&5q^5zD$85g>iL>I+T26q6un2RD-4zyq~f@o?KY43D0fDbFK z>rl==E@FhXLs9gJ6PFy8+p{F?Ai4jGDjUiGkd@K_jGh-e(~Vv1Rfw%DO?j zg|5|GtfWgq)@<`Rt!{$>nP$$AMY34b6qH8}fYua)I;c%O%F{*8KXqx<`;-i}{ROEL z+X_o{dPQbl9EMg^G>uQoq}vW>Y{2IHT81GfXY-~b#RaYtZ3$L1s3jb?PeY@cDYzuN zvxmJrxvOA$DvHGFPvnY0A}dzfpt2?I^*oJPV$($~Yx@%0l3i_b$AaxL!acW*t_#t< z1!3P&P#Vkwx!zPkdCHm1Eov8zHHO6)dA%;`qWS*c|%o= z1z~;}o?XCgb~M_VHwRdnv9?C#jc;;*kXj}8;RIu~F4L)+nimC>R@dSVD|I;?<*ZRX z)zYmwSilg;CsCKb)qW6qv$Oxtwot%T|Kw=1+{EYTQ;FxWW~nZsOC5_yMDiu^co*z(++KTLd~BR% zJ}XO4v6SLh7Vo*#ajjVP^0V<_X+-Cb_g-RLs&7KNHU(kxp!d<2#phlcwaIgt`*PP6 z&MS?p^s7Nt7Qf%&cr!Xaw=8C+NerYH*_FlnF7<43U*@{pd4+MMeif+w@uiNQ=y)IA zq=Y{&|MrD_zj^*Sh@sKrx#mG~u#EH~b?X?$nLj>ONeAY=@v&tu%iNmgv#8Xwz_xlU z2F)`lLh8jN!_!)tpI&*|LQhg^f*zA~&dB#`u4uR4BcdG9daS@xts+IF>SNEex6 zjFByJ#UxRV%0(RZ7(+XH+@6fbf9yd#b|oJuvf^}l5X*Mx^ema}(D67K9+r|^N`ZK) zSDRoK(E=<1PMD@Ml~_=rAq;4w4Xq2uAQaQ@L6-aaPFr?zp>!)LZb z57R6?s2dl-9}k_`4jr`#=bxaJBb~HFcIJ?^4Q0?Zyr|K3=y=s(xcv0sbLh}vP2v2L zHF}i|@h7`zQf9FDn$lnXY9=l%E}uo*Pk~ zy;oBH@e%YBBKU>3hOSMF;5RWMf4DYuZE^&^$r1EqouNaQ-#@U23nTIuh7xh6%Wr6e zqI7L)C?M0PMTDnEgzY0A@uPtybm+F8NwK;%Ka?oL^CH5f^6MOCB%Wi`E;a)|3f~kF zzBeLF?-?);qTg=@fE0c&BK%cEm_B@N9z;JOBJ7U{H$;Sk5#j!b@Z}NVJ0ijlMTDP; z2)`N;J`@rDIwCxZhg`DU5n7=(8DS!!@hlPjcRr^hDD|^ABHY9D!;*fic2Pw7)e+$z zMTBpU2;UPCekdaRazywb!X$5rEI(KKCx>aKNJM`cVVgpzy~y=37gKnq*%k_0rR5H3 zx$R-8q3wk5Xu6ls&P6TI%;ydYiYSqG7OZQE9JcQ?1cP$64XWElf^Gf%c&u3FlsE7q zM`$NH;zCVWnzc(!1%|xd?|nQ448k`~%~c`s2yIN#&Bbyx1bVr%Xgxh*XF!z=_d?Co z6IY$#{H=6i5xI34#>7;p&3Q$-O+kD+ekev=z6KE$`CZEkB%5}@dvswj>SipHhkP2{ zcIhfCUMdYmk)Re!`yMJTDbWKmNCsE)sR#3}KE(3c31@uq31=kwckU_L)(s#%p-ixm zk6GE%$U3N{Ol_)dN!9P81DfVTS0SVshmd?I`ldXM@M9|R2M4{iSsr-94)v|*Y89Mh zx;2O=4=VaJPG6|rwHjTcN&hu^5x)OJ=?K%vPl*2#TN(QqhZ#3BZe!fZxR-H1;~Rvv z>iw?Kb$IP828rl;ycLr0bokMPD6F1wHDLpN0u|V(Y3C9)(Wgv-aFQM+T#VPv5|WTO zCgE+0@<2VKaT2{m`Rmb3xt^%^6pCMlatV>Ilo0hM78E{%aflG*U%=sO8MiUs&-g6k z-w46?3qmj#a|e!LHr5b;Hfr!X#Hq@pPurXZ12NMVQ~v6oTS8}S!$_&UZL8Sh}+!T1p4 zQ;ff3{1fB*j7J%1Aw}iJ358=B$1zS}Bzq^iYQ|>9R>nTY^BAvW{1M}wj5`^hV5G0g z5Z^Z$KVtlf(c@6*sf^fT9esnI@Gi#t8J}dNPl!%mqZB#OPzpXT-a7WqKv!V#W@}A;wD>w=mwu_#ES_j2|!_X8e*-cd2r`jH4N8 zZX)?+Fjg?0&UhB%YR2`9moi?@NZ%A7KJ+Rs!eqt?jI$U6j4h1kG7d9d#&`|m4UAhE zf5vzht)7Q7~fz#$oK){$Bdsb9%K9$qv28fq8Yu6BN;Op zvl;Uk3m8vftY&OyyozxvBfZa`bTH#6>F{1xLvjE^%u#rPY>ml+Q+{+;o2#;+OUF|m_8d5qH;Ph(udIKX&4;}eX( zWqgnEL&i@T|A+A#MgfO`%5yWuF(xsNVjRmjj&U+$G2;xzd5jAfs~PJUn;Fk!Y++o* zxQ20%aUH>!}vbqVaB73 zUow8nsK+b4MlmKZrZ8qOW-(4+%x9d+IE(RA#tO!TjHfd$VLXemjj@Zdk8v&I4;U|E zyqxiej9VCg!gw3w&l&Gw+{O3^;}eXu;ZAn-0^{!)UuArg@h^;r82`@rIpbH1#~GdQ zeTi=j;|Ru7#?g#9j1w6P8BbxH!{}$MWL(79$heF#$k@Ty&3F#uddBk^FJZir@jAxs zjQ24<$oLrJUdHDcUt;_N5K~)>lx2tT+O(F@p{IeG2X-YDC2XCe_(uv@ngoX z7+qLMlUzxRKE~OMm5fb{EsXt)7cySUcq`*h#+MmiVSIz}bH=Y29oW+#Ibs--8AmgY zXDno#$ymqO%y=ea3*#!rHH?Fd8yPQTyo~XOj5jj=l<^M69gI5}A7Olw@i&b78UMui zF5_XwFBrdN#5a6o{Sz3|7_%5BF-~Qi$5_qS#P|zBY+BsI;b$1%VEiA(OkBz%eU~sU zVr*kv%ea~GmyAy`?q@v8=uT7o@)&0`p2@hLaVz89jC&amGJeBYguN}2FTl8*ae(m( z#yc6e6T+tV5Ms0O8OA>_zQ*`h#=kNCoe<@G$>DDpY2%3EqY1$;o-v8zM{_ufaXiNt zad;ZzERJ8m;Y!9Dj$h2-GZ=#$-^JlIi~}5h9*2h+H*x%R9NxmXmE-T=@Glte;rNF* zyqob!j^D@OmlzLl{F@wphw-l*{|SdbWBiiiUD%@|{iQJGG8Pa*pCyblINs0U3dYko z{tU*|j6Q=8Mkx% zBZQFqamHsE_c8vC5c%IEME-9X9b;7d2twpfVI0Gl%{YM&`A;E4{w0jdIlh~4zNYmt zZeTo*@ghRxzm5?3cQHQ9@y`*?hg~rKf$=rQHwlsdLqg<_8LQAsi1@LD^YLXb#wmg!ZLhO zp7Do_Pcpv1_zL4Yj2|)n52Kc&_{1=dWXxim!q~*v!nld?Dnjf{{)EGK5<<_vWPF(M zF~)t2FEJhPl$ZKXMB(G8$$5a#sMebdwqnEV>IIw#v;b~jAe|Kgvft7;Y?h&Aq1Z_ zoPG}DI*z}JaSP)P!tuENM~M7SbND63*BIX-1mE`=|G^lIyc9o!5OVklVWagNK7$bT zIh%0}<2j7$2tj{2;hFfJDu?eO1i#-fzRma*V*<*g^vR5V#*Ht6N3IWLilp`as2&^k2CIJ+{gG5<2!`N_gBJFP5YeVzhtBf<|Mzt z7)1!WR1Rk_<}&6n788PR8HWRmb&QRS%NbWNb}_DDT*r7W<0XujGj3(Ph4JT%I~eb0 ze3)?$<1>seG45ylGa=-Dj}Z0zjN|{oc$|?w$4+|j5P~j+5cy^>&gJ-pgrKWqT*|nd zv4s%%dkK+$GviGhe-|P0Z)e=a_z>e`gvkFJLgfFD@e_{!mJs>H6ot`@@r+4?$nPUW zem`S?BMgY zV>;s)#vDTMnZa1c*v7b?aWmtsgct`g)yw&QI^#md6^!c{uVuWQ@lnPDjPEcWW2BD_ zksmRQv5E0Q#=9BmK0BiOmNCtt!c!ROzBx)ijj@@rg^})?qx21o@;W!d*Kzn}#$Pb* zVtj&eALDC`e_{NTQC{x`KaZ};Nn*@moWeMpQC{x`eItkE^=^cFIJ}d+{5@1<8j6&x1w9mxSjEF#upghW<1L1^r(EJ7z-KY z^-z?17Ki&7&t<%f@p{Hv8MiY&$he2`MaI_{|H}9&qr7g4@;p&Wo{^05`Y7THIXsuK zmJ!w09COuuIn;h>6o&qwYH6=|gveh+h)B3ZvYko^(SB8gXkTQJ^dOapVO8Qh#u~<@ zjH?*eF>YeKk?~H(Uok$#xS#QT#-oHN6rUB5NcZbfIEPW*4})+ehnF)BG0OX2kiM0| zsQ=FhQJK34(I4(%y88)z>b@|t(>)YM{huR5{Vyat!tXbP$RA7gf&5=b1HpeW;wb+x zA@Yxj2O|GDgvgI=PtCD_^$#9W-w02mc;u1#L%5#8;Cmj^4-f|>Hj1|xtSz4(tRwyRxr464PN2|92!vAX`adZ1`Fgcfhqn?5jLt5%HWq0eqS|Al7CZ*MRua?nD@$lzu}lv z-&^Al(Z3NVobZHto5|*_wBM(I6KMa#qW=@#)@{48Gks4Nun{T++wMp=`>VZQo~#Sg zUCyf4ws*9y#j9m{SN3TI>b#}3b)aLNJr!?Er)<-mKxdRO6{cv4!GaiDkA31sqt zbY={pG<+9u4ZS+to)6FK~&igNxA^R8hdxDW=l5&ydmTi6{BVnb z#cv7oGxKdVPne;}n(o8Jf2$ruNA)0HbeQ$n03v(2H(nX42QDdFsM4;%(a1UhqpJMtqq31nBJi%E6E5{P@8wviOZ*er7#h|BiZ8C_1YiL`U@? zUUZn{`XkC+ZmUNo(^0-oF4r6n4uW47G2(;jNI!b+$zIN}R{s9bukiueKKLF+90L1}cnqUfyp5*_6yUUZn*_D7WalC8ekOh@@9qJH*z(0#>b z-HD$m&sP!r-mg6q_GuxmTbX0%yAUgVe8o_Ta=yFXWpef(s2>FsBUmnu^_!Tl8)hiAeOc@Z= zR)F8#Sa+C*nHB{)dwa|Uzt>@W#IG1XDwp_;ir^QGiFGR_@?r9u96@)-Osu_Z6*lQ6 zfX-fS@;#ci6m_F=!P+X9_AkslRMasLETt1Z%(OWX{Ce(FYh&U^dsax6^=OFTS6`-S zFPcn1W1iMV@Ou#aD3SP~N*2GB5&SaBaqS=;1bmqM=s5v4S^#15FzK#hIy1fsba|A>2bD|5WjL|R_XXq| zM!X+CY$sas(Q^%GrhY`pqyGX;n_~umCTl`-%%J3ZLAMQ)3Dhm+q;kFZQJLUp9W|S< zHn&BX{6<934ei9WH)6tvNryFYJ6-~huZ#2+v=#If7SEVAZE8{Rj8mrje8ojYMYg}w zr%j_!$*ieJ^Z8apUx;sRsPB0zrUE_7IN#&g+5dzr^KLQheJB%JInAu3xcj^zz+tr)v!@}`@PO)6S&#G`KlQtr6BAyrnM ztl#qN(0SD6jLoXnu7H*|e}Br>xTDF@lq2IO4|GMR8Q(Zc#Nh*j?xShO9f#W--Cd3w z9OcpFV$0z!G26HyDp_hrd?-XQC_ZRZUY&Om&idjGSl&yey@_@OUwTiMt>Ih$_e zx?ak4rP?jez9?X9R;@dXvnpBcMFFLOi@Tx@dvs%a^f!98=kV);RI|gY#SN#Gmz9gz z`VD7vz1gMR;E=U4q~;W-)d6FNst=VpVH3$srTW6;9y|QyL#{xaEYS$;-*rhB+1B6F zNk^t_xnWz1rwC|=_xH~#cOG7$5yj`-my~I*FCC-rJfiIC9>=fsRmh&zk3>c+EeE zHyjOh;3YFdzK#ueul?X4-v2+_H*V0EH*RpER=0M@*SFG#4=eW#Y{aVvRkzQdAIawk z`roFVaeub!-Sl+ zc1o?x+}1sF7xxU8;{e6|qD|Su@QP~WId9GhP&T%rM^n7zOAiucP*$l4OB_$ z8cmTI`7{zK-B|dW(mVP!Wak}I)8+@jN&vfQPW2~0*AKVg8So{rCRpN#Nr2>=9Fcf5j-H%cX^iSBNvteOit$aA(_lZEc?$iRd*xRbtvMb0#xKB$~_g9^!I!S;GEjy00$V zx<@~Hy!e^bdq4D!h>_Or3xwyQJeyIT_d)$gf^kimdw-j>fRl8AcmYT2X0#=*U-&AdB@wQk!vSPXYN7HWB(J!t_IFZBSPT2F{> zuPqPWg6M+@uk0A`t#29h4fXZ;2I;*8l<&)joX}l7ta*i+$Fq|HmtbV>>bbtmbwJB? zA3Z)d=Afsa#`YcEFDw^RqbH)>OFlkS(k!N>kGi)k}@7B^BgD%%woIn z?#@GxJaW<2V_K0og=QMhQQ;{MymJWkDmrS}+RmN#4wu^c0{We{_w!P(*>lM6rZ^1` z9ogeB#`}$c@_pZ5ZO$Re7dyBbWfYTc4z5-dTK0JMjTGhW-7Z<1z9XgngR6;BjeY7o zgC-vbDn=x4v1+I=FgX zIhBR5u5TV)PU9g)C%31t=s?bD=V9GLsq`DJ$bb8lV`;-?IA`_V^x=w>x9{vSCWtxr zlpS2Xeb3~8ICYe)g{qUgu;BG~{^mZ?wI;tKKR#-yg51W z)}c^3@piuv3VS9zlm617JG*{+C@vfKR&F`CI!l(L>cdj&Vvd+R>U9<84k%Q!H*wlt z7W39C$EH{{$WJc~Y|Id|DD94Ja~0&st2?6U0+!_1uji%h5m+zDS;h~#Jz7pQ>~qf{ zEyoLd9GC=rMB2{Idud(~S;~7QPlMX}PU+M60$MiB1`}vyv`39-G#}6!#}l|>=M_q8 zdG3J!K&d>BDSUpl5vV>u($SArF0&5&Ra%CslaUvDAg9L{P+p^3=1SXD%rmF5JCT=t zz}TVAoj*~n^6ZCRO`YX*C++659^>vD*rOqPqVr&&O3l$C?~(l;>Gvxhdfs0Symm+w zW=OfPcFg-!j)4NQgvwF&x3gXG{_`O-@1G8Qd?>cieSmcHK)d8CXK`QQOQ`invIftt zE|sVqO>?>e@2;L0s1GEUkOsCra1&NkaYwz@%4-wC)b@Au{M0q&)tsK2%iIUDa*DaX zXXV_{lX!4WzzpBf6FSfC5f+{OoYri_)rI8?cAwdYM-}ez*C?)sFtgLTxmvoK;bJNdP{CDi`g$^8??0x*$N_W%mJ0I z^k?LaQ@poz^`TFZc`8luCe!#T+ZnR693K> zpICi4)c=gU_YP?J4f}lo`@Vv?!=U7do;f0K|Lfw;#$&!Cr(*kK5yU^)F9T^`A&q`? zeli-0D?}RWI`8TIIXzfyP2Ey<+aGdZn;|Joid~@4CU4#^=6rIfttXs@>UC+^#bMG@ zoR;^a{Yv(np0x7!y2YHWW!vFr`93<>?`wbYP?4=1je9bW3b{0@e`^A6;J&y3cWGj~knWr@k1-y1J)*`K?#>wihkMx=fba~(;Ys{v z?3?NnQ)@vyM!0&A;yxXD^~q_p;phG+2In)<)=;v;c{LWS?&w%V%^F4fx9;J5oG(hd zhLR2Ee`h1=DvGKbb(@TG)1BL6JkBmG4o^3ncqy^g@L!ZMfXg>Vaw2UMx__L6^Ry(? zMN4^(BBnqJ!o3r?$`NcU9lU%?|cZ9da0N^FI^0A`{UmwA?t@|?oz(uu+J#I4vgPBuQt zL10GQCy*!2I1lA`X39XOw=xTXS@9&PLlfRZxEH}QTLm4$`xY^oBZFQ;c$cFpp1Cq8 z@KP`LG%$CyXI4Yt6p}jkOth5yR7;s%5WFLc3qvB{fO|jz*1_W0v_5a zH%>!BRCUVNkV-T5f;6f|HnL&NfL5aFQvWNOs_@V#1eVE^G$R4cA9c12Gi7sT>ZpL+{ z=;<;rQ`%|tyu=4lLX}ZKtWT8^)EM)f2$aW>jno_TdV%N~88}^YAIpJkJ(>RnaZ*U8 z+*{E^?kQ=A?aib&B;{@_M#LzXh-+O2UBXPE_a*tFVV=1$XLyFe+V}=r3^B`N{~~q# zM{tY@CLc$@Fz8wSnAX^2^hA#_2ilM6kd_f^?8879vr-1UIR?1ItdcT0w&e^HyG|Jr zcNklcH)eJ0ZU~=Z{0mx+>6U?!Bk3LLF>4anKyhitr;sY9H}$_zY^KzIOrNa1PjmkW z{9Ied(|xnK55m0Nx1NHCTgKf=5qCj_?l0Yl*yg*BB95b~?vF6GxVGo+L4@y4{F&w+ z>lvhhZRr%G`bJEGGD!v;o6#G_AvjqDZxG&3VG-^rDtM#t3Tmc&88m)` zoI!hp)>-n*CE2b|7^GSVdwxR8G8Z0JA!3}!%u#-Aw*^%`%&z~Yxn3r#j+P-y&Fxz~~* zYhyhLW65qtZqO2Z(oVFI8?}Tid1`3xtK)G?OtwyijrAr>q6ur{hGH#YvPp~cDT;XH zh7v6yU!HqLZp3+kJdf4f&*8dqLZN;JGN%v+H3uh5jh~J&SDXR8Y2pa}3PG1O9Rl~T zV&V51h6O|HhdnvPW*Q|oJ+>APV#7K1SDA5bUj216|L5#Q`%wok7Xg*FHf`!Hl zx<;EI($K12aoKq6JBq)+suIQ1P*jo#!km(Y1Kl-6bKit>V;xA|bLkvK_9&tYS=_1ibCI2-SEHI1077`Zg^d2ntL3AVUMDK2}h@ux= z!NdA*$dPg@&d2H_TInTMh656hXp604$Z>tTJMyz5{ub z0!IwT({v)}k$g>5pgKbQ4&A~bzDgx^Jr3dAf?oXK5ntnPl!&9TUF4!oa8QETQ-o^%*aABYuLo4ZU=N_=c(>{Agk?h8Pq!;%WVT(noCK zQnKTmAEQkZm#I#n&2C$%B`TZtcyh>7N<330dA+mOYl&y6bKmSvE%9u1UX;^@#!3vT zP-)I{sB_{96{<%=LzKi8eK+boHZAeoPLwEnQQ{A5y(sZKNgpe_ZsPeVMCCQ+qo#=$ z$YCm3i#mW%)BqBi-Hl+Dc%eQSfs{e~iMkEdih7O+`p{+F^ASwS&%O;wxpN`T7~!}M zRuZ)Z5vnO;Cd7Y%fOsBi(ZpY2^FsU+e;pzj@)}|a{(3|yR2L=oVw{K;A4B0W;zjg@ z;~3$QD`vXB6D%rY%AHxT{;D+SG^RqjZGK#s(_#W6Y3@R;V`kC3W&8<^7&FI7=bEt@ zW*#$FjqpY@&7<>Vz-9ax0>{jk0gv%2m3nI2YseC9(4*rqr7{p}oPsei#-B;Gh|h^Z zSBNQ7R=i>4s;+h|rqZpUAg>V%`;Vzgy9aboBE1FC-2w4qs&$gOj652eUUU*mmuKY8 z>GVg7x*w5IPZAwfg}f{#!I>6CgKg9YI9)&K7je_ zhA9wcu}-fVQ&cGvj*(;IU!@$))P#awt|Y{3d6c6I&Fm9H z=-XMEo1P9FIbNriiAB+Ds>DpKjgLit6dv*qu&GR$x1-BC#3WP<#m%0I2O=Bw53J%+ zm&MPd9M^-NCi2lCh4>a82Zk4VAy?{IdK!Sax5b}Fw4Z=f6C0siAsz-phxlMRDdAQ) z8XhqnicAnQ(Pz<}FGfMB-FkV5M}Pcd#A6~gkXV3zB1Ahnu|w<~0SQF~Brrr;8m(E~ z^vFi)di{z}?(^b5pxp7Yu^Lgf5ak%iAZ->ZkUFeCkL0n=)J@q?oKXiIre5ZyK^3kC zzHXIzx%VtgE4pzEW|n$|mwF`Tv@aoe>XrIuls7i@nl+SnFFIc857X&fGmb-^)N9j; zJbE^{6RFpwQ#JIZIk7}{Lpq6tr{fB#TzcbHQ9fv4Nuzy8zE>|mRAuU}sE2|6-nDDA z)cfUJ=&S(bFU~zYKFK1V@;-b4m?MTTOo;0T!8p2 zaW*EKY*B|2bHw>5D_6XNZZl3?1~rctM`0NgL>tP@6OUm;n6?m!X&q|Oy* zjKGu3Vh=PhU+jSVrQ&J)^^2J(rA#~rt(FUVV_Jo{)vaj(aUS$mB_4;I)nWy-ahiAp zF$={$)TKrYq5CcpMQDF|)@wvEB<~d^=mdRY5&rgzU6A1%@gn{Xh;G>L zpx6l;9TG3$@A=}gY)!jB{0Qe4ij~mbu=pb+zevPj*uPl3i?S{ery=j9;svzqCQ*y{ z%f!fWxTj709_@04xChc+DgKDMUnL%g%vTE^q`F4zK38`=Q(^;yI{0 zU(`eX0?~??LUA7W6p2`rSS(`EVM@fAXsW4V2fEEPu^UZ(ikJ*O(}fe#&JacDx--QQ zXk(VhgjBP|EEw4wu@WXSSNs+e#5|Dzp7X^g(Cw+>Cd8DAjVQ}6&VZ?vWzg&6wBe*g zCvrI8D!X&b#X^lLefz=YDyRdf2boEeZW?FTA!yXM{r z7HQ|}3y>>{oLe=9jmnO{7ct`2Tq@+Cz2-dc%z_UW6hHQ3r9I;x$y#C8F@xEj~og@Q7$AB1+7L;L+k1 z^wb#fD9*7IxfCTv&C{Qz5-}HOQSE4qv6)f5TTz%?uSWIBC8}nOhEYZJC!7uy86&&e zi?yh8q*v%cpaiZTyNL6N)u7y$@fuGN`=MCcZ%kJEGHd0kD@}9%5v?1wPM?NyqG%^+ zY=64X1FJAzEr0=LrI7%daVv(i^c*=^WI{Xy#>dkf<}W%eiz4W;<&}7Vn1*gxG9G4n5QNg7$&obj*81B>kl5Dy0FqKs%11pT@ zDX>5W+KmIGhjJO{H0Tvv=@pV&4}1~mCOx3jd*V_^&tsc1d~=Xj>N~^KH|;}Y)ir5Bx{md)kTYspY;RAsD1gJl#Zk$+fi^pH43Ddb+B zW;}rYpHZAlKI%g6kD%U+k`(gmbnJIjP>rUhkYlK~IlQzpmcb3P(&1e~?$sFyaWu{bK<``wHBWYQY>65mWDHl3nW@Zpictv_W#&pn6d83C7$*bMjQg_?PTj z2iNv%nI#!ise0o=jQE+eLyRO*k5MyOtfn>-Gy`2IIw#R+=fm_AEixxV4DqLNG}=wZi0cqj z(fxHTigvS=Xk*93)BEqle6Yi^0X;+r`Qi%U!T_s_A7aRZgFFpm>)2d96{JzLO`Awt z6xbefJx-a|p#)8QjUFMyQcMaCu@4$E#6nn{M?8R%z2Y65`$QsIpj50uJ%=;aBCF=j zAmwSkjOz$WGiXJOv{}>PHymf5!B^=@rJ3SuNUbG3hXN4LlGb66BON8Z4c$?-lJ1r< zhL&_MO%Yf?Bn7|+Gl7;w4@E&3EvXI?z(GJ2q(9uXkR_oF+X1u0aU4R3 z9S8x&!9a*{NWzef03n1dWFQNfAtYg#3|X0E7~sJq!z6@+_kGoUmU}G7%)Iyizxz|4 z+g)8<-CbQ>U0vPxD9!AKpiMF}u&5-=@1hYK%yTdYubK8Mu-q`G^|CS6w9kV*hCS^l zdTlt<@XxPNbQ=AD=--84Ir{fCGHk=N&tei`l|6`2l1_Y$tYarufzf1j-Zw#CTKa2< zCkUX)6bmC^(n@={&JYm)I9v#O}spO(y6RFPHo^+{+iAEAc8G*VsJo zvRTSV-;QV%Pihp9TNNYyGNdctM2tGb=4p-Iw_k(wWCGVb2ga1VJ>@pU>(=8j>~ffm zy3L4xP{rqe8!b;PG-LDyya2c@4-TA>&VTc@_KhV#m}tJqJT}MXX_=AzMU2wyFT|$N zJ`gb7i}tI?l7}&WCIn$l!pxx(T}vz>%mrQ=Yh;gLyk^(OT6_vDY{W-O0seD36TMzB zBmOo9e)j7Ez1oLnpN2-5{aEaiJ_)HK(vs}2pa-)L#2)prR7HGA{yAR~lFu-U4t=J+{-lkUN^n|~evv-3^Cdy{yq!^l2{sWVoYu~;{OWP&E1+s&hQ0+YLaAsAM-x(pRv0=h%GW4e?PRq+>c7r z9%7any{}=Ro_bI0SweW?XG`n|*k`2YgM4-+rtZRXV|-zt8cY#fCXI9&IN86)+?qO4 zl9d30fa5bTn-`VJL|RPfSIKOWl!vi41BGWzGOL&;k6Ofx^fOQx={yz4&O(71t7Azb z$gs!%2~s~}mGtxwp@B|_&xZ<}*C$!WnWg%5Atqhowb;EL3B`o$;W!4NJ@zoc984qo zFa&B|Y3#cmqLDoanV-Hd_8UTkC0Bq2s_EIkgvOcpjhI~w2wNSR=h;sIxNu`^7V|{x zg;Px8Y!xK3--E)_+hQw;AmHr(1<17hCC!9LRT5L&ug8?mzMb{m9lMGM!a?C>WM0P$ zAplb@&gR{MTZt*s{}7mHWcOosPHu@kNw73nNfJgqXu68gtTW=DU5+-sXA(D1FLKq}gRk^^AJujQPi@k!C3H4L&$~?QHC!Psct% z2yGhs9*XnY-(~>&YV%7zVto4ow6Rq9_9H^2Yjhnb*_i(gl$*86l;*xngsKDx#b-h6 z=UkUdH(M5}Qk{^&?zNcDm(DIeCVH}j`O@_rKZBgks#nC~FF_eBzBYrZrp8B!o2Vo6 zPAPaHq2eTue+ER0J|~Lfavyj82qw|&ZECqXMzESFHv@Ur{W-L^?jW>^E#901l`v}{ z-Uw*?7}zlLDVd#*6N3*Uz1jwwZ$W;d))YhVr_7VN6z9uriasF?_;*6pP<|I8U36a# z*_8$%)6g5|p<^qBrLzf@i7ExQyomYzgp()jM3oRhxU5Hkl*0qtC!A8&2044q>N&;T!hIox0z4~={&7ounBsNZYcFbP4nb3h}hIjH12cG64up#oQ()V z@e7LLL8LDyY%0iq$&s!1-AJD#>|s0}ab!Qn=$8rm2Ik>c9N9m78|iNl_81ejhCPPh{%5;4g99dFz$5bwxSajN?u&HO}HGgNFGLC!b3@CM~aMENM9p^tzpVE?MS-ehuAD zxnDz1sD|E94VQ*$=uMg zYp2nB9RiO+WF{1Ai6WE{sJ5_H!(}aE5n%+`pl~sTLEXk#Rj4t>Fqt|5eRwBI|fnxHCT~9IL+b%W{ zjbieOeIdo<5~O+4NyOxJTNc#ANFO4MV)E~{EPp4E{xD&WLyUiCiI>AxZDVG#e5 zElc93k-nF(#{hfFmL>6PNPmSeiprlA?1xDIfG{d$Ly6RjNdF39`mGp1(-W7UAD(^_ z#3{om;(o$D@!DZgsT>8~07J#a_hG(?N_`EbUquj=`WHmrLZFL5sZLuIH|Nnu{I%_!#x!= zDI^CWO*;XjSd?nmC}2kbdlS-LrC@Bf;T{K&?``kWh++DIk$F2XxOY<%L?*;*hbgvK zA!FS$(B@CsZ=v+uF2j7vo^u^WVuyzJ9nv)jB9s@Zn)e{Rn=rQEBGrOnqz4G&iNGEuSjUh)LfG?YL{h=%F68S$V!Pl6 zxJ1Ed6aFp2^re99wY84B^{QA^InFz6alU^Q`CmcUiQhUJW{;i0rrRf;I~*G=K+USV zye;x~Bt&I-+9UMxRnvK??mk<*#rBD7uA2T0$l?8pUG|A%S5Izs>cFwCv&P2L^u(g1VDcDA&Hy})>Q}=^*9*?L!nb|G5mqe_%zpsJopxdm zkkVQJ><6(vgtSda@Cf`6LLss8lYo$Qncqgi$h=yo6mmcC+`ExIrx<=a(A0f1-1`CK zM*O1+C<=9(y+O*cMTX1f{3d~BdBr}1*|Nuf1+sJ$lNZ$n#C)IoK#3}>M zQ8gb!pEHi5e(s*#pChsZk^dB8z(RKB?*a6dC|&s0pm5Q;2IvBynAhU5$DTe2X-K;W z!1sd%?;}qdk>Ec^rH{XmSoytxPy{m*NTu*Z8~&)@C^`)+C{4q@36G?m{}d@d4&WUi zbdr?6h{Sz}oFQdm<$uqkT#D4$l+8+ji$;O88WHo8cwAynE`g+^eHg$mfet;kY41hi z>xl5;aN#F`mH#(@NR!tiH4fn_fQvr5RlUc>45R9un*Y$@L%sz1|WMn&l zT-X0eBWkUyrHB~az$if%{uIU#g9N*`Kw^|O9)WdE9`AtG72!U(-1@{oNtRE%}c%)A;dO7FRryGbJstL^ghD4 zAE;1@{XwM95XOB$rGmYV^uG$;O00NF*-ynLAQz#i3_?tSHcQa0O?LM8paRn>09=P$ zUXLzhMpgqLwMg;*@Mi5sq79L4Omri0DI(oW3?XqXBJV-SKa7NRqG{pv_+IugJT{;n z&c;8N1C{6Vw*&1K1ecQW1SIGg)iz+zr?bkSgMcMT#9ch;x_G ziAX*|1v-%bDF9Hl+Xukn1bPS{%ZSm43_}E(o(f%?kpbR_$HrZY2pu|m{4$1niG~e@ zV21&_6v#(4jBP#!7`NBAhhVn=_9eg`@nICSwAr*9*pde{ZPh*`%DD@F1QC-Dhzsn> z^v|GuX+J~8{ooh>dvVswNbuhjKgPr#kl;ngXP9u%dwRS0^6achNW6^5ZxNPFN8)=R z$Wb^9iup4DAfuiIfQ;G&U<#w$pCX5h+OKoQFbuy2jNSB^M_ZKcF84`9$h^Pt=@^+W zYna!;B3jqH5-B%3n(g#*^fB#50C9F_yoGia^2$fnZGcP$Bo86$lSm{GnaRZGkXVAq z0w%tSL^UECnBe>IFGgesLjI4Cuug2q`USqn02o17`3e&2LH_sW0pnG{Xmau6CxctV zJpigsag6BgX|d9Z4YyC{A08(ka_JsGKDV!TyhHvGUH+?Q=bOt6mktmX|4Aep!l4UB z8-+>@Hy4@IyJ_Gb5e@)06)@`E=>aTrF<@Bet z`ZBs13laGdh`V5t28f!~2_9K?0Q)5R^(h_2rx77m7$f}?_9xA`XO^4+g>@^= zf!%9;;C$@EsS(Ymt(8=XG@qZg>ZuFW=KdK=l;A`vzvnDbepAFz@Q;@4oy7C;yd`_9 z_2+^dT@L?jiOXRk&qQ9Z;`Bj_-{5D~6#5N}^-V;CYve7fpf-WbhXMSvHBFqp>j#+G zVVI^Zcc~Xo{9izsZWnPkC{72%oNrHl74eBb$I`z*#Sys*!lD`9?diL%D zcFk<6=Z2t#WXx@%xu3LTLvSt7c_BeG_fx80Hz3XPU@_Cbqx#4H@O=w{v0xUs@u1X% zg%LG9uv)Jy4_X^o*J)tgjUevb2d!4t`4rM$Ly)oOnbj5)@`cOJz~QtDvT~f&8O}1x z4L5;|<9J*h&Y;0(xbt<^t>G+)b}^eask23o%ax*Gb^maK-#|8v@EWMgGm zKc%{DEa=BF#a|jKRd1gBw>7%EN3FH&?th?LuOmozk6KNnP>>GS1cET|gNjlG(&q~d z9lcXAzX$0~gmMzy$U6AQLO5j=+znXTpYb>fjO!4x=%c$Gky{YldSE3JupoiqOS+NS z4DeQf$y`o1cO@R=-d7c#HkXCt>yh<5*1+e(S+4B>Y-CpBaVX)95)|Jvur6>3R~-3f z5t?!ie=!KiN_JUIjBAwu8T0O(2#1d)rwycrDFsR4vL$R9vd&?d`_Yg45QI&micQ}| z`tJ}jGf?Ck;4h{(2Gm$|8U?y!9Ho*r=?>PR9h}Xx`Qw}MsgIN{s!rr2*axfjOms*RUSk75yH6louOdQBK6cQ`H6cCcU4~Z~Ia{~ZHKWQ+G&m&?_LPus< z1$#;HbpX3Tppz6|M1r^d21$`v`F{q46d#RJtN=iEIlK+=9#BdV-F)P7f_~V~Fx=^Y z@kYfbGz=QRr9AWU#g_%P%}RgUa7zKB8vc%gaVB6%6|w(UT~sziRvLHAka_Wg(w+5Z zKihCOq6n9joDHgJW2mhOFy0B7FR*RmhPXg&w|IGEZGf6_5m0{xnA@o%yL9FVVApBb z{t)bXz)1UA4P)<)12zir_^5`V4H?e^CW7_?A|hxnd5~8~%^GM1T$vnxev~=Vda~VmLA}mChdT%+gt61R{q&FeN zc!}m&Q+#z7BYh!Zb0)zGH02ELQlz^HJ8fa$6zmAnR}%IyNXSoA*?W<`i?E@5Sa4=; zK6w2&(vKn(JzUMkVW|EYk7vy(ucMD?-v#hl3v|9v9u= zbc98mxdAZVO!B9v_7XrAjYW%d@Y)a5i+>7*V4j=_dcubX%yJHBJdUA8$e}Ot0dvE( zXzE;~`LAQ9Ua^RU8{S08TBJ81$f$i$vAi4Uy$B_}#)FCrN0AyMRvm`%%L?`s(qAX+ zBG`lvnQ~wJUy*(hp`^q3w!-=|Qh!9aU;vesqLIqF&H&e?!bvKn2!JMiuk;bW4CdyDR&@1Q483Z$CZ1{Rpd&}Lx367^Q_726^EkNDmk+@rt=s~)ZBz8RweP`aHKyN{q$^)fA zb2aZ7@$CnL2ts;9kv@U+hY*TMMsL&u6AE3ZMfpytXpU6$F|VRdQw+ifQ20KC9NHzF z=DAdb&m#Raf>hL_D*6M`|Bg_MNjGjq8%xn*sc5lOl)p*$sKs2!9wjg-3lOG$butlG zae_4D`ICV;?I;w`jTO>?7oAz8_!435gZ3Dn4jlX^c&>l$Z3W(8){P?x-ofZs}qENsRPb+|QsTL#R6 zz5RPo+eqE|_G+ruW`L>@&Kn#UHs0RC4&Q;~%?L8%e*_9@-b()+)vO;Pn?K8r9n0f= z5>Xu!5zR!1J%ovpt6=9KJ&Ukh)LN)u8>sc@nx&M?Akv+LS!i~dDeqnQ1k$%5 zRQIAy57#2|0jw-(<|JyuCy?3ZQPB?&l+DCSitB{=W~3tPohu@7RS{G-+I=Y=vR(}7$a+Om zye5YM;|0_m0^2rW)EF~LW@9gW5*e)juJP-i^3L@~I=b~~Q2Mg2@*o6hn{^1M+Rp*X z3$f3Ja++P6dd6^Hz=I3$Z*}IFZMbg%#s)2im~a7zFl6aFHwXd|=Df=_m^WuP3MFyf zxb*e%{%(h&uI@YO=4>rR=0TmIoUgR|RsqT$+!V^e4FTlP%f=aWuTKn)Ucfk+zM^3x z(0@BMOf6HCe_5sq@D3=%cN>M6Sig*!=WIc*#q0A+F@4VED?`j*R&r9w%vk{hHFGZH zO&IexVw08j8s@)=v7+b`OX$xuCX-~%YglW)0Nxl+BA6%dt=BX73k#^A{sUt8D};@# z?F(yI*)~iE{^U(6{W8#1r46j~A>Nm}3z;_|uc&2-1>aT+J~DoV;DQS>l7B)Y z&KgN8?ZL=O9!w!BpO9p`8<3`CPefCwpfD;Kt$>O4x(E@<&|;klGs&gSq702HSgH(J zY0tc4%@LUvcQ-}o143w<9Q@o4;vC_R>k3CO!e=y0jR09DBT#5eCbw%&LNtjYw@A#B ziLH7B&dlWqI9M6}0*0M8a$v+bvx*}yAD|KhVfm-Y@_M8;A{1xos=$cwig!^{0S8xZ zlCq{E1oI@1#5U4-a#9wfK@hkUp^;K{N<51#PFaX*HJQph?zZtMFAM zY+i3ue4*6Au1Iaj)Nx|tE89gOC-6is8>>&LCWj*Tw_P@(U5MwvoUuV>g0A zl7)oK8$f&sq3~klE@bhAES7!Ae75mvr}#1EFX(D@U6 z@()7js5}V_#SAX*`h>3!uTep1GD|bc;IFym=IhWsU}vNuEk|#0M0hw;fS$7^62K4|^bjx9FbvZr-GI?&Tccnh1y($UEZxu$ z*f^hO*8C_NmzPu19tY?OFku)W?fXc47LgMOSL=GVo5^EvpWs%M%Oq*p0S)}(>L~dh(bhl5#Tt`^Ov!7Ow zFG4ueg4|UA`~W%pSzlHa62Cy?X9#k|jZ$o0i%R}%m0S;Wx#IRRa$iDFw}ugU1EG*u z{*`dDP`Ml_`50_{Gh{d5E+72$z#SmSaR5`r_~gAbV_62;(2oe3Zn$V_7T*KN7aj6u zde&4V;*2oNMPdpfg$Nl#z~>2h2FHlU;u%*W!hz4Y1`$e*v63fRA3{SvLc(oG@D*|; z2rDl^;vVGGGp8Mi20-f(GPptFuOw#hH+G^8+{tMsL8Fhy3&u*GpwZv*L*!-+BC!kA?Lf$S4-%ImvKL_n4=lN%%e({;{+vVCsIHLk zc=9)zJbEsERUS|NDS*wm8MRTMXWW4Zf1!~taZkO!I+Xz$=r9co06COJ|@ z`$Jf(84Pp2VaKOuqHvvI6&;31*{)FsQxLBevg4~W*JPfbS(mp82yU%;m3eiZiM&`j z^NP(iE;FsdFIPg_OehEyfMB`CGA}EAqLEqbkZMLPUf6LpBAJRBm{A_!WtZa3-d?Tq zrmUU9%HpZOx;zD*n9>Gp7sKt%&b$mxlpNQv)1uAHb?V4q1N@vbZmCDsAqnV+1enXd@Wn^KpTW9G&-6djVGnePt`N;6Xp z&4N-iQ1QJud)}0AiG^e^Tr**^#j#YJ#hH-jB|<~mLBa{?XsPC}$Rv04W}V36(qfEO z8G5xW6XU}A$fxDHD;oP;-BFz^_lJ=9p+Q`cX?he^l3ZIMiJd3Jzy>LS_#>jKC+PAfv}BvTYO*QIhZQEak`^_lW@0jbpG zl~1uCKe#wRzQ??=tO(a?7?qPvwvnZ)7-giI^2|t0Fe2zoWJGXHR1Ijj^P37yOzL0~ z)rN%(=1RG-DUU(`as_PN=29a(xhX6#NP^CZ0EK0x-mA6v38iO1WGh9T?QIbDDe{wj z9n>fS5*ekY9P^xb9;VW?cw1qPISKQ3o1R@TE1FlxOmBgT!l<-{S*El|8%?9_sN2}# z_rMo-9Mwscdcv@uyF#NVeNwW!+XsV*^QI`^h0+Tx1h|fpijz9oF6PvsrrzUAE|gE^ zu1uwSlGL|Y&3s)zF1548Yp3+bsYi^PuoAiA3`PPUC_MUxv1~Y2R)&B0e9ExiEt7@# z(WNJ#^n@m})oE%Ck#JgfnpnK_C*~mH7&cJtdZ5-fg;ASYeN?`k2#7+n*4z$6bGu<0 zX|P9GTFAwg3XTI}PL|n*Y_w&40859lYMAQ1aaq>VQ+}MJ%ruscYp}!t=0|rY9c0r{ zH9@u=hHrDyOU*W?ba~n!%&<|T4FCS$(^Q~fego(2-w8+=qP%F zVF-EyqX5~`n}oST^`iXXYFT z{G8Y9vjl+JM7QLZHcCp9qd?%``bmKKW81t?VRAa_;td|_R}0Jr@9YO{{Cw(4q|>VL z_>3+6PwPhfdK>(qcH$>S2*v||tT4}QPbE;0B7;IV zOCgHM^X5-Y5e~^PVh>8rdULn)J@Xlisq>8atZApeead;({H-^}py1(c4>LuU=4poH(DN<}q;HIc7rccR2T$ukq{m=5dUyb2DiB z>ck@vO9%l`s<}`rx0oL%fsb>HS}_DKGW9R!%lvxT{5@wA#gQLfGz*&K7W0=FA?KGs zw+0sj{~8NZ*%ze*upPX9@0}2#wYgYWAZ`ayRutp3a&Uau>KuUH(Q`ooyL}*Vh`UN~ zWgXmusWo)ilgj!aBkrkyM*`R?sTTwyFz7o%R-r3y5Cug2aL&OyldznXqZYCx#_Pxq z&XzHnCrzj=88+Up<*=cPUQ`J1C6VZo{nD_WSQ((~W!Ndmfgy4&~9RMGXnz!mH z!Hc<6y(_}?cQS0)>Y`B0K=O-+;%cGh{Fg%nDh+{@JdWd~vt5doRv1L+1%VwCI zsNK%-$m#l)gV^#FAh80Li?dTuJvxFCH0|9`(N`m;mLdlu>`cn^XVPrlzl}iA6T+2+ z8!L2!z(g=m42e`e98dW5}ZLb7*|$=k~9|I>q_5{T3Gj?-OGIoGgN%`#kZVw_ixXf5Cnu1;0}8 zg#mZi5T85jyO_A!egr9@sx`M*N?4afqS3H>q@dWa%OTe{;+6&E8p8Z}WK7j_33%TS zycpJ(Sbl8KI6%W`@PLk~3ce*M&th$M?zA4VR2`;blVIQxQ%I|TvuYKHt=bSDHgZRe zg8U`(O`{<1l(VM~d42uJ>pw|SC(S!dBvcn1jN&x zMqQW-(ty};B(x+h)_ON~tH5L+rh)@luDD`OQY($bCs-qkxn7a;YP~Wf?rJz0FZh`7 zjHeUMj}{^s!Hlq!g(Ujy%>OGTMLwK&sPpX1P@Nf&!i=*Nhwe%tlty7ES!br@vxk@h z7KG2U^=O(@Hj#HW<;b$UoEURrt05k%EA7#%i3MgmB5b;FIc81yMu_xA?5FWnGnWq!DS6WAQ~gI4OhbU`a@rE{bfRcIo*HgPUy;@tU&&4)@ST(yJW z+|o1?V+S#siLnE^+^^K9i+=Ot&!gBRq+sKd15N>E#`F?AO6J?cV8eVdo=aoH#t0|q z(p8|mYNJjX>=Wm`?pHoZ)sk{%AEWHtWTjHjZZ+2hUofO zl)9gZe}^TR-kKUBJAO&OT{F<^88btKotbm=poVbpq71?D+72Am_7Kjy&X2X2#7`Yg;^=UMAHvHH~y5KcMISuYU$f^{ssZl{v-Cn9+;AF68p z3dB}`-cFyM#}%Qs)2HW&K|oNqEf>={cRsWVXf-=4?y(TPM>oQACD1RUJ~3{T9GaI- z>@#fdXRy|V`SpN>D<-YZgVxW(U@08yld>{RE1`YWCpIQf#~#EQ>s)G&;p-S|Sw_U> z@DShzf)i-A4XjmZ>ME7(`7xBXi=7ctSVo;)+z6DE{VrRmx7UztK27;aDlVPw=RYf%INf`7=;wqSn*j(%t+I)K6 z@C&^*pPo1T!AO!~Yz`g{Zuz0D+fn=WJ&5f=$6K9i%p>83I7hgRY{kgj69%hh88Kx| zu7c=n*o#N^rP{jjXO|eVVV|dy1)h7w`AuVYo0BOxUMGO#&1~KE{|X%u&U6q9ks+8A&J3+x zXJ<;$$U{>SzqSbW?hrX=_g+-Lw+jvF>JG!ZhX5ZM1$=ZY3?IYnjZ~nLVLy8_$~JEg z7sG67b@sG_Tzj~y&fb2&`!5Il@}V&P5S+N7YV<}?B()xc*0d9ki#VcvgQCO4TL)oB znY3~|RMZztnFjB+n1t$LX(s8wz`Qw5*UfSBW|22fa&9(nC-`=3uh?o2e1~}pJUh-U z*6pJ3J@D<;BLqKUJ(dD~%zB#Or>$pFz|UBJA^0!Wwe0S-wraK~pPW=|A-YQAHl`e( z>%+XOd{gM@#gtun$B$PW^;JS6Z-+)cn$n}A<_!ejU>;8aA2*M&jmNATQks5)g>`Vd zzYco+f53X2;K!|RrC@){dX3=Mtlv?Pe`l#?2OS-+)%rL=BtI9!pS#2!%{=8SS&8`S zT0C~{6~JNmj@qE1udyU~#JW{Q&R}mXkVmcGN@ToB&Vp%Q9_%k?sVreKXSX4_Z4mN1 zIE>iHRd^i6deMaS;tj43ZP_=@S^>9PA7`uYu$wIl-gf6_3vA+`q(eONLHGY|^D8xTk=%#So?D*v#K%VbU)(iq4*fGEo$ zdJP}``Ule7+v|S^?iyv+d`B|*KeEOn=04vaNuZ73j8g z<)}aS@xJ-PUVi4PFL{d!qq#bLNPm0nW%A=-ns=Nlzu&-s;Yie(l&h}9!7O&tGMwoN zXYNAv!)!wElMi{vCIrWcWf^V)l%!zXaMen=%2~fTHBPP&C$`dX?~{0%)7q)-E-5-r ze3Fw3%04wz9moDr{q|GnOJlOoHVUb<1o0ar-UGk<)0W}#j09eI=>akjH=J0SlLf-Z zB`N*WRh{%8epRYz7HlXdp6e788SYZS>2VGnHF3FFsNZOc?;8!1ycL^i0FBx zdTD@TtamnEDXJKX_c{w|_Ou11`iKP;`jQ2O`6k-C+iL>&c!$IXohxr)1^1b-?Y{`Z zyeS3`j57&+h)Z1BSKp(Y8EN9u;Hz&T@Uc!4~f&~s8KuHXj*@|q%~sH%(%$xzR?RQ6l}J){zR*ADKv z$@7?P#EYSgjC#yv%luP38(K-6K;VLj|E^Ki*SoiGY+qm56}_GNx<-b}{C^l;TGrd& z(Kp)J^^PcIrKSAq7#Qj@%6bO&ca^pGjh2;m4D@&R?klSrK+(40uA#DheFJ;j`&vc@ zhT8Xal@0gq+dD8aTsk;3FpMgON80=P%9vO(GBD8B(bL}Bzof6XfAm0E`_TR+{R917 zOS;&F+yDP(jl&0r|3B#;SYNiUqa)JKW#^WjTe{5auJPX*1`fym-rwU2Zu zavIjr*FHQP%7N~e_OxFCG-!UE2w~utO#re}z<~WD7z2Zy16TBiuyD@}8SO(u?FWGd zGteW1->n0HtILwz)s6&=JS6%C_WALSfxdwuKh?V*+CPc^aqbrs$qm&uQIYHK-47Ji z;gPNbY@kZ)?d|OK6T(+N)iu^7JyA{6Rdsb>31S0692n~AAVFA+UROjeQbAJQ2a)N* zU_dZ}D7SBDU~~|v97%~#BLyoFdBFDZe1YgO6ero8P=|3hP?bpH2fBVKUut}a7IdWZ zrG(ey$$t5fp{_t8hDU~a`#B7-mqCAj7x}5;q)iF-Nw*JmwU65(kE5!`(x#4~fxbRf z5@*VWi!7KHPq?P*=JDg^$4u8;XPK}uLiy>E?@mJIgoNwHN?iQIy0h^#lK4 zyiO|IzXw(S@o%nx5l6{6_%~K%TXxkWIoov?rDC5}*!jW^b2_>*$4!qFm+9^jIi zXiCf;TkEFVndUloS`1w_^Ajo6-jqhRl3nfuv~7tyq1ZKNxf9CJ!;(B9kFLh1x|8e! z?9NhQB&u?!poVlXb|x9>#%3oWl{1mAVV$8^c?YI>B(;1H+5k>C*Osr3qo<_T&U!wWoTJH@Q;8#a-%7oe7%t zWnL>}0)hnC>rF-|NGqPgXk7YJWAcB-JE%lcvC7VPHx|x9TLS)-xKvY6sY}?~QpK?@!+ z=dq=fRa^~nT{{m_LpXu*fe_>@cBhoNdFuf@f`w@5R<{6c&WqW}&5$ihI?`Iqk&!Qh zH=U9It;!{tGCYsn^aCzW9x%K=N#6Q)JT zsjrIz*?SU2yos?`6;Fp&gR1LB0}DjhS0?aAGSr>G3k*>K#l1v2=O)VC0$Y~lbMo8- z7p|E^l({{A9lq%1V{#X`iG^Hg6VpL*wwmsuNJ`w?S?(H=g2q(+HdR{Y1_#21N~8@k zMYRkQEw-7_ZXe?U84x$N4s%IJspn3_J%!+A+rtT2)v~b?b9Ku>gHic-X zoD1%3*36x7fjdjOBK_uCi@7R>7%4_n^sfVwG&aqJ?xZ=K_#~P~z%n;)k)){J?Uc^r z07g2G=5Tg#@k(7+{um&X2*SRzRbaG1M`<;XqcjaM`%(?#8{ake7M+U*iCJB2O-N}l z?q{k7k4yXBcg=mk&&`vjLHA&|?Q|+GD4z*-x=dbKa^2VpHy*P`O*hldRBM_Nb6fO; zy%z5p#B7+0*-ndxq2(}U50{EcK+!5n@hms97#?m;xP(99BnSVSgR?;jWuQ5T zZ4k&bS!o`hS41IsZcPN=B?|+6xG|QbZE#NOvvosG{>WjLDzINQX#tc0IK%$%VU$*zq^vTv*olEAn<*2h<`PzTK|s08or`8>E_3J3 z;FzLP8V%Wq#n#5|$2`d++wF;1fzFAUC2rA7qPYuzRGx5)WQ}ExTcpG(HAB%Vi)}@r z3pC|*A}iU&?u<382crx9n{DQ;+nx81vR1gW*10*#s>Lp%#GUW$AGna{t%Se7;OLZS z#jy_bRw7LWiW#LyP_47YEbGR4A+)=IWC7J=YiE=UCdmTU>;QS zC3&%u(#5f|efwnWetgj5G1x!F{#2~n&E}|1wSRojmldo9pF)MQfXxJ%Vl-&VEQw&p z7qbh&bL1nV*K$(C_8FPCZrrY9HP~^A;jjwgo{xX{=+3g&CEWN-cM&IwT|*UW!9U2TPSe#DP3h zbq8~Lwx)-5G7pLamg_RhP3gr;TKmX4bCyz&Zwn@UH#5p4WQi$F^$iR)~oB>r$Eo2`o+ z(|g4~`9*+VV!zKWmA3rp$^qJkK22^o&_veF7-bV=bCi2RZ--)# zP{2(L8ulvdMF&mTj5^oJ;!ZyTO=baLb4ApYzOPUwaH)GPsiTFek|pX(r5LAjEfAIE z?sl_hyE7I5Py+T%cHJ5HS{5sJ%{gxNDz)i|+53c{H2cggk-7aMhS8T>*PZQ}*w@dF zmE|jwuFRdn{bBJ^h&8ORC8<7*FM*S89`>17cCma+N3~dIuvX5cLuh)S?YNzkjr0b0 z(hRpyGGGFDijae@cbZBRbdOPGzI}=o5L6CV9<;>sx2Y*aj~tlDVZ~nGomK44o`n?j z3sPh}2c0y5M3qOqRH&R?1XA&pqVIq7Q68^tX3bXC6sg8jUkTMWgzK&eguDIVZ zG>@H`K>&q`o!Eqg6~_y8*avx#{G%cAw4K?1Gd2Yq?}MyKX8$;gGDfkxU`h%Wo(@+a4^Pl zV)lX3UHkSS?_89sXA9UV`z2^H?oVJWPdp#F_DyE#u86GuyOvdOjFp(v-K;qY{0mSS zU6|$KX2DUrau9!=p2~bI9h2Cz*<`XPxM1{^dEiUPT1tqw@NU6KPj(lbj}~J)%K_rf zi89Q!m}Wh`W8g(L_SDcI`1XndteZq1We(%;!zoZUCaxKq59M=!vbS7pfOMDwN@`8i znSMT)kh%$YTK4eXJcAQut_+q)Dp+*@{i16EYL;-(HjHe^k8S?(X2|4E3>hQ4u9Q8Y zxq139&CTaUifJhn+n)%Q5)_4igV`9Df5Kj!BH_!Uoh%jmj8hJFn&ROqV2C}=)vcC>#gNlHcI@=x+W23c{fYqqN-nbSPlGcl09q_FMdEhSEM$L~JazTL@z{dU=XCQE|p#1-hIh| z!FHp5d$MMGO+#yPdqsU)O|q)CqG3}_wb7Hrf%m}Z2#-#9K9=0qcW|%=(V_kAIJPtJ z@6)=5#=1ILzNK|neND2yVpn5ZEAhPpAD|(3OUl>Ss8ylOqRR`ws&+9siMAaQ$rHfCtDkvl3VMl zjij`r{fgvB`|xF|A(f5I)iuq@mb&ViWJ6;^je%(=o(xuS41}oJ42A zFTY`^IoZ?R-`UqSG|V!Uxc9+Y)M#w1Z)>Sd?x?71O>V4fsB5WZJzYHCOZN2+a|Cc@ zWTY!OFw`3@)Y4kf+)7{*zLQmLEv=1PL8Q4w1_#Gt9ql8=D2}j)goz_Py&aeJcMT5* zbhcJBZ>gzHR@czFEwNkYjkm{O^6>WF{ zmftG?8qpxgmtV4SQ*vtsilUWGtVqrgaZ;?#h7CwZvNz~E;e+i%?fVIm6IpO#V6X%C zCjgL9#Ha?;n<}a)R&84w2ve=1h}73?Y&AOCAwRt%2Muo+f^x0R6%8$v#AI!a^ohrX zJho*uJO*S#aK1j$Lx3;v!+`Py&Ps3$%EPjiXd!Uqv@%HqX(dOm7t~~uq0?hw!aZHR z`+B65Pnq?RvLeHV^y3tj4Oa5fQq^2j(~xXysBc7%$Tne_(T$0?x4q*sqkE{m1Cs~$5r&Q7 z(Y=EQSUl*dOzqa@I;g?=aqHYsSKV4`3=Va5cMT17b;?0iRMv;A{ zj0LD6hE-KSRSU<2?bS6^P`NGW@0Oa@T2R|mYv5km$iRMYq!~Kp&PSUvH=?-&*fyk*xDDY=jno@89yL?fUAEr?LdN;Xj_toPMus*5Y&)X+iIV!y8&>uYu< zQMduK6S7yeg^dQ&TWgZlbuDBdB_GFX9h zKe5EZzJproQZ=?ibBo#LQ*Ex<*qr2AB-5*pWH=|yUimJM+ z5BJHSaC>03z=nqD($UvDD3cp{1NWlEvNndh`XFlULnDSVaCi&Qz%}N+&Lj;uZ?#j` z_(Ep*NN*nuXJs+z?ZPkzQ3RS-+1Ny1(lEtnR&`;q~9}T z?&l^4_t@D+UzJwX)>Lf~Z3AfPgckLh3K9uS1&Pq5f>yy+9!7OTm(lXUxCgV9vP&5c z&v32Hy-g)L(~T9Bof7tUg2l9HkRBX>j4GX>m?&!q6ebjSQ+-8M$P{Z9sZO@kG_-Ku z)wPD~DJiwFzHtXRp;jEdN~Ca-b6M>>WvvK}WK(0E7(8ea6(_`_W3-POEu|x+*-DyG z0gcw=rutn?wf?S^%QdTFVeW2e%c{0;kDRias}{kEq6pLKQJnC0p&;VVvfg1d7nX;z zI=lKi&>ops(#wFdmb%J{7Ou3gHd{FtaN{>A`xLc?%XCQ@)`kkvUm&JtQ8Nr~kf_Gw zY#&nFFZL%`Dh8oF`?|WZ2?c4{qG2CD)VmM1&BAh9*-}ZNn zB42W4dBjlGXUAScrbJ48-j>mThSyFRFlCHg_SG`?0u{1Ah9(c}o*kr=I&>pL?ft`a z<0OX$xCd3P7hh>$9|;ATtbyg!T35wN6r0o(ftsvo4fr22V+o9yr6TMBaUyv?xVh#V^&v8dAo7r!wbOk&aR;V4+{9+6~Ii1O=s0 zVw`zWp-0}||5Mwv*5RMlYiE%50pL1u$Ns^y>W17Im;K7 zDrmM3VELoeu}P32&xaJuEWb<(re&4Zud11{2du83r$~0Cpsq4JvuXSd1LjT0$%SP@ zONm-}#aM*U1Sla3Q*8;c;p7U-mWd3)YN9y=3yLiy*cT{KzsdSWYyy?(FrfPS&$v1ZXf}+vWKyQj3?LO>q@Ln#q_7 z$;!4m*az6t&>9z0C3X8V>}}CmPW4BogZQ>8Yv3G%x`WFS|3MV`9+tlJP%r=V!*aa4 z`a4B~DyNd(ABd8T+E-dSz%1p4^$bWZ1+v?(=W-m{y97YJS~6cO1gLp1T1`cm5D-E9 zuuRVvW%?>paR5J38yfAv@7Kh3g0k!EGWJ4pJCpkv4UZP~$uzW40EP`YB4X20Es%VhO=F6d0Y%oPI zh?KiTurCVKu&YGYP+kSMB9 z3z`E*t@di5UBuZxfDJqNLexMq72kpL-BwULhTDdP%Wo= zR8Vh<_}8z3(D`O4>G|tQRbvCRRLDOfd`>A1Ws9w0h0GV-9p#D~&kDEFjY-@O(j)~ywwe|F^qpGJPZzvLe_mP zL#>DYN7M$LO3H1ow}LVue9us@x%Lb>(nw)aTf>%y#vS5=_HDBrH5J+~!byv>3mHG9 z$Mss{X+g?^-m3Wz0162Pyx1gjw#cT zy`{Prb0B4!$|4|VGH0z#utGy;S+eNxc_w*<5OAXv2z=K>TrwYL{B3r3el z8~kmZz1`gg{yo>(4m2&|TN}5+bKAC68&%wC3-2jwo(LNK?fYfqLiSYyPv4|7YB+g- z;_rABkHk;XT(hl>dJankPrP(TWPrr8$Q?r9NcL)kN3abmktme?aL5mI7_g-G)7z>v zx!%+V=0Ds3+%PEVm(3JU?X;DC_Wnz|LV+{VF1sXppwYO1ftPiOlAtz?x(9v7Ov>D? zD=#l6?^1x`5~I)1XR0i)*pI?e1Wa*?Ms$FoCX}}g0E4tr!OT=nUr{UF@YKorPb+~8 z0=0-?UD>!ZskRmYaTt8G^#;0!p%nR)UUI@xdx6H;ylUAVnja~>^Wk^?0~**CHNp3azfNJRKc;>jJd0i8x-w^wymjlXbTC- zR!KOfu#^s`0^X?>GVz?rN%1}-FWwK z+QwaksP0=}3@Yb7Ei3ZO9~CMrU9oRyDLq}~AAF@Ss-hl~UMzWiNK1~k!wgO#D-%a_ z4!1M(&dd5FMuczH`)Y}nG|g^!);b3E@5hdu9#8f?uxK~p*kbrHI4HnrejPNZGr|T! zV21eH>J(Y!45eo*xxKEXj)o)ZS2sJrgK&>L_z2uh+PUMmMV%M&%(0o~3gN!7h(nJ$ zZ|UF?9~v@$!i1--2pR||u@KLl?3R3YUkc-SZihXl0aqAY7&tH)*5?Fb=P0_B@PYIV z^zTbh=imh#-i9R!#|nC-#EN!2xb1nHwO@}tQG%szUg%2~KD4d@Zu(Z-J>mTq5>w6! z8lj;%r6u1#8&E=_6})%L0G0b>(eB{bK0HgdR_yey9st?rpKKC5pRTG+JDI54#A=dz zI?68$!xnY#$Gb!fG1bK3j<$Q2h1%~AlBamTMMqZ;d=c2yD;J3{jGj+vE=`+S*c5EK zs#jza2lF@{<_v>}b`*QjBoBU#ksd7SsHUfDD3~4M5)=zTFUm04KpgeZ;u{_0*^G8@ zu@+xP;ARqzuBec>J~3=u`O~= zlG@{nw${d=EhxpF%J_qMfn}#$QgX6_@@g`B-X~>;d5aj%`P3Bvxwau5L^bGVd(o5> zM$X?;CSD8bsDP{7JA?IY-TGE>GK6l=`NyIunyq2`vgID{Rc~nWhQ)waM)Wk1`QuyI zuwRsYO#Q89yKD$IHMAwFmhVicx9B96FI`@~bmg-0#FG6TgQM$kasWYF(tbYD-AMO$ z4fHSR9$dDP>Ar#XktH}^S_jvECjcWoqx<*byM3smXC2-}GwDF!IaHs}e_^@-& zTLM(ZE}SEZzl2A0)W%wLd>5tC=!&M+0;~sUYGF{fMVJ;F5ITvy5gw^Rve%K@aZPpG z8&jGR&DzEOP#sm`8i-mZ!oycly*&w^nddT-p;0!5_!)G|1EE*PN_<@svb+lm!6Gu$ zC2lj>CjtSlVZl~$3{nM~GNh6Z8e%x1A%X5uE_&rP^4i=0zc%B(w29Z^+|(iRHvFkb zE%bq)2WTy>xfv0I^g8uY}586PZ4v}@^E(Hx@fD81f0(vK;m zPT9OeHS{2)4Y6#JpXxp@Pcx7mnQUU(X(NHIIb8{u-Ze79<7)5Ttr7|4d?(_6E4y!Hlea2nLA->Ts)*kfTC@?4~7v8p-X$1c6s z8K*N`D_Ef-6}niPdJRnb=R(^sh%NO14h7X!Xun#|S*Mf;z#RL?Ef4RmkrqRo1q-8L zjc6H@TNz@!sEflA)owYpn8@VyE0t?NaL8gQ)8j$oQ}05671%#|wbCN*Id>IJT~tpL zwQZs)EUQ##iep?-mOdqz+W#5SRw(K#Nw&u~f&6x3(3+qDn;X;xA(R%$-`-v0>sn3c)Ikw0>OrfD9*%K)WoNtx} z4kCR#Gs>L{$SF~-YuFC`RZVNM0yc=qSLzjYxE{p_PFaAI$DY_q`_UW8qe(3q5oIeo zLw~~iN=_SmJL+0%dDE9C&D?m&BgNi?Ck57JiuijXTTfr69(K(lLHK9p6%I_wUf6Qa3fhWIO^+^PN_9E zL4HTk!<(gkd-RoNUyaI6oEH__`$u|VfwYGVer+`Q8dFQXy3gt}$nji&4o-W_K>d8o@PLVIQS1w15Hvu zyu}RB;M@}vQYj()kOZ6w8Y-j&wJ5qhBHGJ-xGISV8{y0HC8yUoAH z5$=XqmBE3Z5+GdjZVD}@N3a3kG~w!=W{(&9Lio3 zlMcO6qAY8%*nP_6)%aK7zFudq+_BYl%A)2QSiCT%mSkj$R7Lc@qAr#Ils~x_w2l`r z0y|Dv(h?k#akn1oCsZ(u`mp(+cu39SyLM9tN6a)1j`UI%9d##JrhQdga|;gD#i-E- zLfFxy+@{jX689+JF~a>^+;#FcJ#^58J5yVS-kj4n$Z1LpEco&=*kF*THh(Fq31mDy#=a&DXh_^ zu-7XQV9z-&$JH_ba**d4X(^r*J?ZpqqqA3s3b`#a4qUX$IPh|g%{cJTnLk%uzgeCw zqg$oADE?g-Kvi4xea_*_a79>dqv;bPYDb8u5_zSzp ze;kI%0+fPWSH5&9TdD*=sUkWPjlrISJeE?omV>@*n z`xA8jw0bX*RxY6CuD)f7`IV!%YMtQwq~RA@UcO*K)IWq5S;|}P-^K^;1GqAtmF>Uv zo_TnKXi6II88zlJLx1>Y{EB$d5$ApOQR_ytDkU-|Ej- zyL+D}5vhph2Xrdq^R2BJ@%+lC|ITLx2#5K`H_unZvs7=<;DL;IR^`)*Z#D6(6y9_K zH_RLUcN6c!H}Y4;mqvMGoz93SDxdz&Q%?phNQC>&|2Uw>Vpj$SqcSsvH;a+4`@U_w ze2!OD9RCNYHUovLGb{0=Y#R9Z z8Q)+va_BQJjS7HOABBWvo&V_pAi$qRQBO19a$P8~-+5 z@xNYD`9IgV9oeK`i(vWx3r3Z(Q&unbXF-Ji0)?obwy`Kef05t^qqr!7pDHc3Q5vCN z8o^&0p&wq6**;29@Ue|^BlOMq2({xd$-O5;8qr=4IL5BWKa*v6_z z`us@!=ST9_MCw~3_y>HfHO7~8oRVT1U-oktv5j?+^!iAB>m&IaBI$}q{T0UJz@R*E z9kh%Jp|=xp^{Mb8@@*Sck#u#W{_05n#z=Zor2b7({t`AoKAVi^bc{3CG#=C`^<^7% zk@V(B{hK5C^^y9*t1J205W#PZ(4)2rKDMzfLT_7;iI{Du|GMn~ZKE|puhq+vZ`;@& zp|?GfAB+SuY-3l1-mVD#g%NreM)EI?r1wPV?TO@H5}|iVB!6!t-4UVJ5y|h0(Cdoi zcSq9uBJ}n}@_QrndL#LlM$(r>=yA0OKDMzxNFZh#{So^8Ql4wC`t*Ad`L>P0Nc!?f zeV0e_ha>cdBl#nd^k{_MXe9rN2)!#J`GKZkhHV^-&^s8xe@`TRWrY5fQohf}y3+WS zj?cii>1#6uw2i|)CL^|Sb)^2QBl*`x>bur>6&O?(wDT?F+6ex8Bk3a%`bQ%9M#_k@=5fRqocHkE$Br=rS}$Lgcj}sU*$s;e*>#5 z%Fplmn2gxQcOvQU8*BZsz<=^YZc8NH8A*>t(#Ip|(~DQobva9*Cq5M$+#^n)JC+!oC(r-l4mV=7)hyBfpq~{~e_N+$8g}1Cyrx#0ln{lB|&ynH*4nsA63zX{X4tKX45MWNPtZUkOCoelopB+1r@=9V4>Gg1O#k=4HX**R!~ta z*Z_N1#NOdmc~N;^QB<%YD!yXnd!Cu+Zk7eb@ArN8mz)1RGiT1sIWu=|*}Hc`RvzXp zkj#6PIo@#ZZpi@TG2XNL$P>JGC9^F#I3N6apZpnK0&eNBJ+Az0uSoJ7tACEy1G2x+ z#?Uxd;^YtF_p6|;2HJPOU0NrX zCAn?>XMS~@JSt8;BTl|3PQE%$UJ)nXA1A*PCvSnwc(=fsgY%c2aruETGPJP0d2w<{ zoZKx=J~~c5El!>pCtn&TFOQQ~LuPwNW1(_0^x|F1at%Q*S>IJsW3oCD}zi#WMQ zoP1)O>^=;3pXuTOGW&tLlj0w^Et%<+jE;Fz-~pfLk1rql3{y-Vo>KEa(~f_NEc&Qg z{PR8jn^7y<hcrnURmj<#64mVqpOE3_3p!7PqboFPkCTVU+8sdeA^GUqC+^wfPKV; z?>?;?J?LkC(=n!idwyxZ#<62#p9r$wOh+;Q%d*(C5C8Bbu-Hc9__A9+^)DX@iUuS0 z%PJ_fPxGUXw#H}J_p-(-yRWIotNJ!#9wmuY;n<<)v5|-yP--eQV>%?-P^SBp>}SOl z&`S^E>-9@9Xe{X-QKY^7Ux-4Gk`#h3%;Qi6n$!FM6V*gkD*lcF)6CDMCkGJEoVf(|Ne3MVSntNnx|78EoPj&CQ zi!T{J9PFFBpyW?X(I>o^5c6D%RQ7%GhZ1AHPl6OT5BWQ4-2TMmecmy(?>FmYkg<+x z#lDKte-kV8Vv`T_hRSH$qR){j#r7}05Xb1zNmgd3gQyVw!V_B?&H9_St;Jg2r&HWZ z@sz#KW9>+*8>bv$EEoR`7bn{hTK59Qs2@(_YF`c`QHGA*8X1$-N%@F zqF2^j>+F}kkP;oF{>$E^75!?*0guY|t3-8f;t?tLZfr(+|F40AKSt94=2&it4aKfAMbLdBp6&>gZQmqF6GTE ztUZ3}$nw3#0VK*FN5bBG62H8{YvzNsW?m3l|G-Kl)NS9tmr{>2c8t1Nc=}oYilI5NONy#=Y4v5K>b6JoPv7hfPrey zJ4c)^vOR%n&)$U(eBycIAxG`@gTMuLZU11r@E$=*p7E;5dd7a{or1U>O&M{czX5#2 zcd|H~tgkq7aBzV=JDw3QYd2rx6s7nvTrZZSvRBu$@|L6

kT+rE{zN(m46bI+^9zUn5C$LM<4;M;_D2YQ&NJ82_-8 zFLh*nVQi+98W*QB;OvgN9>uG7Med=A#blf0cO;#9h3)#we zyGYD4m_qG5g|4vW(S=s89|=8<1L{pDTO03YveJ0>kZtg3Iay`A^(5+hk8F#7Sjv}K z*tq9mlX2)qwl{YEi^lWTIz4Wc-xVj{7bibZC)+r6QJk>9NigYVt7510?J% zCsBTt<}HHkR^7Eo^^4{({_v^3ggD9;3JqGBky7A2NSDWjM|KBc-kT%qZmu<8dD5 z{B$*mb}T3H!2pK_%RNb=o);x=AYo@S2|HU!l;1%@KZ9{VdpY%{VE@9VJq`~cD=^QC zoaa)S@5eei-EZ9RNA6+(zmHi}LlTj0^T>8_(mBiKYBC3(rHRCQ!ylA|%^y zeg<5K>PW3(M;Ulx*5&~N!9 zoVWdOqUMi1o;%Lqyuco3V4wC<&|h;%wDTMi^{*gLGVb{NzUMs*IRHK`J}s^j*+0yG zReV!qe=+?%akIEZ+$w%1vLC7cjkrrhsBQYMAmeA}GZ4FqmoilQ6XcUA55u?uc^?0m4 zvcGAEE4F)>xr;ClmmSP97mw2?u&&pVCym*FqzIc^*lek)ZNPJFwQG8$gRQyi- zT};L`CF`p%HWS;5J;edySaF7Uo_K|LwRp3*Qd}cGEUpvZ5_$*iAe^94+#*E9##mE)bW9 z{H%)k{EUixQhY^xU;ISmXH(SsO$=iqq+Cxd7LO5^iVup9i_eNLim!_s#7*KB@l$b! zxKrFM{wjLOu00_!P0SJV#U^5jST0tHoyCFT3F67(NO8P4MVu*~C7vfr5E5y6RXT=xA*ToIu zCUJ}SsklSjDgGoT<3xh(EEhYAeZ^zNQ^iT*9PuJ?h4_%z64yes+gj`(9wiPIPZCcP z$B4D!MdD@RV(~ihX7Mrc8Sw@2HSryBlek;_Rpdh_Y;QQl#e2lZ#0}ym zaf|q=xI^42?iPO)c|l;~DyE4!V!qf!ED_7aDzTH;P3$f96OR^;6Nie!#j#?oI9;40 z&J`~d7mAC-YsKZ_ZQ?3%wfM03q_|FeS$tFcm$+H{ulSkxmAFg%pZL2N$aZlJiy2~` z*hq|sEyPx0JF$z{L+mRaDGn4*5Kk6IisQv8;!N=@alW`fyj;9myk5Lnyj{FUTq`~* zJ}s^nUlrdL-xEI+w~Akg--thmd&ED*1Y96i^&k?T?mx;HEcZv6l4~b8R&xtRIZ-^Vke~bSSw~1eh--$nozljFd zw2WJlm@eju4aKHnbFo5fD|QyUi+#i+#AC$c#bM$Iahy0=oFSem&J!;ZFB2Dw*NHcY zE5*CTHR2=UQ{waDE8<(?yW$7p$KvPW*W&l$&*C3q5EuB2YqFRr))NcFBC(}dDRvPD zh$o5T#987}@kVilc&B*3xIx?`ZV^8fcZfU1-Quqzz6R-z2V$C-Bj$@u#UsVj#kt~T z;tk@1;&bAg;s@dv;*TP4crdQ%Vk5Do*g@zEMg?PXCr1*;Xp7@El zQ~XU#Zs6KiEVdE5iARVhh@-@5;<@5N@jCH#@d5D-akKcj_=9NjT|2VGredYoOB^Jg zCY~uS5SNH6#QVi3#aG1l#81TE#1!27Vt+LhJBq!Wn z#ChTZ@d|ONc$0XixJGXK5+{iB#TDXH;=jco z#4zqH(_S<25b+psmUy|iQhY-EQ2b3yk2rg+#iPaH;@RS2ah3R__@=l+Oek{pnv0#q zA>v%|2JtoVW05z&>0gdmD)tdi6K9E6h_{Q6ikrl5#q?&1n^+~*h$oBF#Y@Fo#Cye; z#s7#uipeF;eu>zI#I^nry`eNHJ6} z5tn)-{Aef^i!H%}+3_esQStN5+> ziB}VFBHpg_HIg3^A6NRT;=4-!x41>=+a-T3?ov7*h+zA& z!~zn2HWf=q#Gx$-yOUt@cE#4lX$DRhJ?Mh#81V93YVTQ7KuGc)O#3- zHXkSXH1aFY8zqic`V7gl#RcL*@hTGbZj^kpxKin>B|j)Wru6laUl!j``X>AC>;6m}jrS}vElZeX@@*8}PMj|e?;u+$Z;#~3@ zJO@Og+#2y=rN2m`{Hx+d@qO__@*6xiL85$8YsUhyjo4QlD_%%4?&6)|gW|K|>*6Ny zQ}H|T4>4E?d&}@$L=x?7Dz*{Zi(SZ_c!!we!^HtgKT+~9ak$baNuDasRQf#07l@ZA zeTn4j#N|rAPkc=2Pl+3qzD4p@@pGmBBqn06Wc%xphU&3gPx)VnKayx?QkAopMxwoiB+5m^GO@MTj)Yz{ ziFTYO&J?c|pAtV5w~2eig0`-FgoM2+67_ZvyNkWV8WMWPk*N0!@hqh;BvJlK@j7vt zxPnCa)g;QlExxPtZ6wNX7k7!f#a~F2Pip7Nw-j5ENbg3Xe6@%lowf2&;vf=w!%5VC zuDDpdLwr))BK|IBw|C{*iYJJZ#2ZQU=L&K?<_XD9l4#en;+x_IajW>5_$3KDyCv@t z|4@3kgR_?=W|Pn_lpGP8E4@lGemKvzqdSTA^(GOIK}tVC9H#WqlE;gui)V;)#q-6> z#H++RNYwMFV-`T?}+|`VGXkVsEj(c$zpvyjWZ&J|%7xH;G@7=!c!+&*E=l zLMN9W7PG~AViU1gtRUfEwK!CqBF+;p5toY(h>wzp|H~xW^}6_u(l<-qB7QD@DgGe- zPuwd8J3D)6VwPAWHWw>N)ZdeYAE$})#9PE?#m(YRVsaN(uCdrrJVHE094k&0=aaY} zaJl4b#M_kqD2eg>y!eHYF`oC4rb&^Hz${nuX$b%67lRU9V6Hr^GkJcf|Kd*!@`YHgN|D|MyA`_Hh2^ zi1oz+5_%ji`R;`h^xd0#3#iU#D9xh#V^Gl#NWh(UamdqVv$%b_7RUFFX%@9I5=tl1~?BEB$=(QqNni^cCVA%3mw_Vev_&e;|G#eovl@ z=K&9M^=FECB-+7z;RdUi^N;RmEtNA z^*#`h(Z|FrnL^52xaL4057TP1%ceo4a4A7Z`3UHt{* zX`a`SgkOh>Vzis{GNC&k~o4tHh_pk4VI4x9IhEatiqg>X+PAtR{P5o+Q7*JSmP;ey!wb z;u%VxM}CU$sY<>=`HRJS#MRb!nH{$=q-%03a4RCBIwif%4urr8+ zos%Vx6{m@_NZ45@-Yh;tB2Mc`TyuOx!vBxOo#GGT&m{D{qnuuXm`tL45sCa(B);s_G@(@A_@ev#yBN!WWtd|Uih3?1$An~OcfQ^Z-~BJnQqd2zG& zgP4qKG1k{iJXFNb{o3@YWMj`epM*aP#H++5;&O3?csGf1tHt$7e_4D-d{_Jr3H|Nj zPbBu`Fs>NE}AOUajP5 z;<-w{Nn9{Hj)-MqYq1jvy{;tc>96!-#3ACz;s_FY zQ%ID%OuR+BUwoECT-J+ki0_D-#Vz6|BuJ|aFz!tM*=d*Tl9cQNsJr>T%=hAO@d9zB_@cN${IB@EXurP*J4r!jubx;;mU&)h zaez2NoF`r_-YniHt`pxA?e`L4?|aF6#gqhBPrhism$=OHj-(8pCe9Qu747#9k^i7% zzMGT!8^pv!CpQ%j7e|Xz#dF0=M7~p#c5V^x6(1GXi}w41(ECX8cjS7{YY=igO`Ih@ zCh{GX)GJ7G>>(Z@+VAZlf0E?$#bx3e@deR-FAw@#C4VcLu(MxZED|fl!^Bg?+2Z*m ze7QorLA;B^ePsLnJn(;%aja>O?ATkJAYLpk6W5ThdET4ix8yVUzGsSKHxl=?YQ^Q^ zbK?8rPVo;hf_<6g4ij$^6VhCIw%A;>-^YS}AIZmv!^Cmo4Dmej0nfWxe2Tme=au45 zk;u6 zu?Q0`uXm3TXNz}{xPJYY7|el;>yg3YE#iA(R<6r$As#NCF5WJ_EWRiHkL-o>_dLhj z#IMA}dPwhz`&HsmqJ2KTqvu^i8C*@`eDMwOWAS@2vA)Z1LiY2#$>Jm8&thBbJ3N0o zT0EP42iGTJ&wM8j7bl5x$oJ6>v42A+4-u~u`!#au&x$7&IC+EksraqY@Vmk8zJ8=C(V%|XW?C~{1qHjw{_*O+CeqG3B_&k#=({By6aqrt=oQE*I zD?UFb(Qo5P#B&-sQ15?&(tOGoKbMdgUyDeLzw1ei&lThh>}TX0y_X8({c*~O|2h); z!>c6rlMN*Hx6R}-%%>#w(;X!C?_DJJ`#t0X_-DXJJ^P**&SP1WF%RdHuX$dCM8B4j z=r`=vHXaC@^}A9$l!X5^;vll0=bb7}B!}Ssws<~?_MxekcZ$|8q`xTnU*dnsTRrbv z67Ah9+Vd62&DcJ)yGq0>bgYb5huHSp_d1~c=Tio+6z>op5Z96D|CdS3!Eci2|9_F_ z|IH-&|Gy;q|8o-k{|yQMe<0ESdr0*EpJXrmo?8G!Jkm(?e-4RwG$hggO-b~Ba}xbu zL8AZLlIZ`=f zB7WzQ=zse@iS>vNW%R#&uLS!4M#_lWurP@DoJ}G=D@nv>STczCTuLH7{~{5eR3695 zFn)M^L43X<5ubWIJ|I55NyKMv28j4vkO?9_^|L_4r-bt+;&U~L_8s6VVB0h&V1rZ;Z_X6Kz{~-~l63L|`V$nfz7ZPzBE*Y-b_?;tp zK8ZM9FL^nMc)lq4RT6Qv`!nj>O&RgE`!D1?0~v9)`z_>Flo9VPB;;;nFTH0C@-)hb z|MkjWPNE+kmi#z5MB^O#yC|by?0ANp#qj|rT9J^eNc7VH$pcCB*U6IYdHxL4FL@d{ z2l13VpF}@iE_o4&{#-731&MyWPx4w4{rj}!btL+EtK`o}^mkSeMEml{ThUI*9Z2+l zwdB4e#=$_z$B_@9za)<)F)kKKUP@wo*y{$^UrTwt=l!mHF99;fOCE`Qd!2xBbDZQM zB*u?diMO}T95E7{Io)x*zhz%-T#5HbkMJr-&Y0m<_8N3lC0^G&Vq_(=D)E9#|4p3n zFAA^3PdiI}!st2wOx@b#J3{R{TlcFiCg%Xg<8rO71HPR+-iZS%9iWE4Ry<%ZVqZia zUuS&a_R&2+)d$s&Z$a$4)&HjQeboNG-u+ZWJy&(_+>3tHyts@qV7f zTBuVxNL4Y4Q@N|h?$!2{%X)P-=ZChHZC%t4*e3rS+kfXjYm4grgO=^1`**eaZ+8BN zl}FY8c^m4A>>sC?9r*9#6r=dJ-M5e4LE5;l?*5IddlCHKx2;a^Z<`jYc953EtM1o< zqiSQ{BL8=N7pHlUiVvW@U)>yv{)^oI*5Q2>4^s2~$_K2NFFyY}cWK7z{DbPEdIzjY zFK0hkWxm=!s4rIaz*X-5;`f7Ae}E$Yq$vj|_SYvV_T}pKHvT;T88 zO(pt&zynddH7V}Dchbr~nqp%V58AAKrcD=+1D%H1fJAi<61cj3|}9}f#|Cq%;Ev|`2)l$eg}+pL*1`Y#0NgU zNOWR7NW-Ig`*nu>J&V7q#wi@6`E^SBRp5To;qPjY#zCrx(b}&Ldu?Zb;^1$`QmooR zYKvFhuS)-S9sbU-sLnwu+egpV^fy276kp-rsUD!-gQ@T5=)uD(jRRB`J6wG&Hyy_O z+EwNBxFnvz$0fDfKdF5*DfYBq1!F3Gsd~!t*La|BSwy# zK4zAiM_o$o)KN5wyA5<%TGK~N88>F1r0G+}?Wa~dVaga!MeI~QYUja(ndRfk2aJ$Jat?-|EzTC|vNB=XA%P_3io_4;KaDNV@J=_+ui_a4wC1b6&skq;d zX9IAn)O#B%V?aHYyB%w6`}#u0t=H({w`T!TV(o2(J(j0Ezkc#Ytg(LJ*5E#i@5kd# zFX{*NSe`2v-;al}9b4~?7(Z~EH0sB1*pBrBw;=6jD}Y^mKlnL8ti3(3SB*6K!OtxG zxZu{?K7Oo)9J}~_G{Oe{qJB`1KF}5y-w%9cXPQX0T8tmK zRUWOEpL5_Z>c?(umtgf5zdg^#*_$6@54YT-_CA$8zg#|z$1J{>4h3vS{h%KGpe-)G zAIZ>*^t#ERl0Cm1Klh1U ze3AFLu^sh;69dcB78l_C(UEF-m=|%l`95Vf&EiS$veE)c?AElXf`$viNSnhXcFY3oS z$o*(Y3q-qYjO z7(dFS$8x7Qdr?2KAm`JN7T;c{ID6Azk9zc@0;})GVA=EiD1{umuM!+Jp0>F7#m>e?Y`vxU zppVBF)_aKbSnfk-FWPUbAYYDjfAQ_z6=$yt?Dc~Z?RCXUJ=)`QXl$$RM+bbS8N2v? z1d)#Is2|j0dD`OQ*Sj~a-uW?p^pGCQwR85O{niaK=RJR6y<9Jnp5JdLLmurbfquOw zAw4#Ji%@Sh^676c>9O9kWzY9_9pu=Bb#l4O=|%me9?R1f7r$PfHb(`g=H5>apJXvgi9dGYN?? zi*LG@(~J5`J(i~}E`Gh;p%?4#T0EfPkJBTi$8y)IUcfHrz#g9=@fW{6>UeT-;X5O^UHk$Id<{;ql43n`awOmhqk!*e(?7cV*6uHOuffRkLCCq;IV$} zhFn5JTKx8$5@#=*Q#aqA0A1gYvt`dOm(NOK7T=GRPA}>Q^{7f)Tzo%niK{mY_4?!L zBncF3Mzt_3TJS$scok&f-CAEl6~N?Tlf zKQfUR+aIMdew->jmOCB)V*8^Ca(x=o;r^Sqy zDNy$7eN^^*f6t*4F^k`ZPn}-WU+Phnwz&B9{x`1PIWhj8Ed5`7y; zj`l~2^!)Z+!oo3&-@eXHFWNrpQPsc4QQwzRxW<~u83>j^)c-`Q+h1-tm^g8cb6j(kJLsN#)WGEZnDJ2nZIMh z^H_iJ>-{RO-c_i#6iPggI0vgA7yh0J?fLz|-<^qFn8&5J(~I^8_1JFO;^Noa1A4Lj zu_4CadD3IKE8_g83XKI|it+2Na`SjyFtiB%?$ev%W6msn1o4(cQMg5>2 z+e2Gid_QhNdaNHSa_f#;7fO%izH#=V=Xd2Su+j}a`-dfo6&xaO3mwL4KsqFcF z@ONWk7vGQEG}~`cKd8s@w8h1*HxqiXe!Lpv$EDI^xg(vus2|H=&$mH)etW8==gTYp zqJ8{b8MHOpKI*Za%V-RXZ+l!^`!>h4?+WR$-14~gt%5xa@#x~W=jyojJ@^;xdo8Yg z537Aw$)exBm*U#DBc^?ep-VlsFN7P6>>Gdnd-^Zh_j_FXUjB>rl{kCR_`Rz3EkPYz z{Psnl7u&ykV%m3&^w_@1aqZ*p3;pg7Cgl6^>lbG)j0aNtL67^}busov$(~>CO~|o} zZ~79a7xjaBY!7X5@%^|E>9Kwc#Ba3v=ZU&KiJKW>4p??;!6ef>y)%x87| z#ka@bEsC{w3H^W``{P!uzP(D>^Zj@_)3@a4n?A|uMg5>2{h%!_e!a)X)w=>W%>Dkj zU3x6X-!-Cbf84(ad;UFYBuB^9{5X4SVUOkC#(F1K-;bMR&-Y_9>|vLQE`Ix7c6w1i zK9e7`#l_cKA6M_=sMj9{cT11$Xo&K$etZM@EE>|{w};arMr}U`7*d{2r1X%e@s> zF9#JKtB)>zy<6k-8biODXa>uAY=0^&W0 zuU7VuWS2K#Z}9QHR2M&v%h>j9g}t@7fywqgiT7e9XdJuZKn zd8t!yOeplV>hc!E)w^gAe&Zh3_N@1LtbV;W$Jx7Wq5IB+Z_%&o#yERhPePoLNqaBE z*yHyJ{W7%i;boX3{XqfQ&$~a)UKqa>%)vu@FJblD_fnj_v#-QFSp)?wzP;z;?VV!m zce!Zq6|BC!jj~sz@>i@uo#+pLp*^l!;`D}n>Avd~ulJ?&{Pf$Q_cSZh;%|Nqz1VS3 zdMfV6%HKDj>$i`;Z-!g()BN(och=ogW}5FW8534-IrKK*gUff2&d(@m52kFLuoqow z6Y!h!Y={=$9;c^Rz46117mAs)d_6pSF=6tEabqe+RZeXaiA36V?$DuqRol)TJ7c@5 zsw(Dxrw$z=kz% z=SA3*yTcF6XB)B}NvjE>cGJ~Vq-=h5B5U@VZ5zoN*(%nQh3~|0S-W=Cd{dM4NU$HZ z5^SxJ8b8dNmxTY*CUBFj)&BQv=z9nUCqOL22_>RgjSg)5AW$$Y|UYcb2`P`HCvj zt7}XV`TwVu)V0s-*mZ%8^ZhA^^GQ`H==scGN=54C3u-Ux9oYB+{wHoQ6pBY#NE{AeHawtdiczdjf- zAyN}scH4y1zM&;a%X0fBEeS8f_TAwn$&iwlFt%ex`;kwKiM%N)wNl`^{}hOvV6pMtrT?_tS>vK`D;}9|6 z{>X7a?^7#^HhOl%dzi=EthQ}Z#Y4?%3m$THe=^Anu$}&%SXArevYG(m;?Htv6{-8# z!7MmEyXKqiZZCK9-;C*_+SE=MSvzZ7ZJXH>M&l{p8Ex!=piSKo!8>Ehq$yKpPl?!! z$jmdRjq#dK^Tv*tP>Z26b7};ols93@*r|s`n$Pf#Ib&vI>e$HSF_WiGKhv8sW;P#! zjudr|9DV$N0bZ{eGsaAxiNYghM#jvUHhs*D855>XVZlggbN&Q~$9*Eb=E}8hhIJz` zSQ@G++<0pLHN~eM5r}w8PU+7$aF+IG@4)7*2b{e#>?lmU+u1RtIU7u6XhTI!`2M4g z%r6SBqMZT#pDFGKyXG2i$>G-Ww(XBTbs+1Xk9=lNepP5!FofJlq-NWwXZAFzD&93O z&}{Tgd+Jp!^Mbq13AXQ(+s8jfxt<$U+x3Z+wGaI?e_n9oHp{?1#qG6~ z_iY?n>=n71hZQH)ctznwPCB_5Z&Qp)Q+MH=pT%!|Y1)<5^r;Ci@)jLh<02AXc0c?~ z#{WiD7j5^RYwmVi`@akR^D}W?>y5=a3oDnk_oYY2vz^ZZ3w!5oNG%U;#OOQS_18&N zk(x349H0GBTX+0%Lv6;?Gp3Ik6PYl>4V!%uISiSj!HK#tW{wHh+>3dX_276^v&O(x9iUN z6&yKN`J*6Ek+AWTi7txYZ+HB5yBk%bY7=YX`}bq@uRl)(t_!$1s-{;>X57&-^Tvwt zgL>cC`|;-*)szpl7-_)){<--RkD}lU^{0?*?6xw)9zEHr=Pk#Q*-8zYU{R1 z!Qstn`wTx;a;V0|uTf<}&1vW-_FZsJVoji;=kDq?h`e_}Qs8~ltYTW1?dyKL(9Y4O z#w-14V_(dW)XrSA?!mpK-)y>{ck2BXxw`_P>Rs2*&s>%KeSRWqLbUIR)TDo37^ZX$euBDW%_aEXRFPa+ zi;|H@ZNZXlwd;Rems5!Itwu|D?)$=z!Q4Jy1#)lNb7`b_SJOalpZC5@%(-IErB%%) zW%V^(%9d=KSbxd3N#3F^HK~0~SK3c2Zj0ka>S}J&M(U!{MK}@#lFQRJubhPa<@-Dj zXLOU8e;rz}0BfhMJXWPu{EyKMl&J^b`!YSp%|7panfXBTWgqM*tp2P~|0bU`axpHs zade{(Fr%DQv#e3-_j}u|{5p^_(Dp%b%{^ZmB zSlfNUIX_U5wb6|Iw@qZ5s9)cn-8BAU+r<7)B=xWU0lyuxB-B3%b3A>?{vr`+ z6-YDvck7JAPGS5BSG%lTQ$Bxw%z1O{_PUsK9J_HrR(F1l^LKoX87m`ySElDu+sy963cLZD)c&&j%mnSy{PdE++wO1 zPMlJK7k(rpPQWAdN8XQ|(0#Z?m5`Ui14^hASEmX2xkqC=hj$D@{OQw#NG^Q{<>6X3 zp(JlIx8H!v39WMHbNja@*sjXsrvd#FLVU?l;-&_03AH8Mh)T1Jb)!>8M>u6n6>`iG z@EaGy3Ao%29U3e^M(9Bt;zB1i!aWr)rx*U^?k&bGtE9GJUeX7BtI(E&*v>*qm83*N{who*&KEGt-qn{G)xGXF%c_$tXp(o7L+tIuV@>i*8tLQ2K_>Ya^hHu% zCk{5r{Jqhn!>kxO&hS@uy`&nKJJcle*YlDNcj7RUd}d3C{hW9*LNODK4Gqg-#i0hM zCUkPnuiSox>8EDf-sr_%9qzVIpw7t1d1!SG9|+F<8e^g)+%()C9t8hD<>83J)egnN z#c6l4FN0grGvQ`d2nWZ&NVrAXQ_*mRJ1SfgXrNQh6S%FB7pz1Z!kyE1qCNS+XHZYL zixmo!--gTKLo(RXfM=3BvecnY44C9H#5dg4idhLJ`F5J=W<`UKazf?ki_qx8o@j70 zzI!KhFS;@`w#h&yY=h;{kr=F@@r8WRUhWQzj{(UwVZJplI0hNXN7Q>R9Tf+g<6d3z z0Nb?*!7Rig`IrWCFu?MHH)A?UKFQ|f2OmanC7)`A(qJMwHhFCQ3o*ZTvEwOue9om1 zx&`^xj^qhes1CM4vyvyKOu%jbzIHq%PqG2(=Y{xIywJqRA8gz6XvT3VO~Y4U_*nxf z5o;RzFrt-G+;9#|Cj>W?Kxk=O5DxNfG%2mrw%*uJQrf6(-(qN_bh1JhJ33Rk=RAxW z`UQW5b16M-3kC!~LS-p^(>XE*2Jb^8QU+MzST8gg)rF=M-T;keSL2jEG!`KW%_>-f zgq)l4FE<5sl%x&~4}%xMD-hb$lhf|B(QJ%fN&&26(&>1+1dju3Odo;cq^IPg3q8QQYWT8fo9eV{u}X3on(djX`^S1 z@=_<~v_o+7gXhu2lm^pLQ=yG?>Qw7z#0w38z0mb7#-XXraw@T1zcv0XZ$1YJxj(~^ zw6vz-)ewRghag0KP1y;=TZSn<+uvE-$f*x``ih3;ZA?rgc2Wr{E$!|AQU zE!hIA);jMp&H%R4(<>Vs0i!7MRx^}YRni`6xouFeLsHZ5b_l_bn`1tRWGAwoU?<#W zOe)G53j+zkyU~KA;(G7ovJZlAH>o7+VeC4Q;AK!wYGM1JH27{S2raG9D)J^+Fl(j!km*)YP$;iBF0=snHBm4!xYM`Fd+CXEmc@c1Cv)$ zXk~K(>jDEtjrB5GTPbmUAo&RNZAPUP%`1WAWOPAB8!INf8c1%0xMoy2@y&qO_BITM zLrv+2a4LtMHRIQ5+Rn$GcbF;s8VR`-h;&|NvoN2V3%=h1FM=w`JR05W1$jq5v$?Ys zd>chFTUa3++yd`2TUsG4cu`9TWp)^4d2P2MmirCGylrCGse;ZN4dc4x^8{u`BMol-Iw&B^x)!`V$aQqtyl*%3Q3 zytFgD>>|5~!MGk;*~LLtmP5V5tn6|gAk*fw^|CAc0@!ZlN~Fzc=ViCH+u^h`v0Z7m z)4b4tr-Ses|+VF$j!?8g5G%^dX4o2DJQ z`Eyf_p5JRO!(6c!Gh6ORPENs3D$u@Bc8c_Zrz3c|quqRoxns1KJH`qDFSHYl&K(zCv?4F(XYfF2x+8#|c?;n( z<{?b^0W;Kg#}-VXN#;BJ51Rr6HrZ72sAamPG5Fokl{sb)IwjZe0GDU(N0-$zKVv7! zGy^b{vkX6L&Ne~lr<(fspJvMNKiyQLgCb@+s*RY7@xRD)hJLZR3XWt-f2#wy5JRfn>XA^15pY2can2?f&(5yYPPHma-1O)RM z0^*s6us0d=2L1=kHvCU8zu|w_bVSgSO*(>{V)Aj^NHs5&b4Z3FD3#hNcm_;#Pwkud z1=u44eVTfhJppacxjeO|K9ADyI`t49p@WUleW_g&x$OlH$1a-M%^fm=Ju)D4w?Zg* z2O6B(!wTVG8f)#Dz6nKAf;kkbt&kSH7*lR)uR?l}QBckEkKS%X&q*6MVYHWecoH9d z$_h4!Agf>gGzbXdJqZZUT#S*_BZ6#oPoAZ5FHc~z66_XxHG%)Uq}fPJx&Z%r(iNUL zIu&~knZ&s~>0Tsu;JHqn1uy9}$S%rYZg>o9FHDU5JiPGiPIt$TBx0LYQAL>*kmX z;Bc-nl^7jn6%ID_Of{;iZ?-}+-`pPL?7asOZ)6%Hx4_K84p3-*ht0<3O0*ImY z^BQ`#*c^r$o0&ghxx@@b!<(BMFlJkro~Wgz;csJ?noChvndyeGmYYN1QH9CE4A{z? zfRxszcO#tfn8B!}t@#CI+nN6&d>zatc-PU4MIUxCH)G5kVj@U6)NDqnuI6iOcQd8X z>~4~=FZ3{%qy5$94*c(BPDCxe%`+Ggea%ArKg{gJu2^Hjh+99?3++6@G)0?_G<}fL z-$XDk4>0{Am}*QWx@4efjO}C13iQh$b2(<6!MH_>s~7V%#@7(D2k9pne$+kG%tP(N z%qJ*yvPs1NI>ju+*ge%ufJdj93t(rsc^SPq!c0XRMw%X|ca(V*|3{lKi0W8#C3W6{?an5XdnLh~eg_9Bym zIckA99=(6Dc^Lh2i5Y=*UTV&R?+Z-@df_tD3$41`%tr1NW(InHulW$^d%YxH)@3EY zQ?Frh#$xXGpP=cUIR_?;nF!MXvlZb8nw`i@Fu5p}Xm&y;WcV`DB*UL_4jZ0RCY!F< zPBB>sbgF5GQfcNKSV%WXXnKa>%T6;*12iJbW$4zIMBqLgPp&r;nh;ajDdcU zxeQ?{Ht+|-eKtC*#N3H6H8)RSsI@SUV@S0$)u^k~6d?{}W;9w-ZdM?r!mLCst;`Xy z(Aq3UCsmq3NNHnUhMg*NDr#(N9)@@A%+=_s_U6Gd?f_|}+yOp=kDW|gw6?Rk7CTiJ zvm4Pk#QcU99%}M1$hw*zP-8d4hsL^_5wO|AoQl}?Gdp!q6=#ItrTH9thG(|IF=JlCNC}uXu#K7gcf`9<%ivZPLnYY+b(;Oi%<`ZlN%*SvbXg)z85)7XWOEfibGGvxvcqN&sa3E~#cP-75 z5QomC*i%zYGMvDfcPmtt+&x$b(@DHFl5{-&6&5B>`2i{Rsw{b`y;J4|a}e<4X_*5s zh7!^yjBe{CpKec8!Vubd$R%B;{Xcq^@y+v8A|;8O@zfxBkuW=}N= z+(k>ZJ=G|1S1o~O34tE!f1?}tc7#kcFNanW;3Oc)iGd7T1MX$O!aaE{xctYoR^UEG)8Tnh|@E zT-eO|-pXDi7nWF|%3dTFHn&2DU;|8(h3*==ORxzAca`1EUOpF=+RNwaAiv>JSZ>4G zFZgc+ys*NCsK1R@VQVW4u$Rh(mDclw@$S01u*#m@nc6_Iq4~B>oE%7-amF;Suw4P2 z8W_9-gSGGwdrRxMU+!tVC&z<4jI76D4?i(N7F0m4(*BiI!I${7e7 zNhk9kZ*ID?oW_kacz?zGiaE?PRZue~5u+66EFUB0jf;YlknLveCWnW9r0!gl_RXMHc^rQZYFJiSXV$HaswI%@mm z4BkdIJE3UIkFXsucVP!jFyCTegw4qaZI)RL{fNmxBdX2QXz~2UlhH`eG`<8u!%Ld) z!OoAf>W!EcyoAOV5#h$KV{iAe8sExBMH*j0N2?nra<7`7-k}7b6K`U!wobIh-fi37 z%{Cb=J%YAzjg)>d=Q}UrrLVOc^S$(!>;^7r8&)w3KMzysHWJdW!Dz%1PG99VveKV& z8`_U)BcEiqcpof@N15u!v1d1J&P3O7P0KUp z!&|e9ju`vQv6+_2u$_d2pqY){PcU;}Dbe&nqeA9b)RJV%G1-Sr{d7z^<^>o?F_*z+ zsyP?cV;&re3Y&HbmLMnTUhIQO>k#-3_MSICG)Q36yrgTf*@3sa6Ko<+NTCk-=!W=b zCe%;l5b?6xB0kxBl6PYJOKNk&{_`qsLvI)52Rwv3;ZOLGz{?IV`}`J&@Qf^`)Mpm| zc}YiM)KuJr&EhjnJ3l#r_X54l4LFDtuL$+^lf8~Zuz9Qr(cn;~+BRoC3cdP+LkpQ= z|M8~0yF!UJ%QY~?`p7#u*+8oxn)S{l18BuQ|tO8b0E62$*#~*zH$QhB`@<5jP52shj^x8Z76vjcG&Foq4`X< zk%;>5W!{69wipq*ntA-h$ID&_=USeh!%LP2nQFVm9{fgQ;CPvjpvQ8Cg+5^3{S2v% zD`VrfDE9I)FGr;XlZ$_%8b2XOuv@kZlR6>Fng2n&OS^~aV{dbfwRKR$T~{iMfa3)x z7PqE?P0oB5J4WHS5O+{#a|DLChQ$Y{Hv9U}80Ix#eRWP|cfk%=R%r*wMbUgVMP++1 zK(~eNWu8s826zuH#!BX?XjJy-(8j2RXbrJimB=ow34Kc~c3pyXi=vmr2|2SVDl0rb zlz=HO!6s+l8^OdoBZEP328OIdcb9BYaejg*Fte;ipT?1!~H|L$P%y1EAgCj$aF>l}KIp02okp%nC-qG(^ ziv7K@u{-)(epOz_AX4*O>b7WV_GAp3h7W`}x_)7*buY7COT=khC>364yidYZ)NrNM zD`Kh(!(C`u<4$(h>c-T%2`KwvOkoZ0$>x>CplE?kPoR#$!K;x_pEuXd;9zt1L*9hR z<2-YGFo!vHe&7=fS9vd90x;(;w&VMufd+LMpK;(n#2m``egd7L|MhVG466LHk=IAe~+@hxBm z24Fgoa|3&6PE1+^Y3yx&s^RPL2;C983a?{aTEH9|m<7T8Wfo2 z1p?=Wtr~qOK;_%_F|c@`mv|O(IQ9P)&G8b?M-q<`c@bCL9GE*6pK~W(f((w7Qf1JG zMN;miG^gCwOS}geY}$Bb9JpyIo1n&~)%k^Hd7X~IU|1XIhHk4r#xrXJ%{l0r)We8+ zFi?*JE6T4Y19lAcMtN@lO1fiTpP$fxCKqETd^AvWERtL0jquF-fd;&k zX~Le{6v*c>hNF+y3OfV!xyScu1>Gk6g!2195hsWyldxy}q;mG-_n@_bVuxZxHVqbW zcEr+!x8T`;Ls~;h@p9-!5f*n z!C2AWYhB7DNaL`!WdB}Q=VRiLFu?XVg8?^Gy+l6R!S;8qOG~LmT3q|<_Cv3TSN`1V zSE2}_cxy}zS0ig2tX<};IqwHyw@bMhIXsd?cM;|xroX}v!|<5uM<^2U)eYOuH)7g^ z*WB24s@-1E3M6Epa9Rm`pXS{asL!*HbK&>dSX1sqc5HYLofpB*h(vrX3ICTv=e|Jl zd)ON?79!_r$P2LMUjyMIY;2@(D}>~r=lwxpHH2yie8X4S>kwXqopl~&KFrPe?;v3! za(I{P(Bwnim(`8^$~vd=7XxW;qM;crkaI3n&c>S25W=O{xEO20_7E78lsz!ZGbTS$ zg92gn`Y|7&g5Iz+6ty+n0)fg6x7&>^a~nm_L>}K0J7I(KYzFjv6KFbN6Pn_Ro`=G=x&?Z%e51KS?r0&cvcVb~-FOY&R5 zx1*7~3AWzDn$Ziwr`XtvwKdfm4nsz3tr)*uHzrUz&qKohpn)#&&S&^r+hBh)H<7<-Q-E@Pks1w4D8ci7#c&+$5?xp@6cm+| z`pD<$`hJzc6EBfJ-@}v9YgHQKB&8B1c=C@DrX5=64slR^)Zm<^38woPR*v zG?~bKo=Q9Fl9q|6E zXpWaM3u!!MU>gu$FKH+LJ(q}~`2bF9h6JvGatV)sW=Nn54}tFFa7bW4-O1rFcj)pu zKh(g@=eT14GiLb}WjcKJ2pqz)-=P=2#%j+9djyW6iEM-{8LK@A_HmZFL+*$*5%t>r z`q#Q9Ct^(4{W=52)$GJ0k;bdHNNm7yu@0l z@!D{TZ-!c?o!9g%Wbj%N^(C(i-eFp-YQ2hi!Rl@$n01QbN83Ptf4I*DEr;_PV8lAw zHqeufjzRJWtk%(v&e8KB&!u|tt0_1%26A|-f(s;=$VC@e6QzMpG;s@5m-!}IITQS* z;^WrDd&M}*3D|2Dnh0AHC-^3s21;q-1E{|5n`q`t{0}nke0#;uVMx{wWbeFxjLmQE+R1R-JLTU@OV;C*_ZoZR=|$d( zc;5GL5f_qJ&GH+dZ{z#DDWUqssQv=14fwFn_ofpMyUQS7ht+!fle4r2^1WCap^W!7 zx~vgT8o1#V--#V?hieZ+-+#ZN9j2TWy@0~p$*j?DoYAe2w_wFVtQpS%<3iXJc5Pcf zb|(IS>My>DZO%j^1g<_-Jd+O-o8nE3^i6DXCOSivPlnl6eCSLZ2YH}1u@Yy?ZP2VqbI6}yZHm?24bpz-+5Hd|^}>X_##YqLR&=Ld(Hhsxa1wsj z5QQ7?uKOBO&E2dM()g-5ThT+VqT?a=$7&~@1#R#i1Q>FY4EOdF&v=PdsDYQwS4OkE zrZ~YlV7pRqg>buV7YB%0o>{2?+-~gNcme7<7i$APGj_XaHvz%E3-Ya4ZM#;vcD(_a z_fVVi3Wm4C;sda(1P7v+istwgU2E(P_Z{KqQA@~0 zSpTx3Gt&9NCR*WPwt+``{fZWt7VOggD9n$t8>FL^3rvS!p~Vk3Ct$S|Ep!#V0{MBY zO(Rga4&mI#Bh1N-+D0eZ=tfmpsqyN=gUE0+gO^#@#A=qauk6U0<(ly|On;8mHe;4+ z20#5z#%h~!mTSgv$V0I<<&ow9%{caNn=$x$)NaO_ka-&QyP0RKu~SJ2{YO?i2Ea{2 z6J3>FWIP68SKIjCk!hBH)K-n}>dKyv2F=C#f2eyG_^OJleR%J4&ORh3A%rAAzyK%6 zB?L$UL<|}(fg}(JNz8@29zzmHFeEVq0qX@7FRgc_)+%1xTD4YbtJb#OYg=DyeYIX+ zYg=or+Ujf3T5HwX?|Ej{?7h!Uz_$PY_x*m~{^jJ^Yi7-wH8X4Ov-eKh1-9Amg6Aus zuB6LuxRlf74p6t^rxLSBOMV3O19aPoy?M1j@&YJ+))F(Q8tw8ns5kM$>}G{63nXjR zWOJo03nUF{fn=?%7D(6=eF}aD<*XJ+&V~K!8eyrYygBUts?UuTki+h8``oJG#N`vRd5KD3vQHx4?tLp{+jVJB9h2BxbCj+zSt;>N=O% zr0SROVX7VzpP^F~`w(n_wUxCn=rqX0tFCd8!QOw@TrrOf-Kp`r-I@4}xfvtS47-%( zFb{MQe##uOv^i`5-9opW*oRlH_>=4)J7j$WJzhB5e*gf%iK6 zTyxlmAym*DZuPktbGYB9KPflV+Y2ObIs&=(_46R!1Rj>_Fru@b_ z=l!gK zDE3Wa^WTP`3H*xKqwg!_;NfhL1Ncqhq3LUKxS{hH$cOP$@m{OqeF5Zi_^H*wTOd@= zbgF(=h~cf;gbrO^S(N1*9FXxCq3>LUGdBb@tMzb0`dt+0S@&H(6?uAdhI^km(I&^wOP2BQXvNZIf zc}V6bD4?gtG37RX|A3BD!ua=m4tKwD;gp4+!;dvw3e}!-RYP+MH^x66VxTV0F`F5r z(&2@G4yT9?PI$AvOL4+$ac9LALlAeZm}b-$y}s6mn}?5vHv4h&>JdD&NF|H#o5Ir! zzZ=Phq#EQBI^6`~HRZG(#rzD%FDitCM~Otuqe7aT|E~ z4!n%tgV>E5Zn5%Msx|f>a6#Bu9m4q+FR*;AlDHmB$6g1f)nHKP46NV9OQCee58=2M zGS0>?J~tW%8_RP&x7Y`8lhLSJJy0v_th{PvJ=4l!>rlq?Og}P? zW2_b~nAjJn{aJ)p>#g>Fu7<7VgLd`>s;#;gC2#=0Vm4nFs$GPaK|Y6{g9>JGzcR(hePhSr-<1twGiWB7O| zpB0m9ROazlO7uJl5E({3`MZnJf|N;V-~yl7tb z{vRM<#x^+p1=;&&{4!1jkqJf8@yk6Q1YgP+$FG_pvs76AAC2GI&~O#F4Bn;qslY9` zIS#*a23FH!S{r6u9I5kyGh#mdSn%(I(@Eg%VBniTT#B17;+K0Ti0|R%+xS&8B+3aF z|3gch_>3z47vcR3eoE5B3|I$#?5N)=Vcp=x{sp;Lj+l>!Qzc^M z%MEk4f;b&FC*yYvnQ4vsKXMwoti$_Em^;C8JAUO1GkquiF=Hm-R}PlkU2x!g{2s(F zcQ1(NaPv$2)BucQ?@?eABOiwr*g6Q>S%@1B!sqxrtHslDSZJJcw791 zM$1!<$PBhuYntK3e7sPH@l`eF1QB<=@=}624=JdG3p%_a_}Tlp?wc_VPJcq0-e4l9 zffzOdtv`O&vTx*}F~)BhU)sr^WfxfCj6B?hYOGN18L)nw&<$rClXh&{{Ir_vGWbLs zs|J0ov)n%2J~P|KZFIDcMafUgkB}#&)C#8@lW!mEFmPzh_m_-8?ehy9o^}#eSz=li z258O@0Z>aI#izk=rDPOobFA4$?1&Sd*<; zv!<$KWoO&rjI=b5Jx8Shk4G>GFo?-kTH3<2FfwzrQr7hu12Q9+SUmLYYB*NiBTL6E z$C>9dA?%1iRv>rtvTd)*l+pbZSXMR5Ht{71sGaiaI+V?GS$hS5hC+gRvQOdEd zN6Q#Gr)lSMniFQ;V{Ftm&t4b$Z3?{>HPi@3ls~T~dl7QgvMNwa))IQuWS5Q& zfm)iTRIfA%waFhasVY;jI-?P)+SSpgJQ|iFi}Cbiu)ZuGX-~<>M%6hYqh-uUI}^oN zBef|7$8?WU^>5_})Gr(m@aMm7Bv!GrsVlXXNnNJ0^)#lIG0dd~R|Diyn#sH4e3qmv zjI518$GFPpretUB*sN?y8Xrd4;&LJJ!78*`YL4Fk*SHmxaa(z4c^%b0gTRGmjLr2( zyCE|2729S{;B!1qIj&QVKIg{B$TRG}4}nugoQ zMTR%qEs^H+45jyVZiuWu8!AN3wm(qH8`lr)&*=P_ePh_qd}H{jFr1$X?{)mnd!5G| zI6vmRJIwF=?yx6QBzegyMLC?39GGmcj!Zr}e9Gt>B1bR5{qoKDxA_`dxx8loN#9%& zzCH~1>%+H%>4D%pM$TLi$x#j^A~@rUteR;zN9J4;M(Lr6!Zoy?@;Mv-BRG%N5XtE` zC9z+*sp45HnGP9uDAx!$BO`5;_;OQ5pLy&zOKIBCTEr{~EH{jt=S6VNwjq)-%5Frc z6rOH~AqiSdxZsNNTtft_SS^tW&n1<~bN0RvT=#_@jQDf;!N_M3IPY=xqYShREr>^O ze3@Lh2^lzW9&9V}qpKK6+vVVz;jNB1O?}AC56c?h8H2 zl6f@r8mZSpACUSW^bx6#Lsy~vQL$3Ek)Ndm%YAZ9PDhyZJt}j9l}9SecvP10ry#|r z>;~^{%`25dHxf)d^^D+*<6(HoB7DlCRMDA8F_1X4r!S-`l^6?sh>(LlgCUbz316Hl zWRmCqm5~2=I#n^}C6`qSayKOp_Tp1~D8BzZ*8hKnbYPE8)Nc#ELUWK=+SAyoFV}_+ z$c1WTA-;UqY$CyLGns(#Tfzcn3$!O{cCa#8J9@OKurIc?1@On#JE2l@ku%zHd;F` zckt{*B$|VsBqwiFzm>Ik<>X1TN9Pb`sExlHB6;yVx1S!$A95Qd*G20?$L+f|968#m$bia}tYP!1KTr&b}dt?*NKh{TLyCwN?B0vu&DWE>kK z6ZW$Q@!57DI2Q+`>wDO?*D#|bQ@XQP!-n;4_bJ&~0G$fnU}yM-{UJI- zN>P{ikEW4a#&Oac_WOkQ$recZkV2w91#frLw-~}j!5du#FH??6!3I%Kq93|GyPp4c zOW=n5zuUlw*x|^`;dgUThD(f%x2`uvr*+7~x@Ov@8HYA^!m0CQyD4(=c}atz^K8hH zp)*He?B3z4jHF%>v-&qB-0 zL-mbJni3kAsRQU?oa!`A0KXE#m3Aq)23VGIJ5{-ydvBWW5^~+3mgOJ8`x|Y_HlC_88XZ)63UYJGRA0Q2si-0A!e3ld4jdpQZbal}eza2!;!@QMWmh3bE<`XBZE z*Dikdi1Ho$KTo;8qQw;`BCh`Pt!&6L?eVFGe&u#|SV6h^|0GY3AvuHoYj^!WrhP5G zJuPfq2r6WMk}({ux@y;vavNLXL%)C9Dk|>kY3tt6-Z8X)aZwTf+Issttm4kzZ5_p} z-8+hl+Io97cWo(N+KX^4c*%D0mhRq7t=&xnz5V#QL-F>mEt`4=wiosF_u@U@J=+Ib zySs}?%o^zJ?QZLA?dqA;-PN;WS8;3qwpl&BJsq<;S~qpMs%&d*>+I_J|1!qyySM+p zl0Lljym(7nTOggY=N8Q^nr)K%ZB=qqp!7TjZ^0uhD{{h$c!>+d?H zb)Z9w6SubR*6rI9o)21A_^@7p4PBHFJ`Nl?fFsQx9O%3ZhkD2IAU-Cf41fJNEqnY#Z>4l+SJwFTccC(G4ezoQ(R4+jVmD z11>03Fu}#WH@rG8$UD&A;T4z|HrPj+pozX-+JY8^k3)3zFi)`H4awV4tUUwFJnTK_ zm=dbI-2nKogv-s?OsZYYj3sD?*8YxGUmoV5>vnK#8=mNyAB@;J`S>E~2|4$1HT5+0K{=j#J{~OmxP~ zfKPEw6k%rJZe{Tn1V$taot&AVYl{)jBFC9g6bfT7;A!%b)+F1R0d9Ln+?jEtGpxuN z9xZcH$3)}NVrL9IQZ;UN?3{Q~@CzWzK{~P_KGPXp5?2Z`vg{%Z_x&+_EUZX!HZ_ap zM~jje_J*{qLo#3qSw)sJ%1MI+sOdx(I-{a0S4t3PamY@R_;nK?+sX9;sCHaVK+bJYI|kwO|nwnUhW?)Kz4; zW9KIq(E+A}w174RFzWVA)t z;Zuv8VN(%vtuqWUk7ovzJJD!(XSw5q)9jq+iXz9(4wT!6$x@VEX#ub=1aa)3VV!5n zV-$2^^-Y_q&GGQTE-?{hD+9I*S2)8aJEN#&w2uE5uo$R0B92b^*UHG5?8Ne%+@GQ~+7&xUNW$_`3XwS1v!k`8CMFDk?Rx6)Cvbx>}s{13zoHqU37 z>1a&QHpZRoNzSkpXjo@BsiPOHQwET$lQkUKI1#MM5X!-_j$|A+#bO*Ig;D56XwjTTkO z$d9f->o^lWf>Py>mn!ob$EAOy`IaMP)}v0KZ(aNXZ+m zB6E%ggjPV<%d};*(+rF~ChHmqF{`Agila=;Y}Ly+#ZKl#Rod)v^Brf_ z;O6o7YEZ#Ga)gsN+p))^8#&S$Guz2ykAXYY;fTFBD0t>1I+W4yo~{04@RMB` z4~#sbJ5-irZYHU3*Lt@;*CIwg+L;0kM=W-xD1C;g>y`?6OTK`#2t)~)@q)Ggt(^SI4cQ?sar^0fh$Gl5@+lLYL<;^xkKqO zChknhcg9SFs~(=Ql5&{l;lijL9is$|pruad|()H6E0h0h%G^_oQe!+SPE(mX>v)(u6Ix zv@aZjs?Lw;s%6^|cgB@C6J~;(L}nIdF&oDto#8W7NiB4S&xEzBq6#Co#)NmUH7Z%D zTAnFKItBBb3EC}RJ58cIs>c37iJOX>eB{M0C%=#`4jl@nI>X01Q*|mhbcIlqRE{%z zf>Tg}|IrH7xcuM@lkv#!?C|6EX4PoicLpo8Zi*%`>mN&fo$+MUnJpV~U`QPgKOZepZ)^|LAcLq_rI#IQ{s;)V) zx}vtFDzS8VMcuNhN~<%01-afG1DuX>2_dnidv{+aZu_^jVr9d^Q%D{Cr{Kl;2;bDa zuC^*sTd}UbrP)d(Ht*Cs_Pq9 zRWv7RO6Qae#Wst-`>-LkN8Az@cBwD+> zw)B8TpvuOIHHqemrj?22bq!UCCH0M!RgGlS3j~U1Y5nS|#zbRPQ(_eukpqdu4ou3+ zAb~M#>F?dqhkGm_tBAHITCs@J?!}J9k3?r{PkVPq|8|C1f(2&Atuwc}wxwx#VogO& zbE3MYuBK@@W7o?q-Cf(6p#j#W=8DEHFaJA>SCy@s;+3MRVAvE35R;9hum{RE?I^QMNsJ6;3b;c_O2x0t5p#;WF}%dOU)E!`^hT9t;1O4?7$syasE8CPvpb+gsh3Pb4{*ln4j z@Dyootf*_E$t9LoDLYg~!w=#>1+J-3C#>5JbXqL<+4G>0t^TlxogH0UI_Zfe zqyz=@z}^^<&V;6=ja5~3iI%$BdZ?-k(#?)#jWv~t#`-l{aRyRl$}I9Ec=lRRS?SMA zDTXEW&9DG3X|B-9rlpCB#>R?u^z*8U=9kh#YPH!b^Yer>SFMF{*4HVUVt#DyZr$QH zOl2-r%m^KRJ1wqjU|VZnfecc6V=TZ9Bf1$6FIQA8Zf>kWQ&n5#h4Ug^Q&ZWz+`@-eH+S^o>mIs&*wNE9kmyn^ zmM*Bqsyeg-sPh$-D#N55tEsC>XaR0=R#mJOC$*hHYdxZ}zGVq?Sz24Ol#Lzadgh{>bZ+kuinzcSF;4-)NaUuSDVH9k}(P}Xdc zQBF&nb&0!@X@b3*Hxra5^-ESHs%tBjC7S9g8X78)LN_zmKC4Qqi%K^%5UF~i`i6=j zVqJ|0>s3GDF1hO5?Q4VHy$NlW((vbJFyJ5UpKntLm1arnxj)`(>!Ux`R(r3$0>(ZLKO2 zm%E`6gMx~>Kx^fV6#B7pkKF?6kh{kIuQo%fF4U&RrHQ6>tCrN)Qe_rh7i+$%MqZl@ z_M{9z2e+i`sCh?uX_0QCzjvT@0H157hrfH$wS*%O*BsFo=%Up5E*$~80aP*3McIBg zx@5OFHS_AGb#+U<$W2C8)-=*l^DJFnQ!CxJzkyNBKN5p3G2!(9h)-<;Z0kLx!$gjb z43*K0CbZDTs_MoB+kRE&nrhao78O;et}?Nzz7pfN%F3GN8ni{~OW0~`g^l!qF4b{* zU4hiY-Bee#Zn{BH-Ljj4#(Fdj>oB%5J**yOsm>Nm+NiwH)^_x;h^${VYC0~j@j)-I zdSY(4d4)j#uAZKbemw%Tu!G;-o@m1+uxY#XR@#8o3wQQf^0{s=pS7*B_lFdfYUt** zkJ6p8=v8iX_hOjF(5PY<4khYWdfK$>%_lXu;Mc;*=C>jmI|Ug(odXpxVQG`RTvU8J zdT^$pr=vZN!wdbsQ66@ex|EeB60JPKfR3)~6wB?NF*26^*=;x_}Ui2_Uqss}V3J#Cl}sbdx>0DllMnI#oXRS7g4iNvrsjbIM51 zQLuTzDu(}YeCea=$! zgq~d0+A!z(FxMIwK-O|B1+6hZp-r{*_V%}{$&=QjX?aB@#_z5w{#39wD;q{|T7hY4 z^suLGlcj7H)4G0{UL!9~p(Q`( zYr4Ho8_wFw>MCoNR>(NdtCX!h16@c|E9M_C2bh6b3^3uEFnM0u?C*waIdQ10;5=VV zKfoz@FN30?N115rnQ+fs)My2y?thYsTn*w9we=VhLb@*Qr4@Bct5iMT-lNYE7)vHk zQg+k~ZrE#7!|r7etrrUZGZX5Qo_ zK-r>NBUn;}MFtCN5v|>Nbj0o-OBxoN8QqfTlUKUc*QKTEn7ba8Q0eg*NNq*4Ou2%N zYD6m~-p_#>j`|I#9vyWaODMk86rR_B3yR4%8N=xw1oFxO^T_5Zi&bQ>7VNjN_aCb6Y%WnKLm)egCx@S3U$Ra>?BVdYX~q}xRJm1(Zg z6IQn^u+W2a_365xGmfi;v_s!SnzpJ2KvYMyX;5N`Ypgm2?$ku9;h!?7bdeoa-i|K_ zxw)*Fs%mRlj+|Uzy+J40ES1*P!-lwUYPGhXq6Y$=EpWgIsj7cq>khfPU{x!|bw}4l zGM#H6YZAH@Kp)wQwbu5oehSf2Rn^eTOkyHx<=G4nAx`HeXMnz<@Eog|!C>=>((SRg zwQj+T27Ycu5T#btufpiBMJ>0X1y9T_DY10-$7u%w=o~fWO&5Qess@$Anx58e9rX0| zkab)DSBo-Q2A4Kn)72?dv$Mvk<62n7(LQlK+RYD~eny$?Xv1k|CE1Mo>Z)4MIo4Vj zhi&5;iy6@b#$f~2CJxhd1In=*g$y3o$})&LKCOnH93O!*sruHGmX;23RC8)BD}Y<4 zQ1#guccZUHDro0kbEnIgUkd}fPCdI6GRk>6^aZVGl{skA(^#37YuVb4S!q=|-36b( zSZ7K7+Jqj%d1|4_War$wc{|pT_+O322WLgoYM;?2rQg_~nb*2W(EAE%vSn@W?Cl?j zyHhxJH~!ficP&ugu{6-v+Mc8w*Hq{bv`y7{(8F(W6)ny6TsP9I-SiFQ09IizV1T<= zuG$V!8E|TE?>3AcFx`f)E&}NeEEWM>T@^4-!k|mn;v_-tniq=~OR(s9Iuq#0H)}iG zf;pU8OwobrT2>_w8k$((s?kuEP9bi2cj%_jRo!c$*6KP<4U@`cUCTN(A~3b72`w4T z&)w)UQ?fy`FxZ67Rkq41_r=W6xVSBf>I!9%O7+=oC{s7@e48OUe!YNWY=x^RswQc{ zUSik^HetX(NxG?$31~2N6}6~bYL`d$Bs$u=23SQf9@6tXRwq>@`~xSMj-cZ}YckNK zcUQb&c6AMQo=)o6iMpU*x5c`|A~BWLTTpX*mn7R@m%w>+Vs%YZ4M!0uQnibyGDpRv z*S@(_-pCFyDY&$}%DNNmUHpq0*xoW~cx{JXhvD?C-`gwH*{UW_YIy0c1OzMurjFho z6Xb#ZRt%N4bIk%dt-4aJ%908!1NZi9iL=W3THOSubV!;$0M6kW^3$v`X-B^`s69a0 z{&Q`lrmm?9LmR!Z%4oILUN6B2+y>2TYat%JD=3Rxt~luHZ9e(UmRlIIq6ucV7ON4U zSq0Kj%LJDVA~RTT{OWnXrS`|vdYhiw_A%S=>_%HhCsxxs`YolYG79RgZBRCixiqAf z`E{1T_K^xV!OAGGABlAq+CG+Sc3_7&!QBmOpcDNVT7k}velc&zRz%F^ZR6d1bsw9gmywvZrVU$9jlkseK8rbhset+t|{&NHx{tHCLV* z-qLvB;*GQ1VGvw>inFisVqx4+xT+C`>t?jOZbm0>*sB(2vABy>P>5tmoFZ@oF>BRo z9X++SX6~$~N?vZF!X@oiv8`ipGzLA}X}Va-RBaz5=|XkK?ow4vM-kXfN~%pwh#q~o z?kYs#xk_Q*=?Zs{p433qt)4x{n6*wnhizWMD0rP7%CRf3mesYym(E!m*AI8a=akGT zEtxmFG(KxvTi=caST{t?nbkTU^k&dK9lbrXHuue*N4mSWbzl}&j~5_Y+u<`#b<5iArP)d&jKqE z-kVvM{q&BWo!D=hr8+FNz!n&%sOg=a>Zvj|n|rFw!ax-#4NS{rM&Ai#P)TOst>m}` zs0>i$vD;d62NDbG$rj{pEhY){Z*4joGlLs#~|G*T_Yq$G5xL-BI z(z$On1_ALzQKB1_0f%vtTFu>-8K$TaBs(Xyx~RAByyi%+1A6ORUOD*N!FejF+D|oW zYISc}MT2!xM}LnD6SQ|lUCk<{$T!8}a+1FQlE-&4m-e+yX!Mv(y1zwJz_JL`2sKiY zEJX$mIo_criOQBny&|f1zp&A+3|%&~RAoX*9_>pWM!RZ^gc7E=H1HVS549fcrDUBq z><+5RcH9%?I{@Xb<(OZeC7uQ>f>Q+?- zH>}!bURqzLTYhDsYB|~Lu;^}A<&X?gC5z4Eg%dMXux4S8n$J(pJw3iKBHg&rRyCk) zXsknKBn=ceaB_FZ%(5AF5>-R)wH9p{b?ZrjHzG`|!Y(6r3Vb_PUTxK9OnhD@=g`P_ z8mPp2W3>dn9IZ`N7ko|KYSfiVE}d4Odl|wKv67+&NJ-6}Uc)1|u4!Cc;nIg>XP^;C zKG^3rC^D*8Q`5YhXPL0+frTW!3#&#kgNHJhuwuA^c{>k+F!rDx2&4Al^e+vn6aD?|6v?5^P?<&NH9!{z`JX11$z z>*3BdxtPfbgzo2k!((<4UUQ{OX&L$kY(rFIS4VH!4_>fPZLqfQO|AXz4V}CkP}jFja5@39@s$W;EwJP{j6*{={oCH329>7l)K(K19j6ZW~0a2 zGyocp+KNZiGU>#2vbXp(IPLnJB+dx5a$(lw4cF3@)7&KES5Bqa#@NvjtnThW(-bp~faqbQTS^@9y8~UecO^=Q z@2sXSE*`~|Rd>^MYN5;3fm(fvZHR<&%8hK&vt%si?U31^n<6bmb|Jv&O}pHp@n@4X z8{F<4)Ld&*Qw_iB#`XLXp}j-DdKH^b7MmsKp;|{RNcAUZB9n3(2MTaB$31AQv{$R; zIvuQ{?wV6_cBp=r*}>!>qqQm^RBc<@(%7UohlVghb&iHh!r<1rNsEI`I9Lr117XM6 z)DkXMFbXq_US5O4rD}~ylEu|$G`DKGhz){1EG5Gjlz_?+nvNQ_sYrF=eA`Icq1Jce z3}aMTa;z!ERs)pOd8+G^+HC3T z-0j;KaMiG%q}R8&6`Qdr#|(Q$9|0W4p@BZ-CTSp(b9~Rz3@+R z=R1g&h&x}5Wv(c04o5Sb-#deUV>sSCjKOGOylR%TlTzrpGWk&Aa=()~$k@LeBD5;A>C&e;y z`E{Hm9r&)L0PoU_#i1P;NQ7TkzKhA1jx8}=ScBy8T}?}ZaW}N9sQvQzE+?P7^?rFX z;b*Q|WcZSd$$L}JO*wDa`OyoUFGju;zEGv;X?sg7V=^@G=MC8ZEgEl@Na7FDe0Nk( zeg(gSpbqO<{JenW96hVTipGXjq}ZvUSUBCr8>8$|_Ly+4J=Pv)=h+h?lkCZMq0RS9 z1unl!#Cq?aes4SjM}y$!+Ne}yetpLd0!ZL)lSPV-e%83Fkj zir;G=*jjj3m@ftKU17Y$BUwIP>fyV>cxy*;{_qXr-W9g+J}loA#ur19<&F0FQs3Nw zJbz0-f4;@eyZDWuWO?c3eZIXc|`&Ll7Kwc zR__X1_>PG03R`mm^5*z_8GmU&UTMJpr~o}LAdhbe^{%j07LZrwdEzc?;rlzjD{LJT zkjI9|yTW)wUUGS`mG!Q$#TN;BSJ+w1!- z@Rb4il>z_ifc)x!|MCD`6OdOE@Lw5_w=&?rDnQo-uD0`k5P@IO5u4{zP| zU194CAI0>X8IX5o!2hg(yt4xSX9wtW0`krY_@5h)cW%J{ya0WEK;HQQ|1SpQeKFww zr2u_lK;DG`|BD0iE)Mu#5}+>)$h$P)AFO{t`@1s0zb_zfU%>yW0DX0U{%U}}Hb7q& zpl=A!H>vo&UP9Ne6)snwd&irw^|b(fbAbMa<+ostHvKtH+OHAm+kFy9KMg|`@xZ97RJM$2K;l}wo-qhtx#yT8zb?p)A^w3#CdHN#=G?a{?;V_Tx+M$I==DN zrAhQ8>y{+`Y1X4cvx&;W`0d#wy2Scp5?yLxAwcP)`OB*^gRLkm!KJcfzrR)`h(DMMX$6z7J8DR8>|sw&HtgITkv^QO|x9G z&>xq9HW$mgO8hx5&ayhJ)dBzR0KGFnUml>Z3()rl=!XOJ3jz8~&`fVRepwd!KNf^s z)HgFgPYTeb0lFbTw*}~(0s7(q{mlSs#Ce;lBr{Dy#BOixaLo*JO%2Iz_a zy*5B^571|UW`0tQEcB=QlIY#mZAtX$)`LQ)DE_mo7n106t^XA|ru@HXMNx4*`4?N0 zSdryo`rIW-yx7!Tt@IsqvnCH%lhwJqL3=Oy;H12xBI!_?c@;>J?_iGF*uti*eo08t zY{q7GfAz~3d=BPC3+4eoZtsbA;G6(OxR2bK(}MbZNusT<5AVX%XKm#9L7fQMTNR0e zw)>LYy@ztlPJ})-4JL2T$bVjh8hPhdy-elt5BCH~QfP0-D4E;aSW9M4e)WRur*>KO z(R**p#IM;P*WF%x4D4>NB#G2VR^a44{0@StOg?Jo20G+9DhcLgPSVj*YG955fb(!C zzeUi{yY#Le%y4C+UMgKDp0e{7pg9DbXHtF<^Qj&;gG<`O_f>Z1om2C90>P zBnIuO4xqus$CLazha^AWi(c?rTK}0G5vn5bo{5L+p%0Flb3OWDR!;$a9uPr&`*z%` zQjaT2JVPB@hL;kFGG%e7d-o{V;2mD&VjijYqGC`*xi1(vM8vLtatO~7R1vCkr4Z>= zRc)C*b9MRftU?m!P|XOLhiFFV?6-nsIfL348li6W)Cy$me*Mjb7zU%&=t5!-;-ig% zoH559vMkR0COnLPxC+rHsp}EFHxqkQlZ9rv7VhkpVvp&y^4L!_U+Aa8m!;7HABI!b zgvZ65gG^pQ_wm}9?hNYka}dTW=x&xBgL2IBA>4Ttn&m!2&(rRd$E%QwTf7XtSW${* ze;oUzq#wwuuu3EOxe^_FR{W8_d8CoQQ;E-5)?(sw=&p&+>->$qV5u2w>_vPYp6)MM z)l2>f`d8Wg@s2!kv1T5TSP&5qd8n zLhp@4=)H#sJuVw6cO>iPc-qjgW!euvj8zDmq+}yr2l?=Y?}0M@R?YmNk3?275OQG z{LE@MAG<*Cf?Q=Eu-bDG@g#gw znuzorBtq_J8~6v56A|Ici3qoX_y*()ZWi1_d=vQw3}MmeYQg=)Z&}ujLVsQGR>3<2 z`O!*-<5k$Fk?Ev;#r_B1l_x^ac|f;*?)3OnejpJ!36KJd5SDmGp1*x+2qg zD(U|fdqR0!Pa5U$Ln6xaL-FTen0A^@gnzZr{ALU3P9pfRU2MhPwXAE1e}=sfA^*EX z==DP)^!cf{zd=N1e?UZj=7oUo!7hln8%A1#aXI^v_^{wneBmh};CR|53@ z0DV({z9pH)t0FC^V}+vlWGXR3_Zy)zrQi6rxPQmuM+vOZy}I5KM+;3m4Bf5U!O%VU z`nf)#?R1lI|62%ao>w&10L`vq?k4 z!BWA+f?Q`I-*JLmXCb{wuvd`vjqYC*yh`wEf(Ha25PU-LMZwnv-xvH$Fpc#Ka&rZz z2+k2)B&hZQz_(85&4Swn_Xu7hc#YrNiesnjqIZ z=w2tdQLs~Ro8WH2^8~LHyixEj!5;}eEcm40{|J5{$N{6$N3cM!RIoy@PH=-@r{E63 zvjr~|+%Nbo!5<3#m*7i+ZwY=Nc*HQR4?nR*y;cgY73>h?C${K+rr>_TZwdZT@Cm_R z3BD@$j^N(~qi6srFIzA!I7{$Y!DWKYf~|r*f?p84K=2;He+rII)$trDI9;$<@F>A! z1uF!X39b@s5?m*k5bO{K=5Nh9-X0`LBFxI(Z)aF^gag6|7{B>0(N1Y;k{PZOLhSSVN` zI8Sha;A+8*f|~?81$zW{2wo}pRlyqszae;s;7#S(FZgxA+XW8@-Ya;&;G=?%3qB?IoZ!oXuL`~) z_>SQFf*%QfCKws1^ED=zDL7g%PjHf8fnbqfso*h!iv_C%YXutx*9x8>*ezYbir@^v*@8z4E)ZNQSR+_3*dn+=uvKu2;5NbSg1ZIJ6g*e(Lcz-gzan^@ z;MW9i6TD0C9>E_8J|g%t!CweIEBHTxzZLw0;M;=l3I0v+AA;d*ov*2aBLqhY9wC@7 zI8AVt;9SA^f{O&J1Xl_kC%8uNc)>QoF2P>G9fDsFJWKEb!7BuB5&WLuBZ5y0zAN~F z;Kzbo;8FG@SSVN`I8U%#aEah@!8*Za!S#YC3T_tc7VH3*1+xXm3QiQ9A~-{EwqTjyBEf3GRf5fe8w58Ab_w?CxYX~>U@|ZSSGkouu^b^V1wXl z!Ht5O1Um(L1P2696+BDu3F1#J>%WEmlc0@-HrDSv!MTD}f*S-c6TC(6XM(Q@ek2$> zLgWb^Em$YmA$XSHm4e?Bd|B`l!Mr>zuSjr(;AX+|1n&_1rQlx#@wGpdz9R&W6+BL` zQ}6=8`vjj7d|mKk!So4Q-Xy^Vf=z-I>5%H%?(($GXjwHhUD52*IE)!fS z*gyndyWlRt>jdu<{1FlH{gjCGJt6qt;{OMs|0wu3!A}IOBX#&pBI27YSSGkeuwU>Z z!LJM6C-|h`uLb`?gg$>0{8ZdWPS){^5u8B;U$J1BV7XwGV2xm-;A+7H5qkFtJs^0x zxSu2V6>+~-@auxN3f@bEoM(u4Th=>5|5b3r6zzYc;L(B`1bYQf7rcasbX_5Mt+@Y8 z@E1hH^BeJhP4I2OKMQ_91Yc+>e$a2MV3A=LLTw_>thaX+|5l-U1kVsWTkw1$ z!e1tM4Uu{g7eg;1Oz_8w%RwBahCPKe6iR)3%#Q!?Mo5lazLVri_ z5y77bK0!oyt60m65?gTIfC&923r-jRQlZNPmkZVk9!Es@^NG;!X2Aype@tw*tX~r$ z|966a7W|8#U84OR!BK)^1*Zwl5S%Z#K(L;O_)ie*68CL_I2Nn)I8X2z!8-*X7yPqe zDr}p2^9&Smq2L<9lLYq)UN86)!B>dT=QU!&vOXmu{X95B#0O24f2Pnmf|CUc1m_7J zBe-0!R`3KO;@Kv+OWaQrJd230Zf=h_K zmenHk7NJieLe3tcFA@K1iHPSLM995O@J?~RPw4vvA0Z;X=LO#;BEFA_kRO?+=?uYK z!3ji!D;6v#-iz}=M8vy7uwLBP34OfaCUNf;x=(P2xSvmi{ELZqJBK&;8MdDsZMEFL*4T1^5b|S)`Ohoug z1RoK6Uht2C|0E)xGs=L-=UgJ_2}FdSCRic3LhuB^e!=qu?y)uK#UjjiJ<2YA+KJrQ}A5D>ji%#_?+N-g0W+C_-TTb#B|GALxesX z1lt8W1y2^-A$SH6;r0sd6ZfkHZxZ~5;9W%UKS*rAyh7Zc7yOOjYl3eJ{#o!NBEo$p zn87g+^vx1HLU5wsbRziACU&8n6!)(R-Yj^F;9W%U-6Qy4;{FT4Uy1uWLLU_TyWl?r z@#$nGXSCo%!MTD91Xl~5EO?RN4T296FF-yKkUx)#BH zBE}Hv+z#*#(ij)3b2`8`giaj>_nnq?wBTyNy~Jsjb*tc$f(MC{kPj&u3j}M4>n&?Q z@NvO+h%Mkx)z~Vi&Z)Gcza-oQoH{OOP*yqWklL zZxb)Ty4nbhFc&Lyz_K!lusvj*(ko7cz6C@$mJpHO=w_6iEGEK^mJ?^{^WC(|wWMLM zClX=Doy5ghUm{jn)-K`-jCY6)`dmEi=rYoz5%u&S5%u;X;w^GM7V`2)1EIRYr9{ZB7u-NZzHB0* zygG@ID(`aw-w^XAcqiavl-+auE^2p_0m%tBJ^$>xqjk>+3}1%k4zu%Xf$k zST7+WUmhSLUw%wPzC1xhzC1%jzPw0;{=Xq2UtT9d|F?TT^j<{NbegtzzZ6ysG#^SA|ijT78+6Oc30>-h%?2W5&!+9k#CQS|C2=I-%CQj zLPS2kCGKk1#!hp`M+L1S_3GrJ zP54}V5x(PCM8_icxiJ3|!9^8~tBT;;y6JFCl%W~B+IM{(V{&BPn=7qD#^vWZTvS26 zC zQ|RaWyf}lrgJbm`X*_JCKDN(`Gr&4H%E0$e4;ycg_wynT@*k>#sYgHYg!f@f&1E{A z6wfRVryE6iod1Hn&oL;Uyu%nMx!gyuKR2n#oXO=zN&0c^Ll&2h<@0hvB#});ll1*CkgPkasp2_&O%|3RB5>PopCniJ!Jc>`KA47~nf|4yDD7~O9j5qQb@6=j zVM~7yWxaM{QgAAEj+8K%LR=YJsmun{FO4w2d>eq+Gp4 z;4tY{{)bMrcppxM&ym39=U=G8KDI-ZfXia4-l423iShHLeNH9xq#dS8lPTD#A5J|# z@8L8IblQg#>0>>d#AItZ%n+7IN@6~o)L{R9ID=7nmHY;VqJC|*?#pvZP|pHRthU<8 zUyH@btq}Sp4yuy2cWm0R1xeW4i=n@|Z{4)1zvC2Lg|!R5O2W_1%8Wp`@O7*$9Z638 zJzEB`sSi?#U}$6&we@b}2RHoUH}~_)sH&>B4&Xz}n|2I9@V|Z?0ai@6)Vm`Xs+9kH z7yWqU zek<{#eweDM>ux~<^y4*vAMX3kR+MFtkKs*x1~L6iinkQ;X2Ol}Vp+qD7tTrP;M}_q zKXVyhC6H%i zF@B>DpKbTcyBqRMI9g?}0ocgYt|%cLem?YZM|AE<-*O(2so7kNpoX zBl{Nt{XTuf)2~SQ81B=6eiuQWkwJMzKfc3&IvDyg628ljc?gVq*AB?XcuIuV$mY8b z{P~yusHfi?@RE<=_znchHu=Z3StA3^u0BhI&*;asTmNOqZq4WFM?S`5#tBAtCvN=u z<@xl(61A(}eu>xU_w_^QcZKj7{cbf1iIRrAU-P;8k&pV72_L-Gbsuj0`pxv|cMLel z$8f1w-=}P&-vJPLpv`6Uc`YEX+$XOb%tqcnaYK0~+><1Hmm&G?Ox(NaARqOiEMAny zYZCbU>8SO^y9oX!-mQUjJO_ENC<*$X(WfRLZzJTL2$oy$tH965J5l7Ba0ko{cz8j) zy5yamZaT=vbWj#AlaA8^@!pSkO?yx&d<^%KKsvaVUqC@}88xmC$a@m<7@p~<#?PdK z@6e#GCfuv$25!7eI$qO!ZaT-j6OVr;7`Y=kZ01-06vqB%SE0E$9FmTFOv?wYXtXhI{1zn%A+h^CLQ+% z;*I>+OGlINF&xi6P&U}rRStO{%00p8^V@*D9LPHn{~vn-20(AIjoo(s5}Z-Vc1~I9~V|?nQ|g*{H6?kk>Ew1f$Qr0eO+f z^!Wm&16z@9I({MYOt|kJA|3B)J~thAOFAfvmr2K;0`b-&UQ<6d2_MsuhJVZ>_Q|~N zhrFxwt@=+t{u+eOq_-J2cbm+GzlnDS`22RT5%InRf2OxX_!w`s$TR6pp`-6IqEFI% zZhFZ_R?6aK;@tvAf4rqX@zUEVd<^#k{G)7>j!e*|&w{gCZWqDbFRv2vIL>A|w&KTl zDUW9dD9@yWXN&xoNyjUi&rJvU$VyqfOgdhIqd(q_zI1F8K8AC^MA@d?_%0xG4`<~^ z|7zhg>Ae7a9CMk=-11#O{&>3)FUMj`FYBF2Z@I`b>3xoqci&~w%Xb0c-c2w0s5fQt zGVyK*#2fjUS8iNCGVxv@@tSnJ0(nLT2MK==W$qzsy7EcV9ri+(YR1`+$Dr zqkiWG^!sf0-s;M z0iS-C3LnGWABcA`TM9Ugwg!tqg7m)Yd`{?(Fyc_T{>D?jnN+kSKr(k?&2)I!me|rLav%cxg@fg(bT^!JF0DRAx zN(DZ~%Zu+!^XvD@2RLU6A=K|{_!<4K0UwIVbl=wU+b#9|H_G6}czF?h(O7%I$M;bo zdUYO<@<6IMAoH6!;SE8e%v#xIN?-KPG!?J@<0bTsS3mGp*<##1RQ3Qv;`ywU@9dfN$AcAj9N4vdxRy{b ztUCLd0(Bp));O*xQf(c4VNdL(?Gs`%A}=leFc$vH;$ID$^4!b=54?5otno!to-Qr= zNJ2THgHM<2XFs|qZWX@y%*$J?!q=aE_M>+|z52|xmlSqhv*eD43QwGI;{Uv-QCMjo6TK{4IqVAi*xbvV+ehA3 zQk|k?{C=#~eHB7{uqO=u4@+{daBjcx?G)Rd?OY!EYFgzl{us@)kM+V#tNaAzw&;Vd zyXc`&Hc^KXmLd-Mo z8rC-*)~T-pcg)y>!ym=nU7Na3+0tE%&$(b1dwa3^hygZr2YP#o%@(vKi`uNV)}Cnt zaqz{}9`w=oIMwOZ(|?dTDGUoJQ8s0d*ZFD}#Ga0>T>Sp3tY}RrZe8iDq=w-GB@fIz z@sl^Lhh`f^j6S!8_GI3ZULARFrgb7dSxWB6dl&ic-@*L@Z)Gl4eh)F&fdjYhv8yxh z2`^XN%39;qnPS!2|D$`-ZKpbV17(e@E~uQKYX)MO4eFgzhAbF6U%3{bW_+Ylp_Td; z>V-YM45=LZbY%LNr$hLyoVanx#){YN@chv9g6gXusyt{%Zc^G7ROh==bp47?e*4Wm zlmDploOR54+s=IYql-|FwS3lDx;?zrtHYY-og^MP354R(d;h*N(t?KgkI!!};_u-c zydU{UG-{Tux`O$aqO%_VON2NZz57;Q$jp>s>#>uT85veK24JW3VVvR2g_ARV3^mTQ zqg>T-_CSy`BbTjYX2_Wu2W6q9cIJ=WrksZ5Os3Nm{9Bc~hfWdaW<=&Z3SFG~u~#am zVLe&!NpaqX<1rD3UtT}HO?6Y|WvG4PsT{D_C*Z$rIUDle zaZH#S&Cb{G2A!03`&~vmuT`hJN5{&KXs`l8|~Psqd`_`vdNAWF>IA0 zqs?~gd8n6Kt$o+qu`e;~GEHu79}2m{T@nF=8hjAyYPHy~g`qWJSse zBUK5Ukb(OX_5I1{;ZrunyP$Q>TKvoU1&U{KY+}k0=*mMi$oE)Wva230u}SHL$dpKE zI&w93q#{y6zkmV6rl#}dcRIUbM@e>FO}2Si8&r1nV1y7mdiV>_CpUBkj4M{Ah`d-a zLdNE2P}7iQ$DV+x#g5Tr2suFCV-=Yhv16B@2x8@mwDG)wvz*Cn&zlDICZtY9T9+^n zI`jBVx2*3UiA9vO>XgSpg!;#022e9<4FXu9A3|zctt!b#i0>s%s~^Mqk`wwXebyWy*ZgI%}QntpQqi(k%tDDm&rnJLN2}qAC(N^fI@J^pJ_8{Vkgf2#;>C==3DWMH8 z@AR3X8=q=RFBaWa!?e@qDWXgnWBP)uTcODEPzj|iQX15T{y+hh!)XW&q1i`*s8z&q zmh&viKcy$H59&IPdSSYdk~kyDNo9caqgf^*oS-P24?jw)4m3WEIxyi zGJIyr&q1X3<4Do)Svf!D08*u3c+r>&FhnfpdibZ@I+?FN&*FQjOH(JNT!<16@n!3& z@sS^@%E>q7rsike1Obr{UuT~>X%wF>O9`D%pUIhjN7V5UKgf_eRhdyiC>KSMI!zHX zLyK95r>mM#65|?8YM~-Rm)WsB^qZl{D_~J1XKHev9eW7Mq|Q=goA4O@`NqBU8=<5qeW z&R4g{Ii5lZPYN@#+{|zx8{YI?v#sz9!;AZwnmHYBoe0lT_bKVSabKkF(=F$3D8g`Y z*kLn73C_F7&XLnIzl{uuZlP{=%Kd0bb56v4Za8a`dOv&!xt!IeYKIlN3RNYmT@f~{ zyWPs_P(;Xb8jv|zo5S4S(4AD)o(#4mcG*z%vhB-Jnjw1(7N(;%XQadI)9^pV z<{Pk6?H}QP%tixlW!QX&T$X(^f@a%4MyMQn7D{)N{WWCU2)hEsmud64w2}63@Tb{v z{7<*%;{R}aB|^pRj%L|Z^59u4z3-Q4u-wKU`L(_mBC>$I_01#O$H^{*kil$7!82eUUQ zkIc-1o!0Sm&x{vzS|_NxlJRFCe0D-}EFRw-0(GLM8Z74%)SK+q@M+-5&CNb_3hYAJ zRrVKrc9nga;!jt`oPGKza%G0@M5$z-p{iVt75xdKjq=s_3!P6G#hKx^ATy@~F3}Z8 zNtCT#bR0}6(+<5&S5}WG>z*#SoVx#qw>N>Wt0?=&&)j?N%}s9ht!bOKH%rqkThnyk zk~B$^Hci?rrDaRgBwc8lge;{kOUsUm$gW6{vg3vzpdcs}K@kyA5fL{~UPM7aM6Js5 z|9)qlbMCpf#pV6H|KCaGe$UK2^UO2PJhPrH^<;m|T4U>HO*ts>D{$puz&`4+RiXU4ZIIP<)|WNDbjPQT3p3N$MWZ zB&%A`q^lFr9c8HB!ca05w|=q|Ulg0IT2cKuY8yD`s%J2!=czA8@Q|^(7vYoC_o0Nz zDgl+4uU-L%De8|9I-(ZCPzu!lK*B=x2jpI)Nu2AQp>DDN|z_nI|kZ+xO8Lhis%|faMwH)D%YCE*i zq+Ugdn$<&4@EWxrxvW*Ypp6#wSCny`;-?GNt0K(3HmL7H8|`W@?4U!ffmS=!O9lZdIj-?Nyo3 zMxXjT>SCMnqb%FicI3N5r6Xjg%0ZuVnwpK@U1}Q2GN6{=ceh%C5)G)>t)RSEy^Gv0QE5JGFsUTe+DDZ_?jKW&pn*%(QW)vS)i0od57Z*$ z_<d%H=x2`7gVpJFbV2W z2p3XUBQ{a-&G1R81j-GoaimICHK0jR&!Gxal?6f5)IFe2SL-1}hI#|%nQAhMk)_TA zO}1Kt(K|<-06}r5B?>b^jYFI~^=qhUqT&}1CaD(@K3RPP;rZ%2sNgB;AQU%M@jbfJ z)HhLi5p_M}EKr|AfeO{@2rp7k!XS!O67rg^?f^}R`UA>1L;V7=GgSh9XQ^L7akCY_ zCo@O!ao$q(5zv>ZZ$l5|Y6(oRLVW^;Ua9JeX!@6fPnG%>&gZEMAxX6Y8#I6lRL=tS zTQrP?>K5=^q+UU)#i|ujEm03bdrQ?MVP39@R7Sbl+95 zrSMqtTaY>1%+Sa6(~$eogYE{fvY08j4JJPKeX^QoKMi0;Cpw@42MrM}z6=Q=bnU739fAb8X5zZY_dL{)YbLJCd`XO% zspq#fzHgz;<<8clNR#hVC_?U>)Ebm@ZSv4?kCj`dJuOLB*@!96;oxQO@FlH;LUSwi zlvNG*lK8gV+_}cP+m}2#K5XSyO=h9i`_2Hf+{Jp?(COnPh}@-G!am>0u%z7O`4@p~ zhZP)04nba04)B{~xhwp8poi>_Au`B{4syL{EMmfxR8ITVyQpE>9xY-I>=84iQRrqu zf&X?yXZUs_Ca*lW7>2LjfdVX5SU}oV)TdAJO(eFu6#|9Svp7#z_n=S_H47G8qn?J9 z987s1^j3OGY9Sz!GL=x1QcgISaxtv>gAb&m%3B@0hS~5n$5!YEux5Cy&>i~3XN6`m zdyMa)Lohq!i}zEY@u93%=xwsY^`KBYGsA_O(05P>^hzj#?gaBrPUQxGI)Iu|st+uE z>IU@swrW90NUhbvTSy&IUj$)|`Z)@CFomzuuvE$yA(!P#NkB8P{3&Zu!@?8)CL{j)|5R`8dvp*ObfWCDha>&3!A@=GM$bO+N79`ErrAfC!l@ZcJtkAd6 zZjsswJ+DtJ6^bxpqz}zECw6EN4IJ5r)|!*_(9er>NF=n&gw$98z7Rj}pr2YT{{hS^ z?}a{}V*nE;r1Cxd>U8Q*r6X3Udy$QkZme0nt1T~09gGdm`3lS+<0QUr-{$>JHg`1a zn~=bq(OYL_9Vx~zb4m(#sQ4y+n@d6aqpY`_r|~;!$&VbiRu*5qK50=hh5jQ$qeaN! zTYBxv5L9Eo!7Lu+&s+Ghs?LA~=Pg#r6m}X3_+tgu$#D(43DzApf;|y}!xkIgr}?v9gw;2opwAnZ-+t*EKZjb~K7<2NYlY zZ_1Q20sYUky@@b)lc!Ey^%a=Yv<*s^BI3kZS-ja`!e>$!AcW2^4RT?bbv;<-+!LZE zH@Hz*{BlsvEjpAR3or??{(`2H^SKPpYR-;^{tdECSfH!*Qw)t7)~Z1$M%7~__H#tc zdlp5jSBrUG%@Lwrwa^6Wxf`O^stg)N1D{8D3lzoB00N1l$jo$lmBL)Dl=j zbl(`lSWuRJq9=?K9ok5lC#(cvG^E;S*tAN7(cI$HP_PS4Ry~lS(ovC<`f*xJdz`?+ zsITc6Mk-73kS;|kClL?pIYcT8@`x@->fr)>@w0%nK4I((OFgCs&_~VU(96-(xtvDpLMQ_`lX1m!r&*-3D2K~_I?=!DTPyq9)oO?DaBEozKl6G=FL-JiC}8!%NsQ0s{>pzCM-aB2M9L6CCrAW4=1O> zrO^=BX==kL^{Wl4(y!Wmp)JCV@jm{L+cklG4z~kHe73`l&qI8a+&K6PH~-kBDu&%U z3P%FpsrXUX23jfA7A?*_NX&=0rcnvPAQ??e=_Xe6dMqcaXgfx~^HTNpAQGU%g61-y ze66PQ7Enz;1G}HVmD0M-Yp2T92CcITwa)&ExVPb~qA-fK-(|+uq7I$vFx$V7%=l4I zuIn_j{T&`=XKQAajDxd^evf=kcbOTqv(q@ry*_|nJriZ z6Wxpxs~%1rs>duqmvHlJ^7%Mu&WD@K5^ioJpNDXEKU^;RuTymI^=q8{3@&jtcyNf$ z1Q*u!IDR+yLO0=2q<5O{}>(cvmopTeWM47}NvrNetp1ZOd#1oe%E;I9+q= zwSI1Z_Zm2ULB`@J@+TvAXdDli78YrL0rfHr}1 z`UG@PAE3Ai{Gv}aJhS1#XTif)HJ%E$o+;Vi=$}?5$LOl*xjOp@oaXc`obWY{5hlhu zp92pMzQRf!T3HCPDG2%>ki5h+v*5{sM)r!J z9VVPwTnML`@SCo@XM8$^jF3~997-_Wa7#2yPN(36GvE@A3~NBQ0`4W~D!c;$S0RRP zehiPma~n=>q33LP?#9VoaEa^58^**T90MEi4Hy?2$RV{f6PzACj0{t1vr@oH=RWJnTYmZ@$NZk z55rfCN;4WjBa$&}2gBJYAH#{i96yg|HbubeCkQJApV@E;--TxpP8PsTCsF=O2+@q6 zgztEacQTw!~(@+^(;dvFb`G3_) z`NcUU3boF=&Z`mgBxCqGI{y`~pOf|&Lb<+R!S>*H1Es?7?7!lvb1)!XiRgNX#x);C zKgDR>StNc6>^Mt*7c9wu_H!6vTuG!CM8obx7;UOp!p1;%H^OLBi#%bkB8`)d_qTfkzQ|0DUAaB06l%u*Cc3T-7~__eq)38FDOn!u^n&ZKDA2DTUW_27|;A1+%!ZWb3P z0X1l~bEM$W1g8!q+z#(v!6y`A8_&t+;oyf$f1)xH$p6*PPtko>d9OH-Mb%7&z`byk_N|)-I+Z_#}Pb6B5d5^BD?^CP$^^hMG zt#Ein*pIr-u+@r!gfL__ESORvXh&d4Gf4-EVlmBtH(Ds6!K?P6Lg;!*oUTw0 zQ?rm@8D{U(Sp4(UL~gQ0m;feFj*^;k&X^bpQ-(s#-_5Q_3TK33*)vpTuqJQ6)vbo7_lTL-x<343qnf+G!X3l>uM{=Lgf^sHfNz; zA?qwxm4U@kRn88hUC(i|B1cbVrLhWu63PtgY^UDKbycuP1q+(9R-%G#8h3 zB~~EsxjAZvE>x9Ah;X#F=Q;UE0jlBGl_mc9T9;Z+1t~KodeyYRt3;N|8@bS=^HIDB z%q~*kr@|JMi}oC4FV0ZYQ?p>TlT*7UWT!cG59?XyN|tF6`23TR4oaMmg@5R}m|kb1FUDRu*u+niNBk!c#eOIT5B>s&K|MTTjR7>3!wu#ak!bh?j{ zbnD#&+OEQz15C1^32R(wEA8HjK#%Sw&^dsd`F0)?3hm8A*BsExa(Hl{U*jr0pw`=g zsw8(K=|%=yLB`tHFj{YC=PAwsokNl(ASR(yb=svBIIF1iFt97DRHs7@3}T)OUg*bd z|4gKqIR|HRO1&vc%OyoHUDGCkB2tKa(bjM{p^3v*bukxLrFK$^>L5vnA>c1I%8@MO zWvnClBT^@;4R&$~WGIHC&fjU$O>cSa@dd5r&?NH--1L>0e zp)EH$f|`W3|Mb!uZ95Ec!pZ)z(i^#(&ypEhAMg&a9<8Fb-GUz*$wZhqSjKgbJ2IyklFHPzno8mz2ugQjB<5dmH0wXW3DNo$56fXt&r!0fkm(@w0*igUG zu4_k7`z6X7c8R)7A@nkZn+)BSc%yx#x{ty4spoW_(nHwK`Cs>|E@aA!-)x{xH^CXQ zjk}7$!ffB)XqS(8ePhr6OW}jU0C|?Lz|RVu*vWQmKZ5q3;}!6n!<6qZZq)FGKI(to z$QRX1&~!Sw{vt5qlGE@rFoK^w7b*OH&Hs#FZH&^(S+GQxC>Ir%UxJ^KEwH<-yKpuz zh@ZhRc<=UqnPb40{onRGy*(EbVl35A6na#KRO{%_7My~Yqq8eDZ6S(L_%)xm6c76z z^ZG%?Blv0j2=C_fN-+cfRX$9}ov8Ybl?u0m> z_8szR;Ti8lhMl2GckZ3xaT&SjWdd)2BhzD=uU37gI>F8?Lgz+tgFlK!p!1R80pUk= zxbE`OZ)XKRhkG&D0luJq1+V2tyh~Qch&tR1v_HIs4FYmYvY_)*m+I5fgm9cX^&ZG zkA~E-=xp5sH9-hXW^6PS$tRU+0|{|ynoN0hJbgB9J>l@{$&sV5A*|tujQl=~a14=V z5N0{eQ6+eCoS)l#Jemx+Z;RrLmB#`Ddh?v8+;Zi?ym>f&p5G1U%+Uhb@Su~h7mV5a zaj#u~kuYf6PPS9i?aXW|@URmSv_q+OdZwM7YX!JlM6yuGPM(DOZX7S}!7+LZ+DYm9 z{e@N)w!E-0s(;P->wfKN(!ZtpH&6dA(7*NiH%b47%(=A~ow(oPMJ}KEXKIS2aDXeE z!anT3dYH*7uh==*J22kY|F5Vj%FFrRJ2ZlKT>h5{m~i*b(O%-Vp}{d?-$>6HPWb;h zLoyy6>%$XVR>h8?-Tf6k1LGBVXXoIyo!cu`4WXo6qx~Zl+XsfW_6&544UP0{@2?o$ zxqa)<*l79i$Pga(8XO(#85pRbr)+F!XrOmT&(6Uzya#lAZ$;0@?y|w5!Tz%To~=7w zUF`1Z-LZ49|Nmi*qx(kxf5{DctJvP#8&}S`^UCLy&vlCXzpk_6B>Z0+Ro~9h;enog zjy)ZRHO=fe!N+-~??0nrR`{pHI@hQGH1PiwkK?tB{}rPTDXSLDI_8N*^b82YWuxxV zv3&#m-P`*I%XhH5MQG1Re-AtuxZuJ2Zg&oDhZmi2cVGXup7DXP?y-Ht{i6uOtRDn@ zct#B#bUru-3C__iA+1A(?oTos9@)94XRIF-CMyciJJ2&a+8vF-5*gGi4#?0ki^oHO z<+$+EZ>09bn6#ef06lT&B9W?RWTa;w7~@jA!+7gBMaI@20tSXyR#Wuep@E?h*Qc3w z_l@?tv|4lUnc`_t;PWunNf3m4a=h{)#4Wvh?vWW`Mpjolu~evrUi4xV&8Ww%MwgCN z=qY--D}bog&A)qih!qJxHX*D4(ei)Ervia2rLqGmm=?${3Iu|cfrOw6BnCGJ=3-b= zLB-!?0p(AQAlAP(g7|X87dY`aKRFN%DxZzPD9ZYB%^G|&kgO1x9w;gdB$NlH1?L13 za|0O{1hRrEf+z0Q^8{GoMMj(?0Xw}BflU<1e|jWv0#7yswh+qr6M>W&%7=SlJaYUK zo_khDOnEG0NO5SSRqXQ2YY<$+vtvNreyh?NZ$CIfm|4Dt3H-w-RM4M=y7BK`7MvSM@n@oB*-k!Ss96Vs zD_KUv+4cn{`L8*!%vOQvWbA*a^tcb4vx%{Yi$!^@cc*iqZv8 z?H(*A*P#D-OI2nqKQSvSJCF{dgf&n=g+3)lf~p{}pfHdJLxS>)gIR&akwD%w*C(fo zku;|ukXR7NTf(@kKwxf`VMv`o7!|9+PPLz8O*d9yUXU?=%LJ$^_g50JdJSDg`m>rlnHIPymm{@qZPLG4(T*ri z1)F3*TY3=YME1ut(Z}2-ibh=krYKjAZKLAOJBOBmx)7b!A($rLg50zGPYJg0{+R#B3pM1s>0`w5#b*aj|MUW^^Ew~0-mQ84qarkn_)cD zw`}ZQ)wZ#ry}P}kqr0`O)A%d|H*9QZ?d)!D-B{bwTwmMS&|TZ!P-|hhU(`Lu_>Rua zEe+jm>uasio%{Pu*s8Xcw)XDEw)Sb+ zf1+Xa?X@R#ud8it?XGKB-Q3EE7`CfZf)*pvbsUp!8#9qMj(h@DO-A73S2v zwgM(H^}4#fxxRZ)Sf49sNC+cUWfD#m^*=RrCWFhF@JvLu-Bay0-d; z?sZ))oz3f8He1fu9xU8G**~(UzpuN>G7~D!RIJhA{@!kWHo@v2=;xOex@k|Anb%0I z7zMO9G}2BtbTxG7;(0Rb=&I{%uU*yIyiu3X2&v7~Bwf|i+=B8n)wZr~sK->5d>svP zUT35?MQ>_oUfrZKaI$T!*A1k$ezV0n6ca=>Rkzw$Ye#3>ddu^9x$fSr7CtVADelhR zUERYy+U(ov)^s4())ZE!AMTxQS){S$kEY6>!nKZUEZ0cT(s$h^2Yc-N~ zwKqfqTH0Dycdth~?m!XUimYpEr}QT@*LOBWY1`Y-FgHj2q93&IP9%nAbUE2(y_zvb z(bm$nuC*Jz!s=EF>)wIB5!@5zBrz3hG)f!Qd@#v&%+1q3v~H}L3*#7JLk*l@?$3(oswAa=*cXe2!y(5wkO=nNE-0NyLMGI{zwxg-G9>&Zr%T6ucsVhnr?mQL8euUpjT>!V=s7( zbocJ)M=RnRcDy!#w%5F_c6CE{XLF0!=+|M8zyK1b?U+X9^aZXZh;?WpD#p{h)YjKS z-RN4(dbt;sfns^PU;X7NXACj5q%Dh`(%NogTE@J!m14tbu)i;Youv`WvHy|&Z6k)K zH9pugpeefbw=7)|qn$FOWFzcYU#ka5x0+gNH@9_lcI$B~K2VQbMmFeeHQG;ieRDgS z+qmv%TykT(>@3ab>qejtS=|uNTmn7JIii_b=`e$!$CK1(ak=p2XfV6GgEqutvw^%yRnZD zRa`R$xs99!Ht3>t>sM|j!>Z1 zU(3QM$~&T6BQ-N_t)?j7y4nuPt!Kg>?R$(*tJ_4Ok?UD6`_A5;;hx@|WBaV(9s4-j zFxC*wt)oM>77-T>z^?nY~?_t}HZ~-8=ix@{F8RttqItw{7iO z*In1u+``oYD!pxeM>KQHak`H?$!R`zZryzB+`74%tYSLuO`QMZI3}W5Pp_kv);m6e znF*S6&j`wb*=JARY2%~(Or0Jxd$wUfavF+j3g{V4#cmtu**+St6VLQ6T0|(Mp`o?A zrLDFeT7edwIb!!#%;Sw>&1_cB8jh8_x~j_3^)}Mew{v_n+JWfZSus7Tz5&CKQM}tH zdpm24_w8=}(TUj3!JQuSjV_krI+p0*vRN7dlyYq2_O`5eGv%yOPfJW!I80&8kco>a z(y_Uc8*{Ads^cWd)X6dGMx9}zt|tRgeMkEXjLX!xnSF4+EX~&JDzn^d#Y|}=HBFao z286oT@F>Pi@`Qh2 zsAsGUSEZI?QqhNiu^r>Pw*q@cdUq_xb*nuK%X;SQ9-f0a*c?y7?UAy!(MTC~@0V{M z9Ix6NDciPfe6V+HCs=d321N8WPDH%^@xe284)&Gd+t~wn64TW%TR(La4e4Z`tBnqm z6-=;Wsz|HfXuut~yRm{~@@O^d1$AB9rfxGui}Kb}ti~2hMuls1a!!N8Ds#Kj@frhg z<~@3?hBT&;n3XLWD(Piy=Tkn~PpDkzrIy&im`y zFg~uc^g_Xzqq|w41ZXy`t6}I^567?UF>-k3y>6nIhA$f^rjWWJa}=uYSjD+|t!LbT z0^I2~$8vWNfij}lVw-Y1AwLyE!9vRnyW?YgXaj(L{I4 zW-a4R0lBD=&UkdNXBgl6^!oH@z8>30oDpL1KYquzu5BH*sk+wD0(1dPm6~}}@6gal zA1*IpQpb3&JkIDg(7(;o2bg6sGHmVOgul5{FGkpTb2xxX`ulcjllRmvEq+y7s~KZm zed)nnum7BxYcz>gx;uSvlQcD>JJZv7Q;&MRXjc3&1E3lIEH0|G!HnRF5H40(Y@%lG zL|?)l?8Op{J1Nn|2}5jYXza9(H%l-(0QFF{XgVg(uFV@gR#e;CypC++n&>+2e$_R1 zuEQ=IV%>suwAQX)AG;RTy@FX0fb!T;22%>wSadK)9ro-d*BG&|RVXtUy;Ww&vG3w0 z<+UHRPWz@-9G#7m<0s(!%QnPOq}hB#zxG+y%X-(h|QM!@n&`ndKpehbW^Ft@)@e)_eovh zw65zhU)7TXT;%K?fG)5j%gHo0F|fQIja@^vb)kj3Q$&|hEmkA#ZCzL>c=ne#yNsRv zMYYdeLQ_Il7kZ%6wlKO2GgZBZLQ!1;v^}g#xd*H_Q*~u%P3!VumD0SbmJ0!-ae89C zJ!f{B5o)>&z5h~I>zz$=Akx+o6_C9EO(e?AGyqJ;^mS=ZI3+@zqpW&YI;Imtjk1rx z=C*8lL}%fMGBcn(xDiDrgWi6~*=u1{I(<>RiDNppzDdtnn2QmOo5W-N&h#cW#p*h2 zkJsu6vQZHxsF*%R3$wAdrHjinvm5HxFDhL&Z%G=%vjuZ&PP3>w3Zds#p8hs|)RfT) zqodwgvRE|i6~(`_*R4dew|zn_Rtu&grBmzXJ9&_2jLNuQkL47CclYn!-#;=GEgAB4 z=HkN0EuFL?ch+lEqxVZW_JS^Ib$Z63yEClwI-w@-J|0Y%J$`#Du3ALD#;oW1x^9lc zO7{;QDKSxpEy@ziHJ0vPv|H%d)rxmV7ZcF+s6|GaRkpL!8%>V&zlr9^E?Z#Sly+4h zRf?4wCaiiI%)YR1XdIKcC{=VJz)6I&#bo*@%pde-sm!6H{j;$SHz$r=$PFE3l&>@S zlC(4dHz6 zntrCUVV$Rcmz_#Yj{!$^tew#{hK;^F#pP*qoQdfxki)UVT|0(dEdM>*6=KL;t+K3i z_le^78T`JFOI{20e_UvN5E~Hl9|@ z+SazZsBS&YR<28-QJPIBJ>$X%r*9dGZ^CXniBTOd7;^H@z7V?(%*F__4*LqG-GaUD zb=)foacvg68>Y36?&?3ITTdZPJ2zJv&D2!$)w@IujkQ?RSz|k4|HC`?4Cztx*y{0^ zP>jH}EvVL$S8)sxw@*-TtR~Ty0+ZHII~0ym%MnQO-q+yZ&VF> zAa87I?R0u!ZW;HF?&uzM_SBpRSHDJodR4}$LA*elyEa!@eULtyiFA`4D08i6n2+vT zcC4yJ_Y%J!sJE$1)Mi`-<9xImL)3toqPjI1T}DN(I@88r`my6MvWL{Ga52j%lSf93 zQ>)F@tQhrTV$AEpt_hlbPiS-)it5K^5H^f?`EHyW177<=&t&?X*bQsUa=Yuh+Rc^* zwKOu`i#tYnVGjj5)=ZpzPq#I*(XyM}tE;gN>%j#suE&V`tkE6Vd2lX5xgzQ1 zH=1T^114*{&_QO#`sGqBub9SXV8oFtNqS-f3YVvDYS>HjGSh8b&%I=8z|oez$RkT@ zFfqZLrJADc92~?BA8tMv^6b5KV6cy!+`4(oq@{sV+U8X-NUk1@-q>46_0qngGanPp z0hdFbjJCR`#051h`Ek9z-7F1_bb9RKjNB@YdGuao$j%TLN zb^GwR4iF8@dozVoB(tR=dP9{(uW_5nM05+w_ZxruSDL=St;trLa~rX1YCX=pb?tkh3? zhgnBRR_5LnGdaT6NmOjNg>mL$`jURVy4H6uy8`f}_tHlt7V~s(^pV<$Aa<_x zRuD_-*1ss4m)4x!Fc!tk-`y&6u3)-S%TN)mFn4GJNzAa()ry(n37*Nhvz?A^F{*QI z$k<`x`onAoTdP;CS`wLAJF+{%z3)!vc?+`x-rhejH!`zs95&1Kc930 z|MPn&Q z4z#QrS`{IEX$JItV>|L8o*b6BY4R-R0a2Dj>Gx&2k;tE~|A`)cYjT`Cczc}Z z@LN;j@}FY$AfEZNZTb-JJ^a=*uNV16;`m46;tS*W7i#)wJ1>l*_qJf_b9x;A>2dTk z;`q;qi=P$epB=|~Te0 z{K~lWE92s89zdg>+7n?c< z`C%?pVx0fa;%CdwuvX$rOfGx$&Un&0&aYoBDkO|wh* z)Nd4(Xq~=4F8!H8&z6vB&9JT%KP@K{z1rvF=pTvmKO^)U_cYGBH-A`x`cRU+X#v7o$H;i z*pS#;mtx}F%|5d)5EB=3jVA792oUO9Ufc%^5D?wR&}%e(rx1c!(&Js>iAh0?3Pb14 zUW7zTWvO}KjxP#h0^ zzplB4H{FNCnv1!Tx6u`wVA83k74bE$`sg;Z zSH8EB2fr(=k1ZxV2~$@FCE>YN&U%u1@Fq9nRx@{*+6xa3zUW^cTM&nnq&_o0P3p&s z;^^Oo*Y6UyJUy%3*h&%DxL&2Acr&-n?h`TK79pV7L z`U2byzJlyylLjq|eJR7AC*nQloM-xm%{#KE%0SC^TI*wr=>wBS@b+E=B#oMRp)X=t zHSiPJ$N5_EW(?re)A562c7Z`_i|7mC>`Rk?Gl4FhGgSf|ifAQ`3;iDRl32>cW41HJ z*~0!1bVZgG5hOqQtAMWj&J<+}UbMpaeIoyUyztFS=S(#~$78lLHQ1uP)@&Az#}@r- z&2Bd6_3%7w*GlmJQ~XIj6F*UK zmf(EBT0y=YoP0J5@@?Ss^XoFi3k0ta{EQ&SaK=9%__*MY1o<9t#=jx>o?x=ygy##+ z6f6_ur^}eGQLsaBi{Ng-{el+@UM+Z&;9Y_b34T}bCxX8bd{gjU!9*A^^UoD5608(l zF1SYU1i^m6(*^eko+o&*Am1oW{+|-ORqz{vPYFIR$hS$8{%t|NOq%{=^wC7Ty;Ea} zAYK@${WXGZf~N}Z7Ua9Anf_A2PYK>8_+`N(f=>zlPVgN;g^r4R__YdRL~y#`T)`EB zYXvt6_6v>(9u&M(@H)ZU1@9F+BKUp5e+aI`b_wNJFW4(MF37JMGyVoazCxP*hXo%M zd_wSP!Dj_u5PVVa6~Wg9-xfS7_`aYWGWjG4rVHi@<_i`I&J-*ctQK4%SR>dd*doX` zK(joX1Wy(06Fg1ubU}W}jP#!oJR28y7|S%K%M;``Wa;O3VTnV6bK|dxI4CkBfiD`oTP#^u11q%dc2$l)X z6I?9FPaQE`gWy`h4T2{Ko+8*QxKnUQa9r?A!E*&K7W}y2Rf5+E-Y9sR;O7PJ5&Wv) z*9E^N_+7yt2>wLy=YlT@{!Z|Zf`1nLyWj_cct3#F1K;mTePjso8$a|<5iAnq#~c~X zm)jEO3oaGJ_OlLOEx1mwLvXWTw_v{@U(`!}rwg7Tc(&mAf*%q5gy1!T*9+bxc!%H@ z1@9GnQ1B7K#|6J9_(Q>;3jR{?w}QVHd{gi*g8vj$m@u;(34$qtS%MPNI zI9G6?;BvuLg3W?$f?a|q3HAtX7u+p4D!5PZfZ&CKpAo!O@NJg5MT=O7KU5&kO!a@MXb22>wYhKh2bLmEd~8Qv~^eJnG>L z!3zXGBlvm22LvA%{E^_V1z#8ZyC7d_OuiAp3c(eECkk#C922}$ke`WV`mYHd5#%T1 z82+N*D}t{JzAboE@O?o$!=y_ROc%@*oFZ5(I7hHbaJAq%!Ht65f;$9H7u+v+zTl;T zw+Mb#@JoXC3qB1Y}n}YmgF!l7Fpp6AH{b9jO!O4Qff@OjW z1Xl_+32qQPQLtBVKyX~}9KnkPuMoUJ@P5IE1ivZx9l`Gl{#fv5f-efbF4&4a7VZyp z5K+F<1kV+`L-0|-9}B)An23cs(@hs_5bPH`D0o=#9>J#seCO@42l=?abdAJcC-@nOf1J1p-|{0iV;@lBUl;t7#J?{X!iE*|!>d;{W)hJ; zpIDE1uY@laTp{sm1-m4CvtYM`?<8X1?K}y;NbqA4|0%(nC7d6|r5s<7@Oy|$@F^Gx ze_HUzM9B9`@xLVaiiE!<{&xibPF#YIAz=@XSSHv&1fMm;`S?&e5&3Ty9FX`u;@>ZL zK*B#F{*Mb@DdC62e^~G~3ICG#?-k^y=b8Vb;{Ueb_lS_^ZNbcZm4#0qR- zivKhsvE?-tx4I3PGq1mBCq&+l3?|EmN)DR@}$R>98_k?!k)KNNgL z@HN5riQwm(W-u(6CYUFfFF0LrmSC0O0>PDns{~sF*9&eIJVo$a!3za16TDLJdLqhk zm^;NwKl{g{Y!?+E@~!b1^+v;G8g1SbkkB_e$(5$V?nwo7;q5$XE{ z2L(q2&mtn-wSr#|{GQY0QC@}QX1s4mp3ib+~FL;~a6M{b@LY`j={zk(8ESOMe z_)iur5u8UvyR0XIwu1;hCkSp4>=WEAc)H+zBGMfoLSL6l_|<|p2;L-kI}vpE5s~ge z@qb(5pA`JD;7WyK zfr|y}1v>i}2UPA51iK*@6(;^0k}mj-2P_(GNXFh_IWPMC4yd z1fNAj*hLKy`fnnl-qsUQuNcB~eQzPwTh;u~dnh%B%jYz5yBpN%2;NMLI|6N4L zb2<_7oI!*dM1w_z)lnDCEiC}sy5%L@&LY|w6u)jNr$m}j6ID%uuI41r$5*(N2cqR4TrSxyg8$)`WJmX4z z4Eb@hH!s=wcR35ye~_t%@_6| zuZ6``TP%HCd;Jhvxv%KI;O?aO&-j}=ll}|#P6E^7Joo68kC-5Dqm!VxvY8v8be?_v zTgSJX8{W#zdC%6ZBmH|!n>8VL%#SaeknU2b@QzMAo$DnV8Qgvh89wfTZ=0ATkjugc zLw55`oZfWX@B$JLQC)mn?M~c{2FCyKF&UKT`Yp}}cvKs3e;LQ40FLLFcIo58=w=`` z1o!Xg)_^8H-zv@7{9szB500OSa5dV8aS;;&^4|bwi=)2=j{KZ-J8+KS);&ne<5W1% z4WFldmNf=sdMDn&6A|Xk_fF)?ITG{5R6)}-9r<|6aTfe1!#Rf|&t3$0<$K;C5M&&W zPs4fTBOUXhEIb_fIN$NgcLegKBaHH4YU0ZGQ=EI{dlCNQ>G=VKd-**Belrn9ew@QG zU&`@)IBz*J9l;UK!|}du&RsocBZBG4i-%K=S8?vm_o$~FERU0KCDN0(W2gD>@E#`T zaQG!4%*!tX#orAgmIGVgF254cF}YJeA;(}5#=~LVX6W2X39&G!l9TZwpj_JvZhm-I3mO2%uNgYG9HgT>B30wt&ex$ zUqD83IP$z0$8Qt(MLb`@H4Y z>nX=^&CheNkIF5k+lkS~tKmF=P&uu-4I82;51WC((rKTJ{Kq76QJAc2n9Ok%j5Pq z`5u6LM-Wc=upRBn_f^oLiy20cK57Q=^>@bubXXIew!!GLK=&3V*zGvyT%Gx{z0fqk z&pie(aj*6SIQ%l===Ofnvc3aZoWr5Rnr>JBzO6%eDQ$Ug`B25&h1J#bD(5bozc3P+ zTUlA@`CU+59f?#|RxLsxjx9+C@G5xoF-yZ$VW#ZxWyqF~>F|JABh9o%tr6?;qw6Y% z@3$LsTeIF$X$j9@ z6vOkgp?ePYZ0)sb>sDEFi>x;fe%yNVfG38%-`1h+y45&sA~LFo%Pl;2ThKFMyU9$?;h-LCe@|~`_^7?w8fgZ!;#0)MtAc} zqn`&=5hyB8T)TP4>%TkE4fW~J&b8O=c$(toH5jL-be z5#KD(I62Lkb9f*DbWu6W3SRr&T&>YEq2HPR%I^*j%yR8-`0Lgqjy*Yj6W5<v*7ZWf%ba3JkeHKyP1Z(@$7?jw!qUq_Ta?!KG$X*ZrfkkXiSk59{WTVL5d zkwzct#n{~b)WcO!0HW%_;ox0HQpUBWXxf42Om9JSXT zL?|hFZm93R`|!c^`vNWXM++kM8iv;$EzmU4a*`|Q4h}eJ$iKyk%MTryiV0&*Chgq^ zKkVE{{D1e0PYmL(&>xHV1eg0a7i-aZm@`#l4z>VKpD)5(r;^XB&B4Q871nG#AU++{ zx6&%Y#fuf#+^E5XVelal*5sW^q5{* zTuZb4OoO9*MR06KGvG)&2aaW6S-7s43&;68=hK`gFNWi|yBv=5zFN3da1C%wLw%7i zn+o|-S1kW@zkQq|L6!LZcKlxgKH-MHSj{jb5G_CJqZw{3+&Z{6IL;Y5;JV;WfZGgr z5}a2Dr@-G0*8|rJ*AKTHZYSI>xZQBn56dzHcRJiC+&J7BaQooSggYDV037T2T)6Y$ zn1+4T|Euy}h`cU_`v}~};64ub3AiiZu7bnV(ZY1aEkAALI=JiMZh*TH?k2cf;BJGv z1MahM@#X(K!oCRiCAfRw?uEM_?yGR|0m>Vvi0=xP?^n(7Ju=^2Qis2Yy1T55UCNHj(NC=aDQxC~y^8`&>J~7q|!f zIQQpe)qx=J5tPzjoJ~6m6d|F%G;0UXm!c5<%52(4l^w`QL>KbhgfjS&Lv{z!WGD(2 zSdjWpfV!OhhPnV*DJ$>|un#Qpzr^@4Xdtk8QXYzz$^FL(EAUf_51&G8`)fHcw5ohQ z-(%TVK=k0e^kL}3wqHqsr+U&DVnX&WkR&)icON{-b}yI*mn1)hBl6IR;l5Z@Wsm6zPNY z#@nHi&PD-(4cZ&*R7ndN+h}4>R7rf~Be>dlPf|%Yl5>;s;%ai>W{4CxDU%roxXT#W z8Yu)xW(IyHd>^633DbUzbNe-DE+HbC_zMc3P?)?O?a#L7Fs4X*LiUePs)Ul{vk+r6 zkuYC0u>%#5upl!XWy!X$fIboyrrd`N^6aT7K*A#J$xq_4FJW=&5dg-yB;Hw^u*7(M zDrpr;ldx2K(`}XXTS%O+OnVjfr~@lQC_!I7A4i=s2YLt$K+wQo{#y(f&cOLk8E{EN z`4Mmy13n9j3LK7PGN25`8`z6ZJ#c4n5dtRgImYVXG;Z_QRcIZ-NXBVkYuQC$6D-KQ z9{JgJ8x#;M%sB_1ko_)_2aD4SP{4?N3(coQmu#l}2oeToXiurlJL7}1bUjoi{elc; zYme`8m6XW1ImUaXN}51#sqtQ|k~Xt`%e2?NRwezEwoz_kKMfUZfQAAO6#a(cKMeIW zg{EzWezWnC0V@uVhnQ-ckH3YA zQ;#6YBAd@Ng{EuIGJ6inA1cwFnxqDZADW>(D&n&O4}xLf>1ljO7VRH*nIulT1LyWD z;E))ZKy6ytV?9=4fo@ApHn+zU3-f9a-;#6>be33@!dofS4xcqIgMCPY%D<27_M#H9 zlZto`i2V}ClZw+yp#aN%3j!q>>1_L#2uU*1h3pY@3`s`1WP2J!O`4U&=Ty_Jf>3xG z>nVG$6^`h7v9kAB;R1bXTY;IdnlJ`IkQAhcXX`e+cdiwl|wA`bt(8LDm#C0~}J-v&bt=-3dcTS3g5YhI$1& zGu5du^(=J1sT1WW^392yr z9hC^}gj5b<6O|unlT<#{ugE4@6(W}u^&9-As%fB1QztFO!1qx;eLGu6`w$x^eR zoouy}I#RbImt2*E-wEnh;GCyUhny4D=fP)^;vM~y)q}`AUwr}voTC1M->Iq+Sx!^a zk#9tO3iVW=Mxm)f^$J3YR0a&bSe*vS>FNo{U!vxrB4(&Hu;Q6&D?(`A=m4XU=4XrR`kN;W(6y&AsWhZEVl9jwKosHfqv7yENw4cKzeF#63r#E5l zfZ&v~{d|Hsku585CUQ?L$~=PTM2Vp}8n349^NRA{FwrLVQF4Qd^;MNCOMBLVTDJiLKCL*a{?fj5+P( zRF3#6jCiF!4wd@Uy$~25m4`}0suslQ>Wf~%EtSxKAj_Aqh7HZ1 z@N?9@WheZV`VS>+qc1&ykME&;@8K8a%cZObL%)H3bRqsmA{OGe(5jYQu@WiiEY=Wu z!Vn+40Shbi9z;TFE0hTZ;!vS;&518GRhQ4QL%(NsNFOTIda}|(E6qtH)NW2{tibh9 zOWHv{wVKEoQ{oilo;U#t#rMOV+D$J^{RLH%4P~XPek6`4KI2rQ&IHZDghLcvCG=1P zUqUv8v=hF;VuTX@N!imACY!qb5o@X@;Vr^JEAS5#KE1+!4wz>$hZ%g+L3*{8A&1g1 z(DY;(Gg3M5sQpx_YK8KY+KS5csm~z?zd8fTvehT>8&G%PH>e)LZ-N!zOEEI$`F%({ z<3t2ytR(wFPKx}TF#1_+EAa&Q3ppP$fu^e)fPa1qepGF4fHGTo6zfKWOe}+Mj+M!0 znp3+Fcfw=_3)QP&%%_w!6<)@7KdIhP?MW&^4CT8l4CXRuIlqH(4}m1w1I zg$3O^WmlBo5Kiedn?x&-#Z3J<)cMUBm%3Cbjj*Zo&*YLDpEUOK$4bmXm8E?J%_{Sx z-!hbH_j8(QrOiQt%=7;4hTexjE9FfnBlG!GlBA*D44afL=q&S(Nk>32-3?9qALuEw zhrOPu&dE&;OK;|2*Qe_Xe(k=TXK}Y*W0Hv(P-!@6rYNrIU?teV_JzyDrV2ohU2i z0Z5Q?ONfjUQ3Yn)oxBu1ep-TxFhnblYZ7bnnbd2V;%u+?UbziA{&S4ip=o=PQJ52t zFhI*kOR>_%QRV3^&$*#A3v2Ry_?^(|f7=b_G{yf3_8=+S(VDV0WKKYDLuZ(cGd`;C z#J`~MY4wmZ@7`rD5oc_ET95v*(ypTbe`|N+*}+>2zXJa18I_{=9PuK~xZ$g&$VDfh zs(z$$7_qpB6X6%slw05_T7-l@SB0E#&)jMKT4f$V0IG+R_C!vVXFZA1K90Iz{|x?z zGSE$i$^3CuLEf-&vr)!8zGL!OiLixmK@L|`oPI)Ct@n*VXZZ-D=svYR@fQDWR>_@Z zcOq!kx%jzTXVii-bx5H_OyvsrZncb+x(%UQ;dJJAtM$zMBk*%)CX1QhZ!-TX{P)1| zDRYZDJQETlGi2^l8?Y)5&O`*C(LNj#G2f@!edD0%z%LfpAYwIs*GptN6cUDt9KsbK zq#69)OQ;!;#003IfryPRxpHreP-47%4W*_dNkVy5{f z3U`CjeP5KzpUGv{Rz%cNR^DdCM?o}`FC!q1N%1hWFkja&Hn&mOFQRh8{Rk@Mu(S?g z&2afNu7yf3&e#cThtu`D#MJMz@E>6qRkBp29)Um{`uO&#{4v~RzC!7B#7g+f;AWo% z0vg>Nu*Q76ZXWls=diy!h{$u`rdQO4)&-{7@iw8W;j;KV_Jvqw zK`Hmb|0THGPL!C#MJ~2YEDk9_&fhuWbb<{Hd#;r`j3AC4xxD(yu0Q7jAqrkDC+9_} z`Pwg12MH$Q4pOrgl1-jQcW=6pn4max1TS%k(syV8X?f*Nl({Is! z*%_Ca#>z$Yi*VK?F42lrHYdA0Xin(Y@Ioq zzdCdh%te>pRGt&ArE2!jtel2A7V0|9E97eF#&O zmzhT)oH|s4ep2W0vMveVAonWVbnLUeyo9+HgMJd6&f+y@u?fCbIKH*S;_R;oJZOVv zoUXFcBZ%Nc5rNT}0=v2@C?*fJpq_V)f&H{P^c6rEH_D&aVq66F2jQ0L$=C%gZg^5qR9v;Q zmXk0-N*IQol^wvMPSf+PbgST2FlHqa)$GF$eUbe**@L)2xX4BD+=LUpmM+3N{W?w_ zg3Fx=T25etOK`&Z?Pf4H&DZpmoV|`pm{uoeA~~Bt%{ej-ty@yX=oS%brsYq~hfVmJ zEngnr%-|1L&FJ*(6htfuFAXmaH)kyZK_J%?09l&U+3G-+0%?Ng0hNUG2_#NT!^Wmf zHh7m(lub%_7pTGk%O6@&pq2*6+Be~=d_P5Uu@w%l2>T&oO1WA&(MdF8VsqBAiOeOn znw*eKOXP#3X&%CY;EaieE}ep%rzRdinhaa5C`bq+8&eYU$t=<3%W~LxrO1Y~A#b5` znk<)DF3-tzLYDHUhQpe!AVi*dN;PX$Oe_F%zMpK8$YzSkQe>#iU`^hBU6#qNy5-A;wtbospkPcyXugQ>RWI=U>#QjT_sgL)Q|kpO zu{q5SD`rel=Y&<)1fG;eMFZD3(XhSkH3cJDxl=gM=eTxN5s2!gGDA&I&4P_hPVJhI zq0(V?bH(gJ*v*8^qAVDqz&mV=6PYqeMq?QVgm_QFvEU8qZ_Q_h$e39}T7 zv<_Wni^CWVmbj^**m%QOssx4z0X=lWBL{*wnr5i=c1E7+wDTt8Y;q*YU7g)%aR}$}ACP*;g5VQu z@$%73^p9`~sSS201#~I($hm$s&Q|LbO0Sb{wDfps7IQXsk~{4Mi$Sw^1-Uvjo-F-{ z^xN@SN@jj!W+MOll>dTl0C@)9^2cWyEvq>T!l8I3XKERc} zn+do3zC!q#?>up@eK!p{n zE_>!V_&HAW^Iz)+TQ=-)tl)->AAw1eZKEuBNQFXa0Zey?K09)zv?I&OZ0t+zdClWPp$axFif=O2QyU z1kHE}5~dIk6b&SV8A2Hp>l6itS_cLP1hiOf1+^7zZKbuvv9*&zwXId@Lt7Osw#DJ8 zJho5$eZPCJbMLtq9G>@m-uIvPJ)fMr&RTozwbq{29?r?$!-ZW6Gyqy4!=Lf2sGl0B z)$k{P@fBhQ{V~xKCB;k%^u^Q$Ce<)s%##CsF$ zw*)e>v*Xo%6b>3F4P+Pe@KG?LgL@Y_N?MRlMu9z30v%sqTty!k*r%^AQv!VlB+7?! z0vLeL5FW9UJTt^WNX~x|IXTdk6Y=YcpFT_%C0QK2uIAUkMsgNk3@r z=P!mpv=l8XaY-t&pgpSuHL;|hv-){U;)v&9oLTzIViQl|Xlp)Si*RfIm<~1Rg}#gs zL-e#-+(ig>hqB_?lce&L$(bG~ZAF~cIX=08IZKdC&y!PznDIZ9Aok&N1UyND9Rp=! zs{P8Un|#W?0Bc<8a4l7Pm~v!(`7jjM@bSoOyhGx6H>9e*X5EMflM>7_l|S5*Jv zWxhZzHt|AFt*=snSY^@I0D)0~osH+;kO01B7}I3AyYzD) zfU%s*w>tr=A~5PgyuiV=ME^$hZ?pbA?r2b`e@pdmuKpdMe+_FuKL_=1hW<4a`L)h~ z!H(66R-){GW{2@Y$z~4VwsG`k<%*^4D=u2RqVnRU3-MpsYb)cQLRK#6TG?5NGuZ!6cdNQqb&lX^YGCbHu^u8?@2jDY<<$_ z|J<}wNIIz|{m-SQBzWP{wX1RP%l}T=Jt>5Xx>l_tH*PmK|Z ztq+#2S_}rPi3)>GJ1B+$r}iX;YMXH6>Z&-0&ciNdJ!0TByro}ITFybocHO*uHx$I@ z%EO{=+DJD&c$Rx6(DVw|c5*A+bZ1qC8xA^O=3|DP=Qbj6MAV%%!5z^L-2L4Vnmc%Y z9$-&P1?=ECZu;oSt{p6O(}yGO5Vtpi$`RxQ&s8`w63RRap3@fOfjJU&N0z#7MQ|>V z{;oTsLa8LyeSTKAH0l z0=%WRjp)5#Us|QxYXm6$-85h>vY{|&NAXZ8gl3&hX-wgGCOnwu7BUAagHCodH~~VP zpIK4l()X{da5I9#kaFA2B0KT}Vj&K2f}2tE#Y2j9oVjkMhG)6?fSFOmpWq_9Swv^r zZk{u(qQX6mnw&4$?kJ-&Bj{wXiIW=fQKGM`yeb&AkF4DI-|&?1H|Iz_0~kL;XGJHP~k zu-szurZQL&teg-W6r2zo=-PwaFe`6%(7Cw6jesXy>_!H{lKvAWjG8bxh$KX#+%&Y3 z;8b1v>?*f#csy2eL)@ZcdFjkWOEh)NwM*SR9Vu9W4>|pc?((8AZ}OrkX55z)T9Fd^ zpbpK`70|9saSC_omd*-Sk)-hJpF+PsiQWb$8Ta)1@bmZ)&eNKk+v3Ms8*1W!@{Vdk;US9Er)>s%;(j@7wPPKWn1`Zs$L=Pjp~En2Z)F;(dU zy4zYNO>Amyn=+}vLVs;efLput%jV2(dT-O)t+P57tX|NubloM1!=Go@HqS~r;XHo4 zv`JvytU6lnPt?T5nXR*08ru><`s{U_6c#|9F)=jHzX=s}=t)a0^ zpB6o9`t-(@gbgi?=5X%h6k<^AKNDN$^px63Q<;-G3`!)1mpqo8zvBc)(uwD~Yg=or zThh6*6B`dL>0Bdu4l{k_NiA)SQyWeyGb6i=y)MI6cVP?y9j7>NyuN8tvmD^v*nlJ6 z7c5-1e(k!pwH<4^R;*}Sun4E?wPAeMwcc05nx@Uh5!%g-wX=18o07$m+ii8zT3e@0 zK}f9CTDlhFp%tC$(5EMvw-PfIn1Y1V%>wt-DYdOFljgM5x3)C5wKSSj*O#}qv6dzk zW~_NyZ7a_hM|$G*lbdg??pob-QRf<6geGq$O`X};(#qJnyeCahC-nhK!}a?Cjmv%Dc3EI<=!ThT#vtS3Bo&m1q<(SB;<>zf+uC+ijzFC?7gjzia5 zCrz8$R^L=Rbs}=uZ@p~N=5LTE=SlsnnatCXpQ6-+j$-J{Rv!M|*f6OTdXf)!kGB<; z9CGs9w%L!bJ#+5V`UJ|hf= zm`hr6+nPFSN*&r2w5-H@w5!9P?K(GBtzYT6D6!5I7>f&ugTRwB3Yp#5G8?DS>&*C! z@X^+KG>6fn63r6l+Am&3sU{0&L6FICAMVRy9X>jRe~g96)w(5|1n7iyuIyNS37?YM zxz5p~O28`YjgBeuq}HTercQG0%*M8cNyydK=92`U%2PvHJonfov^KS%{{{II4e=T%SHgRL_m5C&_+#I?&>k8LgPfI(JfQQ(J8d(#Blz@)8q+b!}MB zXw%!P#gnV+?K*#jV>@RqB#BNm=ETZJLs!Ro?#s5ea(3e!Z-D?lm9=T)SbzQ{xfj#u zF}vwlsry`$q?T!|wJmdLur7s890F@Los1{Cxpro2Qi8NQMWb7?U`>*(&9!sse6@#& z=Zz3`tv#tqvHykU#cR6OuZG<|r>9%r`VO!0o!pA*nJDUDNGXH8+j z##^AAR?FJ&750*ox^pit+Sjep9$otWg-h31OBSp}RamneqrZ4(9xp5H;gOx_YS%7b zii(8o4%b?Gje!Q55{{RjuC}nlRCi>eZi(#+)^@g06GFW173Bvk-j4Cz-P$hrpUy?= ztcg=+Me9e+iJE1*=%}huW2(lE91|S@XS;p^*2xfS#DX(`F9N=*vuo9eMXN`SCBC9- z!MYJx+MIyqvk-)JOV+P!2VAhGW61<8eqMC?hy}w|t{%3wvtyVq;^OFtX=|e+uyiwF z@v8NsHbh4(TC{#u$GW8u4OT(~FXGOwe%zevJOUf!uE58Hrzm|>%bGAKIYnB{_LX`I zUKGkoU*?#>)0(b}bxG0lRGaD^uU$=(8X6j>CaILhseOT|TlKY5>l>Rby&$}*qtn!A z7?RXiVN8kz$w8 z^AnJD$7~X)hjKC)icM-k%Sy^s^bKu#U3i=o-H>wt{?Lf-o{j+v$mT#Wb zhJh#s*=Thf{c@P?&k)Z8)nhjXFUbv!v1!Ob(;*op+>F$;H?~VN-isewZ3e-K_-4cp z15YtyqSL18xqMPSKs!f*t=EN--TW4(P$~#7_Wx{CePxv6fQaLuJmY9_y7KS%y!|8eNxkv z)Z^7Q>wd%NGMQ(Td9Kk^e`ETjsk0%hf#dvI)Kwa(+l7f&SF8K1ggW-PdNSs(89EDf zy^NQcCh01fOd3N4Cuiu?X&Bf~M^lOG*VA2`xz1f{5hXRBIdEIM1l~DHztGXuwPvAq zipiGhQ3(fyWMWST7ocaJdeG_5Ts^P^gXwFezgoKrlns_2^DQ65nrF>yYCE@fQY(wq z%nps2EwB#beKS>omUzcQEzFL&!q#3iYQlazO8&TBGYMn+xygX_fX16s>YHcMWlqWfAU4eZWuP4!Mv1u)sTgNA! z5M~UkojO+rtj8hCvkuVQo@N6Qax_ z!>Ojg>#TJP+W4;kakZX{k|hkj)6sS1Z}!a%LmeA6BhG=jBZ=G5lWN zfp?;Gnoy;a%#7d!p<_vB$8sy-4->Y`#PG{EdOUfu0#TCYX_Hwj@w&t10&k#hY(wE; zP05s=(IxeZjiwFnu7Fa+qBWhJQiP(S%Ex=PjfvQ zI>Dq`om!U|pPg@94|{Fnj@fN{c~?KHWu|{Yg@gZ@*f6b)%Lq&cy9lnVB{~-~;PaLA z%+|TgTv-@_I0EGp<^6<-VzaPQr@#OwHJZdD(Pdg++E4I#R{;F5hYw ziYTs|Wga)qqhg6imNgT3Gqra5bZ?C~$pcY>G+0)&Qp$VmC zl8+@c?HMRK9yV#>)M;4XHFI6oI^7}oJIofiHI$&wt?5}ys*>RcH0CNN0}KUJ~m!HCW#)8{2GZ=^U0FS|@R`Fg3?q^Xl;HZi%0UQ$n{5~Cs$ zNBXanUafiB)QN2}v-5gu-AlpUcgP6#k9nz;7*SRI`*Gm)+Jm^AyR z`lbZpnVCF9pEs@%F#z&|Ebw^x=Et=xk3U@+e`-3#Q(K%iC;kMv`1hdr#gDz}jEzZq-16fupM6s@ zjDdCdUP0%PCx9P^@t+30YXBbVvjdy#rVOOGA+rv@-UnsmiQ=whcnkr!nBU&T561jB zKO^wt{J_kQr}Cc)ujQw33;0!)#s5>Z+|x(Y;(uDwYD0Fq%5bvm+(5ovVE1wg?cR2g zU1IkQl-dLAp>_i@KjrdM0@iz<_=EAD(~shV6MTQ-yBvOk;=3GthJt@p(Xm*s6!2lb zaQy`w@P%<&AilqJIcT=t;Vm8r>CCOf<>1q~iUf)${RLc{;^5PeWPRy+A3LTZid!L^ z@e^g6Zh2oI8~xJ|nz$T($>O^llvJ{Qf64K~yX+MG*?NCE>Tkxa5YG5bahciiCq6h< zBn9u0qOV6vI6m+9T@G47a{BXid~U{ME`KYbKK{2_;&QNQQgZtEUjvED!Onuo@_TFk zgjD>mhwpOqE`$k!gPc#6pC}1(Iac2k`TQ@p#O3Hx^yB?gPk;>p3ThspMqrGyVm z!3U+t8zy@)0N`M^ z&1C)4tQRDBpXQ%u9ZACHTJI;}v++M3hR_ON>s>pA0lr`|=J{{qh>vJc5ce?2uNd{GL1ncxG!-vc}6 z^Pk-rzf{NXYu%s1|HBmAJ70uj=3Ml*f0X!?mur<<9}6DU_y~);rcpis!be$y1?NaF z7yC$$7o6kbTx{?>D~bOstBVokVtTJj3a_{BPr{q5XHxh%)AAN1Fe&t5ZK)s6;D4+J zEVR5YhfcxCl^%Jc;Scq_QTepxmDE)ic|V>?j;|-B26$hy_~=~T#>Yh|6f6y=Q1pih zDKx$SMhZ?^htMlROeF&4yBa>lKSa?hi*0RsD$-_NP_}if#xnbws#D4nQC!LMf6E7% zB$;n!JOnEV@zoolacSh_m%LtS@;jNND4(?^nv_(oHJN#L;+sUMJc-8;^kOKJCm&$M zjf;P90ZM#vG`?)>CsJYjLlS?0|IPF%=;kf1KfwP5ho4RjzBdi2L3)kIPds@IHz@@k ze>|_{GXRKS$(iNHlfUXpdHVFnp@r^dWuem~joo|4`@) zeDuv3Uln~fnq9jyZo+@FlYXO?IY~T+)ToAxD6q~Q;3-Q^dWo*WO^AT>r{s@Fy z(f1N=!+**X!j5wUpD*wtfmajWimf~Z-zV@1p}#8l8-%x6)?Wy3H)obpeg--q!oC7W z35*GxPPhZRlo0O3?qh_z@INGkcbc>KDECI8Zx#A3!S5qPIOp98nf@dp^7C22pBMN` zfd>V0cPsM0BJg#AM+CkhkYgC~y(_Q|>0>#;M5{0Ir6=fp??9dtZs(q=fUvup5KP}C zybH{@hU(pi@PKk*QD=P3tVd<+Hfw6?9uRR2Ei;gOT=mGfSLzcB0oTwW272M~a`y(@ zh{tk{*Qe15evVa`KS+|L=CR)gpI2{K8F(Q+uc6+Q&co{sJs$2&sU*DbLneIalw`iX zsCT@EwixKe?~8iKYv{QKdUS505&%hk$<$kgp)vD8Ey0E=gb2?UsM7;nrw5Rix>(|` zmH1r}A46^(AK^MappFly;{)pW%OpM^+l>O$`oW~*1K05Zb$mb_A23ROAOj>G+Zp2z z7g!~53?cZKq3ikzzS9L~*T8t}5(v4PL^xZZ zu6Mwf3QpI`aH!Vs27&AvNM{#GxL4p~0-qB2qQJuf|1R)91^!E5$To7gRzi6L1#;X$ z{A_{E0_O@`Byg=j_TS{cNg&4?#2*y+1A#visK*fqKPvb?1O}Cfmn*PLV5PwE0w)Qa zEwDo%&#I-~%LU#b@D73B6!@6HX9d12@QA=S1->VcYaNt}e`?b(O<e! z0(o{R`4$OWBk-#Nw+q}OkY|LF|0#hl2z*T-ch_V1e+n$c7@qiIf!zYR1s>@)3gp?3 z#J3B)TOhZ@Bc0ph5$+TCJ%LXMd|Kf10$&iwQy&=bRe?tYz9sNof$s}EA&@&oGoFiq zCt)9fV+6(oHVfp||Kyt^@Irx|0=au0!|xOLfWUnMzbEhsflmv3Uf>G?Ul#bPz#{_R z68Nsb_XVC1_-}#SjDvP?gAT%oz@7q21agxPhL;Ph5I9EQIDs_+V*P+1R)ISN?iTn>fe#6MRN&(Re=P7>fj<{`P~dL`zAo@j z0^b(+H-R4t{8%6dl1wi*(IU(e$b$li7YghvaDc#}0;>d$6*xiQM1kiETq1C-z$*oA z7Wi#}-xc@+flmtji9nv}LA!n}@D+i75cr0`V*=k7_+J9K!vW*-U@5|4fdd4N5I9!g z*#esc&JcK>z%L2BSm5OXHwyfUz*_{~CUB>~dj#$g_^`n53H*`3X9fO3;I9S#Uf>ad z+{&NndSBo_1qLzt zOt=K&B*CvIY{%B(f`6NE9yZ1m`~`t;2>e)J1Oq(k!^V*so-S~b!1D#J5qQ18Jp!K* z_y>U>3e3R573KC9SS@gpz=Zg94ut_&b3g2<($%P z?>xaT6xcxsIhP5%N8saxw_w9x!T%yq^)Pb6gy%v(A@mLtSS8_S3eGcp7~Vh#{-qMW zju7iBH%s_dfp-Y~VM5sZ1Hvhm^^%1DPT=c8|Bw)TJX%Hd!TbOVMAX+);2?oR1@e3y z@{bezEP?expDK8Zz;=O)1TH6po{fTEC-6q0?;*r|3HwxS>@DYK(6nI47hXOP6 zp{E4z{|KRPpuh@&jS@at@OHtM2!5sD*9g8#@UIKLU+@Eh|5otV1^>Ii69RKkS7}cH zA?z70_$a~86xbs4If5?`xIySw2!5TwyM=zA;NK=h{_iJjLj5DW+_HWr@O244D)=#h z?+N{1g!QP0n5Z&dk-&b0kULcH3V~yUel{T{t8;~ZfxvbNUn%&P1YRuk%L%b)aEH)$ z3fwK>4+{RUzykuG5%@eI?0QM?-wAx35OP11@Q(>cV}9NX5a}uuI9T8?fmMW%cc$QH z3v3`n{CN_-fUp8*aY^_U0yj#yK9~x6wg~-pp?^(qp5;k9_7FnOlM?zLv@OJ`V6Zi%p_}(FepZHkl{}$-rvpUjy2rMFmyuJbl3mhhJjKFGv zJh_kZV*<|;xK3cVKvZYl57h`KDHuApC{E4+v3DunV?^a|K>UScdf%fxjfgoy~b5pq{q^ zUM%?61^!qdfTb>#b#d^axOM(V36byRgvhTdLg+!#wEh}G*oQ39>6lK4z&V7-kNJf4 z*kh6qOsfe|E*l6@PThnkKMXmvohW{-XQ055LO-1lOcMxU4@7Fda|mIN){A_ZO&s=M z2&nBrR%?5-e%P~$I3lkjggsv-ggxDau;*Gr*wcYLV7|Rc2)z;J6ZEzcA|I{|0YdL1 zgwUIr4hX%~gecEdgvbXyUxD5O#G&^vA@qJs2)(%+r$g^hLg+=eW2vhp|Dn4C`1ORa>utf`C4_wz>pSEH2#25?1s_gGdj%g)2)p^7k^J)rVgEY8HxMEn zn*_g}5b3#9@a=>!@;<@$5F&kizejnG6C$0@3jRDH(rZ<$y<{c+ksNT{8UvSjPx?)N zh5iriigvuAuUON$qJqQ<|NHaQPh~1q#p8-}QW!&LqCiQJT!##e7f7X#Y1YEUl3hBR{1`{G6YeCCQARW8cZlCua-( z(Fwa%eP)gb%jYPQk4jEm<&r)R`7CA0jGv?OWag97M;870$LA?EOkY4@g7K8f;-8g# zp27s<7f_nad`iWi*O+upu)%!+b)P3I>1&(M6PV2W8NNn;e8XM0zKF!nEmTTN&bH5R zTPHK0l*ih-_@_aiRk|shpOfFG;6A19)Q^ll&w`WqzknU5jB`qB{GT*^o+U}VU%-l! z__bs8KIPPv!=o5~Z#*x&o!)L&7`ZWy{@3M-H74BefQ96X0!ex+9go`=l>FbpTK}oz z>#s9EO@MqQ`Weyjx#y=vmVfO1jL7(U)F0~a@69J>I&@)Y`})P$KVeaqRbieNw70M6 zyvW2g6l}o8Z9ru7AY9nXXEAoJ@d;V8YVk>IdT%WejO@0s9r;Rbk>roJXbm?I&~=9U zj4efJL+}^Bip>yBfA7RtV^X4Gn53`%_~o->&`;$XjPTGG;N$q1@;L72MZHV(llckA z^Kd{6RjnGq=VRc>IRMA;1LD74IxrL@-)cf$-{~R{pq+5coesHdGfvuf?wWl$SVYm@<=Bi?RXJ4<$39N7SH~RVZ1)Z zjpuke$jA7U#f$QI{R6jO@8b&->A+HSTrW?Zq-?J|eu?L1+}`EM>klTsyyqd$E01h2 zlaF@Pi##tKg%s|)JhaR3#nVAP#-}V^p5Eo4`}LlH-Uz~(e^?5Q>%GIs!`JlYiUQ{x z&bxr>bn<&aK6~kH1;YP}@Gej90nq$UrUkq zyiZTI6~0_`e+f%S*@K4PQJRn=DGTdG|c!VS6dGQ_q?!UZr%r|`TbUXx{^2&tSOUFFW{d$l4 z(lH3Up58}|ym&geel)Jo}CszPNqN zcj_4{yk4|F-(|^6beHJ`b<(6bYwi-x-E4ZXdsQ zqMmWW=S4dWe17}p`|KMJUh*;C<`ny?5#Y(7NY9@36nU#5kMZd@usjx*$M2nJs~3;| zOXk14bbQzF#nVAP%A+h^UNn9Oz}j;2y`zr(_FJRRg?e9GeGMdP};KOK8~>6k2hjK}Y? zC>!ogU-KZKT%HL$d4Efh_c-L$Ae{9I%c${m@Ov)5yiK1XkAq~teJ6bKrupRc5P4p{ zJOp{A2=^|JK2rER|HSVApZ1slX%p{;6nSh{tv)_4z5I^MZ(sEiyi)@o(>oJ4`Ivug zDe~Tcyy>8OmuKIm6h3~px6fk&^z?S8=sg0x^I z(t999Z_ToV-nl-#hg0Oe0sK^YnK{gFFa2YHpGxn)QuOY|w=`aQ=lS&Vdo{m2eit?X z;ojxtUlHj3a|w^A<}kla0()I@v2UdR|t96V?wbSVe@f&@|sfQ z?Jl*fBVMBdpC|9U6u$03I1n6V=UpD(>=eDbuYgVjQf~)tPw%P}c@r^!*z5@d^yDo| zkr(NDrSx!dTaeT#8>@@`9!*MWCB6MP-3CvQuN zyy#Wt9USE?^~t+OIaaI-G^ zs*$y+&9Z*)8HF%U9_P4zzU!~Htlz>G@ACMtQng}1JKidFRCHBFqtTJ4j~O$%YUJss zRpYs;s>=5}cFdS)^o;5=Mj;5-{EREH#h^JO&q%e=Q+RSoxxQ0l?id|hZtb@ow>F=c zUKM#P5IaBU{Ki@ydgPOj{{6|Vpp_l3aW(;3Wn~?a9~pW3_U-A8JQj*&#XPR!H1+b4 zWyGwqKezk&o>~a%0WaRZ?yFMp)sJPx)NnV}I~Iur?>_uape%BTassicSm4;p>-fAd zVjVlUdf1X@kIfI1H4K}-`bW<2f5o}TF>Hxd>@>W0)YJ1ow;HMrIzzJ$uAW%G+#2@! zfyvA3J0`EFUzoYVS(v%hS@6~68#_KNZ1qG>&c5yw$P?y`b3Dz#p;(7%m!DJ8=U~oc z=Zq(p6))L7k$H4}aN2RpX+AJ$dEmXO;2)Pw|9Ip3haa^^-!gCg1vj-?mH&Ats&i`E z@lQr~bexb}#5?xTBi(6_%`3I~GY!tZ3r+<7sWop>pr8LK^z%+hKm9QqbXZ#BYF%B& zYwDlb7H%$DAfp z3jB@6yb?v`;15{s`K9zz$xyaQ*CgkD?4|$lUi?0oz>hN z)km^)uEC~|Yoq-qL`k!1*J8hIoU{{NurAuUVKw&0UW@I;$3+LOjg}8wI|Lax;+^Bu zZrc}(^@^o$S+;-P6>f3l6+!p(I3`{=XFtp24sU&=OYjD2UnD!+7o z)1DG|Ca+)ST5KF()-5iavMs%a* zk{aA>U_fBnW>O=2LxM;45YO0bU}#5hXXa+-Se=u#Ex0qUA-t{Qg8A5*YSf{}_c~t!;acxeoQ`?EL9F*0>vvX6?+}F|%PuUB;`o z$7{QNz};DYJm9?csJqSG8Q76_r@aje5!*6$GNyaXN`Jm_-%I%?(yOdt4;>8eoD$p7 zaPLv;z(CV{^c>Wie+bFi_i%nUN)wCi@dDN5<;HH?mla#OzYV4Ji#2V!v@S$xU5L`U zP)aLvNiOQKH7IQx^)Fl!0T$dG*=%ZdWN%p!pF=t{vgbD^hU*+pmmJOzzN=$~Kj6X5 z({*{J3Emz1bMMS;y-x(I(vJl*Gxv{)4Ly>%^Ph#tgB=+=x7DS;dRsh)0tcFo2SRNh zUw;DsFtfwjHY1k4b5876Cj#BHFtl?_;ScNTU$2~;v$rXhb1Q2{M!9pa_lZE2v)>+L z4gSlrGoUr=4su5xv}0=9d9lFGtUbSa$GZ34Vp79*eD{&V?*z;4Dhlr$-EePR&acA{ z<~)$ScaFCC@H^SL#`>(Cg$>u#MP3cxQ80N^ZO!8)o252hL|-#?}~!ePbWCi8}so`h%*Bz4gbtoo+la zg&DdXbjM7sbp@sg36Ei5Z-yDp^(QsmE39I;S(TSmE| zgRlKxu+?ZZc`{IYQx&`9=sZtz+4k7I3wIu^k3DnLK?&aVsU_HbiV_6vQ%W#&x5<@j z>pBldOUq+DbZZIi*nO-UpVWJ0Hcs-PR^*ILl-(m3HB^p2n40tUpp*0c%)?g28Hdt$ zl*gWa&q`6j6zJ2ir&*=Q_ILcCZ>VPQ) zk9y!}Hey?YsN=yfyVI2-MnZI>6rO^xVo z{QKdVlaJ_8j8p#3?@f+Xly)Px49CXa8GG(Mw$Z6?$kskJDD*Q5P0v;yyI$vOcjGsY zg@VnmnOMOFt2BFWG?sHa?Q~;iTzJORt7B(O9s-PBFm3bU6D8e8mWAGP(tqAK@})87 z1P1@diP!g8gYuTR+tPL%S?2DHG;E(()$rO0EBcd1)Ak-&wt1pc5qKqS$JR#sCHw4m z4;@`*YE__OV#Da)uP&jsXh-+{(#bXNKU3EqJ&3ifzwS8>y!DUb?;ah!ByF!fVf)0V zj*g0*q3tePZk6ts#SvV+jB@|HtfJI8%{dW@{&`t_!+ERuyJNLg`sZcNiS%e^$Bwti z&G;DUS>D)~n*Zp_W0TXT{@wTRfbMDQ*G0P)iO(msEG_T+DtX6smC#0n!;SYi#)+8L96fU|&T%w-#{L5dF~>J;Dc z`TL4}4+gpytxTjQ`@5?jyAEl|ynE69o|7Ld?Wwi(gtng0)>E`G7mqB9Tk0B1-)zs? zTNQJ+FqD=YX^+M{Ye-9jJ*#V+eHdTH#~sXh&z=W@_Er1#Wk2FC4fa8+F|H5CkR!ps zp(mF`9-*wa+E3H@^k#c~JiU~TFx`Ik?R%iRTF2`-iTnj#`zsB+*JK$V^FUu(sfONo zz$&#%+dpW`W4@W$gL|lBxjkAPH1(Ez(OBmPO6Tm4-mZ@8@oe3T`9Ui;3ddFb7~AsX zjx3Bhscj2lqfcxvJD%fQg=bS%)Bf?v+Gyqfl&#C%F5eit?2xG^u8e8F@!m)$5VMD+y+V1>*bvr+Y0RJE5n)}kNVoe| z#U4N4jQmO@5k6)_+o8?>g?Z$#`d7*0_3vK4e-&(l#k(1Hp6<7Q{y|L=d7yIL~z5^F#2Gr zn6#CxP)l~yJ#;|LcjnhE=~%(%y7~3BMExlG2+_T&~AaCiGh; zuCQ)8(OqT6s6j^!D>_7->P&lB!7E5jeen)^Th5;TJAZW|wAtELy7L`9n#$RgrY+x8 z_v`_?4E9xp-YX1bK3p10+gq*cgH?X^hwC4P+(?h(X~FbECdDITb#*4@uw@zBs5R%? z&T;C!@X)Pq=UCU`z619r+-VQw?XA(WZWl@_hc~izhK)Pq+3KETtNS&h@j8rC9$ew> zDBk|H!f2^!f7Y=Y>)4942dW$L_Lgm~iJ4pv#$#k7#$Q(yZ!g0vt51Wji4VBo1?O$V zJj*_LD`D+}QvUlMF4t`&7~8h*20d4)c|Tlw>bXkxUNblRU|IGaSC@R+W;1s1=6~Ki zkt-eAj+n`ts|4SO^^bHX9W$?C4FUX~f5E*!93FcgGgiZ|%BLSXGgcQ{P#oCK_#Dp$ zkNx%{K3}9)On!1~e$Xn*yzN)-WR13lw;#GEcKDsFT%+Yx^s9T1r8zt5=Dzk!Z+rA) z%>90Oz>3<@JUvQF-#NJ`hsZ8>$_HaYdh$_ycHHqz;P-TJC_7ytv-wen;tI2 znJ_%eCmzJFF>y*QkGbvA2P5b~i#|M3$Vu$p7szcG1tf%c)MScG7tJt;DLeIrt^UvE zUE|_^bmm}x1r>C z;p=M$AHs@sh}*jch81!(G*p14-N5OEix{ljoGOs|k#t7yOEf9%PR3{&4APWBuDACM zxEuO_)I!p<-e1$Cw24uKgxu$b;bl<3X=bU#)IHw;7Rr%XU;HP7A0-?(xC-~c5SpTFF!!N6H7#hkSgrB)Zn@PA5Khayt@DGjYBe{2qd#EoK!$+04 zg^=KmMFFIbjyTX0aQUyJ>0^pA5E63VMCqlU)-wl4mYWZI)5m4es)&07nA6Y7IgyT! zsa%Y*t@N|=-bTI+aBsm!j_EZKswoe*Bb(A|vkya!J>3pBA*<8t3_8OOKSv?;25qs! zCn|w97<8r`UO+*O8V$DEVSa~|9y6im*p7!XEVRg>8@DtsDY#or%uZ!i(Z&Na&l3O<* zRz_*oouCEWi%?NB$}|#kzXur^gR;II&#jEpB)3+=_>8f+1$b4H@BS2~Wt<*nO(}Fc zpeCbQBPHQqBgGkKWYbV(+2OMoYn(xq9Uem~&eUimV2Ar6B^l#2YUd-xFX8<}Xkp2v zF!;8xV3sc|eAXX}2LCvMR;2Tgriq)kw9jiCGhJzY7ITE<)r|%4!I+ z7EE{FLPlgYYh;EM3M1K}RV7cuoHLK0VT49QS!iAHDr*uMEi5C3}HH+&hN@*;w=* zkbL(~s7>KbC5M0%>KqGSqeYjvF7h&bZLbLkiMs!Q9|~Wm>&yW6)+mtcHB#>OK{1EF zqLJZl5Y;h!gGQ>{rBwP=jf`=dsq{u&b*f$d&s+E=jf{8Cp#?W zFT6Fa4ry$1hoL%zZ_^>u!+$~nhi}*UXYW?wAJc|A40?|WSEIItw;S~9D!i3q?lkDV z$_ibL`WL#Wcq}qAhdCO(6AgJl_IZEAv-=JTJ$qi3i&R_gLufYHZTV$D0`A=~BfCAT z8c4|f2?`{;Q>QJx(eN2QpBoWhrnH;%Otx?mr2wL?SZ_|_CbH8*?W+2Svk>uX|Qx3 zDsE1xHo?lf1nJU`0r%0KpbybV$O`=gtfAe}VE||Dr6>9bMHJdIU_1!XAEHpkr1$$f z#ho<>t}WU_e<0`H8UfNj_eO{cxcqnU^wNTEAR%|_U?2k`-+@Ptx{srZqz}@n%H35X zfDG2iaCa3_l|Do}%Bt`>wB+=m8d00=@E_>mhZ%G$JPgv8KHQ+U+F|~4cKQg725z^* z+bO8RgzkXotJPazV z$iTEYXdG4UhxrH@q^r~z_vK0;BQ#R&4rH7Pjf{79LrP?%PGyZd0qrv~N+V6-=a7Ao z(M2_o=5(v@Td3oaF{ZFLs_^%aiILL`x=Dq{A%7xc4SJ0VUjTa|ryKNI73OvUk!pip zr>xizRK0O_`D;i{4%2id|6elpGt`+zyX0LEqThzL{2pcFkooQfD2N^da=wN9v0NMd zevg6L_<+kT)O(mThTQ*vckeM+hh({-av(#ruZ&o+O~}K^cE1>laxc^c|+N|=WQ5i!8Ef7(# z&=f%4n$Cq*L8nIGFpALf3l=$p5XX#$3c9n|VW~UO81PS~$ZuP{3nr!hh++&X?x~Tc zuE1|dZNYE4x(~k@>T0AlTm1|fpR2B5LRBFoGIifZ-ytz9&bF6y97CzJwYQucLWlfeU?T-?nls_eRlW| zqGY)LO{7L6S?+(J46U4)aDW~lyA^s1 z=?r&9ZXv_1WVnwE`bRTlazGP0e>k|7L>?p856H!FisrIHQHTjI*I}Vfs#}$Jn0$Z2 zkG6>;7vUX_au0t=^9~Ay*NsKN(0hc}>s*JY!ShA>SS5uK?CXK4Alkg8UPaN{io3TcwG16uKwS=} zh>ms@cnU{36k_Uc;c3}FV7#A0m8JfS>Tj!JJS%k-;yF->94s8?+zO@~a++vPzwD0~ z?G0FEDQ^8_tAD}8DD@QDYE(S}_t76Sj{%S|$oU1rGui2x$i1g#SLA?q4OlJpL#=aH zgpr%dwaz<{xxHsPAuvgdx!LD2#`hr4Qa2)9wi=8Y2p{-oRF2*kIO7o9)ccY2ZGa6t zNul?n+6OoArEc%<=mAXqA7E|o??&ijtE4eyixNtn2)3b(tGh=~$tLjH>W*|g zDsCC)C~lA!PMan-f(96>b~ttCxyBZQE80>9~Mhi>A(K~2h1--XkQs4O^!9;y{? zKUZCc1m~$cD(G5|z&#eI3!ti}%15#aRSshHR&%4+!bVL&Xt8pT4<+g-WcE>Sz!JDt z(EF=%kkh5=186K$s|L}vzJ+2RsD1+1GDtN+%V72MA((TjE|kL%^*t2+P_+#y8m3C% z(ub>qpo~!Si!jIL}ZofoGihayk5Oe)plU+XS*9+)?{bv|IV)5fQnyl7!17h993|DI>hZf;al_CrsYmg< zM$JZEtyL3{-gRm&elJ&fkbH&uH)`jV>JQM~tv-b1SE&i`*H?^ zQt!jGbafhvE<=?f<1^K_@Qe}7PUKAH1ZNdQXL1Ui*^Q(OD#={cfB-$f&Fs?4Cze|Q z4VkNRzJfX%$XmK_q?P$4(}x2YWo53>NR~U8qSoq(a>PAE@$0habueB-Ze*_4gSSE} z^kbA{=0(mCun%f2impM$afc#VMg0q@+YG3S%Jj-YiTfZZMFaF)C922JMP}qVK#!q| z%*eCcrAsIptX;xzcQW$2s9YnJ?s8P~q9Ga?)5-E}*w`I#ieg*CH93FH+&(p}>pAo6dT%a@UY~LJ9L_x|PWRS?FE3 zf}*pW=?KZW81zi8EEES|i&b2j&8n!LMs2m!D=2zf{eT434_V@<`Ct#Iji`67`Zi<* z)$6b#P5m9E5K@amtR9E(oT0|U@=W#hD1F{9At9`;L2JlX*TdQzH4c>^qJCOQFX)1j zt9Br6p5njfgmBVm7q`Y|Y#ss=u$O8pudM=BTDIZ8c)Ha%KJhtgBt ziTZb%;t7jmRSB#;UF`r*wHl2)JVUL4RpZqC;5<`Z;nHh9fqFeb?T2k=sppZmXR9xR zQlowYUA5{)RE4_ILC9yTJ5sC@g3!=w5MO+ea}(^$VVMmoEZ)F*uDcbIi!X^BL55lb z=Rj!jmrZThJ@7UdS$wI%?y*9*K~C}I&Q!$8tjPVE60jod$)VVa6r$)+DXhpbNQRA8htwb&= zRa3?~H5#UcR0dKUQE4dis44|xjXD>3++F%Nl#gYXK7&5qQl*EHrsI}A(~ZF%Ib|=yL$it6Y(eHE+kly$*6#cY(@5wk(N%OY|J$x{PZ6p ztO&o^M{FxHLqAw{=>0(r2ub57y!T$iQ=*mfI95b-52(ea2uUs4T*@ga&-dW<>^MlWvV*r|=a#RWR|6 zb(&eK1tCC_tW1WT##Pz?*S`bTGZ!=O#^VsWyr)UyO06|~AAb7&yznJZGQWeL9PXnw zVMzAYO0P^ijvi$%?x4q2GoSU|L8p$ zq2fDXV2^DvPxS8$Ix{8 zo)x^6(U>_}nbBDAGV-+VX~BKTVLG)1x1u2Wwge9`j1--;#E;dZ0adZEE&UxR;Syvb zC1&IU?W?nAX{ znO{YN>rsb#)^}ovNm?G4%$Frr502EMt98(|4ARNgQF|Of-t=D<;-u&v2Js=luGT8( z0ZFCfg5M!o*Nh&;$b!=9EFv$Es_TaiD)<)~S;7b1~59ptG zDp6(9VcO{^&3@m^8tZ_H;Pa4iXFL`q2DI3M4%jttLhvy!MnLB@Q7e-! zrQjiCXVJN(za)bu_jo@F^Veq6z(0|y+f0vUwD#y=owuBKnY`s>S2B1AT4?_HLC)L) z>8w$@T73(8%oEY+R*&BxC;K;QF=vximrf7v4chN&opEiXCNhqW!5X^^kq2LCf5{88 zdW=TtMQ7^S+jXRx3NQ!M>^n0KBhLM#>bm$bZQzg9<4UxeyeoAc{)pi^k1A)Niw$?# zIun0SvaUB=+P5l4V&D+2x5J!AA7|JFB#&Kz@(icjY3NeS6kE$L*obZ*{A93iGP&{_ zsDk0kjF52*ODHI)L!Axp56*~3(RvG(!<~d*4z7%o6E$J%1F$1pW^amzY2{;QqDKf9 z*gI3mGmv-T68q6)a=|AfK;9SpS)5Fptb(0GK;9dC%_CctdDQlpty}rONRH>H$<)e= zicmN+O!nm=1EgkhAKJVPI@Sr}izeI;oR;%AUMmS+DLk3S%dgZV*j1M}o%+y_Zp6(#LLX8m7) zzlD1|S|AR_#&|J`QSe1*%tPE>{|VeeQvLwH5E+B0GgkQqcA zL0X(GR?xO*I$HukD+?KIu~Hz0UOnx}L~8jXjC{P#v?91m&Jy|fo-R3x)z$&EcD~z7 zmnlN)aNE1u`y(lDLw3G9hR@}YG5~iPXB<6UJ>wV;yc%~I-%J#_dg3+>_!Qi||6Gg8 z1W`)=KV-2R%I=Tx{=Y#z55aSAXS@$&5gr!e?#Z-dXF$2yvLcHGMi0h>t!EzCRkqz? zb2K&SJBY=+G`}b{yiN*bya4K#Acq^XWIPSzay(p$JNs22lvxhWQ^-6GcBVUmDeuEqEkJ6u7aY76hT5M5^tT8058~mU1coy_e?{ji*z4*!sCD|U zQSc`M(15`%qV4LB8l21AIuR&iOS}R1wYYOH0;P)8=zd`L;!dLp9|v-2!Lz`h#ND4l z=)$FjSh`YR-mn}h-t(!s-c$3QQS(PcK8zb`-ZN_c4eVpwTFnPW4d)EKaDS?rd}JXv zI53UJ-u0rV=4haT9VRzx;nx#d=sQMeGjJZjTf!zl$7Bs&1g~%ZE|9~qh5gS`C}oa- zQb{4{O!)6jWNYx_7zEk-17UW-_H?vf!@EB)g1mkBwg$mxP*g9S_4@-&Y_(d-6Glqa zN)YBFt{K)@Bl@GDi0ff(zLi6{)n~)19fAFE6+4UyEohe!l>PzK-4nKPH#ZA-RER8bBBJPaefD1@J*+H6*0ea)k4d@-yrGNB42*& z^kzq$&Ntu(g#IT)ebULLgkkxdJJ`Q)`Y<|h9qCP9q_=#LjwVHV--~1oJrB91ZBGv* zY|jY9ZO;lMZ0`{;wzKTCwxNN9iNgXq9b!j=FQidIU@{Eu2o!RBnSK?z--RY5Jp-As zF3?lgr01%z{cj+jW2tm*%f3PA6I^r*=9v|sTOM^Syed$@GDEdm(I2aZ&fj5RpTA*x zXm>axnTfslZU)FC7EhlGP?v#pa586A{|F5r;P5?buTIMjI0M)_=j%2SbhMMzl`>5# z5LduLj$Q%Nl_^6i6Dvg6REYHI;h5n#y*VaL&#Ay_gz(%4`Y1=gElqzDl{;qWLpMQr zI&0SuC!d*P4ZRJN{I!-{?ex&aJM@0CFwO+0H(z`qpBdpCiC|T4M4fw4tp`URek5hT zs7ABHW}049lXRN!&y1G+vg*ZUjP%Qpx4%=xlhEgz#J-|*Vu$vD2;CgsP{r(h)4zxA z;Z0>a&|x|+-cdd2DAV6Sx&2f11OO*ZvgMdggmFJnU47gn}=Jw^XF7E8#X`H;_2bq0Y0yE1K$Gt zCfpA5h>rPH2x7ms4o(qrj8i=QLRfwu*dP?Qz3Tz^TCMIrbq3Xa17RGlYjyXjDOC3p z;QY=?tJ`bT@gS~ua62d-i*u~m5CnD3y5|9A=-#vizn0Sg2F}g83>7-e`fw4=h{ws+kF1pWfkffFjeYb zJb&5wh_-Zf{KqXlX8+RICY+Yq&xxl$gkggb< zWb)%Pq{SYMVmGQV#Bws$D-16M#}4(ba~4yjE)T?MA=eoQn&pha5A*LKBT3h2WU$4V zq*EskKa)UYVF_y%mld34c%Tg>NaiVQ*!bx-prO(l*nkJPn=j+XxfVZMr8!fJ^B3B! z2=UceGh))?Ni1)19Kej$9k{0B$<&1?o)BnzgT4WXi&tTnmk@ zhV!X7XRDeJ=bS5?&6`kM8A?xqVUM*N?#|v-i+)A7<_tB8QEE^)6}WXh$xsb+V)p>Q z6SuAtGZ4Wfd(^5Z{JGMD2DPQBj8m8%O24~!65KrOO;?*-W59m^e~C1HPnD??VF_St>iMhracAxN2EOnhF(gKQC7Y`sA5jy8i1cgt_@gh*IZu$b^*CYBTLUPv|j;#3ipJiSWwrgceXrnWg0(rIaBZu z`VDZ5nua_cZ)j>u&8S&0e1eBIq+N;UUtv?kh2Co1r!UYr(lsXkvja4}pdjhN%r&m%0=(#@~z|csFZe1yaCy;z-lY z&4i|DxSbscTgtDn&CQp{i`X*St$>A1QIDQNaf{(E7^Ms#fgfE8R z4hpXU1BGwnJpu;8~e=w*Q? zuC%h&fRT|UqH%Qe9@^0rSvhn)&G(}LZZ#`UP-g8xBzxDRm=0^FwAI#5iTfGxW2SzV zBDZ!*RfsqUcfS_6wXOCH4*nMapNm^Ns;42uI4bRh?y&VhXgh*$#$Cp~|4v)aT3!Wy z5Vv+{ciBk}?Q6DnXk4|e!>ygyZd*6sR^U@fqw~7Q(AEQANgAEk*KO?#?gV}tX>?xq z8XA4zL!{Ap-Dhj(#Z%#)A&t)K8@6_GuLFODG&-+u8rpH-?~+F6b-$sdA@vS!II2BH zLvLWcaBFw=fUVuxU~-Vwngdm~9=wbPUX6Rg2J2-L)7kR)mD;`i#@6m_8bW!3TpHJ- zerwV>ANU-`T5A2?P_#3<59R%;!M7sx2FCg+3hq5a0|F*+7WcTV=RT-ZY4nKu4f-quJdJz)yWnT#x&*&yX=piFuYe@p4z7&kFXOi* zuw^?d=}F!W_1T(2mv_!+@w!JmmB#D-(L)=`7GG?=Ve6qgKOg%QZfBe{g)$p=e5AEz^w;` zgYB6%oYA*{e*?GnwI4!=&({t&zV??0ejc|T8ICZHl;64?#;qMpg>f(rRv-RJ8t1`v z##Qy>iUjU7E_O87dbO((_%PDwAY;byH2|+6jSh06q4D^~b4hy;e3OiG>XwrS|l6o1h@9TOH78G27EMWzm4GAEyLFU{4Ct?$=4VS^nrB0*BgeV2<*T; zh2G%s>EcLd8AqDM)okMhXGr(#^ML#O<2`rFt}AZ^x1PBUg{**{GNYHZM%ab9)zZ*! zfGRFd=r(=_9=74OoO1kd*fbA(r)c6sKfQ_5`}v1WXneYzTxuj~_hVMuIh}K6Bbe`l zZixq5&U~TW>!Ym(jZN_T3EE7y;ui(iiwkTpNmjKpPRcoJf&poGUnx;e2bf80$hPJdcNlPgO($Y+A)22z9 zp-lm~q)FNY(j+EnX)Cm~7ARGbB9Ea~sXjzhP()OOry?@RBqGldWe^o7L{uIk%Kv?9 zuQS|}Ainp%|3B@y-`UgJd#}Cr+G`Kz1oZOlJXsb*`5@v@8?>~=M9a5VP;GFJ`4-$_ zYt1(O|J!gsfZJO4I!H{lWkY`}5}N7kRC_@%Nu6#|Sk>j|XQNOF2%F^d9Y3E@HkJ#q zkp+4$;GV@J=A&#`r=kB_@RPi=45fVdO~?Iq+XyRaT+8}vm=Bkl&f@CkUr!-9{-xH_ zaj#@He=UCl5qY3(BfYsb@DDEZT?E%4?zhe35)|q==Fx@QK9(%gJf54!Jg&!m74DUM z)#bSg^7or?-h*56c#(Ph3a)2yJJ637H?)tTpln?u22csOWDSXdUmYnhA2GNF_d^q? zYj9>S3(~$8!JR0}eq=oL7%gn9>jf1$`_`0)w z$LY*1ab&1L#-m=uHRF+Fd>1pm8|T}2uq=w#!?NM{7y za*7eaCA(|YPj+L$PP0tR)_c~3#9I$$=G$1A=$bkN;Q@_y9)7qpCZc0hB48%gz64E(M-jBOO zHevS4w#1j<=3hUSb$y{C7mHliUno_P>b2ovniLS(yH;|<>W~C}- z_^hE~o>7b+I5zP-QSMGFaX}(a4mr(z7!8=%k|^M|ky9C@+Y(K;B}~`hr+aQ5(w&@` zOqEMkW`%F zoxyfWJXy^&rwA{fY-W;*oz_#r$MQM|;c?*xr*9_y@rp41@eLaP6DIzOLaZ=L{4WOa zuPG1XU(=xRuQl;cgGwrt_&*Qg7gmPx3mY|lk%|9jlrB%==T!LR$vZ2IpI4{xr%3$H zo>Ab>>RhK9u}`@HV~DeQg*;ykp>nlJ{=_Tb38nc8`*GV zQI59iTAT77unSsafvufPNU6!=sgUC0N;gmn0ulX-_LQNHKl zdkuoG#+?VF!17*(&y8?>6gL!jK7O)l@pB0NerL9dDp$e_mniXLG+;AZR>CqvBL1QA z>^?X!Le_5qW|5^jI(ATAh90fn%nz=_AEO7Y2T1QzaFE_n;5*Sf z2lT#(c)ScfuGeHfuo4y>XuUvs&%!}^PXXVF-r1l>6O>mHw|(pzq{nSG2gV2gP`XT3 z^5NiLN4JWob$Q9(s5o|M17hC~FTPI6KacKx7mh|e)Zw1;Q#hvlnm>Qxk6nbHvHY3J zpA+%3mGoE>GeX<@A(W)ojpXgP^Ehr#A<=9SbB?^S*CW9z5XM&`JQBVg54X_441R=% z@6f@FJd6kbfFqk3I!9jG>oL=L@GZhUZxI}viri3xs7v8k3Ewktdlhi-&#JfL&aQ*Q zIkJDBw;2x~fX_kPQ^%~tR2YeE>y!9B>MST)1!l~L?-vlvktlNp9ACr3J-G82EBiF~ zkW|(#xcs#uu|ZX0+TlNyBi3F#B&;vs_an~CeI)%Vd>;m-2TA%Da6F9%9!kn%tn9bo zBcv~bYb4Sg@SoR-DtrwOcdbS(FM#8D5cnx>Zzmjlaql%ccZCa89EqS&vIUZC(m%6;Ct@J zk_|eH<-CFr9{M~zEyRq$mh(D7d0cd(2~D@$xrWFirteNmDyB^Zf;jSB76w`JK^UsU zo0S-jj=*qwH+~xv1CZ|XkcbCdrPTZPfpI)i^B9Wol{Kj5U2yQ#miOZJ?uX+>JX}Y| zlW;tMhi~9s@(j}`d&V%`PvP+#LVkwZaxO*?r>Xe}3fOZ9o}B+KF`hK$9Ih>pW%YhU zVVUeB977O!wmmJ#=h;mNCC?5kv9#IFFA+$deKIX6d6xAug2=O=`m$HWqpm+vN*VLO zFeme5EKXpbdHh_<`2?!OGqNv-g(dc1HjEo*arS3!!Pv91%2aSHqa=wlr zp4nZQ7R1~v=Rt(=tZz#gW;sv7lY(}E?@2-HLM6!FeG$(r{>^hv@lcpF39{z#oYjv( zr(iuA>Qy*?k4E}6Ztov(czMtyaAapfYD5`K!oytn7T})8LrcFx;yc$O>Pk2&;aiT| ztA&Fv+tlKA(4#Gi-3&xy31VXBcnGK1EjHoI$8u;+P$E`oB1#1QiA1!85y{t`2+BYZ zC1PJ%kS`JA5z0nCnifh?%9?^83d=Coh^i|^DQxR6sN?A5f^q9q)on(tHsKak*NKOA z+r&m1!T;sn@LedK2$DJ`)3+j2PQ4?0(A9L(Y41c3IbC3a(ge|Y0)do~at(~h zNY?ieo~D`{o?K$z+@UFk_stH(VBb6(mc?><;K{!E$!K2zIktY5c}p{1hK3A zrysLvOjDq3LJ}mKH+&kr3Jb0hL&sp#;!R_4!$A|F1*RQAYwCdI* zBn2OH0Be%t`|2QVb7w;o5d2x(nbY8S91joCF&2(rx&2}8Qu9n)L~O>Slg{ttLko zrauF}Kei&97d7xVVW9J>`u!u~XQ8nC5Xek4Y|!+kYc!%uP0v6$mqMEI@Nk+$lJ$&j zE8tEZd1kM-p%zchdn|9G33ZOVxYugDnw~p(ntp?LSPoi3R*c`5o)e{Y9)c*s*P9^2 z6BJ68q`w%%4>q@!A&66+C&HjDD^Y%^0D!D<|2hmhszDeAWflGJL6GIZ-nP1s^T`cT zeOjdCIr-m&#+1D(v@DO1>_UakM|8eOveHDCVKWO|Ed>rWNBs7H(`>J9pDb&6RM~%t zM#QkOmdEaJ74bYOuW4}G$Nmj1nE6e3O__of3f!4bz_AJsi*b8Dg5$Gz;5T=s{F2dL z#m`jIfT@UU5&FV+5@X-fs$}j)#5-{d8GEW_{Q-_V#+pJ}9%)<%?-Xv2v~Ixzk9^I0 z3yxKYw`T)Fl5^4D;QK2^gM}fRF|WcQryV(w+Kgy^D@`ZADW3)B;(>3lK)%9*jUdjW zr;Q-~)h5uJ2}jm6Jn)_m#~eHq;hwh?jy6QQh0#uf<5c*TFj^%XO?X&OM?D< z?gi+%E%Y+!b2$6JK8JqD-Qhimo%I@i_>vXN2{mgi;<4`{u+Wy@*YIRHqnEUT4{snO z3Elh;@WFE-!b{;O#qCXmqZto%bj*Zf01rL5v**L%9C>=Lw-gUo!sjr3E5!HUzU(@A zcyX_HHXi;RK_6%ER`LDw-bGwj>X5SVHxosf?zopX<8c{6K8Lus;?6u7j=S-27ajR< zJcNe_a9fLb98x})slQOkPX2$8!lw}OG~)2Hi{71ZJdcN;GSSrSaPfGzZM`4Avz(cK zVuDNH`x?Ukj6073-eLGS&_{1Em9^-%E3r^5$@p6YuL7s2y9G%z%b^nxF%Ng<-w|yN z9*S^hPezDy$d%yETnq4-DsX)+q`IyTGLD=SlAG_4k#*ZAd9Ckv!Q~c*3BC0A2 zIwqWxPQHme3EG0pr||~nv(dPxY^GlSq%P1a7GJ1bqv=_fLin+M=SKWW;m3v6e)R+C zt}^(UMY}92a=w9yBA7`E8w9khB5DI(N!<3aZy~v;fp#!Ig_W9NXDYt;bU zu?RY2%$Z|OA5)XV^K{-4Yf(;O@>eP*V` zIiQ;ntw%1(MGq-DBq5!ap_DhqZb3CC3&9{NKJL5-*-V{bFUo1O@2YTHCbt&Yo83)g znESLEYrmaCuAY#zR}_pI1J0Oy849C_490>3Xp*m*{mde3%$OBp97x1035hW^KgV{m z$BYp|1sSANK#m=-r;=Eqa0INHEtQI;Eh1*+lnA(3&xh#+P-YEqSsU0X-e*r?oJM`d6oF6lY93aoF{abDOt4SP z&O!G(A-iSr1baL>{YLGP8CXv{RrF3Pv=wT)IqZt0c{UkK)wl#Lehvm`>)gp!w$nx5QelYJuXOO7CvbI-k$N!vu-S7?W&KqDC0t(XOnM-bYc0Qt1$R(2l91 z)2W$?_*GNg5m~?|CHShOJ(hZtay(FpTw={9YN-nL#Z_GC-z8qYGvLSAU_(DABOM@V3 zB~Y@2XTt`k-%9+bU$*bZfTT4J@y1nvFEB&=+D=K7-k6+Hfrz%10cKnC5$@RXm_!(e zn`e02b_NU$yz~TbOP`g?S{D~NxE|SN4oMjH27wzi(3W=$K|3tRJEZ)7LN*(v&7Om* zN6HcSp=dsjl8Bd_`8Ks0jpiOb6GUK!`UwKR2$At1GXC5+kw}C>5Grhjd^T@F)J+oA zXOwU-r2o&NlA^hk?Kz;9Qv|w2bMZ8HUZe=gdGl?o3dQ4ZVEmS3kwn!ZFe+AA;!ztJ zb)!c0y9%N_&;b5gD4CeBMY-jUp^2J8vE^iN9vikQ~#65_VmPrwedq1+{S zDmiAO3dii1(m3>zeP06J_az=nM2q%V;t6^`kvQ%|ynXt92Fk{>MTnB~k306+62)68 z`8#-(#Q9Ca!Mjh=75(HIycHR2y(6tOci10bwjW4bn^u}@6W7!G`owRd-ce?o49lqW z$`09R*gNdk32)d(6M)AOPXWM^^h*n3lC4F&wMg5Hv@bL5%S_vxJPOu0L-vgz@+93) zf)?FED%x-_qNca*Gu~AIRo2hI`*!u_;(~fVov>R?TauyfpJKS+5q0wr;{*(R4pot?y^!`}lm8iE;^C7*DLKB?|_MLh&rS;~-OVNbMml7}2`{l$f zBX&lVkVKP~c1I}2VrYlrWf0b7CW$}Z#4i=Ymlojw zMe~4tfF1ry#?yXzz7P>9dN|VEyF%}KBi+3}^u8&9K7=X9U!{?P9hq`zL(#i7tU z3rYa;NuMlK0RU!Rg`cEVYPTkrKtZy+ePMyb6i*{~Hq7aYdE7BWDt=SsLRCX2PQ zGkyneSnT-CsAAwK(@Srpxw#m=R0sge_UKB&IBiHe+0@c@#!C1|HDR&JGrUoIHiCyo zzju1{NLtV%Ezl#^q>17+3DNvV6HiCI5#L72+P( zxJG6q?xBdNT`wf04fewuBeoDZF5VLRb=yIgGv3^TQN{Tic>BZK-Qq3Nw4cHI&V5o> zPrWHSSwFMU4``R$_?H&46pdJRFPri{8?iPA9TRnlQpiJ$yge94_CUN_lDC`4kTME> z8D!6JQ2RlKC$9iOYR5t+jxAHCA89%z)5`MXl^+yu96G|dDe6Q>23rr+w?+epHzhrB zBcjYDGNZN<4du5DWFifGhZ$0QZWST>4k`azbE|hG8!55awC6%*&rLxnQ(e(oGg?r! z46r=oTr|?T5(lGD+SJ^mzDnZtq=w|ER*-8w2T$j83?~;5WOtZYim0X1U6%}xs!Wy1 zdMR=)l{o(R=TBZV);p7nR3;aB=VDfwoO2SMPTGQ}Ef+@%K)F*9k)gLS8c0ICG-qMq z$Jp;bW`CT9)5kGWiN_D(Zb*(nTz}mIL^420H6~u&XvQBVx`9M)uy0Qz0+l%hF)yP@ z2CX|D&lwV6$!J#LS>*#8C3qr zH51;`5{qwSrt-}BrvJ#{ftO}59T`lQxpHeX1L})+iX$;tLtQ7TP))#teeg><@4n>5 zWDSaIy^9vX8~AQ@PSN}QmV+1q!oJ7jlvs-O+efUZ#rnS1Iaf> zYsDno3|^AaaT|8V{^ao_;9l<$Pp2;u&5Ym@?P&+S?m6elQGlm2en@!>FYgRI>%dWk zvGNt?vLxVk@0C%2$1;ALp>rLfS`kKGg(3PS=gUdJE#3!4aTvwrt&td+D1PPy=g5)6Vahb4v#RTDvUqV(=x(riEEU>?i_DEQi=Jh$7GMCSC9QLiCUj{g1@Gq~_bH zCWte+q?eV^Z}C+7bPP=su=v7D2euWc^ifVU!Wo^0n3>j0SRpgd;2jRuJRW0A;^S^8$N4g+ybtZ8RpDvZd=whFO~>PO zc49k&r(FGZl4sLSEP~%o@~nNp<4I2N3OqPyA0-cXd3TF%4r;#Fw}4S-?>Xc{t-K-W zEJJ;7wm$=5krepx#VLV7PkX>Y+AoLfD+yQHSJ}=EOkc0!WS#35Prwb8^@M$xOBd$y zvLv_bQDuF8#W;Wr+z9w-ibDuZh-X%^RGs?#ExM0bHLn`T2?b{K8TPJhD7& zwV=RIBgw>c$X$LJepX&X5q#Z#lW;JBF6Rqin2=Ap#wi9|u!5U=0%)B;BW+0~o+_a+ zo0Gre@=&u`9%{g{!S^xPfIvnSelY0}X;5u0mNYC!BO#V|KBDM4>gPz~PApBC#IGR) z6FB_x@~C&UCKNIBKlCK7rSkH2;zvXGpmTmK+BtQ+5GD*@W^pZ-n*6mW4a{Ya$sIta zlhCt44ilK$g(?|0b0sY+JL78j$W98hjXa~Qcw|Ih@yIj0F;?8`d&44PfoJK=&MzL~q zB&|2OSah6YGfFusgGbLSJhJ0@bR?};7~>j_$k^SoGvs_(5{JWN6+v7kfCs@cg8*?M zfS1R!RY{n&G+mPe)+`Qm@aB)o!~e*>5@Gq*QzlVB6htx=z|S0gn5igb!n2Qc>c2wK zA4|roJB}6VKSj}}<0EvmT(rV@@yj;6Zc*erf4uH8ARiRq;}UguDROa|7f%=SIQ%cJ{Bu?G=n2995UC%BnA9%zmQhD|wzjgA=4?E&@O8Ff>?6*RErpRwJ zZBl$P<@b6=;1&ZPFrIhu6O=fYCcpfsq-Ax<@451O)DSyv(im#yR};>+UdhJ@W8H>6 zkg)%jJ(i{;stWC7+4!t;Nl*8do}JrzN-pZ|*w#5TSklwBrL)H>F6r)V@7dAOIdXVO zaWVh5_YHLZi%~lU+Ad;}?cIazR!LXi_Rf;Fo*gB{?R~vlySJ58_93g5!Onq_Z9RQk z+IpIX`Ucvzb(RcvZ`;y0G+5j}&^L%84Gy*S^pw!CaHy}Zr@gDKyLVwvckhl}C2a%S z7xwn`b}sB}+tMABetTPcS9fpc|Hm8$cMtwQ$qnsPvaP*6R?kJJ6rWPO$gl1QZSmi1 zq7f*ts-tsj+m4>0)X?t!&O!J=X(K^Lckd7!7)0@mD0qg}!E@WdHuDTB zeiD#@i#hcVbnk2%>O>5a5B=JE+6D(BAy9UR&1OWjjKC3zf%R#`XzT6Xju?hG#SadQ z_L|mIGm^+qlFCPXaY&1#1_s)8BRN*}{N!79uufw&xU&t8Y;pATv4ZBgy|1TlAaHeW zhZ;-aPs;}hrGX>4jS~t(ox508Q*hyZ;9{+{f&996?(CGRnX-Xlh-{c=8nVkWbs*J9 zRv7b9m7sNlM1w;E-My^A1c|V{lRPxfL1P4wC3*WmUr$fq)i%)CHexo~U}3xZ1rL4j zeN{uJY|D=Bo}q=^y~f&eF?1sq#;#wDwp}+T$Ib9;*FHJl9aRVeD3P>_-5G>@ceGdF zx~1+kguC80LAxX$16@et0as|`y0(|?x<#%%9lu_Q&>U6lPA4I+*mak?6PQaZ_3K)K zDUw5hSDZ%skN-6E=1k^{d?%pf1+G1-7`R-@obRCyEc`goJ;T&xT(Nm7b{86tEJCrn zDC&}D{^X&;sEn86W_r%-#7v;F)oJFWkt`Ql;CXd0OTHBrGETMCeJD$9EJ*UQY zXWMR`so?Cge0P3f)P{Wv-oLSeE2p##F)lY?8USlfCiov_iyR z$CgMqD0?*4C;wTj0-x56CRV|4TA>hMBcddHKnByC_wCF_s!`7V%wpGG;CmI*k1g)J zFVkLtVwL8wIL_a8u(W=l$52V~_Z{R~foJ^Yb3L{P4Ftj!XmS}4DU7Rjh} zS1klD3*BsR&-Kn??aR^{?r#)7+2x6M zh;V~OfTjTb{Fn?K4?|54mv#zy`zb#ha_5aNbKOGMo{3*p*UOjRGXBaVe;n@se{K9E z^4%!}6p%9K^zZ?-&Y?0PbDas0GCZQ^m%6h-7EBujra>;zb;r*V0iAHR)O-SD6@BO@ zVBG}I`P9BLvfpH2FM?NrJ30@L?aeX)%aF5(a-(|!NM<|Z^W77i{(N_4sXNvg3v>qI zV=|p7EmceXz;Z2j3(dm{7a_)necfH;&Yr`RvHq&Oguza-2Q+?6014*J6S+P7&aa;pq+OQp5O9G8BEeo3vvRvrsYp6BJBK|#t9Ej|`a$>CH)rr14; z6p#zshYgQ-_;tOh?r3K$9`fLWzFFXoJrllWq=P9TeY7CQ8$!-1n7Ja_!ZhdW`_QdC z=UY}8rPZBDL0*)T(fDp0~jq#Q5&SSkjDpb3bIf(LEw|R3d zR3xHJD#qW`MpzkYvpk0?m8>1>o#mBz%WGlH(XkHICUYjBR`Z}+r!6G&@yNhZ4U+1K zKN!MRS|_9?AtI^FE^>>eL&}ja^(DQj6cuUOI zMtk@pgG?8c`&7U9>s%U4tBtcseF2FwZ`<&il>85Bvi!eYlYH>Oc?_dYP@C=OHyFDf zu<%uF8bIzO=Tm#jSWjoBy-tKD+gX+G&T!7icPA|^rioREKPD)3H}dhLiy>g5l17k^ zn;jz`KMNvJ&y8_D?i7o{diG+GC^0)AE?5Hp7sTak6_)%^SezV~&nT1(8LckPLvqp} zu43=(bpgZO6-M}2!`a%nCCU!^Z7{7n>z}nQWNe z#t=cw3j~p6B%y5YYHD-p9ua&Opqv)yv7L|KzyCC@FtlI3+KA>- zkqL|3nKR&&ep%*^5p)-$(1^JJ#>p(VxENXnHt>WJchUlPN+B|V4}urMZh~l!pbkkjZC{R3NLtT#`%<~paygl)W2OHZc+LODs5>u59|RfK3Tj#Drg z;6wqBP-~(?-MWwc27Y)RU5s&|#GNpUDv%2BQ7eC)Yo3=Ax4JV~0?(<0*2r-eBUa5K zckvAO6nHz{LK7T>8Q(Mix$lHYE|n2=oKZ^7@?t6T=n{8k4N9>NywYsHzRylfOdClq zSF2nMcxr>9MKY?0Sp_E1oUuWk2JJZKlZmd3EKViCd{^vm_Oj(AG8nN5IG$=F`vk;7Hw2Il2D%uc z;CfCjtl}3~(8*A0XoO=Z8b!(Vx?#!{xbB(7i7{zRz$U6pO~lsY)PVBhPYO6Vzs*#j zWKu9e)!Dnq2`i1lQz&S?LJ*NDWI`lza;ZCk)K5kj><>&XX}H&-WF=(@uHA<-mM8pT znF*RbA7Z-Loy*j)%n7nG66B<&c>!x%LbG-q1ld%1Vfuo`b4pof+^#nV(VRUf?;K1A z)^!Ob*SkYdY+kVlXqIy#?UuNCoIcBR*mV~c2?#BPf}1uIvB5mE_)}ZLOc%NCg82OMJCZ5u zo9)h6$@QNZMeZmlO_sDkYJ$#98)h1H5J#Tn%q-tMsnpG5bNExXQqEtU6Tw{P94gsT zRkEju?$Xs4uore26qD^tXUqxb>*4{LCe6flQvr9 zP7CI#W{yC^mLm|@Ld`MN*-0hj%SVaG$<(=+b?qj1=H`?n9T?u9m3pgIr>ej#&NZ_+ zqmRH{m_pwJ12dg3>r4qM8bc*|o%0~XdxG=O-eNp|6+WU**>SP#c&AI0iuGbVf-$|O*{=$1G9dvW{IL(Q; z1KOW^k1s6lSa3o*jx^R>Bx8x{Wz4~X+0u2`MMeHx-&v9Kh_PcMCRKqnr|Z?_xGSX* zk$9V`g_XknQILI(hca1YXDBn8o?Oorb8HmV?>bfDvbaF^W~wL7|EGurMlC}1P8}$7 z50RXl$A*=t#9e}DMSxjuQGt67OTX4FglSahE}!m>EpiL->lGsNLSvMSUOWO3njcFF z+_UoCLe8xUgz8ynfKpc)3P}siqR`1gjn&Cx38?{{_I&KQM^)WnvejQE81EXBNtX#Y za>#Ph+YBE$FwbVYV%}w7jet$(uPI@H=XJ=;1X(&j37o$$MCNMJ=gC8(!Gf82@DM0B zXdcE{;Ya3NuS{mUCzP?zaP3GIgRtNuO{=QS=z7kIb;&wAzGN+LvXxm_yZ#NdjGKpUXJxXi*PTIZ|ak{qb!3GTE4uuoRe zMDRpeitY6NnKS14E^IF@NwC+GC9b!AGwM|WlM6d8G0XEx8LuJMlgz%)Nzk+9 zEJ-QWs@^L~k}^-@^6z;66Lbn-YLE{14r({1sy9~GHK#U~*S1urD%X_Pt*)-Jy0DG5 zyKl#kZ0}*G5POzw14F6yEh+Kheqm}`&+h)N)YiU%?QPiKWK6R?IMBIuAjSPO3&fk6 zH`i9DYRfm*w=`R+)Ycun?Wq(4D(h?O8&j+58`qaNr)rigE*;5pu{GGer!!@CdS#Cs zxyV*sXKyo5Hi~6%MrxUWlUiw+(fnZmfb3 zZ|mva)(d|Wv#POtQ>wYVX$_I3^qhUC|mH?FI$N>x?YRyWtwt!5VZ3*WMQaq0tJgHsH`dromW0Hss#n#cM3A{4b;at``f?;kF&mhf5v!iQ-fgMv zXmoHeU=XX>-!{;;onEpJZ9=6PaSA3R+E8A_VzjKUW7KpO;e^Iem(|_|3F;o&ZTU?V zCT?yluWO>Lrq)zTokV)DS8Y)a7A-ZInsN@JNRmCe%usi`WjYd=yfdr|N@jY9lp0&Y ztVdU8_qMJftFvvOXLqWtzrSa<)vLY82uf3BV|8_1s->>B9+lDN?(E%$vIo3d-B?qV zYOLRsDzB|sT}OXubMg~n4n}njbq>(mkPOAUys9eN2HJuZ_05o#5y)3HRi?@t8_PGd zQl`3oy?65O2L%Ocu5N`~*Vi>$WK7@I!PG7}d*HXi)}FR)U|(1wN?COzeZcyrb=8|v zt#2E$+1iQ@xTUTA!Z1o>c~wnI6Ao73gvOvXxMNHIE(V6RmQLN=SOcwBJ7T7rYO0#o zSpCpxodW~VH`4Gsdb@{G-5u7J-9w$gRNp{%*tTK&clLC)4|VtT8s*6t(u)~kCysQX zL_w_^tLvawQjOK+Rhz@&*Vfckr%VX~ey%TXRWGU@IbzV?*`8_}8iLY|C2g#40of{x z=YYtVRL711$Yft{&}hCIMFn?;i9>O3sw{{47N$!>R#jI*Yd3*o>#CdAfd1+=mQ-q} zb31Ywf-crtcA)lf1~sg$F5g(q(5T`KLZw9->YIoQ{;6Ky2}2C_)gKAT&pq*PNHEz8c=z5~sRK@GzkoFrIVUQu0} zs;#eEokGW}udPj0)-+bO)Rs3gG$umpIYKm6S2hQNR9~?+wW_upiR;Q68p=^xR-Pw= zFr4+Y?;x{MGSCD};V=dP(0$QdP}R ztVX1eD5|{;r_GrgaAIJ$DN9g~RkhWvDI~5#FNAPLzvvt3T_%)8Z98v&{*G)DzDp&A+I02;d!BDle$_PBK*jLboE05_5l?iNjEJe)>Q!PSnVjYHTqMJKXok%&@BC5S7iES>9R)jXf;5Bq%Nt{w%#4>7&62h zG*#>AgS4|C=t?cM&8d3njWMN!J_%bjQ2xDr7llPHZ>&sFrR?a%!QtM{j(nUD9$+m* zo2x+#4GNm?&17gdn%C5j;3YYB^#?zIdC*kEdV+rWh! zZ#j(M$ek}fqN_3cpssH3>l^5Zh>PkVe-4AnY#rznF%xm<=)}=jqviVh(7;B&8Nn9i z1})#zlxnCguY{b%ZA2lV`Vyz_I$;ci+-wxNNi|j1HBks_nj?d_kX}_=zbQ%+hqLU?EILF0ZW(OO!TvsQm)D#576HIU|v& zxQVBOOGSB8bqdNM)!1Ci(wgduaHcg;UAgqMAm>KdY)C5FBi*v@Z|i`%+B#%y>D!gM zh%}{AYV^Trx*?TCVBa$q&RMqi@5WHx)7dtN!?m1h(m!2)qMLTZVBQ7$2eUU6M{M1i z=4yN&Jg6ZhT}n@{v}$m0EU#@?Q*H%z5u(I8QC)pqgvS`VFb-5={4zSfQ*^LlrDy|k zQU-bckv7g&SZWyFlr}sC24K)DgRDboHsqStlvlxyH$_KMGS=4?#%@8KMW(I6_5m=G z^L3eK_?iNhF_Hmutzjf63j~2^_y$z>#RO#c4&NQ zeMU?x8AOeKMn3DRYAVZVw#nj#6v%Xg?!gq*a7vV}*fRbygP*nuJ*~3Y^t7<+bo4>I zwhP0I?8wBSs+`LTGJipG6X06_BU_W`D&$TmX=1a$X@(=#AdnI<;$R-b4(x(jrC>8$ zZHn@`%IaGDT}>$$%v_9D!+26Ne1xbOK0?$CA0cYQIMkX#NK+LpH5db7o6<&;WtVg_ zcF><8g(Vb0l~sm{YAjV)uvH*1G-ITj0%cBa^z&e64+eG2_n^c?4VftqXBwRYoM}k0 zO@UO50TIM3ak9 zGTv*jY}H(iiQ6z4ljWO0B$|)~)}F!%TTqbINZrziwY8QC&XNK;BE&}hiK<}df^=&A z(LyjGv8qCAQfjQrgd9t_%z!l%mC3Z8Si4NblFf;nf)TI0rMaHejb;_LrX_=Bfn8o6 znU;WmT#bpY#q3Psg#eCQK^-b;n%9>%UekiO zZ;}mVHn!zj5dj$q|CzVD)18jsB5Qt&R)e5xb4cl)9z{e(l3pCzW|El@vVx@|W)7xvS3n#yLGe3<RnmC5sQE_r?Lhyst)A`(=!el(U}@e z5_D>;>A}QKs~(p$FobX&0u_jhE=rHl&a{s#LNZc}Zz8r4nzH91Y@;D-WKR}iOsQ3W zr{#wE4y+>6CrvA=p%^SZQMGWVsB^F@1&(bsBDxI|wuoM-YgwN@xHpmCve+QCi*zv4 zHN#RHl|=p08m@(>HRR@&%`$HLy{rj(h;kTgf&~%?p)tz3xu(`Euc%~VYGDGX+i4}p zjLBdBk+l;ulybX9)tK3*3T4X-tGe&TJp)k@CWEjN)MQNk#;Yf5d(suov^B=SvV|Pe*K*=ZJ-;r_hYWRrE^br=fEiz zyPudzNEc!MrpEGyGzp+6bJm;MSkqL)aUD4ZBSN&izP~hRI77fT2Uf&6pjq9iwsx>D zqGxnr35x@5(tk&k@)SydrJOdt=8RSP?wy#9kqRX*G;-9mkOjM-X$<#edL%ZYSrZ7_ zY>o6&{tRmlE-zzE%7Q6BG|;va8-858KuQ@`jgVGg37NCqe0J*HDXf}tF#$^g7*=<* z<9%-3iwvzWXncRcNS6jk(g?2EKGdDVz_+HZsT#Y1W_LE=UHgu~p}y@YRnwq~_}V># zl{7{+>WY?>u!kEu@D*z`wwD=Xh^mE~Q_)Vs4GUexMC72Q#1izE#YGgET`(IC3Z~Ow zDs48Ju_d;24{dMjx1>PZ@n*Xv#)Vm8Gw;K)0WimI@9e_73_D&@BUVCsShVIMa@ccf zhU!HR!`jadSoJCHLs&yy7(Owl?&=%}JC(3R1W1R!zWz24~-0CqEtRtT4lc9~@{B!VJQ8)vY$tv|KP z$XrL?4pk26!&WFzv^T1;3+)%!l&lgK59A#jl*UqZAe*nKyoht!U==i=?j*{(D;7ok zRXf>Y2;~n`Pi$M7?J9pSCK#WLpsVo}*mH&-V)E*AHo{1;=YujJ9Lfr-p=Rc6)S@&G zmsznai?z={CCcI__ezbFn9Tj@t}#sfAp^_PW-lqdW06aNmN91L5T;V>=odkduPUWy%x!%XBidji5Z#rIzt6{6_TJkFwx8|EKG2|~U zUA&}p>7ph13o&Kdu^h{i=vWKePKSFd+`XNBy$iSYFIq}>PhZ>6La6cOXs8Z&40Y|; zz6IDe(B8Ei-?P|x+QPO4+xr&`cD65wB;1z2uzoOqA>ONBjwSTPyYd%q; zn6nu?b>lH6)M9CIN+PTDWF=PCu`(4X;jl2Ns+LBx<|+GG*f$rs)h#O)H5kvsWp3Y8 zGh|>JK0!lX3J29f3syMkJ8nG zo+BH`mGyNPLd5=+-8d0rS$0+>uQDeb6)i1tYVz|9vQTt_nTek|$c+mQ&>f9+7_`&u ziJ+s?L<+Xox_f(J^q84+SU+9Am2EU%{~PA`W|`41vKJp&)mV=`No+Z64htHp4RfR< z66Et4+AJ(-D8My!8)1P|aYeNpLmdNRqPwcb*imVk(k$5deVo#-mNV6Y@ISEj0|l-Y z#-^I)H9XwJEjya&!;KqQ2e4nTey|ly!aM?-Fj(b^6UDqzMux~IkE;6GcW`xPuw-L( ztN-~ZGjwuQ3S^}p$tD+SomM@w1&8H*7FG7Jf|d_tf|F8OHAcHe+aIJ=}(m7&xMBMRUk8I+SDha*C*EU-22Ox&<2@{sx&5Zz(5w zCB7zOOnW(=+0|(lI7~70pp@y_!XAH6l?fKlX9SG!1xuBTY96ziVLCNthmloQH+w-GkX1R-rmB!0Zb9tNh?gs%)qL ztZ(~voOcl$o$?W-V`k&#eAx(f=WLvlzHXSgutHHPqXgQd{M0KpMwXt8gEAm~~@hQU(FB0?Y(dHjs5;T6-i9A3+nQ z6XxNUP!~$!BO^aMYIH3tA`~+Ak}-Z8ab($vNsvs?uvfr*q(fD zM5>Lj@diP{Ss?TPIhY)@eY!O!T{W29hXbc>+y^bNrUvIwWtB@S&h>C8Vz&Hn1IYK} z97YVgi1hngP0>!r;u|(Z52A&KV6^*;P($hvpIM=3ntqu+ICC{q*MC*14p)cfaLfq) z()~v8Ut&?g%8vI4p^;swb=8|?AyV{H*jlobg)z8tot|$Qybv2gSfRoZX|mQ-0S2$E zI+G3XG+*R03Xe7Ao&&Y*KnivjX{U`yEt@yO;Fn3nu&|mXrKM7=;4pfB*Y3!sR3KIB zxff}USOVA}-hf<>fa_b+4@O!RVg9n{JRd*e z(YX9#7(e6eU#)m3&z|x=@1T2W@-lqwBvuA|2aU9@w5zj|{JN-r{VV>_GF2cU@;T^S ziX2keSy5VySMe{_Gg_A<(na0;R_)2S{fpnMt;jAqIQr6z%SK)99dfTo9(LZ3{L8a< zwP$7*Rp85S(fItf?TGO!vUepuXA+e9#DV+dz}M`_o2+w501LjyUe{ZS)RSDCwqFu6HJg* z{;m7IiLdG9Gl5=9fR$nUw@5_zx+LP?b&J=s9J5f{@>h|$M~86%ft<;3Xc zSnCiT(#IcFj$Dp4DdHmiycqqwSoo9}{VA6D_Pf!^2`j1*NpD&#{RuJpC&a>M#OTkk z-i;V6KlOUTnh}f7RtYc1niZozD-6VwV->{c7g$%opY&UCClJo|YsPJ^0{=nKv1Z5I zMX~&%J&gIyiRCxP`WPrMKelWl`0BYK>!fK?ravi0|0EMpe;sQ$Ip7>6gXmFN=kr5u<;G#1F@2D!TA;q&G(0%VYGHhk0{=)+g{AUXFEs=)jX>wZ+QY77K5WxjSOz z?U3|01+hA;PR)NJ{A}yvK?ollYirECEtdbbSa^5LeL*b$3nV>lKXYAR^=tkd$!zPm z`WtYpo>+c8vGDD&@a?hizF7W!v2c!F;pJEZF?s`GAf6m+C`NBc;-4SH8Va8H;8^@a zF5%@^7scpb6b9nSv3AGYdt&+RvEBoIk!7@v6V@J~$Fb2|d;AAMC-|!v#@n$jiRFJu zEdIV&e*3JeG(Xze32UFE=O3apmx-Srar+@e$9iwn3HO0m{s&^=2V?mkl=xx)K4{&j zdC@Ylt&hgiUlwy;9?S3YSojsO{Ag{2mt!3c9e8rA_s8hHKNkMM7`+e1!mo_EKNO?) zp;-8lnEUD&{i`MY^+Bwwt-5iU5OU(W0nESIa_iZuv z=VR_K#N1zux$lU%zhr$W=v&4n{aVcZbjTounE>p))kuGgL@+Eug|8rtE@-W%^`52Rb%~B-CR4F2>a#F>gL+X zM61!tg5L2j=07>+K0W4cjJYp}xevzN*Tvko!Oi+}EoLI@jr(KaFT~t$#N6XpF}+yc z1u^%TF?Vgu-5GPgC+0pBb6+2Ge<9|6Eav`2%>8=IO*_WFSpF$7_rjQaUCg~X=I)BQ z2V(AvWA4jh?vKaZUyivSg`4el7w(BxhxOA~_)9VOs~Z1eiGP8WK|$4v^_>}Wp9(kW zFTp+0>a*(9O&ew+?19c${DGMJ(wO_YnETT)_X9Eab20ayVs7(Cg-{q=EdPvA@+d!a zFN?X&Up+E$7=A%4e1FXS!I=9aaFZX$rGFf>zN~JF(L~JFf0*X}p!K@CP5WGJWoDSX z`OEzC;3hq;cTKdev*yLZm&DxM7LdIHd_~89^bfR{w{44ttfG;RNN|rS@?wtf)X#yu z%?ZZ0J2Mw#9zA#i&-7gr(iF_eEq0c4%V4S;kS~4(4}F-Q^QB>xca*^(X&*6r`bCXh%5?IN=@Yi zhkq8@oNr6D_v66JK)?unl}caCj~!@0KC)HK>X{=B@ENu{>c7B=uyoeSn`A**&AUW? z1DJPO)88**YU3Ziff!Vu2Yf?rP>iG?;kKLE`wFrfAqF?*f^gP}6w-Zo=p%MMLE6^H zhrU$GvtoK8NQxYM*dub*#2n;{umtUw{_eLqj7h%ek3CZA|ajumk*1Dl;m^{%N;q3z{3Z=P_kU2 zveLtufBXRe+GYXAwIA9vklU{29GRH zGcfU-@t=Q^L59;5%zR$`OW($S>D&01h5pgp5L0i)Xd*mm<^(wzc*`NM6L#AR#{k80xq^> zwI*|!WnE483jEDj;>(t-s%HKHb2_@w4!09uL3v?#vOVSzu@$w2_(#jy4@_*atb>Y& z6uAyXf3Aro9HlDW}@6ElJK=cv4Mzka21;604XWQ1w@p0fQUp~ z#bZ4V5K;caMAY+XBFZP_20x}Cf0mnn4>|KsmbH@jXUj?}Co++8A`{N3S^i_hZyOsv z@fXXwiSE}x9M}8{4YD3H@yPN@JD|KL(~WX2A)=gRM3fUnlk#mOzOL=_R|~TvxS!X0 z0I#L{4NF$#Gyi7EYD?yu+8%$mth*Wh56ilb_?BfoMnt|pRD6+$*#fF=W!kods^V`s z+ot~bg6Rs>BQt4R4a5_{XCl7B-a$lr?^0yDlCNw>(j#9;?>G_kULbvf2TN?cDwIgS%ij$4Sx z|8^qE^9T|7KSe}+o*|+>uMkm>H;G7}#99Q?bIpY5bBRdbOhh@)SKLWNdhSysrb1qb zIcOjHgWjz~l*uW6Q8pzu1zGyfd52x4i~ru^oft-FR~M}&^Wl}4+@AL z;*^o?Gm(gL%qM2sMxP@8v+0KZ2PrAnULyQ2BaXANiUqot7=6L~ZdLc~M7ZxHLO4GL zoVf!(xaN}xFZ7#y0O`#kq8#WVl3x{Zf-QU5nMl_KH|g~#_7g8P{f7R#=zbJGxaPBP zye6WZ0rR00a)GQzDKIFJ`?XdgdSz`u=Jn`q^jH{bhAOsQ4W5b<28{cmnE+B5|CW17yC%M0hSE zLa&LwK%=apdj|Rkai(n@CO&WUW#%l~l0VT7_v`creJcS(|B(KlZ(IC}*_j2lbq2A} zwzd*yLym}ue=8C3?NSxQ7cV4=`mMTDb{2tIBkg6Mffuhqh~v(d*tqjBh~k>>FQr3H#C^L#%8j_c6uJxX$o^DHM1PWcqFbd*^iDX9w%auxk=r(5Fd*5Z}j^+=?{H$6)=$Nd*I-O@{I?G z{wL12Wqb_!&3%l7OY4zXVEStUg~)(+Vyv;F692At)D!Cel*PYRYbAbQ^cFEs-P4Hw zY5HN}`xZ`}n0Vv|6hEQJreZ!|o#2CtD6+UA z5`w=`{F@@0MEub;1lbQsXR#vtAKf*ITNJw#`xN&p9#Q#S0WKQaq@5 zwc>Hb+Y}#Cd|L4Z#g`S|P@IUhc=9J-@npqCipv#i6gMiiEA}g1qIg*GI>nn5zo>Yh z;&&CFQ+!47O~px2j4W4)Vwqx%;zq@G#eT(oidQOrRPk2DdlVm4d`9tk#osIbRnZ%5 z%8{d(ueeb0OvTlTO^W9$Zdcr+c)8-8ihotigki+`&QL5-EK}U1*sr)#@nXdTiiZ@h zRJ=yS&9=C zrzp-;EK*#cc$Q+T;vU6Aiq|RLrFg&MqlzymzNGlF;-3}YP~@RyDW_tV;zY%%iVGF% z6wguYQrw|<{ zinA0?R9v9ANbxkq<%*SxHH!6$EsEzTwkd8?+^#sNxLa|b;-!l3S3IJ4o#ICo|6TFZ zil0~flHxsz-&A}^@o~lPDgH?DS;b!{{#NmiivOkfcSQ$lsO0Nt#c_(06i-krP@Jo{ zQ1KMS(-qHBtX5p7xIuA~;=2^v6}uJt6n7}TNAbOimn(iy@xzKYDBh^}NyX19enIgo zieFRwmg2V+zoYn{ia$|&Uh!9ozgPT|;$IctQgkO8zK&6xpg37^hT?3+lN3u7PgOiq zv0QPr;(Em<#m$NrD;`ihq^il0)vQ}LUMPbmIG@g>DXuE~F#;&jE66qhNkR@|uAsklq= zBZ?na{FLHtieFUxs^T{kA5eT$@w{+o@DAXN^z`Wj^b3s zS&AnrE>K*gc$(sJ#Y)8*#d^gS#d8$f6t^jER~%H_t+-F|QpNWx9#Onb@uQ0WuJ~!i z&ntdO@gBu*Dn6w6xZ?K|f28=V;x80`tN2I7|5E(BqJs&&=sU%6ijx#iP%KcKtGG~c ziQ)>yO^O|g1B&leyixI!il0;bisHSB-&TA|@h6HeD*jE;o~&}AI94%7ajN1h#S;}5 zC@xk!U2&!2YQ;Lm7R7TF+Z8WR98|nm@lwSr6|Yk~uJ~!iI~4CxykGHg#qTRVtN3fh zzbFR4{H5Zk6HNNKifa@*6!$0|RlG;>amAl2I@1lE`HCwQ z&sQ8!JfwJw;@1^_toTR8j2VXBEX6Yw8x?yMFI7CI_(jD>6rWN2yJGH4EvI6+Vv}OG z;th(oD?X(7Q^h|ij-F-c6)DaqBCiVK_pr{axK6`2s{3rk3lw`52Z?CUz3M)oc)9vt zt?p|TKcfCOtNSyGpI868)%|tFZxKi?|biyA&H-^5!${7c)*iKy3E zid96=Td$ZRBHo3>3haBS`%)s(U7>iT`rn}Lk1F1#_yxtgiJ)^Y5#@MN{hwC+sp9jB zza%2wpNL48Q($na;z>l5W1-?w#WNIF6OpcqhDFC-#-9&s|{NW)htHY>I&zKe+XUFz;pd^Zv4uh8%h5wS+~ zX$`+k@eU3Dn!3NK_#hGSpVaU_D88w9!fcc8sfy)_>xhqIpF!Pw6%Q+3t9YB@-HJ~s z{!H;VimxdqicEgliqjP5D4wQRsd%>Hg^C9iuTngw_*KOR6u+zZC&jlE^G-DR&s97{ zv0QPz;x@%W#eItJSG-Q~Yl;smzM%MuV$K|s-z>!iil-@7D%LBWqqt3Rm*PhhKdtx` z#rqV0rHH>wE^;(MahBo&#bt_BiVceAD(+Ogn20r&_pAF_BKpHo#m^{yPVtLG$nV$H zeV^h(M9}$(;xCAZ_gmso%X&lI?mW0bf3)IM#Tkl)M5J4&?nR1AiJ-Gdv0w49;!VUG zEbFsGr2hi(KFfNPi2S~z_^jg375}98Uy5%Mk$%)kCfyjt@kIEapzc|U^N7f&Sg}I= zS1HyjHYsiddu^R z=wvJA5D{;tx(gNOs{dkjFI7BK{a2}btztb9|xuMq-2t}kNkU%7~5D;u34TwMz6Hx5fyNkUm z)&+G}?7B8=yXx9q*R_0h)z!72yQu3f>sr3A*O}McOfCf7KYqV?DmrN2R|n`6KZ&rGF#&KVsq-H~thclSI4sl{`Qk zBNmGjNa&SHE*F<6y+QISajnvi6VDMZRsNOYbtL-pcI7`Hd8fEr>A?cm??f?`M7fFL z9B~N=KUa|G=SHzv`Im^>#5+kG$2?AQyA_{R`m2)P5Z@(H?^h(od!P^>jIUG@a!)ZT z4ke*KS)4D{izkRzi1&!U6WLlBbC? zl|El`wRn)y>m{!g*C_oc$;XN(Dg7MD7l;=t{W{4vird9|#fM15^R(n=#TS+SC&}-M z|4{n3l7A3`V_iGxB>F2`9HR6h$tB|cN}nZpjyR9R_+6^}dJ^N{M9F89uz$XIk@9a5 z-y%`|0}^q4DJG9|%cYAsB8DCQQ#?=UmrK4{+@kc` zCEqFDtMtbuKP5h^^w%Z7DZZ=po#MZg{;l|<(vv5;?UOF{6Qkk~@=cs)OD+-jSNbf; zbHsT{Uncobu}#1AbGMlUFmZqSBZ;A z*g05iCt?3+@(kSPO~U>q;x^^qL;fE3IZJ**`Ok>YEB!4JcK$(PJpVwVTx6;%XOpMn zxrUMllF%O|mWcDk^(6c|hCC7XwUY4fGVyBV-y(UN_-my&qI?ku!_hQa;xBNg7y;` zmx))2*OSoSPJV>rZpnWjVee}(b%raC5@(4G;_>3u;=SVQ;^$&YscUDjI9;p}TgB7F z>&1J;m&FgoAI01<*KWQzMyw$RVcr!_5icS+9>wd$o5VZB?c&4a2pk_seocHw{EPS< z3BABfm)Ruh=_w8thl|DHcyXFoCe9TXh|5UWKb*vVtVQYV;?YXqB>6P)ToUCri?@(Z_@5>YAdy}{Vvbm@^uxqfrC&xa!}V9C|4O`H{EhfD+2J^E zN`6QDQ2a#9EqC?$kcfL23BN{(MM|G7d9GL^E)(m-Cb30q7f%z<5-%iC-*u926mJ*r z6rT{E5nmz^*B?lf|4`|lh+m4|h~JXXi&VJfMu>$Z(x;P%ccxe+E)fZU?c$x{gW@CNGvagNYb5OdRr1H;7fKJzcJup*B_#HnlO->be30aJ@l5fT z;-e(ud7ebvFNtr8?}#6YpNL8m7=Ssd+d{BH_ z{D+ua>DnJ6mWoToHR2}mViN6g9f>$^C*kj%;)CKN;!EOd;yWbDeIogD@f-0!;twR^ z-tRz{yW)G|Mm&~ zzCfHP9w5#jp*NpI`BurtD}R%Cws^jH5efaf#TUd6NwoK8k`t<2y?!Lp2TCpz@osi& z=P2=9@mBE(@sHw8F)+`y7a`$CUor>xYfGL%zK-9Qi1Wln;=$tK;s)^;@f7h4@fRfO zxs*hE-J_nsOdlkMmmcMf}czY{zMm@~g!* z@pSPP@i*d2;+x`5@kepM0=K^5;v}(5JV`SVD`vst`SyjHxGgx)=p9}stlPm3>#uZnMre-=L$cZ&Zc z;n%k$>?c>dex!@N#J*ybgkAxOa(GRGUnJhD^xMRH#0SJDNa+8LL_5E!^moMfl>VvY zFT~v>%Kac_FM<3zj+4a!;vlh@gnqTyBCaRj!0`@=@@I(`ikFI4k#FGlt|aU{FTN*+ zm%8cw#4#l76^j#;exSHgJYKwByia^b+$AO-Ju~IxtJW@PfJe&Lo-%pd<@qHqRIPVgFBR(cROWud?r6vDG{6zd*{EB?jasDM{ zIgtC~I9@$A;bfX7P6MN%1Yw{(cH}0*S7E zFL8u8UMv^e#h1iT#4X2Xn$e#cakY4?_zUqPat*etB$xH#mEt>Md9s_oM6|yTLOJ`p zAMh@vKP _@x*@-?5%P;&5@QxKOMUFBb0+pAlaX-xvQOnpD?*nwTe!5F5z`TrU-W zExsszD2CEpy{K3umWzjq9pX9S4dR31%i^bER=R61M zxftUv!)3lWjhv71DsB|7BrnEuEyPbm`}>g#@Vn|v~L~ zIpU?Fy{{j7zoJ}(b|WX?eh3oRMM60s=E8h&8rk7Ei^U_vbHuyEx5dOyJKA5A~UiSWJaI<84e>3ElB!4D`@?8Dig z=C2jEiJyt~K4avk^>Ouvi4(*c@ksFk@iy@h@mcY8@h{?M;=ja%zHU7e#U)~g_zUr7 z@lMg+mkd9jmHdYIf%tDR)X%lwTO1~i743b?urp6`Be~siP8P2t@56Q~Vz=Q0UUi=j z!2Knf)$S*wB(|;LB>DuKgx!BnBC-9=AhEq*)3n>mLUMxMc`*gw`%*5`^FpB1Mj7+W zMshK(OOVTOd`DuQ+Du{|yMkQfI9o`Ji>)N)i|r)ll?O@8J3GjW(O%?L`2LAR+BZve7=o&|V? z((UsG&>r_wM*luSVxRXUiT-_-ME|}-;`olwW@i7sO`?C_Ba0m8ZzTHna}xdg6^Zt; z&nK9J<9^EM-%tQVqw$%|?B7fh{o9j7yY?s1u7gR$KZ->EjwR8*lSuUMH1cBf1Bw1U zki5Zh7LkaD&nsg89!{cv8%gx<8uCfR83qxr!{ZvnJB>uVhmwf*SQ7C@BOu~^ltjEs zl0d|J9Eo^uAQA5~WSQgG;}*nw1CL7(?~^3r{VR!h4eDaN`6S|9!2LJk{et^X#5=Jk zh-i1)52hx8(0gv?CtH)NVF@T+roHekZ9j3$@Y8!P9G|H1&Q`vE4htCyI&)D z3yJoBLGmjk`oRg{5B5VO`eU@@A`<;##}o2bQ%3)srTp_q^wS-Zx09TIB>#cD0pmLe zqWo|Y{Z}J-8Mz(yC9fvYpX()WB+;*1CEr0l34aSZj#-D7tAp#?U9R@l_|QP7z`i%R zpdOETEog6ATfoGE*fR|E7FqXc!v&?)^9qn%SHDj!T5&a-8#n%>W?X%pFM001HlNNu z>x$E}HSsBwzULyxR}!DS7yElt>0(;XSnkfWm%R_ueiduFo98vhSJ9o?UaIO&HLi=h zdm^+QDsi2>Pu;HF?0=4Qd=Rm**F|YBA#|_kRTg`uXXiWWJ6}fK-j_Y{_fqLz zb-V^}jq8!y@z!JG)yv zSHlO~ z=ZLpK?86UFrF%CzHTLC&Ppcaz_+ap#;fQ^Hc(jrM=YRmWdlS z-lN?2F=jlK?t8LRV_$)H)#}=xv1i72+l`$X`>MmI9{2BEuU)UJugBR2?BLYZOF8HPs=PBhl7Yihx%cBlE3c-aAzI1=mDuWxUz z->@Er|A(b7ba6?-!R0Eul!zXf$0Z*huH$lmUAog7hTI4~Kc%-6I`Q=mwU*s~xQt;J zUPr>EFK338aD5fe@}~X!@d@cexe6cJ^U58Jb^pRVE=S>m^|n*2wORPW+ILC;?kYfW4WjC@yF2!c|Ux-#q;MHB>3&^^4ViL>!rQl;Ny?O^ApK-@#6RZ zl0S~qAhSGeaiKjff5yjOuM_T!BNcgGz5HIBw!Lw1o^Ktiv35oAF7`5!zG*i| zc>S36y!bD|x_@CFmoir`)*rmSM|-rz#fxJa^!#z;`QpH3)mXi!x%Oglu-(0wXwUPf zF3#R?UmQ6;d&kP2SMEj{@h!-<%eAgvERLIz$~b6?ixA z{(4vV;^3U()yw-JXxob;1YsHtY4Q9il%6MZT=*AHJjB(D`8Nw0^bePe?c(`&5cK^1 zwfX$RrR$h~ypBrSo`1Z~yUaD!#onoL_BQ$K<@@aMdB(H{*yUylzQq&yd}FM~;-DVm z$d|4c2k#5<$FbR0?_lV9?Ocorm$tn)?tsAg%3C~tcE#D-0(-2N<7Fs5p1onR=au6) z^Dmyr>&IA+#X&vVqb)989K7D_k7KJZjuFyhxliKacpCQh7RN1d_8#=bG0JD}&$8#m z!S9#+iznv8QLM+}pdS69EiPUh{juVYV}~z}0_m~b)vmo*f4mEOdy8X5oV{0kaTNLN zT_}5A9G`oRLx+ne^4*nKkHtYf`a@e>kZl(}AKD+spL}tQlOD?r!*@Bf?TxE{LMXEq z+<%@wLFoDIed4n>9;&RD_WH}7S8js0;+l)a!TXW?aqxRNmZvQ)UK~^7>fPyg2yW zY=8SjQ7^{}>zyh+mitEadU33PJ#QV^v3ck5ID18~$MUo{9UrehcFLaTKHtOOU%WW- zQHj4l_`MYE(H0jkj{eZ|$1%wlN160k?o8KS%=b3f+gluqE_A8Ka^qZkv9{&+hxn>Ews>yv{yeskCtv2R zNYiV-nmGTifFA3aCq2)nA1`TSb|UC+PcRPR`o-vWDwYn@=d{P6xj(rag)VDKIT zZ}IBAF|OWCsCO%rIPR=D_78kGB=W+E8k92Oo zOQgqgdH6@$v3OwsU(LrB=JC@kJulwv(Br+Q-s06e4SN1@FbVZO2qnhL;~46(-dfr7 z;$7w$MjjW>^f|6xEMDrdJZ*9D>OBLA{(5)$;ypxqEO(b{FBb0#*c(YhTD*9_m7eF; zd062)3cSUu_w~4Xoh0|&PmGu2#*25C?0NBCk>Xi$>BZX%L0~-=FZEC~HU_c!&CgC66h zEiRtkNa*?FJqz{bA)ocGlOD^Rta`mTc%QBRT8QUQO`N?gzV>VN**jYHV&!1Zzj*z2 zv#S@2qegMi78frLzQ4d9$97-6?b2f$yH&3j2k#4BO+#8ddoRY>+W~u%pu=`qj}P@| zkMA>}uU;HacN0f%jC1J4;-DVO(-s%6-X75N$FbWN$I;Sbxf!m#*!K1U?D?h*>l6Jt zUwU4=e}LYhNcR@6-p06kBWcFogUEP~#m9^HRN3?5E%Gi{$e`D6cer}7c&SIfX^V?j z@7B0_i%_pOznmaFmg9REXxocp672QEzR+7dd#}dXn*n>gcZqSFgpU`;XR_zTQNxQV zzQv1!_oZV!76P>>4zuz|Fg+^W+r$~?G_#Oy<9EZZ*7Oyg&z0q;@w!j|e zNyc%S^k{F9?0Io~myJZ<;+fv$>c!%q9?R1f7cUOZi~cy4;T?Bg9A`?8FTFhnIRo`3Jh`A0q0bGFs$wEcf^{;l@;cP@141IzWtIQO@6W;g!j zNYC>(w;TUvyLz$qqaN!yA0IAW>@%U~Z@-N`|9&AomOEPYdi#%lu!qoM3w`J3G3j~j zJREv^+h1N0SMOPm^XI!bdwHpt`|q1?0My~b3IEgSr?aSu3jvTT1}~tkGztn%)Io;PNh z#5{g>$Ju)XdV{H;#p{oMLeJkHGteKyp~LZfGd|Q~f8^jK!ix!_^B(N|cNy2*#mmcp zp5NYT*xNPHwRbC2J$nPX_u%9CcP;c#yv?(B#bMB6tosbxfD+JSb>g6FcUMQx-))Mn-My&j{M~4wuM=mSzdPVuyL+)S^RvL9 znV&f`sOwxAsCe%PuhjXw7fG`kr4~D#=^>>jAU*8#xPmz*u568TmOy7|tn9VB4~8d6 z@MJmCBhpERCx>+LBoJq9xik+(sY86$&VjWwSUVf(snSV@wR5{z3&vSHTbk#f)VVQh z=kLx`dKS{Nokw@Kz;YWbxvdk5v(h5%R%o~RtmG=a2hw}O%CWF=e9THhoRwpxeH^rp zk6CehtT#%s$MU4pC)Q)(D=*ny81+13A9vqd{ZzU?EbZs8T;i2(pSk7s)l>QKfIStJ zje)VAitNRMJ$vc=-GfDn`A=0j)2per^`Yn#dOK4|lq`9rU8*N1L)x5Lnv zxq;Me%niR6nlr*~gJ$^je~$k3@a=7n+RYjNw%;~vQzo|ORGZJ%ISrnjwtGwwTj@tg z1&|7hGF4*x_N|*tMdp3MIkX(IrJ@yHF6<%ylB;wpU z*@XG)^59=F-v>tJadu1&B;1Ar+29p8LI~{NyUr#h@*O_G)jg3kFAs+WFq5zf6$I@& z02lP;X%sB~9#;;MBMIlC-r=EyX58NrTt)MFIb~1?_QakbI5>9+*D+%{!O=OZiCP*j z$~_M2BSOK^KL`KrLwz=4Q2JUR6R6v+(ms53k*d0aX*|o8TQOW?l5Rj%;R-kRV3YI( z?1yK&;vpvKOXkjT#Y52&=fQNsA=#`rcqH-?4$a=d^?%@B!r@uhaQ!;$vJ>i~d{KAy z2>i?Z8Y5zG;((o458R5DPK>IB_?x`MfvFcFz))Z;+A(pE6(WI^=-kAiskg>jC~>@6 zXa&_KWJfS?as$)Rkcku1?nSkEfd|o$iIc3*FKIF^QzY)6z5_V{$0QvGzY{0BV!$Mw z&D;a5m>Duj52Do*r&!V8cV0n$SC`P(@858^*GimJ1Ycp;tNTTOO#UFbDpGMd)&mD) zFhnYQJb?Ch0!P7Uq{{YPC~zB0L>BbwkDS~9-=P^ALI9DKJrkfX z$qtyv>g;3)Qvy-c8)>$}jKDnDj~tP_9oA;q0TWqcn`4d>JO@rD91*<9bD6jywlZRR% z5@F?HQ%m=oZwLS zlsYiT%F;4ZM{-h0*;wqPj`DP|KH61I**Mlo9b?xcDaT;Fz^7hT-pe-U zU_Hn1C91iGuU_n7YSB~~W&?UG)9@i9S>`6_q?r5hKh->k|7m6%{zpwY^rPkl*vvPV zVtN^9=AqOe^CUWJuo;H`L(I+48EPJa&0*#S1Tf6>g=Uud8~$fH!6YE<$>0*yla`vk zjD4DwiBXik+#MfIUc*W!-R<8bd>gZDdR>rT!$!8?-^fUi4a6}Xc>_I>YyuCkyEuq>PlDPyqapo2 z&^7}QgJTkHTiaJ88csVQ^E`%b#GH(9GR#)=A!3_BVNLJ}`fT@+8ExqkBPe|mbRF|P zDlq18v`@eshYdMs#$r8Wo`LNICwL`VA>-&^0t%?~@#%cWG(2MIYd~Y{!#AAZFR8mJ zI1|}v2^ptf584em;|#kYV-s(yb284%T-p?Eko&M%m7(Dx# zLToJqOcfd~Y6ieszS$p^2bvF&KFIV$&kQ#0sCS5&3Z0>5Dq| zr0IZHqs)yMKcmf4&>v%#BDw-|F-A_m=C-+>Au5XL%@b}OU?`oQr>huybl2KeIE$okZmpqA_I+c((BKFh6aor70f_A zX>D22KO>AlAsQenKaX|enbL?ZYml9)`vp#iZ&^drxp71T<;)poH=F#x59r*i;W-@B zg9F9P8I^rCY!?MCgeO^}tx$q9cL-x_nMr{^qgk^GthECIyU+w#g;tmn=#LJ~DzeQp zHLwY0vc}mm(*h5%Oo?@8R^V$^I^LF|p$ULcT#PRN>U zjT{&_k}e%!jVugIp!q3Qs0sWRV=il|wYV&BB^o1ZhAp!^a5Y9$R;g7xG;lH1%B-*= za3W35v_fOxa}0p2Syosbm_Yx^t+lmIFi6)cg4_*fvz;S6T6H({?AhUkh~H!)ZYTU_ zta4O^`Nbi+zzMtGfCZf}#}((IFrP8R$uGPbexZyL-i*p%)CuorOCdzrJ~W+&_ofQ< z8nX$R0n>y*A2Kf?C1M7lPcuyr=~2TsxX&;nF~snl6o;|=(+S_pZPbZ6 z;R{%ev&jkHWLF#${-e7R2=lNBODMb zkjK>HpBdUSfeqmle1k0}_aqa3fvWuHL~^hV^nM>!dQ1-gmC4p(#!Xo5F)5Y84@~W> zEaN`d>UmHq4|H_$$nj&$bDrIK|r<3osf z#RF+<4O6+|{^Q=s$>@)wd1XlyPWJMh!dsD=cA~L9^sa?}y~l-bV>bOw;GB~{(TQ;U z_I{dUef_{Es9=*b`amu7rpOCW;Y-@(O9jSLuL)^9>HUhSHfGn&1k{mvTNd|n5sYZJ zz@U%NcBezzc^1K&YfeJ{?Z@-p(~DV@BOlc}IZe*#vuUOX!bp5_+wnV-v$I&wVtf|i zGav=p=k=idMu>;vlgoqni|lNACd5JXrjrJ6cD=VJoBU2>{|cWTqw()fB)^IZ6U{=ZIXxyI@d70B&FM%CtjGUF2KPNy z+x*aEqWuxV+K~CG&AimRZ4X*IA zPV=%Z@Um|8vYz*{c&o8><8v=-KXkrL;oY&eiltskis`M^v0)=L?UX0~=_ zVa3{M@lr0r%6r&uL)U4g$E{cykJcE1&S3j(z_G@5q;dN|OR^EsmVxz{fO>F9aCj~1 z)a|h!(w;zCQ)gPA-=I7PC+xXfFAUMJ6X6-^pyQx=0wjC4xVh#7h<5CqFp*>L5oA1w zPYwss33Itwyan+MeC)W{l*w`P1;kJB>BISro4MQfI4~K2D$J2~vok!PA51$(7IDfL z!g05O#ht!qVw&Q3wPW2}a}6|Yjg15BhKN4-9+?Ap(z(*^;>IJ1d);yLmkXNPUChd! zN27SpuaQv+joJ7_e}Hf>R;uxFO4xF&;v#(DY0^!>Tb!X=$81I0W86CLBiZSjgl4P7 z3U)QzCYhK+k8AtUrE_5D41D@AcPP4}iygLbWFw6H0dXDNX@rW_$iaPS{$P z{fL9Oa`7)wuNYnXW@+-PlEE^^y)I+}bI>trnEn)_KNTYc6*mg2qq zJMfvrvw1UXtUb-V@Oayqb8Kh6k6ivzr60>b}v6IgMcJdjFByLnaI7qmM=z}8uLFucc59@x_H;{(1>A1MH-HoC>$02Dt z4D#nKJ*Pq7q5NU^L=S{;CRR?yXEICL-6a3PB-_%eZ$s`a_*g@~#R^YO4`A7T*uCv7 zbZ4kH+}uIIjn@t|UWWY(K6aq-(k_o@ohf1D^W&J|PB6V6rq4hcRwkz$kg|VDWzHld z1bg}tFcr*kPB157tR*Bkl|a}QL~V(cP9X0@L?6j;Qu0I0OY+-FOId?M?Bu~tO3Jj9 zAi_*RZp2?xsx<|rv>cO?VsrA7c(RZlGSl)CQ{a%R&a{jIGrhOx>9F3FIa7KwIWxxu z)4jqGrewuAfsnF?TGw-MrW%=?Z`@b|y&fpTZZWrHFNrYwXfAJ-1HJLTHS^TWe>XPNBqjJ#uQ4E?Beis{W(?r&Q^KjDA` z_6No%d`^$|c>sLgBQaXi>1e)HV5jC!sLYw(n?4WhVTRf21{I*mT$A}}T|F7xrG>B+ zcQy_#v%#IA1*SO1@B6SUGbB9+{o6NvNv|xEi54BMF30E|fuVu6895XqZj>>Vwnazh zqc;kXJf_5%tsV|w92LY`5U~$~&usp}0!Q6$6WQ%JT1YYUf%(O;NYPxhGB#!fBbwtR znnJyC{o#1Ed9W;nC6}cvPdUh@m&DqhT6kYWtS2UPHRPI^XuCsO3#Jyo$lCYsTBx#1 zTTR}J57@rhZ`d>$=#<_q>D*MD9@t_NaF*dM+`1u#%)(IU*~H}7{^5ElC_lw43Z*=q zXqJSYPIT3b-HlK!!rgAzEK~`sb4P^}8Q2W}D{PjAwj|z&*)Mcs;;$3UQmYmo*r~EP z(bPDYKyfA5CI+AyIFE_2&BKHw+4lQ7G~QKZCc)99p(u-Tc7Fy(VrfXSODw2`p_Ejg zp-^fD>dwgYCE5AZ(+{*2LIwYwK*Y|o`2NJ~gt zJU8~tq}f=u?Hk)JdGS?4her*#CaLeb@=JfjNj4g~I8qNmktAZe|+XNVA#lL5(|T<)ab@AH$4sK{PuPdY&)i-y`gYzbN$+*R;?{Oy15b0cjzeOFsB=tb~LZ5Z(ZL}(AM7C zQHX~ztglyX=g9VzJ89Yu(7$LZEf8#Ol@qhJ9^(`_nq6l<^L%vuNg=_>g?ya7FRiIj5k2} zfA*xCMp?hQX&s+u;oarMy;5ys)5^LHYw;+TW7?WJ3RZKHz*B%4apwR8Ob}Ry3f8e% zqM)aS$p#Y6MrzyIn~$nn-vkZJ2THS#_3-6jV@D3%f*Q7R2-tdk3b+=6w7T~8x?`Y$ z^9rfg)^A|lIOwt2O?413eM4wyUEA6olbY9I8?SBbXox9y@ack(Tu1GrbRhXGw>LE~ zM4afr8Un$(8vs1Ry6ce*u$Ao+7hEjGHYy|>eYkdNy}H~I*3a73HmJCc)1+Dg8ua(KYY)dyNIoN9HDsQ7K4YdqNj?T{W-bF4A7~JSV6(KjAR6 z@6c$%VFd|=_#aIeFa_xY6KathU53>`3HxC+DLgH_EE*0jGYJ`C!$zH&kb-m*95JOJ zfO{*j>UHn;4!bue2i=>IkUc2D^vC~#gsf8&ve}7+30W*y80}JM63ZCFLYWCYi=qYW z?m|d8@#del=8egvZhAuIU}(;zVnV`zf-W{+?9}9F3Wv)R5_%`(U^QzB3KfS75=>42 zUnBXPf7_M`PwA5Qm%Sx^XcH5Xf+=u4m;Qt?o{z+6MFmOWxkcfw-hA2Vjg5-+RxPca zU0ph>wtQJl`TSY63rlA?NGe}iKEI~6a{kiNs>)fVHRZLX)#as5NAs~wwde`A0)$>YgYL_orTD!QWw7SN@e!g~nUB{Y^+B(c+jh&X}ELd7zUCV!+X|t+J52~G4 zS~5d!g2IB@>QMF|8 zoZ5=Y`IU?3u%y=ni^~xhrkl1_6hVP{JUGeDfH+Qa+UpvdH*_$~&OMHuk81fqBnOw7 zo7#`U%sbZUXlrVybY@ngH__ziwpq*RKKB9EuH$=_T5UtU!^eu@Nly)H zYTN2;k1Z%Wu(qPAbarj&tfjScDr;)!ReYb%Us`ON+-;@VP+3x4-dTIqg88#+7gm=q zUJTD-jaj__qhxuftN`F+4b- z(cf5`ES_1tpsK30tjZT`X;qc);Bi)K!v^+oN8!@)W!@2;!{_Nm;RS8CVk_bI{;S$s zH?;Affa8aE6u<@Bi*8VHb=DqKSu+RQVfBK8sA%_vwS4%RyVt{^!MeKkV{908#~^eY zk!?`!eVJ}|`L1oZ+qyKHH;&Le_7TBuqpMX|Pknpys@3aTn(&-#yTh+-Ksd_h(*;$) zHn43soCdTsHAZo~-|l!lu%V@Htxc}APu=cVUDw!pG@eJjk`|8X($rO@%NH!EskIw> ztSyu{)~R2+!H)J=j@vWb9Nf7imT^$!tl8!9c9b}l!=I0<+tA|o77s1sz=;i9mS2o} z?rRrU9$e0tZM$;#t*&cnT-(&%fo5G@*HMcuSc46%5!?Ct=9X2R7GjefOSjdvb0)!> zI|SC-AFV+UjI*{+F2X{RCV2WqXeHq=<2TDN8nhF|A=?F}PN?lb3<&z$Qt z)V0+$G_OC#XnRKjgZR@~z*?<8QtD&a4a$!|@?aZpmnR784 zxEpQp1pj!&WK_G?*{E{QJwoN4dxXjo*4AavFXKK2%N`k(c30s}#C9Xw(2l7Gy;j!_ z(eXACPML_W@rVr_nAF`(yKd!rY<`+(x;dFHbhn#=25+KrH=dPi>sEDiHVGQNynKFb z)q>JlzWEVH-nI309o!SciXAoX)4lf$qGaq?Pscq?Xl`l7)8FyE2Io+JQO%cat=MzL zx};*k%q5(_-BH@6;pW(Rq*Kd|mYUMVbFss)e!9~S&T&{byC0r%FJm_vyXWJK#4`vQ z!6;o)6+6~oN^HwT<<)W9zfH1Tt8xqG?peh4v&N=|)9m?6qBF-Xi@K-Y(XmBiONu5G zmqf>`YiQdr6=%hGO5~Wj{UNV}+|tzAGG=94@dV0iTkF=3!R3jmn8zBCuzvN1b@gCf zd&BCfxPWog#4&ZF*0qi5XlfYcE4V5;WsZc4KtR%9R^h8rC<%G*n4s zujDl7mp8N=-Q3bR2Co=ci}OeIlG}N{o{3E-wb;#5D>l)ySuy)I+ri-;sJIgeIzh8- zM;nK1mu9P+J%2%Ud96FUGRJK_wDE$fB{h``=En{*Y(+fAtEE{77Y^31w)-%D$5mj+ z)>O`)-K7ry1Z`&`l!(ntRh9G0ORKx+^Jo!<4ys*Rxww)$T)WrlaE}A*&L`$)Re9-B z%*))z#wK##&bFhauB~>Xx9hc%-PJ5Ct+w-e`Ai;vz*^aYY92H#uAGIoD6gpL;*b2F zw_qNQjhD=Gni`vJFJa<$_W@nB=Tu^2*z=&)oo^iOI_$*A?sty{?RB!2h9+0q+uZ3M zF3l>hDwn%mrm`i=m)b+C*w$kwWP7B7@!{?~)-`YJ;^gA_r3)8&2Q&WQ%NEqsESSfE zcvq!^>}>AeYj84ox<%=wmXsHXcL-R#|{falJk(8fC0pW0$4-MRj zvD1;Ybq#A6gF8UoKA{{NNi!GBubf$0)v2>|@$&gIyM(R7)!MQpWjc_HHJUoPocpOt zTgncS()r6B?6vs}Q|v$2x7QtoeSX&+{DLL072AEmqnJ(CRaF*?mnR8m0KcN$_u1~~ zSc5$$s%f!%gP5hoJVooAZ>{0QUh7+1)?4iU(F8RM?Dpgia(mcXhAk|1`l7>X@4(Zy ztLt(o;SM)PSD89n)q1gT!QvVn4RqP=*sB~6u|1UC?{t}?XeoXi)s|K*oP*QME(e7h z86S65t_$v~1MEI*4-2!)aJpD(cjj)JWB-X$i%zGPmR2o6AL)$A+llkgJKk0m_W#_E zF{88jZ7bGdHne-jPP^{8<3Xi3K5|E_Bqq|YM8(3rO2JBioH$)!YxS=+vzmP?omKB~W;e5R{>*Z_&2{P1%95fYmU2gBP5HdV_8J0{y6D+ceIAB&P61uU zlZKOC8xac?8!H=k$$T9l#ZCg3+UC*B@sxZ~Zj(xnnDy(-Ini#e`UGa`R{qy4d z1@nEw$sRDf9qxI!whpI9Uc__fFDUD5G~Xc6RR$Dtr&qh3*bSz2)hf4haQVPqD&C{5 zc(sK)eI2p6!^jK4JtLMgtu37$s4?yiO807vyVHcP@#EW`Le*k)?NN7Wm3ychn{09A zsM4KlyYy#e$=D*twkaI4?d=Kv6DF_Ca3Hk4eM1AjJaTyOVvi7!7u)9daAWzBti>PCuzy0Ch|Ok9WXW)V9ox;TqnGOseBMz=HEGc0#%?xHv!$22(1 zXpFs8iI-1M%y+E;rSM?uhS(5W@3inS*ZxMf8>~Bl>}}6mu>@BWpx>qD%94^2Op7>5 zwbu~*<}jp};X+;Q{PKfpYpP3e3Kk1qmz8({DBhqOiY_VGN!M@FZr(WU@Ehx#?>YFq zDH=0pb4v?OcW~ve)gI1k+QUrNb#Lh3ifR@tMEBtejonmY{pW35cDBHo2aZ5+J+9il z`sCW3RqmaWxYs|LTUIx<>o5!v_$#TdoIR(evoX9Kd*_zJO#+kcDqO?E*=8NTfvjzA zY(9!z%EV@Sp$@02?od!*HOm>7_8`8dRx8U*UfSf&(M}}Zbw1e7W5b?a`?2_1g`&-sxV|i8YHikkAmdI4Oy{;>z(^?!VZoYnHJYmA$|#We7@r zQtMu>LBi@LUXAk3Jk&Y<{XzVm*qwf3wmG}t;vTL>;Sk(+>11AMH7-BY+QT01j$2Tp zW3N^Dw-Ajc?hSY`$Lmh_Ac{Ndn8TdW+{0Y&T2HKXs&OP=stcrDHuoj-vFA8wK5oOD zIdgJ!cxn5(D9>MOyf4q)v)JmUwZ+llWgBo+G|KPMacVoZWW0x>W^Gt8k$MiG%g$A0zW~7#Jed% z_W7i=$u1f85X z`?$l*w*(#D1KPO+@f4)4{_=j)&LxO@Xu7tCcTbJ06O1bz#M7L*+UwhC3~NEOW>}((Nv!Xsp}C1 zPZ8a#0Nw$sd%3u_p{)&f_!P0!zP=b_aa{Yw@s7;zaZRO5dhFW*q_S$?w|uU5z5^(q zitiGjQgJ5gt>Noct*(!q>(X}IH;mBfJpZ$I&L+>oj~_4ulFM=XHd*05t1fvqe(gbd zj^osml^7=Ef$p<0nSPzpw<>)HiS*Bv{x7AcW4tkaG6_38WS|{9am1!?Qu;YczftKN z$JBpC>7OXQ4-Oevp6}?U-D=54NWMn$y^{YdnGeRG{%{;Cu>1@X@)43RAZI$xRpO20 zT)bPEtirR<$a(nP3K+m~B$tu6JIgMZw75McFLcF`sV+I0+4O4nNFaGJet3YaSb5%x z%>{ZavfmObIU~K@EYhhGOZRq{NJlu%eoLi4&?W73N%wYNNRLo|nd&)652 zBC>3`nc^amq0wHW*eo6`9xt9FUMOBGZWHelpAcUb|4;mf_>K6T$ma~Q{@&scajZC9 ztP=SM2kNgBJ4B9erk^kJp$L?37k?x289+?`llZatFENacWq!8EUocS~DIOrs7Hh;h zk-rtB{&AvxhdAU*CEqCCDLy8?D84IxF5*FT*53Cbf2KzJ{0Rd&P%IRuh?U|}u|ed6 zVOZ`2@f`6A@n&(G$RF)epFeLPe=Gi8d{g|ZxJ&$AOb)r_dWnO@VsV-{PdrpyBOWWB zBVH!nDLx`TFTNwbCw?yO7V$eP8%MS{KpZVj7AwSRu~u9w9wVM1-Xrc7GqDZZ{t*jB zKF^cs4Pvv{DsB*u6HgZT?hckaU%XhnQoLTgMZ8_)yEj4~b#9 z_r;IJFT}6K|A;?|2{_ebxfC%=>?Q6ejuq#L9pcI2X7L{JW$_L19g)94XMG=wUx;6e z-->+T2laZ31H>WXD6v?aBrXyU68S72+G!LwiWiAn#Cydj#COI2ioKIuI|IZa;wZ6L zoG4BeXNr~L0&$7RcNfsVI&qb_PV5km5l<3N7ta+h6fYO~4g=b~N!%vhDc&bOEIuLr zPJB^(U3^RYi};baQ~Xl=xA?snOm_W95;H{p%9Q@~74yYm;uvw9xWCB9pRruII9FUG z9wZ(nHi*q)tGGctPCQvWQ#@b1SiDlaUc5!*bM5F4AN@u0;WXqcA|Lxjna}$ozZHk1 zxH6xD!Sv*SXjQ7I9TK(sF*%YoF^VC zHj77zr;2<>15lzbD3e)*+%zxW&RIq^mDH4^3jO2S?;F3FM^cPpnfqpD4ugEn>U4k%a!m;t5sKc8Dsh zzfltQhm%MwB4K9|IS|)nNccC0gx?EE*u(C`why}7+OgLcU?)l$c7~F$gCf?>SQ2)u zT_oD;46ySp&$r;uTRbmF#XOz}!pkk3>>y!h7YRGoj~R*!_G~?n zd4-&It>2Jsf5QH1rbAv!qMl9U4EK5(>)R~(5)$=pk$f|W`nOBImxLcXBtK2UAEy8} zH{s?r#z-^|iYil)De(J`KO!&MULsnD!}jZ#_;az5?HM-F?*J*V=bg z@tXenaK*TrI+)YFT`#wbEnIW%&KR@yVa?0-o6~jcZY+Aa-5d2ZN~`A;V64~G7x=Bm zT?gNXb9-pEa--oERa{W)M%C^n>4Lla&4IPp*i^p(zhi4z*@{iguGiJqw>KT-7IRZ@ zLl5s!)fOl%+>*Kq_oe%cw70C@QGoCS>aH6Tycv?FI1R@}18XW#(~d#0TrK_aIS^<-Phmu0R@2^Xy+9=Md7k zFptYK_+UL2$7txWJZ*9DiamjKf4y^jaimI*<&t5Hw!Jt?U;w+U*y7py1Sx)d%V3Xs zY!{q<#p0kb+VkS5@(du23-h=PboF9!P>=r578kGBe$eyR+vbZSOL{EVCb#p0kI{qgGd zit)P&e;iwUad1xY>McZtwC#c!%?1bU2vwzzo3_z*XLy$|~0h)R#;j#s^&@7Ht_2cH4wxA&|sj)6XV?Xm~h z0d)q$lh_m;e&mQM^ z)=PU&%N}4Ceh1=Tyg2^m>c!%q9?R1f7q8d{arN%<)jLvpESHXXo3_3Fcp3)0btK2e zM@V{}fBbI7zj*!?xOy@FUXXvIrR)_O2|a&1^TpR}znSV1rLxvvNYh~8O<@h*z zMX)yq*SlzM96p}C^WyCN4JTpOBh6bpdwh(jx6ZuN_rv!ad(q=}?fy769*XZjp+6HJ ze8n8A_wG1**X29T3gml>SJ$uO>@7UZJrAS3N%(ki@O2qp8QS;(_GWQKiLLTNRP+H1?ZCP6ETqvU?QwhI7=XRlvKx*3Z_fx)y;bhp{dzm#UmqIL;_30=9EZ!X z7s371d*H@Rm^5)hl*>=Q2QK$iTUqQqaEqO4bi|IC_k8Kp_IWjmwborL$}TR;edV4n zH`OK|c;n+weR)zt@SBqc1^@M9$K08x{x=YPr`Jf^}&za#pUv=Mh6|QjE z7jK`-cy-P|hvo2os<7UM6wPY`O5GL zcyHfjHEfMDs82=jiigVrukQHN$^P5NA03gf^QqJ&yT>g|*tKK+V~98S>JY5mUmkdM zTiJt;kEnQecZhjak9c`i_ag5$Zmz~Vkv1oP8F7|Z1b5v&3+pvA-6 z-btMO_^_t;i+x4!=i1#%&^w{v`QZH@YX~~q@9g=L?*-co z>zVh3Dt3IDl09fwAh-!KEk-LI{Umb+)*g4Q@f~7*-I+f}_uk+x6FRRf@s+x-@rIY( zp}DgDIM=;*jBVMp;|OmZ<84jnI_ksw*k*KjkJw&+agPnm{^Z_nXbx_Xi*lQb+Go1p z=6O5{E85%Ta_-C76$mB28lD@7hAWRB=v*A0>&70~p84pGBmVob z^Y|dIF~#j$`OY+)W$wcJ?q_>#vwf4cb9#BKZ2`PqcYbcSbL+U?ju|jCI%hrC|BIvB zP*LugSRWq>O$8F%ccP_6LVPb-4}%7E!V}VSP{`b!3c>sr|BVxR4kp8sga1KN=mfMx zcu^L27oqd8zYj0(!&_W?j>5lQ(-Gh3#A3b)EHEAolQ_0t9w+p`mvB6BT;>Gq1Ve!y z$WAQj!*9wWfvXW&;`p8eA*2S*Mmr=Qc#OXQTL3?n3 z$GwR&GFi>=#I?vzEKT2mGI&2);^%1H#4=Z0WD;k?-Nc!$SZxxoz$sVaELU7?66dgN zxfSt#w8SkDh!t+`!6xw=^j+d?S3JZdCS$jRSKZl)aJOQp4&4+!B%5;RpXmPZq1ilG z3E^e4PWbSwd%2#B1`Mxo*VA#@8m^D>#>Ae>@vm1uH0$8VfWD|E@PD}cABn29UPo?Z zVCp)wNhnZ^HjNCjLL~4xMnz<3>M60-ii}rlwNY(CHgCJh4Sb5KA`{ctNqK?YXw=9g zEA&g`*NKt+)9EOl=apE77$TEh5wBp%rTGJ_hZ1rdW~hN(+^seZr0XhQZL)RAu`y6xfEOqy@chM0@21 zN|>|U=Hvx_K=URYZiV52-y(pdl|A{T_9Q!al2&K8LYNYmi+YoqtuP~i{k@ZPMDj=& zon;44(i+Nw?x^?{ZGewXfTKN z*1=(**L0XHNgVJH)&q}0BQctlgQjx=0rY5Me)bkP7z*&F)Wm^3mcz41U^;UK<0Tpn z-pRsKmBgX8(T4|aX3j7xj1Jt$0Y4&r2aFXZK7wizM_M7U*(AQmyiu-rkx6`q;%HaA z#3bUW!%pHDE8<;giA}Ux;O1V1-gybzOZc_E&(Qs`=zvMd1A3uEGH&v9lB4O|K%Kxj zOc|Uw7O{*DypBy2uQ=miC`x=C!vwE5qhPj}#0$_Jc*&U+Z!pe)>(FC(liF~U?@6=$ zPe2s|p2iy9q{bId^%@5QxhaFr#Cl+16n9n)&WJ`>Cts_V;#Lz1d;_~FZZ(m>0JKty zTS;o*D)^r=!ggk+Gav)z@g_CC(5x57RKL_^eEU@3N|;Pt-YeZ&PR0OAJ=i*#YU@lr z#MYS^I2XN;dZ--?xq)rmTn-z|Td4A!+(_C0_EGXiCoO9G#7REJNz1pZc((Euv{Tx^ zAS;9F;89W?k~e@2NY$Zs6{%<~9F;yIb1P~K^R7AUU3#L?dS1jDf*JKMfdRbH z*U4zGueWgmzsIJR(P#ye%ong_G+6<^k9sT*Su2CrLEW9;Gd87j<1=@ohaB?=8qk=t zFb)Ey2d1E~S;P6$oQVGsb0PjGnMd(I+2BP?cumzUnDMjC)hL={euGlEW-9urhxrUG zoMG0WqchFT(9bd<=%<)o_@9a&h9NpL3#Fo_7Wz?hFt)dR^Cadh{BR7V1{uDgaIlHs z{}A&jbcUKk;oC6t1_Bsn-a@@uCI=%V(+NESA>+y5+iZ{2%w-%3eaB$%WiGcPA>u?E zRyqfBMvrz5V|r#Zy4pG1t`+q?6U~uX>uSvC%kMigSGdwbC$tLN zd1hVk*U$;`R=f#e&g*zyBI641ouOe4_%OFFw}G?fr`I9bRKjt`6vIhlmcVGhybm4x zgzZ%zYjN-ZD2>dzE9ojQzh%QZC+luI8uHt4H9zZ~>^?{zbr|EmH_I{UEcY~g5ka15Lx1!(f5&Mb*EC_BsWuEcUv zkMs)j1)`f{?nXqF=1ny4f#wF(GS}RV)~K?tJ)39NqAwPjQf#q{%$d-yHoWh9v002( ztua3$eVOSA{pIF5jOl~T7x3p0^9}mzP_rAg9A@~w*~1Nzomvw@>?_Q0{I4@bXrFp> zByt-}AGAiJ;h0-#3}RVj7Ng$PW*cH@Ht%8m2=fj8uQ9_A%UV;0|Le@(;CYMr0iLuP z-c8zOE{EkK&0YB4ZVt!T=rF_K+j>)i-Z{Z+hP4yTNzgpWRHLmnnf_?)lg&-|e~Ouo zRz1~>M9-dP-opCnW)}QE!(0W;GY#+lJj>jU*v~dg;rTh{_o)3`!x!eBXQpCCIN!X9 z7WmQd{-qzC@Sk9`hkdtR_Q3SMXbj^|=uTtqN00$?F{%lgPp}>`x1w=x3U0IFV)6VLjVC z2~9kW6gs))4g}W2EQjTu=J#lVUZw@^EtV~$321tuR&S!lMSRFOFuomXrgfSs}CA6Oq}-=0~5I=BJc z27e|PzOHkk;l=AoW<0uif5VfS$>vS8-T~&9NS|Vc!opN@EXqwYyya!Oxe1yx%y_g_ zsYyjUl%;RPFmg6U#=;eJ3VPui&Iv~a`JRj1yzGrU>%-@qcg!4;00BaH zGk^(02q8cigd~Ij66T=b#2DtO5D;1iR2({4YHhD=X{B0ktsO2@y~VZ;t+r~l6;c^iWJwFTKc1#SdWS>t~Ei}e2NZ-h~lA<=b>UB>Ky0of*Cm_)8j6> zt@|tnoRj<$s+Y}_{Hb_6CwU%Plq*j1WpJSqvGGSA;_Yp+AG!`?ImyS+Uy;~JzJP*Z znE0~K&gZ?B`!f{LbuWQP&)tDu6m>rbO47XtWh!)kjzlT<9WXY#i&E$;`Fvg1ar5(- zqnH18R3>bc)S-!-Xg)tlaFY2Kp%*!Y`D2)KD!)H!!)eaHfZ6X!zJ}6DA@-rDkl-ZW z5D#>}L5c-UFQjbj1Cq}|ABcd-IA-JQagwr5B7KskQsKPhWaEh@f5Uu`eNxQgA$>A| z#)nHK`6@14vlHEpYAM+hVXY4TIl5BG6J1a!&fC_w_}*cceHlN)uSS`A4v!zubReo8MX;tpmO zqajD7C5C#nPc8j3 zdTqbC-yuOVmmC;$;v5mBYoSbW<2{TQYEcp$zyGBo{Bd7Q5#K=Uzgwt(@u{Uxp~?IF zf;WUl{VsNfqAM_@25ir#)&m$N4O8?@Br7_Ud>$O50xI8lFS|W9ByD#b(eE^2BQmTQSV2+n67X;=A)nV zrr-k3m-onYIr0&REBqy*?vrOT1>2qbiz&?+8OLwoRgm^j?@jO)Y;}(G;apsBp7V&| zUF-bHc-A?O$}g4m zYr#6_uOh4-8NJz?EnTqI`I~s)kCPDR{WVNxVs(n6hq>Ral$$KX%)sUDzXfXcI~}$D z-I3Y^u_2g4Ev{ay@y~QHgAN4SarI}_ zUPCck5n7L{oFX`aV3UQm!(a<##7zjycN?&_d>Os@5*dr&GRIl$=S#05`jX)sLsui> zDqJG^a*F;JguaE#DQiW4-Pva`xab;jx%NY?@Lyo|bU-JBjyHJDP1>mm&D>e(fA*FyRtdagsA7)*)7vpVn zMv=Bzoi^7~C+<+{afwdbsMCCeX5(_op2QrzI-AWyhaQ0<9kR(+k6?0|T<6Lt$=5Ua zClR_rl263kcy1XRn$9GD%_cv00+aLQ*00;-E0~R=?wcXWrpELL$STJTXi%Q9& z3_U=ym^qwT@QdZsaP?!4o!Q2w-HqT5lGt-+p24d50)kiL8pSa|=dtZ)H9U==oA+z{ z(%wA3*37#ffg|ud#K0X0ybjOHxP~xE*2|!jL8B5}IcPcO*T~U>PEgzHMlmWuJ5DiB zSEr#`+YqY-dBGN>t(pay4uMl}NkQ6L*&>?}?u9P;i&nPtyKcrkOsl<#omNJP%52$CdYK z1g?YUv$(RpfWRy89L06Y*AO`6+xTf`di*zYr+YZ>D5hGG@;3P1z$H>(^v&U49){$C z^Aw88qKFkBorx=pqWJXiLR>Z9M_>r}IMdzEJ@=15_&#Fzd1=;t2s{AKeYmExTFL72 zhqB%K%5OrFyxoX+6db?8mA4Ur=iqr7SMB8pL_T}%Ma6Ys=cdC{A!pEfnVe=|!EZtw z*Jj4;fPV&8K*)7Up;Xpy5qJx-{)#K>Sp<@pxZ=37UO}KYJiQp8G0vgz3}N711g5|< z5m)iD4DmHwMh}DdBrZO<%1VIH3D$W`TZ8~Vk?q1&I}m}$XRo{{s|KD6K;cKSS)&p7 zI6VA9wsx|xTzgR#&FOJc<#)0*3lQK7`&S~5Cg!ma1bz{F3$CoQ5qJom`*GzIf{i<; zAELC{!*WVNTMgR7AzB@1v^)9-q0RR`hO|6;fwZ@khU&}VUoA+>LAI!9;X7ApgOmoo z;!8l|W)FErE^y*tWlJI5ozR)vs19M4HpzJuH14(5D6N~KSu;)!tC5?tkNHtf&MTmC z8~2$I?M=|W2in&SO)@L~2Z-Dt`u)N?4}RG46;0549PY$^t752j3N-H7Y;SRjv2&E2 z87Thnm5$`NVvrKMuAW9Qt+C5!x^+xz6w^0>naHp{iC&l#scgrPg~sf#1xena<^(1u za|4^1c_HhQ`634b3j(W*Vk5FpY#>^@mgwMVRvguKWl^SOLStXC*jlJ8$*{rM`#3f@ z`xrZ#eS6s4EDZ^#bxR|=pIAqA?;x1Te%hCn#Y1>v+2WBfniZRbhB16rILG? z#$uy7S%Zz1)RZo+ef zHQ@IRf=L7^$OtTa%0WF0OE4?y>?sr-9vxR$oW=G~3x2nC*nY zXPWICI|L(TT)L6YCXTVd%4Nt>=LFG7Ok-v?)}i1tm$YS(E|S=xFjG3$vxZwe!boM)#>W9Ha?(WYWFc3Rk|DVEJ})%k`( zr~6du8yFCs!Ny(Gm-X*FhCyzP2O`MZ8}3W%VgImxM#u~!$u?3<9QMzQ^rQR0uwtKn z5YSI}%pJvbCb1Q90-nrFvcs96GuY&!L0TkJ(y9K1$iA>LlsZ~j4N`Suh=g(*_hHh6 z^606=`)a5;i5=2trYa|l4CVQsNa@$fKvclM@=&hPa@0wB9SlU<86GrSBTZ|9C&RSn zN#*#t^+j%d%VFcQyaK+8a9c>0TH3zIu&+egeiABeUw45xru_d4wf2gNVqPPbF}f26DShLUJP?$ z9mF=Cj-S)7Ps{Oo_g?0BuWQl=IZ7G4I5w_GEhBdb{=hlB6+d5cpLf+@v2fuhUM+ku zNgU0}#ki?#gs*X*3-3Pn3oZg*a9{IWHE7%r2+ao#Tec?tpm?5}90G5ySAU%;Dnn8H z5o%sEk!_QoCbWFe^4FW>%RuS0wZi}&V?#tV*@^Kl!!Dh;01Qw%ow(5CcvzB4iJyf2 z2!Zn_LX<3j<>E07T=F^me9v{4(En%r{IlyWW@fJI#JO*d;;&0*M2GKlBj;UoovDU1 zKxX@)6}3_?aow{Fu}p~4Bj>q`oNiF5IXSJv-IzEw3LWoL>9BT-tIR+)3Z0c;kvG+J zjRxe|n0lR$!(-P}-en+h9ebA(Gu1vMTC?6PK6o!9n(QCNQw&*)f}l)6Gvv3w{9Y3g zFxGr4#czJA#UBm*W{ba3ezTp2@U#$T$wK}Iv+RraAWvqtm2XbME-LDd48O!EF; zBf!@7a(WY-#7gb^8Taie=tEfd{ZRdcN`_>=pH}Ny*Udt#c zp>^3548^*U-KkjLA@#84x-Ondx3_v&*nKO*Ijv%4IF>U6%p=7}YhFCE3wCBB*|0$z zcT=Fl&M-ZR`dFWG1S{2+Yh~1n^^N>H1(wA6$KBJ&3v;_s8hVXfcA*>V%Vb%Qn}hNV zWZ~kIVl0g-r9-3}`LW~1vg47KNwHk95IeF&xGTWru_`80bgYnxhQ#_uK3YeC#V~VQ zX5_>QQn6kG2gUkGuo{+Uv+H8{uzQPg?3^T4bql&OedGRTR;j|Ml z3`H^z=9p<6*^5(im`;Yad9KyAn1+B;v7Gu?c{wzz43wv$lZ)eZ$O{IUV^yhGK_m+b zQIp7drd~8cwSx)g;#1EmHbrq`HRMD}DOnwq9U1Em37H|LN3y(l2m3-SFOpS< zQb74$5LgxOGcq<3hN%(g9UF~!)+;fuDmEyxD^-CkP8k`i1cm(=6}eIDP{&;lC)tPk z@P{>X3`N8uvDg=e{1Wt|uU=G_LjQQyVJ|e9#^N3IFo7J|e-UVr=bgIrq3{5DUJU&t z@*8@>vTiW4o;;4MuZgVRXUh7e$P)9*?8ffUSb`RqJEXazq>M7&VW3i}kr`F+bRYnB zkW-$URzWYGH1^LyET#<@kgkq(p)MG!GsM%Ljf4z+Pq3^wweZn`n12WP_= zCJdo2!P(_B7rAt4*pRfGEwdcwX!v$w(=AFvw45L=-N0BLflkIaidq9QMy5dx<+*TC zD@_N9bt8x{XO2tHGD%NhXxenU8Pn1Y?W7r=_G_edx-s<)qdv6#<6C_Ce{O-=Xdz~h zrqedEU*PvON^MfARUH@v?hM)e{!pf>{Zg8Chsn&@b70F3Mm0a2(dy$Hs?HeG{#Ro` zC$gi)?-k)`fhM{Z!R}fQo7SfIvs)I!43w7LkQUBpX+yV_`DEu(n8?||&1Kihbz*bY zFRWC#*l(ZL(K1!cqM7vQOLG>|HvH0{Z}^snjO83_`N|}K(fOqr=9)f~O>JK#$$2L2 zm0Dw;>2|i!x&7MQP4hop#&*vKv$}08z#Hqgl%!_1{oJ)DX}w8C!D;&;Yf7fj7!fmP zw@jb5v~y+$zSQ)kzyQ&7*z?M$k2L#0Qv>r;X)Pv9loT4Os{_H`WoI|2}i+(8Zr?%!)>}mkyFvB6I747Mrt>JHMHovL8sltCn4d8H&4> zZdtt@7A~X_CJW1~2^a;r&% zNL__z%9;OY{bs+24rK0}WjD7R z$6NN053{gA?XcLq8#Z@+VkFk2Uny3F)eoE8nCiKUv$y4ejch!qaQykyl+p|eW@5sp zFI+Mww6hHs9+aCqbv~Q$>o08^WQU30YYC@8W~{Sfy;-`z_6_J_$bPdJ zF%AmGCpj`3ceX5?Wm-Y1*w{dy(>8NzODBrrw@{kVTTq41R8MP5Xi}4EFoVfgkUh;> zZ8z;Lc5A0O`ZuE>7tx3oiI=uc!|kQx-`ubdL7v%In0tNSoGrzh{ln5-6qPnsXyUj< zOh+R*XBU&Fx#K0FX9_X2-O}WkO*B6%M^b;%4U|2-rDIWG2H9__;I6iZ=ng#BAS-Tkee zNiHUkX-L@TLl>Hds$4J!OBPK9t3|&cL+l|t!@buC>X=b@o z2NSrNPXf7ibCI?*fq2|GM*2Ln3eszdWIFe&MvG4_Qz=th=HM|a!)bkUW@CLliDt}o zPMaN?M|$xr6E@o(S#$4S0!7{ly1i{`NFV9Mbf zE}gx5`SuNFTG48ryPyqCv~XsdzrPd9i~h)1ibuKZz5W`$a@&@T8<+0(&CJ{F;0}!D zQDcp4Q$h07*YDB62wFOaYpm3qDlxNjcFR0Gq{XDA4@0E(V2QfbA32zC!#BY8?$jA=yggt{}Akogw$wu&0eD zU94zn7l}{Hr=8neF<_M&5%xr9^cckW#L(pa!&v*E2-F6wHp-j*1bLVv0hT7J( z8pT};qnR658(wX}jA=tQS6ufpHCeJ~NrM%}L1!$Ulg;F)^UXpGik8rV7TiECoZ5nA zFti|NMlHcMXyX={G>u5}m=4rcGDG+?7<8P9iN|UaTAcBRi|OXMd0H)E;EWkNhWw`W zS8v(2X*nA{wDHU=?;PCiqV@dp`I7~^BdT)C#+`T$y#-wyLbq%S-N)Nyhg81wp$csV(45DraV6W23Wu?UrrbDXzZZyySijeSOZfGnS&Y%mbs)NM=*_>?x+^ zFhDwI=#m_kDU&AFF9_Q$dwoP2k-?^bV=q_|O(Ap!*1Iz#GGy+eOu5!=-rTiq>GF*@ zD4vBdG8ba43vIrnrM8=9*I6tWnliymU4;A3*;uC*;P%4LMQ+RdNkG+|);<^9m`aU} z+jX1Qc5Pc{j_dRDH&c+A@$5Xn(G!$T^)#DCc_Ae5g!BISwEXdOanEApo0Yu2rl9D4k{#eXPZ z?$)^T3iVpk8_eF=uN3=`%XIf0+tJ&_E{U(B9a`ucvXiilWt+Gi+qKXi6>ayGy+Y8N z%ofbtj|ERG%ye&`hiG34Zz+P^D624JirH5WBX|}zi*irEE$C*NR!ZdxL_KVUye?&q|JAW=3olJsve&>|zf;y4q zv}0N)_pav2mot6p)CsAYmTj9-)8{Nob#B?R5r3Fjw>dRxblvE>1zj6QrD|GttlPK> z=Xq`#0b)aAZLNtMm1?MOXsjPQiZAc-D^HxK`5s>RIzK-*Pr@LH5EPElD@a%Z}u_MbQ$sx7#;T>h^Q{yJc>9 z6vw9FShY5N(;8{43sa)b>+e}Q5pOAlg9!8Oy}(642|FBC=1^azV!PoyImaBDV!5JH z&uup7ztU|8cstvVp$G3w3x7b22VRL!X2?%EgF$Eh>?b%52ET!eq`e|e`8gT#seRxg zuo{)Ff1WcQ(Ui}A=OLc`hDSCTCnrMK0Oa%7lfXrAA_e&ahwr#UE`ral)AK75{t};u zZ?Xq2lGd|Xp57Vqdk4($MV!7F^6|A{$VKFP=ztJGEvD;hU)eW25%k=2eZxJO`SFB< zz(v5FE-yWG#Hq-TR}mzJFXB{XgsU^;aWn=lf)B~la~Kjt!WZ!^1{iV#R>jiwtI6OW znjvp!M*Ogh@bCE(#2K9-f3&0z zN;TSjBTkr7^z5#F8= zzAPhrwT3xTd!hXfAWRb10Wm-^|i*RKi1?bJM~@ot+xyx?6%f3^mL6-nOUuim5vGO%66A6e2!=E)>T8MhT7ivL8rCv7){ zr9F1TzIvUn%gLY0nZLw@gz5vEut>_6dolA6$PXE_ewx-i%?mw9Pos+xD4j1V^t!Jy zp77CA=qABt9i;Ye3d2$UV@*p8-Anf%p;333KPN~TPw=#`N3!(SX!LeC%oSFG?P@Ad zJNi(&ja!Vf(m*Tc$Axf1?M4`Mj;HK1ajFmz-wtx;kbO3Ii07D(`m)c(xu*;Re?VMn z4y(#uX6(FVFL#_5Nne4Z{fR4a$_{ZA_RJXc*K&^55Onk(FU1L!c9TA6y9u{WWu%H!?MYp2eF=b8h+r0+U3%wx67Y~aY~Bp z(7k+9ZV!cH`8+IpN#b0b#6#@lTxgK(%`nU1VX>j}?ER__*Rrihol~pdV0=JVo{&hEs~e6?wij z=`$5iS6r#MRq+DFPbmJAB99ki`a_C$D?Y6FwBnx>-&M@P`oeVm6^ANvT_e3!agO4d ziW?NqQ{1aa+XzheRmE>99#;IR;;$5culQ%hzbocOj2xa6MtL=gBNWFgPE%Z#u6+fqVK=C_@KTxEdN9OmaB5f%#{DR^uif<|YhhhQ?KKY6jQ;H)Ld7KyHrz_I- zAH&NPH!IS<1?its{IcTBia${Nnd0viUse2f#U$oT$|+T>RjgB-pxCasP;r^!CdH2` zUa5GE;sM3)DE>f^XKpdyM-^R6bPNwy+^Kkp;^!5=p?Is}!-_{0|E&0?;ya2ocuDzj z#azWAMSfk)_;N*lTg~uL#d^iDijx#u75Tw7`R6EhDxRshOmVg1M#XK4yA&@}+^hHr z#eIrm-x>Mr*YFLB-&Z`M_*X?vnAEF4afISb#kq=$6wgvzp?HD!|2xHJ6<<>Plj0kS|E~C+ zVhkH(rq59=rnak%1m#f6G16hET4 zN0A4qGyN@!w=4cc@j=B$6`xXkQSmQ|#}o_j2%PeID-KYsP&`F(gyLw$@rqLvX(NPk zW-E3oo~5`#ah>8;#q$(-3Ov(ap}0@+i;6U}#Q1M1-l}+q;?EQxR(wqHS;bcr-%$L! zVpgG%OUoIQKT+|s#I-o5SHnM2d{mJZa>)N5ihXc=CBwrNI~3O_UZD6n#ak5bReVD6 zHANn%M0sV34T>`q&sE&5c&Xy`igzgfn_?0t*->7xV!2|iVx!^|#a)V*60!HZTEqK^ z^Bm`Z;;l-5K=DzK(4__W5qq~Sj*zOMAQh_%@N;sF8mELN;g9IQB$h;ohA@HoXuM5OQ3_$9<@ zSfamA~YeyxW0E8a+ioSTUY@SI8McPiee_@LsWijOHiMMSz6HT;U= zUx<)P12x2fM3k$Ni045QiKvGuiftM{N5cyg&rteu4R7FE_9Iq<|ULH#; zn5X!6DB=jkg+$B)G~GlLyKBH(HT;O;UlnOfi+nSP7>`>NKc)Ch#h)p@q*xR+{1b`j z8%q^;5m7$}6#u9QgT+E0%;!IdU#a*>#lwm}SNx6Q9~9qK%;NJMr0=6h^EC`ND=t!8 zuXv&2ClqNHjQoccf1wC)yg80jNJL&3&eD!4BKT{FC}%wp^@OI9dTS=4{$~);F6g?_ zZi|UvT1G@Wql-xUWBV-f&@Bar5Fu|2vDy(c2FxEzv*a)GkpCGBBY$~b4gQtNzmACf zw-Ay44kG%^$B4-PVj}Xtf;bKPW7Z?CGl!&o?!EjM#+dAsjc*FG+;n)f%oLLVu@j`|eG6u@u<7 z&EQ(=>*h;zb@CQn-HPqoow}9B-K(bd@i{L#==6RZJXEhVB^~ZRxlKD>Q-*qw29w@hSIIZs~=!uz3^0%bt`ss zL-2=i*s?j8?#=n&K(0w)$2htQT=ZkhBkn|eryv%~6N@?nc6 zj%#ArS^YXegn#QL8c9CtVdYrl9sAnho*x7R231YY$2M}g@UUaq`KY%}+Z)vC;c)aYFgKIox zvut!X;o^I=)>(Pafe@Bg19=BPV>!4_v-R>0{7i1kG0A#BqqCxUCN=*1?Lj`4fwJgq zzO;uE&iDRMIoK{X-*b#SzZ`9lS1OXskCjKeIbnH^K_2;74s7jwc?(sZRsU@3G2;Ak z>@<9SImpLyP!^rdcUwljuZ7CdTltvoN1Cr~k5!OYNkQtY8lTUQ=d23)DIN#-<@lb; zv*|9k9+ih^agQ55zZ_SBkNQv+oh`?2GV(19<;(t0KBgOn^ptJOu@B)&gsnqR9N(b` zw?`@@uM8YkUWLlD>Aq(@Du;Q|%`<#{Ic`Om`cM`f<>aF<*wir1EUKXRHTtbhaG#7(Txohox-W9!C+jGC=mnE9v9|h&dtz|eAI8K@>$tuX6Uyzq#xH7 ztKYs1{kVYP&z!!qYVaMIaQ$T?9ClW}+YO&ze|%Sm`r)=roYn6((8Kk&E2LjNIIVt1 zjXeKtb6N(RuCfTsmsblC5N$s=8+_rl+UCn=7U6uaT;(_^q+`Frt)ibVt=;M4+VJ`1B_GR6S#*dNw*sDUzBjE3`V032Z-s}u{^YGATEtn{88ZIkuRffDPAn(&w7|_aFmLcyjYsAB|dPb^azI4}S=yxsjyBl=sHyfAL@0;L5SK11axK)es+};L&Ry5Jh z8H_#vzC8(;l!YH&kyi+0RY9KbQp@n1EtJs8<1^(j-{K2k)e^c`XZhqdZF_g!%DOEh zQ*fikH8zf}A2n`F6a4k{^`YOfjg1J6ZW`Y}#?-Rxi*UM^>sm=HOO0P1=CgN%J0Q7eiN;x&e+$6t9iFvUj40#FuJs|!De!SVGoRebFSOe2cfpl+fKg=wY zb{!aE$ygp@21H{#5+TkHcOs?59AEL#h>i>|KAV1S#v=74e9m1KjU}V}!$$mX_=zs* z|4R^ivFr6d2g5^V-sp$6Rj-C<&Ie59>WX{4LOqhbR3QQIxkUA3OtKw0-ScfXh8XH-I zQ1(jvWVMQ{S3%D1M{iL(s1?RIY7y^EYt%m<{*lI?vldzB+@8$}{u9U^f1Jbv_{rg) zpt3%nL)139Btx%I)M-GuaintP~oOmJ}Xa-pS?n9`Q35k;-Uq zpHQE`Z&vpPpUQGOIR{9cEn+UVQBH0g6_LCApDe+<31Xa_yYZ9TDZKJ3x->}ctyF#S zJw7jcqLZ6KI6hO}NEaR0C7j&Pfj4i0yq7MCbHZ{ z1%|wd_&L9piMeXwk2g*M=cw~1kTeRxT9Udkf1Te!P0mHI6IcE^=c0Vp{HJhTj;nM4 zejb9f;(PFOF_Yg6%JsM+)%an3e+e!oX ziFLB_@sp+c-UH-4mHnn0*JfPOD2wK?;Md~f zw35#c#};GhHqT@J71)nDvq&vy`TTX8);Q;uF#gxL9>FDT!;V>xc$NvRk~I|k?7b|* z4*2`AnJDNEFcm+6dR;{s&)|BJGFV0qgzi8_#J1m6N;7S~6Wp!f=3wG$|9&mHqn)hN z5W%q*5YYi6tTy)WXAQd<``Rni%zcENf@9-vfdW}&pm7wLLLq@$k172DC_l@u^J?(8 z`@e1Ld{zyM#i8{YE~(&I6IsFiQTrvhq=M&41y4q>2^U{>75y%T6y$YW{rFUk`hDK; zNG10N&2(^9x~=M}pRotE`WmLd1;guKf)cGms2vw%z5pPqOcPZuK=3@O!p#AzDmQsz zRXEJ4O3LtvDy5*MR~1LTYb{RWZ^<-a8wu<~N3EIaSYRkRo^F>q;Txn*ido@`7_1b- z6fP}IXIYca*~c+4oTFxqeLKF!lyh!~92j`c6SKM*2A=c9xNZiqKnw${Iq6Z#TLmY=v2@H}?t|iSBKUME5bqtSj7^#bR)|BHu-o z_O<4eOKGl|lzurb)6?6(r-kGJfraEUVrsM2~1!km#fg{tYJh1byMbuO~|&8DNe?T!|3GlpAYk& z`D0;YbL@n$sm}>*F!C5UpLqe9Pmhirk7VN|g_@6zBE{*DM`yWd;}YzhjO+A;#cSY= z(gJ%lk`EJ<`MuyPDsyqu2&ZYqdTH}X^iD#7B+Z7_HH7tUfF;v(EsUkjI%t8okQSAJ z7P%-8=shvHQQJy$diAxmBgVw*xN-B~N@}gdZ=0}|IZz{~`s7-cqr%FCCqqk4?5aT_G$`z2 zvIW&I?+c@f#Cn~l_bN_@4 zylByoD881BQ7KyV>@z%C-{@c>hiLibXJrs8zs>U7=6n^2BhCxZopz#S%Z@3TL}4|%7;utV)a4{D*}noVGSGn=$7zHcD_|f76VauQiUj^G=kVe zm{d6ZxU0)gDmo*C)mx+Gg#l2ICuR&h58x<>{6r0;72^RyVJgR_CWF~(O0hzW9MUA)BxKyjr_$(N z)~T_wL9iuAbz-xPM(KI{Ni>4-M^Pwua4e@BCVy!>Fcm8ibWIrMBWb}8))`^pk+O4V zscbQ4m_uF~8mx$w(Ae9MSPASc*2Nk?_u>WeoATmmwefB!@46WBc57ofRVU1T3^Ruf z$CGC6#v5XJLo@TG*~@S%nqvSvT3V-d;3P>LL~IU?vn|cnP*$$R*=wOGs%^{49einH z`^eL$Ew%%i3E27Yv*kP^)HhMUL*sZP`56mv4($RQc(-674zdmoC9$V@n)5&8P>zl4 zp-c7sFniLcbUPk3YAqUQd~o6>VoXZDuEk@0#S|M4p9_@XX~@*XIle7B%oLPjMkjn6 zYm_F1!&!Ofo#3Gn$2~DK zJ+-a!;G9Ef=2y0V0y3Y^o#;GdGD*Ct8lG#ZWeuNn9hf;|6`Cg8xE!xiYE76IjqEwB zp-#t>vrXQ5iZ#=-K3Vf-ev;}6PB$0RP3zE!((GB;eAafY#6irvw{|)HNt+tg9f+{y z5k39RV)|EFtFucxJeqK7!{W?y2U8<9t=zifR4glK&JoMUBfJ{n&0SkIk668R)L4c$ zZdu+v0>|u~3UgDdKF#hF2YB?i=$9D&J3Ngqz3vF$8v#o3L=JH0b)0BQ=`E7Rg==db5+++YcHmbST_ z#`+$MAiadW(L88pTT;IeyNvbV5KlSG#~!{JVl(sJ(y22SOkLE0TG{!zm0pUKJR$x;Zlo2fI{y{*YlR|xU*jiQ{DZEaC|23y*a%UYr zLz7QetV_Yua-1_Sxw~%3FT6CmH*#6#d6?XBBW`c>vdHC(n|z*dkK~P3 zA3ug3o=usapM4w5u<>llbou>+zu83N7au8vTqNxc2+A+ZkRP-plO6A@%5;4Og`|_e zB12w9MtoI9d{svL;EeDo8R76KVt#zU8@Py^=oAju1p)YYR%F=qJR6da3j-H%8s%Fl z+}6n5cM+TU)PSaCMmbSC6>*R z=AgUT6CWj*v0B?Dw#S;r1uob``>D(-%Ei)HGz$t~!geP^bveEBtfyux2L72Y${`k^A3*34h%QcE(unCyLm4?d%Ai5HhYGC zk9QjWqz--$Q#xm<@|jGH^i+Zl=|wN3Pa(+kHAJLu26{+Oeaa~WZYck(MTc~BjOXg& zaUc^rGQxOi$i^obKOBFYBVr2VUwMeEKVpC4NTa`3ujkf*4zI+c>I9`cpd)Ju&sSWm zc#h%*#jT1LDqg1eS;em?epB&wMb3fL>tV%56<<)~oX7ZoC}z7R+()rek#imS_)a>p zU2%cpQpJsmyA`ic{G8%-igIophZSXBs_{@ zc)H>O#d8$5EACe08z1DqO!1S7S1ZbSc8LF`hWQo@$I*R6^xt0-F-{)S_%{@@@Ys%W z2P-x!p02o2@e)P83rha)D&DL3gyJ6+`8EOh@`&iaWf~qr#JgNW6~`-{s@S18Pw^bZ z<%+9`=&xIdkT2i)Lf-ire=!mH@f}v;ZHm88e42=KM~N7ZZ)=$Ec2Y0C3rZ|el=JBj zmhXjua!wsk&Z&bQe3^mrnw7szaV8P+<@;jb1sc9Wk?;I5-Sxy?I2TdFKO{o_U5fWA z{g)d4mEyCCFDSmLcueu{M93|{Hl6ZH6$cVQAEnr;IF|^078AjLw&HS)-=X*!#hVoG zRFw1Z+8pOO4Zo!*=iNbWAKVUjn4bp|5gtiIKBE=oJUfKjHM~f1iQ>6Lq~AhBKfXl6 zaxNX{-(eVX4---Ldo=tDBIG`z_>AK7iZ2tv{|*u3B@YuO!xf6XIM1LTH7G7s{Iue? z6dxd>onKKb<~T=ql;V6MgzZrLqT(Hjk19T^DDwo$#n;_f?kS3A5~1IPil}D1`)1Y? z(vhX`r-;a}h6tj}=O{;>hRcWuBdN$k)k!*;?~x8wEa|2y-gQ1pquTFhWc6YW3BIg#*y;UwbInR;ZP`^b}JVOicM6Q3>gxhaa5u}?g~x28QA zkN=_R@%T=nS4QUM+sd>$$lOz&s3Lmsog~+uyeI$e6osNry33dEKf|A;B06oGdprj7 zz%BIY=>Pq06(d{j4T-1V!gPy!c;gxsEnrF%Hy6M3bIzk9Uy2@en1aM{&f(LfW(na% zsS3l#w~5Kai}_8%MR}Oo#C0lKU>qIiCiwmDSIEcoHb0B2Knv$vSZU^E=8NUU&-dH# zQ?@O~+3;86vd+r80)()<6y&8qqdd~dM?J2`MR~Ryd*BZ{#?jq}3x2;Gdk|)N%A&LR z-UEL)-{w#`a+Qzi3LuQKZ8@%lKU{}a-ciuQ^5#L_JkVGU-p|=`@C+Ktv*maa{;*>l z-EhO_mxFxNhqCBwzI-1tobQ29Ik0s3`OY=+{O`M-N1V-z^62Mvz4F=evRuu$th4#< z1YbDcgUFZbAIn>U%a)g~L{hFTFZB&O8@$)>`Q;@a%S%~wHs8BJ59j+#sJyrp_46%7 zhLml~!FNa7C`g@^_iBc`*C4M3JS;~)T(%tfDi0uzZ-0iJ4Nfq8emTg;a!?kX&6jUP zhs#k~6^tY9TWr27G+*w`=+1{c?mMhwzPxrQA3)qSAXclNVDtS*M!q$neEBrg=6g+s zyu&Au$M15(INKL*V@E06ECTR-C#W3u4=sdYB)WzfR)axFU50WdLN_Ai^S z8%dY<3I=#H;;pmtcqV&TUQ=x_-iCtN%HwyNHVtJAEim7IWy&iAUs&E+$ZG-<_2b%N z<<(@!+YWixGg6(+i?3scM&m^8g*TWVEOo{a!Ysjx-R_!&Hw&veCW%wdhwg@ z&&K1=-s0Z>`?GgVW%=Kq6~flpa_D8hS@OXX-}Y)wil1h4%a|DBpN3z$9sEWUl+n$2CS zQu60|^A1c}g8!v&EQH?X@n20zE7yr@Sl-;xt{S}OA@w7*m;QzeL;p2@HUF>t>$CJC z_Azn)6}A+uEaLJ0zMLM<*&}ervvnB6QXUqg&;-Fa4jjDSW}b;aToJ=Sc{UD|XX9Y1 zP&(&q#^bS{Am=lN;yTA!%eqE*x@-Vwg;lJwJXh4Wp7jF=De4d3^jgK${hzacywmvuI79SHQZ+;rs#Tw)^;rk59H zg*3hcSOMBWv(EBe0D@M9M7;>U543J0(cMVF`znl{6Rz9OgO6pk&Z?TZZf``reA+Sr zEgyy@Uenys^SkjAtlMK7t{Rs5}Gjw4<6i8cw26J z@a?!)amUd@`SRMt-=y)5d|U2SrP`f}{^l#~_MW_dx%hJqzs)uhox$dNbd&a)W9#dq z6;b5=^!|Qf_&zxz(nwRViLoZF_%TqDe_ew!JNKfS~@6#rf3EC8MZ z@Y!Sa^=#__x8J`$DJh+*KdjhG>K)XDJW0v>j-yHK0m(z|#Rm^Md&9aG-j;07m3H{? zdUGOx?LFzegLT!jFGbt;Y}j?n$_*QCL4PRx@f$6!TN^*()s`Qbf4ix@$TOzDI2FsJ zK25EL{kER#Z$GfX=HOQR{-q#fPe5Rq3U7d$R2ye*P;(t_2*)bIb>@%u2ISl)ZyXz@PLntx>Z8?BK&I>tEu zewT>;CWW&Q%m@$k#+aR+i}Mn^id4Hf`=Jm%*2M3Rt=)%~T#j+CqnXq_?bD_e9;rnS zXNcFu)5;#Ht#B&s84(7PDaK{ZjI~GF?|#|YnXU1|kTN>6wi2UaIymlf$NcuCa34E( z@Vk4Cw}0eB$=#!wFrB$Ox>H+Lr#5wM+Olmo-pXFnHDYr2y6%l#sftrma~5@UI4#>@ zG`<_V@8#X8u3cMkHtcr1k2@hXczdd5@b+5fc@gSs-?92-dF?}Pzk7Y5jEomoeCLo; zRnyMV!4f>PV$bbav*y0}^KDr(BPs85$yqKg2Nz@i@zM(%NAscwx8lr;DlNz;;579U z4&EHmvpABW9^zm|t!+2skg`(knP+k|8U5<>FmmtKk^905=hV`>+`-Hh{Ni|iNArfQ zvZQie-?K5~57F-q`$Ig=rhq@P>65KlNAB71$=2i}`;Nizc+IEof>FHG*6F+)UgFI9 z5p6$PYRReEdu*-FCZ@k{?mBPj<}Is&_CTt7l&5*aWe4-x3lBZJo@I7M%sRq#f&OK; zH_UpZvO#LO0kzzKT5ixWafBEz)G{h9ai%=>CbF1bf>aP`+TZBcJPj)^)d&Ve*EA| znAQ`>#Ssq1>gZEu#IZ%&M<(N%oXX*KPWWc{?1ns&R+*64a( ziyc8@C@t6Xn)W(PHA-~yFkbt&8^29QIp%Dcn)Vk~vBX@@W9^li(&jTtPoSx3AKXQ* z0TORk0k^{F%NFkHn);e6yOyT*<+4VYmP@sNW0hYEb#EW}@%lXyyG(wWa?Kl#q4>&d<>)GkFvJjadfNn=>x5QKC*J-rLFNJEUQ!V)*~;zRMY;>O9wXH)EYTb zc*ve3#Mm3V9(xJ18XV8?(WzIy_uzE9RAyV=S#n19$w7hshxn)+KE9y6;_fZm91Y61 z876=)RJx6i#S-7iROk6WCp!ZOk3!$~3?M$sXFoWZ9Nw2%p61B$HR65JJ-B$5(A{y| zQ{hI?K9?JJ3tl=H$S;YXOPHtHRz^`Wu?nQ3XrdGMLq%?~8Tb8(k$9Hs)%NA=UgXAa z!tGvS0v@j6cp=_(7J0G9phUvM?VUHi-zFg?eoii)sem(v_K*~f;nztlg+QD!^f@6V z3VI_Z8QY6Hr6%);FG0h+k&+_bizU8?J1m?x#Cy)fTHHBBs!NvBe-O!V_7Ly&5|~IF zoIP{}{NtmEQrvS!f7^EiLPg2ww;{LGrIN9+`SSM3Ht6km^N`+k5{D5Tn-KYTkP@du zz1Wie{IgFvpE&mCjq~vMsDY@5*iWH!yrFC|s?CWF!y}RS=t3H|jK-#-P2-LIry?d9 z<5>>zF@0zzE;qIn!s8QipGT6y*jlEUT)-EIN@7nze0)lACD^KCtMJe=-dxCRYI1KN zTTA}kNaN0PbNNg=-fDvL-CUZzj88Se1#WID(#P9OaG{&qj62f!GzrE#-Q0utdqlk5 z#GdKq{+QWJH^H;q+}l~8876o(YGN=;c~%iKPE4bJMT&ozDzC*)e^y*|V$dH+zY#T; zNNG(hK;aXWxkYHDXzWb1Pohc!$=Dx|U1CTs4aAw6NQ}{%ScC>hj4k4cBPFqw_)Uz< zdkEQ<#_o+G&?JGf+-s@H`25EJ`1CY)J-guq6ZG6%8dOV6lpv04%DonvB_>Ib2R0?X zl7yzK%H9Tf$Uf9V;yb9D*yb`G^fH9TrxLG`aAm3=3A0G(g$!Z`QbS4TVApNJ=!o4^ zJrRWdZ$iz+_@F<-ANwiBLOj)LJSyLboyIz^DEc8gUF=nqEMD20#w3$5zH$|>F6@hx zso1wz+e4&eH8K7{H-3r)hR3c%-tk&#hx*)$QMd7-67cr9xqo117-oW3yScA3INSuU zadT-4F+M_q(J#2UA7g%XCKhLoB<@5mu}ACQq59v#Pcm6vf%=Vo8mc4*N#}K9Z=)KM zDbtgk#1$x6?6*}ke%t>5iWf~*O=l9}sy0cS#B)$G_Sk@hW( z5Kr*+Zcu_U!^&8I2ddS}8& zgksa&vYRQO73D3-s^VLVvA0mgS=9ymz~;ng_bzL&^z&$}3N@WIL;}g!*B~?N6bas+ydk}l!fL%^@N_w3$V7HT9A>OEycn5j8q|Uf<_s0Y71|I!daJrP|l%_m1Gy{ zs+<;IviQ2>#4Of!k?Xwx%@fz)C%3E@NvGuI4tfj>u_|{i_iSaDC+=>!LL}T|R z5vY_v(#hHnTHwEaA zxdT5@{y16hqWq=N5%3mN=5Ir7c^{FiZpSR(dMohjd5?e`@m8alQSWVN81n{!68Bur z#oj9%MBW$CPqRGQ6U_D|pwV)?v5=YT{RDNE=UtAx@ZJLcGFjlYK|-PT4KzY8ZzL+E z$om#3#ooW7a3x+XB=q*SU`p!a{Rs5F-hGf?>TSbR)6bg%IsLsgkUzltIdU)ailF~M zkAGV)_a26}gZO&Blk#YBu)@0;&Q*ZzhDf-W-(9 z^JqIU>hU~09Jk1_0KJUrr_;d>MM-x){Qwh!a3kiGjN1ztodrv!A z;o14zop?V$)w|xUXh_f74xv%+ArvO*ZJ`|RkCH(*^lA2HA$Cvxdhk1L{u! zF8+W}z<1Ljz$y3xr8_C7U@6Lm)HwD_JdRuNfbn<*zo0%yU+{0J1-N9vE5=h;@KY!Z zmnul26Tme)i3lVX?uoF1dq0Sb3!fN+iqGPTlqJ5AAZC^0$Bg=3gYsoPxRElw)zHxO z!DDU8WE*9Q;7T@Djb}Z80K!5606QQ}_-n4nvYbdkn{Tvey6Yn!% z>@{4xaj4a6gm~{ot@WxC?=VtFiuY|O)~jB;?~-AZc;}#Mdo|EoBl|S&VWTV(<^j}B z4Yz1fA)1+{FT(w<1Ct)y*zaceN14OX`q2>aMD^bd|5Wuq2>&eg{}%oQ>VFpg)74L7 z!)L1hRrt>}{_K9xrRbt0SH?cvY;%Uj} zL8mF+=!@_;*#+nsC1=FB?7d5>Y|tN*s5>#-3a%>n8oD5D??(CKWaXj4vg=VZC5wtk zX<$?+)fI>@S(r@`Gi;QTLv8xhE%6Db(mG$?k#5#Qh~TC_${#0d7%D!87N7ebxZI~^ zPr>xlcbO=;-xray6#Dh)`kp03DGFa?p&OUf<#GG{D?f^pf0QM6M*ag41@2KliuVxC zNE!o7xc^9}=KLMimvdG%`e<}5DoAQM`Ze$yA1i&blYJBeFn5ep>;$s%$I0S?nsYgP zeHJbvRjNq3P&U83==0HB1~xECik`C@g)ClvJ_({}&QloAxgA%NAaaG8eKEqh-I5zO z=u!EhEjTCZW&CD8%lIydzu(3?+2=rb!3{!vnpEkw*$=~8aC0x#&YM0p=S!%C(#6@B zYmCy;x3X#GzTmJ(NHNMtcn|YH>1-*=SewAf`63kQx4gp=qM}~*IAqhWQ+R1}ScE&- zXR!m$m##z$!zN4ixoFU6*#prd`d3TRuUIB0=NFiI@)yv~ut~+eNYwvvay|ypeV5SQ zu!&~}F});*jac~hpZzFK+)mB~m|F7BjB?JF=Hk-g}~(V!8YKBb?U-(s(u^_~dW0 zwY(WAkI0696lk@$;=J=26zRnj3lW}08t+CbB7Fvd_7Q|Pk;WU0;f8hv!WZKjdeK0x zJ(#%V2cC*Z<5uX_=PE>e72*B3O1^}^zrgbiT+Yxl5K6)0@`odHcx2qynPxR29z^&7 zTqWBOcmkeBaXAt8efHM7z=tC#d48&%l$k_bO3#j@;9*Djo$$!pe2u@k-dQ%2=!a;q_*%mhsLi5-Da|m+_OKcw`{ul+lcLmhr>G+tA{62>c5x zMgETN?*9|`(2jrc#xg&4hQHv7^QGq3y&;Uvhc_3OUq`$>POqa%WGvGV)@<~V;!mT_ zekPf$MTEP*8e1G>@-uG?GZ_eBeQ`-=x!;q{(t_|rT$1qvCgU>^J{?ypi|YQ|lOE)D z#(7)(ph>nF(d%&yAB%k07(c^28s}~6!=BvX?Lp*)xZ-?vbi`EMK7>DkE7^twoL3`f z!^4UGHl#LfQ@8@8o3Rw4pgi!?k@wm-89pIALX5E6v)BANL`#9Ts2b8yW|J5ay`3O{ z=x|+4)~TnGT65`jiXVfh>!rrlBk1m@!RkD=_x0XbHuoXu%expEO#f`E;thmfVmT_2 zgln3d4NT7kk~fcUO*SHqQ&e&SJX{Ww&DPTn&kj;L;Nh}baV9+MvUh0uQBEZrkR978 zz8UKAyH9xn3Kf@QIS>^u^2Sp|?sWLnN>semsL1DX8*uehF@@Bu>i1VsH0wmR)QpC< zO$$}70Lf@}6T18^5lI2$KRA$LHTzKm!S#I^_Gs`N_ z_}t6Sawrn{T?91|VU}E*W~WEE?gF>Lbr&M%zRd1~THTCXcsMwQJ}!4Z>p-+x=}n?m z{7h~ZF41bGH;-EJliIboWLT~7WJ=zH@cFo8htBN<42ENKbB2g!k8<~a5vz%aKEo9F z8nDySi-ARS~8j8SI_Xp=)UjAe)ILsQ&A zWsPzoLlD8r`e<52eYmoyDtk?46C(3wl<7GPz0;&j=s+k_De7O!becDg)kUkmf50VW zI?bEK>WW6eic88g*OZA9>p;>t56|-oI1e`?JONis8K-zZreYo| zkK132Vs}5M8_7Q5H8J}&NWK!6WS{UlnEfXaz8IHeUtqGo6XC<8{Q+Vs&BXWu!q1Yn z1wX?K?cd@38)uD3Uq#d3%y%bfD?sB8>{C9C+~*;Nvn!{=8^bZoV;dr%qNkbA%ev_9F8!>`z4~doqouV zaw1QF#*O!zJ`IZ6@-1*DV3v|rd0xd9=n^WYyBo2uB8mm64M#~wc@r_*@Sp0(IFWZi z<6S|g&@?M-3DMPg3lT}eL;ZL9X-vEIqAWdYwjdZwK z#f3w}F^$UTd)qyQqmQ4_Pvgjt&6g`15^mp?kjBCPt}BCoJHnfA6=H+@n}lJks=M7rhGlPjuirBK zZ*VVn<8Cu#j-t#O=0A#(rcq8A_p~23=^HM@bTSW&rl&fi`7EE|#t{(M$0?_f6c+;S ze2qB?cYmLhcA@pA3*}*>9m6H{x!!b)QxWC~2fdivdUpBpMHbrKNUcufT!7C7g;g8fGS$>aI+S zXm%n)5y2EUgd;E~;YjRyL^VK#@B2|saG`Go#Yz2vP%3pjoPSd-gnofO~ zj{ELWrjtxOwP?VLF~yuK4Ooo??*5BX+F0khquDUWPm>VQ_|GPG$`ED&UT8qTz;*yN!yKQ{3 zdJV$+a7jjsOh(^F_&d17b{y~Mo`)dQC{Euxi03_v7FzF}oz!qtYLR5#h+lU7P%8hYsB8V2A5>s$7KFdgg4?Ej!6>lOyh}p6&SvX`FfyR%0#y# z@-`;oUnYkb+ArXJfHeMra-^X>i||vV(X8bdLwf_^*Gc2wE}IO^!PNaOXkx*HYx(ag zq;z)qFq;oH9oO=|m`GX0hJ(hNFy8a9dc=$ecM|`Hx;KHZs=D5W&%XDbo12l4gn7CN z0YZQz3?d*1fg}=%0YaFZLLdPGfnX98P%A1bDs`$_2UHxZRa;b4Y_$$`K&w`*?Z1On zYt>q{)wYh+>i0Z*uYK;hha}qXd*Ao>e*2e`=d8WgUVE*z$1~isCnJHAe2G87%|N}y z^*rB%6GwL#PLD_UxtM(}va|WF^e31pbpet%yPxb&VqZ8K2~_?HlaNrJ>xLCbr1E!o zxtwq-;;7?GUL5E5463GeG;5Jga8bwi{akt>vmGg1i)5pEJmZnV9wL`8;ho^2wxj(# z)b=m(B`}vI6{YauA_xh8xA&(%1 zYmukD6th<1TI6*d=dDH99Jv{c`y+jAQ*{ zdQx8qvKq$_t~8$1iK*ukP`g*w&rVQQ?uYerbt|t0xC=`1U3ovPup;J+IC5;K48u8*{ZWz9X zCAIiR4@ljcD^o`3VVZa1PtZl^CHodIvw`hML~TbDtLFO>HNlBpBwXPuB<&tAEqnu_ zI3>NLqwK831tX`V{2w8iBjDdmvahQ2VqD)hf-|WsYBu&0u)hRpu}5%1Ey4$ILJdc1 zF5Xgzy&-AY?@Ah6g?KalvugD8pY04~MIZ4nW(IXj6s-C)Y`AtECDnh+P*(p3sFJ_n z&~^PoUDpFKuIJ#;^?AEqr}E{g8I0mh!ygUcJ;RM4S2K$3X0N_CcM-^)IP|_kcf;p@ zga)+jM8sj?=Nr(PWN)>fk(=;cqpX*l7yk1ReL}5ZiMW$IEHcgd0G|MpO=8#g+nWG26NvBYA+7m z4$jgG+h2m@f=J)L;;iy<_j>8&87G%ilr8?x#%$qmRc&at6HG%+;nCV*22CXh*@sB}Fzn*A?&xT}da7<24XN1c%!FJ*vb*$9@9Y_hLfo{s>ukY zq&MSn#?-NpO#Zn@uE235>vu9U&6|sVr1JP^X&us5;>cS9Vkb^^kXQ-gDx6$FVk3y# zaB?GwZ6F@U$ie;Pgc=j@%scjz$W{y!Q@DS%DPZFa26l$lWg7+!Bt}Wj5^N0&E9TI53Wr6zE-W zfk*&k$MBC&T1|fek=S3%?k48nVa)6~hBq|BS$e}P**Yw0H{rs@R^A?5Dal)p#khYJ zH?K#!`@&1Vzac~NbRLh(2=w4#%8_k zzGQy>oW$n_a!VBK((>{%lXv3Eo8*ko4fVT!Hm-E~XluC>TK?qf+?fNWV*u{!Cer)) zcJ1nKb{K$k*aZR1Li z$G@RkiP>7N7uC(I&dtnM>(enmS~IfIk`gVh%to_;8SCQt*y)C^%!r5c&knQ2V|B~= zsLq`fk60|y(e3SA~A*Cqc5UZoVN+z>S;q|n{M=lok>#g{qiz$f@UEuj@Is{CU z&ZIqp;cz6n>huz4<^bCf>3cTB8D8fBtBIs0hjSR5soQrtyUVBnaqYZW=~&s9Yk%u_ z+A^EApz#^+BO_jj)veKss7Nlvh^n-^9(ei zWCnaq(-S?(V7m-mcq7a9z@gfEFY6*x~E&lZnjlT}SAbZngB3Bl6ev9-U z=xHMi1o8h8=(OZ$pH7jZn-JCHS2MD99qh(n?gg<**WkC8;AO{&U%~<4pd6_2`9|);(P^0AS5y=D8$F0w-96> zESm_{iJCQGTTFK}+whnTyZljPEGSa+N`YP}I?)PYLbr)26ls$qkrQ5Vu8Tx;SBYhK zk8*||o8)G_73Ka=PysE;ib{hTY1~1w*Ht0dc2(#a_N{9|CYx2w3^q}Y$r0xaGM*7S zi;QQ5_GtN*Q7g%wCVMJQ)7=h=bDb=4+-_6zy{zN(;8$k4=SPTWk_2WWIeVbbW08S_5jA+I zKWb+i! zNKyj)p4Gbdo`UUEPuZ?~UW;s3yOeCLnpA>rv8SL3o^l$h;WU#;+Mmf}Rq~4HjXg|z zpMn-7McAERbrDPSR2rRtLL%6tdvT=pXwE5$ZC+v>6od`5moaIXQHF^tb(S0b~w_o<*6`>3xRPhGB^wSU3o%GY4 z>PJa_`jOi1caUV$dm$s+Vq`P?)+d^OvCkR*WkE9X_l1hwwwB|j%sW#OgJ=}DbCArQ zFc@Pa?a@KX(mh0PGdvX>X7gopKk_*0v=i0Ss3_6?%esAdoKo^UkC~xmbJBT5B3?thA zP1*G_K<}|U);9nIHN;NPBhh|FY947lmdE%}w^}an`wtZtMsddpmg@yyV&(k5#%FrE zs6}bDP2Fm(C!1Oh*_y{{%{zFgTY_nnX-7iNkt_UiZ~?=6mRuNmr_zO)89O$ksfPYf zP2*nw*DJcA(01rW{%#MA^u-y52Wsa?lhf__i~yr%aOB!YTcPW<6dj<{8@fz~&4Ggm8Y`xtB|;VokZwlaoE2Ap+*O@dZVcUUHTy8`)eCs7Ap^fFitzb)E)Z0tIS{uc?! zXE_Xfn$KYETx&@E|8MwjFZ^9Rjeru7$l$~A6FhysE%F_FK2ERk%`f))>vOXw`2LV4 z7U=(j_5UpWf0F*cPXFhJ65#4?{`1HBc$%SntYh_gf&L%)7XJ-rj^^BMG`h&ho2KLT znK+~JTBjBdNW;!8Shjqtt;_kf3*WxLCHU6G>XtR7bMRfB(#7~ZQt6u3wv~;oi|}O( zeEXslpDSJ2*4a_AslBZO`+;M7(bm>d65~3tZRo1CjV&9;wYF^ByrmR-qK@0xwy}9! zGj>h&whrIWh@FTxHvb383D<~-fd z(y{8>=jej-8}>!lRo(r*=v`>k)Y7pD+q3`o%Gn&m)%bb}v8lcBBpcs_@^*XnF4Ul7 zm{WF&|NoTvo3@$nq4=&0p<3A77meY+)2d}-Q}c<;{0()cca!TuwB9qXhjiK7#D0Y5 zTW(eli?F+J$y$!s_$dGT(;>^R4NU@f@!(BxjYlZeiT*Gs<$nqcwAZRK zmd|sCM)Tb4p%H-g38}riQzth%?+#<0xbXau|69Zjok~akyJ(I105A zrO|%wkkOPE?c??t!c1PtDmvVC$CQNlneT*GcQbn~9MIeCn-3pE^Yh${@b^zeY#yt@ z&5kNs6n-nD+!Qe9)8aVR5gJla09}zDcQd2;s0_TE7QXc0-0w*4LX&MsA~zjlbF1hi zH#5AgBpTjQ5}h6mBVNIf%rUN-8BbFC&${mN^0Z27blgoD;f^puhbCmB=8WGdEzq9+#}tLMUhatDt{TGsZnP{~5-pv_mNny`EH`Mua9<0I@VQX$>w~m6%Ce3uk>7M&xM}ELNmH8^izjE#DhL)mF@N|i|aO|Jy{aM z2a9}7?E(%58`caAMAZ+X&Lr_Z8s zjD*Z>rKqx!P|oXYB$&VMCt_F}Z|QLf4l*z>8)najZ`yp646WE^7>hjBF{*)@+z=gOmp!RuyB zauudHjJG3MyHPf+@zP?-aycvM-o$30*fLf0Nc;~+&)|Q?VkjC;K;y{Ol}jmo-2Ow{ z)baX%bS65Ti=LBVr?5neOoxh@`EL3!PByMP*%oa3EP9UH3p~9G++Nf0?X7}RH?_{y zxk}yiaU4T4N-#;)9Sw6J;4s(_o`)V6PCwG^9nP8#{&25llB3W~ALPz}val)NKxTAe zX{c9H`}o+KMB?sX$b=`^fik1TZfZYvc=QsC?xT5eUy zH9+PV3~GG>t>PA2(d+|RZm&XJuc-5_$}JqFCoMDAa;VJG3Kg(GoI@Rqc+ydiMfQW2 zWS7{1QkoH3W|5mR*3Bs3e=!0YmT|qqk$`IntdFqX8I2XvprME;pv6GDLYjbt0+TR- z38n4?R#NK>P>7Ga#ilv-M#spUc{mrEXeZ$`bYrCw+m4tkfu`ox=FVojmgk;{ zyd1&5wv(I&d$r)yENQ4*QdwKyuxL)*{F<7E*_B6B*Ct{s>dKckESSHjUT5KjN`v`k zDp}^wKC+>zru+!WTRyv{(qA0DRN9O$k~TNBbT+PR^)zY6m#$B2h8~S;9DL0B#D=Ek zO`U5g@2JY!#SL}y=hrvPE}t{6VfNzs`uVjDm9-RHLCLy&e&#f>VLPvRXq&n6a=6VS zuizUxTDCQNW}0ihPG?o)rp8q*om-ve6QNl{Q)6di!qg?@HH#}7=FBaxJ;GPo2HYxY zSlis#)ZE_SE7@=T5tWPT7uQun-`Vtl-=me4wGE4FYvz|%G%Ttwud8QbRZZnG{F}eD zVb1)T#YfdPEUhbF;91w&*4SiRoY1kM)1kLI9IXtsNEA|6SyflLXs-3UI2Sj(Q1zZB zx)zTrN5#U4It?PF32+NfDGK*>B+@!8X)_#K0UL1B&AO!1>FC_r+T6j6x_0zN^qboo zw5s|$w4H04H#9f2Y+T#io@fY~x4n6FJ1Pp>oiw&vffU|_;%Ehl7NA?8R?%V2uu6`RHdyHB?nE zgB!dyQ(e2L5)D?@hv>ttZcS5JwbHaj(=lwTVL#OU&YGt?W^#j06fm!HISKTO`pSmN zifUHE+UAxuYtb>ASNr7$zR;|z($mB56jp=oSxc%HRm*6k{Y*v7xWzB)TYXI{Uxk|Q zY^KAtu?_8QZP*Z&&1GfhM$77T7d>`$wxO9dHE&56vt-fo+Bpf5y|SSW?p^NH4;zGS z1TvnOLN<4HqE*6WUN6*p`ohKHcIK3^)T^s%2DNY^D3o-OHc7; zK)Pp@?cS)&6BF6y=*~Q6ZsnYL)KnT8$2>HGuD1!pD1otp_a75tWIpA%P zOE*ddzJK|jC~!=`rGB4 zRlOF_+1S#WRMOJwiX$qeBr{S}R4?+@1Ey}+KQ`kTkT;(TV`WwO;+lGlyxUlHUbCo} zzZgS9!s*D+#`CKr57~CcN~)f7uy!S4 znV*|l`~yby(TSzo+QtqnKibzfHyI0XJDqN^dwlERK4FUpIrAY{Cun#*Nxx z{x-azd`>00>-@!L6+-85GSq8WJWXt;d^;nVCQg>ko3O%cwq|;hzAPWW_y5yv6T7H& z(*@?vuhUJwZB0Wf+|g>f-9e6=U0J^rW0AwriW8Mz-rVYn3MBcXWDJ<#we7B^j5+1C zb1G{b{j7K6s%CGY(M84$3w69%U_q$IWy8VYU5^L}`F7Rs zIo{XMyn0HytfG*EmJssPQD20zQ##%rPps{Sf5|3uWZd+sIPYdbD^G38?+62v4T=$MZoUUmGiuw zXjGFOpG^d2HqMAe5UHkYibgijK54ZnvTS_hbx*!baAo;yU#(_T}!ZVs^CRYIl2OK zcy*CjwkJpFp%IUyIVl~SVG^T^rlxaY%+PmcylC$(Pts-fiH)tBn;S5_VOLV$h2N^S zw)Q69l45RkeM3ENfp`_gp-JB(@LfsCMNZ?^w#}V-x!uJ`chJPV2=_3KDI?gk$s%G(`xeZIpp{AMUy_7nPgSZYdYa%v6J0vB} zF{t~7W!9wacXH`#$u-Rzo3SxZbCZKNhgzHTIEsQyL(;vXffu~mFOn6>iALzV7v%K| zpQ8G5a^YfeGlp4Abo!P_QgxSCENMV>=-TiyL-PDObj-S=%IiH(da9MzF2_w1-%M;8 zirmw3Ha2e1m&T|3TDrlL4LCW>5y1*v~s@+{uK&I_?t61X9&;P z(2=98+>^r1!-RG7eHVgyHrm|I{?pLe*bb5{Z#CY!koL%XS$br$EyL8d+{0Me*nuvk zSK3%1=o?j5ExBCMOHF#GM&BNh0qlsnYCSRNdhi*|i=#!AHB}9ZumYwgw1Lag#Jr(z z(1Eo3*!etGznl(}JD#4e^nw;z`PwdqGt)@4#%5UKO&V}{BauuLdL?K!pF*ms=EPc~ z9ILwueV2AsYYT3%Y{Kn3%#iv@gEOd^PEv8YDskCWTe-BMz7F?`6L!_t zRWIJ{nKj>DqcWs*Fm)i0L3-pxOfh)jO z7$VScyqh~L!QAz7PO?`D$$sN~Te0s%xupQ{C5E5_bf>+L7tQOezfxt2b|4)zCn{>H_U*!{@P@`L#zh=(QhiOJPZk zg|5f0^}`biP97Lsym;>}iDwS$MUO(TlB1Bc9+b-zUY44>|1$n0nz@+>#Wbs?@rx18 zT0f{w$N*$V3D5dPxY)ydlDLba+l%e57$Qz$$-0-Ck!=oc3*Z)sEx5}Sg1<4Eo9et7 zM?s=St*k>$jrkp#u+t1gEXWL0tJ_v>?r6~0B%b!h7pCg0MrK%cj+irNTD+*deM6j= z=k@k|;kbThwywE#e7tD(X4F!guMQ(}!lcooP2%|Ygt7^f$|jH3Z>aOlZG8IcYdldu zB?}*WAZ-I*eYdZvGmhuwS+O0V3sm*<_(q36tuT=`pJ_$RAc3#S&(7+P+bmku>~w$I;ZG;Zvyym^ww!*M z{AopiFLbg`roS#Ie@<3phnkxP^(xY52iogeU1qket7U1=>)xd8D5pY={HcJ0Z<;xd zd+4}wd~+bBJf>1ZY2gf&6UkG3RKIY4H9!qigVoSTfhttRszQGIfjl<&V?j` zmr8sgjBn2RL)hsT(2rmHNQ5xH0G_N*P#!+j>3@0}_TiKS6fN=R6TYx<7=S5dnE4{K?RFWFUQHAiXG1UXk+~ zaIieiJ)z{$2=a;p`Nst0j|rrY3&|{qo4^)Ax<7=yAGw*>uyaU2{vm#L*n4O|{-K&bF?Jss;GY_xrv>D5pi6|XGd&=G zdO-g41T)UU*q_NC!p_Wq{F(k_@RtYVmj~pR2l(d%=!$^+ia>f*Kz>y~epP^fZh)>1 z$gd8h&kM+(7f3%UK-UK3)dtcR1mrEy{5w3Z1x|^yAI?`HXOEY{ldw}4pce(ov!D7g zY+=Xzw$)||J4*uPFVXoq)|s%xsYdw>9Lbb(vp%=~!p<^#sxgewH9skaqirIDonr#! z9i#b+JeFg;GoFN<;{x>Y0r|%V(pLoJuLz{C4A83r@>T`Xn*;Ki1L>;+^qPRYHG%Y& zfV`GKI!B>I2s`To^42F3aTdmGl{}wp2&8We&}{*EZGrR?0`g7>q_+p?j)1(5K>Fr@ zyv>3169e=~0eL3{(zgcWZ4IPv3(zMAi@b9RDR)8_=_pQH1??{S^u)JuQm%1Al4cqu#yJLd-I^8)3c7f9a~ zC~sFF{el2}VL;x6f%J<5@-B87pf6SCOcZi14)A|3Kwlb=e`z57@__uyH9vorZo=jE zL}S>wB0ygmkbh+${px`Hs{`rR1n6r6@~#b}?+M7;6G-Q3E)l}cjRAQ#CK7QLK4^Rn z*8dLz`F{||e_J5^wm|yrf%Mx0>30Uw?+m2>I6&_W@b3+z-yKN5JCMFFkiIXFeqSK{ zzCil^K>GebI#;`i5Oy9+5I74v4+ZFl1N5T-`sV@qi2(gnfPOMSKkc-7Z5dw(Me3FS zePMvUDL~&Jpq~rSuLbCL1N3JBIu=T(NPXe~dUAlC8=#L1&>I3Y_b9P}@-GR{W@|XZ z!Ss6q=|2~`5NW-g+nqlo(YHC=YupCr?;W<3@h`U~vw`Vj0`%+vT_2!V2k4Un^sWGX zeSrQcXu6!&-#J+SKO^bJp8a~qutfTF=l!Jgea_cO`OBTY5o3+Xf44IhbRvJ1Q<;>$ z*Evqo%XInkoXtXWCdk26@x{VVsr1jS0s5f;{bGRrbAUE`DN~w}r(C076X+bQSNnsu zf#nqh=yAe77HK(HZ8T7u+u4Q@)EqKCW$wAyfpJtRM!dKi>S5){cOp5>}F%T zc{9Q$>t`xH-E2IckObeUv}p%DpRx&EzxI-p8hFyoCo7({T|9uZkE%+_@DR*AwJI6! zWzg>*Lp+}Mnb%<&8uSg%hRqvK!b|TBt2S-I*AvRfpY+5>|E@?P{Xg*u^67T~{J9f9 zv9OOAB}?Mva{FLQzi(+%`4C-R_Mj$KWZ*R^U-8Kg%DhL*`cajS&HjQR`F&AgNcsr` z;*wq+_GrqM7v0T^e+g6cvqAk_(f4v5GA82Xsb+GrX@Y$0mw4?Exq`11%9{vXR++A1 zdXiG)4IqfHm6#lp{4)n(OS~H)5y>yON@Um1CbfM5H<$-*$Yv6|cxs#M1kL7kZSR3- za&*#L%pJ|%dz3+TFCmaY-d&Oh{#H5GXrL?E21k2kgwVhA@wvf7>lZ`q%SC*lNPEcl z27vd*y<|=L%?>r_`qj_G&tl}~9bmODfiai&W4(ae%}{fY**aRkHQ@Wn4Q2t*n5id9v>P493fAg$AmEWhN(eDWR)(Fs)|EKjX5otYd3{{|zgo z+X2WtS(gZ@CND10NA2sXzL9{%4zdG%r*rc-D8G9$7b^n@L8)JmSEbFDM7`|Aw!`6aQ|W(WHHVE%!)& zh`rm0|G@qv#D6*t?}jn|79#k!6QLLHdNAKbMC98|{1>(eA%cG|5&H4!ko=Dkk^dRu zM~;3*k@m6Uye{#`qVqwNllBR=mn43QUDJr4;j3?0ATfU-F!VWg5Fq{=TL2IT!#*Nz zxN;2^8iFlFfI}glp_mr}4DbstUDCb~zd$&$YW=wOO#^NHG6gjKdL$9$G8E?`hot%vH|O#60D+644HK z07K2#jfPl)9bbT6`&f~+fN_UenJDpFDE4UZTXBTwzrZYN7GcA!P2K2(xcA~(B}u}ivsjz0s5*0 zt=q-hhAzG?5wGn)e;J6VGzqk5Eo0Y1A84X1(na`ck2H|Gj|}80p+9tC`Y$* z@W)9b|774$Rxd#wqhzRXhmP^F*mSXr5qw4ZR2d5Q^_NNWak!Ui?FecwKK0mVqeFAA^bT zW1Ki%>2ZWOi!{ddWkj?mj*o0#^yAP8P!6H^F%4cn3QaWeJz*ZQgkCiH$VYwfF*Gx- z2IF(Pi9bZ%fhp=H9mdBf7oE?Rr|Cap11845VeY{Y`wC5egLQ zF35h${PP8m6I?0CcEj||f@ccu6lA+$`Za>L3EnICsNi#gzZ2w;#e8UL8dKnM(tOu| zh@o0zTo6^M=^27Y3N96F5?+ zVS+~p)(bWYZWKIOaHrs9g1q-jdw(qWGr{KsUlDv?@H4^x2&UrRDD!6t4ip?F$a}p^ zFB6szt z!BK+a1i5oK(|IqHI8(4vutu<1aJ}FOf+q>`UMcgRDR{2ng@W9Boar|Rz99G;!B+&| z5PV1Q?}8r*{#%d(B;|2~Ct`+Rj$nVmp@M~i#e!vmlLe;>&K8_2SSwgBc(mXO!PSDT zg6)D^1ivG=L-0I7?!!&JFBjY`c!S`rf!2U9 z1qTQY7vvUuOg~1jQE-hQcN}K=IfCC6yi{R!AV#M z@_Kd_5!X>Q#F%oH5wQquBI3Gp6A|msQ;4{4v6J|3$GMb@iyWr0R4-irQ^F-XAdxwbf-xvIc zq<<;2)5oOaYq^>~OE6!sSa71?biqo&Wr8b-D0eLpW9CUhpFu?VXA52~c$MIFMDXty z{527B{y;?AeOKs@iIDTTU@9(1NoNY?5Wzo2uvTzA5%NwTj>P?Jq0c8G|Am6r3En7p zD-rqb5&C|?2Z@mLq@+JfoCtk|ewzrn?+X4~@GHS^KO;Ab2)-P_eniL_BRErVnc&HS zR}rDt9wOHEKNk8YM9BM@;PZkn3H}ce`Q8xvZNc{>{u819E%-GN@(19C67vls;wTY% zDiP()5Ijn7q2LlC@-+(GEVxeMHw(R0@H-NJuF&5VyhP%!5&C+;TO|H2q3;#^iNrr4 z^wWaR6LI`SPz^BjAi+|>*@BCRpF2*2&>e!`6}(08VZq-E{!1`|8zr3gvxz9PQ1A%B zM!~ZLuN8bi@HxRZiMaXnvC!FrjJ#sO!v*IPQD=*VK3?!7!HbDQ9Orf->g6sX?z8@a zhs=Y^RXwr#D5{^z$er@od`X93HFir zIPq-U50&`C1?Nb5tcsir}A!uVeg_^p7R}bHT5O(6j$AgZYB91eXeK5MEZE44-uRu z@s&bX3)T`L=NL&}E%ECF+a!LQ(BBa}Q{pcW`VztKOZ*K&-y(Rs#NQ|MPXr$(qWl+# zxSo1N=nn-`3ru>c;9S8~f~N?6m&ofbq3;y@mEhk5dk;7AiUlhLmkVwpV$3*Q=-q<% z2|gqE2Vy_R`IFG^3i4$?+LI?(BsfQ~MsNx74cwb!a1W%LnbA|q{;3X2j zTj)K4H%t7Fi3c!l5+V0diT?!=@_#A#vc$hC^c#YIAtK+Gf;l5Vx1fCyA$N?>hY)YV z{XL;8i8o`M5o{1_7d%Vw3c>3I_X++=@b7|Ldr@AxV4mP8!7{2_^!nNUGP)EF9h9U!{3kC z;y9y-PodoieVAaSU=48{)`NoUh^IKtsYK{`y5M<&7YJTKJRR#qp?@s6U+_V}Cy94B z&aZ|3o!}dSZwr1v1m8!**YTZzF+h}`Dwst?{9wTm5+TLkYWrlXz&RTwmsFBDur#Mrb! z@N~h;h`1iTPw)?d?+{(oW5l3-&IY<%=(R*#@9YwMSnzGZe+ysuxfZSm4vB&W))CJ~KNZ|XJlk<@6MT|*lH@vaqf`2Ds9dJmh!IK4lBB-A)ApH%Y zKN3`FhJO(8X4omXL+}B?-wJ+6yvuP0q3($lf^C8q3*Jq{eDWK?e-Ia9yw5OLMx2ND zkObR^Cpgac1n(DoLGW#2CEkJHeP-YY;yT>_65Js8UBN2^Zzf`VdQ9*&;^|m#2oB)%`xU0@ehpK#U-Y;Jzf2+BAL|ifzT?1D?H8D;{Q^_9Utp^C3ry91 zSw#eM3lYq1L@;kAg85`3m`^9dFWNt7Cl`=D0qYnd`~nlTU-l5edLxf*mBqGyqiFcXzyy%y=NI&E_?-3t!oO@j$4*eWG9rqha_ja6u zC=hbMQ6~G#wZs#!jv>Mi#Th`fkGVwnVKotc*g-tsac&^O5Bhl${O~Gi_(4BEf*&f` zk8VagmHtq|=PdBUE+YKUmJNg-ZYRPIxIOHI{w)0jJ}4BrhzOl#30*;ie~uM;1rdJQ zDfBKP{Iyr;eMI=}fY8qp$KpAG(C-l8N8N5wenf$WKZ}T<_4~i@>jI(ciSX}Qp<9Xb z(C>uaL4?2c`#H$Jn>75sSJL%+I`IDsLcdHzJw!r4@bkButdByWi-@R~SwdG3Q9s8D zy@H5(Y884D@pQBcp|=xJZ@YxPh=}^zE%Y8D>hTVt_YzT`4+{MV5%v14&@T{Czi$ft z4iWX79R@=GJmMXWquZ7D%>jr+Uu>?P{ zFu2y9=?{6A=N@_WjXR3ZAeJl~@E9mLl|;a&13m74fDiv2+pI!-qY zzf0a8O7E6GNdv88Qf+oq{K1Spl-)IRQo&vSO0zrTyW#FZg&uMotcU##kon=1`5JML zs&tv*o3!aRQ<6gR+q3S9x5+&e=4VM3?fb!CxAOfwJrxq^vx1(E-?Hjby1C04#^T89C8GU+g1W7zS6m}5bL6wkD#r_Jkr)ubeyNA+~ zz4A@+?QcuLtlP9`3Gp1h{%I zF38#S!1T>S(l-u9JyxXcn_aAHlfQw{oxuUF9t`e+Gs(eR>vU_3N$f#-f+0yL?XykD z^!RQX&B2U46xKEKK?QgHo9ga7Nuk~3_y$#a$d#m1U^e8gHr*-H6>AS#bjfa7wD+x% zGPJQklw7z;w7q_|^(E_Atn2N@zq%I(xP2q3f2ZDVS-(M?Ej)?MsO`Vj3@G9I;Dr9b zLRY1GYrk$elFGzgfj}X8)-}Jd?@GQe1v{HnZ}ThgXg$)qeFLmqmUZI@lAY-z!NN&`E0-~CmnDbPk;S- zmLZ*2t~BzW0UeQp`KobHp3OHM=l;MnhD|tdzUd52;T{%{`6-LRVk^#ZJJp$mgW*k- zi`$s`-Y;&`YCh)sIS#)a6`*me(hF9f?;*x7?<1c)#rK0X_yY}*c+a9)VR25Sd?_MIdzkN1PY#QMN(V9$;z zBG2aAX$1+gEQV&o=hX-Ks1Ic^SUVa6<&O2)fm_91xfe*eeAd8#+n$~b(kz$9?}X3V zdnw|mvkkV~yAbF1-*lAA=N_~-4+r_E?=MB3wf9+{EF|kPiJuxi&tCE|KV>o4a{q;R zf4LP`C+e-A@G)O43S?2%4&G~C0NMtt&mf%m<<&#p6fn__0XVE3y!T9bHeaDVK^z0q z7)~;Lo*m?)K9t2^?dU+fzua9uI|d6M^Sxx`d3KBi&2$?;>TpXy-fqZae%dh?&$EMklt)<%){YMm@3-S7pB?$a$9y#y_~;{B9}AGrwq-om*`22p!gS@%mp&jFJSUYBlJe!ZdUG@i-#c+b*^Xy=K zQykWN14d)dhI+7;imXhOUVR-fwv@>(Hp7MN%U$3!dd8Ifo6 z?d-;muMMAP2l=Rv9bYMr;R~Gj?YP5d$00~3AM-83b3cE5@EMVRzO?fATV}t!2O-b4 z(?fmoszsi)gpc{|k#cSS;Ipl+>^MIl?@gZ_ z(|z*n_b#m+2fDF?&ye9i&kpiYAIf5|c03m-_e-B0c+~0DM;r$D>*IxP?D#k!FXNg- zeU$s;^%Z&6j(57TqulU$c94&DP!@x=V+Q#A?Vu3l+Vx9?@G;+I0XshI#*VcCd6Rs0 zRQcqcFY>G%F{==G80a&G{f5u8gM8G7vKVZ(ecYg-9I(Oa z^QVBkV}0`QsM@RFu*kFdW?6+qptYma@OgHSkNQv+gUvPue11DxedX2)AM>3PuwyO+ z?4lqER^HNpyi*`=EqFLyaUDZG%HwbJsjIbv4LLT$ejukkp9TAad^F^&-@G!6}hRKG{vm*vR%3Hxi1ZxMsHGn^7 z79$Z(@!7Eov@Lg|lxvI2#)*}|d{&<(;j?s}%|Ipus~_JP^81;5)UR1{C1hU!KKyz5 z?egij2Ju$EC#76l+~98XdrQLtpx=W&{dfb(>i1?qzggYr$8R&R4z2$xy3sE+J-PjnkNR!a z+L>~B>VnVjzh`~=orH9&-{D4{*UxLZ(QlIQS^XAtqaWX8_4g0*QNOKJ3c>nseL%lg zeEOX%e9X5upx-jcE1)0=R-an}`fck*KfY7z*Y6b3?^Kaz^?NCx-}^rOP6My?-&kBs zvfgZQJ8+UCvIthc5cvG{@g?NZzGrZpj>F0;5P3G=W z?+3~~c2B|%-ZQl2z9r?_c69}WO|pgg>wZWQx=1@BLY5(n8iqhrt1@STnXCRvBt>r`Uk&BRH$>9e^#II0ePK}$8u>0 zZUK4njuUw{AHP}T57rKT6UJ```6!RF7_1!^2Fg9fX9tEPuiTHMTw5RfnB`h6$^5hW z@LhhtUv@#>T(HoNJvgji-W7Q^-&)A?2W!Uwy!-68gM74Ok1$(1`hd@0?#n(qZUnC_ zx5CKt#^Ftn$NRrF*m9Q!_|5@eaQtJQjRC$Zz*lI60j+-P0{XoP{bC-13%yw|&t_w#_fk9_iO_sM%NATNS>u`7H35|H<$Pu`tAdE8rA zfwuEZ5#;gymJLkfkuQ90Orm7mWD$g6<7IOMQh-RF~cb3opQ-N?H>Ag{?M zZ@*98!y*q+I^E;YXK%oU>jigV}LJX z2A(}(EV04z{Vq`M9S@uL<>{A)aM*JH5s>%RJowKF0iQknTR`5iKS#SlBIQA}Coh6Q z!sbD=;~wQW|KN!PFAaSDcG~(l+Lg$A6uefy{sDQPKwcfG;K~+y4 zzlp^>Wg=j11Ab3C$VxM5OfL=aUAQfA502dA;W1tK7{~Bi@Vy*1=lpN0kl)<$+q>&Y z_%CGq_muE){Hq2ZvTtHuhC9B4?>d-M{hwtr5Ru&r?|^SsE}pX>=4~7-7geUq^r_<% zU4nbfSliiP<)K*b89UQ-J$mB!=a51lk=V%hjZ51ESd zva&MY|H+dk#p4sFPMI(z&afiww91+)rK}{{P^9g!W$ZgopSk9_P?6J$eKT|K{rc0d zz77>Q`H}TJYx{6kdHKM2RsV-oerWGQ?_|$HEE^!g-dojnY~)hf+Oo3s#5Jv@C$%); zU9^r;qj0HDb!YzO&UoAE_=e^UZS7kfyk?8{AmaHm;m+1%q_{VaPua`3FjV zXT-Z&hRQb*M%*?3L+1o@-e+#UmK3gvuiA1K<;T~ne4;bFSM~S;!)5*tuj*gr?k(eR z;Eduw1kODb`b^(%jPtZfXbXF9i)`R7SH=0Ikjs07oiC^y!U$hEUo41>qct~4S#*zz$$b8`nqhbuT8sg{lo`e zU&s6^f6pr7p7rB(t{d0)uX^a64^O9FOBOF)Ox(Noj_t&suiJ#0$*jtKpjS2X{Apd5 zc=ihIm2B}{^Ib;2(N$3`(;1$cKd`DypU0~#L-m|&D9jw zx{00fswq0pZLzzyQ-iAYnN?3dpsEJy(pRj?e!wZDT;^FJc7%qnSRY2ICeB#jxW1R@ z>lD590#mHU&bU`!=w9a+{-TFtqp;}w!S?Su+4s8I50UCfl`}l8fD+?X*#Y}*-TuhB zO-C48_imrHK5_2&&bRx{v+rfwGoC0DU)o+7uloEiM%Jy{W4a%+R2~n#6O(=$yGxzE zcdy=xz|;BL%Je$4Y%JxNjy{gBEH<^bZL+j^BW;}7BFaXtZfomoZtpVEvhc+&z8@uG z5q0 z{T6bX!NcDjyFg(`9(-fDKFurL+%4)bwG9I;#J6 zMn&9tC@jkLT6q3|@9C(N7OaHQWA2NHEQz=+sJkeg6UocroDzK*B}V$^vVliW#Z^zF zFt3s4FOg?#ZYR$_gJF@fymN3~8cB~u&g_H8)&a0~`M|FbnfEvR8}KqB#zx2g86I(q zXxfCqrI|=@RSt-W*(oq2;x0pSbke{{NQt@m&@FmMU*5>baQ{hjre(Z|EZJ@o)*sQs zd;Jsk9nI&tcdxJ(9|(1R)!Twbgrh3RZjFODC8cKLpsWD zX1mAc{Fdi?(r~___dcHA0zKW8@&0JWc`5ieUa~$ToW<(4pdjl$PC_+F`h{|L_AZ5hLAEjhYz9h+_gwgIW+TG6x-k3fu@i$ zMH7Q#e}ZdMrc$?%qhcLUJ7t=tLMnDSnq|siq_QI_b|YM!GM$vlgN2J|Rny=Xq1wPu z9Om4Mba(a8zaS#-H;larg+|YU|J{v)`Q7<}Pe9q|qcF_f8Rv)R2abd$(brHL?w&Z` z-WV8xd!plU=H6O31~A}wlrkwg?01afw=JUa-o+5>xV%`7=I1<#?h|oGvaSpITm~ZM zKFyTEY+eDxUA_wy9jR?Ca*slKbd)B>x>MMuMrS<&VP!FXE<9Sy^Uy^qb~2O3XzCIb zNZDitz&&(Q%|Am#f$ZEUQGPT?L=)fY04mhP*}1k4Dn;SiwZ__r|Kni4D*C z8*(}BvnVT8sGIp%cRspIY=kDtT;AA-jnu>>mtSs+jnc#vr))5)(XCX2XF=S6vyhaR zI{X5hyMKZUQww|Xdl`=V2?mMO5m~IGi2F8LWa>yw#N3teQ0gd6WVkbto;o^>H4$AWjr=5vAj4RYnXd)nSjkY z^m(lJR-BjU^9;BTo=+{2nTpCjs@ zY%408twha*KU37ZXk;<<7>12h^$3QSG&KSqOjiYn&rmzjz%tcrxG_sb&`f%%GlsxM zwGJ|StJjd4qgJDn<*Kh>Ri0{rgg#F6D4IAg{1vo|4o3e^ADw+G)JoY04KcFvo9=mc z;(Ta0W946gE_W5UE0JfzM;QwpmM&^)5nvUNGp;u-Uec80$iJl4fXWbjV)YBmA!RRiySe=X!%~2o2 zYNhUk9U-+D`NAsFpW3X_8uUheMU~6ZN%1R@F|`u^Q`LS*OH&o#$x!Q2o7t)!HP~C- z1nqOw1oY!v)rs>w#rG5YD1Oo{2!sR;@A^P-3`BtQddH9k-7qI9<8=PX0iGLJY&=- zNFJ;1Kpl-!r$L7@^#oGKs~F-ZsB%c2q^7}^L)2t6_bKWR@by&nB4kce<01brbv*J; zSKRYqhB^_J9PW;_sZ(IxT$P9RU#+&l!AGhM zC}p0S3UAb?S7GB(>U=b)1!^4{??N>d{B`P4a4u5U!}fX=L4_?-{KofkbvjBpT2(=x zW7Kz1U&pE#avi6pp^Y7{CLmXXQm}o6;x{lG)qL2#QhkN8R;eGuGfk=<{baTJ95UCa zc9gqT{S3CWs3>$^rv~Bwdi5GgX;uHm{|)LCXueSm0cV?CA@vQdK>@GP!}WDnd)v>y+bu)WH?KWg_q7& z90AW!?@Fx z!l5VsR{RU|pOf-F8(L%>PJ0z(9fx{R`qd-VqKB(aRAxwh33bBi4>*sg8aUonbto#T zhNJKl)dC4I6~%d~x`$(+8V1Lwt0#~vLv=veO!Xh+%2Jm?W-ql2{Mo7k3iejF<2(n~ zhiv#4fhSKL4VC+-O6b;C{R8glr{+Po{;CxG1JpH;Hc&l>iW;OE5IwEK7V?fzzW~ojbrbX%rCvg6k?N2Cqt!)l zYO(q$v>K!C1Ls(EA#@w3=D_w6bpTqGDt_*`Og)I|9k0%WoC)f1SUOSt8qIJL*LUa~ zQ&4r2)nZiFp^Bfqnxf7|uBqy2Xf;j!9ZZL*hY&wqJqD|1sNW;k;c7HWnW=sW&RJ@R z?k*p|-q~5p&?KGhX$PPR>Ia_Zm*IPz7`_ww4DH`*3)ckh3oy0U)@;tj&d3Usux%gC z_KbWVYMso}>z(M;i0*Z2xCQ(vT)vpGHM<~-OAJ*DsgAk_#Vb_<*MyuDF4Iiw=zVM! z*PQBqps!N5Lr_Q^0&615g`Z;Tw`kDW>TPHpSKmh+&Qfnf-R)T;;U`CB@!S4RDC>AA z3_eJWb)XK#D%&hD0gcr6`}P;4rTk!c28i4##Oe7r-XcblpXu z`~DHCjCPR+=kMTryqxnv>{L1b3g_i=o`+1;a-NFwIyoPP^JC0;Y8u4l&U+3qruftg z(F}7-I0~DHN$;Vz_bygZF0cO0X#I~3#7X%a|1z#Z4d-slp!R)GJv!aVSc6X1>&Dod z;26VLZAU7eG0Vm(D5N$>1I#ed=|& z-?d3j>c0`&ciD|LBFqa0C!+{--=j3|12)M?{S`V`Zu2i~gp_s&Dm1h1122|KnXvcI z$(V**{a#C@>g*3;{&P~^K>cPcMK8_m$i5zJD9$9h%E{oz!_z*|874DU8=Y}GlKP*K z!$ryx%Nzaxvcq5CpOgAmL}nh{$|UV7_G>5OLrCm(wRYn;|Z)^rgob z#Er%=h!-mPCTxdfAb8!^?4xN{_s|@_hR|9iUME`dYxeoMN9HW^~ z{0U+<%za#dsGWIR7D1(9Q#m}@m6w}bu;j{Zl3*oBkxaEvC`q3wtXUEJA=YO|Sy z)IwDjQgwO_6QK@l3#UO+NG(XcF?_Q#^44*;!m^P_VheIcU5J1Ev_D{pqjqOQEBK?I znoNIOiMY#fOj+5v(NP18@oZIhkMMc#`NIs0BLFH4nGyPhu6BKGpQ;0w-fetTQ9UL`=DW4+t zUpTboVU^2t+z7zThR76Nq0ivOq553QQDHQqF}j@3$1(fiY*p$@oz2PRci#V*TpqXn z=*JBI9Lt395Q~i;oowd&SZAvR$&LG*+z;S~_mZ=72N0e8J)M0$_}19$f7jV}g5>wY zoZRiGpEqsxIAYZ96u3`ke{%v8ZU*1=I0m!s-_~8>agaa55s4u~9cu5-C^4yNp(@NQ z;q+o_Xa3 z9FY}B<3zwq9BDxjc3I9APfFa0NLd&{*X`Ab6i!U!)Uj$R%|jQ|=0(sv96fMBBk))U zEJT}iGUG_(;1?;v2?x`-=2{3zPGl0|ILXW~acZLO)s#EIiA+Z#N7Mz9ILnDtAc`fe z@t5R8Y7xycPBzgjx7QNM?bVB#h4n8l^y#?5aY!EIiLfAt?MR`>u`9ji)D>1Mj2dDjz=kjTQ;n5_UWd??H=V3Jq&U+P8@hO4=k3x%-}Nx*N*qIYQ*PG`R`hcqpTeP? zcY$`^Cm{KoIqj*BAc2DQuuS#R5P@=&y8*-{x&c=}qYPIFwXA)ZhPcBdj{SyRgDWjO ziE9qq4ykH#`bwPUaN+(<9n!oY0$}8;N#`o`EU47D=qMVdy$u8+0?8IIOEWbK*pnfQv0= zy5UM{F_Cs8QeVBX3?60#^xfL6z9@v6d-}2xwZ1!W!uIk5zfx+v6S)Wp4g+43+* zx;mmte2CXA7Q4L$C;m1otv4y9*U)wsF?#Ke|~h-fawD$ zGfkHZYtjpy^z_5i!>};J$C*BAKy|KR&76yyb*CXumd-<4jc(|Plc-3(GOC68-9Hm77Yr!>lTPadGUFE7c#_Gml z38e<|L`E$h#mmO{^6zbR*IAD5+s_vNjr5V~d=o zq%khmO`_u>87j5yxEZRX8oEDYs47EKMax|s9e@GIZAvCulkBvmH40tPrw2HWBxXGh z(x+D7R%w#E621*l{7oG8rdKeT<>%_si_PU0Z_X%$VdS*@808TbNbIwMe1KunZQel8 zccxV_={Cgc?0zKmM>yf;o#x}IxXtod`r391053<7oM8kp>G&Ky_Rft=%t0BEEgAAB z=R&yL{HVO%{E%v40w)=URIkSyl>)jrO60#eC+g`<2t`XvfgrDG3mqLqorBp?3egF8 z^5V|H3U6wLTItQu%@(VfFfxXRR6KXlXArr9LrSeeGer)G{JZ#8Yms11-oyn?qjcyn zw5-?8S9ERMwt(Gu{l!NRE)l{d7K>~m(-AVzT)emmgA$+vU4mOi8bZ_ZpoY8^@ddeQ zv>s~JDsQb$qx3crZI_1>eRMt?p}aI%Z$bsis+jB8JKc2=EnO-f#WWom(z8&}tSc0< zU7@Z!tf^c9Qjshb$yU3`V&!xb9v4#z!9!}70zp!={S@Jk6DW5B6sJg&xXMH^w{p#NFx z7zuND=?wj?J(n3pqN5KFdQkDBybF=TG%b8MIVK1m6ueH*8G?$19uf=*IvkFKPP&}9 zd?a_^&l#kBtOA&Lv4berxJ=^xJ52HVd{Ak)&cF&y6zlVl2?}Y#dxW!z&C#(TD*?Nk zwzUf-depnADVD;4lJKXF{1C8JR^Gj}y=PlT=aHTgE-Nd?|MuSgPOH4DcS~n^ThF#~ zyee($#_mn!OL~!U6`l?*-_+B)p{=KRu(u!YIxQdQ#v{>#17&^vy#pv6EFZQG9Ww*D=pTYI;5mUgyn=yqk<($?O^x3m4vl{l~y?~8NGKf)8! z5nWIxTe=6@hsmQ=bu3oH3V=N zLUnG(!?&OeKh{%=gAmjasS)B{8<9X7QJ8qJzcaQneZAC$$*Wrl6nuP&$2I{4cLkK# z9%w9LO*yV)Zpr4I`Gy}R7R!eij7J~$D4#FOr~Dbdk%c~=zuXtJ*B~fcsjMuo$Cu}~ zKl?$2d+O=-4^>$RDeUnI;Un#fKgeWA0PvUlk;ZQyQp$gdPnG+8CzWA*ixhLfLaHqC zL{VwJgmFGqz;mL%Jj;jmO_}BKsu0M9idUNSpMp!`*O4l%alKac;_6Q+n40Gw?TMj_uI*3co0f6@?~X}XVv=>kbi{9>hrAwXXVQx zxdz+|b0cnqj5tD0WsODOWGF+3;w3w^nM6$+L4 za>$+4b-0f)+!M2W$>50a3g1$u@o&VBOHl9vUn0OR^Ix-U(=wlLxfTM-^NnQkg+}_Z zx(MI2dSAMT<&6>RP7#aMRbxWFgbHTxvr(tHIy8dB)RqYf%Z-{?2{t*(%+uwSLqwHR z=7}xpFB8lil`039i}#;wX!2>Z4x<$@WAQ_ zYS!*4t5~*)s&cI32sJBrYgX>dH#N&QHN#K-A(7ivex=2O*crZ@LZ5G;FGp8snXX7& z{SWB0V((cY4{r2Dar)y?W8Xe%?2zuTN8)@*q&o)+eX7)la{~2J=JWf<_~!F6nOBb zHLaEPbxRvsYZ|I8gw(9AX=rJ!YgmoY>dKay*2<=uN(*zq+}1(HH@B>+39D|ZJhgRsWnDvSRn5}6h6tDXx`vw8>dNNY)}@szini-NSjI{B(xyp;Ov&Pef1HQ}b#rka(jYMQkWrUb2BBlVKnx_U@a zTiLL*rrLsAIH+?Q)z{Y4Ev;>d=GIURm7|ra*E;jgmfr21t%JRIDR2k84!6~+mYQa0 zZfRV>P}A^@t6Ex{$g_2MU9|<5)%pAlUm1DH#RJ7UC~t2+>Clf#A<9}4Nk4AZmDGr#8EJY&^EAhYm|L8HMUeXt&MOL zRiXAR(JU$7lE(T~%cHE#G_4LaHMihB_jKSle2&^W&|ZU`t)|G<)@@?-XJMwN6Xzsz z+c(;9nkuX7RyA7#?fsG(%HJNTjb(Nt*A$Qgmp_(WkYkgv1xg0#55YKP65ZtrLE0Nni}itE34{t2F)W}k5Y|tT2F04 z$8+1O62D@MtR<>@+qcnr2g+C1tZ~*ot`1=Kbi$0$TRpv7H-(_CIH~Gd>KYrUlir>l zI7t20rvBb-eRMRP-p-!Uij@xDMBNe7-L=&l1-q50tX|z(Ti4RUegmQ1a8pU>x1|=t z6-_W=Mdk-v#s`cFX18^IsO7dul`%xN2)i>K)95Bf_o-W6xwNLWrLI2O*p^o|VOWdw z2kFF(^^HxfY?sOww=YNJ($*bOmly+@rLhS;o{o8Yv^sUmp{18BYc2PEc%i{Hix*Mu>E;6?Ll{TUysd%8!rI z4@7jQjm;G&VnyOjM08}Dt*ORX zwkv^HL`yBFS>qOnzRVyTX`Ch6qgYZ~vt(I>YgJ`4JO`MXWYSY_BpL>*eGB&F_O`yZ z_U^%*5svkhX8ag-G=x^*yfoKfvS(kKHamI*XjrwpwQ5yeJsl*>V~s1CBU~{swd#>c zMAD9d*^gkN$Xr`r6E;&VKKIjc#x@{bq;i`y;+w@;Xr!&z$~5YV>eh_5 zFSGcd#jjFO7`=FQesk-V6X^+@+Vy;4dQczpn30gqUffh*I&RgfD$Z<1f0iDwBihit zx}~ytS!-pr)<@e;sFyn!6Z4sZ40r%s=^w!Sat)(0Lrp+de&v*=$Vmomm=8X;n z40dhXvH{rE-`=$l8;;xOl(tRT(l-U4vX~N;aZ{+YaUfKRjiH5`wr-ogBUHL^8s zgLv0LseJVU(Hr>@$7p)n*0bP^mg3`>J@_<)+x+ZATx~=`T58s`v})_qevo6v#%{HP z5jSW%E0-uYiL)Lvx}IbkzTFw2*)?UrbZwV&TvcOBOXKoLZ*yA$>!Ze|npQLGMH&GE zDBMZftUJL+Du%hx@UyVzIM}6~p6J$vj4=0xrDW$86g^S4auLOzBs)vdwx>HGhtBHe zC3JZzqZ~zy4&qZ9jkqHrSed1Uo>1EQ0WpPhpw<4u>bmAS-LE((XvLY{B46p#ZnNW_ zM8-AI9v2a)l4+#+n#$ER#yfPUX}XCr;tgzV>ucQ+L+NokULVUFmt$4BYB?FpWJN29 zsis*OV9IZ3hTFNiu4S#&+0m`-%`#44B)7J@C5;Vnex#mc4)>L*XFAI6)Zj{?RVzN* z@x4LB&8k;W(TgRn3Tv=R)%O9mws*P%iK#Htb9{~H)+~LhYwBxc>0?x`SC`a|9{;rS zgNE0h2+Usl>=^dA~MY^hH3f3!nW4Kt5x<=fNn=0rM>>$np zTCYN)mm(3idTNsXDC%hI=zu!fv>#{^iUr52d3E#JhA5viGX06e%sm2EA2HsJW1p^K zWjzcRLQh)}?NSu8+?BUYfMLWtq5U~tiCdDhdJKo*#6^2-u@QP)a0QUzrG_3*-4ZJ@ zsYG?EYPf3JufpzoYY$Z011(2Hb>5O8mH?k{u)l44Xa7K~N8Pvz0|<=4%u=q@m2hu$ zqeriwC{3(e6=`MeyO@E`t%PQ(&2wOLH~a#8#z;>nZUPJeSch=aNzeYeTj(}&I*8sd zX~sr^Hp{5G$2qB{Z&`9XBhvFUZ?rq4)*D(eLmO0OJRSYru>ST)T{!HvZ|mnvgIWj8 z@QcL8#W7#~jaIY_wp;MhB(l(pH-1b?JSgqGL9fPgmtc5|-g1K@2uD65@#@O@RcH>` zQF5CDZ3I;-iyBMQ`;2CbOZ!i`I?se$xHb!I#5)JnLzuKG+&l|^cOua=vI;XQep8niq>BN@3*M|)kQMX^*aXIVI&*c^u{6QdROA++Qud2{ma9*OQh~jsWhMX(LY>SkEN8`8i#NFIa?}6SRh8SE~#w5wk&B=XUr{?tLmdV zux#F#F5HTZ5ogERq<8hB_hKV6MNHpy1r>8%)gWsrw{4tl4rdEhv}iVtn(NS!oOOSc z!y0KN)A+QO=*6WoE@4~P?N-9Lu4OqKkL6s&$kxYjYHn#-6{Y2T4ggy5Ufe zqbXdw5#h#$7H6a*3+<|4m2#F7s5KhNq@B3RhA7WhMw(`rS!LAza%73wyrdGHIDUIW z@12^cwb=j0edb6Z;_{;+t~fE%p=>XjX*=Q_xnmrJT!QUxrwW5noNF4EV!srXA-UZ?m-MO(zN|}e;sZR#Et~qp_UEg zNVAz$lGJM}Kk^58-FZR}t7eXHyk;?5*$i~&)94Xi?`~Jsw492)3QFW|6o7T4uX1P} z=)(Hd*;aN-)x2P>4K}#mSB7U-BCZZO zg6RGmX&<^XZXJyX&6v}oCW`jn-u@0f9~u61Lp5yZMfY(Y6@qkHS9!j*xhy=JCU9GaTiQ(b3_e;%g}YAS|=_> z59F=`(AI%nv6%5~6CRP#gSU}D?gcn)=k8QThBapaEgd>$%H@D{*qs)4dqZo7T8=O? zV`TJ#NEBh5*0@{D&L*AdrQ7ffUMqK|B4*)?4Q4CAw1%t$O=piRFpZaKp2X4)hGRrV z0H@EQLXPsI=Ud~|ncI(%T^n(*ctfN9iB8Z+xeGQuIlo*iP37|oc>bRx5HSA*MgaAP>g;}y9} zmdp>8RQ7KPai6lqd8pCsRyK9^ObeA%ZNoj-5T9?v7UuMslP1M)W$GWtS=QQ1xF=;DPAqcs|uynHs#%z6dF*QbV5irv{_r`Lt_Q zYVL*pi+mS*FR?F0s+jMm@hR9U@b_M1UmPD-Y|6gCYq-bc8!~ZjzHHFW5yC}fYJf89 zx;f!qT=2ISW<1JFfYO<>41GTY7bcok_{k`Z| zn~x+$9X21fi#lvRh!}O)covbr6Jsv6zXvpblN&jxxyWIgr=;Bg8&CU{x)d+;qrq;7 zt>1p^k|;eXj(?KQ|Ad<)$$c+0eq0Z^>f9J!*fFh2Iwh`r{i`=Ok8P#Jm6xW|U*V>} zj{~C)JLV1htVzAEOT2DvYAYzbKA>QCxg+ z96dg+yzx4Jq?Y6LyS8bM>|-8lQC$9sadb&s`6Y4jljF*Z)t+rliAz5D zWpVN4adbr-Klc8}VO!JV_)U*Q;>xyW#L+Y3`0=M9k;ArT$MKsTiNuxdejU>U+xTK| zZ2z4bmwtX6KMrJ(!*;(?X~Jx4VI04Ok;J&N(Vnp_5Z}I)arrCb@>j*hSH;Cw$MLU@ zix0=qOXK)0jf;;Te@=;uUlx~tSzP?`xcKF9@r`lujdAfS(sdTQ{(cljiXPCqfd{c-ycV>kE1ul(H(L0#yGk&j_!iQks}?KnHH=A*C1#eX-BekqRreH`s2GdU=ac@vNcAU!cIenA{vA4ji`qqhpp zku(Ee@4O_2KGphI4Bc#f4m5-4k7Z*1dtBl{YW;jCj(#DIJ{U*)qg)8qhuG-kM zUt;pFw6eqnGW;4Xz9*RcLOT6;_j})7O;5JkB;L?v7T>tZ^oE{pT@gdiwmuQVZ@#q~ zv~y5jd*kRI#L+Lt(SM1fvruqE-fC+S1(AdN7sk<%eW9}UqdzKGJZKenxKHMm&2Um5 z=`munG~>2HXA+N#~*R`V=FYkOZGe$7%5k=1#)1&g)F!z3Vv zy?4VzvPTh<#CaTw7Wg&1acEV@9;^Ym`wo*Yd22=f|A8$+}*uM zgxPzIqRnQH>KKo~cA0gifQ--~cPm zU&7Nc*VG|#aj4J+v0UlN*ZY+96Xrgr8j?HIQ52yd+*UX1+?BI>8>iF&LieFq%Sk|_FN7E$K))7ET5tzU4Xa45FrQmE?halSIcpw==;N#wV3f& znRhFC@LrO7(4MPt!ZDeZ-~qm@D&j84I{XN&=Elk9Z;)G-Jc!QMFi_4@dq#e-ixu88$ zjGP`>f=#9pcpyEG$ukVPG=<~g#5+qBhi2pP0384%-6G}PYRVf!Bg8S;Su!A<2XxYH zqDQ1lA`Q$0j=32p9FwVh9-lDvnA~s#{<5g0pWp^Twm-wS3BtrReW~E}f>5ar zzgzGj!LJE^Pw-j6*93nr_?{r&@Xhl0-815N!RdmF1nHwQey!j}!2!Wtf>#ONDtNEp zBZA)&{E^_V1nF~=|6c?HFeK8W1jh^V{q+oABv>!FR&b->fZ&kem4Y`5-Yxhg!EXxk zo%rPc6Tw#ne<%31AYTEr^U`TMP;9S8P!6w00!5+b#f)@*3E66wJv7FBd zens%Rg3k%QEcl*a5CaACjS`$7I8(4vaJk?*!A*jLg1ZFo7koo7h&hk^`GzhcUJIph zj9{@K=SId?2+kHE7%~|BDhX)z2HW{9>IRW9fBVeyio8m!D|F>72GZOb;0io z{zlNogh09Zwr^rcaDw1e!RdnhHaXKR66CkBN%N)T#16qT1p5TH3-a67On1KEhXnae zXNG@G@HxR31z#5Ao7kD|kAjB;|0>A$S};CIFkO&uv|xC?V3A;nV42`d!TExV1;c{% zf=z;J1o{0L^6wBlL$FV9yWly3=L=pc_+i281aA`jgy5Zm_X+Z=2Q2Sl!LJHFA^07^ zeS$w0;o* ztzd&7za`E1b%N^!HwyL$_6zP1{Gi~4f|m*M8`0!_>ADs1b-#?8^MEue-`|UpeNDD6%b4n%ofZO3<*vUoGLh7aIWCVg4Kej2(A!Z zEqJ=%2Ei`Dt%8GsXA2GqUMzT};G=?H6a1Fo_XK|^_^cp5-o$qJwcr84*9G4a{BJ=U zjuq1<3Z@B;5F9O7C^%7&U-4kR8G`c!7YWt~E)!fSc&gz01lt9>1$zaz34TCum*6FW zR|;M$c%$HLf}a+=SMUMBFA07{@Nq$Yq>Arh1(|-9;7Nj&f=dPY=`5ye5q!U3zu@_XLwtOnpZPh6MYFyRgn8UXJ&76VJyw zn|K|TC`7Ek?jv4}`Gh!x_qh_cSQfvGMEtoR7mlQJ1g8q}TUrd?Ah<*D!-Ag@{IcLa z!GnUyX(oT6;2c4IBb|J=2wos~o#0mmpBDU$pfBCz8!b3hut{)>;MsyhMEFEE5WDfZ zZoyAV{Cz_27Ub7sDA!)0pAh`Egg-6xGlIV$g8$3J&6f3N34cfMJqhRc%vgRn-apBKX}W_!Ysg34W7^^!tVW zk>GPg#*-J!thBE zEEGIhaHZe|;zup3OXzb1KSM;lcN0UF^=%^L`<~zrB>tyDzbN=?3IBu8ZwMZeaJ=?N z^T8XCH6|0mKU=U&uu8C*2sutCVl!kLk$MvRpu}G)^c8~FNchb{-zIp!;O7OuL`p4nO0{a(*uOD+xa&$PZ{S-E_e^BKG|ngg;;DF9xrDD0Tqp4zLU##n zA)>tPf|n36Z(b?%9mHhlmk7R(3C)kP>V0a#9}~gn=YsDDhS0VQpGL&|y-?_8BKU3~ zf^Uz|+XaUNFD4@YRf2a3J}&q)5q`jnLcb>X7s0I2h{u|`mP2)<0j z_*v*Nc(UM5LA_6h_)n4!;X^TkdS4FoAB5(s?%BU52`(2rQ;^^LWc=+!^soOCd`oZ& z_pi`y?-%@#Aio92@Xr&`e%}{7NQ9n8_za@yEzc&iA5Q-P-Aw0$h`PKIBFe8IA`q(4 z^x# zPZzQL8X^*dl`bEwboshml+XJyEWd+@^3Nbfm9OmunXaZDQ2tv)l=o{~vpl_Th4Nm3 zVpyKuM?!gzCV-xba3bpKC*CS75$>DnL>kw zF26-+T@T1HDD(~@-O+4R$$K`u=m7e(t(# z1Ad2C){i$tGO$c;mk$5Fqq54T(P@t% zYHZSDN*bFyt{+CsHR{m`-KXRF-|z{K%1xfRI5syY;ZeCc4{IEootyHg{LEt>$L1E5 zF3!ZXVvo{R5`WYNib|uoJHyv-uZWEAFh@;0OsU6AKV1FfiIe!UBj#Yt%RH-cbZy3_ zG#$oy;UpewE9*Bw(POp*MM{f%d`lO2SfZFgNFE;=K4nZVKAx23k(=R}iQOHQjfi$s zHhc$y89F;UH*DL4A4hKNwaUzO+lCGOo!g^h@p4kWLLw$d8{QbP3GcPha+-|&TQ?n+ z3~yfVbQnYH7T)H*h3`X*&bP6jzlqh&&li4n<3TVmKK=ts0t;@1McYfbBNuS5^siwS3%z)w@$0ah(a*EMrPSp$1If?H zw+`3Q2jh5Lh(BESov$hLEDhx)A07@4;W`n2i}A-}4a!XivfKpxIpscpYx16sKOP(f`}#5n%_S&&9feZY1 z>&tYkFM08B%1uFdbh&dkMe57-gHzvihM#LMPl3Kpb22A~AJ=%%{A$6EdSN}Vo$T^k zA^ef-o?z%PUt)&ol;w;p_EhWwm-eC8$k zaO%OeIj-G$FdgL~FCI=kK7{b-dMu8rM}eecz84KYw;l&U4%lK>MjuW+{0NV(2h%Y>dGT<{^&mXD9uK3?bi`ACMUsyBrW=0lxUmDY z!voP;CYF7MvNeG=t{kcQ=A$?Dd3m+(Wi^>GX6=!0eQ;Pdym zcH52VC^vcWaLT<8;nC&38dcvCNymJ@HvHUn`xI!02l+YjJTK`S`YzDXha;aCnWN=n zI+in861%){5iQ@LDET{M{5XyRtoitJ_>~GjC*PY#sK-i^&eb#1Q6BQ* z;nZV!T)8Wv>VYjIx7<%kxsDzD1^jX}Cv$S-IWvymdhiP&3G2cAJ*OTY6Mjy9XpcgX`$8MDC^vk87nU49|jN;dbc!!@SA-2AJwsSasd=@bg z`4;1k$H6FmD?vN_#>esFv!BE9D@3|ze%!ov+LvnyhhJSBKRz2e9KV`4e(6#CRz>ma ziQ~u5Sr5mrD~?|%iXU!Kx$^N@N7{>XJOzH^abL$doVW|)_*H=4?rbw2tVLp{zI;~F z$wMBm7vfvUjFiKPzbx7su}h;CBwW-@oRwd zkW2%T!{PTr9KXf8BI}+FNbB(Xo$%uv&tvT@yy_yvD|3(^{|?2a`!b9vENKW%I^HAU zwR@~KYbJ+gxjYooMce)EUFQA;^|uj!j(mI;6;n$e^YGXKqdUo5>a$Z8(HW~4@gUMI zPBQm`&IC<<>{l!k{M_TsHr)SoghHspk7H+ax~tEJ-waut!%0^@bH=P0p~x|9&dixJ zDyGeuH7^vJR#8zAb)G$QCaBr7W}DROlg`6S`OQc73|D29xaBkCkP!f%T;fpz`O~!T z?z5DZSj$lGCB(g~Q$Pb=A73hL;VZq)$9ef-UQgu1yym8qP99Zj&>XC7bF1xmJ_m>& zx$VG@47c=Q^1!xRgv8HODc67K>$r#e@?oTIc0)eDpzkN6Lvufc&s@|0ByvsfK_Vp4_j~{5`;^DC zpX%`giS#axQSjH(csH)(O0j!->Px6ElYMcS0oybN1;tz_6_r z;Lpi}OKTneSU2Zz;u;X(Tr+MP{^+wihZA=S0yvH@mWcHzm*ucrOjGXM;q2{7GV4lQ z(C2dwhhH}Wcg0H)M1Gv3vmf7A;e^-$qNDe$t#~hj4(-N= zM9s_?dE+jp>X=sm4mbNaTsij)&r~yv;S(t$CfFtPH*54sr=%Rmn#trdI{H1NE+1x$ z{^XG6CNFW0yt4E^)D<`}ce4jM$KN}54{x%^KZh4W0M6;0SBT|;vjw>)#qerDy0N6$ zcZur-HwkVP_CgPfNDW(p6n6-xx04LpWJ_5&Y=Wx=+`v~0U;t0*T zn*PC&e1!WEH=NJWfN+O5F0H5WcRW4<_pewlmU}cG;kSrijX&pb%IZb{uN@zu3dCJb zq{NYo_Yr=BIsJHigbFD9czgu@)_O0>!HjlPA7Lu$OF!5-98u$aglCX$cpqUV7q9Md zY##yNQqsq<*R|XW!*OIE;rECwD8=boro#ar;VBJ)vj`sFuQVh)Lh$-7(~v-~BH|;g z2X&Z_@C=ivz(pE7UjY1rJ_7wo+p5Fa^Edkl=0!Vyi-U0ZRDUd&VVE*bcnAN4?{@v~ z^A2FiG-o;f8Sj>LcoF|qYx`mBQ;*Zfv%W8cT%5yC_y*A}6}i^qAxQc-JdQM%Q;)Qr zW6k;hYTsZn=AwUxZ}23_Jzn2{_hg*I>2LAA0pC0GX(tkidC9+c-{4or=^IQwPTzp* z{kWf`r_i#jw_YLSX9l{ z|DYNnhwUGn%0O?NZ$RJTFyBD-54dtr>fgP8u(@;RhF*M*@^9KdINUw>7tHm?@;HW< z{KWpj-}lb{|Lc4I!&}pd{e#%&u>b$K$8ci*;BX(|KY0IO*!$u~_7VQs`v;u(58po! zAK_P=)rxy@D$JsxJCva>>qpwm$)mydxF?M_@#z~FA=;xZb%*9{=tu#QUxy1;CTS>58hi? z4i2`p6z9MF-U44j|1a?jj^zd%R(7XP?QdIwhwln@C*KR_Z1E^L-Zo< z@t(M^;QV&`|Bhe4-wpgb?khZja*y}E!b;etb2$6)@%I%LBH|7w5{Y@qzxewKFCOQ8 zg$c)bU!mhT?<*9ez9XDUh-@U|?<+iobi?0Qm{l?DZ}SWOdCwgD0fK73;5v$o1Af8x zGz4}KJicFRNcb|r>$_aT@!VHVhx@L0so+1umT)x{WXri-7o0x?did%fB!A6 z!Ej}t@D6&nMtcMQY2HE9aD->M{_*eGvUfPgzv`KT;q35)ZxH=nm;XDy!GFS@L5tHN zfKGpl_YD>!g72$z4qoyv-ZyypIDLbu$LSmVEzcYb_ncjT!>g1doraecVsbbG+Ag{LdVG+HjHk2}7X%LEqpXc^)zH)kpk{;kbUV z@IUgv!9Vcmz_B(fhNWSYoR?MC@)B3;uJmT=iapK;>iRTfGe?ULsf5JyN@q0!n8b|#8!I6H?h;iL) z`<1nq^_EBdW&t-GhI>!X+&S~aNjUa12l%F)Bx`*=Z-o1M$;h}X! zpx?81zweOuU54Vg&@*HeI;os=rx)q4=#)rz@F8FLqTQ)s6W93WP@y+m5+=ula7d#! zJXdHF{?e%Xy6po$9Iy_wCzufHz`nkO13&5a9$0U8BljH#HrNB}PpW=nJ^5HS&sgud z`3viPyAOWFh`0M*@6e%#yy2@4EvT>$+P0c9YyU-?_nt8+yd}UKHB0)LRdia|cjNb7Q=X=<|1Rr#axpPhp&zZ} zKk(!2412umg7BBS=Y|`9voVSK^c-mS+yT4aX#Y5m@y{O$rdQ_SGdnNrwn_WLw|85G zp_@bDk5nhz^nBM3^7@xBU($iwXIB*6d7$0TRGCE=pxv`YmaL-lqp0@oo2ruzB-`J6 zEq(S&-P!kz&btFt=CuhoD2_SQr9RxCNF>??sEeKpOx5Pvt|?;`w}{+SL9j=j28 z*ZMk%S;O^#wfl23(Khc@LfbpM;nZ+V*qZpnBb8y$72kW!Q%%Vxg@-iFYtOx&uyyUu zswJ>ibsa;zY?EDEF@hLfd9I#Y-2*D&^M>A1gkDkTadcejx%%NfYP>4JITU!;_ou+S z)*GR4X=dYZ#+7J(;je1RAlrTRP~Srr@AhfAz2R3MpiLM{IIW1+jwSiRUg2+z>pi%> z3T-$}K~C>oQ^M0t?i>8O`DDj0y?Kkp{F7=1=<=Q8G(#U1{ z%#^O;ygRDy+cRbT)b+j>t7{822UYU(eN(833#OGO>}PtbP}56ry{Dk`AULYeG292s z&DNId50B8cKH?syzl*iKp6lHeW;K0A3xh0`ChYblFY>nRjYmsa51bJx&tJEdmACmsnP->^7ls&aRSpbb#VyX}$MWfv6H*4ZJ?wM&;N{8{*;e1Cm~=l(GXVQbtIuLWnkwBe;QG7qV% z)C`WVS^Hnwa2@8PPe0Q6hO(z&-n$SKbBxfAtho&XT#dPOlhI28~xtPU#a~}$ZuYsnl@uBe7UQ1pz4s-hQ_FV``rx$|pwed~s zOkNd+ecDcVJsEnj>%Q{pTs`kPjVgC>W-nFfy#BjNHF#v#ITc zRlacg4^+59`w7XTyO!Ma`O%-ZraZMLD|}kj7Y?jSOL=B|cxrBS&Af2Qp1|wx&8!H2 z^R-|#+OQJk@A+ia6?;lYb&md>86$V!r{}MWcHdo_D!qNyelr?4BSfgw8y^46sxPR8 zV@oGK^Yd3n9IV0nJkG-YT=c(ax<;L$LTbK>j{hL2i*(3EYIuRR20y0hwHQ#|!7 zLp^t!vnj*A*_yIpQj{s z|G3TGlJ@o_8Cm^04zi1 zBlMdWx7}KG*B<-z_hyxTe$tDJHD9}A@4j)Hr-#R(T#p_>D_>b0o~GmO>7Ew0Z!QV{ z{Lp>7zZ||f?~HEyTF=cl=cyu-a!7ovh2dRc^|5_53HzbWVxAB`M-56>SbY zu%Z1=FSl>LscO-if4pB6j%)Y5GH!Ew`+=ADy%rqzhRmLLH~&QkRsy%P+yT5a@DoTDayTr3EqvX6dpS-_tvo&ean@{L)HP6W3 z+5YIuhSS5s>FL*!v(&uY>Rr&I3K#z77iV4$iSEAtCq{O6M63u$ERFK){+t*6>5WSI z8^&iJ5*<|(Vf2+Y_hHW4qFZZjwf|jfC0c|Wb^jz6`Ugsn1?dlYH=DIW03*QOGpH}D z5p=5sfzFJ>`DU=IGqhpb#*Ll*p|jcsLW8}%p@A)JJw4?2)xj?b+-@YD&`NM<^WS#`Md?j+jE4`>Z^_TT~F&W=`Yn?#}p5G9kUWv1Lx{reUn zjD$x&FE-D=AC@QuA@9BS-lFq?K5SCFf``bQck-<~2Qy85y$P@5 zOo|C(g(H`F)<{;=- z44O9zuf{`A!dIB1xD-LlbFW~K*SDz%L1heT9Ce!xN@yOBn1Ju~>3Er!dDUO@XA$F1 z&WGgLnJ4l3nJirAX7NUg|7vjcg|gQ1`YJrV;49AF!s}oAaXmF_2-i8UF<@OW0xGik z+rSpD|6#E3|9B+t-{c3pzeQZSVl@(Gr_Ms9RK`3I>ct>Vmj5(7J&`cq9*qe9{Znwg zHm?cSIotp!_*e-(;T@Q^2x;tn<6s8U^GA$9X8Ry?7nqU0F&)*j@5U37fth)EhzZzi zt-!3Du^@tWG0G0i5Aw~E>Go~d*a)1QRtUvq+lwJXU{ThWQNv>U)DVcp=`5xscmpaL zs7!r^~pHB%Gf44zE|D5()3m_y(`fL!&0FH`gyR z&4$nrq|WKZsh|xSElwOe4Hd9gqDd1&qOCsUN-PS_ggjn*5v(t9oF)SHAHXAVLa@%& zR^lwt){~4(wso#uk75$%Y9c>)QwYSoR0`^`RFL1XO`LB?j|!ek zDNfR4x>p6uP?N+3npD}S@%BX2pd-Hu0_RZbNoUXs@^TQmaZEDBUYuNaQoy!5cRrsz4j)kBdKv@3nb09ZyE(+t&YjH&zuY5 z{hBDTKRFG=#+-{r!kN=1mDH7a8Hfe;3*evBt%=3u3N zJt5(Y(0df^TM(lqdF+S1kcRn_Lz=T?e*ij6E*iBHoW1t$$si_b0Rr|@u-xRSBHE{+ zo#b*6Z3+xLdA26zYWqxHnE4C(_r3Yh^$2l=8xEpAj`fAQUu55&P8K+by>l}oLdkRu+K!5gGD2> zE#zK;&K4Z6*{c<~p90I^1VgRNZA51ePBc_g?p}x(EHPAb?nJa_aFU@~?6W3;nxbtW zXwO0|gHw%t*ge@G%5=rDwVH$Fn#i^9rFl-z=AGVrdmIMT;H=C+w0g+?5`uzrHSc13 zG+I4)k|xI6zoY0UYhr@^F1mTJQWF#H0Gcys`fQ1P0XlHd^vTKgG8k0w6m8j4?f-^4 zf*TWdpzI3!+ZdmNn-lIDi%-VdznB4HiynL)v@@Ilb2oIWluYD6bd$2#lk0yG?^6!Ay30w1LqbVl+4)yV;L-d5c{G|+-0`~re>;!|O z--m#ldYlR}Vc%;~&bcQ6AH>++)^DYptCfRs5zUhF!Q3ZMwAa3K0*Ld*{2D~Sz6CW% z*_AsHWd`jn7)n#l&rb%CZvPlXq+F2K3?kd!g8?Ds!u%N^a<$%5F4C;??VrFpQZ62O z8@Pq+IZ#B(C0aSf_MPKFT&jr@`%CDPDIXHGWnn}~xl9uk_Sr1-a!t&%Kg2?>(2YIU z&P1J3uGGW=JBt#0SQCrw=g~YVS81Z!UI;5o`AEX2AzQ7TjJ})lQ5~})n3e+KdflYz z6Q1A)rh@#KAwTH}o`jZ6xxtXPdxHE#Ps)vkyu)Mp&w(-%wvT=k%FLlg3+_NG7N@S; zi2Dro2T`5W(}N38Ys>xwdQoa?_ByTIk3-d|8-l%ByB`jL=+t!!+WiwjY}7=0?oxEh z)J?iH&nI#xl3kaGVqXHWQ_l!K0^TF+GPHW?W=-T|bqusysarCC2)oU-r<29jkpYyH zuiGTGSGP$BmH~bVH%#b!z$87_RRsGn>;@)l!gI9> z{;U|}6hnSQ1#iay8JKFw>s0Ve~o*9-1mWqzz}P{bCk~LQPcIr=q{47inUqJs-T%$7y12kV9X3 zan2!B$@8KLUV|>3K3>Nuyrg!b+E^ zv0dbx0h#hM*L;zjXTs1k*N*&_=KMT5RpvU$&oVPl(`BaHU6VkZu1zT0u1A@f?<;-@ zd2+2$fvmBKY`&}=R#r$i7tJTDP+xj2|049gtRkDG1p#n}$Du`Xmf(7n zJz_)R5H9Qsp~(^Lx(8Wy5_pX0Fx@Guzq7*{(P?^`<}XCju=X%3!s)` zB(~HR=v}F|k;tR6FaZ12L`-}MYCg^ZwH)U}wI1gr6+*X5RTq>)P09;lv(yDhpRIO= zP=H#9=1x;zM_Z*U#kN$hpi?KScW@4>6y!}&{ANr@U5R2t>UNw9)y?SZMXDA<*f{la z2}T>W0At2@bq?w?LFFNQqAEv+#2FH1sD~=R-|`QkUyk^?eFYT~%vqDjhR$7$$tGv5 zF&b-r`$j9rG5_8(@^(ZOu3{I;8r6@h{4OAm=2zB>=1Tu{*EqW7ilRgH8Kr6NP$;z zGTKj_nA!l9s9EUlmO2Ssm1@S>qc-F0RcE861L|s+SE6czHj~s^7`IjPB z>TEj+ENWA$eIEdxybi^u)@ZkQ5w=&Y)Nl^ROKVha>byh_mi8PdKJ_FYuPu8m#*Wkl zX6&&0q1M!en(*7%sB-Gbnh4m-QEcj>l>Nw(WH*yotcjrg4KzquicWi;9^8iM$lctFPWcVP2lB z04*jk3a44D3%yyBMEkV?jvrW#;PZE!b|M_CKr86LN$B!M-6_qf*CIqc3FETV<7GHm z{;^YGjjQdQi12qnl$5nu_cGgVoMyd-gnMw|<;e=H0W1F=PMmG&`hwbS;zT5 zz~Z)Maf}I68h=1JLUw<7cE`Lw!}tCRPDIC*vY6a>SEMOsYPfnxI`a7TjssbzBQ7z zJypS%Q$I&iOZ^%)t<)Set4G~5o0>?3XAn>i!rIc*Xh?v;YC9|}Z?paF2#>zhMdUGs zom7>=lraEfsPm`-$Z4xPA%Rz|L4|#m--in1on@yWgGhT$>SpHtq_*hiQ5mJajzt2b z{qiKF9kQ1pdXz8kqQtv!VP`^#c^9X1&VU2Z*JkBil71?NUE4m%hnP##zkvwMXuXg; z??d)k%pAzGS+T=?48wWeefEP0uFZQOaUr4>ZQZuT%KN;Y1Q+#TcPj4-+RHmx%ln{_ z*FO>NQr<&$IxDit9~>YXW^nEX&#x_TSpXQ)4+{WH}s(P~+0Jz6tcmBS|(q27<8a@6%m znXAr(>pek&Nyim1|FyIucQ_)J} z)o+k;g8Cv#nW%n(a!b?;Xz5An1@xiG>Iu|niuwigHC4TZkW%#xv`dBhDN329PQ&$d z^)YB;rur;uH%o0to6J@F!GE6m42FgIDyJMT_*P#>>;iQs6uwYhf%=}TW<&nPsuAZ( z^&6B@rGAHASFJvebB#)b-ool@&|9q<4>{{p0`zl=`U^sqsqdpM_3Fo{^>Xz%tbK*L z2G=Xq%dqJtRRaTWR&PV*7Iguva*f)Aa@VTe(A7GXh@O6$+KYxfT|EKG->3cnQ+&Ug zjK0&V-UXla>TR@Un+ihy4XPaFwyXcbxkEjV?!HmIgTZx^;s-yv)GD+{w_1l0=nU11 z^JZ1-$9FK)yXf0n)Jlv`Th*^o$6m!RqxPv^K!!8byEyl&C!ps6#i4spDb)I0l>^Qn zRNqC&dFnBgKBOuj;V$(Kw0gec{>26AQsli*y?~azNKM4ld9ivJHM&I2Mtv_;O_1|L z>U|;0x=hug6)sl;FwZMgI%2O>d(istsby%#_u$(@&~z^}Z;dWW{VHTvKBxd57+5H^ z8>~HQBcg3}E7a{(6=3I6nMmVTJy3drdJ0AvP=7{KC93;zorIgM^bPhxi9z)OIHag7 zh@PrG6664M6U-%D-Gqu|sP81xxXU4Emg2X9vlYL9I6|#NSvl%_RC}a)AB-kfy@|3$ zsk>mNc`6IJMyoHNO8IIX$}LdWqN&EH_om}+gL)DiLMjnWTd3ARO+|_o8mAtDT8mW@ zq#Cc>Mm8cppnYdB6N>(H4}zg zq0U8#)07t>)75Ecsu?N;onfYGhM~_=4?)qhRX?PiqyB_6bJa(n!+Gj+sKtD>8!1mx z_ri1*sFyKCEL68awv*MB(Cs3%8zGC;4wPQ0{s2>}Dx3kswT3dPpdd5~H2*Zj9KGF6 zh5R{evr)ODcO-K2!oC@-NAFDcAh(sf6kJE2ZM>jQTj(mWwz8TY!%2T-urt(?1>Or-XDn%ZT3ZYuIT7qWus{7DHKGhDv{pyM-G>0AN zr*P3xxkU9bXg*2JK<`Ud#b_w3E53>Hk`~$pU>)GjU|f2t;C+DlA39W;|) zsgs>Ha+|D$n`?g!_E}&S!3*?4qQI-jb@l>^Q!#=r;VJg%=$Zx7vgv^?3m$@g3#N~t!)CAd1h1v2Ge*$kv)etvA2FY_ z%tlX;PEWxC(@>i{_JvHmFrRu^VFkFYqNB_hLWuQdmKlA2Vm~D72tgUBU)%oD)*;VKG<1m4RoT^ z7f^slT?DJN)tekFu+)I%g^KM{kW}(bOy%yiT8Z(}QhL0x{4E%~LX++DBdMmQa$8$< z>r_iq$$f>cxW5Hj2vyj3A$nAHXhz~x)Ytwx^cI?_H@d7Wyh7Is%`)SL{S!=*q1iHS z_%VEj=IDh-y536<&C`47nf4v1SZKc9&&k3fyAae#_R}cCe-PFcT9{sqVghwIOM_sDh$XVtc=Uy60l)1o`k5>WriOrrH(S5fzhBt zTNz)*V1W{?jCV1ffT@+S4^4_0)a8A8D({J@<+G`fHr+BSG1hw37tss>brG?rbM07Y8f!bi&ifx^8o0xP}nSqc>@oQrJM z;=%`+Zzy9b%mMkWjIfpqmDo)dlzpZa8Imp~Z!9x1?tnRig_ZG?z8JDHexWaLXL0#F zM&Zk38_b0_BNwwHjzGrubrDv2#xKo9DB~0pwb=4M4owyg+0^PuS3-M*&&~b-M(2|r zg+UZm>1$(KK)W=)jXt?2i`7EM&x&oE|HHie#RpMnMruGYi?JAjcmc&a8A+kZr>2G?k!+Wrp3 zS*wX!yNAivWziR?x6{EUc$#K?x?K;u4W6Fy8l>v5uV5Z?v$M-iM$-pdb+R7&>lA0b z-uoHUyTZW@`aY<4uO0k2tR~oQ$S3UJePrLEN%f>1{Npr`ore6jjUCV6CLeFn*uRIi zgWY)?EiC(1oP%d*{$4BaOX%=aFSM%~a(w8y@bwSEa8+jx8`OlPwU)x~+u;v{q&dwN zN!kDglL>A9JO*>;#LB)70!{1-WT6pfF_ag&U9Id1u(=5}0j68VC^{Kd_8(C5iOm5L zZ49LiSZUuyc|~jdI~c;2kYGQ8vrqHi#^C8R7Hu(~MGkXCa;=qiGvpsL-~WJ<+sghC zOnuDUAXz=d(1=~84NXQbc+3Bili15q0TN6?jlbuAhr#-kOS=p#hn#5>(T)XMibfYA zj(1VL`s!KCQ&!*}G~U<}xU1s}R3ck?4pWhXmHiQT*d=9tZjznKP_pzgn?6}-uO-5Z zUg#fSoUXO@-AGyiPGo71K>mVLi!NgV9h`O%a_4`_ueTSpDEi8XawaOBHUpC(5py01BRSGSoAX{(81a1kbd$&D%risP~BCthcJUpxkRfltq7r7DXgG1_93V+ zWr<4R-q-}j>20>LyD=lCJa4qH&<##2f@V{G?Qda--c7p=R%E5^fl^c6^>22Ac>~W% zI|~DI%3lBZZty!SGVKO<$SF_zKkf!o5@VIwy%o^@>st8_GF~e`ZR$Mac*Or*HwW({ zT50#d{!(`Pf9VF(KCQI7z$4{u|C>&*HMSiI$CsPhBts}+n}`(SEB!?b(QRf_vcpDj zwn;tDO+9u3>NI|W30@Hi-ily5q%!Cmo#_O7b?fW?kllfHNd1Ja(j|=7yS~{A(RGVH zmqd+x#?7U#Xku1?!(-j~=-TP(>x|bY##@1#Fb||X1=+{m>Hity=-YU8wzLt@ZPsV~ zT;zK-H&?e>!CsCiCTaHN(BYJ`wNZ>^a%1PkupImROuZ%Kgqqs4d#K#S2+VEv_qqk> zZmhSACxf{UMnYFkL(%Z9pg)7ZP+0}$FIzjWo@>@mtwvY_{?3I|iM;dMWb5hoCkXo?{t~kivCn0~ zZ0PSjgjJol6nkj6Q2I>SSK67gp@Nhf5L1R^Q}LH_C5Q#Mn2Wy=cYr{F$t;XL!J}4q z260}gDm<#m6WEGb?n5<@P4iukbCW%0KY8AT&<3!mC(oNfti#0`{N*uK!b1q@1l5ke zB`=^9ab)gsL@iy&uGIa`hk_qBWwFjkxex zm*L!OkLiKJQnn)W60o|6yxTxri;HW>o2e2$fDrm4x8QHd{V19o60F;BwkJchZz1Sz z#C-;TDUX482p3<#UmlZ;_yIzwGKw&qXj>4DMbn3I;!tEXieWH>fbXxs#ZmXEohUryx9NVd|Feq4yZE zr`z-2387dHTKG$R1&Wwy*w%usX4sdIXO6A61x^ROhGAUK&ow=&4|EUy#tiNlwC34* zFX2MaL--5vCjNY~0 za_OifP-+h{brdPBkoaF3!CQauyNe4tco?7p{y+*M9`=2T7xlT@}lJ7w|mX&yq%2`>dh;3GO#>7wxpJHk46NX_>gQ9tOuh z7n8OwfqM#R6z%JcV623D8SWy~{)?s{9dMq=V3gA@ndC;`9wLq6`ej4=B-|I0Myb8Q z(5{F30PgvZqNKIBJHX*}P^GuV^11o$?7!$N_es!cy&r`5u-BgnrSU9iH1xmi)1Wj& zoxBJiP6~bz_A!%O%Y6-=oKgH-zxyafiPo)A?rjgT&ca`W(yO7=<3e>Z51PEGoX(pYg6$Kn*_1D^&S zLdUt7#9EvHje!WWzzn<`G-~O&O4D2|w;CR!pp@%;kEN3kj_Is}7biPg)QdcA0gZF6 zU4C%O?FEh6_?!^!a?p;Sf!0!*3?|CqvV-vCDDB>W2Ts1e6N>pY&`Lo2i67H)zpLS1 z4#MR;tl_kV*35O|V2H&)wfb<|2eyI_rU!S&W>9%Pg@*VE?s*@h67G&I<@Ek{AiRt_ z>l~<=ou(gh=kl+l{bCF@J`L>%7iGqsb?Gu}gPN{09qwtQ70v;74ecnn7n8<5+-qp{ zaPuT)QJ1yLP}<;X!JRBbp$B4exH`6fv$Q>%>8I$%refNrnA=GEy&3i}qb%is&19jz zjKgMv_y}#B(oO>nkJ8fRN*l5Kmac_YvKU69?`7p|1MTHxs2J?HR$UjGU~%j{1T5*c z?8UJeoUCNCneC%=SdyW1nL18f44Bx$1)NA-2lwZ2i^calTL#zr;Jy?0d~zNGAy$9csHnhy+2gtL z@;p4B#hqkne{aijqO~|WG>zu1Sh=i$oAm~^BtwhOoXwG z(exOCKWV%iBw@Lg2>(?O|CAQq*k%$U2SQ_U*~yn0lA#GDQEPrPysK>}i=(s_@0eQr z5jA*|wRp<0tiRY(*-VTnwR+F1)s6d-b@2GWbKkQsYcyKoLpzTP5>5hq#y$TcWRi_c z_A(Q(RALj@@kYaQ6z=2`X!5ujv7P+~_hp>}Y0ffZ@C^7D2e_jkLGW_JxMl33rOLm1wd_hIR(rdr0FCy%!nUez-3s?HjOw zrWx9o;r>t3l4$d!q1_Glow$>i;otOFAysfECM%rM4ZIyx@ zMX{o1j>KS)xdsy##JnGO?t2LGBpx2aJ&B$Vcj? z#imv)MQS~uzJ!!s#GQK*9Dl&Wn@pNgQ!wl$U2)i??P{i6j6j?wJJxYdgb9$u0bI8GW_Fc_5~#9X{Red<7jrf(x{!j1RB-; z!=Z5ZfX2DP`-Vo5fjW%uKd>*sG5&NU*c$t|nL=Vf<9uPEC4&W(*=R_im*ZndiF$R8 zPgA}6COjB;g?gYUdGCY9`K!AR^9VLA=1wi3?yxQjT8_>nD>h-=`!8n@`v9~*u8b-2Gs8g;-^MxVX__fxp%Cz0h$ z+{>`sTQp=nW9KvL3{0#Y+@gYiVav>EBHV?zvp(rS)!MQyG!yO;(q@getmh1E8Qe>8 zyG)h~Y}rWKYk5>tChSE@+l^X5by=MB=Pbtqg^q#YVO7&+V9VI@{||V2(axHS^5u5J zrw*A^;m#OF1Q#DXa6N@aDeR&*I^AWXPWWPZYM`*W&a3J~xI2q8R>Gs{onG84X%Q3@t7wAP@K6>oyzQvWlZIiPrQ(fqH{5fP-+9Ir8kkqTvx%RT);D()qqQNqtN zG%~<)uL6-0{v{0<7`n#)0Q}ii?g=G+7ibjhXO(7zn|%Z81mi51{g{2?E%8U+dme-1 zYZ@sR?POY#JwhXaSBvbRw@4uZKVxmPv#iv}tl}gj$ZEHQXw9H;!L{Gej45mK!HYQX zBu^If;enHOcyP5Lle5{n+_4z4?4Lm!FO&{eZ!cj7qy1EGuVcqD)A9|bM`hD8v0LrQ zj{?WaB1N0&LuQWOZp$3M^j(yM)AP;t_^&{QtDgsy7W)(S1S=PLS*2GpaHnM- zv}KW`^nB*@D@-BnFWP2?KixQQR;N|^14bFN>^n@i&2GZzZ-3J`H1OTFtS&G=smOg= z5o_jhjIWE)kXVPsZ6Em73Qu1xHu~yDbTsa381 z)MBtjs=;a`68D0)P+-=79+pmtEqfsdZ&4EM1BsPhwMy)z|42gHp{NzOrCKvhwfI5; zTRLw7;yl}of9uQ9RFmyI*`b0v4>zVoeqxjDBbnG4h_nZ{n}9!u>Slz{Qkn%+tBg^p zI;_gakmh@MkOgl0z<(Z#W}%F}w}@$7hjgyQy%=x*Tkoyp=JLPJhMVUbv);xKh_`(?rGFCc$8Z;Q!bX+UUV-aH+zoqBrrS^v(-bm(k`Kp$L>Yj- z&4Vln16=e;*&XjwPw0!Bb)fA@N??0YxJmKKhz%P>n-~))^MoxXzGB2It2ky&vc{8- z8-4**@Rr~9^sx^VuTloTB@F%>%KHv(Vcpxpx&kCM2KOW`{1>wjtV9+>5?Yj9|yI%{~R^`M3-3hT~;fuDTV@ zn@GABq*r8B>-%utM^XVA=v5&-4d+jBH_|W$6=N&6D_))Q)+!9Ew2OZS-&b*qUHoS} zyp4Mj1BqQ6+uxN_f_NWg7WgFf1hB_MkG!wU#N8X7($g98;+ke3}JeXnX&~1{~f*Y6I2>;3_ zkHiK89&lWp)qWTXOsakMELM9d(w>WZQ5LL{vyY~Z8Gw^-_AKHHi)Xj;bkdD*egU_1 zv1gEi=>Woo^Mwn~!S|=Q3#pASkg0bD`1JuuOFH|o#%$iqozFh{817~yA~JZ5tjEtm z*jcy>_l~iwYsExd0_P%Dl ziLO}e*l|1_9x^@R#N+{_=*uqGDD$p@HzhRh8+efE2&=z7X<2V**xiW#5@<()_JPu% ztK1Jk>j13~tYVs{;lEk;jDr`M@R_GR$j6-k8dvX*RT>pqDQO7Dc*wzi`VI)@@1X zJwyR>R5hC&LLKdLAl@=&n+CzAj01soX4{2tz{BA#vFsgz(#%0`;gv<=o#J_r?7{_b z%(X@LS>@L=W{Jk+qOplt5{_A7hhmm`F_TMCz@4!PR4C4SUQAHd`gy{!iFuBNReMTo zJdbl&<=21>vH3AmRtm1<2ughrZ+>jE7q85V_e?S3&D3}lNfU2oY<&=KW^Ah$Z??v( z<@RDM87t;44ljazfXZGhF?elY0$E3Z`MBqiSspj7p+qRzVl_rf?05Y>&J81-^zh)aai8#4#f#jq_XXeVEZJ&N9&Q`3@DH;Bz6Ms zj74yK8V?uZu3=#2jM6grSSMEk-vd9s1T~4&3dT6$Sp1_aV-+6w0g-2LXKaAuT|B%^ z$5uG9keZ7-V+R~Ok2R5wVK^4zVF4Xy!BK;UDmpHKqY)1cbbJnuZFo4DjvL@O4G$x@ z^QItYj*@w^@xVb+Rtfmvt^|c0VmoSTR03oX*1AiEu?^1gJ$(D35nj~ZSE?8F@-+^9k7!}|hS*%=7O?Gaw9FFnRQtaaFW90zi*2I=b2Sl`B-`(-$uz{BmhGrj>w z4+cWM3RZC+92Jl9-!JfQ789a^fT@PN-p;+VS<~8$(1W-ot=sVMIoy*Ns)7k-FrijN zJrZ{Y6MPpBKca&P^Ak&#;GX>o9Ooet3S!;84!&2odz zjq5OmsYrrT+N(euk2`ZclK2M*-H6_aJC7rEm|R_9lqJWAJ$#<@q7*jOXC^Z#=w8 z$7^s*Eud`<$DiR?iHAx$xJ|MS4{LE3rnQxBC!gy?d14dczm>-YQ0WlM@xTsRte&)bcPj135bZUk)dw_u ztktNRAk)n0vKUG3a>1+}0lt9<89U%u07lHgJ)5gxe?fT@2zDKPF96|K_^iNf6 z9)M-4V1+ez2eQ9SUHi!!3XJ97H8xj7gKD~#z?&& zKVy+&Cg@TMNC+~b)34pQ^c3s!O_~K#C$MAuOsRdLR~w0_wV4npHJCLq-_FSiiZLn2 zZUg55}ihz;7_aKG*4cJGMgAzm zfEZFME|jc`9oB4_Nsx317ltX5tM6VO7A8n7+W#1743)2AA)pxCwb`U##ffwVTm52@*FyFEU;F+Dg+VVWfyX=T@XB}*c9oTfrN zHW$JoLIL~3qa`5(yb>^UK$CLh*vDD6otXqBJC2hU%4xdsnkBN%%swP*_`%afHf|#7 zNk5-Qxd@Vb0CF2YfIZPr(D*_7iWtaO#16(nWE0ura4wk0*qazzf`OS>hBwTVY-k;+ zKwJh9k6&i*heXCNw=alkT~U@22}DlqJDa{&*;i9+$sO zuB+@D#Cd~#Bb*XRc__S|gpnv|tYzTx%8SWY?@Dk4(2i3E{w!IJ z^q1ci^9mU%c!|e|6C{cxcu!1(BJ(_u(7cjr;xpne+T^^L)*e>?`rAIn0p0memVEV-I^^_LU(o_?NdhIcjklv(qq4eVGPM}x~gh&XTIST*C z4K}`i*&+(#;f6}$Xcf-`Yw|`XMyw&L1h(M>WImzPb5^c~@9G9;=&bAF4UKqiY*8<< zD#0G+0!xoc~<`%E_n*8U(qjH-kP(}}yp(d-^JUz&S;`riB zb9~&)aP8Q5+AxQDN)1O#%y{0w{KSnj2bSUAWEcVQc*dv!>&BTM!%a8SmrE0q;YbYD z707eN%5a`(0cDI@jt;S0!ld;ileKi2xoQ&rX?2UyUd1QDRzgz8#XEYL zlsUEF^^Z{Ce=}bsJ`=H2H)D8-XR%LILj9R)t8XrB3bc$iL_CpY2x%>&8f`ohDO*OH zlf}WM^l_-xI4amOQR~Zmt)-y|aeN-GIX-?ig3g|Yr+I;HS4|M_d(az;O+24HTqkW zK9F9pM1@pnCaN)WIa+Nwg>+>L{X(! z8E7lxnbs>!Oqm=-rcsiz*Cj-q>_MJ;&Ipw&e#SnO0F{@fpi!0ZAN{lHT^Z+Lk;%S8P$ANhz`9mAzx%08K? z?L(j1cV5^UiJxcR!^z)0_PuH3d+lG6{7d^cY2@G7KjWP6XR$xYwA!=k{uI9lHZcC( zE5-82_a+`B`N6~wDStmqm_i3~B1bRaWi-`Tlsj&P+blkK*S}Rw9r>V*x08H(;!f7)&V(sjP@8nN zr@M4S66u13#7A#-Mz8?1na0W~==Je4xcp3ZKjpA|em_Cy@6C*nV)x%$)ixh`Diy4TaDyWV|? zu9w_5>3Y+>I04tiiA%}ROA}Ynb#>wzx~@qagv(c*|3m4;`~Rm^VA&Fv;GaKRqq#3S z8~TyHxDtDy?$qL(0!f$+%glJ3Egob^a;5~&<|g8Sr3 z{TW;7=k{ZfagGx}U7@*|Qg|1{5AdXYZVYfw>=A(Ez<-IQL3-cBsz>}m`wxU$V)w>m z4J4BR@J#b3lUtZ$z4EmLG4r5J;o`97n9(`WE53tH)<3U{4-O;a%k0Z+ab0FVXw%?* z(0-HU`h)!!!e6j}L~o{ICC--E(!b_<)1!+5TDFeYpcu{}%H`tSh>`tC`$a5anS^c@ zDwc+z5}`Ew6{6dPo(&5ldvfNU8CTeu|D1GP{2O4E?=m&A5*n06&gQ7aK*|GTdzU0M z3da2{_@*r2+fcoBt3*!RFP@2vkqLHHMh2_|k1O(N0%&a%X$1MUUVu$nFNIolDRyvoDc=7NsuLc8FuOfGW zd95@cuY~b&kGj2baYEr;Y#DDufk(hloi11>=B;#S1uQkg9~sJXB0gbKyr?8zIx{|d zE{+=n^vt~Y=&`WD@v?20=%o{nCq`jz86P_?K4}V4IFxSAZD}qhweeF9CE{?c6fzOd z9BbZ(k|?9hDO5CJeDtdL=53a1?CFyD@> zIvBIx%gcpwl=TDD-~Q-dLbl4vd-^(iN4mPpdwaI^?%vT`ep*i#e$R2JTz@LLtgIY= zo&AH|R{75UUESp!y(8sio&9~=dv=u9^dn+Bej>SiM{obOj^5Vc{=tqN-Q`0)JGS)? z50woJ_75S0p<(i%yUfsL`NXQ=Zqaiop@7wyTUx_X8N zdOP;Y<6y^Whe@^T@Z_GpuI}B33I37N;}x8^y&vy5d~`|W2SOQ+1w4HA>Dl~?v<{JC zNi?YSNANN|eJu+a%tyu{vKo@yzf;D4BMmR@|7~@mx$x={E3Hl=@y+mV`xB#`!h zBY*$C7@1#I5UqQxZT^^jo-ZOE89r}BTO}v zR9E-*j*;Hs)bQSc?jg`Hjv!VSeqtUDSR;5w5IkdT6w$q47*{m0fx({L9mCxwIi+>> zb_@-r0v{-U_^`zg3`@@H2!+TJqOdqb#lA9vcJ%e^LOhct1sM*UZ}1WkZiga`5--!4 zLS&pyV_JiQ9eWWU){7S(Z$g5AGi&1A-2n$o7dU$Rclghp{k{EzzN=>!MvfGIh0l*D zA{@#M2egsGaQ7Y-)|7l(PgjrckcRPH-MhP`R-sZ2;unhH4`ahCr_|FYv2}&bpqQ53 zG1xyc02fYnAd0XOF6?u{h0uODFP#GMF?@oj;SWn3ss{B8($kg5JIoc0cCiwTg8Y+!d-a4N_Z$?yKa7>3^qbM7LX6dNp|hT z7!>n2vM*A!j`);=u-(x%r0|l4NN!S zE_7G%X&x*~@n#-K(H+ZNit{U6oPv`yh;{{85mfSW`sI&91&&C%1=HP(GB-D|+RZ9- zkC7yj?vW+#*dlj1k|}btke<6RF{aF&QcjO4B$ed5M}m*Za<^oOBoU`bjpOqpiFR@5NDi=24s7!PuOug;VibjB-20wu}(73sg^< zcRbV0D0jzC6DRA1rq>3paEpv^B$A2p{1rPAn_b)azGb`F38%V}T?m28g|YcgPSP!M zMo=g4o8jGx#BnI!-m=8P{Po~WzJ%W5<^XfyEzOXdI5yucCxt~XlYeeGgjH&Sf3eEM z^$hARUg0LuZBXRJaP2H{7teP$Rk(|bKr3;Vf|e|GcTRCPmAOmH+}<*`fE+57xCJI% zFw#8&0mqm!(|?9rkSLI*zhhq#ZC~I#s-ke0x*rFB%8T8CDF{8?l=Y~jTU_i;TmVWr z<0hQj_CYY*iOx?DI5$xNVxe>EK3{a4r}x>;SM6lddmyhVO9<@zR8&}@bIzGw_~a7j z^yEz3;b0%csObuw3xZ(q2J1{J|G+O&g5$QktjwKO&XS31YN=Z>#XUOdPNM=aypu$15-4y-9}OR<1USYlD2AvtxVc5HTjJUykQZmTQmXdl(>)GUif~HZDD1ZL ztjpR@a;`m{tz>Agx)iqJxC5>{`Ef>-R37&EUY*WHC*feNUlK*0UyIuk^XbFIOv02>)&u{;@Zf zxf6=nn4%@9EugB%l1a|nXHp{-IiH3)fXqk*{}4!k5Lu&y^O>0KPGDztE8Gbi85qMO zT5~jVv5V7H=tH6h#&LMab*C(L?a4`Z$_zK7f|}n&cQOifCKGfsR=5+=l>^l!YPEuD zkq_nWM9L7_!kz3<@(^5MG=D=3>2HTe zIdwj;A>YkR9O=5w-X!GHWvMeu-MnS+Di#-mk{U*Q+uNjM>Ws=G@g1x?aJ_VvtQGh< zBjj}qDCj@%T8AVG{;x8~{}(As$qHDRb+LGwu78JI%g1SIH1cS7d__`tBtvQ$wphah z@7ZujP&7_rGzwZ`S|s>y1{Sy-9KFMT8~-peQAI%P+;RDo6lMSkO4!ACSSYeXDKz7x z?JhxJj^`7J(~J{J$GF_YvDzXOKEqcGO>P!OrUl?322rO3<_YUN-JLQOIZQ`kVI7de zPJ5XQD_U;N%68|mdVhAwfKc8W{SfNHPu#}2fm+kJPM)<6e0?i=>*1-xvbYx(h z^(nD!lh){RdQD^Y`RJ=q1zCw|sV77!AD_a2FW7K`JJWDurUYHF(zvI)Yo@x(VHlLS z#}>I$O4M%4b#_;}rI6s<1*laSVlo#8`?>sY$8gpTP3@Vzcd!Zb#aPTsx?@Yls>1)N z?%4V6l!fkCa=U!oI1cJtDNxi3-~lW-v>L3Ph~(X;;xwUvy$}6;H~QyX+6UOoD|0j0 z7$lk}@}0I%(#=`qj-7()7Z<3FPz*tsw9u`d%0WokB_=`=pLzn%%VZ#k!@ymR5Hpz@ z6~lP9js=|V){%KA{IN!@vAi@Vp_G|B?U7jwf%aJ{XhTMfNgmPEKN1d&D?kDc#;BZX zlpmvW&P*~!lqJUTJ&=DV8`5M-vBH>E;M2H7Wvq1UcEouTeG)=*RdtnoW!S4 zP!2ZzLT&mAVL`qYFKhh@6tcjXFJYWbEVAvq$kd#JXH_B=6)Oxc=|j{-Y$8#nP^-=_ zEofgR<=l`Kmqt;4P%nQV21V@M!@lYF5{f*{vz%+_73iAhH z6JyY0&};G&4{Lv!guOw4zCcr8Q`0#Ez&)HJK2s@kC(2X^ClKK z2JxyA6g@9Z!KO~)tHboAV8k%@#{VSZ{;w+#t?jsL%csZU199NtIx7!nE|_)oSjZhy2lu{yM|z| zaOKHR(*}aKyaKQT`^yfWGPvIM8pTbc||d%3gn1H&BI|JmY6K|1AOR8#xm1* zbgc{p9KBIjw+KcE`Y@AS5Mj#oUO*aP7*`8Q-SJSA9KP3!SmGPXT>sd%BgG$@ZrGTr z+gR7wmfBd=&|a6SSzFb(rmoi7nZn*i|Hv@c+qmF~Mc9tP;Z*0g)Ueglw>>q$6-Rz= z3I1FIP3`F2JFpXvgS$Ggddp;6+qN{+r5dWXG_|+Uy}oWss=e7trM8dsb*55`sjH$A zyr!w4sU@|#sbxb|TdID^q6)@|5*Jy_%)$m(cWP*$qqEyeAsH^_rG`6(PDRE89m6|O zOh&G5YN@SjNwwD3)}t)D+ zMU>T0JYzRcN;;J4z(RIcP<$-=rgnDpb@g@+q9E3e?xEq4K`iR_3|gsb?EEn&(@?7$ z+FRGAHdWQPrB>HB*0-)@m1Oxc)!Q>f<_~rcbfXp6Jds$fZB;GO7|p;`O?zuw(*~r{ z(%L3`LH!32f2flUlN#PR*ngVU+1rE9myTf5YEaldytAkC)IP8)NP9z7%lf+7RBc^D zU0Z$Q8fn??Az8+^WTjf=f-#I#AjX>d##BrFnzfR%3c@aIiXwjmi!?l5YV~VUTerFi zC5Mpu$yKjOZKy(es7|xwj^d*xL*2uv-91Cto$ZFGotEnCA2AYZ7WT1MD;o#_|413= z80^?ZlB~_6G#!0Adb@+XnyYGAy7mo?R%Zu9uxEI$DssRG*wY~KD&i-8kz1_pzUD}~UXvk>vGB61~gF$z}4gohMf?R_RQ&n3VZY^#6 z>ZUeGU%)cIAhoSEsj8Nisx1&?HsQxcx(D|L;o9mpL-Ly%MR3T-xG)sm&khvxSW_(2tf#4G(to4N;q+Ck{gwg0a?iblzC7*tpELt9HdG-<NSeG(s`aNPp)n+A8`;bdR1Kpjej^SZ;a6gztZE0#p zvb7esvsu4X*T`VUa8G|<5H1ks)|x74b>X2jL~UIS)OIVXyS}b%Es|QZ77{(2f|#Nf zme0o&l`kZ+Q`^*DjY`%u z)Ym|-1zc!quA)fx_wGic$v}k6(=^qVc4|24*uL)5QX;gh2PBfkHcFZT1uhI?j}1e? zAe>&O24dZeMqG^otgUOQ zZ)4hN?cTDcdfBpN5H}v};D0HTsj~DH^C$|&GX;E}G}JY&fj;ov7|qtSm{A6-2HCG0 z6gi|=8rl!t+|tyXs%qR~^$!fEp!NqlEHphe347DtgNJr-;&yhE{Ucxsfc#$9>z$Jg1!LR46U#hhdGjia2VZVT3}=Amc|-} zFbrWz-CaEx@OA{*d#pgdB$|jdYwH`-+Cc9_0%Ff~_jSU0=t_A*Uubkg9Wh*|!sE&= zoTEzZG`V*`1NW#}G&!`?t!_zim=OtXt=|f*BPJ(}U`A4V1p_oToJTrwc8kTUhZ@~z zG>oJ}8aicTt)XEUtZ%D_2IHv(OA1Xs^>i{^AZ>LB#U@Uzu4-r%6(x#RhUZj6-D(;4 z4EJTnJzz{r6I9O@SlFH|VQf$_E0BfZNRSvS!qy?@&B=^FTMu=1z-Zc=8tT~I%?$k3 z7eiWXXOSS#PWQ$0D z7feR>JGebLgkcHoAEtbSWLn#X`wW9ZtssL0bR=|kb3;{4$oMi{Bh^~h*vdXw-xji; zB-ZMNrcG8Kr?0)L+RRKdC>pJCj@ia)N14@9^c!fzYoUeyag z)moRLN^fav@Vf|&5F}~FX0(LNDWprJ2~A^_s4^t%sZ3aBoRn!z1En$m{o32Tec0O8 zzXuZ?_)Fuf)vnWT%+*Y@LuNY%_QK4PDUDfH2+F2`(uXmqyPjdIdk^eeGx3*s3e39= ztpU&2L8StR2sY>SRSnH+tE{ly8!^H}2l$nR-GE`Y2F8O$1H|-G_=asvtOabS5~DJt zcgc7aG8udz?wqg>?d<2`N-t*C?6ln-r(*60H4zf+*0oi&n53C1U|~kaBNavJi=F+u zyD^uL^${?$*J}q)`x@I5{E<#ai&Iy4WTuHm(IHL3kw?D9=NzF*hF?<==`JvdHhEbD zO&yFMgZ&)Y%oM^`SVpg>>R?p0)z>f+BRi(QKwH;|Wo5Dn*{uv2X%FcFq=%R*QxVHp z69e=MjlHey)wCK#W@WuHj%%NHzy(V6}Rjitvb>A zqe%!u5CSF7Xb-byCw-a|PCx5btliYKq5JxlO}hBWM6tGt3r{k6HEKaDOqn6`$(y-p z`>7R6k?+ExObmIPmodjkTcT?Qb^#9Ddvaw&SL{{{4~%H$gwQb@@ktONg`q|p3q~93 zK(a4!V&JD5nlN1mSQ@sSpd(@YnbtGHSX0$lgXtP8#FZ4JmL?_jhmN21hmN21hmN21 z%b1qo4Ld-py1gF838pl(;Mqp9%tEUveHP?T+!^1LQ5YyIUe$G2N3*y{ z0b^5$RgU#6Ea!IjK^==7!bMd?J={*!G~7SHp3sREKaBUf7=v6S8TcD9 zL;3M81LwuU4DFTd2n|(jx?T_^Zn5yD!mt>^Puv>L;v$qgB?LZs-{%X1o@a z5Tq{?5tECgWLjq}R%YAkunvKM>3u=gCqXp|4+{lgjm|+mp_jFjpbD)h1{P|Al?cDE zYmh@bmYb{Ft2y!a^OBxwh6%O}mJ7_f9Gc9`%~aCBDDsmd0T+9WlGz=@z zB3!u)ty^kRy*;~(_EHAdw{56u#v(A5N?M^#d~RR@X{;rxAziiT-@ct(-V<@lguu@h z^K2|X)r$NNsp>`1DGtF*n$woUYKiv7^^HxNMDP3D*;H4xJ}4MAMWm(t#So@!=5sUz z28=c}oZ_-Rxo=$LzjPPh?2y3&8CH8uWHe_dS{jxnTUKjs>;<1Wvf_#s;N;k>{;Ez; zyMpf#MFQ7>EgAz$ZPqSsx$xSJvEVX3ZSqbD!_Nu(iFOWml z2YM@3AsdY?M{Oi?@E~d+q8L7L5+CzNm0MRD$+^EHtJ*}!L;p}+@TX1T|bl;+hlseRoXPs zX02saL5+FxD7p;iuZ*Or4_Uq9G8}RajWw9>84Juv1jk-Wx(-YT&ydC(C4DPSxDl~a zs+%^aj2Rx}0R2ME(!YHO`h@>QiyT_-){Scz$rK^2)Sl3JYc_%CL`SnGth`|^jY&Vc z8zu}%f3bnXXn5U$vr03YV8wiP=xUljo${4vSlWF-i3+C-i`q1@F~Ni*EW+9(Y^NYY zvja;Gp;}zF?hz59O(8wQbP}oqqs%xT3izZ$oJDJdRKG-+ti!IxPGdBuG;NCg6<8%Z zsh_s{20&jpShSRi)WjL3(h&*qA;u12$0s zx5DINxzZ|M)qpN5(^<2OXmJ&|1GXS}!BLUoarjlBJ*Lx|cM^?6nK6>%BiudQ*xzk^ z^h>f+)WelcxtFhqktxRw0KE0=VaIwX$6K}rbizPcK*O5{i>s#w-lp%GQ zY_bO78hUh*b;-zVqj4Xug=PV!Vc4!luSP+9YYKY;^=1_Eb4;^XbzwfjGU@`X)p3R1 zoR~o7rrXIjnRG)&F(#4Ua5Br6DTcq2mey+A>7sqqgVPFw9hlv5cEI9_F=EP9jb#I_ z??lQGQlqK7)naXErews+9Cy%@4nDQMv9%7nZ05X)=`?uVOe*0u6>^Z) z>>R-y1~VSBJ{0c5!H~)9v{T3~IO59q7CDvSXRmgt*-;PoDek)ldnSH6i2?5|)k>+z z?(lk($z4}@s4&Gwl0!AydWLs(3}6zCC1F`F5c5n{+x@l#f6YsdY!IwvcXsdW@5M5+ zSL?EL4~cUHLUvtII@MmREfkC_OEbfub5&!GwjLT(MhzjGjSe#m`Ia!ZGk5g#nRWfB z28LkLgca?=Wnu1pnHk4WU&jCjW)Z@!{t;CwW&wZ&XAJ^Tqfu0c^E6%oO-X9ZF0?03 zssZGjNWe)Lr5jB)X@jyaR(j?^Oh*iXIM0Ceyq+q1CP6z;FME6Po_%ZvT+dudJGiAf zz!RKSeC{HlIFbgc+9)?#=)z9pzBEzz+!J{DHLw6rl zw%K$v%T8>vfVbXCjF}c6Y9NJYePW!NZS?fc8}P^s^nPvqAuhao&81lsC5WWGs}*Ib z3Rb%O$(9-Ykfv`1H?+x8oYCRZ7tQ)Q!lWs~#*GUXc@1iqNMkstyg9HT1~P{MYfWQ& zvS!idr1_XZa#6*iB^65-E=exf)j2S-0-Y6dxuD}{xVOXI*WKT@VEe$rrF8f9cMLDU zcF+p!FLi-1ymMsNHeknK=gt-QB*gBc7Ie(pH85|eyK`PB;*R8krlI5lygt2RN8iYz zJ;?>zc?^$BveX1a4xcIVRJifjf*nC!Dlv+502^NZ zG!-2wuz=-sqR$dl7NmrrQSWfmlpq^-Xbu13b<38=KM! z9QBf&F^&$^IAvkR0VLx$ZB^~Y6jr#r1ukhiW4(C$q@KFap_~Q?xysg&E?_p>;bOqS zZrZ(ahKm94k~<2HEm~A7ti$(O-r|vI64{7Hu~^PVNJyIW;c#G!S%>sXEu_T(KiJ&f zJl=3f6sD|juc>Ml`%Y%Mr*;qar5#D2u(70}`7f6-%}`*HN;i7BPJ)seYev){v~4iD z>mqZcV~G)HT3t4_m0Q%aUFKMrm1flW4K014w!OvdJIKg_9aZU8x=$W3fd*x}6wZ_z zT2w4Pov#U}jb1mkGgWBC#OrXUqk>v*31&pmYH_f!21oi}7+~jHPD!bX4qJP2xYa+W z$Tr5_m&_bO(>IW*6He28te{%n(wb2yD!XP0!9QE!9pq7w!(m*r)B>Ty!3S$sPZy8Q z$Vmz@Wz0zmdDOKuGg^3C8is*#76*%-8056UX!z)`Nu}aV83Ox92P_qKZ@twd&Vg3+ zk>AC=DJ}by2%xtbAS_gpui+;hHh+WM1!Q6S)O3^(3JG|`Fr~MU<;b1 zAQ{|HHZ|@{-ZJiCDQSDkY;e*f)a68+Y#5f~NyD(VSSgJtIzH5*)$KSD+UWIrvvf!y zWYY$=dTIj>b<{UEh@LX4ztNbvG%@}4sdO!rwy^2*AW(hgSfeCq80QHQMa*Z9Sa{Ij zIA9&t;v7zpUC_(x8#lsstmX246~=ygL^{IidNXvT4NhkL+Y=oztj&=+Hn+?l%?u97 z`HD@gzfJXRYk6pvyRw{d$-gvH)H_)rdw-DaZT@0#G%c(t$jEK>q&Qj)S_3`1`-elH zd8+O29N}`{Q2EBX&E5yFSaPGY^dNVjBg2*2i@kb|Tx1LLj&#komUhgXrI=(Y(iBA` zoBW88#xZjW0eh0Hz3ky5L`3qrxIv*ahFQoQCZ=642-BKOfxd4F?NH^`I+>~&c*kD1x zm@%@-hS3zu2{208_THd{$6$L<1ItDxr}cXzzDOHp?5sli#;~034EhC^BM`>4xO7Y& z8`kXsc=#PctOg7N$XvRC83w~9DDAUDVk}Ydl>+JbZZg9$>E_Vbxedp=L&vVWQCVN! z!zOch_|=vBv=iV}m@%3ekvUE+JIR1r>C_v zj*{UJs{c}uu%b2Cy5bZ)R7LObnA!q9ko6y0i!dCFDopK$j0MBZ9e86;J#9{)niQuHU@qfuEO;XC4MB#C9HzIA zl)+!J>cUQ&Ir$per;*p7*4E>74>8tE`%uktT%sTb142rTW{=2;wagAg!opq5Gt-T* zd0XLO-4S%=hR~^Q?`Q%n0@w(9iQ?Yd{$FPF);4%|5J4V!e z;JA6g&1iGV1`Qaa;9#0F%d|nZeaprz=|-7(kxmws4+&krq@p5d5Tj_QZLEQvdqX?h zv}7>{*CVfD{!?Ap9|I9vksa5#P=SHjih#glmUu0A|e<&8VfJwJYd zb7AZtdAA0bCJgYj#@;>m(@Ft(kPavhb zC*ZxzO9Yt2=K`zqlILZfpK(FrLieKhC!LECt}1U&tUfz0S^dPLKYE0zGSNMGN&bkm zfAJ&3)p@1oWu2dSLB@rNi`-AfFLpj9<^7v|a&}%R%2DcvHXkEKRnAMC?_LnU(76a9 zPs+}lfKVt$C|o0+!I$&m=Q|fjS!Q?Tu@2#KpDcM#IWOb<#0Bn!@r#^KO1_WSJF@ep zROhVb|0jZ?r}3S8ix{ z-j}Tr$GgzH{uQ_0{-^K213n%YcET-RAoOVtzl|BX9DE)VA5D~4?Ef*iDObToYH&IJ zC%g^K!55h)2i|y+ZzTH^$I6PNmt_^fm!%}{V(<@N4nK++x*TYz^z_4;i1p2jq@QOU zjrdHTdMYNl1PMC+r^gM=vBpHw$44(imxC`+rt>4;s)0Y#XJ3x-OO>I^vG7I8(Bj)hc}bwxDiVmNm%}}ATpjDt2~l^dBlHV zB>jcfy$HedFUK9T@Wb<=%dr-RTugsSB>g23|D}=ims(FF1k-QC9kZ53!Y_-skB+3z z-W6Pqbxb7vW2`^Go9Uk{{5eMApFo0K$9NBdj{OGj^wvm;`5XK=2~s>mppi}XWQ0pdG`J})>`jT(6Q`EBI%tJ@jp3|-pLXFZ4q~8B)!gve|N;aJ(B)* ziBFr%T-&W9RURo9wl(5;2s+lzh`T3}e^12!)JT4(M*Me0;_r(1_eK0Uss)#W(Jo!T za`X!>#~O^p4ls`_!6TlWL+T&xpQlB_<2Sq0D0|Xe4u0`B-T(B6KYuGU zxE%kdO$^Pk&I&y7PmHxzSzn2S|6auXw7N?r{^{1M za5FxqQe!cmzZVIgaN(&J>oXzZJ~HAyHsY?2xQ~mtkB_+f;AVNKv&Uk*JwM|A*@*ia z5%>KO_s=5k-$mSikGQirG180mofdH~iMZE9+$TlcLlO6R5%=feW_@YNjm3C-U&Q|> z>OWKbPqtoDH#P5AYrAD*O3CXmWfc<5-?mTR+V=LfxG*2ys=*?9 zcwti(yyehl@NR76OE~{(-$YmR&2Ea>VfVhDRwiHe@HP%ZAEH1Fl^Tgq;ZiQ-cW%5?nTNNItl6@l!R8+W$c7tspF?ZU{_abdm?nK;5AV#HPxHQBB4rX^|2;~N zk8A^GX*SDQD0$T^os$0XqBK9*u4Muu_=nx`JIw2I;qZQB(}3I;@_0#32eEyBVG&=? zNZUA;&d&;XM`VJ%Cq|GhzR+jB(rUpot@0HF=4e=P*fTHYZ6`$ax*H5AMz?uy z5J3+8Y>-cs{-xg%N=wXa?1B_%2R%k-zFs6kllCPcgbn%v-%U#+gx}|bM~GdA{q7(+ z%(4ZVQDcalh8TPpGPiF-vcec4*$722RP|=t~CYdbY)v`4fHk zz0Mny?k(ejPII{ED@ym4S3$=xAB4v*@5lu@elW?(#-cRWQ;0>x8}TE2iexISu^g+3 zC`TjFD+lJL^}*^eq8APHo_6zv$rW^6jCc=FY5q!R!2xeVP zL_0wwh0h>a@Bzlc3${O2|Y;iP^~E5Fg+!ry0_W?R75Q&~FzL(Qf?FX6E-O@qWk|5#iq< zqP!mxe+M4KfUhHeBIIl(@z<6$NJPH;5pI^}3?ky=$7rP-Tq~wraUF;H>mK48mh~|G zQRxqfNN2PI{5{%@i26ZA3g00rR?!{MQ=k{2-MJo9bTo*#=ALTM@0Y0GSddu1A|jYQ zn}~WY2Nu1Bf4Jt37-T$YKeV^#6|^_6xu+YXe4^9ThfPIucjOQq8AuD%aVOU z%I`4U|ABwF=AJDe`WV%ebSO7PNQc+l3k~|?)F*@Ti2tP#|4$ot3_`;4#MYbeu`8AS zXEWZ#I@Etx;Lm!*uC-);Id;(0gE*da;3VP~j6RE9hjk>SS13{iGhC(OI>jc%;}v@p z`xMVmJV%jLU^-VQUaxqQ;d`-|A*p1#ak7>t;ls%hI>ZwRYmq2(j7E7k?W_#VnzOFINhrh8x%Jyb}0@h zo}+lF;x&q2QT(Rj_Z6Q|{FUPCitj4M(SMkKz9QE@>E;iI6KfP@KM3wNb#GDZR{WUa zKE+QdUak0L#oHCXr}&uSbBeDi;-{=7e;RZw$0)^#iZc}#E3Q)9ptx0WhvKl}If|cF zJg9h!;96yH?*yCQ$Uo9X2%CKVSbE>~Qm*rwQ_$e$CBA^w?)mndGV_*KPw6(3Q2TJa^t z|5kioF$;<@hI9)RXDBXGY*5^yxI=MB@hrv9Dt=k{c96JV)^w#jhxSQ}O$XPbmIc@h!y<6&(y%c#h&ViU$>MP`pL)cEx)XzpMD5 z;-iXBDn6t5yy8oWuPgpR@g2o~C~{yXzY>b06vrw~P%Kg`Rh+9>p}17BQn6Zbtzx5M zyW%N|=PQ0y@mq?ID88ZiuHyTO6JR^B+(n9|igOh!6qhPiDpo75Rcuo1R6Jkta>eTu zZ&Cb~;=_thDZZ%qo?>2}Dc^;PmnvSNcu?^n#n%)^9bw|lR$QXkrg)9w4T^UtKCbwb z;&X~GD88!rrlLFA6}T5+vnqhg!l@rrvD&r&>J@l%SID}Gh+HpROY zzpMBQ#a}DFtoVlFe=EML_?}`6YebZb$%@5_vlJI7E>=8Rah2j0#gt;VVz1&kiq|UM zr1)LMA1l75h@Ui;@+?$bsklk;M8!_U9>spe5yg)yo}+l7;-!lJq4+t)>lDAN_*KQ* z6z^8NPw@f8A1VGs@oB|hDgIXRcZzQ*{#o(wivLt}F&ANb9#}rRfJX7%#il0>cwBnVD*DC&};#U-JRlGy-TZ-RP zd`R)fia%BSh2pOjUsilW@xK+{ReVp;#srZ3%uvi#%vYSKI8AYe;ylHLibpA~P^?j` zS8P&jS3F*^Lve@VF2y0my^3ckp0D^R#r=w(Rs6i-7Zq<({JP?uir-QEzTyuRA6I-z z@j1m86kk>Rz2e)7e^vZI(J3%|ouXKxI9styaf#w`#Z`){6&n;=6gMlLq}Zi+isFFc zZpAYc&sDrg@iN6L6t7V{sCa|oEsD1*-lOo{ z6LQL9LUEMhSj7p7MT(`0a}_HTmnv2&Rx7SmY*cJh+^Tr8;&#Pe#X-eAiu)ALQ@mL5 zGm2L!9#Fhq@kYh3Dc-60J;mn~UsHTX(J3^1nWwl=@hHU=iZzP$icN~`ipMKvDjqRGN{mndGRc%R|}ia%2Pwc^W)Zzz7C=u9@{$x=K*u|RRM zVzJ^Z#RZCs6^~XtR&lf9Ns3*Hrzj36o~HO2#j6xQuXvZ@y^23j{E^~s6#u4(-!c^b zj#ZqdxIpn}#g8eTrg*mEClxPOyjJl`inl7>rTDnwQ;N?izM%N3;_nsTR{X2t2a55j zrrbG-V-+VVCKYEXmMI>oSgBa2*r>Qk@nppw#X-f7E1su#sp3_N*D2npc$?yP6o07r zl;WF;e^UIrB7VPF+ND$RT*Xf-9#FhV@h-&&6rWW5wc>v%{#7wP&7?m@u}E>A;xffL z#TLbsVz1)I6)#r&oZ{_@-&6b*@hQuCQQdD5e}erBb!R0_c_u3^Rcuh)rnpz}pyKU{ zk1M{SXce3EiWQeBZdTl@_$kF(6dzZ7LGfM1(IqCmS&Aza+ZB5iKcRS?;+=|*DZZ@u zuHvZaCf(_Z%N37P98|nW@m9r06kkxxE;Z>S6;~+^C|;m=wc^(lA5?rn@mi@9fkCpz6x__zoG7<6KQ2apY z_AFDsY{fjq$wY)dMzMK;}+lZf;_q5hvy`W1?wSNu=K z8;D5f4kF?`qxihi-z1`4{;2qO#Sau?vrYUQBElV^IDv@tiqwCe(#sW>DOM_05mAmt zBI4~*+^2Y<;%5}^B_6b_9}r#3`ZW>x|5ovjiti}?orrKnb4{Yx_@mj?vh{)%cM698_OGNsASNu@vljoUm zixsOB8x@aN+^KlB;-!k$D1JrpJBq(l{GH-EiuQby-_eR26+fXW~Hz?krc)#M~ zihoipT%h$(JepX6eXRdO*>}KKRb>C)JNNYzUU~=tUJ4;0lmtRY2oN5#>)TuoqO)fBZB+;-%lprIcLtC zIcNHD|CIqrh-L+t%;B;6}n8YxA2DvJyP&e;ZGKN zy5N;W)aPo!`vmt3zD@KP#(P44CFp5k=L-q8C894}B=lgxNrKaf=;w=wXtxT%n*>)2 zt|LNjD-m`*Cs--?h2ZakiIAaOpjdv6!k;ZdZx?)4@Q~o=g8wC=o_`_M z$9OIVay$z*BqF^~=oW${!tWw&*r*9+b! z_@LlUBJ6vH2>ag_{94d#Y4cMAiv-IAM-!3%O2H+9w+Lb0R@E)nIn5W1CMcfp>5{fNka2@&!Wgg;quhVT~)t|mhMKEY=ND+SL8 zCYIQ84T;d(gb4eZ3$_w|cfp~8;{|6DAwNg(Y9h*AA?ddXf4$%a;cpjwO!!X;J}dlJ zgnnJ{knlec`eVV*h5xP4X9TN-Z?(4V^9sfi;b)rA^#nu0FBH0kV2SX%2;E(vdZ*v{6MLqxk35PRdfDxu4W@TZsH2*J^U(*$P;&Lcw4QlXa%t`z=y zq3;shOhkG6gnm-+Wx>}3-y%Zq`$B&t_?hs(5&Ap9ABoT#)8590g870M33eA8L4=>9 z1t$nj7Q9k$zTl05w+KE>M0x)d{EwikgUwGBY$Di8aE#z=!RrMd6nsYTh~PJZ@f~fw zg@RoKhYC(0zGWD*g}z4cRwC;0Zo%gT-xK^rFus#5*H|ztI81PX;EjTR5qwG#_ zgm@X|0V2xzJ8`vPd_sgBp9>zB^zVhP7W|C}d2eSse0^Pv|EF_Y41Jph!ZiIebLDiQw87Mw5XONCx8xKjA*guYX7lkguDdWYa6MA-F|r2kF$ ze;0gB_=kmlPw+z`@_i}kr-c8#;7`K0y4iMn1>=bDCrvOU*nMEDUDI$5x;@N9>ycM3i)_!e;*-k%^s|CfT_3Z4=CRgf>bQ7)Z`d<}@GzvjYkDcDi4i(nZMazli^ zSnzVe@q*I@XA53KL^(GLeXHPl;Xfq!tl*oHUMcu5;eRYxEg09=wkLxKe;Noj7AzDj zA;NC_fTot~A=rmF4f}Dy34${OuN7QHg#I;x_X&TW&`%2P7yesL^bWyCg#V)8zXVSaQBS`SVTak@ z#sCrgG@@3(#u&>}i!E(U~f-?lK6kI5{MDRwzTLfOK=_$cHAQPpx{BlcLh%i zx(C|w@q*ccZ3O!WP9vhc1w`1rNbq_|zf;w#3y~*8~?6Z$v#3D-7dZ!Q+DZJqz&L1nl&|g8Kak@ShgCQt%7GpNKfm zO^vZpzb^rLJZYRat`dAi@I^uWego3=`wT$+9s|%Di+qy|qqX1=!KH$G1m6_=NiZSK z&exVW0^>w*hv55yzIZ#miC}BN-h!h9mkZu4xKHqT!8eJRYfcLW>VSrCjRnhyX@)V8 zn1g+T;4^|B3jQD%2-SZ}Nnb6vPjFbG&Hq7A zKi3SoVaYaslHh#7TLrfY?h<@j@SlRG1RJE-db$Yq71Ynmq8$A^EbwvRzbg2?V3pu+ zf+?xCzEZ)<1g{mmL+~lVw*|iz^rP-s4_SiE1xp3{3XT-KN^qGVhP9zKVxA&mj!7rR z7)FSQI?X3Swup#%43~j*JC_m*M;d&ggyZwCt&JVLmLudhU1kOu| z7}qO_7zb;J@M8mUKE^K*<7+#y0`m$HU9xzK2I8Uy+(vRM+Cnh!Y&WjEnu=>wxE8W9(;Zmfa!e%FBTjpI8%`Chf_|! z{|Z0Xk%pi55>fvT5M%83#aaJ*NvFwriu!++H2i*%i28q(2>;(A!vB8};qQk;`1KhP z^?!mm2+yMs;pdM;)W2Sj;jey=7Ip==p2Dsm5q6~#EAZYn5%r%a)GiLm!}8IM1wgND7=q9f4W$B3|3Kd%aVU(Emwdm(P9`=o!v?p&esiLj-U(4|C_ z*-vPgpzD8v(36SqYo*Yui16=mp>_X+pNE7#OoYF&tZ$SbB*Jg~y#>&vq~SlmAHej< zMAU=cUx8jl8uf9I2wJx{j5;c`-dCZ1^nMEIx}8u@o!CyGONpqj$wE&jqMbhx`g0=c zFV?c<`F#M^W3JHo#0s>B(EW(0*9k&TCZc|g=5w!^fgisF&YNT7WGALSywqI({#)~L z_-s>i{O(M1GMn=YKk{L^=3R&MZw}traeqvryq!E{!h-WBYjyap5Wm@@KM_>(b71-x z6>F>iGtu)D_rJt-@hn$=Ldd9HT2#t;l-ElA6IU+q@x9u`o!{CEWj>EZ|Njai6%hFd zU~Qvxt2jUGr@KI{CjFy;R(kHo1Z!)pm3kgu&Lg4qUhuPowTrm0;CV{>b75WZxt~3( zU0SWw^AvF&39Yy01B$hEMx~rbU#(QF>w=$PtgZUOg6Ape&xLit(h2nU)8x}*_SXVy z7kpvC^A!B&!n$B|dHFJ!{S`3#i;%TTy@1qtiu@DFTII=4*;a2u|G^-7m)f>d!mX(d9{twpANNu6zk87iW2)1qt21~Q=|SM zS*s~%bmZ%O7jBSq#s0L!KZ@2W@_+R+N&nMAqGW1mXYqghzTTgEb{_dZE&T#zFi$OO zqKDz1wCA~Ee_D1e(c0ZCI+u_k|W}FyF|XnTNIfQA}mfywp8>S^@n*Q`U{P^(*Gb~ zf3Q)fO_(@t{uTJF=A>Chb2~nE+_*Utud?Sqn=^eDezJD%JlT|r)SR(1ub6laYtGCo z{vgKvl%p6%8~7gb4F1q-wE9W-Ix2*?(-}K&-kd4p=FfxT|Bs^{WUxf5}`&E=5u_8x5_&rMM zcKjF_6-P8uuRkLmt?$<;KjM+*_`&boQJ>@gWr#-~OykkimW#AUIe4^(x_CH#Z2|mjvxH)ShOFRQGVc(Tcli`XH&P+9uDKRBm2!R#{>=)k$%PNfgv*FaP(zCE?VFB(Dw;ssE>0z<*2W{=yUwweY5DpQ9at0 zi}*n~=BF+mPPrp$m3tT+koC-Rn}{6q@xEKMA8$Y(?-e?SV+Mc6BifJ8q3=})QD0L8 z$B)&b&&gNr7$gcE)w^uDh#!=rJ=Dd+$@WmKavwfj<3|gTW4`aCT&G`6hJtleB!^?q z-)rf67W&#jhJF+yuw3dpCiyHYRg6Z7zR1o zLtQ+mj|cCsM*Gne5yml9_RQ z4t*2ssQ%CTWB9koIcD|3CasJKayaGgu2pVRl)C{kY_~9i<=~dQVv;1AHO3S-5z}|;K!x5T*Qxl;shknGYsG-tqSx(dX3Du?zUi@0_Cih`*FW zR)e~DIR5gvn&^6-5asU_kz>9Qw!TQaoq|5+T#))4dzwKmTHm}VeYpJ?@uR=!bMjGH z^iXo_yV{nE_z?>^+CyDD9J#r*%3XnSoq1@c$T8m=Qm)e;$nHbWot za~#b^aN6TV(dXnVx_}?2ZMldaox~67;^Fx5b**wAi1K5u$kC2W+)t10_hrymkBa1A z8jlvW=kGeS0sUZ*DDphoLV7J!}u$wvOmqFZ#gJ$6@F@Imn@GA4&21xY71~4}G&sY<-K6 z?%21bmcAEokDcF=b`Gch9<3!eYNBD>l;%j)l)JlDxf2RaqZFNyek?_B%KdvSeV@Uo zS8LSiwj%krTKXO+HY5ApWl{RxtEF$(Vyp{Jr-hv3$KhJ~#)`SzeP7km_YREz zZ`43?^c}0E?`SJiKhr~huaDAKE&7VUC!0CG?tgB4?=BiH3{&7O{;j$BaW z$m6jRatqG0?#Dtdx*x16G4*)`?YjxVX^;AlLw0Al;sXpd=K$32_)CncR-+T-O6%Zz z4&Xn4Kz%_3mKkM^v8W2?WmrRL*^buwXS=C)+P3L9CW@SD}fR`M#sy~0=d88gGaXUvjMt6rbny@&T` z%#`juTp#qEa<CJW$My2`; z&UlTN&UmxOov9N7b{~Hxt<>6kX|?MYoneK7e3C6+!^NUbe&PlA!3*#c&dYChyn3K3 zTnB!x(N-H-o^VKF*F|D(i7gY{deRePOO@8!butjM^`zfe-Xj!Fc%Qy4uea@Fz#2DY zv@fHqWm$*v`=?}-H7Q$I{%W;R^xU!P+bGi=GJfkTT{C-pk5-&|A|-s|UL!j*JnK|> z_cxE5Ej{5|rn$Bo>tCN%dEA@GJa<-iDhd`he(&RB)+xU~KQBKoFYjUm9v2%;CYyz> zyJt+k|KwmpogAz}fpaiA^`l_@eyljEUvmy{Dd= zI$0IE?`{#vU0(j5@`Os)CR@kZ4CZJyxl4vkH!jz7#)IXbREdO6Z&zmL2$dIw>zCSXt(t+4F=lS7qR7Aj9F8&`f``P16}y}LXWv!93!o2Q$4io!Y5>OJ$^ zvDu}_{espIHp4}_Me_CkukAd0cUAR%YonDcx9kZ zD17jEYO9<{_fNRJx?gD9`0-~9wF0plvkx9mP7G!}cPyyOF7nbJ^a##tNo8$B$2V!m;7{;k2;Pr1PPv;a*wov~^~FMy0VKG=6HhUxbrh zX>8hdeZANf)y<2hhWkhO^(ybFMrXz=;TBq;S9XE;X|DOG%84I1Lvy^1{H zm(IjnW?|sS?Wj>-Vay@ld#bSXyL&5Kg~q8(70vW~5iI<$tW|{9X=jRwDptY4m-S{E>nf?!iBfAUCZ&mDD2u4yW`E{DMNNwPbi|c zky^$bHu7IQl({|bbbf%`OkE;l?wy0rQ`)h~Ok-)wBBkX|A+N>ciZEWtIF+)@vvW|S zHA+u?TjAM|yT-F~NEGj@3eTq9)vJo?#jdWtwaBw`XjIzQ757x98>_1yHa5cU#@hPK z9qvs<;Wv*r+OWI&0d0Lj*tY-Ps@Ux;-L5Idin3W}j2T%K;mkEo+&Jm;M#bGu+?jpY zCXk6ed_1jzDlD)3Y)bkD>*OG7+sRnV?6`G`Z+&2W&Qx#NLnjA&N7wV;Wu3gtidnCA z`*!5Bh4c)52P{s~76-tk4dkRq3&idqr&pxjyL|82lc}w*sr6k`XH6Y=VyKVSEcK~E z^N_2sM`hu(535648ww(X=Z=1{oFWFseYhwVY;4%ST0L#UlwsJ{T~3GvM;SE2u; z&u~|cpOU`OIyuC$$~IP+g$bnZ*<7}5igj|h)v@f0DG#3n~dthH|mD8W2rTb^M4^ujX|EqOd_saIJVSjL>y=!vU zocfY;#@;;3*@fA{@I0H5~Fa zNjy~NJ=J8=5m%E5hqCne8~FWJ=|6|U%OQ87D%j+7WvtY;-P_z@8@u^px9>YSyiVzN z-es)wtQkFgvG=mX^cP+V$89u!@t(rS4+a`HDQjL9v+i$a;?2OF3%Z-_t#y>(oc^6Ia2c zDFaUok8M+FZJ1Q%y(hJd67DiebUpOyX(I-;RiO%AJrnQqoj%(Ry}zJcWzQZdhg=&Q zP0c9VopIx%p|EY~hsUj)u9$>74&N-9Gup>$7_1)j3ct7yrO(nmwG7GS?v zv12cNd-}AAKC`xB4MuqobN{LeAO7D|;oENHF{f{5O@B?-GekN#PQOIWw6fOUHyv|2 z<{f8mIet3!mcLjVZ^n9OWEtxRo)}#(XF9ccWkzs^7d(1$^8RimM+>Ly?^gT)YrUXy z>SUDF$|wEXvujkiIBcv(-`K^x?7hhwb2qW)Qoi)mvWi=~8Hd9AIYapha}Nazvk%?c ztzM-)SJkWh&%}&Rc0%XYob(-st9&~{VfsQ{p|I@*Vf$#oW@ic1RIQ3}7yVb5W&*=E|70EkCX4!en{PN0VtnB5*^-r)ydFSW|_tMJb4P(|M?;I83ECk2yll6BDmpLY|+qbJ5`ei6===tyV z>b^yzJ*B4`Ewk-uw9K_3?sU0cgOjt}YYfqL|1{j5J+-moz8MXFzU9m<-DV%PPFHj{ zI}WMNDKZMD92&O%p6ZI?oKvN!=ZfO-pP-(7S5}S8t{Ht;nYyR1fk)<@RhLBZ)7Ko> zx1nnEIh>8>6`$P12%E2l#Q@fvGU>Egli!42Y1EqG(QRM zY7*`*R=PI?clOu2uZ4PMeiS~qUl_A#U>RQNYvp_4Z2G%Z>`6<%pSI`RnkxB2O|{XS zW;>=-880~JEql6T<6J8)+@KfBH}mr<^R*?Ou#NSbyTYlJYkumBUYGs>W$e8O&Yy}3 z(5pZ2#=lE0b{V@A+Z7&%|C#1 zk!aeS=ukZW+gs7K7Cm>)_!iTrjGKPd71LYbVRt;^Ik$zrh|{9xYK}2*{=CqvNue1N zXUv*&jWKiL#0k?UUanv1(7)6@HANiVdR)u8PZlJ_Nex3rm{U@ zZ)7gn+szBA^wcdC#>qo-U#|1`$?^x}&@OuHj1a#j%Qa!Aw;m;MnB>h}*%Gie*I*Y3^KZ9$GEHm~EJaM9f z@P5h<4?JC^keAcvx^8VN-5Yeiu(3bLRypemFWBFp z@2}YndRrm2zJ6a5!9ZZz?^R{t9aTo?=_$@c!9XmZVV{JFr2XANmBV&->$&H^8$VxBk+C3j*qMd!! zAoP7zJL$XzB%>^$s_;E};JB4IyQgEr$VVUjuhGSQ z=+XafZQ(kU^^7W?-Lo6QbqJ0Oda_|tw%r)RINORphgUKEz?pv*Md#@YnTlX^K4V5r zx-q>bUK$m5M&#vVCrrSr0=k0uTl0Fn>R+taV^YTFRb!{mpJ?bb8v8$vuDJd`9q;nF z4U?CLjUgRTQ}x&3a_f!F45Mw-<>Zjh+ZL>l%R3gSA=Ag7sq;O8PG%LPv0g%^=bB8g z_;amRVLGqa`ugzFb=&kwOjhpuT7xx=toC)U(Jb#I=6JFRSpCy^-8ujX>+&gjQeW=Sl12dKL_9r-?OOK$8NH#^6-pY#csE?? zcI76|VB&{l^n=T;rb!iKd_#sG+FeD->&ZBaf5Tk9#n9;f7e6?Sa$Tz-kZIB(Pn-BI za8F&*2822bS4_hfQb_1vH9~^#hb+VgCuqIHF!6aV$>8gibw}V|<6e1qD9l?t9P-xX z5cIapyfYn&tN|#<+bZ}(91O9Fl0lSYY(k39I*nHGwocs&BGx*J6YTMJNh*X`t~I9th|(a7$&cv^_q|=?>A5+`j447Ddb`==U^C_$D(P;M zL(CX{fz?}PlS9pz5-RGUNzX7drXO^8!*=Q@GiETF$lKEm& zQd|9y%a}<7uce%oq=Ib+Acg#w6n|r>~TFqdD ze`=s7JS@|l$3IP1M=#VR27za4=qzph8fN$&NCjhNW)S_YU=Y;%*1#^$RrUDeymk3x zVB=ymaBg5!CE`{Qya|kny-9mehI$BGp8OC9mz9hgPJwZ;&w}t-|3P&IChEG4wTdyb z1SV-Bm|qPofh*z;u%fr-Kame=vZl=Ytue?Om>T;y(o(E5@F6fw6RD{a=8iW4GZM4l zP`dRVRm@Bq4(UwoU0{~>E@b#V#}M+Y41EZR0{$A3?*kOz*^tLy{4GepK=$451!HUI zEE&^6V0?tJ>DivkZ>KcA6aPxQ4POFS{Luh!D1pD(WLVpAOU#><_!jEQWiI#nlVpNQFA+WBl_O!Xh_c|x%?^N##JrQ6Ji=% zk0!Q$gmp0u6Cc#(@2w9aqzRYxD(WaEOA|h85LzuJTN>*6cn~>uLs?hkg2>gK9McSH zEvAts(yh->3o&_`$h2Bvh8&SDBR zQDXQGv(5gKxfWJ8K7xsGLQL}oC@vLmR~s=c;yHmD)=xReQWU3<-qczKKVyoMcEY!I z*8QlEn3gFEL3FZ0=yx%#beW}ANg9X}O_arqEe6qA+gYbn#nh*YHa0m>#aQSXF>N(z zUZ!HcKru1xZ1QpyqgYAy+NPB?b%?EbvGuKm`=KoVb%$(9x{0U}HU$fzlRL$R= z%8VP?1AW#?!;}8VRb17`CLB8Ncl$Tec8H{&(l%JUy5-T z-`JW@(O`TNE_101ijDX}M>pb4ZRM#8S{m`qbljJE4dTspJl60nM@NirVQod`y3}AV z;_VckbDgIuZOZ^Ld!L2$Y?opjE$9UCtbQYi5ioWGn zT`{W!)O%16qxjrWtXhJGic>G5GU8QROe=NNqsSXnSE9)i)YBM;iE0ZfHc7QZ_efU# z@-e*`z7{AlzOQux*7@?ls#6er99jcgp%j~}7m>RzJ6Dz!9LEm}S-B`DI6m$GgbZse z91Kp-gqb>L;shf&Q4`AWt%c&?BREJYrEcKduhzjt zuX>Qvnc`1x`qk(7A5eUJFkT%)1tqH4(3Yh3Kt5T$iHb;3SHbW)st>wSP`!pOnV>d7 zK1Mx)|FP(X$1|CH)N{e=*D%q+y>g%I_(u9@^AKL3g=5Z&SqK+If_dc~9pMxdv6JCcG{6ZF+Uuk@iH zl8rzX#(?h)v}&NYMXP(WURJ;&7tM0%7~8?ce@0*wn1M<7*PE_zYh;V)O;UiY8BDg=?0%mkP9d;y4TP56ue zyQuGPsH3DDi(kH~%f-cRy5xfRE+Eto=+~GoQrL8tG-T7|WJ8hq4fCu+S;hzc=O9r$Caoyeh72mH4T-*4b2cd+_Ka-=kj*I(0m7WIX1qo9#Ym4k7i z)DCoskop>9Hp}q2F+rr{S&NY`zy;AZGj%|`{z>g#5H-|`=&+{R3zL=V*;E&|9Fu$M zQ0uRe;!-b(=fjNZrpC;%5iXhPOKcr5ZOn&I>ZR6KfS#$3`Z*(ZoH>7nk-AS$svT$J zt<%)U^cJkwldv}R@gS!q!*{e8#1mFJGKg8vdJ<^Ghu8oaY9wS$brVFDszm>_)H`TX zms*Zu-O7)#>QTRkI0LOms!!dE|9*8nJEi*6#kph^>LaMeG{>-1*PtR2)unJaNqyIf zv(bZ?##7YwC@NLO!mV`WLaw^%ENVPMwMS|_bti^Yruq;%>#JX2Nl48FKTExXmd#e5 zqQo4v1DzvRC1d7mr1-;#c`Arf8mkT{H(zBVUZD5`N=?)cV17FOd?Z@p9{X7S$YUerb(wG*7asvd?yKXo~J zUVk+JO)^NeM|`l_fth}YDnth#s{EL_hp7_iAF0lQe~B85x*DY(MCqf|OtjY+bvrD- zR9%j~dzs=7^IWbrLQlDR3bj2}ExCym1-CM&r!d?i@Ay)YMQ5B z#{b2NKR&obtwDUL;tz*Zs7|nOnVOH0d!72InPDtf^^kXk8h`1e0RVG^D7Nua-Ds=@?SF1Yc4`M%22{{}jLxZP0s zDBCoOzlNi!BTS2ZdqiyNEYr{5JMWZ;lIELwXJmAW!`Qsq)N_xk({Plsz>GTp9X_LY zF6uk=8q?~4Om&&lSBbupRzG+%;(^=nuhmBUbMc=MU?0wO!8s!>JANQKrCR6#p&Fvj zP4yOhRO$<~i=~dE54+U&;Jek0knyPBV6|8EE#YXo1by4DIv^fUhtP{+)Wc|nSoJA1 z#HrQjnepl&v~?YojM@mQKB(aY)d8GD)fqLGq{=Z;k`+GznWA>1tW?F%;iai6NT#d1 ziaFK>qt9okrKtaU>UGp)raFMWT3?l-&ood^V-{+tT0lccJq-CQbrL-!Td{I;)Y=fo z-QB3gMv6adn5V9SyNy*{l$EcRp&kmd5-3d;i3Zj&z>JeyYrd~yFX|6a8wNPI` zPm#(&iN(r?twBpQ9PQRh&BpjGQE$QP*6LmO*hXc++O}#oMsz#nYQ$050akTTXCc{9 z^+#Xrr1%Q&Me17U?5x_tqb`acDJ@lBp{%ZoKk(YE(ZA55Mn$3*6~qo=`1re>X;)cW zP(NAeX$yFQXuSiaY1agALwy+eIUx`Wb&oK&<|o6xv}fYxA(bDkG(L}7( zA4>gm_0<79HGq2b&x=h&dCB(Gf%&@orW?M-=qUcHtlbdL8kQd7hX<`U3enJ6=`7o@ z&ftG~j=r3dX}tG_{(bj?(ir(ZXth z_De6&L`&;UYHOkwn|9W0^yhSY%il@wP}1!^f2rP~q}!YRvea3##~SI)<7dGAUe*@O zU+FE9xSsa5j-Z>Q7o~7H?qi)nTc;N%b4~9X^8xx@ddn29gI2kU@xsUSRw-Oat??>` z-^@&JYd6Xy74tFGbh61Sl*M06ProRW^)ko^{0E)WcbK|6TlJArw+#HO(z=;^+FjRM z-THRDrOqxk>NZU0c~55Q?3PB|kdEi-x~ZEbb@Or|bl4~3MbQX0g-Fh zjdr?jBkgo2ZGPQ6ZN55Y#yr^uf{kr^Pna?HVSv}ox5<-cOnw%~0-O8_7Y~}FW$HGu zhQsW-v^lFZqyD{)?HLWE&Dnk#A#G!(MH@5hle>_Wg>IUWt90geFeI+C#}i{$e+p z$Vfb(IW8k{69+S{h9|CT#fZm9dIP+=tU z6SyecNaQPE3vXjb9{;Xy*nJi#2@WQC^0}2V1(hDi@u&&VX;>G zq`>{m_t#?3*-cWvMLaLRsLdEsINyO@Qw>DLD%A-s6s(d21Q z>l`hZq*W)KMk_b$;Nj1z+rm0_mN^0(+VMYPaD)aY&W8YlEwlvoySRkAXn+ymb=0KW z;D4Rbp8F`Z627_UpldhM?HI|vM*MS_T(Wv-JD#E_=WHYXO4yOMMswdJmt`68FQ9*= z-CBpmeOAMLBnXp+YmW(i9pRp#8}xM<*Ha9(2}*<5THclN#<$jIf5o zwQOk(Hx?bf;TTU(wC}|=+)q(tcAG}5$?4=)B4Wh9jMB2(H6-`C2sf!cjLvz?v(3rv z;sqMr2zE>Kn}LFtnvXM`|BS$RR6$Y!sd7hzwW+xrZLYocs94ANr)7?j(U$cU1D$vC>&j|3sTheFf8R;{! z0~l_$4La5sjb{V~p&jCHfMJaqxp#w6M4`KBD7&2QlYNb(@fa<2yLoy>G%#iaVqs*w zg|QZYAerM}9Mk#F2+U@|!_lU>7kQSGUE?50BfupyX$%}pACbM00-7DaCkK6VZak}M zFS+&r{5ytD{BF+&2RIjak1Z#3d()10M#3h?LYUE0m~%dkqvFVI{sW>1^juOsTH zomrm@-O=tvsm4Xc(2$dCYT*(m&A4be+4XI9-v~Rt0)FIOm&nuRX%5$=8}b_TGvlIc zxS0C78RU7zDhlX-OmnRTX#}o8LV($m8l!jR4)pA!R84h}Gy+@^K< zKg7PgNcX(Y$<^IYUmA+9hRaFQb<)pHk`dp&6-MJK?OQH7d{l=yw@Qtqi?Qy6?(}q| z6kEX_m+>EAJD;{qs~zkl8S(8fveI@YaJIXmhWk63Ez~BCH&Cx5w`R7^M;3;eM8BcwIRm+)?hMXKm}89s1UD=&IB_3A9@8A;-)22%tQ+_SMTHslQjbCbI_>om3tOayVs0Q8pF8=JFi_fS@5?4wwOK`hY3 zEEHnit}bj1dnX=2hFB>3Z@NLkE&n6MWuvc;XqViHzE$yRs9e8fuwBmtc`{h{P2f2gH zk&uge7%cI2m^+8KlPGWGcEI8o(rtDFNOSX8Oh$Ed<%ZlPG@~8ZB?ul?OSY}LKj_}% zd7(SkRy7XvW#lbGQH^Zge9&{r;|-fUcQQSx0KJ4fx>w-V=QOK9--M8YCCKowH4EMG z9QyZzzLz{UU2}IDZGHmbG4j|pMeYV{n}eXAM@Xi%y+@!w^+SY1q$B)6e^T@Cf3R6( znnTpJhz_;Z4)d65F;2xHd@+PM)CP+1H8^ns-{7ERX3%J6G?Vd_YY$}X-uIR3qMBy@ z$~96q^Nm<>&97Zuc(1M`p#mfPlq-WXK{lSJGR)JibWR%V%czq5uHPcs_PdI;wpr|o z`(1swHpISyCInGlqwV=i0y=%gx#|6!^lp;=z`5!DCEY(6>C0hAv{%>;(4U=1 zG7T26+f_Fe&8K~N7p7M_zEmOd1wsm?A`a~Zao(DOLq-PM;AuomqdopV;;MHgRkQxT zgQind&HDch5q@zjg;J45H~`|js?i9Be;xkW&aiPX5i~;2<~2zCm?(m|na^w4bID*= z3wA<&tIUItrf0^%u09+x9l_uuN@)Wykj=raah!xFg26{$(hju*bBL>m%lLC(JcFR8 zqG2vQL%$FDp9sM!^y?8WeIFYA(G4#R?y*|J2G;i4a*TGDJNE3^vkejRnMHy)Nvwx^Xrg0%jN?O)r7Ft-+i%*Mq^& zUZv?}?GdYpHTonN`^emkdCYvo>PsdcICup?*XUk6K8Gea0h*`U!Mzykk6G#5rC4h> zEcHyoKzqv4*Dczjl^Y>=`V^ph*}R3I=OMJlQ#8hP2wRcnS%V?jdhgz#5!JYCQ`UbT6rL7ybAdp@RRo0s55S4Hq#-3mXyVDs`p z=aR>te|g>JbphRxysz4zQElGEp!ww~&r0k{-n4m(K~Ev?AF%l?ORw|qfqs#^U9j(v z&Fg}-h!;RTH=x{aB`@e}$lDaaPqkR-Y@79!1EkuDn~t)9XA#nYwgOV{szeD zOfgYwv=3bb(=8G?3cre!tQT>^-3AF9xo-H!fh0K%cQ+((;5De7z{QK>xNYqOJmscy z42e##$~xy7?#Ys8#vhaBA&Hi){6mtz0!g$jVwYBC1#&S2&ac0gU`xRQ89m{kxQ ziYczKE19Qt*4m1tp3cyj@6tnNH7e{D1WzM$)21%nB{zV+le{C@nBHvOL!j>??`c1- zqS(AwK);0Go{55af>eUSYm7q4hI<~8ct+LRPNF%6dl8sCE4wV3xk@DGMlqA01#>jI zocnu3cxty#ins;^4c4pY5d3ZuJ`FHb1NU2KDon&&Fx)&FWiH;YfnnBK{8-BW&X&9p zeUJ9x9DF!BJ0hm>6#nnGQU+qu^o|1eeK`Ief_ET@V~FsfgA_`|O$0}GJ$A8kx*lg@ ztkh;JBxv1(5HXFH@&9=%X(w?dUeqYG3qfjU<=dlY<5#=ob~82h13 z`@CVP!8>`zonS^0+p^hpU{??X9!9xgF*MdsSU;wcsgkB1{M%r13hfx!&r^ znY|c{W@HXTiC_+8wlEmo5Ioz_DK_dX8I$8wTs~cA$0wtA|7CNbLmJpa;}< zwG%L%>xsz&*X*h@+@;`gX3U7g5As?E)E-h{Xg*`&;cc4ZO5djOU{wALUTe-M zoF866-wSdlej3kc==JrzC3>m+LFsYd8W~z3=%w;Uo5u?;{OFNhDywbYwV>yd$7S&+ zo3{}(uOR8=^Jkm)D(C~`acTQi>3M`dtaFS!E^WWrJbrYiJ3{cPESxl2GAF&dB)AfE zqC+2AqR+irSo+-SR>-eJ$lHOM8G+NuU=qedu@#DJ9FkE$8!Md?9KT-kAc7|sytX#4 z3iOBMjljTbZ`I@KSAcB{FL`)k(C8g(-X)+1Be?l|Eyob=@i}A2-3CmKp@y*FJmbjC z@5}ORt4nk`hZrU&YzF;Y<#?ftdF_p$9)5ax<2Pna;~v=cgUZ_n1$uc~4qKKX=;iG; zL{=lDP)e4!4NLvp2c0ty*r%ZO@-`ER^y3xVBx~(^OR(C4Nk91fXKg>2ek;;BO!&iE zQR#*o50L6%Qnz-(Uy#71uVw87o^Wxo#4A|{=bxUGzOf#M^s%!jC$r`UX6YbO=+6#HpJo}^-) zVr#_>kmY=e`(yCBO#2l2Rp?^>l~e3NSa|6kx{(MRKUZK#M4&_j0;rZK4MQCP|L^e2 zIm>o-hW1HzsrCq~s_~I4eG!|0-n<0k`2d;r<}F0{1X&8DYFz45+a-HPNJ zLbpXN=*@!r0GKy`nQJqheX*_?Y$n{VA)P0dJ)+Zb2}}z-yTnL73ISd=OFktL|7ED{ zsZhz9j+z(UWe{NbE1dE<&QY1V{0E}-%Vvh@W021B{~nz#`$UXkBYCD2n|z%_+*=W0 z`QJ&Fs9EJNNaC#G!E{0Mu0?H4g1OGD!V7)&tm5a$;2jBw@zSzsUs^VDze8*6LU(~# z$Y^dp)XrJ=cc~6s_s>A!TLitt@3xnCANVc=eOYsl(w8;sfv$@X~FXK}{k0+0F*egme zzqf#1h7jb*{`;zC$>w?f2M&E`Nd~V^zerE@WxtP=e;@Ww-fD2^=WYb=Ne~|(@(ziQ zK%7P7ClZw)vQded2;PGrIwH~@A%)iv)7>F#EVj^N?NP)-$e9D*sJwp}iBdKLmko2;LSTUPOeyD(cM!@oz-lA&~;&6e7n+ z_&}uBLAOQl{sOhF5NUzXnePInP<_kZlo^hH7lYpqq0Lwj1xUIS#iow~aRazlA^6L| z9%t)SqfBG8q5=1zd9+OPE>*~?q!u0Dg z+&4ggT3@Nr>fQ++i~c}(DBk^7@OUvTfIecI#EwmMk*nFSF2QLPW?wGE9vH?gMAK+- zIk~Yn89ei%#DH@oaEjv06#k6!I_JjHrnf8$?TogzPGC~o=5w^!CsVdWH_7&>lZ|IR z10-9-Bc3Qb1{h5XiZSrjKX5_PzT7@l6|kem4o5a~s?xWVV)cc@smi|gu5YnSQ_b`Z z6MeI1n(E8lWURjCHBC+6nUQ_xXSyw>Zi}L;uClca<0;E zZIvYO?0tpOXYUC-b6;r>u>_vA-(>Hi6L?i@wLN4L?!feYt4cfzGZJ_fzgA?XqOjYA z-zOcv>uu}729?i?9YMLJ&5$Pvw`h{>E2p@u3SH*rce^`tRHACeD&h10Pb1jpCW)#G z&rK@9coRWST*cA+9S3Ywg~}{(m9kIa?(er^+`H zsy`i!t-Dsu|5UBq4O(Eld4EUB257ny!Fw9SUl4f!Auh&I{mlhcUjo(hk%#+yrT?S; zj2L(0o2hyoQXYk-JqX_GLA-#-a|m%;KxnIx>jGAfj@shwf;M}y6 zxzo^sZ=5S|NkqWe;(dLtz-ULn9~KQ!>PI<=M#e7KSqc+PV+!Ol-SsA;^}Mfw%a>bT zMeyzi@g5@oLP()h+`Hgt=lWgHxlyR43^un5A_@-&W5l>K|4!v>YCe zZ1R>``6gsD>$!7uTcN+zu9PT7|MOq5-QcV^+u_<>0P0) z0JB&Llr^RHOb}xb;SX(l>ww?|r$r>p*;m$TuXe2N92%H-M1BEa?w}lM5<@fSF+uG`|V{H>D`=3SG?B#c^|Wq+)UU zQbag&w?Rn11;h|U`jNN`#B@X^lh_90dPJ6z*aPBOM4m*5+YbWQDHrQ2kvs{&1$Gp- zTIIAxiTWz%yO4VaL0{$k0+CMM<+b5KP+7AMV~R7} zzaoj(h9}xdocD0{25r3dx-goV2qqbaMNap8M0 zHZU&UmfMUBynp?DRpyPU=UDx@yB+Yd=|p4b|=7P8fl$s?EhV z4Kt74ahYX?`zSoB155gxlUfFA+|WxsLwRoH{|l&Zuv0*VxYmBYh!>?=(G3rypDp2bAk(( zD$HhOXza_g;MzxKD?V^#Z-PHEdvm8}KUwmbnZReV5)R<9*q3GspW4dS&+$~5`t<_6 z(>-SDYt-1^V8Q3)g(48l&0nB|G+n}*W;>Sf6K0bCBG`8t-ZcAhqnVk48b;82%C~J@ zeAtjLA?PjHJEneAiqFq2L}-gk+XkP>d=%>8U`*uHJEy6BOx561m-=2kAILmxOWBth z*lGMtke`o!v2s8gxo@|?WTNdJr0t&7!?Am>*`9XajbiUWuW6u2?C2PF?6}j^4-Zs8c9ElFgRSEp(06Mcb>YhzQ$PAk9RUP$^U{cpHKsoE z`YU9gbabqn@#-~()W-(g`n$Wm8~No4eJ$x(S*C1 z6*W3+JG?y|Usl*UnnSh;g4S_^t)nmKo?6GZEx8j(;4|zzP&@FYZ$!ruyFMmEc7mg$ z!q#y;=w;N=Vi_t4~m}Iu$<7VcdB0d~7$?VN%qs+lYUN9$_WBB-# zImBo&qAu>9>il*!yzb<`ERvt!YPiho`3?0CF1j9_@G^6ZriP$jVBqyIQ&|*`F$m`7 zJ8(77?pr-f{e0mAu=QTYhu*diuYo>D9um79x!K+*Tt-jV^ovo<-_& z*<_fvdJxjDJF<5@?uh~pJ!l?Gq5tTS<@VRke-@S&Fa;MGIWt=`%8 zwh8DwgdFPOW9Kqb<;hW_MOV0i-!s5rm$W2OQn9IT>-9wL?g+Z1VzVVn8V9-@L6=lw zmoy9XG=vM5v;hT#qPom?k&;4YWBPO}a<4>4;|DLyklCJJym%bpVFX=Nj$PEpppPKr z6{2q)gPQCq6R-!!H|+;c`=f7YUyT-f(bfIBOfFgG=G!n~**(N>&m4X*?g3T7LGG|mZN4ri~M3C3gu&lVIKW9mD;w}M_p9-sV-vyIyZn(x6RgQd53Ih_zu z;7HXwS5^xTgZC8D^!-jef{RX4U#~|`=_dXN$%hacjKwzJv6X zHjH10T0ow*_UUFc_EXUBAk?F=f7P}YVUcK#Q15CtF1KpdMIhUg^&*zI{Ta+S0%U)( zzC-tXR!i~G{l#QGmyeTN&AJ=pda`K!a}AjBDa0Qoi;pfpub*750{IqMtewBm{tmi;Jh0yvn6bIjod}iRM za=vT8S3=%L+F=Cu+eqUpAtusM=U5iGT+Ktudr09cB&l|awHDvV@_!B{-!_4$W*Gj1 z;PCAcJ2P&nZW@l#z%&g7L;sPq7Wuu8gLww!abNG<0pctozagYhDDDMt)Y@Tw^uWm3 zMbu`y80^6_A=3^K3$LZ(%scrw_1*|(0CSTM!Mg}VDk6McHHAWP>qKwq`Sr3mzCN$t zI*IM?IKef!7~6C1^m#Kk`38vaU5C=!%*G-Mo;>cW-t@m6r=%GI%f4@Y)UlkFO_vZ1bWw z979aJ{mJ!YP^8(SXJq9ofHmv__I%5pr{~)SxH^G&;r)JG-$$w}hReXShvIHMGv%Q6 z8zMB|g-3ID32UPibSDJeyZ7qeeJRLG5OTPro@cTxEWyy*R#VKeNHN=*aC9$3-m4HA z@RK{{wsvPBdKc*R2)dZR=wcoR$xj?zu$a-v$7aRbe9*Ib{6NQ>4Y@3)5_#W5s6S&0 z7LN_Z^yVATCp2#?X3`Cv$&10z^CIY?H|e7DLGlHP9BMwFhYL{uw<1kelh-0e->NrA zJ&?C6LW2(Ru8PEu$Wi`b93<^$HNu+DcYNn z_XdOp{O*yt;v!b$L!h@I=wfcv#T*2A03nB3&gV@LwigSLCf;m_6thql^C|Lvh|qu+ zcFl#lnBPJFjG&8Itc$4!EolfB^kzo3Va#SRc6*(T6f--A?bQx>OAs2|kJ>V4x8ufb zIOxF$x|q4Tm^mP4B3!6#My+j)>|^vhV=N3>P<6cG)qvmSGsozzz7`s8LFmer=yH8t z^aRK~2<`xK@Ex=X$b-32HZ$hns8><^LC8D<8P1&?Z_VFA&ODXI4#kU(`c8$)Q+@ed zRxJ03AVzVMn0=L@@>MF|1TdQKXpGH*%Hk_tyx?c&3aS1zxk74;lPlZF^#Epo43*CJ zqj?R|&Xu9M*W}7jL!4ZhPOg$VxQ?YV-o@DFW9D|Qc-6BeSG>B|$rW^Rtxm*+3saZH zd(U>R&&{Z^J~ty}{Xgp71-`DTOdsC+oU>2U^xpJNFG+f((4;K|N@<}~+aRff&k(j|;F5ZQ4xlZy|$GJ}OH-@>^E7#JB#n^FYuk*t` z^>6tJa+_JreA2{JQjS$2{!ceG_@qf|Hs}icKW?9Q7ggc!ZlS*lBjqQ^aeHy0ylCnQ zy}gz-t_AZG@ZS}B`^l_$0rV-Z&^!KTh1R0b4}t5=#f9?vkt_6O6YjZSzCSATW|Q$p zKws|)z2$#aXblRT1pn;1;zD`X(-nGM4O{vEnBNx_dR;SH`X8Xb=?cB!e^%&9i0+5* zM3=EpIxeedA(pLVNpeh-iL_~8uT-@;wSAwNRUYvs5HjsHV_17c1EyeRyi^frjA@o*LX zFCJ3I-Ew}F<7)~Tv96x?8=t#KBdSAQw<7gN@ZWg-01uDi|9GZaOoo%lsJ;?D68=vj z!?W?wNrH^Ofrkh2KNttr{Jr3%o18`5i!e-G-th>#ISw0Fg|K7F5xE2pyjl66A_ox$ zhTaO;jc-R`^k>29SWFal4*H74Bu2b9Zo8t6?N#p4Xj+j~@MfNmD9+}v)k$N4gQ!l# z45hi>>7pZ3Z+lFu*B*o07x=%r5B8b=SO0bd&T{bow5#C&>=}aV+F;v&W$O8uW-{}< z?8vE5hwKPEEE{(Gu;Yd`lr2R7e)ir_h9<7{&-33`=HoHHgh?v=;{&G2Onk6*B6=b4 z7KP8)D~frbmM$wgdlX*tm?O7g$x=oPI|EMF@W5p#D(gMNx`LQ+ zn%b63H(f<1!)7F9fXR54H*DAm!?GAI6=nXgVaBjxC^=T5=tx@dKiDG|`jgq#Syg^0 zqKXl7Cy(*R=2uQS+hjc3q=mkjLwS(T+%hB%IhQa5uObRNr=biz35~%|;j<%`L&@e# z$WB$*cS-I?#IeJUtH>7@ePnU1$}4;pwjdHL86`wp<&tNp4lJjiMraY10QE@DvoI=BL_G#5Q*0qcHK<0nA+i5x1K{(n%fjMC}{&W zxc%}S76K2rTQKwo%Lt6*t z@2P_3CCAcfvGgf*R5(8qHrqDzL6GKG&I@oF7>q29ewcn6LQ5Do#K%mP%Z2GGk*@Mm z-{0u*<#oy&2U<$Zo-Dv`&EchM*R)~lrG!D9{x%P9?{klvy)5%9X=dSVNb55xY6PDZ z`R6cj&NhD&^TSK`miSxn%}<^WId3}ZGQ9#ns)VWHbm~5;(>O$qyVCbJ<*xLv!7Q1( z#(x4-m@2ILSY#iIWNk=x73SF7RZP~FPBt39(j1Lsn;o|n#|_i6J}Pt~+B^}-Ho9c3 zE*adS#3zq_Lgn+Q(%5o*&0mbKWh?Quwh>=Dde9c%w-yhFn4?FN1E+lp^-A0$Lp?u# zxA6>6f9&m8CWe$!cz(%4cr075&-hmsHSfyIb!;BaK%i9|jQAMj;Y@F1GM2dOZ88pS|X#^K-BJ zpUv3A!~C&US#L+~#+KKRM=K3vW-4tImYE9d8)_rH!5uecQXEsAf!YgZBc zX9aJ!V3Xec2!2b!y>ake2!2h$XUD;}AovXz>}n8y=XnO0!w7E94WEN1&EeQzd?udG zywX+eV;maI(3ktL>zTXHzn|3o{&z^d?Eenn`XlD4C$Sz!xsICyrJu8uk4vwn3B20B z$NpybqCK`}Ga@BdqoHcWQ+RCjH+w$jMaYCC9w=NdKV+|W%~}+g ztDJ=BG|+j5!J7^(L394wxml@>)l zWT~tCQ*%%IzwiNP~{ej&IH>&ocnMtmsyy{!)83uSySLu{tdo@!$xD~%DbVQSE76glbnK_ zB~|$??&(_pT0g)u0lf~m zzso}DMCKo(COwvWD2N1?|B1yKpG$pzE2d-2!_H|?{x>XzO+8*ZYPipQ4#mnE%tWp2QbA}jmkU8*Yhk=r`)byeot4B*;iDy12&S`QzaS#+E6q1;kz;5c`p z(N+qV3?<}0+~gNMLd>3cjt%yiB$(bk8o&ILfE?b|c&4|{gP<-)t@P~TpRxEnYI42CU~58`}R;2g{mPO-H}WWIWusx1(JWvh^jiJ->Gc>ASR7Laz$tn zgB*U1s{-**6eXE~e^EzUDb7vh#4*xT>Qr>%sk=b#`WOuw2Tk&mf3G!kQ_u_`WU|-%RQ0H?t?&|$RPu|z%rx~pJLoj z0UI_yf1MRFmMt1Pg=%+i<^h{eSXB6twwPhV6uCKfaRx(nbMEroLohzMr-Nq#z}vya z`Dj{=vObHaoQJ)DT$QcC-}3LnAj;jBd6@n3aONFS?_{t}Y0h1leIOfJ*w-yzC+y^N z{)?G#ai!24?nd8c5%v@oCX|t*9i38%uZ73pt9C8Ep7gQ6YRko`x)9 zC(S4~qUi08miOkB7=?(eU-AYbM!E=CN~2tkl~DXRhfyvEf50&*%3&09z(YhtN$eq# zauJL1I6R6l3K8r!e)8wzDd(+5$6t==8}MxAE~>%ZxyJzqr`zb#ZFK22x^(doc-;PtRs<%DJbTa<}F%P;SlL zsen6kpJKqLa(5|!O>#XQau2z3Xjwh%ffBF>X0TD0P7hbwTG!@k-R5eIF0~4WT$8CF z%(l2SUY@_fln1*ME8cT+fA+7%;t~%}WNt>Gc(?_VH6KhCdHw_>=T%~P^$MIYEU#Fn zFw{wa5pny%IMl*&xY`{Y%39?opyoNeEN?TGk+;*vx=((Ig>#JI&uMSXosGe_)fr9~ zb86ZYQg! z^L#OL4)67c37N1A_1LltkMs!m3zEF_mrF;|T=O^QvZ3p*)dKyIk|Ps4A!-F7N^)|p zWGqB7c6@eE+ikh=6B28S+=L_1NtV)b{{4AeL3y4bs#AxceM3fvW{C05Un)s%M7eDE zR!O!HTaDVSZa`BSENODx!}NK&vD{-kIhVJspL!&%Z%j0UsX~s{bGf8QU=7|q^8e$U z<_VX+OKlI1OxL#LU2>WbiXsy^4`!Q?(7}=EoVGS~*LLMmFol$$D3alk=#B9ZQ^6sp zCaaB;x4$Emr76L;Q>y80+9a1A*?NC;k}YNf<|)B=V+nsF-QSG-`bR*0vnoeP{~Lx0rYI*jbt#6^(&fqWm!E*}6ILR8Wo@D+ zQ2|phw5BYDKe6<9Bs|{ohV_9LhkH-7oerW5g(^76h`|iPpX*A<&Nsm*qTn{!4wqXzWApjEdlYanT zoP4+DPP>jBdy|i4&ekHmv4r|kZ$093u6&6bM9tXMdDX~Q{kKWJ4b?y;uFTw-VWK-T zce6Y1&Y*MKT<4w)&*garK97z-;E$jloN!B%CH-&foVhGdT5HQu=4Cz{0C+`i4dKE) zR0-bbDTur|+(d?mzGIne(jS+(rZIQ+`S_;WI}Z`zev3Ura5=w(ooTxZaI)<=bo~(y zS=*85LDpG83Nr&f<@a9&8x7sFE0Z)bZCR4n(2Pt~`P}@E$JFaY4eBSLN zacamMgMENy+!|QhhOaH1m=+KH$(JKMhu>N?=SI-7m(Rr0OsuAIM^@u$;c|STzRkHB zJB;V)eG`1vT-!F-e@f@z&;Ko!ZQw~ao|Otem+FDD1V5B1KktSYSgd;`I3Ia+g&#LM z<9tuJV0-^2ANdw+ex6gi`0g8iE_PrS{P}3UG>|*f{Ll{Y6VhS4=_|rRyg+t@i~?u4a=Fpta^+3Amb2Y2l5^h5TpfN@ z{xKwnJCz$gHaBj97u;)PCWnpqV7WctlgZr^;4RX@Jx1Q==N`%3A9(gkUW^kvdhmj` zEplz{)$HAvwwK!4A16Jfxsi@9-`0Sgcr5C@fafjP0nH6Z8Qc!bc`Z2le%!}f@UL;5Ea{D&-eH^Ab9{Kj7#t+Hy*j%l6@Y3js$)$`*u#?evHM|l^m1X-jlll z=W;00vX0~?HD2dxL|v}=Y7lOF^!^-5csPe zCc@ow&O-FDk`GX9_NN0_i-jy|Bx^YOQnt9!b)_w3u*Q+-x<=gzLdf$D*d z_MR@Us=B+kqi1ht*P-L9tE%{~qp!cqtKQYOyQ{jrXK!^?M_=!b?w!@E`jBtqKv#eD z&Yr&Q?LDo7ef{k_yQ&AecW&<+9H`pU-!}mM1B2~7J=G)@4EFW)bnI&H?p@H+-Me>x zb$kEr1-*T}T?@L}w|7TX+1=i;tGoCA%@PL=4E#URJ_x;fXGce>or{jDI;v_>*xdg? zAFwZWcjE`I2X~uw(ZRt*y`AVyK6Z8w?CEJgV2}OnXB~p+-^$H;Fzb%K-ogJa>wg#j z?iG8N*8aT}`(J2V$b$I4P#Y6l2Ne8&GWNnc{5^8)-i;yn_awv!{JYYj-Bhly{Y3V8 zSf^z8z+fjd{_iRL5KNWX>)BT@+f>y-+XV_gGb#)W9_Z;R?Ck2T+C_J((Al-4eQ(cT zVer77t^tH$Zbq8U?%qKV@F(z$BzVT!2`s{7@JPgPPk;Bm_Q5X4PGKEA?E?daI0mK^ zF`XD2NCxKx1X~UQzZ3*v)l8(vJcQ8p{{Hp@NP~OQ%3avLmsNomW6@phAn;Qe5Iuc6 zqvwvkp1%HwvTiKk$L&!@Q<_9+@FvNj2MJuW2D|pNZjRXA-Ps)xCcTL2+Sg@`NK~+= zeR~%f;fIi6ov9whA?^LFj7!2kF>xUT{eesfiJo2m?cx>>Vyr2MgS*HIJHBJWOogyI zj?M0_-AFptVt2O>?gHUN#S-`Qv9F`@!me=v1L(NkK?)kz=Us)I+PEysx9{!l8C=la zdjcn1?91TqNAn?jd#N7;W#a-rKPot~CK$Uo7&?EAB-;#W^D_GO%G-*42E733_A>wmH7MWnOr7c z#XR|P_@kh*2go7=azuV!FbY|ZV)XK0OnyahJjk;0V0^whSW2e(ir^UFn0#e0Z(=ai z^5ZW@S$=+3A!<%grliLjRtHDp4|iqY0pv1qJ8=SzcB0;6f+-ct*&39Oc6>3DO{K); z(Ksa%u0W=;gHql8ccsEMR|hLthZ(`b3Rj!sqiQ;lxX@V$U0^k;!l^IPS1`9#e}QE<5nQXv z8EE`C@)ig45qK;Lsj%-E)xiSPYC57Sf(7|;;iIcyMaD0Z{Wokll==R+G7gID*^tw) zd@Y7jSul)Ba}+|y2f-0wH{S->(EN&gRlYjahq$Q@)g>RKA4#2ysNRIx z!5H*wzPc>@1QYTjg7M3OY3S!HlxQmKK`^bFogPff<1%G1Jv*#C7`G51mBIA<$Y6Z- z>~%<6x}1F%98qOMG1j8zhecXcUBRL_T!UaiRZ)8{9~!1A4~DEjqgIrSr|~H-XD3%n zfgnOudK!b~nrRxE-x@_tL)6fG;gI2nRY7yJs0nmyM-}YO#O&Q?qeS#V9;OXO1V!a6 z`h~y`X5{@UCLQ_|l1|D#Qk1kh7|wbjHMH-mNPQSc@|===`0O1BJ}moWKn*y_GCvq+ z&YtRLF*GqQ^FGo|q$(jT8C6@Iu8qA@>d2!Adw*7XhQR|xC_6WRc@{-%g;V6U!Bj6Tb}KyqAr{gEJvTrK0a919n7Xm zRR+rtFmuK_Jf9fAc(FYz@)LqdQ-h(ig2Sc5CQ6m&Q`@SgMh;Baslk>85SA3il0F)KK7dT{uW2&o=#6IM2RI){2Tza^i& z;C+5szC2%jiuJ~K&kZ#MomG*&JG;d?`FrQG3#+YnAkI%?grPq%y~5a23^T0$vruZ~ zieyM7LT0WADj8o9%w(2@N4W%tBWNKe`C)n1x;kLy<&aap8kNpx$6(UU_LZX!W6CRo z#TB4>D3Z!x)|6oAIE<7L9KNW=_+T+bJ(D#8Rv4m^BbNsg5i+zUn8>pBIx2rnqjLbF z?pxuSkE(1(Uv!M)@qF+!9q~PpwLt6PwkMEjA}Vj%o&l-D(OuiM^M-MGjbOr9V3ajWG9%HJimJ z%nLOf$>XT?`Rs)UXtRc7-@!1)Shc4Ab${4&M2*P)DbEoyJbUSZs$hzFHY_ury%@}C zxc%&<{?*8w{lodoE&rd3^Z!}-FTs=(=9is)c}P{+dYGs@olAcmzA~n?=Bt{^v@WP! z9L#1cOcYdP9twPqwRS{#FfTiZ_{!kqs-U(im^Xb!FsULqxiXkUV^`BI2|7IvCZ^H61LlH5P#Mgh9!zE-6#-m9AScPQfZ2D>M`xo7m!6Z5 zbVc@$IcJMLa88jedW(jt*cM^TL{`a-o0*ZFnpqSFixgBwag{}Jv|aNQw;-5T6h}eN ztq$fnr*AHcpHm&obtF8)^5F35V2&eUi_PjCPAgPt7LW2-VFS7bHncpbt`2J4Acu(! z%Bq5zc@zYC<3#qR6o3X}XSt2$@`?Z>cC>TEsxkOy%?RLWB$-gO*%2@gWj0xGC4)&D zfyYb?=nxKD6jV(MCUKH;7Ux(N#hNX2MsM{ITtKbH$_HLIe2;O+w4?&Ypek5`M_9nJ z05^nDz0m<2J$sxHbT}^kgsNbM0WALt=pz(v#5g!qR0WH`Fhjd^Vi}~L9SWV#o`q?;yKKd-XvMn@ zlg-flGV6~8=h{5ElkN4vsazN&dUBKhsF1JSO(5o^lxhn*IO&heX9zpD}$1%z_f}h z^~Dy)ig00coRb$=jYfUh#pCnYAH(F2ISn5DNm^D9?8x38Y$?uAO@nAvdke`&WFMwL zCzOpN!yWuWqij*1&wdOE%uZtEl+Vths%IY!mK(onCgp6pA{-vB!HemUa7GTpt4)_i zU`fwWGpaJEnvPhkD?wpmv^@cgSR1HpMKwKXq?mq;?^I{{sX!ZKML>j3gwkZn$W zU7q%oZZun7TFzW_31&<24=$dw2?nPMcAF80E|?2T%;^JFY5p{vS-cb6x}t`)Il?w2 z;yLkJ^zuReb%15|l*)shY&uR0p^!VxuuEytm9*ttk_Y+I%goE6^6tYzjhbA_h10(B z{GzfI+sxA)NA193%ykuJ%zXA}>#FtfHqNju!O`rnJVtq0a2Oxqi=E2Ck5*K?Si=?&?ararao8o|oQK}QatK`jm8kFow+?zP;MDK*iA=I#xmH%wWn9LFuAk$~5qv8I*FMLD+Df5j%u+ zS%EfR3?djmL5<#OSs`&6MJ_ODVlh#!3ua{hZ~%pj%>D~h2t)UYfG*9H?DdhW2LIi5 zA;RTedG;3=o=7^BDJNxbN~Gj2R=BD}idO^YT7I-R2?fJhEBl(oPs#p1a`4t=hr<}r zBbkyNRzY5iOm=S-hVEh;>kuR+IDd99^zihq(+eJLH(s2Ce4~R23$e08oow%^DrM$h z3zLpBF~k4BhIn!x^zAqSO+b*}l}d0iQd?p4=$N1}l>l#D2@}8+!RQ}U#!YdG2~gyN z6MQ^QfbAG0s7#gdnK;4tLngpYTU3IdagYlIlRe9a0UL^qyX;xeiy?e8=ZC_o!9F3T zG}HEPoR6%wSC$>SCELsHw*8NM_Vc!jKQa4al!7*9NcIk{WMOk&JU@~6A5jD6+F_-J zIu2RR9c9dwrLe~|-ldqf=$K>m6kyU|J1iDP8;{sNAI<^3*cOvDtmG*{BOrdxXTU=F8vd~3vn|xtVLf%Zr0W=$XU7$z7w$l_ql^KKa;dTbFdt`cR z+vnUOSYcbvKx7K?6WJ&?PB|YUznL88RnqWe^B3})+X2~)*w7q>y^(U~4RWElgoU|z zmHFZ3I)<=~@M(^OI$$|-&Q{A zi^{Fztcxmw;gq1dh~2o}yh2PlOF?0@Vk>z8BtV7p;p?ULG;g;;Q6`5{SuoC>kGN4) zVaj7&gANR8f)VrStw*+Q9KD!BrTD6Nz$U}`1+$#-v%WP? z+IBs&`H!&z49&PB0n0Vs7V`6E2h(W`;Rmo!4B5dI!CcX^g@+q1WZz{*7Ig!Dt%+{X zxT!Qoes!v~_%%W@&4_(6<`tEusBl^;ZCauC;^!x(a=&A_*~qf0RMf?0{oPpsO65^p ztRVQEI2FXKreBeYygC_~&Uu3(QDRyFZh7~pJJM0TU0t0xckk)y-8s0caKLNaRH)xn z-_%yvRMWVzzOZU-P1BnCI?o-14|EL{x_djjJKAv%s9;CRIIiy7)73xN-8JCtLePP} zy@OsC&!2fh8)xfp@5QAB1o3>mu(RjDo?UqC#{qC*kcGCkZEdVCG}dh0u(8c66n5v@x(5SXi~OwQa+C z6xq_+=5@9Y>?+_=&EPI?Z*ON;zlmya7Yga^8W@Nft*>c0slKjISKnCQ*3h(uHS6yh zu!|U;-Ct0zF^B6j_k(3G{K5( zT~z~xUcaHPzRfX7_nj5wx3~9$@jl$0MJ>bbF{sn|y zC@P!dq}jTvrM|wYu(7Fe14QEb9jwFg)-l-KM}I&pw|92$9f;dQduSSp7@D`Jds^z7 z>grnxE%h~ZCM#LDhNk+0e-CsyMWmce?w%F14_8bR!m4R(j7zQCu(1~7 zW>sUuD%c^0$9iTahQ{23N$Ts_*VSpW2@@5~5?eP?b7=}u6DJ@VgpR%a{g{_v!TUkR zwPakf7sFbciR94h9>By#I}K~e!Zy^dE39s;SyO0js%dVnL46}JaU!r`=enw4ea#w- ze@LB^*oNjBOe}Uwsk^s;dr*)I#J|75IWsDufL?$RDX1D`ZK`1RV!+O@i|eoFzFn=tO6Osh^RYPFlB3yTgFxY)z= ziTR~7u2|!SrZt7;mikuMeu$#EzQ$&Sq8@8mQ@eEOQYcVomuaA@e`3gQb(*uMy%Vm= z4(mM37VNoQUG1HeQ8-6KAQ~q1O=~c2BO0^K8rT4*Dn)gNG2PJEX#E(aZf?PZQPZ>) z_M*LC`oT=GHgZOBlU`y3MUxP_jFXugJ+T=Fi=vie@~mBY^f5=r_0&Am4=;dLJl0c= zqA0Yz^Ypy~gBSs{Nqv~v;l0`5f+t5_MbiW)2{)Kr@TS(SO{?M(L&?-Nw8U9gt!-$O zAAqb1kR z9?96_h1E5Ut@RvLHVTo(45jO4a~M=<7VEq(P12E&TQd zZ!dls(A(8nj-LSZCmc;&>+CjVE)?4NLjc&gZu62Nle21V{i>6kDGfCX?2CtrS)Aga z#cV-w(2|3LmdcN^S;|elXne=s9;jepH-4-D>$rPQSMPuuaa;!MZtp(>qpP#4r)#jg zcc)3ymM9Pxyc#%k;h3Oe;O7#9oLV~i`uaN)-n2|*xQc=*?db2aWsvnjXBX~WJ7X*l zG%m+%FborPwYjloRec=e^sUfZ-_%M~Z)i)n7?x{wnhq5tP))e{a|U zbkGWG8n-sDjn-J4v*OZO0G=0h!pTU~Cf+&+2z!l>QQ!WBbnLtSF*#Xh^|+?ze*l9=sUH`dZW3pKw; z8@4#73bs!jZ*}*~27-(6HZQhmLsPQMXu(T6)7G%T7LG-np=Yc|JnJ~e{NPDvQ+*3s zjsa^EDY7_yZmL6I+lCga3-kruvum)heJ5)gcCQ;)HsN!lBixNic)!u&$(XicxUXt+ zPL7jkBUf8>HQafz1zZRGrM}%^560Unu}`Cs!M3SW}1+@z|G;QRMC+g+~U|2j^ze zo*q1~>bEr4!0sjWK{f#n0Yr=$Eo4L6;#8ipOX!Dr;n?g!6^xUs(^_mLw$)?tUDPx( z>DV53Xz175{#vARttb|ogYg18Qr0!#xUr=kI#A0sEpjAAk|~w>uG@FI#iS*O=jUj! zyG4-`a4(!!h};Q}rrbt!V$V35>WY-MaVhq@Y-756x0wake>SxgC4`N`;;Ck7EHUkj zCHBR3boXoV?v~c!gcY@~wxMl(4R(mRBi7oo3XOEz7IK19^mdG7Z1zA4Y^mx-VbK;C z?MMgQ!LEMVhq!oFvM9Nk#l)l+_mQng3s}{-^|TF{1BJdF=3Ax)J~u?dDn~=QNJ<-< zPHNh)*$jE)cWth(v1PsMVr)*Dy^OXCB3tKSV(s2z!&sY5+_R1q&yEwaJFT7SRJ!`cMw&*hDY5h9wRi4=`{wj)(8Df@ zla3o9W_Y=Qot7!Ly*3wW>#=7|cc2eeptHL_k<7gOgvVawG`Zzj(wcyO+#mFRty58} zQ0L<I`K8!tBTSXP97jBMCWj8of@b7eJcTwm;C*}}}6B*?@~Jh8?& z`$)UD#aS6{k?Q#M(58Ot#;xWyxdvbX275`3i%xQr!gRyAt)VgLH`ic&=^{86MvGEZ zu1E8}b5yuj6-g>_wx`~Aj*E_uZ2^b9@g0~Fxf^F&Ah5h0SZJH=b;608OB>w^?};Ti z^STPg4|`YUxY~HIr5}x(v&O1Uk(SmpV)$8N?b&s8cDubS3?pTegAz{pT){fY9svTQ zlW~;2$ejc$W-qp&CVA{(!5N89#+|fn)oKT@(FRkI^mvRy4+K8UV1GM?3|7!)INgHF zT$I`xl-bw2vz$%FE?Br_5Kcp8ZEQIZZ)`gCNh*(>kLze0&2t*m(A0|MBM$a?Nr0`^ zV2$>AJyZz-$60x_y%<`@)OmcwQ_i6~Hccu$kKVNLo|Lb7$+jy=zn|-ts2Gs+LWBG_X(jq<<-dfWG4Dl$## z?Axo|=Fo<%h8eSioJ4st2g%ODZI2CDz32{!6JtkD9|eSyeNLFhzi1YUB&(xubKYDX zDYbY!4|tf1FlpF53ZBeIIcYD$)7XT~NX@|JT~k?*FZLI0;jVp?MB{2Uwrz+DKrS|_ zz6A;k2|ByQ+SwrhP7Yu~U6pyXh(mCR{P}*dc(%mYWE5L>(U9 zCJw;D@f8|ir%G|3#v9F%cpS5YU{c4MQ9?}aZrVv6mqxJ~ZmnoR4Yv~UCJjm`atRyT z%=jg47jaE)L#N27HEmi{G(YNqK2|lD8J!##8&Y~Y+#EJXlI{1_G;J(jwRlUpd)ZI< z;)RQsEIek>lJW(+JNE2dft`KGenIAk&Y!EIPzGv9#M-Z8irHZxoW*u^i3GMZG(=)pV2ZJqE;G!k>MW}3>H zc%xIRLrHw`B0I~A99XBp>>p}zY{8<==5m3n+9)72wyRgS*0&|MfQlow;>gK1WO#Bz zn@EF)1x2)J<@D9GmoA}}Oa~os$ruz>!JK!y2-MuL347X!!|8OCT}W|_WGVD+Z9Nh$ zCn8DL)NLwYE5~+n&{h+to9=B-Hnu(mn+}Q<(oDNudkcp$_Z@UaMMDys_d4LRHXB1X zITamvK}@FBSO_}_u_Sk-Yu9urN4&@eNALUK1ahTe>t?gs2jDa7P##T)O`F>j)~2MZ zj&qmd<5OpJ*xAnP%HXgW+CGUCAl}SfQ`797(beBeU!+KfF@HqKYnmF?v(kxWAa??t zJxI?`^fkGkfHg|@**M5cIuziTu$(Z!)L1vy)Bn_-ZWms-rb8?qZ%ONHJ?o|+T`Qw- z59x}rzJt>od>%E zD{HJfYd3GjoweIzR42PaU@~&sJZ1`_>e$VWRU4YzI^M>d9fN4vk#e(mCs;Sr@*19P z(C~O(9=csUiTI}HuSh#NS462`T${0Z(86xJ{;b~uXa6YW6i zsL+{KyTFEY&h&I_r@E!r1JF-g^bNzg?H;C1oa;Fgv8$a|tP;U-&9t`Vp1IweV*3)? zKkIR!00(Mj2aAo?p||&91L}5K5(nC$^1w>ON~dK{xQWNp%Gjzny=-XO1Y1WW+HVDF0#`qZ*xQ2THb%eIiGow2fLHlK7gBuEtMTG{1mb? z($P)FG)JtjT|4a1>B0dLey)(Sk_mXR%f?P8c6G3|h7747&$%44fJ&SRlH zR-=mCY-bM#;T^E7NSsgH9dY9#4mFABlVa3z-G)-9SRG|O7|94usa zX&g6`+PO{*s~-<^YH5vEXd@eX!lk-x;@cVHH5l(n1&EUIHQFgHG<;f zH`pvoj1_!jKxMMH&0s@L+bgc)qKl~7(}$pFLo%HK2#lCUE{JOVYX_pD0C~IgZ79xLc;6qQLn)<&ODU+eLMEaibFB zHgkU_>{r}UgvKS#)=-e!YjJCR>+z_Gj=hfh*ejf7sYxlP7*WNhhTZ12e3KHBiR4uR zCpE{%JIMKUdTrCLIdyIuBeAU+EjxKQ&6gb7`3!G;>WVjBqLK_X+LJ@8L-a5;;N2R^!kfs*d~lxb>3UgG+YN+6LVAw;ffN zl~&p2GW(4|S1&L5C4ST5Bq_HUtu@t0-Q7~bs^G+uI7)T_$s4~|k!h!&qt;#SDVjZs z8bI6kuCFq#4m%I;4GkY*V70iSoT3|CXtuMKZq~7x9bpHXyBfP(afom;5r+t0LeU>0 z+>Uu%^G~Wz7=qA$DYELe^9rYD)k(VBH*f}ySh304oA_~oJ1^DI35AC?JB4?~*=a%1 zT)lDYCM&uquwlu|YYVGaJT+zis z3@nz2Z9Cp9l`9tanT@^pR|jrt<*D3&7F4F*@tIrV=AXO>yJQaIrqh~e0HZGSD~hkC zD{yf<=(vyLty#5dS^2!0{@vx=$Y~4TTkW=UTDp1`mCvi?ep)$SVU0bW#Y+x9JiXV$ z*NgJi^?$_&KVLj|dYA$#DK%0SmAD-wU4=77Dxo|7%CiyQuWwntI7}Zy{aH z$Z;13m*g(ZegN&L9l7w_(vjn8(2iufBQ4$Ni*uJ`FGZ@grO!P1)h9-JY_2y6|HBVo zo?kPvB$n-TM@A5kiPS3x|aLDv^BcJj!H(7=xfBx-;L#D4Cd2cpTXX%%Ol?Pso z|LF5jhFy^i*GEsQomh)?h%&5oGL8NY1ljU$GYsd0K6qJg5zV;26`#(ZPo*c#zs3-L zE_iqOtj*lY=05Z9Pk-&Hf0Jgc8wmwU>QF5hq5T)-F3w&89XO@*nXf(pH834Y){}pW zB1xy)MLIc_PBp%huJYeIGMCJkZeN;jy1o3H1b-`kIzE?5e<-?U84}qIZO>nb$Kcon zHD11SNKJ`9G*g-#?&A+t_~ZSF*-8Fne~LfVpPsAqXZiE}ItV-UNrvRS-~BZijUOQ= zNxWR!-jp1LW%;`8#3ze4ZnLe-MVpoZOtqznl|)vapQB{3m(uLv+kP zX*tPnN}L%_S?{nE|HD%8(^CAWc{dgDpO#8LBSn{|_?M^RD^vU{z59`Z^}hiBGhQXW z;}8DIMNHr+>&;H_pPh=Io8mv$`zlh9|6BN<@#b27jw$z<8$K9jy~9)V{8V}KQ}IWp z$~)3~0V!DCk@%k}@&Z_YYIFR_detfZ)o~=AvfiQ;|3%(w2q*t${Ldhs`re5D?z1R- zFwA;KrRXK8@{%(R%R44j-Z36tQefq|@o`Lw-_jJnrK$MiQt`*7;*U?2cf2=8_wm*T(9+adn+J2Gay;w;&OCNMPXtxxe^A1Ai>4Jo=gRbI1q znaZQzl7ZGy-`wEteMi^$jOH%Zusq*Qy#heTv`psrVaH{BBIeebH6is{iQu`QDSM{I{j(+f(J=o{GOCRo)$`_>ZUPJ5&7bOvQgP z#qX1;_)n$iyHfn_O2yxu;&*o{{-09xJt=EVr08#@ z=x0;(cT)8Cto)iN)U7{i6Lj>5hphKpk_7$z6#cyScx3C{-|hU56#df_{i_uH#}r+X ziHjJG#~CU5=oGy=MQ=&b-6?u+ipJlTj6N*yniTz!6n$rkelSHplcIl?qW_ShOC#UZ z$!|uA=HL4aKdfI}ir$u@2UGNADf;>peMgGEH$^|4qF+eSzfIBjD>TuE^_`rem!#<9 zQ}mh?y)i}aOwk8Y^z|wFUeU8qmoeVgyhlM(ZeTk(nc%uS5 z=)?9^fF?gakM%me6Gaao#G zxWoILXvhDP-qWI4&9UCy-V35jjsC3nc2WNOyh&ih`nmWAyoI8vR%5+~y@n$C%ifM6 z`f=|f(BX&mi_V{LeCW=A4}EuI)}S}bZl4t&dnaz#;2^FzEAnK4= z^cIBptXfwQ;((%qZt!q1@#$~WT)vznJQ5BY{_ejWbZmI4Y7I`@CQt#<51`|!#7ES4 zubSP8!PmRKT_wRMI`xk$Yj<^U&h1_RS+yvBT!_cS%S(917zXfVCZr(-p2-7}zwM4m zdnI6)$=!-BbnMxKI};0;Db+uzSADoUc8O%Va)uDQ<;7FY@aKooPn+Vh?Yfa8^|B-o z;oD&BZkK!WAuEx(dh6~lk$-$w`jD+yWOB6M+%Ppek0Eh>yL!VQJIvQ*1b49#fh_vq zw;?1_M>$P5co%@l8Csk*jAo3x0GoKVV#tq)ih3|2+{Y;y%L4Q z-J+s-tZwfFj7kn)s`zfz597mM<0519dWIqM_E#>6vf&XU*-+fh3OAJ*Q+0HLJ#}i6}Y_ zjep`(6l?~i=nhU4&3fq~q4h)YJ=TzO`e*V{_V5lOtK@!}8AVZip)xx@40(6ewe;zW zCq>*2rMk>@NIhkQZertVv|X}`WtE7;8y=&`Xl!~*;F6U7+4I&C-|=h*z4Wi1$DPbl z^L#vSe&}=J553dxDaE^``I$e=01i?rJUo_6hfjQ$^x?5yI{nNzJ^k;}$sSH9fn}ao zPQ)hUeBx}+TTH~uyO$GlzMW5z9uy7m=7+~?D5sp^I9xi7i2U3+CcoQ>DCb_`V?>n4 zl{b-}`Qb4c_*i|0h+m2C%|U$WP#?ab=izPSOzzD;#=zu6KeDvc_f`X^4^uoV%@6o- zIaxZ~H-B?F`0z7-m4WAtaB`lH%;OMLI#T5UdGbVh3laU(NyJ|?zF72CqPe5R_(y~Q zZ~i)dYHAytd@9Vc8U+(rby?L;Ixomhr`BqH(oMAZLsBKqqFBKq$RBKnQ{)9k0$h~pto z2$VREIKlU(5K+&0MDSfq1m8|#qvs70k?vd~%72xJ^4=ywo>QU$8GM?_NN z!}ChYVKEVMIDv@vuOmVpTSRw?-a|zCbBRd*1`*?BINLW7awcNjTqXJjBI?7>d{&wt zw9DFob}a?TcA5TxrYezsFY(Ww#}f|r`-Mcv{gXt<`2peM%!gEqSW`h2DXZF-FQK1Le# z{W=llhk9!AMkPZ%tz~^cn|x6}o{_LU7ZXvRtBEsw?^z-m`77a{g(h!=&!K#QONDEN z+lgpLFA?=STX-Q6mEyh?_4)zf(?kgGIbyl*y-tK)y+vf@sh{Y_kwnl(N?%QXphA6%1pgAt4BcA#*eKzWk&wK{*6P7bi{eL*dH-a-94EW3s zkM)p_^VRet6n>UPM|u;5pBsmBxgLeTKMtp!Md6pm;YIwfh{GZFIQ`Y{5*{88p`Npl zr1U7?ZfH;+mXiivNJRf!M_hvbARdi=Cm!QFeLWWaLwc$2=BeY*Po$SY?}*2vUm$|g zM z!e@SX3<9|u{bd8IztLYw(NCr5a2r3&|7yII6^9Dl@Ph14_BwA)19$RM5~ z84KMDO(*Ullr5yCRzWZ?|qY~c~YMZ#l+D}<|r z4Z;n=jlxre?ZTbH-NFIk0pa_Emk6&AUL(9wc&qT^!n=iE7Jgs&N8ylRuKg2)#|l>o z*9mtBdxZVM{lfEw7Yi>JUM;*qc&qU9!e@m)6uu(-qc9H#fO=gfEEg^it`(jld|dcF z;ZKFH3A1n<$ge^;SGYiUl<+v=O5s*vLD(fcL)b68LU@hvM&Yf(j|=Y>J|%oc_#NT% z!XFFY7V@e*>z@~n5FRI7Ei4GTgl7oP6rLqKPk52=gTj9hUN8Kp@E?Vr5`ISb1>wI4 z9~FL8`0v7R3%@V?PvK96zZCvf_g#IYk{vpB~tMKE(PYXXM{Ab}8h5su2H{myg{~`Q= z@Q1>m34bm8o$wFBzX-Efpir-d3P%aY3l9@k2Jm9Rm$LAX(Pim+X{Q@C3=AUq&^ zpYRgl6~b$THwteReq8uz;pc?^Ec~MIUxoiB{D$y9gg+4eQ1~<9uZ6!8{z3Q`VHSIp zHr|AzgyV&W2`hwig$sm736B$=C|oUU7Iq5H6uwV*mGCRVUkU#py_&ed-!t6v> zpW(vs!s)`f!V`pb!ga!C;U?j!!tKIc!d~HC;km+#gqI7i5#A)cP54RSXM_(39~C|& z{I>9U;ZKFH2!AhpM>u4XYyW8BWMQT7Na0dpvv8B}RN;2vE@7{5P=E85d`S4T@Mpq531?4t{FVz_gu8?n2|q|&h5b3=>o|uI{*&S#5dE<5Q6kbmFMNrJ zdjDBC6lX}JCkST>7YbJh*9kWXJA~&5KPM>S0T{vHO ztZ)Spdn#LqX#c6gb|Tu*BYKZ;ufi`7eX;O^3cpVDO~P9hewXNbgr8UVBcdM@ewFx! z=RK|X?<)KU!WR|(OVPg(zOL}Ui1sU7d-6oIZuV3E^YHCyA){_lV&8 zyzr;Op9^0hBHbT};D6XGhZRJGFCrrU(ZUmiwZb(-q-!H0f4}e|BIN%;VzuYpNd%v} zgr8CTzli>l@NtDdBl=n4_Z9wA(LWcyqVPY6{*w?tjkfYf5mEk8!Y1KnVZZQ0!n=fz z5mEmqiJLs{$3)csXTo18{!P(u3;(L{VRKyiQNnRV@GBQROL(}#j~0EL@C1c7h+Z#j zQTTS@ZiSyI+^6vOi@rp7IT7u+QSo;u{FB0eQuqU+9~M5U@TWyTBm57AzbN`A!k;Vr zby~6W^7ZFk3hlwcXM&a$kJB6PnBHe>T z@cEALH^ThkE_{Y?sjyYpEBv7FABo_1Hxcc8SopN?yF}FI2f`N>{!7un5x%bQzliqd zyL@>f_>K`hUO0t_`X4P^CoBjDh35&sApDi^E#W&v)PLj=uDr3r!-O-0vxrEyn22)Q zgxeH;IuY&c6`mzLM|c4d`L7}(|EGkH2!B9CJAX)o4BjS!-#fzWkuH7|5#eRRNeZ7O zdY*8B!k3C(F04^_qv&SgMuopubf>Ue;e(?03ojL3F8l`~>V22+Uxm*L|4TSzflGIo zuv&Nm5$&%dHhW%yh<0`ecPV~Q^nT%a3cpPBmBMQjev9bag`XgT|9y&oT=)&ee_QxH zh5uOe&xF5H`0qvkQTUF+hgP|Ij}VR}qFvKOR|w}Qe39s*h07FPFSE zKTmie5qfro;y)_i1H^1D}=L!M-h>(RfxaC zWAtvtpD8?Bc)svTBI_&sn($Y`VMn?6*}@};sPFN_*FEn<;aXv%@MI#=6^P*fe&Gic zej^e2KPtRac$e@qMCAV>5&3^0d`%cEapALttA!hcTZDUrmk2*0d{X#L;d8?O5)L`q z@t-cl-$*w-TuwaI^EMMv|5JqTRs0#E`-FoEf1l`!gqJD&CgEMeFDU*&;UmO1JnyTD z|CYkPBm9BFUlRQb;cpcFmgqkV{bO7^#t3H<(VioSDCc-0`&GDB*eKj6+$!8I+#&1} z4hZ)X!T0^5FA-iPyjJ*8;cddZg!c#^B%+>QB7)yH6#i}D^THQ}KNtR5_=fN;p?|Dv zXCNFY94nkkL^<gp(CMOY}V90);OXyB7AVzfSZ`!haNg zLikzXeZnsa9~C|&{JQW(BI^4R5#_$2@VA8iN`ynsfv}W_bd!k4cZ~34;SS+B!mEWJ z5k4*aneey5pvLi=DLj$5-SbWoy<50Xc)jq`!Y>JbEgVtn_*Dx}7M>xzRCv4a0pYiW zzYxA7EL-LH9W7iZ>=C|S_;KMw!tW7bkAEzDRajEz!YhPT!X-q^$*V+fAVU7F!cO5X z;cg=M?-zZp@cjzEQuNir>xtlhpYV&q?+RZgg5N7d*q%R$9#Rh)^%y3cDl8YyCL-TL z(MyEK5y7WbxQB>z=MZ1Ux`_zBHw$l5{N18IE4*Lfj}m{3ePxBeDEz77Ulskj@GXUB zS0mpGIBz1Nyh`C*BI>hP^fAKa3SUF~zUOUM_zvM2ir**tY~ck8zk>KI&X*K^xA1d{ ze^~UFg-g*q%b7$_7+?z}Ggd~ug5Fl(xSVV*X0YU^+cG;Bx2@r@RLReJP zptw{~QE@}6RIEiy6?e2MRI$>QT2N|frAn15inXZJqP6z-{hoQ|-pM6F-@c#s|M~m} z=04|n&U2pataD~Ea}4!E2)W|~&LP~0`Cjrb6Z{&&XAI*O!GB5!`HvGmj=yIjgkAdt z9u{~+;75euKOy)@f&V5%`HazaelFoQjDLiXH&Eahfnx}<5amA>m~@_vX9~<0SS+wy;5dP`gcuK+2tUE!b;tl$#`P8Iqb!D|IBB7~f)B>y_X^%zej|HlF! zk^H9xe@@^_Lf<3!UV-}wA?G8>|CI1X%nRcHVQ)xap1_E}GJ*XBo<#_MM+knlz;g*9 zuSW9g2(LAat0n(Bf$JpyF2U~=xLN3r2>z(RCkY|vH$h2(!LIQPEj zm!FXRSnv#iIfRhYNAk}kT#f5t$vx#CUAhja)HALFUI={2=QD} zt>7yNA@6p9+XVhf;Cll9BQSfS&3}f#u>uzhTq|%rVbCysO87bYwZNwcp>LPqy9NG% z5d5A=c7DFV0Rqn#xJ2Me!W6u(j_`BL69P9%{*MKJSm1Mn;D2B8KOxM*^YD}H@`(c5 z5yHM4!8-~pAq4+4$)7{m3F}kIzf#~@$-hPL+XZeR1pjX(|1H7}c+NudPYC=<@~!ic z55EEevkAdJoDlZS6xbl}dV!k+J}vOKgo_O0Fd^g}5%@QOp9%b0;I{%Zr`YB42v1;t zg%IV-1fC^uu)yJj;2SUaWPuk5oFj0Nz$F5g5yHOf1l}v~L4i92z9H~$0>2cPGSx0$ zCU7tz+V>d3FAZa?z)1q93Y;adT41ffI)P{^`gyLN0vE;M)R2CioD`Ndh+rd{&_TyG7(56MTSW^Isd> z^aO1AX@uP{UkE%~;4FcS0@n(>Ti_!CpC!Z?zE|MK0{sa#y}!UI0#^&XSKzM%{!8G* zM7!KA0v{E4RA6_GrO-D+p#J+R;QH^X0QKKf0qVb}0(?#Q{wmNPvdfnVtP;3L;GF^= z5co5J&k5WuaG$`p1%4>-1mP_7gCrZ~3G69ww7^9I*9m+^;30wf@0uW|Q`nYMF7RxD zlLamnc$>hj0$&k$P~c|*_1^HVeF2;5`C=BJc@;y9DaL-+-Jy3VuZ3=K}vNFqmrV z%M@57@C<<$2)st%&jkKip#D1o=$V&h%lU!8Z36!+@C$+M(rv!Z0tX44B=91E*9v@5 z;9CMe5coA=e>``PVZ#Xm*9hE5SdROj0zVL#lnMF=*l!hhHsN2eUKO~8@Q`8LC-CQl zf53Zq1pb5Y4g6h0mJLe@e~b4g2&^OAgTGf7_+!Fnv2GRkcY$U$=#OK6Nnj6wqX@Sl zo&p;M-a_~j!+2WYVS#*C4X>An32YE}i@*m3zDtPfn1MMqyiVYI0(=$^Uz{?2N8^+xNpBDHA;f;pz zcY&dfHr`EO72&nmpAxu4;EjZ9FrNy1Rp5Jst8rgVU|znBpGCM5?LESVcJAz?V*JSR-($z-EEB z3A|6>BLcPGh}&z#0pAq(p1@B9eoctD>UAPu2igbNT_9dzqvL&!z*zzp30x)cI)VCq z9;lzKg6|Uey1@4YeoBb?Gd+Nae>;I41@{)LbU&L2+__a5Tcz; zCG2Dv7Z9SI)execEha=eyO^-tFjf+dFpSFy(azQqBF;AwB2Kpv!hgPxob7BgA?*AK zA==r`2+_`-BwTG6&k?S{eitFy*{g(TXTKp_kLRNZ(a!YyLg42+#2>)*5h48hm=Nvk zI3e2EmxO3%-w>jmc}$$IpxqIoo$)YOj4)N1}PmlPWfDFbjhwCcDZ!FhG zh~GxYWc=D?0wR8oW&_ScoFJR=Tg34X@w;D*$`|_e%-^5x+%*h~GLw#P3l;#IGNGVf>~MzJh%~!aZ1r5+Z)D6C!@c z2ob+P5g_8%i4gJA&-WvKSOyrLuh7p45ywiwM-d_xa8>756Cwspg0CV(eAfvMS9F{o z6nrZobiW|@E<(iph~P&F5&w_^gnm8VpdR`OuE&*fjH7~2CLAH}i2{Ekan#Rx$=^VT zdeZ$7`MZguzK%=&2|_p%@c<&fh;Sa{3qF|;^?1GD>j+Vwx_^NGLE@-a{k|OFPZ3`Y zeZs$+a1F*?!4D9kz7Gqo`vdA-_XCtaK{|tG0s^-P(GHRY*Xnyy9D1&i1xEj@B@Uez+S#ov{TU_8F1e^_&RoEzr8ZpXr1%O} zqoig|(;TB@E?xp$vb46ogv1j2b*HVr!MtSH#PdqPG-vMj;H5;HzpiH0_vF_W;JvBN zJ9F)?jO*9a&TFV|SZc&ua9ZA0Ecj0T)-8y=hy6PZaIt7o`tPON;r+hq-Tc~u*o%JUo%r!;Pi1IDSL;l13R=8l zzil-w*-oqMR8}Xdwn47<_s8ptzNgsD(~7b-`C4jne-)rjRV|oKr|T3(S0wq8d;8th z^5$-Nef2yHd99CBrzy~i5q9KGr-g-F2JubOda!bR-Jo?#TIFohgf_Wdy7haqFPei_ zlDDqWmEWeGI3AaDzI59CHHOx8oWj+nrdBy!`cC(qht_qUwnUqDoW4{8CrFtQb!?*F zmEe@x8y}H~pEp}_ovtdPqHGzh&Xn=e=!Onbv@7bD!=IuiKD!n7TVrV{dY=6`fcR)f z3p)9y6Yl0|DV3$4iuStbRN($t#i^sw>G|6pFj^Jg>In5+8tCGwfvUS`&Vt(6Zre|9 zOKbe!6}+~}oN5gzv-u&4(^gxI>$^0!=PHKRp?^-E{$=lr>fLbNQ=*BoK|%! z?B8WVYenK3t?NS_r)jD#uC^K*>15BGr*l8Xbvik%&t7f0uNQ6jd``W+6turA(`Iwh7Q}xO<+MR)y~OG4kDqx? zXStjAbTUsF?oTJQ1@q~o#(&P`I|Fe_f$t$b`aPKME8SJV?y}MEqm^OMk0WulYm?lI zUm->Ni2gp5J!90=&RxC$pTe5ofUPE-o-=pu(%Kd7-1>%j^>xddWCu#PwC^oQOP4G- zg^gEQj$l}1l+0_m=%U&s*w!fR%i@+g1D&^LHcc+ z*ap-m^-aV{`gUV*e*?|A4<290`g+aRj<9i%DS ziQjIdi*Y)KW6z@?xaCzt9`#Zl>C{X708Y0bp8$6sjvp2h_#gFyd@N5{JRCpBPSZ=m0FY3n$(C`>W^li= zKYkadx7y`Lcj43iqd*HkAdho}b2w&v9Vf35@*-fOALMuZ$QF4{Io?xtAC4atHeb{a z^3fhgH|6mtN5b6>*1P<`t;?w1n?$cuAH0W$TanSjkyjHZZ?j8YZti4Ea!g}8I7|5G$ND%wcyDw!=+5ETGdE7& zQOFwwCdwOxlX@xdT9N0J8}Ar|JRVNF;x{&sj`~49mZvNpPO7;rNkf>y7$BKH5_uypA8);B(hU zb8gI!5#S{s%gvATV;AIYa*Rj5lPr&uw;uBLAfJAW#OcVJCGwndvl5Z%IvhW)wfUlc zkdO9I77xddtK#%d!^H2@$0*@rx%WgbfIey<@1Ua$6vv)zaq<>I-YVqNk1;qMKMsmK zr(C(abAZng9Y(y6j`~49+Cy1996$JN6nA|bcKLCh@UdKlEswAE(MKiZIWkC~UY<7z zpW`pT^>7k>$vK=dHF0{6LvJ$#&|i*&j=y|{oN^t1D;Q+g!8{(@Y`&^^U`DhPi@o@Aefavz)pvw>Hcl3_8xeljYjk5Wo^+7(`Ls>i=KPth8|3(FgILcgpEC5bEmfI?N zo%+awJoixK*s~%|UWLn#I+wirM4nTwxD7w{*?dty$VYo9i-+UKUhv_6)Q?dvKk9{# z<+@`$cGpK4}iUV*XZ(t`$taw@*72ri&JiV8-DDt`J#T1kM>X&566$E;`FX^ z`LROyST2C)2i^5C4f32eMtP1sZ^y~I-sQ(Cm%MM|{J5|UKYG}DqkdG2AC$$z@uMsF z-1V{E<;P{hM?d&&CAS|7+wfy@oV?90KQ4F4YZ7^m|4Z8N<35`&>PMsaL0LQ;KQ_kc z-RknAS@`J3Zqe(^`>P<&X`{&2KGM(5==^SfkAkn61UVeNpU3Il0lhoG!}0lQoaCe4 zT#@JayU^KCK^_lB^jMoO>M!|Np0ap2ddGmzU2lz%*gSKs@Uh(Eaeg#H-f#+%!?EY` zIC;%3dDny2@#7~V&nfpr8-DO_wBS?JkEg^B%HrYp@rO9Q>s@+p6h8WK2A)B7*T)Nx zmq$TzIQ9g==Z?!}$YXid$4xjLKYEBfr`*9d{5ap{i~2!6%A+hEjvo`i=hnN`<;QyA zW4VV!uQLW5hP>9s=gZ>c?Qr>Vn@ip%k>~hvybV8Iv-zTakdO9I77xddSK{>Ua`}Nr zbEEMqz(ujUK2Emb$ER`f_PPAH%Ox*M(rH!faQep>n=k4I`RE5_@o@a$H^|)e zanR+*M&V<*OGK|T9wbAayFRFw=P!lNskaFDxcBcIj@}=}={*X)1Hi=g_d}fIquv)p zp5yQ8HvIjo%@_5Td@N5{JRH4$iPIY?h>ZuEg^%UZ+qJB>wIUB$`f%(?6g~%E*M@y( z*?dv^$VWX7h&;!>Gr;Grk205i4}#Z;%aS^mH1-*}gO+g$b~qw%`? z7sx6K!|k9?H(ga~x(+Wro&v99-@Z8eK7qW};`hrq`}mD0 z_u-6JpU2sEQtW$1m>v5*jkB-WWgpiQj(tT~hq&w4$guMq-A=r6gwMe(@VO7izO!w< zX#B{>_&N6-9s5Rr&mF(@F8g@z(XsE+IQv3v*vEAoZE);MZo|GG#o0$b+J`^e(1&B+ z5993H?6PkcI34>A#@UzMhJCNc*_YRbegBEGk9@T6Wo=!oZul)bcl@@y?Az_KuV-q@ zxD-L2TeVYfL*w|)0u%mxDtb746NRsjfX!EBwxR>#RZ3VCG%ZF#>zz9Vm4oV*kDcpo43a-GBR z_r5s3*O#LIc5=94dN;=D&7P$U?#a-P*Ks;}pNNxp@DBXFnWGGRPV&(>d3$QGkB&^r z+vk$^YMi_>EL{4y_7fd>{N|rK&dKwYu@Iew^4@UC+XJa%R~XB;u$}ymI8ZRZ2OM=u2_bA1bc5^Su4E6~)+-SZWM-+FSLX ze}4NPtEyPTwZosTy*~Ql>`;}r3g1}maqhlO3uoqZs!pp^gSJ#(T{o}VT=af*YT>vO6}@e_X@zRN zzbb|&7hYAR*2nM^b=%ujS-Mtz`d1ZK9N*Ghrqc$}KWz3qY-47j=V80n?O$)z zEst+N>v-FrbN~(T_>Ij6PHu>J?!7nX&XYwEqsNY&Gl$PW>f(deXFbi`CpVQH_$buBYoUR5_GJ!znEiG0No&1bX2)l$-G-Cr zt`F@*O&`bP*~>Woc5|xcCT|+rgi+vdUtQ&-elgN>Z}!gj>NX!sRDqpy>wa`Bs4{jw za4hJ#t@6#BEyohgVUMe0`x`5geg85IO6s)Otc2AOSd;wx@X*e~i+;5D>fu{=npHOr z-?1}Tm9p@j;mP~bs%gQ?&ErlO7rWzP6n2t+;%5uG<-p0iBj&x!KJ*mdvY*nehxuz3 zS`y8!g~O`s^1pmSiLa^zo|bjkfATr+Jw}fU_a8WUec6q}hyHW%V+T$)BQ^2u2O5wv zNN>(Dj_qso9IN&mIJw@Km}7L`v2)_^yu(KE;eAzAPY$>4>5KB~Q0hNlp7Yqeh8u_X zJv6uBFv_oOQFdLl>@F?QJXUSa%(3fnZuGiW_k8J_<#G%a}CKq-SpSx9EU6oSk)YVn4T4Q}>@7$v6E3mWE zBJ=Kyo%dF5tlWGonE1#sBhjg|M5E|Kj!@;gS8jjIhq2}O+1{!bw(Dric*jUp%=vVHF_GJ5p-(~gn7_P@W_xZT=n zeYQ4H%YTHUkX?U$tGZX!i4No5NY!pcL*2U@b>zYCx-t{L>&sZmQ`}+S#479IQM#X% z>yc*1$o>20)$jW-rq!>tTF`3k-%_t`f91m+Bfs9?ss5`E8`*lck~1ddoyT{K4DEb> z@w|HD_Li137DgVnw$59i?%lG$bMN~LXh*ZQ!}_er^K(cI?c7q|2^!wBWBBMG#t>t} z^P|EtD)iZJj{@E*8`@(=hhF}w!h@ZkRD<(+6&!r`XvXo`*d<+VL|XiF;}g_cg^36M zIz@RtLh3Hn8@=gg&32!$b^Lf?bCvh;pDkjm>R#2Y%CpsTJ6pVo-*sgce%F_IZ)X$^ zp2Q?w=+P1JRb77)vv%XJ5c8SWw%WsyoSuMj3XSuxDMrmPe{poU`93y>XwN>nRTH zXZgGR)&ce=_M*!_od3lzo$8IY8`GzXuRPKCm|bqbzz zboS5vAKE2XNl9|Cj7@d>6{Awerytt$u+5jI=VZ@%_7F-)7MwkZc#7aoPg^K>v*gzm zdi5;rLH`@~@yH;{{PrVd*rknQBfWM?Z8VMz$9?H*hUfpurd(Y)?&HPg)R8-OPSp~| zjf_<7*g3B1?2+4czTJLAu8twt7svo7rx&cNXm zR6cuNAs+tw0K0uhy5Y^#t|e~!fd77w+FO2p|EawS493=ad*z#)gDbw{&|>w-=E~9c zCPZ3iX3s#ny~n%03?zlS7}iCKu=W9~FoL&@C|d3BAI1}ihPtFT5cPA|s|+6>lJyTXzXi$n zZD*vX=bQmj1|KrbsqTcQ*#f-_q1$YPjzFKh>)V6Vdn%rU`V^i5xR8qhp-_qG;Jl=ip-zo0jWr)n&QNN z;WscWybER2c$N5U51_+sbb?A8gbR+q2pgTK60bqz1C=&9NhL0#pphE&O;(8rxDlwb zb7!c;>4<&cY#W`a60a==I?6_IMKb#}XnEExsHpp)hm~s?#!OqGcs?(n!GU0~rZj zLeM`IGOAWM9 zk4o%KD+Xya*;0wWrkHY#s&sh#P5>U%ov|u}q9(rrop`RUV#~zXWh9QvItX*qO}@`9ak|dQ zHiM}A#0xc2Y<}Jy$o$OF>3E5eZdZv5Q^x`+H)lhBVx2}ROdq8!O00*TO5Ls!7wbrk zGJIXp9sG+TAJW#1^q`hCR-gB85Hdc&PtI8g%b{S-_1Nq%Z$LzYc^Q4PXz)>7G6(as z`IT}@H^X2-=5!zda}mrA7G_)nBq28m%^}!1iA_L_&+UyS9_(Uc6LJ?70PAXF6LT4# zV6lx&%AJo;2D{nVWV4_MSPvckkl7JEDA?1k8uK&s*kFnFCtW)iEY(Q18OcRXpY+`b zNS?`$TL#Za<$cD8c|ESgg9EheBJ){9CpbtWoy|iueTYW7nAf9e1&3**tN9x^5VX5X zvDpWGCunzv?&gC%fQ-?Ns;BuVnoV%NzZONy%wA}(!NvYNV8}MJ69$#wMY`WVW&RBP zDYzt+ukYDmHYNdS$nK9aFPQ64+rf)72EgiF=I&x3OH+z61pP$ zw}^*jK8$(@UD@$dAOUkcJP57HE`!dH*}oHhugXgYl5A%80&;cEEFkITtMDzfHm@8= zwvKz~8ZA1{d<2mSU7NL4hk7@h3SFmzQ)Ipy0dl=YicLRyLg)t)w&gVE291=NBdGL7 zjr22r1HVG+bY-KB!>7l{7T_l`e_5#vX z!Z{vp2D*iJL0DPh>u4&0?i%r|SBdEnpgnB#HkH`EGtizkxO>A&;nK8c zQ2}PNnYbNwA1=#zpXk-5;ky*Wp#MmRWZ0K;1r$Hnt|Q-Ts~vBbA7&5?bEXgLg^1SM zWZr@n(yl-wYt7Cm-mXyB+Xk})gIT*y?RvxHO^N@2uy#duBQv~-J5e3&WVlpbqyNj0 zGEf!Y1YH?aSd@vV^lv~lj8u7i$}6WkDn32A(lvmWBV%%B-S92* zW|T7F`mC9mpZn7wp5kbDW!B|43UwE+XJ zS!%ANC`t&tjvp*ZhoD_#yoPk9nL0PYLXDfh#PE_jPlw+ym!e#1ja?V$w>3s;twzxI z?}l}$^Gz;Z?G<5abC}b!8iu}Zs9uP*QZrGP9`zN5ZlB^E2*0`=zXA0ScbC<3_)S!Q zL^Q%`Q8$QF(-7q}H5vUVUHuL#g$(smw4-)vA6iSY;yt+(wHf?D^(1~n>X-OUQkxL{ zh?)$w5mkrZ0u@4_3)OoV=sKy#FnAWJE`@l8NF9McUDVG(@2Y--nV_rM0yk3B;O>xb z_NZ!i~W7h(>$m zDM16z;94cXCLOp3gQOkt(4_Dtkkzg5&`@uo*~@KF|R^~kM@VAr#;28e0g*E zUNG)K!s3q+;OyZG^#s$LWL87q9sG3WtY>|Md}}X$4Bra$xKM5K*JSt)894h|`bRSa zII;Tv)Dv6_lOxCrbjD9-&X<}Cizub0J7NNL(7w%qB(5vp%psqVS^8?)M<+iKD0`weTFX!CWS6B7ozYv=cADaLhFNj zfDEogt%q)nP^v^RJwJQ`n94*8G1O|b2c>uy(xbfS?h!Q|?YY44y^oHZ-o>Pl00&~b z3Nq$}2eZTzG)?)?ew5mbNO;udQn;k<)M+LQ0A7ds#Bf9`0%vfxCQA}hshA*Rx zerN-Rx)yb;R2^EDM;-2r4yl&HWJ`5}NnXRp=Q=Z1nxkW-SBHPX(u;H>sDy5%dZS~Z zi_V708O`Q($j0Lnx}`?OEje_=oR*tQzT0wWm}jPO zE)`dx%z3@Qi#GZdx?#pP^Ek+3t&GPLRv~Z5lI0f}Pv`+_NF)9z`N`C&2-IM0?o+n8 zzKc;l<7x9;uuJG(@KwTBRaZj6J5bR|@rhuM`X~TH)ZM5MOI?D-;8pDrQlCoTa$fC0 zZa}?>-vsp}ns=f)huuc~4na&-YhZnfx(LBfRX<_xSF1}oB3+6wWvGErm8k|Hw%O_f zlRfn52<8U$B^pJpT8!qMr#?W->7f1&OCqWtN)@OJFa{Q?Z=tc1nh9M+>JUcA&T1vX z+(oU2madB5fiG4sqoTX1(qcS2tX_jhJ=7qKggw>8p!8A$5xO!p8d`d*eJI;U{WzI# zsO$yr&QOa`B?Hu4^tZFr6m+D4>MtlYNDW7Bxq26I8>|K+0z=eccv_*p!tXHkS7;fo z>QEb%st~9A(1(x#~{nou^U|u^P1wQJt^uM|~|&-$L3#tXT16wz?HV>LT?Jeiy4fu&`de zkKc<_3M^lu8c|aX>PGxFs!b?$v3dr-OVz`O^D^}^`g4@J;1EkXzk^*e}A>Pm?AsHF&p zsct~HEwu*XylN$Qd}<8L@~bxxrhpoXCY7L`LOM}BkID zDp#e#*gSO&nn(xrJ5*#xwGg9DzUmJN5p@pu3)F8Bra}c4H1`Rpup(80Cem3ADr9qS zL{Pe_Hz222twUvWQ`f+f?y4WO_fQtJ^i(yF&`Vu}N-9xdbdOSX9CFIkbI{mZy$SF7 zsA5!AUv)=!c7O@p*a7k(r@#6V4dqPrJW35vcOZsmsn1~HK&8-a2B~p~e7WMsI0mah zkU2!Xj@S-W{XnTuzday;;6QWIZe*ZR5cz*WeC7&sH0;mJ&Rmtii&FCw z=+C?)`8E_Za^FWA%DmKGF>TKM1brd%G8_Am;Ts1TnU|YhlnUr&7&vKe0hB91>AwiH+?_P(xO7T}^Kz@nXGl2mtA0BrerR$m{`o5|`=Cjb!sZgf+1# zbPU$m*Z+yj_3|^@@ZH2#vclwh`2*aIu?Nwtobca4Q6C_(hT_LEl=?I3z@sii-C(Id z2@NW%i}@=sWj1C<5@w=NnfHO1U64(i4RZ^|m+Ve@@Xmu=AYH8X)^<_i#!-Ak7lVEzzRWtV7agUm&!_UuxPl$#A` z)wn9(ilT$ff1p=o_tj;Fm?>oIr_HG}D-nbh zdCY$xKG_4ckTGUQ)Lr%xke_Ne~SPatR+q}_fT<#E;HRcfXHMI(`>WM zgVZ%#Bh}_nA|o_XW4?v{m0hWkg=RU89jT?&V@m^;WmlR1LRd2xXS<5p=Y_cqqAr0l zLlvUIDW$&-;^Y^Gw=sWRfca18eErn`$!zjT<{ z@FMq2y;w}vTXnf->8-j{lkfV@9jGt<(hT1N=*_u<%v&Maw+|-f4o+4GSipy$&YAeJ z^iM8QSe>J2fL7SUdfwT-)u5|;KsJ&-gCx3`Gz`t2_9s1t3S%sjmT8J*Bn{+ngGF9a zN3=s|G?MPpBTv9c%EHJ6!BN?>!rbjvbzoGggRYsJPMjugKs5wZ2I82kmZOGNby1v*Az{+1k5Xe7{iZ_z;MyTDGb-|b#B$9^ zyU;YW6AL3uz=_VR7X!9mhHi@DM$-A((PSg(ML#JKBPoN8(r7l4y6c3Yk{-dJfWwot z(@t1PYkF!*An9zhI2_4IGwehp=}9}Q!tn8Lm-CuUMm4~@1%V4O#00p(6yScI-L5+1 zhq+~;_R@02SLQ3V47q4A#c1~(I+=GNTX;K%xu2o<@RXst!Ud&@p$@#|h(?EQ<}1h^ z`Yk4m4n3&MF4i#;&OzwZbYvQ8EviqcJh+WwcP3yyEHb}lu^W)vv5U5GFOq?!Xt$m9 zzCG`ISo+V{1A`!_Gxx15P2_6U2#g1wxjJ~Rmm8(#{iycf*mQ0I80K!&a&VkR0_Kts zkntKxHh+oi-~^3in}0?v1}ADHV(!C49-O3+Vsl~y$YhO_nbQ#e;Q8q^Wq{ciE(fP* zq}==zH6EO*kqUDpA`_gZkxDawRu!DCkx}Mg3~Rv|X`IZ?HP=B*aHbYL%M2kb!C5Kv zyvBT$F4(s{7Mc?&ZMJ5s*Ig@Et#6Jr>Akk#TzyBx+GQrLLc0#mv(epVVrL4e(Wu&E zCeB8e2-e!@uS{&G1Q&QYn3z2zVP68GI7JrNY-&zyC5h^-dsgSI(bI;1&l-O2ZX5iD54uxL(5H$jv53}w?zs_zdyqOG|9PUwowdS%g#XU%>?nB{@ zKs#NP%1g`Lr0QDJ!m1EfqxVnIWOD~7?f2Vc;ExgD-;#$%VuUHYUOV_@OyUpG^$JUp zc-u1*%SPKguH3bkMtCSHt#D1^pCP6v^KCl@qLCF;YguPUOVJLa_XrrC)j{dJ3z?@I zRqs8>%u2V(%cJD1R5X%;1-|PXAx73`7>@J)>ATONSSxk2DMU@?9rryQN9Naaavt*S zC7Fu>i|yVBkAb$_M^iY5^Se2A7{Y(TIF|D(-8J}?2#Y`1jz@5MpAF8uQA#f;($Pb0 ztIGx=o>^C_E-}gKifYU1(aFkEF0RkH)B3^+? z*={jN8jSCNZy@>Cst<#WmVlikj7Ou;ulA}mmKg)QinN!}p?|AV>Gd4oGjUF6G}N0) zFJ?TqjtZuC$EQ1#UYe{%?kbj=0AoK?dL?-u@S91y5VPG;m39#6cX7T=+A(z5k5uw9 zSaAaQ=cEyD3#xqff;tNp~pQI9Qi|0V6ZWm+6J7_xVZ)=wdz$b&L6v#bL^T}b)Ssc$TS%D35ApkVRX7aBdtU?f z50LYF3jR5e_mTJu1(Pe~O;9NK5Rg^`j{rI01N^YZ+e#6;Z6K_~_!69k-laU+XMQH+ z6P!UGw0dls=cs!jhpyY0# zjsSHSPHzVwd?4mLoN2$JetQ2T^tL zWRTTA9zPrue}o)i^-lqfW7E?yT0%8w9L=K@?Fn?EJ7w@D4Lz|5(v|)_q7ph|-0>EG z%0YzhOw$j@gi1hJ3Tz3^&_E#kGz;UDQUwIHUNM0j(8L~<1|gw|AZ!N5Mi#jc$QwxP zC9(*}F(f`BvI2-@+TUOaT?OPRAiU?+bvfG8wUDOtFNPN5PF40xbQbRhAl!F5tL)m!z+Nvb!biMWx+i532upx5oRt*KIpcgtnncl@Gv*;N zhoZA7+MY9JC9u7fpOrAS zEzuRo(8Kv;Bs@lc{9dARd!f4ZaDE*mT|?0v&hJ3tc8VsK4Ck{FE(Fr5)x(gH`T)w+ zAYtlvTwSKJe?ZYMfXcfG_fhnAAde!kjiN_V^d3+=x6Vpf(uQbHU?FnOzZh&yS~iVW zt5vr5Mv$I^oM&-*uLSZM60hP+BTLF%BDfhyYc_iVb;vQ!T#HuST{r)7{Hjd@vEb=m z3sMo6^>0DmKAe5o(R(VrTl;U||G=qNcfIWXUgX1C8E23?v?WUK(4Gx^1ZnK^W%gQ& zZx5SB8vA~4o5rssuf|!xF`$o4JByvIpVH4zn71CkJjjlAhTXVt1@Co~@j2x7x7Uf! z0)GlS_1ufDXg|39@pK#k*C=g27j?w;)f?L5+t0 zODVi4zAzaurTA$I$FcRoV2{t2L)=8Y8kyw5n4iFkq9Uz?(xHU9Fwr%l1#%|RL!$8k z^p&Zei9O*4XV3TH!e4Oe+4Jv6{0(Q?2jJ2(5v3$VfH^HCwm`I}qSQ&4^2)(r>Lqo5 zl{WP=V~%Fjg@*Y^yrNYmrdKxA+~SybUbF5PPw5H*x9^CnLePtQr0g zes~3QHTWn6Z5NCq; zWt1^Cve_K8nRSteu3$R@4o_TN_&IZPAy5|OGCI5r8kf7qhsIttNMw$op3<9CMvwQv6 z?}9a~Po?ppC!@zai0?8FyXZ=9RT;y(EHzXIn-Po2_GkxFjv)-{7AUjFQ?-eWuOEYW z%Rt7EpGzlWCx+^lv7Drb1MQDl`OVV&WEH8iqSgG0FB#BD4wvz{ITk?wbxdV20aYF zuGQE1Y&_Yzwy*6@AB>(uBe*Y{$~6-YwtTgTPh0k*S67sgiLdA5tM>+Sfz{0IvtI#w z6=#AE{M_CXjfQCK+1|oLr}thc6$qpzlu7t5>BGI4cTt}A!#XmTn}P8%{9tN|lX0FS zqe;v72IWsWGQu&>9Xke%L}r7QQHPSY=M8=JR?r|7z@2TKcTF^JQHjp0ydS%KwK3C= zIBIK)7?AcT$&L4Z3`p%j2CqL*e&Swx!`;Ug-k>i_h4kABsg-+Bt~w@u9#&DhVO4jg z_(_m64rix}@ZGHHK6}B~2((_4=BzTRhmv#?&>!H`8o9gKhDJ024AxZdk=hwK3&m#M z2BmgDX6mMpcNCScW}ZpedGG7=IKAaL@{SC2kY7aEr)VQ>_9@yrn|;a{&EE6o2%bFA ztqqb43?Zm{zIsx7IJPGP{0I!-OZ;@#nZT~|8n9Pz8a?^J>ngo-$l_eVsZE?@`teU0 zs`UQP2VgvmbEnPv{Zn!3%wxc4leTbv@vZ6N_v_- z9r&=4$(;#(l>y2qnme7hih)e!)?$|xhUY3zCigy#;>UZz5k`!QUL8%(LnBxuPZxP; zB1=S2VyhI`i~8Nn0=&kz3v3=9E3kQjQ{Vw9@DU=gkp;LwwF_*lj1|~8$tkc&3XCbl z{tgRp{bm=~Ff3MJ!+58_ol>9zK2Ku-E+*{))5gRKOq=c$m>~u7G5Stq0j_840ux8a z3QU~l6qsxm7%>Y@n~T%UufU)86)MhL+>4hq+5F0lxp<`BqVC29$-^EkYWrcT-o%c9 zs>#Rc-3p`viE<)O0l5H)={R){;AZ{z=>fU}c4Lo=>Do_S7lCvsr123aFaPr9E+lRz zat)BDkl2n>>*7s=@2`s^PfSi-`^av7sS~5i8FD79G z!x^HI6=)yxaaP<3?IVk4Xy*b2hT-; zH(@rep7eU}4RGzlsn>h&A@L4QL-X%JLg}w3{5iT#g)#vSulgvKq63HAn_UOzsM{6)w=nE!|r{Kl2xDwuFw3R02YC!so{ zgp04m@a_wSh28?fS4u6y>F2WDj9{8U8H$tDH5LxY;Pzcp zG{f+Z0`1>edtC3LjRlQ2Ej9@ai;fPHLF497hiOP~bI3m*2`(yLj+H#)Hqdy3GVX=ylO6sJOZAqs)lf2-WJhCELYKBAk3gUbIboD( z$FlS^_0y048E=EPD&<|>}QNh;0?l7B@d%yPC?_fj}O@H0NkPWeYLoF}Rrj4N#|bx(f(K`C>ZzD7AxofNu-VR4S|1%FaZ7 zM1^~SMJsv^+0WwCie5wF6(UshHWGitnJ@$eW$_V<&qOVacZTxS&^eUG_#6fQ5tf;P z>=yB14UwqyFR$S8RhKO+$2$HRWlrMMwG>Fjatx=grF!LJ&L{-Qgz(F4Hr3nk9|Vc> z)UBGNFAn@iK;t~MElPt6xS01C{!fv`>-=5OETigc(D-D5pS_OdjzlxPe^M)bl(x2SI1kKn;*t4+Lzr+30C5a@E8dR;0zVHD|H0nfM`D=wY} zZk?OqJgm_?qYY2?6$rGM1j@kRpx{}-(P;yaV|k6yX%Or+dZ&4^o*kZr?w;x5fm5T@ z3;w4gd4 z&ZIlWXpeCX-$nbInWlolnDnfchS+9gdtEBA@GUZe!688t^_7#R%&?R%2vA#YTo@49 zJQRWCDWbgo+oB23`S%4 z?v7q}4fhBtGWV2F+E!7DyJRoc8dh{cNIXA_{H5-SMFT?Q%A&R5J*&XiwY^;(y!&LrE<$HSYk=kY>*ikIx0@?&RoGEr^DRi~+TLyb07shJ@3UIe z6`%hd=ui;Hv}g|)bV^_%1v+Botf$esgAH~!BRom3V^fe}*Dvm!X~FEh1^q{-4MkuK zT!KmE(3fGlVuFqqWear+Z0CF?c~V#Ofj>H4OrUk*(s`XI1POv zH++6pib_UD8ztQXm-?eIOrRRaaKJt%E7n!C?sJv0eLb%LJ+TygW3yWH#c}g;J7Vt8Ock~6 z?l!HZY&*cybwi2P!wmXR-hN4#gNJcG#%`}3)Pdl@K*%vZNsYIX_IcH0qBx@D30Be) zHPu?O&zorP@M1sXewziC^C*dj!Y%Wcu9C?y@}+8u^_J%gw z1-z`F`H=a91_a#yrU0YrX*|?BXwJ>I2Gm3HAiK-fz8N z-eyS}IgroGTnm2$KP-G&> zP8wvbi_i6lu42g5v^!(82=qf2AJ0j*bv=S)1iCybz^9G0E+=j4qDV)VPCL4=D1xqz zYO?jUy4E5y2)=;M$64CY(L5v$fiqu4_XshDbVc!k7-!3~*BuC39 zqgyB2jAoau9Av=w2s`^D(8cmX)&+h20Qgt+<1ODPHPvp_l`&e4Zq*P@bA+#tnr8FW z#Auajx=m|}(UR>k<9bjcY?dleh-9*bOJsC9#*MgzKcX3L1(OjY#Fgd5*kB>r2@20GEhQeb_PvMkBZV5GVDXDO`BAR`YC(?e-7m=%I!u(MjvMY z84R|guB`3qNsg{hDvZYVc=0{hG)qoQ(gPkRiba~(J+R#AyBjfVM=@juO7MeP!>@Dr z#v*0m?-a*dnG0e1!bYT4Y@k^i)Td}{n$b60b9KRJ-?UljF*Cr&39{7%s1rMBq4(U+ z+MsQAE0;8U!=E|f0vo#NW?(InId)My$w3gg{IT%&mgB8ZO=|&kG3BAb=jDSle+mLQ zWja#RXRwTY7xaE>MvYd>BK9HDzh6NXkpftkK$XMYo{OeWwP<4pUpd5~UN_SKMIW_0y^t4eNDmib)-cMj;L=*{#ISp!r7}l>*(w{&-xbR z^-gFWY~k#K<`Kr=hX@*w%WMOwhUmb8w!8X=JkXsrrnQ%IE4EV&AC$5Nq~) zf|<`c?zzDPxWT-Mg>E(v5IbQ0f!IOw5Uy^lL*92e5WnmFlGvBtuZVr^U5gpTTI;)x zk-g4$GqIa}w-US6x1HE_-;>0i^gU1PdEbk~Ui9q+rrTWWF0@Yl|BYku=KH#XVi{v` zB{}&6h2M|W34)XAArHVhbFT@o&%{N;RBOBUQ!l{h-rYVd?RfaO7{i}vA#&j*SjM5- z@)qnOEDk(&vZK|sR$=ldGqbR|H*Xz<^?XO&wF7%V%eEH?x}y`v3 zGBfl+xan(oi#@kiTC=M0Yctqahk00f=k?Q`26$tLvm@5RyeTQGPzOUp#-fX^ z$V%72>utGHr5z2ur{VkvDLK3kRg5@My3QI$81cw-zpzY zU=QrPFXb$Ybddn>I$56HT!`3dvk?u*L2Mr0>hak;ND#B|cO8va-fvkxTp@#5bAXxA z_3_4$O9@mOKHeB|(NKhUejLR*O@Wl95%I^z*F}mqyv9H_?{375A*PMNQ0y3^IUHkn zm!_p+-h+t=AO-=xYT@gV3d#9Zg#%)z6^2GQ@z zV9!h++(F{ul=yF9x-CZk^&XRa%9{sod+>1NGW`OKbT+`eg*r22g;NbLFHI0}%a?4W zW*T1HL~*0`RZ2AX!j`#99F(H0>>R^8MpN>vO`ZomhL=}s*cj2G)^rET5H_Y-Pe$K6=1Xg7$BT@+QCJrl#xoPtgt4E+zFZ zU!cjqP}Cq>|MG*`kn%tLk>R;g`jL8ZC_xNlg?jOyR>vceZ$;2 z^^=+!md;sFTe_@n!Q6(XWhISE8r09BYHDbxpSN&M-I8AQbxW47DxI_R zqFzfHmelsDoin#C>g7dq<}IvSQv3g*#$}f*`#;f!3N2kQZ(f|Az5AB*E$QvJ`@g8G zR*L>FYQLs#S!4a2OPq>tMR?tkn%Whu&|9`w3gAmuzpD*?CxZwgz<+v1=rWV-^}m$T zT2ucoMX{Ismqm3z9q0ZxGXBf563hRxbZarBGY)-OQw=&mE5dcX8LkgPaRda4C$wiT zYr3SqcJ_kWB_#{FBms5K(%LydFoe&pshvM(d41FDrb`-Ymw|@00SeUM75hN2wS+WS zkj6>}B^@@5w<5i9Y2AuBO|{^#WmDt4`Z>#%&5q>+G&gG%YR z0!vJK?TXqZO)fTD68eIRhP#9)YLDzLGWN45ap}@Imq28a#%RLqxy$KKSQF+o)Hf^z zhEUL`i!j*Eu30uOnm@O$rVfa0kPc)N)20ElCDZN321d{hgVwaPb{@lsXB#0r8ki{0 zf~5`18-XR;$~hDO!^1x|ca#tABJFk)sO_FKH{e*LpxCmerFBad0L9H$(J5h%)sAC$ zjN&+EQ`kCOapcm;i`57+G1XpUDz7)qt9&UDZ>XTe+Zk&l74fRUxXe;9wp)OB)6z21 z$ZB2!j?6CJoL*jUkvAvLn_24h`p)x}_)5>2?k)0xl~T&RMFb@+u!xOCkYi2rssfGT z)q)<&Q-VK@b?f{PZ#A_|gIQ%>f4(=tSL)63K{*p$p{H-en?2wqI~7%k`gnOe5F2R!QOE>Z6Y(;qH(tST2#qU$Ff+nhr&2G|+FEhf@)%(pM6-D$u}yaff` z`~pq=yKcSXOY^L-^Ph;O$>Jlq=budNY3)Y3F(=Ka-3RZ<@`|UQpq~v!&>3`0a?pxkasU8u01$Gfvl|Vq5Hwi@OE3NQm<$05Q zMQrdoBM6uTcl)y{ve16h%rxfc{zC6FykVS4J&|;5F3{mk@b%Wvi*TnvN;}45Fx|3; zrhKiTz-wz5>?OISJr56$)w>;wQoM!Sf&qn7IJL@*QPk7IiP zEC5XLb}U7*H|97Wn zCX+iPfeay%$pM5bghN0DCD%YCB$$L#a0nrga3z}r!8@ModM$#wKs@kVyz#&lj|I;U z>#+--c&;B;#bb40(cP%~k?-qW_3EC^fa~wSUq2o*&#CIFcU|wQdRKK%w|CSSZ{{#0 zQS2S%3!sK4g2=SeuQBP4f{j5A(CIEzx@G{GyJcNRI+8PD1ZS2Hr;oTmvBbp3mwB>!S*BtT~fJk&rOvIq7l8 zp8U|=%9XzfN98ZsSLBXrr4*&lKb_i}=SA0&(ufHH$yor36z3bXOqJy-T}8Sqan`pi z%T;>JV_8PIDP@7W;qnUx8|$n|$4nq>A}syVYVM74WOrN8hrvIrVJO3B~umY-z( z#n6iIP%rsMRUV4^ipcK|`I#bcseH+7rd;sNM#HO=Pzk89PYs;3x-Xc7T)_FUfz#H_ z;+!s>NXD(WJnz7PG9ShHre}v2 zXU!1b;q$z4C2Bm}rW*+rwbD9UH#}`&XwcgnH1Br;1(huv9qu)T+Y$+f={q_UOf!|_ zEs;<(h@(S(%#d&B?kBdom;*tW>!Rq+OostYNqi>~4yvq%C+jYCF3WoNe2FsMwh`_` zUlWr@)tmhVW2qItV@}m^iBDq8l-Q>@#N%VCl`s8^izzB5o4d3`=> zIYx^NUyrV)Pd(XUa_}8HP zv=^wC!GTpEG+g`_FAK|iAgX4ED`r5S}*Se-tmddjA zfaP;TduOnh7D z!qqj^6~>v^M=(~lu3m;^c@uV4I$KsX87P|Gujn{y)#BEbVcB9f!r?X8x|s-hB42GV z;5T-Q!;(x#xBHLGq~cuq-WeK=HEU0F9x z3W4%qM`mS92lkAN_NKO`22>bQmVB4ghG*0u({=M^%&4fZtt>04ik4PaUs9_ob0!!r zn^jj|GXv6V>*__g6s#R`I~vlvA;#3o>Tqr4)M+ZwsCFASE+V|VB2*byUrt_>T64?>qMc# z(<)SMAxgHnlv*kUmHi`030uRR&61Lw?tn*o!|G*ChP3zuRJT<(AKu{EMsj$OJ{fuB&x`mVzq{kP3$Gqw<WG448%?(9B#us~ytZUcxW1%rdbp&#+}&bq@6wujs8ytLowUpA z%EBeJwI%bUh#)h0nx=m?mhnROzqQG_{`zv};{(!bM6_htZ|tXDUmba%xL$M@v#N zfMXV@s1=7+rK*Y&G!1g*9*do`O3`N4U~pQ}(Af~~XgRydKtCHhMk=dmX=ixF>ej`& zhMYJhRjxs=yk=G@a#>bYS%#r2Qrw!ECF1Bc9?hF20}qEs$tngq$(e3YY4XN3?d>x9 zVwQr_9wj^Qav@9x%i0^3h)mH)rGa(TB{OH1AbIh1&nfI4cA;ewaJ59`jFPEJZPgqn z8AU)>Us2^|XHg>$POD~Bml>2GXCi?5PIW83^jp>Akt419Gcdk7I_Vz7b(WmMgsLj$ zqECgZ(LtaCWz+4V9<%dBI$iI)>ukF#Nzd-#(Y82MbMzb|o>Y^X>Z#$GwH0-kAfWX# zD@xQ@z-o~W9;+_I{~UHs;8odFKOyP`0>XhyGvUmx#e7j&?@=z%GxkSMVCUY!XPGn$(~$M zU!C+g#!#W#Vs_oU>N1I<%Pt+GX-Nwvwq=oo?E)i3@zfE^rd3wad~o+gH9P1TI^1i5 zkQ`w8Y=GH@Tc>6uuGz*=%hMsbGd&Ig_kN&1)5? zD6g!SiVufMs_N7j6frPp03ipF?AO*{aF_=Z&z|Wi?U+4)(+>?oWf-Wjs=Z}dGwQnm z=9|1i1R^*GNeP^(*=a3hel|BrB)L>*;5LGlOO(B5kLLPXU#B508JV(SBxsx0xeg}P z=S*EKt2x~|ZKL&2j21BfSy$+9v#RRDHPa=stFLK`XBkv{O?y)qkLe1Z*|f4%Sym7z zL#MX*oOxumHY0VT)X$qqyBelH?wV+#t>e^1No`qJ#=SMGao@%2rX@k#V9_pFP;({? zb*;6FTicf)!yPSJjip-U5@TB{+6Z;uAa`MeaSc)RV5ifSO{*xIZuhxfoxVg3M7_P# zFx1;?oHSf-uZb`!J7CDPuV{jb!ah?SLRzUAW?Luf3VO4&Rco$GJL@ZF^qLRVYR6e2 zA$so-AYveDtuS!W6Me6BwVDcz#ht5l;X5L#rG{<{GZ^(|R+W@h7?Guxp>(pdwawMQ zSTtcp19PywrLjS+Mzn@%^$*uoRM%D3SI(}icNrckiBMI|9AizJ^i@4CBWog8HHN#~ zN&!@_(PNR65DOz^)kU)1YaSFijw;I)V%_}eQfXsro2w(~Xq?|mOJD)Ys8?HGW!U;E z^EJfj$xaQ@y;`!m1f_FLnzgVNA*Nj7^lpnb3`R2T7(aif(bJfH&k|y(m3qu8rqzLUfvhq+@OWk08pQ?friK+*$)Mx8bgXV#NjcUQI%jC8 zWy@qbh?wynnGOI>1}rG<2?`pO!$ChHX)Eh^!)8dR5KIbV-V zpiOP-M%y(a9Ia$;JlHYnptoi9oM@}CmvM~Efrx&H38khGMA!XYtq96XWCy}tv)J>8 zV^8Uj_GB+wvjn%JU_cggJu(}~bMBB-q|sYeV@!loil-L^=w34Qh=-c|Fdbrv15*#p zTBe%FX;NhdhO25|gEp;hggJm}h5fC1BBJZ|Ei0)mgZU13uPUuPdVH@udVH@OcXY&w z;>DVQE`>{HRbpy{MJ(1DmaP~IxO;?Mn3~#3taDVWhD&DE*BH*4OQh%=Dsx5cZS`MY-q9G!+4k=^jE3zVV@;4PiXVq4qX-m0kV|&Z8S`Td~q&5=S;HZ45V}m_W zZ<|rEdnsPkM7tfuR*~E|bCXgKcsNF1SxvRtx}y;)lbp1-9vM3&ZZFXoWMKK1C7pAlEh!MXhXE)uOC@moXRJnJepOl+45`5xYBewW__HN{-B}906OGE|q~}ojoGb zeU{qcl+l6;h%7rf!*U0k0Od+)J1`4lN6Q`@)UeQNnm?+rv#O_8*UV94rBi`(DoWIH zROb_$#jbr2*+gm6I|RD^Wal(en`%`ritfyUYP3ZfrFN$DG}VYkfL$X^%d+czK$J`; z>t4lZJHD~GNw!ch8R`zLdI>x8F(X%?X3(mN93B+WK+w=BbJ}SaBeWD9u zo2OduKg-ZjRS{Ah)=>jnK`}w8O?8Y;x(#p-U`wM?Al=iVTC2SkyDw+yQ6FhKotK%O zQ8NQ0@2nZpdXDL%=WSU(In8A&kFgp%pAm1_EOvIQbzar_vbN&1SsZeD^*y!jmTdwg zXSa~v$ra-e_l$S8t`g~Xa@aqag^{<)zye{FY$a)>kY&BzB~v$-uWoE|#?;8}ldKo@ zeukcC>Rgk0wOk5O)16dE^cII+;5ubjLqBYIZF1;RihZOzf$RcvU4}CBzE;sGmsD7- zE}PAf3`>BPx0c$gu53-Qm(R{vD$7j_q>y6A!X^clKv<-q6TtQiIx9h0*0~pjk!@1R zDn9;d;hl}XK1tn=t$QpcyEEPH>lagM%-nOJFTWG_Lh zwb;^;B66xRWDXZ!CuJ<6U^d|5N~BJ8O3t>fYY|;hU53j&wR(7=vMp;O3!c`x4IH%*O*<0jcd>! zSK(TUT2dnowfollq5;PVY}=Nr?ZQac(X%*YDT^fPQZ2k?ypL?hI0l5y9!)TPEzYgA zay=%pE$g(SvPadHRIf`KI(J-M%V4v*X)PC<%7jpxg2;r*R;qR`qa)50QXY3S2wk;9=Wt_^muWvY;EWq zi5=p}*k4`(kIv>bs}_R|?TyWo@lU=pCyZb1~;k!r3`TW5~Os?LuK+_?Wi4FQd-Wo1CYr4X)2%EndqbIh!qUDGQ^(WmCg+DTuRL2+bMEXDOr zJ^sPNX{D0#*s^~CozhGXfu@ff0oowJ9nOeP()7xuoq{gImdJkHW&Ah24u2vIOh(zmc@W>KW zT~t;5cxfv}2np&MT=cZ&SR0ZC=6g;>atVo*A%oMB$QCJwQPINkS+#1DOhQT>@p7cP z%7rWKO1*hWDw0jHYG&0%+!<nL=A!Sx>ziLB>t%ptVYBBQl^=Z49vWV(^iN$5qLjk4pvhHvR zrg6*Se9>$enSluqAqXTVLN))49Hx zP5tDahaSGw=B|^jx>}7bE6g)msqKv}9hfca>@Txi?M+LuE7=@XDo1GaJYz)G3>2XI zNyPq&+!Ca#17qq;%qq3jSRcu3Z(osXS-l!24erQm#m=f&{oIkk#VR#?xLTrg7H(sz zw(S*lGn}%`MOpM9s#XNOtDgfel}=mRdJjeQBYRgj+=(3*F+DH<;x0bdAgC^tV8*wV z#dS-TTc2@(83t;(Y;l%gx|KZjnnU%jpm;mO1h+`$RMtoh$bD(Ld8T5j!ex>WZuP`n1G08^ z=H=)u6qO;Z-}XQyb+FQP>zcarP+QyTp3-KyID{PPw0OssbAypuCGjSY=qtp?zrDFH z_Rf+vW#F=;dOJY(a(z3hOf@Pcr!MqaZE-f!@?2|3hOoP1?;(XTwur^Z9W|H%awYjp zxjzymTe2LBr!c3fhNZYU&>nG+J2hlT*7S&{ZrDY$ws)>n8$_WP~W9w8L zdu1inBsVR&ubW_TiYs<{`RcZ8?7M%&Y*(r)YfGn^ojb<3afuU-{;QdDv{DbHxw<>K zO(dE$y?sRb3+FzS)0eSr6ihD9Ic7Gyn&Fa`kfI;cHix3r?;8y z7)Q>HWxe+s-8&0%zjW`Z3OUeF-03!Qe&<%i|N!C2R~eAgc9J+D73Y@-CHZ5++n6K zvhl*B)6CNN`_Uyq8CvRoR`0|QJxk;feCzZuM$H+x=hTR{CSAUas(xZ>hSCFu?< zz1V1LKFf76%E_(VfEn2j>NUoz8(*D(TuABhLl%W%BWU{vcbg-aV~ES8Rk(Tg77Yc_ zcHJP1v(^xksl$-1Yi-&)3WPLdYV3VeCOz@=rm1CRCk6{k+E)c-?Oks_0Y|UEYnxV% z4i=WK!F_5$c^D3sxygx1>Sc%GFNZv#Eu{!3#o^ZnX;x#u_56_6D( zGd?*ef#t~x_94#zD^2!aB56s!>_eUj=5~Aje{j3=DZfjS{TE9z&q7ZB%k1GOup` zGw=d7!|+ZRSz`F&V@v#ITui)`Xr_5G%)Vx(6)^joS!T95(358tn8VC+d3;sx!|mfS z4jply#gh@-PCUp&J*UI*v*ghxuEW9;Uhu>c6-#tH2JSr9d3mOm`>^yQ?i?=*&q5jG zxa0?(jp8~iJm00ayg1b-B$v`}VsKvKFTzJ3cpi-Fu;e)>uERpj_D;{;8|2wv$x-Pg z8}h6=Nl*G;j6CSYby)JW71v?mc`Lo;ADWf7#k&Ttm~}EJ3dO@@lod|M7bwM$(tB;{=_JGGSEa0 zOTDt)?VcPZ5AOhT9hPxQl)O`1XC?n7QSQ2{*NPK%N+ z4@Qj~mQfcazs^{S(;{EyIJ`$y#gDYQ4&UyG(C7b-vg$*-54zlWIPtB^ZHE+EhJJ&9 z?PnRYqw+i3KBZ_GbEEP*H|qTSDEH}6^5o?$k;5_;MjZHM8D~U=KO^e=qA2&`D0gF& zyD7@OEXv&yioC8&JQ z$lu)S{3*smQRiRed70DGjB?|hsPkV$xuLYqA@Y-=+{Z<^M@6}(M!DxlxqlVqzBtN# zeU$s5DEISG?sucy2cz8aQt>=gdqlZ&qugVo+!ayoxl!(xDEE0$?rWmlw@0}jk8-~m z<^DFxjc3F;hm>a^+!6hnYfOkbFKcmqF$RBF1Gi`qOS2tT<2db5FWjQ z%k<D6!HsyMGFsAsaOM*v*bY1^)Wn9AR|BAVUIvy^e>YoR$Ft(dPoDC?EEt%`(;R4P-TnUa^A~d?~1}p)G~6Fte1E1|5i#s*R24E8o3?CzR!h!eC~Bl->L#H zsXytxy?6hAevkPWcY8yM6JBaB@@EIhoz9QCXxA$T>Yoa|eB_=OJ`DoT(sXX{Lzts3 zv%^nhOI_+)tKp&V7Zxwq9c9{6RNCb!QICBolX8FV`YldJs#osp?d9RV$r&f8ghyAd zRJp!yScc&Ev-Mt8{5g8~#j8p6aW3A#D(BBL)IOR}R$cMu{9$m%Ux@d4lBbeleTx5b5eIu-kdi|p z;}~Wyk?9_IIsNlB?QjFHpufFjwZmUUe|za^`(HzUdkJa#ucyDg6tw*}(0`JqlkRo& zFNyNMf&TWA3Ub7BiQhzjdnp71RoZLV44jkm-P#U|zme^96YKkCw$ClBcT}R-zVW}q zo0WyA_j`o!e~Iq>zTd8LV5j??rkj3?JN)C4HkdMk*bWp1FuLGB7U>*PQ&OF-i368 zFa%ZkP|o|r{d>KaB<1;B+}rT}cKXLl{t$k!5dLxuo1-c1rRw)?t#9$DtZbZ;{N)KD zze{*8>k)}PChq$U<0B#5f2aEgA?isC8L20gULE?4xVIXHY#YWufET?AAH=I#g$Q3S zywNZg3z43@9a8GyF`j>d=ii|JN5bV-O(JxLEUV%Mf z;iJ$io|kuY$oW*{e<1W|pb+(Rjc_~KQ;72XOZX7hPzXQpR>N2=oQLw_7`9N;>2J^% zIfgZB+Ws+UEDyY5lJvL|6Xv+GO6y_Fudp_d^XN2bWIr-X2&KytuEBeq>0eAvAWtUC z$Qn|zC~_B*Z6rh~|BFdfopRqm-b6wrmH!U%8S+)~LsIll(h>a=CZgU{dC30cAaXoe zO4g9l-z8oPc_w)=xt_d|pHAkJqsWuUsbn3wgcN<1_~(&V zkiR4EAZ6_+;p81a!k5YY}ct>k+02J$BI zZt~CMKghnA=%v0!latAX(M0!$n{_)Z<)y}D8KQf!lBMZqQavXUgIfV?7 zRb(wWmpp@9LM|uU$TP`v$&1L#$!o~#$Sven@-Ff|@?r9E@{i>6BP8@Y{qfP9pEg4|8MNWMb8M(!s+BtId)BoC7RBL73iV4)%PikImr;#Gc% z8Dth2BnOit$T8$Z@?>%jxsYrmTgX;&4S5cEA^B_aYH}mFnY@L(lf0LFi2MWjH2EC) zC-N`ko8)`s|B?sDugSyY_v8^0Pi$88l|c3(Gs)w~d~zr`iaee?i7X+fk~7FUavm8b zo5&U9ugJCJdE~|9Z^+-0*OT4kt>o{?`^iVho#Za^1@dKbANe-<0r@xb3-TcO1DS$7 z5z)hJau|66xtzR~yqUb0+)2Joen9?>{DM44di(11(#RZg1bG4(BJ0RSmyzA%4)R&@FXa2= zm*l_5BJAag-i;$ClOeK(oJ%&4%gGM%3UWPp19>BP8@Y{qfP9pEf_#SDL;i()i~NB6 zg#3#9C;2@YgWJHQTnS_bc^o;I97RqfOUP5nI&uNoM6M>+k#~~!k`IxOll#cG$q&d+ z$b+OG8(os`WHN&sKn@{W$#coykT;OGliSIs$(P8t$xp~b5VmN$Sr ziCjRQNB)+)lYD{vU-I8%=0GiPBsq-?lV_5bledtMk*|_}BYz_M=4iP?$Z2GlTtQw* z{+@iAe4YG)^aQoMc;RWdo+NC?eb?kjo}WnfB(jA5RdmlJXVHHV-Al-|^uLJi%g8I~ ze*@iH$Xn=t58V%tkI?^*bU#b}5B*=G`z`W4`hQ0Em*hX_{{!7Wkyfs*k7Ob0A&txw zc4D8A?os6NLeyKS5c)WS{-=?%>EA$i6WKwoCC?Qi{;%o2lDtj``CEiY{~r23K>mSz zlH4ssxL1XU_ceK#{#G9RQLb1rmCPXf3lV>?P|8Kt(SLyu`CKN1oE2mn{m-HM0`h9| zTJi=V;@?X5o#X>Tr1z*0=|4~ZJ>)*}P4ZnK!W|GIo#LZ;|f{A?NQxq<4_~j{ZN<9aEssCy*&*P>A$L(|tU7GFeJa zCu_*L5n*65_;f@Fq zFSk&0h!Fl0gs9(>$Z~QTIYWqW^M#0iE_o6CHwY2`2J#m2c5<5#@plLj|84RE`hP7% z{6pjqqWEqMWbL{gDvm`;7ko5~7?xkk)YRjwO?X2wzB^O0FQU zB_Ac95F)*ogpm7Z@@?`x@*^R_eItbYlo6VJh43FFMEs#-5zm*Al|qD@$MXxxrQ~w5 zO$hmykekT+$lc_d%d_;)+KSlR$@&zH}d_;avW{lGQh2$i%UI;mD z-37vS z^kZ@&If*P0B7CjzQp0GX`%EF^T~9th?jiq5eov;3)!~PcCFJR3J9!m(JNY#E2Km3_ zPeRyoea3<9xc`70Nam5l$x$R;iKXH#7h=vikNy{uSCH3`zazWJtwO|mOE>}bPXDjT zf6_nsc$}Yv`B#Yi4I+opKO|g;af<#6$))6SvV&YpUMEDnEy7O2xSRg>laG;4kh_Ek z_bT1{$al#P$phq9+$o$S=trA@bp!sPhp=CJT{HCOJrmaASCWJb4OPM&dcwsys8vdE`QJDY=~NAlH&z z%KNuDJ{{L6%hzm0r={!a@L{~7Wn^3UY!Ld5?_i1;xlYWjun&lDp5 z0J4BABu5Gn?nEKtFC-i3-!4S_Gsz3ci^$H*th=Y`1kOG4!1UHX4W9w5IWza@Lf z{}Up98pcXtKnOX7LX>9&IhyA~WEHuH=a-Nz^j}M!M_$YG*ONDsw~_af50X2CQZ6C# z^EUn8BR}E!FM0k4`u{}6PS*KPAT!7Sd7N;eVT>Us3X#qXIhR~Po=}$#G;kIh$NUwvy+Omy`^43!#KBksk>|hVg&G64>8T|N{}Ixurh6W_jBF>n$ScXs#Tpyi}zGNObl01p5 zAs3Ks3*48KqyvLg*dLIHg}xgg7}(2tA!C9Ag-Bh0v!(Lg*8cQ2LD|l)kSMq91e# zPcw|mh3Kd2g~;C~AtFJYRQmnNLK32tKe~?MEOMC;^45?SlfNZzChsSoBwr%mArABCq(@`B1Asq|1Q#wD`b2_el`e^ADS7FGPNdgvd{s5cxS>i2QU2k)JDt$j|LU-AdX9W4y@q?7_#=OFd47Qq`MiYg%Z14AjdX7nBH#DXyKSlR$Ae#Ur!9&UVda`xhSU-Dwo5r_mNI#$TL^@LKF5@hm## zpU8_!YG)MTY{TOJ7D#01fGtbb{Zc@cSmY0y?!To+r}i_Uj*;Ad38~WS{l>@WbfV54 zL;f*BM3(~(mF#RXqD8wh#sJ5VesrLyYL5hP{SjR?T~xLIe88yeM*gb)^Eq~f`LCId z3U`c@T>mlu@5#9X{$iTZfsc`}{^R_APm^JOF*#SbW2B`1e*fPS(m{SPok*~#WaQ7) z`Y8fGpN=cce@!SV+%Zye*Y3}%qlj?_{KYh*10N&d$g>3gdof+%elgjou*XW(c~ZeI zq#6nL%c=Gbd#qID5eL7JpbGNKX*t1EGSScUh)(0E^T$Zwm|>Lk$P+@M<+{!sLt@m~ zs0z`~7>Sk`8Pa(E7;=vpCQ5qLlK_4`ndpH3HNB$(x60fq6YuDv(Ry}m*Ito4>ZcE= z;d@Eb;x)_gum!w;yh#6USiHC$FHd)!#Z%Yi1$>;V8A=UCy}a62FFPujyeZlij4T;N zc=ED5Y}_q=DIWVk9c<{tt1B0;!Hbt+!Tf(a1|S&B5w!-97-ECD4>>1CE~eI%6TjOo;>nqy#1~m|*cAEhbQkT8qzg0JN%uMYc9%nJ*CqJahb?b2Jlyiyc5A!W zPDjE?K6c_G^6YYmE$cq)a{LXR?s7;ti7#o$VW<07{C20ib$6s3i3}(4hC`Uh_TeMP z^Z5Kx{nB4{eq>M1EpPkoNI9^b;M7Yl<=OG%84K>ic9!XIPJ3Jex8z4;$zhj6o-gK3 z_oLmBa`a(1iFcWn=al0rxUpn#4qIMBl)QtxbvS8{bbKV7$UB$v>~e_h?mleitvZ}j z4hbjmMV1_Py7FIhcRBpeM9R^R;UwNGTAovm`{2g1$~o-(Jj-ylTlPHNhwc1Ihja4x zINXwsT{m|AWbNzDU*MTY{-l4}^&)Ft1aJm*PUML!IqW>hvmxB+7C#dyM-IbDyx%ijTkoabZ5blZ&W}7( z!YywK^!^}mF~1>BIPJxIEgm^1Fp!n z%OQK*whVYXDuKeVmOKSccyE%$3e)mWr#dGKl0o>cfDK=d3HI9UGhGrJUiaE zkmo*Zr#w>uznyYOIFTo^z|2~V=Ti-ywkNjN3Z?^dA1CZXXmFVO5Rq; zv&(V3OWtXeXUB5{h%g)wua5I|IHw#EPUML!IqW=~9hL4jS2-p!oWy&b>Duk#hdf(` z$g}hF`zU#jyUKyfy(*5#`xE8a@e=JHA`FLJj_-6hryLSa;)^Uf>^vNbN_V%b9FrMN z;#Fe5Ok~^T$bdXs2E3he9EWi3_TB3$$0-OWaYWuJlxJr@VE@25IqY(*(BYhNNH`T= z2XpeUEGpgou5y$jtevi0D{_}32zeQlC9t!xF-qR&u5y&S^hQb zQb^Y+#}tHNB>~OC~rF#(R%3LYq)l`O)cmvT8?s80nyuEfNaNhp;LzF!Kvxc!7 z=S5y6K9a7;%b+|vUI6jjhomLPL>(B1;at9ODqqtp|IMZYs`8x>XD(@y=wr zfI8%vCzI^N;A7`!Zj`+Jkk^ItB2R2?yBsSi&yKgi7K|`**rKn{;hb_vILVL5lEW^? zW$<^GWA1a2a$t+qNq3Ky=kyPG=1C{UPW!Os-4P|P8S=IxQ&NsPeC%@kk@Du^pvB%G8(WXWNt`(aeNffpj>n9Xn!Zxj|8A{)Wg@e$!lF# zB)*hmErP{I|bJS0syq&Sd_e9RpNeouf))YEpJa$xY!z`i)$G6VTXG@D&2$sz;!;z zlX5iTW2gIml)Oa^xSz@v2HNuWN68C(r?2CQye5~te?-aiFUB}zSGr5yS5fk|L*5=F zCi0fKP`g)_tYr)4ZZwloVGyZ|I4dac`bO0hx zK60&IXoq|9KEnvXZ69{HAyN7B;NqiPkFyU+SB`vybL)Y>$57XIB!8>$vGX?$;V_(t zw>lO*i2rTa4p7pSL+DDzxDnyn5^yg8{81z&FBOzDUBi=+h>N0fKZbqS@??$c4p;a+ z!XYpAVTY4lsP;y9@HIe;w(VUUu=1F~RpTpZjW2YUvvP?jtox+PprFOcnUbRZq)Du@cb!T52acu!@chmPs}O2Y8TWJwW?}Xm3w=a(b3*$ zzj<&Jp6iTF{f<$h1*05oFj^b&JlkNy>R?lQduw~Jv$>%&C_#d<%Nm?KIan=k%7uCU&^O)K=$kI3w6-to@%*UUQ#7FfALqCvrfcLEhf9tNeei|9 z8MQhj_|WrYO#`l?B>1bbnXnE-LT)%2xv(UHq^gJUs zsM;@PJL-DVk9PQNk?`|f;phLC@TyK^n>&cdJ2$Qf;x&WqcxUq35kb727_ZI@;$m4) z-cL2Nq&i$zT{&~6yic)SUc4o5O$&Cmwgy)=v@gRu2aSB^D)}zxM?CHAh^AscRfy?lHJwBJnE?z+9p!WQ0#i`mzb5Z-abE|J7r7idf&#Z?zl~_2P~DI)f}_F@3y|`cQzyq zR`DmR?+|MCo?S^BPASaYpPe`O?wB8qnNmyepJ0xC0pEe{PqN~> z({~ypPWkto2Pa7lU$h_o@f$bp%)8fnW6H~canibV(ldTLVS3HCL)*t!T0vvuc-7}V zJP_ZVT@b%z;Xu!i-izzY=C!=n?ElK+o81!_@%n-lJ7@P~XX}jr~3T zpo9?LJw2($W{h9Y9qvj<=uX_2)9u@`r8M{5tZr*#Vz)8;=6$*FF~@Ex-TZzG+&Ap~ zpr?3i?2Ye!R&&ruc(tc^`={)Q&M4u`Cuca?JaYZ+hc6yz4j;Jxu~VPGXpz$G-(}># z1|8@Z$|xV*l0E*e(uDFK_GRaqKYH^vv~*|1A{VdhdOgd?x37E6_dAT>?*Zn=g+{}Bf?#UZ1Qtk1lb?-bU zrj+ICo=N7k5JIF%9agN*yhlPWbH<7BmX`5q0 z?;>}S(?GWmzXL(5JiUA%;wHUo6u!4Nu<@M(H=!mrs_$(FP7l4>GjaP12P7xP!A)IH zmQFc*eV3$f4VLu1n~L%S_e@sfok%lJ4s@rNCvQnF4{SWR@5xg0eRD$KcTyvn_bhbk z#5j0y*FvXOUVM1u`oj+!!%yEkQjJg3y6^A#sCYo))jb~D`Hh$l? z_>QbkvhCg2P#4OqwH@zV*4x>xVM*nmZ z9|Ipb|I-1lYi^g`D)YNsgR%G3#m~6J(-k8lSPbIqij+z0Iy02I!zEtz@KJuPv1VW?@*piusz z{PW5VnpXZANv$yC-Cq23#3qq!_R2Hd+wb;t_3TIvc|(Pd*i*qHCd_Ia~d*VLkeI|I|V=LJ;RGg0CW3Z?Eea{ZyUr}uu5nvPei9h&5OV3$z*CaFa4QHV3+hMb7ZR?d*><*cUB=qiwY2Qlr zpzASG9%J|6F2kKSV?`uya^Ap;ZQSQ~FOQt>*&({-g?<@>B?V6?ac6O;=jq&#wll=< zGU(sqyLrRIAdRJzF86hq6vjdmyly>TK zo#ZDsl+L_lu1{AbjfFki5B6*(?AgSziLhsrV9%ZuO5g0&_Acz%^1UB?kvKeVgE8!s zy*`w4(g!h{^g1(cOX|+d&G&v~CWI?0-WxGJ`R?Qm-c19V<2G!X8n;EP+4cPkPn}XO z)~#5xUD}#0&HEwYpRdIRXw7b=HQTjQx96grkBj9?yVrmCJy^8*%%+DDw|Kkzm1k_| zwI>`89OK&n3w6{f|6ci^kso)+j7!;=+Fe(k3Y%$qh4=l` zO|jj(v-&G7^4wB;zzFtGOLZ%6e=wl>=_zXbHw%;Y>2~u`&&L#bLZ1D_MWgl~R}|da z_Vl=-|1gBClzk!Vpyf437VOK4O@7l}$t`LODjk#%TO0GSqL-C)(~7MtMtnrApmZ}N zYkWP@*^GfS9lxX58#0EEdarTCrc!I4NE;CQ{+mM)N7_}~Sh3Hv<&SN?xAeYUV;3F2 zsH6E}{OVZLw&<<{t9Dw=czF7II*vEg0hf<1ShzuN=wp0;gKIv`lko z^1jxCQ%WR7p_UU2$!b{dO~edM*k^JaLWnYR{if0{_ASAx7CR0@zrZ=hRc9=9Mtour zM@zF~y}r-LHS@He?6R04*=I4=`(&rZ87D-t#Fx4gKCbe<9qZ*7jM~U|u;H*7gHbz( zv%SX4XBLYO+Z|&ycNo;GlVmGF-svK9p?-7B>ZY~IW&7ei?J!_)zf_A3xVojS4R;{6 ztwEJatgwg(H#Rplu261!6girBh4Lx#*^Q04_1JLs8m4T~;TbWwVtd@Y{@7u|r9!#t zY9IOj*t@ZFmG6no$A(?L>Hjnd(W-GF&O0=7DnjL(z7Kqpj|Fe`=?8_2k!DxKV2wWvz9&hI$xK@c*P5)bzSL~gIIOF%;HvxYN z@Ob4_+^1q6((rn4_qs15O*Rm{@qO_-kS-TKGGD;gsq*E0APC=J`h58<*OYw)8L}Pe zt&hd;5$Rp>`=TNEU7WEIzvpRG5;6C@b(Q>Q0^_Riew;Ypw zFb5&6-H;tOHg!NcYTU}ngkxORcR1s>9B6-uXzzzaZ_1{9Y>lXY^4Gvw0AHFVes7mN1Kh*CN-MUHIz13bk7hpCc~{u}(!B z#|K$k=OI>nUSeLZ)Yh+{d-3_o;kRCfjQGKc6L3b?R{Zg-t)0i=%=onFss{-p!M;_)6Nd(TAe`fz(Dve_uZFj$(DFtc_QWiK;s!PELCi1(;_24b`1^iYj!Kbte)_EKhm? zXJ%T>xRQ`qr5vXj-shnr{*~ET2r)t)&FDQn3m&Vphl|Ij7!|!IqhAKOm({Nv^+V40=iO{KY;b-Gu=sc|l^UQX_c~S#mhz zYB)SrDZY~zC*B75t^1*h$xSM?MC&*V^~p<_wA`SOyiCnrF{S$4OpcjVs)ncEihXZGPzY1GKlFw#=}j6S0k$< zZb!HEKH`VR)}Z`#b;R9+;4uILu76v>dU*6d0bk?da>}41Ryz7hT(Hkq7~Tx)*U+xG z+_ZM+mB;#Ds6|{}-?sx&u=hs8QIINs4GmgHf^ZC01w;Qh0gfTcF~Vv@kB=LwMyle3 zsi@z$VagG+-b~1ZhQ|%p&JAWlC-g0DgmzwMCiG;(IZ`=2H<$@`h@c{U7Vl^BT7!{` z&j!>W%l#*!cNC-yycfR{v7$9nauUx)UJdI23Xu}zSYL>OrR1i{!+re)>F5V3d2D#= zbm(J>E=<5W6*`kLNaY_DIRzTx|2+5yNhcR2uSywu3aT;@FO@S=h9%2fV^}AnBq_sL zNOKan{$+(3B$Om}n)SSyM(O%d^HOCHxkpODR^_iJ20Ua388L zWwg#+X-q;RR5oRdc9z8$#Ys~36V1ZYkdaKuO@FzoGLSmpKK!;0p%bTO5BM8Y#IQWj zjnw1%`{C!YZbfyZ4$LZ0qsTvyaB5CLrF41gCM1{|RE|_@R303;1)VsPVHBT=UhJn|qd|ScI;hHZN0N zUx8@~Es{2$awRWmr>nfAT8Sg!SfF}BhP4TKNn2QOGjbU)(*5Z|yvpfsnMdgdePaBK+g%W$8n#yCrC9`Y^E%64#A3 z(zPleEPiWE@FcDqW29?E@F$*y-&zk64R0x`JAIV(h9oKyyiMo`8AGv&fZso$sWT>} zj)%YRBzy&BR`m>&FZpHo=HMH);fA4zJrlpvt-gz|0k+!&cd4}iakSmlw<}quKy#IJA@ej?XQrwCDQxCIe|_d6bf8$XL%NZ9 z8NTDp&G?QtSID4cj(~ZUX5J?`F_$8IhPer?+}GTN;-#2{qJie!qAcbZgikOl@SSMR z#dngq15FwvW@7uf<km3+oV53LZfJ?zc$0W*T03SV+GHYbDa~?L$o8$M`kZ zdv1T!Lv`9e#QR%(C5a`ex?vK2c%+66@A)Wp+RW4pD5tMKzJk&C4l-8Tfy)RMoswSf3e;dFvh3N&ghb$m*Oi) z3MZY{BR{k}-wP6_3Z2j^|3l5}pL9Pwv|0oPCclZ$W;!~QVg3Q9O>;haT8#N}4%E%? zmZ2g7`PPF7yBKU+}wYk%J>-Qbzn>2fXa9+)F;qAAQ7?s)+dsSn=(hjk!Z7dg>Mlb&G_Orid2qm4|o-7O8xC??iw=)4*3G#y)(hEJ-uD^F3Vx ztr&7h0{u$@N%xWFbBR`CfzHK=qEzjfK?Lv(!dKEbe91=zH+(YZ`ff#C=5to zGzX&-V64VCV49cWJI1^T-yU-ZzWrt%g2b6?k@a{p9F*}k4Rh!b!#fYLlE+&o<9tksRtLm20F2l1~sD)A~Ke=j4;T^4qYwv*DPe?KA5q#7~~A z96qZR`j~vOa`>%@NHzJCr1uad-a1(vQ4{l6ebEuEDQKZAy)H4VfiQrwax>(F$Eq!cBTqT}hEK$J zZ$+(U4k$>SfZx7J_zF&ysPcs^6sZdt&<6}vbBNZA?4ik*;Iw%J zF%5Gk#vRjCPo_3+9D=Cki=)*L`wk}R>@n6{1ZBMAlOL0KbB0R15{Na;I@EoP`4r+| zfS22Avrn|vJ28&SN&ZG+T!-c`%&X8ErdcpTVkAK0g65?I4E#UDJE;geT!XD=5!AbX z6mCHtkm^I;eDeC3pxTE~U%C&AL9O$XQ=J?_2=k8^h7B`S-SNx4no2X@LxI!H z4VXeR%vmU7U$YHK^)o{#R=~U*qg8)X9*LY~Zo$+szW z%oS+#$!05R;AHb%lyr)D7~du46r@sWo&}XDH_P!|VYZ>(LS_%@WSUuud{&x!Q5&b4 zGf-$Gr@ zH~T|xsDe*4%>OENm`^oJHmw)OLeejQlS)kAsdjn&04iiCKb{ zT5A4d5N;whuR`9MP5I+Zi}`O14a?0$wCM_S9dfwRycVTiWe&k?w%U{j^|qRSz;~M& zi&(!hbMf77{t@-uVg3fX*lGR`zRxqihmxLe%7cq8Fq2T9U8aQ`UT99hIB=19D)N7^ zc?-TTF>gi7UTU5P|I5t3p+vtnt5Dv{%_+#|Z_N4mhH-^?FmM<1K} zOtqFWDlSIfTx)8Bt70f>V4bN(Y`;-_71|-^EYp%#?PN+!Uk*x~=0O!0!Mxy{ z>f10|kzdn%3FU|}w;>0X`5kJ-W3E8nz2-#-<1^*Km9b_LTElN{j*}kqIoc=Q{1Y@K z!OTajMDzXsN8Ovi*Hu-0!)KoAmSlOVc53(l%|Hq!~H@a!Hf4 z4W>!V&;e+r+lbZAjMyW_eAVs5Bpx+90 z&pDt@odev$>c3DwqDC+#RSKj)x4t`zy0r+yR$ zR0evVuUgSdovK0p0(A_uN7XMeN-MU2UqQ@0#FR(gSy%{xEs;9yE22}{ESE(-mx7F&W;O!dq6ozlDnt|RM z)qcqJy4q}LiE&xpK2)U;7|wG*Gkm~$4)_<8gby*)WAWQo!-w-2TQF+60WW-so~Li9 z`2g?>zg4FYF#8KYgpXLCL@RBOBUL$TK(e}){iusqaOD3Dqi3qyFg})gzJ?=Ti;;2E zedxwjxr;dRb3jc=E zi9E}J#za~RXlx6u9qe&y0S-T53Gfr(5@{=_0>Nb#-=v7N7pz4hY}o{`Er-9fQ)8V# z*OAVGw;@q$y&tL-=@QU&68wwwh?>@GmuMJ(ZQcy`W1z$(39^JFVp1Rh1e<&_+(Rto zP!UsIs;6WAw2%}$l2V`-2y};R78ouc-B0_KNmT-hUMM70e!{Ouf|Ke=6%LW%+9;8J z$%dpVy0nJrn^nbv~?yqpriix$1pT{WLWS=?ST~K;P1p4cW_3PtK>D@&|Y!r&mEh zGgn#fVP_2RyZw;Ng0jrv-ZGRkf|xlX!AZlq6Fp>(=JKS!oi&Ir^v-;XUdtk}$jBVi zYgy|w)nHsU1@f#r2!0}qYluRu>D23!OUrDUYgZ@$Cz`tHU?I zbXdQFu2n}$h>T%v0+b+ktwVb?)?UbPwGQpoT6C1E=ZK?J zXZ-<|sk&AYG3!YTV)a}}EV7;vW{WjhheUl5UDeGN1Jl(D3+eA}$$S*|>P1C#0j-P7%r}vu#YOa0 ztUfc7KPp>&jo~ z-)hP=-?By*8a0(A3=)=QjV>~3!tz`rys3$Jym@L7)VE4FP;a$>rW(BgvBYv<(Q0Zm zZ-nTYSweJ!pkFgv&^Mn|nFm*);v9|d^D46igHltglQ@;J7gI;gT%CLY(eXbL>^$o( zkTab)yWH7xx#6Ry{{oofoK7ikvA7~K>Urox54~j{taMXki)%E#cwHAY8x;!RS1J-s{%|HA=Lx5%TvV| zmay6f1lOu&jPGT&-^LIas+K=qgKt6G423YP+GnAQhF$v>{t4Bd%Q+~o_I@H2t}R3} zV{PrHA#0e#9-*s2BKFnt0YrS0Ac*@nSdp046E*^bc}*BEfH3k#9xb(ux3F1ZbZGwa98t^$Kx zE^SvIzRFEkwf+;rAm)~C@$ST>lsL2r{`hRdJm3UhDSmQ4QgqT$X# zTEdncERaaJ%m+*Q0LgrMMlZ762Hd7!fZLKj@Y?*X&ZQx7_`Ak)mgRBc(0r{e%lQOq zsy|YK)lM)`ss9b(!Wcv$PPJj{?I!$xgQ(c|dZ&e}bS zf?1+|A?qE`l-k*nNVnEQqiVI5; zx*IUF^(In@b-^4Y7E84kSc$}PnPKV- zhZttBu=0U*LE+q)S!ibQ_rd0tNqVc}nLPybUARE=$^;3+DuLF`D=&Tw9okkclyY80@xOz|A?wRv?!3x^FCl^1 z_Cr8+Uf3!DfP%95oqWHemIY{LKc6JZ+=7) zS=J0p6!W#Q&a+m5)ARL^7h3z!`Fw4xOAPndK**U5VDo2Ly#V9zXE*1+bHUSiUic7h zFX385t7Jii>dIpnPU}qoQ5VTQh-QZMGpKuAl}zBa^%zWcU9}`a)=NOBu0}QoLD`O_ zNX@bcuOPHw=9>U0t8cflpls%A90r;D7nIA$U{h)un75$9T8Ub1_krXkX0$!;DVSkv zF0!H>-uV0me2;GP#^*1vW6>@d65IMZU`D$O_rs3lS?ghWqdk%+w5|n((H&B)#QLI* z#7+TFW94BCqI!3w*4l%)HLADf;1|F`MfKKPy|o2WAAOSmSYlnqelC>F<+axPL0t4A zDQU9q!4O1yr!j8XVO7C0M|X>#)NQ>A?9YfweiOub{qJlOqHs;C)q5Pg@Rdxt7| znM``GjQVF)(bEk`osiVsswf8Rq92mfX;pL^gf9A#A`0NWs_4!+NSzeS9#=)*;_zIT z&o#m`s_4DM^Gnld?Mlp|_fabDE6+uP8nfsZSfoUMATVpqq9ug#nBY=p7V)%H^f@W3 zHw~8(+V*j@wy~BAvAy+gV5q7s`Z%7AB1W3k+@jajR^I7lmt4i@!aX1D!DlFb=$a)XxQIR}?&ayr+4GCYB_dr0D z_PYu#x}hpiWgdKRs&G@YtU7eCkiWF{pSVPQ*BIx&DU7n#Vtx@i;sLvXe!>0jPf)>@ z+snwcc{5yY8&})~lNGzdeU%j?wkc&5w*rIMAvXtxDmnW!lp;3d^5k1mcK)R>9i?y2 zASEkV#2YsBKvMo?z@zli5GS(p{UW^+v-A+muC>lO7yzTAY>z>gjr>1A(&{gkX8Z{@ zy@=!T!B~146)LY#H!+(x!(|XBpTC4v+9WN$!Xn-bm(x?l6)@=w&vhSTw#?c2MS!tz zc@`6YU~XbM&##0g*Eb8Cw7DpfPAk@sjHp||904x^vGh8KL*-Sfp4oy+#c$vv)%UvV zm_wqCifce-X{);{Xe!yuUWtH}+my@Au2Gf=W=roy?btDOoH@K<0SGAhABERq&k?Nt zokfJ97psC_em=CptdkL-b=Dq-Y%>G{Zc72zABM}!WgU?7%5SMWM%ez!Msk}l@uXnx z4fkg#a2bED;LkS|p6@O|c49~0z73UhPjqlDFe>=#R(8GH!fJxy*H}Yi_&mI;s^ilL zZjj|dp)4ZVqfyZb16Q-oy^Lk_{%k%O?tTnM#q(iE@dNJ1Std80Z?NT%gUj_y#RlM4 zv&7|&yUm;7aw$=<41HD~ta_5!0#lxT!K93z%b(G8Zvuq;0Z2s7M>2kmwxRhb7v8aw zu9^Q0OfF^dbTV!M%f+RW@_@@m{sI88yFw&*y zB$sk1n^+Z}fGAh*sJepL#MoH&LySb#5|u&U@J40_+%xifFw+$r67YAkNOsfnTY0V#YvbTj!8(Z$r6sGSFW~V`<}Cxq8g$-I zk^TYmc;;)B&a=VEzccU0z-hJ4t3h5ES6W&nSY*ixe4uQz23Xq9 z;H7M^WU{MA>%=oh(w+k!S}d7?&qw(d);S-xVzV`k)0cJPmZLLE zFb8k7W>6!o6PF)LbKpL8SmGqzg!T^in#ykq= zm#rC`p&mo}QC#N?8sF2k_#-1f!&Qk&#)n{vW{yDRN33Gn2kXQOM`rGWJdIjKFH8FO zN77coL3xWcjVR|rY}0X7ZbspSAUe%L;{#SXD=$F7d|WdJAVSBi3JvgqqiKxrUZ&IM zqMScplJ=J>!+4v{YeSklGNBF(5sl7I!6V4Bed4o6TvKhcPki`@YpmXf(pPkec?jj( ztP>9$HCFS>)boJ}8e~iw2aKu{Hym-RP^{{W&<9YsvkOrJUBQH4hj7Z#Sc$w9NqIMV zd0V}_NyHra&4_FZz$Vg0`b1ly-5;3xDbZsb`$M)C}vg?@$75nwx8mr}lg05aDBqjfsdJdB1OlS9-p?(|%E zX4$MPlyRoWsKdj5Zr7aQNOZvp5i9G&?~mZGO)2Wwv>JQ?iOV;Ds&}Ky^I#X!ZktWV zzl=uclVHZjaHS2xOnp+z+Y?B0b8&e;8ex7iD%t3rFk!b?;;#M?g)iX>4Wk0-R;b|9 zZG;XXm!uWxT##nWx)gat8}F&3qzx(mPE_V^MAh^=P!fW>=;AVF-HJM#H)q|82Trg? zfa_)aO(#LUaz}Md!KeS5dOmnc(W?^3cxyF-U#KtdAOUuf}l11mefHZf# z(%R9{FLmBb7#!}xr)9v)dtOt`nT204w&7xY-=Swno;{Mrz;V7^&cJamO8GNCmA?n1 zk1RoR8ikjvQW}X%Q80l^jKa%0??$ArW8NvS>=kRq%cyq`(x1Uq8G-=vK;$_CLqo>v zRylpUCs6P>t_((izBJF1ikrlO&_+{@D4&ql5aem?wU8qGNYy5Q5&3!4tNH8^W9^N) z>^vzGLvlNExCc3^v+NU(!z5*d(ceGpO4l_7#n#b>b=53h3%dBHPK|mI&SDRmlYe5MrHpmga;- z8DB;b-B+Q{=LBq~vHX6NUqb$0u#2lLH7%+zitP~|1B$`yVU-7ShT z_!W0&?KXpQd9y}HjJFY?nDbQ<)3_DrJYv;626!UoSwJQOml3%Yl5(@C!d*!I*s6KY zGSvAda;Kxb2-lj^NK~=3@G(5m{^W4sUW>BXxaKeI!LO?c2;TEh@o{td7{PR-WHG8N z#Ff4gi8Xjwg{!a^31XRXH=1yj05)n{sp`q$&`uzDE6RQ%uGcnXh>X2(gh=l|_dk{% zzk}pYtg5Z&po0U*=kpupoD zQe^zXoUw#3%Yf%QQ048o(sPkGfrt0wDxB+6@DiGwje=dE;2D$!6zoc(z(M!?c2H$J zjoyB0&E?Nwrq>|%B!KgfNBVRm_+wh1!d1muIs7TWuOjsoT!pKU5K3C`@FV2>0N4E6 zFsGIXT;55^AI!+#Ny)<~`7Nsa23Pu5koYqmUd2`TBP3)js?g+Ylg+2DY=sZynuNxVK$(I5v*0X(ql+$!9xqK!WJZig5_v5aw^5rN4?Qe0AU=QjqUcz}3XrD7X+H=J%jh8y-x#6Y5H< z^a)H)=@Tf~4?u4w(0+p0-#{-MN7E zEJ`j1oZ|%i1QOTafxpp~aU*Im3?O!qZWe4g7zJMoyG|(MVsaxu1e(o7jv`;ClCix`Kv9#~}paxh=UH^DW3cgc7crzn)w| zr}ZinuzUG=(V%Yrdt-~1ST6r&{m>=*LD?hfD zb!M&=<;w4KV9}>>UBqovRA0&JYMU(b^7SI`M=1V2E?I~b=tbA-NWY59Xk1c^606Yq z2mt4Dqg$m}iChkLyk1V z8scxv<^;swnA-&+-w*n&DVxCp@x^3_zw;q(2BPYxW<5rYuDTAXUuF>zL+p?GpEz>RWwSu60g3^jL``+c7K~D^%gUq zDb@JxdQ3EEW?~(YdkzUbY1Xl6aZ4dwLsP=%Qw6QOZ8<7lX3FVh^)56mpApI2(sD^Oa(}e=+?jB# zHA_oI_CN+tm=ZQH8n2m+1tO6DA~6`i5k0epVW<*DdDKBuHeHGta5-ekp%ds57~g;v zb!*TIU#wOQ<~a-+v3Y~JmCcKHLdVvdMGQ4*P)!~vMv9tEiOcjAQ=PY&5;`be37&R( z&$FNyU1l*O>zJW>0DC?J8r|YjCx45M7qjE}W&``J#TuaomspJXW(UWABhvgaOED2q z-QRws_cD*Mm6$29l@mz67Z=~l5mWX_0H=|iL>@S2teXoLA;{wl1_L?^Lx2O5sImkP zj9x$CRhbCk6=tuHU{Kjul?x=xg#ge60(#bZ1eBYrNWdq7z{hb30p;d45^z7#U&bW_ zgf#&aLjLk*Mh?I*iY`4g$h2Am|FLH=H;E*0hziCNik%&6@&KPwiwXF70QeQI#bo{| zwf1Gyd>!e(;F8Whtz>kHA%)X$NmT4}N}^)(k)9)YXmpnn`?dk;walYjeqQHYjP!2i zF)DVq&U-)7?_nOJVqegC{Q14>am{1|?6i^yn04Z_$7F=QqGW{bMfqK5u))jDzN zn1rN$sU#$I9~yoMSLNks_=k0X%#hUcN>+@Iq2N(m5|VmJ$!gO&amO)PeZH*Izd-rV zaLMZP6`l7g(l6r*O#@Jd8HNEEa$%pi>=;8*l)%+dl)cl>ze@56+gQCC1vlw}j6=qW zlgHdD#HG-Tv-?gIGOTpBt{@?)i;%~V)Wb=640kc_DKGC3B=oq~mJ*6IUOdK)=w*Y; zQ_u^27G<3Bt8|%l;-+Ip=ze5!qG-^WP)LuO(8DO=Qz8 z7uK0N@^k8#j{MwmEQtIV5juky3^;>(fcagj^aTJHM=%|hAq|%}f<<^Jz*WUso;P^< zSOzpH@CG%Wj8wtRy#NIv&h_+?%%%kCMrbXIKy;bT_2{F!)rOL9;VC7Ue@)Bd;KBMfrrzD@NWlToR_aN$1rfJsa2BkD^oSt%iFm06{vf6Rn~< zCpwI^x3K6$llvtpqGDux23dMNgPNP9<|W7qZO4rw`#TLq$9`odxdq5-Rf6Mz zIVNKiB^*2Ep1|Q&{iV{VpVUzfoUYI?(7@H7Jq5r>u2IeVte5AXr50 z@+pN9Ynx^a+y%Ew?NlyGWf`eXzO%(6bEm2$nO{Y(cM=>@&bl&+$@4ywgu19|twlaPW>W5W%9$Kg0gWUZn=IfT}wF z4+n8ou~y;Nkz<~i$haK6`D;dmq5UNuIAw%x#*J=44d9VC6QKKc0TMs3N&u0) z*^|W0Y9T>P&&9lfOF(SZAeJCqkIR^yyBH!j6^jlZ#Clan5d4Yrtv-ki8pJTt7Ym4^ zOEFWb!pbn<;iIwmpbw%!tssc^pz1q)5NkAuTadmSW~>j}Ux0 zFhP6`Rqw;KjWHR1OuVXsO#qc8@tCJj^dv5c$GnJ#=W$iBh6H7(1w_po=EMN`%3y{r zB+%J0G{eg>oN@TkkSHlF) z&P1`Jvbiwi2Tlv8PcIeK9JXhpQCtp*m{a%cyiGlK+8Ay35kt{RruAGj9p( zTDHpN8J7HfqzVg7OkJKfu3L~^!@RrF(MZWlpnPGRZ=;4N^|X0Q zfEQ)<0H^`-IP8qu>~73$hRTtnF?iBqyB}2-GYVm-IuiE@z_}imF?Vwmad|u#w3X`Q z_fc^H*LSaoV0{5~K8I@#9b@&%3ex%*(vRSpN7lY7>w%Y%{2i_+fp9_rT8RNfFViqb zJclx)7?(P^VyoB7b8{#-(;!b-xaKgBp`Kg0Ee!LEbUiNVE-9r%h!>-7gv;gq{Wy@%lntW z8)q+Mw>s&xd9*w_pS?VfrqAG-!*6L(kFKZIEMa6sz()$ULgTRAdDIlRm91%79mL<2Kq!Yf1 zF&AImtiRh5LI6^}fKKK}tm-TCC?y{Nw0E-?iHdz?72T?@ApJR9Vs^RAT?q_?PsZF| zV$Qr7DdPrQ>STI{5ANn_g8MU?{Vo7^^D=^4iLqRWYu` zCe9D{Gv~JpY2rK0Mn^nNw#LhYDuk%C+<(4O=cVpJo1r_VY(bZyI-UMtTRP;0`$C&h z!jp0*1<*F?S!j<3{Fi43{@H&T_@w~E{qxs7;B%4V6@{QuL`0ap(d~JNk0!^9LSiE z_h+4#WF}^HqKJmg==uUwbUZM_`;djuj!)^h#C^MgYb!3H>Jp*q7?KB>MHzmpP<1Pk zH{udu`Wqm4!juD$pTgK4LKcafY%oHQ84;ZOblz0Kx%8hN+eHAxBa}bzfHUy333+F+ zCK662UNXi-#&lBIbsXdm$x%tP!Z#C<{Da`m0!EdG#Lhefq8`AtQG#*95{r8g>1T0; zpjZZvUhY8~Q0IxZwgBF_s*F6;c>r}tJqFU4`;B~r!0=$OM4kK)+VVSvWOR+WFQBT- zzpYX_y9;dQsojetg2_Ozg-h7H3}qgh*`E6Olt#qLu+xkTpU>!dDvx{LkjES_sHv}< zS~=L0Fm9SLofvKU&LY$rE~LxL=tK+Gede%^%;F(__b9O({7vVC>@0kh8C(KHDkxVwDI3UPr6*q)$ z?jdnLPhFNAFsuVQx@?p;p|!Q#tfb|(xD{6>?UpCETb^iluHWtp@YStFW+jg!Sd2{Q zc8ikRElRXo;Ueo!OGWv(DV<fkZ8Crh1#`j z)FOjd+s-!K2aI{bkWGUY8Wc+dZszF*#cL7`irc&fCDLH;Hwxi}wG>+ao3;DLCy?`(sOFR5a};`|*M8JrH^;Ph4|e#Xj9!OwZP)X6P7&}|{I<^bkQT>eSc$~9@$fY!dXV@H9)8Wl zZX^`Q{2LNEBS=g~q5xOUTalQLhdHfD_kpzBcOBrfUVGkD-DxB~S{c=#f&7@@`pas^e8K(L$df%=wNl70%g52E7Naiw36 z#G`n41Xtk~kl+%j0=3Uv37etw35Awh@4U;x2F@Oi&{l^ySBK80e{lpA8W?BcM>Az| z7rN?3*3Z$+PuXuT5`V_SA8_RiBN3i~sU270B}kAdSK#jgWX#1ipWsM?zLP1~d28S0 z0pe@pt8hsdU3l1rOQ2qehYN7U2sK8KD`;N`D#4U5nR)5YAa@WI_u@+bArg~#7{^uk z2PFOxQz(%CkSXW+Ou3kQT>S7*7F^c{kvxtrjqRdtZk!64HEHDONSOqnsHUJRt{l&7Ad|@pF>!`zyp2(#>gSenwcOC*PER+ zSbwAbf1QUC7m2;d?ZK5Z4T(GP@F^xLka!*sKgJbW226Mad>h(`V}ra7SM0!DU^1_k(9P~`Dw`3I8n?m}MAS~%!I9z|*rpr7|@-y4(|8Gk|^&#e2NMT9$; zL&!9Z{{%Ig%=8WCgDux0cNWY|1XmRcaz2inCZty5%DEkhH{oFyuFx1-^9cJKH1w&u z1bI9)zcP`x@(Sb?V&*{;$`Myb=Ov2eNCd$QC-PRl5B0>|HYEJO!|&)JaG4}>YN%RF zE@hc0YB9``qfiVh8#(7@uFPDK*;23^CAMR)2&Go7VjGKmk7a(ur_r@DKc(=&Z%MD22RNb4$A#48{*MrP*fObZ%alT0I6 zk0GA52?6nA05aR_OCwGk^3^nVZOJ9l#T<|GA{yR6*9!Z=skw=!nJXghoEgb2=lPT; zH=Q3~%&JK^BYt4zG{7b;@VS`WEJ_(Vu4WM57zYmigD0Eba4b|xi_M}4Mk@vaamx2h z8C@bsd6K?n20L6D@Y)d?G_#i_<;uY5>~lm2ri}6OOhsxqA}h{DAC?mAwxwXn3<|(X za^54RA&L=9=GrO|2k9V^oyySFWCAiQo@Z~oWrBp)jlL6e38drQ2|2j zjRpWI1lT%B&Y*F@Ru|p%el4-^WK+dF8Ty{oF-oNc8&p%O>6}@V? zfRlSVOYM@zUS<}~Z)cs(!gl--EJs`}9kCy_9z(@bQjwrWrJ4;;_G#33_=tVK z^)PBYOpJo^J1p?xe(T5hqcJ!t&2C4F?;Wu}Yke6lzUOr=6;Mnff{%L{9&N*PK4^D+ z(6-G`+6V0ue?5Z7P-X}@`Z@EIm4Wl@NZ!Jt&sbO5$>}TYC+svSN8uCr=b)uLK4}XO zY4xQ28e07+fbyFCq7$@w(YY)$NL-eAJktYlJo9vr?;}n2T&>Y2r~(yoMKSJGzTH6**OlZno5)n#|zWlGjv=Kb)T?fcDZ01j0? zYTX2IH)zglHoCV6ppd!ndOP$dQ=MnO+q%QXpF8YFYyy15e$Y|piD3BrcJGijzc*Qa z+&U@sPTDuv1agD@5Z=kT_Xz&HAO$bjSE18;vE)N5{dofb58>;XQktpr4J_jmgd1MN zJa(LSgQ<4dH<&kLxoh8S-UE_PAGPl>f6wgW)-5*vJY?VNs2x;6@=T*Gjh{CEiuw;6 zv9Gm=-2=Y3qE-d)gdhQ^nPZ)}`-ojT56|iSSaTvl;YbRrLsFDRYhys z{Jf)*mxbn84FHOiuFIFgY$F7jK8i8Sh05oa>cplCS@+BqP zutSqZYsDd>>U!JG0KFLvuwAz*9gE<(lJJcJ2Y|#1lvC znMtrd&Wa^}K+R`$O@5zCyY8#I$wcY+Jj+(0NesjY;Dec9C*I9Uj$XaQ3%VY$nHJzW`}*1c{O-VUhuV#9FG_BtRc!96kbR2jBHEEnKP-4mYmvi zkPQ*$M3G^(UN1%f-Rp_N)dm6z+F_?>Xe%Lz`0j*=L>RIj?mp8u@w|&SsH5SaD^Lpz zR-=p6O-VcW_4bBM$lKIG8u;cBKb>1i;JH>!Gv9g0rv+$+og(2SsgCQCY+mkJ~YKyse2Jd@=$E<)p?C!ljz z9)mX+beO11gW%Q(7B`ABc8hh2e`(=abgmSMCSL_G*BrAyU|lN@dQ1~_1kVCklLA(} z(yxe)`Ei>BP{J@{W_347-lLo|pDc&&|izXglp(W@B z0L6+jMY|VCZEXSDAl}{EL4>{iR+tR?%jU26=LOEr+oc)iOLlRwG|FPltOrdhpZPu0 zIt)AaJ@W~spJq!aBfB!(15(`pi3Y0SO-uVR^T+al0{w9>$6wpH0l8NngMV-fU7%ac z(>nd2`LH~o4%FN5Dqlm#=cA~DKdb?VhadM9+-z8|4!h)T%-A1325LhYK%~~6loug^ z*%LMFPCu_n^74?Ew^r?>ZgO=YI+ZlH{)uWKdvC1gz(_draI$ zxniJIWK4O_Km*x}kj?R;o+_6q+eibRX*s%_Qw7yem+Lj5gK{TJm+wJ&o|G#&R*{En zemsf<13TGnCJoh@g-I<%C^Ful<(Y*^Ezbn|f4@(eD5oW33$-Rr8RQMLL!V-`@g=gH zQIjjO7C#=xgtRnk6!TbGD5;(e!_tAlk*ZWTPnjI4>bOZ&rB3qA11+XKE2*NLC9937 zbpX9Z7Yd|>%O$mZrKDD_V=90Z0KzPqg{1;a!8SW@9W+oQrYpKx_-o?@*ABa|N}yHE z5@@sPBvluaRBTxaY;d4h+Lgd`mCQurnN@hInuVuXb(|LTLHjyq(x{*3#X)HGad|Dt zY&)X@x>gakCNN2aYw=t=&zis&tk0{1Xu<*XK7JEx^j^cxmV`OEI z(Y7^uD8>4S8l1s*k3|l^=t1%QkR%~Id&@usB>GdBJWhqhf${O+i{Y0#fRDpq*W0Lr zAKDY@f;xyI{WowjL33uROkle4d8EnD1TDIbKfh#QVVBz1KLaO%z9Lo0bXC<(?JI)5 zbRC~A)S1%PKY$Z(9~SDL8XB_Bqc-3_-RvxpoVsLW>!Ja&Y~gh^9SBdag)Y?2Pn?3X z=SxeUU1+K8vhK-iDHi*3Ob7Pm>PnfY^{Jlg?JLz)%)Uz9kenT$8T2he00=z+1iwdt z&=WxLvH?NfRT)m12?KC~&}Kl}ycHbSDjtQ8Qd>9jySJZ>1A;{qsv1r8LAsHJ7Tc0+ zgUgL&dg1V}*8(7ZRk*`m-;~VdCLo|GRa|!gIc*ih1J4Gtv*Bsm(I{1Y`AVc$uJ)!J zsmz;RdS#r84$j?(4mR#f>cGcFxwOxoZZAUBMQc!X&D!Lu1cs0D76u|0+Pa`>_}rjh zZ$N$5*-kGx6N+aP;ZWFC2o!_>O`yAZ_@hxSYe?d+2UI%ENrGqRh{G99$`YEq`ZgJ3 z7s7L*t@AQ-T_eID-eN#xp+YtzXx+*;h|gmu|zkV{=t^IHafp1f|yiY)S! zX?7rsLB6c^M0#>LbJ@AG$)A8$LslB_m2?Mr0t+sNJq`0V!)t}e5l1Cx;^m<$6j!hv zYQoQvn&Rhp&mJ=Wze4azGevwzUCPHJ1|ds3eI5pQUaEx`Yc`a`VS5N`pC0?Tx*~ZE zW?#V&VGrVcx<8+{THHN5QzVHgEcm=^Q2KYFWf_d`IZ9ocNQjaQm_25ACqx_sD|Qs!s~%?LkJFz!Bu$HfRdH$3xOw2+2`QHGz>3Yz$@dld z(nJBn>`TB|nNER+{|S2!dc}sr7ham!@)Om63!bc?cU!TyuW@wUUPXRgGD)BxsUNWFHI+cAFkl}@zZ|2sp)09nsKl9m#@w9 z!&74X+@b%-QA$4gc<}jKV4A;4>#(AYulm6L(PN8w!8&^5@`<$yC`zGgM$Ir_UOfHvl+jc`}jn$A{wEoI5yjKDx!=IAH-m!7-IY7P9}FTdcbu=sXPw;Td&dlZ;X4F9sWka{ndINAfj(hL>Pl1o z+@UjzCE*$`Rw1Tk+?ftzp#GARjkUA*JP<~OpM#7I4elN~uy-hSaIk;xz{GfLe6)Ai zh{gto`-Ud_2ZG}LgX4W?$xdz+i$?jsZ)9xXpRdUlgw4NuMusQ&w|}hnU~>NWL_e@J zV*5t+55#(hCS%dQk>Ndqdt>WIfML)0z*ubW(8%uIp{|LMvEID{vGKvZyGJI*qoZRZ z9e&k&&UkeZ7Oj3x)=VClAGX$M!E69vL23FwnbuFd%w=Z{NPb;er1T zdmKMJ{(q%6@GZ8tuWt&S3l~QhM;H3!{_BHvmKOi|sP_+!j}G-7_6PhdFewLT$!1r+ zc$}s94Mfs!!M_x=|EA?xiv51y0Ih$}ZxX5hnjTF>n(2SN`+uZgXQA^S5Hb~#r2C*P zG9W;1WW0Ci{}jmo8Jvm1zBm8RT0$5{CMU-KwZ=(9n{2lJMIirJ(6#-G?VcPQnixEr zarPzi4dmJ{egoF{#e)C%Khij#L&ng7IOmCIAH8=ZCI${o#7D;l5A;q9MEB9_L?+(I ziH}bl9vX=69T-L~{1CRA7#kekizFO|c>lnj-pQef_{8DSfpO%)tw4qT!Qlxc;FIAQ zRq%|tjNN$E5XSM~C;HUT*=OHS@A!BUHkkQPo74di97QjYR0D_h2z_w>z*tf)LfXhB zPtgu9I3q!#lWM>(@qytdX_5+ZrJ#3gtoJb5=A~3aM!r`((2E3IS^yauAy4#k-^kF& zSdbdrk0~wQKi(HK92t*u&O#bzFVR*MFsb)K$>nIHN|6RXgh$ObAv2M}$OVbrgZ+a+ zLJu~Q2*#0gj$}|ca9}{#qDkAsvBQZ`R0{?jIeJLQ`1nxo?g63z?+}%A7G~HW2hD;8 zB3b*m6hPI9p>d8s&MqUtv54>44|z!uw^AwW9Uk1D!~{KhWI|Hr%tZI&2jlyD$CC@o zf)0~f=#DinlCsOCuJ$^Bo)$6Ej;}Zl2-!cdAJ33;k1ryaL22*UKyMPngwFW91^eJq zJMeE&1|RN6hH{*Of+DBNFm2@`5q4(FV>rl?bkxZx4?F2@jg#rB1}8t_IPNS*xdkS| zO)3HK{e)3ah>~0xnB_0b=Vn>}yRtP)g zOik#_ur5)JPN8)u41jZ-ELTnG^$Q^(!zlzPRTp*&t59)E3|#}y1<@1?|HGEL1%l%I zYG7lfN2O(^YaQB*Y%7D5S_i{!*j=Sd!p>riTB-h%?XHSBGtpbRTeW2hG9S|&08k$B zt#+efH|9)p3y|1VPym2@iaGhc`D^Tf~7$f=kw%Fpfqf58XT2Wr4s}l}=g&h*mi1MNTgA z(<4sqN)Q`y!#f@PU~Cp!X8Tg~Iw>y3VCJB=wK8rp%)3A}Srii{qP3HUG=8_3e6dCw zW=K9p%E>{#gI_5p*)z!Es4(1YaMmMbMR^N5%jDTXD22k3cL9z?CKK>AupH6@nFE(8 zfTh(@CSw9N&zYkJrTg`G6806cYlYq-ccC)} zjICIStOy>Jvpwd_sgzV5Q(*_Tu*jWs_c%D}M-AFaPz_FL#2Lnuz0x@c!-ywmC9tb< z`dQ1JaLS|_Zy0=c21d59lDyMYK}ayz6-Y%yUYr_XERr6n$S!m9LFoIALIEqRmqAXs z^0X9T?m?S{4n>j@T~3>x?oQ`KEW{d{3%sca zs39|qn3y2Lf%Q{i8D<|%%yc(`YdP+L1qAUM;~5x-O6#>tlZ?Y&8ow~?11el@VYWth znDz=>>qXd*rG#yLzzjPwBf962V=o-h!u%odb-MMOm>R*_x)wQ{@}+WxQ&Jyx<^X~P zEtD*Pu0fMu`AuZDwLXki^b8=e9R5aEF%hsgf)T^?R1UUia1H$$eH!nk#N+taLV7QbFH^QI!mqBRTNKQ{AJ6k0uDEy zBB-LAU7}pApx^r2kp`#1dOLZ6=P;C-&#YKr{aLyy5JB)~B8WKHU25H>1y`manAp+< zw76oDr(55E@HuWPNCP>g6!XJjrv?&B%-#w7YOFsCHt-{?<63_T1hG<13#(+x(;byq zpHJ$DW!}JI4u+utEh4<4rDQXtS=%A%AIt-km0|%?OlgKiksh`r^-yWO{g^K~oO_ac zcpdxR&;bsJ^=l9XMGOq$Y?RdOK~}w3&TRL5bV4PkwS>Hfotaylu(rrB@|@^u=$zGC z2gm^bsX@lao2r0u5dgG$mVYY^_bv?rPvBw9snr&}Mp(Phsi6Q>i)jUAvoL-%nyV;D zFp4pn51DFyi=l+bz@kATa;QCgF1G%lWQwp#8>G)_lDgShwFZrM>~)p_$~EtCTtJn-s_0;Rl+PlOtTf-v}d*KBn|5>kLjyKUGGd8)-57AIHboJ75h() zzy+-LL8v{Z76@BG?p|jpIvWl(l0(evrb7sXvD(pH`#;l0Sv|DU6YqL{O z@64(|M!jbNBQi8AFfdSSShI+;0<)0JMdf1LR_$_WI*YveF$c)9+7_vX`<$?IPJ`1F zbuJF`j->{sG-*XE%E_E;HLXt_3p-`j4-IfhGF;>+t?ptQTsE|pU+p#o1Gq|NMwr@4 z_`VpqSHV@z`eC8gv~VhSiXZu;EQ;Xg5acj)H z6i@Wm8UhWB6Gj9bqoI6f`Go}Z;uxG5=sXuH1<@&3yqu_)7ICyk?zlC0gH?NBXc!ZW zXb)8iM#z8xn#n&@ODtpb-09RfMHNm~4JP1A#7`Cxfv;FtPYk9IaV2GlK4?DtO{@mk z4bc@83a}Xo@VakkL`2UI__F}=3yNs%b1|xH1&NYB8Uh_KZ%(e-vI=XVV)PNgI*kBb zYfS9B8^t;ycj^*_-d++)MFdELvxu`|*vZlzIPhfX4Wxyg7<0Tiih3J^c)*{~?XVyT zhSa(Td6ugFZ^}^#oUP#>U{d6F!yc){4yGhp@m1s}NLuNrSQI;0$>aZ(v(O-H^?`}4 z4C7~$1$E#Yqh~1KtDW2mXF46}Ra|0&cMH(Nly%&9r2~vla<7j{rU(zEQqAY;To#sk zb;P-etWot&Q61n@Bx9zP0^`X946f50ceUs0Bxsq}f>^YsZ zq?{?};e7$1r@l1w(Uh0a;eVr^Qgi{0?`}ZSCrt#yD2k7UB@mRu z<)WI0b!&~I$|MwoHeyN^$-KW}vsiE}_E(_5-U)7EndsDrx8`uJ&t3`DVk0+fL24LP zP!S?KvRNZr5_765kpXvwLx^=}iB9SOLKHWu!kcI9SK%pfpi@2*^a>d&7uxEma%XyV(h7bd zsiFyM*X#2?(&|fS0z#H;efU^|$k?+67RvB7-hC{J^>Id6GG8z#crgl|Yh8H^p^Mbj zx{HuZ8ERA)UcoF)X2mI;$%XIfF6Tv7$48hb1{YSLV-3|`Jky9 z7{TGLMl3<&MX$Fr;#4PA`<-E@ma&0JrxozAEapAz;7ea9yu}gcVmx69y;#qUF!n{T zgcnKOtMzh=bEL>g307!WD_2%?-JFZCUKxZ3%VdTSbE}*gYn%csVK^%@n=!XSG7OT_L@t9AL#t^>CG7W!W6E?>Ec$5(m4ogO zqNREUaiwg8v78w)$c!Y3SkX;@jwq`R6hZYaM0keEhm~c$Q&oqoDw*^ps;m7Cx{ULw zH{vwuzzhQ?;Z>w0ArIMD=;$>*oOdfrv12F|I=P5Sus~G8Lt+(;5~XxCd_83`jI>nz zx^6Mbv%m@Kd?<-)`O9MdX~PO%e@2R2%dLm^`2 zo6%DYs4vFfdc<<4f$`d*$Z)NTqv9%{2F$>8>$9>op;L=nQUM?&}@y9~u}N7fx|Aw|8i8@37{aY*b-O7R3X7LTyuL ziw)oY1hUDvvCTT1-yujnU>jO{x;DjkG`4idH?*|1bZsK~1KgU74-JlU zXmE~as6URM>73H0tGltYo0%Q>8(-hk)!n`oFgm-sg##ih82R4uecsSd4uki?^of1g zQyd-`A5XyC+Ss|JxhdY%+}hmT(zcNxFlw@~ZOCS>Co62BB?T=uwzS1NTQ+X$Hu}d# zM#1o*c;9Z;m?9+j8mGzO!HIYu&a4DfG&OH%2i6eN0OY!j@vV)32~s+U!ESs_Wq*7> zj!1zI1lzcNQ**qtxvRNzJEXk5ttsBVCBZNX48EndcR#a$%OLvXqikYp2paW{#wMcJ zv$c)I-1AJxTA(HXAOOb(4j6sC5Yxel!w?Ej$O4?ZI~&`&s1ET>&B6+lKw7r8Hvv;k zTSsGCynTCf=Z4ny9r5PY)|QU0mM*Xio66V|Hz-XDmjOR-i*|7M0MXK0;=1#$CXZ=Ouit7gZgb93IAriA1yR=ADrD z_BIh!@}E@c5z=ZQa@d^IAmDP>mgXJtoo`sO%kYfF9!TTvUL2&+3aa%-Bi-59)Y8+X z5gj+iCwGq?BD@6cViLMLTVO?7&x*v3mZt7a#wds!7#kbt*G5Q09N)|DiPSixF%Tw^ zui?SbQDpXwOeX6=XLB1&52U)WX;*@*)|R&Bxb9|u@1gkk;3Wfz!mW)vy)rFq(1>_z z`+6v_m>n{7d~~2M-a9cdmMr%Iw6nbj9X1h7IrB0w+y@2g$38v;Js8-8Sa+>&#JnIJ zmtkvaUXKZ&3+&m_+`S3VHj2#>ScBv7-7w;Bj^ltLzAf4_*R+7biTK2b9G-zb!%mPV z_%k>$us_u@v^FA;81%6p`G@`Kq&deYX}& z9wFI%cmluOII(YF{{Rf-@CaMAuiG5o(Au~$-qqIF(a{L(jX_L}@zH^?!I6H9K<}9J zEEb4^BYkPzXxZAhktS9XLK@FRV>>Wt@8k%0Hd4$Hk|KDb{sPfAgFB>ds+kpW;ZHpR zeA1Bl)<`3>6?1{s0RT^)g@ExOW;5MmZ{Nh=fdQhUO(s}4c39ICaAHGi^UgS+wZV8m zwAah5F**W~h(k|Pn5I3T_`VWnj#6E z8`mvgzFcrVM1hA3B)*O(vzppnaFKXU$~XL&9+G{BB!1J4V$%0Lz(Wn9wYhC03{#NC zgt`&dPK#va%GB|0NB zEZV0K3%_99@}~WV3VP_h35?U1HcWCzO>Cx?CU)3AfKz@6 z{%`Nv)wbS{6H}O8;_z38`x8C-gg3QxCYr3@)Y9s?IA^hcDMAd>q~|e_Q}HA{{*Mjp zAAz(5Op|F9^uw8mCniBp88DTjEliL!(8P8&Z|ID3{uAZyYB?`q>O6mbaCpxMBUy0NW#_9o9|61**T^j8xi+2-n zEP`}3bdfkA&^qZ;mtq>V4(b^SLqQibAxBzw=&k`J83KU{+;MVP+a=E? zfo8C!r?s1YYQTWT&h>Fx*2!U<@*f`P56f(+ZTR@${?VZU6#2e7PU8(u42}%5d0@`q z2Cv^D$}4I}FA~M6S||oAHA~D_YSxl78!ji?g1G^UHxVu_hxYf5y_w$50EQ#QpX1nX zpkKkJzM+SjPjEWx8yOkvPg-ht2G(Dsq6Pa9_M~{qm~mwlAj}o*$4H>I9-F?A{qXfY zi9~K<=*4dEl&f~Mf)-QF4+``QkTm_tJOR_#)fMk(ZCu|hSjob;Q)C?rz_u>xUQ73` z1TO6Hz#yg}I5NAjh{S80fAf#q5&v|+-EL=dW#CeE1L9cG)IRNV# zyPD&$rSZ=0Rw0|mdy|nB7N$s6TccPgpy``ExOH6ZjSmdKKiq9VOa}Y)+DwS?R@m!% zI*r{UhoI^-3BL4cW9%8JiC!!WwNEGZU-KGVl#$m?AzZVe0a%c@1UiVb2Ei&ca?J4s zHObP8lVM;5PYmf1$7L<%)qug|io%Ol$Vyk%P%YifTe}jhqkao7q+3d&w1eK9b-tvl z+SuB$>1?i6TYHv;V-uE#0p^~b`Hl*Pn=+>jJLOATutkS=;$1CG z!p$jewTOD6a$=R^tsO^MmNfl#^{k^0>C1PD*zeS?p4iY-wH-JFN$5{334JL7UkBhN zOfsqmF8M1x!9u)vkpb{o>>%Zro{IQiNjL}VW7?_imi9J8ZMe+Tk|z|T;0dAQ*m=I@ z0A6VrIgIZ0AZwv+Yie2FNJl?7vyMolFVcFJm6$bg-Axh97Gab`kP`<`ael@FXY)zlfX= zth*4vTHg&b6O6qqdYc*&0${wtCvS5sw7_C`42J7j31`gBJPq zjcx0jTMelxLV}l>pm=C}77M3+S+q?Nhn6$Fg_bkDg_b2GE4AVBBu+yWNv zITG}{@CQ|8{-vIXICIr9glT4=mt_(NW|@x6z{89q#3&Pv#KygMp&*l}oX}tGr+WS} zWOR6(0a>lVcxq@xI_QtHpndND-g zy`E(ChEON^6PP-C6C&r`%{u6v@CK53>Fc>fmEY)n;g~nxcpuCktkfk5auGE0V$lhS z92rGqhe!q#ZUizto!C<7S;xo=ioCTsBYL7caDj&6yJ7O^MZu(rWf|mKStENPO4z}W zT^rc|Fc8@q934ksO-n3i3h~lXw6K-21qRr~LYH|1%nze z17nhKFg3nO@wYAr2DUW3h?^HmhD{jSqlHX2IGB(P-x+|giMorEA^Tkt7Z4ps-=3-F zDz#-RjMM&6vAZZqVM9;bmbUgC5)}^|-yO}3Nh>&PktGFa!4itFEFa0`berK>o0$~$Q>b0mMQd*0zI*f_EIcUOD7EN zmSTR{JJ_eA2NFF@Ra{SqwzhA@PHN9qI=Ilf#8zm6yS`KiC@qYB>|nTezo=)DyV%CP z(pDX+N?w+67fSD*1ssvsP-pYD9vU=QbZ#=D(C-i7%O1=OvINt?5|{@>ei_B&1_5{? z(~P{TDAUS>!7z#^ng@GfBB-f*Ff!N{gtY*(Ji{U@QS^1@qS6cZ%9jwxLNU238cE@N zitS0-4g>{yp5#3amvj(IU3disr+yLg_{eblurZ2lQBJDZ>!9T8OllH?#3_S~xB|p| zvJc;sK<1>VuEZW0YDGcPOo|mdJmM56{q%VQAX*@~mPoWbi{5ZgN6VR}S>gwb=3;fj z?L0>AL@0vriHzS__AQ$`J2CkM8cEz}xe!Al0#g)Ln5_3A8v9V{pvSJLEdxN#za zX2cK4{ctL|)DT)ldgv01Idh!5wkPRk3RivIOJN{+;W=G?v=5kTMy}^}CypT?N@a}i z8yTAj2eB^tDam0kz|>I~thW0GA&!j4(`$sSl(4x9vR*nrg=)5U})L(_~@fcq)Y>rg=b>#Kxc}wdGaX-d%QC}AX4YHwBhWE z-Y6tB2(9n{7Mb7~gkY0Ldg9tYv8>}<>mNWtb^z3K()Ia|WEJB%fyAklV9dm^mfZu+ zSzP}H{d+M$&MXP9aQEQE{@zhN!|lfx4<(qug)i{q29g&Q@l27oAEP%zz)^{1k0LT1 z#~0@G4eT2k!u|%~Xz$54rJ7iLkp$L47>PL6NDN5{(-|L2;*{tE4l5x{LghuM9ukLu zvJQK}uNjMT>)+cN9~|C?&2O!lyC=u7Jq&MzaOs6e2ePn2w|Wwqkhqf^7mxy+>Vn_N zF;D1-1n0!%g*9z8_KfpHfwmEXoZfoV9$w)1$4ABn_YMwYqbT5c!Yo6S>1F%2NS5Eg z4qTp;y*J-I9v|)<#WXJh+dndi6^5bD4CpnO7^KAP=p8jce@SSqhmQ+wMP?utI2F{6 zb*py*Fc=$eVX3*4*xO*53X?Li1Ke4Bo$mH_K<&iNL_o85oG4{q680GrzAPFf&ZEz+ z?ShAdI90BNBxlF|HIpRz*kYM@!zxOoSalbNa!_z&>@5>AYc-@ zqI5(-C3F-B(!_Q_1w~LV3U(9=_J)dz1smA)ie4+CV#O|c^@`={`}@uQ=A1oCP~Z3e zzVCjr`R+6G%rkXoXJ=>k_-B>9SJO0KpbW~#jv1b`4S(i+;3%9y$h?2n+b)y$wOEFS z6)lLW^Yg6<)_R&G)+7_v*Q`tN&CxO5}Nx@ zUiuf$;8Km`ZEqr&PUz7{U%8z%v3F~UON1TqYK@sa9WVf4p53!M|AsIz-yOcDM+?4+Kh;g0moEWbLeu?sa#CHC!ApG)U^6ZmjC*mQwzjh`uly+U8e@nwM zGJ}s8TiCzL_(K0{V1->uyL2n<(Yae;M@&#G>Wc?jxbAeU>;-u`cElIc`l4Q^!eQaeMRO*DmGh^}?2B)zEk3AYW&1hv+GD|J`#``Mg&l`4DC~%@ z`t+SKcTtxmg&n7JZ7iSAcI4Vp5Z=?-^#tWbb5BBF*wJ=Cwg(A~@a+tVKU)&GskGf) z;{3GTHtx@`Xwr7xsN+O^q&8*S#%(>YPH{htdpE2qnl(Ex#q2LxL0flEzqy1JV-#Nf zFlKUN`{U;M>t#c=+NCos`;D~{-^H;voA%UAv^?J4Y8@vpb#Ce`;qNXrg9c$yZE%`1 z)#E5U3%3d5gJ*W=h?lJ?F$L^*Ou=Uqyn{@=Sg5;Uau9ztUDOc+v5IHhP(0JY{JkwQ zd**Y>x(ZY2T#AucW|7E&ousu(KSvB5hdHJ2RBgb^Htj@BmJb+r9Ofheci z?paSYqbKIjE+m^Z|3v?}adJY;)rB2XK(IIcOtgRPMDhFcJ{;#K?*f@oTxw_I#N&b1^1Ue8sbxi0cpT-O>w@>#IEAfyT z+fG>U8cp#wFfe^~!nFCR%Sg+Q@T)7(4ml5wyd>gFUR*iK=lqo$s9-F@xg^_mm50*^4p{>?bN$jIQdIgkT;BaS>*oY?xJ~I7UYj_5~*c| zjvFv`l>Y<|DV#oQKE_ryjrOrW)(6@X*3PxE&Uo*i%q?z^?T}eB11Q^*X4;4Qn1tc! ze-g$(cD6scdV+!dypP7MDV{*NY1c%el0|q_a_w-qJb2+`?pTF>TjPDKJ?X8pmTJyh zgf{^aF$NaDYt^z}Hi?BB?m;4Q$`5eacNr4ta+9#hjt-3(kM8}6Y2GX%J*n4I+e6va zNp@&wud_3?px?SAl4kQ~%hDfL*sdoLwOuKP_2;Cr+RXz{0GjM2&Hm$sM;^SIA%;&2d81JfqpM<;Qxp46(v6%S8 z>nS+4H-IowdE7}@4dmY?*bBL9G~s8Q;nODBuy}4JpY|o5#$vh0e0y%#Uc~PL5;N0w zoP%VfTG1oOU;v-+m1FGVW;gg$MTW$MCk)UIO?L_~s0rinX#|+_`et*$YvgCLXanmaPJ;44q0$iHqpMbXF z8LvN-bWI_-;6EHK=8)_dC-5=Z0aa6Q12h+(_8m8Hy!)Q7YdC&y!x-F^4X+v5_l4}m zjrXQJa5sE*@s%4OAT^r4*J?6@qZU>36=+PUJ7)q8@9& zz$1p@ii+87EPG%d#ii(+GH?}`n0*Y4PW@{U-n+q4hQx#A{qyR-^QL^Xrl~+x}gr?NMDvYj4x>jZ`~*e)Y;y|Fp?C%q1{SLlQH|}J5PEuZzlTs#9{{o^E1E~dNd*JFL!t2lSJwd8yFZ+ z=^A6-<4V}j^nl+p1=f0T)|0E#?V1W`qY$|8UIQ(^f!j5XhC=|H#FaA^7=Iy_osZ&T zS%0+%y0rPJ-3=n+l{fXBAUSri_WU^qV+Qx{-@C9)`TRMBoSPcszSZx~P>q^4yK`Zi z3VZ~6Y9T+{k7=te-P*PdPha7;EAg@1Kd|9TA*bc$)UYy~>{f{X_&joA8-t_%xf#nN z7kKu6tvq*cBwE|c$}P5W2Gh(ul;_sJz#Eqv3+4^q zfKJI9%dtXb8cZ{P3#L3bXL)o5;z1^-tzYzobXT_JNt%#i+JqKD-v;OtW z(@$;RmTQojHdNAf4OotHQXMSK%FV0z7c{AeaxuX&_3I?>te7A3=&XM^i+)>iHc=!g zWz6{c=i+zv4$Xqy0ofJ!AIvvCP@N*jAP3t}1>|5m35MnG)db6yziR{C3%o(8WlOza zIK~l_tMd<*Ie!NyRHmi_+}!p!4ytVj{d3DEsSyPA`8zrTs%tkDxhuWMdp1N+pTD;g zD1%5@maC)2B+GuZ$`nJ_Sug_QqFMZ7ayMwY*EuFWFMcL4{TA>BxJvdIRXB(KMZ>W z{=qGp_=PUtHENoL>^BRlBR#39kDBHom*(blgkXHU21Ve{@<^6Rb8|jqZmb#4JZz8M zzi2>{Zc)=RdH8PUY+tD6tF}X!er;zc?4gre z)EpFw?;x`e-i(je>SFuDlbCAL3D(&Xi*F!dZFrqV}u{%6&uW?`y*+bKMueiRbI{O!drz$-p>@nnOZzSt$Opkbgxez6z_K z?3H*GPHs^%ASvJ|Y6gbv4-EMa4%r`U^=l`z1}Bbq5H&+X@}VL7hlc!l)+e{9IXo2K z;Wm7-e?HtaQu(px@@#7lh9903a1=$)o;O#nNg;caLjIFO_9ln?r-tNdA$!w8{xd@MW`z7_h2-Ny_Kpwv&kos}9rB+WlB+`Y zszUxJhU}df@}D1)7liCB2>CAx*;^FyKPed|H_cPl_CFgL-MMSy;ULq^FsEL zXCf7&iL1XKENU(Y*}EWQZ%xSFnvnm6A^D<^y^BKr>q7R{h5RoG$(M%gT^jPgJY?^3 ztN%zs>+-}A52EJEki0%*e|^aR>X7}btv-M2)8DRk2bNKDO-Q~rWdGWb|MemJ*PG6; zP4m3BikRzd_!u4RcD*~WjG7xl@{OVRZVdU~9E$JekpHbA`L>X~+d}?#gzViB^1mx2 zZwlGl6!O0(WbdAk|K^ZI&6TBtPgYSey+w$)T=7i+4L-NHT`MQvN zYe;@DBySJNFNfq$Lh?@`xkeA|&4vk{=1lPlx2U zLh^?p`KOSalNj6k^-&y>dxYd+A-OUn&xOn)9ELsL^fhOM{8!7LWtnd(%r%nhTY0eA z9MXR=B!4KG$=6tUycreJKSut% z)5|xkj*=DC?2Fo`mny(~RSb33&rr|)FEhETG zZx;4^bBZYm`S+23zV%;fMyKd6H*+NW@vSr~QvA;|SEl%{G51U6on*dQXWo?jxRozA zKT77@UB0>6B=7zF_EW@y(Z=+54aoyTa%D(f7?RHk$=8JBhaj_jHet^N{vU?q zA3`#JFqz?b|C4X-FvXIomT&Gchd_24^Wz>t`)?<^wKRcG?G-OH#aI%w|I$r7-$}0A zNIv9q2K72<;Eg&2aQ3xU$38x@ZvJ-#+}B`B@Hl$^2h03n;{^-3Qof|r#qxL7_Jnop za!1(rpVVSi8J=SLU!g7Onmp{1JjCO4r;v!)&z@al0be`0idPW16!*9(^X6eazt!Xe z%j6eGm}t7}{~i`Ru$Gn&679kXU)1-&An*~k&9QqQkFQ49Aa>aq54AuIhl%I$$&Y!! z)nE6>7+8QVCCNvZVORIaSf5ye1^dny9_;B$x6Xwo5({urAJFm*h~y_25FojxG4Obo z&ukOf@C(7dp#^=rMvW2p%jvZCCh?j$H1u{djuP2UBu20KJHM2#QHCA&i!u1tGL&t4 zlOI2DE;e1k45Tj6)B;XFvs_hOK(hIk#p8BMZ9CbEf9SUAFgBuIFy0^8H z?krNOxj1Ekugj!51wSPbT+q#!ZF_T-6Fl4T)K(v7Nu(Op#5$mH_r7V^&pyh;OMr6s zlf*?|{`zn@GyQZ3EYnT+CF4(BC+3%F(pX>xA6JJb+IVWTboRe@g=ls1*$3nxxV>v5aFs)2T`Iv%nB`8PI;(ZWUUn0&M`jfSXvL7AzDhgufA# zn()-+iip^6$7;We@A=Y>q|C8t*3bTPjYtP$pB*$mA>7VtB+`A{; zbLjr7pP#JX&Q+9 zqc_m=%tjKQ&fh^sJ@cXbS!7xL@ec!}tiJvnK^7(l+E6|SV|)_&ShirYFiyIJ#K8Az zakJe2OX9&o8SXt;j=U#gINl4<{t^;)ZzSWM;XO`Px@VtDL@+UtfiZq0(=)tRiDY>u zj~t9=-XsdSKKY?B%|Yh>MiS-AdkMViqS@? z*NueU0J4T>ZYFa*bC38CS<^EgOa4auuiW|Eg!#!Mk&nh8?Q?54#KN{eIGe0mo_*%T z^6Cbe;d+vz^=uOPE|WY!q>0D}_=m0C7@us1Y;O!tyG`ABFd^x0?>iSOum_A0$dKpj7FlHhN_etb#W2Tbu=hkkfPo^^u zhispPB+g^ou94o}lyM%Hk&urd(S8mEn<8Fr?cCI}vx9cj9PTW~ek96q5ZTznU7Ig2 zA<-_+1DU=xB+|8xTxjgGMY^x2{Jt^E!9;wEAaFx`wE?CJO+V>>8a=VWKLRvurt&<) zx?1<9bVt9&t=-u^sh@$vL_DjL?mTM8L~?_kEq{~)+eKEf>|bnstv{NtX{rYz?XF0= z+xkX3=GJb5Pukf6>Y z!i|D6!%Za7-^?b_Pq8Rj-;A2)=OZA`A8zg36d3IB9+>gl_Ct3K(ybW?AO?@c68`BTMz$er`H?6=+` zU3#~{2sfnH)vO0S9e9G$JnYr>`Om_49e!M&SAIc@3 z`ILl=A~0D!(0?*soX2NEZi+%!MY{9lISAa4j@m$0PtUFn$m-?!*GrV&2)cvze1X5M z56H{pejSN;ZzX$sc)A|2&qCv-dTx3U5`(SX>lW7Co)^x2XVRTV5&Y;P+i#?~e?CMS zs~^J@BhwrCSni)0!=XatYrp`IWJ&0q9;Te^jN_>m#CwtUO#~7fF3S zMI%}MJz z+aJTt6HgaciI<8S#k<8v#TP`|USVgCWM02%Hw_g=))rfcUBq&6q5uXxY72g-X5`PxsQ9oUEM9yI{on6KL;&5?{I7yr)o+zF!t`aX5H;Q+QkBTpd zZ;79X--~R>OizwjUu-FM5f2fEiARak#f9QBk#mo#!EN9ykpe-J&4 zPv~A#Y$O(n9mLLJUva27PMjjn6HgaciI<5tiCe_&;w$2N;+Nt+F%2Ci(^(*Lu90$y zI7A#PP7$j_&Mi`ZnYco{P`paKReV6)E^=;>;olR#6!(egxE9dAuGmuSCJqosh_l4S z;#uN_;??5q;ui50@jdZNai5r$;in^CED}q_GI5l6tayUBL|h?WByJGz5FZks7XK~o z7QYsM5i>IVbkz|XiXFtB;y`hfc$_#}yj*-v%+2!cHWS;6qs3|BeDQqoM)7v>9&wBK zsJLBxUfdzRA?^}C6h9Nc5q}VW5xESK?IbSdi1}iDv8h-rwi8Rm9%3JnYg=h|hpXh?~Sm#h1j7#Y_zFXuqX+sJKYnC~g(EiO-2Ii*JY@irn0dm+Pk^S8OD<5xa~1#o^)@agunBc%FEN z_^SAsSOa5KmT!r8j5tgDr+A8(H5zED!#Ye@R;y2>2Vg?5G%vU3^gLt?&U7Rh>7ng|t5Lbv- ziyOsT#ZBS^;tuf*ahLd^_?h^v_^Vh_;HS5n*jp?U2aA)$>Edj0fw)1uU3^M>L3~Ag zQ+!waNc>#c$# zrdU&~BQ_F?#MWX*v8&iiJVYEQ9wv?yj}(s)r--w}Dsho`s(6NYj(EPfR=ix?Al@L} zCf+SRAZ``6iO-2Ii?56Ch#!c1#IMEwh(C*ei1@K++g`K9T4Fu1iP%DHD|QmQiwBG4 z;$ZP`akO}pc$_#*JV88BJV!iVTqoWpZV{gn|1JI`{!fh7Q@assigm?n2> zdx?jL1I5F{k>Zi!G2#?)mRKb&5>FM+5YG|M7uSlHiyOon#M{KX#RtT#;x_R)@n!LK z@g4C4agX@5_#g3S@edI{$?Ufqv6fg*Y$CQ0+lrmU?&85>xj0xnTpTSPB_1bE6HgFN z6i*UQ7ta#U71xMYhyW$t(Pht!cJG^ey5}S(c#h&6oag=y@BR|{*@doiW z@ow<}ajUpZd`^5>d|iA;{6PFnEWn%<)7e`bERGQ;iwnea#C77e;+^8d;gCVyW0yJXAbVoGvaBmy2t~8^y=OkHzoA-^FZ9Y%||2#cpDMag;b&TqUj% zFBh*9Zxc6*Tg9ivm&H%Tuf*@ged6z8teKy_EHO{4D>e~}#r9$sv6omT4i=9P$BM^_ zGsJn~$>N#fYH^)-m3X6gm$*fILVR9)P24TkDD?AJAT|&S#a`ke;z02*ag=zhxJ7(Q zd{um3{7U>;OfT}|A1TfdmxvdNmx@=38^!m;FU5Ugyt!|;q1amNCYFmwh!ez_;v(@( z@t@*)@fPuZal81I_=)(v_=i}dg`ch>u|zyr93qYrPZF1l7m8Plw~1TC7sNNkU&V}K zKi)cGbFow$As#CpFD?;Rh!=?)#M{LO#izx8i@U|I#b3nqmVSC_i$!9Ic(6D`94k&1 ztHjg9bHz)<>%~ptR`Gf9P4Q##dyx-P*&pSKjm36iPjQeqMw~3p6aOKeCte}mEZ#3} z7he@W6@L)D)~YwLNbD{S7bl9d#Kq!S;w9q4B%bp;F8Kp-pIEbvA73l6T%0H_5!Z^h zicg7eirD(@X3p|Dlo(7e~o`vN%WXCyI;Zeztgtc&+?z5O0!a zl3x;EmHWGrKM+5a`*)Im6n~L>T8W>pOfi@I+L#8Cn~2Tj-cfRAv4`9Ti6iAcRy3K{3AIW`>_?7%4U3|T|VzJmx>_;NL3UP?sM~V|jl-pDi>8m24zd&3f_p>CQBVH_C zE?!N-&P^ojJU}A-Tjjn(@*Co(B;xr({EkHUUr2;c>+1Vwin%1*8%S;ri8 zxsQ}QRyAge#Tjc(T_=MbFl)OWHUGBRje=L4Z z!ruQRd)@r}$4Qi9M-e~PXXOdviQ*L`!e39KobHwTb0o_7CGl0c|0w2l_wBV4%Sh-C z5QoZrws?+st@wbrl|=k6kqG~a_>TNPkpFjb|55xy?zMXO;p&J@N#wg&>?!v?;y`hz zcq9q^1>zd<5)$dUkwm&~6*tR$tK=ude~WL5yGhvnRQyHmzl-Sy`F69#1|;;mi=)Kx zB+@aHL^@`Ri^P+~e~{2SNAha%D)CzJRub`S61U6!S@9L|b@3w-`hSRxd-`&767h8* zk**$MncRm;K3qIboFdL9VRycGw%k{VYsE{&8%XFsA?_5v5i@)F{xwOYtC8d)v5VMK z96}=9!^E-TQQ`~|@vRgu5U-Q}jpAM6z2Xxj!hIm_5r38cA7VytKmHuC7Kv~j#UbLc z;!<&)c&GS`_^$Z9n0YYl;e4(`)-a|MiTrjId&+;XI7;s0#0herF8O$Ip4?9tSBdM$ zkFefV^1sF1;#Xq4kDsoVVi&QWI9@zSyimMNd|rH0{7%g4>)UN2wiWw}lf^3WRPkbQ zgLt?2nD~;oQ`{r|NBkd&>wL7IAAfVPlh{WbDvlGUi1Wl%;$7k+;&b8$;xA(QA%1)X zVl%O$*p+OE>$l{?N!0&Hu~M8S9#5jZERuY(_z$_CEBSo!A`F^XB=T_^iS*wkZV?|5pCF<4GP%u|uf^y9Uv47y6ps+6h|5Tn(`s_7 zF*lHi?-ub+`9COmtN5hcUy}Ta_=em+ko<}Gh1`FX{ImGG+%pII@zxOYN#v^$iS)IS zdpog@+z%t6H%9Vt@}DBkl=}k7CyA%Y{T#`w#Wf_#;WqJ6@eOgWm^H}PYb16O`-?}D zNcS{y3;GEX<$9L5QvPctUn;Jb`%RK>6F15IVabn)+ezgACHcQ4_g&%#a{o&5Uhzi~ z>8go)MY4g|Q5--b{lmx|xUVLW{^P|e`JW>BAL3ag^w-G$O1W2>+w_yBHbjyQh-~UzO z2l=@%cZ>Iv@P9(`Q{oG9e}lZ!n7wlULHt?%u|s`(8DcI8dkx52Fs_sPL1G{I50-qG zI8yEt$&JP=misBV*if00DFy(RZu;wR$g;x{DpekEbA z@GubhX-{5Z%s}#UV}^=H$p0wG$B2_j=$|J4bI6O0xmNx+h?~VN;#LyzJuCS|@fEr6 zlDu2|MDBYf{~-P>_t-E$y%}N+687s$ZY&m&NMCpH5E6Qal531PO7c_^`JXAymHPs6 zr!nWreT{gr{I8L`QM^U&_ey?1e1wFZ*W~{;`MNRR%m2UPukw!{?x!b9tVtr>4J0=a zo0G89oBZ0CL&(*54~s;8CW@8h*SMdRJWpIC_ob505?7M2bB+9OAkW5oGV*^?d`AAS zN`6CpNA90U{#^Wqgq`>ietNRWGcbQZBE4S z*UJ5B$=8WDkqEa*e2Dzon8(OP#{5h2+a&D0D}E^VuO)vc{#Wj1xUU}*GfCJjAm2y( zBw@dUSSF4mJK%arLa&M(ZOqB!LR>c`pGzYARpPxQ!aYeM+>0c_y+I<}ZpojL2*($E z$YvzcRZLbH)0ad(@v~5tgXBL_@>ua`xlffmQ=B9BlO&%iE+b)oop`7CfcS#=zW9q6 z8;Nj8UoJTl-{2vUzV>3N{Ci98C-#^7;gUy+LT3VfSS5pCrohYWd$xq8#rb zXBhK{2?;x=lM~S2h?mIy zN^%V5#UyVg5ziKJtK6Rsn}N>CoU2%5bqG57C#Yx7n_Xr?e!4HigU$P z;s)_yafkQ|*$VYJ4n+QHi494(7mB5F?8{#e!@qR@jJ$uC;<^H>5 z_O0~K7Hf*NNyOhq>>~~qCx}(zDdIUK)?w7arIpY1G3{iDONO0a#t_5uLJ>o6D?cQ@ zC#HG6drPs8I7cjw`2G{c8^pK8hEd;tw75pRUwl*iOyqYEIR9ND9xM(QXNVVw_B})B zzbpACF*D7#Q&(&&^1BJNUnY(eSBnpeUyJ-M0`>cflf~1;>&1t~cg3H?NV*@shFD*0 zE86$*m>$W8i4(>7;@RRw;#K0E;&yST_>K6BXy3y_Jaset^mGu*#9`u*;uLYNc#3G> z!y97E#ggwQYZ$XrG?~8KmTZXkzr?xXMdFQQp)uRUH^nc>ZD@R1KI@4c#KGbT;u>+I z_=NbaXx~?Zz0ujey_3X^;*;W=qJ6&%`uikj<@n+1iY-XYL-i9Ei|31XivJev`()6M zqKp`>p4e9GLvBI8DNYrair0v@iQCB?7$@cW93oB>=ZdF@E5xi z9~bM_gnXwl-NjMlEw~R5&m%V)bBp*iiO%E$@mn!35AIjsIwzh$UX15N;!ZKYmhawG z940OmHA}^c{b+T3Ve1I$C78@xum$3 zM5p<<_zSrR-*rIWN-h@d`#@E=@1YF-AhxOF%VWuzc<)!V@2^09fpVoW--;P^A&)Vp zkVIcHLbUIFKwd_<6~_PKr({R8vwA+;klisqC|)7{OZ-ZV)c5u3iycJ!UctebhoB5D z6VDeni1&(*iuOGK=)W%cL$Vy}GDN$sA96_p-@Qy6Bii-*@IPMiV(~2UIn1|<1?XES zj}z|`KNedy^8IIuo5e51R*ilCf#R_uiq=H-_}>Fzxg*)Oe?wPgub*v5#8FDZu_uXo zC?iq+Lr9eS2=ZWkcLw>HL>Zo_YFn@K$O#zdk(DT45}qqbv>P;W+paDn(eADx&oJg@ z@@)SblWfmhC`0*i@?!rxAw17^P{w)q7K!t7H;ME1GZN?XUh-b_b0m#;Ao?eKn#cCP zc_hlWJ_%!m;D93Ij&imdZ+D92# ziSGrGGjab*qJ4}a7vcOQ(LRnN&%pcviS}^Z> z{3h9WkjwSG7sOvk8Rb5Lgv{>@vHWLBo=r|bKPLG!veK9}lGl-_mras4lc=9vl6RA+ zrwq0m*v}zPL;ot-o)2f}Jb?cIx}*Lk$$u(|dYmVDA&Ej*CV4rDdR;I18WQz;yW~wI z>Uq25XGzreYm)g5Yu5Y6l0PHw#C2WrJ`(L976p;M3=)N0EV&Jdc45Es0{`)px8eI; z@?S}!o$&i`48Mg$d$HedfxL?{+Ks(Gg8UU_v>#Kl;N&^@0cddHe4jJjk^PisiT&ls zlF9gFXvzF43MKg9q5aY-esDYakzj`JT+$gz(`J{@yLvTKQa~6GJ<|W2tp5weDIcV+rtbb+zna)x=J^>^{R(nw91P=9 zW0Pt%?N@qjWGO#wUrmbsI!yJc`g`I2EM@ki+kZ1fzV6>oiS!d4RN}+l`?nF4aKd-L z29oMoef)vY$sW-bkNvr7`z7mYqYdd)7x{iF)hD4^wUn~=lcFz3AE?k%mHsj+XN`)% z$n;%l|I5?|h$~g+z)^+t5*5lE`+n|Y)dwu%RJ8+@a#-uHlH{UIy}~7v<^P1e?X3Si z$`r-FiZxX^r8E-1Y=6LlNN5}=K>>vWCnTg4toVeN`>OW=Dt~{yzY$%+CUt|c`ZdRo zF#8|dK0u`VsU0}ZYE`R`GVvkrzl=4h`FA2t)vi8neJcDfV|IFfCtjz!|CQSIF^P*y zwWBEXmepzPpL+XI@0s{z>I1bzzXk$of0g!-YV}dt#QC3X|Iuq|7B`Ywf|01_7Cx=>Co5n|87E@ z`u~lT1cU6K6#r*f{xo{2{8f|zwf&<>{>Z?eMio%|tLQ?i`$w7h4T3+7F{$-e5vFP$ zAim@&@nF-|DL5~YI$ZZVHUD=T zY)3J5+T=wuFnph0WlH?x%E_4FSPWYjg7_}8tESAJwO}DYxrhh|0}%?(4oC9*tyXj!?}%q+)ou<`uadF#O}734n~5R*vllZ z$3#8taXuf9)D870pNO4yF@0vYiJ}AjxLt`I$Mep#lK(w+hNmrVF5XLV9E^7(;?08_ zmBzt|PcHE^deWdWn4O zh8x4v7B`oVp`mzR3&e{@u!(rDRJ<-9EGM=Zx4HCGh3tI{du^b^dMm*0@^PW;xp2jh zgPRk#`g)0cP>=bbEp9F!55hfIA30bnM?zI{9!kjzGcu0rmtHdeRxEYNFRT1g|=Nk zv<1SUzA5{ke%wEop36rJazk~PKj0qB@9aQ+TSC{xd!%nK(XPr6?r7N}Alj`3^n&(IgFVK}e6Wvq z_70al7cThQoiya~!Qa3P=7Y~gXpgqIx$@(8=Y#Ps59Fhr^ce1Q#p~*0BkZ-JA#E-_ z{7!w)-nxK2UV~gd-j_WW?s<10doCaK5FnV37oo@W&=xnBj{+P7M>saoln494#AF-rDaKE@m%AE)?w ziF{Cx>7gxdE+30S@%9Pi<51}_+|`QLwZDn5hsXDcjqQN@*U|&*HXC{~bxgQ;w}s*z zhImK7pZPspdW`oY*>m}Q4fcYYYkypK8mu?!F+6Q?bMaWY2}`lI`1Z|6M-#dlbQZbb}uAL0jBhK9+{! z{Wy@1vC?BW{*DE0yL#jA7UV;A8~wO{Cp}khBcOMUQvzMQFNWg%0r5_PKl3|YdW?6E z?795zJwSeQpd8FE^%$PExVd;U;25m8F%6UF`2^`P+)=*0M7?o+YY7c$bLr_AvNttg z?-=O1dK)f#E?lb|XUQkaj@zleUgCUf13ft5*Q@=_<>RDKybA;IPJ*h7_g{+F)ki7p zxno*%>A5~+Z#nESUe?EC?9SeH*>mA~93UUx`g)0c^i)1*i<`^Gm!Wvi3*=*(^q7tT zs5F+5OM4mYwSnw5m!7)N3)b)YKt5(b+2y0R?746=50HeXN8%XM^@!dNQQv*Qq0ee_xm9TfB?747n93UU-eZ53J-cmkj zi<`^GWubV#3dFladd&ZS6t8P9yI~JbiOr>FTgcvTu*dK`e^0^g%H?y}bK$-?Kt39v zzYF%KUnw87#m(iT4)lWc5o?s}PfwQ~(=pGtmpFfafW6@L!=-0n$X;#ObNN^rus2=y zT)22}5CJ{cpI+$eCF&ysdbCGd++04+55?O!kdHH^$8dcAA=vKoV6VFR*b+)#!vm!6 z(@^>vD}BqEIBYI`ABNJ`A&|barN{I&M7ajjR}6d32JN}>%9Eax+Z-T$eSEz{`B9JY ztfVn)&Nln^U_0m&NZ%^yG2Glx`buH1y7HSEN?-2-r0;@I`uKhb<2esIH+AKXM4>>^kKJxVv<`vqXS}r6OZHs2vmpmJ#>H)}ub0TjO2`aP zTijeej)!|N-tz+a;GDCI_Z8n>qCZ#z`EeT3=Im_<*;@~LWzbALAi&t*+agz1DCKmdjVLcMX)7 zkE^k}d@wx>?()$sc(V$3XZkE(FOd)GF+H@!&BePk6z_SBll}9x(qp){6|ZaeeQ3`` z7O;0u$liL`H4I*Sq37!3 z4PP&jkH*lWJ=)^t^6_dY-tz+aV0pWE+oK)Pw#!E`?73swbLsglWN&>SANK_870I3p z*X{uM7~$(B^1$-ZLRR{%%@zdVFt?VYaT zI_MP#^j!IU4!vOcZASUEf!@p5w_R1U~e67xV1UI4Cn>z?Sj3_Fo8*X zk70NA>WAzNn~QgH0u9UAYZuacXQ4538oOANX=)XUcj0)?lw$6I@je-dw_nKKkPGoH zjEf9?$n%^f=A}&{Ka6Ji z**3B?KF{E6$cZS1mRNe&@$GwZAteR3~+Ewf{?T7C*@fzRN zN!$Eb$L8&upTDnmp=s~kwdJu16`c>wE$TUl+W!A_`Xn*p zy|;&dQLFwVgG`Id21ed(ywA&C@^Hzammp59YZ1U9;&;@Nk9o@m-WwZpnM`tP2zevOQHr=Hhq+n3iwpW4Hc zm@$3&baK<}nag_KXPVbM%xjr5sBq8|pEqey7qmLi48JES%pkRzX!b*+fmDfgA&#|Zh34@ z#a4vwJ7@*+4qx-FtqaD9{1#UJry_#gfL4stmLyR4^~ugVrK7&`*gM z>A`~`FD1T;Dp<%f?Fx2|M!U>=cS1$>fHP1Y@poBU@1$qGeqlxCE8D8pR%GnxZ%e3P z(ARsi2mROX$$U6F`R}f($lJNP;e>`y(8|uBm9zfTieEPK&=SVkHs-Y{+k4}(Hnye3 z2l>n{i48jG71jm!SetII_~##`dH3QhER5j1_1cwvf9|q%NI%ZW5z)QzXsmtyD_+Og zyR5l+wp~PeySBwTOS*dr_b=@tCYH1-QtThjM$D!6 zd|A*e`gYCsD<6w|_eYoL-kMQUqSt9T`#YwjZlcQ(52+Eir6dV zO?~Tc?=kJ)eB~q5NBI!MA!|87PiyU5m8J%KjTw0OV81n^@;SJVWr}Sl*LP=|m z%UNVb{Tu0&kv0qponmRTu(+pf6FDC#jQ7sTgF;^95)3or z{c27@nA(x&@IQV?!S~QEjtr-PvOGr9CjKglG+v(j3ez~ki(g5_3SS)Q#V>_UyuUAw z^5UFwi4X9_(O&#nh8<|d_!uv~45R7zAm8_BFMcY+4)(jBZ`K$(k$x!A^g@-yRY-e!^PDxvZ!GdplvjESD`Z4k zqm0s9<=l`ciS+I&iJPd_BmY5L5)l+Z`av~V#q}fKpup05TA^|LC;IfVbsaHYydL6C z@9m2bFFpr$(+{>{Ud)U0N0Zb0SkbGE+|)wu(xx`TNt^WKCNsX+eG-xF5cP-9U?Pe zCf?T8NNN0^te$pOh^+DAx6`k^FJ9!uAEMa77uR|593(8>(TcH4ym)_1u~Y=($-|32!D@0qm`|KvdF!#pV8V110wuo;Ec}cO`tF&awg8> zjIP#aX5>)xNg3U&Fgt!R8dgU48c(4xy=BojfA2k`hcBKHjbDV)%joHgXGY^AQS=$T zeDSQPNn6c&`l@LI#M@ve8pF!WX4f%~3oA`#VF7E)M4o^{W^-HG3nS0MDYJzYmPGOq zS7xylPKzw0PfIH-iz8nq)6Z3`Fcx2e+ROCw6)TR#uSIEQwz28=+Qj1JI3F|HS}}qs zJ6{6tw1HmZyO^rOP{6gbTKo^kkpU=?tm2x_BTwjIadKs~w4q{=c5uq_O`te2sXXPRYXH_K#$Dp+E&3vF6W!O14O$R5T_+Q+b*-8{`u|P2<&&F*@x%e0m0)(wv2ZL zvf+8VP;U`$4qRd$A8uuMyycI2A0hQQ-bhqTO_TN}LS>JORsoq$;a?3e<1>WFebhR@ zSPd_7E*vu1^JWe~!PSYeAJ1u?y9SBy{)Ku#Tqr8fE3gsr_qwCrP#niR{&sts$0tZ} zuN)TBy+2?k!1kWynN)bwKodB zZM?S;wyie+*4lY3k*fCIsnG1;{fu;W^ge=4iMJcEck;#}RH?_`cJJ&>#Q!c{4d`_B z?nc;d$eS_Uy-$&z9^S1e+k?Ckxb^g|N2p$2eWa?l_ZIXI_HgrU`gk>9p|AHSLiO{W zLoA1QyP#R-9gngq_qrm+iv0P=yIGdr9>t1ELHYB6e$L`3(_`zbS^bCtNuCX)@rZ*w&o=SGooZw{;&FAK@> zypbq|i2QRKm%_V9wdBO0buGutq6-`e?*%czYh_dm`Q!NI=xP0-iY8c0#CG z96c6NCa)`g)6E+k|A~P=M=+CqAMyslq+f3jA}0N16e;6Ne-@F`PI`0el4jCxM){*H zoAjqpHAt~Z--=S>iR5fg%;n(0W1s4I?O`(F-HwFCygT8N;XQ!HlILBAK!x6F1T6E0 zqI8z!^P_df%WuUPBl#0h`X-uxC5qI<@~0x@CL@1444AxpPE(q~e16fyl;xky=$EAr zqY5+eG%^MYCOyZcou7HJDeZ4v@=W?KNDoYy^oESaEHmky?1AypPxcQY>HHWVwpjY% zsB>%?>683}y!4hVbA(S{=DU=cv zE6iwPyNDsU?HPZ zt*4;2yYOukSw^W9J}|A`K@#$tGm6%B(8B>?jA=2M%W&A5cTM45AU z2FI=o=w)-$kk8s`oq29T*OqFx)0v#1UVOcCH#NV7joPC#7|%U)_0v*{v#-`$xfGtI zEB~2Hj6O}x4#;SoGcq}l|BPNdh&_mZrY09e<~|o^)_!euA2soSFl$BHb3Koz&)2zd?M;fnv>`ae*eZ8^4D<8@*!@}y>xYu|&CzR0Uh z|CW%8u(xBti@g|1FmmCT+LPgRiDySwhr*YSQ)}Oaf0uc7c(4(N>#?_EwQTfi+fV}z znq|D3J$uQ1AD(QrwI4!Mw|MzYp~pF4UIA*K3*)zWH8;cm2*^X|#)onbc(pMFY4|;$ znRMg$=SAP%S&&bs+Y;2lOMW8wy{*f!XCn#|!M)touo3k}ApKEqq*ogCMtKz`y9~Z; zi;v6qB@#o3Qe_`IUF@zhSJ&ZZx5Tyt-^j9qTS!ve1n78nR_K`4#P9jMtE5 zUw6tpGtH~}4H8#(_O!VuU*DPi&@8#nGIRYS*lBV)Qn<)#z?NHgiaE)%9TG+Y1Cd!) zy1(?;W~@(d)xeZFS-bO@nZ9XZMfG%xEy;PlNE@4qVbALV3)MtX^Z=6myzOS7V0abt)~|8#Jl~dC zISApqVz=?UWaHs&BbVTtT9x?6A(MSN<*m;^Qfv|*wMje?I&)mmCv4CQAg-d*CRF#f zg3l537Kk^|>3sa#Zk?Xy5%#=d_*aweTEF95xtH;_!S1b}5uTTN8`G^eCVm6> zAnc~-GF{&c}SM=gZ%|0j%yNzU}jifh3Ug!Fj8_KYJCC zpi_*Xf#*!L5Yw5(h+>-{; zX*0x4*lkizu}OUe;!D``>chXfc#lHsp9?<>Kv^EoxOnHbWO;mppkH9G#|y^Xt}G9} zLy(T$MslK!qz%Mk?0K|NT_kf+8%M#EP8Oc!WyrZkf8}XwKW+d|= z&Zbj7;yr34o$i8o3w9gtL>q5SG?;Yk{g}Bf*vG?gMjS3v>hTp!j)c2lZ`2%qtO!;D zx<8Z0bX1qnpAp?i_}Nvm-uee&?-2HK-bmYgy%F^|9Wb&h2Py+#xdOXQ&={Mb;SdkU zZfZ?J$N@A|7rVEx$#_@<=*ys7k5iXDZF;%>Jc7NLc{tdg_<`68dp0{i4p5gO2s(TJijC_7dwq4u zjd&7qZK1m$m+`vGZ7NFFThEa}^Db~22!rL=n;!zoaJ?BseHF1VyV{b7ILW{}# zHy8iPX^7VCsEJqa&yWFYt2wj_v0Gb1anK!m1+rvX&|nS?JqM@9u;$+xDFTgv-JGQmUV`fj^jQsIAbis3!xb%jOX3aeIhR4;l;n35HbTfn-gCI$ z1%dZr^(Z_HVGIsNPaxA>9UZTvhZ-g6%KyS(o?Js*X+&IGiGO5@2 zd$_Th8~u)h;3%km8#r`_PyG%!;1D>w2M(e*XpbzYZtC}j8;8}6XX1btruy@7z*b*> zl@3fxj%wJxpJd)&gYXX|dkOQg8^Yx{Sc|>!GN|yfSidpq*+yN60~ziq1BzZa@K-vY>vA>=V$T zrCVFGs524L%h?yr3D`RbGn(%1qxN8*kot- z%Z}o_%xz`UQM1H5q=8Fn>jpy$@S+j|;dbV9?@X`3QXJQkicLXLymf5 z-=-4DEkF)3f;q13lAXpfPy*`2ynaRL*>Lbx8CP8>+6-7llp`{-!PB`CeP17BfkV#_Xw%1G)YMl1`7pH$MBQv?Fa&Dzd$?D6am@O`isHbN%xMWpOKt zEDdvKZo^rNGab{qBVxJBBiSx(b5e#c%Jg}fR&&3c2eF6Sb3+n3$lqQ5@$J53d0w8-Z)rZ z=TTbceGkzvEq;1jVoU_X9qjQ*Hc>Gu<3-TXu|Y$Si6J9!H0EghJNnq@0wn0z={TN# zd~|`gA$I&c9M4;5-50L(AguJx^Q?HDhuBBMBD%d{)^HB29X-(-Vcp=$gP4iM=VJj+ zV?>E*@YuM2cpMVJcM|@^Fqb$!Hg}`vji(#7_?h?@!<_i&*zEcEx8zJ4i89X|#aCJl zJPe5CD!SN`tRAWo*~#@r z#d7mdKE-YDucQma-hEUX31gj+gU(%o5q2pHM|c38{UXdm40-v8t5rMvEA0lcPd``v z)J8=kx>!~qI-50RY=2J%l4lEqY*BoGko$Ya?Jb09Q84c}6K{||Z=Z?Rt=%5ug}Mc- zR=%5s2PvZ%K}rm5{w#(RPsLD}K5v;9@7>66EWw<_4`9k>GsQEIhzPP7i5(#1{+@x5 zH4(CAUN9uGN&gJAayB5PtvWrbag$0OOyxC418?3EM=e_gjK*5^Q6Cr3&&64h+Z^3Y zbE~RzfvV%wbOXwN%Xl1jerPUPh(5oKdJ8449^C5H4p{yF7RX@N{!;VJ43!b^eK_ZtaeKmSZNPNysgqr+?zak7d*;whD<-b752Uf~QM0i3z6FUg9&6 zp3ME4B$CUUju`JOV$lo~P6n`HOo6?u=&??wEyx@L|WAy*?= zkX> z*`V*I?Pvk+sjmWBr_Wzssa3Z!rWN4m>GJc)SmTj-YPk$6vF-nqbt>y9@&c z+pu<9H;&m#x@nw-=GGh$#ju!RT&z_I{&ne*sHZsB)Wxt0Vq~moTl{O+8KE}92)jZ0 zxQ!3ZxN$(rjqQLNdopggW44<=232nb7pK=p{%pV8oMn50LS~tAEB0Y0_IX$)na?b^ zaoWmlyKvy{D$@KDV?=Ds%-HOmUhF+@Qv|L4k%(>MwndvX8jqPiv9d9-iBEgDGuVrD zSA1j@GYEK!Nn2u%O)QoXyT*IgLu-7^i@k;WgxGHHV?0oYw^<&s@E7^>=jKod_CKE( zV}8{B&#?b}-#+#@&;F0u|D4}MmhFEoUBe`W{a$j+lc`s8RDIE{qZHSG=I9 z`yrHow_yI1PP1oCp1pX+>`o`mnu<^5F6iWzrFNQGHD_9<%GrxL@dNqOXU*u;ziR5V zPGc8Lo8M{1?5fF?vq$5X4Jv0$>$G6jjLB6C7nIDKU$vmqthxB=`Rv)9D0Ey{RW*Cc z%*t7FJL2Pvi#cJPWE*W-o%tIh9jp^4pF7|HZiA)4Gi$+=|HlTZ2}rxu zIEUIoFhPH<{nr{ndpr(gaO$iD^JZ6`OsD^&ygCCUf4qR?4+}W=|D#0m!^?|l>HmK5 zF_Z$5*3$n`T3AZ7v|!;>w7&mWOjTE2fhbJyhhqai=*}2c=S9E+ z!&rEz+X}ejNdVj{=g+S^8HO=Dx6-uA|BJdefsdoO)pp6bgC|}<&4S=B-iLpEF_P%W(vD6N7 zN5^mv2%{9$u!_MLi?{6D-a9;Nd!M;-;ZT*uB5wj>r!Vy;%tZQfZ#pQ* z(Nd<*^0LZ6h2lwXeMBLlTggbUAY_V`ob;-Jp-82sLyVuS6Ej)mYHwPk$jhCjMdn3{ z$Lo^>vY4xx#)%9sG7{HSXj%$}>f%V!Q&rxm(2B)gPH0y$32j58lE`+N;n)8wz5EJq zR2kOzS;ARfZk0C^r=dszL(M4*8$!C=$T)8Wil7q6Bsb~h;ViMl%bUPF zBFe>g9V$?-F6*^Osp1hu=0F{X29;NaN|@y-Si|!|iKJIHcGe=;>fa*CNL4d)~1B4WNsLiYjZz_tfmU>yxGPDQUM=FY$2klYjl|@t~ZR!<8RGAl_;1wmS zy!b4yl8Mj^R%ujTEs?FZ%$va^@k(8T3f8YPEd0*`jwtd@g|8jx<#Tjh106zMw?@i zH;(lM@fkXO+Hz2*qGU#O-kTO%nGyS-A6o<~7ImP9Q= ziBPH}nrG2UFKelkH!0Om<1Wom7_0Hth^#rZz))I|pG(E(>e`v;ogzlek~UN6>0yVX z3fh`5VF2|il3o@==XyDy(8RR)D|JuK*L;(t;Z}JipxGL8BcWc5M4|jj5ARf^_l7r) ztBY2GjsO2$CGOKB3VMZ#VDyPkVk0xdJ5=9`Y6``aR~}IeU*e7ANmjKtk`2DhTufrP zEU=MMQ*9X9v(npOKzb$zOI#gtVG;}tUj9n20ODribV8L^G|L+iS*0UJM?#58j_;vw zpo@(TJ$`XzB($><*9m2=C>y=ek*ZPPD2Rj>qk=IqE3Y6lTv-Vjp*rPFrOb`qC}y7o zbFDW8At+32C0Y{CR(TZ~=XjHW`4qJT0>Oeo9wpRTRx_&7tD%_1-e#%~o-G>5v9t(s z3%sI}ypuwElla^jgZLD0WaxYfD)-PHl4fYrl1F+oC}=w3s*8%eF(fFZIDyv zXCr#}Vq{%_AqVZPFtSLKvzee$+iWs(3guOrEWujNfC$^7{7+&K7^SO%Rk8pq zOoQaH$WmQ&J$#ta5``{;0(}RlF|0lUbrjkSo1c$Xt3zOfTu^$X9O328Ktmpp)V->C zLwm!9hBa;NO=~vPHaFGRwl%cZwl>r{n9eL{A9jYepWh7t+p305?X6AASG18ZX;!ps zXlQNczf@R#YwhXnt81Iqv@dH|-n2$fhRkP>m=tvnVD<)g0GuI7AZ`%{yY(ji5ZkhB zWqV_D?eg|@b*(MU&F!mORztV-tEtW0InbkX=V1F#&-Sgu?Y-SwwOU4##^&|wROwIW2CeQlJtj*E0v39x}aJsf{+Ya9ZLj&EN?erhu zboXlQ+G&WCe4`X! zKkM2)*xfn2y}!?~GtG9sf*SAy*xtFtq31mKPUt+heW0VuInJGZRm#4Voz$kjskJ?= zmX<^B^{ox50yVd+S>C?3wPD@5hWb=!YfD>g>!uW4x1y=JzP%1bXak$JRlD&Hg!}v6 zu0hxp_x`XX?)6hTwC@~%+sp17hN_HE8)*EuM$n3eBx z+96EO&KcFyzndCmw3XUr&4J?7Ha7=u|LglZce05MRc&b4Xz$4#SQxDcEup_}TM{}k z)BfJxc2tIAJX_$FMrWO>6sWJK>)ZRpr5t2oX%J_mimTfM|(&^C!tV%R|BC`iOz+{XWDvQOLI$Wdt*!M>e{yUx)rr+ zmZL6)wEx0Rl)@NQn@vPFH#D}PBX8^L?n+{FF2(4xZcHg}YYxa>RXDN<)8i3N}xgz&A5&V=8}GSAAx~44RI9r?lx1 zXos^vmu0T3*=4nLtJbZpt<%kuJ+ZB2tscl|svtAJH#>nH7#obT}7&qS#ryY3NC*Nm7{7h^gG4w$lI5Tq`iEsu==zlXKQcA zwjo+$dsq7&Mxz@C^F}cn8rHNox75}{JH+dnHC{g*dW}L-8*COPw)brxCReH*2sg}= zG5D|>;)=JTMPCSMV-7&R85>*b*2}ocgmp07y7q?prZx^*xbm)OXl>G$5!;H)up(DT z+Q_eE%fU8l#$SC^O1|9q^+?Ub>-Lq z)5-#q7=LiW%t2p-O|Ng;w6*~ubuE}Z=&=*m*B#q+6S3FCpy8XAuW4y*Xg5PPCQew$ zOjR=s-_pFkt*K>=f91eR@Nf?o_|od45gnziY0Yx9lkSeRnBY)uCl!9JbG$&()7v*R zt!v^HSznii96dc~=jF-o6wM8_8yd{T*B{||6^6NjjU1!HQ2(I5BFQ)~)Ymb9E*_-x zptQEORbLSr>Nq(;J{){kUU-KIH2vUYUO$0T6ea1XistD>%(v|_JlLcdt! zVClNEyQjami@gI^O}{vt5jL2~=TZ82V{P-g22=*-hkc#h8IwsftHK1JK@>O5Ue7Tb zHnz3vcA>9w!FtxCvYqw#6|ini?b@|E)Gss(Y(~OBds?=>t*u4R&Qk;N0NilxuvgOU zeKLgWdADK0928RJ9FK}1l`}IFfSTh(%AZa7mN5+`WvLD8Hm#{kv#rcV+n23hCbKvW zq03sJ;_5U;X?qR4@-%4~y3%XcY|;~FcuDPT$BYgIp;s_m|Aq%UFn1bCp98e4=df!p zR6&~>!;2bz$#`R64CtF#C)Q?8AB3HubGHvL*S_=#)H?KNQ;&L#)%mP5ozov={l>?! zJ<#l-pe`k9uc@xK&0J$lW7l^{%W7Lw)xs9uiKl7fJ6nv z=*wsyC>i)we?&1HqP7IsQG)mX4urV~JF%b(jTUUM|-xUs&)43lq7uxP?lSD;2J9 zYnhpD%ec+JQ`T+4;vUi^BNB&K_ZZo_!C%?Ht4czM; zar0MKyQU5|CEzv9udQMAI*bXZGP^Jk=<#VoxL;_o`1&=eX_u|G)C6X0{~(@^__Hi~ zS>*jl`t(r`h^9^h6-R^kvv;fPsx>XkQdJUY60$^q^!Q3tKha9DndJ;~U4o#1MPaP9 zwf;4wzUB0k3D?y*sXIZxl^k&y(^ZzU5 zn(#h4HH1!nhtTcIbOw73V2!T9^@4mnhx`q^TOJ(NcejvbE`lAHx9m!n*4W&z5#>el z)7#rxaleu>imY^S%_5k;ZY`Ki2U$}i3g<7|`}%N=#ESy`dI>_hAi7if*vl5mc{A_E zx9r7O!n>l*{{F!(J#+Fc+RiPyd8z1h$$_{MO(>*AY0mw0Gng(N^SZ~$u$0l8SkNiAOagA7-$WCkZ; zZJSu=)P1oDHY-6KH!&?34C=@=G!D)Brd(fuQ$=iD2WvqGHVoeMm@AWHgj-=hpMaib zI)eb;oPldh>Q2EgzufN!H1->wp2W|Uc9quaX>hx0;Y&h8WV;FUrK8?`nzh26c=M#4 zlj&6Rv+WGF=sJ`B3TBLw>jH1F zx9sf2>H!6@Gp%2n61lpz6?eE?v1!m#WUH}nBmZipr=CIO{QEf8o|!lC8p7oO%yM;` zwW|-vn0-Sp-uUKhMV__1m2{TZ)h$d;tsUHvhFMS)8(wqwt`Ti zpe(*77No-&bOf}0XAP%1pZdJ;ezp9YR6i{(%Mz5u*W-h9O$N<30nDc^IKjbp*?Y|-alLBpE{(5x~hi~8AmWAj15DB(RgGRB=M4nc~j5^hV*-g zmg4(sv~cRcCSc~vTm-Qlx}YbeqH*SFo4@ae@xAcWfsJ@l1kOTub0gRmQg0p_wh-PQ zNtd7P%s>=N(Ttyqc&4w%&m649)DcRnQRbK4m+*CYiWz4iyc&|8U%r-~>MwY8Byfb% zb_Hkp!i@6pgQwIHLeEQ=pOQ?jkpD)eNfW|nm+AJw2U>w6Z@M-ic;ZYCnUYG3 zvyd|_gPxutZ+b@j%nW%mGvX^V=&B5PRT=TKGvv+Ah@YE5&&!ZEFC%__hP?S1@h4}{ z3o_&_$cSHIkLnrcHY;&X8x{1U6|x*o`E;K9*|!RIS=Ke=UDaDl?pgoZ1Ze zwHfhs8S?8g;u|vP#teCl8SyJJAzy*-0I zH-kPWgWi!=1DubX5#S)bHG>|=pfAs$@64dTl0pA4gMJG%tAq2LLR_yxe%+WI9pGxl zKd29Vrt@H*EWoU78E6J^epiU=(dj~Sf>em>34M+;o;6X3>%lc7cxzKEvg&1E>7Ml7O zI#^#6npgTlXNA)xbd9E)oxMVHdG=ALU?O- z#Oh{Rxc_7@n4asaL9_5))W6*e-UIrJRe{t;tcD>jW37QKX5lZju93Rm&5#u^T1HIz zdbPZD65!!-+7W7}799h5^KBlzU>ZoRS5Y%x@kv{u3oxf%{Rsr7mQ)a!ahHq`bI(kP zdND0MB>h1$;?fqpe4454lTGG8+J7=~jS4`R&9E@f?5sa64^AIJ5G@D?#u;IL9i=D+l`Vb~=lA-aGr@3qbHdIFIQ|4Ei*U z$OG|7fS+zT194=AuQtJcdh->#=A(*!`qNW8huev_I?mlhw1-2)+pysu5$&M_7d6V`7Cw|$ zLHwlSYzDGkyTCX8I%A^oAH`N*q|q*TOF#Yqb~hqkkNP7rGaS=93|c$5cbIx~aa&6J zyPeW*Fm2)W+3hoTxbBcCFL5Npfh@Oso~ciF5W5;mc(ve3f^~u`1UCqNNN|hbfZ$HS z%LK0ygb8%MFoDMV1phT}%O@iwM&k)=y$oUBQcMD=CcugM=yhD(CUX$-D zg4|D$^s|C53I0j&eL-%ENIq_BNSrP>U$8~+EWz!9y96&2JRo?7;AaKDBKS?gX9Zst zd_(YGf_WIjwLXG#1hK7-4sRCRB*@(c$-h%@zaaMpWcX(UxiKK=#{~aV@F#-55qwi{ zJO(QAb4PUIg@Ts}UM=`B!J7p?DR`IQy@Fp5d{Xc^!9NSWBlzEfT&iQf{M?n8BUmWN z&tn5AuLBTzO7YXhc{D|NI z!H)~xE_k=#LBTHwJ|y@bf`zHbAm4jz9jgHARRWad~XW=Rq%a5?gz+ty*D5* zPv~O7F@i}!ZWc)XnSyf!7YHsDtQTAf1ZxGC3$7MiC)g`ED7Z)PBEkKF z*9hJx_<-Oef=>#5SMYg3`bwuhuL}NIklPMi#$PS?F(Sss`-uJ6{8sQw692f+PYQlp!harv>1f~OK8XOrNN;59_(cYuidg8PV&_j$oDN&I6%9~S(+ z;Io21AtL>siIDdfBJMxv`;_t$f+L8CpCI%^!D_*If^?z5^z;!*{xgZK@FXPhdjv0( z_$!6JM(}zGr;ki`HTLV3@COASk@&9*{cXYTN%)V2eo^ox34cxKKMKA@g#1{c(KC;@ z9Q~h&a?cQ~miUE2FBPPJ7M5?d(5DG*AVLm(-ZFjFYz}E-X`()2z^lS3ldIW zvo7v8pOx?*3;s;vUlE#KXQ=O=CHyZ$+_&Zwnec?*2qN^EAoN7RsS-X%==p++h>){R z;x`iKVvlVi^4lr6U+^ly>xe_xS6b*#3f?K<_X~bm!v90?3F2IAn=SYU;t=K^#7fi? zZs?hBu3#Y%@ufm11?dZf;Z;J<6{Jr(hA$JkQINitD8EzUdx+B<=Mss(T<{|jf0NL+ z2;L##_X_jYOw{3gNkh>*XFi1n5mg}#G`{O%H@FC_9E68a&*|B&z}h`0%VLBjt_ z@O8mI3BFB)ocD$14LtL~_xC#eI3nVw5MhJ)Le~(%S1-6u@N~hmh~VEr#C3R|&^Hr1 z;LDtd^!E!sEcmG4*9E^V_!1H6enUJDetsqVJwY|f$ioMuT5dKGd?iAc3QiK7COAiM zzTl}uq-z#>t>7jJ-zxMuf3ceutN5OXm zBPE6}U$8`Qrr=3}+&rD~mJ6;YqI_G3u>V%Ue!(HZJw&9tMDQbmHwxY>cu4S3!EXru zRPc4dzY@_7LZg9bPg#NmTz|p!f3n~z!G9BcS@0BP_~>ep{5u5q3-UP;!}&aj*X8#F zr@MyUNW}H@0>OI(|C4w+Hn7tZB1we4Q;E>Onuv0u3Uv8vh_KfRBJ8`C2>Wj&f@w1m_0~f~y$%qUJI)>= z+QU8~+RIf$w4(z=w7Xk~&_7pjwqT2PlUeD6QS>mMCeNo6V&HE)<2Zj z>kZIHuOC34Pp0SY&kv~IMOGvnhFD!_F7A_W+aT`T$#vi-*V z1gam&d$aPX-=%q(bFBf3G<=6d1c`Q?Ki-9d}*ml zKXyN+uoT}BHuK+(IG&MGOee5PI^$6@({EjzC^N(KKgjGv(pY-`MV9}8+0%J53y^vf zfW+*8(xCh+V51F^NuZBxc^Qd7N2MF`&Lc>a7h*}JrJb@4fbt2f=zGpB1xc=gI#2I z=$(85qPF6bV(dT4Zp7_$wr|-vj8EeK7spueVmf2C!UoRENXs}LW%%(Nw_N%-7T*-a zVw!qFzM0^mygB&spuDg?GyfRJ--Uvhe(D3$KK;FdkbW9W-?&$#o})7EmQHiO(T8(P zt2H0>qH!qK#gE5g5`n{#pF$YU2QHO3@-aPS@vyqyhVx*)Pa)p~!k91l$wzz>Kgzb{ z;GDD>v^}i6Zy_Kk?*+)?{G0MHP50&f7Uz^_%fUHn@UUb7PVncKgM8G7vUu2ha}gfQ z_su{#FxB_-J=@6h%W(^6>SqrtkMD8>;@9EV5*4ojYI`22E^ zkLf9khs}2v!h`viAYWS_g~G>l-!k(2ay$YW%Uk|o?aDcSP~KF?V|vy{F@Clj_FY+< z?ir*D9+rFsC;0Qr@k0=lM_D{BH(b8+<|iY6ALkOd%iBT_^e4cK;^i;a18&tUe#gkheA< zZydO-yvszMO~-eLgNH50gNDy92l=QEW$~aq9uFWqSdPtse3OW``DTUE?c65vD1!$` zef%;*-T>q=U$&QW{H(lxf{(h|bZ6NUgz>QDm}K(x%RxTME7x49a+HBDSdKk`a!dlR z&6jIylx^#S?_3A_uT_KZ5(VX56(|SCcq^|*B@zZ~RaIVg(<kpSm@ zImpLyP!o@16A@_3af{*e%RxTMqbwej$KxiP1k3SMSE?NLn$2`SG4lL&^)lpH8I)tycv|=@ z{fa#y6Ar82yN1u#k9^E$zUE5FehYj-{a)xw>9+v9h}P*UaN!Qx`Hzri+YUuqHO2^^ zrQfzEWWr(fTW0ut{oVl|^;@X9Qu-|gUr@i-0{XGNTKztjq2K$EH&tX2$j5{4s0HP{ z2YJkw?O-W>R^H_z&#GU6_8mNIIlf@{{Bn?w@+gak&G)kz`8wSxJJ$*y)4ebGTHDTq zyb21E!|L;VhP(vi*>co@*OudLk!RDbJw`dkB14qPF9-Q3kFt2!a*P6B(0(Pz*N!iZ z!pC%6yQhr+`q&70cFx2At51#aS$fMc^rH*jpnhGV-wGq%*RKbBLH(u%^jisDYnR6* zUw}S(A+JWx309w*GUP1?*qQTBEAK&(XVcw(jB@;!;q&cGKHAI9Wv!iG$jG-QP>z;B zzI?|pXy=C@&$d0V`Q=dH3)*FEpd6&DOOw=qNB4>1{8lxL--@@mVF zx8MTve2wz91>|*!ylN2E?k`tjGF!S{`Ij?-wFgok_=WayWJPR4r%d$1fl z_GIYy6!c4ikNTa9pDpjz;6t?!Fb$9Q*Q31VRR6c4iMFpXVgWkP%c!7!obSeu@_3zK zodueaQ?eOr6oCLMuONf(H7sP@3SI1B`Q&*J_VTIhtn9B!&OUkGyt&o0Po6(FnVel+ zT^;y8f8M-ga?b48^AU(+bN0p9p4GZ$rCfy>gOyAA5HA>5vfw<8vx&J_ZTaAD|9XPd zp+krE1EcXi1=28F#m zbW^Vk4a;pAeWMP_dJ2-Wquv^1mJEB?vB&ZD;yhGR#5V3-1zkePqBT5!9D0T-iaU7T z02M+ri-vjrUue9c>f$SLUKY-dhQA0tZw>y1Pb+wu44kQiH;sXV4JV&HV5T?wZR&L^ zH1Xz?zRgDMKEM*pP22+_?3Q8t^yZEE7KB9I+raCcH1fM3a$JRCdkb@3L6U^a*Jiz? z`IjP1v3nBPPAz%}Y!&W%6kU^GHdCXOEOu?)VWd%ORkRqr)LUlA(^PZ-MfBb}8%^vPDmsCcv)qtps_1phb%i0%f}0qAW)wcNkQsY> zdA=o?kIakzh4cKcAhaSf;V=SRzNZ>ViY1y*_(*w97OEla-iG>#Ow>fwZ9xS`Cg+qQ z##kb9l2~F1+2$91G)hZEP@>4mxwL(W8$tmh3p7z0ZAVb#l)M)J@I4Zp34J3A4e6@r zGmsluq{&2BMel-^k;R%+cwp}R3Au;6N}q> zVO?3>V9lC1dMv^c?vK$Pvnoa}22rf5F>9(;z9jxDRAbik+=EE3UXK5s5@s0cSMgg> zmaLhE`gMFY?37h$sNXo=n`jK-zS6UyMgEPbZ6?kyW%@OLyFzP$D`}6JfUw zc|&PiA=~I=O(ftu5yX_jKhd1=(Xdi$>)xIj%a)RXa3kZV*_ z|GMKHfLX%BV>uNprY8BD@NZ-6f?Aj^cNaGHj$J5PeG#0oi%P~Zft!sSVi%8J3L@&Z z!tAk2O7?-sala2mVwaY7fk?OuP^{QxW9|o0>@I|bWBW_51yQ0)61!ZBE_MHb!o{u_ z^&aXY>AnjEVpr>5qXb2pK=R=0u$ zF27%hU8jk~E|>g!cYlfsjopy-Pw2M7-3XJ#Zq_ktqYCzlecV{@ zPB+@f;(fx9ce&B;QT#22yxWcPE%Vr|hWre+7kU!4AHFlW8ph1O5BWv2$6k+f_idOj zyR_s7D3BAs3?bR$bao}lI6q9v9d&zrCoMspvB zoxP-P!;brD=;W0Zo{Un2-G^WduY3ewZ;HChk)KzQSOPO7-5%)RO%~JM1Vy|lV%pE4 z6yCJF!w9R6mLN-Sx+dHMD!QC;GYolyimoR)(~$5V`9rAd&C+D}<0|?pRP-uMEXKq! z*TMwh237hY=$!u-=v*A1_&Ms|gnk^a$p3T{S-QO7#3$)8hu!ZWBtBUaQFjM;<5M(| z<9-w+i%-iQg)|Ar+l;83(t?9vFU-lA@HoDdMAXTm z3LZab$(b1X3eWFgYuHp2MrpEQ_&4@xh-Jlu_|M6D1Fh1lW83aXOe0ez{w3HMLa!h` zM0Ur!hYa0`m1JlkLpvGtKh2QE{^mW3z*tXWfLuGt#crgz9Ph8Fuh_Xd&Kt$1)mL;2 z`R>3!trI(z@cx`F@jT627>y0Tg_ztuvz^$^+=r-5?p~bl(&ujOo;glzw>}T&?#1~Y zeI7wWLBope4LyRy^C$C?{evYsa|3ZSD$_!Z}S`e~ZnU*wyUs&!@x^G6E zF%Lq!yuB)PA6SZ+GK*J+tZX!y1g~QuUgJZ&wmVt;7A(O_mtyACE(*`WX?}Sg zM`!hI)RvIrncEVT^bQFSF-iQ;EK+3FKe zKCZ?{HZNQE0gOM#wa^3^`6$A?Pqe{S%xs)hCeeEcH{! zsZ<9cp-No~ovRf$6q&7FMdO;IK0w*$s@risPyGTqoTPq+RP)te(AG~@-@^X|DgtYt zqHaQ}g^C{`EK(ODe6iYv(k)THK*&@CcgEjFUFLt-PVAP;Q8KBG*9!q`|z2rNjbAIKvR(sOq?SWO;e@<*XqpcEbJWQQS4w|TFY!gA@@7J!dXHMEC!noT zGa%7bZ^OJH#jh#DstnD;Q&@CBEtF10>5C_F{3v}9mK%}e>7rF^8P%bW8g3!8F~v(R$OwH1$&0t&;DQHI!$su_-nWlx!g*;aN1tl)3& zTHX+Qi!*8pjM0q~bT-u8?X9Tr0&MBxbWdS6>~v%+*yVK3qZw!6Hx0iMvaf{+!)k2| zZr+V2^{_gPgmGpL;dg^+Gkzlc0V{m-GzwpdUn71HzIi@{Z^N$>KP{Z?=D5Olp)+Br z2j<34-OhrH<{j($MJ)7w1n$F67iN764RSBYJMfFKM6?dST0|CjK^TgwIZg>BQI6zm z%7M60_G_WAYIUPeA^ve!BN{fRULLObVAu^ zJTa6>=lxh3KRC$Uqny|UU|@lNmd0QUd?{k7*c+)>+!-N|15Q4wFVzZsk>hVcJclVi zE|i^zDx1b{$5plNV&Kq^*46E!xja%mjrG40OnmoeI=hiFD<)iMfSOJWX&rXgt4yXw zK@>gJhn(@KGu_cm#vs>#`yTAm`#_VSG{ilz3Co0tAFSrwLcOaFgSfTvUSbd1QbA z1GP?wrka)S#LL2DjRr;J#?QqF8(X0+R2LU1#Aa7G@%Yks2pYyS7?E2}r8;%AC{Pxe zGJ5f7rpX0kG^kXb&J}|5i&Q8t9@lYYQSv56s3|&8fyYE;$`r*N^_69K<)yGlS?(CQ zi{KKqEGv$(8u1J(o~%neLTgu+x5%@m7%9q?#TYhabW@R0Z&W3eFgcawP8nUG3L`Zo z=W8WOSnx~L=!+qDG!zmxQcm@XRPEXIr7>i){R21XpUN| z--^NfNylgioP{L-HLH(?(Ya4Eq4*J}XIK|Y=3r561J6Z8&XaJlHt7G|7ztLSw8D8c=3nlLz2wRL-McYF7qf!_W>SOC81 z@dy7~c+vL=LB|PZD!LP^8rm%~y0#C&!O~t*$54Rc{s+;bC(5>?zfXiqSpOE(8k_=2 zs1>NU3S`&`6#m~yK8iu$ZwoKa4^<7pQ=QQQ?*5L$w|xiN6<(VjhIh~-&1k=b!# z{Rc_Gr+IAkbcN8N-Jrlp)KFy)?f@Np)c{XC!yquR<35EFg-!#C8z#bS>Mpqb0SCI1 zgqa;PQ!yA^5My>z%nUV~IHp34d^wL!ALLNCvfFXr|*W%Tk0veaju3(;w7tAZCbT$ z>8dYmTeWl>WNfO$Cy{Va?5pu(og>`NGb#K;dy|q$I6PPIFYL`)3D%+Eer~AR-`PE+ zJ!Ylc&-nf)#IuEQ*Wriyj$h!o#kiizaD|~=)c8Kv#8~j00>`G>hY5XaG_9^(-eBC4 z(F+Is5U+vbUwld!a5)J3x3ig`df_kyr`vkrQ8s9Ncthzt!cpahG@nz*%U93107>~B z^COOQNv1u_Xum?pkBXQNEsWnu-xSsjoKelF*|{auStouX;yHrBz6F-E#KI`pYy zJK^+89rT*%%aKOxh&n+ke6 zJGQ45l#F#@zD$HU=|fq6yM%912H?Mi{w@RNKZ^fDzYug)lkOnK*Zv5%hJGTtHh*v(>vBlSO;7)?QD|hifVKy}o4MO`a)yx*w)AgNSo2q&%_@Y5zI! z7ejAa>Gdqmu}u>dE$G%W%^#$n4}BU1UBuc>7j)X}tDfl~C*>G0&0!EcI0l_OckLWB z^#@h8<1Y+F1KJbZV7F;C1O4!R9dJM!bWh8MphpJ#F`(Xz*|v@DzAhOpFukyjO?`c3 zR1=>~eyvMzz*n=)WJ~w?+q(zn!VmW#{h~sUpD5*)(Ol)w`ciYbqdTGwxXOhyC~V0L zPe4K4QtpXRk$yy`Z*J?2*Vn{%+8pR3TecZ9XycfRvsVAehU0r08t&NMo65ER*v=Eh zTyPo%Phx4_#>E98^niQqKI1qt&96FQG)wGV6Iqh56Z;8Q%vLnsC zlNpEMCerr+ovu_skRCN`OAcQ7y7$0~JQ^4)m~B5e=Al`NhgAAAw;b9ZbhjgF9p6`W zz}?s8vnT&>%*dUXRlLD$tbYvH986!ZuGfP?#ouf&$oGhDYm-+!f7JAwkN9mo z!rAPxo34M6@cpkL2iqZKzXINuZRzMdH?j=%V5!AL06jOzVQ@u7$m^eS|+|rJ2+uN-tK)NbT`{$ehiX%@` z4RAW%!72_+6wEBhxG=4Ec**XCclH7FH-5%?^pU_H0RnqT=_{7M?9i6xOwspK=&LDyXhElD89`SB{-|Te1+wWYXUb;AyQSUQK3GfAx@MRAQuD7rhh!%wPiDgHri4&A%_hh7Z0=h} z{3He~tb^t`$608qLh~q((G`FxtA4Fm5t&lhV+Z=07#vEv!|BZm*4TI5If!>#9c? zQ*&t-96y6~NBCbo_Eo{30h$htwUPE6yuIg4L^s9Mq&naS87)TNXY3yA81S18E5{D8 zs4z2<+dDzFB{QV?<7>d;b?ddmQ@;eu8?=-6#&+!xT@s2PR4ZoK+!3?!r1}iIfst#f zXkD69R^MEDN+TD0JC4d#Bj^y_6alMeX-z9Q1x~d@-7&S_?^^hfuh(lD;)BNAoBNmA zek>Rp_rG*ruCry2lC`z8td8Td7xS;R=}vZ~#7FqQ*0-I!SPrNA15SC7x7T8f1H0vB zEu&z1rNLhi@_U)weauNy+P`Fo8*kLApP*?uE(s0oCY^3MgM%G=gEi(iNdM+jDjM}{ z>Z2P=tLED7w--H&g;!+becd)1t`$NwR_pt^yOO%j^<`oR4W^50U<2v?+f)AD&A93} z7Y>lANrm6wb<5eKXBoaGfgw-4Q2SA7PHO$oW4H|0O**}Wq9}N5(A$Lz0$s`Kg$2xj zFk(Aml2oM`HADm5MKbMtr1xKGKS%d$ZWe#IM3TxRsCp{YR6l96#G^fm`^619UH*T@ zy)B`$_Sj{5L$|A-Yws>{_hb6NK<>E@18;_Tgq`xCh@)+T59ma$Sw3as8DFiNkTV^R zfb}uk!1y@^r`w?%;SmI7&okHC?33^o6liz8@Yx|3d>q}g7qH&}PZ57<3(a0K+4x|P zqeJ#$vlmzP633|_jqiCIiKjZ+18z0~yGYlXk7^mehcwb(BzzwsF2mj-#5&pc6;E~V z1nt&4&OJmbjbl3AbJ7R&i{d1^!Hg~APd35R?GTH29xjv#6DLSHF~BpOi=h!&I4%mo z@)3D8AaYc9r<-!R7$W(KD#K}FBC{f*=o(iFwg`SmaEsu8;7-BI1g{e07)g0|2;L|7 zu;7z|-xqvQ@O8mI3;wrY1Y->46$(xeoGGaH>qdN|(CY*@3+ny55zjreDCcTH?%hTD zUcoO5eoK&J9pir^s6R&q{ejR4jBSiB6`UqGU$9P)@4S&ke}0$??u7i3jRe97d#!W{iT6#jL=gB=L^;gt`lq*)c(U+++! z_KybC{?UNiKN|3x60iNEf!6z*1OFi5?+JPsTPUYkaH630lZJ5aal`mEf@cWoebEuF z{iFdelkgh^KPAXLW0?Lcg5MN;R`4akKM3**1M+(q8?;`669wl8)(V~`c(&j%4-0-@@MnU568yX1cuc#gjlf|m$hC-`|mekw!$e+hCg3ex=KlBoTB z0WTB!QUKP_M_rumes{b>QUKP{m4rv=<3@$G`$g69gJ zC%9YiLcz-fuNM56;LU=c6ue9DUct``J}CI8;1h!168xUvvw}Yr{Dt6e1YZ|?L-1X} ze+crca+W_!FjufhQ163|_z6N!5}YA8TTt(l4!$KqYyVxKn}lu=)cdF-{7j)c1h)xl zKVFC*5_+%T#e$a$UL$zD;3ov{5d4hbeS!}NJ}k(O&RFgz1)mapPVl#a+P@e06y^-% zPYCLl#z8L;`dq>D1kV?|Oz>L4n*~25$nQ)j_mJRs1ivr%yx@z1zZBH|!I16`Lcb;W zH^F}idO1dZj$o1C7{M~Zse)C4^94^8)c(e1!Y`B1X9#u*_6qJ4yh!j$!2^P~3f?XF zIl+eoe=Yc$;GYG#XFlzOx9m0I1zC;7f@1`ef|CVj2`&(9CSrbfn$X;df^shuyixEA zg3k-SF8G1q2;9CiUA17N;8}u$f>#OND)^8fKT2f!mj(YS_zxoLt{7kRxKlBo6V(31 zKu;68k_f(aM9A4l#5LeNiQg%Bso)iY*AT&Xh=_C#6ERQxrqIt2kNoJxe8DkA2iD~L$nEU5jCf&P%tTZrKA6?#DMG9uFRBTnKM1)mmtg$UdKUT6<< zbMhqxmkFLO*eiIu;NybYzZb4eKNtEQg9U!_U{qAoCrG}6#NMhdi+zcg7ZbttB4TRFNh*I?qsuWKzUqK zV0%as!3R}!x@sci!*n`dt_qP4UsY&6+zMzuh|+umoZmp+c-*o=DXY(F}6?|;m!0xZYND1$AyLpN{#tv`mN?+72{I7%kCE%w(H%({f$`#LiZ z-luC5>SwWd-~QN{9l?71T#w40nSF3E<~UiWu^m6#bk-AXORkNmmt6uoga04AEjd?N zF+}Kf4S?>4M0+rfM;U%R$8DBA*k6N(<(q=QD1Im6TMr(l;kd+u@-S5R2W~UuI9F)bw zmg7a72lIU|P>vkoW4g%@94rUNUtS~ZVdar2C@+dNE%MPWn2Px2C>43O{9RU%AoJqE zHD&zyCa+j0C^UHxGsbt6vVCb%RxSt!?p!mjv3$!=KFFWUydm@-wl%Q z9LcLjvI z40%zkt!~DAgzX@SpOtq*hP+5I)`Spd4=eAU48G5xQiIPyEZ?0O`SvtoP7YzrcOrf^ z-$yd!O-5mB5N{7F@1YENhar!$_?v{EmG`|2dGwRWG1eYd-gh$Oy$N|!!9;l+Rh9rUUmhQ1=vM>%)*_tpF-`ULOF$m}1`wo==-mI=9+&mt<6L<* zQc))JP2k7240-t(CvW55+UxPqz9)SO_l?;5GHP~`e1fS-Cmv>+oW}2M z!OoYmYh+XqJ5_dY|HzcQgZpN^{${P$c=!-^rVKYu)q7EHZ;W8iNrpuA?wHZfw!Gua zHX-LUM(?YZoi)jk)fj%On7eU)@auE#{6kiBUFjJ=tZO`@Zp9NH%o$NQrQ9hq>3;OO zH>c&Dn%NZx4u45a^=^nhaqthGSALGF8dtxl@sTIgM71dEh8gvR<;lj#jp3Uqv8a4s zW5ofcGBOh7S!pz5JcJY=4f(^jRUEkc4^cOKL*%xF^^qIA+gitZH)P%B)>j55C0ObhA*Ef)Q(?mFH3hsduDl#Su$+!bw*z9qdP|-?U zp1lId4Vyhq6Rvl65<#5T6vIp+ z>J1?96xri+GIO+hoR;BS_BbuZY{Zj2PTMg0c(TXouP5T%>~Xp<>|wU)M1C@gBWNNT zj*Y=q6nZ11toeCGNTkl-JWt(#|M<4^D-fBrF!Xl>c{8!lkhN({HJD2I3~uyK5HK@3 zdmP3_w*bb7&MBquYRCQZ2oQ4Nkm8IjiEQ|sJjuRiJmkv3q+3l6bulx+o67@ z48+p>52I|wE|(&srxtw{(kk4WDWE37Y^KKY5g)D1J4_wds@P;Q`rDz#wxAlKbtbk| z#kS*0AFVg!Iu-jv1Z0CIu^npcN(}T-e>>FJe5UocLyd7YJ-WiA<#wpAqiV8bJJegE zI6tfK1zKexERl7#-fht13S`!1bN+8wWy{)?p?TQ#q5@;UqFM3 z$(E_HIhbC>{4G;sx1kI%f6LSucjt}yTc*Y~m4ggynfhy%va56~6i!|_1x1|!`(^c% z&P2fIS1PcOmfiSOmgei25M(!v;PV*lKMA4P&AJ}L?g0d4w~V?Al8W6zOuVx<>6jAt zEtog^Y)wpcFG2ybw~qV;V1aHt**%572C>*3iF~uSYof+I1M;)a$({$H^}6w7pR0HG zTj6-OK##0*l6(}Id<=&6X!5MS(ia%e1v7ek(DJf|$Nm`srN6+x(VHN8WBh_eut}V+ zcE|1Rru8UJ{Gt**CJMWyP$Pcv_$xp}-Fsl}_$4Jzfyi;kLSX#T()&Rq+2-;mV+^RIAMGL7tR8v8AJ zW8B}}G`1hzA@1*P8v8b?HSX_j8tXz+hzE8zy&Yn+?o2L+F_S;Rxpyj(XC18Ah=9?5 zLiNv!PKYCo%k7+^$%6OvII$D`C0bVaJID^Zzd%QdmXF|San${H##AKcqwGnS54xjv zd(vhMOi{Z%X*-7#*`74^8CW&yZ%-P#iE;k+q_Mk6`rDJn=x`)DEAKFx6t*Xg{fhae zwkP%Yo>kVL$I)HJ=!F=W=H-;HW|8sY3bqE#HAOfQ4@RcgY2QZl_Sl;&+51?#!{ATn>$s3I-- zHCQ_D4B0i6dFGv|^Gvwhwlwc7-JObEu7u}(sDck%OPmqW&;-^)e2){7%{}9Loshq| zCvWdVyGMZ0;HIH}@QkS`Af&mLYK| zB}BNnDXye^hFN+&&PRmuw|pPy@+otEr{0Lsai7O1l;5QZ6(7WxSoz(Wz<#^;qYve8 z4RL=|bA8L-m&b8PeR&FOtiq@#rLI7)bJbK_<|FEAT%5Di?f4&658!`H@xffSnuRWx zry4LW7phMnX_0ygsfyJe7<`2KcbF<)4RJ=Go&$e@dKWx#6@^uD6!&b*RW%4ns?UQz zsraz0Ol?SVPtB8%YNCpxr&OpMRM{l88gqupY90p4De7k^z!cSod<)b|;K$CkXMxE7 zdgw)zX+%z9BkOeBTC}3XCS9dbr=oMKlQ8ugjgI40G;yYmN+c?FW8X=0o~-C`5@(z9 z>T!!IsSq0fUSQi1FiMXp5Vk%K5vWD}ZNLb-P!IKoEk z&4XRyn~Itla2o#2dKzq-aT4Y~C-OSV=<(@uyd%Mf?vY*iSH__={0id3WOuxCVefc% z;s!E&f((4F9@hUfLxiKZ*8ywBdlHY3>v3{%P}W?KkVM?MI?me*i^ltkUMAnG_@{N^ zFfF`|)cHKkJ0cn%K84z$^~PndT(;i0?3K&b8<)Lu*?QytUb&yf1vyViZzp7h0sN1|TG9_b4BY@SLh3pgHmp8}Qh1Kn0xb)7hh9#lz94TYQzI?@(*uZ7 zKSMJ{hucBkeWCG)9^n;UuAiR21nU=GkzmKg*g4SQ6keI2i@lKhEcLo7!G?qlg3q1^ z>gv!+rp+n5_FF)=kQ~>I;W-`~;(y^s$B;d{f}b20erybj5!yKJT?j9{VGPxB&vceB z-yh?*bQX9qZ+jZr72Y4Z0zs#S3%?l4MW?9h+quK}k{-CL2JpS*gM|}dhf1yOLq=O~ zCmKfK!=Yaxofz)1$cvm5pO1;1quxdpDD_E{#Z@Ok(~!#3hC2_v*;9|AA|mQ92+vY` zP)$*F9!eNf6VQ*cRV#RM)UQzi3B|2j@zO7N3RM)Xp-A0~5v5q2j*IpP^$P4aQvDoP z^Afcj{G-)(5I#oTi0(F4twvEw)!!juocb87kW_qCtW3QG4a?Q3XaEz{Z17j8bMb$Y zx)JScvf}F!Q`F_qZK|3Eo@r`o5?3a5J$PoQ4@2@yrI6z+btXDmwb}>+&Q|jgK1U^R znVhGZP?nR_NifC&^+gOnr>N&4bD??$@)xNWF`6z`KL-C2#aFYIs-Lz<-+B z4r{ckIy6N1Ie=B$)Xy>5->BXK=O#54b~{6T0DaC>*TNcSsmGD(L+T*xe72ei`R(ct zkiS{w!vY=Z4U~6_;ue6N>XWccm-;a3VylXxEZdYqzCG%vD9d*B9h{$|H+?-<9Yij@ z>KpjKLv4cQed=y#(yt!J{{eL+B%i15!v8_lg4QymMxrdk>U+@VLiIIByGU(?w2Rfd zu+=_Q25VoUzJmXks$p2^GR67ue)X}*c$BN2L5I9THKLZURBf=^Rq9J9`_*a$YV9Lx zDRRF?<-h{hsx#4IuTzVl)dy-3a{R!FJPo1wdV}hs^1P2is#<{JIjR^{tJE7Pq^q7o zmLatoh6t+zNbIR!!ekLO8sf5410`CUsBx(Bnd(vS&r*k=VWk@6_@F+6RMn~rl{Z`6 z2RU=pn>e4V>Y&Ly?k$K8!1o~LEAD@OvN{ZizVP(AKEXjYWkpn58@FS;;v8+4552^H_uB1!xkQJUSi3KgK| zvf2ImF5PiEQIXjL`Fw{p9N*qG+sQspPXeMK<~Z4dn#ggRVWaFJeLt3P-$!+259jkwC!;0CvLcc@yBL<3-Uq(B0uSFKcWhKnpalelu7EjbeaH-2Jx{D|0 z@yd{Nf5ez6dK4~mYhnB1sYM*nE8GnfFhh^k)$S~`gW{Q*nCCu+auv_gX%@I^z+7CZ zr7dzFgvE-hG_lzIJ332owVoj^aoeF{@m!r|sjE)Z+Og zdENC^xUn$hovcNu)vo&;)I{+@Eo7zpJs78WkruMn<=a`si#5^amNI6EmblTq2o+mg zqtk41&quQ=uGMU3xp$&{7BADpX7}qXMx7?Q+!-)ralIyb+_TF-G-zqP=%;8(#f>4p zHB(AEo2%7`@;u&FsaM%n)lTpz^kzLR5#gxMLab63p#i$; zG1N#{{T5}2s(WyrP~U~UlZp;dYSd34d0(zV-8hNd0zxvkj8Kz1o3JnUblByC4`k38 zxjga!v-uBZll`A)nIN3(yYz|cWcNTj3_ecwAvO&s>}0P*_k+DLp@MnPZsGq2bpmCa zY!71-^v9nb&_$5kSADGRF>K%}d3l2pD0AyGvKnF+NYT_vgb;!usc0UGYh9g9La zD)%t#irK}NFs?eG+*VYR6VA;g1<9La3D6v0vBcpG4rk^4flYIP+HGV*7epiuR_A&jNtcxoEKsEK*JA5}NATxJq*_OK?PM9Y~qI_7c)fP*Sr7`PC-pMg8vcuxF5`= zC8wYSHi`cz@+Cj`X@r`4rGl54FY>kxb|&4J zL%hw2(>r&|62IqH?(II*D=GuqD5QsIiw8avI%WL&Mr^wP18+{{iF2 z#cG3%a!Q^ylq&QxRGX#*TNOK_H|xs0lA&x6T8vY|_g;%WqZ8bbO7I4>F8XW% zXD<(?Lc7qK$IQ>=!u2x@O*PILBQap9S8~s6Xb>6r)~5|N4{m|268PsM$Z8(|6D@{#&p5j_h#Yv4S_EXeeCQDz88% zeUT*Wf(_R%g!G9W&Wm$czic549)p~Jt}~tiY8rlX8B8-e<=?;{_ye5i*9+9`zoGyx zOa5R6Ew=!_dH79!3-W%j;Axz$$L}=!DD_z_br4h^ep8^3mWq9b1AAvX<<~>Wn-GU7 z6_s3ob~v%yxv7Fxax;Rj!EX#r^>IBbpgP}U5OVm0&Vj1DjNe$!18&vRfWL!$7r&`= za&Ws|&<$Px+J#eZMYZ2q!cG*r{;G?{cEfi6uCHGSKVv3=bgq^Z4aZadr||)g1<3;WCU< zXX8Y%79SdWHPU6BjWBvrc?`d-RuJFC$y508t!=0H9E60ffA1pgaDcta2n%70{pt`m z(MM^W!gG@5Ycg&*?L6u|Lcy0IjE;+*r{LWnevOlt@pB4)3Zb{)gdcf1kB=@yNweNU z*qey`GudAS@h_abk6#g)ivMZ#xE)lQ9-$RWDxis4hKRy{2ix5^2`$FIuZ`)YWUeU0 zT%7Rt5D0$b$z`J=G8I25*kmb$l_P8s1f4?3{}*@f9bZ+I^^Kpi z&uzI$Zf**YM!0Dtv=AWlnw#X32qYm1T}>dAgam>iG#jyC9|chd2r70^W-bN7}N3cysALae7z1KOn5NGE3eSZJE@A>5Bdv;rU?X}mg=bXLz!cl>n=|q_# zB^AI&QvNGky;3elfQxF7I;$d(qp}Y}_+=u)f{h;0! ztJ8C!0rVhHZ!4mXIAa;^PNB}FZ~L;fI0HML`ssf0Xk?rEP)FWZcFSkV&SqpkYTDN_rww|znQ;zY_CT_@FF*10}qEknK}rSC38bqpk~R*Wa6 z=ycl>OXJxaf1dJY=KMc!`n+jd#e_ij1zr2r~~6F%(AaavwJ2Sl=FkWmQD-wsjhGvu@j5#vq`)N!i>*Axd6TvKf(xK1S)k_-VEElI{!#2>JPYPMw*TO-D4(V~Ahch80taIZhIZHarQ}r81Fl*%!@>sBJm&w%G2QLm2wFJy1#3*lIgn|Az?cEe$8L)i}?x+=Rlp<0T0 zp!HV+2b=?0{sKQ*s?nYg5r6?7%nQ~b#DNx03%uWkhNv!AbJ4t$2E;#y24V(Ega3LY zPDVJbC0`2-Hxmy=AT2$es0Ay}wDnqtmfoSQ=YNI6@^!6m;sz~aT&@;Vh$OU#RnfsS zvcNxDixn^x%GL)znhp7bexoKKX&LUpM4q zTJV9%IohL-G~{F1?{V6-5vF+>SI}?|Z0Q9p11YmUZqxV=S@N+=ypYwP7}Fw6tZAvo zQxv2c*NfF1Z_qAKe7JoWWn?FzzdjB@Xi{|IqGDCp*cQo@iW z?E$f=CCt|o!5SI)$uun(W&OHcA$(uF&{{wZAKHyG3< z^k9#lFgJ%w6x)Z1YyzL`=95AeTT;lukpd70-@%c1L);kigj-sI#>pqQE)y zo>I~_qex>(r|WZUr(Y&Qvanqyb_n?H5W7RYWl{(AfXx1tLa)=H1=>lT6xBh!F2}r3 z=yPREc+*_QhQ}d=H`;PeK`saNk99aG2`+~p|7_U*uD01$>+@{S>Tm1%JQYNOvEdQw zeA`3%Uv+)H%KLZHS6WtTGX3ri`prjb$>Ra(CkY4iIm(a5L>r#mRojyLi#2el;VQzzE0d$3Gkt?L?WS|uc<8wBf6Qy&?IHr=QNDcv{`k8GL zL0t)r!xUC!I*#B1Ns}}{f7RSq+@zNCjJV|w*6JSOzrt) zp>i<`4Q-;<0_K&rCBR|Rt_d|ZX4|Dd|L-|diOxhWXR4HD-n;bM!dSdbKR_%V(C-do z@ow=DvG|a9lvsRJsO*9)vH)nE&W&|2s_+JsA8?zvm)iKrmjjbE#Frh&`8rzhCHgf4 z*XTFu$mT}<8tOo<5x=EOsULxBxA+~oekbIlpqw91UAubiN#>Ml`a)PECvIlO9c>@!3Hf|!4lK5z=n4c&?-A1l}`Oa2u>+F zLL4E%XCwIR&4|cxSO(8Z0ARFu?l#eFx+;#`9w0Xj7v@FpjG2R`ow{H=n6xGI)$C33-e&W7ZGDq%IRiDjs(70% zC*L--&^B_6X5TI22%EzzliU?_CgIV(5{%8}LTHj^H`^o{;vNBg|D!-tc^*#~l^%5J zwu|(u@gA0Px@|EYnXHhB+FUj_5wazxYW8Wpc~*ycrly-5bjVuO?9a>a<+k?qRB`C< z<$s6#?~?!X<^SD6!n+ERwfCd2Jdq~*{ySrR@)NFqX9Z102(kP2zllr9$R-`(^0w6- zgwl8&`-fP0`G3083IQLhSk^s%WNKO)q{wU9 z*yd&4CGlKv}raejG5h1N z-x&qOV3Ix6p~D8@D0^xe+}TME*dk1vykb$JJw>uU!=C2Q3+%2!d#na~+AwkmTZK*p zMFIQDC=Hm^_c#7(fVL!OGwdGY?`O@2cdAiTV0>uEtn4w!$)?+#M90{7Hj&7rxDMmN z&9K;Q?`u4xffdKpMEE8d_iiSFNr{L+p?>29geDBI`(+~I{>`TlHM;{lzq&osktnlU z;VXb=f{~&RKu~59Jo_1qCT9i7#+g3KB9lluj5J+_H<{s+jMW83LTHS>D#jcuMiB|x z?ij8J3{t@h&0v*zUV-FgK}b#m!ITu%`lkI~^ zWZ3$||5NZ~RH!w{ucbC5^+769g=jyig3lgJsxVwuRIJ0;2$l`EZcmqW4T7jRpWTTH zr25R_`plHV$TrI|pM*6~6<5lOm|CO?oNq?*vBZqkx{)BOSymQe&Q&q{STP~FlgKrz zNU2sNR9?KXqQKra%N{>eN--sj>T-lbj!}*kCN(pMxJZjUt%laP~iJ(2V& z**GCgeoqOiLgzV9ZJ9#0dY|1h(ud?j5|ixF@Qwwc@u00cB%{PmO&>>rX)x4Y;4s!9 zJ0sd>FEG~m>_ZU)4##B2B!_V^nu6}gwMUHw9pk80kZ2!|lK8-;u>)busRKnxvPVsb zv^e^L)Df@`BE6b4#o7PUYl=(jVV?oU_h1zu#J*jmogTzhCOfLCi($CoOg1PKX1Ha+ z9Ewz2Q>Ve~6D&%uZGk}tj6>2Er7~jBo3#SVC}+K8$0Ceuam{r9xY1)qQxDHW4$M}< z_>Qz!s7zES-ey)*merRQ*Ou2$FRnHR1TvhX#!@mYLFNy_sY{bf;a<{gMz~i|NbbsF z${Mz3qOvZoDXAyXm?*LqhhPc#+$$>@+k->|(^RMxR9jL*_8-|kqRMW1O+{&a zNg2Frs^-KIlAk)q4D}IaDk$7qk7W);6|}sp zVtTo>Afyy1%svq^QnCEg>!l%-+PbQ07+A6nKPQ7&WWzRS?*&OLnrFFxmLVFDloKM;EL&(xM7L5gr>7^5Rk`Jhe2-Pgahs{_2^U$rV} z8rhjnyf{QG1xan0{6QOnNSE@~QfefTF(QG`(nzWD=Vm1u1qk!9E#zQk$%;F0Q2fEV)`XVSDim>21)P z$^H{nL)M|BDMf8b>$(UlQEFI_Y8jSGucidqb0l?#)W{TF%Q&BET{MVEi)8h+H6=kw zslLTBy42W&*KT1ci@F6AMAghmhQX}Pr3p5jT9>u2MXfh2UR%FvaeE6!7t6YqMZuZ| zkT&6@Mwn9zvJh;_)fIEA>gwnJde8!`Wp&#UW!@T;R8xW_OWglzcNHYBI%5#WR9@knpV3<_H^F2B~nUwAxx$I5G|nyMUGnTB*P=8QH#SG5Gbj zwZZ0PV|!a`t7ZJn5>}|GI(Vw;lcktRokFB|q~`+7s%}%gq@mz2TW3_aD801M)!4RX zlXQ?hj^1o)^iAX<+8SwGVzQj)Z(>O@=&YO7Dcm4 zg0)dKr%uiWsdutW(ywXSL{ot^YNlh6l(w76iXtqdOH(0MNQ5o75L3}IYZA5MRdvj2 z?6tb*1uz3wIcHYAe@?~Bx_b0xu$Nk0OFXJ#T9zN-6V|g;oIEG3ko`k=EEuzFTD-Jv zLw(!w<#ZCMw9OqBWj;-vaZ#RO0Ttt@VuQnMgxNB)OI-sCd6*Rbx()iEbxSD_DlvL5 znUy(xP~9@w2n;bN4XKe`ZMK~bR%Ca9ZJ>JDa?}jl+-*^fD4hSIkt3-D)S~6A2$nFL zJIEPq=xm-&GDbC3R$5VqdXoA^0~PH$nM`6MD5SUHk*&6(G-NgrTwJJDZWTDF=?fw? zJ=m|%j8Bg8sy~v(8H1}5RYGf=Q0n2IX3)*O>1OF ztvU(S_;}DJ@dcL!sO@^$5X}xiR)g#cD3UZye{u^`(x6$ktV3EGQY4tsoFlb=o#h)#ac(!5~Z$T`heMNn39L| zk=Ae-zA%)7Okk#3si+z^rxS82 z$X~Oyidw~-h#G)p-c@P~Z4%T|ra=MFB-~$BS64MllNyJqLb#bvlnza)cdPMglFr5u zRqq*ZchZ3%1+*A&Z{vL%|Zr9^PZXj`?W6;^x6RyDC^4VV-o!Xh!*UL=Xv&#kDf zkS&&ap0y!XaxJx0_MfSF(U6MfMOJ>Ti4|G1R0DqfubJ;X$qa5tS5-f=EKnC#H$0Bc zs+v_+SvO}^P{vZpsO08ypnmx}SlDhP1GAQHszqu&?1$H4fikzE4)$)BHg_yu(i##; zDsV|vWrUUAlJc^W8FF!DPXB^*rI6JS5voW*lk2K(prT}kQel;nRxD76O0tSx-VHR2c@A=9y(>*7E#Jrb9-`RBdG`YP>FV>m|}=uj&}(l9(;V zhe$_ic(531Sr@u`Rju2y^lZ+C)p{wce?}=~+u)s3>ciP5XopyNl0M5xscg;WcuUdM zyiXEW(u{0@m_}BYW1Br}c8}eo(D`nN(M5Y#a%VB95tx(BfkN;G zidFZ}64c17DolIL6#y@0!syQop==saxAy5Q&EUZYBfgBI;nSVrc;ldT{fgG%5f9c$ zCguZhV&>%Dvv^KjRgnFV)dSjKF&;RW>_*H{xdmDib|sB!%tpu*dr;}2#nq5uO(m=- zTg*UXn^&yB1}If{aOS;s)2bzHtyrdGv<|Vn4!#xj+AurKY=RQXf!VtiCv>kEGi7ss z+}!33ZeRzK$oU?6GBnOI?2Kuo#7c$K3`Ok{%A$ofXWmDneQ~RrxiYaR#m=-`3D7iT zY1_K6kv-Ur(&Wk9%Tle%+;6ugPjb913lw9@AIyhFaO8z9IOu0iMrF22pH-jCM$j$# zC-=psHBYsPCmTHN`UYupSwp8mk;7h~cxG)`ur52ATk&*Ct_Xu;L5PwlNpc%1uEYZu z$}OxhR1_5!lBepZOq<$V47EclBvjSw`F|S;&na z)$+)`i|Qv4%Ehjzn^jzmCo;7&%#B1Tof(x?exlLae59^sP6+*w9qizfGqpV?xyD1P zb*(fM1skjEl}#hC$RwWA%&#E^At3?f!=3s6?Zl zaE4Fx8$(tTO0;3z70*;VG}a7M|5MtNMZRF9wsaY`RUkK$ho)t6 zTsI{d+J`B*C>c`c+}ngDxSdjq3E;`wobp+Z3R-~03_Sp|7*%`k#Ehy$+E=GgOX&1u zM{WX=ui^u}Dau!Z(ZVc*OrlDTv2wb4rWaN(Sf22+YNfAgJGYlwuf)1wuGD#MHRh9$ z@V$4eDC$e+)W}7IlxO?8#*Q`^PLdPwkVkaLVtM=GMyruqf)6z$Y>9)O!0}VD)r(ij z1)Vi=%Q>AIwZor}q4N&wmPt~fokU;`9*Ds&Odu6SMMdFa2k%NXdAuVnQKhotsmT;( zKyB?EK3W%ps>Pq&<3J;=ESpykl_-&0MIjv%COf4kE2NS)T6SGI&#yvh%7GL6ksucG zazRiPg2ONMBh>pc^C23+;}5UJ%-Ngyu#WadX~r#ugZBi;EEC?7XltZ*272pq)w68# zse>Bd<+>W960ZqNwNyhWJ>rteZS_tlAvaSD#XJYF6yEI8W%DnYgYBVN^?`~SwUTEY zrxz-$*;81xVtQ${B}_#^yEv_*Y1yh}=u4WGwex;~88v)cNwtbl4N}kh7Gra^qZwMs z>P?eSS+Le+t5+f^!n)om3@10k82(mK}cr%gX;Ph8TWsY`H2Qi)l* z`H7qrK1$_lxr=BXL4$6PA1(?_(T#_XNZVHR$-QwTl43TaZx1+ znYWu-&kD~Hz#^U&y>)Ulmy32wVwiW;qbn?{QBxbP`xomD{3F(nTtJ@~e^CHc*b#cP+T;e6HN=G8$~SqrQ;qm(?%r&~(m z>+r^odMIs`(Cp5j1J;)8>b4ERn&g#HEh6HzFFEi_Md8|OT-@5Yu9aRHIB8?wRJj0F zQRNtstZh`nuOjVn)A1DVrMFYJyc15r$h7CSi6s`t`nta4h44u3b z#cnTlXP|55JOaeh$m;Z?0cZGq8pk@&NAf#kB51{3oswIu^yCk0DW z1O6b-UUncWF|VE%vJ5hn1Iw>qYUL&8cqlzB2h~FdZF)(`1Ydq}`zjwj zVX4ETXgu|AUhR_~2h=QU9pTIOuWN2y>Ra5tY8X6677ZGt0!R2p7LF_`95bRwer$q& zCvf2<*0Vh^vGTYA@}~>0dxyCl5pMdPC-j@0e7K7}t_#JL`s|kuc&zVy;4Q!P@q3al zbZoI-WV_h71abVH9YSn&dy@TlUA&Yc@kPglM8qxjtP!(iR8dOs(zDMz{S>nBM+ZV& zNS|a90TOS1#gA4@Uu`X3ws=Xirqic8_OZi?HHX_-?9!uz+lbKSNQ6pD_Ii4gOBe^fNSi4?TDp^jdw$W#GdmI+&4YlDq}n z14F_?zo#N^!}^*^MKbUn{-Ch<@*^S3$G~?1;q;=UZ7#}>>Qm5n10k0|@9u|O2Dl2R zPh18s16K9I>3g&i1QUJI4`Er|Q)vu&n4G$&|ArPHK|ekiD8myY=qE~>W<;O#P0-2H zA(x@`32_nqz7h0sFhs~@Kuf~;PnJi}5q9{IX>HV7thQh)>^f1}_7a z-NNe|r(=X%hP2cc^e|8h;qj?ff|sEU4mxmWgjt3o_ppfY;Suf;5$;hD?$HtMu@UYu z5$^F}w%WW1-4zmp-1{Qjk43m&jc|Vw;STK(h+cwKxA z2={Ly+&4$K$v&ic5xu7)+=nCF|BP_c!HDKX>FK;Y^CEX%gqsekGcO9SjBu}raGxFF zzKq?ZneouCU2qdi)So9nzv)bB^CJ3BM!4UKa0lmz1&zUbwGs=?7js|Y0Nz$EmNELsI>^)f@0MvA%K58hor(NDOv-v32e+ER&_dIEI)WV(I4OBBOg#qRvISR-*J@dFpl5*(-JGb$taNx z*+{}03Gy8lwU`LWI{11`Xi6*#Xu@{Vvr>Bs{2G@N=tSd4?qff+!$ z2IIsZc_AL<=k}{U&5c2yMn-q3ruhiV(9aPDaNrB!bez^gSdQbY2rFQufDj+e?_k`^ z_yFUxj9(Cf-VcP77@Yypiy@o=H?G0vunE5Kl_M;8skxwg7RGUMgHOp1@{@c35k=;I zD&yINl{jvduu6>!ese@Z!5;&jGL8mjT`kG0|!~fuH5T^^}LloE{Q}adlLRC(pL)YNJ z3Mn34Vv(w6fzyqsz67RAF@zY_X-*&t*}n)D5Xe2A`dEcj|Kz566&O~t2*;^|f5{(7 zWjKN)l3d9jB9aIZN<58m3F8{Zb&MAU_6)ca>gBuw=&W=OYxs%e1-8N#$$|FY{__JkD20U zFb-xM!{}$E@sr}!Gqx~pWZc3?_Jk?kjf{6OKFIhq?$kxZSC{|k(V89!zGhVcZW2YoNaC!58DLm4MA zmNU``lN7#yk&c)qHyP0++{}0d<4(rg81G|zjFFCjq;&5ye#Q7dj4|jqC_I^Q1mhIO zO2&FdvXMve$>tm3*^HMmUdMPdBb`G?@&3a2JmVXTpD-R{{F%{>B`c*H%Xl{9HH^10 z-pBY7;}OQM7{6uw7vl*=J32n1AI%ug*pIP4V>aU;#^H>k87DFpGfrom#aPR@fU%x& z8Dk40SvnzpHZY#Ucmd<3j8`#U%h<(8MtUgypBN7@{*%!jrNWaK$1)Z(lF=SYe=*}9 z7@uQ&o$-6d32qfXz*x(;ig7LDCdSQ-TNtlkyo0fu@lTA8Fh0TfEaOXzuQUFG@jJ#J z8EMOc%Hv>+VN7Hk$~cmdPD!NrQyFU+S23Q&coid=)T8)+W_*KD$3RN{9>zSzVT^P* zK825GoXS|nID>IE<2=UG7#kUz8QU1wF`mVE9^=J~zhT_YxRdcl##8Q)?2i17&HSB&2>{)_PhBaSSPa>3D+65|>BG2;A2>7UIwh!JNMO8?P} z6B&ycr!&rCtYswAR#Xr5jLR5X7|&qbz(`hbDgFhFmoi?(cr9ZW<4ugeXCxy>l%7oY z5I)GbpYbWi7Z?vQzRCC=<0p(q8NX)yp7AF}9TRrS$H^GWn8=vIIDj#iaR}oG#<7f( z8A})|7^@iPFfL+T%(#Ma72{gQO^jp^hWOmVcsb)X#@{kt&v-NA?Tq&@-p}|jXi~+`(j5Un&8Bb?i z%D9qo4dZ&ovl-84yoB*e#%maNG45f!jqxtVdl?^K{0rj&#^)IiGQPq1F5}0HpELf0 zk!;LRz5d8Zn_T2}Fw!yWpS5 zjf`ZqS?VL>Rg5h9Pj5&;h84DT5GEQMEW1Pvjm~jQ;8pchG=QCc;cn#zA zjJGj9%J?MXbBr%DzRvg#<424~7{6ltj`1f(fdw{|H;U2A*pD%TF_&>D<7mbyjMEvb z85b}vVQgXSU_6KMBF3v2cQD?>cqikZ8J}Q$oAE=&<aAoYn{B!hS;;A<9RFF$vol zFJ;`rNcI{i{1wJ;8I!QVK>h<6Co$GAHZyiI{+5v}6H>b889!qDmNBj$(`6(RxfFjM z<0{5W7;j+wBjd}A-!evH>xzEa|uE30z%9s zcXRk2##=f39(Lcy_&DQJjL#Dy{l|o$cZ3l8V83uU?fDQt@r->Kvl;UkhZ2s*J{`L! zFivIvO2*R|S8#X>;~MrqlilYsUcmmpVfQx1>)8KR#(UWRKE?;w{|RM>9?!91Ghz96pP2F5^PRdP2loMF_fAGHz%8 z-w`68+Zf4yJ-P2=e3TIBo*)FBL+t-Lwe?W-zpD_NN@fhRxgh+3s ztMr+SqZun08yPn;?qYnH@nyzO7<(8~!4vT{o^U+&ml>NFI~gx$ypHiE#=97wWqgqk zW9z%@{)`ai`-1Ubj6X9*XQ=Qv#w0?dA3+Fy#t`;Hf64ADLeQ&aB>O4kUe4ITxRLQ3 zLZrWr@gByP2tofX!oe`q!R~JeLGK4fJNA&t9mVJ&MEn7S^I#j6-6e#eSI@YPaU0|B z86Rgn%=issluxD4W}LuS$JoNSk?~r>Z0xrYg1^0t`xx(M{0rj~jIR?S-P?rFtE24y z72^+#KQf*mM7-Ecl}|ilDq{v?9wFitv3ne2F=H8HC1VZaBF1{gCdO9Ab&Q)B&nE=` z7ZW1C>)3x6Xx_22rV*g`=kl%NVKQroC%HKhV^htzBKZbE4`=3IH z^p%YB7#A@%5F-6*LZsiycrE+iLP+(;xR3FE#)k-z{#in#|BO+`J-PcZ7BbFcoK1*y z4TPY-l(Cup+u6OIaWmruj8_oiw~g^u_9uJDMDJe4KQSI4#P5AVnu${tIdWH_PtLI;YXyS6-Fqd&H<8_4S(+)Cz%J?HA%)HC+LdF@4iy7B3UdnhqV>jb| z#upghVElyfIHP<%0zT-y1L7x{F`ID&<0QsY80Qh9u6 z`oTuVvk9{?ZZrPE7;RJj(-?oxNCwp@KCFpIB%9>qu4G)ncqZeejC&Zn8J}Q0$oLN9 zQARS`NpwjU2;&(G8EY7u88*?Ok*uP_2MF-kqZCB4A3QR;<{5OT{Wgxm@V zQ4iw?k$xH>&TrLi^rGhvkkY zCa_!(Cx_iqE}&DyZYdYgD`j^%A?P-+dnqC4U%~FJgvjSLb{{50ep&%OUBu`6z>ao> zP3Bz(z4Tfj-+C=rvUaUj(7vp-fIJI=?-0nh53E-bw1VQASp|r(c*%c?NVHVs=A|3| zo5;OoY`!YqDEvH@=40CXBZmk-)0vXF(R|j*L!|Fx3F0MHoKEz%KYSe zH1g&0$UH(qdZ8N;8o|4I^(c~JP-!^47rMR1iJ;D>Wd1sNGs3^6Z$)Y&1t;wvQ7}TO zc)Rin@*-b>QDIA$Em?hor*?UHA${7JqREK1W`%t^ZLv< z^rA4jGV!B(gB-YiEnXhNT=@N`cnc6GGG9ENu`Udi@*0Z&=niF{PadsjDEjCY<@-Yz z0%d+xK%!@+n}++)i^AwS8$aByIbXUIUE-JM&}HIA+=u4dfqcF2qkPd#%XpNI<|?7( zpuU&JHS;q0xfLFv^ezl32l<=jcpCSi<)}0XF`DH#uHsqcsD_*PAzE~q<@gHsq4{1B zQVx>0nQt)&hn8bL!ib)EndL}Eq)>XhL&|~285X^o4J zT6CG^pm$P3^Svdc9Pu2F(vh)gqHWee6YlfzGcS{$EfMto2ztqgMD>g9Q>z^GZVk~h z)6v)&dQli%FROS~IVc|SL$v5J%RzI`&~p4Wq#W2jwDL_vhD6&e#}3@5o0;L>utksFeF~LJ9q3U!qL;<-h~7g?4M$=HQOYDc;@Yz2zu{=-d=S*fQw8y5 z(z`H%-i7F}#vu;TLy;{0=$$!AQ-~j3lc(Z+OsZJED2#qLM#P)90{ft5B#uMz?uy`V z58{0u63?u{y%GF90{+$@9`QF8KU01WA|C!INM4sT!JNG508*ZG5t_P8?gNNN@2yeX z$@mdHFMcE{(6g=!S7W~@B%w(!J|f=GZ7@w6lF*EYiK9Fat)Q`>ZMe_p8!@)1XjI{d zv15vGUszZe@_$Sb{Kk(TUj$EF4erflGXuJAQlc{CTje1J&sHC1*wtJtUwcq{Ky%)o zkagmpznn0-PwTP$#KpK!bUN=({1tz1ul~c19;f8*tcuBM73Ynf#l?_ z^wOVJ8b7&zeD7$V>{pZL2Atb}Tq(YE8~6E*!@fXt_oJU5yXvf#+Ma=4z=e@dfYn)Pwgr2 z9StpoMw;Unqbl>Cd?73gdjR_17ymmBtWJ61B z$({a~!>)ZqVNZ*~4_mtTJ^FdiH2CeWMhWiL8u!g_^2s=jEnN%h8yZ`7ET9yPEjP~A zN56HX=TRm5J6-!a^=$9`HeXEO@uShBD9(qCzLrjn?mligKYLGOVuR6uyhk*&EGW5D z`fJ$@jYfl)X>@n*?HqRW+v4N(@@)!U-($6uR+Tm5cspdv0?ZjlS-pZ*C^99HYKOt z+0ua6d4{}tD-~qF20Y?BG&~06|zXWqPN=FeJZ;h>|V%jC%YZ&?qoO7ir#u&04B&)X*16c zL~qS*+39z^s(gHbSdwoQmC)7YN4gh}8uv$S6Wg6#FCNv_j*{u3c2<|&+_HCnb)dZL zuKguFnHqju^$~BeF2~67*#cK}#|9|R?J^bJIYP>4mRFV0EU_x%i$|k0#nGu*=SdoF zPPs7a{4lp8t24~)%yNXeqq>{{f55$U5XxfP?&>m760zMurMY>Ar<^I(Ki(_M2uTPAmCN%f5LDaWMA|sslxFs4NS) zhu)!lV!C{Rs9o7xuIU+En0?G;TnN0mIkEKg3`%S78k6b^WRwoLP8*nh-M&D^b>y3u z6}xo=OX$ga+qb&5XSd8Ki+<~7^t*$61G@B4JCplw*T)ao_OGVP{jT?t?@S&Y_rew` zE962ww5v-W5_c$i=O@jJQe$`O6Bni0cP>gz-!8sEy=Bo9^ZJ+U>duL;Fbg3C0 zU7E4|A4l%f9NQaP(6|i?JmuC$rEf=1;m-K5 zEAWpa8Q>{hh8U$3=lGGD9^1t2`_eWZcE-K#+A$lYb|bc)AH6?)N5+oFQqz)S_NQ;n z*#27C(L;B9=`sfF$|yanX_w#m_QAkwJwqQmQ1;+q^!`!j9l5^erV;P;toiW0o{q;d zb{NM7=!={$_H=&uV$X$-y?8WBIJdc9Z)|q&j4oYUwtxSMF5}Br*WUeQqv3;2?sU3e zzqvUIVU1SUT?orWSen!G`X|lNkc&R?0!UG&Jli;?8^)KdhEbY@IEN7@d!Wh-Z^8F>pgfZJm zXfqO=179zJ7G!T}-%A=n_oNY2>%~%c+C#LdIOIO2D_n;>A8PwG?Vl&KA%_pG$(nn6 zyG&h|HS~5x$9G5j?fK|uI(EExv}6a-Z)|bw>YA?&nfhJjJwc77J1_J;`k08OSmZYQ z5W4RS#B;yq?MmO3zcsZqqbuiX=dP|)$F70f`*)R;=58O*m6n>bHxGK#HNR+=aopvq z?ux(KyS=K*xt(Y_yD%5fllSYHFCNwP;()e2VeflKy(1}%W(m=U;=20pN-a&4b+^d7 z$bTsLmDJpAc~{3C-xHmF$N0c}ZqZY}J9c*$^xS?t*>wr9_;$yx`~c;fbBAkGxy&u; z&bSvS?CsB}&$!2PZ|5@3;ZUKxvj-F=4zmTcW7|424o45uj@{8|JFHLE zhXvlUcOQE+e%MbO+u2n0!-=)89rfxv{NmtF|FmO|bZXhYz=5M)IqtW8IC5Cj!J=U? z2m25E2x(|cJ0{1p;GN3vqm^1#V&HOr)S=uKEjuM}yWf3CpP)|^4J8c+j(plOrzg8w zA2qo2t0T9y%&B$6OZ#}GHgHtnUVq*pb2Pmf;gsg9RHBp#eukx{26p;04rR68>o*Q9Y2D?Y`rVoL zpp=bjoK|IOlyp_9VX3bi`3N(If!^rSJN<{=)yKSeWKT;q9%PErYyEG(qmO#S;$G&` zN|F@FC03RqSgOt6mEA*OB-5!!7Ps#7|Kp&R|Mx@L+`H=eo4+f%=WjEYclA3?`0_H3ab5YFmdOHMDE+B>nR}xy)x(;94a^I?D ztJ>N(X)<`&ly;o+-{i}j?5m_hwu;x{%oiL_?OWX8TecCWa<5(6+_rjxFL$jkKX>gQ zGg0F*7~-N$Zz~~K9d`7@bX&mQ;tBl5f7(I4@lvg`g*e{R*zn-c8E<9{tuTCI`_LIW zej0uh_REp`{e2FH&te-I=RfS5aWu;(<7Xqj5Al5*A92TGoN?Ee7(dy2rk6FgeDDg* zHmkn4II0A*>q4Gg*Y-peKG|d2)7YYq#l1$k9YJpHSD>qz*)4NQ7M5sVZqaJeu9jh# zZBVbBA764gJ&(FTwKN<7J zC~L;(=t5d2Ni#L@J|da3FSon4DtYRl~J+Pi3+>@MvpJ#^%`1?5foQnriHmY-WN zqhWCijl0jv^$YpEFxxivqa$vVV|#m)EJqB=5ruL@aXF@8+}FoEd_;0^l__5ms3~9C z%cQIO9#nZBij>qbY zF!Q9;jV&{9huGSh2m8$E$nwhaC!zdal;6wce(NJ69P07Lz==1KpVQ+ zDSHNMPD*l!#m|%t$%~#@)75>Ct#kRRph#SQq*7mm)d`h4uB-9Eq8aC96-h2efs0Y# zVia@n-$N`hhX=q7oPze8%P-o0kJEI9v*l*v7I{k-mO*S^p= zPp({Zzbz0O=!+3i9M(q=wNF}nv|4C*^z${-;Ff)CclRBb`=2Pz2t2vc9*7Gh1%g^J zq~&2~#in##39o#;r>N8T$yqwTCuhwE561e4=E|1xo*b>FC#SIG!B}YjZSAp^_Q#;? zFn$sn38HzWrdt=rYP9vJR)As-O{O$6KS5=D| z(sF~}c=e13+5I|yUdV2LyJ|Uc;4cpR#r4i#;ru4G!=fZv-=L)U@A>S3HaxacyDz)t z+kJVheW4k@#YnxP^(ueggIoPO_TxyTF_#04<0nS@0s~=Rl4{o+zqKsd$;r+ntx>x) zv`2$87UiiJJ`AJ2wss%7{dKFb_h+;??}ygCMQttSa5N-;XM(#z__XbAS)!fZmfUi8t(3%@96UMb&qowQJj*k}J)pxOx&C zWokVka}bja4SXctZ)>>%WjnC)8h`ZR7?ka;glJi|Xr>~%y^rcY*|Lf;cgyl=gTFtR zuyK1y%zoXc`HmflEMNCty|bh>y1{5oY%p6nm62q)(=T3ma^)_6%&R2Buft?$a%=pg zD;XAQL%usWzo}Olf^TysBv18_19$L%J1dM#iOI0Wj`mhMTSE>uDv7LHHdhlKLL-qn ztl09Wqc?snlg8F%i*eE_r3%l64o2z4ThdawD??IYxzG%*7jH>NGF6X}B3KlQF~zVf zpH;n)H#lN#D*d)#qx-XJoIj@NwB@bM?vsOuVrQW$Gx4asMg-IOT+R=NXqwOF{AmP0 zI6p`Q=&nROHg^702oi((RU*1icl-+>PCCWFJ|vko)SV~XxF4Imih_mxb3ANvM&X4e z`}h>vt9ITu2=}v+ub^O?T^|6iN6D)yL z;HUe!@wiV;oJ05bf&qswaWUOz8@SI&>Y)1!2kwU^cH%zuD0vLaghyf0cHGz5oMS=4 z`9?o_zTAL<~)Q6qiwJ@1^080B9a3)i1KnAqO3?xgUh2+aihj~ z5}GXds(@zBCp0e;+5;ugB_ z#+Y#cJh-POPC~RCqpm+3)4Y^Te%w&V#a--q583F|dRzfy>-H<>Y(4HVB2uE9HG14% zQDyE@<*e1?vWQTbbUNyEde0mOp{US>dfZCXoqM`+F4E(g@SM(FuAF$(>%0ZbMlDL9 zjGd<;o2XM0ex!RN6ZfabKSlRrpaW42>i%~WXNm6~aGiPs{^e|fM027CG@t;+G88P@ z$I{9}s_3kk58!7rW;sMHfid4%(uy9<(t0czA!8Eg+xH}6DOigh8%wH@ zY%E1K(c`2eJ?^(CarAf(F$%-lako&a3Cbz-IQo(#dZKiCZF<~?L}rq7>PaZ^RuGR` znoiF+^QWVZoJ%3>sHXID;E}Th$}lq~5QF+OHp4%rqR&OhSu^N$|CpJw9&N@H6g;M? z-xX2B=6je;$1IQ`$%Y>_9CNyKsKri|49qliGev(4QYE$jiFELHKPOsJ@rYK!(lV-LtdUGF?--}8T4s}XPK<~7$Z6d zj^)zf&3y(GJu4(jVo&aUD7&Xgy7b=}BhgGfD`Or6?LLMbHRfrNj=srcmB+Ix!40`3 z8}|~4)&0gJr*tWOPn#^fPjfy8dQm$DUI$k5e+vb6u64p=kMH;7(M%oV54rHzoAUrX za^~P)k$XT3dNt#06wK|5-wjRFjMaE_>CQ};)Q<}GJ+#H0)kjCoxC{fbaOZgYKqGyI zJq?b5vS9f}e{|vQJn0x}w1GGGAlYUM<0e6=+=HbK4g9b!Tyz zQYN-!ED*K0EO$3TT$gt!9f zDAguCjY^oH=TAnARLVKO5m`?93o5%zPp^bWPSbF-QE&Ec+#9c>EA-~X^+COB#-C9u z-dst@X1s?K-htBLGD^XMH%~fZj1E+hcaUtHUTsne$js0O5Jx$wC|7#?{2z#N9=eM7 z1^s?OhoBir5J&t%PEUEpFOqqBjU!N(_*11QlMH%r9e-L*DrupXg$;C4gXE2x;gi*_ zC2!J5gK_^joMEel%CZ>QuqBsNblf-&-1AW9i(2o<3P#uY_pcyZgBYw2l zg#R((3jB{1)CPUxEM)5wTk$_rEQYYNM9L_{YejmxzpRo5<8E{*R=i)4`3 zJ9>kbbeg*Njc(GCPFMGZxu2u$C)F$0wA@R`)u3F}=~1K^?L?#c6X!XX@BUK52NsEcy^7oq|GZ36lM ziPL!#QDPnB=oV)|m7_&8l=y_^gidIlF~%g2DEE}w{{XD$ph_*1GlR)=Ft#VqmwHbv zE7>!idQRgsNZd2gPWPH|D|$N5B-QH}7eSt$$Hi07>v1OBYKO!?5{llaTp6*ld?-VKujq)mr9Pi!KVYu7jIfcfcAO+36 z6>cTyzO|nHaEMc(P?|V6SWYefl#g$L=Nh+KvHA`2{F7om0%g@iUJ_NueyFk#V=_Tm z{9};pORs>O`i(SR2&NnD83b(>^nsKn4uD5p97YNuX5l}M_Wc3={U#U&A}M~72Y41! ziXD)FCh|cL4Gz2sF%Z@46MNARGd1T#)Nt}ZV>F_=sf$*LQz|_>C^3CMtchxw-FmPr z#DgdpvTK8Sq|_SiR(2^1JO?Pn^#dtI4qA^c3f)D=HO{59F)3I4i_+3N zX(_)+rF+dNhR{>4Or_}V(PSMy<*HOFhA}_4Z771SPL*se(gsn!QK+=RNUmXYz7u^@ z%3a1o@Gei;7v)FLcb}dc1TWCL!u7x1I=#4nFw`>E%+ZL{waHkZTZy8 z-U1nV#p_@{UR(xkN)T_O&Jx9H)Mb)*4r1yfrXZ`nA_}5S7Brns5mTYasbU5~)5Jee z#&kj7O7|DngA<>)6#kjww`d+&q8mA8i<^*Fj<^ww=ZgLi^FVPoa>*0-A>VxQ66$%7 z7y{iKENW4rA>wb4*HBRgpJC!H#4i+&AeRxM1NS4vFz9lTSc=k(77wCM#tA%V(Z-AG z(Hl+>*+cNQnb?HTNn$m$X|fpZL)#bkqomWsOZZ}Z85CxE1 zxo88Q6=FA}af)b$&kXSa$}&^zMX6^AKdPi!EX4h6@hvFS2m!sW75@XC>qI}$pD$)0 z-vweSWVKK{jNBKAA*ioY1)W@Snn;4ypDwD=&(@0~9!9>6Vi_d1 zRL~dj%f-E@!4=|jP-_xjL$=Lgd!nYT6npW%MeG2Ft-^&;uM#hT{%SD=HPt2-;Qtyy zXW*S7=;XV0aX;j|R?J3uJH!_JKSy+c!`QlMS(=HI% zNPD4p8#TK{w8H-)(Sc6uVzC8W0ugB9Um&52qaZEBj}V6;{s3{?#4{jg7vm7eA>tu) zr}z|Na)~q$jS{cn-YpiQ0;0uPNEIV~0)<#H3<}{9)YHd_`=BnETA*O@;%oFG31TQ1 zO%(LuV3PO*g6ku;Ag{iHj;iS=3ZOK}q62xQi07fusbU~frHOb5I$fOaBo)6K6`3LK zD!}J}LI-b9cf`*W-$Gb;0Rjce7FVIda>O$bQ?B>~sy0weLvizj2YKa-2FPKMm<&z^ zi`DQMBJPE7hl)L*Fic#AN-7W=;4@sj2Remf2XY)CMxw!t6#oNN8zqjS*%S#ss(iF~ z7J?olt^v1W#aDxcu@eZCWs3l?ujB9C7mSR!2mH?Yy!Tlp9mozbLa_>ho?nVwVYvRsCfo;jnOGjuiXUGYh3yzUmOuKZ%7(K`^ zX02T1dks3zC8i_B1xAz9Du10^2qbIHKR_#E)*DwMpR6@$zSB^d#ujvAX_?8Cw`M#) z3XW{q>(jBDa18X&VB|CQQAnQb_cM)GQK+>1L>fbKjOUSg+7LN96dJS_l{Qp5ij0pz zB5jyVGtRgidXiQksZBIqLt{uAE*+DMOVJwA3T3TKHr&L{D4Ax8QBTo|Bs-WsE5 zI3`Pq^NnYrb7|9LngzyK%D7lYJJt9b<>i--2ID(<{-?V;L$mtyDUij9rwbOj2vr zoX5dgTEO@POsA5Zv+B})v_6sYPB-QKDuUCq9_VYGSC7j0TXNFS#CWe2bb-A0!pp2TJoq3JE14h;vOFeh_9gS zhURX7YOAaVWO(FBK3{{JCT>Ty>tYTv5aJdnr6KyD2gLO4At>H}9HSUqxM>&5BZ?5; zSK#=R`1(^OC8iUgFkeEKB}6gGXcIIib%}I@dc_Wq_K6uN+cfb36t6SwG9=Z!Y1cpy znlJ4Zf@x`gB5gKQQ@l=X+WR#!Kt`H36=i|1=1m|%D30{Hp zpQ34_X=&c~K?gmX<~@d%4Q4d&PH=$X3q_ElrSDV^Z8M8SBZzsokC^`g-JMO)0h2EA z2CBp>enxzsxCBg06F&_n1}8#UH9f6~m=S3u=;$;f&5lxQwzLO^09H z_s}SLBfOuf8=Lnj44$}L-oxs~>)ik?z~%G)qI{-l&KgvquhSr@&Nv9o^Sylsx=E!G znK>TX&=R$fwk~c(N+DhVyIyew|9!#$xoKhm{&#B53HcbFhZwa;FvI7={V*crrmcUs zyt|7Ou?znO(da~5SaRA9&!=$jrX2|PQRFd2?tjzs0~;mQ+%MyH3T=Jcq$kbGHTU1( zo=^MM`oz9=(grR41jyP79obM&8+G5dr{HU&;X_N@2VS!C?0>+0Ifc{NX)?%0JLfif zCZbK92My2Kq|+SRCjWU!1>I*OF#TUqsMZ~hP73QsiHTMDPfMf&6>V!=M6=5xPIR?I z8mnxhQIPaa--~9Iu*h+keCQNg#RM^@?kLtwE&WZDwEqOh7Zgp3B5?rpyZ^Wt za?s|d5{L>Ki&!};T~u%%1xX30!qWj%Ib||v3|ev1MtAjrKjX#12r;zd%xZ+)9?%K)#!#@0*tI zR1)I=ul^76k^jEMo#ws|E!IstpXuNDFq^J* z4zV4n)b?tba(M zQrL-eP?xFur2hOszOrT#x1z&Hy;=IkpkVB)fkf&Z@swp&(DzU_*cv0*noPdIj${~} zGFc9hVikvtf`X0ve~-5-7YJ?kV^!T&(FcZSt9r*w$c2 z^U?AV{5xc!>(!zI|7*oLXsb{yjnw2%R){uj0{gw8{Gx6)Zq)|v9kv&VX6uET-H&k6 zxG#cf>@(T#mk_^G;YSLafSgsXTGVp(W4Gp}hZMsu#b}f(i~20W_1$m!xTv|dfmGD9 z;Y&h@#*=$QEcy}mx8rv!`QarF`1#523H%$gNt2&| z_hb0U@s(PT3&B*%b?~F;B(e0MUsNglwgt>MO0?RdO=XxYAw-w|q4}CV+~&O;>0CPy z^dfSgFPmML!$Ir0H}UIxD;#3m(kRGYqxPe+l_Yh&Mz|mh`%;8;PgiGfg@kK%k}Gu! z4kiapOX&&=gwnWrI-^+s{alv2-nTDcv@VM#>C&q6EiOIhG80E(+;9 zwm1^BJ}A=+$DD@3<7c4P^V;MhN*nSfmJ|BhMiMnoeILaoMTd{n^bD$YIHtv-J~ODk z;ix7@Jn80{~0t%Qx5{)HiHP4g#g z()6F%p`H353a#%nyi}uf{S7~TH!b01%iC!TCUyK8Tz-jPN(&nEPGcOYo&&uO=15u! z>EKSIhPtppaOaXAEe>`Wc|?_-H%}nHXW-anOeViNxU0!8cMt|@6_0E`tRTNd$gs

%WjWp7P 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

PaXtjnDCXKEdCZKg4E?#S4`yy~zh{C%xf7i}DvH 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�^7 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�-g-D-y8 zyrxQIZ>W+Ve@B(`B)e$hkxez$!q(UWhu}!eM2X7$Zayx@HTWF9iu>_1Jcg$+O5e9+ zzogpND8+xqt5n&aCfHt;{pyA0Jx}&8L8ryBI2G@}CHM$FiJNgZzKe%d*~!!Bz6X}! zJ*^rx#CCWs4#m+p31{QI_y|6Un^ieK`|u0=4GZaeoXjt;7MA*8RZeCNRj)%;uEPeZ zoZO~r4Qc zQ&qVRXQ~N~bB8L|;XSIHwhAR6pPnG>xrOJN1t;&9!R%JgbXnwq>l-sDXAN^F>kI|~^ z$IY70l>L~XCP;r&RrcczRraHHDN*)gt}6R6N48P-qqsi5Wj`)<#HCVCugd;3WxAy* z`z5O~^9QN&+eD^i6=pxjF+EY0{hh`1TvhgaG1E&`+5go{uT|wZY-0K)RgT9lrr%KI zxEy5qV^xmNH%x!0c98$+buN(?QssC_b&r{rVrp~TYB60;mE+fe=`QO3arYkJRUFsb z_|D#4?UhztLI@B-LUd3?7bFlW2#MZ%v4sEuvIPhg46eB1xWvXLjth<(uDDm?UgB=Y z-LW0l7pB`&Ana&!!nIzkqiJ)8R*h92o?F~dS65uzFukF% zrDem)#*U`CBMO?^+Zqdsw1S#B(+eQAamD|JaO&(7(7bB%|3(4bv~O9ts-d;5c|B_G z07VD5-SRaoDR0@drlp~IeRIdA1Lp09*e}1+0419u8`|n-%q?mt9#!Ku#qkstY-28Y4X~Vy0r&t&Vv9CP(SEc2LT`4T)+6y&Fu{xG;_|> z8FL#B)Dxvz%Difs(A0qrDi!meYUTf483(PrNLy2TQ%4=z{t!%!f)BA0yJk435+$S8 zG<7sIt#4e>(zL2!l~fSNGOM-y5Ow>HG7eGYLy~iFOG+Fo_A}xjL*tODz2v_ZdZ@Pk zj|3mw_>rrc+u4Tycdh^Lr5>vJ|1-%4wZFI&L#d&oaZSVO#&yjtTb%iDv^VhQHLj_5 z(sAEAgwgijh&x1!|67p}KDeSqQAO(xt?r7uWjR#k z4v_8OYL!Y|w=}l5H>_`5*HqUsYvmy|Z1Djz9;%85&3wp;j*qO|yt%j-|0n*?W{R$6 z26F!oRqiI?pn8|LcQm$jG&CNy;t+4sT{9e_cKc^Ks6u5@6Igj3VlV81KSXu*%X4sT zoM{r;IJ0CVFiWm#I@C$B>_1C6RLu`fl4s9Bp0=>~9yOt9Q}aqJ?eUORf`_aLB?oT* z|5n0*?f9Qa`42W6Xr1moG5(jv{AW@Bl~sozZUdi=`8d4aQ%iA#{U1-e?o9)$XFg&V z7Zf|s8eXj&O2**RN$@fGzs(zb0zUM-o~Cmr>pL4bp^k27SihldT_YZNJDS=Wv5PQy7GQHr*@atY&ck!+ z{tL7J*BTtGxBS1Y2WsK9!M|y>RWc9ALt0etL+mXF%zKEvC79P64)f;jKOnFSrCx15 z=0M%3J7&Q_<*aI2(YXdaZ1o0gQAxaU#fr8jck9GS!A?_4b9;xobLFDi8rQFB>XOv9 ze$9TcmgeNYH7oPOHa(b3ktqO*g7*R*Zu_&2y?!3)E&+&}&s+$rG2ySTUi4UX?% zJlu@|Tpz@-J*n|s5wD$2;QQq9%7tSbTi|jX42NxA(fdE)&IYb~xkZj>@mYVoM!;b^ zU8{!U75GTGBmmcXlFN7lA@frfFAw)V;=yur z0_9?B+%K2!bb@v;ALV(Mr%#QG^XN}KfE!Wqi{rVGCa_Prs$W1@$X~e#tOZ@>nk0gJaB-H^-IdwE^E*1TT*~!NK`< z5J!2G#mlqfm~Q2^2JFaoam;tSTdvm+av;y^^OWc5bDfLx=wY5h1mW_?cnomFef{{3 zh2`WBgv-+}3|z2Ywg&X;@8X#6Qb(R&&!v#(=}LK?J}uqkog1j<0RegEyYjqzV<0bh zdF1aLoNq@37}STdczJd_+^yUT19ouEBaZpX5ut2PcfM=#;z;)G_-i+L*9Ght3Y;ge z(3R)eF~w7y!f<)yQ4Y?xV;UILhq8E49jF{`zjD#oN_#U_H>i?M!=4d0eN9po|o?kPjL#v<&i5KoNq@97_@`3czJdl4qVWV z_XBp|6{v5AZFRMS?<(<{*S|b{_H>i?bwFNOK%R2tdHMLQdGPYcc@ECEgYQIX2W9c{ z?BKV-K|8b$qxYk+E{^&B(#?*uAdl-N@ACAys++uI$YXxar{mzfe)W+n&&#*VQ`{Bk zk;TZ2xNiq>lt)>-JUjA{7_=iZU`Mr!W4@amd46BI5%Lby9{hGWC~ru>j`0C`yIgsm z9rt>Q1H;QB`K>eJz8!q`j3kY+czJfb)~(#4fE{%%j`=1+Im$-2k?VILyf_m)efUjv z(2nYW9TS1`+GCt6&&&4=g$FK=Jletec031$=;LBNJ2rJIcT&I(d>Y}G`?*`Lr#s)l zAE-U<=q7Jbz>aAFdGEXOJUjm6Demg$kv(w}MclVzF9_N}S-d zrwP6t+Z=g*8+-|Qo=wc>=`*F9yw-pnvjg(@4LWu8@^Rf0ygc$=2j|=IcQ9xNW%2Ut z;J52RJ2nUGz$X>H9T9w^LfM|~{{(Rw1-X}}&o|xVoep_JfZ;e_0O$3q;jTO{-$`D? zmFL;9&cXS1oB|x}pe$aV9nHW6?YK2y2R;Sy%YDC_9cMwFXA|XlYV7VN@8LjuEDgwe z-IeF%<2O~o%d^AA!wcfR9Xo)d9hAk(v%>-|Xvb3lJMamMZ%3;m&)0n?3H~}Y_ARO zggmZuy~|VMnQrpF4%pEIu-C76CV}$2d@p+uSDn;dy^=8XCG0e>Jn4(}!}Ct$~hfV`_*d7d47 z&In$f9e;Chz8%C-AIjq8+3{7ka)$)$z$aRM{f)x|Hf5JEGp=;V8|FmCCy(w<7w7fA zYT&p=^)9d64&Z|QpbX`%1&H%nC!E)AH@Nb==GqAcKHv2(Pu?}%3K6d2! z{q%kaV7;(RUY@)^b(42ppkB7PIOf}hMyGlFmXsII(8V9X-fZB4{bdj24FR6^9s|d6 zDeq!ep4YxFV%;6QJkdGW#6a9{U*edbvUquR@XSiE-1h@^9Pi?o?@x|Af8KZl@{Xk- z_wwXj>B)1`zlOYO#A(M?IM0qZTzOu*%|nL>u46rUuXdAH^ig#Do)nOmp6c3*G+r%` zN4>X_z~#wH2ChrLf;?|rp5o$|Z<-@d^Xj<+@`B^itLN5kxYL2d)ahSdxh-C~uECQ~ zF70K#Y=a|?`@_-$`2*}&x%0rS|mqXrQoVWEZFLtLV&t)mkoj8)p>fr07aUhY=z5PW3J^Kh(}U&49ie%?*q zv5S@VzE>zhPu|Df*%!g5JecFl`>C6}Wq6>zB`{Zd^1kmT?{s|h%=5mKcV0kV z3O4Y(JV@5;!;V;XM7u1BdErWgcF8pV76k zPE>rB$%|p27%hh%x#OO~{qL*bC@&d~brPt4E$2;L`-lU=y*zoC4!Ypho*vQ`Ll^Jz zaGO@GYrzL&e4SjdvS34D@#xXTql-(+Mn!URii?Vh1OBMe(wv+~qzpc<<#8v}O~X%1 zdy;6w5WoFc&Wlu7)67x{hG;ojKTXR?yfbubD<9>wTN7{FT6Wij?7g?=)c^dCfBjta z+n)zAOvno@A5vfTfRk$0JK?vVFwgbj+qON;ltLw^UtV{~qDTlzToVf{L! z+x&mETD-mK0k6~#s zec>s?z{lTYj{;>4g7?5CBuqxcI0X?cX&*dmhn_?|m;1@dS3z7jErBM+Fo(rm``wJ4 z>Vv}1vCJNl6%2WSqISk2G4@%2RF5Gnf<1uKd(50>864Xqef7Ey zq_y@ZYkNlz)R_J`bE*NFZCBbM3^#p<7D~**vr{MokummIyWF0PVPlvY19P&bXC9x4 zYDv=UT!TqgfvV~SXl@L!x#r+rlhZ1CDKNq=Lu4>HMWx16XC5ugSTi7A?|IL7Oo4He z)N$&BH0HHa)WF0vXw)Zhe$Nz@3~s!uBy3DDR4B31wxOA$A+sb75)G65Qq6KZs!Vc$ zCR+N+RN&=9O6mSeq)yVP1YWc_+MwE?YS^m@9k%y?)3oVurc6tuP$TpVEv#l4;Sq6H zg|5~HT~~UYb{SH`1L&#wM0hwII6ds*@`)qJX-7kV^t_2}gr9=q5%&tV1SI|ljawoi zjblJpKPD!id1Y<_t=ijG7P{}OwSvOt^($LCS2Y##?1EOfcEh@+!cBN%TzJ%mwj&FR z3)>4D+t%gdqlNsA4I5fku5D~ypI~cBMq}j zLwm<6%xoY~@$Riaz!Zd3tY8~kn>RZGn%dgdZ*ZWP$joCjQ`#&vLYZcosbbR1W3o-v zAIm|d%mR;_F5H5c6f-Wj!VGJ=p$g1UOs*M+455Bztd~+~_GL6fBOXV089Z*pzTG;MXuhQ^K{NNd@!eoc;eo$K41*Q{?^ zmBTxQpL4~j9Obd*Q~+k z`fSGobug_J`5V^Z>x9h>YnnGTX{$DL;@j|Ov2#%F%&1OX6rM42Mx7>FdKD?3Mg&B5 zG#=Tcd375-;NqJ+Ve;I0H8X1K0(H}+gt@3`)FmZqVuE9D7tF+2bG3;x=I7LwEXtAb zSDaH)R8m?rs<<>Kf8EN~&T%V|y=ilPV>#&6pw~BTSf9VTwRjY1Hd8(Z=Qz~%DkOBQ z?OeA4VPo6Mwc{{+H;vA39KNn~cze^z;em{6a`I=k=j3BdjKdUAvNJaXY;(7%c;3Jn7ML>jPGo2S(U?? z3)NXtI&^6FYQ=2Id-Bh?@C!x9CdMadS)5_ri?i|g#P}0KC+R1vn#Ue}1UF2%7r1=R z(lv?6CmW}PPSx>aLNz=v+sFx0Q$>iHqw{ODm^iB@tYY=JP`paTFQxWSJwutQm+Gyu zRJPGy4N$|>1Wa1pu3(Cx{q^S{JH$yYaE09ah?f-NEEl*!nCJqJV&FvYID~~bhcDh^6hT&u;2(>Avu8@O$c?99+G8Mkl$6iP?slg zmX{F)BNpn?YNUI2n6o=<>?g7Wa8^qA9gkf@JKgobHlA}$j1=k`3S`DQa8NC4exTp``qvm zH+<3!pLfGo-0)2|e9sL(a>Fm&@UL$84>$bD4GnY(md~d%hP~X7-+PcQc0)d*kmh#> z3>)3B%?(d;Ls{{ozAty_-3;-tdy5<1>83yA(){j+{HGWq-`j5ZksE&RhH+TNu-qOD z(f$KmTF$T||47mZr@HBgiahpr$}MMze4H8hl*j%;n)4(1(jP#h>4o0RazS6y+z%LwaD4^Bv{? z2S4IOO&{9T2QW07^C*LmZ56!8XrBdAxSPA@18j9P`uhqJF$ChYOZ#U{G?LvRvMQiDRCp z;XK)h%I}TL@{|bh9!ESVkM9h57N7Ds-aUD*1@a)OVM|fAF&O9NmGwy=&h($qA!ak; zULNj4(7|&5>8`_AF75Hk{Sk3552D%(ForPVULKEgc2HhA<}c1el*jv*ClCK_ql>&v zU<6kRp1e3jg7QYV^C9JNp7Z2!BgV^vWR1V4$olgxFN&Xy?IN!tAdmM|PhJ6V%v0nF zI0}<-4{uN*jXb*YZn(3cEc>{3dANEP=cT_2+%%6s$Z~m&2QFyuH0YOublS`Ny{8|y zrJ)YHr(8L>FC5BV@G{^y2)OoOeN!IWnPmpd)0SZzZAO}Rp*XpCuL|N?px;W537!`% zEFL*3Cvf?D!AL#OUU1pSlF~B4|L48nr&#HD1aRiSA=+g8>JL)}!Eyd$zZ?oT46gMq zv)P4ru6|pwOen!VQcq2WoLJpyj!qKvUVL8qznK5JbI|+k)`Je5Z8B_n_XWHgp)Sp*B zX6kicSjMj8Wwm8fcaGOzDx1VT?>%+t5B0BC{jd1KvUg?HzpRa@e{tvdArEEM$LB1s zCBm$~c%M;Zeqrk)CJn8x+h=QO8{gU&E;@htnELH?>aX#t@TK?m?RwdyD;}-hXQSun8B`*VZNeH9m3BOILjn8;Z}pBpm-^=$pK+t83Mdp&^5B zyKQY*{nLF|R(#$QpW)|jel+Iawfuok_nnhff8Qqq>mU3iZA*Mf&A#|}wJ%&TXP;3~ z1NZPJy|%=UoPpHDec`OR`;4p^a8G}tJ+%7Gj0B<%fGt4NZtm_`YknicpsK}kskTqyp&UK-1@+$UvG1`d&Z}| z^y+6SwLR;Pw?Dtn*!ujw_;a_9KO6O7zli_Cyfwao6~lGw%^^Jhs@UwqkJrv{UNJZf`2M*R@BAIoynH?gk$*IEhtkP> z)cWaI2<)DqX|Hj0=?yiYdWWs+rXVn^^A{jc;eG)0)~)11Y%0&3j~(5iJ^7T>TgBut z=@HBTiOwqvYsPTIM`x}hTQ}z{0{d{REECInaXzu>Sx=(O#Oayai80LUaC5gR>X0yNNVoIk!d~D2l3PTQV(l3)*p$dXLAHw(<$ll zY${;gn2Y$8{iM*k9K`R=W}(&&Oh<`(`mr?Yb$E$SWwRLTj9SE>=_m5j#v%TCFG;@y zb6VoNy(K*v_ld-hd(A+7ZFb(f*o<4Z5&voLe8{osSq5q%DLr*OLtlnQSel(0o&h7OB<0oVw-oJMYoKYgwt$(WEM)9Zu2!*C}pM{FX1ek4{@QC*>;75bL@E%&a?Rt7)qIM z|D9oKwOxRb5K2AU&M0Acj$I}6x%PYsx7$Zbc%Hpe!t?EWB-~-YE#a^1e@J+Noj!*7 ze{B~_c%eN}!i(&=5?*X?mhck$QVDn3dnCNn{*#2iv44{Aayt!uBb0ij9g*-Vdya&= z>~#`eWB*dZ>uvU-Q0k5LYZBgUe<$Isb}9yYDD`%`K*Brh84})UH%oYzeTsy4+m}gr zkA1I%d+gUF{H?tW{UVfluYIY6_t_6fc)$IQgb&z1N%){W7`qgq)Q9Zx5$ z316_kl<-B{s-~Qm?EVtIY>z`2pK7a&YbG!fuQDEyNP^1vKq7rqB6W;U%~px5#Q4-) zmB`wQPaU8VS#9yDLsX)ZeW*%wvJX><%%1%~F4jtEmGRXWLe>I|wX~Xig^4g{2@=w3 zQ+DHKuou$|zuixS(-Xkda?XkHZCcj4EQdP?oDn`ZrC}cay)(b43~ZOuevO$1r6nMJ4%{ZVW8w7FU}@7aWs%G8VlMW%`BpmnvtLeF!P}&-MlP*0_ZHftb6~V(f&1AAsp`M?!xKOSn!9n;v&19o-+@x5r;I z1|2;Y`(3M&@;}4fB%?NzkiTRYB9Dc747v#uW6uc*+Mpei@rY5FP{4$=?Fo0H=JFrF zY})IZl%74#9055eWQ1W)k4rG^^*Gjv|Nk|;cqwkaMd@Pi!Q%hRwrlz0(MFl&dcvF& zCL(gNk$%kc>F5^*Zy+-kCuZ|UbCrEvypE2wyH#f%q0A_0Lcul(-t)zSpUFh#v zv7|>-mfVV7!R;z-PAq$Ms87TmiFOV38D(#&XE@s4fpE|n5Svw!koN+HReG7~n~Xj+ zXdn{%7TKZflkKkw&OXJ?gLa|pGwf{=o@-w!;dc8D3D2{imhgQ0Jqdqh$4(;tLVKWu z7u#bcywqMG;cx7X5?*F+m+%VvHVLn_UzYHC`&|idu)mgYx1EfR8_K@XE|TyjdzOT^ z*sCSH)jmzazh^9v^1sh`oKsWw4;fcT`ad%sknpFBj44e2SH`PC|D5qH!uV`WWfYUq zZ-w2T_mqAs?dd`{*@sKG+U}HajeVwsYwar}Y_{)_@Cf^P36Hctl(5APO{JW5cAkVA z?MeyT?3EIB*e6TaXsayq!La>9uyDgcIy364u$vC9JoPk#M5D9bv(JD5L-AgxhRP zkqrwbU+p&3+FeC7+W||5sF!cKna%l68wh=}#ef&f;VwSDWeDprPov{Yw)H z{*1=S8<+3_`sU~dVSSAli2$5yvRF-KYBid@W-;J@r+#>V<`jsD43DpSNa%7&XEO> zbH23{bwz{KLhx637@aeUHuqUp^j8zzSG<|luKv?Wr^$L9Sx0ExaL9{lmWi95_dbLGtr z*WmW}Gw_Ou+W4E$ZEVt^yl;9xjqva+ltRUa4oUnj3H@iqXnYB8Jc^#uYK+0$d7SY* z?wuzXdjPhKdyqfZ;ICUJ8jFTwpT~F(oqxJ<_Asm_jK5;O-DrG;$$7JJJ!Eb$Uc~}t zt+8qdCS#*yDAw;rSuz&$#`XCy!FUusD{LHr&Y5D2!Lv~x38-ROx9 za=g(8`m`A*q4Z|saQJb?SCCn2?1dEt#vCjg#u>X|Z=NwJThrDV*P}|ajJu(8mGLfW zF~*pO+kcu7MvLmkj%lboBNE1JVf-2Tv>5%7USX_<%&o?=SboMEr5L@Z8S9p4+F3>^ zmRLs_1JKmU=$wO3T8yiqn{BMb3gnl@#n3Im7=zL$8sjG7+iv4~bf0Wv!#oT_<2>|5 z+jubpL){oxs%d8%Z@}tG<1EPUZM*=jI*hs$tXqsN194|Go=02uGtyA*GGh+(Jk!{L zsp?3)^Tz};V2%n6oMXQPOlaU-`*8{9IS&>Cm)Y+K-DK~RaIKw&whs+#wudqtv?BeZ zYKAM*tAt*a{;kkW=|4)iI$fa_2K@!Z-~u~)@M1LVkjl8TlhIvTJKD4%)%JyGPA#`- zr8cA{E(J4&p`EDSFJ{BB`wclpPrMgsV-b43G6qACUc0twGg^8R`bS6`y#S`DVOJHr z1yoAI{9@UkM5IJ}j*_#hVRm@feewL)2;(R!d`&Jk?H-XW2Q9oI4aB21vBrcg{Wb0J za`dAau!i5y4~El8sJZYo0X*>wtgM;Fe*!TH&H*eUpqRsN*zc_+vryMyt?}81McMCJ zt>~V|fOQ(#E5LEY=dk=?-&@DSG8XU~uy+wcLhC8qVl@K&lL_~O^PI<3laZn(z|)p< z#u_>ZV;$570DK7-Frp{G#`@G0UUL+3VOmdZb5so}bIo*rg<3&F3A~6_qg5f`MkjPRma;g`( z#f!Y@MM6DYaK0B==tWNSBD=lFYlvtGi{_*6FA0U7L62CC3ZdDGL&foK#M)AE6e+p6 zIPe9bPzL4-!dW>7g1ds}hC(fvC5UA0bwj$KX`#?wOyUHwW&@zB4^;Z3Q0N-WLWHya z4+M7w*M&m=!u&}j8>k!71q}+N{Tekv5F0N5`k@$PciRVq(rz*wIGgxDa942uP}3;74yA2CGq7~_j{xW}XuecL zB-rDQRrvnbk;icmKw|pof;>j46-yl?2TA~WPdDVzN@ksONwB-R^U^gK$bk8sB#l7lsXOCWm_fxvm?sL#ecC2g&&$fGq8XY*(srl!N4i5kO)k)}{0|r3&3~`Eys~rK3G$ z{wHYf5xrGHeEwp~z5sJ|eEt&4J_C_KkE4nT&ap?A5ZT0 z2S`oI#61a4C*`u2Sve>`*lWOQ^VsS}Vj6iD3a`p6FTj5%MZy_i|Een_<9<|m_;~9$ zG>AN@-wghPK87(h0zFczTLnGBwf(s9Gj}As@J?%TuBN>U#8*CEL@<+<^Sf$bKDILB z9CdGszDp7Gas`$gO!pM7h z1eU~isRY6j*b;FcC~N#;tk_Z6Rd8xAIBGUxTHZ{qpKnnKlw*^b$0mvUol0Nr zbs98a_LJeF*%e7GZ)Y`fJg5@br1exe&d{yDpyS`>qnXz!G2w4$g1E7|wXO(X93Ywh ziAR0Ls!jL`oilE#ZoP=^PF+6nS$W(7jk{eXuzB;crh|Azg{gG?TX-gj8>Z`1BIxt5 zA1laKjW9<~)&l_m%#Aw#o!vKJ{mW;^lYOcxO9B6A{a!pABtaJutWwC+ z>>~iS*c;3xvF~CiWnSMI#AcX%eNd8q22{kMV*`@cWav*;K^Pv7#}u0TG&FBQRzVDfPI(`ktT5pTdH5eyA+t4d>l9ONu`fK(`!A4qSu*6 zt1mH2aj1OB=am~HL|QRK-BptsZ{^Q zk$M|+Wn*hLr_$^nai39XXU1;@-rAmuO@p&!rcAx9!o@XpV$O;;Z&X7u&KTP7q7aEt zQHjt*iLl>EB-e{vrC#Fq7^@c9n$5O>^LyWWYb6hSL6ovncdSWvQ8%_HuBqgHwzIyg6(iDJV|{&m*dk1IH%T z5%7(&F2O2{`F`0ouZR)>qE5o)SU8yblryPCD+6wP~)`MB!In}$u8BVe&^?S|g8KwXB^8+-vr zQe&~WMUUWyPsk(SKIbD^iEzZU>eh-yu9%Mj_|6AWjN+D))>AY-M(2MtqOe3vdUi){p3;vd#J+P)~bEcR|EurSY=4Mn`cp;7{QH*~2KQ!Z>2gf9Y1+ zI2UAL#z}>X8m>8@^pLd;nMKkF07m;D>ZSGFjOPw>NXXiN8dTH4Jj@43S7CFzsD&YG z3Ob@{2jX}iC1M6#&inf_YFy!XG~Y5bo7o()QZaf6R9C~>?d8x0?14=4Ic05};DOsi z7I)u?Q7^-LgWwZb^u(t1tK^@0Iimgo#mI~+O9Kg@k&EKn{ zarx|0s04F+$SSOHFsdBDDuPAQfSaqpe_ln#``}AL)MiBYTJwGb>i#odQ>nR#`{ z`Xxp;3sk4UJBxe~=J0O`S+Bq*$$t%aHz$#jedyfcIRKKLl$=^LHVu z74w|b$;aS*8RhpvKJ)h>ONZeiKL!Hh;avH>2ZR3x^1~?M4+3vQlz$Ey#(Y0y{eZ@o zR;~wcT9nVFsrfPF>n?vacr8A^@4OQ5zYST#X2JH8kbX9Kv|Z*G%>l$2)-8odqP2H) z0VtfISR{zJfs$o6IF1)ZCngJrAj_WcZj=^)wSBNuEmHTP|b(8yjzZ2 zssVahjsDKhvBj_=s2~E>HhAYT2eor6p?C>$oNQR5MZXEeW{En1yc4GCqgE%B|5+Q63l=2fM0M1 z=(~ltzhS2J9Hl1=!MzmDu|DHLNHG&BON3XiR1U`a=eBhcJvTF;`z1i1jH z)m@QNoP#{sv_3)(L2d==+^$HO5gp{EruFeu7kL9v4|PRGXV^HS7ApM9v=(`S-vo4T z7dRd#3F;kVJ%e;9{a=VAq6VB!BNoxq`f?ZFEQztc&qcKi0HV-G@m8SqU5d4sSr=oy zggc3<19Pee(E7eK0le#CtXJzHxe@6bJ)X0Ca7OQWeAv4q#@Y+Cz72@;x}dbaBT=@I zsLWM;0Jsj!JwAX-4!4Cna)3(F%}d#}e-FfmK1xiC)=}S+O+b&<%~9yB`uBhtc-{|; zm$;L$8a1BP%^tWLaZ=E;0T|$cw75G^E5<5iwqtUkaJ>?|86My15l%b5heWf{vOY## z334qGHXjK2A*?jlTGl6+aHy+(9#Gtfh>lYw?{U^_L{Dh9t`0f4hXDz!#?}l*-eaxH zFym9oo8sL+xG6 zW99?6GmAN+!JpU#qXamQGx@ca0e=bDNB9s~OUdF`Aa_{nX5tkp*k^Zz$l|H*-(#WD z1IjXCfqpv>kHX0=0|{rBA*!CU%aD%DX-3U8fMIUJ78D{8o%oOL?M_~T63xFRz775|Pe7g*NtB$Lg!qVQHvBKY> z_ZF6=P6NoK{X-!}lIrq*5QIYZyOgJAlUx37G;B*p-F-4qK$E8nU zL?mZOp6Zm-aTgTWvp~G$WzsTulP;{YKANIw%&R_!_chrULWY*XMONWtD}uPlkA>n% za1Q$yitDDr=~g{vZs89Fuh8eGG}Ou75cawta(oD5c>GhirDoS+jH#k0;!gt9+KbzF z(X$Es{7Cjsik_3rG>do7qURH?g(9g}Agk;xjn1k^R=mf&5?Q;x$9x%ML(3kIshjUH z=R)c@%0J+HOk&;ln2X0@Nq{o;0{a&@orHRo<~#2(k4D`v4L^FI;ny}?z?%ek?=eq+ zQ3Jp#^x5x5+3#6bqIGM*nnCu5;5g#F_m~gCBo?q5>=sXg{~q((VuyPQI6FM9^B(g` z79#I4Td}nq(Qo6p!lm@fekR=T{sLT>2U&{R(q97ixJ5AMxAJmm}Ar2~F zZ7h0z#?&K0|>nNl2n$TLrj`#%2_G{xa z7#)v0@^xwCYvFb%S-Q)Tx7OjK(A!I|Hz$H)XoE4*wet}jLJLBgRapz}4WY3}I!77j zs=-jkn62Fhdb?UX)463qmtp7;k)Coy#JV+A(?<30^$IYtZ@@e9hD0E8X8|#w&yz^V z{uW~;GZG2cLcj3CsQJj~G{&{uh9k8|nP_H&pDY8TOb&2_!;?AC%F?NGeE9wzB>Ip@ z&TZJNMau0-$eymneg^S_sof&bVg!miG6fT8WL)@=ff54g}GG2)IaE$??R*2;A65Jpo6NE?)zljkUsS_eI+=FV>3y~H6kerD^@iBsORwXBp^Cd7}vtpxXDE}#ZWCni)B*wXK3HGk&D7}BCMEJEpl-26b;t~zkvsAmArf;NR;<<{m!eW1fp# zE_pJ;xr0Dl8^^7jtZ?pP5ZCv;9ygqv@WVYp?C$$IhymeCDf;Gw??DU+?;Qi;me^FZ z&xqWH&J|kZb`f0!0&3nNYL{S2p2$-j9*HR^vL|IQh}ztS76`ac z1WX9ONZ5mtXIl8r7zL4s;_{%|tnjx9ARbL^MP~&=3`VRb13m-ze>K}kk*gw1m}FU2feczyC!;=tR3pp$SU2uYZM*=5nZjv zUV~`T#hAS#N9d{Yp;XdasK>~Wdh&TNz)0$i;S_1nd$P;rB-Ks>wN6iB5fhSbgviKx zeFSP*o0N1tZWNIXdhf}|H!JB!+S;mTQ1RtSmsf$>=um5uZiQ-*Hiv3WIuVFSyPkX{ z@@-D~m;4xIVq_n2UMdT%l4d>G`T;hb9L)fSTyU`>N`R&)a`i8$z@850+69h$&=z|$Vr7MBK@Oe(m`TpJ46%PCg!wq6q7W_iUtq|b z%%LLFneNb|JsLL%eLmDpRK1hXhOuO<+=_9W7%5TVlRzb9uvSK@R1#X!)g1k$4i%Gh z9&0nAQpbW7uMK9vPVE&%YuV|9?xhVT&2A^O<hkUm$Ux~%u`Kv6a|nMPVyBcW_TI!BM3 z#4?-Hkgzz++Z|6}IfBd|W+3%LN#%Jg#onixkK@)=wm0rfq|hnx*a8ke_FN?5h~=Z` zLN?>3fxBzjMS)+6I~S}h zB|IJlb9l@(OzXG17np?(ljp;NO!HX^{alpdnK4J7;Xhy|Df>cF%@3G;X_zPS+KG@J zN=lK`VtItkdgy^OjopG@o5Q6>-ROArNja7#N2*>XJ|~W1K?q> zZo0W*@-ZsQN*xpr+C}wq0S|IA$#VcaO6C9@9ZIowEF0zUcq%WzGdI+McZAeB59&Ez zA4#{ArZs=x2mCG4#d(0w(T??^nQvpYR(6cECC~IlRRRmkw6bG`#bbU!)_t`1I1$K` ze?ftT7`5HhiSU&eP341~ zyGl3@`j!t7!U%7~4X=Et5aICI)gXom5g%THsxBWcL~?jCZrkM}gh&r_RbQSjL}qv} zlr1k1A}f4(42VJ@a`5#%v@v)0fW~J#!vU&@F`Ah;9jV*JdVXpWwO-K}&D_E6a=ug? z&pSq|z~%F27s_@>ex8HeFaM*Q&f28Z{;<$#PKilnIm4CBXND>1QbFM~pb!)nhq+%xjYYyV~N1jC76!2WA+LzkVZ>n5-cpGw*VK2LA%$6rtWZn1%mILt#EMqxS#qZD^(WvKDk^U-W(xkL>&0E!Hm zita-oO8O3+Mvcvn;~Ux#!ozzzVLvxK*A4lt+BgH=f>IbWwy|$(inFoO0y)m7f0Hgj zRgY~NGzEohV=DJZoGpRM60~yjPq2;q@0Ewo#Ygjhp5#(ZFmWS(dDG$T#oD*?ilHvG zZw}7TbPRAPIeI%b65)4m_VXw~b|1%%ilibzb|1%%jqF3A)-AAhY(?ZJ#It|os%Y$S zi34Gw^)4pxvB%f^9U1)n3oZItOH+0+D$eR@w4m8`sxdjp(%VSkmI;0;jOV7TBBS?@ zgYnuHimBBQ*~0oIrOg+9sllJ@Wx^@ooa1rT-Gs;sMr){1(t^Gk_m5P_n`&4up{o<9 z?uK_ibKECjeyU;(GfI{d{5hskYnEY+L#q;_K7_}|SqB_<<{0qj8`h0^_;3i>Rftm) zoTHq>Kg_TOfX~KOdEgazd}oS@yN89WG^`6COoU7VV1@_M9R87pRRq2WSqomf$9IMB zy{Wa)u-=^Lnsqh+7ZOCX6l2-|?jc)4jIw#O?Rj(@Ym;FmqhCm|4*~NGb4WEyjyV3Z zvUQAMU5~qql)V>#zYr7^8}}X!*lJjxV=fg*v1rJ2xS*uLlys_L{Vv;;Q~*FZK> zfcDlIhBYS+dur5sE&z)?P;{3sbr~k4t^Ht=O|8Zc?THO9bvk|@i)D;(b+{Abe#fzPqko!?vO zb=VfO$&0N<)y3WnueVB$HxcN`7h$Q_+emIhGsG4H^Ba}j3{hnj!@@ii9RAxtyc``N z&vf|lXbj7Wd?AeRKFFyk5F#8tEDJ=T5b?A~SqE zx_8A$A+o~1M0Hn`3Xv0DfKgfz5n@1iIp*hzQDHtN4GC`@3}UnpL&Lwsq*75P#IW#c z^r4D!A%=&`F;P~G5n@F6E0|a@R*3v?1BP-%g%AbdTS`ET6QVH8(-;+%LKKD1!YHe# z5~4U9ss>RlL`nF9MIdT~7#Y4m2QglV((um_5Vb-?H1iYmn~J%X?0=vlrL~-G>*3c> zyLm~MBRQ5QuzMTE^?#jLE~-;giwb zDhJ8}OUrF*TBlVG62j1|Pk^Z$9Aai<8FnY0OnFY*$uc~=9irSUBZNSfOHikk`JsO@ zOLArLOR$MI87E6g3VWWLWuy>c&H5wSv9dH&2$*#Vx_V`K(t5;W+u_MWH_wF2H|)-b z?B+nUXyr6nW$>7|;opoGwc%9vXM5$2<@HwQ{y#d4$|ey@siCV`u;ml)I@@ zEu_v5a~F!o%cDig3eoXa0FGZS;ytu-nZ*j^33R7H_<*UI-=MWC8>GMSP`WGoa17_l zBg3pd9#K~;T0DGNfI(NePE_Qnb;;naNn4;wWxK4xc#z#$h4~MDnmKO@_!}fE54d;d zmrq28s5~czhu-C+a(6?9A3?ymBB1ip#NXLkN z#j^oOQ!*)XA=MpVzRy~?N*3!}U`6>_ztTPbn>sH1y4$TJ}gA@yZSAw0{=_V?<(?{ z%Nb10=xe9}|7+nt=<^xVVi!~YS-7`U{Y|*0EfJ|dNh*IqA*#Ptz8;;S>YEt;pn_9C`HQ`f z@>C3eTEQ_ycCXEs(0i+%78z%CVL8(bt4tey7uFk94@*UvL$QLYdPKIz`Ev}?D4O}x zFr@AkF;6o!+DZkpF@&l|$!{`Tp;l_uqwSl~Zo_lX-)i2&;TFVKFG2jTIGlnFMwNsf zRI^IO!~>n z|7pU~cEBnA6qt6ET8aUL{}m$ZmD7~r0Bvgo6>mYuB{4L)(uq^!geN zsH+o=`8m|nz8Csjt$tMv!(zu;{8srQl)CVTc~BKyi#@##iL>BzuK%6Sa2GPe>5HA$ ztWDsxdVJ?=72$t|yEwC)3f{RspGW1iYg9YthHn^E%P33Ls^j7v_?>`0=bVrI-5EQ6&s@q5=aMQN}l22NDhGA`%tNM7o;LQSLH zsvlSb$rdr|$sU}_Ef#Vs!Ejn?eIYUw_sB+FaD}^&3?j4)svi4@{vr&K%4r2_E1Z-k znH}JUzh`LL6Fp9b?#71uA>+wRHfC6}sitrfQFC904pzx=kJ%8KjBHByxiuN z4S%OZ@yATW!}oNkyYexTT|QN%r^U)X)f#lK^0C6IV=j7HEc2SXD14kuqx^vrXP3?V z2{m6{DXE*7N>7V@n;BYQZh2KarEm9HW^EEut0h%_zQfIcK^S{~0(vaHp>KmsrWb1@ zqIZ9R$zp0o0!M?j7ow*2k+@lewdm9VGF|Lr39=RYIAWSviBUQ=-`Veoei&gWSVQLnTHpmZU7YIjs!SV!3CsTNx{n=~F}#t1Nh2C?_tYx02ol zddJY)M(=!jm(klz?;d)O(R+d3AL)HU?;CnQ)3d|ydeY0IS4eLxJ^mDH;v%S&*hH_5 z-U;;1qIVI!Yv|1-u7Tc>^p2u;GQD%?T|)0#c$40&#%*9*%+0u+y*(GbRhA%fENQ{t zFvHI{zIOq}2~)o#TR6k(;x%n%T7r(rTwYt7FQTGmJs=~cFA|;U%{+4|Qg=)0NIx}` zCu?g!hNi+x>oFMHv1ksh4?jE#U5GS)=V<@WjI!pIV*biEhCYleSxc7+Q6t3caUcqe zWchL^lShL292k1hE96?_7}3zM9w&o)^E9tK%iO41SI)$Id0x*aP#N5DD?*;p7(V~z zTcxZ=QczT_k;f5~bu7jmh_OQSLC*LIMo%F`qX|YnHJZ{v&P*ed9IX$(h6?e}yuWdg zHC5r3QlYX0kjeA9tHBQ)3r{NPHDnb16CUU(tvC>KI(*<^^YEU{&iFU4>!&r%gn!L>BvDQ$2aXaN53{mq$E9p7RtW)M;(3&SZ zgw}_fqoL!x95}r@NDk~~K7(dFlO^2bmEbmVD^7At8#oQVbC4Y0&fJM1dmr(Sd-#W` zQ6@LA_(5Fg^I*D|gMF-A*&pkpFgb-X7qYh96TXh|!}Q*+@vS@vT6J**f9s|5GhAeD)~r%vnCz5RG0zEg*ak%S8eBSar0<5O_4$|`Cvj1r zW64Ku{{YkZ$j#|zhf5W2v=1NV9$3CfaXE+OUJml=h44gm&bAJsibBsU!Acw9RJe2^ z(}%*-GI{)bF=C-(;03#UD-NMYTQlL=Jg57AfDs$I2-pLCSC<*VymBq2-R4PK#>$z> z52yctBwq0ta%$(14cMl90M*ZA$G&Ntm59$I3hrigXFZl!532tBUVA!HYT#~BNQv~s zn7dW%I{|4&!D(Y(Eyl7;^{mRpjvwfYnf3-Inx|9}TYE3)_nDT0x_H`2`vLTKOq+%3 zddA6{38L%A3VZi3#4 zkURZp>UTdp{=2mhoK}6Z3sgk&0(i{bENVMA{68jXaHH6ziO@Zmc|<5VhFv-b>})vc z{83;m718+;A199(xGavR(X z4ijQ^Vq-Ww9z^o}#BsnpjmVR5xJGhDT8@ZnglD|3`sW`8)MTW-4g~-AdQ1g~FA({J zL?H+bP4G_={Xy{G2Bg3ZHT*+t@8WPA*f-@=u4AoKL0 zVE+ZwM{onVSa=4h>J-YIZS+n*11T}b!Ruwf3b>e75c!DkHC*W_zzt-JF_%s%K4SEi z)*1u;C^%^?{;P;-aOrF8#as)~3|r6)5x~xKe_o7Wps6AB2-yd>^UmQs(bciywf`18q`^-y-r2Tq$u< zi_E1Z2KM!_h?K)gEfQ-GE44TU$@Rps zuOE)cGC2PlnT?)x4M=r8Jj2q{7hw`eAA!`E@$ilWxS6>lAdW|bi<(km2cEMW{S6WA zE;#cvl@@acQhovcHfFd6#7;ymhD*N)#6aGnm_ac^oT>MWS&x)!!M_?Vh6knZMPv^% z@YXexixg(inIYljya`l|OOzNMZh0KI$Cz;kh&K><9S&cj!g~aZYfO&%QHbM;V7{02 zIMR#`tpdw|Ouj+e0(l`$hjM>(RxfAf;Q^TGeAy-Ga;Hn?^G%;k@It&R_zO+{4O!Ne z5j-l6GOL&`>**8_qs=mTW0uJ?SG-4rGM2kCxwLTBA8V~_o|OX8&Ldcbe7>E+8y;=| zsl4N9nIi_`wt$?Wf?#$nlLw3|m|pLti>iJ2!zm%Qj=#2&8!|_vb3;a9SZDUov!Y9_ z9{PALweC=H8G5|C0O=#I(;q=LCxfB)k7h9RLcYirBk&V3m9k3h!*BURe?|^}6)}d( zd;9Kwls<-?$G%$@#9AhgQ^lcIh1dl}LsE{0e#LJzTKl-_WU78xvopgic!F@3ajlwp zlIqLfNDy^E40RSYJSPx33us>*e{nA>NgNdr#bhN3LNs$e0?6dgI$X@sb_Gk*GI_f5 zcBVh=rL)#i@Mg_SHM8aD-7NlK#${NI{1F)aD-TF@(;l0Jm+wl$^iKhQ>yQ0Cgysr# zZKAbV`~f27?TI9P7(6kR4=jPa#5X5n;3MSPA)RQg56?V=HXtf?;xW=`I-GAvUjqTq za)kzB00}K~C)St8G2i*{q!cbL$D9OD)#h;(I1)1~G#Z@TBbiq*uRpuz zg4GXBX7>_AM!?DJPOMI>%!o|vs~zy?=-cNZsiHqTZc;o6+2n1)4?zt<8uvFU zsu4L3ZMHYcjI<%mLIxKMRoPRHN2;Qi!AOnjg|wImymO$#*>Iz(KoFpNDDzLcb+=lA zWIbj!{ELCQ5U!d7o}dstUgrCH*7_z0UV5aGs^+-vtC@*UhLPUNRi06hcFzttLHm<}hm+B8H`NbpwM50Sobqj<|@ zKILWhZ@a_59zr~CyXAsS#21;^547WyKtgRPLfR!)@X`My~EdPECyAT($|^4mi1H{}RF1&G2UN zFfC_C_Kgtxgnz5hX6-^}B#*rz#KL`EbmqKA@pq{3yIBNM75!`v*k?|cDV75Gb9ui( zxC<_wXsr+5M5rebb>_*zWt^;9IX|fp3G%*SD&J+iOE9h&IJNT!Q1Tf34dzyE9G(ET zN0CX<+El(uNm+{+E;cgePf&iA%K_gBr%inqz%edxhyZT@B|uKz4*>LAxSCT-G2N$9 zw--P@&!lbTP(Onzz6J6PxC&0@9KENm^+vWqkl8rQP&~_mHTXlO6)bX== z-tAZf@Y3Pb&JMmf;|1X$e}st6+fd(nem!5EeTn2x;qFzd*L5JVm8%_nd&e-X4?oZi z4Mr3DcP{KUHEJ=R$&Cwf+_*k-?pyaM*-O1S_hFRHW(>_lKG{qKu2q|Ha}86q`xWb! zFN%1LfKxl!iDGU>a%?Pm0o?R^K@38qKinc_NFPr3{Esa1SWvnVk+c zXF07R9v*A)Ss*M5WH;MR@kg9m+A9+bel zv2vIiHMDTsNeT(Hxu{UOMsZgwJsV5hb`(qeb{x5%`jk{^tNG}#kxBUNT7H8%%15QB z)ELjq(R#N^FYDo&S{_uv>5OCCmUK-TE8655?81}10aD?VM-9eh!IrXIR8OT_J-K7i zJh^?G{)Clg0qT8yqBAI}51=2V)HtOmr(xY;I9^BVRG<&nV&sN7awoXz<_=>KDNYe* zs$AtruM3V_Y4m#EKB&JQ!dTcuNeqw4HDQ#~@d5U#f0Ca?`ks>o9mDOkxoW+%;gn!2 z;f~^r7}k1q=Fw8jG*%?%A=jMgrO_E?hF=fpjJfvW+z+&cxfoG1gX#8Sd!dZLSrk6m zACR*rX-;d;iFUVNDAd#3uBr!&n&)zSlRaza`&qhF#Y%S)Ti~;$GQ9D*&`D+R<**2a+hjry{Q@xx9I@~}PU)QTL z*OZw#I_&TPh&N+M9W8eSpbO>h43+05IGyMWwE(yHXdheQ_V*H~y3(J_(7V{P zR(ZmsJ*%QuG;fnX4pG^XVfFqQ#N23}H3vfIj?rtq5m&dqI%D>9 zl^f>W zIugt9%Yj(Gw7LW1|8RF6@NpD(``^CJ zf9=zEXLfda`OR-;ch!F!e=fQ`>l*|?){jj0n>1rCy4DmcxVPhbkpdez9Hxhdo@BqMB0u%SYsC>e1aMb;$|wti2)=4wI&=!-{wa0B-I#{ zsd04jLeB_(iaK?Bk$#@4{4s-)txRrZJonnkmnGzK?l9kWbLT z&mymoa+NPr?DX@CIeB6mPvS`aJIJ*gKqL< zH=}!VAFr6aRpHfR_V$RpJKSu7AM*GXj}^D}%r}w`-q?W>wt_6)4-4t+Yw-LKH9=SK z{5r(>j8Lgw;0~WU6cz7IBlGLxH&Cr858dhWb~H@jH$AseALj}s-cILk#AMTGy1oaV zRt@KH^({}lG9&Q4J`TZW_{LJ^x-Y8`%X?CTJiaQMaaFEk$3== ziE{me#{WfQJ4)GDoLbDCf@XFLgXiEZ7}gOe=Oa^nn*&pq;B3hwKAb+{d&~#JW4;Ru ze4HlX2%?_j&`l-2!viI=d`AUlRTmuocA)w+AI{BPhvTjnU^1>fcTDlE4@{ZrJ326R z7S3kD zBl_ANX>E_>N{{1)ShOAM+!Gd!w*jP0=1#ae6ej_!Hg5`~PJntXaE9+upATx%zSqa# z`j}+}mDdK2J;8S*9DTtD1NK&?v#L6Tl|QskWX}(LIycv8n^OkW$aXsPL0xT*5U11u zr@*%nZ-KeY2VCa6+&8S3ai2YH=xtBk`qT*%6VBvop$fqG1@*GIwP-3%i$d4kX$rz0 zEMhie0q3&hL}><>H3WAX5>iP zLHcw()8yWkKILtQ=ob75I5SXNx1#phTAH@pWGroI$ufc(N|&}~rd=LkERQgXl(ePm zC$%eSOV>}2WyVjB8743j|P~WSxD#lgR`RuE*;#EX8`>L#X z)s#B?K?292z{g$Ay63el=yGU_1q8=ezzaM=)F2{N?7Iqvp&1Pu;qUfc8yFGs_W+R- z+%~nuxSJKiezcFqT^p!gpfgw(aUrP4l#)I5U%Jtj3GAKFM*ImlV`v$OOg5OjA8Olv zGt%x{H|WgOay%$m8DottHb3}m_cp3rO5-Ki81p>vTYzDBjP7xxq zIdd2L?cLvnJkK~)F77UXf+FNL@*4r@)Sn6$~i^6)7C7* zQ07KN{wziqHzG+q4F->QFs7xAyaAWa!5@F-k}-NN1sKo1u3V$3HTDu+ArHKMxklrc zzlhD0sX*G?Q`&_1hlAL^OPOgF=CQ8E0QXcJ5& z+mKL?shA9+Pe4WT>%gplir`n#EM2TlU!02D6~!V1gi@pMRP1%fvbM#JcB5muSR~r( z^vWL8fAcV@1gZMx!5witF1Ij$4}+a6sRd~RPf%|IrLzLFs{;!b8_57JJXglxE!f5w z3KSJN!D@3JFr%>(JXEHl;y}rmz?gAPkYgtj87M6c3|SE9z1Wwra?Ov)NnnH%WElqV z-N(&mz~Kv?3pcsvB~Fk%6C+ws>;#!gRMtRIX<)>xKsDCpJvO7J^|dJu)UFAv+vo&W z=&m8d0;8q}@Z5ONwyHoNRO(PFai*KUMdojT`5Q2Qxjc)!HGhYgzZcre*b_Js<>z-^ zM!^*L-Y*^O_;A26e!gU)v7#x~6K{+qo$`u!M`K%eQ>>yZ(V28AT07fg6+OvRvSM3j z;<$>cieyE7qP?u8qq{8C+1b|ES|9HytC~|jr#umBt19bVFfTfngmPc;3f65hX;HD> z)PE_Yu4Jms(`)oJwYOp29Dk#>ODS*c>S8a`))s5;E^p)YBo8#7i4TS1tM(Nv-y z{Y=J_#?FppD$(7T%2;)G#5>}tczs*^gjkcc&hi+kYOe2YOGQ)LyJGYVeSI{UYKnKz z8w^J2b9D8M*1%4?aT~hI1kZS*;$kk$oQa4u$6IhaI%k|W#=6iQ!lj$asB39sl&J4$ zi6x_r?OoQ~*xBAypNR1e`Q~6e<#sj71d@#Z@uqJ;onqLo!w0VagC$#j4U(A6JOYor!jQ+iYGK&uxO0(o_@j2ImmO z(s!U9u!^fnAk&Y716w)j6D%1xHWdP=s3*)+d)9@li8W)aYKnGtsjg<#UTD>9De4a7 zW8a$10<_mm3EI>4c(M^^Xm5#BCq2d)t5tU*5krlG1^jhe4KLPr#e1zYTb-gk@z^%z zoxR_--S${}XJUIa5lePGdGkC1w|$>7vh2UsKZvEEo?x2Zlz zI-^#C#S|2py^6+dN-vQx)eZNubHTO2*z?fP9dApO#XA;L?y*U<5p#ljn}-b`^NjWd zv2kwi(9lS5*rZ@EbWm_a$QQv$MQ}^V7c2;^gaqhY1hET%nSi}-(qWL10tLYnU5{oN zk9?uw!4oG2eUmY9#C3nL!oB_&zQ0i!f+iUD!I`e@M0hzoh`S>8!eaNrG;?8bXlQWM zq(wH^^5C%0K0*HoYzeWE@JH-vdC-sO?oHcKZv2KL>NA7OO%hgxBF4Jhx?!pmk2!8| zlTC1Ak#rOBAVgS{GVGuEE-uJ9BXcR z2dZz}v?x#%tn}ZK@I?ZH5StrMJq)p$;J?aW9>7kskpH{*hI=>|^#AxIpKiI^chA32f0VE+$K_63Ukhcm=La6kW_3SbP5^WS)K zgbA7Jf4;yM+-INQ+=}3S<-y=2__Gkc`u#5!Gjuri0n$q7U_dQgAftgP)d*f&mzf`%pQ~D{P(H z%X>>C=<^R|yYX*7EO;32M9ViV2zLxez9RASu#AX|KCB$=b1oafVYZBZF$g8$f3C-t z6q<(ra8~pJe+6n($bW-BlAW8VJ|X|2a#LegM9RzI8fMfShU-6swN_R5p%7Yu|68ow za5U1S`G>tGnWhb!Kekrc$h?S5@IQVM-50Yo&O&76*Mleef_sHV1gA`5Wg1exyNZP` z-S~%?Hd`9ah!vjR&GdD&C4E0b3Le;+YoDsci`SO$|1OOLux^)GfKfExvp_T zv_|o1 zV)e$CLtN4EN%G@cuTw&X>8sWZ^}1@ z^&4tXe$`P(Xs7~6c2~4vdom5TDNjr4csc%yWx5P3K{igTcb0-tqm`( zg0Z=)GYJ^6k#ar~y@=I&;liG|3m4i7J}Z)Kv)JjGtGP=QGN2P}Z-CU9LinrQS%%`0 zZ^g{Gi=%3xnyQNC)$rVUl20Q=72SY_6>B^WwLi}4-%+#GZ4au(j!pMQO5=H!;@oD) z`YD!rdiFz+7EQD*-nbpMsG#kg9rVuAT&l5imXk6`r*&wiIlW5_nrcl|C1Q{-g=DOuT-G+@z*DS9=5LvxPEW7tGHK!TPe$H$bUS4^eP9VD> zR;1=wXS2gvRW%PLRNszNyg43Apy9Q5_MqWWuBG?QZS^h5%tXx!;yIOU#$uD2Xn5vhE)xf zH8qVr4X6iAv2@3i>Vznd8EKMFlzzbQ{4OFBdgHfjBFIDR^u# znq+-jx1DmCjE|;^5S1&QY+^2J*x26fFiN%$Z-^x*U&cHnN|0qOAB%w4TGLs8j>;0wp%j^XA1MI zgXo(#MA50Eig9|EQZJkT@K<#JN`NEh#xA#?>P)cFqRa2Vbh0^JE^a@bXUtYqo2JjZ zpcrZCh_*GEYFr;}iYLs#yxrM@gwCr^qV9FnAZ5AY1BRm-2Wp%+nuaI9Hrkn-q}0)W z?W}TZXMSxy-3_DgIvTsM`=K$J>_UsfWET1zrvqaNG~P7EV3LZ&TT5~p8k#xl=x$@k z_S1&Ew6YdED$_@SOe!ikdI2gUqxDTqoFSWL)nw!_tEJeJl%cXV#V~d6+@2FpL~}LL zWqap%M>3Yk9T(F{nTsTQ^=tif;#F1f&#hFfE1y_Ht!8U9J|a`m_T9D-?QGbJniuV7 zNI?y91;U8zsRz}xvtcp4)MYby_zu2$48E%wuwtr7;UzA5j8a=vW+g7J%Te7jf zqdC)eu3o!w?RwMHJkphIUuf9TJ{q#BIem;qY^_AsvL~``j!3bVLT^=7rp=iC61kSA z@C?yGgA8SqXj6Tv9=D=P@9f%cOcYw?8WA@Mc`Vjwl%&*(b)aiO)rE?#qf_;NK)EnI zCqSaJW*o?lR(Qukvf{fP$J^N^@r|Bl3ZTwBSHhF34}y6rn(Xf4q=Ca~egbVZR9~Fb zn4BLl&Ze9+z1VFNMG-|HeodD=x%GHZWXz;VmIxd{S*t>kxY;dz3Q4!cmp)ad8qgpN##DPf-Z1pr?_m@ zm{uQaG~-5mFhfZyf$y`&>YHq#CF&b7TDEYVGtabFH||O0L>Igv(*;|RzZns2%rk$` zxo%)1f>wW9x|ih;-TzpNkxa_sXeWhYtNx8PbSJkviB8OxC~Ddz0#r{f*0h;~_d5qz zF&jC_$ifNK0iEga)eYFb+Q?YwXiU>i&jK4c3$$&dp9HWVQk}U=5}RLpeaH4_bG!{}Gmv~cFoTKOWe`>b+8{mnwg^(-iADaiB+l*nHabm}qX;xX z`8b+rO=6vmZ*6Y2D=*Qd?y^|lVB6#Uh`9aB$~9{?MEg^HY>Z-Lt*M&Z6mLdgTthIc zAB@wo=!O~$xQ%f;ZBiW^sL|Pi#6V~kiV{#7L3-J4B-*aF?v@rTiI^+VRcn{8jBZp- z7|7Szl~E{f>OCVcJwb(YCnqz~XEQSreLo_T>%I*6%&D{$)e>0j=ybMW9fb2jb3$>^ zb$pPju<5WHI9Gxkf+E$R#$UI3lY{9a)^s>+MQ(S*&3qYI-x%$wxAHJYR*XN%D3;9{ zv2d0|337sh!Pkh>m^yB2s+WesP9in;rl0j~?4P%@onpvtL28n=r|4!T;NI=Lx4VP0 zl~_~6mKIXl*`4pGBay-B+}44aC1%YO>yy3B3G@QcDq$rJMr5ARE}_)=5oc=_xKnLt z(%_m(fwrC&=pZp&b&$NIRV`o)>S&3WKggB-*8Y*E#_nValWFu?Fj(-~QBO zuE=L3GTSfrGo#Cv@6xJdI}NmxeWRzff}VsHYF`%_)qooMfbtpU3XR91KC4!ulsM-# zi{-4e^=;egwVVx#)m-Xm{ZS$|1r)q=Y*%opC`nQ@n^SxtAM+)1yP*si8Z&F9SDH;pA zb!ye~>RPI1yDD@RN!?+PV4-wb53J}~yYYWD(=oC_p0U_7k%p4{?j`1a>wn*gaZW*- zDfGa?rctjnLqL-DOXC$(HteB0@F`Qyh0NTcS<_C49(LLuO`xk|x6o{)Pt&q7{!lvw zH&7#Bp}=WxNU+yPcdcvJZLC|qbQNk(J=8)SZB}S;WfgDH^`9gvI0g`)t(wqwq8Mcy zwjeutCt};;sI=+GtY5mKZmsHU9;ycPsGP4IknRF$!i;=fPsU65h`k}`T%o73G@>73 zovUxk?VS*US=HH!%`{Cm3o$OBhwf#6%lhvTKFye$LfgR5g&v*xtnR!c)&eQG2g*>4 z9`?QgdoZ*51Oc)wDixV#f3|N;2fMAN+N#RU)X=lgMa?zp0+fe#{Nkb!MEY35Xnm=% zukWdkx7lGF)gzJM*a*SfDn>Y~inc+BZ>BG)&L-y+X{t=J2P$*OZ)-O|d}~g{pbDi( z5brRP9|{<0;o{@;W7ObLKbD?Pba$j9j9zSew7v!1lLP%VdpVTn>~t4}rJY>GlVv+v~`>7Hq@|E*3DP4fN%hb=B6b zs&P*7DtFj5q}4h$sJyjAX>F2LvP^z8nrS&!79d8YIvYFNF#oYLK#G`q7{YwU4qa1b z9RY$*eG;P(=lohC#*%0kXIc)1_-2ZFpP0t6J&viJ?XHZnzrM{Z^_U(tuWDgt;;sN} z)>l!bDBg1XY-v|A8aulorLkjYqdmU66KhUfWXrSU)0!)*9p0$LJT?ipq|G`;PWR@j zM$vI?#illHB&3+lU3#{W=YKzXUX+yCKgRxsvUo;}>+aAtHeN|W3PXK};tnipX>c&FTW!JWx<(RhV)>Pg;t| zt3E3;x%kzNeg$KhyS`)xba?0H5Vz{FU!J`H@iv+yGlX)OF`^RgZb`MGe>ZAGhb#GZ zq=CxP=H7rqBnBB&^4xKpBBlwu&(@L^wGf-wC^&aZrni^uQB8LxPLIy!f3xz~Ma>a2 zeh*rzk-fRKg?D~p@jz=d3-_GlHXC(>6E#f@pZqaqtZSo>0YALC3fv|wx1KOa0imnx}{x*6TX*^4nYs5DryXDmsjC{sm zUHObGYH@BUY?myK(78iWNo+_fbE zo1!4qg44BlvcHpRjVB$5A(*P92R5@Y1hP&tW|qG*%T4Ua7A0G;_7q8Li*VPhh|%yx zQxPMkV%5dWMyOrt;YRrtW@Q)Ser9a|vy7BcAzM|tR=Hel;xV5_EwXZ*&6s@qkbV~T zP#T;%eL~%d@vS}HvB;bL#kO-t>qJg=CX*Vpp}OP#lRfDJGwEc*F;W4AffU5V_Vnt5 zU0@h^olUOr z<`J2b5XZ4D&_|tZXSrU5`ktxNsSThQX|jAk;VQjIno;1p`z&%aLAeUCeDstXts0aFcOk~?7X?-15+m@ggX zfPSOn&EDFFhQx|JC;#1vu3|gA+sf>AFiYdiPrDF+1ui|_#61wv_HGO%(H1D6`fauv z*wqKGu=@n4a<5y}0J#M+rYVTd?fq1@nwlQ7WMi|JDvp8XJ64jw^!Jpsa)gh6;UOP) zN15imd26jRiz1v>Z(X;t$I((NTC!mc{J zZp*3Ro{Ym*UPeJC-Ja3jo;?B2ns(#16&+Bga_6K8F5kt8%#L#_AmZ+P7Hk$Y)?>qX z-0mDPx8z+ub5y+CfoXS7<}CW4>+iFJ{1aO4!5)E_c@)uIbZx?_A-DdU6-+Ava@BHM zXE&sY2BUIg_ilDBqC-Jh_GF5MTfglZv*~Tzxv$Zeae>;DgJ&o=CF?4(qtKjV=<0|k zu@ft2gI3kttR{dR0+rFKN-NG%6;(qGF1Km5HB#urcyJ)?thh59M zjb_b?yAre>%se;yMDweQW@=&-ZB_+CIf|PvsVa*>?!bO;h!Tl769=UeB7!ZORG@O} zG|C$($=dPWLNqURsy$|&l%mhLoA)E z5<|HkiB-(*e6$2CW}@cK zCnHqYA!qrZ4Yy60Hf0kraF31^H`H9K?zgH^wh*K5_iWyzRGm|U>*EadW6G0-lrZ?>!(C3mmK)3wtiq?YGntBdH|AtNHnu4JgN;6%g`mtZ zE^|nWC5$+o)gL#qHrrXRyCoMb*36p`CG7V?{Msoe~(8+E+O62#B$aci>s{f+Vf zMUO7V4wAV!hYZLW3f!hW^B|^?>JjFLb}Z#1J3&(NEEd#2w8r*5JGaN08;b!(AVIv*;nV)DVTz4{RJG)&MT@r^+>=okPkZzV?Gd6k+&VtO6EDYw6GrLEhx_Zt|HF&xEg8G>abMWST7!L+uzRA4=h>mIe zHqWzVY`D*}Fd!S5HJ|J`ApB?drw(;#0?!|E|0#A`8|g0A(b?V78nticU{F~DX+M+7 zR&;Jzn-^>x^PM(f6i`GyqG)tP)|6p5wjMA#Y8$j&9 zT2ESbHY0OZSKOT4AI7srBJNh#Xl$M+$z0ci^B=XFVcr+IJ=%AFqWl#f8;GO2Cir;XI+`a=xk9>(&{#M(qzU{ zn*#$51M||4%Ag9QD8%;}*V9}3Y`Gza2GXHrG+svAmAd@4R2*jYsm0l-lDM71_c zLXHH!oZ7#YVhW`&yR&LrJVnXYZm;qzK1W-%BN{bH(-iN9yWF05ws$KETe@fB1x-n#HcMcWf_Em0qRyd4U8Et*$Zm4W*S3+@$lQ;8RLdrhBpPq>vpQP5p#KJD> z81c+JW@mrY(Fj;xtrc5IpTB5tR7=y)H5rZ)Cy7ar0;vWSy*~ zTdv?y{N>vA?xncw1@4@t)8 zTa8Iro*m4B+^XVg%yUxG?_Q#e3Z$P&{eT_ZiYn9Sxp<0K9P;ITF)Ru*U3<1~7)iEz zemn8NfYW0}x=&0Gf>pJ6W^r`Q+BFbz^O{g#SFD*ebJ5Fv+hWdiJ9jD3-8rBCX2kTI zD{Gi*k2`omjW2_-e-Uj@Ys-5reKsGyqoOvw=Ihy|!$SNwz2%!v`gm(Lc5@^!E9%_H zomW1au5zGfliA;AJ&OKsM?5D#JZs>{4=b|Tp4cuU^pj4Tw!RZ2yF0AEUfA=1Qy;wv z8!8|2vlAG*#n9@%sk+d%N(RNp7IG)6+0&yMY)9b2nJLpe248j|MtT@fIzjJc_8f8h zK;L)t*!de4ay(17srutEHb6JQcY8*gu|G94ea&e>11v%D1u*&5qdistY_*HwE%oi~ zSXO`%8E1|e*z6PO(1@8KjuW%|b|$-uUZX!m+c0}a%noy8L3$s%=_^f|^7Xf$rB~eQ zd4?AcDB=AESoP@O0~E~|@;js;bm#L%c#XPmi$HWTGJ<`LXimW_&h(nv-harNO_Aj@ zXU?7zvF`br!2)q9Xw~qN1M%iUCm}_?l3Uz%G06#Z+6D=aeGZfy*qUJ$N=`` zx$%zXPRG@?Qq{``{hB)4`EUr|Gw$%YLCrKUjcabE9+qBn4$j#LCcZJeijL2m?%d3Lyd%uVZZu`TZjzETk1V+>BzR{6mT_IVD{EXdS`Ic! z??R$0t4ZR*q8&6d$RE@@sBiKei_%*UY+}>>dwQc6IzqhyC#SvSwTCEYF#}nPr5`B3 zS~7cTxyjHx&Wp!U_=KE!nGVvB*VB$B=Kbv+F~X%;Jm8jfcU_0FU;05M4zYOEbu!uz z!(uE1I?vh~msF{zGYTQ2!!^@9v)<`>>6~6GHXB}f_e0rT!x%lhZ;49p#x`4u^Q&G9 z+?|IUsgJWyq~upGxt$40bMsm^J2Q8m?(Ff(RsD4X?(kd6tqlc=Oi8NPHwW(LFcWp?H693xBRiBfCL-J^hvM8TQI6xh`8pm(}E_=I}2Rb1c5 z5_~+Z8pUfL$Tq>}S9D%MFK75MJ+yg>Fa0){ocyB-FRL%;CzqQ|cbQpbK;$xcG6$k` zO>ZxDVtAjt&+#^e#OJ<{jO%FTUD2r8^-ZQ@u{&Bi8}Td=8=iNMso7+1WI|gXFp1#f zfv)ZkuCt4JHs2n^6n>1(UJ85X6locwQKJ`fWk~bTim77Ucxhe+7G0H5U`tJezQkw> zO;%em$3E)GwF3?^?mJFV%+zXPY%&i*n#RtO$5XL=);vrF$V);sy^wcPXtXM)CxuA3 zJ3URhd(XLvf+Ccqd@3}*{(vva>5~e|&Dd^&w{o*b=6g3h&oP_)!gI9vnh1tqJZH{P zkpX$e2$Qxx0)D22C#n~~eN)@I9;gA#D_N_s_r>$>d8fI#4Ua^c3IKV}yDY@=?8)rE zWdXVJD0@!(7MJYE)VpsOMI?7K9AL_AmkaV)T+L{O^UU8l*_rF=6|JTl)syW4ODOd@ zW%+Mc090QL``ukezlF(7I)m+AU@SG-Wz_zP&gO>QK?#2x_qmmP79UaaMt^0M7!=pC z_CohF#j|l3P|>pIle7&BqIhUQ(dRO8x;dx21T#csR8V>E`^jkX&E8eJr^D3joX(8P zYJ9RhzZIi-_Aw!M>YDe&C_ORL>J?UD+_xFoSHj?v5)`MP*6fM#Jx-7T_~fXa#hSVOkbL4k8ql~(fvM?oocSf_n9Kom!WTNitzg}n19Z$-hcn>c__cW;CzGw zuOvUIv}CZuuZp?Hbet?L9dcISZ2vh0_*~Wm_X3D7ayZLMOHRl8`p@(&{oW(r#RsS8 zmwWJQ170&eoYKedSun%zGXrP&&!*pAxA;m#A2UB2HWfej;OE1Zl}OHC-^9RV-&EfW-wJ+9tMB2p z2{`Y3UI9~LXk@{eDO%N%}ZuZ#g_eth_?uYc}`;H)#hGc3!$ zVOjU%!@i!w58wLw*Vp8CMrHXo%5yj4#7=80MU zP0YF;$?`8^+-Gt*lI4DKmU&8+|5LKA@0(?wmKEMKbN{Zit7+*op7{H;BAWNl3UB`` z_cOEnpK07*l6EySeZ~{NQJ3v$NdK&bnTmb-g<4`n)Xjf-Lg^ zS>^+?%m-ze56&_#%`z{~GB3+A*JPP}&S==Mk755d4E+JSF85$-I?OeIG&g0LQ(5K< zV5WcU$0wtIxI$+3RFl!ZZ;+Wi(=hydL}vEe!_dB72i=3=y@Mb9W8Xat?PV+sH1pap zC*oAnfP-~>s8j9KW?lcZ%$vy9(AAig;zmsMD2h6m(9KT`COs9eg(ZTzd zW|=q3%${bbQ{}YD%={SY%y!Pma-Z{&v#BX(s@WlvH7BjgUgytN^Y8v$haQ*qS+1xV zoFHsaF&o9F)v$b2>3z;3>(xkWvY#pPzP%JONOn|npE%;ncrhQ)yL|_CZx&9noMCC2 zld_GQv%{;Q9F*<2$~ewv%3vO^`$Y6nR2l4k70JHzIX(5viE=)V#BjpecRGyy*}c8o zOpxTa%J8^Sw5O7}v>`i3m`fXTUvFe{6no-06^6*tQ^h%NBfcnruU=rA4HOa0oi(O? z6(7nrfbX}~ISxN`T&&JvhAT#_ge8s{t{C8&-C^4`yTdBXY!~#GZK-%2K0-^ve~uh! z|J`8|?%8}MuEif5Gu+`1_H6$J`m*&5ci4h`1op-FkohtaUvU09c_jXzQ5Rsi!3U!< z_sxJk58P+sfp}3qWV{xUh*t-RboY|@7Wz3P{5zjK+Ho!c)A2Y41{^ag5e_-W7@dM+ zt+@bSWTkza|{v0G$%=$`!@d6jsxc)R#*@geai;;+O%h<_H}7Ymu+@OQYlk2q7DFD@64 z5!*z3B-V+W#Cow^+%BFi zUMhZByhXfQd67Lcp7M~PFD(6)zXB6K@yq6(1EJ7oQbh6aOZ%V_|$t z#4+Mju~J+l9x84Ww}@?GuXvVtiFmcRL%dsjQ2e3zl=!0fy7-ppA7tY@M64DUiFM+* zuyuF7xI?^Cd`SGU_=NbJ_=fnN_@Ous9Vqi_l2|PsD6SDViEUz1ygjK+#V)Z&JV`u5JXgF}yj=XEc%68Yc)NI~c(3@N_^9}p__+AA_^kM% z_?q~Z_&4#NBB$Uir;u184im?S6UC|G46#z2CoU3~iHC}7#Es(7;uf)4Y!ee=uXu`h zmUzB+iFl=WwRpX_L;SjUm-ub*VetpzPsJz2XT;x$FNtr6Z;R0(HXmEW&x+TJJH)%h z?})z@-xU8T7D5qY`a5yDSSHqq>%>;EQ~Zp0vG`T-cJXK86XKiV-^3vhR2cqfagMl9 z+$?@tywoLBFud<7@nP{t;v3>$#JwOpnsCI$Vy)OJc8M2>SBUqEkBYB|Z;9cN*8kz+ zLUEbcB({m?iIwRtq4+7WNjyiqSllVzEB;1&Q4C;0Pyb8A za&ew`q_{;qLp)!+UA#+tTKt_z6&L*Ah6W55F#DutAyh6NMyia^s{GIr+7=)nBaE6N!ak{ufTrWn&7V#|cQt>MB zPVw8~&%~$1*Tlbz1yBhx9>wBxu~J+t9xEOv_KIhVmxEbcEZ5f2fM6}!Z3;>F_S;%(xc z;?KpW#COD9;#f=s8U8-vf#NdpSTQD^BVHtaUA$X-LVR9)MJ(9IhEpW&E0&3C#bd?e z#BJi~;$z~I;>+TjqAy~@86*x9_YwCK*N9uhR`Ijq=f(TPhs3AF=fr=A;Yl{!Vd5OI zMqDkX#B;=p#oNShh(8mb65kU)6sJzM;ms5e7mpH86wegDDt=9TOngFoOMF)x4jlvQ z#dvXnxI{cwY!*)yFBC5qZx`KT<3c=ZdSvO=7#)EnX~MDc&XCFFr0lBfc%}5{FE);g1$8#6{u? zv0m&Dd&JL)UlQ*Ven_imEtwxJ>rAnuf*rYT_P3n zEaws8c<~^yMr;u~#Y@Gj#D~Qni7$(9ihJ#^{1hw21>!1kqnHp+5I-k=NxV<|uK1Gp zCou@!8q+mc+*d3U*NR7o+r`tx8^l}0?}|SZe zSBf`^-xD7bpB3K~KNKUgY`7KT5^=S7l-MjL#8bs{#GA!$ir*HW6n`zgBkmH%l-ckX zi_67B#Z6+p*e-4t&lGPE?-m~se(i&p2_i zSRpPDmx@ubMNEljisy^hi?@p35+4?SEWRqfB?hXLKjOY(xwuR`Oxz%LizkcMiZ_Xm zioX(H5Z@I4CHiOE@P~<`#i?SYc(Ax${InPsd&JAd8^v#k_lrLge=Yt_d_#Os95Tno zYj2UddiGaGiOphCJWaev{GxcXc$fHH@#o?n#J9zNi9@PwcuU1KVyoCKo*{l#yjr|P zd`^5r49vCu4izVgGsOjBjkry`TD(=fSNwtaOYueVZSg~~WS$LooH$*aC$13Ji(AAF z@g(tl@eAS(@gDI}@k#Lo@h$NKv3S0X&lquCS*NMl9ZQ=>ydE#~Af(6#!!^9)S zW-%rHK^%R6bw5R{5SNIX#WwMC;+MsH#plFb;>d;8-`V1!;zn`1c#U|U_y_Sram0bv zpLya2u|xc!3A5vPfj;$m^NxJhgmQ{pA!m&LD&4~UP6Pl|7de-Vq9+jtBU zE5!NYTJZ=mC7vW+CEg@{UHpmoKjPcsE^*`v8}8oXLUEaRwAd&n#9r|<@jUS|@n-Q6 z@kKFEW5XLKP7&1J;pNlVvftA+3sp7$6lX#YRqxh)!8}V)N1F>|K{1Xor4;Nd-i^QwMJH*Gt--~aG z{}czWw*K!eP7(JPE5y0tf#Oo}5OKA*K|D%~iZSsxF(IBJUMYS@{E7I4_$%=b;_Kp{ z#rMU+H8wqi#o=N^tPZQan<;P`qFKr8wmX>%LMvNIXnz7B3KQ z5FZp@7k7!1ju#7hhJ=hU zMdtm)S+bum^MT?L*{_s&t+-M4QJEXXR@o<|dckv@#4;*dXjU|zPdyCU$KbPDe`)OsaB@y1INVwl3 zZq@Zp@hsV&D_$!5E5(~-f1CIn**{Fe|0iVsl=wUGMe#Kf?*2j|o$tw9bc~Hxi8xXm zD^3=ti4`R7uO{K&QrXvtYsB^9F(lk?A>lqQ`*yKMJV88%g!>CfxW8KV*NL}?UlZ>U zzb$@G{Gs?b3ICoV;opn0e?|PW_*d}*(fJhIqr3)*gT+xK{2Ncgzv;4{CC(KO5SNLy z;#zTocq9pb>Sd0J9VEg@>iXHTKTo_&yi)uU34d-Rao;U6-=pi_7QZL{P<)Dn``?hb z|5e%lQT&^@OZ0u(x(|_XzZZ#o8ZJ%{BjOwq?v50=4s ziR^zNJ|jLW{+>j5Z;-g}&oY0Y>&~&TXSs@l#qlKEM@ZaXCi^OJp}1H)goOK5B;0S3 z{ZV3r*ev#vaDOrh_n(vf=f&&98^v2lxVw|YeczJ#QCfzG+6&8i5220;%CIG#IKN3 z9OrvvrQn@Cy}^ss5pwm_3^sCuk801XOjqb zJ_&b+$R2NbGX887j}#k7xNjlh9&dUv?oJfX63-PcCE@-`67Fx1{mtS|@hb4KP^5l{z3ec__p{D68C>d;{I?Gi2T?~93xH;_a)(e1_}3bWItbABCZhEk#N6B zjLW`V?2-M6;)SxmM7&z|cZoj|pAcUb-xr;j4Q~XAbc_)v$$px+SoX`rm9k$a#$=B# z4jO;(QaqE6UhyK?Un+i4yhglPyiL5DL_U05{E6&;AwDDf=fuCr{$24S(cf(2Qz8x# z$CB`WqF5pOIpQL5iC8DD7B`c){}{1N_Fdw3@nrEF@qF=fB<}x$_%+#oL;SY*p!hu! z?tdx%T6{y--xA-G{Rd)63+_X?4iU$Z@Mj*0_Pky^Mm$kGOT0|HL;Q~TI62XAo|pMm z65;$&d`H*)t*{?~=PF2qH;#n6iQ+6W=r{-J`f}MHBCeACW|@x`qq2|7+%6_a_;-%@ zMe%kL;ol|ROYY@3KO~DC=V{sho<#g!7Wa?CjQc9ZP2y4HSO+iTwC=ma?c&MeIV9X& zAYLo`8^o{6{$BB?;tS$mNQD2c2(QezhH1XxY2vlw%i{auP@i>Yp7X$Xc!bQ`#WTqL z9S4tG8-7{#4~cwUkK^dO;=jm67?%sIy?K5E=20?F63fLE;<@7I#A`(JTn7BVOXi2f z$HZTWe-eFu8}2A^rnp4hByJT?6)zWW5g!%b7RLpwzvbeA;#%=jVwZTbc&T{3_9I%(t=ak{ujTq#DyHt|&PeDTZT4)HtU55!-KuaIcx?~7wX*1Sagl-MGkAYLQh zBmPGGllU)jbfNWcvN%UvEgmcOif4+Kh+h(K62BqdFaAjUrTDz~hWHOLSY+cdLX3zr z#f4(6c(`buH$ncG=S{$EvOkMNzxEXp{g!#I1bO&4&ERjvH%asx#e+aJ%KgLxL}Zg` zCqqcwH-?1!2#J1YItl*~w7Gu)iEx*YQyk||676Cg2}grv-cOt-E)$JAxNnfTTRdC5 zRJ=yKRlG-hghV*M6kic{iN$R9xIT(RdM1!a&t#J6A(5VP68TY0B0UR9q-P0<_#HyR zpT8*|4`P17pHGwUCrQGe3zd)WlkjH*+|Zx7B>XwO1cX0u>J%(j{vuwmGUjR$Zr91Y zk%a$SWNspHbC=9167jxJ=1WL~d$r8hkqG~GnRk+i$1i1mhOES&a=d*7uU-UG3CmXZ zjNb`%%FWBA%Ny`f*>b!HsGOGNxzE$)Jbqlhbp7gbxUFx<{}%dhZ;Lne=6_pONSW`! znFwcj=((D8U$oCt&Hde*{0wLBoOJsf)LYA8jh%hD{4DTrX=%0HZWfbqhYdk2c;JoV$V{#n2o!Q_qKS-S4Rjo2FYu2{{7P`mjb9KR({DGQnJza@I8C2(4or9MwTpStbMP9Ey{&)g_%S~jzfxYr z;l^()+t8y4U-0-r|J?W-D0i-zvZnXIWpi{`cj@@i9pg95UQWkv zE8KbGH`Nor5pe6q?-_;b=HHFD#yaU9ZhWW<@cLH`{~~b2`Z5YX*T0|3Kli@Jam{<+ zvN;C90nXFupgX36e(|7xJc4lN4R@m_9b<9b4fiDLUpk+k!8JEc^v8|Qk}Ut4;2*ujRW`*14Ne8AD>2Qal1ESw<++V{v z>yvx9{=Jgr-$|ZyMBvy>N1^<4(}8B*=Wx?8+qz4qgYKA)h+MnjmcyO5JkIi@V+!25 z;U1-MvBldS2xy#p4l-Q+s7oQKL*l`?WC<;FxZytIhAVfMBi!k5!*ZL3pBwIa`Bxx! z)7^y2KiBK0t-G!>JnooY`o+Ty_eq?X^vd1+p7ic7cf9XLbg(8JyctI&++S`_&0p8Q z&2Z<XHT zm#Lm`S%=(obY%I*ftcfgd$|5>&GN6><6ku#yZ&7w|J?ga;NSak*OW=eg<1ZsfPXs? zv06B#{>An0>MZ{X+p%B86G6BBeLc(FAGbTsVaxy>uDe^a!u{JUpR)sTWVi?5=Z5=8 zmVa~4wEB%~{~pZp@9IjQ(TmW(13msdmF3?R@NbP9DY$b_pUCp>Pwi>Vv;4ci%4hUn^zUGge}9*Mm9XRS!DWu~*fI8;e;Gd$N63k!>+T0{ z*|^aS57*sbxwE#YQ-6k^t^s5|^B4qo-g+9C?K3hLY$-mqW>u}v=laAnOgHIp!#HbS za~5PfV=rCdlsitO^e+F-E+)y@S^ACB7TmpJ;!AfHPKwli^xlUb9eJN+u-0?ScndTWNE~^peNz**Vh-AE!+iZtOj;ziO|ze*EE8hILEP|Lz@G{($R{^nQEo2%)0nW$-{+B^596)E&o4dg$G+2dB4e4q z?r{d%W6<%LW-??AD(2qI{vV?%dOANRP*hlqYXM);+o(Q)g2Esi3=IVNrtv_aa5k?M z1+V9|qQFapFZ3Z0`Vs#4XY#>HC-fZd@y{RAgY!T^@GM$AM612i1Wp6Nqv0kL zd=fT=!Gn?JqTpk&4+npPza_yL@N`J<6nYlq(6@K+4xFDJ?{|vMr0siie~R>Zpdl_s8JrLvwQ%zgO!6_QeKmRap4@7Kxh_@dKBjey7hCdg=&2W0)TUU_6-@|?L9sf97V1!wn z>;=a^8Ft6O?!b&)!F1R${RK;K!t5zH%sp9;6JGLv3Mb6Zr02dS*!=)8Decfj1>y_} z!`8RI$pBn3FOKzHon*e6RPH~6sch91lgb$;A7OJkekPT(ikW}c;m0=QXFFgj|B;S> zQaK72n99NM-c2QEG)(2Bj9tN0*qKz$!-+}d68D5zX;R7LGL=Vp?mHTGtc#@$x|mMo zM~uqktW+L__GVK#d4Hyozn%D*R8C5u_ruN2xs6b01U5ww0U8>zT^&S*bi2-K|aK_=!v*$6tyoCY2MI%6(u%C51`l zM3c$|Fmf#}oyza0BaoF!t{i8V<(nD1Jxb-ih^m`AOeOn@+*FQ1DhtXcoC3!@itzJY zO;fR1B`m9b7&dIzhvGM`xjhBfU3b8);L_B1bnON6;eq3;a|*_sG6uGXIw$*19gegf z>f?zIr-7+XIJ`K_)CZ>{6DEYwg^t3>!tjCN1HyH1f|4YP%6$iqb?x^XTQ_{sSb8uh z+j^*PSZK+Z6U@cppvR|z(cfBz&Mmx`6P^^Hk0sT-I?0ECCKc2T*Y&}$EwZ)dLx%eHEgg;&j4$0ZdZ=#*f*7hqA;X4EGm#%Y9JehRi_s(C^Or6T zhvBtNA=5B&xGx;e7)K$DA~*dEVzkd!XL4)IB=}YVo3Z6ic4nXiklOTp1;}u|lL|Y6 zQ8+;(v(kj@<)464>RT5m?Jd5+|5az&jj}2h9;QH1-M)=#J4Fh@l!tPZgHX2 zUI?xGT;TA}1#q?K5}aOwb9MO~+OA#Cm(?R&>?l6KAm|ETou3dy>yjT045JI2KX(ft2z_ z*7P=fP_DbYmF0%dW;NG$x8ZXic*AoNcIde9;j<>lz%U@g@g2GPF1$?IUPZ5KKRj>m zcHcA(6B?IwigUPP*w)s(>>H=79*~evG)hzyI6UYJ4G*3;G3c8N6`9W$oa$a3 z=L;4L4^9mY4Hir~%qa-?%JHWl6yd2co6`c?`mJq<=RW=Q1%0!FGhq=3&45Sd$|Br$6>4Z3QuV3s-5c5x79@Pfk3pso_J$St;&96)br`asOSFm zYd0?4Shsc!zVn8Ux<)ulZBl5)C;L6ED88xG*@y;<_v~k)H#eHZS6$uEqIjWuCSHnF zI%P{&)H$C1w1Q0;pFK@?AoP{rJ9DkPft&A$}ExbnPL`a)A@i8{Km0` zA{K4HR|w)AEy@kYe4sYxE5^I=egi(UY`pI5XoZu3c|G`b>M9IZQ^{ z#frKO8<(zGUSl0Kb#~(`wfKr7zrq)5ikQzxde2P|=1%Fs&%>HH)KEeCn`F8K@UVNo@&%fMjD`1~wXEs}zj6z!H%tq#dRrA2;GK{qN zN^4dtaa&8Dc2c)`lPPms4t+vNm(?NbHt4&F-s)k#Y2mGwnZn(GvRJwb#qP$epE28B zHSzT{LAPm|uLOHN$H%lgn)&r+G~aZ@HmzAvQ(L#DW<|zo?YfP1%Nh3Ox%h~rY3(@~ zu{`Y+vm)(qBcfzKmhqqY78fO6_n^?0{k<(CM#}+(Iq&zh{@rV{+yFref*wCtl#U6m z3k44k9#I@x7dpIj$WloBOBce?f8`rmkc>P>KHt>x?)mTv!1RXS*zz8Jh)5&67Ir?8 zw&6Fn`ugXJ(bfsSvE@DZO|8EEA+tP(A3JmV`Zw5fmGRpv%lyCnhF0I$__0FR*T%bI z$nZyJ#c#B6-<6IP6>^zl;BRP+%L;E?=4PDv`+QxFW@=0_hu_&JW5Ai;nUrOol4agE z%e-HfnJT)>k^9Z7ndxsXv7{$MLiUD8wci5#SS#7~hM|7cfbPNTQP%*{oXj$xnPt8p z%Y0LonaWr9pnv~^Uncy)&L7>2Ag^=pb>{joX9^8Eczv0!vz-q^YNJ`#&&V?8OjhhS zkTQb{K6=jiSoQ~tyxlUs=i35dC4tZ1WQ!H)D=itp%kxR3RQ+-IcCk9#oGv;e(Rpq$ zBTkM}@37{Lns>y=xvB3E(C0Qub{{8PxzbO6_oXGmoG^0*vwkzU$}Q6wZkIL_We>|@ ztSnIBTwHGVQxrop9ih3>!56MT+(`uixkC19NL<`Z&T$;BchJlu{k@=1%Ky1p{<~e? zC*}YAEdSjO5B^g{&HSN8n)$=thWRsQcE-P$K(s_kE9v-v4zB<`c|0%X9g5$ z=D?U3pcw-=`;LN1P_2^FYEa@>MqDEvA#M><;>qI0B;t1! ziTcj{A11!!WISgt-Y@&_%gohRUgzE^@>%isB>efOSc-~G^JH0-8jusom z6p8qqN}|1AEb~<)!u_&%z3gw3`3~_x@e%QdB>Z_n{F_*WzL54qMJS<-d5SnoTq4$q zN0W$Oj6^4zlG!{@hxnaIGkC7-FO~TUk$by%-8^RpevM}MW1h1Ee+O}ZN- z4il$|72*mbKduWXb3jE(p9KJEqxD#vYZ zs9w?NV}tGEaG-E=9Pc*Zv}~16;2FnxMxgHv|7RbVKxNMF7!PM?X6czP+mQF*H6D}j z<2jn3Idpj`#D&gYo0>1^m3>{>YP#Fs{)Z?|B(NZ#s6u++RBGgT2?kXFTa( zzwP?>Tlwdve}o%x*z<6Wg*d_gba~Jn<3qoAxasi2-W%?8$j@$hkZ!o2vi_y(DffZ* zmyU`o{}#YMw>*Y<{97;o+;p4EP}tZ#vHPq=Q-(HyyvW z{-x7#F3i2gC;P`O=N(!8eZi9sYGGXeej)$dbg-e6c>HtYM|(I;r=tXBhUIE>Tz4O2 zh5H)9<@n0_%z29&Zk6>9Hue|+^EqrlI^c~t%3$x!7k)PVG`du?r&yKxxjW9~)V=blog_lA4gB(!y0XSkF%+;lW%`FAQB&k|gB57)nFmVd9o zze+fwe>hG1*OTQRzxg=R^$c|V;~c{qzcG`oyhQ(|c>Fs*%Rhc2@+`NoJpP@N<=+yI zf0V1-^j<0d7G>Ad+L?vQeplLL!=>@otoXGe zer~(mAJ^UZeFyF^c67O3ya4|WbPb@Jev()*$pcy>hF-O+Ym^z6z7+#j9KzUXQS zzSw(V$JXi4B_3a8WZ&^;Z1Ejdu%+t|x8GuzE3`5hImRpnEsQv`BCfz`44Gvb zW3;kegvvCp*%h^5_h~12cd)jkc2*ttbkD4tZgz!-v>SX*tFQK=U4_nuT_ua=toTx^ zGxOlbeUk^jQ|PNS?jmwOrImLa)B1%&e6{w<_&!&D>$x(r&z14<%soT;Tsa0;tY2Z- zPp>W5+4X?6`|hjEc{EuwUa;SR+R2pHdXUG?TYaY$9A7xOzkD2WH{P_}I_4W+X&p3< z>5kM6dBEJWbH`~tSibE{EL<2}9qs#hbT}w`eb?Gh?c=XIz30_lR=aTJjz1O#ZXEKd z|UpxHx-|Q-?{M?p>wKcoK&ZRZJcS?K}PdvZt>WA09@uhId3BeRe|acV6AM_Q6+&Z!ekc+f}q^{jR{GrMpT> zmVytzI(B=>oYGxI6E^G$OjrZkHQ@Gk2w&)81VZRPes&PN~l2A80-S}`l(oMpGiGs@;je_}TjDasrb)4(m{tWj|E-HMho7$bi+s_3G3MUjo7XI`(P^9cX`cOLX zg<^HEx*8qi(3xY7F;+#VqRR{&TLY{4V>)P65d6vouo@YG)d6GY!m5~mLeI3pV)dBI z=q3<6724&{(OY1(cI;P;RpFaQ!HOTf7}_%CURo6epGF)*PagrR_*hOUiuosWE=I?p z=j_cmg#w#!e(pp@CiIzhoL@JQu?X>FDnqZ|$AtXBY@FXSks*gJ8j16J_hFEs8A$!m zA5COfp=Y<^{IPwE|D92sKRwpimq0oh`nz$)e(fZjzcO|sZadFspGGLAA@l)ncx@aT zH5JNE==Uqo)JF_s&m4NA3g=^nujR#4==w24d{|_71266>!uiw@-8{byx`|=4h9kq_ z0n$9Ia>P|UKd>3+3x?m$^Q$mO4qG&WJ$dMLx?et`l78+OhVw&5F5>xY-n)7Pcff{L zLRma){m6QrFTwyZeB_wNdGF;dI3G3kS)M<87S6|yeU0bOe+uUl#{G@wH=t05Pa4ZH zCbZWyoKGIdM=nFZ#~3?&zp-O@zUp+GPantU0YVR*g!4HQO^&pjkMrt%OlGW4;{2d} zjQz#*b8*DjAB(gPKg8Pqb6=bvYV8}4o5K&^$7KI|^*CQ2VfLTz!|pd{)NEh)!j%}{ zM$8E(5UPJfb@;P}bHg_q&I>`{c+a;rG^)7lof^dPjaXT!g~( zkGv#2(eTo6wc%yqnBnKbrx{)z{;J^>;fD>c4D&_i{*j*#|I_db;UODozA8My@QdN4 zhF=Od8(tkg-SErd+YGM>|G@CN@Uw>3hd(sDAv}H){kbtb&+w-35r(&fdkt?7Ut{?7 z@I!_>!@o7WGyI<6H^ZYh^ZvWSvkmVKuQt3V+-mr(@R^49hOaTaFT4&F+duN#VZKn@ zKk_@_a}4hf-(>he_y>j$hTk@PC>%bL?!FtIZTP+LM#D$LDZ}rFFE{)__%6dAhJR`J zqcC3>?jQN%a4|Y0|H#L}GYo$cKFsi^;jM;03!h>5^Y9l9e-Xah@bU2DhEIh5X!v9} zgq4~hBg4K?Z`AXo#5XF~z>~qgQTv*c@xD^VamdJtzEWo5kdc#orOdq{Bd7XGnQcQx zPWP4C+xPdC+S_ONN_qPQzTZy9mh=GI)DcIOPU=N}GpgEWdn4+a_nABwg5v1KB~%cH zj$De_-qNxf+!+}Lk!1App>3s@kmFhve)I7wI2;$9$oElQMjtxiWysRJx)#4p>8rz| z8@n8O5|2iE%!v;RkGQOb-e5>cz-Rfw3h6HvQ6MhuY02t3D)Au*1-$LV$O+x_#V3}d9|DO4Kslz3TJfK zKz(=M(%tEs?d4SADgFt$r*+WGt3|vBxeZ{BxjH$jsyvUB(n%8W>m~MN6fCe zuIsw$?z+3?9M;{{@BMt<>h5!9z~B8o_dfTZd!DDN>#g_mzLl%1-tMkbaKQP#xhb&T z1paOxWAO%{`aXpQE4bA8X|_2q?^d6!sa5UPI}+euoAF9ZWPy2k4uF>ll3JTT7M-Zz zey4Xa?!jdLC19y|1Vs-OjLpbJ!52t6{|MK^94e}fe(WkQq55QBU{7c5-(YkcbNc2217tLO# z=Igy!9dR)Hk#Hgne9^*{YO(&LyPAlsL9WH7hx6*HTid5k;MNuubW(d$=fH_ zU-Qn8>;L2}#Wkae(s{QsqUpZuk zT<5z3<+{L~D%XYXM!7C>56N|z`=DHxyYI_&rTeQ~SGkSmQQvB}k6hQdW8}KloiEpo z?rOPicDKtF4I$U9?t^mO=DsA??e1UYdZFvgr@q}TzX=bO?QvV+I`i-jwD?%vH*{JL z_eHe+;-!n0tC8hPMxq^$cRbWF$D zgRWBQJb^Bk?#w+M%NFM!=i<4$)3G0xXAaIxRLh(;O}OUhZYj0IvCqVf*I8MK+rG1` zuTpCreDtU?9R35^B&TKsY!1$g+pt%423~*(!P&P3!`gXh9oIA$ASbIGo=IEgRQ14i z%jp4pp)>75ESsF(m_+iNC#rF)a$0qUJ;C__`OI}jfxFK692!=OyI7!0CbZDt1O7-6_rnv&d(H|4|2jx(X9re=mSdyy+sm6;h*w%IzZnuZJK?;&diHb_ z5Wh8QOk$8y-$A_L>*=VT>vjD#Aol4M%Rqf+g*RZF)C`39=ZLnNUq)4NCKqZt${m6F z4mBO^_LJ)vvz2T*#hoJbZ1)_w&UN?8b)I_@u47*4iI>r`(TSc!`!%a@+E?OGV=%1A zS(xeI(mzCnHN}p_a#149kji?Zi-2#9d*JN=9`M2YfiPf()U2heR;p%KgcqaosQDOh z_rVzmL#iF`h2hEuoLSr5f)v7o+O-EG>m{Tee&6|`1^Ufqr2bDtejCV|ya?tdXJ<C2u{CKGDW%YA(@uf5&J<=V$RfguuVQR%)XbYJ&l zxmLNMC5*3j8_Bhw+g+}wyJyI?zdK*91Kb*1J8e4yPbRvi-H+Vt*X$`RpS1M>-SS|# z_*ukt<Ttq#h2{D_;1@M-ZlpfwUh@hR=P7#yQXYhMOBs!OQ3_(3#qwEe@0))+nAsVeqsXFM@`(j`vCnwEfg$|cqwzXToV+3lE6 zu19Ge1@;7-MMB>KPYK|;o(m1&eK0=>0LKaF#x;NYSDihWWPbrGn(NEolVpG3n11`8oy)eH1S-Hj-PfQBh1)^@(8_Sn1ZR=Y)kmo1DkieRMUj5&g{NPj zHUU6`V@e?k$!~u|`;hCwzT;GoWBP)fM#~AX-wYs9QlsTHU5x37b@Lh6KN6BGj)AeaA9%wL{MQdOt?!AC@B{1oz;%A$ zRX^}AKhT(WM;36XA6SimN}GebW7|og(3r01`=}5WTXU!wuNelE<|xvf+dcTWP-xOp z183!&3hp6CheAEa8zgJ54$=b+4TTEPjhQ-YHU(62s?-ODLJKDuIP3pZa8L2+q0k20 zW~rDBR0rvSnufCbHZveLUJB^xAt39Py)2a7Giu;$;#0vr#f?MR_iZsq_JKM`57a1> z{WR*8S!Dl60daOeDfOaI_L*235YAq7D!8Y(K`8sEmpZ#y9i#`!4`p}8eUIwc1yex7 zPL+CYDEntja)h&^o(k?M&Ix6|;HA!Fk4E?_f7iL5VperN?d1`u46S zWsZXsB$}>P-(0Wt&^-ppfs%rJpbm1K)_qnOBu7#T^7=Z+wOS9vw8C<8sHGtH*Fmn) zdN!7-L~<;qAlueKo}+cMIR?qWnu27pQ%Bost66>&9I+ttRVxmDFsg2~i#+0b*rRY~3 z>+7_PP7@vX3sh=Gr%8_c7X;c)7y!%V9=G#d=-@hD;ogr4KdUb$hWG@B8_(w{){ zS8x_7k3GeCvD9NnA(IU!Y#qWRr6%w$6rWX4f!lW!5v{=PQX7&r6pPaMM(5>DnBf4? zXMjH~z%Zl>F%_wHA>0z<)y3SV_x&u6@ImLocG$!Ku_wTb3JR%`zoC-j|8R~rG5T&q zil#emobRoyGdVC0V!qJ zH#*IRdTa-hS#ZME9f*BS2r@qU5-8BoTXo{!SZ9?E>W@ab zSEmt{##V^_MLSy{eH`vRINcK*{Ut)G^dd}E(c?Oedg5f3vN@v9=rkr^#J|?g$H)N1 zOSq5=#5GA(`Y;+K`j}2*bM|9?qd0PH-C%tA5}+w-QcT;B20%~Cq2Yjem`6}0t2J$M z4Ol}gXDx<1^RgvimGZGe^e&yorY-$o9f&t|l$q`~qyj`s%NjQX7Jmp}^|(|KX7b5e zP?zcNF(*cIEo({c-3d z31@5i%_Ue$v*x-JQo?9whgF4PIv0{ZAnrfZMZ)9mw`hf8L^fm_!3kF{PeQJ=s?Rcz zE@1Z!Am=0@hpiu{8puSjX9bWANyv59Ke1I|LL0!|RSTj;)#~ptGrX}DAPmo|eSjHG zD)K!hZ)Za8A5q*mi&zwD%0aamraGiB}74EYfW_v(h=?j?2anLy%uxip3 zm?~}q=h1*mynz((wJB$pb`GC~yuS&=`vFQSHMn7{6G{HK7vVE zY2A^m1MBdOJB&T~T%@Tl!bGAB>jUjfoo`r|ll5K%taBd549aJ+T-Y^~q5hn1!J?=A z(g6BC*Url|*lj}KFBD=R#k-D8BWaY%xOq~y*yJW1ZyoY!=HwtAfLVM(sLC(J0AXgRMA_Y`zOY@a~Eqs+0Cc%d~G>phlfEV$DH#8X5V zHA^k$vU5B&>j2mpfT%`4Ph_Fwc)fL?&;YLm=KcUjWs+6Xss>zR{WWI5uL1bcDZtW# zCJzTJ=WGm5=2QO)XnIq>E=0HF!60w2oKfRFWOJap1;{rr7EFbOtJe5nFHC32dFoRR&J)L%e+699td_E6(P&S1an)<~ z;#un4&{r_DP}OF*9c0S*5aza!sxhKRz_@`-k!;AnFmPVg?O$z=WGcIW*cWorvBoDx zzXI<~f<;rq?U*v0S9JNC0r;wr(=yj!^uGaA&3(<`*&vAw=ZBT0UjKH$F-a{h){Mbdu=yeE?Uo@jdK!;s@9%+#RY1@FTopDR-5ALu#QM@cXE zH+cM<+SF{p|6q7KKZKk=cSG6o5MN53j1t0?0mN-59R<)`!5mNvpgD=Cf_E=~n%1^6 zr7cir0x{D^sc^?AcwKDgdQ9Asg>%8%OujU3cpfL%O53>?RVe%TtHC=O@cWkH?(0^E z-@u*le#Fv{nUcYVZ*PV83ElA?_SY_K&N;Tj6%m2@6L{a(k$80`KriU7PXrQcZRa1u z3{W>{iKP#mRV>}yem|E%pKmU;Pn8oU>LB`Vw)Hx}o2wxc$A z@_z&Glcc=x|7<($abIVJXx=koa9%51h7Ra_ZaXE&qin*OfY*Y2GZ2LTjqSwI;Z8^G z>T2)?1@Z+wr$AnZ9rOmJry+j6FY9#?0c3@p%fkTFfO%m6;OwFb9^gHwW!TA`55P5G z-sl5V)|b%kZVg}7+M9;>-0yXttvMl?RKf&0%fimmg&y)#p#EJODaje+=CJeNb`O~Y zhg)&fbfQ~^7K(=p<_I*)|};^_dz`-Lhv(jI`*BhEh?1Mo*MKkxyn;I9k8yD8!f z?2dB%fcS75zktac7retg-rW(W@?0<*0MWD-N)-&kUCvF{;mrd9=mqA`0Kg@O*TP${ z&vG-Z@cgwvodv`>0ZQs2CBolOd0lPea5~aeQ4+Y>QD?Bt|CI#y*03Pr` zDtrrS#hss3hFQRgpCAjKTS(l%IQr#PVf18)p8^OOTz_6Si=IL-Hx`Pz_CGh`L3!?=% z=mYFHZgiTWS9}TfuK`5XJF++y$lXpRrkqR+>ryzA8-d8;sX()(9@WmU*#<-9bIRipVoGg@D=CX}|?(pSEq{@jsB3MxMPV*L2M*+JTPLwBYUt^P7 z8QHz?#rpg`cs&FQ*Czq*ymLCNA?0n{7ceZ^aWPZgxjrYXSVOdXdAF<&05XQT@=gWp zy|I0J!04X+FEH$qnk^uDW!_y6)rJ;q0WIC(EE1X_O`K}Sl}~xOXwDLu%FGq0aDhz) zY?d#ivUra!Ki%oR0|r?H^|@eeCi^?+R9ReOl@D^B=w(vU2f?~FVB@H^S*m=Pb1k|O zlYa>AiGZ6u?R2pRsW_*qs$W~ctJsKIc%wNIf>HG44oJZ>isqm){=O9Pze3&y!y*+J zMZdx_Uf2!6YVNc3SH$>6(MJa0?tzF(u!q!!_(svk(NW|Luvy@*3@{A+wo!B!hRnr4 zTo>R)1%(2m=R>U`${XJ--GW10wnt z2#3J7NCigG?{|9aBCwkIY@J1nZxqcy8|5RS0_?%HA-+-c0471&0Q5}o7yFpnM$rjq zODW$r@b~+eRHNt{m}rj#48gLiqL9Bs=0^|chXiO8y$7iUMp427qv##GlzIjlzJb$4 z$g>Usn>312Pn^tC8%5t4ZN$qVloZz_f5Rv`9}+VIG?O+d21e1rs1@d6BSEFeQPL=S z98(ALaz(%jjG}DXz$nU0tKz6mv#7 z@_{qN@j(Xq1Bt+L*>SMp@|B)0K3Df3#J5}?&p|f;Yiz)-Alq0jbJn3g0!BYFFhik$ zzUA^KOuK>Qa%MS(H;dPu5Z`i{u^VeFNFIltd#Q^=V7dIoHr!XhdB^AK(MiaaRzC~? z%6tv>e*(yaB;>GlUABQ_BL|J(Bn^FL5^|mOGgkN1(gp1PwIEtliRJQwO4ISj`+z!@ z%jVNieiqZWTv`}#XF=;O#O7TsoLWSd?49xr5wg3z;S<&vJSH5W~&ITA~C_xOz3yGnT>u`aDlTH?XS%hzv;s z8K%qAjh4w^FQ^4Esw69;^hakI*d{=B2e9?Y#K!C6(+%W$uxH^{08uXvQa@nyOlQAL& z0nAqcjAE$}&vH3;36ciqoPbMw9n0kn=%3bZATAG3q9d5q#d68UR&maC#dl>v2P~Iw z0`FTc$rj6{;3nO59;b&}bqtfFSS33ED*ocELkv#kz7fDjYKvXWc$2Dc zwB#)!PMA>uqhEx~RFM$2|K zZz1FQ5g?uqP@*OHAcdG+K6!0Ps1O|E&ekrdRn!%Nf`;>8w7GgY&A; zH(GATO;NJg5xj2Xn=15;mgk`gcmvR*z?%^8eWT^?mSaLd>^bBlGZ+{xL+r1<(Xvs0 z1Js9rzPXNsZ?vozNWf_M1}ca^&2LoxL<#0jn@aGFmgU0{&#yxMTN_}Emi)|+xy!1+ zJPwzVOJlUW9lHvq(Fx2x1SFFPjFyi?y_`<~V5+YrX|(L&c==od-bPMFnVTw{7_e52)f&Jg)P zv<^^G#AF>6_(sd$Z3MImuwemIMqFUDT(!+i3f9>GEb>7rFj~HIwy8gB8+e!beA6RL zJNrh<9@<0R3DlFPLi$F_+a{Tb%K8&fpAi|1Q+>%uRJmugO?Ap*$}?In z$Ba*IV{-48mhz33XIaqM4e`}*rW0`m85k{}UF~Ic3ixLS7*=9nv~0D@!_@H+O z;TaPj?TU3_I@Twhe_n?{17l(yCJ^74$ce-^Cbs4xM&9zPV@y09jKG+Bp zyqreEQ-sgqy1bJ160(v0D#j!uRq>;q=vBWV%12GUsD+!Qh{}6yo$pzURPp`9!w{|g z{lrzHsd_4I82o->;Q&}osQ;ATPY~;UKXLCgyv~R;egQU$N!cQy+rjg`pLk-G0q{oL zA^>zI!2foTT(AzKx2%j0A@4*p25RXN13)Z$8`N zXJ-L6-T#hC^NTK-k2L`*5`t*Yez_b?Yw|C^Dtq`&gkGGA0%Uc;+A$9^X0M^4g&6Ml zLBLGq{l;KY&1hqX*Kfu5U5E}|^a@@OO+Oz~C|@K>er>J!I5CgoqL&VTgDPh9WGdmP7YsdB{XP0v`iO8YmMZJO4)Q2D zQfX^Y+Kg3p_$M?B1s?x@kdGl&d!#WnJRD6)9Y3a~BM+%QLyY$ZtYl3dHl^)B+lG5s z;mZ=Hv5E&nP3<R^C?Aab!XKlatBE-}$6IKMNnWP7>aTF;1?CUyG3w=*%PyP(Ac$`#`GA|S8(OMrjQ(P+Ouw}fm&9n|*Kdd)?EO;B4vAJUt! ze&NytdFg?9u_9lN`ihj}&Rp5J@E|zuHSpH+E1$@?^MEL8uon@-MEHDoJdrtnLswNeN>_C2boqOTCq*vs8OR0)xY zZFfLa3y~4~xh05xLgd5>nt(W6h=SM^B>D?c6l+XkfDk3hy%|X#*2NvpKv^nQM&D#k zJ}LxaRVKqK_C2Puiq#Qj%T_L%p}6;4RBy!<(FPD|Hf^b@xH3zy&896^6<3)`YBud0 zRdG_#>0dYL`ClIZhO~b)06?cj1 z_8^eWyCs|5Kp>y@NIJb@3osc}+@Hx0uPbB!aX~zg`89~@X44iz!Na1UU+k-y;5;TW zLt|}*gLpjtIr{I2*xQ)KDxS*fj>;Gl`+*9cOWc55Pl!EjgE*1SZaXFR$oU{%kZPZ$ zMzT67p~aJB^b90wKFo3ZfOABL&>$Gf^)3c5(IO`;)Yr= z-^wCH_({=g^$AE}-^W&Ty1y#C7^&LNB-6-$SsQRxa`O>dP=-p$c6_Y+z$bN%67}f-a~3 z4XkjlO5SDUi|`^3q1*Ir-e3VnN#v_`*v}2gU?C&R&spto|bya;7AA=Y=Z9KGq;ky$NiK8;#LayQrN8iT%pz80U zriKEH^mJVUV?)(H!fZco60~@dj5{54oOJY83!sk$^n@>Ja@eFZMrl=%79P*?6SbnH zw`y{23o!Bjtkli}{!*FIY|MOBpGu~9=%2|?pF+%`Ri8<0^e2i>j`B#wUPMR_C8bF! zIfF2|b2UIy1jI7}O=Z+UMn?<)Xu9NM13~nZ8)Di1gPVWV*&@$Fd5pY-Qc|M6XnoA+ zRi8`No+C1)7Vl;2eIcy(e3okR1+rSz&=jBN5*pp2meq<1`cpL!?G1t_7Mkie%;@8r z!TeH`@)SeOzF}&qNeE-Us@TYlCyy;=gg;;xX>tz+Lsdru;E{(X0p3IBsKOr+vuSvm zU!A;Zqvmy#yQ;H6@ub9L{yacAidEIb0C*N)Y92nz0v=Lw7^cdQo`eU=TjUNX)@8IxI3(Lps}Z4egEX-s9k!t$Og3OCnL z_|*!qwn$!hnq#WegY1D@V{Edg1F4_^HRF^!WIR4h(JL3Jvg*^KBw~3OFV)S=T_x5D z`K@j)gdK~|0MSB-XzW(>_3D;FBx1jys;gTGkrDeZskN;#k_!o;j53)Q-{vu9i%O%y%$d`4Bgru^hO)^BQ)?=n?QlG^-~d=6X{J-7(5 z4@ztt`=w;by*h4x4)_mAu3M6y%(c<_Z|qE}9ufZFQ}IJ3;6Ew+`2k;sl*l(}#c@++ zh9gf0l?-4G+KHiA)z!rFv`{ZT`X#nxRqI3_4-Yl@r9KrsA70f}!s2w&D6M#ESx2l^9L){R=^fqx&$*%$VJCsxw05eoX|YtC zGB@e@4lw1-KSIF>RH5SMF9N84n>fGg3E}#mhUWT+cWncM5##w`bN6cyIiv!m=|7|4 zlMtXKsSB>=8}aISmEg>7`Y&|Ek&LCWz*vSlR-u{aJvj)eqe42Cp&*M|Vq-4Uu~j&g zYwkLan%@);g}=pGLU_ko{MK5`#r=Dh4@RO9 zJ{IlYtNaXviw`$u3C~UciUNGmz5m9(`=B8(Z>Z#Vkdxl*i$!)?zTIvrzDwu3hqTs& zzr;p6t-W2pg^g-OW;Bl+YX@hMQiFxx+5U5eVGjUjl+V?fgvg`av=(;9t*D4FKY30Y zVmq0bT?y1{;hjf`JOT5|#LFOx5sGyF4cCl`FSvi=8n-}rnpxr84_dDCXvPKREe68B8J{SD_S5&i<(`L>>? zq!oBwe7>iIPps3H*-n4V8B(kf08A!`#nKF^hI~+v*4*y4h-Eu~PMEgZcK(chDS6)n z%x+3ZHH$>}0@l`g+gX6^jTGQU0PZ3vsW#k`wNzs}&9XgBF9Yz0I+|{!rmeQK1-(Et zeFMOM>u6fL44|F1)2btCfceft-4wx@#tH11>9_Y#iZ7ch89Y@z7ofBCKMevHE_~yJ z!zQDXx&98yNb{p}UT5Ok{XRtc!|BT+jO`Av|05yucCkO4_MvW$FqY;zW3w~E>D!gw zAd%s8`3jGc;ndyd$#D8-RqAm1pnL7%#Mf)%|3C`Vp#c!|4WS2n>v7ILYI)Nxg@e;j|GGqzosTB7@;{LkJJ4Sg1A7wGqxD6%41xN(}o_ zaIW#W`dvbT;WRjPI32+~gFt-(9$!MTJ`k`!ocg2=r`!z&qkjPKKLI!xP8+-7F#$7| zJ6)*;a3*uXaQd+;%nuOL<=|EN{5r#F1;(2wnFPReAEeB1!*EIiUzDr^Z>!I*Gn~Tc zgi@@-0Ng?li=`P#4yTT(!|D0WUb4Rf<~>SCHH$+J^Bs$W#%L7DPBw`h%AleI&5xZkN zhz>&J#0oou=qN-%EYTlCCn1Vr8_|dZItx(}E5?p!K)DcQu}<|tbcxcU(L7dI0ivrA zEn@ehcMj+#M9bL0i6FWQ(JJ;oTR`*>qIK*Ls$@V+pAVv!5N%`Yv6LUsTZneC z7aD`;BSibytPLP4gy;}!jEWdgDMZKE-!BBwSBOrrWg!q%LUfMZH3mer5alX*2t8)N zXotH4p86rJYo4g}d15PAW9sD~TF$9;8zFRyZfx6kV9LV=U>D}nPWKg~|F?Dffp<)o z_9(a#&92Uj4l0|5Ihm)^#=h-|Es<)reD)$WsHqUPitGnwP_qz)A=2`;T3!^yO9n4V8TX&(YO1^s8uVY~}_Hlg$uM)it#gEyC_; z&`81dOUAZm?C1y!Few?^5B+w~*eLDBTNuj|bc`o^GV%V5ICZP6dIwE$Sb;pE*R%^Q z11kCw8hy|->2^G|*UQJ7XCrn&l-0*Gd^M96Pes3E`4>qRKlcT^9ZolNtwAef-;|ic zWJY@mJ^r9o;4cx;)~DbPJ%17Sdm=pCM^3&MG2=-=`dmlAUQsag&eIV-99ckcTVxL# zFvc8_D!qWQVkBZn$x)Nh2Pc4kOser%ExtDkZNn5f=r-9F^66Dl-s3+#5d6m_bsj|Q zRn_!L#IBM;^H^fDHI@m?Z0knngTG9qxK&A7LR6DpjlfFRG44dTeM#AgG+8|ZyqK0b zlUo{-T9ei6O!Z7OcQ|!3+2l|S0NGmRQf__f0-}3Z3rA&p%`H)qubRxD^8Px9Q#emV zPT@rw+gMKY&!k;APTtV<{Sfhe9qyJ#6r&63cU+Bvvz|-SN*pi}BWw zo~ed*b=NGwgXj9V`40Oa&OhSm^TBR}zlrnDcy8BAwt<+XBN3o9*(y4EAztFSRHmjP z#`52MRCMH8#BPZ3uY)=!V-+@r!>3B@z+~*aR*0>X*r`G6aor44uGOZ9DYj(YCWXU|@V9ZEWH z7iBmt$gjpFDQC|Td@5xfXx?9&D49SN1@8HJGeXX9F zy9IvJ^rNM|ScqaxQAMrcq(aoxx#)wsW%@hk`yiX3ApndFK=P~fzlQH z$HCKVRW&t&s<)Tddl18deay;`7Z~3M;3F#FZa|Gy#1uLZL@(`-2=X4S8}4_>`$G>fK~4!cR4Pz-$&oq6?wU3ro(CU zUi@bB{B7N--m(=q&SV>c;_=l-yy2zaM^YnB%eo)(86!GIGu}nPGDdWdX8c0}r$;ls zML;cP#~;-MFNVbM#Ij{p0je#|2_W+78r1B9?CSyQv#mYM^W73WsyjMy8p7ROwn%6R zQYBbCEU_>#SND+lqmV3mxIbY57<~X^u)3$PI+I0D2^o!b0IRp$y3Qa=o<&5DqgAT= zNbGFJ(!)6p%mM8L)fEY9=V9N56+I7qs=88Qc~G~B&Hck94Av`0!b4wEE)QOoW3tO6 zM9*!FSue2&Ciqawh2g`u4scGTo)CJE*bQm>nbAP($O6B^B@JVP^aupvB>iT4=#1fI+JBtbJ} z;wU_qXAhRqOWaG3A(zL##d-Q);@%Q)NtWG=P=cPzlhWcmtj^_WjBy^)mk5;tLPp{* zO~Bwdjq|98#1-gJiJa5m@ocs-G7_&KB&WH#jEnQUiZUMKmH3jf{0u(MPx})*4j@6& zWp|CU$IB4`E?XxaT?X!*9pRBo&?=hv6`spsnxNq*@hv=;pD35nOYp1f1Vb*r4vq68 z;lvWGz{^OM@yo>oJ(nL;#?J=V14!Zyf5j`yTZhDW?dx_p3=>3h} zSM>fv&xym!rdLd_6}_(Xs_C6UZ!*2J>8+r59=!|cT}JOHz2o$jG2M;yE~Ixkz3b`S zMelKX4-@x1y*KH7K#%8_=Ke%4J%iw7|TP(a+8o zLUPp4Zo?c+dyAYi>;iIB5nrWU#8mt@VH+LR=rp}_k?`|)M(%p>L;K)K6}5((WIy(3 zzNyBV4oV#+=1Cv(slhD8;lcSFu%@^No66xBMSS!2LqLP-ZGAm%b?GB=O_uoPZTD6G zi-NDROQm>H@KttqA*A4|ZPC?83clKIB~4Mp$3|yDaf4~oX7Ci=lAg#Kh{Yt@eF?70 zd#40e5nw{A;7NHe0Z0|`z?>U=S!aXOg2&@byLSVYcjr6x{(~l)Hhdz8&4y4#d?xj% zFMtDfn^sa!-U4)om#F^>U%%HKq^?*3zpmtT@gL$FuJ-bihN%IVr7HGPvTkE9 zH8E{5Z3HJaj0PhZ#kOkmqgS2i@J&R7-=isLCCiC;DpPvg6 zFZsbCqjD;w%HyGM|02l3qDLCzZ4u_vtqeq2&HVTT3JKwPI2gljDG#+;Qs&+Ym;rFD zhRdWxW+6OP^fS9aOE;BlfcXa@KhOR`Z-+S**#xC#5-^z&MDul=~_O7xbbJeq>bzMaG3;V zz5!3=$uZPxP!oLLUj)5jDBU3FHhwp7`AtEb*gSqo(2J7&eaRLGsG^>jNoOK-s`tZ- z_$26JFird0R^uXcIuK}o+iLd=`lPfJh&~}eRnatPyVKXk?3g#QrKjZa$hXJA47~tP zGS3e*)v!|B+P*>*e+kSw`d~(lcTf|fO;Zf#v`l;fQE(6IJ1~K|kLku)&7cG^ec>L_ zh$(Nk7K2V&<2=N%=F}NE!|~OX&VLi#^$_SQ8J7n330;r<@*~h6GVVg)UNCY02K^)B z9<5R8MI)QRX%X&>DMw?hmiw}a8wYwgT*Z3G@~5Z5bD!7gW7eVd57*$8 zPOw+PW$p)I?|^p@)WvZ9i9P#P#5@M-0l12XK=5a=qMZ3oeiqf7s8Q-uus?=VZT<)2 z48=2E6jx`F)24#BM%%E90_Hoo%uEof1%XGF{`%We85SX%31&O^-i-d%Vh|y42wQ3`{m$Qw}~NEFb2~4`tXKd?jEvf|KEh zlsSbE6gfa;FX`6d^-#vCp$$+i;OzH6R3lIU_n0P5ReV~5T?a$gz`1Yfq7xKrbv`CA zpte%10K~-z>?PrXIEKK@aLqX#P*_tqT4d$gD-m-aSoaXidEjXT9)~OEpeEKLHho6A z&GGy$IPVb35&lmE{zfPVFrlG4;9=ixbL{d(!2c4;(HujCJ6@$%aHc&ANc}iG_e0(I z=(&L1kJvmwvf%7nK(s`lDT%8=^g*BpiM=4kATS)RId7)aWKomzi>`0C!YyMFSo4T& z1mb)I&Lxov;t~Y*k+4A=L*RP2=3JmqONd%B*4w3aN9cV9tS5*)4a7SLyhWk_#ODZn zOu_|W+bAZ8{;xs!>hKCV544(z!5lURAOyn z{YE_w&M`vSs81vCB%y3nLc^cI^BeVbaCk(nH0nnP{1q1GT8{3tbD2TACT%7aQz9A zN-w}dBnwU|{X@iRN7t?Na_~FANu>`$U;tcy;-u0kWr>tu=@Y;oLjhL$LImc+B`ci* zAqoVQz8?H@D8NeJgTQV$sdQp(V*N@#1kRO&veNHD;0{7r>4b)}0re~WNpKz|lq2c) z2)qfG{8i9edjn|Q7()0r@SI;*@&7`s%>(%U3iO8**C2jC;5)ef#5V7EKCD;N)E1O; zfzGzaB1T0pdMPjvL^g;_x}G4K^Y%;uO@V0G%D3||JvRcs2+npv@ZXo)QGgTo0Imcn zU{N6UMw3sNHLe5g58?F!t_KC*0&xZc!{AhlyWr)b3t*<^e9B*o{_wcLL7cr(@o`5U z-w|n4gErvYEVoy)Bq}$H^H4^(e@cw0UBCdn;`7P98A92I`Qkft=1_bo7^iJ4aivsi_1%HI!&D&nV+ zmx5iV7Yt7A1%s{X$pYr*kx!otzBB-@P~l6hzVc|Kh@VLQO0eG@f)|uzH-#@ArDMo$ z3WW3w^LAC<%5tnjw;_)@ za0=#~32+tctGHrZHV4YL-3b4dIM&MpLY!u9VDndaPEM5$pE zHE>S705O+=e+itu7Q`(G+(cp_h)z zvqC%ey@+)j41c(R97g0?0c2~s&7s8CZ8PBTJ74p}!L4i!%ASCeh8kXbL^3tEInF}C z^#iy}f>jZ}jIDn`%7_d$sX^c1cntam3G*Ur-a{p*KZu6-(rqwaRNnkncnZXLepM;) zyc1yPtWi!@xY3_Ls5~AZHJhL%K4>TMtMcCJiIpScx7CWT?BCdQxGNBC-Rko=K$9J= zC1svMe|r?yr{OY*R+apBCRWeyL0KQelT2|-n<7hmeltv$xN?V+Ni?R?A()u9@uq-( z?ZN$s<(R=Qesdnf&J4s^B+5vr>5~`3$1ej;ALMh3O?no-?R*JzFzKO z3H}A^bUtO_?=3ie@DDqgpCv0)r{>Js4j{L}ZPxN10iAmB5z8S&TnRUT6IBUi6O=7) zdTcuq*^bEj!95OVuLtob1pWZmocFsj!co;KJOq23O^EpctS^XN1)>n6B^Rzu$IA>> zQy@ZoFDq{y^;d$!FZWu(sV?XtYVbf9KfvOmWHtPe*1jeAdX(;Cb3`}-vZwh$7 z2fnQ~xQ~EYV~-}mEpG9^DWxAppc=*pvR?wppH%O`*o7E%H2=`X_7E!cKDe{U<9h&V z7@zZ&0K=b==$R_<2cX~dCHRg2{%RW%{Eut?jKrc;iSL2_+Lz$_18O=SLG!m4P9MDH z03L;FPFRid_@Kwy*Y7DkU@Tb01$?NL8N+HB?rF_akRIPd^w9~(WrFrUYu|`xbblns z^Q77WRtC3KSBy3%3~kk2x|q;_(H9$|h#Cqtx+FJy7rNF0M2>~TXgK>U5N9DU6;2IU zh`ENn!J15bY5hlt-;BsLV6P;89f(~B?1US@32z|aYAN9LdiOp?I48X;z`cxcPI_FG zUJECa9^rZuwR@A^o!}fNl#|}02s})Jlimpgo`b^xpcH#8TYDcSf>yk@;J%?WJ^oO* z#BK=k4)c2my$RQpYeE7nA0^f!t_lAN_J?q?N`yY%&~OAq zEn*gdHJezjkM|+48?M!-HF(z$Sn<%wl)I|Yj*EbzU4zfbuAvCG*modsI|=S|_)zRY zxTZ8(QC`!de6Zbq4(w-$=XRTq&VC0skcKNlEg$c1x!(u(J;J%==JT~r2Jp zAYgj&=t`c7$+yIMf>FkfsP&^dfM&Oz*?=V&4r$e_$%%nm+2GLO#m*EB;>o z9mLK6o91@=H4w`XSOC|Cy9q*Vdi*&bT1CC7mYaoLfb4`*ZMa1dl>zPptKNCU{R^Bc zfVm9L{tUzo2wX?veGqpca0i@f(Hb827c!>%foSztWMnx4nqGo|GJQAh3ikJ4JO-gh z;F|vGq2#?0qFAB}bRlZT&VcsR+Y0D(LbG%z(o;54|Vv|p^F0(v$T`1YkvV0R#%_N6KWDoN13 zG#ml`i%3)2nJA}y;lS235$y5A)7CT>fjJ~-Yg&oGa=3xCIZ@8?g|R0}+MLb<R$+vu$DeG6zC-Mlz+MhFkZW{utpI}U5ZCF~gL@QCe$wZO zu<2#Np@(cle~>$NuMVm?4wK%VW*eQ{w6>?jYv8>F%f$Fv4^xIjGg^UKt6{v zot=ev*#d?1*cj-UG2`^B?B>h)9W&*F+%`LINepv z-44dF%ivYMU2S$Z9MB;SWZB)wZmN=p9CPQx!5iYh33$n!PbL3%gdmQe5XVihXH%8k zni?L5Oo;PMz)LE~<0nI$c0xUU04*;n?{>rwVmucZBKQ&G=kWD1yC>Ha%Y24Bn3R{v zS`vIKChkqR?uN@GFq6v>mB%k?u0kkuJ-npG1m9vQ;ukUOL??gdVvLNp*_9MCM#kIi z?j*2#-c{o5p4rtRSc!<Wv&eDE8>WfH80@x8*%Ao=5P)dwem z3RaPg(W;H$p4DWc{bEN$*Q;hXwY>@CFuuXKtd=lWN`Y_%1bf2C5_I4KNaXR|Nv@UD z9q=TZT&uRe|9qsJ-E1dwTBE7teN@HE1medoqz~4=6wj(Oh4qMSnyW88a-hGzq@c;a zx7?b9bSJ>ca%&C(vq*5cwG4qJaD2+Sy9_PylGUWD6=@7hIDK$BUvK3v3a1ZpvA9{c zXbX0m{(F$pMo6!NdtT33v=Wg^X{56Dt?aGx_}(X%j@Djy$?|bcTd#Ma=^oVg0($H< zxHA8l6v*W2Q|0l!L}t=@51z=gUrGJgPZqI$T5suxf;`!cuhFWOlpoLq%Qjqpfy<-9io^E%y0I_yhb;!2z@2|?o zQ8Z0tH^0Mn!r%s35XlSOUy z3pFU4*~#s!1|UAKtsam)E4##Hp7RGOt6*aRmScfN$xyNi3R4)R4%6~0r+(*@^7bk$ zD%A^--3G{c)YK(&QN+|rN<&Pnp;wzo0hL^euGomhOoEHEbtv6+O*2uVBuLyVr=NCd zsw!+q%9QK&aYN}?GzKD)jH%bMD!<}S^Rnl)Xw!zeL-r{BK$V-Rvmz7RiQ)06sb;7; zmO((Qy5<3FY`za_F;JhY&qF3#wuO$x>88iD3Xq;ccf3?|YpW->RR%BbCwFCVBwyw4Lbpmb&HWVl@s; zjW$uk%(!Kul?CerHJqJ_vzs@Qogt+um5FSSKfR6cnu!~tk-1*~8D;ddw{$K{slw60 z2t z0+b@DB{urSqQX9$8|B~o8m-SlI3zI#for+mko5F(u1My zrD>)M?Zii*GSRK{`7w4d+<&~zic>*+jzf;M7`=2BG_N+%RMQznV$?bQ9O?8d{TtHo z?qb+s`ix#w5n7xswSb3ga_cPZ%>}`r?CrWV%9{WdY?x9@`v5Def%Vzmbh9B>+W%a` zPwQEFWfWsU=EjbtSP*X9j_J|V5MD9i^pU)a)Zm2%bN5K?Q|BWV&5y|h`9ev89`>4;o zNPFW3a?*SD;Imk$@{%-t1Eygu-3JTkeMxmPtNV*L{8<=Pd2*uafbPKsAYfcbUCfer zOAoMFm`k+Rr~SfsQ{bg1rO~Sp{gWb>)nRd9U5+ogTz9+XGDh-5;1xP`!2%{WF}f$} zj;G1y`?HcvaR)Wli{M`kJ^pHlDh_G(FD~V{Dm<)naSuIWFkzDvQP=p|yv$!Kxk>Vm ziWWn2eRf?fx?7m1gdyE%>MHDpl)7RXH=0tL$v~E$W`?-Q^f^ZOl8%)#xo^qJI;C*y!JDcq4F=e6>kI=HC- z)=(yyyJ{uMtPgeNE)Z-4?l%3<8)HPU+u{Y3T8Y+`#M9`L_>^N2?(-`Zx$v@fe@YbJ zMeQm}sRy--mGVO=b<1{p*dOv}=U~V`qP>~MYy3w63Yd?f({WYvxK5pcn3X3|#Q1iN zS!j^+RIOCK+2(0vXly>&&jj;{$9h)tW{7(rx5mNxPDX)0y>ZhkbC|d834~u6 zA{X((l`5-pNLk~=Ew|hf&&y%3O>?dCvJcz)^`-i^*|oIj@q*UlYsXG7u@g`aD1w(_ zbS+-IF6!05BoI&{3DiIYY`p$F)?T>|50LFm`Wdaqdfb3tAN=}NR{O*D)OC6SK$mL} z3SG~ys?L!Rg$|>7p3`1f_>4WN4LYOR3DhIV#xK$lo~OKQ5IT7jwqoq#S0Cnl?>u>dr&#Z z2CE%_)GGV!RuJ@Wv!OZ45@q?VPQq5{=nCmskyUCv3lLz&p?(6mROPAQD6g-Q=A+1| zFd>6UAlV=|3Shu#AF)+)^!B+My-ps)jb)r^YcH-5`Zwaxt@#46FRhS&s2ESycrjuH zDm=B4Ge0R$ZAx6A*7|L=Dd`2dWtR$)^3#32L@xYmC?vjnP-D2Gebo|JGHqImE=Z^#=1Zx;sd=Pfyh~1pdUqz zp=buuQv@c1jPZ(KM@Aj6M<1|lJ0k*9yVZ;nYLd$iAGelbA~v&Z96HgKqQL5U7~$I3 z2(dmuN)+&2R2Du2@#hz+K$BzCMG?t*Grvd)t~RH0yP$!!OquDQ)AA)6uQCb9!xUi> z+pF)vo!f}QkCcgY4y1GPDZLAC3V^ss?-Oa6RZ9euB8?R+<&?8ptyme6DH*EF#A-p> z3S*d~VTaT6C(ZdFc!Nr^=ccl^oW$M~u%mqICLG;cdBEP=_W*~3#6*16i11ZM;=uzD zZ-oB8WhShpcn-H$^A#mlhxtVsRgt92rK;%e<0xlB}g}IYS*%?`K$-=t>c7A<3lAwD6uoRoM}ufdPx$YT&Kf|~XT;6o94<3U*+ zP~1?I9o3r>Bp6z0AI5)r7)<2IYZsEwwnV0z!b3NgzJPHs!VXIxp?0#;t&V0E_&-4H zus}_-g`HCn*1myweb+GX&KC2y9Lf`B+VX=TTVk1WJ91LcT8XacMYC^5k~&axYgiTt zqP`gnhnFcVfdi5PV6B4}O0tAZVcDihQc+MHpu8|qXp>ZwPl~RPdE8A@GH5!mJTO01 zZS#JJ0`NKcsn`+6=#+us#7;r5hJA+AFx63~txTi-ujd(*l5!Dmph_5B%#W@;>C5yO z^>mltqz*~7de=WPV6%~6~ z`&w34cSTtRE3O3_3hF9W-rsZ1@7%e$GZQAR?&lp1-+RwJ_w@3d=alO+CVLObA3E0Z z_2-KN_RJq%nqM(Ff6BC!VX1ARBM67!zKLwN9{Ifnzpn@bknx60R+42nJmd z)MeaMtDncG_Vp{hMwNxylK&&0niEN^zGY&z6N7a1ga&N)ZW+;WBA2NOEeq} zC&PhA__$D=w&t%3)dyN4Nq=&Ab4Wr6dBvYd)`g?u4*E*_8f|k>-$<;3%g~I*)zyd* z@VY+S0Q*H)BnfvIUwIm83x=AL;aJq)oMe)~wwNX4v5AI+UK#38#RJiXP{JQ}j(>7bzHONN^Kp?Ex|QYwLf zhUz3C90dmPN`(9jPAUo#A#qr}tn)SyRYeGCEP2@+2s1tFWAUayQY_cEL=li!G!Ri? zf@!02qpcYwGNb~UDgbeR1Z7{Ii*t5HNHMbu15y{IOs9xWctqL6K4qY?fobCpM-!nq z3t=-1S+3xe3Z5vp$x@72Qs%Yp-T_E&zQ#cXC z6{|kwZv5rkxV$w&oncBiCt?T z0%wr|juZ;Dg@P@rS|Q5fD^}AmjwDBgqtiqt(*f1~TE2ZOAA$_= zs;|eFx3jNXfoBTDE8m{RxQ{a4v%pgVMJpZ*GY@{H9t^V|3^xyksRzUD2Sd$+QR+dd zc>tZv@#fJ;kI%QW&r`6o@Ay4^o($0OzC48(Ru}Xx@fDSo`0@(Md_xL6V*jvw zpKn+1>G@OOz!2rYH^-O23wDL&*LrisC>yUL=rM1Kh5)? zRQP%hk`zMrDjs`uuu9`Cj`JSgzKalEG#@9yXQ69$g3=zab8(h?X{ zh{0h9R$hLd_sl|%ukX~7{BBYZE=`o8l=VFzzq@aD_4JM+DLZ)*gwYZ=@7?*TFqKHa zzgy zLN&nqdv7Tc0{QZoRhr+!=kq>uf+xQxEX+V6d;8;BUM}#~d-8kv`g(80pjTf1WLe1p z`VpRp4OIdW;R5d~NQqu>=m!LNzQ?z#3Pg7g2D6AuL5Vgfwcj~RuIl9Fb;og1WU^&iSKmI~Px5r8{pmLdT36pV?^}5u-(Gw9#+CW@DfRgV!kx)*)$9Ft zvH0$l5PM5}I{|s#^Kq6Fh!g)LG1vG!k|^E}j`w6tlU`yMHCGbD`|+|8lM)9=l3@&M zKUa>bDCL!i!$wN|#heb&;@EO#v?%sQ)WZ}JC5Le{?C(Bee7l^aFsJ9;QVTI-kCy1>g ziQ6ft&Z-1@Z$HtaS|5-1@#Cbb!p+@KT6|Lr2C351s~+xpRhjCER7S9;DzD(pA*Had z8eFMEx3ADOeXUixSDDnJJnwBVGHviRD^#hIS_Ln*cR{`LzR}8ZQsDigw*TvR{8qlscK`~?NfpGx@^wt zyn&|K%xXL6WQRTG$9Q{k_wn$+BqXoMIUJf>>l9GF;{ zUmQPE=}7F?#)P7ERjpz<&FL{XR2q+#1ryD+@ngiwoSJ0$c(=fq3Y2lXYFuroAsofK z5hbQ80(jN&063Ovn{d6fU3IbA=Go(`Ky$OC{ZjRIAQi{dYgK_7 z=4Cw8im^$^7Rs$;lRps(T8U5+qt#@{^4Iuf*oi;6^}}HcNgqWT%1A37s&7d^+~=?o z)-ha4#*XnvkXBhjpO#MJB%R_i7ziZAgQ^8AWhfOpOy!A9fi`~vqfA}aa(N}(hP0_) z7Oq2ZGu8oj2z6?Wm6BhRj3j2Gkd;dzqX0iUSXH$UW@Gd)g`<<%!A1V6nsNRGbAlGW zx7|{2Ng--R>Nfjpm-`dVC>GlPu`awNIRjkBWiByhpakR_2%w%Y3RYH|3H>HWS;~_)uObvtG zc1=RSq~%=HoKhL-8kWk~^n%Cq8jn$?)X1eB^%ofuXdD_FG$&|PWTc#AmCnJ#ia?Uh zon7>^1`gR!gAOAUJO-_LSeo^y3aD!5**sf`M)VjZEzv}{0fYP!)J02oZ;M1dqdTk} zHcjK|p`ekD&Tlu(qGLdB6bT2HTQU}hIt)+I<~HGj-*DDZ)yHB_oI|5G8(EVUrz)x1 z<)aZHw8e>Kfo8NrWBoPbRfap<%GBG~jyW>IPCaLxZJt{dwvbjqD;Pkd6;2}P?tV8U zh0EFRs>ZG!oxqq1-Ga>d*@6?1;AE^L?s{uyfP_pM)A~@X-jbHJe7uBe9kVpl9q-~v+5%; zbbCoF8cT}uO?p;%fl}E3m71R&sk?LU$YIKFa5{4;Ir5wJRkacnc94-1kU*h^IAjxq zM|9T7*|l?PM^{x@{$OhoAww@83PEmjNK$Dr8(9J^*5t_)3}W##3)4!bS%GkCH~~2V zk%x*f3MWzF{Gz;rVks$8YEnr;T9SxKo1`;pc0_vI*dn`O%NpchYpv?`Yyl-1gGvob z--Kj8)b1kGB%mS>G=!{Jv(|L$pr@t6lv+&bjVyuYJ2VYFXCTs|)t5P^^Y}nQ8k8!e zak{VznWsvmuW+JHi%vP$7`xbKuD()V8sf2*W~i|(zqCM>KPvKwoi`GJOoCH-Nf}E? z3!-~67KvE3i4Zj6D5n|gWBU83ck}#-MrhQJ@k4H}4@>iCC%dFCoa(%c1qtgXyp=83 zc6yrbKj(faJ;F1~rTvF|8-=R4-Y#iIXw8yv?hwor+0E~lw=kp95cNmuRC^J?q*7cB zXO>$`JcuMa?3i|34l&<@M%L+J#DbaRP6slNJJ@JfLh(<7D)t#kP}5oS=}(G#ngd}$QeP%1eGEnU5|^pMHTd`;%i zq-XJ1kw_(fI*KD&&tSy1l$Jy3u4<7+kItntHT`JDwj;eeQu4kUQ7)CYrR1nq^ylh@ zo0_B-_QzV_D$-OYiT!~()isJJ;OrVwVoQ1~Q9@M0Nv!PV$PBBT5>M(?C?r(3B=e7= zpg2Gp&Z?@`g(znW7Wrp3AGm1r&no{Qj3{py{n;Hy#>OslF~w^bXeDF8SOf$9q(9Np zEXoM<@V0O%!igz7z-{x#p^IB-KVZ1--E{DzNh-=RC|X zu2I=)n)Rtu)B675ln!+9PJ1k(0eXEsU8dwUmR~h<=hqTha`}`TBnSZhdIHe3q^pF#@eBbkau!T-c%vYoWM=9jp$mAjBYnyT|TDWEfVm+ z8eNRDS0_6+O+RI48HcF{vgyt4gd@ZqIdUM!r8x=-N>|uwrROeN+>T^JT9G19UY_dk zvvgafx9)yN%nmB>>%>iRi3NH1)-{piZRa5MsxNWP-u%qD#ga~PA6KVhkSqmMLouC~kZPP12N^hM*(2OKSO$U02SW~T} zLWXzKy+SL{zOm7oPpmy?X~LjWt(t(CjImJ+qI?*svhh7Y#*787o1HA;+UuFqNdcn!LMyOh@1mtAgs>f(oNobkUJ>3&E zf1#E~X>}PiY*M4@h=c1RRbZGL(3u=NMU%NtLbYV5bC8 z)mzphw`4S#sRFwTMEN8H6ha-=VJ$;R5^)7OOSG|>hdH7^(W4K4OmsL1h5lrf%7!Icy3+-lb)ys$nd8zk zbe$RcOf-5dsK3U@`$&eksEhpZMpamH>USoHQZ3#J1-&lmovbDh4%7@0)TwH{VJA}p zjTb9*rRcY1X=$z%PG(d^1?#6GO{QqG);Ey|62Y+6-m*^bNbc72LlC^Bi?sV$nZ2E& z)P9zK?twGr_!milQ9E|zT*YX7Wuz_O5cO5pn^JiVw+rcrlsYc0Tc2jz8ikyeISM`E zj${2^%mgJ}qnIX8Rk7<`hQ)xAjFw!8det7P!FgLfUMs3njKeV6=D0o=30Ny=bD!(R zplgDkOKqXSnIfZMjt}ILx&UP?V}j-u%usT`?5NKjPH=SG#OUIv1m0X4eG1pD78iSB zCU<#Lt!TzXw9@jK(OtJh(c>bt97F85ydW$y(RiW7fv#2$Jkn*Ju_92U^i^!{RawlU zJ4p2wG7HSgr)Qu1qH|Byp(5Lb-~<^0n|3Bk%}lvy&lq;PZgSm*8q-_Qykpg<%mtuq zN5jyM#6z_hmpki%85-(35cIbO^txh^N+5zJ{8*M7#KPPJs*)&4p`q7Gubdi1J7d*+ z+_Jg=1X`Jy)B1R%w^{QLh=?4uTzVY{9t}uGw!GPzQM>$^A$I!U6xpKI!z5!ZQj*~9 zauoo(mDzF5rs;){tx7$YlPrS(NMkD5ZI?JBghayQl#E@q+=?xWV(5r&tWLW6w)%LJ znuEuZ58R?4p=VPiCX@7$>bsW8%W57;*4?A5HCU0>1}ufa$kg&Lt4rufu^d{qR5>(l zn+%mo)ITT|nKpTdtB#hVBT2yFI(pkI6Ro zB6KV&Y*0pOG9ZUcZVPSxfWJKRxLmLL5Va@<&t$WLk|*;WYWN@xS|GA4usq=p9ovE(1G@7}>rLGC#7s7&EtQ(0 z6u?fgUr(lXtX1qt>!fp{M0ywmE{oz>iO;61#K(4(hQzu0EQAbdHwzv{D<++1&U#DJ z#7Q`o#W4u5XDL*;b|fmA6s)QmGr=jeMw8fwh>EM0nyADR?Kv7-(;29dvaLRBzdFP? zYPa;ZJyA2NM3FSJ<#)RQNqez#<0X;bvTHgrR;2dIb7$XSs+x-E4u?(YE z+EH~&6?41FN#In=klqFwCELOvT0#Uo0QFupqDO#c;HR6E9m(UIW>ozvRHT-)hNjtC z25EzpEQeVb)nWUOm}K``GL40)h6Szm(hO{NLcfTaTBDy5eGm;zOmh+1;T0$H+D#Ea zX0DSdHzj|d-)%GcBX<`vLFS#HU_xEz!WqY)UX|k{L_+BtbkSfp9t|}>C4sS)ELq64 zEQ=6`fqBFX&{8YFoVtW%Rb%yHCB2+j1ZUmzaKU4Swj|XRn`Q_}C%eCLA8Dw82I>w* zoLa<^b*|9fgyL%XiLA^Dvkm?M5gJ9sAvEydm_-+)N3_IopmCoXI1mJ zqp}x}rJWdA)+a+)I3YrJSS4%D%RC%OV7ImHbR}WTE=f|#$iyC%XbCd2MhY#gnv_Nn zQk%lCYtv2v2sBtG+JJt;!pa;i)!E+KO}rya6mC0OikEIXz46PfD@o0ph)@K5hE~Ga z6$IVUj`E|*GHtmO?%Y(OMg^>-sN6#8Sfz!*>9Foh9(;wv)1zI0Oug)kItk- zO7EX4P~F@0Pt~*MR#_*SiFxU|Wg)ko<;uJsxLp@(nryXf%B)yrdua;<+@~CM= z*))5M)IjtxdY(L{cJW$j7ORs!$TIl$i@Izbms_xoB#mGlNa#JaP^Rhqt;wcl(Joq$ zVC(e=GUrNa#DP>3mR3b|r=wP41tMy>pz6PK6QM*mZmXI_hX~1DgnRg6H8knz1c-Sp z82f1TiRiIJppd5Z*p?X9K+2-j9NTlpJYCKy;Hczwd*MujoK_jw$;eg(g=H!B2g_D% zQ5DE8XWi)LSoH8dI%t#)wL@3hf4k2aBMVepqTJ6bPZAimKsffdS|_HO2&{aRY!cmz z>CZb3f+HQwxZe&e=jT z9K-Mhb0Do?Z-*@M#AyUFrccIdEv!ZMCmUlei9oatgZfZ2mR50VdHu3xtldjO+)Pc; zNV+=ud>xiFu{RY0(}8nQ8`OE6F_jiOO9N=i1IFO#%^$=T(Lbcr59zI;(t3%ABcdOo zhRHDM&4Vq8B(hv2Y3CfgS|E&=wqFP9TmdRVKosf=tqV7brX5VpPlU9tv?S@X^JZW< zWlD)&*pf;8*=i37a%wIpW{F~_3H=S^4YQtKOTBQ;6u{3Zj;{3B`k$*l&+_I^h`DES|roWmTYp-f)nPkvlJ4O&8CPz zW*T^rS4D|hjddoWxZ(q>j; zB!@V-)B>Gqyg0;mxxAdhd^W9Pdfd!V-J$*ZFZAZk&Gup@yIt$J|5sxTbOlDy__KvW zN+s%blc-GV)eJ$F@|B(@_Er`BM(&9zJrXtPxfZR7rlCx2bhNj~sJ4ClSRH)mlMhj= zdiC^urv**39mtWu9jQ4@t<$?nWU;fE)Rsvibez~>!i`pF=Fs~zLFFy$5u~76;su9ll4CGoK6@#|Na$E0 zi7DaU2xn%=M<9bfCX-;Do4N!m_vP%Oc46Y=Sq!2)&I#Jl1ezMoOP)cPsl&QA*@D^} zLxQRbkV*JJBg~OYJH>g2O@|{PGYWxNK8(x_#$v~WLzyQ&Q{xRJbS$p&%(0lQM)ct- zE7N<2Or^;&U_=pgC_tRCO9}0^6Q*vM@_?zx)KPQbc1QIy4$*Ii{frba*&9ra z3bHOD`u3q*6*f#|pPklO!w-Mkt^82y5K?0Z#4WR`Ko+kg8^Z|;qbumiP+n3Rn|ci4 z5?D9iZh5nG_fyih(Tyxo)3^R)i5h%j!J5*NVb;sYKcg~Km>nt`jp9CS{$#wCTV#2! zP9e8;th~ZG4~aYsV}z7i;RL-JmONoFsMqOm6($CV&<3F)(gS$2tu{l*wdOS~SYt#V zhZ>Np;=x&b9j*F*RRJHAwxkfl9Nt2MSgHT57pgbapM!)LFk%C-*1?btZA z%zK9w&)$_^GfCPUmlRen4Uhml(kjUhx@p+xSmF6Gt}$qbca zC2=N?rb*_YpTROAv)z4J5JR=5+SE`jH@(|<-RX9!#yHlEI%-Vk9GNUL3R~E^=}Jgd2_)la)q|k^2jk&pS?`uMw%60|GAFOzQJtcr zn;j!csst2Zbyjn`l`bOILI;thBXKu*Mt_Y~S*c9WRH{|VO66nk5migW;9`bS>2^>Z zrJ=+}%%Ws|CDomnnqlViQj?jlkvw5_seX^>QVMkQ|EBQ((NO*vR)c2p+ zZ6!TA!rD>Kw!>_3v|Pv*4lgOECCpi*x`JmLJDb!twLJ5-K(mt!rFXo$=V*7tg(JxA zmA-19Cq_eN?XqiL$22Yrf=iXepGu*ou%kw$oKMvX=PX6l{2D)E;FhOmFY?Pir}A-i zVG(OY-=X9+k)-$Y*Ho!dX{X{g!PIscLE5`m(ZIBG-@?LDF*0iATr&YOgC3P8Oc#a% zZW=^84az4;j&qMnt88SzAs;9QTFPu+sqB~34r6Cy)^UEC;!#zVIWLaI9V3TF2iEc zI)AO2KNUGZZG}fegF@2k%y+vQj+9%u)?@`@KVW)1i1- zrdJ}Hl_!3zlYx*F4JXv045oxKAJTX4r%x{^=hF&NsDP`T6 zhqnGH5|lw0x)^lq3DKH~DpZ!c8kt+q9Yw~E4Jf4=0^$lj2HNUq7GSBYq_<}s8a?FQuCEo`<cVfB}MUJS@?{qPZKZG;4GH$9j!yF?2W@F%dQKuW8TrJPoE?ZoiaPIAX^G}T>X zYW*|rg0&kWXa7+rdUM(Krn4%yg6TMMP%2CAxuWzmsPlT4yFR7}!mZ?vqz7bGDDvZa zVUtP{DO>8usTzMhR-o8>57QRSaQG*^Vf!8GRkC7C#0HEV^bQ`C!HyLrsiASI80o_r zW-e+-M3)6y7qrd|kFLTB<>qjrIT)EBN==Mu)mCC0>97FGDIDhj?WE<{xT-ez>Qv1l zSfjn$!8Ggy>a>tYrk<3jmD{N18E1UeYEajqKWZXWPX@>W3vSKLu-}KZHP`;JowS;g zcI>)^*$-Wb`5)vgUqRZ`=GV~bFzDHLyjjJsUU{=s=sda)^5jHWP_-?rEHE9V^*(kwlI zf=dsNF%mR$W7u~MO@^MzYK%c`<=iOMxrNDU7U7rK2>=bJD3@D;jT{JxLW#B9-Mgu2 z{?25+j1f}P!1@CT>bPAa6T8Y`ZCL4O+RxZ!klI_L0y0Ok`)v+W+sSWi!P`#y&%WZ@>D4)#G>OsT_g+wMdbu*xp zV-Zw5_Xe@lBLCb(-qc702MWu+A+1NpTt);Uw@8SxOBPXgWkygM1$0zUzM8Wd5Joke zO$lfAR7Lwm5vjhgy+q1o5%3X5kwD3prv2=MIFJ$?)HI3g`c~0%&d=x!b!T8L75!{KGq$xn7)u&ij%VyhjgU0|*?jpg^gj@7vu$eEQ@Q$x3Jg?~-pXuvMB~BJ zDeV)%^&}tmIH)5x@a-F;ph#;e>{N5C=rnB|WZfOw?{vE&t)HHwR=Pp1u*7ml=b?Fw zl8mOMw#)byg%WEF(Z;A_l2iR-s^V6)E?8s~J=s;T4*LPMf+DLD)}1t+R&{6XOpq-y z53iOHWt@zc{IzG|b8X_);NGdo?Qk2utQ=T|HOCDiv}zel&2XAUd%7V?%l}mJnYwMC z=IU4TMW$Mfl0EU+S1ej5+M5F8b4YCVa&ORVn_RQ2P6@I7o@$RDMxm?R52vD_lNCjs zT8S+sP^NVBS|yQVMXRn0S*D|v?1BJQp!;AY-M#4GJH#xl&d558XuHT-hmxpQ->Gf> zMwrP||I*VRUYQkdm2sSHD~AWjk}8n{L(y1ELn9W3$w!8eA1TqprMtlFS=wd|bf)H0 zVOkK%Ae>y=ccBK6skYee&$dW)DbyGnszPWvFi1N za7qnjXQeF6O-(fFQki*d=1$LX_WW>@Iu;_OF_Avpxmqz(gK27T%BEeJFt%4RDVkr` zhX^{%Z#zo%NE3Zp)~z2|0_cvUDm2gxq7>*eCZzs4Rds2()`-PI;Wn(^$f>aCx@w>5 zw}YZ3l9VbmvQS9WHL|*OrV??PWUVm>pl0&bq#|b})VIIX8c2Q~!Gfar7^U$vjaNw> zRDj&C|KDUHdvWwM>O&G-NtoWFr{@`4lnV2i4Yfv{Ma$G6HFJ*oW6!v%_68b0H6X}R zW868LI+qWXBdL@m&Rx2YEK^0Zy}0gnDZ7B1TO+E9DTXrYWOpr-%r+;O?npL-K(3Ym z$`PkKmOo6$-5Wk~DynAmt_rJ5bPp?)h;BWwu^-BzuvuHzv5G5I05VMi$#U9o)U}+p zIu>7sFP_@-w2)`;2|-zS;rvbjPFqKwO2;atB}=;s`Z`u&X} z^O!?Oa&Ts%S%ru~i>8`80-PJDa}3Wp z=OTI~IbjfDc1DUI?OsoirCmyuW79HqdibliyEys?$ZbjrN5w;jpwAW3pCZl@2zTR% zkwWT=8>!I=R&i?KN%RFW>`|vyCFL}4l*vp@b$aX^C#W8qK!b_0Bx0uexR_E@U;q-( zV=JudQ!D^vKI=j>er{g(GJC=4k;heEdEeBUxR{NA~qtVG>o&{<~ z99g5zt;9grwH#d5sTx5!i$I>9T4{@Dcc9O3Z!XBSjYe*uvg6}b(vw0B z{6&c*BRMYZ%3Q|XA#shhFbryy#Vpcp{XFdla*3i{4&sBYhiaz~@5B;Dv_@&$6mv_6 z|N8J#qqTOG@g{xvioJvzO9bT`dI)AiET*?GrsNhJc7*R2EtF+UsZ2)qsouyrO-vr= zwANNuh{asa(^Epbvomg%)#*xn(M#eoB%Ju??gX?X zlu2~a6M$J}0duIZYPe`x{h#nLQxrNm3|H&v^`1Pv+)LJY@Bjyuf*D8TZh5~72S`Z+ zm}{rk`5~Cp+x8y`)H0bIbC2b2O;C3E>v2rR&zkF)hhn(sq*r2$I>KZMKI&&M`>JhPCxtjG(9}cSz+MZNs}!VGh~-7hTFR- zbxdvZ9q2;S&#{H)j>Fo~$La5x=Gf|{f~b46Y#oMtAW(g(rTr2l^l(w>Md~p~lW8Vd z9>Qreb0Tvc4zTTTx`|6jX3amiWX6aQ6=O=u$CQpKEib7UT`_j_`0}wOqnd)vEmMP{ z>S`Mmn1p+rI59OEibY4&HdpV|ORG>CI6|+HgFi1AGG}VIgrM#(ucvI_yQGpRn z%_DIB+z7{u4JD%vOq7hmI>f0s;#+w>s@_C(6f8@WVWD0|h|c?#sGMCmDkd2s@c^oKFj4)T!pobdnu(VVpr}x0BC#48A&N9RuL{m}OSd z$fsN6=-9eglN>%5jp6V)IeT5N{lN?#W>;mEjW{jBmMBW0ZU{y7rwwpqdFJY7ht@P! zKXJ&1JzD4j^eMKfnA<&6stg-_Ms{TaoXPo=&`uq%Ey9m{=V4hwof2uz>p;T%w3?`- zZP#Yl&S|35^i&55^Z!~uX0%divP@dOXZ}>W+JRsO>@Lwh<6yEITF^k(h$-GvzRJe0GwnPNl84 zPp1^oK7wx-_-jMhJ3#p%E$h>x@>BIZQt6#5k7etCtbO2eImf(>nN`mzWjnj5Nsb_p zt*iXJa0QYBl8mje6Wp0KJ38@fD)1qO<*qJ+p51yh^j`$gY${=M1AQ zf0>|UNC$TvaLy&zwQ0w@$;}QO6z-;D)Owrt%GuPX7SR%_g>3R!D6COK3b`tH0+qQ^ zresx_l;QDAvjVKceYuV_FgtVgJiJna^1~)+nSt_+y)2NEjC#=6V8Y1r3>%!<>pS!& zcir1L8ubiY7E_y6?1ay#09N1m7R5cHV7`Uw9OwioUl(R%R%#Q=lqm?2SpnidL?#Fp=@c^s+942{%rWAi->+tL z%^+PJ|EKGOtc_G(Bb=LBHD&1uUNrVaC0VMi$2B=BD^!Pu)i!dRbWY=R zOa!?$tV(;0op50s7>j}{pA>Q&G_P_12Y@H=VK400kQtaP9;F&AQ>1>1YQ!lj%|D@PJ{u&uhPW+o@T9d$+}Ui!-Qw6-QaYMs`0WXw)fzbb5489Nb4S{GT+ zs`j0uT4&h5k>2mNQ&igyvd zYS%8DLhs{Pi7Sl(vjV%CbEODrRO!grsBtTI*TsCDZ`jJ$`T4F z)ATahOxa{Cn#6Fd0#Vxl)mCTAtb$NVAGCiM5VSO_*a{CiwvWs!5rkNac>S(i+LATGHZ%SmL3%@8T z-{Qnqg-my0cR5OCOHF$2;M52cBrGtaB#Buvv_Yt}GL^0>v0Y1P8PQhTvsKfab8T>U z3s|FRzD%e;2o?^i1I{qBj}sMirxP24o%K}^GO=b@&a&1TW;E#Y;* z!GMIvEhMYc>(r6X%3AK@g-q-AxV$`Pnze90fIH z#n@rP-0DgTzi#;3j-SWMJE2Fn?&@C5*spDyX$^{%ROhQ7ytKkxwoh5{k>fGB`)_$T+au&+#BS2KG=1?x63_e zO_1;nak)1{*-zEQAujiZy6%U$+#lw8KEicB(&gVs_5OXft&#SXTzIWg*L|7GzcSbJ za+mw%uK1L@?2mEXk9D~}*7bb6%l+}L=M!D`lU(jiay|dG>wb#M{VD4GZMLl`_LW?C zt!b|NeO>v~@4a=%j9Kf|_FX-j9#{r)cd`@5bW;Cg<5 z>-k*Q{e0K`fv)?5T=zAu`-5Hghq~?$x7xP=&emGe=P;N3BVG4y`+3$J*bq}`nRmj! z&5k#u-#Zqyu0Ha?f0U=Z4` zlXx$E^dS6q0q@1FozQ;V#P>^Z-`hICdd&6wRo<^t_D5RZ(LQc1abt`)%%9vZblqR= zy1(Cb|Dx;uP27tYI(+5U54@M2VURW6DsyzHVrK&G#lCqS=Do-XgRCjmYcBiWxbC;p z{snMjC#%xh$I(TL`$xI%W3KyCUH6ysUc%Gcnq}R=dufwF&-qn)C< z{jMCMk2lQA>O*)Ak>0jfp8joP=R55*)2R_b>h*CF#P+is?cR4h${5aU2jOLM#GI37 zISvSOeGkwcv)Cb2J23r6EIK6p5tK|BqBNsi<_b~|GA|sI;YTDf8yXnbkzg47CdejP2JQy-pm781L-r5~K9R?L~Y z&AOj%E5qzln$o#lDK@PLbQuk8ZL%*S5sTu0l;m=Mt27CVYBHpgm}lB9Ear#I$JT1m zfMV#?S}scm6Jc!G#PP4(oq#1HQezwrq{5IYDkg^R{Xx=P4ma&*z_O%k*)u4nFgHUV zV;-Wp8NwLz2AWF)EGU`v~uoyg!Zi=kfjzLOi^l_jd?eEbBfn52E;k z33K@cbh;IvXjzhE#mg*frV#0);(wfF;eX}MN4m-bp$?@=oRb$-GD6c9Z9|I-l~EXc;4~PUlx%y=BR0F|U#K7g<&hxj)=e zGP+Pkr^4NZ5KX0Ms;MxH>PL7q=uPu@blL4HVnPJTxg7BW4^LF6#9ikwUO$$D}*xsv=H`3LeI@*(n7 z@@?`*(pRLzF^C*SR+IC{rR1^XdE_PJt>oS0^W-}6EAj_&*Dl)MJ;;&dBytXUD7l1e zB%8_QQR#pn;Zf?M+S~_azsTb>u4YO!9j2R`T!UOXU0HHWKPl<=@Wa?&K7*ikwF- zAx|RDC$Av?NG2hJNIcFVuOzP}ZzOLe?;;-{A0?k6pCex+*OPCO?~)&pTgb1-@5#Jg zI$T9$53�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

3c@~ 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

P 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

a=jg&Sx}K2z${yzy@PpF%pInc_u+It5bhVqS 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

##yJ}??I^KVy_bW6_1+eXuzbfO>^@ZO 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]VC}{!PF!YR+i5~LP6zx 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

vp?m%FOg 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

yLxCYF`VPTA2S)E~~dWK5>5K4t`~Md`?u# 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

Bw%&l}ZMJ#m{jqcHsw!%t1 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 z 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�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 literal 0 HcmV?d00001 diff --git a/test/firmware/v5-common.ld b/test/firmware/v5-common.ld new file mode 100644 index 00000000..7f262fc3 --- /dev/null +++ b/test/firmware/v5-common.ld @@ -0,0 +1,226 @@ +/* Define the sections, and where they are mapped in memory */ +SECTIONS +{ +/* This will get stripped out before uploading, but we need to place code + here so we can at least link to it (install_hot_table) */ +.hot_init : { + KEEP (*(.hot_magic)) + KEEP (*(.hot_init)) +} > HOT_MEMORY + +.text : { + KEEP (*(.vectors)) + /* boot data should be exactly 32 bytes long */ + *(.boot_data) + . = 0x20; + *(.boot) + . = ALIGN(64); + *(.freertos_vectors) + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + *(.plt) + *(.gnu_warning) + *(.gcc_except_table) + *(.glue_7) + *(.glue_7t) + *(.vfp11_veneer) + *(.ARM.extab) + *(.gnu.linkonce.armextab.*) +} > RAM + +.init : { + KEEP (*(.init)) +} > RAM + +.fini : { + KEEP (*(.fini)) +} > RAM + +.rodata : { + __rodata_start = .; + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + __rodata_end = .; +} > RAM + +.rodata1 : { + __rodata1_start = .; + *(.rodata1) + *(.rodata1.*) + __rodata1_end = .; +} > RAM + +.sdata2 : { + __sdata2_start = .; + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + __sdata2_end = .; +} > RAM + +.sbss2 : { + __sbss2_start = .; + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + __sbss2_end = .; +} > RAM + +.data : { + __data_start = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.jcr) + *(.got) + *(.got.plt) + __data_end = .; +} > RAM + +.data1 : { + __data1_start = .; + *(.data1) + *(.data1.*) + __data1_end = .; +} > RAM + +.got : { + *(.got) +} > RAM + +.ctors : { + __CTOR_LIST__ = .; + ___CTORS_LIST___ = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + ___CTORS_END___ = .; +} > RAM + +.dtors : { + __DTOR_LIST__ = .; + ___DTORS_LIST___ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + ___DTORS_END___ = .; +} > RAM + +.fixup : { + __fixup_start = .; + *(.fixup) + __fixup_end = .; +} > RAM + +.eh_frame : { + *(.eh_frame) +} > RAM + +.eh_framehdr : { + __eh_framehdr_start = .; + *(.eh_framehdr) + __eh_framehdr_end = .; +} > RAM + +.gcc_except_table : { + *(.gcc_except_table) +} > RAM + +.ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + *(.gnu.linkonce.armexidix.*.*) + __exidx_end = .; +} > RAM + +.preinit_array : { + __preinit_array_start = .; + KEEP (*(SORT(.preinit_array.*))) + KEEP (*(.preinit_array)) + __preinit_array_end = .; +} > RAM + +.init_array : { + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; +} > RAM + +.fini_array : { + __fini_array_start = .; + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array)) + __fini_array_end = .; +} > RAM + +/DISCARD/ : { + *(.ARM.attributes*) +} + +.sdata : { + __sdata_start = .; + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + __sdata_end = .; +} > RAM + +.sbss (NOLOAD) : { + __sbss_start = .; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + __sbss_end = .; +} > RAM + +.tdata : { + __tdata_start = .; + *(.tdata) + *(.tdata.*) + *(.gnu.linkonce.td.*) + __tdata_end = .; +} > RAM + +.tbss : { + __tbss_start = .; + *(.tbss) + *(.tbss.*) + *(.gnu.linkonce.tb.*) + __tbss_end = .; +} > RAM + +.bss (NOLOAD) : { + __bss_start = .; + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + __bss_end = .; +} > RAM + +_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 ); + +_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 ); + +/* Generate Stack and Heap definitions */ + +.heap (NOLOAD) : { + . = ALIGN(16); + _heap = .; + HeapBase = .; + _heap_start = .; + . += _HEAP_SIZE; + _heap_end = .; + HeapLimit = .; +} > HEAP +/* There are no sections for the stack. This is intentional, since VEXOs sets up a stack before + starting the program, and FreeRTOS task stacks are dynamically allocated. */ +_end = .; +} diff --git a/test/firmware/v5-hot.ld b/test/firmware/v5-hot.ld new file mode 100644 index 00000000..017cb356 --- /dev/null +++ b/test/firmware/v5-hot.ld @@ -0,0 +1,33 @@ +/* This stack is used during initialization, but FreeRTOS tasks have their own + stack allocated in BSS or Heap (kernel tasks in FreeRTOS .bss heap; user tasks + in standard heap) */ +_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x2000; + +_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024; +_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048; +_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024; +_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024; +_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024; + +_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x02E00000; /* ~48 MB */ + +/* Define Memories in the system */ +start_of_cold_mem = 0x03800000; +_COLD_MEM_SIZE = 0x04800000; +end_of_cold_mem = start_of_cold_mem + _COLD_MEM_SIZE; + +start_of_hot_mem = 0x07800000; +_HOT_MEM_SIZE = 0x00800000; +end_of_hot_mem = start_of_hot_mem + _HOT_MEM_SIZE; + +MEMORY +{ + /* user code 72M */ + COLD_MEMORY : ORIGIN = start_of_cold_mem, LENGTH = _COLD_MEM_SIZE /* Just under 19 MB */ + HEAP : ORIGIN = 0x04A00000, LENGTH = _HEAP_SIZE + HOT_MEMORY : ORIGIN = start_of_hot_mem, LENGTH = _HOT_MEM_SIZE /* Just over 8 MB */ +} + +REGION_ALIAS("RAM", HOT_MEMORY); + +ENTRY(install_hot_table) diff --git a/test/firmware/v5.ld b/test/firmware/v5.ld new file mode 100644 index 00000000..7cbd06f3 --- /dev/null +++ b/test/firmware/v5.ld @@ -0,0 +1,33 @@ +/* This stack is used during initialization, but FreeRTOS tasks have their own + stack allocated in BSS or Heap (kernel tasks in FreeRTOS .bss heap; user tasks + in standard heap) */ +_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x2000; + +_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024; +_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048; +_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024; +_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024; +_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024; + +_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x02E00000; /* ~48 MB */ + +/* Define Memories in the system */ +start_of_cold_mem = 0x03800000; +_COLD_MEM_SIZE = 0x04800000; +end_of_cold_mem = start_of_cold_mem + _COLD_MEM_SIZE; + +start_of_hot_mem = 0x07800000; +_HOT_MEM_SIZE = 0x00800000; +end_of_hot_mem = start_of_hot_mem + _HOT_MEM_SIZE; + +MEMORY +{ + /* user code 72M */ + COLD_MEMORY : ORIGIN = start_of_cold_mem, LENGTH = _COLD_MEM_SIZE /* Just under 19 MB */ + HEAP : ORIGIN = 0x04A00000, LENGTH = _HEAP_SIZE + HOT_MEMORY : ORIGIN = start_of_hot_mem, LENGTH = _HOT_MEM_SIZE /* Just over 8 MB */ +} + +REGION_ALIAS("RAM", COLD_MEMORY); + +ENTRY(vexStartup) diff --git a/test/include/api.h b/test/include/api.h new file mode 100644 index 00000000..71bf8d32 --- /dev/null +++ b/test/include/api.h @@ -0,0 +1,80 @@ +/** + * \file api.h + * + * PROS API header provides high-level user functionality + * + * Contains declarations for use by typical VEX programmers using PROS. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright Copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef _PROS_API_H_ +#define _PROS_API_H_ + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#include +#include +#else /* (not) __cplusplus */ +#include +#include +#include +#include +#include +#include +#include +#include +#endif /* __cplusplus */ + +#include "pros/adi.h" +#include "pros/ai_vision.h" +#include "pros/colors.h" +#include "pros/device.h" +#include "pros/distance.h" +#include "pros/error.h" +#include "pros/ext_adi.h" +#include "pros/gps.h" +#include "pros/imu.h" +#include "pros/link.h" +#include "pros/llemu.h" +#include "pros/misc.h" +#include "pros/motors.h" +#include "pros/optical.h" +#include "pros/rotation.h" +#include "pros/rtos.h" +#include "pros/screen.h" +#include "pros/vision.h" + +#ifdef __cplusplus +#include "pros/adi.hpp" +#include "pros/ai_vision.hpp" +#include "pros/colors.hpp" +#include "pros/device.hpp" +#include "pros/distance.hpp" +#include "pros/gps.hpp" +#include "pros/imu.hpp" +#include "pros/link.hpp" +#include "pros/llemu.hpp" +#include "pros/misc.hpp" +#include "pros/motor_group.hpp" +#include "pros/motors.hpp" +#include "pros/optical.hpp" +#include "pros/rotation.hpp" +#include "pros/rtos.hpp" +#include "pros/screen.hpp" +#include "pros/vision.hpp" +#endif + +#endif // _PROS_API_H_ diff --git a/test/include/liblvgl/core/lv_global.h b/test/include/liblvgl/core/lv_global.h new file mode 100644 index 00000000..5d37b394 --- /dev/null +++ b/test/include/liblvgl/core/lv_global.h @@ -0,0 +1,266 @@ +/** + * @file lv_global.h + * + */ + +#ifndef LV_GLOBAL_H +#define LV_GLOBAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include "../misc/lv_types.h" +#include "../draw/lv_draw.h" +#if LV_USE_DRAW_SW +#include "../draw/sw/lv_draw_sw.h" +#endif +#include "../misc/lv_anim.h" +#include "../misc/lv_area.h" +#include "../misc/lv_color_op.h" +#include "../misc/lv_ll.h" +#include "../misc/lv_log.h" +#include "../misc/lv_style.h" +#include "../misc/lv_timer.h" +#include "../osal/lv_os.h" +#include "../others/sysmon/lv_sysmon.h" +#include "../stdlib/builtin/lv_tlsf.h" + +#if LV_USE_FONT_COMPRESSED +#include "../font/lv_font_fmt_txt_private.h" +#endif + +#include "../tick/lv_tick.h" +#include "../layouts/lv_layout.h" + +#include "../misc/lv_types.h" + +#include "../misc/lv_timer_private.h" +#include "../misc/lv_anim_private.h" +#include "../tick/lv_tick_private.h" +#include "../draw/lv_draw_buf_private.h" +#include "../draw/lv_draw_private.h" +#include "../draw/sw/lv_draw_sw_private.h" +#include "../draw/sw/lv_draw_sw_mask_private.h" +#include "../stdlib/builtin/lv_tlsf_private.h" +#include "../others/sysmon/lv_sysmon_private.h" +#include "../layouts/lv_layout_private.h" + +/********************* + * DEFINES + *********************/ +#define ZERO_MEM_SENTINEL 0xa1b2c3d4 + +/********************** + * TYPEDEFS + **********************/ + +#if LV_USE_SPAN != 0 +struct _snippet_stack; +#endif + +#if LV_USE_FREETYPE +struct _lv_freetype_context_t; +#endif + +#if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN +struct _lv_profiler_builtin_ctx_t; +#endif + +#if LV_USE_NUTTX +struct _lv_nuttx_ctx_t; +#endif + +typedef struct _lv_global_t { + bool inited; + bool deinit_in_progress; /**< Can be used e.g. in the LV_EVENT_DELETE to deinit the drivers too */ + + lv_ll_t disp_ll; + lv_display_t * disp_refresh; + lv_display_t * disp_default; + + lv_ll_t style_trans_ll; + bool style_refresh; + uint32_t style_custom_table_size; + uint32_t style_last_custom_prop_id; + uint8_t * style_custom_prop_flag_lookup_table; + + lv_ll_t group_ll; + lv_group_t * group_default; + + lv_ll_t indev_ll; + lv_indev_t * indev_active; + lv_obj_t * indev_obj_active; + + uint32_t layout_count; + lv_layout_dsc_t * layout_list; + bool layout_update_mutex; + + uint32_t memory_zero; + uint32_t math_rand_seed; + + lv_event_t * event_header; + uint32_t event_last_register_id; + + lv_timer_state_t timer_state; + lv_anim_state_t anim_state; + lv_tick_state_t tick_state; + + lv_draw_buf_handlers_t draw_buf_handlers; + lv_draw_buf_handlers_t font_draw_buf_handlers; + lv_draw_buf_handlers_t image_cache_draw_buf_handlers; /**< Ensure that all assigned draw buffers + * can be managed by image cache. */ + + lv_ll_t img_decoder_ll; + + lv_cache_t * img_cache; + lv_cache_t * img_header_cache; + + lv_draw_global_info_t draw_info; +#if defined(LV_DRAW_SW_SHADOW_CACHE_SIZE) && LV_DRAW_SW_SHADOW_CACHE_SIZE > 0 + lv_draw_sw_shadow_cache_t sw_shadow_cache; +#endif +#if LV_DRAW_SW_COMPLEX + lv_draw_sw_mask_radius_circle_dsc_arr_t sw_circle_cache; +#endif + +#if LV_USE_LOG + lv_log_print_g_cb_t custom_log_print_cb; +#endif + +#if LV_USE_LOG && LV_LOG_USE_TIMESTAMP + uint32_t log_last_log_time; +#endif + +#if LV_USE_THEME_SIMPLE + void * theme_simple; +#endif + +#if LV_USE_THEME_DEFAULT + void * theme_default; +#endif + +#if LV_USE_THEME_MONO + void * theme_mono; +#endif + +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN + lv_tlsf_state_t tlsf_state; +#endif + + lv_ll_t fsdrv_ll; +#if LV_USE_FS_STDIO != '\0' + lv_fs_drv_t stdio_fs_drv; +#endif +#if LV_USE_FS_POSIX + lv_fs_drv_t posix_fs_drv; +#endif + +#if LV_USE_FS_FATFS + lv_fs_drv_t fatfs_fs_drv; +#endif + +#if LV_USE_FS_WIN32 != '\0' + lv_fs_drv_t win32_fs_drv; +#endif + +#if LV_USE_FS_LITTLEFS + lv_fs_drv_t littlefs_fs_drv; +#endif + +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + lv_fs_drv_t arduino_esp_littlefs_fs_drv; +#endif + +#if LV_USE_FS_ARDUINO_SD + lv_fs_drv_t arduino_sd_fs_drv; +#endif + +#if LV_USE_FREETYPE + struct _lv_freetype_context_t * ft_context; +#endif + +#if LV_USE_FONT_COMPRESSED + lv_font_fmt_rle_t font_fmt_rle; +#endif + +#if LV_USE_SPAN != 0 + struct _snippet_stack * span_snippet_stack; +#endif + +#if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN + struct _lv_profiler_builtin_ctx_t * profiler_context; +#endif + +#if LV_USE_FILE_EXPLORER != 0 + lv_style_t fe_list_button_style; +#endif + +#if LV_USE_MEM_MONITOR + lv_sysmon_backend_data_t sysmon_mem; +#endif + +#if LV_USE_IME_PINYIN != 0 + size_t ime_cand_len; +#endif + +#if LV_USE_OBJ_ID_BUILTIN + void * objid_array; + uint32_t objid_count; +#endif + +#if LV_USE_NUTTX + struct _lv_nuttx_ctx_t * nuttx_ctx; +#endif + +#if LV_USE_OS != LV_OS_NONE + lv_mutex_t lv_general_mutex; +#endif + +#if LV_USE_OS == LV_OS_FREERTOS + uint32_t freertos_idle_time_sum; + uint32_t freertos_non_idle_time_sum; + uint32_t freertos_task_switch_timestamp; + bool freertos_idle_task_running; +#endif + + + void * user_data; +} lv_global_t; + +/********************** + * MACROS + **********************/ + +#if LV_ENABLE_GLOBAL_CUSTOM +#include LV_GLOBAL_CUSTOM_INCLUDE + +#ifndef LV_GLOBAL_CUSTOM +#define LV_GLOBAL_CUSTOM() lv_global_default() +#endif +#define LV_GLOBAL_DEFAULT() LV_GLOBAL_CUSTOM() +#else +LV_ATTRIBUTE_EXTERN_DATA extern lv_global_t lv_global; +#define LV_GLOBAL_DEFAULT() (&lv_global) +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ +#if LV_ENABLE_GLOBAL_CUSTOM +/** + * Get the default global object for current thread + * @return pointer to the default global object + */ +lv_global_t * lv_global_default(void); +#endif +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GLOBAL_H*/ diff --git a/test/include/liblvgl/core/lv_group.h b/test/include/liblvgl/core/lv_group.h new file mode 100644 index 00000000..e5f267d0 --- /dev/null +++ b/test/include/liblvgl/core/lv_group.h @@ -0,0 +1,245 @@ +/** + * @file lv_group.h + * + */ + +#ifndef LV_GROUP_H +#define LV_GROUP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include "../misc/lv_types.h" +#include "../misc/lv_ll.h" + +/********************* + * DEFINES + *********************/ +/** Predefined keys to control focused object via lv_group_send(group, c) */ +typedef enum { + LV_KEY_UP = 17, /*0x11*/ + LV_KEY_DOWN = 18, /*0x12*/ + LV_KEY_RIGHT = 19, /*0x13*/ + LV_KEY_LEFT = 20, /*0x14*/ + LV_KEY_ESC = 27, /*0x1B*/ + LV_KEY_DEL = 127, /*0x7F*/ + LV_KEY_BACKSPACE = 8, /*0x08*/ + LV_KEY_ENTER = 10, /*0x0A, '\n'*/ + LV_KEY_NEXT = 9, /*0x09, '\t'*/ + LV_KEY_PREV = 11, /*0x0B, '*/ + LV_KEY_HOME = 2, /*0x02, STX*/ + LV_KEY_END = 3, /*0x03, ETX*/ +} lv_key_t; + +/********************** + * TYPEDEFS + **********************/ + +typedef void (*lv_group_focus_cb_t)(lv_group_t *); +typedef void (*lv_group_edge_cb_t)(lv_group_t *, bool); + +typedef enum { + LV_GROUP_REFOCUS_POLICY_NEXT = 0, + LV_GROUP_REFOCUS_POLICY_PREV = 1 +} lv_group_refocus_policy_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a new object group + * @return pointer to the new object group + */ +lv_group_t * lv_group_create(void); + +/** + * Delete a group object + * @param group pointer to a group + */ +void lv_group_delete(lv_group_t * group); + +/** + * Set a default group. New object are added to this group if it's enabled in their class with `add_to_def_group = true` + * @param group pointer to a group (can be `NULL`) + */ +void lv_group_set_default(lv_group_t * group); + +/** + * Get the default group + * @return pointer to the default group + */ +lv_group_t * lv_group_get_default(void); + +/** + * Add an object to a group + * @param group pointer to a group + * @param obj pointer to an object to add + */ +void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj); + +/** + * Swap 2 object in a group. The object must be in the same group + * @param obj1 pointer to an object + * @param obj2 pointer to another object + */ +void lv_group_swap_obj(lv_obj_t * obj1, lv_obj_t * obj2); + +/** + * Remove an object from its group + * @param obj pointer to an object to remove + */ +void lv_group_remove_obj(lv_obj_t * obj); + +/** + * Remove all objects from a group + * @param group pointer to a group + */ +void lv_group_remove_all_objs(lv_group_t * group); + +/** + * Focus on an object (defocus the current) + * @param obj pointer to an object to focus on + */ +void lv_group_focus_obj(lv_obj_t * obj); + +/** + * Focus the next object in a group (defocus the current) + * @param group pointer to a group + */ +void lv_group_focus_next(lv_group_t * group); + +/** + * Focus the previous object in a group (defocus the current) + * @param group pointer to a group + */ +void lv_group_focus_prev(lv_group_t * group); + +/** + * Do not let to change the focus from the current object + * @param group pointer to a group + * @param en true: freeze, false: release freezing (normal mode) + */ +void lv_group_focus_freeze(lv_group_t * group, bool en); + +/** + * Send a control character to the focuses object of a group + * @param group pointer to a group + * @param c a character (use LV_KEY_.. to navigate) + * @return result of focused object in group. + */ +lv_result_t lv_group_send_data(lv_group_t * group, uint32_t c); + +/** + * Set a function for a group which will be called when a new object is focused + * @param group pointer to a group + * @param focus_cb the call back function or NULL if unused + */ +void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb); + +/** + * Set a function for a group which will be called when a focus edge is reached + * @param group pointer to a group + * @param edge_cb the call back function or NULL if unused + */ +void lv_group_set_edge_cb(lv_group_t * group, lv_group_edge_cb_t edge_cb); + +/** + * Set whether the next or previous item in a group is focused if the currently focused obj is + * deleted. + * @param group pointer to a group + * @param policy new refocus policy enum + */ +void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy); + +/** + * Manually set the current mode (edit or navigate). + * @param group pointer to group + * @param edit true: edit mode; false: navigate mode + */ +void lv_group_set_editing(lv_group_t * group, bool edit); + +/** + * Set whether focus next/prev will allow wrapping from first->last or last->first object. + * @param group pointer to group + * @param en true: wrapping enabled; false: wrapping disabled + */ +void lv_group_set_wrap(lv_group_t * group, bool en); + +/** + * Get the focused object or NULL if there isn't one + * @param group pointer to a group + * @return pointer to the focused object + */ +lv_obj_t * lv_group_get_focused(const lv_group_t * group); + +/** + * Get the focus callback function of a group + * @param group pointer to a group + * @return the call back function or NULL if not set + */ +lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group); + +/** + * Get the edge callback function of a group + * @param group pointer to a group + * @return the call back function or NULL if not set + */ +lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t * group); + +/** + * Get the current mode (edit or navigate). + * @param group pointer to group + * @return true: edit mode; false: navigate mode + */ +bool lv_group_get_editing(const lv_group_t * group); + +/** + * Get whether focus next/prev will allow wrapping from first->last or last->first object. + * @param group pointer to group + */ +bool lv_group_get_wrap(lv_group_t * group); + +/** + * Get the number of object in the group + * @param group pointer to a group + * @return number of objects in the group + */ +uint32_t lv_group_get_obj_count(lv_group_t * group); + +/** + * Get the nth object within a group + * @param group pointer to a group + * @param index index of object within the group + * @return pointer to the object + */ +lv_obj_t * lv_group_get_obj_by_index(lv_group_t * group, uint32_t index); + +/** + * Get the number of groups + * @return number of groups + */ +uint32_t lv_group_get_count(void); + +/** + * Get a group by its index + * @param index index of the group + * @return pointer to the group + */ +lv_group_t * lv_group_by_index(uint32_t index); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GROUP_H*/ diff --git a/test/include/liblvgl/core/lv_group_private.h b/test/include/liblvgl/core/lv_group_private.h new file mode 100644 index 00000000..fe5f22b0 --- /dev/null +++ b/test/include/liblvgl/core/lv_group_private.h @@ -0,0 +1,75 @@ +/** + * @file lv_group_private.h + * + */ + +#ifndef LV_GROUP_PRIVATE_H +#define LV_GROUP_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_group.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Groups can be used to logically hold objects so that they can be individually focused. + * They are NOT for laying out objects on a screen (try layouts for that). + */ +struct _lv_group_t { + lv_ll_t obj_ll; /**< Linked list to store the objects in the group*/ + lv_obj_t ** obj_focus; /**< The object in focus*/ + + lv_group_focus_cb_t focus_cb; /**< A function to call when a new object is focused (optional)*/ + lv_group_edge_cb_t edge_cb; /**< A function to call when an edge is reached, no more focus + targets are available in this direction (to allow edge feedback + like a sound or a scroll bounce) */ + + void * user_data; + + uint8_t frozen : 1; /**< 1: can't focus to new object*/ + uint8_t editing : 1; /**< 1: Edit mode, 0: Navigate mode*/ + uint8_t refocus_policy : 1; /**< 1: Focus prev if focused on deletion. 0: Focus next if focused on + deletion.*/ + uint8_t wrap : 1; /**< 1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end + of list.*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Init the group module + * @remarks Internal function, do not call directly. + */ +void lv_group_init(void); + +/** + * Deinit the group module + * @remarks Internal function, do not call directly. + */ +void lv_group_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GROUP_PRIVATE_H*/ diff --git a/test/include/liblvgl/core/lv_obj.h b/test/include/liblvgl/core/lv_obj.h new file mode 100644 index 00000000..4ae648ff --- /dev/null +++ b/test/include/liblvgl/core/lv_obj.h @@ -0,0 +1,486 @@ +/** + * @file lv_obj.h + * + */ + +#ifndef LV_OBJ_H +#define LV_OBJ_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include "../misc/lv_types.h" +#include "../misc/lv_style.h" +#include "../misc/lv_area.h" +#include "../misc/lv_color.h" +#include "../misc/lv_assert.h" + +#include "lv_obj_tree.h" +#include "lv_obj_pos.h" +#include "lv_obj_scroll.h" +#include "lv_obj_style.h" +#include "lv_obj_draw.h" +#include "lv_obj_class.h" +#include "lv_obj_event.h" +#include "lv_obj_property.h" +#include "lv_group.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Possible states of a widget. + * OR-ed values are possible + */ +enum { + LV_STATE_DEFAULT = 0x0000, + LV_STATE_CHECKED = 0x0001, + LV_STATE_FOCUSED = 0x0002, + LV_STATE_FOCUS_KEY = 0x0004, + LV_STATE_EDITED = 0x0008, + LV_STATE_HOVERED = 0x0010, + LV_STATE_PRESSED = 0x0020, + LV_STATE_SCROLLED = 0x0040, + LV_STATE_DISABLED = 0x0080, + LV_STATE_USER_1 = 0x1000, + LV_STATE_USER_2 = 0x2000, + LV_STATE_USER_3 = 0x4000, + LV_STATE_USER_4 = 0x8000, + + LV_STATE_ANY = 0xFFFF, /**< Special value can be used in some functions to target all states*/ +}; + +/** + * The possible parts of widgets. + * The parts can be considered as the internal building block of the widgets. + * E.g. slider = background + indicator + knob + * Not all parts are used by every widget + */ + +enum { + LV_PART_MAIN = 0x000000, /**< A background like rectangle*/ + LV_PART_SCROLLBAR = 0x010000, /**< The scrollbar(s)*/ + LV_PART_INDICATOR = 0x020000, /**< Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox*/ + LV_PART_KNOB = 0x030000, /**< Like handle to grab to adjust the value*/ + LV_PART_SELECTED = 0x040000, /**< Indicate the currently selected option or section*/ + LV_PART_ITEMS = 0x050000, /**< Used if the widget has multiple similar elements (e.g. table cells)*/ + LV_PART_CURSOR = 0x060000, /**< Mark a specific place e.g. for text area's cursor or on a chart*/ + + LV_PART_CUSTOM_FIRST = 0x080000, /**< Extension point for custom widgets*/ + + LV_PART_ANY = 0x0F0000, /**< Special value can be used in some functions to target all parts*/ +}; + +/** + * On/Off features controlling the object's behavior. + * OR-ed values are possible + * + * Note: update obj flags corresponding properties below + * whenever add/remove flags or change bit definition of flags. + */ +typedef enum { + LV_OBJ_FLAG_HIDDEN = (1L << 0), /**< Make the object hidden. (Like it wasn't there at all)*/ + LV_OBJ_FLAG_CLICKABLE = (1L << 1), /**< Make the object clickable by the input devices*/ + LV_OBJ_FLAG_CLICK_FOCUSABLE = (1L << 2), /**< Add focused state to the object when clicked*/ + LV_OBJ_FLAG_CHECKABLE = (1L << 3), /**< Toggle checked state when the object is clicked*/ + LV_OBJ_FLAG_SCROLLABLE = (1L << 4), /**< Make the object scrollable*/ + LV_OBJ_FLAG_SCROLL_ELASTIC = (1L << 5), /**< Allow scrolling inside but with slower speed*/ + LV_OBJ_FLAG_SCROLL_MOMENTUM = (1L << 6), /**< Make the object scroll further when "thrown"*/ + LV_OBJ_FLAG_SCROLL_ONE = (1L << 7), /**< Allow scrolling only one snappable children*/ + LV_OBJ_FLAG_SCROLL_CHAIN_HOR = (1L << 8), /**< Allow propagating the horizontal scroll to a parent*/ + LV_OBJ_FLAG_SCROLL_CHAIN_VER = (1L << 9), /**< Allow propagating the vertical scroll to a parent*/ + LV_OBJ_FLAG_SCROLL_CHAIN = (LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER), + LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1L << 10), /**< Automatically scroll object to make it visible when focused*/ + LV_OBJ_FLAG_SCROLL_WITH_ARROW = (1L << 11), /**< Allow scrolling the focused object with arrow keys*/ + LV_OBJ_FLAG_SNAPPABLE = (1L << 12), /**< If scroll snap is enabled on the parent it can snap to this object*/ + LV_OBJ_FLAG_PRESS_LOCK = (1L << 13), /**< Keep the object pressed even if the press slid from the object*/ + LV_OBJ_FLAG_EVENT_BUBBLE = (1L << 14), /**< Propagate the events to the parent too*/ + LV_OBJ_FLAG_GESTURE_BUBBLE = (1L << 15), /**< Propagate the gestures to the parent*/ + LV_OBJ_FLAG_ADV_HITTEST = (1L << 16), /**< Allow performing more accurate hit (click) test. E.g. consider rounded corners.*/ + LV_OBJ_FLAG_IGNORE_LAYOUT = (1L << 17), /**< Make the object not positioned by the layouts*/ + LV_OBJ_FLAG_FLOATING = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout*/ + LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS = (1L << 19), /**< Send `LV_EVENT_DRAW_TASK_ADDED` events*/ + LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 20),/**< Do not clip the children to the parent's ext draw size*/ +#if LV_USE_FLEX + LV_OBJ_FLAG_FLEX_IN_NEW_TRACK = (1L << 21), /**< Start a new flex track on this item*/ +#endif + + LV_OBJ_FLAG_LAYOUT_1 = (1L << 23), /**< Custom flag, free to use by layouts*/ + LV_OBJ_FLAG_LAYOUT_2 = (1L << 24), /**< Custom flag, free to use by layouts*/ + + LV_OBJ_FLAG_WIDGET_1 = (1L << 25), /**< Custom flag, free to use by widget*/ + LV_OBJ_FLAG_WIDGET_2 = (1L << 26), /**< Custom flag, free to use by widget*/ + LV_OBJ_FLAG_USER_1 = (1L << 27), /**< Custom flag, free to use by user*/ + LV_OBJ_FLAG_USER_2 = (1L << 28), /**< Custom flag, free to use by user*/ + LV_OBJ_FLAG_USER_3 = (1L << 29), /**< Custom flag, free to use by user*/ + LV_OBJ_FLAG_USER_4 = (1L << 30), /**< Custom flag, free to use by user*/ +} lv_obj_flag_t; + +#if LV_USE_OBJ_PROPERTY +enum { + /*OBJ flag properties */ + LV_PROPERTY_ID(OBJ, FLAG_START, LV_PROPERTY_TYPE_INT, 0), + LV_PROPERTY_ID(OBJ, FLAG_HIDDEN, LV_PROPERTY_TYPE_INT, 0), + LV_PROPERTY_ID(OBJ, FLAG_CLICKABLE, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(OBJ, FLAG_CLICK_FOCUSABLE, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(OBJ, FLAG_CHECKABLE, LV_PROPERTY_TYPE_INT, 3), + LV_PROPERTY_ID(OBJ, FLAG_SCROLLABLE, LV_PROPERTY_TYPE_INT, 4), + LV_PROPERTY_ID(OBJ, FLAG_SCROLL_ELASTIC, LV_PROPERTY_TYPE_INT, 5), + LV_PROPERTY_ID(OBJ, FLAG_SCROLL_MOMENTUM, LV_PROPERTY_TYPE_INT, 6), + LV_PROPERTY_ID(OBJ, FLAG_SCROLL_ONE, LV_PROPERTY_TYPE_INT, 7), + LV_PROPERTY_ID(OBJ, FLAG_SCROLL_CHAIN_HOR, LV_PROPERTY_TYPE_INT, 8), + LV_PROPERTY_ID(OBJ, FLAG_SCROLL_CHAIN_VER, LV_PROPERTY_TYPE_INT, 9), + LV_PROPERTY_ID(OBJ, FLAG_SCROLL_ON_FOCUS, LV_PROPERTY_TYPE_INT, 10), + LV_PROPERTY_ID(OBJ, FLAG_SCROLL_WITH_ARROW, LV_PROPERTY_TYPE_INT, 11), + LV_PROPERTY_ID(OBJ, FLAG_SNAPPABLE, LV_PROPERTY_TYPE_INT, 12), + LV_PROPERTY_ID(OBJ, FLAG_PRESS_LOCK, LV_PROPERTY_TYPE_INT, 13), + LV_PROPERTY_ID(OBJ, FLAG_EVENT_BUBBLE, LV_PROPERTY_TYPE_INT, 14), + LV_PROPERTY_ID(OBJ, FLAG_GESTURE_BUBBLE, LV_PROPERTY_TYPE_INT, 15), + LV_PROPERTY_ID(OBJ, FLAG_ADV_HITTEST, LV_PROPERTY_TYPE_INT, 16), + LV_PROPERTY_ID(OBJ, FLAG_IGNORE_LAYOUT, LV_PROPERTY_TYPE_INT, 17), + LV_PROPERTY_ID(OBJ, FLAG_FLOATING, LV_PROPERTY_TYPE_INT, 18), + LV_PROPERTY_ID(OBJ, FLAG_SEND_DRAW_TASK_EVENTS, LV_PROPERTY_TYPE_INT, 19), + LV_PROPERTY_ID(OBJ, FLAG_OVERFLOW_VISIBLE, LV_PROPERTY_TYPE_INT, 20), + LV_PROPERTY_ID(OBJ, FLAG_FLEX_IN_NEW_TRACK, LV_PROPERTY_TYPE_INT, 21), + LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_1, LV_PROPERTY_TYPE_INT, 23), + LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_2, LV_PROPERTY_TYPE_INT, 24), + LV_PROPERTY_ID(OBJ, FLAG_WIDGET_1, LV_PROPERTY_TYPE_INT, 25), + LV_PROPERTY_ID(OBJ, FLAG_WIDGET_2, LV_PROPERTY_TYPE_INT, 26), + LV_PROPERTY_ID(OBJ, FLAG_USER_1, LV_PROPERTY_TYPE_INT, 27), + LV_PROPERTY_ID(OBJ, FLAG_USER_2, LV_PROPERTY_TYPE_INT, 28), + LV_PROPERTY_ID(OBJ, FLAG_USER_3, LV_PROPERTY_TYPE_INT, 29), + LV_PROPERTY_ID(OBJ, FLAG_USER_4, LV_PROPERTY_TYPE_INT, 30), + LV_PROPERTY_ID(OBJ, FLAG_END, LV_PROPERTY_TYPE_INT, 30), + + LV_PROPERTY_ID(OBJ, STATE_START, LV_PROPERTY_TYPE_INT, 31), + LV_PROPERTY_ID(OBJ, STATE_CHECKED, LV_PROPERTY_TYPE_INT, 31), + LV_PROPERTY_ID(OBJ, STATE_FOCUSED, LV_PROPERTY_TYPE_INT, 32), + LV_PROPERTY_ID(OBJ, STATE_FOCUS_KEY, LV_PROPERTY_TYPE_INT, 33), + LV_PROPERTY_ID(OBJ, STATE_EDITED, LV_PROPERTY_TYPE_INT, 34), + LV_PROPERTY_ID(OBJ, STATE_HOVERED, LV_PROPERTY_TYPE_INT, 35), + LV_PROPERTY_ID(OBJ, STATE_PRESSED, LV_PROPERTY_TYPE_INT, 36), + LV_PROPERTY_ID(OBJ, STATE_SCROLLED, LV_PROPERTY_TYPE_INT, 37), + LV_PROPERTY_ID(OBJ, STATE_DISABLED, LV_PROPERTY_TYPE_INT, 38), + /*not used bit8-bit11*/ + LV_PROPERTY_ID(OBJ, STATE_USER_1, LV_PROPERTY_TYPE_INT, 43), + LV_PROPERTY_ID(OBJ, STATE_USER_2, LV_PROPERTY_TYPE_INT, 44), + LV_PROPERTY_ID(OBJ, STATE_USER_3, LV_PROPERTY_TYPE_INT, 45), + LV_PROPERTY_ID(OBJ, STATE_USER_4, LV_PROPERTY_TYPE_INT, 46), + LV_PROPERTY_ID(OBJ, STATE_ANY, LV_PROPERTY_TYPE_INT, 47), + LV_PROPERTY_ID(OBJ, STATE_END, LV_PROPERTY_TYPE_INT, 47), + + /*OBJ normal properties*/ + LV_PROPERTY_ID(OBJ, PARENT, LV_PROPERTY_TYPE_OBJ, 48), + LV_PROPERTY_ID(OBJ, X, LV_PROPERTY_TYPE_INT, 49), + LV_PROPERTY_ID(OBJ, Y, LV_PROPERTY_TYPE_INT, 50), + LV_PROPERTY_ID(OBJ, W, LV_PROPERTY_TYPE_INT, 51), + LV_PROPERTY_ID(OBJ, H, LV_PROPERTY_TYPE_INT, 52), + LV_PROPERTY_ID(OBJ, CONTENT_WIDTH, LV_PROPERTY_TYPE_INT, 53), + LV_PROPERTY_ID(OBJ, CONTENT_HEIGHT, LV_PROPERTY_TYPE_INT, 54), + LV_PROPERTY_ID(OBJ, LAYOUT, LV_PROPERTY_TYPE_INT, 55), + LV_PROPERTY_ID(OBJ, ALIGN, LV_PROPERTY_TYPE_INT, 56), + LV_PROPERTY_ID(OBJ, SCROLLBAR_MODE, LV_PROPERTY_TYPE_INT, 57), + LV_PROPERTY_ID(OBJ, SCROLL_DIR, LV_PROPERTY_TYPE_INT, 58), + LV_PROPERTY_ID(OBJ, SCROLL_SNAP_X, LV_PROPERTY_TYPE_INT, 59), + LV_PROPERTY_ID(OBJ, SCROLL_SNAP_Y, LV_PROPERTY_TYPE_INT, 60), + LV_PROPERTY_ID(OBJ, SCROLL_X, LV_PROPERTY_TYPE_INT, 61), + LV_PROPERTY_ID(OBJ, SCROLL_Y, LV_PROPERTY_TYPE_INT, 62), + LV_PROPERTY_ID(OBJ, SCROLL_TOP, LV_PROPERTY_TYPE_INT, 63), + LV_PROPERTY_ID(OBJ, SCROLL_BOTTOM, LV_PROPERTY_TYPE_INT, 64), + LV_PROPERTY_ID(OBJ, SCROLL_LEFT, LV_PROPERTY_TYPE_INT, 65), + LV_PROPERTY_ID(OBJ, SCROLL_RIGHT, LV_PROPERTY_TYPE_INT, 66), + LV_PROPERTY_ID(OBJ, SCROLL_END, LV_PROPERTY_TYPE_INT, 67), + LV_PROPERTY_ID(OBJ, EXT_DRAW_SIZE, LV_PROPERTY_TYPE_INT, 68), + LV_PROPERTY_ID(OBJ, EVENT_COUNT, LV_PROPERTY_TYPE_INT, 69), + LV_PROPERTY_ID(OBJ, SCREEN, LV_PROPERTY_TYPE_OBJ, 70), + LV_PROPERTY_ID(OBJ, DISPLAY, LV_PROPERTY_TYPE_POINTER, 71), + LV_PROPERTY_ID(OBJ, CHILD_COUNT, LV_PROPERTY_TYPE_INT, 72), + LV_PROPERTY_ID(OBJ, INDEX, LV_PROPERTY_TYPE_INT, 73), + + LV_PROPERTY_OBJ_END, +}; +#endif + +/** + * Make the base object's class publicly available. + */ +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_obj_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a base object (a rectangle) + * @param parent pointer to a parent object. If NULL then a screen will be created. + * @return pointer to the new object + */ +lv_obj_t * lv_obj_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set one or more flags + * @param obj pointer to an object + * @param f OR-ed values from `lv_obj_flag_t` to set. + */ +void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f); + +/** + * Remove one or more flags + * @param obj pointer to an object + * @param f OR-ed values from `lv_obj_flag_t` to clear. + */ +void lv_obj_remove_flag(lv_obj_t * obj, lv_obj_flag_t f); + +/** + * Set add or remove one or more flags. + * @param obj pointer to an object + * @param f OR-ed values from `lv_obj_flag_t` to update. + * @param v true: add the flags; false: remove the flags + */ +void lv_obj_update_flag(lv_obj_t * obj, lv_obj_flag_t f, bool v); + +/** + * Add one or more states to the object. The other state bits will remain unchanged. + * If specified in the styles, transition animation will be started from the previous state to the current. + * @param obj pointer to an object + * @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED` + */ +void lv_obj_add_state(lv_obj_t * obj, lv_state_t state); + +/** + * Remove one or more states to the object. The other state bits will remain unchanged. + * If specified in the styles, transition animation will be started from the previous state to the current. + * @param obj pointer to an object + * @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED` + */ +void lv_obj_remove_state(lv_obj_t * obj, lv_state_t state); + +/** + * Add or remove one or more states to the object. The other state bits will remain unchanged. + * @param obj pointer to an object + * @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED` + * @param v true: add the states; false: remove the states + */ +void lv_obj_set_state(lv_obj_t * obj, lv_state_t state, bool v); + +/** + * Set the user_data field of the object + * @param obj pointer to an object + * @param user_data pointer to the new user_data. + */ +void lv_obj_set_user_data(lv_obj_t * obj, void * user_data); + +/*======================= + * Getter functions + *======================*/ + +/** + * Check if a given flag or all the given flags are set on an object. + * @param obj pointer to an object + * @param f the flag(s) to check (OR-ed values can be used) + * @return true: all flags are set; false: not all flags are set + */ +bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f); + +/** + * Check if a given flag or any of the flags are set on an object. + * @param obj pointer to an object + * @param f the flag(s) to check (OR-ed values can be used) + * @return true: at least one flag is set; false: none of the flags are set + */ +bool lv_obj_has_flag_any(const lv_obj_t * obj, lv_obj_flag_t f); + +/** + * Get the state of an object + * @param obj pointer to an object + * @return the state (OR-ed values from `lv_state_t`) + */ +lv_state_t lv_obj_get_state(const lv_obj_t * obj); + +/** + * Check if the object is in a given state or not. + * @param obj pointer to an object + * @param state a state or combination of states to check + * @return true: `obj` is in `state`; false: `obj` is not in `state` + */ +bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state); + +/** + * Get the group of the object + * @param obj pointer to an object + * @return the pointer to group of the object + */ +lv_group_t * lv_obj_get_group(const lv_obj_t * obj); + +/** + * Get the user_data field of the object + * @param obj pointer to an object + * @return the pointer to the user_data of the object + */ +void * lv_obj_get_user_data(lv_obj_t * obj); + +/*======================= + * Other functions + *======================*/ + +/** + * Allocate special data for an object if not allocated yet. + * @param obj pointer to an object + */ +void lv_obj_allocate_spec_attr(lv_obj_t * obj); + +/** + * Check the type of obj. + * @param obj pointer to an object + * @param class_p a class to check (e.g. `lv_slider_class`) + * @return true: `class_p` is the `obj` class. + */ +bool lv_obj_check_type(const lv_obj_t * obj, const lv_obj_class_t * class_p); + +/** + * Check if any object has a given class (type). + * It checks the ancestor classes too. + * @param obj pointer to an object + * @param class_p a class to check (e.g. `lv_slider_class`) + * @return true: `obj` has the given class + */ +bool lv_obj_has_class(const lv_obj_t * obj, const lv_obj_class_t * class_p); + +/** + * Get the class (type) of the object + * @param obj pointer to an object + * @return the class (type) of the object + */ +const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj); + +/** + * Check if any object is still "alive". + * @param obj pointer to an object + * @return true: valid + */ +bool lv_obj_is_valid(const lv_obj_t * obj); + +/** + * Utility to set an object reference to NULL when it gets deleted. + * The reference should be in a location that will not become invalid + * during the object's lifetime, i.e. static or allocated. + * @param obj_ptr a pointer to a pointer to an object + */ +void lv_obj_null_on_delete(lv_obj_t ** obj_ptr); + +#if LV_USE_OBJ_ID +/** + * Set an id for an object. + * @param obj pointer to an object + * @param id the id of the object + */ +void lv_obj_set_id(lv_obj_t * obj, void * id); + +/** + * Get the id of an object. + * @param obj pointer to an object + * @return the id of the object + */ +void * lv_obj_get_id(const lv_obj_t * obj); + +/** + * Get the child object by its id. + * It will check children and grandchildren recursively. + * Function `lv_obj_id_compare` is used to matched obj id with given id. + * + * @param obj pointer to an object + * @param id the id of the child object + * @return pointer to the child object or NULL if not found + */ +lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id); + +/** + * Assign id to object if not previously assigned. + * This function gets called automatically when LV_OBJ_ID_AUTO_ASSIGN is enabled. + * + * Set `LV_USE_OBJ_ID_BUILTIN` to use the builtin method to generate object ID. + * Otherwise, these functions including `lv_obj_[set|assign|free|stringify]_id` and + * `lv_obj_id_compare`should be implemented externally. + * + * @param class_p the class this obj belongs to. Note obj->class_p is the class currently being constructed. + * @param obj pointer to an object + */ +void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj); + +/** + * Free resources allocated by `lv_obj_assign_id` or `lv_obj_set_id`. + * This function is also called automatically when object is deleted. + * @param obj pointer to an object + */ +void lv_obj_free_id(lv_obj_t * obj); + +/** + * Compare two obj id, return 0 if they are equal. + * + * Set `LV_USE_OBJ_ID_BUILTIN` to use the builtin method for compare. + * Otherwise, it must be implemented externally. + * + * @param id1: the first id + * @param id2: the second id + * @return 0 if they are equal, non-zero otherwise. + */ +int lv_obj_id_compare(const void * id1, const void * id2); + +/** + * Format an object's id into a string. + * @param obj pointer to an object + * @param buf buffer to write the string into + * @param len length of the buffer + */ +const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len); + +#if LV_USE_OBJ_ID_BUILTIN +/** + * Free resources used by builtin ID generator. + */ +void lv_objid_builtin_destroy(void); +#endif + +#endif /*LV_USE_OBJ_ID*/ + +/********************** + * MACROS + **********************/ + +#if LV_USE_ASSERT_OBJ +# define LV_ASSERT_OBJ(obj_p, obj_class) \ + do { \ + LV_ASSERT_MSG(obj_p != NULL, "The object is NULL"); \ + LV_ASSERT_MSG(lv_obj_has_class(obj_p, obj_class) == true, "Incompatible object type."); \ + LV_ASSERT_MSG(lv_obj_is_valid(obj_p) == true, "The object is invalid, deleted or corrupted?"); \ + } while(0) +# else +# define LV_ASSERT_OBJ(obj_p, obj_class) do{}while(0) +#endif + +#if LV_USE_LOG && LV_LOG_TRACE_OBJ_CREATE +# define LV_TRACE_OBJ_CREATE(...) LV_LOG_TRACE(__VA_ARGS__) +#else +# define LV_TRACE_OBJ_CREATE(...) +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_H*/ diff --git a/test/include/liblvgl/core/lv_obj_class.h b/test/include/liblvgl/core/lv_obj_class.h new file mode 100644 index 00000000..4c3bdcb2 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_class.h @@ -0,0 +1,72 @@ +/** + * @file lv_obj_class.h + * + */ + +#ifndef LV_OBJ_CLASS_H +#define LV_OBJ_CLASS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_types.h" +#include "../misc/lv_area.h" +#include "lv_obj_property.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_OBJ_CLASS_EDITABLE_INHERIT, /**< Check the base class. Must have 0 value to let zero initialized class inherit*/ + LV_OBJ_CLASS_EDITABLE_TRUE, + LV_OBJ_CLASS_EDITABLE_FALSE, +} lv_obj_class_editable_t; + +typedef enum { + LV_OBJ_CLASS_GROUP_DEF_INHERIT, /**< Check the base class. Must have 0 value to let zero initialized class inherit*/ + LV_OBJ_CLASS_GROUP_DEF_TRUE, + LV_OBJ_CLASS_GROUP_DEF_FALSE, +} lv_obj_class_group_def_t; + +typedef enum { + LV_OBJ_CLASS_THEME_INHERITABLE_FALSE, /**< Do not inherit theme from base class. */ + LV_OBJ_CLASS_THEME_INHERITABLE_TRUE, +} lv_obj_class_theme_inheritable_t; + +typedef void (*lv_obj_class_event_cb_t)(lv_obj_class_t * class_p, lv_event_t * e); +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an object form a class descriptor + * @param class_p pointer to a class + * @param parent pointer to an object where the new object should be created + * @return pointer to the created object + */ +lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * parent); + +void lv_obj_class_init_obj(lv_obj_t * obj); + +bool lv_obj_is_editable(lv_obj_t * obj); + +bool lv_obj_is_group_def(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_CLASS_H*/ diff --git a/test/include/liblvgl/core/lv_obj_class_private.h b/test/include/liblvgl/core/lv_obj_class_private.h new file mode 100644 index 00000000..de2b1738 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_class_private.h @@ -0,0 +1,78 @@ +/** + * @file lv_obj_class_private.h + * + */ + +#ifndef LV_OBJ_CLASS_PRIVATE_H +#define LV_OBJ_CLASS_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_class.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Describe the common methods of every object. + * Similar to a C++ class. + */ +struct _lv_obj_class_t { + const lv_obj_class_t * base_class; + /** class_p is the final class while obj->class_p is the class currently being [de]constructed. */ + void (*constructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj); + void (*destructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj); + + /** class_p is the class in which event is being processed. */ + void (*event_cb)(const lv_obj_class_t * class_p, lv_event_t * e); /**< Widget type specific event function*/ + +#if LV_USE_OBJ_PROPERTY + uint32_t prop_index_start; + uint32_t prop_index_end; + const lv_property_ops_t * properties; + uint32_t properties_count; + +#if LV_USE_OBJ_PROPERTY_NAME + /* An array of property ID and name */ + const lv_property_name_t * property_names; + uint32_t names_count; +#endif +#endif + + void * user_data; + const char * name; + int32_t width_def; + int32_t height_def; + uint32_t editable : 2; /**< Value from ::lv_obj_class_editable_t*/ + uint32_t group_def : 2; /**< Value from ::lv_obj_class_group_def_t*/ + uint32_t instance_size : 16; + uint32_t theme_inheritable : 1; /**< Value from ::lv_obj_class_theme_inheritable_t*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_obj_destruct(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_CLASS_PRIVATE_H*/ diff --git a/test/include/liblvgl/core/lv_obj_draw.h b/test/include/liblvgl/core/lv_obj_draw.h new file mode 100644 index 00000000..c0dbee43 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_draw.h @@ -0,0 +1,113 @@ +/** + * @file lv_obj_draw.h + * + */ + +#ifndef LV_OBJ_DRAW_H +#define LV_OBJ_DRAW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_types.h" +#include "../draw/lv_draw_rect.h" +#include "../draw/lv_draw_label.h" +#include "../draw/lv_draw_image.h" +#include "../draw/lv_draw_line.h" +#include "../draw/lv_draw_arc.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_LAYER_TYPE_NONE, + LV_LAYER_TYPE_SIMPLE, + LV_LAYER_TYPE_TRANSFORM, +} lv_layer_type_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a rectangle draw descriptor from an object's styles in its current state + * @param obj pointer to an object + * @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc + * @param draw_dsc the descriptor to initialize. + * If an `..._opa` field is set to `LV_OPA_TRANSP` the related properties won't be initialized. + * Should be initialized with `lv_draw_rect_dsc_init(draw_dsc)`. + * @note Only the relevant fields will be set. + * E.g. if `border width == 0` the other border properties won't be evaluated. + */ +void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_t * draw_dsc); + +/** + * Initialize a label draw descriptor from an object's styles in its current state + * @param obj pointer to an object + * @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc + * @param draw_dsc the descriptor to initialize. + * If the `opa` field is set to or the property is equal to `LV_OPA_TRANSP` the rest won't be initialized. + * Should be initialized with `lv_draw_label_dsc_init(draw_dsc)`. + */ +void lv_obj_init_draw_label_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_label_dsc_t * draw_dsc); + +/** + * Initialize an image draw descriptor from an object's styles in its current state + * @param obj pointer to an object + * @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc + * @param draw_dsc the descriptor to initialize. + * Should be initialized with `lv_draw_image_dsc_init(draw_dsc)`. + */ +void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_dsc_t * draw_dsc); + +/** + * Initialize a line draw descriptor from an object's styles in its current state + * @param obj pointer to an object + * @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc + * @param draw_dsc the descriptor to initialize. + * Should be initialized with `lv_draw_line_dsc_init(draw_dsc)`. + */ +void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_t * draw_dsc); + +/** + * Initialize an arc draw descriptor from an object's styles in its current state + * @param obj pointer to an object + * @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc + * @param draw_dsc the descriptor to initialize. + * Should be initialized with `lv_draw_arc_dsc_init(draw_dsc)`. + */ +void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t * draw_dsc); + +/** + * Get the required extra size (around the object's part) to draw shadow, outline, value etc. + * @param obj pointer to an object + * @param part part of the object + * @return the extra size required around the object + */ +int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, lv_part_t part); + +/** + * Send a 'LV_EVENT_REFR_EXT_DRAW_SIZE' Call the ancestor's event handler to the object to refresh the value of the extended draw size. + * The result will be saved in `obj`. + * @param obj pointer to an object + */ +void lv_obj_refresh_ext_draw_size(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_DRAW_H*/ diff --git a/test/include/liblvgl/core/lv_obj_draw_private.h b/test/include/liblvgl/core/lv_obj_draw_private.h new file mode 100644 index 00000000..36c8bff9 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_draw_private.h @@ -0,0 +1,48 @@ +/** + * @file lv_obj_draw_private.h + * + */ + +#ifndef LV_OBJ_DRAW_PRIVATE_H +#define LV_OBJ_DRAW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_draw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the extended draw area of an object. + * @param obj pointer to an object + * @return the size extended draw area around the real coordinates + */ +int32_t lv_obj_get_ext_draw_size(const lv_obj_t * obj); + +lv_layer_type_t lv_obj_get_layer_type(const lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_DRAW_PRIVATE_H*/ diff --git a/test/include/liblvgl/core/lv_obj_event.h b/test/include/liblvgl/core/lv_obj_event.h new file mode 100644 index 00000000..2035f176 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_event.h @@ -0,0 +1,198 @@ +/** + * @file lv_obj_event.h + * + */ + +#ifndef LV_OBJ_EVENT_H +#define LV_OBJ_EVENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_types.h" +#include "../misc/lv_event.h" +#include "../indev/lv_indev.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Cover check results.*/ +typedef enum { + LV_COVER_RES_COVER = 0, + LV_COVER_RES_NOT_COVER = 1, + LV_COVER_RES_MASKED = 2, +} lv_cover_res_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Send an event to the object + * @param obj pointer to an object + * @param event_code the type of the event from `lv_event_t` + * @param param arbitrary data depending on the widget type and the event. (Usually `NULL`) + * @return LV_RESULT_OK: `obj` was not deleted in the event; LV_RESULT_INVALID: `obj` was deleted in the event_code + */ +lv_result_t lv_obj_send_event(lv_obj_t * obj, lv_event_code_t event_code, void * param); + +/** + * Used by the widgets internally to call the ancestor widget types's event handler + * @param class_p pointer to the class of the widget (NOT the ancestor class) + * @param e pointer to the event descriptor + * @return LV_RESULT_OK: the target object was not deleted in the event; LV_RESULT_INVALID: it was deleted in the event_code + */ +lv_result_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e); + +/** + * Get the current target of the event. It's the object which event handler being called. + * If the event is not bubbled it's the same as "original" target. + * @param e pointer to the event descriptor + * @return the target of the event_code + */ +lv_obj_t * lv_event_get_current_target_obj(lv_event_t * e); + +/** + * Get the object originally targeted by the event. It's the same even if the event is bubbled. + * @param e pointer to the event descriptor + * @return pointer to the original target of the event_code + */ +lv_obj_t * lv_event_get_target_obj(lv_event_t * e); + +/** + * Add an event handler function for an object. + * Used by the user to react on event which happens with the object. + * An object can have multiple event handler. They will be called in the same order as they were added. + * @param obj pointer to an object + * @param filter an event code (e.g. `LV_EVENT_CLICKED`) on which the event should be called. `LV_EVENT_ALL` can be used to receive all the events. + * @param event_cb the new event function + * @param user_data custom data will be available in `event_cb` + * @return handler to the event. It can be used in `lv_obj_remove_event_dsc`. + */ +lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data); + +uint32_t lv_obj_get_event_count(lv_obj_t * obj); + +lv_event_dsc_t * lv_obj_get_event_dsc(lv_obj_t * obj, uint32_t index); + +bool lv_obj_remove_event(lv_obj_t * obj, uint32_t index); + +bool lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb); + +bool lv_obj_remove_event_dsc(lv_obj_t * obj, lv_event_dsc_t * dsc); + +/** + * Remove an event_cb with user_data + * @param obj pointer to a obj + * @param event_cb the event_cb of the event to remove + * @param user_data user_data + * @return the count of the event removed + */ +uint32_t lv_obj_remove_event_cb_with_user_data(lv_obj_t * obj, lv_event_cb_t event_cb, void * user_data); + +/** + * Get the input device passed as parameter to indev related events. + * @param e pointer to an event + * @return the indev that triggered the event or NULL if called on a not indev related event + */ +lv_indev_t * lv_event_get_indev(lv_event_t * e); + +/** + * Get the draw context which should be the first parameter of the draw functions. + * Namely: `LV_EVENT_DRAW_MAIN/POST`, `LV_EVENT_DRAW_MAIN/POST_BEGIN`, `LV_EVENT_DRAW_MAIN/POST_END` + * @param e pointer to an event + * @return pointer to a draw context or NULL if called on an unrelated event + */ +lv_layer_t * lv_event_get_layer(lv_event_t * e); + +/** + * Get the old area of the object before its size was changed. Can be used in `LV_EVENT_SIZE_CHANGED` + * @param e pointer to an event + * @return the old absolute area of the object or NULL if called on an unrelated event + */ +const lv_area_t * lv_event_get_old_size(lv_event_t * e); + +/** + * Get the key passed as parameter to an event. Can be used in `LV_EVENT_KEY` + * @param e pointer to an event + * @return the triggering key or NULL if called on an unrelated event + */ +uint32_t lv_event_get_key(lv_event_t * e); + +/** + * Get the signed rotary encoder diff. passed as parameter to an event. Can be used in `LV_EVENT_ROTARY` + * @param e pointer to an event + * @return the triggering key or NULL if called on an unrelated event + */ +int32_t lv_event_get_rotary_diff(lv_event_t * e); + +/** + * Get the animation descriptor of a scrolling. Can be used in `LV_EVENT_SCROLL_BEGIN` + * @param e pointer to an event + * @return the animation that will scroll the object. (can be modified as required) + */ +lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e); + +/** + * Set the new extra draw size. Can be used in `LV_EVENT_REFR_EXT_DRAW_SIZE` + * @param e pointer to an event + * @param size The new extra draw size + */ +void lv_event_set_ext_draw_size(lv_event_t * e, int32_t size); + +/** + * Get a pointer to an `lv_point_t` variable in which the self size should be saved (width in `point->x` and height `point->y`). + * Can be used in `LV_EVENT_GET_SELF_SIZE` + * @param e pointer to an event + * @return pointer to `lv_point_t` or NULL if called on an unrelated event + */ +lv_point_t * lv_event_get_self_size_info(lv_event_t * e); + +/** + * Get a pointer to an `lv_hit_test_info_t` variable in which the hit test result should be saved. Can be used in `LV_EVENT_HIT_TEST` + * @param e pointer to an event + * @return pointer to `lv_hit_test_info_t` or NULL if called on an unrelated event + */ +lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e); + +/** + * Get a pointer to an area which should be examined whether the object fully covers it or not. + * Can be used in `LV_EVENT_HIT_TEST` + * @param e pointer to an event + * @return an area with absolute coordinates to check + */ +const lv_area_t * lv_event_get_cover_area(lv_event_t * e); + +/** + * Set the result of cover checking. Can be used in `LV_EVENT_COVER_CHECK` + * @param e pointer to an event + * @param res an element of ::lv_cover_check_info_t + */ +void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res); + +/** + * Get the draw task which was just added. + * Can be used in `LV_EVENT_DRAW_TASK_ADDED event` + * @param e pointer to an event + * @return the added draw task + */ +lv_draw_task_t * lv_event_get_draw_task(lv_event_t * e); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_EVENT_H*/ diff --git a/test/include/liblvgl/core/lv_obj_event_private.h b/test/include/liblvgl/core/lv_obj_event_private.h new file mode 100644 index 00000000..2199717c --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_event_private.h @@ -0,0 +1,62 @@ +/** + * @file lv_obj_event_private.h + * + */ + +#ifndef LV_OBJ_EVENT_PRIVATE_H +#define LV_OBJ_EVENT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_event.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Used as the event parameter of ::LV_EVENT_HIT_TEST to check if an `point` can click the object or not. + * `res` should be set like this: + * - If already set to `false` another event wants that point non clickable. If you want to respect it leave it as `false` or set `true` to overwrite it. + * - If already set `true` and `point` shouldn't be clickable set to `false` + * - If already set to `true` you agree that `point` can click the object leave it as `true` + */ +struct _lv_hit_test_info_t { + const lv_point_t * point; /**< A point relative to screen to check if it can click the object or not*/ + bool res; /**< true: `point` can click the object; false: it cannot*/ +}; + +/** + * Used as the event parameter of ::LV_EVENT_COVER_CHECK to check if an area is covered by the object or not. + * In the event use `const lv_area_t * area = lv_event_get_cover_area(e)` to get the area to check + * and `lv_event_set_cover_res(e, res)` to set the result. + */ +struct _lv_cover_check_info_t { + lv_cover_res_t res; + const lv_area_t * area; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_EVENT_PRIVATE_H*/ diff --git a/test/include/liblvgl/core/lv_obj_pos.h b/test/include/liblvgl/core/lv_obj_pos.h new file mode 100644 index 00000000..584f0b7e --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_pos.h @@ -0,0 +1,451 @@ +/** + * @file lv_obj_pos.h + * + */ + +#ifndef LV_OBJ_POS_H +#define LV_OBJ_POS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_area.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + /** No flags */ + LV_OBJ_POINT_TRANSFORM_FLAG_NONE = 0x00, + + /** Consider the transformation properties of the parents too */ + LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE = 0x01, + + /** Execute the inverse of the transformation (-angle and 1/zoom) */ + LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE = 0x02, + + /** Both inverse and recursive*/ + LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE_RECURSIVE = 0x03, +} lv_obj_point_transform_flag_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Set the position of an object relative to the set alignment. + * @param obj pointer to an object + * @param x new x coordinate + * @param y new y coordinate + * @note With default alignment it's the distance from the top left corner + * @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent + * @note The position is interpreted on the content area of the parent + * @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)` + */ +void lv_obj_set_pos(lv_obj_t * obj, int32_t x, int32_t y); + +/** + * Set the x coordinate of an object + * @param obj pointer to an object + * @param x new x coordinate + * @note With default alignment it's the distance from the top left corner + * @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent + * @note The position is interpreted on the content area of the parent + * @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)` + */ +void lv_obj_set_x(lv_obj_t * obj, int32_t x); + +/** + * Set the y coordinate of an object + * @param obj pointer to an object + * @param y new y coordinate + * @note With default alignment it's the distance from the top left corner + * @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent + * @note The position is interpreted on the content area of the parent + * @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)` + */ +void lv_obj_set_y(lv_obj_t * obj, int32_t y); + +/** + * Set the size of an object. + * @param obj pointer to an object + * @param w the new width + * @param h the new height + * @note possible values are: + * pixel simple set the size accordingly + * LV_SIZE_CONTENT set the size to involve all children in the given direction + * lv_pct(x) to set size in percentage of the parent's content area size (the size without paddings). + * x should be in [0..1000]% range + */ +void lv_obj_set_size(lv_obj_t * obj, int32_t w, int32_t h); + +/** + * Recalculate the size of the object + * @param obj pointer to an object + * @return true: the size has been changed + */ +bool lv_obj_refr_size(lv_obj_t * obj); + +/** + * Set the width of an object + * @param obj pointer to an object + * @param w the new width + * @note possible values are: + * pixel simple set the size accordingly + * LV_SIZE_CONTENT set the size to involve all children in the given direction + * lv_pct(x) to set size in percentage of the parent's content area size (the size without paddings). + * x should be in [0..1000]% range + */ +void lv_obj_set_width(lv_obj_t * obj, int32_t w); + +/** + * Set the height of an object + * @param obj pointer to an object + * @param h the new height + * @note possible values are: + * pixel simple set the size accordingly + * LV_SIZE_CONTENT set the size to involve all children in the given direction + * lv_pct(x) to set size in percentage of the parent's content area size (the size without paddings). + * x should be in [0..1000]% range + */ +void lv_obj_set_height(lv_obj_t * obj, int32_t h); + +/** + * Set the width reduced by the left and right padding and the border width. + * @param obj pointer to an object + * @param w the width without paddings in pixels + */ +void lv_obj_set_content_width(lv_obj_t * obj, int32_t w); + +/** + * Set the height reduced by the top and bottom padding and the border width. + * @param obj pointer to an object + * @param h the height without paddings in pixels + */ +void lv_obj_set_content_height(lv_obj_t * obj, int32_t h); + +/** + * Set a layout for an object + * @param obj pointer to an object + * @param layout pointer to a layout descriptor to set + */ +void lv_obj_set_layout(lv_obj_t * obj, uint32_t layout); + +/** + * Test whether the and object is positioned by a layout or not + * @param obj pointer to an object to test + * @return true: positioned by a layout; false: not positioned by a layout + */ +bool lv_obj_is_layout_positioned(const lv_obj_t * obj); + +/** + * Mark the object for layout update. + * @param obj pointer to an object whose children needs to be updated + */ +void lv_obj_mark_layout_as_dirty(lv_obj_t * obj); + +/** + * Update the layout of an object. + * @param obj pointer to an object whose children needs to be updated + */ +void lv_obj_update_layout(const lv_obj_t * obj); + +/** + * Change the alignment of an object. + * @param obj pointer to an object to align + * @param align type of alignment (see 'lv_align_t' enum) `LV_ALIGN_OUT_...` can't be used. + */ +void lv_obj_set_align(lv_obj_t * obj, lv_align_t align); + +/** + * Change the alignment of an object and set new coordinates. + * Equivalent to: + * lv_obj_set_align(obj, align); + * lv_obj_set_pos(obj, x_ofs, y_ofs); + * @param obj pointer to an object to align + * @param align type of alignment (see 'lv_align_t' enum) `LV_ALIGN_OUT_...` can't be used. + * @param x_ofs x coordinate offset after alignment + * @param y_ofs y coordinate offset after alignment + */ +void lv_obj_align(lv_obj_t * obj, lv_align_t align, int32_t x_ofs, int32_t y_ofs); + +/** + * Align an object to another object. + * @param obj pointer to an object to align + * @param base pointer to another object (if NULL `obj`s parent is used). 'obj' will be aligned to it. + * @param align type of alignment (see 'lv_align_t' enum) + * @param x_ofs x coordinate offset after alignment + * @param y_ofs y coordinate offset after alignment + * @note if the position or size of `base` changes `obj` needs to be aligned manually again + */ +void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, int32_t x_ofs, + int32_t y_ofs); + +/** + * Align an object to the center on its parent. + * @param obj pointer to an object to align + * @note if the parent size changes `obj` needs to be aligned manually again + */ +void lv_obj_center(lv_obj_t * obj); + +/** + * Copy the coordinates of an object to an area + * @param obj pointer to an object + * @param coords pointer to an area to store the coordinates + */ +void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * coords); + +/** + * Get the x coordinate of object. + * @param obj pointer to an object + * @return distance of `obj` from the left side of its parent plus the parent's left padding + * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation + * call `lv_obj_update_layout(obj)`. + * @note Zero return value means the object is on the left padding of the parent, and not on the left edge. + * @note Scrolling of the parent doesn't change the returned value. + * @note The returned value is always the distance from the parent even if `obj` is positioned by a layout. + */ +int32_t lv_obj_get_x(const lv_obj_t * obj); + +/** + * Get the x2 coordinate of object. + * @param obj pointer to an object + * @return distance of `obj` from the right side of its parent plus the parent's right padding + * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation + * call `lv_obj_update_layout(obj)`. + * @note Zero return value means the object is on the right padding of the parent, and not on the right edge. + * @note Scrolling of the parent doesn't change the returned value. + * @note The returned value is always the distance from the parent even if `obj` is positioned by a layout. + */ +int32_t lv_obj_get_x2(const lv_obj_t * obj); + +/** + * Get the y coordinate of object. + * @param obj pointer to an object + * @return distance of `obj` from the top side of its parent plus the parent's top padding + * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation + * call `lv_obj_update_layout(obj)`. + * @note Zero return value means the object is on the top padding of the parent, and not on the top edge. + * @note Scrolling of the parent doesn't change the returned value. + * @note The returned value is always the distance from the parent even if `obj` is positioned by a layout. + */ +int32_t lv_obj_get_y(const lv_obj_t * obj); + +/** + * Get the y2 coordinate of object. + * @param obj pointer to an object + * @return distance of `obj` from the bottom side of its parent plus the parent's bottom padding + * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation + * call `lv_obj_update_layout(obj)`. + * @note Zero return value means the object is on the bottom padding of the parent, and not on the bottom edge. + * @note Scrolling of the parent doesn't change the returned value. + * @note The returned value is always the distance from the parent even if `obj` is positioned by a layout. + */ +int32_t lv_obj_get_y2(const lv_obj_t * obj); + +/** + * Get the actually set x coordinate of object, i.e. the offset from the set alignment + * @param obj pointer to an object + * @return the set x coordinate + */ +int32_t lv_obj_get_x_aligned(const lv_obj_t * obj); + +/** + * Get the actually set y coordinate of object, i.e. the offset from the set alignment + * @param obj pointer to an object + * @return the set y coordinate + */ +int32_t lv_obj_get_y_aligned(const lv_obj_t * obj); + +/** + * Get the width of an object + * @param obj pointer to an object + * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation + * call `lv_obj_update_layout(obj)`. + * @return the width in pixels + */ +int32_t lv_obj_get_width(const lv_obj_t * obj); + +/** + * Get the height of an object + * @param obj pointer to an object + * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation + * call `lv_obj_update_layout(obj)`. + * @return the height in pixels + */ +int32_t lv_obj_get_height(const lv_obj_t * obj); + +/** + * Get the width reduced by the left and right padding and the border width. + * @param obj pointer to an object + * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation + * call `lv_obj_update_layout(obj)`. + * @return the width which still fits into its parent without causing overflow (making the parent scrollable) + */ +int32_t lv_obj_get_content_width(const lv_obj_t * obj); + +/** + * Get the height reduced by the top and bottom padding and the border width. + * @param obj pointer to an object + * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation + * call `lv_obj_update_layout(obj)`. + * @return the height which still fits into the parent without causing overflow (making the parent scrollable) + */ +int32_t lv_obj_get_content_height(const lv_obj_t * obj); + +/** + * Get the area reduced by the paddings and the border width. + * @param obj pointer to an object + * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation + * call `lv_obj_update_layout(obj)`. + * @param area the area which still fits into the parent without causing overflow (making the parent scrollable) + */ +void lv_obj_get_content_coords(const lv_obj_t * obj, lv_area_t * area); + +/** + * Get the width occupied by the "parts" of the widget. E.g. the width of all columns of a table. + * @param obj pointer to an objects + * @return the width of the virtually drawn content + * @note This size independent from the real size of the widget. + * It just tells how large the internal ("virtual") content is. + */ +int32_t lv_obj_get_self_width(const lv_obj_t * obj); + +/** + * Get the height occupied by the "parts" of the widget. E.g. the height of all rows of a table. + * @param obj pointer to an objects + * @return the width of the virtually drawn content + * @note This size independent from the real size of the widget. + * It just tells how large the internal ("virtual") content is. + */ +int32_t lv_obj_get_self_height(const lv_obj_t * obj); + +/** + * Handle if the size of the internal ("virtual") content of an object has changed. + * @param obj pointer to an object + * @return false: nothing happened; true: refresh happened + */ +bool lv_obj_refresh_self_size(lv_obj_t * obj); + +void lv_obj_refr_pos(lv_obj_t * obj); + +void lv_obj_move_to(lv_obj_t * obj, int32_t x, int32_t y); + +void lv_obj_move_children_by(lv_obj_t * obj, int32_t x_diff, int32_t y_diff, bool ignore_floating); + +/** + * Transform a point using the angle and zoom style properties of an object + * @param obj pointer to an object whose style properties should be used + * @param p a point to transform, the result will be written back here too + * @param flags OR-ed valued of :cpp:enum:`lv_obj_point_transform_flag_t` + */ +void lv_obj_transform_point(const lv_obj_t * obj, lv_point_t * p, lv_obj_point_transform_flag_t flags); + +/** + * Transform an array of points using the angle and zoom style properties of an object + * @param obj pointer to an object whose style properties should be used + * @param points the array of points to transform, the result will be written back here too + * @param count number of points in the array + * @param flags OR-ed valued of :cpp:enum:`lv_obj_point_transform_flag_t` + */ +void lv_obj_transform_point_array(const lv_obj_t * obj, lv_point_t points[], size_t count, + lv_obj_point_transform_flag_t flags); + +/** + * Transform an area using the angle and zoom style properties of an object + * @param obj pointer to an object whose style properties should be used + * @param area an area to transform, the result will be written back here too + * @param flags OR-ed valued of :cpp:enum:`lv_obj_point_transform_flag_t` + */ +void lv_obj_get_transformed_area(const lv_obj_t * obj, lv_area_t * area, lv_obj_point_transform_flag_t flags); + +/** + * Mark an area of an object as invalid. + * The area will be truncated to the object's area and marked for redraw. + * @param obj pointer to an object + * @param area the area to redraw + */ +void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area); + +/** + * Mark the object as invalid to redrawn its area + * @param obj pointer to an object + */ +void lv_obj_invalidate(const lv_obj_t * obj); + +/** + * Tell whether an area of an object is visible (even partially) now or not + * @param obj pointer to an object + * @param area the are to check. The visible part of the area will be written back here. + * @return true visible; false not visible (hidden, out of parent, on other screen, etc) + */ +bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area); + +/** + * Tell whether an object is visible (even partially) now or not + * @param obj pointer to an object + * @return true: visible; false not visible (hidden, out of parent, on other screen, etc) + */ +bool lv_obj_is_visible(const lv_obj_t * obj); + +/** + * Set the size of an extended clickable area + * @param obj pointer to an object + * @param size extended clickable area in all 4 directions [px] + */ +void lv_obj_set_ext_click_area(lv_obj_t * obj, int32_t size); + +/** + * Get the an area where to object can be clicked. + * It's the object's normal area plus the extended click area. + * @param obj pointer to an object + * @param area store the result area here + */ +void lv_obj_get_click_area(const lv_obj_t * obj, lv_area_t * area); + +/** + * Hit-test an object given a particular point in screen space. + * @param obj object to hit-test + * @param point screen-space point (absolute coordinate) + * @return true: if the object is considered under the point + */ +bool lv_obj_hit_test(lv_obj_t * obj, const lv_point_t * point); + +/** + * Clamp a width between min and max width. If the min/max width is in percentage value use the ref_width + * @param width width to clamp + * @param min_width the minimal width + * @param max_width the maximal width + * @param ref_width the reference width used when min/max width is in percentage + * @return the clamped width + */ +int32_t lv_clamp_width(int32_t width, int32_t min_width, int32_t max_width, int32_t ref_width); + +/** + * Clamp a height between min and max height. If the min/max height is in percentage value use the ref_height + * @param height height to clamp + * @param min_height the minimal height + * @param max_height the maximal height + * @param ref_height the reference height used when min/max height is in percentage + * @return the clamped height + */ +int32_t lv_clamp_height(int32_t height, int32_t min_height, int32_t max_height, int32_t ref_height); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_POS_H*/ diff --git a/test/include/liblvgl/core/lv_obj_private.h b/test/include/liblvgl/core/lv_obj_private.h new file mode 100644 index 00000000..865b9771 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_private.h @@ -0,0 +1,88 @@ +/** + * @file lv_obj_private.h + * + */ + +#ifndef LV_OBJ_PRIVATE_H +#define LV_OBJ_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Special, rarely used attributes. + * They are allocated automatically if any elements is set. + */ +struct _lv_obj_spec_attr_t { + lv_obj_t ** children; /**< Store the pointer of the children in an array.*/ + lv_group_t * group_p; + lv_event_list_t event_list; + + lv_point_t scroll; /**< The current X/Y scroll offset*/ + + int32_t ext_click_pad; /**< Extra click padding in all direction*/ + int32_t ext_draw_size; /**< EXTend the size in every direction for drawing.*/ + + uint16_t child_cnt; /**< Number of children*/ + uint16_t scrollbar_mode : 2; /**< How to display scrollbars, see `lv_scrollbar_mode_t`*/ + uint16_t scroll_snap_x : 2; /**< Where to align the snappable children horizontally, see `lv_scroll_snap_t`*/ + uint16_t scroll_snap_y : 2; /**< Where to align the snappable children vertically*/ + uint16_t scroll_dir : 4; /**< The allowed scroll direction(s), see `lv_dir_t`*/ + uint16_t layer_type : 2; /**< Cache the layer type here. Element of lv_intermediate_layer_type_t */ +}; + +struct _lv_obj_t { + const lv_obj_class_t * class_p; + lv_obj_t * parent; + lv_obj_spec_attr_t * spec_attr; + lv_obj_style_t * styles; +#if LV_OBJ_STYLE_CACHE + uint32_t style_main_prop_is_set; + uint32_t style_other_prop_is_set; +#endif + void * user_data; +#if LV_USE_OBJ_ID + void * id; +#endif + lv_area_t coords; + lv_obj_flag_t flags; + lv_state_t state; + uint16_t layout_inv : 1; + uint16_t readjust_scroll_after_layout : 1; + uint16_t scr_layout_inv : 1; + uint16_t skip_trans : 1; + uint16_t style_cnt : 6; + uint16_t h_layout : 1; + uint16_t w_layout : 1; + uint16_t is_deleting : 1; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_PRIVATE_H*/ diff --git a/test/include/liblvgl/core/lv_obj_property.h b/test/include/liblvgl/core/lv_obj_property.h new file mode 100644 index 00000000..2053a5c2 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_property.h @@ -0,0 +1,209 @@ +/** + * @file lv_obj_property.h + * + */ + +#ifndef LV_OBJ_PROPERTY_H +#define LV_OBJ_PROPERTY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_types.h" +#include "../misc/lv_style.h" + +#if LV_USE_OBJ_PROPERTY + +/********************* + * DEFINES + *********************/ + +/*All possible property value types*/ +#define LV_PROPERTY_TYPE_INVALID 0 /*Use default 0 as invalid to detect program outliers*/ +#define LV_PROPERTY_TYPE_INT 1 /*int32_t type*/ +#define LV_PROPERTY_TYPE_PRECISE 2 /*lv_value_precise_t, int32_t or float depending on LV_USE_FLOAT*/ +#define LV_PROPERTY_TYPE_COLOR 3 /*ARGB8888 type*/ +#define LV_PROPERTY_TYPE_POINT 4 /*lv_point_t */ +#define LV_PROPERTY_TYPE_POINTER 5 /*void * pointer*/ +#define LV_PROPERTY_TYPE_IMGSRC 6 /*Special pointer for image*/ +#define LV_PROPERTY_TYPE_TEXT 7 /*Special pointer of char* */ +#define LV_PROPERTY_TYPE_OBJ 8 /*Special pointer of lv_obj_t* */ +#define LV_PROPERTY_TYPE_DISPLAY 9 /*Special pointer of lv_display_t* */ +#define LV_PROPERTY_TYPE_FONT 10 /*Special pointer of lv_font_t* */ +#define LV_PROPERTY_TYPE_BOOL 11 /*int32_t type*/ + +#define LV_PROPERTY_TYPE_SHIFT 28 +#define LV_PROPERTY_ID(clz, name, type, index) LV_PROPERTY_## clz ##_##name = (LV_PROPERTY_## clz ##_START + (index)) | ((type) << LV_PROPERTY_TYPE_SHIFT) + +#define LV_PROPERTY_ID_TYPE(id) ((id) >> LV_PROPERTY_TYPE_SHIFT) +#define LV_PROPERTY_ID_INDEX(id) ((id) & 0xfffffff) + +/*Set properties from an array of lv_property_t*/ +#define LV_OBJ_SET_PROPERTY_ARRAY(obj, array) lv_obj_set_properties(obj, array, sizeof(array)/sizeof(array[0])) + + +/********************** + * TYPEDEFS + **********************/ + +/** + * Group of predefined widget ID start value. + */ +enum { + LV_PROPERTY_ID_INVALID = 0, + + /*ID 0x01 to 0xff are style ID, check lv_style_prop_t*/ + LV_PROPERTY_STYLE_START = 0x00, + + LV_PROPERTY_ID_START = 0x0100, /*ID smaller than 0xff is style ID*/ + /*Define the property ID for every widget here. */ + LV_PROPERTY_OBJ_START = 0x0100, /* lv_obj.c */ + LV_PROPERTY_IMAGE_START = 0x0200, /* lv_image.c */ + LV_PROPERTY_LABEL_START = 0x0300, /* lv_label.c */ + LV_PROPERTY_KEYBOARD_START = 0x0400, /* lv_keyboard.c */ + LV_PROPERTY_TEXTAREA_START = 0x0500, /* lv_textarea.c */ + LV_PROPERTY_ROLLER_START = 0x0600, /* lv_roller.c */ + LV_PROPERTY_DROPDOWN_START = 0x0700, /* lv_dropdown.c */ + + /*Special ID, use it to extend ID and make sure it's unique and compile time determinant*/ + LV_PROPERTY_ID_BUILTIN_LAST = 0xffff, /*ID of 0x10000 ~ 0xfffffff is reserved for user*/ + + LV_PROPERTY_ID_ANY = 0x7ffffffe, /*Special ID used by lvgl to intercept all setter/getter call.*/ +}; + +struct _lv_property_name_t { + const char * name; + lv_prop_id_t id; +}; + +typedef struct { + lv_prop_id_t id; + union { + int32_t num; /**< Number integer number (opacity, enums, booleans or "normal" numbers)*/ + bool enable; /**< booleans*/ + const void * ptr; /**< Constant pointers (font, cone text, etc)*/ + lv_color_t color; /**< Colors*/ + lv_value_precise_t precise; /**< float or int for precise value*/ + lv_point_t point; /**< Point*/ + struct { + /** + * Note that place struct member `style` at first place is intended. + * `style` shares same memory with `num`, `ptr`, `color`. + * So we set the style value directly without using `prop.style.num`. + * + * E.g. + * + * static const lv_property_t obj_pos_x = { + * .id = LV_PROPERTY_STYLE_X, + * .num = 123, + * .selector = LV_STATE_PRESSED, + * } + * + * instead of: + * static const lv_property_t obj_pos_x = { + * .id = LV_PROPERTY_STYLE_X, + * .style.num = 123, // note this line. + * .selector = LV_STATE_PRESSED, + * } + */ + lv_style_value_t style; /**< Make sure it's the first element in struct. */ + uint32_t selector; /**< Style selector, lv_part_t | lv_state_t */ + }; + }; +} lv_property_t; + +typedef struct { + lv_prop_id_t id; + + void * setter; /**< Callback used to set property. */ + void * getter; /**< Callback used to get property. */ +} lv_property_ops_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/*===================== + * Setter functions + *====================*/ + +/** + * Set widget property. + * @param obj pointer to an object + * @param value The property value to set + * @return return LV_RESULT_OK if success + */ +lv_result_t lv_obj_set_property(lv_obj_t * obj, const lv_property_t * value); + +/** + * Set multiple widget properties. Helper `LV_OBJ_SET_PROPERTY_ARRAY` can be used for constant property array. + * @param obj pointer to an object + * @param value The property value array to set + * @param count The count of the property value array + * @return return LV_RESULT_OK if success + */ +lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, uint32_t count); + +/*===================== + * Getter functions + *====================*/ + +/** + * Read property value from object. + * If id is a style property, the style selector is default to 0. + * @param obj pointer to an object + * @param id ID of which property to read + * @return return the property value read. The returned property ID is set to `LV_PROPERTY_ID_INVALID` if failed. + */ +lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id); + +/** + * Read a style property value from object + * @param obj pointer to an object + * @param id ID of style property + * @param selector selector for the style property. + * @return return the property value read. The returned property ID is set to `LV_PROPERTY_ID_INVALID` if failed. + */ +lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_t selector); + +/** + * Get the property ID by name recursively to base classes. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`. + * @param obj pointer to an object that has specified property or base class has. + * @param name property name + * @return property ID found or `LV_PROPERTY_ID_INVALID` if not found. + */ +lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name); + +/** + * Get the property ID by name without check base class recursively. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`. + * @param clz pointer to an object class that has specified property or base class has. + * @param name property name + * @return property ID found or `LV_PROPERTY_ID_INVALID` if not found. + */ +lv_prop_id_t lv_obj_class_property_get_id(const lv_obj_class_t * clz, const char * name); + +/** + * Get the style property ID by name. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`. + * @param name property name + * @return property ID found or `LV_PROPERTY_ID_INVALID` if not found. + */ +lv_prop_id_t lv_style_property_get_id(const char * name); + +/********************** + * MACROS + **********************/ + +#include "../widgets/property/lv_obj_property_names.h" +#include "../widgets/property/lv_style_properties.h" + +#endif /*LV_USE_OBJ_PROPERTY*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_PROPERTY_H*/ diff --git a/test/include/liblvgl/core/lv_obj_scroll.h b/test/include/liblvgl/core/lv_obj_scroll.h new file mode 100644 index 00000000..f2cb2f10 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_scroll.h @@ -0,0 +1,290 @@ +/** + * @file lv_obj_scroll.h + * + */ + +#ifndef LV_OBJ_SCROLL_H +#define LV_OBJ_SCROLL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_area.h" +#include "../misc/lv_anim.h" +#include "../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/*Can't include lv_obj.h because it includes this header file*/ + +/** Scrollbar modes: shows when should the scrollbars be visible*/ +typedef enum { + LV_SCROLLBAR_MODE_OFF, /**< Never show scrollbars*/ + LV_SCROLLBAR_MODE_ON, /**< Always show scrollbars*/ + LV_SCROLLBAR_MODE_ACTIVE, /**< Show scroll bars when object is being scrolled*/ + LV_SCROLLBAR_MODE_AUTO, /**< Show scroll bars when the content is large enough to be scrolled*/ +} lv_scrollbar_mode_t; + +/** Scroll span align options. Tells where to align the snappable children when scroll stops.*/ +typedef enum { + LV_SCROLL_SNAP_NONE, /**< Do not align, leave where it is*/ + LV_SCROLL_SNAP_START, /**< Align to the left/top*/ + LV_SCROLL_SNAP_END, /**< Align to the right/bottom*/ + LV_SCROLL_SNAP_CENTER /**< Align to the center*/ +} lv_scroll_snap_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/*===================== + * Setter functions + *====================*/ + +/** + * Set how the scrollbars should behave. + * @param obj pointer to an object + * @param mode LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE + */ +void lv_obj_set_scrollbar_mode(lv_obj_t * obj, lv_scrollbar_mode_t mode); + +/** + * Set the object in which directions can be scrolled + * @param obj pointer to an object + * @param dir the allow scroll directions. An element or OR-ed values of `lv_dir_t` + */ +void lv_obj_set_scroll_dir(lv_obj_t * obj, lv_dir_t dir); + +/** + * Set where to snap the children when scrolling ends horizontally + * @param obj pointer to an object + * @param align the snap align to set from `lv_scroll_snap_t` + */ +void lv_obj_set_scroll_snap_x(lv_obj_t * obj, lv_scroll_snap_t align); + +/** + * Set where to snap the children when scrolling ends vertically + * @param obj pointer to an object + * @param align the snap align to set from `lv_scroll_snap_t` + */ +void lv_obj_set_scroll_snap_y(lv_obj_t * obj, lv_scroll_snap_t align); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the current scroll mode (when to hide the scrollbars) + * @param obj pointer to an object + * @return the current scroll mode from `lv_scrollbar_mode_t` + */ +lv_scrollbar_mode_t lv_obj_get_scrollbar_mode(const lv_obj_t * obj); + +/** + * Get the object in which directions can be scrolled + * @param obj pointer to an object + */ +lv_dir_t lv_obj_get_scroll_dir(const lv_obj_t * obj); + +/** + * Get where to snap the children when scrolling ends horizontally + * @param obj pointer to an object + * @return the current snap align from `lv_scroll_snap_t` + */ +lv_scroll_snap_t lv_obj_get_scroll_snap_x(const lv_obj_t * obj); + +/** + * Get where to snap the children when scrolling ends vertically + * @param obj pointer to an object + * @return the current snap align from `lv_scroll_snap_t` + */ +lv_scroll_snap_t lv_obj_get_scroll_snap_y(const lv_obj_t * obj); + +/** + * Get current X scroll position. + * @param obj pointer to an object + * @return the current scroll position from the left edge. + * If the object is not scrolled return 0 + * If scrolled return > 0 + * If scrolled in (elastic scroll) return < 0 + */ +int32_t lv_obj_get_scroll_x(const lv_obj_t * obj); + +/** + * Get current Y scroll position. + * @param obj pointer to an object + * @return the current scroll position from the top edge. + * If the object is not scrolled return 0 + * If scrolled return > 0 + * If scrolled inside return < 0 + */ +int32_t lv_obj_get_scroll_y(const lv_obj_t * obj); + +/** + * Return the height of the area above the object. + * That is the number of pixels the object can be scrolled down. + * Normally positive but can be negative when scrolled inside. + * @param obj pointer to an object + * @return the scrollable area above the object in pixels + */ +int32_t lv_obj_get_scroll_top(lv_obj_t * obj); + +/** + * Return the height of the area below the object. + * That is the number of pixels the object can be scrolled down. + * Normally positive but can be negative when scrolled inside. + * @param obj pointer to an object + * @return the scrollable area below the object in pixels + */ +int32_t lv_obj_get_scroll_bottom(lv_obj_t * obj); + +/** + * Return the width of the area on the left the object. + * That is the number of pixels the object can be scrolled down. + * Normally positive but can be negative when scrolled inside. + * @param obj pointer to an object + * @return the scrollable area on the left the object in pixels + */ +int32_t lv_obj_get_scroll_left(lv_obj_t * obj); + +/** + * Return the width of the area on the right the object. + * That is the number of pixels the object can be scrolled down. + * Normally positive but can be negative when scrolled inside. + * @param obj pointer to an object + * @return the scrollable area on the right the object in pixels + */ +int32_t lv_obj_get_scroll_right(lv_obj_t * obj); + +/** + * Get the X and Y coordinates where the scrolling will end for this object if a scrolling animation is in progress. + * If no scrolling animation, give the current `x` or `y` scroll position. + * @param obj pointer to an object + * @param end pointer to store the result + */ +void lv_obj_get_scroll_end(lv_obj_t * obj, lv_point_t * end); + +/*===================== + * Other functions + *====================*/ + +/** + * Scroll by a given amount of pixels + * @param obj pointer to an object to scroll + * @param x pixels to scroll horizontally + * @param y pixels to scroll vertically + * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately + * @note > 0 value means scroll right/bottom (show the more content on the right/bottom) + * @note e.g. dy = -20 means scroll down 20 px + */ +void lv_obj_scroll_by(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t anim_en); + +/** + * Scroll by a given amount of pixels. + * `dx` and `dy` will be limited internally to allow scrolling only on the content area. + * @param obj pointer to an object to scroll + * @param dx pixels to scroll horizontally + * @param dy pixels to scroll vertically + * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately + * @note e.g. dy = -20 means scroll down 20 px + */ +void lv_obj_scroll_by_bounded(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en); + +/** + * Scroll to a given coordinate on an object. + * `x` and `y` will be limited internally to allow scrolling only on the content area. + * @param obj pointer to an object to scroll + * @param x pixels to scroll horizontally + * @param y pixels to scroll vertically + * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately + */ +void lv_obj_scroll_to(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t anim_en); + +/** + * Scroll to a given X coordinate on an object. + * `x` will be limited internally to allow scrolling only on the content area. + * @param obj pointer to an object to scroll + * @param x pixels to scroll horizontally + * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately + */ +void lv_obj_scroll_to_x(lv_obj_t * obj, int32_t x, lv_anim_enable_t anim_en); + +/** + * Scroll to a given Y coordinate on an object + * `y` will be limited internally to allow scrolling only on the content area. + * @param obj pointer to an object to scroll + * @param y pixels to scroll vertically + * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately + */ +void lv_obj_scroll_to_y(lv_obj_t * obj, int32_t y, lv_anim_enable_t anim_en); + +/** + * Scroll to an object until it becomes visible on its parent + * @param obj pointer to an object to scroll into view + * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately + */ +void lv_obj_scroll_to_view(lv_obj_t * obj, lv_anim_enable_t anim_en); + +/** + * Scroll to an object until it becomes visible on its parent. + * Do the same on the parent's parent, and so on. + * Therefore the object will be scrolled into view even it has nested scrollable parents + * @param obj pointer to an object to scroll into view + * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately + */ +void lv_obj_scroll_to_view_recursive(lv_obj_t * obj, lv_anim_enable_t anim_en); + +/** + * Tell whether an object is being scrolled or not at this moment + * @param obj pointer to an object + * @return true: `obj` is being scrolled + */ +bool lv_obj_is_scrolling(const lv_obj_t * obj); + +/** + * Check the children of `obj` and scroll `obj` to fulfill the scroll_snap settings + * @param obj an object whose children needs to checked and snapped + * @param anim_en LV_ANIM_ON/OFF + */ +void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en); + +/** + * Get the area of the scrollbars + * @param obj pointer to an object + * @param hor pointer to store the area of the horizontal scrollbar + * @param ver pointer to store the area of the vertical scrollbar + */ +void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor, lv_area_t * ver); + +/** + * Invalidate the area of the scrollbars + * @param obj pointer to an object + */ +void lv_obj_scrollbar_invalidate(lv_obj_t * obj); + +/** + * Checks if the content is scrolled "in" and adjusts it to a normal position. + * @param obj pointer to an object + * @param anim_en LV_ANIM_ON/OFF + */ +void lv_obj_readjust_scroll(lv_obj_t * obj, lv_anim_enable_t anim_en); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_SCROLL_H*/ diff --git a/test/include/liblvgl/core/lv_obj_scroll_private.h b/test/include/liblvgl/core/lv_obj_scroll_private.h new file mode 100644 index 00000000..9ae6332d --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_scroll_private.h @@ -0,0 +1,50 @@ +/** + * @file lv_obj_scroll_private.h + * + */ + +#ifndef LV_OBJ_SCROLL_PRIVATE_H +#define LV_OBJ_SCROLL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_scroll.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Low level function to scroll by given x and y coordinates. + * `LV_EVENT_SCROLL` is sent. + * @param obj pointer to an object to scroll + * @param x pixels to scroll horizontally + * @param y pixels to scroll vertically + * @return `LV_RESULT_INVALID`: to object was deleted in `LV_EVENT_SCROLL`; + * `LV_RESULT_OK`: if the object is still valid + */ +lv_result_t lv_obj_scroll_by_raw(lv_obj_t * obj, int32_t x, int32_t y); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_SCROLL_PRIVATE_H*/ diff --git a/test/include/liblvgl/core/lv_obj_style.h b/test/include/liblvgl/core/lv_obj_style.h new file mode 100644 index 00000000..ff4e365d --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_style.h @@ -0,0 +1,318 @@ +/** + * @file lv_obj_style.h + * + */ + +#ifndef LV_OBJ_STYLE_H +#define LV_OBJ_STYLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_bidi.h" +#include "../misc/lv_style.h" +#include "../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_STYLE_STATE_CMP_SAME, /**< The style properties in the 2 states are identical */ + LV_STYLE_STATE_CMP_DIFF_REDRAW, /**< The differences can be shown with a simple redraw */ + LV_STYLE_STATE_CMP_DIFF_DRAW_PAD, /**< The differences can be shown with a simple redraw */ + LV_STYLE_STATE_CMP_DIFF_LAYOUT, /**< The differences can be shown with a simple redraw */ +} lv_style_state_cmp_t; + +typedef uint32_t lv_style_selector_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Add a style to an object. + * @param obj pointer to an object + * @param style pointer to a style to add + * @param selector OR-ed value of parts and state to which the style should be added + * + * Examples: + * @code + * lv_obj_add_style(btn, &style_btn, 0); //Default button style + * + * lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); //Overwrite only some colors to red when pressed + * @endcode + */ +void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector); + +/** + * Replaces a style of an object, preserving the order of the style stack (local styles and transitions are ignored). + * @param obj pointer to an object + * @param old_style pointer to a style to replace. + * @param new_style pointer to a style to replace the old style with. + * @param selector OR-ed values of states and a part to replace only styles with matching selectors. LV_STATE_ANY and LV_PART_ANY can be used + * + * Examples: + * @code + * lv_obj_replace_style(obj, &yellow_style, &blue_style, LV_PART_ANY | LV_STATE_ANY); //Replace a specific style + * + * lv_obj_replace_style(obj, &yellow_style, &blue_style, LV_PART_MAIN | LV_STATE_PRESSED); //Replace a specific style assigned to the main part when it is pressed + * @endcode + */ +bool lv_obj_replace_style(lv_obj_t * obj, const lv_style_t * old_style, const lv_style_t * new_style, + lv_style_selector_t selector); + +/** + * Remove a style from an object. + * @param obj pointer to an object + * @param style pointer to a style to remove. Can be NULL to check only the selector + * @param selector OR-ed values of states and a part to remove only styles with matching selectors. LV_STATE_ANY and LV_PART_ANY can be used + * + * Examples: + * @code + * lv_obj_remove_style(obj, &style, LV_PART_ANY | LV_STATE_ANY); //Remove a specific style + * + * lv_obj_remove_style(obj, NULL, LV_PART_MAIN | LV_STATE_ANY); //Remove all styles from the main part + * + * lv_obj_remove_style(obj, NULL, LV_PART_ANY | LV_STATE_ANY); //Remove all styles + * @endcode + */ +void lv_obj_remove_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector); + +/** + * Remove all styles from an object + * @param obj pointer to an object + */ +void lv_obj_remove_style_all(lv_obj_t * obj); + +/** + * Notify all object if a style is modified + * @param style pointer to a style. Only the objects with this style will be notified + * (NULL to notify all objects) + */ +void lv_obj_report_style_change(lv_style_t * style); + +/** + * Notify an object and its children about its style is modified. + * @param obj pointer to an object + * @param part the part whose style was changed. E.g. `LV_PART_ANY`, `LV_PART_MAIN` + * @param prop `LV_STYLE_PROP_ANY` or an `LV_STYLE_...` property. + * It is used to optimize what needs to be refreshed. + * `LV_STYLE_PROP_INV` to perform only a style cache update + */ +void lv_obj_refresh_style(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop); + +/** + * Enable or disable automatic style refreshing when a new style is added/removed to/from an object + * or any other style change happens. + * @param en true: enable refreshing; false: disable refreshing + */ +void lv_obj_enable_style_refresh(bool en); + +/** + * Get the value of a style property. The current state of the object will be considered. + * Inherited properties will be inherited. + * If a property is not set a default value will be returned. + * @param obj pointer to an object + * @param part a part from which the property should be get + * @param prop the property to get + * @return the value of the property. + * Should be read from the correct field of the `lv_style_value_t` according to the type of the property. + */ +lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop); + +/** + * Check if an object has a specified style property for a given style selector. + * @param obj pointer to an object + * @param selector the style selector to be checked, defining the scope of the style to be examined. + * @param prop the property to be checked. + * @return true if the object has the specified selector and property, false otherwise. + */ +bool lv_obj_has_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop); + +/** + * Set local style property on an object's part and state. + * @param obj pointer to an object + * @param prop the property + * @param value value of the property. The correct element should be set according to the type of the property + * @param selector OR-ed value of parts and state for which the style should be set + */ +void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value, + lv_style_selector_t selector); + +lv_style_res_t lv_obj_get_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value, + lv_style_selector_t selector); + +/** + * Remove a local style property from a part of an object with a given state. + * @param obj pointer to an object + * @param prop a style property to remove. + * @param selector OR-ed value of parts and state for which the style should be removed + * @return true the property was found and removed; false: the property was not found + */ +bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_selector_t selector); + +/** + * Used internally for color filtering + */ +lv_style_value_t lv_obj_style_apply_color_filter(const lv_obj_t * obj, lv_part_t part, lv_style_value_t v); + +/** + * Fade in an an object and all its children. + * @param obj the object to fade in + * @param time time of fade + * @param delay delay to start the animation + */ +void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay); + +/** + * Fade out an an object and all its children. + * @param obj the object to fade out + * @param time time of fade + * @param delay delay to start the animation + */ +void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay); + +static inline lv_state_t lv_obj_style_get_selector_state(lv_style_selector_t selector) +{ + return selector & 0xFFFF; +} + +static inline lv_part_t lv_obj_style_get_selector_part(lv_style_selector_t selector) +{ + return selector & 0xFF0000; +} + +#include "lv_obj_style_gen.h" + +static inline void lv_obj_set_style_pad_all(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_obj_set_style_pad_left(obj, value, selector); + lv_obj_set_style_pad_right(obj, value, selector); + lv_obj_set_style_pad_top(obj, value, selector); + lv_obj_set_style_pad_bottom(obj, value, selector); +} + +static inline void lv_obj_set_style_pad_hor(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_obj_set_style_pad_left(obj, value, selector); + lv_obj_set_style_pad_right(obj, value, selector); +} + +static inline void lv_obj_set_style_pad_ver(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_obj_set_style_pad_top(obj, value, selector); + lv_obj_set_style_pad_bottom(obj, value, selector); +} + +static inline void lv_obj_set_style_margin_all(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_obj_set_style_margin_left(obj, value, selector); + lv_obj_set_style_margin_right(obj, value, selector); + lv_obj_set_style_margin_top(obj, value, selector); + lv_obj_set_style_margin_bottom(obj, value, selector); +} + +static inline void lv_obj_set_style_margin_hor(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_obj_set_style_margin_left(obj, value, selector); + lv_obj_set_style_margin_right(obj, value, selector); +} + +static inline void lv_obj_set_style_margin_ver(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_obj_set_style_margin_top(obj, value, selector); + lv_obj_set_style_margin_bottom(obj, value, selector); +} + +static inline void lv_obj_set_style_pad_gap(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_obj_set_style_pad_row(obj, value, selector); + lv_obj_set_style_pad_column(obj, value, selector); +} + +static inline void lv_obj_set_style_size(lv_obj_t * obj, int32_t width, int32_t height, + lv_style_selector_t selector) +{ + lv_obj_set_style_width(obj, width, selector); + lv_obj_set_style_height(obj, height, selector); +} + +static inline void lv_obj_set_style_transform_scale(lv_obj_t * obj, int32_t value, + lv_style_selector_t selector) +{ + lv_obj_set_style_transform_scale_x(obj, value, selector); + lv_obj_set_style_transform_scale_y(obj, value, selector); +} + +static inline int32_t lv_obj_get_style_space_left(const lv_obj_t * obj, lv_part_t part) +{ + int32_t padding = lv_obj_get_style_pad_left(obj, part); + int32_t border_width = lv_obj_get_style_border_width(obj, part); + lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part); + return (border_side & LV_BORDER_SIDE_LEFT) ? padding + border_width : padding; +} + +static inline int32_t lv_obj_get_style_space_right(const lv_obj_t * obj, lv_part_t part) +{ + int32_t padding = lv_obj_get_style_pad_right(obj, part); + int32_t border_width = lv_obj_get_style_border_width(obj, part); + lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part); + return (border_side & LV_BORDER_SIDE_RIGHT) ? padding + border_width : padding; +} + +static inline int32_t lv_obj_get_style_space_top(const lv_obj_t * obj, lv_part_t part) +{ + int32_t padding = lv_obj_get_style_pad_top(obj, part); + int32_t border_width = lv_obj_get_style_border_width(obj, part); + lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part); + return (border_side & LV_BORDER_SIDE_TOP) ? padding + border_width : padding; +} + +static inline int32_t lv_obj_get_style_space_bottom(const lv_obj_t * obj, lv_part_t part) +{ + int32_t padding = lv_obj_get_style_pad_bottom(obj, part); + int32_t border_width = lv_obj_get_style_border_width(obj, part); + lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part); + return (border_side & LV_BORDER_SIDE_BOTTOM) ? padding + border_width : padding; +} + +lv_text_align_t lv_obj_calculate_style_text_align(const lv_obj_t * obj, lv_part_t part, const char * txt); + +static inline int32_t lv_obj_get_style_transform_scale_x_safe(const lv_obj_t * obj, lv_part_t part) +{ + int32_t scale = lv_obj_get_style_transform_scale_x(obj, part); + return scale > 0 ? scale : 1; +} + +static inline int32_t lv_obj_get_style_transform_scale_y_safe(const lv_obj_t * obj, lv_part_t part) +{ + int32_t scale = lv_obj_get_style_transform_scale_y(obj, part); + return scale > 0 ? scale : 1; +} + +/** + * Get the `opa` style property from all parents and multiply and `>> 8` them. + * @param obj the object whose opacity should be get + * @param part the part whose opacity should be get. Non-MAIN parts will consider the `opa` of the MAIN part too + * @return the final opacity considering the parents' opacity too + */ +lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_STYLE_H*/ diff --git a/test/include/liblvgl/core/lv_obj_style_gen.h b/test/include/liblvgl/core/lv_obj_style_gen.h new file mode 100644 index 00000000..77cf5378 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_style_gen.h @@ -0,0 +1,875 @@ + +/* + ********************************************************************** + * DO NOT EDIT + * This file is automatically generated by "style_api_gen.py" + ********************************************************************** + */ + + +#ifndef LV_OBJ_STYLE_GEN_H +#define LV_OBJ_STYLE_GEN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../misc/lv_area.h" +#include "../misc/lv_style.h" +#include "../core/lv_obj_style.h" +#include "../misc/lv_types.h" + +static inline int32_t lv_obj_get_style_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_WIDTH); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_min_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MIN_WIDTH); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_max_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MAX_WIDTH); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_height(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_HEIGHT); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_min_height(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MIN_HEIGHT); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_max_height(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MAX_HEIGHT); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_length(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LENGTH); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_x(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_X); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_y(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_Y); + return (int32_t)v.num; +} + +static inline lv_align_t lv_obj_get_style_align(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ALIGN); + return (lv_align_t)v.num; +} + +static inline int32_t lv_obj_get_style_transform_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_WIDTH); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_transform_height(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_HEIGHT); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_translate_x(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSLATE_X); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_translate_y(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSLATE_Y); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_transform_scale_x(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SCALE_X); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_transform_scale_y(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SCALE_Y); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_transform_rotation(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_ROTATION); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_transform_pivot_x(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_PIVOT_X); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_transform_pivot_y(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_PIVOT_Y); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_transform_skew_x(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SKEW_X); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_transform_skew_y(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SKEW_Y); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_pad_top(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_TOP); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_pad_bottom(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_BOTTOM); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_pad_left(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_LEFT); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_pad_right(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_RIGHT); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_pad_row(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_ROW); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_pad_column(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_COLUMN); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_margin_top(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_TOP); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_margin_bottom(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_BOTTOM); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_margin_left(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_LEFT); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_margin_right(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_RIGHT); + return (int32_t)v.num; +} + +static inline lv_color_t lv_obj_get_style_bg_color(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_COLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_bg_color_filtered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_COLOR)); + return v.color; +} + +static inline lv_opa_t lv_obj_get_style_bg_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_OPA); + return (lv_opa_t)v.num; +} + +static inline lv_color_t lv_obj_get_style_bg_grad_color(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_COLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_BG_GRAD_COLOR)); + return v.color; +} + +static inline lv_grad_dir_t lv_obj_get_style_bg_grad_dir(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_DIR); + return (lv_grad_dir_t)v.num; +} + +static inline int32_t lv_obj_get_style_bg_main_stop(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_MAIN_STOP); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_bg_grad_stop(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_STOP); + return (int32_t)v.num; +} + +static inline lv_opa_t lv_obj_get_style_bg_main_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_MAIN_OPA); + return (lv_opa_t)v.num; +} + +static inline lv_opa_t lv_obj_get_style_bg_grad_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_OPA); + return (lv_opa_t)v.num; +} + +static inline const lv_grad_dsc_t * lv_obj_get_style_bg_grad(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD); + return (const lv_grad_dsc_t *)v.ptr; +} + +static inline const void * lv_obj_get_style_bg_image_src(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_SRC); + return (const void *)v.ptr; +} + +static inline lv_opa_t lv_obj_get_style_bg_image_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_OPA); + return (lv_opa_t)v.num; +} + +static inline lv_color_t lv_obj_get_style_bg_image_recolor(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_RECOLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_bg_image_recolor_filtered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_BG_IMAGE_RECOLOR)); + return v.color; +} + +static inline lv_opa_t lv_obj_get_style_bg_image_recolor_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_RECOLOR_OPA); + return (lv_opa_t)v.num; +} + +static inline bool lv_obj_get_style_bg_image_tiled(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_TILED); + return (bool)v.num; +} + +static inline lv_color_t lv_obj_get_style_border_color(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_COLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_border_color_filtered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_BORDER_COLOR)); + return v.color; +} + +static inline lv_opa_t lv_obj_get_style_border_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_OPA); + return (lv_opa_t)v.num; +} + +static inline int32_t lv_obj_get_style_border_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_WIDTH); + return (int32_t)v.num; +} + +static inline lv_border_side_t lv_obj_get_style_border_side(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_SIDE); + return (lv_border_side_t)v.num; +} + +static inline bool lv_obj_get_style_border_post(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_POST); + return (bool)v.num; +} + +static inline int32_t lv_obj_get_style_outline_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_WIDTH); + return (int32_t)v.num; +} + +static inline lv_color_t lv_obj_get_style_outline_color(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_COLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_outline_color_filtered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_OUTLINE_COLOR)); + return v.color; +} + +static inline lv_opa_t lv_obj_get_style_outline_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_OPA); + return (lv_opa_t)v.num; +} + +static inline int32_t lv_obj_get_style_outline_pad(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_PAD); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_shadow_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_WIDTH); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_shadow_offset_x(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OFFSET_X); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_shadow_offset_y(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OFFSET_Y); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_shadow_spread(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_SPREAD); + return (int32_t)v.num; +} + +static inline lv_color_t lv_obj_get_style_shadow_color(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_COLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_SHADOW_COLOR)); + return v.color; +} + +static inline lv_opa_t lv_obj_get_style_shadow_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OPA); + return (lv_opa_t)v.num; +} + +static inline lv_opa_t lv_obj_get_style_image_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_OPA); + return (lv_opa_t)v.num; +} + +static inline lv_color_t lv_obj_get_style_image_recolor(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_RECOLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_image_recolor_filtered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_IMAGE_RECOLOR)); + return v.color; +} + +static inline lv_opa_t lv_obj_get_style_image_recolor_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_RECOLOR_OPA); + return (lv_opa_t)v.num; +} + +static inline int32_t lv_obj_get_style_line_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_WIDTH); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_line_dash_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_DASH_WIDTH); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_line_dash_gap(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_DASH_GAP); + return (int32_t)v.num; +} + +static inline bool lv_obj_get_style_line_rounded(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_ROUNDED); + return (bool)v.num; +} + +static inline lv_color_t lv_obj_get_style_line_color(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_COLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_line_color_filtered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_COLOR)); + return v.color; +} + +static inline lv_opa_t lv_obj_get_style_line_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_OPA); + return (lv_opa_t)v.num; +} + +static inline int32_t lv_obj_get_style_arc_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_WIDTH); + return (int32_t)v.num; +} + +static inline bool lv_obj_get_style_arc_rounded(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_ROUNDED); + return (bool)v.num; +} + +static inline lv_color_t lv_obj_get_style_arc_color(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_COLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_arc_color_filtered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_COLOR)); + return v.color; +} + +static inline lv_opa_t lv_obj_get_style_arc_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_OPA); + return (lv_opa_t)v.num; +} + +static inline const void * lv_obj_get_style_arc_image_src(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_IMAGE_SRC); + return (const void *)v.ptr; +} + +static inline lv_color_t lv_obj_get_style_text_color(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_COLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_text_color_filtered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_COLOR)); + return v.color; +} + +static inline lv_opa_t lv_obj_get_style_text_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_OPA); + return (lv_opa_t)v.num; +} + +static inline const lv_font_t * lv_obj_get_style_text_font(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_FONT); + return (const lv_font_t *)v.ptr; +} + +static inline int32_t lv_obj_get_style_text_letter_space(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_LETTER_SPACE); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_text_line_space(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_LINE_SPACE); + return (int32_t)v.num; +} + +static inline lv_text_decor_t lv_obj_get_style_text_decor(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_DECOR); + return (lv_text_decor_t)v.num; +} + +static inline lv_text_align_t lv_obj_get_style_text_align(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_ALIGN); + return (lv_text_align_t)v.num; +} + +static inline int32_t lv_obj_get_style_radius(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_RADIUS); + return (int32_t)v.num; +} + +static inline bool lv_obj_get_style_clip_corner(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_CLIP_CORNER); + return (bool)v.num; +} + +static inline lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OPA); + return (lv_opa_t)v.num; +} + +static inline lv_opa_t lv_obj_get_style_opa_layered(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OPA_LAYERED); + return (lv_opa_t)v.num; +} + +static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_DSC); + return (const lv_color_filter_dsc_t *)v.ptr; +} + +static inline lv_opa_t lv_obj_get_style_color_filter_opa(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_OPA); + return (lv_opa_t)v.num; +} + +static inline const lv_anim_t * lv_obj_get_style_anim(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM); + return (const lv_anim_t *)v.ptr; +} + +static inline uint32_t lv_obj_get_style_anim_duration(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM_DURATION); + return (uint32_t)v.num; +} + +static inline const lv_style_transition_dsc_t * lv_obj_get_style_transition(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSITION); + return (const lv_style_transition_dsc_t *)v.ptr; +} + +static inline lv_blend_mode_t lv_obj_get_style_blend_mode(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BLEND_MODE); + return (lv_blend_mode_t)v.num; +} + +static inline uint16_t lv_obj_get_style_layout(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LAYOUT); + return (uint16_t)v.num; +} + +static inline lv_base_dir_t lv_obj_get_style_base_dir(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BASE_DIR); + return (lv_base_dir_t)v.num; +} + +static inline const void * lv_obj_get_style_bitmap_mask_src(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BITMAP_MASK_SRC); + return (const void *)v.ptr; +} + +static inline uint32_t lv_obj_get_style_rotary_sensitivity(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ROTARY_SENSITIVITY); + return (uint32_t)v.num; +} + +#if LV_USE_FLEX +static inline lv_flex_flow_t lv_obj_get_style_flex_flow(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_FLOW); + return (lv_flex_flow_t)v.num; +} + +static inline lv_flex_align_t lv_obj_get_style_flex_main_place(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_MAIN_PLACE); + return (lv_flex_align_t)v.num; +} + +static inline lv_flex_align_t lv_obj_get_style_flex_cross_place(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_CROSS_PLACE); + return (lv_flex_align_t)v.num; +} + +static inline lv_flex_align_t lv_obj_get_style_flex_track_place(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_TRACK_PLACE); + return (lv_flex_align_t)v.num; +} + +static inline uint8_t lv_obj_get_style_flex_grow(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_GROW); + return (uint8_t)v.num; +} + +#endif /*LV_USE_FLEX*/ + +#if LV_USE_GRID +static inline const int32_t * lv_obj_get_style_grid_column_dsc_array(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_COLUMN_DSC_ARRAY); + return (const int32_t *)v.ptr; +} + +static inline lv_grid_align_t lv_obj_get_style_grid_column_align(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_COLUMN_ALIGN); + return (lv_grid_align_t)v.num; +} + +static inline const int32_t * lv_obj_get_style_grid_row_dsc_array(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_ROW_DSC_ARRAY); + return (const int32_t *)v.ptr; +} + +static inline lv_grid_align_t lv_obj_get_style_grid_row_align(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_ROW_ALIGN); + return (lv_grid_align_t)v.num; +} + +static inline int32_t lv_obj_get_style_grid_cell_column_pos(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_COLUMN_POS); + return (int32_t)v.num; +} + +static inline lv_grid_align_t lv_obj_get_style_grid_cell_x_align(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_X_ALIGN); + return (lv_grid_align_t)v.num; +} + +static inline int32_t lv_obj_get_style_grid_cell_column_span(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_COLUMN_SPAN); + return (int32_t)v.num; +} + +static inline int32_t lv_obj_get_style_grid_cell_row_pos(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_ROW_POS); + return (int32_t)v.num; +} + +static inline lv_grid_align_t lv_obj_get_style_grid_cell_y_align(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_Y_ALIGN); + return (lv_grid_align_t)v.num; +} + +static inline int32_t lv_obj_get_style_grid_cell_row_span(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_ROW_SPAN); + return (int32_t)v.num; +} + +#endif /*LV_USE_GRID*/ + +void lv_obj_set_style_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_min_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_max_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_min_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_max_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_length(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_align(lv_obj_t * obj, lv_align_t value, lv_style_selector_t selector); +void lv_obj_set_style_transform_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_transform_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_translate_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_translate_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_transform_scale_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_transform_scale_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_transform_rotation(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_transform_pivot_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_transform_pivot_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_transform_skew_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_transform_skew_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_pad_top(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_pad_bottom(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_pad_left(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_pad_right(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_pad_row(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_pad_column(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_margin_top(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_margin_bottom(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_margin_left(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_margin_right(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_grad_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_grad_dir(lv_obj_t * obj, lv_grad_dir_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_main_stop(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_grad_stop(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_main_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_grad_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_grad(lv_obj_t * obj, const lv_grad_dsc_t * value, lv_style_selector_t selector); +void lv_obj_set_style_bg_image_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector); +void lv_obj_set_style_bg_image_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_image_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_image_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_bg_image_tiled(lv_obj_t * obj, bool value, lv_style_selector_t selector); +void lv_obj_set_style_border_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_border_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_border_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_border_side(lv_obj_t * obj, lv_border_side_t value, lv_style_selector_t selector); +void lv_obj_set_style_border_post(lv_obj_t * obj, bool value, lv_style_selector_t selector); +void lv_obj_set_style_outline_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_outline_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_outline_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_outline_pad(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_shadow_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_shadow_offset_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_shadow_offset_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_shadow_spread(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_shadow_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_shadow_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_image_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_image_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_image_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_line_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_line_dash_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_line_dash_gap(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_line_rounded(lv_obj_t * obj, bool value, lv_style_selector_t selector); +void lv_obj_set_style_line_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_line_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_arc_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_arc_rounded(lv_obj_t * obj, bool value, lv_style_selector_t selector); +void lv_obj_set_style_arc_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_arc_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_arc_image_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector); +void lv_obj_set_style_text_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_text_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_text_font(lv_obj_t * obj, const lv_font_t * value, lv_style_selector_t selector); +void lv_obj_set_style_text_letter_space(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_text_line_space(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_text_decor(lv_obj_t * obj, lv_text_decor_t value, lv_style_selector_t selector); +void lv_obj_set_style_text_align(lv_obj_t * obj, lv_text_align_t value, lv_style_selector_t selector); +void lv_obj_set_style_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_clip_corner(lv_obj_t * obj, bool value, lv_style_selector_t selector); +void lv_obj_set_style_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_opa_layered(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_color_filter_dsc(lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector); +void lv_obj_set_style_color_filter_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_anim(lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector); +void lv_obj_set_style_anim_duration(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector); +void lv_obj_set_style_transition(lv_obj_t * obj, const lv_style_transition_dsc_t * value, lv_style_selector_t selector); +void lv_obj_set_style_blend_mode(lv_obj_t * obj, lv_blend_mode_t value, lv_style_selector_t selector); +void lv_obj_set_style_layout(lv_obj_t * obj, uint16_t value, lv_style_selector_t selector); +void lv_obj_set_style_base_dir(lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector); +void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector); +void lv_obj_set_style_rotary_sensitivity(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector); +#if LV_USE_FLEX +void lv_obj_set_style_flex_flow(lv_obj_t * obj, lv_flex_flow_t value, lv_style_selector_t selector); +void lv_obj_set_style_flex_main_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector); +void lv_obj_set_style_flex_cross_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector); +void lv_obj_set_style_flex_track_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector); +void lv_obj_set_style_flex_grow(lv_obj_t * obj, uint8_t value, lv_style_selector_t selector); +#endif /*LV_USE_FLEX*/ + +#if LV_USE_GRID +void lv_obj_set_style_grid_column_dsc_array(lv_obj_t * obj, const int32_t * value, lv_style_selector_t selector); +void lv_obj_set_style_grid_column_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector); +void lv_obj_set_style_grid_row_dsc_array(lv_obj_t * obj, const int32_t * value, lv_style_selector_t selector); +void lv_obj_set_style_grid_row_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector); +void lv_obj_set_style_grid_cell_column_pos(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_grid_cell_x_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector); +void lv_obj_set_style_grid_cell_column_span(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_grid_cell_row_pos(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_grid_cell_y_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector); +void lv_obj_set_style_grid_cell_row_span(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +#endif /*LV_USE_GRID*/ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_OBJ_STYLE_GEN_H */ diff --git a/test/include/liblvgl/core/lv_obj_style_private.h b/test/include/liblvgl/core/lv_obj_style_private.h new file mode 100644 index 00000000..e6be1279 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_style_private.h @@ -0,0 +1,95 @@ +/** + * @file lv_obj_style_private.h + * + */ + +#ifndef LV_OBJ_STYLE_PRIVATE_H +#define LV_OBJ_STYLE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_style.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_obj_style_t { + const lv_style_t * style; + uint32_t selector : 24; + uint32_t is_local : 1; + uint32_t is_trans : 1; +}; + +struct _lv_obj_style_transition_dsc_t { + uint16_t time; + uint16_t delay; + lv_style_selector_t selector; + lv_style_prop_t prop; + lv_anim_path_cb_t path_cb; + void * user_data; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the object related style manager module. + * Called by LVGL in `lv_init()` + */ +void lv_obj_style_init(void); + +/** + * Deinitialize the object related style manager module. + * Called by LVGL in `lv_deinit()` + */ +void lv_obj_style_deinit(void); + +/** + * Used internally to create a style transition + * @param obj + * @param part + * @param prev_state + * @param new_state + * @param tr + */ +void lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t prev_state, + lv_state_t new_state, const lv_obj_style_transition_dsc_t * tr); + +/** + * Used internally to compare the appearance of an object in 2 states + * @param obj + * @param state1 + * @param state2 + * @return + */ +lv_style_state_cmp_t lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2); + +/** + * Update the layer type of a widget bayed on its current styles. + * The result will be stored in `obj->spec_attr->layer_type` + * @param obj the object whose layer should be updated + */ +void lv_obj_update_layer_type(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_STYLE_PRIVATE_H*/ diff --git a/test/include/liblvgl/core/lv_obj_tree.h b/test/include/liblvgl/core/lv_obj_tree.h new file mode 100644 index 00000000..9f679dd4 --- /dev/null +++ b/test/include/liblvgl/core/lv_obj_tree.h @@ -0,0 +1,237 @@ +/** + * @file lv_obj_tree.h + * + */ + +#ifndef LV_OBJ_TREE_H +#define LV_OBJ_TREE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_types.h" +#include "../misc/lv_anim.h" +#include "../display/lv_display.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_OBJ_TREE_WALK_NEXT, + LV_OBJ_TREE_WALK_SKIP_CHILDREN, + LV_OBJ_TREE_WALK_END, +} lv_obj_tree_walk_res_t; + +typedef lv_obj_tree_walk_res_t (*lv_obj_tree_walk_cb_t)(lv_obj_t *, void *); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Delete an object and all of its children. + * Also remove the objects from their group and remove all animations (if any). + * Send `LV_EVENT_DELETED` to deleted objects. + * @param obj pointer to an object + */ +void lv_obj_delete(lv_obj_t * obj); + +/** + * Delete all children of an object. + * Also remove the objects from their group and remove all animations (if any). + * Send `LV_EVENT_DELETED` to deleted objects. + * @param obj pointer to an object + */ +void lv_obj_clean(lv_obj_t * obj); + +/** + * Delete an object after some delay + * @param obj pointer to an object + * @param delay_ms time to wait before delete in milliseconds + */ +void lv_obj_delete_delayed(lv_obj_t * obj, uint32_t delay_ms); + +/** + * A function to be easily used in animation ready callback to delete an object when the animation is ready + * @param a pointer to the animation + */ +void lv_obj_delete_anim_completed_cb(lv_anim_t * a); + +/** + * Helper function for asynchronously deleting objects. + * Useful for cases where you can't delete an object directly in an `LV_EVENT_DELETE` handler (i.e. parent). + * @param obj object to delete + * @see lv_async_call + */ +void lv_obj_delete_async(lv_obj_t * obj); + +/** + * Move the parent of an object. The relative coordinates will be kept. + * + * @param obj pointer to an object whose parent needs to be changed + * @param parent pointer to the new parent + */ +void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent); + +/** + * Swap the positions of two objects. + * When used in listboxes, it can be used to sort the listbox items. + * @param obj1 pointer to the first object + * @param obj2 pointer to the second object + */ +void lv_obj_swap(lv_obj_t * obj1, lv_obj_t * obj2); + +/** + * moves the object to the given index in its parent. + * When used in listboxes, it can be used to sort the listbox items. + * @param obj pointer to the object to be moved. + * @param index new index in parent. -1 to count from the back + * @note to move to the background: lv_obj_move_to_index(obj, 0) + * @note to move forward (up): lv_obj_move_to_index(obj, lv_obj_get_index(obj) - 1) + */ +void lv_obj_move_to_index(lv_obj_t * obj, int32_t index); + +/** + * Get the screen of an object + * @param obj pointer to an object + * @return pointer to the object's screen + */ +lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj); + +/** + * Get the display of the object + * @param obj pointer to an object + * @return pointer to the object's display + */ +lv_display_t * lv_obj_get_display(const lv_obj_t * obj); + +/** + * Get the parent of an object + * @param obj pointer to an object + * @return the parent of the object. (NULL if `obj` was a screen) + */ +lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj); + +/** + * Get the child of an object by the child's index. + * @param obj pointer to an object whose child should be get + * @param idx the index of the child. + * 0: the oldest (firstly created) child + * 1: the second oldest + * child count-1: the youngest + * -1: the youngest + * -2: the second youngest + * @return pointer to the child or NULL if the index was invalid + */ +lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, int32_t idx); + +/** + * Get the child of an object by the child's index. Consider the children only with a given type. + * @param obj pointer to an object whose child should be get + * @param idx the index of the child. + * 0: the oldest (firstly created) child + * 1: the second oldest + * child count-1: the youngest + * -1: the youngest + * -2: the second youngest + * @param class_p the type of the children to check + * @return pointer to the child or NULL if the index was invalid + */ +lv_obj_t * lv_obj_get_child_by_type(const lv_obj_t * obj, int32_t idx, + const lv_obj_class_t * class_p); + +/** + * Return a sibling of an object + * @param obj pointer to an object whose sibling should be get + * @param idx 0: `obj` itself + * -1: the first older sibling + * -2: the next older sibling + * 1: the first younger sibling + * 2: the next younger sibling + * etc + * @return pointer to the requested sibling or NULL if there is no such sibling + */ +lv_obj_t * lv_obj_get_sibling(const lv_obj_t * obj, int32_t idx); + +/** + * Return a sibling of an object. Consider the siblings only with a given type. + * @param obj pointer to an object whose sibling should be get + * @param idx 0: `obj` itself + * -1: the first older sibling + * -2: the next older sibling + * 1: the first younger sibling + * 2: the next younger sibling + * etc + * @param class_p the type of the children to check + * @return pointer to the requested sibling or NULL if there is no such sibling + */ +lv_obj_t * lv_obj_get_sibling_by_type(const lv_obj_t * obj, int32_t idx, + const lv_obj_class_t * class_p); + +/** + * Get the number of children + * @param obj pointer to an object + * @return the number of children + */ +uint32_t lv_obj_get_child_count(const lv_obj_t * obj); + +/** + * Get the number of children having a given type. + * @param obj pointer to an object + * @param class_p the type of the children to check + * @return the number of children + */ + +uint32_t lv_obj_get_child_count_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p); + +/** + * Get the index of a child. + * @param obj pointer to an object + * @return the child index of the object. + * E.g. 0: the oldest (firstly created child). + * (-1 if child could not be found or no parent exists) + */ +int32_t lv_obj_get_index(const lv_obj_t * obj); + +/** + * Get the index of a child. Consider the children only with a given type. + * @param obj pointer to an object + * @param class_p the type of the children to check + * @return the child index of the object. + * E.g. 0: the oldest (firstly created child with the given class). + * (-1 if child could not be found or no parent exists) + */ +int32_t lv_obj_get_index_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p); + +/** + * Iterate through all children of any object. + * @param start_obj start integrating from this object + * @param cb call this callback on the objects + * @param user_data pointer to any user related data (will be passed to `cb`) + */ +void lv_obj_tree_walk(lv_obj_t * start_obj, lv_obj_tree_walk_cb_t cb, void * user_data); + +/** + * Iterate through all children of any object and print their ID. + * @param start_obj start integrating from this object + */ +void lv_obj_dump_tree(lv_obj_t * start_obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_TREE_H*/ diff --git a/test/include/liblvgl/core/lv_refr.h b/test/include/liblvgl/core/lv_refr.h new file mode 100644 index 00000000..6b756edb --- /dev/null +++ b/test/include/liblvgl/core/lv_refr.h @@ -0,0 +1,68 @@ +/** + * @file lv_refr.h + * + */ + +#ifndef LV_REFR_H +#define LV_REFR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_obj.h" +#include "../display/lv_display.h" +#include "../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Redraw the invalidated areas now. + * Normally the redrawing is periodically executed in `lv_timer_handler` but a long blocking process + * can prevent the call of `lv_timer_handler`. In this case if the GUI is updated in the process + * (e.g. progress bar) this function can be called when the screen should be updated. + * @param disp pointer to display to refresh. NULL to refresh all displays. + */ +void lv_refr_now(lv_display_t * disp); + +/** + * Redrawn on object and all its children using the passed draw context + * @param layer pointer to a layer where to draw. + * @param obj the start object from the redraw should start + */ +void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj); + +/********************** + * STATIC FUNCTIONS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_REFR_H*/ diff --git a/test/include/liblvgl/core/lv_refr_private.h b/test/include/liblvgl/core/lv_refr_private.h new file mode 100644 index 00000000..8f840780 --- /dev/null +++ b/test/include/liblvgl/core/lv_refr_private.h @@ -0,0 +1,75 @@ +/** + * @file lv_refr_private.h + * + */ + +#ifndef LV_REFR_PRIVATE_H +#define LV_REFR_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_refr.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the screen refresh subsystem + */ +void lv_refr_init(void); + +/** + * Deinitialize the screen refresh subsystem + */ +void lv_refr_deinit(void); + +/** + * Invalidate an area on display to redraw it + * @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas) + * @param disp pointer to display where the area should be invalidated (NULL can be used if there is + * only one display) + */ +void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p); + +/** + * Get the display which is being refreshed + * @return the display being refreshed + */ +lv_display_t * lv_refr_get_disp_refreshing(void); + +/** + * Set the display which is being refreshed + * @param disp the display being refreshed + */ +void lv_refr_set_disp_refreshing(lv_display_t * disp); + +/** + * Called periodically to handle the refreshing + * @param timer pointer to the timer itself + */ +void lv_display_refr_timer(lv_timer_t * timer); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_REFR_PRIVATE_H*/ diff --git a/test/include/liblvgl/display/lv_display.h b/test/include/liblvgl/display/lv_display.h new file mode 100644 index 00000000..2887ab69 --- /dev/null +++ b/test/include/liblvgl/display/lv_display.h @@ -0,0 +1,629 @@ +/** + * @file lv_display.h + * + */ + +#ifndef LV_DISPLAY_H +#define LV_DISPLAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_types.h" +#include "../misc/lv_timer.h" +#include "../misc/lv_event.h" +#include "../misc/lv_color.h" +#include "../draw/lv_draw.h" + +/********************* + * DEFINES + *********************/ + +#ifndef LV_ATTRIBUTE_FLUSH_READY +#define LV_ATTRIBUTE_FLUSH_READY +#endif + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_DISPLAY_ROTATION_0 = 0, + LV_DISPLAY_ROTATION_90, + LV_DISPLAY_ROTATION_180, + LV_DISPLAY_ROTATION_270 +} lv_display_rotation_t; + +typedef enum { + /** + * Use the buffer(s) to render the screen is smaller parts. + * This way the buffers can be smaller then the display to save RAM. At least 1/10 screen size buffer(s) are recommended. + */ + LV_DISPLAY_RENDER_MODE_PARTIAL, + + /** + * The buffer(s) has to be screen sized and LVGL will render into the correct location of the buffer. + * This way the buffer always contain the whole image. Only the changed ares will be updated. + * With 2 buffers the buffers' content are kept in sync automatically and in flush_cb only address change is required. + */ + LV_DISPLAY_RENDER_MODE_DIRECT, + + /** + * Always redraw the whole screen even if only one pixel has been changed. + * With 2 buffers in flush_cb only and address change is required. + */ + LV_DISPLAY_RENDER_MODE_FULL, +} lv_display_render_mode_t; + +typedef enum { + LV_SCR_LOAD_ANIM_NONE, + LV_SCR_LOAD_ANIM_OVER_LEFT, + LV_SCR_LOAD_ANIM_OVER_RIGHT, + LV_SCR_LOAD_ANIM_OVER_TOP, + LV_SCR_LOAD_ANIM_OVER_BOTTOM, + LV_SCR_LOAD_ANIM_MOVE_LEFT, + LV_SCR_LOAD_ANIM_MOVE_RIGHT, + LV_SCR_LOAD_ANIM_MOVE_TOP, + LV_SCR_LOAD_ANIM_MOVE_BOTTOM, + LV_SCR_LOAD_ANIM_FADE_IN, + LV_SCR_LOAD_ANIM_FADE_ON = LV_SCR_LOAD_ANIM_FADE_IN, /*For backward compatibility*/ + LV_SCR_LOAD_ANIM_FADE_OUT, + LV_SCR_LOAD_ANIM_OUT_LEFT, + LV_SCR_LOAD_ANIM_OUT_RIGHT, + LV_SCR_LOAD_ANIM_OUT_TOP, + LV_SCR_LOAD_ANIM_OUT_BOTTOM, +} lv_screen_load_anim_t; + +typedef void (*lv_display_flush_cb_t)(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +typedef void (*lv_display_flush_wait_cb_t)(lv_display_t * disp); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a new display with the given resolution + * @param hor_res horizontal resolution in pixels + * @param ver_res vertical resolution in pixels + * @return pointer to a display object or `NULL` on error + */ +lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res); + +/** + * Remove a display + * @param disp pointer to display + */ +void lv_display_delete(lv_display_t * disp); + +/** + * Set a default display. The new screens will be created on it by default. + * @param disp pointer to a display + */ +void lv_display_set_default(lv_display_t * disp); + +/** + * Get the default display + * @return pointer to the default display + */ +lv_display_t * lv_display_get_default(void); + +/** + * Get the next display. + * @param disp pointer to the current display. NULL to initialize. + * @return the next display or NULL if no more. Gives the first display when the parameter is NULL. + */ +lv_display_t * lv_display_get_next(lv_display_t * disp); + +/*--------------------- + * RESOLUTION + *--------------------*/ + +/** + * Sets the resolution of a display. `LV_EVENT_RESOLUTION_CHANGED` event will be sent. + * Here the native resolution of the device should be set. If the display will be rotated later with + * `lv_display_set_rotation` LVGL will swap the hor. and ver. resolution automatically. + * @param disp pointer to a display + * @param hor_res the new horizontal resolution + * @param ver_res the new vertical resolution + */ +void lv_display_set_resolution(lv_display_t * disp, int32_t hor_res, int32_t ver_res); + +/** + * It's not mandatory to use the whole display for LVGL, however in some cases physical resolution is important. + * For example the touchpad still sees whole resolution and the values needs to be converted + * to the active LVGL display area. + * @param disp pointer to a display + * @param hor_res the new physical horizontal resolution, or -1 to assume it's the same as the normal hor. res. + * @param ver_res the new physical vertical resolution, or -1 to assume it's the same as the normal hor. res. + */ +void lv_display_set_physical_resolution(lv_display_t * disp, int32_t hor_res, int32_t ver_res); + +/** + * If physical resolution is not the same as the normal resolution + * the offset of the active display area can be set here. + * @param disp pointer to a display + * @param x X offset + * @param y Y offset + */ +void lv_display_set_offset(lv_display_t * disp, int32_t x, int32_t y); + +/** + * Set the rotation of this display. LVGL will swap the horizontal and vertical resolutions internally. + * @param disp pointer to a display (NULL to use the default display) + * @param rotation `LV_DISPLAY_ROTATION_0/90/180/270` + */ +void lv_display_set_rotation(lv_display_t * disp, lv_display_rotation_t rotation); + +/** + * Set the DPI (dot per inch) of the display. + * dpi = sqrt(hor_res^2 + ver_res^2) / diagonal" + * @param disp pointer to a display + * @param dpi the new DPI + */ +void lv_display_set_dpi(lv_display_t * disp, int32_t dpi); + +/** + * Get the horizontal resolution of a display. + * @param disp pointer to a display (NULL to use the default display) + * @return the horizontal resolution of the display. + */ +int32_t lv_display_get_horizontal_resolution(const lv_display_t * disp); + +/** + * Get the vertical resolution of a display + * @param disp pointer to a display (NULL to use the default display) + * @return the vertical resolution of the display + */ +int32_t lv_display_get_vertical_resolution(const lv_display_t * disp); + +/** + * Get the physical horizontal resolution of a display + * @param disp pointer to a display (NULL to use the default display) + * @return the physical horizontal resolution of the display + */ +int32_t lv_display_get_physical_horizontal_resolution(const lv_display_t * disp); + +/** + * Get the physical vertical resolution of a display + * @param disp pointer to a display (NULL to use the default display) + * @return the physical vertical resolution of the display + */ +int32_t lv_display_get_physical_vertical_resolution(const lv_display_t * disp); + +/** + * Get the horizontal offset from the full / physical display + * @param disp pointer to a display (NULL to use the default display) + * @return the horizontal offset from the physical display + */ +int32_t lv_display_get_offset_x(const lv_display_t * disp); + +/** + * Get the vertical offset from the full / physical display + * @param disp pointer to a display (NULL to use the default display) + * @return the horizontal offset from the physical display + */ +int32_t lv_display_get_offset_y(const lv_display_t * disp); + +/** + * Get the current rotation of this display. + * @param disp pointer to a display (NULL to use the default display) + * @return the current rotation + */ +lv_display_rotation_t lv_display_get_rotation(lv_display_t * disp); + +/** + * Get the DPI of the display + * @param disp pointer to a display (NULL to use the default display) + * @return dpi of the display + */ +int32_t lv_display_get_dpi(const lv_display_t * disp); + +/*--------------------- + * BUFFERING + *--------------------*/ + +/** + * Set the buffers for a display, similarly to `lv_display_set_draw_buffers`, but accept the raw buffer pointers. + * For DIRECT/FULL rending modes, the buffer size must be at least + * `hor_res * ver_res * lv_color_format_get_size(lv_display_get_color_format(disp))` + * @param disp pointer to a display + * @param buf1 first buffer + * @param buf2 second buffer (can be `NULL`) + * @param buf_size buffer size in byte + * @param render_mode LV_DISPLAY_RENDER_MODE_PARTIAL/DIRECT/FULL + */ +void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, + lv_display_render_mode_t render_mode); + +/** + * Set the frame buffers for a display, similarly to `lv_display_set_buffers`, but allow + * for a custom stride as required by a display controller. + * This allows the frame buffers to have a stride alignment different from the rest of + * the buffers` + * @param disp pointer to a display + * @param buf1 first buffer + * @param buf2 second buffer (can be `NULL`) + * @param buf_size buffer size in byte + * @param stride buffer stride in bytes + * @param render_mode LV_DISPLAY_RENDER_MODE_PARTIAL/DIRECT/FULL + */ +void lv_display_set_buffers_with_stride(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, + uint32_t stride, lv_display_render_mode_t render_mode); + +/** + * Set the buffers for a display, accept a draw buffer pointer. + * Normally use `lv_display_set_buffers` is enough for most cases. + * Use this function when an existing lv_draw_buf_t is available. + * @param disp pointer to a display + * @param buf1 first buffer + * @param buf2 second buffer (can be `NULL`) + */ +void lv_display_set_draw_buffers(lv_display_t * disp, lv_draw_buf_t * buf1, lv_draw_buf_t * buf2); + +/** + * Set display render mode + * @param disp pointer to a display + * @param render_mode LV_DISPLAY_RENDER_MODE_PARTIAL/DIRECT/FULL + */ +void lv_display_set_render_mode(lv_display_t * disp, lv_display_render_mode_t render_mode); + +/** + * Set the flush callback which will be called to copy the rendered image to the display. + * @param disp pointer to a display + * @param flush_cb the flush callback (`px_map` contains the rendered image as raw pixel map and it should be copied to `area` on the display) + */ +void lv_display_set_flush_cb(lv_display_t * disp, lv_display_flush_cb_t flush_cb); + +/** + * Set a callback to be used while LVGL is waiting flushing to be finished. + * It can do any complex logic to wait, including semaphores, mutexes, polling flags, etc. + * If not set the `disp->flushing` flag is used which can be cleared with `lv_display_flush_ready()` + * @param disp pointer to a display + * @param wait_cb a callback to call while LVGL is waiting for flush ready. + * If NULL `lv_display_flush_ready()` can be used to signal that flushing is ready. + */ +void lv_display_set_flush_wait_cb(lv_display_t * disp, lv_display_flush_wait_cb_t wait_cb); + +/** + * Set the color format of the display. + * @param disp pointer to a display + * @param color_format Possible values are + * - LV_COLOR_FORMAT_RGB565 + * - LV_COLOR_FORMAT_RGB888 + * - LV_COLOR_FORMAT_XRGB888 + * - LV_COLOR_FORMAT_ARGB888 + *@note To change the endianness of the rendered image in case of RGB565 format + * (i.e. swap the 2 bytes) call `lv_draw_sw_rgb565_swap` in the flush_cb + */ +void lv_display_set_color_format(lv_display_t * disp, lv_color_format_t color_format); + +/** + * Get the color format of the display + * @param disp pointer to a display + * @return the color format + */ +lv_color_format_t lv_display_get_color_format(lv_display_t * disp); + +/** + * Set the number of tiles for parallel rendering. + * @param disp pointer to a display + * @param tile_cnt number of tiles (1 =< tile_cnt < 256) + */ +void lv_display_set_tile_cnt(lv_display_t * disp, uint32_t tile_cnt); + +/** + * Get the number of tiles used for parallel rendering + * @param disp pointer to a display + * @return number of tiles + */ +uint32_t lv_display_get_tile_cnt(lv_display_t * disp); + +/** + * Enable anti-aliasing for the render engine + * @param disp pointer to a display + * @param en true/false + */ +void lv_display_set_antialiasing(lv_display_t * disp, bool en); + +/** + * Get if anti-aliasing is enabled for a display or not + * @param disp pointer to a display (NULL to use the default display) + * @return true/false + */ +bool lv_display_get_antialiasing(lv_display_t * disp); + +//! @cond Doxygen_Suppress + +/** + * Call from the display driver when the flushing is finished + * @param disp pointer to display whose `flush_cb` was called + */ +LV_ATTRIBUTE_FLUSH_READY void lv_display_flush_ready(lv_display_t * disp); + +/** + * Tell if it's the last area of the refreshing process. + * Can be called from `flush_cb` to execute some special display refreshing if needed when all areas area flushed. + * @param disp pointer to display + * @return true: it's the last area to flush; + * false: there are other areas too which will be refreshed soon + */ +LV_ATTRIBUTE_FLUSH_READY bool lv_display_flush_is_last(lv_display_t * disp); + +//! @endcond + +bool lv_display_is_double_buffered(lv_display_t * disp); + +/*--------------------- + * SCREENS + *--------------------*/ + +/** + * Return a pointer to the active screen on a display + * @param disp pointer to display which active screen should be get. + * (NULL to use the default screen) + * @return pointer to the active screen object (loaded by 'lv_screen_load()') + */ +lv_obj_t * lv_display_get_screen_active(lv_display_t * disp); + +/** + * Return with a pointer to the previous screen. Only used during screen transitions. + * @param disp pointer to display which previous screen should be get. + * (NULL to use the default screen) + * @return pointer to the previous screen object or NULL if not used now + */ +lv_obj_t * lv_display_get_screen_prev(lv_display_t * disp); + +/** + * Return the top layer. The top layer is the same on all screens and it is above the normal screen layer. + * @param disp pointer to display which top layer should be get. (NULL to use the default screen) + * @return pointer to the top layer object + */ +lv_obj_t * lv_display_get_layer_top(lv_display_t * disp); + +/** + * Return the sys. layer. The system layer is the same on all screen and it is above the normal screen and the top layer. + * @param disp pointer to display which sys. layer should be retrieved. (NULL to use the default screen) + * @return pointer to the sys layer object + */ +lv_obj_t * lv_display_get_layer_sys(lv_display_t * disp); + +/** + * Return the bottom layer. The bottom layer is the same on all screen and it is under the normal screen layer. + * It's visible only if the screen is transparent. + * @param disp pointer to display (NULL to use the default screen) + * @return pointer to the bottom layer object + */ +lv_obj_t * lv_display_get_layer_bottom(lv_display_t * disp); + +/** + * Load a screen on the default display + * @param scr pointer to a screen + */ +void lv_screen_load(struct _lv_obj_t * scr); + +/** + * Switch screen with animation + * @param scr pointer to the new screen to load + * @param anim_type type of the animation from `lv_screen_load_anim_t`, e.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT` + * @param time time of the animation + * @param delay delay before the transition + * @param auto_del true: automatically delete the old screen + */ +void lv_screen_load_anim(lv_obj_t * scr, lv_screen_load_anim_t anim_type, uint32_t time, uint32_t delay, + bool auto_del); + +/** + * Get the active screen of the default display + * @return pointer to the active screen + */ +lv_obj_t * lv_screen_active(void); + +/** + * Get the top layer of the default display + * @return pointer to the top layer + */ +lv_obj_t * lv_layer_top(void); + +/** + * Get the system layer of the default display + * @return pointer to the sys layer + */ +lv_obj_t * lv_layer_sys(void); + +/** + * Get the bottom layer of the default display + * @return pointer to the bottom layer + */ +lv_obj_t * lv_layer_bottom(void); + +/*--------------------- + * OTHERS + *--------------------*/ + +/** + * Add an event handler to the display + * @param disp pointer to a display + * @param event_cb an event callback + * @param filter event code to react or `LV_EVENT_ALL` + * @param user_data optional user_data + */ +void lv_display_add_event_cb(lv_display_t * disp, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data); + +/** + * Get the number of event attached to a display + * @param disp pointer to a display + * @return number of events + */ +uint32_t lv_display_get_event_count(lv_display_t * disp); + +/** + * Get an event descriptor for an event + * @param disp pointer to a display + * @param index the index of the event + * @return the event descriptor + */ +lv_event_dsc_t * lv_display_get_event_dsc(lv_display_t * disp, uint32_t index); + +/** + * Remove an event + * @param disp pointer to a display + * @param index the index of the event to remove + * @return true: and event was removed; false: no event was removed + */ +bool lv_display_delete_event(lv_display_t * disp, uint32_t index); + +/** + * Remove an event_cb with user_data + * @param disp pointer to a display + * @param event_cb the event_cb of the event to remove + * @param user_data user_data + * @return the count of the event removed + */ +uint32_t lv_display_remove_event_cb_with_user_data(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data); + +/** + * Send an event to a display + * @param disp pointer to a display + * @param code an event code. LV_EVENT_... + * @param param optional param + * @return LV_RESULT_OK: disp wasn't deleted in the event. + */ +lv_result_t lv_display_send_event(lv_display_t * disp, lv_event_code_t code, void * param); + +/** + * Get the area to be invalidated. Can be used in `LV_EVENT_INVALIDATE_AREA` + * @param e pointer to an event + * @return the area to invalidated (can be modified as required) + */ +lv_area_t * lv_event_get_invalidated_area(lv_event_t * e); + +/** + * Set the theme of a display. If there are no user created widgets yet the screens' theme will be updated + * @param disp pointer to a display + * @param th pointer to a theme + */ +void lv_display_set_theme(lv_display_t * disp, lv_theme_t * th); + +/** + * Get the theme of a display + * @param disp pointer to a display + * @return the display's theme (can be NULL) + */ +lv_theme_t * lv_display_get_theme(lv_display_t * disp); + +/** + * Get elapsed time since last user activity on a display (e.g. click) + * @param disp pointer to a display (NULL to get the overall smallest inactivity) + * @return elapsed ticks (milliseconds) since the last activity + */ +uint32_t lv_display_get_inactive_time(const lv_display_t * disp); + +/** + * Manually trigger an activity on a display + * @param disp pointer to a display (NULL to use the default display) + */ +void lv_display_trigger_activity(lv_display_t * disp); + +/** + * Temporarily enable and disable the invalidation of the display. + * @param disp pointer to a display (NULL to use the default display) + * @param en true: enable invalidation; false: invalidation + */ +void lv_display_enable_invalidation(lv_display_t * disp, bool en); + +/** + * Get display invalidation is enabled. + * @param disp pointer to a display (NULL to use the default display) + * @return return true if invalidation is enabled + */ +bool lv_display_is_invalidation_enabled(lv_display_t * disp); + +/** + * Get a pointer to the screen refresher timer to + * modify its parameters with `lv_timer_...` functions. + * @param disp pointer to a display + * @return pointer to the display refresher timer. (NULL on error) + */ +lv_timer_t * lv_display_get_refr_timer(lv_display_t * disp); + +/** + * Delete screen refresher timer + * @param disp pointer to a display + */ +void lv_display_delete_refr_timer(lv_display_t * disp); + +void lv_display_set_user_data(lv_display_t * disp, void * user_data); +void lv_display_set_driver_data(lv_display_t * disp, void * driver_data); +void * lv_display_get_user_data(lv_display_t * disp); +void * lv_display_get_driver_data(lv_display_t * disp); +lv_draw_buf_t * lv_display_get_buf_active(lv_display_t * disp); + +/** + * Rotate an area in-place according to the display's rotation + * @param disp pointer to a display + * @param area pointer to an area to rotate + */ +void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area); + +/********************** + * MACROS + **********************/ + +/*------------------------------------------------ + * To improve backward compatibility + * Recommended only if you have one display + *------------------------------------------------*/ + +#ifndef LV_HOR_RES +/** + * The horizontal resolution of the currently active display. + */ +#define LV_HOR_RES lv_display_get_horizontal_resolution(lv_display_get_default()) +#endif + +#ifndef LV_VER_RES +/** + * The vertical resolution of the currently active display. + */ +#define LV_VER_RES lv_display_get_vertical_resolution(lv_display_get_default()) +#endif + +/** + * Same as Android's DIP. (Different name is chosen to avoid mistype between LV_DPI and LV_DIP) + * 1 dip is 1 px on a 160 DPI screen + * 1 dip is 2 px on a 320 DPI screen + * https://stackoverflow.com/questions/2025282/what-is-the-difference-between-px-dip-dp-and-sp + */ +#define LV_DPX_CALC(dpi, n) ((n) == 0 ? 0 :LV_MAX((( (dpi) * (n) + 80) / 160), 1)) /*+80 for rounding*/ +#define LV_DPX(n) LV_DPX_CALC(lv_display_get_dpi(NULL), n) + +/** + * Scale the given number of pixels (a distance or size) relative to a 160 DPI display + * considering the DPI of the default display. + * It ensures that e.g. `lv_dpx(100)` will have the same physical size regardless to the + * DPI of the display. + * @param n the number of pixels to scale + * @return `n x current_dpi/160` + */ +int32_t lv_dpx(int32_t n); + +/** + * Scale the given number of pixels (a distance or size) relative to a 160 DPI display + * considering the DPI of the given display. + * It ensures that e.g. `lv_dpx(100)` will have the same physical size regardless to the + * DPI of the display. + * @param disp a display whose dpi should be considered + * @param n the number of pixels to scale + * @return `n x current_dpi/160` + */ +int32_t lv_display_dpx(const lv_display_t * disp, int32_t n); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DISPLAY_H*/ diff --git a/test/include/liblvgl/display/lv_display_private.h b/test/include/liblvgl/display/lv_display_private.h new file mode 100644 index 00000000..d831ec48 --- /dev/null +++ b/test/include/liblvgl/display/lv_display_private.h @@ -0,0 +1,183 @@ +/** + * @file lv_display_private.h + * + */ + +#ifndef LV_DISPLAY_PRIVATE_H +#define LV_DISPLAY_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_types.h" +#include "../core/lv_obj.h" +#include "../draw/lv_draw.h" +#include "lv_display.h" + +#if LV_USE_SYSMON +#include "../others/sysmon/lv_sysmon_private.h" +#endif + +/********************* + * DEFINES + *********************/ +#ifndef LV_INV_BUF_SIZE +#define LV_INV_BUF_SIZE 32 /**< Buffer size for invalid areas */ +#endif + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_display_t { + + /*--------------------- + * Resolution + *--------------------*/ + + /** Horizontal resolution.*/ + int32_t hor_res; + + /** Vertical resolution.*/ + int32_t ver_res; + + /** Horizontal resolution of the full / physical display. Set to -1 for fullscreen mode.*/ + int32_t physical_hor_res; + + /** Vertical resolution of the full / physical display. Set to -1 for fullscreen mode.*/ + int32_t physical_ver_res; + + /** Horizontal offset from the full / physical display. Set to 0 for fullscreen mode.*/ + int32_t offset_x; + + /** Vertical offset from the full / physical display. Set to 0 for fullscreen mode.*/ + int32_t offset_y; + + /** DPI (dot per inch) of the display. Default value is `LV_DPI_DEF`.*/ + uint32_t dpi; + + /*--------------------- + * Buffering + *--------------------*/ + lv_draw_buf_t * buf_1; + lv_draw_buf_t * buf_2; + + /** Internal, used by the library*/ + lv_draw_buf_t * buf_act; + + /** MANDATORY: Write the internal buffer (draw_buf) to the display. 'lv_display_flush_ready()' has to be + * called when finished*/ + lv_display_flush_cb_t flush_cb; + + /** + * Used to wait while flushing is ready. + * It can do any complex logic to wait, including semaphores, mutexes, polling flags, etc. + * If not set `flushing` flag is used which can be cleared with `lv_display_flush_ready()` */ + lv_display_flush_wait_cb_t flush_wait_cb; + + /** 1: flushing is in progress. (It can't be a bit field because when it's cleared from IRQ + * Read-Modify-Write issue might occur) */ + volatile int flushing; + + /** 1: It was the last chunk to flush. (It can't be a bit field because when it's cleared + * from IRQ Read-Modify-Write issue might occur) */ + volatile int flushing_last; + volatile uint32_t last_area : 1; /**< 1: last area is being rendered */ + volatile uint32_t last_part : 1; /**< 1: last part of the current area is being rendered */ + + lv_display_render_mode_t render_mode; + uint32_t antialiasing : 1; /**< 1: anti-aliasing is enabled on this display.*/ + uint32_t tile_cnt : 8; /**< Divide the display buffer into these number of tiles */ + + + /** 1: The current screen rendering is in progress*/ + uint32_t rendering_in_progress : 1; + + lv_color_format_t color_format; + + /** Invalidated (marked to redraw) areas*/ + lv_area_t inv_areas[LV_INV_BUF_SIZE]; + uint8_t inv_area_joined[LV_INV_BUF_SIZE]; + uint32_t inv_p; + int32_t inv_en_cnt; + + /** Double buffer sync areas (redrawn during last refresh) */ + lv_ll_t sync_areas; + + lv_draw_buf_t _static_buf1; /**< Used when user pass in a raw buffer as display draw buffer */ + lv_draw_buf_t _static_buf2; + /*--------------------- + * Layer + *--------------------*/ + lv_layer_t * layer_head; + void (*layer_init)(lv_display_t * disp, lv_layer_t * layer); + void (*layer_deinit)(lv_display_t * disp, lv_layer_t * layer); + + /*--------------------- + * Screens + *--------------------*/ + + /** Screens of the display*/ + lv_obj_t ** screens; /**< Array of screen objects.*/ + lv_obj_t * sys_layer; /**< @see lv_display_get_layer_sys*/ + lv_obj_t * top_layer; /**< @see lv_display_get_layer_top*/ + lv_obj_t * act_scr; /**< Currently active screen on this display*/ + lv_obj_t * bottom_layer;/**< @see lv_display_get_layer_bottom*/ + lv_obj_t * prev_scr; /**< Previous screen. Used during screen animations*/ + lv_obj_t * scr_to_load; /**< The screen prepared to load in lv_screen_load_anim*/ + uint32_t screen_cnt; + uint8_t draw_prev_over_act : 1;/** 1: Draw previous screen over active screen*/ + uint8_t del_prev : 1; /** 1: Automatically delete the previous screen when the screen load animation is ready*/ + + /*--------------------- + * Others + *--------------------*/ + + void * driver_data; /**< Custom user data*/ + + void * user_data; /**< Custom user data*/ + + lv_event_list_t event_list; + + uint32_t rotation : 3; /**< Element of lv_display_rotation_t*/ + + lv_theme_t * theme; /**< The theme assigned to the screen*/ + + /** A timer which periodically checks the dirty areas and refreshes them*/ + lv_timer_t * refr_timer; + + /*Miscellaneous data*/ + uint32_t last_activity_time; /**< Last time when there was activity on this display*/ + + /** The area being refreshed*/ + lv_area_t refreshed_area; + +#if LV_USE_PERF_MONITOR + lv_obj_t * perf_label; + lv_sysmon_backend_data_t perf_sysmon_backend; + lv_sysmon_perf_info_t perf_sysmon_info; +#endif + +#if LV_USE_MEM_MONITOR + lv_obj_t * mem_label; +#endif + +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DISPLAY_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/dma2d/lv_draw_dma2d.h b/test/include/liblvgl/draw/dma2d/lv_draw_dma2d.h new file mode 100644 index 00000000..af175f1f --- /dev/null +++ b/test/include/liblvgl/draw/dma2d/lv_draw_dma2d.h @@ -0,0 +1,49 @@ +/** + * @file lv_draw_dma2d.h + * + */ + +#ifndef LV_DRAW_DMA2D_H +#define LV_DRAW_DMA2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_DMA2D + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_dma2d_init(void); +void lv_draw_dma2d_deinit(void); + +#if LV_USE_DRAW_DMA2D_INTERRUPT +void lv_draw_dma2d_transfer_complete_interrupt_handler(void); +#endif + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_DMA2D*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_DMA2D_H*/ diff --git a/test/include/liblvgl/draw/dma2d/lv_draw_dma2d_private.h b/test/include/liblvgl/draw/dma2d/lv_draw_dma2d_private.h new file mode 100644 index 00000000..051d02c1 --- /dev/null +++ b/test/include/liblvgl/draw/dma2d/lv_draw_dma2d_private.h @@ -0,0 +1,155 @@ +/** + * @file lv_draw_dma2d_private.h + * + */ + +#ifndef LV_DRAW_DMA2D_PRIVATE_H +#define LV_DRAW_DMA2D_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_dma2d.h" +#if LV_USE_DRAW_DMA2D + +#include "../lv_draw_private.h" +#include LV_DRAW_DMA2D_HAL_INCLUDE + +/********************* + * DEFINES + *********************/ + +#if LV_USE_DRAW_DMA2D_INTERRUPT && LV_USE_OS +#define LV_DRAW_DMA2D_ASYNC 1 +#else +#define LV_DRAW_DMA2D_ASYNC 0 +#endif + +#if defined(__CORTEX_M) && (__CORTEX_M == 7) +#define LV_DRAW_DMA2D_CACHE 1 +#else +#define LV_DRAW_DMA2D_CACHE 0 +#endif + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_DRAW_DMA2D_OUTPUT_CF_ARGB8888 = 0, + LV_DRAW_DMA2D_OUTPUT_CF_RGB888, + LV_DRAW_DMA2D_OUTPUT_CF_RGB565, + LV_DRAW_DMA2D_OUTPUT_CF_ARGB1555, + LV_DRAW_DMA2D_OUTPUT_CF_ARGB4444 +} lv_draw_dma2d_output_cf_t; + +typedef enum { + LV_DRAW_DMA2D_FGBG_CF_ARGB8888 = 0, + LV_DRAW_DMA2D_FGBG_CF_RGB888, + LV_DRAW_DMA2D_FGBG_CF_RGB565, + LV_DRAW_DMA2D_FGBG_CF_ARGB1555, + LV_DRAW_DMA2D_FGBG_CF_ARGB4444, + LV_DRAW_DMA2D_FGBG_CF_L8, + LV_DRAW_DMA2D_FGBG_CF_AL44, + LV_DRAW_DMA2D_FGBG_CF_AL88, + LV_DRAW_DMA2D_FGBG_CF_L4, + LV_DRAW_DMA2D_FGBG_CF_A8, + LV_DRAW_DMA2D_FGBG_CF_A4, + LV_DRAW_DMA2D_FGBG_CF_YCBCR +} lv_draw_dma2d_fgbg_cf_t; + +typedef enum { + LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY = 0, + LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_PFC, + LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING, + LV_DRAW_DMA2D_MODE_REGISTER_TO_MEMORY, + LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING_AND_FIXED_COLOR_FG, + LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING_AND_FIXED_COLOR_BG +} lv_draw_dma2d_mode_t; + +typedef enum { + LV_DRAW_DMA2D_ALPHA_MODE_NO_MODIFY_IMAGE_ALPHA_CHANNEL = 0, + LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL, + LV_DRAW_DMA2D_ALPHA_MODE_MULTIPLY_IMAGE_ALPHA_CHANNEL +} lv_draw_dma2d_alpha_mode_t; + +typedef struct { + lv_draw_dma2d_mode_t mode; + uint32_t w; + uint32_t h; + + void * output_address; + uint32_t output_offset; + lv_draw_dma2d_output_cf_t output_cf; + + uint32_t reg_to_mem_mode_color; + + const void * fg_address; + uint32_t fg_offset; + lv_draw_dma2d_fgbg_cf_t fg_cf; + uint32_t fg_color; + uint32_t fg_alpha_mode; + uint32_t fg_alpha; + + const void * bg_address; + uint32_t bg_offset; + lv_draw_dma2d_fgbg_cf_t bg_cf; + uint32_t bg_color; + uint32_t bg_alpha_mode; + uint32_t bg_alpha; + +} lv_draw_dma2d_configuration_t; + +typedef struct { + const void * first_byte; + uint32_t width_bytes; + uint32_t height; + uint32_t stride; +} lv_draw_dma2d_cache_area_t; + +typedef struct { + lv_draw_unit_t base_unit; + lv_draw_task_t * volatile task_act; +#if LV_DRAW_DMA2D_CACHE + lv_draw_dma2d_cache_area_t writing_area; +#endif +#if LV_DRAW_DMA2D_ASYNC + lv_thread_t thread; + lv_thread_sync_t interrupt_signal; +#endif +} lv_draw_dma2d_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_dma2d_opaque_fill(lv_draw_dma2d_unit_t * u, void * first_pixel, int32_t w, int32_t h, int32_t stride); +void lv_draw_dma2d_fill(lv_draw_dma2d_unit_t * u, void * first_pixel, int32_t w, int32_t h, int32_t stride); +void lv_draw_dma2d_opaque_image(lv_draw_dma2d_unit_t * u, void * dest_first_pixel, lv_area_t * clipped_coords, + int32_t dest_stride); +void lv_draw_dma2d_image(lv_draw_dma2d_unit_t * u, void * dest_first_pixel, lv_area_t * clipped_coords, + int32_t dest_stride); +lv_draw_dma2d_output_cf_t lv_draw_dma2d_cf_to_dma2d_output_cf(lv_color_format_t cf); +uint32_t lv_draw_dma2d_color_to_dma2d_ocolr(lv_draw_dma2d_output_cf_t cf, lv_color_t color); +void lv_draw_dma2d_configure_and_start_transfer(const lv_draw_dma2d_configuration_t * conf); +#if LV_DRAW_DMA2D_CACHE +void lv_draw_dma2d_invalidate_cache(const lv_draw_dma2d_cache_area_t * mem_area); +void lv_draw_dma2d_clean_cache(const lv_draw_dma2d_cache_area_t * mem_area); +#endif + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_DMA2D*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_DMA2D_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw.h b/test/include/liblvgl/draw/lv_draw.h new file mode 100644 index 00000000..6f69f69d --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw.h @@ -0,0 +1,283 @@ +/** + * @file lv_draw.h + * + */ + +/** + * Modified by NXP in 2024 + */ + +#ifndef LV_DRAW_H +#define LV_DRAW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include "../misc/lv_types.h" +#include "../misc/lv_style.h" +#include "../misc/lv_text.h" +#include "../misc/lv_profiler.h" +#include "../misc/lv_matrix.h" +#include "lv_image_decoder.h" +#include "../osal/lv_os.h" +#include "lv_draw_buf.h" + +/********************* + * DEFINES + *********************/ +#define LV_DRAW_UNIT_NONE 0 +#define LV_DRAW_UNIT_IDLE -1 /**< The draw unit is idle, new dispatching might be requested to try again */ + +#if LV_DRAW_TRANSFORM_USE_MATRIX +#if !LV_USE_MATRIX +#error "LV_DRAW_TRANSFORM_USE_MATRIX requires LV_USE_MATRIX = 1" +#endif +#endif + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_DRAW_TASK_TYPE_NONE = 0, + LV_DRAW_TASK_TYPE_FILL, + LV_DRAW_TASK_TYPE_BORDER, + LV_DRAW_TASK_TYPE_BOX_SHADOW, + LV_DRAW_TASK_TYPE_LABEL, + LV_DRAW_TASK_TYPE_IMAGE, + LV_DRAW_TASK_TYPE_LAYER, + LV_DRAW_TASK_TYPE_LINE, + LV_DRAW_TASK_TYPE_ARC, + LV_DRAW_TASK_TYPE_TRIANGLE, + LV_DRAW_TASK_TYPE_MASK_RECTANGLE, + LV_DRAW_TASK_TYPE_MASK_BITMAP, + LV_DRAW_TASK_TYPE_VECTOR, +} lv_draw_task_type_t; + +typedef enum { + LV_DRAW_TASK_STATE_WAITING, /*Waiting for something to be finished. E.g. rendering a layer*/ + LV_DRAW_TASK_STATE_QUEUED, + LV_DRAW_TASK_STATE_IN_PROGRESS, + LV_DRAW_TASK_STATE_READY, +} lv_draw_task_state_t; + +struct _lv_layer_t { + + /** Target draw buffer of the layer*/ + lv_draw_buf_t * draw_buf; + + /** The absolute coordinates of the buffer */ + lv_area_t buf_area; + + /** The color format of the layer. LV_COLOR_FORMAT_... */ + lv_color_format_t color_format; + + /** + * NEVER USE IT DRAW UNITS. USED INTERNALLY DURING DRAW TASK CREATION. + * The current clip area with absolute coordinates, always the same or smaller than `buf_area` + * Can be set before new draw tasks are added to indicate the clip area of the draw tasks. + * Therefore `lv_draw_add_task()` always saves it in the new draw task to know the clip area when the draw task was added. + * During drawing the draw units also sees the saved clip_area and should use it during drawing. + * During drawing the layer's clip area shouldn't be used as it might be already changed for other draw tasks. + */ + lv_area_t _clip_area; + + /** + * The physical clipping area relative to the display. + */ + lv_area_t phy_clip_area; + +#if LV_DRAW_TRANSFORM_USE_MATRIX + /** Transform matrix to be applied when rendering the layer */ + lv_matrix_t matrix; +#endif + + /** Linked list of draw tasks */ + lv_draw_task_t * draw_task_head; + + lv_layer_t * parent; + lv_layer_t * next; + bool all_tasks_added; + void * user_data; +}; + +typedef struct { + lv_obj_t * obj; + lv_part_t part; + uint32_t id1; + uint32_t id2; + lv_layer_t * layer; + size_t dsc_size; + void * user_data; +} lv_draw_dsc_base_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Used internally to initialize the drawing module + */ +void lv_draw_init(void); + +/** + * Deinitialize the drawing module + */ +void lv_draw_deinit(void); + +/** + * Allocate a new draw unit with the given size and appends it to the list of draw units + * @param size the size to allocate. E.g. `sizeof(my_draw_unit_t)`, + * where the first element of `my_draw_unit_t` is `lv_draw_unit_t`. + */ +void * lv_draw_create_unit(size_t size); + +/** + * Add an empty draw task to the draw task list of a layer. + * @param layer pointer to a layer + * @param coords the coordinates of the draw task + * @return the created draw task which needs to be + * further configured e.g. by added a draw descriptor + */ +lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords); + +/** + * Needs to be called when a draw task is created and configured. + * It will send an event about the new draw task to the widget + * and assign it to a draw unit. + * @param layer pointer to a layer + * @param t pointer to a draw task + */ +void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t); + +/** + * Try dispatching draw tasks to draw units + */ +void lv_draw_dispatch(void); + +/** + * Used internally to try dispatching draw tasks of a specific layer + * @param disp pointer to a display on which the dispatching was requested + * @param layer pointer to a layer + * @return at least one draw task is being rendered (maybe it was taken earlier) + */ +bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer); + +/** + * Wait for a new dispatch request. + * It's blocking if `LV_USE_OS == 0` else it yields + */ +void lv_draw_dispatch_wait_for_request(void); + +/** + * Wait for draw finish in case of asynchronous task execution. + * If `LV_USE_OS == 0` it just return. + */ +void lv_draw_wait_for_finish(void); + +/** + * When a draw unit finished a draw task it needs to request dispatching + * to let LVGL assign a new draw task to it + */ +void lv_draw_dispatch_request(void); + +/** + * Get the total number of draw units. + */ +uint32_t lv_draw_get_unit_count(void); + +/** + * Find and available draw task + * @param layer the draw ctx to search in + * @param t_prev continue searching from this task + * @param draw_unit_id check the task where `preferred_draw_unit_id` equals this value or `LV_DRAW_UNIT_NONE` + * @return tan available draw task or NULL if there is no any + */ +lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id); + +/** + * Tell how many draw task are waiting to be drawn on the area of `t_check`. + * It can be used to determine if a GPU shall combine many draw tasks into one or not. + * If a lot of tasks are waiting for the current ones it makes sense to draw them one-by-one + * to not block the dependent tasks' rendering + * @param t_check the task whose dependent tasks shall be counted + * @return number of tasks depending on `t_check` + */ +uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check); + +/** + * Create (allocate) a new layer on a parent layer + * @param parent_layer the parent layer to which the layer will be merged when it's rendered + * @param color_format the color format of the layer + * @param area the areas of the layer (absolute coordinates) + * @return the new target_layer or NULL on error + */ +lv_layer_t * lv_draw_layer_create(lv_layer_t * parent_layer, lv_color_format_t color_format, const lv_area_t * area); + +/** + * Initialize a layer which is allocated by the user + * @param layer pointer the layer to initialize (its lifetime needs to be managed by the user) + * @param parent_layer the parent layer to which the layer will be merged when it's rendered + * @param color_format the color format of the layer + * @param area the areas of the layer (absolute coordinates) + * @return the new target_layer or NULL on error + */ +void lv_draw_layer_init(lv_layer_t * layer, lv_layer_t * parent_layer, lv_color_format_t color_format, + const lv_area_t * area); + +/** + * Try to allocate a buffer for the layer. + * @param layer pointer to a layer + * @return pointer to the allocated aligned buffer or NULL on failure + */ +void * lv_draw_layer_alloc_buf(lv_layer_t * layer); + +/** + * Got to a pixel at X and Y coordinate on a layer + * @param layer pointer to a layer + * @param x the target X coordinate + * @param y the target X coordinate + * @return `buf` offset to point to the given X and Y coordinate + */ +void * lv_draw_layer_go_to_xy(lv_layer_t * layer, int32_t x, int32_t y); + +/** + * Get the type of a draw task + * @param t the draw task to get the type of + * @return the draw task type +*/ +lv_draw_task_type_t lv_draw_task_get_type(const lv_draw_task_t * t); + +/** + * Get the draw descriptor of a draw task + * @param t the draw task to get the draw descriptor of + * @return a void pointer to the draw descriptor +*/ +void * lv_draw_task_get_draw_dsc(const lv_draw_task_t * t); + +/** + * Get the draw area of a draw task + * @param t the draw task to get the draw area of + * @param area the destination where the draw area will be stored +*/ +void lv_draw_task_get_area(const lv_draw_task_t * t, lv_area_t * area); + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_arc.h b/test/include/liblvgl/draw/lv_draw_arc.h new file mode 100644 index 00000000..726bd68c --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_arc.h @@ -0,0 +1,90 @@ +/** + * @file lv_draw_arc.h + * + */ + +#ifndef LV_DRAW_ARC_H +#define LV_DRAW_ARC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "../misc/lv_color.h" +#include "../misc/lv_area.h" +#include "../misc/lv_style.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_draw_dsc_base_t base; + + lv_color_t color; + int32_t width; + lv_value_precise_t start_angle; + lv_value_precise_t end_angle; + lv_point_t center; + uint16_t radius; + const void * img_src; + lv_opa_t opa; + uint8_t rounded : 1; +} lv_draw_arc_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize an arc draw descriptor. + * @param dsc pointer to a draw descriptor + */ +void lv_draw_arc_dsc_init(lv_draw_arc_dsc_t * dsc); + +/** + * Try to get an arc draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_ARC + */ +lv_draw_arc_dsc_t * lv_draw_task_get_arc_dsc(lv_draw_task_t * task); + +/** + * Create an arc draw task. + * @param layer pointer to a layer + * @param dsc pointer to an initialized draw descriptor variable + */ +void lv_draw_arc(lv_layer_t * layer, const lv_draw_arc_dsc_t * dsc); + +/** + * Get an area the should be invalidated when the arcs angle changed between start_angle and end_ange + * @param x the x coordinate of the center of the arc + * @param y the y coordinate of the center of the arc + * @param radius the radius of the arc + * @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right) + * @param end_angle the end angle of the arc + * @param w width of the arc + * @param rounded true: the arc is rounded + * @param area store the area to invalidate here + */ +void lv_draw_arc_get_area(int32_t x, int32_t y, uint16_t radius, lv_value_precise_t start_angle, + lv_value_precise_t end_angle, + int32_t w, bool rounded, lv_area_t * area); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_ARC_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_buf.h b/test/include/liblvgl/draw/lv_draw_buf.h new file mode 100644 index 00000000..0a608696 --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_buf.h @@ -0,0 +1,356 @@ +/** + * @file lv_draw_buf.h + * + */ + +#ifndef LV_DRAW_BUF_H +#define LV_DRAW_BUF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_types.h" +#include "../misc/lv_area.h" +#include "../misc/lv_color.h" +#include "../stdlib/lv_string.h" +#include "lv_image_dsc.h" + +/********************* + * DEFINES + *********************/ + +/** Use this value to let LVGL calculate stride automatically */ +#define LV_STRIDE_AUTO 0 +LV_EXPORT_CONST_INT(LV_STRIDE_AUTO); + +/** + * Stride alignment for draw buffers. + * It may vary between different color formats and hardware. + * Refine it to suit your needs. + */ + +#define LV_DRAW_BUF_STRIDE(w, cf) \ + LV_ROUND_UP(((w) * LV_COLOR_FORMAT_GET_BPP(cf) + 7) / 8, LV_DRAW_BUF_STRIDE_ALIGN) + +/** Allocate a slightly larger buffer, so we can adjust the start address to meet alignment */ +#define LV_DRAW_BUF_SIZE(w, h, cf) \ + (LV_DRAW_BUF_STRIDE(w, cf) * (h) + LV_DRAW_BUF_ALIGN + \ + LV_COLOR_INDEXED_PALETTE_SIZE(cf) * sizeof(lv_color32_t)) + +/** + * Define a static draw buffer with the given width, height, and color format. + * Stride alignment is set to LV_DRAW_BUF_STRIDE_ALIGN. + * + * For platform that needs special buffer alignment, call LV_DRAW_BUF_INIT_STATIC. + */ +#define LV_DRAW_BUF_DEFINE_STATIC(name, _w, _h, _cf) \ + static uint8_t buf_##name[LV_DRAW_BUF_SIZE(_w, _h, _cf)]; \ + static lv_draw_buf_t name = { \ + .header = { \ + .magic = LV_IMAGE_HEADER_MAGIC, \ + .cf = (_cf), \ + .flags = LV_IMAGE_FLAGS_MODIFIABLE, \ + .w = (_w), \ + .h = (_h), \ + .stride = LV_DRAW_BUF_STRIDE(_w, _cf), \ + .reserved_2 = 0, \ + }, \ + .data_size = sizeof(buf_##name), \ + .data = buf_##name, \ + .unaligned_data = buf_##name, \ + } + +#define LV_DRAW_BUF_INIT_STATIC(name) \ + do { \ + lv_image_header_t * header = &name.header; \ + lv_draw_buf_init(&name, header->w, header->h, (lv_color_format_t)header->cf, header->stride, buf_##name, sizeof(buf_##name)); \ + lv_draw_buf_set_flag(&name, LV_IMAGE_FLAGS_MODIFIABLE); \ + } while(0) + +/********************** + * TYPEDEFS + **********************/ + +typedef void * (*lv_draw_buf_malloc_cb)(size_t size, lv_color_format_t color_format); + +typedef void (*lv_draw_buf_free_cb)(void * draw_buf); + +typedef void * (*lv_draw_buf_align_cb)(void * buf, lv_color_format_t color_format); + +typedef void (*lv_draw_buf_cache_operation_cb)(const lv_draw_buf_t * draw_buf, const lv_area_t * area); + +typedef uint32_t (*lv_draw_buf_width_to_stride_cb)(uint32_t w, lv_color_format_t color_format); + +struct _lv_draw_buf_t { + lv_image_header_t header; + uint32_t data_size; /**< Total buf size in bytes */ + uint8_t * data; + void * unaligned_data; /**< Unaligned address of `data`, used internally by lvgl */ + const lv_draw_buf_handlers_t * handlers; /**< draw buffer alloc/free ops. */ +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the draw buffer with the default handlers. + * + * @param handlers the draw buffer handlers to set + */ +void lv_draw_buf_init_with_default_handlers(lv_draw_buf_handlers_t * handlers); + +/** + * Initialize the draw buffer with given handlers. + * + * @param handlers the draw buffer handlers to set + * @param buf_malloc_cb the callback to allocate memory for the buffer + * @param buf_free_cb the callback to free memory of the buffer + * @param align_pointer_cb the callback to align the buffer + * @param invalidate_cache_cb the callback to invalidate the cache of the buffer + * @param flush_cache_cb the callback to flush buffer + * @param width_to_stride_cb the callback to calculate the stride based on the width and color format + */ +void lv_draw_buf_handlers_init(lv_draw_buf_handlers_t * handlers, + lv_draw_buf_malloc_cb buf_malloc_cb, + lv_draw_buf_free_cb buf_free_cb, + lv_draw_buf_align_cb align_pointer_cb, + lv_draw_buf_cache_operation_cb invalidate_cache_cb, + lv_draw_buf_cache_operation_cb flush_cache_cb, + lv_draw_buf_width_to_stride_cb width_to_stride_cb); + +/** + * Get the struct which holds the callbacks for draw buf management. + * Custom callback can be set on the returned value + * @return pointer to the struct of handlers + */ +lv_draw_buf_handlers_t * lv_draw_buf_get_handlers(void); +lv_draw_buf_handlers_t * lv_draw_buf_get_font_handlers(void); +lv_draw_buf_handlers_t * lv_draw_buf_get_image_handlers(void); + + +/** + * Align the address of a buffer. The buffer needs to be large enough for the real data after alignment + * @param buf the data to align + * @param color_format the color format of the buffer + * @return the aligned buffer + */ +void * lv_draw_buf_align(void * buf, lv_color_format_t color_format); + +/** + * Align the address of a buffer with custom draw buffer handlers. + * The buffer needs to be large enough for the real data after alignment + * @param handlers the draw buffer handlers + * @param buf the data to align + * @param color_format the color format of the buffer + * @return the aligned buffer + */ +void * lv_draw_buf_align_ex(const lv_draw_buf_handlers_t * handlers, void * buf, lv_color_format_t color_format); + +/** + * Invalidate the cache of the buffer + * @param draw_buf the draw buffer needs to be invalidated + * @param area the area to invalidate in the buffer, + * use NULL to invalidate the whole draw buffer address range + */ +void lv_draw_buf_invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); + +/** + * Flush the cache of the buffer + * @param draw_buf the draw buffer needs to be flushed + * @param area the area to flush in the buffer, + * use NULL to flush the whole draw buffer address range + */ +void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); + +/** + * Calculate the stride in bytes based on a width and color format + * @param w the width in pixels + * @param color_format the color format + * @return the stride in bytes + */ +uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format); + +/** + * Calculate the stride in bytes based on a width and color format + * @param handlers the draw buffer handlers + * @param w the width in pixels + * @param color_format the color format + * @return the stride in bytes + */ +uint32_t lv_draw_buf_width_to_stride_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w, + lv_color_format_t color_format); + +/** + * Clear an area on the buffer + * @param draw_buf pointer to draw buffer + * @param a the area to clear, or NULL to clear the whole buffer + */ +void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a); + +/** + * Copy an area from a buffer to another + * @param dest pointer to the destination draw buffer + * @param dest_area the area to copy from the destination buffer, if NULL, use the whole buffer + * @param src pointer to the source draw buffer + * @param src_area the area to copy from the destination buffer, if NULL, use the whole buffer + * @note `dest_area` and `src_area` should have the same width and height + * @note `dest` and `src` should have same color format. Color converting is not supported fow now. + */ +void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, + const lv_draw_buf_t * src, const lv_area_t * src_area); + +/** + * Note: Eventually, lv_draw_buf_malloc/free will be kept as private. + * For now, we use `create` to distinguish with malloc. + * + * Create an draw buf by allocating struct for `lv_draw_buf_t` and allocating a buffer for it + * that meets specified requirements. + * + * @param w the buffer width in pixels + * @param h the buffer height in pixels + * @param cf the color format for image + * @param stride the stride in bytes for image. Use 0 for automatic calculation based on + * w, cf, and global stride alignment configuration. + */ +lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride); + +/** + * Note: Eventually, lv_draw_buf_malloc/free will be kept as private. + * For now, we use `create` to distinguish with malloc. + * + * Create an draw buf by allocating struct for `lv_draw_buf_t` and allocating a buffer for it + * that meets specified requirements. + * + * @param handlers the draw buffer handlers + * @param w the buffer width in pixels + * @param h the buffer height in pixels + * @param cf the color format for image + * @param stride the stride in bytes for image. Use 0 for automatic calculation based on + * w, cf, and global stride alignment configuration. + */ +lv_draw_buf_t * lv_draw_buf_create_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w, uint32_t h, + lv_color_format_t cf, uint32_t stride); + +/** + * Duplicate a draw buf with same image size, stride and color format. Copy the image data too. + * @param draw_buf the draw buf to duplicate + * @return the duplicated draw buf on success, NULL if failed + */ +lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf); + +/** + * Duplicate a draw buf with same image size, stride and color format. Copy the image data too. + * @param handlers the draw buffer handlers + * @param draw_buf the draw buf to duplicate + * @return the duplicated draw buf on success, NULL if failed + */ +lv_draw_buf_t * lv_draw_buf_dup_ex(const lv_draw_buf_handlers_t * handlers, const lv_draw_buf_t * draw_buf); + +/** + * Initialize a draw buf with the given buffer and parameters. Clear draw buffer flag to zero. + * @param draw_buf the draw buf to initialize + * @param w the buffer width in pixels + * @param h the buffer height in pixels + * @param cf the color format + * @param stride the stride in bytes. Use 0 for automatic calculation + * @param data the buffer used for drawing. Unaligned `data` will be aligned internally + * @param data_size the size of the buffer in bytes + * @return return LV_RESULT_OK on success, LV_RESULT_INVALID otherwise + */ +lv_result_t lv_draw_buf_init(lv_draw_buf_t * draw_buf, uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride, + void * data, uint32_t data_size); + +/** + * Keep using the existing memory, reshape the draw buffer to the given width and height. + * Return NULL if data_size is smaller than the required size. + * @param draw_buf pointer to a draw buffer + * @param cf the new color format, use 0 or LV_COLOR_FORMAT_UNKNOWN to keep using the original color format. + * @param w the new width in pixels + * @param h the new height in pixels + * @param stride the stride in bytes for image. Use 0 for automatic calculation. + */ +lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t cf, uint32_t w, uint32_t h, + uint32_t stride); + +/** + * Destroy a draw buf by freeing the actual buffer if it's marked as LV_IMAGE_FLAGS_ALLOCATED in header. + * Then free the lv_draw_buf_t struct. + * + * @param draw_buf the draw buffer to destroy + */ +void lv_draw_buf_destroy(lv_draw_buf_t * draw_buf); + +/** + * Return pointer to the buffer at the given coordinates + */ +void * lv_draw_buf_goto_xy(const lv_draw_buf_t * buf, uint32_t x, uint32_t y); + +/** + * Adjust the stride of a draw buf in place. + * @param src pointer to a draw buffer + * @param stride the new stride in bytes for image. Use LV_STRIDE_AUTO for automatic calculation. + * @return LV_RESULT_OK: success or LV_RESULT_INVALID: failed + */ +lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride); + +/** + * Premultiply draw buffer color with alpha channel. + * If it's already premultiplied, return directly. + * Only color formats with alpha channel will be processed. + * + * @return LV_RESULT_OK: premultiply success + */ +lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf); + +bool lv_draw_buf_has_flag(const lv_draw_buf_t * draw_buf, lv_image_flags_t flag); + +void lv_draw_buf_set_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); + +void lv_draw_buf_clear_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); + +/** + * As of now, draw buf share same definition as `lv_image_dsc_t`. + * And is interchangeable with `lv_image_dsc_t`. + */ + +void lv_draw_buf_from_image(lv_draw_buf_t * buf, const lv_image_dsc_t * img); + +void lv_draw_buf_to_image(const lv_draw_buf_t * buf, lv_image_dsc_t * img); + +/** + * Set the palette color of an indexed image. Valid only for `LV_COLOR_FORMAT_I1/2/4/8` + * @param draw_buf pointer to an image descriptor + * @param index the palette color to set: + * - for `LV_COLOR_FORMAT_I1`: 0..1 + * - for `LV_COLOR_FORMAT_I2`: 0..3 + * - for `LV_COLOR_FORMAT_I4`: 0..15 + * - for `LV_COLOR_FORMAT_I8`: 0..255 + * @param color the color to set in lv_color32_t format + */ +void lv_draw_buf_set_palette(lv_draw_buf_t * draw_buf, uint8_t index, lv_color32_t color); + +/** + * @deprecated Use lv_draw_buf_set_palette instead. + */ +void lv_image_buf_set_palette(lv_image_dsc_t * dsc, uint8_t id, lv_color32_t c); + +/** + * @deprecated Use lv_draw_buffer_create/destroy instead. + * Free the data pointer and dsc struct of an image. + */ +void lv_image_buf_free(lv_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_BUF_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_buf_private.h b/test/include/liblvgl/draw/lv_draw_buf_private.h new file mode 100644 index 00000000..a2264031 --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_buf_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_draw_buf_private.h + * + */ + +#ifndef LV_DRAW_BUF_PRIVATE_H +#define LV_DRAW_BUF_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_buf.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_draw_buf_handlers_t { + lv_draw_buf_malloc_cb buf_malloc_cb; + lv_draw_buf_free_cb buf_free_cb; + lv_draw_buf_align_cb align_pointer_cb; + lv_draw_buf_cache_operation_cb invalidate_cache_cb; + lv_draw_buf_cache_operation_cb flush_cache_cb; + lv_draw_buf_width_to_stride_cb width_to_stride_cb; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Called internally to initialize the draw_buf_handlers in lv_global + */ +void lv_draw_buf_init_handlers(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_BUF_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_image.h b/test/include/liblvgl/draw/lv_draw_image.h new file mode 100644 index 00000000..d755604e --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_image.h @@ -0,0 +1,129 @@ +/** + * @file lv_draw_image.h + * + */ + +#ifndef LV_DRAW_IMAGE_H +#define LV_DRAW_IMAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_draw.h" +#include "lv_image_decoder.h" +#include "lv_draw_buf.h" +#include "../misc/lv_style.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * MACROS + **********************/ + +typedef struct _lv_draw_image_dsc_t { + lv_draw_dsc_base_t base; + + const void * src; + lv_image_header_t header; + + int32_t rotation; + int32_t scale_x; + int32_t scale_y; + int32_t skew_x; + int32_t skew_y; + lv_point_t pivot; + + lv_color_t recolor; + lv_opa_t recolor_opa; + + lv_opa_t opa; + lv_blend_mode_t blend_mode : 4; + + uint16_t antialias : 1; + uint16_t tile : 1; + lv_draw_image_sup_t * sup; + + /** Used to indicate the entire original, non-clipped area where the image is to be drawn. + * This is important for: + * 1. Layer rendering, where it might happen that only a smaller area of the layer is rendered. + * 2. Tiled images, where the target draw area is larger than the image to be tiled. + */ + lv_area_t image_area; + + int32_t clip_radius; + + const lv_image_dsc_t * bitmap_mask_src; +} lv_draw_image_dsc_t; + +/** + * PErform the actual rendering of a decoded image + * @param draw_unit pointer to a draw unit + * @param draw_dsc the draw descriptor of the image + * @param decoder_dsc pointer to the decoded image's descriptor + * @param sup supplementary data + * @param img_coords the absolute coordinates of the image + * @param clipped_img_area the absolute clip coordinates + */ +typedef void (*lv_draw_image_core_cb)(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize an image draw descriptor. + * @param dsc pointer to a draw descriptor + */ +void lv_draw_image_dsc_init(lv_draw_image_dsc_t * dsc); + +/** + * Try to get an image draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_IMAGE + */ +lv_draw_image_dsc_t * lv_draw_task_get_image_dsc(lv_draw_task_t * task); + +/** + * Create an image draw task + * @param layer pointer to a layer + * @param dsc pointer to an initialized draw descriptor + * @param coords the coordinates of the image + * @note `coords` can be small than the real image area + * (if only a part of the image is rendered) + * or can be larger (in case of tiled images). . + */ +void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords); + +/** + * Create a draw task to blend a layer to another layer + * @param layer pointer to a layer + * @param dsc pointer to an initialized draw descriptor + * @param coords the coordinates of the layer. + * @note `coords` can be small than the total widget area from which the layer is created + * (if only a part of the widget was rendered to a layer) + */ +void lv_draw_layer(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords); + +/** + * Get the type of an image source + * @param src pointer to an image source: + * - pointer to an 'lv_image_t' variable (image stored internally and compiled into the code) + * - a path to a file (e.g. "S:/folder/image.bin") + * - or a symbol (e.g. LV_SYMBOL_CLOSE) + * @return type of the image source LV_IMAGE_SRC_VARIABLE/FILE/SYMBOL/UNKNOWN + */ +lv_image_src_t lv_image_src_get_type(const void * src); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_IMAGE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_image_private.h b/test/include/liblvgl/draw/lv_draw_image_private.h new file mode 100644 index 00000000..ee22040b --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_image_private.h @@ -0,0 +1,85 @@ +/** + * @file lv_draw_image_private.h + * + */ + +#ifndef LV_DRAW_IMAGE_PRIVATE_H +#define LV_DRAW_IMAGE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_image.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_draw_image_sup_t { + lv_color_t alpha_color; + const lv_color32_t * palette; + uint32_t palette_size : 9; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Can be used by draw units to handle the decoding and + * prepare everything for the actual image rendering + * @param draw_unit pointer to a draw unit + * @param draw_dsc the draw descriptor of the image + * @param coords the absolute coordinates of the image + * @param draw_core_cb a callback to perform the actual rendering + */ +void lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb); + +/** + * Can be used by draw units for TILED images to handle the decoding and + * prepare everything for the actual image rendering + * @param draw_unit pointer to a draw unit + * @param draw_dsc the draw descriptor of the image + * @param coords the absolute coordinates of the image + * @param draw_core_cb a callback to perform the actual rendering + */ +void lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb); + +/** + * Get the area of a rectangle if its rotated and scaled + * @param res store the coordinates here + * @param w width of the rectangle to transform + * @param h height of the rectangle to transform + * @param angle angle of rotation + * @param scale_x zoom in x direction, (256 no zoom) + * @param scale_y zoom in y direction, (256 no zoom) + * @param pivot x,y pivot coordinates of rotation + */ +void lv_image_buf_get_transformed_area(lv_area_t * res, int32_t w, int32_t h, int32_t angle, + uint16_t scale_x, uint16_t scale_y, const lv_point_t * pivot); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_IMAGE_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_label.h b/test/include/liblvgl/draw/lv_draw_label.h new file mode 100644 index 00000000..e0e46290 --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_label.h @@ -0,0 +1,145 @@ +/** + * @file lv_draw_label.h + * + */ + +#ifndef LV_DRAW_LABEL_H +#define LV_DRAW_LABEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_draw.h" +#include "lv_draw_rect.h" +#include "../misc/lv_bidi.h" +#include "../misc/lv_text.h" +#include "../misc/lv_color.h" +#include "../misc/lv_style.h" + +/********************* + * DEFINES + *********************/ +#define LV_DRAW_LABEL_NO_TXT_SEL (0xFFFF) + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_draw_dsc_base_t base; + + const char * text; + const lv_font_t * font; + uint32_t sel_start; + uint32_t sel_end; + lv_color_t color; + lv_color_t sel_color; + lv_color_t sel_bg_color; + int32_t line_space; + int32_t letter_space; + int32_t ofs_x; + int32_t ofs_y; + lv_opa_t opa; + lv_base_dir_t bidi_dir; + lv_text_align_t align; + lv_text_flag_t flag; + lv_text_decor_t decor : 3; + lv_blend_mode_t blend_mode : 3; + /** + * < 1: malloc buffer and copy `text` there. + * 0: `text` is const and it's pointer will be valid during rendering.*/ + uint8_t text_local : 1; + + /** + * Indicate that the text is constant and its pointer can be safely saved e.g. in a cache. + */ + uint8_t text_static : 1; + lv_draw_label_hint_t * hint; +} lv_draw_label_dsc_t; + +/** + * Passed as a parameter to `lv_draw_label_iterate_characters` to + * draw the characters one by one + * @param draw_unit pointer to a draw unit + * @param dsc pointer to `lv_draw_glyph_dsc_t` to describe the character to draw + * if NULL don't draw character + * @param fill_dsc pointer to a fill descriptor to draw a background for the character or + * underline or strike through + * if NULL do not fill anything + * @param fill_area the area to fill + * if NULL do not fill anything + */ +typedef void(*lv_draw_glyph_cb_t)(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, lv_draw_fill_dsc_t * fill_dsc, + const lv_area_t * fill_area); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a label draw descriptor + * @param dsc pointer to a draw descriptor + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc); + +/** + * Try to get a label draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_LABEL + */ +lv_draw_label_dsc_t * lv_draw_task_get_label_dsc(lv_draw_task_t * task); + +/** + * Initialize a glyph draw descriptor. + * Used internally. + * @param dsc pointer to a draw descriptor + */ +void lv_draw_glyph_dsc_init(lv_draw_glyph_dsc_t * dsc); + +/** + * Crate a draw task to render a text + * @param layer pointer to a layer + * @param dsc pointer to draw descriptor + * @param coords coordinates of the character + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_label(lv_layer_t * layer, const lv_draw_label_dsc_t * dsc, + const lv_area_t * coords); + +/** + * Crate a draw task to render a single character + * @param layer pointer to a layer + * @param dsc pointer to draw descriptor + * @param point position of the label + * @param unicode_letter the letter to draw + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_character(lv_layer_t * layer, lv_draw_label_dsc_t * dsc, + const lv_point_t * point, uint32_t unicode_letter); + +/** + * Should be used during rendering the characters to get the position and other + * parameters of the characters + * @param draw_unit pointer to a draw unit + * @param dsc pointer to draw descriptor + * @param coords coordinates of the label + * @param cb a callback to call to draw each glyphs one by one + */ +void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, + const lv_area_t * coords, lv_draw_glyph_cb_t cb); + +/*********************** + * GLOBAL VARIABLES + ***********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_LABEL_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_label_private.h b/test/include/liblvgl/draw/lv_draw_label_private.h new file mode 100644 index 00000000..4d225d5e --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_label_private.h @@ -0,0 +1,68 @@ +/** + * @file lv_draw_label_private.h + * + */ + +#ifndef LV_DRAW_LABEL_PRIVATE_H +#define LV_DRAW_LABEL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_label.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Store some info to speed up drawing of very large texts + * It takes a lot of time to get the first visible character because + * all the previous characters needs to be checked to calculate the positions. + * This structure stores an earlier (e.g. at -1000 px) coordinate and the index of that line. + * Therefore the calculations can start from here.*/ +struct _lv_draw_label_hint_t { + /** Index of the line at `y` coordinate*/ + int32_t line_start; + + /** Give the `y` coordinate of the first letter at `line start` index. Relative to the label's coordinates*/ + int32_t y; + + /** The 'y1' coordinate of the label when the hint was saved. + * Used to invalidate the hint if the label has moved too much.*/ + int32_t coord_y; +}; + +struct _lv_draw_glyph_dsc_t { + void * glyph_data; /**< Depends on `format` field, it could be image source or draw buf of bitmap or vector data. */ + lv_font_glyph_format_t format; + const lv_area_t * letter_coords; + const lv_area_t * bg_coords; + const lv_font_glyph_dsc_t * g; + lv_color_t color; + lv_opa_t opa; + lv_draw_buf_t * _draw_buf; /**< a shared draw buf for get_bitmap, do not use it directly, use glyph_data instead */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_LABEL_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_line.h b/test/include/liblvgl/draw/lv_draw_line.h new file mode 100644 index 00000000..72430fa7 --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_line.h @@ -0,0 +1,76 @@ +/** + * @file lv_draw_line.h + * + */ + +#ifndef LV_DRAW_LINE_H +#define LV_DRAW_LINE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "../misc/lv_color.h" +#include "../misc/lv_area.h" +#include "../misc/lv_style.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + lv_draw_dsc_base_t base; + + lv_point_precise_t p1; + lv_point_precise_t p2; + lv_color_t color; + int32_t width; + int32_t dash_width; + int32_t dash_gap; + lv_opa_t opa; + lv_blend_mode_t blend_mode : 2; + uint8_t round_start : 1; + uint8_t round_end : 1; + uint8_t raw_end : 1; /**< Do not bother with perpendicular line ending if it's not visible for any reason */ +} lv_draw_line_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a line draw descriptor + * @param dsc pointer to a draw descriptor + */ +void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc); + +/** + * Try to get a line draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_LINE + */ +lv_draw_line_dsc_t * lv_draw_task_get_line_dsc(lv_draw_task_t * task); + +/** + * Create a line draw task + * @param layer pointer to a layer + * @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable + */ +void lv_draw_line(lv_layer_t * layer, const lv_draw_line_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_LINE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_mask.h b/test/include/liblvgl/draw/lv_draw_mask.h new file mode 100644 index 00000000..6dfed79b --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_mask.h @@ -0,0 +1,56 @@ +/** + * @file lv_draw_mask.h + * + */ + +#ifndef LV_DRAW_MASK_H +#define LV_DRAW_MASK_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_color.h" +#include "../misc/lv_area.h" +#include "../misc/lv_style.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a rectangle mask draw descriptor. + * @param dsc pointer to a draw descriptor + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_mask_rect_dsc_init(lv_draw_mask_rect_dsc_t * dsc); + +/** + * Try to get a rectangle mask draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_MASK_RECTANGLE + */ +lv_draw_mask_rect_dsc_t * lv_draw_task_get_mask_rect_dsc(lv_draw_task_t * task); + +/** + * Create a draw task to mask a rectangle from the buffer + * @param layer pointer to a layer + * @param dsc pointer to a draw descriptor + */ +void lv_draw_mask_rect(lv_layer_t * layer, const lv_draw_mask_rect_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_MASK_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_mask_private.h b/test/include/liblvgl/draw/lv_draw_mask_private.h new file mode 100644 index 00000000..9863e365 --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_mask_private.h @@ -0,0 +1,51 @@ +/** + * @file lv_draw_mask_private.h + * + */ + +#ifndef LV_DRAW_MASK_PRIVATE_H +#define LV_DRAW_MASK_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_mask.h" +#include "lv_draw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ +struct _lv_draw_mask_rect_dsc_t { + lv_draw_dsc_base_t base; + + lv_area_t area; + int32_t radius; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_MASK_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_private.h b/test/include/liblvgl/draw/lv_draw_private.h new file mode 100644 index 00000000..e3fd0345 --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_private.h @@ -0,0 +1,196 @@ +/** + * @file lv_draw_private.h + * + */ + +/** + * Modified by NXP in 2024 + */ + +#ifndef LV_DRAW_PRIVATE_H +#define LV_DRAW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_draw_task_t { + lv_draw_task_t * next; + + lv_draw_task_type_t type; + + /** + * The area where to draw + */ + lv_area_t area; + + /** + * The real draw area. E.g. for shadow, outline, or transformed images it's different from `area` + */ + lv_area_t _real_area; + + /** The original area which is updated*/ + lv_area_t clip_area_original; + + /** + * The clip area of the layer is saved here when the draw task is created. + * As the clip area of the layer can be changed as new draw tasks are added its current value needs to be saved. + * Therefore during drawing the layer's clip area shouldn't be used as it might be already changed for other draw tasks. + */ + lv_area_t clip_area; + +#if LV_DRAW_TRANSFORM_USE_MATRIX + /** Transform matrix to be applied when rendering the layer */ + lv_matrix_t matrix; +#endif + + volatile int state; /** int instead of lv_draw_task_state_t to be sure its atomic */ + + void * draw_dsc; + + /** + * The ID of the draw_unit which should take this task + */ + uint8_t preferred_draw_unit_id; + + /** + * Set to which extent `preferred_draw_unit_id` is good at this task. + * 80: means 20% better (faster) than software rendering + * 100: the default value + * 110: means 10% worse (slower) than software rendering + */ + uint8_t preference_score; + +}; + +struct _lv_draw_mask_t { + void * user_data; +}; + +struct _lv_draw_unit_t { + lv_draw_unit_t * next; + + /** + * The target_layer on which drawing should happen + */ + lv_layer_t * target_layer; + + const lv_area_t * clip_area; + + /** + * Called to try to assign a draw task to itself. + * `lv_draw_get_next_available_task` can be used to get an independent draw task. + * A draw task should be assign only if the draw unit can draw it too + * @param draw_unit pointer to the draw unit + * @param layer pointer to a layer on which the draw task should be drawn + * @return >=0: The number of taken draw task: + * 0 means the task has not yet been completed. + * 1 means a new task has been accepted. + * -1: The draw unit wanted to work on a task but couldn't do that + * due to some errors (e.g. out of memory). + * It signals that LVGL should call the dispatcher later again + * to let draw unit try to start the rendering again. + */ + int32_t (*dispatch_cb)(lv_draw_unit_t * draw_unit, lv_layer_t * layer); + + /** + * + * @param draw_unit + * @param task + * @return + */ + int32_t (*evaluate_cb)(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); + + /** + * Called to signal the unit to complete all tasks in order to return their ready status. + * This callback can be implemented in case of asynchronous task processing. + * Below is an example to show the difference between synchronous and asynchronous: + * + * Synchronous: + * LVGL thread DRAW thread HW + * + * task1 --> submit --> Receive task1 + * wait_for_finish() + * <-- task1->state = READY <-- Complete task1 + * task2 --> submit --> Receive task2 + * wait_for_finish() + * task2->state = READY <-- Complete task2 + * task3 --> submit --> Receive task3 + * wait_for_finish() + * <-- task3->state = READY <-- Complete task3 + * task4 --> submit --> Receive task4 + * wait_for_finish() + * <-- task4->state = READY <-- Complete task4 + * NO MORE TASKS + * + * + * Asynchronous: + * LVGL thread DRAW thread HW + * is IDLE + * task1 --> queue task1 + * submit --> Receive task1 + * task2 --> queue task2 is BUSY (with task1) + * task3 --> queue task3 still BUSY (with task1) + * task4 --> queue task4 becomes IDLE + * <-- task1->state = READY <-- Complete task1 + * submit --> Receive task2, task3, task4 + * NO MORE TASKS + * wait_for_finish_cb() wait_for_finish() + * <-- Complete task2, task3, task4 + * <-- task2->state = READY <-- + * <-- task3->state = READY <-- + * <-- task4->state = READY <-- + * + * @param draw_unit + * @return + */ + int32_t (*wait_for_finish_cb)(lv_draw_unit_t * draw_unit); + + /** + * Called to delete draw unit. + * @param draw_unit + * @return + */ + int32_t (*delete_cb)(lv_draw_unit_t * draw_unit); +}; + +typedef struct { + lv_draw_unit_t * unit_head; + uint32_t unit_cnt; + uint32_t used_memory_for_layers_kb; +#if LV_USE_OS + lv_thread_sync_t sync; +#else + volatile int dispatch_req; +#endif + lv_mutex_t circle_cache_mutex; + bool task_running; +} lv_draw_global_info_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_rect.h b/test/include/liblvgl/draw/lv_draw_rect.h new file mode 100644 index 00000000..6fe3a82e --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_rect.h @@ -0,0 +1,174 @@ +/** + * @file lv_draw_rect.h + * + */ + +#ifndef LV_DRAW_RECT_H +#define LV_DRAW_RECT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_draw.h" +#include "../misc/lv_color.h" +#include "../misc/lv_area.h" +#include "../misc/lv_style.h" +#include "sw/lv_draw_sw_gradient.h" + +/********************* + * DEFINES + *********************/ +#define LV_RADIUS_CIRCLE 0x7FFF /**< A very big radius to always draw as circle*/ +LV_EXPORT_CONST_INT(LV_RADIUS_CIRCLE); + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_draw_dsc_base_t base; + + int32_t radius; + + /*Background*/ + lv_opa_t bg_opa; + lv_color_t bg_color; /**< First element of a gradient is a color, so it maps well here*/ + lv_grad_dsc_t bg_grad; + + /*Background img*/ + const void * bg_image_src; + const void * bg_image_symbol_font; + lv_color_t bg_image_recolor; + lv_opa_t bg_image_opa; + lv_opa_t bg_image_recolor_opa; + uint8_t bg_image_tiled; + + /*Border*/ + lv_color_t border_color; + int32_t border_width; + lv_opa_t border_opa; + lv_border_side_t border_side : 5; + uint8_t border_post : 1; /*The border will be drawn later*/ + + /*Outline*/ + lv_color_t outline_color; + int32_t outline_width; + int32_t outline_pad; + lv_opa_t outline_opa; + + /*Shadow*/ + lv_color_t shadow_color; + int32_t shadow_width; + int32_t shadow_offset_x; + int32_t shadow_offset_y; + int32_t shadow_spread; + lv_opa_t shadow_opa; +} lv_draw_rect_dsc_t; + +typedef struct { + lv_draw_dsc_base_t base; + + int32_t radius; + + lv_opa_t opa; + lv_color_t color; + lv_grad_dsc_t grad; +} lv_draw_fill_dsc_t; + +typedef struct { + lv_draw_dsc_base_t base; + + int32_t radius; + + lv_color_t color; + int32_t width; + lv_opa_t opa; + lv_border_side_t side : 5; + +} lv_draw_border_dsc_t; + +typedef struct { + lv_draw_dsc_base_t base; + + int32_t radius; + + lv_color_t color; + int32_t width; + int32_t spread; + int32_t ofs_x; + int32_t ofs_y; + lv_opa_t opa; + uint8_t bg_cover : 1; +} lv_draw_box_shadow_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a rectangle draw descriptor. + * @param dsc pointer to a draw descriptor + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_rect_dsc_init(lv_draw_rect_dsc_t * dsc); + +/** + * Initialize a fill draw descriptor. + * @param dsc pointer to a draw descriptor + */ +void lv_draw_fill_dsc_init(lv_draw_fill_dsc_t * dsc); + +/** + * Try to get a fill draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_FILL + */ +lv_draw_fill_dsc_t * lv_draw_task_get_fill_dsc(lv_draw_task_t * task); + +/** + * Initialize a border draw descriptor. + * @param dsc pointer to a draw descriptor + */ +void lv_draw_border_dsc_init(lv_draw_border_dsc_t * dsc); + +/** + * Try to get a border draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_BORDER + */ +lv_draw_border_dsc_t * lv_draw_task_get_border_dsc(lv_draw_task_t * task); + +/** + * Initialize a box shadow draw descriptor. + * @param dsc pointer to a draw descriptor + */ +void lv_draw_box_shadow_dsc_init(lv_draw_box_shadow_dsc_t * dsc); + +/** + * Try to get a box shadow draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_BOX_SHADOW + */ +lv_draw_box_shadow_dsc_t * lv_draw_task_get_box_shadow_dsc(lv_draw_task_t * task); + +/** + * The rectangle is a wrapper for fill, border, bg. image and box shadow. + * Internally fill, border, image and box shadow draw tasks will be created. + * @param layer pointer to a layer + * @param dsc pointer to an initialized draw descriptor variable + * @param coords the coordinates of the rectangle + */ +void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_RECT_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_rect_private.h b/test/include/liblvgl/draw/lv_draw_rect_private.h new file mode 100644 index 00000000..ad75b535 --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_rect_private.h @@ -0,0 +1,39 @@ +/** + * @file lv_draw_rect_private.h + * + */ + +#ifndef LV_DRAW_RECT_PRIVATE_H +#define LV_DRAW_RECT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_rect.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_RECT_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_triangle.h b/test/include/liblvgl/draw/lv_draw_triangle.h new file mode 100644 index 00000000..b1ad8e58 --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_triangle.h @@ -0,0 +1,67 @@ +/** + * @file lv_draw_triangle.h + * + */ + +#ifndef LV_DRAW_TRIANGLE_H +#define LV_DRAW_TRIANGLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_rect.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + lv_draw_dsc_base_t base; + + lv_opa_t bg_opa; + lv_color_t bg_color; + lv_grad_dsc_t bg_grad; + + lv_point_precise_t p[3]; +} lv_draw_triangle_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a triangle draw descriptor + * @param draw_dsc pointer to a draw descriptor + */ +void lv_draw_triangle_dsc_init(lv_draw_triangle_dsc_t * draw_dsc); + +/** + * Try to get a triangle draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_TRIANGLE + */ +lv_draw_triangle_dsc_t * lv_draw_task_get_triangle_dsc(lv_draw_task_t * task); + +/** + * Create a triangle draw task + * @param layer pointer to a layer + * @param draw_dsc pointer to an initialized `lv_draw_triangle_dsc_t` object + */ +void lv_draw_triangle(lv_layer_t * layer, const lv_draw_triangle_dsc_t * draw_dsc); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_TRIANGLE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_triangle_private.h b/test/include/liblvgl/draw/lv_draw_triangle_private.h new file mode 100644 index 00000000..7fc8ed5a --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_triangle_private.h @@ -0,0 +1,43 @@ +/** + * @file lv_draw_triangle_private.h + * + */ + +#ifndef LV_DRAW_TRIANGLE_PRIVATE_H +#define LV_DRAW_TRIANGLE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_triangle.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_TRIANGLE_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/lv_draw_vector.h b/test/include/liblvgl/draw/lv_draw_vector.h new file mode 100644 index 00000000..5a59e525 --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_vector.h @@ -0,0 +1,489 @@ +/** + * @file lv_draw_vector.h + * + */ + +#ifndef LV_DRAW_VECTOR_H +#define LV_DRAW_VECTOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../misc/lv_array.h" +#include "../misc/lv_matrix.h" +#include "lv_draw_image.h" + +#if LV_USE_VECTOR_GRAPHIC + +#if !LV_USE_MATRIX +#error "lv_draw_vector needs LV_USE_MATRIX = 1" +#endif + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_VECTOR_FILL_NONZERO = 0, + LV_VECTOR_FILL_EVENODD, +} lv_vector_fill_t; + +typedef enum { + LV_VECTOR_STROKE_CAP_BUTT = 0, + LV_VECTOR_STROKE_CAP_SQUARE, + LV_VECTOR_STROKE_CAP_ROUND, +} lv_vector_stroke_cap_t; + +typedef enum { + LV_VECTOR_STROKE_JOIN_MITER = 0, + LV_VECTOR_STROKE_JOIN_BEVEL, + LV_VECTOR_STROKE_JOIN_ROUND, +} lv_vector_stroke_join_t; + +typedef enum { + LV_VECTOR_PATH_QUALITY_MEDIUM = 0, /* default*/ + LV_VECTOR_PATH_QUALITY_HIGH, + LV_VECTOR_PATH_QUALITY_LOW, +} lv_vector_path_quality_t; + +typedef enum { + LV_VECTOR_BLEND_SRC_OVER = 0, + LV_VECTOR_BLEND_SRC_IN, + LV_VECTOR_BLEND_DST_OVER, + LV_VECTOR_BLEND_DST_IN, + LV_VECTOR_BLEND_SCREEN, + LV_VECTOR_BLEND_MULTIPLY, + LV_VECTOR_BLEND_NONE, + LV_VECTOR_BLEND_ADDITIVE, + LV_VECTOR_BLEND_SUBTRACTIVE, +} lv_vector_blend_t; + +typedef enum { + LV_VECTOR_PATH_OP_MOVE_TO = 0, + LV_VECTOR_PATH_OP_LINE_TO, + LV_VECTOR_PATH_OP_QUAD_TO, + LV_VECTOR_PATH_OP_CUBIC_TO, + LV_VECTOR_PATH_OP_CLOSE, +} lv_vector_path_op_t; + +typedef enum { + LV_VECTOR_DRAW_STYLE_SOLID = 0, + LV_VECTOR_DRAW_STYLE_PATTERN, + LV_VECTOR_DRAW_STYLE_GRADIENT, +} lv_vector_draw_style_t; + +typedef enum { + LV_VECTOR_GRADIENT_SPREAD_PAD = 0, + LV_VECTOR_GRADIENT_SPREAD_REPEAT, + LV_VECTOR_GRADIENT_SPREAD_REFLECT, +} lv_vector_gradient_spread_t; + +typedef enum { + LV_VECTOR_GRADIENT_STYLE_LINEAR = 0, + LV_VECTOR_GRADIENT_STYLE_RADIAL, +} lv_vector_gradient_style_t; + +struct _lv_fpoint_t { + float x; + float y; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Transform the coordinates of a point using given matrix + * @param matrix pointer to a matrix + * @param point pointer to a point + */ +void lv_matrix_transform_point(const lv_matrix_t * matrix, lv_fpoint_t * point); + +/** + * Transform all the coordinates of a path using given matrix + * @param matrix pointer to a matrix + * @param path pointer to a path + */ +void lv_matrix_transform_path(const lv_matrix_t * matrix, lv_vector_path_t * path); + +/** + * Create a vector graphic path object + * @param quality the quality hint of path + * @return pointer to the created path object + */ +lv_vector_path_t * lv_vector_path_create(lv_vector_path_quality_t quality); + +/** + * Copy a path data to another + * @param target_path pointer to a path + * @param path pointer to source path + */ +void lv_vector_path_copy(lv_vector_path_t * target_path, const lv_vector_path_t * path); + +/** + * Clear path data + * @param path pointer to a path + */ +void lv_vector_path_clear(lv_vector_path_t * path); + +/** + * Delete the graphic path object + * @param path pointer to a path + */ +void lv_vector_path_delete(lv_vector_path_t * path); + +/** + * Begin a new sub path and set a point to path + * @param path pointer to a path + * @param p pointer to a `lv_fpoint_t` variable + */ +void lv_vector_path_move_to(lv_vector_path_t * path, const lv_fpoint_t * p); + +/** + * Add a line to the path from last point to the point + * @param path pointer to a path + * @param p pointer to a `lv_fpoint_t` variable + */ +void lv_vector_path_line_to(lv_vector_path_t * path, const lv_fpoint_t * p); + +/** + * Add a quadratic bezier line to the path from last point to the point + * @param path pointer to a path + * @param p1 pointer to a `lv_fpoint_t` variable for control point + * @param p2 pointer to a `lv_fpoint_t` variable for end point + */ +void lv_vector_path_quad_to(lv_vector_path_t * path, const lv_fpoint_t * p1, const lv_fpoint_t * p2); + +/** + * Add a cubic bezier line to the path from last point to the point + * @param path pointer to a path + * @param p1 pointer to a `lv_fpoint_t` variable for first control point + * @param p2 pointer to a `lv_fpoint_t` variable for second control point + * @param p3 pointer to a `lv_fpoint_t` variable for end point + */ +void lv_vector_path_cubic_to(lv_vector_path_t * path, const lv_fpoint_t * p1, const lv_fpoint_t * p2, + const lv_fpoint_t * p3); + +/** + * Close the sub path + * @param path pointer to a path + */ +void lv_vector_path_close(lv_vector_path_t * path); + +/** + * Get the bounding box of a path + * @param path pointer to a path + * @param area pointer to a `lv_area_t` variable for bounding box + */ +void lv_vector_path_get_bounding(const lv_vector_path_t * path, lv_area_t * area); + +/** + * Add a rectangle to the path + * @param path pointer to a path + * @param rect pointer to a `lv_area_t` variable + * @param rx the horizontal radius for rounded rectangle + * @param ry the vertical radius for rounded rectangle + */ +void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, float rx, float ry); + +/** + * Add a circle to the path + * @param path pointer to a path + * @param c pointer to a `lv_fpoint_t` variable for center of the circle + * @param rx the horizontal radius for circle + * @param ry the vertical radius for circle + */ +void lv_vector_path_append_circle(lv_vector_path_t * path, const lv_fpoint_t * c, float rx, float ry); + +/** + * Add a arc to the path + * @param path pointer to a path + * @param c pointer to a `lv_fpoint_t` variable for center of the circle + * @param radius the radius for arc + * @param start_angle the start angle for arc + * @param sweep the sweep angle for arc, could be negative + * @param pie true: draw a pie, false: draw a arc + */ +void lv_vector_path_append_arc(lv_vector_path_t * path, const lv_fpoint_t * c, float radius, float start_angle, + float sweep, bool pie); + +/** + * Add an sub path to the path + * @param path pointer to a path + * @param subpath pointer to another path which will be added + */ +void lv_vector_path_append_path(lv_vector_path_t * path, const lv_vector_path_t * subpath); + +/** + * Create a vector graphic descriptor + * @param layer pointer to a layer + * @return pointer to the created descriptor + */ +lv_vector_dsc_t * lv_vector_dsc_create(lv_layer_t * layer); + +/** + * Delete the vector graphic descriptor + * @param dsc pointer to a vector graphic descriptor + */ +void lv_vector_dsc_delete(lv_vector_dsc_t * dsc); + +/** + * Set a matrix to current transformation matrix + * @param dsc pointer to a vector graphic descriptor + * @param matrix pointer to a matrix + */ +void lv_vector_dsc_set_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix); + +/** + * Set blend mode for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param blend the blend mode to be set in `lv_vector_blend_t` + */ +void lv_vector_dsc_set_blend_mode(lv_vector_dsc_t * dsc, lv_vector_blend_t blend); + +/** + * Set fill color for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param color the color to be set in lv_color32_t format + */ +void lv_vector_dsc_set_fill_color32(lv_vector_dsc_t * dsc, lv_color32_t color); + +/** + * Set fill color for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param color the color to be set in lv_color_t format + */ +void lv_vector_dsc_set_fill_color(lv_vector_dsc_t * dsc, lv_color_t color); + +/** + * Set fill opacity for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param opa the opacity to be set in lv_opa_t format + */ +void lv_vector_dsc_set_fill_opa(lv_vector_dsc_t * dsc, lv_opa_t opa); + +/** + * Set fill rule for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param rule the fill rule to be set in lv_vector_fill_t format + */ +void lv_vector_dsc_set_fill_rule(lv_vector_dsc_t * dsc, lv_vector_fill_t rule); + +/** + * Set fill image for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param img_dsc pointer to a `lv_draw_image_dsc_t` variable + */ +void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc_t * img_dsc); + +/** + * Set fill linear gradient for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param x1 the x for start point + * @param y1 the y for start point + * @param x2 the x for end point + * @param y2 the y for end point + */ +void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2); + +/** + + * Set fill radial gradient radius for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param cx the x for center of the circle + * @param cy the y for center of the circle + * @param radius the radius for circle + */ +void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius); + +/** + * Set fill radial gradient spread for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param spread the gradient spread to be set in lv_vector_gradient_spread_t format + */ +void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread); + +/** + * Set fill gradient color stops for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param stops an array of `lv_gradient_stop_t` variables + * @param count the number of stops in the array, range: 0..LV_GRADIENT_MAX_STOPS + */ +void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, + uint16_t count); + +/** + * Set a matrix to current fill transformation matrix + * @param dsc pointer to a vector graphic descriptor + * @param matrix pointer to a matrix + */ +void lv_vector_dsc_set_fill_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix); + +/** + * Set stroke color for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param color the color to be set in lv_color32_t format + */ +void lv_vector_dsc_set_stroke_color32(lv_vector_dsc_t * dsc, lv_color32_t color); + +/** + * Set stroke color for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param color the color to be set in lv_color_t format + */ +void lv_vector_dsc_set_stroke_color(lv_vector_dsc_t * dsc, lv_color_t color); + +/** + * Set stroke opacity for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param opa the opacity to be set in lv_opa_t format + */ +void lv_vector_dsc_set_stroke_opa(lv_vector_dsc_t * dsc, lv_opa_t opa); + +/** + * Set stroke line width for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param width the stroke line width + */ +void lv_vector_dsc_set_stroke_width(lv_vector_dsc_t * dsc, float width); + +/** + * Set stroke line dash pattern for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param dash_pattern an array of values that specify the segments of dash line + * @param dash_count the length of dash pattern array + */ +void lv_vector_dsc_set_stroke_dash(lv_vector_dsc_t * dsc, float * dash_pattern, uint16_t dash_count); + +/** + * Set stroke line cap style for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param cap the line cap to be set in lv_vector_stroke_cap_t format + */ +void lv_vector_dsc_set_stroke_cap(lv_vector_dsc_t * dsc, lv_vector_stroke_cap_t cap); + +/** + * Set stroke line join style for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param join the line join to be set in lv_vector_stroke_join_t format + */ +void lv_vector_dsc_set_stroke_join(lv_vector_dsc_t * dsc, lv_vector_stroke_join_t join); + +/** + * Set stroke miter limit for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param miter_limit the stroke miter_limit + */ +void lv_vector_dsc_set_stroke_miter_limit(lv_vector_dsc_t * dsc, uint16_t miter_limit); + +/** + * Set stroke linear gradient for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param x1 the x for start point + * @param y1 the y for start point + * @param x2 the x for end point + * @param y2 the y for end point + */ +void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2); +/** + * Set stroke radial gradient for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param cx the x for center of the circle + * @param cy the y for center of the circle + * @param radius the radius for circle + */ +void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius); + +/** + * Set stroke color stops for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param spread the gradient spread to be set in lv_vector_gradient_spread_t format + */ +void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread); + +/** + * Set stroke color stops for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param stops an array of `lv_gradient_stop_t` variables + * @param count the number of stops in the array + */ +void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, + uint16_t count); + +/** + * Set a matrix to current stroke transformation matrix + * @param dsc pointer to a vector graphic descriptor + * @param matrix pointer to a matrix + */ +void lv_vector_dsc_set_stroke_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix); + +/** + * Set current transformation matrix to identity matrix + * @param dsc pointer to a vector graphic descriptor + */ +void lv_vector_dsc_identity(lv_vector_dsc_t * dsc); + +/** + * Change the scale factor of current transformation matrix + * @param dsc pointer to a vector graphic descriptor + * @param scale_x the scale factor for the X direction + * @param scale_y the scale factor for the Y direction + */ +void lv_vector_dsc_scale(lv_vector_dsc_t * dsc, float scale_x, float scale_y); + +/** + * Rotate current transformation matrix with origin + * @param dsc pointer to a vector graphic descriptor + * @param degree angle to rotate + */ +void lv_vector_dsc_rotate(lv_vector_dsc_t * dsc, float degree); + +/** + * Translate current transformation matrix to new position + * @param dsc pointer to a vector graphic descriptor + * @param tx the amount of translate in x direction + * @param tx the amount of translate in y direction + */ +void lv_vector_dsc_translate(lv_vector_dsc_t * dsc, float tx, float ty); + +/** + * Change the skew factor of current transformation matrix + * @param dsc pointer to a vector graphic descriptor + * @param skew_x the skew factor for x direction + * @param skew_y the skew factor for y direction + */ +void lv_vector_dsc_skew(lv_vector_dsc_t * dsc, float skew_x, float skew_y); + +/** + * Add a graphic path to the draw list + * @param dsc pointer to a vector graphic descriptor + * @param path pointer to a path + */ +void lv_vector_dsc_add_path(lv_vector_dsc_t * dsc, const lv_vector_path_t * path); + +/** + * Clear a rectangle area use current fill color + * @param dsc pointer to a vector graphic descriptor + * @param rect the area to clear in the buffer + */ +void lv_vector_clear_area(lv_vector_dsc_t * dsc, const lv_area_t * rect); + +/** + * Draw all the vector graphic paths + * @param dsc pointer to a vector graphic descriptor + */ +void lv_draw_vector(lv_vector_dsc_t * dsc); + +/* Traverser for task list */ +typedef void (*vector_draw_task_cb)(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc); + +#endif /* LV_USE_VECTOR_GRAPHIC */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_DRAW_VECTOR_H */ diff --git a/test/include/liblvgl/draw/lv_draw_vector_private.h b/test/include/liblvgl/draw/lv_draw_vector_private.h new file mode 100644 index 00000000..9257736a --- /dev/null +++ b/test/include/liblvgl/draw/lv_draw_vector_private.h @@ -0,0 +1,109 @@ +/** + * @file lv_draw_vector_private.h + * + */ + +#ifndef LV_DRAW_VECTOR_PRIVATE_H +#define LV_DRAW_VECTOR_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_vector.h" + +#if LV_USE_VECTOR_GRAPHIC + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_vector_path_t { + lv_vector_path_quality_t quality; + lv_array_t ops; + lv_array_t points; +}; + +struct _lv_vector_gradient_t { + lv_vector_gradient_style_t style; + lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ + uint16_t stops_count; /**< The number of used stops in the array */ + float x1; + float y1; + float x2; + float y2; + float cx; + float cy; + float cr; + lv_vector_gradient_spread_t spread; +}; + +struct _lv_vector_fill_dsc_t { + lv_vector_draw_style_t style; + lv_color32_t color; + lv_opa_t opa; + lv_vector_fill_t fill_rule; + lv_draw_image_dsc_t img_dsc; + lv_vector_gradient_t gradient; + lv_matrix_t matrix; +}; + +struct _lv_vector_stroke_dsc_t { + lv_vector_draw_style_t style; + lv_color32_t color; + lv_opa_t opa; + float width; + lv_array_t dash_pattern; + lv_vector_stroke_cap_t cap; + lv_vector_stroke_join_t join; + uint16_t miter_limit; + lv_vector_gradient_t gradient; + lv_matrix_t matrix; +}; + +struct _lv_vector_draw_dsc_t { + lv_vector_fill_dsc_t fill_dsc; + lv_vector_stroke_dsc_t stroke_dsc; + lv_matrix_t matrix; + lv_vector_blend_t blend_mode; + lv_area_t scissor_area; +}; + +struct _lv_draw_vector_task_dsc_t { + lv_draw_dsc_base_t base; + lv_ll_t * task_list; /*draw task list.*/ +}; + +struct _lv_vector_dsc_t { + lv_layer_t * layer; + lv_vector_draw_dsc_t current_dsc; + /* private data */ + lv_draw_vector_task_dsc_t tasks; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_VECTOR_GRAPHIC */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_VECTOR_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/lv_image_decoder.h b/test/include/liblvgl/draw/lv_image_decoder.h new file mode 100644 index 00000000..e898edc9 --- /dev/null +++ b/test/include/liblvgl/draw/lv_image_decoder.h @@ -0,0 +1,194 @@ +/** + * @file lv_image_decoder.h + * + */ + +#ifndef LV_IMAGE_DECODER_H +#define LV_IMAGE_DECODER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include "lv_draw_buf.h" +#include "../misc/lv_fs.h" +#include "../misc/lv_types.h" +#include "../misc/lv_area.h" +#include "../misc/cache/lv_cache.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Source of image.*/ +typedef enum { + LV_IMAGE_SRC_VARIABLE, /** Binary/C variable*/ + LV_IMAGE_SRC_FILE, /** File in filesystem*/ + LV_IMAGE_SRC_SYMBOL, /** Symbol (@ref lv_symbol_def.h)*/ + LV_IMAGE_SRC_UNKNOWN, /** Unknown source*/ +} lv_image_src_t; + +/** + * Get info from an image and store in the `header` + * @param decoder pointer to decoder object + * @param dsc pointer to decoder descriptor + * @param header store the info here + * @return LV_RESULT_OK: info written correctly; LV_RESULT_INVALID: failed + */ +typedef lv_result_t (*lv_image_decoder_info_f_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, + lv_image_header_t * header); + +/** + * Open an image for decoding. Prepare it as it is required to read it later + * @param decoder pointer to the decoder the function associated with + * @param dsc pointer to decoder descriptor. `src`, `color` are already initialized in it. + */ +typedef lv_result_t (*lv_image_decoder_open_f_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); + +/** + * Decode `full_area` pixels incrementally by calling in a loop. Set `decoded_area` values to `LV_COORD_MIN` on first call. + * Required only if the "open" function can't return with the whole decoded pixel array. + * @param decoder pointer to the decoder the function associated with + * @param dsc pointer to decoder descriptor + * @param full_area input parameter. the full area to decode after enough subsequent calls + * @param decoded_area input+output parameter. set the values to `LV_COORD_MIN` for the first call and to reset decoding. + * the decoded area is stored here after each call. + * @return LV_RESULT_OK: ok; LV_RESULT_INVALID: failed or there is nothing left to decode + */ +typedef lv_result_t (*lv_image_decoder_get_area_cb_t)(lv_image_decoder_t * decoder, + lv_image_decoder_dsc_t * dsc, + const lv_area_t * full_area, lv_area_t * decoded_area); + +/** + * Close the pending decoding. Free resources etc. + * @param decoder pointer to the decoder the function associated with + * @param dsc pointer to decoder descriptor + */ +typedef void (*lv_image_decoder_close_f_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get information about an image. + * Try the created image decoder one by one. Once one is able to get info that info will be used. + * @param src the image source. Can be + * 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_drv_register()`) + * 2) Variable: Pointer to an `lv_image_dsc_t` variable + * 3) Symbol: E.g. `LV_SYMBOL_OK` + * @param header the image info will be stored here + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: wasn't able to get info about the image + */ +lv_result_t lv_image_decoder_get_info(const void * src, lv_image_header_t * header); + +/** + * Open an image. + * Try the created image decoders one by one. Once one is able to open the image that decoder is saved in `dsc` + * @param dsc describes a decoding session. Simply a pointer to an `lv_image_decoder_dsc_t` variable. + * @param src the image source. Can be + * 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_drv_register())`) + * 2) Variable: Pointer to an `lv_image_dsc_t` variable + * 3) Symbol: E.g. `LV_SYMBOL_OK` + * @param args args about how the image should be opened. + * @return LV_RESULT_OK: opened the image. `dsc->decoded` and `dsc->header` are set. + * LV_RESULT_INVALID: none of the registered image decoders were able to open the image. + */ +lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src, const lv_image_decoder_args_t * args); + +/** + * Decode `full_area` pixels incrementally by calling in a loop. Set `decoded_area` to `LV_COORD_MIN` on first call. + * @param dsc image decoder descriptor + * @param full_area input parameter. the full area to decode after enough subsequent calls + * @param decoded_area input+output parameter. set the values to `LV_COORD_MIN` for the first call and to reset decoding. + * the decoded area is stored here after each call. + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: an error occurred or there is nothing left to decode + */ +lv_result_t lv_image_decoder_get_area(lv_image_decoder_dsc_t * dsc, const lv_area_t * full_area, + lv_area_t * decoded_area); + +/** + * Close a decoding session + * @param dsc pointer to `lv_image_decoder_dsc_t` used in `lv_image_decoder_open` + */ +void lv_image_decoder_close(lv_image_decoder_dsc_t * dsc); + +/** + * Create a new image decoder + * @return pointer to the new image decoder + */ +lv_image_decoder_t * lv_image_decoder_create(void); + +/** + * Delete an image decoder + * @param decoder pointer to an image decoder + */ +void lv_image_decoder_delete(lv_image_decoder_t * decoder); + +/** + * Get the next image decoder in the linked list of image decoders + * @param decoder pointer to an image decoder or NULL to get the first one + * @return the next image decoder or NULL if no more image decoder exists + */ +lv_image_decoder_t * lv_image_decoder_get_next(lv_image_decoder_t * decoder); + +/** + * Set a callback to get information about the image + * @param decoder pointer to an image decoder + * @param info_cb a function to collect info about an image (fill an `lv_image_header_t` struct) + */ +void lv_image_decoder_set_info_cb(lv_image_decoder_t * decoder, lv_image_decoder_info_f_t info_cb); + +/** + * Set a callback to open an image + * @param decoder pointer to an image decoder + * @param open_cb a function to open an image + */ +void lv_image_decoder_set_open_cb(lv_image_decoder_t * decoder, lv_image_decoder_open_f_t open_cb); + +/** + * Set a callback to a decoded line of an image + * @param decoder pointer to an image decoder + * @param read_line_cb a function to read a line of an image + */ +void lv_image_decoder_set_get_area_cb(lv_image_decoder_t * decoder, lv_image_decoder_get_area_cb_t read_line_cb); + +/** + * Set a callback to close a decoding session. E.g. close files and free other resources. + * @param decoder pointer to an image decoder + * @param close_cb a function to close a decoding session + */ +void lv_image_decoder_set_close_cb(lv_image_decoder_t * decoder, lv_image_decoder_close_f_t close_cb); + +lv_cache_entry_t * lv_image_decoder_add_to_cache(lv_image_decoder_t * decoder, + lv_image_cache_data_t * search_key, + const lv_draw_buf_t * decoded, void * user_data); + +/** + * Check the decoded image, make any modification if decoder `args` requires. + * @note A new draw buf will be allocated if provided `decoded` is not modifiable or stride mismatch etc. + * @param dsc pointer to a decoder descriptor + * @param decoded pointer to a decoded image to post process to meet dsc->args requirement. + * @return post processed draw buffer, when it differs with `decoded`, it's newly allocated. + */ +lv_draw_buf_t * lv_image_decoder_post_process(lv_image_decoder_dsc_t * dsc, lv_draw_buf_t * decoded); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGE_DECODER_H*/ diff --git a/test/include/liblvgl/draw/lv_image_decoder_private.h b/test/include/liblvgl/draw/lv_image_decoder_private.h new file mode 100644 index 00000000..c5bcb0d6 --- /dev/null +++ b/test/include/liblvgl/draw/lv_image_decoder_private.h @@ -0,0 +1,142 @@ +/** + * @file lv_image_decoder_private.h + * + */ + +#ifndef LV_IMAGE_DECODER_PRIVATE_H +#define LV_IMAGE_DECODER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_image_decoder.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Image decoder args. + * It determines how to decoder an image, e.g. whether to premultiply the alpha or not. + * It should be passed to lv_img_decoder_open() function. If NULL is provided, default + * args are used. + * + * Default args: + * all field are zero or false. + */ +struct _lv_image_decoder_args_t { + bool stride_align; /**< Whether stride should be aligned */ + bool premultiply; /**< Whether image should be premultiplied or not after decoding */ + bool no_cache; /**< When set, decoded image won't be put to cache, and decoder open will also ignore cache. */ + bool use_indexed; /**< Decoded indexed image as is. Convert to ARGB8888 if false. */ + bool flush_cache; /**< Whether to flush the data cache after decoding */ +}; + +struct _lv_image_decoder_t { + lv_image_decoder_info_f_t info_cb; + lv_image_decoder_open_f_t open_cb; + lv_image_decoder_get_area_cb_t get_area_cb; + lv_image_decoder_close_f_t close_cb; + + const char * name; + + void * user_data; +}; + +struct _lv_image_cache_data_t { + lv_cache_slot_size_t slot; + + const void * src; + lv_image_src_t src_type; + + const lv_draw_buf_t * decoded; + const lv_image_decoder_t * decoder; + void * user_data; +}; + +struct _lv_image_header_cache_data_t { + const void * src; + lv_image_src_t src_type; + + lv_image_header_t header; + lv_image_decoder_t * decoder; +}; + +/**Describe an image decoding session. Stores data about the decoding*/ +struct _lv_image_decoder_dsc_t { + /**The decoder which was able to open the image source*/ + lv_image_decoder_t * decoder; + + /**A copy of parameters of how this image is decoded*/ + lv_image_decoder_args_t args; + + /**The image source. A file path like "S:my_img.png" or pointer to an `lv_image_dsc_t` variable*/ + const void * src; + + /**Type of the source: file or variable. Can be set in `open` function if required*/ + lv_image_src_t src_type; + + lv_fs_file_t file; + + /**Info about the opened image: color format, size, etc. MUST be set in `open` function*/ + lv_image_header_t header; + + /** Pointer to a draw buffer where the image's data (pixels) are stored in a decoded, plain format. + * MUST be set in `open` or `get_area_cb`function*/ + const lv_draw_buf_t * decoded; + + const lv_color32_t * palette; + uint32_t palette_size; + + /** How much time did it take to open the image. [ms] + * If not set `lv_image_cache` will measure and set the time to open*/ + uint32_t time_to_open; + + /**A text to display instead of the image when the image can't be opened. + * Can be set in `open` function or set NULL.*/ + const char * error_msg; + + lv_cache_t * cache; + + /**Point to cache entry information*/ + lv_cache_entry_t * cache_entry; + + /**Store any custom data here is required*/ + void * user_data; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the image decoder module + * @param image_cache_size Image cache size in bytes. 0 to disable cache. + * @param image_header_count Number of header cache entries. 0 to disable header cache. + */ +void lv_image_decoder_init(uint32_t image_cache_size, uint32_t image_header_count); + +/** + * Deinitialize the image decoder module + */ +void lv_image_decoder_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGE_DECODER_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/lv_image_dsc.h b/test/include/liblvgl/draw/lv_image_dsc.h new file mode 100644 index 00000000..535f72cd --- /dev/null +++ b/test/include/liblvgl/draw/lv_image_dsc.h @@ -0,0 +1,141 @@ +/** + * @file lv_image_dsc.h + * + */ + +#ifndef LV_IMAGE_DSC_H +#define LV_IMAGE_DSC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +/********************* + * DEFINES + *********************/ + +/** Magic number for lvgl image, 9 means lvgl version 9 + * It must be neither a valid ASCII character nor larger than 0x80. See `lv_image_src_get_type`. + */ +#define LV_IMAGE_HEADER_MAGIC (0x19) +LV_EXPORT_CONST_INT(LV_IMAGE_HEADER_MAGIC); + +/********************** + * TYPEDEFS + **********************/ + +typedef enum _lvimage_flags_t { + /** + * For RGB map of the image data, mark if it's pre-multiplied with alpha. + * For indexed image, this bit indicated palette data is pre-multiplied with alpha. + */ + LV_IMAGE_FLAGS_PREMULTIPLIED = 0x0001, + /** + * The image data is compressed, so decoder needs to decode image firstly. + * If this flag is set, the whole image will be decompressed upon decode, and + * `get_area_cb` won't be necessary. + */ + LV_IMAGE_FLAGS_COMPRESSED = 0x0008, + + /*Below flags are applicable only for draw buffer header.*/ + + /** + * The image is allocated from heap, thus should be freed after use. + */ + LV_IMAGE_FLAGS_ALLOCATED = 0x0010, + + /** + * If the image data is malloced and can be processed in place. + * In image decoder post processing, this flag means we modify it in-place. + */ + LV_IMAGE_FLAGS_MODIFIABLE = 0x0020, + + /** + * Flags reserved for user, lvgl won't use these bits. + */ + LV_IMAGE_FLAGS_USER1 = 0x0100, + LV_IMAGE_FLAGS_USER2 = 0x0200, + LV_IMAGE_FLAGS_USER3 = 0x0400, + LV_IMAGE_FLAGS_USER4 = 0x0800, + LV_IMAGE_FLAGS_USER5 = 0x1000, + LV_IMAGE_FLAGS_USER6 = 0x2000, + LV_IMAGE_FLAGS_USER7 = 0x4000, + LV_IMAGE_FLAGS_USER8 = 0x8000, +} lv_image_flags_t; + +typedef enum { + LV_IMAGE_COMPRESS_NONE = 0, + LV_IMAGE_COMPRESS_RLE, /**< LVGL custom RLE compression */ + LV_IMAGE_COMPRESS_LZ4, +} lv_image_compress_t; + +#if LV_BIG_ENDIAN_SYSTEM +typedef struct { + uint32_t reserved_2: 16; /**< Reserved to be used later*/ + uint32_t stride: 16; /**< Number of bytes in a row*/ + uint32_t h: 16; + uint32_t w: 16; + uint32_t flags: 16; /**< Image flags, see `lv_image_flags_t`*/ + uint32_t cf : 8; /**< Color format: See `lv_color_format_t`*/ + uint32_t magic: 8; /**< Magic number. Must be LV_IMAGE_HEADER_MAGIC*/ +} lv_image_header_t; +#else +typedef struct { + uint32_t magic: 8; /**< Magic number. Must be LV_IMAGE_HEADER_MAGIC*/ + uint32_t cf : 8; /**< Color format: See `lv_color_format_t`*/ + uint32_t flags: 16; /**< Image flags, see `lv_image_flags_t`*/ + + uint32_t w: 16; + uint32_t h: 16; + uint32_t stride: 16; /**< Number of bytes in a row*/ + uint32_t reserved_2: 16; /**< Reserved to be used later*/ +} lv_image_header_t; +#endif + +typedef struct { + void * buf; + uint32_t stride; /**< Number of bytes in a row*/ +} lv_yuv_plane_t; + +typedef union { + lv_yuv_plane_t yuv; /**< packed format*/ + struct { + lv_yuv_plane_t y; + lv_yuv_plane_t u; + lv_yuv_plane_t v; + } planar; /**< planar format with 3 plane*/ + struct { + lv_yuv_plane_t y; + lv_yuv_plane_t uv; + } semi_planar; /**< planar format with 2 plane*/ +} lv_yuv_buf_t; + +/** + * Struct to describe a constant image resource. + * It's similar to lv_draw_buf_t, but the data is constant. + */ +typedef struct { + lv_image_header_t header; /**< A header describing the basics of the image*/ + uint32_t data_size; /**< Size of the image in bytes*/ + const uint8_t * data; /**< Pointer to the data of the image*/ + const void * reserved; /**< A reserved field to make it has same size as lv_draw_buf_t*/ +} lv_image_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGE_DSC_H*/ diff --git a/test/include/liblvgl/draw/nema_gfx/lv_draw_nema_gfx.h b/test/include/liblvgl/draw/nema_gfx/lv_draw_nema_gfx.h new file mode 100644 index 00000000..e455bb77 --- /dev/null +++ b/test/include/liblvgl/draw/nema_gfx/lv_draw_nema_gfx.h @@ -0,0 +1,122 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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 lv_draw_nema_gfx.h + * + */ + +#ifndef LV_DRAW_NEMA_GFX_H +#define LV_DRAW_NEMA_GFX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_NEMA_GFX + +#include "lv_draw_nema_gfx_utils.h" + +#include "../lv_draw_private.h" +#include "../lv_draw_buf_private.h" +#include "../lv_draw_image_private.h" +#include "../lv_image_decoder_private.h" +#include "../lv_draw_label_private.h" +#include "../lv_draw_mask_private.h" +#include "../lv_draw_rect_private.h" +#include "../lv_draw_triangle_private.h" +#include "../lv_draw_vector_private.h" + +#include "../../misc/lv_area_private.h" + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + lv_draw_unit_t base_unit; + lv_draw_task_t * task_act; +#if LV_USE_OS + lv_thread_sync_t sync; + lv_thread_t thread; + volatile bool inited; + volatile bool exit_status; +#endif + uint32_t idx; + nema_cmdlist_t cl; +#if LV_USE_NEMA_VG + NEMA_VG_PAINT_HANDLE paint; + NEMA_VG_GRAD_HANDLE gradient; + NEMA_VG_PATH_HANDLE path; +#endif +} lv_draw_nema_gfx_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_nema_gfx_init(void); + +void lv_draw_nema_gfx_deinit(void); + +void lv_draw_nema_gfx_fill(lv_draw_unit_t * draw_unit, + const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_nema_gfx_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc); + +void lv_draw_nema_gfx_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_nema_gfx_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_nema_gfx_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); + +void lv_draw_nema_gfx_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); + +void lv_draw_nema_gfx_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_nema_gfx_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, + const lv_area_t * coords); + + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_NEMA_GFX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_NEMA_GFX_H*/ \ No newline at end of file diff --git a/test/include/liblvgl/draw/nema_gfx/lv_draw_nema_gfx_utils.h b/test/include/liblvgl/draw/nema_gfx/lv_draw_nema_gfx_utils.h new file mode 100644 index 00000000..f77807a1 --- /dev/null +++ b/test/include/liblvgl/draw/nema_gfx/lv_draw_nema_gfx_utils.h @@ -0,0 +1,125 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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 lv_draw_nema_gfx.h + * + */ + +#ifndef LV_DRAW_NEMA_GFX_UTILS_H +#define LV_DRAW_NEMA_GFX_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_NEMA_GFX +#include "../sw/lv_draw_sw.h" + +#include "nema_core.h" +#include "nema_utils.h" +#include "nema_error.h" +#include "nema_provisional.h" +#include "nema_vg.h" + +/********************* + * DEFINES + *********************/ + +#ifndef NEMA_VIRT2PHYS +#define NEMA_VIRT2PHYS +#else +uintptr_t NEMA_VIRT2PHYS(void * addr); +#endif + +/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/ +#if LV_COLOR_DEPTH == 8 +#define LV_NEMA_GFX_COLOR_FORMAT NEMA_L8 +#define LV_NEMA_GFX_FORMAT_MULTIPLIER 1 +#elif LV_COLOR_DEPTH == 16 +#define LV_NEMA_GFX_COLOR_FORMAT NEMA_RGB565 +#define LV_NEMA_GFX_FORMAT_MULTIPLIER 2 +#elif LV_COLOR_DEPTH == 24 +#define LV_NEMA_GFX_COLOR_FORMAT NEMA_BGR24 +#define LV_NEMA_GFX_FORMAT_MULTIPLIER 3 +#elif LV_COLOR_DEPTH == 32 +#define LV_NEMA_GFX_COLOR_FORMAT NEMA_BGRA8888 +#define LV_NEMA_GFX_FORMAT_MULTIPLIER 4 +#else +/*Can't use GPU with other formats*/ +#error Selected Color Depth Not Supported +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Convert a `lv_color_format_t` to a Nema color format. + * @param cf The LVGL color format + * @return The Nema color format + */ +uint32_t lv_nemagfx_cf_to_nema(lv_color_format_t cf); + +/** + * Get NemaGFX blending mode + * + * @param[in] lv_blend_mode The LVGL blend mode + * + * @return NemaGFX blending mode + * + */ +uint32_t lv_nemagfx_blending_mode(lv_blend_mode_t lv_blend_mode); + + +/** + * Get NemaGFX blending mode + * + * @param[in] gradient NemaGFX Gradient Buffer + * + * @param[in] lv_grad Gradient descripto + * + * @param[in] opa Descriptor's opacity + * +*/ +void lv_nemagfx_grad_set(NEMA_VG_GRAD_HANDLE gradient, lv_grad_dsc_t lv_grad, lv_opa_t opa); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_NEMA_GFX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_NEMA_GFX_UTILS_H*/ \ No newline at end of file diff --git a/test/include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h b/test/include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h new file mode 100644 index 00000000..d34ad3f8 --- /dev/null +++ b/test/include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h @@ -0,0 +1,75 @@ +/** + * @file lv_draw_pxp.h + * + */ + +/** + * Copyright 2022-2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_DRAW_PXP_H +#define LV_DRAW_PXP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP +#include "../../sw/lv_draw_sw_private.h" +#include "../../../misc/lv_area_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef lv_draw_sw_unit_t lv_draw_pxp_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_pxp_init(void); + +void lv_draw_pxp_deinit(void); + +void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width, int32_t src_height, + int32_t src_stride, int32_t dest_stride, lv_display_rotation_t rotation, + lv_color_format_t cf); + +#if LV_USE_DRAW_PXP +void lv_draw_buf_pxp_init_handlers(void); + +void lv_draw_pxp_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_pxp_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); + +/********************** + * MACROS + **********************/ +#endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_PXP_H*/ diff --git a/test/include/liblvgl/draw/nxp/pxp/lv_pxp_cfg.h b/test/include/liblvgl/draw/nxp/pxp/lv_pxp_cfg.h new file mode 100644 index 00000000..67d13585 --- /dev/null +++ b/test/include/liblvgl/draw/nxp/pxp/lv_pxp_cfg.h @@ -0,0 +1,104 @@ +/** + * @file lv_pxp_cfg.h + * + */ + +/** + * Copyright 2020-2023 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_PXP_CFG_H +#define LV_PXP_CFG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP +#include "fsl_cache.h" +#include "fsl_pxp.h" + +#include "../../../misc/lv_log.h" + +/********************* + * DEFINES + *********************/ + +/** PXP module instance to use*/ +#define PXP_ID PXP + +/** PXP interrupt line ID*/ +#define PXP_IRQ_ID PXP_IRQn + +/********************** + * TYPEDEFS + **********************/ + +/** + * NXP PXP device configuration. + */ +typedef struct { + /** Callback for PXP interrupt initialization*/ + void (*pxp_interrupt_init)(void); + + /** Callback for PXP interrupt de-initialization*/ + void (*pxp_interrupt_deinit)(void); + + /** Callback for PXP start*/ + void (*pxp_run)(void); + + /** Callback for waiting of PXP completion*/ + void (*pxp_wait)(void); +} pxp_cfg_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Reset and initialize PXP device. This function should be called as a part + * of display init sequence. + */ +void lv_pxp_init(void); + +/** + * Disable PXP device. Should be called during display deinit sequence. + */ +void lv_pxp_deinit(void); + +/** + * Reset PXP device. + */ +void lv_pxp_reset(void); + +/** + * Clear cache and start PXP. + */ +void lv_pxp_run(void); + +/** + * Wait for PXP completion. + */ +void lv_pxp_wait(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_PXP_CFG_H*/ diff --git a/test/include/liblvgl/draw/nxp/pxp/lv_pxp_osa.h b/test/include/liblvgl/draw/nxp/pxp/lv_pxp_osa.h new file mode 100644 index 00000000..5e3d6669 --- /dev/null +++ b/test/include/liblvgl/draw/nxp/pxp/lv_pxp_osa.h @@ -0,0 +1,62 @@ +/** + * @file lv_pxp_osa.h + * + */ + +/** + * Copyright 2020, 2022-2023 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_PXP_OSA_H +#define LV_PXP_OSA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP +#include "lv_pxp_cfg.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * PXP device interrupt handler. Used to check PXP task completion status. + */ +void PXP_IRQHandler(void); + +/** + * Get the PXP default configuration. + */ +pxp_cfg_t * pxp_get_default_cfg(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_PXP_OSA_H*/ diff --git a/test/include/liblvgl/draw/nxp/pxp/lv_pxp_utils.h b/test/include/liblvgl/draw/nxp/pxp/lv_pxp_utils.h new file mode 100644 index 00000000..c9ba7baf --- /dev/null +++ b/test/include/liblvgl/draw/nxp/pxp/lv_pxp_utils.h @@ -0,0 +1,84 @@ +/** + * @file lv_pxp_utils.h + * + */ + +/** + * Copyright 2023-2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_PXP_UTILS_H +#define LV_PXP_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP +#include "fsl_pxp.h" +#include "../../../misc/lv_color.h" + +/********************* + * DEFINES + *********************/ + +#if LV_USE_PXP_ASSERT +#define PXP_ASSERT(expr) LV_ASSERT(expr) +#else +#define PXP_ASSERT(expr) +#endif + +#define PXP_ASSERT_MSG(expr, msg) \ + do { \ + if(!(expr)) { \ + LV_LOG_ERROR(msg); \ + PXP_ASSERT(false); \ + } \ + } while(0) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +pxp_output_pixel_format_t pxp_get_out_px_format(lv_color_format_t cf); + +pxp_as_pixel_format_t pxp_get_as_px_format(lv_color_format_t cf); + +#if LV_USE_DRAW_PXP +pxp_ps_pixel_format_t pxp_get_ps_px_format(lv_color_format_t cf); + +bool pxp_buf_aligned(const void * buf, uint32_t stride); + +/********************** + * MACROS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_PXP_UTILS_H*/ diff --git a/test/include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h b/test/include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h new file mode 100644 index 00000000..93b18cd7 --- /dev/null +++ b/test/include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h @@ -0,0 +1,86 @@ +/** + * @file lv_draw_vglite.h + * + */ + +/** + * Copyright 2023-2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_DRAW_VGLITE_H +#define LV_DRAW_VGLITE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_DRAW_VGLITE +#include "../../lv_draw_private.h" +#include "../../sw/lv_draw_sw_private.h" +#include "../../../misc/lv_area_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct lv_draw_vglite_unit { + lv_draw_sw_unit_t; +#if LV_USE_VGLITE_DRAW_ASYNC + volatile bool wait_for_finish; +#endif +} lv_draw_vglite_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_buf_vglite_init_handlers(void); + +void lv_draw_vglite_init(void); + +void lv_draw_vglite_deinit(void); + +void lv_draw_vglite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_vglite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_vglite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_vglite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_vglite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); + +void lv_draw_vglite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); + +void lv_draw_vglite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc); + +/********************** + * MACROS + **********************/ +#endif /*LV_USE_DRAW_VGLITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_VGLITE_H*/ diff --git a/test/include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h b/test/include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h new file mode 100644 index 00000000..3ef43474 --- /dev/null +++ b/test/include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h @@ -0,0 +1,124 @@ +/** + * @file lv_vglite_buf.h + * + */ + +/** + * Copyright 2023 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_VGLITE_BUF_H +#define LV_VGLITE_BUF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_DRAW_VGLITE +#include "../../sw/lv_draw_sw.h" + +#include "vg_lite.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get vglite destination buffer pointer. + * + * @retval The vglite destination buffer + * + */ +vg_lite_buffer_t * vglite_get_dest_buf(void); + +/** + * Get vglite source buffer pointer. + * + * @retval The vglite source buffer + * + */ +vg_lite_buffer_t * vglite_get_src_buf(void); + +/** + * Set vglite destination buffer address only. + * + * @param[in] buf Destination buffer address (does not require alignment for VG_LITE_LINEAR mode) + * + */ +void vglite_set_dest_buf_ptr(void * buf); + +/** + * Set vglite source buffer address only. + * + * @param[in] buf Source buffer address + * + */ +void vglite_set_src_buf_ptr(const void * buf); + +/** + * Set vglite destination buffer. + * + * @param[in] buf Destination buffer address + * @param[in] width Destination buffer width + * @param[in] height Destination buffer height + * @param[in] stride Destination buffer stride in bytes + * @param[in] cf Destination buffer color format + * + */ +void vglite_set_dest_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride, + lv_color_format_t cf); + +/** + * Set vglite source buffer. + * + * @param[in] buf Source buffer address + * @param[in] width Source buffer width + * @param[in] height Source buffer height + * @param[in] stride Source buffer stride in bytes + * @param[in] cf Source buffer color format + * + */ +void vglite_set_src_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride, + lv_color_format_t cf); + +/** + * Set vglite buffer. + * + * @param[in] vgbuf Address of the VGLite buffer object + * @param[in] buf Address of the memory for the VGLite buffer + * @param[in] width Buffer width + * @param[in] height Buffer height + * @param[in] stride Buffer stride in bytes + * @param[in] cf Buffer color format + * + */ +void vglite_set_buf(vg_lite_buffer_t * vgbuf, void * buf, + uint32_t width, uint32_t height, uint32_t stride, + lv_color_format_t cf); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VGLITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VGLITE_BUF_H*/ diff --git a/test/include/liblvgl/draw/nxp/vglite/lv_vglite_matrix.h b/test/include/liblvgl/draw/nxp/vglite/lv_vglite_matrix.h new file mode 100644 index 00000000..832cd86b --- /dev/null +++ b/test/include/liblvgl/draw/nxp/vglite/lv_vglite_matrix.h @@ -0,0 +1,78 @@ +/** + * @file lv_vglite_matrix.h + * + */ + +/** + * Copyright 2023 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_VGLITE_MATRIX_H +#define LV_VGLITE_MATRIX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_DRAW_VGLITE +#include "../../sw/lv_draw_sw.h" + +#include "vg_lite.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +vg_lite_matrix_t * vglite_get_matrix(void); + +/** + * Creates matrix that translates to origin of given destination area. + * + * @param[in] dest_area Area with relative coordinates of destination buffer + * + */ +void vglite_set_translation_matrix(const lv_area_t * dest_area); + +/** + * Creates matrix that translates to origin of given destination area with transformation (scale or rotate). + * + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dsc Image descriptor + * + */ +void vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_DRAW_VGLITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VGLITE_MATRIX_H*/ diff --git a/test/include/liblvgl/draw/nxp/vglite/lv_vglite_path.h b/test/include/liblvgl/draw/nxp/vglite/lv_vglite_path.h new file mode 100644 index 00000000..f38593ae --- /dev/null +++ b/test/include/liblvgl/draw/nxp/vglite/lv_vglite_path.h @@ -0,0 +1,97 @@ +/** + * @file lv_vglite_path.h + * + */ + +/** + * Copyright 2023 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_VGLITE_PATH_H +#define LV_VGLITE_PATH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_DRAW_VGLITE +#include "../../sw/lv_draw_sw.h" + +/********************* + * DEFINES + *********************/ + +/* The optimal Bezier control point offset for radial unit + * see: https://spencermortensen.com/articles/bezier-circle/ + **/ +#define BEZIER_OPTIM_CIRCLE 0.551915024494f + +/* Draw lines for control points of Bezier curves */ +#define BEZIER_DBG_CONTROL_POINTS 0 + +/* Path data sizes for different elements */ +#define CUBIC_PATH_DATA_SIZE 7 /* 1 opcode, 6 arguments */ +#define LINE_PATH_DATA_SIZE 3 /* 1 opcode, 2 arguments */ +#define MOVE_PATH_DATA_SIZE 3 /* 1 opcode, 2 arguments */ +#define END_PATH_DATA_SIZE 1 /* 1 opcode, 0 arguments */ +/* Maximum possible rectangle path size + * is in the rounded rectangle case: + * - 1 move for the path start + * - 4 cubics for the corners + * - 4 lines for the sides + * - 1 end for the path end */ +#define RECT_PATH_DATA_MAX_SIZE (1 * MOVE_PATH_DATA_SIZE + 4 * CUBIC_PATH_DATA_SIZE + 4 * LINE_PATH_DATA_SIZE + 1 * END_PATH_DATA_SIZE) + +/* Maximum possible arc path size + * is in the rounded arc case: + * - 1 move for the path start + * - 16 cubics for the arc (5 inner, 5 outer) and corners (3 per corner) + * - 1 end for the path end */ +#define ARC_PATH_DATA_MAX_SIZE (1 * MOVE_PATH_DATA_SIZE + 16 * CUBIC_PATH_DATA_SIZE + 1 * END_PATH_DATA_SIZE) +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Generates path data for rectangle drawing. + * + * @param[in/out] path The path data to initialize + * @param[in/out] path_size The resulting size of the created path data + * @param[in] dsc The style descriptor for the rectangle to be drawn + * @param[in] coords The coordinates of the rectangle to be drawn + * + */ +void vglite_create_rect_path_data(int32_t * path_data, uint32_t * path_data_size, + int32_t radius, + const lv_area_t * coords); + +/********************** + * MACROS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_DRAW_VGLITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VGLITE_PATH_H*/ diff --git a/test/include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h b/test/include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h new file mode 100644 index 00000000..6615c4c7 --- /dev/null +++ b/test/include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h @@ -0,0 +1,179 @@ +/** + * @file lv_vglite_utils.h + * + */ + +/** + * Copyright 2022-2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_VGLITE_UTILS_H +#define LV_VGLITE_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_DRAW_VGLITE +#include "../../sw/lv_draw_sw.h" + +#include "vg_lite.h" +#include "vg_lite_options.h" + +/********************* + * DEFINES + *********************/ + +#define ENUM_TO_STRING(e) \ + case (e): \ + return #e + +#if LV_USE_VGLITE_ASSERT +#define VGLITE_ASSERT(expr) LV_ASSERT(expr) +#else +#define VGLITE_ASSERT(expr) +#endif + +#define VGLITE_ASSERT_MSG(expr, msg) \ + do { \ + if(!(expr)) { \ + LV_LOG_ERROR(msg); \ + VGLITE_ASSERT(false); \ + } \ + } while(0) + +#define VGLITE_CHECK_ERROR(function) \ + do { \ + vg_lite_error_t error = function; \ + if(error != VG_LITE_SUCCESS) { \ + LV_LOG_ERROR("Execute '" #function "' error(%d): %s", \ + (int)error, vglite_error_to_string(error)); \ + VGLITE_ASSERT(false); \ + } \ + } while (0) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/** + * Set the clipping box. + * + * @param[in] clip_area Clip area with relative coordinates of destination buffer + * + */ +static inline void vglite_set_scissor(const lv_area_t * clip_area); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +const char * vglite_error_to_string(vg_lite_error_t error); + +#if LV_USE_VGLITE_DRAW_ASYNC +/** + * Get VG-Lite command buffer flushed status. + * + */ +bool vglite_cmd_buf_is_flushed(void); +#endif + +/** + * Flush command to VG-Lite. + * + */ +void vglite_run(void); + +/** + * Wait for VG-Lite finish. + * + */ +#if LV_USE_VGLITE_DRAW_ASYNC +void vglite_wait_for_finish(void); +#endif + +/** + * Get vglite color. Premultiplies (if not hw already) and swizzles the given + * LVGL 32bit color to obtain vglite color. + * + * @param[in] lv_col32 The initial LVGL 32bit color + * @param[in] gradient True for gradient color + * + * @retval The vglite 32-bit color value: + * + */ +vg_lite_color_t vglite_get_color(lv_color32_t lv_col32, bool gradient); + +/** + * Get vglite blend mode. + * + * @param[in] lv_blend_mode The LVGL blend mode + * + * @retval The vglite blend mode + * + */ +vg_lite_blend_t vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode); + +/** + * Get vglite buffer format. + * + * @param[in] cf Color format + * + * @retval The vglite buffer format + * + */ +vg_lite_buffer_format_t vglite_get_buf_format(lv_color_format_t cf); + +/** + * Get vglite stride alignment. + * + * @param[in] cf Color format + * + * @retval Alignment requirement in bytes + * + */ +uint8_t vglite_get_stride_alignment(lv_color_format_t cf); + +/** + * Check source start address and stride alignment. + * + * @param[in] buf Buffer address + * @param[in] stride Stride of buffer in bytes + * @param[in] cf Color format - to calculate the expected alignment + * + * @retval true Alignment OK + * + */ +bool vglite_src_buf_aligned(const void * buf, uint32_t stride, lv_color_format_t cf); + +/********************** + * MACROS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static inline void vglite_set_scissor(const lv_area_t * clip_area) +{ + vg_lite_set_scissor(clip_area->x1, clip_area->y1, clip_area->x2 + 1, clip_area->y2 + 1); +} + +#endif /*LV_USE_DRAW_VGLITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VGLITE_UTILS_H*/ diff --git a/test/include/liblvgl/draw/opengles/lv_draw_opengles.h b/test/include/liblvgl/draw/opengles/lv_draw_opengles.h new file mode 100644 index 00000000..1285c93e --- /dev/null +++ b/test/include/liblvgl/draw/opengles/lv_draw_opengles.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_opengles.h + * + */ + +#ifndef LV_DRAW_OPENGLES_H +#define LV_DRAW_OPENGLES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_OPENGLES + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_opengles_init(void); +void lv_draw_opengles_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_OPENGLES*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_OPENGLES_H*/ diff --git a/test/include/liblvgl/draw/renesas/dave2d/lv_draw_dave2d.h b/test/include/liblvgl/draw/renesas/dave2d/lv_draw_dave2d.h new file mode 100644 index 00000000..3a52289a --- /dev/null +++ b/test/include/liblvgl/draw/renesas/dave2d/lv_draw_dave2d.h @@ -0,0 +1,105 @@ +/** + * @file lv_draw_dave2d.h + * + */ + +#ifndef LV_DRAW_DAVE2D_H +#define LV_DRAW_DAVE2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" +#if LV_USE_DRAW_DAVE2D +#include "../../lv_draw.h" +#include "../../lv_draw_private.h" +#include "hal_data.h" +#include "lv_draw_dave2d_utils.h" +#include "../../lv_draw_rect.h" +#include "../../lv_draw_line.h" +#include "../../lv_draw_arc.h" +#include "../../lv_draw_label.h" +#include "../../lv_draw_image.h" +#include "../../lv_draw_triangle.h" +#include "../../lv_draw_buf.h" + + +/********************* + * DEFINES + *********************/ + +#define D2_RENDER_EACH_OPERATION (1) + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_draw_unit_t base_unit; + lv_draw_task_t * task_act; +#if LV_USE_OS + lv_thread_sync_t sync; + lv_thread_t thread; +#endif + uint32_t idx; + d2_device * d2_handle; + d2_renderbuffer * renderbuffer; +#if LV_USE_OS + lv_mutex_t * pd2Mutex; +#endif +} lv_draw_dave2d_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_dave2d_init(void); + +void lv_draw_dave2d_image(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); + +void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_dave2d_border(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_dave2d_box_shadow(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_dave2d_label(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); + +void lv_draw_dave2d_layer(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); + +void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc); + +void lv_draw_dave2d_mask_rect(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_dave2d_transform(lv_draw_dave2d_unit_t * draw_unit, const lv_area_t * dest_area, const void * src_buf, + int32_t src_w, int32_t src_h, int32_t src_stride, + const lv_draw_image_dsc_t * draw_dsc, const lv_draw_image_sup_t * sup, lv_color_format_t cf, void * dest_buf); + +/*********************** + * GLOBAL VARIABLES + ***********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_DAVE2D*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_USE_DRAW_DAVE2D*/ diff --git a/test/include/liblvgl/draw/renesas/dave2d/lv_draw_dave2d_utils.h b/test/include/liblvgl/draw/renesas/dave2d/lv_draw_dave2d_utils.h new file mode 100644 index 00000000..67c51026 --- /dev/null +++ b/test/include/liblvgl/draw/renesas/dave2d/lv_draw_dave2d_utils.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_dave2d_utils.h + * + */ + +#ifndef LV_DRAW_DAVE2D_UTILS_H +#define LV_DRAW_DAVE2D_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +d2_color lv_draw_dave2d_lv_colour_to_d2_colour(lv_color_t color); + +d2_s32 lv_draw_dave2d_cf_fb_get(void); + +d2_u32 lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(lv_color_format_t colour_format); + +void d2_framebuffer_from_layer(d2_device * handle, lv_layer_t * layer); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_DAVE2D_UTILS_H*/ diff --git a/test/include/liblvgl/draw/sdl/lv_draw_sdl.h b/test/include/liblvgl/draw/sdl/lv_draw_sdl.h new file mode 100644 index 00000000..cb370a1b --- /dev/null +++ b/test/include/liblvgl/draw/sdl/lv_draw_sdl.h @@ -0,0 +1,87 @@ +/** + * @file lv_draw_sdl.h + * + */ + +#ifndef LV_DRAW_SDL_H +#define LV_DRAW_SDL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw.h" + +#if LV_USE_DRAW_SDL + +#include "../../misc/cache/lv_cache.h" +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" +#include "../../display/lv_display.h" +#include "../../osal/lv_os.h" +#include "../../draw/lv_draw_label.h" +#include "../../draw/lv_draw_rect.h" +#include "../../draw/lv_draw_arc.h" +#include "../../draw/lv_draw_image.h" +#include "../../draw/lv_draw_triangle.h" +#include "../../draw/lv_draw_line.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_draw_unit_t base_unit; + lv_draw_task_t * task_act; + lv_cache_t * texture_cache; +} lv_draw_sdl_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_sdl_init(void); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sdl_image(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); + +void lv_draw_sdl_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_sdl_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_sdl_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_sdl_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_sdl_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sdl_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); + +void lv_draw_sdl_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords); + +void lv_draw_sdl_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc); + +void lv_draw_sdl_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc, const lv_area_t * coords); + +/*********************** + * GLOBAL VARIABLES + ***********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SDL*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SDL_H*/ diff --git a/test/include/liblvgl/draw/sw/arm2d/lv_draw_sw_arm2d.h b/test/include/liblvgl/draw/sw/arm2d/lv_draw_sw_arm2d.h new file mode 100644 index 00000000..77c6cc4d --- /dev/null +++ b/test/include/liblvgl/draw/sw/arm2d/lv_draw_sw_arm2d.h @@ -0,0 +1,589 @@ +/** + * @file lv_draw_sw_arm2d.h + * + */ + +#ifndef LV_DRAW_SW_ARM2D_H +#define LV_DRAW_SW_ARM2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* *INDENT-OFF* */ + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" +#include "../../../misc/lv_area_private.h" + +#if LV_USE_DRAW_ARM2D_SYNC + +#define __ARM_2D_IMPL__ +#include "arm_2d.h" +#include "__arm_2d_impl.h" + +#if defined(__IS_COMPILER_ARM_COMPILER_5__) +#pragma diag_suppress 174,177,188,68,513,144,1296 +#elif defined(__IS_COMPILER_IAR__) +#pragma diag_suppress=Pa093 +#elif defined(__IS_COMPILER_GCC__) +#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" +#endif + +/********************* + * DEFINES + *********************/ +#ifndef LV_DRAW_SW_RGB565_SWAP + #define LV_DRAW_SW_RGB565_SWAP(__buf_ptr, __buf_size_px) \ + lv_draw_sw_rgb565_swap_helium((__buf_ptr), (__buf_size_px)) +#endif + +#ifndef LV_DRAW_SW_IMAGE + #define LV_DRAW_SW_IMAGE(__transformed, \ + __cf, \ + __src_buf, \ + __img_coords, \ + __src_stride, \ + __blend_area, \ + __draw_unit, \ + __draw_dsc) \ + lv_draw_sw_image_helium( (__transformed), \ + (__cf), \ + (uint8_t *)(__src_buf), \ + (__img_coords), \ + (__src_stride), \ + (__blend_area), \ + (__draw_unit), \ + (__draw_dsc)) +#endif + +#ifndef LV_DRAW_SW_RGB565_RECOLOR + #define LV_DRAW_SW_RGB565_RECOLOR(__src_buf, __blend_area, __color, __opa) \ + lv_draw_sw_image_recolor_rgb565( (__src_buf), \ + &(__blend_area), \ + (__color), \ + (__opa)) +#endif + +#ifndef LV_DRAW_SW_RGB888_RECOLOR + #define LV_DRAW_SW_RGB888_RECOLOR( __src_buf, \ + __blend_area, \ + __color, \ + __opa, \ + __cf) \ + lv_draw_sw_image_recolor_rgb888( (__src_buf), \ + &(__blend_area), \ + (__color), \ + (__opa), \ + (__cf)) +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +extern void arm_2d_helper_swap_rgb16(uint16_t * phwBuffer, uint32_t wCount); + +/********************** + * MACROS + **********************/ + +#define __RECOLOUR_BEGIN() \ + do { \ + lv_color_t *rgb_tmp_buf = NULL; \ + if(draw_dsc->recolor_opa > LV_OPA_MIN) { \ + if(LV_COLOR_FORMAT_RGB565 == des_cf) { \ + rgb_tmp_buf \ + = lv_malloc(src_w * src_h * sizeof(uint16_t)); \ + if (NULL == rgb_tmp_buf) { \ + LV_LOG_WARN( \ + "Failed to allocate memory for accelerating recolor, " \ + "use normal route instead."); \ + break; \ + } \ + lv_memcpy( rgb_tmp_buf, \ + src_buf, \ + src_w * src_h * sizeof(uint16_t)); \ + arm_2d_size_t copy_size = { \ + .iWidth = src_w, \ + .iHeight = src_h, \ + }; \ + /* apply re-color */ \ + __arm_2d_impl_rgb565_colour_filling_with_opacity( \ + (uint16_t *)rgb_tmp_buf, \ + src_w, \ + ©_size, \ + lv_color_to_u16(draw_dsc->recolor), \ + draw_dsc->recolor_opa); \ + \ + /* replace src_buf for the following operation */ \ + src_buf = (const uint8_t *)rgb_tmp_buf; \ + } \ + else if(LV_COLOR_FORMAT_XRGB8888 == des_cf) { \ + rgb_tmp_buf \ + = lv_malloc(src_w * src_h * sizeof(uint32_t)); \ + if (NULL == rgb_tmp_buf) { \ + LV_LOG_WARN( \ + "Failed to allocate memory for accelerating recolor, " \ + "use normal route instead."); \ + break; \ + } \ + lv_memcpy( rgb_tmp_buf, \ + src_buf, \ + src_w * src_h * sizeof(uint32_t)); \ + arm_2d_size_t copy_size = { \ + .iWidth = src_w, \ + .iHeight = src_h, \ + }; \ + /* apply re-color */ \ + __arm_2d_impl_cccn888_colour_filling_with_opacity( \ + (uint32_t *)rgb_tmp_buf, \ + src_w, \ + ©_size, \ + lv_color_to_u32(draw_dsc->recolor), \ + draw_dsc->recolor_opa); \ + \ + /* replace src_buf for the following operation */ \ + src_buf = (const uint8_t *)rgb_tmp_buf; \ + } \ + } \ + do { + +#define __RECOLOUR_END() \ + } while(0); \ + if (NULL != rgb_tmp_buf) { \ + lv_free(rgb_tmp_buf); \ + } \ + } while(0); + +static inline lv_result_t lv_draw_sw_rgb565_swap_helium(void * buf, uint32_t buf_size_px) +{ + arm_2d_helper_swap_rgb16((uint16_t *)buf, buf_size_px); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_draw_sw_image_helium( + bool is_transform, + lv_color_format_t src_cf, + const uint8_t *src_buf, + const lv_area_t * coords, + int32_t src_stride, + const lv_area_t * des_area, + lv_draw_unit_t * draw_unit, + const lv_draw_image_dsc_t * draw_dsc) +{ + lv_result_t result = LV_RESULT_INVALID; + lv_layer_t * layer = draw_unit->target_layer; + lv_color_format_t des_cf = layer->color_format; + static bool arm_2d_initialized = false; + + if (!arm_2d_initialized) { + arm_2d_initialized = true; + arm_2d_init(); + } + + do { + if (!is_transform) { + break; + } + if(draw_dsc->scale_x != draw_dsc->scale_y) { + break; + } + /* filter the unsupported colour format combination */ + if((LV_COLOR_FORMAT_RGB565 == des_cf) + && !( (LV_COLOR_FORMAT_RGB565 == src_cf) + || (LV_COLOR_FORMAT_RGB565A8 == src_cf))) { + break; + } + #if 0 /* a temporary patch */ + if((LV_COLOR_FORMAT_XRGB8888 == des_cf) + && !( (LV_COLOR_FORMAT_ARGB8888 == src_cf) + || (LV_COLOR_FORMAT_XRGB8888 == src_cf))) { + break; + } + #else + if((LV_COLOR_FORMAT_XRGB8888 == des_cf) + || (LV_COLOR_FORMAT_RGB888 == des_cf) + || (LV_COLOR_FORMAT_ARGB8888 == des_cf)) { + break; + } + #endif + + /* ------------- prepare parameters for arm-2d APIs - BEGIN --------- */ + + lv_area_t blend_area; + if(!lv_area_intersect(&blend_area, des_area, draw_unit->clip_area)) { + break; + } + + int32_t src_w = lv_area_get_width(coords); + int32_t src_h = lv_area_get_height(coords); + + arm_2d_size_t src_size = { + .iWidth = (int16_t)src_w, + .iHeight = (int16_t)src_h, + }; + +// arm_2d_size_t des_size; + +// do{ +// int32_t des_w = lv_area_get_width(&blend_area); +// int32_t des_h = lv_area_get_height(&blend_area); + +// LV_ASSERT(des_w <= INT16_MAX); +// LV_ASSERT(des_h <= INT16_MAX); + +// des_size.iWidth = (int16_t)des_w; +// des_size.iHeight = (int16_t)des_h; +// } while(0); +// +// arm_2d_size_t copy_size = { +// .iWidth = MIN(des_size.iWidth, src_size.iWidth), +// .iHeight = MIN(des_size.iHeight, src_size.iHeight), +// }; +// +// int32_t des_stride = lv_draw_buf_width_to_stride( +// lv_area_get_width(&layer->buf_area), +// des_cf); +// uint8_t *des_buf_moved = (uint8_t *)lv_draw_layer_go_to_xy( +// layer, +// blend_area.x1 - layer->buf_area.x1, +// blend_area.y1 - layer->buf_area.y1); + uint8_t *des_buf = (uint8_t *)lv_draw_layer_go_to_xy(layer, 0, 0); + uint8_t opa = draw_dsc->opa; + + /* ------------- prepare parameters for arm-2d APIs - END ----------- */ + __RECOLOUR_BEGIN() + + static arm_2d_tile_t target_tile_origin; + static arm_2d_tile_t target_tile; + arm_2d_region_t clip_region; + static arm_2d_region_t target_region; + + target_region = (arm_2d_region_t) { + .tLocation = { + .iX = (int16_t)(coords->x1 - draw_unit->clip_area->x1), + .iY = (int16_t)(coords->y1 - draw_unit->clip_area->y1), + }, + .tSize = src_size, + }; + + target_tile_origin = (arm_2d_tile_t) { + .tRegion = { + .tSize = { + .iWidth = (int16_t)lv_area_get_width(&layer->buf_area), + .iHeight = (int16_t)lv_area_get_height(&layer->buf_area), + }, + }, + .tInfo = { + .bIsRoot = true, + }, + .phwBuffer = (uint16_t *)des_buf, + }; + + clip_region = (arm_2d_region_t) { + .tLocation = { + .iX = (int16_t)(draw_unit->clip_area->x1 - layer->buf_area.x1), + .iY = (int16_t)(draw_unit->clip_area->y1 - layer->buf_area.y1), + }, + .tSize = { + .iWidth = (int16_t)lv_area_get_width(draw_unit->clip_area), + .iHeight = (int16_t)lv_area_get_height(draw_unit->clip_area), + }, + }; + + arm_2d_tile_generate_child(&target_tile_origin, + &clip_region, + &target_tile, + false); + + static arm_2d_tile_t source_tile; + + source_tile = (arm_2d_tile_t) { + .tRegion = { + .tSize = { + .iWidth = (int16_t)src_w, + .iHeight = (int16_t)src_h, + }, + }, + .tInfo = { + .bIsRoot = true, + }, + .pchBuffer = (uint8_t *)src_buf, + }; + + static arm_2d_location_t source_center, target_center; + source_center.iX = draw_dsc->pivot.x; + source_center.iY = draw_dsc->pivot.y; + target_center = target_region.tLocation; + target_center.iX += draw_dsc->pivot.x; + target_center.iY += draw_dsc->pivot.y; + + if(LV_COLOR_FORMAT_A8 == src_cf) { + + source_tile.tInfo.bHasEnforcedColour = true; + source_tile.tInfo.tColourInfo.chScheme = ARM_2D_COLOUR_GRAY8; + + if(LV_COLOR_FORMAT_RGB565 == des_cf) { + + arm_2d_rgb565_fill_colour_with_mask_opacity_and_transform( + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + lv_color_to_u16(draw_dsc->recolor), + opa, + &target_center + ); + + } + else if(LV_COLOR_FORMAT_XRGB8888 == des_cf) { + arm_2d_cccn888_fill_colour_with_mask_opacity_and_transform( + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + lv_color_to_int(draw_dsc->recolor), + opa, + &target_center + ); + } + else { + break; + } + + } + else if(LV_COLOR_FORMAT_RGB565A8 == src_cf) { + LV_ASSERT(LV_COLOR_FORMAT_RGB565 == des_cf); + + /* mask_buf = src_buf + src_stride * src_w / header->w * src_h; */ + const uint8_t *mask_buf = src_buf + src_stride * src_h; + int32_t mask_stride = src_stride / 2; + + static arm_2d_tile_t mask_tile; + mask_tile = source_tile; + + mask_tile.tInfo.bHasEnforcedColour = true; + mask_tile.tInfo.tColourInfo.chScheme = ARM_2D_COLOUR_GRAY8; + mask_tile.pchBuffer = (uint8_t *)mask_buf; + + if(opa >= LV_OPA_MAX) { + arm_2d_rgb565_tile_transform_with_src_mask( + &source_tile, + &mask_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + &target_center + ); + } + else { + arm_2d_rgb565_tile_transform_with_src_mask_and_opacity( + &source_tile, + &mask_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + opa, + &target_center + ); + } + + } + else if(LV_COLOR_FORMAT_RGB565 == src_cf) { + LV_ASSERT(LV_COLOR_FORMAT_RGB565 == des_cf); + + if(opa >= LV_OPA_MAX) { + #if ARM_2D_VERSION >= 10106 + arm_2d_rgb565_tile_transform_only( + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + &target_center); + #else + + arm_2dp_rgb565_tile_transform_only_prepare( + NULL, + &source_tile, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + (float)(draw_dsc->scale_x / 256.0f)); + + arm_2dp_tile_transform(NULL, + &target_tile, + NULL, + &target_center); + #endif + } + else { + arm_2d_rgb565_tile_transform_only_with_opacity( + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + opa, + &target_center + ); + } + + } + #if 0 /* a temporary patch */ + else if(LV_COLOR_FORMAT_ARGB8888 == src_cf) { + LV_ASSERT(LV_COLOR_FORMAT_XRGB8888 == des_cf); + + static arm_2d_tile_t mask_tile; + mask_tile = source_tile; + + mask_tile.tInfo.bHasEnforcedColour = true; + mask_tile.tInfo.tColourInfo.chScheme = ARM_2D_CHANNEL_8in32; + mask_tile.pchBuffer = (uint8_t *)src_buf + 3; + + if(opa >= LV_OPA_MAX) { + arm_2d_cccn888_tile_transform_with_src_mask( + &source_tile, + &mask_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + &target_center + ); + } + else { + arm_2d_cccn888_tile_transform_with_src_mask_and_opacity( + &source_tile, + &mask_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + opa, + &target_center + ); + } + + } + else if(LV_COLOR_FORMAT_XRGB8888 == src_cf) { + LV_ASSERT(LV_COLOR_FORMAT_XRGB8888 == des_cf); + + if(opa >= LV_OPA_MAX) { + arm_2d_cccn888_tile_transform_only( + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + &target_center + ); + } + else { + arm_2d_cccn888_tile_transform_only_with_opacity( + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + opa, + &target_center + ); + } + + } + #endif + else { + break; + } + + result = LV_RESULT_OK; + + __RECOLOUR_END() + } while(0); + + return result; +} + +static inline lv_result_t lv_draw_sw_image_recolor_rgb565( + const uint8_t *src_buf, + const lv_area_t * blend_area, + lv_color_t color, + lv_opa_t opa) +{ + int32_t src_w = lv_area_get_width(blend_area); + int32_t src_h = lv_area_get_height(blend_area); + + arm_2d_size_t copy_size = { + .iWidth = (int16_t)src_w, + .iHeight = (int16_t)src_h, + }; + + __arm_2d_impl_rgb565_colour_filling_with_opacity( + (uint16_t *)src_buf, + src_w, + ©_size, + lv_color_to_u16(color), + opa); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_draw_sw_image_recolor_rgb888( + const uint8_t *src_buf, + const lv_area_t * blend_area, + lv_color_t color, + lv_opa_t opa, + lv_color_format_t src_cf) +{ + if(LV_COLOR_FORMAT_XRGB8888 != src_cf) { + return LV_RESULT_INVALID; + } + + int32_t src_w = lv_area_get_width(blend_area); + int32_t src_h = lv_area_get_height(blend_area); + + arm_2d_size_t copy_size = { + .iWidth = (int16_t)src_w, + .iHeight = (int16_t)src_h, + }; + + __arm_2d_impl_cccn888_colour_filling_with_opacity( + (uint32_t *)src_buf, + src_w, + ©_size, + lv_color_to_u32(color), + opa); + + return LV_RESULT_OK; +} + +#endif /* LV_USE_DRAW_ARM2D_SYNC */ + +/* *INDENT-ON* */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_ARM2D_H */ diff --git a/test/include/liblvgl/draw/sw/arm2d/lv_draw_sw_helium.h b/test/include/liblvgl/draw/sw/arm2d/lv_draw_sw_helium.h new file mode 100644 index 00000000..c35a06eb --- /dev/null +++ b/test/include/liblvgl/draw/sw/arm2d/lv_draw_sw_helium.h @@ -0,0 +1,60 @@ +/** + * @file lv_draw_sw_helium.h + * + */ + +#ifndef LV_DRAW_SW_HELIUM_H +#define LV_DRAW_SW_HELIUM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* *INDENT-OFF* */ + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +/* detect whether helium is available based on arm compilers' standard */ +#if defined(__ARM_FEATURE_MVE) && __ARM_FEATURE_MVE + +#ifdef LV_DRAW_SW_HELIUM_CUSTOM_INCLUDE +#include LV_DRAW_SW_HELIUM_CUSTOM_INCLUDE +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************* + * POST INCLUDES + *********************/ +/* use arm-2d as the default helium acceleration */ +#include "lv_draw_sw_arm2d.h" + +#endif /* defined(__ARM_FEATURE_MVE) && __ARM_FEATURE_MVE */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_HELIUM_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/arm2d/lv_blend_arm2d.h b/test/include/liblvgl/draw/sw/blend/arm2d/lv_blend_arm2d.h new file mode 100644 index 00000000..0eb29b85 --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/arm2d/lv_blend_arm2d.h @@ -0,0 +1,937 @@ +/** + * @file lv_blend_arm2d.h + * + */ + +#ifndef LV_BLEND_ARM2D_H +#define LV_BLEND_ARM2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../../lv_conf_internal.h" + +#if LV_USE_DRAW_ARM2D_SYNC + +#define __ARM_2D_IMPL__ +#include "arm_2d.h" +#include "__arm_2d_impl.h" + +#if defined(__IS_COMPILER_ARM_COMPILER_5__) +#pragma diag_suppress 174,177,188,68,513,144,1296 +#elif defined(__IS_COMPILER_IAR__) +#pragma diag_suppress=Pa093 +#elif defined(__IS_COMPILER_GCC__) +#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" +#endif + + +#if ARM_2D_VERSION < 10106ul +#error Please upgrade to Arm-2D v1.1.6 or above +#endif + +#ifndef LV_ARM2D_XRGB888_ALPHA_ALWAYS_FF +#define LV_ARM2D_XRGB888_ALPHA_ALWAYS_FF 1 +#endif + +/********************* + * DEFINES + *********************/ + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565 +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565(dsc) \ + lv_color_blend_to_rgb565_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA(dsc) \ + lv_color_blend_to_rgb565_with_opa_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK(dsc) \ + lv_color_blend_to_rgb565_with_mask_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA(dsc) \ + lv_color_blend_to_rgb565_mix_mask_opa_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(dsc) \ + lv_rgb565_blend_normal_to_rgb565_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ + lv_rgb565_blend_normal_to_rgb565_with_opa_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ + lv_rgb565_blend_normal_to_rgb565_with_mask_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ + lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_arm2d(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_with_opa_arm2d(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_with_mask_arm2d(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_arm2d(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565(dsc) \ + lv_argb8888_blend_normal_to_rgb565_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ + lv_argb8888_blend_normal_to_rgb565_with_opa_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ + lv_argb8888_blend_normal_to_rgb565_with_mask_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ + lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_arm2d(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888 +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_with_opa_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_with_mask_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_with_opa_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_with_mask_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_arm2d(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_with_opa_arm2d(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_with_mask_arm2d(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_with_opa_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_with_mask_arm2d(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size) +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +static inline lv_result_t lv_color_blend_to_rgb565_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t stride = (dsc->dest_stride) / sizeof(uint16_t); + __arm_2d_impl_rgb16_colour_filling((uint16_t *)dsc->dest_buf, + stride, + &draw_size, + lv_color_to_u16(dsc->color)); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_color_blend_to_rgb565_with_opa_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t stride = (dsc->dest_stride) / sizeof(uint16_t); + __arm_2d_impl_rgb565_colour_filling_with_opacity((uint16_t *)dsc->dest_buf, + stride, + &draw_size, + lv_color_to_u16(dsc->color), + dsc->opa); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_color_blend_to_rgb565_with_mask_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t stride = (dsc->dest_stride) / sizeof(uint16_t); + __arm_2d_impl_rgb565_colour_filling_mask((uint16_t *)dsc->dest_buf, + stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + lv_color_to_u16(dsc->color)); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_color_blend_to_rgb565_mix_mask_opa_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t stride = (dsc->dest_stride) / sizeof(uint16_t); + __arm_2d_impl_rgb565_colour_filling_mask_opacity((uint16_t *)dsc->dest_buf, + stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + lv_color_to_u16(dsc->color), + dsc->opa); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) +{ + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint16_t); + __arm_2d_impl_rgb16_copy((uint16_t *)dsc->src_buf, + src_stride, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint16_t); + __arm_2d_impl_rgb565_tile_copy_opacity((uint16_t *)dsc->src_buf, + src_stride, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint16_t); + __arm_2d_impl_rgb565_src_msk_copy((uint16_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint16_t); + + __arm_2d_impl_rgb565_tile_copy_with_src_mask_and_opacity((uint16_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + if(src_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, + src_stride, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + if(src_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + uint16_t * tmp_buf = (uint16_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); + if(NULL == tmp_buf) { + return LV_RESULT_INVALID; + } + +#if !LV_ARM2D_XRGB888_ALPHA_ALWAYS_FF + __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, + src_stride, + (uint16_t *)tmp_buf, + des_stride, + &draw_size); + + __arm_2d_impl_rgb565_tile_copy_opacity(tmp_buf, + des_stride, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); +#else + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); +#endif + lv_free(tmp_buf); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + if(src_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + uint16_t * tmp_buf = (uint16_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); + if(NULL == tmp_buf) { + return LV_RESULT_INVALID; + } + +#if !LV_ARM2D_XRGB888_ALPHA_ALWAYS_FF + __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, + src_stride, + (uint16_t *)tmp_buf, + des_stride, + &draw_size); + + __arm_2d_impl_rgb565_src_msk_copy(tmp_buf, + des_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size); +#else + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_src_mask((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size); +#endif + + lv_free(tmp_buf); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + if(src_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + uint16_t * tmp_buf = (uint16_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); + if(NULL == tmp_buf) { + return LV_RESULT_INVALID; + } + +#if !LV_ARM2D_XRGB888_ALPHA_ALWAYS_FF + __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, + src_stride, + (uint16_t *)tmp_buf, + des_stride, + &draw_size); + + __arm_2d_impl_rgb565_tile_copy_with_src_mask_and_opacity(tmp_buf, + des_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); +#else + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_src_mask_and_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); +#endif + + lv_free(tmp_buf); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_ccca8888_to_rgb565((uint32_t *)dsc->src_buf, + src_stride, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_src_mask((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) +{ + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_src_mask_and_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_color_blend_to_rgb888_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) +{ + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t stride = (dsc->dest_stride) / sizeof(uint32_t); + __arm_2d_impl_rgb32_colour_filling((uint32_t *)dsc->dest_buf, + stride, + &draw_size, + lv_color_to_u32(dsc->color)); + return LV_RESULT_OK; + +} + +static inline lv_result_t lv_color_blend_to_rgb888_with_opa_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t stride = (dsc->dest_stride) / sizeof(uint32_t); + __arm_2d_impl_cccn888_colour_filling_with_opacity((uint32_t *)dsc->dest_buf, + stride, + &draw_size, + lv_color_to_u32(dsc->color), + dsc->opa); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_color_blend_to_rgb888_with_mask_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t stride = (dsc->dest_stride) / sizeof(uint32_t); + __arm_2d_impl_cccn888_colour_filling_mask((uint32_t *)dsc->dest_buf, + stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + lv_color_to_u32(dsc->color)); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_color_blend_to_rgb888_mix_mask_opa_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t stride = (dsc->dest_stride) / sizeof(uint32_t); + __arm_2d_impl_cccn888_colour_filling_mask_opacity((uint32_t *)dsc->dest_buf, + stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + lv_color_to_u32(dsc->color), + dsc->opa); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint16_t); + + __arm_2d_impl_rgb565_to_cccn888((uint16_t *)dsc->src_buf, + src_stride, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size); + + return LV_RESULT_OK; + +} + +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint16_t); + + uint32_t * tmp_buf = (uint32_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); + if(NULL == tmp_buf) { + return LV_RESULT_INVALID; + } + + /* get rgb565 */ + __arm_2d_impl_rgb565_to_cccn888((uint16_t *)dsc->src_buf, + src_stride, + (uint32_t *)tmp_buf, + des_stride, + &draw_size); + + __arm_2d_impl_cccn888_tile_copy_opacity(tmp_buf, + des_stride, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + + lv_free(tmp_buf); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint16_t); + + uint32_t * tmp_buf = (uint32_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); + if(NULL == tmp_buf) { + return LV_RESULT_INVALID; + } + + __arm_2d_impl_rgb565_to_cccn888((uint16_t *)dsc->src_buf, + src_stride, + (uint32_t *)tmp_buf, + des_stride, + &draw_size); + + __arm_2d_impl_cccn888_src_msk_copy(tmp_buf, + des_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size); + + lv_free(tmp_buf); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint16_t); + + uint32_t * tmp_buf = (uint32_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); + if(NULL == tmp_buf) { + return LV_RESULT_INVALID; + } + + __arm_2d_impl_rgb565_to_cccn888((uint16_t *)dsc->src_buf, + src_stride, + (uint32_t *)tmp_buf, + des_stride, + &draw_size); + + __arm_2d_impl_cccn888_tile_copy_with_src_mask_and_opacity(tmp_buf, + des_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + + lv_free(tmp_buf); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, + uint32_t src_px_size) +{ + if((dst_px_size == 3) || (src_px_size == 3)) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_rgb32_copy((uint32_t *)dsc->src_buf, + src_stride, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + if((dst_px_size == 3) || (src_px_size == 3)) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_cccn888_tile_copy_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + if((dst_px_size == 3) || (src_px_size == 3)) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_cccn888_src_msk_copy((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + if((dst_px_size == 3) || (src_px_size == 3)) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_cccn888_tile_copy_with_src_mask_and_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_ccca8888_to_cccn888((uint32_t *)dsc->src_buf, + src_stride, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_ccca8888_tile_copy_to_cccn888_with_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_ccca8888_tile_copy_to_cccn888_with_src_mask((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_ccca8888_tile_copy_to_cccn888_with_src_mask_and_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + + return LV_RESULT_OK; +} + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DRAW_ARM2D_SYNC */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BLEND_ARM2D_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/helium/lv_blend_helium.h b/test/include/liblvgl/draw/sw/blend/helium/lv_blend_helium.h new file mode 100644 index 00000000..69b999ef --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/helium/lv_blend_helium.h @@ -0,0 +1,1313 @@ +/** + * @file lv_blend_helium.h + * + */ + +#ifndef LV_BLEND_HELIUM_H +#define LV_BLEND_HELIUM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#if defined(_RTE_) +#include "Pre_Include_Global.h" +#include "lv_conf_cmsis.h" +#endif + +#include "../../../../lv_conf_internal.h" + +/* detect whether helium is available based on arm compilers' standard */ +#if defined(__ARM_FEATURE_MVE) && __ARM_FEATURE_MVE + +#ifdef LV_DRAW_SW_HELIUM_CUSTOM_INCLUDE +#include LV_DRAW_SW_HELIUM_CUSTOM_INCLUDE +#endif + +#if !defined(__ASSEMBLY__) + +/* Use arm2d functions if present */ +#include "../arm2d/lv_blend_arm2d.h" + +/********************* + * DEFINES + *********************/ + +#if LV_USE_NATIVE_HELIUM_ASM + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565 +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565(dsc) \ + lv_color_blend_to_rgb565_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA(dsc) \ + lv_color_blend_to_rgb565_with_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK(dsc) \ + lv_color_blend_to_rgb565_with_mask_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA(dsc) \ + lv_color_blend_to_rgb565_mix_mask_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(dsc) \ + lv_rgb565_blend_normal_to_rgb565_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ + lv_rgb565_blend_normal_to_rgb565_with_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ + lv_rgb565_blend_normal_to_rgb565_with_mask_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ + lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_helium(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_with_opa_helium(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_with_mask_helium(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565(dsc) \ + lv_argb8888_blend_normal_to_rgb565_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ + lv_argb8888_blend_normal_to_rgb565_with_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ + lv_argb8888_blend_normal_to_rgb565_with_mask_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ + lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888 +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_with_opa_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_with_mask_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_with_opa_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_with_mask_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_helium(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_with_opa_helium(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_with_mask_helium(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_with_opa_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_with_mask_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888 +#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888(dsc) \ + lv_color_blend_to_argb8888_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_OPA(dsc) \ + lv_color_blend_to_argb8888_with_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_MASK +#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_MASK(dsc) \ + lv_color_blend_to_argb8888_with_mask_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA(dsc) \ + lv_color_blend_to_argb8888_mix_mask_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888 +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888(dsc) \ + lv_rgb565_blend_normal_to_argb8888_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc) \ + lv_rgb565_blend_normal_to_argb8888_with_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc) \ + lv_rgb565_blend_normal_to_argb8888_with_mask_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc) \ + lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888 +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_argb8888_helium(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_argb8888_with_opa_helium(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_argb8888_with_mask_helium(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888 +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888(dsc) \ + lv_argb8888_blend_normal_to_argb8888_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc) \ + lv_argb8888_blend_normal_to_argb8888_with_opa_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc) \ + lv_argb8888_blend_normal_to_argb8888_with_mask_helium(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc) \ + lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(dsc) +#endif + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint32_t opa; + void * dst_buf; + uint32_t dst_w; + uint32_t dst_h; + uint32_t dst_stride; + const void * src_buf; + uint32_t src_stride; + const lv_opa_t * mask_buf; + uint32_t mask_stride; +} asm_dsc_t; +/********************** + * GLOBAL PROTOTYPES + **********************/ + +extern void lv_color_blend_to_rgb565_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_helium(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + + lv_color_blend_to_rgb565_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_rgb565_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_with_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + lv_color_blend_to_rgb565_with_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_rgb565_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_with_mask_helium(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_color_blend_to_rgb565_with_mask_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_color_blend_to_rgb565_mix_mask_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + lv_rgb565_blend_normal_to_rgb565_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + lv_rgb565_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_rgb565_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_rgb565_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_rgb565_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + lv_argb8888_blend_normal_to_rgb565_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + lv_argb8888_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_argb8888_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_rgb888_helium(asm_dsc_t * dsc); +extern void lv_color_blend_to_xrgb8888_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_helium(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + if(dst_px_size == 3) { + lv_color_blend_to_rgb888_helium(&asm_dsc); + } + else { + lv_color_blend_to_xrgb8888_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_rgb888_with_opa_helium(asm_dsc_t * dsc); +extern void lv_color_blend_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_with_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + if(dst_px_size == 3) { + lv_color_blend_to_rgb888_with_opa_helium(&asm_dsc); + } + else { + lv_color_blend_to_xrgb8888_with_opa_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_rgb888_with_mask_helium(asm_dsc_t * dsc); +extern void lv_color_blend_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_with_mask_helium(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + lv_color_blend_to_rgb888_with_mask_helium(&asm_dsc); + } + else { + lv_color_blend_to_xrgb8888_with_mask_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern void lv_color_blend_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + lv_color_blend_to_rgb888_mix_mask_opa_helium(&asm_dsc); + } + else { + lv_color_blend_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); +extern void lv_rgb565_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + lv_rgb565_blend_normal_to_rgb888_helium(&asm_dsc); + } + else { + lv_rgb565_blend_normal_to_xrgb8888_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); +extern void lv_rgb565_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + lv_rgb565_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); + } + else { + lv_rgb565_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); +extern void lv_rgb565_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + lv_rgb565_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); + } + else { + lv_rgb565_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern void lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); + } + else { + lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); +extern void lv_rgb888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_rgb888_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_rgb888_helium(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_xrgb8888_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_xrgb8888_helium(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); +extern void lv_rgb888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); +extern void lv_rgb888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern void lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); +extern void lv_argb8888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + lv_argb8888_blend_normal_to_rgb888_helium(&asm_dsc); + } + else { + lv_argb8888_blend_normal_to_xrgb8888_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); +extern void lv_argb8888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + lv_argb8888_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); + } + else { + lv_argb8888_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); +extern void lv_argb8888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + lv_argb8888_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); + } + else { + lv_argb8888_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern void lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); + } + else { + lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_argb8888_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_helium(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + + lv_color_blend_to_argb8888_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_argb8888_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_with_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + lv_color_blend_to_argb8888_with_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_argb8888_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_with_mask_helium(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_color_blend_to_argb8888_with_mask_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_color_blend_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_color_blend_to_argb8888_mix_mask_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + lv_rgb565_blend_normal_to_argb8888_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + lv_rgb565_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_rgb565_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_argb8888_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_argb8888_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern void lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(src_px_size == 3) { + lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); + } + else { + lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + lv_argb8888_blend_normal_to_argb8888_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + lv_argb8888_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_argb8888_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); + return LV_RESULT_OK; +} + +extern void lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); + return LV_RESULT_OK; +} + +#endif /* LV_USE_NATIVE_HELIUM_ASM */ + +#endif /* !defined(__ASSEMBLY__) */ + +#endif /* defined(__ARM_FEATURE_MVE) && __ARM_FEATURE_MVE */ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BLEND_HELIUM_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend.h b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend.h new file mode 100644 index 00000000..1528cacc --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend.h @@ -0,0 +1,52 @@ +/** + * @file lv_draw_sw_blend.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_H +#define LV_DRAW_SW_BLEND_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw_sw_mask.h" +#if LV_USE_DRAW_SW + +#include "../../../misc/lv_color.h" +#include "../../../misc/lv_area.h" +#include "../../../misc/lv_style.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Call the blend function of the `layer`. + * @param draw_unit pointer to a draw unit + * @param dsc pointer to an initialized blend descriptor + */ +void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_private.h b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_private.h new file mode 100644 index 00000000..731f9ad0 --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_private.h @@ -0,0 +1,92 @@ +/** + * @file lv_draw_sw_blend_private.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_PRIVATE_H +#define LV_DRAW_SW_BLEND_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_sw_blend.h" + +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_draw_sw_blend_dsc_t { + const lv_area_t * blend_area; /**< The area with absolute coordinates to draw on `layer->buf` + * will be clipped to `layer->clip_area` */ + const void * src_buf; /**< Pointer to an image to blend. If set `fill_color` is ignored */ + uint32_t src_stride; + lv_color_format_t src_color_format; + const lv_area_t * src_area; + lv_opa_t opa; /**< The overall opacity*/ + lv_color_t color; /**< Fill color*/ + const lv_opa_t * mask_buf; /**< NULL if ignored, or an alpha mask to apply on `blend_area`*/ + lv_draw_sw_mask_res_t mask_res; /**< The result of the previous mask operation */ + const lv_area_t * mask_area; /**< The area of `mask_buf` with absolute coordinates*/ + int32_t mask_stride; + lv_blend_mode_t blend_mode; /**< E.g. LV_BLEND_MODE_ADDITIVE*/ +}; + +struct _lv_draw_sw_blend_fill_dsc_t { + void * dest_buf; + int32_t dest_w; + int32_t dest_h; + int32_t dest_stride; + const lv_opa_t * mask_buf; + int32_t mask_stride; + lv_color_t color; + lv_opa_t opa; + lv_area_t relative_area; +}; + +struct _lv_draw_sw_blend_image_dsc_t { + void * dest_buf; + int32_t dest_w; + int32_t dest_h; + int32_t dest_stride; + const lv_opa_t * mask_buf; + int32_t mask_stride; + const void * src_buf; + int32_t src_stride; + lv_color_format_t src_color_format; + lv_opa_t opa; + lv_blend_mode_t blend_mode; + lv_area_t relative_area; /**< The blend area relative to the layer's buffer area. */ + lv_area_t src_area; /**< The original src area. */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DRAW_SW */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_al88.h b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_al88.h new file mode 100644 index 00000000..63197c91 --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_al88.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_sw_blend_to_al88.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_AL88_H +#define LV_DRAW_SW_BLEND_TO_AL88_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw_sw.h" +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_al88(lv_draw_sw_blend_fill_dsc_t * dsc); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_al88(lv_draw_sw_blend_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_TO_AL88_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_argb8888.h b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_argb8888.h new file mode 100644 index 00000000..2046c23f --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_argb8888.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_sw_blend_to_argb8888.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_ARGB8888_H +#define LV_DRAW_SW_BLEND_TO_ARGB8888_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw_sw.h" +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_argb8888(lv_draw_sw_blend_fill_dsc_t * dsc); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_argb8888(lv_draw_sw_blend_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_TO_ARGB8888_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_i1.h b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_i1.h new file mode 100644 index 00000000..5d72523d --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_i1.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_sw_blend_to_i1.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_I1_H +#define LV_DRAW_SW_BLEND_TO_I1_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw_sw.h" +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_i1(lv_draw_sw_blend_fill_dsc_t * dsc); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_i1(lv_draw_sw_blend_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_TO_I1_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_l8.h b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_l8.h new file mode 100644 index 00000000..04f4b44a --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_l8.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_sw_blend_to_l8.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_L8_H +#define LV_DRAW_SW_BLEND_TO_L8_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw_sw.h" +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_l8(lv_draw_sw_blend_fill_dsc_t * dsc); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_l8(lv_draw_sw_blend_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_TO_L8_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_rgb565.h b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_rgb565.h new file mode 100644 index 00000000..d14bfd94 --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_rgb565.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_sw_blend_to_rgb565.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_RGB565_H +#define LV_DRAW_SW_BLEND_TO_RGB565_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw_sw.h" +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_rgb565(lv_draw_sw_blend_fill_dsc_t * dsc); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_TO_RGB565_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_rgb888.h b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_rgb888.h new file mode 100644 index 00000000..441c0d3e --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_rgb888.h @@ -0,0 +1,47 @@ +/** + * @file lv_draw_sw_blend_to_rgb888.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_RGB888_H +#define LV_DRAW_SW_BLEND_TO_RGB888_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw_sw.h" +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_rgb888(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dest_px_size); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dest_px_size); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_TO_RGB888_H*/ diff --git a/test/include/liblvgl/draw/sw/blend/neon/lv_blend_neon.h b/test/include/liblvgl/draw/sw/blend/neon/lv_blend_neon.h new file mode 100644 index 00000000..fd52647b --- /dev/null +++ b/test/include/liblvgl/draw/sw/blend/neon/lv_blend_neon.h @@ -0,0 +1,1301 @@ +/** + * @file lv_blend_neon.h + * + */ + +#ifndef LV_BLEND_NEON_H +#define LV_BLEND_NEON_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../../lv_conf_internal.h" + +#ifdef LV_DRAW_SW_NEON_CUSTOM_INCLUDE +#include LV_DRAW_SW_NEON_CUSTOM_INCLUDE +#endif + +/********************* + * DEFINES + *********************/ +#if !defined(__ASSEMBLY__) + +#if __GNUC__ >= 4 +#define LVGL_HIDDEN __attribute__((visibility("hidden"))) +#else +#define LVGL_HIDDEN +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565 +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565(dsc) \ + lv_color_blend_to_rgb565_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA(dsc) \ + lv_color_blend_to_rgb565_with_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK(dsc) \ + lv_color_blend_to_rgb565_with_mask_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA(dsc) \ + lv_color_blend_to_rgb565_mix_mask_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(dsc) \ + lv_rgb565_blend_normal_to_rgb565_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ + lv_rgb565_blend_normal_to_rgb565_with_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ + lv_rgb565_blend_normal_to_rgb565_with_mask_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ + lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_neon(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_with_opa_neon(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_with_mask_neon(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565(dsc) \ + lv_argb8888_blend_normal_to_rgb565_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ + lv_argb8888_blend_normal_to_rgb565_with_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ + lv_argb8888_blend_normal_to_rgb565_with_mask_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ + lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888 +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_with_opa_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_with_mask_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ + lv_color_blend_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ + lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_neon(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size, src_px_size) \ + lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ + lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888 +#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888(dsc) \ + lv_color_blend_to_argb8888_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_OPA(dsc) \ + lv_color_blend_to_argb8888_with_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_MASK +#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_MASK(dsc) \ + lv_color_blend_to_argb8888_with_mask_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA(dsc) \ + lv_color_blend_to_argb8888_mix_mask_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888 +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888(dsc) \ + lv_rgb565_blend_normal_to_argb8888_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc) \ + lv_rgb565_blend_normal_to_argb8888_with_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc) \ + lv_rgb565_blend_normal_to_argb8888_with_mask_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc) \ + lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888 +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_argb8888_neon(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_argb8888_with_opa_neon(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_argb8888_with_mask_neon(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc, src_px_size) \ + lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888 +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888(dsc) \ + lv_argb8888_blend_normal_to_argb8888_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc) \ + lv_argb8888_blend_normal_to_argb8888_with_opa_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc) \ + lv_argb8888_blend_normal_to_argb8888_with_mask_neon(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc) \ + lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(dsc) +#endif + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint32_t opa; + void * dst_buf; + uint32_t dst_w; + uint32_t dst_h; + uint32_t dst_stride; + const void * src_buf; + uint32_t src_stride; + const lv_opa_t * mask_buf; + uint32_t mask_stride; +} asm_dsc_t; +/********************** + * GLOBAL PROTOTYPES + **********************/ + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + + _lv_color_blend_to_rgb565_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_with_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + _lv_color_blend_to_rgb565_with_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_with_mask_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_color_blend_to_rgb565_with_mask_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_color_blend_to_rgb565_mix_mask_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_rgb565_blend_normal_to_rgb565_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_rgb565_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_rgb565_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb565_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb565_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_argb8888_blend_normal_to_rgb565_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_argb8888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_argb8888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_neon(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + if(dst_px_size == 3) { + _lv_color_blend_to_rgb888_neon(&asm_dsc); + } + else { + _lv_color_blend_to_xrgb8888_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_with_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + if(dst_px_size == 3) { + _lv_color_blend_to_rgb888_with_opa_neon(&asm_dsc); + } + else { + _lv_color_blend_to_xrgb8888_with_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_with_mask_neon(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_color_blend_to_rgb888_with_mask_neon(&asm_dsc); + } + else { + _lv_color_blend_to_xrgb8888_with_mask_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_color_blend_to_rgb888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_color_blend_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + _lv_rgb565_blend_normal_to_rgb888_neon(&asm_dsc); + } + else { + _lv_rgb565_blend_normal_to_xrgb8888_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + _lv_rgb565_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); + } + else { + _lv_rgb565_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_rgb565_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); + } + else { + _lv_rgb565_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb888_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb888_neon(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_xrgb8888_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_xrgb8888_neon(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + _lv_argb8888_blend_normal_to_rgb888_neon(&asm_dsc); + } + else { + _lv_argb8888_blend_normal_to_xrgb8888_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + _lv_argb8888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); + } + else { + _lv_argb8888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_argb8888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); + } + else { + _lv_argb8888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + + _lv_color_blend_to_argb8888_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_with_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + _lv_color_blend_to_argb8888_with_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_with_mask_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_color_blend_to_argb8888_with_mask_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_color_blend_to_argb8888_mix_mask_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_rgb565_blend_normal_to_argb8888_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_rgb565_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_rgb565_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_argb8888_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_argb8888_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_argb8888_blend_normal_to_argb8888_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_argb8888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_argb8888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +#endif /* !defined(__ASSEMBLY__) */ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BLEND_NEON_H*/ diff --git a/test/include/liblvgl/draw/sw/lv_draw_sw.h b/test/include/liblvgl/draw/sw/lv_draw_sw.h new file mode 100644 index 00000000..1152fe58 --- /dev/null +++ b/test/include/liblvgl/draw/sw/lv_draw_sw.h @@ -0,0 +1,204 @@ +/** + * @file lv_draw_sw.h + * + */ + +#ifndef LV_DRAW_SW_H +#define LV_DRAW_SW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw.h" +#if LV_USE_DRAW_SW + +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" +#include "../../display/lv_display.h" +#include "../../osal/lv_os.h" + +#include "../lv_draw_vector.h" +#include "../lv_draw_triangle.h" +#include "../lv_draw_label.h" +#include "../lv_draw_image.h" +#include "../lv_draw_line.h" +#include "../lv_draw_arc.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the SW renderer. Called in internally. + * It creates as many SW renderers as defined in LV_DRAW_SW_DRAW_UNIT_CNT + */ +void lv_draw_sw_init(void); + +/** + * Deinitialize the SW renderers + */ +void lv_draw_sw_deinit(void); + +/** + * Fill an area using SW render. Handle gradient and radius. + * @param draw_unit pointer to a draw unit + * @param dsc the draw descriptor + * @param coords the coordinates of the rectangle + */ +void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); + +/** + * Draw border with SW render. + * @param draw_unit pointer to a draw unit + * @param dsc the draw descriptor + * @param coords the coordinates of the rectangle + */ +void lv_draw_sw_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords); + +/** + * Draw box shadow with SW render. + * @param draw_unit pointer to a draw unit + * @param dsc the draw descriptor + * @param coords the coordinates of the rectangle for which the box shadow should be drawn + */ +void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords); + +/** + * Draw an image with SW render. It handles image decoding, tiling, transformations, and recoloring. + * @param draw_unit pointer to a draw unit + * @param draw_dsc the draw descriptor + * @param coords the coordinates of the image + */ +void lv_draw_sw_image(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); + +/** + * Draw a label with SW render. + * @param draw_unit pointer to a draw unit + * @param dsc the draw descriptor + * @param coords the coordinates of the label + */ +void lv_draw_sw_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords); + +/** + * Draw an arc with SW render. + * @param draw_unit pointer to a draw unit + * @param dsc the draw descriptor + * @param coords the coordinates of the arc + */ +void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); + +/** + * Draw a line with SW render. + * @param draw_unit pointer to a draw unit + * @param dsc the draw descriptor + */ +void lv_draw_sw_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); + +/** + * Blend a layer with SW render + * @param draw_unit pointer to a draw unit + * @param draw_dsc the draw descriptor + * @param coords the coordinates of the layer + */ +void lv_draw_sw_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords); + +/** + * Draw a triangle with SW render. + * @param draw_unit pointer to a draw unit + * @param dsc the draw descriptor + */ +void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc); + +/** + * Mask out a rectangle with radius from a current layer + * @param draw_unit pointer to a draw unit + * @param dsc the draw descriptor + * @param coords the coordinates of the mask + */ +void lv_draw_sw_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc, const lv_area_t * coords); + +/** + * Used internally to get a transformed are of an image + * @param draw_unit pointer to a draw unit + * @param dest_area area to calculate, i.e. get this area from the transformed image + * @param src_buf source buffer + * @param src_w source buffer width in pixels + * @param src_h source buffer height in pixels + * @param src_stride source buffer stride in bytes + * @param draw_dsc draw descriptor + * @param sup supplementary data + * @param cf color format of the source buffer + * @param dest_buf the destination buffer + */ +void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_area, const void * src_buf, + int32_t src_w, int32_t src_h, int32_t src_stride, + const lv_draw_image_dsc_t * draw_dsc, const lv_draw_image_sup_t * sup, lv_color_format_t cf, void * dest_buf); + +#if LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG +/** + * Draw vector graphics with SW render. + * @param draw_unit pointer to a draw unit + * @param dsc the draw descriptor + */ +void lv_draw_sw_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc_t * dsc); +#endif + +/** + * Swap the upper and lower byte of an RGB565 buffer. + * Might be required if a 8bit parallel port or an SPI port send the bytes in the wrong order. + * The bytes will be swapped in place. + * @param buf pointer to buffer + * @param buf_size_px number of pixels in the buffer + */ +void lv_draw_sw_rgb565_swap(void * buf, uint32_t buf_size_px); + +/** + * Invert a draw buffer in the I1 color format. + * Conventionally, a bit is set to 1 during blending if the luminance is greater than 127. + * Depending on the display controller used, you might want to have different behavior. + * The inversion will be performed in place. + * @param buf pointer to the buffer to be inverted + * @param buf_size size of the buffer in bytes + */ +void lv_draw_sw_i1_invert(void * buf, uint32_t buf_size); + +/** + * Rotate a buffer into another buffer + * @param src the source buffer + * @param dest the destination buffer + * @param src_width source width in pixels + * @param src_height source height in pixels + * @param src_stride source stride in bytes (number of bytes in a row) + * @param dest_stride destination stride in bytes (number of bytes in a row) + * @param rotation LV_DISPLAY_ROTATION_0/90/180/270 + * @param color_format LV_COLOR_FORMAT_RGB565/RGB888/XRGB8888/ARGB8888 + */ +void lv_draw_sw_rotate(const void * src, void * dest, int32_t src_width, int32_t src_height, int32_t src_stride, + int32_t dest_stride, lv_display_rotation_t rotation, lv_color_format_t color_format); + +/*********************** + * GLOBAL VARIABLES + ***********************/ + +/********************** + * MACROS + **********************/ + +#include "blend/lv_draw_sw_blend.h" + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_H*/ diff --git a/test/include/liblvgl/draw/sw/lv_draw_sw_gradient.h b/test/include/liblvgl/draw/sw/lv_draw_sw_gradient.h new file mode 100644 index 00000000..e68301bd --- /dev/null +++ b/test/include/liblvgl/draw/sw/lv_draw_sw_gradient.h @@ -0,0 +1,203 @@ +/** + * @file lv_draw_sw_gradient.h + * + */ + +#ifndef LV_DRAW_SW_GRADIENT_H +#define LV_DRAW_SW_GRADIENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_color.h" +#include "../../misc/lv_style.h" + +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ +#if LV_GRADIENT_MAX_STOPS < 2 +#error LVGL needs at least 2 stops for gradients. Please increase the LV_GRADIENT_MAX_STOPS +#endif + +#define LV_GRAD_LEFT LV_PCT(0) +#define LV_GRAD_RIGHT LV_PCT(100) +#define LV_GRAD_TOP LV_PCT(0) +#define LV_GRAD_BOTTOM LV_PCT(100) +#define LV_GRAD_CENTER LV_PCT(50) + +/********************** + * TYPEDEFS + **********************/ +typedef lv_color_t lv_grad_color_t; + +/********************** + * PROTOTYPES + **********************/ +/** Compute the color in the given gradient and fraction + * Gradient are specified in a virtual [0-255] range, so this function scales the virtual range to the given range + * @param dsc The gradient descriptor to use + * @param range The range to use in computation. + * @param frac The current part used in the range. frac is in [0; range] + * @param color_out Calculated gradient color + * @param opa_out Calculated opacity + */ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_color_calculate(const lv_grad_dsc_t * dsc, int32_t range, + int32_t frac, lv_grad_color_t * color_out, lv_opa_t * opa_out); + +/** Get a gradient cache from the given parameters */ +lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * gradient, int32_t w, int32_t h); + +/** + * Clean up the gradient item after it was get with `lv_grad_get_from_cache`. + * @param grad pointer to a gradient + */ +void lv_gradient_cleanup(lv_grad_t * grad); + +/** + * Initialize gradient color map from a table + * @param grad pointer to a gradient descriptor + * @param colors color array + * @param fracs position array (0..255): if NULL, then colors are distributed evenly + * @param opa opacity array: if NULL, then LV_OPA_COVER is assumed + * @param num_stops number of gradient stops (1..LV_GRADIENT_MAX_STOPS) + */ +void lv_gradient_init_stops(lv_grad_dsc_t * grad, const lv_color_t colors[], const lv_opa_t opa[], + const uint8_t fracs[], int num_stops); + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + +/** + * Helper function to initialize linear gradient + * @param dsc gradient descriptor + * @param from_x start x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param from_y start y position + * @param to_x end x position + * @param to_y end y position + * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT + */ +void lv_grad_linear_init(lv_grad_dsc_t * dsc, int32_t from_x, int32_t from_y, int32_t to_x, int32_t to_y, + lv_grad_extend_t extend); + +/** + * Helper function to initialize radial gradient + * @param dsc gradient descriptor + * @param center_x center x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param center_y center y position + * @param to_x point on the end circle x position + * @param to_y point on the end circle y position + * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT + */ +void lv_grad_radial_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t to_x, int32_t to_y, + lv_grad_extend_t extend); + +/** + * Set focal (starting) circle of a radial gradient + * @param dsc gradient descriptor + * @param center_x center x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param center_y center y position + * @param radius radius of the starting circle (NOTE: this must be a scalar number, not percentage) + */ +void lv_grad_radial_set_focal(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t radius); + +/** + * Helper function to initialize conical gradient + * @param dsc gradient descriptor + * @param center_x center x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param center_y center y position + * @param start_angle start angle in degrees + * @param end_angle end angle in degrees + * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT + */ +void lv_grad_conical_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t start_angle, + int32_t end_angle, lv_grad_extend_t extend); + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + */ +void lv_gradient_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); + +/** + * Free up the allocated memory for the gradient calculation + * @param dsc gradient descriptor + */ +void lv_gradient_linear_cleanup(lv_grad_dsc_t * dsc); + +/** + * Calculate a line segment of a linear gradient + * @param dsc gradient descriptor + * @param xp starting point x coordinate in gradient space + * @param yp starting point y coordinate in gradient space + * @param width width of the line segment in pixels + * @param result color buffer for the resulting line segment + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_linear_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, int32_t width, + lv_grad_t * result); + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + */ +void lv_gradient_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); + +/** + * Free up the allocated memory for the gradient calculation + * @param dsc gradient descriptor + */ +void lv_gradient_radial_cleanup(lv_grad_dsc_t * dsc); + +/** + * Calculate a line segment of a radial gradient + * @param dsc gradient descriptor + * @param xp starting point x coordinate in gradient space + * @param yp starting point y coordinate in gradient space + * @param width width of the line segment in pixels + * @param result color buffer for the resulting line segment + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_radial_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, int32_t width, + lv_grad_t * result); + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + */ +void lv_gradient_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); + +/** + * Free up the allocated memory for the gradient calculation + * @param dsc gradient descriptor + */ +void lv_gradient_conical_cleanup(lv_grad_dsc_t * dsc); + +/** + * Calculate a line segment of a conical gradient + * @param dsc gradient descriptor + * @param xp starting point x coordinate in gradient space + * @param yp starting point y coordinate in gradient space + * @param width width of the line segment in pixels + * @param result color buffer for the resulting line segment + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_conical_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, + lv_grad_t * result); + +#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_GRADIENT_H*/ diff --git a/test/include/liblvgl/draw/sw/lv_draw_sw_gradient_private.h b/test/include/liblvgl/draw/sw/lv_draw_sw_gradient_private.h new file mode 100644 index 00000000..a1e14932 --- /dev/null +++ b/test/include/liblvgl/draw/sw/lv_draw_sw_gradient_private.h @@ -0,0 +1,50 @@ +/** + * @file lv_draw_sw_gradient_private.h + * + */ + +#ifndef LV_DRAW_SW_GRADIENT_PRIVATE_H +#define LV_DRAW_SW_GRADIENT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_sw_gradient.h" + +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_grad_t { + lv_color_t * color_map; + lv_opa_t * opa_map; + uint32_t size; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DRAW_SW */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_GRADIENT_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/sw/lv_draw_sw_mask.h b/test/include/liblvgl/draw/sw/lv_draw_sw_mask.h new file mode 100644 index 00000000..3f7b306e --- /dev/null +++ b/test/include/liblvgl/draw/sw/lv_draw_sw_mask.h @@ -0,0 +1,185 @@ +/** + * @file lv_draw_sw_mask.h + * + */ + +#ifndef LV_DRAW_SW_MASK_H +#define LV_DRAW_SW_MASK_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" +#include "../../misc/lv_math.h" +#include "../../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ +#define LV_MASK_ID_INV (-1) +#if LV_DRAW_SW_COMPLEX +# define LV_MASK_MAX_NUM 16 +#else +# define LV_MASK_MAX_NUM 1 +#endif + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_DRAW_SW_MASK_RES_TRANSP, + LV_DRAW_SW_MASK_RES_FULL_COVER, + LV_DRAW_SW_MASK_RES_CHANGED, + LV_DRAW_SW_MASK_RES_UNKNOWN +} lv_draw_sw_mask_res_t; + +#if LV_DRAW_SW_COMPLEX + +typedef enum { + LV_DRAW_SW_MASK_TYPE_LINE, + LV_DRAW_SW_MASK_TYPE_ANGLE, + LV_DRAW_SW_MASK_TYPE_RADIUS, + LV_DRAW_SW_MASK_TYPE_FADE, + LV_DRAW_SW_MASK_TYPE_MAP, +} lv_draw_sw_mask_type_t; + +typedef enum { + LV_DRAW_SW_MASK_LINE_SIDE_LEFT = 0, + LV_DRAW_SW_MASK_LINE_SIDE_RIGHT, + LV_DRAW_SW_MASK_LINE_SIDE_TOP, + LV_DRAW_SW_MASK_LINE_SIDE_BOTTOM, +} lv_draw_sw_mask_line_side_t; + +/** + * A common callback type for every mask type. + * Used internally by the library. + */ +typedef lv_draw_sw_mask_res_t (*lv_draw_sw_mask_xcb_t)(lv_opa_t * mask_buf, int32_t abs_x, int32_t abs_y, + int32_t len, + void * p); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_sw_mask_init(void); + +void lv_draw_sw_mask_deinit(void); + +//! @cond Doxygen_Suppress + +/** + * Apply the added buffers on a line. Used internally by the library's drawing routines. + * @param masks the masks list to apply, must be ended with NULL pointer in array. + * @param mask_buf store the result mask here. Has to be `len` byte long. Should be initialized with `0xFF`. + * @param abs_x absolute X coordinate where the line to calculate start + * @param abs_y absolute Y coordinate where the line to calculate start + * @param len length of the line to calculate (in pixel count) + * @return One of these values: + * - `LV_DRAW_MASK_RES_FULL_TRANSP`: the whole line is transparent. `mask_buf` is not set to zero + * - `LV_DRAW_MASK_RES_FULL_COVER`: the whole line is fully visible. `mask_buf` is unchanged + * - `LV_DRAW_MASK_RES_CHANGED`: `mask_buf` has changed, it shows the desired opacity of each pixel in the given line + */ +lv_draw_sw_mask_res_t /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_mask_apply(void * masks[], lv_opa_t * mask_buf, + int32_t abs_x, + int32_t abs_y, + int32_t len); + +//! @endcond + +/** + * Free the data from the parameter. + * It's called inside `lv_draw_sw_mask_remove_id` and `lv_draw_sw_mask_remove_custom` + * Needs to be called only in special cases when the mask is not added by `lv_draw_mask_add` + * and not removed by `lv_draw_mask_remove_id` or `lv_draw_mask_remove_custom` + * @param p pointer to a mask parameter + */ +void lv_draw_sw_mask_free_param(void * p); + +/** + *Initialize a line mask from two points. + * @param param pointer to a `lv_draw_mask_param_t` to initialize + * @param p1x X coordinate of the first point of the line + * @param p1y Y coordinate of the first point of the line + * @param p2x X coordinate of the second point of the line + * @param p2y y coordinate of the second point of the line + * @param side and element of `lv_draw_mask_line_side_t` to describe which side to keep. + * With `LV_DRAW_MASK_LINE_SIDE_LEFT/RIGHT` and horizontal line all pixels are kept + * With `LV_DRAW_MASK_LINE_SIDE_TOP/BOTTOM` and vertical line all pixels are kept + */ +void lv_draw_sw_mask_line_points_init(lv_draw_sw_mask_line_param_t * param, int32_t p1x, int32_t p1y, + int32_t p2x, + int32_t p2y, lv_draw_sw_mask_line_side_t side); + +/** + *Initialize a line mask from a point and an angle. + * @param param pointer to a `lv_draw_mask_param_t` to initialize + * @param px X coordinate of a point of the line + * @param py X coordinate of a point of the line + * @param angle right 0 deg, bottom: 90 + * @param side an element of `lv_draw_mask_line_side_t` to describe which side to keep. + * With `LV_DRAW_MASK_LINE_SIDE_LEFT/RIGHT` and horizontal line all pixels are kept + * With `LV_DRAW_MASK_LINE_SIDE_TOP/BOTTOM` and vertical line all pixels are kept + */ +void lv_draw_sw_mask_line_angle_init(lv_draw_sw_mask_line_param_t * param, int32_t px, int32_t py, int16_t angle, + lv_draw_sw_mask_line_side_t side); + +/** + * Initialize an angle mask. + * @param param pointer to a `lv_draw_mask_param_t` to initialize + * @param vertex_x X coordinate of the angle vertex (absolute coordinates) + * @param vertex_y Y coordinate of the angle vertex (absolute coordinates) + * @param start_angle start angle in degrees. 0 deg on the right, 90 deg, on the bottom + * @param end_angle end angle + */ +void lv_draw_sw_mask_angle_init(lv_draw_sw_mask_angle_param_t * param, int32_t vertex_x, int32_t vertex_y, + int32_t start_angle, int32_t end_angle); + +/** + * Initialize a fade mask. + * @param param pointer to an `lv_draw_mask_radius_param_t` to initialize + * @param rect coordinates of the rectangle to affect (absolute coordinates) + * @param radius radius of the rectangle + * @param inv true: keep the pixels inside the rectangle; keep the pixels outside of the rectangle + */ +void lv_draw_sw_mask_radius_init(lv_draw_sw_mask_radius_param_t * param, const lv_area_t * rect, int32_t radius, + bool inv); + +/** + * Initialize a fade mask. + * @param param pointer to a `lv_draw_mask_param_t` to initialize + * @param coords coordinates of the area to affect (absolute coordinates) + * @param opa_top opacity on the top + * @param y_top at which coordinate start to change to opacity to `opa_bottom` + * @param opa_bottom opacity at the bottom + * @param y_bottom at which coordinate reach `opa_bottom`. + */ +void lv_draw_sw_mask_fade_init(lv_draw_sw_mask_fade_param_t * param, const lv_area_t * coords, lv_opa_t opa_top, + int32_t y_top, + lv_opa_t opa_bottom, int32_t y_bottom); + +/** + * Initialize a map mask. + * @param param pointer to a `lv_draw_mask_param_t` to initialize + * @param coords coordinates of the map (absolute coordinates) + * @param map array of bytes with the mask values + */ +void lv_draw_sw_mask_map_init(lv_draw_sw_mask_map_param_t * param, const lv_area_t * coords, const lv_opa_t * map); + +#endif /*LV_DRAW_SW_COMPLEX*/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_MASK_H*/ diff --git a/test/include/liblvgl/draw/sw/lv_draw_sw_mask_private.h b/test/include/liblvgl/draw/sw/lv_draw_sw_mask_private.h new file mode 100644 index 00000000..e3c1dd34 --- /dev/null +++ b/test/include/liblvgl/draw/sw/lv_draw_sw_mask_private.h @@ -0,0 +1,157 @@ +/** + * @file lv_draw_sw_mask_private.h + * + */ + +#ifndef LV_DRAW_SW_MASK_PRIVATE_H +#define LV_DRAW_SW_MASK_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_sw_mask.h" + +#if LV_DRAW_SW_COMPLEX + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint8_t * buf; + lv_opa_t * cir_opa; /**< Opacity of values on the circumference of an 1/4 circle */ + uint16_t * x_start_on_y; /**< The x coordinate of the circle for each y value */ + uint16_t * opa_start_on_y; /**< The index of `cir_opa` for each y value */ + int32_t life; /**< How many times the entry way used */ + uint32_t used_cnt; /**< Like a semaphore to count the referencing masks */ + int32_t radius; /**< The radius of the entry */ +} lv_draw_sw_mask_radius_circle_dsc_t; + +struct _lv_draw_sw_mask_common_dsc_t { + lv_draw_sw_mask_xcb_t cb; + lv_draw_sw_mask_type_t type; +}; + +struct _lv_draw_sw_mask_line_param_t { + /** The first element must be the common descriptor */ + lv_draw_sw_mask_common_dsc_t dsc; + + struct { + /*First point*/ + lv_point_t p1; + + /*Second point*/ + lv_point_t p2; + + /*Which side to keep?*/ + lv_draw_sw_mask_line_side_t side : 2; + } cfg; + + /** A point of the line */ + lv_point_t origo; + + /** X / (1024*Y) steepness (X is 0..1023 range). What is the change of X in 1024 Y? */ + int32_t xy_steep; + + /** Y / (1024*X) steepness (Y is 0..1023 range). What is the change of Y in 1024 X? */ + int32_t yx_steep; + + /** Helper which stores yx_steep for flat lines and xy_steep for steep (non flat) lines */ + int32_t steep; + + /** Steepness in 1 px in 0..255 range. Used only by flat lines. */ + int32_t spx; + + /** 1: It's a flat line? (Near to horizontal) */ + uint8_t flat : 1; + + /** Invert the mask. The default is: Keep the left part. + *It is used to select left/right/top/bottom */ + uint8_t inv: 1; +}; + +struct _lv_draw_sw_mask_angle_param_t { + /** The first element must be the common descriptor */ + lv_draw_sw_mask_common_dsc_t dsc; + + struct { + lv_point_t vertex_p; + int32_t start_angle; + int32_t end_angle; + } cfg; + + lv_draw_sw_mask_line_param_t start_line; + lv_draw_sw_mask_line_param_t end_line; + uint16_t delta_deg; +}; + +struct _lv_draw_sw_mask_radius_param_t { + /** The first element must be the common descriptor */ + lv_draw_sw_mask_common_dsc_t dsc; + + struct { + lv_area_t rect; + int32_t radius; + /** Invert the mask. 0: Keep the pixels inside. */ + uint8_t outer: 1; + } cfg; + + lv_draw_sw_mask_radius_circle_dsc_t * circle; +}; + +struct _lv_draw_sw_mask_fade_param_t { + /** The first element must be the common descriptor */ + lv_draw_sw_mask_common_dsc_t dsc; + + struct { + lv_area_t coords; + int32_t y_top; + int32_t y_bottom; + lv_opa_t opa_top; + lv_opa_t opa_bottom; + } cfg; + +}; + +struct _lv_draw_sw_mask_map_param_t { + /** The first element must be the common descriptor */ + lv_draw_sw_mask_common_dsc_t dsc; + + struct { + lv_area_t coords; + const lv_opa_t * map; + } cfg; +}; + +typedef lv_draw_sw_mask_radius_circle_dsc_t lv_draw_sw_mask_radius_circle_dsc_arr_t[LV_DRAW_SW_CIRCLE_CACHE_SIZE]; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Called by LVGL the rendering of a screen is ready to clean up + * the temporal (cache) data of the masks + */ +void lv_draw_sw_mask_cleanup(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_DRAW_SW_COMPLEX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_MASK_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/sw/lv_draw_sw_private.h b/test/include/liblvgl/draw/sw/lv_draw_sw_private.h new file mode 100644 index 00000000..4339a780 --- /dev/null +++ b/test/include/liblvgl/draw/sw/lv_draw_sw_private.h @@ -0,0 +1,68 @@ +/** + * @file lv_draw_sw_private.h + * + */ + +#ifndef LV_DRAW_SW_PRIVATE_H +#define LV_DRAW_SW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_sw.h" +#include "../lv_draw_private.h" + +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_draw_sw_unit_t { + lv_draw_unit_t base_unit; + lv_draw_task_t * task_act; +#if LV_USE_OS + lv_thread_sync_t sync; + lv_thread_t thread; + volatile bool inited; + volatile bool exit_status; +#endif + uint32_t idx; +}; + +#if LV_DRAW_SW_SHADOW_CACHE_SIZE +typedef struct { + uint8_t cache[LV_DRAW_SW_SHADOW_CACHE_SIZE * LV_DRAW_SW_SHADOW_CACHE_SIZE]; + int32_t cache_size; + int32_t cache_r; +} lv_draw_sw_shadow_cache_t; +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DRAW_SW */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_PRIVATE_H*/ diff --git a/test/include/liblvgl/draw/vg_lite/lv_draw_vg_lite.h b/test/include/liblvgl/draw/vg_lite/lv_draw_vg_lite.h new file mode 100644 index 00000000..63ff7f50 --- /dev/null +++ b/test/include/liblvgl/draw/vg_lite/lv_draw_vg_lite.h @@ -0,0 +1,90 @@ +/** + * @file lv_draw_vg_lite.h + * + */ + +#ifndef LV_DRAW_VG_LITE_H +#define LV_DRAW_VG_LITE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" + +#if LV_USE_DRAW_VG_LITE + +#include "../lv_draw.h" +#include "../../draw/lv_draw_vector.h" +#include "../../draw/lv_draw_arc.h" +#include "../../draw/lv_draw_rect.h" +#include "../../draw/lv_draw_image.h" +#include "../../draw/lv_draw_label.h" +#include "../../draw/lv_draw_line.h" +#include "../../draw/lv_draw_triangle.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_buf_vg_lite_init_handlers(void); + +void lv_draw_vg_lite_init(void); + +void lv_draw_vg_lite_deinit(void); + +void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_vg_lite_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, + const lv_area_t * coords, bool no_cache); + +void lv_draw_vg_lite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_vg_lite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); + +void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); + +void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc); + +void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc, + const lv_area_t * coords); + +#if LV_USE_VECTOR_GRAPHIC +void lv_draw_vg_lite_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc_t * dsc); +#endif + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_VG_LITE_H*/ diff --git a/test/include/liblvgl/draw/vg_lite/lv_draw_vg_lite_type.h b/test/include/liblvgl/draw/vg_lite/lv_draw_vg_lite_type.h new file mode 100644 index 00000000..e06fc75d --- /dev/null +++ b/test/include/liblvgl/draw/vg_lite/lv_draw_vg_lite_type.h @@ -0,0 +1,73 @@ +/** + * @file lv_draw_vg_lite_type.h + * + */ + +#ifndef LV_DRAW_VG_LITE_TYPE_H +#define LV_DRAW_VG_LITE_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" + +#if LV_USE_DRAW_VG_LITE + +#include "../lv_draw_private.h" +#include "../../misc/lv_array.h" + +#if LV_USE_VG_LITE_THORVG +#include "../../others/vg_lite_tvg/vg_lite.h" +#else +#include +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_vg_lite_pending_t; + +struct _lv_draw_vg_lite_unit_t { + lv_draw_unit_t base_unit; + lv_draw_task_t * task_act; + + struct _lv_vg_lite_pending_t * image_dsc_pending; + + lv_cache_t * grad_cache; + struct _lv_vg_lite_pending_t * grad_pending; + + lv_cache_t * stroke_cache; + + uint16_t flush_count; + uint16_t letter_count; + vg_lite_buffer_t target_buffer; + vg_lite_matrix_t global_matrix; + struct _lv_vg_lite_path_t * global_path; + bool path_in_use; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_VG_LITE_TYPE_H*/ diff --git a/test/include/liblvgl/draw/vg_lite/lv_vg_lite_decoder.h b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_decoder.h new file mode 100644 index 00000000..9bab540c --- /dev/null +++ b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_decoder.h @@ -0,0 +1,47 @@ +/** + * @file lv_vg_lite_decoder.h + * + */ + +#ifndef LV_VG_LITE_DECODER_H +#define LV_VG_LITE_DECODER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lv_image_decoder.h" + +#if LV_USE_DRAW_VG_LITE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_vg_lite_decoder_init(void); + +void lv_vg_lite_decoder_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VG_LITE_DECODER_H*/ diff --git a/test/include/liblvgl/draw/vg_lite/lv_vg_lite_grad.h b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_grad.h new file mode 100644 index 00000000..d9bde91e --- /dev/null +++ b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_grad.h @@ -0,0 +1,69 @@ +/** + * @file lv_vg_lite_grad.h + * + */ + +#ifndef LV_VG_LITE_GRAD_H +#define LV_VG_LITE_GRAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" + +#if LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC + +#include "lv_vg_lite_utils.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_vg_lite_grad_init(struct _lv_draw_vg_lite_unit_t * u, uint32_t cache_cnt); + +void lv_vg_lite_grad_deinit(struct _lv_draw_vg_lite_unit_t * u); + +bool lv_vg_lite_draw_grad( + struct _lv_draw_vg_lite_unit_t * u, + vg_lite_buffer_t * buffer, + vg_lite_path_t * path, + const lv_vector_gradient_t * grad, + const vg_lite_matrix_t * grad_matrix, + const vg_lite_matrix_t * matrix, + vg_lite_fill_t fill, + vg_lite_blend_t blend); + +bool lv_vg_lite_draw_grad_helper( + struct _lv_draw_vg_lite_unit_t * u, + vg_lite_buffer_t * buffer, + vg_lite_path_t * path, + const lv_area_t * area, + const lv_grad_dsc_t * grad_dsc, + const vg_lite_matrix_t * matrix, + vg_lite_fill_t fill, + vg_lite_blend_t blend); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VG_LITE_GRAD_H*/ diff --git a/test/include/liblvgl/draw/vg_lite/lv_vg_lite_math.h b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_math.h new file mode 100644 index 00000000..e2afc793 --- /dev/null +++ b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_math.h @@ -0,0 +1,76 @@ +/** + * @file lv_vg_lite_math.h + * + */ + +#ifndef LV_VG_LITE_MATH_H +#define LV_VG_LITE_MATH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" + +#if LV_USE_DRAW_VG_LITE + +#include +#include +#include + +/********************* + * DEFINES + *********************/ + +#define MATH_PI 3.14159265358979323846f +#define MATH_HALF_PI 1.57079632679489661923f +#define MATH_TWO_PI 6.28318530717958647692f +#define DEG_TO_RAD 0.017453292519943295769236907684886f +#define RAD_TO_DEG 57.295779513082320876798154814105f + +#define MATH_TANF(x) tanf(x) +#define MATH_SINF(x) sinf(x) +#define MATH_COSF(x) cosf(x) +#define MATH_ASINF(x) asinf(x) +#define MATH_ACOSF(x) acosf(x) +#define MATH_FABSF(x) fabsf(x) +#define MATH_SQRTF(x) sqrtf(x) + +#define MATH_RADIANS(deg) ((deg) * DEG_TO_RAD) +#define MATH_DEGREES(rad) ((rad) * RAD_TO_DEG) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +static inline bool math_zero(float a) +{ + return (MATH_FABSF(a) < FLT_EPSILON); +} + +static inline bool math_equal(float a, float b) +{ + return math_zero(a - b); +} + +float math_fast_inv_sqrtf(float number); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VG_LITE_MATH_H*/ diff --git a/test/include/liblvgl/draw/vg_lite/lv_vg_lite_path.h b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_path.h new file mode 100644 index 00000000..5781d513 --- /dev/null +++ b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_path.h @@ -0,0 +1,128 @@ +/** + * @file lv_vg_lite_path.h + * + */ + +#ifndef LV_VG_LITE_PATH_H +#define LV_VG_LITE_PATH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_vg_lite_utils.h" + +#if LV_USE_DRAW_VG_LITE + +/********************* + * DEFINES + *********************/ + +typedef struct _lv_vg_lite_path_t lv_vg_lite_path_t; +typedef struct _lv_draw_vg_lite_unit_t lv_draw_vg_lite_unit_t; + +typedef void (*lv_vg_lite_path_iter_cb_t)(void * user_data, uint8_t op_code, const float * data, uint32_t len); + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_vg_lite_path_init(lv_draw_vg_lite_unit_t * unit); + +void lv_vg_lite_path_deinit(lv_draw_vg_lite_unit_t * unit); + +lv_vg_lite_path_t * lv_vg_lite_path_create(vg_lite_format_t data_format); + +void lv_vg_lite_path_destroy(lv_vg_lite_path_t * path); + +lv_vg_lite_path_t * lv_vg_lite_path_get(lv_draw_vg_lite_unit_t * unit, vg_lite_format_t data_format); + +void lv_vg_lite_path_drop(lv_draw_vg_lite_unit_t * unit, lv_vg_lite_path_t * path); + +void lv_vg_lite_path_reset(lv_vg_lite_path_t * path, vg_lite_format_t data_format); + +void lv_vg_lite_path_set_bonding_box_area(lv_vg_lite_path_t * path, const lv_area_t * area); + +void lv_vg_lite_path_set_bonding_box(lv_vg_lite_path_t * path, + float min_x, float min_y, + float max_x, float max_y); + +void lv_vg_lite_path_get_bonding_box(lv_vg_lite_path_t * path, + float * min_x, float * min_y, + float * max_x, float * max_y); + +bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path); + +void lv_vg_lite_path_set_transform(lv_vg_lite_path_t * path, const vg_lite_matrix_t * matrix); + +void lv_vg_lite_path_set_quality(lv_vg_lite_path_t * path, vg_lite_quality_t quality); + +vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path); + +void lv_vg_lite_path_move_to(lv_vg_lite_path_t * path, + float x, float y); + +void lv_vg_lite_path_line_to(lv_vg_lite_path_t * path, + float x, float y); + +void lv_vg_lite_path_quad_to(lv_vg_lite_path_t * path, + float cx, float cy, + float x, float y); + +void lv_vg_lite_path_cubic_to(lv_vg_lite_path_t * path, + float cx1, float cy1, + float cx2, float cy2, + float x, float y); + +void lv_vg_lite_path_close(lv_vg_lite_path_t * path); + +void lv_vg_lite_path_end(lv_vg_lite_path_t * path); + +void lv_vg_lite_path_append_rect(lv_vg_lite_path_t * path, + float x, float y, + float w, float h, + float r); + +void lv_vg_lite_path_append_circle(lv_vg_lite_path_t * path, + float cx, float cy, + float rx, float ry); + +void lv_vg_lite_path_append_arc_right_angle(lv_vg_lite_path_t * path, + float start_x, float start_y, + float center_x, float center_y, + float end_x, float end_y); + +void lv_vg_lite_path_append_arc(lv_vg_lite_path_t * path, + float cx, float cy, + float radius, + float start_angle, + float sweep, + bool pie); + +void lv_vg_lite_path_append_path(lv_vg_lite_path_t * dest, const lv_vg_lite_path_t * src); + +uint8_t lv_vg_lite_vlc_op_arg_len(uint8_t vlc_op); + +uint8_t lv_vg_lite_path_format_len(vg_lite_format_t format); + +void lv_vg_lite_path_for_each_data(const vg_lite_path_t * path, lv_vg_lite_path_iter_cb_t cb, void * user_data); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VG_LITE_PATH_H*/ diff --git a/test/include/liblvgl/draw/vg_lite/lv_vg_lite_pending.h b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_pending.h new file mode 100644 index 00000000..8def9dcf --- /dev/null +++ b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_pending.h @@ -0,0 +1,83 @@ +/** + * @file lv_vg_lite_pending.h + * + */ + +#ifndef LV_VG_LITE_PENDING_H +#define LV_VG_LITE_PENDING_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" + +#if LV_USE_DRAW_VG_LITE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_vg_lite_pending_t lv_vg_lite_pending_t; + +typedef void (*lv_vg_lite_pending_free_cb_t)(void * obj, void * user_data); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a pending list + * @param obj_size the size of the objects in the list + * @param capacity_default the default capacity of the list + * @return a pointer to the pending list + */ +lv_vg_lite_pending_t * lv_vg_lite_pending_create(size_t obj_size, uint32_t capacity_default); + +/** + * Destroy a pending list + * @param pending pointer to the pending list + */ +void lv_vg_lite_pending_destroy(lv_vg_lite_pending_t * pending); + +/** + * Set a free callback for the pending list + * @param pending pointer to the pending list + * @param free_cb the free callback + * @param user_data user data to pass to the free callback + */ +void lv_vg_lite_pending_set_free_cb(lv_vg_lite_pending_t * pending, lv_vg_lite_pending_free_cb_t free_cb, + void * user_data); + +/** + * Add an object to the pending list + * @param pending pointer to the pending list + * @param obj pointer to the object to add + */ +void lv_vg_lite_pending_add(lv_vg_lite_pending_t * pending, void * obj); + +/** + * Remove all objects from the pending list + * @param pending pointer to the pending list + */ +void lv_vg_lite_pending_remove_all(lv_vg_lite_pending_t * pending); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VG_LITE_PENDING_H*/ diff --git a/test/include/liblvgl/draw/vg_lite/lv_vg_lite_stroke.h b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_stroke.h new file mode 100644 index 00000000..81c7e510 --- /dev/null +++ b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_stroke.h @@ -0,0 +1,84 @@ +/** + * @file lv_vg_lite_stroke.h + * + */ + +#ifndef LV_VG_LITE_STROKE_H +#define LV_VG_LITE_STROKE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_vg_lite_utils.h" + +#if LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_vg_lite_path_t; + +struct _lv_draw_vg_lite_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the stroke module + * @param unit pointer to the unit + */ +void lv_vg_lite_stroke_init(struct _lv_draw_vg_lite_unit_t * unit, uint32_t cache_cnt); + +/** + * Deinitialize the stroke module + * @param unit pointer to the unit + */ +void lv_vg_lite_stroke_deinit(struct _lv_draw_vg_lite_unit_t * unit); + +/** + * Get the stroke cache entry + * @param unit pointer to the unit + * @param path pointer to the path + * @param dsc pointer to the stroke descriptor + * @return pointer to the stroke cache entry + */ +lv_cache_entry_t * lv_vg_lite_stroke_get(struct _lv_draw_vg_lite_unit_t * unit, + struct _lv_vg_lite_path_t * path, + const lv_vector_stroke_dsc_t * dsc); + +/** + * Get the path of a stroke + * @param cache_entry pointer to the stroke cache entry + * @return pointer to the path + */ +struct _lv_vg_lite_path_t * lv_vg_lite_stroke_get_path(lv_cache_entry_t * cache_entry); + +/** + * Drop the stroke cache entry + * @param unit pointer to the unit + * @param stroke pointer to the stroke + */ +void lv_vg_lite_stroke_drop(struct _lv_draw_vg_lite_unit_t * unit, lv_cache_entry_t * cache_entry); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VG_LITE_STROKE_H*/ diff --git a/test/include/liblvgl/draw/vg_lite/lv_vg_lite_utils.h b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_utils.h new file mode 100644 index 00000000..7d397632 --- /dev/null +++ b/test/include/liblvgl/draw/vg_lite/lv_vg_lite_utils.h @@ -0,0 +1,188 @@ +/** + * @file lv_vg_lite_utils.h + * + */ + +#ifndef LV_VG_LITE_UTILS_H +#define LV_VG_LITE_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" + +#if LV_USE_DRAW_VG_LITE + +#include "../../misc/lv_profiler.h" + +#include +#if LV_USE_VG_LITE_THORVG +#include "../../others/vg_lite_tvg/vg_lite.h" +#else +#include +#endif + +/********************* + * DEFINES + *********************/ + +#define LV_VG_LITE_IS_ERROR(err) (err > 0) + +#define VLC_GET_OP_CODE(ptr) (*((uint8_t*)ptr)) + +#if LV_VG_LITE_USE_ASSERT +#define LV_VG_LITE_ASSERT(expr) LV_ASSERT(expr) +#else +#define LV_VG_LITE_ASSERT(expr) +#endif + +#define LV_VG_LITE_CHECK_ERROR(expr) \ + do { \ + vg_lite_error_t error = expr; \ + if (LV_VG_LITE_IS_ERROR(error)) { \ + LV_LOG_ERROR("Execute '" #expr "' error(%d): %s", \ + (int)error, lv_vg_lite_error_string(error)); \ + LV_VG_LITE_ASSERT(false); \ + } \ + } while (0) + +#define LV_VG_LITE_ASSERT_PATH(path) LV_VG_LITE_ASSERT(lv_vg_lite_path_check(path)) +#define LV_VG_LITE_ASSERT_SRC_BUFFER(buffer) LV_VG_LITE_ASSERT(lv_vg_lite_buffer_check(buffer, true)) +#define LV_VG_LITE_ASSERT_DEST_BUFFER(buffer) LV_VG_LITE_ASSERT(lv_vg_lite_buffer_check(buffer, false)) +#define LV_VG_LITE_ASSERT_MATRIX(matrix) LV_VG_LITE_ASSERT(lv_vg_lite_matrix_check(matrix)) + +#define LV_VG_LITE_ALIGN(number, align_bytes) \ + (((number) + ((align_bytes)-1)) & ~((align_bytes)-1)) + +#define LV_VG_LITE_IS_ALIGNED(num, align) (((uintptr_t)(num) & ((align)-1)) == 0) + +#define LV_VG_LITE_IS_INDEX_FMT(fmt) \ + ((fmt) == VG_LITE_INDEX_1 \ + || (fmt) == VG_LITE_INDEX_2 \ + || (fmt) == VG_LITE_INDEX_4 \ + || (fmt) == VG_LITE_INDEX_8) + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_draw_vg_lite_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/* Print info */ + +void lv_vg_lite_dump_info(void); + +const char * lv_vg_lite_error_string(vg_lite_error_t error); + +const char * lv_vg_lite_feature_string(vg_lite_feature_t feature); + +const char * lv_vg_lite_buffer_format_string(vg_lite_buffer_format_t format); + +const char * lv_vg_lite_vlc_op_string(uint8_t vlc_op); + +void lv_vg_lite_path_dump_info(const vg_lite_path_t * path); + +void lv_vg_lite_stroke_dump_info(const vg_lite_stroke_t * stroke); + +void lv_vg_lite_buffer_dump_info(const vg_lite_buffer_t * buffer); + +void lv_vg_lite_matrix_dump_info(const vg_lite_matrix_t * matrix); + +bool lv_vg_lite_is_dest_cf_supported(lv_color_format_t cf); + +bool lv_vg_lite_is_src_cf_supported(lv_color_format_t cf); + +/* Converter */ + +vg_lite_buffer_format_t lv_vg_lite_vg_fmt(lv_color_format_t cf); + +void lv_vg_lite_buffer_format_bytes( + vg_lite_buffer_format_t format, + uint32_t * mul, + uint32_t * div, + uint32_t * bytes_align); + +uint32_t lv_vg_lite_width_to_stride(uint32_t w, vg_lite_buffer_format_t color_format); + +uint32_t lv_vg_lite_width_align(uint32_t w); + +void lv_vg_lite_buffer_init( + vg_lite_buffer_t * buffer, + const void * ptr, + int32_t width, + int32_t height, + uint32_t stride, + vg_lite_buffer_format_t format, + bool tiled); + +void lv_vg_lite_buffer_from_draw_buf(vg_lite_buffer_t * buffer, const lv_draw_buf_t * draw_buf); + +void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc); + +void lv_vg_lite_image_dec_init(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc); + +bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src, + bool no_cache, bool premultiply); + +void lv_vg_lite_image_dsc_init(struct _lv_draw_vg_lite_unit_t * unit); + +void lv_vg_lite_image_dsc_deinit(struct _lv_draw_vg_lite_unit_t * unit); + +vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_mul); + +uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format); + +vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul); + +void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area); + +void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src); + +/* Param checker */ + +bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src); + +bool lv_vg_lite_path_check(const vg_lite_path_t * path); + +bool lv_vg_lite_matrix_check(const vg_lite_matrix_t * matrix); + +/* Wrapper */ + +bool lv_vg_lite_support_blend_normal(void); + +bool lv_vg_lite_16px_align(void); + +void lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult); + +bool lv_vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix); + +lv_point_precise_t lv_vg_lite_matrix_transform_point(const vg_lite_matrix_t * matrix, const lv_point_precise_t * point); + +void lv_vg_lite_set_scissor_area(const lv_area_t * area); + +void lv_vg_lite_disable_scissor(void); + +void lv_vg_lite_flush(struct _lv_draw_vg_lite_unit_t * u); + +void lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*VG_LITE_UTILS_H*/ diff --git a/test/include/liblvgl/drivers/README.md b/test/include/liblvgl/drivers/README.md new file mode 100644 index 00000000..f755a3ab --- /dev/null +++ b/test/include/liblvgl/drivers/README.md @@ -0,0 +1 @@ +High level drivers for display controllers, frame buffers, etc \ No newline at end of file diff --git a/test/include/liblvgl/drivers/display/drm/lv_linux_drm.h b/test/include/liblvgl/drivers/display/drm/lv_linux_drm.h new file mode 100644 index 00000000..ee32466c --- /dev/null +++ b/test/include/liblvgl/drivers/display/drm/lv_linux_drm.h @@ -0,0 +1,46 @@ +/** + * @file lv_linux_drm.h + * + */ + +#ifndef LV_LINUX_DRM_H +#define LV_LINUX_DRM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../display/lv_display.h" + +#if LV_USE_LINUX_DRM + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +lv_display_t * lv_linux_drm_create(void); + +void lv_linux_drm_set_file(lv_display_t * disp, const char * file, int64_t connector_id); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LINUX_DRM */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_LINUX_DRM_H */ diff --git a/test/include/liblvgl/drivers/display/fb/lv_linux_fbdev.h b/test/include/liblvgl/drivers/display/fb/lv_linux_fbdev.h new file mode 100644 index 00000000..2c41aec1 --- /dev/null +++ b/test/include/liblvgl/drivers/display/fb/lv_linux_fbdev.h @@ -0,0 +1,52 @@ +/** + * @file lv_linux_fbdev.h + * + */ + +#ifndef LV_LINUX_FBDEV_H +#define LV_LINUX_FBDEV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../display/lv_display.h" + +#if LV_USE_LINUX_FBDEV + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +lv_display_t * lv_linux_fbdev_create(void); + +void lv_linux_fbdev_set_file(lv_display_t * disp, const char * file); + +/** + * Force the display to be refreshed on every change. + * Expected to be used with LV_DISPLAY_RENDER_MODE_DIRECT or LV_DISPLAY_RENDER_MODE_FULL. + */ +void lv_linux_fbdev_set_force_refresh(lv_display_t * disp, bool enabled); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LINUX_FBDEV */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_LINUX_FBDEV_H */ diff --git a/test/include/liblvgl/drivers/display/ili9341/lv_ili9341.h b/test/include/liblvgl/drivers/display/ili9341/lv_ili9341.h new file mode 100644 index 00000000..90fe5daf --- /dev/null +++ b/test/include/liblvgl/drivers/display/ili9341/lv_ili9341.h @@ -0,0 +1,94 @@ +/** + * @file lv_ili9341.h + * + * This driver is just a wrapper around the generic MIPI compatible LCD controller driver + * + */ + +#ifndef LV_ILI9341_H +#define LV_ILI9341_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lcd/lv_lcd_generic_mipi.h" + +#if LV_USE_ILI9341 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef lv_lcd_send_cmd_cb_t lv_ili9341_send_cmd_cb_t; +typedef lv_lcd_send_color_cb_t lv_ili9341_send_color_cb_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an LCD display with ILI9341 driver + * @param hor_res horizontal resolution + * @param ver_res vertical resolution + * @param flags default configuration settings (mirror, RGB ordering, etc.) + * @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer) + * @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback) + * @return pointer to the created display + */ +lv_display_t * lv_ili9341_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags, + lv_ili9341_send_cmd_cb_t send_cmd_cb, lv_ili9341_send_color_cb_t send_color_cb); + +/** + * Set gap, i.e., the offset of the (0,0) pixel in the VRAM + * @param disp display object + * @param x x offset + * @param y y offset + */ +void lv_ili9341_set_gap(lv_display_t * disp, uint16_t x, uint16_t y); + +/** + * Set color inversion + * @param disp display object + * @param invert false: normal, true: invert + */ +void lv_ili9341_set_invert(lv_display_t * disp, bool invert); + +/** + * Set gamma curve + * @param disp display object + * @param gamma gamma curve + */ +void lv_ili9341_set_gamma_curve(lv_display_t * disp, uint8_t gamma); + +/** + * Send list of commands. + * @param disp display object + * @param cmd_list controller and panel-specific commands + */ +void lv_ili9341_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list); + +/********************** + * OTHERS + **********************/ + +/********************** + * MACROS + **********************/ + + +#endif /*LV_USE_ILI9341*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ILI9341_H*/ diff --git a/test/include/liblvgl/drivers/display/lcd/lv_lcd_generic_mipi.h b/test/include/liblvgl/drivers/display/lcd/lv_lcd_generic_mipi.h new file mode 100644 index 00000000..95fbf679 --- /dev/null +++ b/test/include/liblvgl/drivers/display/lcd/lv_lcd_generic_mipi.h @@ -0,0 +1,242 @@ +/** + * @file lv_lcd_generic_mipi.h + * + * Generic driver for controllers adhering to the MIPI DBI/DCS specification + * + * Works with: + * + * ST7735 + * ST7789 + * ST7796 + * ILI9341 + * ILI9488 (NOTE: in SPI mode ILI9488 only supports RGB666 mode, which is currently not supported) + * + * any probably many more + * + */ + +#ifndef LV_LCD_GENERIC_MIPI_H +#define LV_LCD_GENERIC_MIPI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../display/lv_display.h" + +#if LV_USE_GENERIC_MIPI + +/********************* + * DEFINES + *********************/ + +/* MIPI DCS (Display Command Set) v1.02.00 User Command Set */ +#define LV_LCD_CMD_NOP 0x00 /* No Operation */ +#define LV_LCD_CMD_SOFT_RESET 0x01 /* Software Reset */ +#define LV_LCD_CMD_GET_POWER_MODE 0x0A /* Get the current power mode */ +#define LV_LCD_CMD_GET_ADDRESS_MODE 0x0B /* Get the data order for transfers from the Host to the display module and from the frame memory to the display device */ +#define LV_LCD_CMD_GET_PIXEL_FORMAT 0x0C /* Get the current pixel format */ +#define LV_LCD_CMD_GET_DISPLAY_MODE 0x0D /* Get the current display mode from the peripheral */ +#define LV_LCD_CMD_GET_SIGNAL_MODE 0x0E /* Get display module signaling mode */ +#define LV_LCD_CMD_GET_DIAGNOSTIC_RESULT 0x0F /* Get Peripheral Self-Diagnostic Result */ +#define LV_LCD_CMD_ENTER_SLEEP_MODE 0x10 /* Power for the display panel is off */ +#define LV_LCD_CMD_EXIT_SLEEP_MODE 0x11 /* Power for the display panel is on */ +#define LV_LCD_CMD_ENTER_PARTIAL_MODE 0x12 /* Part of the display area is used for image display */ +#define LV_LCD_CMD_ENTER_NORMAL_MODE 0x13 /* The whole display area is used for image display */ +#define LV_LCD_CMD_EXIT_INVERT_MODE 0x20 /* Displayed image colors are not inverted */ +#define LV_LCD_CMD_ENTER_INVERT_MODE 0x21 /* Displayed image colors are inverted */ +#define LV_LCD_CMD_SET_GAMMA_CURVE 0x26 /* Selects the gamma curve used by the display device */ +#define LV_LCD_CMD_SET_DISPLAY_OFF 0x28 /* Blanks the display device */ +#define LV_LCD_CMD_SET_DISPLAY_ON 0x29 /* Show the image on the display device */ +#define LV_LCD_CMD_SET_COLUMN_ADDRESS 0x2A /* Set the column extent */ +#define LV_LCD_CMD_SET_PAGE_ADDRESS 0x2B /* Set the page extent */ +#define LV_LCD_CMD_WRITE_MEMORY_START 0x2C /* Transfer image data from the Host Processor to the peripheral starting at the location provided by set_column_address and set_page_address */ +#define LV_LCD_CMD_READ_MEMORY_START 0x2E /* Transfer image data from the peripheral to the Host Processor interface starting at the location provided by set_column_address and set_page_address */ +#define LV_LCD_CMD_SET_PARTIAL_ROWS 0x30 /* Defines the number of rows in the partial display area on the display device */ +#define LV_LCD_CMD_SET_PARTIAL_COLUMNS 0x31 /* Defines the number of columns in the partial display area on the display device */ +#define LV_LCD_CMD_SET_SCROLL_AREA 0x33 /* Defines the vertical scrolling and fixed area on display device */ +#define LV_LCD_CMD_SET_TEAR_OFF 0x34 /* Synchronization information is not sent from the display module to the host processor */ +#define LV_LCD_CMD_SET_TEAR_ON 0x35 /* Synchronization information is sent from the display module to the host processor at the start of VFP */ +#define LV_LCD_CMD_SET_ADDRESS_MODE 0x36 /* Set the data order for transfers from the Host to the display module and from the frame memory to the display device */ +#define LV_LCD_CMD_SET_SCROLL_START 0x37 /* Defines the vertical scrolling starting point */ +#define LV_LCD_CMD_EXIT_IDLE_MODE 0x38 /* Full color depth is used on the display panel */ +#define LV_LCD_CMD_ENTER_IDLE_MODE 0x39 /* Reduced color depth is used on the display panel */ +#define LV_LCD_CMD_SET_PIXEL_FORMAT 0x3A /* Defines how many bits per pixel are used in the interface */ +#define LV_LCD_CMD_WRITE_MEMORY_CONTINUE 0x3C /* Transfer image information from the Host Processor interface to the peripheral from the last written location */ +#define LV_LCD_CMD_READ_MEMORY_CONTINUE 0x3E /* Read image data from the peripheral continuing after the last read_memory_continue or read_memory_start */ +#define LV_LCD_CMD_SET_TEAR_SCANLINE 0x44 /* Synchronization information is sent from the display module to the host processor when the display device refresh reaches the provided scanline */ +#define LV_LCD_CMD_GET_SCANLINE 0x45 /* Get the current scanline */ +#define LV_LCD_CMD_READ_DDB_CONTINUE 0xA8 /* Continue reading the DDB from the last read location */ +#define LV_LCD_CMD_READ_DDB_START 0xA1 /* Read the DDB from the provided location */ + +/* address mode flag masks */ +#define LV_LCD_MASK_FLIP_VERTICAL (1 << 0) /* This bit flips the image shown on the display device top to bottom. No change is made to the frame memory */ +#define LV_LCD_MASK_FLIP_HORIZONTAL (1 << 1) /* This bit flips the image shown on the display device left to right. No change is made to the frame memory */ +#define LV_LCD_MASK_DATA_LATCH_DATA_ORDER (1 << 2) /* Display Data Latch Order */ +#define LV_LCD_MASK_RGB_ORDER (1 << 3) /* RGB/BGR Order */ +#define LV_LCD_MASK_LINE_ADDRESS_ORDER (1 << 4) /* Line Address Order */ +#define LV_LCD_MASK_PAGE_COLUMN_ORDER (1 << 5) /* Page/Column Order */ +#define LV_LCD_MASK_COLUMN_ADDRESS_ORDER (1 << 6) /* Column Address Order */ +#define LV_LCD_MASK_PAGE_ADDRESS_ORDER (1 << 7) /* Page Address Order */ + +#define LV_LCD_BIT_FLIP_VERTICAL__NOT_FLIPPED 0 +#define LV_LCD_BIT_FLIP_VERTICAL__FLIPPED LV_LCD_MASK_FLIP_VERTICAL /* This bit flips the image shown on the display device top to bottom. No change is made to the frame memory */ +#define LV_LCD_BIT_FLIP_HORIZONTAL__NOT_FLIPPED 0 +#define LV_LCD_BIT_FLIP_HORIZONTAL__FLIPPED LV_LCD_MASK_FLIP_HORIZONTAL /* This bit flips the image shown on the display device left to right. No change is made to the frame memory */ +#define LV_LCD_BIT_DATA_LATCH_DATA_ORDER__LTOR 0 /* Display Data Latch Order: LCD Refresh Left to Right */ +#define LV_LCD_BIT_DATA_LATCH_DATA_ORDER__RTOL LV_LCD_MASK_DATA_LATCH_DATA_ORDER /* Display Data Latch Order: LCD Refresh Right to Left */ +#define LV_LCD_BIT_RGB_ORDER__RGB 0 /* RGB/BGR Order: RGB */ +#define LV_LCD_BIT_RGB_ORDER__BGR LV_LCD_MASK_RGB_ORDER /* RGB/BGR Order: BGR */ +#define LV_LCD_BIT_LINE_ADDRESS_ORDER__TTOB 0 /* Line Address Order: LCD Refresh Top to Bottom */ +#define LV_LCD_BIT_LINE_ADDRESS_ORDER__BTOT LV_LCD_MASK_LINE_ADDRESS_ORDER /* Line Address Order: LCD Refresh Bottom to Top */ +#define LV_LCD_BIT_PAGE_COLUMN_ORDER__NORMAL 0 /* Page/Column Order: Normal Mode */ +#define LV_LCD_BIT_PAGE_COLUMN_ORDER__REVERSE LV_LCD_MASK_PAGE_COLUMN_ORDER /* Page/Column Order: Reverse Mode */ +#define LV_LCD_BIT_COLUMN_ADDRESS_ORDER__LTOR 0 /* Column Address Order: Left to Right */ +#define LV_LCD_BIT_COLUMN_ADDRESS_ORDER__RTOL LV_LCD_MASK_COLUMN_ADDRESS_ORDER /* Column Address Order: Right to Left */ +#define LV_LCD_BIT_PAGE_ADDRESS_ORDER__TTOB 0 /* Page Address Order: Top to Bottom */ +#define LV_LCD_BIT_PAGE_ADDRESS_ORDER__BTOT LV_LCD_MASK_PAGE_ADDRESS_ORDER /* Page Address Order: Bottom to Top */ + +/* predefined gamma curves */ +#define LV_LCD_GAMMA_2_2 0x01 /* 2.2 */ +#define LV_LCD_GAMMA_1_8 0x02 /* 1.8 */ +#define LV_LCD_GAMMA_2_5 0x04 /* 2.5 */ +#define LV_LCD_GAMMA_1_0 0x08 /* 1.0 */ + +/* common pixel formats */ +#define LV_LCD_PIXEL_FORMAT_RGB565 0x55 /* bus: 16 bits, pixel: 16 bits */ +#define LV_LCD_PIXEL_FORMAT_RGB666 0x66 /* bus: 18 bits, pixel: 18 bits */ + +/* flags for lv_lcd_xxx_create() */ +#define LV_LCD_FLAG_NONE 0x00000000UL +#define LV_LCD_FLAG_MIRROR_X 0x00000001UL +#define LV_LCD_FLAG_MIRROR_Y 0x00000002UL +#define LV_LCD_FLAG_BGR 0x00000008UL +#define LV_LCD_FLAG_RGB666 0x00000010UL + +/* command list */ +#define LV_LCD_CMD_DELAY_MS 0xff +#define LV_LCD_CMD_EOF 0xff + +/********************** + * TYPEDEFS + **********************/ + +/** + * Configuration flags for lv_lcd_xxx_create() + * + */ +typedef uint32_t lv_lcd_flag_t; + +/** + * Prototype of a platform-dependent callback to transfer commands and data to the LCD controller. + * @param disp display object + * @param cmd command buffer (can handle 16 bit commands as well) + * @param cmd_size number of bytes of the command + * @param param parameter buffer + * @param param_size number of bytes of the parameters + */ +typedef void (*lv_lcd_send_cmd_cb_t)(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, const uint8_t * param, + size_t param_size); + +/** + * Prototype of a platform-dependent callback to transfer pixel data to the LCD controller. + * @param disp display object + * @param cmd command buffer (can handle 16 bit commands as well) + * @param cmd_size number of bytes of the command + * @param param parameter buffer + * @param param_size number of bytes of the parameters + */ +typedef void (*lv_lcd_send_color_cb_t)(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, uint8_t * param, + size_t param_size); + +/** + * Generic MIPI compatible LCD driver + */ +typedef struct { + lv_display_t * disp; /* the associated LVGL display object */ + lv_lcd_send_cmd_cb_t send_cmd; /* platform-specific implementation to send a command to the LCD controller */ + lv_lcd_send_color_cb_t send_color; /* platform-specific implementation to send pixel data to the LCD controller */ + uint16_t x_gap; /* x offset of the (0,0) pixel in VRAM */ + uint16_t y_gap; /* y offset of the (0,0) pixel in VRAM */ + uint8_t madctl_reg; /* current value of MADCTL register */ + uint8_t colmod_reg; /* current value of COLMOD register */ + bool mirror_x; + bool mirror_y; + bool swap_xy; +} lv_lcd_generic_mipi_driver_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a MIPI DCS compatible LCD display + * @param hor_res horizontal resolution + * @param ver_res vertical resolution + * @param flags default configuration settings (mirror, RGB ordering, etc.) + * @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer) + * @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback) + * @return pointer to the created display + */ +lv_display_t * lv_lcd_generic_mipi_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags, + lv_lcd_send_cmd_cb_t send_cmd_cb, lv_lcd_send_color_cb_t send_color_cb); + +/** + * Set gap, i.e., the offset of the (0,0) pixel in the VRAM + * @param disp display object + * @param x x offset + * @param y y offset + */ +void lv_lcd_generic_mipi_set_gap(lv_display_t * disp, uint16_t x, uint16_t y); + +/** + * Set color inversion + * @param disp display object + * @param invert false: normal, true: invert + */ +void lv_lcd_generic_mipi_set_invert(lv_display_t * disp, bool invert); + +/** + * Set address mode + * @param disp display object + * @param mirror_x horizontal mirror (false: normal, true: mirrored) + * @param mirror_y vertical mirror (false: normal, true: mirrored) + * @param swap_xy swap axes (false: normal, true: swap) + * @param bgr RGB/BGR order (false: RGB, true: BGR) + */ +void lv_lcd_generic_mipi_set_address_mode(lv_display_t * disp, bool mirror_x, bool mirror_y, bool swap_xy, bool bgr); + +/** + * Set gamma curve + * @param disp display object + * @param gamma gamma curve + */ +void lv_lcd_generic_mipi_set_gamma_curve(lv_display_t * disp, uint8_t gamma); + +/** + * Send list of commands. + * @param disp display object + * @param cmd_list controller and panel-specific commands + */ +void lv_lcd_generic_mipi_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list); + +/********************** + * OTHERS + **********************/ + +/********************** + * MACROS + **********************/ + + +#endif /*LV_USE_GENERIC_MIPI*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LCD_GENERIC_MIPI_H*/ diff --git a/test/include/liblvgl/drivers/display/renesas_glcdc/lv_renesas_glcdc.h b/test/include/liblvgl/drivers/display/renesas_glcdc/lv_renesas_glcdc.h new file mode 100644 index 00000000..0558614e --- /dev/null +++ b/test/include/liblvgl/drivers/display/renesas_glcdc/lv_renesas_glcdc.h @@ -0,0 +1,57 @@ +/** + * @file lv_renesas_glcdc.h + * + */ + +#ifndef LV_RENESAS_GLCDC_H +#define LV_RENESAS_GLCDC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../display/lv_display.h" + +#if LV_USE_RENESAS_GLCDC + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a display using Renesas' GLCDC peripherial in DIRECT render mode + * @return pointer to the created display + */ +lv_display_t * lv_renesas_glcdc_direct_create(void); + +/** + * Create a display using Renesas' GLCDC peripherial in PARTIAL render mode + * @param buf1 first buffer + * @param buf2 second buffer (can be `NULL`) + * @param buf_size buffer size in byte + * @return pointer to the created display + */ +lv_display_t * lv_renesas_glcdc_partial_create(void * buf1, void * buf2, size_t buf_size); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_RENESAS_GLCDC */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_RENESAS_GLCDC_H */ diff --git a/test/include/liblvgl/drivers/display/st7735/lv_st7735.h b/test/include/liblvgl/drivers/display/st7735/lv_st7735.h new file mode 100644 index 00000000..c19e9fad --- /dev/null +++ b/test/include/liblvgl/drivers/display/st7735/lv_st7735.h @@ -0,0 +1,93 @@ +/** + * @file lv_st7735.h + * + * This driver is just a wrapper around the generic MIPI compatible LCD controller driver + * + */ + +#ifndef LV_ST7735_H +#define LV_ST7735_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lcd/lv_lcd_generic_mipi.h" + +#if LV_USE_ST7735 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef lv_lcd_send_cmd_cb_t lv_st7735_send_cmd_cb_t; +typedef lv_lcd_send_color_cb_t lv_st7735_send_color_cb_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an LCD display with ST7735 driver + * @param hor_res horizontal resolution + * @param ver_res vertical resolution + * @param flags default configuration settings (mirror, RGB ordering, etc.) + * @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer) + * @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback) + * @return pointer to the created display + */ +lv_display_t * lv_st7735_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags, + lv_st7735_send_cmd_cb_t send_cmd_cb, lv_st7735_send_color_cb_t send_color_cb); + +/** + * Set gap, i.e., the offset of the (0,0) pixel in the VRAM + * @param disp display object + * @param x x offset + * @param y y offset + */ +void lv_st7735_set_gap(lv_display_t * disp, uint16_t x, uint16_t y); + +/** + * Set color inversion + * @param disp display object + * @param invert false: normal, true: invert + */ +void lv_st7735_set_invert(lv_display_t * disp, bool invert); + +/** + * Set gamma curve + * @param disp display object + * @param gamma gamma curve + */ +void lv_st7735_set_gamma_curve(lv_display_t * disp, uint8_t gamma); + +/** + * Send list of commands. + * @param disp display object + * @param cmd_list controller and panel-specific commands + */ +void lv_st7735_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list); + +/********************** + * OTHERS + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_ST7735*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ST7735_H*/ diff --git a/test/include/liblvgl/drivers/display/st7789/lv_st7789.h b/test/include/liblvgl/drivers/display/st7789/lv_st7789.h new file mode 100644 index 00000000..9770432a --- /dev/null +++ b/test/include/liblvgl/drivers/display/st7789/lv_st7789.h @@ -0,0 +1,94 @@ +/** + * @file lv_st7789.h + * + * This driver is just a wrapper around the generic MIPI compatible LCD controller driver + * + */ + +#ifndef LV_ST7789_H +#define LV_ST7789_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lcd/lv_lcd_generic_mipi.h" + +#if LV_USE_ST7789 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef lv_lcd_send_cmd_cb_t lv_st7789_send_cmd_cb_t; +typedef lv_lcd_send_color_cb_t lv_st7789_send_color_cb_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an LCD display with ST7789 driver + * @param hor_res horizontal resolution + * @param ver_res vertical resolution + * @param flags default configuration settings (mirror, RGB ordering, etc.) + * @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer) + * @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback) + * @return pointer to the created display + */ +lv_display_t * lv_st7789_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags, + lv_st7789_send_cmd_cb_t send_cmd_cb, lv_st7789_send_color_cb_t send_color_cb); + +/** + * Set gap, i.e., the offset of the (0,0) pixel in the VRAM + * @param disp display object + * @param x x offset + * @param y y offset + */ +void lv_st7789_set_gap(lv_display_t * disp, uint16_t x, uint16_t y); + +/** + * Set color inversion + * @param disp display object + * @param invert false: normal, true: invert + */ +void lv_st7789_set_invert(lv_display_t * disp, bool invert); + +/** + * Set gamma curve + * @param disp display object + * @param gamma gamma curve + */ +void lv_st7789_set_gamma_curve(lv_display_t * disp, uint8_t gamma); + +/** + * Send list of commands. + * @param disp display object + * @param cmd_list controller and panel-specific commands + */ +void lv_st7789_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list); + +/********************** + * OTHERS + **********************/ + +/********************** + * MACROS + **********************/ + + +#endif /*LV_USE_ST7789*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ST7789_H*/ diff --git a/test/include/liblvgl/drivers/display/st7796/lv_st7796.h b/test/include/liblvgl/drivers/display/st7796/lv_st7796.h new file mode 100644 index 00000000..79d7a883 --- /dev/null +++ b/test/include/liblvgl/drivers/display/st7796/lv_st7796.h @@ -0,0 +1,93 @@ +/** + * @file lv_st7796.h + * + * This driver is just a wrapper around the generic MIPI compatible LCD controller driver + * + */ + +#ifndef LV_ST7796_H +#define LV_ST7796_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lcd/lv_lcd_generic_mipi.h" + +#if LV_USE_ST7796 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef lv_lcd_send_cmd_cb_t lv_st7796_send_cmd_cb_t; +typedef lv_lcd_send_color_cb_t lv_st7796_send_color_cb_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an LCD display with ST7796 driver + * @param hor_res horizontal resolution + * @param ver_res vertical resolution + * @param flags default configuration settings (mirror, RGB ordering, etc.) + * @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer) + * @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback) + * @return pointer to the created display + */ +lv_display_t * lv_st7796_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags, + lv_st7796_send_cmd_cb_t send_cmd_cb, lv_st7796_send_color_cb_t send_color_cb); + +/** + * Set gap, i.e., the offset of the (0,0) pixel in the VRAM + * @param disp display object + * @param x x offset + * @param y y offset + */ +void lv_st7796_set_gap(lv_display_t * disp, uint16_t x, uint16_t y); + +/** + * Set color inversion + * @param disp display object + * @param invert false: normal, true: invert + */ +void lv_st7796_set_invert(lv_display_t * disp, bool invert); + +/** + * Set gamma curve + * @param disp display object + * @param gamma gamma curve + */ +void lv_st7796_set_gamma_curve(lv_display_t * disp, uint8_t gamma); + +/** + * Send list of commands. + * @param disp display object + * @param cmd_list controller and panel-specific commands + */ +void lv_st7796_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list); + +/********************** + * OTHERS + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_ST7796*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ST7796_H*/ diff --git a/test/include/liblvgl/drivers/display/st_ltdc/lv_st_ltdc.h b/test/include/liblvgl/drivers/display/st_ltdc/lv_st_ltdc.h new file mode 100644 index 00000000..69a0e7b7 --- /dev/null +++ b/test/include/liblvgl/drivers/display/st_ltdc/lv_st_ltdc.h @@ -0,0 +1,65 @@ +/** + * @file lv_st_ltdc.h + * + */ + +#ifndef LV_ST_LTDC_H +#define LV_ST_LTDC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_ST_LTDC + +#include "../../../display/lv_display.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a direct render mode display bound to a LTDC layer. + * @param fb_adr_1 The LTDC layer's framebuffer memory address. + * @param fb_adr_2 An additional framebuffer-sized buffer to use for double buffering, or `NULL`. + * @param layer_idx The LTDC layer number to bind the display to. Typically 0 or 1. + * @return The display. + */ +lv_display_t * lv_st_ltdc_create_direct(void * fb_adr_1, void * fb_adr_2, uint32_t layer_idx); + +/** + * Create a partial render mode display bound to a LTDC layer. The layer's framebuffer is flushed to internally. + * Enable `LV_ST_LTDC_USE_DMA2D_FLUSH` for parallel flushing. + * @param render_buf_1 A render buffer. + * @param render_buf_2 An additional render buffer for double-buffering, or `NULL`. + * @param buf_size The size of the buffer(s) in bytes. + * @param layer_idx The LTDC layer number to bind the display to. Typically 0 or 1. + * @return The display. + */ +lv_display_t * lv_st_ltdc_create_partial(void * render_buf_1, void * render_buf_2, uint32_t buf_size, + uint32_t layer_idx); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_ST_LTDC*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ST_LTDC_H*/ diff --git a/test/include/liblvgl/drivers/display/tft_espi/lv_tft_espi.cpp b/test/include/liblvgl/drivers/display/tft_espi/lv_tft_espi.cpp new file mode 100644 index 00000000..1cb7b45f --- /dev/null +++ b/test/include/liblvgl/drivers/display/tft_espi/lv_tft_espi.cpp @@ -0,0 +1,110 @@ +/** + * @file lv_tft_espi.cpp + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_tft_espi.h" +#if LV_USE_TFT_ESPI + +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + TFT_eSPI * tft; +} lv_tft_espi_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static void resolution_changed_event_cb(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_tft_espi_create(uint32_t hor_res, uint32_t ver_res, void * buf, uint32_t buf_size_bytes) +{ + lv_tft_espi_t * dsc = (lv_tft_espi_t *)lv_malloc_zeroed(sizeof(lv_tft_espi_t)); + LV_ASSERT_MALLOC(dsc); + if(dsc == NULL) return NULL; + + lv_display_t * disp = lv_display_create(hor_res, ver_res); + if(disp == NULL) { + lv_free(dsc); + return NULL; + } + + dsc->tft = new TFT_eSPI(hor_res, ver_res); + dsc->tft->begin(); /* TFT init */ + dsc->tft->setRotation(0); + lv_display_set_driver_data(disp, (void *)dsc); + lv_display_set_flush_cb(disp, flush_cb); + lv_display_add_event_cb(disp, resolution_changed_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); + lv_display_set_buffers(disp, (void *)buf, NULL, buf_size_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL); + return disp; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + lv_tft_espi_t * dsc = (lv_tft_espi_t *)lv_display_get_driver_data(disp); + + uint32_t w = (area->x2 - area->x1 + 1); + uint32_t h = (area->y2 - area->y1 + 1); + + dsc->tft->startWrite(); + dsc->tft->setAddrWindow(area->x1, area->y1, w, h); + dsc->tft->pushColors((uint16_t *)px_map, w * h, true); + dsc->tft->endWrite(); + + lv_display_flush_ready(disp); + +} + +static void resolution_changed_event_cb(lv_event_t * e) +{ + lv_display_t * disp = (lv_display_t *)lv_event_get_target(e); + lv_tft_espi_t * dsc = (lv_tft_espi_t *)lv_display_get_driver_data(disp); + int32_t hor_res = lv_display_get_horizontal_resolution(disp); + int32_t ver_res = lv_display_get_vertical_resolution(disp); + lv_display_rotation_t rot = lv_display_get_rotation(disp); + + /* handle rotation */ + switch(rot) { + case LV_DISPLAY_ROTATION_0: + dsc->tft->setRotation(0); /* Portrait orientation */ + break; + case LV_DISPLAY_ROTATION_90: + dsc->tft->setRotation(1); /* Landscape orientation */ + break; + case LV_DISPLAY_ROTATION_180: + dsc->tft->setRotation(2); /* Portrait orientation, flipped */ + break; + case LV_DISPLAY_ROTATION_270: + dsc->tft->setRotation(3); /* Landscape orientation, flipped */ + break; + } +} + +#endif /*LV_USE_TFT_ESPI*/ diff --git a/test/include/liblvgl/drivers/display/tft_espi/lv_tft_espi.h b/test/include/liblvgl/drivers/display/tft_espi/lv_tft_espi.h new file mode 100644 index 00000000..a8f49f89 --- /dev/null +++ b/test/include/liblvgl/drivers/display/tft_espi/lv_tft_espi.h @@ -0,0 +1,43 @@ +/** + * @file lv_tft_espi.h + * + */ + +#ifndef LV_TFT_ESPI_H +#define LV_TFT_ESPI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../display/lv_display.h" + +#if LV_USE_TFT_ESPI + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +lv_display_t * lv_tft_espi_create(uint32_t hor_res, uint32_t ver_res, void * buf, uint32_t buf_size_bytes); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_TFT_ESPI */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_TFT_ESPI_H */ diff --git a/test/include/liblvgl/drivers/evdev/lv_evdev.h b/test/include/liblvgl/drivers/evdev/lv_evdev.h new file mode 100644 index 00000000..95ab1544 --- /dev/null +++ b/test/include/liblvgl/drivers/evdev/lv_evdev.h @@ -0,0 +1,64 @@ +/** + * @file lv_evdev.h + * + */ + +#ifndef LV_EVDEV_H +#define LV_EVDEV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../indev/lv_indev.h" + +#if LV_USE_EVDEV + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create evdev input device. + * @param type LV_INDEV_TYPE_POINTER or LV_INDEV_TYPE_KEYPAD + * @param dev_path device path, e.g., /dev/input/event0 + * @return pointer to input device or NULL if opening failed + */ +lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path); + +/** + * Set whether coordinates of pointer device should be swapped. Defaults to + * false. + * @param indev evdev input device + * @param swap_axes whether to swap x and y axes + */ +void lv_evdev_set_swap_axes(lv_indev_t * indev, bool swap_axes); + +/** + * Configure a coordinate transformation for pointer devices. Applied after + * axis swap, if any. Defaults to apply no transformation. + * @param indev evdev input device + * @param min_x pointer coordinate mapped to min x of display + * @param min_y pointer coordinate mapped to min y of display + * @param max_x pointer coordinate mapped to max x of display + * @param max_y pointer coordinate mapped to max y of display + */ +void lv_evdev_set_calibration(lv_indev_t * indev, int min_x, int min_y, int max_x, int max_y); + +/** + * Remove evdev input device. + * @param indev evdev input device to close and free + */ +void lv_evdev_delete(lv_indev_t * indev); + +#endif /*LV_USE_EVDEV*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_EVDEV_H*/ diff --git a/test/include/liblvgl/drivers/glfw/lv_glfw_window.h b/test/include/liblvgl/drivers/glfw/lv_glfw_window.h new file mode 100644 index 00000000..e8e51610 --- /dev/null +++ b/test/include/liblvgl/drivers/glfw/lv_glfw_window.h @@ -0,0 +1,108 @@ +/** + * @file lv_glfw_window.h + * + */ + +#ifndef LV_GLFW_WINDOW_H +#define LV_GLFW_WINDOW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_OPENGLES + +#include "../../misc/lv_types.h" +#include "../../display/lv_display.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a GLFW window with no textures and initialize OpenGL + * @param hor_res width in pixels of the window + * @param ver_res height in pixels of the window + * @param use_mouse_indev send pointer indev input to LVGL display textures + * @return the new GLFW window handle + */ +lv_glfw_window_t * lv_glfw_window_create(int32_t hor_res, int32_t ver_res, bool use_mouse_indev); + +/** + * Delete a GLFW window. If it is the last one, the process will exit + * @param window GLFW window to delete + */ +void lv_glfw_window_delete(lv_glfw_window_t * window); + +/** + * Add a texture to the GLFW window. It can be an LVGL display texture, or any OpenGL texture + * @param window GLFW window + * @param texture_id OpenGL texture ID + * @param w width in pixels of the texture + * @param h height in pixels of the texture + * @return the new texture handle + */ +lv_glfw_texture_t * lv_glfw_window_add_texture(lv_glfw_window_t * window, unsigned int texture_id, int32_t w, + int32_t h); + +/** + * Remove a texture from its GLFW window and delete it + * @param texture handle of a GLFW window texture + */ +void lv_glfw_texture_remove(lv_glfw_texture_t * texture); + +/** + * Set the x position of a texture within its GLFW window + * @param texture handle of a GLFW window texture + * @param x new x position of the texture + */ +void lv_glfw_texture_set_x(lv_glfw_texture_t * texture, int32_t x); + +/** + * Set the y position of a texture within its GLFW window + * @param texture handle of a GLFW window texture + * @param y new y position of the texture + */ +void lv_glfw_texture_set_y(lv_glfw_texture_t * texture, int32_t y); + +/** + * Set the opacity of a texture in a GLFW window + * @param texture handle of a GLFW window texture + * @param opa new opacity of the texture + */ +void lv_glfw_texture_set_opa(lv_glfw_texture_t * texture, lv_opa_t opa); + +/** + * Get the mouse indev associated with a texture in a GLFW window, if it exists + * @param texture handle of a GLFW window texture + * @return the indev or `NULL` + * @note there will only be an indev if the texture is based on an + * LVGL display texture and the window was created with + * `use_mouse_indev` as `true` + */ +lv_indev_t * lv_glfw_texture_get_mouse_indev(lv_glfw_texture_t * texture); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_GLFW_WINDOW_H */ diff --git a/test/include/liblvgl/drivers/glfw/lv_glfw_window_private.h b/test/include/liblvgl/drivers/glfw/lv_glfw_window_private.h new file mode 100644 index 00000000..cc6cac09 --- /dev/null +++ b/test/include/liblvgl/drivers/glfw/lv_glfw_window_private.h @@ -0,0 +1,70 @@ +/** + * @file lv_glfw_window_private.h + * + */ + +#ifndef LV_GLFW_WINDOW_PRIVATE_H +#define LV_GLFW_WINDOW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_glfw_window.h" +#if LV_USE_OPENGLES + +#include +#include + +#include "../../misc/lv_area.h" +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_glfw_window_t { + GLFWwindow * window; + int32_t hor_res; + int32_t ver_res; + lv_ll_t textures; + lv_point_t mouse_last_point; + lv_indev_state_t mouse_last_state; + uint8_t use_indev : 1; + uint8_t closing : 1; +}; + +struct _lv_glfw_texture_t { + lv_glfw_window_t * window; + unsigned int texture_id; + lv_area_t area; + lv_opa_t opa; + lv_indev_t * indev; + lv_point_t indev_last_point; + lv_indev_state_t indev_last_state; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OPENGLES*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GLFW_WINDOW_PRIVATE_H*/ diff --git a/test/include/liblvgl/drivers/glfw/lv_opengles_debug.h b/test/include/liblvgl/drivers/glfw/lv_opengles_debug.h new file mode 100644 index 00000000..aa8bbebe --- /dev/null +++ b/test/include/liblvgl/drivers/glfw/lv_opengles_debug.h @@ -0,0 +1,40 @@ +/** + * @file lv_opengles_debug.h + * + */ + +#ifndef LV_OPENGLES_DEBUG_H +#define LV_OPENGLES_DEBUG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../lv_conf_internal.h" +#if LV_USE_OPENGLES + +#include +#include +#include + +void GLClearError(void); + +void GLLogCall(const char * function, const char * file, int line); + +#if LV_USE_OPENGLES_DEBUG +#define GL_CALL(x) do {\ + GLClearError();\ + x;\ + GLLogCall(#x, __FILE__, __LINE__);\ + } while(0) +#else +#define GL_CALL(x) x +#endif + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_OPENGLES_DEBUG_H */ diff --git a/test/include/liblvgl/drivers/glfw/lv_opengles_driver.h b/test/include/liblvgl/drivers/glfw/lv_opengles_driver.h new file mode 100644 index 00000000..34bda861 --- /dev/null +++ b/test/include/liblvgl/drivers/glfw/lv_opengles_driver.h @@ -0,0 +1,92 @@ +/** + * @file lv_opengles_driver.h + * + */ + +#ifndef LV_OPENGLES_DRIVER_H +#define LV_OPENGLES_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_OPENGLES + +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize OpenGL + * @note it is not necessary to call this if you use `lv_glfw_window_create` + */ +void lv_opengles_init(void); + +/** + * Deinitialize OpenGL + * @note it is not necessary to call this if you use `lv_glfw_window_create` + */ +void lv_opengles_deinit(void); + +/** + * Render a texture + * @param texture OpenGL texture ID + * @param texture_area the area in the window to render the texture in + * @param opa opacity to blend the texture with existing contents + * @param disp_w width of the window/framebuffer being rendered to + * @param disp_h height of the window/framebuffer being rendered to + */ +void lv_opengles_render_texture(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, int32_t disp_w, + int32_t disp_h, const lv_area_t * texture_clip_area, bool flip); + +/** + * Render a fill + * @param color the color of the fill + * @param area the area in the window to render the fill + * @param opa opacity to blend the fill with existing contents + * @param disp_w width of the window/framebuffer being rendered to + * @param disp_h height of the window/framebuffer being rendered to + */ +void lv_opengles_render_fill(lv_color_t color, const lv_area_t * area, lv_opa_t opa, int32_t disp_w, int32_t disp_h); + +/** + * Clear the window/display + */ +void lv_opengles_render_clear(void); + +/** + * Set the OpenGL viewport + * @param x x position of the viewport + * @param y y position of the viewport + * @param w width of the viewport + * @param h height of the viewport + */ +void lv_opengles_viewport(int32_t x, int32_t y, int32_t w, int32_t h); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_OPENGLES_DRIVER_H */ diff --git a/test/include/liblvgl/drivers/glfw/lv_opengles_texture.h b/test/include/liblvgl/drivers/glfw/lv_opengles_texture.h new file mode 100644 index 00000000..0d53b2b1 --- /dev/null +++ b/test/include/liblvgl/drivers/glfw/lv_opengles_texture.h @@ -0,0 +1,66 @@ +/** + * @file lv_opengles_texture.h + * + */ + +#ifndef LV_OPENGLES_TEXTURE_H +#define LV_OPENGLES_TEXTURE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_OPENGLES + +#include "../../display/lv_display.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a display that flushes to an OpenGL texture + * @param w width in pixels of the texture + * @param h height in pixels of the texture + * @return the new display + */ +lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h); + +/** + * Get the OpenGL texture ID of the display + * @param disp display + * @return texture ID + */ +unsigned int lv_opengles_texture_get_texture_id(lv_display_t * disp); + +/** + * Get the display of an OpenGL texture if it is associated with one + * @param texture_id OpenGL texture ID + * @return display or `NULL` if there no display with that texture ID + */ +lv_display_t * lv_opengles_texture_get_from_texture_id(unsigned int texture_id); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OPENGLES_TEXTURE_H*/ diff --git a/test/include/liblvgl/drivers/libinput/lv_libinput.h b/test/include/liblvgl/drivers/libinput/lv_libinput.h new file mode 100644 index 00000000..ce19a33b --- /dev/null +++ b/test/include/liblvgl/drivers/libinput/lv_libinput.h @@ -0,0 +1,101 @@ +/** + * @file lv_libinput.h + * + */ + +#ifndef LV_LIBINPUT_H +#define LV_LIBINPUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../indev/lv_indev.h" + +#if LV_USE_LIBINPUT + +#include +#include + +#if LV_LIBINPUT_XKB +#include "lv_xkb.h" +#endif /* LV_LIBINPUT_XKB */ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_LIBINPUT_CAPABILITY_NONE = 0, + LV_LIBINPUT_CAPABILITY_KEYBOARD = 1U << 0, + LV_LIBINPUT_CAPABILITY_POINTER = 1U << 1, + LV_LIBINPUT_CAPABILITY_TOUCH = 1U << 2 +} lv_libinput_capability; + +struct libinput_device; + +#define LV_LIBINPUT_MAX_EVENTS 32 + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Determine the capabilities of a specific libinput device. + * @param device the libinput device to query + * @return the supported input capabilities + */ +lv_libinput_capability lv_libinput_query_capability(struct libinput_device * device); + +/** + * Find connected input device with specific capabilities + * @param capabilities required device capabilities + * @param force_rescan erase the device cache (if any) and rescan the file system for available devices + * @return device node path (e.g. /dev/input/event0) for the first matching device or NULL if no device was found. + * The pointer is safe to use until the next forceful device search. + */ +char * lv_libinput_find_dev(lv_libinput_capability capabilities, bool force_rescan); + +/** + * Find connected input devices with specific capabilities + * @param capabilities required device capabilities + * @param devices pre-allocated array to store the found device node paths (e.g. /dev/input/event0). The pointers are + * safe to use until the next forceful device search. + * @param count maximum number of devices to find (the devices array should be at least this long) + * @param force_rescan erase the device cache (if any) and rescan the file system for available devices + * @return number of devices that were found + */ +size_t lv_libinput_find_devs(lv_libinput_capability capabilities, char ** found, size_t count, bool force_rescan); + +/** + * Create a new libinput input device + * @param type LV_INDEV_TYPE_POINTER or LV_INDEV_TYPE_KEYPAD + * @param dev_path device path, e.g. /dev/input/event0 + * @return pointer to input device or NULL if opening failed + */ +lv_indev_t * lv_libinput_create(lv_indev_type_t indev_type, const char * dev_path); + +/** + * Delete a libinput input device + * @param indev pointer to input device + */ +void lv_libinput_delete(lv_indev_t * indev); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LIBINPUT */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_LIBINPUT_H */ diff --git a/test/include/liblvgl/drivers/libinput/lv_libinput_private.h b/test/include/liblvgl/drivers/libinput/lv_libinput_private.h new file mode 100644 index 00000000..2856bbef --- /dev/null +++ b/test/include/liblvgl/drivers/libinput/lv_libinput_private.h @@ -0,0 +1,83 @@ +/** + * @file lv_libinput_private.h + * + */ + +#ifndef LV_LIBINPUT_PRIVATE_H +#define LV_LIBINPUT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_libinput.h" + +#if LV_USE_LIBINPUT + +#if LV_LIBINPUT_XKB +#include "lv_xkb_private.h" +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_libinput_event_t { + lv_indev_state_t pressed; + int key_val; + lv_point_t point; +}; + +struct _lv_libinput_t { + int fd; + struct pollfd fds[1]; + + /* The points array is implemented as a circular LIFO queue */ + lv_libinput_event_t points[LV_LIBINPUT_MAX_EVENTS]; /* Event buffer */ + lv_libinput_event_t slots[2]; /* Realtime state of up to 2 fingers to handle multitouch */ + + /* Pointer devices work a bit differently in libinput which requires us to store their last known state */ + lv_point_t pointer_position; + bool pointer_button_down; + + int start; /* Index of start of event queue */ + int end; /* Index of end of queue*/ + lv_libinput_event_t last_event; /* Report when no new events + * to keep indev state consistent + */ + bool deinit; /* Tell worker thread to quit */ + pthread_mutex_t event_lock; + pthread_t worker_thread; + + struct libinput * libinput_context; + struct libinput_device * libinput_device; + +#if LV_LIBINPUT_XKB + lv_xkb_t xkb; +#endif /* LV_LIBINPUT_XKB */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LIBINPUT */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LIBINPUT_PRIVATE_H*/ diff --git a/test/include/liblvgl/drivers/libinput/lv_xkb.h b/test/include/liblvgl/drivers/libinput/lv_xkb.h new file mode 100644 index 00000000..3f9fd86e --- /dev/null +++ b/test/include/liblvgl/drivers/libinput/lv_xkb.h @@ -0,0 +1,64 @@ +/** + * @file lv_xkb.h + * + */ + +#ifndef LV_XKB_H +#define LV_XKB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" + +#if defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB + +#include "../../misc/lv_types.h" +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialise an XKB descriptor. + * @return true if the initialisation was successful + */ +bool lv_xkb_init(lv_xkb_t * dsc, struct xkb_rule_names names); + +/** + * De-initialise an XKB descriptor. + * @param dsc Pointer to descriptor + */ +void lv_xkb_deinit(lv_xkb_t * dsc); + +/** + * Process an evdev scancode using a specific XKB descriptor. + * @param state XKB descriptor to use + * @param scancode evdev scancode to process + * @param down true if the key was pressed, false if it was releases + * @return the (first) UTF-8 character produced by the event or 0 if no output was produced + */ +uint32_t lv_xkb_process_key(lv_xkb_t * dsc, uint32_t scancode, bool down); + +/********************** + * MACROS + **********************/ + +#endif /* LV_LIBINPUT_XKB */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB */ diff --git a/test/include/liblvgl/drivers/libinput/lv_xkb_private.h b/test/include/liblvgl/drivers/libinput/lv_xkb_private.h new file mode 100644 index 00000000..97aad749 --- /dev/null +++ b/test/include/liblvgl/drivers/libinput/lv_xkb_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_xkb_private.h + * + */ + +#ifndef LV_XKB_PRIVATE_H +#define LV_XKB_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_xkb.h" + +#if defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_xkb_t { + struct xkb_keymap * keymap; + struct xkb_state * state; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XKB_PRIVATE_H*/ diff --git a/test/include/liblvgl/drivers/lv_drivers.h b/test/include/liblvgl/drivers/lv_drivers.h new file mode 100644 index 00000000..621f1565 --- /dev/null +++ b/test/include/liblvgl/drivers/lv_drivers.h @@ -0,0 +1,77 @@ +/** + * @file lv_drivers.h + * + */ + +#ifndef LV_DRIVERS_H +#define LV_DRIVERS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "sdl/lv_sdl_window.h" +#include "sdl/lv_sdl_mouse.h" +#include "sdl/lv_sdl_mousewheel.h" +#include "sdl/lv_sdl_keyboard.h" + +#include "x11/lv_x11.h" + +#include "display/drm/lv_linux_drm.h" +#include "display/fb/lv_linux_fbdev.h" + +#include "display/tft_espi/lv_tft_espi.h" + +#include "display/lcd/lv_lcd_generic_mipi.h" +#include "display/ili9341/lv_ili9341.h" +#include "display/st7735/lv_st7735.h" +#include "display/st7789/lv_st7789.h" +#include "display/st7796/lv_st7796.h" + +#include "display/renesas_glcdc/lv_renesas_glcdc.h" +#include "display/st_ltdc/lv_st_ltdc.h" + +#include "nuttx/lv_nuttx_entry.h" +#include "nuttx/lv_nuttx_fbdev.h" +#include "nuttx/lv_nuttx_touchscreen.h" +#include "nuttx/lv_nuttx_lcd.h" +#include "nuttx/lv_nuttx_libuv.h" + +#include "evdev/lv_evdev.h" +#include "libinput/lv_libinput.h" + +#include "windows/lv_windows_input.h" +#include "windows/lv_windows_display.h" + +#include "glfw/lv_glfw_window.h" +#include "glfw/lv_opengles_texture.h" +#include "glfw/lv_opengles_driver.h" + +#include "qnx/lv_qnx.h" + +#include "wayland/lv_wayland.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRIVERS_H*/ diff --git a/test/include/liblvgl/drivers/nuttx/lv_nuttx_cache.h b/test/include/liblvgl/drivers/nuttx/lv_nuttx_cache.h new file mode 100644 index 00000000..74be6d3a --- /dev/null +++ b/test/include/liblvgl/drivers/nuttx/lv_nuttx_cache.h @@ -0,0 +1,41 @@ +/** + * @file lv_nuttx_cache.h + * + */ + +#ifndef LV_NUTTX_CACHE_H +#define LV_NUTTX_CACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_nuttx_cache_init(void); + +void lv_nuttx_cache_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_NUTTX_CACHE_H*/ diff --git a/test/include/liblvgl/drivers/nuttx/lv_nuttx_entry.h b/test/include/liblvgl/drivers/nuttx/lv_nuttx_entry.h new file mode 100644 index 00000000..049e741e --- /dev/null +++ b/test/include/liblvgl/drivers/nuttx/lv_nuttx_entry.h @@ -0,0 +1,112 @@ +/** + * @file lv_nuttx_entry.h + * + */ + +/********************* + * INCLUDES + *********************/ + +#ifndef LV_NUTTX_ENTRY_H +#define LV_NUTTX_ENTRY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_NUTTX + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + const char * fb_path; + const char * input_path; + const char * utouch_path; +} lv_nuttx_dsc_t; + +typedef struct { + lv_display_t * disp; + lv_indev_t * indev; + lv_indev_t * utouch_indev; +} lv_nuttx_result_t; + +typedef struct _lv_nuttx_ctx_t { + void * image_cache; +} lv_nuttx_ctx_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the lv_nuttx_dsc_t structure with default values for the NuttX port of LVGL. + * @param dsc Pointer to the lv_nuttx_dsc_t structure to be initialized. + */ +void lv_nuttx_dsc_init(lv_nuttx_dsc_t * dsc); + +/** + * Initialize the LVGL display driver for NuttX using the provided configuration information. + * @param dsc Pointer to the lv_nuttx_dsc_t structure containing the configuration information for the display driver. + * @param result Pointer to the lv_nuttx_result_t structure containing display and input device handler. + */ +void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result); + +/** + * Deinitialize the LVGL display driver for NuttX. + * @param result Pointer to the lv_nuttx_result_t structure containing display and input device handler. + */ +void lv_nuttx_deinit(lv_nuttx_result_t * result); + +#if LV_USE_NUTTX_CUSTOM_INIT +/** + * Initialize the LVGL display driver for NuttX using the provided custom configuration information. + * @param dsc Pointer to the lv_nuttx_dsc_t structure containing the custom configuration for the display driver. + * @param result Pointer to the lv_nuttx_result_t structure containing display and input device handler. + */ +void lv_nuttx_init_custom(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result); + +/** + * Deinitialize the LVGL display driver for NuttX using the provided custom configuration information. + * @param result Pointer to the lv_nuttx_result_t structure containing display and input device handler. + */ +void lv_nuttx_deinit_custom(lv_nuttx_result_t * result); +#endif /* LV_USE_NUTTX_CUSTOM_INIT */ + +/** + * Call `lv_timer_handler()` (LVGL's super loop) in an endless loop. + * If LV_USE_NUTTX_LIBUV is enabled an UV timer will be created, + * else `lv_timer_handler()` will be called in a loop with some sleep. + * @param result pointer to a variable initialized by `lv_nuttx_init()` or `lv_nuttx_init_custom()` + */ +void lv_nuttx_run(lv_nuttx_result_t * result); + +/** + * Get the idle percentage of the system. + * @return The idle percentage of the system. + */ +uint32_t lv_nuttx_get_idle(void); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_NUTTX*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_NUTTX_ENTRY_H */ diff --git a/test/include/liblvgl/drivers/nuttx/lv_nuttx_fbdev.h b/test/include/liblvgl/drivers/nuttx/lv_nuttx_fbdev.h new file mode 100644 index 00000000..4310aa9c --- /dev/null +++ b/test/include/liblvgl/drivers/nuttx/lv_nuttx_fbdev.h @@ -0,0 +1,55 @@ +/** + * @file lv_nuttx_fbdev.h + * + */ + +#ifndef LV_NUTTX_FBDEV_H +#define LV_NUTTX_FBDEV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" + +#if LV_USE_NUTTX + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a new display with NuttX backend. + */ +lv_display_t * lv_nuttx_fbdev_create(void); + +/** + * Initialize display with specified framebuffer device + * @param disp pointer to display with NuttX backend + * @param file the name of framebuffer device + */ +int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_NUTTX */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_NUTTX_FBDEV_H */ diff --git a/test/include/liblvgl/drivers/nuttx/lv_nuttx_image_cache.h b/test/include/liblvgl/drivers/nuttx/lv_nuttx_image_cache.h new file mode 100644 index 00000000..0e056b4a --- /dev/null +++ b/test/include/liblvgl/drivers/nuttx/lv_nuttx_image_cache.h @@ -0,0 +1,44 @@ +/** + * @file lv_nuttx_image_cache.h + * + */ + +#ifndef LV_NUTTX_IMAGE_CACHE_H +#define LV_NUTTX_IMAGE_CACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#include LV_STDBOOL_INCLUDE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_nuttx_image_cache_init(bool use_independent_image_heap); + +void lv_nuttx_image_cache_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_NUTTX_IMAGE_CACHE_H*/ diff --git a/test/include/liblvgl/drivers/nuttx/lv_nuttx_lcd.h b/test/include/liblvgl/drivers/nuttx/lv_nuttx_lcd.h new file mode 100644 index 00000000..16e24ff8 --- /dev/null +++ b/test/include/liblvgl/drivers/nuttx/lv_nuttx_lcd.h @@ -0,0 +1,49 @@ +/** + * @file lv_nuttx_lcd.h + * + */ + +#ifndef LV_NUTTX_LCD_H +#define LV_NUTTX_LCD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" + +#if LV_USE_NUTTX + +#if LV_USE_NUTTX_LCD + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_display_t * lv_nuttx_lcd_create(const char * dev_path); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_NUTTX_LCD */ + +#endif /* LV_USE_NUTTX*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_NUTTX_LCD_H */ diff --git a/test/include/liblvgl/drivers/nuttx/lv_nuttx_libuv.h b/test/include/liblvgl/drivers/nuttx/lv_nuttx_libuv.h new file mode 100644 index 00000000..0799e67b --- /dev/null +++ b/test/include/liblvgl/drivers/nuttx/lv_nuttx_libuv.h @@ -0,0 +1,66 @@ +/** + * @file lv_nuttx_libuv.h + * + */ + +#ifndef LV_NUTTX_LIBUV_H +#define LV_NUTTX_LIBUV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_NUTTX + +#if LV_USE_NUTTX_LIBUV + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + void * loop; + lv_display_t * disp; + lv_indev_t * indev; +} lv_nuttx_uv_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the uv_loop using the provided configuration information. + * @param uv_info Pointer to the lv_nuttx_uv_t structure to be initialized. + */ +void * lv_nuttx_uv_init(lv_nuttx_uv_t * uv_info); + +/** + * Deinitialize the uv_loop configuration for NuttX porting layer. + * @param data Pointer to user data. + */ +void lv_nuttx_uv_deinit(void ** data); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_NUTTX_LIBUV*/ + +#endif /*LV_USE_NUTTX*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_NUTTX_LIBUV_H*/ diff --git a/test/include/liblvgl/drivers/nuttx/lv_nuttx_profiler.h b/test/include/liblvgl/drivers/nuttx/lv_nuttx_profiler.h new file mode 100644 index 00000000..8b8cf652 --- /dev/null +++ b/test/include/liblvgl/drivers/nuttx/lv_nuttx_profiler.h @@ -0,0 +1,39 @@ +/** + * @file lv_nuttx_profiler.h + * + */ + +#ifndef LV_NUTTX_PROFILER_H +#define LV_NUTTX_PROFILER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_nuttx_profiler_init(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_NUTTX_PROFILER_H*/ diff --git a/test/include/liblvgl/drivers/nuttx/lv_nuttx_touchscreen.h b/test/include/liblvgl/drivers/nuttx/lv_nuttx_touchscreen.h new file mode 100644 index 00000000..e0dd1f14 --- /dev/null +++ b/test/include/liblvgl/drivers/nuttx/lv_nuttx_touchscreen.h @@ -0,0 +1,57 @@ +/** + * @file lv_nuttx_touchscreen.h + * + */ + +/********************* + * INCLUDES + *********************/ + +#ifndef LV_NUTTX_TOUCHSCREEN_H +#define LV_NUTTX_TOUCHSCREEN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../indev/lv_indev.h" + +#if LV_USE_NUTTX + +#if LV_USE_NUTTX_TOUCHSCREEN + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize indev with specified input device. + * @param dev_path path of input device + */ +lv_indev_t * lv_nuttx_touchscreen_create(const char * dev_path); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_NUTTX_TOUCHSCREEN */ + +#endif /* LV_USE_NUTTX*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_NUTTX_TOUCHSCREEN_H */ diff --git a/test/include/liblvgl/drivers/qnx/lv_qnx.h b/test/include/liblvgl/drivers/qnx/lv_qnx.h new file mode 100644 index 00000000..bb8f9409 --- /dev/null +++ b/test/include/liblvgl/drivers/qnx/lv_qnx.h @@ -0,0 +1,86 @@ +/** + * @file lv_qnx.h + * @brief LVGL driver for the QNX Screen compositing window manager + */ + +#ifndef LV_QNX_H +#define LV_QNX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_QNX + +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a window to use as a display for LVGL. + * @param hor_res The horizontal resolution (size) of the window + * @param ver_res The vertical resolution (size) of the window + * @return A pointer to a new display object if successful, NULL otherwise + */ +lv_display_t * lv_qnx_window_create(int32_t hor_res, int32_t ver_res); + +/** + * Set the title of the window identified by the given display. + * @param disp The display object for the window + * @param title The new title to set + */ +void lv_qnx_window_set_title(lv_display_t * disp, const char * title); + +/** + * Create a pointer input device for the display. + * Only one pointer object is currently supported. + * @param disp The display object associated with the device + * @return true if successful, false otherwise + */ +bool lv_qnx_add_pointer_device(lv_display_t * disp); + +/** + * Create a keyboard input device for the display. + * Only one keyboard object is currently supported. + * @param disp The display object associated with the device + * @return true if successful, false otherwise + */ +bool lv_qnx_add_keyboard_device(lv_display_t * disp); + +/** + * Runs the event loop for the display. + * The function only returns in response to a close event. + * @param disp The display for the event loop + * @return Exit code + */ +int lv_qnx_event_loop(lv_display_t * disp); + +/********************** + * MACROS + **********************/ + +#endif /* LV_DRV_QNX */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_QNX_H */ diff --git a/test/include/liblvgl/drivers/sdl/lv_sdl_keyboard.h b/test/include/liblvgl/drivers/sdl/lv_sdl_keyboard.h new file mode 100644 index 00000000..a18b09d8 --- /dev/null +++ b/test/include/liblvgl/drivers/sdl/lv_sdl_keyboard.h @@ -0,0 +1,46 @@ +/** + * @file lv_sdl_keyboard.h + * + */ + +#ifndef LV_SDL_KEYBOARD_H +#define LV_SDL_KEYBOARD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_sdl_window.h" +#if LV_USE_SDL + +/********************* + * DEFINES + *********************/ +#ifndef KEYBOARD_BUFFER_SIZE +#define KEYBOARD_BUFFER_SIZE 32 +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_indev_t * lv_sdl_keyboard_create(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SDL*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_SDL_KEYBOARD_H */ diff --git a/test/include/liblvgl/drivers/sdl/lv_sdl_mouse.h b/test/include/liblvgl/drivers/sdl/lv_sdl_mouse.h new file mode 100644 index 00000000..ef60685f --- /dev/null +++ b/test/include/liblvgl/drivers/sdl/lv_sdl_mouse.h @@ -0,0 +1,43 @@ +/** + * @file lv_sdl_mouse.h + * + */ + +#ifndef LV_SDL_MOUSE_H +#define LV_SDL_MOUSE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_sdl_window.h" +#if LV_USE_SDL + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_indev_t * lv_sdl_mouse_create(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SDL*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_SDL_MOUSE_H */ diff --git a/test/include/liblvgl/drivers/sdl/lv_sdl_mousewheel.h b/test/include/liblvgl/drivers/sdl/lv_sdl_mousewheel.h new file mode 100644 index 00000000..7ca34bdb --- /dev/null +++ b/test/include/liblvgl/drivers/sdl/lv_sdl_mousewheel.h @@ -0,0 +1,43 @@ +/** + * @file lv_sdl_mousewheel.h + * + */ + +#ifndef LV_SDL_MOUSEWHEEL_H +#define LV_SDL_MOUSEWHEEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_sdl_window.h" +#if LV_USE_SDL && LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_ENCODER + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_indev_t * lv_sdl_mousewheel_create(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SDL*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_DEV_SDL_MOUSEWHEEL_H */ diff --git a/test/include/liblvgl/drivers/sdl/lv_sdl_private.h b/test/include/liblvgl/drivers/sdl/lv_sdl_private.h new file mode 100644 index 00000000..1fd519bf --- /dev/null +++ b/test/include/liblvgl/drivers/sdl/lv_sdl_private.h @@ -0,0 +1,49 @@ +/** + * @file lv_sdl_private.h + * + */ + +#ifndef LV_SDL_PRIVATE_H +#define LV_SDL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" + +#if LV_USE_SDL + +#include LV_SDL_INCLUDE_PATH + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_sdl_keyboard_handler(SDL_Event * event); +void lv_sdl_mouse_handler(SDL_Event * event); +void lv_sdl_mousewheel_handler(SDL_Event * event); +lv_display_t * lv_sdl_get_disp_from_win_id(uint32_t win_id); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SDL*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_SDL_PRIVATE_H */ diff --git a/test/include/liblvgl/drivers/sdl/lv_sdl_window.h b/test/include/liblvgl/drivers/sdl/lv_sdl_window.h new file mode 100644 index 00000000..f2e243cd --- /dev/null +++ b/test/include/liblvgl/drivers/sdl/lv_sdl_window.h @@ -0,0 +1,62 @@ +/** + * @file lv_sdl_window.h + * + */ + +#ifndef LV_SDL_WINDOW_H +#define LV_SDL_WINDOW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_SDL + +/********************* + * DEFINES + *********************/ + +/* Possible values of LV_SDL_MOUSEWHEEL_MODE */ +#define LV_SDL_MOUSEWHEEL_MODE_ENCODER 0 /* The mousewheel emulates an encoder input device*/ +#define LV_SDL_MOUSEWHEEL_MODE_CROWN 1 /* The mousewheel emulates a smart watch crown*/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res); + +void lv_sdl_window_set_resizeable(lv_display_t * disp, bool value); + +void lv_sdl_window_set_zoom(lv_display_t * disp, uint8_t zoom); + +uint8_t lv_sdl_window_get_zoom(lv_display_t * disp); + +void lv_sdl_window_set_title(lv_display_t * disp, const char * title); + +void * lv_sdl_window_get_renderer(lv_display_t * disp); + +void lv_sdl_quit(void); + +/********************** + * MACROS + **********************/ + +#endif /* LV_DRV_SDL */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_SDL_WINDOW_H */ diff --git a/test/include/liblvgl/drivers/wayland/lv_wayland.h b/test/include/liblvgl/drivers/wayland/lv_wayland.h new file mode 100644 index 00000000..f3d340b0 --- /dev/null +++ b/test/include/liblvgl/drivers/wayland/lv_wayland.h @@ -0,0 +1,142 @@ +/******************************************************************* + * + * @file lv_wayland.h - Public functions of the LVGL Wayland client + * + * Based on the original file from the repository. + * + * Porting to LVGL 9.1 + * 2024 EDGEMTech Ltd. + * + * See LICENCE.txt for details + * + * Author(s): EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch) + * + ******************************************************************/ +#ifndef LV_WAYLAND_H +#define LV_WAYLAND_H + +#ifndef _WIN32 + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_WAYLAND + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef bool (*lv_wayland_display_close_f_t)(lv_display_t * disp); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Retrieves the file descriptor of the wayland socket + */ +int lv_wayland_get_fd(void); + +/** + * Creates a window + * @param hor_res The width of the window in pixels + * @param ver_res The height of the window in pixels + * @param title The title of the window + * @param close_cb The callback that will be execute when the user closes the window + * @return The LVGL display associated to the window + */ +lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char * title, + lv_wayland_display_close_f_t close_cb); + +/** + * Closes the window programmatically + * @param disp Reference to the LVGL display associated to the window + */ +void lv_wayland_window_close(lv_display_t * disp); + +/** + * Check if the window is open + * @param disp Reference to the LVGL display associated to the window + * @return true: The window is open + */ +bool lv_wayland_window_is_open(lv_display_t * disp); + +/** + * Sets the fullscreen state of the window + * @param disp Reference to the LVGL display associated to the window + * @param fullscreen If true the window enters fullscreen + */ +void lv_wayland_window_set_fullscreen(lv_display_t * disp, bool fullscreen); + +/** + * Sets the maximized state of the window + * @param disp Reference to the LVGL display associated to the window + * @param fullscreen If true the window is maximized + */ +void lv_wayland_window_set_maximized(lv_display_t * disp, bool maximize); + +/** + * Obtains the input device of the mouse pointer + * @note It is used to create an input group on application start + * @param disp Reference to the LVGL display associated to the window + * @return The input device + */ +lv_indev_t * lv_wayland_get_pointer(lv_display_t * disp); + +/** + * Obtains the input device of the encoder + * @note It is used to create an input group on application start + * @param disp Reference to the LVGL display associated to the window + * @return The input device + */ +lv_indev_t * lv_wayland_get_pointeraxis(lv_display_t * disp); + +/** + * Obtains the input device of the keyboard + * @note It is used to create an input group on application start + * @param disp Reference to the LVGL display associated to the window + * @return The input device + */ +lv_indev_t * lv_wayland_get_keyboard(lv_display_t * disp); + +/** + * Obtains the input device of the touch screen + * @note It is used to create an input group on application start + * @param disp Reference to the LVGL display associated to the window + * @return The input device + */ +lv_indev_t * lv_wayland_get_touchscreen(lv_display_t * disp); + +/** + * Wrapper around lv_timer_handler + * @note Must be called in the application run loop instead of the + * regular lv_timer_handler provided by LVGL + * @return true: if the cycle was completed, false if the application + * went to sleep because the last frame wasn't completed + */ +bool lv_wayland_timer_handler(void); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_WAYLAND */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* _WIN32 */ +#endif /* WAYLAND_H */ diff --git a/test/include/liblvgl/drivers/wayland/lv_wayland_smm.h b/test/include/liblvgl/drivers/wayland/lv_wayland_smm.h new file mode 100644 index 00000000..617244f1 --- /dev/null +++ b/test/include/liblvgl/drivers/wayland/lv_wayland_smm.h @@ -0,0 +1,105 @@ +/** + * @file lv_wayland_smm.h + * + */ +#ifndef LV_WAYLAND_SMM_H +#define LV_WAYLAND_SMM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _WIN32 + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include LV_STDDEF_INCLUDE +#include LV_STDBOOL_INCLUDE + +#if LV_USE_WAYLAND + +/********************* + * DEFINES + *********************/ + +#define SMM_FD_NAME "lvgl-wayland" +#define SMM_POOL_TAGS (1) +#define SMM_BUFFER_TAGS (2) +#define SMM_GROUP_TAGS (1) + +/********************** + * TYPEDEFS + **********************/ + +typedef void smm_pool_t; +typedef void smm_buffer_t; +typedef void smm_group_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +struct smm_events { + void * ctx; + bool (*new_pool)(void * ctx, smm_pool_t * pool); + void (*expand_pool)(void * ctx, smm_pool_t * pool); + void (*free_pool)(void * ctx, smm_pool_t * pool); + bool (*new_buffer)(void * ctx, smm_buffer_t * buf); + bool (*init_buffer)(void * ctx, smm_buffer_t * buf); + void (*free_buffer)(void * ctx, smm_buffer_t * buf); +}; + +struct smm_pool_properties { + void * tag[SMM_POOL_TAGS]; + size_t size; + int fd; +}; + +struct smm_buffer_properties { + void * tag[SMM_BUFFER_TAGS]; + smm_group_t * const group; + smm_pool_t * const pool; + size_t offset; +}; + +struct smm_group_properties { + void * tag[SMM_GROUP_TAGS]; +}; + +void smm_init(struct smm_events * evs); +void smm_setctx(void * ctx); +void smm_deinit(void); +smm_group_t * smm_create(void); +void smm_resize(smm_group_t * grp, size_t sz); +void smm_destroy(smm_group_t * grp); +smm_buffer_t * smm_acquire(smm_group_t * grp); +void * smm_map(smm_buffer_t * buf); +void smm_release(smm_buffer_t * buf); +smm_buffer_t * smm_latest(smm_group_t * grp); +smm_buffer_t * smm_next(smm_buffer_t * buf); + +/********************** + * MACROS + **********************/ + +#define SMM_POOL_PROPERTIES(p) ((const struct smm_pool_properties *)(p)) +#define SMM_BUFFER_PROPERTIES(b) ((const struct smm_buffer_properties *)(b)) +#define SMM_GROUP_PROPERTIES(g) ((const struct smm_group_properties *)(g)) +#define SMM_TAG(o, n, v) \ + do { \ + void **smm_tag = (void **)((char *)o + (n * sizeof(void *))); \ + *smm_tag = (v); \ + } while(0) + + +#endif /* LV_USE_WAYLAND */ +#endif /* _WIN32 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_WAYLAND_SMM_H */ diff --git a/test/include/liblvgl/drivers/windows/lv_windows_context.h b/test/include/liblvgl/drivers/windows/lv_windows_context.h new file mode 100644 index 00000000..d080ca56 --- /dev/null +++ b/test/include/liblvgl/drivers/windows/lv_windows_context.h @@ -0,0 +1,134 @@ +/** + * @file lv_windows_context.h + * + */ + +#ifndef LV_WINDOWS_CONTEXT_H +#define LV_WINDOWS_CONTEXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_WINDOWS + +#if LV_USE_OS != LV_OS_WINDOWS +#error [lv_windows] LV_OS_WINDOWS is required. Enable it in lv_conf.h (LV_USE_OS LV_OS_WINDOWS) +#endif + +#include + +#ifndef CREATE_WAITABLE_TIMER_MANUAL_RESET +#define CREATE_WAITABLE_TIMER_MANUAL_RESET 0x00000001 +#endif + +#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION +#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002 +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_windows_pointer_context_t { + lv_indev_state_t state; + lv_point_t point; + lv_indev_t * indev; +} lv_windows_pointer_context_t; + +typedef struct _lv_windows_keypad_queue_item_t { + uint32_t key; + lv_indev_state_t state; +} lv_windows_keypad_queue_item_t; + +typedef struct _lv_windows_keypad_context_t { + lv_ll_t queue; + uint16_t utf16_high_surrogate; + uint16_t utf16_low_surrogate; + lv_indev_t * indev; +} lv_windows_keypad_context_t; + +typedef struct _lv_windows_encoder_context_t { + lv_indev_state_t state; + int16_t enc_diff; + lv_indev_t * indev; +} lv_windows_encoder_context_t; + +typedef struct _lv_windows_window_context_t { + lv_display_t * display_device_object; + lv_timer_t * display_timer_object; + + int32_t window_dpi; + int32_t zoom_level; + bool allow_dpi_override; + bool simulator_mode; + bool display_resolution_changed; + lv_point_t requested_display_resolution; + + HDC display_framebuffer_context_handle; + uint32_t * display_framebuffer_base; + size_t display_framebuffer_size; + + lv_windows_pointer_context_t pointer; + lv_windows_keypad_context_t keypad; + lv_windows_encoder_context_t encoder; + +} lv_windows_window_context_t; + +typedef struct _lv_windows_create_display_data_t { + const wchar_t * title; + int32_t hor_res; + int32_t ver_res; + int32_t zoom_level; + bool allow_dpi_override; + bool simulator_mode; + HANDLE mutex; + lv_display_t * display; +} lv_windows_create_display_data_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Initialize the LVGL Windows backend. + * @remark This is a private API which is used for LVGL Windows backend + * implementation. LVGL users shouldn't use that because the + * LVGL has already used it in lv_init. +*/ +void lv_windows_platform_init(void); + +/** + * @brief Get the window context from specific LVGL display window. + * @param window_handle The window handle of specific LVGL display window. + * @return The window context from specific LVGL display window. + * @remark This is a private API which is used for LVGL Windows backend + * implementation. LVGL users shouldn't use that because the + * maintainer doesn't promise the application binary interface + * compatibility for this API. +*/ +lv_windows_window_context_t * lv_windows_get_window_context( + HWND window_handle); + +/********************** + * MACROS + **********************/ + +#endif // LV_USE_WINDOWS + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WINDOWS_CONTEXT_H*/ diff --git a/test/include/liblvgl/drivers/windows/lv_windows_display.h b/test/include/liblvgl/drivers/windows/lv_windows_display.h new file mode 100644 index 00000000..b9c6f8e9 --- /dev/null +++ b/test/include/liblvgl/drivers/windows/lv_windows_display.h @@ -0,0 +1,127 @@ +/** + * @file lv_windows_display.h + * + */ + +#ifndef LV_WINDOWS_DISPLAY_H +#define LV_WINDOWS_DISPLAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_WINDOWS + +#include + +/********************* + * DEFINES + *********************/ + +#define LV_WINDOWS_ZOOM_BASE_LEVEL 100 + +#ifndef USER_DEFAULT_SCREEN_DPI +#define USER_DEFAULT_SCREEN_DPI 96 +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Create a LVGL display object. + * @param title The window title of LVGL display. + * @param hor_res The horizontal resolution value of LVGL display. + * @param ver_res The vertical resolution value of LVGL display. + * @param zoom_level The zoom level value. Base value is 100 a.k.a 100%. + * @param allow_dpi_override Allow DPI override if true, or follow the + * Windows DPI scaling setting dynamically. + * @param simulator_mode Create simulator mode display if true, or create + * application mode display. + * @return The created LVGL display object. +*/ +lv_display_t * lv_windows_create_display( + const wchar_t * title, + int32_t hor_res, + int32_t ver_res, + int32_t zoom_level, + bool allow_dpi_override, + bool simulator_mode); + +/** + * @brief Get the window handle from specific LVGL display object. + * @param display The specific LVGL display object. + * @return The window handle from specific LVGL display object. +*/ +HWND lv_windows_get_display_window_handle(lv_display_t * display); + +/** + * @brief Get logical pixel value from physical pixel value taken account + * with zoom level. + * @param physical The physical pixel value taken account with zoom level. + * @param zoom_level The zoom level value. Base value is 100 a.k.a 100%. + * @return The logical pixel value. + * @remark It uses the same calculation style as Windows OS implementation. + * It will be useful for integrate LVGL Windows backend to other + * Windows applications. +*/ +int32_t lv_windows_zoom_to_logical(int32_t physical, int32_t zoom_level); + +/** + * @brief Get physical pixel value taken account with zoom level from + * logical pixel value. + * @param logical The logical pixel value. + * @param zoom_level The zoom level value. Base value is 100 a.k.a 100%. + * @return The physical pixel value taken account with zoom level. + * @remark It uses the same calculation style as Windows OS implementation. + * It will be useful for integrate LVGL Windows backend to other + * Windows applications. +*/ +int32_t lv_windows_zoom_to_physical(int32_t logical, int32_t zoom_level); + +/** + * @brief Get logical pixel value from physical pixel value taken account + * with DPI scaling. + * @param physical The physical pixel value taken account with DPI scaling. + * @param dpi The DPI scaling value. Base value is USER_DEFAULT_SCREEN_DPI. + * @return The logical pixel value. + * @remark It uses the same calculation style as Windows OS implementation. + * It will be useful for integrate LVGL Windows backend to other + * Windows applications. +*/ +int32_t lv_windows_dpi_to_logical(int32_t physical, int32_t dpi); + +/** + * @brief Get physical pixel value taken account with DPI scaling from + * logical pixel value. + * @param logical The logical pixel value. + * @param dpi The DPI scaling value. Base value is USER_DEFAULT_SCREEN_DPI. + * @return The physical pixel value taken account with DPI scaling. + * @remark It uses the same calculation style as Windows OS implementation. + * It will be useful for integrate LVGL Windows backend to other + * Windows applications. +*/ +int32_t lv_windows_dpi_to_physical(int32_t logical, int32_t dpi); + +/********************** + * MACROS + **********************/ + +#endif // LV_USE_WINDOWS + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WINDOWS_DISPLAY_H*/ diff --git a/test/include/liblvgl/drivers/windows/lv_windows_input.h b/test/include/liblvgl/drivers/windows/lv_windows_input.h new file mode 100644 index 00000000..892014ea --- /dev/null +++ b/test/include/liblvgl/drivers/windows/lv_windows_input.h @@ -0,0 +1,83 @@ +/** + * @file lv_windows_input.h + * + */ + +#ifndef LV_WINDOWS_INPUT_H +#define LV_WINDOWS_INPUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_WINDOWS + +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Get the window handle from specific LVGL input device object. + * @param indev The specific LVGL input device object. + * @return The window handle from specific LVGL input device object. +*/ +HWND lv_windows_get_indev_window_handle(lv_indev_t * indev); + +/** + * @brief Open a LVGL pointer input device object for the specific LVGL + * display object, or create it if the LVGL pointer input device + * object is not created or removed before. + * @param display The specific LVGL display object. + * @return The LVGL pointer input device object for the specific LVGL + * display object. +*/ +lv_indev_t * lv_windows_acquire_pointer_indev(lv_display_t * display); + +/** + * @brief Open a LVGL keypad input device object for the specific LVGL + * display object, or create it if the LVGL keypad input device + * object is not created or removed before. + * @param display The specific LVGL display object. + * @return The LVGL keypad input device object for the specific LVGL + * display object. +*/ +lv_indev_t * lv_windows_acquire_keypad_indev(lv_display_t * display); + +/** + * @brief Open a LVGL encoder input device object for the specific LVGL + * display object, or create it if the LVGL encoder input device + * object is not created or removed before. + * @param display The specific LVGL display object. + * @return The LVGL encoder input device object for the specific LVGL + * display object. +*/ +lv_indev_t * lv_windows_acquire_encoder_indev(lv_display_t * display); + +/********************** + * MACROS + **********************/ + +#endif // LV_USE_WINDOWS + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WINDOWS_INPUT_H*/ diff --git a/test/include/liblvgl/drivers/windows/lv_windows_input_private.h b/test/include/liblvgl/drivers/windows/lv_windows_input_private.h new file mode 100644 index 00000000..7d1096ed --- /dev/null +++ b/test/include/liblvgl/drivers/windows/lv_windows_input_private.h @@ -0,0 +1,65 @@ +/** + * @file lv_windows_input_private.h + * + */ + +#ifndef LV_WINDOWS_INPUT_PRIVATE_H +#define LV_WINDOWS_INPUT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#if LV_USE_WINDOWS + +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +bool lv_windows_pointer_device_window_message_handler( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + LRESULT * plResult); + +bool lv_windows_keypad_device_window_message_handler( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + LRESULT * plResult); + +bool lv_windows_encoder_device_window_message_handler( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + LRESULT * plResult); + +/********************** + * MACROS + **********************/ + +#endif // LV_USE_WINDOWS + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WINDOWS_INPUT_PRIVATE_H*/ diff --git a/test/include/liblvgl/drivers/x11/lv_x11.h b/test/include/liblvgl/drivers/x11/lv_x11.h new file mode 100644 index 00000000..7daabe3e --- /dev/null +++ b/test/include/liblvgl/drivers/x11/lv_x11.h @@ -0,0 +1,81 @@ +/** + * @file lv_x11.h + * + */ + +#ifndef LV_X11_H +#define LV_X11_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_X11 + +/********************* + * DEFINES + *********************/ + +/** Header of private display driver user data - for internal use only */ +typedef struct { + struct _XDisplay * display; /**< X11 display object */ + struct _x11_inp_data * inp_data; /**< input user data object */ +} _x11_user_hdr_t; + +/** optional window close callback function type + * @see lv_x11_window_set_close_cb +*/ +typedef void(*lv_x11_close_cb)(void * user_data); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * create and add keyboard, mouse and scrollwheel objects and connect them to x11 display. + * + * This is a convenience method handling the typical input initialisation of an X11 window: + * - create keyboard (lv_x11_keyboard_create) + * - create mouse (with scrollwheel, lv_x11_mouse_create lv_x11_mousewheel_create) + * + * @param[in] disp the created X11 display object from @ref lv_x11_window_create + * @param[in] mouse_img optional image description for the mouse cursor (NULL for no/invisible mouse cursor) + */ +void lv_x11_inputs_create(lv_display_t * disp, lv_image_dsc_t const * mouse_img); + +/** + * create the X11 display + * + * The minimal initialisation for initializing the X11 display driver with keyboard/mouse support: + * @code + * lv_display_t* disp = lv_x11_window_create("My Window Title", window_width, window_width); + * lv_x11_inputs_create(disp, NULL); + * @endcode + * or with mouse cursor icon: + * @code + * lv_image_dsc_t mouse_symbol = {.....}; + * lv_display_t* disp = lv_x11_window_create("My Window Title", window_width, window_width); + * lv_x11_inputs_create(disp, &mouse_symbol); + * @endcode + * + * @param[in] title title of the created X11 window + * @param[in] hor_res horizontal resolution (=width) of the X11 window + * @param[in] ver_res vertical resolution (=height) of the X11 window + * @return pointer to the display object + */ +lv_display_t * lv_x11_window_create(char const * title, int32_t hor_res, int32_t ver_res); + +#endif /* LV_USE_X11 */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_X11_H */ diff --git a/test/include/liblvgl/font/lv_binfont_loader.h b/test/include/liblvgl/font/lv_binfont_loader.h new file mode 100644 index 00000000..25e7b837 --- /dev/null +++ b/test/include/liblvgl/font/lv_binfont_loader.h @@ -0,0 +1,61 @@ +/** + * @file lv_binfont_loader.h + * + */ + +#ifndef LV_BINFONT_LOADER_H +#define LV_BINFONT_LOADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Loads a `lv_font_t` object from a binary font file + * @param path path to font file + * @return pointer to font where to load + */ +lv_font_t * lv_binfont_create(const char * path); + +#if LV_USE_FS_MEMFS +/** + * Loads a `lv_font_t` object from a memory buffer containing the binary font file. + * Requires LV_USE_FS_MEMFS + * @param buffer address of the font file in the memory + * @param size size of the font file buffer + * @return pointer to font where to load + */ +lv_font_t * lv_binfont_create_from_buffer(void * buffer, uint32_t size); +#endif + +/** + * Frees the memory allocated by the `lv_binfont_create()` function + * @param font lv_font_t object created by the lv_binfont_create function + */ +void lv_binfont_destroy(lv_font_t * font); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_BINFONT_LOADER_H */ diff --git a/test/include/liblvgl/font/lv_font.h b/test/include/liblvgl/font/lv_font.h new file mode 100644 index 00000000..9a043a78 --- /dev/null +++ b/test/include/liblvgl/font/lv_font.h @@ -0,0 +1,324 @@ +/** + * @file lv_font.h + * + */ + +#ifndef LV_FONT_H +#define LV_FONT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "../misc/lv_types.h" + +#include "lv_symbol_def.h" +#include "../draw/lv_draw_buf.h" +#include "../misc/lv_area.h" +#include "../misc/cache/lv_cache.h" + +/********************* + * DEFINES + *********************/ + +#define LV_IMGFONT_BPP 9 + +/********************** + * TYPEDEFS + **********************/ + +/*------------------ + * General types + *-----------------*/ + +/** The font format.*/ +typedef enum { + LV_FONT_GLYPH_FORMAT_NONE = 0, /**< Maybe not visible*/ + + /**< Legacy simple formats*/ + LV_FONT_GLYPH_FORMAT_A1 = 0x01, /**< 1 bit per pixel*/ + LV_FONT_GLYPH_FORMAT_A2 = 0x02, /**< 2 bit per pixel*/ + LV_FONT_GLYPH_FORMAT_A4 = 0x04, /**< 4 bit per pixel*/ + LV_FONT_GLYPH_FORMAT_A8 = 0x08, /**< 8 bit per pixel*/ + + LV_FONT_GLYPH_FORMAT_IMAGE = 0x09, /**< Image format*/ + + /**< Advanced formats*/ + LV_FONT_GLYPH_FORMAT_VECTOR = 0x0A, /**< Vectorial format*/ + LV_FONT_GLYPH_FORMAT_SVG = 0x0B, /**< SVG format*/ + LV_FONT_GLYPH_FORMAT_CUSTOM = 0xFF, /**< Custom format*/ +} lv_font_glyph_format_t; + +/** Describes the properties of a glyph.*/ +typedef struct { + const lv_font_t * + resolved_font; /**< Pointer to a font where the glyph was actually found after handling fallbacks*/ + uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width.*/ + uint16_t box_w; /**< Width of the glyph's bounding box*/ + uint16_t box_h; /**< Height of the glyph's bounding box*/ + int16_t ofs_x; /**< x offset of the bounding box*/ + int16_t ofs_y; /**< y offset of the bounding box*/ + lv_font_glyph_format_t format; /**< Font format of the glyph see lv_font_glyph_format_t */ + uint8_t is_placeholder: 1; /**< Glyph is missing. But placeholder will still be displayed*/ + + union { + uint32_t index; /**< Unicode code point*/ + const void * src; /**< Pointer to the source data used by image fonts*/ + } gid; /**< The index of the glyph in the font file. Used by the font cache*/ + lv_cache_entry_t * entry; /**< The cache entry of the glyph draw data. Used by the font cache*/ +} lv_font_glyph_dsc_t; + +/** The bitmaps might be upscaled by 3 to achieve subpixel rendering.*/ +typedef enum { + LV_FONT_SUBPX_NONE, + LV_FONT_SUBPX_HOR, + LV_FONT_SUBPX_VER, + LV_FONT_SUBPX_BOTH, +} lv_font_subpx_t; + +/** Adjust letter spacing for specific character pairs.*/ +typedef enum { + LV_FONT_KERNING_NORMAL, + LV_FONT_KERNING_NONE, +} lv_font_kerning_t; + +/** Describe the properties of a font*/ +struct _lv_font_t { + /** Get a glyph's descriptor from a font*/ + bool (*get_glyph_dsc)(const lv_font_t *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next); + + /** Get a glyph's bitmap from a font*/ + const void * (*get_glyph_bitmap)(lv_font_glyph_dsc_t *, lv_draw_buf_t *); + + /** Release a glyph*/ + void (*release_glyph)(const lv_font_t *, lv_font_glyph_dsc_t *); + + /*Pointer to the font in a font pack (must have the same line height)*/ + int32_t line_height; /**< The real line height where any text fits*/ + int32_t base_line; /**< Base line measured from the bottom of the line_height*/ + uint8_t subpx : 2; /**< An element of `lv_font_subpx_t`*/ + uint8_t kerning : 1; /**< An element of `lv_font_kerning_t`*/ + + int8_t underline_position; /**< Distance between the top of the underline and base line (< 0 means below the base line)*/ + int8_t underline_thickness; /**< Thickness of the underline*/ + + const void * dsc; /**< Store implementation specific or run_time data or caching here*/ + const lv_font_t * fallback; /**< Fallback font for missing glyph. Resolved recursively */ + void * user_data; /**< Custom user data for font.*/ +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Return with the bitmap of a font. + * @note You must call lv_font_get_glyph_dsc() to get `g_dsc` (lv_font_glyph_dsc_t) before you can call this function. + * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and the format. + * @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it. + * @return pointer to the glyph's data. It can be a draw buffer for bitmap fonts or an image source for imgfonts. + */ +const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); + +/** + * Get the descriptor of a glyph + * @param font pointer to font + * @param dsc_out store the result descriptor here + * @param letter a UNICODE letter code + * @param letter_next the next letter after `letter`. Used for kerning + * @return true: descriptor is successfully loaded into `dsc_out`. + * false: the letter was not found, no data is loaded to `dsc_out` + */ +bool lv_font_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, + uint32_t letter_next); + +/** + * Release the bitmap of a font. + * @note You must call lv_font_get_glyph_dsc() to get `g_dsc` (lv_font_glyph_dsc_t) before you can call this function. + * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and the format. + */ +void lv_font_glyph_release_draw_data(lv_font_glyph_dsc_t * g_dsc); + +/** + * Get the width of a glyph with kerning + * @param font pointer to a font + * @param letter a UNICODE letter + * @param letter_next the next letter after `letter`. Used for kerning + * @return the width of the glyph + */ +uint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32_t letter_next); + +/** + * Get the line height of a font. All characters fit into this height + * @param font pointer to a font + * @return the height of a font + */ +int32_t lv_font_get_line_height(const lv_font_t * font); + +/** + * Configure the use of kerning information stored in a font + * @param font pointer to a font + * @param kerning `LV_FONT_KERNING_NORMAL` (default) or `LV_FONT_KERNING_NONE` + */ +void lv_font_set_kerning(lv_font_t * font, lv_font_kerning_t kerning); + +/********************** + * MACROS + **********************/ + +#define LV_FONT_DECLARE(font_name) LV_ATTRIBUTE_EXTERN_DATA extern const lv_font_t font_name; + +#if LV_FONT_MONTSERRAT_8 +LV_FONT_DECLARE(lv_font_montserrat_8) +#endif + +#if LV_FONT_MONTSERRAT_10 +LV_FONT_DECLARE(lv_font_montserrat_10) +#endif + +#if LV_FONT_MONTSERRAT_12 +LV_FONT_DECLARE(lv_font_montserrat_12) +#endif + +#if LV_FONT_MONTSERRAT_14 +LV_FONT_DECLARE(lv_font_montserrat_14) +#endif + +#if LV_FONT_MONTSERRAT_16 +LV_FONT_DECLARE(lv_font_montserrat_16) +#endif + +#if LV_FONT_MONTSERRAT_18 +LV_FONT_DECLARE(lv_font_montserrat_18) +#endif + +#if LV_FONT_MONTSERRAT_20 +LV_FONT_DECLARE(lv_font_montserrat_20) +#endif + +#if LV_FONT_MONTSERRAT_22 +LV_FONT_DECLARE(lv_font_montserrat_22) +#endif + +#if LV_FONT_MONTSERRAT_24 +LV_FONT_DECLARE(lv_font_montserrat_24) +#endif + +#if LV_FONT_MONTSERRAT_26 +LV_FONT_DECLARE(lv_font_montserrat_26) +#endif + +#if LV_FONT_MONTSERRAT_28 +LV_FONT_DECLARE(lv_font_montserrat_28) +#endif + +#if LV_FONT_MONTSERRAT_30 +LV_FONT_DECLARE(lv_font_montserrat_30) +#endif + +#if LV_FONT_MONTSERRAT_32 +LV_FONT_DECLARE(lv_font_montserrat_32) +#endif + +#if LV_FONT_MONTSERRAT_34 +LV_FONT_DECLARE(lv_font_montserrat_34) +#endif + +#if LV_FONT_MONTSERRAT_36 +LV_FONT_DECLARE(lv_font_montserrat_36) +#endif + +#if LV_FONT_MONTSERRAT_38 +LV_FONT_DECLARE(lv_font_montserrat_38) +#endif + +#if LV_FONT_MONTSERRAT_40 +LV_FONT_DECLARE(lv_font_montserrat_40) +#endif + +#if LV_FONT_MONTSERRAT_42 +LV_FONT_DECLARE(lv_font_montserrat_42) +#endif + +#if LV_FONT_MONTSERRAT_44 +LV_FONT_DECLARE(lv_font_montserrat_44) +#endif + +#if LV_FONT_MONTSERRAT_46 +LV_FONT_DECLARE(lv_font_montserrat_46) +#endif + +#if LV_FONT_MONTSERRAT_48 +LV_FONT_DECLARE(lv_font_montserrat_48) +#endif + +#if LV_FONT_MONTSERRAT_28_COMPRESSED +LV_FONT_DECLARE(lv_font_montserrat_28_compressed) +#endif + +#if LV_FONT_DEJAVU_16_PERSIAN_HEBREW +LV_FONT_DECLARE(lv_font_dejavu_16_persian_hebrew) +#endif + +#if LV_FONT_SIMSUN_14_CJK +LV_FONT_DECLARE(lv_font_simsun_14_cjk) +#endif + +#if LV_FONT_SIMSUN_16_CJK +LV_FONT_DECLARE(lv_font_simsun_16_cjk) +#endif + +#if LV_FONT_UNSCII_8 +LV_FONT_DECLARE(lv_font_unscii_8) +#endif + +#if LV_FONT_UNSCII_16 +LV_FONT_DECLARE(lv_font_unscii_16) +#endif + +// TODO: reimplement some of the '_LATIN_SUP' fonts as custom fonts + +/*Declare the custom (user defined) fonts*/ +#ifdef LV_FONT_CUSTOM_DECLARE +LV_FONT_CUSTOM_DECLARE +#endif +#if USE_PROS_FONT_DEJAVU_MONO_10 +LV_FONT_DECLARE(pros_font_dejavu_mono_10); +#endif +#if USE_PROS_FONT_DEJAVU_MONO_10_LATIN_SUP +LV_FONT_DECLARE(pros_font_dejavu_mono_10_latin_sup); +#endif +#if USE_PROS_FONT_DEJAVU_MONO_18 +LV_FONT_DECLARE(pros_font_dejavu_mono_18); +#endif +#if USE_PROS_FONT_DEJAVU_MONO_18_LATIN_SUP +LV_FONT_DECLARE(pros_font_dejavu_mono_18_latin_sup); +#endif +#if USE_PROS_FONT_DEJAVU_MONO_30 +LV_FONT_DECLARE(pros_font_dejavu_mono_30); +#endif +#if USE_PROS_FONT_DEJAVU_MONO_30_LATIN_SUP +LV_FONT_DECLARE(pros_font_dejavu_mono_30_latin_sup); +#endif +#if USE_PROS_FONT_DEJAVU_MONO_40 +LV_FONT_DECLARE(pros_font_dejavu_mono_40); +#endif +#if USE_PROS_FONT_DEJAVU_MONO_40_LATIN_SUP +LV_FONT_DECLARE(pros_font_dejavu_mono_40_latin_sup); +#endif + +/** + * Just a wrapper around LV_FONT_DEFAULT because it might be more convenient to use a function in some cases + * @return pointer to LV_FONT_DEFAULT + */ +const lv_font_t * lv_font_default(void); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*USE_FONT*/ diff --git a/test/include/liblvgl/font/lv_font_fmt_txt.h b/test/include/liblvgl/font/lv_font_fmt_txt.h new file mode 100644 index 00000000..4eeb0c6e --- /dev/null +++ b/test/include/liblvgl/font/lv_font_fmt_txt.h @@ -0,0 +1,224 @@ +/** + * @file lv_font_fmt_txt.h + * + */ + +#ifndef LV_FONT_FMT_TXT_H +#define LV_FONT_FMT_TXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_font.h" +#include "../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** This describes a glyph.*/ +typedef struct { +#if LV_FONT_FMT_TXT_LARGE == 0 + uint32_t bitmap_index : 20; /**< Start index of the bitmap. A font can be max 1 MB.*/ + uint32_t adv_w : 12; /**< Draw the next glyph after this width. 8.4 format (real_value * 16 is stored).*/ + uint8_t box_w; /**< Width of the glyph's bounding box*/ + uint8_t box_h; /**< Height of the glyph's bounding box*/ + int8_t ofs_x; /**< x offset of the bounding box*/ + int8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/ +#else + uint32_t bitmap_index; /**< Start index of the bitmap. A font can be max 4 GB.*/ + uint32_t adv_w; /**< Draw the next glyph after this width. 28.4 format (real_value * 16 is stored).*/ + uint16_t box_w; /**< Width of the glyph's bounding box*/ + uint16_t box_h; /**< Height of the glyph's bounding box*/ + int16_t ofs_x; /**< x offset of the bounding box*/ + int16_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/ +#endif +} lv_font_fmt_txt_glyph_dsc_t; + +/** Format of font character map.*/ +typedef enum { + LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL, + LV_FONT_FMT_TXT_CMAP_SPARSE_FULL, + LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY, + LV_FONT_FMT_TXT_CMAP_SPARSE_TINY, +} lv_font_fmt_txt_cmap_type_t; + +/** + * Map codepoints to a `glyph_dsc`s + * Several formats are supported to optimize memory usage + * See https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md + */ +typedef struct { + /** First Unicode character for this range*/ + uint32_t range_start; + + /** Number of Unicode characters related to this range. + * Last Unicode character = range_start + range_length - 1*/ + uint16_t range_length; + + /** First glyph ID (array index of `glyph_dsc`) for this range*/ + uint16_t glyph_id_start; + + /* + According the specification there are 4 formats: + https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md + + For simplicity introduce "relative code point": + rcp = codepoint - range_start + + and a search function: + search a "value" in an "array" and returns the index of "value". + + Format 0 tiny + unicode_list == NULL && glyph_id_ofs_list == NULL + glyph_id = glyph_id_start + rcp + + Format 0 full + unicode_list == NULL && glyph_id_ofs_list != NULL + glyph_id = glyph_id_start + glyph_id_ofs_list[rcp] + + Sparse tiny + unicode_list != NULL && glyph_id_ofs_list == NULL + glyph_id = glyph_id_start + search(unicode_list, rcp) + + Sparse full + unicode_list != NULL && glyph_id_ofs_list != NULL + glyph_id = glyph_id_start + glyph_id_ofs_list[search(unicode_list, rcp)] + */ + + const uint16_t * unicode_list; + + /** if(type == LV_FONT_FMT_TXT_CMAP_FORMAT0_...) it's `uint8_t *` + * if(type == LV_FONT_FMT_TXT_CMAP_SPARSE_...) it's `uint16_t *` + */ + const void * glyph_id_ofs_list; + + /** Length of `unicode_list` and/or `glyph_id_ofs_list`*/ + uint16_t list_length; + + /** Type of this character map*/ + lv_font_fmt_txt_cmap_type_t type; +} lv_font_fmt_txt_cmap_t; + +/** A simple mapping of kern values from pairs*/ +typedef struct { + /*To get a kern value of two code points: + 1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t + 2. for(i = 0; i < pair_cnt * 2; i += 2) + if(glyph_ids[i] == glyph_id_left && + glyph_ids[i+1] == glyph_id_right) + return values[i / 2]; + */ + const void * glyph_ids; + const int8_t * values; + uint32_t pair_cnt : 30; + uint32_t glyph_ids_size : 2; /**< 0: `glyph_ids` is stored as `uint8_t`; 1: as `uint16_t` */ +} lv_font_fmt_txt_kern_pair_t; + +/** More complex but more optimal class based kern value storage*/ +typedef struct { + /*To get a kern value of two code points: + 1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t + 2. Get the class of the left and right glyphs as `left_class` and `right_class` + left_class = left_class_mapping[glyph_id_left]; + right_class = right_class_mapping[glyph_id_right]; + 3. value = class_pair_values[(left_class-1)*right_class_cnt + (right_class-1)] + */ + + const int8_t * class_pair_values; /**< left_class_cnt * right_class_cnt value */ + const uint8_t * left_class_mapping; /**< Map the glyph_ids to classes: index -> glyph_id -> class_id */ + const uint8_t * right_class_mapping; /**< Map the glyph_ids to classes: index -> glyph_id -> class_id */ + uint8_t left_class_cnt; + uint8_t right_class_cnt; +} lv_font_fmt_txt_kern_classes_t; + +/** Bitmap formats*/ +typedef enum { + LV_FONT_FMT_TXT_PLAIN = 0, + LV_FONT_FMT_TXT_COMPRESSED = 1, + LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 1, +} lv_font_fmt_txt_bitmap_format_t; + +/** Describe store for additional data for fonts */ +typedef struct { + /** The bitmaps of all glyphs */ + const uint8_t * glyph_bitmap; + + /** Describe the glyphs */ + const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc; + + /** Map the glyphs to Unicode characters. + *Array of `lv_font_cmap_fmt_txt_t` variables */ + const lv_font_fmt_txt_cmap_t * cmaps; + + /** + * Store kerning values. + * Can be `lv_font_fmt_txt_kern_pair_t * or `lv_font_kern_classes_fmt_txt_t *` + * depending on `kern_classes` + */ + const void * kern_dsc; + + /** Scale kern values in 12.4 format */ + uint16_t kern_scale; + + /** Number of cmap tables */ + uint16_t cmap_num : 9; + + /** Bit per pixel: 1, 2, 3, 4, 8 */ + uint16_t bpp : 4; + + /** Type of `kern_dsc` */ + uint16_t kern_classes : 1; + + /** + * storage format of the bitmap + * from `lv_font_fmt_txt_bitmap_format_t` + */ + uint16_t bitmap_format : 2; +} lv_font_fmt_txt_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Used as `get_glyph_bitmap` callback in lvgl's native font format if the font is uncompressed. + * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and format. + * @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it. + * @return pointer to an A8 bitmap (not necessarily bitmap_out) or NULL if `unicode_letter` not found + */ +const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); + +/** + * Used as `get_glyph_dsc` callback in lvgl's native font format if the font is uncompressed. + * @param font pointer to font + * @param dsc_out store the result descriptor here + * @param unicode_letter a UNICODE letter code + * @param unicode_letter_next the unicode letter succeeding the letter under test + * @return true: descriptor is successfully loaded into `dsc_out`. + * false: the letter was not found, no data is loaded to `dsc_out` + */ +bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, + uint32_t unicode_letter_next); + +/********************** + * MACROS + **********************/ + +/********************** + * ADD BUILT IN FONTS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FONT_FMT_TXT_H*/ diff --git a/test/include/liblvgl/font/lv_font_fmt_txt_private.h b/test/include/liblvgl/font/lv_font_fmt_txt_private.h new file mode 100644 index 00000000..66df402d --- /dev/null +++ b/test/include/liblvgl/font/lv_font_fmt_txt_private.h @@ -0,0 +1,56 @@ +/** + * @file lv_font_fmt_txt_private.h + * + */ + +#ifndef LV_FONT_FMT_TXT_PRIVATE_H +#define LV_FONT_FMT_TXT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_font_fmt_txt.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +#if LV_USE_FONT_COMPRESSED +typedef enum { + RLE_STATE_SINGLE = 0, + RLE_STATE_REPEATED, + RLE_STATE_COUNTER, +} lv_font_fmt_rle_state_t; + +typedef struct { + uint32_t rdp; + const uint8_t * in; + uint8_t bpp; + uint8_t prev_v; + uint8_t count; + lv_font_fmt_rle_state_t state; +} lv_font_fmt_rle_t; +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FONT_FMT_TXT_PRIVATE_H*/ diff --git a/test/include/liblvgl/font/lv_symbol_def.h b/test/include/liblvgl/font/lv_symbol_def.h new file mode 100644 index 00000000..d78f3892 --- /dev/null +++ b/test/include/liblvgl/font/lv_symbol_def.h @@ -0,0 +1,357 @@ +/** + * @file lv_symbol_def.h + * + */ + +#ifndef LV_SYMBOL_DEF_H +#define LV_SYMBOL_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../lv_conf_internal.h" + +/*------------------------------- + * Symbols from "normal" font + *-----------------------------*/ +#if !defined LV_SYMBOL_BULLET +#define LV_SYMBOL_BULLET "\xE2\x80\xA2" /*20042, 0x2022*/ +#endif + +/*------------------------------- + * Symbols from FontAwesome font + *-----------------------------*/ + +/*In the font converter use this list as range: + 61441, 61448, 61451, 61452, 61453, 61457, 61459, 61461, 61465, 61468, + 61473, 61478, 61479, 61480, 61502, 61507, 61512, 61515, 61516, 61517, + 61521, 61522, 61523, 61524, 61543, 61544, 61550, 61552, 61553, 61556, + 61559, 61560, 61561, 61563, 61587, 61589, 61636, 61637, 61639, 61641, + 61664, 61671, 61674, 61683, 61724, 61732, 61787, 61931, 62016, 62017, + 62018, 62019, 62020, 62087, 62099, 62189, 62212, 62810, 63426, 63650 +*/ + +/* These symbols can be predefined in the lv_conf.h file. + * If they are not predefined, they will use the following values + */ + +#if !defined LV_SYMBOL_AUDIO +#define LV_SYMBOL_AUDIO "\xEF\x80\x81" /*61441, 0xF001*/ +#endif + +#if !defined LV_SYMBOL_VIDEO +#define LV_SYMBOL_VIDEO "\xEF\x80\x88" /*61448, 0xF008*/ +#endif + +#if !defined LV_SYMBOL_LIST +#define LV_SYMBOL_LIST "\xEF\x80\x8B" /*61451, 0xF00B*/ +#endif + +#if !defined LV_SYMBOL_OK +#define LV_SYMBOL_OK "\xEF\x80\x8C" /*61452, 0xF00C*/ +#endif + +#if !defined LV_SYMBOL_CLOSE +#define LV_SYMBOL_CLOSE "\xEF\x80\x8D" /*61453, 0xF00D*/ +#endif + +#if !defined LV_SYMBOL_POWER +#define LV_SYMBOL_POWER "\xEF\x80\x91" /*61457, 0xF011*/ +#endif + +#if !defined LV_SYMBOL_SETTINGS +#define LV_SYMBOL_SETTINGS "\xEF\x80\x93" /*61459, 0xF013*/ +#endif + +#if !defined LV_SYMBOL_HOME +#define LV_SYMBOL_HOME "\xEF\x80\x95" /*61461, 0xF015*/ +#endif + +#if !defined LV_SYMBOL_DOWNLOAD +#define LV_SYMBOL_DOWNLOAD "\xEF\x80\x99" /*61465, 0xF019*/ +#endif + +#if !defined LV_SYMBOL_DRIVE +#define LV_SYMBOL_DRIVE "\xEF\x80\x9C" /*61468, 0xF01C*/ +#endif + +#if !defined LV_SYMBOL_REFRESH +#define LV_SYMBOL_REFRESH "\xEF\x80\xA1" /*61473, 0xF021*/ +#endif + +#if !defined LV_SYMBOL_MUTE +#define LV_SYMBOL_MUTE "\xEF\x80\xA6" /*61478, 0xF026*/ +#endif + +#if !defined LV_SYMBOL_VOLUME_MID +#define LV_SYMBOL_VOLUME_MID "\xEF\x80\xA7" /*61479, 0xF027*/ +#endif + +#if !defined LV_SYMBOL_VOLUME_MAX +#define LV_SYMBOL_VOLUME_MAX "\xEF\x80\xA8" /*61480, 0xF028*/ +#endif + +#if !defined LV_SYMBOL_IMAGE +#define LV_SYMBOL_IMAGE "\xEF\x80\xBE" /*61502, 0xF03E*/ +#endif + +#if !defined LV_SYMBOL_TINT +#define LV_SYMBOL_TINT "\xEF\x81\x83" /*61507, 0xF043*/ +#endif + +#if !defined LV_SYMBOL_PREV +#define LV_SYMBOL_PREV "\xEF\x81\x88" /*61512, 0xF048*/ +#endif + +#if !defined LV_SYMBOL_PLAY +#define LV_SYMBOL_PLAY "\xEF\x81\x8B" /*61515, 0xF04B*/ +#endif + +#if !defined LV_SYMBOL_PAUSE +#define LV_SYMBOL_PAUSE "\xEF\x81\x8C" /*61516, 0xF04C*/ +#endif + +#if !defined LV_SYMBOL_STOP +#define LV_SYMBOL_STOP "\xEF\x81\x8D" /*61517, 0xF04D*/ +#endif + +#if !defined LV_SYMBOL_NEXT +#define LV_SYMBOL_NEXT "\xEF\x81\x91" /*61521, 0xF051*/ +#endif + +#if !defined LV_SYMBOL_EJECT +#define LV_SYMBOL_EJECT "\xEF\x81\x92" /*61522, 0xF052*/ +#endif + +#if !defined LV_SYMBOL_LEFT +#define LV_SYMBOL_LEFT "\xEF\x81\x93" /*61523, 0xF053*/ +#endif + +#if !defined LV_SYMBOL_RIGHT +#define LV_SYMBOL_RIGHT "\xEF\x81\x94" /*61524, 0xF054*/ +#endif + +#if !defined LV_SYMBOL_PLUS +#define LV_SYMBOL_PLUS "\xEF\x81\xA7" /*61543, 0xF067*/ +#endif + +#if !defined LV_SYMBOL_MINUS +#define LV_SYMBOL_MINUS "\xEF\x81\xA8" /*61544, 0xF068*/ +#endif + +#if !defined LV_SYMBOL_EYE_OPEN +#define LV_SYMBOL_EYE_OPEN "\xEF\x81\xAE" /*61550, 0xF06E*/ +#endif + +#if !defined LV_SYMBOL_EYE_CLOSE +#define LV_SYMBOL_EYE_CLOSE "\xEF\x81\xB0" /*61552, 0xF070*/ +#endif + +#if !defined LV_SYMBOL_WARNING +#define LV_SYMBOL_WARNING "\xEF\x81\xB1" /*61553, 0xF071*/ +#endif + +#if !defined LV_SYMBOL_SHUFFLE +#define LV_SYMBOL_SHUFFLE "\xEF\x81\xB4" /*61556, 0xF074*/ +#endif + +#if !defined LV_SYMBOL_UP +#define LV_SYMBOL_UP "\xEF\x81\xB7" /*61559, 0xF077*/ +#endif + +#if !defined LV_SYMBOL_DOWN +#define LV_SYMBOL_DOWN "\xEF\x81\xB8" /*61560, 0xF078*/ +#endif + +#if !defined LV_SYMBOL_LOOP +#define LV_SYMBOL_LOOP "\xEF\x81\xB9" /*61561, 0xF079*/ +#endif + +#if !defined LV_SYMBOL_DIRECTORY +#define LV_SYMBOL_DIRECTORY "\xEF\x81\xBB" /*61563, 0xF07B*/ +#endif + +#if !defined LV_SYMBOL_UPLOAD +#define LV_SYMBOL_UPLOAD "\xEF\x82\x93" /*61587, 0xF093*/ +#endif + +#if !defined LV_SYMBOL_CALL +#define LV_SYMBOL_CALL "\xEF\x82\x95" /*61589, 0xF095*/ +#endif + +#if !defined LV_SYMBOL_CUT +#define LV_SYMBOL_CUT "\xEF\x83\x84" /*61636, 0xF0C4*/ +#endif + +#if !defined LV_SYMBOL_COPY +#define LV_SYMBOL_COPY "\xEF\x83\x85" /*61637, 0xF0C5*/ +#endif + +#if !defined LV_SYMBOL_SAVE +#define LV_SYMBOL_SAVE "\xEF\x83\x87" /*61639, 0xF0C7*/ +#endif + +#if !defined LV_SYMBOL_BARS +#define LV_SYMBOL_BARS "\xEF\x83\x89" /*61641, 0xF0C9*/ +#endif + +#if !defined LV_SYMBOL_ENVELOPE +#define LV_SYMBOL_ENVELOPE "\xEF\x83\xA0" /*61664, 0xF0E0*/ +#endif + +#if !defined LV_SYMBOL_CHARGE +#define LV_SYMBOL_CHARGE "\xEF\x83\xA7" /*61671, 0xF0E7*/ +#endif + +#if !defined LV_SYMBOL_PASTE +#define LV_SYMBOL_PASTE "\xEF\x83\xAA" /*61674, 0xF0EA*/ +#endif + +#if !defined LV_SYMBOL_BELL +#define LV_SYMBOL_BELL "\xEF\x83\xB3" /*61683, 0xF0F3*/ +#endif + +#if !defined LV_SYMBOL_KEYBOARD +#define LV_SYMBOL_KEYBOARD "\xEF\x84\x9C" /*61724, 0xF11C*/ +#endif + +#if !defined LV_SYMBOL_GPS +#define LV_SYMBOL_GPS "\xEF\x84\xA4" /*61732, 0xF124*/ +#endif + +#if !defined LV_SYMBOL_FILE +#define LV_SYMBOL_FILE "\xEF\x85\x9B" /*61787, 0xF158*/ +#endif + +#if !defined LV_SYMBOL_WIFI +#define LV_SYMBOL_WIFI "\xEF\x87\xAB" /*61931, 0xF1EB*/ +#endif + +#if !defined LV_SYMBOL_BATTERY_FULL +#define LV_SYMBOL_BATTERY_FULL "\xEF\x89\x80" /*62016, 0xF240*/ +#endif + +#if !defined LV_SYMBOL_BATTERY_3 +#define LV_SYMBOL_BATTERY_3 "\xEF\x89\x81" /*62017, 0xF241*/ +#endif + +#if !defined LV_SYMBOL_BATTERY_2 +#define LV_SYMBOL_BATTERY_2 "\xEF\x89\x82" /*62018, 0xF242*/ +#endif + +#if !defined LV_SYMBOL_BATTERY_1 +#define LV_SYMBOL_BATTERY_1 "\xEF\x89\x83" /*62019, 0xF243*/ +#endif + +#if !defined LV_SYMBOL_BATTERY_EMPTY +#define LV_SYMBOL_BATTERY_EMPTY "\xEF\x89\x84" /*62020, 0xF244*/ +#endif + +#if !defined LV_SYMBOL_USB +#define LV_SYMBOL_USB "\xEF\x8a\x87" /*62087, 0xF287*/ +#endif + +#if !defined LV_SYMBOL_BLUETOOTH +#define LV_SYMBOL_BLUETOOTH "\xEF\x8a\x93" /*62099, 0xF293*/ +#endif + +#if !defined LV_SYMBOL_TRASH +#define LV_SYMBOL_TRASH "\xEF\x8B\xAD" /*62189, 0xF2ED*/ +#endif + +#if !defined LV_SYMBOL_EDIT +#define LV_SYMBOL_EDIT "\xEF\x8C\x84" /*62212, 0xF304*/ +#endif + +#if !defined LV_SYMBOL_BACKSPACE +#define LV_SYMBOL_BACKSPACE "\xEF\x95\x9A" /*62810, 0xF55A*/ +#endif + +#if !defined LV_SYMBOL_SD_CARD +#define LV_SYMBOL_SD_CARD "\xEF\x9F\x82" /*63426, 0xF7C2*/ +#endif + +#if !defined LV_SYMBOL_NEW_LINE +#define LV_SYMBOL_NEW_LINE "\xEF\xA2\xA2" /*63650, 0xF8A2*/ +#endif + +#if !defined LV_SYMBOL_DUMMY +/** Invalid symbol at (U+F8FF). If written before a string then `lv_img` will show it as a label*/ +#define LV_SYMBOL_DUMMY "\xEF\xA3\xBF" +#endif + +/* + * The following list is generated using + * cat src/font/lv_symbol_def.h | sed -E -n 's/^#define\s+LV_(SYMBOL_\w+).*".*$/ LV_STR_\1,/p' + */ +enum { + LV_STR_SYMBOL_BULLET, + LV_STR_SYMBOL_AUDIO, + LV_STR_SYMBOL_VIDEO, + LV_STR_SYMBOL_LIST, + LV_STR_SYMBOL_OK, + LV_STR_SYMBOL_CLOSE, + LV_STR_SYMBOL_POWER, + LV_STR_SYMBOL_SETTINGS, + LV_STR_SYMBOL_HOME, + LV_STR_SYMBOL_DOWNLOAD, + LV_STR_SYMBOL_DRIVE, + LV_STR_SYMBOL_REFRESH, + LV_STR_SYMBOL_MUTE, + LV_STR_SYMBOL_VOLUME_MID, + LV_STR_SYMBOL_VOLUME_MAX, + LV_STR_SYMBOL_IMAGE, + LV_STR_SYMBOL_TINT, + LV_STR_SYMBOL_PREV, + LV_STR_SYMBOL_PLAY, + LV_STR_SYMBOL_PAUSE, + LV_STR_SYMBOL_STOP, + LV_STR_SYMBOL_NEXT, + LV_STR_SYMBOL_EJECT, + LV_STR_SYMBOL_LEFT, + LV_STR_SYMBOL_RIGHT, + LV_STR_SYMBOL_PLUS, + LV_STR_SYMBOL_MINUS, + LV_STR_SYMBOL_EYE_OPEN, + LV_STR_SYMBOL_EYE_CLOSE, + LV_STR_SYMBOL_WARNING, + LV_STR_SYMBOL_SHUFFLE, + LV_STR_SYMBOL_UP, + LV_STR_SYMBOL_DOWN, + LV_STR_SYMBOL_LOOP, + LV_STR_SYMBOL_DIRECTORY, + LV_STR_SYMBOL_UPLOAD, + LV_STR_SYMBOL_CALL, + LV_STR_SYMBOL_CUT, + LV_STR_SYMBOL_COPY, + LV_STR_SYMBOL_SAVE, + LV_STR_SYMBOL_BARS, + LV_STR_SYMBOL_ENVELOPE, + LV_STR_SYMBOL_CHARGE, + LV_STR_SYMBOL_PASTE, + LV_STR_SYMBOL_BELL, + LV_STR_SYMBOL_KEYBOARD, + LV_STR_SYMBOL_GPS, + LV_STR_SYMBOL_FILE, + LV_STR_SYMBOL_WIFI, + LV_STR_SYMBOL_BATTERY_FULL, + LV_STR_SYMBOL_BATTERY_3, + LV_STR_SYMBOL_BATTERY_2, + LV_STR_SYMBOL_BATTERY_1, + LV_STR_SYMBOL_BATTERY_EMPTY, + LV_STR_SYMBOL_USB, + LV_STR_SYMBOL_BLUETOOTH, + LV_STR_SYMBOL_TRASH, + LV_STR_SYMBOL_EDIT, + LV_STR_SYMBOL_BACKSPACE, + LV_STR_SYMBOL_SD_CARD, + LV_STR_SYMBOL_NEW_LINE, + LV_STR_SYMBOL_DUMMY, +}; + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SYMBOL_DEF_H*/ diff --git a/test/include/liblvgl/indev/lv_indev.h b/test/include/liblvgl/indev/lv_indev.h new file mode 100644 index 00000000..bee5ec1a --- /dev/null +++ b/test/include/liblvgl/indev/lv_indev.h @@ -0,0 +1,422 @@ +/** + * @file lv_indev.h + * + */ + +#ifndef LV_INDEV_H +#define LV_INDEV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../core/lv_group.h" +#include "../misc/lv_area.h" +#include "../misc/lv_timer.h" +#include "../misc/lv_event.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Possible input device types*/ +typedef enum { + LV_INDEV_TYPE_NONE, /**< Uninitialized state*/ + LV_INDEV_TYPE_POINTER, /**< Touch pad, mouse, external button*/ + LV_INDEV_TYPE_KEYPAD, /**< Keypad or keyboard*/ + LV_INDEV_TYPE_BUTTON, /**< External (hardware button) which is assigned to a specific point of the screen*/ + LV_INDEV_TYPE_ENCODER, /**< Encoder with only Left, Right turn and a Button*/ +} lv_indev_type_t; + +/** States for input devices*/ +typedef enum { + LV_INDEV_STATE_RELEASED = 0, + LV_INDEV_STATE_PRESSED +} lv_indev_state_t; + +typedef enum { + LV_INDEV_MODE_NONE = 0, + LV_INDEV_MODE_TIMER, + LV_INDEV_MODE_EVENT, +} lv_indev_mode_t; + +/** Data structure passed to an input driver to fill*/ +typedef struct { + lv_point_t point; /**< For LV_INDEV_TYPE_POINTER the currently pressed point*/ + uint32_t key; /**< For LV_INDEV_TYPE_KEYPAD the currently pressed key*/ + uint32_t btn_id; /**< For LV_INDEV_TYPE_BUTTON the currently pressed button*/ + int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/ + + lv_indev_state_t state; /**< LV_INDEV_STATE_RELEASED or LV_INDEV_STATE_PRESSED*/ + bool continue_reading; /**< If set to true, the read callback is invoked again, unless the device is in event-driven mode*/ +} lv_indev_data_t; + +typedef void (*lv_indev_read_cb_t)(lv_indev_t * indev, lv_indev_data_t * data); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an indev + * @return Pointer to the created indev or NULL when allocation failed + */ +lv_indev_t * lv_indev_create(void); + +/** + * Remove the provided input device. Make sure not to use the provided input device afterwards anymore. + * @param indev pointer to delete + */ +void lv_indev_delete(lv_indev_t * indev); + +/** + * Get the next input device. + * @param indev pointer to the current input device. NULL to initialize. + * @return the next input device or NULL if there are no more. Provide the first input device when + * the parameter is NULL + */ +lv_indev_t * lv_indev_get_next(lv_indev_t * indev); + +/** + * Read data from an input device. + * @param indev pointer to an input device + */ +void lv_indev_read(lv_indev_t * indev); + +/** + * Called periodically to read the input devices + * @param timer pointer to a timer to read + */ +void lv_indev_read_timer_cb(lv_timer_t * timer); + +/** + * Enable or disable one or all input devices (default enabled) + * @param indev pointer to an input device or NULL to enable/disable all of them + * @param enable true to enable, false to disable + */ +void lv_indev_enable(lv_indev_t * indev, bool enable); + +/** + * Get the currently processed input device. Can be used in action functions too. + * @return pointer to the currently processed input device or NULL if no input device processing + * right now + */ +lv_indev_t * lv_indev_active(void); + +/** + * Set the type of an input device + * @param indev pointer to an input device + * @param indev_type the type of the input device from `lv_indev_type_t` (`LV_INDEV_TYPE_...`) + */ +void lv_indev_set_type(lv_indev_t * indev, lv_indev_type_t indev_type); + +/** + * Set a callback function to read input device data to the indev + * @param indev pointer to an input device + * @param read_cb pointer to callback function to read input device data + */ +void lv_indev_set_read_cb(lv_indev_t * indev, lv_indev_read_cb_t read_cb); + +/** + * Set user data to the indev + * @param indev pointer to an input device + * @param user_data pointer to user data + */ +void lv_indev_set_user_data(lv_indev_t * indev, void * user_data); + +/** + * Set driver data to the indev + * @param indev pointer to an input device + * @param driver_data pointer to driver data + */ +void lv_indev_set_driver_data(lv_indev_t * indev, void * driver_data); + +/** + * Assign a display to the indev + * @param indev pointer to an input device + * @param disp pointer to an display + */ +void lv_indev_set_display(lv_indev_t * indev, struct _lv_display_t * disp); + +/** + * Set long press time to indev + * @param indev pointer to input device + * @param long_press_time time long press time in ms + */ +void lv_indev_set_long_press_time(lv_indev_t * indev, uint16_t long_press_time); + +/** + * Set scroll limit to the input device + * @param indev pointer to an input device + * @param scroll_limit the number of pixels to slide before actually drag the object + */ +void lv_indev_set_scroll_limit(lv_indev_t * indev, uint8_t scroll_limit); + +/** + * Set scroll throw slow-down to the indev. Greater value means faster slow-down + * @param indev pointer to an input device + * @param scroll_throw the slow-down in [%] + */ +void lv_indev_set_scroll_throw(lv_indev_t * indev, uint8_t scroll_throw); + +/** + * Get the type of an input device + * @param indev pointer to an input device + * @return the type of the input device from `lv_hal_indev_type_t` (`LV_INDEV_TYPE_...`) + */ +lv_indev_type_t lv_indev_get_type(const lv_indev_t * indev); + +/** + * Get the callback function to read input device data to the indev + * @param indev pointer to an input device + * @return Pointer to callback function to read input device data or NULL if indev is NULL + */ +lv_indev_read_cb_t lv_indev_get_read_cb(lv_indev_t * indev); + +/** + * Get the indev state + * @param indev pointer to an input device + * @return Indev state or LV_INDEV_STATE_RELEASED if indev is NULL + */ +lv_indev_state_t lv_indev_get_state(const lv_indev_t * indev); + +/** + * Get the indev assigned group + * @param indev pointer to an input device + * @return Pointer to indev assigned group or NULL if indev is NULL + */ +lv_group_t * lv_indev_get_group(const lv_indev_t * indev); + +/** + * Get a pointer to the assigned display of the indev + * @param indev pointer to an input device + * @return pointer to the assigned display or NULL if indev is NULL + */ +lv_display_t * lv_indev_get_display(const lv_indev_t * indev); + +/** + * Get a pointer to the user data of the indev + * @param indev pointer to an input device + * @return pointer to the user data or NULL if indev is NULL + */ +void * lv_indev_get_user_data(const lv_indev_t * indev); + +/** + * Get a pointer to the driver data of the indev + * @param indev pointer to an input device + * @return pointer to the driver data or NULL if indev is NULL + */ +void * lv_indev_get_driver_data(const lv_indev_t * indev); + +/** + * Get whether indev is moved while pressed + * @param indev pointer to an input device + * @return true: indev is moved while pressed; false: indev is not moved while pressed + */ +bool lv_indev_get_press_moved(const lv_indev_t * indev); + +/** + * Reset one or all input devices + * @param indev pointer to an input device to reset or NULL to reset all of them + * @param obj pointer to an object which triggers the reset. + */ +void lv_indev_reset(lv_indev_t * indev, lv_obj_t * obj); + +/** + * Touch and key related events are sent to the input device first and to the widget after that. + * If this functions called in an indev event, the event won't be sent to the widget. + * @param indev pointer to an input device + */ +void lv_indev_stop_processing(lv_indev_t * indev); + +/** + * Reset the long press state of an input device + * @param indev pointer to an input device + */ +void lv_indev_reset_long_press(lv_indev_t * indev); + +/** + * Set a cursor for a pointer input device (for LV_INPUT_TYPE_POINTER and LV_INPUT_TYPE_BUTTON) + * @param indev pointer to an input device + * @param cur_obj pointer to an object to be used as cursor + */ +void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj); + +/** + * Set a destination group for a keypad input device (for LV_INDEV_TYPE_KEYPAD) + * @param indev pointer to an input device + * @param group pointer to a group + */ +void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group); + +/** + * Set the an array of points for LV_INDEV_TYPE_BUTTON. + * These points will be assigned to the buttons to press a specific point on the screen + * @param indev pointer to an input device + * @param points array of points + */ +void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t points[]); + +/** + * Get the last point of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON) + * @param indev pointer to an input device + * @param point pointer to a point to store the result + */ +void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point); + +/** +* Get the current gesture direct +* @param indev pointer to an input device +* @return current gesture direct +*/ +lv_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev); + +/** + * Get the last pressed key of an input device (for LV_INDEV_TYPE_KEYPAD) + * @param indev pointer to an input device + * @return the last pressed key (0 on error) + */ +uint32_t lv_indev_get_key(const lv_indev_t * indev); + + +/** + * Get the counter for consecutive clicks within a short distance and time. + * The counter is updated before LV_EVENT_SHORT_CLICKED is fired. + * @param indev pointer to an input device + * @return short click streak counter + */ +uint8_t lv_indev_get_short_click_streak(const lv_indev_t * indev); + +/** + * Check the current scroll direction of an input device (for LV_INDEV_TYPE_POINTER and + * LV_INDEV_TYPE_BUTTON) + * @param indev pointer to an input device + * @return LV_DIR_NONE: no scrolling now + * LV_DIR_HOR/VER + */ +lv_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev); + +/** + * Get the currently scrolled object (for LV_INDEV_TYPE_POINTER and + * LV_INDEV_TYPE_BUTTON) + * @param indev pointer to an input device + * @return pointer to the currently scrolled object or NULL if no scrolling by this indev + */ +lv_obj_t * lv_indev_get_scroll_obj(const lv_indev_t * indev); + +/** + * Get the movement vector of an input device (for LV_INDEV_TYPE_POINTER and + * LV_INDEV_TYPE_BUTTON) + * @param indev pointer to an input device + * @param point pointer to a point to store the types.pointer.vector + */ +void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point); + +/** + * Do nothing until the next release + * @param indev pointer to an input device + */ +void lv_indev_wait_release(lv_indev_t * indev); + +/** + * Gets a pointer to the currently active object in the currently processed input device. + * @return pointer to currently active object or NULL if no active object + */ +lv_obj_t * lv_indev_get_active_obj(void); + +/** + * Get a pointer to the indev read timer to + * modify its parameters with `lv_timer_...` functions. + * @param indev pointer to an input device + * @return pointer to the indev read refresher timer. (NULL on error) + */ +lv_timer_t * lv_indev_get_read_timer(lv_indev_t * indev); + +/** +* Set the input device's event model: event-driven mode or timer mode. +* @param indev pointer to an input device +* @param mode the mode of input device +*/ +void lv_indev_set_mode(lv_indev_t * indev, lv_indev_mode_t mode); + +/** + * Get the input device's running mode. + * @param indev pointer to an input device + * @return the running mode for the specified input device. + */ +lv_indev_mode_t lv_indev_get_mode(lv_indev_t * indev); + +/** + * Search the most top, clickable object by a point + * @param obj pointer to a start object, typically the screen + * @param point pointer to a point for searching the most top child + * @return pointer to the found object or NULL if there was no suitable object + */ +lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point); + +/** + * Add an event handler to the indev + * @param indev pointer to an indev + * @param event_cb an event callback + * @param filter event code to react or `LV_EVENT_ALL` + * @param user_data optional user_data + */ +void lv_indev_add_event_cb(lv_indev_t * indev, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data); + +/** + * Get the number of event attached to an indev + * @param indev pointer to an indev + * @return number of events + */ +uint32_t lv_indev_get_event_count(lv_indev_t * indev); + +/** + * Get an event descriptor for an event + * @param indev pointer to an indev + * @param index the index of the event + * @return the event descriptor + */ +lv_event_dsc_t * lv_indev_get_event_dsc(lv_indev_t * indev, uint32_t index); + +/** + * Remove an event + * @param indev pointer to an indev + * @param index the index of the event to remove + * @return true: and event was removed; false: no event was removed + */ +bool lv_indev_remove_event(lv_indev_t * indev, uint32_t index); + +/** + * Remove an event_cb with user_data + * @param indev pointer to a indev + * @param event_cb the event_cb of the event to remove + * @param user_data user_data + * @return the count of the event removed + */ +uint32_t lv_indev_remove_event_cb_with_user_data(lv_indev_t * indev, lv_event_cb_t event_cb, void * user_data); + +/** + * Send an event to an indev + * @param indev pointer to an indev + * @param code an event code. LV_EVENT_... + * @param param optional param + * @return LV_RESULT_OK: indev wasn't deleted in the event. + */ +lv_result_t lv_indev_send_event(lv_indev_t * indev, lv_event_code_t code, void * param); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_INDEV_H*/ diff --git a/test/include/liblvgl/indev/lv_indev_private.h b/test/include/liblvgl/indev/lv_indev_private.h new file mode 100644 index 00000000..9bf98091 --- /dev/null +++ b/test/include/liblvgl/indev/lv_indev_private.h @@ -0,0 +1,137 @@ +/** + * @file lv_indev_private.h + * + */ + +#ifndef LV_INDEV_PRIVATE_H +#define LV_INDEV_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_indev.h" +#include "../misc/lv_anim.h" +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_indev_t { + /** Input device type*/ + lv_indev_type_t type; + + /** Function pointer to read input device data.*/ + lv_indev_read_cb_t read_cb; + + lv_indev_state_t state; /**< Current state of the input device.*/ + lv_indev_mode_t mode; + + /*Flags*/ + uint8_t long_pr_sent : 1; + uint8_t reset_query : 1; + uint8_t enabled : 1; + uint8_t wait_until_release : 1; + uint8_t stop_processing_query : 1; + + uint32_t pr_timestamp; /**< Pressed time stamp*/ + uint32_t longpr_rep_timestamp; /**< Long press repeat time stamp*/ + + void * driver_data; + void * user_data; + + /**< Pointer to the assigned display*/ + lv_display_t * disp; + + /**< Timer to periodically read the input device*/ + lv_timer_t * read_timer; + + /**< Number of pixels to slide before actually drag the object*/ + uint8_t scroll_limit; + + /**< Drag throw slow-down in [%]. Greater value means faster slow-down*/ + uint8_t scroll_throw; + + /**< At least this difference should be between two points to evaluate as gesture*/ + uint8_t gesture_min_velocity; + + /**< At least this difference should be to send a gesture*/ + uint8_t gesture_limit; + + /**< Long press time in milliseconds*/ + uint16_t long_press_time; + + /**< Repeated trigger period in long press [ms]*/ + uint16_t long_press_repeat_time; + + /**< Rotary diff count will be multiplied by this value and divided by 256*/ + int32_t rotary_sensitivity; + + struct { + /*Pointer and button data*/ + lv_point_t act_point; /**< Current point of input device.*/ + lv_point_t last_point; /**< Last point of input device.*/ + lv_point_t last_raw_point; /**< Last point read from read_cb. */ + lv_point_t vect; /**< Difference between `act_point` and `last_point`.*/ + lv_point_t scroll_sum; /*Count the dragged pixels to check LV_INDEV_DEF_SCROLL_LIMIT*/ + lv_point_t scroll_throw_vect; + lv_point_t scroll_throw_vect_ori; + lv_obj_t * act_obj; /*The object being pressed*/ + lv_obj_t * last_obj; /*The last object which was pressed*/ + lv_obj_t * scroll_obj; /*The object being scrolled*/ + lv_obj_t * last_pressed; /*The lastly pressed object*/ + lv_obj_t * last_hovered; /*The lastly hovered object*/ + lv_area_t scroll_area; + lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/ + int32_t diff; + /*Short click streaks*/ + uint8_t short_click_streak; + lv_point_t last_short_click_point; + uint32_t last_short_click_timestamp; + /*Flags*/ + uint8_t scroll_dir : 4; + uint8_t gesture_dir : 4; + uint8_t gesture_sent : 1; + uint8_t press_moved : 1; + } pointer; + struct { + /*Keypad data*/ + lv_indev_state_t last_state; + uint32_t last_key; + } keypad; + + lv_obj_t * cursor; /**< Cursor for LV_INPUT_TYPE_POINTER*/ + lv_group_t * group; /**< Keypad destination group*/ + const lv_point_t * btn_points; /**< Array points assigned to the button ()screen will be pressed + here by the buttons*/ + lv_event_list_t event_list; + lv_anim_t * scroll_throw_anim; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Find a scrollable object based on the current scroll vector in the indev. + * In handles scroll propagation to the parent if needed, and scroll directions too. + * @param indev pointer to an indev + * @return the found scrollable object or NULL if not found. + */ +lv_obj_t * lv_indev_find_scroll_obj(lv_indev_t * indev); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_INDEV_PRIVATE_H*/ diff --git a/test/include/liblvgl/indev/lv_indev_scroll.h b/test/include/liblvgl/indev/lv_indev_scroll.h new file mode 100644 index 00000000..413376f1 --- /dev/null +++ b/test/include/liblvgl/indev/lv_indev_scroll.h @@ -0,0 +1,65 @@ +/** + * @file lv_indev_scroll.h + * + */ + +#ifndef LV_INDEV_SCROLL_H +#define LV_INDEV_SCROLL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../core/lv_obj.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Handle scrolling. Called by LVGL during input device processing + * @param indev pointer to an input device + */ +void lv_indev_scroll_handler(lv_indev_t * indev); + +/** + * Handle throwing after scrolling. Called by LVGL during input device processing + * @param indev pointer to an input device + */ +void lv_indev_scroll_throw_handler(lv_indev_t * indev); + +/** + * Predict where would a scroll throw end + * @param indev pointer to an input device + * @param dir ` LV_DIR_VER` or `LV_DIR_HOR` + * @return the difference compared to the current position when the throw would be finished + */ +int32_t lv_indev_scroll_throw_predict(lv_indev_t * indev, lv_dir_t dir); + +/** + * Get the distance of the nearest snap point + * @param obj the object on which snap points should be found + * @param p save the distance of the found snap point there + */ +void lv_indev_scroll_get_snap_dist(lv_obj_t * obj, lv_point_t * p); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_INDEV_SCROLL_H*/ diff --git a/test/include/liblvgl/layouts/flex/lv_flex.h b/test/include/liblvgl/layouts/flex/lv_flex.h new file mode 100644 index 00000000..9724f9b1 --- /dev/null +++ b/test/include/liblvgl/layouts/flex/lv_flex.h @@ -0,0 +1,102 @@ +/** + * @file lv_flex.h + * + */ + +#ifndef LV_FLEX_H +#define LV_FLEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../misc/lv_area.h" + +#if LV_USE_FLEX + +/********************* + * DEFINES + *********************/ + +#define LV_FLEX_COLUMN (1 << 0) +#define LV_FLEX_WRAP (1 << 2) +#define LV_FLEX_REVERSE (1 << 3) + +/********************** + * TYPEDEFS + **********************/ + +/*Can't include lv_obj.h because it includes this header file*/ + +typedef enum { + LV_FLEX_ALIGN_START, + LV_FLEX_ALIGN_END, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_SPACE_EVENLY, + LV_FLEX_ALIGN_SPACE_AROUND, + LV_FLEX_ALIGN_SPACE_BETWEEN, +} lv_flex_align_t; + +typedef enum { + LV_FLEX_FLOW_ROW = 0x00, + LV_FLEX_FLOW_COLUMN = LV_FLEX_COLUMN, + LV_FLEX_FLOW_ROW_WRAP = LV_FLEX_FLOW_ROW | LV_FLEX_WRAP, + LV_FLEX_FLOW_ROW_REVERSE = LV_FLEX_FLOW_ROW | LV_FLEX_REVERSE, + LV_FLEX_FLOW_ROW_WRAP_REVERSE = LV_FLEX_FLOW_ROW | LV_FLEX_WRAP | LV_FLEX_REVERSE, + LV_FLEX_FLOW_COLUMN_WRAP = LV_FLEX_FLOW_COLUMN | LV_FLEX_WRAP, + LV_FLEX_FLOW_COLUMN_REVERSE = LV_FLEX_FLOW_COLUMN | LV_FLEX_REVERSE, + LV_FLEX_FLOW_COLUMN_WRAP_REVERSE = LV_FLEX_FLOW_COLUMN | LV_FLEX_WRAP | LV_FLEX_REVERSE, +} lv_flex_flow_t; + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a flex layout to default values + */ +void lv_flex_init(void); + +/** + * Set how the item should flow + * @param obj pointer to an object. The parent must have flex layout else nothing will happen. + * @param flow an element of `lv_flex_flow_t`. + */ +void lv_obj_set_flex_flow(lv_obj_t * obj, lv_flex_flow_t flow); + +/** + * Set how to place (where to align) the items and tracks + * @param obj pointer to an object. The parent must have flex layout else nothing will happen. + * @param main_place where to place the items on main axis (in their track). Any value of `lv_flex_align_t`. + * @param cross_place where to place the item in their track on the cross axis. `LV_FLEX_ALIGN_START/END/CENTER` + * @param track_cross_place where to place the tracks in the cross direction. Any value of `lv_flex_align_t`. + */ +void lv_obj_set_flex_align(lv_obj_t * obj, lv_flex_align_t main_place, lv_flex_align_t cross_place, + lv_flex_align_t track_cross_place); + +/** + * Sets the width or height (on main axis) to grow the object in order fill the free space + * @param obj pointer to an object. The parent must have flex layout else nothing will happen. + * @param grow a value to set how much free space to take proportionally to other growing items. + */ +void lv_obj_set_flex_grow(lv_obj_t * obj, uint8_t grow); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_FLEX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FLEX_H*/ diff --git a/test/include/liblvgl/layouts/grid/lv_grid.h b/test/include/liblvgl/layouts/grid/lv_grid.h new file mode 100644 index 00000000..a7bf7382 --- /dev/null +++ b/test/include/liblvgl/layouts/grid/lv_grid.h @@ -0,0 +1,99 @@ +/** + * @file lv_grid.h + * + */ + +#ifndef LV_GRID_H +#define LV_GRID_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../misc/lv_area.h" + +#if LV_USE_GRID + +/********************* + * DEFINES + *********************/ +/** + * Can be used track size to make the track fill the free space. + * @param x how much space to take proportionally to other FR tracks + * @return a special track size + */ +#define LV_GRID_FR(x) (LV_COORD_MAX - 100 + x) + +#define LV_GRID_CONTENT (LV_COORD_MAX - 101) +LV_EXPORT_CONST_INT(LV_GRID_CONTENT); + +#define LV_GRID_TEMPLATE_LAST (LV_COORD_MAX) +LV_EXPORT_CONST_INT(LV_GRID_TEMPLATE_LAST); + +/********************** + * TYPEDEFS + **********************/ + +/*Can't include lv_obj.h because it includes this header file*/ + +typedef enum { + LV_GRID_ALIGN_START, + LV_GRID_ALIGN_CENTER, + LV_GRID_ALIGN_END, + LV_GRID_ALIGN_STRETCH, + LV_GRID_ALIGN_SPACE_EVENLY, + LV_GRID_ALIGN_SPACE_AROUND, + LV_GRID_ALIGN_SPACE_BETWEEN, +} lv_grid_align_t; + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_grid_init(void); + +void lv_obj_set_grid_dsc_array(lv_obj_t * obj, const int32_t col_dsc[], const int32_t row_dsc[]); + +void lv_obj_set_grid_align(lv_obj_t * obj, lv_grid_align_t column_align, lv_grid_align_t row_align); + +/** + * Set the cell of an object. The object's parent needs to have grid layout, else nothing will happen + * @param obj pointer to an object + * @param column_align the vertical alignment in the cell. `LV_GRID_START/END/CENTER/STRETCH` + * @param col_pos column ID + * @param col_span number of columns to take (>= 1) + * @param row_align the horizontal alignment in the cell. `LV_GRID_START/END/CENTER/STRETCH` + * @param row_pos row ID + * @param row_span number of rows to take (>= 1) + */ +void lv_obj_set_grid_cell(lv_obj_t * obj, lv_grid_align_t column_align, int32_t col_pos, int32_t col_span, + lv_grid_align_t row_align, int32_t row_pos, int32_t row_span); + +/** + * Just a wrapper to `LV_GRID_FR` for bindings. + */ +int32_t lv_grid_fr(uint8_t x); + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_GRID*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GRID_H*/ diff --git a/test/include/liblvgl/layouts/lv_layout.h b/test/include/liblvgl/layouts/lv_layout.h new file mode 100644 index 00000000..a783d2b2 --- /dev/null +++ b/test/include/liblvgl/layouts/lv_layout.h @@ -0,0 +1,67 @@ +/** + * @file lv_layout.h + * + */ + +#ifndef LV_LAYOUT_H +#define LV_LAYOUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef void (*lv_layout_update_cb_t)(lv_obj_t *, void * user_data); + +typedef enum { + LV_LAYOUT_NONE = 0, + +#if LV_USE_FLEX + LV_LAYOUT_FLEX, +#endif + +#if LV_USE_GRID + LV_LAYOUT_GRID, +#endif + + LV_LAYOUT_LAST +} lv_layout_t; + +/** + * Register a new layout + * @param cb the layout update callback + * @param user_data custom data that will be passed to `cb` + * @return the ID of the new layout + */ +uint32_t lv_layout_register(lv_layout_update_cb_t cb, void * user_data); + +/********************** + * MACROS + **********************/ + +#if LV_USE_FLEX +#include "flex/lv_flex.h" +#endif /* LV_USE_FLEX */ + +#if LV_USE_GRID +#include "grid/lv_grid.h" +#endif /* LV_USE_GRID */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LAYOUT_H*/ diff --git a/test/include/liblvgl/layouts/lv_layout_private.h b/test/include/liblvgl/layouts/lv_layout_private.h new file mode 100644 index 00000000..dace2fcc --- /dev/null +++ b/test/include/liblvgl/layouts/lv_layout_private.h @@ -0,0 +1,58 @@ +/** + * @file lv_layout_private.h + * + */ + +#ifndef LV_LAYOUT_PRIVATE_H +#define LV_LAYOUT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_layout.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_layout_update_cb_t cb; + void * user_data; +} lv_layout_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_layout_init(void); + +void lv_layout_deinit(void); + +/** + * Update the layout of a widget + * @param obj pointer to a widget + */ +void lv_layout_apply(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LAYOUT_PRIVATE_H*/ diff --git a/test/include/liblvgl/libs/barcode/code128.h b/test/include/liblvgl/libs/barcode/code128.h new file mode 100644 index 00000000..51d53d0c --- /dev/null +++ b/test/include/liblvgl/libs/barcode/code128.h @@ -0,0 +1,47 @@ +// Copyright (c) 2013-15, LKC Technologies, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. Redistributions in binary +// form must reproduce the above copyright notice, this list of conditions and +// the following disclaimer in the documentation and/or other materials +// provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT +// HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CODE128_H +#define CODE128_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Since the FNCn characters are not ASCII, define versions here to +// simplify encoding strings that include them. +#define CODE128_FNC1 '\xf1' +#define CODE128_FNC2 '\xf2' +#define CODE128_FNC3 '\xf3' +#define CODE128_FNC4 '\xf4' + +size_t code128_estimate_len(const char * s); +size_t code128_encode_gs1(const char * s, char * out, size_t maxlength); +size_t code128_encode_raw(const char * s, char * out, size_t maxlength); + +#ifdef __cplusplus +} +#endif + +#endif // CODE128_H diff --git a/test/include/liblvgl/libs/barcode/lv_barcode.h b/test/include/liblvgl/libs/barcode/lv_barcode.h new file mode 100644 index 00000000..c9c0ce65 --- /dev/null +++ b/test/include/liblvgl/libs/barcode/lv_barcode.h @@ -0,0 +1,118 @@ +/** + * @file lv_barcode.h + * + */ + +#ifndef LV_BARCODE_H +#define LV_BARCODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../misc/lv_types.h" +#include "../../misc/lv_color.h" +#include "../../widgets/canvas/lv_canvas.h" + +#if LV_USE_BARCODE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_barcode_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an empty barcode (an `lv_canvas`) object. + * @param parent point to an object where to create the barcode + * @return pointer to the created barcode object + */ +lv_obj_t * lv_barcode_create(lv_obj_t * parent); + +/** + * Set the dark color of a barcode object + * @param obj pointer to barcode object + * @param color dark color of the barcode + */ +void lv_barcode_set_dark_color(lv_obj_t * obj, lv_color_t color); + +/** + * Set the light color of a barcode object + * @param obj pointer to barcode object + * @param color light color of the barcode + */ +void lv_barcode_set_light_color(lv_obj_t * obj, lv_color_t color); + +/** + * Set the scale of a barcode object + * @param obj pointer to barcode object + * @param scale scale factor + */ +void lv_barcode_set_scale(lv_obj_t * obj, uint16_t scale); + +/** + * Set the direction of a barcode object + * @param obj pointer to barcode object + * @param direction draw direction (`LV_DIR_HOR` or `LB_DIR_VER`) + */ +void lv_barcode_set_direction(lv_obj_t * obj, lv_dir_t direction); + +/** + * Set the tiled mode of a barcode object + * @param obj pointer to barcode object + * @param tiled true: tiled mode, false: normal mode (default) + */ +void lv_barcode_set_tiled(lv_obj_t * obj, bool tiled); + +/** + * Set the data of a barcode object + * @param obj pointer to barcode object + * @param data data to display + * @return LV_RESULT_OK: if no error; LV_RESULT_INVALID: on error + */ +lv_result_t lv_barcode_update(lv_obj_t * obj, const char * data); + +/** + * Get the dark color of a barcode object + * @param obj pointer to barcode object + * @return dark color of the barcode + */ +lv_color_t lv_barcode_get_dark_color(lv_obj_t * obj); + +/** + * Get the light color of a barcode object + * @param obj pointer to barcode object + * @return light color of the barcode + */ +lv_color_t lv_barcode_get_light_color(lv_obj_t * obj); + +/** + * Get the scale of a barcode object + * @param obj pointer to barcode object + * @return scale factor + */ +uint16_t lv_barcode_get_scale(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_BARCODE*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_BARCODE_H*/ diff --git a/test/include/liblvgl/libs/barcode/lv_barcode_private.h b/test/include/liblvgl/libs/barcode/lv_barcode_private.h new file mode 100644 index 00000000..dadf0684 --- /dev/null +++ b/test/include/liblvgl/libs/barcode/lv_barcode_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_barcode_private.h + * + */ + +#ifndef LV_BARCODE_PRIVATE_H +#define LV_BARCODE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../widgets/canvas/lv_canvas_private.h" +#include "lv_barcode.h" + +#if LV_USE_BARCODE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/*Data of barcode*/ +struct _lv_barcode_t { + lv_canvas_t canvas; + lv_color_t dark_color; + lv_color_t light_color; + uint16_t scale; + lv_dir_t direction; + bool tiled; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_BARCODE */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BARCODE_PRIVATE_H*/ diff --git a/test/include/liblvgl/libs/bin_decoder/lv_bin_decoder.h b/test/include/liblvgl/libs/bin_decoder/lv_bin_decoder.h new file mode 100644 index 00000000..d441230d --- /dev/null +++ b/test/include/liblvgl/libs/bin_decoder/lv_bin_decoder.h @@ -0,0 +1,70 @@ +/** + * @file lv_bin_decoder.h + * + */ + +#ifndef LV_BIN_DECODER_H +#define LV_BIN_DECODER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../draw/lv_image_decoder.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the binary image decoder module + */ +void lv_bin_decoder_init(void); + +/** + * Get info about a lvgl binary image + * @param decoder the decoder where this function belongs + * @param dsc image descriptor containing the source and type of the image and other info. + * @param header store the image data here + * @return LV_RESULT_OK: the info is successfully stored in `header`; LV_RESULT_INVALID: unknown format or other error. + */ +lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header); + +lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, + const lv_area_t * full_area, lv_area_t * decoded_area); + +/** + * Open a lvgl binary image + * @param decoder the decoder where this function belongs + * @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it. + * @return LV_RESULT_OK: the info is successfully stored in `header`; LV_RESULT_INVALID: unknown format or other error. + */ +lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); + +/** + * Close the pending decoding. Free resources etc. + * @param decoder pointer to the decoder the function associated with + * @param dsc pointer to decoder descriptor + */ +void lv_bin_decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BIN_DECODER_H*/ diff --git a/test/include/liblvgl/libs/bmp/lv_bmp.h b/test/include/liblvgl/libs/bmp/lv_bmp.h new file mode 100644 index 00000000..a7dbe277 --- /dev/null +++ b/test/include/liblvgl/libs/bmp/lv_bmp.h @@ -0,0 +1,43 @@ +/** + * @file lv_bmp.h + * + */ + +#ifndef LV_BMP_H +#define LV_BMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_BMP + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void lv_bmp_init(void); +void lv_bmp_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_BMP*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_BMP_H*/ diff --git a/test/include/liblvgl/libs/ffmpeg/lv_ffmpeg.h b/test/include/liblvgl/libs/ffmpeg/lv_ffmpeg.h new file mode 100644 index 00000000..1cb86b9d --- /dev/null +++ b/test/include/liblvgl/libs/ffmpeg/lv_ffmpeg.h @@ -0,0 +1,97 @@ +/** + * @file lv_ffmpeg.h + * + */ +#ifndef LV_FFMPEG_H +#define LV_FFMPEG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_FFMPEG != 0 +#include "../../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +struct ffmpeg_context_s; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_ffmpeg_player_class; + +typedef enum { + LV_FFMPEG_PLAYER_CMD_START, + LV_FFMPEG_PLAYER_CMD_STOP, + LV_FFMPEG_PLAYER_CMD_PAUSE, + LV_FFMPEG_PLAYER_CMD_RESUME, + LV_FFMPEG_PLAYER_CMD_LAST +} lv_ffmpeg_player_cmd_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Register FFMPEG image decoder + */ +void lv_ffmpeg_init(void); + +/** + * Get the number of frames contained in the file + * @param path image or video file name + * @return Number of frames, less than 0 means failed + */ +int lv_ffmpeg_get_frame_num(const char * path); + +/** + * Create ffmpeg_player object + * @param parent pointer to an object, it will be the parent of the new player + * @return pointer to the created ffmpeg_player + */ +lv_obj_t * lv_ffmpeg_player_create(lv_obj_t * parent); + +/** + * Set the path of the file to be played + * @param obj pointer to a ffmpeg_player object + * @param path video file path + * @return LV_RESULT_OK: no error; LV_RESULT_INVALID: can't get the info. + */ +lv_result_t lv_ffmpeg_player_set_src(lv_obj_t * obj, const char * path); + +/** + * Set command control video player + * @param obj pointer to a ffmpeg_player object + * @param cmd control commands + */ +void lv_ffmpeg_player_set_cmd(lv_obj_t * obj, lv_ffmpeg_player_cmd_t cmd); + +/** + * Set the video to automatically replay + * @param obj pointer to a ffmpeg_player object + * @param en true: enable the auto restart + */ +void lv_ffmpeg_player_set_auto_restart(lv_obj_t * obj, bool en); + +/*===================== + * Other functions + *====================*/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_FFMPEG*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FFMPEG_H*/ diff --git a/test/include/liblvgl/libs/ffmpeg/lv_ffmpeg_private.h b/test/include/liblvgl/libs/ffmpeg/lv_ffmpeg_private.h new file mode 100644 index 00000000..e4a0488a --- /dev/null +++ b/test/include/liblvgl/libs/ffmpeg/lv_ffmpeg_private.h @@ -0,0 +1,51 @@ +/** + * @file lv_ffmpeg_private.h + * + */ + +#ifndef LV_FFMPEG_PRIVATE_H +#define LV_FFMPEG_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_ffmpeg.h" +#if LV_USE_FFMPEG != 0 +#include "../../widgets/image/lv_image_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_ffmpeg_player_t { + lv_image_t img; + lv_timer_t * timer; + lv_image_dsc_t imgdsc; + bool auto_restart; + struct ffmpeg_context_s * ffmpeg_ctx; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_FFMPEG*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FFMPEG_PRIVATE_H*/ diff --git a/test/include/liblvgl/libs/freetype/arial.ttf b/test/include/liblvgl/libs/freetype/arial.ttf new file mode 100644 index 0000000000000000000000000000000000000000..886789b85b4b4e662519fcb7fe4d88ddf2205c5b GIT binary patch literal 311636 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 VXQc0|TekeI1$m{%qWu+${|A/objs/`) based on information + * from `/modules.cfg`. + * + * Please read `docs/INSTALL.ANY` and `docs/CUSTOMIZE` how to compile + * FreeType without GNU make. + * + */ + +/* FT_USE_MODULE( FT_Module_Class, autofit_module_class ) */ +FT_USE_MODULE(FT_Driver_ClassRec, tt_driver_class) +/* FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) */ +/* FT_USE_MODULE( FT_Module_Class, psaux_module_class ) */ +/* FT_USE_MODULE( FT_Module_Class, psnames_module_class ) */ +/* FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) */ +FT_USE_MODULE(FT_Module_Class, sfnt_module_class) +FT_USE_MODULE(FT_Renderer_Class, ft_smooth_renderer_class) +/* FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) */ +/* FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class ) */ +/* FT_USE_MODULE( FT_Renderer_Class, ft_bitmap_sdf_renderer_class ) */ +/* FT_USE_MODULE( FT_Renderer_Class, ft_svg_renderer_class ) */ + +/* EOF */ diff --git a/test/include/liblvgl/libs/freetype/ftoption.h b/test/include/liblvgl/libs/freetype/ftoption.h new file mode 100644 index 00000000..1a762bb0 --- /dev/null +++ b/test/include/liblvgl/libs/freetype/ftoption.h @@ -0,0 +1,964 @@ +/**************************************************************************** + * + * ftoption.h + * + * User-selectable configuration macros (specification only). + * + * Copyright (C) 1996-2022 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +#ifndef FTOPTION_H_ +#define FTOPTION_H_ + +#include + +FT_BEGIN_HEADER + +/************************************************************************** + * + * USER-SELECTABLE CONFIGURATION MACROS + * + * This file contains the default configuration macro definitions for a + * standard build of the FreeType library. There are three ways to use + * this file to build project-specific versions of the library: + * + * - You can modify this file by hand, but this is not recommended in + * cases where you would like to build several versions of the library + * from a single source directory. + * + * - You can put a copy of this file in your build directory, more + * precisely in `$BUILD/freetype/config/ftoption.h`, where `$BUILD` is + * the name of a directory that is included _before_ the FreeType include + * path during compilation. + * + * The default FreeType Makefiles use the build directory + * `builds/` by default, but you can easily change that for your + * own projects. + * + * - Copy the file to `$BUILD/ft2build.h` and modify it + * slightly to pre-define the macro `FT_CONFIG_OPTIONS_H` used to locate + * this file during the build. For example, + * + * ``` + * #define FT_CONFIG_OPTIONS_H + * #include + * ``` + * + * will use `$BUILD/myftoptions.h` instead of this file for macro + * definitions. + * + * Note also that you can similarly pre-define the macro + * `FT_CONFIG_MODULES_H` used to locate the file listing of the modules + * that are statically linked to the library at compile time. By + * default, this file is ``. + * + * We highly recommend using the third method whenever possible. + * + */ + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + +/*#************************************************************************ + * + * If you enable this configuration option, FreeType recognizes an + * environment variable called `FREETYPE_PROPERTIES`, which can be used to + * control the various font drivers and modules. The controllable + * properties are listed in the section @properties. + * + * You have to undefine this configuration option on platforms that lack + * the concept of environment variables (and thus don't have the `getenv` + * function), for example Windows CE. + * + * `FREETYPE_PROPERTIES` has the following syntax form (broken here into + * multiple lines for better readability). + * + * ``` + * + * ':' + * '=' + * + * ':' + * '=' + * ... + * ``` + * + * Example: + * + * ``` + * FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ + * cff:no-stem-darkening=1 + * ``` + * + */ +#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + +/************************************************************************** + * + * Uncomment the line below if you want to activate LCD rendering + * technology similar to ClearType in this build of the library. This + * technology triples the resolution in the direction color subpixels. To + * mitigate color fringes inherent to this technology, you also need to + * explicitly set up LCD filtering. + * + * When this macro is not defined, FreeType offers alternative LCD + * rendering technology that produces excellent output. + */ +/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + +/************************************************************************** + * + * Many compilers provide a non-ANSI 64-bit data type that can be used by + * FreeType to speed up some computations. However, this will create some + * problems when compiling the library in strict ANSI mode. + * + * For this reason, the use of 64-bit integers is normally disabled when + * the `__STDC__` macro is defined. You can however disable this by + * defining the macro `FT_CONFIG_OPTION_FORCE_INT64` here. + * + * For most compilers, this will only create compilation warnings when + * building the library. + * + * ObNote: The compiler-specific 64-bit integers are detected in the + * file `ftconfig.h` either statically or through the `configure` + * script on supported platforms. + */ +#undef FT_CONFIG_OPTION_FORCE_INT64 + +/************************************************************************** + * + * If this macro is defined, do not try to use an assembler version of + * performance-critical functions (e.g., @FT_MulFix). You should only do + * that to verify that the assembler function works properly, or to execute + * benchmark tests of the various implementations. + */ +/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ + +/************************************************************************** + * + * If this macro is defined, try to use an inlined assembler version of the + * @FT_MulFix function, which is a 'hotspot' when loading and hinting + * glyphs, and which should be executed as fast as possible. + * + * Note that if your compiler or CPU is not supported, this will default to + * the standard and portable implementation found in `ftcalc.c`. + */ +#define FT_CONFIG_OPTION_INLINE_MULFIX + +/************************************************************************** + * + * LZW-compressed file support. + * + * FreeType now handles font files that have been compressed with the + * `compress` program. This is mostly used to parse many of the PCF + * files that come with various X11 distributions. The implementation + * uses NetBSD's `zopen` to partially uncompress the file on the fly (see + * `src/lzw/ftgzip.c`). + * + * Define this macro if you want to enable this 'feature'. + */ +#define FT_CONFIG_OPTION_USE_LZW + +/************************************************************************** + * + * Gzip-compressed file support. + * + * FreeType now handles font files that have been compressed with the + * `gzip` program. This is mostly used to parse many of the PCF files + * that come with XFree86. The implementation uses 'zlib' to partially + * uncompress the file on the fly (see `src/gzip/ftgzip.c`). + * + * Define this macro if you want to enable this 'feature'. See also the + * macro `FT_CONFIG_OPTION_SYSTEM_ZLIB` below. + */ +#define FT_CONFIG_OPTION_USE_ZLIB + +/************************************************************************** + * + * ZLib library selection + * + * This macro is only used when `FT_CONFIG_OPTION_USE_ZLIB` is defined. + * It allows FreeType's 'ftgzip' component to link to the system's + * installation of the ZLib library. This is useful on systems like + * Unix or VMS where it generally is already available. + * + * If you let it undefined, the component will use its own copy of the + * zlib sources instead. These have been modified to be included + * directly within the component and **not** export external function + * names. This allows you to link any program with FreeType _and_ ZLib + * without linking conflicts. + * + * Do not `#undef` this macro here since the build system might define + * it for certain configurations only. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + * + * If you use the GNU make build system directly (that is, without the + * `configure` script) and you define this macro, you also have to pass + * `SYSTEM_ZLIB=yes` as an argument to make. + */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ + +/************************************************************************** + * + * Bzip2-compressed file support. + * + * FreeType now handles font files that have been compressed with the + * `bzip2` program. This is mostly used to parse many of the PCF files + * that come with XFree86. The implementation uses `libbz2` to partially + * uncompress the file on the fly (see `src/bzip2/ftbzip2.c`). Contrary + * to gzip, bzip2 currently is not included and need to use the system + * available bzip2 implementation. + * + * Define this macro if you want to enable this 'feature'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ +/* #define FT_CONFIG_OPTION_USE_BZIP2 */ + +/************************************************************************** + * + * Define to disable the use of file stream functions and types, `FILE`, + * `fopen`, etc. Enables the use of smaller system libraries on embedded + * systems that have multiple system libraries, some with or without file + * stream support, in the cases where file stream support is not necessary + * such as memory loading of font files. + */ +/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ + +/************************************************************************** + * + * PNG bitmap support. + * + * FreeType now handles loading color bitmap glyphs in the PNG format. + * This requires help from the external libpng library. Uncompressed + * color bitmaps do not need any external libraries and will be supported + * regardless of this configuration. + * + * Define this macro if you want to enable this 'feature'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ +#define FT_CONFIG_OPTION_USE_PNG + +/************************************************************************** + * + * HarfBuzz support. + * + * FreeType uses the HarfBuzz library to improve auto-hinting of OpenType + * fonts. If available, many glyphs not directly addressable by a font's + * character map will be hinted also. + * + * Define this macro if you want to enable this 'feature'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ +/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */ + +/************************************************************************** + * + * Brotli support. + * + * FreeType uses the Brotli library to provide support for decompressing + * WOFF2 streams. + * + * Define this macro if you want to enable this 'feature'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ +/* #define FT_CONFIG_OPTION_USE_BROTLI */ + +/************************************************************************** + * + * Glyph Postscript Names handling + * + * By default, FreeType 2 is compiled with the 'psnames' module. This + * module is in charge of converting a glyph name string into a Unicode + * value, or return a Macintosh standard glyph name for the use with the + * TrueType 'post' table. + * + * Undefine this macro if you do not want 'psnames' compiled in your + * build of FreeType. This has the following effects: + * + * - The TrueType driver will provide its own set of glyph names, if you + * build it to support postscript names in the TrueType 'post' table, + * but will not synthesize a missing Unicode charmap. + * + * - The Type~1 driver will not be able to synthesize a Unicode charmap + * out of the glyphs found in the fonts. + * + * You would normally undefine this configuration macro when building a + * version of FreeType that doesn't contain a Type~1 or CFF driver. + */ +#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES + +/************************************************************************** + * + * Postscript Names to Unicode Values support + * + * By default, FreeType~2 is built with the 'psnames' module compiled in. + * Among other things, the module is used to convert a glyph name into a + * Unicode value. This is especially useful in order to synthesize on + * the fly a Unicode charmap from the CFF/Type~1 driver through a big + * table named the 'Adobe Glyph List' (AGL). + * + * Undefine this macro if you do not want the Adobe Glyph List compiled + * in your 'psnames' module. The Type~1 driver will not be able to + * synthesize a Unicode charmap out of the glyphs found in the fonts. + */ +#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + +/************************************************************************** + * + * Support for Mac fonts + * + * Define this macro if you want support for outline fonts in Mac format + * (mac dfont, mac resource, macbinary containing a mac resource) on + * non-Mac platforms. + * + * Note that the 'FOND' resource isn't checked. + */ +/* #define FT_CONFIG_OPTION_MAC_FONTS */ + +/************************************************************************** + * + * Guessing methods to access embedded resource forks + * + * Enable extra Mac fonts support on non-Mac platforms (e.g., GNU/Linux). + * + * Resource forks which include fonts data are stored sometimes in + * locations which users or developers don't expected. In some cases, + * resource forks start with some offset from the head of a file. In + * other cases, the actual resource fork is stored in file different from + * what the user specifies. If this option is activated, FreeType tries + * to guess whether such offsets or different file names must be used. + * + * Note that normal, direct access of resource forks is controlled via + * the `FT_CONFIG_OPTION_MAC_FONTS` option. + */ +#ifdef FT_CONFIG_OPTION_MAC_FONTS + #define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#endif + +/************************************************************************** + * + * Allow the use of `FT_Incremental_Interface` to load typefaces that + * contain no glyph data, but supply it via a callback function. This is + * required by clients supporting document formats which supply font data + * incrementally as the document is parsed, such as the Ghostscript + * interpreter for the PostScript language. + */ +#define FT_CONFIG_OPTION_INCREMENTAL + +/************************************************************************** + * + * The size in bytes of the render pool used by the scan-line converter to + * do all of its work. + */ +#define FT_RENDER_POOL_SIZE 16384L + +/************************************************************************** + * + * FT_MAX_MODULES + * + * The maximum number of modules that can be registered in a single + * FreeType library object. 32~is the default. + */ +#define FT_MAX_MODULES 32 + +/************************************************************************** + * + * Debug level + * + * FreeType can be compiled in debug or trace mode. In debug mode, + * errors are reported through the 'ftdebug' component. In trace mode, + * additional messages are sent to the standard output during execution. + * + * Define `FT_DEBUG_LEVEL_ERROR` to build the library in debug mode. + * Define `FT_DEBUG_LEVEL_TRACE` to build it in trace mode. + * + * Don't define any of these macros to compile in 'release' mode! + * + * Do not `#undef` these macros here since the build system might define + * them for certain configurations only. + */ +/* #define FT_DEBUG_LEVEL_ERROR */ +/* #define FT_DEBUG_LEVEL_TRACE */ + +/************************************************************************** + * + * Logging + * + * Compiling FreeType in debug or trace mode makes FreeType write error + * and trace log messages to `stderr`. Enabling this macro + * automatically forces the `FT_DEBUG_LEVEL_ERROR` and + * `FT_DEBUG_LEVEL_TRACE` macros and allows FreeType to write error and + * trace log messages to a file instead of `stderr`. For writing logs + * to a file, FreeType uses an the external `dlg` library (the source + * code is in `src/dlg`). + * + * This option needs a C99 compiler. + */ +/* #define FT_DEBUG_LOGGING */ + +/************************************************************************** + * + * Autofitter debugging + * + * If `FT_DEBUG_AUTOFIT` is defined, FreeType provides some means to + * control the autofitter behaviour for debugging purposes with global + * boolean variables (consequently, you should **never** enable this + * while compiling in 'release' mode): + * + * ``` + * _af_debug_disable_horz_hints + * _af_debug_disable_vert_hints + * _af_debug_disable_blue_hints + * ``` + * + * Additionally, the following functions provide dumps of various + * internal autofit structures to stdout (using `printf`): + * + * ``` + * af_glyph_hints_dump_points + * af_glyph_hints_dump_segments + * af_glyph_hints_dump_edges + * af_glyph_hints_get_num_segments + * af_glyph_hints_get_segment_offset + * ``` + * + * As an argument, they use another global variable: + * + * ``` + * _af_debug_hints + * ``` + * + * Please have a look at the `ftgrid` demo program to see how those + * variables and macros should be used. + * + * Do not `#undef` these macros here since the build system might define + * them for certain configurations only. + */ +/* #define FT_DEBUG_AUTOFIT */ + +/************************************************************************** + * + * Memory Debugging + * + * FreeType now comes with an integrated memory debugger that is capable + * of detecting simple errors like memory leaks or double deletes. To + * compile it within your build of the library, you should define + * `FT_DEBUG_MEMORY` here. + * + * Note that the memory debugger is only activated at runtime when when + * the _environment_ variable `FT2_DEBUG_MEMORY` is defined also! + * + * Do not `#undef` this macro here since the build system might define it + * for certain configurations only. + */ +/* #define FT_DEBUG_MEMORY */ + +/************************************************************************** + * + * Module errors + * + * If this macro is set (which is _not_ the default), the higher byte of + * an error code gives the module in which the error has occurred, while + * the lower byte is the real error code. + * + * Setting this macro makes sense for debugging purposes only, since it + * would break source compatibility of certain programs that use + * FreeType~2. + * + * More details can be found in the files `ftmoderr.h` and `fterrors.h`. + */ +#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + +/************************************************************************** + * + * OpenType SVG Glyph Support + * + * Setting this macro enables support for OpenType SVG glyphs. By + * default, FreeType can only fetch SVG documents. However, it can also + * render them if external rendering hook functions are plugged in at + * runtime. + * + * More details on the hooks can be found in file `otsvg.h`. + */ +#define FT_CONFIG_OPTION_SVG + +/************************************************************************** + * + * Error Strings + * + * If this macro is set, `FT_Error_String` will return meaningful + * descriptions. This is not enabled by default to reduce the overall + * size of FreeType. + * + * More details can be found in the file `fterrors.h`. + */ +#define FT_CONFIG_OPTION_ERROR_STRINGS + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** S F N T D R I V E R C O N F I G U R A T I O N ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + +/************************************************************************** + * + * Define `TT_CONFIG_OPTION_EMBEDDED_BITMAPS` if you want to support + * embedded bitmaps in all formats using the 'sfnt' module (namely + * TrueType~& OpenType). + */ +#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS + +/************************************************************************** + * + * Define `TT_CONFIG_OPTION_COLOR_LAYERS` if you want to support colored + * outlines (from the 'COLR'/'CPAL' tables) in all formats using the 'sfnt' + * module (namely TrueType~& OpenType). + */ +#define TT_CONFIG_OPTION_COLOR_LAYERS + +/************************************************************************** + * + * Define `TT_CONFIG_OPTION_POSTSCRIPT_NAMES` if you want to be able to + * load and enumerate the glyph Postscript names in a TrueType or OpenType + * file. + * + * Note that when you do not compile the 'psnames' module by undefining the + * above `FT_CONFIG_OPTION_POSTSCRIPT_NAMES`, the 'sfnt' module will + * contain additional code used to read the PS Names table from a font. + * + * (By default, the module uses 'psnames' to extract glyph names.) + */ +#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES + +/************************************************************************** + * + * Define `TT_CONFIG_OPTION_SFNT_NAMES` if your applications need to access + * the internal name table in a SFNT-based format like TrueType or + * OpenType. The name table contains various strings used to describe the + * font, like family name, copyright, version, etc. It does not contain + * any glyph name though. + * + * Accessing SFNT names is done through the functions declared in + * `ftsnames.h`. + */ +#define TT_CONFIG_OPTION_SFNT_NAMES + +/************************************************************************** + * + * TrueType CMap support + * + * Here you can fine-tune which TrueType CMap table format shall be + * supported. + */ +#define TT_CONFIG_CMAP_FORMAT_0 +#define TT_CONFIG_CMAP_FORMAT_2 +#define TT_CONFIG_CMAP_FORMAT_4 +#define TT_CONFIG_CMAP_FORMAT_6 +#define TT_CONFIG_CMAP_FORMAT_8 +#define TT_CONFIG_CMAP_FORMAT_10 +#define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_13 +#define TT_CONFIG_CMAP_FORMAT_14 + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + +/************************************************************************** + * + * Define `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` if you want to compile a + * bytecode interpreter in the TrueType driver. + * + * By undefining this, you will only compile the code necessary to load + * TrueType glyphs without hinting. + * + * Do not `#undef` this macro here, since the build system might define it + * for certain configurations only. + */ +#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER + +/************************************************************************** + * + * Define `TT_CONFIG_OPTION_SUBPIXEL_HINTING` if you want to compile + * subpixel hinting support into the TrueType driver. This modifies the + * TrueType hinting mechanism when anything but `FT_RENDER_MODE_MONO` is + * requested. + * + * In particular, it modifies the bytecode interpreter to interpret (or + * not) instructions in a certain way so that all TrueType fonts look like + * they do in a Windows ClearType (DirectWrite) environment. See [1] for a + * technical overview on what this means. See `ttinterp.h` for more + * details on the LEAN option. + * + * There are three possible values. + * + * Value 1: + * This value is associated with the 'Infinality' moniker, contributed by + * an individual nicknamed Infinality with the goal of making TrueType + * fonts render better than on Windows. A high amount of configurability + * and flexibility, down to rules for single glyphs in fonts, but also + * very slow. Its experimental and slow nature and the original + * developer losing interest meant that this option was never enabled in + * default builds. + * + * The corresponding interpreter version is v38. + * + * Value 2: + * The new default mode for the TrueType driver. The Infinality code + * base was stripped to the bare minimum and all configurability removed + * in the name of speed and simplicity. The configurability was mainly + * aimed at legacy fonts like 'Arial', 'Times New Roman', or 'Courier'. + * Legacy fonts are fonts that modify vertical stems to achieve clean + * black-and-white bitmaps. The new mode focuses on applying a minimal + * set of rules to all fonts indiscriminately so that modern and web + * fonts render well while legacy fonts render okay. + * + * The corresponding interpreter version is v40. + * + * Value 3: + * Compile both, making both v38 and v40 available (the latter is the + * default). + * + * By undefining these, you get rendering behavior like on Windows without + * ClearType, i.e., Windows XP without ClearType enabled and Win9x + * (interpreter version v35). Or not, depending on how much hinting blood + * and testing tears the font designer put into a given font. If you + * define one or both subpixel hinting options, you can switch between + * between v35 and the ones you define (using `FT_Property_Set`). + * + * This option requires `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` to be + * defined. + * + * [1] + * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx + */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ +#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ + +/************************************************************************** + * + * Define `TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED` to compile the + * TrueType glyph loader to use Apple's definition of how to handle + * component offsets in composite glyphs. + * + * Apple and MS disagree on the default behavior of component offsets in + * composites. Apple says that they should be scaled by the scaling + * factors in the transformation matrix (roughly, it's more complex) while + * MS says they should not. OpenType defines two bits in the composite + * flags array which can be used to disambiguate, but old fonts will not + * have them. + * + * https://www.microsoft.com/typography/otspec/glyf.htm + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html + */ +#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + +/************************************************************************** + * + * Define `TT_CONFIG_OPTION_GX_VAR_SUPPORT` if you want to include support + * for Apple's distortable font technology ('fvar', 'gvar', 'cvar', and + * 'avar' tables). Tagged 'Font Variations', this is now part of OpenType + * also. This has many similarities to Type~1 Multiple Masters support. + */ +#define TT_CONFIG_OPTION_GX_VAR_SUPPORT + +/************************************************************************** + * + * Define `TT_CONFIG_OPTION_BDF` if you want to include support for an + * embedded 'BDF~' table within SFNT-based bitmap formats. + */ +#define TT_CONFIG_OPTION_BDF + +/************************************************************************** + * + * Option `TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES` controls the maximum + * number of bytecode instructions executed for a single run of the + * bytecode interpreter, needed to prevent infinite loops. You don't want + * to change this except for very special situations (e.g., making a + * library fuzzer spend less time to handle broken fonts). + * + * It is not expected that this value is ever modified by a configuring + * script; instead, it gets surrounded with `#ifndef ... #endif` so that + * the value can be set as a preprocessor option on the compiler's command + * line. + */ +#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES + #define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L +#endif + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + +/************************************************************************** + * + * `T1_MAX_DICT_DEPTH` is the maximum depth of nest dictionaries and arrays + * in the Type~1 stream (see `t1load.c`). A minimum of~4 is required. + */ +#define T1_MAX_DICT_DEPTH 5 + +/************************************************************************** + * + * `T1_MAX_SUBRS_CALLS` details the maximum number of nested sub-routine + * calls during glyph loading. + */ +#define T1_MAX_SUBRS_CALLS 16 + +/************************************************************************** + * + * `T1_MAX_CHARSTRING_OPERANDS` is the charstring stack's capacity. A + * minimum of~16 is required. + * + * The Chinese font 'MingTiEG-Medium' (covering the CNS 11643 character + * set) needs 256. + */ +#define T1_MAX_CHARSTRINGS_OPERANDS 256 + +/************************************************************************** + * + * Define this configuration macro if you want to prevent the compilation + * of the 't1afm' module, which is in charge of reading Type~1 AFM files + * into an existing face. Note that if set, the Type~1 driver will be + * unable to produce kerning distances. + */ +#undef T1_CONFIG_OPTION_NO_AFM + +/************************************************************************** + * + * Define this configuration macro if you want to prevent the compilation + * of the Multiple Masters font support in the Type~1 driver. + */ +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT + +/************************************************************************** + * + * `T1_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe Type~1 + * engine gets compiled into FreeType. If defined, it is possible to + * switch between the two engines using the `hinting-engine` property of + * the 'type1' driver module. + */ +/* #define T1_CONFIG_OPTION_OLD_ENGINE */ + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** C F F D R I V E R C O N F I G U R A T I O N ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + +/************************************************************************** + * + * Using `CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4}` it is + * possible to set up the default values of the four control points that + * define the stem darkening behaviour of the (new) CFF engine. For more + * details please read the documentation of the `darkening-parameters` + * property (file `ftdriver.h`), which allows the control at run-time. + * + * Do **not** undefine these macros! + */ +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 + +/************************************************************************** + * + * `CFF_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe CFF engine + * gets compiled into FreeType. If defined, it is possible to switch + * between the two engines using the `hinting-engine` property of the 'cff' + * driver module. + */ +/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** P C F D R I V E R C O N F I G U R A T I O N ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + +/************************************************************************** + * + * There are many PCF fonts just called 'Fixed' which look completely + * different, and which have nothing to do with each other. When selecting + * 'Fixed' in KDE or Gnome one gets results that appear rather random, the + * style changes often if one changes the size and one cannot select some + * fonts at all. This option makes the 'pcf' module prepend the foundry + * name (plus a space) to the family name. + * + * We also check whether we have 'wide' characters; all put together, we + * get family names like 'Sony Fixed' or 'Misc Fixed Wide'. + * + * If this option is activated, it can be controlled with the + * `no-long-family-names` property of the 'pcf' driver module. + */ +/* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + +/************************************************************************** + * + * Compile 'autofit' module with CJK (Chinese, Japanese, Korean) script + * support. + */ +#define AF_CONFIG_OPTION_CJK + +/************************************************************************** + * + * Compile 'autofit' module with fallback Indic script support, covering + * some scripts that the 'latin' submodule of the 'autofit' module doesn't + * (yet) handle. Currently, this needs option `AF_CONFIG_OPTION_CJK`. + */ +#ifdef AF_CONFIG_OPTION_CJK + #define AF_CONFIG_OPTION_INDIC +#endif + +/************************************************************************** + * + * Use TrueType-like size metrics for 'light' auto-hinting. + * + * It is strongly recommended to avoid this option, which exists only to + * help some legacy applications retain its appearance and behaviour with + * respect to auto-hinted TrueType fonts. + * + * The very reason this option exists at all are GNU/Linux distributions + * like Fedora that did not un-patch the following change (which was + * present in FreeType between versions 2.4.6 and 2.7.1, inclusive). + * + * ``` + * 2011-07-16 Steven Chu + * + * [truetype] Fix metrics on size request for scalable fonts. + * ``` + * + * This problematic commit is now reverted (more or less). + */ +/* #define AF_CONFIG_OPTION_TT_SIZE_METRICS */ + +/* */ + +/* + * This macro is obsolete. Support has been removed in FreeType version + * 2.5. + */ +/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ + +/* + * The next three macros are defined if native TrueType hinting is + * requested by the definitions above. Don't change this. + */ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + #define TT_USE_BYTECODE_INTERPRETER + + #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + #if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1 + #define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + #endif + + #if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2 + #define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + #endif + #endif +#endif + +/* + * The TT_SUPPORT_COLRV1 macro is defined to indicate to clients that this + * version of FreeType has support for 'COLR' v1 API. This definition is + * useful to FreeType clients that want to build in support for 'COLR' v1 + * depending on a tip-of-tree checkout before it is officially released in + * FreeType, and while the feature cannot yet be tested against using + * version macros. Don't change this macro. This may be removed once the + * feature is in a FreeType release version and version macros can be used + * to test for availability. + */ +#ifdef TT_CONFIG_OPTION_COLOR_LAYERS + #define TT_SUPPORT_COLRV1 +#endif + +/* + * Check CFF darkening parameters. The checks are the same as in function + * `cff_property_set` in file `cffdrivr.c`. + */ +#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500 + #error "Invalid CFF darkening parameters!" +#endif + +FT_END_HEADER + +#endif /* FTOPTION_H_ */ + +/* END */ diff --git a/test/include/liblvgl/libs/freetype/lv_freetype.h b/test/include/liblvgl/libs/freetype/lv_freetype.h new file mode 100644 index 00000000..76b9f7b5 --- /dev/null +++ b/test/include/liblvgl/libs/freetype/lv_freetype.h @@ -0,0 +1,127 @@ +/** + * @file lv_freetype.h + * + */ +#ifndef LV_FREETYPE_H +#define LV_FREETYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../misc/lv_types.h" +#include "../../misc/lv_event.h" +#include LV_STDBOOL_INCLUDE + +#if LV_USE_FREETYPE + +/********************* + * DEFINES + *********************/ + +#define LV_FREETYPE_F26DOT6_TO_INT(x) ((x) >> 6) +#define LV_FREETYPE_F26DOT6_TO_FLOAT(x) ((float)(x) / 64) + +#define FT_FONT_STYLE_NORMAL LV_FREETYPE_FONT_STYLE_NORMAL +#define FT_FONT_STYLE_ITALIC LV_FREETYPE_FONT_STYLE_ITALIC +#define FT_FONT_STYLE_BOLD LV_FREETYPE_FONT_STYLE_BOLD + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_FREETYPE_FONT_STYLE_NORMAL = 0, + LV_FREETYPE_FONT_STYLE_ITALIC = 1 << 0, + LV_FREETYPE_FONT_STYLE_BOLD = 1 << 1, +} lv_freetype_font_style_t; + +typedef lv_freetype_font_style_t LV_FT_FONT_STYLE; + +typedef enum { + LV_FREETYPE_FONT_RENDER_MODE_BITMAP = 0, + LV_FREETYPE_FONT_RENDER_MODE_OUTLINE = 1, +} lv_freetype_font_render_mode_t; + +typedef void * lv_freetype_outline_t; + +typedef enum { + LV_FREETYPE_OUTLINE_END, + LV_FREETYPE_OUTLINE_MOVE_TO, + LV_FREETYPE_OUTLINE_LINE_TO, + LV_FREETYPE_OUTLINE_CUBIC_TO, + LV_FREETYPE_OUTLINE_CONIC_TO, +} lv_freetype_outline_type_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the freetype library. + * @return LV_RESULT_OK on success, otherwise LV_RESULT_INVALID. + */ +lv_result_t lv_freetype_init(uint32_t max_glyph_cnt); + +/** + * Uninitialize the freetype library + */ +void lv_freetype_uninit(void); + +/** + * Create a freetype font. + * @param pathname font file path. + * @param render_mode font render mode(see @lv_freetype_font_render_mode_t for details). + * @param size font size. + * @param style font style(see lv_freetype_font_style_t for details). + * @return Created font, or NULL on failure. + */ +lv_font_t * lv_freetype_font_create(const char * pathname, lv_freetype_font_render_mode_t render_mode, uint32_t size, + lv_freetype_font_style_t style); + +/** + * Delete a freetype font. + * @param font freetype font to be deleted. + */ +void lv_freetype_font_delete(lv_font_t * font); + +/** + * Register a callback function to generate outlines for FreeType fonts. + * + * @param cb The callback function to be registered. + * @param user_data User data to be passed to the callback function. + * @return The ID of the registered callback function, or a negative value on failure. + */ +void lv_freetype_outline_add_event(lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data); + +/** + * Get the scale of a FreeType font. + * + * @param font The FreeType font to get the scale of. + * @return The scale of the FreeType font. + */ +uint32_t lv_freetype_outline_get_scale(const lv_font_t * font); + +/** + * Check if the font is an outline font. + * + * @param font The FreeType font. + * @return Is outline font on success, otherwise false. + */ +bool lv_freetype_is_outline_font(const lv_font_t * font); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_FREETYPE*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_FREETYPE_H */ diff --git a/test/include/liblvgl/libs/freetype/lv_freetype_private.h b/test/include/liblvgl/libs/freetype/lv_freetype_private.h new file mode 100644 index 00000000..86c87025 --- /dev/null +++ b/test/include/liblvgl/libs/freetype/lv_freetype_private.h @@ -0,0 +1,151 @@ +/** + * @file lv_freetype_private.h + * + */ + +#ifndef LV_FREETYPE_PRIVATE_H +#define LV_FREETYPE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_freetype.h" +#include "../../misc/cache/lv_cache.h" +#include "../../misc/lv_ll.h" +#include "../../font/lv_font.h" + +#if LV_USE_FREETYPE + +#include "ft2build.h" +#include FT_FREETYPE_H +#include FT_GLYPH_H +#include FT_CACHE_H +#include FT_SIZES_H +#include FT_IMAGE_H +#include FT_OUTLINE_H + +/********************* + * DEFINES + *********************/ + +#ifdef FT_CONFIG_OPTION_ERROR_STRINGS +#define FT_ERROR_MSG(msg, error_code) \ + LV_LOG_ERROR(msg " error(0x%x): %s", (int)error_code, FT_Error_String(error_code)) +#else +#define FT_ERROR_MSG(msg, error_code) \ + LV_LOG_ERROR(msg " error(0x%x)", (int)error_code) +#endif + +#define LV_FREETYPE_FONT_DSC_MAGIC_NUM 0x5F5F4654 /* '__FT' */ +#define LV_FREETYPE_FONT_DSC_HAS_MAGIC_NUM(dsc) ((dsc)->magic_num == LV_FREETYPE_FONT_DSC_MAGIC_NUM) +#define LV_ASSERT_FREETYPE_FONT_DSC(dsc) \ + do { \ + LV_ASSERT_NULL(dsc); \ + LV_ASSERT_FORMAT_MSG(LV_FREETYPE_FONT_DSC_HAS_MAGIC_NUM(dsc), \ + "Invalid font descriptor: 0x%" LV_PRIx32, (dsc)->magic_num); \ + } while (0) + +#define FT_INT_TO_F26DOT6(x) ((x) << 6) +#define FT_F26DOT6_TO_INT(x) ((x) >> 6) + +#define FT_INT_TO_F16DOT16(x) ((x) << 16) +#define FT_F16DOT16_TO_INT(x) ((x) >> 16) + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_freetype_outline_vector_t { + int32_t x; + int32_t y; +}; + +struct _lv_freetype_outline_event_param_t { + lv_freetype_outline_t outline; + lv_freetype_outline_type_t type; + lv_freetype_outline_vector_t to; + lv_freetype_outline_vector_t control1; + lv_freetype_outline_vector_t control2; +}; + + +typedef struct _lv_freetype_cache_node_t lv_freetype_cache_node_t; + +struct _lv_freetype_cache_node_t { + const char * pathname; + lv_freetype_font_style_t style; + lv_freetype_font_render_mode_t render_mode; + + uint32_t ref_size; /**< Reference size for calculating outline glyph's real size.*/ + + FT_Face face; + lv_mutex_t face_lock; + + /*glyph cache*/ + lv_cache_t * glyph_cache; + + /*draw data cache*/ + lv_cache_t * draw_data_cache; +}; + +typedef struct _lv_freetype_context_t { + FT_Library library; + lv_ll_t face_id_ll; + lv_event_cb_t event_cb; + + uint32_t max_glyph_cnt; + + lv_cache_t * cache_node_cache; +} lv_freetype_context_t; + +typedef struct _lv_freetype_font_dsc_t { + uint32_t magic_num; + lv_font_t font; + uint32_t size; + lv_freetype_font_style_t style; + lv_freetype_font_render_mode_t render_mode; + lv_freetype_context_t * context; + lv_freetype_cache_node_t * cache_node; + lv_cache_entry_t * cache_node_entry; + FTC_FaceID face_id; +} lv_freetype_font_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the FreeType context. + * + * @return A pointer to the FreeType context used by LittlevGL. + */ +lv_freetype_context_t * lv_freetype_get_context(void); + +void lv_freetype_italic_transform(FT_Face face); +int32_t lv_freetype_italic_transform_on_pos(lv_point_t point); + +lv_cache_t * lv_freetype_create_glyph_cache(uint32_t cache_size); +void lv_freetype_set_cbs_glyph(lv_freetype_font_dsc_t * dsc); + +lv_cache_t * lv_freetype_create_draw_data_image(uint32_t cache_size); +void lv_freetype_set_cbs_image_font(lv_freetype_font_dsc_t * dsc); + +lv_cache_t * lv_freetype_create_draw_data_outline(uint32_t cache_size); +void lv_freetype_set_cbs_outline_font(lv_freetype_font_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_FREETYPE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FREETYPE_PRIVATE_H*/ diff --git a/test/include/liblvgl/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp b/test/include/liblvgl/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp new file mode 100644 index 00000000..ca80d902 --- /dev/null +++ b/test/include/liblvgl/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp @@ -0,0 +1,201 @@ +#include "liblvgl/lvgl.h" +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + +#include "../../core/lv_global.h" +#include "LittleFS.h" + +#if LV_FS_ARDUINO_ESP_LITTLEFS_LETTER == '\0' + #error "LV_FS_ARDUINO_ESP_LITTLEFS_LETTER must be set to a valid value" +#else + #if (LV_FS_ARDUINO_ESP_LITTLEFS_LETTER < 'A') || (LV_FS_ARDUINO_ESP_LITTLEFS_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + #error "LV_FS_ARDUINO_ESP_LITTLEFS_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_ARDUINO_ESP_LITTLEFS_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism + #endif + #endif +#endif + +typedef struct ArduinoEspLittleFile { + File file; +} ArduinoEspLittleFile; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void fs_init(void); +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode); +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p); +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); +static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); + +/** + * Register a driver for the LittleFS File System interface + */ +extern "C" void lv_fs_arduino_esp_littlefs_init(void) +{ + fs_init(); + + lv_fs_drv_t * fs_drv = &(LV_GLOBAL_DEFAULT()->arduino_esp_littlefs_fs_drv); + lv_fs_drv_init(fs_drv); + + fs_drv->letter = LV_FS_ARDUINO_ESP_LITTLEFS_LETTER; + fs_drv->open_cb = fs_open; + fs_drv->close_cb = fs_close; + fs_drv->read_cb = fs_read; + fs_drv->write_cb = fs_write; + fs_drv->seek_cb = fs_seek; + fs_drv->tell_cb = fs_tell; + + fs_drv->dir_close_cb = NULL; + fs_drv->dir_open_cb = NULL; + fs_drv->dir_read_cb = NULL; + + lv_fs_drv_register(fs_drv); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/*Initialize your Storage device and File system.*/ +static void fs_init(void) +{ + LittleFS.begin(); +} + +/** + * Open a file + * @param drv pointer to a driver where this function belongs + * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt) + * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR + * @return a file descriptor or NULL on error + */ +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) +{ + LV_UNUSED(drv); + + const char * flags; + if(mode == LV_FS_MODE_WR) + flags = FILE_WRITE; + else if(mode == LV_FS_MODE_RD) + flags = FILE_READ; + else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) + flags = FILE_WRITE; + + File file = LittleFS.open(path, flags); + if(!file) { + return NULL; + } + + ArduinoEspLittleFile * lf = new ArduinoEspLittleFile{file}; + + return (void *)lf; +} + +/** + * Close an opened file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. (opened with fs_open) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + lf->file.close(); + delete lf; + + return LV_FS_RES_OK; +} + +/** + * Read data from an opened file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. + * @param buf pointer to a memory block where to store the read data + * @param btr number of Bytes To Read + * @param br the real number of read bytes (Byte Read) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + *br = lf->file.read((uint8_t *)buf, btr); + + return (int32_t)(*br) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Write into a file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable + * @param buf pointer to a buffer with the bytes to write + * @param btw Bytes To Write + * @param bw the number of real written bytes (Bytes Written) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + *bw = lf->file.write((uint8_t *)buf, btw); + + return (int32_t)(*bw) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Set the read write pointer. Also expand the file size if necessary. + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. (opened with fs_open ) + * @param pos the new position of read write pointer + * @param whence tells from where to interpret the `pos`. See @lv_fs_whence_t + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence) +{ + LV_UNUSED(drv); + SeekMode mode; + if(whence == LV_FS_SEEK_SET) + mode = SeekSet; + else if(whence == LV_FS_SEEK_CUR) + mode = SeekCur; + else if(whence == LV_FS_SEEK_END) + mode = SeekEnd; + + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + + int rc = lf->file.seek(pos, mode); + + return rc < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Give the position of the read write pointer + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_p variable + * @param pos_p pointer to store the result + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + + *pos_p = lf->file.position(); + + return (int32_t)(*pos_p) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +#else /*LV_USE_FS_ARDUINO_ESP_LITTLEFS == 0*/ + +#if defined(LV_FS_ARDUINO_ESP_LITTLEFS_LETTER) && LV_FS_ARDUINO_ESP_LITTLEFS_LETTER != '\0' + #warning "LV_USE_FS_ARDUINO_ESP_LITTLEFS is not enabled but LV_FS_ARDUINO_ESP_LITTLEFS_LETTER is set" +#endif + +#endif /*LV_USE_FS_ARDUINO_ESP_LITTLEFS*/ + diff --git a/test/include/liblvgl/libs/fsdrv/lv_fs_arduino_sd.cpp b/test/include/liblvgl/libs/fsdrv/lv_fs_arduino_sd.cpp new file mode 100644 index 00000000..88974d6f --- /dev/null +++ b/test/include/liblvgl/libs/fsdrv/lv_fs_arduino_sd.cpp @@ -0,0 +1,192 @@ +#include "liblvgl/lvgl.h" +#if LV_USE_FS_ARDUINO_SD + +#include "../../core/lv_global.h" +#include +#include "SD.h" + +#if LV_FS_ARDUINO_SD_LETTER == '\0' + #error "LV_FS_ARDUINO_SD_LETTER must be set to a valid value" +#else + #if (LV_FS_ARDUINO_SD_LETTER < 'A') || (LV_FS_ARDUINO_SD_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + #error "LV_FS_ARDUINO_SD_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_ARDUINO_SD_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism + #endif + #endif +#endif + +typedef struct SdFile { + File file; +} SdFile; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode); +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p); +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); +static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); + +/** + * Register a driver for the SD File System interface + */ +extern "C" void lv_fs_arduino_sd_init(void) +{ + lv_fs_drv_t * fs_drv = &(LV_GLOBAL_DEFAULT()->arduino_sd_fs_drv); + lv_fs_drv_init(fs_drv); + + fs_drv->letter = LV_FS_ARDUINO_SD_LETTER; + fs_drv->open_cb = fs_open; + fs_drv->close_cb = fs_close; + fs_drv->read_cb = fs_read; + fs_drv->write_cb = fs_write; + fs_drv->seek_cb = fs_seek; + fs_drv->tell_cb = fs_tell; + + fs_drv->dir_close_cb = NULL; + fs_drv->dir_open_cb = NULL; + fs_drv->dir_read_cb = NULL; + + lv_fs_drv_register(fs_drv); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Open a file + * @param drv pointer to a driver where this function belongs + * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt) + * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR + * @return a file descriptor or NULL on error + */ +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) +{ + LV_UNUSED(drv); + + const char * flags; + if(mode == LV_FS_MODE_WR) + flags = FILE_WRITE; + else if(mode == LV_FS_MODE_RD) + flags = FILE_READ; + else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) + flags = FILE_WRITE; + + File file = SD.open(path, flags); + if(!file) { + return NULL; + } + + SdFile * lf = new SdFile{file}; + + return (void *)lf; +} + +/** + * Close an opened file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. (opened with fs_open) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) +{ + LV_UNUSED(drv); + SdFile * lf = (SdFile *)file_p; + lf->file.close(); + delete lf; + + return LV_FS_RES_OK; +} + +/** + * Read data from an opened file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. + * @param buf pointer to a memory block where to store the read data + * @param btr number of Bytes To Read + * @param br the real number of read bytes (Byte Read) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) +{ + LV_UNUSED(drv); + SdFile * lf = (SdFile *)file_p; + *br = lf->file.read((uint8_t *)buf, btr); + + return (int32_t)(*br) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Write into a file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable + * @param buf pointer to a buffer with the bytes to write + * @param btw Bytes To Write + * @param bw the number of real written bytes (Bytes Written) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw) +{ + LV_UNUSED(drv); + SdFile * lf = (SdFile *)file_p; + *bw = lf->file.write((uint8_t *)buf, btw); + + return (int32_t)(*bw) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Set the read write pointer. Also expand the file size if necessary. + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. (opened with fs_open ) + * @param pos the new position of read write pointer + * @param whence tells from where to interpret the `pos`. See @lv_fs_whence_t + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence) +{ + LV_UNUSED(drv); + SeekMode mode; + if(whence == LV_FS_SEEK_SET) + mode = SeekSet; + else if(whence == LV_FS_SEEK_CUR) + mode = SeekCur; + else if(whence == LV_FS_SEEK_END) + mode = SeekEnd; + + SdFile * lf = (SdFile *)file_p; + + int rc = lf->file.seek(pos, mode); + + return rc < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Give the position of the read write pointer + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_p variable + * @param pos_p pointer to store the result + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) +{ + LV_UNUSED(drv); + SdFile * lf = (SdFile *)file_p; + + *pos_p = lf->file.position(); + + return (int32_t)(*pos_p) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +#else /*LV_USE_FS_ARDUINO_SD == 0*/ + +#if defined(LV_FS_ARDUINO_SD_LETTER) && LV_FS_ARDUINO_SD_LETTER != '\0' + #warning "LV_USE_FS_ARDUINO_SD is not enabled but LV_FS_ARDUINO_SD_LETTER is set" +#endif + +#endif /*LV_USE_FS_ARDUINO_SD*/ diff --git a/test/include/liblvgl/libs/fsdrv/lv_fsdrv.h b/test/include/liblvgl/libs/fsdrv/lv_fsdrv.h new file mode 100644 index 00000000..f830c3a2 --- /dev/null +++ b/test/include/liblvgl/libs/fsdrv/lv_fsdrv.h @@ -0,0 +1,72 @@ +/** + * @file lv_fsdrv.h + * + */ + +#ifndef LV_FSDRV_H +#define LV_FSDRV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +#if LV_USE_FS_FATFS +void lv_fs_fatfs_init(void); +#endif + +#if LV_USE_FS_STDIO +void lv_fs_stdio_init(void); +#endif + +#if LV_USE_FS_POSIX +void lv_fs_posix_init(void); +#endif + +#if LV_USE_FS_WIN32 +void lv_fs_win32_init(void); +#endif + +#if LV_USE_FS_MEMFS +void lv_fs_memfs_init(void); +#endif + +#if LV_USE_FS_LITTLEFS +struct lfs; +void lv_littlefs_set_handler(struct lfs *); +void lv_fs_littlefs_init(void); +#endif + +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS +void lv_fs_arduino_esp_littlefs_init(void); +#endif + +#if LV_USE_FS_ARDUINO_SD +void lv_fs_arduino_sd_init(void); +#endif + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_FSDRV_H*/ diff --git a/test/include/liblvgl/libs/gif/gifdec.h b/test/include/liblvgl/libs/gif/gifdec.h new file mode 100644 index 00000000..21ff210a --- /dev/null +++ b/test/include/liblvgl/libs/gif/gifdec.h @@ -0,0 +1,71 @@ +#ifndef GIFDEC_H +#define GIFDEC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../misc/lv_fs.h" + +#if LV_USE_GIF +#include + +typedef struct _gd_Palette { + int size; + uint8_t colors[0x100 * 3]; +} gd_Palette; + +typedef struct _gd_GCE { + uint16_t delay; + uint8_t tindex; + uint8_t disposal; + int input; + int transparency; +} gd_GCE; + + + +typedef struct _gd_GIF { + lv_fs_file_t fd; + const char * data; + uint8_t is_file; + uint32_t f_rw_p; + int32_t anim_start; + uint16_t width, height; + uint16_t depth; + int32_t loop_count; + gd_GCE gce; + gd_Palette * palette; + gd_Palette lct, gct; + void (*plain_text)( + struct _gd_GIF * gif, uint16_t tx, uint16_t ty, + uint16_t tw, uint16_t th, uint8_t cw, uint8_t ch, + uint8_t fg, uint8_t bg + ); + void (*comment)(struct _gd_GIF * gif); + void (*application)(struct _gd_GIF * gif, char id[8], char auth[3]); + uint16_t fx, fy, fw, fh; + uint8_t bgindex; + uint8_t * canvas, * frame; + #if LV_GIF_CACHE_DECODE_DATA + uint8_t *lzw_cache; + #endif +} gd_GIF; + +gd_GIF * gd_open_gif_file(const char * fname); + +gd_GIF * gd_open_gif_data(const void * data); + +void gd_render_frame(gd_GIF * gif, uint8_t * buffer); + +int gd_get_frame(gd_GIF * gif); +void gd_rewind(gd_GIF * gif); +void gd_close_gif(gd_GIF * gif); + +#endif /*LV_USE_GIF*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* GIFDEC_H */ diff --git a/test/include/liblvgl/libs/gif/gifdec_mve.h b/test/include/liblvgl/libs/gif/gifdec_mve.h new file mode 100644 index 00000000..6d833934 --- /dev/null +++ b/test/include/liblvgl/libs/gif/gifdec_mve.h @@ -0,0 +1,140 @@ +/** + * @file gifdec_mve.h + * + */ + +#ifndef GIFDEC_MVE_H +#define GIFDEC_MVE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include +#include "../../misc/lv_color.h" + +/********************* + * DEFINES + *********************/ + +#define GIFDEC_FILL_BG(dst, w, h, stride, color, opa) \ + _gifdec_fill_bg_mve(dst, w, h, stride, color, opa) + +#define GIFDEC_RENDER_FRAME(dst, w, h, stride, frame, pattern, tindex) \ + _gifdec_render_frame_mve(dst, w, h, stride, frame, pattern, tindex) + +/********************** + * MACROS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +static inline void _gifdec_fill_bg_mve(uint8_t * dst, uint16_t w, uint16_t h, uint16_t stride, uint8_t * color, + uint8_t opa) +{ + lv_color32_t c = lv_color32_make(*(color + 0), *(color + 1), *(color + 2), opa); + uint32_t color_32 = *(uint32_t *)&c; + + __asm volatile( + ".p2align 2 \n" + "vdup.32 q0, %[src] \n" + "3: \n" + "mov r0, %[dst] \n" + + "wlstp.32 lr, %[w], 1f \n" + "2: \n" + + "vstrw.32 q0, [r0], #16 \n" + "letp lr, 2b \n" + "1: \n" + "add %[dst], %[iTargetStride] \n" + "subs %[h], #1 \n" + "bne 3b \n" + : [dst] "+r"(dst), + [h] "+r"(h) + : [src] "r"(color_32), + [w] "r"(w), + [iTargetStride] "r"(stride * sizeof(uint32_t)) + : "r0", "q0", "memory", "r14", "cc"); +} + +static inline void _gifdec_render_frame_mve(uint8_t * dst, uint16_t w, uint16_t h, uint16_t stride, uint8_t * frame, + uint8_t * pattern, uint16_t tindex) +{ + if(w == 0 || h == 0) { + return; + } + + __asm volatile( + "vmov.u16 q3, #255 \n" + "vshl.u16 q3, q3, #8 \n" /* left shift 8 for a*/ + + "mov r0, #2 \n" + "vidup.u16 q6, r0, #4 \n" /* [2, 6, 10, 14, 18, 22, 26, 30] */ + "mov r0, #0 \n" + "vidup.u16 q7, r0, #4 \n" /* [0, 4, 8, 12, 16, 20, 24, 28] */ + + "3: \n" + "mov r1, %[dst] \n" + "mov r2, %[frame] \n" + + "wlstp.16 lr, %[w], 1f \n" + "2: \n" + + "mov r0, #3 \n" + "vldrb.u16 q4, [r2], #8 \n" + "vmul.u16 q5, q4, r0 \n" + + "mov r0, #1 \n" + "vldrb.u16 q2, [%[pattern], q5] \n" /* load 8 pixel r*/ + + "vadd.u16 q5, q5, r0 \n" + "vldrb.u16 q1, [%[pattern], q5] \n" /* load 8 pixel g*/ + + "vadd.u16 q5, q5, r0 \n" + "vldrb.u16 q0, [%[pattern], q5] \n" /* load 8 pixel b*/ + + "vshl.u16 q1, q1, #8 \n" /* left shift 8 for g*/ + + "vorr.u16 q0, q0, q1 \n" /* make 8 pixel gb*/ + "vorr.u16 q1, q2, q3 \n" /* make 8 pixel ar*/ + + "vcmp.i16 ne, q4, %[tindex] \n" + "vpstt \n" + "vstrht.16 q0, [r1, q7] \n" + "vstrht.16 q1, [r1, q6] \n" + "add r1, r1, #32 \n" + + "letp lr, 2b \n" + + "1: \n" + "mov r0, %[stride], LSL #2 \n" + "add %[dst], r0 \n" + "add %[frame], %[stride] \n" + "subs %[h], #1 \n" + "bne 3b \n" + + : [dst] "+r"(dst), + [frame] "+r"(frame), + [h] "+r"(h) + : [pattern] "r"(pattern), + [w] "r"(w), + [stride] "r"(stride), + [tindex] "r"(tindex) + : "r0", "r1", "r2", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "memory", "r14", "cc"); +} + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*GIFDEC_MVE_H*/ diff --git a/test/include/liblvgl/libs/gif/lv_gif.h b/test/include/liblvgl/libs/gif/lv_gif.h new file mode 100644 index 00000000..cf1bee47 --- /dev/null +++ b/test/include/liblvgl/libs/gif/lv_gif.h @@ -0,0 +1,104 @@ +/** + * @file lv_gif.h + * + */ + +#ifndef LV_GIF_H +#define LV_GIF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#include "../../misc/lv_types.h" +#include "../../draw/lv_draw_buf.h" +#include "../../widgets/image/lv_image.h" +#include "../../core/lv_obj_class.h" +#include LV_STDBOOL_INCLUDE +#include LV_STDINT_INCLUDE +#if LV_USE_GIF + +#include "gifdec.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_gif_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a gif object + * @param parent pointer to an object, it will be the parent of the new gif. + * @return pointer to the gif obj + */ +lv_obj_t * lv_gif_create(lv_obj_t * parent); + +/** + * Set the gif data to display on the object + * @param obj pointer to a gif object + * @param src 1) pointer to an ::lv_image_dsc_t descriptor (which contains gif raw data) or + * 2) path to a gif file (e.g. "S:/dir/anim.gif") + */ +void lv_gif_set_src(lv_obj_t * obj, const void * src); + +/** + * Restart a gif animation. + * @param obj pointer to a gif obj + */ +void lv_gif_restart(lv_obj_t * obj); + +/** + * Pause a gif animation. + * @param obj pointer to a gif obj + */ +void lv_gif_pause(lv_obj_t * obj); + +/** + * Resume a gif animation. + * @param obj pointer to a gif obj + */ +void lv_gif_resume(lv_obj_t * obj); + +/** + * Checks if the GIF was loaded correctly. + * @param obj pointer to a gif obj + */ +bool lv_gif_is_loaded(lv_obj_t * obj); + +/** + * Get the loop count for the GIF. + * @param obj pointer to a gif obj + */ +int32_t lv_gif_get_loop_count(lv_obj_t * obj); + +/** + * Set the loop count for the GIF. + * @param obj pointer to a gif obj + * @param count the loop count to set + */ +void lv_gif_set_loop_count(lv_obj_t * obj, int32_t count); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_GIF*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_GIF_H*/ diff --git a/test/include/liblvgl/libs/gif/lv_gif_private.h b/test/include/liblvgl/libs/gif/lv_gif_private.h new file mode 100644 index 00000000..c88507f1 --- /dev/null +++ b/test/include/liblvgl/libs/gif/lv_gif_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_gif_private.h + * + */ + +#ifndef LV_GIF_PRIVATE_H +#define LV_GIF_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../widgets/image/lv_image_private.h" +#include "lv_gif.h" + +#if LV_USE_GIF + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_gif_t { + lv_image_t img; + gd_GIF * gif; + lv_timer_t * timer; + lv_image_dsc_t imgdsc; + uint32_t last_call; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_GIF */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GIF_PRIVATE_H*/ diff --git a/test/include/liblvgl/libs/libjpeg_turbo/lv_libjpeg_turbo.h b/test/include/liblvgl/libs/libjpeg_turbo/lv_libjpeg_turbo.h new file mode 100644 index 00000000..177c83a6 --- /dev/null +++ b/test/include/liblvgl/libs/libjpeg_turbo/lv_libjpeg_turbo.h @@ -0,0 +1,48 @@ +/** + * @file lv_libjpeg_turbo.h + * + */ + +#ifndef LV_LIBJPEG_TURBO_H +#define LV_LIBJPEG_TURBO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_LIBJPEG_TURBO + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Register the JPEG-Turbo decoder functions in LVGL + */ +void lv_libjpeg_turbo_init(void); + +void lv_libjpeg_turbo_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_LIBJPEG_TURBO*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_LIBJPEG_TURBO_H*/ diff --git a/test/include/liblvgl/libs/libpng/lv_libpng.h b/test/include/liblvgl/libs/libpng/lv_libpng.h new file mode 100644 index 00000000..12794585 --- /dev/null +++ b/test/include/liblvgl/libs/libpng/lv_libpng.h @@ -0,0 +1,48 @@ +/** + * @file lv_libpng.h + * + */ + +#ifndef LV_LIBPNG_H +#define LV_LIBPNG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_LIBPNG + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Register the PNG decoder functions in LVGL + */ +void lv_libpng_init(void); + +void lv_libpng_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_LIBPNG*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_LIBPNG_H*/ diff --git a/test/include/liblvgl/libs/lodepng/lodepng.h b/test/include/liblvgl/libs/lodepng/lodepng.h new file mode 100644 index 00000000..624eb269 --- /dev/null +++ b/test/include/liblvgl/libs/lodepng/lodepng.h @@ -0,0 +1,2105 @@ +/* +LodePNG version 20230410 + +Copyright (c) 2005-2023 Lode Vandevenne + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#ifndef LODEPNG_H +#define LODEPNG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "liblvgl/lvgl.h" +#if LV_USE_LODEPNG +#include LV_STDDEF_INCLUDE /*for size_t*/ +LV_ATTRIBUTE_EXTERN_DATA extern const char * LODEPNG_VERSION_STRING; + +/* +The following #defines are used to create code sections. They can be disabled +to disable code sections, which can give faster compile time and smaller binary. +The "NO_COMPILE" defines are designed to be used to pass as defines to the +compiler command to disable them without modifying this header, e.g. +-DLODEPNG_NO_COMPILE_ZLIB for gcc or clang. +*/ +/*deflate & zlib. If disabled, you must specify alternative zlib functions in +the custom_zlib field of the compress and decompress settings*/ +#ifndef LODEPNG_NO_COMPILE_ZLIB + /*pass -DLODEPNG_NO_COMPILE_ZLIB to the compiler to disable this, or comment out LODEPNG_COMPILE_ZLIB below*/ + #define LODEPNG_COMPILE_ZLIB +#endif + +/*png encoder and png decoder*/ +#ifndef LODEPNG_NO_COMPILE_PNG + /*pass -DLODEPNG_NO_COMPILE_PNG to the compiler to disable this, or comment out LODEPNG_COMPILE_PNG below*/ + #define LODEPNG_COMPILE_PNG +#endif + +/*deflate&zlib decoder and png decoder*/ +#ifndef LODEPNG_NO_COMPILE_DECODER + /*pass -DLODEPNG_NO_COMPILE_DECODER to the compiler to disable this, or comment out LODEPNG_COMPILE_DECODER below*/ + #define LODEPNG_COMPILE_DECODER +#endif + +/*deflate&zlib encoder and png encoder*/ +#ifndef LODEPNG_NO_COMPILE_ENCODER + /*pass -DLODEPNG_NO_COMPILE_ENCODER to the compiler to disable this, or comment out LODEPNG_COMPILE_ENCODER below*/ + #define LODEPNG_COMPILE_ENCODER +#endif + +/*the optional built in harddisk file loading and saving functions*/ +#ifndef LODEPNG_NO_COMPILE_DISK + /*pass -DLODEPNG_NO_COMPILE_DISK to the compiler to disable this, or comment out LODEPNG_COMPILE_DISK below*/ + #define LODEPNG_COMPILE_DISK +#endif + +/*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ +#ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS + /*pass -DLODEPNG_NO_COMPILE_ANCILLARY_CHUNKS to the compiler to disable this, + or comment out LODEPNG_COMPILE_ANCILLARY_CHUNKS below*/ + #define LODEPNG_COMPILE_ANCILLARY_CHUNKS +#endif + +/*ability to convert error numerical codes to English text string*/ +#ifndef LODEPNG_NO_COMPILE_ERROR_TEXT + /*pass -DLODEPNG_NO_COMPILE_ERROR_TEXT to the compiler to disable this, + or comment out LODEPNG_COMPILE_ERROR_TEXT below*/ + #define LODEPNG_COMPILE_ERROR_TEXT +#endif + +/*Compile the default allocators (C's free, malloc and realloc). If you disable this, +you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your +source files with custom allocators.*/ +#ifndef LODEPNG_NO_COMPILE_ALLOCATORS + /*pass -DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler to disable the built-in ones, + or comment out LODEPNG_COMPILE_ALLOCATORS below*/ + #define LODEPNG_COMPILE_ALLOCATORS +#endif + +/*Disable built-in CRC function, in that case a custom implementation of +lodepng_crc32 must be defined externally so that it can be linked in. +The default built-in CRC code comes with 8KB of lookup tables, so for memory constrained environment you may want it +disabled and provide a much smaller implementation externally as said above. You can find such an example implementation +in a comment in the lodepng.c(pp) file in the 'else' case of the searchable LODEPNG_COMPILE_CRC section.*/ +#ifndef LODEPNG_NO_COMPILE_CRC + /*pass -DLODEPNG_NO_COMPILE_CRC to the compiler to disable the built-in one, + or comment out LODEPNG_COMPILE_CRC below*/ + #define LODEPNG_COMPILE_CRC +#endif + +/*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/ +#ifdef __cplusplus + #ifndef LODEPNG_NO_COMPILE_CPP + /*pass -DLODEPNG_NO_COMPILE_CPP to the compiler to disable C++ (not needed if a C-only compiler), + or comment out LODEPNG_COMPILE_CPP below*/ + #define LODEPNG_COMPILE_CPP + #endif +#endif + +#ifdef LODEPNG_COMPILE_CPP + #include + #include +#endif /*LODEPNG_COMPILE_CPP*/ + +#ifdef LODEPNG_COMPILE_PNG +/*The PNG color types (also used for raw image).*/ +typedef enum LodePNGColorType { + LCT_GREY = 0, /*grayscale: 1,2,4,8,16 bit*/ + LCT_RGB = 2, /*RGB: 8,16 bit*/ + LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ + LCT_GREY_ALPHA = 4, /*grayscale with alpha: 8,16 bit*/ + LCT_RGBA = 6, /*RGB with alpha: 8,16 bit*/ + /*LCT_MAX_OCTET_VALUE lets the compiler allow this enum to represent any invalid + byte value from 0 to 255 that could be present in an invalid PNG file header. Do + not use, compare with or set the name LCT_MAX_OCTET_VALUE, instead either use + the valid color type names above, or numeric values like 1 or 7 when checking for + particular disallowed color type byte values, or cast to integer to print it.*/ + LCT_MAX_OCTET_VALUE = 255 +} LodePNGColorType; + +#ifdef LODEPNG_COMPILE_DECODER +/* +Converts PNG data in memory to raw pixel data. +out: Output parameter. Pointer to buffer that will contain the raw pixel data. + After decoding, its size is w * h * (bytes per pixel) bytes larger than + initially. Bytes per pixel depends on colortype and bitdepth. + Must be freed after usage with free(*out). + Note: for 16-bit per channel colors, uses big endian format like PNG does. +w: Output parameter. Pointer to width of pixel data. +h: Output parameter. Pointer to height of pixel data. +in: Memory buffer with the PNG file. +insize: size of the in buffer. +colortype: the desired color type for the raw output image. See explanation on PNG color types. +bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types. +Return value: LodePNG error code (0 means no error). +*/ +unsigned lodepng_decode_memory(unsigned char ** out, unsigned * w, unsigned * h, + const unsigned char * in, size_t insize, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/ +unsigned lodepng_decode32(unsigned char ** out, unsigned * w, unsigned * h, + const unsigned char * in, size_t insize); + +/*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/ +unsigned lodepng_decode24(unsigned char ** out, unsigned * w, unsigned * h, + const unsigned char * in, size_t insize); + +#ifdef LODEPNG_COMPILE_DISK +/* +Load PNG from disk, from file with given name. +Same as the other decode functions, but instead takes a filename as input. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory.*/ +unsigned lodepng_decode_file(unsigned char ** out, unsigned * w, unsigned * h, + const char * filename, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory.*/ +unsigned lodepng_decode32_file(unsigned char ** out, unsigned * w, unsigned * h, + const char * filename); + +/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory.*/ +unsigned lodepng_decode24_file(unsigned char ** out, unsigned * w, unsigned * h, + const char * filename); +#endif /*LODEPNG_COMPILE_DISK*/ +#endif /*LODEPNG_COMPILE_DECODER*/ + + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Converts raw pixel data into a PNG image in memory. The colortype and bitdepth + of the output PNG image cannot be chosen, they are automatically determined + by the colortype, bitdepth and content of the input pixel data. + Note: for 16-bit per channel colors, needs big endian format like PNG does. +out: Output parameter. Pointer to buffer that will contain the PNG image data. + Must be freed after usage with free(*out). +outsize: Output parameter. Pointer to the size in bytes of the out buffer. +image: The raw pixel data to encode. The size of this buffer should be + w * h * (bytes per pixel), bytes per pixel depends on colortype and bitdepth. +w: width of the raw pixel data in pixels. +h: height of the raw pixel data in pixels. +colortype: the color type of the raw input image. See explanation on PNG color types. +bitdepth: the bit depth of the raw input image. See explanation on PNG color types. +Return value: LodePNG error code (0 means no error). +*/ +unsigned lodepng_encode_memory(unsigned char ** out, size_t * outsize, + const unsigned char * image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/ +unsigned lodepng_encode32(unsigned char ** out, size_t * outsize, + const unsigned char * image, unsigned w, unsigned h); + +/*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/ +unsigned lodepng_encode24(unsigned char ** out, size_t * outsize, + const unsigned char * image, unsigned w, unsigned h); + +#ifdef LODEPNG_COMPILE_DISK +/* +Converts raw pixel data into a PNG file on disk. +Same as the other encode functions, but instead takes a filename as output. + +NOTE: This overwrites existing files without warning! + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory.*/ +unsigned lodepng_encode_file(const char * filename, + const unsigned char * image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory.*/ +unsigned lodepng_encode32_file(const char * filename, + const unsigned char * image, unsigned w, unsigned h); + +/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory.*/ +unsigned lodepng_encode24_file(const char * filename, + const unsigned char * image, unsigned w, unsigned h); +#endif /*LODEPNG_COMPILE_DISK*/ +#endif /*LODEPNG_COMPILE_ENCODER*/ + + +#ifdef LODEPNG_COMPILE_CPP +namespace lodepng +{ +#ifdef LODEPNG_COMPILE_DECODER +/*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype +is the format to output the pixels to. Default is RGBA 8-bit per channel.*/ +unsigned decode(std::vector & out, unsigned & w, unsigned & h, + const unsigned char * in, size_t insize, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned decode(std::vector & out, unsigned & w, unsigned & h, + const std::vector & in, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#ifdef LODEPNG_COMPILE_DISK +/* +Converts PNG file from disk to raw pixel data in memory. +Same as the other decode functions, but instead takes a filename as input. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory. +*/ +unsigned decode(std::vector & out, unsigned & w, unsigned & h, + const std::string & filename, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +/*Same as lodepng_encode_memory, but encodes to an std::vector. colortype +is that of the raw input data. The output PNG color type will be auto chosen.*/ +unsigned encode(std::vector & out, + const unsigned char * in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned encode(std::vector & out, + const std::vector & in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#ifdef LODEPNG_COMPILE_DISK +/* +Converts 32-bit RGBA raw pixel data into a PNG file on disk. +Same as the other encode functions, but instead takes a filename as output. + +NOTE: This overwrites existing files without warning! + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory. +*/ +unsigned encode(const std::string & filename, + const unsigned char * in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned encode(const std::string & filename, + const std::vector & in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ERROR_TEXT + /*Returns an English description of the numerical error code.*/ + const char * lodepng_error_text(unsigned code); +#endif /*LODEPNG_COMPILE_ERROR_TEXT*/ + +#ifdef LODEPNG_COMPILE_DECODER +/*Settings for zlib decompression*/ +typedef struct LodePNGDecompressSettings LodePNGDecompressSettings; +struct LodePNGDecompressSettings { + /* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */ + unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ + unsigned ignore_nlen; /*ignore complement of len checksum in uncompressed blocks*/ + + /*Maximum decompressed size, beyond this the decoder may (and is encouraged to) stop decoding, + return an error, output a data size > max_output_size and all the data up to that point. This is + neither a hard limit nor a guarantee, but can prevent excessive memory usage. This setting is + ignored by the PNG decoder, but is used by the deflate/zlib decoder and can be used by custom ones. + Set to 0 to impose no limit (the default).*/ + size_t max_output_size; + + /*use custom zlib decoder instead of built in one (default: null). + Should return 0 if success, any non-0 if error (numeric value not exposed).*/ + unsigned(*custom_zlib)(unsigned char **, size_t *, + const unsigned char *, size_t, + const LodePNGDecompressSettings *); + /*use custom deflate decoder instead of built in one (default: null) + if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate). + Should return 0 if success, any non-0 if error (numeric value not exposed).*/ + unsigned(*custom_inflate)(unsigned char **, size_t *, + const unsigned char *, size_t, + const LodePNGDecompressSettings *); + + const void * custom_context; /*optional custom settings for custom functions*/ +}; + +LV_ATTRIBUTE_EXTERN_DATA extern const LodePNGDecompressSettings lodepng_default_decompress_settings; +void lodepng_decompress_settings_init(LodePNGDecompressSettings * settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Settings for zlib compression. Tweaking these settings tweaks the balance +between speed and compression ratio. +*/ +typedef struct LodePNGCompressSettings LodePNGCompressSettings; +struct LodePNGCompressSettings { /*deflate = compress*/ + /*LZ77 related settings*/ + unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ + unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ + unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/ + unsigned minmatch; /*minimum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/ + unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/ + unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/ + + /*use custom zlib encoder instead of built in one (default: null)*/ + unsigned(*custom_zlib)(unsigned char **, size_t *, + const unsigned char *, size_t, + const LodePNGCompressSettings *); + /*use custom deflate encoder instead of built in one (default: null) + if custom_zlib is used, custom_deflate is ignored since only the built in + zlib function will call custom_deflate*/ + unsigned(*custom_deflate)(unsigned char **, size_t *, + const unsigned char *, size_t, + const LodePNGCompressSettings *); + + const void * custom_context; /*optional custom settings for custom functions*/ +}; + +LV_ATTRIBUTE_EXTERN_DATA extern const LodePNGCompressSettings lodepng_default_compress_settings; +void lodepng_compress_settings_init(LodePNGCompressSettings * settings); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_PNG +/* +Color mode of an image. Contains all information required to decode the pixel +bits to RGBA colors. This information is the same as used in the PNG file +format, and is used both for PNG and raw image data in LodePNG. +*/ +typedef struct LodePNGColorMode { + /*header (IHDR)*/ + LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ + unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ + + /* + palette (PLTE and tRNS) + + Dynamically allocated with the colors of the palette, including alpha. + This field may not be allocated directly, use lodepng_color_mode_init first, + then lodepng_palette_add per color to correctly initialize it (to ensure size + of exactly 1024 bytes). + + The alpha channels must be set as well, set them to 255 for opaque images. + + When decoding, with the default settings you can ignore this palette, since + LodePNG already fills the palette colors in the pixels of the raw RGBA output, + but when decoding to the original PNG color mode it is needed to reconstruct + the colors. + + The palette is only supported for color type 3. + */ + unsigned char * palette; /*palette in RGBARGBA... order. Must be either 0, or when allocated must have 1024 bytes*/ + size_t palettesize; /*palette size in number of colors (amount of used bytes is 4 * palettesize)*/ + + /* + transparent color key (tRNS) + + This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. + For grayscale PNGs, r, g and b will all 3 be set to the same. + + When decoding, by default you can ignore this information, since LodePNG sets + pixels with this key to transparent already in the raw RGBA output. + + The color key is only supported for color types 0 and 2. + */ + unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ + unsigned key_r; /*red/grayscale component of color key*/ + unsigned key_g; /*green component of color key*/ + unsigned key_b; /*blue component of color key*/ +} LodePNGColorMode; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_color_mode_init(LodePNGColorMode * info); +void lodepng_color_mode_cleanup(LodePNGColorMode * info); +/*return value is error code (0 means no error)*/ +unsigned lodepng_color_mode_copy(LodePNGColorMode * dest, const LodePNGColorMode * source); +/* Makes a temporary LodePNGColorMode that does not need cleanup (no palette) */ +LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth); + +void lodepng_palette_clear(LodePNGColorMode * info); +/*add 1 color to the palette*/ +unsigned lodepng_palette_add(LodePNGColorMode * info, + unsigned char r, unsigned char g, unsigned char b, unsigned char a); + +/*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/ +unsigned lodepng_get_bpp(const LodePNGColorMode * info); +/*get the amount of color channels used, based on colortype in the struct. +If a palette is used, it counts as 1 channel.*/ +unsigned lodepng_get_channels(const LodePNGColorMode * info); +/*is it a grayscale type? (only colortype 0 or 4)*/ +unsigned lodepng_is_greyscale_type(const LodePNGColorMode * info); +/*has it got an alpha channel? (only colortype 2 or 6)*/ +unsigned lodepng_is_alpha_type(const LodePNGColorMode * info); +/*has it got a palette? (only colortype 3)*/ +unsigned lodepng_is_palette_type(const LodePNGColorMode * info); +/*only returns true if there is a palette and there is a value in the palette with alpha < 255. +Loops through the palette to check this.*/ +unsigned lodepng_has_palette_alpha(const LodePNGColorMode * info); +/* +Check if the given color info indicates the possibility of having non-opaque pixels in the PNG image. +Returns true if the image can have translucent or invisible pixels (it still be opaque if it doesn't use such pixels). +Returns false if the image can only have opaque pixels. +In detail, it returns true only if it's a color type with alpha, or has a palette with non-opaque values, +or if "key_defined" is true. +*/ +unsigned lodepng_can_have_alpha(const LodePNGColorMode * info); +/*Returns the byte size of a raw image buffer with given width, height and color mode*/ +size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode * color); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +/*The information of a Time chunk in PNG.*/ +typedef struct LodePNGTime { + unsigned year; /*2 bytes used (0-65535)*/ + unsigned month; /*1-12*/ + unsigned day; /*1-31*/ + unsigned hour; /*0-23*/ + unsigned minute; /*0-59*/ + unsigned second; /*0-60 (to allow for leap seconds)*/ +} LodePNGTime; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +/*Information about the PNG image, except pixels, width and height.*/ +typedef struct LodePNGInfo { + /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ + unsigned compression_method;/*compression method of the original file. Always 0.*/ + unsigned filter_method; /*filter method of the original file*/ + unsigned interlace_method; /*interlace method of the original file: 0=none, 1=Adam7*/ + LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /* + Suggested background color chunk (bKGD) + + This uses the same color mode and bit depth as the PNG (except no alpha channel), + with values truncated to the bit depth in the unsigned integer. + + For grayscale and palette PNGs, the value is stored in background_r. The values + in background_g and background_b are then unused. The decoder will set them + equal to background_r, the encoder ignores them in this case. + + When decoding, you may get these in a different color mode than the one you requested + for the raw pixels: the colortype and bitdepth defined by info_png.color, that is the + ones defined in the header of the PNG image, are used. + + When encoding with auto_convert, you must use the color model defined in info_png.color for + these values. The encoder normally ignores info_png.color when auto_convert is on, but will + use it to interpret these values (and convert copies of them to its chosen color model). + + When encoding, avoid setting this to an expensive color, such as a non-gray value + when the image is gray, or the compression will be worse since it will be forced to + write the PNG with a more expensive color mode (when auto_convert is on). + + The decoder does not use this background color to edit the color of pixels. This is a + completely optional metadata feature. + */ + unsigned background_defined; /*is a suggested background color given?*/ + unsigned background_r; /*red/gray/palette component of suggested background color*/ + unsigned background_g; /*green component of suggested background color*/ + unsigned background_b; /*blue component of suggested background color*/ + + /* + Non-international text chunks (tEXt and zTXt) + + The char** arrays each contain num strings. The actual messages are in + text_strings, while text_keys are keywords that give a short description what + the actual text represents, e.g. Title, Author, Description, or anything else. + + All the string fields below including strings, keys, names and language tags are null terminated. + The PNG specification uses null characters for the keys, names and tags, and forbids null + characters to appear in the main text which is why we can use null termination everywhere here. + + A keyword is minimum 1 character and maximum 79 characters long (plus the + additional null terminator). It's discouraged to use a single line length + longer than 79 characters for texts. + + Don't allocate these text buffers yourself. Use the init/cleanup functions + correctly and use lodepng_add_text and lodepng_clear_text. + + Standard text chunk keywords and strings are encoded using Latin-1. + */ + size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ + char ** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ + char ** text_strings; /*the actual text*/ + + /* + International text chunks (iTXt) + Similar to the non-international text chunks, but with additional strings + "langtags" and "transkeys", and the following text encodings are used: + keys: Latin-1, langtags: ASCII, transkeys and strings: UTF-8. + keys must be 1-79 characters (plus the additional null terminator), the other + strings are any length. + */ + size_t itext_num; /*the amount of international texts in this PNG*/ + char ** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ + char ** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ + char ** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ + char ** itext_strings; /*the actual international text - UTF-8 string*/ + + /*time chunk (tIME)*/ + unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ + LodePNGTime time; + + /*phys chunk (pHYs)*/ + unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ + unsigned phys_x; /*pixels per unit in x direction*/ + unsigned phys_y; /*pixels per unit in y direction*/ + unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ + + /* + Color profile related chunks: gAMA, cHRM, sRGB, iCPP, sBIT + + LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color + profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please + use these values with a color management library. + + See the PNG, ICC and sRGB specifications for more information about the meaning of these values. + */ + + /* gAMA chunk: optional, overridden by sRGB or iCCP if those are present. */ + unsigned gama_defined; /* Whether a gAMA chunk is present (0 = not present, 1 = present). */ + unsigned gama_gamma; /* Gamma exponent times 100000 */ + + /* cHRM chunk: optional, overridden by sRGB or iCCP if those are present. */ + unsigned chrm_defined; /* Whether a cHRM chunk is present (0 = not present, 1 = present). */ + unsigned chrm_white_x; /* White Point x times 100000 */ + unsigned chrm_white_y; /* White Point y times 100000 */ + unsigned chrm_red_x; /* Red x times 100000 */ + unsigned chrm_red_y; /* Red y times 100000 */ + unsigned chrm_green_x; /* Green x times 100000 */ + unsigned chrm_green_y; /* Green y times 100000 */ + unsigned chrm_blue_x; /* Blue x times 100000 */ + unsigned chrm_blue_y; /* Blue y times 100000 */ + + /* + sRGB chunk: optional. May not appear at the same time as iCCP. + If gAMA is also present gAMA must contain value 45455. + If cHRM is also present cHRM must contain respectively 31270,32900,64000,33000,30000,60000,15000,6000. + */ + unsigned srgb_defined; /* Whether an sRGB chunk is present (0 = not present, 1 = present). */ + unsigned srgb_intent; /* Rendering intent: 0=perceptual, 1=rel. colorimetric, 2=saturation, 3=abs. colorimetric */ + + /* + iCCP chunk: optional. May not appear at the same time as sRGB. + + LodePNG does not parse or use the ICC profile (except its color space header field for an edge case), a + separate library to handle the ICC data (not included in LodePNG) format is needed to use it for color + management and conversions. + + For encoding, if iCCP is present, gAMA and cHRM are recommended to be added as well with values that match the ICC + profile as closely as possible, if you wish to do this you should provide the correct values for gAMA and cHRM and + enable their '_defined' flags since LodePNG will not automatically compute them from the ICC profile. + + For encoding, the ICC profile is required by the PNG specification to be an "RGB" profile for non-gray + PNG color types and a "GRAY" profile for gray PNG color types. If you disable auto_convert, you must ensure + the ICC profile type matches your requested color type, else the encoder gives an error. If auto_convert is + enabled (the default), and the ICC profile is not a good match for the pixel data, this will result in an encoder + error if the pixel data has non-gray pixels for a GRAY profile, or a silent less-optimal compression of the pixel + data if the pixels could be encoded as grayscale but the ICC profile is RGB. + + To avoid this do not set an ICC profile in the image unless there is a good reason for it, and when doing so + make sure you compute it carefully to avoid the above problems. + */ + unsigned iccp_defined; /* Whether an iCCP chunk is present (0 = not present, 1 = present). */ + char * iccp_name; /* Null terminated string with profile name, 1-79 bytes */ + /* + The ICC profile in iccp_profile_size bytes. + Don't allocate this buffer yourself. Use the init/cleanup functions + correctly and use lodepng_set_icc and lodepng_clear_icc. + */ + unsigned char * iccp_profile; + unsigned iccp_profile_size; /* The size of iccp_profile in bytes */ + + /* + sBIT chunk: significant bits. Optional metadata, only set this if needed. + + If defined, these values give the bit depth of the original data. Since PNG only stores 1, 2, 4, 8 or 16-bit + per channel data, the significant bits value can be used to indicate the original encoded data has another + sample depth, such as 10 or 12. + + Encoders using this value, when storing the pixel data, should use the most significant bits + of the data to store the original bits, and use a good sample depth scaling method such as + "left bit replication" to fill in the least significant bits, rather than fill zeroes. + + Decoders using this value, if able to work with data that's e.g. 10-bit or 12-bit, should right + shift the data to go back to the original bit depth, but decoders are also allowed to ignore + sbit and work e.g. with the 8-bit or 16-bit data from the PNG directly, since thanks + to the encoder contract, the values encoded in PNG are in valid range for the PNG bit depth. + + For grayscale images, sbit_g and sbit_b are not used, and for images that don't use color + type RGBA or grayscale+alpha, sbit_a is not used (it's not used even for palette images with + translucent palette values, or images with color key). The values that are used must be + greater than zero and smaller than or equal to the PNG bit depth. + + The color type from the header in the PNG image defines these used and unused fields: if + decoding with a color mode conversion, such as always decoding to RGBA, this metadata still + only uses the color type of the original PNG, and may e.g. lack the alpha channel info + if the PNG was RGB. When encoding with auto_convert (as well as without), also always the + color model defined in info_png.color determines this. + + NOTE: enabling sbit can hurt compression, because the encoder can then not always use + auto_convert to choose a more optimal color mode for the data, because the PNG format has + strict requirements for the allowed sbit values in combination with color modes. + For example, setting these fields to 10-bit will force the encoder to keep using a 16-bit per channel + color mode, even if the pixel data would in fact fit in a more efficient 8-bit mode. + */ + unsigned sbit_defined; /*is significant bits given? if not, the values below are unused*/ + unsigned sbit_r; /*red or gray component of significant bits*/ + unsigned sbit_g; /*green component of significant bits*/ + unsigned sbit_b; /*blue component of significant bits*/ + unsigned sbit_a; /*alpha component of significant bits*/ + + /* End of color profile related chunks */ + + + /* + unknown chunks: chunks not known by LodePNG, passed on byte for byte. + + There are 3 buffers, one for each position in the PNG where unknown chunks can appear. + Each buffer contains all unknown chunks for that position consecutively. + The 3 positions are: + 0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND. + + For encoding, do not store critical chunks or known chunks that are enabled with a "_defined" flag + above in here, since the encoder will blindly follow this and could then encode an invalid PNG file + (such as one with two IHDR chunks or the disallowed combination of sRGB with iCCP). But do use + this if you wish to store an ancillary chunk that is not supported by LodePNG (such as sPLT or hIST), + or any non-standard PNG chunk. + + Do not allocate or traverse this data yourself. Use the chunk traversing functions declared + later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct. + */ + unsigned char * unknown_chunks_data[3]; + size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGInfo; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_info_init(LodePNGInfo * info); +void lodepng_info_cleanup(LodePNGInfo * info); +/*return value is error code (0 means no error)*/ +unsigned lodepng_info_copy(LodePNGInfo * dest, const LodePNGInfo * source); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +unsigned lodepng_add_text(LodePNGInfo * info, const char * key, const char * str); /*push back both texts at once*/ +void lodepng_clear_text(LodePNGInfo * info); /*use this to clear the texts again after you filled them in*/ + +unsigned lodepng_add_itext(LodePNGInfo * info, const char * key, const char * langtag, + const char * transkey, const char * str); /*push back the 4 texts of 1 chunk at once*/ +void lodepng_clear_itext(LodePNGInfo * info); /*use this to clear the itexts again after you filled them in*/ + +/*replaces if exists*/ +unsigned lodepng_set_icc(LodePNGInfo * info, const char * name, const unsigned char * profile, unsigned profile_size); +void lodepng_clear_icc(LodePNGInfo * info); /*use this to clear the texts again after you filled them in*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +/* +Converts raw buffer from one color type to another color type, based on +LodePNGColorMode structs to describe the input and output color type. +See the reference manual at the end of this header file to see which color conversions are supported. +return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported) +The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel +of the output color type (lodepng_get_bpp). +For < 8 bpp images, there should not be padding bits at the end of scanlines. +For 16-bit per channel colors, uses big endian format like PNG does. +Return value is LodePNG error code +*/ +unsigned lodepng_convert(unsigned char * out, const unsigned char * in, + const LodePNGColorMode * mode_out, const LodePNGColorMode * mode_in, + unsigned w, unsigned h); + +#ifdef LODEPNG_COMPILE_DECODER +/* +Settings for the decoder. This contains settings for the PNG and the Zlib +decoder, but not the Info settings from the Info structs. +*/ +typedef struct LodePNGDecoderSettings { + LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ + + /* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */ + unsigned ignore_crc; /*ignore CRC checksums*/ + unsigned ignore_critical; /*ignore unknown critical chunks*/ + unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/ + /* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable + errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some + strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters + in string keys, etc... */ + + unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ + + /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ + unsigned remember_unknown_chunks; + + /* maximum size for decompressed text chunks. If a text chunk's text is larger than this, an error is returned, + unless reading text chunks is disabled or this limit is set higher or disabled. Set to 0 to allow any size. + By default it is a value that prevents unreasonably large strings from hogging memory. */ + size_t max_text_size; + + /* maximum size for compressed ICC chunks. If the ICC profile is larger than this, an error will be returned. Set to + 0 to allow any size. By default this is a value that prevents ICC profiles that would be much larger than any + legitimate profile could be to hog memory. */ + size_t max_icc_size; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGDecoderSettings; + +void lodepng_decoder_settings_init(LodePNGDecoderSettings * settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/ +typedef enum LodePNGFilterStrategy { + /*every filter at zero*/ + LFS_ZERO = 0, + /*every filter at 1, 2, 3 or 4 (paeth), unlike LFS_ZERO not a good choice, but for testing*/ + LFS_ONE = 1, + LFS_TWO = 2, + LFS_THREE = 3, + LFS_FOUR = 4, + /*Use filter that gives minimum sum, as described in the official PNG filter heuristic.*/ + LFS_MINSUM, + /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending + on the image, this is better or worse than minsum.*/ + LFS_ENTROPY, + /* + Brute-force-search PNG filters by compressing each filter for each scanline. + Experimental, very slow, and only rarely gives better compression than MINSUM. + */ + LFS_BRUTE_FORCE, + /*use predefined_filters buffer: you specify the filter type for each scanline*/ + LFS_PREDEFINED +} LodePNGFilterStrategy; + +/*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...), +which helps decide which color model to use for encoding. +Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/ +typedef struct LodePNGColorStats { + unsigned colored; /*not grayscale*/ + unsigned key; /*image is not opaque and color key is possible instead of full alpha*/ + unsigned short key_r; /*key values, always as 16-bit, in 8-bit case the byte is duplicated, e.g. 65535 means 255*/ + unsigned short key_g; + unsigned short key_b; + unsigned alpha; /*image is not opaque and alpha channel or alpha palette required*/ + unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16 or allow_palette is disabled.*/ + unsigned char + palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order, only valid when numcolors is valid*/ + unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for grayscale only. 16 if 16-bit per channel required.*/ + size_t numpixels; + + /*user settings for computing/using the stats*/ + unsigned allow_palette; /*default 1. if 0, disallow choosing palette colortype in auto_choose_color, and don't count numcolors*/ + unsigned allow_greyscale; /*default 1. if 0, choose RGB or RGBA even if the image only has gray colors*/ +} LodePNGColorStats; + +void lodepng_color_stats_init(LodePNGColorStats * stats); + +/*Get a LodePNGColorStats of the image. The stats must already have been inited. +Returns error code (e.g. alloc fail) or 0 if ok.*/ +unsigned lodepng_compute_color_stats(LodePNGColorStats * stats, + const unsigned char * image, unsigned w, unsigned h, + const LodePNGColorMode * mode_in); + +/*Settings for the encoder.*/ +typedef struct LodePNGEncoderSettings { + LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ + + unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/ + + /*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than + 8 bit depth, set all filters to zero. Otherwise use the filter_strategy. Note that to + completely follow the official PNG heuristic, filter_palette_zero must be true and + filter_strategy must be LFS_MINSUM*/ + unsigned filter_palette_zero; + /*Which filter strategy to use when not using zeroes due to filter_palette_zero. + Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/ + LodePNGFilterStrategy filter_strategy; + /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with + the same length as the amount of scanlines in the image, and each value must <= 5. You + have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero + must be set to 0 to ensure this is also used on palette or low bitdepth images.*/ + const unsigned char * predefined_filters; + + /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). + If colortype is 3, PLTE is always created. If color type is explicitely set + to a grayscale type (1 or 4), this is not done and is ignored. If enabling this, + a palette must be present in the info_png. + NOTE: enabling this may worsen compression if auto_convert is used to choose + optimal color mode, because it cannot use grayscale color modes in this case*/ + unsigned force_palette; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*add LodePNG identifier and version as a text chunk, for debugging*/ + unsigned add_id; + /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ + unsigned text_compression; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGEncoderSettings; + +void lodepng_encoder_settings_init(LodePNGEncoderSettings * settings); +#endif /*LODEPNG_COMPILE_ENCODER*/ + + +#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) +/*The settings, state and information for extended encoding and decoding.*/ +typedef struct LodePNGState { +#ifdef LODEPNG_COMPILE_DECODER + LodePNGDecoderSettings decoder; /*the decoding settings*/ +#endif /*LODEPNG_COMPILE_DECODER*/ +#ifdef LODEPNG_COMPILE_ENCODER + LodePNGEncoderSettings encoder; /*the encoding settings*/ +#endif /*LODEPNG_COMPILE_ENCODER*/ + LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ + LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ + unsigned error; +} LodePNGState; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_state_init(LodePNGState * state); +void lodepng_state_cleanup(LodePNGState * state); +void lodepng_state_copy(LodePNGState * dest, const LodePNGState * source); +#endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ + +#ifdef LODEPNG_COMPILE_DECODER +/* +Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings and +getting much more information about the PNG image and color mode. +*/ +unsigned lodepng_decode(unsigned char ** out, unsigned * w, unsigned * h, + LodePNGState * state, + const unsigned char * in, size_t insize); + +/* +Read the PNG header, but not the actual data. This returns only the information +that is in the IHDR chunk of the PNG, such as width, height and color type. The +information is placed in the info_png field of the LodePNGState. +*/ +unsigned lodepng_inspect(unsigned * w, unsigned * h, + LodePNGState * state, + const unsigned char * in, size_t insize); +#endif /*LODEPNG_COMPILE_DECODER*/ + +/* +Reads one metadata chunk (other than IHDR, which is handled by lodepng_inspect) +of the PNG file and outputs what it read in the state. Returns error code on failure. +Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const +to find the desired chunk type, and if non null use lodepng_inspect_chunk (with +chunk_pointer - start_of_file as pos). +Supports most metadata chunks from the PNG standard (gAMA, bKGD, tEXt, ...). +Ignores unsupported, unknown, non-metadata or IHDR chunks (without error). +Requirements: &in[pos] must point to start of a chunk, must use regular +lodepng_inspect first since format of most other chunks depends on IHDR, and if +there is a PLTE chunk, that one must be inspected before tRNS or bKGD. +*/ +unsigned lodepng_inspect_chunk(LodePNGState * state, size_t pos, + const unsigned char * in, size_t insize); + +#ifdef LODEPNG_COMPILE_ENCODER +/*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/ +unsigned lodepng_encode(unsigned char ** out, size_t * outsize, + const unsigned char * image, unsigned w, unsigned h, + LodePNGState * state); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/* +The lodepng_chunk functions are normally not needed, except to traverse the +unknown chunks stored in the LodePNGInfo struct, or add new ones to it. +It also allows traversing the chunks of an encoded PNG file yourself. + +The chunk pointer always points to the beginning of the chunk itself, that is +the first byte of the 4 length bytes. + +In the PNG file format, chunks have the following format: +-4 bytes length: length of the data of the chunk in bytes (chunk itself is 12 bytes longer) +-4 bytes chunk type (ASCII a-z,A-Z only, see below) +-length bytes of data (may be 0 bytes if length was 0) +-4 bytes of CRC, computed on chunk name + data + +The first chunk starts at the 8th byte of the PNG file, the entire rest of the file +exists out of concatenated chunks with the above format. + +PNG standard chunk ASCII naming conventions: +-First byte: uppercase = critical, lowercase = ancillary +-Second byte: uppercase = public, lowercase = private +-Third byte: must be uppercase +-Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy +*/ + +/* +Gets the length of the data of the chunk. Total chunk length has 12 bytes more. +There must be at least 4 bytes to read from. If the result value is too large, +it may be corrupt data. +*/ +unsigned lodepng_chunk_length(const unsigned char * chunk); + +/*puts the 4-byte type in null terminated string*/ +void lodepng_chunk_type(char type[5], const unsigned char * chunk); + +/*check if the type is the given type*/ +unsigned char lodepng_chunk_type_equals(const unsigned char * chunk, const char * type); + +/*0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard)*/ +unsigned char lodepng_chunk_ancillary(const unsigned char * chunk); + +/*0: public, 1: private (see PNG standard)*/ +unsigned char lodepng_chunk_private(const unsigned char * chunk); + +/*0: the chunk is unsafe to copy, 1: the chunk is safe to copy (see PNG standard)*/ +unsigned char lodepng_chunk_safetocopy(const unsigned char * chunk); + +/*get pointer to the data of the chunk, where the input points to the header of the chunk*/ +unsigned char * lodepng_chunk_data(unsigned char * chunk); +const unsigned char * lodepng_chunk_data_const(const unsigned char * chunk); + +/*returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!)*/ +unsigned lodepng_chunk_check_crc(const unsigned char * chunk); + +/*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ +void lodepng_chunk_generate_crc(unsigned char * chunk); + +/* +Iterate to next chunks, allows iterating through all chunks of the PNG file. +Input must be at the beginning of a chunk (result of a previous lodepng_chunk_next call, +or the 8th byte of a PNG file which always has the first chunk), or alternatively may +point to the first byte of the PNG file (which is not a chunk but the magic header, the +function will then skip over it and return the first real chunk). +Will output pointer to the start of the next chunk, or at or beyond end of the file if there +is no more chunk after this or possibly if the chunk is corrupt. +Start this process at the 8th byte of the PNG file. +In a non-corrupt PNG file, the last chunk should have name "IEND". +*/ +unsigned char * lodepng_chunk_next(unsigned char * chunk, unsigned char * end); +const unsigned char * lodepng_chunk_next_const(const unsigned char * chunk, const unsigned char * end); + +/*Finds the first chunk with the given type in the range [chunk, end), or returns NULL if not found.*/ +unsigned char * lodepng_chunk_find(unsigned char * chunk, unsigned char * end, const char type[5]); +const unsigned char * lodepng_chunk_find_const(const unsigned char * chunk, const unsigned char * end, + const char type[5]); + +/* +Appends chunk to the data in out. The given chunk should already have its chunk header. +The out variable and outsize are updated to reflect the new reallocated buffer. +Returns error code (0 if it went ok) +*/ +unsigned lodepng_chunk_append(unsigned char ** out, size_t * outsize, const unsigned char * chunk); + +/* +Appends new chunk to out. The chunk to append is given by giving its length, type +and data separately. The type is a 4-letter string. +The out variable and outsize are updated to reflect the new reallocated buffer. +Returne error code (0 if it went ok) +*/ +unsigned lodepng_chunk_create(unsigned char ** out, size_t * outsize, size_t length, + const char * type, const unsigned char * data); + + +/*Calculate CRC32 of buffer*/ +unsigned lodepng_crc32(const unsigned char * buf, size_t len); +#endif /*LODEPNG_COMPILE_PNG*/ + + +#ifdef LODEPNG_COMPILE_ZLIB +/* +This zlib part can be used independently to zlib compress and decompress a +buffer. It cannot be used to create gzip files however, and it only supports the +part of zlib that is required for PNG, it does not support dictionaries. +*/ + +#ifdef LODEPNG_COMPILE_DECODER +/*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/ +unsigned lodepng_inflate(unsigned char ** out, size_t * outsize, + const unsigned char * in, size_t insize, + const LodePNGDecompressSettings * settings); + +/* +Decompresses Zlib data. Reallocates the out buffer and appends the data. The +data must be according to the zlib specification. +Either, *out must be NULL and *outsize must be 0, or, *out must be a valid +buffer and *outsize its size in bytes. out must be freed by user after usage. +*/ +unsigned lodepng_zlib_decompress(unsigned char ** out, size_t * outsize, + const unsigned char * in, size_t insize, + const LodePNGDecompressSettings * settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Compresses data with Zlib. Reallocates the out buffer and appends the data. +Zlib adds a small header and trailer around the deflate data. +The data is output in the format of the zlib specification. +Either, *out must be NULL and *outsize must be 0, or, *out must be a valid +buffer and *outsize its size in bytes. out must be freed by user after usage. +*/ +unsigned lodepng_zlib_compress(unsigned char ** out, size_t * outsize, + const unsigned char * in, size_t insize, + const LodePNGCompressSettings * settings); + +/* +Find length-limited Huffman code for given frequencies. This function is in the +public interface only for tests, it's used internally by lodepng_deflate. +*/ +unsigned lodepng_huffman_code_lengths(unsigned * lengths, const unsigned * frequencies, + size_t numcodes, unsigned maxbitlen); + +/*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/ +unsigned lodepng_deflate(unsigned char ** out, size_t * outsize, + const unsigned char * in, size_t insize, + const LodePNGCompressSettings * settings); + +#endif /*LODEPNG_COMPILE_ENCODER*/ +#endif /*LODEPNG_COMPILE_ZLIB*/ + +#ifdef LODEPNG_COMPILE_DISK + /* + Load a file from disk into buffer. The function allocates the out buffer, and + after usage you should free it. + out: output parameter, contains pointer to loaded buffer. + outsize: output parameter, size of the allocated out buffer + filename: the path to the file to load + return value: error code (0 means ok) + + NOTE: Wide-character filenames are not supported, you can use an external method + to handle such files and decode in-memory. + */ + unsigned lodepng_load_file(unsigned char ** out, size_t * outsize, const char * filename); + + /* + Save a file from buffer to disk. Warning, if it exists, this function overwrites + the file without warning! + buffer: the buffer to write + buffersize: size of the buffer to write + filename: the path to the file to save to + return value: error code (0 means ok) + + NOTE: Wide-character filenames are not supported, you can use an external method + to handle such files and encode in-memory + */ + unsigned lodepng_save_file(const unsigned char * buffer, size_t buffersize, const char * filename); +#endif /*LODEPNG_COMPILE_DISK*/ + +#ifdef LODEPNG_COMPILE_CPP +/* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */ +namespace lodepng +{ +#ifdef LODEPNG_COMPILE_PNG +class State : public LodePNGState +{ + public: + State(); + State(const State & other); + ~State(); + State & operator=(const State & other); +}; + +#ifdef LODEPNG_COMPILE_DECODER +/* Same as other lodepng::decode, but using a State for more settings and information. */ +unsigned decode(std::vector & out, unsigned & w, unsigned & h, + State & state, + const unsigned char * in, size_t insize); +unsigned decode(std::vector & out, unsigned & w, unsigned & h, + State & state, + const std::vector & in); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* Same as other lodepng::encode, but using a State for more settings and information. */ +unsigned encode(std::vector & out, + const unsigned char * in, unsigned w, unsigned h, + State & state); +unsigned encode(std::vector & out, + const std::vector & in, unsigned w, unsigned h, + State & state); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_DISK + /* + Load a file from disk into an std::vector. + return value: error code (0 means ok) + + NOTE: Wide-character filenames are not supported, you can use an external method + to handle such files and decode in-memory + */ + unsigned load_file(std::vector & buffer, const std::string & filename); + + /* + Save the binary data in an std::vector to a file on disk. The file is overwritten + without warning. + + NOTE: Wide-character filenames are not supported, you can use an external method + to handle such files and encode in-memory + */ + unsigned save_file(const std::vector & buffer, const std::string & filename); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_PNG */ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_DECODER +/* Zlib-decompress an unsigned char buffer */ +unsigned decompress(std::vector & out, const unsigned char * in, size_t insize, + const LodePNGDecompressSettings & settings = lodepng_default_decompress_settings); + +/* Zlib-decompress an std::vector */ +unsigned decompress(std::vector & out, const std::vector & in, + const LodePNGDecompressSettings & settings = lodepng_default_decompress_settings); +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +/* Zlib-compress an unsigned char buffer */ +unsigned compress(std::vector & out, const unsigned char * in, size_t insize, + const LodePNGCompressSettings & settings = lodepng_default_compress_settings); + +/* Zlib-compress an std::vector */ +unsigned compress(std::vector & out, const std::vector & in, + const LodePNGCompressSettings & settings = lodepng_default_compress_settings); +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_ZLIB */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ + +/* +TODO: +[.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often +[.] check compatibility with various compilers - done but needs to be redone for every newer version +[X] converting color to 16-bit per channel types +[X] support color profile chunk types (but never let them touch RGB values by default) +[ ] support all public PNG chunk types (almost done except sPLT and hIST) +[ ] make sure encoder generates no chunks with size > (2^31)-1 +[ ] partial decoding (stream processing) +[X] let the "isFullyOpaque" function check color keys and transparent palettes too +[X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" +[ ] allow treating some errors like warnings, when image is recoverable (e.g. 69, 57, 58) +[ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ... +[ ] error messages with line numbers (and version) +[ ] errors in state instead of as return code? +[ ] new errors/warnings like suspiciously big decompressed ztxt or iccp chunk +[ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes +[ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ... +[ ] allow user to give data (void*) to custom allocator +[X] provide alternatives for C library functions not present on some platforms (memcpy, ...) +*/ + +#endif /*LV_USE_LODEPNG*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LODEPNG_H inclusion guard*/ + +/* +LodePNG Documentation +--------------------- + +0. table of contents +-------------------- + + 1. about + 1.1. supported features + 1.2. features not supported + 2. C and C++ version + 3. security + 4. decoding + 5. encoding + 6. color conversions + 6.1. PNG color types + 6.2. color conversions + 6.3. padding bits + 6.4. A note about 16-bits per channel and endianness + 7. error values + 8. chunks and PNG editing + 9. compiler support + 10. examples + 10.1. decoder C++ example + 10.2. decoder C example + 11. state settings reference + 12. changes + 13. contact information + + +1. about +-------- + +PNG is a file format to store raster images losslessly with good compression, +supporting different color types and alpha channel. + +LodePNG is a PNG codec according to the Portable Network Graphics (PNG) +Specification (Second Edition) - W3C Recommendation 10 November 2003. + +The specifications used are: + +*) Portable Network Graphics (PNG) Specification (Second Edition): + http://www.w3.org/TR/2003/REC-PNG-20031110 +*) RFC 1950 ZLIB Compressed Data Format version 3.3: + http://www.gzip.org/zlib/rfc-zlib.html +*) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3: + http://www.gzip.org/zlib/rfc-deflate.html + +The most recent version of LodePNG can currently be found at +http://lodev.org/lodepng/ + +LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds +extra functionality. + +LodePNG exists out of two files: +-lodepng.h: the header file for both C and C++ +-lodepng.c(pp): give it the name lodepng.c or lodepng.cpp (or .cc) depending on your usage + +If you want to start using LodePNG right away without reading this doc, get the +examples from the LodePNG website to see how to use it in code, or check the +smaller examples in chapter 13 here. + +LodePNG is simple but only supports the basic requirements. To achieve +simplicity, the following design choices were made: There are no dependencies +on any external library. There are functions to decode and encode a PNG with +a single function call, and extended versions of these functions taking a +LodePNGState struct allowing to specify or get more information. By default +the colors of the raw image are always RGB or RGBA, no matter what color type +the PNG file uses. To read and write files, there are simple functions to +convert the files to/from buffers in memory. + +This all makes LodePNG suitable for loading textures in games, demos and small +programs, ... It's less suitable for full fledged image editors, loading PNGs +over network (it requires all the image data to be available before decoding can +begin), life-critical systems, ... + +1.1. supported features +----------------------- + +The following features are supported by the decoder: + +*) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image, + or the same color type as the PNG +*) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image +*) Adam7 interlace and deinterlace for any color type +*) loading the image from harddisk or decoding it from a buffer from other sources than harddisk +*) support for alpha channels, including RGBA color model, translucent palettes and color keying +*) zlib decompression (inflate) +*) zlib compression (deflate) +*) CRC32 and ADLER32 checksums +*) colorimetric color profile conversions: currently experimentally available in lodepng_util.cpp only, + plus alternatively ability to pass on chroma/gamma/ICC profile information to other color management system. +*) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks. +*) the following chunks are supported by both encoder and decoder: + IHDR: header information + PLTE: color palette + IDAT: pixel data + IEND: the final chunk + tRNS: transparency for palettized images + tEXt: textual information + zTXt: compressed textual information + iTXt: international textual information + bKGD: suggested background color + pHYs: physical dimensions + tIME: modification time + cHRM: RGB chromaticities + gAMA: RGB gamma correction + iCCP: ICC color profile + sRGB: rendering intent + sBIT: significant bits + +1.2. features not supported +--------------------------- + +The following features are not (yet) supported: + +*) some features needed to make a conformant PNG-Editor might be still missing. +*) partial loading/stream processing. All data must be available and is processed in one call. +*) The hIST and sPLT public chunks are not (yet) supported but treated as unknown chunks + + +2. C and C++ version +-------------------- + +The C version uses buffers allocated with alloc that you need to free() +yourself. You need to use init and cleanup functions for each struct whenever +using a struct from the C version to avoid exploits and memory leaks. + +The C++ version has extra functions with std::vectors in the interface and the +lodepng::State class which is a LodePNGState with constructor and destructor. + +These files work without modification for both C and C++ compilers because all +the additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers +ignore it, and the C code is made to compile both with strict ISO C90 and C++. + +To use the C++ version, you need to rename the source file to lodepng.cpp +(instead of lodepng.c), and compile it with a C++ compiler. + +To use the C version, you need to rename the source file to lodepng.c (instead +of lodepng.cpp), and compile it with a C compiler. + + +3. Security +----------- + +Even if carefully designed, it's always possible that LodePNG contains possible +exploits. If you discover one, please let me know, and it will be fixed. + +When using LodePNG, care has to be taken with the C version of LodePNG, as well +as the C-style structs when working with C++. The following conventions are used +for all C-style structs: + +-if a struct has a corresponding init function, always call the init function when making a new one +-if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks +-if a struct has a corresponding copy function, use the copy function instead of "=". + The destination must also be inited already. + + +4. Decoding +----------- + +Decoding converts a PNG compressed image to a raw pixel buffer. + +Most documentation on using the decoder is at its declarations in the header +above. For C, simple decoding can be done with functions such as +lodepng_decode32, and more advanced decoding can be done with the struct +LodePNGState and lodepng_decode. For C++, all decoding can be done with the +various lodepng::decode functions, and lodepng::State can be used for advanced +features. + +When using the LodePNGState, it uses the following fields for decoding: +*) LodePNGInfo info_png: it stores extra information about the PNG (the input) in here +*) LodePNGColorMode info_raw: here you can say what color mode of the raw image (the output) you want to get +*) LodePNGDecoderSettings decoder: you can specify a few extra settings for the decoder to use + +LodePNGInfo info_png +-------------------- + +After decoding, this contains extra information of the PNG image, except the actual +pixels, width and height because these are already gotten directly from the decoder +functions. + +It contains for example the original color type of the PNG image, text comments, +suggested background color, etc... More details about the LodePNGInfo struct are +at its declaration documentation. + +LodePNGColorMode info_raw +------------------------- + +When decoding, here you can specify which color type you want +the resulting raw image to be. If this is different from the colortype of the +PNG, then the decoder will automatically convert the result. This conversion +always works, except if you want it to convert a color PNG to grayscale or to +a palette with missing colors. + +By default, 32-bit color is used for the result. + +LodePNGDecoderSettings decoder +------------------------------ + +The settings can be used to ignore the errors created by invalid CRC and Adler32 +chunks, and to disable the decoding of tEXt chunks. + +There's also a setting color_convert, true by default. If false, no conversion +is done, the resulting data will be as it was in the PNG (after decompression) +and you'll have to puzzle the colors of the pixels together yourself using the +color type information in the LodePNGInfo. + + +5. Encoding +----------- + +Encoding converts a raw pixel buffer to a PNG compressed image. + +Most documentation on using the encoder is at its declarations in the header +above. For C, simple encoding can be done with functions such as +lodepng_encode32, and more advanced decoding can be done with the struct +LodePNGState and lodepng_encode. For C++, all encoding can be done with the +various lodepng::encode functions, and lodepng::State can be used for advanced +features. + +Like the decoder, the encoder can also give errors. However it gives less errors +since the encoder input is trusted, the decoder input (a PNG image that could +be forged by anyone) is not trusted. + +When using the LodePNGState, it uses the following fields for encoding: +*) LodePNGInfo info_png: here you specify how you want the PNG (the output) to be. +*) LodePNGColorMode info_raw: here you say what color type of the raw image (the input) has +*) LodePNGEncoderSettings encoder: you can specify a few settings for the encoder to use + +LodePNGInfo info_png +-------------------- + +When encoding, you use this the opposite way as when decoding: for encoding, +you fill in the values you want the PNG to have before encoding. By default it's +not needed to specify a color type for the PNG since it's automatically chosen, +but it's possible to choose it yourself given the right settings. + +The encoder will not always exactly match the LodePNGInfo struct you give, +it tries as close as possible. Some things are ignored by the encoder. The +encoder uses, for example, the following settings from it when applicable: +colortype and bitdepth, text chunks, time chunk, the color key, the palette, the +background color, the interlace method, unknown chunks, ... + +When encoding to a PNG with colortype 3, the encoder will generate a PLTE chunk. +If the palette contains any colors for which the alpha channel is not 255 (so +there are translucent colors in the palette), it'll add a tRNS chunk. + +LodePNGColorMode info_raw +------------------------- + +You specify the color type of the raw image that you give to the input here, +including a possible transparent color key and palette you happen to be using in +your raw image data. + +By default, 32-bit color is assumed, meaning your input has to be in RGBA +format with 4 bytes (unsigned chars) per pixel. + +LodePNGEncoderSettings encoder +------------------------------ + +The following settings are supported (some are in sub-structs): +*) auto_convert: when this option is enabled, the encoder will +automatically choose the smallest possible color mode (including color key) that +can encode the colors of all pixels without information loss. +*) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree, + 2 = dynamic huffman tree (best compression). Should be 2 for proper + compression. +*) use_lz77: whether or not to use LZ77 for compressed block types. Should be + true for proper compression. +*) windowsize: the window size used by the LZ77 encoder (1 - 32768). Has value + 2048 by default, but can be set to 32768 for better, but slow, compression. +*) force_palette: if colortype is 2 or 6, you can make the encoder write a PLTE + chunk if force_palette is true. This can used as suggested palette to convert + to by viewers that don't support more than 256 colors (if those still exist) +*) add_id: add text chunk "Encoder: LodePNG " to the image. +*) text_compression: default 1. If 1, it'll store texts as zTXt instead of tEXt chunks. + zTXt chunks use zlib compression on the text. This gives a smaller result on + large texts but a larger result on small texts (such as a single program name). + It's all tEXt or all zTXt though, there's no separate setting per text yet. + + +6. color conversions +-------------------- + +An important thing to note about LodePNG, is that the color type of the PNG, and +the color type of the raw image, are completely independent. By default, when +you decode a PNG, you get the result as a raw image in the color type you want, +no matter whether the PNG was encoded with a palette, grayscale or RGBA color. +And if you encode an image, by default LodePNG will automatically choose the PNG +color type that gives good compression based on the values of colors and amount +of colors in the image. It can be configured to let you control it instead as +well, though. + +To be able to do this, LodePNG does conversions from one color mode to another. +It can convert from almost any color type to any other color type, except the +following conversions: RGB to grayscale is not supported, and converting to a +palette when the palette doesn't have a required color is not supported. This is +not supported on purpose: this is information loss which requires a color +reduction algorithm that is beyond the scope of a PNG encoder (yes, RGB to gray +is easy, but there are multiple ways if you want to give some channels more +weight). + +By default, when decoding, you get the raw image in 32-bit RGBA or 24-bit RGB +color, no matter what color type the PNG has. And by default when encoding, +LodePNG automatically picks the best color model for the output PNG, and expects +the input image to be 32-bit RGBA or 24-bit RGB. So, unless you want to control +the color format of the images yourself, you can skip this chapter. + +6.1. PNG color types +-------------------- + +A PNG image can have many color types, ranging from 1-bit color to 64-bit color, +as well as palettized color modes. After the zlib decompression and unfiltering +in the PNG image is done, the raw pixel data will have that color type and thus +a certain amount of bits per pixel. If you want the output raw image after +decoding to have another color type, a conversion is done by LodePNG. + +The PNG specification gives the following color types: + +0: grayscale, bit depths 1, 2, 4, 8, 16 +2: RGB, bit depths 8 and 16 +3: palette, bit depths 1, 2, 4 and 8 +4: grayscale with alpha, bit depths 8 and 16 +6: RGBA, bit depths 8 and 16 + +Bit depth is the amount of bits per pixel per color channel. So the total amount +of bits per pixel is: amount of channels * bitdepth. + +6.2. color conversions +---------------------- + +As explained in the sections about the encoder and decoder, you can specify +color types and bit depths in info_png and info_raw to change the default +behaviour. + +If, when decoding, you want the raw image to be something else than the default, +you need to set the color type and bit depth you want in the LodePNGColorMode, +or the parameters colortype and bitdepth of the simple decoding function. + +If, when encoding, you use another color type than the default in the raw input +image, you need to specify its color type and bit depth in the LodePNGColorMode +of the raw image, or use the parameters colortype and bitdepth of the simple +encoding function. + +If, when encoding, you don't want LodePNG to choose the output PNG color type +but control it yourself, you need to set auto_convert in the encoder settings +to false, and specify the color type you want in the LodePNGInfo of the +encoder (including palette: it can generate a palette if auto_convert is true, +otherwise not). + +If the input and output color type differ (whether user chosen or auto chosen), +LodePNG will do a color conversion, which follows the rules below, and may +sometimes result in an error. + +To avoid some confusion: +-the decoder converts from PNG to raw image +-the encoder converts from raw image to PNG +-the colortype and bitdepth in LodePNGColorMode info_raw, are those of the raw image +-the colortype and bitdepth in the color field of LodePNGInfo info_png, are those of the PNG +-when encoding, the color type in LodePNGInfo is ignored if auto_convert + is enabled, it is automatically generated instead +-when decoding, the color type in LodePNGInfo is set by the decoder to that of the original + PNG image, but it can be ignored since the raw image has the color type you requested instead +-if the color type of the LodePNGColorMode and PNG image aren't the same, a conversion + between the color types is done if the color types are supported. If it is not + supported, an error is returned. If the types are the same, no conversion is done. +-even though some conversions aren't supported, LodePNG supports loading PNGs from any + colortype and saving PNGs to any colortype, sometimes it just requires preparing + the raw image correctly before encoding. +-both encoder and decoder use the same color converter. + +The function lodepng_convert does the color conversion. It is available in the +interface but normally isn't needed since the encoder and decoder already call +it. + +Non supported color conversions: +-color to grayscale when non-gray pixels are present: no error is thrown, but +the result will look ugly because only the red channel is taken (it assumes all +three channels are the same in this case so ignores green and blue). The reason +no error is given is to allow converting from three-channel grayscale images to +one-channel even if there are numerical imprecisions. +-anything to palette when the palette does not have an exact match for a from-color +in it: in this case an error is thrown + +Supported color conversions: +-anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA +-any gray or gray+alpha, to gray or gray+alpha +-anything to a palette, as long as the palette has the requested colors in it +-removing alpha channel +-higher to smaller bitdepth, and vice versa + +If you want no color conversion to be done (e.g. for speed or control): +-In the encoder, you can make it save a PNG with any color type by giving the +raw color mode and LodePNGInfo the same color mode, and setting auto_convert to +false. +-In the decoder, you can make it store the pixel data in the same color type +as the PNG has, by setting the color_convert setting to false. Settings in +info_raw are then ignored. + +6.3. padding bits +----------------- + +In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines +have a bit amount that isn't a multiple of 8, then padding bits are used so that each +scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output. +The raw input image you give to the encoder, and the raw output image you get from the decoder +will NOT have these padding bits, e.g. in the case of a 1-bit image with a width +of 7 pixels, the first pixel of the second scanline will the 8th bit of the first byte, +not the first bit of a new byte. + +6.4. A note about 16-bits per channel and endianness +---------------------------------------------------- + +LodePNG uses unsigned char arrays for 16-bit per channel colors too, just like +for any other color format. The 16-bit values are stored in big endian (most +significant byte first) in these arrays. This is the opposite order of the +little endian used by x86 CPU's. + +LodePNG always uses big endian because the PNG file format does so internally. +Conversions to other formats than PNG uses internally are not supported by +LodePNG on purpose, there are myriads of formats, including endianness of 16-bit +colors, the order in which you store R, G, B and A, and so on. Supporting and +converting to/from all that is outside the scope of LodePNG. + +This may mean that, depending on your use case, you may want to convert the big +endian output of LodePNG to little endian with a for loop. This is certainly not +always needed, many applications and libraries support big endian 16-bit colors +anyway, but it means you cannot simply cast the unsigned char* buffer to an +unsigned short* buffer on x86 CPUs. + + +7. error values +--------------- + +All functions in LodePNG that return an error code, return 0 if everything went +OK, or a non-zero code if there was an error. + +The meaning of the LodePNG error values can be retrieved with the function +lodepng_error_text: given the numerical error code, it returns a description +of the error in English as a string. + +Check the implementation of lodepng_error_text to see the meaning of each code. + +It is not recommended to use the numerical values to programmatically make +different decisions based on error types as the numbers are not guaranteed to +stay backwards compatible. They are for human consumption only. Programmatically +only 0 or non-0 matter. + + +8. chunks and PNG editing +------------------------- + +If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG +editor that should follow the rules about handling of unknown chunks, or if your +program is able to read other types of chunks than the ones handled by LodePNG, +then that's possible with the chunk functions of LodePNG. + +A PNG chunk has the following layout: + +4 bytes length +4 bytes type name +length bytes data +4 bytes CRC + +8.1. iterating through chunks +----------------------------- + +If you have a buffer containing the PNG image data, then the first chunk (the +IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the +signature of the PNG and are not part of a chunk. But if you start at byte 8 +then you have a chunk, and can check the following things of it. + +NOTE: none of these functions check for memory buffer boundaries. To avoid +exploits, always make sure the buffer contains all the data of the chunks. +When using lodepng_chunk_next, make sure the returned value is within the +allocated memory. + +unsigned lodepng_chunk_length(const unsigned char* chunk): + +Get the length of the chunk's data. The total chunk length is this length + 12. + +void lodepng_chunk_type(char type[5], const unsigned char* chunk): +unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type): + +Get the type of the chunk or compare if it's a certain type + +unsigned char lodepng_chunk_critical(const unsigned char* chunk): +unsigned char lodepng_chunk_private(const unsigned char* chunk): +unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk): + +Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are). +Check if the chunk is private (public chunks are part of the standard, private ones not). +Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical +chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your +program doesn't handle that type of unknown chunk. + +unsigned char* lodepng_chunk_data(unsigned char* chunk): +const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk): + +Get a pointer to the start of the data of the chunk. + +unsigned lodepng_chunk_check_crc(const unsigned char* chunk): +void lodepng_chunk_generate_crc(unsigned char* chunk): + +Check if the crc is correct or generate a correct one. + +unsigned char* lodepng_chunk_next(unsigned char* chunk): +const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk): + +Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these +functions do no boundary checking of the allocated data whatsoever, so make sure there is enough +data available in the buffer to be able to go to the next chunk. + +unsigned lodepng_chunk_append(unsigned char** out, size_t* outsize, const unsigned char* chunk): +unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, unsigned length, + const char* type, const unsigned char* data): + +These functions are used to create new chunks that are appended to the data in *out that has +length *outsize. The append function appends an existing chunk to the new data. The create +function creates a new chunk with the given parameters and appends it. Type is the 4-letter +name of the chunk. + +8.2. chunks in info_png +----------------------- + +The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3 +buffers (each with size) to contain 3 types of unknown chunks: +the ones that come before the PLTE chunk, the ones that come between the PLTE +and the IDAT chunks, and the ones that come after the IDAT chunks. +It's necessary to make the distinction between these 3 cases because the PNG +standard forces to keep the ordering of unknown chunks compared to the critical +chunks, but does not force any other ordering rules. + +info_png.unknown_chunks_data[0] is the chunks before PLTE +info_png.unknown_chunks_data[1] is the chunks after PLTE, before IDAT +info_png.unknown_chunks_data[2] is the chunks after IDAT + +The chunks in these 3 buffers can be iterated through and read by using the same +way described in the previous subchapter. + +When using the decoder to decode a PNG, you can make it store all unknown chunks +if you set the option settings.remember_unknown_chunks to 1. By default, this +option is off (0). + +The encoder will always encode unknown chunks that are stored in the info_png. +If you need it to add a particular chunk that isn't known by LodePNG, you can +use lodepng_chunk_append or lodepng_chunk_create to the chunk data in +info_png.unknown_chunks_data[x]. + +Chunks that are known by LodePNG should not be added in that way. E.g. to make +LodePNG add a bKGD chunk, set background_defined to true and add the correct +parameters there instead. + + +9. compiler support +------------------- + +No libraries other than the current standard C library are needed to compile +LodePNG. For the C++ version, only the standard C++ library is needed on top. +Add the files lodepng.c(pp) and lodepng.h to your project, include +lodepng.h where needed, and your program can read/write PNG files. + +It is compatible with C90 and up, and C++03 and up. + +If performance is important, use optimization when compiling! For both the +encoder and decoder, this makes a large difference. + +Make sure that LodePNG is compiled with the same compiler of the same version +and with the same settings as the rest of the program, or the interfaces with +std::vectors and std::strings in C++ can be incompatible. + +CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets. + +*) gcc and g++ + +LodePNG is developed in gcc so this compiler is natively supported. It gives no +warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++ +version 4.7.1 on Linux, 32-bit and 64-bit. + +*) Clang + +Fully supported and warning-free. + +*) Mingw + +The Mingw compiler (a port of gcc for Windows) should be fully supported by +LodePNG. + +*) Visual Studio and Visual C++ Express Edition + +LodePNG should be warning-free with warning level W4. Two warnings were disabled +with pragmas though: warning 4244 about implicit conversions, and warning 4996 +where it wants to use a non-standard function fopen_s instead of the standard C +fopen. + +Visual Studio may want "stdafx.h" files to be included in each source file and +give an error "unexpected end of file while looking for precompiled header". +This is not standard C++ and will not be added to the stock LodePNG. You can +disable it for lodepng.cpp only by right clicking it, Properties, C/C++, +Precompiled Headers, and set it to Not Using Precompiled Headers there. + +NOTE: Modern versions of VS should be fully supported, but old versions, e.g. +VS6, are not guaranteed to work. + +*) Compilers on Macintosh + +LodePNG has been reported to work both with gcc and LLVM for Macintosh, both for +C and C++. + +*) Other Compilers + +If you encounter problems on any compilers, feel free to let me know and I may +try to fix it if the compiler is modern and standards compliant. + + +10. examples +------------ + +This decoder example shows the most basic usage of LodePNG. More complex +examples can be found on the LodePNG website. + +NOTE: these examples do not support wide-character filenames, you can use an +external method to handle such files and encode or decode in-memory + +10.1. decoder C++ example +------------------------- + +#include "lodepng.h" +#include + +int main(int argc, char *argv[]) { + const char* filename = argc > 1 ? argv[1] : "test.png"; + + //load and decode + std::vector image; + unsigned width, height; + unsigned error = lodepng::decode(image, width, height, filename); + + //if there's an error, display it + if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; + + //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... +} + +10.2. decoder C example +----------------------- + +#include "lodepng.h" + +int main(int argc, char *argv[]) { + unsigned error; + unsigned char* image; + size_t width, height; + const char* filename = argc > 1 ? argv[1] : "test.png"; + + error = lodepng_decode32_file(&image, &width, &height, filename); + + if(error) printf("decoder error %u: %s\n", error, lodepng_error_text(error)); + + / * use image here * / + + free(image); + return 0; +} + +11. state settings reference +---------------------------- + +A quick reference of some settings to set on the LodePNGState + +For decoding: + +state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums +state.decoder.zlibsettings.custom_...: use custom inflate function +state.decoder.ignore_crc: ignore CRC checksums +state.decoder.ignore_critical: ignore unknown critical chunks +state.decoder.ignore_end: ignore missing IEND chunk. May fail if this corruption causes other errors +state.decoder.color_convert: convert internal PNG color to chosen one +state.decoder.read_text_chunks: whether to read in text metadata chunks +state.decoder.remember_unknown_chunks: whether to read in unknown chunks +state.info_raw.colortype: desired color type for decoded image +state.info_raw.bitdepth: desired bit depth for decoded image +state.info_raw....: more color settings, see struct LodePNGColorMode +state.info_png....: no settings for decoder but ouput, see struct LodePNGInfo + +For encoding: + +state.encoder.zlibsettings.btype: disable compression by setting it to 0 +state.encoder.zlibsettings.use_lz77: use LZ77 in compression +state.encoder.zlibsettings.windowsize: tweak LZ77 windowsize +state.encoder.zlibsettings.minmatch: tweak min LZ77 length to match +state.encoder.zlibsettings.nicematch: tweak LZ77 match where to stop searching +state.encoder.zlibsettings.lazymatching: try one more LZ77 matching +state.encoder.zlibsettings.custom_...: use custom deflate function +state.encoder.auto_convert: choose optimal PNG color type, if 0 uses info_png +state.encoder.filter_palette_zero: PNG filter strategy for palette +state.encoder.filter_strategy: PNG filter strategy to encode with +state.encoder.force_palette: add palette even if not encoding to one +state.encoder.add_id: add LodePNG identifier and version as a text chunk +state.encoder.text_compression: use compressed text chunks for metadata +state.info_raw.colortype: color type of raw input image you provide +state.info_raw.bitdepth: bit depth of raw input image you provide +state.info_raw: more color settings, see struct LodePNGColorMode +state.info_png.color.colortype: desired color type if auto_convert is false +state.info_png.color.bitdepth: desired bit depth if auto_convert is false +state.info_png.color....: more color settings, see struct LodePNGColorMode +state.info_png....: more PNG related settings, see struct LodePNGInfo + + +12. changes +----------- + +The version number of LodePNG is the date of the change given in the format +yyyymmdd. + +Some changes aren't backwards compatible. Those are indicated with a (!) +symbol. + +Not all changes are listed here, the commit history in github lists more: +https://github.com/lvandeve/lodepng + +*) 10 apr 2023: faster CRC32 implementation, but with larger lookup table. +*) 13 jun 2022: added support for the sBIT chunk. +*) 09 jan 2022: minor decoder speed improvements. +*) 27 jun 2021: added warnings that file reading/writing functions don't support + wide-character filenames (support for this is not planned, opening files is + not the core part of PNG decoding/decoding and is platform dependent). +*) 17 okt 2020: prevent decoding too large text/icc chunks by default. +*) 06 mar 2020: simplified some of the dynamic memory allocations. +*) 12 jan 2020: (!) added 'end' argument to lodepng_chunk_next to allow correct + overflow checks. +*) 14 aug 2019: around 25% faster decoding thanks to huffman lookup tables. +*) 15 jun 2019: (!) auto_choose_color API changed (for bugfix: don't use palette + if gray ICC profile) and non-ICC LodePNGColorProfile renamed to + LodePNGColorStats. +*) 30 dec 2018: code style changes only: removed newlines before opening braces. +*) 10 sep 2018: added way to inspect metadata chunks without full decoding. +*) 19 aug 2018: (!) fixed color mode bKGD is encoded with and made it use + palette index in case of palette. +*) 10 aug 2018: (!) added support for gAMA, cHRM, sRGB and iCCP chunks. This + change is backwards compatible unless you relied on unknown_chunks for those. +*) 11 jun 2018: less restrictive check for pixel size integer overflow +*) 14 jan 2018: allow optionally ignoring a few more recoverable errors +*) 17 sep 2017: fix memory leak for some encoder input error cases +*) 27 nov 2016: grey+alpha auto color model detection bugfix +*) 18 apr 2016: Changed qsort to custom stable sort (for platforms w/o qsort). +*) 09 apr 2016: Fixed colorkey usage detection, and better file loading (within + the limits of pure C90). +*) 08 dec 2015: Made load_file function return error if file can't be opened. +*) 24 okt 2015: Bugfix with decoding to palette output. +*) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding. +*) 24 aug 2014: Moved to github +*) 23 aug 2014: Reduced needless memory usage of decoder. +*) 28 jun 2014: Removed fix_png setting, always support palette OOB for + simplicity. Made ColorProfile public. +*) 09 jun 2014: Faster encoder by fixing hash bug and more zeros optimization. +*) 22 dec 2013: Power of two windowsize required for optimization. +*) 15 apr 2013: Fixed bug with LAC_ALPHA and color key. +*) 25 mar 2013: Added an optional feature to ignore some PNG errors (fix_png). +*) 11 mar 2013: (!) Bugfix with custom free. Changed from "my" to "lodepng_" + prefix for the custom allocators and made it possible with a new #define to + use custom ones in your project without needing to change lodepng's code. +*) 28 jan 2013: Bugfix with color key. +*) 27 okt 2012: Tweaks in text chunk keyword length error handling. +*) 8 okt 2012: (!) Added new filter strategy (entropy) and new auto color mode. + (no palette). Better deflate tree encoding. New compression tweak settings. + Faster color conversions while decoding. Some internal cleanups. +*) 23 sep 2012: Reduced warnings in Visual Studio a little bit. +*) 1 sep 2012: (!) Removed #define's for giving custom (de)compression functions + and made it work with function pointers instead. +*) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc + and free functions and toggle #defines from compiler flags. Small fixes. +*) 6 may 2012: (!) Made plugging in custom zlib/deflate functions more flexible. +*) 22 apr 2012: (!) Made interface more consistent, renaming a lot. Removed + redundant C++ codec classes. Reduced amount of structs. Everything changed, + but it is cleaner now imho and functionality remains the same. Also fixed + several bugs and shrunk the implementation code. Made new samples. +*) 6 nov 2011: (!) By default, the encoder now automatically chooses the best + PNG color model and bit depth, based on the amount and type of colors of the + raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color. +*) 9 okt 2011: simpler hash chain implementation for the encoder. +*) 8 sep 2011: lz77 encoder lazy matching instead of greedy matching. +*) 23 aug 2011: tweaked the zlib compression parameters after benchmarking. + A bug with the PNG filtertype heuristic was fixed, so that it chooses much + better ones (it's quite significant). A setting to do an experimental, slow, + brute force search for PNG filter types is added. +*) 17 aug 2011: (!) changed some C zlib related function names. +*) 16 aug 2011: made the code less wide (max 120 characters per line). +*) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors. +*) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled. +*) 11 dec 2010: encoding is made faster, based on suggestion by Peter Eastman + to optimize long sequences of zeros. +*) 13 nov 2010: added LodePNG_InfoColor_hasPaletteAlpha and + LodePNG_InfoColor_canHaveAlpha functions for convenience. +*) 7 nov 2010: added LodePNG_error_text function to get error code description. +*) 30 okt 2010: made decoding slightly faster +*) 26 okt 2010: (!) changed some C function and struct names (more consistent). + Reorganized the documentation and the declaration order in the header. +*) 08 aug 2010: only changed some comments and external samples. +*) 05 jul 2010: fixed bug thanks to warnings in the new gcc version. +*) 14 mar 2010: fixed bug where too much memory was allocated for char buffers. +*) 02 sep 2008: fixed bug where it could create empty tree that linux apps could + read by ignoring the problem but windows apps couldn't. +*) 06 jun 2008: added more error checks for out of memory cases. +*) 26 apr 2008: added a few more checks here and there to ensure more safety. +*) 06 mar 2008: crash with encoding of strings fixed +*) 02 feb 2008: support for international text chunks added (iTXt) +*) 23 jan 2008: small cleanups, and #defines to divide code in sections +*) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor. +*) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder. +*) 17 jan 2008: ability to encode and decode compressed zTXt chunks added + Also various fixes, such as in the deflate and the padding bits code. +*) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved + filtering code of encoder. +*) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A + C++ wrapper around this provides an interface almost identical to before. + Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code + are together in these files but it works both for C and C++ compilers. +*) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks +*) 30 aug 2007: bug fixed which makes this Borland C++ compatible +*) 09 aug 2007: some VS2005 warnings removed again +*) 21 jul 2007: deflate code placed in new namespace separate from zlib code +*) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images +*) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing + invalid std::vector element [0] fixed, and level 3 and 4 warnings removed +*) 02 jun 2007: made the encoder add a tag with version by default +*) 27 may 2007: zlib and png code separated (but still in the same file), + simple encoder/decoder functions added for more simple usage cases +*) 19 may 2007: minor fixes, some code cleaning, new error added (error 69), + moved some examples from here to lodepng_examples.cpp +*) 12 may 2007: palette decoding bug fixed +*) 24 apr 2007: changed the license from BSD to the zlib license +*) 11 mar 2007: very simple addition: ability to encode bKGD chunks. +*) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding + palettized PNG images. Plus little interface change with palette and texts. +*) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes. + Fixed a bug where the end code of a block had length 0 in the Huffman tree. +*) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented + and supported by the encoder, resulting in smaller PNGs at the output. +*) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone. +*) 24 jan 2007: gave encoder an error interface. Added color conversion from any + greyscale type to 8-bit greyscale with or without alpha. +*) 21 jan 2007: (!) Totally changed the interface. It allows more color types + to convert to and is more uniform. See the manual for how it works now. +*) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days: + encode/decode custom tEXt chunks, separate classes for zlib & deflate, and + at last made the decoder give errors for incorrect Adler32 or Crc. +*) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel. +*) 29 dec 2006: Added support for encoding images without alpha channel, and + cleaned out code as well as making certain parts faster. +*) 28 dec 2006: Added "Settings" to the encoder. +*) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now. + Removed some code duplication in the decoder. Fixed little bug in an example. +*) 09 dec 2006: (!) Placed output parameters of public functions as first parameter. + Fixed a bug of the decoder with 16-bit per color. +*) 15 okt 2006: Changed documentation structure +*) 09 okt 2006: Encoder class added. It encodes a valid PNG image from the + given image buffer, however for now it's not compressed. +*) 08 sep 2006: (!) Changed to interface with a Decoder class +*) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different + way. Renamed decodePNG to decodePNGGeneric. +*) 29 jul 2006: (!) Changed the interface: image info is now returned as a + struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy. +*) 28 jul 2006: Cleaned the code and added new error checks. + Corrected terminology "deflate" into "inflate". +*) 23 jun 2006: Added SDL example in the documentation in the header, this + example allows easy debugging by displaying the PNG and its transparency. +*) 22 jun 2006: (!) Changed way to obtain error value. Added + loadFile function for convenience. Made decodePNG32 faster. +*) 21 jun 2006: (!) Changed type of info vector to unsigned. + Changed position of palette in info vector. Fixed an important bug that + happened on PNGs with an uncompressed block. +*) 16 jun 2006: Internally changed unsigned into unsigned where + needed, and performed some optimizations. +*) 07 jun 2006: (!) Renamed functions to decodePNG and placed them + in LodePNG namespace. Changed the order of the parameters. Rewrote the + documentation in the header. Renamed files to lodepng.cpp and lodepng.h +*) 22 apr 2006: Optimized and improved some code +*) 07 sep 2005: (!) Changed to std::vector interface +*) 12 aug 2005: Initial release (C++, decoder only) + + +13. contact information +----------------------- + +Feel free to contact me with suggestions, problems, comments, ... concerning +LodePNG. If you encounter a PNG image that doesn't work properly with this +decoder, feel free to send it and I'll use it to find and fix the problem. + +My email address is (puzzle the account and domain together with an @ symbol): +Domain: gmail dot com. +Account: lode dot vandevenne. + + +Copyright (c) 2005-2022 Lode Vandevenne +*/ diff --git a/test/include/liblvgl/libs/lodepng/lv_lodepng.h b/test/include/liblvgl/libs/lodepng/lv_lodepng.h new file mode 100644 index 00000000..f3dc4b77 --- /dev/null +++ b/test/include/liblvgl/libs/lodepng/lv_lodepng.h @@ -0,0 +1,48 @@ +/** + * @file lv_lodepng.h + * + */ + +#ifndef LV_LODEPNG_H +#define LV_LODEPNG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_LODEPNG + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Register the PNG decoder functions in LVGL + */ +void lv_lodepng_init(void); + +void lv_lodepng_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_LODEPNG*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_LODEPNG_H*/ diff --git a/test/include/liblvgl/libs/lz4/LICENSE b/test/include/liblvgl/libs/lz4/LICENSE new file mode 100644 index 00000000..48849169 --- /dev/null +++ b/test/include/liblvgl/libs/lz4/LICENSE @@ -0,0 +1,24 @@ +LZ4 Library +Copyright (c) 2011-2020, Yann Collet +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/test/include/liblvgl/libs/lz4/lz4.h b/test/include/liblvgl/libs/lz4/lz4.h new file mode 100644 index 00000000..536c3b0e --- /dev/null +++ b/test/include/liblvgl/libs/lz4/lz4.h @@ -0,0 +1,877 @@ +/* + * LZ4 - Fast LZ compression algorithm + * Header File + * Copyright (C) 2011-2020, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 homepage : http://www.lz4.org + - LZ4 source repository : https://github.com/lz4/lz4 +*/ + +#include "../../lv_conf_internal.h" +#if LV_USE_LZ4_INTERNAL +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * LVGL's porting + */ +#include "liblvgl/lvgl.h" +#define LZ4_FREESTANDING 1 +#define LZ4_memset lv_memset +#define LZ4_memcpy lv_memcpy +#define LZ4_memmove lv_memmove + +#ifndef LZ4_H_2983827168210 +#define LZ4_H_2983827168210 + +/* --- Dependency --- */ +#include /* size_t */ + + +/** + Introduction + + LZ4 is lossless compression algorithm, providing compression speed >500 MB/s per core, + scalable with multi-cores CPU. It features an extremely fast decoder, with speed in + multiple GB/s per core, typically reaching RAM speed limits on multi-core systems. + + The LZ4 compression library provides in-memory compression and decompression functions. + It gives full buffer control to user. + Compression can be done in: + - a single step (described as Simple Functions) + - a single step, reusing a context (described in Advanced Functions) + - unbounded multiple steps (described as Streaming compression) + + lz4.h generates and decodes LZ4-compressed blocks (doc/lz4_Block_format.md). + Decompressing such a compressed block requires additional metadata. + Exact metadata depends on exact decompression function. + For the typical case of LZ4_decompress_safe(), + metadata includes block's compressed size, and maximum bound of decompressed size. + Each application is free to encode and pass such metadata in whichever way it wants. + + lz4.h only handle blocks, it cannot generate Frames. + + Blocks are different from Frames (doc/lz4_Frame_format.md). + Frames bundle both blocks and metadata in a specified manner. + Embedding metadata is required for compressed data to be self-contained and portable. + Frame format is delivered through a companion API, declared in lz4frame.h. + The `lz4` CLI can only manage frames. +*/ + +/*^*************************************************************** +* Export parameters +*****************************************************************/ +/* +* LZ4_DLL_EXPORT : +* Enable exporting of functions when building a Windows DLL +* LZ4LIB_VISIBILITY : +* Control library symbols visibility. +*/ +#ifndef LZ4LIB_VISIBILITY +# if defined(__GNUC__) && (__GNUC__ >= 4) +# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default"))) +# else +# define LZ4LIB_VISIBILITY +# endif +#endif +#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1) +# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY +#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1) +# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define LZ4LIB_API LZ4LIB_VISIBILITY +#endif + +/*! LZ4_FREESTANDING : + * When this macro is set to 1, it enables "freestanding mode" that is + * suitable for typical freestanding environment which doesn't support + * standard C library. + * + * - LZ4_FREESTANDING is a compile-time switch. + * - It requires the following macros to be defined: + * LZ4_memcpy, LZ4_memmove, LZ4_memset. + * - It only enables LZ4/HC functions which don't use heap. + * All LZ4F_* functions are not supported. + * - See tests/freestanding.c to check its basic setup. + */ +#if defined(LZ4_FREESTANDING) && (LZ4_FREESTANDING == 1) +# define LZ4_HEAPMODE 0 +# define LZ4HC_HEAPMODE 0 +# define LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION 1 +# if !defined(LZ4_memcpy) +# error "LZ4_FREESTANDING requires macro 'LZ4_memcpy'." +# endif +# if !defined(LZ4_memset) +# error "LZ4_FREESTANDING requires macro 'LZ4_memset'." +# endif +# if !defined(LZ4_memmove) +# error "LZ4_FREESTANDING requires macro 'LZ4_memmove'." +# endif +#elif ! defined(LZ4_FREESTANDING) +# define LZ4_FREESTANDING 0 +#endif + + +/*------ Version ------*/ +#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ +#define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */ +#define LZ4_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */ + +#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) + +#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE +#define LZ4_QUOTE(str) #str +#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str) +#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) /* requires v1.7.3+ */ + +LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version; requires v1.3.0+ */ +LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version; requires v1.7.5+ */ + + +/*-************************************ +* Tuning parameter +**************************************/ +#define LZ4_MEMORY_USAGE_MIN 10 +#define LZ4_MEMORY_USAGE_DEFAULT 14 +#define LZ4_MEMORY_USAGE_MAX 20 + +/*! + * LZ4_MEMORY_USAGE : + * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; ) + * Increasing memory usage improves compression ratio, at the cost of speed. + * Reduced memory usage may improve speed at the cost of ratio, thanks to better cache locality. + * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache + */ +#ifndef LZ4_MEMORY_USAGE +# define LZ4_MEMORY_USAGE LZ4_MEMORY_USAGE_DEFAULT +#endif + +#if (LZ4_MEMORY_USAGE < LZ4_MEMORY_USAGE_MIN) +# error "LZ4_MEMORY_USAGE is too small !" +#endif + +#if (LZ4_MEMORY_USAGE > LZ4_MEMORY_USAGE_MAX) +# error "LZ4_MEMORY_USAGE is too large !" +#endif + +/*-************************************ +* Simple Functions +**************************************/ +/*! LZ4_compress_default() : + * Compresses 'srcSize' bytes from buffer 'src' + * into already allocated 'dst' buffer of size 'dstCapacity'. + * Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize). + * It also runs faster, so it's a recommended setting. + * If the function cannot compress 'src' into a more limited 'dst' budget, + * compression stops *immediately*, and the function result is zero. + * In which case, 'dst' content is undefined (invalid). + * srcSize : max supported value is LZ4_MAX_INPUT_SIZE. + * dstCapacity : size of buffer 'dst' (which must be already allocated) + * @return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity) + * or 0 if compression fails + * Note : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer). + */ +LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity); + +/*! LZ4_decompress_safe() : + * @compressedSize : is the exact complete size of the compressed block. + * @dstCapacity : is the size of destination buffer (which must be already allocated), + * is an upper bound of decompressed size. + * @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity) + * If destination buffer is not large enough, decoding will stop and output an error code (negative value). + * If the source stream is detected malformed, the function will stop decoding and return a negative result. + * Note 1 : This function is protected against malicious data packets : + * it will never writes outside 'dst' buffer, nor read outside 'source' buffer, + * even if the compressed block is maliciously modified to order the decoder to do these actions. + * In such case, the decoder stops immediately, and considers the compressed block malformed. + * Note 2 : compressedSize and dstCapacity must be provided to the function, the compressed block does not contain them. + * The implementation is free to send / store / derive this information in whichever way is most beneficial. + * If there is a need for a different format which bundles together both compressed data and its metadata, consider looking at lz4frame.h instead. + */ +LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity); + + +/*-************************************ +* Advanced Functions +**************************************/ +#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ +#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) + +/*! LZ4_compressBound() : + Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) + This function is primarily useful for memory allocation purposes (destination buffer size). + Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). + Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize) + inputSize : max supported value is LZ4_MAX_INPUT_SIZE + return : maximum output size in a "worst case" scenario + or 0, if input size is incorrect (too large or negative) +*/ +LZ4LIB_API int LZ4_compressBound(int inputSize); + +/*! LZ4_compress_fast() : + Same as LZ4_compress_default(), but allows selection of "acceleration" factor. + The larger the acceleration value, the faster the algorithm, but also the lesser the compression. + It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed. + An acceleration value of "1" is the same as regular LZ4_compress_default() + Values <= 0 will be replaced by LZ4_ACCELERATION_DEFAULT (currently == 1, see lz4.c). + Values > LZ4_ACCELERATION_MAX will be replaced by LZ4_ACCELERATION_MAX (currently == 65537, see lz4.c). +*/ +LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); + + +/*! LZ4_compress_fast_extState() : + * Same as LZ4_compress_fast(), using an externally allocated memory space for its state. + * Use LZ4_sizeofState() to know how much memory must be allocated, + * and allocate it on 8-bytes boundaries (using `malloc()` typically). + * Then, provide this buffer as `void* state` to compression function. + */ +LZ4LIB_API int LZ4_sizeofState(void); +LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); + + +/*! LZ4_compress_destSize() : + * Reverse the logic : compresses as much data as possible from 'src' buffer + * into already allocated buffer 'dst', of size >= 'targetDestSize'. + * This function either compresses the entire 'src' content into 'dst' if it's large enough, + * or fill 'dst' buffer completely with as much data as possible from 'src'. + * note: acceleration parameter is fixed to "default". + * + * *srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'. + * New value is necessarily <= input value. + * @return : Nb bytes written into 'dst' (necessarily <= targetDestSize) + * or 0 if compression fails. + * + * Note : from v1.8.2 to v1.9.1, this function had a bug (fixed in v1.9.2+): + * the produced compressed content could, in specific circumstances, + * require to be decompressed into a destination buffer larger + * by at least 1 byte than the content to decompress. + * If an application uses `LZ4_compress_destSize()`, + * it's highly recommended to update liblz4 to v1.9.2 or better. + * If this can't be done or ensured, + * the receiving decompression function should provide + * a dstCapacity which is > decompressedSize, by at least 1 byte. + * See https://github.com/lz4/lz4/issues/859 for details + */ +LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize); + + +/*! LZ4_decompress_safe_partial() : + * Decompress an LZ4 compressed block, of size 'srcSize' at position 'src', + * into destination buffer 'dst' of size 'dstCapacity'. + * Up to 'targetOutputSize' bytes will be decoded. + * The function stops decoding on reaching this objective. + * This can be useful to boost performance + * whenever only the beginning of a block is required. + * + * @return : the number of bytes decoded in `dst` (necessarily <= targetOutputSize) + * If source stream is detected malformed, function returns a negative result. + * + * Note 1 : @return can be < targetOutputSize, if compressed block contains less data. + * + * Note 2 : targetOutputSize must be <= dstCapacity + * + * Note 3 : this function effectively stops decoding on reaching targetOutputSize, + * so dstCapacity is kind of redundant. + * This is because in older versions of this function, + * decoding operation would still write complete sequences. + * Therefore, there was no guarantee that it would stop writing at exactly targetOutputSize, + * it could write more bytes, though only up to dstCapacity. + * Some "margin" used to be required for this operation to work properly. + * Thankfully, this is no longer necessary. + * The function nonetheless keeps the same signature, in an effort to preserve API compatibility. + * + * Note 4 : If srcSize is the exact size of the block, + * then targetOutputSize can be any value, + * including larger than the block's decompressed size. + * The function will, at most, generate block's decompressed size. + * + * Note 5 : If srcSize is _larger_ than block's compressed size, + * then targetOutputSize **MUST** be <= block's decompressed size. + * Otherwise, *silent corruption will occur*. + */ +LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity); + + +/*-********************************************* +* Streaming Compression Functions +***********************************************/ +typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ + +/** + Note about RC_INVOKED + + - RC_INVOKED is predefined symbol of rc.exe (the resource compiler which is part of MSVC/Visual Studio). + https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros + + - Since rc.exe is a legacy compiler, it truncates long symbol (> 30 chars) + and reports warning "RC4011: identifier truncated". + + - To eliminate the warning, we surround long preprocessor symbol with + "#if !defined(RC_INVOKED) ... #endif" block that means + "skip this block when rc.exe is trying to read it". +*/ +#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */ +#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +LZ4LIB_API LZ4_stream_t* LZ4_createStream(void); +LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr); +#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */ +#endif + +/*! LZ4_resetStream_fast() : v1.9.0+ + * Use this to prepare an LZ4_stream_t for a new chain of dependent blocks + * (e.g., LZ4_compress_fast_continue()). + * + * An LZ4_stream_t must be initialized once before usage. + * This is automatically done when created by LZ4_createStream(). + * However, should the LZ4_stream_t be simply declared on stack (for example), + * it's necessary to initialize it first, using LZ4_initStream(). + * + * After init, start any new stream with LZ4_resetStream_fast(). + * A same LZ4_stream_t can be re-used multiple times consecutively + * and compress multiple streams, + * provided that it starts each new stream with LZ4_resetStream_fast(). + * + * LZ4_resetStream_fast() is much faster than LZ4_initStream(), + * but is not compatible with memory regions containing garbage data. + * + * Note: it's only useful to call LZ4_resetStream_fast() + * in the context of streaming compression. + * The *extState* functions perform their own resets. + * Invoking LZ4_resetStream_fast() before is redundant, and even counterproductive. + */ +LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr); + +/*! LZ4_loadDict() : + * Use this function to reference a static dictionary into LZ4_stream_t. + * The dictionary must remain available during compression. + * LZ4_loadDict() triggers a reset, so any previous data will be forgotten. + * The same dictionary will have to be loaded on decompression side for successful decoding. + * Dictionary are useful for better compression of small data (KB range). + * While LZ4 accept any input as dictionary, + * results are generally better when using Zstandard's Dictionary Builder. + * Loading a size of 0 is allowed, and is the same as reset. + * @return : loaded dictionary size, in bytes (necessarily <= 64 KB) + */ +LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); + +/*! LZ4_compress_fast_continue() : + * Compress 'src' content using data from previously compressed blocks, for better compression ratio. + * 'dst' buffer must be already allocated. + * If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. + * + * @return : size of compressed block + * or 0 if there is an error (typically, cannot fit into 'dst'). + * + * Note 1 : Each invocation to LZ4_compress_fast_continue() generates a new block. + * Each block has precise boundaries. + * Each block must be decompressed separately, calling LZ4_decompress_*() with relevant metadata. + * It's not possible to append blocks together and expect a single invocation of LZ4_decompress_*() to decompress them together. + * + * Note 2 : The previous 64KB of source data is __assumed__ to remain present, unmodified, at same address in memory ! + * + * Note 3 : When input is structured as a double-buffer, each buffer can have any size, including < 64 KB. + * Make sure that buffers are separated, by at least one byte. + * This construction ensures that each block only depends on previous block. + * + * Note 4 : If input buffer is a ring-buffer, it can have any size, including < 64 KB. + * + * Note 5 : After an error, the stream status is undefined (invalid), it can only be reset or freed. + */ +LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); + +/*! LZ4_saveDict() : + * If last 64KB data cannot be guaranteed to remain available at its current memory location, + * save it into a safer place (char* safeBuffer). + * This is schematically equivalent to a memcpy() followed by LZ4_loadDict(), + * but is much faster, because LZ4_saveDict() doesn't need to rebuild tables. + * @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error. + */ +LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int maxDictSize); + + +/*-********************************************** +* Streaming Decompression Functions +* Bufferless synchronous API +************************************************/ +typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */ + +/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() : + * creation / destruction of streaming decompression tracking context. + * A tracking context can be re-used multiple times. + */ +#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */ +#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void); +LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); +#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */ +#endif + +/*! LZ4_setStreamDecode() : + * An LZ4_streamDecode_t context can be allocated once and re-used multiple times. + * Use this function to start decompression of a new stream of blocks. + * A dictionary can optionally be set. Use NULL or size 0 for a reset order. + * Dictionary is presumed stable : it must remain accessible and unmodified during next decompression. + * @return : 1 if OK, 0 if error + */ +LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); + +/*! LZ4_decoderRingBufferSize() : v1.8.2+ + * Note : in a ring buffer scenario (optional), + * blocks are presumed decompressed next to each other + * up to the moment there is not enough remaining space for next block (remainingSize < maxBlockSize), + * at which stage it resumes from beginning of ring buffer. + * When setting such a ring buffer for streaming decompression, + * provides the minimum size of this ring buffer + * to be compatible with any source respecting maxBlockSize condition. + * @return : minimum ring buffer size, + * or 0 if there is an error (invalid maxBlockSize). + */ +LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize); +#define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 14 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */ + +/*! LZ4_decompress_safe_continue() : + * This decoding function allows decompression of consecutive blocks in "streaming" mode. + * The difference with the usual independent blocks is that + * new blocks are allowed to find references into former blocks. + * A block is an unsplittable entity, and must be presented entirely to the decompression function. + * LZ4_decompress_safe_continue() only accepts one block at a time. + * It's modeled after `LZ4_decompress_safe()` and behaves similarly. + * + * @LZ4_streamDecode : decompression state, tracking the position in memory of past data + * @compressedSize : exact complete size of one compressed block. + * @dstCapacity : size of destination buffer (which must be already allocated), + * must be an upper bound of decompressed size. + * @return : number of bytes decompressed into destination buffer (necessarily <= dstCapacity) + * If destination buffer is not large enough, decoding will stop and output an error code (negative value). + * If the source stream is detected malformed, the function will stop decoding and return a negative result. + * + * The last 64KB of previously decoded data *must* remain available and unmodified + * at the memory position where they were previously decoded. + * If less than 64KB of data has been decoded, all the data must be present. + * + * Special : if decompression side sets a ring buffer, it must respect one of the following conditions : + * - Decompression buffer size is _at least_ LZ4_decoderRingBufferSize(maxBlockSize). + * maxBlockSize is the maximum size of any single block. It can have any value > 16 bytes. + * In which case, encoding and decoding buffers do not need to be synchronized. + * Actually, data can be produced by any source compliant with LZ4 format specification, and respecting maxBlockSize. + * - Synchronized mode : + * Decompression buffer size is _exactly_ the same as compression buffer size, + * and follows exactly same update rule (block boundaries at same positions), + * and decoding function is provided with exact decompressed size of each block (exception for last block of the stream), + * _then_ decoding & encoding ring buffer can have any size, including small ones ( < 64 KB). + * - Decompression buffer is larger than encoding buffer, by a minimum of maxBlockSize more bytes. + * In which case, encoding and decoding buffers do not need to be synchronized, + * and encoding ring buffer can have any size, including small ones ( < 64 KB). + * + * Whenever these conditions are not possible, + * save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression, + * then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block. +*/ +LZ4LIB_API int +LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, + const char* src, char* dst, + int srcSize, int dstCapacity); + + +/*! LZ4_decompress_safe_usingDict() : + * Works the same as + * a combination of LZ4_setStreamDecode() followed by LZ4_decompress_safe_continue() + * However, it's stateless: it doesn't need any LZ4_streamDecode_t state. + * Dictionary is presumed stable : it must remain accessible and unmodified during decompression. + * Performance tip : Decompression speed can be substantially increased + * when dst == dictStart + dictSize. + */ +LZ4LIB_API int +LZ4_decompress_safe_usingDict(const char* src, char* dst, + int srcSize, int dstCapacity, + const char* dictStart, int dictSize); + +/*! LZ4_decompress_safe_partial_usingDict() : + * Behaves the same as LZ4_decompress_safe_partial() + * with the added ability to specify a memory segment for past data. + * Performance tip : Decompression speed can be substantially increased + * when dst == dictStart + dictSize. + */ +LZ4LIB_API int +LZ4_decompress_safe_partial_usingDict(const char* src, char* dst, + int compressedSize, + int targetOutputSize, int maxOutputSize, + const char* dictStart, int dictSize); + +#endif /* LZ4_H_2983827168210 */ + + +/*^************************************* + * !!!!!! STATIC LINKING ONLY !!!!!! + ***************************************/ + +/*-**************************************************************************** + * Experimental section + * + * Symbols declared in this section must be considered unstable. Their + * signatures or semantics may change, or they may be removed altogether in the + * future. They are therefore only safe to depend on when the caller is + * statically linked against the library. + * + * To protect against unsafe usage, not only are the declarations guarded, + * the definitions are hidden by default + * when building LZ4 as a shared/dynamic library. + * + * In order to access these declarations, + * define LZ4_STATIC_LINKING_ONLY in your application + * before including LZ4's headers. + * + * In order to make their implementations accessible dynamically, you must + * define LZ4_PUBLISH_STATIC_FUNCTIONS when building the LZ4 library. + ******************************************************************************/ + +#ifdef LZ4_STATIC_LINKING_ONLY + +#ifndef LZ4_STATIC_3504398509 +#define LZ4_STATIC_3504398509 + +#ifdef LZ4_PUBLISH_STATIC_FUNCTIONS +#define LZ4LIB_STATIC_API LZ4LIB_API +#else +#define LZ4LIB_STATIC_API +#endif + + +/*! LZ4_compress_fast_extState_fastReset() : + * A variant of LZ4_compress_fast_extState(). + * + * Using this variant avoids an expensive initialization step. + * It is only safe to call if the state buffer is known to be correctly initialized already + * (see above comment on LZ4_resetStream_fast() for a definition of "correctly initialized"). + * From a high level, the difference is that + * this function initializes the provided state with a call to something like LZ4_resetStream_fast() + * while LZ4_compress_fast_extState() starts with a call to LZ4_resetStream(). + */ +LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); + +/*! LZ4_attach_dictionary() : + * This is an experimental API that allows + * efficient use of a static dictionary many times. + * + * Rather than re-loading the dictionary buffer into a working context before + * each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a + * working LZ4_stream_t, this function introduces a no-copy setup mechanism, + * in which the working stream references the dictionary stream in-place. + * + * Several assumptions are made about the state of the dictionary stream. + * Currently, only streams which have been prepared by LZ4_loadDict() should + * be expected to work. + * + * Alternatively, the provided dictionaryStream may be NULL, + * in which case any existing dictionary stream is unset. + * + * If a dictionary is provided, it replaces any preexisting stream history. + * The dictionary contents are the only history that can be referenced and + * logically immediately precede the data compressed in the first subsequent + * compression call. + * + * The dictionary will only remain attached to the working stream through the + * first compression call, at the end of which it is cleared. The dictionary + * stream (and source buffer) must remain in-place / accessible / unchanged + * through the completion of the first compression call on the stream. + */ +LZ4LIB_STATIC_API void +LZ4_attach_dictionary(LZ4_stream_t* workingStream, + const LZ4_stream_t* dictionaryStream); + + +/*! In-place compression and decompression + * + * It's possible to have input and output sharing the same buffer, + * for highly constrained memory environments. + * In both cases, it requires input to lay at the end of the buffer, + * and decompression to start at beginning of the buffer. + * Buffer size must feature some margin, hence be larger than final size. + * + * |<------------------------buffer--------------------------------->| + * |<-----------compressed data--------->| + * |<-----------decompressed size------------------>| + * |<----margin---->| + * + * This technique is more useful for decompression, + * since decompressed size is typically larger, + * and margin is short. + * + * In-place decompression will work inside any buffer + * which size is >= LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize). + * This presumes that decompressedSize > compressedSize. + * Otherwise, it means compression actually expanded data, + * and it would be more efficient to store such data with a flag indicating it's not compressed. + * This can happen when data is not compressible (already compressed, or encrypted). + * + * For in-place compression, margin is larger, as it must be able to cope with both + * history preservation, requiring input data to remain unmodified up to LZ4_DISTANCE_MAX, + * and data expansion, which can happen when input is not compressible. + * As a consequence, buffer size requirements are much higher, + * and memory savings offered by in-place compression are more limited. + * + * There are ways to limit this cost for compression : + * - Reduce history size, by modifying LZ4_DISTANCE_MAX. + * Note that it is a compile-time constant, so all compressions will apply this limit. + * Lower values will reduce compression ratio, except when input_size < LZ4_DISTANCE_MAX, + * so it's a reasonable trick when inputs are known to be small. + * - Require the compressor to deliver a "maximum compressed size". + * This is the `dstCapacity` parameter in `LZ4_compress*()`. + * When this size is < LZ4_COMPRESSBOUND(inputSize), then compression can fail, + * in which case, the return code will be 0 (zero). + * The caller must be ready for these cases to happen, + * and typically design a backup scheme to send data uncompressed. + * The combination of both techniques can significantly reduce + * the amount of margin required for in-place compression. + * + * In-place compression can work in any buffer + * which size is >= (maxCompressedSize) + * with maxCompressedSize == LZ4_COMPRESSBOUND(srcSize) for guaranteed compression success. + * LZ4_COMPRESS_INPLACE_BUFFER_SIZE() depends on both maxCompressedSize and LZ4_DISTANCE_MAX, + * so it's possible to reduce memory requirements by playing with them. + */ + +#define LZ4_DECOMPRESS_INPLACE_MARGIN(compressedSize) (((compressedSize) >> 8) + 32) +#define LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize) ((decompressedSize) + LZ4_DECOMPRESS_INPLACE_MARGIN(decompressedSize)) /**< note: presumes that compressedSize < decompressedSize. note2: margin is overestimated a bit, since it could use compressedSize instead */ + +#ifndef LZ4_DISTANCE_MAX /* history window size; can be user-defined at compile time */ +# define LZ4_DISTANCE_MAX 65535 /* set to maximum value by default */ +#endif + +#define LZ4_COMPRESS_INPLACE_MARGIN (LZ4_DISTANCE_MAX + 32) /* LZ4_DISTANCE_MAX can be safely replaced by srcSize when it's smaller */ +#define LZ4_COMPRESS_INPLACE_BUFFER_SIZE(maxCompressedSize) ((maxCompressedSize) + LZ4_COMPRESS_INPLACE_MARGIN) /**< maxCompressedSize is generally LZ4_COMPRESSBOUND(inputSize), but can be set to any lower value, with the risk that compression can fail (return code 0(zero)) */ + +#endif /* LZ4_STATIC_3504398509 */ +#endif /* LZ4_STATIC_LINKING_ONLY */ + + + +#ifndef LZ4_H_98237428734687 +#define LZ4_H_98237428734687 + +/*-************************************************************ + * Private Definitions + ************************************************************** + * Do not use these definitions directly. + * They are only exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`. + * Accessing members will expose user code to API and/or ABI break in future versions of the library. + **************************************************************/ +#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) +#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) +#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ + +#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# include + typedef int8_t LZ4_i8; + typedef uint8_t LZ4_byte; + typedef uint16_t LZ4_u16; + typedef uint32_t LZ4_u32; +#else + typedef signed char LZ4_i8; + typedef unsigned char LZ4_byte; + typedef unsigned short LZ4_u16; + typedef unsigned int LZ4_u32; +#endif + +/*! LZ4_stream_t : + * Never ever use below internal definitions directly ! + * These definitions are not API/ABI safe, and may change in future versions. + * If you need static allocation, declare or allocate an LZ4_stream_t object. +**/ + +typedef struct LZ4_stream_t_internal LZ4_stream_t_internal; +struct LZ4_stream_t_internal { + LZ4_u32 hashTable[LZ4_HASH_SIZE_U32]; + const LZ4_byte* dictionary; + const LZ4_stream_t_internal* dictCtx; + LZ4_u32 currentOffset; + LZ4_u32 tableType; + LZ4_u32 dictSize; + /* Implicit padding to ensure structure is aligned */ +}; + +#define LZ4_STREAM_MINSIZE ((1UL << LZ4_MEMORY_USAGE) + 32) /* static size, for inter-version compatibility */ +union LZ4_stream_u { + char minStateSize[LZ4_STREAM_MINSIZE]; + LZ4_stream_t_internal internal_donotuse; +}; /* previously typedef'd to LZ4_stream_t */ + + +/*! LZ4_initStream() : v1.9.0+ + * An LZ4_stream_t structure must be initialized at least once. + * This is automatically done when invoking LZ4_createStream(), + * but it's not when the structure is simply declared on stack (for example). + * + * Use LZ4_initStream() to properly initialize a newly declared LZ4_stream_t. + * It can also initialize any arbitrary buffer of sufficient size, + * and will @return a pointer of proper type upon initialization. + * + * Note : initialization fails if size and alignment conditions are not respected. + * In which case, the function will @return NULL. + * Note2: An LZ4_stream_t structure guarantees correct alignment and size. + * Note3: Before v1.9.0, use LZ4_resetStream() instead +**/ +LZ4LIB_API LZ4_stream_t* LZ4_initStream (void* buffer, size_t size); + + +/*! LZ4_streamDecode_t : + * Never ever use below internal definitions directly ! + * These definitions are not API/ABI safe, and may change in future versions. + * If you need static allocation, declare or allocate an LZ4_streamDecode_t object. +**/ +typedef struct { + const LZ4_byte* externalDict; + const LZ4_byte* prefixEnd; + size_t extDictSize; + size_t prefixSize; +} LZ4_streamDecode_t_internal; + +#define LZ4_STREAMDECODE_MINSIZE 32 +union LZ4_streamDecode_u { + char minStateSize[LZ4_STREAMDECODE_MINSIZE]; + LZ4_streamDecode_t_internal internal_donotuse; +} ; /* previously typedef'd to LZ4_streamDecode_t */ + + + +/*-************************************ +* Obsolete Functions +**************************************/ + +/*! Deprecation warnings + * + * Deprecated functions make the compiler generate a warning when invoked. + * This is meant to invite users to update their source code. + * Should deprecation warnings be a problem, it is generally possible to disable them, + * typically with -Wno-deprecated-declarations for gcc + * or _CRT_SECURE_NO_WARNINGS in Visual. + * + * Another method is to define LZ4_DISABLE_DEPRECATE_WARNINGS + * before including the header file. + */ +#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS +# define LZ4_DEPRECATED(message) /* disable deprecation warnings */ +#else +# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ +# define LZ4_DEPRECATED(message) [[deprecated(message)]] +# elif defined(_MSC_VER) +# define LZ4_DEPRECATED(message) __declspec(deprecated(message)) +# elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ * 10 + __GNUC_MINOR__ >= 45)) +# define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) +# elif defined(__GNUC__) && (__GNUC__ * 10 + __GNUC_MINOR__ >= 31) +# define LZ4_DEPRECATED(message) __attribute__((deprecated)) +# else +# pragma message("WARNING: LZ4_DEPRECATED needs custom implementation for this compiler") +# define LZ4_DEPRECATED(message) /* disabled */ +# endif +#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */ + +/*! Obsolete compression functions (since v1.7.3) */ +LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress (const char* src, char* dest, int srcSize); +LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput (const char* src, char* dest, int srcSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); + +/*! Obsolete decompression functions (since v1.8.0) */ +LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize); +LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); + +/* Obsolete streaming functions (since v1.7.0) + * degraded functionality; do not use! + * + * In order to perform streaming compression, these functions depended on data + * that is no longer tracked in the state. They have been preserved as well as + * possible: using them will still produce a correct output. However, they don't + * actually retain any history between compression calls. The compression ratio + * achieved will therefore be no better than compressing each chunk + * independently. + */ +LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer); +LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void); +LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer); +LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state); + +/*! Obsolete streaming decoding functions (since v1.7.0) */ +LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize); +LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize); + +/*! Obsolete LZ4_decompress_fast variants (since v1.9.0) : + * These functions used to be faster than LZ4_decompress_safe(), + * but this is no longer the case. They are now slower. + * This is because LZ4_decompress_fast() doesn't know the input size, + * and therefore must progress more cautiously into the input buffer to not read beyond the end of block. + * On top of that `LZ4_decompress_fast()` is not protected vs malformed or malicious inputs, making it a security liability. + * As a consequence, LZ4_decompress_fast() is strongly discouraged, and deprecated. + * + * The last remaining LZ4_decompress_fast() specificity is that + * it can decompress a block without knowing its compressed size. + * Such functionality can be achieved in a more secure manner + * by employing LZ4_decompress_safe_partial(). + * + * Parameters: + * originalSize : is the uncompressed size to regenerate. + * `dst` must be already allocated, its size must be >= 'originalSize' bytes. + * @return : number of bytes read from source buffer (== compressed size). + * The function expects to finish at block's end exactly. + * If the source stream is detected malformed, the function stops decoding and returns a negative result. + * note : LZ4_decompress_fast*() requires originalSize. Thanks to this information, it never writes past the output buffer. + * However, since it doesn't know its 'src' size, it may read an unknown amount of input, past input buffer bounds. + * Also, since match offsets are not validated, match reads from 'src' may underflow too. + * These issues never happen if input (compressed) data is correct. + * But they may happen if input data is invalid (error or intentional tampering). + * As a consequence, use these functions in trusted environments with trusted data **only**. + */ +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe() instead") +LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize); +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_continue() instead") +LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize); +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_usingDict() instead") +LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize); + +/*! LZ4_resetStream() : + * An LZ4_stream_t structure must be initialized at least once. + * This is done with LZ4_initStream(), or LZ4_resetStream(). + * Consider switching to LZ4_initStream(), + * invoking LZ4_resetStream() will trigger deprecation warnings in the future. + */ +LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr); + + +#endif /* LZ4_H_98237428734687 */ + + +#if defined (__cplusplus) +} +#endif + +#endif /* LV_USE_LZ4_INTERNAL */ + diff --git a/test/include/liblvgl/libs/qrcode/lv_qrcode.h b/test/include/liblvgl/libs/qrcode/lv_qrcode.h new file mode 100644 index 00000000..ba9b0e86 --- /dev/null +++ b/test/include/liblvgl/libs/qrcode/lv_qrcode.h @@ -0,0 +1,85 @@ +/** + * @file lv_qrcode.h + * + */ + +#ifndef LV_QRCODE_H +#define LV_QRCODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../misc/lv_color.h" +#include "../../misc/lv_types.h" +#include "../../widgets/canvas/lv_canvas.h" +#include LV_STDBOOL_INCLUDE +#include LV_STDINT_INCLUDE +#if LV_USE_QRCODE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_qrcode_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an empty QR code (an `lv_canvas`) object. + * @param parent point to an object where to create the QR code + * @return pointer to the created QR code object + */ +lv_obj_t * lv_qrcode_create(lv_obj_t * parent); + +/** + * Set QR code size. + * @param obj pointer to a QR code object + * @param size width and height of the QR code + */ +void lv_qrcode_set_size(lv_obj_t * obj, int32_t size); + +/** + * Set QR code dark color. + * @param obj pointer to a QR code object + * @param color dark color of the QR code + */ +void lv_qrcode_set_dark_color(lv_obj_t * obj, lv_color_t color); + +/** + * Set QR code light color. + * @param obj pointer to a QR code object + * @param color light color of the QR code + */ +void lv_qrcode_set_light_color(lv_obj_t * obj, lv_color_t color); + +/** + * Set the data of a QR code object + * @param obj pointer to a QR code object + * @param data data to display + * @param data_len length of data in bytes + * @return LV_RESULT_OK: if no error; LV_RESULT_INVALID: on error + */ +lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_len); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_QRCODE*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_QRCODE_H*/ diff --git a/test/include/liblvgl/libs/qrcode/lv_qrcode_private.h b/test/include/liblvgl/libs/qrcode/lv_qrcode_private.h new file mode 100644 index 00000000..bcd2c8c5 --- /dev/null +++ b/test/include/liblvgl/libs/qrcode/lv_qrcode_private.h @@ -0,0 +1,52 @@ +/** + * @file lv_qrcode_private.h + * + */ + +#ifndef LV_QRCODE_PRIVATE_H +#define LV_QRCODE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../widgets/canvas/lv_canvas_private.h" +#include "lv_qrcode.h" + +#if LV_USE_QRCODE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/*Data of qrcode*/ +struct _lv_qrcode_t { + lv_canvas_t canvas; + lv_color_t dark_color; + lv_color_t light_color; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_QRCODE */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_QRCODE_PRIVATE_H*/ diff --git a/test/include/liblvgl/libs/qrcode/qrcodegen.h b/test/include/liblvgl/libs/qrcode/qrcodegen.h new file mode 100644 index 00000000..0c7fd115 --- /dev/null +++ b/test/include/liblvgl/libs/qrcode/qrcodegen.h @@ -0,0 +1,324 @@ +/* + * QR Code generator library (C) + * + * Copyright (c) Project Nayuki. (MIT License) + * https://www.nayuki.io/page/qr-code-generator-library + * + * 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. + */ + +#pragma once + +#include "liblvgl/lvgl.h" +#ifdef LV_USE_QRCODE + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * This library creates QR Code symbols, which is a type of two-dimension barcode. + * Invented by Denso Wave and described in the ISO/IEC 18004 standard. + * A QR Code structure is an immutable square grid of black and white cells. + * The library provides functions to create a QR Code from text or binary data. + * The library covers the QR Code Model 2 specification, supporting all versions (sizes) + * from 1 to 40, all 4 error correction levels, and 4 character encoding modes. + * + * Ways to create a QR Code object: + * - High level: Take the payload data and call qrcodegen_encodeText() or qrcodegen_encodeBinary(). + * - Low level: Custom-make the list of segments and call + * qrcodegen_encodeSegments() or qrcodegen_encodeSegmentsAdvanced(). + * (Note that all ways require supplying the desired error correction level and various byte buffers.) + */ + + +/*---- Enum and struct types----*/ + +/* + * The error correction level in a QR Code symbol. + */ +enum qrcodegen_Ecc { + // Must be declared in ascending order of error protection + // so that an internal qrcodegen function works properly + qrcodegen_Ecc_LOW = 0, // The QR Code can tolerate about 7% erroneous codewords + qrcodegen_Ecc_MEDIUM, // The QR Code can tolerate about 15% erroneous codewords + qrcodegen_Ecc_QUARTILE, // The QR Code can tolerate about 25% erroneous codewords + qrcodegen_Ecc_HIGH, // The QR Code can tolerate about 30% erroneous codewords +}; + + +/* + * The mask pattern used in a QR Code symbol. + */ +enum qrcodegen_Mask { + // A special value to tell the QR Code encoder to + // automatically select an appropriate mask pattern + qrcodegen_Mask_AUTO = -1, + // The eight actual mask patterns + qrcodegen_Mask_0 = 0, + qrcodegen_Mask_1, + qrcodegen_Mask_2, + qrcodegen_Mask_3, + qrcodegen_Mask_4, + qrcodegen_Mask_5, + qrcodegen_Mask_6, + qrcodegen_Mask_7, +}; + + +/* + * Describes how a segment's data bits are interpreted. + */ +enum qrcodegen_Mode { + qrcodegen_Mode_NUMERIC = 0x1, + qrcodegen_Mode_ALPHANUMERIC = 0x2, + qrcodegen_Mode_BYTE = 0x4, + qrcodegen_Mode_KANJI = 0x8, + qrcodegen_Mode_ECI = 0x7, +}; + + +/* + * A segment of character/binary/control data in a QR Code symbol. + * The mid-level way to create a segment is to take the payload data + * and call a factory function such as qrcodegen_makeNumeric(). + * The low-level way to create a segment is to custom-make the bit buffer + * and initialize a qrcodegen_Segment struct with appropriate values. + * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data. + * Any segment longer than this is meaningless for the purpose of generating QR Codes. + * Moreover, the maximum allowed bit length is 32767 because + * the largest QR Code (version 40) has 31329 modules. + */ +struct qrcodegen_Segment { + // The mode indicator of this segment. + enum qrcodegen_Mode mode; + + // The length of this segment's unencoded data. Measured in characters for + // numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode. + // Always zero or positive. Not the same as the data's bit length. + int numChars; + + // The data bits of this segment, packed in bitwise big endian. + // Can be null if the bit length is zero. + uint8_t * data; + + // The number of valid data bits used in the buffer. Requires + // 0 <= bitLength <= 32767, and bitLength <= (capacity of data array) * 8. + // The character count (numChars) must agree with the mode and the bit buffer length. + int bitLength; +}; + + + +/*---- Macro constants and functions ----*/ + +#define qrcodegen_VERSION_MIN 1 // The minimum version number supported in the QR Code Model 2 standard +#define qrcodegen_VERSION_MAX 40 // The maximum version number supported in the QR Code Model 2 standard + +// Calculates the number of bytes needed to store any QR Code up to and including the given version number, +// as a compile-time constant. For example, 'uint8_t buffer[qrcodegen_BUFFER_LEN_FOR_VERSION(25)];' +// can store any single QR Code from version 1 to 25 (inclusive). The result fits in an int (or int16). +// Requires qrcodegen_VERSION_MIN <= n <= qrcodegen_VERSION_MAX. +#define qrcodegen_BUFFER_LEN_FOR_VERSION(n) ((((n) * 4 + 17) * ((n) * 4 + 17) + 7) / 8 + 1) + +// The worst-case number of bytes needed to store one QR Code, up to and including +// version 40. This value equals 3918, which is just under 4 kilobytes. +// Use this more convenient value to avoid calculating tighter memory bounds for buffers. +#define qrcodegen_BUFFER_LEN_MAX qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX) + + + +/*---- Functions (high level) to generate QR Codes ----*/ + +/* + * Encodes the given text string to a QR Code, returning true if encoding succeeded. + * If the data is too long to fit in any version in the given range + * at the given ECC level, then false is returned. + * - The input text must be encoded in UTF-8 and contain no NULs. + * - The variables ecl and mask must correspond to enum constant values. + * - Requires 1 <= minVersion <= maxVersion <= 40. + * - The arrays tempBuffer and qrcode must each have a length + * of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion). + * - After the function returns, tempBuffer contains no useful data. + * - If successful, the resulting QR Code may use numeric, + * alphanumeric, or byte mode to encode the text. + * - In the most optimistic case, a QR Code at version 40 with low ECC + * can hold any UTF-8 string up to 2953 bytes, or any alphanumeric string + * up to 4296 characters, or any digit string up to 7089 characters. + * These numbers represent the hard upper limit of the QR Code standard. + * - Please consult the QR Code specification for information on + * data capacities per version, ECC level, and text encoding mode. + */ +bool qrcodegen_encodeText(const char * text, uint8_t tempBuffer[], uint8_t qrcode[], + enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl); + + +/* + * Encodes the given binary data to a QR Code, returning true if encoding succeeded. + * If the data is too long to fit in any version in the given range + * at the given ECC level, then false is returned. + * - The input array range dataAndTemp[0 : dataLen] should normally be + * valid UTF-8 text, but is not required by the QR Code standard. + * - The variables ecl and mask must correspond to enum constant values. + * - Requires 1 <= minVersion <= maxVersion <= 40. + * - The arrays dataAndTemp and qrcode must each have a length + * of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion). + * - After the function returns, the contents of dataAndTemp may have changed, + * and does not represent useful data anymore. + * - If successful, the resulting QR Code will use byte mode to encode the data. + * - In the most optimistic case, a QR Code at version 40 with low ECC can hold any byte + * sequence up to length 2953. This is the hard upper limit of the QR Code standard. + * - Please consult the QR Code specification for information on + * data capacities per version, ECC level, and text encoding mode. + */ +bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[], + enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl); + + +/*---- Functions (low level) to generate QR Codes ----*/ + +/* + * Renders a QR Code representing the given segments at the given error correction level. + * The smallest possible QR Code version is automatically chosen for the output. Returns true if + * QR Code creation succeeded, or false if the data is too long to fit in any version. The ECC level + * of the result may be higher than the ecl argument if it can be done without increasing the version. + * This function allows the user to create a custom sequence of segments that switches + * between modes (such as alphanumeric and byte) to encode text in less space. + * This is a low-level API; the high-level API is qrcodegen_encodeText() and qrcodegen_encodeBinary(). + * To save memory, the segments' data buffers can alias/overlap tempBuffer, and will + * result in them being clobbered, but the QR Code output will still be correct. + * But the qrcode array must not overlap tempBuffer or any segment's data buffer. + */ +bool qrcodegen_encodeSegments(const struct qrcodegen_Segment segs[], size_t len, + enum qrcodegen_Ecc ecl, uint8_t tempBuffer[], uint8_t qrcode[]); + + +/* + * Renders a QR Code representing the given segments with the given encoding parameters. + * Returns true if QR Code creation succeeded, or false if the data is too long to fit in the range of versions. + * The smallest possible QR Code version within the given range is automatically + * chosen for the output. Iff boostEcl is true, then the ECC level of the result + * may be higher than the ecl argument if it can be done without increasing the + * version. The mask number is either between 0 to 7 (inclusive) to force that + * mask, or -1 to automatically choose an appropriate mask (which may be slow). + * This function allows the user to create a custom sequence of segments that switches + * between modes (such as alphanumeric and byte) to encode text in less space. + * This is a low-level API; the high-level API is qrcodegen_encodeText() and qrcodegen_encodeBinary(). + * To save memory, the segments' data buffers can alias/overlap tempBuffer, and will + * result in them being clobbered, but the QR Code output will still be correct. + * But the qrcode array must not overlap tempBuffer or any segment's data buffer. + */ +bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], size_t len, enum qrcodegen_Ecc ecl, + int minVersion, int maxVersion, int mask, bool boostEcl, uint8_t tempBuffer[], uint8_t qrcode[]); + + +/* + * Tests whether the given string can be encoded as a segment in alphanumeric mode. + * A string is encodable iff each character is in the following set: 0 to 9, A to Z + * (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon. + */ +bool qrcodegen_isAlphanumeric(const char * text); + + +/* + * Tests whether the given string can be encoded as a segment in numeric mode. + * A string is encodable iff each character is in the range 0 to 9. + */ +bool qrcodegen_isNumeric(const char * text); + + +/* + * Returns the number of bytes (uint8_t) needed for the data buffer of a segment + * containing the given number of characters using the given mode. Notes: + * - Returns SIZE_MAX on failure, i.e. numChars > INT16_MAX or + * the number of needed bits exceeds INT16_MAX (i.e. 32767). + * - Otherwise, all valid results are in the range [0, ceil(INT16_MAX / 8)], i.e. at most 4096. + * - It is okay for the user to allocate more bytes for the buffer than needed. + * - For byte mode, numChars measures the number of bytes, not Unicode code points. + * - For ECI mode, numChars must be 0, and the worst-case number of bytes is returned. + * An actual ECI segment can have shorter data. For non-ECI modes, the result is exact. + */ +size_t qrcodegen_calcSegmentBufferSize(enum qrcodegen_Mode mode, size_t numChars); + + +/* + * Returns a segment representing the given binary data encoded in + * byte mode. All input byte arrays are acceptable. Any text string + * can be converted to UTF-8 bytes and encoded as a byte mode segment. + */ +struct qrcodegen_Segment qrcodegen_makeBytes(const uint8_t data[], size_t len, uint8_t buf[]); + + +/* + * Returns a segment representing the given string of decimal digits encoded in numeric mode. + */ +struct qrcodegen_Segment qrcodegen_makeNumeric(const char * digits, uint8_t buf[]); + + +/* + * Returns a segment representing the given text string encoded in alphanumeric mode. + * The characters allowed are: 0 to 9, A to Z (uppercase only), space, + * dollar, percent, asterisk, plus, hyphen, period, slash, colon. + */ +struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char * text, uint8_t buf[]); + + +/* + * Returns a segment representing an Extended Channel Interpretation + * (ECI) designator with the given assignment value. + */ +struct qrcodegen_Segment qrcodegen_makeEci(long assignVal, uint8_t buf[]); + + +/*---- Functions to extract raw data from QR Codes ----*/ + +/* + * Returns the side length of the given QR Code, assuming that encoding succeeded. + * The result is in the range [21, 177]. Note that the length of the array buffer + * is related to the side length - every 'uint8_t qrcode[]' must have length at least + * qrcodegen_BUFFER_LEN_FOR_VERSION(version), which equals ceil(size^2 / 8 + 1). + */ +int qrcodegen_getSize(const uint8_t qrcode[]); + + +/* + * Returns the color of the module (pixel) at the given coordinates, which is false + * for white or true for black. The top left corner has the coordinates (x=0, y=0). + * If the given coordinates are out of bounds, then false (white) is returned. + */ +bool qrcodegen_getModule(const uint8_t qrcode[], int x, int y); + +/* + * Returns the qrcode size of the specified version. Returns -1 on failure + */ +int qrcodegen_version2size(int version); +/* + * Returns the min version of the data that can be stored. Returns -1 on failure + */ +int qrcodegen_getMinFitVersion(enum qrcodegen_Ecc ecl, size_t dataLen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/include/liblvgl/libs/rle/lv_rle.h b/test/include/liblvgl/libs/rle/lv_rle.h new file mode 100644 index 00000000..02ab6a34 --- /dev/null +++ b/test/include/liblvgl/libs/rle/lv_rle.h @@ -0,0 +1,46 @@ +/** + * @file lv_rle.h + * + */ + +#ifndef LV_RLE_H +#define LV_RLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_RLE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +uint32_t lv_rle_decompress(const uint8_t * input, + uint32_t input_buff_len, uint8_t * output, + uint32_t output_buff_len, uint8_t blk_size); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_RLE*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_RLE_H*/ diff --git a/test/include/liblvgl/libs/rlottie/lv_rlottie.h b/test/include/liblvgl/libs/rlottie/lv_rlottie.h new file mode 100644 index 00000000..44bcf2ef --- /dev/null +++ b/test/include/liblvgl/libs/rlottie/lv_rlottie.h @@ -0,0 +1,58 @@ +/** + * @file lv_rlottie.h + * + */ + +#ifndef LV_RLOTTIE_H +#define LV_RLOTTIE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_RLOTTIE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_RLOTTIE_CTRL_FORWARD = 0, + LV_RLOTTIE_CTRL_BACKWARD = 1, + LV_RLOTTIE_CTRL_PAUSE = 2, + LV_RLOTTIE_CTRL_PLAY = 0, /* Yes, play = 0 is the default mode */ + LV_RLOTTIE_CTRL_LOOP = 8, +} lv_rlottie_ctrl_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_rlottie_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_obj_t * lv_rlottie_create_from_file(lv_obj_t * parent, int32_t width, int32_t height, const char * path); + +lv_obj_t * lv_rlottie_create_from_raw(lv_obj_t * parent, int32_t width, int32_t height, + const char * rlottie_desc); + +void lv_rlottie_set_play_mode(lv_obj_t * rlottie, const lv_rlottie_ctrl_t ctrl); +void lv_rlottie_set_current_frame(lv_obj_t * rlottie, const size_t goto_frame); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_RLOTTIE*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_RLOTTIE_H*/ diff --git a/test/include/liblvgl/libs/rlottie/lv_rlottie_private.h b/test/include/liblvgl/libs/rlottie/lv_rlottie_private.h new file mode 100644 index 00000000..344c3909 --- /dev/null +++ b/test/include/liblvgl/libs/rlottie/lv_rlottie_private.h @@ -0,0 +1,61 @@ +/** + * @file lv_rlottie_private.h + * + */ + +#ifndef LV_RLOTTIE_PRIVATE_H +#define LV_RLOTTIE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_rlottie.h" +#if LV_USE_RLOTTIE +#include "../../widgets/image/lv_image_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** definition in lottieanimation_capi.c */ +struct Lottie_Animation_S; + +struct _lv_rlottie_t { + lv_image_t img_ext; + struct Lottie_Animation_S * animation; + lv_timer_t * task; + lv_image_dsc_t imgdsc; + size_t total_frames; + size_t current_frame; + size_t framerate; + uint32_t * allocated_buf; + size_t allocated_buffer_size; + size_t scanline_width; + lv_rlottie_ctrl_t play_ctrl; + size_t dest_frame; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_RLOTTIE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_RLOTTIE_PRIVATE_H*/ diff --git a/test/include/liblvgl/libs/svg/lv_svg.h b/test/include/liblvgl/libs/svg/lv_svg.h new file mode 100644 index 00000000..b5a8965c --- /dev/null +++ b/test/include/liblvgl/libs/svg/lv_svg.h @@ -0,0 +1,334 @@ +/** + * @file lv_svg.h + * + */ + +#ifndef LV_SVG_H +#define LV_SVG_H + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_SVG + +#include "../../misc/lv_array.h" +#include "../../misc/lv_tree.h" +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +enum { + LV_SVG_TAG_INVALID = -1, + LV_SVG_TAG_CONTENT, + LV_SVG_TAG_SVG, + LV_SVG_TAG_USE, + LV_SVG_TAG_G, + LV_SVG_TAG_PATH, + LV_SVG_TAG_RECT, + LV_SVG_TAG_CIRCLE, + LV_SVG_TAG_ELLIPSE, + LV_SVG_TAG_LINE, + LV_SVG_TAG_POLYLINE, + LV_SVG_TAG_POLYGON, + LV_SVG_TAG_SOLID_COLOR, + LV_SVG_TAG_LINEAR_GRADIENT, + LV_SVG_TAG_RADIAL_GRADIENT, + LV_SVG_TAG_STOP, + LV_SVG_TAG_DEFS, + LV_SVG_TAG_IMAGE, +#if LV_USE_SVG_ANIMATION + LV_SVG_TAG_MPATH, + LV_SVG_TAG_SET, + LV_SVG_TAG_ANIMATE, + LV_SVG_TAG_ANIMATE_COLOR, + LV_SVG_TAG_ANIMATE_TRANSFORM, + LV_SVG_TAG_ANIMATE_MOTION, +#endif + LV_SVG_TAG_TEXT, + LV_SVG_TAG_TSPAN, + LV_SVG_TAG_TEXT_AREA, +}; +typedef int8_t lv_svg_tag_t; + +enum { + LV_SVG_ATTR_INVALID = 0, + LV_SVG_ATTR_ID, + LV_SVG_ATTR_XML_ID, + LV_SVG_ATTR_VERSION, + LV_SVG_ATTR_BASE_PROFILE, + LV_SVG_ATTR_VIEWBOX, + LV_SVG_ATTR_PRESERVE_ASPECT_RATIO, + LV_SVG_ATTR_VIEWPORT_FILL, + LV_SVG_ATTR_VIEWPORT_FILL_OPACITY, + LV_SVG_ATTR_DISPLAY, + LV_SVG_ATTR_VISIBILITY, + LV_SVG_ATTR_X, + LV_SVG_ATTR_Y, + LV_SVG_ATTR_WIDTH, + LV_SVG_ATTR_HEIGHT, + LV_SVG_ATTR_RX, + LV_SVG_ATTR_RY, + LV_SVG_ATTR_CX, + LV_SVG_ATTR_CY, + LV_SVG_ATTR_R, + LV_SVG_ATTR_X1, + LV_SVG_ATTR_Y1, + LV_SVG_ATTR_X2, + LV_SVG_ATTR_Y2, + LV_SVG_ATTR_POINTS, + LV_SVG_ATTR_D, + LV_SVG_ATTR_PATH_LENGTH, + LV_SVG_ATTR_XLINK_HREF, + LV_SVG_ATTR_FILL, + LV_SVG_ATTR_FILL_RULE, + LV_SVG_ATTR_FILL_OPACITY, + LV_SVG_ATTR_STROKE, + LV_SVG_ATTR_STROKE_WIDTH, + LV_SVG_ATTR_STROKE_LINECAP, + LV_SVG_ATTR_STROKE_LINEJOIN, + LV_SVG_ATTR_STROKE_MITER_LIMIT, + LV_SVG_ATTR_STROKE_DASH_ARRAY, + LV_SVG_ATTR_STROKE_DASH_OFFSET, + LV_SVG_ATTR_STROKE_OPACITY, + LV_SVG_ATTR_OPACITY, + LV_SVG_ATTR_SOLID_COLOR, + LV_SVG_ATTR_SOLID_OPACITY, + LV_SVG_ATTR_GRADIENT_UNITS, + LV_SVG_ATTR_GRADIENT_STOP_OFFSET, + LV_SVG_ATTR_GRADIENT_STOP_COLOR, + LV_SVG_ATTR_GRADIENT_STOP_OPACITY, + LV_SVG_ATTR_FONT_FAMILY, + LV_SVG_ATTR_FONT_STYLE, + LV_SVG_ATTR_FONT_VARIANT, + LV_SVG_ATTR_FONT_WEIGHT, + LV_SVG_ATTR_FONT_SIZE, + LV_SVG_ATTR_TRANSFORM, + LV_SVG_ATTR_TEXT_ANCHOR, +#if LV_USE_SVG_ANIMATION + LV_SVG_ATTR_ATTRIBUTE_NAME, + LV_SVG_ATTR_ATTRIBUTE_TYPE, + LV_SVG_ATTR_BEGIN, + LV_SVG_ATTR_END, + LV_SVG_ATTR_DUR, + LV_SVG_ATTR_MIN, + LV_SVG_ATTR_MAX, + LV_SVG_ATTR_RESTART, + LV_SVG_ATTR_REPEAT_COUNT, + LV_SVG_ATTR_REPEAT_DUR, + LV_SVG_ATTR_CALC_MODE, + LV_SVG_ATTR_VALUES, + LV_SVG_ATTR_KEY_TIMES, + LV_SVG_ATTR_KEY_SPLINES, + LV_SVG_ATTR_KEY_POINTS, + LV_SVG_ATTR_FROM, + LV_SVG_ATTR_TO, + LV_SVG_ATTR_BY, + LV_SVG_ATTR_ADDITIVE, + LV_SVG_ATTR_ACCUMULATE, + LV_SVG_ATTR_PATH, + LV_SVG_ATTR_ROTATE, + LV_SVG_ATTR_TRANSFORM_TYPE, +#endif +}; +typedef uint8_t lv_svg_attr_type_t; + +enum { + LV_SVG_TRANSFORM_TYPE_MATRIX = 1, + LV_SVG_TRANSFORM_TYPE_TRANSLATE, + LV_SVG_TRANSFORM_TYPE_ROTATE, + LV_SVG_TRANSFORM_TYPE_SCALE, + LV_SVG_TRANSFORM_TYPE_SKEW_X, + LV_SVG_TRANSFORM_TYPE_SKEW_Y, +}; +typedef uint8_t lv_svg_transform_type_t; + +#if LV_USE_SVG_ANIMATION +enum { + LV_SVG_ANIM_REMOVE = 0, + LV_SVG_ANIM_FREEZE, +}; + +enum { + LV_SVG_ANIM_RESTART_ALWAYS = 0, + LV_SVG_ANIM_RESTART_WHEN_NOT_ACTIVE, + LV_SVG_ANIM_RESTART_NEVER, +}; + +enum { + LV_SVG_ANIM_CALC_MODE_LINEAR = 0, + LV_SVG_ANIM_CALC_MODE_PACED, + LV_SVG_ANIM_CALC_MODE_SPLINE, + LV_SVG_ANIM_CALC_MODE_DISCRETE, +}; + +enum { + LV_SVG_ANIM_ADDITIVE_REPLACE = 0, + LV_SVG_ANIM_ADDITIVE_SUM, +}; + +enum { + LV_SVG_ANIM_ACCUMULATE_NONE = 0, + LV_SVG_ANIM_ACCUMULATE_SUM, +}; +#endif + +enum { + LV_SVG_ASPECT_RATIO_NONE = 0, + LV_SVG_ASPECT_RATIO_XMIN_YMIN = (1 << 1), + LV_SVG_ASPECT_RATIO_XMID_YMIN = (2 << 1), + LV_SVG_ASPECT_RATIO_XMAX_YMIN = (3 << 1), + LV_SVG_ASPECT_RATIO_XMIN_YMID = (4 << 1), + LV_SVG_ASPECT_RATIO_XMID_YMID = (5 << 1), + LV_SVG_ASPECT_RATIO_XMAX_YMID = (6 << 1), + LV_SVG_ASPECT_RATIO_XMIN_YMAX = (7 << 1), + LV_SVG_ASPECT_RATIO_XMID_YMAX = (8 << 1), + LV_SVG_ASPECT_RATIO_XMAX_YMAX = (9 << 1), +}; + +enum { + LV_SVG_ASPECT_RATIO_OPT_MEET = 0, + LV_SVG_ASPECT_RATIO_OPT_SLICE, +}; +typedef uint32_t lv_svg_aspect_ratio_t; + +typedef struct { + float x; + float y; +} lv_svg_point_t; + +typedef struct { + float m[3][3]; +} lv_svg_matrix_t; + +typedef uint32_t lv_svg_color_t; + +enum { + LV_SVG_FILL_NONZERO = 0, + LV_SVG_FILL_EVENODD, +}; +typedef uint8_t lv_svg_fill_rule_t; + +enum { + LV_SVG_LINE_CAP_BUTT = 0, + LV_SVG_LINE_CAP_SQUARE, + LV_SVG_LINE_CAP_ROUND, +}; +typedef uint8_t lv_svg_line_cap_t; + +enum { + LV_SVG_LINE_JOIN_MITER = 0, + LV_SVG_LINE_JOIN_BEVEL, + LV_SVG_LINE_JOIN_ROUND, +}; +typedef uint8_t lv_svg_line_join_t; + +enum { + LV_SVG_GRADIENT_UNITS_OBJECT = 0, + LV_SVG_GRADIENT_UNITS_USER_SPACE, +}; +typedef uint8_t lv_svg_gradient_units_t; + +typedef union { + int32_t ival; + uint32_t uval; + float fval; + char * sval; + void * val; +} lv_svg_attr_value_t; + +/* + * to simplify list buffer management, allocate enough memory for all data and length. + * | size | data[0] | data[1] | data[2] | ... | + */ +typedef struct { + uint32_t length; + uint8_t data[1]; +} lv_svg_attr_values_list_t; + +/* https://www.w3.org/TR/SVGTiny12/svgudomidl.html */ +enum { + LV_SVG_PATH_CMD_MOVE_TO = 77, + LV_SVG_PATH_CMD_LINE_TO = 76, + LV_SVG_PATH_CMD_CURVE_TO = 67, + LV_SVG_PATH_CMD_QUAD_TO = 81, + LV_SVG_PATH_CMD_CLOSE = 90, +}; + +/* + * to simplify list buffer management, allocate enough memory for all path data and cmd. + * | cmd | data[0] | data[1] | data[2] | ... | + */ +typedef struct { + uint32_t cmd; + uint8_t data[1]; +} lv_svg_attr_path_value_t; + +enum { + LV_SVG_ATTR_VALUE_DATA = 0, + LV_SVG_ATTR_VALUE_PTR, +}; +typedef uint8_t lv_svg_attr_value_type_t; + +enum { + LV_SVG_ATTR_VALUE_NONE = 0, + LV_SVG_ATTR_VALUE_INITIAL, + LV_SVG_ATTR_VALUE_INHERIT, +}; +typedef uint8_t lv_svg_attr_value_class_t; + +typedef struct { + lv_svg_attr_type_t id; + lv_svg_attr_value_type_t val_type; + lv_svg_attr_value_class_t class_type; + lv_svg_attr_value_t value; +} lv_svg_attr_t; + +struct _lv_svg_render_obj; + +typedef struct { + lv_tree_node_t base; + char * xml_id; /* xml_id or content */ + lv_svg_tag_t type; + lv_array_t attrs; + struct _lv_svg_render_obj * render_obj; +} lv_svg_node_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Loading SVG data and creating the DOM tree + * @param svg_data pointer to the SVG data + * @param data_len the SVG data length + */ +lv_svg_node_t * lv_svg_load_data(const char * svg_data, uint32_t data_len); + +/** + * @brief Create an SVG DOM node + * @param parent pointer to the parent node + * @return true: an new SVG DOM node, false: NULL + */ +lv_svg_node_t * lv_svg_node_create(lv_svg_node_t * parent); + +/** + * @brief Delete an SVG DOM subtree + * @param node pointer to an SVG DOM subtree + */ +void lv_svg_node_delete(lv_svg_node_t * node); + +/********************** + * MACROS + **********************/ +#define LV_SVG_NODE_CHILD(n, i) \ + ((lv_svg_node_t *)(LV_TREE_NODE((n))->children[i])) + +#define LV_SVG_NODE(n) ((lv_svg_node_t*)(n)) + +#endif /*LV_USE_SVG*/ + +#endif /*LV_SVG_H*/ diff --git a/test/include/liblvgl/libs/svg/lv_svg_parser.h b/test/include/liblvgl/libs/svg/lv_svg_parser.h new file mode 100644 index 00000000..fc99fe8b --- /dev/null +++ b/test/include/liblvgl/libs/svg/lv_svg_parser.h @@ -0,0 +1,84 @@ +/** + * @file lv_svg_parser.h + * + */ + +#ifndef LV_SVG_PARSER_H +#define LV_SVG_PARSER_H + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_SVG + +#include "lv_svg.h" +#include "lv_svg_token.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_SVG_PARSER_PROCESS = 0, + LV_SVG_PARSER_IGNORE, +} _lv_svg_parser_state_t; + +typedef struct { + uint16_t state; + char * ignore_name; + uint32_t ignore_len; + int32_t dpi; + lv_svg_node_t * doc_root; + lv_svg_node_t * cur_node; +} _lv_svg_parser_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Initialize the SVG parser + * @param parser pointer to a parser object + */ +void _lv_svg_parser_init(_lv_svg_parser_t * parser); + +/** + * @brief Deinitialize the SVG parser + * @param parser pointer to a parser object + */ +void _lv_svg_parser_deinit(_lv_svg_parser_t * parser); + +/** + * @brief Parse an SVG document + * @param parser pointer to a parser object + * @param token pointer to a token object + * @return true: the parsing is finished, false: the parsing is not finished yet. + */ +bool _lv_svg_parser_token(_lv_svg_parser_t * parser, const _lv_svg_token_t * token); + +/** + * @brief Check if the parsing is finished + * @param parser pointer to a parser object + * @return true: the parsing is finished, false: the parsing is not finished yet. + */ +bool _lv_svg_parser_is_finish(_lv_svg_parser_t * parser); + +/** + * @brief Dump the SVG tree + * @param root pointer to the root of the SVG tree + * @param depth the depth of the current node in the tree + */ +void _lv_svg_dump_tree(lv_svg_node_t * root, int depth); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SVG*/ + +#endif /*LV_SVG_PARSER_H*/ diff --git a/test/include/liblvgl/libs/svg/lv_svg_render.h b/test/include/liblvgl/libs/svg/lv_svg_render.h new file mode 100644 index 00000000..13530548 --- /dev/null +++ b/test/include/liblvgl/libs/svg/lv_svg_render.h @@ -0,0 +1,98 @@ +/** + * @file lv_svg_render.h + * + */ + +#ifndef LV_SVG_RENDER_H +#define LV_SVG_RENDER_H + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_SVG && LV_USE_VECTOR_GRAPHIC +#include "lv_svg.h" +#include "../../misc/lv_types.h" +#include "../../draw/lv_draw_vector_private.h" + +/********************* + * DEFINES + *********************/ + +#define LV_SVG_RENDER_OBJ(n) ((lv_svg_render_obj_t*)(n)) + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_svg_render_obj { + struct _lv_svg_render_obj * next; + uint32_t flags; + char * id; + lv_vector_draw_dsc_t dsc; + lv_matrix_t matrix; + + /* for url(XXX) reference */ + struct _lv_svg_render_obj * head; + char * fill_ref; + char * stroke_ref; + void (*set_paint_ref)(struct _lv_svg_render_obj * obj, lv_vector_draw_dsc_t * dsc, + const struct _lv_svg_render_obj * target_obj, bool fill); + + void (*init)(struct _lv_svg_render_obj * obj, const lv_svg_node_t * node); + void (*render)(const struct _lv_svg_render_obj * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix); + void (*set_attr)(struct _lv_svg_render_obj * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr); + void (*get_bounds)(const struct _lv_svg_render_obj * obj, lv_area_t * area); + void (*destroy)(struct _lv_svg_render_obj * obj); +} lv_svg_render_obj_t; + +typedef struct _lv_svg_render_hal { + void (*load_image)(const char * image_url, lv_draw_image_dsc_t * img_dsc); + const char * (*get_font_path)(const char * font_family); +} lv_svg_render_hal_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Initialize the SVG render + * @param hal pointer to a structure with rendering functions + */ +void lv_svg_render_init(const lv_svg_render_hal_t * hal); + +/** + * @brief Create a new SVG render from an SVG document + * @param svg_doc pointer to the SVG document + * @return pointer to the new SVG render object + */ +lv_svg_render_obj_t * lv_svg_render_create(const lv_svg_node_t * svg_doc); + +/** + * @brief Delete an SVG render object + * @param render pointer to the SVG render object to delete + */ +void lv_svg_render_delete(lv_svg_render_obj_t * render); + +/** + * @brief Render an SVG object to a vector graphics + * @param dsc pointer to the vector graphics descriptor + * @param render pointer to the SVG render object to render + */ +void lv_draw_svg_render(lv_vector_dsc_t * dsc, const lv_svg_render_obj_t * render); + +/** + * @brief Draw an SVG document to a layer + * @param layer pointer to the target layer + * @param svg_doc pointer to the SVG document to draw + */ +void lv_draw_svg(lv_layer_t * layer, const lv_svg_node_t * svg_doc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SVG*/ + +#endif /*LV_SVG_RENDER_H*/ diff --git a/test/include/liblvgl/libs/svg/lv_svg_token.h b/test/include/liblvgl/libs/svg/lv_svg_token.h new file mode 100644 index 00000000..1c57b91e --- /dev/null +++ b/test/include/liblvgl/libs/svg/lv_svg_token.h @@ -0,0 +1,70 @@ +/** + * @file lv_svg_token.h + * + */ + +#ifndef LV_SVG_TOKEN_H +#define LV_SVG_TOKEN_H + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_SVG + +#include "../../misc/lv_array.h" + +/********************* + * DEFINES + *********************/ + +#define SVG_TOKEN_LEN(t) ((t)->end - (t)->start) + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_SVG_TOKEN_BEGIN = 0, + LV_SVG_TOKEN_END, + LV_SVG_TOKEN_CONTENT, +} _lv_svg_token_type_t; + +typedef struct { + const char * name_start; + const char * name_end; + const char * value_start; + const char * value_end; +} _lv_svg_token_attr_t; + +typedef struct { + const char * start; + const char * end; + _lv_svg_token_type_t type; + bool flat; + _lv_svg_token_attr_t * cur_attr; + lv_array_t attrs; +} _lv_svg_token_t; + +typedef bool (*svg_token_process)(_lv_svg_token_t * token, void * user_data); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Parse SVG data and call a callback for each token + * @param svg_data pointer to SVG data + * @param len length of the SVG data + * @param cb callback function to be called for each token + * @param user_data custom data to be passed to the callback function + * @return true: SVG data successfully parsed, false: error occurred + */ +bool _lv_svg_tokenizer(const char * svg_data, uint32_t len, svg_token_process cb, void * user_data); + +/********************** + * MACROS + **********************/ +#endif /*LV_USE_SVG*/ + +#endif /*LV_SVG_TOKEN_H*/ diff --git a/test/include/liblvgl/libs/thorvg/add_lvgl_if.sh b/test/include/liblvgl/libs/thorvg/add_lvgl_if.sh new file mode 100644 index 00000000..43ce9030 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/add_lvgl_if.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +#Add LVGL #if LV_USE_THORVG_INTERNAL guard +#Usage +# find -name "*.cpp" | xargs ./add_lvgl_if.sh +# find -name "t*.h" | xargs ./add_lvgl_if.sh + +sed '0,/\*\/$/ {/\*\/$/ {n; s|^|\n#include "../../lv_conf_internal.h"\n#if LV_USE_THORVG_INTERNAL\n|}}' $@ -i + +sed -i -e '$a\ +\ +#endif /* LV_USE_THORVG_INTERNAL */\ +' $@ -i diff --git a/test/include/liblvgl/libs/thorvg/config.h b/test/include/liblvgl/libs/thorvg/config.h new file mode 100644 index 00000000..baa258a4 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/config.h @@ -0,0 +1,15 @@ +/* + * Autogenerated by the Meson build system. + * Do not edit, your changes will be lost. + */ + +#pragma once + +#define THORVG_SW_RASTER_SUPPORT 1 + +#define THORVG_SVG_LOADER_SUPPORT LV_USE_LOTTIE + +#define THORVG_LOTTIE_LOADER_SUPPORT LV_USE_LOTTIE + +#define THORVG_VERSION_STRING "0.13.5" + diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/allocators.h b/test/include/liblvgl/libs/thorvg/rapidjson/allocators.h new file mode 100644 index 00000000..a943cf19 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/allocators.h @@ -0,0 +1,693 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ALLOCATORS_H_ +#define RAPIDJSON_ALLOCATORS_H_ + +#include "rapidjson.h" +#include "internal/meta.h" + +#include +#include + +#if RAPIDJSON_HAS_CXX11 +#include +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Allocator + +/*! \class rapidjson::Allocator + \brief Concept for allocating, resizing and freeing memory block. + + Note that Malloc() and Realloc() are non-static but Free() is static. + + So if an allocator need to support Free(), it needs to put its pointer in + the header of memory block. + +\code +concept Allocator { + static const bool kNeedFree; //!< Whether this allocator needs to call Free(). + + // Allocate a memory block. + // \param size of the memory block in bytes. + // \returns pointer to the memory block. + void* Malloc(size_t size); + + // Resize a memory block. + // \param originalPtr The pointer to current memory block. Null pointer is permitted. + // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) + // \param newSize the new size in bytes. + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); + + // Free a memory block. + // \param pointer to the memory block. Null pointer is permitted. + static void Free(void *ptr); +}; +\endcode +*/ + + +/*! \def RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY + \ingroup RAPIDJSON_CONFIG + \brief User-defined kDefaultChunkCapacity definition. + + User can define this as any \c size that is a power of 2. +*/ + +#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY +#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024) +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// CrtAllocator + +//! C-runtime library allocator. +/*! This class is just wrapper for standard C library memory routines. + \note implements Allocator concept +*/ +class CrtAllocator { +public: + static const bool kNeedFree = true; + void* Malloc(size_t size) { + if (size) // behavior of malloc(0) is implementation defined. + return RAPIDJSON_MALLOC(size); + else + return NULL; // standardize to returning NULL. + } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + (void)originalSize; + if (newSize == 0) { + RAPIDJSON_FREE(originalPtr); + return NULL; + } + return RAPIDJSON_REALLOC(originalPtr, newSize); + } + static void Free(void *ptr) RAPIDJSON_NOEXCEPT { RAPIDJSON_FREE(ptr); } + + bool operator==(const CrtAllocator&) const RAPIDJSON_NOEXCEPT { + return true; + } + bool operator!=(const CrtAllocator&) const RAPIDJSON_NOEXCEPT { + return false; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// MemoryPoolAllocator + +//! Default memory allocator used by the parser and DOM. +/*! This allocator allocate memory blocks from pre-allocated memory chunks. + + It does not free memory blocks. And Realloc() only allocate new memory. + + The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. + + User may also supply a buffer as the first chunk. + + If the user-buffer is full then additional chunks are allocated by BaseAllocator. + + The user-buffer is not deallocated by this allocator. + + \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. + \note implements Allocator concept +*/ +template +class MemoryPoolAllocator { + //! Chunk header for perpending to each chunk. + /*! Chunks are stored as a singly linked list. + */ + struct ChunkHeader { + size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). + size_t size; //!< Current size of allocated memory in bytes. + ChunkHeader *next; //!< Next chunk in the linked list. + }; + + struct SharedData { + ChunkHeader *chunkHead; //!< Head of the chunk linked-list. Only the head chunk serves allocation. + BaseAllocator* ownBaseAllocator; //!< base allocator created by this object. + size_t refcount; + bool ownBuffer; + }; + + static const size_t SIZEOF_SHARED_DATA = RAPIDJSON_ALIGN(sizeof(SharedData)); + static const size_t SIZEOF_CHUNK_HEADER = RAPIDJSON_ALIGN(sizeof(ChunkHeader)); + + static inline ChunkHeader *GetChunkHead(SharedData *shared) + { + return reinterpret_cast(reinterpret_cast(shared) + SIZEOF_SHARED_DATA); + } + static inline uint8_t *GetChunkBuffer(SharedData *shared) + { + return reinterpret_cast(shared->chunkHead) + SIZEOF_CHUNK_HEADER; + } + + static const size_t kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity. + +public: + static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) + static const bool kRefCounted = true; //!< Tell users that this allocator is reference counted on copy + + //! Constructor with chunkSize. + /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + explicit + MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunk_capacity_(chunkSize), + baseAllocator_(baseAllocator ? baseAllocator : RAPIDJSON_NEW(BaseAllocator)()), + shared_(static_cast(baseAllocator_ ? baseAllocator_->Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER) : 0)) + { + RAPIDJSON_ASSERT(baseAllocator_ != 0); + RAPIDJSON_ASSERT(shared_ != 0); + if (baseAllocator) { + shared_->ownBaseAllocator = 0; + } + else { + shared_->ownBaseAllocator = baseAllocator_; + } + shared_->chunkHead = GetChunkHead(shared_); + shared_->chunkHead->capacity = 0; + shared_->chunkHead->size = 0; + shared_->chunkHead->next = 0; + shared_->ownBuffer = true; + shared_->refcount = 1; + } + + //! Constructor with user-supplied buffer. + /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. + + The user buffer will not be deallocated when this allocator is destructed. + + \param buffer User supplied buffer. + \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). + \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunk_capacity_(chunkSize), + baseAllocator_(baseAllocator), + shared_(static_cast(AlignBuffer(buffer, size))) + { + RAPIDJSON_ASSERT(size >= SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER); + shared_->chunkHead = GetChunkHead(shared_); + shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER; + shared_->chunkHead->size = 0; + shared_->chunkHead->next = 0; + shared_->ownBaseAllocator = 0; + shared_->ownBuffer = false; + shared_->refcount = 1; + } + + MemoryPoolAllocator(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT : + chunk_capacity_(rhs.chunk_capacity_), + baseAllocator_(rhs.baseAllocator_), + shared_(rhs.shared_) + { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + ++shared_->refcount; + } + MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT + { + RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0); + ++rhs.shared_->refcount; + this->~MemoryPoolAllocator(); + baseAllocator_ = rhs.baseAllocator_; + chunk_capacity_ = rhs.chunk_capacity_; + shared_ = rhs.shared_; + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + MemoryPoolAllocator(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT : + chunk_capacity_(rhs.chunk_capacity_), + baseAllocator_(rhs.baseAllocator_), + shared_(rhs.shared_) + { + RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0); + rhs.shared_ = 0; + } + MemoryPoolAllocator& operator=(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT + { + RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0); + this->~MemoryPoolAllocator(); + baseAllocator_ = rhs.baseAllocator_; + chunk_capacity_ = rhs.chunk_capacity_; + shared_ = rhs.shared_; + rhs.shared_ = 0; + return *this; + } +#endif + + //! Destructor. + /*! This deallocates all memory chunks, excluding the user-supplied buffer. + */ + ~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT { + if (!shared_) { + // do nothing if moved + return; + } + if (shared_->refcount > 1) { + --shared_->refcount; + return; + } + Clear(); + BaseAllocator *a = shared_->ownBaseAllocator; + if (shared_->ownBuffer) { + baseAllocator_->Free(shared_); + } + RAPIDJSON_DELETE(a); + } + + //! Deallocates all memory chunks, excluding the first/user one. + void Clear() RAPIDJSON_NOEXCEPT { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + for (;;) { + ChunkHeader* c = shared_->chunkHead; + if (!c->next) { + break; + } + shared_->chunkHead = c->next; + baseAllocator_->Free(c); + } + shared_->chunkHead->size = 0; + } + + //! Computes the total capacity of allocated memory chunks. + /*! \return total capacity in bytes. + */ + size_t Capacity() const RAPIDJSON_NOEXCEPT { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + size_t capacity = 0; + for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next) + capacity += c->capacity; + return capacity; + } + + //! Computes the memory blocks allocated. + /*! \return total used bytes. + */ + size_t Size() const RAPIDJSON_NOEXCEPT { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + size_t size = 0; + for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next) + size += c->size; + return size; + } + + //! Whether the allocator is shared. + /*! \return true or false. + */ + bool Shared() const RAPIDJSON_NOEXCEPT { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + return shared_->refcount > 1; + } + + //! Allocates a memory block. (concept Allocator) + void* Malloc(size_t size) { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + if (!size) + return NULL; + + size = RAPIDJSON_ALIGN(size); + if (RAPIDJSON_UNLIKELY(shared_->chunkHead->size + size > shared_->chunkHead->capacity)) + if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size)) + return NULL; + + void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size; + shared_->chunkHead->size += size; + return buffer; + } + + //! Resizes a memory block (concept Allocator) + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + if (originalPtr == 0) + return Malloc(newSize); + + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + if (newSize == 0) + return NULL; + + originalSize = RAPIDJSON_ALIGN(originalSize); + newSize = RAPIDJSON_ALIGN(newSize); + + // Do not shrink if new size is smaller than original + if (originalSize >= newSize) + return originalPtr; + + // Simply expand it if it is the last allocation and there is sufficient space + if (originalPtr == GetChunkBuffer(shared_) + shared_->chunkHead->size - originalSize) { + size_t increment = static_cast(newSize - originalSize); + if (shared_->chunkHead->size + increment <= shared_->chunkHead->capacity) { + shared_->chunkHead->size += increment; + return originalPtr; + } + } + + // Realloc process: allocate and copy memory, do not free original buffer. + if (void* newBuffer = Malloc(newSize)) { + if (originalSize) + std::memcpy(newBuffer, originalPtr, originalSize); + return newBuffer; + } + else + return NULL; + } + + //! Frees a memory block (concept Allocator) + static void Free(void *ptr) RAPIDJSON_NOEXCEPT { (void)ptr; } // Do nothing + + //! Compare (equality) with another MemoryPoolAllocator + bool operator==(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0); + return shared_ == rhs.shared_; + } + //! Compare (inequality) with another MemoryPoolAllocator + bool operator!=(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT { + return !operator==(rhs); + } + +private: + //! Creates a new chunk. + /*! \param capacity Capacity of the chunk in bytes. + \return true if success. + */ + bool AddChunk(size_t capacity) { + if (!baseAllocator_) + shared_->ownBaseAllocator = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)(); + if (ChunkHeader* chunk = static_cast(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity))) { + chunk->capacity = capacity; + chunk->size = 0; + chunk->next = shared_->chunkHead; + shared_->chunkHead = chunk; + return true; + } + else + return false; + } + + static inline void* AlignBuffer(void* buf, size_t &size) + { + RAPIDJSON_NOEXCEPT_ASSERT(buf != 0); + const uintptr_t mask = sizeof(void*) - 1; + const uintptr_t ubuf = reinterpret_cast(buf); + if (RAPIDJSON_UNLIKELY(ubuf & mask)) { + const uintptr_t abuf = (ubuf + mask) & ~mask; + RAPIDJSON_ASSERT(size >= abuf - ubuf); + buf = reinterpret_cast(abuf); + size -= abuf - ubuf; + } + return buf; + } + + size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. + BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. + SharedData *shared_; //!< The shared data of the allocator +}; + +namespace internal { + template + struct IsRefCounted : + public FalseType + { }; + template + struct IsRefCounted::Type> : + public TrueType + { }; +} + +template +inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n) +{ + RAPIDJSON_NOEXCEPT_ASSERT(old_n <= (std::numeric_limits::max)() / sizeof(T) && new_n <= (std::numeric_limits::max)() / sizeof(T)); + return static_cast(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T))); +} + +template +inline T *Malloc(A& a, size_t n = 1) +{ + return Realloc(a, NULL, 0, n); +} + +template +inline void Free(A& a, T *p, size_t n = 1) +{ + static_cast(Realloc(a, p, n, 0)); +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) // std::allocator can safely be inherited +#endif + +template +class StdAllocator : + public std::allocator +{ + typedef std::allocator allocator_type; +#if RAPIDJSON_HAS_CXX11 + typedef std::allocator_traits traits_type; +#else + typedef allocator_type traits_type; +#endif + +public: + typedef BaseAllocator BaseAllocatorType; + + StdAllocator() RAPIDJSON_NOEXCEPT : + allocator_type(), + baseAllocator_() + { } + + StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT : + allocator_type(rhs), + baseAllocator_(rhs.baseAllocator_) + { } + + template + StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT : + allocator_type(rhs), + baseAllocator_(rhs.baseAllocator_) + { } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + StdAllocator(StdAllocator&& rhs) RAPIDJSON_NOEXCEPT : + allocator_type(std::move(rhs)), + baseAllocator_(std::move(rhs.baseAllocator_)) + { } +#endif +#if RAPIDJSON_HAS_CXX11 + using propagate_on_container_move_assignment = std::true_type; + using propagate_on_container_swap = std::true_type; +#endif + + /* implicit */ + StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT : + allocator_type(), + baseAllocator_(allocator) + { } + + ~StdAllocator() RAPIDJSON_NOEXCEPT + { } + + template + struct rebind { + typedef StdAllocator other; + }; + + typedef typename traits_type::size_type size_type; + typedef typename traits_type::difference_type difference_type; + + typedef typename traits_type::value_type value_type; + typedef typename traits_type::pointer pointer; + typedef typename traits_type::const_pointer const_pointer; + +#if RAPIDJSON_HAS_CXX11 + + typedef typename std::add_lvalue_reference::type &reference; + typedef typename std::add_lvalue_reference::type>::type &const_reference; + + pointer address(reference r) const RAPIDJSON_NOEXCEPT + { + return std::addressof(r); + } + const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT + { + return std::addressof(r); + } + + size_type max_size() const RAPIDJSON_NOEXCEPT + { + return traits_type::max_size(*this); + } + + template + void construct(pointer p, Args&&... args) + { + traits_type::construct(*this, p, std::forward(args)...); + } + void destroy(pointer p) + { + traits_type::destroy(*this, p); + } + +#else // !RAPIDJSON_HAS_CXX11 + + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + + pointer address(reference r) const RAPIDJSON_NOEXCEPT + { + return allocator_type::address(r); + } + const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT + { + return allocator_type::address(r); + } + + size_type max_size() const RAPIDJSON_NOEXCEPT + { + return allocator_type::max_size(); + } + + void construct(pointer p, const_reference r) + { + allocator_type::construct(p, r); + } + void destroy(pointer p) + { + allocator_type::destroy(p); + } + +#endif // !RAPIDJSON_HAS_CXX11 + + template + U* allocate(size_type n = 1, const void* = 0) + { + return RAPIDJSON_NAMESPACE::Malloc(baseAllocator_, n); + } + template + void deallocate(U* p, size_type n = 1) + { + RAPIDJSON_NAMESPACE::Free(baseAllocator_, p, n); + } + + pointer allocate(size_type n = 1, const void* = 0) + { + return allocate(n); + } + void deallocate(pointer p, size_type n = 1) + { + deallocate(p, n); + } + +#if RAPIDJSON_HAS_CXX11 + using is_always_equal = std::is_empty; +#endif + + template + bool operator==(const StdAllocator& rhs) const RAPIDJSON_NOEXCEPT + { + return baseAllocator_ == rhs.baseAllocator_; + } + template + bool operator!=(const StdAllocator& rhs) const RAPIDJSON_NOEXCEPT + { + return !operator==(rhs); + } + + //! rapidjson Allocator concept + static const bool kNeedFree = BaseAllocator::kNeedFree; + static const bool kRefCounted = internal::IsRefCounted::Value; + void* Malloc(size_t size) + { + return baseAllocator_.Malloc(size); + } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) + { + return baseAllocator_.Realloc(originalPtr, originalSize, newSize); + } + static void Free(void *ptr) RAPIDJSON_NOEXCEPT + { + BaseAllocator::Free(ptr); + } + +private: + template + friend class StdAllocator; // access to StdAllocator.* + + BaseAllocator baseAllocator_; +}; + +#if !RAPIDJSON_HAS_CXX17 // std::allocator deprecated in C++17 +template +class StdAllocator : + public std::allocator +{ + typedef std::allocator allocator_type; + +public: + typedef BaseAllocator BaseAllocatorType; + + StdAllocator() RAPIDJSON_NOEXCEPT : + allocator_type(), + baseAllocator_() + { } + + StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT : + allocator_type(rhs), + baseAllocator_(rhs.baseAllocator_) + { } + + template + StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT : + allocator_type(rhs), + baseAllocator_(rhs.baseAllocator_) + { } + + /* implicit */ + StdAllocator(const BaseAllocator& baseAllocator) RAPIDJSON_NOEXCEPT : + allocator_type(), + baseAllocator_(baseAllocator) + { } + + ~StdAllocator() RAPIDJSON_NOEXCEPT + { } + + template + struct rebind { + typedef StdAllocator other; + }; + + typedef typename allocator_type::value_type value_type; + +private: + template + friend class StdAllocator; // access to StdAllocator.* + + BaseAllocator baseAllocator_; +}; +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/cursorstreamwrapper.h b/test/include/liblvgl/libs/thorvg/rapidjson/cursorstreamwrapper.h new file mode 100644 index 00000000..fd6513db --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/cursorstreamwrapper.h @@ -0,0 +1,78 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_ +#define RAPIDJSON_CURSORSTREAMWRAPPER_H_ + +#include "stream.h" + +#if defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#if defined(_MSC_VER) && _MSC_VER <= 1800 +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4702) // unreachable code +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + + +//! Cursor stream wrapper for counting line and column number if error exists. +/*! + \tparam InputStream Any stream that implements Stream Concept +*/ +template > +class CursorStreamWrapper : public GenericStreamWrapper { +public: + typedef typename Encoding::Ch Ch; + + CursorStreamWrapper(InputStream& is): + GenericStreamWrapper(is), line_(1), col_(0) {} + + // counting line and column number + Ch Take() { + Ch ch = this->is_.Take(); + if(ch == '\n') { + line_ ++; + col_ = 0; + } else { + col_ ++; + } + return ch; + } + + //! Get the error line number, if error exists. + size_t GetLine() const { return line_; } + //! Get the error column number, if error exists. + size_t GetColumn() const { return col_; } + +private: + size_t line_; //!< Current Line + size_t col_; //!< Current Column +}; + +#if defined(_MSC_VER) && _MSC_VER <= 1800 +RAPIDJSON_DIAG_POP +#endif + +#if defined(__GNUC__) +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/document.h b/test/include/liblvgl/libs/thorvg/rapidjson/document.h new file mode 100644 index 00000000..f18fbd5f --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/document.h @@ -0,0 +1,3043 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_DOCUMENT_H_ +#define RAPIDJSON_DOCUMENT_H_ + +/*! \file document.h */ + +#include "reader.h" +#include "internal/meta.h" +#include "internal/strfunc.h" +#include "memorystream.h" +#include "encodedstream.h" +#include // placement new +#include +#ifdef __cpp_lib_three_way_comparison +#include +#endif + +RAPIDJSON_DIAG_PUSH +#ifdef __clang__ +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(c++98-compat) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_OFF(effc++) +#endif // __GNUC__ + +#ifdef GetObject +// see https://github.com/Tencent/rapidjson/issues/1448 +// a former included windows.h might have defined a macro called GetObject, which affects +// GetObject defined here. This ensures the macro does not get applied +#pragma push_macro("GetObject") +#define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED +#undef GetObject +#endif + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS +#include // std::random_access_iterator_tag +#endif + +#if RAPIDJSON_USE_MEMBERSMAP +#include // std::multimap +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +// Forward declaration. +template +class GenericValue; + +template +class GenericDocument; + +/*! \def RAPIDJSON_DEFAULT_ALLOCATOR + \ingroup RAPIDJSON_CONFIG + \brief Allows to choose default allocator. + + User can define this to use CrtAllocator or MemoryPoolAllocator. +*/ +#ifndef RAPIDJSON_DEFAULT_ALLOCATOR +#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator> +#endif + +/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR + \ingroup RAPIDJSON_CONFIG + \brief Allows to choose default stack allocator for Document. + + User can define this to use CrtAllocator or MemoryPoolAllocator. +*/ +#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR +#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator +#endif + +/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY + \ingroup RAPIDJSON_CONFIG + \brief User defined kDefaultObjectCapacity value. + + User can define this as any natural number. +*/ +#ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY +// number of objects that rapidjson::Value allocates memory for by default +#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16 +#endif + +/*! \def RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY + \ingroup RAPIDJSON_CONFIG + \brief User defined kDefaultArrayCapacity value. + + User can define this as any natural number. +*/ +#ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY +// number of array elements that rapidjson::Value allocates memory for by default +#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16 +#endif + +//! Name-value pair in a JSON object value. +/*! + This class was internal to GenericValue. It used to be a inner struct. + But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. + https://code.google.com/p/rapidjson/issues/detail?id=64 +*/ +template +class GenericMember { +public: + GenericValue name; //!< name of member (must be a string) + GenericValue value; //!< value of member. + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT + : name(std::move(rhs.name)), + value(std::move(rhs.value)) + { + } + + //! Move assignment in C++11 + GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT { + return *this = static_cast(rhs); + } +#endif + + //! Assignment with move semantics. + /*! \param rhs Source of the assignment. Its name and value will become a null value after assignment. + */ + GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT { + if (RAPIDJSON_LIKELY(this != &rhs)) { + name = rhs.name; + value = rhs.value; + } + return *this; + } + + // swap() for std::sort() and other potential use in STL. + friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT { + a.name.Swap(b.name); + a.value.Swap(b.value); + } + +private: + //! Copy constructor is not permitted. + GenericMember(const GenericMember& rhs); +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericMemberIterator + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS + +//! (Constant) member iterator for a JSON object value +/*! + \tparam Const Is this a constant iterator? + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. + + This class implements a Random Access Iterator for GenericMember elements + of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. + + \note This iterator implementation is mainly intended to avoid implicit + conversions from iterator values to \c NULL, + e.g. from GenericValue::FindMember. + + \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a + pointer-based implementation, if your platform doesn't provide + the C++ header. + + \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator + */ +template +class GenericMemberIterator { + + friend class GenericValue; + template friend class GenericMemberIterator; + + typedef GenericMember PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + +public: + //! Iterator type itself + typedef GenericMemberIterator Iterator; + //! Constant iterator type + typedef GenericMemberIterator ConstIterator; + //! Non-constant iterator type + typedef GenericMemberIterator NonConstIterator; + + /** \name std::iterator_traits support */ + //@{ + typedef ValueType value_type; + typedef ValueType * pointer; + typedef ValueType & reference; + typedef std::ptrdiff_t difference_type; + typedef std::random_access_iterator_tag iterator_category; + //@} + + //! Pointer to (const) GenericMember + typedef pointer Pointer; + //! Reference to (const) GenericMember + typedef reference Reference; + //! Signed integer type (e.g. \c ptrdiff_t) + typedef difference_type DifferenceType; + + //! Default constructor (singular value) + /*! Creates an iterator pointing to no element. + \note All operations, except for comparisons, are undefined on such values. + */ + GenericMemberIterator() : ptr_() {} + + //! Iterator conversions to more const + /*! + \param it (Non-const) iterator to copy from + + Allows the creation of an iterator from another GenericMemberIterator + that is "less const". Especially, creating a non-constant iterator + from a constant iterator are disabled: + \li const -> non-const (not ok) + \li const -> const (ok) + \li non-const -> const (ok) + \li non-const -> non-const (ok) + + \note If the \c Const template parameter is already \c false, this + constructor effectively defines a regular copy-constructor. + Otherwise, the copy constructor is implicitly defined. + */ + GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} + Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; } + + //! @name stepping + //@{ + Iterator& operator++(){ ++ptr_; return *this; } + Iterator& operator--(){ --ptr_; return *this; } + Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } + Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } + //@} + + //! @name increment/decrement + //@{ + Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } + Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } + + Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } + Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } + //@} + + //! @name relations + //@{ + template bool operator==(const GenericMemberIterator& that) const { return ptr_ == that.ptr_; } + template bool operator!=(const GenericMemberIterator& that) const { return ptr_ != that.ptr_; } + template bool operator<=(const GenericMemberIterator& that) const { return ptr_ <= that.ptr_; } + template bool operator>=(const GenericMemberIterator& that) const { return ptr_ >= that.ptr_; } + template bool operator< (const GenericMemberIterator& that) const { return ptr_ < that.ptr_; } + template bool operator> (const GenericMemberIterator& that) const { return ptr_ > that.ptr_; } + +#ifdef __cpp_lib_three_way_comparison + template std::strong_ordering operator<=>(const GenericMemberIterator& that) const { return ptr_ <=> that.ptr_; } +#endif + //@} + + //! @name dereference + //@{ + Reference operator*() const { return *ptr_; } + Pointer operator->() const { return ptr_; } + Reference operator[](DifferenceType n) const { return ptr_[n]; } + //@} + + //! Distance + DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } + +private: + //! Internal constructor from plain pointer + explicit GenericMemberIterator(Pointer p) : ptr_(p) {} + + Pointer ptr_; //!< raw pointer +}; + +#else // RAPIDJSON_NOMEMBERITERATORCLASS + +// class-based member iterator implementation disabled, use plain pointers + +template +class GenericMemberIterator; + +//! non-const GenericMemberIterator +template +class GenericMemberIterator { +public: + //! use plain pointer as iterator type + typedef GenericMember* Iterator; +}; +//! const GenericMemberIterator +template +class GenericMemberIterator { +public: + //! use plain const pointer as iterator type + typedef const GenericMember* Iterator; +}; + +#endif // RAPIDJSON_NOMEMBERITERATORCLASS + +/////////////////////////////////////////////////////////////////////////////// +// GenericStringRef + +//! Reference to a constant string (not taking a copy) +/*! + \tparam CharType character type of the string + + This helper class is used to automatically infer constant string + references for string literals, especially from \c const \b (!) + character arrays. + + The main use is for creating JSON string values without copying the + source string via an \ref Allocator. This requires that the referenced + string pointers have a sufficient lifetime, which exceeds the lifetime + of the associated GenericValue. + + \b Example + \code + Value v("foo"); // ok, no need to copy & calculate length + const char foo[] = "foo"; + v.SetString(foo); // ok + + const char* bar = foo; + // Value x(bar); // not ok, can't rely on bar's lifetime + Value x(StringRef(bar)); // lifetime explicitly guaranteed by user + Value y(StringRef(bar, 3)); // ok, explicitly pass length + \endcode + + \see StringRef, GenericValue::SetString +*/ +template +struct GenericStringRef { + typedef CharType Ch; //!< character type of the string + + //! Create string reference from \c const character array +#ifndef __clang__ // -Wdocumentation + /*! + This constructor implicitly creates a constant string reference from + a \c const character array. It has better performance than + \ref StringRef(const CharType*) by inferring the string \ref length + from the array length, and also supports strings containing null + characters. + + \tparam N length of the string, automatically inferred + + \param str Constant character array, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note Constant complexity. + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ +#endif + template + GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT + : s(str), length(N-1) {} + + //! Explicitly create string reference from \c const character pointer +#ifndef __clang__ // -Wdocumentation + /*! + This constructor can be used to \b explicitly create a reference to + a constant string pointer. + + \see StringRef(const CharType*) + + \param str Constant character pointer, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ +#endif + explicit GenericStringRef(const CharType* str) + : s(str), length(NotNullStrLen(str)) {} + + //! Create constant string reference from pointer and length +#ifndef __clang__ // -Wdocumentation + /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param len length of the string, excluding the trailing NULL terminator + + \post \ref s == str && \ref length == len + \note Constant complexity. + */ +#endif + GenericStringRef(const CharType* str, SizeType len) + : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); } + + GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {} + + //! implicit conversion to plain CharType pointer + operator const Ch *() const { return s; } + + const Ch* const s; //!< plain CharType pointer + const SizeType length; //!< length of the string (excluding the trailing NULL terminator) + +private: + SizeType NotNullStrLen(const CharType* str) { + RAPIDJSON_ASSERT(str != 0); + return internal::StrLen(str); + } + + /// Empty string - used when passing in a NULL pointer + static const Ch emptyString[]; + + //! Disallow construction from non-const array + template + GenericStringRef(CharType (&str)[N]) /* = delete */; + //! Copy assignment operator not permitted - immutable type + GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */; +}; + +template +const CharType GenericStringRef::emptyString[] = { CharType() }; + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + \tparam CharType Character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + + \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember +*/ +template +inline GenericStringRef StringRef(const CharType* str) { + return GenericStringRef(str); +} + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + This version has better performance with supplied length, and also + supports string containing null characters. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param length The length of source string. + \return GenericStringRef string reference object + \relatesalso GenericStringRef +*/ +template +inline GenericStringRef StringRef(const CharType* str, size_t length) { + return GenericStringRef(str, SizeType(length)); +} + +#if RAPIDJSON_HAS_STDSTRING +//! Mark a string object as constant string +/*! Mark a string object (e.g. \c std::string) as a "string literal". + This function can be used to avoid copying a string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. +*/ +template +inline GenericStringRef StringRef(const std::basic_string& str) { + return GenericStringRef(str.data(), SizeType(str.size())); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue type traits +namespace internal { + +template +struct IsGenericValueImpl : FalseType {}; + +// select candidates according to nested encoding and allocator types +template struct IsGenericValueImpl::Type, typename Void::Type> + : IsBaseOf, T>::Type {}; + +// helper to match arbitrary GenericValue instantiations, including derived classes +template struct IsGenericValue : IsGenericValueImpl::Type {}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// TypeHelper + +namespace internal { + +template +struct TypeHelper {}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsBool(); } + static bool Get(const ValueType& v) { return v.GetBool(); } + static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); } + static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt(); } + static int Get(const ValueType& v) { return v.GetInt(); } + static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); } + static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint(); } + static unsigned Get(const ValueType& v) { return v.GetUint(); } + static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); } + static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); } +}; + +#ifdef _MSC_VER +RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int)); +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt(); } + static long Get(const ValueType& v) { return v.GetInt(); } + static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); } + static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); } +}; + +RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned)); +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint(); } + static unsigned long Get(const ValueType& v) { return v.GetUint(); } + static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); } + static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); } +}; +#endif + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt64(); } + static int64_t Get(const ValueType& v) { return v.GetInt64(); } + static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); } + static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint64(); } + static uint64_t Get(const ValueType& v) { return v.GetUint64(); } + static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); } + static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsDouble(); } + static double Get(const ValueType& v) { return v.GetDouble(); } + static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); } + static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsFloat(); } + static float Get(const ValueType& v) { return v.GetFloat(); } + static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); } + static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); } +}; + +template +struct TypeHelper { + typedef const typename ValueType::Ch* StringType; + static bool Is(const ValueType& v) { return v.IsString(); } + static StringType Get(const ValueType& v) { return v.GetString(); } + static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); } + static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } +}; + +#if RAPIDJSON_HAS_STDSTRING +template +struct TypeHelper > { + typedef std::basic_string StringType; + static bool Is(const ValueType& v) { return v.IsString(); } + static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); } + static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } +}; +#endif + +template +struct TypeHelper { + typedef typename ValueType::Array ArrayType; + static bool Is(const ValueType& v) { return v.IsArray(); } + static ArrayType Get(ValueType& v) { return v.GetArray(); } + static ValueType& Set(ValueType& v, ArrayType data) { return v = data; } + static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; } +}; + +template +struct TypeHelper { + typedef typename ValueType::ConstArray ArrayType; + static bool Is(const ValueType& v) { return v.IsArray(); } + static ArrayType Get(const ValueType& v) { return v.GetArray(); } +}; + +template +struct TypeHelper { + typedef typename ValueType::Object ObjectType; + static bool Is(const ValueType& v) { return v.IsObject(); } + static ObjectType Get(ValueType& v) { return v.GetObject(); } + static ValueType& Set(ValueType& v, ObjectType data) { return v = data; } + static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; } +}; + +template +struct TypeHelper { + typedef typename ValueType::ConstObject ObjectType; + static bool Is(const ValueType& v) { return v.IsObject(); } + static ObjectType Get(const ValueType& v) { return v.GetObject(); } +}; + +} // namespace internal + +// Forward declarations +template class GenericArray; +template class GenericObject; + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue + +//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. +/*! + A JSON value can be one of 7 types. This class is a variant type supporting + these types. + + Use the Value if UTF8 and default allocator + + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. +*/ +template +class GenericValue { +public: + //! Name-value pair in an object. + typedef GenericMember Member; + typedef Encoding EncodingType; //!< Encoding type from template parameter. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericStringRef StringRefType; //!< Reference to a constant string + typedef typename GenericMemberIterator::Iterator MemberIterator; //!< Member iterator for iterating in object. + typedef typename GenericMemberIterator::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. + typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. + typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. + typedef GenericValue ValueType; //!< Value type of itself. + typedef GenericArray Array; + typedef GenericArray ConstArray; + typedef GenericObject Object; + typedef GenericObject ConstObject; + + //!@name Constructors and destructor. + //@{ + + //! Default constructor creates a null value. + GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) { + rhs.data_.f.flags = kNullFlag; // give up contents + } +#endif + +private: + //! Copy constructor is not permitted. + GenericValue(const GenericValue& rhs); + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Moving from a GenericDocument is not permitted. + template + GenericValue(GenericDocument&& rhs); + + //! Move assignment from a GenericDocument is not permitted. + template + GenericValue& operator=(GenericDocument&& rhs); +#endif + +public: + + //! Constructor with JSON value type. + /*! This creates a Value of specified type with default content. + \param type Type of the value. + \note Default content for number is zero. + */ + explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() { + static const uint16_t defaultFlags[] = { + kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag, + kNumberAnyFlag + }; + RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType); + data_.f.flags = defaultFlags[type]; + + // Use ShortString to store empty string. + if (type == kStringType) + data_.ss.SetLength(0); + } + + //! Explicit copy constructor (with allocator) + /*! Creates a copy of a Value by using the given Allocator + \tparam SourceAllocator allocator of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). + \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer) + \see CopyFrom() + */ + template + GenericValue(const GenericValue& rhs, Allocator& allocator, bool copyConstStrings = false) { + switch (rhs.GetType()) { + case kObjectType: + DoCopyMembers(rhs, allocator, copyConstStrings); + break; + case kArrayType: { + SizeType count = rhs.data_.a.size; + GenericValue* le = reinterpret_cast(allocator.Malloc(count * sizeof(GenericValue))); + const GenericValue* re = rhs.GetElementsPointer(); + for (SizeType i = 0; i < count; i++) + new (&le[i]) GenericValue(re[i], allocator, copyConstStrings); + data_.f.flags = kArrayFlag; + data_.a.size = data_.a.capacity = count; + SetElementsPointer(le); + } + break; + case kStringType: + if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) { + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + } + else + SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); + break; + default: + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + break; + } + } + + //! Constructor for boolean value. + /*! \param b Boolean value + \note This constructor is limited to \em real boolean values and rejects + implicitly converted types like arbitrary pointers. Use an explicit cast + to \c bool, if you want to construct a boolean JSON value in such cases. + */ +#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen + template + explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame))) RAPIDJSON_NOEXCEPT // See #472 +#else + explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT +#endif + : data_() { + // safe-guard against failing SFINAE + RAPIDJSON_STATIC_ASSERT((internal::IsSame::Value)); + data_.f.flags = b ? kTrueFlag : kFalseFlag; + } + + //! Constructor for int value. + explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() { + data_.n.i64 = i; + data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag; + } + + //! Constructor for unsigned value. + explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() { + data_.n.u64 = u; + data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag); + } + + //! Constructor for int64_t value. + explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() { + data_.n.i64 = i64; + data_.f.flags = kNumberInt64Flag; + if (i64 >= 0) { + data_.f.flags |= kNumberUint64Flag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + data_.f.flags |= kUintFlag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + else if (i64 >= static_cast(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + + //! Constructor for uint64_t value. + explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() { + data_.n.u64 = u64; + data_.f.flags = kNumberUint64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) + data_.f.flags |= kInt64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + data_.f.flags |= kUintFlag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + + //! Constructor for double value. + explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; } + + //! Constructor for float value. + explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast(f); data_.f.flags = kNumberDoubleFlag; } + + //! Constructor for constant string (i.e. do not make a copy of string) + GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); } + + //! Constructor for constant string (i.e. do not make a copy of string) + explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor for copy-string from a string object (i.e. do make a copy of string) + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue(const std::basic_string& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } +#endif + + //! Constructor for Array. + /*! + \param a An array obtained by \c GetArray(). + \note \c Array is always pass-by-value. + \note the source array is moved into this value and the source array becomes empty. + */ + GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) { + a.value_.data_ = Data(); + a.value_.data_.f.flags = kArrayFlag; + } + + //! Constructor for Object. + /*! + \param o An object obtained by \c GetObject(). + \note \c Object is always pass-by-value. + \note the source object is moved into this value and the source object becomes empty. + */ + GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) { + o.value_.data_ = Data(); + o.value_.data_.f.flags = kObjectFlag; + } + + //! Destructor. + /*! Need to destruct elements of array, members of object, or copy-string. + */ + ~GenericValue() { + // With RAPIDJSON_USE_MEMBERSMAP, the maps need to be destroyed to release + // their Allocator if it's refcounted (e.g. MemoryPoolAllocator). + if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 && + internal::IsRefCounted::Value)) { + switch(data_.f.flags) { + case kArrayFlag: + { + GenericValue* e = GetElementsPointer(); + for (GenericValue* v = e; v != e + data_.a.size; ++v) + v->~GenericValue(); + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + Allocator::Free(e); + } + } + break; + + case kObjectFlag: + DoFreeMembers(); + break; + + case kCopyStringFlag: + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + Allocator::Free(const_cast(GetStringPointer())); + } + break; + + default: + break; // Do nothing for other types. + } + } + } + + //@} + + //!@name Assignment operators + //@{ + + //! Assignment with move semantics. + /*! \param rhs Source of the assignment. It will become a null value after assignment. + */ + GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + if (RAPIDJSON_LIKELY(this != &rhs)) { + // Can't destroy "this" before assigning "rhs", otherwise "rhs" + // could be used after free if it's an sub-Value of "this", + // hence the temporary dance. + GenericValue temp; + temp.RawAssign(rhs); + this->~GenericValue(); + RawAssign(temp); + } + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { + return *this = rhs.Move(); + } +#endif + + //! Assignment of constant string reference (no copy) + /*! \param str Constant string reference to be assigned + \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. + \see GenericStringRef, operator=(T) + */ + GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { + GenericValue s(str); + return *this = s; + } + + //! Assignment with primitive types. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value The value to be assigned. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref SetString(const Ch*, Allocator&) (for copying) or + \ref StringRef() (to explicitly mark the pointer as constant) instead. + All other pointer types would implicitly convert to \c bool, + use \ref SetBool() instead. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer), (GenericValue&)) + operator=(T value) { + GenericValue v(value); + return *this = v; + } + + //! Deep-copy assignment from Value + /*! Assigns a \b copy of the Value to the current Value object + \tparam SourceAllocator Allocator type of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator to use for copying + \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer) + */ + template + GenericValue& CopyFrom(const GenericValue& rhs, Allocator& allocator, bool copyConstStrings = false) { + RAPIDJSON_ASSERT(static_cast(this) != static_cast(&rhs)); + this->~GenericValue(); + new (this) GenericValue(rhs, allocator, copyConstStrings); + return *this; + } + + //! Exchange the contents of this value with those of other. + /*! + \param other Another value. + \note Constant complexity. + */ + GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { + GenericValue temp; + temp.RawAssign(*this); + RawAssign(other); + other.RawAssign(temp); + return *this; + } + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.value, b.value); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //! Prepare Value for move semantics + /*! \return *this */ + GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } + //@} + + //!@name Equal-to and not-equal-to operators + //@{ + //! Equal-to operator + /*! + \note If an object contains duplicated named member, comparing equality with any object is always \c false. + \note Complexity is quadratic in Object's member number and linear for the rest (number of all values in the subtree and total lengths of all strings). + */ + template + bool operator==(const GenericValue& rhs) const { + typedef GenericValue RhsType; + if (GetType() != rhs.GetType()) + return false; + + switch (GetType()) { + case kObjectType: // Warning: O(n^2) inner-loop + if (data_.o.size != rhs.data_.o.size) + return false; + for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { + typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); + if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) + return false; + } + return true; + + case kArrayType: + if (data_.a.size != rhs.data_.a.size) + return false; + for (SizeType i = 0; i < data_.a.size; i++) + if ((*this)[i] != rhs[i]) + return false; + return true; + + case kStringType: + return StringEqual(rhs); + + case kNumberType: + if (IsDouble() || rhs.IsDouble()) { + double a = GetDouble(); // May convert from integer to double. + double b = rhs.GetDouble(); // Ditto + return a >= b && a <= b; // Prevent -Wfloat-equal + } + else + return data_.n.u64 == rhs.data_.n.u64; + + default: + return true; + } + } + + //! Equal-to operator with const C-string pointer + bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } + +#if RAPIDJSON_HAS_STDSTRING + //! Equal-to operator with string object + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + bool operator==(const std::basic_string& rhs) const { return *this == GenericValue(StringRef(rhs)); } +#endif + + //! Equal-to operator with primitive types + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr,internal::IsGenericValue >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } + +#ifndef __cpp_impl_three_way_comparison + //! Not-equal-to operator + /*! \return !(*this == rhs) + */ + template + bool operator!=(const GenericValue& rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with const C-string pointer + bool operator!=(const Ch* rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with arbitrary types + /*! \return !(*this == rhs) + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } + + //! Equal-to operator with arbitrary types (symmetric version) + /*! \return (rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } + + //! Not-Equal-to operator with arbitrary types (symmetric version) + /*! \return !(rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } + //@} +#endif + + //!@name Type + //@{ + + Type GetType() const { return static_cast(data_.f.flags & kTypeMask); } + bool IsNull() const { return data_.f.flags == kNullFlag; } + bool IsFalse() const { return data_.f.flags == kFalseFlag; } + bool IsTrue() const { return data_.f.flags == kTrueFlag; } + bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; } + bool IsObject() const { return data_.f.flags == kObjectFlag; } + bool IsArray() const { return data_.f.flags == kArrayFlag; } + bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; } + bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; } + bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; } + bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; } + bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; } + bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; } + bool IsString() const { return (data_.f.flags & kStringFlag) != 0; } + + // Checks whether a number can be losslessly converted to a double. + bool IsLosslessDouble() const { + if (!IsNumber()) return false; + if (IsUint64()) { + uint64_t u = GetUint64(); + volatile double d = static_cast(u); + return (d >= 0.0) + && (d < static_cast((std::numeric_limits::max)())) + && (u == static_cast(d)); + } + if (IsInt64()) { + int64_t i = GetInt64(); + volatile double d = static_cast(i); + return (d >= static_cast((std::numeric_limits::min)())) + && (d < static_cast((std::numeric_limits::max)())) + && (i == static_cast(d)); + } + return true; // double, int, uint are always lossless + } + + // Checks whether a number is a float (possible lossy). + bool IsFloat() const { + if ((data_.f.flags & kDoubleFlag) == 0) + return false; + double d = GetDouble(); + return d >= -3.4028234e38 && d <= 3.4028234e38; + } + // Checks whether a number can be losslessly converted to a float. + bool IsLosslessFloat() const { + if (!IsNumber()) return false; + double a = GetDouble(); + if (a < static_cast(-(std::numeric_limits::max)()) + || a > static_cast((std::numeric_limits::max)())) + return false; + double b = static_cast(static_cast(a)); + return a >= b && a <= b; // Prevent -Wfloat-equal + } + + //@} + + //!@name Null + //@{ + + GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } + + //@} + + //!@name Bool + //@{ + + bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; } + //!< Set boolean value + /*! \post IsBool() == true */ + GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } + + //@} + + //!@name Object + //@{ + + //! Set this value as an empty object. + /*! \post IsObject() == true */ + GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } + + //! Get the number of members in the object. + SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } + + //! Get the capacity of object. + SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; } + + //! Check whether the object is empty. + bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType)) + \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. + Since 0.2, if the name is not correct, it will assert. + If user is unsure whether a member exists, user should use HasMember() first. + A better approach is to use FindMember(). + \note Linear time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(GenericValue&)) operator[](T* name) { + GenericValue n(StringRef(name)); + return (*this)[n]; + } + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast(*this)[name]; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam SourceAllocator Allocator of the \c name value + + \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen(). + And it can also handle strings with embedded null characters. + + \note Linear time complexity. + */ + template + GenericValue& operator[](const GenericValue& name) { + MemberIterator member = FindMember(name); + if (member != MemberEnd()) + return member->value; + else { + RAPIDJSON_ASSERT(false); // see above note + +#if RAPIDJSON_HAS_CXX11 + // Use thread-local storage to prevent races between threads. + // Use static buffer and placement-new to prevent destruction, with + // alignas() to ensure proper alignment. + alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)]; + return *new (buffer) GenericValue(); +#elif defined(_MSC_VER) && _MSC_VER < 1900 + // There's no way to solve both thread locality and proper alignment + // simultaneously. + __declspec(thread) static char buffer[sizeof(GenericValue)]; + return *new (buffer) GenericValue(); +#elif defined(__GNUC__) || defined(__clang__) + // This will generate -Wexit-time-destructors in clang, but that's + // better than having under-alignment. + __thread static GenericValue buffer; + return buffer; +#else + // Don't know what compiler this is, so don't know how to ensure + // thread-locality. + static GenericValue buffer; + return buffer; +#endif + } + } + template + const GenericValue& operator[](const GenericValue& name) const { return const_cast(*this)[name]; } + +#if RAPIDJSON_HAS_STDSTRING + //! Get a value from an object associated with name (string object). + GenericValue& operator[](const std::basic_string& name) { return (*this)[GenericValue(StringRef(name))]; } + const GenericValue& operator[](const std::basic_string& name) const { return (*this)[GenericValue(StringRef(name))]; } +#endif + + //! Const member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); } + //! Const \em past-the-end member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); } + //! Member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); } + //! \em Past-the-end member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); } + + //! Request the object to have enough capacity to store members. + /*! \param newCapacity The capacity that the object at least need to have. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note Linear time complexity. + */ + GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) { + RAPIDJSON_ASSERT(IsObject()); + DoReserveMembers(newCapacity, allocator); + return *this; + } + + //! Check whether a member exists in the object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } + +#if RAPIDJSON_HAS_STDSTRING + //! Check whether a member exists in the object with string object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const std::basic_string& name) const { return FindMember(name) != MemberEnd(); } +#endif + + //! Check whether a member exists in the object with GenericValue name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + template + bool HasMember(const GenericValue& name) const { return FindMember(name) != MemberEnd(); } + + //! Find member by name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + MemberIterator FindMember(const Ch* name) { + GenericValue n(StringRef(name)); + return FindMember(n); + } + + ConstMemberIterator FindMember(const Ch* name) const { return const_cast(*this).FindMember(name); } + + //! Find member by name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + template + MemberIterator FindMember(const GenericValue& name) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + return DoFindMember(name); + } + template ConstMemberIterator FindMember(const GenericValue& name) const { return const_cast(*this).FindMember(name); } + +#if RAPIDJSON_HAS_STDSTRING + //! Find member by string object name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + */ + MemberIterator FindMember(const std::basic_string& name) { return FindMember(GenericValue(StringRef(name))); } + ConstMemberIterator FindMember(const std::basic_string& name) const { return FindMember(GenericValue(StringRef(name))); } +#endif + + //! Add a member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c name and \c value will be transferred to this object on success. + \pre IsObject() && name.IsString() + \post name.IsNull() && value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + DoAddMember(name, value, allocator); + return *this; + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Add a string object as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, std::basic_string& value, Allocator& allocator) { + GenericValue v(value, allocator); + return AddMember(name, v, allocator); + } +#endif + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A string value as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(GenericValue& name, T value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + + //! Add a member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this object on success. + \pre IsObject() + \post value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A constant string reference as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(StringRefType name, T value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Remove all members in the object. + /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void RemoveAllMembers() { + RAPIDJSON_ASSERT(IsObject()); + DoClearMembers(); + } + + //! Remove a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Linear time complexity. + */ + bool RemoveMember(const Ch* name) { + GenericValue n(StringRef(name)); + return RemoveMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string& name) { return RemoveMember(GenericValue(StringRef(name))); } +#endif + + template + bool RemoveMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + RemoveMember(m); + return true; + } + else + return false; + } + + //! Remove a member in object by iterator. + /*! \param m member iterator (obtained by FindMember() or MemberBegin()). + \return the new iterator after removal. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Constant time complexity. + */ + MemberIterator RemoveMember(MemberIterator m) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(GetMembersPointer() != 0); + RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); + return DoRemoveMember(m); + } + + //! Remove a member from an object by iterator. + /*! \param pos iterator to the member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() + \return Iterator following the removed element. + If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. + \note This function preserves the relative order of the remaining object + members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator). + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator pos) { + return EraseMember(pos, pos +1); + } + + //! Remove members in the range [first, last) from an object. + /*! \param first iterator to the first member to remove + \param last iterator following the last member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() + \return Iterator following the last removed element. + \note This function preserves the relative order of the remaining object + members. + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(GetMembersPointer() != 0); + RAPIDJSON_ASSERT(first >= MemberBegin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= MemberEnd()); + return DoEraseMembers(first, last); + } + + //! Erase a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note Linear time complexity. + */ + bool EraseMember(const Ch* name) { + GenericValue n(StringRef(name)); + return EraseMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool EraseMember(const std::basic_string& name) { return EraseMember(GenericValue(StringRef(name))); } +#endif + + template + bool EraseMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + EraseMember(m); + return true; + } + else + return false; + } + + Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); } + Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); } + ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); } + ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); } + + //@} + + //!@name Array + //@{ + + //! Set this value as an empty array. + /*! \post IsArray == true */ + GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } + + //! Get the number of elements in array. + SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } + + //! Get the capacity of array. + SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } + + //! Check whether the array is empty. + bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } + + //! Remove all elements in the array. + /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void Clear() { + RAPIDJSON_ASSERT(IsArray()); + GenericValue* e = GetElementsPointer(); + for (GenericValue* v = e; v != e + data_.a.size; ++v) + v->~GenericValue(); + data_.a.size = 0; + } + + //! Get an element from array by index. + /*! \pre IsArray() == true + \param index Zero-based index of element. + \see operator[](T*) + */ + GenericValue& operator[](SizeType index) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(index < data_.a.size); + return GetElementsPointer()[index]; + } + const GenericValue& operator[](SizeType index) const { return const_cast(*this)[index]; } + + //! Element iterator + /*! \pre IsArray() == true */ + ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); } + //! \em Past-the-end element iterator + /*! \pre IsArray() == true */ + ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; } + //! Constant element iterator + /*! \pre IsArray() == true */ + ConstValueIterator Begin() const { return const_cast(*this).Begin(); } + //! Constant \em past-the-end element iterator + /*! \pre IsArray() == true */ + ConstValueIterator End() const { return const_cast(*this).End(); } + + //! Request the array to have enough capacity to store elements. + /*! \param newCapacity The capacity that the array at least need to have. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note Linear time complexity. + */ + GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (newCapacity > data_.a.capacity) { + SetElementsPointer(reinterpret_cast(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)))); + data_.a.capacity = newCapacity; + } + return *this; + } + + //! Append a GenericValue at the end of the array. + /*! \param value Value to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \post value.IsNull() == true + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this array on success. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + */ + GenericValue& PushBack(GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (data_.a.size >= data_.a.capacity) + Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); + GetElementsPointer()[data_.a.size++].RawAssign(value); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { + return PushBack(value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + //! Append a constant string reference at the end of the array. + /*! \param value Constant string reference to be appended. + \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + \see GenericStringRef + */ + GenericValue& PushBack(StringRefType value, Allocator& allocator) { + return (*this).template PushBack(value, allocator); + } + + //! Append a primitive value at the end of the array. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value Value of primitive type T to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref PushBack(GenericValue&, Allocator&) or \ref + PushBack(StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + PushBack(T value, Allocator& allocator) { + GenericValue v(value); + return PushBack(v, allocator); + } + + //! Remove the last element in the array. + /*! + \note Constant time complexity. + */ + GenericValue& PopBack() { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(!Empty()); + GetElementsPointer()[--data_.a.size].~GenericValue(); + return *this; + } + + //! Remove an element of array by iterator. + /*! + \param pos iterator to the element to remove + \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() + \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator pos) { + return Erase(pos, pos + 1); + } + + //! Remove elements in the range [first, last) of the array. + /*! + \param first iterator to the first element to remove + \param last iterator following the last element to remove + \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() + \return Iterator following the last removed element. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(data_.a.size > 0); + RAPIDJSON_ASSERT(GetElementsPointer() != 0); + RAPIDJSON_ASSERT(first >= Begin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= End()); + ValueIterator pos = Begin() + (first - Begin()); + for (ValueIterator itr = pos; itr != last; ++itr) + itr->~GenericValue(); + std::memmove(static_cast(pos), last, static_cast(End() - last) * sizeof(GenericValue)); + data_.a.size -= static_cast(last - first); + return pos; + } + + Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); } + ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); } + + //@} + + //!@name Number + //@{ + + int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; } + unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; } + int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; } + uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; } + + //! Get the value as double type. + /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the conversion is lossless. + */ + double GetDouble() const { + RAPIDJSON_ASSERT(IsNumber()); + if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. + if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double + if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double + if ((data_.f.flags & kInt64Flag) != 0) return static_cast(data_.n.i64); // int64_t -> double (may lose precision) + RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast(data_.n.u64); // uint64_t -> double (may lose precision) + } + + //! Get the value as float type. + /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the conversion is lossless. + */ + float GetFloat() const { + return static_cast(GetDouble()); + } + + GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } + GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } + GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } + GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } + GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } + GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast(f)); return *this; } + + //@} + + //!@name String + //@{ + + const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); } + + //! Get the length of string. + /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). + */ + SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); } + + //! Set this value as a string without copying source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string pointer. + \param length The length of source string, excluding the trailing null terminator. + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == length + \see SetString(StringRefType) + */ + GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } + + //! Set this value as a string without copying source string. + /*! \param s source string reference + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == s.length + */ + GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } + + //! Set this value as a string by copying from source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string. + \param length The length of source string, excluding the trailing null terminator. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); } + + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); } + + //! Set this value as a string by copying from source string. + /*! \param s source string reference + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s.s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; } + +#if RAPIDJSON_HAS_STDSTRING + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue& SetString(const std::basic_string& s, Allocator& allocator) { return SetString(StringRef(s), allocator); } +#endif + + //@} + + //!@name Array + //@{ + + //! Templated version for checking whether this value is type T. + /*! + \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string + */ + template + bool Is() const { return internal::TypeHelper::Is(*this); } + + template + T Get() const { return internal::TypeHelper::Get(*this); } + + template + T Get() { return internal::TypeHelper::Get(*this); } + + template + ValueType& Set(const T& data) { return internal::TypeHelper::Set(*this, data); } + + template + ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper::Set(*this, data, allocator); } + + //@} + + //! Generate events of this value to a Handler. + /*! This function adopts the GoF visitor pattern. + Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. + It can also be used to deep clone this value via GenericDocument, which is also a Handler. + \tparam Handler type of handler. + \param handler An object implementing concept Handler. + */ + template + bool Accept(Handler& handler) const { + switch(GetType()) { + case kNullType: return handler.Null(); + case kFalseType: return handler.Bool(false); + case kTrueType: return handler.Bool(true); + + case kObjectType: + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) + return false; + for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { + RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator. + if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0))) + return false; + if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler))) + return false; + } + return handler.EndObject(data_.o.size); + + case kArrayType: + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) + return false; + for (ConstValueIterator v = Begin(); v != End(); ++v) + if (RAPIDJSON_UNLIKELY(!v->Accept(handler))) + return false; + return handler.EndArray(data_.a.size); + + case kStringType: + return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0); + + default: + RAPIDJSON_ASSERT(GetType() == kNumberType); + if (IsDouble()) return handler.Double(data_.n.d); + else if (IsInt()) return handler.Int(data_.n.i.i); + else if (IsUint()) return handler.Uint(data_.n.u.u); + else if (IsInt64()) return handler.Int64(data_.n.i64); + else return handler.Uint64(data_.n.u64); + } + } + +private: + template friend class GenericValue; + template friend class GenericDocument; + + enum { + kBoolFlag = 0x0008, + kNumberFlag = 0x0010, + kIntFlag = 0x0020, + kUintFlag = 0x0040, + kInt64Flag = 0x0080, + kUint64Flag = 0x0100, + kDoubleFlag = 0x0200, + kStringFlag = 0x0400, + kCopyFlag = 0x0800, + kInlineStrFlag = 0x1000, + + // Initial flags of different types. + kNullFlag = kNullType, + // These casts are added to suppress the warning on MSVC about bitwise operations between enums of different types. + kTrueFlag = static_cast(kTrueType) | static_cast(kBoolFlag), + kFalseFlag = static_cast(kFalseType) | static_cast(kBoolFlag), + kNumberIntFlag = static_cast(kNumberType) | static_cast(kNumberFlag | kIntFlag | kInt64Flag), + kNumberUintFlag = static_cast(kNumberType) | static_cast(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag), + kNumberInt64Flag = static_cast(kNumberType) | static_cast(kNumberFlag | kInt64Flag), + kNumberUint64Flag = static_cast(kNumberType) | static_cast(kNumberFlag | kUint64Flag), + kNumberDoubleFlag = static_cast(kNumberType) | static_cast(kNumberFlag | kDoubleFlag), + kNumberAnyFlag = static_cast(kNumberType) | static_cast(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag), + kConstStringFlag = static_cast(kStringType) | static_cast(kStringFlag), + kCopyStringFlag = static_cast(kStringType) | static_cast(kStringFlag | kCopyFlag), + kShortStringFlag = static_cast(kStringType) | static_cast(kStringFlag | kCopyFlag | kInlineStrFlag), + kObjectFlag = kObjectType, + kArrayFlag = kArrayType, + + kTypeMask = 0x07 + }; + + static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY; + static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY; + + struct Flag { +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION + char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer +#elif RAPIDJSON_64BIT + char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes +#else + char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes +#endif + uint16_t flags; + }; + + struct String { + SizeType length; + SizeType hashcode; //!< reserved + const Ch* str; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars + // (excluding the terminating zero) and store a value to determine the length of the contained + // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string + // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as + // the string terminator as well. For getting the string length back from that value just use + // "MaxSize - str[LenPos]". + // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode, + // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings). + struct ShortString { + enum { MaxChars = sizeof(static_cast(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; + Ch str[MaxChars]; + + inline static bool Usable(SizeType len) { return (MaxSize >= len); } + inline void SetLength(SizeType len) { str[LenPos] = static_cast(MaxSize - len); } + inline SizeType GetLength() const { return static_cast(MaxSize - str[LenPos]); } + }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // By using proper binary layout, retrieval of different integer types do not need conversions. + union Number { +#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN + struct I { + int i; + char padding[4]; + }i; + struct U { + unsigned u; + char padding2[4]; + }u; +#else + struct I { + char padding[4]; + int i; + }i; + struct U { + char padding2[4]; + unsigned u; + }u; +#endif + int64_t i64; + uint64_t u64; + double d; + }; // 8 bytes + + struct ObjectData { + SizeType size; + SizeType capacity; + Member* members; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + struct ArrayData { + SizeType size; + SizeType capacity; + GenericValue* elements; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + union Data { + String s; + ShortString ss; + Number n; + ObjectData o; + ArrayData a; + Flag f; + }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION + + static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) { + return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str); + } + static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) { + return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length; + } + + RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); } + RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); } + RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); } + RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); } + RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); } + RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); } + +#if RAPIDJSON_USE_MEMBERSMAP + + struct MapTraits { + struct Less { + bool operator()(const Data& s1, const Data& s2) const { + SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2); + int cmp = std::memcmp(DataString(s1), DataString(s2), sizeof(Ch) * (n1 < n2 ? n1 : n2)); + return cmp < 0 || (cmp == 0 && n1 < n2); + } + }; + typedef std::pair Pair; + typedef std::multimap > Map; + typedef typename Map::iterator Iterator; + }; + typedef typename MapTraits::Map Map; + typedef typename MapTraits::Less MapLess; + typedef typename MapTraits::Pair MapPair; + typedef typename MapTraits::Iterator MapIterator; + + // + // Layout of the members' map/array, re(al)located according to the needed capacity: + // + // {Map*}<>{capacity}<>{Member[capacity]}<>{MapIterator[capacity]} + // + // (where <> stands for the RAPIDJSON_ALIGN-ment, if needed) + // + + static RAPIDJSON_FORCEINLINE size_t GetMapLayoutSize(SizeType capacity) { + return RAPIDJSON_ALIGN(sizeof(Map*)) + + RAPIDJSON_ALIGN(sizeof(SizeType)) + + RAPIDJSON_ALIGN(capacity * sizeof(Member)) + + capacity * sizeof(MapIterator); + } + + static RAPIDJSON_FORCEINLINE SizeType &GetMapCapacity(Map* &map) { + return *reinterpret_cast(reinterpret_cast(&map) + + RAPIDJSON_ALIGN(sizeof(Map*))); + } + + static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map* &map) { + return reinterpret_cast(reinterpret_cast(&map) + + RAPIDJSON_ALIGN(sizeof(Map*)) + + RAPIDJSON_ALIGN(sizeof(SizeType))); + } + + static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) { + return reinterpret_cast(reinterpret_cast(&map) + + RAPIDJSON_ALIGN(sizeof(Map*)) + + RAPIDJSON_ALIGN(sizeof(SizeType)) + + RAPIDJSON_ALIGN(GetMapCapacity(map) * sizeof(Member))); + } + + static RAPIDJSON_FORCEINLINE Map* &GetMap(Member* members) { + RAPIDJSON_ASSERT(members != 0); + return *reinterpret_cast(reinterpret_cast(members) - + RAPIDJSON_ALIGN(sizeof(SizeType)) - + RAPIDJSON_ALIGN(sizeof(Map*))); + } + + // Some compilers' debug mechanisms want all iterators to be destroyed, for their accounting.. + RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) { +#if RAPIDJSON_HAS_CXX11 + MapIterator ret = std::move(rhs); +#else + MapIterator ret = rhs; +#endif + rhs.~MapIterator(); + return ret; + } + + Map* &DoReallocMap(Map** oldMap, SizeType newCapacity, Allocator& allocator) { + Map **newMap = static_cast(allocator.Malloc(GetMapLayoutSize(newCapacity))); + GetMapCapacity(*newMap) = newCapacity; + if (!oldMap) { + *newMap = new (allocator.Malloc(sizeof(Map))) Map(MapLess(), allocator); + } + else { + *newMap = *oldMap; + size_t count = (*oldMap)->size(); + std::memcpy(static_cast(GetMapMembers(*newMap)), + static_cast(GetMapMembers(*oldMap)), + count * sizeof(Member)); + MapIterator *oldIt = GetMapIterators(*oldMap), + *newIt = GetMapIterators(*newMap); + while (count--) { + new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count])); + } + Allocator::Free(oldMap); + } + return *newMap; + } + + RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) { + return GetMapMembers(DoReallocMap(0, capacity, allocator)); + } + + void DoReserveMembers(SizeType newCapacity, Allocator& allocator) { + ObjectData& o = data_.o; + if (newCapacity > o.capacity) { + Member* oldMembers = GetMembersPointer(); + Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0, + *&newMap = DoReallocMap(oldMap, newCapacity, allocator); + RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap)); + o.capacity = newCapacity; + } + } + + template + MemberIterator DoFindMember(const GenericValue& name) { + if (Member* members = GetMembersPointer()) { + Map* &map = GetMap(members); + MapIterator mit = map->find(reinterpret_cast(name.data_)); + if (mit != map->end()) { + return MemberIterator(&members[mit->second]); + } + } + return MemberEnd(); + } + + void DoClearMembers() { + if (Member* members = GetMembersPointer()) { + Map* &map = GetMap(members); + MapIterator* mit = GetMapIterators(map); + for (SizeType i = 0; i < data_.o.size; i++) { + map->erase(DropMapIterator(mit[i])); + members[i].~Member(); + } + data_.o.size = 0; + } + } + + void DoFreeMembers() { + if (Member* members = GetMembersPointer()) { + GetMap(members)->~Map(); + for (SizeType i = 0; i < data_.o.size; i++) { + members[i].~Member(); + } + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + Map** map = &GetMap(members); + Allocator::Free(*map); + Allocator::Free(map); + } + } + } + +#else // !RAPIDJSON_USE_MEMBERSMAP + + RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) { + return Malloc(allocator, capacity); + } + + void DoReserveMembers(SizeType newCapacity, Allocator& allocator) { + ObjectData& o = data_.o; + if (newCapacity > o.capacity) { + Member* newMembers = Realloc(allocator, GetMembersPointer(), o.capacity, newCapacity); + RAPIDJSON_SETPOINTER(Member, o.members, newMembers); + o.capacity = newCapacity; + } + } + + template + MemberIterator DoFindMember(const GenericValue& name) { + MemberIterator member = MemberBegin(); + for ( ; member != MemberEnd(); ++member) + if (name.StringEqual(member->name)) + break; + return member; + } + + void DoClearMembers() { + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + data_.o.size = 0; + } + + void DoFreeMembers() { + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + Allocator::Free(GetMembersPointer()); + } + +#endif // !RAPIDJSON_USE_MEMBERSMAP + + void DoAddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { + ObjectData& o = data_.o; + if (o.size >= o.capacity) + DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator); + Member* members = GetMembersPointer(); + Member* m = members + o.size; + m->name.RawAssign(name); + m->value.RawAssign(value); +#if RAPIDJSON_USE_MEMBERSMAP + Map* &map = GetMap(members); + MapIterator* mit = GetMapIterators(map); + new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size))); +#endif + ++o.size; + } + + MemberIterator DoRemoveMember(MemberIterator m) { + ObjectData& o = data_.o; + Member* members = GetMembersPointer(); +#if RAPIDJSON_USE_MEMBERSMAP + Map* &map = GetMap(members); + MapIterator* mit = GetMapIterators(map); + SizeType mpos = static_cast(&*m - members); + map->erase(DropMapIterator(mit[mpos])); +#endif + MemberIterator last(members + (o.size - 1)); + if (o.size > 1 && m != last) { +#if RAPIDJSON_USE_MEMBERSMAP + new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members])); + mit[mpos]->second = mpos; +#endif + *m = *last; // Move the last one to this place + } + else { + m->~Member(); // Only one left, just destroy + } + --o.size; + return m; + } + + MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last) { + ObjectData& o = data_.o; + MemberIterator beg = MemberBegin(), + pos = beg + (first - beg), + end = MemberEnd(); +#if RAPIDJSON_USE_MEMBERSMAP + Map* &map = GetMap(GetMembersPointer()); + MapIterator* mit = GetMapIterators(map); +#endif + for (MemberIterator itr = pos; itr != last; ++itr) { +#if RAPIDJSON_USE_MEMBERSMAP + map->erase(DropMapIterator(mit[itr - beg])); +#endif + itr->~Member(); + } +#if RAPIDJSON_USE_MEMBERSMAP + if (first != last) { + // Move remaining members/iterators + MemberIterator next = pos + (last - first); + for (MemberIterator itr = pos; next != end; ++itr, ++next) { + std::memcpy(static_cast(&*itr), &*next, sizeof(Member)); + SizeType mpos = static_cast(itr - beg); + new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg])); + mit[mpos]->second = mpos; + } + } +#else + std::memmove(static_cast(&*pos), &*last, + static_cast(end - last) * sizeof(Member)); +#endif + o.size -= static_cast(last - first); + return pos; + } + + template + void DoCopyMembers(const GenericValue& rhs, Allocator& allocator, bool copyConstStrings) { + RAPIDJSON_ASSERT(rhs.GetType() == kObjectType); + + data_.f.flags = kObjectFlag; + SizeType count = rhs.data_.o.size; + Member* lm = DoAllocMembers(count, allocator); + const typename GenericValue::Member* rm = rhs.GetMembersPointer(); +#if RAPIDJSON_USE_MEMBERSMAP + Map* &map = GetMap(lm); + MapIterator* mit = GetMapIterators(map); +#endif + for (SizeType i = 0; i < count; i++) { + new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings); + new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings); +#if RAPIDJSON_USE_MEMBERSMAP + new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i))); +#endif + } + data_.o.size = data_.o.capacity = count; + SetMembersPointer(lm); + } + + // Initialize this value as array with initial data, without calling destructor. + void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { + data_.f.flags = kArrayFlag; + if (count) { + GenericValue* e = static_cast(allocator.Malloc(count * sizeof(GenericValue))); + SetElementsPointer(e); + std::memcpy(static_cast(e), values, count * sizeof(GenericValue)); + } + else + SetElementsPointer(0); + data_.a.size = data_.a.capacity = count; + } + + //! Initialize this value as object with initial data, without calling destructor. + void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { + data_.f.flags = kObjectFlag; + if (count) { + Member* m = DoAllocMembers(count, allocator); + SetMembersPointer(m); + std::memcpy(static_cast(m), members, count * sizeof(Member)); +#if RAPIDJSON_USE_MEMBERSMAP + Map* &map = GetMap(m); + MapIterator* mit = GetMapIterators(map); + for (SizeType i = 0; i < count; i++) { + new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i))); + } +#endif + } + else + SetMembersPointer(0); + data_.o.size = data_.o.capacity = count; + } + + //! Initialize this value as constant string, without calling destructor. + void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { + data_.f.flags = kConstStringFlag; + SetStringPointer(s); + data_.s.length = s.length; + } + + //! Initialize this value as copy string with initial data, without calling destructor. + void SetStringRaw(StringRefType s, Allocator& allocator) { + Ch* str = 0; + if (ShortString::Usable(s.length)) { + data_.f.flags = kShortStringFlag; + data_.ss.SetLength(s.length); + str = data_.ss.str; + } else { + data_.f.flags = kCopyStringFlag; + data_.s.length = s.length; + str = static_cast(allocator.Malloc((s.length + 1) * sizeof(Ch))); + SetStringPointer(str); + } + std::memcpy(str, s, s.length * sizeof(Ch)); + str[s.length] = '\0'; + } + + //! Assignment without calling destructor + void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + data_ = rhs.data_; + // data_.f.flags = rhs.data_.f.flags; + rhs.data_.f.flags = kNullFlag; + } + + template + bool StringEqual(const GenericValue& rhs) const { + RAPIDJSON_ASSERT(IsString()); + RAPIDJSON_ASSERT(rhs.IsString()); + + const SizeType len1 = GetStringLength(); + const SizeType len2 = rhs.GetStringLength(); + if(len1 != len2) { return false; } + + const Ch* const str1 = GetString(); + const Ch* const str2 = rhs.GetString(); + if(str1 == str2) { return true; } // fast path for constant string + + return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); + } + + Data data_; +}; + +//! GenericValue with UTF8 encoding +typedef GenericValue > Value; + +/////////////////////////////////////////////////////////////////////////////// +// GenericDocument + +//! A document for parsing JSON text as DOM. +/*! + \note implements Handler concept + \tparam Encoding Encoding for both parsing and string storage. + \tparam Allocator Allocator for allocating memory for the DOM + \tparam StackAllocator Allocator for allocating memory for stack during parsing. + \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. +*/ +template +class GenericDocument : public GenericValue { +public: + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericValue ValueType; //!< Value type of the document. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef StackAllocator StackAllocatorType; //!< StackAllocator type from template parameter. + + //! Constructor + /*! Creates an empty document of specified type. + \param type Mandatory type of object to create. + \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + GenericValue(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + } + + //! Constructor + /*! Creates an empty document which type is Null. + \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + : ValueType(std::forward(rhs)), // explicit cast to avoid prohibited move from Document + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(std::move(rhs.stack_)), + parseResult_(rhs.parseResult_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + } +#endif + + ~GenericDocument() { + // Clear the ::ValueType before ownAllocator is destroyed, ~ValueType() + // runs last and may access its elements or members which would be freed + // with an allocator like MemoryPoolAllocator (CrtAllocator does not + // free its data when destroyed, but MemoryPoolAllocator does). + if (ownAllocator_) { + ValueType::SetNull(); + } + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + { + // The cast to ValueType is necessary here, because otherwise it would + // attempt to call GenericValue's templated assignment operator. + ValueType::operator=(std::forward(rhs)); + + // Calling the destructor here would prematurely call stack_'s destructor + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = std::move(rhs.stack_); + parseResult_ = rhs.parseResult_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + + return *this; + } +#endif + + //! Exchange the contents of this document with those of another. + /*! + \param rhs Another document. + \note Constant complexity. + \see GenericValue::Swap + */ + GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT { + ValueType::Swap(rhs); + stack_.Swap(rhs.stack_); + internal::Swap(allocator_, rhs.allocator_); + internal::Swap(ownAllocator_, rhs.ownAllocator_); + internal::Swap(parseResult_, rhs.parseResult_); + return *this; + } + + // Allow Swap with ValueType. + // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names. + using ValueType::Swap; + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.doc, b.doc); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //! Populate this document by a generator which produces SAX events. + /*! \tparam Generator A functor with bool f(Handler) prototype. + \param g Generator functor which sends SAX events to the parameter. + \return The document itself for fluent API. + */ + template + GenericDocument& Populate(Generator& g) { + ClearStackOnExit scope(*this); + if (g(*this)) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document + } + return *this; + } + + //!@name Parse from stream + //!@{ + + //! Parse JSON text from an input stream (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam SourceEncoding Encoding of input stream + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + GenericReader reader( + stack_.HasAllocator() ? &stack_.GetAllocator() : 0); + ClearStackOnExit scope(*this); + parseResult_ = reader.template Parse(is, *this); + if (parseResult_) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document + } + return *this; + } + + //! Parse JSON text from an input stream + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + + //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + //!@} + + //!@name Parse in-place from mutable string + //!@{ + + //! Parse JSON text from a mutable string + /*! \tparam parseFlags Combination of \ref ParseFlag. + \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseInsitu(Ch* str) { + GenericInsituStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) + /*! \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + GenericDocument& ParseInsitu(Ch* str) { + return ParseInsitu(str); + } + //!@} + + //!@name Parse from read-only string + //!@{ + + //! Parse JSON text from a read-only string (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \tparam SourceEncoding Transcoding from input Encoding + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const typename SourceEncoding::Ch* str) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + GenericStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a read-only string + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) + /*! \param str Read-only zero-terminated string to be parsed. + */ + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + template + GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + MemoryStream ms(reinterpret_cast(str), length * sizeof(typename SourceEncoding::Ch)); + EncodedInputStream is(ms); + ParseStream(is); + return *this; + } + + template + GenericDocument& Parse(const Ch* str, size_t length) { + return Parse(str, length); + } + + GenericDocument& Parse(const Ch* str, size_t length) { + return Parse(str, length); + } + +#if RAPIDJSON_HAS_STDSTRING + template + GenericDocument& Parse(const std::basic_string& str) { + // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t) + return Parse(str.c_str()); + } + + template + GenericDocument& Parse(const std::basic_string& str) { + return Parse(str.c_str()); + } + + GenericDocument& Parse(const std::basic_string& str) { + return Parse(str); + } +#endif // RAPIDJSON_HAS_STDSTRING + + //!@} + + //!@name Handling parse errors + //!@{ + + //! Whether a parse error has occurred in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseError() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + + //! Implicit conversion to get the last parse result +#ifndef __clang // -Wdocumentation + /*! \return \ref ParseResult of the last parse operation + + \code + Document doc; + ParseResult ok = doc.Parse(json); + if (!ok) + printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset()); + \endcode + */ +#endif + operator ParseResult() const { return parseResult_; } + //!@} + + //! Get the allocator of this document. + Allocator& GetAllocator() { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + + //! Get the capacity of stack in bytes. + size_t GetStackCapacity() const { return stack_.GetCapacity(); } + +private: + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} + ~ClearStackOnExit() { d_.ClearStack(); } + private: + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + GenericDocument& d_; + }; + + // callers of the following private Handler functions + // template friend class GenericReader; // for parsing + template friend class GenericValue; // for deep copying + +public: + // Implementation of Handler + bool Null() { new (stack_.template Push()) ValueType(); return true; } + bool Bool(bool b) { new (stack_.template Push()) ValueType(b); return true; } + bool Int(int i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint(unsigned i) { new (stack_.template Push()) ValueType(i); return true; } + bool Int64(int64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Double(double d) { new (stack_.template Push()) ValueType(d); return true; } + + bool RawNumber(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool String(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool StartObject() { new (stack_.template Push()) ValueType(kObjectType); return true; } + + bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount) { + typename ValueType::Member* members = stack_.template Pop(memberCount); + stack_.template Top()->SetObjectRaw(members, memberCount, GetAllocator()); + return true; + } + + bool StartArray() { new (stack_.template Push()) ValueType(kArrayType); return true; } + + bool EndArray(SizeType elementCount) { + ValueType* elements = stack_.template Pop(elementCount); + stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); + return true; + } + +private: + //! Prohibit copying + GenericDocument(const GenericDocument&); + //! Prohibit assignment + GenericDocument& operator=(const GenericDocument&); + + void ClearStack() { + if (Allocator::kNeedFree) + while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) + (stack_.template Pop(1))->~ValueType(); + else + stack_.Clear(); + stack_.ShrinkToFit(); + } + + void Destroy() { + RAPIDJSON_DELETE(ownAllocator_); + } + + static const size_t kDefaultStackCapacity = 1024; + Allocator* allocator_; + Allocator* ownAllocator_; + internal::Stack stack_; + ParseResult parseResult_; +}; + +//! GenericDocument with UTF8 encoding +typedef GenericDocument > Document; + + +//! Helper class for accessing Value of array type. +/*! + Instance of this helper class is obtained by \c GenericValue::GetArray(). + In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. +*/ +template +class GenericArray { +public: + typedef GenericArray ConstArray; + typedef GenericArray Array; + typedef ValueT PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef ValueType* ValueIterator; // This may be const or non-const iterator + typedef const ValueT* ConstValueIterator; + typedef typename ValueType::AllocatorType AllocatorType; + typedef typename ValueType::StringRefType StringRefType; + + template + friend class GenericValue; + + GenericArray(const GenericArray& rhs) : value_(rhs.value_) {} + GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; } + ~GenericArray() {} + + operator ValueType&() const { return value_; } + SizeType Size() const { return value_.Size(); } + SizeType Capacity() const { return value_.Capacity(); } + bool Empty() const { return value_.Empty(); } + void Clear() const { value_.Clear(); } + ValueType& operator[](SizeType index) const { return value_[index]; } + ValueIterator Begin() const { return value_.Begin(); } + ValueIterator End() const { return value_.End(); } + GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; } + GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } + GenericArray PopBack() const { value_.PopBack(); return *this; } + ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); } + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); } + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR + ValueIterator begin() const { return value_.Begin(); } + ValueIterator end() const { return value_.End(); } +#endif + +private: + GenericArray(); + GenericArray(ValueType& value) : value_(value) {} + ValueType& value_; +}; + +//! Helper class for accessing Value of object type. +/*! + Instance of this helper class is obtained by \c GenericValue::GetObject(). + In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. +*/ +template +class GenericObject { +public: + typedef GenericObject ConstObject; + typedef GenericObject Object; + typedef ValueT PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef GenericMemberIterator MemberIterator; // This may be const or non-const iterator + typedef GenericMemberIterator ConstMemberIterator; + typedef typename ValueType::AllocatorType AllocatorType; + typedef typename ValueType::StringRefType StringRefType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename ValueType::Ch Ch; + + template + friend class GenericValue; + + GenericObject(const GenericObject& rhs) : value_(rhs.value_) {} + GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; } + ~GenericObject() {} + + operator ValueType&() const { return value_; } + SizeType MemberCount() const { return value_.MemberCount(); } + SizeType MemberCapacity() const { return value_.MemberCapacity(); } + bool ObjectEmpty() const { return value_.ObjectEmpty(); } + template ValueType& operator[](T* name) const { return value_[name]; } + template ValueType& operator[](const GenericValue& name) const { return value_[name]; } +#if RAPIDJSON_HAS_STDSTRING + ValueType& operator[](const std::basic_string& name) const { return value_[name]; } +#endif + MemberIterator MemberBegin() const { return value_.MemberBegin(); } + MemberIterator MemberEnd() const { return value_.MemberEnd(); } + GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; } + bool HasMember(const Ch* name) const { return value_.HasMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool HasMember(const std::basic_string& name) const { return value_.HasMember(name); } +#endif + template bool HasMember(const GenericValue& name) const { return value_.HasMember(name); } + MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); } + template MemberIterator FindMember(const GenericValue& name) const { return value_.FindMember(name); } +#if RAPIDJSON_HAS_STDSTRING + MemberIterator FindMember(const std::basic_string& name) const { return value_.FindMember(name); } +#endif + GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#if RAPIDJSON_HAS_STDSTRING + GenericObject AddMember(ValueType& name, std::basic_string& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#endif + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + void RemoveAllMembers() { value_.RemoveAllMembers(); } + bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string& name) const { return value_.RemoveMember(name); } +#endif + template bool RemoveMember(const GenericValue& name) const { return value_.RemoveMember(name); } + MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); } + MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); } + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); } + bool EraseMember(const Ch* name) const { return value_.EraseMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool EraseMember(const std::basic_string& name) const { return EraseMember(ValueType(StringRef(name))); } +#endif + template bool EraseMember(const GenericValue& name) const { return value_.EraseMember(name); } + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR + MemberIterator begin() const { return value_.MemberBegin(); } + MemberIterator end() const { return value_.MemberEnd(); } +#endif + +private: + GenericObject(); + GenericObject(ValueType& value) : value_(value) {} + ValueType& value_; +}; + +RAPIDJSON_NAMESPACE_END +RAPIDJSON_DIAG_POP + +#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED +#pragma pop_macro("GetObject") +#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED +#endif + +#endif // RAPIDJSON_DOCUMENT_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/encodedstream.h b/test/include/liblvgl/libs/thorvg/rapidjson/encodedstream.h new file mode 100644 index 00000000..309499dc --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/encodedstream.h @@ -0,0 +1,299 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODEDSTREAM_H_ +#define RAPIDJSON_ENCODEDSTREAM_H_ + +#include "stream.h" +#include "memorystream.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Input byte stream wrapper with a statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam InputByteStream Type of input byte stream. For example, FileReadStream. +*/ +template +class EncodedInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedInputStream(InputByteStream& is) : is_(is) { + current_ = Encoding::TakeBOM(is_); + } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); + + InputByteStream& is_; + Ch current_; +}; + +//! Specialized for UTF8 MemoryStream. +template <> +class EncodedInputStream, MemoryStream> { +public: + typedef UTF8<>::Ch Ch; + + EncodedInputStream(MemoryStream& is) : is_(is) { + if (static_cast(is_.Peek()) == 0xEFu) is_.Take(); + if (static_cast(is_.Peek()) == 0xBBu) is_.Take(); + if (static_cast(is_.Peek()) == 0xBFu) is_.Take(); + } + Ch Peek() const { return is_.Peek(); } + Ch Take() { return is_.Take(); } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) {} + void Flush() {} + Ch* PutBegin() { return 0; } + size_t PutEnd(Ch*) { return 0; } + + MemoryStream& is_; + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); +}; + +//! Output byte stream wrapper with statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream. +*/ +template +class EncodedOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { + if (putBOM) + Encoding::PutBOM(os_); + } + + void Put(Ch c) { Encoding::Put(os_, c); } + void Flush() { os_.Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} + Ch Take() { RAPIDJSON_ASSERT(false); return 0;} + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedOutputStream(const EncodedOutputStream&); + EncodedOutputStream& operator=(const EncodedOutputStream&); + + OutputByteStream& os_; +}; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + +//! Input stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for reading. + \tparam InputByteStream type of input byte stream to be wrapped. +*/ +template +class AutoUTFInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param is input stream to be wrapped. + \param type UTF encoding type if it is not detected from the stream. + */ + AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + DetectType(); + static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; + takeFunc_ = f[type_]; + current_ = takeFunc_(*is_); + } + + UTFType GetType() const { return type_; } + bool HasBOM() const { return hasBOM_; } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } + size_t Tell() const { return is_->Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFInputStream(const AutoUTFInputStream&); + AutoUTFInputStream& operator=(const AutoUTFInputStream&); + + // Detect encoding type with BOM or RFC 4627 + void DetectType() { + // BOM (Byte Order Mark): + // 00 00 FE FF UTF-32BE + // FF FE 00 00 UTF-32LE + // FE FF UTF-16BE + // FF FE UTF-16LE + // EF BB BF UTF-8 + + const unsigned char* c = reinterpret_cast(is_->Peek4()); + if (!c) + return; + + unsigned bom = static_cast(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)); + hasBOM_ = false; + if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } + + // RFC 4627: Section 3 + // "Since the first two characters of a JSON text will always be ASCII + // characters [RFC0020], it is possible to determine whether an octet + // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking + // at the pattern of nulls in the first four octets." + // 00 00 00 xx UTF-32BE + // 00 xx 00 xx UTF-16BE + // xx 00 00 00 UTF-32LE + // xx 00 xx 00 UTF-16LE + // xx xx xx xx UTF-8 + + if (!hasBOM_) { + int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); + switch (pattern) { + case 0x08: type_ = kUTF32BE; break; + case 0x0A: type_ = kUTF16BE; break; + case 0x01: type_ = kUTF32LE; break; + case 0x05: type_ = kUTF16LE; break; + case 0x0F: type_ = kUTF8; break; + default: break; // Use type defined by user. + } + } + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + } + + typedef Ch (*TakeFunc)(InputByteStream& is); + InputByteStream* is_; + UTFType type_; + Ch current_; + TakeFunc takeFunc_; + bool hasBOM_; +}; + +//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for writing. + \tparam OutputByteStream type of output byte stream to be wrapped. +*/ +template +class AutoUTFOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param os output stream to be wrapped. + \param type UTF encoding type. + \param putBOM Whether to write BOM at the beginning of the stream. + */ + AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + + static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; + putFunc_ = f[type_]; + + if (putBOM) + PutBOM(); + } + + UTFType GetType() const { return type_; } + + void Put(Ch c) { putFunc_(*os_, c); } + void Flush() { os_->Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} + Ch Take() { RAPIDJSON_ASSERT(false); return 0;} + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFOutputStream(const AutoUTFOutputStream&); + AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); + + void PutBOM() { + typedef void (*PutBOMFunc)(OutputByteStream&); + static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; + f[type_](*os_); + } + + typedef void (*PutFunc)(OutputByteStream&, Ch); + + OutputByteStream* os_; + UTFType type_; + PutFunc putFunc_; +}; + +#undef RAPIDJSON_ENCODINGS_FUNC + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/encodings.h b/test/include/liblvgl/libs/thorvg/rapidjson/encodings.h new file mode 100644 index 00000000..5ee169e1 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/encodings.h @@ -0,0 +1,716 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODINGS_H_ +#define RAPIDJSON_ENCODINGS_H_ + +#include "rapidjson.h" + +#if defined(_MSC_VER) && !defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#elif defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(overflow) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Encoding + +/*! \class rapidjson::Encoding + \brief Concept for encoding of Unicode characters. + +\code +concept Encoding { + typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. + + enum { supportUnicode = 1 }; // or 0 if not supporting unicode + + //! \brief Encode a Unicode codepoint to an output stream. + //! \param os Output stream. + //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. + template + static void Encode(OutputStream& os, unsigned codepoint); + + //! \brief Decode a Unicode codepoint from an input stream. + //! \param is Input stream. + //! \param codepoint Output of the unicode codepoint. + //! \return true if a valid codepoint can be decoded from the stream. + template + static bool Decode(InputStream& is, unsigned* codepoint); + + //! \brief Validate one Unicode codepoint from an encoded stream. + //! \param is Input stream to obtain codepoint. + //! \param os Output for copying one codepoint. + //! \return true if it is valid. + //! \note This function just validating and copying the codepoint without actually decode it. + template + static bool Validate(InputStream& is, OutputStream& os); + + // The following functions are deal with byte streams. + + //! Take a character from input byte stream, skip BOM if exist. + template + static CharType TakeBOM(InputByteStream& is); + + //! Take a character from input byte stream. + template + static Ch Take(InputByteStream& is); + + //! Put BOM to output byte stream. + template + static void PutBOM(OutputByteStream& os); + + //! Put a character to output byte stream. + template + static void Put(OutputByteStream& os, Ch c); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// UTF8 + +//! UTF-8 encoding. +/*! http://en.wikipedia.org/wiki/UTF-8 + http://tools.ietf.org/html/rfc3629 + \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. + \note implements Encoding concept +*/ +template +struct UTF8 { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + os.Put(static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + os.Put(static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + os.Put(static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + PutUnsafe(os, static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + PutUnsafe(os, static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + PutUnsafe(os, static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { +#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast(c) & 0x3Fu) +#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) +#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70) + typename InputStream::Ch c = is.Take(); + if (!(c & 0x80)) { + *codepoint = static_cast(c); + return true; + } + + unsigned char type = GetRange(static_cast(c)); + if (type >= 32) { + *codepoint = 0; + } else { + *codepoint = (0xFFu >> type) & static_cast(c); + } + bool result = true; + switch (type) { + case 2: RAPIDJSON_TAIL(); return result; + case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result; + case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result; + case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + default: return false; + } +#undef RAPIDJSON_COPY +#undef RAPIDJSON_TRANS +#undef RAPIDJSON_TAIL + } + + template + static bool Validate(InputStream& is, OutputStream& os) { +#define RAPIDJSON_COPY() os.Put(c = is.Take()) +#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) +#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70) + Ch c; + RAPIDJSON_COPY(); + if (!(c & 0x80)) + return true; + + bool result = true; + switch (GetRange(static_cast(c))) { + case 2: RAPIDJSON_TAIL(); return result; + case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result; + case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result; + case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + default: return false; + } +#undef RAPIDJSON_COPY +#undef RAPIDJSON_TRANS +#undef RAPIDJSON_TAIL + } + + static unsigned char GetRange(unsigned char c) { + // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ + // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. + static const unsigned char type[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + }; + return type[c]; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + typename InputByteStream::Ch c = Take(is); + if (static_cast(c) != 0xEFu) return c; + c = is.Take(); + if (static_cast(c) != 0xBBu) return c; + c = is.Take(); + if (static_cast(c) != 0xBFu) return c; + c = is.Take(); + return c; + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return static_cast(is.Take()); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xEFu)); + os.Put(static_cast(0xBBu)); + os.Put(static_cast(0xBFu)); + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF16 + +//! UTF-16 encoding. +/*! http://en.wikipedia.org/wiki/UTF-16 + http://tools.ietf.org/html/rfc2781 + \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF16LE and UTF16BE, which handle endianness. +*/ +template +struct UTF16 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + os.Put(static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + os.Put(static_cast((v >> 10) | 0xD800)); + os.Put(static_cast((v & 0x3FF) | 0xDC00)); + } + } + + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + PutUnsafe(os, static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + PutUnsafe(os, static_cast((v >> 10) | 0xD800)); + PutUnsafe(os, static_cast((v & 0x3FF) | 0xDC00)); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + typename InputStream::Ch c = is.Take(); + if (c < 0xD800 || c > 0xDFFF) { + *codepoint = static_cast(c); + return true; + } + else if (c <= 0xDBFF) { + *codepoint = (static_cast(c) & 0x3FF) << 10; + c = is.Take(); + *codepoint |= (static_cast(c) & 0x3FF); + *codepoint += 0x10000; + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + typename InputStream::Ch c; + os.Put(static_cast(c = is.Take())); + if (c < 0xD800 || c > 0xDFFF) + return true; + else if (c <= 0xDBFF) { + os.Put(c = is.Take()); + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } +}; + +//! UTF-16 little endian encoding. +template +struct UTF16LE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(is.Take()); + c |= static_cast(static_cast(is.Take())) << 8; + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFFu)); + os.Put(static_cast(0xFEu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(static_cast(c) & 0xFFu)); + os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); + } +}; + +//! UTF-16 big endian encoding. +template +struct UTF16BE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())); + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0xFFu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); + os.Put(static_cast(static_cast(c) & 0xFFu)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF32 + +//! UTF-32 encoding. +/*! http://en.wikipedia.org/wiki/UTF-32 + \tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF32LE and UTF32BE, which handle endianness. +*/ +template +struct UTF32 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(codepoint); + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, codepoint); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c = is.Take(); + *codepoint = c; + return c <= 0x10FFFF; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c; + os.Put(c = is.Take()); + return c <= 0x10FFFF; + } +}; + +//! UTF-32 little endian encoding. +template +struct UTF32LE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(is.Take()); + c |= static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())) << 16; + c |= static_cast(static_cast(is.Take())) << 24; + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFFu)); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0x00u)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c & 0xFFu)); + os.Put(static_cast((c >> 8) & 0xFFu)); + os.Put(static_cast((c >> 16) & 0xFFu)); + os.Put(static_cast((c >> 24) & 0xFFu)); + } +}; + +//! UTF-32 big endian encoding. +template +struct UTF32BE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(static_cast(is.Take())) << 24; + c |= static_cast(static_cast(is.Take())) << 16; + c |= static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())); + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0xFFu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast((c >> 24) & 0xFFu)); + os.Put(static_cast((c >> 16) & 0xFFu)); + os.Put(static_cast((c >> 8) & 0xFFu)); + os.Put(static_cast(c & 0xFFu)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// ASCII + +//! ASCII encoding. +/*! http://en.wikipedia.org/wiki/ASCII + \tparam CharType Code unit for storing 7-bit ASCII data. Default is char. + \note implements Encoding concept +*/ +template +struct ASCII { + typedef CharType Ch; + + enum { supportUnicode = 0 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + os.Put(static_cast(codepoint & 0xFF)); + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + PutUnsafe(os, static_cast(codepoint & 0xFF)); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + uint8_t c = static_cast(is.Take()); + *codepoint = c; + return c <= 0X7F; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + uint8_t c = static_cast(is.Take()); + os.Put(static_cast(c)); + return c <= 0x7F; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + uint8_t c = static_cast(Take(is)); + return static_cast(c); + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return static_cast(is.Take()); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + (void)os; + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// AutoUTF + +//! Runtime-specified UTF encoding type of a stream. +enum UTFType { + kUTF8 = 0, //!< UTF-8. + kUTF16LE = 1, //!< UTF-16 little endian. + kUTF16BE = 2, //!< UTF-16 big endian. + kUTF32LE = 3, //!< UTF-32 little endian. + kUTF32BE = 4 //!< UTF-32 big endian. +}; + +//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. +/*! \note This class can be used with AutoUTFInputStream and AutoUTFOutputStream, which provides GetType(). +*/ +template +struct AutoUTF { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + + template + static RAPIDJSON_FORCEINLINE void Encode(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; + (*f[os.GetType()])(os, codepoint); + } + + template + static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) }; + (*f[os.GetType()])(os, codepoint); + } + + template + static RAPIDJSON_FORCEINLINE bool Decode(InputStream& is, unsigned* codepoint) { + typedef bool (*DecodeFunc)(InputStream&, unsigned*); + static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; + return (*f[is.GetType()])(is, codepoint); + } + + template + static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { + typedef bool (*ValidateFunc)(InputStream&, OutputStream&); + static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; + return (*f[is.GetType()])(is, os); + } + +#undef RAPIDJSON_ENCODINGS_FUNC +}; + +/////////////////////////////////////////////////////////////////////////////// +// Transcoder + +//! Encoding conversion. +template +struct Transcoder { + //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. + template + static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::Encode(os, codepoint); + return true; + } + + template + static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::EncodeUnsafe(os, codepoint); + return true; + } + + //! Validate one Unicode codepoint from an encoded stream. + template + static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { + return Transcode(is, os); // Since source/target encoding is different, must transcode. + } +}; + +// Forward declaration. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c); + +//! Specialization of Transcoder with same source and target encoding. +template +struct Transcoder { + template + static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) { + os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { + return Encoding::Validate(is, os); // source/target encoding are the same + } +}; + +RAPIDJSON_NAMESPACE_END + +#if defined(__GNUC__) || (defined(_MSC_VER) && !defined(__clang__)) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/error/en.h b/test/include/liblvgl/libs/thorvg/rapidjson/error/en.h new file mode 100644 index 00000000..c87b04eb --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/error/en.h @@ -0,0 +1,176 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_EN_H_ +#define RAPIDJSON_ERROR_EN_H_ + +#include "error.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(covered-switch-default) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Maps error code of parsing into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param parseErrorCode Error code obtained in parsing. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { + switch (parseErrorCode) { + case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); + case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); + + case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); + + case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); + case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); + case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); + + case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); + + case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); + case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); + case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); + case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); + case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); + + case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); + case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); + case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); + + case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); + case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +//! Maps error code of validation into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param validateErrorCode Error code obtained from validator. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetValidateError_En(ValidateErrorCode validateErrorCode) { + switch (validateErrorCode) { + case kValidateErrors: return RAPIDJSON_ERROR_STRING("One or more validation errors have occurred"); + case kValidateErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kValidateErrorMultipleOf: return RAPIDJSON_ERROR_STRING("Number '%actual' is not a multiple of the 'multipleOf' value '%expected'."); + case kValidateErrorMaximum: return RAPIDJSON_ERROR_STRING("Number '%actual' is greater than the 'maximum' value '%expected'."); + case kValidateErrorExclusiveMaximum: return RAPIDJSON_ERROR_STRING("Number '%actual' is greater than or equal to the 'exclusiveMaximum' value '%expected'."); + case kValidateErrorMinimum: return RAPIDJSON_ERROR_STRING("Number '%actual' is less than the 'minimum' value '%expected'."); + case kValidateErrorExclusiveMinimum: return RAPIDJSON_ERROR_STRING("Number '%actual' is less than or equal to the 'exclusiveMinimum' value '%expected'."); + + case kValidateErrorMaxLength: return RAPIDJSON_ERROR_STRING("String '%actual' is longer than the 'maxLength' value '%expected'."); + case kValidateErrorMinLength: return RAPIDJSON_ERROR_STRING("String '%actual' is shorter than the 'minLength' value '%expected'."); + case kValidateErrorPattern: return RAPIDJSON_ERROR_STRING("String '%actual' does not match the 'pattern' regular expression."); + + case kValidateErrorMaxItems: return RAPIDJSON_ERROR_STRING("Array of length '%actual' is longer than the 'maxItems' value '%expected'."); + case kValidateErrorMinItems: return RAPIDJSON_ERROR_STRING("Array of length '%actual' is shorter than the 'minItems' value '%expected'."); + case kValidateErrorUniqueItems: return RAPIDJSON_ERROR_STRING("Array has duplicate items at indices '%duplicates' but 'uniqueItems' is true."); + case kValidateErrorAdditionalItems: return RAPIDJSON_ERROR_STRING("Array has an additional item at index '%disallowed' that is not allowed by the schema."); + + case kValidateErrorMaxProperties: return RAPIDJSON_ERROR_STRING("Object has '%actual' members which is more than 'maxProperties' value '%expected'."); + case kValidateErrorMinProperties: return RAPIDJSON_ERROR_STRING("Object has '%actual' members which is less than 'minProperties' value '%expected'."); + case kValidateErrorRequired: return RAPIDJSON_ERROR_STRING("Object is missing the following members required by the schema: '%missing'."); + case kValidateErrorAdditionalProperties: return RAPIDJSON_ERROR_STRING("Object has an additional member '%disallowed' that is not allowed by the schema."); + case kValidateErrorPatternProperties: return RAPIDJSON_ERROR_STRING("Object has 'patternProperties' that are not allowed by the schema."); + case kValidateErrorDependencies: return RAPIDJSON_ERROR_STRING("Object has missing property or schema dependencies, refer to following errors."); + + case kValidateErrorEnum: return RAPIDJSON_ERROR_STRING("Property has a value that is not one of its allowed enumerated values."); + case kValidateErrorType: return RAPIDJSON_ERROR_STRING("Property has a type '%actual' that is not in the following list: '%expected'."); + + case kValidateErrorOneOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'oneOf', refer to following errors."); + case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf', indices '%matches'."); + case kValidateErrorAllOf: return RAPIDJSON_ERROR_STRING("Property did not match all of the sub-schemas specified by 'allOf', refer to following errors."); + case kValidateErrorAnyOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'anyOf', refer to following errors."); + case kValidateErrorNot: return RAPIDJSON_ERROR_STRING("Property matched the sub-schema specified by 'not'."); + + case kValidateErrorReadOnly: return RAPIDJSON_ERROR_STRING("Property is read-only but has been provided when validation is for writing."); + case kValidateErrorWriteOnly: return RAPIDJSON_ERROR_STRING("Property is write-only but has been provided when validation is for reading."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +//! Maps error code of schema document compilation into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param schemaErrorCode Error code obtained from compiling the schema document. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ + inline const RAPIDJSON_ERROR_CHARTYPE* GetSchemaError_En(SchemaErrorCode schemaErrorCode) { + switch (schemaErrorCode) { + case kSchemaErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kSchemaErrorStartUnknown: return RAPIDJSON_ERROR_STRING("Pointer '%value' to start of schema does not resolve to a location in the document."); + case kSchemaErrorRefPlainName: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' must be a JSON pointer."); + case kSchemaErrorRefInvalid: return RAPIDJSON_ERROR_STRING("$ref must not be an empty string."); + case kSchemaErrorRefPointerInvalid: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' is not a valid JSON pointer at offset '%offset'."); + case kSchemaErrorRefUnknown: return RAPIDJSON_ERROR_STRING("$ref '%value' does not resolve to a location in the target document."); + case kSchemaErrorRefCyclical: return RAPIDJSON_ERROR_STRING("$ref '%value' is cyclical."); + case kSchemaErrorRefNoRemoteProvider: return RAPIDJSON_ERROR_STRING("$ref is remote but there is no remote provider."); + case kSchemaErrorRefNoRemoteSchema: return RAPIDJSON_ERROR_STRING("$ref '%value' is remote but the remote provider did not return a schema."); + case kSchemaErrorRegexInvalid: return RAPIDJSON_ERROR_STRING("Invalid regular expression '%value' in 'pattern' or 'patternProperties'."); + case kSchemaErrorSpecUnknown: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not recognized."); + case kSchemaErrorSpecUnsupported: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not supported."); + case kSchemaErrorSpecIllegal: return RAPIDJSON_ERROR_STRING("Both JSON schema draft and OpenAPI version found in document."); + case kSchemaErrorReadOnlyAndWriteOnly: return RAPIDJSON_ERROR_STRING("Property must not be both 'readOnly' and 'writeOnly'."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } + } + +//! Maps error code of pointer parse into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param pointerParseErrorCode Error code obtained from pointer parse. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetPointerParseError_En(PointerParseErrorCode pointerParseErrorCode) { + switch (pointerParseErrorCode) { + case kPointerParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kPointerParseErrorTokenMustBeginWithSolidus: return RAPIDJSON_ERROR_STRING("A token must begin with a '/'."); + case kPointerParseErrorInvalidEscape: return RAPIDJSON_ERROR_STRING("Invalid escape."); + case kPointerParseErrorInvalidPercentEncoding: return RAPIDJSON_ERROR_STRING("Invalid percent encoding in URI fragment."); + case kPointerParseErrorCharacterMustPercentEncode: return RAPIDJSON_ERROR_STRING("A character must be percent encoded in a URI fragment."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ERROR_EN_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/error/error.h b/test/include/liblvgl/libs/thorvg/rapidjson/error/error.h new file mode 100644 index 00000000..cae345db --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/error/error.h @@ -0,0 +1,285 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_ERROR_H_ +#define RAPIDJSON_ERROR_ERROR_H_ + +#include "../rapidjson.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +/*! \file error.h */ + +/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_CHARTYPE + +//! Character type of error messages. +/*! \ingroup RAPIDJSON_ERRORS + The default character type is \c char. + On Windows, user can define this macro as \c TCHAR for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_CHARTYPE +#define RAPIDJSON_ERROR_CHARTYPE char +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_STRING + +//! Macro for converting string literal to \ref RAPIDJSON_ERROR_CHARTYPE[]. +/*! \ingroup RAPIDJSON_ERRORS + By default this conversion macro does nothing. + On Windows, user can define this macro as \c _T(x) for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_STRING +#define RAPIDJSON_ERROR_STRING(x) x +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseErrorCode + +//! Error code of parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericReader::Parse, GenericReader::GetParseErrorCode +*/ +enum ParseErrorCode { + kParseErrorNone = 0, //!< No error. + + kParseErrorDocumentEmpty, //!< The document is empty. + kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. + + kParseErrorValueInvalid, //!< Invalid value. + + kParseErrorObjectMissName, //!< Missing a name for object member. + kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. + kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. + + kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. + + kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. + kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. + kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. + kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. + kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. + + kParseErrorNumberTooBig, //!< Number too big to be stored in double. + kParseErrorNumberMissFraction, //!< Miss fraction part in number. + kParseErrorNumberMissExponent, //!< Miss exponent in number. + + kParseErrorTermination, //!< Parsing was terminated. + kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. +}; + +//! Result of parsing (wraps ParseErrorCode) +/*! + \ingroup RAPIDJSON_ERRORS + \code + Document doc; + ParseResult ok = doc.Parse("[42]"); + if (!ok) { + fprintf(stderr, "JSON parse error: %s (%u)", + GetParseError_En(ok.Code()), ok.Offset()); + exit(EXIT_FAILURE); + } + \endcode + \see GenericReader::Parse, GenericDocument::Parse +*/ +struct ParseResult { + //!! Unspecified boolean type + typedef bool (ParseResult::*BooleanType)() const; +public: + //! Default constructor, no error. + ParseResult() : code_(kParseErrorNone), offset_(0) {} + //! Constructor to set an error. + ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} + + //! Get the error code. + ParseErrorCode Code() const { return code_; } + //! Get the error offset, if \ref IsError(), 0 otherwise. + size_t Offset() const { return offset_; } + + //! Explicit conversion to \c bool, returns \c true, iff !\ref IsError(). + operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; } + //! Whether the result is an error. + bool IsError() const { return code_ != kParseErrorNone; } + + bool operator==(const ParseResult& that) const { return code_ == that.code_; } + bool operator==(ParseErrorCode code) const { return code_ == code; } + friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } + + bool operator!=(const ParseResult& that) const { return !(*this == that); } + bool operator!=(ParseErrorCode code) const { return !(*this == code); } + friend bool operator!=(ParseErrorCode code, const ParseResult & err) { return err != code; } + + //! Reset error code. + void Clear() { Set(kParseErrorNone); } + //! Update error code and offset. + void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } + +private: + ParseErrorCode code_; + size_t offset_; +}; + +//! Function pointer type of GetParseError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetParseError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetParseErrorFunc GetParseError = GetParseError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); + +/////////////////////////////////////////////////////////////////////////////// +// ValidateErrorCode + +//! Error codes when validating. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericSchemaValidator +*/ +enum ValidateErrorCode { + kValidateErrors = -1, //!< Top level error code when kValidateContinueOnErrorsFlag set. + kValidateErrorNone = 0, //!< No error. + + kValidateErrorMultipleOf, //!< Number is not a multiple of the 'multipleOf' value. + kValidateErrorMaximum, //!< Number is greater than the 'maximum' value. + kValidateErrorExclusiveMaximum, //!< Number is greater than or equal to the 'maximum' value. + kValidateErrorMinimum, //!< Number is less than the 'minimum' value. + kValidateErrorExclusiveMinimum, //!< Number is less than or equal to the 'minimum' value. + + kValidateErrorMaxLength, //!< String is longer than the 'maxLength' value. + kValidateErrorMinLength, //!< String is longer than the 'maxLength' value. + kValidateErrorPattern, //!< String does not match the 'pattern' regular expression. + + kValidateErrorMaxItems, //!< Array is longer than the 'maxItems' value. + kValidateErrorMinItems, //!< Array is shorter than the 'minItems' value. + kValidateErrorUniqueItems, //!< Array has duplicate items but 'uniqueItems' is true. + kValidateErrorAdditionalItems, //!< Array has additional items that are not allowed by the schema. + + kValidateErrorMaxProperties, //!< Object has more members than 'maxProperties' value. + kValidateErrorMinProperties, //!< Object has less members than 'minProperties' value. + kValidateErrorRequired, //!< Object is missing one or more members required by the schema. + kValidateErrorAdditionalProperties, //!< Object has additional members that are not allowed by the schema. + kValidateErrorPatternProperties, //!< See other errors. + kValidateErrorDependencies, //!< Object has missing property or schema dependencies. + + kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values. + kValidateErrorType, //!< Property has a type that is not allowed by the schema. + + kValidateErrorOneOf, //!< Property did not match any of the sub-schemas specified by 'oneOf'. + kValidateErrorOneOfMatch, //!< Property matched more than one of the sub-schemas specified by 'oneOf'. + kValidateErrorAllOf, //!< Property did not match all of the sub-schemas specified by 'allOf'. + kValidateErrorAnyOf, //!< Property did not match any of the sub-schemas specified by 'anyOf'. + kValidateErrorNot, //!< Property matched the sub-schema specified by 'not'. + + kValidateErrorReadOnly, //!< Property is read-only but has been provided when validation is for writing + kValidateErrorWriteOnly //!< Property is write-only but has been provided when validation is for reading +}; + +//! Function pointer type of GetValidateError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetValidateError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetValidateErrorFunc GetValidateError = GetValidateError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetValidateError(validator.GetInvalidSchemaCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetValidateErrorFunc)(ValidateErrorCode); + +/////////////////////////////////////////////////////////////////////////////// +// SchemaErrorCode + +//! Error codes when validating. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericSchemaValidator +*/ +enum SchemaErrorCode { + kSchemaErrorNone = 0, //!< No error. + + kSchemaErrorStartUnknown, //!< Pointer to start of schema does not resolve to a location in the document + kSchemaErrorRefPlainName, //!< $ref fragment must be a JSON pointer + kSchemaErrorRefInvalid, //!< $ref must not be an empty string + kSchemaErrorRefPointerInvalid, //!< $ref fragment is not a valid JSON pointer at offset + kSchemaErrorRefUnknown, //!< $ref does not resolve to a location in the target document + kSchemaErrorRefCyclical, //!< $ref is cyclical + kSchemaErrorRefNoRemoteProvider, //!< $ref is remote but there is no remote provider + kSchemaErrorRefNoRemoteSchema, //!< $ref is remote but the remote provider did not return a schema + kSchemaErrorRegexInvalid, //!< Invalid regular expression in 'pattern' or 'patternProperties' + kSchemaErrorSpecUnknown, //!< JSON schema draft or OpenAPI version is not recognized + kSchemaErrorSpecUnsupported, //!< JSON schema draft or OpenAPI version is not supported + kSchemaErrorSpecIllegal, //!< Both JSON schema draft and OpenAPI version found in document + kSchemaErrorReadOnlyAndWriteOnly //!< Property must not be both 'readOnly' and 'writeOnly' +}; + +//! Function pointer type of GetSchemaError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetSchemaError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetSchemaErrorFunc GetSchemaError = GetSchemaError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetSchemaError(validator.GetInvalidSchemaCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetSchemaErrorFunc)(SchemaErrorCode); + +/////////////////////////////////////////////////////////////////////////////// +// PointerParseErrorCode + +//! Error code of JSON pointer parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode +*/ +enum PointerParseErrorCode { + kPointerParseErrorNone = 0, //!< The parse is successful + + kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/' + kPointerParseErrorInvalidEscape, //!< Invalid escape + kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment + kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment +}; + +//! Function pointer type of GetPointerParseError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetPointerParseError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetPointerParseErrorFunc GetPointerParseError = GetPointerParseError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetPointerParseError(pointer.GetParseErrorCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetPointerParseErrorFunc)(PointerParseErrorCode); + + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ERROR_ERROR_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/filereadstream.h b/test/include/liblvgl/libs/thorvg/rapidjson/filereadstream.h new file mode 100644 index 00000000..3daff092 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/filereadstream.h @@ -0,0 +1,99 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEREADSTREAM_H_ +#define RAPIDJSON_FILEREADSTREAM_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(missing-noreturn) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! File byte stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileReadStream { +public: + typedef char Ch; //!< Character type (byte). + + //! Constructor. + /*! + \param fp File pointer opened for read. + \param buffer user-supplied buffer. + \param bufferSize size of buffer in bytes. Must >=4 bytes. + */ + FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + RAPIDJSON_ASSERT(fp_ != 0); + RAPIDJSON_ASSERT(bufferSize >= 4); + Read(); + } + + Ch Peek() const { return *current_; } + Ch Take() { Ch c = *current_; Read(); return c; } + size_t Tell() const { return count_ + static_cast(current_ - buffer_); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0; + } + +private: + void Read() { + if (current_ < bufferLast_) + ++current_; + else if (!eof_) { + count_ += readCount_; + readCount_ = std::fread(buffer_, 1, bufferSize_, fp_); + bufferLast_ = buffer_ + readCount_ - 1; + current_ = buffer_; + + if (readCount_ < bufferSize_) { + buffer_[readCount_] = '\0'; + ++bufferLast_; + eof_ = true; + } + } + } + + std::FILE* fp_; + Ch *buffer_; + size_t bufferSize_; + Ch *bufferLast_; + Ch *current_; + size_t readCount_; + size_t count_; //!< Number of characters read + bool eof_; +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/filewritestream.h b/test/include/liblvgl/libs/thorvg/rapidjson/filewritestream.h new file mode 100644 index 00000000..8a78ef7f --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/filewritestream.h @@ -0,0 +1,104 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEWRITESTREAM_H_ +#define RAPIDJSON_FILEWRITESTREAM_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(unreachable-code) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of C file stream for output using fwrite(). +/*! + \note implements Stream concept +*/ +class FileWriteStream { +public: + typedef char Ch; //!< Character type. Only support char. + + FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { + RAPIDJSON_ASSERT(fp_ != 0); + } + + void Put(char c) { + if (current_ >= bufferEnd_) + Flush(); + + *current_++ = c; + } + + void PutN(char c, size_t n) { + size_t avail = static_cast(bufferEnd_ - current_); + while (n > avail) { + std::memset(current_, c, avail); + current_ += avail; + Flush(); + n -= avail; + avail = static_cast(bufferEnd_ - current_); + } + + if (n > 0) { + std::memset(current_, c, n); + current_ += n; + } + } + + void Flush() { + if (current_ != buffer_) { + size_t result = std::fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); + if (result < static_cast(current_ - buffer_)) { + // failure deliberately ignored at this time + // added to avoid warn_unused_result build errors + } + current_ = buffer_; + } + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + // Prohibit copy constructor & assignment operator. + FileWriteStream(const FileWriteStream&); + FileWriteStream& operator=(const FileWriteStream&); + + std::FILE* fp_; + char *buffer_; + char *bufferEnd_; + char *current_; +}; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(FileWriteStream& stream, char c, size_t n) { + stream.PutN(c, n); +} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/fwd.h b/test/include/liblvgl/libs/thorvg/rapidjson/fwd.h new file mode 100644 index 00000000..07358d8c --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/fwd.h @@ -0,0 +1,151 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FWD_H_ +#define RAPIDJSON_FWD_H_ + +#include "rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN + +// encodings.h + +template struct UTF8; +template struct UTF16; +template struct UTF16BE; +template struct UTF16LE; +template struct UTF32; +template struct UTF32BE; +template struct UTF32LE; +template struct ASCII; +template struct AutoUTF; + +template +struct Transcoder; + +// allocators.h + +class CrtAllocator; + +template +class MemoryPoolAllocator; + +// stream.h + +template +struct GenericStringStream; + +typedef GenericStringStream > StringStream; + +template +struct GenericInsituStringStream; + +typedef GenericInsituStringStream > InsituStringStream; + +// stringbuffer.h + +template +class GenericStringBuffer; + +typedef GenericStringBuffer, CrtAllocator> StringBuffer; + +// filereadstream.h + +class FileReadStream; + +// filewritestream.h + +class FileWriteStream; + +// memorybuffer.h + +template +struct GenericMemoryBuffer; + +typedef GenericMemoryBuffer MemoryBuffer; + +// memorystream.h + +struct MemoryStream; + +// reader.h + +template +struct BaseReaderHandler; + +template +class GenericReader; + +typedef GenericReader, UTF8, CrtAllocator> Reader; + +// writer.h + +template +class Writer; + +// prettywriter.h + +template +class PrettyWriter; + +// document.h + +template +class GenericMember; + +template +class GenericMemberIterator; + +template +struct GenericStringRef; + +template +class GenericValue; + +typedef GenericValue, MemoryPoolAllocator > Value; + +template +class GenericDocument; + +typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document; + +// pointer.h + +template +class GenericPointer; + +typedef GenericPointer Pointer; + +// schema.h + +template +class IGenericRemoteSchemaDocumentProvider; + +template +class GenericSchemaDocument; + +typedef GenericSchemaDocument SchemaDocument; +typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; + +template < + typename SchemaDocumentType, + typename OutputHandler, + typename StateAllocator> +class GenericSchemaValidator; + +typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSONFWD_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/biginteger.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/biginteger.h new file mode 100644 index 00000000..09d0387f --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/biginteger.h @@ -0,0 +1,297 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_BIGINTEGER_H_ +#define RAPIDJSON_BIGINTEGER_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64) +#include // for _umul128 +#if !defined(_ARM64EC_) +#pragma intrinsic(_umul128) +#else +#pragma comment(lib,"softintrin") +#endif +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class BigInteger { +public: + typedef uint64_t Type; + + BigInteger(const BigInteger& rhs) : count_(rhs.count_) { + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + + explicit BigInteger(uint64_t u) : count_(1) { + digits_[0] = u; + } + + template + BigInteger(const Ch* decimals, size_t length) : count_(1) { + RAPIDJSON_ASSERT(length > 0); + digits_[0] = 0; + size_t i = 0; + const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19 + while (length >= kMaxDigitPerIteration) { + AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration); + length -= kMaxDigitPerIteration; + i += kMaxDigitPerIteration; + } + + if (length > 0) + AppendDecimal64(decimals + i, decimals + i + length); + } + + BigInteger& operator=(const BigInteger &rhs) + { + if (this != &rhs) { + count_ = rhs.count_; + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + return *this; + } + + BigInteger& operator=(uint64_t u) { + digits_[0] = u; + count_ = 1; + return *this; + } + + BigInteger& operator+=(uint64_t u) { + Type backup = digits_[0]; + digits_[0] += u; + for (size_t i = 0; i < count_ - 1; i++) { + if (digits_[i] >= backup) + return *this; // no carry + backup = digits_[i + 1]; + digits_[i + 1] += 1; + } + + // Last carry + if (digits_[count_ - 1] < backup) + PushBack(1); + + return *this; + } + + BigInteger& operator*=(uint64_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + uint64_t hi; + digits_[i] = MulAdd64(digits_[i], u, k, &hi); + k = hi; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator*=(uint32_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + const uint64_t c = digits_[i] >> 32; + const uint64_t d = digits_[i] & 0xFFFFFFFF; + const uint64_t uc = u * c; + const uint64_t ud = u * d; + const uint64_t p0 = ud + k; + const uint64_t p1 = uc + (p0 >> 32); + digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32); + k = p1 >> 32; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator<<=(size_t shift) { + if (IsZero() || shift == 0) return *this; + + size_t offset = shift / kTypeBit; + size_t interShift = shift % kTypeBit; + RAPIDJSON_ASSERT(count_ + offset <= kCapacity); + + if (interShift == 0) { + std::memmove(digits_ + offset, digits_, count_ * sizeof(Type)); + count_ += offset; + } + else { + digits_[count_] = 0; + for (size_t i = count_; i > 0; i--) + digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift)); + digits_[offset] = digits_[0] << interShift; + count_ += offset; + if (digits_[count_]) + count_++; + } + + std::memset(digits_, 0, offset * sizeof(Type)); + + return *this; + } + + bool operator==(const BigInteger& rhs) const { + return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0; + } + + bool operator==(const Type rhs) const { + return count_ == 1 && digits_[0] == rhs; + } + + BigInteger& MultiplyPow5(unsigned exp) { + static const uint32_t kPow5[12] = { + 5, + 5 * 5, + 5 * 5 * 5, + 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 + }; + if (exp == 0) return *this; + for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27 + for (; exp >= 13; exp -= 13) *this *= static_cast(1220703125u); // 5^13 + if (exp > 0) *this *= kPow5[exp - 1]; + return *this; + } + + // Compute absolute difference of this and rhs. + // Assume this != rhs + bool Difference(const BigInteger& rhs, BigInteger* out) const { + int cmp = Compare(rhs); + RAPIDJSON_ASSERT(cmp != 0); + const BigInteger *a, *b; // Makes a > b + bool ret; + if (cmp < 0) { a = &rhs; b = this; ret = true; } + else { a = this; b = &rhs; ret = false; } + + Type borrow = 0; + for (size_t i = 0; i < a->count_; i++) { + Type d = a->digits_[i] - borrow; + if (i < b->count_) + d -= b->digits_[i]; + borrow = (d > a->digits_[i]) ? 1 : 0; + out->digits_[i] = d; + if (d != 0) + out->count_ = i + 1; + } + + return ret; + } + + int Compare(const BigInteger& rhs) const { + if (count_ != rhs.count_) + return count_ < rhs.count_ ? -1 : 1; + + for (size_t i = count_; i-- > 0;) + if (digits_[i] != rhs.digits_[i]) + return digits_[i] < rhs.digits_[i] ? -1 : 1; + + return 0; + } + + size_t GetCount() const { return count_; } + Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; } + bool IsZero() const { return count_ == 1 && digits_[0] == 0; } + +private: + template + void AppendDecimal64(const Ch* begin, const Ch* end) { + uint64_t u = ParseUint64(begin, end); + if (IsZero()) + *this = u; + else { + unsigned exp = static_cast(end - begin); + (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u + } + } + + void PushBack(Type digit) { + RAPIDJSON_ASSERT(count_ < kCapacity); + digits_[count_++] = digit; + } + + template + static uint64_t ParseUint64(const Ch* begin, const Ch* end) { + uint64_t r = 0; + for (const Ch* p = begin; p != end; ++p) { + RAPIDJSON_ASSERT(*p >= Ch('0') && *p <= Ch('9')); + r = r * 10u + static_cast(*p - Ch('0')); + } + return r; + } + + // Assume a * b + k < 2^128 + static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t low = _umul128(a, b, outHigh) + k; + if (low < k) + (*outHigh)++; + return low; +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __extension__ typedef unsigned __int128 uint128; + uint128 p = static_cast(a) * static_cast(b); + p += k; + *outHigh = static_cast(p >> 64); + return static_cast(p); +#else + const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32; + uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1; + x1 += (x0 >> 32); // can't give carry + x1 += x2; + if (x1 < x2) + x3 += (static_cast(1) << 32); + uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF); + uint64_t hi = x3 + (x1 >> 32); + + lo += k; + if (lo < k) + hi++; + *outHigh = hi; + return lo; +#endif + } + + static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000 + static const size_t kCapacity = kBitCount / sizeof(Type); + static const size_t kTypeBit = sizeof(Type) * 8; + + Type digits_[kCapacity]; + size_t count_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_BIGINTEGER_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/clzll.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/clzll.h new file mode 100644 index 00000000..8fc5118a --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/clzll.h @@ -0,0 +1,71 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_CLZLL_H_ +#define RAPIDJSON_CLZLL_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && !defined(UNDER_CE) +#include +#if defined(_WIN64) +#pragma intrinsic(_BitScanReverse64) +#else +#pragma intrinsic(_BitScanReverse) +#endif +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline uint32_t clzll(uint64_t x) { + // Passing 0 to __builtin_clzll is UB in GCC and results in an + // infinite loop in the software implementation. + RAPIDJSON_ASSERT(x != 0); + +#if defined(_MSC_VER) && !defined(UNDER_CE) + unsigned long r = 0; +#if defined(_WIN64) + _BitScanReverse64(&r, x); +#else + // Scan the high 32 bits. + if (_BitScanReverse(&r, static_cast(x >> 32))) + return 63 - (r + 32); + + // Scan the low 32 bits. + _BitScanReverse(&r, static_cast(x & 0xFFFFFFFF)); +#endif // _WIN64 + + return 63 - r; +#elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll) + // __builtin_clzll wrapper + return static_cast(__builtin_clzll(x)); +#else + // naive version + uint32_t r = 0; + while (!(x & (static_cast(1) << 63))) { + x <<= 1; + ++r; + } + + return r; +#endif // _MSC_VER +} + +#define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_CLZLL_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/diyfp.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/diyfp.h new file mode 100644 index 00000000..1f60fb60 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/diyfp.h @@ -0,0 +1,261 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DIYFP_H_ +#define RAPIDJSON_DIYFP_H_ + +#include "../rapidjson.h" +#include "clzll.h" +#include + +#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER) +#include +#if !defined(_ARM64EC_) +#pragma intrinsic(_umul128) +#else +#pragma comment(lib,"softintrin") +#endif +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +struct DiyFp { + DiyFp() : f(), e() {} + + DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {} + + explicit DiyFp(double d) { + union { + double d; + uint64_t u64; + } u = { d }; + + int biased_e = static_cast((u.u64 & kDpExponentMask) >> kDpSignificandSize); + uint64_t significand = (u.u64 & kDpSignificandMask); + if (biased_e != 0) { + f = significand + kDpHiddenBit; + e = biased_e - kDpExponentBias; + } + else { + f = significand; + e = kDpMinExponent + 1; + } + } + + DiyFp operator-(const DiyFp& rhs) const { + return DiyFp(f - rhs.f, e); + } + + DiyFp operator*(const DiyFp& rhs) const { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t h; + uint64_t l = _umul128(f, rhs.f, &h); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __extension__ typedef unsigned __int128 uint128; + uint128 p = static_cast(f) * static_cast(rhs.f); + uint64_t h = static_cast(p >> 64); + uint64_t l = static_cast(p); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#else + const uint64_t M32 = 0xFFFFFFFF; + const uint64_t a = f >> 32; + const uint64_t b = f & M32; + const uint64_t c = rhs.f >> 32; + const uint64_t d = rhs.f & M32; + const uint64_t ac = a * c; + const uint64_t bc = b * c; + const uint64_t ad = a * d; + const uint64_t bd = b * d; + uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); + tmp += 1U << 31; /// mult_round + return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); +#endif + } + + DiyFp Normalize() const { + int s = static_cast(clzll(f)); + return DiyFp(f << s, e - s); + } + + DiyFp NormalizeBoundary() const { + DiyFp res = *this; + while (!(res.f & (kDpHiddenBit << 1))) { + res.f <<= 1; + res.e--; + } + res.f <<= (kDiySignificandSize - kDpSignificandSize - 2); + res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2); + return res; + } + + void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { + DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); + DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); + mi.f <<= mi.e - pl.e; + mi.e = pl.e; + *plus = pl; + *minus = mi; + } + + double ToDouble() const { + union { + double d; + uint64_t u64; + }u; + RAPIDJSON_ASSERT(f <= kDpHiddenBit + kDpSignificandMask); + if (e < kDpDenormalExponent) { + // Underflow. + return 0.0; + } + if (e >= kDpMaxExponent) { + // Overflow. + return std::numeric_limits::infinity(); + } + const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : + static_cast(e + kDpExponentBias); + u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize); + return u.d; + } + + static const int kDiySignificandSize = 64; + static const int kDpSignificandSize = 52; + static const int kDpExponentBias = 0x3FF + kDpSignificandSize; + static const int kDpMaxExponent = 0x7FF - kDpExponentBias; + static const int kDpMinExponent = -kDpExponentBias; + static const int kDpDenormalExponent = -kDpExponentBias + 1; + static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + uint64_t f; + int e; +}; + +inline DiyFp GetCachedPowerByIndex(size_t index) { + // 10^-348, 10^-340, ..., 10^340 + static const uint64_t kCachedPowers_F[] = { + RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76), + RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea), + RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df), + RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f), + RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c), + RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5), + RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d), + RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637), + RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7), + RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5), + RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b), + RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996), + RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6), + RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8), + RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053), + RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd), + RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94), + RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b), + RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac), + RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3), + RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb), + RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c), + RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000), + RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984), + RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70), + RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245), + RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8), + RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a), + RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea), + RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85), + RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2), + RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3), + RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25), + RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece), + RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5), + RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a), + RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c), + RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a), + RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129), + RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429), + RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d), + RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841), + RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9), + RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b) + }; + static const int16_t kCachedPowers_E[] = { + -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, + -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, + -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, + -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, + -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, + 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, + 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, + 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, + 907, 933, 960, 986, 1013, 1039, 1066 + }; + RAPIDJSON_ASSERT(index < 87); + return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); +} + +inline DiyFp GetCachedPower(int e, int* K) { + + //int k = static_cast(ceil((-61 - e) * 0.30102999566398114)) + 374; + double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive + int k = static_cast(dk); + if (dk - k > 0.0) + k++; + + unsigned index = static_cast((k >> 3) + 1); + *K = -(-348 + static_cast(index << 3)); // decimal exponent no need lookup table + + return GetCachedPowerByIndex(index); +} + +inline DiyFp GetCachedPower10(int exp, int *outExp) { + RAPIDJSON_ASSERT(exp >= -348); + unsigned index = static_cast(exp + 348) / 8u; + *outExp = -348 + static_cast(index) * 8; + return GetCachedPowerByIndex(index); +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +RAPIDJSON_DIAG_OFF(padded) +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DIYFP_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/dtoa.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/dtoa.h new file mode 100644 index 00000000..91c5756d --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/dtoa.h @@ -0,0 +1,249 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DTOA_ +#define RAPIDJSON_DTOA_ + +#include "itoa.h" // GetDigitsLut() +#include "diyfp.h" +#include "ieee754.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124 +#endif + +inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { + while (rest < wp_w && delta - rest >= ten_kappa && + (rest + ten_kappa < wp_w || /// closer + wp_w - rest > rest + ten_kappa - wp_w)) { + buffer[len - 1]--; + rest += ten_kappa; + } +} + +inline int CountDecimalDigit32(uint32_t n) { + // Simple pure C++ implementation was faster than __builtin_clz version in this situation. + if (n < 10) return 1; + if (n < 100) return 2; + if (n < 1000) return 3; + if (n < 10000) return 4; + if (n < 100000) return 5; + if (n < 1000000) return 6; + if (n < 10000000) return 7; + if (n < 100000000) return 8; + // Will not reach 10 digits in DigitGen() + //if (n < 1000000000) return 9; + //return 10; + return 9; +} + +inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { + static const uint64_t kPow10[] = { 1ULL, 10ULL, 100ULL, 1000ULL, 10000ULL, 100000ULL, 1000000ULL, 10000000ULL, 100000000ULL, + 1000000000ULL, 10000000000ULL, 100000000000ULL, 1000000000000ULL, + 10000000000000ULL, 100000000000000ULL, 1000000000000000ULL, + 10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL, + 10000000000000000000ULL }; + const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); + const DiyFp wp_w = Mp - W; + uint32_t p1 = static_cast(Mp.f >> -one.e); + uint64_t p2 = Mp.f & (one.f - 1); + int kappa = CountDecimalDigit32(p1); // kappa in [0, 9] + *len = 0; + + while (kappa > 0) { + uint32_t d = 0; + switch (kappa) { + case 9: d = p1 / 100000000; p1 %= 100000000; break; + case 8: d = p1 / 10000000; p1 %= 10000000; break; + case 7: d = p1 / 1000000; p1 %= 1000000; break; + case 6: d = p1 / 100000; p1 %= 100000; break; + case 5: d = p1 / 10000; p1 %= 10000; break; + case 4: d = p1 / 1000; p1 %= 1000; break; + case 3: d = p1 / 100; p1 %= 100; break; + case 2: d = p1 / 10; p1 %= 10; break; + case 1: d = p1; p1 = 0; break; + default:; + } + if (d || *len) + buffer[(*len)++] = static_cast('0' + static_cast(d)); + kappa--; + uint64_t tmp = (static_cast(p1) << -one.e) + p2; + if (tmp <= delta) { + *K += kappa; + GrisuRound(buffer, *len, delta, tmp, kPow10[kappa] << -one.e, wp_w.f); + return; + } + } + + // kappa = 0 + for (;;) { + p2 *= 10; + delta *= 10; + char d = static_cast(p2 >> -one.e); + if (d || *len) + buffer[(*len)++] = static_cast('0' + d); + p2 &= one.f - 1; + kappa--; + if (p2 < delta) { + *K += kappa; + int index = -kappa; + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 20 ? kPow10[index] : 0)); + return; + } + } +} + +inline void Grisu2(double value, char* buffer, int* length, int* K) { + const DiyFp v(value); + DiyFp w_m, w_p; + v.NormalizedBoundaries(&w_m, &w_p); + + const DiyFp c_mk = GetCachedPower(w_p.e, K); + const DiyFp W = v.Normalize() * c_mk; + DiyFp Wp = w_p * c_mk; + DiyFp Wm = w_m * c_mk; + Wm.f++; + Wp.f--; + DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); +} + +inline char* WriteExponent(int K, char* buffer) { + if (K < 0) { + *buffer++ = '-'; + K = -K; + } + + if (K >= 100) { + *buffer++ = static_cast('0' + static_cast(K / 100)); + K %= 100; + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else if (K >= 10) { + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else + *buffer++ = static_cast('0' + static_cast(K)); + + return buffer; +} + +inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) { + const int kk = length + k; // 10^(kk-1) <= v < 10^kk + + if (0 <= k && kk <= 21) { + // 1234e7 -> 12340000000 + for (int i = length; i < kk; i++) + buffer[i] = '0'; + buffer[kk] = '.'; + buffer[kk + 1] = '0'; + return &buffer[kk + 2]; + } + else if (0 < kk && kk <= 21) { + // 1234e-2 -> 12.34 + std::memmove(&buffer[kk + 1], &buffer[kk], static_cast(length - kk)); + buffer[kk] = '.'; + if (0 > k + maxDecimalPlaces) { + // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1 + // Remove extra trailing zeros (at least one) after truncation. + for (int i = kk + maxDecimalPlaces; i > kk + 1; i--) + if (buffer[i] != '0') + return &buffer[i + 1]; + return &buffer[kk + 2]; // Reserve one zero + } + else + return &buffer[length + 1]; + } + else if (-6 < kk && kk <= 0) { + // 1234e-6 -> 0.001234 + const int offset = 2 - kk; + std::memmove(&buffer[offset], &buffer[0], static_cast(length)); + buffer[0] = '0'; + buffer[1] = '.'; + for (int i = 2; i < offset; i++) + buffer[i] = '0'; + if (length - kk > maxDecimalPlaces) { + // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1 + // Remove extra trailing zeros (at least one) after truncation. + for (int i = maxDecimalPlaces + 1; i > 2; i--) + if (buffer[i] != '0') + return &buffer[i + 1]; + return &buffer[3]; // Reserve one zero + } + else + return &buffer[length + offset]; + } + else if (kk < -maxDecimalPlaces) { + // Truncate to zero + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else if (length == 1) { + // 1e30 + buffer[1] = 'e'; + return WriteExponent(kk - 1, &buffer[2]); + } + else { + // 1234e30 -> 1.234e33 + std::memmove(&buffer[2], &buffer[1], static_cast(length - 1)); + buffer[1] = '.'; + buffer[length + 1] = 'e'; + return WriteExponent(kk - 1, &buffer[0 + length + 2]); + } +} + +inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) { + RAPIDJSON_ASSERT(maxDecimalPlaces >= 1); + Double d(value); + if (d.IsZero()) { + if (d.Sign()) + *buffer++ = '-'; // -0.0, Issue #289 + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else { + if (value < 0) { + *buffer++ = '-'; + value = -value; + } + int length, K; + Grisu2(value, buffer, &length, &K); + return Prettify(buffer, length, K, maxDecimalPlaces); + } +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DTOA_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/ieee754.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/ieee754.h new file mode 100644 index 00000000..f887d1b2 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/ieee754.h @@ -0,0 +1,78 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_IEEE754_ +#define RAPIDJSON_IEEE754_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class Double { +public: + Double() {} + Double(double d) : d_(d) {} + Double(uint64_t u) : u_(u) {} + + double Value() const { return d_; } + uint64_t Uint64Value() const { return u_; } + + double NextPositiveDouble() const { + RAPIDJSON_ASSERT(!Sign()); + return Double(u_ + 1).Value(); + } + + bool Sign() const { return (u_ & kSignMask) != 0; } + uint64_t Significand() const { return u_ & kSignificandMask; } + int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } + + bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } + bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } + bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } + bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } + bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } + + uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } + int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } + uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } + + static int EffectiveSignificandSize(int order) { + if (order >= -1021) + return 53; + else if (order <= -1074) + return 0; + else + return order + 1074; + } + +private: + static const int kSignificandSize = 52; + static const int kExponentBias = 0x3FF; + static const int kDenormalExponent = 1 - kExponentBias; + static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); + static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + union { + double d_; + uint64_t u_; + }; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_IEEE754_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/itoa.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/itoa.h new file mode 100644 index 00000000..9fe8c932 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/itoa.h @@ -0,0 +1,308 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ITOA_ +#define RAPIDJSON_ITOA_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline const char* GetDigitsLut() { + static const char cDigitsLut[200] = { + '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', + '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', + '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', + '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', + '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', + '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', + '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', + '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', + '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', + '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' + }; + return cDigitsLut; +} + +inline char* u32toa(uint32_t value, char* buffer) { + RAPIDJSON_ASSERT(buffer != 0); + + const char* cDigitsLut = GetDigitsLut(); + + if (value < 10000) { + const uint32_t d1 = (value / 100) << 1; + const uint32_t d2 = (value % 100) << 1; + + if (value >= 1000) + *buffer++ = cDigitsLut[d1]; + if (value >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else if (value < 100000000) { + // value = bbbbcccc + const uint32_t b = value / 10000; + const uint32_t c = value % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + else { + // value = aabbbbcccc in decimal + + const uint32_t a = value / 100000000; // 1 to 42 + value %= 100000000; + + if (a >= 10) { + const unsigned i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else + *buffer++ = static_cast('0' + static_cast(a)); + + const uint32_t b = value / 10000; // 0 to 9999 + const uint32_t c = value % 10000; // 0 to 9999 + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + return buffer; +} + +inline char* i32toa(int32_t value, char* buffer) { + RAPIDJSON_ASSERT(buffer != 0); + uint32_t u = static_cast(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u32toa(u, buffer); +} + +inline char* u64toa(uint64_t value, char* buffer) { + RAPIDJSON_ASSERT(buffer != 0); + const char* cDigitsLut = GetDigitsLut(); + const uint64_t kTen8 = 100000000; + const uint64_t kTen9 = kTen8 * 10; + const uint64_t kTen10 = kTen8 * 100; + const uint64_t kTen11 = kTen8 * 1000; + const uint64_t kTen12 = kTen8 * 10000; + const uint64_t kTen13 = kTen8 * 100000; + const uint64_t kTen14 = kTen8 * 1000000; + const uint64_t kTen15 = kTen8 * 10000000; + const uint64_t kTen16 = kTen8 * kTen8; + + if (value < kTen8) { + uint32_t v = static_cast(value); + if (v < 10000) { + const uint32_t d1 = (v / 100) << 1; + const uint32_t d2 = (v % 100) << 1; + + if (v >= 1000) + *buffer++ = cDigitsLut[d1]; + if (v >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (v >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else { + // value = bbbbcccc + const uint32_t b = v / 10000; + const uint32_t c = v % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + } + else if (value < kTen16) { + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + if (value >= kTen15) + *buffer++ = cDigitsLut[d1]; + if (value >= kTen14) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= kTen13) + *buffer++ = cDigitsLut[d2]; + if (value >= kTen12) + *buffer++ = cDigitsLut[d2 + 1]; + if (value >= kTen11) + *buffer++ = cDigitsLut[d3]; + if (value >= kTen10) + *buffer++ = cDigitsLut[d3 + 1]; + if (value >= kTen9) + *buffer++ = cDigitsLut[d4]; + + *buffer++ = cDigitsLut[d4 + 1]; + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + else { + const uint32_t a = static_cast(value / kTen16); // 1 to 1844 + value %= kTen16; + + if (a < 10) + *buffer++ = static_cast('0' + static_cast(a)); + else if (a < 100) { + const uint32_t i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else if (a < 1000) { + *buffer++ = static_cast('0' + static_cast(a / 100)); + + const uint32_t i = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else { + const uint32_t i = (a / 100) << 1; + const uint32_t j = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + *buffer++ = cDigitsLut[j]; + *buffer++ = cDigitsLut[j + 1]; + } + + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + + return buffer; +} + +inline char* i64toa(int64_t value, char* buffer) { + RAPIDJSON_ASSERT(buffer != 0); + uint64_t u = static_cast(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u64toa(u, buffer); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ITOA_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/meta.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/meta.h new file mode 100644 index 00000000..76a1d5be --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/meta.h @@ -0,0 +1,186 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_META_H_ +#define RAPIDJSON_INTERNAL_META_H_ + +#include "../rapidjson.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(6334) +#endif + +#if RAPIDJSON_HAS_CXX11_TYPETRAITS +#include +#endif + +//@cond RAPIDJSON_INTERNAL +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching +template struct Void { typedef void Type; }; + +/////////////////////////////////////////////////////////////////////////////// +// BoolType, TrueType, FalseType +// +template struct BoolType { + static const bool Value = Cond; + typedef BoolType Type; +}; +typedef BoolType TrueType; +typedef BoolType FalseType; + + +/////////////////////////////////////////////////////////////////////////////// +// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr +// + +template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; }; +template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; }; +template struct SelectIfCond : SelectIfImpl::template Apply {}; +template struct SelectIf : SelectIfCond {}; + +template struct AndExprCond : FalseType {}; +template <> struct AndExprCond : TrueType {}; +template struct OrExprCond : TrueType {}; +template <> struct OrExprCond : FalseType {}; + +template struct BoolExpr : SelectIf::Type {}; +template struct NotExpr : SelectIf::Type {}; +template struct AndExpr : AndExprCond::Type {}; +template struct OrExpr : OrExprCond::Type {}; + + +/////////////////////////////////////////////////////////////////////////////// +// AddConst, MaybeAddConst, RemoveConst +template struct AddConst { typedef const T Type; }; +template struct MaybeAddConst : SelectIfCond {}; +template struct RemoveConst { typedef T Type; }; +template struct RemoveConst { typedef T Type; }; + + +/////////////////////////////////////////////////////////////////////////////// +// IsSame, IsConst, IsMoreConst, IsPointer +// +template struct IsSame : FalseType {}; +template struct IsSame : TrueType {}; + +template struct IsConst : FalseType {}; +template struct IsConst : TrueType {}; + +template +struct IsMoreConst + : AndExpr::Type, typename RemoveConst::Type>, + BoolType::Value >= IsConst::Value> >::Type {}; + +template struct IsPointer : FalseType {}; +template struct IsPointer : TrueType {}; + +/////////////////////////////////////////////////////////////////////////////// +// IsBaseOf +// +#if RAPIDJSON_HAS_CXX11_TYPETRAITS + +template struct IsBaseOf + : BoolType< ::std::is_base_of::value> {}; + +#else // simplified version adopted from Boost + +template struct IsBaseOfImpl { + RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); + RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); + + typedef char (&Yes)[1]; + typedef char (&No) [2]; + + template + static Yes Check(const D*, T); + static No Check(const B*, int); + + struct Host { + operator const B*() const; + operator const D*(); + }; + + enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; +}; + +template struct IsBaseOf + : OrExpr, BoolExpr > >::Type {}; + +#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS + + +////////////////////////////////////////////////////////////////////////// +// EnableIf / DisableIf +// +template struct EnableIfCond { typedef T Type; }; +template struct EnableIfCond { /* empty */ }; + +template struct DisableIfCond { typedef T Type; }; +template struct DisableIfCond { /* empty */ }; + +template +struct EnableIf : EnableIfCond {}; + +template +struct DisableIf : DisableIfCond {}; + +// SFINAE helpers +struct SfinaeTag {}; +template struct RemoveSfinaeTag; +template struct RemoveSfinaeTag { typedef T Type; }; + +#define RAPIDJSON_REMOVEFPTR_(type) \ + typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ + < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type + +#define RAPIDJSON_ENABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + ::Type * = NULL + +#define RAPIDJSON_DISABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + ::Type * = NULL + +#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + ::Type + +#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + ::Type + +} // namespace internal +RAPIDJSON_NAMESPACE_END +//@endcond + +#if defined(_MSC_VER) && !defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_META_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/pow10.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/pow10.h new file mode 100644 index 00000000..04ee1f6b --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/pow10.h @@ -0,0 +1,55 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POW10_ +#define RAPIDJSON_POW10_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Computes integer powers of 10 in double (10.0^n). +/*! This function uses lookup table for fast and accurate results. + \param n non-negative exponent. Must <= 308. + \return 10.0^n +*/ +inline double Pow10(int n) { + static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes + 1e+0, + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 + }; + RAPIDJSON_ASSERT(n >= 0 && n <= 308); + return e[n]; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_POW10_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/regex.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/regex.h new file mode 100644 index 00000000..e3712610 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/regex.h @@ -0,0 +1,739 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_REGEX_H_ +#define RAPIDJSON_INTERNAL_REGEX_H_ + +#include "../allocators.h" +#include "../stream.h" +#include "stack.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifndef RAPIDJSON_REGEX_VERBOSE +#define RAPIDJSON_REGEX_VERBOSE 0 +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// DecodedStream + +template +class DecodedStream { +public: + DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); } + unsigned Peek() { return codepoint_; } + unsigned Take() { + unsigned c = codepoint_; + if (c) // No further decoding when '\0' + Decode(); + return c; + } + +private: + void Decode() { + if (!Encoding::Decode(ss_, &codepoint_)) + codepoint_ = 0; + } + + SourceStream& ss_; + unsigned codepoint_; +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericRegex + +static const SizeType kRegexInvalidState = ~SizeType(0); //!< Represents an invalid index in GenericRegex::State::out, out1 +static const SizeType kRegexInvalidRange = ~SizeType(0); + +template +class GenericRegexSearch; + +//! Regular expression engine with subset of ECMAscript grammar. +/*! + Supported regular expression syntax: + - \c ab Concatenation + - \c a|b Alternation + - \c a? Zero or one + - \c a* Zero or more + - \c a+ One or more + - \c a{3} Exactly 3 times + - \c a{3,} At least 3 times + - \c a{3,5} 3 to 5 times + - \c (ab) Grouping + - \c ^a At the beginning + - \c a$ At the end + - \c . Any character + - \c [abc] Character classes + - \c [a-c] Character class range + - \c [a-z0-9_] Character class combination + - \c [^abc] Negated character classes + - \c [^a-c] Negated character class range + - \c [\b] Backspace (U+0008) + - \c \\| \\\\ ... Escape characters + - \c \\f Form feed (U+000C) + - \c \\n Line feed (U+000A) + - \c \\r Carriage return (U+000D) + - \c \\t Tab (U+0009) + - \c \\v Vertical tab (U+000B) + + \note This is a Thompson NFA engine, implemented with reference to + Cox, Russ. "Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).", + https://swtch.com/~rsc/regexp/regexp1.html +*/ +template +class GenericRegex { +public: + typedef Encoding EncodingType; + typedef typename Encoding::Ch Ch; + template friend class GenericRegexSearch; + + GenericRegex(const Ch* source, Allocator* allocator = 0) : + ownAllocator_(allocator ? 0 : RAPIDJSON_NEW(Allocator)()), allocator_(allocator ? allocator : ownAllocator_), + states_(allocator_, 256), ranges_(allocator_, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), + anchorBegin_(), anchorEnd_() + { + GenericStringStream ss(source); + DecodedStream, Encoding> ds(ss); + Parse(ds); + } + + ~GenericRegex() + { + RAPIDJSON_DELETE(ownAllocator_); + } + + bool IsValid() const { + return root_ != kRegexInvalidState; + } + +private: + enum Operator { + kZeroOrOne, + kZeroOrMore, + kOneOrMore, + kConcatenation, + kAlternation, + kLeftParenthesis + }; + + static const unsigned kAnyCharacterClass = 0xFFFFFFFF; //!< For '.' + static const unsigned kRangeCharacterClass = 0xFFFFFFFE; + static const unsigned kRangeNegationFlag = 0x80000000; + + struct Range { + unsigned start; // + unsigned end; + SizeType next; + }; + + struct State { + SizeType out; //!< Equals to kInvalid for matching state + SizeType out1; //!< Equals to non-kInvalid for split + SizeType rangeStart; + unsigned codepoint; + }; + + struct Frag { + Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {} + SizeType start; + SizeType out; //!< link-list of all output states + SizeType minIndex; + }; + + State& GetState(SizeType index) { + RAPIDJSON_ASSERT(index < stateCount_); + return states_.template Bottom()[index]; + } + + const State& GetState(SizeType index) const { + RAPIDJSON_ASSERT(index < stateCount_); + return states_.template Bottom()[index]; + } + + Range& GetRange(SizeType index) { + RAPIDJSON_ASSERT(index < rangeCount_); + return ranges_.template Bottom()[index]; + } + + const Range& GetRange(SizeType index) const { + RAPIDJSON_ASSERT(index < rangeCount_); + return ranges_.template Bottom()[index]; + } + + template + void Parse(DecodedStream& ds) { + Stack operandStack(allocator_, 256); // Frag + Stack operatorStack(allocator_, 256); // Operator + Stack atomCountStack(allocator_, 256); // unsigned (Atom per parenthesis) + + *atomCountStack.template Push() = 0; + + unsigned codepoint; + while (ds.Peek() != 0) { + switch (codepoint = ds.Take()) { + case '^': + anchorBegin_ = true; + break; + + case '$': + anchorEnd_ = true; + break; + + case '|': + while (!operatorStack.Empty() && *operatorStack.template Top() < kAlternation) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + *operatorStack.template Push() = kAlternation; + *atomCountStack.template Top() = 0; + break; + + case '(': + *operatorStack.template Push() = kLeftParenthesis; + *atomCountStack.template Push() = 0; + break; + + case ')': + while (!operatorStack.Empty() && *operatorStack.template Top() != kLeftParenthesis) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + if (operatorStack.Empty()) + return; + operatorStack.template Pop(1); + atomCountStack.template Pop(1); + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '?': + if (!Eval(operandStack, kZeroOrOne)) + return; + break; + + case '*': + if (!Eval(operandStack, kZeroOrMore)) + return; + break; + + case '+': + if (!Eval(operandStack, kOneOrMore)) + return; + break; + + case '{': + { + unsigned n, m; + if (!ParseUnsigned(ds, &n)) + return; + + if (ds.Peek() == ',') { + ds.Take(); + if (ds.Peek() == '}') + m = kInfinityQuantifier; + else if (!ParseUnsigned(ds, &m) || m < n) + return; + } + else + m = n; + + if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}') + return; + ds.Take(); + } + break; + + case '.': + PushOperand(operandStack, kAnyCharacterClass); + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '[': + { + SizeType range; + if (!ParseRange(ds, &range)) + return; + SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass); + GetState(s).rangeStart = range; + *operandStack.template Push() = Frag(s, s, s); + } + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '\\': // Escape character + if (!CharacterEscape(ds, &codepoint)) + return; // Unsupported escape character + // fall through to default + RAPIDJSON_DELIBERATE_FALLTHROUGH; + + default: // Pattern character + PushOperand(operandStack, codepoint); + ImplicitConcatenation(atomCountStack, operatorStack); + } + } + + while (!operatorStack.Empty()) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + + // Link the operand to matching state. + if (operandStack.GetSize() == sizeof(Frag)) { + Frag* e = operandStack.template Pop(1); + Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0)); + root_ = e->start; + +#if RAPIDJSON_REGEX_VERBOSE + printf("root: %d\n", root_); + for (SizeType i = 0; i < stateCount_ ; i++) { + State& s = GetState(i); + printf("[%2d] out: %2d out1: %2d c: '%c'\n", i, s.out, s.out1, (char)s.codepoint); + } + printf("\n"); +#endif + } + } + + SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) { + State* s = states_.template Push(); + s->out = out; + s->out1 = out1; + s->codepoint = codepoint; + s->rangeStart = kRegexInvalidRange; + return stateCount_++; + } + + void PushOperand(Stack& operandStack, unsigned codepoint) { + SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint); + *operandStack.template Push() = Frag(s, s, s); + } + + void ImplicitConcatenation(Stack& atomCountStack, Stack& operatorStack) { + if (*atomCountStack.template Top()) + *operatorStack.template Push() = kConcatenation; + (*atomCountStack.template Top())++; + } + + SizeType Append(SizeType l1, SizeType l2) { + SizeType old = l1; + while (GetState(l1).out != kRegexInvalidState) + l1 = GetState(l1).out; + GetState(l1).out = l2; + return old; + } + + void Patch(SizeType l, SizeType s) { + for (SizeType next; l != kRegexInvalidState; l = next) { + next = GetState(l).out; + GetState(l).out = s; + } + } + + bool Eval(Stack& operandStack, Operator op) { + switch (op) { + case kConcatenation: + RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2); + { + Frag e2 = *operandStack.template Pop(1); + Frag e1 = *operandStack.template Pop(1); + Patch(e1.out, e2.start); + *operandStack.template Push() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex)); + } + return true; + + case kAlternation: + if (operandStack.GetSize() >= sizeof(Frag) * 2) { + Frag e2 = *operandStack.template Pop(1); + Frag e1 = *operandStack.template Pop(1); + SizeType s = NewState(e1.start, e2.start, 0); + *operandStack.template Push() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex)); + return true; + } + return false; + + case kZeroOrOne: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + *operandStack.template Push() = Frag(s, Append(e.out, s), e.minIndex); + return true; + } + return false; + + case kZeroOrMore: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + Patch(e.out, s); + *operandStack.template Push() = Frag(s, s, e.minIndex); + return true; + } + return false; + + case kOneOrMore: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + Patch(e.out, s); + *operandStack.template Push() = Frag(e.start, s, e.minIndex); + return true; + } + return false; + + default: + // syntax error (e.g. unclosed kLeftParenthesis) + return false; + } + } + + bool EvalQuantifier(Stack& operandStack, unsigned n, unsigned m) { + RAPIDJSON_ASSERT(n <= m); + RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag)); + + if (n == 0) { + if (m == 0) // a{0} not support + return false; + else if (m == kInfinityQuantifier) + Eval(operandStack, kZeroOrMore); // a{0,} -> a* + else { + Eval(operandStack, kZeroOrOne); // a{0,5} -> a? + for (unsigned i = 0; i < m - 1; i++) + CloneTopOperand(operandStack); // a{0,5} -> a? a? a? a? a? + for (unsigned i = 0; i < m - 1; i++) + Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a? + } + return true; + } + + for (unsigned i = 0; i < n - 1; i++) // a{3} -> a a a + CloneTopOperand(operandStack); + + if (m == kInfinityQuantifier) + Eval(operandStack, kOneOrMore); // a{3,} -> a a a+ + else if (m > n) { + CloneTopOperand(operandStack); // a{3,5} -> a a a a + Eval(operandStack, kZeroOrOne); // a{3,5} -> a a a a? + for (unsigned i = n; i < m - 1; i++) + CloneTopOperand(operandStack); // a{3,5} -> a a a a? a? + for (unsigned i = n; i < m; i++) + Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a? + } + + for (unsigned i = 0; i < n - 1; i++) + Eval(operandStack, kConcatenation); // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a? + + return true; + } + + static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; } + + void CloneTopOperand(Stack& operandStack) { + const Frag src = *operandStack.template Top(); // Copy constructor to prevent invalidation + SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_) + State* s = states_.template Push(count); + memcpy(s, &GetState(src.minIndex), count * sizeof(State)); + for (SizeType j = 0; j < count; j++) { + if (s[j].out != kRegexInvalidState) + s[j].out += count; + if (s[j].out1 != kRegexInvalidState) + s[j].out1 += count; + } + *operandStack.template Push() = Frag(src.start + count, src.out + count, src.minIndex + count); + stateCount_ += count; + } + + template + bool ParseUnsigned(DecodedStream& ds, unsigned* u) { + unsigned r = 0; + if (ds.Peek() < '0' || ds.Peek() > '9') + return false; + while (ds.Peek() >= '0' && ds.Peek() <= '9') { + if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295 + return false; // overflow + r = r * 10 + (ds.Take() - '0'); + } + *u = r; + return true; + } + + template + bool ParseRange(DecodedStream& ds, SizeType* range) { + bool isBegin = true; + bool negate = false; + int step = 0; + SizeType start = kRegexInvalidRange; + SizeType current = kRegexInvalidRange; + unsigned codepoint; + while ((codepoint = ds.Take()) != 0) { + if (isBegin) { + isBegin = false; + if (codepoint == '^') { + negate = true; + continue; + } + } + + switch (codepoint) { + case ']': + if (start == kRegexInvalidRange) + return false; // Error: nothing inside [] + if (step == 2) { // Add trailing '-' + SizeType r = NewRange('-'); + RAPIDJSON_ASSERT(current != kRegexInvalidRange); + GetRange(current).next = r; + } + if (negate) + GetRange(start).start |= kRangeNegationFlag; + *range = start; + return true; + + case '\\': + if (ds.Peek() == 'b') { + ds.Take(); + codepoint = 0x0008; // Escape backspace character + } + else if (!CharacterEscape(ds, &codepoint)) + return false; + // fall through to default + RAPIDJSON_DELIBERATE_FALLTHROUGH; + + default: + switch (step) { + case 1: + if (codepoint == '-') { + step++; + break; + } + // fall through to step 0 for other characters + RAPIDJSON_DELIBERATE_FALLTHROUGH; + + case 0: + { + SizeType r = NewRange(codepoint); + if (current != kRegexInvalidRange) + GetRange(current).next = r; + if (start == kRegexInvalidRange) + start = r; + current = r; + } + step = 1; + break; + + default: + RAPIDJSON_ASSERT(step == 2); + GetRange(current).end = codepoint; + step = 0; + } + } + } + return false; + } + + SizeType NewRange(unsigned codepoint) { + Range* r = ranges_.template Push(); + r->start = r->end = codepoint; + r->next = kRegexInvalidRange; + return rangeCount_++; + } + + template + bool CharacterEscape(DecodedStream& ds, unsigned* escapedCodepoint) { + unsigned codepoint; + switch (codepoint = ds.Take()) { + case '^': + case '$': + case '|': + case '(': + case ')': + case '?': + case '*': + case '+': + case '.': + case '[': + case ']': + case '{': + case '}': + case '\\': + *escapedCodepoint = codepoint; return true; + case 'f': *escapedCodepoint = 0x000C; return true; + case 'n': *escapedCodepoint = 0x000A; return true; + case 'r': *escapedCodepoint = 0x000D; return true; + case 't': *escapedCodepoint = 0x0009; return true; + case 'v': *escapedCodepoint = 0x000B; return true; + default: + return false; // Unsupported escape character + } + } + + Allocator* ownAllocator_; + Allocator* allocator_; + Stack states_; + Stack ranges_; + SizeType root_; + SizeType stateCount_; + SizeType rangeCount_; + + static const unsigned kInfinityQuantifier = ~0u; + + // For SearchWithAnchoring() + bool anchorBegin_; + bool anchorEnd_; +}; + +template +class GenericRegexSearch { +public: + typedef typename RegexType::EncodingType Encoding; + typedef typename Encoding::Ch Ch; + + GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) : + regex_(regex), allocator_(allocator), ownAllocator_(0), + state0_(allocator, 0), state1_(allocator, 0), stateSet_() + { + RAPIDJSON_ASSERT(regex_.IsValid()); + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + stateSet_ = static_cast(allocator_->Malloc(GetStateSetSize())); + state0_.template Reserve(regex_.stateCount_); + state1_.template Reserve(regex_.stateCount_); + } + + ~GenericRegexSearch() { + Allocator::Free(stateSet_); + RAPIDJSON_DELETE(ownAllocator_); + } + + template + bool Match(InputStream& is) { + return SearchWithAnchoring(is, true, true); + } + + bool Match(const Ch* s) { + GenericStringStream is(s); + return Match(is); + } + + template + bool Search(InputStream& is) { + return SearchWithAnchoring(is, regex_.anchorBegin_, regex_.anchorEnd_); + } + + bool Search(const Ch* s) { + GenericStringStream is(s); + return Search(is); + } + +private: + typedef typename RegexType::State State; + typedef typename RegexType::Range Range; + + template + bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) { + DecodedStream ds(is); + + state0_.Clear(); + Stack *current = &state0_, *next = &state1_; + const size_t stateSetSize = GetStateSetSize(); + std::memset(stateSet_, 0, stateSetSize); + + bool matched = AddState(*current, regex_.root_); + unsigned codepoint; + while (!current->Empty() && (codepoint = ds.Take()) != 0) { + std::memset(stateSet_, 0, stateSetSize); + next->Clear(); + matched = false; + for (const SizeType* s = current->template Bottom(); s != current->template End(); ++s) { + const State& sr = regex_.GetState(*s); + if (sr.codepoint == codepoint || + sr.codepoint == RegexType::kAnyCharacterClass || + (sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint))) + { + matched = AddState(*next, sr.out) || matched; + if (!anchorEnd && matched) + return true; + } + if (!anchorBegin) + AddState(*next, regex_.root_); + } + internal::Swap(current, next); + } + + return matched; + } + + size_t GetStateSetSize() const { + return (regex_.stateCount_ + 31) / 32 * 4; + } + + // Return whether the added states is a match state + bool AddState(Stack& l, SizeType index) { + RAPIDJSON_ASSERT(index != kRegexInvalidState); + + const State& s = regex_.GetState(index); + if (s.out1 != kRegexInvalidState) { // Split + bool matched = AddState(l, s.out); + return AddState(l, s.out1) || matched; + } + else if (!(stateSet_[index >> 5] & (1u << (index & 31)))) { + stateSet_[index >> 5] |= (1u << (index & 31)); + *l.template PushUnsafe() = index; + } + return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation. + } + + bool MatchRange(SizeType rangeIndex, unsigned codepoint) const { + bool yes = (regex_.GetRange(rangeIndex).start & RegexType::kRangeNegationFlag) == 0; + while (rangeIndex != kRegexInvalidRange) { + const Range& r = regex_.GetRange(rangeIndex); + if (codepoint >= (r.start & ~RegexType::kRangeNegationFlag) && codepoint <= r.end) + return yes; + rangeIndex = r.next; + } + return !yes; + } + + const RegexType& regex_; + Allocator* allocator_; + Allocator* ownAllocator_; + Stack state0_; + Stack state1_; + uint32_t* stateSet_; +}; + +typedef GenericRegex > Regex; +typedef GenericRegexSearch RegexSearch; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_REGEX_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/stack.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/stack.h new file mode 100644 index 00000000..ceead449 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/stack.h @@ -0,0 +1,232 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STACK_H_ +#define RAPIDJSON_INTERNAL_STACK_H_ + +#include "../allocators.h" +#include "swap.h" +#include + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// Stack + +//! A type-unsafe stack for storing different types of data. +/*! \tparam Allocator Allocator for allocating stack memory. +*/ +template +class Stack { +public: + // Optimization note: Do not allocate memory for stack_ in constructor. + // Do it lazily when first Push() -> Expand() -> Resize(). + Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack(Stack&& rhs) + : allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(rhs.stack_), + stackTop_(rhs.stackTop_), + stackEnd_(rhs.stackEnd_), + initialCapacity_(rhs.initialCapacity_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } +#endif + + ~Stack() { + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack& operator=(Stack&& rhs) { + if (&rhs != this) + { + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = rhs.stack_; + stackTop_ = rhs.stackTop_; + stackEnd_ = rhs.stackEnd_; + initialCapacity_ = rhs.initialCapacity_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } + return *this; + } +#endif + + void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT { + internal::Swap(allocator_, rhs.allocator_); + internal::Swap(ownAllocator_, rhs.ownAllocator_); + internal::Swap(stack_, rhs.stack_); + internal::Swap(stackTop_, rhs.stackTop_); + internal::Swap(stackEnd_, rhs.stackEnd_); + internal::Swap(initialCapacity_, rhs.initialCapacity_); + } + + void Clear() { stackTop_ = stack_; } + + void ShrinkToFit() { + if (Empty()) { + // If the stack is empty, completely deallocate the memory. + Allocator::Free(stack_); // NOLINT (+clang-analyzer-unix.Malloc) + stack_ = 0; + stackTop_ = 0; + stackEnd_ = 0; + } + else + Resize(GetSize()); + } + + // Optimization note: try to minimize the size of this function for force inline. + // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. + template + RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) { + // Expand the stack if needed + if (RAPIDJSON_UNLIKELY(static_cast(sizeof(T) * count) > (stackEnd_ - stackTop_))) + Expand(count); + } + + template + RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { + Reserve(count); + return PushUnsafe(count); + } + + template + RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) { + RAPIDJSON_ASSERT(stackTop_); + RAPIDJSON_ASSERT(static_cast(sizeof(T) * count) <= (stackEnd_ - stackTop_)); + T* ret = reinterpret_cast(stackTop_); + stackTop_ += sizeof(T) * count; + return ret; + } + + template + T* Pop(size_t count) { + RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); + stackTop_ -= count * sizeof(T); + return reinterpret_cast(stackTop_); + } + + template + T* Top() { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + const T* Top() const { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + T* End() { return reinterpret_cast(stackTop_); } + + template + const T* End() const { return reinterpret_cast(stackTop_); } + + template + T* Bottom() { return reinterpret_cast(stack_); } + + template + const T* Bottom() const { return reinterpret_cast(stack_); } + + bool HasAllocator() const { + return allocator_ != 0; + } + + Allocator& GetAllocator() { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + + bool Empty() const { return stackTop_ == stack_; } + size_t GetSize() const { return static_cast(stackTop_ - stack_); } + size_t GetCapacity() const { return static_cast(stackEnd_ - stack_); } + +private: + template + void Expand(size_t count) { + // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. + size_t newCapacity; + if (stack_ == 0) { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + newCapacity = initialCapacity_; + } else { + newCapacity = GetCapacity(); + newCapacity += (newCapacity + 1) / 2; + } + size_t newSize = GetSize() + sizeof(T) * count; + if (newCapacity < newSize) + newCapacity = newSize; + + Resize(newCapacity); + } + + void Resize(size_t newCapacity) { + const size_t size = GetSize(); // Backup the current size + stack_ = static_cast(allocator_->Realloc(stack_, GetCapacity(), newCapacity)); + stackTop_ = stack_ + size; + stackEnd_ = stack_ + newCapacity; + } + + void Destroy() { + Allocator::Free(stack_); + RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack + } + + // Prohibit copy constructor & assignment operator. + Stack(const Stack&); + Stack& operator=(const Stack&); + + Allocator* allocator_; + Allocator* ownAllocator_; + char *stack_; + char *stackTop_; + char *stackEnd_; + size_t initialCapacity_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_STACK_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/strfunc.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/strfunc.h new file mode 100644 index 00000000..1a88f49b --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/strfunc.h @@ -0,0 +1,83 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ +#define RAPIDJSON_INTERNAL_STRFUNC_H_ + +#include "../stream.h" +#include + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom strlen() which works on different character types. +/*! \tparam Ch Character type (e.g. char, wchar_t, short) + \param s Null-terminated input string. + \return Number of characters in the string. + \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. +*/ +template +inline SizeType StrLen(const Ch* s) { + RAPIDJSON_ASSERT(s != 0); + const Ch* p = s; + while (*p) ++p; + return SizeType(p - s); +} + +template <> +inline SizeType StrLen(const char* s) { + return SizeType(std::strlen(s)); +} + +template <> +inline SizeType StrLen(const wchar_t* s) { + return SizeType(std::wcslen(s)); +} + +//! Custom strcmpn() which works on different character types. +/*! \tparam Ch Character type (e.g. char, wchar_t, short) + \param s1 Null-terminated input string. + \param s2 Null-terminated input string. + \return 0 if equal +*/ +template +inline int StrCmp(const Ch* s1, const Ch* s2) { + RAPIDJSON_ASSERT(s1 != 0); + RAPIDJSON_ASSERT(s2 != 0); + while(*s1 && (*s1 == *s2)) { s1++; s2++; } + return static_cast(*s1) < static_cast(*s2) ? -1 : static_cast(*s1) > static_cast(*s2); +} + +//! Returns number of code points in a encoded string. +template +bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { + RAPIDJSON_ASSERT(s != 0); + RAPIDJSON_ASSERT(outCount != 0); + GenericStringStream is(s); + const typename Encoding::Ch* end = s + length; + SizeType count = 0; + while (is.src_ < end) { + unsigned codepoint; + if (!Encoding::Decode(is, &codepoint)) + return false; + count++; + } + *outCount = count; + return true; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_INTERNAL_STRFUNC_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/strtod.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/strtod.h new file mode 100644 index 00000000..62a42c69 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/strtod.h @@ -0,0 +1,293 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRTOD_ +#define RAPIDJSON_STRTOD_ + +#include "ieee754.h" +#include "biginteger.h" +#include "diyfp.h" +#include "pow10.h" +#include +#include + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline double FastPath(double significand, int exp) { + if (exp < -308) + return 0.0; + else if (exp >= 0) + return significand * internal::Pow10(exp); + else + return significand / internal::Pow10(-exp); +} + +inline double StrtodNormalPrecision(double d, int p) { + if (p < -308) { + // Prevent expSum < -308, making Pow10(p) = 0 + d = FastPath(d, -308); + d = FastPath(d, p + 308); + } + else + d = FastPath(d, p); + return d; +} + +template +inline T Min3(T a, T b, T c) { + T m = a; + if (m > b) m = b; + if (m > c) m = c; + return m; +} + +inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) { + const Double db(b); + const uint64_t bInt = db.IntegerSignificand(); + const int bExp = db.IntegerExponent(); + const int hExp = bExp - 1; + + int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0; + + // Adjust for decimal exponent + if (dExp >= 0) { + dS_Exp2 += dExp; + dS_Exp5 += dExp; + } + else { + bS_Exp2 -= dExp; + bS_Exp5 -= dExp; + hS_Exp2 -= dExp; + hS_Exp5 -= dExp; + } + + // Adjust for binary exponent + if (bExp >= 0) + bS_Exp2 += bExp; + else { + dS_Exp2 -= bExp; + hS_Exp2 -= bExp; + } + + // Adjust for half ulp exponent + if (hExp >= 0) + hS_Exp2 += hExp; + else { + dS_Exp2 -= hExp; + bS_Exp2 -= hExp; + } + + // Remove common power of two factor from all three scaled values + int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2); + dS_Exp2 -= common_Exp2; + bS_Exp2 -= common_Exp2; + hS_Exp2 -= common_Exp2; + + BigInteger dS = d; + dS.MultiplyPow5(static_cast(dS_Exp5)) <<= static_cast(dS_Exp2); + + BigInteger bS(bInt); + bS.MultiplyPow5(static_cast(bS_Exp5)) <<= static_cast(bS_Exp2); + + BigInteger hS(1); + hS.MultiplyPow5(static_cast(hS_Exp5)) <<= static_cast(hS_Exp2); + + BigInteger delta(0); + dS.Difference(bS, &delta); + + return delta.Compare(hS); +} + +inline bool StrtodFast(double d, int p, double* result) { + // Use fast path for string-to-double conversion if possible + // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + if (p > 22 && p < 22 + 16) { + // Fast Path Cases In Disguise + d *= internal::Pow10(p - 22); + p = 22; + } + + if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1 + *result = FastPath(d, p); + return true; + } + else + return false; +} + +// Compute an approximation and see if it is within 1/2 ULP +template +inline bool StrtodDiyFp(const Ch* decimals, int dLen, int dExp, double* result) { + uint64_t significand = 0; + int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 + for (; i < dLen; i++) { + if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || + (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > Ch('5'))) + break; + significand = significand * 10u + static_cast(decimals[i] - Ch('0')); + } + + if (i < dLen && decimals[i] >= Ch('5')) // Rounding + significand++; + + int remaining = dLen - i; + const int kUlpShift = 3; + const int kUlp = 1 << kUlpShift; + int64_t error = (remaining == 0) ? 0 : kUlp / 2; + + DiyFp v(significand, 0); + v = v.Normalize(); + error <<= -v.e; + + dExp += remaining; + + int actualExp; + DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); + if (actualExp != dExp) { + static const DiyFp kPow10[] = { + DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 0x00000000), -60), // 10^1 + DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 0x00000000), -57), // 10^2 + DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 0x00000000), -54), // 10^3 + DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), -50), // 10^4 + DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 0x00000000), -47), // 10^5 + DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 0x00000000), -44), // 10^6 + DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 0x00000000), -40) // 10^7 + }; + int adjustment = dExp - actualExp; + RAPIDJSON_ASSERT(adjustment >= 1 && adjustment < 8); + v = v * kPow10[adjustment - 1]; + if (dLen + adjustment > 19) // has more digits than decimal digits in 64-bit + error += kUlp / 2; + } + + v = v * cachedPower; + + error += kUlp + (error == 0 ? 0 : 1); + + const int oldExp = v.e; + v = v.Normalize(); + error <<= oldExp - v.e; + + const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); + int precisionSize = 64 - effectiveSignificandSize; + if (precisionSize + kUlpShift >= 64) { + int scaleExp = (precisionSize + kUlpShift) - 63; + v.f >>= scaleExp; + v.e += scaleExp; + error = (error >> scaleExp) + 1 + kUlp; + precisionSize -= scaleExp; + } + + DiyFp rounded(v.f >> precisionSize, v.e + precisionSize); + const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; + const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; + if (precisionBits >= halfWay + static_cast(error)) { + rounded.f++; + if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340) + rounded.f >>= 1; + rounded.e++; + } + } + + *result = rounded.ToDouble(); + + return halfWay - static_cast(error) >= precisionBits || precisionBits >= halfWay + static_cast(error); +} + +template +inline double StrtodBigInteger(double approx, const Ch* decimals, int dLen, int dExp) { + RAPIDJSON_ASSERT(dLen >= 0); + const BigInteger dInt(decimals, static_cast(dLen)); + Double a(approx); + int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); + if (cmp < 0) + return a.Value(); // within half ULP + else if (cmp == 0) { + // Round towards even + if (a.Significand() & 1) + return a.NextPositiveDouble(); + else + return a.Value(); + } + else // adjustment + return a.NextPositiveDouble(); +} + +template +inline double StrtodFullPrecision(double d, int p, const Ch* decimals, size_t length, size_t decimalPosition, int exp) { + RAPIDJSON_ASSERT(d >= 0.0); + RAPIDJSON_ASSERT(length >= 1); + + double result = 0.0; + if (StrtodFast(d, p, &result)) + return result; + + RAPIDJSON_ASSERT(length <= INT_MAX); + int dLen = static_cast(length); + + RAPIDJSON_ASSERT(length >= decimalPosition); + RAPIDJSON_ASSERT(length - decimalPosition <= INT_MAX); + int dExpAdjust = static_cast(length - decimalPosition); + + RAPIDJSON_ASSERT(exp >= INT_MIN + dExpAdjust); + int dExp = exp - dExpAdjust; + + // Make sure length+dExp does not overflow + RAPIDJSON_ASSERT(dExp <= INT_MAX - dLen); + + // Trim leading zeros + while (dLen > 0 && *decimals == '0') { + dLen--; + decimals++; + } + + // Trim trailing zeros + while (dLen > 0 && decimals[dLen - 1] == '0') { + dLen--; + dExp++; + } + + if (dLen == 0) { // Buffer only contains zeros. + return 0.0; + } + + // Trim right-most digits + const int kMaxDecimalDigit = 767 + 1; + if (dLen > kMaxDecimalDigit) { + dExp += dLen - kMaxDecimalDigit; + dLen = kMaxDecimalDigit; + } + + // If too small, underflow to zero. + // Any x <= 10^-324 is interpreted as zero. + if (dLen + dExp <= -324) + return 0.0; + + // If too large, overflow to infinity. + // Any x >= 10^309 is interpreted as +infinity. + if (dLen + dExp > 309) + return std::numeric_limits::infinity(); + + if (StrtodDiyFp(decimals, dLen, dExp, &result)) + return result; + + // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison + return StrtodBigInteger(result, decimals, dLen, dExp); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STRTOD_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/internal/swap.h b/test/include/liblvgl/libs/thorvg/rapidjson/internal/swap.h new file mode 100644 index 00000000..2cf92f93 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/internal/swap.h @@ -0,0 +1,46 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_SWAP_H_ +#define RAPIDJSON_INTERNAL_SWAP_H_ + +#include "../rapidjson.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom swap() to avoid dependency on C++ header +/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. + \note This has the same semantics as std::swap(). +*/ +template +inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { + T tmp = a; + a = b; + b = tmp; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_SWAP_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/istreamwrapper.h b/test/include/liblvgl/libs/thorvg/rapidjson/istreamwrapper.h new file mode 100644 index 00000000..23dd83e9 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/istreamwrapper.h @@ -0,0 +1,128 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ISTREAMWRAPPER_H_ +#define RAPIDJSON_ISTREAMWRAPPER_H_ + +#include "stream.h" +#include +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::istringstream + - \c std::stringstream + - \c std::wistringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wifstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_istream. +*/ + +template +class BasicIStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + + //! Constructor. + /*! + \param stream stream opened for read. + */ + BasicIStreamWrapper(StreamType &stream) : stream_(stream), buffer_(peekBuffer_), bufferSize_(4), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + Read(); + } + + //! Constructor. + /*! + \param stream stream opened for read. + \param buffer user-supplied buffer. + \param bufferSize size of buffer in bytes. Must >=4 bytes. + */ + BasicIStreamWrapper(StreamType &stream, char* buffer, size_t bufferSize) : stream_(stream), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + RAPIDJSON_ASSERT(bufferSize >= 4); + Read(); + } + + Ch Peek() const { return *current_; } + Ch Take() { Ch c = *current_; Read(); return c; } + size_t Tell() const { return count_ + static_cast(current_ - buffer_); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0; + } + +private: + BasicIStreamWrapper(); + BasicIStreamWrapper(const BasicIStreamWrapper&); + BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); + + void Read() { + if (current_ < bufferLast_) + ++current_; + else if (!eof_) { + count_ += readCount_; + readCount_ = bufferSize_; + bufferLast_ = buffer_ + readCount_ - 1; + current_ = buffer_; + + if (!stream_.read(buffer_, static_cast(bufferSize_))) { + readCount_ = static_cast(stream_.gcount()); + *(bufferLast_ = buffer_ + readCount_) = '\0'; + eof_ = true; + } + } + } + + StreamType &stream_; + Ch peekBuffer_[4], *buffer_; + size_t bufferSize_; + Ch *bufferLast_; + Ch *current_; + size_t readCount_; + size_t count_; //!< Number of characters read + bool eof_; +}; + +typedef BasicIStreamWrapper IStreamWrapper; +typedef BasicIStreamWrapper WIStreamWrapper; + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ISTREAMWRAPPER_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/memorybuffer.h b/test/include/liblvgl/libs/thorvg/rapidjson/memorybuffer.h new file mode 100644 index 00000000..14aad686 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/memorybuffer.h @@ -0,0 +1,70 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYBUFFER_H_ +#define RAPIDJSON_MEMORYBUFFER_H_ + +#include "stream.h" +#include "internal/stack.h" + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output byte stream. +/*! + This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. + + It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. + + Differences between MemoryBuffer and StringBuffer: + 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. + 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. + + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +struct GenericMemoryBuffer { + typedef char Ch; // byte + + GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + + void Put(Ch c) { *stack_.template Push() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { stack_.ShrinkToFit(); } + Ch* Push(size_t count) { return stack_.template Push(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetBuffer() const { + return stack_.template Bottom(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; +}; + +typedef GenericMemoryBuffer<> MemoryBuffer; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { + std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/memorystream.h b/test/include/liblvgl/libs/thorvg/rapidjson/memorystream.h new file mode 100644 index 00000000..1bc393f2 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/memorystream.h @@ -0,0 +1,71 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYSTREAM_H_ +#define RAPIDJSON_MEMORYSTREAM_H_ + +#include "stream.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(missing-noreturn) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory input byte stream. +/*! + This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. + + It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. + + Differences between MemoryStream and StringStream: + 1. StringStream has encoding but MemoryStream is a byte stream. + 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. + 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). + \note implements Stream concept +*/ +struct MemoryStream { + typedef char Ch; // byte + + MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} + + Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } + Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } + size_t Tell() const { return static_cast(src_ - begin_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return Tell() + 4 <= size_ ? src_ : 0; + } + + const Ch* src_; //!< Current read position. + const Ch* begin_; //!< Original head of the string. + const Ch* end_; //!< End of stream. + size_t size_; //!< Size of the stream. +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/msinttypes/inttypes.h b/test/include/liblvgl/libs/thorvg/rapidjson/msinttypes/inttypes.h new file mode 100644 index 00000000..1620402e --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/msinttypes/inttypes.h @@ -0,0 +1,316 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR 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. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// miloyip: VC supports inttypes.h since VC2013 +#if _MSC_VER >= 1800 +#include +#else + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + +#endif // _MSC_VER >= 1800 + +#endif // _MSC_INTTYPES_H_ ] diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/msinttypes/stdint.h b/test/include/liblvgl/libs/thorvg/rapidjson/msinttypes/stdint.h new file mode 100644 index 00000000..1c266ecf --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/msinttypes/stdint.h @@ -0,0 +1,300 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR 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. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. +#if _MSC_VER >= 1600 // [ +#include + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#else // ] _MSC_VER >= 1700 [ + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we have to wrap include with 'extern "C++" {}' +// or compiler would give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#if defined(__cplusplus) && !defined(_M_ARM) +extern "C" { +#endif +# include +#if defined(__cplusplus) && !defined(_M_ARM) +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ] diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/ostreamwrapper.h b/test/include/liblvgl/libs/thorvg/rapidjson/ostreamwrapper.h new file mode 100644 index 00000000..bfd4d6da --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/ostreamwrapper.h @@ -0,0 +1,81 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_OSTREAMWRAPPER_H_ +#define RAPIDJSON_OSTREAMWRAPPER_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::ostringstream + - \c std::stringstream + - \c std::wpstringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wofstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_ostream. +*/ + +template +class BasicOStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} + + void Put(Ch c) { + stream_.put(c); + } + + void Flush() { + stream_.flush(); + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + BasicOStreamWrapper(const BasicOStreamWrapper&); + BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); + + StreamType& stream_; +}; + +typedef BasicOStreamWrapper OStreamWrapper; +typedef BasicOStreamWrapper WOStreamWrapper; + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_OSTREAMWRAPPER_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/pointer.h b/test/include/liblvgl/libs/thorvg/rapidjson/pointer.h new file mode 100644 index 00000000..d0d762d2 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/pointer.h @@ -0,0 +1,1470 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POINTER_H_ +#define RAPIDJSON_POINTER_H_ + +#include "document.h" +#include "uri.h" +#include "internal/itoa.h" +#include "error/error.h" // PointerParseErrorCode + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token + +/////////////////////////////////////////////////////////////////////////////// +// GenericPointer + +//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator. +/*! + This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" + (https://tools.ietf.org/html/rfc6901). + + A JSON pointer is for identifying a specific value in a JSON document + (GenericDocument). It can simplify coding of DOM tree manipulation, because it + can access multiple-level depth of DOM tree with single API call. + + After it parses a string representation (e.g. "/foo/0" or URI fragment + representation (e.g. "#/foo/0") into its internal representation (tokens), + it can be used to resolve a specific value in multiple documents, or sub-tree + of documents. + + Contrary to GenericValue, Pointer can be copy constructed and copy assigned. + Apart from assignment, a Pointer cannot be modified after construction. + + Although Pointer is very convenient, please aware that constructing Pointer + involves parsing and dynamic memory allocation. A special constructor with user- + supplied tokens eliminates these. + + GenericPointer depends on GenericDocument and GenericValue. + + \tparam ValueType The value type of the DOM tree. E.g. GenericValue > + \tparam Allocator The allocator type for allocating memory for internal representation. + + \note GenericPointer uses same encoding of ValueType. + However, Allocator of GenericPointer is independent of Allocator of Value. +*/ +template +class GenericPointer { +public: + typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value + typedef typename ValueType::Ch Ch; //!< Character type from Value + typedef GenericUri UriType; + + + //! A token is the basic units of internal representation. + /*! + A JSON pointer string representation "/foo/123" is parsed to two tokens: + "foo" and 123. 123 will be represented in both numeric form and string form. + They are resolved according to the actual value type (object or array). + + For token that are not numbers, or the numeric value is out of bound + (greater than limits of SizeType), they are only treated as string form + (i.e. the token's index will be equal to kPointerInvalidIndex). + + This struct is public so that user can create a Pointer without parsing and + allocation, using a special constructor. + */ + struct Token { + const Ch* name; //!< Name of the token. It has null character at the end but it can contain null character. + SizeType length; //!< Length of the name. + SizeType index; //!< A valid array index, if it is not equal to kPointerInvalidIndex. + }; + + //!@name Constructors and destructor. + //@{ + + //! Default constructor. + GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} + + //! Constructor that parses a string or URI fragment representation. + /*! + \param source A null-terminated, string or URI fragment representation of JSON pointer. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + */ + explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source, internal::StrLen(source)); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor that parses a string or URI fragment representation. + /*! + \param source A string or URI fragment representation of JSON pointer. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + explicit GenericPointer(const std::basic_string& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source.c_str(), source.size()); + } +#endif + + //! Constructor that parses a string or URI fragment representation, with length of the source string. + /*! + \param source A string or URI fragment representation of JSON pointer. + \param length Length of source. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + \note Slightly faster than the overload without length. + */ + GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source, length); + } + + //! Constructor with user-supplied tokens. + /*! + This constructor let user supplies const array of tokens. + This prevents the parsing process and eliminates allocation. + This is preferred for memory constrained environments. + + \param tokens An constant array of tokens representing the JSON pointer. + \param tokenCount Number of tokens. + + \b Example + \code + #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex } + #define INDEX(i) { #i, sizeof(#i) - 1, i } + + static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) }; + static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0])); + // Equivalent to static const Pointer p("/foo/123"); + + #undef NAME + #undef INDEX + \endcode + */ + GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} + + //! Copy constructor. + GenericPointer(const GenericPointer& rhs) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + *this = rhs; + } + + //! Copy constructor. + GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + *this = rhs; + } + + //! Destructor. + ~GenericPointer() { + if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated. + Allocator::Free(tokens_); + RAPIDJSON_DELETE(ownAllocator_); + } + + //! Assignment operator. + GenericPointer& operator=(const GenericPointer& rhs) { + if (this != &rhs) { + // Do not delete ownAllocator + if (nameBuffer_) + Allocator::Free(tokens_); + + tokenCount_ = rhs.tokenCount_; + parseErrorOffset_ = rhs.parseErrorOffset_; + parseErrorCode_ = rhs.parseErrorCode_; + + if (rhs.nameBuffer_) + CopyFromRaw(rhs); // Normally parsed tokens. + else { + tokens_ = rhs.tokens_; // User supplied const tokens. + nameBuffer_ = 0; + } + } + return *this; + } + + //! Swap the content of this pointer with another. + /*! + \param other The pointer to swap with. + \note Constant complexity. + */ + GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT { + internal::Swap(allocator_, other.allocator_); + internal::Swap(ownAllocator_, other.ownAllocator_); + internal::Swap(nameBuffer_, other.nameBuffer_); + internal::Swap(tokens_, other.tokens_); + internal::Swap(tokenCount_, other.tokenCount_); + internal::Swap(parseErrorOffset_, other.parseErrorOffset_); + internal::Swap(parseErrorCode_, other.parseErrorCode_); + return *this; + } + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.pointer, b.pointer); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //@} + + //!@name Append token + //@{ + + //! Append a token and return a new Pointer + /*! + \param token Token to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const Token& token, Allocator* allocator = 0) const { + GenericPointer r; + r.allocator_ = allocator; + Ch *p = r.CopyFromRaw(*this, 1, token.length + 1); + std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch)); + r.tokens_[tokenCount_].name = p; + r.tokens_[tokenCount_].length = token.length; + r.tokens_[tokenCount_].index = token.index; + return r; + } + + //! Append a name token with length, and return a new Pointer + /*! + \param name Name to be appended. + \param length Length of name. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const { + Token token = { name, length, kPointerInvalidIndex }; + return Append(token, allocator); + } + + //! Append a name token without length, and return a new Pointer + /*! + \param name Name (const Ch*) to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >), (GenericPointer)) + Append(T* name, Allocator* allocator = 0) const { + return Append(name, internal::StrLen(name), allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Append a name token, and return a new Pointer + /*! + \param name Name to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const std::basic_string& name, Allocator* allocator = 0) const { + return Append(name.c_str(), static_cast(name.size()), allocator); + } +#endif + + //! Append a index token, and return a new Pointer + /*! + \param index Index to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(SizeType index, Allocator* allocator = 0) const { + char buffer[21]; + char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer); + SizeType length = static_cast(end - buffer); + buffer[length] = '\0'; + + if (sizeof(Ch) == 1) { + Token token = { reinterpret_cast(buffer), length, index }; + return Append(token, allocator); + } + else { + Ch name[21]; + for (size_t i = 0; i <= length; i++) + name[i] = static_cast(buffer[i]); + Token token = { name, length, index }; + return Append(token, allocator); + } + } + + //! Append a token by value, and return a new Pointer + /*! + \param token token to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const { + if (token.IsString()) + return Append(token.GetString(), token.GetStringLength(), allocator); + else { + RAPIDJSON_ASSERT(token.IsUint64()); + RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0)); + return Append(static_cast(token.GetUint64()), allocator); + } + } + + //!@name Handling Parse Error + //@{ + + //! Check whether this is a valid pointer. + bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; } + + //! Get the parsing error offset in code unit. + size_t GetParseErrorOffset() const { return parseErrorOffset_; } + + //! Get the parsing error code. + PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; } + + //@} + + //! Get the allocator of this pointer. + Allocator& GetAllocator() { return *allocator_; } + + //!@name Tokens + //@{ + + //! Get the token array (const version only). + const Token* GetTokens() const { return tokens_; } + + //! Get the number of tokens. + size_t GetTokenCount() const { return tokenCount_; } + + //@} + + //!@name Equality/inequality operators + //@{ + + //! Equality operator. + /*! + \note When any pointers are invalid, always returns false. + */ + bool operator==(const GenericPointer& rhs) const { + if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_) + return false; + + for (size_t i = 0; i < tokenCount_; i++) { + if (tokens_[i].index != rhs.tokens_[i].index || + tokens_[i].length != rhs.tokens_[i].length || + (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0)) + { + return false; + } + } + + return true; + } + + //! Inequality operator. + /*! + \note When any pointers are invalid, always returns true. + */ + bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); } + + //! Less than operator. + /*! + \note Invalid pointers are always greater than valid ones. + */ + bool operator<(const GenericPointer& rhs) const { + if (!IsValid()) + return false; + if (!rhs.IsValid()) + return true; + + if (tokenCount_ != rhs.tokenCount_) + return tokenCount_ < rhs.tokenCount_; + + for (size_t i = 0; i < tokenCount_; i++) { + if (tokens_[i].index != rhs.tokens_[i].index) + return tokens_[i].index < rhs.tokens_[i].index; + + if (tokens_[i].length != rhs.tokens_[i].length) + return tokens_[i].length < rhs.tokens_[i].length; + + if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length)) + return cmp < 0; + } + + return false; + } + + //@} + + //!@name Stringify + //@{ + + //! Stringify the pointer into string representation. + /*! + \tparam OutputStream Type of output stream. + \param os The output stream. + */ + template + bool Stringify(OutputStream& os) const { + return Stringify(os); + } + + //! Stringify the pointer into URI fragment representation. + /*! + \tparam OutputStream Type of output stream. + \param os The output stream. + */ + template + bool StringifyUriFragment(OutputStream& os) const { + return Stringify(os); + } + + //@} + + //!@name Create value + //@{ + + //! Create a value in a subtree. + /*! + If the value is not exist, it creates all parent values and a JSON Null value. + So it always succeed and return the newly created or existing value. + + Remind that it may change types of parents according to tokens, so it + potentially removes previously stored values. For example, if a document + was an array, and "/foo" is used to create a value, then the document + will be changed to an object, and all existing array elements are lost. + + \param root Root value of a DOM subtree to be resolved. It can be any value other than document root. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \param alreadyExist If non-null, it stores whether the resolved value is already exist. + \return The resolved newly created (a JSON Null value), or already exists value. + */ + ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const { + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + bool exist = true; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + if (v->IsArray() && t->name[0] == '-' && t->length == 1) { + v->PushBack(ValueType().Move(), allocator); + v = &((*v)[v->Size() - 1]); + exist = false; + } + else { + if (t->index == kPointerInvalidIndex) { // must be object name + if (!v->IsObject()) + v->SetObject(); // Change to Object + } + else { // object name or array index + if (!v->IsArray() && !v->IsObject()) + v->SetArray(); // Change to Array + } + + if (v->IsArray()) { + if (t->index >= v->Size()) { + v->Reserve(t->index + 1, allocator); + while (t->index >= v->Size()) + v->PushBack(ValueType().Move(), allocator); + exist = false; + } + v = &((*v)[t->index]); + } + else { + typename ValueType::MemberIterator m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); + if (m == v->MemberEnd()) { + v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator); + m = v->MemberEnd(); + v = &(--m)->value; // Assumes AddMember() appends at the end + exist = false; + } + else + v = &m->value; + } + } + } + + if (alreadyExist) + *alreadyExist = exist; + + return *v; + } + + //! Creates a value in a document. + /*! + \param document A document to be resolved. + \param alreadyExist If non-null, it stores whether the resolved value is already exist. + \return The resolved newly created, or already exists value. + */ + template + ValueType& Create(GenericDocument& document, bool* alreadyExist = 0) const { + return Create(document, document.GetAllocator(), alreadyExist); + } + + //@} + + //!@name Compute URI + //@{ + + //! Compute the in-scope URI for a subtree. + // For use with JSON pointers into JSON schema documents. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param rootUri Root URI + \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token. + \param allocator Allocator for Uris + \return Uri if it can be resolved. Otherwise null. + + \note + There are only 3 situations when a URI cannot be resolved: + 1. A value in the path is neither an array nor object. + 2. An object value does not contain the token. + 3. A token is out of range of an array value. + + Use unresolvedTokenIndex to retrieve the token index. + */ + UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const { + static const Ch kIdString[] = { 'i', 'd', '\0' }; + static const ValueType kIdValue(kIdString, 2); + UriType base = UriType(rootUri, allocator); + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + switch (v->GetType()) { + case kObjectType: + { + // See if we have an id, and if so resolve with the current base + typename ValueType::MemberIterator m = v->FindMember(kIdValue); + if (m != v->MemberEnd() && (m->value).IsString()) { + UriType here = UriType(m->value, allocator).Resolve(base, allocator); + base = here; + } + m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); + if (m == v->MemberEnd()) + break; + v = &m->value; + } + continue; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + break; + v = &((*v)[t->index]); + continue; + default: + break; + } + + // Error: unresolved token + if (unresolvedTokenIndex) + *unresolvedTokenIndex = static_cast(t - tokens_); + return UriType(allocator); + } + return base; + } + + UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const { + return GetUri(const_cast(root), rootUri, unresolvedTokenIndex, allocator); + } + + + //!@name Query value + //@{ + + //! Query a value in a subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token. + \return Pointer to the value if it can be resolved. Otherwise null. + + \note + There are only 3 situations when a value cannot be resolved: + 1. A value in the path is neither an array nor object. + 2. An object value does not contain the token. + 3. A token is out of range of an array value. + + Use unresolvedTokenIndex to retrieve the token index. + */ + ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const { + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + switch (v->GetType()) { + case kObjectType: + { + typename ValueType::MemberIterator m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); + if (m == v->MemberEnd()) + break; + v = &m->value; + } + continue; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + break; + v = &((*v)[t->index]); + continue; + default: + break; + } + + // Error: unresolved token + if (unresolvedTokenIndex) + *unresolvedTokenIndex = static_cast(t - tokens_); + return 0; + } + return v; + } + + //! Query a const value in a const subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \return Pointer to the value if it can be resolved. Otherwise null. + */ + const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { + return Get(const_cast(root), unresolvedTokenIndex); + } + + //@} + + //!@name Query a value with default + //@{ + + //! Query a value in a subtree with default value. + /*! + Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value. + So that this function always succeed. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param defaultValue Default value to be cloned if the value was not exists. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + ValueType& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.CopyFrom(defaultValue, allocator); + } + + //! Query a value in a subtree with default null-terminated string. + ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + ValueType& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.SetString(defaultValue, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Query a value in a subtree with default std::basic_string. + ValueType& GetWithDefault(ValueType& root, const std::basic_string& defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + ValueType& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.SetString(defaultValue, allocator); + } +#endif + + //! Query a value in a subtree with default primitive value. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const { + return GetWithDefault(root, ValueType(defaultValue).Move(), allocator); + } + + //! Query a value in a document with default value. + template + ValueType& GetWithDefault(GenericDocument& document, const ValueType& defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + + //! Query a value in a document with default null-terminated string. + template + ValueType& GetWithDefault(GenericDocument& document, const Ch* defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Query a value in a document with default std::basic_string. + template + ValueType& GetWithDefault(GenericDocument& document, const std::basic_string& defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } +#endif + + //! Query a value in a document with default primitive value. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + GetWithDefault(GenericDocument& document, T defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + + //@} + + //!@name Set a value + //@{ + + //! Set a value in a subtree, with move semantics. + /*! + It creates all parents if they are not exist or types are different to the tokens. + So this function always succeeds but potentially remove existing values. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param value Value to be set. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = value; + } + + //! Set a value in a subtree, with copy semantics. + ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator).CopyFrom(value, allocator); + } + + //! Set a null-terminated string in a subtree. + ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value, allocator).Move(); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Set a std::basic_string in a subtree. + ValueType& Set(ValueType& root, const std::basic_string& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value, allocator).Move(); + } +#endif + + //! Set a primitive value in a subtree. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value).Move(); + } + + //! Set a value in a document, with move semantics. + template + ValueType& Set(GenericDocument& document, ValueType& value) const { + return Create(document) = value; + } + + //! Set a value in a document, with copy semantics. + template + ValueType& Set(GenericDocument& document, const ValueType& value) const { + return Create(document).CopyFrom(value, document.GetAllocator()); + } + + //! Set a null-terminated string in a document. + template + ValueType& Set(GenericDocument& document, const Ch* value) const { + return Create(document) = ValueType(value, document.GetAllocator()).Move(); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Sets a std::basic_string in a document. + template + ValueType& Set(GenericDocument& document, const std::basic_string& value) const { + return Create(document) = ValueType(value, document.GetAllocator()).Move(); + } +#endif + + //! Set a primitive value in a document. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + Set(GenericDocument& document, T value) const { + return Create(document) = value; + } + + //@} + + //!@name Swap a value + //@{ + + //! Swap a value with a value in a subtree. + /*! + It creates all parents if they are not exist or types are different to the tokens. + So this function always succeeds but potentially remove existing values. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param value Value to be swapped. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator).Swap(value); + } + + //! Swap a value with a value in a document. + template + ValueType& Swap(GenericDocument& document, ValueType& value) const { + return Create(document).Swap(value); + } + + //@} + + //! Erase a value in a subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \return Whether the resolved value is found and erased. + + \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false. + */ + bool Erase(ValueType& root) const { + RAPIDJSON_ASSERT(IsValid()); + if (tokenCount_ == 0) // Cannot erase the root + return false; + + ValueType* v = &root; + const Token* last = tokens_ + (tokenCount_ - 1); + for (const Token *t = tokens_; t != last; ++t) { + switch (v->GetType()) { + case kObjectType: + { + typename ValueType::MemberIterator m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); + if (m == v->MemberEnd()) + return false; + v = &m->value; + } + break; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + return false; + v = &((*v)[t->index]); + break; + default: + return false; + } + } + + switch (v->GetType()) { + case kObjectType: + return v->EraseMember(GenericStringRef(last->name, last->length)); + case kArrayType: + if (last->index == kPointerInvalidIndex || last->index >= v->Size()) + return false; + v->Erase(v->Begin() + last->index); + return true; + default: + return false; + } + } + +private: + //! Clone the content from rhs to this. + /*! + \param rhs Source pointer. + \param extraToken Extra tokens to be allocated. + \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated. + \return Start of non-occupied name buffer, for storing extra names. + */ + Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) { + if (!allocator_) // allocator is independently owned. + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + + size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens + for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t) + nameBufferSize += t->length; + + tokenCount_ = rhs.tokenCount_ + extraToken; + tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch))); + nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); + if (rhs.tokenCount_ > 0) { + std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token)); + } + if (nameBufferSize > 0) { + std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch)); + } + + // Adjust pointers to name buffer + std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_; + for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t) + t->name += diff; + + return nameBuffer_ + nameBufferSize; + } + + //! Check whether a character should be percent-encoded. + /*! + According to RFC 3986 2.3 Unreserved Characters. + \param c The character (code unit) to be tested. + */ + bool NeedPercentEncode(Ch c) const { + return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~'); + } + + //! Parse a JSON String or its URI fragment representation into tokens. +#ifndef __clang__ // -Wdocumentation + /*! + \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated. + \param length Length of the source string. + \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped. + */ +#endif + void Parse(const Ch* source, size_t length) { + RAPIDJSON_ASSERT(source != NULL); + RAPIDJSON_ASSERT(nameBuffer_ == 0); + RAPIDJSON_ASSERT(tokens_ == 0); + + // Create own allocator if user did not supply. + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + + // Count number of '/' as tokenCount + tokenCount_ = 0; + for (const Ch* s = source; s != source + length; s++) + if (*s == '/') + tokenCount_++; + + Token* token = tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch))); + Ch* name = nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); + size_t i = 0; + + // Detect if it is a URI fragment + bool uriFragment = false; + if (source[i] == '#') { + uriFragment = true; + i++; + } + + if (i != length && source[i] != '/') { + parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus; + goto error; + } + + while (i < length) { + RAPIDJSON_ASSERT(source[i] == '/'); + i++; // consumes '/' + + token->name = name; + bool isNumber = true; + + while (i < length && source[i] != '/') { + Ch c = source[i]; + if (uriFragment) { + // Decoding percent-encoding for URI fragment + if (c == '%') { + PercentDecodeStream is(&source[i], source + length); + GenericInsituStringStream os(name); + Ch* begin = os.PutBegin(); + if (!Transcoder, EncodingType>().Validate(is, os) || !is.IsValid()) { + parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding; + goto error; + } + size_t len = os.PutEnd(begin); + i += is.Tell() - 1; + if (len == 1) + c = *name; + else { + name += len; + isNumber = false; + i++; + continue; + } + } + else if (NeedPercentEncode(c)) { + parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode; + goto error; + } + } + + i++; + + // Escaping "~0" -> '~', "~1" -> '/' + if (c == '~') { + if (i < length) { + c = source[i]; + if (c == '0') c = '~'; + else if (c == '1') c = '/'; + else { + parseErrorCode_ = kPointerParseErrorInvalidEscape; + goto error; + } + i++; + } + else { + parseErrorCode_ = kPointerParseErrorInvalidEscape; + goto error; + } + } + + // First check for index: all of characters are digit + if (c < '0' || c > '9') + isNumber = false; + + *name++ = c; + } + token->length = static_cast(name - token->name); + if (token->length == 0) + isNumber = false; + *name++ = '\0'; // Null terminator + + // Second check for index: more than one digit cannot have leading zero + if (isNumber && token->length > 1 && token->name[0] == '0') + isNumber = false; + + // String to SizeType conversion + SizeType n = 0; + if (isNumber) { + for (size_t j = 0; j < token->length; j++) { + SizeType m = n * 10 + static_cast(token->name[j] - '0'); + if (m < n) { // overflow detection + isNumber = false; + break; + } + n = m; + } + } + + token->index = isNumber ? n : kPointerInvalidIndex; + token++; + } + + RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer + parseErrorCode_ = kPointerParseErrorNone; + return; + + error: + Allocator::Free(tokens_); + nameBuffer_ = 0; + tokens_ = 0; + tokenCount_ = 0; + parseErrorOffset_ = i; + return; + } + + //! Stringify to string or URI fragment representation. + /*! + \tparam uriFragment True for stringifying to URI fragment representation. False for string representation. + \tparam OutputStream type of output stream. + \param os The output stream. + */ + template + bool Stringify(OutputStream& os) const { + RAPIDJSON_ASSERT(IsValid()); + + if (uriFragment) + os.Put('#'); + + for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + os.Put('/'); + for (size_t j = 0; j < t->length; j++) { + Ch c = t->name[j]; + if (c == '~') { + os.Put('~'); + os.Put('0'); + } + else if (c == '/') { + os.Put('~'); + os.Put('1'); + } + else if (uriFragment && NeedPercentEncode(c)) { + // Transcode to UTF8 sequence + GenericStringStream source(&t->name[j]); + PercentEncodeStream target(os); + if (!Transcoder >().Validate(source, target)) + return false; + j += source.Tell() - 1; + } + else + os.Put(c); + } + } + return true; + } + + //! A helper stream for decoding a percent-encoded sequence into code unit. + /*! + This stream decodes %XY triplet into code unit (0-255). + If it encounters invalid characters, it sets output code unit as 0 and + mark invalid, and to be checked by IsValid(). + */ + class PercentDecodeStream { + public: + typedef typename ValueType::Ch Ch; + + //! Constructor + /*! + \param source Start of the stream + \param end Past-the-end of the stream. + */ + PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {} + + Ch Take() { + if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet + valid_ = false; + return 0; + } + src_++; + Ch c = 0; + for (int j = 0; j < 2; j++) { + c = static_cast(c << 4); + Ch h = *src_; + if (h >= '0' && h <= '9') c = static_cast(c + h - '0'); + else if (h >= 'A' && h <= 'F') c = static_cast(c + h - 'A' + 10); + else if (h >= 'a' && h <= 'f') c = static_cast(c + h - 'a' + 10); + else { + valid_ = false; + return 0; + } + src_++; + } + return c; + } + + size_t Tell() const { return static_cast(src_ - head_); } + bool IsValid() const { return valid_; } + + private: + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. + const Ch* end_; //!< Past-the-end position. + bool valid_; //!< Whether the parsing is valid. + }; + + //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence. + template + class PercentEncodeStream { + public: + PercentEncodeStream(OutputStream& os) : os_(os) {} + void Put(char c) { // UTF-8 must be byte + unsigned char u = static_cast(c); + static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + os_.Put('%'); + os_.Put(static_cast(hexDigits[u >> 4])); + os_.Put(static_cast(hexDigits[u & 15])); + } + private: + OutputStream& os_; + }; + + Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_. + Allocator* ownAllocator_; //!< Allocator owned by this Pointer. + Ch* nameBuffer_; //!< A buffer containing all names in tokens. + Token* tokens_; //!< A list of tokens. + size_t tokenCount_; //!< Number of tokens in tokens_. + size_t parseErrorOffset_; //!< Offset in code unit when parsing fail. + PointerParseErrorCode parseErrorCode_; //!< Parsing error code. +}; + +//! GenericPointer for Value (UTF-8, default allocator). +typedef GenericPointer Pointer; + +//!@name Helper functions for GenericPointer +//@{ + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer& pointer, typename T::AllocatorType& a) { + return pointer.Create(root, a); +} + +template +typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Create(root, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer& pointer) { + return pointer.Create(document); +} + +template +typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) { + return GenericPointer(source, N - 1).Create(document); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType* GetValueByPointer(T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { + return pointer.Get(root, unresolvedTokenIndex); +} + +template +const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { + return pointer.Get(root, unresolvedTokenIndex); +} + +template +typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) { + return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); +} + +template +const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) { + return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const std::basic_string& defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, T2 defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string& defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const std::basic_string& defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, T2 defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string& defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::Ch* value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const std::basic_string& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +SetValueByPointer(T& root, const GenericPointer& pointer, T2 value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* value) { + return pointer.Set(document, value); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const std::basic_string& value) { + return pointer.Set(document, value); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +SetValueByPointer(DocumentType& document, const GenericPointer& pointer, T2 value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string& value) { + return GenericPointer(source, N - 1).Set(document, value); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Swap(root, value, a); +} + +template +typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Swap(root, value, a); +} + +template +typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { + return pointer.Swap(document, value); +} + +template +typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Swap(document, value); +} + +////////////////////////////////////////////////////////////////////////////// + +template +bool EraseValueByPointer(T& root, const GenericPointer& pointer) { + return pointer.Erase(root); +} + +template +bool EraseValueByPointer(T& root, const CharType(&source)[N]) { + return GenericPointer(source, N - 1).Erase(root); +} + +//@} + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_POINTER_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/prettywriter.h b/test/include/liblvgl/libs/thorvg/rapidjson/prettywriter.h new file mode 100644 index 00000000..cea596ef --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/prettywriter.h @@ -0,0 +1,277 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_PRETTYWRITER_H_ +#define RAPIDJSON_PRETTYWRITER_H_ + +#include "writer.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Combination of PrettyWriter format flags. +/*! \see PrettyWriter::SetFormatOptions + */ +enum PrettyFormatOptions { + kFormatDefault = 0, //!< Default pretty formatting. + kFormatSingleLineArray = 1 //!< Format arrays on a single line. +}; + +//! Writer with indentation and spacing. +/*! + \tparam OutputStream Type of output os. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> +class PrettyWriter : public Writer { +public: + typedef Writer Base; + typedef typename Base::Ch Ch; + + //! Constructor + /*! \param os Output stream. + \param allocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} + + + explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + PrettyWriter(PrettyWriter&& rhs) : + Base(std::forward(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {} +#endif + + //! Set custom indentation. + /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). + \param indentCharCount Number of indent characters for each indentation level. + \note The default indentation is 4 spaces. + */ + PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { + RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); + indentChar_ = indentChar; + indentCharCount_ = indentCharCount; + return *this; + } + + //! Set pretty writer formatting options. + /*! \param options Formatting options. + */ + PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { + formatOptions_ = options; + return *this; + } + + /*! @name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { PrettyPrefix(kNullType); return Base::EndValue(Base::WriteNull()); } + bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); } + bool Int(int i) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); } + bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); } + bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); } + bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64)); } + bool Double(double d) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); } + + bool RawNumber(const Ch* str, SizeType length, bool copy = false) { + RAPIDJSON_ASSERT(str != 0); + (void)copy; + PrettyPrefix(kNumberType); + return Base::EndValue(Base::WriteString(str, length)); + } + + bool String(const Ch* str, SizeType length, bool copy = false) { + RAPIDJSON_ASSERT(str != 0); + (void)copy; + PrettyPrefix(kStringType); + return Base::EndValue(Base::WriteString(str, length)); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + PrettyPrefix(kObjectType); + new (Base::level_stack_.template Push()) typename Base::Level(false); + return Base::WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + +#if RAPIDJSON_HAS_STDSTRING + bool Key(const std::basic_string& str) { + return Key(str.data(), SizeType(str.size())); + } +#endif + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object + RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); // currently inside an Array, not Object + RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top()->valueCount % 2); // Object has a Key without a Value + + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::EndValue(Base::WriteEndObject()); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::Flush(); + return true; + } + + bool StartArray() { + PrettyPrefix(kArrayType); + new (Base::level_stack_.template Push()) typename Base::Level(true); + return Base::WriteStartArray(); + } + + bool EndArray(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::EndValue(Base::WriteEndArray()); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::Flush(); + return true; + } + + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} + + //! Write a raw JSON value. + /*! + For user to write a stringified JSON as a value. + + \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. + \param length Length of the json. + \param type Type of the root of json. + \note When using PrettyWriter::RawValue(), the result json may not be indented correctly. + */ + bool RawValue(const Ch* json, size_t length, Type type) { + RAPIDJSON_ASSERT(json != 0); + PrettyPrefix(type); + return Base::EndValue(Base::WriteRawValue(json, length)); + } + +protected: + void PrettyPrefix(Type type) { + (void)type; + if (Base::level_stack_.GetSize() != 0) { // this value is not at root + typename Base::Level* level = Base::level_stack_.template Top(); + + if (level->inArray) { + if (level->valueCount > 0) { + Base::os_->Put(','); // add comma if it is not the first element in array + if (formatOptions_ & kFormatSingleLineArray) + Base::os_->Put(' '); + } + + if (!(formatOptions_ & kFormatSingleLineArray)) { + Base::os_->Put('\n'); + WriteIndent(); + } + } + else { // in object + if (level->valueCount > 0) { + if (level->valueCount % 2 == 0) { + Base::os_->Put(','); + Base::os_->Put('\n'); + } + else { + Base::os_->Put(':'); + Base::os_->Put(' '); + } + } + else + Base::os_->Put('\n'); + + if (level->valueCount % 2 == 0) + WriteIndent(); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. + Base::hasRoot_ = true; + } + } + + void WriteIndent() { + size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; + PutN(*Base::os_, static_cast(indentChar_), count); + } + + Ch indentChar_; + unsigned indentCharCount_; + PrettyFormatOptions formatOptions_; + +private: + // Prohibit copy constructor & assignment operator. + PrettyWriter(const PrettyWriter&); + PrettyWriter& operator=(const PrettyWriter&); +}; + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/rapidjson.h b/test/include/liblvgl/libs/thorvg/rapidjson/rapidjson.h new file mode 100644 index 00000000..89de8386 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/rapidjson.h @@ -0,0 +1,741 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_RAPIDJSON_H_ +#define RAPIDJSON_RAPIDJSON_H_ + +/*!\file rapidjson.h + \brief common definitions and configuration + + \see RAPIDJSON_CONFIG + */ + +/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration + \brief Configuration macros for library features + + Some RapidJSON features are configurable to adapt the library to a wide + variety of platforms, environments and usage scenarios. Most of the + features can be configured in terms of overridden or predefined + preprocessor macros at compile-time. + + Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. + + \note These macros should be given on the compiler command-line + (where applicable) to avoid inconsistent values when compiling + different translation units of a single application. + */ + +#include // malloc(), realloc(), free(), size_t +#include // memset(), memcpy(), memmove(), memcmp() + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_VERSION_STRING +// +// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt. +// + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +// token stringification +#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) +#define RAPIDJSON_DO_STRINGIFY(x) #x + +// token concatenation +#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) +#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) +#define RAPIDJSON_DO_JOIN2(X, Y) X##Y +//!@endcond + +/*! \def RAPIDJSON_MAJOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Major version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_MINOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Minor version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_PATCH_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Patch version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_VERSION_STRING + \ingroup RAPIDJSON_CONFIG + \brief Version of RapidJSON in ".." string format. +*/ +#define RAPIDJSON_MAJOR_VERSION 1 +#define RAPIDJSON_MINOR_VERSION 1 +#define RAPIDJSON_PATCH_VERSION 0 +#define RAPIDJSON_VERSION_STRING \ + RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION) + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NAMESPACE_(BEGIN|END) +/*! \def RAPIDJSON_NAMESPACE + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace + + In order to avoid symbol clashes and/or "One Definition Rule" errors + between multiple inclusions of (different versions of) RapidJSON in + a single binary, users can customize the name of the main RapidJSON + namespace. + + In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE + to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple + levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref + RAPIDJSON_NAMESPACE_END need to be defined as well: + + \code + // in some .cpp file + #define RAPIDJSON_NAMESPACE my::rapidjson + #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { + #define RAPIDJSON_NAMESPACE_END } } + #include "rapidjson/..." + \endcode + + \see rapidjson + */ +/*! \def RAPIDJSON_NAMESPACE_BEGIN + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (opening expression) + \see RAPIDJSON_NAMESPACE +*/ +/*! \def RAPIDJSON_NAMESPACE_END + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (closing expression) + \see RAPIDJSON_NAMESPACE +*/ +#ifndef RAPIDJSON_NAMESPACE +#define RAPIDJSON_NAMESPACE rapidjson +#endif +#ifndef RAPIDJSON_NAMESPACE_BEGIN +#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { +#endif +#ifndef RAPIDJSON_NAMESPACE_END +#define RAPIDJSON_NAMESPACE_END } +#endif + +/////////////////////////////////////////////////////////////////////////////// +// __cplusplus macro + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN + +#if defined(_MSC_VER) +#define RAPIDJSON_CPLUSPLUS _MSVC_LANG +#else +#define RAPIDJSON_CPLUSPLUS __cplusplus +#endif + +//!@endcond + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_HAS_STDSTRING + +#ifndef RAPIDJSON_HAS_STDSTRING +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation +#else +#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default +#endif +/*! \def RAPIDJSON_HAS_STDSTRING + \ingroup RAPIDJSON_CONFIG + \brief Enable RapidJSON support for \c std::string + + By defining this preprocessor symbol to \c 1, several convenience functions for using + \ref rapidjson::GenericValue with \c std::string are enabled, especially + for construction and comparison. + + \hideinitializer +*/ +#endif // !defined(RAPIDJSON_HAS_STDSTRING) + +#if RAPIDJSON_HAS_STDSTRING +#include +#endif // RAPIDJSON_HAS_STDSTRING + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_USE_MEMBERSMAP + +/*! \def RAPIDJSON_USE_MEMBERSMAP + \ingroup RAPIDJSON_CONFIG + \brief Enable RapidJSON support for object members handling in a \c std::multimap + + By defining this preprocessor symbol to \c 1, \ref rapidjson::GenericValue object + members are stored in a \c std::multimap for faster lookup and deletion times, a + trade off with a slightly slower insertion time and a small object allocat(or)ed + memory overhead. + + \hideinitializer +*/ +#ifndef RAPIDJSON_USE_MEMBERSMAP +#define RAPIDJSON_USE_MEMBERSMAP 0 // not by default +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_INT64DEFINE + +/*! \def RAPIDJSON_NO_INT64DEFINE + \ingroup RAPIDJSON_CONFIG + \brief Use external 64-bit integer types. + + RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types + to be available at global scope. + + If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to + prevent RapidJSON from defining its own types. +*/ +#ifndef RAPIDJSON_NO_INT64DEFINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013 +#include "msinttypes/stdint.h" +#include "msinttypes/inttypes.h" +#else +// Other compilers should have this. +#include +#include +#endif +//!@endcond +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_INT64DEFINE +#endif +#endif // RAPIDJSON_NO_INT64TYPEDEF + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_FORCEINLINE + +#ifndef RAPIDJSON_FORCEINLINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __forceinline +#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) +#else +#define RAPIDJSON_FORCEINLINE +#endif +//!@endcond +#endif // RAPIDJSON_FORCEINLINE + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ENDIAN +#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine +#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine + +//! Endianness of the machine. +/*! + \def RAPIDJSON_ENDIAN + \ingroup RAPIDJSON_CONFIG + + GCC 4.6 provided macro for detecting endianness of the target machine. But other + compilers may not have this. User can define RAPIDJSON_ENDIAN to either + \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. + + Default detection implemented with reference to + \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html + \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp +*/ +#ifndef RAPIDJSON_ENDIAN +// Detect with GCC 4.6's macro +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __BYTE_ORDER__ +// Detect with GLIBC's endian.h +# elif defined(__GLIBC__) +# include +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __GLIBC__ +// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +// Detect with architecture macros +# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(RAPIDJSON_DOXYGEN_RUNNING) +# define RAPIDJSON_ENDIAN +# else +# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. +# endif +#endif // RAPIDJSON_ENDIAN + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_64BIT + +//! Whether using 64-bit architecture +#ifndef RAPIDJSON_64BIT +#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__) +#define RAPIDJSON_64BIT 1 +#else +#define RAPIDJSON_64BIT 0 +#endif +#endif // RAPIDJSON_64BIT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ALIGN + +//! Data alignment of the machine. +/*! \ingroup RAPIDJSON_CONFIG + \param x pointer to align + + Some machines require strict data alignment. The default is 8 bytes. + User can customize by defining the RAPIDJSON_ALIGN function macro. +*/ +#ifndef RAPIDJSON_ALIGN +#define RAPIDJSON_ALIGN(x) (((x) + static_cast(7u)) & ~static_cast(7u)) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_UINT64_C2 + +//! Construct a 64-bit literal by a pair of 32-bit integer. +/*! + 64-bit literal with or without ULL suffix is prone to compiler warnings. + UINT64_C() is C macro which cause compilation problems. + Use this macro to define 64-bit constants by a pair of 32-bit integer. +*/ +#ifndef RAPIDJSON_UINT64_C2 +#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast(high32) << 32) | static_cast(low32)) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_48BITPOINTER_OPTIMIZATION + +//! Use only lower 48-bit address for some pointers. +/*! + \ingroup RAPIDJSON_CONFIG + + This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address. + The higher 16-bit can be used for storing other data. + \c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture. +*/ +#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1 +#else +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 +#endif +#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION + +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1 +#if RAPIDJSON_64BIT != 1 +#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1 +#endif +#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast((reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast(reinterpret_cast(x)))) +#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast(reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF)))) +#else +#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x)) +#define RAPIDJSON_GETPOINTER(type, p) (p) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_NEON/RAPIDJSON_SIMD + +/*! \def RAPIDJSON_SIMD + \ingroup RAPIDJSON_CONFIG + \brief Enable SSE2/SSE4.2/Neon optimization. + + RapidJSON supports optimized implementations for some parsing operations + based on the SSE2, SSE4.2 or NEon SIMD extensions on modern Intel + or ARM compatible processors. + + To enable these optimizations, three different symbols can be defined; + \code + // Enable SSE2 optimization. + #define RAPIDJSON_SSE2 + + // Enable SSE4.2 optimization. + #define RAPIDJSON_SSE42 + \endcode + + // Enable ARM Neon optimization. + #define RAPIDJSON_NEON + \endcode + + \c RAPIDJSON_SSE42 takes precedence over SSE2, if both are defined. + + If any of these symbols is defined, RapidJSON defines the macro + \c RAPIDJSON_SIMD to indicate the availability of the optimized code. +*/ +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ + || defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING) +#define RAPIDJSON_SIMD +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_SIZETYPEDEFINE + +#ifndef RAPIDJSON_NO_SIZETYPEDEFINE +/*! \def RAPIDJSON_NO_SIZETYPEDEFINE + \ingroup RAPIDJSON_CONFIG + \brief User-provided \c SizeType definition. + + In order to avoid using 32-bit size types for indexing strings and arrays, + define this preprocessor symbol and provide the type rapidjson::SizeType + before including RapidJSON: + \code + #define RAPIDJSON_NO_SIZETYPEDEFINE + namespace rapidjson { typedef ::std::size_t SizeType; } + #include "rapidjson/..." + \endcode + + \see rapidjson::SizeType +*/ +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_SIZETYPEDEFINE +#endif +RAPIDJSON_NAMESPACE_BEGIN +//! Size type (for string lengths, array sizes, etc.) +/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, + instead of using \c size_t. Users may override the SizeType by defining + \ref RAPIDJSON_NO_SIZETYPEDEFINE. +*/ +typedef unsigned SizeType; +RAPIDJSON_NAMESPACE_END +#endif + +// always import std::size_t to rapidjson namespace +RAPIDJSON_NAMESPACE_BEGIN +using std::size_t; +RAPIDJSON_NAMESPACE_END + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ASSERT + +//! Assertion. +/*! \ingroup RAPIDJSON_CONFIG + By default, rapidjson uses C \c assert() for internal assertions. + User can override it by defining RAPIDJSON_ASSERT(x) macro. + + \note Parsing errors are handled and can be customized by the + \ref RAPIDJSON_ERRORS APIs. +*/ +#ifndef RAPIDJSON_ASSERT +#include +#define RAPIDJSON_ASSERT(x) assert(x) +#endif // RAPIDJSON_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_STATIC_ASSERT + +// Prefer C++11 static_assert, if available +#ifndef RAPIDJSON_STATIC_ASSERT +#if RAPIDJSON_CPLUSPLUS >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 ) +#define RAPIDJSON_STATIC_ASSERT(x) \ + static_assert(x, RAPIDJSON_STRINGIFY(x)) +#endif // C++11 +#endif // RAPIDJSON_STATIC_ASSERT + +// Adopt C++03 implementation from boost +#ifndef RAPIDJSON_STATIC_ASSERT +#ifndef __clang__ +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#endif +RAPIDJSON_NAMESPACE_BEGIN +template struct STATIC_ASSERTION_FAILURE; +template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; +template struct StaticAssertTest {}; +RAPIDJSON_NAMESPACE_END + +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) +#else +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif +#ifndef __clang__ +//!@endcond +#endif + +/*! \def RAPIDJSON_STATIC_ASSERT + \brief (Internal) macro to check for conditions at compile-time + \param x compile-time condition + \hideinitializer + */ +#define RAPIDJSON_STATIC_ASSERT(x) \ + typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ + sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE)> \ + RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif // RAPIDJSON_STATIC_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY + +//! Compiler branching hint for expression with high probability to be true. +/*! + \ingroup RAPIDJSON_CONFIG + \param x Boolean expression likely to be true. +*/ +#ifndef RAPIDJSON_LIKELY +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1) +#else +#define RAPIDJSON_LIKELY(x) (x) +#endif +#endif + +//! Compiler branching hint for expression with low probability to be true. +/*! + \ingroup RAPIDJSON_CONFIG + \param x Boolean expression unlikely to be true. +*/ +#ifndef RAPIDJSON_UNLIKELY +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define RAPIDJSON_UNLIKELY(x) (x) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Helpers + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN + +#define RAPIDJSON_MULTILINEMACRO_BEGIN do { +#define RAPIDJSON_MULTILINEMACRO_END \ +} while((void)0, 0) + +// adopted from Boost +#define RAPIDJSON_VERSION_CODE(x,y,z) \ + (((x)*100000) + ((y)*100) + (z)) + +#if defined(__has_builtin) +#define RAPIDJSON_HAS_BUILTIN(x) __has_builtin(x) +#else +#define RAPIDJSON_HAS_BUILTIN(x) 0 +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF + +#if defined(__GNUC__) +#define RAPIDJSON_GNUC \ + RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) +#endif + +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) + +#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) +#define RAPIDJSON_DIAG_OFF(x) \ + RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) + +// push/pop support in Clang and GCC>=4.6 +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) +#else // GCC >= 4.2, < 4.6 +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ +#endif + +#elif defined(_MSC_VER) + +// pragma (MSVC specific) +#define RAPIDJSON_PRAGMA(x) __pragma(x) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) + +#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) + +#else + +#define RAPIDJSON_DIAG_OFF(x) /* ignored */ +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ + +#endif // RAPIDJSON_DIAG_* + +/////////////////////////////////////////////////////////////////////////////// +// C++11 features + +#ifndef RAPIDJSON_HAS_CXX11 +#define RAPIDJSON_HAS_CXX11 (RAPIDJSON_CPLUSPLUS >= 201103L) +#endif + +#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS +#if RAPIDJSON_HAS_CXX11 +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#elif defined(__clang__) +#if __has_feature(cxx_rvalue_references) && \ + (defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1600) || \ + (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) + +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include // std::move +#endif + +#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT +#if RAPIDJSON_HAS_CXX11 +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 +#elif defined(__clang__) +#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1900) || \ + (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 +#else +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 +#endif +#endif +#ifndef RAPIDJSON_NOEXCEPT +#if RAPIDJSON_HAS_CXX11_NOEXCEPT +#define RAPIDJSON_NOEXCEPT noexcept +#else +#define RAPIDJSON_NOEXCEPT throw() +#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT +#endif + +// no automatic detection, yet +#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS +#if (defined(_MSC_VER) && _MSC_VER >= 1700) +#define RAPIDJSON_HAS_CXX11_TYPETRAITS 1 +#else +#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 +#endif +#endif + +#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1700) || \ + (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) +#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 +#else +#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR + +/////////////////////////////////////////////////////////////////////////////// +// C++17 features + +#ifndef RAPIDJSON_HAS_CXX17 +#define RAPIDJSON_HAS_CXX17 (RAPIDJSON_CPLUSPLUS >= 201703L) +#endif + +#if RAPIDJSON_HAS_CXX17 +# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]] +#elif defined(__has_cpp_attribute) +# if __has_cpp_attribute(clang::fallthrough) +# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[clang::fallthrough]] +# elif __has_cpp_attribute(fallthrough) +# define RAPIDJSON_DELIBERATE_FALLTHROUGH __attribute__((fallthrough)) +# else +# define RAPIDJSON_DELIBERATE_FALLTHROUGH +# endif +#else +# define RAPIDJSON_DELIBERATE_FALLTHROUGH +#endif + +//!@endcond + +//! Assertion (in non-throwing contexts). + /*! \ingroup RAPIDJSON_CONFIG + Some functions provide a \c noexcept guarantee, if the compiler supports it. + In these cases, the \ref RAPIDJSON_ASSERT macro cannot be overridden to + throw an exception. This macro adds a separate customization point for + such cases. + + Defaults to C \c assert() (as \ref RAPIDJSON_ASSERT), if \c noexcept is + supported, and to \ref RAPIDJSON_ASSERT otherwise. + */ + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NOEXCEPT_ASSERT + +#ifndef RAPIDJSON_NOEXCEPT_ASSERT +#ifdef RAPIDJSON_ASSERT_THROWS +#include +#define RAPIDJSON_NOEXCEPT_ASSERT(x) assert(x) +#else +#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x) +#endif // RAPIDJSON_ASSERT_THROWS +#endif // RAPIDJSON_NOEXCEPT_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// malloc/realloc/free + +#ifndef RAPIDJSON_MALLOC +///! customization point for global \c malloc +#define RAPIDJSON_MALLOC(size) std::malloc(size) +#endif +#ifndef RAPIDJSON_REALLOC +///! customization point for global \c realloc +#define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size) +#endif +#ifndef RAPIDJSON_FREE +///! customization point for global \c free +#define RAPIDJSON_FREE(ptr) std::free(ptr) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// new/delete + +#ifndef RAPIDJSON_NEW +///! customization point for global \c new +#define RAPIDJSON_NEW(TypeName) new TypeName +#endif +#ifndef RAPIDJSON_DELETE +///! customization point for global \c delete +#define RAPIDJSON_DELETE(x) delete x +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Type + +/*! \namespace rapidjson + \brief main RapidJSON namespace + \see RAPIDJSON_NAMESPACE +*/ +RAPIDJSON_NAMESPACE_BEGIN + +//! Type of JSON value +enum Type { + kNullType = 0, //!< null + kFalseType = 1, //!< false + kTrueType = 2, //!< true + kObjectType = 3, //!< object + kArrayType = 4, //!< array + kStringType = 5, //!< string + kNumberType = 6 //!< number +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/reader.h b/test/include/liblvgl/libs/thorvg/rapidjson/reader.h new file mode 100644 index 00000000..86c1f28e --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/reader.h @@ -0,0 +1,2246 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_READER_H_ +#define RAPIDJSON_READER_H_ + +/*! \file reader.h */ + +#include "allocators.h" +#include "stream.h" +#include "encodedstream.h" +#include "internal/clzll.h" +#include "internal/meta.h" +#include "internal/stack.h" +#include "internal/strtod.h" +#include + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#elif defined(RAPIDJSON_NEON) +#include +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(old-style-cast) +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define RAPIDJSON_NOTHING /* deliberately empty */ +#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \ + RAPIDJSON_MULTILINEMACRO_END +#endif +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING) +//!@endcond + +/*! \def RAPIDJSON_PARSE_ERROR_NORETURN + \ingroup RAPIDJSON_ERRORS + \brief Macro to indicate a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + This macros can be used as a customization point for the internal + error handling mechanism of RapidJSON. + + A common usage model is to throw an exception instead of requiring the + caller to explicitly check the \ref rapidjson::GenericReader::Parse's + return value: + + \code + #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \ + throw ParseException(parseErrorCode, #parseErrorCode, offset) + + #include // std::runtime_error + #include "rapidjson/error/error.h" // rapidjson::ParseResult + + struct ParseException : std::runtime_error, rapidjson::ParseResult { + ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset) + : std::runtime_error(msg), ParseResult(code, offset) {} + }; + + #include "rapidjson/reader.h" + \endcode + + \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse + */ +#ifndef RAPIDJSON_PARSE_ERROR_NORETURN +#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ + SetParseError(parseErrorCode, offset); \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +/*! \def RAPIDJSON_PARSE_ERROR + \ingroup RAPIDJSON_ERRORS + \brief (Internal) macro to indicate and handle a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing. + + \see RAPIDJSON_PARSE_ERROR_NORETURN + \hideinitializer + */ +#ifndef RAPIDJSON_PARSE_ERROR +#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +#include "error/error.h" // ParseErrorCode, ParseResult + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseFlag + +/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kParseDefaultFlags definition. + + User can define this as any \c ParseFlag combinations. +*/ +#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS +#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags +#endif + +//! Combination of parseFlags +/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream + */ +enum ParseFlag { + kParseNoFlags = 0, //!< No flags are set. + kParseInsituFlag = 1, //!< In-situ(destructive) parsing. + kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. + kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing. + kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error. + kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower). + kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments. + kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings. + kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays. + kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles. + kParseEscapedApostropheFlag = 512, //!< Allow escaped apostrophe in strings. + kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS +}; + +/////////////////////////////////////////////////////////////////////////////// +// Handler + +/*! \class rapidjson::Handler + \brief Concept for receiving events from GenericReader upon parsing. + The functions return true if no error occurs. If they return false, + the event publisher should terminate the process. +\code +concept Handler { + typename Ch; + + bool Null(); + bool Bool(bool b); + bool Int(int i); + bool Uint(unsigned i); + bool Int64(int64_t i); + bool Uint64(uint64_t i); + bool Double(double d); + /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) + bool RawNumber(const Ch* str, SizeType length, bool copy); + bool String(const Ch* str, SizeType length, bool copy); + bool StartObject(); + bool Key(const Ch* str, SizeType length, bool copy); + bool EndObject(SizeType memberCount); + bool StartArray(); + bool EndArray(SizeType elementCount); +}; +\endcode +*/ +/////////////////////////////////////////////////////////////////////////////// +// BaseReaderHandler + +//! Default implementation of Handler. +/*! This can be used as base class of any reader handler. + \note implements Handler concept +*/ +template, typename Derived = void> +struct BaseReaderHandler { + typedef typename Encoding::Ch Ch; + + typedef typename internal::SelectIf, BaseReaderHandler, Derived>::Type Override; + + bool Default() { return true; } + bool Null() { return static_cast(*this).Default(); } + bool Bool(bool) { return static_cast(*this).Default(); } + bool Int(int) { return static_cast(*this).Default(); } + bool Uint(unsigned) { return static_cast(*this).Default(); } + bool Int64(int64_t) { return static_cast(*this).Default(); } + bool Uint64(uint64_t) { return static_cast(*this).Default(); } + bool Double(double) { return static_cast(*this).Default(); } + /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) + bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool String(const Ch*, SizeType, bool) { return static_cast(*this).Default(); } + bool StartObject() { return static_cast(*this).Default(); } + bool Key(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool EndObject(SizeType) { return static_cast(*this).Default(); } + bool StartArray() { return static_cast(*this).Default(); } + bool EndArray(SizeType) { return static_cast(*this).Default(); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// StreamLocalCopy + +namespace internal { + +template::copyOptimization> +class StreamLocalCopy; + +//! Do copy optimization. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original), original_(original) {} + ~StreamLocalCopy() { original_ = s; } + + Stream s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; + + Stream& original_; +}; + +//! Keep reference. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original) {} + + Stream& s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// SkipWhitespace + +//! Skip the JSON white spaces in a stream. +/*! \param is A input stream for skipping white spaces. + \note This function has SSE2/SSE4.2 specialization. +*/ +template +void SkipWhitespace(InputStream& is) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + typename InputStream::Ch c; + while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t') + s.Take(); +} + +inline const char* SkipWhitespace(const char* p, const char* end) { + while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + return p; +} + +#ifdef RAPIDJSON_SSE42 +//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY); + if (r != 16) // some of characters is non-whitespace + return p + r; + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + // The middle of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); + + for (; p <= end - 16; p += 16) { + const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); + const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY); + if (r != 16) // some of characters is non-whitespace + return p + r; + } + + return SkipWhitespace(p, end); +} + +#elif defined(RAPIDJSON_SSE2) + +//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string + #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } + static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; + #undef C16 + + const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); + const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); + const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); + const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = static_cast(~_mm_movemask_epi8(x)); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + // The rest of string + #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } + static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; + #undef C16 + + const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); + const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); + const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); + const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); + + for (; p <= end - 16; p += 16) { + const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = static_cast(~_mm_movemask_epi8(x)); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } + + return SkipWhitespace(p, end); +} + +#elif defined(RAPIDJSON_NEON) + +//! Skip whitespace with ARM Neon instructions, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + const uint8x16_t w0 = vmovq_n_u8(' '); + const uint8x16_t w1 = vmovq_n_u8('\n'); + const uint8x16_t w2 = vmovq_n_u8('\r'); + const uint8x16_t w3 = vmovq_n_u8('\t'); + + for (;; p += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, w0); + x = vorrq_u8(x, vceqq_u8(s, w1)); + x = vorrq_u8(x, vceqq_u8(s, w2)); + x = vorrq_u8(x, vceqq_u8(s, w3)); + + x = vmvnq_u8(x); // Negate + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + return p + 8 + (lz >> 3); + } + } else { + uint32_t lz = internal::clzll(low); + return p + (lz >> 3); + } + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + const uint8x16_t w0 = vmovq_n_u8(' '); + const uint8x16_t w1 = vmovq_n_u8('\n'); + const uint8x16_t w2 = vmovq_n_u8('\r'); + const uint8x16_t w3 = vmovq_n_u8('\t'); + + for (; p <= end - 16; p += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, w0); + x = vorrq_u8(x, vceqq_u8(s, w1)); + x = vorrq_u8(x, vceqq_u8(s, w2)); + x = vorrq_u8(x, vceqq_u8(s, w3)); + + x = vmvnq_u8(x); // Negate + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + return p + 8 + (lz >> 3); + } + } else { + uint32_t lz = internal::clzll(low); + return p + (lz >> 3); + } + } + + return SkipWhitespace(p, end); +} + +#endif // RAPIDJSON_NEON + +#ifdef RAPIDJSON_SIMD +//! Template function specialization for InsituStringStream +template<> inline void SkipWhitespace(InsituStringStream& is) { + is.src_ = const_cast(SkipWhitespace_SIMD(is.src_)); +} + +//! Template function specialization for StringStream +template<> inline void SkipWhitespace(StringStream& is) { + is.src_ = SkipWhitespace_SIMD(is.src_); +} + +template<> inline void SkipWhitespace(EncodedInputStream, MemoryStream>& is) { + is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_); +} +#endif // RAPIDJSON_SIMD + +/////////////////////////////////////////////////////////////////////////////// +// GenericReader + +//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. +/*! GenericReader parses JSON text from a stream, and send events synchronously to an + object implementing Handler concept. + + It needs to allocate a stack for storing a single decoded string during + non-destructive parsing. + + For in-situ parsing, the decoded string is directly written to the source + text string, no temporary buffer is required. + + A GenericReader object can be reused for parsing multiple JSON text. + + \tparam SourceEncoding Encoding of the input stream. + \tparam TargetEncoding Encoding of the parse output. + \tparam StackAllocator Allocator type for stack. +*/ +template +class GenericReader { +public: + typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type + + //! Constructor. + /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) + \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) + */ + GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : + stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {} + + //! Parse JSON text. + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + if (parseFlags & kParseIterativeFlag) + return IterativeParse(is, handler); + + parseResult_.Clear(); + + ClearStackOnExit scope(*this); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + else { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (!(parseFlags & kParseStopWhenDoneFlag)) { + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + } + } + + return parseResult_; + } + + //! Parse JSON text (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + return Parse(is, handler); + } + + //! Initialize JSON text token-by-token parsing + /*! + */ + void IterativeParseInit() { + parseResult_.Clear(); + state_ = IterativeParsingStartState; + } + + //! Parse one token from JSON text + /*! \tparam InputStream Type of input stream, implementing Stream concept + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + bool IterativeParseNext(InputStream& is, Handler& handler) { + while (RAPIDJSON_LIKELY(is.Peek() != '\0')) { + SkipWhitespaceAndComments(is); + + Token t = Tokenize(is.Peek()); + IterativeParsingState n = Predict(state_, t); + IterativeParsingState d = Transit(state_, t, n, is, handler); + + // If we've finished or hit an error... + if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) { + // Report errors. + if (d == IterativeParsingErrorState) { + HandleError(state_, is); + return false; + } + + // Transition to the finish state. + RAPIDJSON_ASSERT(d == IterativeParsingFinishState); + state_ = d; + + // If StopWhenDone is not set... + if (!(parseFlags & kParseStopWhenDoneFlag)) { + // ... and extra non-whitespace data is found... + SkipWhitespaceAndComments(is); + if (is.Peek() != '\0') { + // ... this is considered an error. + HandleError(state_, is); + return false; + } + } + + // Success! We are done! + return true; + } + + // Transition to the new state. + state_ = d; + + // If we parsed anything other than a delimiter, we invoked the handler, so we can return true now. + if (!IsIterativeParsingDelimiterState(n)) + return true; + } + + // We reached the end of file. + stack_.Clear(); + + if (state_ != IterativeParsingFinishState) { + HandleError(state_, is); + return false; + } + + return true; + } + + //! Check if token-by-token parsing JSON text is complete + /*! \return Whether the JSON has been fully decoded. + */ + RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const { + return IsIterativeParsingCompleteState(state_); + } + + //! Whether a parse error has occurred in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + +protected: + void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); } + +private: + // Prohibit copy constructor & assignment operator. + GenericReader(const GenericReader&); + GenericReader& operator=(const GenericReader&); + + void ClearStack() { stack_.Clear(); } + + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericReader& r) : r_(r) {} + ~ClearStackOnExit() { r_.ClearStack(); } + private: + GenericReader& r_; + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + }; + + template + void SkipWhitespaceAndComments(InputStream& is) { + SkipWhitespace(is); + + if (parseFlags & kParseCommentsFlag) { + while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) { + if (Consume(is, '*')) { + while (true) { + if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) + RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + else if (Consume(is, '*')) { + if (Consume(is, '/')) + break; + } + else + is.Take(); + } + } + else if (RAPIDJSON_LIKELY(Consume(is, '/'))) + while (is.Peek() != '\0' && is.Take() != '\n') {} + else + RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + + SkipWhitespace(is); + } + } + } + + // Parse object: { string : value, ... } + template + void ParseObject(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '{'); + is.Take(); // Skip '{' + + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, '}')) { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType memberCount = 0;;) { + if (RAPIDJSON_UNLIKELY(is.Peek() != '"')) + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); + + ParseString(is, handler, true); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (RAPIDJSON_UNLIKELY(!Consume(is, ':'))) + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++memberCount; + + switch (is.Peek()) { + case ',': + is.Take(); + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + break; + case '}': + is.Take(); + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + default: + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy + } + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == '}') { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } + } + } + + // Parse array: [ value, ... ] + template + void ParseArray(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '['); + is.Take(); // Skip '[' + + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, ']')) { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType elementCount = 0;;) { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++elementCount; + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, ',')) { + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + } + else if (Consume(is, ']')) { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == ']') { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } + } + } + + template + void ParseNull(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'n'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) { + if (RAPIDJSON_UNLIKELY(!handler.Null())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + void ParseTrue(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 't'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) { + if (RAPIDJSON_UNLIKELY(!handler.Bool(true))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + void ParseFalse(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'f'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) { + if (RAPIDJSON_UNLIKELY(!handler.Bool(false))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) { + if (RAPIDJSON_LIKELY(is.Peek() == expect)) { + is.Take(); + return true; + } + else + return false; + } + + // Helper function to parse four hexadecimal digits in \uXXXX in ParseString(). + template + unsigned ParseHex4(InputStream& is, size_t escapeOffset) { + unsigned codepoint = 0; + for (int i = 0; i < 4; i++) { + Ch c = is.Peek(); + codepoint <<= 4; + codepoint += static_cast(c); + if (c >= '0' && c <= '9') + codepoint -= '0'; + else if (c >= 'A' && c <= 'F') + codepoint -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + codepoint -= 'a' - 10; + else { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0); + } + is.Take(); + } + return codepoint; + } + + template + class StackStream { + public: + typedef CharType Ch; + + StackStream(internal::Stack& stack) : stack_(stack), length_(0) {} + RAPIDJSON_FORCEINLINE void Put(Ch c) { + *stack_.template Push() = c; + ++length_; + } + + RAPIDJSON_FORCEINLINE void* Push(SizeType count) { + length_ += count; + return stack_.template Push(count); + } + + size_t Length() const { return length_; } + + Ch* Pop() { + return stack_.template Pop(length_); + } + + private: + StackStream(const StackStream&); + StackStream& operator=(const StackStream&); + + internal::Stack& stack_; + SizeType length_; + }; + + // Parse string and generate String event. Different code paths for kParseInsituFlag. + template + void ParseString(InputStream& is, Handler& handler, bool isKey = false) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + RAPIDJSON_ASSERT(s.Peek() == '\"'); + s.Take(); // Skip '\"' + + bool success = false; + if (parseFlags & kParseInsituFlag) { + typename InputStream::Ch *head = s.PutBegin(); + ParseStringToStream(s, s); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + size_t length = s.PutEnd(head) - 1; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + const typename TargetEncoding::Ch* const str = reinterpret_cast(head); + success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); + } + else { + StackStream stackStream(stack_); + ParseStringToStream(s, stackStream); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + SizeType length = static_cast(stackStream.Length()) - 1; + const typename TargetEncoding::Ch* const str = stackStream.Pop(); + success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true)); + } + if (RAPIDJSON_UNLIKELY(!success)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); + } + + // Parse string to an output is + // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. + template + RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + static const char escape[256] = { + Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/', + Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, + 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, + 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 + }; +#undef Z16 +//!@endcond + + for (;;) { + // Scan and copy string before "\\\"" or < 0x20. This is an optional optimization. + if (!(parseFlags & kParseValidateEncodingFlag)) + ScanCopyUnescapedString(is, os); + + Ch c = is.Peek(); + if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape + size_t escapeOffset = is.Tell(); // For invalid escaping, report the initial '\\' as error offset + is.Take(); + Ch e = is.Peek(); + if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast(e)])) { + is.Take(); + os.Put(static_cast(escape[static_cast(e)])); + } + else if ((parseFlags & kParseEscapedApostropheFlag) && RAPIDJSON_LIKELY(e == '\'')) { // Allow escaped apostrophe + is.Take(); + os.Put('\''); + } + else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode + is.Take(); + unsigned codepoint = ParseHex4(is, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDFFF)) { + // high surrogate, check if followed by valid low surrogate + if (RAPIDJSON_LIKELY(codepoint <= 0xDBFF)) { + // Handle UTF-16 surrogate pair + if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u'))) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + unsigned codepoint2 = ParseHex4(is, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; + } + // single low surrogate + else + { + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + } + } + TEncoding::Encode(os, codepoint); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset); + } + else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote + is.Take(); + os.Put('\0'); // null-terminate the string + return; + } + else if (RAPIDJSON_UNLIKELY(static_cast(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF + if (c == '\0') + RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell()); + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell()); + } + else { + size_t offset = is.Tell(); + if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? + !Transcoder::Validate(is, os) : + !Transcoder::Transcode(is, os)))) + RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset); + } + } + } + + template + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) { + // Do nothing for generic version + } + +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) + // StringStream -> StackStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream& os) { + const char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + return; + } + else + os.Put(*p++); + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + SizeType length; + #ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; + #else + length = static_cast(__builtin_ffs(r) - 1); + #endif + if (length != 0) { + char* q = reinterpret_cast(os.Push(length)); + for (size_t i = 0; i < length; i++) + q[i] = p[i]; + + p += length; + } + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s); + } + + is.src_ = p; + } + + // InsituStringStream -> InsituStringStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { + RAPIDJSON_ASSERT(&is == &os); + (void)os; + + if (is.src_ == is.dst_) { + SkipUnescapedString(is); + return; + } + + char* p = is.src_; + char *q = is.dst_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + is.dst_ = q; + return; + } + else + *q++ = *p++; + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16, q += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + size_t length; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; +#else + length = static_cast(__builtin_ffs(r) - 1); +#endif + for (const char* pend = p + length; p != pend; ) + *q++ = *p++; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s); + } + + is.src_ = p; + is.dst_ = q; + } + + // When read/write pointers are the same for insitu stream, just skip unescaped characters + static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { + RAPIDJSON_ASSERT(is.src_ == is.dst_); + char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + for (; p != nextAligned; p++) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = is.dst_ = p; + return; + } + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + size_t length; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; +#else + length = static_cast(__builtin_ffs(r) - 1); +#endif + p += length; + break; + } + } + + is.src_ = is.dst_ = p; + } +#elif defined(RAPIDJSON_NEON) + // StringStream -> StackStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream& os) { + const char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + return; + } + else + os.Put(*p++); + + // The rest of string using SIMD + const uint8x16_t s0 = vmovq_n_u8('"'); + const uint8x16_t s1 = vmovq_n_u8('\\'); + const uint8x16_t s2 = vmovq_n_u8('\b'); + const uint8x16_t s3 = vmovq_n_u8(32); + + for (;; p += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, s0); + x = vorrq_u8(x, vceqq_u8(s, s1)); + x = vorrq_u8(x, vceqq_u8(s, s2)); + x = vorrq_u8(x, vcltq_u8(s, s3)); + + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + SizeType length = 0; + bool escaped = false; + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + length = 8 + (lz >> 3); + escaped = true; + } + } else { + uint32_t lz = internal::clzll(low); + length = lz >> 3; + escaped = true; + } + if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped + if (length != 0) { + char* q = reinterpret_cast(os.Push(length)); + for (size_t i = 0; i < length; i++) + q[i] = p[i]; + + p += length; + } + break; + } + vst1q_u8(reinterpret_cast(os.Push(16)), s); + } + + is.src_ = p; + } + + // InsituStringStream -> InsituStringStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { + RAPIDJSON_ASSERT(&is == &os); + (void)os; + + if (is.src_ == is.dst_) { + SkipUnescapedString(is); + return; + } + + char* p = is.src_; + char *q = is.dst_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + is.dst_ = q; + return; + } + else + *q++ = *p++; + + // The rest of string using SIMD + const uint8x16_t s0 = vmovq_n_u8('"'); + const uint8x16_t s1 = vmovq_n_u8('\\'); + const uint8x16_t s2 = vmovq_n_u8('\b'); + const uint8x16_t s3 = vmovq_n_u8(32); + + for (;; p += 16, q += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, s0); + x = vorrq_u8(x, vceqq_u8(s, s1)); + x = vorrq_u8(x, vceqq_u8(s, s2)); + x = vorrq_u8(x, vcltq_u8(s, s3)); + + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + SizeType length = 0; + bool escaped = false; + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + length = 8 + (lz >> 3); + escaped = true; + } + } else { + uint32_t lz = internal::clzll(low); + length = lz >> 3; + escaped = true; + } + if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped + for (const char* pend = p + length; p != pend; ) { + *q++ = *p++; + } + break; + } + vst1q_u8(reinterpret_cast(q), s); + } + + is.src_ = p; + is.dst_ = q; + } + + // When read/write pointers are the same for insitu stream, just skip unescaped characters + static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { + RAPIDJSON_ASSERT(is.src_ == is.dst_); + char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + for (; p != nextAligned; p++) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = is.dst_ = p; + return; + } + + // The rest of string using SIMD + const uint8x16_t s0 = vmovq_n_u8('"'); + const uint8x16_t s1 = vmovq_n_u8('\\'); + const uint8x16_t s2 = vmovq_n_u8('\b'); + const uint8x16_t s3 = vmovq_n_u8(32); + + for (;; p += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, s0); + x = vorrq_u8(x, vceqq_u8(s, s1)); + x = vorrq_u8(x, vceqq_u8(s, s2)); + x = vorrq_u8(x, vcltq_u8(s, s3)); + + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + p += 8 + (lz >> 3); + break; + } + } else { + uint32_t lz = internal::clzll(low); + p += lz >> 3; + break; + } + } + + is.src_ = is.dst_ = p; + } +#endif // RAPIDJSON_NEON + + template + class NumberStream; + + template + class NumberStream { + public: + typedef typename InputStream::Ch Ch; + + NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; } + + RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); } + RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); } + RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); } + RAPIDJSON_FORCEINLINE void Push(char) {} + + size_t Tell() { return is.Tell(); } + size_t Length() { return 0; } + const StackCharacter* Pop() { return 0; } + + protected: + NumberStream& operator=(const NumberStream&); + + InputStream& is; + }; + + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s), stackStream(reader.stack_) {} + + RAPIDJSON_FORCEINLINE Ch TakePush() { + stackStream.Put(static_cast(Base::is.Peek())); + return Base::is.Take(); + } + + RAPIDJSON_FORCEINLINE void Push(StackCharacter c) { + stackStream.Put(c); + } + + size_t Length() { return stackStream.Length(); } + + const StackCharacter* Pop() { + stackStream.Put('\0'); + return stackStream.Pop(); + } + + private: + StackStream stackStream; + }; + + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s) {} + + RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); } + }; + + template + void ParseNumber(InputStream& is, Handler& handler) { + typedef typename internal::SelectIf, typename TargetEncoding::Ch, char>::Type NumberCharacter; + + internal::StreamLocalCopy copy(is); + NumberStream s(*this, copy.s); + + size_t startOffset = s.Tell(); + double d = 0.0; + bool useNanOrInf = false; + + // Parse minus + bool minus = Consume(s, '-'); + + // Parse int: zero / ( digit1-9 *DIGIT ) + unsigned i = 0; + uint64_t i64 = 0; + bool use64bit = false; + int significandDigit = 0; + if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) { + i = 0; + s.TakePush(); + } + else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) { + i = static_cast(s.TakePush() - '0'); + + if (minus) + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648 + if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + else + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295 + if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + } + // Parse NaN or Infinity here + else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) { + if (Consume(s, 'N')) { + if (Consume(s, 'a') && Consume(s, 'N')) { + d = std::numeric_limits::quiet_NaN(); + useNanOrInf = true; + } + } + else if (RAPIDJSON_LIKELY(Consume(s, 'I'))) { + if (Consume(s, 'n') && Consume(s, 'f')) { + d = (minus ? -std::numeric_limits::infinity() : std::numeric_limits::infinity()); + useNanOrInf = true; + + if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') + && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) { + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + } + } + } + + if (RAPIDJSON_UNLIKELY(!useNanOrInf)) { + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + + // Parse 64bit int + bool useDouble = false; + if (use64bit) { + if (minus) + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808 + if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) { + d = static_cast(i64); + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + else + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615 + if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) { + d = static_cast(i64); + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + } + + // Force double for big integer + if (useDouble) { + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + d = d * 10 + (s.TakePush() - '0'); + } + } + + // Parse frac = decimal-point 1*DIGIT + int expFrac = 0; + size_t decimalPosition; + if (Consume(s, '.')) { + decimalPosition = s.Length(); + + if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9'))) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell()); + + if (!useDouble) { +#if RAPIDJSON_64BIT + // Use i64 to store significand in 64-bit architecture + if (!use64bit) + i64 = i; + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path + break; + else { + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + --expFrac; + if (i64 != 0) + significandDigit++; + } + } + + d = static_cast(i64); +#else + // Use double to store significand in 32-bit architecture + d = static_cast(use64bit ? i64 : i); +#endif + useDouble = true; + } + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (significandDigit < 17) { + d = d * 10.0 + (s.TakePush() - '0'); + --expFrac; + if (RAPIDJSON_LIKELY(d > 0.0)) + significandDigit++; + } + else + s.TakePush(); + } + } + else + decimalPosition = s.Length(); // decimal position at the end of integer. + + // Parse exp = e [ minus / plus ] 1*DIGIT + int exp = 0; + if (Consume(s, 'e') || Consume(s, 'E')) { + if (!useDouble) { + d = static_cast(use64bit ? i64 : i); + useDouble = true; + } + + bool expMinus = false; + if (Consume(s, '+')) + ; + else if (Consume(s, '-')) + expMinus = true; + + if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = static_cast(s.Take() - '0'); + if (expMinus) { + // (exp + expFrac) must not underflow int => we're detecting when -exp gets + // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into + // underflow territory): + // + // -(exp * 10 + 9) + expFrac >= INT_MIN + // <=> exp <= (expFrac - INT_MIN - 9) / 10 + RAPIDJSON_ASSERT(expFrac <= 0); + int maxExp = (expFrac + 2147483639) / 10; + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = exp * 10 + static_cast(s.Take() - '0'); + if (RAPIDJSON_UNLIKELY(exp > maxExp)) { + while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent + s.Take(); + } + } + } + else { // positive exp + int maxExp = 308 - expFrac; + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = exp * 10 + static_cast(s.Take() - '0'); + if (RAPIDJSON_UNLIKELY(exp > maxExp)) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); + } + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell()); + + if (expMinus) + exp = -exp; + } + + // Finish parsing, call event according to the type of number. + bool cont = true; + + if (parseFlags & kParseNumbersAsStringsFlag) { + if (parseFlags & kParseInsituFlag) { + s.Pop(); // Pop stack no matter if it will be used or not. + typename InputStream::Ch* head = is.PutBegin(); + const size_t length = s.Tell() - startOffset; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + // unable to insert the \0 character here, it will erase the comma after this number + const typename TargetEncoding::Ch* const str = reinterpret_cast(head); + cont = handler.RawNumber(str, SizeType(length), false); + } + else { + SizeType numCharsToCopy = static_cast(s.Length()); + GenericStringStream > srcStream(s.Pop()); + StackStream dstStream(stack_); + while (numCharsToCopy--) { + Transcoder, TargetEncoding>::Transcode(srcStream, dstStream); + } + dstStream.Put('\0'); + const typename TargetEncoding::Ch* str = dstStream.Pop(); + const SizeType length = static_cast(dstStream.Length()) - 1; + cont = handler.RawNumber(str, SizeType(length), true); + } + } + else { + size_t length = s.Length(); + const NumberCharacter* decimal = s.Pop(); // Pop stack no matter if it will be used or not. + + if (useDouble) { + int p = exp + expFrac; + if (parseFlags & kParseFullPrecisionFlag) + d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp); + else + d = internal::StrtodNormalPrecision(d, p); + + // Use > max, instead of == inf, to fix bogus warning -Wfloat-equal + if (d > (std::numeric_limits::max)()) { + // Overflow + // TODO: internal::StrtodX should report overflow (or underflow) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); + } + + cont = handler.Double(minus ? -d : d); + } + else if (useNanOrInf) { + cont = handler.Double(d); + } + else { + if (use64bit) { + if (minus) + cont = handler.Int64(static_cast(~i64 + 1)); + else + cont = handler.Uint64(i64); + } + else { + if (minus) + cont = handler.Int(static_cast(~i + 1)); + else + cont = handler.Uint(i); + } + } + } + if (RAPIDJSON_UNLIKELY(!cont)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset); + } + + // Parse any JSON value + template + void ParseValue(InputStream& is, Handler& handler) { + switch (is.Peek()) { + case 'n': ParseNull (is, handler); break; + case 't': ParseTrue (is, handler); break; + case 'f': ParseFalse (is, handler); break; + case '"': ParseString(is, handler); break; + case '{': ParseObject(is, handler); break; + case '[': ParseArray (is, handler); break; + default : + ParseNumber(is, handler); + break; + + } + } + + // Iterative Parsing + + // States + enum IterativeParsingState { + IterativeParsingFinishState = 0, // sink states at top + IterativeParsingErrorState, // sink states at top + IterativeParsingStartState, + + // Object states + IterativeParsingObjectInitialState, + IterativeParsingMemberKeyState, + IterativeParsingMemberValueState, + IterativeParsingObjectFinishState, + + // Array states + IterativeParsingArrayInitialState, + IterativeParsingElementState, + IterativeParsingArrayFinishState, + + // Single value state + IterativeParsingValueState, + + // Delimiter states (at bottom) + IterativeParsingElementDelimiterState, + IterativeParsingMemberDelimiterState, + IterativeParsingKeyValueDelimiterState, + + cIterativeParsingStateCount + }; + + // Tokens + enum Token { + LeftBracketToken = 0, + RightBracketToken, + + LeftCurlyBracketToken, + RightCurlyBracketToken, + + CommaToken, + ColonToken, + + StringToken, + FalseToken, + TrueToken, + NullToken, + NumberToken, + + kTokenCount + }; + + RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) const { + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define N NumberToken +#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N + // Maps from ASCII to Token + static const unsigned char tokenMap[256] = { + N16, // 00~0F + N16, // 10~1F + N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F + N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F + N16, // 40~4F + N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F + N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F + N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F + N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF + }; +#undef N +#undef N16 +//!@endcond + + if (sizeof(Ch) == 1 || static_cast(c) < 256) + return static_cast(tokenMap[static_cast(c)]); + else + return NumberToken; + } + + RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) const { + // current state x one lookahead token -> new state + static const char G[cIterativeParsingStateCount][kTokenCount] = { + // Finish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Error(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Start + { + IterativeParsingArrayInitialState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingValueState, // String + IterativeParsingValueState, // False + IterativeParsingValueState, // True + IterativeParsingValueState, // Null + IterativeParsingValueState // Number + }, + // ObjectInitial + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberKey + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingKeyValueDelimiterState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberValue + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingMemberDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ObjectFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ArrayInitial + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // Element + { + IterativeParsingErrorState, // Left bracket + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingElementDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ArrayFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Single Value (sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ElementDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // MemberDelimiter + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // KeyValueDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push MemberValue state) + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberValueState, // String + IterativeParsingMemberValueState, // False + IterativeParsingMemberValueState, // True + IterativeParsingMemberValueState, // Null + IterativeParsingMemberValueState // Number + }, + }; // End of G + + return static_cast(G[state][token]); + } + + // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). + // May return a new state on state pop. + template + RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) { + (void)token; + + switch (dst) { + case IterativeParsingErrorState: + return dst; + + case IterativeParsingObjectInitialState: + case IterativeParsingArrayInitialState: + { + // Push the state(Element or MemberValue) if we are nested in another array or value of member. + // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop. + IterativeParsingState n = src; + if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState) + n = IterativeParsingElementState; + else if (src == IterativeParsingKeyValueDelimiterState) + n = IterativeParsingMemberValueState; + // Push current state. + *stack_.template Push(1) = n; + // Initialize and push the member/element count. + *stack_.template Push(1) = 0; + // Call handler + bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray(); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return dst; + } + } + + case IterativeParsingMemberKeyState: + ParseString(is, handler, true); + if (HasParseError()) + return IterativeParsingErrorState; + else + return dst; + + case IterativeParsingKeyValueDelimiterState: + RAPIDJSON_ASSERT(token == ColonToken); + is.Take(); + return dst; + + case IterativeParsingMemberValueState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingElementState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingMemberDelimiterState: + case IterativeParsingElementDelimiterState: + is.Take(); + // Update member/element count. + *stack_.template Top() = *stack_.template Top() + 1; + return dst; + + case IterativeParsingObjectFinishState: + { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell()); + return IterativeParsingErrorState; + } + // Get member count. + SizeType c = *stack_.template Pop(1); + // If the object is not empty, count the last member. + if (src == IterativeParsingMemberValueState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndObject(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + case IterativeParsingArrayFinishState: + { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell()); + return IterativeParsingErrorState; + } + // Get element count. + SizeType c = *stack_.template Pop(1); + // If the array is not empty, count the last element. + if (src == IterativeParsingElementState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndArray(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + default: + // This branch is for IterativeParsingValueState actually. + // Use `default:` rather than + // `case IterativeParsingValueState:` is for code coverage. + + // The IterativeParsingStartState is not enumerated in this switch-case. + // It is impossible for that case. And it can be caught by following assertion. + + // The IterativeParsingFinishState is not enumerated in this switch-case either. + // It is a "derivative" state which cannot triggered from Predict() directly. + // Therefore it cannot happen here. And it can be caught by following assertion. + RAPIDJSON_ASSERT(dst == IterativeParsingValueState); + + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return IterativeParsingFinishState; + } + } + + template + void HandleError(IterativeParsingState src, InputStream& is) { + if (HasParseError()) { + // Error flag has been set. + return; + } + + switch (src) { + case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return; + case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return; + case IterativeParsingObjectInitialState: + case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return; + case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return; + case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return; + case IterativeParsingKeyValueDelimiterState: + case IterativeParsingArrayInitialState: + case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return; + default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return; + } + } + + RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const { + return s >= IterativeParsingElementDelimiterState; + } + + RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const { + return s <= IterativeParsingErrorState; + } + + template + ParseResult IterativeParse(InputStream& is, Handler& handler) { + parseResult_.Clear(); + ClearStackOnExit scope(*this); + IterativeParsingState state = IterativeParsingStartState; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + while (is.Peek() != '\0') { + Token t = Tokenize(is.Peek()); + IterativeParsingState n = Predict(state, t); + IterativeParsingState d = Transit(state, t, n, is, handler); + + if (d == IterativeParsingErrorState) { + HandleError(state, is); + break; + } + + state = d; + + // Do not further consume streams if a root JSON has been parsed. + if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState) + break; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + + // Handle the end of file. + if (state != IterativeParsingFinishState) + HandleError(state, is); + + return parseResult_; + } + + static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. + internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. + ParseResult parseResult_; + IterativeParsingState state_; +}; // class GenericReader + +//! Reader with UTF8 encoding and default allocator. +typedef GenericReader, UTF8<> > Reader; + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_READER_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/schema.h b/test/include/liblvgl/libs/thorvg/rapidjson/schema.h new file mode 100644 index 00000000..453e43e3 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/schema.h @@ -0,0 +1,3262 @@ +// Tencent is pleased to support the open source community by making RapidJSON available-> +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved-> +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License-> You may obtain a copy of the License at +// +// http://opensource->org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied-> See the License for the +// specific language governing permissions and limitations under the License-> + +#ifndef RAPIDJSON_SCHEMA_H_ +#define RAPIDJSON_SCHEMA_H_ + +#include "document.h" +#include "pointer.h" +#include "stringbuffer.h" +#include "error/en.h" +#include "uri.h" +#include // abs, floor + +#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX) +#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 +#else +#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 +#endif + +#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) +#define RAPIDJSON_SCHEMA_USE_STDREGEX 1 +#else +#define RAPIDJSON_SCHEMA_USE_STDREGEX 0 +#endif + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX +#include "internal/regex.h" +#elif RAPIDJSON_SCHEMA_USE_STDREGEX +#include +#endif + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX +#define RAPIDJSON_SCHEMA_HAS_REGEX 1 +#else +#define RAPIDJSON_SCHEMA_HAS_REGEX 0 +#endif + +#ifndef RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_SCHEMA_VERBOSE 0 +#endif + +RAPIDJSON_DIAG_PUSH + +#if defined(__GNUC__) +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_OFF(weak-vtables) +RAPIDJSON_DIAG_OFF(exit-time-destructors) +RAPIDJSON_DIAG_OFF(c++98-compat-pedantic) +RAPIDJSON_DIAG_OFF(variadic-macros) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Verbose Utilities + +#if RAPIDJSON_SCHEMA_VERBOSE + +namespace internal { + +inline void PrintInvalidKeywordData(const char* keyword) { + printf(" Fail keyword: '%s'\n", keyword); +} + +inline void PrintInvalidKeywordData(const wchar_t* keyword) { + wprintf(L" Fail keyword: '%ls'\n", keyword); +} + +inline void PrintInvalidDocumentData(const char* document) { + printf(" Fail document: '%s'\n", document); +} + +inline void PrintInvalidDocumentData(const wchar_t* document) { + wprintf(L" Fail document: '%ls'\n", document); +} + +inline void PrintValidatorPointersData(const char* s, const char* d, unsigned depth) { + printf(" Sch: %*s'%s'\n Doc: %*s'%s'\n", depth * 4, " ", s, depth * 4, " ", d); +} + +inline void PrintValidatorPointersData(const wchar_t* s, const wchar_t* d, unsigned depth) { + wprintf(L" Sch: %*ls'%ls'\n Doc: %*ls'%ls'\n", depth * 4, L" ", s, depth * 4, L" ", d); +} + +inline void PrintSchemaIdsData(const char* base, const char* local, const char* resolved) { + printf(" Resolving id: Base: '%s', Local: '%s', Resolved: '%s'\n", base, local, resolved); +} + +inline void PrintSchemaIdsData(const wchar_t* base, const wchar_t* local, const wchar_t* resolved) { + wprintf(L" Resolving id: Base: '%ls', Local: '%ls', Resolved: '%ls'\n", base, local, resolved); +} + +inline void PrintMethodData(const char* method) { + printf("%s\n", method); +} + +inline void PrintMethodData(const char* method, bool b) { + printf("%s, Data: '%s'\n", method, b ? "true" : "false"); +} + +inline void PrintMethodData(const char* method, int64_t i) { + printf("%s, Data: '%" PRId64 "'\n", method, i); +} + +inline void PrintMethodData(const char* method, uint64_t u) { + printf("%s, Data: '%" PRIu64 "'\n", method, u); +} + +inline void PrintMethodData(const char* method, double d) { + printf("%s, Data: '%lf'\n", method, d); +} + +inline void PrintMethodData(const char* method, const char* s) { + printf("%s, Data: '%s'\n", method, s); +} + +inline void PrintMethodData(const char* method, const wchar_t* s) { + wprintf(L"%hs, Data: '%ls'\n", method, s); +} + +inline void PrintMethodData(const char* method, const char* s1, const char* s2) { + printf("%s, Data: '%s', '%s'\n", method, s1, s2); +} + +inline void PrintMethodData(const char* method, const wchar_t* s1, const wchar_t* s2) { + wprintf(L"%hs, Data: '%ls', '%ls'\n", method, s1, s2); +} + +} // namespace internal + +#endif // RAPIDJSON_SCHEMA_VERBOSE + +#ifndef RAPIDJSON_SCHEMA_PRINT +#if RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_SCHEMA_PRINT(name, ...) internal::Print##name##Data(__VA_ARGS__) +#else +#define RAPIDJSON_SCHEMA_PRINT(name, ...) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_INVALID_KEYWORD_RETURN + +#define RAPIDJSON_INVALID_KEYWORD_RETURN(code)\ +RAPIDJSON_MULTILINEMACRO_BEGIN\ + context.invalidCode = code;\ + context.invalidKeyword = SchemaType::GetValidateErrorKeyword(code).GetString();\ + RAPIDJSON_SCHEMA_PRINT(InvalidKeyword, context.invalidKeyword);\ + return false;\ +RAPIDJSON_MULTILINEMACRO_END + +/////////////////////////////////////////////////////////////////////////////// +// ValidateFlag + +/*! \def RAPIDJSON_VALIDATE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kValidateDefaultFlags definition. + + User can define this as any \c ValidateFlag combinations. +*/ +#ifndef RAPIDJSON_VALIDATE_DEFAULT_FLAGS +#define RAPIDJSON_VALIDATE_DEFAULT_FLAGS kValidateNoFlags +#endif + +//! Combination of validate flags +/*! \see + */ +enum ValidateFlag { + kValidateNoFlags = 0, //!< No flags are set. + kValidateContinueOnErrorFlag = 1, //!< Don't stop after first validation error. + kValidateReadFlag = 2, //!< Validation is for a read semantic. + kValidateWriteFlag = 4, //!< Validation is for a write semantic. + kValidateDefaultFlags = RAPIDJSON_VALIDATE_DEFAULT_FLAGS //!< Default validate flags. Can be customized by defining RAPIDJSON_VALIDATE_DEFAULT_FLAGS +}; + +/////////////////////////////////////////////////////////////////////////////// +// Specification +enum SchemaDraft { + kDraftUnknown = -1, + kDraftNone = 0, + kDraft03 = 3, + kDraftMin = 4, //!< Current minimum supported draft + kDraft04 = 4, + kDraft05 = 5, + kDraftMax = 5, //!< Current maximum supported draft + kDraft06 = 6, + kDraft07 = 7, + kDraft2019_09 = 8, + kDraft2020_12 = 9 +}; + +enum OpenApiVersion { + kVersionUnknown = -1, + kVersionNone = 0, + kVersionMin = 2, //!< Current minimum supported version + kVersion20 = 2, + kVersion30 = 3, + kVersionMax = 3, //!< Current maximum supported version + kVersion31 = 4, +}; + +struct Specification { + Specification(SchemaDraft d) : draft(d), oapi(kVersionNone) {} + Specification(OpenApiVersion o) : oapi(o) { + if (oapi == kVersion20) draft = kDraft04; + else if (oapi == kVersion30) draft = kDraft05; + else if (oapi == kVersion31) draft = kDraft2020_12; + else draft = kDraft04; + } + ~Specification() {} + bool IsSupported() const { + return ((draft >= kDraftMin && draft <= kDraftMax) && ((oapi == kVersionNone) || (oapi >= kVersionMin && oapi <= kVersionMax))); + } + SchemaDraft draft; + OpenApiVersion oapi; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Forward declarations + +template +class GenericSchemaDocument; + +namespace internal { + +template +class Schema; + +/////////////////////////////////////////////////////////////////////////////// +// ISchemaValidator + +class ISchemaValidator { +public: + virtual ~ISchemaValidator() {} + virtual bool IsValid() const = 0; + virtual void SetValidateFlags(unsigned flags) = 0; + virtual unsigned GetValidateFlags() const = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// ISchemaStateFactory + +template +class ISchemaStateFactory { +public: + virtual ~ISchemaStateFactory() {} + virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&, const bool inheritContinueOnErrors) = 0; + virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0; + virtual void* CreateHasher() = 0; + virtual uint64_t GetHashCode(void* hasher) = 0; + virtual void DestroyHasher(void* hasher) = 0; + virtual void* MallocState(size_t size) = 0; + virtual void FreeState(void* p) = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// IValidationErrorHandler + +template +class IValidationErrorHandler { +public: + typedef typename SchemaType::Ch Ch; + typedef typename SchemaType::SValue SValue; + + virtual ~IValidationErrorHandler() {} + + virtual void NotMultipleOf(int64_t actual, const SValue& expected) = 0; + virtual void NotMultipleOf(uint64_t actual, const SValue& expected) = 0; + virtual void NotMultipleOf(double actual, const SValue& expected) = 0; + virtual void AboveMaximum(int64_t actual, const SValue& expected, bool exclusive) = 0; + virtual void AboveMaximum(uint64_t actual, const SValue& expected, bool exclusive) = 0; + virtual void AboveMaximum(double actual, const SValue& expected, bool exclusive) = 0; + virtual void BelowMinimum(int64_t actual, const SValue& expected, bool exclusive) = 0; + virtual void BelowMinimum(uint64_t actual, const SValue& expected, bool exclusive) = 0; + virtual void BelowMinimum(double actual, const SValue& expected, bool exclusive) = 0; + + virtual void TooLong(const Ch* str, SizeType length, SizeType expected) = 0; + virtual void TooShort(const Ch* str, SizeType length, SizeType expected) = 0; + virtual void DoesNotMatch(const Ch* str, SizeType length) = 0; + + virtual void DisallowedItem(SizeType index) = 0; + virtual void TooFewItems(SizeType actualCount, SizeType expectedCount) = 0; + virtual void TooManyItems(SizeType actualCount, SizeType expectedCount) = 0; + virtual void DuplicateItems(SizeType index1, SizeType index2) = 0; + + virtual void TooManyProperties(SizeType actualCount, SizeType expectedCount) = 0; + virtual void TooFewProperties(SizeType actualCount, SizeType expectedCount) = 0; + virtual void StartMissingProperties() = 0; + virtual void AddMissingProperty(const SValue& name) = 0; + virtual bool EndMissingProperties() = 0; + virtual void PropertyViolations(ISchemaValidator** subvalidators, SizeType count) = 0; + virtual void DisallowedProperty(const Ch* name, SizeType length) = 0; + + virtual void StartDependencyErrors() = 0; + virtual void StartMissingDependentProperties() = 0; + virtual void AddMissingDependentProperty(const SValue& targetName) = 0; + virtual void EndMissingDependentProperties(const SValue& sourceName) = 0; + virtual void AddDependencySchemaError(const SValue& sourceName, ISchemaValidator* subvalidator) = 0; + virtual bool EndDependencyErrors() = 0; + + virtual void DisallowedValue(const ValidateErrorCode code) = 0; + virtual void StartDisallowedType() = 0; + virtual void AddExpectedType(const typename SchemaType::ValueType& expectedType) = 0; + virtual void EndDisallowedType(const typename SchemaType::ValueType& actualType) = 0; + virtual void NotAllOf(ISchemaValidator** subvalidators, SizeType count) = 0; + virtual void NoneOf(ISchemaValidator** subvalidators, SizeType count) = 0; + virtual void NotOneOf(ISchemaValidator** subvalidators, SizeType count) = 0; + virtual void MultipleOneOf(SizeType index1, SizeType index2) = 0; + virtual void Disallowed() = 0; + virtual void DisallowedWhenWriting() = 0; + virtual void DisallowedWhenReading() = 0; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Hasher + +// For comparison of compound value +template +class Hasher { +public: + typedef typename Encoding::Ch Ch; + + Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {} + + bool Null() { return WriteType(kNullType); } + bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); } + bool Int(int i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } + bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } + bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } + bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } + bool Double(double d) { + Number n; + if (d < 0) n.u.i = static_cast(d); + else n.u.u = static_cast(d); + n.d = d; + return WriteNumber(n); + } + + bool RawNumber(const Ch* str, SizeType len, bool) { + WriteBuffer(kNumberType, str, len * sizeof(Ch)); + return true; + } + + bool String(const Ch* str, SizeType len, bool) { + WriteBuffer(kStringType, str, len * sizeof(Ch)); + return true; + } + + bool StartObject() { return true; } + bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); } + bool EndObject(SizeType memberCount) { + uint64_t h = Hash(0, kObjectType); + uint64_t* kv = stack_.template Pop(memberCount * 2); + for (SizeType i = 0; i < memberCount; i++) + h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive + *stack_.template Push() = h; + return true; + } + + bool StartArray() { return true; } + bool EndArray(SizeType elementCount) { + uint64_t h = Hash(0, kArrayType); + uint64_t* e = stack_.template Pop(elementCount); + for (SizeType i = 0; i < elementCount; i++) + h = Hash(h, e[i]); // Use hash to achieve element order sensitive + *stack_.template Push() = h; + return true; + } + + bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); } + + uint64_t GetHashCode() const { + RAPIDJSON_ASSERT(IsValid()); + return *stack_.template Top(); + } + +private: + static const size_t kDefaultSize = 256; + struct Number { + union U { + uint64_t u; + int64_t i; + }u; + double d; + }; + + bool WriteType(Type type) { return WriteBuffer(type, 0, 0); } + + bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); } + + bool WriteBuffer(Type type, const void* data, size_t len) { + // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/ + uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type); + const unsigned char* d = static_cast(data); + for (size_t i = 0; i < len; i++) + h = Hash(h, d[i]); + *stack_.template Push() = h; + return true; + } + + static uint64_t Hash(uint64_t h, uint64_t d) { + static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3); + h ^= d; + h *= kPrime; + return h; + } + + Stack stack_; +}; + +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidationContext + +template +struct SchemaValidationContext { + typedef Schema SchemaType; + typedef ISchemaStateFactory SchemaValidatorFactoryType; + typedef IValidationErrorHandler ErrorHandlerType; + typedef typename SchemaType::ValueType ValueType; + typedef typename ValueType::Ch Ch; + + enum PatternValidatorType { + kPatternValidatorOnly, + kPatternValidatorWithProperty, + kPatternValidatorWithAdditionalProperty + }; + + SchemaValidationContext(SchemaValidatorFactoryType& f, ErrorHandlerType& eh, const SchemaType* s, unsigned fl = 0) : + factory(f), + error_handler(eh), + schema(s), + flags(fl), + valueSchema(), + invalidKeyword(), + invalidCode(), + hasher(), + arrayElementHashCodes(), + validators(), + validatorCount(), + patternPropertiesValidators(), + patternPropertiesValidatorCount(), + patternPropertiesSchemas(), + patternPropertiesSchemaCount(), + valuePatternValidatorType(kPatternValidatorOnly), + propertyExist(), + inArray(false), + valueUniqueness(false), + arrayUniqueness(false) + { + } + + ~SchemaValidationContext() { + if (hasher) + factory.DestroyHasher(hasher); + if (validators) { + for (SizeType i = 0; i < validatorCount; i++) { + if (validators[i]) { + factory.DestroySchemaValidator(validators[i]); + } + } + factory.FreeState(validators); + } + if (patternPropertiesValidators) { + for (SizeType i = 0; i < patternPropertiesValidatorCount; i++) { + if (patternPropertiesValidators[i]) { + factory.DestroySchemaValidator(patternPropertiesValidators[i]); + } + } + factory.FreeState(patternPropertiesValidators); + } + if (patternPropertiesSchemas) + factory.FreeState(patternPropertiesSchemas); + if (propertyExist) + factory.FreeState(propertyExist); + } + + SchemaValidatorFactoryType& factory; + ErrorHandlerType& error_handler; + const SchemaType* schema; + unsigned flags; + const SchemaType* valueSchema; + const Ch* invalidKeyword; + ValidateErrorCode invalidCode; + void* hasher; // Only validator access + void* arrayElementHashCodes; // Only validator access this + ISchemaValidator** validators; + SizeType validatorCount; + ISchemaValidator** patternPropertiesValidators; + SizeType patternPropertiesValidatorCount; + const SchemaType** patternPropertiesSchemas; + SizeType patternPropertiesSchemaCount; + PatternValidatorType valuePatternValidatorType; + PatternValidatorType objectPatternValidatorType; + SizeType arrayElementIndex; + bool* propertyExist; + bool inArray; + bool valueUniqueness; + bool arrayUniqueness; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Schema + +template +class Schema { +public: + typedef typename SchemaDocumentType::ValueType ValueType; + typedef typename SchemaDocumentType::AllocatorType AllocatorType; + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + typedef SchemaValidationContext Context; + typedef Schema SchemaType; + typedef GenericValue SValue; + typedef IValidationErrorHandler ErrorHandler; + typedef GenericUri UriType; + friend class GenericSchemaDocument; + + Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator, const UriType& id = UriType()) : + allocator_(allocator), + uri_(schemaDocument->GetURI(), *allocator), + id_(id, allocator), + spec_(schemaDocument->GetSpecification()), + pointer_(p, allocator), + typeless_(schemaDocument->GetTypeless()), + enum_(), + enumCount_(), + not_(), + type_((1 << kTotalSchemaType) - 1), // typeless + validatorCount_(), + notValidatorIndex_(), + properties_(), + additionalPropertiesSchema_(), + patternProperties_(), + patternPropertyCount_(), + propertyCount_(), + minProperties_(), + maxProperties_(SizeType(~0)), + additionalProperties_(true), + hasDependencies_(), + hasRequired_(), + hasSchemaDependencies_(), + additionalItemsSchema_(), + itemsList_(), + itemsTuple_(), + itemsTupleCount_(), + minItems_(), + maxItems_(SizeType(~0)), + additionalItems_(true), + uniqueItems_(false), + pattern_(), + minLength_(0), + maxLength_(~SizeType(0)), + exclusiveMinimum_(false), + exclusiveMaximum_(false), + defaultValueLength_(0), + readOnly_(false), + writeOnly_(false), + nullable_(false) + { + GenericStringBuffer sb; + p.StringifyUriFragment(sb); + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Schema", sb.GetString(), id.GetString()); + + typedef typename ValueType::ConstValueIterator ConstValueIterator; + typedef typename ValueType::ConstMemberIterator ConstMemberIterator; + + // PR #1393 + // Early add this Schema and its $ref(s) in schemaDocument's map to avoid infinite + // recursion (with recursive schemas), since schemaDocument->getSchema() is always + // checked before creating a new one. Don't cache typeless_, though. + if (this != typeless_) { + typedef typename SchemaDocumentType::SchemaEntry SchemaEntry; + SchemaEntry *entry = schemaDocument->schemaMap_.template Push(); + new (entry) SchemaEntry(pointer_, this, true, allocator_); + schemaDocument->AddSchemaRefs(this); + } + + if (!value.IsObject()) + return; + + // If we have an id property, resolve it with the in-scope id + // Not supported for open api 2.0 or 3.0 + if (spec_.oapi != kVersion20 && spec_.oapi != kVersion30) + if (const ValueType* v = GetMember(value, GetIdString())) { + if (v->IsString()) { + UriType local(*v, allocator); + id_ = local.Resolve(id_, allocator); + RAPIDJSON_SCHEMA_PRINT(SchemaIds, id.GetString(), v->GetString(), id_.GetString()); + } + } + + if (const ValueType* v = GetMember(value, GetTypeString())) { + type_ = 0; + if (v->IsString()) + AddType(*v); + else if (v->IsArray()) + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) + AddType(*itr); + } + + if (const ValueType* v = GetMember(value, GetEnumString())) { + if (v->IsArray() && v->Size() > 0) { + enum_ = static_cast(allocator_->Malloc(sizeof(uint64_t) * v->Size())); + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) { + typedef Hasher > EnumHasherType; + char buffer[256u + 24]; + MemoryPoolAllocator hasherAllocator(buffer, sizeof(buffer)); + EnumHasherType h(&hasherAllocator, 256); + itr->Accept(h); + enum_[enumCount_++] = h.GetHashCode(); + } + } + } + + if (schemaDocument) + AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document); + + // AnyOf, OneOf, Not not supported for open api 2.0 + if (schemaDocument && spec_.oapi != kVersion20) { + AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document); + AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document); + + if (const ValueType* v = GetMember(value, GetNotString())) { + schemaDocument->CreateSchema(¬_, p.Append(GetNotString(), allocator_), *v, document, id_); + notValidatorIndex_ = validatorCount_; + validatorCount_++; + } + } + + // Object + + const ValueType* properties = GetMember(value, GetPropertiesString()); + const ValueType* required = GetMember(value, GetRequiredString()); + const ValueType* dependencies = GetMember(value, GetDependenciesString()); + { + // Gather properties from properties/required/dependencies + SValue allProperties(kArrayType); + + if (properties && properties->IsObject()) + for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) + AddUniqueElement(allProperties, itr->name); + + if (required && required->IsArray()) + for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) + if (itr->IsString()) + AddUniqueElement(allProperties, *itr); + + // Dependencies not supported for open api 2.0 and 3.0 + if (spec_.oapi != kVersion20 && spec_.oapi != kVersion30) + if (dependencies && dependencies->IsObject()) + for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { + AddUniqueElement(allProperties, itr->name); + if (itr->value.IsArray()) + for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i) + if (i->IsString()) + AddUniqueElement(allProperties, *i); + } + + if (allProperties.Size() > 0) { + propertyCount_ = allProperties.Size(); + properties_ = static_cast(allocator_->Malloc(sizeof(Property) * propertyCount_)); + for (SizeType i = 0; i < propertyCount_; i++) { + new (&properties_[i]) Property(); + properties_[i].name = allProperties[i]; + properties_[i].schema = typeless_; + } + } + } + + if (properties && properties->IsObject()) { + PointerType q = p.Append(GetPropertiesString(), allocator_); + for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) { + SizeType index; + if (FindPropertyIndex(itr->name, &index)) + schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document, id_); + } + } + + // PatternProperties not supported for open api 2.0 and 3.0 + if (spec_.oapi != kVersion20 && spec_.oapi != kVersion30) + if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) { + PointerType q = p.Append(GetPatternPropertiesString(), allocator_); + patternProperties_ = static_cast(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount())); + patternPropertyCount_ = 0; + + for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) { + new (&patternProperties_[patternPropertyCount_]) PatternProperty(); + PointerType r = q.Append(itr->name, allocator_); + patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name, schemaDocument, r); + schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, r, itr->value, document, id_); + patternPropertyCount_++; + } + } + + if (required && required->IsArray()) + for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) + if (itr->IsString()) { + SizeType index; + if (FindPropertyIndex(*itr, &index)) { + properties_[index].required = true; + hasRequired_ = true; + } + } + + // Dependencies not supported for open api 2.0 and 3.0 + if (spec_.oapi != kVersion20 && spec_.oapi != kVersion30) + if (dependencies && dependencies->IsObject()) { + PointerType q = p.Append(GetDependenciesString(), allocator_); + hasDependencies_ = true; + for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { + SizeType sourceIndex; + if (FindPropertyIndex(itr->name, &sourceIndex)) { + if (itr->value.IsArray()) { + properties_[sourceIndex].dependencies = static_cast(allocator_->Malloc(sizeof(bool) * propertyCount_)); + std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_); + for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) { + SizeType targetIndex; + if (FindPropertyIndex(*targetItr, &targetIndex)) + properties_[sourceIndex].dependencies[targetIndex] = true; + } + } + else if (itr->value.IsObject()) { + hasSchemaDependencies_ = true; + schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document, id_); + properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_; + validatorCount_++; + } + } + } + } + + if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) { + if (v->IsBool()) + additionalProperties_ = v->GetBool(); + else if (v->IsObject()) + schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document, id_); + } + + AssignIfExist(minProperties_, value, GetMinPropertiesString()); + AssignIfExist(maxProperties_, value, GetMaxPropertiesString()); + + // Array + if (const ValueType* v = GetMember(value, GetItemsString())) { + PointerType q = p.Append(GetItemsString(), allocator_); + if (v->IsObject()) // List validation + schemaDocument->CreateSchema(&itemsList_, q, *v, document, id_); + else if (v->IsArray()) { // Tuple validation + itemsTuple_ = static_cast(allocator_->Malloc(sizeof(const Schema*) * v->Size())); + SizeType index = 0; + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++) + schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document, id_); + } + } + + AssignIfExist(minItems_, value, GetMinItemsString()); + AssignIfExist(maxItems_, value, GetMaxItemsString()); + + // AdditionalItems not supported for openapi 2.0 and 3.0 + if (spec_.oapi != kVersion20 && spec_.oapi != kVersion30) + if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) { + if (v->IsBool()) + additionalItems_ = v->GetBool(); + else if (v->IsObject()) + schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document, id_); + } + + AssignIfExist(uniqueItems_, value, GetUniqueItemsString()); + + // String + AssignIfExist(minLength_, value, GetMinLengthString()); + AssignIfExist(maxLength_, value, GetMaxLengthString()); + + if (const ValueType* v = GetMember(value, GetPatternString())) + pattern_ = CreatePattern(*v, schemaDocument, p.Append(GetPatternString(), allocator_)); + + // Number + if (const ValueType* v = GetMember(value, GetMinimumString())) + if (v->IsNumber()) + minimum_.CopyFrom(*v, *allocator_); + + if (const ValueType* v = GetMember(value, GetMaximumString())) + if (v->IsNumber()) + maximum_.CopyFrom(*v, *allocator_); + + AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString()); + AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString()); + + if (const ValueType* v = GetMember(value, GetMultipleOfString())) + if (v->IsNumber() && v->GetDouble() > 0.0) + multipleOf_.CopyFrom(*v, *allocator_); + + // Default + if (const ValueType* v = GetMember(value, GetDefaultValueString())) + if (v->IsString()) + defaultValueLength_ = v->GetStringLength(); + + // ReadOnly - open api only (until draft 7 supported) + // WriteOnly - open api 3 only (until draft 7 supported) + // Both can't be true + if (spec_.oapi != kVersionNone) + AssignIfExist(readOnly_, value, GetReadOnlyString()); + if (spec_.oapi >= kVersion30) + AssignIfExist(writeOnly_, value, GetWriteOnlyString()); + if (readOnly_ && writeOnly_) + schemaDocument->SchemaError(kSchemaErrorReadOnlyAndWriteOnly, p); + + // Nullable - open api 3 only + // If true add 'null' as allowable type + if (spec_.oapi >= kVersion30) { + AssignIfExist(nullable_, value, GetNullableString()); + if (nullable_) + AddType(GetNullString()); + } + } + + ~Schema() { + AllocatorType::Free(enum_); + if (properties_) { + for (SizeType i = 0; i < propertyCount_; i++) + properties_[i].~Property(); + AllocatorType::Free(properties_); + } + if (patternProperties_) { + for (SizeType i = 0; i < patternPropertyCount_; i++) + patternProperties_[i].~PatternProperty(); + AllocatorType::Free(patternProperties_); + } + AllocatorType::Free(itemsTuple_); +#if RAPIDJSON_SCHEMA_HAS_REGEX + if (pattern_) { + pattern_->~RegexType(); + AllocatorType::Free(pattern_); + } +#endif + } + + const SValue& GetURI() const { + return uri_; + } + + const UriType& GetId() const { + return id_; + } + + const Specification& GetSpecification() const { + return spec_; + } + + const PointerType& GetPointer() const { + return pointer_; + } + + bool BeginValue(Context& context) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::BeginValue"); + if (context.inArray) { + if (uniqueItems_) + context.valueUniqueness = true; + + if (itemsList_) + context.valueSchema = itemsList_; + else if (itemsTuple_) { + if (context.arrayElementIndex < itemsTupleCount_) + context.valueSchema = itemsTuple_[context.arrayElementIndex]; + else if (additionalItemsSchema_) + context.valueSchema = additionalItemsSchema_; + else if (additionalItems_) + context.valueSchema = typeless_; + else { + context.error_handler.DisallowedItem(context.arrayElementIndex); + // Must set valueSchema for when kValidateContinueOnErrorFlag is set, else reports spurious type error + context.valueSchema = typeless_; + // Must bump arrayElementIndex for when kValidateContinueOnErrorFlag is set + context.arrayElementIndex++; + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAdditionalItems); + } + } + else + context.valueSchema = typeless_; + + context.arrayElementIndex++; + } + return true; + } + + RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::EndValue"); + // Only check pattern properties if we have validators + if (context.patternPropertiesValidatorCount > 0) { + bool otherValid = false; + SizeType count = context.patternPropertiesValidatorCount; + if (context.objectPatternValidatorType != Context::kPatternValidatorOnly) + otherValid = context.patternPropertiesValidators[--count]->IsValid(); + + bool patternValid = true; + for (SizeType i = 0; i < count; i++) + if (!context.patternPropertiesValidators[i]->IsValid()) { + patternValid = false; + break; + } + + if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) { + if (!patternValid) { + context.error_handler.PropertyViolations(context.patternPropertiesValidators, count); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPatternProperties); + } + } + else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) { + if (!patternValid || !otherValid) { + context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPatternProperties); + } + } + else if (!patternValid && !otherValid) { // kPatternValidatorWithAdditionalProperty) + context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPatternProperties); + } + } + + // For enums only check if we have a hasher + if (enum_ && context.hasher) { + const uint64_t h = context.factory.GetHashCode(context.hasher); + for (SizeType i = 0; i < enumCount_; i++) + if (enum_[i] == h) + goto foundEnum; + context.error_handler.DisallowedValue(kValidateErrorEnum); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorEnum); + foundEnum:; + } + + // Only check allOf etc if we have validators + if (context.validatorCount > 0) { + if (allOf_.schemas) + for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++) + if (!context.validators[i]->IsValid()) { + context.error_handler.NotAllOf(&context.validators[allOf_.begin], allOf_.count); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAllOf); + } + + if (anyOf_.schemas) { + for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++) + if (context.validators[i]->IsValid()) + goto foundAny; + context.error_handler.NoneOf(&context.validators[anyOf_.begin], anyOf_.count); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAnyOf); + foundAny:; + } + + if (oneOf_.schemas) { + bool oneValid = false; + SizeType firstMatch = 0; + for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++) + if (context.validators[i]->IsValid()) { + if (oneValid) { + context.error_handler.MultipleOneOf(firstMatch, i - oneOf_.begin); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorOneOfMatch); + } else { + oneValid = true; + firstMatch = i - oneOf_.begin; + } + } + if (!oneValid) { + context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorOneOf); + } + } + + if (not_ && context.validators[notValidatorIndex_]->IsValid()) { + context.error_handler.Disallowed(); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorNot); + } + } + + return true; + } + + bool Null(Context& context) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Null"); + if (!(type_ & (1 << kNullSchemaType))) { + DisallowedType(context, GetNullString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + return CreateParallelValidator(context); + } + + bool Bool(Context& context, bool b) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Bool", b); + if (!CheckBool(context, b)) + return false; + return CreateParallelValidator(context); + } + + bool Int(Context& context, int i) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Int", (int64_t)i); + if (!CheckInt(context, i)) + return false; + return CreateParallelValidator(context); + } + + bool Uint(Context& context, unsigned u) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Uint", (uint64_t)u); + if (!CheckUint(context, u)) + return false; + return CreateParallelValidator(context); + } + + bool Int64(Context& context, int64_t i) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Int64", i); + if (!CheckInt(context, i)) + return false; + return CreateParallelValidator(context); + } + + bool Uint64(Context& context, uint64_t u) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Uint64", u); + if (!CheckUint(context, u)) + return false; + return CreateParallelValidator(context); + } + + bool Double(Context& context, double d) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Double", d); + if (!(type_ & (1 << kNumberSchemaType))) { + DisallowedType(context, GetNumberString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d)) + return false; + + if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d)) + return false; + + if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d)) + return false; + + return CreateParallelValidator(context); + } + + bool String(Context& context, const Ch* str, SizeType length, bool) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::String", str); + if (!(type_ & (1 << kStringSchemaType))) { + DisallowedType(context, GetStringString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + if (minLength_ != 0 || maxLength_ != SizeType(~0)) { + SizeType count; + if (internal::CountStringCodePoint(str, length, &count)) { + if (count < minLength_) { + context.error_handler.TooShort(str, length, minLength_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinLength); + } + if (count > maxLength_) { + context.error_handler.TooLong(str, length, maxLength_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxLength); + } + } + } + + if (pattern_ && !IsPatternMatch(pattern_, str, length)) { + context.error_handler.DoesNotMatch(str, length); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPattern); + } + + return CreateParallelValidator(context); + } + + bool StartObject(Context& context) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::StartObject"); + if (!(type_ & (1 << kObjectSchemaType))) { + DisallowedType(context, GetObjectString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + if (hasDependencies_ || hasRequired_) { + context.propertyExist = static_cast(context.factory.MallocState(sizeof(bool) * propertyCount_)); + std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_); + } + + if (patternProperties_) { // pre-allocate schema array + SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType + context.patternPropertiesSchemas = static_cast(context.factory.MallocState(sizeof(const SchemaType*) * count)); + context.patternPropertiesSchemaCount = 0; + std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count); + } + + return CreateParallelValidator(context); + } + + bool Key(Context& context, const Ch* str, SizeType len, bool) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Key", str); + + if (patternProperties_) { + context.patternPropertiesSchemaCount = 0; + for (SizeType i = 0; i < patternPropertyCount_; i++) + if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema; + context.valueSchema = typeless_; + } + } + + SizeType index = 0; + if (FindPropertyIndex(ValueType(str, len).Move(), &index)) { + if (context.patternPropertiesSchemaCount > 0) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema; + context.valueSchema = typeless_; + context.valuePatternValidatorType = Context::kPatternValidatorWithProperty; + } + else + context.valueSchema = properties_[index].schema; + + if (context.propertyExist) + context.propertyExist[index] = true; + + return true; + } + + if (additionalPropertiesSchema_) { + if (context.patternPropertiesSchemaCount > 0) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_; + context.valueSchema = typeless_; + context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty; + } + else + context.valueSchema = additionalPropertiesSchema_; + return true; + } + else if (additionalProperties_) { + context.valueSchema = typeless_; + return true; + } + + if (context.patternPropertiesSchemaCount == 0) { // patternProperties are not additional properties + // Must set valueSchema for when kValidateContinueOnErrorFlag is set, else reports spurious type error + context.valueSchema = typeless_; + context.error_handler.DisallowedProperty(str, len); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAdditionalProperties); + } + + return true; + } + + bool EndObject(Context& context, SizeType memberCount) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::EndObject"); + if (hasRequired_) { + context.error_handler.StartMissingProperties(); + for (SizeType index = 0; index < propertyCount_; index++) + if (properties_[index].required && !context.propertyExist[index]) + if (properties_[index].schema->defaultValueLength_ == 0 ) + context.error_handler.AddMissingProperty(properties_[index].name); + if (context.error_handler.EndMissingProperties()) + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorRequired); + } + + if (memberCount < minProperties_) { + context.error_handler.TooFewProperties(memberCount, minProperties_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinProperties); + } + + if (memberCount > maxProperties_) { + context.error_handler.TooManyProperties(memberCount, maxProperties_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxProperties); + } + + if (hasDependencies_) { + context.error_handler.StartDependencyErrors(); + for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) { + const Property& source = properties_[sourceIndex]; + if (context.propertyExist[sourceIndex]) { + if (source.dependencies) { + context.error_handler.StartMissingDependentProperties(); + for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++) + if (source.dependencies[targetIndex] && !context.propertyExist[targetIndex]) + context.error_handler.AddMissingDependentProperty(properties_[targetIndex].name); + context.error_handler.EndMissingDependentProperties(source.name); + } + else if (source.dependenciesSchema) { + ISchemaValidator* dependenciesValidator = context.validators[source.dependenciesValidatorIndex]; + if (!dependenciesValidator->IsValid()) + context.error_handler.AddDependencySchemaError(source.name, dependenciesValidator); + } + } + } + if (context.error_handler.EndDependencyErrors()) + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorDependencies); + } + + return true; + } + + bool StartArray(Context& context) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::StartArray"); + context.arrayElementIndex = 0; + context.inArray = true; // Ensure we note that we are in an array + + if (!(type_ & (1 << kArraySchemaType))) { + DisallowedType(context, GetArrayString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + return CreateParallelValidator(context); + } + + bool EndArray(Context& context, SizeType elementCount) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::EndArray"); + context.inArray = false; + + if (elementCount < minItems_) { + context.error_handler.TooFewItems(elementCount, minItems_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinItems); + } + + if (elementCount > maxItems_) { + context.error_handler.TooManyItems(elementCount, maxItems_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxItems); + } + + return true; + } + + static const ValueType& GetValidateErrorKeyword(ValidateErrorCode validateErrorCode) { + switch (validateErrorCode) { + case kValidateErrorMultipleOf: return GetMultipleOfString(); + case kValidateErrorMaximum: return GetMaximumString(); + case kValidateErrorExclusiveMaximum: return GetMaximumString(); // Same + case kValidateErrorMinimum: return GetMinimumString(); + case kValidateErrorExclusiveMinimum: return GetMinimumString(); // Same + + case kValidateErrorMaxLength: return GetMaxLengthString(); + case kValidateErrorMinLength: return GetMinLengthString(); + case kValidateErrorPattern: return GetPatternString(); + + case kValidateErrorMaxItems: return GetMaxItemsString(); + case kValidateErrorMinItems: return GetMinItemsString(); + case kValidateErrorUniqueItems: return GetUniqueItemsString(); + case kValidateErrorAdditionalItems: return GetAdditionalItemsString(); + + case kValidateErrorMaxProperties: return GetMaxPropertiesString(); + case kValidateErrorMinProperties: return GetMinPropertiesString(); + case kValidateErrorRequired: return GetRequiredString(); + case kValidateErrorAdditionalProperties: return GetAdditionalPropertiesString(); + case kValidateErrorPatternProperties: return GetPatternPropertiesString(); + case kValidateErrorDependencies: return GetDependenciesString(); + + case kValidateErrorEnum: return GetEnumString(); + case kValidateErrorType: return GetTypeString(); + + case kValidateErrorOneOf: return GetOneOfString(); + case kValidateErrorOneOfMatch: return GetOneOfString(); // Same + case kValidateErrorAllOf: return GetAllOfString(); + case kValidateErrorAnyOf: return GetAnyOfString(); + case kValidateErrorNot: return GetNotString(); + + case kValidateErrorReadOnly: return GetReadOnlyString(); + case kValidateErrorWriteOnly: return GetWriteOnlyString(); + + default: return GetNullString(); + } + } + + + // Generate functions for string literal according to Ch +#define RAPIDJSON_STRING_(name, ...) \ + static const ValueType& Get##name##String() {\ + static const Ch s[] = { __VA_ARGS__, '\0' };\ + static const ValueType v(s, static_cast(sizeof(s) / sizeof(Ch) - 1));\ + return v;\ + } + + RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l') + RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n') + RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't') + RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y') + RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g') + RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r') + RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r') + RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e') + RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm') + RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f') + RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f') + RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f') + RAPIDJSON_STRING_(Not, 'n', 'o', 't') + RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd') + RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's') + RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h') + RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h') + RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n') + RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f') + RAPIDJSON_STRING_(DefaultValue, 'd', 'e', 'f', 'a', 'u', 'l', 't') + RAPIDJSON_STRING_(Schema, '$', 's', 'c', 'h', 'e', 'm', 'a') + RAPIDJSON_STRING_(Ref, '$', 'r', 'e', 'f') + RAPIDJSON_STRING_(Id, 'i', 'd') + RAPIDJSON_STRING_(Swagger, 's', 'w', 'a', 'g', 'g', 'e', 'r') + RAPIDJSON_STRING_(OpenApi, 'o', 'p', 'e', 'n', 'a', 'p', 'i') + RAPIDJSON_STRING_(ReadOnly, 'r', 'e', 'a', 'd', 'O', 'n', 'l', 'y') + RAPIDJSON_STRING_(WriteOnly, 'w', 'r', 'i', 't', 'e', 'O', 'n', 'l', 'y') + RAPIDJSON_STRING_(Nullable, 'n', 'u', 'l', 'l', 'a', 'b', 'l', 'e') + +#undef RAPIDJSON_STRING_ + +private: + enum SchemaValueType { + kNullSchemaType, + kBooleanSchemaType, + kObjectSchemaType, + kArraySchemaType, + kStringSchemaType, + kNumberSchemaType, + kIntegerSchemaType, + kTotalSchemaType + }; + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX + typedef internal::GenericRegex RegexType; +#elif RAPIDJSON_SCHEMA_USE_STDREGEX + typedef std::basic_regex RegexType; +#else + typedef char RegexType; +#endif + + struct SchemaArray { + SchemaArray() : schemas(), count() {} + ~SchemaArray() { AllocatorType::Free(schemas); } + const SchemaType** schemas; + SizeType begin; // begin index of context.validators + SizeType count; + }; + + template + void AddUniqueElement(V1& a, const V2& v) { + for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) + if (*itr == v) + return; + V1 c(v, *allocator_); + a.PushBack(c, *allocator_); + } + + static const ValueType* GetMember(const ValueType& value, const ValueType& name) { + typename ValueType::ConstMemberIterator itr = value.FindMember(name); + return itr != value.MemberEnd() ? &(itr->value) : 0; + } + + static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) { + if (const ValueType* v = GetMember(value, name)) + if (v->IsBool()) + out = v->GetBool(); + } + + static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) { + if (const ValueType* v = GetMember(value, name)) + if (v->IsUint64() && v->GetUint64() <= SizeType(~0)) + out = static_cast(v->GetUint64()); + } + + void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) { + if (const ValueType* v = GetMember(value, name)) { + if (v->IsArray() && v->Size() > 0) { + PointerType q = p.Append(name, allocator_); + out.count = v->Size(); + out.schemas = static_cast(allocator_->Malloc(out.count * sizeof(const Schema*))); + memset(out.schemas, 0, sizeof(Schema*)* out.count); + for (SizeType i = 0; i < out.count; i++) + schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document, id_); + out.begin = validatorCount_; + validatorCount_ += out.count; + } + } + } + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX + template + RegexType* CreatePattern(const ValueType& value, SchemaDocumentType* sd, const PointerType& p) { + if (value.IsString()) { + RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), allocator_); + if (!r->IsValid()) { + sd->SchemaErrorValue(kSchemaErrorRegexInvalid, p, value.GetString(), value.GetStringLength()); + r->~RegexType(); + AllocatorType::Free(r); + r = 0; + } + return r; + } + return 0; + } + + static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) { + GenericRegexSearch rs(*pattern); + return rs.Search(str); + } +#elif RAPIDJSON_SCHEMA_USE_STDREGEX + template + RegexType* CreatePattern(const ValueType& value, SchemaDocumentType* sd, const PointerType& p) { + if (value.IsString()) { + RegexType *r = static_cast(allocator_->Malloc(sizeof(RegexType))); + try { + return new (r) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript); + } + catch (const std::regex_error& e) { + sd->SchemaErrorValue(kSchemaErrorRegexInvalid, p, value.GetString(), value.GetStringLength()); + AllocatorType::Free(r); + } + } + return 0; + } + + static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) { + std::match_results r; + return std::regex_search(str, str + length, r, *pattern); + } +#else + template + RegexType* CreatePattern(const ValueType&) { + return 0; + } + + static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; } +#endif // RAPIDJSON_SCHEMA_USE_STDREGEX + + void AddType(const ValueType& type) { + if (type == GetNullString() ) type_ |= 1 << kNullSchemaType; + else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType; + else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType; + else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType; + else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType; + else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType; + else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType); + } + + // Creates parallel validators for allOf, anyOf, oneOf, not and schema dependencies, if required. + // Also creates a hasher for enums and array uniqueness, if required. + // Also a useful place to add type-independent error checks. + bool CreateParallelValidator(Context& context) const { + if (enum_ || context.arrayUniqueness) + context.hasher = context.factory.CreateHasher(); + + if (validatorCount_) { + RAPIDJSON_ASSERT(context.validators == 0); + context.validators = static_cast(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_)); + std::memset(context.validators, 0, sizeof(ISchemaValidator*) * validatorCount_); + context.validatorCount = validatorCount_; + + // Always return after first failure for these sub-validators + if (allOf_.schemas) + CreateSchemaValidators(context, allOf_, false); + + if (anyOf_.schemas) + CreateSchemaValidators(context, anyOf_, false); + + if (oneOf_.schemas) + CreateSchemaValidators(context, oneOf_, false); + + if (not_) + context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_, false); + + if (hasSchemaDependencies_) { + for (SizeType i = 0; i < propertyCount_; i++) + if (properties_[i].dependenciesSchema) + context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema, false); + } + } + + // Add any other type-independent checks here + if (readOnly_ && (context.flags & kValidateWriteFlag)) { + context.error_handler.DisallowedWhenWriting(); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorReadOnly); + } + if (writeOnly_ && (context.flags & kValidateReadFlag)) { + context.error_handler.DisallowedWhenReading(); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorWriteOnly); + } + + return true; + } + + void CreateSchemaValidators(Context& context, const SchemaArray& schemas, const bool inheritContinueOnErrors) const { + for (SizeType i = 0; i < schemas.count; i++) + context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i], inheritContinueOnErrors); + } + + // O(n) + bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const { + SizeType len = name.GetStringLength(); + const Ch* str = name.GetString(); + for (SizeType index = 0; index < propertyCount_; index++) + if (properties_[index].name.GetStringLength() == len && + (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0)) + { + *outIndex = index; + return true; + } + return false; + } + + bool CheckBool(Context& context, bool) const { + if (!(type_ & (1 << kBooleanSchemaType))) { + DisallowedType(context, GetBooleanString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + return true; + } + + bool CheckInt(Context& context, int64_t i) const { + if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) { + DisallowedType(context, GetIntegerString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + if (!minimum_.IsNull()) { + if (minimum_.IsInt64()) { + if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) { + context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum); + } + } + else if (minimum_.IsUint64()) { + context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum); // i <= max(int64_t) < minimum.GetUint64() + } + else if (!CheckDoubleMinimum(context, static_cast(i))) + return false; + } + + if (!maximum_.IsNull()) { + if (maximum_.IsInt64()) { + if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) { + context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum); + } + } + else if (maximum_.IsUint64()) { } + /* do nothing */ // i <= max(int64_t) < maximum_.GetUint64() + else if (!CheckDoubleMaximum(context, static_cast(i))) + return false; + } + + if (!multipleOf_.IsNull()) { + if (multipleOf_.IsUint64()) { + if (static_cast(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) { + context.error_handler.NotMultipleOf(i, multipleOf_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMultipleOf); + } + } + else if (!CheckDoubleMultipleOf(context, static_cast(i))) + return false; + } + + return true; + } + + bool CheckUint(Context& context, uint64_t i) const { + if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) { + DisallowedType(context, GetIntegerString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + if (!minimum_.IsNull()) { + if (minimum_.IsUint64()) { + if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) { + context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum); + } + } + else if (minimum_.IsInt64()) + /* do nothing */; // i >= 0 > minimum.Getint64() + else if (!CheckDoubleMinimum(context, static_cast(i))) + return false; + } + + if (!maximum_.IsNull()) { + if (maximum_.IsUint64()) { + if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) { + context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum); + } + } + else if (maximum_.IsInt64()) { + context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum); // i >= 0 > maximum_ + } + else if (!CheckDoubleMaximum(context, static_cast(i))) + return false; + } + + if (!multipleOf_.IsNull()) { + if (multipleOf_.IsUint64()) { + if (i % multipleOf_.GetUint64() != 0) { + context.error_handler.NotMultipleOf(i, multipleOf_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMultipleOf); + } + } + else if (!CheckDoubleMultipleOf(context, static_cast(i))) + return false; + } + + return true; + } + + bool CheckDoubleMinimum(Context& context, double d) const { + if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) { + context.error_handler.BelowMinimum(d, minimum_, exclusiveMinimum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum); + } + return true; + } + + bool CheckDoubleMaximum(Context& context, double d) const { + if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) { + context.error_handler.AboveMaximum(d, maximum_, exclusiveMaximum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum); + } + return true; + } + + bool CheckDoubleMultipleOf(Context& context, double d) const { + double a = std::abs(d), b = std::abs(multipleOf_.GetDouble()); + double q = std::floor(a / b); + double r = a - q * b; + if (r > 0.0) { + context.error_handler.NotMultipleOf(d, multipleOf_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMultipleOf); + } + return true; + } + + void DisallowedType(Context& context, const ValueType& actualType) const { + ErrorHandler& eh = context.error_handler; + eh.StartDisallowedType(); + + if (type_ & (1 << kNullSchemaType)) eh.AddExpectedType(GetNullString()); + if (type_ & (1 << kBooleanSchemaType)) eh.AddExpectedType(GetBooleanString()); + if (type_ & (1 << kObjectSchemaType)) eh.AddExpectedType(GetObjectString()); + if (type_ & (1 << kArraySchemaType)) eh.AddExpectedType(GetArrayString()); + if (type_ & (1 << kStringSchemaType)) eh.AddExpectedType(GetStringString()); + + if (type_ & (1 << kNumberSchemaType)) eh.AddExpectedType(GetNumberString()); + else if (type_ & (1 << kIntegerSchemaType)) eh.AddExpectedType(GetIntegerString()); + + eh.EndDisallowedType(actualType); + } + + struct Property { + Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {} + ~Property() { AllocatorType::Free(dependencies); } + SValue name; + const SchemaType* schema; + const SchemaType* dependenciesSchema; + SizeType dependenciesValidatorIndex; + bool* dependencies; + bool required; + }; + + struct PatternProperty { + PatternProperty() : schema(), pattern() {} + ~PatternProperty() { + if (pattern) { + pattern->~RegexType(); + AllocatorType::Free(pattern); + } + } + const SchemaType* schema; + RegexType* pattern; + }; + + AllocatorType* allocator_; + SValue uri_; + UriType id_; + Specification spec_; + PointerType pointer_; + const SchemaType* typeless_; + uint64_t* enum_; + SizeType enumCount_; + SchemaArray allOf_; + SchemaArray anyOf_; + SchemaArray oneOf_; + const SchemaType* not_; + unsigned type_; // bitmask of kSchemaType + SizeType validatorCount_; + SizeType notValidatorIndex_; + + Property* properties_; + const SchemaType* additionalPropertiesSchema_; + PatternProperty* patternProperties_; + SizeType patternPropertyCount_; + SizeType propertyCount_; + SizeType minProperties_; + SizeType maxProperties_; + bool additionalProperties_; + bool hasDependencies_; + bool hasRequired_; + bool hasSchemaDependencies_; + + const SchemaType* additionalItemsSchema_; + const SchemaType* itemsList_; + const SchemaType** itemsTuple_; + SizeType itemsTupleCount_; + SizeType minItems_; + SizeType maxItems_; + bool additionalItems_; + bool uniqueItems_; + + RegexType* pattern_; + SizeType minLength_; + SizeType maxLength_; + + SValue minimum_; + SValue maximum_; + SValue multipleOf_; + bool exclusiveMinimum_; + bool exclusiveMaximum_; + + SizeType defaultValueLength_; + + bool readOnly_; + bool writeOnly_; + bool nullable_; +}; + +template +struct TokenHelper { + RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { + *documentStack.template Push() = '/'; + char buffer[21]; + size_t length = static_cast((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer); + for (size_t i = 0; i < length; i++) + *documentStack.template Push() = static_cast(buffer[i]); + } +}; + +// Partial specialized version for char to prevent buffer copying. +template +struct TokenHelper { + RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { + if (sizeof(SizeType) == 4) { + char *buffer = documentStack.template Push(1 + 10); // '/' + uint + *buffer++ = '/'; + const char* end = internal::u32toa(index, buffer); + documentStack.template Pop(static_cast(10 - (end - buffer))); + } + else { + char *buffer = documentStack.template Push(1 + 20); // '/' + uint64 + *buffer++ = '/'; + const char* end = internal::u64toa(index, buffer); + documentStack.template Pop(static_cast(20 - (end - buffer))); + } + } +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// IGenericRemoteSchemaDocumentProvider + +template +class IGenericRemoteSchemaDocumentProvider { +public: + typedef typename SchemaDocumentType::Ch Ch; + typedef typename SchemaDocumentType::ValueType ValueType; + typedef typename SchemaDocumentType::AllocatorType AllocatorType; + + virtual ~IGenericRemoteSchemaDocumentProvider() {} + virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0; + virtual const SchemaDocumentType* GetRemoteDocument(const GenericUri uri, Specification& spec) { + // Default implementation just calls through for compatibility + // Following line suppresses unused parameter warning + (void)spec; + // printf("GetRemoteDocument: %d %d\n", spec.draft, spec.oapi); + return GetRemoteDocument(uri.GetBaseString(), uri.GetBaseStringLength()); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaDocument + +//! JSON schema document. +/*! + A JSON schema document is a compiled version of a JSON schema. + It is basically a tree of internal::Schema. + + \note This is an immutable class (i.e. its instance cannot be modified after construction). + \tparam ValueT Type of JSON value (e.g. \c Value ), which also determine the encoding. + \tparam Allocator Allocator type for allocating memory of this document. +*/ +template +class GenericSchemaDocument { +public: + typedef ValueT ValueType; + typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProviderType; + typedef Allocator AllocatorType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + typedef internal::Schema SchemaType; + typedef GenericPointer PointerType; + typedef GenericValue GValue; + typedef GenericUri UriType; + typedef GenericStringRef StringRefType; + friend class internal::Schema; + template + friend class GenericSchemaValidator; + + //! Constructor. + /*! + Compile a JSON document into schema document. + + \param document A JSON document as source. + \param uri The base URI of this schema document for purposes of violation reporting. + \param uriLength Length of \c name, in code points. + \param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null. + \param allocator An optional allocator instance for allocating memory. Can be null. + \param pointer An optional JSON pointer to the start of the schema document + \param spec Optional schema draft or OpenAPI version. Used if no specification in document. Defaults to draft-04. + */ + explicit GenericSchemaDocument(const ValueType& document, const Ch* uri = 0, SizeType uriLength = 0, + IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0, + const PointerType& pointer = PointerType(), // PR #1393 + const Specification& spec = Specification(kDraft04)) : + remoteProvider_(remoteProvider), + allocator_(allocator), + ownAllocator_(), + root_(), + typeless_(), + schemaMap_(allocator, kInitialSchemaMapSize), + schemaRef_(allocator, kInitialSchemaRefSize), + spec_(spec), + error_(kObjectType), + currentError_() + { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaDocument::GenericSchemaDocument"); + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + + Ch noUri[1] = {0}; + uri_.SetString(uri ? uri : noUri, uriLength, *allocator_); + docId_ = UriType(uri_, allocator_); + + typeless_ = static_cast(allocator_->Malloc(sizeof(SchemaType))); + new (typeless_) SchemaType(this, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), allocator_, docId_); + + // Establish the schema draft or open api version. + // We only ever look for '$schema' or 'swagger' or 'openapi' at the root of the document. + SetSchemaSpecification(document); + + // Generate root schema, it will call CreateSchema() to create sub-schemas, + // And call HandleRefSchema() if there are $ref. + // PR #1393 use input pointer if supplied + root_ = typeless_; + if (pointer.GetTokenCount() == 0) { + CreateSchemaRecursive(&root_, pointer, document, document, docId_); + } + else if (const ValueType* v = pointer.Get(document)) { + CreateSchema(&root_, pointer, *v, document, docId_); + } + else { + GenericStringBuffer sb; + pointer.StringifyUriFragment(sb); + SchemaErrorValue(kSchemaErrorStartUnknown, PointerType(), sb.GetString(), static_cast(sb.GetSize() / sizeof(Ch))); + } + + RAPIDJSON_ASSERT(root_ != 0); + + schemaRef_.ShrinkToFit(); // Deallocate all memory for ref + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT : + remoteProvider_(rhs.remoteProvider_), + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + root_(rhs.root_), + typeless_(rhs.typeless_), + schemaMap_(std::move(rhs.schemaMap_)), + schemaRef_(std::move(rhs.schemaRef_)), + uri_(std::move(rhs.uri_)), + docId_(std::move(rhs.docId_)), + spec_(rhs.spec_), + error_(std::move(rhs.error_)), + currentError_(std::move(rhs.currentError_)) + { + rhs.remoteProvider_ = 0; + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.typeless_ = 0; + } +#endif + + //! Destructor + ~GenericSchemaDocument() { + while (!schemaMap_.Empty()) + schemaMap_.template Pop(1)->~SchemaEntry(); + + if (typeless_) { + typeless_->~SchemaType(); + Allocator::Free(typeless_); + } + + // these may contain some allocator data so clear before deleting ownAllocator_ + uri_.SetNull(); + error_.SetNull(); + currentError_.SetNull(); + + RAPIDJSON_DELETE(ownAllocator_); + } + + const GValue& GetURI() const { return uri_; } + + const Specification& GetSpecification() const { return spec_; } + bool IsSupportedSpecification() const { return spec_.IsSupported(); } + + //! Static method to get the specification of any schema document + // Returns kDraftNone if document is silent + static const Specification GetSpecification(const ValueType& document) { + SchemaDraft draft = GetSchemaDraft(document); + if (draft != kDraftNone) + return Specification(draft); + else { + OpenApiVersion oapi = GetOpenApiVersion(document); + if (oapi != kVersionNone) + return Specification(oapi); + } + return Specification(kDraftNone); + } + + //! Get the root schema. + const SchemaType& GetRoot() const { return *root_; } + + //! Gets the error object. + GValue& GetError() { return error_; } + const GValue& GetError() const { return error_; } + + static const StringRefType& GetSchemaErrorKeyword(SchemaErrorCode schemaErrorCode) { + switch (schemaErrorCode) { + case kSchemaErrorStartUnknown: return GetStartUnknownString(); + case kSchemaErrorRefPlainName: return GetRefPlainNameString(); + case kSchemaErrorRefInvalid: return GetRefInvalidString(); + case kSchemaErrorRefPointerInvalid: return GetRefPointerInvalidString(); + case kSchemaErrorRefUnknown: return GetRefUnknownString(); + case kSchemaErrorRefCyclical: return GetRefCyclicalString(); + case kSchemaErrorRefNoRemoteProvider: return GetRefNoRemoteProviderString(); + case kSchemaErrorRefNoRemoteSchema: return GetRefNoRemoteSchemaString(); + case kSchemaErrorRegexInvalid: return GetRegexInvalidString(); + case kSchemaErrorSpecUnknown: return GetSpecUnknownString(); + case kSchemaErrorSpecUnsupported: return GetSpecUnsupportedString(); + case kSchemaErrorSpecIllegal: return GetSpecIllegalString(); + case kSchemaErrorReadOnlyAndWriteOnly: return GetReadOnlyAndWriteOnlyString(); + default: return GetNullString(); + } + } + + //! Default error method + void SchemaError(const SchemaErrorCode code, const PointerType& location) { + currentError_ = GValue(kObjectType); + AddCurrentError(code, location); + } + + //! Method for error with single string value insert + void SchemaErrorValue(const SchemaErrorCode code, const PointerType& location, const Ch* value, SizeType length) { + currentError_ = GValue(kObjectType); + currentError_.AddMember(GetValueString(), GValue(value, length, *allocator_).Move(), *allocator_); + AddCurrentError(code, location); + } + + //! Method for error with invalid pointer + void SchemaErrorPointer(const SchemaErrorCode code, const PointerType& location, const Ch* value, SizeType length, const PointerType& pointer) { + currentError_ = GValue(kObjectType); + currentError_.AddMember(GetValueString(), GValue(value, length, *allocator_).Move(), *allocator_); + currentError_.AddMember(GetOffsetString(), static_cast(pointer.GetParseErrorOffset() / sizeof(Ch)), *allocator_); + AddCurrentError(code, location); + } + + private: + //! Prohibit copying + GenericSchemaDocument(const GenericSchemaDocument&); + //! Prohibit assignment + GenericSchemaDocument& operator=(const GenericSchemaDocument&); + + typedef const PointerType* SchemaRefPtr; // PR #1393 + + struct SchemaEntry { + SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {} + ~SchemaEntry() { + if (owned) { + schema->~SchemaType(); + Allocator::Free(schema); + } + } + PointerType pointer; + SchemaType* schema; + bool owned; + }; + + void AddErrorInstanceLocation(GValue& result, const PointerType& location) { + GenericStringBuffer sb; + location.StringifyUriFragment(sb); + GValue instanceRef(sb.GetString(), static_cast(sb.GetSize() / sizeof(Ch)), *allocator_); + result.AddMember(GetInstanceRefString(), instanceRef, *allocator_); + } + + void AddError(GValue& keyword, GValue& error) { + typename GValue::MemberIterator member = error_.FindMember(keyword); + if (member == error_.MemberEnd()) + error_.AddMember(keyword, error, *allocator_); + else { + if (member->value.IsObject()) { + GValue errors(kArrayType); + errors.PushBack(member->value, *allocator_); + member->value = errors; + } + member->value.PushBack(error, *allocator_); + } + } + + void AddCurrentError(const SchemaErrorCode code, const PointerType& location) { + RAPIDJSON_SCHEMA_PRINT(InvalidKeyword, GetSchemaErrorKeyword(code)); + currentError_.AddMember(GetErrorCodeString(), code, *allocator_); + AddErrorInstanceLocation(currentError_, location); + AddError(GValue(GetSchemaErrorKeyword(code)).Move(), currentError_); + } + +#define RAPIDJSON_STRING_(name, ...) \ + static const StringRefType& Get##name##String() {\ + static const Ch s[] = { __VA_ARGS__, '\0' };\ + static const StringRefType v(s, static_cast(sizeof(s) / sizeof(Ch) - 1)); \ + return v;\ + } + + RAPIDJSON_STRING_(InstanceRef, 'i', 'n', 's', 't', 'a', 'n', 'c', 'e', 'R', 'e', 'f') + RAPIDJSON_STRING_(ErrorCode, 'e', 'r', 'r', 'o', 'r', 'C', 'o', 'd', 'e') + RAPIDJSON_STRING_(Value, 'v', 'a', 'l', 'u', 'e') + RAPIDJSON_STRING_(Offset, 'o', 'f', 'f', 's', 'e', 't') + + RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l') + RAPIDJSON_STRING_(SpecUnknown, 'S', 'p', 'e', 'c', 'U', 'n', 'k', 'n', 'o', 'w', 'n') + RAPIDJSON_STRING_(SpecUnsupported, 'S', 'p', 'e', 'c', 'U', 'n', 's', 'u', 'p', 'p', 'o', 'r', 't', 'e', 'd') + RAPIDJSON_STRING_(SpecIllegal, 'S', 'p', 'e', 'c', 'I', 'l', 'l', 'e', 'g', 'a', 'l') + RAPIDJSON_STRING_(StartUnknown, 'S', 't', 'a', 'r', 't', 'U', 'n', 'k', 'n', 'o', 'w', 'n') + RAPIDJSON_STRING_(RefPlainName, 'R', 'e', 'f', 'P', 'l', 'a', 'i', 'n', 'N', 'a', 'm', 'e') + RAPIDJSON_STRING_(RefInvalid, 'R', 'e', 'f', 'I', 'n', 'v', 'a', 'l', 'i', 'd') + RAPIDJSON_STRING_(RefPointerInvalid, 'R', 'e', 'f', 'P', 'o', 'i', 'n', 't', 'e', 'r', 'I', 'n', 'v', 'a', 'l', 'i', 'd') + RAPIDJSON_STRING_(RefUnknown, 'R', 'e', 'f', 'U', 'n', 'k', 'n', 'o', 'w', 'n') + RAPIDJSON_STRING_(RefCyclical, 'R', 'e', 'f', 'C', 'y', 'c', 'l', 'i', 'c', 'a', 'l') + RAPIDJSON_STRING_(RefNoRemoteProvider, 'R', 'e', 'f', 'N', 'o', 'R', 'e', 'm', 'o', 't', 'e', 'P', 'r', 'o', 'v', 'i', 'd', 'e', 'r') + RAPIDJSON_STRING_(RefNoRemoteSchema, 'R', 'e', 'f', 'N', 'o', 'R', 'e', 'm', 'o', 't', 'e', 'S', 'c', 'h', 'e', 'm', 'a') + RAPIDJSON_STRING_(ReadOnlyAndWriteOnly, 'R', 'e', 'a', 'd', 'O', 'n', 'l', 'y', 'A', 'n', 'd', 'W', 'r', 'i', 't', 'e', 'O', 'n', 'l', 'y') + RAPIDJSON_STRING_(RegexInvalid, 'R', 'e', 'g', 'e', 'x', 'I', 'n', 'v', 'a', 'l', 'i', 'd') + +#undef RAPIDJSON_STRING_ + + // Static method to get schema draft of any schema document + static SchemaDraft GetSchemaDraft(const ValueType& document) { + static const Ch kDraft03String[] = { 'h', 't', 't', 'p', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '-', '0', '3', '/', 's', 'c', 'h', 'e', 'm', 'a', '#', '\0' }; + static const Ch kDraft04String[] = { 'h', 't', 't', 'p', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '-', '0', '4', '/', 's', 'c', 'h', 'e', 'm', 'a', '#', '\0' }; + static const Ch kDraft05String[] = { 'h', 't', 't', 'p', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '-', '0', '5', '/', 's', 'c', 'h', 'e', 'm', 'a', '#', '\0' }; + static const Ch kDraft06String[] = { 'h', 't', 't', 'p', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '-', '0', '6', '/', 's', 'c', 'h', 'e', 'm', 'a', '#', '\0' }; + static const Ch kDraft07String[] = { 'h', 't', 't', 'p', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '-', '0', '7', '/', 's', 'c', 'h', 'e', 'm', 'a', '#', '\0' }; + static const Ch kDraft2019_09String[] = { 'h', 't', 't', 'p', 's', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '/', '2', '0', '1', '9', '-', '0', '9', '/', 's', 'c', 'h', 'e', 'm', 'a', '\0' }; + static const Ch kDraft2020_12String[] = { 'h', 't', 't', 'p', 's', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '/', '2', '0', '2', '0', '-', '1', '2', '/', 's', 'c', 'h', 'e', 'm', 'a', '\0' }; + + if (!document.IsObject()) { + return kDraftNone; + } + + // Get the schema draft from the $schema keyword at the supplied location + typename ValueType::ConstMemberIterator itr = document.FindMember(SchemaType::GetSchemaString()); + if (itr != document.MemberEnd()) { + if (!itr->value.IsString()) return kDraftUnknown; + const UriType draftUri(itr->value); + // Check base uri for match + if (draftUri.Match(UriType(kDraft04String), false)) return kDraft04; + if (draftUri.Match(UriType(kDraft05String), false)) return kDraft05; + if (draftUri.Match(UriType(kDraft06String), false)) return kDraft06; + if (draftUri.Match(UriType(kDraft07String), false)) return kDraft07; + if (draftUri.Match(UriType(kDraft03String), false)) return kDraft03; + if (draftUri.Match(UriType(kDraft2019_09String), false)) return kDraft2019_09; + if (draftUri.Match(UriType(kDraft2020_12String), false)) return kDraft2020_12; + return kDraftUnknown; + } + // $schema not found + return kDraftNone; + } + + + // Get open api version of any schema document + static OpenApiVersion GetOpenApiVersion(const ValueType& document) { + static const Ch kVersion20String[] = { '2', '.', '0', '\0' }; + static const Ch kVersion30String[] = { '3', '.', '0', '.', '\0' }; // ignore patch level + static const Ch kVersion31String[] = { '3', '.', '1', '.', '\0' }; // ignore patch level + static SizeType len = internal::StrLen(kVersion30String); + + if (!document.IsObject()) { + return kVersionNone; + } + + // Get the open api version from the swagger / openapi keyword at the supplied location + typename ValueType::ConstMemberIterator itr = document.FindMember(SchemaType::GetSwaggerString()); + if (itr == document.MemberEnd()) itr = document.FindMember(SchemaType::GetOpenApiString()); + if (itr != document.MemberEnd()) { + if (!itr->value.IsString()) return kVersionUnknown; + const ValueType kVersion20Value(kVersion20String); + if (kVersion20Value == itr->value) return kVersion20; // must match 2.0 exactly + const ValueType kVersion30Value(kVersion30String); + if (itr->value.GetStringLength() > len && kVersion30Value == ValueType(itr->value.GetString(), len)) return kVersion30; // must match 3.0.x + const ValueType kVersion31Value(kVersion31String); + if (itr->value.GetStringLength() > len && kVersion31Value == ValueType(itr->value.GetString(), len)) return kVersion31; // must match 3.1.x + return kVersionUnknown; + } + // swagger or openapi not found + return kVersionNone; + } + + // Get the draft of the schema or the open api version (which implies the draft). + // Report an error if schema draft or open api version not supported or not recognized, or both in document, and carry on. + void SetSchemaSpecification(const ValueType& document) { + // Look for '$schema', 'swagger' or 'openapi' keyword at document root + SchemaDraft docDraft = GetSchemaDraft(document); + OpenApiVersion docOapi = GetOpenApiVersion(document); + // Error if both in document + if (docDraft != kDraftNone && docOapi != kVersionNone) + SchemaError(kSchemaErrorSpecIllegal, PointerType()); + // Use document draft or open api version if present or use spec from constructor + if (docDraft != kDraftNone) + spec_ = Specification(docDraft); + else if (docOapi != kVersionNone) + spec_ = Specification(docOapi); + // Error if draft or version unknown + if (spec_.draft == kDraftUnknown || spec_.oapi == kVersionUnknown) + SchemaError(kSchemaErrorSpecUnknown, PointerType()); + else if (!spec_.IsSupported()) + SchemaError(kSchemaErrorSpecUnsupported, PointerType()); + } + + // Changed by PR #1393 + void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document, const UriType& id) { + if (v.GetType() == kObjectType) { + UriType newid = UriType(CreateSchema(schema, pointer, v, document, id), allocator_); + + for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) + CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document, newid); + } + else if (v.GetType() == kArrayType) + for (SizeType i = 0; i < v.Size(); i++) + CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document, id); + } + + // Changed by PR #1393 + const UriType& CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document, const UriType& id) { + RAPIDJSON_ASSERT(pointer.IsValid()); + GenericStringBuffer sb; + pointer.StringifyUriFragment(sb); + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaDocument::CreateSchema", sb.GetString(), id.GetString()); + if (v.IsObject()) { + if (const SchemaType* sc = GetSchema(pointer)) { + if (schema) + *schema = sc; + AddSchemaRefs(const_cast(sc)); + } + else if (!HandleRefSchema(pointer, schema, v, document, id)) { + // The new schema constructor adds itself and its $ref(s) to schemaMap_ + SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_, id); + if (schema) + *schema = s; + return s->GetId(); + } + } + else { + if (schema) + *schema = typeless_; + AddSchemaRefs(typeless_); + } + return id; + } + + // Changed by PR #1393 + // TODO should this return a UriType& ? + bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document, const UriType& id) { + typename ValueType::ConstMemberIterator itr = v.FindMember(SchemaType::GetRefString()); + if (itr == v.MemberEnd()) + return false; + + GenericStringBuffer sb; + source.StringifyUriFragment(sb); + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaDocument::HandleRefSchema", sb.GetString(), id.GetString()); + // Resolve the source pointer to the $ref'ed schema (finally) + new (schemaRef_.template Push()) SchemaRefPtr(&source); + + if (itr->value.IsString()) { + SizeType len = itr->value.GetStringLength(); + if (len == 0) + SchemaError(kSchemaErrorRefInvalid, source); + else { + // First resolve $ref against the in-scope id + UriType scopeId = UriType(id, allocator_); + UriType ref = UriType(itr->value, allocator_).Resolve(scopeId, allocator_); + RAPIDJSON_SCHEMA_PRINT(SchemaIds, id.GetString(), itr->value.GetString(), ref.GetString()); + // See if the resolved $ref minus the fragment matches a resolved id in this document + // Search from the root. Returns the subschema in the document and its absolute JSON pointer. + PointerType basePointer = PointerType(); + const ValueType *base = FindId(document, ref, basePointer, docId_, false); + if (!base) { + // Remote reference - call the remote document provider + if (!remoteProvider_) + SchemaError(kSchemaErrorRefNoRemoteProvider, source); + else { + if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(ref, spec_)) { + const Ch* s = ref.GetFragString(); + len = ref.GetFragStringLength(); + if (len <= 1 || s[1] == '/') { + // JSON pointer fragment, absolute in the remote schema + const PointerType pointer(s, len, allocator_); + if (!pointer.IsValid()) + SchemaErrorPointer(kSchemaErrorRefPointerInvalid, source, s, len, pointer); + else { + // Get the subschema + if (const SchemaType *sc = remoteDocument->GetSchema(pointer)) { + if (schema) + *schema = sc; + AddSchemaRefs(const_cast(sc)); + return true; + } else + SchemaErrorValue(kSchemaErrorRefUnknown, source, ref.GetString(), ref.GetStringLength()); + } + } else + // Plain name fragment, not allowed in remote schema + SchemaErrorValue(kSchemaErrorRefPlainName, source, s, len); + } else + SchemaErrorValue(kSchemaErrorRefNoRemoteSchema, source, ref.GetString(), ref.GetStringLength()); + } + } + else { // Local reference + const Ch* s = ref.GetFragString(); + len = ref.GetFragStringLength(); + if (len <= 1 || s[1] == '/') { + // JSON pointer fragment, relative to the resolved URI + const PointerType relPointer(s, len, allocator_); + if (!relPointer.IsValid()) + SchemaErrorPointer(kSchemaErrorRefPointerInvalid, source, s, len, relPointer); + else { + // Get the subschema + if (const ValueType *pv = relPointer.Get(*base)) { + // Now get the absolute JSON pointer by adding relative to base + PointerType pointer(basePointer, allocator_); + for (SizeType i = 0; i < relPointer.GetTokenCount(); i++) + pointer = pointer.Append(relPointer.GetTokens()[i], allocator_); + if (IsCyclicRef(pointer)) + SchemaErrorValue(kSchemaErrorRefCyclical, source, ref.GetString(), ref.GetStringLength()); + else { + // Call CreateSchema recursively, but first compute the in-scope id for the $ref target as we have jumped there + // TODO: cache pointer <-> id mapping + size_t unresolvedTokenIndex; + scopeId = pointer.GetUri(document, docId_, &unresolvedTokenIndex, allocator_); + CreateSchema(schema, pointer, *pv, document, scopeId); + return true; + } + } else + SchemaErrorValue(kSchemaErrorRefUnknown, source, ref.GetString(), ref.GetStringLength()); + } + } else { + // Plain name fragment, relative to the resolved URI + // Not supported in open api 2.0 and 3.0 + PointerType pointer(allocator_); + if (spec_.oapi == kVersion20 || spec_.oapi == kVersion30) + SchemaErrorValue(kSchemaErrorRefPlainName, source, s, len); + // See if the fragment matches an id in this document. + // Search from the base we just established. Returns the subschema in the document and its absolute JSON pointer. + else if (const ValueType *pv = FindId(*base, ref, pointer, UriType(ref.GetBaseString(), ref.GetBaseStringLength(), allocator_), true, basePointer)) { + if (IsCyclicRef(pointer)) + SchemaErrorValue(kSchemaErrorRefCyclical, source, ref.GetString(), ref.GetStringLength()); + else { + // Call CreateSchema recursively, but first compute the in-scope id for the $ref target as we have jumped there + // TODO: cache pointer <-> id mapping + size_t unresolvedTokenIndex; + scopeId = pointer.GetUri(document, docId_, &unresolvedTokenIndex, allocator_); + CreateSchema(schema, pointer, *pv, document, scopeId); + return true; + } + } else + SchemaErrorValue(kSchemaErrorRefUnknown, source, ref.GetString(), ref.GetStringLength()); + } + } + } + } + + // Invalid/Unknown $ref + if (schema) + *schema = typeless_; + AddSchemaRefs(typeless_); + return true; + } + + //! Find the first subschema with a resolved 'id' that matches the specified URI. + // If full specified use all URI else ignore fragment. + // If found, return a pointer to the subschema and its JSON pointer. + // TODO cache pointer <-> id mapping + ValueType* FindId(const ValueType& doc, const UriType& finduri, PointerType& resptr, const UriType& baseuri, bool full, const PointerType& here = PointerType()) const { + SizeType i = 0; + ValueType* resval = 0; + UriType tempuri = UriType(finduri, allocator_); + UriType localuri = UriType(baseuri, allocator_); + if (doc.GetType() == kObjectType) { + // Establish the base URI of this object + typename ValueType::ConstMemberIterator m = doc.FindMember(SchemaType::GetIdString()); + if (m != doc.MemberEnd() && m->value.GetType() == kStringType) { + localuri = UriType(m->value, allocator_).Resolve(baseuri, allocator_); + } + // See if it matches + if (localuri.Match(finduri, full)) { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaDocument::FindId (match)", full ? localuri.GetString() : localuri.GetBaseString()); + resval = const_cast(&doc); + resptr = here; + return resval; + } + // No match, continue looking + for (m = doc.MemberBegin(); m != doc.MemberEnd(); ++m) { + if (m->value.GetType() == kObjectType || m->value.GetType() == kArrayType) { + resval = FindId(m->value, finduri, resptr, localuri, full, here.Append(m->name.GetString(), m->name.GetStringLength(), allocator_)); + } + if (resval) break; + } + } else if (doc.GetType() == kArrayType) { + // Continue looking + for (typename ValueType::ConstValueIterator v = doc.Begin(); v != doc.End(); ++v) { + if (v->GetType() == kObjectType || v->GetType() == kArrayType) { + resval = FindId(*v, finduri, resptr, localuri, full, here.Append(i, allocator_)); + } + if (resval) break; + i++; + } + } + return resval; + } + + // Added by PR #1393 + void AddSchemaRefs(SchemaType* schema) { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaDocument::AddSchemaRefs"); + while (!schemaRef_.Empty()) { + SchemaRefPtr *ref = schemaRef_.template Pop(1); + SchemaEntry *entry = schemaMap_.template Push(); + new (entry) SchemaEntry(**ref, schema, false, allocator_); + } + } + + // Added by PR #1393 + bool IsCyclicRef(const PointerType& pointer) const { + for (const SchemaRefPtr* ref = schemaRef_.template Bottom(); ref != schemaRef_.template End(); ++ref) + if (pointer == **ref) + return true; + return false; + } + + const SchemaType* GetSchema(const PointerType& pointer) const { + for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) + if (pointer == target->pointer) + return target->schema; + return 0; + } + + PointerType GetPointer(const SchemaType* schema) const { + for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) + if (schema == target->schema) + return target->pointer; + return PointerType(); + } + + const SchemaType* GetTypeless() const { return typeless_; } + + static const size_t kInitialSchemaMapSize = 64; + static const size_t kInitialSchemaRefSize = 64; + + IRemoteSchemaDocumentProviderType* remoteProvider_; + Allocator *allocator_; + Allocator *ownAllocator_; + const SchemaType* root_; //!< Root schema. + SchemaType* typeless_; + internal::Stack schemaMap_; // Stores created Pointer -> Schemas + internal::Stack schemaRef_; // Stores Pointer(s) from $ref(s) until resolved + GValue uri_; // Schema document URI + UriType docId_; + Specification spec_; + GValue error_; + GValue currentError_; +}; + +//! GenericSchemaDocument using Value type. +typedef GenericSchemaDocument SchemaDocument; +//! IGenericRemoteSchemaDocumentProvider using SchemaDocument. +typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; + +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaValidator + +//! JSON Schema Validator. +/*! + A SAX style JSON schema validator. + It uses a \c GenericSchemaDocument to validate SAX events. + It delegates the incoming SAX events to an output handler. + The default output handler does nothing. + It can be reused multiple times by calling \c Reset(). + + \tparam SchemaDocumentType Type of schema document. + \tparam OutputHandler Type of output handler. Default handler does nothing. + \tparam StateAllocator Allocator for storing the internal validation states. +*/ +template < + typename SchemaDocumentType, + typename OutputHandler = BaseReaderHandler, + typename StateAllocator = CrtAllocator> +class GenericSchemaValidator : + public internal::ISchemaStateFactory, + public internal::ISchemaValidator, + public internal::IValidationErrorHandler { +public: + typedef typename SchemaDocumentType::SchemaType SchemaType; + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename SchemaType::EncodingType EncodingType; + typedef typename SchemaType::SValue SValue; + typedef typename EncodingType::Ch Ch; + typedef GenericStringRef StringRefType; + typedef GenericValue ValueType; + + //! Constructor without output handler. + /*! + \param schemaDocument The schema document to conform to. + \param allocator Optional allocator for storing internal validation states. + \param schemaStackCapacity Optional initial capacity of schema path stack. + \param documentStackCapacity Optional initial capacity of document path stack. + */ + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(schemaDocument.GetRoot()), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + outputHandler_(0), + error_(kObjectType), + currentError_(), + missingDependents_(), + valid_(true), + flags_(kValidateDefaultFlags), + depth_(0) + { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::GenericSchemaValidator"); + } + + //! Constructor with output handler. + /*! + \param schemaDocument The schema document to conform to. + \param allocator Optional allocator for storing internal validation states. + \param schemaStackCapacity Optional initial capacity of schema path stack. + \param documentStackCapacity Optional initial capacity of document path stack. + */ + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + OutputHandler& outputHandler, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(schemaDocument.GetRoot()), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + outputHandler_(&outputHandler), + error_(kObjectType), + currentError_(), + missingDependents_(), + valid_(true), + flags_(kValidateDefaultFlags), + depth_(0) + { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::GenericSchemaValidator (output handler)"); + } + + //! Destructor. + ~GenericSchemaValidator() { + Reset(); + RAPIDJSON_DELETE(ownStateAllocator_); + } + + //! Reset the internal states. + void Reset() { + while (!schemaStack_.Empty()) + PopSchema(); + documentStack_.Clear(); + ResetError(); + } + + //! Reset the error state. + void ResetError() { + error_.SetObject(); + currentError_.SetNull(); + missingDependents_.SetNull(); + valid_ = true; + } + + //! Implementation of ISchemaValidator + void SetValidateFlags(unsigned flags) { + flags_ = flags; + } + virtual unsigned GetValidateFlags() const { + return flags_; + } + + virtual bool IsValid() const { + if (!valid_) return false; + if (GetContinueOnErrors() && !error_.ObjectEmpty()) return false; + return true; + } + //! End of Implementation of ISchemaValidator + + //! Gets the error object. + ValueType& GetError() { return error_; } + const ValueType& GetError() const { return error_; } + + //! Gets the JSON pointer pointed to the invalid schema. + // If reporting all errors, the stack will be empty. + PointerType GetInvalidSchemaPointer() const { + return schemaStack_.Empty() ? PointerType() : CurrentSchema().GetPointer(); + } + + //! Gets the keyword of invalid schema. + // If reporting all errors, the stack will be empty, so return "errors". + const Ch* GetInvalidSchemaKeyword() const { + if (!schemaStack_.Empty()) return CurrentContext().invalidKeyword; + if (GetContinueOnErrors() && !error_.ObjectEmpty()) return (const Ch*)GetErrorsString(); + return 0; + } + + //! Gets the error code of invalid schema. + // If reporting all errors, the stack will be empty, so return kValidateErrors. + ValidateErrorCode GetInvalidSchemaCode() const { + if (!schemaStack_.Empty()) return CurrentContext().invalidCode; + if (GetContinueOnErrors() && !error_.ObjectEmpty()) return kValidateErrors; + return kValidateErrorNone; + } + + //! Gets the JSON pointer pointed to the invalid value. + // If reporting all errors, the stack will be empty. + PointerType GetInvalidDocumentPointer() const { + if (documentStack_.Empty()) { + return PointerType(); + } + else { + return PointerType(documentStack_.template Bottom(), documentStack_.GetSize() / sizeof(Ch)); + } + } + + void NotMultipleOf(int64_t actual, const SValue& expected) { + AddNumberError(kValidateErrorMultipleOf, ValueType(actual).Move(), expected); + } + void NotMultipleOf(uint64_t actual, const SValue& expected) { + AddNumberError(kValidateErrorMultipleOf, ValueType(actual).Move(), expected); + } + void NotMultipleOf(double actual, const SValue& expected) { + AddNumberError(kValidateErrorMultipleOf, ValueType(actual).Move(), expected); + } + void AboveMaximum(int64_t actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMaximumString : 0); + } + void AboveMaximum(uint64_t actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMaximumString : 0); + } + void AboveMaximum(double actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMaximumString : 0); + } + void BelowMinimum(int64_t actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMinimumString : 0); + } + void BelowMinimum(uint64_t actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMinimumString : 0); + } + void BelowMinimum(double actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMinimumString : 0); + } + + void TooLong(const Ch* str, SizeType length, SizeType expected) { + AddNumberError(kValidateErrorMaxLength, + ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move()); + } + void TooShort(const Ch* str, SizeType length, SizeType expected) { + AddNumberError(kValidateErrorMinLength, + ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move()); + } + void DoesNotMatch(const Ch* str, SizeType length) { + currentError_.SetObject(); + currentError_.AddMember(GetActualString(), ValueType(str, length, GetStateAllocator()).Move(), GetStateAllocator()); + AddCurrentError(kValidateErrorPattern); + } + + void DisallowedItem(SizeType index) { + currentError_.SetObject(); + currentError_.AddMember(GetDisallowedString(), ValueType(index).Move(), GetStateAllocator()); + AddCurrentError(kValidateErrorAdditionalItems, true); + } + void TooFewItems(SizeType actualCount, SizeType expectedCount) { + AddNumberError(kValidateErrorMinItems, + ValueType(actualCount).Move(), SValue(expectedCount).Move()); + } + void TooManyItems(SizeType actualCount, SizeType expectedCount) { + AddNumberError(kValidateErrorMaxItems, + ValueType(actualCount).Move(), SValue(expectedCount).Move()); + } + void DuplicateItems(SizeType index1, SizeType index2) { + ValueType duplicates(kArrayType); + duplicates.PushBack(index1, GetStateAllocator()); + duplicates.PushBack(index2, GetStateAllocator()); + currentError_.SetObject(); + currentError_.AddMember(GetDuplicatesString(), duplicates, GetStateAllocator()); + AddCurrentError(kValidateErrorUniqueItems, true); + } + + void TooManyProperties(SizeType actualCount, SizeType expectedCount) { + AddNumberError(kValidateErrorMaxProperties, + ValueType(actualCount).Move(), SValue(expectedCount).Move()); + } + void TooFewProperties(SizeType actualCount, SizeType expectedCount) { + AddNumberError(kValidateErrorMinProperties, + ValueType(actualCount).Move(), SValue(expectedCount).Move()); + } + void StartMissingProperties() { + currentError_.SetArray(); + } + void AddMissingProperty(const SValue& name) { + currentError_.PushBack(ValueType(name, GetStateAllocator()).Move(), GetStateAllocator()); + } + bool EndMissingProperties() { + if (currentError_.Empty()) + return false; + ValueType error(kObjectType); + error.AddMember(GetMissingString(), currentError_, GetStateAllocator()); + currentError_ = error; + AddCurrentError(kValidateErrorRequired); + return true; + } + void PropertyViolations(ISchemaValidator** subvalidators, SizeType count) { + for (SizeType i = 0; i < count; ++i) + MergeError(static_cast(subvalidators[i])->GetError()); + } + void DisallowedProperty(const Ch* name, SizeType length) { + currentError_.SetObject(); + currentError_.AddMember(GetDisallowedString(), ValueType(name, length, GetStateAllocator()).Move(), GetStateAllocator()); + AddCurrentError(kValidateErrorAdditionalProperties, true); + } + + void StartDependencyErrors() { + currentError_.SetObject(); + } + void StartMissingDependentProperties() { + missingDependents_.SetArray(); + } + void AddMissingDependentProperty(const SValue& targetName) { + missingDependents_.PushBack(ValueType(targetName, GetStateAllocator()).Move(), GetStateAllocator()); + } + void EndMissingDependentProperties(const SValue& sourceName) { + if (!missingDependents_.Empty()) { + // Create equivalent 'required' error + ValueType error(kObjectType); + ValidateErrorCode code = kValidateErrorRequired; + error.AddMember(GetMissingString(), missingDependents_.Move(), GetStateAllocator()); + AddErrorCode(error, code); + AddErrorInstanceLocation(error, false); + // When appending to a pointer ensure its allocator is used + PointerType schemaRef = GetInvalidSchemaPointer().Append(SchemaType::GetValidateErrorKeyword(kValidateErrorDependencies), &GetInvalidSchemaPointer().GetAllocator()); + AddErrorSchemaLocation(error, schemaRef.Append(sourceName.GetString(), sourceName.GetStringLength(), &GetInvalidSchemaPointer().GetAllocator())); + ValueType wrapper(kObjectType); + wrapper.AddMember(ValueType(SchemaType::GetValidateErrorKeyword(code), GetStateAllocator()).Move(), error, GetStateAllocator()); + currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(), wrapper, GetStateAllocator()); + } + } + void AddDependencySchemaError(const SValue& sourceName, ISchemaValidator* subvalidator) { + currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(), + static_cast(subvalidator)->GetError(), GetStateAllocator()); + } + bool EndDependencyErrors() { + if (currentError_.ObjectEmpty()) + return false; + ValueType error(kObjectType); + error.AddMember(GetErrorsString(), currentError_, GetStateAllocator()); + currentError_ = error; + AddCurrentError(kValidateErrorDependencies); + return true; + } + + void DisallowedValue(const ValidateErrorCode code = kValidateErrorEnum) { + currentError_.SetObject(); + AddCurrentError(code); + } + void StartDisallowedType() { + currentError_.SetArray(); + } + void AddExpectedType(const typename SchemaType::ValueType& expectedType) { + currentError_.PushBack(ValueType(expectedType, GetStateAllocator()).Move(), GetStateAllocator()); + } + void EndDisallowedType(const typename SchemaType::ValueType& actualType) { + ValueType error(kObjectType); + error.AddMember(GetExpectedString(), currentError_, GetStateAllocator()); + error.AddMember(GetActualString(), ValueType(actualType, GetStateAllocator()).Move(), GetStateAllocator()); + currentError_ = error; + AddCurrentError(kValidateErrorType); + } + void NotAllOf(ISchemaValidator** subvalidators, SizeType count) { + // Treat allOf like oneOf and anyOf to match https://rapidjson.org/md_doc_schema.html#allOf-anyOf-oneOf + AddErrorArray(kValidateErrorAllOf, subvalidators, count); + //for (SizeType i = 0; i < count; ++i) { + // MergeError(static_cast(subvalidators[i])->GetError()); + //} + } + void NoneOf(ISchemaValidator** subvalidators, SizeType count) { + AddErrorArray(kValidateErrorAnyOf, subvalidators, count); + } + void NotOneOf(ISchemaValidator** subvalidators, SizeType count) { + AddErrorArray(kValidateErrorOneOf, subvalidators, count); + } + void MultipleOneOf(SizeType index1, SizeType index2) { + ValueType matches(kArrayType); + matches.PushBack(index1, GetStateAllocator()); + matches.PushBack(index2, GetStateAllocator()); + currentError_.SetObject(); + currentError_.AddMember(GetMatchesString(), matches, GetStateAllocator()); + AddCurrentError(kValidateErrorOneOfMatch); + } + void Disallowed() { + currentError_.SetObject(); + AddCurrentError(kValidateErrorNot); + } + void DisallowedWhenWriting() { + currentError_.SetObject(); + AddCurrentError(kValidateErrorReadOnly); + } + void DisallowedWhenReading() { + currentError_.SetObject(); + AddCurrentError(kValidateErrorWriteOnly); + } + +#define RAPIDJSON_STRING_(name, ...) \ + static const StringRefType& Get##name##String() {\ + static const Ch s[] = { __VA_ARGS__, '\0' };\ + static const StringRefType v(s, static_cast(sizeof(s) / sizeof(Ch) - 1)); \ + return v;\ + } + + RAPIDJSON_STRING_(InstanceRef, 'i', 'n', 's', 't', 'a', 'n', 'c', 'e', 'R', 'e', 'f') + RAPIDJSON_STRING_(SchemaRef, 's', 'c', 'h', 'e', 'm', 'a', 'R', 'e', 'f') + RAPIDJSON_STRING_(Expected, 'e', 'x', 'p', 'e', 'c', 't', 'e', 'd') + RAPIDJSON_STRING_(Actual, 'a', 'c', 't', 'u', 'a', 'l') + RAPIDJSON_STRING_(Disallowed, 'd', 'i', 's', 'a', 'l', 'l', 'o', 'w', 'e', 'd') + RAPIDJSON_STRING_(Missing, 'm', 'i', 's', 's', 'i', 'n', 'g') + RAPIDJSON_STRING_(Errors, 'e', 'r', 'r', 'o', 'r', 's') + RAPIDJSON_STRING_(ErrorCode, 'e', 'r', 'r', 'o', 'r', 'C', 'o', 'd', 'e') + RAPIDJSON_STRING_(ErrorMessage, 'e', 'r', 'r', 'o', 'r', 'M', 'e', 's', 's', 'a', 'g', 'e') + RAPIDJSON_STRING_(Duplicates, 'd', 'u', 'p', 'l', 'i', 'c', 'a', 't', 'e', 's') + RAPIDJSON_STRING_(Matches, 'm', 'a', 't', 'c', 'h', 'e', 's') + +#undef RAPIDJSON_STRING_ + +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\ + if (!valid_) return false; \ + if ((!BeginValue() && !GetContinueOnErrors()) || (!CurrentSchema().method arg1 && !GetContinueOnErrors())) {\ + *documentStack_.template Push() = '\0';\ + documentStack_.template Pop(1);\ + RAPIDJSON_SCHEMA_PRINT(InvalidDocument, documentStack_.template Bottom());\ + valid_ = false;\ + return valid_;\ + } + +#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\ + for (Context* context = schemaStack_.template Bottom(); context != schemaStack_.template End(); context++) {\ + if (context->hasher)\ + static_cast(context->hasher)->method arg2;\ + if (context->validators)\ + for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\ + static_cast(context->validators[i_])->method arg2;\ + if (context->patternPropertiesValidators)\ + for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\ + static_cast(context->patternPropertiesValidators[i_])->method arg2;\ + } + +#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ + valid_ = (EndValue() || GetContinueOnErrors()) && (!outputHandler_ || outputHandler_->method arg2);\ + return valid_; + +#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ + RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ + RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) + + bool Null() { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext()), ( )); } + bool Bool(bool b) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), b), (b)); } + bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); } + bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); } + bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); } + bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); } + bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); } + bool RawNumber(const Ch* str, SizeType length, bool copy) + { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } + bool String(const Ch* str, SizeType length, bool copy) + { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } + + bool StartObject() { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::StartObject"); + RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext())); + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ()); + valid_ = !outputHandler_ || outputHandler_->StartObject(); + return valid_; + } + + bool Key(const Ch* str, SizeType len, bool copy) { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::Key", str); + if (!valid_) return false; + AppendToken(str, len); + if (!CurrentSchema().Key(CurrentContext(), str, len, copy) && !GetContinueOnErrors()) { + valid_ = false; + return valid_; + } + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy)); + valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy); + return valid_; + } + + bool EndObject(SizeType memberCount) { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::EndObject"); + if (!valid_) return false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount)); + if (!CurrentSchema().EndObject(CurrentContext(), memberCount) && !GetContinueOnErrors()) { + valid_ = false; + return valid_; + } + RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount)); + } + + bool StartArray() { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::StartArray"); + RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext())); + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ()); + valid_ = !outputHandler_ || outputHandler_->StartArray(); + return valid_; + } + + bool EndArray(SizeType elementCount) { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::EndArray"); + if (!valid_) return false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount)); + if (!CurrentSchema().EndArray(CurrentContext(), elementCount) && !GetContinueOnErrors()) { + valid_ = false; + return valid_; + } + RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount)); + } + +#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ +#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ +#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ + + // Implementation of ISchemaStateFactory + virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root, const bool inheritContinueOnErrors) { + *documentStack_.template Push() = '\0'; + documentStack_.template Pop(1); + ISchemaValidator* sv = new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root, documentStack_.template Bottom(), documentStack_.GetSize(), + depth_ + 1, + &GetStateAllocator()); + sv->SetValidateFlags(inheritContinueOnErrors ? GetValidateFlags() : GetValidateFlags() & ~(unsigned)kValidateContinueOnErrorFlag); + return sv; + } + + virtual void DestroySchemaValidator(ISchemaValidator* validator) { + GenericSchemaValidator* v = static_cast(validator); + v->~GenericSchemaValidator(); + StateAllocator::Free(v); + } + + virtual void* CreateHasher() { + return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator()); + } + + virtual uint64_t GetHashCode(void* hasher) { + return static_cast(hasher)->GetHashCode(); + } + + virtual void DestroyHasher(void* hasher) { + HasherType* h = static_cast(hasher); + h->~HasherType(); + StateAllocator::Free(h); + } + + virtual void* MallocState(size_t size) { + return GetStateAllocator().Malloc(size); + } + + virtual void FreeState(void* p) { + StateAllocator::Free(p); + } + // End of implementation of ISchemaStateFactory + +private: + typedef typename SchemaType::Context Context; + typedef GenericValue, StateAllocator> HashCodeArray; + typedef internal::Hasher HasherType; + + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + const SchemaType& root, + const char* basePath, size_t basePathSize, + unsigned depth, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(root), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + outputHandler_(0), + error_(kObjectType), + currentError_(), + missingDependents_(), + valid_(true), + flags_(kValidateDefaultFlags), + depth_(depth) + { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::GenericSchemaValidator (internal)", basePath && basePathSize ? basePath : ""); + if (basePath && basePathSize) + memcpy(documentStack_.template Push(basePathSize), basePath, basePathSize); + } + + StateAllocator& GetStateAllocator() { + if (!stateAllocator_) + stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator)(); + return *stateAllocator_; + } + + bool GetContinueOnErrors() const { + return flags_ & kValidateContinueOnErrorFlag; + } + + bool BeginValue() { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::BeginValue"); + if (schemaStack_.Empty()) + PushSchema(root_); + else { + if (CurrentContext().inArray) + internal::TokenHelper, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex); + + if (!CurrentSchema().BeginValue(CurrentContext()) && !GetContinueOnErrors()) + return false; + + SizeType count = CurrentContext().patternPropertiesSchemaCount; + const SchemaType** sa = CurrentContext().patternPropertiesSchemas; + typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType; + bool valueUniqueness = CurrentContext().valueUniqueness; + RAPIDJSON_ASSERT(CurrentContext().valueSchema); + PushSchema(*CurrentContext().valueSchema); + + if (count > 0) { + CurrentContext().objectPatternValidatorType = patternValidatorType; + ISchemaValidator**& va = CurrentContext().patternPropertiesValidators; + SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount; + va = static_cast(MallocState(sizeof(ISchemaValidator*) * count)); + std::memset(va, 0, sizeof(ISchemaValidator*) * count); + for (SizeType i = 0; i < count; i++) + va[validatorCount++] = CreateSchemaValidator(*sa[i], true); // Inherit continueOnError + } + + CurrentContext().arrayUniqueness = valueUniqueness; + } + return true; + } + + bool EndValue() { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::EndValue"); + if (!CurrentSchema().EndValue(CurrentContext()) && !GetContinueOnErrors()) + return false; + + GenericStringBuffer sb; + schemaDocument_->GetPointer(&CurrentSchema()).StringifyUriFragment(sb); + *documentStack_.template Push() = '\0'; + documentStack_.template Pop(1); + RAPIDJSON_SCHEMA_PRINT(ValidatorPointers, sb.GetString(), documentStack_.template Bottom(), depth_); + void* hasher = CurrentContext().hasher; + uint64_t h = hasher && CurrentContext().arrayUniqueness ? static_cast(hasher)->GetHashCode() : 0; + + PopSchema(); + + if (!schemaStack_.Empty()) { + Context& context = CurrentContext(); + // Only check uniqueness if there is a hasher + if (hasher && context.valueUniqueness) { + HashCodeArray* a = static_cast(context.arrayElementHashCodes); + if (!a) + CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType); + for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr) + if (itr->GetUint64() == h) { + DuplicateItems(static_cast(itr - a->Begin()), a->Size()); + // Cleanup before returning if continuing + if (GetContinueOnErrors()) { + a->PushBack(h, GetStateAllocator()); + while (!documentStack_.Empty() && *documentStack_.template Pop(1) != '/'); + } + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorUniqueItems); + } + a->PushBack(h, GetStateAllocator()); + } + } + + // Remove the last token of document pointer + while (!documentStack_.Empty() && *documentStack_.template Pop(1) != '/') + ; + + return true; + } + + void AppendToken(const Ch* str, SizeType len) { + documentStack_.template Reserve(1 + len * 2); // worst case all characters are escaped as two characters + *documentStack_.template PushUnsafe() = '/'; + for (SizeType i = 0; i < len; i++) { + if (str[i] == '~') { + *documentStack_.template PushUnsafe() = '~'; + *documentStack_.template PushUnsafe() = '0'; + } + else if (str[i] == '/') { + *documentStack_.template PushUnsafe() = '~'; + *documentStack_.template PushUnsafe() = '1'; + } + else + *documentStack_.template PushUnsafe() = str[i]; + } + } + + RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push()) Context(*this, *this, &schema, flags_); } + + RAPIDJSON_FORCEINLINE void PopSchema() { + Context* c = schemaStack_.template Pop(1); + if (HashCodeArray* a = static_cast(c->arrayElementHashCodes)) { + a->~HashCodeArray(); + StateAllocator::Free(a); + } + c->~Context(); + } + + void AddErrorInstanceLocation(ValueType& result, bool parent) { + GenericStringBuffer sb; + PointerType instancePointer = GetInvalidDocumentPointer(); + ((parent && instancePointer.GetTokenCount() > 0) + ? PointerType(instancePointer.GetTokens(), instancePointer.GetTokenCount() - 1) + : instancePointer).StringifyUriFragment(sb); + ValueType instanceRef(sb.GetString(), static_cast(sb.GetSize() / sizeof(Ch)), + GetStateAllocator()); + result.AddMember(GetInstanceRefString(), instanceRef, GetStateAllocator()); + } + + void AddErrorSchemaLocation(ValueType& result, PointerType schema = PointerType()) { + GenericStringBuffer sb; + SizeType len = CurrentSchema().GetURI().GetStringLength(); + if (len) memcpy(sb.Push(len), CurrentSchema().GetURI().GetString(), len * sizeof(Ch)); + if (schema.GetTokenCount()) schema.StringifyUriFragment(sb); + else GetInvalidSchemaPointer().StringifyUriFragment(sb); + ValueType schemaRef(sb.GetString(), static_cast(sb.GetSize() / sizeof(Ch)), + GetStateAllocator()); + result.AddMember(GetSchemaRefString(), schemaRef, GetStateAllocator()); + } + + void AddErrorCode(ValueType& result, const ValidateErrorCode code) { + result.AddMember(GetErrorCodeString(), code, GetStateAllocator()); + } + + void AddError(ValueType& keyword, ValueType& error) { + typename ValueType::MemberIterator member = error_.FindMember(keyword); + if (member == error_.MemberEnd()) + error_.AddMember(keyword, error, GetStateAllocator()); + else { + if (member->value.IsObject()) { + ValueType errors(kArrayType); + errors.PushBack(member->value, GetStateAllocator()); + member->value = errors; + } + member->value.PushBack(error, GetStateAllocator()); + } + } + + void AddCurrentError(const ValidateErrorCode code, bool parent = false) { + AddErrorCode(currentError_, code); + AddErrorInstanceLocation(currentError_, parent); + AddErrorSchemaLocation(currentError_); + AddError(ValueType(SchemaType::GetValidateErrorKeyword(code), GetStateAllocator(), false).Move(), currentError_); + } + + void MergeError(ValueType& other) { + for (typename ValueType::MemberIterator it = other.MemberBegin(), end = other.MemberEnd(); it != end; ++it) { + AddError(it->name, it->value); + } + } + + void AddNumberError(const ValidateErrorCode code, ValueType& actual, const SValue& expected, + const typename SchemaType::ValueType& (*exclusive)() = 0) { + currentError_.SetObject(); + currentError_.AddMember(GetActualString(), actual, GetStateAllocator()); + currentError_.AddMember(GetExpectedString(), ValueType(expected, GetStateAllocator()).Move(), GetStateAllocator()); + if (exclusive) + currentError_.AddMember(ValueType(exclusive(), GetStateAllocator()).Move(), true, GetStateAllocator()); + AddCurrentError(code); + } + + void AddErrorArray(const ValidateErrorCode code, + ISchemaValidator** subvalidators, SizeType count) { + ValueType errors(kArrayType); + for (SizeType i = 0; i < count; ++i) + errors.PushBack(static_cast(subvalidators[i])->GetError(), GetStateAllocator()); + currentError_.SetObject(); + currentError_.AddMember(GetErrorsString(), errors, GetStateAllocator()); + AddCurrentError(code); + } + + const SchemaType& CurrentSchema() const { return *schemaStack_.template Top()->schema; } + Context& CurrentContext() { return *schemaStack_.template Top(); } + const Context& CurrentContext() const { return *schemaStack_.template Top(); } + + static const size_t kDefaultSchemaStackCapacity = 1024; + static const size_t kDefaultDocumentStackCapacity = 256; + const SchemaDocumentType* schemaDocument_; + const SchemaType& root_; + StateAllocator* stateAllocator_; + StateAllocator* ownStateAllocator_; + internal::Stack schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *) + internal::Stack documentStack_; //!< stack to store the current path of validating document (Ch) + OutputHandler* outputHandler_; + ValueType error_; + ValueType currentError_; + ValueType missingDependents_; + bool valid_; + unsigned flags_; + unsigned depth_; +}; + +typedef GenericSchemaValidator SchemaValidator; + +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidatingReader + +//! A helper class for parsing with validation. +/*! + This helper class is a functor, designed as a parameter of \ref GenericDocument::Populate(). + + \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam SourceEncoding Encoding of the input stream. + \tparam SchemaDocumentType Type of schema document. + \tparam StackAllocator Allocator type for stack. +*/ +template < + unsigned parseFlags, + typename InputStream, + typename SourceEncoding, + typename SchemaDocumentType = SchemaDocument, + typename StackAllocator = CrtAllocator> +class SchemaValidatingReader { +public: + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename InputStream::Ch Ch; + typedef GenericValue ValueType; + + //! Constructor + /*! + \param is Input stream. + \param sd Schema document. + */ + SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), invalidSchemaCode_(kValidateErrorNone), error_(kObjectType), isValid_(true) {} + + template + bool operator()(Handler& handler) { + GenericReader reader; + GenericSchemaValidator validator(sd_, handler); + parseResult_ = reader.template Parse(is_, validator); + + isValid_ = validator.IsValid(); + if (isValid_) { + invalidSchemaPointer_ = PointerType(); + invalidSchemaKeyword_ = 0; + invalidDocumentPointer_ = PointerType(); + error_.SetObject(); + } + else { + invalidSchemaPointer_ = validator.GetInvalidSchemaPointer(); + invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword(); + invalidSchemaCode_ = validator.GetInvalidSchemaCode(); + invalidDocumentPointer_ = validator.GetInvalidDocumentPointer(); + error_.CopyFrom(validator.GetError(), allocator_); + } + + return parseResult_; + } + + const ParseResult& GetParseResult() const { return parseResult_; } + bool IsValid() const { return isValid_; } + const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; } + const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; } + const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; } + const ValueType& GetError() const { return error_; } + ValidateErrorCode GetInvalidSchemaCode() const { return invalidSchemaCode_; } + +private: + InputStream& is_; + const SchemaDocumentType& sd_; + + ParseResult parseResult_; + PointerType invalidSchemaPointer_; + const Ch* invalidSchemaKeyword_; + PointerType invalidDocumentPointer_; + ValidateErrorCode invalidSchemaCode_; + StackAllocator allocator_; + ValueType error_; + bool isValid_; +}; + +RAPIDJSON_NAMESPACE_END +RAPIDJSON_DIAG_POP + +#endif // RAPIDJSON_SCHEMA_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/stream.h b/test/include/liblvgl/libs/thorvg/rapidjson/stream.h new file mode 100644 index 00000000..1fd70915 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/stream.h @@ -0,0 +1,223 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include "rapidjson.h" + +#ifndef RAPIDJSON_STREAM_H_ +#define RAPIDJSON_STREAM_H_ + +#include "encodings.h" + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Stream + +/*! \class rapidjson::Stream + \brief Concept for reading and writing characters. + + For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). + + For write-only stream, only need to implement Put() and Flush(). + +\code +concept Stream { + typename Ch; //!< Character type of the stream. + + //! Read the current character from stream without moving the read cursor. + Ch Peek() const; + + //! Read the current character from stream and moving the read cursor to next character. + Ch Take(); + + //! Get the current read cursor. + //! \return Number of characters read from start. + size_t Tell(); + + //! Begin writing operation at the current read pointer. + //! \return The begin writer pointer. + Ch* PutBegin(); + + //! Write a character. + void Put(Ch c); + + //! Flush the buffer. + void Flush(); + + //! End the writing operation. + //! \param begin The begin write pointer returned by PutBegin(). + //! \return Number of characters written. + size_t PutEnd(Ch* begin); +} +\endcode +*/ + +//! Provides additional information for stream. +/*! + By using traits pattern, this type provides a default configuration for stream. + For custom stream, this type can be specialized for other configuration. + See TEST(Reader, CustomStringStream) in readertest.cpp for example. +*/ +template +struct StreamTraits { + //! Whether to make local copy of stream for optimization during parsing. + /*! + By default, for safety, streams do not use local copy optimization. + Stream that can be copied fast should specialize this, like StreamTraits. + */ + enum { copyOptimization = 0 }; +}; + +//! Reserve n characters for writing to a stream. +template +inline void PutReserve(Stream& stream, size_t count) { + (void)stream; + (void)count; +} + +//! Write character to a stream, presuming buffer is reserved. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { + stream.Put(c); +} + +//! Put N copies of a character to a stream. +template +inline void PutN(Stream& stream, Ch c, size_t n) { + PutReserve(stream, n); + for (size_t i = 0; i < n; i++) + PutUnsafe(stream, c); +} + +/////////////////////////////////////////////////////////////////////////////// +// GenericStreamWrapper + +//! A Stream Wrapper +/*! \tThis string stream is a wrapper for any stream by just forwarding any + \treceived message to the origin stream. + \note implements Stream concept +*/ + +#if defined(_MSC_VER) && _MSC_VER <= 1800 +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4702) // unreachable code +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +template > +class GenericStreamWrapper { +public: + typedef typename Encoding::Ch Ch; + GenericStreamWrapper(InputStream& is): is_(is) {} + + Ch Peek() const { return is_.Peek(); } + Ch Take() { return is_.Take(); } + size_t Tell() { return is_.Tell(); } + Ch* PutBegin() { return is_.PutBegin(); } + void Put(Ch ch) { is_.Put(ch); } + void Flush() { is_.Flush(); } + size_t PutEnd(Ch* ch) { return is_.PutEnd(ch); } + + // wrapper for MemoryStream + const Ch* Peek4() const { return is_.Peek4(); } + + // wrapper for AutoUTFInputStream + UTFType GetType() const { return is_.GetType(); } + bool HasBOM() const { return is_.HasBOM(); } + +protected: + InputStream& is_; +}; + +#if defined(_MSC_VER) && _MSC_VER <= 1800 +RAPIDJSON_DIAG_POP +#endif + +/////////////////////////////////////////////////////////////////////////////// +// StringStream + +//! Read-only string stream. +/*! \note implements Stream concept +*/ +template +struct GenericStringStream { + typedef typename Encoding::Ch Ch; + + GenericStringStream(const Ch *src) : src_(src), head_(src) {} + + Ch Peek() const { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() const { return static_cast(src_ - head_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! String stream with UTF8 encoding. +typedef GenericStringStream > StringStream; + +/////////////////////////////////////////////////////////////////////////////// +// InsituStringStream + +//! A read-write string stream. +/*! This string stream is particularly designed for in-situ parsing. + \note implements Stream concept +*/ +template +struct GenericInsituStringStream { + typedef typename Encoding::Ch Ch; + + GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} + + // Read + Ch Peek() { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() { return static_cast(src_ - head_); } + + // Write + void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } + + Ch* PutBegin() { return dst_ = src_; } + size_t PutEnd(Ch* begin) { return static_cast(dst_ - begin); } + void Flush() {} + + Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } + void Pop(size_t count) { dst_ -= count; } + + Ch* src_; + Ch* dst_; + Ch* head_; +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! Insitu string stream with UTF8 encoding. +typedef GenericInsituStringStream > InsituStringStream; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STREAM_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/stringbuffer.h b/test/include/liblvgl/libs/thorvg/rapidjson/stringbuffer.h new file mode 100644 index 00000000..17bfeac9 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/stringbuffer.h @@ -0,0 +1,121 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRINGBUFFER_H_ +#define RAPIDJSON_STRINGBUFFER_H_ + +#include "stream.h" +#include "internal/stack.h" + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include // std::move +#endif + +#include "internal/stack.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output stream. +/*! + \tparam Encoding Encoding of the stream. + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +class GenericStringBuffer { +public: + typedef typename Encoding::Ch Ch; + + GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} + GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { + if (&rhs != this) + stack_ = std::move(rhs.stack_); + return *this; + } +#endif + + void Put(Ch c) { *stack_.template Push() = c; } + void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.ShrinkToFit(); + stack_.template Pop(1); + } + + void Reserve(size_t count) { stack_.template Reserve(count); } + Ch* Push(size_t count) { return stack_.template Push(count); } + Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetString() const { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.template Pop(1); + + return stack_.template Bottom(); + } + + //! Get the size of string in bytes in the string buffer. + size_t GetSize() const { return stack_.GetSize(); } + + //! Get the length of string in Ch in the string buffer. + size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; + +private: + // Prohibit copy constructor & assignment operator. + GenericStringBuffer(const GenericStringBuffer&); + GenericStringBuffer& operator=(const GenericStringBuffer&); +}; + +//! String buffer with UTF8 encoding +typedef GenericStringBuffer > StringBuffer; + +template +inline void PutReserve(GenericStringBuffer& stream, size_t count) { + stream.Reserve(count); +} + +template +inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { + stream.PutUnsafe(c); +} + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { + std::memset(stream.stack_.Push(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_STRINGBUFFER_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/uri.h b/test/include/liblvgl/libs/thorvg/rapidjson/uri.h new file mode 100644 index 00000000..f93e508a --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/uri.h @@ -0,0 +1,481 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// (C) Copyright IBM Corporation 2021 +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_URI_H_ +#define RAPIDJSON_URI_H_ + +#include "internal/strfunc.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// GenericUri + +template +class GenericUri { +public: + typedef typename ValueType::Ch Ch; +#if RAPIDJSON_HAS_STDSTRING + typedef std::basic_string String; +#endif + + //! Constructors + GenericUri(Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + } + + GenericUri(const Ch* uri, SizeType len, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + Parse(uri, len); + } + + GenericUri(const Ch* uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + Parse(uri, internal::StrLen(uri)); + } + + // Use with specializations of GenericValue + template GenericUri(const T& uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + const Ch* u = uri.template Get(); // TypeHelper from document.h + Parse(u, internal::StrLen(u)); + } + +#if RAPIDJSON_HAS_STDSTRING + GenericUri(const String& uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + Parse(uri.c_str(), internal::StrLen(uri.c_str())); + } +#endif + + //! Copy constructor + GenericUri(const GenericUri& rhs) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(), ownAllocator_() { + *this = rhs; + } + + //! Copy constructor + GenericUri(const GenericUri& rhs, Allocator* allocator) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + *this = rhs; + } + + //! Destructor. + ~GenericUri() { + Free(); + RAPIDJSON_DELETE(ownAllocator_); + } + + //! Assignment operator + GenericUri& operator=(const GenericUri& rhs) { + if (this != &rhs) { + // Do not delete ownAllocator + Free(); + Allocate(rhs.GetStringLength()); + auth_ = CopyPart(scheme_, rhs.scheme_, rhs.GetSchemeStringLength()); + path_ = CopyPart(auth_, rhs.auth_, rhs.GetAuthStringLength()); + query_ = CopyPart(path_, rhs.path_, rhs.GetPathStringLength()); + frag_ = CopyPart(query_, rhs.query_, rhs.GetQueryStringLength()); + base_ = CopyPart(frag_, rhs.frag_, rhs.GetFragStringLength()); + uri_ = CopyPart(base_, rhs.base_, rhs.GetBaseStringLength()); + CopyPart(uri_, rhs.uri_, rhs.GetStringLength()); + } + return *this; + } + + //! Getters + // Use with specializations of GenericValue + template void Get(T& uri, Allocator& allocator) { + uri.template Set(this->GetString(), allocator); // TypeHelper from document.h + } + + const Ch* GetString() const { return uri_; } + SizeType GetStringLength() const { return uri_ == 0 ? 0 : internal::StrLen(uri_); } + const Ch* GetBaseString() const { return base_; } + SizeType GetBaseStringLength() const { return base_ == 0 ? 0 : internal::StrLen(base_); } + const Ch* GetSchemeString() const { return scheme_; } + SizeType GetSchemeStringLength() const { return scheme_ == 0 ? 0 : internal::StrLen(scheme_); } + const Ch* GetAuthString() const { return auth_; } + SizeType GetAuthStringLength() const { return auth_ == 0 ? 0 : internal::StrLen(auth_); } + const Ch* GetPathString() const { return path_; } + SizeType GetPathStringLength() const { return path_ == 0 ? 0 : internal::StrLen(path_); } + const Ch* GetQueryString() const { return query_; } + SizeType GetQueryStringLength() const { return query_ == 0 ? 0 : internal::StrLen(query_); } + const Ch* GetFragString() const { return frag_; } + SizeType GetFragStringLength() const { return frag_ == 0 ? 0 : internal::StrLen(frag_); } + +#if RAPIDJSON_HAS_STDSTRING + static String Get(const GenericUri& uri) { return String(uri.GetString(), uri.GetStringLength()); } + static String GetBase(const GenericUri& uri) { return String(uri.GetBaseString(), uri.GetBaseStringLength()); } + static String GetScheme(const GenericUri& uri) { return String(uri.GetSchemeString(), uri.GetSchemeStringLength()); } + static String GetAuth(const GenericUri& uri) { return String(uri.GetAuthString(), uri.GetAuthStringLength()); } + static String GetPath(const GenericUri& uri) { return String(uri.GetPathString(), uri.GetPathStringLength()); } + static String GetQuery(const GenericUri& uri) { return String(uri.GetQueryString(), uri.GetQueryStringLength()); } + static String GetFrag(const GenericUri& uri) { return String(uri.GetFragString(), uri.GetFragStringLength()); } +#endif + + //! Equality operators + bool operator==(const GenericUri& rhs) const { + return Match(rhs, true); + } + + bool operator!=(const GenericUri& rhs) const { + return !Match(rhs, true); + } + + bool Match(const GenericUri& uri, bool full = true) const { + Ch* s1; + Ch* s2; + if (full) { + s1 = uri_; + s2 = uri.uri_; + } else { + s1 = base_; + s2 = uri.base_; + } + if (s1 == s2) return true; + if (s1 == 0 || s2 == 0) return false; + return internal::StrCmp(s1, s2) == 0; + } + + //! Resolve this URI against another (base) URI in accordance with URI resolution rules. + // See https://tools.ietf.org/html/rfc3986 + // Use for resolving an id or $ref with an in-scope id. + // Returns a new GenericUri for the resolved URI. + GenericUri Resolve(const GenericUri& baseuri, Allocator* allocator = 0) { + GenericUri resuri; + resuri.allocator_ = allocator; + // Ensure enough space for combining paths + resuri.Allocate(GetStringLength() + baseuri.GetStringLength() + 1); // + 1 for joining slash + + if (!(GetSchemeStringLength() == 0)) { + // Use all of this URI + resuri.auth_ = CopyPart(resuri.scheme_, scheme_, GetSchemeStringLength()); + resuri.path_ = CopyPart(resuri.auth_, auth_, GetAuthStringLength()); + resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength()); + resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength()); + resuri.RemoveDotSegments(); + } else { + // Use the base scheme + resuri.auth_ = CopyPart(resuri.scheme_, baseuri.scheme_, baseuri.GetSchemeStringLength()); + if (!(GetAuthStringLength() == 0)) { + // Use this auth, path, query + resuri.path_ = CopyPart(resuri.auth_, auth_, GetAuthStringLength()); + resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength()); + resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength()); + resuri.RemoveDotSegments(); + } else { + // Use the base auth + resuri.path_ = CopyPart(resuri.auth_, baseuri.auth_, baseuri.GetAuthStringLength()); + if (GetPathStringLength() == 0) { + // Use the base path + resuri.query_ = CopyPart(resuri.path_, baseuri.path_, baseuri.GetPathStringLength()); + if (GetQueryStringLength() == 0) { + // Use the base query + resuri.frag_ = CopyPart(resuri.query_, baseuri.query_, baseuri.GetQueryStringLength()); + } else { + // Use this query + resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength()); + } + } else { + if (path_[0] == '/') { + // Absolute path - use all of this path + resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength()); + resuri.RemoveDotSegments(); + } else { + // Relative path - append this path to base path after base path's last slash + size_t pos = 0; + if (!(baseuri.GetAuthStringLength() == 0) && baseuri.GetPathStringLength() == 0) { + resuri.path_[pos] = '/'; + pos++; + } + size_t lastslashpos = baseuri.GetPathStringLength(); + while (lastslashpos > 0) { + if (baseuri.path_[lastslashpos - 1] == '/') break; + lastslashpos--; + } + std::memcpy(&resuri.path_[pos], baseuri.path_, lastslashpos * sizeof(Ch)); + pos += lastslashpos; + resuri.query_ = CopyPart(&resuri.path_[pos], path_, GetPathStringLength()); + resuri.RemoveDotSegments(); + } + // Use this query + resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength()); + } + } + } + // Always use this frag + resuri.base_ = CopyPart(resuri.frag_, frag_, GetFragStringLength()); + + // Re-constitute base_ and uri_ + resuri.SetBase(); + resuri.uri_ = resuri.base_ + resuri.GetBaseStringLength() + 1; + resuri.SetUri(); + return resuri; + } + + //! Get the allocator of this GenericUri. + Allocator& GetAllocator() { return *allocator_; } + +private: + // Allocate memory for a URI + // Returns total amount allocated + std::size_t Allocate(std::size_t len) { + // Create own allocator if user did not supply. + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + + // Allocate one block containing each part of the URI (5) plus base plus full URI, all null terminated. + // Order: scheme, auth, path, query, frag, base, uri + // Note need to set, increment, assign in 3 stages to avoid compiler warning bug. + size_t total = (3 * len + 7) * sizeof(Ch); + scheme_ = static_cast(allocator_->Malloc(total)); + *scheme_ = '\0'; + auth_ = scheme_; + auth_++; + *auth_ = '\0'; + path_ = auth_; + path_++; + *path_ = '\0'; + query_ = path_; + query_++; + *query_ = '\0'; + frag_ = query_; + frag_++; + *frag_ = '\0'; + base_ = frag_; + base_++; + *base_ = '\0'; + uri_ = base_; + uri_++; + *uri_ = '\0'; + return total; + } + + // Free memory for a URI + void Free() { + if (scheme_) { + Allocator::Free(scheme_); + scheme_ = 0; + } + } + + // Parse a URI into constituent scheme, authority, path, query, & fragment parts + // Supports URIs that match regex ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? as per + // https://tools.ietf.org/html/rfc3986 + void Parse(const Ch* uri, std::size_t len) { + std::size_t start = 0, pos1 = 0, pos2 = 0; + Allocate(len); + + // Look for scheme ([^:/?#]+):)? + if (start < len) { + while (pos1 < len) { + if (uri[pos1] == ':') break; + pos1++; + } + if (pos1 != len) { + while (pos2 < len) { + if (uri[pos2] == '/') break; + if (uri[pos2] == '?') break; + if (uri[pos2] == '#') break; + pos2++; + } + if (pos1 < pos2) { + pos1++; + std::memcpy(scheme_, &uri[start], pos1 * sizeof(Ch)); + scheme_[pos1] = '\0'; + start = pos1; + } + } + } + // Look for auth (//([^/?#]*))? + // Note need to set, increment, assign in 3 stages to avoid compiler warning bug. + auth_ = scheme_ + GetSchemeStringLength(); + auth_++; + *auth_ = '\0'; + if (start < len - 1 && uri[start] == '/' && uri[start + 1] == '/') { + pos2 = start + 2; + while (pos2 < len) { + if (uri[pos2] == '/') break; + if (uri[pos2] == '?') break; + if (uri[pos2] == '#') break; + pos2++; + } + std::memcpy(auth_, &uri[start], (pos2 - start) * sizeof(Ch)); + auth_[pos2 - start] = '\0'; + start = pos2; + } + // Look for path ([^?#]*) + // Note need to set, increment, assign in 3 stages to avoid compiler warning bug. + path_ = auth_ + GetAuthStringLength(); + path_++; + *path_ = '\0'; + if (start < len) { + pos2 = start; + while (pos2 < len) { + if (uri[pos2] == '?') break; + if (uri[pos2] == '#') break; + pos2++; + } + if (start != pos2) { + std::memcpy(path_, &uri[start], (pos2 - start) * sizeof(Ch)); + path_[pos2 - start] = '\0'; + if (path_[0] == '/') + RemoveDotSegments(); // absolute path - normalize + start = pos2; + } + } + // Look for query (\?([^#]*))? + // Note need to set, increment, assign in 3 stages to avoid compiler warning bug. + query_ = path_ + GetPathStringLength(); + query_++; + *query_ = '\0'; + if (start < len && uri[start] == '?') { + pos2 = start + 1; + while (pos2 < len) { + if (uri[pos2] == '#') break; + pos2++; + } + if (start != pos2) { + std::memcpy(query_, &uri[start], (pos2 - start) * sizeof(Ch)); + query_[pos2 - start] = '\0'; + start = pos2; + } + } + // Look for fragment (#(.*))? + // Note need to set, increment, assign in 3 stages to avoid compiler warning bug. + frag_ = query_ + GetQueryStringLength(); + frag_++; + *frag_ = '\0'; + if (start < len && uri[start] == '#') { + std::memcpy(frag_, &uri[start], (len - start) * sizeof(Ch)); + frag_[len - start] = '\0'; + } + + // Re-constitute base_ and uri_ + base_ = frag_ + GetFragStringLength() + 1; + SetBase(); + uri_ = base_ + GetBaseStringLength() + 1; + SetUri(); + } + + // Reconstitute base + void SetBase() { + Ch* next = base_; + std::memcpy(next, scheme_, GetSchemeStringLength() * sizeof(Ch)); + next+= GetSchemeStringLength(); + std::memcpy(next, auth_, GetAuthStringLength() * sizeof(Ch)); + next+= GetAuthStringLength(); + std::memcpy(next, path_, GetPathStringLength() * sizeof(Ch)); + next+= GetPathStringLength(); + std::memcpy(next, query_, GetQueryStringLength() * sizeof(Ch)); + next+= GetQueryStringLength(); + *next = '\0'; + } + + // Reconstitute uri + void SetUri() { + Ch* next = uri_; + std::memcpy(next, base_, GetBaseStringLength() * sizeof(Ch)); + next+= GetBaseStringLength(); + std::memcpy(next, frag_, GetFragStringLength() * sizeof(Ch)); + next+= GetFragStringLength(); + *next = '\0'; + } + + // Copy a part from one GenericUri to another + // Return the pointer to the next part to be copied to + Ch* CopyPart(Ch* to, Ch* from, std::size_t len) { + RAPIDJSON_ASSERT(to != 0); + RAPIDJSON_ASSERT(from != 0); + std::memcpy(to, from, len * sizeof(Ch)); + to[len] = '\0'; + Ch* next = to + len + 1; + return next; + } + + // Remove . and .. segments from the path_ member. + // https://tools.ietf.org/html/rfc3986 + // This is done in place as we are only removing segments. + void RemoveDotSegments() { + std::size_t pathlen = GetPathStringLength(); + std::size_t pathpos = 0; // Position in path_ + std::size_t newpos = 0; // Position in new path_ + + // Loop through each segment in original path_ + while (pathpos < pathlen) { + // Get next segment, bounded by '/' or end + size_t slashpos = 0; + while ((pathpos + slashpos) < pathlen) { + if (path_[pathpos + slashpos] == '/') break; + slashpos++; + } + // Check for .. and . segments + if (slashpos == 2 && path_[pathpos] == '.' && path_[pathpos + 1] == '.') { + // Backup a .. segment in the new path_ + // We expect to find a previously added slash at the end or nothing + RAPIDJSON_ASSERT(newpos == 0 || path_[newpos - 1] == '/'); + size_t lastslashpos = newpos; + // Make sure we don't go beyond the start segment + if (lastslashpos > 1) { + // Find the next to last slash and back up to it + lastslashpos--; + while (lastslashpos > 0) { + if (path_[lastslashpos - 1] == '/') break; + lastslashpos--; + } + // Set the new path_ position + newpos = lastslashpos; + } + } else if (slashpos == 1 && path_[pathpos] == '.') { + // Discard . segment, leaves new path_ unchanged + } else { + // Move any other kind of segment to the new path_ + RAPIDJSON_ASSERT(newpos <= pathpos); + std::memmove(&path_[newpos], &path_[pathpos], slashpos * sizeof(Ch)); + newpos += slashpos; + // Add slash if not at end + if ((pathpos + slashpos) < pathlen) { + path_[newpos] = '/'; + newpos++; + } + } + // Move to next segment + pathpos += slashpos + 1; + } + path_[newpos] = '\0'; + } + + Ch* uri_; // Everything + Ch* base_; // Everything except fragment + Ch* scheme_; // Includes the : + Ch* auth_; // Includes the // + Ch* path_; // Absolute if starts with / + Ch* query_; // Includes the ? + Ch* frag_; // Includes the # + + Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_. + Allocator* ownAllocator_; //!< Allocator owned by this Uri. +}; + +//! GenericUri for Value (UTF-8, default allocator). +typedef GenericUri Uri; + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_URI_H_ diff --git a/test/include/liblvgl/libs/thorvg/rapidjson/writer.h b/test/include/liblvgl/libs/thorvg/rapidjson/writer.h new file mode 100644 index 00000000..81f34fc8 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/rapidjson/writer.h @@ -0,0 +1,710 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_WRITER_H_ +#define RAPIDJSON_WRITER_H_ + +#include "stream.h" +#include "internal/clzll.h" +#include "internal/meta.h" +#include "internal/stack.h" +#include "internal/strfunc.h" +#include "internal/dtoa.h" +#include "internal/itoa.h" +#include "stringbuffer.h" +#include // placement new + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#elif defined(RAPIDJSON_NEON) +#include +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(c++98-compat) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// WriteFlag + +/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kWriteDefaultFlags definition. + + User can define this as any \c WriteFlag combinations. +*/ +#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS +#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags +#endif + +//! Combination of writeFlags +enum WriteFlag { + kWriteNoFlags = 0, //!< No flags are set. + kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings. + kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN. + kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS +}; + +//! JSON writer +/*! Writer implements the concept Handler. + It generates JSON text by events to an output os. + + User may programmatically calls the functions of a writer to generate JSON text. + + On the other side, a writer can also be passed to objects that generates events, + + for example Reader::Parse() and Document::Accept(). + + \tparam OutputStream Type of output stream. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. + \note implements Handler concept +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> +class Writer { +public: + typedef typename SourceEncoding::Ch Ch; + + static const int kDefaultMaxDecimalPlaces = 324; + + //! Constructor + /*! \param os Output stream. + \param stackAllocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit + Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} + + explicit + Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Writer(Writer&& rhs) : + os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) { + rhs.os_ = 0; + } +#endif + + //! Reset the writer with a new stream. + /*! + This function reset the writer with a new stream and default settings, + in order to make a Writer object reusable for output multiple JSONs. + + \param os New output stream. + \code + Writer writer(os1); + writer.StartObject(); + // ... + writer.EndObject(); + + writer.Reset(os2); + writer.StartObject(); + // ... + writer.EndObject(); + \endcode + */ + void Reset(OutputStream& os) { + os_ = &os; + hasRoot_ = false; + level_stack_.Clear(); + } + + //! Checks whether the output is a complete JSON. + /*! + A complete JSON has a complete root object or array. + */ + bool IsComplete() const { + return hasRoot_ && level_stack_.Empty(); + } + + int GetMaxDecimalPlaces() const { + return maxDecimalPlaces_; + } + + //! Sets the maximum number of decimal places for double output. + /*! + This setting truncates the output with specified number of decimal places. + + For example, + + \code + writer.SetMaxDecimalPlaces(3); + writer.StartArray(); + writer.Double(0.12345); // "0.123" + writer.Double(0.0001); // "0.0" + writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent) + writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent) + writer.EndArray(); + \endcode + + The default setting does not truncate any decimal places. You can restore to this setting by calling + \code + writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces); + \endcode + */ + void SetMaxDecimalPlaces(int maxDecimalPlaces) { + maxDecimalPlaces_ = maxDecimalPlaces; + } + + /*!@name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { Prefix(kNullType); return EndValue(WriteNull()); } + bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); } + bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); } + bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); } + bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); } + bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); } + + //! Writes the given \c double value to the stream + /*! + \param d The value to be written. + \return Whether it is succeed. + */ + bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); } + + bool RawNumber(const Ch* str, SizeType length, bool copy = false) { + RAPIDJSON_ASSERT(str != 0); + (void)copy; + Prefix(kNumberType); + return EndValue(WriteString(str, length)); + } + + bool String(const Ch* str, SizeType length, bool copy = false) { + RAPIDJSON_ASSERT(str != 0); + (void)copy; + Prefix(kStringType); + return EndValue(WriteString(str, length)); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + Prefix(kObjectType); + new (level_stack_.template Push()) Level(false); + return WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + +#if RAPIDJSON_HAS_STDSTRING + bool Key(const std::basic_string& str) + { + return Key(str.data(), SizeType(str.size())); + } +#endif + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object + RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); // currently inside an Array, not Object + RAPIDJSON_ASSERT(0 == level_stack_.template Top()->valueCount % 2); // Object has a Key without a Value + level_stack_.template Pop(1); + return EndValue(WriteEndObject()); + } + + bool StartArray() { + Prefix(kArrayType); + new (level_stack_.template Push()) Level(true); + return WriteStartArray(); + } + + bool EndArray(SizeType elementCount = 0) { + (void)elementCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + return EndValue(WriteEndArray()); + } + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* const& str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* const& str) { return Key(str, internal::StrLen(str)); } + + //@} + + //! Write a raw JSON value. + /*! + For user to write a stringified JSON as a value. + + \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. + \param length Length of the json. + \param type Type of the root of json. + */ + bool RawValue(const Ch* json, size_t length, Type type) { + RAPIDJSON_ASSERT(json != 0); + Prefix(type); + return EndValue(WriteRawValue(json, length)); + } + + //! Flush the output stream. + /*! + Allows the user to flush the output stream immediately. + */ + void Flush() { + os_->Flush(); + } + + static const size_t kDefaultLevelDepth = 32; + +protected: + //! Information for each nested level + struct Level { + Level(bool inArray_) : valueCount(0), inArray(inArray_) {} + size_t valueCount; //!< number of values in this level + bool inArray; //!< true if in array, otherwise in object + }; + + bool WriteNull() { + PutReserve(*os_, 4); + PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true; + } + + bool WriteBool(bool b) { + if (b) { + PutReserve(*os_, 4); + PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e'); + } + else { + PutReserve(*os_, 5); + PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e'); + } + return true; + } + + bool WriteInt(int i) { + char buffer[11]; + const char* end = internal::i32toa(i, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteUint(unsigned u) { + char buffer[10]; + const char* end = internal::u32toa(u, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteInt64(int64_t i64) { + char buffer[21]; + const char* end = internal::i64toa(i64, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteUint64(uint64_t u64) { + char buffer[20]; + char* end = internal::u64toa(u64, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteDouble(double d) { + if (internal::Double(d).IsNanOrInf()) { + if (!(writeFlags & kWriteNanAndInfFlag)) + return false; + if (internal::Double(d).IsNan()) { + PutReserve(*os_, 3); + PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); + return true; + } + if (internal::Double(d).Sign()) { + PutReserve(*os_, 9); + PutUnsafe(*os_, '-'); + } + else + PutReserve(*os_, 8); + PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); + PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); + return true; + } + + char buffer[25]; + char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); + PutReserve(*os_, static_cast(end - buffer)); + for (char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteString(const Ch* str, SizeType length) { + static const typename OutputStream::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + static const char escape[256] = { +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 + 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 + Z16, Z16, // 30~4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF +#undef Z16 + }; + + if (TargetEncoding::supportUnicode) + PutReserve(*os_, 2 + length * 6); // "\uxxxx..." + else + PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..." + + PutUnsafe(*os_, '\"'); + GenericStringStream is(str); + while (ScanWriteUnescapedString(is, length)) { + const Ch c = is.Peek(); + if (!TargetEncoding::supportUnicode && static_cast(c) >= 0x80) { + // Unicode escaping + unsigned codepoint; + if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint))) + return false; + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { + PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint ) & 15]); + } + else { + RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF); + // Surrogate pair + unsigned s = codepoint - 0x010000; + unsigned lead = (s >> 10) + 0xD800; + unsigned trail = (s & 0x3FF) + 0xDC00; + PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(lead ) & 15]); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(trail ) & 15]); + } + } + else if ((sizeof(Ch) == 1 || static_cast(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast(c)])) { + is.Take(); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, static_cast(escape[static_cast(c)])); + if (escape[static_cast(c)] == 'u') { + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, hexDigits[static_cast(c) >> 4]); + PutUnsafe(*os_, hexDigits[static_cast(c) & 0xF]); + } + } + else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? + Transcoder::Validate(is, *os_) : + Transcoder::TranscodeUnsafe(is, *os_)))) + return false; + } + PutUnsafe(*os_, '\"'); + return true; + } + + bool ScanWriteUnescapedString(GenericStringStream& is, size_t length) { + return RAPIDJSON_LIKELY(is.Tell() < length); + } + + bool WriteStartObject() { os_->Put('{'); return true; } + bool WriteEndObject() { os_->Put('}'); return true; } + bool WriteStartArray() { os_->Put('['); return true; } + bool WriteEndArray() { os_->Put(']'); return true; } + + bool WriteRawValue(const Ch* json, size_t length) { + PutReserve(*os_, length); + GenericStringStream is(json); + while (RAPIDJSON_LIKELY(is.Tell() < length)) { + RAPIDJSON_ASSERT(is.Peek() != '\0'); + if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? + Transcoder::Validate(is, *os_) : + Transcoder::TranscodeUnsafe(is, *os_)))) + return false; + } + return true; + } + + void Prefix(Type type) { + (void)type; + if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root + Level* level = level_stack_.template Top(); + if (level->valueCount > 0) { + if (level->inArray) + os_->Put(','); // add comma if it is not the first element in array + else // in object + os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. + hasRoot_ = true; + } + } + + // Flush the value if it is the top level one. + bool EndValue(bool ret) { + if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text + Flush(); + return ret; + } + + OutputStream* os_; + internal::Stack level_stack_; + int maxDecimalPlaces_; + bool hasRoot_; + +private: + // Prohibit copy constructor & assignment operator. + Writer(const Writer&); + Writer& operator=(const Writer&); +}; + +// Full specialization for StringStream to prevent memory copying + +template<> +inline bool Writer::WriteInt(int i) { + char *buffer = os_->Push(11); + const char* end = internal::i32toa(i, buffer); + os_->Pop(static_cast(11 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteUint(unsigned u) { + char *buffer = os_->Push(10); + const char* end = internal::u32toa(u, buffer); + os_->Pop(static_cast(10 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteInt64(int64_t i64) { + char *buffer = os_->Push(21); + const char* end = internal::i64toa(i64, buffer); + os_->Pop(static_cast(21 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteUint64(uint64_t u) { + char *buffer = os_->Push(20); + const char* end = internal::u64toa(u, buffer); + os_->Pop(static_cast(20 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteDouble(double d) { + if (internal::Double(d).IsNanOrInf()) { + // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag). + if (!(kWriteDefaultFlags & kWriteNanAndInfFlag)) + return false; + if (internal::Double(d).IsNan()) { + PutReserve(*os_, 3); + PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); + return true; + } + if (internal::Double(d).Sign()) { + PutReserve(*os_, 9); + PutUnsafe(*os_, '-'); + } + else + PutReserve(*os_, 8); + PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); + PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); + return true; + } + + char *buffer = os_->Push(25); + char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); + os_->Pop(static_cast(25 - (end - buffer))); + return true; +} + +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) +template<> +inline bool Writer::ScanWriteUnescapedString(StringStream& is, size_t length) { + if (length < 16) + return RAPIDJSON_LIKELY(is.Tell() < length); + + if (!RAPIDJSON_LIKELY(is.Tell() < length)) + return false; + + const char* p = is.src_; + const char* end = is.head_ + length; + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + const char* endAligned = reinterpret_cast(reinterpret_cast(end) & static_cast(~15)); + if (nextAligned > end) + return true; + + while (p != nextAligned) + if (*p < 0x20 || *p == '\"' || *p == '\\') { + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); + } + else + os_->PutUnsafe(*p++); + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (; p != endAligned; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + SizeType len; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + len = offset; +#else + len = static_cast(__builtin_ffs(r) - 1); +#endif + char* q = reinterpret_cast(os_->PushUnsafe(len)); + for (size_t i = 0; i < len; i++) + q[i] = p[i]; + + p += len; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s); + } + + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); +} +#elif defined(RAPIDJSON_NEON) +template<> +inline bool Writer::ScanWriteUnescapedString(StringStream& is, size_t length) { + if (length < 16) + return RAPIDJSON_LIKELY(is.Tell() < length); + + if (!RAPIDJSON_LIKELY(is.Tell() < length)) + return false; + + const char* p = is.src_; + const char* end = is.head_ + length; + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + const char* endAligned = reinterpret_cast(reinterpret_cast(end) & static_cast(~15)); + if (nextAligned > end) + return true; + + while (p != nextAligned) + if (*p < 0x20 || *p == '\"' || *p == '\\') { + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); + } + else + os_->PutUnsafe(*p++); + + // The rest of string using SIMD + const uint8x16_t s0 = vmovq_n_u8('"'); + const uint8x16_t s1 = vmovq_n_u8('\\'); + const uint8x16_t s2 = vmovq_n_u8('\b'); + const uint8x16_t s3 = vmovq_n_u8(32); + + for (; p != endAligned; p += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, s0); + x = vorrq_u8(x, vceqq_u8(s, s1)); + x = vorrq_u8(x, vceqq_u8(s, s2)); + x = vorrq_u8(x, vcltq_u8(s, s3)); + + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + SizeType len = 0; + bool escaped = false; + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + len = 8 + (lz >> 3); + escaped = true; + } + } else { + uint32_t lz = internal::clzll(low); + len = lz >> 3; + escaped = true; + } + if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped + char* q = reinterpret_cast(os_->PushUnsafe(len)); + for (size_t i = 0; i < len; i++) + q[i] = p[i]; + + p += len; + break; + } + vst1q_u8(reinterpret_cast(os_->PushUnsafe(16)), s); + } + + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); +} +#endif // RAPIDJSON_NEON + +RAPIDJSON_NAMESPACE_END + +#if defined(_MSC_VER) || defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/test/include/liblvgl/libs/thorvg/thorvg.h b/test/include/liblvgl/libs/thorvg/thorvg.h new file mode 100644 index 00000000..da3944c5 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/thorvg.h @@ -0,0 +1,2182 @@ +#ifndef _THORVG_H_ +#define _THORVG_H_ + +#include "../../lv_conf_internal.h" + +/*Testing of dependencies*/ +#if LV_USE_THORVG && LV_USE_VECTOR_GRAPHIC == 0 +#error "ThorVG: LV_USE_VECTOR_GRAPHIC is required. Enable it in lv_conf.h" +#endif + +#if LV_USE_THORVG_INTERNAL +#define TVG_BUILD 1 + + +#include +#include +#include +#include + +#ifdef TVG_API + #undef TVG_API +#endif + +#ifndef TVG_STATIC + #ifdef _WIN32 + #if TVG_BUILD + #define TVG_API __declspec(dllexport) + #else + #define TVG_API __declspec(dllimport) + #endif + #elif (defined(__SUNPRO_C) || defined(__SUNPRO_CC)) + #define TVG_API __global + #else + #if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__INTEL_COMPILER) + #define TVG_API __attribute__ ((visibility("default"))) + #else + #define TVG_API + #endif + #endif +#else + #define TVG_API +#endif + +#ifdef TVG_DEPRECATED + #undef TVG_DEPRECATED +#endif + +#ifdef _WIN32 + #define TVG_DEPRECATED __declspec(deprecated) +#elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) + #define TVG_DEPRECATED __attribute__ ((__deprecated__)) +#else + #define TVG_DEPRECATED +#endif + +#define _TVG_DECLARE_PRIVATE(A) \ + struct Impl; \ + Impl* pImpl; \ +protected: \ + A(const A&) = delete; \ + const A& operator=(const A&) = delete; \ + A() + +#define _TVG_DISABLE_CTOR(A) \ + A() = delete; \ + ~A() = delete + +#define _TVG_DECLARE_ACCESSOR(A) \ + friend A + +namespace tvg +{ + +class RenderMethod; +class Animation; + +/** + * @defgroup ThorVG ThorVG + * @brief ThorVG classes and enumerations providing C++ APIs. + */ + +/**@{*/ + +/** + * @brief Enumeration specifying the result from the APIs. + */ +enum class Result +{ + Success = 0, ///< The value returned in case of a correct request execution. + InvalidArguments, ///< The value returned in the event of a problem with the arguments given to the API - e.g. empty paths or null pointers. + InsufficientCondition, ///< The value returned in case the request cannot be processed - e.g. asking for properties of an object, which does not exist. + FailedAllocation, ///< The value returned in case of unsuccessful memory allocation. + MemoryCorruption, ///< The value returned in the event of bad memory handling - e.g. failing in pointer releasing or casting + NonSupport, ///< The value returned in case of choosing unsupported options. + Unknown ///< The value returned in all other cases. +}; + + +/** + * @brief Enumeration specifying the values of the path commands accepted by TVG. + * + * Not to be confused with the path commands from the svg path element (like M, L, Q, H and many others). + * TVG interprets all of them and translates to the ones from the PathCommand values. + */ +enum class PathCommand +{ + Close = 0, ///< Ends the current sub-path and connects it with its initial point. This command doesn't expect any points. + MoveTo, ///< Sets a new initial point of the sub-path and a new current point. This command expects 1 point: the starting position. + LineTo, ///< Draws a line from the current point to the given point and sets a new value of the current point. This command expects 1 point: the end-position of the line. + CubicTo ///< Draws a cubic Bezier curve from the current point to the given point using two given control points and sets a new value of the current point. This command expects 3 points: the 1st control-point, the 2nd control-point, the end-point of the curve. +}; + + +/** + * @brief Enumeration determining the ending type of a stroke in the open sub-paths. + */ +enum class StrokeCap +{ + Square = 0, ///< The stroke is extended in both end-points of a sub-path by a rectangle, with the width equal to the stroke width and the length equal to the half of the stroke width. For zero length sub-paths the square is rendered with the size of the stroke width. + Round, ///< The stroke is extended in both end-points of a sub-path by a half circle, with a radius equal to the half of a stroke width. For zero length sub-paths a full circle is rendered. + Butt ///< The stroke ends exactly at each of the two end-points of a sub-path. For zero length sub-paths no stroke is rendered. +}; + + +/** + * @brief Enumeration determining the style used at the corners of joined stroked path segments. + */ +enum class StrokeJoin +{ + Bevel = 0, ///< The outer corner of the joined path segments is bevelled at the join point. The triangular region of the corner is enclosed by a straight line between the outer corners of each stroke. + Round, ///< The outer corner of the joined path segments is rounded. The circular region is centered at the join point. + Miter ///< The outer corner of the joined path segments is spiked. The spike is created by extension beyond the join point of the outer edges of the stroke until they intersect. In case the extension goes beyond the limit, the join style is converted to the Bevel style. +}; + + +/** + * @brief Enumeration specifying how to fill the area outside the gradient bounds. + */ +enum class FillSpread +{ + Pad = 0, ///< The remaining area is filled with the closest stop color. + Reflect, ///< The gradient pattern is reflected outside the gradient area until the expected region is filled. + Repeat ///< The gradient pattern is repeated continuously beyond the gradient area until the expected region is filled. +}; + + +/** + * @brief Enumeration specifying the algorithm used to establish which parts of the shape are treated as the inside of the shape. + */ +enum class FillRule +{ + Winding = 0, ///< A line from the point to a location outside the shape is drawn. The intersections of the line with the path segment of the shape are counted. Starting from zero, if the path segment of the shape crosses the line clockwise, one is added, otherwise one is subtracted. If the resulting sum is non zero, the point is inside the shape. + EvenOdd ///< A line from the point to a location outside the shape is drawn and its intersections with the path segments of the shape are counted. If the number of intersections is an odd number, the point is inside the shape. +}; + + +/** + * @brief Enumeration indicating the method used in the composition of two objects - the target and the source. + * + * Notation: S(Source), T(Target), SA(Source Alpha), TA(Target Alpha) + * + * @see Paint::composite() + */ +enum class CompositeMethod +{ + None = 0, ///< No composition is applied. + ClipPath, ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered. + AlphaMask, ///< Alpha Masking using the compositing target's pixels as an alpha value. + InvAlphaMask, ///< Alpha Masking using the complement to the compositing target's pixels as an alpha value. + LumaMask, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the compositing target's pixels. @since 0.9 + InvLumaMask, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the complement to the compositing target's pixels. + AddMask, ///< Combines the target and source objects pixels using target alpha. (T * TA) + (S * (255 - TA)) (Experimental API) + SubtractMask, ///< Subtracts the source color from the target color while considering their respective target alpha. (T * TA) - (S * (255 - TA)) (Experimental API) + IntersectMask, ///< Computes the result by taking the minimum value between the target alpha and the source alpha and multiplies it with the target color. (T * min(TA, SA)) (Experimental API) + DifferenceMask ///< Calculates the absolute difference between the target color and the source color multiplied by the complement of the target alpha. abs(T - S * (255 - TA)) (Experimental API) +}; + + +/** + * @brief Enumeration indicates the method used for blending paint. Please refer to the respective formulas for each method. + * + * Notation: S(source paint as the top layer), D(destination as the bottom layer), Sa(source paint alpha), Da(destination alpha) + * + * @see Paint::blend() + * + * @note Experimental API + */ +enum class BlendMethod : uint8_t +{ + Normal = 0, ///< Perform the alpha blending(default). S if (Sa == 255), otherwise (Sa * S) + (255 - Sa) * D + Add, ///< Simply adds pixel values of one layer with the other. (S + D) + Screen, ///< The values of the pixels in the two layers are inverted, multiplied, and then inverted again. (S + D) - (S * D) + Multiply, ///< Takes the RGB channel values from 0 to 255 of each pixel in the top layer and multiples them with the values for the corresponding pixel from the bottom layer. (S * D) + Overlay, ///< Combines Multiply and Screen blend modes. (2 * S * D) if (2 * D < Da), otherwise (Sa * Da) - 2 * (Da - S) * (Sa - D) + Difference, ///< Subtracts the bottom layer from the top layer or the other way around, to always get a non-negative value. (S - D) if (S > D), otherwise (D - S) + Exclusion, ///< The result is twice the product of the top and bottom layers, subtracted from their sum. s + d - (2 * s * d) + SrcOver, ///< Replace the bottom layer with the top layer. + Darken, ///< Creates a pixel that retains the smallest components of the top and bottom layer pixels. min(S, D) + Lighten, ///< Only has the opposite action of Darken Only. max(S, D) + ColorDodge, ///< Divides the bottom layer by the inverted top layer. D / (255 - S) + ColorBurn, ///< Divides the inverted bottom layer by the top layer, and then inverts the result. 255 - (255 - D) / S + HardLight, ///< The same as Overlay but with the color roles reversed. (2 * S * D) if (S < Sa), otherwise (Sa * Da) - 2 * (Da - S) * (Sa - D) + SoftLight ///< The same as Overlay but with applying pure black or white does not result in pure black or white. (1 - 2 * S) * (D ^ 2) + (2 * S * D) +}; + + +/** + * @brief Enumeration specifying the engine type used for the graphics backend. For multiple backends bitwise operation is allowed. + */ +enum class CanvasEngine +{ + Sw = (1 << 1), ///< CPU rasterizer. + Gl = (1 << 2), ///< OpenGL rasterizer. + Wg = (1 << 3), ///< WebGPU rasterizer. (Experimental API) +}; + + +/** + * @brief A data structure representing a point in two-dimensional space. + */ +struct Point +{ + float x, y; +}; + + +/** + * @brief A data structure representing a three-dimensional matrix. + * + * The elements e11, e12, e21 and e22 represent the rotation matrix, including the scaling factor. + * The elements e13 and e23 determine the translation of the object along the x and y-axis, respectively. + * The elements e31 and e32 are set to 0, e33 is set to 1. + */ +struct Matrix +{ + float e11, e12, e13; + float e21, e22, e23; + float e31, e32, e33; +}; + + +/** + * @brief A data structure representing a texture mesh vertex + * + * @param pt The vertex coordinate + * @param uv The normalized texture coordinate in the range (0.0..1.0, 0.0..1.0) + * + * @note Experimental API + */ +struct Vertex +{ + Point pt; + Point uv; +}; + + +/** + * @brief A data structure representing a triangle in a texture mesh + * + * @param vertex The three vertices that make up the polygon + * + * @note Experimental API + */ +struct Polygon +{ + Vertex vertex[3]; +}; + + +/** + * @class Paint + * + * @brief An abstract class for managing graphical elements. + * + * A graphical element in TVG is any object composed into a Canvas. + * Paint represents such a graphical object and its behaviors such as duplication, transformation and composition. + * TVG recommends the user to regard a paint as a set of volatile commands. They can prepare a Paint and then request a Canvas to run them. + */ +class TVG_API Paint +{ +public: + virtual ~Paint(); + + /** + * @brief Sets the angle by which the object is rotated. + * + * The angle in measured clockwise from the horizontal axis. + * The rotational axis passes through the point on the object with zero coordinates. + * + * @param[in] degree The value of the angle in degrees. + * + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result rotate(float degree) noexcept; + + /** + * @brief Sets the scale value of the object. + * + * @param[in] factor The value of the scaling factor. The default value is 1. + * + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result scale(float factor) noexcept; + + /** + * @brief Sets the values by which the object is moved in a two-dimensional space. + * + * The origin of the coordinate system is in the upper left corner of the canvas. + * The horizontal and vertical axes point to the right and down, respectively. + * + * @param[in] x The value of the horizontal shift. + * @param[in] y The value of the vertical shift. + * + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result translate(float x, float y) noexcept; + + /** + * @brief Sets the matrix of the affine transformation for the object. + * + * The augmented matrix of the transformation is expected to be given. + * + * @param[in] m The 3x3 augmented matrix. + * + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result transform(const Matrix& m) noexcept; + + /** + * @brief Gets the matrix of the affine transformation of the object. + * + * The values of the matrix can be set by the transform() API, as well by the translate(), + * scale() and rotate(). In case no transformation was applied, the identity matrix is returned. + * + * @return The augmented transformation matrix. + * + * @since 0.4 + */ + Matrix transform() noexcept; + + /** + * @brief Sets the opacity of the object. + * + * @param[in] o The opacity value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. + * + * @retval Result::Success when succeed. + * + * @note Setting the opacity with this API may require multiple render pass for composition. It is recommended to avoid changing the opacity if possible. + * @note ClipPath won't use the opacity value. (see: enum class CompositeMethod::ClipPath) + */ + Result opacity(uint8_t o) noexcept; + + /** + * @brief Sets the composition target object and the composition method. + * + * @param[in] target The paint of the target object. + * @param[in] method The method used to composite the source object with the target. + * + * @retval Result::Success when succeed, Result::InvalidArguments otherwise. + */ + Result composite(std::unique_ptr target, CompositeMethod method) noexcept; + + /** + * @brief Sets the blending method for the paint object. + * + * The blending feature allows you to combine colors to create visually appealing effects, including transparency, lighting, shading, and color mixing, among others. + * its process involves the combination of colors or images from the source paint object with the destination (the lower layer image) using blending operations. + * The blending operation is determined by the chosen @p BlendMethod, which specifies how the colors or images are combined. + * + * @param[in] method The blending method to be set. + * + * @retval Result::Success when the blending method is successfully set. + * + * @note Experimental API + */ + Result blend(BlendMethod method) const noexcept; + + /** + * @brief Gets the bounding box of the paint object before any transformation. + * + * @param[out] x The x coordinate of the upper left corner of the object. + * @param[out] y The y coordinate of the upper left corner of the object. + * @param[out] w The width of the object. + * @param[out] h The height of the object. + * + * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @note The bounding box doesn't indicate the final rendered region. It's the smallest rectangle that encloses the object. + * @see Paint::bounds(float* x, float* y, float* w, float* h, bool transformed); + * @deprecated Use bounds(float* x, float* y, float* w, float* h, bool transformed) instead + */ + TVG_DEPRECATED Result bounds(float* x, float* y, float* w, float* h) const noexcept; + + /** + * @brief Gets the axis-aligned bounding box of the paint object. + * + * In case @p transform is @c true, all object's transformations are applied first, and then the bounding box is established. Otherwise, the bounding box is determined before any transformations. + * + * @param[out] x The x coordinate of the upper left corner of the object. + * @param[out] y The y coordinate of the upper left corner of the object. + * @param[out] w The width of the object. + * @param[out] h The height of the object. + * @param[in] transformed If @c true, the paint's transformations are taken into account, otherwise they aren't. + * + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @note The bounding box doesn't indicate the actual drawing region. It's the smallest rectangle that encloses the object. + */ + Result bounds(float* x, float* y, float* w, float* h, bool transformed) const noexcept; + + /** + * @brief Duplicates the object. + * + * Creates a new object and sets its all properties as in the original object. + * + * @return The created object when succeed, @c nullptr otherwise. + */ + Paint* duplicate() const noexcept; + + /** + * @brief Gets the opacity value of the object. + * + * @return The opacity value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. + */ + uint8_t opacity() const noexcept; + + /** + * @brief Gets the composition target object and the composition method. + * + * @param[out] target The paint of the target object. + * + * @return The method used to composite the source object with the target. + * + * @since 0.5 + */ + CompositeMethod composite(const Paint** target) const noexcept; + + /** + * @brief Gets the blending method of the object. + * + * @return The blending method + * + * @note Experimental API + */ + BlendMethod blend() const noexcept; + + /** + * @brief Return the unique id value of the paint instance. + * + * This method can be called for checking the current concrete instance type. + * + * @return The type id of the Paint instance. + */ + uint32_t identifier() const noexcept; + + _TVG_DECLARE_PRIVATE(Paint); +}; + + +/** + * @class Fill + * + * @brief An abstract class representing the gradient fill of the Shape object. + * + * It contains the information about the gradient colors and their arrangement + * inside the gradient bounds. The gradients bounds are defined in the LinearGradient + * or RadialGradient class, depending on the type of the gradient to be used. + * It specifies the gradient behavior in case the area defined by the gradient bounds + * is smaller than the area to be filled. + */ +class TVG_API Fill +{ +public: + /** + * @brief A data structure storing the information about the color and its relative position inside the gradient bounds. + */ + struct ColorStop + { + float offset; /**< The relative position of the color. */ + uint8_t r; /**< The red color channel value in the range [0 ~ 255]. */ + uint8_t g; /**< The green color channel value in the range [0 ~ 255]. */ + uint8_t b; /**< The blue color channel value in the range [0 ~ 255]. */ + uint8_t a; /**< The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. */ + }; + + virtual ~Fill(); + + /** + * @brief Sets the parameters of the colors of the gradient and their position. + * + * @param[in] colorStops An array of ColorStop data structure. + * @param[in] cnt The count of the @p colorStops array equal to the colors number used in the gradient. + * + * @retval Result::Success when succeed. + */ + Result colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept; + + /** + * @brief Sets the FillSpread value, which specifies how to fill the area outside the gradient bounds. + * + * @param[in] s The FillSpread value. + * + * @retval Result::Success when succeed. + */ + Result spread(FillSpread s) noexcept; + + /** + * @brief Sets the matrix of the affine transformation for the gradient fill. + * + * The augmented matrix of the transformation is expected to be given. + * + * @param[in] m The 3x3 augmented matrix. + * + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result transform(const Matrix& m) noexcept; + + /** + * @brief Gets the parameters of the colors of the gradient, their position and number. + * + * @param[out] colorStops A pointer to the memory location, where the array of the gradient's ColorStop is stored. + * + * @return The number of colors used in the gradient. This value corresponds to the length of the @p colorStops array. + */ + uint32_t colorStops(const ColorStop** colorStops) const noexcept; + + /** + * @brief Gets the FillSpread value of the fill. + * + * @return The FillSpread value of this Fill. + */ + FillSpread spread() const noexcept; + + /** + * @brief Gets the matrix of the affine transformation of the gradient fill. + * + * In case no transformation was applied, the identity matrix is returned. + * + * @return The augmented transformation matrix. + */ + Matrix transform() const noexcept; + + /** + * @brief Creates a copy of the Fill object. + * + * Return a newly created Fill object with the properties copied from the original. + * + * @return A copied Fill object when succeed, @c nullptr otherwise. + */ + Fill* duplicate() const noexcept; + + /** + * @brief Return the unique id value of the Fill instance. + * + * This method can be called for checking the current concrete instance type. + * + * @return The type id of the Fill instance. + */ + uint32_t identifier() const noexcept; + + _TVG_DECLARE_PRIVATE(Fill); +}; + + +/** + * @class Canvas + * + * @brief An abstract class for drawing graphical elements. + * + * A canvas is an entity responsible for drawing the target. It sets up the drawing engine and the buffer, which can be drawn on the screen. It also manages given Paint objects. + * + * @note A Canvas behavior depends on the raster engine though the final content of the buffer is expected to be identical. + * @warning The Paint objects belonging to one Canvas can't be shared among multiple Canvases. + */ +class TVG_API Canvas +{ +public: + Canvas(RenderMethod*); + virtual ~Canvas(); + + /** + * @brief Sets the size of the container, where all the paints pushed into the Canvas are stored. + * + * If the number of objects pushed into the Canvas is known in advance, calling the function + * prevents multiple memory reallocation, thus improving the performance. + * + * @param[in] n The number of objects for which the memory is to be reserved. + * + * @return Result::Success when succeed. + */ + TVG_DEPRECATED Result reserve(uint32_t n) noexcept; + + /** + * @brief Returns the list of the paints that currently held by the Canvas. + * + * This function provides the list of paint nodes, allowing users a direct opportunity to modify the scene tree. + * + * @warning Please avoid accessing the paints during Canvas update/draw. You can access them after calling sync(). + * @see Canvas::sync() + * + * @note Experimental API + */ + std::list& paints() noexcept; + + /** + * @brief Passes drawing elements to the Canvas using Paint objects. + * + * Only pushed paints in the canvas will be drawing targets. + * They are retained by the canvas until you call Canvas::clear(). + * + * @param[in] paint A Paint object to be drawn. + * + * @retval Result::Success When succeed. + * @retval Result::MemoryCorruption In case a @c nullptr is passed as the argument. + * @retval Result::InsufficientCondition An internal error. + * + * @note The rendering order of the paints is the same as the order as they were pushed into the canvas. Consider sorting the paints before pushing them if you intend to use layering. + * @see Canvas::paints() + * @see Canvas::clear() + */ + virtual Result push(std::unique_ptr paint) noexcept; + + /** + * @brief Clear the internal canvas resources that used for the drawing. + * + * This API sets the total number of paints pushed into the canvas to zero. + * Depending on the value of the @p free argument, the paints are either freed or retained. + * So if you need to update paint properties while maintaining the existing scene structure, you can set @p free = false. + * + * @param[in] free If @c true, the memory occupied by paints is deallocated, otherwise it is not. + * + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @see Canvas::push() + * @see Canvas::paints() + */ + virtual Result clear(bool free = true) noexcept; + + /** + * @brief Request the canvas to update the paint objects. + * + * If a @c nullptr is passed all paint objects retained by the Canvas are updated, + * otherwise only the paint to which the given @p paint points. + * + * @param[in] paint A pointer to the Paint object or @c nullptr. + * + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @note The Update behavior can be asynchronous if the assigned thread number is greater than zero. + */ + virtual Result update(Paint* paint = nullptr) noexcept; + + /** + * @brief Requests the canvas to draw the Paint objects. + * + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @note Drawing can be asynchronous if the assigned thread number is greater than zero. To guarantee the drawing is done, call sync() afterwards. + * @see Canvas::sync() + */ + virtual Result draw() noexcept; + + /** + * @brief Sets the drawing region in the canvas. + * + * This function defines the rectangular area of the canvas that will be used for drawing operations. + * The specified viewport is used to clip the rendering output to the boundaries of the rectangle. + * + * @param[in] x The x-coordinate of the upper-left corner of the rectangle. + * @param[in] y The y-coordinate of the upper-left corner of the rectangle. + * @param[in] w The width of the rectangle. + * @param[in] h The height of the rectangle. + * + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @see SwCanvas::target() + * @see GlCanvas::target() + * @see WgCanvas::target() + * + * @warning It's not allowed to change the viewport during Canvas::push() - Canvas::sync() or Canvas::update() - Canvas::sync(). + * + * @note When resetting the target, the viewport will also be reset to the target size. + * @note Experimental API + */ + virtual Result viewport(int32_t x, int32_t y, int32_t w, int32_t h) noexcept; + + /** + * @brief Guarantees that drawing task is finished. + * + * The Canvas rendering can be performed asynchronously. To make sure that rendering is finished, + * the sync() must be called after the draw() regardless of threading. + * + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. + * @see Canvas::draw() + */ + virtual Result sync() noexcept; + + _TVG_DECLARE_PRIVATE(Canvas); +}; + + +/** + * @class LinearGradient + * + * @brief A class representing the linear gradient fill of the Shape object. + * + * Besides the APIs inherited from the Fill class, it enables setting and getting the linear gradient bounds. + * The behavior outside the gradient bounds depends on the value specified in the spread API. + */ +class TVG_API LinearGradient final : public Fill +{ +public: + ~LinearGradient(); + + /** + * @brief Sets the linear gradient bounds. + * + * The bounds of the linear gradient are defined as a surface constrained by two parallel lines crossing + * the given points (@p x1, @p y1) and (@p x2, @p y2), respectively. Both lines are perpendicular to the line linking + * (@p x1, @p y1) and (@p x2, @p y2). + * + * @param[in] x1 The horizontal coordinate of the first point used to determine the gradient bounds. + * @param[in] y1 The vertical coordinate of the first point used to determine the gradient bounds. + * @param[in] x2 The horizontal coordinate of the second point used to determine the gradient bounds. + * @param[in] y2 The vertical coordinate of the second point used to determine the gradient bounds. + * + * @retval Result::Success when succeed. + * + * @note In case the first and the second points are equal, an object filled with such a gradient fill is not rendered. + */ + Result linear(float x1, float y1, float x2, float y2) noexcept; + + /** + * @brief Gets the linear gradient bounds. + * + * The bounds of the linear gradient are defined as a surface constrained by two parallel lines crossing + * the given points (@p x1, @p y1) and (@p x2, @p y2), respectively. Both lines are perpendicular to the line linking + * (@p x1, @p y1) and (@p x2, @p y2). + * + * @param[out] x1 The horizontal coordinate of the first point used to determine the gradient bounds. + * @param[out] y1 The vertical coordinate of the first point used to determine the gradient bounds. + * @param[out] x2 The horizontal coordinate of the second point used to determine the gradient bounds. + * @param[out] y2 The vertical coordinate of the second point used to determine the gradient bounds. + * + * @retval Result::Success when succeed. + */ + Result linear(float* x1, float* y1, float* x2, float* y2) const noexcept; + + /** + * @brief Creates a new LinearGradient object. + * + * @return A new LinearGradient object. + */ + static std::unique_ptr gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the LinearGradient class type. + * + * @return The type id of the LinearGradient class. + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(LinearGradient); +}; + + +/** + * @class RadialGradient + * + * @brief A class representing the radial gradient fill of the Shape object. + * + */ +class TVG_API RadialGradient final : public Fill +{ +public: + ~RadialGradient(); + + /** + * @brief Sets the radial gradient bounds. + * + * The radial gradient bounds are defined as a circle centered in a given point (@p cx, @p cy) of a given radius. + * + * @param[in] cx The horizontal coordinate of the center of the bounding circle. + * @param[in] cy The vertical coordinate of the center of the bounding circle. + * @param[in] radius The radius of the bounding circle. + * + * @retval Result::Success when succeed, Result::InvalidArguments in case the @p radius value is zero or less. + */ + Result radial(float cx, float cy, float radius) noexcept; + + /** + * @brief Gets the radial gradient bounds. + * + * The radial gradient bounds are defined as a circle centered in a given point (@p cx, @p cy) of a given radius. + * + * @param[out] cx The horizontal coordinate of the center of the bounding circle. + * @param[out] cy The vertical coordinate of the center of the bounding circle. + * @param[out] radius The radius of the bounding circle. + * + * @retval Result::Success when succeed. + */ + Result radial(float* cx, float* cy, float* radius) const noexcept; + + /** + * @brief Creates a new RadialGradient object. + * + * @return A new RadialGradient object. + */ + static std::unique_ptr gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the RadialGradient class type. + * + * @return The type id of the RadialGradient class. + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(RadialGradient); +}; + + +/** + * @class Shape + * + * @brief A class representing two-dimensional figures and their properties. + * + * A shape has three major properties: shape outline, stroking, filling. The outline in the Shape is retained as the path. + * Path can be composed by accumulating primitive commands such as moveTo(), lineTo(), cubicTo(), or complete shape interfaces such as appendRect(), appendCircle(), etc. + * Path can consists of sub-paths. One sub-path is determined by a close command. + * + * The stroke of Shape is an optional property in case the Shape needs to be represented with/without the outline borders. + * It's efficient since the shape path and the stroking path can be shared with each other. It's also convenient when controlling both in one context. + */ +class TVG_API Shape final : public Paint +{ +public: + ~Shape(); + + /** + * @brief Resets the properties of the shape path. + * + * The transformation matrix, the color, the fill and the stroke properties are retained. + * + * @retval Result::Success when succeed. + * + * @note The memory, where the path data is stored, is not deallocated at this stage for caching effect. + */ + Result reset() noexcept; + + /** + * @brief Sets the initial point of the sub-path. + * + * The value of the current point is set to the given point. + * + * @param[in] x The horizontal coordinate of the initial point of the sub-path. + * @param[in] y The vertical coordinate of the initial point of the sub-path. + * + * @retval Result::Success when succeed. + */ + Result moveTo(float x, float y) noexcept; + + /** + * @brief Adds a new point to the sub-path, which results in drawing a line from the current point to the given end-point. + * + * The value of the current point is set to the given end-point. + * + * @param[in] x The horizontal coordinate of the end-point of the line. + * @param[in] y The vertical coordinate of the end-point of the line. + * + * @retval Result::Success when succeed. + * + * @note In case this is the first command in the path, it corresponds to the moveTo() call. + */ + Result lineTo(float x, float y) noexcept; + + /** + * @brief Adds new points to the sub-path, which results in drawing a cubic Bezier curve starting + * at the current point and ending at the given end-point (@p x, @p y) using the control points (@p cx1, @p cy1) and (@p cx2, @p cy2). + * + * The value of the current point is set to the given end-point. + * + * @param[in] cx1 The horizontal coordinate of the 1st control point. + * @param[in] cy1 The vertical coordinate of the 1st control point. + * @param[in] cx2 The horizontal coordinate of the 2nd control point. + * @param[in] cy2 The vertical coordinate of the 2nd control point. + * @param[in] x The horizontal coordinate of the end-point of the curve. + * @param[in] y The vertical coordinate of the end-point of the curve. + * + * @retval Result::Success when succeed. + * + * @note In case this is the first command in the path, no data from the path are rendered. + */ + Result cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) noexcept; + + /** + * @brief Closes the current sub-path by drawing a line from the current point to the initial point of the sub-path. + * + * The value of the current point is set to the initial point of the closed sub-path. + * + * @retval Result::Success when succeed. + * + * @note In case the sub-path does not contain any points, this function has no effect. + */ + Result close() noexcept; + + /** + * @brief Appends a rectangle to the path. + * + * The rectangle with rounded corners can be achieved by setting non-zero values to @p rx and @p ry arguments. + * The @p rx and @p ry values specify the radii of the ellipse defining the rounding of the corners. + * + * The position of the rectangle is specified by the coordinates of its upper left corner - @p x and @p y arguments. + * + * The rectangle is treated as a new sub-path - it is not connected with the previous sub-path. + * + * The value of the current point is set to (@p x + @p rx, @p y) - in case @p rx is greater + * than @p w/2 the current point is set to (@p x + @p w/2, @p y) + * + * @param[in] x The horizontal coordinate of the upper left corner of the rectangle. + * @param[in] y The vertical coordinate of the upper left corner of the rectangle. + * @param[in] w The width of the rectangle. + * @param[in] h The height of the rectangle. + * @param[in] rx The x-axis radius of the ellipse defining the rounded corners of the rectangle. + * @param[in] ry The y-axis radius of the ellipse defining the rounded corners of the rectangle. + * + * @retval Result::Success when succeed. + * + * @note For @p rx and @p ry greater than or equal to the half of @p w and the half of @p h, respectively, the shape become an ellipse. + */ + Result appendRect(float x, float y, float w, float h, float rx = 0, float ry = 0) noexcept; + + /** + * @brief Appends an ellipse to the path. + * + * The position of the ellipse is specified by the coordinates of its center - @p cx and @p cy arguments. + * + * The ellipse is treated as a new sub-path - it is not connected with the previous sub-path. + * + * The value of the current point is set to (@p cx, @p cy - @p ry). + * + * @param[in] cx The horizontal coordinate of the center of the ellipse. + * @param[in] cy The vertical coordinate of the center of the ellipse. + * @param[in] rx The x-axis radius of the ellipse. + * @param[in] ry The y-axis radius of the ellipse. + * + * @retval Result::Success when succeed. + */ + Result appendCircle(float cx, float cy, float rx, float ry) noexcept; + + /** + * @brief Appends a circular arc to the path. + * + * The arc is treated as a new sub-path - it is not connected with the previous sub-path. + * The current point value is set to the end-point of the arc in case @p pie is @c false, and to the center of the arc otherwise. + * + * @param[in] cx The horizontal coordinate of the center of the arc. + * @param[in] cy The vertical coordinate of the center of the arc. + * @param[in] radius The radius of the arc. + * @param[in] startAngle The start angle of the arc given in degrees, measured counter-clockwise from the horizontal line. + * @param[in] sweep The central angle of the arc given in degrees, measured counter-clockwise from @p startAngle. + * @param[in] pie Specifies whether to draw radii from the arc's center to both of its end-point - drawn if @c true. + * + * @retval Result::Success when succeed. + * + * @note Setting @p sweep value greater than 360 degrees, is equivalent to calling appendCircle(cx, cy, radius, radius). + */ + Result appendArc(float cx, float cy, float radius, float startAngle, float sweep, bool pie) noexcept; + + /** + * @brief Appends a given sub-path to the path. + * + * The current point value is set to the last point from the sub-path. + * For each command from the @p cmds array, an appropriate number of points in @p pts array should be specified. + * If the number of points in the @p pts array is different than the number required by the @p cmds array, the shape with this sub-path will not be displayed on the screen. + * + * @param[in] cmds The array of the commands in the sub-path. + * @param[in] cmdCnt The number of the sub-path's commands. + * @param[in] pts The array of the two-dimensional points. + * @param[in] ptsCnt The number of the points in the @p pts array. + * + * @retval Result::Success when succeed, Result::InvalidArguments otherwise. + * + * @note The interface is designed for optimal path setting if the caller has a completed path commands already. + */ + Result appendPath(const PathCommand* cmds, uint32_t cmdCnt, const Point* pts, uint32_t ptsCnt) noexcept; + + /** + * @brief Sets the stroke width for all of the figures from the path. + * + * @param[in] width The width of the stroke. The default value is 0. + * + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result stroke(float width) noexcept; + + /** + * @brief Sets the color of the stroke for all of the figures from the path. + * + * @param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. The default value is 0. + * + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result stroke(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) noexcept; + + /** + * @brief Sets the gradient fill of the stroke for all of the figures from the path. + * + * @param[in] f The gradient fill. + * + * @retval Result::Success When succeed. + * @retval Result::FailedAllocation An internal error with a memory allocation for an object to be filled. + * @retval Result::MemoryCorruption In case a @c nullptr is passed as the argument. + */ + Result stroke(std::unique_ptr f) noexcept; + + /** + * @brief Sets the dash pattern of the stroke. + * + * @param[in] dashPattern The array of consecutive pair values of the dash length and the gap length. + * @param[in] cnt The length of the @p dashPattern array. + * + * @retval Result::Success When succeed. + * @retval Result::FailedAllocation An internal error with a memory allocation for an object to be dashed. + * @retval Result::InvalidArguments In case @p dashPattern is @c nullptr and @p cnt > 0, @p cnt is zero, any of the dash pattern values is zero or less. + * + * @note To reset the stroke dash pattern, pass @c nullptr to @p dashPattern and zero to @p cnt. + * @warning @p cnt must be greater than 1 if the dash pattern is valid. + */ + Result stroke(const float* dashPattern, uint32_t cnt) noexcept; + + /** + * @brief Sets the cap style of the stroke in the open sub-paths. + * + * @param[in] cap The cap style value. The default value is @c StrokeCap::Square. + * + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result stroke(StrokeCap cap) noexcept; + + /** + * @brief Sets the join style for stroked path segments. + * + * The join style is used for joining the two line segment while stroking the path. + * + * @param[in] join The join style value. The default value is @c StrokeJoin::Bevel. + * + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result stroke(StrokeJoin join) noexcept; + + + /** + * @brief Sets the stroke miterlimit. + * + * @param[in] miterlimit The miterlimit imposes a limit on the extent of the stroke join, when the @c StrokeJoin::Miter join style is set. The default value is 4. + * + * @retval Result::Success when succeed, Result::NonSupport unsupported value, Result::FailedAllocation otherwise. + * + * @since 0.11 + */ + Result strokeMiterlimit(float miterlimit) noexcept; + + /** + * @brief Sets the solid color for all of the figures from the path. + * + * The parts of the shape defined as inner are colored. + * + * @param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. The default value is 0. + * + * @retval Result::Success when succeed. + * + * @note Either a solid color or a gradient fill is applied, depending on what was set as last. + * @note ClipPath won't use the fill values. (see: enum class CompositeMethod::ClipPath) + */ + Result fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) noexcept; + + /** + * @brief Sets the gradient fill for all of the figures from the path. + * + * The parts of the shape defined as inner are filled. + * + * @param[in] f The unique pointer to the gradient fill. + * + * @retval Result::Success when succeed, Result::MemoryCorruption otherwise. + * + * @note Either a solid color or a gradient fill is applied, depending on what was set as last. + */ + Result fill(std::unique_ptr f) noexcept; + + /** + * @brief Sets the fill rule for the Shape object. + * + * @param[in] r The fill rule value. The default value is @c FillRule::Winding. + * + * @retval Result::Success when succeed. + */ + Result fill(FillRule r) noexcept; + + + /** + * @brief Sets the rendering order of the stroke and the fill. + * + * @param[in] strokeFirst If @c true the stroke is rendered before the fill, otherwise the stroke is rendered as the second one (the default option). + * + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. + * + * @since 0.10 + */ + Result order(bool strokeFirst) noexcept; + + + /** + * @brief Gets the commands data of the path. + * + * @param[out] cmds The pointer to the array of the commands from the path. + * + * @return The length of the @p cmds array when succeed, zero otherwise. + */ + uint32_t pathCommands(const PathCommand** cmds) const noexcept; + + /** + * @brief Gets the points values of the path. + * + * @param[out] pts The pointer to the array of the two-dimensional points from the path. + * + * @return The length of the @p pts array when succeed, zero otherwise. + */ + uint32_t pathCoords(const Point** pts) const noexcept; + + /** + * @brief Gets the pointer to the gradient fill of the shape. + * + * @return The pointer to the gradient fill of the stroke when succeed, @c nullptr in case no fill was set. + */ + const Fill* fill() const noexcept; + + /** + * @brief Gets the solid color of the shape. + * + * @param[out] r The red color channel value in the range [0 ~ 255]. + * @param[out] g The green color channel value in the range [0 ~ 255]. + * @param[out] b The blue color channel value in the range [0 ~ 255]. + * @param[out] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. + * + * @return Result::Success when succeed. + */ + Result fillColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a = nullptr) const noexcept; + + /** + * @brief Gets the fill rule value. + * + * @return The fill rule value of the shape. + */ + FillRule fillRule() const noexcept; + + /** + * @brief Gets the stroke width. + * + * @return The stroke width value when succeed, zero if no stroke was set. + */ + float strokeWidth() const noexcept; + + /** + * @brief Gets the color of the shape's stroke. + * + * @param[out] r The red color channel value in the range [0 ~ 255]. + * @param[out] g The green color channel value in the range [0 ~ 255]. + * @param[out] b The blue color channel value in the range [0 ~ 255]. + * @param[out] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. + * + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. + */ + Result strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a = nullptr) const noexcept; + + /** + * @brief Gets the pointer to the gradient fill of the stroke. + * + * @return The pointer to the gradient fill of the stroke when succeed, @c nullptr otherwise. + */ + const Fill* strokeFill() const noexcept; + + /** + * @brief Gets the dash pattern of the stroke. + * + * @param[out] dashPattern The pointer to the memory, where the dash pattern array is stored. + * + * @return The length of the @p dashPattern array. + */ + uint32_t strokeDash(const float** dashPattern) const noexcept; + + /** + * @brief Gets the cap style used for stroking the path. + * + * @return The cap style value of the stroke. + */ + StrokeCap strokeCap() const noexcept; + + /** + * @brief Gets the join style value used for stroking the path. + * + * @return The join style value of the stroke. + */ + StrokeJoin strokeJoin() const noexcept; + + /** + * @brief Gets the stroke miterlimit. + * + * @return The stroke miterlimit value when succeed, 4 if no stroke was set. + * + * @since 0.11 + */ + float strokeMiterlimit() const noexcept; + + /** + * @brief Creates a new Shape object. + * + * @return A new Shape object. + */ + static std::unique_ptr gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the Shape class type. + * + * @return The type id of the Shape class. + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(Shape); +}; + + +/** + * @class Picture + * + * @brief A class representing an image read in one of the supported formats: raw, svg, png, jpg, lottie(json) and etc. + * Besides the methods inherited from the Paint, it provides methods to load & draw images on the canvas. + * + * @note Supported formats are depended on the available TVG loaders. + * @note See Animation class if the picture data is animatable. + */ +class TVG_API Picture final : public Paint +{ +public: + ~Picture(); + + /** + * @brief Loads a picture data directly from a file. + * + * ThorVG efficiently caches the loaded data using the specified @p path as a key. + * This means that loading the same file again will not result in duplicate operations; + * instead, ThorVG will reuse the previously loaded picture data. + * + * @param[in] path A path to the picture file. + * + * @retval Result::Success When succeed. + * @retval Result::InvalidArguments In case the @p path is invalid. + * @retval Result::NonSupport When trying to load a file with an unknown extension. + * @retval Result::Unknown If an error occurs at a later stage. + * + * @note The Load behavior can be asynchronous if the assigned thread number is greater than zero. + * @see Initializer::init() + */ + Result load(const std::string& path) noexcept; + + /** + * @brief Loads a picture data from a memory block of a given size. + * + * ThorVG efficiently caches the loaded data using the specified @p data address as a key + * when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations + * for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data. + * + * @param[in] data A pointer to a memory location where the content of the picture file is stored. + * @param[in] size The size in bytes of the memory occupied by the @p data. + * @param[in] copy Decides whether the data should be copied into the engine local buffer. + * + * @retval Result::Success When succeed. + * @retval Result::InvalidArguments In case no data are provided or the @p size is zero or less. + * @retval Result::NonSupport When trying to load a file with an unknown extension. + * @retval Result::Unknown If an error occurs at a later stage. + * + * @warning: you have responsibility to release the @p data memory if the @p copy is true + * @deprecated Use load(const char* data, uint32_t size, const std::string& mimeType, bool copy) instead. + * @see Result load(const char* data, uint32_t size, const std::string& mimeType, bool copy = false) noexcept + */ + TVG_DEPRECATED Result load(const char* data, uint32_t size, bool copy = false) noexcept; + + /** + * @brief Loads a picture data from a memory block of a given size. + * + * @param[in] data A pointer to a memory location where the content of the picture file is stored. + * @param[in] size The size in bytes of the memory occupied by the @p data. + * @param[in] mimeType Mimetype or extension of data such as "jpg", "jpeg", "lottie", "svg", "svg+xml", "png", etc. In case an empty string or an unknown type is provided, the loaders will be tried one by one. + * @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not. + * + * @retval Result::Success When succeed. + * @retval Result::InvalidArguments In case no data are provided or the @p size is zero or less. + * @retval Result::NonSupport When trying to load a file with an unknown extension. + * @retval Result::Unknown If an error occurs at a later stage. + * + * @warning: It's the user responsibility to release the @p data memory if the @p copy is @c true. + * + * @note If you are unsure about the MIME type, you can provide an empty value like @c "", and thorvg will attempt to figure it out. + * @since 0.5 + */ + Result load(const char* data, uint32_t size, const std::string& mimeType, bool copy = false) noexcept; + + /** + * @brief Resizes the picture content to the given width and height. + * + * The picture content is resized while keeping the default size aspect ratio. + * The scaling factor is established for each of dimensions and the smaller value is applied to both of them. + * + * @param[in] w A new width of the image in pixels. + * @param[in] h A new height of the image in pixels. + * + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. + */ + Result size(float w, float h) noexcept; + + /** + * @brief Gets the size of the image. + * + * @param[out] w The width of the image in pixels. + * @param[out] h The height of the image in pixels. + * + * @retval Result::Success when succeed. + */ + Result size(float* w, float* h) const noexcept; + + /** + * @brief Loads a raw data from a memory block with a given size. + * + * ThorVG efficiently caches the loaded data using the specified @p data address as a key + * when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations + * for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data. + * + * @param[in] paint A Tvg_Paint pointer to the picture object. + * @param[in] data A pointer to a memory location where the content of the picture raw data is stored. + * @param[in] w The width of the image @p data in pixels. + * @param[in] h The height of the image @p data in pixels. + * @param[in] premultiplied If @c true, the given image data is alpha-premultiplied. + * @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not. + * + * @retval Result::Success When succeed, Result::InsufficientCondition otherwise. + * @retval Result::FailedAllocation An internal error possibly with memory allocation. + * + * @since 0.9 + */ + Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) noexcept; + + /** + * @brief Sets or removes the triangle mesh to deform the image. + * + * If a mesh is provided, the transform property of the Picture will apply to the triangle mesh, and the + * image data will be used as the texture. + * + * If @p triangles is @c nullptr, or @p triangleCnt is 0, the mesh will be removed. + * + * Only raster image types are supported at this time (png, jpg). Vector types like svg and tvg do not support. + * mesh deformation. However, if required you should be able to render a vector image to a raster image and then apply a mesh. + * + * @param[in] triangles An array of Polygons(triangles) that make up the mesh, or null to remove the mesh. + * @param[in] triangleCnt The number of Polygons(triangles) provided, or 0 to remove the mesh. + * + * @retval Result::Success When succeed. + * @retval Result::Unknown If fails + * + * @note The Polygons are copied internally, so modifying them after calling Mesh::mesh has no affect. + * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * + * @note Experimental API + */ + Result mesh(const Polygon* triangles, uint32_t triangleCnt) noexcept; + + /** + * @brief Return the number of triangles in the mesh, and optionally get a pointer to the array of triangles in the mesh. + * + * @param[out] triangles Optional. A pointer to the array of Polygons used by this mesh. + * + * @return The number of polygons in the array. + * + * @note Modifying the triangles returned by this method will modify them directly within the mesh. + * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * + * @note Experimental API + */ + uint32_t mesh(const Polygon** triangles) const noexcept; + + /** + * @brief Creates a new Picture object. + * + * @return A new Picture object. + */ + static std::unique_ptr gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the Picture class type. + * + * @return The type id of the Picture class. + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_ACCESSOR(Animation); + _TVG_DECLARE_PRIVATE(Picture); +}; + + +/** + * @class Scene + * + * @brief A class to composite children paints. + * + * As the traditional graphics rendering method, TVG also enables scene-graph mechanism. + * This feature supports an array function for managing the multiple paints as one group paint. + * + * As a group, the scene can be transformed, made translucent and composited with other target paints, + * its children will be affected by the scene world. + */ +class TVG_API Scene final : public Paint +{ +public: + ~Scene(); + + /** + * @brief Passes drawing elements to the Scene using Paint objects. + * + * Only the paints pushed into the scene will be the drawn targets. + * The paints are retained by the scene until Scene::clear() is called. + * + * @param[in] paint A Paint object to be drawn. + * + * @retval Result::Success when succeed, Result::MemoryCorruption otherwise. + * + * @note The rendering order of the paints is the same as the order as they were pushed. Consider sorting the paints before pushing them if you intend to use layering. + * @see Scene::paints() + * @see Scene::clear() + */ + Result push(std::unique_ptr paint) noexcept; + + /** + * @brief Sets the size of the container, where all the paints pushed into the Scene are stored. + * + * If the number of objects pushed into the scene is known in advance, calling the function + * prevents multiple memory reallocation, thus improving the performance. + * + * @param[in] size The number of objects for which the memory is to be reserved. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + TVG_DEPRECATED Result reserve(uint32_t size) noexcept; + + /** + * @brief Returns the list of the paints that currently held by the Scene. + * + * This function provides the list of paint nodes, allowing users a direct opportunity to modify the scene tree. + * + * @warning Please avoid accessing the paints during Scene update/draw. You can access them after calling Canvas::sync(). + * @see Canvas::sync() + * @see Scene::push() + * @see Scene::clear() + * + * @note Experimental API + */ + std::list& paints() noexcept; + + /** + * @brief Sets the total number of the paints pushed into the scene to be zero. + * Depending on the value of the @p free argument, the paints are freed or not. + * + * @param[in] free If @c true, the memory occupied by paints is deallocated, otherwise it is not. + * + * @retval Result::Success when succeed + * + * @warning If you don't free the paints they become dangled. They are supposed to be reused, otherwise you are responsible for their lives. Thus please use the @p free argument only when you know how it works, otherwise it's not recommended. + * + * @since 0.2 + */ + Result clear(bool free = true) noexcept; + + /** + * @brief Creates a new Scene object. + * + * @return A new Scene object. + */ + static std::unique_ptr gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the Scene class type. + * + * @return The type id of the Scene class. + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(Scene); +}; + + +/** + * @class Text + * + * @brief A class to represent text objects in a graphical context, allowing for rendering and manipulation of unicode text. + * + * @note Experimental API + */ +class TVG_API Text final : public Paint +{ +public: + ~Text(); + + /** + * @brief Sets the font properties for the text. + * + * This function allows you to define the font characteristics used for text rendering. + * It sets the font name, size and optionally the style. + * + * @param[in] name The name of the font. This should correspond to a font available in the canvas. + * @param[in] size The size of the font in points. This determines how large the text will appear. + * @param[in] style The style of the font. It can be used to set the font to 'italic'. + * If not specified, the default style is used. Only 'italic' style is supported currently. + * + * @retval Result::Success when the font properties are set successfully. + * @retval Result::InsufficientCondition when the specified @p name cannot be found. + * + * @note Experimental API + */ + Result font(const char* name, float size, const char* style = nullptr) noexcept; + + /** + * @brief Assigns the given unicode text to be rendered. + * + * This function sets the unicode string that will be displayed by the rendering system. + * The text is set according to the specified UTF encoding method, which defaults to UTF-8. + * + * @param[in] text The multi-byte text encoded with utf8 string to be rendered. + * + * @retval Result::Success when succeed. + * + * @note Experimental API + */ + Result text(const char* text) noexcept; + + /** + * @brief Sets the text color. + * + * @param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. + * + * @retval Result::Success when succeed. + * @retval Result::InsufficientCondition when the font has not been set up prior to this operation. + * + * @see Text::font() + * + * @note Experimental API + */ + Result fill(uint8_t r, uint8_t g, uint8_t b) noexcept; + + /** + * @brief Sets the gradient fill for all of the figures from the text. + * + * The parts of the text defined as inner are filled. + * + * @param[in] f The unique pointer to the gradient fill. + * + * @retval Result::Success when succeed, Result::MemoryCorruption otherwise. + * @retval Result::InsufficientCondition when the font has not been set up prior to this operation. + * + * @note Either a solid color or a gradient fill is applied, depending on what was set as last. + * @note Experimental API + * + * @see Text::font() + */ + Result fill(std::unique_ptr f) noexcept; + + /** + * @brief Loads a scalable font data(ttf) from a file. + * + * ThorVG efficiently caches the loaded data using the specified @p path as a key. + * This means that loading the same file again will not result in duplicate operations; + * instead, ThorVG will reuse the previously loaded font data. + * + * @param[in] path The path to the font file. + * + * @retval Result::Success When succeed. + * @retval Result::InvalidArguments In case the @p path is invalid. + * @retval Result::NonSupport When trying to load a file with an unknown extension. + * @retval Result::Unknown If an error occurs at a later stage. + * + * @note Experimental API + * + * @see Text::unload(const std::string& path) + */ + static Result load(const std::string& path) noexcept; + + /** + * @brief Unloads the specified scalable font data (TTF) that was previously loaded. + * + * This function is used to release resources associated with a font file that has been loaded into memory. + * + * @param[in] path The file path of the loaded font. + * + * @retval Result::Success Successfully unloads the font data. + * @retval Result::InsufficientCondition Fails if the loader is not initialized. + * + * @note If the font data is currently in use, it will not be immediately unloaded. + * @note Experimental API + * + * @see Text::load(const std::string& path) + */ + static Result unload(const std::string& path) noexcept; + + /** + * @brief Creates a new Text object. + * + * @return A new Text object. + * + * @note Experimental API + */ + static std::unique_ptr gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the Text class type. + * + * @return The type id of the Text class. + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(Text); +}; + + +/** + * @class SwCanvas + * + * @brief A class for the rendering graphical elements with a software raster engine. + */ +class TVG_API SwCanvas final : public Canvas +{ +public: + ~SwCanvas(); + + /** + * @brief Enumeration specifying the methods of combining the 8-bit color channels into 32-bit color. + */ + enum Colorspace + { + ABGR8888 = 0, ///< The channels are joined in the order: alpha, blue, green, red. Colors are alpha-premultiplied. (a << 24 | b << 16 | g << 8 | r) + ARGB8888, ///< The channels are joined in the order: alpha, red, green, blue. Colors are alpha-premultiplied. (a << 24 | r << 16 | g << 8 | b) + ABGR8888S, ///< The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. @since 0.12 + ARGB8888S, ///< The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. @since 0.12 + }; + + /** + * @brief Enumeration specifying the methods of Memory Pool behavior policy. + * @since 0.4 + */ + enum MempoolPolicy + { + Default = 0, ///< Default behavior that ThorVG is designed to. + Shareable, ///< Memory Pool is shared among the SwCanvases. + Individual ///< Allocate designated memory pool that is only used by current instance. + }; + + /** + * @brief Sets the drawing target for the rasterization. + * + * The buffer of a desirable size should be allocated and owned by the caller. + * + * @param[in] buffer A pointer to a memory block of the size @p stride x @p h, where the raster data are stored. + * @param[in] stride The stride of the raster image - greater than or equal to @p w. + * @param[in] w The width of the raster image. + * @param[in] h The height of the raster image. + * @param[in] cs The value specifying the way the 32-bits colors should be read/written. + * + * @retval Result::Success When succeed. + * @retval Result::MemoryCorruption When casting in the internal function implementation failed. + * @retval Result::InvalidArguments In case no valid pointer is provided or the width, or the height or the stride is zero. + * @retval Result::NonSupport In case the software engine is not supported. + * + * @warning Do not access @p buffer during Canvas::push() - Canvas::sync(). It should not be accessed while the engine is writing on it. + * + * @see Canvas::viewport() + */ + Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Colorspace cs) noexcept; + + /** + * @brief Set sw engine memory pool behavior policy. + * + * Basically ThorVG draws a lot of shapes, it allocates/deallocates a few chunk of memory + * while processing rendering. It internally uses one shared memory pool + * which can be reused among the canvases in order to avoid memory overhead. + * + * Thus ThorVG suggests using a memory pool policy to satisfy user demands, + * if it needs to guarantee the thread-safety of the internal data access. + * + * @param[in] policy The method specifying the Memory Pool behavior. The default value is @c MempoolPolicy::Default. + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition If the canvas contains some paints already. + * @retval Result::NonSupport In case the software engine is not supported. + * + * @note When @c policy is set as @c MempoolPolicy::Individual, the current instance of canvas uses its own individual + * memory data, which is not shared with others. This is necessary when the canvas is accessed on a worker-thread. + * + * @warning It's not allowed after pushing any paints. + * + * @since 0.4 + */ + Result mempool(MempoolPolicy policy) noexcept; + + /** + * @brief Creates a new SwCanvas object. + * @return A new SwCanvas object. + */ + static std::unique_ptr gen() noexcept; + + _TVG_DECLARE_PRIVATE(SwCanvas); +}; + + +/** + * @class GlCanvas + * + * @brief A class for the rendering graphic elements with a GL raster engine. + * + * @warning Please do not use it. This class is not fully supported yet. + * + * @note Experimental API + */ +class TVG_API GlCanvas final : public Canvas +{ +public: + ~GlCanvas(); + + /** + * @brief Sets the drawing target for rasterization. + * + * This function specifies the drawing target where the rasterization will occur. It can target + * a specific framebuffer object (FBO) or the main surface. + * + * @param[in] id The GL target ID, usually indicating the FBO ID. A value of @c 0 specifies the main surface. + * @param[in] w The width (in pixels) of the raster image. + * @param[in] h The height (in pixels) of the raster image. + * + * @warning This API is experimental and not officially supported. It may be modified or removed in future versions. + * @warning Drawing on the main surface is currently not permitted. If the identifier (@p id) is set to @c 0, the operation will be aborted. + * + * @see Canvas::viewport() + * + * @note Currently, this only allows the GL_RGBA8 color space format. + * @note Experimental API + */ + Result target(int32_t id, uint32_t w, uint32_t h) noexcept; + + /** + * @brief Creates a new GlCanvas object. + * + * @return A new GlCanvas object. + * + * @note Experimental API + */ + static std::unique_ptr gen() noexcept; + + _TVG_DECLARE_PRIVATE(GlCanvas); +}; + + +/** + * @class WgCanvas + * + * @brief A class for the rendering graphic elements with a WebGPU raster engine. + * + * @warning Please do not use it. This class is not fully supported yet. + * + * @note Experimental API + */ +class TVG_API WgCanvas final : public Canvas +{ +public: + ~WgCanvas(); + + /** + * @brief Sets the target window for the rasterization. + * + * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * + * @note Experimental API + * @see Canvas::viewport() + */ + Result target(void* window, uint32_t w, uint32_t h) noexcept; + + /** + * @brief Creates a new WgCanvas object. + * + * @return A new WgCanvas object. + * + * @note Experimental API + */ + static std::unique_ptr gen() noexcept; + + _TVG_DECLARE_PRIVATE(WgCanvas); +}; + + +/** + * @class Initializer + * + * @brief A class that enables initialization and termination of the TVG engines. + */ +class TVG_API Initializer final +{ +public: + /** + * @brief Initializes TVG engines. + * + * TVG requires the running-engine environment. + * TVG runs its own task-scheduler for parallelizing rendering tasks efficiently. + * You can indicate the number of threads, the count of which is designated @p threads. + * In the initialization step, TVG will generate/spawn the threads as set by @p threads count. + * + * @param[in] engine The engine types to initialize. This is relative to the Canvas types, in which it will be used. For multiple backends bitwise operation is allowed. + * @param[in] threads The number of additional threads. Zero indicates only the main thread is to be used. + * + * @retval Result::Success When succeed. + * @retval Result::FailedAllocation An internal error possibly with memory allocation. + * @retval Result::InvalidArguments If unknown engine type chosen. + * @retval Result::NonSupport In case the engine type is not supported on the system. + * @retval Result::Unknown Others. + * + * @note The Initializer keeps track of the number of times it was called. Threads count is fixed at the first init() call. + * @see Initializer::term() + */ + static Result init(CanvasEngine engine, uint32_t threads) noexcept; + + /** + * @brief Terminates TVG engines. + * + * @param[in] engine The engine types to terminate. This is relative to the Canvas types, in which it will be used. For multiple backends bitwise operation is allowed + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition In case there is nothing to be terminated. + * @retval Result::InvalidArguments If unknown engine type chosen. + * @retval Result::NonSupport In case the engine type is not supported on the system. + * @retval Result::Unknown Others. + * + * @note Initializer does own reference counting for multiple calls. + * @see Initializer::init() + */ + static Result term(CanvasEngine engine) noexcept; + + _TVG_DISABLE_CTOR(Initializer); +}; + + +/** + * @class Animation + * + * @brief The Animation class enables manipulation of animatable images. + * + * This class supports the display and control of animation frames. + * + * @since 0.13 + */ + +class TVG_API Animation +{ +public: + ~Animation(); + + /** + * @brief Specifies the current frame in the animation. + * + * @param[in] no The index of the animation frame to be displayed. The index should be less than the totalFrame(). + * + * @retval Result::Success Successfully set the frame. + * @retval Result::InsufficientCondition if the given @p no is the same as the current frame value. + * @retval Result::NonSupport The current Picture data does not support animations. + * + * @note For efficiency, ThorVG ignores updates to the new frame value if the difference from the current frame value + * is less than 0.001. In such cases, it returns @c Result::InsufficientCondition. + * Values less than 0.001 may be disregarded and may not be accurately retained by the Animation. + * + * @see totalFrame() + * + */ + Result frame(float no) noexcept; + + /** + * @brief Retrieves a picture instance associated with this animation instance. + * + * This function provides access to the picture instance that can be used to load animation formats, such as Lottie(json). + * After setting up the picture, it can be pushed to the designated canvas, enabling control over animation frames + * with this Animation instance. + * + * @return A picture instance that is tied to this animation. + * + * @warning The picture instance is owned by Animation. It should not be deleted manually. + * + */ + Picture* picture() const noexcept; + + /** + * @brief Retrieves the current frame number of the animation. + * + * @return The current frame number of the animation, between 0 and totalFrame() - 1. + * + * @note If the Picture is not properly configured, this function will return 0. + * + * @see Animation::frame(float no) + * @see Animation::totalFrame() + * + */ + float curFrame() const noexcept; + + /** + * @brief Retrieves the total number of frames in the animation. + * + * @return The total number of frames in the animation. + * + * @note Frame numbering starts from 0. + * @note If the Picture is not properly configured, this function will return 0. + * + */ + float totalFrame() const noexcept; + + /** + * @brief Retrieves the duration of the animation in seconds. + * + * @return The duration of the animation in seconds. + * + * @note If the Picture is not properly configured, this function will return 0. + * + */ + float duration() const noexcept; + + /** + * @brief Specifies the playback segment of the animation. + * + * The set segment is designated as the play area of the animation. + * This is useful for playing a specific segment within the entire animation. + * After setting, the number of animation frames and the playback time are calculated + * by mapping the playback segment as the entire range. + * + * @param[in] begin segment start. + * @param[in] end segment end. + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition In case the animation is not loaded. + * @retval Result::InvalidArguments When the given parameter is invalid. + * @retval Result::NonSupport When it's not animatable. + * + * @note Range from 0.0~1.0 + * @note If a marker has been specified, its range will be disregarded. + * @see LottieAnimation::segment(const char* marker) + * @note Experimental API + */ + Result segment(float begin, float end) noexcept; + + /** + * @brief Gets the current segment. + * + * @param[out] begin segment start. + * @param[out] end segment end. + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition In case the animation is not loaded. + * @retval Result::InvalidArguments When the given parameter is invalid. + * @retval Result::NonSupport When it's not animatable. + * + * @note Experimental API + */ + Result segment(float* begin, float* end = nullptr) noexcept; + + /** + * @brief Creates a new Animation object. + * + * @return A new Animation object. + * + */ + static std::unique_ptr gen() noexcept; + + _TVG_DECLARE_PRIVATE(Animation); +}; + + +/** + * @class Saver + * + * @brief A class for exporting a paint object into a specified file, from which to recover the paint data later. + * + * ThorVG provides a feature for exporting & importing paint data. The Saver role is to export the paint data to a file. + * It's useful when you need to save the composed scene or image from a paint object and recreate it later. + * + * The file format is decided by the extension name(i.e. "*.tvg") while the supported formats depend on the TVG packaging environment. + * If it doesn't support the file format, the save() method returns the @c Result::NonSupport result. + * + * Once you export a paint to the file successfully, you can recreate it using the Picture class. + * + * @see Picture::load() + * + * @since 0.5 + */ +class TVG_API Saver final +{ +public: + ~Saver(); + + /** + * @brief Sets the base background content for the saved image. + * + * @param[in] paint The paint to be drawn as the background image for the saving paint. + * + * @note Experimental API + */ + Result background(std::unique_ptr paint) noexcept; + + /** + * @brief Exports the given @p paint data to the given @p path + * + * If the saver module supports any compression mechanism, it will optimize the data size. + * This might affect the encoding/decoding time in some cases. You can turn off the compression + * if you wish to optimize for speed. + * + * @param[in] paint The paint to be saved with all its associated properties. + * @param[in] path A path to the file, in which the paint data is to be saved. + * @param[in] compress If @c true then compress data if possible. + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition If currently saving other resources. + * @retval Result::NonSupport When trying to save a file with an unknown extension or in an unsupported format. + * @retval Result::MemoryCorruption An internal error. + * @retval Result::Unknown In case an empty paint is to be saved. + * + * @note Saving can be asynchronous if the assigned thread number is greater than zero. To guarantee the saving is done, call sync() afterwards. + * @see Saver::sync() + * + * @since 0.5 + */ + Result save(std::unique_ptr paint, const std::string& path, bool compress = true) noexcept; + + /** + * @brief Export the provided animation data to the specified file path. + * + * This function exports the given animation data to the provided file path. You can also specify the desired frame rate in frames per second (FPS) by providing the fps parameter. + * + * @param[in] animation The animation to be saved, including all associated properties. + * @param[in] path The path to the file where the animation will be saved. + * @param[in] quality The encoded quality level. @c 0 is the minimum, @c 100 is the maximum value(recommended). + * @param[in] fps The desired frames per second (FPS). For example, to encode data at 60 FPS, pass 60. Pass 0 to keep the original frame data. + * + * @retval Result::Success if the export succeeds. + * @retval Result::InsufficientCondition if there are ongoing resource-saving operations. + * @retval Result::NonSupport if an attempt is made to save the file with an unknown extension or in an unsupported format. + * @retval Result::MemoryCorruption in case of an internal error. + * @retval Result::Unknown if attempting to save an empty paint. + * + * @note A higher frames per second (FPS) would result in a larger file size. It is recommended to use the default value. + * @note Saving can be asynchronous if the assigned thread number is greater than zero. To guarantee the saving is done, call sync() afterwards. + * + * @see Saver::sync() + * + * @note Experimental API + */ + Result save(std::unique_ptr animation, const std::string& path, uint32_t quality = 100, uint32_t fps = 0) noexcept; + + /** + * @brief Guarantees that the saving task is finished. + * + * The behavior of the Saver works on a sync/async basis, depending on the threading setting of the Initializer. + * Thus, if you wish to have a benefit of it, you must call sync() after the save() in the proper delayed time. + * Otherwise, you can call sync() immediately. + * + * @retval Result::Success when succeed. + * @retval Result::InsufficientCondition otherwise. + * + * @note The asynchronous tasking is dependent on the Saver module implementation. + * @see Saver::save() + * + * @since 0.5 + */ + Result sync() noexcept; + + /** + * @brief Creates a new Saver object. + * + * @return A new Saver object. + * + * @since 0.5 + */ + static std::unique_ptr gen() noexcept; + + _TVG_DECLARE_PRIVATE(Saver); +}; + + +/** + * @class Accessor + * + * @brief The Accessor is a utility class to debug the Scene structure by traversing the scene-tree. + * + * The Accessor helps you search specific nodes to read the property information, figure out the structure of the scene tree and its size. + * + * @warning We strongly warn you not to change the paints of a scene unless you really know the design-structure. + * + * @since 0.10 + */ +class TVG_API Accessor final +{ +public: + ~Accessor(); + + /** + * @brief Set the access function for traversing the Picture scene tree nodes. + * + * @param[in] picture The picture node to traverse the internal scene-tree. + * @param[in] func The callback function calling for every paint nodes of the Picture. + * + * @return Return the given @p picture instance. + * + * @note The bitmap based picture might not have the scene-tree. + */ + std::unique_ptr set(std::unique_ptr picture, std::function func) noexcept; + + /** + * @brief Creates a new Accessor object. + * + * @return A new Accessor object. + */ + static std::unique_ptr gen() noexcept; + + _TVG_DECLARE_PRIVATE(Accessor); +}; + + +/** + * @brief The cast() function is a utility function used to cast a 'Paint' to type 'T'. + * @since 0.11 + */ +template +std::unique_ptr cast(Paint* paint) +{ + return std::unique_ptr(static_cast(paint)); +} + + +/** + * @brief The cast() function is a utility function used to cast a 'Fill' to type 'T'. + * @since 0.11 + */ +template +std::unique_ptr cast(Fill* fill) +{ + return std::unique_ptr(static_cast(fill)); +} + + +/** @}*/ + +} //namespace + +#endif //_THORVG_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/thorvg_capi.h b/test/include/liblvgl/libs/thorvg/thorvg_capi.h new file mode 100644 index 00000000..98b709ea --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/thorvg_capi.h @@ -0,0 +1,2508 @@ +/*! +* \file thorvg_capi.h +* +* \brief The module provides C bindings for the ThorVG library. +* Please refer to src/examples/Capi.cpp to find the thorvg_capi usage examples. +* +* The thorvg_capi module allows to implement the ThorVG client and provides +* the following functionalities: +* - drawing shapes: line, arc, curve, polygon, circle, user-defined, ... +* - filling: solid, linear and radial gradient +* - scene graph & affine transformation (translation, rotation, scale, ...) +* - stroking: width, join, cap, dash +* - composition: blending, masking, path clipping +* - pictures: SVG, PNG, JPG, bitmap +* +*/ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL +#define TVG_BUILD 1 + +#define TVG_BUILD 1 + +#ifndef __THORVG_CAPI_H__ +#define __THORVG_CAPI_H__ + +#include +#include + +#ifdef TVG_API + #undef TVG_API +#endif + +#ifndef TVG_STATIC + #ifdef _WIN32 + #if TVG_BUILD + #define TVG_API __declspec(dllexport) + #else + #define TVG_API __declspec(dllimport) + #endif + #elif (defined(__SUNPRO_C) || defined(__SUNPRO_CC)) + #define TVG_API __global + #else + #if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__INTEL_COMPILER) + #define TVG_API __attribute__ ((visibility("default"))) + #else + #define TVG_API + #endif + #endif +#else + #define TVG_API +#endif + +#ifdef TVG_DEPRECATED + #undef TVG_DEPRECATED +#endif + +#ifdef _WIN32 + #define TVG_DEPRECATED __declspec(deprecated) +#elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) + #define TVG_DEPRECATED __attribute__ ((__deprecated__)) +#else + #define TVG_DEPRECATED +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* \defgroup ThorVG_CAPI ThorVG_CAPI +* \brief ThorVG C language binding APIs. +* +* \{ +*/ + + +/** +* \brief A structure responsible for managing and drawing graphical elements. +* +* It sets up the target buffer, which can be drawn on the screen. It stores the Tvg_Paint objects (Shape, Scene, Picture). +*/ +typedef struct _Tvg_Canvas Tvg_Canvas; + + +/** +* \brief A structure representing a graphical element. +* +* \warning The TvgPaint objects cannot be shared between Canvases. +*/ +typedef struct _Tvg_Paint Tvg_Paint; + + +/** +* \brief A structure representing a gradient fill of a Tvg_Paint object. +*/ +typedef struct _Tvg_Gradient Tvg_Gradient; + + +/** +* \brief A structure representing an object that enables to save a Tvg_Paint object into a file. +*/ +typedef struct _Tvg_Saver Tvg_Saver; + +/** +* \brief A structure representing an animation controller object. +*/ +typedef struct _Tvg_Animation Tvg_Animation; + + +/** +* \brief Enumeration specifying the engine type used for the graphics backend. For multiple backends bitwise operation is allowed. +* +* \ingroup ThorVGCapi_Initializer +*/ +typedef enum { + TVG_ENGINE_SW = (1 << 1), ///< CPU rasterizer. + TVG_ENGINE_GL = (1 << 2) ///< OpenGL rasterizer. +} Tvg_Engine; + + +/** + * \brief Enumeration specifying the result from the APIs. + */ +typedef enum { + TVG_RESULT_SUCCESS = 0, ///< The value returned in case of a correct request execution. + TVG_RESULT_INVALID_ARGUMENT, ///< The value returned in the event of a problem with the arguments given to the API - e.g. empty paths or null pointers. + TVG_RESULT_INSUFFICIENT_CONDITION, ///< The value returned in case the request cannot be processed - e.g. asking for properties of an object, which does not exist. + TVG_RESULT_FAILED_ALLOCATION, ///< The value returned in case of unsuccessful memory allocation. + TVG_RESULT_MEMORY_CORRUPTION, ///< The value returned in the event of bad memory handling - e.g. failing in pointer releasing or casting + TVG_RESULT_NOT_SUPPORTED, ///< The value returned in case of choosing unsupported options. + TVG_RESULT_UNKNOWN ///< The value returned in all other cases. +} Tvg_Result; + + +/** + * \brief Enumeration indicating the method used in the composition of two objects - the target and the source. + * + * \ingroup ThorVGCapi_Paint + */ +typedef enum { + TVG_COMPOSITE_METHOD_NONE = 0, ///< No composition is applied. + TVG_COMPOSITE_METHOD_CLIP_PATH, ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered. + TVG_COMPOSITE_METHOD_ALPHA_MASK, ///< The pixels of the source and the target are alpha blended. As a result, only the part of the source, which intersects with the target is visible. + TVG_COMPOSITE_METHOD_INVERSE_ALPHA_MASK, ///< The pixels of the source and the complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible. + TVG_COMPOSITE_METHOD_LUMA_MASK, ///< The source pixels are converted to grayscale (luma value) and alpha blended with the target. As a result, only the part of the source which intersects with the target is visible. \since 0.9 + TVG_COMPOSITE_METHOD_INVERSE_LUMA_MASK ///< The source pixels are converted to grayscale (luma value) and complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible. \Experimental API +} Tvg_Composite_Method; + +/** + * @brief Enumeration indicates the method used for blending paint. Please refer to the respective formulas for each method. + * + * \ingroup ThorVGCapi_Paint + * + * @note Experimental API + */ +typedef enum { + TVG_BLEND_METHOD_NORMAL = 0, ///< Perform the alpha blending(default). S if (Sa == 255), otherwise (Sa * S) + (255 - Sa) * D + TVG_BLEND_METHOD_ADD, ///< Simply adds pixel values of one layer with the other. (S + D) + TVG_BLEND_METHOD_SCREEN, ///< The values of the pixels in the two layers are inverted, multiplied, and then inverted again. (S + D) - (S * D) + TVG_BLEND_METHOD_MULTIPLY, ///< Takes the RGB channel values from 0 to 255 of each pixel in the top layer and multiples them with the values for the corresponding pixel from the bottom layer. (S * D) + TVG_BLEND_METHOD_OVERLAY, ///< Combines Multiply and Screen blend modes. (2 * S * D) if (2 * D < Da), otherwise (Sa * Da) - 2 * (Da - S) * (Sa - D) + TVG_BLEND_METHOD_DIFFERENCE, ///< Subtracts the bottom layer from the top layer or the other way around, to always get a non-negative value. (S - D) if (S > D), otherwise (D - S) + TVG_BLEND_METHOD_EXCLUSION, ///< The result is twice the product of the top and bottom layers, subtracted from their sum. s + d - (2 * s * d) + TVG_BLEND_METHOD_SRCOVER, ///< Replace the bottom layer with the top layer. + TVG_BLEND_METHOD_DARKEN, ///< Creates a pixel that retains the smallest components of the top and bottom layer pixels. min(S, D) + TVG_BLEND_METHOD_LIGHTEN, ///< Only has the opposite action of Darken Only. max(S, D) + TVG_BLEND_METHOD_COLORDODGE, ///< Divides the bottom layer by the inverted top layer. D / (255 - S) + TVG_BLEND_METHOD_COLORBURN, ///< Divides the inverted bottom layer by the top layer, and then inverts the result. 255 - (255 - D) / S + TVG_BLEND_METHOD_HARDLIGHT, ///< The same as Overlay but with the color roles reversed. (2 * S * D) if (S < Sa), otherwise (Sa * Da) - 2 * (Da - S) * (Sa - D) + TVG_BLEND_METHOD_SOFTLIGHT ///< The same as Overlay but with applying pure black or white does not result in pure black or white. (1 - 2 * S) * (D ^ 2) + (2 * S * D) +} Tvg_Blend_Method; + + +/** + * \brief Enumeration indicating the ThorVG class type. + * + * \ingroup ThorVGCapi_Paint + * + * \since 0.9 + */ +typedef enum { + TVG_IDENTIFIER_UNDEF = 0, ///< Undefined type. + TVG_IDENTIFIER_SHAPE, ///< A shape type paint. + TVG_IDENTIFIER_SCENE, ///< A scene type paint. + TVG_IDENTIFIER_PICTURE, ///< A picture type paint. + TVG_IDENTIFIER_LINEAR_GRAD, ///< A linear gradient type. + TVG_IDENTIFIER_RADIAL_GRAD ///< A radial gradient type. +} Tvg_Identifier; + + +/** + * \addtogroup ThorVGCapi_Shape + * \{ + */ + +/** + * \brief Enumeration specifying the values of the path commands accepted by TVG. + * + * Not to be confused with the path commands from the svg path element (like M, L, Q, H and many others). + * TVG interprets all of them and translates to the ones from the PathCommand values. + */ +typedef enum { + TVG_PATH_COMMAND_CLOSE = 0, ///< Ends the current sub-path and connects it with its initial point - corresponds to Z command in the svg path commands. + TVG_PATH_COMMAND_MOVE_TO, ///< Sets a new initial point of the sub-path and a new current point - corresponds to M command in the svg path commands. + TVG_PATH_COMMAND_LINE_TO, ///< Draws a line from the current point to the given point and sets a new value of the current point - corresponds to L command in the svg path commands. + TVG_PATH_COMMAND_CUBIC_TO ///< Draws a cubic Bezier curve from the current point to the given point using two given control points and sets a new value of the current point - corresponds to C command in the svg path commands. +} Tvg_Path_Command; + + +/** + * \brief Enumeration determining the ending type of a stroke in the open sub-paths. + */ +typedef enum { + TVG_STROKE_CAP_SQUARE = 0, ///< The stroke is extended in both endpoints of a sub-path by a rectangle, with the width equal to the stroke width and the length equal to the half of the stroke width. For zero length sub-paths the square is rendered with the size of the stroke width. + TVG_STROKE_CAP_ROUND, ///< The stroke is extended in both endpoints of a sub-path by a half circle, with a radius equal to the half of a stroke width. For zero length sub-paths a full circle is rendered. + TVG_STROKE_CAP_BUTT ///< The stroke ends exactly at each of the two endpoints of a sub-path. For zero length sub-paths no stroke is rendered. +} Tvg_Stroke_Cap; + + +/** + * \brief Enumeration specifying how to fill the area outside the gradient bounds. + */ +typedef enum { + TVG_STROKE_JOIN_BEVEL = 0, ///< The outer corner of the joined path segments is bevelled at the join point. The triangular region of the corner is enclosed by a straight line between the outer corners of each stroke. + TVG_STROKE_JOIN_ROUND, ///< The outer corner of the joined path segments is rounded. The circular region is centered at the join point. + TVG_STROKE_JOIN_MITER ///< The outer corner of the joined path segments is spiked. The spike is created by extension beyond the join point of the outer edges of the stroke until they intersect. In case the extension goes beyond the limit, the join style is converted to the Bevel style. +} Tvg_Stroke_Join; + + +/** + * \brief Enumeration specifying how to fill the area outside the gradient bounds. + */ +typedef enum { + TVG_STROKE_FILL_PAD = 0, ///< The remaining area is filled with the closest stop color. + TVG_STROKE_FILL_REFLECT, ///< The gradient pattern is reflected outside the gradient area until the expected region is filled. + TVG_STROKE_FILL_REPEAT ///< The gradient pattern is repeated continuously beyond the gradient area until the expected region is filled. +} Tvg_Stroke_Fill; + + +/** + * \brief Enumeration specifying the algorithm used to establish which parts of the shape are treated as the inside of the shape. + */ +typedef enum { + TVG_FILL_RULE_WINDING = 0, ///< A line from the point to a location outside the shape is drawn. The intersections of the line with the path segment of the shape are counted. Starting from zero, if the path segment of the shape crosses the line clockwise, one is added, otherwise one is subtracted. If the resulting sum is non zero, the point is inside the shape. + TVG_FILL_RULE_EVEN_ODD ///< A line from the point to a location outside the shape is drawn and its intersections with the path segments of the shape are counted. If the number of intersections is an odd number, the point is inside the shape. +} Tvg_Fill_Rule; + +/** \} */ // end addtogroup ThorVGCapi_Shape + + +/*! +* \addtogroup ThorVGCapi_Gradient +* \{ +*/ + +/*! +* \brief A data structure storing the information about the color and its relative position inside the gradient bounds. +*/ +typedef struct +{ + float offset; /**< The relative position of the color. */ + uint8_t r; /**< The red color channel value in the range [0 ~ 255]. */ + uint8_t g; /**< The green color channel value in the range [0 ~ 255]. */ + uint8_t b; /**< The blue color channel value in the range [0 ~ 255]. */ + uint8_t a; /**< The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. */ +} Tvg_Color_Stop; + +/** \} */ // end addtogroup ThorVGCapi_Gradient + + +/** + * \brief A data structure representing a point in two-dimensional space. + */ +typedef struct +{ + float x, y; +} Tvg_Point; + + +/** + * \brief A data structure representing a three-dimensional matrix. + * + * The elements e11, e12, e21 and e22 represent the rotation matrix, including the scaling factor. + * The elements e13 and e23 determine the translation of the object along the x and y-axis, respectively. + * The elements e31 and e32 are set to 0, e33 is set to 1. + */ +typedef struct +{ + float e11, e12, e13; + float e21, e22, e23; + float e31, e32, e33; +} Tvg_Matrix; + + +/** +* \defgroup ThorVGCapi_Initializer Initializer +* \brief A module enabling initialization and termination of the TVG engines. +* +* \{ +*/ + +/************************************************************************/ +/* Engine API */ +/************************************************************************/ +/*! +* \brief Initializes TVG engines. +* +* TVG requires the running-engine environment. +* TVG runs its own task-scheduler for parallelizing rendering tasks efficiently. +* You can indicate the number of threads, the count of which is designated @p threads. +* In the initialization step, TVG will generate/spawn the threads as set by @p threads count. +* +* \code +* tvg_engine_init(TVG_ENGINE_SW, 0); //Initialize software renderer and use the main thread only +* \endcode +* +* \param[in] engine_method The engine types to initialize. This is relative to the Canvas types, in which it will be used. For multiple backends bitwise operation is allowed. +* - TVG_ENGINE_SW: CPU rasterizer +* - TVG_ENGINE_GL: OpenGL rasterizer (not supported yet) +* \param[in] threads The number of additional threads used to perform rendering. Zero indicates only the main thread is to be used. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error possibly with memory allocation. +* \retval TVG_RESULT_INVALID_ARGUMENT Unknown engine type. +* \retval TVG_RESULT_NOT_SUPPORTED Unsupported engine type. +* \retval TVG_RESULT_UNKNOWN Other error. +* +* \note The Initializer keeps track of the number of times it was called. Threads count is fixed at the first init() call. +* \see tvg_engine_term() +* \see Tvg_Engine +*/ +TVG_API Tvg_Result tvg_engine_init(Tvg_Engine engine_method, unsigned threads); + + +/*! +* \brief Terminates TVG engines. +* +* It should be called in case of termination of the TVG client with the same engine types as were passed when tvg_engine_init() was called. +* +* \code +* tvg_engine_init(TVG_ENGINE_SW, 0); +* //define canvas and shapes, update shapes, general rendering calls +* tvg_engine_term(TVG_ENGINE_SW); +* \endcode +* +* \param engine_method The engine types to terminate. This is relative to the Canvas types, in which it will be used. For multiple backends bitwise operation is allowed +* - TVG_ENGINE_SW: CPU rasterizer +* - TVG_ENGINE_GL: OpenGL rasterizer (not supported yet) +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION Nothing to be terminated. +* \retval TVG_RESULT_INVALID_ARGUMENT Unknown engine type. +* \retval TVG_RESULT_NOT_SUPPORTED Unsupported engine type. +* \retval TVG_RESULT_UNKNOWN An internal error. +* +* \see tvg_engine_init() +* \see Tvg_Engine +*/ +TVG_API Tvg_Result tvg_engine_term(Tvg_Engine engine_method); + + +/** \} */ // end defgroup ThorVGCapi_Initializer + + +/** +* \defgroup ThorVGCapi_Canvas Canvas +* \brief A module for managing and drawing graphical elements. +* +* A canvas is an entity responsible for drawing the target. It sets up the drawing engine and the buffer, which can be drawn on the screen. It also manages given Paint objects. +* +* \note A Canvas behavior depends on the raster engine though the final content of the buffer is expected to be identical. +* \warning The Paint objects belonging to one Canvas can't be shared among multiple Canvases. +\{ +*/ + + +/** +* \defgroup ThorVGCapi_SwCanvas SwCanvas +* \ingroup ThorVGCapi_Canvas +* +* \brief A module for rendering the graphical elements using the software engine. +* +* \{ +*/ + +/************************************************************************/ +/* SwCanvas API */ +/************************************************************************/ + +/** + * \brief Enumeration specifying the methods of Memory Pool behavior policy. + */ +typedef enum { + TVG_MEMPOOL_POLICY_DEFAULT = 0, ///< Default behavior that ThorVG is designed to. + TVG_MEMPOOL_POLICY_SHAREABLE, ///< Memory Pool is shared among canvases. + TVG_MEMPOOL_POLICY_INDIVIDUAL ///< Allocate designated memory pool that is used only by the current canvas instance. +} Tvg_Mempool_Policy; + + +/** + * \brief Enumeration specifying the methods of combining the 8-bit color channels into 32-bit color. + */ +typedef enum { + TVG_COLORSPACE_ABGR8888 = 0, ///< The channels are joined in the order: alpha, blue, green, red. Colors are alpha-premultiplied. (a << 24 | b << 16 | g << 8 | r) + TVG_COLORSPACE_ARGB8888, ///< The channels are joined in the order: alpha, red, green, blue. Colors are alpha-premultiplied. (a << 24 | r << 16 | g << 8 | b) + TVG_COLORSPACE_ABGR8888S, ///< The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. @since 0.13 + TVG_COLORSPACE_ARGB8888S ///< The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. @since 0.13 +} Tvg_Colorspace; + + +/*! +* \brief Creates a Canvas object. +* +* \code +* Tvg_Canvas *canvas = NULL; +* +* tvg_engine_init(TVG_ENGINE_SW, 4); +* canvas = tvg_swcanvas_create(); +* +* //set up the canvas buffer +* uint32_t *buffer = NULL; +* buffer = (uint32_t*) malloc(sizeof(uint32_t) * 100 * 100); +* if (!buffer) return; +* +* tvg_swcanvas_set_target(canvas, buffer, 100, 100, 100, TVG_COLORSPACE_ARGB8888); +* +* //set up paints and add them into the canvas before drawing it +* +* tvg_canvas_destroy(canvas); +* tvg_engine_term(TVG_ENGINE_SW); +* \endcode +* +* \return A new Tvg_Canvas object. +*/ +TVG_API Tvg_Canvas* tvg_swcanvas_create(void); + + +/*! +* \brief Sets the buffer used in the rasterization process and defines the used colorspace. +* +* For optimisation reasons TVG does not allocate memory for the output buffer on its own. +* The buffer of a desirable size should be allocated and owned by the caller. +* +* \param[in] canvas The Tvg_Canvas object managing the @p buffer. +* \param[in] buffer A pointer to the allocated memory block of the size @p stride x @p h. +* \param[in] stride The stride of the raster image - in most cases same value as @p w. +* \param[in] w The width of the raster image. +* \param[in] h The height of the raster image. +* \param[in] cs The colorspace value defining the way the 32-bits colors should be read/written. +* - TVG_COLORSPACE_ABGR8888 +* - TVG_COLORSPACE_ARGB8888 +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_MEMORY_CORRUPTION Casting in the internal function implementation failed. +* \retval TVG_RESULT_INVALID_ARGUMENTS An invalid canvas or buffer pointer passed or one of the @p stride, @p w or @p h being zero. +* \retval TVG_RESULT_NOT_SUPPORTED The software engine is not supported. +* +* \warning Do not access @p buffer during tvg_canvas_draw() - tvg_canvas_sync(). It should not be accessed while the engine is writing on it. +* +* \see Tvg_Colorspace +*/ +TVG_API Tvg_Result tvg_swcanvas_set_target(Tvg_Canvas* canvas, uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Tvg_Colorspace cs); + + +/*! +* \brief Sets the software engine memory pool behavior policy. +* +* ThorVG draws a lot of shapes, it allocates/deallocates a few chunk of memory +* while processing rendering. It internally uses one shared memory pool +* which can be reused among the canvases in order to avoid memory overhead. +* +* Thus ThorVG suggests using a memory pool policy to satisfy user demands, +* if it needs to guarantee the thread-safety of the internal data access. +* +* \param[in] canvas The Tvg_Canvas object of which the Memory Pool behavior is to be specified. +* \param[in] policy The method specifying the Memory Pool behavior. The default value is @c TVG_MEMPOOL_POLICY_DEFAULT. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENTS An invalid canvas pointer passed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION The canvas contains some paints already. +* \retval TVG_RESULT_NOT_SUPPORTED The software engine is not supported. +* +* \note When @c policy is set as @c TVG_MEMPOOL_POLICY_INDIVIDUAL, the current instance of canvas uses its own individual +* memory data, which is not shared with others. This is necessary when the canvas is accessed on a worker-thread. +* +* \warning It's not allowed after pushing any paints. +*/ +TVG_API Tvg_Result tvg_swcanvas_set_mempool(Tvg_Canvas* canvas, Tvg_Mempool_Policy policy); + +/** \} */ // end defgroup ThorVGCapi_SwCanvas + + +/************************************************************************/ +/* Common Canvas API */ +/************************************************************************/ +/*! +* \brief Clears the canvas internal data, releases all paints stored by the canvas and destroys the canvas object itself. +* +* \code +* static Tvg_Canvas *canvas = NULL; +* static uint32_t *buffer = NULL; +* +* static void _init() { +* canvas = tvg_swcanvas_create(); +* buffer = (uint32_t*) malloc(sizeof(uint32_t) * 100 * 100); +* tvg_swcanvas_set_target(canvas, buffer, 100, 100, 100, TVG_COLORSPACE_ARGB8888); +* } +* +* //a task called from main function in a loop +* static void _job(const int cmd) { +* //define a valid rectangle shape +* switch (cmd) { +* case CMD_EXIT: return 0; +* case CMD_ADD_RECT: +* tvg_canvas_push(canvas, rect); +* break; +* case CMD_DEL_RECT: +* tvg_paint_del(rect); +* //now to safely delete Tvg_Canvas, tvg_canvas_clear() API have to be used +* break; +* default: +* break; +* } +* } +* +* int main(int argc, char **argv) { +* int cmd = 0; +* int stop = 1; +* +* tvg_engine_init(TVG_ENGINE_SW, 4); +* +* while (stop) { +* //wait for a command e.g. from a console +* stop = _job(cmd); +* } +* tvg_canvas_clear(canvas, false); +* tvg_canvas_destroy(canvas); +* tvg_engine_term(TVG_ENGINE_SW); +* return 0; +* } +* +* tvg_canvas_destroy(canvas); +* tvg_engine_term(TVG_ENGINE_SW) +* \endcode +* +* \param[in] canvas The Tvg_Canvas object to be destroyed. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer to the Tvg_Canvas object is passed. +* +* \note If the paints from the canvas should not be released, the tvg_canvas_clear() with a @c free argument value set to @c false should be called. +* Please be aware that in such a case TVG is not responsible for the paints release anymore and it has to be done manually in order to avoid memory leaks. +* +* \see tvg_paint_del(), tvg_canvas_clear() +*/ +TVG_API Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas); + + +/*! +* \brief Inserts a drawing element into the canvas using a Tvg_Paint object. +* +* \param[in] canvas The Tvg_Canvas object managing the @p paint. +* \param[in] paint The Tvg_Paint object to be drawn. +* +* Only the paints pushed into the canvas will be drawing targets. +* They are retained by the canvas until you call tvg_canvas_clear(). +* If you know the number of the pushed objects in advance, please call tvg_canvas_reserve(). +* +* \return Tvg_Result return values: +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION An internal error. +* +* \note The rendering order of the paints is the same as the order as they were pushed. Consider sorting the paints before pushing them if you intend to use layering. +* \see tvg_canvas_clear() +*/ +TVG_API Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint); + + +/*! +* \brief Reserves a memory block where the objects pushed into a canvas are stored. +* +* If the number of Tvg_Paints to be stored in a canvas is known in advance, calling this function reduces the multiple +* memory allocations thus improves the performance. +* +* \code +* Tvg_Canvas *canvas = NULL; +* +* tvg_engine_init(TVG_ENGINE_SW, 4); +* canvas = tvg_swcanvas_create(); +* +* uint32_t *buffer = NULL; +* buffer = (uint32_t*) malloc(sizeof(uint32_t) * 100 * 100); +* if (!buffer) return; +* +* tvg_swcanvas_set_target(canvas, buffer, 100, 100, 100, TVG_COLORSPACE_ARGB8888); +* +* tvg_canvas_destroy(canvas); +* tvg_engine_term(TVG_ENGINE_SW) +* \endcode +* +* \param[in] canvas The Tvg_Canvas object managing the reserved memory. +* \param[in] n The number of objects for which the memory is to be reserved. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Canvas pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with memory allocation. +*/ +TVG_DEPRECATED TVG_API Tvg_Result tvg_canvas_reserve(Tvg_Canvas* canvas, uint32_t n); + + +/*! +* \brief Sets the total number of the paints pushed into the canvas to be zero. +* Tvg_Paint objects stored in the canvas are released if @p free is set to @c true, otherwise the memory is not deallocated and +* all paints should be released manually in order to avoid memory leaks. +* +* \param[in] canvas The Tvg_Canvas object to be cleared. +* \param[in] free If @c true the memory occupied by paints is deallocated, otherwise it is not. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Canvas pointer. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION An internal error. +* +* \warning Please use the @p free argument only when you know how it works, otherwise it's not recommended. +* +* \see tvg_canvas_destroy() +*/ +TVG_API Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas, bool free); + + +/*! +* \brief Updates all paints in a canvas. +* +* Should be called before drawing in order to prepare paints for the rendering. +* +* \code +* //A frame drawing example. Thread safety and events implementation is skipped to show only TVG code. +* +* static Tvg_Canvas *canvas = NULL; +* static Tvg_Paint *rect = NULL; +* +* int _frame_render(void) { +* tvg_canvas_update(canvas); +* tvg_canvas_draw(canvas); +* tvg_canvas_sync(canvas); +* } +* +* //event handler from your code or third party library +* void _event_handler(event *event_data) { +* if (!event_data) return NULL; +* switch(event_data.type) { +* case EVENT_RECT_ADD: +* if (!rect) { +* tvg_shape_append_rect(rect, 10, 10, 50, 50, 0, 0); +* tvg_shape_set_stroke_width(rect, 1.0f); +* tvg_shape_set_stroke_color(rect, 255, 0, 0, 255); +* tvg_canvas_push(canvas, rect); +* } +* break; +* case EVENT_RECT_MOVE: +* if (rect) tvg_paint_translate(rect, 10.0, 10.0); +* break; +* default: +* break; +* } +* } +* +* int main(int argc, char **argv) { +* //example handler from your code or third party lib +* event_handler_add(handler, _event_handler); +* +* //create frame rendering process which calls _frame_render() function. +* app_loop_begin(_frame_render); +* app_loop_finish(); +* cleanup(); +* } +* \endcode +* +* \param[in] canvas The Tvg_Canvas object to be updated. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Canvas pointer. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION An internal error. +* +* \see tvg_canvas_update_paint() +*/ +TVG_API Tvg_Result tvg_canvas_update(Tvg_Canvas* canvas); + + +/*! +* \brief Updates the given Tvg_Paint object from the canvas before the rendering. +* +* If a client application using the TVG library does not update the entire canvas with tvg_canvas_update() in the frame +* rendering process, Tvg_Paint objects previously added to the canvas should be updated manually with this function. +* +* \param[in] canvas The Tvg_Canvas object to which the @p paint belongs. +* \param[in] paint The Tvg_Paint object to be updated. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. +* +* \see tvg_canvas_update() +*/ +TVG_API Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint); + + +/*! +* \brief Requests the canvas to draw the Tvg_Paint objects. +* +* All paints from the given canvas will be rasterized to the buffer. +* +* \param[in] canvas The Tvg_Canvas object containing elements to be drawn. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Canvas pointer. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION An internal error. +* +* \note Drawing can be asynchronous based on the assigned thread number. To guarantee the drawing is done, call tvg_canvas_sync() afterwards. +* \see tvg_canvas_sync() +*/ +TVG_API Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas); + + +/*! +* \brief Guarantees that the drawing process is finished. +* +* Since the canvas rendering can be performed asynchronously, it should be called after the tvg_canvas_draw(). +* +* \param[in] canvas The Tvg_Canvas object containing elements which were drawn. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Canvas pointer. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION An internal error. +* +* \see tvg_canvas_draw() +*/ +TVG_API Tvg_Result tvg_canvas_sync(Tvg_Canvas* canvas); + + +/*! +* \brief Sets the drawing region in the canvas. +* +* This function defines the rectangular area of the canvas that will be used for drawing operations. +* The specified viewport is used to clip the rendering output to the boundaries of the rectangle. +* +* \param[in] canvas The Tvg_Canvas object containing elements which were drawn. +* \param[in] x The x-coordinate of the upper-left corner of the rectangle. +* \param[in] y The y-coordinate of the upper-left corner of the rectangle. +* \param[in] w The width of the rectangle. +* \param[in] h The height of the rectangle. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION An internal error. +* +* \warning It's not allowed to change the viewport during tvg_canvas_update() - tvg_canvas_sync() or tvg_canvas_push() - tvg_canvas_sync(). +* +* \note When resetting the target, the viewport will also be reset to the target size. +* \note Experimental API +* \see tvg_swcanvas_set_target() +*/ +TVG_API Tvg_Result tvg_canvas_set_viewport(Tvg_Canvas* canvas, int32_t x, int32_t y, int32_t w, int32_t h); + +/** \} */ // end defgroup ThorVGCapi_Canvas + + +/** +* \defgroup ThorVGCapi_Paint Paint +* \brief A module for managing graphical elements. It enables duplication, transformation and composition. +* +* \{ +*/ + +/************************************************************************/ +/* Paint API */ +/************************************************************************/ +/*! +* \brief Releases the given Tvg_Paint object. +* +* \code +* //example of cleanup function +* Tvg_Paint *rect = NULL; //rectangle shape added in other function +* +* //rectangle delete API +* int rectangle_delete(void) { +* if (rect) tvg_paint_del(rect); +* rect = NULL; +* } +* +* int cleanup(void) { +* tvg_canvas_clear(canvas, false); +* tvg_canvas_destroy(canvas); +* canvas = NULL; +* } +* \endcode +* +* \param[in] paint The Tvg_Paint object to be released. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* +* \warning If this function is used, tvg_canvas_clear() with the @c free argument value set to @c false should be used in order to avoid unexpected behaviours. +* +* \see tvg_canvas_clear(), tvg_canvas_destroy() +*/ +TVG_API Tvg_Result tvg_paint_del(Tvg_Paint* paint); + + +/*! +* \brief Scales the given Tvg_Paint object by the given factor. +* +* \param[in] paint The Tvg_Paint object to be scaled. +* \param[in] factor The value of the scaling factor. The default value is 1. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with memory allocation. +*/ +TVG_API Tvg_Result tvg_paint_scale(Tvg_Paint* paint, float factor); + + +/*! +* \brief Rotates the given Tvg_Paint by the given angle. +* +* The angle in measured clockwise from the horizontal axis. +* The rotational axis passes through the point on the object with zero coordinates. +* +* \param[in] paint The Tvg_Paint object to be rotated. +* \param[in] degree The value of the rotation angle in degrees. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with memory allocation. +*/ +TVG_API Tvg_Result tvg_paint_rotate(Tvg_Paint* paint, float degree); + + +/*! +* \brief Moves the given Tvg_Paint in a two-dimensional space. +* +* The origin of the coordinate system is in the upper left corner of the canvas. +* The horizontal and vertical axes point to the right and down, respectively. +* +* \param[in] paint The Tvg_Paint object to be shifted. +* \param[in] x The value of the horizontal shift. +* \param[in] y The value of the vertical shift. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with memory allocation. +*/ +TVG_API Tvg_Result tvg_paint_translate(Tvg_Paint* paint, float x, float y); + + +/*! +* \brief Transforms the given Tvg_Paint using the augmented transformation matrix. +* +* The augmented matrix of the transformation is expected to be given. +* +* \param[in] paint The Tvg_Paint object to be transformed. +* \param[in] m The 3x3 augmented matrix. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr is passed as the argument. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with memory allocation. +*/ +TVG_API Tvg_Result tvg_paint_set_transform(Tvg_Paint* paint, const Tvg_Matrix* m); + + +/*! +* \brief Gets the matrix of the affine transformation of the given Tvg_Paint object. +* +* In case no transformation was applied, the identity matrix is returned. +* +* \param[in] paint The Tvg_Paint object of which to get the transformation matrix. +* \param[out] m The 3x3 augmented matrix. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr is passed as the argument. +*/ +TVG_API Tvg_Result tvg_paint_get_transform(Tvg_Paint* paint, Tvg_Matrix* m); + + +/*! +* \brief Sets the opacity of the given Tvg_Paint. +* +* \param[in] paint The Tvg_Paint object of which the opacity value is to be set. +* \param[in] opacity The opacity value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* +* \note Setting the opacity with this API may require multiple renderings using a composition. It is recommended to avoid changing the opacity if possible. +*/ +TVG_API Tvg_Result tvg_paint_set_opacity(Tvg_Paint* paint, uint8_t opacity); + + +/*! +* \brief Gets the opacity of the given Tvg_Paint. +* +* \param[in] paint The Tvg_Paint object of which to get the opacity value. +* \param[out] opacity The opacity value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. +*/ +TVG_API Tvg_Result tvg_paint_get_opacity(const Tvg_Paint* paint, uint8_t* opacity); + + +/*! +* \brief Duplicates the given Tvg_Paint object. +* +* Creates a new object and sets its all properties as in the original object. +* +* \param[in] paint The Tvg_Paint object to be copied. +* +* \return A copied Tvg_Paint object if succeed, @c nullptr otherwise. +*/ +TVG_API Tvg_Paint* tvg_paint_duplicate(Tvg_Paint* paint); + + +/*! +* \brief Gets the axis-aligned bounding box of the Tvg_Paint object. +* +* \param[in] paint The Tvg_Paint object of which to get the bounds. +* \param[out] x The x coordinate of the upper left corner of the object. +* \param[out] y The y coordinate of the upper left corner of the object. +* \param[out] w The width of the object. +* \param[out] h The height of the object. +* \param[in] transformed If @c true, the transformation of the paint is taken into account, otherwise it isn't. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION Other errors. +* +* \note The bounding box doesn't indicate the actual drawing region. It's the smallest rectangle that encloses the object. +*/ +TVG_API Tvg_Result tvg_paint_get_bounds(const Tvg_Paint* paint, float* x, float* y, float* w, float* h, bool transformed); + + +/*! +* \brief Sets the composition target object and the composition method. +* +* \param[in] paint The source object of the composition. +* \param[in] target The target object of the composition. +* \param[in] method The method used to composite the source object with the target. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid @p paint or @p target object or the @p method equal to TVG_COMPOSITE_METHOD_NONE. +*/ +TVG_API Tvg_Result tvg_paint_set_composite_method(Tvg_Paint* paint, Tvg_Paint* target, Tvg_Composite_Method method); + + +/** +* \brief Gets the composition target object and the composition method. +* +* \param[in] paint The source object of the composition. +* \param[out] target The target object of the composition. +* \param[out] method The method used to composite the source object with the target. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr is passed as the argument. +*/ +TVG_API Tvg_Result tvg_paint_get_composite_method(const Tvg_Paint* paint, const Tvg_Paint** target, Tvg_Composite_Method* method); + + +/** +* \brief Gets the unique id value of the paint instance indicating the instance type. +* +* \param[in] paint The Tvg_Paint object of which to get the identifier value. +* \param[out] identifier The unique identifier of the paint instance type. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. +* +* \since 0.9 +*/ +TVG_API Tvg_Result tvg_paint_get_identifier(const Tvg_Paint* paint, Tvg_Identifier* identifier); + + +/** + * @brief Sets the blending method for the paint object. + * + * The blending feature allows you to combine colors to create visually appealing effects, including transparency, lighting, shading, and color mixing, among others. + * its process involves the combination of colors or images from the source paint object with the destination (the lower layer image) using blending operations. + * The blending operation is determined by the chosen @p BlendMethod, which specifies how the colors or images are combined. + * + * \param[in] paint The Tvg_Paint object of which to get the identifier value. + * \param[in] method The blending method to be set. + * + * \return Tvg_Result enumeration. + * \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. + * + * @note Experimental API + */ +TVG_API Tvg_Result tvg_paint_set_blend_method(const Tvg_Paint* paint, Tvg_Blend_Method method); + + +/** + * @brief Gets the blending method for the paint object. + * + * The blending feature allows you to combine colors to create visually appealing effects, including transparency, lighting, shading, and color mixing, among others. + * its process involves the combination of colors or images from the source paint object with the destination (the lower layer image) using blending operations. + * The blending operation is determined by the chosen @p BlendMethod, which specifies how the colors or images are combined. + * + * \param[in] paint The Tvg_Paint object of which to get the identifier value. + * \param[out] method The blending method of the paint. + * + * \return Tvg_Result enumeration. + * \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. + * + * @note Experimental API + */ +TVG_API Tvg_Result tvg_paint_get_blend_method(const Tvg_Paint* paint, Tvg_Blend_Method* method); + + +/** \} */ // end defgroup ThorVGCapi_Paint + +/** +* \defgroup ThorVGCapi_Shape Shape +* +* \brief A module for managing two-dimensional figures and their properties. +* +* A shape has three major properties: shape outline, stroking, filling. The outline in the shape is retained as the path. +* Path can be composed by accumulating primitive commands such as tvg_shape_move_to(), tvg_shape_line_to(), tvg_shape_cubic_to() or complete shape interfaces such as tvg_shape_append_rect(), tvg_shape_append_circle(), etc. +* Path can consists of sub-paths. One sub-path is determined by a close command. +* +* The stroke of a shape is an optional property in case the shape needs to be represented with/without the outline borders. +* It's efficient since the shape path and the stroking path can be shared with each other. It's also convenient when controlling both in one context. +* +* \{ +*/ + +/************************************************************************/ +/* Shape API */ +/************************************************************************/ +/*! +* \brief Creates a new shape object. +* +* \return A new shape object. +*/ +TVG_API Tvg_Paint* tvg_shape_new(void); + + +/*! +* \brief Resets the shape path properties. +* +* The color, the fill and the stroke properties are retained. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* +* \note The memory, where the path data is stored, is not deallocated at this stage for caching effect. +*/ +TVG_API Tvg_Result tvg_shape_reset(Tvg_Paint* paint); + + +/*! +* \brief Sets the initial point of the sub-path. +* +* The value of the current point is set to the given point. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] x The horizontal coordinate of the initial point of the sub-path. +* \param[in] y The vertical coordinate of the initial point of the sub-path. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +*/ +TVG_API Tvg_Result tvg_shape_move_to(Tvg_Paint* paint, float x, float y); + + +/*! +* \brief Adds a new point to the sub-path, which results in drawing a line from the current point to the given end-point. +* +* The value of the current point is set to the given end-point. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] x The horizontal coordinate of the end-point of the line. +* \param[in] y The vertical coordinate of the end-point of the line. + +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* +* \note In case this is the first command in the path, it corresponds to the tvg_shape_move_to() call. +*/ +TVG_API Tvg_Result tvg_shape_line_to(Tvg_Paint* paint, float x, float y); + + +/*! +* \brief Adds new points to the sub-path, which results in drawing a cubic Bezier curve. +* +* The Bezier curve starts at the current point and ends at the given end-point (@p x, @p y). Two control points (@p cx1, @p cy1) and (@p cx2, @p cy2) are used to determine the shape of the curve. +* The value of the current point is set to the given end-point. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] cx1 The horizontal coordinate of the 1st control point. +* \param[in] cy1 The vertical coordinate of the 1st control point. +* \param[in] cx2 The horizontal coordinate of the 2nd control point. +* \param[in] cy2 The vertical coordinate of the 2nd control point. +* \param[in] x The horizontal coordinate of the endpoint of the curve. +* \param[in] y The vertical coordinate of the endpoint of the curve. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* +* \note In case this is the first command in the path, no data from the path are rendered. +*/ +TVG_API Tvg_Result tvg_shape_cubic_to(Tvg_Paint* paint, float cx1, float cy1, float cx2, float cy2, float x, float y); + + +/*! +* \brief Closes the current sub-path by drawing a line from the current point to the initial point of the sub-path. +* +* The value of the current point is set to the initial point of the closed sub-path. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* +* \note In case the sub-path does not contain any points, this function has no effect. +*/ +TVG_API Tvg_Result tvg_shape_close(Tvg_Paint* paint); + + +/*! +* \brief Appends a rectangle to the path. +* +* The rectangle with rounded corners can be achieved by setting non-zero values to @p rx and @p ry arguments. +* The @p rx and @p ry values specify the radii of the ellipse defining the rounding of the corners. +* +* The position of the rectangle is specified by the coordinates of its upper left corner - @p x and @p y arguments. +* +* The rectangle is treated as a new sub-path - it is not connected with the previous sub-path. +* +* The value of the current point is set to (@p x + @p rx, @p y) - in case @p rx is greater +* than @p w/2 the current point is set to (@p x + @p w/2, @p y) +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] x The horizontal coordinate of the upper left corner of the rectangle. +* \param[in] y The vertical coordinate of the upper left corner of the rectangle. +* \param[in] w The width of the rectangle. +* \param[in] h The height of the rectangle. +* \param[in] rx The x-axis radius of the ellipse defining the rounded corners of the rectangle. +* \param[in] ry The y-axis radius of the ellipse defining the rounded corners of the rectangle. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* +& \note For @p rx and @p ry greater than or equal to the half of @p w and the half of @p h, respectively, the shape become an ellipse. +*/ +TVG_API Tvg_Result tvg_shape_append_rect(Tvg_Paint* paint, float x, float y, float w, float h, float rx, float ry); + + +/*! +* \brief Appends an ellipse to the path. +* +* The position of the ellipse is specified by the coordinates of its center - @p cx and @p cy arguments. +* +* The ellipse is treated as a new sub-path - it is not connected with the previous sub-path. +* +* The value of the current point is set to (@p cx, @p cy - @p ry). +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] cx The horizontal coordinate of the center of the ellipse. +* \param[in] cy The vertical coordinate of the center of the ellipse. +* \param[in] rx The x-axis radius of the ellipse. +* \param[in] ry The y-axis radius of the ellipse. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +*/ +TVG_API Tvg_Result tvg_shape_append_circle(Tvg_Paint* paint, float cx, float cy, float rx, float ry); + + +/*! +* \brief Appends a circular arc to the path. +* +* The arc is treated as a new sub-path - it is not connected with the previous sub-path. +* The current point value is set to the end-point of the arc in case @p pie is @c false, and to the center of the arc otherwise. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] cx The horizontal coordinate of the center of the arc. +* \param[in] cy The vertical coordinate of the center of the arc. +* \param[in] radius The radius of the arc. +* \param[in] startAngle The start angle of the arc given in degrees, measured counter-clockwise from the horizontal line. +* \param[in] sweep The central angle of the arc given in degrees, measured counter-clockwise from @p startAngle. +* \param[in] pie Specifies whether to draw radii from the arc's center to both of its end-point - drawn if @c true. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* +* \note Setting @p sweep value greater than 360 degrees, is equivalent to calling tvg_shape_append_circle(paint, cx, cy, radius, radius). +*/ +TVG_API Tvg_Result tvg_shape_append_arc(Tvg_Paint* paint, float cx, float cy, float radius, float startAngle, float sweep, uint8_t pie); + + +/*! +* \brief Appends a given sub-path to the path. +* +* The current point value is set to the last point from the sub-path. +* For each command from the @p cmds array, an appropriate number of points in @p pts array should be specified. +* If the number of points in the @p pts array is different than the number required by the @p cmds array, the shape with this sub-path will not be displayed on the screen. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] cmds The array of the commands in the sub-path. +* \param[in] cmdCnt The length of the @p cmds array. +* \param[in] pts The array of the two-dimensional points. +* \param[in] ptsCnt The length of the @p pts array. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the argument or @p cmdCnt or @p ptsCnt equal to zero. +*/ +TVG_API Tvg_Result tvg_shape_append_path(Tvg_Paint* paint, const Tvg_Path_Command* cmds, uint32_t cmdCnt, const Tvg_Point* pts, uint32_t ptsCnt); + + +/*! +* \brief Gets the points values of the path. +* +* The function does not allocate any data, it operates on internal memory. There is no need to free the @p pts array. +* +* \code +* Tvg_Shape *shape = tvg_shape_new(); +* Tvg_Point *coords = NULL; +* uint32_t len = 0; +* +* tvg_shape_append_circle(shape, 10, 10, 50, 50); +* tvg_shape_get_path_coords(shape, (const Tvg_Point**)&coords, &len); +* //TVG approximates a circle by four Bezier curves. In the example above the coords array stores their coordinates. +* \endcode +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] pts The pointer to the array of the two-dimensional points from the path. +* \param[out] cnt The length of the @p pts array. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the argument. +*/ +TVG_API Tvg_Result tvg_shape_get_path_coords(const Tvg_Paint* paint, const Tvg_Point** pts, uint32_t* cnt); + + +/*! +* \brief Gets the commands data of the path. +* +* The function does not allocate any data. There is no need to free the @p cmds array. +* +* \code +* Tvg_Shape *shape = tvg_shape_new(); +* Tvg_Path_Command *cmds = NULL; +* uint32_t len = 0; +* +* tvg_shape_append_circle(shape, 10, 10, 50, 50); +* tvg_shape_get_path_commands(shape, (const Tvg_Path_Command**)&cmds, &len); +* //TVG approximates a circle by four Bezier curves. In the example above the cmds array stores the commands of the path data. +* \endcode +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] cmds The pointer to the array of the commands from the path. +* \param[out] cnt The length of the @p cmds array. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the argument. +*/ +TVG_API Tvg_Result tvg_shape_get_path_commands(const Tvg_Paint* paint, const Tvg_Path_Command** cmds, uint32_t* cnt); + + +/*! +* \brief Sets the stroke width for all of the figures from the @p paint. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] width The width of the stroke. The default value is 0. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +*/ +TVG_API Tvg_Result tvg_shape_set_stroke_width(Tvg_Paint* paint, float width); + + +/*! +* \brief Gets the shape's stroke width. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] width The stroke width. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument. +*/ +TVG_API Tvg_Result tvg_shape_get_stroke_width(const Tvg_Paint* paint, float* width); + + +/*! +* \brief Sets the shape's stroke color. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0. +* \param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0. +* \param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. +* \param[in] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +* +* \note Either a solid color or a gradient fill is applied, depending on what was set as last. +*/ +TVG_API Tvg_Result tvg_shape_set_stroke_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a); + + +/*! +* \brief Gets the shape's stroke color. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] r The red color channel value in the range [0 ~ 255]. The default value is 0. +* \param[out] g The green color channel value in the range [0 ~ 255]. The default value is 0. +* \param[out] b The blue color channel value in the range [0 ~ 255]. The default value is 0. +* \param[out] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION No stroke was set. +*/ +TVG_API Tvg_Result tvg_shape_get_stroke_color(const Tvg_Paint* paint, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a); + + +/*! +* \brief Sets the linear gradient fill of the stroke for all of the figures from the path. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] grad The linear gradient fill. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +* \retval TVG_RESULT_MEMORY_CORRUPTION An invalid Tvg_Gradient pointer. +* +* \note Either a solid color or a gradient fill is applied, depending on what was set as last. +*/ +TVG_API Tvg_Result tvg_shape_set_stroke_linear_gradient(Tvg_Paint* paint, Tvg_Gradient* grad); + + +/*! +* \brief Sets the radial gradient fill of the stroke for all of the figures from the path. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] grad The radial gradient fill. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +* \retval TVG_RESULT_MEMORY_CORRUPTION An invalid Tvg_Gradient pointer. +* +* \note Either a solid color or a gradient fill is applied, depending on what was set as last. +*/ +TVG_API Tvg_Result tvg_shape_set_stroke_radial_gradient(Tvg_Paint* paint, Tvg_Gradient* grad); + + +/*! +* \brief Gets the gradient fill of the shape's stroke. +* +* The function does not allocate any memory. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] grad The gradient fill. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument. +*/ +TVG_API Tvg_Result tvg_shape_get_stroke_gradient(const Tvg_Paint* paint, Tvg_Gradient** grad); + + +/*! +* \brief Sets the shape's stroke dash pattern. +* +* \code +* //dash pattern examples +* float dashPattern[2] = {20, 10}; // -- -- -- +* float dashPattern[2] = {40, 20}; // ---- ---- ---- +* float dashPattern[4] = {10, 20, 30, 40} // - --- - --- +* \endcode +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] dashPattern The array of consecutive pair values of the dash length and the gap length. +* \param[in] cnt The size of the @p dashPattern array. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument and @p cnt > 0, the given length of the array is less than two or any of the @p dashPattern values is zero or less. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +* +* \note To reset the stroke dash pattern, pass @c nullptr to @p dashPattern and zero to @p cnt. +*/ +TVG_API Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt); + + +/*! +* \brief Gets the dash pattern of the stroke. +* +* The function does not allocate any memory. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] dashPattern The array of consecutive pair values of the dash length and the gap length. +* \param[out] cnt The size of the @p dashPattern array. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument. +*/ +TVG_API Tvg_Result tvg_shape_get_stroke_dash(const Tvg_Paint* paint, const float** dashPattern, uint32_t* cnt); + + +/*! +* \brief Sets the cap style used for stroking the path. +* +* The cap style specifies the shape to be used at the end of the open stroked sub-paths. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] cap The cap style value. The default value is @c TVG_STROKE_CAP_SQUARE. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +*/ +TVG_API Tvg_Result tvg_shape_set_stroke_cap(Tvg_Paint* paint, Tvg_Stroke_Cap cap); + + +/*! +* \brief Gets the stroke cap style used for stroking the path. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] cap The cap style value. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument. +*/ +TVG_API Tvg_Result tvg_shape_get_stroke_cap(const Tvg_Paint* paint, Tvg_Stroke_Cap* cap); + + +/*! +* \brief Sets the join style for stroked path segments. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] join The join style value. The default value is @c TVG_STROKE_JOIN_BEVEL. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +*/ +TVG_API Tvg_Result tvg_shape_set_stroke_join(Tvg_Paint* paint, Tvg_Stroke_Join join); + + +/*! +* \brief The function gets the stroke join method +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] join The join style value. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument. +*/ +TVG_API Tvg_Result tvg_shape_get_stroke_join(const Tvg_Paint* paint, Tvg_Stroke_Join* join); + + +/*! +* \brief Sets the stroke miterlimit. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] miterlimit The miterlimit imposes a limit on the extent of the stroke join when the @c TVG_STROKE_JOIN_MITER join style is set. The default value is 4. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_NOT_SUPPORTED Unsupported value. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +* +* \since 0.11 +*/ +TVG_API Tvg_Result tvg_shape_set_stroke_miterlimit(Tvg_Paint* paint, float miterlimit); + + +/*! +* \brief The function gets the stroke miterlimit. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] miterlimit The stroke miterlimit. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument. +* +* \since 0.11 +*/ +TVG_API Tvg_Result tvg_shape_get_stroke_miterlimit(const Tvg_Paint* paint, float* miterlimit); + + +/*! +* \brief Sets the shape's solid color. +* +* The parts of the shape defined as inner are colored. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0. +* \param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0. +* \param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. +* \param[in] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. The default value is 0. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* +* \note Either a solid color or a gradient fill is applied, depending on what was set as last. +* \see tvg_shape_set_fill_rule() +*/ +TVG_API Tvg_Result tvg_shape_set_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a); + + +/*! +* \brief Gets the shape's solid color. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] r The red color channel value in the range [0 ~ 255]. The default value is 0. +* \param[out] g The green color channel value in the range [0 ~ 255]. The default value is 0. +* \param[out] b The blue color channel value in the range [0 ~ 255]. The default value is 0. +* \param[out] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. The default value is 0. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +*/ +TVG_API Tvg_Result tvg_shape_get_fill_color(const Tvg_Paint* paint, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a); + + +/*! +* \brief Sets the shape's fill rule. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] rule The fill rule value. The default value is @c TVG_FILL_RULE_WINDING. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +*/ +TVG_API Tvg_Result tvg_shape_set_fill_rule(Tvg_Paint* paint, Tvg_Fill_Rule rule); + + +/*! +* \brief Gets the shape's fill rule. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] rule shape's fill rule +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument. +*/ +TVG_API Tvg_Result tvg_shape_get_fill_rule(const Tvg_Paint* paint, Tvg_Fill_Rule* rule); + + +/*! +* \brief Sets the rendering order of the stroke and the fill. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] strokeFirst If @c true the stroke is rendered before the fill, otherwise the stroke is rendered as the second one (the default option). +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +* +* \since 0.10 +*/ +TVG_API Tvg_Result tvg_shape_set_paint_order(Tvg_Paint* paint, bool strokeFirst); + + +/*! +* \brief Sets the linear gradient fill for all of the figures from the path. +* +* The parts of the shape defined as inner are filled. +* +* \code +* Tvg_Gradient* grad = tvg_linear_gradient_new(); +* tvg_linear_gradient_set(grad, 700, 700, 800, 800); +* Tvg_Color_Stop color_stops[4] = +* { +* {0.0 , 0, 0, 0, 255}, +* {0.25, 255, 0, 0, 255}, +* {0.5 , 0, 255, 0, 255}, +* {1.0 , 0, 0, 255, 255} +* }; +* tvg_gradient_set_color_stops(grad, color_stops, 4); +* tvg_shape_set_linear_gradient(shape, grad); +* \endcode +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] grad The linear gradient fill. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_MEMORY_CORRUPTION An invalid Tvg_Gradient pointer. +* +* \note Either a solid color or a gradient fill is applied, depending on what was set as last. +* \see tvg_shape_set_fill_rule() +*/ +TVG_API Tvg_Result tvg_shape_set_linear_gradient(Tvg_Paint* paint, Tvg_Gradient* grad); + + +/*! +* \brief Sets the radial gradient fill for all of the figures from the path. +* +* The parts of the shape defined as inner are filled. +* +* \code +* Tvg_Gradient* grad = tvg_radial_gradient_new(); +* tvg_radial_gradient_set(grad, 550, 550, 50); +* Tvg_Color_Stop color_stops[4] = +* { +* {0.0 , 0, 0, 0, 255}, +* {0.25, 255, 0, 0, 255}, +* {0.5 , 0, 255, 0, 255}, +* {1.0 , 0, 0, 255, 255} +* }; +* tvg_gradient_set_color_stops(grad, color_stops, 4); +* tvg_shape_set_radial_gradient(shape, grad); +* \endcode +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[in] grad The radial gradient fill. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_MEMORY_CORRUPTION An invalid Tvg_Gradient pointer. +* +* \note Either a solid color or a gradient fill is applied, depending on what was set as last. +* \see tvg_shape_set_fill_rule() +*/ +TVG_API Tvg_Result tvg_shape_set_radial_gradient(Tvg_Paint* paint, Tvg_Gradient* grad); + + +/*! +* \brief Gets the gradient fill of the shape. +* +* The function does not allocate any data. +* +* \param[in] paint A Tvg_Paint pointer to the shape object. +* \param[out] grad The gradient fill. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument. +*/ +TVG_API Tvg_Result tvg_shape_get_gradient(const Tvg_Paint* paint, Tvg_Gradient** grad); + + +/** \} */ // end defgroup ThorVGCapi_Shape + + +/** +* \defgroup ThorVGCapi_Gradient Gradient +* \brief A module managing the gradient fill of objects. +* +* The module enables to set and to get the gradient colors and their arrangement inside the gradient bounds, +* to specify the gradient bounds and the gradient behavior in case the area defined by the gradient bounds +* is smaller than the area to be filled. +* +* \{ +*/ + +/************************************************************************/ +/* Gradient API */ +/************************************************************************/ +/*! +* \brief Creates a new linear gradient object. +* +* \code +* Tvg_Paint* shape = tvg_shape_new(); +* tvg_shape_append_rect(shape, 700, 700, 100, 100, 20, 20); +* Tvg_Gradient* grad = tvg_linear_gradient_new(); +* tvg_linear_gradient_set(grad, 700, 700, 800, 800); +* Tvg_Color_Stop color_stops[2] = +* { +* {0.0, 0, 0, 0, 255}, +* {1.0, 0, 255, 0, 255}, +* }; +* tvg_gradient_set_color_stops(grad, color_stops, 2); +* tvg_shape_set_linear_gradient(shape, grad); +* \endcode +* +* \return A new linear gradient object. +*/ +TVG_API Tvg_Gradient* tvg_linear_gradient_new(void); + + +/*! +* \brief Creates a new radial gradient object. +* +* \code +* Tvg_Paint* shape = tvg_shape_new(); +* tvg_shape_append_rect(shape, 700, 700, 100, 100, 20, 20); +* Tvg_Gradient* grad = tvg_radial_gradient_new(); +* tvg_radial_gradient_set(grad, 550, 550, 50); +* Tvg_Color_Stop color_stops[2] = +* { +* {0.0, 0, 0, 0, 255}, +* {1.0, 0, 255, 0, 255}, +* }; +* tvg_gradient_set_color_stops(grad, color_stops, 2); +* tvg_shape_set_radial_gradient(shape, grad); +* \endcode +* +* \return A new radial gradient object. +*/ +TVG_API Tvg_Gradient* tvg_radial_gradient_new(void); + + +/*! +* \brief Sets the linear gradient bounds. +* +* The bounds of the linear gradient are defined as a surface constrained by two parallel lines crossing +* the given points (@p x1, @p y1) and (@p x2, @p y2), respectively. Both lines are perpendicular to the line linking +* (@p x1, @p y1) and (@p x2, @p y2). +* +* \param[in] grad The Tvg_Gradient object of which bounds are to be set. +* @param[in] x1 The horizontal coordinate of the first point used to determine the gradient bounds. +* @param[in] y1 The vertical coordinate of the first point used to determine the gradient bounds. +* @param[in] x2 The horizontal coordinate of the second point used to determine the gradient bounds. +* @param[in] y2 The vertical coordinate of the second point used to determine the gradient bounds. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Gradient pointer. +* +* \note In case the first and the second points are equal, an object filled with such a gradient fill is not rendered. +*/ +TVG_API Tvg_Result tvg_linear_gradient_set(Tvg_Gradient* grad, float x1, float y1, float x2, float y2); + + +/*! +* \brief Gets the linear gradient bounds. +* +* The bounds of the linear gradient are defined as a surface constrained by two parallel lines crossing +* the given points (@p x1, @p y1) and (@p x2, @p y2), respectively. Both lines are perpendicular to the line linking +* (@p x1, @p y1) and (@p x2, @p y2). +* +* \param[in] grad The Tvg_Gradient object of which to get the bounds. +* \param[out] x1 The horizontal coordinate of the first point used to determine the gradient bounds. +* \param[out] y1 The vertical coordinate of the first point used to determine the gradient bounds. +* \param[out] x2 The horizontal coordinate of the second point used to determine the gradient bounds. +* \param[out] y2 The vertical coordinate of the second point used to determine the gradient bounds. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Gradient pointer. +*/ +TVG_API Tvg_Result tvg_linear_gradient_get(Tvg_Gradient* grad, float* x1, float* y1, float* x2, float* y2); + + +/*! +* \brief Sets the radial gradient bounds. +* +* The radial gradient bounds are defined as a circle centered in a given point (@p cx, @p cy) of a given radius. +* +* \param[in] grad The Tvg_Gradient object of which bounds are to be set. +* \param[in] cx The horizontal coordinate of the center of the bounding circle. +* \param[in] cy The vertical coordinate of the center of the bounding circle. +* \param[in] radius The radius of the bounding circle. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Gradient pointer or the @p radius value less than zero. +*/ +TVG_API Tvg_Result tvg_radial_gradient_set(Tvg_Gradient* grad, float cx, float cy, float radius); + + +/*! +* \brief The function gets radial gradient center point ant radius +* +* \param[in] grad The Tvg_Gradient object of which bounds are to be set. +* \param[out] cx The horizontal coordinate of the center of the bounding circle. +* \param[out] cy The vertical coordinate of the center of the bounding circle. +* \param[out] radius The radius of the bounding circle. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Gradient pointer. +*/ +TVG_API Tvg_Result tvg_radial_gradient_get(Tvg_Gradient* grad, float* cx, float* cy, float* radius); + + +/*! +* \brief Sets the parameters of the colors of the gradient and their position. +* +* \param[in] grad The Tvg_Gradient object of which the color information is to be set. +* \param[in] color_stop An array of Tvg_Color_Stop data structure. +* \param[in] cnt The size of the @p color_stop array equal to the colors number used in the gradient. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Gradient pointer. +*/ +TVG_API Tvg_Result tvg_gradient_set_color_stops(Tvg_Gradient* grad, const Tvg_Color_Stop* color_stop, uint32_t cnt); + + +/*! +* \brief Gets the parameters of the colors of the gradient, their position and number +* +* The function does not allocate any memory. +* +* \param[in] grad The Tvg_Gradient object of which to get the color information. +* \param[out] color_stop An array of Tvg_Color_Stop data structure. +* \param[out] cnt The size of the @p color_stop array equal to the colors number used in the gradient. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the argument. +*/ +TVG_API Tvg_Result tvg_gradient_get_color_stops(const Tvg_Gradient* grad, const Tvg_Color_Stop** color_stop, uint32_t* cnt); + + +/*! +* \brief Sets the Tvg_Stroke_Fill value, which specifies how to fill the area outside the gradient bounds. +* +* \param[in] grad The Tvg_Gradient object. +* \param[in] spread The FillSpread value. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Gradient pointer. +*/ +TVG_API Tvg_Result tvg_gradient_set_spread(Tvg_Gradient* grad, const Tvg_Stroke_Fill spread); + + +/*! +* \brief Gets the FillSpread value of the gradient object. +* +* \param[in] grad The Tvg_Gradient object. +* \param[out] spread The FillSpread value. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the argument. +*/ +TVG_API Tvg_Result tvg_gradient_get_spread(const Tvg_Gradient* grad, Tvg_Stroke_Fill* spread); + + +/*! +* \brief Sets the matrix of the affine transformation for the gradient object. +* +* The augmented matrix of the transformation is expected to be given. +* +* \param[in] grad The Tvg_Gradient object to be transformed. +* \param[in] m The 3x3 augmented matrix. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr is passed as the argument. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +*/ +TVG_API Tvg_Result tvg_gradient_set_transform(Tvg_Gradient* grad, const Tvg_Matrix* m); + + +/*! +* \brief Gets the matrix of the affine transformation of the gradient object. +* +* In case no transformation was applied, the identity matrix is set. +* +* \param[in] grad The Tvg_Gradient object of which to get the transformation matrix. +* \param[out] m The 3x3 augmented matrix. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr is passed as the argument. +*/ +TVG_API Tvg_Result tvg_gradient_get_transform(const Tvg_Gradient* grad, Tvg_Matrix* m); + +/** +* \brief Gets the unique id value of the gradient instance indicating the instance type. +* +* \param[in] grad The Tvg_Gradient object of which to get the identifier value. +* \param[out] identifier The unique identifier of the gradient instance type. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. +* +* \since 0.9 +*/ +TVG_API Tvg_Result tvg_gradient_get_identifier(const Tvg_Gradient* grad, Tvg_Identifier* identifier); + + +/*! +* \brief Duplicates the given Tvg_Gradient object. +* +* Creates a new object and sets its all properties as in the original object. +* +* \param[in] grad The Tvg_Gradient object to be copied. +* +* \return A copied Tvg_Gradient object if succeed, @c nullptr otherwise. +*/ +TVG_API Tvg_Gradient* tvg_gradient_duplicate(Tvg_Gradient* grad); + + +/*! +* \brief Deletes the given gradient object. +* +* \param[in] grad The gradient object to be deleted. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Gradient pointer. +*/ +TVG_API Tvg_Result tvg_gradient_del(Tvg_Gradient* grad); + + +/** \} */ // end defgroup ThorVGCapi_Gradient + + +/** +* \defgroup ThorVGCapi_Picture Picture +* +* \brief A module enabling to create and to load an image in one of the supported formats: svg, png, jpg, lottie and raw. +* +* +* \{ +*/ + +/************************************************************************/ +/* Picture API */ +/************************************************************************/ +/*! +* \brief Creates a new picture object. +* +* \return A new picture object. +*/ +TVG_API Tvg_Paint* tvg_picture_new(void); + + +/*! +* \brief Loads a picture data directly from a file. +* +* ThorVG efficiently caches the loaded data using the specified @p path as a key. +* This means that loading the same file again will not result in duplicate operations; +* instead, ThorVG will reuse the previously loaded picture data. +* +* \param[in] paint A Tvg_Paint pointer to the picture object. +* \param[in] path The absolute path to the image file. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer or an empty @p path. +* \retval TVG_RESULT_NOT_SUPPORTED A file with an unknown extension. +* \retval TVG_RESULT_UNKNOWN An error at a later stage. +*/ +TVG_API Tvg_Result tvg_picture_load(Tvg_Paint* paint, const char* path); + + +/*! +* \brief Loads a picture data from a memory block of a given size. +* +* ThorVG efficiently caches the loaded data using the specified @p data address as a key +* when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations +* for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data. +* +* \param[in] paint A Tvg_Paint pointer to the picture object. +* \param[in] data A pointer to a memory location where the content of the picture raw data is stored. +* \param[in] w The width of the image @p data in pixels. +* \param[in] h The height of the image @p data in pixels. +* \param[in] premultiplied If @c true, the given image data is alpha-premultiplied. +* \param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer or no data are provided or the @p width or @p height value is zero or less. +* \retval TVG_RESULT_FAILED_ALLOCATION A problem with memory allocation occurs. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION An error occurs at a later stage. +* +* \since 0.9 +*/ +TVG_API Tvg_Result tvg_picture_load_raw(Tvg_Paint* paint, uint32_t *data, uint32_t w, uint32_t h, bool copy); + + +/*! +* \brief Loads a picture data from a memory block of a given size. +* +* ThorVG efficiently caches the loaded data using the specified @p data address as a key +* when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations +* for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data. +* +* \param[in] paint A Tvg_Paint pointer to the picture object. +* \param[in] data A pointer to a memory location where the content of the picture file is stored. +* \param[in] size The size in bytes of the memory occupied by the @p data. +* \param[in] mimetype Mimetype or extension of data such as "jpg", "jpeg", "svg", "svg+xml", "lottie", "png", etc. In case an empty string or an unknown type is provided, the loaders will be tried one by one. +* \param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument or the @p size is zero or less. +* \retval TVG_RESULT_NOT_SUPPORTED A file with an unknown extension. +* \retval TVG_RESULT_UNKNOWN An error at a later stage. +* +* \warning: It's the user responsibility to release the @p data memory if the @p copy is @c true. +*/ +TVG_API Tvg_Result tvg_picture_load_data(Tvg_Paint* paint, const char *data, uint32_t size, const char *mimetype, bool copy); + + +/*! +* \brief Resizes the picture content to the given width and height. +* +* The picture content is resized while keeping the default size aspect ratio. +* The scaling factor is established for each of dimensions and the smaller value is applied to both of them. +* +* \param[in] paint A Tvg_Paint pointer to the picture object. +* \param[in] w A new width of the image in pixels. +* \param[in] h A new height of the image in pixels. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION An internal error. +*/ +TVG_API Tvg_Result tvg_picture_set_size(Tvg_Paint* paint, float w, float h); + + +/*! +* \brief Gets the size of the loaded picture. +* +* \param[in] paint A Tvg_Paint pointer to the picture object. +* \param[out] w A width of the image in pixels. +* \param[out] h A height of the image in pixels. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +*/ +TVG_API Tvg_Result tvg_picture_get_size(const Tvg_Paint* paint, float* w, float* h); + + +/** \} */ // end defgroup ThorVGCapi_Picture + + +/** +* \defgroup ThorVGCapi_Scene Scene +* \brief A module managing the multiple paints as one group paint. +* +* As a group, scene can be transformed, translucent, composited with other target paints, +* its children will be affected by the scene world. +* +* \{ +*/ + +/************************************************************************/ +/* Scene API */ +/************************************************************************/ +/*! +* \brief Creates a new scene object. +* +* A scene object is used to group many paints into one object, which can be manipulated using TVG APIs. +* +* \return A new scene object. +*/ +TVG_API Tvg_Paint* tvg_scene_new(void); + + +/*! +* \brief Sets the size of the container, where all the paints pushed into the scene are stored. +* +* If the number of objects pushed into the scene is known in advance, calling the function +* prevents multiple memory reallocation, thus improving the performance. +* +* \param[in] scene A Tvg_Paint pointer to the scene object. +* \param[in] size The number of objects for which the memory is to be reserved. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. +*/ +TVG_DEPRECATED TVG_API Tvg_Result tvg_scene_reserve(Tvg_Paint* scene, uint32_t size); + + +/*! +* \brief Passes drawing elements to the scene using Tvg_Paint objects. +* +* Only the paints pushed into the scene will be the drawn targets. +* The paints are retained by the scene until the tvg_scene_clear() is called. +* If you know the number of pushed objects in advance, please call tvg_scene_reserve(). +* +* \param[in] scene A Tvg_Paint pointer to the scene object. +* \param[in] paint A graphical object to be drawn. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the argument. +* \retval TVG_RESULT_MEMORY_CORRUPTION An internal error. +* +* \note The rendering order of the paints is the same as the order as they were pushed. Consider sorting the paints before pushing them if you intend to use layering. +*/ +TVG_API Tvg_Result tvg_scene_push(Tvg_Paint* scene, Tvg_Paint* paint); + + +/*! +* \brief Clears a Tvg_Scene objects from pushed paints. +* +* Tvg_Paint objects stored in the scene are released if @p free is set to @c true, otherwise the memory is not deallocated and +* all paints should be released manually in order to avoid memory leaks. +* +* \param[in] scene The Tvg_Scene object to be cleared. +* \param[in] free If @c true the memory occupied by paints is deallocated, otherwise it is not. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Canvas pointer. +* +* \warning Please use the @p free argument only when you know how it works, otherwise it's not recommended. +*/ +TVG_API Tvg_Result tvg_scene_clear(Tvg_Paint* scene, bool free); + +/** \} */ // end defgroup ThorVGCapi_Scene + + +/** +* \defgroup ThorVGCapi_Saver Saver +* \brief A module for exporting a paint object into a specified file. +* +* The module enables to save the composed scene and/or image from a paint object. +* Once it's successfully exported to a file, it can be recreated using the Picture module. +* +* \{ +*/ + +/************************************************************************/ +/* Saver API */ +/************************************************************************/ +/*! +* \brief Creates a new Tvg_Saver object. +* +* \return A new Tvg_Saver object. +*/ +TVG_API Tvg_Saver* tvg_saver_new(void); + + +/*! +* \brief Exports the given @p paint data to the given @p path +* +* If the saver module supports any compression mechanism, it will optimize the data size. +* This might affect the encoding/decoding time in some cases. You can turn off the compression +* if you wish to optimize for speed. +* +* \param[in] saver The Tvg_Saver object connected with the saving task. +* \param[in] paint The paint to be saved with all its associated properties. +* \param[in] path A path to the file, in which the paint data is to be saved. +* \param[in] compress If @c true then compress data if possible. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the argument. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION Currently saving other resources. +* \retval TVG_RESULT_NOT_SUPPORTED Trying to save a file with an unknown extension or in an unsupported format. +* \retval TVG_RESULT_MEMORY_CORRUPTION An internal error. +* \retval TVG_RESULT_UNKNOWN An empty paint is to be saved. +* +* \note Saving can be asynchronous if the assigned thread number is greater than zero. To guarantee the saving is done, call tvg_saver_sync() afterwards. +* \see tvg_saver_sync() +*/ +TVG_API Tvg_Result tvg_saver_save(Tvg_Saver* saver, Tvg_Paint* paint, const char* path, bool compress); + + +/*! +* \brief Guarantees that the saving task is finished. +* +* The behavior of the Saver module works on a sync/async basis, depending on the threading setting of the Initializer. +* Thus, if you wish to have a benefit of it, you must call tvg_saver_sync() after the tvg_saver_save() in the proper delayed time. +* Otherwise, you can call tvg_saver_sync() immediately. +* +* \param[in] saver The Tvg_Saver object connected with the saving task. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the argument. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION No saving task is running. +* +* \note The asynchronous tasking is dependent on the Saver module implementation. +* \see tvg_saver_save() +*/ +TVG_API Tvg_Result tvg_saver_sync(Tvg_Saver* saver); + + +/*! +* \brief Deletes the given Tvg_Saver object. +* +* \param[in] saver The Tvg_Saver object to be deleted. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Saver pointer. +*/ +TVG_API Tvg_Result tvg_saver_del(Tvg_Saver* saver); + + +/** \} */ // end defgroup ThorVGCapi_Saver + + +/** +* \defgroup ThorVGCapi_Animation Animation +* \brief A module for manipulation of animatable images. +* +* The module supports the display and control of animation frames. +* +* \{ +*/ + +/************************************************************************/ +/* Animation API */ +/************************************************************************/ + +/*! +* \brief Creates a new Animation object. +* +* \return Tvg_Animation A new Tvg_Animation object. +* +* \since 0.13 +*/ +TVG_API Tvg_Animation* tvg_animation_new(void); + + +/*! +* \brief Specifies the current frame in the animation. +* +* \param[in] animation A Tvg_Animation pointer to the animation object. +* \param[in] no The index of the animation frame to be displayed. The index should be less than the tvg_animation_total_frame(). +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Animation pointer. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION No animatable data loaded from the Picture. +* \retval TVG_RESULT_NOT_SUPPORTED The picture data does not support animations. +* +* \note For efficiency, ThorVG ignores updates to the new frame value if the difference from the current frame value +* is less than 0.001. In such cases, it returns @c Result::InsufficientCondition. +* Values less than 0.001 may be disregarded and may not be accurately retained by the Animation. +* \see tvg_animation_get_total_frame() +* +* \since 0.13 +*/ +TVG_API Tvg_Result tvg_animation_set_frame(Tvg_Animation* animation, float no); + + +/*! +* \brief Retrieves a picture instance associated with this animation instance. +* +* This function provides access to the picture instance that can be used to load animation formats, such as Lottie(json). +* After setting up the picture, it can be pushed to the designated canvas, enabling control over animation frames +* with this Animation instance. +* +* \param[in] animation A Tvg_Animation pointer to the animation object. +* +* \return A picture instance that is tied to this animation. +* +* \warning The picture instance is owned by Animation. It should not be deleted manually. +* +* \since 0.13 +*/ +TVG_API Tvg_Paint* tvg_animation_get_picture(Tvg_Animation* animation); + + +/*! +* \brief Retrieves the current frame number of the animation. +* +* \param[in] animation A Tvg_Animation pointer to the animation object. +* \param[in] no The current frame number of the animation, between 0 and totalFrame() - 1. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Animation pointer or @p no +* +* \see tvg_animation_get_total_frame() +* \see tvg_animation_set_frame() +* +* \since 0.13 +*/ +TVG_API Tvg_Result tvg_animation_get_frame(Tvg_Animation* animation, float* no); + + +/*! +* \brief Retrieves the total number of frames in the animation. +* +* \param[in] animation A Tvg_Animation pointer to the animation object. +* \param[in] cnt The total number of frames in the animation. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Animation pointer or @p cnt. +* +* \note Frame numbering starts from 0. +* \note If the Picture is not properly configured, this function will return 0. +* +* \since 0.13 +*/ +TVG_API Tvg_Result tvg_animation_get_total_frame(Tvg_Animation* animation, float* cnt); + + +/*! +* \brief Retrieves the duration of the animation in seconds. +* +* \param[in] animation A Tvg_Animation pointer to the animation object. +* \param[in] duration The duration of the animation in seconds. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Animation pointer or @p duration. +* +* \note If the Picture is not properly configured, this function will return 0. +* +* \since 0.13 +*/ +TVG_API Tvg_Result tvg_animation_get_duration(Tvg_Animation* animation, float* duration); + + +/*! +* \brief Specifies the playback segment of the animation. (Experimental API) +* +* \param[in] animation The Tvg_Animation pointer to the animation object. +* \param[in] begin segment begin. +* \param[in] end segment end. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION In case the animation is not loaded. +* \retval TVG_RESULT_INVALID_ARGUMENT When the given parameters are out of range. +* +* \since 0.13 +*/ +TVG_API Tvg_Result tvg_animation_set_segment(Tvg_Animation* animation, float begin, float end); + + +/*! +* \brief Gets the current segment. (Experimental API) +* +* \param[in] animation The Tvg_Animation pointer to the animation object. +* \param[out] begin segment begin. +* \param[out] end segment end. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION In case the animation is not loaded. +* \retval TVG_RESULT_INVALID_ARGUMENT When the given parameters are @c nullptr. +*/ +TVG_API Tvg_Result tvg_animation_get_segment(Tvg_Animation* animation, float* begin, float* end); + + +/*! +* \brief Deletes the given Tvg_Animation object. +* +* \param[in] animation The Tvg_Animation object to be deleted. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Animation pointer. +* +* \since 0.13 +*/ +TVG_API Tvg_Result tvg_animation_del(Tvg_Animation* animation); + + +/** \} */ // end defgroup ThorVGCapi_Animation + + +/** +* \defgroup ThorVGCapi_LottieAnimation LottieAnimation +* \brief A module for manipulation of lottie extension features. +* +* The module enables control of advanced Lottie features. +* \{ +*/ + +/************************************************************************/ +/* LottieAnimation Extension API */ +/************************************************************************/ + +/*! +* \brief Creates a new LottieAnimation object. (Experimental API) +* +* \return Tvg_Animation A new Tvg_LottieAnimation object. +*/ +TVG_API Tvg_Animation* tvg_lottie_animation_new(void); + + +/*! +* \brief Override the lottie properties through the slot data. (Experimental API) +* +* \param[in] animation The Tvg_Animation object to override the property with the slot. +* \param[in] slot The Lottie slot data in json, or @c nullptr to reset. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION In case the animation is not loaded. +* \retval TVG_RESULT_INVALID_ARGUMENT When the given @p slot is invalid +* \retval TVG_RESULT_NOT_SUPPORTED The Lottie Animation is not supported. +*/ +TVG_API Tvg_Result tvg_lottie_animation_override(Tvg_Animation* animation, const char* slot); + + +/*! +* \brief Specifies a segment by marker. (Experimental API) +* +* \param[in] animation The Tvg_Animation pointer to the Lottie animation object. +* \param[in] marker The name of the segment marker. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION In case the animation is not loaded. +* \retval TVG_RESULT_INVALID_ARGUMENT When the given @p marker is invalid. +* \retval TVG_RESULT_NOT_SUPPORTED The Lottie Animation is not supported. +*/ +TVG_API Tvg_Result tvg_lottie_animation_set_marker(Tvg_Animation* animation, const char* marker); + + +/*! +* \brief Gets the marker count of the animation. (Experimental API) +* +* \param[in] animation The Tvg_Animation pointer to the Lottie animation object. +* \param[out] cnt The count value of the markers. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. +*/ +TVG_API Tvg_Result tvg_lottie_animation_get_markers_cnt(Tvg_Animation* animation, uint32_t* cnt); + + +/*! +* \brief Gets the marker name by a given index. (Experimental API) +* +* \param[in] animation The Tvg_Animation pointer to the Lottie animation object. +* \param[in] idx The index of the animation marker, starts from 0. +* \param[out] name The name of marker when succeed. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT In case @c nullptr is passed as the argument or @c idx is out of range. +*/ +TVG_API Tvg_Result tvg_lottie_animation_get_marker(Tvg_Animation* animation, uint32_t idx, const char** name); + + +/** \} */ // end addtogroup ThorVGCapi_LottieAnimation + + +/** \} */ // end defgroup ThorVGCapi + + +#ifdef __cplusplus +} +#endif + +#endif //_THORVG_CAPI_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/thorvg_lottie.h b/test/include/liblvgl/libs/thorvg/thorvg_lottie.h new file mode 100644 index 00000000..b69410ae --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/thorvg_lottie.h @@ -0,0 +1,100 @@ +#ifndef _THORVG_LOTTIE_H_ +#define _THORVG_LOTTIE_H_ + +#include "thorvg.h" + +namespace tvg +{ + +/** + * @class LottieAnimation + * + * @brief The LottieAnimation class enables control of advanced Lottie features. + * + * This class extends the Animation and has additional interfaces. + * + * @see Animation + * + * @note Experimental API + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL +class TVG_API LottieAnimation final : public Animation +{ +public: + ~LottieAnimation(); + + /** + * @brief Override Lottie properties using slot data. + * + * @param[in] slot The Lottie slot data in JSON format to override, or @c nullptr to reset. + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition In case the animation is not loaded. + * @retval Result::InvalidArguments When the given parameter is invalid. + * + * @note Experimental API + */ + Result override(const char* slot) noexcept; + + /** + * @brief Specifies a segment by marker. + * + * Markers are used to control animation playback by specifying start and end points, + * eliminating the need to know the exact frame numbers. + * Generally, markers are designated at the design level, + * meaning the callers must know the marker name in advance to use it. + * + * @param[in] marker The name of the segment marker. + * + * @retval Result::Success When successful. + * @retval Result::InsufficientCondition If the animation is not loaded. + * @retval Result::InvalidArguments When the given parameter is invalid. + * @retval Result::NonSupport When it's not animatable. + * + * @note If a @c marker is specified, the previously set segment will be disregarded. + * @note Set @c nullptr to reset the specified segment. + * @see Animation::segment(float begin, float end) + * @note Experimental API + */ + Result segment(const char* marker) noexcept; + + /** + * @brief Gets the marker count of the animation. + * + * @retval The count of the markers, zero if there is no marker. + * + * @see LottieAnimation::marker() + * @note Experimental API + */ + uint32_t markersCnt() noexcept; + + /** + * @brief Gets the marker name by a given index. + * + * @param[in] idx The index of the animation marker, starts from 0. + * + * @retval The name of marker when succeed, @c nullptr otherwise. + * + * @see LottieAnimation::markersCnt() + * @note Experimental API + */ + const char* marker(uint32_t idx) noexcept; + + /** + * @brief Creates a new LottieAnimation object. + * + * @return A new LottieAnimation object. + * + * @note Experimental API + */ + static std::unique_ptr gen() noexcept; +}; + +} //namespace + +#endif //_THORVG_LOTTIE_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgAccessor.cpp b/test/include/liblvgl/libs/thorvg/tvgAccessor.cpp new file mode 100644 index 00000000..e1f8608d --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgAccessor.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgIteratorAccessor.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static bool accessChildren(Iterator* it, function func) +{ + while (auto child = it->next()) { + //Access the child + if (!func(child)) return false; + + //Access the children of the child + if (auto it2 = IteratorAccessor::iterator(child)) { + if (!accessChildren(it2, func)) { + delete(it2); + return false; + } + delete(it2); + } + } + return true; +} + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +unique_ptr Accessor::set(unique_ptr picture, function func) noexcept +{ + auto p = picture.get(); + if (!p || !func) return picture; + + //Use the Preorder Tree-Search + + //Root + if (!func(p)) return picture; + + //Children + if (auto it = IteratorAccessor::iterator(p)) { + accessChildren(it, func); + delete(it); + } + return picture; +} + + +Accessor::~Accessor() +{ + +} + + +Accessor::Accessor() : pImpl(nullptr) +{ + +} + + +unique_ptr Accessor::gen() noexcept +{ + return unique_ptr(new Accessor); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgAnimation.cpp b/test/include/liblvgl/libs/thorvg/tvgAnimation.cpp new file mode 100644 index 00000000..399ee458 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgAnimation.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgFrameModule.h" +#include "tvgAnimation.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Animation::~Animation() +{ + delete(pImpl); +} + + +Animation::Animation() : pImpl(new Impl) +{ +} + + +Result Animation::frame(float no) noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + + if (!loader) return Result::InsufficientCondition; + if (!loader->animatable()) return Result::NonSupport; + + if (static_cast(loader)->frame(no)) return Result::Success; + return Result::InsufficientCondition; +} + + +Picture* Animation::picture() const noexcept +{ + return pImpl->picture; +} + + +float Animation::curFrame() const noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + + if (!loader) return 0; + if (!loader->animatable()) return 0; + + return static_cast(loader)->curFrame(); +} + + +float Animation::totalFrame() const noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + + if (!loader) return 0; + if (!loader->animatable()) return 0; + + return static_cast(loader)->totalFrame(); +} + + +float Animation::duration() const noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + + if (!loader) return 0; + if (!loader->animatable()) return 0; + + return static_cast(loader)->duration(); +} + + +Result Animation::segment(float begin, float end) noexcept +{ + if (begin < 0.0 || end > 1.0 || begin >= end) return Result::InvalidArguments; + + auto loader = pImpl->picture->pImpl->loader; + if (!loader) return Result::InsufficientCondition; + if (!loader->animatable()) return Result::NonSupport; + + static_cast(loader)->segment(begin, end); + + return Result::Success; +} + + +Result Animation::segment(float *begin, float *end) noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + if (!loader) return Result::InsufficientCondition; + if (!loader->animatable()) return Result::NonSupport; + if (!begin && !end) return Result::InvalidArguments; + + static_cast(loader)->segment(begin, end); + + return Result::Success; +} + + +unique_ptr Animation::gen() noexcept +{ + return unique_ptr(new Animation); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgAnimation.h b/test/include/liblvgl/libs/thorvg/tvgAnimation.h new file mode 100644 index 00000000..d0b45671 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgAnimation.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_ANIMATION_H_ +#define _TVG_ANIMATION_H_ + +#include "tvgCommon.h" +#include "tvgPaint.h" +#include "tvgPicture.h" + +struct Animation::Impl +{ + Picture* picture = nullptr; + + Impl() + { + picture = Picture::gen().release(); + PP(picture)->ref(); + } + + ~Impl() + { + if (PP(picture)->unref() == 0) { + delete(picture); + } + } +}; + +#endif //_TVG_ANIMATION_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgArray.h b/test/include/liblvgl/libs/thorvg/tvgArray.h new file mode 100644 index 00000000..33cd55ba --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgArray.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_ARRAY_H_ +#define _TVG_ARRAY_H_ + +#include +#include +#include + +namespace tvg +{ + +template +struct Array +{ + T* data = nullptr; + uint32_t count = 0; + uint32_t reserved = 0; + + Array(){} + + Array(int32_t size) + { + reserve(size); + } + + Array(const Array& rhs) + { + reset(); + *this = rhs; + } + + void push(T element) + { + if (count + 1 > reserved) { + reserved = count + (count + 2) / 2; + data = static_cast(realloc(data, sizeof(T) * reserved)); + } + data[count++] = element; + } + + void push(Array& rhs) + { + if (rhs.count == 0) return; + grow(rhs.count); + memcpy(data + count, rhs.data, rhs.count * sizeof(T)); + count += rhs.count; + } + + bool reserve(uint32_t size) + { + if (size > reserved) { + reserved = size; + data = static_cast(realloc(data, sizeof(T) * reserved)); + } + return true; + } + + bool grow(uint32_t size) + { + return reserve(count + size); + } + + const T& operator[](size_t idx) const + { + return data[idx]; + } + + T& operator[](size_t idx) + { + return data[idx]; + } + + const T* begin() const + { + return data; + } + + T* begin() + { + return data; + } + + T* end() + { + return data + count; + } + + const T* end() const + { + return data + count; + } + + const T& last() const + { + return data[count - 1]; + } + + const T& first() const + { + return data[0]; + } + + T& last() + { + return data[count - 1]; + } + + T& first() + { + return data[0]; + } + + void pop() + { + if (count > 0) --count; + } + + void reset() + { + free(data); + data = nullptr; + count = reserved = 0; + } + + void clear() + { + count = 0; + } + + bool empty() const + { + return count == 0; + } + + template + void sort() + { + qsort(data, 0, static_cast(count) - 1); + } + + void operator=(const Array& rhs) + { + reserve(rhs.count); + if (rhs.count > 0) memcpy(data, rhs.data, sizeof(T) * rhs.count); + count = rhs.count; + } + + ~Array() + { + free(data); + } + +private: + template + void qsort(T* arr, int32_t low, int32_t high) + { + if (low < high) { + int32_t i = low; + int32_t j = high; + T tmp = arr[low]; + while (i < j) { + while (i < j && !COMPARE{}(arr[j], tmp)) --j; + if (i < j) { + arr[i] = arr[j]; + ++i; + } + while (i < j && COMPARE{}(arr[i], tmp)) ++i; + if (i < j) { + arr[j] = arr[i]; + --j; + } + } + arr[i] = tmp; + qsort(arr, low, i - 1); + qsort(arr, i + 1, high); + } + } +}; + +} + +#endif //_TVG_ARRAY_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgBinaryDesc.h b/test/include/liblvgl/libs/thorvg/tvgBinaryDesc.h new file mode 100644 index 00000000..add8b081 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgBinaryDesc.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_BINARY_DESC_H_ +#define _TVG_BINARY_DESC_H_ + +/* TODO: Need to consider whether uin8_t is enough size for extension... + Rather than optimal data, we can use enough size and data compress? */ + +using TvgBinByte = uint8_t; +using TvgBinCounter = uint32_t; +using TvgBinTag = TvgBinByte; +using TvgBinFlag = TvgBinByte; + + +//Header +#define TVG_HEADER_SIZE 33 //TVG_HEADER_SIGNATURE_LENGTH + TVG_HEADER_VERSION_LENGTH + 2*SIZE(float) + TVG_HEADER_RESERVED_LENGTH + TVG_HEADER_COMPRESS_SIZE +#define TVG_HEADER_SIGNATURE "ThorVG" +#define TVG_HEADER_SIGNATURE_LENGTH 6 +#define TVG_HEADER_VERSION "001200" //Major 00, Minor 12, Micro 00 +#define TVG_HEADER_VERSION_LENGTH 6 +#define TVG_HEADER_RESERVED_LENGTH 1 //Storing flags for extensions +#define TVG_HEADER_COMPRESS_SIZE 12 //TVG_HEADER_UNCOMPRESSED_SIZE + TVG_HEADER_COMPRESSED_SIZE + TVG_HEADER_COMPRESSED_SIZE_BITS +//Compress Size +#define TVG_HEADER_UNCOMPRESSED_SIZE 4 //SIZE (TvgBinCounter) +#define TVG_HEADER_COMPRESSED_SIZE 4 //SIZE (TvgBinCounter) +#define TVG_HEADER_COMPRESSED_SIZE_BITS 4 //SIZE (TvgBinCounter) +//Reserved Flag +#define TVG_HEAD_FLAG_COMPRESSED 0x01 + +//Paint Type +#define TVG_TAG_CLASS_PICTURE (TvgBinTag)0xfc +#define TVG_TAG_CLASS_SHAPE (TvgBinTag)0xfd +#define TVG_TAG_CLASS_SCENE (TvgBinTag)0xfe + + +//Paint +#define TVG_TAG_PAINT_OPACITY (TvgBinTag)0x10 +#define TVG_TAG_PAINT_TRANSFORM (TvgBinTag)0x11 +#define TVG_TAG_PAINT_CMP_TARGET (TvgBinTag)0x01 +#define TVG_TAG_PAINT_CMP_METHOD (TvgBinTag)0x20 + + +//TODO: Keep this for the compatibility, Remove in TVG 1.0 release +//Scene + #define TVG_TAG_SCENE_RESERVEDCNT (TvgBinTag)0x30 + + +//Shape +#define TVG_TAG_SHAPE_PATH (TvgBinTag)0x40 +#define TVG_TAG_SHAPE_STROKE (TvgBinTag)0x41 +#define TVG_TAG_SHAPE_FILL (TvgBinTag)0x42 +#define TVG_TAG_SHAPE_COLOR (TvgBinTag)0x43 +#define TVG_TAG_SHAPE_FILLRULE (TvgBinTag)0x44 + + +//Stroke +#define TVG_TAG_SHAPE_STROKE_CAP (TvgBinTag)0x50 +#define TVG_TAG_SHAPE_STROKE_JOIN (TvgBinTag)0x51 +#define TVG_TAG_SHAPE_STROKE_WIDTH (TvgBinTag)0x52 +#define TVG_TAG_SHAPE_STROKE_COLOR (TvgBinTag)0x53 +#define TVG_TAG_SHAPE_STROKE_FILL (TvgBinTag)0x54 +#define TVG_TAG_SHAPE_STROKE_DASHPTRN (TvgBinTag)0x55 +#define TVG_TAG_SHAPE_STROKE_MITERLIMIT (TvgBinTag)0x56 +#define TVG_TAG_SHAPE_STROKE_ORDER (TvgBinTag)0x57 +#define TVG_TAG_SHAPE_STROKE_DASH_OFFSET (TvgBinTag)0x58 + + +//Fill +#define TVG_TAG_FILL_LINEAR_GRADIENT (TvgBinTag)0x60 +#define TVG_TAG_FILL_RADIAL_GRADIENT (TvgBinTag)0x61 +#define TVG_TAG_FILL_COLORSTOPS (TvgBinTag)0x62 +#define TVG_TAG_FILL_FILLSPREAD (TvgBinTag)0x63 +#define TVG_TAG_FILL_TRANSFORM (TvgBinTag)0x64 +#define TVG_TAG_FILL_RADIAL_GRADIENT_FOCAL (TvgBinTag)0x65 + +//Picture +#define TVG_TAG_PICTURE_RAW_IMAGE (TvgBinTag)0x70 +#define TVG_TAG_PICTURE_MESH (TvgBinTag)0x71 + +#endif //_TVG_BINARY_DESC_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgCanvas.cpp b/test/include/liblvgl/libs/thorvg/tvgCanvas.cpp new file mode 100644 index 00000000..22a97c20 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgCanvas.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgCanvas.h" + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Canvas::Canvas(RenderMethod *pRenderer):pImpl(new Impl(pRenderer)) +{ +} + + +Canvas::~Canvas() +{ + delete(pImpl); +} + + +Result Canvas::reserve(TVG_UNUSED uint32_t n) noexcept +{ + return Result::NonSupport; +} + + +list& Canvas::paints() noexcept +{ + return pImpl->paints; +} + + +Result Canvas::push(unique_ptr paint) noexcept +{ + return pImpl->push(std::move(paint)); +} + + +Result Canvas::clear(bool free) noexcept +{ + return pImpl->clear(free); +} + + +Result Canvas::draw() noexcept +{ + TVGLOG("RENDERER", "Draw S. -------------------------------- Canvas(%p)", this); + auto ret = pImpl->draw(); + TVGLOG("RENDERER", "Draw E. -------------------------------- Canvas(%p)", this); + + return ret; +} + + +Result Canvas::update(Paint* paint) noexcept +{ + TVGLOG("RENDERER", "Update S. ------------------------------ Canvas(%p)", this); + auto ret = pImpl->update(paint, false); + TVGLOG("RENDERER", "Update E. ------------------------------ Canvas(%p)", this); + + return ret; +} + + +Result Canvas::viewport(int32_t x, int32_t y, int32_t w, int32_t h) noexcept +{ + return pImpl->viewport(x, y, w, h); +} + + +Result Canvas::sync() noexcept +{ + return pImpl->sync(); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgCanvas.h b/test/include/liblvgl/libs/thorvg/tvgCanvas.h new file mode 100644 index 00000000..171f6aae --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgCanvas.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_CANVAS_H_ +#define _TVG_CANVAS_H_ + +#include "tvgPaint.h" + + +struct Canvas::Impl +{ + enum Status : uint8_t {Synced = 0, Updating, Drawing}; + + list paints; + RenderMethod* renderer; + RenderRegion vport = {0, 0, INT32_MAX, INT32_MAX}; + Status status = Status::Synced; + + bool refresh = false; //if all paints should be updated by force. + + Impl(RenderMethod* pRenderer) : renderer(pRenderer) + { + renderer->ref(); + } + + ~Impl() + { + //make it sure any deferred jobs + renderer->sync(); + renderer->clear(); + + clearPaints(); + + if (renderer->unref() == 0) delete(renderer); + } + + void clearPaints() + { + for (auto paint : paints) { + if (P(paint)->unref() == 0) delete(paint); + } + paints.clear(); + } + + Result push(unique_ptr paint) + { + //You cannot push paints during rendering. + if (status == Status::Drawing) return Result::InsufficientCondition; + + auto p = paint.release(); + if (!p) return Result::MemoryCorruption; + PP(p)->ref(); + paints.push_back(p); + + return update(p, true); + } + + Result clear(bool free) + { + //Clear render target before drawing + if (!renderer->clear()) return Result::InsufficientCondition; + + //Free paints + if (free) clearPaints(); + + status = Status::Synced; + + return Result::Success; + } + + void needRefresh() + { + refresh = true; + } + + Result update(Paint* paint, bool force) + { + if (paints.empty() || status == Status::Drawing) return Result::InsufficientCondition; + + Array clips; + auto flag = RenderUpdateFlag::None; + if (refresh || force) flag = RenderUpdateFlag::All; + + if (paint) { + paint->pImpl->update(renderer, nullptr, clips, 255, flag); + } else { + for (auto paint : paints) { + paint->pImpl->update(renderer, nullptr, clips, 255, flag); + } + refresh = false; + } + status = Status::Updating; + return Result::Success; + } + + Result draw() + { + if (status == Status::Drawing || paints.empty() || !renderer->preRender()) return Result::InsufficientCondition; + + bool rendered = false; + for (auto paint : paints) { + if (paint->pImpl->render(renderer)) rendered = true; + } + + if (!rendered || !renderer->postRender()) return Result::InsufficientCondition; + + status = Status::Drawing; + return Result::Success; + } + + Result sync() + { + if (status == Status::Synced) return Result::InsufficientCondition; + + if (renderer->sync()) { + status = Status::Synced; + return Result::Success; + } + + return Result::InsufficientCondition; + } + + Result viewport(int32_t x, int32_t y, int32_t w, int32_t h) + { + if (status != Status::Synced) return Result::InsufficientCondition; + RenderRegion val = {x, y, w, h}; + //intersect if the target buffer is already set. + auto surface = renderer->mainSurface(); + if (surface && surface->w > 0 && surface->h > 0) { + val.intersect({0, 0, (int32_t)surface->w, (int32_t)surface->h}); + } + if (vport == val) return Result::Success; + renderer->viewport(val); + vport = val; + needRefresh(); + return Result::Success; + } +}; + +#endif /* _TVG_CANVAS_H_ */ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgCapi.cpp b/test/include/liblvgl/libs/thorvg/tvgCapi.cpp new file mode 100644 index 00000000..1720d508 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgCapi.cpp @@ -0,0 +1,871 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "config.h" +#include +#include "thorvg.h" +#include "thorvg_capi.h" +#ifdef THORVG_LOTTIE_LOADER_SUPPORT +#include "thorvg_lottie.h" +#endif + +using namespace std; +using namespace tvg; + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************/ +/* Engine API */ +/************************************************************************/ + +TVG_API Tvg_Result tvg_engine_init(Tvg_Engine engine_method, unsigned threads) +{ + return (Tvg_Result) Initializer::init(CanvasEngine(engine_method), threads); +} + + +TVG_API Tvg_Result tvg_engine_term(Tvg_Engine engine_method) +{ + return (Tvg_Result) Initializer::term(CanvasEngine(engine_method)); +} + + +/************************************************************************/ +/* Canvas API */ +/************************************************************************/ + +TVG_API Tvg_Canvas* tvg_swcanvas_create() +{ + return (Tvg_Canvas*) SwCanvas::gen().release(); +} + + +TVG_API Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + delete(reinterpret_cast(canvas)); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_swcanvas_set_mempool(Tvg_Canvas* canvas, Tvg_Mempool_Policy policy) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->mempool(static_cast(policy)); +} + + +TVG_API Tvg_Result tvg_swcanvas_set_target(Tvg_Canvas* canvas, uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Tvg_Colorspace cs) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->target(buffer, stride, w, h, static_cast(cs)); +} + + +TVG_API Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint) +{ + if (!canvas || !paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->push(unique_ptr((Paint*)paint)); +} + + +TVG_API Tvg_Result tvg_canvas_reserve(Tvg_Canvas* canvas, uint32_t n) +{ + return TVG_RESULT_NOT_SUPPORTED; +} + + +TVG_API Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas, bool free) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->clear(free); +} + + +TVG_API Tvg_Result tvg_canvas_update(Tvg_Canvas* canvas) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->update(nullptr); +} + + +TVG_API Tvg_Result tvg_canvas_est_viewport(Tvg_Canvas* canvas, int32_t x, int32_t y, int32_t w, int32_t h) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->viewport(x, y, w, h); +} + + +TVG_API Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint) +{ + if (!canvas || !paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->update((Paint*) paint); +} + + +TVG_API Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->draw(); +} + + +TVG_API Tvg_Result tvg_canvas_sync(Tvg_Canvas* canvas) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->sync(); +} + +TVG_API Tvg_Result tvg_canvas_set_viewport(Tvg_Canvas* canvas, int32_t x, int32_t y, int32_t w, int32_t h) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->viewport(x, y, w, h); +} + + +/************************************************************************/ +/* Paint API */ +/************************************************************************/ + +TVG_API Tvg_Result tvg_paint_del(Tvg_Paint* paint) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + delete(reinterpret_cast(paint)); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_paint_scale(Tvg_Paint* paint, float factor) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->scale(factor); +} + + +TVG_API Tvg_Result tvg_paint_rotate(Tvg_Paint* paint, float degree) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->rotate(degree); +} + + +TVG_API Tvg_Result tvg_paint_translate(Tvg_Paint* paint, float x, float y) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->translate(x, y); +} + + +TVG_API Tvg_Result tvg_paint_set_transform(Tvg_Paint* paint, const Tvg_Matrix* m) +{ + if (!paint || !m) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->transform(*(reinterpret_cast(m))); +} + + +TVG_API Tvg_Result tvg_paint_get_transform(Tvg_Paint* paint, Tvg_Matrix* m) +{ + if (!paint || !m) return TVG_RESULT_INVALID_ARGUMENT; + *reinterpret_cast(m) = reinterpret_cast(paint)->transform(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Paint* tvg_paint_duplicate(Tvg_Paint* paint) +{ + if (!paint) return nullptr; + return (Tvg_Paint*) reinterpret_cast(paint)->duplicate(); +} + + +TVG_API Tvg_Result tvg_paint_set_opacity(Tvg_Paint* paint, uint8_t opacity) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->opacity(opacity); +} + + +TVG_API Tvg_Result tvg_paint_get_opacity(const Tvg_Paint* paint, uint8_t* opacity) +{ + if (!paint || !opacity) return TVG_RESULT_INVALID_ARGUMENT; + *opacity = reinterpret_cast(paint)->opacity(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_paint_get_bounds(const Tvg_Paint* paint, float* x, float* y, float* w, float* h, bool transformed) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->bounds(x, y, w, h, transformed); +} + + +TVG_API Tvg_Result tvg_paint_set_composite_method(Tvg_Paint* paint, Tvg_Paint* target, Tvg_Composite_Method method) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->composite(unique_ptr((Paint*)(target)), (CompositeMethod)method); +} + + +TVG_API Tvg_Result tvg_paint_get_composite_method(const Tvg_Paint* paint, const Tvg_Paint** target, Tvg_Composite_Method* method) +{ + if (!paint || !target || !method) return TVG_RESULT_INVALID_ARGUMENT; + *reinterpret_cast(method) = reinterpret_cast(paint)->composite(reinterpret_cast(target)); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_paint_set_blend_method(const Tvg_Paint* paint, Tvg_Blend_Method method) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->blend((BlendMethod)method); +} + + +TVG_API Tvg_Result tvg_paint_get_blend_method(const Tvg_Paint* paint, Tvg_Blend_Method* method) +{ + if (!paint || !method) return TVG_RESULT_INVALID_ARGUMENT; + *method = static_cast(reinterpret_cast(paint)->blend()); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_paint_get_identifier(const Tvg_Paint* paint, Tvg_Identifier* identifier) +{ + if (!paint || !identifier) return TVG_RESULT_INVALID_ARGUMENT; + *identifier = static_cast(reinterpret_cast(paint)->identifier()); + return TVG_RESULT_SUCCESS; +} + +/************************************************************************/ +/* Shape API */ +/************************************************************************/ + +TVG_API Tvg_Paint* tvg_shape_new() +{ + return (Tvg_Paint*) Shape::gen().release(); +} + + +TVG_API Tvg_Result tvg_shape_reset(Tvg_Paint* paint) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->reset(); +} + + +TVG_API Tvg_Result tvg_shape_move_to(Tvg_Paint* paint, float x, float y) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->moveTo(x, y); +} + + +TVG_API Tvg_Result tvg_shape_line_to(Tvg_Paint* paint, float x, float y) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->lineTo(x, y); +} + + +TVG_API Tvg_Result tvg_shape_cubic_to(Tvg_Paint* paint, float cx1, float cy1, float cx2, float cy2, float x, float y) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->cubicTo(cx1, cy1, cx2, cy2, x, y); +} + + +TVG_API Tvg_Result tvg_shape_close(Tvg_Paint* paint) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->close(); +} + + +TVG_API Tvg_Result tvg_shape_append_rect(Tvg_Paint* paint, float x, float y, float w, float h, float rx, float ry) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->appendRect(x, y, w, h, rx, ry); +} + + +TVG_API Tvg_Result tvg_shape_append_arc(Tvg_Paint* paint, float cx, float cy, float radius, float startAngle, float sweep, uint8_t pie) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->appendArc(cx, cy, radius, startAngle, sweep, pie); +} + + +TVG_API Tvg_Result tvg_shape_append_circle(Tvg_Paint* paint, float cx, float cy, float rx, float ry) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->appendCircle(cx, cy, rx, ry); +} + + +TVG_API Tvg_Result tvg_shape_append_path(Tvg_Paint* paint, const Tvg_Path_Command* cmds, uint32_t cmdCnt, const Tvg_Point* pts, uint32_t ptsCnt) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->appendPath((const PathCommand*)cmds, cmdCnt, (const Point*)pts, ptsCnt); +} + + +TVG_API Tvg_Result tvg_shape_get_path_coords(const Tvg_Paint* paint, const Tvg_Point** pts, uint32_t* cnt) +{ + if (!paint || !pts || !cnt) return TVG_RESULT_INVALID_ARGUMENT; + *cnt = reinterpret_cast(paint)->pathCoords((const Point**)pts); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_shape_get_path_commands(const Tvg_Paint* paint, const Tvg_Path_Command** cmds, uint32_t* cnt) +{ + if (!paint || !cmds || !cnt) return TVG_RESULT_INVALID_ARGUMENT; + *cnt = reinterpret_cast(paint)->pathCommands((const PathCommand**)cmds); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_shape_set_stroke_width(Tvg_Paint* paint, float width) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->stroke(width); +} + + +TVG_API Tvg_Result tvg_shape_get_stroke_width(const Tvg_Paint* paint, float* width) +{ + if (!paint || !width) return TVG_RESULT_INVALID_ARGUMENT; + *width = reinterpret_cast(paint)->strokeWidth(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_shape_set_stroke_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->stroke(r, g, b, a); +} + + +TVG_API Tvg_Result tvg_shape_get_stroke_color(const Tvg_Paint* paint, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->strokeColor(r, g, b, a); +} + + +TVG_API Tvg_Result tvg_shape_set_stroke_linear_gradient(Tvg_Paint* paint, Tvg_Gradient* gradient) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->stroke(unique_ptr((LinearGradient*)(gradient))); +} + + +TVG_API Tvg_Result tvg_shape_set_stroke_radial_gradient(Tvg_Paint* paint, Tvg_Gradient* gradient) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->stroke(unique_ptr((RadialGradient*)(gradient))); +} + + +TVG_API Tvg_Result tvg_shape_get_stroke_gradient(const Tvg_Paint* paint, Tvg_Gradient** gradient) +{ + if (!paint || !gradient) return TVG_RESULT_INVALID_ARGUMENT; + *gradient = (Tvg_Gradient*)(reinterpret_cast(paint)->strokeFill()); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->stroke(dashPattern, cnt); +} + + +TVG_API Tvg_Result tvg_shape_get_stroke_dash(const Tvg_Paint* paint, const float** dashPattern, uint32_t* cnt) +{ + if (!paint || !cnt || !dashPattern) return TVG_RESULT_INVALID_ARGUMENT; + *cnt = reinterpret_cast(paint)->strokeDash(dashPattern); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_shape_set_stroke_cap(Tvg_Paint* paint, Tvg_Stroke_Cap cap) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->stroke((StrokeCap)cap); +} + + +TVG_API Tvg_Result tvg_shape_get_stroke_cap(const Tvg_Paint* paint, Tvg_Stroke_Cap* cap) +{ + if (!paint || !cap) return TVG_RESULT_INVALID_ARGUMENT; + *cap = (Tvg_Stroke_Cap) reinterpret_cast(paint)->strokeCap(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_shape_set_stroke_join(Tvg_Paint* paint, Tvg_Stroke_Join join) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->stroke((StrokeJoin)join); +} + + +TVG_API Tvg_Result tvg_shape_get_stroke_join(const Tvg_Paint* paint, Tvg_Stroke_Join* join) +{ + if (!paint || !join) return TVG_RESULT_INVALID_ARGUMENT; + *join = (Tvg_Stroke_Join) reinterpret_cast(paint)->strokeJoin(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_shape_set_stroke_miterlimit(Tvg_Paint* paint, float ml) +{ + if (ml < 0.0f) return TVG_RESULT_NOT_SUPPORTED; + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->strokeMiterlimit(ml); +} + + +TVG_API Tvg_Result tvg_shape_get_stroke_miterlimit(const Tvg_Paint* paint, float* ml) +{ + if (!paint || !ml) return TVG_RESULT_INVALID_ARGUMENT; + *ml = reinterpret_cast(paint)->strokeMiterlimit(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_shape_set_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->fill(r, g, b, a); +} + + +TVG_API Tvg_Result tvg_shape_get_fill_color(const Tvg_Paint* paint, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->fillColor(r, g, b, a); +} + + +TVG_API Tvg_Result tvg_shape_set_fill_rule(Tvg_Paint* paint, Tvg_Fill_Rule rule) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->fill((FillRule)rule); +} + + +TVG_API Tvg_Result tvg_shape_get_fill_rule(const Tvg_Paint* paint, Tvg_Fill_Rule* rule) +{ + if (!paint || !rule) return TVG_RESULT_INVALID_ARGUMENT; + *rule = (Tvg_Fill_Rule) reinterpret_cast(paint)->fillRule(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_shape_set_paint_order(Tvg_Paint* paint, bool strokeFirst) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->order(strokeFirst); +} + + +TVG_API Tvg_Result tvg_shape_set_linear_gradient(Tvg_Paint* paint, Tvg_Gradient* gradient) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->fill(unique_ptr((LinearGradient*)(gradient))); +} + + +TVG_API Tvg_Result tvg_shape_set_radial_gradient(Tvg_Paint* paint, Tvg_Gradient* gradient) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->fill(unique_ptr((RadialGradient*)(gradient))); +} + + +TVG_API Tvg_Result tvg_shape_get_gradient(const Tvg_Paint* paint, Tvg_Gradient** gradient) +{ + if (!paint || !gradient) return TVG_RESULT_INVALID_ARGUMENT; + *gradient = (Tvg_Gradient*)(reinterpret_cast(paint)->fill()); + return TVG_RESULT_SUCCESS; +} + +/************************************************************************/ +/* Picture API */ +/************************************************************************/ + +TVG_API Tvg_Paint* tvg_picture_new() +{ + return (Tvg_Paint*) Picture::gen().release(); +} + + +TVG_API Tvg_Result tvg_picture_load(Tvg_Paint* paint, const char* path) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->load(path); +} + + +TVG_API Tvg_Result tvg_picture_load_raw(Tvg_Paint* paint, uint32_t *data, uint32_t w, uint32_t h, bool copy) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->load(data, w, h, copy); +} + + +TVG_API Tvg_Result tvg_picture_load_data(Tvg_Paint* paint, const char *data, uint32_t size, const char *mimetype, bool copy) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->load(data, size, mimetype ? mimetype : "", copy); +} + + +TVG_API Tvg_Result tvg_picture_set_size(Tvg_Paint* paint, float w, float h) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->size(w, h); +} + + +TVG_API Tvg_Result tvg_picture_get_size(const Tvg_Paint* paint, float* w, float* h) +{ + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(paint)->size(w, h); +} + + +/************************************************************************/ +/* Gradient API */ +/************************************************************************/ + +TVG_API Tvg_Gradient* tvg_linear_gradient_new() +{ + return (Tvg_Gradient*)LinearGradient::gen().release(); +} + + +TVG_API Tvg_Gradient* tvg_radial_gradient_new() +{ + return (Tvg_Gradient*)RadialGradient::gen().release(); +} + + +TVG_API Tvg_Gradient* tvg_gradient_duplicate(Tvg_Gradient* grad) +{ + if (!grad) return nullptr; + return (Tvg_Gradient*) reinterpret_cast(grad)->duplicate(); +} + + +TVG_API Tvg_Result tvg_gradient_del(Tvg_Gradient* grad) +{ + if (!grad) return TVG_RESULT_INVALID_ARGUMENT; + delete(reinterpret_cast(grad)); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_linear_gradient_set(Tvg_Gradient* grad, float x1, float y1, float x2, float y2) +{ + if (!grad) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(grad)->linear(x1, y1, x2, y2); +} + + +TVG_API Tvg_Result tvg_linear_gradient_get(Tvg_Gradient* grad, float* x1, float* y1, float* x2, float* y2) +{ + if (!grad) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(grad)->linear(x1, y1, x2, y2); +} + + +TVG_API Tvg_Result tvg_radial_gradient_set(Tvg_Gradient* grad, float cx, float cy, float radius) +{ + if (!grad) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(grad)->radial(cx, cy, radius); +} + + +TVG_API Tvg_Result tvg_radial_gradient_get(Tvg_Gradient* grad, float* cx, float* cy, float* radius) +{ + if (!grad) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(grad)->radial(cx, cy, radius); +} + + +TVG_API Tvg_Result tvg_gradient_set_color_stops(Tvg_Gradient* grad, const Tvg_Color_Stop* color_stop, uint32_t cnt) +{ + if (!grad) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(grad)->colorStops(reinterpret_cast(color_stop), cnt); +} + + +TVG_API Tvg_Result tvg_gradient_get_color_stops(const Tvg_Gradient* grad, const Tvg_Color_Stop** color_stop, uint32_t* cnt) +{ + if (!grad || !color_stop || !cnt) return TVG_RESULT_INVALID_ARGUMENT; + *cnt = reinterpret_cast(grad)->colorStops(reinterpret_cast(color_stop)); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_gradient_set_spread(Tvg_Gradient* grad, const Tvg_Stroke_Fill spread) +{ + if (!grad) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(grad)->spread((FillSpread)spread); +} + + +TVG_API Tvg_Result tvg_gradient_get_spread(const Tvg_Gradient* grad, Tvg_Stroke_Fill* spread) +{ + if (!grad || !spread) return TVG_RESULT_INVALID_ARGUMENT; + *spread = (Tvg_Stroke_Fill) reinterpret_cast(grad)->spread(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_gradient_set_transform(Tvg_Gradient* grad, const Tvg_Matrix* m) +{ + if (!grad || !m) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(grad)->transform(*(reinterpret_cast(m))); +} + + +TVG_API Tvg_Result tvg_gradient_get_transform(const Tvg_Gradient* grad, Tvg_Matrix* m) +{ + if (!grad || !m) return TVG_RESULT_INVALID_ARGUMENT; + *reinterpret_cast(m) = reinterpret_cast(const_cast(grad))->transform(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_gradient_get_identifier(const Tvg_Gradient* grad, Tvg_Identifier* identifier) +{ + if (!grad || !identifier) return TVG_RESULT_INVALID_ARGUMENT; + *identifier = static_cast(reinterpret_cast(grad)->identifier()); + return TVG_RESULT_SUCCESS; +} + +/************************************************************************/ +/* Scene API */ +/************************************************************************/ + +TVG_API Tvg_Paint* tvg_scene_new() +{ + return (Tvg_Paint*) Scene::gen().release(); +} + + +TVG_API Tvg_Result tvg_scene_reserve(Tvg_Paint* scene, uint32_t size) +{ + return TVG_RESULT_NOT_SUPPORTED; +} + + +TVG_API Tvg_Result tvg_scene_push(Tvg_Paint* scene, Tvg_Paint* paint) +{ + if (!scene || !paint) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(scene)->push(unique_ptr((Paint*)paint)); +} + + +TVG_API Tvg_Result tvg_scene_clear(Tvg_Paint* scene, bool free) +{ + if (!scene) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(scene)->clear(free); +} + + +/************************************************************************/ +/* Saver API */ +/************************************************************************/ + +TVG_API Tvg_Saver* tvg_saver_new() +{ + return (Tvg_Saver*) Saver::gen().release(); +} + + +TVG_API Tvg_Result tvg_saver_save(Tvg_Saver* saver, Tvg_Paint* paint, const char* path, bool compress) +{ + if (!saver || !paint || !path) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(saver)->save(unique_ptr((Paint*)paint), path, compress); +} + + +TVG_API Tvg_Result tvg_saver_sync(Tvg_Saver* saver) +{ + if (!saver) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(saver)->sync(); +} + + +TVG_API Tvg_Result tvg_saver_del(Tvg_Saver* saver) +{ + if (!saver) return TVG_RESULT_INVALID_ARGUMENT; + delete(reinterpret_cast(saver)); + return TVG_RESULT_SUCCESS; +} + + +/************************************************************************/ +/* Animation API */ +/************************************************************************/ + +TVG_API Tvg_Animation* tvg_animation_new() +{ + return (Tvg_Animation*) Animation::gen().release(); +} + + +TVG_API Tvg_Result tvg_animation_set_frame(Tvg_Animation* animation, float no) +{ + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(animation)->frame(no); +} + + +TVG_API Tvg_Result tvg_animation_get_frame(Tvg_Animation* animation, float* no) +{ + if (!animation || !no) return TVG_RESULT_INVALID_ARGUMENT; + *no = reinterpret_cast(animation)->curFrame(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_animation_get_total_frame(Tvg_Animation* animation, float* cnt) +{ + if (!animation || !cnt) return TVG_RESULT_INVALID_ARGUMENT; + *cnt = reinterpret_cast(animation)->totalFrame(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Paint* tvg_animation_get_picture(Tvg_Animation* animation) +{ + if (!animation) return nullptr; + return (Tvg_Paint*) reinterpret_cast(animation)->picture(); +} + + +TVG_API Tvg_Result tvg_animation_get_duration(Tvg_Animation* animation, float* duration) +{ + if (!animation || !duration) return TVG_RESULT_INVALID_ARGUMENT; + *duration = reinterpret_cast(animation)->duration(); + return TVG_RESULT_SUCCESS; +} + + +TVG_API Tvg_Result tvg_animation_set_segment(Tvg_Animation* animation, float start, float end) +{ + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(animation)->segment(start, end); +} + + +TVG_API Tvg_Result tvg_animation_get_segment(Tvg_Animation* animation, float* start, float* end) +{ + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(animation)->segment(start, end); +} + + +TVG_API Tvg_Result tvg_animation_del(Tvg_Animation* animation) +{ + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + delete(reinterpret_cast(animation)); + return TVG_RESULT_SUCCESS; +} + + +/************************************************************************/ +/* Lottie Animation API */ +/************************************************************************/ + +TVG_API Tvg_Animation* tvg_lottie_animation_new() +{ +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + return (Tvg_Animation*) LottieAnimation::gen().release(); +#endif + return nullptr; +} + + +TVG_API Tvg_Result tvg_lottie_animation_override(Tvg_Animation* animation, const char* slot) +{ +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(animation)->override(slot); +#endif + return TVG_RESULT_NOT_SUPPORTED; +} + + +TVG_API Tvg_Result tvg_lottie_animation_set_marker(Tvg_Animation* animation, const char* marker) +{ +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(animation)->segment(marker); +#endif + return TVG_RESULT_NOT_SUPPORTED; +} + + +TVG_API Tvg_Result tvg_lottie_animation_get_markers_cnt(Tvg_Animation* animation, uint32_t* cnt) +{ +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + if (!animation || !cnt) return TVG_RESULT_INVALID_ARGUMENT; + *cnt = reinterpret_cast(animation)->markersCnt(); + return TVG_RESULT_SUCCESS; +#endif + return TVG_RESULT_NOT_SUPPORTED; +} + + +TVG_API Tvg_Result tvg_lottie_animation_get_marker(Tvg_Animation* animation, uint32_t idx, const char** name) +{ +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + if (!animation || !name) return TVG_RESULT_INVALID_ARGUMENT; + *name = reinterpret_cast(animation)->marker(idx); + if (!(*name)) return TVG_RESULT_INVALID_ARGUMENT; + return TVG_RESULT_SUCCESS; +#endif + return TVG_RESULT_NOT_SUPPORTED; +} + +#ifdef __cplusplus +} +#endif + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgCommon.h b/test/include/liblvgl/libs/thorvg/tvgCommon.h new file mode 100644 index 00000000..d22c893f --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgCommon.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_COMMON_H_ +#define _TVG_COMMON_H_ + +#include "config.h" +#include "thorvg.h" + +using namespace std; +using namespace tvg; + +//for MSVC Compat +#ifdef _MSC_VER + #define TVG_UNUSED + #define strncasecmp _strnicmp + #define strcasecmp _stricmp +#else + #define TVG_UNUSED __attribute__ ((__unused__)) +#endif + +// Portable 'fallthrough' attribute +#if __has_cpp_attribute(fallthrough) + #ifdef _MSC_VER + #define TVG_FALLTHROUGH [[fallthrough]]; + #else + #define TVG_FALLTHROUGH __attribute__ ((fallthrough)); + #endif +#else + #define TVG_FALLTHROUGH +#endif + +#if defined(_MSC_VER) && defined(__clang__) + #define strncpy strncpy_s + #define strdup _strdup +#endif + +//TVG class identifier values +#define TVG_CLASS_ID_UNDEFINED 0 +#define TVG_CLASS_ID_SHAPE 1 +#define TVG_CLASS_ID_SCENE 2 +#define TVG_CLASS_ID_PICTURE 3 +#define TVG_CLASS_ID_LINEAR 4 +#define TVG_CLASS_ID_RADIAL 5 +#define TVG_CLASS_ID_TEXT 6 + +enum class FileType { Png = 0, Jpg, Webp, Tvg, Svg, Lottie, Ttf, Raw, Gif, Unknown }; + +using Size = Point; + +#ifdef THORVG_LOG_ENABLED + constexpr auto ErrorColor = "\033[31m"; //red + constexpr auto ErrorBgColor = "\033[41m";//bg red + constexpr auto LogColor = "\033[32m"; //green + constexpr auto LogBgColor = "\033[42m"; //bg green + constexpr auto GreyColor = "\033[90m"; //grey + constexpr auto ResetColors = "\033[0m"; //default + #define TVGERR(tag, fmt, ...) fprintf(stderr, "%s[E]%s %s" tag "%s (%s %d): %s" fmt "\n", ErrorBgColor, ResetColors, ErrorColor, GreyColor, __FILE__, __LINE__, ResetColors, ##__VA_ARGS__) + #define TVGLOG(tag, fmt, ...) fprintf(stdout, "%s[L]%s %s" tag "%s (%s %d): %s" fmt "\n", LogBgColor, ResetColors, LogColor, GreyColor, __FILE__, __LINE__, ResetColors, ##__VA_ARGS__) +#else + #define TVGERR(...) do {} while(0) + #define TVGLOG(...) do {} while(0) +#endif + +uint16_t THORVG_VERSION_NUMBER(); + + +#define P(A) ((A)->pImpl) //Access to pimpl. +#define PP(A) (((Paint*)(A))->pImpl) //Access to pimpl. + +#endif //_TVG_COMMON_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgCompressor.cpp b/test/include/liblvgl/libs/thorvg/tvgCompressor.cpp new file mode 100644 index 00000000..d0c7c4ec --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgCompressor.cpp @@ -0,0 +1,481 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +/* + * Lempel–Ziv–Welch (LZW) encoder/decoder by Guilherme R. Lampert(guilherme.ronaldo.lampert@gmail.com) + + * This is the compression scheme used by the GIF image format and the Unix 'compress' tool. + * Main differences from this implementation is that End Of Input (EOI) and Clear Codes (CC) + * are not stored in the output and the max code length in bits is 12, vs 16 in compress. + * + * EOI is simply detected by the end of the data stream, while CC happens if the + * dictionary gets filled. Data is written/read from bit streams, which handle + * byte-alignment for us in a transparent way. + + * The decoder relies on the hardcoded data layout produced by the encoder, since + * no additional reconstruction data is added to the output, so they must match. + * The nice thing about LZW is that we can reconstruct the dictionary directly from + * the stream of codes generated by the encoder, so this avoids storing additional + * headers in the bit stream. + + * The output code length is variable. It starts with the minimum number of bits + * required to store the base byte-sized dictionary and automatically increases + * as the dictionary gets larger (it starts at 9-bits and grows to 10-bits when + * code 512 is added, then 11-bits when 1024 is added, and so on). If the dictionary + * is filled (4096 items for a 12-bits dictionary), the whole thing is cleared and + * the process starts over. This is the main reason why the encoder and the decoder + * must match perfectly, since the lengths of the codes will not be specified with + * the data itself. + + * USEFUL LINKS: + * https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch + * http://rosettacode.org/wiki/LZW_compression + * http://www.cs.duke.edu/csed/curious/compression/lzw.html + * http://www.cs.cf.ac.uk/Dave/Multimedia/node214.html + * http://marknelson.us/1989/10/01/lzw-data-compression/ + */ +#include "config.h" + + + +#include +#include +#include "tvgCompressor.h" + +namespace tvg { + + +/************************************************************************/ +/* LZW Implementation */ +/************************************************************************/ + + +//LZW Dictionary helper: +constexpr int Nil = -1; +constexpr int MaxDictBits = 12; +constexpr int StartBits = 9; +constexpr int FirstCode = (1 << (StartBits - 1)); // 256 +constexpr int MaxDictEntries = (1 << MaxDictBits); // 4096 + + +//Round up to the next power-of-two number, e.g. 37 => 64 +static int nextPowerOfTwo(int num) +{ + --num; + for (size_t i = 1; i < sizeof(num) * 8; i <<= 1) { + num = num | num >> i; + } + return ++num; +} + + +struct BitStreamWriter +{ + uint8_t* stream; //Growable buffer to store our bits. Heap allocated & owned by the class instance. + int bytesAllocated; //Current size of heap-allocated stream buffer *in bytes*. + int granularity; //Amount bytesAllocated multiplies by when auto-resizing in appendBit(). + int currBytePos; //Current byte being written to, from 0 to bytesAllocated-1. + int nextBitPos; //Bit position within the current byte to access next. 0 to 7. + int numBitsWritten; //Number of bits in use from the stream buffer, not including byte-rounding padding. + + void internalInit() + { + stream = nullptr; + bytesAllocated = 0; + granularity = 2; + currBytePos = 0; + nextBitPos = 0; + numBitsWritten = 0; + } + + uint8_t* allocBytes(const int bytesWanted, uint8_t * oldPtr, const int oldSize) + { + auto newMemory = static_cast(malloc(bytesWanted)); + memset(newMemory, 0, bytesWanted); + + if (oldPtr) { + memcpy(newMemory, oldPtr, oldSize); + free(oldPtr); + } + return newMemory; + } + + BitStreamWriter() + { + /* 8192 bits for a start (1024 bytes). It will resize if needed. + Default granularity is 2. */ + internalInit(); + allocate(8192); + } + + BitStreamWriter(const int initialSizeInBits, const int growthGranularity = 2) + { + internalInit(); + setGranularity(growthGranularity); + allocate(initialSizeInBits); + } + + ~BitStreamWriter() + { + free(stream); + } + + void allocate(int bitsWanted) + { + //Require at least a byte. + if (bitsWanted <= 0) bitsWanted = 8; + + //Round upwards if needed: + if ((bitsWanted % 8) != 0) bitsWanted = nextPowerOfTwo(bitsWanted); + + //We might already have the required count. + const int sizeInBytes = bitsWanted / 8; + if (sizeInBytes <= bytesAllocated) return; + + stream = allocBytes(sizeInBytes, stream, bytesAllocated); + bytesAllocated = sizeInBytes; + } + + void appendBit(const int bit) + { + const uint32_t mask = uint32_t(1) << nextBitPos; + stream[currBytePos] = (stream[currBytePos] & ~mask) | (-bit & mask); + ++numBitsWritten; + + if (++nextBitPos == 8) { + nextBitPos = 0; + if (++currBytePos == bytesAllocated) allocate(bytesAllocated * granularity * 8); + } + } + + void appendBitsU64(const uint64_t num, const int bitCount) + { + for (int b = 0; b < bitCount; ++b) { + const uint64_t mask = uint64_t(1) << b; + const int bit = !!(num & mask); + appendBit(bit); + } + } + + uint8_t* release() + { + auto oldPtr = stream; + internalInit(); + return oldPtr; + } + + void setGranularity(const int growthGranularity) + { + granularity = (growthGranularity >= 2) ? growthGranularity : 2; + } + + int getByteCount() const + { + int usedBytes = numBitsWritten / 8; + int leftovers = numBitsWritten % 8; + if (leftovers != 0) ++usedBytes; + return usedBytes; + } +}; + + +struct BitStreamReader +{ + const uint8_t* stream; // Pointer to the external bit stream. Not owned by the reader. + const int sizeInBytes; // Size of the stream *in bytes*. Might include padding. + const int sizeInBits; // Size of the stream *in bits*, padding *not* include. + int currBytePos = 0; // Current byte being read in the stream. + int nextBitPos = 0; // Bit position within the current byte to access next. 0 to 7. + int numBitsRead = 0; // Total bits read from the stream so far. Never includes byte-rounding padding. + + BitStreamReader(const uint8_t* bitStream, const int byteCount, const int bitCount) : stream(bitStream), sizeInBytes(byteCount), sizeInBits(bitCount) + { + } + + bool readNextBit(int& bitOut) + { + if (numBitsRead >= sizeInBits) return false; //We are done. + + const uint32_t mask = uint32_t(1) << nextBitPos; + bitOut = !!(stream[currBytePos] & mask); + ++numBitsRead; + + if (++nextBitPos == 8) { + nextBitPos = 0; + ++currBytePos; + } + return true; + } + + uint64_t readBitsU64(const int bitCount) + { + uint64_t num = 0; + for (int b = 0; b < bitCount; ++b) { + int bit; + if (!readNextBit(bit)) break; + /* Based on a "Stanford bit-hack": + http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching */ + const uint64_t mask = uint64_t(1) << b; + num = (num & ~mask) | (-bit & mask); + } + return num; + } + + bool isEndOfStream() const + { + return numBitsRead >= sizeInBits; + } +}; + + +struct Dictionary +{ + struct Entry + { + int code; + int value; + }; + + //Dictionary entries 0-255 are always reserved to the byte/ASCII range. + int size; + Entry entries[MaxDictEntries]; + + Dictionary() + { + /* First 256 dictionary entries are reserved to the byte/ASCII range. + Additional entries follow for the character sequences found in the input. + Up to 4096 - 256 (MaxDictEntries - FirstCode). */ + size = FirstCode; + + for (int i = 0; i < size; ++i) { + entries[i].code = Nil; + entries[i].value = i; + } + } + + int findIndex(const int code, const int value) const + { + if (code == Nil) return value; + + //Linear search for now. + //TODO: Worth optimizing with a proper hash-table? + for (int i = 0; i < size; ++i) { + if (entries[i].code == code && entries[i].value == value) return i; + } + return Nil; + } + + bool add(const int code, const int value) + { + if (size == MaxDictEntries) return false; + entries[size].code = code; + entries[size].value = value; + ++size; + return true; + } + + bool flush(int & codeBitsWidth) + { + if (size == (1 << codeBitsWidth)) { + ++codeBitsWidth; + if (codeBitsWidth > MaxDictBits) { + //Clear the dictionary (except the first 256 byte entries). + codeBitsWidth = StartBits; + size = FirstCode; + return true; + } + } + return false; + } +}; + + +static bool outputByte(int code, uint8_t*& output, int outputSizeBytes, int& bytesDecodedSoFar) +{ + if (bytesDecodedSoFar >= outputSizeBytes) return false; + *output++ = static_cast(code); + ++bytesDecodedSoFar; + return true; +} + + +static bool outputSequence(const Dictionary& dict, int code, uint8_t*& output, int outputSizeBytes, int& bytesDecodedSoFar, int& firstByte) +{ + /* A sequence is stored backwards, so we have to write + it to a temp then output the buffer in reverse. */ + int i = 0; + uint8_t sequence[MaxDictEntries]; + + do { + sequence[i++] = dict.entries[code].value; + code = dict.entries[code].code; + } while (code >= 0); + + firstByte = sequence[--i]; + + for (; i >= 0; --i) { + if (!outputByte(sequence[i], output, outputSizeBytes, bytesDecodedSoFar)) return false; + } + return true; +} + + +uint8_t* lzwDecode(const uint8_t* compressed, uint32_t compressedSizeBytes, uint32_t compressedSizeBits, uint32_t uncompressedSizeBytes) +{ + int code = Nil; + int prevCode = Nil; + int firstByte = 0; + int bytesDecoded = 0; + int codeBitsWidth = StartBits; + auto uncompressed = (uint8_t*) malloc(sizeof(uint8_t) * uncompressedSizeBytes); + auto ptr = uncompressed; + + /* We'll reconstruct the dictionary based on the bit stream codes. + Unlike Huffman encoding, we don't store the dictionary as a prefix to the data. */ + Dictionary dictionary; + BitStreamReader bitStream(compressed, compressedSizeBytes, compressedSizeBits); + + /* We check to avoid an overflow of the user buffer. + If the buffer is smaller than the decompressed size, we break the loop and return the current decompression count. */ + while (!bitStream.isEndOfStream()) { + code = static_cast(bitStream.readBitsU64(codeBitsWidth)); + + if (prevCode == Nil) { + if (!outputByte(code, ptr, uncompressedSizeBytes, bytesDecoded)) break; + firstByte = code; + prevCode = code; + continue; + } + if (code >= dictionary.size) { + if (!outputSequence(dictionary, prevCode, ptr, uncompressedSizeBytes, bytesDecoded, firstByte)) break; + if (!outputByte(firstByte, ptr, uncompressedSizeBytes, bytesDecoded)) break; + } else if (!outputSequence(dictionary, code, ptr, uncompressedSizeBytes, bytesDecoded, firstByte)) break; + + dictionary.add(prevCode, firstByte); + if (dictionary.flush(codeBitsWidth)) prevCode = Nil; + else prevCode = code; + } + + return uncompressed; +} + + +uint8_t* lzwEncode(const uint8_t* uncompressed, uint32_t uncompressedSizeBytes, uint32_t* compressedSizeBytes, uint32_t* compressedSizeBits) +{ + //LZW encoding context: + int code = Nil; + int codeBitsWidth = StartBits; + Dictionary dictionary; + + //Output bit stream we write to. This will allocate memory as needed to accommodate the encoded data. + BitStreamWriter bitStream; + + for (; uncompressedSizeBytes > 0; --uncompressedSizeBytes, ++uncompressed) { + const int value = *uncompressed; + const int index = dictionary.findIndex(code, value); + + if (index != Nil) { + code = index; + continue; + } + + //Write the dictionary code using the minimum bit-with: + bitStream.appendBitsU64(code, codeBitsWidth); + + //Flush it when full so we can restart the sequences. + if (!dictionary.flush(codeBitsWidth)) { + //There's still space for this sequence. + dictionary.add(code, value); + } + code = value; + } + + //Residual code at the end: + if (code != Nil) bitStream.appendBitsU64(code, codeBitsWidth); + + //Pass ownership of the compressed data buffer to the user pointer: + *compressedSizeBytes = bitStream.getByteCount(); + *compressedSizeBits = bitStream.numBitsWritten; + + return bitStream.release(); +} + + +/************************************************************************/ +/* B64 Implementation */ +/************************************************************************/ + + +size_t b64Decode(const char* encoded, const size_t len, char** decoded) +{ + static constexpr const char B64_INDEX[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 + }; + + + if (!decoded || !encoded || len == 0) return 0; + + auto reserved = 3 * (1 + (len >> 2)) + 1; + auto output = static_cast(malloc(reserved * sizeof(char))); + if (!output) return 0; + output[reserved - 1] = '\0'; + + size_t idx = 0; + + while (*encoded && *(encoded + 1)) { + if (*encoded <= 0x20) { + ++encoded; + continue; + } + + auto value1 = B64_INDEX[(size_t)encoded[0]]; + auto value2 = B64_INDEX[(size_t)encoded[1]]; + output[idx++] = (value1 << 2) + ((value2 & 0x30) >> 4); + + if (!encoded[2] || encoded[3] < 0 || encoded[2] == '=' || encoded[2] == '.') break; + auto value3 = B64_INDEX[(size_t)encoded[2]]; + output[idx++] = ((value2 & 0x0f) << 4) + ((value3 & 0x3c) >> 2); + + if (!encoded[3] || encoded[3] < 0 || encoded[3] == '=' || encoded[3] == '.') break; + auto value4 = B64_INDEX[(size_t)encoded[3]]; + output[idx++] = ((value3 & 0x03) << 6) + value4; + encoded += 4; + } + *decoded = output; + return reserved; +} + + +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgCompressor.h b/test/include/liblvgl/libs/thorvg/tvgCompressor.h new file mode 100644 index 00000000..11e5fb39 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgCompressor.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_COMPRESSOR_H_ +#define _TVG_COMPRESSOR_H_ + +#include + +namespace tvg +{ + uint8_t* lzwEncode(const uint8_t* uncompressed, uint32_t uncompressedSizeBytes, uint32_t* compressedSizeBytes, uint32_t* compressedSizeBits); + uint8_t* lzwDecode(const uint8_t* compressed, uint32_t compressedSizeBytes, uint32_t compressedSizeBits, uint32_t uncompressedSizeBytes); + size_t b64Decode(const char* encoded, const size_t len, char** decoded); +} + +#endif //_TVG_COMPRESSOR_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgFill.cpp b/test/include/liblvgl/libs/thorvg/tvgFill.cpp new file mode 100644 index 00000000..76d678fe --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgFill.cpp @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgFill.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +Fill* RadialGradient::Impl::duplicate() +{ + auto ret = RadialGradient::gen(); + if (!ret) return nullptr; + + ret->pImpl->cx = cx; + ret->pImpl->cy = cy; + ret->pImpl->r = r; + ret->pImpl->fx = fx; + ret->pImpl->fy = fy; + ret->pImpl->fr = fr; + + return ret.release(); +} + + +Result RadialGradient::Impl::radial(float cx, float cy, float r, float fx, float fy, float fr) +{ + if (r < 0 || fr < 0) return Result::InvalidArguments; + + this->cx = cx; + this->cy = cy; + this->r = r; + this->fx = fx; + this->fy = fy; + this->fr = fr; + + return Result::Success; +}; + + +Fill* LinearGradient::Impl::duplicate() +{ + auto ret = LinearGradient::gen(); + if (!ret) return nullptr; + + ret->pImpl->x1 = x1; + ret->pImpl->y1 = y1; + ret->pImpl->x2 = x2; + ret->pImpl->y2 = y2; + + return ret.release(); +}; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Fill::Fill():pImpl(new Impl()) +{ +} + + +Fill::~Fill() +{ + delete(pImpl); +} + + +Result Fill::colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept +{ + if ((!colorStops && cnt > 0) || (colorStops && cnt == 0)) return Result::InvalidArguments; + + if (cnt == 0) { + if (pImpl->colorStops) { + free(pImpl->colorStops); + pImpl->colorStops = nullptr; + pImpl->cnt = 0; + } + return Result::Success; + } + + if (pImpl->cnt != cnt) { + pImpl->colorStops = static_cast(realloc(pImpl->colorStops, cnt * sizeof(ColorStop))); + } + + pImpl->cnt = cnt; + memcpy(pImpl->colorStops, colorStops, cnt * sizeof(ColorStop)); + + return Result::Success; +} + + +uint32_t Fill::colorStops(const ColorStop** colorStops) const noexcept +{ + if (colorStops) *colorStops = pImpl->colorStops; + + return pImpl->cnt; +} + + +Result Fill::spread(FillSpread s) noexcept +{ + pImpl->spread = s; + + return Result::Success; +} + + +FillSpread Fill::spread() const noexcept +{ + return pImpl->spread; +} + + +Result Fill::transform(const Matrix& m) noexcept +{ + if (!pImpl->transform) { + pImpl->transform = static_cast(malloc(sizeof(Matrix))); + } + *pImpl->transform = m; + return Result::Success; +} + + +Matrix Fill::transform() const noexcept +{ + if (pImpl->transform) return *pImpl->transform; + return {1, 0, 0, 0, 1, 0, 0, 0, 1}; +} + + +Fill* Fill::duplicate() const noexcept +{ + return pImpl->duplicate(); +} + + +uint32_t Fill::identifier() const noexcept +{ + return pImpl->id; +} + + +RadialGradient::RadialGradient():pImpl(new Impl()) +{ + Fill::pImpl->id = TVG_CLASS_ID_RADIAL; + Fill::pImpl->method(new FillDup(pImpl)); +} + + +RadialGradient::~RadialGradient() +{ + delete(pImpl); +} + + +Result RadialGradient::radial(float cx, float cy, float r) noexcept +{ + return pImpl->radial(cx, cy, r, cx, cy, 0.0f); +} + + +Result RadialGradient::radial(float* cx, float* cy, float* r) const noexcept +{ + if (cx) *cx = pImpl->cx; + if (cy) *cy = pImpl->cy; + if (r) *r = pImpl->r; + + return Result::Success; +} + + +unique_ptr RadialGradient::gen() noexcept +{ + return unique_ptr(new RadialGradient); +} + + +uint32_t RadialGradient::identifier() noexcept +{ + return TVG_CLASS_ID_RADIAL; +} + + +LinearGradient::LinearGradient():pImpl(new Impl()) +{ + Fill::pImpl->id = TVG_CLASS_ID_LINEAR; + Fill::pImpl->method(new FillDup(pImpl)); +} + + +LinearGradient::~LinearGradient() +{ + delete(pImpl); +} + + +Result LinearGradient::linear(float x1, float y1, float x2, float y2) noexcept +{ + pImpl->x1 = x1; + pImpl->y1 = y1; + pImpl->x2 = x2; + pImpl->y2 = y2; + + return Result::Success; +} + + +Result LinearGradient::linear(float* x1, float* y1, float* x2, float* y2) const noexcept +{ + if (x1) *x1 = pImpl->x1; + if (x2) *x2 = pImpl->x2; + if (y1) *y1 = pImpl->y1; + if (y2) *y2 = pImpl->y2; + + return Result::Success; +} + + +unique_ptr LinearGradient::gen() noexcept +{ + return unique_ptr(new LinearGradient); +} + + +uint32_t LinearGradient::identifier() noexcept +{ + return TVG_CLASS_ID_LINEAR; +} + + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgFill.h b/test/include/liblvgl/libs/thorvg/tvgFill.h new file mode 100644 index 00000000..e6d776f9 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgFill.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_FILL_H_ +#define _TVG_FILL_H_ + +#include +#include +#include "tvgCommon.h" + +template +struct DuplicateMethod +{ + virtual ~DuplicateMethod() {} + virtual T* duplicate() = 0; +}; + +template +struct FillDup : DuplicateMethod +{ + T* inst = nullptr; + + FillDup(T* _inst) : inst(_inst) {} + ~FillDup() {} + + Fill* duplicate() override + { + return inst->duplicate(); + } +}; + +struct Fill::Impl +{ + ColorStop* colorStops = nullptr; + Matrix* transform = nullptr; + uint32_t cnt = 0; + FillSpread spread; + DuplicateMethod* dup = nullptr; + uint8_t id; + + ~Impl() + { + delete(dup); + free(colorStops); + free(transform); + } + + void method(DuplicateMethod* dup) + { + this->dup = dup; + } + + Fill* duplicate() + { + auto ret = dup->duplicate(); + if (!ret) return nullptr; + + ret->pImpl->cnt = cnt; + ret->pImpl->spread = spread; + ret->pImpl->colorStops = static_cast(malloc(sizeof(ColorStop) * cnt)); + memcpy(ret->pImpl->colorStops, colorStops, sizeof(ColorStop) * cnt); + if (transform) { + ret->pImpl->transform = static_cast(malloc(sizeof(Matrix))); + *ret->pImpl->transform = *transform; + } + return ret; + } +}; + + +struct RadialGradient::Impl +{ + float cx = 0.0f, cy = 0.0f; + float fx = 0.0f, fy = 0.0f; + float r = 0.0f, fr = 0.0f; + + Fill* duplicate(); + Result radial(float cx, float cy, float r, float fx, float fy, float fr); +}; + + +struct LinearGradient::Impl +{ + float x1 = 0.0f; + float y1 = 0.0f; + float x2 = 0.0f; + float y2 = 0.0f; + + Fill* duplicate(); +}; + + +#endif //_TVG_FILL_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgFrameModule.h b/test/include/liblvgl/libs/thorvg/tvgFrameModule.h new file mode 100644 index 00000000..02e69a87 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgFrameModule.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_FRAME_MODULE_H_ +#define _TVG_FRAME_MODULE_H_ + +#include "tvgLoadModule.h" + +namespace tvg +{ + +class FrameModule: public ImageLoader +{ +public: + float segmentBegin = 0.0f; + float segmentEnd = 1.0f; + + FrameModule(FileType type) : ImageLoader(type) {} + virtual ~FrameModule() {} + + virtual bool frame(float no) = 0; //set the current frame number + virtual float totalFrame() = 0; //return the total frame count + virtual float curFrame() = 0; //return the current frame number + virtual float duration() = 0; //return the animation duration in seconds + + void segment(float* begin, float* end) + { + if (begin) *begin = segmentBegin; + if (end) *end = segmentEnd; + } + + void segment(float begin, float end) + { + segmentBegin = begin; + segmentEnd = end; + } + + virtual bool animatable() override { return true; } +}; + +} + +#endif //_TVG_FRAME_MODULE_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgGlCanvas.cpp b/test/include/liblvgl/libs/thorvg/tvgGlCanvas.cpp new file mode 100644 index 00000000..d246ea55 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgGlCanvas.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgCanvas.h" + +#ifdef THORVG_GL_RASTER_SUPPORT + #include "tvgGlRenderer.h" +#else + class GlRenderer : public RenderMethod + { + //Non Supported. Dummy Class */ + }; +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct GlCanvas::Impl +{ +}; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +#ifdef THORVG_GL_RASTER_SUPPORT +GlCanvas::GlCanvas() : Canvas(GlRenderer::gen()), pImpl(new Impl) +#else +GlCanvas::GlCanvas() : Canvas(nullptr), pImpl(new Impl) +#endif +{ +} + + + +GlCanvas::~GlCanvas() +{ + delete(pImpl); +} + + +Result GlCanvas::target(int32_t id, uint32_t w, uint32_t h) noexcept +{ +#ifdef THORVG_GL_RASTER_SUPPORT + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast(Canvas::pImpl->renderer); + if (!renderer) return Result::MemoryCorruption; + + if (!renderer->target(id, w, h)) return Result::Unknown; + Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; + renderer->viewport(Canvas::pImpl->vport); + + //Paints must be updated again with this new target. + Canvas::pImpl->needRefresh(); + + return Result::Success; +#endif + return Result::NonSupport; +} + + +unique_ptr GlCanvas::gen() noexcept +{ +#ifdef THORVG_GL_RASTER_SUPPORT + if (GlRenderer::init() <= 0) return nullptr; + return unique_ptr(new GlCanvas); +#endif + return nullptr; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgInitializer.cpp b/test/include/liblvgl/libs/thorvg/tvgInitializer.cpp new file mode 100644 index 00000000..2506fd2b --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgInitializer.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgCommon.h" +#include "tvgTaskScheduler.h" +#include "tvgLoader.h" + +#ifdef _WIN32 + #include +#endif + +#ifdef THORVG_SW_RASTER_SUPPORT + #include "tvgSwRenderer.h" +#endif + +#ifdef THORVG_GL_RASTER_SUPPORT + #include "tvgGlRenderer.h" +#endif + +#ifdef THORVG_WG_RASTER_SUPPORT + #include "tvgWgRenderer.h" +#endif + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static int _initCnt = 0; +static uint16_t _version = 0; + +//enum class operation helper +static constexpr bool operator &(CanvasEngine a, CanvasEngine b) +{ + return int(a) & int(b); +} + +static bool _buildVersionInfo() +{ + auto SRC = THORVG_VERSION_STRING; //ex) 0.3.99 + auto p = SRC; + const char* x; + + char major[3]; + x = strchr(p, '.'); + if (!x) return false; + memcpy(major, p, x - p); + major[x - p] = '\0'; + p = x + 1; + + char minor[3]; + x = strchr(p, '.'); + if (!x) return false; + memcpy(minor, p, x - p); + minor[x - p] = '\0'; + p = x + 1; + + char micro[3]; + x = SRC + strlen(THORVG_VERSION_STRING); + memcpy(micro, p, x - p); + micro[x - p] = '\0'; + + char sum[7]; + snprintf(sum, sizeof(sum), "%s%s%s", major, minor, micro); + + _version = atoi(sum); + + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Result Initializer::init(CanvasEngine engine, uint32_t threads) noexcept +{ + auto nonSupport = true; + if (static_cast(engine) == 0) return Result::InvalidArguments; + + if (engine & CanvasEngine::Sw) { + #ifdef THORVG_SW_RASTER_SUPPORT + if (!SwRenderer::init(threads)) return Result::FailedAllocation; + nonSupport = false; + #endif + } + + if (engine & CanvasEngine::Gl) { + #ifdef THORVG_GL_RASTER_SUPPORT + if (!GlRenderer::init(threads)) return Result::FailedAllocation; + nonSupport = false; + #endif + } + + if (engine & CanvasEngine::Wg) { + #ifdef THORVG_WG_RASTER_SUPPORT + if (!WgRenderer::init(threads)) return Result::FailedAllocation; + nonSupport = false; + #endif + } + + if (nonSupport) return Result::NonSupport; + + if (_initCnt++ > 0) return Result::Success; + + if (!_buildVersionInfo()) return Result::Unknown; + + if (!LoaderMgr::init()) return Result::Unknown; + + TaskScheduler::init(threads); + + return Result::Success; +} + + +Result Initializer::term(CanvasEngine engine) noexcept +{ + if (_initCnt == 0) return Result::InsufficientCondition; + + auto nonSupport = true; + if (static_cast(engine) == 0) return Result::InvalidArguments; + + if (engine & CanvasEngine::Sw) { + #ifdef THORVG_SW_RASTER_SUPPORT + if (!SwRenderer::term()) return Result::InsufficientCondition; + nonSupport = false; + #endif + } + + if (engine & CanvasEngine::Gl) { + #ifdef THORVG_GL_RASTER_SUPPORT + if (!GlRenderer::term()) return Result::InsufficientCondition; + nonSupport = false; + #endif + } + + if (engine & CanvasEngine::Wg) { + #ifdef THORVG_WG_RASTER_SUPPORT + if (!WgRenderer::term()) return Result::InsufficientCondition; + nonSupport = false; + #endif + } + + if (nonSupport) return Result::NonSupport; + + if (--_initCnt > 0) return Result::Success; + + TaskScheduler::term(); + + if (!LoaderMgr::term()) return Result::Unknown; + + return Result::Success; +} + + +uint16_t THORVG_VERSION_NUMBER() +{ + return _version; +} + + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgInlist.h b/test/include/liblvgl/libs/thorvg/tvgInlist.h new file mode 100644 index 00000000..eaedecce --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgInlist.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_INLIST_H_ +#define _TVG_INLIST_H_ + +namespace tvg { + +//NOTE: declare this in your list item +#define INLIST_ITEM(T) \ + T* prev; \ + T* next + +template +struct Inlist +{ + T* head = nullptr; + T* tail = nullptr; + + void free() + { + while (head) { + auto t = head; + head = t->next; + delete(t); + } + head = tail = nullptr; + } + + void back(T* element) + { + if (tail) { + tail->next = element; + element->prev = tail; + element->next = nullptr; + tail = element; + } else { + head = tail = element; + element->prev = nullptr; + element->next = nullptr; + } + } + + void front(T* element) + { + if (head) { + head->prev = element; + element->prev = nullptr; + element->next = head; + head = element; + } else { + head = tail = element; + element->prev = nullptr; + element->next = nullptr; + } + } + + T* back() + { + if (!tail) return nullptr; + auto t = tail; + tail = t->prev; + if (!tail) head = nullptr; + return t; + } + + T* front() + { + if (!head) return nullptr; + auto t = head; + head = t->next; + if (!head) tail = nullptr; + return t; + } + + void remove(T* element) + { + if (element->prev) element->prev->next = element->next; + if (element->next) element->next->prev = element->prev; + if (element == head) head = element->next; + if (element == tail) tail = element->prev; + } + + bool empty() + { + return head ? false : true; + } +}; + +} + +#endif // _TVG_INLIST_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgIteratorAccessor.h b/test/include/liblvgl/libs/thorvg/tvgIteratorAccessor.h new file mode 100644 index 00000000..adc5f6ea --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgIteratorAccessor.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_ITERATOR_ACCESSOR_H_ +#define _TVG_ITERATOR_ACCESSOR_H_ + +#include "tvgPaint.h" + +namespace tvg +{ + +class IteratorAccessor +{ +public: + //Utility Method: Iterator Accessor + static Iterator* iterator(const Paint* paint) + { + return paint->pImpl->iterator(); + } +}; + +} + +#endif //_TVG_ITERATOR_ACCESSOR_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLines.cpp b/test/include/liblvgl/libs/thorvg/tvgLines.cpp new file mode 100644 index 00000000..3bdab769 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLines.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" +#include "tvgLines.h" + +#define BEZIER_EPSILON 1e-2f + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static float _lineLengthApprox(const Point& pt1, const Point& pt2) +{ + /* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm. + With alpha = 1, beta = 3/8, giving results with the largest error less + than 7% compared to the exact value. */ + Point diff = {pt2.x - pt1.x, pt2.y - pt1.y}; + if (diff.x < 0) diff.x = -diff.x; + if (diff.y < 0) diff.y = -diff.y; + return (diff.x > diff.y) ? (diff.x + diff.y * 0.375f) : (diff.y + diff.x * 0.375f); +} + + +static float _lineLength(const Point& pt1, const Point& pt2) +{ + Point diff = {pt2.x - pt1.x, pt2.y - pt1.y}; + return sqrtf(diff.x * diff.x + diff.y * diff.y); +} + + +template +float _bezLength(const Bezier& cur, LengthFunc lineLengthFunc) +{ + Bezier left, right; + auto len = lineLengthFunc(cur.start, cur.ctrl1) + lineLengthFunc(cur.ctrl1, cur.ctrl2) + lineLengthFunc(cur.ctrl2, cur.end); + auto chord = lineLengthFunc(cur.start, cur.end); + + if (fabsf(len - chord) > BEZIER_EPSILON) { + tvg::bezSplit(cur, left, right); + return _bezLength(left, lineLengthFunc) + _bezLength(right, lineLengthFunc); + } + return len; +} + + +template +float _bezAt(const Bezier& bz, float at, float length, LengthFunc lineLengthFunc) +{ + auto biggest = 1.0f; + auto smallest = 0.0f; + auto t = 0.5f; + + //just in case to prevent an infinite loop + if (at <= 0) return 0.0f; + if (at >= length) return 1.0f; + + while (true) { + auto right = bz; + Bezier left; + bezSplitLeft(right, t, left); + length = _bezLength(left, lineLengthFunc); + if (fabsf(length - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < BEZIER_EPSILON) { + break; + } + if (length < at) { + smallest = t; + t = (t + biggest) * 0.5f; + } else { + biggest = t; + t = (smallest + t) * 0.5f; + } + } + return t; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +namespace tvg +{ + +float lineLength(const Point& pt1, const Point& pt2) +{ + return _lineLength(pt1, pt2); +} + + +void lineSplitAt(const Line& cur, float at, Line& left, Line& right) +{ + auto len = lineLength(cur.pt1, cur.pt2); + auto dx = ((cur.pt2.x - cur.pt1.x) / len) * at; + auto dy = ((cur.pt2.y - cur.pt1.y) / len) * at; + left.pt1 = cur.pt1; + left.pt2.x = left.pt1.x + dx; + left.pt2.y = left.pt1.y + dy; + right.pt1 = left.pt2; + right.pt2 = cur.pt2; +} + + +void bezSplit(const Bezier& cur, Bezier& left, Bezier& right) +{ + auto c = (cur.ctrl1.x + cur.ctrl2.x) * 0.5f; + left.ctrl1.x = (cur.start.x + cur.ctrl1.x) * 0.5f; + right.ctrl2.x = (cur.ctrl2.x + cur.end.x) * 0.5f; + left.start.x = cur.start.x; + right.end.x = cur.end.x; + left.ctrl2.x = (left.ctrl1.x + c) * 0.5f; + right.ctrl1.x = (right.ctrl2.x + c) * 0.5f; + left.end.x = right.start.x = (left.ctrl2.x + right.ctrl1.x) * 0.5f; + + c = (cur.ctrl1.y + cur.ctrl2.y) * 0.5f; + left.ctrl1.y = (cur.start.y + cur.ctrl1.y) * 0.5f; + right.ctrl2.y = (cur.ctrl2.y + cur.end.y) * 0.5f; + left.start.y = cur.start.y; + right.end.y = cur.end.y; + left.ctrl2.y = (left.ctrl1.y + c) * 0.5f; + right.ctrl1.y = (right.ctrl2.y + c) * 0.5f; + left.end.y = right.start.y = (left.ctrl2.y + right.ctrl1.y) * 0.5f; +} + + +float bezLength(const Bezier& cur) +{ + return _bezLength(cur, _lineLength); +} + + +float bezLengthApprox(const Bezier& cur) +{ + return _bezLength(cur, _lineLengthApprox); +} + + +void bezSplitLeft(Bezier& cur, float at, Bezier& left) +{ + left.start = cur.start; + + left.ctrl1.x = cur.start.x + at * (cur.ctrl1.x - cur.start.x); + left.ctrl1.y = cur.start.y + at * (cur.ctrl1.y - cur.start.y); + + left.ctrl2.x = cur.ctrl1.x + at * (cur.ctrl2.x - cur.ctrl1.x); //temporary holding spot + left.ctrl2.y = cur.ctrl1.y + at * (cur.ctrl2.y - cur.ctrl1.y); //temporary holding spot + + cur.ctrl2.x = cur.ctrl2.x + at * (cur.end.x - cur.ctrl2.x); + cur.ctrl2.y = cur.ctrl2.y + at * (cur.end.y - cur.ctrl2.y); + + cur.ctrl1.x = left.ctrl2.x + at * (cur.ctrl2.x - left.ctrl2.x); + cur.ctrl1.y = left.ctrl2.y + at * (cur.ctrl2.y - left.ctrl2.y); + + left.ctrl2.x = left.ctrl1.x + at * (left.ctrl2.x - left.ctrl1.x); + left.ctrl2.y = left.ctrl1.y + at * (left.ctrl2.y - left.ctrl1.y); + + left.end.x = cur.start.x = left.ctrl2.x + at * (cur.ctrl1.x - left.ctrl2.x); + left.end.y = cur.start.y = left.ctrl2.y + at * (cur.ctrl1.y - left.ctrl2.y); +} + + +float bezAt(const Bezier& bz, float at, float length) +{ + return _bezAt(bz, at, length, _lineLength); +} + + +float bezAtApprox(const Bezier& bz, float at, float length) +{ + return _bezAt(bz, at, length, _lineLengthApprox); +} + + +void bezSplitAt(const Bezier& cur, float at, Bezier& left, Bezier& right) +{ + right = cur; + auto t = bezAt(right, at, bezLength(right)); + bezSplitLeft(right, t, left); +} + + +Point bezPointAt(const Bezier& bz, float t) +{ + Point cur; + auto it = 1.0f - t; + + auto ax = bz.start.x * it + bz.ctrl1.x * t; + auto bx = bz.ctrl1.x * it + bz.ctrl2.x * t; + auto cx = bz.ctrl2.x * it + bz.end.x * t; + ax = ax * it + bx * t; + bx = bx * it + cx * t; + cur.x = ax * it + bx * t; + + float ay = bz.start.y * it + bz.ctrl1.y * t; + float by = bz.ctrl1.y * it + bz.ctrl2.y * t; + float cy = bz.ctrl2.y * it + bz.end.y * t; + ay = ay * it + by * t; + by = by * it + cy * t; + cur.y = ay * it + by * t; + + return cur; +} + + +float bezAngleAt(const Bezier& bz, float t) +{ + if (t < 0 || t > 1) return 0; + + //derivate + // p'(t) = 3 * (-(1-2t+t^2) * p0 + (1 - 4 * t + 3 * t^2) * p1 + (2 * t - 3 * + // t^2) * p2 + t^2 * p3) + float mt = 1.0f - t; + float d = t * t; + float a = -mt * mt; + float b = 1 - 4 * t + 3 * d; + float c = 2 * t - 3 * d; + + Point pt ={a * bz.start.x + b * bz.ctrl1.x + c * bz.ctrl2.x + d * bz.end.x, a * bz.start.y + b * bz.ctrl1.y + c * bz.ctrl2.y + d * bz.end.y}; + pt.x *= 3; + pt.y *= 3; + + return mathRad2Deg(atan2(pt.x, pt.y)); +} + +} + +#endif /* LV_USE_THORVG_INTERNAL */ diff --git a/test/include/liblvgl/libs/thorvg/tvgLines.h b/test/include/liblvgl/libs/thorvg/tvgLines.h new file mode 100644 index 00000000..804ced13 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLines.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LINES_H_ +#define _TVG_LINES_H_ + +#include "tvgCommon.h" + +namespace tvg +{ + +struct Line +{ + Point pt1; + Point pt2; +}; + +float lineLength(const Point& pt1, const Point& pt2); +void lineSplitAt(const Line& cur, float at, Line& left, Line& right); + + +struct Bezier +{ + Point start; + Point ctrl1; + Point ctrl2; + Point end; +}; + +void bezSplit(const Bezier&cur, Bezier& left, Bezier& right); +float bezLength(const Bezier& cur); +void bezSplitLeft(Bezier& cur, float at, Bezier& left); +float bezAt(const Bezier& bz, float at, float length); +void bezSplitAt(const Bezier& cur, float at, Bezier& left, Bezier& right); +Point bezPointAt(const Bezier& bz, float t); +float bezAngleAt(const Bezier& bz, float t); + +float bezLengthApprox(const Bezier& cur); +float bezAtApprox(const Bezier& bz, float at, float length); +} + +#endif //_TVG_LINES_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ diff --git a/test/include/liblvgl/libs/thorvg/tvgLoadModule.h b/test/include/liblvgl/libs/thorvg/tvgLoadModule.h new file mode 100644 index 00000000..210995fc --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLoadModule.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOAD_MODULE_H_ +#define _TVG_LOAD_MODULE_H_ + +#include "tvgRender.h" +#include "tvgInlist.h" + + +struct LoadModule +{ + INLIST_ITEM(LoadModule); + + //Use either hashkey(data) or hashpath(path) + union { + uintptr_t hashkey; + char* hashpath = nullptr; + }; + + FileType type; //current loader file type + uint16_t sharing = 0; //reference count + bool readied = false; //read done already. + bool pathcache = false; //cached by path + + LoadModule(FileType type) : type(type) {} + virtual ~LoadModule() + { + if (pathcache) free(hashpath); + } + + virtual bool open(const string& path) { return false; } + virtual bool open(const char* data, uint32_t size, bool copy) { return false; } + virtual bool resize(Paint* paint, float w, float h) { return false; } + virtual void sync() {}; //finish immediately if any async update jobs. + + virtual bool read() + { + if (readied) return false; + readied = true; + return true; + } + + bool cached() + { + if (hashkey) return true; + return false; + } + + virtual bool close() + { + if (sharing == 0) return true; + --sharing; + return false; + } +}; + + +struct ImageLoader : LoadModule +{ + static ColorSpace cs; //desired value + + float w = 0, h = 0; //default image size + Surface surface; + + ImageLoader(FileType type) : LoadModule(type) {} + + virtual bool animatable() { return false; } //true if this loader supports animation. + virtual Paint* paint() { return nullptr; } + + virtual Surface* bitmap() + { + if (surface.data) return &surface; + return nullptr; + } +}; + + +struct FontLoader : LoadModule +{ + float scale = 1.0f; + + FontLoader(FileType type) : LoadModule(type) {} + + virtual bool request(Shape* shape, char* text, bool italic = false) = 0; +}; + +#endif //_TVG_LOAD_MODULE_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLoader.cpp b/test/include/liblvgl/libs/thorvg/tvgLoader.cpp new file mode 100644 index 00000000..8d1a3c58 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLoader.cpp @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include + +#include "tvgInlist.h" +#include "tvgLoader.h" +#include "tvgLock.h" + +#ifdef THORVG_SVG_LOADER_SUPPORT + #include "tvgSvgLoader.h" +#endif + +#ifdef THORVG_PNG_LOADER_SUPPORT + #include "tvgPngLoader.h" +#endif + +#ifdef THORVG_TVG_LOADER_SUPPORT + #include "tvgTvgLoader.h" +#endif + +#ifdef THORVG_JPG_LOADER_SUPPORT + #include "tvgJpgLoader.h" +#endif + +#ifdef THORVG_WEBP_LOADER_SUPPORT + #include "tvgWebpLoader.h" +#endif + +#ifdef THORVG_TTF_LOADER_SUPPORT + #include "tvgTtfLoader.h" +#endif + +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + #include "tvgLottieLoader.h" +#endif + +#include "tvgRawLoader.h" + + +uintptr_t HASH_KEY(const char* data) +{ + return reinterpret_cast(data); +} + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +ColorSpace ImageLoader::cs = ColorSpace::ARGB8888; + +static Key key; +static Inlist _activeLoaders; + + +static LoadModule* _find(FileType type) +{ + switch(type) { + case FileType::Png: { +#ifdef THORVG_PNG_LOADER_SUPPORT + return new PngLoader; +#endif + break; + } + case FileType::Jpg: { +#ifdef THORVG_JPG_LOADER_SUPPORT + return new JpgLoader; +#endif + break; + } + case FileType::Webp: { +#ifdef THORVG_WEBP_LOADER_SUPPORT + return new WebpLoader; +#endif + break; + } + case FileType::Tvg: { +#ifdef THORVG_TVG_LOADER_SUPPORT + return new TvgLoader; +#endif + break; + } + case FileType::Svg: { +#ifdef THORVG_SVG_LOADER_SUPPORT + return new SvgLoader; +#endif + break; + } + case FileType::Ttf: { +#ifdef THORVG_TTF_LOADER_SUPPORT + return new TtfLoader; +#endif + break; + } + case FileType::Lottie: { +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + return new LottieLoader; +#endif + break; + } + case FileType::Raw: { + return new RawLoader; + break; + } + default: { + break; + } + } + +#ifdef THORVG_LOG_ENABLED + const char *format; + switch(type) { + case FileType::Tvg: { + format = "TVG"; + break; + } + case FileType::Svg: { + format = "SVG"; + break; + } + case FileType::Ttf: { + format = "TTF"; + break; + } + case FileType::Lottie: { + format = "lottie(json)"; + break; + } + case FileType::Raw: { + format = "RAW"; + break; + } + case FileType::Png: { + format = "PNG"; + break; + } + case FileType::Jpg: { + format = "JPG"; + break; + } + case FileType::Webp: { + format = "WEBP"; + break; + } + default: { + format = "???"; + break; + } + } + TVGLOG("RENDERER", "%s format is not supported", format); +#endif + return nullptr; +} + + +static LoadModule* _findByPath(const string& path) +{ + auto ext = path.substr(path.find_last_of(".") + 1); + if (!ext.compare("tvg")) return _find(FileType::Tvg); + if (!ext.compare("svg")) return _find(FileType::Svg); + if (!ext.compare("json")) return _find(FileType::Lottie); + if (!ext.compare("png")) return _find(FileType::Png); + if (!ext.compare("jpg")) return _find(FileType::Jpg); + if (!ext.compare("webp")) return _find(FileType::Webp); + if (!ext.compare("ttf") || !ext.compare("ttc")) return _find(FileType::Ttf); + if (!ext.compare("otf") || !ext.compare("otc")) return _find(FileType::Ttf); + return nullptr; +} + + +static FileType _convert(const string& mimeType) +{ + auto type = FileType::Unknown; + + if (mimeType == "tvg") type = FileType::Tvg; + else if (mimeType == "svg" || mimeType == "svg+xml") type = FileType::Svg; + else if (mimeType == "ttf" || mimeType == "otf") type = FileType::Ttf; + else if (mimeType == "lottie") type = FileType::Lottie; + else if (mimeType == "raw") type = FileType::Raw; + else if (mimeType == "png") type = FileType::Png; + else if (mimeType == "jpg" || mimeType == "jpeg") type = FileType::Jpg; + else if (mimeType == "webp") type = FileType::Webp; + else TVGLOG("RENDERER", "Given mimetype is unknown = \"%s\".", mimeType.c_str()); + + return type; +} + + +static LoadModule* _findByType(const string& mimeType) +{ + return _find(_convert(mimeType)); +} + + +static LoadModule* _findFromCache(const string& path) +{ + ScopedLock lock(key); + + auto loader = _activeLoaders.head; + + while (loader) { + if (loader->pathcache && !strcmp(loader->hashpath, path.c_str())) { + ++loader->sharing; + return loader; + } + loader = loader->next; + } + return nullptr; +} + + +static LoadModule* _findFromCache(const char* data, uint32_t size, const string& mimeType) +{ + auto type = _convert(mimeType); + if (type == FileType::Unknown) return nullptr; + + ScopedLock lock(key); + auto loader = _activeLoaders.head; + + auto key = HASH_KEY(data); + + while (loader) { + if (loader->type == type && loader->hashkey == key) { + ++loader->sharing; + return loader; + } + loader = loader->next; + } + return nullptr; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +bool LoaderMgr::init() +{ + return true; +} + + +bool LoaderMgr::term() +{ + auto loader = _activeLoaders.head; + + //clean up the remained font loaders which is globally used. + while (loader && loader->type == FileType::Ttf) { + auto ret = loader->close(); + auto tmp = loader; + loader = loader->next; + _activeLoaders.remove(tmp); + if (ret) delete(tmp); + } + return true; +} + + +bool LoaderMgr::retrieve(LoadModule* loader) +{ + if (!loader) return false; + if (loader->close()) { + if (loader->cached()) { + ScopedLock lock(key); + _activeLoaders.remove(loader); + } + delete(loader); + } + return true; +} + + +LoadModule* LoaderMgr::loader(const string& path, bool* invalid) +{ + *invalid = false; + + //TODO: lottie is not sharable. + auto allowCache = true; + auto ext = path.substr(path.find_last_of(".") + 1); + if (!ext.compare("json")) allowCache = false; + + if (allowCache) { + if (auto loader = _findFromCache(path)) return loader; + } + + if (auto loader = _findByPath(path)) { + if (loader->open(path)) { + if (allowCache) { + loader->hashpath = strdup(path.c_str()); + loader->pathcache = true; + { + ScopedLock lock(key); + _activeLoaders.back(loader); + } + } + return loader; + } + delete(loader); + } + //Unknown MimeType. Try with the candidates in the order + for (int i = 0; i < static_cast(FileType::Raw); i++) { + if (auto loader = _find(static_cast(i))) { + if (loader->open(path)) { + if (allowCache) { + loader->hashpath = strdup(path.c_str()); + loader->pathcache = true; + { + ScopedLock lock(key); + _activeLoaders.back(loader); + } + } + return loader; + } + delete(loader); + } + } + *invalid = true; + return nullptr; +} + + +bool LoaderMgr::retrieve(const string& path) +{ + return retrieve(_findFromCache(path)); +} + + +LoadModule* LoaderMgr::loader(const char* key) +{ + auto loader = _activeLoaders.head; + + while (loader) { + if (loader->pathcache && strstr(loader->hashpath, key)) { + ++loader->sharing; + return loader; + } + loader = loader->next; + } + return nullptr; +} + + +LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy) +{ + //Note that users could use the same data pointer with the different content. + //Thus caching is only valid for shareable. + auto allowCache = !copy; + + //TODO: lottie is not sharable. + if (allowCache) { + auto type = _convert(mimeType); + if (type == FileType::Lottie) allowCache = false; + } + + if (allowCache) { + if (auto loader = _findFromCache(data, size, mimeType)) return loader; + } + + //Try with the given MimeType + if (!mimeType.empty()) { + if (auto loader = _findByType(mimeType)) { + if (loader->open(data, size, copy)) { + if (allowCache) { + loader->hashkey = HASH_KEY(data); + ScopedLock lock(key); + _activeLoaders.back(loader); + } + return loader; + } else { + TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported.", mimeType.c_str()); + delete(loader); + } + } + } + //Unknown MimeType. Try with the candidates in the order + for (int i = 0; i < static_cast(FileType::Raw); i++) { + auto loader = _find(static_cast(i)); + if (loader) { + if (loader->open(data, size, copy)) { + if (allowCache) { + loader->hashkey = HASH_KEY(data); + ScopedLock lock(key); + _activeLoaders.back(loader); + } + return loader; + } + delete(loader); + } + } + return nullptr; +} + + +LoadModule* LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy) +{ + //Note that users could use the same data pointer with the different content. + //Thus caching is only valid for shareable. + if (!copy) { + //TODO: should we check premultiplied?? + if (auto loader = _findFromCache((const char*)(data), w * h, "raw")) return loader; + } + + //function is dedicated for raw images only + auto loader = new RawLoader; + if (loader->open(data, w, h, copy)) { + if (!copy) { + loader->hashkey = HASH_KEY((const char*)data); + ScopedLock lock(key); + _activeLoaders.back(loader); + } + return loader; + } + delete(loader); + return nullptr; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLoader.h b/test/include/liblvgl/libs/thorvg/tvgLoader.h new file mode 100644 index 00000000..50676990 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLoader.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOADER_H_ +#define _TVG_LOADER_H_ + +#include "tvgLoadModule.h" + +struct LoaderMgr +{ + static bool init(); + static bool term(); + static LoadModule* loader(const string& path, bool* invalid); + static LoadModule* loader(const char* data, uint32_t size, const string& mimeType, bool copy); + static LoadModule* loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); + static LoadModule* loader(const char* key); + static bool retrieve(const string& path); + static bool retrieve(LoadModule* loader); +}; + +#endif //_TVG_LOADER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLock.h b/test/include/liblvgl/libs/thorvg/tvgLock.h new file mode 100644 index 00000000..709c120e --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLock.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOCK_H_ +#define _TVG_LOCK_H_ + +#ifdef THORVG_THREAD_SUPPORT + +#include + +namespace tvg { + + struct Key + { + std::mutex mtx; + }; + + struct ScopedLock + { + Key* key = nullptr; + + ScopedLock(Key& k) + { + k.mtx.lock(); + key = &k; + } + + ~ScopedLock() + { + key->mtx.unlock(); + } + }; + +} + +#else //THORVG_THREAD_SUPPORT + +namespace tvg { + + struct Key {}; + + struct ScopedLock + { + ScopedLock(Key& key) {} + }; + +} + +#endif //THORVG_THREAD_SUPPORT + +#endif //_TVG_LOCK_H_ + + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieAnimation.cpp b/test/include/liblvgl/libs/thorvg/tvgLottieAnimation.cpp new file mode 100644 index 00000000..69818b37 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieAnimation.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgCommon.h" +#include "thorvg_lottie.h" +#include "tvgLottieLoader.h" +#include "tvgAnimation.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +LottieAnimation::~LottieAnimation() +{ +} + + +Result LottieAnimation::override(const char* slot) noexcept +{ + if (!pImpl->picture->pImpl->loader) return Result::InsufficientCondition; + + if (static_cast(pImpl->picture->pImpl->loader)->override(slot)) { + return Result::Success; + } + + return Result::InvalidArguments; +} + + +Result LottieAnimation::segment(const char* marker) noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + if (!loader) return Result::InsufficientCondition; + if (!loader->animatable()) return Result::NonSupport; + + if (!marker) { + static_cast(loader)->segment(0.0f, 1.0f); + return Result::Success; + } + + float begin, end; + if (!static_cast(loader)->segment(marker, begin, end)) { + return Result::InvalidArguments; + } + return static_cast(this)->segment(begin, end); +} + + +uint32_t LottieAnimation::markersCnt() noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + if (!loader || !loader->animatable()) return 0; + return static_cast(loader)->markersCnt(); +} + + +const char* LottieAnimation::marker(uint32_t idx) noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + if (!loader || !loader->animatable()) return nullptr; + return static_cast(loader)->markers(idx); +} + + +unique_ptr LottieAnimation::gen() noexcept +{ + return unique_ptr(new LottieAnimation); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieBuilder.cpp b/test/include/liblvgl/libs/thorvg/tvgLottieBuilder.cpp new file mode 100644 index 00000000..82a43cfd --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieBuilder.cpp @@ -0,0 +1,1378 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include + +#include "tvgCommon.h" +#include "tvgMath.h" +#include "tvgPaint.h" +#include "tvgShape.h" +#include "tvgInlist.h" +#include "tvgTaskScheduler.h" +#include "tvgLottieModel.h" +#include "tvgLottieBuilder.h" +#include "tvgLottieExpressions.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct RenderRepeater +{ + int cnt; + float offset; + Point position; + Point anchor; + Point scale; + float rotation; + uint8_t startOpacity; + uint8_t endOpacity; + bool interpOpacity; + bool inorder; +}; + + +struct RenderContext +{ + INLIST_ITEM(RenderContext); + + Shape* propagator = nullptr; + Shape* merging = nullptr; //merging shapes if possible (if shapes have same properties) + LottieObject** begin = nullptr; //iteration entry point + RenderRepeater* repeater = nullptr; + Matrix* transform = nullptr; + float roundness = 0.0f; + bool fragmenting = false; //render context has been fragmented by filling + bool reqFragment = false; //requirement to fragment the render context + bool ownPropagator = true; //this rendering context shares the propagator + + RenderContext() + { + propagator = Shape::gen().release(); + } + + ~RenderContext() + { + if (ownPropagator) delete(propagator); + delete(repeater); + free(transform); + } + + RenderContext(const RenderContext& rhs, bool mergeable = false) + { + if (mergeable) { + this->ownPropagator = false; + propagator = rhs.propagator; + merging = rhs.merging; + } else { + propagator = static_cast(rhs.propagator->duplicate()); + } + + if (rhs.repeater) { + repeater = new RenderRepeater(); + *repeater = *rhs.repeater; + } + roundness = rhs.roundness; + } +}; + + +static void _updateChildren(LottieGroup* parent, float frameNo, Inlist& contexts, LottieExpressions* exps); +static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps); +static bool _buildComposition(LottieComposition* comp, LottieGroup* parent); +static Shape* _draw(LottieGroup* parent, RenderContext* ctx); + +static void _rotateX(Matrix* m, float degree) +{ + if (degree == 0.0f) return; + auto radian = mathDeg2Rad(degree); + m->e22 *= cosf(radian); +} + + +static void _rotateY(Matrix* m, float degree) +{ + if (degree == 0.0f) return; + auto radian = mathDeg2Rad(degree); + m->e11 *= cosf(radian); +} + + +static void _rotationZ(Matrix* m, float degree) +{ + if (degree == 0.0f) return; + auto radian = mathDeg2Rad(degree); + m->e11 = cosf(radian); + m->e12 = -sinf(radian); + m->e21 = sinf(radian); + m->e22 = cosf(radian); +} + + +static void _skew(Matrix* m, float angleDeg, float axisDeg) +{ + auto angle = -mathDeg2Rad(angleDeg); + float tanVal = tanf(angle); + + axisDeg = fmod(axisDeg, 180.0f); + if (fabsf(axisDeg) < 0.01f || fabsf(axisDeg - 180.0f) < 0.01f || fabsf(axisDeg + 180.0f) < 0.01f) { + float cosVal = cosf(mathDeg2Rad(axisDeg)); + auto B = cosVal * cosVal * tanVal; + m->e12 += B * m->e11; + m->e22 += B * m->e21; + return; + } else if (fabsf(axisDeg - 90.0f) < 0.01f || fabsf(axisDeg + 90.0f) < 0.01f) { + float sinVal = -sinf(mathDeg2Rad(axisDeg)); + auto C = sinVal * sinVal * tanVal; + m->e11 -= C * m->e12; + m->e21 -= C * m->e22; + return; + } + + auto axis = -mathDeg2Rad(axisDeg); + float cosVal = cosf(axis); + float sinVal = sinf(axis); + auto A = sinVal * cosVal * tanVal; + auto B = cosVal * cosVal * tanVal; + auto C = sinVal * sinVal * tanVal; + + auto e11 = m->e11; + auto e21 = m->e21; + m->e11 = (1.0f - A) * e11 - C * m->e12; + m->e12 = B * e11 + (1.0f + A) * m->e12; + m->e21 = (1.0f - A) * e21 - C * m->e22; + m->e22 = B * e21 + (1.0f + A) * m->e22; +} + + +static bool _updateTransform(LottieTransform* transform, float frameNo, bool autoOrient, Matrix& matrix, uint8_t& opacity, LottieExpressions* exps) +{ + mathIdentity(&matrix); + + if (!transform) { + opacity = 255; + return false; + } + + if (transform->coords) { + mathTranslate(&matrix, transform->coords->x(frameNo), transform->coords->y(frameNo)); + } else { + auto position = transform->position(frameNo, exps); + mathTranslate(&matrix, position.x, position.y); + } + + auto angle = 0.0f; + if (autoOrient) angle = transform->position.angle(frameNo); + _rotationZ(&matrix, transform->rotation(frameNo, exps) + angle); + + if (transform->rotationEx) { + _rotateY(&matrix, transform->rotationEx->y(frameNo, exps)); + _rotateX(&matrix, transform->rotationEx->x(frameNo, exps)); + } + + auto skewAngle = transform->skewAngle(frameNo, exps); + if (skewAngle != 0.0f) { + // For angles where tangent explodes, the shape degenerates into an infinitely thin line. + // This is handled by zeroing out the matrix due to finite numerical precision. + skewAngle = fmod(skewAngle, 180.0f); + if (fabsf(skewAngle - 90.0f) < 0.01f || fabsf(skewAngle + 90.0f) < 0.01f) return false; + _skew(&matrix, skewAngle, transform->skewAxis(frameNo, exps)); + } + + auto scale = transform->scale(frameNo, exps); + mathScaleR(&matrix, scale.x * 0.01f, scale.y * 0.01f); + + //Lottie specific anchor transform. + auto anchor = transform->anchor(frameNo, exps); + mathTranslateR(&matrix, -anchor.x, -anchor.y); + + //invisible just in case. + if (scale.x == 0.0f || scale.y == 0.0f) opacity = 0; + else opacity = transform->opacity(frameNo, exps); + + return true; +} + + +static void _updateTransform(LottieLayer* layer, float frameNo, LottieExpressions* exps) +{ + if (!layer || mathEqual(layer->cache.frameNo, frameNo)) return; + + auto transform = layer->transform; + auto parent = layer->parent; + + if (parent) _updateTransform(parent, frameNo, exps); + + auto& matrix = layer->cache.matrix; + + _updateTransform(transform, frameNo, layer->autoOrient, matrix, layer->cache.opacity, exps); + + if (parent) { + if (!mathIdentity((const Matrix*) &parent->cache.matrix)) { + if (mathIdentity((const Matrix*) &matrix)) layer->cache.matrix = parent->cache.matrix; + else layer->cache.matrix = mathMultiply(&parent->cache.matrix, &matrix); + } + } + layer->cache.frameNo = frameNo; +} + + +static void _updateTransform(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto transform = static_cast(*child); + if (!transform) return; + + uint8_t opacity; + + if (parent->mergeable()) { + if (!ctx->transform) ctx->transform = (Matrix*)malloc(sizeof(Matrix)); + _updateTransform(transform, frameNo, false, *ctx->transform, opacity, exps); + return; + } + + ctx->merging = nullptr; + + Matrix matrix; + if (!_updateTransform(transform, frameNo, false, matrix, opacity, exps)) return; + + auto pmatrix = PP(ctx->propagator)->transform(); + ctx->propagator->transform(pmatrix ? mathMultiply(pmatrix, &matrix) : matrix); + ctx->propagator->opacity(MULTIPLY(opacity, PP(ctx->propagator)->opacity)); + + //FIXME: preserve the stroke width. too workaround, need a better design. + if (P(ctx->propagator)->rs.strokeWidth() > 0.0f) { + auto denominator = sqrtf(matrix.e11 * matrix.e11 + matrix.e12 * matrix.e12); + if (denominator > 1.0f) ctx->propagator->stroke(ctx->propagator->strokeWidth() / denominator); + } +} + + +static void _updateGroup(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& pcontexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto group = static_cast(*child); + + if (group->children.empty()) return; + + //Prepare render data + group->scene = parent->scene; + group->reqFragment |= ctx->reqFragment; + + //generate a merging shape to consolidate partial shapes into a single entity + if (group->mergeable()) _draw(parent, ctx); + + Inlist contexts; + contexts.back(new RenderContext(*ctx, group->mergeable())); + + _updateChildren(group, frameNo, contexts, exps); + + contexts.free(); +} + + +static void _updateStroke(LottieStroke* stroke, float frameNo, RenderContext* ctx, LottieExpressions* exps) +{ + ctx->propagator->stroke(stroke->width(frameNo, exps)); + ctx->propagator->stroke(stroke->cap); + ctx->propagator->stroke(stroke->join); + ctx->propagator->strokeMiterlimit(stroke->miterLimit); + + if (stroke->dashattr) { + float dashes[2]; + dashes[0] = stroke->dashSize(frameNo, exps); + dashes[1] = dashes[0] + stroke->dashGap(frameNo, exps); + P(ctx->propagator)->strokeDash(dashes, 2, stroke->dashOffset(frameNo, exps)); + } else { + ctx->propagator->stroke(nullptr, 0); + } +} + + +static bool _fragmented(LottieObject** child, Inlist& contexts, RenderContext* ctx) +{ + if (!ctx->reqFragment) return false; + if (ctx->fragmenting) return true; + + contexts.back(new RenderContext(*ctx)); + auto fragment = contexts.tail; + fragment->begin = child - 1; + ctx->fragmenting = true; + + return false; +} + + +static void _updateSolidStroke(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + if (_fragmented(child, contexts, ctx)) return; + + auto stroke = static_cast(*child); + + ctx->merging = nullptr; + auto color = stroke->color(frameNo, exps); + ctx->propagator->stroke(color.rgb[0], color.rgb[1], color.rgb[2], stroke->opacity(frameNo, exps)); + _updateStroke(static_cast(stroke), frameNo, ctx, exps); +} + + +static void _updateGradientStroke(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + if (_fragmented(child, contexts, ctx)) return; + + auto stroke = static_cast(*child); + + ctx->merging = nullptr; + ctx->propagator->stroke(unique_ptr(stroke->fill(frameNo, exps))); + _updateStroke(static_cast(stroke), frameNo, ctx, exps); +} + + +static void _updateSolidFill(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + if (_fragmented(child, contexts, ctx)) return; + + auto fill = static_cast(*child); + + ctx->merging = nullptr; + auto color = fill->color(frameNo); + ctx->propagator->fill(color.rgb[0], color.rgb[1], color.rgb[2], fill->opacity(frameNo, exps)); + ctx->propagator->fill(fill->rule); + + if (ctx->propagator->strokeWidth() > 0) ctx->propagator->order(true); +} + + +static void _updateGradientFill(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + if (_fragmented(child, contexts, ctx)) return; + + auto fill = static_cast(*child); + + ctx->merging = nullptr; + //TODO: reuse the fill instance? + ctx->propagator->fill(unique_ptr(fill->fill(frameNo, exps))); + ctx->propagator->fill(fill->rule); + ctx->propagator->opacity(MULTIPLY(fill->opacity(frameNo), PP(ctx->propagator)->opacity)); + + if (ctx->propagator->strokeWidth() > 0) ctx->propagator->order(true); +} + + +static Shape* _draw(LottieGroup* parent, RenderContext* ctx) +{ + if (ctx->merging) return ctx->merging; + + auto shape = cast(ctx->propagator->duplicate()); + ctx->merging = shape.get(); + parent->scene->push(std::move(shape)); + + return ctx->merging; +} + + +//OPTIMIZE: path? +static void _repeat(LottieGroup* parent, unique_ptr path, RenderContext* ctx) +{ + auto repeater = ctx->repeater; + + Array shapes(repeater->cnt); + + for (int i = 0; i < repeater->cnt; ++i) { + auto multiplier = repeater->offset + static_cast(i); + + auto shape = static_cast(ctx->propagator->duplicate()); + P(shape)->rs.path = P(path.get())->rs.path; + + auto opacity = repeater->interpOpacity ? mathLerp(repeater->startOpacity, repeater->endOpacity, static_cast(i + 1) / repeater->cnt) : repeater->startOpacity; + shape->opacity(opacity); + + Matrix m; + mathIdentity(&m); + mathTranslate(&m, repeater->position.x * multiplier + repeater->anchor.x, repeater->position.y * multiplier + repeater->anchor.y); + mathScale(&m, powf(repeater->scale.x * 0.01f, multiplier), powf(repeater->scale.y * 0.01f, multiplier)); + mathRotate(&m, repeater->rotation * multiplier); + mathTranslateR(&m, -repeater->anchor.x, -repeater->anchor.y); + + auto pm = PP(shape)->transform(); + shape->transform(pm ? mathMultiply(&m, pm) : m); + + if (ctx->roundness > 1.0f && P(shape)->rs.stroke) { + TVGERR("LOTTIE", "FIXME: Path roundness should be applied properly!"); + P(shape)->rs.stroke->join = StrokeJoin::Round; + } + + shapes.push(shape); + } + + //push repeat shapes in order. + if (repeater->inorder) { + for (auto shape = shapes.begin(); shape < shapes.end(); ++shape) { + parent->scene->push(cast(*shape)); + } + } else { + for (auto shape = shapes.end() - 1; shape >= shapes.begin(); --shape) { + parent->scene->push(cast(*shape)); + } + } +} + + +static void _appendRect(Shape* shape, float x, float y, float w, float h, float r, Matrix* transform) +{ + //sharp rect + if (mathZero(r)) { + PathCommand commands[] = { + PathCommand::MoveTo, PathCommand::LineTo, PathCommand::LineTo, + PathCommand::LineTo, PathCommand::Close + }; + + Point points[] = {{x + w, y}, {x + w, y + h}, {x, y + h}, {x, y}}; + if (transform) { + for (int i = 0; i < 4; i++) mathTransform(transform, &points[i]); + } + shape->appendPath(commands, 5, points, 4); + //round rect + } else { + PathCommand commands[] = { + PathCommand::MoveTo, PathCommand::LineTo, PathCommand::CubicTo, + PathCommand::LineTo, PathCommand::CubicTo, PathCommand::LineTo, + PathCommand::CubicTo, PathCommand::LineTo, PathCommand::CubicTo, + PathCommand::Close + }; + + auto halfW = w * 0.5f; + auto halfH = h * 0.5f; + auto rx = r > halfW ? halfW : r; + auto ry = r > halfH ? halfH : r; + auto hrx = rx * PATH_KAPPA; + auto hry = ry * PATH_KAPPA; + + constexpr int ptsCnt = 17; + Point points[ptsCnt] = { + {x + w, y + ry}, //moveTo + {x + w, y + h - ry}, //lineTo + {x + w, y + h - ry + hry}, {x + w - rx + hrx, y + h}, {x + w - rx, y + h}, //cubicTo + {x + rx, y + h}, //lineTo + {x + rx - hrx, y + h}, {x, y + h - ry + hry}, {x, y + h - ry}, //cubicTo + {x, y + ry}, //lineTo + {x, y + ry - hry}, {x + rx - hrx, y}, {x + rx, y}, //cubicTo + {x + w - rx, y}, //lineTo + {x + w - rx + hrx, y}, {x + w, y + ry - hry}, {x + w, y + ry} //cubicTo + }; + + if (transform) { + for (int i = 0; i < ptsCnt; i++) mathTransform(transform, &points[i]); + } + shape->appendPath(commands, 10, points, ptsCnt); + } +} + +static void _updateRect(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto rect = static_cast(*child); + + auto position = rect->position(frameNo, exps); + auto size = rect->size(frameNo, exps); + auto roundness = rect->radius(frameNo, exps); + if (ctx->roundness > roundness) roundness = ctx->roundness; + + if (roundness > ROUNDNESS_EPSILON) { + if (roundness > size.x * 0.5f) roundness = size.x * 0.5f; + if (roundness > size.y * 0.5f) roundness = size.y * 0.5f; + } + + if (ctx->repeater) { + auto path = Shape::gen(); + _appendRect(path.get(), position.x - size.x * 0.5f, position.y - size.y * 0.5f, size.x, size.y, roundness, ctx->transform); + _repeat(parent, std::move(path), ctx); + } else { + auto merging = _draw(parent, ctx); + _appendRect(merging, position.x - size.x * 0.5f, position.y - size.y * 0.5f, size.x, size.y, roundness, ctx->transform); + } +} + + +static void _appendCircle(Shape* shape, float cx, float cy, float rx, float ry, Matrix* transform) +{ + auto rxKappa = rx * PATH_KAPPA; + auto ryKappa = ry * PATH_KAPPA; + + constexpr int cmdsCnt = 6; + PathCommand commands[cmdsCnt] = { + PathCommand::MoveTo, PathCommand::CubicTo, PathCommand::CubicTo, + PathCommand::CubicTo, PathCommand::CubicTo, PathCommand::Close + }; + + constexpr int ptsCnt = 13; + Point points[ptsCnt] = { + {cx, cy - ry}, //moveTo + {cx + rxKappa, cy - ry}, {cx + rx, cy - ryKappa}, {cx + rx, cy}, //cubicTo + {cx + rx, cy + ryKappa}, {cx + rxKappa, cy + ry}, {cx, cy + ry}, //cubicTo + {cx - rxKappa, cy + ry}, {cx - rx, cy + ryKappa}, {cx - rx, cy}, //cubicTo + {cx - rx, cy - ryKappa}, {cx - rxKappa, cy - ry}, {cx, cy - ry} //cubicTo + }; + + if (transform) { + for (int i = 0; i < ptsCnt; ++i) mathTransform(transform, &points[i]); + } + + shape->appendPath(commands, cmdsCnt, points, ptsCnt); +} + + +static void _updateEllipse(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto ellipse = static_cast(*child); + + auto position = ellipse->position(frameNo, exps); + auto size = ellipse->size(frameNo, exps); + + if (ctx->repeater) { + auto path = Shape::gen(); + _appendCircle(path.get(), position.x, position.y, size.x * 0.5f, size.y * 0.5f, ctx->transform); + _repeat(parent, std::move(path), ctx); + } else { + auto merging = _draw(parent, ctx); + _appendCircle(merging, position.x, position.y, size.x * 0.5f, size.y * 0.5f, ctx->transform); + } +} + + +static void _updatePath(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto path = static_cast(*child); + + if (ctx->repeater) { + auto p = Shape::gen(); + path->pathset(frameNo, P(p)->rs.path.cmds, P(p)->rs.path.pts, ctx->transform, ctx->roundness, exps); + _repeat(parent, std::move(p), ctx); + } else { + auto merging = _draw(parent, ctx); + if (path->pathset(frameNo, P(merging)->rs.path.cmds, P(merging)->rs.path.pts, ctx->transform, ctx->roundness, exps)) { + P(merging)->update(RenderUpdateFlag::Path); + } + } +} + + +static void _updateText(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, TVG_UNUSED RenderContext* ctx, LottieExpressions* exps) +{ + auto text = static_cast(*child); + auto& doc = text->doc(frameNo); + auto p = doc.text; + + if (!p || !text->font) return; + + auto scale = doc.size * 0.01f; + float spacing = text->spacing(frameNo) / scale; + Point cursor = {0.0f, 0.0f}; + auto scene = Scene::gen(); + int line = 0; + + //text string + while (true) { + //TODO: remove nested scenes. + //end of text, new line of the cursor position + if (*p == 13 || *p == 3 || *p == '\0') { + //text layout position + auto ascent = text->font->ascent * scale; + if (ascent > doc.bbox.size.y) ascent = doc.bbox.size.y; + Point layout = {doc.bbox.pos.x, doc.bbox.pos.y + ascent - doc.shift}; + + //adjust the layout + if (doc.justify == 1) layout.x += doc.bbox.size.x - (cursor.x * scale); //right aligned + else if (doc.justify == 2) layout.x += (doc.bbox.size.x * 0.5f) - (cursor.x * 0.5f * scale); //center aligned + + scene->translate(layout.x, layout.y); + scene->scale(scale); + + parent->scene->push(std::move(scene)); + + if (*p == '\0') break; + ++p; + + //new text group, single scene for each line + scene = Scene::gen(); + cursor.x = 0.0f; + cursor.y = ++line * (doc.height / scale); + } + + //find the glyph + for (auto g = text->font->chars.begin(); g < text->font->chars.end(); ++g) { + auto glyph = *g; + //draw matched glyphs + if (!strncmp(glyph->code, p, glyph->len)) { + //TODO: caching? + auto shape = Shape::gen(); + for (auto g = glyph->children.begin(); g < glyph->children.end(); ++g) { + auto group = static_cast(*g); + for (auto p = group->children.begin(); p < group->children.end(); ++p) { + if (static_cast(*p)->pathset(frameNo, P(shape)->rs.path.cmds, P(shape)->rs.path.pts, nullptr, 0.0f, exps)) { + P(shape)->update(RenderUpdateFlag::Path); + } + } + } + shape->fill(doc.color.rgb[0], doc.color.rgb[1], doc.color.rgb[2]); + shape->translate(cursor.x, cursor.y); + + if (doc.stroke.render) { + shape->stroke(StrokeJoin::Round); + shape->stroke(doc.stroke.width / scale); + shape->stroke(doc.stroke.color.rgb[0], doc.stroke.color.rgb[1], doc.stroke.color.rgb[2]); + } + + scene->push(std::move(shape)); + + p += glyph->len; + + //advance the cursor position horizontally + cursor.x += glyph->width + spacing + doc.tracking; + break; + } + } + } +} + + +static void _applyRoundedCorner(Shape* star, Shape* merging, float outerRoundness, float roundness, bool hasRoundness) +{ + static constexpr auto ROUNDED_POLYSTAR_MAGIC_NUMBER = 0.47829f; + + auto cmdCnt = star->pathCommands(nullptr); + const Point *pts = nullptr; + auto ptsCnt = star->pathCoords(&pts); + + auto len = mathLength(pts[1] - pts[2]); + auto r = len > 0.0f ? ROUNDED_POLYSTAR_MAGIC_NUMBER * mathMin(len * 0.5f, roundness) / len : 0.0f; + + if (hasRoundness) { + P(merging)->rs.path.cmds.grow((uint32_t)(1.5 * cmdCnt)); + P(merging)->rs.path.pts.grow((uint32_t)(4.5 * cmdCnt)); + + int start = 3 * mathZero(outerRoundness); + merging->moveTo(pts[start].x, pts[start].y); + + for (uint32_t i = 1 + start; i < ptsCnt; i += 6) { + auto& prev = pts[i]; + auto& curr = pts[i + 2]; + auto& next = (i < ptsCnt - start) ? pts[i + 4] : pts[2]; + auto& nextCtrl = (i < ptsCnt - start) ? pts[i + 5] : pts[3]; + auto dNext = r * (curr - next); + auto dPrev = r * (curr - prev); + + auto p0 = curr - 2.0f * dPrev; + auto p1 = curr - dPrev; + auto p2 = curr - dNext; + auto p3 = curr - 2.0f * dNext; + + merging->cubicTo(prev.x, prev.y, p0.x, p0.y, p0.x, p0.y); + merging->cubicTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + merging->cubicTo(p3.x, p3.y, next.x, next.y, nextCtrl.x, nextCtrl.y); + } + } else { + P(merging)->rs.path.cmds.grow(2 * cmdCnt); + P(merging)->rs.path.pts.grow(4 * cmdCnt); + + auto dPrev = r * (pts[1] - pts[0]); + auto p = pts[0] + 2.0f * dPrev; + merging->moveTo(p.x, p.y); + + for (uint32_t i = 1; i < ptsCnt; ++i) { + auto& curr = pts[i]; + auto& next = (i == ptsCnt - 1) ? pts[1] : pts[i + 1]; + auto dNext = r * (curr - next); + + auto p0 = curr - 2.0f * dPrev; + auto p1 = curr - dPrev; + auto p2 = curr - dNext; + auto p3 = curr - 2.0f * dNext; + + merging->lineTo(p0.x, p0.y); + merging->cubicTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + + dPrev = -1.0f * dNext; + } + } + merging->close(); +} + + +static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, float roundness, float frameNo, Shape* merging, LottieExpressions* exps) +{ + static constexpr auto POLYSTAR_MAGIC_NUMBER = 0.47829f / 0.28f; + + auto ptsCnt = star->ptsCnt(frameNo, exps); + auto innerRadius = star->innerRadius(frameNo, exps); + auto outerRadius = star->outerRadius(frameNo, exps); + auto innerRoundness = star->innerRoundness(frameNo, exps) * 0.01f; + auto outerRoundness = star->outerRoundness(frameNo, exps) * 0.01f; + + auto angle = mathDeg2Rad(-90.0f); + auto partialPointRadius = 0.0f; + auto anglePerPoint = (2.0f * MATH_PI / ptsCnt); + auto halfAnglePerPoint = anglePerPoint * 0.5f; + auto partialPointAmount = ptsCnt - floorf(ptsCnt); + auto longSegment = false; + auto numPoints = size_t(ceilf(ptsCnt) * 2); + auto direction = (star->direction == 0) ? 1.0f : -1.0f; + auto hasRoundness = false; + bool roundedCorner = (roundness > ROUNDNESS_EPSILON) && (mathZero(innerRoundness) || mathZero(outerRoundness)); + //TODO: we can use PathCommand / PathCoord directly. + auto shape = roundedCorner ? Shape::gen().release() : merging; + + float x, y; + + if (!mathZero(partialPointAmount)) { + angle += halfAnglePerPoint * (1.0f - partialPointAmount) * direction; + } + + if (!mathZero(partialPointAmount)) { + partialPointRadius = innerRadius + partialPointAmount * (outerRadius - innerRadius); + x = partialPointRadius * cosf(angle); + y = partialPointRadius * sinf(angle); + angle += anglePerPoint * partialPointAmount * 0.5f * direction; + } else { + x = outerRadius * cosf(angle); + y = outerRadius * sinf(angle); + angle += halfAnglePerPoint * direction; + } + + if (mathZero(innerRoundness) && mathZero(outerRoundness)) { + P(shape)->rs.path.pts.reserve(numPoints + 2); + P(shape)->rs.path.cmds.reserve(numPoints + 3); + } else { + P(shape)->rs.path.pts.reserve(numPoints * 3 + 2); + P(shape)->rs.path.cmds.reserve(numPoints + 3); + hasRoundness = true; + } + + Point in = {x, y}; + if (transform) mathTransform(transform, &in); + shape->moveTo(in.x, in.y); + + for (size_t i = 0; i < numPoints; i++) { + auto radius = longSegment ? outerRadius : innerRadius; + auto dTheta = halfAnglePerPoint; + if (!mathZero(partialPointRadius) && i == numPoints - 2) { + dTheta = anglePerPoint * partialPointAmount * 0.5f; + } + if (!mathZero(partialPointRadius) && i == numPoints - 1) { + radius = partialPointRadius; + } + auto previousX = x; + auto previousY = y; + x = radius * cosf(angle); + y = radius * sinf(angle); + + if (hasRoundness) { + auto cp1Theta = (atan2f(previousY, previousX) - MATH_PI2 * direction); + auto cp1Dx = cosf(cp1Theta); + auto cp1Dy = sinf(cp1Theta); + auto cp2Theta = (atan2f(y, x) - MATH_PI2 * direction); + auto cp2Dx = cosf(cp2Theta); + auto cp2Dy = sinf(cp2Theta); + + auto cp1Roundness = longSegment ? innerRoundness : outerRoundness; + auto cp2Roundness = longSegment ? outerRoundness : innerRoundness; + auto cp1Radius = longSegment ? innerRadius : outerRadius; + auto cp2Radius = longSegment ? outerRadius : innerRadius; + + auto cp1x = cp1Radius * cp1Roundness * POLYSTAR_MAGIC_NUMBER * cp1Dx / ptsCnt; + auto cp1y = cp1Radius * cp1Roundness * POLYSTAR_MAGIC_NUMBER * cp1Dy / ptsCnt; + auto cp2x = cp2Radius * cp2Roundness * POLYSTAR_MAGIC_NUMBER * cp2Dx / ptsCnt; + auto cp2y = cp2Radius * cp2Roundness * POLYSTAR_MAGIC_NUMBER * cp2Dy / ptsCnt; + + if (!mathZero(partialPointAmount) && ((i == 0) || (i == numPoints - 1))) { + cp1x *= partialPointAmount; + cp1y *= partialPointAmount; + cp2x *= partialPointAmount; + cp2y *= partialPointAmount; + } + Point in2 = {previousX - cp1x, previousY - cp1y}; + Point in3 = {x + cp2x, y + cp2y}; + Point in4 = {x, y}; + if (transform) { + mathTransform(transform, &in2); + mathTransform(transform, &in3); + mathTransform(transform, &in4); + } + shape->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y); + } else { + Point in = {x, y}; + if (transform) mathTransform(transform, &in); + shape->lineTo(in.x, in.y); + } + angle += dTheta * direction; + longSegment = !longSegment; + } + shape->close(); + + if (roundedCorner) { + _applyRoundedCorner(shape, merging, outerRoundness, roundness, hasRoundness); + delete(shape); + } +} + + +static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, float frameNo, Shape* merging, LottieExpressions* exps) +{ + static constexpr auto POLYGON_MAGIC_NUMBER = 0.25f; + + auto ptsCnt = size_t(floor(star->ptsCnt(frameNo, exps))); + auto radius = star->outerRadius(frameNo, exps); + auto roundness = star->outerRoundness(frameNo, exps) * 0.01f; + + auto angle = mathDeg2Rad(-90.0f); + auto anglePerPoint = 2.0f * MATH_PI / float(ptsCnt); + auto direction = (star->direction == 0) ? 1.0f : -1.0f; + auto hasRoundness = false; + auto x = radius * cosf(angle); + auto y = radius * sinf(angle); + + angle += anglePerPoint * direction; + + if (mathZero(roundness)) { + P(merging)->rs.path.pts.reserve(ptsCnt + 2); + P(merging)->rs.path.cmds.reserve(ptsCnt + 3); + } else { + P(merging)->rs.path.pts.reserve(ptsCnt * 3 + 2); + P(merging)->rs.path.cmds.reserve(ptsCnt + 3); + hasRoundness = true; + } + + Point in = {x, y}; + if (transform) mathTransform(transform, &in); + merging->moveTo(in.x, in.y); + + for (size_t i = 0; i < ptsCnt; i++) { + auto previousX = x; + auto previousY = y; + x = (radius * cosf(angle)); + y = (radius * sinf(angle)); + + if (hasRoundness) { + auto cp1Theta = atan2f(previousY, previousX) - MATH_PI2 * direction; + auto cp1Dx = cosf(cp1Theta); + auto cp1Dy = sinf(cp1Theta); + auto cp2Theta = atan2f(y, x) - MATH_PI2 * direction; + auto cp2Dx = cosf(cp2Theta); + auto cp2Dy = sinf(cp2Theta); + + auto cp1x = radius * roundness * POLYGON_MAGIC_NUMBER * cp1Dx; + auto cp1y = radius * roundness * POLYGON_MAGIC_NUMBER * cp1Dy; + auto cp2x = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dx; + auto cp2y = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dy; + + Point in2 = {previousX - cp1x, previousY - cp1y}; + Point in3 = {x + cp2x, y + cp2y}; + Point in4 = {x, y}; + if (transform) { + mathTransform(transform, &in2); + mathTransform(transform, &in3); + mathTransform(transform, &in4); + } + merging->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y); + } else { + Point in = {x, y}; + if (transform) mathTransform(transform, &in); + merging->lineTo(in.x, in.y); + } + angle += anglePerPoint * direction; + } + merging->close(); +} + + +static void _updatePolystar(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto star= static_cast(*child); + + //Optimize: Can we skip the individual coords transform? + Matrix matrix; + mathIdentity(&matrix); + auto position = star->position(frameNo, exps); + mathTranslate(&matrix, position.x, position.y); + mathRotate(&matrix, star->rotation(frameNo, exps)); + + if (ctx->transform) matrix = mathMultiply(ctx->transform, &matrix); + + auto identity = mathIdentity((const Matrix*)&matrix); + + if (ctx->repeater) { + auto p = Shape::gen(); + if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, ctx->roundness, frameNo, p.get(), exps); + else _updatePolygon(parent, star, identity ? nullptr : &matrix, frameNo, p.get(), exps); + _repeat(parent, std::move(p), ctx); + } else { + auto merging = _draw(parent, ctx); + if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, ctx->roundness, frameNo, merging, exps); + else _updatePolygon(parent, star, identity ? nullptr : &matrix, frameNo, merging, exps); + P(merging)->update(RenderUpdateFlag::Path); + } +} + + +static void _updateImage(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx) +{ + auto image = static_cast(*child); + auto picture = image->picture; + + if (!picture) { + picture = Picture::gen().release(); + + //force to load a picture on the same thread + TaskScheduler::async(false); + + if (image->size > 0) { + if (picture->load((const char*)image->b64Data, image->size, image->mimeType, false) != Result::Success) { + delete(picture); + return; + } + } else { + if (picture->load(image->path) != Result::Success) { + delete(picture); + return; + } + } + + TaskScheduler::async(true); + + image->picture = picture; + PP(picture)->ref(); + } + + if (ctx->propagator) { + if (auto matrix = PP(ctx->propagator)->transform()) { + picture->transform(*matrix); + } + picture->opacity(PP(ctx->propagator)->opacity); + } + parent->scene->push(cast(picture)); +} + + +static void _updateRoundedCorner(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto roundedCorner= static_cast(*child); + auto roundness = roundedCorner->radius(frameNo, exps); + if (ctx->roundness < roundness) ctx->roundness = roundness; +} + + +static void _updateRepeater(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto repeater= static_cast(*child); + + if (!ctx->repeater) ctx->repeater = new RenderRepeater(); + ctx->repeater->cnt = static_cast(repeater->copies(frameNo, exps)); + ctx->repeater->offset = repeater->offset(frameNo, exps); + ctx->repeater->position = repeater->position(frameNo, exps); + ctx->repeater->anchor = repeater->anchor(frameNo, exps); + ctx->repeater->scale = repeater->scale(frameNo, exps); + ctx->repeater->rotation = repeater->rotation(frameNo, exps); + ctx->repeater->startOpacity = repeater->startOpacity(frameNo, exps); + ctx->repeater->endOpacity = repeater->endOpacity(frameNo, exps); + ctx->repeater->inorder = repeater->inorder; + ctx->repeater->interpOpacity = (ctx->repeater->startOpacity == ctx->repeater->endOpacity) ? false : true; + + ctx->merging = nullptr; +} + + +static void _updateTrimpath(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto trimpath= static_cast(*child); + + float begin, end; + trimpath->segment(frameNo, begin, end, exps); + + if (P(ctx->propagator)->rs.stroke) { + auto pbegin = P(ctx->propagator)->rs.stroke->trim.begin; + auto pend = P(ctx->propagator)->rs.stroke->trim.end; + auto length = fabsf(pend - pbegin); + begin = (length * begin) + pbegin; + end = (length * end) + pbegin; + } + + P(ctx->propagator)->strokeTrim(begin, end, trimpath->type == LottieTrimpath::Type::Individual ? true : false); +} + + +static void _updateChildren(LottieGroup* parent, float frameNo, Inlist& contexts, LottieExpressions* exps) +{ + contexts.head->begin = parent->children.end() - 1; + + while (!contexts.empty()) { + auto ctx = contexts.front(); + ctx->reqFragment = parent->reqFragment; + for (auto child = ctx->begin; child >= parent->children.data; --child) { + //Here switch-case statements are more performant than virtual methods. + switch ((*child)->type) { + case LottieObject::Group: { + _updateGroup(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Transform: { + _updateTransform(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::SolidFill: { + _updateSolidFill(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::SolidStroke: { + _updateSolidStroke(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::GradientFill: { + _updateGradientFill(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::GradientStroke: { + _updateGradientStroke(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Rect: { + _updateRect(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Ellipse: { + _updateEllipse(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Path: { + _updatePath(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Polystar: { + _updatePolystar(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Image: { + _updateImage(parent, child, frameNo, contexts, ctx); + break; + } + case LottieObject::Trimpath: { + _updateTrimpath(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Text: { + _updateText(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Repeater: { + _updateRepeater(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::RoundedCorner: { + _updateRoundedCorner(parent, child, frameNo, contexts, ctx, exps); + break; + } + default: break; + } + } + delete(ctx); + } +} + + +static void _updatePrecomp(LottieLayer* precomp, float frameNo, LottieExpressions* exps) +{ + if (precomp->children.empty()) return; + + frameNo = precomp->remap(frameNo, exps); + + for (auto child = precomp->children.end() - 1; child >= precomp->children.begin(); --child) { + _updateLayer(precomp, static_cast(*child), frameNo, exps); + } + + //clip the layer viewport + if (precomp->w > 0 && precomp->h > 0) { + auto clipper = Shape::gen().release(); + clipper->appendRect(0, 0, static_cast(precomp->w), static_cast(precomp->h)); + clipper->transform(precomp->cache.matrix); + + //TODO: remove the intermediate scene.... + auto cscene = Scene::gen(); + cscene->composite(cast(clipper), CompositeMethod::ClipPath); + cscene->push(cast(precomp->scene)); + precomp->scene = cscene.release(); + } +} + + +static void _updateSolid(LottieLayer* layer) +{ + auto shape = Shape::gen(); + shape->appendRect(0, 0, static_cast(layer->w), static_cast(layer->h)); + shape->fill(layer->color.rgb[0], layer->color.rgb[1], layer->color.rgb[2], layer->cache.opacity); + layer->scene->push(std::move(shape)); +} + + +static void _updateMaskings(LottieLayer* layer, float frameNo, LottieExpressions* exps) +{ + if (layer->masks.count == 0) return; + + //maskings + Shape* pmask = nullptr; + auto pmethod = CompositeMethod::AlphaMask; + + for (auto m = layer->masks.begin(); m < layer->masks.end(); ++m) { + auto mask = static_cast(*m); + auto shape = Shape::gen().release(); + shape->fill(255, 255, 255, mask->opacity(frameNo)); + shape->transform(layer->cache.matrix); + if (mask->pathset(frameNo, P(shape)->rs.path.cmds, P(shape)->rs.path.pts, nullptr, 0.0f, exps)) { + P(shape)->update(RenderUpdateFlag::Path); + } + auto method = mask->method; + if (pmask) { + //false of false is true. invert. + if (method == CompositeMethod::SubtractMask && pmethod == method) { + method = CompositeMethod::AddMask; + } else if (pmethod == CompositeMethod::DifferenceMask && pmethod == method) { + method = CompositeMethod::IntersectMask; + } + pmask->composite(cast(shape), method); + } else { + if (method == CompositeMethod::SubtractMask) method = CompositeMethod::InvAlphaMask; + else if (method == CompositeMethod::AddMask) method = CompositeMethod::AlphaMask; + else if (method == CompositeMethod::IntersectMask) method = CompositeMethod::AlphaMask; + else if (method == CompositeMethod::DifferenceMask) method = CompositeMethod::AlphaMask; //does this correct? + layer->scene->composite(cast(shape), method); + } + pmethod = mask->method; + pmask = shape; + } +} + + +static bool _updateMatte(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps) +{ + auto target = layer->matte.target; + if (!target) return true; + + _updateLayer(root, target, frameNo, exps); + + if (target->scene) { + layer->scene->composite(cast(target->scene), layer->matte.type); + } else if (layer->matte.type == CompositeMethod::AlphaMask || layer->matte.type == CompositeMethod::LumaMask) { + //matte target is not exist. alpha blending definitely bring an invisible result + delete(layer->scene); + layer->scene = nullptr; + return false; + } + return true; +} + + +static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps) +{ + layer->scene = nullptr; + + //visibility + if (frameNo < layer->inFrame || frameNo >= layer->outFrame) return; + + _updateTransform(layer, frameNo, exps); + + //full transparent scene. no need to perform + if (layer->type != LottieLayer::Null && layer->cache.opacity == 0) return; + + //Prepare render data + layer->scene = Scene::gen().release(); + + //ignore opacity when Null layer? + if (layer->type != LottieLayer::Null) layer->scene->opacity(layer->cache.opacity); + + layer->scene->transform(layer->cache.matrix); + + if (layer->matte.target && layer->masks.count > 0) TVGERR("LOTTIE", "FIXME: Matte + Masking??"); + + if (!_updateMatte(root, layer, frameNo, exps)) return; + + _updateMaskings(layer, frameNo, exps); + + switch (layer->type) { + case LottieLayer::Precomp: { + _updatePrecomp(layer, frameNo, exps); + break; + } + case LottieLayer::Solid: { + _updateSolid(layer); + break; + } + default: { + if (!layer->children.empty()) { + Inlist contexts; + contexts.back(new RenderContext); + _updateChildren(layer, frameNo, contexts, exps); + contexts.free(); + } + break; + } + } + + layer->scene->blend(layer->blendMethod); + + //the given matte source was composited by the target earlier. + if (!layer->matteSrc) root->scene->push(cast(layer->scene)); +} + + +static void _buildReference(LottieComposition* comp, LottieLayer* layer) +{ + for (auto asset = comp->assets.begin(); asset < comp->assets.end(); ++asset) { + if (strcmp(layer->refId, (*asset)->name)) continue; + if (layer->type == LottieLayer::Precomp) { + auto assetLayer = static_cast(*asset); + if (_buildComposition(comp, assetLayer)) { + layer->children = assetLayer->children; + layer->reqFragment = assetLayer->reqFragment; + } + } else if (layer->type == LottieLayer::Image) { + layer->children.push(*asset); + } + break; + } +} + + +static void _buildHierarchy(LottieGroup* parent, LottieLayer* child) +{ + if (child->pid == -1) return; + + if (child->matte.target && child->pid == child->matte.target->id) { + child->parent = child->matte.target; + return; + } + + for (auto p = parent->children.begin(); p < parent->children.end(); ++p) { + auto parent = static_cast(*p); + if (child == parent) continue; + if (child->pid == parent->id) { + child->parent = parent; + break; + } + if (parent->matte.target && parent->matte.target->id == child->pid) { + child->parent = parent->matte.target; + break; + } + } +} + + +static void _attachFont(LottieComposition* comp, LottieLayer* parent) +{ + //TODO: Consider to migrate this attachment to the frame update time. + for (auto c = parent->children.begin(); c < parent->children.end(); ++c) { + auto text = static_cast(*c); + auto& doc = text->doc(0); + if (!doc.name) continue; + auto len = strlen(doc.name); + for (uint32_t i = 0; i < comp->fonts.count; ++i) { + auto font = comp->fonts[i]; + auto len2 = strlen(font->name); + if (!strncmp(font->name, doc.name, len < len2 ? len : len2)) { + text->font = font; + break; + } + } + } +} + + +static bool _buildComposition(LottieComposition* comp, LottieGroup* parent) +{ + if (parent->children.count == 0) return false; + if (parent->buildDone) return true; + parent->buildDone = true; + + for (auto c = parent->children.begin(); c < parent->children.end(); ++c) { + auto child = static_cast(*c); + + //attach the precomp layer. + if (child->refId) _buildReference(comp, child); + + if (child->matte.target) { + //parenting + _buildHierarchy(parent, child->matte.target); + //precomp referencing + if (child->matte.target->refId) _buildReference(comp, child->matte.target); + } + _buildHierarchy(parent, child); + + //attach the necessary font data + if (child->type == LottieLayer::Text) _attachFont(comp, child); + } + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +bool LottieBuilder::update(LottieComposition* comp, float frameNo) +{ + if (comp->root->children.empty()) return false; + + frameNo += comp->startFrame; + if (frameNo < comp->startFrame) frameNo = comp->startFrame; + if (frameNo >= comp->endFrame) frameNo = (comp->endFrame - 1); + + //update children layers + auto root = comp->root; + root->scene->clear(); + + if (exps && comp->expressions) exps->update(comp->timeAtFrame(frameNo)); + + for (auto child = root->children.end() - 1; child >= root->children.begin(); --child) { + _updateLayer(root, static_cast(*child), frameNo, exps); + } + + return true; +} + + +void LottieBuilder::build(LottieComposition* comp) +{ + if (!comp) return; + + comp->root->scene = Scene::gen().release(); + if (!comp->root->scene) return; + + _buildComposition(comp, comp->root); + + if (!update(comp, 0)) return; + + //viewport clip + auto clip = Shape::gen(); + clip->appendRect(0, 0, static_cast(comp->w), static_cast(comp->h)); + comp->root->scene->composite(std::move(clip), CompositeMethod::ClipPath); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieBuilder.h b/test/include/liblvgl/libs/thorvg/tvgLottieBuilder.h new file mode 100644 index 00000000..690fa85a --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieBuilder.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL +#ifndef _TVG_LOTTIE_BUILDER_H_ +#define _TVG_LOTTIE_BUILDER_H_ + +#include "tvgCommon.h" +#include "tvgLottieExpressions.h" + +struct LottieComposition; + +struct LottieBuilder +{ + LottieExpressions* exps = nullptr; + + LottieBuilder() + { + exps = LottieExpressions::instance(); + } + + ~LottieBuilder() + { + LottieExpressions::retrieve(exps); + } + + bool update(LottieComposition* comp, float progress); + void build(LottieComposition* comp); +}; + +#endif //_TVG_LOTTIE_BUILDER_H + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieExpressions.cpp b/test/include/liblvgl/libs/thorvg/tvgLottieExpressions.cpp new file mode 100644 index 00000000..aa6c9b13 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieExpressions.cpp @@ -0,0 +1,1298 @@ +/* + * Copyright (c) 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" +#include "tvgLottieModel.h" +#include "tvgLottieExpressions.h" + +#ifdef THORVG_LOTTIE_EXPRESSIONS_SUPPORT + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct ExpContent +{ + LottieObject* obj; + float frameNo; +}; + + +//reserved expressions specifiers +static const char* EXP_NAME = "name"; +static const char* EXP_CONTENT = "content"; +static const char* EXP_WIDTH = "width"; +static const char* EXP_HEIGHT = "height"; +static const char* EXP_CYCLE = "cycle"; +static const char* EXP_PINGPONG = "pingpong"; +static const char* EXP_OFFSET = "offset"; +static const char* EXP_CONTINUE = "continue"; +static const char* EXP_TIME = "time"; +static const char* EXP_VALUE = "value"; +static const char* EXP_INDEX = "index"; +static const char* EXP_EFFECT= "effect"; + +static LottieExpressions* exps = nullptr; //singleton instance engine + + +static void contentFree(void *native_p, struct jerry_object_native_info_t *info_p) +{ + free(native_p); +} + +static jerry_object_native_info_t freeCb {contentFree, 0, 0}; +static uint32_t engineRefCnt = 0; //Expressions Engine reference count + + +static char* _name(jerry_value_t args) +{ + auto arg0 = jerry_value_to_string(args); + auto len = jerry_string_length(arg0); + auto name = (jerry_char_t*)malloc(len * sizeof(jerry_char_t) + 1); + jerry_string_to_buffer(arg0, JERRY_ENCODING_UTF8, name, len); + name[len] = '\0'; + jerry_value_free(arg0); + return (char*) name; +} + + +static jerry_value_t _toComp(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + TVGERR("LOTTIE", "toComp is not supported in expressions!"); + + return jerry_undefined(); +} + + +static void _buildTransform(jerry_value_t context, LottieTransform* transform) +{ + if (!transform) return; + + auto obj = jerry_object(); + jerry_object_set_sz(context, "transform", obj); + + auto anchorPoint = jerry_object(); + jerry_object_set_native_ptr(anchorPoint, nullptr, &transform->anchor); + jerry_object_set_sz(obj, "anchorPoint", anchorPoint); + jerry_value_free(anchorPoint); + + auto position = jerry_object(); + jerry_object_set_native_ptr(position, nullptr, &transform->position); + jerry_object_set_sz(obj, "position", position); + jerry_value_free(position); + + auto scale = jerry_object(); + jerry_object_set_native_ptr(scale, nullptr, &transform->scale); + jerry_object_set_sz(obj, "scale", scale); + jerry_value_free(scale); + + auto rotation = jerry_object(); + jerry_object_set_native_ptr(rotation, nullptr, &transform->rotation); + jerry_object_set_sz(obj, "rotation", rotation); + jerry_value_free(rotation); + + auto opacity = jerry_object(); + jerry_object_set_native_ptr(opacity, nullptr, &transform->opacity); + jerry_object_set_sz(obj, "opacity", opacity); + jerry_value_free(opacity); + + jerry_value_free(obj); +} + + +static void _buildLayer(jerry_value_t context, LottieLayer* layer, LottieComposition* comp) +{ + auto width = jerry_number(layer->w); + jerry_object_set_sz(context, EXP_WIDTH, width); + jerry_value_free(width); + + auto height = jerry_number(layer->h); + jerry_object_set_sz(context, EXP_HEIGHT, height); + jerry_value_free(height); + + auto index = jerry_number(layer->id); + jerry_object_set_sz(context, EXP_INDEX, index); + jerry_value_free(index); + + auto parent = jerry_object(); + jerry_object_set_native_ptr(parent, nullptr, layer->parent); + jerry_object_set_sz(context, "parent", parent); + jerry_value_free(parent); + + auto hasParent = jerry_boolean(layer->parent ? true : false); + jerry_object_set_sz(context, "hasParent", hasParent); + jerry_value_free(hasParent); + + auto inPoint = jerry_number(layer->inFrame); + jerry_object_set_sz(context, "inPoint", inPoint); + jerry_value_free(inPoint); + + auto outPoint = jerry_number(layer->outFrame); + jerry_object_set_sz(context, "outPoint", outPoint); + jerry_value_free(outPoint); + + auto startTime = jerry_number(comp->timeAtFrame(layer->startFrame)); + jerry_object_set_sz(context, "startTime", startTime); + jerry_value_free(startTime); + + auto hasVideo = jerry_boolean(false); + jerry_object_set_sz(context, "hasVideo", hasVideo); + jerry_value_free(hasVideo); + + auto hasAudio = jerry_boolean(false); + jerry_object_set_sz(context, "hasAudio", hasAudio); + jerry_value_free(hasAudio); + + //active, #current in the animation range? + + auto enabled = jerry_boolean(!layer->hidden); + jerry_object_set_sz(context, "enabled", enabled); + jerry_value_free(enabled); + + auto audioActive = jerry_boolean(false); + jerry_object_set_sz(context, "audioActive", audioActive); + jerry_value_free(audioActive); + + //sampleImage(point, radius = [.5, .5], postEffect=true, t=time) + + _buildTransform(context, layer->transform); + + //audioLevels, #the value of the Audio Levels property of the layer in decibels + + auto timeRemap = jerry_object(); + jerry_object_set_native_ptr(timeRemap, nullptr, &layer->timeRemap); + jerry_object_set_sz(context, "timeRemap", timeRemap); + jerry_value_free(timeRemap); + + //marker.key(index) + //marker.key(name) + //marker.nearestKey(t) + //marker.numKeys + + auto name = jerry_string_sz(layer->name); + jerry_object_set_sz(context, EXP_NAME, name); + jerry_value_free(name); + + auto toComp = jerry_function_external(_toComp); + jerry_object_set_sz(context, "toComp", toComp); + jerry_object_set_native_ptr(toComp, nullptr, comp); + jerry_value_free(toComp); +} + + +static jerry_value_t _value(float frameNo, LottieExpression* exp) +{ + switch (exp->type) { + case LottieProperty::Type::Point: { + auto value = jerry_object(); + auto pos = (*static_cast(exp->property))(frameNo); + auto val1 = jerry_number(pos.x); + auto val2 = jerry_number(pos.y); + jerry_object_set_index(value, 0, val1); + jerry_object_set_index(value, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + return value; + } + case LottieProperty::Type::Float: { + return jerry_number((*static_cast(exp->property))(frameNo)); + } + case LottieProperty::Type::Opacity: { + return jerry_number((*static_cast(exp->property))(frameNo)); + } + case LottieProperty::Type::PathSet: { + auto value = jerry_object(); + jerry_object_set_native_ptr(value, nullptr, exp->property); + return value; + } + case LottieProperty::Type::Position: { + auto value = jerry_object(); + auto pos = (*static_cast(exp->property))(frameNo); + auto val1 = jerry_number(pos.x); + auto val2 = jerry_number(pos.y); + jerry_object_set_index(value, 0, val1); + jerry_object_set_index(value, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + return value; + } + default: { + TVGERR("LOTTIE", "Non supported type for value? = %d", (int) exp->type); + } + } + return jerry_undefined(); +} + + +static jerry_value_t _addsub(const jerry_value_t args[], float addsub) +{ + //1d + if (jerry_value_is_number(args[0])) return jerry_number(jerry_value_as_number(args[0]) + addsub * jerry_value_as_number(args[1])); + + //2d + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto val3 = jerry_object_get_index(args[1], 0); + auto val4 = jerry_object_get_index(args[1], 1); + auto x = jerry_value_as_number(val1) + addsub * jerry_value_as_number(val3); + auto y = jerry_value_as_number(val2) + addsub * jerry_value_as_number(val4); + + jerry_value_free(val1); + jerry_value_free(val2); + jerry_value_free(val3); + jerry_value_free(val4); + + auto obj = jerry_object(); + val1 = jerry_number(x); + val2 = jerry_number(y); + jerry_object_set_index(obj, 0, val1); + jerry_object_set_index(obj, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + + return obj; +} + + +static jerry_value_t _muldiv(const jerry_value_t arg1, float arg2) +{ + //1d + if (jerry_value_is_number(arg1)) return jerry_number(jerry_value_as_number(arg1) * arg2); + + //2d + auto val1 = jerry_object_get_index(arg1, 0); + auto val2 = jerry_object_get_index(arg1, 1); + auto x = jerry_value_as_number(val1) * arg2; + auto y = jerry_value_as_number(val2) * arg2; + + jerry_value_free(val1); + jerry_value_free(val2); + + auto obj = jerry_object(); + val1 = jerry_number(x); + val2 = jerry_number(y); + jerry_object_set_index(obj, 0, val1); + jerry_object_set_index(obj, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + + return obj; +} + + +static jerry_value_t _add(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return _addsub(args, 1.0f); +} + + +static jerry_value_t _sub(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return _addsub(args, -1.0f); +} + + +static jerry_value_t _mul(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return _muldiv(args[0], jerry_value_as_number(args[1])); +} + + +static jerry_value_t _div(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return _muldiv(args[0], 1.0f / jerry_value_as_number(args[1])); +} + + +static jerry_value_t _interp(float t, const jerry_value_t args[], int argsCnt) +{ + auto tMin = 0.0f; + auto tMax = 1.0f; + int idx = 0; + + if (argsCnt > 3) { + tMin = jerry_value_as_number(args[1]); + tMax = jerry_value_as_number(args[2]); + idx += 2; + } + + //2d + if (jerry_value_is_object(args[idx + 1]) && jerry_value_is_object(args[idx + 2])) { + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto val3 = jerry_object_get_index(args[1], 0); + auto val4 = jerry_object_get_index(args[1], 1); + + Point pt1 = {(float)jerry_value_as_number(val1), (float)jerry_value_as_number(val2)}; + Point pt2 = {(float)jerry_value_as_number(val3), (float)jerry_value_as_number(val4)}; + Point ret; + if (t <= tMin) ret = pt1; + else if (t >= tMax) ret = pt2; + else ret = mathLerp(pt1, pt2, t); + + jerry_value_free(val1); + jerry_value_free(val2); + jerry_value_free(val3); + jerry_value_free(val4); + + auto obj = jerry_object(); + val1 = jerry_number(ret.x); + val2 = jerry_number(ret.y); + jerry_object_set_index(obj, 0, val1); + jerry_object_set_index(obj, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + + return obj; + } + + //1d + auto val1 = (float) jerry_value_as_number(args[idx + 1]); + if (t <= tMin) jerry_number(val1); + auto val2 = (float) jerry_value_as_number(args[idx + 2]); + if (t >= tMax) jerry_number(val2); + return jerry_number(mathLerp(val1, val2, t)); +} + + +static jerry_value_t _linear(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto t = (float) jerry_value_as_number(args[0]); + return _interp(t, args, jerry_value_as_uint32(argsCnt)); +} + + +static jerry_value_t _ease(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto t = (float) jerry_value_as_number(args[0]); + t = (t < 0.5) ? (4 * t * t * t) : (1.0f - pow(-2.0f * t + 2.0f, 3) * 0.5f); + return _interp(t, args, jerry_value_as_uint32(argsCnt)); +} + + + +static jerry_value_t _easeIn(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto t = (float) jerry_value_as_number(args[0]); + t = t * t * t; + return _interp(t, args, jerry_value_as_uint32(argsCnt)); +} + + +static jerry_value_t _easeOut(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto t = (float) jerry_value_as_number(args[0]); + t = 1.0f - pow(1.0f - t, 3); + return _interp(t, args, jerry_value_as_uint32(argsCnt)); +} + + +static jerry_value_t _clamp(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto num = jerry_value_as_number(args[0]); + auto limit1 = jerry_value_as_number(args[1]); + auto limit2 = jerry_value_as_number(args[2]); + + //clamping + if (num < limit1) num = limit1; + if (num > limit2) num = limit2; + + return jerry_number(num); +} + + +static jerry_value_t _dot(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto val3 = jerry_object_get_index(args[1], 0); + auto val4 = jerry_object_get_index(args[1], 1); + + auto x = jerry_value_as_number(val1) * jerry_value_as_number(val3); + auto y = jerry_value_as_number(val2) * jerry_value_as_number(val4); + + jerry_value_free(val1); + jerry_value_free(val2); + jerry_value_free(val3); + jerry_value_free(val4); + + return jerry_number(x + y); +} + + +static jerry_value_t _cross(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto val3 = jerry_object_get_index(args[1], 0); + auto val4 = jerry_object_get_index(args[1], 1); + + auto x = jerry_value_as_number(val1) * jerry_value_as_number(val4); + auto y = jerry_value_as_number(val2) * jerry_value_as_number(val3); + + jerry_value_free(val1); + jerry_value_free(val2); + jerry_value_free(val3); + jerry_value_free(val4); + + return jerry_number(x - y); +} + + +static jerry_value_t _normalize(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto x = jerry_value_as_number(val1); + auto y = jerry_value_as_number(val2); + + jerry_value_free(val1); + jerry_value_free(val2); + + auto length = sqrtf(x * x + y * y); + + x /= length; + y /= length; + + auto obj = jerry_object(); + val1 = jerry_number(x); + val2 = jerry_number(y); + jerry_object_set_index(obj, 0, val1); + jerry_object_set_index(obj, 0, val2); + jerry_value_free(val1); + jerry_value_free(val2); + + return obj; +} + + +static jerry_value_t _length(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto x = jerry_value_as_number(val1); + auto y = jerry_value_as_number(val2); + + jerry_value_free(val1); + jerry_value_free(val2); + + return jerry_number(sqrtf(x * x + y * y)); +} + + +static jerry_value_t _random(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto val = (float)(rand() % 10000001); + return jerry_number(val * 0.0000001f); +} + + +static jerry_value_t _deg2rad(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return jerry_number(mathDeg2Rad((float)jerry_value_as_number(args[0]))); +} + + +static jerry_value_t _rad2deg(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return jerry_number(mathRad2Deg((float)jerry_value_as_number(args[0]))); +} + + +static jerry_value_t _effect(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + TVGERR("LOTTIE", "effect is not supported in expressions!"); + + return jerry_undefined(); +} + + +static jerry_value_t _fromCompToSurface(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + TVGERR("LOTTIE", "fromCompToSurface is not supported in expressions!"); + + return jerry_undefined(); +} + + +static jerry_value_t _content(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto name = _name(args[0]); + auto data = static_cast(jerry_object_get_native_ptr(info->function, &freeCb)); + auto group = static_cast(data->obj); + auto target = group->content((char*)name); + free(name); + if (!target) return jerry_undefined(); + + //find the a path property(sh) in the group layer? + switch (target->type) { + case LottieObject::Group: { + auto group = static_cast(target); + auto obj = jerry_function_external(_content); + + //attach a transform + for (auto c = group->children.begin(); c < group->children.end(); ++c) { + if ((*c)->type == LottieObject::Type::Transform) { + _buildTransform(obj, static_cast(*c)); + break; + } + } + auto data2 = (ExpContent*)malloc(sizeof(ExpContent)); + data2->obj = group; + data2->frameNo = data->frameNo; + jerry_object_set_native_ptr(obj, &freeCb, data2); + jerry_object_set_sz(obj, EXP_CONTENT, obj); + return obj; + } + case LottieObject::Path: { + jerry_value_t obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, &static_cast(target)->pathset); + jerry_object_set_sz(obj, "path", obj); + return obj; + } + case LottieObject::Trimpath: { + auto trimpath = static_cast(target); + jerry_value_t obj = jerry_object(); + auto start = jerry_number(trimpath->start(data->frameNo)); + jerry_object_set_sz(obj, "start", start); + jerry_value_free(start); + auto end = jerry_number(trimpath->end(data->frameNo)); + jerry_object_set_sz(obj, "end", end); + jerry_value_free(end); + auto offset = jerry_number(trimpath->offset(data->frameNo)); + jerry_object_set_sz(obj, "offset", end); + jerry_value_free(offset); + return obj; + } + default: break; + } + return jerry_undefined(); +} + + +static jerry_value_t _layer(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto comp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + LottieLayer* layer; + + //layer index + if (jerry_value_is_number(args[0])) { + auto idx = (uint16_t)jerry_value_as_int32(args[0]); + layer = comp->layer(idx); + jerry_value_free(idx); + //layer name + } else { + auto name = _name(args[0]); + layer = comp->layer((char*)name); + free(name); + } + + if (!layer) return jerry_undefined(); + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, layer); + _buildLayer(obj, layer, comp); + + return obj; +} + + +static jerry_value_t _nearestKey(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + auto time = jerry_value_as_number(args[0]); + auto frameNo = exp->comp->frameAtTime(time); + auto index = jerry_number(exp->property->nearest(frameNo)); + + auto obj = jerry_object(); + jerry_object_set_sz(obj, EXP_INDEX, index); + jerry_value_free(index); + + return obj; +} + + +static jerry_value_t _valueAtTime(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + auto time = jerry_value_as_number(args[0]); + auto frameNo = exp->comp->frameAtTime(time); + return _value(frameNo, exp); +} + + +static jerry_value_t _velocityAtTime(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + auto time = jerry_value_as_number(args[0]); + auto frameNo = exp->comp->frameAtTime(time); + auto key = exp->property->nearest(frameNo); + auto pframe = exp->property->frameNo(key - 1); + auto cframe = exp->property->frameNo(key); + auto elapsed = (cframe - pframe) / (exp->comp->frameRate); + + Point cur, prv; + + //compute the velocity + switch (exp->type) { + case LottieProperty::Type::Point: { + prv = (*static_cast(exp->property))(pframe); + cur = (*static_cast(exp->property))(cframe); + break; + } + case LottieProperty::Type::Position: { + prv = (*static_cast(exp->property))(pframe); + cur = (*static_cast(exp->property))(cframe); + break; + } + default: { + TVGERR("LOTTIE", "Non supported type for velocityAtTime?"); + return jerry_undefined(); + } + } + + float velocity[] = {(cur.x - prv.x) / elapsed, (cur.y - prv.y) / elapsed}; + + auto obj = jerry_object(); + auto val1 = jerry_number(velocity[0]); + auto val2 = jerry_number(velocity[1]); + jerry_object_set_index(obj, 0, val1); + jerry_object_set_index(obj, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + + return obj; +} + + +static jerry_value_t _speedAtTime(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + auto time = jerry_value_as_number(args[0]); + auto frameNo = exp->comp->frameAtTime(time); + auto key = exp->property->nearest(frameNo); + auto pframe = exp->property->frameNo(key - 1); + auto cframe = exp->property->frameNo(key); + auto elapsed = (cframe - pframe) / (exp->comp->frameRate); + + Point cur, prv; + + //compute the velocity + switch (exp->type) { + case LottieProperty::Type::Point: { + prv = (*static_cast(exp->property))(pframe); + cur = (*static_cast(exp->property))(cframe); + break; + } + case LottieProperty::Type::Position: { + prv = (*static_cast(exp->property))(pframe); + cur = (*static_cast(exp->property))(cframe); + break; + } + default: { + TVGERR("LOTTIE", "Non supported type for speedAtTime?"); + return jerry_undefined(); + } + } + + auto speed = sqrtf(pow(cur.x - prv.x, 2) + pow(cur.y - prv.y, 2)) / elapsed; + auto obj = jerry_number(speed); + return obj; +} + + +static bool _loopOutCommon(LottieExpression* exp, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + exp->loop.mode = LottieExpression::LoopMode::OutCycle; + + if (argsCnt > 0) { + auto name = _name(args[0]); + if (!strcmp(name, EXP_CYCLE)) exp->loop.mode = LottieExpression::LoopMode::OutCycle; + else if (!strcmp(name, EXP_PINGPONG)) exp->loop.mode = LottieExpression::LoopMode::OutPingPong; + else if (!strcmp(name, EXP_OFFSET)) exp->loop.mode = LottieExpression::LoopMode::OutOffset; + else if (!strcmp(name, EXP_CONTINUE)) exp->loop.mode = LottieExpression::LoopMode::OutContinue; + free(name); + } + + if (exp->loop.mode != LottieExpression::LoopMode::OutCycle) { + TVGERR("hermet", "Not supported loopOut type = %d", exp->loop.mode); + return false; + } + + return true; +} + + +static jerry_value_t _loopOut(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + + if (!_loopOutCommon(exp, args, argsCnt)) return jerry_undefined(); + + if (argsCnt > 1) exp->loop.key = jerry_value_as_int32(args[1]); + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, exp->property); + return obj; +} + + +static jerry_value_t _loopOutDuration(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + + if (!_loopOutCommon(exp, args, argsCnt)) return jerry_undefined(); + + if (argsCnt > 1) { + exp->loop.in = exp->comp->frameAtTime((float)jerry_value_as_int32(args[1])); + } + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, exp->property); + return obj; +} + + +static bool _loopInCommon(LottieExpression* exp, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + exp->loop.mode = LottieExpression::LoopMode::InCycle; + + if (argsCnt > 0) { + auto name = _name(args[0]); + if (!strcmp(name, EXP_CYCLE)) exp->loop.mode = LottieExpression::LoopMode::InCycle; + else if (!strcmp(name, EXP_PINGPONG)) exp->loop.mode = LottieExpression::LoopMode::InPingPong; + else if (!strcmp(name, EXP_OFFSET)) exp->loop.mode = LottieExpression::LoopMode::InOffset; + else if (!strcmp(name, EXP_CONTINUE)) exp->loop.mode = LottieExpression::LoopMode::InContinue; + free(name); + } + + if (exp->loop.mode != LottieExpression::LoopMode::InCycle) { + TVGERR("hermet", "Not supported loopOut type = %d", exp->loop.mode); + return false; + } + + return true; +} + +static jerry_value_t _loopIn(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + + if (!_loopInCommon(exp, args, argsCnt)) return jerry_undefined(); + + if (argsCnt > 1) { + exp->loop.in = exp->comp->frameAtTime((float)jerry_value_as_int32(args[1])); + } + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, exp->property); + return obj; +} + + +static jerry_value_t _loopInDuration(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + + if (argsCnt > 1) { + exp->loop.in = exp->comp->frameAtTime((float)jerry_value_as_int32(args[1])); + } + + if (!_loopInCommon(exp, args, argsCnt)) return jerry_undefined(); + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, exp->property); + return obj; +} + + +static jerry_value_t _key(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + auto key = jerry_value_as_int32(args[0]); + auto frameNo = exp->property->frameNo(key); + auto time = jerry_number(exp->comp->timeAtFrame(frameNo)); + auto value = _value(frameNo, exp); + + auto obj = jerry_object(); + jerry_object_set_sz(obj, EXP_TIME, time); + jerry_object_set_sz(obj, EXP_INDEX, args[0]); + jerry_object_set_sz(obj, EXP_VALUE, value); + + jerry_value_free(time); + jerry_value_free(value); + + return obj; +} + + + +static jerry_value_t _createPath(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + //TODO: arg1: points, arg2: inTangents, arg3: outTangents, arg4: isClosed + auto arg1 = jerry_value_to_object(args[0]); + auto pathset = jerry_object_get_native_ptr(arg1, nullptr); + if (!pathset) { + TVGERR("LOTTIE", "failed createPath()"); + return jerry_undefined(); + } + + jerry_value_free(arg1); + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, pathset); + return obj; +} + + +static jerry_value_t _uniformPath(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto pathset = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + + /* TODO: ThorVG prebuilds the path data for performance. + It actually need to constructs the Array for points, inTangents, outTangents and then return here... */ + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, pathset); + return obj; +} + + +static jerry_value_t _isClosed(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + //TODO: Not used + return jerry_boolean(true); +} + + +static void _buildPath(jerry_value_t context, LottieExpression* exp) +{ + //Trick for fast building path. + auto points = jerry_function_external(_uniformPath); + jerry_object_set_native_ptr(points, nullptr, exp->property); + jerry_object_set_sz(context, "points", points); + jerry_value_free(points); + + auto inTangents = jerry_function_external(_uniformPath); + jerry_object_set_native_ptr(inTangents, nullptr, exp->property); + jerry_object_set_sz(context, "inTangents", inTangents); + jerry_value_free(inTangents); + + auto outTangents = jerry_function_external(_uniformPath); + jerry_object_set_native_ptr(outTangents, nullptr, exp->property); + jerry_object_set_sz(context, "outTangents", outTangents); + jerry_value_free(outTangents); + + auto isClosed = jerry_function_external(_isClosed); + jerry_object_set_native_ptr(isClosed, nullptr, exp->property); + jerry_object_set_sz(context, "isClosed", isClosed); + jerry_value_free(isClosed); + +} + + +static void _buildProperty(float frameNo, jerry_value_t context, LottieExpression* exp) +{ + auto value = _value(frameNo, exp); + jerry_object_set_sz(context, EXP_VALUE, value); + jerry_value_free(value); + + auto valueAtTime = jerry_function_external(_valueAtTime); + jerry_object_set_sz(context, "valueAtTime", valueAtTime); + jerry_object_set_native_ptr(valueAtTime, nullptr, exp); + jerry_value_free(valueAtTime); + + auto velocity = jerry_number(0.0f); + jerry_object_set_sz(context, "velocity", velocity); + jerry_value_free(velocity); + + auto velocityAtTime = jerry_function_external(_velocityAtTime); + jerry_object_set_sz(context, "velocityAtTime", velocityAtTime); + jerry_object_set_native_ptr(velocityAtTime, nullptr, exp); + jerry_value_free(velocityAtTime); + + auto speed = jerry_number(0.0f); + jerry_object_set_sz(context, "speed", speed); + jerry_value_free(speed); + + auto speedAtTime = jerry_function_external(_speedAtTime); + jerry_object_set_sz(context, "speedAtTime", speedAtTime); + jerry_object_set_native_ptr(speedAtTime, nullptr, exp); + jerry_value_free(speedAtTime); + + //wiggle(freq, amp, octaves=1, amp_mult=.5, t=time) + //temporalWiggle(freq, amp, octaves=1, amp_mult=.5, t=time) + //smooth(width=.2, samples=5, t=time) + + auto loopIn = jerry_function_external(_loopIn); + jerry_object_set_sz(context, "loopIn", loopIn); + jerry_object_set_native_ptr(loopIn, nullptr, exp); + jerry_value_free(loopIn); + + auto loopOut = jerry_function_external(_loopOut); + jerry_object_set_sz(context, "loopOut", loopOut); + jerry_object_set_native_ptr(loopOut, nullptr, exp); + jerry_value_free(loopOut); + + auto loopInDuration = jerry_function_external(_loopInDuration); + jerry_object_set_sz(context, "loopInDuration", loopInDuration); + jerry_object_set_native_ptr(loopInDuration, nullptr, exp); + jerry_value_free(loopInDuration); + + auto loopOutDuration = jerry_function_external(_loopOutDuration); + jerry_object_set_sz(context, "loopOutDuration", loopOutDuration); + jerry_object_set_native_ptr(loopOutDuration, nullptr, exp); + jerry_value_free(loopOutDuration); + + auto key = jerry_function_external(_key); + jerry_object_set_sz(context, "key", key); + jerry_object_set_native_ptr(key, nullptr, exp); + jerry_value_free(key); + + //key(markerName) + + auto nearestKey = jerry_function_external(_nearestKey); + jerry_object_set_native_ptr(nearestKey, nullptr, exp); + jerry_object_set_sz(context, "nearestKey", nearestKey); + jerry_value_free(nearestKey); + + auto numKeys = jerry_number(exp->property->frameCnt()); + jerry_object_set_sz(context, "numKeys", numKeys); + jerry_value_free(numKeys); + + //propertyGroup(countUp = 1) + //propertyIndex + //name + + //content("name"), #look for the named property from a layer + auto data = (ExpContent*)malloc(sizeof(ExpContent)); + data->obj = exp->layer; + data->frameNo = frameNo; + + auto content = jerry_function_external(_content); + jerry_object_set_sz(context, EXP_CONTENT, content); + jerry_object_set_native_ptr(content, &freeCb, data); + jerry_value_free(content); +} + + +static jerry_value_t _comp(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto comp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + LottieLayer* layer; + + auto arg0 = jerry_value_to_string(args[0]); + auto len = jerry_string_length(arg0); + auto name = (jerry_char_t*)alloca(len * sizeof(jerry_char_t) + 1); + jerry_string_to_buffer(arg0, JERRY_ENCODING_UTF8, name, len); + name[len] = '\0'; + + jerry_value_free(arg0); + + layer = comp->asset((char*)name); + + if (!layer) return jerry_undefined(); + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, layer); + _buildLayer(obj, layer, comp); + + return obj; +} + + +static void _buildMath(jerry_value_t context) +{ + auto bm_mul = jerry_function_external(_mul); + jerry_object_set_sz(context, "$bm_mul", bm_mul); + jerry_value_free(bm_mul); + + auto bm_sum = jerry_function_external(_add); + jerry_object_set_sz(context, "$bm_sum", bm_sum); + jerry_value_free(bm_sum); + + auto bm_add = jerry_function_external(_add); + jerry_object_set_sz(context, "$bm_add", bm_add); + jerry_value_free(bm_add); + + auto bm_sub = jerry_function_external(_sub); + jerry_object_set_sz(context, "$bm_sub", bm_sub); + jerry_value_free(bm_sub); + + auto bm_div = jerry_function_external(_div); + jerry_object_set_sz(context, "$bm_div", bm_div); + jerry_value_free(bm_div); + + auto mul = jerry_function_external(_mul); + jerry_object_set_sz(context, "mul", mul); + jerry_value_free(mul); + + auto sum = jerry_function_external(_add); + jerry_object_set_sz(context, "sum", sum); + jerry_value_free(sum); + + auto add = jerry_function_external(_add); + jerry_object_set_sz(context, "add", add); + jerry_value_free(add); + + auto sub = jerry_function_external(_sub); + jerry_object_set_sz(context, "sub", sub); + jerry_value_free(sub); + + auto div = jerry_function_external(_div); + jerry_object_set_sz(context, "div", div); + jerry_value_free(div); + + auto clamp = jerry_function_external(_clamp); + jerry_object_set_sz(context, "clamp", clamp); + jerry_value_free(clamp); + + auto dot = jerry_function_external(_dot); + jerry_object_set_sz(context, "dot", dot); + jerry_value_free(dot); + + auto cross = jerry_function_external(_cross); + jerry_object_set_sz(context, "cross", cross); + jerry_value_free(cross); + + auto normalize = jerry_function_external(_normalize); + jerry_object_set_sz(context, "normalize", normalize); + jerry_value_free(normalize); + + auto length = jerry_function_external(_length); + jerry_object_set_sz(context, "length", length); + jerry_value_free(length); + + auto random = jerry_function_external(_random); + jerry_object_set_sz(context, "random", random); + jerry_value_free(random); + + auto deg2rad = jerry_function_external(_deg2rad); + jerry_object_set_sz(context, "degreesToRadians", deg2rad); + jerry_value_free(deg2rad); + + auto rad2deg = jerry_function_external(_rad2deg); + jerry_object_set_sz(context, "radiansToDegrees", rad2deg); + jerry_value_free(rad2deg); + + auto linear = jerry_function_external(_linear); + jerry_object_set_sz(context, "linear", linear); + jerry_value_free(linear); + + auto ease = jerry_function_external(_ease); + jerry_object_set_sz(context, "ease", ease); + jerry_value_free(ease); + + auto easeIn = jerry_function_external(_easeIn); + jerry_object_set_sz(context, "easeIn", easeIn); + jerry_value_free(easeIn); + + auto easeOut = jerry_function_external(_easeOut); + jerry_object_set_sz(context, "easeOut", easeOut); + jerry_value_free(easeOut); + + //lookAt +} + + +void LottieExpressions::buildComp(LottieComposition* comp) +{ + jerry_object_set_native_ptr(this->comp, nullptr, comp); + jerry_object_set_native_ptr(thisComp, nullptr, comp); + jerry_object_set_native_ptr(layer, nullptr, comp); + + //marker + //marker.key(index) + //marker.key(name) + //marker.nearestKey(t) + //marker.numKeys + + auto numLayers = jerry_number(comp->root->children.count); + jerry_object_set_sz(thisComp, "numLayers", numLayers); + jerry_value_free(numLayers); + + //activeCamera + + auto width = jerry_number(comp->w); + jerry_object_set_sz(thisComp, EXP_WIDTH, width); + jerry_value_free(width); + + auto height = jerry_number(comp->h); + jerry_object_set_sz(thisComp, EXP_HEIGHT, height); + jerry_value_free(height); + + auto duration = jerry_number(comp->duration()); + jerry_object_set_sz(thisComp, "duration", duration); + jerry_value_free(duration); + + //ntscDropFrame + //displayStartTime + + auto frameDuration = jerry_number(1.0f / comp->frameRate); + jerry_object_set_sz(thisComp, "frameDuration", frameDuration); + jerry_value_free(frameDuration); + + //shutterAngle + //shutterPhase + //bgColor + //pixelAspect + + auto name = jerry_string((jerry_char_t*)comp->name, strlen(comp->name), JERRY_ENCODING_UTF8); + jerry_object_set_sz(thisComp, EXP_NAME, name); + jerry_value_free(name); +} + + +jerry_value_t LottieExpressions::buildGlobal() +{ + global = jerry_current_realm(); + + //comp(name) + comp = jerry_function_external(_comp); + jerry_object_set_sz(global, "comp", comp); + + //footage(name) + + thisComp = jerry_object(); + jerry_object_set_sz(global, "thisComp", thisComp); + + //layer(index) / layer(name) / layer(otherLayer, reIndex) + layer = jerry_function_external(_layer); + jerry_object_set_sz(thisComp, "layer", layer); + + thisLayer = jerry_object(); + jerry_object_set_sz(global, "thisLayer", thisLayer); + + thisProperty = jerry_object(); + jerry_object_set_sz(global, "thisProperty", thisProperty); + + auto effect = jerry_function_external(_effect); + jerry_object_set_sz(global, EXP_EFFECT, effect); + jerry_value_free(effect); + + auto fromCompToSurface = jerry_function_external(_fromCompToSurface); + jerry_object_set_sz(global, "fromCompToSurface", fromCompToSurface); + jerry_value_free(fromCompToSurface); + + auto createPath = jerry_function_external(_createPath); + jerry_object_set_sz(global, "createPath", createPath); + jerry_value_free(createPath); + + //posterizeTime(framesPerSecond) + //value + + return global; +} + + +jerry_value_t LottieExpressions::evaluate(float frameNo, LottieExpression* exp) +{ + buildComp(exp->comp); + + //update global context values + jerry_object_set_native_ptr(thisLayer, nullptr, exp->layer); + _buildLayer(thisLayer, exp->layer, exp->comp); + + jerry_object_set_native_ptr(thisProperty, nullptr, exp->property); + _buildProperty(frameNo, global, exp); + + if (exp->type == LottieProperty::Type::PathSet) _buildPath(thisProperty, exp); + if (exp->object->type == LottieObject::Transform) _buildTransform(global, static_cast(exp->object)); + + //evaluate the code + auto eval = jerry_eval((jerry_char_t *) exp->code, strlen(exp->code), JERRY_PARSE_NO_OPTS); + + if (jerry_value_is_exception(eval) || jerry_value_is_undefined(eval)) { + exp->enabled = false; // The feature is experimental, it will be forcefully turned off if it's incompatible. + return jerry_undefined(); + } + + jerry_value_free(eval); + + return jerry_object_get_sz(global, "$bm_rt"); +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +LottieExpressions::~LottieExpressions() +{ + jerry_value_free(thisProperty); + jerry_value_free(thisLayer); + jerry_value_free(layer); + jerry_value_free(thisComp); + jerry_value_free(comp); + jerry_value_free(global); + jerry_cleanup(); +} + + +LottieExpressions::LottieExpressions() +{ + jerry_init(JERRY_INIT_EMPTY); + _buildMath(buildGlobal()); +} + + +void LottieExpressions::update(float curTime) +{ + //time, #current time in seconds + auto time = jerry_number(curTime); + jerry_object_set_sz(global, EXP_TIME, time); + jerry_value_free(time); +} + + +//FIXME: Threads support +#include "tvgTaskScheduler.h" + +LottieExpressions* LottieExpressions::instance() +{ + //FIXME: Threads support + if (TaskScheduler::threads() > 1) { + TVGLOG("LOTTIE", "Lottie Expressions are not supported with tvg threads"); + return nullptr; + } + + if (!exps) exps = new LottieExpressions; + ++engineRefCnt; + return exps; +} + + +void LottieExpressions::retrieve(LottieExpressions* instance) +{ + if (--engineRefCnt == 0) { + delete(instance); + exps = nullptr; + } +} + + +#endif //THORVG_LOTTIE_EXPRESSIONS_SUPPORT + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieExpressions.h b/test/include/liblvgl/libs/thorvg/tvgLottieExpressions.h new file mode 100644 index 00000000..14819a8f --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieExpressions.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_EXPRESSIONS_H_ +#define _TVG_LOTTIE_EXPRESSIONS_H_ + +#include "tvgCommon.h" + +struct LottieExpression; +struct LottieComposition; +struct RGB24; + +#ifdef THORVG_LOTTIE_EXPRESSIONS_SUPPORT + +#include "jerryscript.h" + + +struct LottieExpressions +{ +public: + template + bool result(float frameNo, NumType& out, LottieExpression* exp) + { + auto bm_rt = evaluate(frameNo, exp); + + if (auto prop = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { + out = (*prop)(frameNo); + } else if (jerry_value_is_number(bm_rt)) { + out = (NumType) jerry_value_as_number(bm_rt); + } else { + TVGERR("LOTTIE", "Failed dispatching a Value!"); + return false; + } + jerry_value_free(bm_rt); + return true; + } + + template + bool result(float frameNo, Point& out, LottieExpression* exp) + { + auto bm_rt = evaluate(frameNo, exp); + + if (jerry_value_is_object(bm_rt)) { + if (auto prop = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { + out = (*prop)(frameNo); + } else { + auto x = jerry_object_get_index(bm_rt, 0); + auto y = jerry_object_get_index(bm_rt, 1); + out.x = jerry_value_as_number(x); + out.y = jerry_value_as_number(y); + jerry_value_free(x); + jerry_value_free(y); + } + } else { + TVGERR("LOTTIE", "Failed dispatching Point!"); + return false; + } + jerry_value_free(bm_rt); + return true; + } + + template + bool result(float frameNo, RGB24& out, LottieExpression* exp) + { + auto bm_rt = evaluate(frameNo, exp); + + if (auto color = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { + out = (*color)(frameNo); + } else { + TVGERR("LOTTIE", "Failed dispatching Color!"); + return false; + } + jerry_value_free(bm_rt); + return true; + } + + template + bool result(float frameNo, Fill* fill, LottieExpression* exp) + { + auto bm_rt = evaluate(frameNo, exp); + + if (auto colorStop = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { + (*colorStop)(frameNo, fill, this); + } else { + TVGERR("LOTTIE", "Failed dispatching ColorStop!"); + return false; + } + jerry_value_free(bm_rt); + return true; + } + + template + bool result(float frameNo, Array& cmds, Array& pts, Matrix* transform, float roundness, LottieExpression* exp) + { + auto bm_rt = evaluate(frameNo, exp); + + if (auto pathset = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { + (*pathset)(frameNo, cmds, pts, transform, roundness); + } else { + TVGERR("LOTTIE", "Failed dispatching PathSet!"); + return false; + } + jerry_value_free(bm_rt); + return true; + } + + void update(float curTime); + + //singleton (no thread safety) + static LottieExpressions* instance(); + static void retrieve(LottieExpressions* instance); + +private: + LottieExpressions(); + ~LottieExpressions(); + + jerry_value_t evaluate(float frameNo, LottieExpression* exp); + jerry_value_t buildGlobal(); + void buildComp(LottieComposition* comp); + + //global object, attributes, methods + jerry_value_t global; + jerry_value_t comp; + jerry_value_t layer; + jerry_value_t thisComp; + jerry_value_t thisLayer; + jerry_value_t thisProperty; +}; + +#else + +struct LottieExpressions +{ + template bool result(TVG_UNUSED float, TVG_UNUSED NumType&, TVG_UNUSED LottieExpression*) { return false; } + template bool result(TVG_UNUSED float, TVG_UNUSED Point&, LottieExpression*) { return false; } + template bool result(TVG_UNUSED float, TVG_UNUSED RGB24&, TVG_UNUSED LottieExpression*) { return false; } + template bool result(TVG_UNUSED float, TVG_UNUSED Fill*, TVG_UNUSED LottieExpression*) { return false; } + template bool result(TVG_UNUSED float, TVG_UNUSED Array&, TVG_UNUSED Array&, TVG_UNUSED Matrix* transform, TVG_UNUSED float, TVG_UNUSED LottieExpression*) { return false; } + void update(TVG_UNUSED float) {} + static LottieExpressions* instance() { return nullptr; } + static void retrieve(TVG_UNUSED LottieExpressions* instance) {} +}; + +#endif //THORVG_LOTTIE_EXPRESSIONS_SUPPORT + +#endif //_TVG_LOTTIE_EXPRESSIONS_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieInterpolator.cpp b/test/include/liblvgl/libs/thorvg/tvgLottieInterpolator.cpp new file mode 100644 index 00000000..c92bfb6e --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieInterpolator.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include "tvgCommon.h" +#include "tvgMath.h" +#include "tvgLottieInterpolator.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +#define NEWTON_MIN_SLOPE 0.02f +#define NEWTON_ITERATIONS 4 +#define SUBDIVISION_PRECISION 0.0000001f +#define SUBDIVISION_MAX_ITERATIONS 10 + + +static inline float _constA(float aA1, float aA2) { return 1.0f - 3.0f * aA2 + 3.0f * aA1; } +static inline float _constB(float aA1, float aA2) { return 3.0f * aA2 - 6.0f * aA1; } +static inline float _constC(float aA1) { return 3.0f * aA1; } + + +static inline float _getSlope(float t, float aA1, float aA2) +{ + return 3.0f * _constA(aA1, aA2) * t * t + 2.0f * _constB(aA1, aA2) * t + _constC(aA1); +} + + +static inline float _calcBezier(float t, float aA1, float aA2) +{ + return ((_constA(aA1, aA2) * t + _constB(aA1, aA2)) * t + _constC(aA1)) * t; +} + + +float LottieInterpolator::getTForX(float aX) +{ + //Find interval where t lies + auto intervalStart = 0.0f; + auto currentSample = &samples[1]; + auto lastSample = &samples[SPLINE_TABLE_SIZE - 1]; + + for (; currentSample != lastSample && *currentSample <= aX; ++currentSample) { + intervalStart += SAMPLE_STEP_SIZE; + } + + --currentSample; // t now lies between *currentSample and *currentSample+1 + + // Interpolate to provide an initial guess for t + auto dist = (aX - *currentSample) / (*(currentSample + 1) - *currentSample); + auto guessForT = intervalStart + dist * SAMPLE_STEP_SIZE; + + // Check the slope to see what strategy to use. If the slope is too small + // Newton-Raphson iteration won't converge on a root so we use bisection + // instead. + auto initialSlope = _getSlope(guessForT, outTangent.x, inTangent.x); + if (initialSlope >= NEWTON_MIN_SLOPE) return NewtonRaphsonIterate(aX, guessForT); + else if (initialSlope == 0.0) return guessForT; + else return binarySubdivide(aX, intervalStart, intervalStart + SAMPLE_STEP_SIZE); +} + + +float LottieInterpolator::binarySubdivide(float aX, float aA, float aB) +{ + float x, t; + int i = 0; + + do { + t = aA + (aB - aA) / 2.0f; + x = _calcBezier(t, outTangent.x, inTangent.x) - aX; + if (x > 0.0f) aB = t; + else aA = t; + } while (fabsf(x) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); + return t; +} + + +float LottieInterpolator::NewtonRaphsonIterate(float aX, float aGuessT) +{ + // Refine guess with Newton-Raphson iteration + for (int i = 0; i < NEWTON_ITERATIONS; ++i) { + // We're trying to find where f(t) = aX, + // so we're actually looking for a root for: CalcBezier(t) - aX + auto currentX = _calcBezier(aGuessT, outTangent.x, inTangent.x) - aX; + auto currentSlope = _getSlope(aGuessT, outTangent.x, inTangent.x); + if (currentSlope == 0.0f) return aGuessT; + aGuessT -= currentX / currentSlope; + } + return aGuessT; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +float LottieInterpolator::progress(float t) +{ + if (outTangent.x == outTangent.y && inTangent.x == inTangent.y) return t; + return _calcBezier(getTForX(t), outTangent.y, inTangent.y); +} + + +void LottieInterpolator::set(const char* key, Point& inTangent, Point& outTangent) +{ + this->key = strdup(key); + this->inTangent = inTangent; + this->outTangent = outTangent; + + if (outTangent.x == outTangent.y && inTangent.x == inTangent.y) return; + + //calculates sample values + for (int i = 0; i < SPLINE_TABLE_SIZE; ++i) { + samples[i] = _calcBezier(float(i) * SAMPLE_STEP_SIZE, outTangent.x, inTangent.x); + } +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieInterpolator.h b/test/include/liblvgl/libs/thorvg/tvgLottieInterpolator.h new file mode 100644 index 00000000..c7d07d47 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieInterpolator.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_INTERPOLATOR_H_ +#define _TVG_LOTTIE_INTERPOLATOR_H_ + +#define SPLINE_TABLE_SIZE 11 + +struct LottieInterpolator +{ + char* key; + Point outTangent, inTangent; + + float progress(float t); + void set(const char* key, Point& inTangent, Point& outTangent); + +private: + static constexpr float SAMPLE_STEP_SIZE = 1.0f / float(SPLINE_TABLE_SIZE - 1); + float samples[SPLINE_TABLE_SIZE]; + + float getTForX(float aX); + float binarySubdivide(float aX, float aA, float aB); + float NewtonRaphsonIterate(float aX, float aGuessT); +}; + +#endif //_TVG_LOTTIE_INTERPOLATOR_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieLoader.cpp b/test/include/liblvgl/libs/thorvg/tvgLottieLoader.cpp new file mode 100644 index 00000000..8230211a --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieLoader.cpp @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgLottieLoader.h" +#include "tvgLottieModel.h" +#include "tvgLottieParser.h" +#include "tvgLottieBuilder.h" +#include "tvgStr.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +void LottieLoader::run(unsigned tid) +{ + //update frame + if (comp) { + builder->update(comp, frameNo); + //initial loading + } else { + LottieParser parser(content, dirName); + if (!parser.parse()) return; + comp = parser.comp; + builder->build(comp); + } + rebuild = false; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +LottieLoader::LottieLoader() : FrameModule(FileType::Lottie), builder(new LottieBuilder) +{ + +} + + +LottieLoader::~LottieLoader() +{ + this->done(); + + if (copy) free((char*)content); + free(dirName); + + //TODO: correct position? + delete(comp); + delete(builder); +} + + +bool LottieLoader::header() +{ + //A single thread doesn't need to perform intensive tasks. + if (TaskScheduler::threads() == 0) { + run(0); + if (comp) { + w = static_cast(comp->w); + h = static_cast(comp->h); + frameDuration = comp->duration(); + frameCnt = comp->frameCnt(); + return true; + } else { + return false; + } + } + + //Quickly validate the given Lottie file without parsing in order to get the animation info. + auto startFrame = 0.0f; + auto endFrame = 0.0f; + auto frameRate = 0.0f; + uint32_t depth = 0; + + auto p = content; + + while (*p != '\0') { + if (*p == '{') { + ++depth; + ++p; + continue; + } + if (*p == '}') { + --depth; + ++p; + continue; + } + if (depth != 1) { + ++p; + continue; + } + //version. + if (!strncmp(p, "\"v\":", 4)) { + p += 4; + continue; + } + + //framerate + if (!strncmp(p, "\"fr\":", 5)) { + p += 5; + auto e = strstr(p, ","); + if (!e) e = strstr(p, "}"); + frameRate = strToFloat(p, nullptr); + p = e; + continue; + } + + //start frame + if (!strncmp(p, "\"ip\":", 5)) { + p += 5; + auto e = strstr(p, ","); + if (!e) e = strstr(p, "}"); + startFrame = strToFloat(p, nullptr); + p = e; + continue; + } + + //end frame + if (!strncmp(p, "\"op\":", 5)) { + p += 5; + auto e = strstr(p, ","); + if (!e) e = strstr(p, "}"); + endFrame = strToFloat(p, nullptr); + p = e; + continue; + } + + //width + if (!strncmp(p, "\"w\":", 4)) { + p += 4; + auto e = strstr(p, ","); + if (!e) e = strstr(p, "}"); + w = strToFloat(p, nullptr); + p = e; + continue; + } + //height + if (!strncmp(p, "\"h\":", 4)) { + p += 4; + auto e = strstr(p, ","); + if (!e) e = strstr(p, "}"); + h = strToFloat(p, nullptr); + p = e; + continue; + } + ++p; + } + + if (frameRate < FLOAT_EPSILON) { + TVGLOG("LOTTIE", "Not a Lottie file? Frame rate is 0!"); + return false; + } + + frameCnt = (endFrame - startFrame); + frameDuration = frameCnt / frameRate; + + TVGLOG("LOTTIE", "info: frame rate = %f, duration = %f size = %f x %f", frameRate, frameDuration, w, h); + + return true; +} + + +bool LottieLoader::open(const char* data, uint32_t size, bool copy) +{ + if (copy) { + content = (char*)malloc(size); + if (!content) return false; + memcpy((char*)content, data, size); + } else content = data; + + this->size = size; + this->copy = copy; + + return header(); +} + + +bool LottieLoader::open(const string& path) +{ + auto f = fopen(path.c_str(), "r"); + if (!f) return false; + + fseek(f, 0, SEEK_END); + + size = ftell(f); + if (size == 0) { + fclose(f); + return false; + } + + auto content = (char*)(malloc(sizeof(char) * size + 1)); + fseek(f, 0, SEEK_SET); + auto ret = fread(content, sizeof(char), size, f); + if (ret < size) { + fclose(f); + return false; + } + content[size] = '\0'; + + fclose(f); + + this->dirName = strDirname(path.c_str()); + this->content = content; + this->copy = true; + + return header(); +} + + +bool LottieLoader::resize(Paint* paint, float w, float h) +{ + if (!paint) return false; + + auto sx = w / this->w; + auto sy = h / this->h; + Matrix m = {sx, 0, 0, 0, sy, 0, 0, 0, 1}; + paint->transform(m); + + //apply the scale to the base clipper + const Paint* clipper; + paint->composite(&clipper); + if (clipper) const_cast(clipper)->transform(m); + + return true; +} + + +bool LottieLoader::read() +{ + if (!content || size == 0) return false; + + //the loading has been already completed + if (comp || !LoadModule::read()) return true; + + TaskScheduler::request(this); + + return true; +} + + +Paint* LottieLoader::paint() +{ + done(); + + if (!comp) return nullptr; + comp->initiated = true; + return comp->root->scene; +} + + +bool LottieLoader::override(const char* slot) +{ + if (!comp) done(); + + if (!comp || comp->slots.count == 0) return false; + + auto success = true; + + //override slots + if (slot) { + //Copy the input data because the JSON parser will encode the data immediately. + auto temp = strdup(slot); + + //parsing slot json + LottieParser parser(temp, dirName); + + auto idx = 0; + while (auto sid = parser.sid(idx == 0)) { + for (auto s = comp->slots.begin(); s < comp->slots.end(); ++s) { + if (strcmp((*s)->sid, sid)) continue; + if (!parser.apply(*s)) success = false; + break; + } + ++idx; + } + + if (idx < 1) success = false; + free(temp); + rebuild = overridden = success; + //reset slots + } else if (overridden) { + for (auto s = comp->slots.begin(); s < comp->slots.end(); ++s) { + (*s)->reset(); + } + overridden = false; + rebuild = true; + } + return success; +} + + +bool LottieLoader::frame(float no) +{ + auto frameNo = no + startFrame(); + + //This ensures that the target frame number is reached. + frameNo *= 10000.0f; + frameNo = roundf(frameNo); + frameNo *= 0.0001f; + + //Skip update if frame diff is too small. + if (fabsf(this->frameNo - frameNo) <= 0.0009f) return false; + + this->done(); + + this->frameNo = frameNo; + + TaskScheduler::request(this); + + return true; +} + + +float LottieLoader::startFrame() +{ + return frameCnt * segmentBegin; +} + + +float LottieLoader::totalFrame() +{ + return (segmentEnd - segmentBegin) * frameCnt; +} + + +float LottieLoader::curFrame() +{ + return frameNo - startFrame(); +} + + +float LottieLoader::duration() +{ + if (segmentBegin == 0.0f && segmentEnd == 1.0f) return frameDuration; + + if (!comp) done(); + if (!comp) return 0.0f; + + return frameCnt * (segmentEnd - segmentBegin) / comp->frameRate; +} + + +void LottieLoader::sync() +{ + this->done(); + + if (rebuild) run(0); +} + + +uint32_t LottieLoader::markersCnt() +{ + if (!comp) done(); + if (!comp) return 0; + return comp->markers.count; +} + + +const char* LottieLoader::markers(uint32_t index) +{ + if (!comp) done(); + if (!comp || index >= comp->markers.count) return nullptr; + auto marker = comp->markers.begin() + index; + return (*marker)->name; +} + + +bool LottieLoader::segment(const char* marker, float& begin, float& end) +{ + if (!comp) done(); + if (!comp) return false; + + for (auto m = comp->markers.begin(); m < comp->markers.end(); ++m) { + if (!strcmp(marker, (*m)->name)) { + begin = (*m)->time / frameCnt; + end = ((*m)->time + (*m)->duration) / frameCnt; + return true; + } + } + return false; +} + + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieLoader.h b/test/include/liblvgl/libs/thorvg/tvgLottieLoader.h new file mode 100644 index 00000000..57ad9b7f --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieLoader.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_LOADER_H_ +#define _TVG_LOTTIE_LOADER_H_ + +#include "tvgCommon.h" +#include "tvgFrameModule.h" +#include "tvgTaskScheduler.h" + +struct LottieComposition; +struct LottieBuilder; + +class LottieLoader : public FrameModule, public Task +{ +public: + const char* content = nullptr; //lottie file data + uint32_t size = 0; //lottie data size + float frameNo = 0.0f; //current frame number + float frameCnt = 0.0f; + float frameDuration = 0.0f; + + LottieBuilder* builder; + LottieComposition* comp = nullptr; + + char* dirName = nullptr; //base resource directory + bool copy = false; //"content" is owned by this loader + bool overridden = false; //overridden properties with slots + bool rebuild = false; //require building the lottie scene + + LottieLoader(); + ~LottieLoader(); + + bool open(const string& path) override; + bool open(const char* data, uint32_t size, bool copy) override; + bool resize(Paint* paint, float w, float h) override; + bool read() override; + Paint* paint() override; + bool override(const char* slot); + + //Frame Controls + bool frame(float no) override; + float totalFrame() override; + float curFrame() override; + float duration() override; + void sync() override; + + //Marker Supports + uint32_t markersCnt(); + const char* markers(uint32_t index); + bool segment(const char* marker, float& begin, float& end); + +private: + bool header(); + void clear(); + float startFrame(); + void run(unsigned tid) override; +}; + + +#endif //_TVG_LOTTIELOADER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieModel.cpp b/test/include/liblvgl/libs/thorvg/tvgLottieModel.cpp new file mode 100644 index 00000000..5230adb4 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieModel.cpp @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgPaint.h" +#include "tvgFill.h" +#include "tvgLottieModel.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void LottieSlot::reset() +{ + if (!overridden) return; + + for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) { + switch (type) { + case LottieProperty::Type::ColorStop: { + static_cast(pair->obj)->colorStops.release(); + static_cast(pair->obj)->colorStops = *static_cast(pair->prop); + static_cast(pair->prop)->frames = nullptr; + break; + } + case LottieProperty::Type::Color: { + static_cast(pair->obj)->color.release(); + static_cast(pair->obj)->color = *static_cast(pair->prop); + static_cast(pair->prop)->frames = nullptr; + break; + } + case LottieProperty::Type::TextDoc: { + static_cast(pair->obj)->doc.release(); + static_cast(pair->obj)->doc = *static_cast(pair->prop); + static_cast(pair->prop)->frames = nullptr; + break; + } + default: break; + } + delete(pair->prop); + pair->prop = nullptr; + } + overridden = false; +} + + +void LottieSlot::assign(LottieObject* target) +{ + //apply slot object to all targets + for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) { + //backup the original properties before overwriting + switch (type) { + case LottieProperty::Type::ColorStop: { + if (!overridden) { + pair->prop = new LottieColorStop; + *static_cast(pair->prop) = static_cast(pair->obj)->colorStops; + } + + pair->obj->override(&static_cast(target)->colorStops); + break; + } + case LottieProperty::Type::Color: { + if (!overridden) { + pair->prop = new LottieColor; + *static_cast(pair->prop) = static_cast(pair->obj)->color; + } + + pair->obj->override(&static_cast(target)->color); + break; + } + case LottieProperty::Type::TextDoc: { + if (!overridden) { + pair->prop = new LottieTextDoc; + *static_cast(pair->prop) = static_cast(pair->obj)->doc; + } + + pair->obj->override(&static_cast(target)->doc); + break; + } + default: break; + } + } + overridden = true; +} + + +LottieImage::~LottieImage() +{ + free(b64Data); + free(mimeType); + + if (picture && PP(picture)->unref() == 0) { + delete(picture); + } +} + + +void LottieTrimpath::segment(float frameNo, float& start, float& end, LottieExpressions* exps) +{ + auto s = this->start(frameNo, exps) * 0.01f; + auto e = this->end(frameNo, exps) * 0.01f; + auto o = fmodf(this->offset(frameNo, exps), 360.0f) / 360.0f; //0 ~ 1 + + auto diff = fabs(s - e); + if (mathZero(diff)) { + start = 0.0f; + end = 0.0f; + return; + } + if (mathEqual(diff, 1.0f) || mathEqual(diff, 2.0f)) { + start = 0.0f; + end = 1.0f; + return; + } + + s += o; + e += o; + + auto loop = true; + + //no loop + if (s > 1.0f && e > 1.0f) loop = false; + if (s < 0.0f && e < 0.0f) loop = false; + if (s >= 0.0f && s <= 1.0f && e >= 0.0f && e <= 1.0f) loop = false; + + if (s > 1.0f) s -= 1.0f; + if (s < 0.0f) s += 1.0f; + if (e > 1.0f) e -= 1.0f; + if (e < 0.0f) e += 1.0f; + + if (loop) { + start = s > e ? s : e; + end = s < e ? s : e; + } else { + start = s < e ? s : e; + end = s > e ? s : e; + } +} + + +uint32_t LottieGradient::populate(ColorStop& color) +{ + colorStops.populated = true; + if (!color.input) return 0; + + uint32_t alphaCnt = (color.input->count - (colorStops.count * 4)) / 2; + Array output(colorStops.count + alphaCnt); + uint32_t cidx = 0; //color count + uint32_t clast = colorStops.count * 4; + if (clast > color.input->count) clast = color.input->count; + uint32_t aidx = clast; //alpha count + Fill::ColorStop cs; + + //merge color stops. + for (uint32_t i = 0; i < color.input->count; ++i) { + if (cidx == clast || aidx == color.input->count) break; + if ((*color.input)[cidx] == (*color.input)[aidx]) { + cs.offset = (*color.input)[cidx]; + cs.r = lroundf((*color.input)[cidx + 1] * 255.0f); + cs.g = lroundf((*color.input)[cidx + 2] * 255.0f); + cs.b = lroundf((*color.input)[cidx + 3] * 255.0f); + cs.a = lroundf((*color.input)[aidx + 1] * 255.0f); + cidx += 4; + aidx += 2; + } else if ((*color.input)[cidx] < (*color.input)[aidx]) { + cs.offset = (*color.input)[cidx]; + cs.r = lroundf((*color.input)[cidx + 1] * 255.0f); + cs.g = lroundf((*color.input)[cidx + 2] * 255.0f); + cs.b = lroundf((*color.input)[cidx + 3] * 255.0f); + //generate alpha value + if (output.count > 0) { + auto p = ((*color.input)[cidx] - output.last().offset) / ((*color.input)[aidx] - output.last().offset); + cs.a = mathLerp(output.last().a, lroundf((*color.input)[aidx + 1] * 255.0f), p); + } else cs.a = 255; + cidx += 4; + } else { + cs.offset = (*color.input)[aidx]; + cs.a = lroundf((*color.input)[aidx + 1] * 255.0f); + //generate color value + if (output.count > 0) { + auto p = ((*color.input)[aidx] - output.last().offset) / ((*color.input)[cidx] - output.last().offset); + cs.r = mathLerp(output.last().r, lroundf((*color.input)[cidx + 1] * 255.0f), p); + cs.g = mathLerp(output.last().g, lroundf((*color.input)[cidx + 2] * 255.0f), p); + cs.b = mathLerp(output.last().b, lroundf((*color.input)[cidx + 3] * 255.0f), p); + } else cs.r = cs.g = cs.b = 255; + aidx += 2; + } + output.push(cs); + } + + //color remains + while (cidx + 3 < clast) { + cs.offset = (*color.input)[cidx]; + cs.r = lroundf((*color.input)[cidx + 1] * 255.0f); + cs.g = lroundf((*color.input)[cidx + 2] * 255.0f); + cs.b = lroundf((*color.input)[cidx + 3] * 255.0f); + cs.a = (output.count > 0) ? output.last().a : 255; + output.push(cs); + cidx += 4; + } + + //alpha remains + while (aidx < color.input->count) { + cs.offset = (*color.input)[aidx]; + cs.a = lroundf((*color.input)[aidx + 1] * 255.0f); + if (output.count > 0) { + cs.r = output.last().r; + cs.g = output.last().g; + cs.b = output.last().b; + } else cs.r = cs.g = cs.b = 255; + output.push(cs); + aidx += 2; + } + + color.data = output.data; + output.data = nullptr; + + color.input->reset(); + delete(color.input); + + return output.count; +} + + +Fill* LottieGradient::fill(float frameNo, LottieExpressions* exps) +{ + Fill* fill = nullptr; + auto s = start(frameNo, exps); + auto e = end(frameNo, exps); + + //Linear Gradient + if (id == 1) { + fill = LinearGradient::gen().release(); + static_cast(fill)->linear(s.x, s.y, e.x, e.y); + } + //Radial Gradient + if (id == 2) { + fill = RadialGradient::gen().release(); + + auto w = fabsf(e.x - s.x); + auto h = fabsf(e.y - s.y); + auto r = (w > h) ? (w + 0.375f * h) : (h + 0.375f * w); + auto progress = this->height(frameNo, exps) * 0.01f; + + if (mathZero(progress)) { + P(static_cast(fill))->radial(s.x, s.y, r, s.x, s.y, 0.0f); + } else { + if (mathEqual(progress, 1.0f)) progress = 0.99f; + auto startAngle = mathRad2Deg(atan2(e.y - s.y, e.x - s.x)); + auto angle = mathDeg2Rad((startAngle + this->angle(frameNo, exps))); + auto fx = s.x + cos(angle) * progress * r; + auto fy = s.y + sin(angle) * progress * r; + // Lottie doesn't have any focal radius concept + P(static_cast(fill))->radial(s.x, s.y, r, fx, fy, 0.0f); + } + } + + if (!fill) return nullptr; + + colorStops(frameNo, fill, exps); + + return fill; +} + + +void LottieGroup::prepare(LottieObject::Type type) +{ + LottieObject::type = type; + + if (children.count == 0) return; + + size_t strokeCnt = 0; + size_t fillCnt = 0; + + for (auto c = children.end() - 1; c >= children.begin(); --c) { + auto child = static_cast(*c); + + if (child->type == LottieObject::Type::Trimpath) trimpath = true; + + /* Figure out if this group is a simple path drawing. + In that case, the rendering context can be sharable with the parent's. */ + if (allowMerge && (child->type == LottieObject::Group || !child->mergeable())) allowMerge = false; + + if (reqFragment) continue; + + /* Figure out if the rendering context should be fragmented. + Multiple stroking or grouping with a stroking would occur this. + This fragment resolves the overlapped stroke outlines. */ + if (child->type == LottieObject::Group && !child->mergeable()) { + if (strokeCnt > 0 || fillCnt > 0) reqFragment = true; + } else if (child->type == LottieObject::SolidStroke || child->type == LottieObject::GradientStroke) { + if (strokeCnt > 0) reqFragment = true; + else ++strokeCnt; + } else if (child->type == LottieObject::SolidFill || child->type == LottieObject::GradientFill) { + if (fillCnt > 0) reqFragment = true; + else ++fillCnt; + } + } + + //Reverse the drawing order if this group has a trimpath. + if (!trimpath) return; + + for (uint32_t i = 0; i < children.count - 1; ) { + auto child2 = children[i + 1]; + if (!child2->mergeable() || child2->type == LottieObject::Transform) { + i += 2; + continue; + } + auto child = children[i]; + if (!child->mergeable() || child->type == LottieObject::Transform) { + i++; + continue; + } + children[i] = child2; + children[i + 1] = child; + i++; + } +} + + +LottieLayer::~LottieLayer() +{ + if (refId) { + //No need to free assets children because the Composition owns them. + children.clear(); + free(refId); + } + + for (auto m = masks.begin(); m < masks.end(); ++m) { + delete(*m); + } + + delete(matte.target); + delete(transform); +} + +void LottieLayer::prepare() +{ + /* if layer is hidden, only useful data is its transform matrix. + so force it to be a Null Layer and release all resource. */ + if (hidden) { + type = LottieLayer::Null; + for (auto p = children.begin(); p < children.end(); ++p) delete(*p); + children.reset(); + return; + } + LottieGroup::prepare(LottieObject::Layer); +} + + +float LottieLayer::remap(float frameNo, LottieExpressions* exp) +{ + if (timeRemap.frames || timeRemap.value) { + frameNo = comp->frameAtTime(timeRemap(frameNo, exp)); + } else { + frameNo -= startFrame; + } + return (frameNo / timeStretch); +} + + +LottieComposition::~LottieComposition() +{ + if (!initiated && root) delete(root->scene); + + delete(root); + free(version); + free(name); + + //delete interpolators + for (auto i = interpolators.begin(); i < interpolators.end(); ++i) { + free((*i)->key); + free(*i); + } + + //delete assets + for (auto a = assets.begin(); a < assets.end(); ++a) { + delete(*a); + } + + //delete fonts + for (auto f = fonts.begin(); f < fonts.end(); ++f) { + delete(*f); + } + + //delete slots + for (auto s = slots.begin(); s < slots.end(); ++s) { + delete(*s); + } + + for (auto m = markers.begin(); m < markers.end(); ++m) { + delete(*m); + } +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieModel.h b/test/include/liblvgl/libs/thorvg/tvgLottieModel.h new file mode 100644 index 00000000..6ba92de1 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieModel.h @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_MODEL_H_ +#define _TVG_LOTTIE_MODEL_H_ + +#include + +#include "tvgCommon.h" +#include "tvgRender.h" +#include "tvgLottieProperty.h" + + +struct LottieComposition; + +struct LottieStroke +{ + struct DashAttr + { + //0: offset, 1: dash, 2: gap + LottieFloat value[3] = {0.0f, 0.0f, 0.0f}; + }; + + virtual ~LottieStroke() + { + delete(dashattr); + } + + LottieFloat& dash(int no) + { + if (!dashattr) dashattr = new DashAttr; + return dashattr->value[no]; + } + + float dashOffset(float frameNo, LottieExpressions* exps) + { + return dash(0)(frameNo, exps); + } + + float dashGap(float frameNo, LottieExpressions* exps) + { + return dash(2)(frameNo, exps); + } + + float dashSize(float frameNo, LottieExpressions* exps) + { + auto d = dash(1)(frameNo, exps); + if (d == 0.0f) return 0.1f; + else return d; + } + + LottieFloat width = 0.0f; + DashAttr* dashattr = nullptr; + float miterLimit = 0; + StrokeCap cap = StrokeCap::Round; + StrokeJoin join = StrokeJoin::Round; +}; + + +struct LottieMask +{ + LottiePathSet pathset; + LottieOpacity opacity = 255; + CompositeMethod method; + bool inverse = false; +}; + + +struct LottieObject +{ + enum Type : uint8_t + { + Composition = 0, + Layer, + Group, + Transform, + SolidFill, + SolidStroke, + GradientFill, + GradientStroke, + Rect, + Ellipse, + Path, + Polystar, + Image, + Trimpath, + Text, + Repeater, + RoundedCorner + }; + + virtual ~LottieObject() + { + free(name); + } + + virtual void override(LottieProperty* prop) + { + TVGERR("LOTTIE", "Unsupported slot type"); + } + + virtual bool mergeable() { return false; } + + char* name = nullptr; + Type type; + bool hidden = false; //remove? +}; + + +struct LottieGlyph +{ + Array children; //glyph shapes. + float width; + char* code; + char* family = nullptr; + char* style = nullptr; + uint16_t size; + uint8_t len; + + void prepare() + { + len = strlen(code); + } + + ~LottieGlyph() + { + for (auto p = children.begin(); p < children.end(); ++p) delete(*p); + free(code); + } +}; + + +struct LottieFont +{ + enum Origin : uint8_t { Local = 0, CssURL, ScriptURL, FontURL, Embedded }; + + ~LottieFont() + { + for (auto c = chars.begin(); c < chars.end(); ++c) delete(*c); + free(style); + free(family); + free(name); + } + + Array chars; + char* name = nullptr; + char* family = nullptr; + char* style = nullptr; + float ascent = 0.0f; + Origin origin = Embedded; +}; + +struct LottieMarker +{ + char* name = nullptr; + float time = 0.0f; + float duration = 0.0f; + + ~LottieMarker() + { + free(name); + } +}; + +struct LottieText : LottieObject +{ + void prepare() + { + LottieObject::type = LottieObject::Text; + } + + void override(LottieProperty* prop) override + { + this->doc = *static_cast(prop); + this->prepare(); + } + + LottieTextDoc doc; + LottieFont* font; + LottieFloat spacing = 0.0f; //letter spacing +}; + + +struct LottieTrimpath : LottieObject +{ + enum Type : uint8_t { Simultaneous = 1, Individual = 2 }; + + void prepare() + { + LottieObject::type = LottieObject::Trimpath; + } + + bool mergeable() override + { + if (!start.frames && start.value == 0.0f && !end.frames && end.value == 100.0f && !offset.frames && offset.value == 0.0f) return true; + return false; + } + + void segment(float frameNo, float& start, float& end, LottieExpressions* exps); + + LottieFloat start = 0.0f; + LottieFloat end = 100.0f; + LottieFloat offset = 0.0f; + Type type = Simultaneous; +}; + + +struct LottieShape : LottieObject +{ + virtual ~LottieShape() {} + uint8_t direction = 0; //0: clockwise, 2: counter-clockwise, 3: xor(?) + + bool mergeable() override + { + return true; + } +}; + + +struct LottieRoundedCorner : LottieObject +{ + void prepare() + { + LottieObject::type = LottieObject::RoundedCorner; + } + LottieFloat radius = 0.0f; +}; + + +struct LottiePath : LottieShape +{ + void prepare() + { + LottieObject::type = LottieObject::Path; + } + + LottiePathSet pathset; +}; + + +struct LottieRect : LottieShape +{ + void prepare() + { + LottieObject::type = LottieObject::Rect; + } + + LottiePosition position = Point{0.0f, 0.0f}; + LottiePoint size = Point{0.0f, 0.0f}; + LottieFloat radius = 0.0f; //rounded corner radius +}; + + +struct LottiePolyStar : LottieShape +{ + enum Type : uint8_t {Star = 1, Polygon}; + + void prepare() + { + LottieObject::type = LottieObject::Polystar; + } + + LottiePosition position = Point{0.0f, 0.0f}; + LottieFloat innerRadius = 0.0f; + LottieFloat outerRadius = 0.0f; + LottieFloat innerRoundness = 0.0f; + LottieFloat outerRoundness = 0.0f; + LottieFloat rotation = 0.0f; + LottieFloat ptsCnt = 0.0f; + Type type = Polygon; +}; + + +struct LottieEllipse : LottieShape +{ + void prepare() + { + LottieObject::type = LottieObject::Ellipse; + } + + LottiePosition position = Point{0.0f, 0.0f}; + LottiePoint size = Point{0.0f, 0.0f}; +}; + + +struct LottieTransform : LottieObject +{ + struct SeparateCoord + { + LottieFloat x = 0.0f; + LottieFloat y = 0.0f; + }; + + struct RotationEx + { + LottieFloat x = 0.0f; + LottieFloat y = 0.0f; + }; + + ~LottieTransform() + { + delete(coords); + delete(rotationEx); + } + + void prepare() + { + LottieObject::type = LottieObject::Transform; + } + + bool mergeable() override + { + if (!opacity.frames && opacity.value == 255) return true; + return false; + } + + LottiePosition position = Point{0.0f, 0.0f}; + LottieFloat rotation = 0.0f; //z rotation + LottiePoint scale = Point{100.0f, 100.0f}; + LottiePoint anchor = Point{0.0f, 0.0f}; + LottieOpacity opacity = 255; + LottieFloat skewAngle = 0.0f; + LottieFloat skewAxis = 0.0f; + + SeparateCoord* coords = nullptr; //either a position or separate coordinates + RotationEx* rotationEx = nullptr; //extension for 3d rotation +}; + + +struct LottieSolid : LottieObject +{ + LottieColor color = RGB24{255, 255, 255}; + LottieOpacity opacity = 255; +}; + + +struct LottieSolidStroke : LottieSolid, LottieStroke +{ + void prepare() + { + LottieObject::type = LottieObject::SolidStroke; + } + + void override(LottieProperty* prop) override + { + this->color = *static_cast(prop); + this->prepare(); + } +}; + + +struct LottieSolidFill : LottieSolid +{ + void prepare() + { + LottieObject::type = LottieObject::SolidFill; + } + + void override(LottieProperty* prop) override + { + this->color = *static_cast(prop); + this->prepare(); + } + + FillRule rule = FillRule::Winding; +}; + + +struct LottieGradient : LottieObject +{ + bool prepare() + { + if (!colorStops.populated) { + if (colorStops.frames) { + for (auto v = colorStops.frames->begin(); v < colorStops.frames->end(); ++v) { + colorStops.count = populate(v->value); + } + } else { + colorStops.count = populate(colorStops.value); + } + } + if (start.frames || end.frames || height.frames || angle.frames || opacity.frames || colorStops.frames) return true; + return false; + } + + uint32_t populate(ColorStop& color); + Fill* fill(float frameNo, LottieExpressions* exps); + + LottiePoint start = Point{0.0f, 0.0f}; + LottiePoint end = Point{0.0f, 0.0f}; + LottieFloat height = 0.0f; + LottieFloat angle = 0.0f; + LottieOpacity opacity = 255; + LottieColorStop colorStops; + uint8_t id = 0; //1: linear, 2: radial +}; + + +struct LottieGradientFill : LottieGradient +{ + void prepare() + { + LottieObject::type = LottieObject::GradientFill; + LottieGradient::prepare(); + } + + void override(LottieProperty* prop) override + { + this->colorStops = *static_cast(prop); + this->prepare(); + } + + FillRule rule = FillRule::Winding; +}; + + +struct LottieGradientStroke : LottieGradient, LottieStroke +{ + void prepare() + { + LottieObject::type = LottieObject::GradientStroke; + LottieGradient::prepare(); + } + + void override(LottieProperty* prop) override + { + this->colorStops = *static_cast(prop); + this->prepare(); + } +}; + + +struct LottieImage : LottieObject +{ + union { + char* b64Data = nullptr; + char* path; + }; + char* mimeType = nullptr; + uint32_t size = 0; + + Picture* picture = nullptr; //tvg render data + + ~LottieImage(); + + void prepare() + { + LottieObject::type = LottieObject::Image; + } +}; + + +struct LottieRepeater : LottieObject +{ + void prepare() + { + LottieObject::type = LottieObject::Repeater; + } + + LottieFloat copies = 0.0f; + LottieFloat offset = 0.0f; + + //Transform + LottiePosition position = Point{0.0f, 0.0f}; + LottieFloat rotation = 0.0f; + LottiePoint scale = Point{100.0f, 100.0f}; + LottiePoint anchor = Point{0.0f, 0.0f}; + LottieOpacity startOpacity = 255; + LottieOpacity endOpacity = 255; + bool inorder = true; //true: higher, false: lower +}; + + +struct LottieGroup : LottieObject +{ + virtual ~LottieGroup() + { + for (auto p = children.begin(); p < children.end(); ++p) delete(*p); + } + + void prepare(LottieObject::Type type = LottieObject::Group); + bool mergeable() override { return allowMerge; } + + LottieObject* content(const char* id) + { + if (name && !strcmp(name, id)) return this; + + //source has children, find recursively. + for (auto c = children.begin(); c < children.end(); ++c) { + auto child = *c; + if (child->type == LottieObject::Type::Group || child->type == LottieObject::Type::Layer) { + if (auto ret = static_cast(child)->content(id)) return ret; + } else if (child->name && !strcmp(child->name, id)) return child; + } + return nullptr; + } + + Scene* scene = nullptr; //tvg render data + Array children; + + bool reqFragment = false; //requirement to fragment the render context + bool buildDone = false; //completed in building the composition. + bool allowMerge = true; //if this group is consisted of simple (transformed) shapes. + bool trimpath = false; //this group has a trimpath. +}; + + +struct LottieLayer : LottieGroup +{ + enum Type : uint8_t {Precomp = 0, Solid, Image, Null, Shape, Text}; + + ~LottieLayer(); + + uint8_t opacity(float frameNo) + { + //return zero if the visibility is false. + if (type == Null) return 255; + return transform->opacity(frameNo); + } + + bool mergeable() override { return false; } + + void prepare(); + float remap(float frameNo, LottieExpressions* exp); + + struct { + CompositeMethod type = CompositeMethod::None; + LottieLayer* target = nullptr; + } matte; + + BlendMethod blendMethod = BlendMethod::Normal; + LottieLayer* parent = nullptr; + LottieFloat timeRemap = 0.0f; + LottieComposition* comp = nullptr; + LottieTransform* transform = nullptr; + Array masks; + RGB24 color; //used by Solid layer + + float timeStretch = 1.0f; + float w = 0.0f, h = 0.0f; + float inFrame = 0.0f; + float outFrame = 0.0f; + float startFrame = 0.0f; + char* refId = nullptr; //pre-composition reference. + int16_t pid = -1; //id of the parent layer. + int16_t id = -1; //id of the current layer. + + //cached data + struct { + float frameNo = -1.0f; + Matrix matrix; + uint8_t opacity; + } cache; + + Type type = Null; + bool autoOrient = false; + bool matteSrc = false; +}; + + +struct LottieSlot +{ + struct Pair { + LottieObject* obj; + LottieProperty* prop; + }; + + void assign(LottieObject* target); + void reset(); + + LottieSlot(char* sid, LottieObject* obj, LottieProperty::Type type) : sid(sid), type(type) + { + pairs.push({obj, 0}); + } + + ~LottieSlot() + { + free(sid); + if (!overridden) return; + for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) { + delete(pair->prop); + } + } + + char* sid; + Array pairs; + LottieProperty::Type type; + bool overridden = false; +}; + + +struct LottieComposition +{ + ~LottieComposition(); + + float duration() const + { + return frameCnt() / frameRate; // in second + } + + float frameAtTime(float timeInSec) const + { + auto p = timeInSec / duration(); + if (p < 0.0f) p = 0.0f; + return p * frameCnt(); + } + + float timeAtFrame(float frameNo) + { + return (frameNo - startFrame) / frameRate; + } + + float frameCnt() const + { + return endFrame - startFrame; + } + + LottieLayer* layer(const char* name) + { + for (auto child = root->children.begin(); child < root->children.end(); ++child) { + auto layer = static_cast(*child); + if (layer->name && !strcmp(layer->name, name)) return layer; + } + return nullptr; + } + + LottieLayer* layer(int16_t id) + { + for (auto child = root->children.begin(); child < root->children.end(); ++child) { + auto layer = static_cast(*child); + if (layer->id == id) return layer; + } + return nullptr; + } + + LottieLayer* asset(const char* name) + { + for (auto asset = assets.begin(); asset < assets.end(); ++asset) { + auto layer = static_cast(*asset); + if (layer->name && !strcmp(layer->name, name)) return layer; + } + return nullptr; + } + + LottieLayer* root = nullptr; + char* version = nullptr; + char* name = nullptr; + float w, h; + float startFrame, endFrame; + float frameRate; + Array assets; + Array interpolators; + Array fonts; + Array slots; + Array markers; + bool expressions = false; + bool initiated = false; +}; + +#endif //_TVG_LOTTIE_MODEL_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieParser.cpp b/test/include/liblvgl/libs/thorvg/tvgLottieParser.cpp new file mode 100644 index 00000000..17e43b09 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieParser.cpp @@ -0,0 +1,1405 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgStr.h" +#include "tvgCompressor.h" +#include "tvgLottieModel.h" +#include "tvgLottieParser.h" +#include "tvgLottieExpressions.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +#define KEY_AS(name) !strcmp(key, name) + + +static LottieExpression* _expression(char* code, LottieComposition* comp, LottieLayer* layer, LottieObject* object, LottieProperty* property, LottieProperty::Type type) +{ + if (!comp->expressions) comp->expressions = true; + + auto inst = new LottieExpression; + inst->code = code; + inst->comp = comp; + inst->layer = layer; + inst->object = object; + inst->property = property; + inst->type = type; + inst->enabled = true; + + return inst; +} + + +static char* _int2str(int num) +{ + char str[20]; + snprintf(str, 20, "%d", num); + return strdup(str); +} + + +CompositeMethod LottieParser::getMaskMethod(bool inversed) +{ + auto mode = getString(); + if (!mode) return CompositeMethod::None; + + switch (mode[0]) { + case 'a': { + if (inversed) return CompositeMethod::InvAlphaMask; + else return CompositeMethod::AddMask; + } + case 's': return CompositeMethod::SubtractMask; + case 'i': return CompositeMethod::IntersectMask; + case 'f': return CompositeMethod::DifferenceMask; + default: return CompositeMethod::None; + } +} + + +BlendMethod LottieParser::getBlendMethod() +{ + switch (getInt()) { + case 0: return BlendMethod::Normal; + case 1: return BlendMethod::Multiply; + case 2: return BlendMethod::Screen; + case 3: return BlendMethod::Overlay; + case 4: return BlendMethod::Darken; + case 5: return BlendMethod::Lighten; + case 6: return BlendMethod::ColorDodge; + case 7: return BlendMethod::ColorBurn; + case 8: return BlendMethod::HardLight; + case 9: return BlendMethod::SoftLight; + case 10: return BlendMethod::Difference; + case 11: return BlendMethod::Exclusion; + //case 12: return BlendMethod::Hue: + //case 13: return BlendMethod::Saturation: + //case 14: return BlendMethod::Color: + //case 15: return BlendMethod::Luminosity: + case 16: return BlendMethod::Add; + //case 17: return BlendMethod::HardMix: + default: { + TVGERR("LOTTIE", "Non-Supported Blend Mode"); + return BlendMethod::Normal; + } + } +} + + +RGB24 LottieParser::getColor(const char *str) +{ + RGB24 color = {0, 0, 0}; + + if (!str) return color; + + auto len = strlen(str); + + // some resource has empty color string, return a default color for those cases. + if (len != 7 || str[0] != '#') return color; + + char tmp[3] = {'\0', '\0', '\0'}; + tmp[0] = str[1]; + tmp[1] = str[2]; + color.rgb[0] = uint8_t(strtol(tmp, nullptr, 16)); + + tmp[0] = str[3]; + tmp[1] = str[4]; + color.rgb[1] = uint8_t(strtol(tmp, nullptr, 16)); + + tmp[0] = str[5]; + tmp[1] = str[6]; + color.rgb[2] = uint8_t(strtol(tmp, nullptr, 16)); + + return color; +} + + +FillRule LottieParser::getFillRule() +{ + switch (getInt()) { + case 1: return FillRule::Winding; + default: return FillRule::EvenOdd; + } +} + + +CompositeMethod LottieParser::getMatteType() +{ + switch (getInt()) { + case 1: return CompositeMethod::AlphaMask; + case 2: return CompositeMethod::InvAlphaMask; + case 3: return CompositeMethod::LumaMask; + case 4: return CompositeMethod::InvLumaMask; + default: return CompositeMethod::None; + } +} + + +StrokeCap LottieParser::getStrokeCap() +{ + switch (getInt()) { + case 1: return StrokeCap::Butt; + case 2: return StrokeCap::Round; + default: return StrokeCap::Square; + } +} + + +StrokeJoin LottieParser::getStrokeJoin() +{ + switch (getInt()) { + case 1: return StrokeJoin::Miter; + case 2: return StrokeJoin::Round; + default: return StrokeJoin::Bevel; + } +} + + +void LottieParser::getValue(TextDocument& doc) +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("s")) doc.size = getFloat(); + else if (KEY_AS("f")) doc.name = getStringCopy(); + else if (KEY_AS("t")) doc.text = getStringCopy(); + else if (KEY_AS("j")) doc.justify = getInt(); + else if (KEY_AS("tr")) doc.tracking = getFloat() * 0.1f; + else if (KEY_AS("lh")) doc.height = getFloat(); + else if (KEY_AS("ls")) doc.shift = getFloat(); + else if (KEY_AS("fc")) getValue(doc.color); + else if (KEY_AS("ps")) getValue(doc.bbox.pos); + else if (KEY_AS("sz")) getValue(doc.bbox.size); + else if (KEY_AS("sc")) getValue(doc.stroke.color); + else if (KEY_AS("sw")) doc.stroke.width = getFloat(); + else if (KEY_AS("of")) doc.stroke.render = getBool(); + else skip(key); + } +} + + +void LottieParser::getValue(PathSet& path) +{ + Array outs, ins, pts; + bool closed = false; + + /* The shape object could be wrapped by a array + if its part of the keyframe object */ + auto arrayWrapper = (peekType() == kArrayType) ? true : false; + if (arrayWrapper) enterArray(); + + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("i")) getValue(ins); + else if (KEY_AS("o")) getValue(outs); + else if (KEY_AS("v")) getValue(pts); + else if (KEY_AS("c")) closed = getBool(); + else skip(key); + } + + //exit properly from the array + if (arrayWrapper) nextArrayValue(); + + //valid path data? + if (ins.empty() || outs.empty() || pts.empty()) return; + if (ins.count != outs.count || outs.count != pts.count) return; + + //convert path + auto out = outs.begin(); + auto in = ins.begin(); + auto pt = pts.begin(); + + //Store manipulated results + Array outPts; + Array outCmds; + + //Reuse the buffers + outPts.data = path.pts; + outPts.reserved = path.ptsCnt; + outCmds.data = path.cmds; + outCmds.reserved = path.cmdsCnt; + + size_t extra = closed ? 3 : 0; + outPts.reserve(pts.count * 3 + 1 + extra); + outCmds.reserve(pts.count + 2); + + outCmds.push(PathCommand::MoveTo); + outPts.push(*pt); + + for (++pt, ++out, ++in; pt < pts.end(); ++pt, ++out, ++in) { + outCmds.push(PathCommand::CubicTo); + outPts.push(*(pt - 1) + *(out - 1)); + outPts.push(*pt + *in); + outPts.push(*pt); + } + + if (closed) { + outPts.push(pts.last() + outs.last()); + outPts.push(pts.first() + ins.first()); + outPts.push(pts.first()); + outCmds.push(PathCommand::CubicTo); + outCmds.push(PathCommand::Close); + } + + path.pts = outPts.data; + path.cmds = outCmds.data; + path.ptsCnt = outPts.count; + path.cmdsCnt = outCmds.count; + + outPts.data = nullptr; + outCmds.data = nullptr; +} + + +void LottieParser::getValue(ColorStop& color) +{ + if (peekType() == kArrayType) enterArray(); + + color.input = new Array(static_cast(context.parent)->colorStops.count); + + while (nextArrayValue()) color.input->push(getFloat()); +} + + +void LottieParser::getValue(Array& pts) +{ + enterArray(); + while (nextArrayValue()) { + enterArray(); + Point pt; + getValue(pt); + pts.push(pt); + } +} + + +void LottieParser::getValue(uint8_t& val) +{ + if (peekType() == kArrayType) { + enterArray(); + if (nextArrayValue()) val = (uint8_t)(getFloat() * 2.55f); + //discard rest + while (nextArrayValue()) getFloat(); + } else { + val = (uint8_t)(getFloat() * 2.55f); + } +} + + +void LottieParser::getValue(float& val) +{ + if (peekType() == kArrayType) { + enterArray(); + if (nextArrayValue()) val = getFloat(); + //discard rest + while (nextArrayValue()) getFloat(); + } else { + val = getFloat(); + } +} + + +void LottieParser::getValue(Point& pt) +{ + int i = 0; + auto ptr = (float*)(&pt); + + if (peekType() == kArrayType) enterArray(); + + while (nextArrayValue()) { + auto val = getFloat(); + if (i < 2) ptr[i++] = val; + } +} + + +void LottieParser::getValue(RGB24& color) +{ + int i = 0; + + if (peekType() == kArrayType) enterArray(); + + while (nextArrayValue()) { + auto val = getFloat(); + if (i < 3) color.rgb[i++] = int32_t(lroundf(val * 255.0f)); + } + + //TODO: color filter? +} + + +void LottieParser::getInterpolatorPoint(Point& pt) +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("x")) getValue(pt.x); + else if (KEY_AS("y")) getValue(pt.y); + } +} + + +template +void LottieParser::parseSlotProperty(T& prop) +{ + while (auto key = nextObjectKey()) { + if (KEY_AS("p")) parseProperty(prop); + else skip(key); + } +} + + +template +bool LottieParser::parseTangent(const char *key, LottieVectorFrame& value) +{ + if (KEY_AS("ti")) { + value.hasTangent = true; + getValue(value.inTangent); + } else if (KEY_AS("to")) { + value.hasTangent = true; + getValue(value.outTangent); + } else return false; + + return true; +} + + +template +bool LottieParser::parseTangent(const char *key, LottieScalarFrame& value) +{ + return false; +} + + +LottieInterpolator* LottieParser::getInterpolator(const char* key, Point& in, Point& out) +{ + char buf[20]; + + if (!key) { + snprintf(buf, sizeof(buf), "%.2f_%.2f_%.2f_%.2f", in.x, in.y, out.x, out.y); + key = buf; + } + + LottieInterpolator* interpolator = nullptr; + + //get a cached interpolator if it has any. + for (auto i = comp->interpolators.begin(); i < comp->interpolators.end(); ++i) { + if (!strncmp((*i)->key, key, sizeof(buf))) interpolator = *i; + } + + //new interpolator + if (!interpolator) { + interpolator = static_cast(malloc(sizeof(LottieInterpolator))); + interpolator->set(key, in, out); + comp->interpolators.push(interpolator); + } + + return interpolator; +} + + +template +void LottieParser::parseKeyFrame(T& prop) +{ + Point inTangent, outTangent; + const char* interpolatorKey = nullptr; + auto& frame = prop.newFrame(); + auto interpolator = false; + + enterObject(); + + while (auto key = nextObjectKey()) { + if (KEY_AS("i")) { + interpolator = true; + getInterpolatorPoint(inTangent); + } else if (KEY_AS("o")) { + getInterpolatorPoint(outTangent); + } else if (KEY_AS("n")) { + if (peekType() == kStringType) { + interpolatorKey = getString(); + } else { + enterArray(); + while (nextArrayValue()) { + if (!interpolatorKey) interpolatorKey = getString(); + else skip(nullptr); + } + } + } else if (KEY_AS("t")) { + frame.no = getFloat(); + } else if (KEY_AS("s")) { + getValue(frame.value); + } else if (KEY_AS("e")) { + //current end frame and the next start frame is duplicated, + //We propagate the end value to the next frame to avoid having duplicated values. + auto& frame2 = prop.nextFrame(); + getValue(frame2.value); + } else if (parseTangent(key, frame)) { + continue; + } else if (KEY_AS("h")) { + frame.hold = getInt(); + } else skip(key); + } + + if (interpolator) { + frame.interpolator = getInterpolator(interpolatorKey, inTangent, outTangent); + } +} + +template +void LottieParser::parsePropertyInternal(T& prop) +{ + //single value property + if (peekType() == kNumberType) { + getValue(prop.value); + //multi value property + } else { + //TODO: Here might be a single frame. + //Can we figure out the frame number in advance? + enterArray(); + while (nextArrayValue()) { + //keyframes value + if (peekType() == kObjectType) { + parseKeyFrame(prop); + //multi value property with no keyframes + } else { + getValue(prop.value); + break; + } + } + prop.prepare(); + } +} + + +template +void LottieParser::parseProperty(T& prop, LottieObject* obj) +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("k")) parsePropertyInternal(prop); + else if (obj && KEY_AS("sid")) { + auto sid = getStringCopy(); + //append object if the slot already exists. + for (auto slot = comp->slots.begin(); slot < comp->slots.end(); ++slot) { + if (strcmp((*slot)->sid, sid)) continue; + (*slot)->pairs.push({obj, 0}); + return; + } + comp->slots.push(new LottieSlot(sid, obj, type)); + } else if (!strcmp(key, "x")) { + prop.exp = _expression(getStringCopy(), comp, context.layer, context.parent, &prop, type); + } + else skip(key); + } +} + + +LottieRect* LottieParser::parseRect() +{ + auto rect = new LottieRect; + if (!rect) return nullptr; + + context.parent = rect; + + while (auto key = nextObjectKey()) { + if (KEY_AS("s")) parseProperty(rect->size); + else if (KEY_AS("p"))parseProperty(rect->position); + else if (KEY_AS("r")) parseProperty(rect->radius); + else if (KEY_AS("nm")) rect->name = getStringCopy(); + else if (KEY_AS("hd")) rect->hidden = getBool(); + else skip(key); + } + rect->prepare(); + return rect; +} + + +LottieEllipse* LottieParser::parseEllipse() +{ + auto ellipse = new LottieEllipse; + if (!ellipse) return nullptr; + + context.parent = ellipse; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) ellipse->name = getStringCopy(); + else if (KEY_AS("p")) parseProperty(ellipse->position); + else if (KEY_AS("s")) parseProperty(ellipse->size); + else if (KEY_AS("hd")) ellipse->hidden = getBool(); + else skip(key); + } + ellipse->prepare(); + return ellipse; +} + + +LottieTransform* LottieParser::parseTransform(bool ddd) +{ + auto transform = new LottieTransform; + if (!transform) return nullptr; + + context.parent = transform; + + if (ddd) { + transform->rotationEx = new LottieTransform::RotationEx; + TVGLOG("LOTTIE", "3D transform(ddd) is not totally compatible."); + } + + while (auto key = nextObjectKey()) { + if (KEY_AS("p")) + { + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("k")) parsePropertyInternal(transform->position); + else if (KEY_AS("s") && getBool()) transform->coords = new LottieTransform::SeparateCoord; + //check separateCoord to figure out whether "x(expression)" / "x(coord)" + else if (transform->coords && KEY_AS("x")) parseProperty(transform->coords->x); + else if (transform->coords && KEY_AS("y")) parseProperty(transform->coords->y); + else if (KEY_AS("x")) transform->position.exp = _expression(getStringCopy(), comp, context.layer, context.parent, &transform->position, LottieProperty::Type::Position); + else skip(key); + } + } + else if (KEY_AS("a")) parseProperty(transform->anchor); + else if (KEY_AS("s")) parseProperty(transform->scale); + else if (KEY_AS("r")) parseProperty(transform->rotation); + else if (KEY_AS("o")) parseProperty(transform->opacity); + else if (transform->rotationEx && KEY_AS("rx")) parseProperty(transform->rotationEx->x); + else if (transform->rotationEx && KEY_AS("ry")) parseProperty(transform->rotationEx->y); + else if (transform->rotationEx && KEY_AS("rz")) parseProperty(transform->rotation); + else if (KEY_AS("nm")) transform->name = getStringCopy(); + else if (KEY_AS("sk")) parseProperty(transform->skewAngle); + else if (KEY_AS("sa")) parseProperty(transform->skewAxis); + else skip(key); + } + transform->prepare(); + return transform; +} + + +LottieSolidFill* LottieParser::parseSolidFill() +{ + auto fill = new LottieSolidFill; + if (!fill) return nullptr; + + context.parent = fill; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) fill->name = getStringCopy(); + else if (KEY_AS("c")) parseProperty(fill->color, fill); + else if (KEY_AS("o")) parseProperty(fill->opacity, fill); + else if (KEY_AS("fillEnabled")) fill->hidden |= !getBool(); + else if (KEY_AS("r")) fill->rule = getFillRule(); + else if (KEY_AS("hd")) fill->hidden = getBool(); + else skip(key); + } + fill->prepare(); + return fill; +} + + +void LottieParser::parseStrokeDash(LottieStroke* stroke) +{ + enterArray(); + while (nextArrayValue()) { + enterObject(); + int idx = 0; + while (auto key = nextObjectKey()) { + if (KEY_AS("n")) { + auto style = getString(); + if (!strcmp("o", style)) idx = 0; //offset + else if (!strcmp("d", style)) idx = 1; //dash + else if (!strcmp("g", style)) idx = 2; //gap + } else if (KEY_AS("v")) { + parseProperty(stroke->dash(idx)); + } else skip(key); + } + } +} + + +LottieSolidStroke* LottieParser::parseSolidStroke() +{ + auto stroke = new LottieSolidStroke; + if (!stroke) return nullptr; + + context.parent = stroke; + + while (auto key = nextObjectKey()) { + if (KEY_AS("c")) parseProperty(stroke->color, stroke); + else if (KEY_AS("o")) parseProperty(stroke->opacity, stroke); + else if (KEY_AS("w")) parseProperty(stroke->width, stroke); + else if (KEY_AS("lc")) stroke->cap = getStrokeCap(); + else if (KEY_AS("lj")) stroke->join = getStrokeJoin(); + else if (KEY_AS("ml")) stroke->miterLimit = getFloat(); + else if (KEY_AS("nm")) stroke->name = getStringCopy(); + else if (KEY_AS("hd")) stroke->hidden = getBool(); + else if (KEY_AS("fillEnabled")) stroke->hidden |= !getBool(); + else if (KEY_AS("d")) parseStrokeDash(stroke); + else skip(key); + } + stroke->prepare(); + return stroke; +} + + +void LottieParser::getPathSet(LottiePathSet& path) +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("k")) { + if (peekType() == kArrayType) { + enterArray(); + while (nextArrayValue()) parseKeyFrame(path); + } else { + getValue(path.value); + } + } else if (!strcmp(key, "x")) { + path.exp = _expression(getStringCopy(), comp, context.layer, context.parent, &path, LottieProperty::Type::PathSet); + } else skip(key); + } +} + + +LottiePath* LottieParser::parsePath() +{ + auto path = new LottiePath; + if (!path) return nullptr; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) path->name = getStringCopy(); + else if (KEY_AS("ks")) getPathSet(path->pathset); + else if (KEY_AS("hd")) path->hidden = getBool(); + else skip(key); + } + path->prepare(); + return path; +} + + +LottiePolyStar* LottieParser::parsePolyStar() +{ + auto star = new LottiePolyStar; + if (!star) return nullptr; + + context.parent = star; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) star->name = getStringCopy(); + else if (KEY_AS("p")) parseProperty(star->position); + else if (KEY_AS("pt")) parseProperty(star->ptsCnt); + else if (KEY_AS("ir")) parseProperty(star->innerRadius); + else if (KEY_AS("is")) parseProperty(star->innerRoundness); + else if (KEY_AS("or")) parseProperty(star->outerRadius); + else if (KEY_AS("os")) parseProperty(star->outerRoundness); + else if (KEY_AS("r")) parseProperty(star->rotation); + else if (KEY_AS("sy")) star->type = (LottiePolyStar::Type) getInt(); + else if (KEY_AS("hd")) star->hidden = getBool(); + else skip(key); + } + star->prepare(); + return star; +} + + +LottieRoundedCorner* LottieParser::parseRoundedCorner() +{ + auto corner = new LottieRoundedCorner; + if (!corner) return nullptr; + + context.parent = corner; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) corner->name = getStringCopy(); + else if (KEY_AS("r")) parseProperty(corner->radius); + else if (KEY_AS("hd")) corner->hidden = getBool(); + else skip(key); + } + corner->prepare(); + return corner; +} + + +void LottieParser::parseGradient(LottieGradient* gradient, const char* key) +{ + if (KEY_AS("t")) gradient->id = getInt(); + else if (KEY_AS("o")) parseProperty(gradient->opacity, gradient); + else if (KEY_AS("g")) + { + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("p")) gradient->colorStops.count = getInt(); + else if (KEY_AS("k")) parseProperty(gradient->colorStops, gradient); + else skip(key); + } + } + else if (KEY_AS("s")) parseProperty(gradient->start, gradient); + else if (KEY_AS("e")) parseProperty(gradient->end, gradient); + else if (KEY_AS("h")) parseProperty(gradient->height, gradient); + else if (KEY_AS("a")) parseProperty(gradient->angle, gradient); + else skip(key); +} + + +LottieGradientFill* LottieParser::parseGradientFill() +{ + auto fill = new LottieGradientFill; + if (!fill) return nullptr; + + context.parent = fill; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) fill->name = getStringCopy(); + else if (KEY_AS("r")) fill->rule = getFillRule(); + else if (KEY_AS("hd")) fill->hidden = getBool(); + else parseGradient(fill, key); + } + + fill->prepare(); + + return fill; +} + + +LottieGradientStroke* LottieParser::parseGradientStroke() +{ + auto stroke = new LottieGradientStroke; + if (!stroke) return nullptr; + + context.parent = stroke; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) stroke->name = getStringCopy(); + else if (KEY_AS("lc")) stroke->cap = getStrokeCap(); + else if (KEY_AS("lj")) stroke->join = getStrokeJoin(); + else if (KEY_AS("ml")) stroke->miterLimit = getFloat(); + else if (KEY_AS("hd")) stroke->hidden = getBool(); + else if (KEY_AS("w")) parseProperty(stroke->width); + else if (KEY_AS("d")) parseStrokeDash(stroke); + else parseGradient(stroke, key); + } + stroke->prepare(); + + return stroke; +} + + +LottieTrimpath* LottieParser::parseTrimpath() +{ + auto trim = new LottieTrimpath; + if (!trim) return nullptr; + + context.parent = trim; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) trim->name = getStringCopy(); + else if (KEY_AS("s")) parseProperty(trim->start); + else if (KEY_AS("e")) parseProperty(trim->end); + else if (KEY_AS("o")) parseProperty(trim->offset); + else if (KEY_AS("m")) trim->type = static_cast(getInt()); + else if (KEY_AS("hd")) trim->hidden = getBool(); + else skip(key); + } + trim->prepare(); + + return trim; +} + + +LottieRepeater* LottieParser::parseRepeater() +{ + auto repeater = new LottieRepeater; + if (!repeater) return nullptr; + + context.parent = repeater; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) repeater->name = getStringCopy(); + else if (KEY_AS("c")) parseProperty(repeater->copies); + else if (KEY_AS("o")) parseProperty(repeater->offset); + else if (KEY_AS("m")) repeater->inorder = getInt(); + else if (KEY_AS("tr")) + { + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("a")) parseProperty(repeater->anchor); + else if (KEY_AS("p")) parseProperty(repeater->position); + else if (KEY_AS("r")) parseProperty(repeater->rotation); + else if (KEY_AS("s")) parseProperty(repeater->scale); + else if (KEY_AS("so")) parseProperty(repeater->startOpacity); + else if (KEY_AS("eo")) parseProperty(repeater->endOpacity); + else skip(key); + } + } + else if (KEY_AS("hd")) repeater->hidden = getBool(); + else skip(key); + } + repeater->prepare(); + + return repeater; +} + + +LottieObject* LottieParser::parseObject() +{ + auto type = getString(); + if (!type) return nullptr; + + if (!strcmp(type, "gr")) return parseGroup(); + else if (!strcmp(type, "rc")) return parseRect(); + else if (!strcmp(type, "el")) return parseEllipse(); + else if (!strcmp(type, "tr")) return parseTransform(); + else if (!strcmp(type, "fl")) return parseSolidFill(); + else if (!strcmp(type, "st")) return parseSolidStroke(); + else if (!strcmp(type, "sh")) return parsePath(); + else if (!strcmp(type, "sr")) return parsePolyStar(); + else if (!strcmp(type, "rd")) return parseRoundedCorner(); + else if (!strcmp(type, "gf")) return parseGradientFill(); + else if (!strcmp(type, "gs")) return parseGradientStroke(); + else if (!strcmp(type, "tm")) return parseTrimpath(); + else if (!strcmp(type, "rp")) return parseRepeater(); + else if (!strcmp(type, "mm")) TVGERR("LOTTIE", "MergePath(mm) is not supported yet"); + else if (!strcmp(type, "pb")) TVGERR("LOTTIE", "Puker/Bloat(pb) is not supported yet"); + else if (!strcmp(type, "tw")) TVGERR("LOTTIE", "Twist(tw) is not supported yet"); + else if (!strcmp(type, "op")) TVGERR("LOTTIE", "Offset Path(op) is not supported yet"); + else if (!strcmp(type, "zz")) TVGERR("LOTTIE", "Zig Zag(zz) is not supported yet"); + return nullptr; +} + + +void LottieParser::parseObject(Array& parent) +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("ty")) { + if (auto child = parseObject()) { + if (child->hidden) delete(child); + else parent.push(child); + } + } else skip(key); + } +} + + +LottieImage* LottieParser::parseImage(const char* data, const char* subPath, bool embedded) +{ + //Used for Image Asset + auto image = new LottieImage; + + //embedded image resource. should start with "data:" + //header look like "data:image/png;base64," so need to skip till ','. + if (embedded && !strncmp(data, "data:", 5)) { + //figure out the mimetype + auto mimeType = data + 11; + auto needle = strstr(mimeType, ";"); + image->mimeType = strDuplicate(mimeType, needle - mimeType); + //b64 data + auto b64Data = strstr(data, ",") + 1; + size_t length = strlen(data) - (b64Data - data); + image->size = b64Decode(b64Data, length, &image->b64Data); + //external image resource + } else { + auto len = strlen(dirName) + strlen(subPath) + strlen(data) + 1; + image->path = static_cast(malloc(len)); + snprintf(image->path, len, "%s%s%s", dirName, subPath, data); + } + + image->prepare(); + + return image; +} + + +LottieObject* LottieParser::parseAsset() +{ + enterObject(); + + LottieObject* obj = nullptr; + char *id = nullptr; + + //Used for Image Asset + const char* data = nullptr; + const char* subPath = nullptr; + auto embedded = false; + + while (auto key = nextObjectKey()) { + if (KEY_AS("id")) + { + if (peekType() == kStringType) { + id = getStringCopy(); + } else { + id = _int2str(getInt()); + } + } + else if (KEY_AS("layers")) obj = parseLayers(); + else if (KEY_AS("u")) subPath = getString(); + else if (KEY_AS("p")) data = getString(); + else if (KEY_AS("e")) embedded = getInt(); + else skip(key); + } + if (data) obj = parseImage(data, subPath, embedded); + if (obj) obj->name = id; + else free(id); + return obj; +} + + +LottieFont* LottieParser::parseFont() +{ + enterObject(); + + auto font = new LottieFont; + + while (auto key = nextObjectKey()) { + if (KEY_AS("fName")) font->name = getStringCopy(); + else if (KEY_AS("fFamily")) font->family = getStringCopy(); + else if (KEY_AS("fStyle")) font->style = getStringCopy(); + else if (KEY_AS("ascent")) font->ascent = getFloat(); + else if (KEY_AS("origin")) font->origin = (LottieFont::Origin) getInt(); + else skip(key); + } + return font; +} + + +void LottieParser::parseAssets() +{ + enterArray(); + while (nextArrayValue()) { + auto asset = parseAsset(); + if (asset) comp->assets.push(asset); + else TVGERR("LOTTIE", "Invalid Asset!"); + } +} + +LottieMarker* LottieParser::parseMarker() +{ + enterObject(); + + auto marker = new LottieMarker; + + while (auto key = nextObjectKey()) { + if (KEY_AS("cm")) marker->name = getStringCopy(); + else if (KEY_AS("tm")) marker->time = getFloat(); + else if (KEY_AS("dr")) marker->duration = getFloat(); + else skip(key); + } + + return marker; +} + +void LottieParser::parseMarkers() +{ + enterArray(); + while (nextArrayValue()) { + comp->markers.push(parseMarker()); + } +} + +void LottieParser::parseChars(Array& glyphs) +{ + enterArray(); + while (nextArrayValue()) { + enterObject(); + //a new glyph + auto glyph = new LottieGlyph; + while (auto key = nextObjectKey()) { + if (KEY_AS("ch")) glyph->code = getStringCopy(); + else if (KEY_AS("size")) glyph->size = static_cast(getFloat()); + else if (KEY_AS("style")) glyph->style = getStringCopy(); + else if (KEY_AS("w")) glyph->width = getFloat(); + else if (KEY_AS("fFamily")) glyph->family = getStringCopy(); + else if (KEY_AS("data")) + { //glyph shapes + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("shapes")) parseShapes(glyph->children); + } + } else skip(key); + } + glyph->prepare(); + glyphs.push(glyph); + } +} + +void LottieParser::parseFonts() +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("list")) { + enterArray(); + while (nextArrayValue()) { + comp->fonts.push(parseFont()); + } + } else skip(key); + } +} + + +LottieObject* LottieParser::parseGroup() +{ + auto group = new LottieGroup; + if (!group) return nullptr; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) { + group->name = getStringCopy(); + } else if (KEY_AS("it")) { + enterArray(); + while (nextArrayValue()) parseObject(group->children); + } else skip(key); + } + if (group->children.empty()) { + delete(group); + return nullptr; + } + group->prepare(); + + return group; +} + + +void LottieParser::parseTimeRemap(LottieLayer* layer) +{ + parseProperty(layer->timeRemap); +} + + +uint8_t LottieParser::getDirection() +{ + auto v = getInt(); + if (v == 1) return 0; + if (v == 2) return 3; + if (v == 3) return 2; + return 0; +} + +void LottieParser::parseShapes(Array& parent) +{ + uint8_t direction; + + enterArray(); + while (nextArrayValue()) { + direction = 0; + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("it")) { + enterArray(); + while (nextArrayValue()) parseObject(parent); + } else if (KEY_AS("d")) { + direction = getDirection(); + } else if (KEY_AS("ty")) { + if (auto child = parseObject()) { + if (child->hidden) delete(child); + else parent.push(child); + if (direction > 0) static_cast(child)->direction = direction; + } + } else skip(key); + } + } +} + + +void LottieParser::parseTextRange(LottieText* text) +{ + enterArray(); + while (nextArrayValue()) { + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("a")) { //text style + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("t")) parseProperty(text->spacing); + else skip(key); + } + } else skip(key); + } + } +} + + +void LottieParser::parseText(Array& parent) +{ + enterObject(); + + auto text = new LottieText; + + while (auto key = nextObjectKey()) { + if (KEY_AS("d")) parseProperty(text->doc, text); + else if (KEY_AS("a")) parseTextRange(text); + //else if (KEY_AS("p")) TVGLOG("LOTTIE", "Text Follow Path (p) is not supported"); + //else if (KEY_AS("m")) TVGLOG("LOTTIE", "Text Alignment Option (m) is not supported"); + else skip(key); + } + + text->prepare(); + parent.push(text); +} + + +void LottieParser::getLayerSize(float& val) +{ + if (val == 0.0f) { + val = getFloat(); + } else { + //layer might have both w(width) & sw(solid color width) + //override one if the a new size is smaller. + auto w = getFloat(); + if (w < val) val = w; + } +} + +LottieMask* LottieParser::parseMask() +{ + auto mask = new LottieMask; + if (!mask) return nullptr; + + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("inv")) mask->inverse = getBool(); + else if (KEY_AS("mode")) mask->method = getMaskMethod(mask->inverse); + else if (KEY_AS("pt")) getPathSet(mask->pathset); + else if (KEY_AS("o")) parseProperty(mask->opacity); + else skip(key); + } + + return mask; +} + + +void LottieParser::parseMasks(LottieLayer* layer) +{ + enterArray(); + while (nextArrayValue()) { + auto mask = parseMask(); + layer->masks.push(mask); + } +} + + +LottieLayer* LottieParser::parseLayer() +{ + auto layer = new LottieLayer; + if (!layer) return nullptr; + + layer->comp = comp; + context.layer = layer; + + auto ddd = false; + + enterObject(); + + while (auto key = nextObjectKey()) { + if (KEY_AS("ddd")) ddd = getInt(); //3d layer + else if (KEY_AS("ind")) layer->id = getInt(); + else if (KEY_AS("ty")) layer->type = (LottieLayer::Type) getInt(); + else if (KEY_AS("nm")) layer->name = getStringCopy(); + else if (KEY_AS("sr")) layer->timeStretch = getFloat(); + else if (KEY_AS("ks")) + { + enterObject(); + layer->transform = parseTransform(ddd); + } + else if (KEY_AS("ao")) layer->autoOrient = getInt(); + else if (KEY_AS("shapes")) parseShapes(layer->children); + else if (KEY_AS("ip")) layer->inFrame = getFloat(); + else if (KEY_AS("op")) layer->outFrame = getFloat(); + else if (KEY_AS("st")) layer->startFrame = getFloat(); + else if (KEY_AS("bm")) layer->blendMethod = getBlendMethod(); + else if (KEY_AS("parent")) layer->pid = getInt(); + else if (KEY_AS("tm")) parseTimeRemap(layer); + else if (KEY_AS("w") || KEY_AS("sw")) getLayerSize(layer->w); + else if (KEY_AS("h") || KEY_AS("sh")) getLayerSize(layer->h); + else if (KEY_AS("sc")) layer->color = getColor(getString()); + else if (KEY_AS("tt")) layer->matte.type = getMatteType(); + else if (KEY_AS("masksProperties")) parseMasks(layer); + else if (KEY_AS("hd")) layer->hidden = getBool(); + else if (KEY_AS("refId")) layer->refId = getStringCopy(); + else if (KEY_AS("td")) layer->matteSrc = getInt(); //used for matte layer + else if (KEY_AS("t")) parseText(layer->children); + else if (KEY_AS("ef")) + { + TVGERR("LOTTIE", "layer effect(ef) is not supported!"); + skip(key); + } + else skip(key); + } + + //Not a valid layer + if (!layer->transform) { + delete(layer); + return nullptr; + } + + layer->prepare(); + + return layer; +} + + +LottieLayer* LottieParser::parseLayers() +{ + auto root = new LottieLayer; + if (!root) return nullptr; + + root->type = LottieLayer::Precomp; + root->comp = comp; + + enterArray(); + while (nextArrayValue()) { + if (auto layer = parseLayer()) { + if (layer->matte.type == CompositeMethod::None) { + root->children.push(layer); + } else { + //matte source must be located in the right previous. + auto matte = static_cast(root->children.last()); + if (matte->matteSrc) { + layer->matte.target = matte; + } else { + TVGLOG("LOTTIE", "Matte Source(%s) is not designated?", matte->name); + } + root->children.last() = layer; + } + } + } + root->prepare(); + return root; +} + + +void LottieParser::postProcess(Array& glyphs) +{ + //aggregate font characters + for (uint32_t g = 0; g < glyphs.count; ++g) { + auto glyph = glyphs[g]; + for (uint32_t i = 0; i < comp->fonts.count; ++i) { + auto& font = comp->fonts[i]; + if (!strcmp(font->family, glyph->family) && !strcmp(font->style, glyph->style)) { + font->chars.push(glyph); + free(glyph->family); + free(glyph->style); + break; + } + } + } +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +const char* LottieParser::sid(bool first) +{ + if (first) { + //verify json + if (!parseNext()) return nullptr; + enterObject(); + } + return nextObjectKey(); +} + + +bool LottieParser::apply(LottieSlot* slot) +{ + enterObject(); + + //OPTIMIZE: we can create the property directly, without object + LottieObject* obj = nullptr; //slot object + + switch (slot->type) { + case LottieProperty::Type::ColorStop: { + obj = new LottieGradient; + context.parent = obj; + parseSlotProperty(static_cast(obj)->colorStops); + break; + } + case LottieProperty::Type::Color: { + obj = new LottieSolid; + context.parent = obj; + parseSlotProperty(static_cast(obj)->color); + break; + } + case LottieProperty::Type::TextDoc: { + obj = new LottieText; + context.parent = obj; + parseSlotProperty(static_cast(obj)->doc); + break; + } + default: break; + } + + if (!obj || Invalid()) return false; + + slot->assign(obj); + + delete(obj); + + return true; +} + + +bool LottieParser::parse() +{ + //verify json. + if (!parseNext()) return false; + + enterObject(); + + if (comp) delete(comp); + comp = new LottieComposition; + if (!comp) return false; + + Array glyphs; + + while (auto key = nextObjectKey()) { + if (KEY_AS("v")) comp->version = getStringCopy(); + else if (KEY_AS("fr")) comp->frameRate = getFloat(); + else if (KEY_AS("ip")) comp->startFrame = getFloat(); + else if (KEY_AS("op")) comp->endFrame = getFloat(); + else if (KEY_AS("w")) comp->w = getFloat(); + else if (KEY_AS("h")) comp->h = getFloat(); + else if (KEY_AS("nm")) comp->name = getStringCopy(); + else if (KEY_AS("assets")) parseAssets(); + else if (KEY_AS("layers")) comp->root = parseLayers(); + else if (KEY_AS("fonts")) parseFonts(); + else if (KEY_AS("chars")) parseChars(glyphs); + else if (KEY_AS("markers")) parseMarkers(); + else skip(key); + } + + if (Invalid() || !comp->root) { + delete(comp); + return false; + } + + comp->root->inFrame = comp->startFrame; + comp->root->outFrame = comp->endFrame; + + postProcess(glyphs); + + return true; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieParser.h b/test/include/liblvgl/libs/thorvg/tvgLottieParser.h new file mode 100644 index 00000000..a8b6b0d9 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieParser.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_PARSER_H_ +#define _TVG_LOTTIE_PARSER_H_ + +#include "tvgCommon.h" +#include "tvgLottieParserHandler.h" +#include "tvgLottieProperty.h" + +struct LottieParser : LookaheadParserHandler +{ +public: + LottieParser(const char *str, const char* dirName) : LookaheadParserHandler(str) + { + this->dirName = dirName; + } + + bool parse(); + bool apply(LottieSlot* slot); + const char* sid(bool first = false); + + LottieComposition* comp = nullptr; + const char* dirName = nullptr; //base resource directory + +private: + BlendMethod getBlendMethod(); + RGB24 getColor(const char *str); + CompositeMethod getMatteType(); + FillRule getFillRule(); + StrokeCap getStrokeCap(); + StrokeJoin getStrokeJoin(); + CompositeMethod getMaskMethod(bool inversed); + LottieInterpolator* getInterpolator(const char* key, Point& in, Point& out); + uint8_t getDirection(); + + void getInterpolatorPoint(Point& pt); + void getPathSet(LottiePathSet& path); + void getLayerSize(float& val); + void getValue(TextDocument& doc); + void getValue(PathSet& path); + void getValue(Array& pts); + void getValue(ColorStop& color); + void getValue(float& val); + void getValue(uint8_t& val); + void getValue(Point& pt); + void getValue(RGB24& color); + + template bool parseTangent(const char *key, LottieVectorFrame& value); + template bool parseTangent(const char *key, LottieScalarFrame& value); + template void parseKeyFrame(T& prop); + template void parsePropertyInternal(T& prop); + template void parseProperty(T& prop, LottieObject* obj = nullptr); + template void parseSlotProperty(T& prop); + + LottieObject* parseObject(); + LottieObject* parseAsset(); + LottieImage* parseImage(const char* data, const char* subPath, bool embedded); + LottieLayer* parseLayer(); + LottieObject* parseGroup(); + LottieRect* parseRect(); + LottieEllipse* parseEllipse(); + LottieSolidFill* parseSolidFill(); + LottieTransform* parseTransform(bool ddd = false); + LottieSolidStroke* parseSolidStroke(); + LottieGradientStroke* parseGradientStroke(); + LottiePath* parsePath(); + LottiePolyStar* parsePolyStar(); + LottieRoundedCorner* parseRoundedCorner(); + LottieGradientFill* parseGradientFill(); + LottieLayer* parseLayers(); + LottieMask* parseMask(); + LottieTrimpath* parseTrimpath(); + LottieRepeater* parseRepeater(); + LottieFont* parseFont(); + LottieMarker* parseMarker(); + + void parseObject(Array& parent); + void parseShapes(Array& parent); + void parseText(Array& parent); + void parseMasks(LottieLayer* layer); + void parseTimeRemap(LottieLayer* layer); + void parseStrokeDash(LottieStroke* stroke); + void parseGradient(LottieGradient* gradient, const char* key); + void parseTextRange(LottieText* text); + void parseAssets(); + void parseFonts(); + void parseChars(Array& glyphs); + void parseMarkers(); + void postProcess(Array& glyphs); + + //Current parsing context + struct Context { + LottieLayer* layer = nullptr; + LottieObject* parent = nullptr; + } context; +}; + +#endif //_TVG_LOTTIE_PARSER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieParserHandler.cpp b/test/include/liblvgl/libs/thorvg/tvgLottieParserHandler.cpp new file mode 100644 index 00000000..4d00441b --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieParserHandler.cpp @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. + + * 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 "tvgLottieParserHandler.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static const int PARSE_FLAGS = kParseDefaultFlags | kParseInsituFlag; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +bool LookaheadParserHandler::enterArray() +{ + if (state != kEnteringArray) { + Error(); + return false; + } + parseNext(); + return true; +} + + +bool LookaheadParserHandler::nextArrayValue() +{ + if (state == kExitingArray) { + parseNext(); + return false; + } + //SPECIAL CASE: same as nextObjectKey() + if (state == kExitingObject) return false; + if (state == kError || state == kHasKey) { + Error(); + return false; + } + return true; +} + + +int LookaheadParserHandler::getInt() +{ + if (state != kHasNumber || !val.IsInt()) { + Error(); + return 0; + } + auto result = val.GetInt(); + parseNext(); + return result; +} + + +float LookaheadParserHandler::getFloat() +{ + if (state != kHasNumber) { + Error(); + return 0; + } + auto result = val.GetFloat(); + parseNext(); + return result; +} + + +const char* LookaheadParserHandler::getString() +{ + if (state != kHasString) { + Error(); + return nullptr; + } + auto result = val.GetString(); + parseNext(); + return result; +} + + +char* LookaheadParserHandler::getStringCopy() +{ + auto str = getString(); + if (str) return strdup(str); + return nullptr; +} + + +bool LookaheadParserHandler::getBool() +{ + if (state != kHasBool) { + Error(); + return false; + } + auto result = val.GetBool(); + parseNext(); + return result; +} + + +void LookaheadParserHandler::getNull() +{ + if (state != kHasNull) { + Error(); + return; + } + parseNext(); +} + + +bool LookaheadParserHandler::parseNext() +{ + if (reader.HasParseError()) { + Error(); + return false; + } + if (!reader.IterativeParseNext(iss, *this)) { + Error(); + return false; + } + return true; +} + + +bool LookaheadParserHandler::enterObject() +{ + if (state != kEnteringObject) { + Error(); + return false; + } + parseNext(); + return true; +} + + +int LookaheadParserHandler::peekType() +{ + if (state >= kHasNull && state <= kHasKey) return val.GetType(); + if (state == kEnteringArray) return kArrayType; + if (state == kEnteringObject) return kObjectType; + return -1; +} + + +void LookaheadParserHandler::skipOut(int depth) +{ + do { + if (state == kEnteringArray || state == kEnteringObject) ++depth; + else if (state == kExitingArray || state == kExitingObject) --depth; + else if (state == kError) return; + parseNext(); + } while (depth > 0); +} + + +const char* LookaheadParserHandler::nextObjectKey() +{ + if (state == kHasKey) { + auto result = val.GetString(); + parseNext(); + return result; + } + + /* SPECIAL CASE: The parser works with a predefined rule that it will be only + while (nextObjectKey()) for each object but in case of our nested group + object we can call multiple time nextObjectKey() while exiting the object + so ignore those and don't put parser in the error state. */ + if (state == kExitingArray || state == kEnteringObject) return nullptr; + + if (state != kExitingObject) { + Error(); + return nullptr; + } + + parseNext(); + return nullptr; +} + + +void LookaheadParserHandler::skip(const char* key) +{ + //if (key) TVGLOG("LOTTIE", "Skipped parsing value = %s", key); + + if (peekType() == kArrayType) { + enterArray(); + skipOut(1); + } else if (peekType() == kObjectType) { + enterObject(); + skipOut(1); + } else { + skipOut(0); + } +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieParserHandler.h b/test/include/liblvgl/libs/thorvg/tvgLottieParserHandler.h new file mode 100644 index 00000000..65b4545a --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieParserHandler.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. + + * 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 _TVG_LOTTIE_PARSER_HANDLER_H_ +#define _TVG_LOTTIE_PARSER_HANDLER_H_ + +#include "rapidjson/document.h" +#include "tvgCommon.h" + + +using namespace rapidjson; + + +struct LookaheadParserHandler +{ + enum LookaheadParsingState { + kInit = 0, + kError, + kHasNull, + kHasBool, + kHasNumber, + kHasString, + kHasKey, + kEnteringObject, + kExitingObject, + kEnteringArray, + kExitingArray + }; + + Value val; + LookaheadParsingState state = kInit; + Reader reader; + InsituStringStream iss; + + LookaheadParserHandler(const char *str) : iss((char*)str) + { + reader.IterativeParseInit(); + } + + bool Null() + { + state = kHasNull; + val.SetNull(); + return true; + } + + bool Bool(bool b) + { + state = kHasBool; + val.SetBool(b); + return true; + } + + bool Int(int i) + { + state = kHasNumber; + val.SetInt(i); + return true; + } + + bool Uint(unsigned u) + { + state = kHasNumber; + val.SetUint(u); + return true; + } + + bool Int64(int64_t i) + { + state = kHasNumber; + val.SetInt64(i); + return true; + } + + bool Uint64(int64_t u) + { + state = kHasNumber; + val.SetUint64(u); + return true; + } + + bool Double(double d) + { + state = kHasNumber; + val.SetDouble(d); + return true; + } + + bool RawNumber(const char *, SizeType, TVG_UNUSED bool) + { + return false; + } + + bool String(const char *str, SizeType length, TVG_UNUSED bool) + { + state = kHasString; + val.SetString(str, length); + return true; + } + + bool StartObject() + { + state = kEnteringObject; + return true; + } + + bool Key(const char *str, SizeType length, TVG_UNUSED bool) + { + state = kHasKey; + val.SetString(str, length); + return true; + } + + bool EndObject(SizeType) + { + state = kExitingObject; + return true; + } + + bool StartArray() + { + state = kEnteringArray; + return true; + } + + bool EndArray(SizeType) + { + state = kExitingArray; + return true; + } + + void Error() + { + TVGERR("LOTTIE", "Parsing Error!"); + state = kError; + } + + bool Invalid() + { + return state == kError; + } + + bool enterObject(); + bool enterArray(); + bool nextArrayValue(); + int getInt(); + float getFloat(); + const char* getString(); + char* getStringCopy(); + bool getBool(); + void getNull(); + bool parseNext(); + const char* nextObjectKey(); + void skip(const char* key); + void skipOut(int depth); + int peekType(); +}; + +#endif //_TVG_LOTTIE_PARSER_HANDLER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgLottieProperty.h b/test/include/liblvgl/libs/thorvg/tvgLottieProperty.h new file mode 100644 index 00000000..19df8952 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgLottieProperty.h @@ -0,0 +1,935 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_PROPERTY_H_ +#define _TVG_LOTTIE_PROPERTY_H_ + +#include "tvgCommon.h" +#include "tvgArray.h" +#include "tvgMath.h" +#include "tvgLines.h" +#include "tvgLottieInterpolator.h" +#include "tvgLottieExpressions.h" + +#define ROUNDNESS_EPSILON 1.0f + +struct LottieFont; +struct LottieLayer; +struct LottieObject; + + +struct PathSet +{ + Point* pts = nullptr; + PathCommand* cmds = nullptr; + uint16_t ptsCnt = 0; + uint16_t cmdsCnt = 0; +}; + + +struct RGB24 +{ + int32_t rgb[3]; +}; + + +struct ColorStop +{ + Fill::ColorStop* data = nullptr; + Array* input = nullptr; +}; + + +struct TextDocument +{ + char* text = nullptr; + float height; + float shift; + RGB24 color; + struct { + Point pos; + Point size; + } bbox; + struct { + RGB24 color; + float width; + bool render = false; + } stroke; + char* name = nullptr; + float size; + float tracking = 0.0f; + uint8_t justify; +}; + + +static inline RGB24 operator-(const RGB24& lhs, const RGB24& rhs) +{ + return {lhs.rgb[0] - rhs.rgb[0], lhs.rgb[1] - rhs.rgb[1], lhs.rgb[2] - rhs.rgb[2]}; +} + + +static inline RGB24 operator+(const RGB24& lhs, const RGB24& rhs) +{ + return {lhs.rgb[0] + rhs.rgb[0], lhs.rgb[1] + rhs.rgb[1], lhs.rgb[2] + rhs.rgb[2]}; +} + + +static inline RGB24 operator*(const RGB24& lhs, float rhs) +{ + return {(int32_t)lroundf(lhs.rgb[0] * rhs), (int32_t)lroundf(lhs.rgb[1] * rhs), (int32_t)lroundf(lhs.rgb[2] * rhs)}; +} + + +template +struct LottieScalarFrame +{ + T value; //keyframe value + float no; //frame number + LottieInterpolator* interpolator; + bool hold = false; //do not interpolate. + + T interpolate(LottieScalarFrame* next, float frameNo) + { + auto t = (frameNo - no) / (next->no - no); + if (interpolator) t = interpolator->progress(t); + + if (hold) { + if (t < 1.0f) return value; + else return next->value; + } + return mathLerp(value, next->value, t); + } +}; + + +template +struct LottieVectorFrame +{ + T value; //keyframe value + float no; //frame number + LottieInterpolator* interpolator; + T outTangent, inTangent; + float length; + bool hasTangent = false; + bool hold = false; + + T interpolate(LottieVectorFrame* next, float frameNo) + { + auto t = (frameNo - no) / (next->no - no); + if (interpolator) t = interpolator->progress(t); + + if (hold) { + if (t < 1.0f) return value; + else return next->value; + } + + if (hasTangent) { + Bezier bz = {value, value + outTangent, next->value + inTangent, next->value}; + t = bezAtApprox(bz, t * length, length); + return bezPointAt(bz, t); + } else { + return mathLerp(value, next->value, t); + } + } + + float angle(LottieVectorFrame* next, float frameNo) + { + if (!hasTangent) return 0; + auto t = (frameNo - no) / (next->no - no); + if (interpolator) t = interpolator->progress(t); + Bezier bz = {value, value + outTangent, next->value + inTangent, next->value}; + t = bezAtApprox(bz, t * length, length); + return -bezAngleAt(bz, t); + } + + void prepare(LottieVectorFrame* next) + { + Bezier bz = {value, value + outTangent, next->value + inTangent, next->value}; + length = bezLengthApprox(bz); + } +}; + + +//Property would have an either keyframes or single value. +struct LottieProperty +{ + enum class Type : uint8_t { Point = 0, Float, Opacity, Color, PathSet, ColorStop, Position, TextDoc, Invalid }; + virtual ~LottieProperty() {} + + LottieExpression* exp = nullptr; + + //TODO: Apply common bodies? + virtual uint32_t frameCnt() = 0; + virtual uint32_t nearest(float time) = 0; + virtual float frameNo(int32_t key) = 0; +}; + + +struct LottieExpression +{ + enum LoopMode : uint8_t { None = 0, InCycle = 1, InPingPong, InOffset, InContinue, OutCycle, OutPingPong, OutOffset, OutContinue }; + + char* code; + LottieComposition* comp; + LottieLayer* layer; + LottieObject* object; + LottieProperty* property; + LottieProperty::Type type; + + bool enabled; + + struct { + uint32_t key = 0; //the keyframe number repeating to + float in = FLT_MAX; //looping duration in frame number + LoopMode mode = None; + } loop; +; + ~LottieExpression() + { + free(code); + } +}; + + +static void _copy(PathSet* pathset, Array& outPts, Matrix* transform) +{ + Array inPts; + + if (transform) { + for (int i = 0; i < pathset->ptsCnt; ++i) { + Point pt = pathset->pts[i]; + mathMultiply(&pt, transform); + outPts.push(pt); + } + } else { + inPts.data = pathset->pts; + inPts.count = pathset->ptsCnt; + outPts.push(inPts); + inPts.data = nullptr; + } +} + + +static void _copy(PathSet* pathset, Array& outCmds) +{ + Array inCmds; + inCmds.data = pathset->cmds; + inCmds.count = pathset->cmdsCnt; + outCmds.push(inCmds); + inCmds.data = nullptr; +} + + +static void _roundCorner(Array& cmds, Array& pts, const Point& prev, const Point& curr, const Point& next, float roundness) +{ + auto lenPrev = mathLength(prev - curr); + auto rPrev = lenPrev > 0.0f ? 0.5f * mathMin(lenPrev * 0.5f, roundness) / lenPrev : 0.0f; + auto lenNext = mathLength(next - curr); + auto rNext = lenNext > 0.0f ? 0.5f * mathMin(lenNext * 0.5f, roundness) / lenNext : 0.0f; + + auto dPrev = rPrev * (curr - prev); + auto dNext = rNext * (curr - next); + + pts.push(curr - 2.0f * dPrev); + pts.push(curr - dPrev); + pts.push(curr - dNext); + pts.push(curr - 2.0f * dNext); + cmds.push(PathCommand::LineTo); + cmds.push(PathCommand::CubicTo); +} + + +static bool _modifier(Point* inputPts, uint32_t inputPtsCnt, PathCommand* inputCmds, uint32_t inputCmdsCnt, Array& cmds, Array& pts, Matrix* transform, float roundness) +{ + cmds.reserve(inputCmdsCnt * 2); + pts.reserve((uint16_t)(inputPtsCnt * 1.5)); + auto ptsCnt = pts.count; + + auto startIndex = 0; + for (uint32_t iCmds = 0, iPts = 0; iCmds < inputCmdsCnt; ++iCmds) { + switch (inputCmds[iCmds]) { + case PathCommand::MoveTo: { + startIndex = pts.count; + cmds.push(PathCommand::MoveTo); + pts.push(inputPts[iPts++]); + break; + } + case PathCommand::CubicTo: { + auto& prev = inputPts[iPts - 1]; + auto& curr = inputPts[iPts + 2]; + if (iCmds < inputCmdsCnt - 1 && + mathZero(inputPts[iPts - 1] - inputPts[iPts]) && + mathZero(inputPts[iPts + 1] - inputPts[iPts + 2])) { + if (inputCmds[iCmds + 1] == PathCommand::CubicTo && + mathZero(inputPts[iPts + 2] - inputPts[iPts + 3]) && + mathZero(inputPts[iPts + 4] - inputPts[iPts + 5])) { + _roundCorner(cmds, pts, prev, curr, inputPts[iPts + 5], roundness); + iPts += 3; + break; + } else if (inputCmds[iCmds + 1] == PathCommand::Close) { + _roundCorner(cmds, pts, prev, curr, inputPts[2], roundness); + pts[startIndex] = pts.last(); + iPts += 3; + break; + } + } + cmds.push(PathCommand::CubicTo); + pts.push(inputPts[iPts++]); + pts.push(inputPts[iPts++]); + pts.push(inputPts[iPts++]); + break; + } + case PathCommand::Close: { + cmds.push(PathCommand::Close); + break; + } + default: break; + } + } + if (transform) { + for (auto i = ptsCnt; i < pts.count; ++i) + mathTransform(transform, &pts[i]); + } + return true; +} + + +template +uint32_t _bsearch(T* frames, float frameNo) +{ + int32_t low = 0; + int32_t high = int32_t(frames->count) - 1; + + while (low <= high) { + auto mid = low + (high - low) / 2; + auto frame = frames->data + mid; + if (frameNo < frame->no) high = mid - 1; + else low = mid + 1; + } + if (high < low) low = high; + if (low < 0) low = 0; + return low; +} + + +template +uint32_t _nearest(T* frames, float frameNo) +{ + if (frames) { + auto key = _bsearch(frames, frameNo); + if (key == frames->count - 1) return key; + return (fabsf(frames->data[key].no - frameNo) < fabsf(frames->data[key + 1].no - frameNo)) ? key : (key + 1); + } + return 0; +} + + +template +float _frameNo(T* frames, int32_t key) +{ + if (!frames) return 0.0f; + if (key < 0) key = 0; + if (key >= (int32_t) frames->count) key = (int32_t)(frames->count - 1); + return (*frames)[key].no; +} + + +template +float _loop(T* frames, float frameNo, LottieExpression* exp) +{ + if (frameNo >= exp->loop.in || frameNo < frames->first().no ||frameNo < frames->last().no) return frameNo; + + switch (exp->loop.mode) { + case LottieExpression::LoopMode::InCycle: { + frameNo -= frames->first().no; + return fmodf(frameNo, frames->last().no - frames->first().no) + (*frames)[exp->loop.key].no; + } + case LottieExpression::LoopMode::OutCycle: { + frameNo -= frames->first().no; + return fmodf(frameNo, (*frames)[frames->count - 1 - exp->loop.key].no - frames->first().no) + frames->first().no; + } + default: break; + } + return frameNo; +} + + +template +struct LottieGenericProperty : LottieProperty +{ + //Property has an either keyframes or single value. + Array>* frames = nullptr; + T value; + + LottieGenericProperty(T v) : value(v) {} + LottieGenericProperty() {} + + ~LottieGenericProperty() + { + release(); + } + + void release() + { + delete(frames); + frames = nullptr; + if (exp) { + delete(exp); + exp = nullptr; + } + } + + uint32_t nearest(float frameNo) override + { + return _nearest(frames, frameNo); + } + + uint32_t frameCnt() override + { + return frames ? frames->count : 1; + } + + float frameNo(int32_t key) override + { + return _frameNo(frames, key); + } + + LottieScalarFrame& newFrame() + { + if (!frames) frames = new Array>; + if (frames->count + 1 >= frames->reserved) { + auto old = frames->reserved; + frames->grow(frames->count + 2); + memset((void*)(frames->data + old), 0x00, sizeof(LottieScalarFrame) * (frames->reserved - old)); + } + ++frames->count; + return frames->last(); + } + + LottieScalarFrame& nextFrame() + { + return (*frames)[frames->count]; + } + + T operator()(float frameNo) + { + if (!frames) return value; + if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value; + if (frameNo >= frames->last().no) return frames->last().value; + + auto frame = frames->data + _bsearch(frames, frameNo); + if (mathEqual(frame->no, frameNo)) return frame->value; + return frame->interpolate(frame + 1, frameNo); + } + + T operator()(float frameNo, LottieExpressions* exps) + { + if (exps && (exp && exp->enabled)) { + T out{}; + if (exp->loop.mode != LottieExpression::LoopMode::None) frameNo = _loop(frames, frameNo, exp); + if (exps->result>(frameNo, out, exp)) return out; + } + return operator()(frameNo); + } + + T& operator=(const T& other) + { + //shallow copy, used for slot overriding + if (other.frames) { + frames = other.frames; + const_cast(other).frames = nullptr; + } else value = other.value; + return *this; + } + + float angle(float frameNo) { return 0; } + void prepare() {} +}; + + +struct LottiePathSet : LottieProperty +{ + Array>* frames = nullptr; + PathSet value; + + ~LottiePathSet() + { + release(); + } + + void release() + { + if (exp) { + delete(exp); + exp = nullptr; + } + + free(value.cmds); + free(value.pts); + + if (!frames) return; + + for (auto p = frames->begin(); p < frames->end(); ++p) { + free((*p).value.cmds); + free((*p).value.pts); + } + free(frames->data); + free(frames); + } + + uint32_t nearest(float frameNo) override + { + return _nearest(frames, frameNo); + } + + uint32_t frameCnt() override + { + return frames ? frames->count : 1; + } + + float frameNo(int32_t key) override + { + return _frameNo(frames, key); + } + + LottieScalarFrame& newFrame() + { + if (!frames) { + frames = static_cast>*>(calloc(1, sizeof(Array>))); + } + if (frames->count + 1 >= frames->reserved) { + auto old = frames->reserved; + frames->grow(frames->count + 2); + memset((void*)(frames->data + old), 0x00, sizeof(LottieScalarFrame) * (frames->reserved - old)); + } + ++frames->count; + return frames->last(); + } + + LottieScalarFrame& nextFrame() + { + return (*frames)[frames->count]; + } + + bool operator()(float frameNo, Array& cmds, Array& pts, Matrix* transform, float roundness) + { + PathSet* path = nullptr; + LottieScalarFrame* frame = nullptr; + float t; + bool interpolate = false; + + if (!frames) path = &value; + else if (frames->count == 1 || frameNo <= frames->first().no) path = &frames->first().value; + else if (frameNo >= frames->last().no) path = &frames->last().value; + else { + frame = frames->data + _bsearch(frames, frameNo); + if (mathEqual(frame->no, frameNo)) path = &frame->value; + else { + t = (frameNo - frame->no) / ((frame + 1)->no - frame->no); + if (frame->interpolator) t = frame->interpolator->progress(t); + if (frame->hold) path = &(frame + ((t < 1.0f) ? 0 : 1))->value; + else interpolate = true; + } + } + + if (!interpolate) { + if (roundness > ROUNDNESS_EPSILON) return _modifier(path->pts, path->ptsCnt, path->cmds, path->cmdsCnt, cmds, pts, transform, roundness); + _copy(path, cmds); + _copy(path, pts, transform); + return true; + } + + auto s = frame->value.pts; + auto e = (frame + 1)->value.pts; + + if (roundness > ROUNDNESS_EPSILON) { + auto interpPts = (Point*)malloc(frame->value.ptsCnt * sizeof(Point)); + auto p = interpPts; + for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e, ++p) { + *p = mathLerp(*s, *e, t); + if (transform) mathMultiply(p, transform); + } + _modifier(interpPts, frame->value.ptsCnt, frame->value.cmds, frame->value.cmdsCnt, cmds, pts, nullptr, roundness); + free(interpPts); + return true; + } else { + for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e) { + auto pt = mathLerp(*s, *e, t); + if (transform) mathMultiply(&pt, transform); + pts.push(pt); + } + _copy(&frame->value, cmds); + } + return true; + } + + + bool operator()(float frameNo, Array& cmds, Array& pts, Matrix* transform, float roundness, LottieExpressions* exps) + { + if (exps && (exp && exp->enabled)) { + if (exp->loop.mode != LottieExpression::LoopMode::None) frameNo = _loop(frames, frameNo, exp); + if (exps->result(frameNo, cmds, pts, transform, roundness, exp)) return true; + } + return operator()(frameNo, cmds, pts, transform, roundness); + } + + void prepare() {} +}; + + +struct LottieColorStop : LottieProperty +{ + Array>* frames = nullptr; + ColorStop value; + uint16_t count = 0; //colorstop count + bool populated = false; + + ~LottieColorStop() + { + release(); + } + + void release() + { + if (exp) { + delete(exp); + exp = nullptr; + } + + if (value.data) { + free(value.data); + value.data = nullptr; + } + + if (!frames) return; + + for (auto p = frames->begin(); p < frames->end(); ++p) { + free((*p).value.data); + } + free(frames->data); + free(frames); + frames = nullptr; + } + + uint32_t nearest(float frameNo) override + { + return _nearest(frames, frameNo); + } + + uint32_t frameCnt() override + { + return frames ? frames->count : 1; + } + + float frameNo(int32_t key) override + { + return _frameNo(frames, key); + } + + LottieScalarFrame& newFrame() + { + if (!frames) { + frames = static_cast>*>(calloc(1, sizeof(Array>))); + } + if (frames->count + 1 >= frames->reserved) { + auto old = frames->reserved; + frames->grow(frames->count + 2); + memset((void*)(frames->data + old), 0x00, sizeof(LottieScalarFrame) * (frames->reserved - old)); + } + ++frames->count; + return frames->last(); + } + + LottieScalarFrame& nextFrame() + { + return (*frames)[frames->count]; + } + + Result operator()(float frameNo, Fill* fill, LottieExpressions* exps) + { + if (exps && (exp && exp->enabled)) { + if (exp->loop.mode != LottieExpression::LoopMode::None) frameNo = _loop(frames, frameNo, exp); + if (exps->result(frameNo, fill, exp)) return Result::Success; + } + + if (!frames) return fill->colorStops(value.data, count); + + if (frames->count == 1 || frameNo <= frames->first().no) { + return fill->colorStops(frames->first().value.data, count); + } + + if (frameNo >= frames->last().no) return fill->colorStops(frames->last().value.data, count); + + auto frame = frames->data + _bsearch(frames, frameNo); + if (mathEqual(frame->no, frameNo)) return fill->colorStops(frame->value.data, count); + + //interpolate + auto t = (frameNo - frame->no) / ((frame + 1)->no - frame->no); + if (frame->interpolator) t = frame->interpolator->progress(t); + + if (frame->hold) { + if (t < 1.0f) fill->colorStops(frame->value.data, count); + else fill->colorStops((frame + 1)->value.data, count); + } + + auto s = frame->value.data; + auto e = (frame + 1)->value.data; + + Array result; + + for (auto i = 0; i < count; ++i, ++s, ++e) { + auto offset = mathLerp(s->offset, e->offset, t); + auto r = mathLerp(s->r, e->r, t); + auto g = mathLerp(s->g, e->g, t); + auto b = mathLerp(s->b, e->b, t); + auto a = mathLerp(s->a, e->a, t); + result.push({offset, r, g, b, a}); + } + return fill->colorStops(result.data, count); + } + + LottieColorStop& operator=(const LottieColorStop& other) + { + //shallow copy, used for slot overriding + if (other.frames) { + frames = other.frames; + const_cast(other).frames = nullptr; + } else { + value = other.value; + const_cast(other).value = {nullptr, nullptr}; + } + populated = other.populated; + count = other.count; + + return *this; + } + + void prepare() {} +}; + + +struct LottiePosition : LottieProperty +{ + Array>* frames = nullptr; + Point value; + + LottiePosition(Point v) : value(v) + { + } + + ~LottiePosition() + { + release(); + } + + void release() + { + delete(frames); + frames = nullptr; + + if (exp) { + delete(exp); + exp = nullptr; + } + } + + uint32_t nearest(float frameNo) override + { + return _nearest(frames, frameNo); + } + + uint32_t frameCnt() override + { + return frames ? frames->count : 1; + } + + float frameNo(int32_t key) override + { + return _frameNo(frames, key); + } + + LottieVectorFrame& newFrame() + { + if (!frames) frames = new Array>; + if (frames->count + 1 >= frames->reserved) { + auto old = frames->reserved; + frames->grow(frames->count + 2); + memset((void*)(frames->data + old), 0x00, sizeof(LottieVectorFrame) * (frames->reserved - old)); + } + ++frames->count; + return frames->last(); + } + + LottieVectorFrame& nextFrame() + { + return (*frames)[frames->count]; + } + + Point operator()(float frameNo) + { + if (!frames) return value; + if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value; + if (frameNo >= frames->last().no) return frames->last().value; + + auto frame = frames->data + _bsearch(frames, frameNo); + if (mathEqual(frame->no, frameNo)) return frame->value; + return frame->interpolate(frame + 1, frameNo); + } + + Point operator()(float frameNo, LottieExpressions* exps) + { + Point out{}; + if (exps && (exp && exp->enabled)) { + if (exp->loop.mode != LottieExpression::LoopMode::None) frameNo = _loop(frames, frameNo, exp); + if (exps->result(frameNo, out, exp)) return out; + } + return operator()(frameNo); + } + + float angle(float frameNo) + { + if (!frames) return 0; + if (frames->count == 1 || frameNo <= frames->first().no) return 0; + if (frameNo >= frames->last().no) return 0; + + auto frame = frames->data + _bsearch(frames, frameNo); + return frame->angle(frame + 1, frameNo); + } + + void prepare() + { + if (!frames || frames->count < 2) return; + for (auto frame = frames->begin() + 1; frame < frames->end(); ++frame) { + (frame - 1)->prepare(frame); + } + } +}; + + +struct LottieTextDoc : LottieProperty +{ + Array>* frames = nullptr; + TextDocument value; + + ~LottieTextDoc() + { + release(); + } + + void release() + { + if (exp) { + delete(exp); + exp = nullptr; + } + + if (value.text) { + free(value.text); + value.text = nullptr; + } + if (value.name) { + free(value.name); + value.name = nullptr; + } + + if (!frames) return; + + for (auto p = frames->begin(); p < frames->end(); ++p) { + free((*p).value.text); + free((*p).value.name); + } + delete(frames); + frames = nullptr; + } + + uint32_t nearest(float frameNo) override + { + return _nearest(frames, frameNo); + } + + uint32_t frameCnt() override + { + return frames ? frames->count : 1; + } + + float frameNo(int32_t key) override + { + return _frameNo(frames, key); + } + + LottieScalarFrame& newFrame() + { + if (!frames) frames = new Array>; + if (frames->count + 1 >= frames->reserved) { + auto old = frames->reserved; + frames->grow(frames->count + 2); + memset((void*)(frames->data + old), 0x00, sizeof(LottieScalarFrame) * (frames->reserved - old)); + } + ++frames->count; + return frames->last(); + } + + LottieScalarFrame& nextFrame() + { + return (*frames)[frames->count]; + } + + TextDocument& operator()(float frameNo) + { + if (!frames) return value; + if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value; + if (frameNo >= frames->last().no) return frames->last().value; + + auto frame = frames->data + _bsearch(frames, frameNo); + return frame->value; + } + + LottieTextDoc& operator=(const LottieTextDoc& other) + { + //shallow copy, used for slot overriding + if (other.frames) { + frames = other.frames; + const_cast(other).frames = nullptr; + } else { + value = other.value; + const_cast(other).value.text = nullptr; + const_cast(other).value.name = nullptr; + } + return *this; + } + + void prepare() {} +}; + + +using LottiePoint = LottieGenericProperty; +using LottieFloat = LottieGenericProperty; +using LottieOpacity = LottieGenericProperty; +using LottieColor = LottieGenericProperty; + +#endif //_TVG_LOTTIE_PROPERTY_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgMath.cpp b/test/include/liblvgl/libs/thorvg/tvgMath.cpp new file mode 100644 index 00000000..509a459d --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgMath.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" + + +bool mathInverse(const Matrix* m, Matrix* out) +{ + auto det = m->e11 * (m->e22 * m->e33 - m->e32 * m->e23) - + m->e12 * (m->e21 * m->e33 - m->e23 * m->e31) + + m->e13 * (m->e21 * m->e32 - m->e22 * m->e31); + + if (mathZero(det)) return false; + + auto invDet = 1 / det; + + out->e11 = (m->e22 * m->e33 - m->e32 * m->e23) * invDet; + out->e12 = (m->e13 * m->e32 - m->e12 * m->e33) * invDet; + out->e13 = (m->e12 * m->e23 - m->e13 * m->e22) * invDet; + out->e21 = (m->e23 * m->e31 - m->e21 * m->e33) * invDet; + out->e22 = (m->e11 * m->e33 - m->e13 * m->e31) * invDet; + out->e23 = (m->e21 * m->e13 - m->e11 * m->e23) * invDet; + out->e31 = (m->e21 * m->e32 - m->e31 * m->e22) * invDet; + out->e32 = (m->e31 * m->e12 - m->e11 * m->e32) * invDet; + out->e33 = (m->e11 * m->e22 - m->e21 * m->e12) * invDet; + + return true; +} + + +Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs) +{ + Matrix m; + + m.e11 = lhs->e11 * rhs->e11 + lhs->e12 * rhs->e21 + lhs->e13 * rhs->e31; + m.e12 = lhs->e11 * rhs->e12 + lhs->e12 * rhs->e22 + lhs->e13 * rhs->e32; + m.e13 = lhs->e11 * rhs->e13 + lhs->e12 * rhs->e23 + lhs->e13 * rhs->e33; + + m.e21 = lhs->e21 * rhs->e11 + lhs->e22 * rhs->e21 + lhs->e23 * rhs->e31; + m.e22 = lhs->e21 * rhs->e12 + lhs->e22 * rhs->e22 + lhs->e23 * rhs->e32; + m.e23 = lhs->e21 * rhs->e13 + lhs->e22 * rhs->e23 + lhs->e23 * rhs->e33; + + m.e31 = lhs->e31 * rhs->e11 + lhs->e32 * rhs->e21 + lhs->e33 * rhs->e31; + m.e32 = lhs->e31 * rhs->e12 + lhs->e32 * rhs->e22 + lhs->e33 * rhs->e32; + m.e33 = lhs->e31 * rhs->e13 + lhs->e32 * rhs->e23 + lhs->e33 * rhs->e33; + + return m; +} + + +void mathRotate(Matrix* m, float degree) +{ + if (degree == 0.0f) return; + + auto radian = degree / 180.0f * MATH_PI; + auto cosVal = cosf(radian); + auto sinVal = sinf(radian); + + m->e12 = m->e11 * -sinVal; + m->e11 *= cosVal; + m->e21 = m->e22 * sinVal; + m->e22 *= cosVal; +} + + +bool mathIdentity(const Matrix* m) +{ + if (m->e11 != 1.0f || m->e12 != 0.0f || m->e13 != 0.0f || + m->e21 != 0.0f || m->e22 != 1.0f || m->e23 != 0.0f || + m->e31 != 0.0f || m->e32 != 0.0f || m->e33 != 1.0f) { + return false; + } + return true; +} + + +void mathMultiply(Point* pt, const Matrix* transform) +{ + auto tx = pt->x * transform->e11 + pt->y * transform->e12 + transform->e13; + auto ty = pt->x * transform->e21 + pt->y * transform->e22 + transform->e23; + pt->x = tx; + pt->y = ty; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgMath.h b/test/include/liblvgl/libs/thorvg/tvgMath.h new file mode 100644 index 00000000..49bbe186 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgMath.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_MATH_H_ +#define _TVG_MATH_H_ + + #define _USE_MATH_DEFINES + +#include +#include +#include "tvgCommon.h" + +#define MATH_PI 3.14159265358979323846f +#define MATH_PI2 1.57079632679489661923f +#define FLOAT_EPSILON 1.0e-06f //1.192092896e-07f +#define PATH_KAPPA 0.552284f + +#define mathMin(x, y) (((x) < (y)) ? (x) : (y)) +#define mathMax(x, y) (((x) > (y)) ? (x) : (y)) + + +bool mathInverse(const Matrix* m, Matrix* out); +Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs); +void mathRotate(Matrix* m, float degree); +bool mathIdentity(const Matrix* m); +void mathMultiply(Point* pt, const Matrix* transform); + + +static inline float mathDeg2Rad(float degree) +{ + return degree * (MATH_PI / 180.0f); +} + + +static inline float mathRad2Deg(float radian) +{ + return radian * (180.0f / MATH_PI); +} + + +static inline bool mathZero(float a) +{ + return (fabsf(a) <= FLOAT_EPSILON) ? true : false; +} + + +static inline bool mathZero(const Point& p) +{ + return mathZero(p.x) && mathZero(p.y); +} + + +static inline bool mathEqual(float a, float b) +{ + return mathZero(a - b); +} + + +static inline bool mathEqual(const Matrix& a, const Matrix& b) +{ + if (!mathEqual(a.e11, b.e11) || !mathEqual(a.e12, b.e12) || !mathEqual(a.e13, b.e13) || + !mathEqual(a.e21, b.e21) || !mathEqual(a.e22, b.e22) || !mathEqual(a.e23, b.e23) || + !mathEqual(a.e31, b.e31) || !mathEqual(a.e32, b.e32) || !mathEqual(a.e33, b.e33)) { + return false; + } + return true; +} + + +static inline bool mathRightAngle(const Matrix* m) +{ + auto radian = fabsf(atan2f(m->e21, m->e11)); + if (radian < FLOAT_EPSILON || mathEqual(radian, MATH_PI2) || mathEqual(radian, MATH_PI)) return true; + return false; +} + + +static inline bool mathSkewed(const Matrix* m) +{ + return !mathZero(m->e21 + m->e12); +} + + +static inline void mathIdentity(Matrix* m) +{ + m->e11 = 1.0f; + m->e12 = 0.0f; + m->e13 = 0.0f; + m->e21 = 0.0f; + m->e22 = 1.0f; + m->e23 = 0.0f; + m->e31 = 0.0f; + m->e32 = 0.0f; + m->e33 = 1.0f; +} + + +static inline void mathTransform(Matrix* transform, Point* coord) +{ + auto x = coord->x; + auto y = coord->y; + coord->x = x * transform->e11 + y * transform->e12 + transform->e13; + coord->y = x * transform->e21 + y * transform->e22 + transform->e23; +} + + +static inline void mathScale(Matrix* m, float sx, float sy) +{ + m->e11 *= sx; + m->e22 *= sy; +} + + +static inline void mathScaleR(Matrix* m, float x, float y) +{ + if (x != 1.0f) { + m->e11 *= x; + m->e21 *= x; + } + if (y != 1.0f) { + m->e22 *= y; + m->e12 *= y; + } +} + + +static inline void mathTranslate(Matrix* m, float x, float y) +{ + m->e13 += x; + m->e23 += y; +} + + +static inline void mathTranslateR(Matrix* m, float x, float y) +{ + if (x == 0.0f && y == 0.0f) return; + m->e13 += (x * m->e11 + y * m->e12); + m->e23 += (x * m->e21 + y * m->e22); +} + + +static inline void mathLog(Matrix* m) +{ + TVGLOG("MATH", "Matrix: [%f %f %f] [%f %f %f] [%f %f %f]", m->e11, m->e12, m->e13, m->e21, m->e22, m->e23, m->e31, m->e32, m->e33); +} + + +static inline float mathLength(const Point* a, const Point* b) +{ + auto x = b->x - a->x; + auto y = b->y - a->y; + + if (x < 0) x = -x; + if (y < 0) y = -y; + + return (x > y) ? (x + 0.375f * y) : (y + 0.375f * x); +} + + +static inline float mathLength(const Point& a) +{ + return sqrtf(a.x * a.x + a.y * a.y); +} + + +static inline Point operator-(const Point& lhs, const Point& rhs) +{ + return {lhs.x - rhs.x, lhs.y - rhs.y}; +} + + +static inline Point operator+(const Point& lhs, const Point& rhs) +{ + return {lhs.x + rhs.x, lhs.y + rhs.y}; +} + + +static inline Point operator*(const Point& lhs, float rhs) +{ + return {lhs.x * rhs, lhs.y * rhs}; +} + + +static inline Point operator*(const float& lhs, const Point& rhs) +{ + return {lhs * rhs.x, lhs * rhs.y}; +} + + +static inline Point operator/(const Point& lhs, const float rhs) +{ + return {lhs.x / rhs, lhs.y / rhs}; +} + + +template +static inline T mathLerp(const T &start, const T &end, float t) +{ + return static_cast(start + (end - start) * t); +} + + +#endif //_TVG_MATH_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgPaint.cpp b/test/include/liblvgl/libs/thorvg/tvgPaint.cpp new file mode 100644 index 00000000..a2f4c628 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgPaint.cpp @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" +#include "tvgPaint.h" +#include "tvgShape.h" +#include "tvgPicture.h" +#include "tvgScene.h" +#include "tvgText.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +#define PAINT_METHOD(ret, METHOD) \ + switch (id) { \ + case TVG_CLASS_ID_SHAPE: ret = P((Shape*)paint)->METHOD; break; \ + case TVG_CLASS_ID_SCENE: ret = P((Scene*)paint)->METHOD; break; \ + case TVG_CLASS_ID_PICTURE: ret = P((Picture*)paint)->METHOD; break; \ + case TVG_CLASS_ID_TEXT: ret = P((Text*)paint)->METHOD; break; \ + default: ret = {}; \ + } + + + +static Result _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport) +{ + /* Access Shape class by Paint is bad... but it's ok still it's an internal usage. */ + auto shape = static_cast(cmpTarget); + + //Rectangle Candidates? + const Point* pts; + auto ptsCnt = shape->pathCoords(&pts); + + //nothing to clip + if (ptsCnt == 0) return Result::InvalidArguments; + + if (ptsCnt != 4) return Result::InsufficientCondition; + + if (rTransform) rTransform->update(); + + //No rotation and no skewing + if (pTransform && (!mathRightAngle(&pTransform->m) || mathSkewed(&pTransform->m))) return Result::InsufficientCondition; + if (rTransform && (!mathRightAngle(&rTransform->m) || mathSkewed(&rTransform->m))) return Result::InsufficientCondition; + + //Perpendicular Rectangle? + auto pt1 = pts + 0; + auto pt2 = pts + 1; + auto pt3 = pts + 2; + auto pt4 = pts + 3; + + if ((mathEqual(pt1->x, pt2->x) && mathEqual(pt2->y, pt3->y) && mathEqual(pt3->x, pt4->x) && mathEqual(pt1->y, pt4->y)) || + (mathEqual(pt2->x, pt3->x) && mathEqual(pt1->y, pt2->y) && mathEqual(pt1->x, pt4->x) && mathEqual(pt3->y, pt4->y))) { + + auto v1 = *pt1; + auto v2 = *pt3; + + if (rTransform) { + mathMultiply(&v1, &rTransform->m); + mathMultiply(&v2, &rTransform->m); + } + + if (pTransform) { + mathMultiply(&v1, &pTransform->m); + mathMultiply(&v2, &pTransform->m); + } + + //sorting + if (v1.x > v2.x) { + auto tmp = v2.x; + v2.x = v1.x; + v1.x = tmp; + } + + if (v1.y > v2.y) { + auto tmp = v2.y; + v2.y = v1.y; + v1.y = tmp; + } + + viewport.x = static_cast(v1.x); + viewport.y = static_cast(v1.y); + viewport.w = static_cast(ceil(v2.x - viewport.x)); + viewport.h = static_cast(ceil(v2.y - viewport.y)); + + if (viewport.w < 0) viewport.w = 0; + if (viewport.h < 0) viewport.h = 0; + + return Result::Success; + } + return Result::InsufficientCondition; +} + + +RenderRegion Paint::Impl::bounds(RenderMethod* renderer) const +{ + RenderRegion ret; + PAINT_METHOD(ret, bounds(renderer)); + return ret; +} + + +Iterator* Paint::Impl::iterator() +{ + Iterator* ret; + PAINT_METHOD(ret, iterator()); + return ret; +} + + +Paint* Paint::Impl::duplicate() +{ + Paint* ret; + PAINT_METHOD(ret, duplicate()); + + //duplicate Transform + if (rTransform) { + ret->pImpl->rTransform = new RenderTransform(); + *ret->pImpl->rTransform = *rTransform; + ret->pImpl->renderFlag |= RenderUpdateFlag::Transform; + } + + ret->pImpl->opacity = opacity; + + if (compData) ret->pImpl->composite(ret, compData->target->duplicate(), compData->method); + + return ret; +} + + +bool Paint::Impl::rotate(float degree) +{ + if (rTransform) { + if (mathEqual(degree, rTransform->degree)) return true; + } else { + if (mathZero(degree)) return true; + rTransform = new RenderTransform(); + } + rTransform->degree = degree; + if (!rTransform->overriding) renderFlag |= RenderUpdateFlag::Transform; + + return true; +} + + +bool Paint::Impl::scale(float factor) +{ + if (rTransform) { + if (mathEqual(factor, rTransform->scale)) return true; + } else { + if (mathEqual(factor, 1.0f)) return true; + rTransform = new RenderTransform(); + } + rTransform->scale = factor; + if (!rTransform->overriding) renderFlag |= RenderUpdateFlag::Transform; + + return true; +} + + +bool Paint::Impl::translate(float x, float y) +{ + if (rTransform) { + if (mathEqual(x, rTransform->x) && mathEqual(y, rTransform->y)) return true; + } else { + if (mathZero(x) && mathZero(y)) return true; + rTransform = new RenderTransform(); + } + rTransform->x = x; + rTransform->y = y; + if (!rTransform->overriding) renderFlag |= RenderUpdateFlag::Transform; + + return true; +} + + +bool Paint::Impl::render(RenderMethod* renderer) +{ + Compositor* cmp = nullptr; + + /* Note: only ClipPath is processed in update() step. + Create a composition image. */ + if (compData && compData->method != CompositeMethod::ClipPath && !(compData->target->pImpl->ctxFlag & ContextFlag::FastTrack)) { + RenderRegion region; + PAINT_METHOD(region, bounds(renderer)); + + if (MASK_REGION_MERGING(compData->method)) region.add(P(compData->target)->bounds(renderer)); + if (region.w == 0 || region.h == 0) return true; + cmp = renderer->target(region, COMPOSITE_TO_COLORSPACE(renderer, compData->method)); + if (renderer->beginComposite(cmp, CompositeMethod::None, 255)) { + compData->target->pImpl->render(renderer); + } + } + + if (cmp) renderer->beginComposite(cmp, compData->method, compData->target->pImpl->opacity); + + renderer->blend(blendMethod); + + bool ret; + PAINT_METHOD(ret, render(renderer)); + + if (cmp) renderer->endComposite(cmp); + + return ret; +} + + +RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) +{ + if (this->renderer != renderer) { + if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!"); + renderer->ref(); + this->renderer = renderer; + } + + if (renderFlag & RenderUpdateFlag::Transform) { + if (!rTransform) return nullptr; + rTransform->update(); + } + + /* 1. Composition Pre Processing */ + RenderData trd = nullptr; //composite target render data + RenderRegion viewport; + Result compFastTrack = Result::InsufficientCondition; + bool childClipper = false; + + if (compData) { + auto target = compData->target; + auto method = compData->method; + target->pImpl->ctxFlag &= ~ContextFlag::FastTrack; //reset + + /* If the transformation has no rotational factors and the ClipPath/Alpha(InvAlpha)Masking involves a simple rectangle, + we can optimize by using the viewport instead of the regular ClipPath/AlphaMasking sequence for improved performance. */ + auto tryFastTrack = false; + if (target->identifier() == TVG_CLASS_ID_SHAPE) { + if (method == CompositeMethod::ClipPath) tryFastTrack = true; + else { + auto shape = static_cast(target); + uint8_t a; + shape->fillColor(nullptr, nullptr, nullptr, &a); + //no gradient fill & no compositions of the composition target. + if (!shape->fill() && !(PP(shape)->compData)) { + if (method == CompositeMethod::AlphaMask && a == 255 && PP(shape)->opacity == 255) tryFastTrack = true; + else if (method == CompositeMethod::InvAlphaMask && (a == 0 || PP(shape)->opacity == 0)) tryFastTrack = true; + } + } + if (tryFastTrack) { + RenderRegion viewport2; + if (target->composite(nullptr) != CompositeMethod::ClipPath && + (compFastTrack = _compFastTrack(target, pTransform, target->pImpl->rTransform, viewport2)) == Result::Success) { + viewport = renderer->viewport(); + viewport2.intersect(viewport); + renderer->viewport(viewport2); + target->pImpl->ctxFlag |= ContextFlag::FastTrack; + } + } + } + if (compFastTrack == Result::InsufficientCondition) { + childClipper = compData->method == CompositeMethod::ClipPath ? true : false; + trd = target->pImpl->update(renderer, pTransform, clips, 255, pFlag, childClipper); + if (childClipper) clips.push(trd); + } + } + + /* 2. Main Update */ + auto newFlag = static_cast(pFlag | renderFlag); + renderFlag = RenderUpdateFlag::None; + opacity = MULTIPLY(opacity, this->opacity); + + RenderData rd = nullptr; + RenderTransform outTransform(pTransform, rTransform); + PAINT_METHOD(rd, update(renderer, &outTransform, clips, opacity, newFlag, clipper)); + + /* 3. Composition Post Processing */ + if (compFastTrack == Result::Success) renderer->viewport(viewport); + else if (childClipper) clips.pop(); + + return rd; +} + + +bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking) +{ + Matrix* m = nullptr; + bool ret; + + //Case: No transformed, quick return! + if (!transformed || !(m = this->transform())) { + PAINT_METHOD(ret, bounds(x, y, w, h, stroking)); + return ret; + } + + //Case: Transformed + auto tx = 0.0f; + auto ty = 0.0f; + auto tw = 0.0f; + auto th = 0.0f; + + PAINT_METHOD(ret, bounds(&tx, &ty, &tw, &th, stroking)); + + //Get vertices + Point pt[4] = {{tx, ty}, {tx + tw, ty}, {tx + tw, ty + th}, {tx, ty + th}}; + + //New bounding box + auto x1 = FLT_MAX; + auto y1 = FLT_MAX; + auto x2 = -FLT_MAX; + auto y2 = -FLT_MAX; + + //Compute the AABB after transformation + for (int i = 0; i < 4; i++) { + mathMultiply(&pt[i], m); + + if (pt[i].x < x1) x1 = pt[i].x; + if (pt[i].x > x2) x2 = pt[i].x; + if (pt[i].y < y1) y1 = pt[i].y; + if (pt[i].y > y2) y2 = pt[i].y; + } + + if (x) *x = x1; + if (y) *y = y1; + if (w) *w = x2 - x1; + if (h) *h = y2 - y1; + + return ret; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Paint :: Paint() : pImpl(new Impl(this)) +{ +} + + +Paint :: ~Paint() +{ + delete(pImpl); +} + + +Result Paint::rotate(float degree) noexcept +{ + if (pImpl->rotate(degree)) return Result::Success; + return Result::FailedAllocation; +} + + +Result Paint::scale(float factor) noexcept +{ + if (pImpl->scale(factor)) return Result::Success; + return Result::FailedAllocation; +} + + +Result Paint::translate(float x, float y) noexcept +{ + if (pImpl->translate(x, y)) return Result::Success; + return Result::FailedAllocation; +} + + +Result Paint::transform(const Matrix& m) noexcept +{ + if (pImpl->transform(m)) return Result::Success; + return Result::FailedAllocation; +} + + +Matrix Paint::transform() noexcept +{ + auto pTransform = pImpl->transform(); + if (pTransform) return *pTransform; + return {1, 0, 0, 0, 1, 0, 0, 0, 1}; +} + + +TVG_DEPRECATED Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept +{ + return this->bounds(x, y, w, h, false); +} + + +Result Paint::bounds(float* x, float* y, float* w, float* h, bool transform) const noexcept +{ + if (pImpl->bounds(x, y, w, h, transform, true)) return Result::Success; + return Result::InsufficientCondition; +} + + +Paint* Paint::duplicate() const noexcept +{ + return pImpl->duplicate(); +} + + +Result Paint::composite(std::unique_ptr target, CompositeMethod method) noexcept +{ + auto p = target.release(); + if (pImpl->composite(this, p, method)) return Result::Success; + delete(p); + return Result::InvalidArguments; +} + + +CompositeMethod Paint::composite(const Paint** target) const noexcept +{ + if (pImpl->compData) { + if (target) *target = pImpl->compData->target; + return pImpl->compData->method; + } else { + if (target) *target = nullptr; + return CompositeMethod::None; + } +} + + +Result Paint::opacity(uint8_t o) noexcept +{ + if (pImpl->opacity == o) return Result::Success; + + pImpl->opacity = o; + pImpl->renderFlag |= RenderUpdateFlag::Color; + + return Result::Success; +} + + +uint8_t Paint::opacity() const noexcept +{ + return pImpl->opacity; +} + + +uint32_t Paint::identifier() const noexcept +{ + return pImpl->id; +} + + +Result Paint::blend(BlendMethod method) const noexcept +{ + if (pImpl->blendMethod != method) { + pImpl->blendMethod = method; + pImpl->renderFlag |= RenderUpdateFlag::Blend; + } + + return Result::Success; +} + + +BlendMethod Paint::blend() const noexcept +{ + return pImpl->blendMethod; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgPaint.h b/test/include/liblvgl/libs/thorvg/tvgPaint.h new file mode 100644 index 00000000..a3fbc074 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgPaint.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_PAINT_H_ +#define _TVG_PAINT_H_ + +#include "tvgRender.h" +#include "tvgMath.h" + +namespace tvg +{ + enum ContextFlag : uint8_t {Invalid = 0, FastTrack = 1}; + + struct Iterator + { + virtual ~Iterator() {} + virtual const Paint* next() = 0; + virtual uint32_t count() = 0; + virtual void begin() = 0; + }; + + struct Composite + { + Paint* target; + Paint* source; + CompositeMethod method; + }; + + struct Paint::Impl + { + Paint* paint = nullptr; + RenderTransform* rTransform = nullptr; + Composite* compData = nullptr; + RenderMethod* renderer = nullptr; + BlendMethod blendMethod = BlendMethod::Normal; //uint8_t + uint8_t renderFlag = RenderUpdateFlag::None; + uint8_t ctxFlag = ContextFlag::Invalid; + uint8_t id; + uint8_t opacity = 255; + uint8_t refCnt = 0; //reference count + + Impl(Paint* pnt) : paint(pnt) {} + + ~Impl() + { + if (compData) { + if (P(compData->target)->unref() == 0) delete(compData->target); + free(compData); + } + delete(rTransform); + if (renderer && (renderer->unref() == 0)) delete(renderer); + } + + uint8_t ref() + { + if (refCnt == 255) TVGERR("RENDERER", "Corrupted reference count!"); + return ++refCnt; + } + + uint8_t unref() + { + if (refCnt == 0) TVGERR("RENDERER", "Corrupted reference count!"); + return --refCnt; + } + + bool transform(const Matrix& m) + { + if (!rTransform) { + if (mathIdentity(&m)) return true; + rTransform = new RenderTransform(); + if (!rTransform) return false; + } + rTransform->override(m); + renderFlag |= RenderUpdateFlag::Transform; + + return true; + } + + Matrix* transform() + { + if (rTransform) { + rTransform->update(); + return &rTransform->m; + } + return nullptr; + } + + bool composite(Paint* source, Paint* target, CompositeMethod method) + { + //Invalid case + if ((!target && method != CompositeMethod::None) || (target && method == CompositeMethod::None)) return false; + + if (compData) { + P(compData->target)->unref(); + if ((compData->target != target) && P(compData->target)->refCnt == 0) { + delete(compData->target); + } + //Reset scenario + if (!target && method == CompositeMethod::None) { + free(compData); + compData = nullptr; + return true; + } + } else { + if (!target && method == CompositeMethod::None) return true; + compData = static_cast(calloc(1, sizeof(Composite))); + } + P(target)->ref(); + compData->target = target; + compData->source = source; + compData->method = method; + return true; + } + + RenderRegion bounds(RenderMethod* renderer) const; + Iterator* iterator(); + bool rotate(float degree); + bool scale(float factor); + bool translate(float x, float y); + bool bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking); + RenderData update(RenderMethod* renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false); + bool render(RenderMethod* renderer); + Paint* duplicate(); + }; +} + +#endif //_TVG_PAINT_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgPicture.cpp b/test/include/liblvgl/libs/thorvg/tvgPicture.cpp new file mode 100644 index 00000000..3d7859d2 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgPicture.cpp @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgPicture.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +RenderUpdateFlag Picture::Impl::load() +{ + if (loader) { + if (paint) { + loader->sync(); + } else { + paint = loader->paint(); + if (paint) { + if (w != loader->w || h != loader->h) { + if (!resizing) { + w = loader->w; + h = loader->h; + } + loader->resize(paint, w, h); + resizing = false; + } + return RenderUpdateFlag::None; + } + } + if (!surface) { + if ((surface = loader->bitmap())) { + return RenderUpdateFlag::Image; + } + } + } + return RenderUpdateFlag::None; +} + + +bool Picture::Impl::needComposition(uint8_t opacity) +{ + //In this case, paint(scene) would try composition itself. + if (opacity < 255) return false; + + //Composition test + const Paint* target; + auto method = picture->composite(&target); + if (!target || method == tvg::CompositeMethod::ClipPath) return false; + if (target->pImpl->opacity == 255 || target->pImpl->opacity == 0) return false; + + return true; +} + + +bool Picture::Impl::render(RenderMethod* renderer) +{ + bool ret = false; + if (surface) return renderer->renderImage(rd); + else if (paint) { + Compositor* cmp = nullptr; + if (needComp) { + cmp = renderer->target(bounds(renderer), renderer->colorSpace()); + renderer->beginComposite(cmp, CompositeMethod::None, 255); + } + ret = paint->pImpl->render(renderer); + if (cmp) renderer->endComposite(cmp); + } + return ret; +} + + +bool Picture::Impl::size(float w, float h) +{ + this->w = w; + this->h = h; + resizing = true; + return true; +} + + +RenderRegion Picture::Impl::bounds(RenderMethod* renderer) +{ + if (rd) return renderer->region(rd); + if (paint) return paint->pImpl->bounds(renderer); + return {0, 0, 0, 0}; +} + + +RenderTransform Picture::Impl::resizeTransform(const RenderTransform* pTransform) +{ + //Overriding Transformation by the desired image size + auto sx = w / loader->w; + auto sy = h / loader->h; + auto scale = sx < sy ? sx : sy; + + RenderTransform tmp; + tmp.m = {scale, 0, 0, 0, scale, 0, 0, 0, 1}; + + if (!pTransform) return tmp; + else return RenderTransform(pTransform, &tmp); +} + + +Result Picture::Impl::load(ImageLoader* loader) +{ + //Same resource has been loaded. + if (this->loader == loader) { + this->loader->sharing--; //make it sure the reference counting. + return Result::Success; + } else if (this->loader) { + LoaderMgr::retrieve(this->loader); + } + + this->loader = loader; + + if (!loader->read()) return Result::Unknown; + + this->w = loader->w; + this->h = loader->h; + + return Result::Success; +} + + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Picture::Picture() : pImpl(new Impl(this)) +{ + Paint::pImpl->id = TVG_CLASS_ID_PICTURE; +} + + +Picture::~Picture() +{ + delete(pImpl); +} + + +unique_ptr Picture::gen() noexcept +{ + return unique_ptr(new Picture); +} + + +uint32_t Picture::identifier() noexcept +{ + return TVG_CLASS_ID_PICTURE; +} + + +Result Picture::load(const std::string& path) noexcept +{ + if (path.empty()) return Result::InvalidArguments; + + return pImpl->load(path); +} + + +Result Picture::load(const char* data, uint32_t size, const string& mimeType, bool copy) noexcept +{ + if (!data || size <= 0) return Result::InvalidArguments; + + return pImpl->load(data, size, mimeType, copy); +} + + +TVG_DEPRECATED Result Picture::load(const char* data, uint32_t size, bool copy) noexcept +{ + return load(data, size, "", copy); +} + + +Result Picture::load(uint32_t* data, uint32_t w, uint32_t h, bool copy) noexcept +{ + if (!data || w <= 0 || h <= 0) return Result::InvalidArguments; + + return pImpl->load(data, w, h, copy); +} + + +Result Picture::size(float w, float h) noexcept +{ + if (pImpl->size(w, h)) return Result::Success; + return Result::InsufficientCondition; +} + + +Result Picture::size(float* w, float* h) const noexcept +{ + if (!pImpl->loader) return Result::InsufficientCondition; + if (w) *w = pImpl->w; + if (h) *h = pImpl->h; + return Result::Success; +} + + +Result Picture::mesh(const Polygon* triangles, uint32_t triangleCnt) noexcept +{ + if (!triangles && triangleCnt > 0) return Result::InvalidArguments; + if (triangles && triangleCnt == 0) return Result::InvalidArguments; + + pImpl->mesh(triangles, triangleCnt); + return Result::Success; +} + + +uint32_t Picture::mesh(const Polygon** triangles) const noexcept +{ + if (triangles) *triangles = pImpl->rm.triangles; + return pImpl->rm.triangleCnt; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgPicture.h b/test/include/liblvgl/libs/thorvg/tvgPicture.h new file mode 100644 index 00000000..7c3ec540 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgPicture.h @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_PICTURE_H_ +#define _TVG_PICTURE_H_ + +#include +#include "tvgPaint.h" +#include "tvgLoader.h" + + +struct PictureIterator : Iterator +{ + Paint* paint = nullptr; + Paint* ptr = nullptr; + + PictureIterator(Paint* p) : paint(p) {} + + const Paint* next() override + { + if (!ptr) ptr = paint; + else ptr = nullptr; + return ptr; + } + + uint32_t count() override + { + if (paint) return 1; + else return 0; + } + + void begin() override + { + ptr = nullptr; + } +}; + + +struct Picture::Impl +{ + ImageLoader* loader = nullptr; + + Paint* paint = nullptr; //vector picture uses + Surface* surface = nullptr; //bitmap picture uses + RenderData rd = nullptr; //engine data + float w = 0, h = 0; + RenderMesh rm; //mesh data + Picture* picture = nullptr; + bool resizing = false; + bool needComp = false; //need composition + + RenderTransform resizeTransform(const RenderTransform* pTransform); + bool needComposition(uint8_t opacity); + bool render(RenderMethod* renderer); + bool size(float w, float h); + RenderRegion bounds(RenderMethod* renderer); + Result load(ImageLoader* ploader); + + Impl(Picture* p) : picture(p) + { + } + + ~Impl() + { + LoaderMgr::retrieve(loader); + if (surface) { + if (auto renderer = PP(picture)->renderer) { + renderer->dispose(rd); + } + } + delete(paint); + } + + RenderData update(RenderMethod* renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + { + auto flag = load(); + + if (surface) { + auto transform = resizeTransform(pTransform); + rd = renderer->prepare(surface, &rm, rd, &transform, clips, opacity, static_cast(pFlag | flag)); + } else if (paint) { + if (resizing) { + loader->resize(paint, w, h); + resizing = false; + } + needComp = needComposition(opacity) ? true : false; + rd = paint->pImpl->update(renderer, pTransform, clips, opacity, static_cast(pFlag | flag), clipper); + } + return rd; + } + + bool bounds(float* x, float* y, float* w, float* h, bool stroking) + { + if (rm.triangleCnt > 0) { + auto triangles = rm.triangles; + auto min = triangles[0].vertex[0].pt; + auto max = triangles[0].vertex[0].pt; + + for (uint32_t i = 0; i < rm.triangleCnt; ++i) { + if (triangles[i].vertex[0].pt.x < min.x) min.x = triangles[i].vertex[0].pt.x; + else if (triangles[i].vertex[0].pt.x > max.x) max.x = triangles[i].vertex[0].pt.x; + if (triangles[i].vertex[0].pt.y < min.y) min.y = triangles[i].vertex[0].pt.y; + else if (triangles[i].vertex[0].pt.y > max.y) max.y = triangles[i].vertex[0].pt.y; + + if (triangles[i].vertex[1].pt.x < min.x) min.x = triangles[i].vertex[1].pt.x; + else if (triangles[i].vertex[1].pt.x > max.x) max.x = triangles[i].vertex[1].pt.x; + if (triangles[i].vertex[1].pt.y < min.y) min.y = triangles[i].vertex[1].pt.y; + else if (triangles[i].vertex[1].pt.y > max.y) max.y = triangles[i].vertex[1].pt.y; + + if (triangles[i].vertex[2].pt.x < min.x) min.x = triangles[i].vertex[2].pt.x; + else if (triangles[i].vertex[2].pt.x > max.x) max.x = triangles[i].vertex[2].pt.x; + if (triangles[i].vertex[2].pt.y < min.y) min.y = triangles[i].vertex[2].pt.y; + else if (triangles[i].vertex[2].pt.y > max.y) max.y = triangles[i].vertex[2].pt.y; + } + if (x) *x = min.x; + if (y) *y = min.y; + if (w) *w = max.x - min.x; + if (h) *h = max.y - min.y; + } else { + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = this->w; + if (h) *h = this->h; + } + return true; + } + + Result load(const string& path) + { + if (paint || surface) return Result::InsufficientCondition; + + bool invalid; //Invalid Path + auto loader = static_cast(LoaderMgr::loader(path, &invalid)); + if (!loader) { + if (invalid) return Result::InvalidArguments; + return Result::NonSupport; + } + return load(loader); + } + + Result load(const char* data, uint32_t size, const string& mimeType, bool copy) + { + if (paint || surface) return Result::InsufficientCondition; + auto loader = static_cast(LoaderMgr::loader(data, size, mimeType, copy)); + if (!loader) return Result::NonSupport; + return load(loader); + } + + Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) + { + if (paint || surface) return Result::InsufficientCondition; + + auto loader = static_cast(LoaderMgr::loader(data, w, h, copy)); + if (!loader) return Result::FailedAllocation; + + return load(loader); + } + + void mesh(const Polygon* triangles, const uint32_t triangleCnt) + { + if (triangles && triangleCnt > 0) { + this->rm.triangleCnt = triangleCnt; + this->rm.triangles = (Polygon*)malloc(sizeof(Polygon) * triangleCnt); + memcpy(this->rm.triangles, triangles, sizeof(Polygon) * triangleCnt); + } else { + free(this->rm.triangles); + this->rm.triangles = nullptr; + this->rm.triangleCnt = 0; + } + } + + Paint* duplicate() + { + load(); + + auto ret = Picture::gen().release(); + auto dup = ret->pImpl; + + if (paint) dup->paint = paint->duplicate(); + + if (loader) { + dup->loader = loader; + ++dup->loader->sharing; + } + + dup->surface = surface; + dup->w = w; + dup->h = h; + dup->resizing = resizing; + + if (rm.triangleCnt > 0) { + dup->rm.triangleCnt = rm.triangleCnt; + dup->rm.triangles = (Polygon*)malloc(sizeof(Polygon) * rm.triangleCnt); + memcpy(dup->rm.triangles, rm.triangles, sizeof(Polygon) * rm.triangleCnt); + } + + return ret; + } + + Iterator* iterator() + { + load(); + return new PictureIterator(paint); + } + + uint32_t* data(uint32_t* w, uint32_t* h) + { + //Try it, If not loaded yet. + load(); + + if (loader) { + if (w) *w = static_cast(loader->w); + if (h) *h = static_cast(loader->h); + } else { + if (w) *w = 0; + if (h) *h = 0; + } + if (surface) return surface->buf32; + else return nullptr; + } + + RenderUpdateFlag load(); +}; + +#endif //_TVG_PICTURE_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgRawLoader.cpp b/test/include/liblvgl/libs/thorvg/tvgRawLoader.cpp new file mode 100644 index 00000000..22741412 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgRawLoader.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include +#include +#include "tvgLoader.h" +#include "tvgRawLoader.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +RawLoader::RawLoader() : ImageLoader(FileType::Raw) +{ +} + + +RawLoader::~RawLoader() +{ + if (copy) free(surface.buf32); +} + + +bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) +{ + if (!LoadModule::read()) return true; + + if (!data || w == 0 || h == 0) return false; + + this->w = (float)w; + this->h = (float)h; + this->copy = copy; + + if (copy) { + surface.buf32 = (uint32_t*)malloc(sizeof(uint32_t) * w * h); + if (!surface.buf32) return false; + memcpy((void*)surface.buf32, data, sizeof(uint32_t) * w * h); + } + else surface.buf32 = const_cast(data); + + //setup the surface + surface.stride = w; + surface.w = w; + surface.h = h; + surface.cs = ColorSpace::ARGB8888; + surface.channelSize = sizeof(uint32_t); + surface.premultiplied = true; + + return true; +} + + +bool RawLoader::read() +{ + LoadModule::read(); + + return true; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgRawLoader.h b/test/include/liblvgl/libs/thorvg/tvgRawLoader.h new file mode 100644 index 00000000..492fd534 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgRawLoader.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_RAW_LOADER_H_ +#define _TVG_RAW_LOADER_H_ + +class RawLoader : public ImageLoader +{ +public: + bool copy = false; + + RawLoader(); + ~RawLoader(); + + using LoadModule::open; + bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy); + bool read() override; +}; + + +#endif //_TVG_RAW_LOADER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgRender.cpp b/test/include/liblvgl/libs/thorvg/tvgRender.cpp new file mode 100644 index 00000000..dad20e8b --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgRender.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" +#include "tvgRender.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void RenderTransform::override(const Matrix& m) +{ + this->m = m; + overriding = true; +} + + +void RenderTransform::update() +{ + if (overriding) return; + + mathIdentity(&m); + + mathScale(&m, scale, scale); + + if (!mathZero(degree)) mathRotate(&m, degree); + + mathTranslate(&m, x, y); +} + + +RenderTransform::RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs) +{ + if (lhs && rhs) m = mathMultiply(&lhs->m, &rhs->m); + else if (lhs) m = lhs->m; + else if (rhs) m = rhs->m; + else mathIdentity(&m); +} + + +void RenderRegion::intersect(const RenderRegion& rhs) +{ + auto x1 = x + w; + auto y1 = y + h; + auto x2 = rhs.x + rhs.w; + auto y2 = rhs.y + rhs.h; + + x = (x > rhs.x) ? x : rhs.x; + y = (y > rhs.y) ? y : rhs.y; + w = ((x1 < x2) ? x1 : x2) - x; + h = ((y1 < y2) ? y1 : y2) - y; + + if (w < 0) w = 0; + if (h < 0) h = 0; +} + + +void RenderRegion::add(const RenderRegion& rhs) +{ + if (rhs.x < x) { + w += (x - rhs.x); + x = rhs.x; + } + if (rhs.y < y) { + h += (y - rhs.y); + y = rhs.y; + } + if (rhs.x + rhs.w > x + w) w = (rhs.x + rhs.w) - x; + if (rhs.y + rhs.h > y + h) h = (rhs.y + rhs.h) - y; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgRender.h b/test/include/liblvgl/libs/thorvg/tvgRender.h new file mode 100644 index 00000000..8467a910 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgRender.h @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_RENDER_H_ +#define _TVG_RENDER_H_ + +#include "tvgCommon.h" +#include "tvgArray.h" +#include "tvgLock.h" + +namespace tvg +{ + +using RenderData = void*; +using pixel_t = uint32_t; + +enum RenderUpdateFlag : uint8_t {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, Blend = 128, All = 255}; + +struct Surface; + +enum ColorSpace +{ + ABGR8888 = 0, //The channels are joined in the order: alpha, blue, green, red. Colors are alpha-premultiplied. + ARGB8888, //The channels are joined in the order: alpha, red, green, blue. Colors are alpha-premultiplied. + ABGR8888S, //The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. + ARGB8888S, //The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. + Grayscale8, //One single channel data. + Unsupported //TODO: Change to the default, At the moment, we put it in the last to align with SwCanvas::Colorspace. +}; + +struct Surface +{ + union { + pixel_t* data = nullptr; //system based data pointer + uint32_t* buf32; //for explicit 32bits channels + uint8_t* buf8; //for explicit 8bits grayscale + }; + Key key; //a reserved lock for the thread safety + uint32_t stride = 0; + uint32_t w = 0, h = 0; + ColorSpace cs = ColorSpace::Unsupported; + uint8_t channelSize = 0; + bool premultiplied = false; //Alpha-premultiplied + + Surface() + { + } + + Surface(const Surface* rhs) + { + data = rhs->data; + stride = rhs->stride; + w = rhs->w; + h = rhs->h; + cs = rhs->cs; + channelSize = rhs->channelSize; + premultiplied = rhs->premultiplied; + } + + +}; + +struct Compositor +{ + CompositeMethod method; + uint8_t opacity; +}; + +struct RenderMesh +{ + Polygon* triangles = nullptr; + uint32_t triangleCnt = 0; + + ~RenderMesh() + { + free(triangles); + } +}; + +struct RenderRegion +{ + int32_t x, y, w, h; + + void intersect(const RenderRegion& rhs); + void add(const RenderRegion& rhs); + + bool operator==(const RenderRegion& rhs) + { + if (x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h) return true; + return false; + } +}; + +struct RenderTransform +{ + Matrix m; //3x3 Matrix Elements + float x = 0.0f; + float y = 0.0f; + float degree = 0.0f; //rotation degree + float scale = 1.0f; //scale factor + bool overriding = false; //user transform? + + void update(); + void override(const Matrix& m); + + RenderTransform() {} + RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs); +}; + +struct RenderStroke +{ + float width = 0.0f; + uint8_t color[4] = {0, 0, 0, 0}; + Fill *fill = nullptr; + float* dashPattern = nullptr; + uint32_t dashCnt = 0; + float dashOffset = 0.0f; + StrokeCap cap = StrokeCap::Square; + StrokeJoin join = StrokeJoin::Bevel; + float miterlimit = 4.0f; + bool strokeFirst = false; + + struct { + float begin = 0.0f; + float end = 1.0f; + bool individual = false; + } trim; + + ~RenderStroke() + { + free(dashPattern); + delete(fill); + } +}; + +struct RenderShape +{ + struct + { + Array cmds; + Array pts; + } path; + + Fill *fill = nullptr; + RenderStroke *stroke = nullptr; + uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a + FillRule rule = FillRule::Winding; + + ~RenderShape() + { + delete(fill); + delete(stroke); + } + + void fillColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const + { + if (r) *r = color[0]; + if (g) *g = color[1]; + if (b) *b = color[2]; + if (a) *a = color[3]; + } + + float strokeWidth() const + { + if (!stroke) return 0; + return stroke->width; + } + + bool strokeTrim() const + { + if (!stroke) return false; + if (stroke->trim.begin == 0.0f && stroke->trim.end == 1.0f) return false; + if (stroke->trim.begin == 1.0f && stroke->trim.end == 0.0f) return false; + return true; + } + + bool strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const + { + if (!stroke) return false; + + if (r) *r = stroke->color[0]; + if (g) *g = stroke->color[1]; + if (b) *b = stroke->color[2]; + if (a) *a = stroke->color[3]; + + return true; + } + + const Fill* strokeFill() const + { + if (!stroke) return nullptr; + return stroke->fill; + } + + uint32_t strokeDash(const float** dashPattern, float* offset) const + { + if (!stroke) return 0; + if (dashPattern) *dashPattern = stroke->dashPattern; + if (offset) *offset = stroke->dashOffset; + return stroke->dashCnt; + } + + StrokeCap strokeCap() const + { + if (!stroke) return StrokeCap::Square; + return stroke->cap; + } + + StrokeJoin strokeJoin() const + { + if (!stroke) return StrokeJoin::Bevel; + return stroke->join; + } + + float strokeMiterlimit() const + { + if (!stroke) return 4.0f; + + return stroke->miterlimit;; + } +}; + +class RenderMethod +{ +private: + uint32_t refCnt = 0; //reference count + Key key; + +public: + uint32_t ref() + { + ScopedLock lock(key); + return (++refCnt); + } + + uint32_t unref() + { + ScopedLock lock(key); + return (--refCnt); + } + + virtual ~RenderMethod() {} + virtual RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0; + virtual RenderData prepare(const Array& scene, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; + virtual RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; + virtual bool preRender() = 0; + virtual bool renderShape(RenderData data) = 0; + virtual bool renderImage(RenderData data) = 0; + virtual bool postRender() = 0; + virtual void dispose(RenderData data) = 0; + virtual RenderRegion region(RenderData data) = 0; + virtual RenderRegion viewport() = 0; + virtual bool viewport(const RenderRegion& vp) = 0; + virtual bool blend(BlendMethod method) = 0; + virtual ColorSpace colorSpace() = 0; + virtual const Surface* mainSurface() = 0; + + virtual bool clear() = 0; + virtual bool sync() = 0; + + virtual Compositor* target(const RenderRegion& region, ColorSpace cs) = 0; + virtual bool beginComposite(Compositor* cmp, CompositeMethod method, uint8_t opacity) = 0; + virtual bool endComposite(Compositor* cmp) = 0; +}; + +static inline bool MASK_REGION_MERGING(CompositeMethod method) +{ + switch(method) { + case CompositeMethod::AlphaMask: + case CompositeMethod::InvAlphaMask: + case CompositeMethod::LumaMask: + case CompositeMethod::InvLumaMask: + case CompositeMethod::SubtractMask: + case CompositeMethod::IntersectMask: + return false; + //these might expand the rendering region + case CompositeMethod::AddMask: + case CompositeMethod::DifferenceMask: + return true; + default: + TVGERR("RENDERER", "Unsupported Composite Method! = %d", (int)method); + return false; + } +} + +static inline uint8_t CHANNEL_SIZE(ColorSpace cs) +{ + switch(cs) { + case ColorSpace::ABGR8888: + case ColorSpace::ABGR8888S: + case ColorSpace::ARGB8888: + case ColorSpace::ARGB8888S: + return sizeof(uint32_t); + case ColorSpace::Grayscale8: + return sizeof(uint8_t); + case ColorSpace::Unsupported: + default: + TVGERR("RENDERER", "Unsupported Channel Size! = %d", (int)cs); + return 0; + } +} + +static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod* renderer, CompositeMethod method) +{ + switch(method) { + case CompositeMethod::AlphaMask: + case CompositeMethod::InvAlphaMask: + case CompositeMethod::AddMask: + case CompositeMethod::DifferenceMask: + case CompositeMethod::SubtractMask: + case CompositeMethod::IntersectMask: + return ColorSpace::Grayscale8; + //TODO: Optimize Luma/InvLuma colorspace to Grayscale8 + case CompositeMethod::LumaMask: + case CompositeMethod::InvLumaMask: + return renderer->colorSpace(); + default: + TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method); + return ColorSpace::Unsupported; + } +} + +static inline uint8_t MULTIPLY(uint8_t c, uint8_t a) +{ + return (((c) * (a) + 0xff) >> 8); +} + + +} + +#endif //_TVG_RENDER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSaveModule.h b/test/include/liblvgl/libs/thorvg/tvgSaveModule.h new file mode 100644 index 00000000..abfd5381 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSaveModule.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SAVE_MODULE_H_ +#define _TVG_SAVE_MODULE_H_ + +#include "tvgIteratorAccessor.h" + +namespace tvg +{ + +class SaveModule +{ +public: + virtual ~SaveModule() {} + + virtual bool save(Paint* paint, const string& path, bool compress) = 0; + virtual bool save(Animation* animation, Paint* bg, const string& path, uint32_t quality, uint32_t fps) = 0; + virtual bool close() = 0; +}; + +} + +#endif //_TVG_SAVE_MODULE_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSaver.cpp b/test/include/liblvgl/libs/thorvg/tvgSaver.cpp new file mode 100644 index 00000000..f2a22ec6 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSaver.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgCommon.h" +#include "tvgSaveModule.h" +#include "tvgPaint.h" + +#ifdef THORVG_TVG_SAVER_SUPPORT + #include "tvgTvgSaver.h" +#endif +#ifdef THORVG_GIF_SAVER_SUPPORT + #include "tvgGifSaver.h" +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct Saver::Impl +{ + SaveModule* saveModule = nullptr; + Paint* bg = nullptr; + + ~Impl() + { + delete(saveModule); + delete(bg); + } +}; + + +static SaveModule* _find(FileType type) +{ + switch(type) { + case FileType::Tvg: { +#ifdef THORVG_TVG_SAVER_SUPPORT + return new TvgSaver; +#endif + break; + } + case FileType::Gif: { +#ifdef THORVG_GIF_SAVER_SUPPORT + return new GifSaver; +#endif + break; + } + default: { + break; + } + } + +#ifdef THORVG_LOG_ENABLED + const char *format; + switch(type) { + case FileType::Tvg: { + format = "TVG"; + break; + } + case FileType::Gif: { + format = "GIF"; + break; + } + default: { + format = "???"; + break; + } + } + TVGLOG("RENDERER", "%s format is not supported", format); +#endif + return nullptr; +} + + +static SaveModule* _find(const string& path) +{ + auto ext = path.substr(path.find_last_of(".") + 1); + if (!ext.compare("tvg")) { + return _find(FileType::Tvg); + } else if (!ext.compare("gif")) { + return _find(FileType::Gif); + } + return nullptr; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Saver::Saver() : pImpl(new Impl()) +{ +} + + +Saver::~Saver() +{ + delete(pImpl); +} + + +Result Saver::save(std::unique_ptr paint, const string& path, bool compress) noexcept +{ + auto p = paint.release(); + if (!p) return Result::MemoryCorruption; + + //Already on saving another resource. + if (pImpl->saveModule) { + if (P(p)->refCnt == 0) delete(p); + return Result::InsufficientCondition; + } + + if (auto saveModule = _find(path)) { + if (saveModule->save(p, path, compress)) { + pImpl->saveModule = saveModule; + return Result::Success; + } else { + if (P(p)->refCnt == 0) delete(p); + delete(saveModule); + return Result::Unknown; + } + } + if (P(p)->refCnt == 0) delete(p); + return Result::NonSupport; +} + + +Result Saver::background(unique_ptr paint) noexcept +{ + delete(pImpl->bg); + pImpl->bg = paint.release(); + + return Result::Success; +} + + +Result Saver::save(unique_ptr animation, const string& path, uint32_t quality, uint32_t fps) noexcept +{ + auto a = animation.release(); + if (!a) return Result::MemoryCorruption; + + //animation holds the picture, it must be 1 at the bottom. + auto remove = PP(a->picture())->refCnt <= 1 ? true : false; + + if (mathZero(a->totalFrame())) { + if (remove) delete(a); + return Result::InsufficientCondition; + } + + //Already on saving another resource. + if (pImpl->saveModule) { + if (remove) delete(a); + return Result::InsufficientCondition; + } + + if (auto saveModule = _find(path)) { + if (saveModule->save(a, pImpl->bg, path, quality, fps)) { + pImpl->saveModule = saveModule; + return Result::Success; + } else { + if (remove) delete(a); + delete(saveModule); + return Result::Unknown; + } + } + if (remove) delete(a); + return Result::NonSupport; +} + + +Result Saver::sync() noexcept +{ + if (!pImpl->saveModule) return Result::InsufficientCondition; + pImpl->saveModule->close(); + delete(pImpl->saveModule); + pImpl->saveModule = nullptr; + + return Result::Success; +} + + +unique_ptr Saver::gen() noexcept +{ + return unique_ptr(new Saver); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgScene.cpp b/test/include/liblvgl/libs/thorvg/tvgScene.cpp new file mode 100644 index 00000000..cd911f71 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgScene.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgScene.h" + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Scene::Scene() : pImpl(new Impl(this)) +{ + Paint::pImpl->id = TVG_CLASS_ID_SCENE; +} + + +Scene::~Scene() +{ + delete(pImpl); +} + + +unique_ptr Scene::gen() noexcept +{ + return unique_ptr(new Scene); +} + + +uint32_t Scene::identifier() noexcept +{ + return TVG_CLASS_ID_SCENE; +} + + +Result Scene::push(unique_ptr paint) noexcept +{ + auto p = paint.release(); + if (!p) return Result::MemoryCorruption; + PP(p)->ref(); + pImpl->paints.push_back(p); + + return Result::Success; +} + + +Result Scene::reserve(TVG_UNUSED uint32_t size) noexcept +{ + return Result::NonSupport; +} + + +Result Scene::clear(bool free) noexcept +{ + pImpl->clear(free); + + return Result::Success; +} + + +list& Scene::paints() noexcept +{ + return pImpl->paints; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgScene.h b/test/include/liblvgl/libs/thorvg/tvgScene.h new file mode 100644 index 00000000..8347d924 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgScene.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SCENE_H_ +#define _TVG_SCENE_H_ + +#include +#include "tvgPaint.h" + + +struct SceneIterator : Iterator +{ + list* paints; + list::iterator itr; + + SceneIterator(list* p) : paints(p) + { + begin(); + } + + const Paint* next() override + { + if (itr == paints->end()) return nullptr; + auto paint = *itr; + ++itr; + return paint; + } + + uint32_t count() override + { + return paints->size(); + } + + void begin() override + { + itr = paints->begin(); + } +}; + +struct Scene::Impl +{ + list paints; + RenderData rd = nullptr; + Scene* scene = nullptr; + uint8_t opacity; //for composition + bool needComp = false; //composite or not + + Impl(Scene* s) : scene(s) + { + } + + ~Impl() + { + for (auto paint : paints) { + if (P(paint)->unref() == 0) delete(paint); + } + + if (auto renderer = PP(scene)->renderer) { + renderer->dispose(rd); + } + } + + bool needComposition(uint8_t opacity) + { + if (opacity == 0 || paints.empty()) return false; + + //Masking may require composition (even if opacity == 255) + auto compMethod = scene->composite(nullptr); + if (compMethod != CompositeMethod::None && compMethod != CompositeMethod::ClipPath) return true; + + //Blending may require composition (even if opacity == 255) + if (scene->blend() != BlendMethod::Normal) return true; + + //Half translucent requires intermediate composition. + if (opacity == 255) return false; + + //If scene has several children or only scene, it may require composition. + //OPTIMIZE: the bitmap type of the picture would not need the composition. + //OPTIMIZE: a single paint of a scene would not need the composition. + if (paints.size() == 1 && paints.front()->identifier() == TVG_CLASS_ID_SHAPE) return false; + + return true; + } + + RenderData update(RenderMethod* renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flag, bool clipper) + { + if ((needComp = needComposition(opacity))) { + /* Overriding opacity value. If this scene is half-translucent, + It must do intermediate composition with that opacity value. */ + this->opacity = opacity; + opacity = 255; + } + + if (clipper) { + Array rds(paints.size()); + for (auto paint : paints) { + rds.push(paint->pImpl->update(renderer, transform, clips, opacity, flag, true)); + } + rd = renderer->prepare(rds, rd, transform, clips, opacity, flag); + return rd; + } else { + for (auto paint : paints) { + paint->pImpl->update(renderer, transform, clips, opacity, flag, false); + } + return nullptr; + } + } + + bool render(RenderMethod* renderer) + { + Compositor* cmp = nullptr; + auto ret = true; + + if (needComp) { + cmp = renderer->target(bounds(renderer), renderer->colorSpace()); + renderer->beginComposite(cmp, CompositeMethod::None, opacity); + } + + for (auto paint : paints) { + ret &= paint->pImpl->render(renderer); + } + + if (cmp) renderer->endComposite(cmp); + + return ret; + } + + RenderRegion bounds(RenderMethod* renderer) const + { + if (paints.empty()) return {0, 0, 0, 0}; + + int32_t x1 = INT32_MAX; + int32_t y1 = INT32_MAX; + int32_t x2 = 0; + int32_t y2 = 0; + + for (auto paint : paints) { + auto region = paint->pImpl->bounds(renderer); + + //Merge regions + if (region.x < x1) x1 = region.x; + if (x2 < region.x + region.w) x2 = (region.x + region.w); + if (region.y < y1) y1 = region.y; + if (y2 < region.y + region.h) y2 = (region.y + region.h); + } + + return {x1, y1, (x2 - x1), (y2 - y1)}; + } + + bool bounds(float* px, float* py, float* pw, float* ph, bool stroking) + { + if (paints.empty()) return false; + + auto x1 = FLT_MAX; + auto y1 = FLT_MAX; + auto x2 = -FLT_MAX; + auto y2 = -FLT_MAX; + + for (auto paint : paints) { + auto x = FLT_MAX; + auto y = FLT_MAX; + auto w = 0.0f; + auto h = 0.0f; + + if (!P(paint)->bounds(&x, &y, &w, &h, true, stroking)) continue; + + //Merge regions + if (x < x1) x1 = x; + if (x2 < x + w) x2 = (x + w); + if (y < y1) y1 = y; + if (y2 < y + h) y2 = (y + h); + } + + if (px) *px = x1; + if (py) *py = y1; + if (pw) *pw = (x2 - x1); + if (ph) *ph = (y2 - y1); + + return true; + } + + Paint* duplicate() + { + auto ret = Scene::gen().release(); + auto dup = ret->pImpl; + + for (auto paint : paints) { + auto cdup = paint->duplicate(); + P(cdup)->ref(); + dup->paints.push_back(cdup); + } + + return ret; + } + + void clear(bool free) + { + for (auto paint : paints) { + if (P(paint)->unref() == 0 && free) delete(paint); + } + paints.clear(); + } + + Iterator* iterator() + { + return new SceneIterator(&paints); + } +}; + +#endif //_TVG_SCENE_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgShape.cpp b/test/include/liblvgl/libs/thorvg/tvgShape.cpp new file mode 100644 index 00000000..fcf77e24 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgShape.cpp @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" +#include "tvgShape.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Shape :: Shape() : pImpl(new Impl(this)) +{ + Paint::pImpl->id = TVG_CLASS_ID_SHAPE; +} + + +Shape :: ~Shape() +{ + delete(pImpl); +} + + +unique_ptr Shape::gen() noexcept +{ + return unique_ptr(new Shape); +} + + +uint32_t Shape::identifier() noexcept +{ + return TVG_CLASS_ID_SHAPE; +} + + +Result Shape::reset() noexcept +{ + pImpl->rs.path.cmds.clear(); + pImpl->rs.path.pts.clear(); + + pImpl->flag |= RenderUpdateFlag::Path; + + return Result::Success; +} + + +uint32_t Shape::pathCommands(const PathCommand** cmds) const noexcept +{ + if (cmds) *cmds = pImpl->rs.path.cmds.data; + return pImpl->rs.path.cmds.count; +} + + +uint32_t Shape::pathCoords(const Point** pts) const noexcept +{ + if (pts) *pts = pImpl->rs.path.pts.data; + return pImpl->rs.path.pts.count; +} + + +Result Shape::appendPath(const PathCommand *cmds, uint32_t cmdCnt, const Point* pts, uint32_t ptsCnt) noexcept +{ + if (cmdCnt == 0 || ptsCnt == 0 || !cmds || !pts) return Result::InvalidArguments; + + pImpl->grow(cmdCnt, ptsCnt); + pImpl->append(cmds, cmdCnt, pts, ptsCnt); + + return Result::Success; +} + + +Result Shape::moveTo(float x, float y) noexcept +{ + pImpl->moveTo(x, y); + + return Result::Success; +} + + +Result Shape::lineTo(float x, float y) noexcept +{ + pImpl->lineTo(x, y); + + return Result::Success; +} + + +Result Shape::cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) noexcept +{ + pImpl->cubicTo(cx1, cy1, cx2, cy2, x, y); + + return Result::Success; +} + + +Result Shape::close() noexcept +{ + pImpl->close(); + + return Result::Success; +} + + +Result Shape::appendCircle(float cx, float cy, float rx, float ry) noexcept +{ + auto rxKappa = rx * PATH_KAPPA; + auto ryKappa = ry * PATH_KAPPA; + + pImpl->grow(6, 13); + pImpl->moveTo(cx + rx, cy); + pImpl->cubicTo(cx + rx, cy + ryKappa, cx + rxKappa, cy + ry, cx, cy + ry); + pImpl->cubicTo(cx - rxKappa, cy + ry, cx - rx, cy + ryKappa, cx - rx, cy); + pImpl->cubicTo(cx - rx, cy - ryKappa, cx - rxKappa, cy - ry, cx, cy - ry); + pImpl->cubicTo(cx + rxKappa, cy - ry, cx + rx, cy - ryKappa, cx + rx, cy); + pImpl->close(); + + return Result::Success; +} + +Result Shape::appendArc(float cx, float cy, float radius, float startAngle, float sweep, bool pie) noexcept +{ + //just circle + if (sweep >= 360.0f || sweep <= -360.0f) return appendCircle(cx, cy, radius, radius); + + const float arcPrecision = 1e-5f; + startAngle = mathDeg2Rad(startAngle); + sweep = mathDeg2Rad(sweep); + + auto nCurves = static_cast(fabsf(sweep / MATH_PI2)); + if (fabsf(sweep / MATH_PI2) - nCurves > arcPrecision) ++nCurves; + auto sweepSign = (sweep < 0 ? -1 : 1); + auto fract = fmodf(sweep, MATH_PI2); + fract = (fabsf(fract) < arcPrecision) ? MATH_PI2 * sweepSign : fract; + + //Start from here + Point start = {radius * cosf(startAngle), radius * sinf(startAngle)}; + + if (pie) { + pImpl->moveTo(cx, cy); + pImpl->lineTo(start.x + cx, start.y + cy); + } else { + pImpl->moveTo(start.x + cx, start.y + cy); + } + + for (int i = 0; i < nCurves; ++i) { + auto endAngle = startAngle + ((i != nCurves - 1) ? MATH_PI2 * sweepSign : fract); + Point end = {radius * cosf(endAngle), radius * sinf(endAngle)}; + + //variables needed to calculate bezier control points + + //get bezier control points using article: + //(http://itc.ktu.lt/index.php/ITC/article/view/11812/6479) + auto ax = start.x; + auto ay = start.y; + auto bx = end.x; + auto by = end.y; + auto q1 = ax * ax + ay * ay; + auto q2 = ax * bx + ay * by + q1; + auto k2 = (4.0f/3.0f) * ((sqrtf(2 * q1 * q2) - q2) / (ax * by - ay * bx)); + + start = end; //Next start point is the current end point + + end.x += cx; + end.y += cy; + + Point ctrl1 = {ax - k2 * ay + cx, ay + k2 * ax + cy}; + Point ctrl2 = {bx + k2 * by + cx, by - k2 * bx + cy}; + + pImpl->cubicTo(ctrl1.x, ctrl1.y, ctrl2.x, ctrl2.y, end.x, end.y); + + startAngle = endAngle; + } + + if (pie) pImpl->close(); + + return Result::Success; +} + + +Result Shape::appendRect(float x, float y, float w, float h, float rx, float ry) noexcept +{ + auto halfW = w * 0.5f; + auto halfH = h * 0.5f; + + //clamping cornerRadius by minimum size + if (rx > halfW) rx = halfW; + if (ry > halfH) ry = halfH; + + //rectangle + if (rx == 0 && ry == 0) { + pImpl->grow(5, 4); + pImpl->moveTo(x, y); + pImpl->lineTo(x + w, y); + pImpl->lineTo(x + w, y + h); + pImpl->lineTo(x, y + h); + pImpl->close(); + //rounded rectangle or circle + } else { + auto hrx = rx * PATH_KAPPA; + auto hry = ry * PATH_KAPPA; + pImpl->grow(10, 17); + pImpl->moveTo(x + rx, y); + pImpl->lineTo(x + w - rx, y); + pImpl->cubicTo(x + w - rx + hrx, y, x + w, y + ry - hry, x + w, y + ry); + pImpl->lineTo(x + w, y + h - ry); + pImpl->cubicTo(x + w, y + h - ry + hry, x + w - rx + hrx, y + h, x + w - rx, y + h); + pImpl->lineTo(x + rx, y + h); + pImpl->cubicTo(x + rx - hrx, y + h, x, y + h - ry + hry, x, y + h - ry); + pImpl->lineTo(x, y + ry); + pImpl->cubicTo(x, y + ry - hry, x + rx - hrx, y, x + rx, y); + pImpl->close(); + } + + return Result::Success; +} + + +Result Shape::fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept +{ + if (pImpl->rs.fill) { + delete(pImpl->rs.fill); + pImpl->rs.fill = nullptr; + pImpl->flag |= RenderUpdateFlag::Gradient; + } + + if (r == pImpl->rs.color[0] && g == pImpl->rs.color[1] && b == pImpl->rs.color[2] && a == pImpl->rs.color[3]) return Result::Success; + + pImpl->rs.color[0] = r; + pImpl->rs.color[1] = g; + pImpl->rs.color[2] = b; + pImpl->rs.color[3] = a; + pImpl->flag |= RenderUpdateFlag::Color; + + return Result::Success; +} + + +Result Shape::fill(unique_ptr f) noexcept +{ + auto p = f.release(); + if (!p) return Result::MemoryCorruption; + + if (pImpl->rs.fill && pImpl->rs.fill != p) delete(pImpl->rs.fill); + pImpl->rs.fill = p; + pImpl->flag |= RenderUpdateFlag::Gradient; + + return Result::Success; +} + + +Result Shape::fillColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept +{ + pImpl->rs.fillColor(r, g, b, a); + + return Result::Success; +} + + +const Fill* Shape::fill() const noexcept +{ + return pImpl->rs.fill; +} + + +Result Shape::order(bool strokeFirst) noexcept +{ + if (!pImpl->strokeFirst(strokeFirst)) return Result::FailedAllocation; + + return Result::Success; +} + + +Result Shape::stroke(float width) noexcept +{ + if (!pImpl->strokeWidth(width)) return Result::FailedAllocation; + + return Result::Success; +} + + +float Shape::strokeWidth() const noexcept +{ + return pImpl->rs.strokeWidth(); +} + + +Result Shape::stroke(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept +{ + if (!pImpl->strokeColor(r, g, b, a)) return Result::FailedAllocation; + + return Result::Success; +} + + +Result Shape::strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept +{ + if (!pImpl->rs.strokeColor(r, g, b, a)) return Result::InsufficientCondition; + + return Result::Success; +} + + +Result Shape::stroke(unique_ptr f) noexcept +{ + return pImpl->strokeFill(std::move(f)); +} + + +const Fill* Shape::strokeFill() const noexcept +{ + return pImpl->rs.strokeFill(); +} + + +Result Shape::stroke(const float* dashPattern, uint32_t cnt) noexcept +{ + return pImpl->strokeDash(dashPattern, cnt, 0); +} + + +uint32_t Shape::strokeDash(const float** dashPattern) const noexcept +{ + return pImpl->rs.strokeDash(dashPattern, nullptr); +} + + +Result Shape::stroke(StrokeCap cap) noexcept +{ + if (!pImpl->strokeCap(cap)) return Result::FailedAllocation; + + return Result::Success; +} + + +Result Shape::stroke(StrokeJoin join) noexcept +{ + if (!pImpl->strokeJoin(join)) return Result::FailedAllocation; + + return Result::Success; +} + +Result Shape::strokeMiterlimit(float miterlimit) noexcept +{ + // https://www.w3.org/TR/SVG2/painting.html#LineJoin + // - A negative value for stroke-miterlimit must be treated as an illegal value. + if (miterlimit < 0.0f) return Result::NonSupport; + // TODO Find out a reasonable max value. + if (!pImpl->strokeMiterlimit(miterlimit)) return Result::FailedAllocation; + + return Result::Success; +} + + +StrokeCap Shape::strokeCap() const noexcept +{ + return pImpl->rs.strokeCap(); +} + + +StrokeJoin Shape::strokeJoin() const noexcept +{ + return pImpl->rs.strokeJoin(); +} + +float Shape::strokeMiterlimit() const noexcept +{ + return pImpl->rs.strokeMiterlimit(); +} + + +Result Shape::fill(FillRule r) noexcept +{ + pImpl->rs.rule = r; + + return Result::Success; +} + + +FillRule Shape::fillRule() const noexcept +{ + return pImpl->rs.rule; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgShape.h b/test/include/liblvgl/libs/thorvg/tvgShape.h new file mode 100644 index 00000000..bb5e6f37 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgShape.h @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SHAPE_H_ +#define _TVG_SHAPE_H_ + +#include +#include "tvgMath.h" +#include "tvgPaint.h" + + +struct Shape::Impl +{ + RenderShape rs; //shape data + RenderData rd = nullptr; //engine data + Shape* shape; + uint8_t flag = RenderUpdateFlag::None; + uint8_t opacity; //for composition + bool needComp = false; //composite or not + + Impl(Shape* s) : shape(s) + { + } + + ~Impl() + { + if (auto renderer = PP(shape)->renderer) { + renderer->dispose(rd); + } + } + + bool render(RenderMethod* renderer) + { + Compositor* cmp = nullptr; + bool ret; + + if (needComp) { + cmp = renderer->target(bounds(renderer), renderer->colorSpace()); + renderer->beginComposite(cmp, CompositeMethod::None, opacity); + } + ret = renderer->renderShape(rd); + if (cmp) renderer->endComposite(cmp); + return ret; + } + + bool needComposition(uint8_t opacity) + { + if (opacity == 0) return false; + + //Shape composition is only necessary when stroking & fill are valid. + if (!rs.stroke || rs.stroke->width < FLOAT_EPSILON || (!rs.stroke->fill && rs.stroke->color[3] == 0)) return false; + if (!rs.fill && rs.color[3] == 0) return false; + + //translucent fill & stroke + if (opacity < 255) return true; + + //Composition test + const Paint* target; + auto method = shape->composite(&target); + if (!target || method == CompositeMethod::ClipPath) return false; + if (target->pImpl->opacity == 255 || target->pImpl->opacity == 0) { + if (target->identifier() == TVG_CLASS_ID_SHAPE) { + auto shape = static_cast(target); + if (!shape->fill()) { + uint8_t r, g, b, a; + shape->fillColor(&r, &g, &b, &a); + if (a == 0 || a == 255) { + if (method == CompositeMethod::LumaMask || method == CompositeMethod::InvLumaMask) { + if ((r == 255 && g == 255 && b == 255) || (r == 0 && g == 0 && b == 0)) return false; + } else return false; + } + } + } + } + + return true; + } + + RenderData update(RenderMethod* renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + { + if ((needComp = needComposition(opacity))) { + /* Overriding opacity value. If this scene is half-translucent, + It must do intermediate composition with that opacity value. */ + this->opacity = opacity; + opacity = 255; + } + + rd = renderer->prepare(rs, rd, transform, clips, opacity, static_cast(pFlag | flag), clipper); + flag = RenderUpdateFlag::None; + return rd; + } + + RenderRegion bounds(RenderMethod* renderer) + { + return renderer->region(rd); + } + + bool bounds(float* x, float* y, float* w, float* h, bool stroking) + { + //Path bounding size + if (rs.path.pts.count > 0 ) { + auto pts = rs.path.pts.begin(); + Point min = { pts->x, pts->y }; + Point max = { pts->x, pts->y }; + + for (auto pts2 = pts + 1; pts2 < rs.path.pts.end(); ++pts2) { + if (pts2->x < min.x) min.x = pts2->x; + if (pts2->y < min.y) min.y = pts2->y; + if (pts2->x > max.x) max.x = pts2->x; + if (pts2->y > max.y) max.y = pts2->y; + } + + if (x) *x = min.x; + if (y) *y = min.y; + if (w) *w = max.x - min.x; + if (h) *h = max.y - min.y; + } + + //Stroke feathering + if (stroking && rs.stroke) { + if (x) *x -= rs.stroke->width * 0.5f; + if (y) *y -= rs.stroke->width * 0.5f; + if (w) *w += rs.stroke->width; + if (h) *h += rs.stroke->width; + } + return rs.path.pts.count > 0 ? true : false; + } + + void reserveCmd(uint32_t cmdCnt) + { + rs.path.cmds.reserve(cmdCnt); + } + + void reservePts(uint32_t ptsCnt) + { + rs.path.pts.reserve(ptsCnt); + } + + void grow(uint32_t cmdCnt, uint32_t ptsCnt) + { + rs.path.cmds.grow(cmdCnt); + rs.path.pts.grow(ptsCnt); + } + + void append(const PathCommand* cmds, uint32_t cmdCnt, const Point* pts, uint32_t ptsCnt) + { + memcpy(rs.path.cmds.end(), cmds, sizeof(PathCommand) * cmdCnt); + memcpy(rs.path.pts.end(), pts, sizeof(Point) * ptsCnt); + rs.path.cmds.count += cmdCnt; + rs.path.pts.count += ptsCnt; + + flag |= RenderUpdateFlag::Path; + } + + void moveTo(float x, float y) + { + rs.path.cmds.push(PathCommand::MoveTo); + rs.path.pts.push({x, y}); + + flag |= RenderUpdateFlag::Path; + } + + void lineTo(float x, float y) + { + rs.path.cmds.push(PathCommand::LineTo); + rs.path.pts.push({x, y}); + + flag |= RenderUpdateFlag::Path; + } + + void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) + { + rs.path.cmds.push(PathCommand::CubicTo); + rs.path.pts.push({cx1, cy1}); + rs.path.pts.push({cx2, cy2}); + rs.path.pts.push({x, y}); + + flag |= RenderUpdateFlag::Path; + } + + void close() + { + //Don't close multiple times. + if (rs.path.cmds.count > 0 && rs.path.cmds.last() == PathCommand::Close) return; + + rs.path.cmds.push(PathCommand::Close); + + flag |= RenderUpdateFlag::Path; + } + + bool strokeWidth(float width) + { + if (!rs.stroke) rs.stroke = new RenderStroke(); + rs.stroke->width = width; + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + bool strokeTrim(float begin, float end, bool individual) + { + if (!rs.stroke) { + if (begin == 0.0f && end == 1.0f) return true; + rs.stroke = new RenderStroke(); + } + + if (mathEqual(rs.stroke->trim.begin, begin) && mathEqual(rs.stroke->trim.end, end)) return true; + + rs.stroke->trim.begin = begin; + rs.stroke->trim.end = end; + rs.stroke->trim.individual = individual; + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + bool strokeCap(StrokeCap cap) + { + if (!rs.stroke) rs.stroke = new RenderStroke(); + rs.stroke->cap = cap; + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + bool strokeJoin(StrokeJoin join) + { + if (!rs.stroke) rs.stroke = new RenderStroke(); + rs.stroke->join = join; + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + bool strokeMiterlimit(float miterlimit) + { + if (!rs.stroke) rs.stroke = new RenderStroke(); + rs.stroke->miterlimit = miterlimit; + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + bool strokeColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) + { + if (!rs.stroke) rs.stroke = new RenderStroke(); + if (rs.stroke->fill) { + delete(rs.stroke->fill); + rs.stroke->fill = nullptr; + flag |= RenderUpdateFlag::GradientStroke; + } + + rs.stroke->color[0] = r; + rs.stroke->color[1] = g; + rs.stroke->color[2] = b; + rs.stroke->color[3] = a; + + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + Result strokeFill(unique_ptr f) + { + auto p = f.release(); + if (!p) return Result::MemoryCorruption; + + if (!rs.stroke) rs.stroke = new RenderStroke(); + if (rs.stroke->fill && rs.stroke->fill != p) delete(rs.stroke->fill); + rs.stroke->fill = p; + + flag |= RenderUpdateFlag::Stroke; + flag |= RenderUpdateFlag::GradientStroke; + + return Result::Success; + } + + Result strokeDash(const float* pattern, uint32_t cnt, float offset) + { + if ((cnt == 1) || (!pattern && cnt > 0) || (pattern && cnt == 0)) { + return Result::InvalidArguments; + } + + for (uint32_t i = 0; i < cnt; i++) { + if (pattern[i] < FLOAT_EPSILON) return Result::InvalidArguments; + } + + //Reset dash + if (!pattern && cnt == 0) { + free(rs.stroke->dashPattern); + rs.stroke->dashPattern = nullptr; + } else { + if (!rs.stroke) rs.stroke = new RenderStroke(); + if (rs.stroke->dashCnt != cnt) { + free(rs.stroke->dashPattern); + rs.stroke->dashPattern = nullptr; + } + if (!rs.stroke->dashPattern) { + rs.stroke->dashPattern = static_cast(malloc(sizeof(float) * cnt)); + if (!rs.stroke->dashPattern) return Result::FailedAllocation; + } + for (uint32_t i = 0; i < cnt; ++i) { + rs.stroke->dashPattern[i] = pattern[i]; + } + } + rs.stroke->dashCnt = cnt; + rs.stroke->dashOffset = offset; + flag |= RenderUpdateFlag::Stroke; + + return Result::Success; + } + + bool strokeFirst() + { + if (!rs.stroke) return true; + return rs.stroke->strokeFirst; + } + + bool strokeFirst(bool strokeFirst) + { + if (!rs.stroke) rs.stroke = new RenderStroke(); + rs.stroke->strokeFirst = strokeFirst; + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + void update(RenderUpdateFlag flag) + { + this->flag |= flag; + } + + Paint* duplicate() + { + auto ret = Shape::gen().release(); + auto dup = ret->pImpl; + + dup->rs.rule = rs.rule; + + //Color + memcpy(dup->rs.color, rs.color, sizeof(rs.color)); + dup->flag = RenderUpdateFlag::Color; + + //Path + if (rs.path.cmds.count > 0 && rs.path.pts.count > 0) { + dup->rs.path.cmds = rs.path.cmds; + dup->rs.path.pts = rs.path.pts; + dup->flag |= RenderUpdateFlag::Path; + } + + //Stroke + if (rs.stroke) { + dup->rs.stroke = new RenderStroke(); + *dup->rs.stroke = *rs.stroke; + memcpy(dup->rs.stroke->color, rs.stroke->color, sizeof(rs.stroke->color)); + if (rs.stroke->dashCnt > 0) { + dup->rs.stroke->dashPattern = static_cast(malloc(sizeof(float) * rs.stroke->dashCnt)); + memcpy(dup->rs.stroke->dashPattern, rs.stroke->dashPattern, sizeof(float) * rs.stroke->dashCnt); + } + if (rs.stroke->fill) { + dup->rs.stroke->fill = rs.stroke->fill->duplicate(); + dup->flag |= RenderUpdateFlag::GradientStroke; + } + dup->flag |= RenderUpdateFlag::Stroke; + } + + //Fill + if (rs.fill) { + dup->rs.fill = rs.fill->duplicate(); + dup->flag |= RenderUpdateFlag::Gradient; + } + + return ret; + } + + Iterator* iterator() + { + return nullptr; + } +}; + +#endif //_TVG_SHAPE_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgStr.cpp b/test/include/liblvgl/libs/thorvg/tvgStr.cpp new file mode 100644 index 00000000..1838e756 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgStr.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "config.h" +#include +#include +#include +#include "tvgMath.h" +#include "tvgStr.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static inline bool _floatExact(float a, float b) +{ + return memcmp(&a, &b, sizeof(float)) == 0; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +namespace tvg { + +/* + * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtof-strtof-l-wcstof-wcstof-l?view=msvc-160 + * + * src should be one of the following form : + * + * [whitespace] [sign] {digits [radix digits] | radix digits} [{e | E} [sign] digits] + * [whitespace] [sign] {INF | INFINITY} + * [whitespace] [sign] NAN [sequence] + * + * No hexadecimal form supported + * no sequence supported after NAN + */ +float strToFloat(const char *nPtr, char **endPtr) +{ + if (endPtr) *endPtr = (char *) (nPtr); + if (!nPtr) return 0.0f; + + auto a = nPtr; + auto iter = nPtr; + auto val = 0.0f; + unsigned long long integerPart = 0; + int minus = 1; + + //ignore leading whitespaces + while (isspace(*iter)) iter++; + + //signed or not + if (*iter == '-') { + minus = -1; + iter++; + } else if (*iter == '+') { + iter++; + } + + if (tolower(*iter) == 'i') { + if ((tolower(*(iter + 1)) == 'n') && (tolower(*(iter + 2)) == 'f')) iter += 3; + else goto error; + + if (tolower(*(iter)) == 'i') { + if ((tolower(*(iter + 1)) == 'n') && (tolower(*(iter + 2)) == 'i') && (tolower(*(iter + 3)) == 't') && + (tolower(*(iter + 4)) == 'y')) + iter += 5; + else goto error; + } + if (endPtr) *endPtr = (char *) (iter); + return (minus == -1) ? -INFINITY : INFINITY; + } + + if (tolower(*iter) == 'n') { + if ((tolower(*(iter + 1)) == 'a') && (tolower(*(iter + 2)) == 'n')) iter += 3; + else goto error; + + if (endPtr) *endPtr = (char *) (iter); + return (minus == -1) ? -NAN : NAN; + } + + //Optional: integer part before dot + if (isdigit(*iter)) { + for (; isdigit(*iter); iter++) { + integerPart = integerPart * 10ULL + (unsigned long long) (*iter - '0'); + } + a = iter; + } else if (*iter != '.') { + goto success; + } + + val = static_cast(integerPart); + + //Optional: decimal part after dot + if (*iter == '.') { + unsigned long long decimalPart = 0; + unsigned long long pow10 = 1; + int count = 0; + + iter++; + + if (isdigit(*iter)) { + for (; isdigit(*iter); iter++, count++) { + if (count < 19) { + decimalPart = decimalPart * 10ULL + +static_cast(*iter - '0'); + pow10 *= 10ULL; + } + } + } else if (isspace(*iter)) { //skip if there is a space after the dot. + a = iter; + goto success; + } + + val += static_cast(decimalPart) / static_cast(pow10); + a = iter; + } + + //Optional: exponent + if (*iter == 'e' || *iter == 'E') { + ++iter; + + //Exception: svg may have 'em' unit for fonts. ex) 5em, 10.5em + if ((*iter == 'm') || (*iter == 'M')) { + //TODO: We don't support font em unit now, but has to multiply val * font size later... + a = iter + 1; + goto success; + } + + //signed or not + int minus_e = 1; + + if (*iter == '-') { + minus_e = -1; + ++iter; + } else if (*iter == '+') { + iter++; + } + + unsigned int exponentPart = 0; + + if (isdigit(*iter)) { + while (*iter == '0') iter++; + for (; isdigit(*iter); iter++) { + exponentPart = exponentPart * 10U + static_cast(*iter - '0'); + } + } else if (!isdigit(*(a - 1))) { + a = nPtr; + goto success; + } else if (*iter == 0) { + goto success; + } + + //if ((_floatExact(val, 2.2250738585072011f)) && ((minus_e * static_cast(exponentPart)) <= -308)) { + if ((_floatExact(val, 1.175494351f)) && ((minus_e * static_cast(exponentPart)) <= -38)) { + //val *= 1.0e-308f; + val *= 1.0e-38f; + a = iter; + goto success; + } + + a = iter; + auto scale = 1.0f; + + while (exponentPart >= 8U) { + scale *= 1E8f; + exponentPart -= 8U; + } + while (exponentPart > 0U) { + scale *= 10.0f; + exponentPart--; + } + val = (minus_e == -1) ? (val / scale) : (val * scale); + } else if ((iter > nPtr) && !isdigit(*(iter - 1))) { + a = nPtr; + goto success; + } + +success: + if (endPtr) *endPtr = (char *)(a); + if (!std::isfinite(val)) return 0.0f; + + return minus * val; + +error: + if (endPtr) *endPtr = (char *)(nPtr); + return 0.0f; +} + + +int str2int(const char* str, size_t n) +{ + int ret = 0; + for(size_t i = 0; i < n; ++i) { + ret = ret * 10 + (str[i] - '0'); + } + return ret; +} + +char* strDuplicate(const char *str, size_t n) +{ + auto len = strlen(str); + if (len < n) n = len; + + auto ret = (char *) malloc(n + 1); + if (!ret) return nullptr; + ret[n] = '\0'; + + return (char *) memcpy(ret, str, n); +} + +char* strDirname(const char* path) +{ + const char *ptr = strrchr(path, '/'); +#ifdef _WIN32 + if (ptr) ptr = strrchr(ptr + 1, '\\'); +#endif + int len = int(ptr + 1 - path); // +1 to include '/' + return strDuplicate(path, len); +} + +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgStr.h b/test/include/liblvgl/libs/thorvg/tvgStr.h new file mode 100644 index 00000000..154a1995 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgStr.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_STR_H_ +#define _TVG_STR_H_ + +#include + +namespace tvg +{ + +float strToFloat(const char *nPtr, char **endPtr); //convert to float +int str2int(const char* str, size_t n); //convert to integer +char* strDuplicate(const char *str, size_t n); //copy the string +char* strDirname(const char* path); //return the full directory name + +} +#endif //_TVG_STR_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgCssStyle.cpp b/test/include/liblvgl/libs/thorvg/tvgSvgCssStyle.cpp new file mode 100644 index 00000000..11274e33 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgCssStyle.cpp @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2022 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgSvgCssStyle.h" + +#include + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static bool _isImportanceApplicable(SvgStyleFlags &toFlagsImportance, SvgStyleFlags fromFlagsImportance, SvgStyleFlags flag) +{ + if (!(toFlagsImportance & flag) && (fromFlagsImportance & flag)) { + return true; + } + return false; +} + +static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from) +{ + if (from == nullptr) return; + //Copy the properties of 'from' only if they were explicitly set (not the default ones). + if ((from->curColorSet && !(to->flags & SvgStyleFlags::Color)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::Color)) { + to->color = from->color; + to->curColorSet = true; + to->flags = (to->flags | SvgStyleFlags::Color); + if (from->flagsImportance & SvgStyleFlags::Color) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::Color); + } + } + if (((from->flags & SvgStyleFlags::PaintOrder) && !(to->flags & SvgStyleFlags::PaintOrder)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::PaintOrder)) { + to->paintOrder = from->paintOrder; + to->flags = (to->flags | SvgStyleFlags::PaintOrder); + if (from->flagsImportance & SvgStyleFlags::PaintOrder) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::PaintOrder); + } + } + if (((from->flags & SvgStyleFlags::Display) && !(to->flags & SvgStyleFlags::Display)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::Display)) { + to->display = from->display; + to->flags = (to->flags | SvgStyleFlags::Display); + if (from->flagsImportance & SvgStyleFlags::Display) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::Display); + } + } + //Fill + if (((from->fill.flags & SvgFillFlags::Paint) && !(to->flags & SvgStyleFlags::Fill)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::Fill)) { + to->fill.paint.color = from->fill.paint.color; + to->fill.paint.none = from->fill.paint.none; + to->fill.paint.curColor = from->fill.paint.curColor; + if (from->fill.paint.url) { + if (to->fill.paint.url) free(to->fill.paint.url); + to->fill.paint.url = strdup(from->fill.paint.url); + } + to->fill.flags = (to->fill.flags | SvgFillFlags::Paint); + to->flags = (to->flags | SvgStyleFlags::Fill); + if (from->flagsImportance & SvgStyleFlags::Fill) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::Fill); + } + } + if (((from->fill.flags & SvgFillFlags::Opacity) && !(to->flags & SvgStyleFlags::FillOpacity)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::FillOpacity)) { + to->fill.opacity = from->fill.opacity; + to->fill.flags = (to->fill.flags | SvgFillFlags::Opacity); + to->flags = (to->flags | SvgStyleFlags::FillOpacity); + if (from->flagsImportance & SvgStyleFlags::FillOpacity) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::FillOpacity); + } + } + if (((from->fill.flags & SvgFillFlags::FillRule) && !(to->flags & SvgStyleFlags::FillRule)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::FillRule)) { + to->fill.fillRule = from->fill.fillRule; + to->fill.flags = (to->fill.flags | SvgFillFlags::FillRule); + to->flags = (to->flags | SvgStyleFlags::FillRule); + if (from->flagsImportance & SvgStyleFlags::FillRule) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::FillRule); + } + } + //Stroke + if (((from->stroke.flags & SvgStrokeFlags::Paint) && !(to->flags & SvgStyleFlags::Stroke)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::Stroke)) { + to->stroke.paint.color = from->stroke.paint.color; + to->stroke.paint.none = from->stroke.paint.none; + to->stroke.paint.curColor = from->stroke.paint.curColor; + if (from->stroke.paint.url) { + if (to->stroke.paint.url) free(to->stroke.paint.url); + to->stroke.paint.url = strdup(from->stroke.paint.url); + } + to->stroke.flags = (to->stroke.flags | SvgStrokeFlags::Paint); + to->flags = (to->flags | SvgStyleFlags::Stroke); + if (from->flagsImportance & SvgStyleFlags::Stroke) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::Stroke); + } + } + if (((from->stroke.flags & SvgStrokeFlags::Opacity) && !(to->flags & SvgStyleFlags::StrokeOpacity)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::StrokeOpacity)) { + to->stroke.opacity = from->stroke.opacity; + to->stroke.flags = (to->stroke.flags | SvgStrokeFlags::Opacity); + to->flags = (to->flags | SvgStyleFlags::StrokeOpacity); + if (from->flagsImportance & SvgStyleFlags::StrokeOpacity) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::StrokeOpacity); + } + } + if (((from->stroke.flags & SvgStrokeFlags::Width) && !(to->flags & SvgStyleFlags::StrokeWidth)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::StrokeWidth)) { + to->stroke.width = from->stroke.width; + to->stroke.flags = (to->stroke.flags | SvgStrokeFlags::Width); + to->flags = (to->flags | SvgStyleFlags::StrokeWidth); + if (from->flagsImportance & SvgStyleFlags::StrokeWidth) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::StrokeWidth); + } + } + if (((from->stroke.flags & SvgStrokeFlags::Dash) && !(to->flags & SvgStyleFlags::StrokeDashArray)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::StrokeDashArray)) { + if (from->stroke.dash.array.count > 0) { + to->stroke.dash.array.clear(); + to->stroke.dash.array.reserve(from->stroke.dash.array.count); + for (uint32_t i = 0; i < from->stroke.dash.array.count; ++i) { + to->stroke.dash.array.push(from->stroke.dash.array[i]); + } + to->stroke.flags = (to->stroke.flags | SvgStrokeFlags::Dash); + to->flags = (to->flags | SvgStyleFlags::StrokeDashArray); + if (from->flagsImportance & SvgStyleFlags::StrokeDashArray) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::StrokeDashArray); + } + } + } + if (((from->stroke.flags & SvgStrokeFlags::Cap) && !(to->flags & SvgStyleFlags::StrokeLineCap)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::StrokeLineCap)) { + to->stroke.cap = from->stroke.cap; + to->stroke.flags = (to->stroke.flags | SvgStrokeFlags::Cap); + to->flags = (to->flags | SvgStyleFlags::StrokeLineCap); + if (from->flagsImportance & SvgStyleFlags::StrokeLineCap) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::StrokeLineCap); + } + } + if (((from->stroke.flags & SvgStrokeFlags::Join) && !(to->flags & SvgStyleFlags::StrokeLineJoin)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::StrokeLineJoin)) { + to->stroke.join = from->stroke.join; + to->stroke.flags = (to->stroke.flags | SvgStrokeFlags::Join); + to->flags = (to->flags | SvgStyleFlags::StrokeLineJoin); + if (from->flagsImportance & SvgStyleFlags::StrokeLineJoin) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::StrokeLineJoin); + } + } + //Opacity + //TODO: it can be set to be 255 and shouldn't be changed by attribute 'opacity' + if ((from->opacity < 255 && !(to->flags & SvgStyleFlags::Opacity)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::Opacity)) { + to->opacity = from->opacity; + to->flags = (to->flags | SvgStyleFlags::Opacity); + if (from->flagsImportance & SvgStyleFlags::Opacity) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::Opacity); + } + } +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void cssCopyStyleAttr(SvgNode* to, const SvgNode* from) +{ + //Copy matrix attribute + if (from->transform && !(to->style->flags & SvgStyleFlags::Transform)) { + to->transform = (Matrix*)malloc(sizeof(Matrix)); + if (to->transform) { + *to->transform = *from->transform; + to->style->flags = (to->style->flags | SvgStyleFlags::Transform); + } + } + //Copy style attribute + _copyStyle(to->style, from->style); + + if (from->style->clipPath.url) { + if (to->style->clipPath.url) free(to->style->clipPath.url); + to->style->clipPath.url = strdup(from->style->clipPath.url); + } + if (from->style->mask.url) { + if (to->style->mask.url) free(to->style->mask.url); + to->style->mask.url = strdup(from->style->mask.url); + } +} + + +SvgNode* cssFindStyleNode(const SvgNode* style, const char* title, SvgNodeType type) +{ + if (!style) return nullptr; + + auto child = style->child.data; + for (uint32_t i = 0; i < style->child.count; ++i, ++child) { + if ((*child)->type == type) { + if ((!title && !(*child)->id) || (title && (*child)->id && !strcmp((*child)->id, title))) return (*child); + } + } + return nullptr; +} + + +SvgNode* cssFindStyleNode(const SvgNode* style, const char* title) +{ + if (!style || !title) return nullptr; + + auto child = style->child.data; + for (uint32_t i = 0; i < style->child.count; ++i, ++child) { + if ((*child)->type == SvgNodeType::CssStyle) { + if ((*child)->id && !strcmp((*child)->id, title)) return (*child); + } + } + return nullptr; +} + + +void cssUpdateStyle(SvgNode* doc, SvgNode* style) +{ + if (doc->child.count > 0) { + auto child = doc->child.data; + for (uint32_t i = 0; i < doc->child.count; ++i, ++child) { + if (auto cssNode = cssFindStyleNode(style, nullptr, (*child)->type)) { + cssCopyStyleAttr(*child, cssNode); + } + cssUpdateStyle(*child, style); + } + } +} + + +void cssApplyStyleToPostponeds(Array& postponeds, SvgNode* style) +{ + for (uint32_t i = 0; i < postponeds.count; ++i) { + auto nodeIdPair = postponeds[i]; + + //css styling: tag.name has higher priority than .name + if (auto cssNode = cssFindStyleNode(style, nodeIdPair.id, nodeIdPair.node->type)) { + cssCopyStyleAttr(nodeIdPair.node, cssNode); + } + if (auto cssNode = cssFindStyleNode(style, nodeIdPair.id)) { + cssCopyStyleAttr(nodeIdPair.node, cssNode); + } + } +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgCssStyle.h b/test/include/liblvgl/libs/thorvg/tvgSvgCssStyle.h new file mode 100644 index 00000000..24812b3e --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgCssStyle.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SVG_CSS_STYLE_H_ +#define _TVG_SVG_CSS_STYLE_H_ + +#include "tvgSvgLoaderCommon.h" + +void cssCopyStyleAttr(SvgNode* to, const SvgNode* from); +SvgNode* cssFindStyleNode(const SvgNode* style, const char* title, SvgNodeType type); +SvgNode* cssFindStyleNode(const SvgNode* style, const char* title); +void cssUpdateStyle(SvgNode* doc, SvgNode* style); +void cssApplyStyleToPostponeds(Array& postponeds, SvgNode* style); + +#endif //_TVG_SVG_CSS_STYLE_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgLoader.cpp b/test/include/liblvgl/libs/thorvg/tvgSvgLoader.cpp new file mode 100644 index 00000000..34ca2c5b --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgLoader.cpp @@ -0,0 +1,3917 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +/* + * Copyright notice for the EFL: + + * Copyright (C) EFL developers (see AUTHORS) + + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include "tvgLoader.h" +#include "tvgXmlParser.h" +#include "tvgSvgLoader.h" +#include "tvgSvgSceneBuilder.h" +#include "tvgStr.h" +#include "tvgSvgCssStyle.h" +#include "tvgMath.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +/* + * According to: https://www.w3.org/TR/SVG2/coords.html#Units + * and: https://www.w3.org/TR/css-values-4/#absolute-lengths + */ +#define PX_PER_IN 96 //1 in = 96 px +#define PX_PER_PC 16 //1 pc = 1/6 in -> PX_PER_IN/6 +#define PX_PER_PT 1.333333f //1 pt = 1/72 in -> PX_PER_IN/72 +#define PX_PER_MM 3.779528f //1 in = 25.4 mm -> PX_PER_IN/25.4 +#define PX_PER_CM 37.79528f //1 in = 2.54 cm -> PX_PER_IN/2.54 + +typedef bool (*parseAttributes)(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data); +typedef SvgNode* (*FactoryMethod)(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func); +typedef SvgStyleGradient* (*GradientFactoryMethod)(SvgLoaderData* loader, const char* buf, unsigned bufLength); + +static char* _skipSpace(const char* str, const char* end) +{ + while (((end && str < end) || (!end && *str != '\0')) && isspace(*str)) { + ++str; + } + return (char*) str; +} + + +static char* _copyId(const char* str) +{ + if (!str) return nullptr; + if (strlen(str) == 0) return nullptr; + + return strdup(str); +} + + +static const char* _skipComma(const char* content) +{ + content = _skipSpace(content, nullptr); + if (*content == ',') return content + 1; + return content; +} + + +static bool _parseNumber(const char** content, const char** end, float* number) +{ + const char* _end = end ? *end : nullptr; + + *number = strToFloat(*content, (char**)&_end); + //If the start of string is not number + if ((*content) == _end) { + if (end) *end = _end; + return false; + } + //Skip comma if any + *content = _skipComma(_end); + if (end) *end = _end; + + return true; +} + + +static constexpr struct +{ + AspectRatioAlign align; + const char* tag; +} alignTags[] = { + { AspectRatioAlign::XMinYMin, "xMinYMin" }, + { AspectRatioAlign::XMidYMin, "xMidYMin" }, + { AspectRatioAlign::XMaxYMin, "xMaxYMin" }, + { AspectRatioAlign::XMinYMid, "xMinYMid" }, + { AspectRatioAlign::XMidYMid, "xMidYMid" }, + { AspectRatioAlign::XMaxYMid, "xMaxYMid" }, + { AspectRatioAlign::XMinYMax, "xMinYMax" }, + { AspectRatioAlign::XMidYMax, "xMidYMax" }, + { AspectRatioAlign::XMaxYMax, "xMaxYMax" }, +}; + + +static void _parseAspectRatio(const char** content, AspectRatioAlign* align, AspectRatioMeetOrSlice* meetOrSlice) +{ + if (!strcmp(*content, "none")) { + *align = AspectRatioAlign::None; + return; + } + + for (unsigned int i = 0; i < sizeof(alignTags) / sizeof(alignTags[0]); i++) { + if (!strncmp(*content, alignTags[i].tag, 8)) { + *align = alignTags[i].align; + *content += 8; + *content = _skipSpace(*content, nullptr); + break; + } + } + + if (!strcmp(*content, "meet")) { + *meetOrSlice = AspectRatioMeetOrSlice::Meet; + } else if (!strcmp(*content, "slice")) { + *meetOrSlice = AspectRatioMeetOrSlice::Slice; + } +} + + +/** + * According to https://www.w3.org/TR/SVG/coords.html#Units + */ +static float _toFloat(const SvgParser* svgParse, const char* str, SvgParserLengthType type) +{ + float parsedValue = strToFloat(str, nullptr); + + if (strstr(str, "cm")) parsedValue *= PX_PER_CM; + else if (strstr(str, "mm")) parsedValue *= PX_PER_MM; + else if (strstr(str, "pt")) parsedValue *= PX_PER_PT; + else if (strstr(str, "pc")) parsedValue *= PX_PER_PC; + else if (strstr(str, "in")) parsedValue *= PX_PER_IN; + else if (strstr(str, "%")) { + if (type == SvgParserLengthType::Vertical) parsedValue = (parsedValue / 100.0f) * svgParse->global.h; + else if (type == SvgParserLengthType::Horizontal) parsedValue = (parsedValue / 100.0f) * svgParse->global.w; + else //if other then it's radius + { + float max = svgParse->global.w; + if (max < svgParse->global.h) + max = svgParse->global.h; + parsedValue = (parsedValue / 100.0f) * max; + } + } + //TODO: Implement 'em', 'ex' attributes + + return parsedValue; +} + + +static float _gradientToFloat(const SvgParser* svgParse, const char* str, bool& isPercentage) +{ + char* end = nullptr; + + float parsedValue = strToFloat(str, &end); + isPercentage = false; + + if (strstr(str, "%")) { + parsedValue = parsedValue / 100.0f; + isPercentage = true; + } + else if (strstr(str, "cm")) parsedValue *= PX_PER_CM; + else if (strstr(str, "mm")) parsedValue *= PX_PER_MM; + else if (strstr(str, "pt")) parsedValue *= PX_PER_PT; + else if (strstr(str, "pc")) parsedValue *= PX_PER_PC; + else if (strstr(str, "in")) parsedValue *= PX_PER_IN; + //TODO: Implement 'em', 'ex' attributes + + return parsedValue; +} + + +static float _toOffset(const char* str) +{ + char* end = nullptr; + auto strEnd = str + strlen(str); + + float parsedValue = strToFloat(str, &end); + + end = _skipSpace(end, nullptr); + auto ptr = strstr(str, "%"); + + if (ptr) { + parsedValue = parsedValue / 100.0f; + if (end != ptr || (end + 1) != strEnd) return 0; + } else if (end != strEnd) return 0; + + return parsedValue; +} + + +static int _toOpacity(const char* str) +{ + char* end = nullptr; + float opacity = strToFloat(str, &end); + + if (end) { + if (end[0] == '%' && end[1] == '\0') return lrint(opacity * 2.55f); + else if (*end == '\0') return lrint(opacity * 255); + } + return 255; +} + + +static SvgMaskType _toMaskType(const char* str) +{ + if (!strcmp(str, "Alpha")) return SvgMaskType::Alpha; + + return SvgMaskType::Luminance; +} + + +//The default rendering order: fill, stroke, markers +//If any is omitted, will be rendered in its default order after the specified ones. +static bool _toPaintOrder(const char* str) +{ + uint8_t position = 1; + uint8_t strokePosition = 0; + uint8_t fillPosition = 0; + + while (*str != '\0') { + str = _skipSpace(str, nullptr); + if (!strncmp(str, "fill", 4)) { + fillPosition = position++; + str += 4; + } else if (!strncmp(str, "stroke", 6)) { + strokePosition = position++; + str += 6; + } else if (!strncmp(str, "markers", 7)) { + str += 7; + } else { + return _toPaintOrder("fill stroke"); + } + } + + if (fillPosition == 0) fillPosition = position++; + if (strokePosition == 0) strokePosition = position++; + + return fillPosition < strokePosition; +} + + +#define _PARSE_TAG(Type, Name, Name1, Tags_Array, Default) \ + static Type _to##Name1(const char* str) \ + { \ + unsigned int i; \ + \ + for (i = 0; i < sizeof(Tags_Array) / sizeof(Tags_Array[0]); i++) { \ + if (!strcmp(str, Tags_Array[i].tag)) return Tags_Array[i].Name; \ + } \ + return Default; \ + } + + +/* parse the line cap used during stroking a path. + * Value: butt | round | square | inherit + * Initial: butt + * https://www.w3.org/TR/SVG/painting.html + */ +static constexpr struct +{ + StrokeCap lineCap; + const char* tag; +} lineCapTags[] = { + { StrokeCap::Butt, "butt" }, + { StrokeCap::Round, "round" }, + { StrokeCap::Square, "square" } +}; + + +_PARSE_TAG(StrokeCap, lineCap, LineCap, lineCapTags, StrokeCap::Butt) + + +/* parse the line join used during stroking a path. + * Value: miter | round | bevel | inherit + * Initial: miter + * https://www.w3.org/TR/SVG/painting.html + */ +static constexpr struct +{ + StrokeJoin lineJoin; + const char* tag; +} lineJoinTags[] = { + { StrokeJoin::Miter, "miter" }, + { StrokeJoin::Round, "round" }, + { StrokeJoin::Bevel, "bevel" } +}; + + +_PARSE_TAG(StrokeJoin, lineJoin, LineJoin, lineJoinTags, StrokeJoin::Miter) + + +/* parse the fill rule used during filling a path. + * Value: nonzero | evenodd | inherit + * Initial: nonzero + * https://www.w3.org/TR/SVG/painting.html + */ +static constexpr struct +{ + FillRule fillRule; + const char* tag; +} fillRuleTags[] = { + { FillRule::EvenOdd, "evenodd" } +}; + + +_PARSE_TAG(FillRule, fillRule, FillRule, fillRuleTags, FillRule::Winding) + + +/* parse the dash pattern used during stroking a path. + * Value: none | | inherit + * Initial: none + * https://www.w3.org/TR/SVG/painting.html + */ +static void _parseDashArray(SvgLoaderData* loader, const char *str, SvgDash* dash) +{ + if (!strncmp(str, "none", 4)) return; + + char *end = nullptr; + + while (*str) { + str = _skipComma(str); + float parsedValue = strToFloat(str, &end); + if (str == end) break; + if (parsedValue <= 0.0f) break; + if (*end == '%') { + ++end; + //Refers to the diagonal length of the viewport. + //https://www.w3.org/TR/SVG2/coords.html#Units + parsedValue = (sqrtf(powf(loader->svgParse->global.w, 2) + powf(loader->svgParse->global.h, 2)) / sqrtf(2.0f)) * (parsedValue / 100.0f); + } + (*dash).array.push(parsedValue); + str = end; + } + //If dash array size is 1, it means that dash and gap size are the same. + if ((*dash).array.count == 1) (*dash).array.push((*dash).array[0]); +} + + +static char* _idFromUrl(const char* url) +{ + auto open = strchr(url, '('); + auto close = strchr(url, ')'); + if (!open || !close || open >= close) return nullptr; + + open = strchr(url, '#'); + if (!open || open >= close) return nullptr; + + ++open; + --close; + + //trim the rest of the spaces if any + while (open < close && *close == ' ') --close; + + //quick verification + for (auto id = open; id < close; id++) { + if (*id == ' ' || *id == '\'') return nullptr; + } + + return strDuplicate(open, (close - open + 1)); +} + + +static unsigned char _parseColor(const char* value, char** end) +{ + float r; + + r = strToFloat(value, end); + *end = _skipSpace(*end, nullptr); + if (**end == '%') { + r = 255 * r / 100; + (*end)++; + } + *end = _skipSpace(*end, nullptr); + + if (r < 0 || r > 255) { + *end = nullptr; + return 0; + } + + return lrint(r); +} + + +static constexpr struct +{ + const char* name; + unsigned int value; +} colors[] = { + { "aliceblue", 0xfff0f8ff }, + { "antiquewhite", 0xfffaebd7 }, + { "aqua", 0xff00ffff }, + { "aquamarine", 0xff7fffd4 }, + { "azure", 0xfff0ffff }, + { "beige", 0xfff5f5dc }, + { "bisque", 0xffffe4c4 }, + { "black", 0xff000000 }, + { "blanchedalmond", 0xffffebcd }, + { "blue", 0xff0000ff }, + { "blueviolet", 0xff8a2be2 }, + { "brown", 0xffa52a2a }, + { "burlywood", 0xffdeb887 }, + { "cadetblue", 0xff5f9ea0 }, + { "chartreuse", 0xff7fff00 }, + { "chocolate", 0xffd2691e }, + { "coral", 0xffff7f50 }, + { "cornflowerblue", 0xff6495ed }, + { "cornsilk", 0xfffff8dc }, + { "crimson", 0xffdc143c }, + { "cyan", 0xff00ffff }, + { "darkblue", 0xff00008b }, + { "darkcyan", 0xff008b8b }, + { "darkgoldenrod", 0xffb8860b }, + { "darkgray", 0xffa9a9a9 }, + { "darkgrey", 0xffa9a9a9 }, + { "darkgreen", 0xff006400 }, + { "darkkhaki", 0xffbdb76b }, + { "darkmagenta", 0xff8b008b }, + { "darkolivegreen", 0xff556b2f }, + { "darkorange", 0xffff8c00 }, + { "darkorchid", 0xff9932cc }, + { "darkred", 0xff8b0000 }, + { "darksalmon", 0xffe9967a }, + { "darkseagreen", 0xff8fbc8f }, + { "darkslateblue", 0xff483d8b }, + { "darkslategray", 0xff2f4f4f }, + { "darkslategrey", 0xff2f4f4f }, + { "darkturquoise", 0xff00ced1 }, + { "darkviolet", 0xff9400d3 }, + { "deeppink", 0xffff1493 }, + { "deepskyblue", 0xff00bfff }, + { "dimgray", 0xff696969 }, + { "dimgrey", 0xff696969 }, + { "dodgerblue", 0xff1e90ff }, + { "firebrick", 0xffb22222 }, + { "floralwhite", 0xfffffaf0 }, + { "forestgreen", 0xff228b22 }, + { "fuchsia", 0xffff00ff }, + { "gainsboro", 0xffdcdcdc }, + { "ghostwhite", 0xfff8f8ff }, + { "gold", 0xffffd700 }, + { "goldenrod", 0xffdaa520 }, + { "gray", 0xff808080 }, + { "grey", 0xff808080 }, + { "green", 0xff008000 }, + { "greenyellow", 0xffadff2f }, + { "honeydew", 0xfff0fff0 }, + { "hotpink", 0xffff69b4 }, + { "indianred", 0xffcd5c5c }, + { "indigo", 0xff4b0082 }, + { "ivory", 0xfffffff0 }, + { "khaki", 0xfff0e68c }, + { "lavender", 0xffe6e6fa }, + { "lavenderblush", 0xfffff0f5 }, + { "lawngreen", 0xff7cfc00 }, + { "lemonchiffon", 0xfffffacd }, + { "lightblue", 0xffadd8e6 }, + { "lightcoral", 0xfff08080 }, + { "lightcyan", 0xffe0ffff }, + { "lightgoldenrodyellow", 0xfffafad2 }, + { "lightgray", 0xffd3d3d3 }, + { "lightgrey", 0xffd3d3d3 }, + { "lightgreen", 0xff90ee90 }, + { "lightpink", 0xffffb6c1 }, + { "lightsalmon", 0xffffa07a }, + { "lightseagreen", 0xff20b2aa }, + { "lightskyblue", 0xff87cefa }, + { "lightslategray", 0xff778899 }, + { "lightslategrey", 0xff778899 }, + { "lightsteelblue", 0xffb0c4de }, + { "lightyellow", 0xffffffe0 }, + { "lime", 0xff00ff00 }, + { "limegreen", 0xff32cd32 }, + { "linen", 0xfffaf0e6 }, + { "magenta", 0xffff00ff }, + { "maroon", 0xff800000 }, + { "mediumaquamarine", 0xff66cdaa }, + { "mediumblue", 0xff0000cd }, + { "mediumorchid", 0xffba55d3 }, + { "mediumpurple", 0xff9370d8 }, + { "mediumseagreen", 0xff3cb371 }, + { "mediumslateblue", 0xff7b68ee }, + { "mediumspringgreen", 0xff00fa9a }, + { "mediumturquoise", 0xff48d1cc }, + { "mediumvioletred", 0xffc71585 }, + { "midnightblue", 0xff191970 }, + { "mintcream", 0xfff5fffa }, + { "mistyrose", 0xffffe4e1 }, + { "moccasin", 0xffffe4b5 }, + { "navajowhite", 0xffffdead }, + { "navy", 0xff000080 }, + { "oldlace", 0xfffdf5e6 }, + { "olive", 0xff808000 }, + { "olivedrab", 0xff6b8e23 }, + { "orange", 0xffffa500 }, + { "orangered", 0xffff4500 }, + { "orchid", 0xffda70d6 }, + { "palegoldenrod", 0xffeee8aa }, + { "palegreen", 0xff98fb98 }, + { "paleturquoise", 0xffafeeee }, + { "palevioletred", 0xffd87093 }, + { "papayawhip", 0xffffefd5 }, + { "peachpuff", 0xffffdab9 }, + { "peru", 0xffcd853f }, + { "pink", 0xffffc0cb }, + { "plum", 0xffdda0dd }, + { "powderblue", 0xffb0e0e6 }, + { "purple", 0xff800080 }, + { "red", 0xffff0000 }, + { "rosybrown", 0xffbc8f8f }, + { "royalblue", 0xff4169e1 }, + { "saddlebrown", 0xff8b4513 }, + { "salmon", 0xfffa8072 }, + { "sandybrown", 0xfff4a460 }, + { "seagreen", 0xff2e8b57 }, + { "seashell", 0xfffff5ee }, + { "sienna", 0xffa0522d }, + { "silver", 0xffc0c0c0 }, + { "skyblue", 0xff87ceeb }, + { "slateblue", 0xff6a5acd }, + { "slategray", 0xff708090 }, + { "slategrey", 0xff708090 }, + { "snow", 0xfffffafa }, + { "springgreen", 0xff00ff7f }, + { "steelblue", 0xff4682b4 }, + { "tan", 0xffd2b48c }, + { "teal", 0xff008080 }, + { "thistle", 0xffd8bfd8 }, + { "tomato", 0xffff6347 }, + { "turquoise", 0xff40e0d0 }, + { "violet", 0xffee82ee }, + { "wheat", 0xfff5deb3 }, + { "white", 0xffffffff }, + { "whitesmoke", 0xfff5f5f5 }, + { "yellow", 0xffffff00 }, + { "yellowgreen", 0xff9acd32 } +}; + + +static bool _hslToRgb(float hue, float saturation, float brightness, uint8_t* red, uint8_t* green, uint8_t* blue) +{ + if (!red || !green || !blue) return false; + + float sv, vsf, f, p, q, t, v; + float _red = 0, _green = 0, _blue = 0; + uint32_t i = 0; + + if (mathZero(saturation)) _red = _green = _blue = brightness; + else { + if (mathEqual(hue, 360.0)) hue = 0.0f; + hue /= 60.0f; + + v = (brightness <= 0.5f) ? (brightness * (1.0f + saturation)) : (brightness + saturation - (brightness * saturation)); + p = brightness + brightness - v; + + if (!mathZero(v)) sv = (v - p) / v; + else sv = 0; + + i = static_cast(hue); + f = hue - i; + + vsf = v * sv * f; + + t = p + vsf; + q = v - vsf; + + switch (i) { + case 0: { + _red = v; + _green = t; + _blue = p; + break; + } + case 1: { + _red = q; + _green = v; + _blue = p; + break; + } + case 2: { + _red = p; + _green = v; + _blue = t; + break; + } + case 3: { + _red = p; + _green = q; + _blue = v; + break; + } + case 4: { + _red = t; + _green = p; + _blue = v; + break; + } + case 5: { + _red = v; + _green = p; + _blue = q; + break; + } + } + } + + *red = static_cast(roundf(_red * 255.0f)); + *green = static_cast(roundf(_green * 255.0f)); + *blue = static_cast(roundf(_blue * 255.0f)); + + return true; +} + + +static bool _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** ref) +{ + unsigned int len = strlen(str); + char *red, *green, *blue; + unsigned char tr, tg, tb; + + if (len == 4 && str[0] == '#') { + //Case for "#456" should be interpreted as "#445566" + if (isxdigit(str[1]) && isxdigit(str[2]) && isxdigit(str[3])) { + char tmp[3] = { '\0', '\0', '\0' }; + tmp[0] = str[1]; + tmp[1] = str[1]; + *r = strtol(tmp, nullptr, 16); + tmp[0] = str[2]; + tmp[1] = str[2]; + *g = strtol(tmp, nullptr, 16); + tmp[0] = str[3]; + tmp[1] = str[3]; + *b = strtol(tmp, nullptr, 16); + } + return true; + } else if (len == 7 && str[0] == '#') { + if (isxdigit(str[1]) && isxdigit(str[2]) && isxdigit(str[3]) && isxdigit(str[4]) && isxdigit(str[5]) && isxdigit(str[6])) { + char tmp[3] = { '\0', '\0', '\0' }; + tmp[0] = str[1]; + tmp[1] = str[2]; + *r = strtol(tmp, nullptr, 16); + tmp[0] = str[3]; + tmp[1] = str[4]; + *g = strtol(tmp, nullptr, 16); + tmp[0] = str[5]; + tmp[1] = str[6]; + *b = strtol(tmp, nullptr, 16); + } + return true; + } else if (len >= 10 && (str[0] == 'r' || str[0] == 'R') && (str[1] == 'g' || str[1] == 'G') && (str[2] == 'b' || str[2] == 'B') && str[3] == '(' && str[len - 1] == ')') { + tr = _parseColor(str + 4, &red); + if (red && *red == ',') { + tg = _parseColor(red + 1, &green); + if (green && *green == ',') { + tb = _parseColor(green + 1, &blue); + if (blue && blue[0] == ')' && blue[1] == '\0') { + *r = tr; + *g = tg; + *b = tb; + } + } + } + return true; + } else if (ref && len >= 3 && !strncmp(str, "url", 3)) { + if (*ref) free(*ref); + *ref = _idFromUrl((const char*)(str + 3)); + return true; + } else if (len >= 10 && (str[0] == 'h' || str[0] == 'H') && (str[1] == 's' || str[1] == 'S') && (str[2] == 'l' || str[2] == 'L') && str[3] == '(' && str[len - 1] == ')') { + float th, ts, tb; + const char *content, *hue, *saturation, *brightness; + content = str + 4; + content = _skipSpace(content, nullptr); + if (_parseNumber(&content, &hue, &th) && hue) { + th = float(uint32_t(th) % 360); + hue = _skipSpace(hue, nullptr); + hue = (char*)_skipComma(hue); + hue = _skipSpace(hue, nullptr); + if (_parseNumber(&hue, &saturation, &ts) && saturation && *saturation == '%') { + ts /= 100.0f; + saturation = _skipSpace(saturation + 1, nullptr); + saturation = (char*)_skipComma(saturation); + saturation = _skipSpace(saturation, nullptr); + if (_parseNumber(&saturation, &brightness, &tb) && brightness && *brightness == '%') { + tb /= 100.0f; + brightness = _skipSpace(brightness + 1, nullptr); + if (brightness && brightness[0] == ')' && brightness[1] == '\0') { + return _hslToRgb(th, ts, tb, r, g, b); + } + } + } + } + } else { + //Handle named color + for (unsigned int i = 0; i < (sizeof(colors) / sizeof(colors[0])); i++) { + if (!strcasecmp(colors[i].name, str)) { + *r = (((uint8_t*)(&(colors[i].value)))[2]); + *g = (((uint8_t*)(&(colors[i].value)))[1]); + *b = (((uint8_t*)(&(colors[i].value)))[0]); + return true; + } + } + } + return false; +} + + +static char* _parseNumbersArray(char* str, float* points, int* ptCount, int len) +{ + int count = 0; + char* end = nullptr; + + str = _skipSpace(str, nullptr); + while ((count < len) && (isdigit(*str) || *str == '-' || *str == '+' || *str == '.')) { + points[count++] = strToFloat(str, &end); + str = end; + str = _skipSpace(str, nullptr); + if (*str == ',') ++str; + //Eat the rest of space + str = _skipSpace(str, nullptr); + } + *ptCount = count; + return str; +} + + +enum class MatrixState { + Unknown, + Matrix, + Translate, + Rotate, + Scale, + SkewX, + SkewY +}; + + +#define MATRIX_DEF(Name, Value) \ + { \ +#Name, sizeof(#Name), Value \ + } + + +static constexpr struct +{ + const char* tag; + int sz; + MatrixState state; +} matrixTags[] = { + MATRIX_DEF(matrix, MatrixState::Matrix), + MATRIX_DEF(translate, MatrixState::Translate), + MATRIX_DEF(rotate, MatrixState::Rotate), + MATRIX_DEF(scale, MatrixState::Scale), + MATRIX_DEF(skewX, MatrixState::SkewX), + MATRIX_DEF(skewY, MatrixState::SkewY) +}; + + +/* parse transform attribute + * https://www.w3.org/TR/SVG/coords.html#TransformAttribute + */ +static Matrix* _parseTransformationMatrix(const char* value) +{ + const int POINT_CNT = 8; + + auto matrix = (Matrix*)malloc(sizeof(Matrix)); + if (!matrix) return nullptr; + *matrix = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + + float points[POINT_CNT]; + int ptCount = 0; + char* str = (char*)value; + char* end = str + strlen(str); + + while (str < end) { + auto state = MatrixState::Unknown; + + if (isspace(*str) || (*str == ',')) { + ++str; + continue; + } + for (unsigned int i = 0; i < sizeof(matrixTags) / sizeof(matrixTags[0]); i++) { + if (!strncmp(matrixTags[i].tag, str, matrixTags[i].sz - 1)) { + state = matrixTags[i].state; + str += (matrixTags[i].sz - 1); + break; + } + } + if (state == MatrixState::Unknown) goto error; + + str = _skipSpace(str, end); + if (*str != '(') goto error; + ++str; + str = _parseNumbersArray(str, points, &ptCount, POINT_CNT); + if (*str != ')') goto error; + ++str; + + if (state == MatrixState::Matrix) { + if (ptCount != 6) goto error; + Matrix tmp = {points[0], points[2], points[4], points[1], points[3], points[5], 0, 0, 1}; + *matrix = mathMultiply(matrix, &tmp); + } else if (state == MatrixState::Translate) { + if (ptCount == 1) { + Matrix tmp = {1, 0, points[0], 0, 1, 0, 0, 0, 1}; + *matrix = mathMultiply(matrix, &tmp); + } else if (ptCount == 2) { + Matrix tmp = {1, 0, points[0], 0, 1, points[1], 0, 0, 1}; + *matrix = mathMultiply(matrix, &tmp); + } else goto error; + } else if (state == MatrixState::Rotate) { + //Transform to signed. + points[0] = fmodf(points[0], 360.0f); + if (points[0] < 0) points[0] += 360.0f; + auto c = cosf(mathDeg2Rad(points[0])); + auto s = sinf(mathDeg2Rad(points[0])); + if (ptCount == 1) { + Matrix tmp = { c, -s, 0, s, c, 0, 0, 0, 1 }; + *matrix = mathMultiply(matrix, &tmp); + } else if (ptCount == 3) { + Matrix tmp = { 1, 0, points[1], 0, 1, points[2], 0, 0, 1 }; + *matrix = mathMultiply(matrix, &tmp); + tmp = { c, -s, 0, s, c, 0, 0, 0, 1 }; + *matrix = mathMultiply(matrix, &tmp); + tmp = { 1, 0, -points[1], 0, 1, -points[2], 0, 0, 1 }; + *matrix = mathMultiply(matrix, &tmp); + } else { + goto error; + } + } else if (state == MatrixState::Scale) { + if (ptCount < 1 || ptCount > 2) goto error; + auto sx = points[0]; + auto sy = sx; + if (ptCount == 2) sy = points[1]; + Matrix tmp = { sx, 0, 0, 0, sy, 0, 0, 0, 1 }; + *matrix = mathMultiply(matrix, &tmp); + } else if (state == MatrixState::SkewX) { + if (ptCount != 1) goto error; + auto deg = tanf(mathDeg2Rad(points[0])); + Matrix tmp = { 1, deg, 0, 0, 1, 0, 0, 0, 1 }; + *matrix = mathMultiply(matrix, &tmp); + } else if (state == MatrixState::SkewY) { + if (ptCount != 1) goto error; + auto deg = tanf(mathDeg2Rad(points[0])); + Matrix tmp = { 1, 0, 0, deg, 1, 0, 0, 0, 1 }; + *matrix = mathMultiply(matrix, &tmp); + } + } + return matrix; +error: + if (matrix) free(matrix); + return nullptr; +} + + +#define LENGTH_DEF(Name, Value) \ + { \ +#Name, sizeof(#Name), Value \ + } + + +static void _postpone(Array& nodes, SvgNode *node, char* id) +{ + nodes.push({node, id}); +} + + +/* +// TODO - remove? +static constexpr struct +{ + const char* tag; + int sz; + SvgLengthType type; +} lengthTags[] = { + LENGTH_DEF(%, SvgLengthType::Percent), + LENGTH_DEF(px, SvgLengthType::Px), + LENGTH_DEF(pc, SvgLengthType::Pc), + LENGTH_DEF(pt, SvgLengthType::Pt), + LENGTH_DEF(mm, SvgLengthType::Mm), + LENGTH_DEF(cm, SvgLengthType::Cm), + LENGTH_DEF(in, SvgLengthType::In) +}; + +static float _parseLength(const char* str, SvgLengthType* type) +{ + float value; + int sz = strlen(str); + + *type = SvgLengthType::Px; + for (unsigned int i = 0; i < sizeof(lengthTags) / sizeof(lengthTags[0]); i++) { + if (lengthTags[i].sz - 1 == sz && !strncmp(lengthTags[i].tag, str, sz)) *type = lengthTags[i].type; + } + value = svgUtilStrtof(str, nullptr); + return value; +} +*/ + +static bool _parseStyleAttr(void* data, const char* key, const char* value); +static bool _parseStyleAttr(void* data, const char* key, const char* value, bool style); + + +static bool _attrParseSvgNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgDocNode* doc = &(node->node.doc); + + if (!strcmp(key, "width")) { + doc->w = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal); + if (strstr(value, "%") && !(doc->viewFlag & SvgViewFlag::Viewbox)) { + doc->viewFlag = (doc->viewFlag | SvgViewFlag::WidthInPercent); + } else { + doc->viewFlag = (doc->viewFlag | SvgViewFlag::Width); + } + } else if (!strcmp(key, "height")) { + doc->h = _toFloat(loader->svgParse, value, SvgParserLengthType::Vertical); + if (strstr(value, "%") && !(doc->viewFlag & SvgViewFlag::Viewbox)) { + doc->viewFlag = (doc->viewFlag | SvgViewFlag::HeightInPercent); + } else { + doc->viewFlag = (doc->viewFlag | SvgViewFlag::Height); + } + } else if (!strcmp(key, "viewBox")) { + if (_parseNumber(&value, nullptr, &doc->vx)) { + if (_parseNumber(&value, nullptr, &doc->vy)) { + if (_parseNumber(&value, nullptr, &doc->vw)) { + if (_parseNumber(&value, nullptr, &doc->vh)) { + doc->viewFlag = (doc->viewFlag | SvgViewFlag::Viewbox); + loader->svgParse->global.h = doc->vh; + } + loader->svgParse->global.w = doc->vw; + } + loader->svgParse->global.y = doc->vy; + } + loader->svgParse->global.x = doc->vx; + } + if ((doc->viewFlag & SvgViewFlag::Viewbox) && (doc->vw < 0.0f || doc->vh < 0.0f)) { + doc->viewFlag = (SvgViewFlag)((uint32_t)doc->viewFlag & ~(uint32_t)SvgViewFlag::Viewbox); + TVGLOG("SVG", "Negative values of the width and/or height - the attribute invalidated."); + } + if (!(doc->viewFlag & SvgViewFlag::Viewbox)) { + loader->svgParse->global.x = loader->svgParse->global.y = 0.0f; + loader->svgParse->global.w = loader->svgParse->global.h = 1.0f; + } + } else if (!strcmp(key, "preserveAspectRatio")) { + _parseAspectRatio(&value, &doc->align, &doc->meetOrSlice); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); +#ifdef THORVG_LOG_ENABLED + } else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(strToFloat(value, nullptr)) > FLOAT_EPSILON) { + TVGLOG("SVG", "Unsupported attributes used [Elements type: Svg][Attribute: %s][Value: %s]", key, value); +#endif + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +//https://www.w3.org/TR/SVGTiny12/painting.html#SpecifyingPaint +static void _handlePaintAttr(SvgPaint* paint, const char* value) +{ + if (!strcmp(value, "none")) { + //No paint property + paint->none = true; + return; + } + if (!strcmp(value, "currentColor")) { + paint->curColor = true; + paint->none = false; + return; + } + if (_toColor(value, &paint->color.r, &paint->color.g, &paint->color.b, &paint->url)) paint->none = false; +} + + +static void _handleColorAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + SvgStyleProperty* style = node->style; + if (_toColor(value, &style->color.r, &style->color.g, &style->color.b, nullptr)) { + style->curColorSet = true; + } +} + + +static void _handleFillAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + SvgStyleProperty* style = node->style; + style->fill.flags = (style->fill.flags | SvgFillFlags::Paint); + _handlePaintAttr(&style->fill.paint, value); +} + + +static void _handleStrokeAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + SvgStyleProperty* style = node->style; + style->stroke.flags = (style->stroke.flags | SvgStrokeFlags::Paint); + _handlePaintAttr(&style->stroke.paint, value); +} + + +static void _handleStrokeOpacityAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (node->style->stroke.flags | SvgStrokeFlags::Opacity); + node->style->stroke.opacity = _toOpacity(value); +} + +static void _handleStrokeDashArrayAttr(SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (node->style->stroke.flags | SvgStrokeFlags::Dash); + _parseDashArray(loader, value, &node->style->stroke.dash); +} + +static void _handleStrokeDashOffsetAttr(SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (node->style->stroke.flags | SvgStrokeFlags::DashOffset); + node->style->stroke.dash.offset = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal); +} + +static void _handleStrokeWidthAttr(SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (node->style->stroke.flags | SvgStrokeFlags::Width); + node->style->stroke.width = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal); +} + + +static void _handleStrokeLineCapAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (node->style->stroke.flags | SvgStrokeFlags::Cap); + node->style->stroke.cap = _toLineCap(value); +} + + +static void _handleStrokeLineJoinAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (node->style->stroke.flags | SvgStrokeFlags::Join); + node->style->stroke.join = _toLineJoin(value); +} + +static void _handleStrokeMiterlimitAttr(SvgLoaderData* loader, SvgNode* node, const char* value) +{ + char* end = nullptr; + const float miterlimit = strToFloat(value, &end); + + // https://www.w3.org/TR/SVG2/painting.html#LineJoin + // - A negative value for stroke-miterlimit must be treated as an illegal value. + if (miterlimit < 0.0f) { + TVGERR("SVG", "A stroke-miterlimit change (%f <- %f) with a negative value is omitted.", + node->style->stroke.miterlimit, miterlimit); + return; + } + + node->style->stroke.flags = (node->style->stroke.flags | SvgStrokeFlags::Miterlimit); + node->style->stroke.miterlimit = miterlimit; +} + +static void _handleFillRuleAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->fill.flags = (node->style->fill.flags | SvgFillFlags::FillRule); + node->style->fill.fillRule = _toFillRule(value); +} + + +static void _handleOpacityAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->flags = (node->style->flags | SvgStyleFlags::Opacity); + node->style->opacity = _toOpacity(value); +} + + +static void _handleFillOpacityAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->fill.flags = (node->style->fill.flags | SvgFillFlags::Opacity); + node->style->fill.opacity = _toOpacity(value); +} + + +static void _handleTransformAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->transform = _parseTransformationMatrix(value); +} + + +static void _handleClipPathAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + SvgStyleProperty* style = node->style; + int len = strlen(value); + if (len >= 3 && !strncmp(value, "url", 3)) { + if (style->clipPath.url) free(style->clipPath.url); + style->clipPath.url = _idFromUrl((const char*)(value + 3)); + } +} + + +static void _handleMaskAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + SvgStyleProperty* style = node->style; + int len = strlen(value); + if (len >= 3 && !strncmp(value, "url", 3)) { + if (style->mask.url) free(style->mask.url); + style->mask.url = _idFromUrl((const char*)(value + 3)); + } +} + + +static void _handleMaskTypeAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->node.mask.type = _toMaskType(value); +} + + +static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + //TODO : The display attribute can have various values as well as "none". + // The default is "inline" which means visible and "none" means invisible. + // Depending on the type of node, additional functionality may be required. + // refer to https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/display + node->style->flags = (node->style->flags | SvgStyleFlags::Display); + if (!strcmp(value, "none")) node->style->display = false; + else node->style->display = true; +} + + +static void _handlePaintOrderAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->flags = (node->style->flags | SvgStyleFlags::PaintOrder); + node->style->paintOrder = _toPaintOrder(value); +} + + +static void _handleCssClassAttr(SvgLoaderData* loader, SvgNode* node, const char* value) +{ + auto cssClass = &node->style->cssClass; + + if (*cssClass && value) free(*cssClass); + *cssClass = _copyId(value); + + bool cssClassFound = false; + + //css styling: tag.name has higher priority than .name + if (auto cssNode = cssFindStyleNode(loader->cssStyle, *cssClass, node->type)) { + cssClassFound = true; + cssCopyStyleAttr(node, cssNode); + } + if (auto cssNode = cssFindStyleNode(loader->cssStyle, *cssClass)) { + cssClassFound = true; + cssCopyStyleAttr(node, cssNode); + } + + if (!cssClassFound) _postpone(loader->nodesToStyle, node, *cssClass); +} + + +typedef void (*styleMethod)(SvgLoaderData* loader, SvgNode* node, const char* value); + +#define STYLE_DEF(Name, Name1, Flag) { #Name, sizeof(#Name), _handle##Name1##Attr, Flag } + + +static constexpr struct +{ + const char* tag; + int sz; + styleMethod tagHandler; + SvgStyleFlags flag; +} styleTags[] = { + STYLE_DEF(color, Color, SvgStyleFlags::Color), + STYLE_DEF(fill, Fill, SvgStyleFlags::Fill), + STYLE_DEF(fill-rule, FillRule, SvgStyleFlags::FillRule), + STYLE_DEF(fill-opacity, FillOpacity, SvgStyleFlags::FillOpacity), + STYLE_DEF(opacity, Opacity, SvgStyleFlags::Opacity), + STYLE_DEF(stroke, Stroke, SvgStyleFlags::Stroke), + STYLE_DEF(stroke-width, StrokeWidth, SvgStyleFlags::StrokeWidth), + STYLE_DEF(stroke-linejoin, StrokeLineJoin, SvgStyleFlags::StrokeLineJoin), + STYLE_DEF(stroke-miterlimit, StrokeMiterlimit, SvgStyleFlags::StrokeMiterlimit), + STYLE_DEF(stroke-linecap, StrokeLineCap, SvgStyleFlags::StrokeLineCap), + STYLE_DEF(stroke-opacity, StrokeOpacity, SvgStyleFlags::StrokeOpacity), + STYLE_DEF(stroke-dasharray, StrokeDashArray, SvgStyleFlags::StrokeDashArray), + STYLE_DEF(stroke-dashoffset, StrokeDashOffset, SvgStyleFlags::StrokeDashOffset), + STYLE_DEF(transform, Transform, SvgStyleFlags::Transform), + STYLE_DEF(clip-path, ClipPath, SvgStyleFlags::ClipPath), + STYLE_DEF(mask, Mask, SvgStyleFlags::Mask), + STYLE_DEF(mask-type, MaskType, SvgStyleFlags::MaskType), + STYLE_DEF(display, Display, SvgStyleFlags::Display), + STYLE_DEF(paint-order, PaintOrder, SvgStyleFlags::PaintOrder) +}; + + +static bool _parseStyleAttr(void* data, const char* key, const char* value, bool style) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + int sz; + if (!key || !value) return false; + + //Trim the white space + key = _skipSpace(key, nullptr); + value = _skipSpace(value, nullptr); + + sz = strlen(key); + for (unsigned int i = 0; i < sizeof(styleTags) / sizeof(styleTags[0]); i++) { + if (styleTags[i].sz - 1 == sz && !strncmp(styleTags[i].tag, key, sz)) { + bool importance = false; + if (auto ptr = strstr(value, "!important")) { + size_t size = ptr - value; + while (size > 0 && isspace(value[size - 1])) { + size--; + } + value = strDuplicate(value, size); + importance = true; + } + if (style) { + if (importance || !(node->style->flagsImportance & styleTags[i].flag)) { + styleTags[i].tagHandler(loader, node, value); + node->style->flags = (node->style->flags | styleTags[i].flag); + } + } else if (!(node->style->flags & styleTags[i].flag)) { + styleTags[i].tagHandler(loader, node, value); + } + if (importance) { + node->style->flagsImportance = (node->style->flags | styleTags[i].flag); + free(const_cast(value)); + } + return true; + } + } + + return false; +} + + +static bool _parseStyleAttr(void* data, const char* key, const char* value) +{ + return _parseStyleAttr(data, key, value, true); +} + + +/* parse g node + * https://www.w3.org/TR/SVG/struct.html#Groups + */ +static bool _attrParseGNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + + if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); + } else if (!strcmp(key, "transform")) { + node->transform = _parseTransformationMatrix(value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +/* parse clipPath node + * https://www.w3.org/TR/SVG/struct.html#Groups + */ +static bool _attrParseClipPathNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgClipNode* clip = &(node->node.clip); + + if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); + } else if (!strcmp(key, "transform")) { + node->transform = _parseTransformationMatrix(value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); + } else if (!strcmp(key, "clipPathUnits")) { + if (!strcmp(value, "objectBoundingBox")) clip->userSpace = false; + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static bool _attrParseMaskNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgMaskNode* mask = &(node->node.mask); + + if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); + } else if (!strcmp(key, "transform")) { + node->transform = _parseTransformationMatrix(value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); + } else if (!strcmp(key, "maskContentUnits")) { + if (!strcmp(value, "objectBoundingBox")) mask->userSpace = false; + } else if (!strcmp(key, "mask-type")) { + mask->type = _toMaskType(value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static bool _attrParseCssStyleNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + + if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static bool _attrParseSymbolNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgSymbolNode* symbol = &(node->node.symbol); + + if (!strcmp(key, "viewBox")) { + if (!_parseNumber(&value, nullptr, &symbol->vx) || !_parseNumber(&value, nullptr, &symbol->vy)) return false; + if (!_parseNumber(&value, nullptr, &symbol->vw) || !_parseNumber(&value, nullptr, &symbol->vh)) return false; + symbol->hasViewBox = true; + } else if (!strcmp(key, "width")) { + symbol->w = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal); + symbol->hasWidth = true; + } else if (!strcmp(key, "height")) { + symbol->h = _toFloat(loader->svgParse, value, SvgParserLengthType::Vertical); + symbol->hasHeight = true; + } else if (!strcmp(key, "preserveAspectRatio")) { + _parseAspectRatio(&value, &symbol->align, &symbol->meetOrSlice); + } else if (!strcmp(key, "overflow")) { + if (!strcmp(value, "visible")) symbol->overflowVisible = true; + } else { + return _attrParseGNode(data, key, value); + } + + return true; +} + + +static SvgNode* _createNode(SvgNode* parent, SvgNodeType type) +{ + SvgNode* node = (SvgNode*)calloc(1, sizeof(SvgNode)); + + if (!node) return nullptr; + + //Default fill property + node->style = (SvgStyleProperty*)calloc(1, sizeof(SvgStyleProperty)); + + if (!node->style) { + free(node); + return nullptr; + } + + //Update the default value of stroke and fill + //https://www.w3.org/TR/SVGTiny12/painting.html#SpecifyingPaint + node->style->fill.paint.none = false; + //Default fill opacity is 1 + node->style->fill.opacity = 255; + node->style->opacity = 255; + //Default current color is not set + node->style->fill.paint.curColor = false; + node->style->curColorSet = false; + //Default fill rule is nonzero + node->style->fill.fillRule = FillRule::Winding; + + //Default stroke is none + node->style->stroke.paint.none = true; + //Default stroke opacity is 1 + node->style->stroke.opacity = 255; + //Default stroke current color is not set + node->style->stroke.paint.curColor = false; + //Default stroke width is 1 + node->style->stroke.width = 1; + //Default line cap is butt + node->style->stroke.cap = StrokeCap::Butt; + //Default line join is miter + node->style->stroke.join = StrokeJoin::Miter; + node->style->stroke.miterlimit = 4.0f; + node->style->stroke.scale = 1.0; + + node->style->paintOrder = _toPaintOrder("fill stroke"); + + //Default display is true("inline"). + node->style->display = true; + + node->parent = parent; + node->type = type; + + if (parent) parent->child.push(node); + return node; +} + + +static SvgNode* _createDefsNode(TVG_UNUSED SvgLoaderData* loader, TVG_UNUSED SvgNode* parent, const char* buf, unsigned bufLength, TVG_UNUSED parseAttributes func) +{ + if (loader->def && loader->doc->node.doc.defs) return loader->def; + SvgNode* node = _createNode(nullptr, SvgNodeType::Defs); + + loader->def = node; + loader->doc->node.doc.defs = node; + return node; +} + + +static SvgNode* _createGNode(TVG_UNUSED SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::G); + if (!loader->svgParse->node) return nullptr; + + func(buf, bufLength, _attrParseGNode, loader); + return loader->svgParse->node; +} + + +static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Doc); + if (!loader->svgParse->node) return nullptr; + SvgDocNode* doc = &(loader->svgParse->node->node.doc); + + loader->svgParse->global.w = 1.0f; + loader->svgParse->global.h = 1.0f; + + doc->align = AspectRatioAlign::XMidYMid; + doc->meetOrSlice = AspectRatioMeetOrSlice::Meet; + doc->viewFlag = SvgViewFlag::None; + func(buf, bufLength, _attrParseSvgNode, loader); + + if (!(doc->viewFlag & SvgViewFlag::Viewbox)) { + if (doc->viewFlag & SvgViewFlag::Width) { + loader->svgParse->global.w = doc->w; + } + if (doc->viewFlag & SvgViewFlag::Height) { + loader->svgParse->global.h = doc->h; + } + } + return loader->svgParse->node; +} + + +static SvgNode* _createMaskNode(SvgLoaderData* loader, SvgNode* parent, TVG_UNUSED const char* buf, TVG_UNUSED unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Mask); + if (!loader->svgParse->node) return nullptr; + + loader->svgParse->node->node.mask.userSpace = true; + loader->svgParse->node->node.mask.type = SvgMaskType::Luminance; + + func(buf, bufLength, _attrParseMaskNode, loader); + + return loader->svgParse->node; +} + + +static SvgNode* _createClipPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::ClipPath); + if (!loader->svgParse->node) return nullptr; + + loader->svgParse->node->style->display = false; + loader->svgParse->node->node.clip.userSpace = true; + + func(buf, bufLength, _attrParseClipPathNode, loader); + + return loader->svgParse->node; +} + + +static SvgNode* _createCssStyleNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::CssStyle); + if (!loader->svgParse->node) return nullptr; + + func(buf, bufLength, _attrParseCssStyleNode, loader); + + return loader->svgParse->node; +} + + +static SvgNode* _createSymbolNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Symbol); + if (!loader->svgParse->node) return nullptr; + + loader->svgParse->node->node.symbol.align = AspectRatioAlign::XMidYMid; + loader->svgParse->node->node.symbol.meetOrSlice = AspectRatioMeetOrSlice::Meet; + loader->svgParse->node->node.symbol.overflowVisible = false; + + loader->svgParse->node->node.symbol.hasViewBox = false; + loader->svgParse->node->node.symbol.hasWidth = false; + loader->svgParse->node->node.symbol.hasHeight = false; + loader->svgParse->node->node.symbol.vx = 0.0f; + loader->svgParse->node->node.symbol.vy = 0.0f; + + func(buf, bufLength, _attrParseSymbolNode, loader); + + return loader->svgParse->node; +} + + +static bool _attrParsePathNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgPathNode* path = &(node->node.path); + + if (!strcmp(key, "d")) { + if (path->path) free(path->path); + //Temporary: need to copy + path->path = _copyId(value); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Path); + + if (!loader->svgParse->node) return nullptr; + + func(buf, bufLength, _attrParsePathNode, loader); + + return loader->svgParse->node; +} + + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} circleTags[] = { + {"cx", SvgParserLengthType::Horizontal, sizeof("cx"), offsetof(SvgCircleNode, cx)}, + {"cy", SvgParserLengthType::Vertical, sizeof("cy"), offsetof(SvgCircleNode, cy)}, + {"r", SvgParserLengthType::Other, sizeof("r"), offsetof(SvgCircleNode, r)} +}; + + +/* parse the attributes for a circle element. + * https://www.w3.org/TR/SVG/shapes.html#CircleElement + */ +static bool _attrParseCircleNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgCircleNode* circle = &(node->node.circle); + unsigned char* array; + int sz = strlen(key); + + array = (unsigned char*)circle; + for (unsigned int i = 0; i < sizeof(circleTags) / sizeof(circleTags[0]); i++) { + if (circleTags[i].sz - 1 == sz && !strncmp(circleTags[i].tag, key, sz)) { + *((float*)(array + circleTags[i].offset)) = _toFloat(loader->svgParse, value, circleTags[i].type); + return true; + } + } + + if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createCircleNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Circle); + + if (!loader->svgParse->node) return nullptr; + + func(buf, bufLength, _attrParseCircleNode, loader); + return loader->svgParse->node; +} + + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} ellipseTags[] = { + {"cx", SvgParserLengthType::Horizontal, sizeof("cx"), offsetof(SvgEllipseNode, cx)}, + {"cy", SvgParserLengthType::Vertical, sizeof("cy"), offsetof(SvgEllipseNode, cy)}, + {"rx", SvgParserLengthType::Horizontal, sizeof("rx"), offsetof(SvgEllipseNode, rx)}, + {"ry", SvgParserLengthType::Vertical, sizeof("ry"), offsetof(SvgEllipseNode, ry)} +}; + + +/* parse the attributes for an ellipse element. + * https://www.w3.org/TR/SVG/shapes.html#EllipseElement + */ +static bool _attrParseEllipseNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgEllipseNode* ellipse = &(node->node.ellipse); + unsigned char* array; + int sz = strlen(key); + + array = (unsigned char*)ellipse; + for (unsigned int i = 0; i < sizeof(ellipseTags) / sizeof(ellipseTags[0]); i++) { + if (ellipseTags[i].sz - 1 == sz && !strncmp(ellipseTags[i].tag, key, sz)) { + *((float*)(array + ellipseTags[i].offset)) = _toFloat(loader->svgParse, value, ellipseTags[i].type); + return true; + } + } + + if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createEllipseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Ellipse); + + if (!loader->svgParse->node) return nullptr; + + func(buf, bufLength, _attrParseEllipseNode, loader); + return loader->svgParse->node; +} + + +static bool _attrParsePolygonPoints(const char* str, SvgPolygonNode* polygon) +{ + float num_x, num_y; + while (_parseNumber(&str, nullptr, &num_x) && _parseNumber(&str, nullptr, &num_y)) { + polygon->pts.push(num_x); + polygon->pts.push(num_y); + } + return true; +} + + +/* parse the attributes for a polygon element. + * https://www.w3.org/TR/SVG/shapes.html#PolylineElement + */ +static bool _attrParsePolygonNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgPolygonNode* polygon = nullptr; + + if (node->type == SvgNodeType::Polygon) polygon = &(node->node.polygon); + else polygon = &(node->node.polyline); + + if (!strcmp(key, "points")) { + return _attrParsePolygonPoints(value, polygon); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createPolygonNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Polygon); + + if (!loader->svgParse->node) return nullptr; + + func(buf, bufLength, _attrParsePolygonNode, loader); + return loader->svgParse->node; +} + + +static SvgNode* _createPolylineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Polyline); + + if (!loader->svgParse->node) return nullptr; + + func(buf, bufLength, _attrParsePolygonNode, loader); + return loader->svgParse->node; +} + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} rectTags[] = { + {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgRectNode, x)}, + {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgRectNode, y)}, + {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgRectNode, w)}, + {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgRectNode, h)}, + {"rx", SvgParserLengthType::Horizontal, sizeof("rx"), offsetof(SvgRectNode, rx)}, + {"ry", SvgParserLengthType::Vertical, sizeof("ry"), offsetof(SvgRectNode, ry)} +}; + + +/* parse the attributes for a rect element. + * https://www.w3.org/TR/SVG/shapes.html#RectElement + */ +static bool _attrParseRectNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgRectNode* rect = &(node->node.rect); + unsigned char* array; + bool ret = true; + int sz = strlen(key); + + array = (unsigned char*)rect; + for (unsigned int i = 0; i < sizeof(rectTags) / sizeof(rectTags[0]); i++) { + if (rectTags[i].sz - 1 == sz && !strncmp(rectTags[i].tag, key, sz)) { + *((float*)(array + rectTags[i].offset)) = _toFloat(loader->svgParse, value, rectTags[i].type); + + //Case if only rx or ry is declared + if (!strncmp(rectTags[i].tag, "rx", sz)) rect->hasRx = true; + if (!strncmp(rectTags[i].tag, "ry", sz)) rect->hasRy = true; + + if ((rect->rx >= FLOAT_EPSILON) && (rect->ry < FLOAT_EPSILON) && rect->hasRx && !rect->hasRy) rect->ry = rect->rx; + if ((rect->ry >= FLOAT_EPSILON) && (rect->rx < FLOAT_EPSILON) && !rect->hasRx && rect->hasRy) rect->rx = rect->ry; + return ret; + } + } + + if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); + } else if (!strcmp(key, "style")) { + ret = simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else { + ret = _parseStyleAttr(loader, key, value, false); + } + + return ret; +} + + +static SvgNode* _createRectNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Rect); + + if (!loader->svgParse->node) return nullptr; + + loader->svgParse->node->node.rect.hasRx = loader->svgParse->node->node.rect.hasRy = false; + + func(buf, bufLength, _attrParseRectNode, loader); + return loader->svgParse->node; +} + + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} lineTags[] = { + {"x1", SvgParserLengthType::Horizontal, sizeof("x1"), offsetof(SvgLineNode, x1)}, + {"y1", SvgParserLengthType::Vertical, sizeof("y1"), offsetof(SvgLineNode, y1)}, + {"x2", SvgParserLengthType::Horizontal, sizeof("x2"), offsetof(SvgLineNode, x2)}, + {"y2", SvgParserLengthType::Vertical, sizeof("y2"), offsetof(SvgLineNode, y2)} +}; + + +/* parse the attributes for a line element. + * https://www.w3.org/TR/SVG/shapes.html#LineElement + */ +static bool _attrParseLineNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgLineNode* line = &(node->node.line); + unsigned char* array; + int sz = strlen(key); + + array = (unsigned char*)line; + for (unsigned int i = 0; i < sizeof(lineTags) / sizeof(lineTags[0]); i++) { + if (lineTags[i].sz - 1 == sz && !strncmp(lineTags[i].tag, key, sz)) { + *((float*)(array + lineTags[i].offset)) = _toFloat(loader->svgParse, value, lineTags[i].type); + return true; + } + } + + if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createLineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Line); + + if (!loader->svgParse->node) return nullptr; + + func(buf, bufLength, _attrParseLineNode, loader); + return loader->svgParse->node; +} + + +static char* _idFromHref(const char* href) +{ + href = _skipSpace(href, nullptr); + if ((*href) == '#') href++; + return strdup(href); +} + + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} imageTags[] = { + {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgRectNode, x)}, + {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgRectNode, y)}, + {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgRectNode, w)}, + {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgRectNode, h)}, +}; + + +/* parse the attributes for a image element. + * https://www.w3.org/TR/SVG/embedded.html#ImageElement + */ +static bool _attrParseImageNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgImageNode* image = &(node->node.image); + unsigned char* array; + int sz = strlen(key); + + array = (unsigned char*)image; + for (unsigned int i = 0; i < sizeof(imageTags) / sizeof(imageTags[0]); i++) { + if (imageTags[i].sz - 1 == sz && !strncmp(imageTags[i].tag, key, sz)) { + *((float*)(array + imageTags[i].offset)) = _toFloat(loader->svgParse, value, imageTags[i].type); + return true; + } + } + + if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { + if (image->href && value) free(image->href); + image->href = _idFromHref(value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else if (!strcmp(key, "transform")) { + node->transform = _parseTransformationMatrix(value); + } else { + return _parseStyleAttr(loader, key, value); + } + return true; +} + + +static SvgNode* _createImageNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Image); + + if (!loader->svgParse->node) return nullptr; + + func(buf, bufLength, _attrParseImageNode, loader); + return loader->svgParse->node; +} + + +static SvgNode* _getDefsNode(SvgNode* node) +{ + if (!node) return nullptr; + + while (node->parent != nullptr) { + node = node->parent; + } + + if (node->type == SvgNodeType::Doc) return node->node.doc.defs; + if (node->type == SvgNodeType::Defs) return node; + + return nullptr; +} + + +static SvgNode* _findNodeById(SvgNode *node, const char* id) +{ + if (!node) return nullptr; + + SvgNode* result = nullptr; + if (node->id && !strcmp(node->id, id)) return node; + + if (node->child.count > 0) { + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + result = _findNodeById(*child, id); + if (result) break; + } + } + return result; +} + + +static SvgNode* _findParentById(SvgNode* node, char* id, SvgNode* doc) +{ + SvgNode *parent = node->parent; + while (parent != nullptr && parent != doc) { + if (parent->id && !strcmp(parent->id, id)) { + return parent; + } + parent = parent->parent; + } + return nullptr; +} + + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} useTags[] = { + {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgUseNode, x)}, + {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgUseNode, y)}, + {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgUseNode, w)}, + {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgUseNode, h)} +}; + + +static void _cloneNode(SvgNode* from, SvgNode* parent, int depth); +static bool _attrParseUseNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode *defs, *nodeFrom, *node = loader->svgParse->node; + char* id; + + SvgUseNode* use = &(node->node.use); + int sz = strlen(key); + unsigned char* array = (unsigned char*)use; + for (unsigned int i = 0; i < sizeof(useTags) / sizeof(useTags[0]); i++) { + if (useTags[i].sz - 1 == sz && !strncmp(useTags[i].tag, key, sz)) { + *((float*)(array + useTags[i].offset)) = _toFloat(loader->svgParse, value, useTags[i].type); + + if (useTags[i].offset == offsetof(SvgUseNode, w)) use->isWidthSet = true; + else if (useTags[i].offset == offsetof(SvgUseNode, h)) use->isHeightSet = true; + + return true; + } + } + + if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { + id = _idFromHref(value); + defs = _getDefsNode(node); + nodeFrom = _findNodeById(defs, id); + if (nodeFrom) { + if (!_findParentById(node, id, loader->doc)) { + _cloneNode(nodeFrom, node, 0); + if (nodeFrom->type == SvgNodeType::Symbol) use->symbol = nodeFrom; + } else { + TVGLOG("SVG", "%s is ancestor element. This reference is invalid.", id); + } + free(id); + } else { + //some svg export software include element at the end of the file + //if so the 'from' element won't be found now and we have to repeat finding + //after the whole file is parsed + _postpone(loader->cloneNodes, node, id); + } + } else { + return _attrParseGNode(data, key, value); + } + return true; +} + + +static SvgNode* _createUseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Use); + + if (!loader->svgParse->node) return nullptr; + + loader->svgParse->node->node.use.isWidthSet = false; + loader->svgParse->node->node.use.isHeightSet = false; + + func(buf, bufLength, _attrParseUseNode, loader); + return loader->svgParse->node; +} + + +//TODO: Implement 'text' primitive +static constexpr struct +{ + const char* tag; + int sz; + FactoryMethod tagHandler; +} graphicsTags[] = { + {"use", sizeof("use"), _createUseNode}, + {"circle", sizeof("circle"), _createCircleNode}, + {"ellipse", sizeof("ellipse"), _createEllipseNode}, + {"path", sizeof("path"), _createPathNode}, + {"polygon", sizeof("polygon"), _createPolygonNode}, + {"rect", sizeof("rect"), _createRectNode}, + {"polyline", sizeof("polyline"), _createPolylineNode}, + {"line", sizeof("line"), _createLineNode}, + {"image", sizeof("image"), _createImageNode} +}; + + +static constexpr struct +{ + const char* tag; + int sz; + FactoryMethod tagHandler; +} groupTags[] = { + {"defs", sizeof("defs"), _createDefsNode}, + {"g", sizeof("g"), _createGNode}, + {"svg", sizeof("svg"), _createSvgNode}, + {"mask", sizeof("mask"), _createMaskNode}, + {"clipPath", sizeof("clipPath"), _createClipPathNode}, + {"style", sizeof("style"), _createCssStyleNode}, + {"symbol", sizeof("symbol"), _createSymbolNode} +}; + + +#define FIND_FACTORY(Short_Name, Tags_Array) \ + static FactoryMethod \ + _find##Short_Name##Factory(const char* name) \ + { \ + unsigned int i; \ + int sz = strlen(name); \ + \ + for (i = 0; i < sizeof(Tags_Array) / sizeof(Tags_Array[0]); i++) { \ + if (Tags_Array[i].sz - 1 == sz && !strncmp(Tags_Array[i].tag, name, sz)) { \ + return Tags_Array[i].tagHandler; \ + } \ + } \ + return nullptr; \ + } + +FIND_FACTORY(Group, groupTags) +FIND_FACTORY(Graphics, graphicsTags) + + +FillSpread _parseSpreadValue(const char* value) +{ + auto spread = FillSpread::Pad; + + if (!strcmp(value, "reflect")) { + spread = FillSpread::Reflect; + } else if (!strcmp(value, "repeat")) { + spread = FillSpread::Repeat; + } + + return spread; +} + + +static void _handleRadialCxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->cx = _gradientToFloat(loader->svgParse, value, radial->isCxPercentage); + if (!loader->svgParse->gradient.parsedFx) { + radial->fx = radial->cx; + radial->isFxPercentage = radial->isCxPercentage; + } +} + + +static void _handleRadialCyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->cy = _gradientToFloat(loader->svgParse, value, radial->isCyPercentage); + if (!loader->svgParse->gradient.parsedFy) { + radial->fy = radial->cy; + radial->isFyPercentage = radial->isCyPercentage; + } +} + + +static void _handleRadialFxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->fx = _gradientToFloat(loader->svgParse, value, radial->isFxPercentage); + loader->svgParse->gradient.parsedFx = true; +} + + +static void _handleRadialFyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->fy = _gradientToFloat(loader->svgParse, value, radial->isFyPercentage); + loader->svgParse->gradient.parsedFy = true; +} + + +static void _handleRadialFrAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->fr = _gradientToFloat(loader->svgParse, value, radial->isFrPercentage); +} + + +static void _handleRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->r = _gradientToFloat(loader->svgParse, value, radial->isRPercentage); +} + + +static void _recalcRadialCxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (userSpace && !radial->isCxPercentage) radial->cx = radial->cx / loader->svgParse->global.w; +} + + +static void _recalcRadialCyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (userSpace && !radial->isCyPercentage) radial->cy = radial->cy / loader->svgParse->global.h; +} + + +static void _recalcRadialFxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (userSpace && !radial->isFxPercentage) radial->fx = radial->fx / loader->svgParse->global.w; +} + + +static void _recalcRadialFyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (userSpace && !radial->isFyPercentage) radial->fy = radial->fy / loader->svgParse->global.h; +} + + +static void _recalcRadialFrAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + // scaling factor based on the Units paragraph from : https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html + if (userSpace && !radial->isFrPercentage) radial->fr = radial->fr / (sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0)); +} + + +static void _recalcRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + // scaling factor based on the Units paragraph from : https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html + if (userSpace && !radial->isRPercentage) radial->r = radial->r / (sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0)); +} + + +static void _recalcInheritedRadialCxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (!radial->isCxPercentage) { + if (userSpace) radial->cx /= loader->svgParse->global.w; + else radial->cx *= loader->svgParse->global.w; + } +} + + +static void _recalcInheritedRadialCyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (!radial->isCyPercentage) { + if (userSpace) radial->cy /= loader->svgParse->global.h; + else radial->cy *= loader->svgParse->global.h; + } +} + + +static void _recalcInheritedRadialFxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (!radial->isFxPercentage) { + if (userSpace) radial->fx /= loader->svgParse->global.w; + else radial->fx *= loader->svgParse->global.w; + } +} + + +static void _recalcInheritedRadialFyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (!radial->isFyPercentage) { + if (userSpace) radial->fy /= loader->svgParse->global.h; + else radial->fy *= loader->svgParse->global.h; + } +} + + +static void _recalcInheritedRadialFrAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (!radial->isFrPercentage) { + if (userSpace) radial->fr /= sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0); + else radial->fr *= sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0); + } +} + + +static void _recalcInheritedRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (!radial->isRPercentage) { + if (userSpace) radial->r /= sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0); + else radial->r *= sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0); + } +} + + +static void _inheritRadialCxAttr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->radial->cx = from->radial->cx; + to->radial->isCxPercentage = from->radial->isCxPercentage; + to->flags = (to->flags | SvgGradientFlags::Cx); +} + + +static void _inheritRadialCyAttr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->radial->cy = from->radial->cy; + to->radial->isCyPercentage = from->radial->isCyPercentage; + to->flags = (to->flags | SvgGradientFlags::Cy); +} + + +static void _inheritRadialFxAttr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->radial->fx = from->radial->fx; + to->radial->isFxPercentage = from->radial->isFxPercentage; + to->flags = (to->flags | SvgGradientFlags::Fx); +} + + +static void _inheritRadialFyAttr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->radial->fy = from->radial->fy; + to->radial->isFyPercentage = from->radial->isFyPercentage; + to->flags = (to->flags | SvgGradientFlags::Fy); +} + + +static void _inheritRadialFrAttr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->radial->fr = from->radial->fr; + to->radial->isFrPercentage = from->radial->isFrPercentage; + to->flags = (to->flags | SvgGradientFlags::Fr); +} + + +static void _inheritRadialRAttr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->radial->r = from->radial->r; + to->radial->isRPercentage = from->radial->isRPercentage; + to->flags = (to->flags | SvgGradientFlags::R); +} + + +typedef void (*radialMethod)(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value); +typedef void (*radialInheritMethod)(SvgStyleGradient* to, SvgStyleGradient* from); +typedef void (*radialMethodRecalc)(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace); + + +#define RADIAL_DEF(Name, Name1, Flag) \ + { \ +#Name, sizeof(#Name), _handleRadial##Name1##Attr, _inheritRadial##Name1##Attr, _recalcRadial##Name1##Attr, _recalcInheritedRadial##Name1##Attr, Flag \ + } + + +static constexpr struct +{ + const char* tag; + int sz; + radialMethod tagHandler; + radialInheritMethod tagInheritHandler; + radialMethodRecalc tagRecalc; + radialMethodRecalc tagInheritedRecalc; + SvgGradientFlags flag; +} radialTags[] = { + RADIAL_DEF(cx, Cx, SvgGradientFlags::Cx), + RADIAL_DEF(cy, Cy, SvgGradientFlags::Cy), + RADIAL_DEF(fx, Fx, SvgGradientFlags::Fx), + RADIAL_DEF(fy, Fy, SvgGradientFlags::Fy), + RADIAL_DEF(r, R, SvgGradientFlags::R), + RADIAL_DEF(fr, Fr, SvgGradientFlags::Fr) +}; + + +static bool _attrParseRadialGradientNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgStyleGradient* grad = loader->svgParse->styleGrad; + SvgRadialGradient* radial = grad->radial; + int sz = strlen(key); + + for (unsigned int i = 0; i < sizeof(radialTags) / sizeof(radialTags[0]); i++) { + if (radialTags[i].sz - 1 == sz && !strncmp(radialTags[i].tag, key, sz)) { + radialTags[i].tagHandler(loader, radial, value); + grad->flags = (grad->flags | radialTags[i].flag); + return true; + } + } + + if (!strcmp(key, "id")) { + if (grad->id && value) free(grad->id); + grad->id = _copyId(value); + } else if (!strcmp(key, "spreadMethod")) { + grad->spread = _parseSpreadValue(value); + grad->flags = (grad->flags | SvgGradientFlags::SpreadMethod); + } else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { + if (grad->ref && value) free(grad->ref); + grad->ref = _idFromHref(value); + } else if (!strcmp(key, "gradientUnits")) { + if (!strcmp(value, "userSpaceOnUse")) grad->userSpace = true; + grad->flags = (grad->flags | SvgGradientFlags::GradientUnits); + } else if (!strcmp(key, "gradientTransform")) { + grad->transform = _parseTransformationMatrix(value); + } else { + return false; + } + + return true; +} + + +static SvgStyleGradient* _createRadialGradient(SvgLoaderData* loader, const char* buf, unsigned bufLength) +{ + auto grad = (SvgStyleGradient*)(calloc(1, sizeof(SvgStyleGradient))); + loader->svgParse->styleGrad = grad; + + grad->flags = SvgGradientFlags::None; + grad->type = SvgGradientType::Radial; + grad->userSpace = false; + grad->radial = (SvgRadialGradient*)calloc(1, sizeof(SvgRadialGradient)); + if (!grad->radial) { + grad->clear(); + free(grad); + return nullptr; + } + /** + * Default values of gradient transformed into global percentage + */ + grad->radial->cx = 0.5f; + grad->radial->cy = 0.5f; + grad->radial->fx = 0.5f; + grad->radial->fy = 0.5f; + grad->radial->r = 0.5f; + grad->radial->isCxPercentage = true; + grad->radial->isCyPercentage = true; + grad->radial->isFxPercentage = true; + grad->radial->isFyPercentage = true; + grad->radial->isRPercentage = true; + grad->radial->isFrPercentage = true; + + loader->svgParse->gradient.parsedFx = false; + loader->svgParse->gradient.parsedFy = false; + simpleXmlParseAttributes(buf, bufLength, + _attrParseRadialGradientNode, loader); + + for (unsigned int i = 0; i < sizeof(radialTags) / sizeof(radialTags[0]); i++) { + radialTags[i].tagRecalc(loader, grad->radial, grad->userSpace); + } + + return loader->svgParse->styleGrad; +} + + +static bool _attrParseStopsStyle(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + auto stop = &loader->svgParse->gradStop; + + if (!strcmp(key, "stop-opacity")) { + stop->a = _toOpacity(value); + loader->svgParse->flags = (loader->svgParse->flags | SvgStopStyleFlags::StopOpacity); + } else if (!strcmp(key, "stop-color")) { + if (_toColor(value, &stop->r, &stop->g, &stop->b, nullptr)) { + loader->svgParse->flags = (loader->svgParse->flags | SvgStopStyleFlags::StopColor); + } + } else { + return false; + } + + return true; +} + + +static bool _attrParseStops(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + auto stop = &loader->svgParse->gradStop; + + if (!strcmp(key, "offset")) { + stop->offset = _toOffset(value); + } else if (!strcmp(key, "stop-opacity")) { + if (!(loader->svgParse->flags & SvgStopStyleFlags::StopOpacity)) { + stop->a = _toOpacity(value); + } + } else if (!strcmp(key, "stop-color")) { + if (!(loader->svgParse->flags & SvgStopStyleFlags::StopColor)) { + _toColor(value, &stop->r, &stop->g, &stop->b, nullptr); + } + } else if (!strcmp(key, "style")) { + simpleXmlParseW3CAttribute(value, strlen(value), _attrParseStopsStyle, data); + } else { + return false; + } + + return true; +} + + +static void _handleLinearX1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value) +{ + linear->x1 = _gradientToFloat(loader->svgParse, value, linear->isX1Percentage); +} + + +static void _handleLinearY1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value) +{ + linear->y1 = _gradientToFloat(loader->svgParse, value, linear->isY1Percentage); +} + + +static void _handleLinearX2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value) +{ + linear->x2 = _gradientToFloat(loader->svgParse, value, linear->isX2Percentage); +} + + +static void _handleLinearY2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value) +{ + linear->y2 = _gradientToFloat(loader->svgParse, value, linear->isY2Percentage); +} + + +static void _recalcLinearX1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (userSpace && !linear->isX1Percentage) linear->x1 = linear->x1 / loader->svgParse->global.w; +} + + +static void _recalcLinearY1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (userSpace && !linear->isY1Percentage) linear->y1 = linear->y1 / loader->svgParse->global.h; +} + + +static void _recalcLinearX2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (userSpace && !linear->isX2Percentage) linear->x2 = linear->x2 / loader->svgParse->global.w; +} + + +static void _recalcLinearY2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (userSpace && !linear->isY2Percentage) linear->y2 = linear->y2 / loader->svgParse->global.h; +} + + +static void _recalcInheritedLinearX1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (!linear->isX1Percentage) { + if (userSpace) linear->x1 /= loader->svgParse->global.w; + else linear->x1 *= loader->svgParse->global.w; + } +} + + +static void _recalcInheritedLinearX2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (!linear->isX2Percentage) { + if (userSpace) linear->x2 /= loader->svgParse->global.w; + else linear->x2 *= loader->svgParse->global.w; + } +} + + +static void _recalcInheritedLinearY1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (!linear->isY1Percentage) { + if (userSpace) linear->y1 /= loader->svgParse->global.h; + else linear->y1 *= loader->svgParse->global.h; + } +} + + +static void _recalcInheritedLinearY2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (!linear->isY2Percentage) { + if (userSpace) linear->y2 /= loader->svgParse->global.h; + else linear->y2 *= loader->svgParse->global.h; + } +} + + +static void _inheritLinearX1Attr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->linear->x1 = from->linear->x1; + to->linear->isX1Percentage = from->linear->isX1Percentage; + to->flags = (to->flags | SvgGradientFlags::X1); +} + + +static void _inheritLinearX2Attr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->linear->x2 = from->linear->x2; + to->linear->isX2Percentage = from->linear->isX2Percentage; + to->flags = (to->flags | SvgGradientFlags::X2); +} + + +static void _inheritLinearY1Attr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->linear->y1 = from->linear->y1; + to->linear->isY1Percentage = from->linear->isY1Percentage; + to->flags = (to->flags | SvgGradientFlags::Y1); +} + + +static void _inheritLinearY2Attr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->linear->y2 = from->linear->y2; + to->linear->isY2Percentage = from->linear->isY2Percentage; + to->flags = (to->flags | SvgGradientFlags::Y2); +} + + +typedef void (*Linear_Method)(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value); +typedef void (*Linear_Inherit_Method)(SvgStyleGradient* to, SvgStyleGradient* from); +typedef void (*Linear_Method_Recalc)(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace); + + +#define LINEAR_DEF(Name, Name1, Flag) \ + { \ +#Name, sizeof(#Name), _handleLinear##Name1##Attr, _inheritLinear##Name1##Attr, _recalcLinear##Name1##Attr, _recalcInheritedLinear##Name1##Attr, Flag \ + } + + +static constexpr struct +{ + const char* tag; + int sz; + Linear_Method tagHandler; + Linear_Inherit_Method tagInheritHandler; + Linear_Method_Recalc tagRecalc; + Linear_Method_Recalc tagInheritedRecalc; + SvgGradientFlags flag; +} linear_tags[] = { + LINEAR_DEF(x1, X1, SvgGradientFlags::X1), + LINEAR_DEF(y1, Y1, SvgGradientFlags::Y1), + LINEAR_DEF(x2, X2, SvgGradientFlags::X2), + LINEAR_DEF(y2, Y2, SvgGradientFlags::Y2) +}; + + +static bool _attrParseLinearGradientNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgStyleGradient* grad = loader->svgParse->styleGrad; + SvgLinearGradient* linear = grad->linear; + int sz = strlen(key); + + for (unsigned int i = 0; i < sizeof(linear_tags) / sizeof(linear_tags[0]); i++) { + if (linear_tags[i].sz - 1 == sz && !strncmp(linear_tags[i].tag, key, sz)) { + linear_tags[i].tagHandler(loader, linear, value); + grad->flags = (grad->flags | linear_tags[i].flag); + return true; + } + } + + if (!strcmp(key, "id")) { + if (grad->id && value) free(grad->id); + grad->id = _copyId(value); + } else if (!strcmp(key, "spreadMethod")) { + grad->spread = _parseSpreadValue(value); + grad->flags = (grad->flags | SvgGradientFlags::SpreadMethod); + } else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { + if (grad->ref && value) free(grad->ref); + grad->ref = _idFromHref(value); + } else if (!strcmp(key, "gradientUnits")) { + if (!strcmp(value, "userSpaceOnUse")) grad->userSpace = true; + grad->flags = (grad->flags | SvgGradientFlags::GradientUnits); + } else if (!strcmp(key, "gradientTransform")) { + grad->transform = _parseTransformationMatrix(value); + } else { + return false; + } + + return true; +} + + +static SvgStyleGradient* _createLinearGradient(SvgLoaderData* loader, const char* buf, unsigned bufLength) +{ + auto grad = (SvgStyleGradient*)(calloc(1, sizeof(SvgStyleGradient))); + loader->svgParse->styleGrad = grad; + + grad->flags = SvgGradientFlags::None; + grad->type = SvgGradientType::Linear; + grad->userSpace = false; + grad->linear = (SvgLinearGradient*)calloc(1, sizeof(SvgLinearGradient)); + if (!grad->linear) { + grad->clear(); + free(grad); + return nullptr; + } + /** + * Default value of x2 is 100% - transformed to the global percentage + */ + grad->linear->x2 = 1.0f; + grad->linear->isX2Percentage = true; + + simpleXmlParseAttributes(buf, bufLength, _attrParseLinearGradientNode, loader); + + for (unsigned int i = 0; i < sizeof(linear_tags) / sizeof(linear_tags[0]); i++) { + linear_tags[i].tagRecalc(loader, grad->linear, grad->userSpace); + } + + return loader->svgParse->styleGrad; +} + + +#define GRADIENT_DEF(Name, Name1) \ + { \ +#Name, sizeof(#Name), _create##Name1 \ + } + + +/** + * In the case when the gradients lengths are given as numbers (not percentages) + * in the current user coordinate system, they are recalculated into percentages + * related to the canvas width and height. + */ +static constexpr struct +{ + const char* tag; + int sz; + GradientFactoryMethod tagHandler; +} gradientTags[] = { + GRADIENT_DEF(linearGradient, LinearGradient), + GRADIENT_DEF(radialGradient, RadialGradient) +}; + + +static GradientFactoryMethod _findGradientFactory(const char* name) +{ + int sz = strlen(name); + + for (unsigned int i = 0; i < sizeof(gradientTags) / sizeof(gradientTags[0]); i++) { + if (gradientTags[i].sz - 1 == sz && !strncmp(gradientTags[i].tag, name, sz)) { + return gradientTags[i].tagHandler; + } + } + return nullptr; +} + + +static void _cloneGradStops(Array& dst, const Array& src) +{ + for (uint32_t i = 0; i < src.count; ++i) { + dst.push(src[i]); + } +} + + +static void _inheritGradient(SvgLoaderData* loader, SvgStyleGradient* to, SvgStyleGradient* from) +{ + if (!to || !from) return; + + if (!(to->flags & SvgGradientFlags::SpreadMethod) && (from->flags & SvgGradientFlags::SpreadMethod)) { + to->spread = from->spread; + to->flags = (to->flags | SvgGradientFlags::SpreadMethod); + } + bool gradUnitSet = (to->flags & SvgGradientFlags::GradientUnits); + if (!(to->flags & SvgGradientFlags::GradientUnits) && (from->flags & SvgGradientFlags::GradientUnits)) { + to->userSpace = from->userSpace; + to->flags = (to->flags | SvgGradientFlags::GradientUnits); + } + + if (!to->transform && from->transform) { + to->transform = (Matrix*)malloc(sizeof(Matrix)); + if (to->transform) memcpy(to->transform, from->transform, sizeof(Matrix)); + } + + if (to->type == SvgGradientType::Linear) { + for (unsigned int i = 0; i < sizeof(linear_tags) / sizeof(linear_tags[0]); i++) { + bool coordSet = to->flags & linear_tags[i].flag; + if (!(to->flags & linear_tags[i].flag) && (from->flags & linear_tags[i].flag)) { + linear_tags[i].tagInheritHandler(to, from); + } + + //GradUnits not set directly, coord set + if (!gradUnitSet && coordSet) { + linear_tags[i].tagRecalc(loader, to->linear, to->userSpace); + } + //GradUnits set, coord not set directly + if (to->userSpace == from->userSpace) continue; + if (gradUnitSet && !coordSet) { + linear_tags[i].tagInheritedRecalc(loader, to->linear, to->userSpace); + } + } + } else if (to->type == SvgGradientType::Radial) { + for (unsigned int i = 0; i < sizeof(radialTags) / sizeof(radialTags[0]); i++) { + bool coordSet = (to->flags & radialTags[i].flag); + if (!(to->flags & radialTags[i].flag) && (from->flags & radialTags[i].flag)) { + radialTags[i].tagInheritHandler(to, from); + } + + //GradUnits not set directly, coord set + if (!gradUnitSet && coordSet) { + radialTags[i].tagRecalc(loader, to->radial, to->userSpace); + //If fx and fy are not set, set cx and cy. + if (!strcmp(radialTags[i].tag, "cx") && !(to->flags & SvgGradientFlags::Fx)) to->radial->fx = to->radial->cx; + if (!strcmp(radialTags[i].tag, "cy") && !(to->flags & SvgGradientFlags::Fy)) to->radial->fy = to->radial->cy; + } + //GradUnits set, coord not set directly + if (to->userSpace == from->userSpace) continue; + if (gradUnitSet && !coordSet) { + //If fx and fx are not set, do not call recalc. + if (!strcmp(radialTags[i].tag, "fx") && !(to->flags & SvgGradientFlags::Fx)) continue; + if (!strcmp(radialTags[i].tag, "fy") && !(to->flags & SvgGradientFlags::Fy)) continue; + radialTags[i].tagInheritedRecalc(loader, to->radial, to->userSpace); + } + } + } + + if (to->stops.empty()) _cloneGradStops(to->stops, from->stops); +} + + +static SvgStyleGradient* _cloneGradient(SvgStyleGradient* from) +{ + if (!from) return nullptr; + + auto grad = (SvgStyleGradient*)(calloc(1, sizeof(SvgStyleGradient))); + if (!grad) return nullptr; + + grad->type = from->type; + grad->id = from->id ? _copyId(from->id) : nullptr; + grad->ref = from->ref ? _copyId(from->ref) : nullptr; + grad->spread = from->spread; + grad->userSpace = from->userSpace; + grad->flags = from->flags; + + if (from->transform) { + grad->transform = (Matrix*)calloc(1, sizeof(Matrix)); + if (grad->transform) memcpy(grad->transform, from->transform, sizeof(Matrix)); + } + + if (grad->type == SvgGradientType::Linear) { + grad->linear = (SvgLinearGradient*)calloc(1, sizeof(SvgLinearGradient)); + if (!grad->linear) goto error_grad_alloc; + memcpy(grad->linear, from->linear, sizeof(SvgLinearGradient)); + } else if (grad->type == SvgGradientType::Radial) { + grad->radial = (SvgRadialGradient*)calloc(1, sizeof(SvgRadialGradient)); + if (!grad->radial) goto error_grad_alloc; + memcpy(grad->radial, from->radial, sizeof(SvgRadialGradient)); + } + + _cloneGradStops(grad->stops, from->stops); + + return grad; + + error_grad_alloc: + if (grad) { + grad->clear(); + free(grad); + } + return nullptr; +} + + +static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* parent) +{ + if (parent == nullptr) return; + //Inherit the property of parent if not present in child. + if (!child->curColorSet) { + child->color = parent->color; + child->curColorSet = parent->curColorSet; + } + if (!(child->flags & SvgStyleFlags::PaintOrder)) { + child->paintOrder = parent->paintOrder; + } + //Fill + if (!(child->fill.flags & SvgFillFlags::Paint)) { + child->fill.paint.color = parent->fill.paint.color; + child->fill.paint.none = parent->fill.paint.none; + child->fill.paint.curColor = parent->fill.paint.curColor; + if (parent->fill.paint.url) { + if (child->fill.paint.url) free(child->fill.paint.url); + child->fill.paint.url = _copyId(parent->fill.paint.url); + } + } + if (!(child->fill.flags & SvgFillFlags::Opacity)) { + child->fill.opacity = parent->fill.opacity; + } + if (!(child->fill.flags & SvgFillFlags::FillRule)) { + child->fill.fillRule = parent->fill.fillRule; + } + //Stroke + if (!(child->stroke.flags & SvgStrokeFlags::Paint)) { + child->stroke.paint.color = parent->stroke.paint.color; + child->stroke.paint.none = parent->stroke.paint.none; + child->stroke.paint.curColor = parent->stroke.paint.curColor; + if (parent->stroke.paint.url) { + if (child->stroke.paint.url) free(child->stroke.paint.url); + child->stroke.paint.url = _copyId(parent->stroke.paint.url); + } + } + if (!(child->stroke.flags & SvgStrokeFlags::Opacity)) { + child->stroke.opacity = parent->stroke.opacity; + } + if (!(child->stroke.flags & SvgStrokeFlags::Width)) { + child->stroke.width = parent->stroke.width; + } + if (!(child->stroke.flags & SvgStrokeFlags::Dash)) { + if (parent->stroke.dash.array.count > 0) { + child->stroke.dash.array.clear(); + child->stroke.dash.array.reserve(parent->stroke.dash.array.count); + for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) { + child->stroke.dash.array.push(parent->stroke.dash.array[i]); + } + } + } + if (!(child->stroke.flags & SvgStrokeFlags::DashOffset)) { + child->stroke.dash.offset = parent->stroke.dash.offset; + } + if (!(child->stroke.flags & SvgStrokeFlags::Cap)) { + child->stroke.cap = parent->stroke.cap; + } + if (!(child->stroke.flags & SvgStrokeFlags::Join)) { + child->stroke.join = parent->stroke.join; + } + if (!(child->stroke.flags & SvgStrokeFlags::Miterlimit)) { + child->stroke.miterlimit = parent->stroke.miterlimit; + } +} + + +static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from) +{ + if (from == nullptr) return; + //Copy the properties of 'from' only if they were explicitly set (not the default ones). + if (from->curColorSet) { + to->color = from->color; + to->curColorSet = true; + } + if (from->flags & SvgStyleFlags::Opacity) { + to->opacity = from->opacity; + } + if (from->flags & SvgStyleFlags::PaintOrder) { + to->paintOrder = from->paintOrder; + } + if (from->flags & SvgStyleFlags::Display) { + to->display = from->display; + } + //Fill + to->fill.flags = (to->fill.flags | from->fill.flags); + if (from->fill.flags & SvgFillFlags::Paint) { + to->fill.paint.color = from->fill.paint.color; + to->fill.paint.none = from->fill.paint.none; + to->fill.paint.curColor = from->fill.paint.curColor; + if (from->fill.paint.url) { + if (to->fill.paint.url) free(to->fill.paint.url); + to->fill.paint.url = _copyId(from->fill.paint.url); + } + } + if (from->fill.flags & SvgFillFlags::Opacity) { + to->fill.opacity = from->fill.opacity; + } + if (from->fill.flags & SvgFillFlags::FillRule) { + to->fill.fillRule = from->fill.fillRule; + } + //Stroke + to->stroke.flags = (to->stroke.flags | from->stroke.flags); + if (from->stroke.flags & SvgStrokeFlags::Paint) { + to->stroke.paint.color = from->stroke.paint.color; + to->stroke.paint.none = from->stroke.paint.none; + to->stroke.paint.curColor = from->stroke.paint.curColor; + if (from->stroke.paint.url) { + if (to->stroke.paint.url) free(to->stroke.paint.url); + to->stroke.paint.url = _copyId(from->stroke.paint.url); + } + } + if (from->stroke.flags & SvgStrokeFlags::Opacity) { + to->stroke.opacity = from->stroke.opacity; + } + if (from->stroke.flags & SvgStrokeFlags::Width) { + to->stroke.width = from->stroke.width; + } + if (from->stroke.flags & SvgStrokeFlags::Dash) { + if (from->stroke.dash.array.count > 0) { + to->stroke.dash.array.clear(); + to->stroke.dash.array.reserve(from->stroke.dash.array.count); + for (uint32_t i = 0; i < from->stroke.dash.array.count; ++i) { + to->stroke.dash.array.push(from->stroke.dash.array[i]); + } + } + } + if (from->stroke.flags & SvgStrokeFlags::DashOffset) { + to->stroke.dash.offset = from->stroke.dash.offset; + } + if (from->stroke.flags & SvgStrokeFlags::Cap) { + to->stroke.cap = from->stroke.cap; + } + if (from->stroke.flags & SvgStrokeFlags::Join) { + to->stroke.join = from->stroke.join; + } + if (from->stroke.flags & SvgStrokeFlags::Miterlimit) { + to->stroke.miterlimit = from->stroke.miterlimit; + } +} + + +static void _copyAttr(SvgNode* to, const SvgNode* from) +{ + //Copy matrix attribute + if (from->transform) { + to->transform = (Matrix*)malloc(sizeof(Matrix)); + if (to->transform) *to->transform = *from->transform; + } + //Copy style attribute + _styleCopy(to->style, from->style); + to->style->flags = (to->style->flags | from->style->flags); + if (from->style->clipPath.url) { + if (to->style->clipPath.url) free(to->style->clipPath.url); + to->style->clipPath.url = strdup(from->style->clipPath.url); + } + if (from->style->mask.url) { + if (to->style->mask.url) free(to->style->mask.url); + to->style->mask.url = strdup(from->style->mask.url); + } + + //Copy node attribute + switch (from->type) { + case SvgNodeType::Circle: { + to->node.circle.cx = from->node.circle.cx; + to->node.circle.cy = from->node.circle.cy; + to->node.circle.r = from->node.circle.r; + break; + } + case SvgNodeType::Ellipse: { + to->node.ellipse.cx = from->node.ellipse.cx; + to->node.ellipse.cy = from->node.ellipse.cy; + to->node.ellipse.rx = from->node.ellipse.rx; + to->node.ellipse.ry = from->node.ellipse.ry; + break; + } + case SvgNodeType::Rect: { + to->node.rect.x = from->node.rect.x; + to->node.rect.y = from->node.rect.y; + to->node.rect.w = from->node.rect.w; + to->node.rect.h = from->node.rect.h; + to->node.rect.rx = from->node.rect.rx; + to->node.rect.ry = from->node.rect.ry; + to->node.rect.hasRx = from->node.rect.hasRx; + to->node.rect.hasRy = from->node.rect.hasRy; + break; + } + case SvgNodeType::Line: { + to->node.line.x1 = from->node.line.x1; + to->node.line.y1 = from->node.line.y1; + to->node.line.x2 = from->node.line.x2; + to->node.line.y2 = from->node.line.y2; + break; + } + case SvgNodeType::Path: { + if (from->node.path.path) { + if (to->node.path.path) free(to->node.path.path); + to->node.path.path = strdup(from->node.path.path); + } + break; + } + case SvgNodeType::Polygon: { + if ((to->node.polygon.pts.count = from->node.polygon.pts.count)) { + to->node.polygon.pts = from->node.polygon.pts; + } + break; + } + case SvgNodeType::Polyline: { + if ((to->node.polyline.pts.count = from->node.polyline.pts.count)) { + to->node.polyline.pts = from->node.polyline.pts; + } + break; + } + case SvgNodeType::Image: { + to->node.image.x = from->node.image.x; + to->node.image.y = from->node.image.y; + to->node.image.w = from->node.image.w; + to->node.image.h = from->node.image.h; + if (from->node.image.href) { + if (to->node.image.href) free(to->node.image.href); + to->node.image.href = strdup(from->node.image.href); + } + break; + } + case SvgNodeType::Use: { + to->node.use.x = from->node.use.x; + to->node.use.y = from->node.use.y; + to->node.use.w = from->node.use.w; + to->node.use.h = from->node.use.h; + to->node.use.isWidthSet = from->node.use.isWidthSet; + to->node.use.isHeightSet = from->node.use.isHeightSet; + to->node.use.symbol = from->node.use.symbol; + break; + } + default: { + break; + } + } +} + + +static void _cloneNode(SvgNode* from, SvgNode* parent, int depth) +{ + /* Exception handling: Prevent invalid SVG data input. + The size is the arbitrary value, we need an experimental size. */ + if (depth == 8192) { + TVGERR("SVG", "Infinite recursive call - stopped after %d calls! Svg file may be incorrectly formatted.", depth); + return; + } + + SvgNode* newNode; + if (!from || !parent || from == parent) return; + + newNode = _createNode(parent, from->type); + if (!newNode) return; + + _styleInherit(newNode->style, parent->style); + _copyAttr(newNode, from); + + auto child = from->child.data; + for (uint32_t i = 0; i < from->child.count; ++i, ++child) { + _cloneNode(*child, newNode, depth + 1); + } +} + + +static void _clonePostponedNodes(Array* cloneNodes, SvgNode* doc) +{ + for (uint32_t i = 0; i < cloneNodes->count; ++i) { + auto nodeIdPair = (*cloneNodes)[i]; + auto defs = _getDefsNode(nodeIdPair.node); + auto nodeFrom = _findNodeById(defs, nodeIdPair.id); + if (!nodeFrom) nodeFrom = _findNodeById(doc, nodeIdPair.id); + if (!_findParentById(nodeIdPair.node, nodeIdPair.id, doc)) { + _cloneNode(nodeFrom, nodeIdPair.node, 0); + if (nodeFrom && nodeFrom->type == SvgNodeType::Symbol && nodeIdPair.node->type == SvgNodeType::Use) { + nodeIdPair.node->node.use.symbol = nodeFrom; + } + } else { + TVGLOG("SVG", "%s is ancestor element. This reference is invalid.", nodeIdPair.id); + } + free(nodeIdPair.id); + } +} + + +static constexpr struct +{ + const char* tag; + size_t sz; +} popArray[] = { + {"g", sizeof("g")}, + {"svg", sizeof("svg")}, + {"defs", sizeof("defs")}, + {"mask", sizeof("mask")}, + {"clipPath", sizeof("clipPath")}, + {"style", sizeof("style")}, + {"symbol", sizeof("symbol")} +}; + + +static void _svgLoaderParserXmlClose(SvgLoaderData* loader, const char* content) +{ + content = _skipSpace(content, nullptr); + + for (unsigned int i = 0; i < sizeof(popArray) / sizeof(popArray[0]); i++) { + if (!strncmp(content, popArray[i].tag, popArray[i].sz - 1)) { + loader->stack.pop(); + break; + } + } + + for (unsigned int i = 0; i < sizeof(graphicsTags) / sizeof(graphicsTags[0]); i++) { + if (!strncmp(content, graphicsTags[i].tag, graphicsTags[i].sz - 1)) { + loader->currentGraphicsNode = nullptr; + loader->stack.pop(); + break; + } + } + + loader->level--; +} + + +static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content, unsigned int length, bool empty) +{ + const char* attrs = nullptr; + int attrsLength = 0; + int sz = length; + char tagName[20] = ""; + FactoryMethod method; + GradientFactoryMethod gradientMethod; + SvgNode *node = nullptr, *parent = nullptr; + loader->level++; + attrs = simpleXmlFindAttributesTag(content, length); + + if (!attrs) { + //Parse the empty tag + attrs = content; + while ((attrs != nullptr) && *attrs != '>') attrs++; + if (empty) attrs--; + } + + if (attrs) { + //Find out the tag name starting from content till sz length + sz = attrs - content; + while ((sz > 0) && (isspace(content[sz - 1]))) sz--; + if ((unsigned)sz >= sizeof(tagName)) return; + strncpy(tagName, content, sz); + tagName[sz] = '\0'; + attrsLength = length - sz; + } + + if ((method = _findGroupFactory(tagName))) { + //Group + if (empty) return; + if (!loader->doc) { + if (strcmp(tagName, "svg")) return; //Not a valid svg document + node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes); + loader->doc = node; + } else { + if (!strcmp(tagName, "svg")) return; //Already loaded (SvgNodeType::Doc) tag + if (loader->stack.count > 0) parent = loader->stack.last(); + else parent = loader->doc; + if (!strcmp(tagName, "style")) { + // TODO: For now only the first style node is saved. After the css id selector + // is introduced this if condition shouldn't be necessary any more + if (!loader->cssStyle) { + node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes); + loader->cssStyle = node; + loader->doc->node.doc.style = node; + loader->style = true; + } + } else { + node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes); + } + } + + if (!node) return; + if (node->type != SvgNodeType::Defs || !empty) { + loader->stack.push(node); + } + } else if ((method = _findGraphicsFactory(tagName))) { + if (loader->stack.count > 0) parent = loader->stack.last(); + else parent = loader->doc; + node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes); + if (node && !empty) { + auto defs = _createDefsNode(loader, nullptr, nullptr, 0, nullptr); + loader->stack.push(defs); + loader->currentGraphicsNode = node; + } + } else if ((gradientMethod = _findGradientFactory(tagName))) { + SvgStyleGradient* gradient; + gradient = gradientMethod(loader, attrs, attrsLength); + //FIXME: The current parsing structure does not distinguish end tags. + // There is no way to know if the currently parsed gradient is in defs. + // If a gradient is declared outside of defs after defs is set, it is included in the gradients of defs. + // But finally, the loader has a gradient style list regardless of defs. + // This is only to support this when multiple gradients are declared, even if no defs are declared. + // refer to: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs + if (loader->def && loader->doc->node.doc.defs) { + loader->def->node.defs.gradients.push(gradient); + } else { + loader->gradients.push(gradient); + } + loader->latestGradient = gradient; + } else if (!strcmp(tagName, "stop")) { + if (!loader->latestGradient) { + TVGLOG("SVG", "Stop element is used outside of the Gradient element"); + return; + } + /* default value for opacity */ + loader->svgParse->gradStop = {0.0f, 0, 0, 0, 255}; + loader->svgParse->flags = SvgStopStyleFlags::StopDefault; + simpleXmlParseAttributes(attrs, attrsLength, _attrParseStops, loader); + loader->latestGradient->stops.push(loader->svgParse->gradStop); + } else if (!isIgnoreUnsupportedLogElements(tagName)) { + TVGLOG("SVG", "Unsupported elements used [Elements: %s]", tagName); + } +} + + +static void _svgLoaderParserXmlCssStyle(SvgLoaderData* loader, const char* content, unsigned int length) +{ + char* tag; + char* name; + const char* attrs = nullptr; + unsigned int attrsLength = 0; + + FactoryMethod method; + GradientFactoryMethod gradientMethod; + SvgNode *node = nullptr; + + while (auto next = simpleXmlParseCSSAttribute(content, length, &tag, &name, &attrs, &attrsLength)) { + if ((method = _findGroupFactory(tag))) { + if ((node = method(loader, loader->cssStyle, attrs, attrsLength, simpleXmlParseW3CAttribute))) node->id = _copyId(name); + } else if ((method = _findGraphicsFactory(tag))) { + if ((node = method(loader, loader->cssStyle, attrs, attrsLength, simpleXmlParseW3CAttribute))) node->id = _copyId(name); + } else if ((gradientMethod = _findGradientFactory(tag))) { + TVGLOG("SVG", "Unsupported elements used in the internal CSS style sheets [Elements: %s]", tag); + } else if (!strcmp(tag, "stop")) { + TVGLOG("SVG", "Unsupported elements used in the internal CSS style sheets [Elements: %s]", tag); + } else if (!strcmp(tag, "all")) { + if ((node = _createCssStyleNode(loader, loader->cssStyle, attrs, attrsLength, simpleXmlParseW3CAttribute))) node->id = _copyId(name); + } else if (!isIgnoreUnsupportedLogElements(tag)) { + TVGLOG("SVG", "Unsupported elements used in the internal CSS style sheets [Elements: %s]", tag); + } + + length -= next - content; + content = next; + + free(tag); + free(name); + } + loader->style = false; +} + + +static bool _svgLoaderParser(void* data, SimpleXMLType type, const char* content, unsigned int length) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + + switch (type) { + case SimpleXMLType::Open: { + _svgLoaderParserXmlOpen(loader, content, length, false); + break; + } + case SimpleXMLType::OpenEmpty: { + _svgLoaderParserXmlOpen(loader, content, length, true); + break; + } + case SimpleXMLType::Close: { + _svgLoaderParserXmlClose(loader, content); + break; + } + case SimpleXMLType::Data: + case SimpleXMLType::CData: { + if (loader->style) _svgLoaderParserXmlCssStyle(loader, content, length); + break; + } + case SimpleXMLType::DoctypeChild: { + break; + } + case SimpleXMLType::Ignored: + case SimpleXMLType::Comment: + case SimpleXMLType::Doctype: { + break; + } + default: { + break; + } + } + + return true; +} + + +static void _inefficientNodeCheck(TVG_UNUSED SvgNode* node) +{ +#ifdef THORVG_LOG_ENABLED + auto type = simpleXmlNodeTypeToString(node->type); + + if (!node->style->display && node->type != SvgNodeType::ClipPath) TVGLOG("SVG", "Inefficient elements used [Display is none][Node Type : %s]", type); + if (node->style->opacity == 0) TVGLOG("SVG", "Inefficient elements used [Opacity is zero][Node Type : %s]", type); + if (node->style->fill.opacity == 0 && node->style->stroke.opacity == 0) TVGLOG("SVG", "Inefficient elements used [Fill opacity and stroke opacity are zero][Node Type : %s]", type); + + switch (node->type) { + case SvgNodeType::Path: { + if (!node->node.path.path) TVGLOG("SVG", "Inefficient elements used [Empty path][Node Type : %s]", type); + break; + } + case SvgNodeType::Ellipse: { + if (node->node.ellipse.rx == 0 && node->node.ellipse.ry == 0) TVGLOG("SVG", "Inefficient elements used [Size is zero][Node Type : %s]", type); + break; + } + case SvgNodeType::Polygon: + case SvgNodeType::Polyline: { + if (node->node.polygon.pts.count < 2) TVGLOG("SVG", "Inefficient elements used [Invalid Polygon][Node Type : %s]", type); + break; + } + case SvgNodeType::Circle: { + if (node->node.circle.r == 0) TVGLOG("SVG", "Inefficient elements used [Size is zero][Node Type : %s]", type); + break; + } + case SvgNodeType::Rect: { + if (node->node.rect.w == 0 && node->node.rect.h) TVGLOG("SVG", "Inefficient elements used [Size is zero][Node Type : %s]", type); + break; + } + case SvgNodeType::Line: { + if (node->node.line.x1 == node->node.line.x2 && node->node.line.y1 == node->node.line.y2) TVGLOG("SVG", "Inefficient elements used [Size is zero][Node Type : %s]", type); + break; + } + default: break; + } +#endif +} + + +static void _updateStyle(SvgNode* node, SvgStyleProperty* parentStyle) +{ + _styleInherit(node->style, parentStyle); + _inefficientNodeCheck(node); + + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + _updateStyle(*child, node->style); + } +} + + +static SvgStyleGradient* _gradientDup(SvgLoaderData* loader, Array* gradients, const char* id) +{ + SvgStyleGradient* result = nullptr; + + auto gradList = gradients->data; + + for (uint32_t i = 0; i < gradients->count; ++i) { + if ((*gradList)->id && !strcmp((*gradList)->id, id)) { + result = _cloneGradient(*gradList); + break; + } + ++gradList; + } + + if (result && result->ref) { + gradList = gradients->data; + for (uint32_t i = 0; i < gradients->count; ++i) { + if ((*gradList)->id && !strcmp((*gradList)->id, result->ref)) { + _inheritGradient(loader, result, *gradList); + break; + } + ++gradList; + } + } + + return result; +} + + +static void _updateGradient(SvgLoaderData* loader, SvgNode* node, Array* gradients) +{ + if (node->child.count > 0) { + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + _updateGradient(loader, *child, gradients); + } + } else { + if (node->style->fill.paint.url) { + auto newGrad = _gradientDup(loader, gradients, node->style->fill.paint.url); + if (newGrad) { + if (node->style->fill.paint.gradient) { + node->style->fill.paint.gradient->clear(); + free(node->style->fill.paint.gradient); + } + node->style->fill.paint.gradient = newGrad; + } + } + if (node->style->stroke.paint.url) { + auto newGrad = _gradientDup(loader, gradients, node->style->stroke.paint.url); + if (newGrad) { + if (node->style->stroke.paint.gradient) { + node->style->stroke.paint.gradient->clear(); + free(node->style->stroke.paint.gradient); + } + node->style->stroke.paint.gradient = newGrad; + } + } + } +} + + +static void _updateComposite(SvgNode* node, SvgNode* root) +{ + if (node->style->clipPath.url && !node->style->clipPath.node) { + SvgNode* findResult = _findNodeById(root, node->style->clipPath.url); + if (findResult) node->style->clipPath.node = findResult; + } + if (node->style->mask.url && !node->style->mask.node) { + SvgNode* findResult = _findNodeById(root, node->style->mask.url); + if (findResult) node->style->mask.node = findResult; + } + if (node->child.count > 0) { + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + _updateComposite(*child, root); + } + } +} + + +static void _freeNodeStyle(SvgStyleProperty* style) +{ + if (!style) return; + + //style->clipPath.node and style->mask.node has only the addresses of node. Therefore, node is released from _freeNode. + free(style->clipPath.url); + free(style->mask.url); + free(style->cssClass); + + if (style->fill.paint.gradient) { + style->fill.paint.gradient->clear(); + free(style->fill.paint.gradient); + } + if (style->stroke.paint.gradient) { + style->stroke.paint.gradient->clear(); + free(style->stroke.paint.gradient); + } + free(style->fill.paint.url); + free(style->stroke.paint.url); + style->stroke.dash.array.reset(); + free(style); +} + + +static void _freeNode(SvgNode* node) +{ + if (!node) return; + + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + _freeNode(*child); + } + node->child.reset(); + + free(node->id); + free(node->transform); + _freeNodeStyle(node->style); + switch (node->type) { + case SvgNodeType::Path: { + free(node->node.path.path); + break; + } + case SvgNodeType::Polygon: { + free(node->node.polygon.pts.data); + break; + } + case SvgNodeType::Polyline: { + free(node->node.polyline.pts.data); + break; + } + case SvgNodeType::Doc: { + _freeNode(node->node.doc.defs); + _freeNode(node->node.doc.style); + break; + } + case SvgNodeType::Defs: { + auto gradients = node->node.defs.gradients.data; + for (size_t i = 0; i < node->node.defs.gradients.count; ++i) { + (*gradients)->clear(); + free(*gradients); + ++gradients; + } + node->node.defs.gradients.reset(); + break; + } + case SvgNodeType::Image: { + free(node->node.image.href); + break; + } + default: { + break; + } + } + free(node); +} + + +static bool _svgLoaderParserForValidCheckXmlOpen(SvgLoaderData* loader, const char* content, unsigned int length) +{ + const char* attrs = nullptr; + int sz = length; + char tagName[20] = ""; + FactoryMethod method; + SvgNode *node = nullptr; + int attrsLength = 0; + loader->level++; + attrs = simpleXmlFindAttributesTag(content, length); + + if (!attrs) { + //Parse the empty tag + attrs = content; + while ((attrs != nullptr) && *attrs != '>') attrs++; + } + + if (attrs) { + sz = attrs - content; + while ((sz > 0) && (isspace(content[sz - 1]))) sz--; + if ((unsigned)sz >= sizeof(tagName)) return false; + strncpy(tagName, content, sz); + tagName[sz] = '\0'; + attrsLength = length - sz; + } + + if ((method = _findGroupFactory(tagName))) { + if (!loader->doc) { + if (strcmp(tagName, "svg")) return true; //Not a valid svg document + node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes); + loader->doc = node; + loader->stack.push(node); + return false; + } + } + return true; +} + + +static bool _svgLoaderParserForValidCheck(void* data, SimpleXMLType type, const char* content, unsigned int length) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + bool res = true;; + + switch (type) { + case SimpleXMLType::Open: + case SimpleXMLType::OpenEmpty: { + //If 'res' is false, it means tag is found. + res = _svgLoaderParserForValidCheckXmlOpen(loader, content, length); + break; + } + default: { + break; + } + } + + return res; +} + + +void SvgLoader::clear(bool all) +{ + //flush out the intermediate data + free(loaderData.svgParse); + loaderData.svgParse = nullptr; + + for (auto gradient = loaderData.gradients.begin(); gradient < loaderData.gradients.end(); ++gradient) { + (*gradient)->clear(); + free(*gradient); + } + loaderData.gradients.reset(); + + _freeNode(loaderData.doc); + loaderData.doc = nullptr; + loaderData.stack.reset(); + + if (!all) return; + + for (auto p = loaderData.images.begin(); p < loaderData.images.end(); ++p) { + free(*p); + } + loaderData.images.reset(); + + if (copy) free((char*)content); + + delete(root); + root = nullptr; + + size = 0; + content = nullptr; + copy = false; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +SvgLoader::SvgLoader() : ImageLoader(FileType::Svg) +{ +} + + +SvgLoader::~SvgLoader() +{ + this->done(); + clear(); +} + + +void SvgLoader::run(unsigned tid) +{ + //According to the SVG standard the value of the width/height of the viewbox set to 0 disables rendering + if ((viewFlag & SvgViewFlag::Viewbox) && (fabsf(vw) <= FLOAT_EPSILON || fabsf(vh) <= FLOAT_EPSILON)) { + TVGLOG("SVG", "The width and/or height set to 0 - rendering disabled."); + root = Scene::gen().release(); + return; + } + + if (!simpleXmlParse(content, size, true, _svgLoaderParser, &(loaderData))) return; + + if (loaderData.doc) { + auto defs = loaderData.doc->node.doc.defs; + + if (loaderData.nodesToStyle.count > 0) cssApplyStyleToPostponeds(loaderData.nodesToStyle, loaderData.cssStyle); + if (loaderData.cssStyle) cssUpdateStyle(loaderData.doc, loaderData.cssStyle); + + if (loaderData.cloneNodes.count > 0) _clonePostponedNodes(&loaderData.cloneNodes, loaderData.doc); + + _updateComposite(loaderData.doc, loaderData.doc); + if (defs) _updateComposite(loaderData.doc, defs); + + _updateStyle(loaderData.doc, nullptr); + if (defs) _updateStyle(defs, nullptr); + + if (loaderData.gradients.count > 0) _updateGradient(&loaderData, loaderData.doc, &loaderData.gradients); + if (defs) _updateGradient(&loaderData, loaderData.doc, &defs->node.defs.gradients); + } + root = svgSceneBuild(loaderData, {vx, vy, vw, vh}, w, h, align, meetOrSlice, svgPath, viewFlag); + + //In case no viewbox and width/height data is provided the completion of loading + //has to be forced, in order to establish this data based on the whole picture. + if (!(viewFlag & SvgViewFlag::Viewbox)) { + //Override viewbox & size again after svg loading. + vx = loaderData.doc->node.doc.vx; + vy = loaderData.doc->node.doc.vy; + vw = loaderData.doc->node.doc.vw; + vh = loaderData.doc->node.doc.vh; + w = loaderData.doc->node.doc.w; + h = loaderData.doc->node.doc.h; + } + + clear(false); +} + + +bool SvgLoader::header() +{ + //For valid check, only tag is parsed first. + //If the tag is found, the loaded file is valid and stores viewbox information. + //After that, the remaining content data is parsed in order with async. + loaderData.svgParse = (SvgParser*)malloc(sizeof(SvgParser)); + if (!loaderData.svgParse) return false; + + loaderData.svgParse->flags = SvgStopStyleFlags::StopDefault; + viewFlag = SvgViewFlag::None; + + simpleXmlParse(content, size, true, _svgLoaderParserForValidCheck, &(loaderData)); + + if (loaderData.doc && loaderData.doc->type == SvgNodeType::Doc) { + viewFlag = loaderData.doc->node.doc.viewFlag; + align = loaderData.doc->node.doc.align; + meetOrSlice = loaderData.doc->node.doc.meetOrSlice; + + if (viewFlag & SvgViewFlag::Viewbox) { + vx = loaderData.doc->node.doc.vx; + vy = loaderData.doc->node.doc.vy; + vw = loaderData.doc->node.doc.vw; + vh = loaderData.doc->node.doc.vh; + + if (viewFlag & SvgViewFlag::Width) w = loaderData.doc->node.doc.w; + else { + w = loaderData.doc->node.doc.vw; + if (viewFlag & SvgViewFlag::WidthInPercent) { + w *= loaderData.doc->node.doc.w; + viewFlag = (viewFlag ^ SvgViewFlag::WidthInPercent); + } + viewFlag = (viewFlag | SvgViewFlag::Width); + } + if (viewFlag & SvgViewFlag::Height) h = loaderData.doc->node.doc.h; + else { + h = loaderData.doc->node.doc.vh; + if (viewFlag & SvgViewFlag::HeightInPercent) { + h *= loaderData.doc->node.doc.h; + viewFlag = (viewFlag ^ SvgViewFlag::HeightInPercent); + } + viewFlag = (viewFlag | SvgViewFlag::Height); + } + //In case no viewbox and width/height data is provided the completion of loading + //has to be forced, in order to establish this data based on the whole picture. + } else { + //Before loading, set default viewbox & size if they are empty + vx = vy = 0.0f; + if (viewFlag & SvgViewFlag::Width) { + vw = w = loaderData.doc->node.doc.w; + } else { + vw = 1.0f; + if (viewFlag & SvgViewFlag::WidthInPercent) { + w = loaderData.doc->node.doc.w; + } else w = 1.0f; + } + + if (viewFlag & SvgViewFlag::Height) { + vh = h = loaderData.doc->node.doc.h; + } else { + vh = 1.0f; + if (viewFlag & SvgViewFlag::HeightInPercent) { + h = loaderData.doc->node.doc.h; + } else h = 1.0f; + } + + run(0); + } + + return true; + } + + TVGLOG("SVG", "No SVG File. There is no "); + return false; +} + + +bool SvgLoader::open(const char* data, uint32_t size, bool copy) +{ + clear(); + + if (copy) { + content = (char*)malloc(size + 1); + if (!content) return false; + memcpy((char*)content, data, size); + content[size] = '\0'; + } else content = (char*)data; + + this->size = size; + this->copy = copy; + + return header(); +} + + +bool SvgLoader::open(const string& path) +{ + clear(); + + ifstream f; + f.open(path); + + if (!f.is_open()) return false; + + svgPath = path; + getline(f, filePath, '\0'); + f.close(); + + if (filePath.empty()) return false; + + content = (char*)filePath.c_str(); + size = filePath.size(); + + return header(); +} + + +bool SvgLoader::resize(Paint* paint, float w, float h) +{ + if (!paint) return false; + + auto sx = w / this->w; + auto sy = h / this->h; + Matrix m = {sx, 0, 0, 0, sy, 0, 0, 0, 1}; + paint->transform(m); + + return true; +} + + +bool SvgLoader::read() +{ + if (!content || size == 0) return false; + + //the loading has been already completed in header() + if (root || !LoadModule::read()) return true; + + TaskScheduler::request(this); + + return true; +} + + +bool SvgLoader::close() +{ + if (!LoadModule::close()) return false; + this->done(); + clear(); + return true; +} + + +Paint* SvgLoader::paint() +{ + this->done(); + auto ret = root; + root = nullptr; + return ret; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgLoader.h b/test/include/liblvgl/libs/thorvg/tvgSvgLoader.h new file mode 100644 index 00000000..d5cd7bb5 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgLoader.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SVG_LOADER_H_ +#define _TVG_SVG_LOADER_H_ + +#include "tvgTaskScheduler.h" +#include "tvgSvgLoaderCommon.h" + +class SvgLoader : public ImageLoader, public Task +{ +public: + string filePath; + string svgPath = ""; + char* content = nullptr; + uint32_t size = 0; + + SvgLoaderData loaderData; + Scene* root = nullptr; + + bool copy = false; + + SvgLoader(); + ~SvgLoader(); + + bool open(const string& path) override; + bool open(const char* data, uint32_t size, bool copy) override; + bool resize(Paint* paint, float w, float h) override; + bool read() override; + bool close() override; + + Paint* paint() override; + +private: + SvgViewFlag viewFlag = SvgViewFlag::None; + AspectRatioAlign align = AspectRatioAlign::XMidYMid; + AspectRatioMeetOrSlice meetOrSlice = AspectRatioMeetOrSlice::Meet; + float vx = 0; + float vy = 0; + float vw = 0; + float vh = 0; + + bool header(); + void clear(bool all = true); + void run(unsigned tid) override; +}; + + +#endif //_TVG_SVG_LOADER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgLoaderCommon.h b/test/include/liblvgl/libs/thorvg/tvgSvgLoaderCommon.h new file mode 100644 index 00000000..b0373908 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgLoaderCommon.h @@ -0,0 +1,577 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SVG_LOADER_COMMON_H_ +#define _TVG_SVG_LOADER_COMMON_H_ + +#include "tvgCommon.h" +#include "tvgArray.h" + +struct SvgNode; +struct SvgStyleGradient; + +//NOTE: Please update simpleXmlNodeTypeToString() as well. +enum class SvgNodeType +{ + Doc, + G, + Defs, + Animation, + Arc, + Circle, + Ellipse, + Image, + Line, + Path, + Polygon, + Polyline, + Rect, + Text, + TextArea, + Tspan, + Use, + Video, + ClipPath, + Mask, + CssStyle, + Symbol, + Unknown +}; + +/* +// TODO - remove? +enum class SvgLengthType +{ + Percent, + Px, + Pc, + Pt, + Mm, + Cm, + In, +}; +*/ + +enum class SvgFillFlags +{ + Paint = 0x01, + Opacity = 0x02, + Gradient = 0x04, + FillRule = 0x08, + ClipPath = 0x16 +}; + +constexpr bool operator &(SvgFillFlags a, SvgFillFlags b) +{ + return int(a) & int(b); +} + +constexpr SvgFillFlags operator |(SvgFillFlags a, SvgFillFlags b) +{ + return SvgFillFlags(int(a) | int(b)); +} + +enum class SvgStrokeFlags +{ + Paint = 0x1, + Opacity = 0x2, + Gradient = 0x4, + Scale = 0x8, + Width = 0x10, + Cap = 0x20, + Join = 0x40, + Dash = 0x80, + Miterlimit = 0x100, + DashOffset = 0x200 +}; + +constexpr bool operator &(SvgStrokeFlags a, SvgStrokeFlags b) +{ + return int(a) & int(b); +} + +constexpr SvgStrokeFlags operator |(SvgStrokeFlags a, SvgStrokeFlags b) +{ + return SvgStrokeFlags(int(a) | int(b)); +} + + +enum class SvgGradientType +{ + Linear, + Radial +}; + +enum class SvgStyleFlags +{ + Color = 0x01, + Fill = 0x02, + FillRule = 0x04, + FillOpacity = 0x08, + Opacity = 0x010, + Stroke = 0x20, + StrokeWidth = 0x40, + StrokeLineJoin = 0x80, + StrokeLineCap = 0x100, + StrokeOpacity = 0x200, + StrokeDashArray = 0x400, + Transform = 0x800, + ClipPath = 0x1000, + Mask = 0x2000, + MaskType = 0x4000, + Display = 0x8000, + PaintOrder = 0x10000, + StrokeMiterlimit = 0x20000, + StrokeDashOffset = 0x40000, +}; + +constexpr bool operator &(SvgStyleFlags a, SvgStyleFlags b) +{ + return int(a) & int(b); +} + +constexpr SvgStyleFlags operator |(SvgStyleFlags a, SvgStyleFlags b) +{ + return SvgStyleFlags(int(a) | int(b)); +} + +enum class SvgStopStyleFlags +{ + StopDefault = 0x0, + StopOpacity = 0x01, + StopColor = 0x02 +}; + +constexpr bool operator &(SvgStopStyleFlags a, SvgStopStyleFlags b) +{ + return int(a) & int(b); +} + +constexpr SvgStopStyleFlags operator |(SvgStopStyleFlags a, SvgStopStyleFlags b) +{ + return SvgStopStyleFlags(int(a) | int(b)); +} + +enum class SvgGradientFlags +{ + None = 0x0, + GradientUnits = 0x1, + SpreadMethod = 0x2, + X1 = 0x4, + X2 = 0x8, + Y1 = 0x10, + Y2 = 0x20, + Cx = 0x40, + Cy = 0x80, + R = 0x100, + Fx = 0x200, + Fy = 0x400, + Fr = 0x800 +}; + +constexpr bool operator &(SvgGradientFlags a, SvgGradientFlags b) +{ + return int(a) & int(b); +} + +constexpr SvgGradientFlags operator |(SvgGradientFlags a, SvgGradientFlags b) +{ + return SvgGradientFlags(int(a) | int(b)); +} + +enum class SvgFillRule +{ + Winding = 0, + OddEven = 1 +}; + +enum class SvgMaskType +{ + Luminance = 0, + Alpha +}; + +//Length type to recalculate %, pt, pc, mm, cm etc +enum class SvgParserLengthType +{ + Vertical, + Horizontal, + //In case of, for example, radius of radial gradient + Other +}; + +enum class SvgViewFlag +{ + None = 0x0, + Width = 0x01, //viewPort width + Height = 0x02, //viewPort height + Viewbox = 0x04, //viewBox x,y,w,h - used only if all 4 are correctly set + WidthInPercent = 0x08, + HeightInPercent = 0x10 +}; + +constexpr bool operator &(SvgViewFlag a, SvgViewFlag b) +{ + return static_cast(a) & static_cast(b); +} + +constexpr SvgViewFlag operator |(SvgViewFlag a, SvgViewFlag b) +{ + return SvgViewFlag(int(a) | int(b)); +} + +constexpr SvgViewFlag operator ^(SvgViewFlag a, SvgViewFlag b) +{ + return SvgViewFlag(int(a) ^ int(b)); +} + +enum class AspectRatioAlign +{ + None, + XMinYMin, + XMidYMin, + XMaxYMin, + XMinYMid, + XMidYMid, + XMaxYMid, + XMinYMax, + XMidYMax, + XMaxYMax +}; + +enum class AspectRatioMeetOrSlice +{ + Meet, + Slice +}; + +struct SvgDocNode +{ + float w; //unit: point or in percentage see: SvgViewFlag + float h; //unit: point or in percentage see: SvgViewFlag + float vx; + float vy; + float vw; + float vh; + SvgViewFlag viewFlag; + SvgNode* defs; + SvgNode* style; + AspectRatioAlign align; + AspectRatioMeetOrSlice meetOrSlice; +}; + +struct SvgGNode +{ +}; + +struct SvgDefsNode +{ + Array gradients; +}; + +struct SvgSymbolNode +{ + float w, h; + float vx, vy, vw, vh; + AspectRatioAlign align; + AspectRatioMeetOrSlice meetOrSlice; + bool overflowVisible; + bool hasViewBox; + bool hasWidth; + bool hasHeight; +}; + +struct SvgUseNode +{ + float x, y, w, h; + bool isWidthSet; + bool isHeightSet; + SvgNode* symbol; +}; + +struct SvgEllipseNode +{ + float cx; + float cy; + float rx; + float ry; +}; + +struct SvgCircleNode +{ + float cx; + float cy; + float r; +}; + +struct SvgRectNode +{ + float x; + float y; + float w; + float h; + float rx; + float ry; + bool hasRx; + bool hasRy; +}; + +struct SvgLineNode +{ + float x1; + float y1; + float x2; + float y2; +}; + +struct SvgImageNode +{ + float x, y, w, h; + char* href; +}; + +struct SvgPathNode +{ + char* path; +}; + +struct SvgPolygonNode +{ + Array pts; +}; + +struct SvgClipNode +{ + bool userSpace; +}; + +struct SvgMaskNode +{ + SvgMaskType type; + bool userSpace; +}; + +struct SvgCssStyleNode +{ +}; + +struct SvgLinearGradient +{ + float x1; + float y1; + float x2; + float y2; + bool isX1Percentage; + bool isY1Percentage; + bool isX2Percentage; + bool isY2Percentage; +}; + +struct SvgRadialGradient +{ + float cx; + float cy; + float fx; + float fy; + float r; + float fr; + bool isCxPercentage; + bool isCyPercentage; + bool isFxPercentage; + bool isFyPercentage; + bool isRPercentage; + bool isFrPercentage; +}; + +struct SvgComposite +{ + char *url; + SvgNode* node; + bool applying; //flag for checking circular dependency. +}; + +struct SvgColor +{ + uint8_t r; + uint8_t g; + uint8_t b; +}; + +struct SvgPaint +{ + SvgStyleGradient* gradient; + char *url; + SvgColor color; + bool none; + bool curColor; +}; + +struct SvgDash +{ + Array array; + float offset; +}; + +struct SvgStyleGradient +{ + SvgGradientType type; + char* id; + char* ref; + FillSpread spread; + SvgRadialGradient* radial; + SvgLinearGradient* linear; + Matrix* transform; + Array stops; + SvgGradientFlags flags; + bool userSpace; + + void clear() + { + stops.reset(); + free(transform); + free(radial); + free(linear); + free(ref); + free(id); + } +}; + +struct SvgStyleFill +{ + SvgFillFlags flags; + SvgPaint paint; + int opacity; + FillRule fillRule; +}; + +struct SvgStyleStroke +{ + SvgStrokeFlags flags; + SvgPaint paint; + int opacity; + float scale; + float width; + float centered; + StrokeCap cap; + StrokeJoin join; + float miterlimit; + SvgDash dash; +}; + +struct SvgStyleProperty +{ + SvgStyleFill fill; + SvgStyleStroke stroke; + SvgComposite clipPath; + SvgComposite mask; + int opacity; + SvgColor color; + char* cssClass; + SvgStyleFlags flags; + SvgStyleFlags flagsImportance; //indicates the importance of the flag - if set, higher priority is applied (https://drafts.csswg.org/css-cascade-4/#importance) + bool curColorSet; + bool paintOrder; //true if default (fill, stroke), false otherwise + bool display; +}; + +struct SvgNode +{ + SvgNodeType type; + SvgNode* parent; + Array child; + char *id; + SvgStyleProperty *style; + Matrix* transform; + union { + SvgGNode g; + SvgDocNode doc; + SvgDefsNode defs; + SvgUseNode use; + SvgCircleNode circle; + SvgEllipseNode ellipse; + SvgPolygonNode polygon; + SvgPolygonNode polyline; + SvgRectNode rect; + SvgPathNode path; + SvgLineNode line; + SvgImageNode image; + SvgMaskNode mask; + SvgClipNode clip; + SvgCssStyleNode cssStyle; + SvgSymbolNode symbol; + } node; + ~SvgNode(); +}; + +struct SvgParser +{ + SvgNode* node; + SvgStyleGradient* styleGrad; + Fill::ColorStop gradStop; + SvgStopStyleFlags flags; + struct + { + float x, y, w, h; + } global; + struct + { + bool parsedFx; + bool parsedFy; + } gradient; +}; + +struct SvgNodeIdPair +{ + SvgNode* node; + char *id; +}; + +struct SvgLoaderData +{ + Array stack; + SvgNode* doc = nullptr; + SvgNode* def = nullptr; + SvgNode* cssStyle = nullptr; + Array gradients; + SvgStyleGradient* latestGradient = nullptr; //For stops + SvgParser* svgParse = nullptr; + Array cloneNodes; + Array nodesToStyle; + Array images; //embedded images + int level = 0; + bool result = false; + bool style = false; + SvgNode* currentGraphicsNode = nullptr; +}; + +struct Box +{ + float x, y, w, h; +}; + +#endif + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgPath.cpp b/test/include/liblvgl/libs/thorvg/tvgSvgPath.cpp new file mode 100644 index 00000000..42312c37 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgPath.cpp @@ -0,0 +1,577 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +/* + * Copyright notice for the EFL: + + * Copyright (C) EFL developers (see AUTHORS) + + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++. + +#include +#include +#include "tvgMath.h" +#include "tvgShape.h" +#include "tvgSvgLoaderCommon.h" +#include "tvgSvgPath.h" +#include "tvgStr.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static char* _skipComma(const char* content) +{ + while (*content && isspace(*content)) { + content++; + } + if (*content == ',') return (char*)content + 1; + return (char*)content; +} + + +static bool _parseNumber(char** content, float* number) +{ + char* end = NULL; + *number = strToFloat(*content, &end); + //If the start of string is not number + if ((*content) == end) return false; + //Skip comma if any + *content = _skipComma(end); + return true; +} + + +static bool _parseFlag(char** content, int* number) +{ + char* end = NULL; + if (*(*content) != '0' && *(*content) != '1') return false; + *number = *(*content) - '0'; + *content += 1; + end = *content; + *content = _skipComma(end); + + return true; +} + + +void _pathAppendArcTo(Array* cmds, Array* pts, Point* cur, Point* curCtl, float x, float y, float rx, float ry, float angle, bool largeArc, bool sweep) +{ + float cxp, cyp, cx, cy; + float sx, sy; + float cosPhi, sinPhi; + float dx2, dy2; + float x1p, y1p; + float x1p2, y1p2; + float rx2, ry2; + float lambda; + float c; + float at; + float theta1, deltaTheta; + float nat; + float delta, bcp; + float cosPhiRx, cosPhiRy; + float sinPhiRx, sinPhiRy; + float cosTheta1, sinTheta1; + int segments; + + //Some helpful stuff is available here: + //http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes + sx = cur->x; + sy = cur->y; + + //Correction of out-of-range radii, see F6.6.1 (step 2) + rx = fabsf(rx); + ry = fabsf(ry); + + angle = mathDeg2Rad(angle); + cosPhi = cosf(angle); + sinPhi = sinf(angle); + dx2 = (sx - x) / 2.0f; + dy2 = (sy - y) / 2.0f; + x1p = cosPhi * dx2 + sinPhi * dy2; + y1p = cosPhi * dy2 - sinPhi * dx2; + x1p2 = x1p * x1p; + y1p2 = y1p * y1p; + rx2 = rx * rx; + ry2 = ry * ry; + lambda = (x1p2 / rx2) + (y1p2 / ry2); + + //Correction of out-of-range radii, see F6.6.2 (step 4) + if (lambda > 1.0f) { + //See F6.6.3 + float lambdaRoot = sqrtf(lambda); + + rx *= lambdaRoot; + ry *= lambdaRoot; + //Update rx2 and ry2 + rx2 = rx * rx; + ry2 = ry * ry; + } + + c = (rx2 * ry2) - (rx2 * y1p2) - (ry2 * x1p2); + + //Check if there is no possible solution + //(i.e. we can't do a square root of a negative value) + if (c < 0.0f) { + //Scale uniformly until we have a single solution + //(see F6.2) i.e. when c == 0.0 + float scale = sqrtf(1.0f - c / (rx2 * ry2)); + rx *= scale; + ry *= scale; + //Update rx2 and ry2 + rx2 = rx * rx; + ry2 = ry * ry; + + //Step 2 (F6.5.2) - simplified since c == 0.0 + cxp = 0.0f; + cyp = 0.0f; + //Step 3 (F6.5.3 first part) - simplified since cxp and cyp == 0.0 + cx = 0.0f; + cy = 0.0f; + } else { + //Complete c calculation + c = sqrtf(c / ((rx2 * y1p2) + (ry2 * x1p2))); + //Inverse sign if Fa == Fs + if (largeArc == sweep) c = -c; + + //Step 2 (F6.5.2) + cxp = c * (rx * y1p / ry); + cyp = c * (-ry * x1p / rx); + + //Step 3 (F6.5.3 first part) + cx = cosPhi * cxp - sinPhi * cyp; + cy = sinPhi * cxp + cosPhi * cyp; + } + + //Step 3 (F6.5.3 second part) we now have the center point of the ellipse + cx += (sx + x) / 2.0f; + cy += (sy + y) / 2.0f; + + //Step 4 (F6.5.4) + //We dont' use arccos (as per w3c doc), see + //http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm + //Note: atan2 (0.0, 1.0) == 0.0 + at = atan2(((y1p - cyp) / ry), ((x1p - cxp) / rx)); + theta1 = (at < 0.0f) ? 2.0f * MATH_PI + at : at; + + nat = atan2(((-y1p - cyp) / ry), ((-x1p - cxp) / rx)); + deltaTheta = (nat < at) ? 2.0f * MATH_PI - at + nat : nat - at; + + if (sweep) { + //Ensure delta theta < 0 or else add 360 degrees + if (deltaTheta < 0.0f) deltaTheta += 2.0f * MATH_PI; + } else { + //Ensure delta theta > 0 or else substract 360 degrees + if (deltaTheta > 0.0f) deltaTheta -= 2.0f * MATH_PI; + } + + //Add several cubic bezier to approximate the arc + //(smaller than 90 degrees) + //We add one extra segment because we want something + //Smaller than 90deg (i.e. not 90 itself) + segments = static_cast(fabsf(deltaTheta / MATH_PI2) + 1.0f); + delta = deltaTheta / segments; + + //http://www.stillhq.com/ctpfaq/2001/comp.text.pdf-faq-2001-04.txt (section 2.13) + bcp = 4.0f / 3.0f * (1.0f - cosf(delta / 2.0f)) / sinf(delta / 2.0f); + + cosPhiRx = cosPhi * rx; + cosPhiRy = cosPhi * ry; + sinPhiRx = sinPhi * rx; + sinPhiRy = sinPhi * ry; + + cosTheta1 = cosf(theta1); + sinTheta1 = sinf(theta1); + + for (int i = 0; i < segments; ++i) { + //End angle (for this segment) = current + delta + float c1x, c1y, ex, ey, c2x, c2y; + float theta2 = theta1 + delta; + float cosTheta2 = cosf(theta2); + float sinTheta2 = sinf(theta2); + Point p[3]; + + //First control point (based on start point sx,sy) + c1x = sx - bcp * (cosPhiRx * sinTheta1 + sinPhiRy * cosTheta1); + c1y = sy + bcp * (cosPhiRy * cosTheta1 - sinPhiRx * sinTheta1); + + //End point (for this segment) + ex = cx + (cosPhiRx * cosTheta2 - sinPhiRy * sinTheta2); + ey = cy + (sinPhiRx * cosTheta2 + cosPhiRy * sinTheta2); + + //Second control point (based on end point ex,ey) + c2x = ex + bcp * (cosPhiRx * sinTheta2 + sinPhiRy * cosTheta2); + c2y = ey + bcp * (sinPhiRx * sinTheta2 - cosPhiRy * cosTheta2); + cmds->push(PathCommand::CubicTo); + p[0] = {c1x, c1y}; + p[1] = {c2x, c2y}; + p[2] = {ex, ey}; + pts->push(p[0]); + pts->push(p[1]); + pts->push(p[2]); + *curCtl = p[1]; + *cur = p[2]; + + //Next start point is the current end point (same for angle) + sx = ex; + sy = ey; + theta1 = theta2; + //Avoid recomputations + cosTheta1 = cosTheta2; + sinTheta1 = sinTheta2; + } +} + +static int _numberCount(char cmd) +{ + int count = 0; + switch (cmd) { + case 'M': + case 'm': + case 'L': + case 'l': + case 'T': + case 't': { + count = 2; + break; + } + case 'C': + case 'c': + case 'E': + case 'e': { + count = 6; + break; + } + case 'H': + case 'h': + case 'V': + case 'v': { + count = 1; + break; + } + case 'S': + case 's': + case 'Q': + case 'q': { + count = 4; + break; + } + case 'A': + case 'a': { + count = 7; + break; + } + default: + break; + } + return count; +} + + +static bool _processCommand(Array* cmds, Array* pts, char cmd, float* arr, int count, Point* cur, Point* curCtl, Point* startPoint, bool *isQuadratic, bool* closed) +{ + switch (cmd) { + case 'm': + case 'l': + case 'c': + case 's': + case 'q': + case 't': { + for (int i = 0; i < count - 1; i += 2) { + arr[i] = arr[i] + cur->x; + arr[i + 1] = arr[i + 1] + cur->y; + } + break; + } + case 'h': { + arr[0] = arr[0] + cur->x; + break; + } + case 'v': { + arr[0] = arr[0] + cur->y; + break; + } + case 'a': { + arr[5] = arr[5] + cur->x; + arr[6] = arr[6] + cur->y; + break; + } + default: { + break; + } + } + + switch (cmd) { + case 'm': + case 'M': { + Point p = {arr[0], arr[1]}; + cmds->push(PathCommand::MoveTo); + pts->push(p); + *cur = {arr[0], arr[1]}; + *startPoint = {arr[0], arr[1]}; + break; + } + case 'l': + case 'L': { + Point p = {arr[0], arr[1]}; + cmds->push(PathCommand::LineTo); + pts->push(p); + *cur = {arr[0], arr[1]}; + break; + } + case 'c': + case 'C': { + Point p[3]; + cmds->push(PathCommand::CubicTo); + p[0] = {arr[0], arr[1]}; + p[1] = {arr[2], arr[3]}; + p[2] = {arr[4], arr[5]}; + pts->push(p[0]); + pts->push(p[1]); + pts->push(p[2]); + *curCtl = p[1]; + *cur = p[2]; + *isQuadratic = false; + break; + } + case 's': + case 'S': { + Point p[3], ctrl; + if ((cmds->count > 1) && (cmds->last() == PathCommand::CubicTo) && + !(*isQuadratic)) { + ctrl.x = 2 * cur->x - curCtl->x; + ctrl.y = 2 * cur->y - curCtl->y; + } else { + ctrl = *cur; + } + cmds->push(PathCommand::CubicTo); + p[0] = ctrl; + p[1] = {arr[0], arr[1]}; + p[2] = {arr[2], arr[3]}; + pts->push(p[0]); + pts->push(p[1]); + pts->push(p[2]); + *curCtl = p[1]; + *cur = p[2]; + *isQuadratic = false; + break; + } + case 'q': + case 'Q': { + Point p[3]; + float ctrl_x0 = (cur->x + 2 * arr[0]) * (1.0f / 3.0f); + float ctrl_y0 = (cur->y + 2 * arr[1]) * (1.0f / 3.0f); + float ctrl_x1 = (arr[2] + 2 * arr[0]) * (1.0f / 3.0f); + float ctrl_y1 = (arr[3] + 2 * arr[1]) * (1.0f / 3.0f); + cmds->push(PathCommand::CubicTo); + p[0] = {ctrl_x0, ctrl_y0}; + p[1] = {ctrl_x1, ctrl_y1}; + p[2] = {arr[2], arr[3]}; + pts->push(p[0]); + pts->push(p[1]); + pts->push(p[2]); + *curCtl = {arr[0], arr[1]}; + *cur = p[2]; + *isQuadratic = true; + break; + } + case 't': + case 'T': { + Point p[3], ctrl; + if ((cmds->count > 1) && (cmds->last() == PathCommand::CubicTo) && + *isQuadratic) { + ctrl.x = 2 * cur->x - curCtl->x; + ctrl.y = 2 * cur->y - curCtl->y; + } else { + ctrl = *cur; + } + float ctrl_x0 = (cur->x + 2 * ctrl.x) * (1.0f / 3.0f); + float ctrl_y0 = (cur->y + 2 * ctrl.y) * (1.0f / 3.0f); + float ctrl_x1 = (arr[0] + 2 * ctrl.x) * (1.0f / 3.0f); + float ctrl_y1 = (arr[1] + 2 * ctrl.y) * (1.0f / 3.0f); + cmds->push(PathCommand::CubicTo); + p[0] = {ctrl_x0, ctrl_y0}; + p[1] = {ctrl_x1, ctrl_y1}; + p[2] = {arr[0], arr[1]}; + pts->push(p[0]); + pts->push(p[1]); + pts->push(p[2]); + *curCtl = {ctrl.x, ctrl.y}; + *cur = p[2]; + *isQuadratic = true; + break; + } + case 'h': + case 'H': { + Point p = {arr[0], cur->y}; + cmds->push(PathCommand::LineTo); + pts->push(p); + cur->x = arr[0]; + break; + } + case 'v': + case 'V': { + Point p = {cur->x, arr[0]}; + cmds->push(PathCommand::LineTo); + pts->push(p); + cur->y = arr[0]; + break; + } + case 'z': + case 'Z': { + cmds->push(PathCommand::Close); + *cur = *startPoint; + *closed = true; + break; + } + case 'a': + case 'A': { + if (mathZero(arr[0]) || mathZero(arr[1])) { + Point p = {arr[5], arr[6]}; + cmds->push(PathCommand::LineTo); + pts->push(p); + *cur = {arr[5], arr[6]}; + } else if (!mathEqual(cur->x, arr[5]) || !mathEqual(cur->y, arr[6])) { + _pathAppendArcTo(cmds, pts, cur, curCtl, arr[5], arr[6], fabsf(arr[0]), fabsf(arr[1]), arr[2], arr[3], arr[4]); + *cur = *curCtl = {arr[5], arr[6]}; + *isQuadratic = false; + } + break; + } + default: { + return false; + } + } + return true; +} + + +static char* _nextCommand(char* path, char* cmd, float* arr, int* count, bool* closed) +{ + int large, sweep; + + path = _skipComma(path); + if (isalpha(*path)) { + *cmd = *path; + path++; + *count = _numberCount(*cmd); + } else { + if (*cmd == 'm') *cmd = 'l'; + else if (*cmd == 'M') *cmd = 'L'; + else { + if (*closed) return nullptr; + } + } + if (*count == 7) { + //Special case for arc command + if (_parseNumber(&path, &arr[0])) { + if (_parseNumber(&path, &arr[1])) { + if (_parseNumber(&path, &arr[2])) { + if (_parseFlag(&path, &large)) { + if (_parseFlag(&path, &sweep)) { + if (_parseNumber(&path, &arr[5])) { + if (_parseNumber(&path, &arr[6])) { + arr[3] = (float)large; + arr[4] = (float)sweep; + return path; + } + } + } + } + } + } + } + *count = 0; + return NULL; + } + for (int i = 0; i < *count; i++) { + if (!_parseNumber(&path, &arr[i])) { + *count = 0; + return NULL; + } + path = _skipComma(path); + } + return path; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +bool svgPathToShape(const char* svgPath, Shape* shape) +{ + float numberArray[7]; + int numberCount = 0; + Point cur = { 0, 0 }; + Point curCtl = { 0, 0 }; + Point startPoint = { 0, 0 }; + char cmd = 0; + bool isQuadratic = false; + bool closed = false; + char* path = (char*)svgPath; + + auto& pts = P(shape)->rs.path.pts; + auto& cmds = P(shape)->rs.path.cmds; + auto lastCmds = cmds.count; + + while ((path[0] != '\0')) { + path = _nextCommand(path, &cmd, numberArray, &numberCount, &closed); + if (!path) break; + closed = false; + if (!_processCommand(&cmds, &pts, cmd, numberArray, numberCount, &cur, &curCtl, &startPoint, &isQuadratic, &closed)) break; + } + + if (cmds.count > lastCmds && cmds[lastCmds] != PathCommand::MoveTo) return false; + return true; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgPath.h b/test/include/liblvgl/libs/thorvg/tvgSvgPath.h new file mode 100644 index 00000000..673fa0dd --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgPath.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SVG_PATH_H_ +#define _TVG_SVG_PATH_H_ + +#include "tvgCommon.h" + +bool svgPathToShape(const char* svgPath, Shape* shape); + +#endif //_TVG_SVG_PATH_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgSceneBuilder.cpp b/test/include/liblvgl/libs/thorvg/tvgSvgSceneBuilder.cpp new file mode 100644 index 00000000..585e487a --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgSceneBuilder.cpp @@ -0,0 +1,888 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" /* to include math.h before cstring */ +#include +#include +#include "tvgShape.h" +#include "tvgCompressor.h" +#include "tvgPaint.h" +#include "tvgFill.h" +#include "tvgStr.h" +#include "tvgSvgLoaderCommon.h" +#include "tvgSvgSceneBuilder.h" +#include "tvgSvgPath.h" +#include "tvgSvgUtil.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static bool _appendShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath); +static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform); +static unique_ptr _sceneBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite = nullptr); + + +static inline bool _isGroupType(SvgNodeType type) +{ + if (type == SvgNodeType::Doc || type == SvgNodeType::G || type == SvgNodeType::Use || type == SvgNodeType::ClipPath || type == SvgNodeType::Symbol) return true; + return false; +} + + +//According to: https://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBoxUnits (the last paragraph) +//a stroke width should be ignored for bounding box calculations +static Box _boundingBox(const Shape* shape) +{ + float x, y, w, h; + shape->bounds(&x, &y, &w, &h, false); + + if (auto strokeW = shape->strokeWidth()) { + x += 0.5f * strokeW; + y += 0.5f * strokeW; + w -= strokeW; + h -= strokeW; + } + + return {x, y, w, h}; +} + + +static void _transformMultiply(const Matrix* mBBox, Matrix* gradTransf) +{ + gradTransf->e13 = gradTransf->e13 * mBBox->e11 + mBBox->e13; + gradTransf->e12 *= mBBox->e11; + gradTransf->e11 *= mBBox->e11; + + gradTransf->e23 = gradTransf->e23 * mBBox->e22 + mBBox->e23; + gradTransf->e22 *= mBBox->e22; + gradTransf->e21 *= mBBox->e22; +} + + +static unique_ptr _applyLinearGradientProperty(SvgStyleGradient* g, const Shape* vg, const Box& vBox, int opacity) +{ + Fill::ColorStop* stops; + int stopCount = 0; + auto fillGrad = LinearGradient::gen(); + + bool isTransform = (g->transform ? true : false); + Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + if (isTransform) finalTransform = *g->transform; + + if (g->userSpace) { + g->linear->x1 = g->linear->x1 * vBox.w; + g->linear->y1 = g->linear->y1 * vBox.h; + g->linear->x2 = g->linear->x2 * vBox.w; + g->linear->y2 = g->linear->y2 * vBox.h; + } else { + Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1}; + if (isTransform) _transformMultiply(&m, &finalTransform); + else { + finalTransform = m; + isTransform = true; + } + } + + if (isTransform) fillGrad->transform(finalTransform); + + fillGrad->linear(g->linear->x1, g->linear->y1, g->linear->x2, g->linear->y2); + fillGrad->spread(g->spread); + + //Update the stops + stopCount = g->stops.count; + if (stopCount > 0) { + stops = (Fill::ColorStop*)calloc(stopCount, sizeof(Fill::ColorStop)); + if (!stops) return fillGrad; + auto prevOffset = 0.0f; + for (uint32_t i = 0; i < g->stops.count; ++i) { + auto colorStop = &g->stops[i]; + //Use premultiplied color + stops[i].r = colorStop->r; + stops[i].g = colorStop->g; + stops[i].b = colorStop->b; + stops[i].a = static_cast((colorStop->a * opacity) / 255); + stops[i].offset = colorStop->offset; + //check the offset corner cases - refer to: https://svgwg.org/svg2-draft/pservers.html#StopNotes + if (colorStop->offset < prevOffset) stops[i].offset = prevOffset; + else if (colorStop->offset > 1) stops[i].offset = 1; + prevOffset = stops[i].offset; + } + fillGrad->colorStops(stops, stopCount); + free(stops); + } + return fillGrad; +} + + +static unique_ptr _applyRadialGradientProperty(SvgStyleGradient* g, const Shape* vg, const Box& vBox, int opacity) +{ + Fill::ColorStop *stops; + int stopCount = 0; + auto fillGrad = RadialGradient::gen(); + + bool isTransform = (g->transform ? true : false); + Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + if (isTransform) finalTransform = *g->transform; + + if (g->userSpace) { + //The radius scaling is done according to the Units section: + //https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html + g->radial->cx = g->radial->cx * vBox.w; + g->radial->cy = g->radial->cy * vBox.h; + g->radial->r = g->radial->r * sqrtf(powf(vBox.w, 2.0f) + powf(vBox.h, 2.0f)) / sqrtf(2.0f); + g->radial->fx = g->radial->fx * vBox.w; + g->radial->fy = g->radial->fy * vBox.h; + g->radial->fr = g->radial->fr * sqrtf(powf(vBox.w, 2.0f) + powf(vBox.h, 2.0f)) / sqrtf(2.0f); + } else { + Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1}; + if (isTransform) _transformMultiply(&m, &finalTransform); + else { + finalTransform = m; + isTransform = true; + } + } + + if (isTransform) fillGrad->transform(finalTransform); + + P(fillGrad)->radial(g->radial->cx, g->radial->cy, g->radial->r, g->radial->fx, g->radial->fy, g->radial->fr); + fillGrad->spread(g->spread); + + //Update the stops + stopCount = g->stops.count; + if (stopCount > 0) { + stops = (Fill::ColorStop*)calloc(stopCount, sizeof(Fill::ColorStop)); + if (!stops) return fillGrad; + auto prevOffset = 0.0f; + for (uint32_t i = 0; i < g->stops.count; ++i) { + auto colorStop = &g->stops[i]; + //Use premultiplied color + stops[i].r = colorStop->r; + stops[i].g = colorStop->g; + stops[i].b = colorStop->b; + stops[i].a = static_cast((colorStop->a * opacity) / 255); + stops[i].offset = colorStop->offset; + //check the offset corner cases - refer to: https://svgwg.org/svg2-draft/pservers.html#StopNotes + if (colorStop->offset < prevOffset) stops[i].offset = prevOffset; + else if (colorStop->offset > 1) stops[i].offset = 1; + prevOffset = stops[i].offset; + } + fillGrad->colorStops(stops, stopCount); + free(stops); + } + return fillGrad; +} + + +//The SVG standard allows only for 'use' nodes that point directly to a basic shape. +static bool _appendClipUseNode(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath) +{ + if (node->child.count != 1) return false; + auto child = *(node->child.data); + + Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + if (node->transform) finalTransform = *node->transform; + if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) { + Matrix m = {1, 0, node->node.use.x, 0, 1, node->node.use.y, 0, 0, 1}; + finalTransform = mathMultiply(&finalTransform, &m); + } + if (child->transform) finalTransform = mathMultiply(child->transform, &finalTransform); + + return _appendClipShape(loaderData, child, shape, vBox, svgPath, mathIdentity((const Matrix*)(&finalTransform)) ? nullptr : &finalTransform); +} + + +static bool _appendClipChild(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, bool clip) +{ + if (node->type == SvgNodeType::Use) { + return _appendClipUseNode(loaderData, node, shape, vBox, svgPath); + } + return _appendClipShape(loaderData, node, shape, vBox, svgPath, nullptr); +} + + +static Matrix _compositionTransform(Paint* paint, const SvgNode* node, const SvgNode* compNode, SvgNodeType type) +{ + Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + //The initial mask transformation ignored according to the SVG standard. + if (node->transform && type != SvgNodeType::Mask) { + m = *node->transform; + } + if (compNode->transform) { + m = mathMultiply(&m, compNode->transform); + } + if (!compNode->node.clip.userSpace) { + float x, y, w, h; + P(paint)->bounds(&x, &y, &w, &h, false, false); + Matrix mBBox = {w, 0, x, 0, h, y, 0, 0, 1}; + m = mathMultiply(&m, &mBBox); + } + return m; +} + + +static void _applyComposition(SvgLoaderData& loaderData, Paint* paint, const SvgNode* node, const Box& vBox, const string& svgPath) +{ + /* ClipPath */ + /* Do not drop in Circular Dependency for ClipPath. + Composition can be applied recursively if its children nodes have composition target to this one. */ + if (node->style->clipPath.applying) { + TVGLOG("SVG", "Multiple Composition Tried! Check out Circular dependency?"); + } else { + auto compNode = node->style->clipPath.node; + if (compNode && compNode->child.count > 0) { + node->style->clipPath.applying = true; + + auto comp = Shape::gen(); + + auto child = compNode->child.data; + auto valid = false; //Composite only when valid shapes exist + + for (uint32_t i = 0; i < compNode->child.count; ++i, ++child) { + if (_appendClipChild(loaderData, *child, comp.get(), vBox, svgPath, compNode->child.count > 1)) valid = true; + } + + if (valid) { + Matrix finalTransform = _compositionTransform(paint, node, compNode, SvgNodeType::ClipPath); + comp->transform(finalTransform); + + paint->composite(std::move(comp), CompositeMethod::ClipPath); + } + + node->style->clipPath.applying = false; + } + } + + /* Mask */ + /* Do not drop in Circular Dependency for Mask. + Composition can be applied recursively if its children nodes have composition target to this one. */ + if (node->style->mask.applying) { + TVGLOG("SVG", "Multiple Composition Tried! Check out Circular dependency?"); + } else { + auto compNode = node->style->mask.node; + if (compNode && compNode->child.count > 0) { + node->style->mask.applying = true; + + bool isMaskWhite = true; + if (auto comp = _sceneBuildHelper(loaderData, compNode, vBox, svgPath, true, 0, &isMaskWhite)) { + if (!compNode->node.mask.userSpace) { + Matrix finalTransform = _compositionTransform(paint, node, compNode, SvgNodeType::Mask); + comp->transform(finalTransform); + } else { + if (node->transform) comp->transform(*node->transform); + } + + if (compNode->node.mask.type == SvgMaskType::Luminance && !isMaskWhite) { + paint->composite(std::move(comp), CompositeMethod::LumaMask); + } else { + paint->composite(std::move(comp), CompositeMethod::AlphaMask); + } + } + + node->style->mask.applying = false; + } + } +} + + +static void _applyProperty(SvgLoaderData& loaderData, SvgNode* node, Shape* vg, const Box& vBox, const string& svgPath, bool clip) +{ + SvgStyleProperty* style = node->style; + + //Clip transformation is applied directly to the path in the _appendClipShape function + if (node->transform && !clip) vg->transform(*node->transform); + if (node->type == SvgNodeType::Doc || !node->style->display) return; + + //If fill property is nullptr then do nothing + if (style->fill.paint.none) { + //Do nothing + } else if (style->fill.paint.gradient) { + Box bBox = vBox; + if (!style->fill.paint.gradient->userSpace) bBox = _boundingBox(vg); + + if (style->fill.paint.gradient->type == SvgGradientType::Linear) { + auto linear = _applyLinearGradientProperty(style->fill.paint.gradient, vg, bBox, style->fill.opacity); + vg->fill(std::move(linear)); + } else if (style->fill.paint.gradient->type == SvgGradientType::Radial) { + auto radial = _applyRadialGradientProperty(style->fill.paint.gradient, vg, bBox, style->fill.opacity); + vg->fill(std::move(radial)); + } + } else if (style->fill.paint.url) { + //TODO: Apply the color pointed by url + } else if (style->fill.paint.curColor) { + //Apply the current style color + vg->fill(style->color.r, style->color.g, style->color.b, style->fill.opacity); + } else { + //Apply the fill color + vg->fill(style->fill.paint.color.r, style->fill.paint.color.g, style->fill.paint.color.b, style->fill.opacity); + } + + //Apply the fill rule + vg->fill((tvg::FillRule)style->fill.fillRule); + //Rendering order + vg->order(!style->paintOrder); + + //Apply node opacity + if (style->opacity < 255) vg->opacity(style->opacity); + + if (node->type == SvgNodeType::G || node->type == SvgNodeType::Use) return; + + //Apply the stroke style property + vg->stroke(style->stroke.width); + vg->stroke(style->stroke.cap); + vg->stroke(style->stroke.join); + vg->strokeMiterlimit(style->stroke.miterlimit); + if (style->stroke.dash.array.count > 0) { + P(vg)->strokeDash(style->stroke.dash.array.data, style->stroke.dash.array.count, style->stroke.dash.offset); + } + + //If stroke property is nullptr then do nothing + if (style->stroke.paint.none) { + vg->stroke(0.0f); + } else if (style->stroke.paint.gradient) { + Box bBox = vBox; + if (!style->stroke.paint.gradient->userSpace) bBox = _boundingBox(vg); + + if (style->stroke.paint.gradient->type == SvgGradientType::Linear) { + auto linear = _applyLinearGradientProperty(style->stroke.paint.gradient, vg, bBox, style->stroke.opacity); + vg->stroke(std::move(linear)); + } else if (style->stroke.paint.gradient->type == SvgGradientType::Radial) { + auto radial = _applyRadialGradientProperty(style->stroke.paint.gradient, vg, bBox, style->stroke.opacity); + vg->stroke(std::move(radial)); + } + } else if (style->stroke.paint.url) { + //TODO: Apply the color pointed by url + } else if (style->stroke.paint.curColor) { + //Apply the current style color + vg->stroke(style->color.r, style->color.g, style->color.b, style->stroke.opacity); + } else { + //Apply the stroke color + vg->stroke(style->stroke.paint.color.r, style->stroke.paint.color.g, style->stroke.paint.color.b, style->stroke.opacity); + } + + _applyComposition(loaderData, vg, node, vBox, svgPath); +} + + +static unique_ptr _shapeBuildHelper(SvgLoaderData& loaderData, SvgNode* node, const Box& vBox, const string& svgPath) +{ + auto shape = Shape::gen(); + if (_appendShape(loaderData, node, shape.get(), vBox, svgPath)) return shape; + else return nullptr; +} + + +static bool _recognizeShape(SvgNode* node, Shape* shape) +{ + switch (node->type) { + case SvgNodeType::Path: { + if (node->node.path.path) { + if (!svgPathToShape(node->node.path.path, shape)) { + TVGERR("SVG", "Invalid path information."); + return false; + } + } + break; + } + case SvgNodeType::Ellipse: { + shape->appendCircle(node->node.ellipse.cx, node->node.ellipse.cy, node->node.ellipse.rx, node->node.ellipse.ry); + break; + } + case SvgNodeType::Polygon: { + if (node->node.polygon.pts.count < 2) break; + auto pts = node->node.polygon.pts.begin(); + shape->moveTo(pts[0], pts[1]); + for (pts += 2; pts < node->node.polygon.pts.end(); pts += 2) { + shape->lineTo(pts[0], pts[1]); + } + shape->close(); + break; + } + case SvgNodeType::Polyline: { + if (node->node.polyline.pts.count < 2) break; + auto pts = node->node.polyline.pts.begin(); + shape->moveTo(pts[0], pts[1]); + for (pts += 2; pts < node->node.polyline.pts.end(); pts += 2) { + shape->lineTo(pts[0], pts[1]); + } + break; + } + case SvgNodeType::Circle: { + shape->appendCircle(node->node.circle.cx, node->node.circle.cy, node->node.circle.r, node->node.circle.r); + break; + } + case SvgNodeType::Rect: { + shape->appendRect(node->node.rect.x, node->node.rect.y, node->node.rect.w, node->node.rect.h, node->node.rect.rx, node->node.rect.ry); + break; + } + case SvgNodeType::Line: { + shape->moveTo(node->node.line.x1, node->node.line.y1); + shape->lineTo(node->node.line.x2, node->node.line.y2); + break; + } + default: { + return false; + } + } + return true; +} + + +static bool _appendShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath) +{ + if (!_recognizeShape(node, shape)) return false; + + _applyProperty(loaderData, node, shape, vBox, svgPath, false); + return true; +} + + +static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform) +{ + //The 'transform' matrix has higher priority than the node->transform, since it already contains it + auto m = transform ? transform : (node->transform ? node->transform : nullptr); + + uint32_t currentPtsCnt = 0; + if (m) { + const Point *tmp = nullptr; + currentPtsCnt = shape->pathCoords(&tmp); + } + + if (!_recognizeShape(node, shape)) return false; + + if (m) { + const Point *pts = nullptr; + auto ptsCnt = shape->pathCoords(&pts); + + auto p = const_cast(pts) + currentPtsCnt; + while (currentPtsCnt++ < ptsCnt) mathMultiply(p++, m); + } + + _applyProperty(loaderData, node, shape, vBox, svgPath, true); + return true; +} + + +enum class imageMimeTypeEncoding +{ + base64 = 0x1, + utf8 = 0x2 +}; + +constexpr imageMimeTypeEncoding operator|(imageMimeTypeEncoding a, imageMimeTypeEncoding b) { + return static_cast(static_cast(a) | static_cast(b)); +} + +constexpr bool operator&(imageMimeTypeEncoding a, imageMimeTypeEncoding b) { + return (static_cast(a) & static_cast(b)); +} + + +static constexpr struct +{ + const char* name; + int sz; + imageMimeTypeEncoding encoding; +} imageMimeTypes[] = { + {"jpeg", sizeof("jpeg"), imageMimeTypeEncoding::base64}, + {"png", sizeof("png"), imageMimeTypeEncoding::base64}, + {"svg+xml", sizeof("svg+xml"), imageMimeTypeEncoding::base64 | imageMimeTypeEncoding::utf8}, +}; + + +static bool _isValidImageMimeTypeAndEncoding(const char** href, const char** mimetype, imageMimeTypeEncoding* encoding) { + if (strncmp(*href, "image/", sizeof("image/") - 1)) return false; //not allowed mime type + *href += sizeof("image/") - 1; + + //RFC2397 data:[][;base64], + //mediatype := [ type "/" subtype ] *( ";" parameter ) + //parameter := attribute "=" value + for (unsigned int i = 0; i < sizeof(imageMimeTypes) / sizeof(imageMimeTypes[0]); i++) { + if (!strncmp(*href, imageMimeTypes[i].name, imageMimeTypes[i].sz - 1)) { + *href += imageMimeTypes[i].sz - 1; + *mimetype = imageMimeTypes[i].name; + + while (**href && **href != ',') { + while (**href && **href != ';') ++(*href); + if (!**href) return false; + ++(*href); + + if (imageMimeTypes[i].encoding & imageMimeTypeEncoding::base64) { + if (!strncmp(*href, "base64,", sizeof("base64,") - 1)) { + *href += sizeof("base64,") - 1; + *encoding = imageMimeTypeEncoding::base64; + return true; //valid base64 + } + } + if (imageMimeTypes[i].encoding & imageMimeTypeEncoding::utf8) { + if (!strncmp(*href, "utf8,", sizeof("utf8,") - 1)) { + *href += sizeof("utf8,") - 1; + *encoding = imageMimeTypeEncoding::utf8; + return true; //valid utf8 + } + } + } + //no encoding defined + if (**href == ',' && (imageMimeTypes[i].encoding & imageMimeTypeEncoding::utf8)) { + ++(*href); + *encoding = imageMimeTypeEncoding::utf8; + return true; //allow no encoding defined if utf8 expected + } + return false; + } + } + return false; +} + +#include "tvgTaskScheduler.h" + +static unique_ptr _imageBuildHelper(SvgLoaderData& loaderData, SvgNode* node, const Box& vBox, const string& svgPath) +{ + if (!node->node.image.href || !strlen(node->node.image.href)) return nullptr; + auto picture = Picture::gen(); + + TaskScheduler::async(false); //force to load a picture on the same thread + + const char* href = node->node.image.href; + if (!strncmp(href, "data:", sizeof("data:") - 1)) { + href += sizeof("data:") - 1; + const char* mimetype; + imageMimeTypeEncoding encoding; + if (!_isValidImageMimeTypeAndEncoding(&href, &mimetype, &encoding)) return nullptr; //not allowed mime type or encoding + char *decoded = nullptr; + if (encoding == imageMimeTypeEncoding::base64) { + auto size = b64Decode(href, strlen(href), &decoded); + if (picture->load(decoded, size, mimetype, false) != Result::Success) { + free(decoded); + TaskScheduler::async(true); + return nullptr; + } + } else { + auto size = svgUtilURLDecode(href, &decoded); + if (picture->load(decoded, size, mimetype, false) != Result::Success) { + free(decoded); + TaskScheduler::async(true); + return nullptr; + } + } + loaderData.images.push(decoded); + } else { + if (!strncmp(href, "file://", sizeof("file://") - 1)) href += sizeof("file://") - 1; + //TODO: protect against recursive svg image loading + //Temporarily disable embedded svg: + const char *dot = strrchr(href, '.'); + if (dot && !strcmp(dot, ".svg")) { + TVGLOG("SVG", "Embedded svg file is disabled."); + TaskScheduler::async(true); + return nullptr; + } + string imagePath = href; + if (strncmp(href, "/", 1)) { + auto last = svgPath.find_last_of("/"); + imagePath = svgPath.substr(0, (last == string::npos ? 0 : last + 1)) + imagePath; + } + if (picture->load(imagePath) != Result::Success) { + TaskScheduler::async(true); + return nullptr; + } + } + + TaskScheduler::async(true); + + float w, h; + Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + if (picture->size(&w, &h) == Result::Success && w > 0 && h > 0) { + auto sx = node->node.image.w / w; + auto sy = node->node.image.h / h; + m = {sx, 0, node->node.image.x, 0, sy, node->node.image.y, 0, 0, 1}; + } + if (node->transform) m = mathMultiply(node->transform, &m); + picture->transform(m); + + _applyComposition(loaderData, picture.get(), node, vBox, svgPath); + + return picture; +} + + +static Matrix _calculateAspectRatioMatrix(AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, float width, float height, const Box& box) +{ + auto sx = width / box.w; + auto sy = height / box.h; + auto tvx = box.x * sx; + auto tvy = box.y * sy; + + if (align == AspectRatioAlign::None) + return {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1}; + + //Scale + if (meetOrSlice == AspectRatioMeetOrSlice::Meet) { + if (sx < sy) sy = sx; + else sx = sy; + } else { + if (sx < sy) sx = sy; + else sy = sx; + } + + //Align + tvx = box.x * sx; + tvy = box.y * sy; + auto tvw = box.w * sx; + auto tvh = box.h * sy; + + switch (align) { + case AspectRatioAlign::XMinYMin: { + break; + } + case AspectRatioAlign::XMidYMin: { + tvx -= (width - tvw) * 0.5f; + break; + } + case AspectRatioAlign::XMaxYMin: { + tvx -= width - tvw; + break; + } + case AspectRatioAlign::XMinYMid: { + tvy -= (height - tvh) * 0.5f; + break; + } + case AspectRatioAlign::XMidYMid: { + tvx -= (width - tvw) * 0.5f; + tvy -= (height - tvh) * 0.5f; + break; + } + case AspectRatioAlign::XMaxYMid: { + tvx -= width - tvw; + tvy -= (height - tvh) * 0.5f; + break; + } + case AspectRatioAlign::XMinYMax: { + tvy -= height - tvh; + break; + } + case AspectRatioAlign::XMidYMax: { + tvx -= (width - tvw) * 0.5f; + tvy -= height - tvh; + break; + } + case AspectRatioAlign::XMaxYMax: { + tvx -= width - tvw; + tvy -= height - tvh; + break; + } + default: { + break; + } + } + + return {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1}; +} + + +static unique_ptr _useBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, int depth, bool* isMaskWhite) +{ + unique_ptr finalScene; + auto scene = _sceneBuildHelper(loaderData, node, vBox, svgPath, false, depth + 1, isMaskWhite); + + // mUseTransform = mUseTransform * mTranslate + Matrix mUseTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + if (node->transform) mUseTransform = *node->transform; + if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) { + Matrix mTranslate = {1, 0, node->node.use.x, 0, 1, node->node.use.y, 0, 0, 1}; + mUseTransform = mathMultiply(&mUseTransform, &mTranslate); + } + + if (node->node.use.symbol) { + auto symbol = node->node.use.symbol->node.symbol; + + auto width = (symbol.hasWidth ? symbol.w : vBox.w); + if (node->node.use.isWidthSet) width = node->node.use.w; + auto height = (symbol.hasHeight ? symbol.h : vBox.h);; + if (node->node.use.isHeightSet) height = node->node.use.h; + auto vw = (symbol.hasViewBox ? symbol.vw : width); + auto vh = (symbol.hasViewBox ? symbol.vh : height); + + Matrix mViewBox = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + if ((!mathEqual(width, vw) || !mathEqual(height, vh)) && vw > 0 && vh > 0) { + Box box = {symbol.vx, symbol.vy, vw, vh}; + mViewBox = _calculateAspectRatioMatrix(symbol.align, symbol.meetOrSlice, width, height, box); + } else if (!mathZero(symbol.vx) || !mathZero(symbol.vy)) { + mViewBox = {1, 0, -symbol.vx, 0, 1, -symbol.vy, 0, 0, 1}; + } + + // mSceneTransform = mUseTransform * mSymbolTransform * mViewBox + Matrix mSceneTransform = mViewBox; + if (node->node.use.symbol->transform) { + mSceneTransform = mathMultiply(node->node.use.symbol->transform, &mViewBox); + } + mSceneTransform = mathMultiply(&mUseTransform, &mSceneTransform); + scene->transform(mSceneTransform); + + if (node->node.use.symbol->node.symbol.overflowVisible) { + finalScene = std::move(scene); + } else { + auto viewBoxClip = Shape::gen(); + viewBoxClip->appendRect(0, 0, width, height, 0, 0); + + // mClipTransform = mUseTransform * mSymbolTransform + Matrix mClipTransform = mUseTransform; + if (node->node.use.symbol->transform) { + mClipTransform = mathMultiply(&mUseTransform, node->node.use.symbol->transform); + } + viewBoxClip->transform(mClipTransform); + + auto compositeLayer = Scene::gen(); + compositeLayer->composite(std::move(viewBoxClip), CompositeMethod::ClipPath); + compositeLayer->push(std::move(scene)); + + auto root = Scene::gen(); + root->push(std::move(compositeLayer)); + + finalScene = std::move(root); + } + } else { + scene->transform(mUseTransform); + finalScene = std::move(scene); + } + + return finalScene; +} + + +static unique_ptr _sceneBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite) +{ + /* Exception handling: Prevent invalid SVG data input. + The size is the arbitrary value, we need an experimental size. */ + if (depth > 2192) { + TVGERR("SVG", "Infinite recursive call - stopped after %d calls! Svg file may be incorrectly formatted.", depth); + return nullptr; + } + + if (_isGroupType(node->type) || mask) { + auto scene = Scene::gen(); + // For a Symbol node, the viewBox transformation has to be applied first - see _useBuildHelper() + if (!mask && node->transform && node->type != SvgNodeType::Symbol) scene->transform(*node->transform); + + if (node->style->display && node->style->opacity != 0) { + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + if (_isGroupType((*child)->type)) { + if ((*child)->type == SvgNodeType::Use) + scene->push(_useBuildHelper(loaderData, *child, vBox, svgPath, depth + 1, isMaskWhite)); + else if (!((*child)->type == SvgNodeType::Symbol && node->type != SvgNodeType::Use)) + scene->push(_sceneBuildHelper(loaderData, *child, vBox, svgPath, false, depth + 1, isMaskWhite)); + } else if ((*child)->type == SvgNodeType::Image) { + auto image = _imageBuildHelper(loaderData, *child, vBox, svgPath); + if (image) { + scene->push(std::move(image)); + if (isMaskWhite) *isMaskWhite = false; + } + } else if ((*child)->type != SvgNodeType::Mask) { + auto shape = _shapeBuildHelper(loaderData, *child, vBox, svgPath); + if (shape) { + if (isMaskWhite) { + uint8_t r, g, b; + shape->fillColor(&r, &g, &b); + if (shape->fill() || r < 255 || g < 255 || b < 255 || shape->strokeFill() || + (shape->strokeColor(&r, &g, &b) == Result::Success && (r < 255 || g < 255 || b < 255))) { + *isMaskWhite = false; + } + } + scene->push(std::move(shape)); + } + } + } + _applyComposition(loaderData, scene.get(), node, vBox, svgPath); + scene->opacity(node->style->opacity); + } + return scene; + } + return nullptr; +} + + +static void _updateInvalidViewSize(const Scene* scene, Box& vBox, float& w, float& h, SvgViewFlag viewFlag) +{ + bool validWidth = (viewFlag & SvgViewFlag::Width); + bool validHeight = (viewFlag & SvgViewFlag::Height); + + float x, y; + scene->bounds(&x, &y, &vBox.w, &vBox.h, false); + if (!validWidth && !validHeight) { + vBox.x = x; + vBox.y = y; + } else { + if (validWidth) vBox.w = w; + if (validHeight) vBox.h = h; + } + + //the size would have 1x1 or percentage values. + if (!validWidth) w *= vBox.w; + if (!validHeight) h *= vBox.h; +} + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Scene* svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag) +{ + //TODO: aspect ratio is valid only if viewBox was set + + if (!loaderData.doc || (loaderData.doc->type != SvgNodeType::Doc)) return nullptr; + + auto docNode = _sceneBuildHelper(loaderData, loaderData.doc, vBox, svgPath, false, 0); + + if (!(viewFlag & SvgViewFlag::Viewbox)) _updateInvalidViewSize(docNode.get(), vBox, w, h, viewFlag); + + if (!mathEqual(w, vBox.w) || !mathEqual(h, vBox.h)) { + Matrix m = _calculateAspectRatioMatrix(align, meetOrSlice, w, h, vBox); + docNode->transform(m); + } else if (!mathZero(vBox.x) || !mathZero(vBox.y)) { + docNode->translate(-vBox.x, -vBox.y); + } + + auto viewBoxClip = Shape::gen(); + viewBoxClip->appendRect(0, 0, w, h); + + auto compositeLayer = Scene::gen(); + compositeLayer->composite(std::move(viewBoxClip), CompositeMethod::ClipPath); + compositeLayer->push(std::move(docNode)); + + auto root = Scene::gen(); + root->push(std::move(compositeLayer)); + + loaderData.doc->node.doc.vx = vBox.x; + loaderData.doc->node.doc.vy = vBox.y; + loaderData.doc->node.doc.vw = vBox.w; + loaderData.doc->node.doc.vh = vBox.h; + loaderData.doc->node.doc.w = w; + loaderData.doc->node.doc.h = h; + + return root.release(); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgSceneBuilder.h b/test/include/liblvgl/libs/thorvg/tvgSvgSceneBuilder.h new file mode 100644 index 00000000..8ab1b672 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgSceneBuilder.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SVG_SCENE_BUILDER_H_ +#define _TVG_SVG_SCENE_BUILDER_H_ + +#include "tvgCommon.h" + +Scene* svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag); + +#endif //_TVG_SVG_SCENE_BUILDER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgUtil.cpp b/test/include/liblvgl/libs/thorvg/tvgSvgUtil.cpp new file mode 100644 index 00000000..e77e2a0f --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgUtil.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include +#include "tvgSvgUtil.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static uint8_t _hexCharToDec(const char c) +{ + if (c >= 'a') return c - 'a' + 10; + else if (c >= 'A') return c - 'A' + 10; + else return c - '0'; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +size_t svgUtilURLDecode(const char *src, char** dst) +{ + if (!src) return 0; + + auto length = strlen(src); + if (length == 0) return 0; + + char* decoded = (char*)malloc(sizeof(char) * length + 1); + + char a, b; + int idx =0; + while (*src) { + if (*src == '%' && + ((a = src[1]) && (b = src[2])) && + (isxdigit(a) && isxdigit(b))) { + decoded[idx++] = (_hexCharToDec(a) << 4) + _hexCharToDec(b); + src+=3; + } else if (*src == '+') { + decoded[idx++] = ' '; + src++; + } else { + decoded[idx++] = *src++; + } + } + decoded[idx] = '\0'; + + *dst = decoded; + return idx + 1; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSvgUtil.h b/test/include/liblvgl/libs/thorvg/tvgSvgUtil.h new file mode 100644 index 00000000..cc4b54c0 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSvgUtil.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SVG_UTIL_H_ +#define _TVG_SVG_UTIL_H_ + +#include "tvgCommon.h" + +size_t svgUtilURLDecode(const char *src, char** dst); + +#endif //_TVG_SVG_UTIL_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwCanvas.cpp b/test/include/liblvgl/libs/thorvg/tvgSwCanvas.cpp new file mode 100644 index 00000000..27bd7e3f --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwCanvas.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgCanvas.h" +#include "tvgLoadModule.h" + +#ifdef THORVG_SW_RASTER_SUPPORT + #include "tvgSwRenderer.h" +#else + class SwRenderer : public RenderMethod + { + //Non Supported. Dummy Class */ + }; +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct SwCanvas::Impl +{ +}; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +#ifdef THORVG_SW_RASTER_SUPPORT +SwCanvas::SwCanvas() : Canvas(SwRenderer::gen()), pImpl(new Impl) +#else +SwCanvas::SwCanvas() : Canvas(nullptr), pImpl(new Impl) +#endif +{ +} + + +SwCanvas::~SwCanvas() +{ + delete(pImpl); +} + + +Result SwCanvas::mempool(MempoolPolicy policy) noexcept +{ +#ifdef THORVG_SW_RASTER_SUPPORT + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast(Canvas::pImpl->renderer); + if (!renderer) return Result::MemoryCorruption; + + //It can't change the policy during the running. + if (!Canvas::pImpl->paints.empty()) return Result::InsufficientCondition; + + if (policy == MempoolPolicy::Individual) renderer->mempool(false); + else renderer->mempool(true); + + return Result::Success; +#endif + return Result::NonSupport; +} + + +Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Colorspace cs) noexcept +{ +#ifdef THORVG_SW_RASTER_SUPPORT + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast(Canvas::pImpl->renderer); + if (!renderer) return Result::MemoryCorruption; + + if (!renderer->target(buffer, stride, w, h, static_cast(cs))) return Result::InvalidArguments; + Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; + renderer->viewport(Canvas::pImpl->vport); + + //Paints must be updated again with this new target. + Canvas::pImpl->needRefresh(); + + //FIXME: The value must be associated with an individual canvas instance. + ImageLoader::cs = static_cast(cs); + + return Result::Success; +#endif + return Result::NonSupport; +} + + +unique_ptr SwCanvas::gen() noexcept +{ +#ifdef THORVG_SW_RASTER_SUPPORT + if (SwRenderer::init() <= 0) return nullptr; + return unique_ptr(new SwCanvas); +#endif + return nullptr; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwCommon.h b/test/include/liblvgl/libs/thorvg/tvgSwCommon.h new file mode 100644 index 00000000..182cf8fa --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwCommon.h @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SW_COMMON_H_ +#define _TVG_SW_COMMON_H_ + +#include "tvgCommon.h" +#include "tvgRender.h" + +#include + +#if 0 +#include +static double timeStamp() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec + tv.tv_usec / 1000000.0); +} +#endif + +#define SW_CURVE_TYPE_POINT 0 +#define SW_CURVE_TYPE_CUBIC 1 +#define SW_ANGLE_PI (180L << 16) +#define SW_ANGLE_2PI (SW_ANGLE_PI << 1) +#define SW_ANGLE_PI2 (SW_ANGLE_PI >> 1) + +using SwCoord = signed long; +using SwFixed = signed long long; + + +static inline float TO_FLOAT(SwCoord val) +{ + return static_cast(val) / 64.0f; +} + +struct SwPoint +{ + SwCoord x, y; + + SwPoint& operator+=(const SwPoint& rhs) + { + x += rhs.x; + y += rhs.y; + return *this; + } + + SwPoint operator+(const SwPoint& rhs) const + { + return {x + rhs.x, y + rhs.y}; + } + + SwPoint operator-(const SwPoint& rhs) const + { + return {x - rhs.x, y - rhs.y}; + } + + bool operator==(const SwPoint& rhs) const + { + return (x == rhs.x && y == rhs.y); + } + + bool operator!=(const SwPoint& rhs) const + { + return (x != rhs.x || y != rhs.y); + } + + bool zero() const + { + if (x == 0 && y == 0) return true; + else return false; + } + + bool small() const + { + //2 is epsilon... + if (abs(x) < 2 && abs(y) < 2) return true; + else return false; + } + + Point toPoint() const + { + return {TO_FLOAT(x), TO_FLOAT(y)}; + } +}; + +struct SwSize +{ + SwCoord w, h; +}; + +struct SwOutline +{ + Array pts; //the outline's points + Array cntrs; //the contour end points + Array types; //curve type + Array closed; //opened or closed path? + FillRule fillRule; +}; + +struct SwSpan +{ + uint16_t x, y; + uint16_t len; + uint8_t coverage; +}; + +struct SwRleData +{ + SwSpan *spans; + uint32_t alloc; + uint32_t size; +}; + +struct SwBBox +{ + SwPoint min, max; + + void reset() + { + min.x = min.y = max.x = max.y = 0; + } +}; + +struct SwFill +{ + struct SwLinear { + float dx, dy; + float len; + float offset; + }; + + struct SwRadial { + float a11, a12, a13; + float a21, a22, a23; + float fx, fy, fr; + float dx, dy, dr; + float invA, a; + }; + + union { + SwLinear linear; + SwRadial radial; + }; + + uint32_t* ctable; + FillSpread spread; + + bool translucent; +}; + +struct SwStrokeBorder +{ + uint32_t ptsCnt; + uint32_t maxPts; + SwPoint* pts; + uint8_t* tags; + int32_t start; //index of current sub-path start point + bool movable; //true: for ends of lineto borders +}; + +struct SwStroke +{ + SwFixed angleIn; + SwFixed angleOut; + SwPoint center; + SwFixed lineLength; + SwFixed subPathAngle; + SwPoint ptStartSubPath; + SwFixed subPathLineLength; + SwFixed width; + SwFixed miterlimit; + + StrokeCap cap; + StrokeJoin join; + StrokeJoin joinSaved; + SwFill* fill = nullptr; + + SwStrokeBorder borders[2]; + + float sx, sy; + + bool firstPt; + bool closedSubPath; + bool handleWideStrokes; +}; + +struct SwDashStroke +{ + SwOutline* outline = nullptr; + float curLen = 0; + int32_t curIdx = 0; + Point ptStart = {0, 0}; + Point ptCur = {0, 0}; + float* pattern = nullptr; + uint32_t cnt = 0; + bool curOpGap = false; + bool move = true; +}; + +struct SwShape +{ + SwOutline* outline = nullptr; + SwStroke* stroke = nullptr; + SwFill* fill = nullptr; + SwRleData* rle = nullptr; + SwRleData* strokeRle = nullptr; + SwBBox bbox; //Keep it boundary without stroke region. Using for optimal filling. + + bool fastTrack = false; //Fast Track: axis-aligned rectangle without any clips? +}; + +struct SwImage +{ + SwOutline* outline = nullptr; + SwRleData* rle = nullptr; + union { + pixel_t* data; //system based data pointer + uint32_t* buf32; //for explicit 32bits channels + uint8_t* buf8; //for explicit 8bits grayscale + }; + uint32_t w, h, stride; + int32_t ox = 0; //offset x + int32_t oy = 0; //offset y + float scale; + uint8_t channelSize; + + bool direct = false; //draw image directly (with offset) + bool scaled = false; //draw scaled image +}; + +typedef uint8_t(*SwMask)(uint8_t s, uint8_t d, uint8_t a); //src, dst, alpha +typedef uint32_t(*SwBlender)(uint32_t s, uint32_t d, uint8_t a); //src, dst, alpha +typedef uint32_t(*SwJoin)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); //color channel join +typedef uint8_t(*SwAlpha)(uint8_t*); //blending alpha + +struct SwCompositor; + +struct SwSurface : Surface +{ + SwJoin join; + SwAlpha alphas[4]; //Alpha:2, InvAlpha:3, Luma:4, InvLuma:5 + SwBlender blender = nullptr; //blender (optional) + SwCompositor* compositor = nullptr; //compositor (optional) + BlendMethod blendMethod; //blending method (uint8_t) + + SwAlpha alpha(CompositeMethod method) + { + auto idx = (int)(method) - 2; //0: None, 1: ClipPath + return alphas[idx > 3 ? 0 : idx]; //CompositeMethod has only four Matting methods. + } + + SwSurface() + { + } + + SwSurface(const SwSurface* rhs) : Surface(rhs) + { + join = rhs->join; + memcpy(alphas, rhs->alphas, sizeof(alphas)); + blender = rhs->blender; + compositor = rhs->compositor; + blendMethod = rhs->blendMethod; + } +}; + +struct SwCompositor : Compositor +{ + SwSurface* recoverSfc; //Recover surface when composition is started + SwCompositor* recoverCmp; //Recover compositor when composition is done + SwImage image; + SwBBox bbox; + bool valid; +}; + +struct SwMpool +{ + SwOutline* outline; + SwOutline* strokeOutline; + SwOutline* dashOutline; + unsigned allocSize; +}; + +static inline SwCoord TO_SWCOORD(float val) +{ + return SwCoord(val * 64.0f); +} + +static inline uint32_t JOIN(uint8_t c0, uint8_t c1, uint8_t c2, uint8_t c3) +{ + return (c0 << 24 | c1 << 16 | c2 << 8 | c3); +} + +static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a) +{ + return (((((c >> 8) & 0x00ff00ff) * a + 0x00ff00ff) & 0xff00ff00) + + ((((c & 0x00ff00ff) * a + 0x00ff00ff) >> 8) & 0x00ff00ff)); +} + +static inline uint32_t INTERPOLATE(uint32_t s, uint32_t d, uint8_t a) +{ + return (((((((s >> 8) & 0xff00ff) - ((d >> 8) & 0xff00ff)) * a) + (d & 0xff00ff00)) & 0xff00ff00) + ((((((s & 0xff00ff) - (d & 0xff00ff)) * a) >> 8) + (d & 0xff00ff)) & 0xff00ff)); +} + +static inline uint8_t INTERPOLATE8(uint8_t s, uint8_t d, uint8_t a) +{ + return (((s) * (a) + 0xff) >> 8) + (((d) * ~(a) + 0xff) >> 8); +} + +static inline SwCoord HALF_STROKE(float width) +{ + return TO_SWCOORD(width * 0.5f); +} + +static inline uint8_t A(uint32_t c) +{ + return ((c) >> 24); +} + +static inline uint8_t IA(uint32_t c) +{ + return (~(c) >> 24); +} + +static inline uint8_t C1(uint32_t c) +{ + return ((c) >> 16); +} + +static inline uint8_t C2(uint32_t c) +{ + return ((c) >> 8); +} + +static inline uint8_t C3(uint32_t c) +{ + return (c); +} + +static inline uint32_t opBlendInterp(uint32_t s, uint32_t d, uint8_t a) +{ + return INTERPOLATE(s, d, a); +} + +static inline uint32_t opBlendNormal(uint32_t s, uint32_t d, uint8_t a) +{ + auto t = ALPHA_BLEND(s, a); + return t + ALPHA_BLEND(d, IA(t)); +} + +static inline uint32_t opBlendPreNormal(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + return s + ALPHA_BLEND(d, IA(s)); +} + +static inline uint32_t opBlendSrcOver(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNUSED uint8_t a) +{ + return s; +} + +//TODO: BlendMethod could remove the alpha parameter. +static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + //if (s > d) => s - d + //else => d - s + auto c1 = (C1(s) > C1(d)) ? (C1(s) - C1(d)) : (C1(d) - C1(s)); + auto c2 = (C2(s) > C2(d)) ? (C2(s) - C2(d)) : (C2(d) - C2(s)); + auto c3 = (C3(s) > C3(d)) ? (C3(s) - C3(d)) : (C3(d) - C3(s)); + return JOIN(255, c1, c2, c3); +} + +static inline uint32_t opBlendExclusion(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + //A + B - 2AB + auto c1 = std::min(255, C1(s) + C1(d) - std::min(255, (C1(s) * C1(d)) << 1)); + auto c2 = std::min(255, C2(s) + C2(d) - std::min(255, (C2(s) * C2(d)) << 1)); + auto c3 = std::min(255, C3(s) + C3(d) - std::min(255, (C3(s) * C3(d)) << 1)); + return JOIN(255, c1, c2, c3); +} + +static inline uint32_t opBlendAdd(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + // s + d + auto c1 = std::min(C1(s) + C1(d), 255); + auto c2 = std::min(C2(s) + C2(d), 255); + auto c3 = std::min(C3(s) + C3(d), 255); + return JOIN(255, c1, c2, c3); +} + +static inline uint32_t opBlendScreen(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + // s + d - s * d + auto c1 = C1(s) + C1(d) - MULTIPLY(C1(s), C1(d)); + auto c2 = C2(s) + C2(d) - MULTIPLY(C2(s), C2(d)); + auto c3 = C3(s) + C3(d) - MULTIPLY(C3(s), C3(d)); + return JOIN(255, c1, c2, c3); +} + + +static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + // s * d + auto c1 = MULTIPLY(C1(s), C1(d)); + auto c2 = MULTIPLY(C2(s), C2(d)); + auto c3 = MULTIPLY(C3(s), C3(d)); + return JOIN(255, c1, c2, c3); +} + + +static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + // if (2 * d < da) => 2 * s * d, + // else => 1 - 2 * (1 - s) * (1 - d) + auto c1 = (C1(d) < 128) ? std::min(255, 2 * MULTIPLY(C1(s), C1(d))) : (255 - std::min(255, 2 * MULTIPLY(255 - C1(s), 255 - C1(d)))); + auto c2 = (C2(d) < 128) ? std::min(255, 2 * MULTIPLY(C2(s), C2(d))) : (255 - std::min(255, 2 * MULTIPLY(255 - C2(s), 255 - C2(d)))); + auto c3 = (C3(d) < 128) ? std::min(255, 2 * MULTIPLY(C3(s), C3(d))) : (255 - std::min(255, 2 * MULTIPLY(255 - C3(s), 255 - C3(d)))); + return JOIN(255, c1, c2, c3); +} + +static inline uint32_t opBlendDarken(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + // min(s, d) + auto c1 = std::min(C1(s), C1(d)); + auto c2 = std::min(C2(s), C2(d)); + auto c3 = std::min(C3(s), C3(d)); + return JOIN(255, c1, c2, c3); +} + +static inline uint32_t opBlendLighten(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + // max(s, d) + auto c1 = std::max(C1(s), C1(d)); + auto c2 = std::max(C2(s), C2(d)); + auto c3 = std::max(C3(s), C3(d)); + return JOIN(255, c1, c2, c3); +} + +static inline uint32_t opBlendColorDodge(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + // d / (1 - s) + auto is = 0xffffffff - s; + auto c1 = (C1(is) > 0) ? (C1(d) / C1(is)) : C1(d); + auto c2 = (C2(is) > 0) ? (C2(d) / C2(is)) : C2(d); + auto c3 = (C3(is) > 0) ? (C3(d) / C3(is)) : C3(d); + return JOIN(255, c1, c2, c3); +} + +static inline uint32_t opBlendColorBurn(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + // 1 - (1 - d) / s + auto id = 0xffffffff - d; + auto c1 = 255 - ((C1(s) > 0) ? (C1(id) / C1(s)) : C1(id)); + auto c2 = 255 - ((C2(s) > 0) ? (C2(id) / C2(s)) : C2(id)); + auto c3 = 255 - ((C3(s) > 0) ? (C3(id) / C3(s)) : C3(id)); + return JOIN(255, c1, c2, c3); +} + +static inline uint32_t opBlendHardLight(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + auto c1 = (C1(s) < 128) ? std::min(255, 2 * MULTIPLY(C1(s), C1(d))) : (255 - std::min(255, 2 * MULTIPLY(255 - C1(s), 255 - C1(d)))); + auto c2 = (C2(s) < 128) ? std::min(255, 2 * MULTIPLY(C2(s), C2(d))) : (255 - std::min(255, 2 * MULTIPLY(255 - C2(s), 255 - C2(d)))); + auto c3 = (C3(s) < 128) ? std::min(255, 2 * MULTIPLY(C3(s), C3(d))) : (255 - std::min(255, 2 * MULTIPLY(255 - C3(s), 255 - C3(d)))); + return JOIN(255, c1, c2, c3); +} + +static inline uint32_t opBlendSoftLight(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +{ + //(255 - 2 * s) * (d * d) + (2 * s * b) + auto c1 = std::min(255, MULTIPLY(255 - std::min(255, 2 * C1(s)), MULTIPLY(C1(d), C1(d))) + 2 * MULTIPLY(C1(s), C1(d))); + auto c2 = std::min(255, MULTIPLY(255 - std::min(255, 2 * C2(s)), MULTIPLY(C2(d), C2(d))) + 2 * MULTIPLY(C2(s), C2(d))); + auto c3 = std::min(255, MULTIPLY(255 - std::min(255, 2 * C3(s)), MULTIPLY(C3(d), C3(d))) + 2 * MULTIPLY(C3(s), C3(d))); + return JOIN(255, c1, c2, c3); +} + + +int64_t mathMultiply(int64_t a, int64_t b); +int64_t mathDivide(int64_t a, int64_t b); +int64_t mathMulDiv(int64_t a, int64_t b, int64_t c); +void mathRotate(SwPoint& pt, SwFixed angle); +SwFixed mathTan(SwFixed angle); +SwFixed mathAtan(const SwPoint& pt); +SwFixed mathCos(SwFixed angle); +SwFixed mathSin(SwFixed angle); +void mathSplitCubic(SwPoint* base); +SwFixed mathDiff(SwFixed angle1, SwFixed angle2); +SwFixed mathLength(const SwPoint& pt); +bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut); +SwFixed mathMean(SwFixed angle1, SwFixed angle2); +SwPoint mathTransform(const Point* to, const Matrix* transform); +bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack); +bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee); + +void shapeReset(SwShape* shape); +bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite); +bool shapePrepared(const SwShape* shape); +bool shapeGenRle(SwShape* shape, const RenderShape* rshape, bool antiAlias); +void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid); +void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix* transform); +bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); +void shapeFree(SwShape* shape); +void shapeDelStroke(SwShape* shape); +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable); +bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable); +void shapeResetFill(SwShape* shape); +void shapeResetStrokeFill(SwShape* shape); +void shapeDelFill(SwShape* shape); +void shapeDelStrokeFill(SwShape* shape); + +void strokeReset(SwStroke* stroke, const RenderShape* shape, const Matrix* transform); +bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline); +SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid); +void strokeFree(SwStroke* stroke); + +bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); +bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias); +void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid); +void imageReset(SwImage* image); +void imageFree(SwImage* image); + +bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable); +void fillReset(SwFill* fill); +void fillFree(SwFill* fill); + +//OPTIMIZE_ME: Skip the function pointer access +void fillLinear(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, SwMask maskOp, uint8_t opacity); //composite masking ver. +void fillLinear(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwMask maskOp, uint8_t opacity); //direct masking ver. +void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a); //blending ver. +void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a); //blending + BlendingMethod(op2) ver. +void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //matting ver. + +void fillRadial(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, SwMask op, uint8_t a); //composite masking ver. +void fillRadial(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwMask op, uint8_t a) ; //direct masking ver. +void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a); //blending ver. +void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a); //blending + BlendingMethod(op2) ver. +void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //matting ver. + +SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias); +SwRleData* rleRender(const SwBBox* bbox); +void rleFree(SwRleData* rle); +void rleReset(SwRleData* rle); +void rleMerge(SwRleData* rle, SwRleData* clip1, SwRleData* clip2); +void rleClipPath(SwRleData* rle, const SwRleData* clip); +void rleClipRect(SwRleData* rle, const SwBBox* clip); + +SwMpool* mpoolInit(uint32_t threads); +bool mpoolTerm(SwMpool* mpool); +bool mpoolClear(SwMpool* mpool); +SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx); +void mpoolRetOutline(SwMpool* mpool, unsigned idx); +SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx); +void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx); +SwOutline* mpoolReqDashOutline(SwMpool* mpool, unsigned idx); +void mpoolRetDashOutline(SwMpool* mpool, unsigned idx); + +bool rasterCompositor(SwSurface* surface); +bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id); +bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint8_t opacity); +bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id); +bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h); +void rasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len); +void rasterGrayscale8(uint8_t *dst, uint8_t val, uint32_t offset, int32_t len); +void rasterUnpremultiply(Surface* surface); +void rasterPremultiply(Surface* surface); +bool rasterConvertCS(Surface* surface, ColorSpace to); + +#endif /* _TVG_SW_COMMON_H_ */ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwFill.cpp b/test/include/liblvgl/libs/thorvg/tvgSwFill.cpp new file mode 100644 index 00000000..f939fc8b --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwFill.cpp @@ -0,0 +1,790 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" +#include "tvgSwCommon.h" +#include "tvgFill.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +#define RADIAL_A_THRESHOLD 0.0005f +#define GRADIENT_STOP_SIZE 1024 +#define FIXPT_BITS 8 +#define FIXPT_SIZE (1<radial.a + * B = 2 * (dr * fr + rx * dx + ry * dy) + * C = fr^2 - rx^2 - ry^2 + * Derivatives are computed with respect to dx. + * This procedure aims to optimize and eliminate the need to calculate all values from the beginning + * for consecutive x values with a constant y. The Taylor series expansions are computed as long as + * its terms are non-zero. + */ +static void _calculateCoefficients(const SwFill* fill, uint32_t x, uint32_t y, float& b, float& deltaB, float& det, float& deltaDet, float& deltaDeltaDet) +{ + auto radial = &fill->radial; + + auto rx = (x + 0.5f) * radial->a11 + (y + 0.5f) * radial->a12 + radial->a13 - radial->fx; + auto ry = (x + 0.5f) * radial->a21 + (y + 0.5f) * radial->a22 + radial->a23 - radial->fy; + + b = (radial->dr * radial->fr + rx * radial->dx + ry * radial->dy) * radial->invA; + deltaB = (radial->a11 * radial->dx + radial->a21 * radial->dy) * radial->invA; + + auto rr = rx * rx + ry * ry; + auto deltaRr = 2.0f * (rx * radial->a11 + ry * radial->a21) * radial->invA; + auto deltaDeltaRr = 2.0f * (radial->a11 * radial->a11 + radial->a21 * radial->a21) * radial->invA; + + det = b * b + (rr - radial->fr * radial->fr) * radial->invA; + deltaDet = 2.0f * b * deltaB + deltaB * deltaB + deltaRr + deltaDeltaRr; + deltaDeltaDet = 2.0f * deltaB * deltaB + deltaDeltaRr; +} + + +static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface* surface, uint8_t opacity) +{ + if (!fill->ctable) { + fill->ctable = static_cast(malloc(GRADIENT_STOP_SIZE * sizeof(uint32_t))); + if (!fill->ctable) return false; + } + + const Fill::ColorStop* colors; + auto cnt = fdata->colorStops(&colors); + if (cnt == 0 || !colors) return false; + + auto pColors = colors; + + auto a = MULTIPLY(pColors->a, opacity); + if (a < 255) fill->translucent = true; + + auto r = pColors->r; + auto g = pColors->g; + auto b = pColors->b; + auto rgba = surface->join(r, g, b, a); + + auto inc = 1.0f / static_cast(GRADIENT_STOP_SIZE); + auto pos = 1.5f * inc; + uint32_t i = 0; + + fill->ctable[i++] = ALPHA_BLEND(rgba | 0xff000000, a); + + while (pos <= pColors->offset) { + fill->ctable[i] = fill->ctable[i - 1]; + ++i; + pos += inc; + } + + for (uint32_t j = 0; j < cnt - 1; ++j) { + auto curr = colors + j; + auto next = curr + 1; + auto delta = 1.0f / (next->offset - curr->offset); + auto a2 = MULTIPLY(next->a, opacity); + if (!fill->translucent && a2 < 255) fill->translucent = true; + + auto rgba2 = surface->join(next->r, next->g, next->b, a2); + + while (pos < next->offset && i < GRADIENT_STOP_SIZE) { + auto t = (pos - curr->offset) * delta; + auto dist = static_cast(255 * t); + auto dist2 = 255 - dist; + + auto color = INTERPOLATE(rgba, rgba2, dist2); + fill->ctable[i] = ALPHA_BLEND((color | 0xff000000), (color >> 24)); + + ++i; + pos += inc; + } + rgba = rgba2; + a = a2; + } + rgba = ALPHA_BLEND((rgba | 0xff000000), a); + + for (; i < GRADIENT_STOP_SIZE; ++i) + fill->ctable[i] = rgba; + + //Make sure the last color stop is represented at the end of the table + fill->ctable[GRADIENT_STOP_SIZE - 1] = rgba; + + return true; +} + + +bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* transform) +{ + float x1, x2, y1, y2; + if (linear->linear(&x1, &y1, &x2, &y2) != Result::Success) return false; + + fill->linear.dx = x2 - x1; + fill->linear.dy = y2 - y1; + fill->linear.len = fill->linear.dx * fill->linear.dx + fill->linear.dy * fill->linear.dy; + + if (fill->linear.len < FLOAT_EPSILON) return true; + + fill->linear.dx /= fill->linear.len; + fill->linear.dy /= fill->linear.len; + fill->linear.offset = -fill->linear.dx * x1 - fill->linear.dy * y1; + + auto gradTransform = linear->transform(); + bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform)); + + if (isTransformation) { + if (transform) gradTransform = mathMultiply(transform, &gradTransform); + } else if (transform) { + gradTransform = *transform; + isTransformation = true; + } + + if (isTransformation) { + Matrix invTransform; + if (!mathInverse(&gradTransform, &invTransform)) return false; + + fill->linear.offset += fill->linear.dx * invTransform.e13 + fill->linear.dy * invTransform.e23; + + auto dx = fill->linear.dx; + fill->linear.dx = dx * invTransform.e11 + fill->linear.dy * invTransform.e21; + fill->linear.dy = dx * invTransform.e12 + fill->linear.dy * invTransform.e22; + + fill->linear.len = fill->linear.dx * fill->linear.dx + fill->linear.dy * fill->linear.dy; + } + + return true; +} + + +bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* transform) +{ + auto cx = P(radial)->cx; + auto cy = P(radial)->cy; + auto r = P(radial)->r; + auto fx = P(radial)->fx; + auto fy = P(radial)->fy; + auto fr = P(radial)->fr; + + if (r < FLOAT_EPSILON) return true; + + fill->radial.dr = r - fr; + fill->radial.dx = cx - fx; + fill->radial.dy = cy - fy; + fill->radial.fr = fr; + fill->radial.fx = fx; + fill->radial.fy = fy; + fill->radial.a = fill->radial.dr * fill->radial.dr - fill->radial.dx * fill->radial.dx - fill->radial.dy * fill->radial.dy; + + //This condition fulfills the SVG 1.1 std: + //the focal point, if outside the end circle, is moved to be on the end circle + //See: the SVG 2 std requirements: https://www.w3.org/TR/SVG2/pservers.html#RadialGradientNotes + if (fill->radial.a < 0) { + auto dist = sqrtf(fill->radial.dx * fill->radial.dx + fill->radial.dy * fill->radial.dy); + fill->radial.fx = cx + r * (fx - cx) / dist; + fill->radial.fy = cy + r * (fy - cy) / dist; + fill->radial.dx = cx - fill->radial.fx; + fill->radial.dy = cy - fill->radial.fy; + // Prevent loss of precision on Apple Silicon when dr=dy and dx=0 due to FMA + // https://github.com/thorvg/thorvg/issues/2014 + auto dr2 = fill->radial.dr * fill->radial.dr; + auto dx2 = fill->radial.dx * fill->radial.dx; + auto dy2 = fill->radial.dy * fill->radial.dy; + + fill->radial.a = dr2 - dx2 - dy2; + } + + if (fill->radial.a > 0) fill->radial.invA = 1.0f / fill->radial.a; + + auto gradTransform = radial->transform(); + bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform)); + + if (transform) { + if (isTransformation) gradTransform = mathMultiply(transform, &gradTransform); + else { + gradTransform = *transform; + isTransformation = true; + } + } + + if (isTransformation) { + Matrix invTransform; + if (!mathInverse(&gradTransform, &invTransform)) return false; + fill->radial.a11 = invTransform.e11; + fill->radial.a12 = invTransform.e12; + fill->radial.a13 = invTransform.e13; + fill->radial.a21 = invTransform.e21; + fill->radial.a22 = invTransform.e22; + fill->radial.a23 = invTransform.e23; + } else { + fill->radial.a11 = fill->radial.a22 = 1.0f; + fill->radial.a12 = fill->radial.a13 = 0.0f; + fill->radial.a21 = fill->radial.a23 = 0.0f; + } + return true; +} + + +static inline uint32_t _clamp(const SwFill* fill, int32_t pos) +{ + switch (fill->spread) { + case FillSpread::Pad: { + if (pos >= GRADIENT_STOP_SIZE) pos = GRADIENT_STOP_SIZE - 1; + else if (pos < 0) pos = 0; + break; + } + case FillSpread::Repeat: { + pos = pos % GRADIENT_STOP_SIZE; + if (pos < 0) pos = GRADIENT_STOP_SIZE + pos; + break; + } + case FillSpread::Reflect: { + auto limit = GRADIENT_STOP_SIZE * 2; + pos = pos % limit; + if (pos < 0) pos = limit + pos; + if (pos >= GRADIENT_STOP_SIZE) pos = (limit - pos - 1); + break; + } + } + return pos; +} + + +static inline uint32_t _fixedPixel(const SwFill* fill, int32_t pos) +{ + int32_t i = (pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; + return fill->ctable[_clamp(fill, i)]; +} + + +static inline uint32_t _pixel(const SwFill* fill, float pos) +{ + auto i = static_cast(pos * (GRADIENT_STOP_SIZE - 1) + 0.5f); + return fill->ctable[_clamp(fill, i)]; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity) +{ + //edge case + if (fill->radial.a < RADIAL_A_THRESHOLD) { + auto radial = &fill->radial; + auto rx = (x + 0.5f) * radial->a11 + (y + 0.5f) * radial->a12 + radial->a13 - radial->fx; + auto ry = (x + 0.5f) * radial->a21 + (y + 0.5f) * radial->a22 + radial->a23 - radial->fy; + + if (opacity == 255) { + for (uint32_t i = 0 ; i < len ; ++i, ++dst, cmp += csize) { + auto x0 = 0.5f * (rx * rx + ry * ry - radial->fr * radial->fr) / (radial->dr * radial->fr + rx * radial->dx + ry * radial->dy); + *dst = opBlendNormal(_pixel(fill, x0), *dst, alpha(cmp)); + rx += radial->a11; + ry += radial->a21; + } + } else { + for (uint32_t i = 0 ; i < len ; ++i, ++dst, cmp += csize) { + auto x0 = 0.5f * (rx * rx + ry * ry - radial->fr * radial->fr) / (radial->dr * radial->fr + rx * radial->dx + ry * radial->dy); + *dst = opBlendNormal(_pixel(fill, x0), *dst, MULTIPLY(opacity, alpha(cmp))); + rx += radial->a11; + ry += radial->a21; + } + } + } else { + float b, deltaB, det, deltaDet, deltaDeltaDet; + _calculateCoefficients(fill, x, y, b, deltaB, det, deltaDet, deltaDeltaDet); + + if (opacity == 255) { + for (uint32_t i = 0 ; i < len ; ++i, ++dst, cmp += csize) { + *dst = opBlendNormal(_pixel(fill, sqrtf(det) - b), *dst, alpha(cmp)); + det += deltaDet; + deltaDet += deltaDeltaDet; + b += deltaB; + } + } else { + for (uint32_t i = 0 ; i < len ; ++i, ++dst, cmp += csize) { + *dst = opBlendNormal(_pixel(fill, sqrtf(det) - b), *dst, MULTIPLY(opacity, alpha(cmp))); + det += deltaDet; + deltaDet += deltaDeltaDet; + b += deltaB; + } + } + } +} + + +void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a) +{ + if (fill->radial.a < RADIAL_A_THRESHOLD) { + auto radial = &fill->radial; + auto rx = (x + 0.5f) * radial->a11 + (y + 0.5f) * radial->a12 + radial->a13 - radial->fx; + auto ry = (x + 0.5f) * radial->a21 + (y + 0.5f) * radial->a22 + radial->a23 - radial->fy; + for (uint32_t i = 0; i < len; ++i, ++dst) { + auto x0 = 0.5f * (rx * rx + ry * ry - radial->fr * radial->fr) / (radial->dr * radial->fr + rx * radial->dx + ry * radial->dy); + *dst = op(_pixel(fill, x0), *dst, a); + rx += radial->a11; + ry += radial->a21; + } + } else { + float b, deltaB, det, deltaDet, deltaDeltaDet; + _calculateCoefficients(fill, x, y, b, deltaB, det, deltaDet, deltaDeltaDet); + + for (uint32_t i = 0; i < len; ++i, ++dst) { + *dst = op(_pixel(fill, sqrtf(det) - b), *dst, a); + det += deltaDet; + deltaDet += deltaDeltaDet; + b += deltaB; + } + } +} + + +void fillRadial(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, SwMask maskOp, uint8_t a) +{ + if (fill->radial.a < RADIAL_A_THRESHOLD) { + auto radial = &fill->radial; + auto rx = (x + 0.5f) * radial->a11 + (y + 0.5f) * radial->a12 + radial->a13 - radial->fx; + auto ry = (x + 0.5f) * radial->a21 + (y + 0.5f) * radial->a22 + radial->a23 - radial->fy; + for (uint32_t i = 0 ; i < len ; ++i, ++dst) { + auto x0 = 0.5f * (rx * rx + ry * ry - radial->fr * radial->fr) / (radial->dr * radial->fr + rx * radial->dx + ry * radial->dy); + auto src = MULTIPLY(a, A(_pixel(fill, x0))); + *dst = maskOp(src, *dst, ~src); + rx += radial->a11; + ry += radial->a21; + } + } else { + float b, deltaB, det, deltaDet, deltaDeltaDet; + _calculateCoefficients(fill, x, y, b, deltaB, det, deltaDet, deltaDeltaDet); + + for (uint32_t i = 0 ; i < len ; ++i, ++dst) { + auto src = MULTIPLY(a, A(_pixel(fill, sqrtf(det) - b))); + *dst = maskOp(src, *dst, ~src); + det += deltaDet; + deltaDet += deltaDeltaDet; + b += deltaB; + } + } +} + + +void fillRadial(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwMask maskOp, uint8_t a) +{ + if (fill->radial.a < RADIAL_A_THRESHOLD) { + auto radial = &fill->radial; + auto rx = (x + 0.5f) * radial->a11 + (y + 0.5f) * radial->a12 + radial->a13 - radial->fx; + auto ry = (x + 0.5f) * radial->a21 + (y + 0.5f) * radial->a22 + radial->a23 - radial->fy; + for (uint32_t i = 0 ; i < len ; ++i, ++dst, ++cmp) { + auto x0 = 0.5f * (rx * rx + ry * ry - radial->fr * radial->fr) / (radial->dr * radial->fr + rx * radial->dx + ry * radial->dy); + auto src = MULTIPLY(A(A(_pixel(fill, x0))), a); + auto tmp = maskOp(src, *cmp, 0); + *dst = tmp + MULTIPLY(*dst, ~tmp); + rx += radial->a11; + ry += radial->a21; + } + } else { + float b, deltaB, det, deltaDet, deltaDeltaDet; + _calculateCoefficients(fill, x, y, b, deltaB, det, deltaDet, deltaDeltaDet); + + for (uint32_t i = 0 ; i < len ; ++i, ++dst, ++cmp) { + auto src = MULTIPLY(A(_pixel(fill, sqrtf(det))), a); + auto tmp = maskOp(src, *cmp, 0); + *dst = tmp + MULTIPLY(*dst, ~tmp); + deltaDet += deltaDeltaDet; + b += deltaB; + } + } +} + + +void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a) +{ + if (fill->radial.a < RADIAL_A_THRESHOLD) { + auto radial = &fill->radial; + auto rx = (x + 0.5f) * radial->a11 + (y + 0.5f) * radial->a12 + radial->a13 - radial->fx; + auto ry = (x + 0.5f) * radial->a21 + (y + 0.5f) * radial->a22 + radial->a23 - radial->fy; + + if (a == 255) { + for (uint32_t i = 0; i < len; ++i, ++dst) { + auto x0 = 0.5f * (rx * rx + ry * ry - radial->fr * radial->fr) / (radial->dr * radial->fr + rx * radial->dx + ry * radial->dy); + auto tmp = op(_pixel(fill, x0), *dst, 255); + *dst = op2(tmp, *dst, 255); + rx += radial->a11; + ry += radial->a21; + } + } else { + for (uint32_t i = 0; i < len; ++i, ++dst) { + auto x0 = 0.5f * (rx * rx + ry * ry - radial->fr * radial->fr) / (radial->dr * radial->fr + rx * radial->dx + ry * radial->dy); + auto tmp = op(_pixel(fill, x0), *dst, 255); + auto tmp2 = op2(tmp, *dst, 255); + *dst = INTERPOLATE(tmp2, *dst, a); + rx += radial->a11; + ry += radial->a21; + } + } + } else { + float b, deltaB, det, deltaDet, deltaDeltaDet; + _calculateCoefficients(fill, x, y, b, deltaB, det, deltaDet, deltaDeltaDet); + if (a == 255) { + for (uint32_t i = 0 ; i < len ; ++i, ++dst) { + auto tmp = op(_pixel(fill, sqrtf(det) - b), *dst, 255); + *dst = op2(tmp, *dst, 255); + det += deltaDet; + deltaDet += deltaDeltaDet; + b += deltaB; + } + } else { + for (uint32_t i = 0 ; i < len ; ++i, ++dst) { + auto tmp = op(_pixel(fill, sqrtf(det) - b), *dst, 255); + auto tmp2 = op2(tmp, *dst, 255); + *dst = INTERPOLATE(tmp2, *dst, a); + det += deltaDet; + deltaDet += deltaDeltaDet; + b += deltaB; + } + } + } +} + + +void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity) +{ + //Rotation + float rx = x + 0.5f; + float ry = y + 0.5f; + float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); + float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); + + if (opacity == 255) { + if (mathZero(inc)) { + auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); + for (uint32_t i = 0; i < len; ++i, ++dst, cmp += csize) { + *dst = opBlendNormal(color, *dst, alpha(cmp)); + } + return; + } + + auto vMax = static_cast(INT32_MAX >> (FIXPT_BITS + 1)); + auto vMin = -vMax; + auto v = t + (inc * len); + + //we can use fixed point math + if (v < vMax && v > vMin) { + auto t2 = static_cast(t * FIXPT_SIZE); + auto inc2 = static_cast(inc * FIXPT_SIZE); + for (uint32_t j = 0; j < len; ++j, ++dst, cmp += csize) { + *dst = opBlendNormal(_fixedPixel(fill, t2), *dst, alpha(cmp)); + t2 += inc2; + } + //we have to fallback to float math + } else { + uint32_t counter = 0; + while (counter++ < len) { + *dst = opBlendNormal(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, alpha(cmp)); + ++dst; + t += inc; + cmp += csize; + } + } + } else { + if (mathZero(inc)) { + auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); + for (uint32_t i = 0; i < len; ++i, ++dst, cmp += csize) { + *dst = opBlendNormal(color, *dst, MULTIPLY(alpha(cmp), opacity)); + } + return; + } + + auto vMax = static_cast(INT32_MAX >> (FIXPT_BITS + 1)); + auto vMin = -vMax; + auto v = t + (inc * len); + + //we can use fixed point math + if (v < vMax && v > vMin) { + auto t2 = static_cast(t * FIXPT_SIZE); + auto inc2 = static_cast(inc * FIXPT_SIZE); + for (uint32_t j = 0; j < len; ++j, ++dst, cmp += csize) { + *dst = opBlendNormal(_fixedPixel(fill, t2), *dst, MULTIPLY(alpha(cmp), opacity)); + t2 += inc2; + } + //we have to fallback to float math + } else { + uint32_t counter = 0; + while (counter++ < len) { + *dst = opBlendNormal(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, MULTIPLY(opacity, alpha(cmp))); + ++dst; + t += inc; + cmp += csize; + } + } + } +} + + +void fillLinear(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, SwMask maskOp, uint8_t a) +{ + //Rotation + float rx = x + 0.5f; + float ry = y + 0.5f; + float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); + float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); + + if (mathZero(inc)) { + auto src = MULTIPLY(a, A(_fixedPixel(fill, static_cast(t * FIXPT_SIZE)))); + for (uint32_t i = 0; i < len; ++i, ++dst) { + *dst = maskOp(src, *dst, ~src); + } + return; + } + + auto vMax = static_cast(INT32_MAX >> (FIXPT_BITS + 1)); + auto vMin = -vMax; + auto v = t + (inc * len); + + //we can use fixed point math + if (v < vMax && v > vMin) { + auto t2 = static_cast(t * FIXPT_SIZE); + auto inc2 = static_cast(inc * FIXPT_SIZE); + for (uint32_t j = 0; j < len; ++j, ++dst) { + auto src = MULTIPLY(_fixedPixel(fill, t2), a); + *dst = maskOp(src, *dst, ~src); + t2 += inc2; + } + //we have to fallback to float math + } else { + uint32_t counter = 0; + while (counter++ < len) { + auto src = MULTIPLY(_pixel(fill, t / GRADIENT_STOP_SIZE), a); + *dst = maskOp(src, *dst, ~src); + ++dst; + t += inc; + } + } +} + + +void fillLinear(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwMask maskOp, uint8_t a) +{ + //Rotation + float rx = x + 0.5f; + float ry = y + 0.5f; + float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); + float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); + + if (mathZero(inc)) { + auto src = A(_fixedPixel(fill, static_cast(t * FIXPT_SIZE))); + src = MULTIPLY(src, a); + for (uint32_t i = 0; i < len; ++i, ++dst, ++cmp) { + auto tmp = maskOp(src, *cmp, 0); + *dst = tmp + MULTIPLY(*dst, ~tmp); + } + return; + } + + auto vMax = static_cast(INT32_MAX >> (FIXPT_BITS + 1)); + auto vMin = -vMax; + auto v = t + (inc * len); + + //we can use fixed point math + if (v < vMax && v > vMin) { + auto t2 = static_cast(t * FIXPT_SIZE); + auto inc2 = static_cast(inc * FIXPT_SIZE); + for (uint32_t j = 0; j < len; ++j, ++dst, ++cmp) { + auto src = MULTIPLY(a, A(_fixedPixel(fill, t2))); + auto tmp = maskOp(src, *cmp, 0); + *dst = tmp + MULTIPLY(*dst, ~tmp); + t2 += inc2; + } + //we have to fallback to float math + } else { + uint32_t counter = 0; + while (counter++ < len) { + auto src = MULTIPLY(A(_pixel(fill, t / GRADIENT_STOP_SIZE)), a); + auto tmp = maskOp(src, *cmp, 0); + *dst = tmp + MULTIPLY(*dst, ~tmp); + ++dst; + ++cmp; + t += inc; + } + } +} + + +void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a) +{ + //Rotation + float rx = x + 0.5f; + float ry = y + 0.5f; + float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); + float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); + + if (mathZero(inc)) { + auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); + for (uint32_t i = 0; i < len; ++i, ++dst) { + *dst = op(color, *dst, a); + } + return; + } + + auto vMax = static_cast(INT32_MAX >> (FIXPT_BITS + 1)); + auto vMin = -vMax; + auto v = t + (inc * len); + + //we can use fixed point math + if (v < vMax && v > vMin) { + auto t2 = static_cast(t * FIXPT_SIZE); + auto inc2 = static_cast(inc * FIXPT_SIZE); + for (uint32_t j = 0; j < len; ++j, ++dst) { + *dst = op(_fixedPixel(fill, t2), *dst, a); + t2 += inc2; + } + //we have to fallback to float math + } else { + uint32_t counter = 0; + while (counter++ < len) { + *dst = op(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, a); + ++dst; + t += inc; + } + } +} + + +void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a) +{ + //Rotation + float rx = x + 0.5f; + float ry = y + 0.5f; + float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); + float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); + + if (mathZero(inc)) { + auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); + if (a == 255) { + for (uint32_t i = 0; i < len; ++i, ++dst) { + auto tmp = op(color, *dst, a); + *dst = op2(tmp, *dst, 255); + } + } else { + for (uint32_t i = 0; i < len; ++i, ++dst) { + auto tmp = op(color, *dst, a); + auto tmp2 = op2(tmp, *dst, 255); + *dst = INTERPOLATE(tmp2, *dst, a); + } + } + return; + } + + auto vMax = static_cast(INT32_MAX >> (FIXPT_BITS + 1)); + auto vMin = -vMax; + auto v = t + (inc * len); + + if (a == 255) { + //we can use fixed point math + if (v < vMax && v > vMin) { + auto t2 = static_cast(t * FIXPT_SIZE); + auto inc2 = static_cast(inc * FIXPT_SIZE); + for (uint32_t j = 0; j < len; ++j, ++dst) { + auto tmp = op(_fixedPixel(fill, t2), *dst, 255); + *dst = op2(tmp, *dst, 255); + t2 += inc2; + } + //we have to fallback to float math + } else { + uint32_t counter = 0; + while (counter++ < len) { + auto tmp = op(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, 255); + *dst = op2(tmp, *dst, 255); + ++dst; + t += inc; + } + } + } else { + //we can use fixed point math + if (v < vMax && v > vMin) { + auto t2 = static_cast(t * FIXPT_SIZE); + auto inc2 = static_cast(inc * FIXPT_SIZE); + for (uint32_t j = 0; j < len; ++j, ++dst) { + auto tmp = op(_fixedPixel(fill, t2), *dst, 255); + auto tmp2 = op2(tmp, *dst, 255); + *dst = INTERPOLATE(tmp2, *dst, a); + t2 += inc2; + } + //we have to fallback to float math + } else { + uint32_t counter = 0; + while (counter++ < len) { + auto tmp = op(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, 255); + auto tmp2 = op2(tmp, *dst, 255); + *dst = INTERPOLATE(tmp2, *dst, a); + ++dst; + t += inc; + } + } + } +} + + +bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable) +{ + if (!fill) return false; + + fill->spread = fdata->spread(); + + if (ctable) { + if (!_updateColorTable(fill, fdata, surface, opacity)) return false; + } + + if (fdata->identifier() == TVG_CLASS_ID_LINEAR) { + return _prepareLinear(fill, static_cast(fdata), transform); + } else if (fdata->identifier() == TVG_CLASS_ID_RADIAL) { + return _prepareRadial(fill, static_cast(fdata), transform); + } + + //LOG: What type of gradient?! + + return false; +} + + +void fillReset(SwFill* fill) +{ + if (fill->ctable) { + free(fill->ctable); + fill->ctable = nullptr; + } + fill->translucent = false; +} + + +void fillFree(SwFill* fill) +{ + if (!fill) return; + + if (fill->ctable) free(fill->ctable); + + free(fill); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwImage.cpp b/test/include/liblvgl/libs/thorvg/tvgSwImage.cpp new file mode 100644 index 00000000..22d1cf79 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwImage.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" +#include "tvgSwCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static inline bool _onlyShifted(const Matrix* m) +{ + if (mathEqual(m->e11, 1.0f) && mathEqual(m->e22, 1.0f) && mathZero(m->e12) && mathZero(m->e21)) return true; + return false; +} + + +static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix* transform, SwMpool* mpool, unsigned tid) +{ + image->outline = mpoolReqOutline(mpool, tid); + auto outline = image->outline; + + outline->pts.reserve(5); + outline->types.reserve(5); + outline->cntrs.reserve(1); + outline->closed.reserve(1); + + Point to[4]; + if (mesh->triangleCnt > 0) { + // TODO: Optimise me. We appear to calculate this exact min/max bounding area in multiple + // places. We should be able to re-use one we have already done? Also see: + // tvgPicture.h --> bounds + // tvgSwRasterTexmap.h --> _rasterTexmapPolygonMesh + // + // TODO: Should we calculate the exact path(s) of the triangle mesh instead? + // i.e. copy tvgSwShape.capp -> _genOutline? + // + // TODO: Cntrs? + auto triangles = mesh->triangles; + auto min = triangles[0].vertex[0].pt; + auto max = triangles[0].vertex[0].pt; + + for (uint32_t i = 0; i < mesh->triangleCnt; ++i) { + if (triangles[i].vertex[0].pt.x < min.x) min.x = triangles[i].vertex[0].pt.x; + else if (triangles[i].vertex[0].pt.x > max.x) max.x = triangles[i].vertex[0].pt.x; + if (triangles[i].vertex[0].pt.y < min.y) min.y = triangles[i].vertex[0].pt.y; + else if (triangles[i].vertex[0].pt.y > max.y) max.y = triangles[i].vertex[0].pt.y; + + if (triangles[i].vertex[1].pt.x < min.x) min.x = triangles[i].vertex[1].pt.x; + else if (triangles[i].vertex[1].pt.x > max.x) max.x = triangles[i].vertex[1].pt.x; + if (triangles[i].vertex[1].pt.y < min.y) min.y = triangles[i].vertex[1].pt.y; + else if (triangles[i].vertex[1].pt.y > max.y) max.y = triangles[i].vertex[1].pt.y; + + if (triangles[i].vertex[2].pt.x < min.x) min.x = triangles[i].vertex[2].pt.x; + else if (triangles[i].vertex[2].pt.x > max.x) max.x = triangles[i].vertex[2].pt.x; + if (triangles[i].vertex[2].pt.y < min.y) min.y = triangles[i].vertex[2].pt.y; + else if (triangles[i].vertex[2].pt.y > max.y) max.y = triangles[i].vertex[2].pt.y; + } + to[0] = {min.x, min.y}; + to[1] = {max.x, min.y}; + to[2] = {max.x, max.y}; + to[3] = {min.x, max.y}; + } else { + auto w = static_cast(image->w); + auto h = static_cast(image->h); + to[0] = {0, 0}; + to[1] = {w, 0}; + to[2] = {w, h}; + to[3] = {0, h}; + } + + for (int i = 0; i < 4; i++) { + outline->pts.push(mathTransform(&to[i], transform)); + outline->types.push(SW_CURVE_TYPE_POINT); + } + + outline->pts.push(outline->pts[0]); + outline->types.push(SW_CURVE_TYPE_POINT); + outline->cntrs.push(outline->pts.count - 1); + outline->closed.push(true); + + image->outline = outline; + + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) +{ + image->direct = _onlyShifted(transform); + + //Fast track: Non-transformed image but just shifted. + if (image->direct) { + image->ox = -static_cast(round(transform->e13)); + image->oy = -static_cast(round(transform->e23)); + //Figure out the scale factor by transform matrix + } else { + auto scaleX = sqrtf((transform->e11 * transform->e11) + (transform->e21 * transform->e21)); + auto scaleY = sqrtf((transform->e22 * transform->e22) + (transform->e12 * transform->e12)); + image->scale = (fabsf(scaleX - scaleY) > 0.01f) ? 1.0f : scaleX; + + if (mathZero(transform->e12) && mathZero(transform->e21)) image->scaled = true; + else image->scaled = false; + } + + if (!_genOutline(image, mesh, transform, mpool, tid)) return false; + return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, image->direct); +} + + +bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias) +{ + if ((image->rle = rleRender(image->rle, image->outline, renderRegion, antiAlias))) return true; + + return false; +} + + +void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid) +{ + mpoolRetOutline(mpool, tid); + image->outline = nullptr; +} + + +void imageReset(SwImage* image) +{ + rleReset(image->rle); +} + + +void imageFree(SwImage* image) +{ + rleFree(image->rle); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwMath.cpp b/test/include/liblvgl/libs/thorvg/tvgSwMath.cpp new file mode 100644 index 00000000..8b8d8a4b --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwMath.cpp @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" +#include "tvgSwCommon.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static float TO_RADIAN(SwFixed angle) +{ + return (float(angle) / 65536.0f) * (MATH_PI / 180.0f); +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +SwFixed mathMean(SwFixed angle1, SwFixed angle2) +{ + return angle1 + mathDiff(angle1, angle2) / 2; +} + + +bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut) +{ + auto d1 = base[2] - base[3]; + auto d2 = base[1] - base[2]; + auto d3 = base[0] - base[1]; + + if (d1.small()) { + if (d2.small()) { + if (d3.small()) { + angleIn = angleMid = angleOut = 0; + return true; + } else { + angleIn = angleMid = angleOut = mathAtan(d3); + } + } else { + if (d3.small()) { + angleIn = angleMid = angleOut = mathAtan(d2); + } else { + angleIn = angleMid = mathAtan(d2); + angleOut = mathAtan(d3); + } + } + } else { + if (d2.small()) { + if (d3.small()) { + angleIn = angleMid = angleOut = mathAtan(d1); + } else { + angleIn = mathAtan(d1); + angleOut = mathAtan(d3); + angleMid = mathMean(angleIn, angleOut); + } + } else { + if (d3.small()) { + angleIn = mathAtan(d1); + angleMid = angleOut = mathAtan(d2); + } else { + angleIn = mathAtan(d1); + angleMid = mathAtan(d2); + angleOut = mathAtan(d3); + } + } + } + + auto theta1 = abs(mathDiff(angleIn, angleMid)); + auto theta2 = abs(mathDiff(angleMid, angleOut)); + + if ((theta1 < (SW_ANGLE_PI / 8)) && (theta2 < (SW_ANGLE_PI / 8))) return true; + return false; +} + + +int64_t mathMultiply(int64_t a, int64_t b) +{ + int32_t s = 1; + + //move sign + if (a < 0) { + a = -a; + s = -s; + } + if (b < 0) { + b = -b; + s = -s; + } + int64_t c = (a * b + 0x8000L) >> 16; + return (s > 0) ? c : -c; +} + + +int64_t mathDivide(int64_t a, int64_t b) +{ + int32_t s = 1; + + //move sign + if (a < 0) { + a = -a; + s = -s; + } + if (b < 0) { + b = -b; + s = -s; + } + int64_t q = b > 0 ? ((a << 16) + (b >> 1)) / b : 0x7FFFFFFFL; + return (s < 0 ? -q : q); +} + + +int64_t mathMulDiv(int64_t a, int64_t b, int64_t c) +{ + int32_t s = 1; + + //move sign + if (a < 0) { + a = -a; + s = -s; + } + if (b < 0) { + b = -b; + s = -s; + } + if (c < 0) { + c = -c; + s = -s; + } + int64_t d = c > 0 ? (a * b + (c >> 1)) / c : 0x7FFFFFFFL; + + return (s > 0 ? d : -d); +} + + +void mathRotate(SwPoint& pt, SwFixed angle) +{ + if (angle == 0 || pt.zero()) return; + + Point v = pt.toPoint(); + + auto radian = TO_RADIAN(angle); + auto cosv = cosf(radian); + auto sinv = sinf(radian); + + pt.x = SwCoord(roundf((v.x * cosv - v.y * sinv) * 64.0f)); + pt.y = SwCoord(roundf((v.x * sinv + v.y * cosv) * 64.0f)); +} + + +SwFixed mathTan(SwFixed angle) +{ + if (angle == 0) return 0; + return SwFixed(tanf(TO_RADIAN(angle)) * 65536.0f); +} + + +SwFixed mathAtan(const SwPoint& pt) +{ + if (pt.zero()) return 0; + return SwFixed(atan2f(TO_FLOAT(pt.y), TO_FLOAT(pt.x)) * (180.0f / MATH_PI) * 65536.0f); +} + + +SwFixed mathSin(SwFixed angle) +{ + if (angle == 0) return 0; + return mathCos(SW_ANGLE_PI2 - angle); +} + + +SwFixed mathCos(SwFixed angle) +{ + return SwFixed(cosf(TO_RADIAN(angle)) * 65536.0f); +} + + +SwFixed mathLength(const SwPoint& pt) +{ + if (pt.zero()) return 0; + + //trivial case + if (pt.x == 0) return abs(pt.y); + if (pt.y == 0) return abs(pt.x); + + auto v = pt.toPoint(); + //return static_cast(sqrtf(v.x * v.x + v.y * v.y) * 65536.0f); + + /* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm. + With alpha = 1, beta = 3/8, giving results with the largest error less + than 7% compared to the exact value. */ + if (v.x < 0) v.x = -v.x; + if (v.y < 0) v.y = -v.y; + return static_cast((v.x > v.y) ? (v.x + v.y * 0.375f) : (v.y + v.x * 0.375f)); +} + + +void mathSplitCubic(SwPoint* base) +{ + SwCoord a, b, c, d; + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = (base[0].x + c) >> 1; + base[5].x = b = (base[3].x + d) >> 1; + c = (c + d) >> 1; + base[2].x = a = (a + c) >> 1; + base[4].x = b = (b + c) >> 1; + base[3].x = (a + b) >> 1; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = (base[0].y + c) >> 1; + base[5].y = b = (base[3].y + d) >> 1; + c = (c + d) >> 1; + base[2].y = a = (a + c) >> 1; + base[4].y = b = (b + c) >> 1; + base[3].y = (a + b) >> 1; +} + + +SwFixed mathDiff(SwFixed angle1, SwFixed angle2) +{ + auto delta = angle2 - angle1; + + delta %= SW_ANGLE_2PI; + if (delta < 0) delta += SW_ANGLE_2PI; + if (delta > SW_ANGLE_PI) delta -= SW_ANGLE_2PI; + + return delta; +} + + +SwPoint mathTransform(const Point* to, const Matrix* transform) +{ + if (!transform) return {TO_SWCOORD(to->x), TO_SWCOORD(to->y)}; + + auto tx = to->x * transform->e11 + to->y * transform->e12 + transform->e13; + auto ty = to->x * transform->e21 + to->y * transform->e22 + transform->e23; + + return {TO_SWCOORD(tx), TO_SWCOORD(ty)}; +} + + +bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee) +{ + clipee.max.x = (clipee.max.x < clipper.max.x) ? clipee.max.x : clipper.max.x; + clipee.max.y = (clipee.max.y < clipper.max.y) ? clipee.max.y : clipper.max.y; + clipee.min.x = (clipee.min.x > clipper.min.x) ? clipee.min.x : clipper.min.x; + clipee.min.y = (clipee.min.y > clipper.min.y) ? clipee.min.y : clipper.min.y; + + //Check valid region + if (clipee.max.x - clipee.min.x < 1 && clipee.max.y - clipee.min.y < 1) return false; + + //Check boundary + if (clipee.min.x >= clipper.max.x || clipee.min.y >= clipper.max.y || + clipee.max.x <= clipper.min.x || clipee.max.y <= clipper.min.y) return false; + + return true; +} + + +bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack) +{ + if (!outline) return false; + + if (outline->pts.empty() || outline->cntrs.empty()) { + renderRegion.reset(); + return false; + } + + auto pt = outline->pts.begin(); + + auto xMin = pt->x; + auto xMax = pt->x; + auto yMin = pt->y; + auto yMax = pt->y; + + for (++pt; pt < outline->pts.end(); ++pt) { + if (xMin > pt->x) xMin = pt->x; + if (xMax < pt->x) xMax = pt->x; + if (yMin > pt->y) yMin = pt->y; + if (yMax < pt->y) yMax = pt->y; + } + //Since no antialiasing is applied in the Fast Track case, + //the rasterization region has to be rearranged. + //https://github.com/Samsung/thorvg/issues/916 + if (fastTrack) { + renderRegion.min.x = static_cast(round(xMin / 64.0f)); + renderRegion.max.x = static_cast(round(xMax / 64.0f)); + renderRegion.min.y = static_cast(round(yMin / 64.0f)); + renderRegion.max.y = static_cast(round(yMax / 64.0f)); + } else { + renderRegion.min.x = xMin >> 6; + renderRegion.max.x = (xMax + 63) >> 6; + renderRegion.min.y = yMin >> 6; + renderRegion.max.y = (yMax + 63) >> 6; + } + return mathClipBBox(clipRegion, renderRegion); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwMemPool.cpp b/test/include/liblvgl/libs/thorvg/tvgSwMemPool.cpp new file mode 100644 index 00000000..4a9d7f52 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwMemPool.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgSwCommon.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx) +{ + return &mpool->outline[idx]; +} + + +void mpoolRetOutline(SwMpool* mpool, unsigned idx) +{ + mpool->outline[idx].pts.clear(); + mpool->outline[idx].cntrs.clear(); + mpool->outline[idx].types.clear(); + mpool->outline[idx].closed.clear(); +} + + +SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx) +{ + return &mpool->strokeOutline[idx]; +} + + +void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx) +{ + mpool->strokeOutline[idx].pts.clear(); + mpool->strokeOutline[idx].cntrs.clear(); + mpool->strokeOutline[idx].types.clear(); + mpool->strokeOutline[idx].closed.clear(); +} + + +SwOutline* mpoolReqDashOutline(SwMpool* mpool, unsigned idx) +{ + return &mpool->dashOutline[idx]; +} + + +void mpoolRetDashOutline(SwMpool* mpool, unsigned idx) +{ + mpool->dashOutline[idx].pts.clear(); + mpool->dashOutline[idx].cntrs.clear(); + mpool->dashOutline[idx].types.clear(); + mpool->dashOutline[idx].closed.clear(); +} + + +SwMpool* mpoolInit(uint32_t threads) +{ + auto allocSize = threads + 1; + + auto mpool = static_cast(calloc(sizeof(SwMpool), 1)); + mpool->outline = static_cast(calloc(1, sizeof(SwOutline) * allocSize)); + mpool->strokeOutline = static_cast(calloc(1, sizeof(SwOutline) * allocSize)); + mpool->dashOutline = static_cast(calloc(1, sizeof(SwOutline) * allocSize)); + mpool->allocSize = allocSize; + + return mpool; +} + + +bool mpoolClear(SwMpool* mpool) +{ + for (unsigned i = 0; i < mpool->allocSize; ++i) { + mpool->outline[i].pts.reset(); + mpool->outline[i].cntrs.reset(); + mpool->outline[i].types.reset(); + mpool->outline[i].closed.reset(); + + mpool->strokeOutline[i].pts.reset(); + mpool->strokeOutline[i].cntrs.reset(); + mpool->strokeOutline[i].types.reset(); + mpool->strokeOutline[i].closed.reset(); + + mpool->dashOutline[i].pts.reset(); + mpool->dashOutline[i].cntrs.reset(); + mpool->dashOutline[i].types.reset(); + mpool->dashOutline[i].closed.reset(); + } + + return true; +} + + +bool mpoolTerm(SwMpool* mpool) +{ + if (!mpool) return false; + + mpoolClear(mpool); + + free(mpool->outline); + free(mpool->strokeOutline); + free(mpool->dashOutline); + free(mpool); + + return true; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwRaster.cpp b/test/include/liblvgl/libs/thorvg/tvgSwRaster.cpp new file mode 100644 index 00000000..237e30de --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwRaster.cpp @@ -0,0 +1,1967 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifdef _WIN32 + #include +#elif defined(__linux__) + #include +#else + #include +#endif + +#include "tvgMath.h" +#include "tvgRender.h" +#include "tvgSwCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ +constexpr auto DOWN_SCALE_TOLERANCE = 0.5f; + +struct FillLinear +{ + void operator()(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, SwMask op, uint8_t a) + { + fillLinear(fill, dst, y, x, len, op, a); + } + + void operator()(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwMask op, uint8_t a) + { + fillLinear(fill, dst, y, x, len, cmp, op, a); + } + + void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a) + { + fillLinear(fill, dst, y, x, len, op, a); + } + + void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity) + { + fillLinear(fill, dst, y, x, len, cmp, alpha, csize, opacity); + } + + void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a) + { + fillLinear(fill, dst, y, x, len, op, op2, a); + } + +}; + +struct FillRadial +{ + void operator()(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, SwMask op, uint8_t a) + { + fillRadial(fill, dst, y, x, len, op, a); + } + + void operator()(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwMask op, uint8_t a) + { + fillRadial(fill, dst, y, x, len, cmp, op, a); + } + + void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a) + { + fillRadial(fill, dst, y, x, len, op, a); + } + + void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity) + { + fillRadial(fill, dst, y, x, len, cmp, alpha, csize, opacity); + } + + void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a) + { + fillRadial(fill, dst, y, x, len, op, op2, a); + } +}; + + +static inline uint8_t _alpha(uint8_t* a) +{ + return *a; +} + + +static inline uint8_t _ialpha(uint8_t* a) +{ + return ~(*a); +} + + +static inline uint8_t _abgrLuma(uint8_t* c) +{ + auto v = *(uint32_t*)c; + return ((((v&0xff)*54) + (((v>>8)&0xff)*183) + (((v>>16)&0xff)*19))) >> 8; //0.2125*R + 0.7154*G + 0.0721*B +} + + +static inline uint8_t _argbLuma(uint8_t* c) +{ + auto v = *(uint32_t*)c; + return ((((v&0xff)*19) + (((v>>8)&0xff)*183) + (((v>>16)&0xff)*54))) >> 8; //0.0721*B + 0.7154*G + 0.2125*R +} + + +static inline uint8_t _abgrInvLuma(uint8_t* c) +{ + return ~_abgrLuma(c); +} + + +static inline uint8_t _argbInvLuma(uint8_t* c) +{ + return ~_argbLuma(c); +} + + +static inline uint32_t _abgrJoin(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + return (a << 24 | b << 16 | g << 8 | r); +} + + +static inline uint32_t _argbJoin(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + return (a << 24 | r << 16 | g << 8 | b); +} + +static inline bool _blending(const SwSurface* surface) +{ + return (surface->blender) ? true : false; +} + + +/* OPTIMIZE_ME: Probably, we can separate masking(8bits) / composition(32bits) + This would help to enhance the performance by avoiding the unnecessary matting from the composition */ +static inline bool _compositing(const SwSurface* surface) +{ + if (!surface->compositor || (int)surface->compositor->method <= (int)CompositeMethod::ClipPath) return false; + return true; +} + + +static inline bool _matting(const SwSurface* surface) +{ + if ((int)surface->compositor->method < (int)CompositeMethod::AddMask) return true; + else return false; +} + +static inline uint8_t _opMaskNone(uint8_t s, TVG_UNUSED uint8_t d, TVG_UNUSED uint8_t a) +{ + return s; +} + +static inline uint8_t _opMaskAdd(uint8_t s, uint8_t d, uint8_t a) +{ + return s + MULTIPLY(d, a); +} + + +static inline uint8_t _opMaskSubtract(uint8_t s, uint8_t d, TVG_UNUSED uint8_t a) +{ + return MULTIPLY(s, 255 - d); +} + + +static inline uint8_t _opMaskIntersect(uint8_t s, uint8_t d, TVG_UNUSED uint8_t a) +{ + return MULTIPLY(s, d); +} + + +static inline uint8_t _opMaskDifference(uint8_t s, uint8_t d, uint8_t a) +{ + return MULTIPLY(s, 255 - d) + MULTIPLY(d, a); +} + + +static inline bool _direct(CompositeMethod method) +{ + //subtract & Intersect allows the direct composition + if (method == CompositeMethod::SubtractMask || method == CompositeMethod::IntersectMask) return true; + return false; +} + + +static inline SwMask _getMaskOp(CompositeMethod method) +{ + switch (method) { + case CompositeMethod::AddMask: return _opMaskAdd; + case CompositeMethod::SubtractMask: return _opMaskSubtract; + case CompositeMethod::DifferenceMask: return _opMaskDifference; + case CompositeMethod::IntersectMask: return _opMaskIntersect; + default: return nullptr; + } +} + + +static bool _compositeMaskImage(SwSurface* surface, const SwImage* image, const SwBBox& region) +{ + auto dbuffer = &surface->buf8[region.min.y * surface->stride + region.min.x]; + auto sbuffer = image->buf8 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + + for (auto y = region.min.y; y < region.max.y; ++y) { + auto dst = dbuffer; + auto src = sbuffer; + for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) { + *dst = *src + MULTIPLY(*dst, ~*src); + } + dbuffer += surface->stride; + sbuffer += image->stride; + } + return true; +} + + +#include "tvgSwRasterTexmap.h" +#include "tvgSwRasterC.h" +#include "tvgSwRasterAvx.h" +#include "tvgSwRasterNeon.h" + + +static inline uint32_t _sampleSize(float scale) +{ + auto sampleSize = static_cast(0.5f / scale); + if (sampleSize == 0) sampleSize = 1; + return sampleSize; +} + + +//Bilinear Interpolation +//OPTIMIZE_ME: Skip the function pointer access +static uint32_t _interpUpScaler(const uint32_t *img, TVG_UNUSED uint32_t stride, uint32_t w, uint32_t h, float sx, float sy, TVG_UNUSED int32_t miny, TVG_UNUSED int32_t maxy, TVG_UNUSED int32_t n) +{ + auto rx = (size_t)(sx); + auto ry = (size_t)(sy); + auto rx2 = rx + 1; + if (rx2 >= w) rx2 = w - 1; + auto ry2 = ry + 1; + if (ry2 >= h) ry2 = h - 1; + + auto dx = (sx > 0.0f) ? static_cast((sx - rx) * 255.0f) : 0; + auto dy = (sy > 0.0f) ? static_cast((sy - ry) * 255.0f) : 0; + + auto c1 = img[rx + ry * w]; + auto c2 = img[rx2 + ry * w]; + auto c3 = img[rx + ry2 * w]; + auto c4 = img[rx2 + ry2 * w]; + + return INTERPOLATE(INTERPOLATE(c4, c3, dx), INTERPOLATE(c2, c1, dx), dy); +} + + +//2n x 2n Mean Kernel +//OPTIMIZE_ME: Skip the function pointer access +static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t w, uint32_t h, float sx, TVG_UNUSED float sy, int32_t miny, int32_t maxy, int32_t n) +{ + size_t c[4] = {0, 0, 0, 0}; + + int32_t minx = (int32_t)sx - n; + if (minx < 0) minx = 0; + + int32_t maxx = (int32_t)sx + n; + if (maxx >= (int32_t)w) maxx = w; + + int32_t inc = (n / 2) + 1; + n = 0; + + auto src = img + minx + miny * stride; + + for (auto y = miny; y < maxy; y += inc) { + auto p = src; + for (auto x = minx; x < maxx; x += inc, p += inc) { + c[0] += A(*p); + c[1] += C1(*p); + c[2] += C2(*p); + c[3] += C3(*p); + ++n; + } + src += (stride * inc); + } + + c[0] /= n; + c[1] /= n; + c[2] /= n; + c[3] /= n; + + return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; +} + + +/************************************************************************/ +/* Rect */ +/************************************************************************/ + +static bool _rasterCompositeMaskedRect(SwSurface* surface, const SwBBox& region, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + auto w = static_cast(region.max.x - region.min.x); + auto h = static_cast(region.max.y - region.min.y); + auto cstride = surface->compositor->image.stride; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); //compositor buffer + auto ialpha = 255 - a; + + for (uint32_t y = 0; y < h; ++y) { + auto cmp = cbuffer; + for (uint32_t x = 0; x < w; ++x, ++cmp) { + *cmp = maskOp(a, *cmp, ialpha); + } + cbuffer += cstride; + } + return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); +} + + +static bool _rasterDirectMaskedRect(SwSurface* surface, const SwBBox& region, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + auto w = static_cast(region.max.x - region.min.x); + auto h = static_cast(region.max.y - region.min.y); + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x); //compositor buffer + auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x); //destination buffer + + for (uint32_t y = 0; y < h; ++y) { + auto cmp = cbuffer; + auto dst = dbuffer; + for (uint32_t x = 0; x < w; ++x, ++cmp, ++dst) { + auto tmp = maskOp(a, *cmp, 0); //not use alpha. + *dst = tmp + MULTIPLY(*dst, ~tmp); + } + cbuffer += surface->compositor->image.stride; + dbuffer += surface->stride; + } + return true; +} + + +static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + //8bit masking channels composition + if (surface->channelSize != sizeof(uint8_t)) return false; + + TVGLOG("SW_ENGINE", "Masked(%d) Rect [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y); + + auto maskOp = _getMaskOp(surface->compositor->method); + if (_direct(surface->compositor->method)) return _rasterDirectMaskedRect(surface, region, maskOp, r, g, b, a); + else return _rasterCompositeMaskedRect(surface, region, maskOp, r, g, b, a); + return false; +} + + +static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + auto w = static_cast(region.max.x - region.min.x); + auto h = static_cast(region.max.y - region.min.y); + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8 + ((region.min.y * surface->compositor->image.stride + region.min.x) * csize); //compositor buffer + auto alpha = surface->alpha(surface->compositor->method); + + TVGLOG("SW_ENGINE", "Matted(%d) Rect [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h); + + //32bits channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + auto cmp = &cbuffer[y * surface->compositor->image.stride * csize]; + for (uint32_t x = 0; x < w; ++x, ++dst, cmp += csize) { + *dst = INTERPOLATE(color, *dst, alpha(cmp)); + } + } + //8bits grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + auto cmp = &cbuffer[y * surface->compositor->image.stride * csize]; + for (uint32_t x = 0; x < w; ++x, ++dst, cmp += csize) { + *dst = INTERPOLATE8(a, *dst, alpha(cmp)); + } + } + } + return true; +} + + +static bool _rasterBlendingRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (surface->channelSize != sizeof(uint32_t)) return false; + + auto w = static_cast(region.max.x - region.min.x); + auto h = static_cast(region.max.y - region.min.y); + auto color = surface->join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + auto ialpha = 255 - a; + + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + for (uint32_t x = 0; x < w; ++x, ++dst) { + *dst = surface->blender(color, *dst, ialpha); + } + } + return true; +} + + +static bool _rasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ +#if defined(THORVG_AVX_VECTOR_SUPPORT) + return avxRasterTranslucentRect(surface, region, r, g, b, a); +#elif defined(THORVG_NEON_VECTOR_SUPPORT) + return neonRasterTranslucentRect(surface, region, r, g, b, a); +#else + return cRasterTranslucentRect(surface, region, r, g, b, a); +#endif +} + + +static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b) +{ + auto w = static_cast(region.max.x - region.min.x); + auto h = static_cast(region.max.y - region.min.y); + + //32bits channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->join(r, g, b, 255); + auto buffer = surface->buf32 + (region.min.y * surface->stride); + for (uint32_t y = 0; y < h; ++y) { + rasterPixel32(buffer + y * surface->stride, color, region.min.x, w); + } + return true; + } + //8bits grayscale + if (surface->channelSize == sizeof(uint8_t)) { + for (uint32_t y = 0; y < h; ++y) { + rasterGrayscale8(surface->buf8, 255, (y + region.min.y) * surface->stride + region.min.x, w); + } + return true; + } + return false; +} + + +static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (_compositing(surface)) { + if (_matting(surface)) return _rasterMattedRect(surface, region, r, g, b, a); + else return _rasterMaskedRect(surface, region, r, g, b, a); + } else if (_blending(surface)) { + return _rasterBlendingRect(surface, region, r, g, b, a); + } else { + if (a == 255) return _rasterSolidRect(surface, region, r, g, b); + else return _rasterTranslucentRect(surface, region, r, g, b, a); + } + return false; +} + + +/************************************************************************/ +/* Rle */ +/************************************************************************/ + +static bool _rasterCompositeMaskedRle(SwSurface* surface, SwRleData* rle, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + auto span = rle->spans; + auto cbuffer = surface->compositor->image.buf8; + auto cstride = surface->compositor->image.stride; + uint8_t src; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto cmp = &cbuffer[span->y * cstride + span->x]; + if (span->coverage == 255) src = a; + else src = MULTIPLY(a, span->coverage); + auto ialpha = 255 - src; + for (auto x = 0; x < span->len; ++x, ++cmp) { + *cmp = maskOp(src, *cmp, ialpha); + } + } + return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); +} + + +static bool _rasterDirectMaskedRle(SwSurface* surface, SwRleData* rle, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + auto span = rle->spans; + auto cbuffer = surface->compositor->image.buf8; + auto cstride = surface->compositor->image.stride; + uint8_t src; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto cmp = &cbuffer[span->y * cstride + span->x]; + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + if (span->coverage == 255) src = a; + else src = MULTIPLY(a, span->coverage); + for (auto x = 0; x < span->len; ++x, ++cmp, ++dst) { + auto tmp = maskOp(src, *cmp, 0); //not use alpha + *dst = tmp + MULTIPLY(*dst, ~tmp); + } + } + return true; +} + + +static bool _rasterMaskedRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + TVGLOG("SW_ENGINE", "Masked(%d) Rle", (int)surface->compositor->method); + + //8bit masking channels composition + if (surface->channelSize != sizeof(uint8_t)) return false; + + auto maskOp = _getMaskOp(surface->compositor->method); + if (_direct(surface->compositor->method)) return _rasterDirectMaskedRle(surface, rle, maskOp, r, g, b, a); + else return _rasterCompositeMaskedRle(surface, rle, maskOp, r, g, b, a); + return false; +} + + +static bool _rasterMattedRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + TVGLOG("SW_ENGINE", "Matted(%d) Rle", (int)surface->compositor->method); + + auto span = rle->spans; + auto cbuffer = surface->compositor->image.buf8; + auto csize = surface->compositor->image.channelSize; + auto alpha = surface->alpha(surface->compositor->method); + + //32bit channels + if (surface->channelSize == sizeof(uint32_t)) { + uint32_t src; + auto color = surface->join(r, g, b, a); + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; + if (span->coverage == 255) src = color; + else src = ALPHA_BLEND(color, span->coverage); + for (uint32_t x = 0; x < span->len; ++x, ++dst, cmp += csize) { + auto tmp = ALPHA_BLEND(src, alpha(cmp)); + *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); + } + } + return true; + } + //8bit grayscale + if (surface->channelSize == sizeof(uint8_t)) { + uint8_t src; + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; + if (span->coverage == 255) src = a; + else src = MULTIPLY(a, span->coverage); + for (uint32_t x = 0; x < span->len; ++x, ++dst, cmp += csize) { + *dst = INTERPOLATE8(src, *dst, alpha(cmp)); + } + } + return true; + } + return false; +} + + +static bool _rasterBlendingRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (surface->channelSize != sizeof(uint32_t)) return false; + + auto span = rle->spans; + auto color = surface->join(r, g, b, a); + auto ialpha = 255 - a; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + if (span->coverage == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = surface->blender(color, *dst, ialpha); + } + } else { + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + auto tmp = surface->blender(color, *dst, ialpha); + *dst = INTERPOLATE(tmp, *dst, span->coverage); + } + } + } + return true; +} + + +static bool _rasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ +#if defined(THORVG_AVX_VECTOR_SUPPORT) + return avxRasterTranslucentRle(surface, rle, r, g, b, a); +#elif defined(THORVG_NEON_VECTOR_SUPPORT) + return neonRasterTranslucentRle(surface, rle, r, g, b, a); +#else + return cRasterTranslucentRle(surface, rle, r, g, b, a); +#endif +} + + +static bool _rasterSolidRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b) +{ + auto span = rle->spans; + + //32bit channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->join(r, g, b, 255); + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + if (span->coverage == 255) { + rasterPixel32(surface->buf32 + span->y * surface->stride, color, span->x, span->len); + } else { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto src = ALPHA_BLEND(color, span->coverage); + auto ialpha = 255 - span->coverage; + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = src + ALPHA_BLEND(*dst, ialpha); + } + } + } + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + if (span->coverage == 255) { + rasterGrayscale8(surface->buf8, span->coverage, span->y * surface->stride + span->x, span->len); + } else { + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + auto ialpha = 255 - span->coverage; + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = span->coverage + MULTIPLY(*dst, ialpha); + } + } + } + } + return true; +} + + +static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (!rle) return false; + + if (_compositing(surface)) { + if (_matting(surface)) return _rasterMattedRle(surface, rle, r, g, b, a); + else return _rasterMaskedRle(surface, rle, r, g, b, a); + } else if (_blending(surface)) { + return _rasterBlendingRle(surface, rle, r, g, b, a); + } else { + if (a == 255) return _rasterSolidRle(surface, rle, r, g, b); + else return _rasterTranslucentRle(surface, rle, r, g, b, a); + } + return false; +} + + +/************************************************************************/ +/* RLE Scaled Image */ +/************************************************************************/ + +#define SCALED_IMAGE_RANGE_Y(y) \ + auto sy = (y) * itransform->e22 + itransform->e23 - 0.49f; \ + if (sy <= -0.5f || (uint32_t)(sy + 0.5f) >= image->h) continue; \ + if (scaleMethod == _interpDownScaler) { \ + auto my = (int32_t)round(sy); \ + miny = my - (int32_t)sampleSize; \ + if (miny < 0) miny = 0; \ + maxy = my + (int32_t)sampleSize; \ + if (maxy >= (int32_t)image->h) maxy = (int32_t)image->h; \ + } + +#define SCALED_IMAGE_RANGE_X \ + auto sx = (x) * itransform->e11 + itransform->e13 - 0.49f; \ + if (sx <= -0.5f || (uint32_t)(sx + 0.5f) >= image->w) continue; \ + + +#if 0 //Enable it when GRAYSCALE image is supported +static bool _rasterCompositeScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity) +{ + auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; + auto sampleSize = _sampleSize(image->scale); + auto span = image->rle->spans; + int32_t miny = 0, maxy = 0; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + SCALED_IMAGE_RANGE_Y(span->y) + auto cmp = &surface->compositor->image.buf8[span->y * surface->compositor->image.stride + span->x]; + auto a = MULTIPLY(span->coverage, opacity); + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++cmp) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + if (a < 255) src = MULTIPLY(src, a); + *cmp = maskOp(src, *cmp, ~src); + } + } + return true; +} + + +static bool _rasterDirectScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity) +{ + auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; + auto sampleSize = _sampleSize(image->scale); + auto span = image->rle->spans; + int32_t miny = 0, maxy = 0; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + SCALED_IMAGE_RANGE_Y(span->y) + auto cmp = &surface->compositor->image.buf8[span->y * surface->compositor->image.stride + span->x]; + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + auto a = MULTIPLY(span->coverage, opacity); + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++cmp, ++dst) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + if (a < 255) src = MULTIPLY(src, a); + src = maskOp(src, *cmp, 0); //not use alpha + *dst = src + MULTIPLY(*dst, ~src); + } + } + return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); +} +#endif + +static bool _rasterScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) +{ +#if 0 //Enable it when GRAYSCALE image is supported + TVGLOG("SW_ENGINE", "Scaled Masked(%d) Rle Image", (int)surface->compositor->method); + + //8bit masking channels composition + if (surface->channelSize != sizeof(uint8_t)) return false; + + auto maskOp = _getMaskOp(surface->compositor->method); + if (_direct(surface->compositor->method)) return _rasterDirectScaledMaskedRleImage(surface, image, itransform, region, maskOp, opacity); + else return _rasterCompositeScaledMaskedRleImage(surface, image, itransform, region, maskOp, opacity); +#endif + return false; +} + + +static bool _rasterScaledMattedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) +{ + TVGLOG("SW_ENGINE", "Scaled Matted(%d) Rle Image", (int)surface->compositor->method); + + auto span = image->rle->spans; + auto csize = surface->compositor->image.channelSize; + auto alpha = surface->alpha(surface->compositor->method); + auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; + auto sampleSize = _sampleSize(image->scale); + int32_t miny = 0, maxy = 0; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + SCALED_IMAGE_RANGE_Y(span->y) + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &surface->compositor->image.buf8[(span->y * surface->compositor->image.stride + span->x) * csize]; + auto a = MULTIPLY(span->coverage, opacity); + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, cmp += csize) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + src = ALPHA_BLEND(src, (a == 255) ? alpha(cmp) : MULTIPLY(alpha(cmp), a)); + *dst = src + ALPHA_BLEND(*dst, IA(src)); + } + } + + return true; +} + + +static bool _rasterScaledBlendingRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) +{ + auto span = image->rle->spans; + auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; + auto sampleSize = _sampleSize(image->scale); + int32_t miny = 0, maxy = 0; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + SCALED_IMAGE_RANGE_Y(span->y) + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto alpha = MULTIPLY(span->coverage, opacity); + if (alpha == 255) { + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + auto tmp = surface->blender(src, *dst, 255); + *dst = INTERPOLATE(tmp, *dst, A(src)); + } + } else { + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + if (opacity < 255) src = ALPHA_BLEND(src, opacity); + auto tmp = surface->blender(src, *dst, 255); + *dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(src))); + } + } + } + return true; +} + + +static bool _rasterScaledRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) +{ + auto span = image->rle->spans; + auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; + auto sampleSize = _sampleSize(image->scale); + int32_t miny = 0, maxy = 0; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + SCALED_IMAGE_RANGE_Y(span->y) + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto alpha = MULTIPLY(span->coverage, opacity); + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + if (alpha < 255) src = ALPHA_BLEND(src, alpha); + *dst = src + ALPHA_BLEND(*dst, IA(src)); + } + } + return true; +} + + +static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint8_t opacity) +{ + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported scaled rle image!"); + return false; + } + + Matrix itransform; + + if (transform) { + if (!mathInverse(transform, &itransform)) return false; + } else mathIdentity(&itransform); + + if (_compositing(surface)) { + if (_matting(surface)) return _rasterScaledMattedRleImage(surface, image, &itransform, region, opacity); + else return _rasterScaledMaskedRleImage(surface, image, &itransform, region, opacity); + } else if (_blending(surface)) { + return _rasterScaledBlendingRleImage(surface, image, &itransform, region, opacity); + } else { + return _rasterScaledRleImage(surface, image, &itransform, region, opacity); + } + return false; +} + + +/************************************************************************/ +/* RLE Direct Image */ +/************************************************************************/ + +#if 0 //Enable it when GRAYSCALE image is supported +static bool _rasterCompositeDirectMaskedRleImage(SwSurface* surface, const SwImage* image, SwMask maskOp, uint8_t opacity) +{ + auto span = image->rle->spans; + auto cbuffer = surface->compositor->image.buf8; + auto cstride = surface->compositor->image.stride; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto src = image->buf8 + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto cmp = &cbuffer[span->y * cstride + span->x]; + auto alpha = MULTIPLY(span->coverage, opacity); + if (alpha == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp) { + *cmp = maskOp(*src, *cmp, ~*src); + } + } else { + for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp) { + auto tmp = MULTIPLY(*src, alpha); + *cmp = maskOp(*src, *cmp, ~tmp); + } + } + } + return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); +} + + +static bool _rasterDirectDirectMaskedRleImage(SwSurface* surface, const SwImage* image, SwMask maskOp, uint8_t opacity) +{ + auto span = image->rle->spans; + auto cbuffer = surface->compositor->image.buf8; + auto cstride = surface->compositor->image.stride; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto src = image->buf8 + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto cmp = &cbuffer[span->y * cstride + span->x]; + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + auto alpha = MULTIPLY(span->coverage, opacity); + if (alpha == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp, ++dst) { + auto tmp = maskOp(*src, *cmp, 0); //not use alpha + *dst = INTERPOLATE8(tmp, *dst, (255 - tmp)); + } + } else { + for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp, ++dst) { + auto tmp = maskOp(MULTIPLY(*src, alpha), *cmp, 0); //not use alpha + *dst = INTERPOLATE8(tmp, *dst, (255 - tmp)); + } + } + } + return true; +} +#endif + +static bool _rasterDirectMaskedRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity) +{ +#if 0 //Enable it when GRAYSCALE image is supported + TVGLOG("SW_ENGINE", "Direct Masked(%d) Rle Image", (int)surface->compositor->method); + + //8bit masking channels composition + if (surface->channelSize != sizeof(uint8_t)) return false; + + auto maskOp = _getMaskOp(surface->compositor->method); + if (_direct(surface->compositor->method)) _rasterDirectDirectMaskedRleImage(surface, image, maskOp, opacity); + else return _rasterCompositeDirectMaskedRleImage(surface, image, maskOp, opacity); +#endif + return false; +} + + +static bool _rasterDirectMattedRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity) +{ + TVGLOG("SW_ENGINE", "Direct Matted(%d) Rle Image", (int)surface->compositor->method); + + auto span = image->rle->spans; + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8; + auto alpha = surface->alpha(surface->compositor->method); + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; + auto img = image->buf32 + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto a = MULTIPLY(span->coverage, opacity); + if (a == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img, cmp += csize) { + auto tmp = ALPHA_BLEND(*img, alpha(cmp)); + *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); + } + } else { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img, cmp += csize) { + auto tmp = ALPHA_BLEND(*img, MULTIPLY(a, alpha(cmp))); + *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); + } + } + } + return true; +} + + +static bool _rasterDirectBlendingRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity) +{ + auto span = image->rle->spans; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto img = image->buf32 + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto alpha = MULTIPLY(span->coverage, opacity); + if (alpha == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { + *dst = surface->blender(*img, *dst, IA(*img)); + } + } else if (opacity == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { + auto tmp = surface->blender(*img, *dst, 255); + *dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(*img))); + } + } else { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { + auto src = ALPHA_BLEND(*img, opacity); + auto tmp = surface->blender(src, *dst, IA(src)); + *dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(src))); + } + } + } + return true; +} + + +static bool _rasterDirectRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity) +{ + auto span = image->rle->spans; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto img = image->buf32 + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto alpha = MULTIPLY(span->coverage, opacity); + if (alpha == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { + *dst = *img + ALPHA_BLEND(*dst, IA(*img)); + } + } else { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { + auto src = ALPHA_BLEND(*img, alpha); + *dst = src + ALPHA_BLEND(*dst, IA(src)); + } + } + } + return true; +} + + +static bool _directRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity) +{ + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale rle image!"); + return false; + } + + if (_compositing(surface)) { + if (_matting(surface)) return _rasterDirectMattedRleImage(surface, image, opacity); + else return _rasterDirectMaskedRleImage(surface, image, opacity); + } else if (_blending(surface)) { + return _rasterDirectBlendingRleImage(surface, image, opacity); + } else { + return _rasterDirectRleImage(surface, image, opacity); + } + return false; +} + + +/************************************************************************/ +/*Scaled Image */ +/************************************************************************/ + +#if 0 //Enable it when GRAYSCALE image is supported +static bool _rasterCompositeScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity) +{ + auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; + auto sampleSize = _sampleSize(image->scale); + auto cstride = surface->compositor->image.stride; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); + int32_t miny = 0, maxy = 0; + + for (auto y = region.min.y; y < region.max.y; ++y) { + SCALED_IMAGE_RANGE_Y(y) + auto cmp = cbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + if (opacity < 255) src = MULTIPLY(src, opacity); + *cmp = maskOp(src, *cmp, ~src); + } + cbuffer += cstride; + } + return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); +} + + +static bool _rasterDirectScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity) +{ + auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; + auto sampleSize = _sampleSize(image->scale); + auto cstride = surface->compositor->image.stride; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); + auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x); + int32_t miny = 0, maxy = 0; + + for (auto y = region.min.y; y < region.max.y; ++y) { + SCALED_IMAGE_RANGE_Y(y) + auto cmp = cbuffer; + auto dst = dbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++cmp, ++dst) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + if (opacity < 255) src = MULTIPLY(src, opacity); + src = maskOp(src, *cmp, 0); //not use alpha + *dst = src + MULTIPLY(*dst, ~src); + } + cbuffer += cstride; + dbuffer += surface->stride; + } + return true; +} +#endif + +static bool _rasterScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) +{ +#if 0 //Enable it when GRAYSCALE image is supported + TVGLOG("SW_ENGINE", "Scaled Masked(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y); + + auto maskOp = _getMaskOp(surface->compositor->method); + if (_direct(surface->compositor->method)) return _rasterDirectScaledMaskedImage(surface, image, itransform, region, maskOp, opacity); + else return _rasterCompositeScaledMaskedImage(surface, image, itransform, region, maskOp, opacity); +#endif + return false; +} + + +static bool _rasterScaledMattedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) +{ + auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; + auto alpha = surface->alpha(surface->compositor->method); + + TVGLOG("SW_ENGINE", "Scaled Matted(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y); + + auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; + auto sampleSize = _sampleSize(image->scale); + int32_t miny = 0, maxy = 0; + + for (auto y = region.min.y; y < region.max.y; ++y) { + SCALED_IMAGE_RANGE_Y(y) + auto dst = dbuffer; + auto cmp = cbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + auto tmp = ALPHA_BLEND(src, opacity == 255 ? alpha(cmp) : MULTIPLY(opacity, alpha(cmp))); + *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); + } + dbuffer += surface->stride; + cbuffer += surface->compositor->image.stride * csize; + } + return true; +} + + +static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) +{ + auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); + auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; + auto sampleSize = _sampleSize(image->scale); + int32_t miny = 0, maxy = 0; + + for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) { + SCALED_IMAGE_RANGE_Y(y) + auto dst = dbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + if (opacity < 255) ALPHA_BLEND(src, opacity); + auto tmp = surface->blender(src, *dst, 255); + *dst = INTERPOLATE(tmp, *dst, A(src)); + } + } + return true; +} + + +static bool _rasterScaledImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) +{ + auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); + auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; + auto sampleSize = _sampleSize(image->scale); + int32_t miny = 0, maxy = 0; + + for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) { + SCALED_IMAGE_RANGE_Y(y) + auto dst = dbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + if (opacity < 255) src = ALPHA_BLEND(src, opacity); + *dst = src + ALPHA_BLEND(*dst, IA(src)); + } + } + return true; +} + + +static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint8_t opacity) +{ + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon mesh!"); + return false; + } + + Matrix itransform; + + if (transform) { + if (!mathInverse(transform, &itransform)) return false; + } else mathIdentity(&itransform); + + if (_compositing(surface)) { + if (_matting(surface)) return _rasterScaledMattedImage(surface, image, &itransform, region, opacity); + else return _rasterScaledMaskedImage(surface, image, &itransform, region, opacity); + } else if (_blending(surface)) { + return _rasterScaledBlendingImage(surface, image, &itransform, region, opacity); + } else { + return _rasterScaledImage(surface, image, &itransform, region, opacity); + } + return false; +} + + +/************************************************************************/ +/* Direct Image */ +/************************************************************************/ + +#if 0 //Enable it when GRAYSCALE image is supported +static bool _rasterCompositeDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, SwMask maskOp, uint8_t opacity) +{ + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + auto cstride = surface->compositor->image.stride; + + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); //compositor buffer + auto sbuffer = image->buf8 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + + for (uint32_t y = 0; y < h; ++y) { + auto cmp = cbuffer; + auto src = sbuffer; + if (opacity == 255) { + for (uint32_t x = 0; x < w; ++x, ++src, ++cmp) { + *cmp = maskOp(*src, *cmp, ~*src); + } + } else { + for (uint32_t x = 0; x < w; ++x, ++src, ++cmp) { + auto tmp = MULTIPLY(*src, opacity); + *cmp = maskOp(tmp, *cmp, ~tmp); + } + } + cbuffer += cstride; + sbuffer += image->stride; + } + return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); +} + + +static bool _rasterDirectDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, SwMask maskOp, uint8_t opacity) +{ + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + auto cstride = surface->compositor->image.stride; + + auto cbuffer = surface->compositor->image.buf32 + (region.min.y * cstride + region.min.x); //compositor buffer + auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x); //destination buffer + auto sbuffer = image->buf8 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + + for (uint32_t y = 0; y < h; ++y) { + auto cmp = cbuffer; + auto dst = dbuffer; + auto src = sbuffer; + if (opacity == 255) { + for (uint32_t x = 0; x < w; ++x, ++src, ++cmp, ++dst) { + auto tmp = maskOp(*src, *cmp, 0); //not use alpha + *dst = tmp + MULTIPLY(*dst, ~tmp); + } + } else { + for (uint32_t x = 0; x < w; ++x, ++src, ++cmp, ++dst) { + auto tmp = maskOp(MULTIPLY(*src, opacity), *cmp, 0); //not use alpha + *dst = tmp + MULTIPLY(*dst, ~tmp); + } + } + cbuffer += cstride; + dbuffer += surface->stride; + sbuffer += image->stride; + } + return true; +} +#endif + +static bool _rasterDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity) +{ + TVGERR("SW_ENGINE", "Not Supported: Direct Masked(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y); + +#if 0 //Enable it when GRAYSCALE image is supported + auto maskOp = _getMaskOp(surface->compositor->method); + if (_direct(surface->compositor->method)) return _rasterDirectDirectMaskedImage(surface, image, region, maskOp, opacity); + else return _rasterCompositeDirectMaskedImage(surface, image, region, maskOp, opacity); +#endif + return false; +} + + +static bool _rasterDirectMattedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity) +{ + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + auto csize = surface->compositor->image.channelSize; + auto alpha = surface->alpha(surface->compositor->method); + auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; //compositor buffer + + TVGLOG("SW_ENGINE", "Direct Matted(%d) Image [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h); + + //32 bits + if (surface->channelSize == sizeof(uint32_t)) { + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + auto dst = buffer; + auto cmp = cbuffer; + auto src = sbuffer; + if (opacity == 255) { + for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, alpha(cmp)); + *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); + } + } else { + for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, MULTIPLY(opacity, alpha(cmp))); + *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); + } + } + buffer += surface->stride; + cbuffer += surface->compositor->image.stride * csize; + sbuffer += image->stride; + } + //8 bits + } else if (surface->channelSize == sizeof(uint8_t)) { + auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + auto dst = buffer; + auto cmp = cbuffer; + auto src = sbuffer; + if (opacity == 255) { + for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) { + *dst = MULTIPLY(A(*src), alpha(cmp)); + } + } else { + for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) { + *dst = MULTIPLY(A(*src), MULTIPLY(opacity, alpha(cmp))); + } + } + buffer += surface->stride; + cbuffer += surface->compositor->image.stride * csize; + sbuffer += image->stride; + } + } + return true; +} + + +static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity) +{ + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale image!"); + return false; + } + + auto dbuffer = &surface->buf32[region.min.y * surface->stride + region.min.x]; + auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + + for (auto y = region.min.y; y < region.max.y; ++y) { + auto dst = dbuffer; + auto src = sbuffer; + if (opacity == 255) { + for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) { + auto tmp = surface->blender(*src, *dst, 255); + *dst = INTERPOLATE(tmp, *dst, A(*src)); + } + } else { + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) { + auto tmp = ALPHA_BLEND(*src, opacity); + auto tmp2 = surface->blender(tmp, *dst, 255); + *dst = INTERPOLATE(tmp2, *dst, A(tmp)); + } + } + dbuffer += surface->stride; + sbuffer += image->stride; + } + return true; +} + + +static bool _rasterDirectImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity) +{ + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale image!"); + return false; + } + + auto dbuffer = &surface->buf32[region.min.y * surface->stride + region.min.x]; + auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + + for (auto y = region.min.y; y < region.max.y; ++y) { + auto dst = dbuffer; + auto src = sbuffer; + if (opacity == 255) { + for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) { + *dst = *src + ALPHA_BLEND(*dst, IA(*src)); + } + } else { + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) { + auto tmp = ALPHA_BLEND(*src, opacity); + *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); + } + } + dbuffer += surface->stride; + sbuffer += image->stride; + } + return true; +} + + +//Blenders for the following scenarios: [Composition / Non-Composition] * [Opaque / Translucent] +static bool _directImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity) +{ + if (_compositing(surface)) { + if (_matting(surface)) return _rasterDirectMattedImage(surface, image, region, opacity); + else return _rasterDirectMaskedImage(surface, image, region, opacity); + } else if (_blending(surface)) { + return _rasterDirectBlendingImage(surface, image, region, opacity); + } else { + return _rasterDirectImage(surface, image, region, opacity); + } + return false; +} + + +//Blenders for the following scenarios: [RLE / Whole] * [Direct / Scaled / Transformed] +static bool _rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& region, uint8_t opacity) +{ + //RLE Image + if (image->rle) { + if (image->direct) return _directRleImage(surface, image, opacity); + else if (image->scaled) return _scaledRleImage(surface, image, transform, region, opacity); + else return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity); + //Whole Image + } else { + if (image->direct) return _directImage(surface, image, region, opacity); + else if (image->scaled) return _scaledImage(surface, image, transform, region, opacity); + else return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity); + } +} + + +/************************************************************************/ +/* Rect Gradient */ +/************************************************************************/ + +template +static bool _rasterCompositeGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, SwMask maskOp) +{ + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + auto cstride = surface->compositor->image.stride; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); + + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, cbuffer, region.min.y + y, region.min.x, w, maskOp, 255); + cbuffer += surface->stride; + } + return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); +} + + +template +static bool _rasterDirectGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, SwMask maskOp) +{ + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + auto cstride = surface->compositor->image.stride; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); + auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x); + + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, dbuffer, region.min.y + y, region.min.x, w, cbuffer, maskOp, 255); + cbuffer += cstride; + dbuffer += surface->stride; + } + return true; +} + + +template +static bool _rasterGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + auto method = surface->compositor->method; + + TVGLOG("SW_ENGINE", "Masked(%d) Gradient [Region: %lu %lu %lu %lu]", (int)method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y); + + auto maskOp = _getMaskOp(method); + + if (_direct(method)) return _rasterDirectGradientMaskedRect(surface, region, fill, maskOp); + else return _rasterCompositeGradientMaskedRect(surface, region, fill, maskOp); + + return false; +} + + +template +static bool _rasterGradientMattedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; + auto alpha = surface->alpha(surface->compositor->method); + + TVGLOG("SW_ENGINE", "Matted(%d) Gradient [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h); + + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, cbuffer, alpha, csize, 255); + buffer += surface->stride; + cbuffer += surface->stride * csize; + } + return true; +} + + +template +static bool _rasterBlendingGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + auto w = static_cast(region.max.x - region.min.x); + auto h = static_cast(region.max.y - region.min.y); + + if (fill->translucent) { + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w, opBlendPreNormal, surface->blender, 255); + } + } else { + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w, opBlendSrcOver, surface->blender, 255); + } + } + return true; +} + +template +static bool _rasterTranslucentGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, opBlendPreNormal, 255); + buffer += surface->stride; + } + return true; +} + + +template +static bool _rasterSolidGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + auto w = static_cast(region.max.x - region.min.x); + auto h = static_cast(region.max.y - region.min.y); + + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w, opBlendSrcOver, 255); + } + return true; +} + + +static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + if (fill->linear.len < FLOAT_EPSILON) return false; + + if (_compositing(surface)) { + if (_matting(surface)) return _rasterGradientMattedRect(surface, region, fill); + else return _rasterGradientMaskedRect(surface, region, fill); + } else if (_blending(surface)) { + return _rasterBlendingGradientRect(surface, region, fill); + } else { + if (fill->translucent) return _rasterTranslucentGradientRect(surface, region, fill); + else _rasterSolidGradientRect(surface, region, fill); + } + return false; +} + + +static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + if (_compositing(surface)) { + if (_matting(surface)) return _rasterGradientMattedRect(surface, region, fill); + else return _rasterGradientMaskedRect(surface, region, fill); + } else if (_blending(surface)) { + return _rasterBlendingGradientRect(surface, region, fill); + } else { + if (fill->translucent) return _rasterTranslucentGradientRect(surface, region, fill); + else _rasterSolidGradientRect(surface, region, fill); + } + return false; +} + + +/************************************************************************/ +/* Rle Gradient */ +/************************************************************************/ + +template +static bool _rasterCompositeGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, SwMask maskOp) +{ + auto span = rle->spans; + auto cstride = surface->compositor->image.stride; + auto cbuffer = surface->compositor->image.buf8; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto cmp = &cbuffer[span->y * cstride + span->x]; + fillMethod()(fill, cmp, span->y, span->x, span->len, maskOp, span->coverage); + } + return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); +} + + +template +static bool _rasterDirectGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, SwMask maskOp) +{ + auto span = rle->spans; + auto cstride = surface->compositor->image.stride; + auto cbuffer = surface->compositor->image.buf8; + auto dbuffer = surface->buf8; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto cmp = &cbuffer[span->y * cstride + span->x]; + auto dst = &dbuffer[span->y * surface->stride + span->x]; + fillMethod()(fill, dst, span->y, span->x, span->len, cmp, maskOp, span->coverage); + } + return true; +} + + +template +static bool _rasterGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + auto method = surface->compositor->method; + + TVGLOG("SW_ENGINE", "Masked(%d) Rle Linear Gradient", (int)method); + + auto maskOp = _getMaskOp(method); + + if (_direct(method)) return _rasterDirectGradientMaskedRle(surface, rle, fill, maskOp); + else return _rasterCompositeGradientMaskedRle(surface, rle, fill, maskOp); + return false; +} + + +template +static bool _rasterGradientMattedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + TVGLOG("SW_ENGINE", "Matted(%d) Rle Linear Gradient", (int)surface->compositor->method); + + auto span = rle->spans; + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8; + auto alpha = surface->alpha(surface->compositor->method); + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; + fillMethod()(fill, dst, span->y, span->x, span->len, cmp, alpha, csize, span->coverage); + } + return true; +} + + +template +static bool _rasterBlendingGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + auto span = rle->spans; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + fillMethod()(fill, dst, span->y, span->x, span->len, opBlendPreNormal, surface->blender, span->coverage); + } + return true; +} + + +template +static bool _rasterTranslucentGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + auto span = rle->spans; + + //32 bits + if (surface->channelSize == sizeof(uint32_t)) { + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + if (span->coverage == 255) fillMethod()(fill, dst, span->y, span->x, span->len, opBlendPreNormal, 255); + else fillMethod()(fill, dst, span->y, span->x, span->len, opBlendNormal, span->coverage); + } + //8 bits + } else if (surface->channelSize == sizeof(uint8_t)) { + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + fillMethod()(fill, dst, span->y, span->x, span->len, _opMaskAdd, 255); + } + } + return true; +} + + +template +static bool _rasterSolidGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + auto span = rle->spans; + + //32 bits + if (surface->channelSize == sizeof(uint32_t)) { + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + if (span->coverage == 255) fillMethod()(fill, dst, span->y, span->x, span->len, opBlendSrcOver, 255); + else fillMethod()(fill, dst, span->y, span->x, span->len, opBlendInterp, span->coverage); + } + //8 bits + } else if (surface->channelSize == sizeof(uint8_t)) { + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + if (span->coverage == 255) fillMethod()(fill, dst, span->y, span->x, span->len, _opMaskNone, 255); + else fillMethod()(fill, dst, span->y, span->x, span->len, _opMaskAdd, span->coverage); + } + } + + return true; +} + + +static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + if (!rle) return false; + + if (_compositing(surface)) { + if (_matting(surface)) return _rasterGradientMattedRle(surface, rle, fill); + else return _rasterGradientMaskedRle(surface, rle, fill); + } else if (_blending(surface)) { + return _rasterBlendingGradientRle(surface, rle, fill); + } else { + if (fill->translucent) return _rasterTranslucentGradientRle(surface, rle, fill); + else return _rasterSolidGradientRle(surface, rle, fill); + } + return false; +} + + +static bool _rasterRadialGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + if (!rle) return false; + + if (_compositing(surface)) { + if (_matting(surface)) return _rasterGradientMattedRle(surface, rle, fill); + else return _rasterGradientMaskedRle(surface, rle, fill); + } else if (_blending(surface)) { + _rasterBlendingGradientRle(surface, rle, fill); + } else { + if (fill->translucent) _rasterTranslucentGradientRle(surface, rle, fill); + else return _rasterSolidGradientRle(surface, rle, fill); + } + return false; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +void rasterGrayscale8(uint8_t *dst, uint8_t val, uint32_t offset, int32_t len) +{ +#if defined(THORVG_AVX_VECTOR_SUPPORT) + avxRasterGrayscale8(dst, val, offset, len); +#elif defined(THORVG_NEON_VECTOR_SUPPORT) + neonRasterGrayscale8(dst, val, offset, len); +#else + cRasterPixels(dst, val, offset, len); +#endif +} + + +void rasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) +{ +#if defined(THORVG_AVX_VECTOR_SUPPORT) + avxRasterPixel32(dst, val, offset, len); +#elif defined(THORVG_NEON_VECTOR_SUPPORT) + neonRasterPixel32(dst, val, offset, len); +#else + cRasterPixels(dst, val, offset, len); +#endif +} + + +bool rasterCompositor(SwSurface* surface) +{ + //See CompositeMethod, Alpha:3, InvAlpha:4, Luma:5, InvLuma:6 + surface->alphas[0] = _alpha; + surface->alphas[1] = _ialpha; + + if (surface->cs == ColorSpace::ABGR8888 || surface->cs == ColorSpace::ABGR8888S) { + surface->join = _abgrJoin; + surface->alphas[2] = _abgrLuma; + surface->alphas[3] = _abgrInvLuma; + } else if (surface->cs == ColorSpace::ARGB8888 || surface->cs == ColorSpace::ARGB8888S) { + surface->join = _argbJoin; + surface->alphas[2] = _argbLuma; + surface->alphas[3] = _argbInvLuma; + } else { + TVGERR("SW_ENGINE", "Unsupported Colorspace(%d) is expected!", surface->cs); + return false; + } + return true; +} + + +bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h) +{ + if (!surface || !surface->buf32 || surface->stride == 0 || surface->w == 0 || surface->h == 0) return false; + + //32 bits + if (surface->channelSize == sizeof(uint32_t)) { + //full clear + if (w == surface->stride) { + rasterPixel32(surface->buf32, 0x00000000, surface->stride * y, w * h); + //partial clear + } else { + for (uint32_t i = 0; i < h; i++) { + rasterPixel32(surface->buf32, 0x00000000, (surface->stride * y + x) + (surface->stride * i), w); + } + } + //8 bits + } else if (surface->channelSize == sizeof(uint8_t)) { + //full clear + if (w == surface->stride) { + rasterGrayscale8(surface->buf8, 0x00, surface->stride * y, w * h); + //partial clear + } else { + for (uint32_t i = 0; i < h; i++) { + rasterGrayscale8(surface->buf8, 0x00, (surface->stride * y + x) + (surface->stride * i), w); + } + } + } + return true; +} + + +void rasterUnpremultiply(Surface* surface) +{ + if (surface->channelSize != sizeof(uint32_t)) return; + + TVGLOG("SW_ENGINE", "Unpremultiply [Size: %d x %d]", surface->w, surface->h); + + //OPTIMIZE_ME: +SIMD + for (uint32_t y = 0; y < surface->h; y++) { + auto buffer = surface->buf32 + surface->stride * y; + for (uint32_t x = 0; x < surface->w; ++x) { + uint8_t a = buffer[x] >> 24; + if (a == 255) { + continue; + } else if (a == 0) { + buffer[x] = 0x00ffffff; + } else { + uint16_t r = ((buffer[x] >> 8) & 0xff00) / a; + uint16_t g = ((buffer[x]) & 0xff00) / a; + uint16_t b = ((buffer[x] << 8) & 0xff00) / a; + if (r > 0xff) r = 0xff; + if (g > 0xff) g = 0xff; + if (b > 0xff) b = 0xff; + buffer[x] = (a << 24) | (r << 16) | (g << 8) | (b); + } + } + } + surface->premultiplied = false; +} + + +void rasterPremultiply(Surface* surface) +{ + ScopedLock lock(surface->key); + if (surface->premultiplied || (surface->channelSize != sizeof(uint32_t))) return; + surface->premultiplied = true; + + TVGLOG("SW_ENGINE", "Premultiply [Size: %d x %d]", surface->w, surface->h); + + //OPTIMIZE_ME: +SIMD + auto buffer = surface->buf32; + for (uint32_t y = 0; y < surface->h; ++y, buffer += surface->stride) { + auto dst = buffer; + for (uint32_t x = 0; x < surface->w; ++x, ++dst) { + auto c = *dst; + auto a = (c >> 24); + *dst = (c & 0xff000000) + ((((c >> 8) & 0xff) * a) & 0xff00) + ((((c & 0x00ff00ff) * a) >> 8) & 0x00ff00ff); + } + } +} + + +bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id) +{ + if (!shape->fill) return false; + + if (shape->fastTrack) { + if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRect(surface, shape->bbox, shape->fill); + else if (id == TVG_CLASS_ID_RADIAL)return _rasterRadialGradientRect(surface, shape->bbox, shape->fill); + } else { + if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->rle, shape->fill); + else if (id == TVG_CLASS_ID_RADIAL) return _rasterRadialGradientRle(surface, shape->rle, shape->fill); + } + return false; +} + + +bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id) +{ + if (!shape->stroke || !shape->stroke->fill || !shape->strokeRle) return false; + + if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->strokeRle, shape->stroke->fill); + else if (id == TVG_CLASS_ID_RADIAL) return _rasterRadialGradientRle(surface, shape->strokeRle, shape->stroke->fill); + + return false; +} + + +bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (a < 255) { + r = MULTIPLY(r, a); + g = MULTIPLY(g, a); + b = MULTIPLY(b, a); + } + if (shape->fastTrack) return _rasterRect(surface, shape->bbox, r, g, b, a); + else return _rasterRle(surface, shape->rle, r, g, b, a); +} + + +bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (a < 255) { + r = MULTIPLY(r, a); + g = MULTIPLY(g, a); + b = MULTIPLY(b, a); + } + + return _rasterRle(surface, shape->strokeRle, r, g, b, a); +} + + +bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint8_t opacity) +{ + //Outside of the viewport, skip the rendering + if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast(surface->w) || bbox.min.y >= static_cast(surface->h)) return true; + + if (mesh && mesh->triangleCnt > 0) return _rasterTexmapPolygonMesh(surface, image, mesh, transform, &bbox, opacity); + else return _rasterImage(surface, image, transform, bbox, opacity); +} + + +bool rasterConvertCS(Surface* surface, ColorSpace to) +{ + ScopedLock lock(surface->key); + if (surface->cs == to) return true; + + //TODO: Support SIMD accelerations + auto from = surface->cs; + + if (((from == ColorSpace::ABGR8888) || (from == ColorSpace::ABGR8888S)) && ((to == ColorSpace::ARGB8888) || (to == ColorSpace::ARGB8888S))) { + surface->cs = to; + return cRasterABGRtoARGB(surface); + } + if (((from == ColorSpace::ARGB8888) || (from == ColorSpace::ARGB8888S)) && ((to == ColorSpace::ABGR8888) || (to == ColorSpace::ABGR8888S))) { + surface->cs = to; + return cRasterARGBtoABGR(surface); + } + return false; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwRasterAvx.h b/test/include/liblvgl/libs/thorvg/tvgSwRasterAvx.h new file mode 100644 index 00000000..cc170de9 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwRasterAvx.h @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifdef THORVG_AVX_VECTOR_SUPPORT + +#include + +#define N_32BITS_IN_128REG 4 +#define N_32BITS_IN_256REG 8 + +static inline __m128i ALPHA_BLEND(__m128i c, __m128i a) +{ + //1. set the masks for the A/G and R/B channels + auto AG = _mm_set1_epi32(0xff00ff00); + auto RB = _mm_set1_epi32(0x00ff00ff); + + //2. mask the alpha vector - originally quartet [a, a, a, a] + auto aAG = _mm_and_si128(a, AG); + auto aRB = _mm_and_si128(a, RB); + + //3. calculate the alpha blending of the 2nd and 4th channel + //- mask the color vector + //- multiply it by the masked alpha vector + //- add the correction to compensate bit shifting used instead of dividing by 255 + //- shift bits - corresponding to division by 256 + auto even = _mm_and_si128(c, RB); + even = _mm_mullo_epi16(even, aRB); + even =_mm_add_epi16(even, RB); + even = _mm_srli_epi16(even, 8); + + //4. calculate the alpha blending of the 1st and 3rd channel: + //- mask the color vector + //- multiply it by the corresponding masked alpha vector and store the high bits of the result + //- add the correction to compensate division by 256 instead of by 255 (next step) + //- remove the low 8 bits to mimic the division by 256 + auto odd = _mm_and_si128(c, AG); + odd = _mm_mulhi_epu16(odd, aAG); + odd = _mm_add_epi16(odd, RB); + odd = _mm_and_si128(odd, AG); + + //5. the final result + return _mm_or_si128(odd, even); +} + + +static void avxRasterGrayscale8(uint8_t* dst, uint8_t val, uint32_t offset, int32_t len) +{ + dst += offset; + + __m256i vecVal = _mm256_set1_epi8(val); + + int32_t i = 0; + for (; i <= len - 32; i += 32) { + _mm256_storeu_si256((__m256i*)(dst + i), vecVal); + } + + for (; i < len; ++i) { + dst[i] = val; + } +} + + +static void avxRasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) +{ + //1. calculate how many iterations we need to cover the length + uint32_t iterations = len / N_32BITS_IN_256REG; + uint32_t avxFilled = iterations * N_32BITS_IN_256REG; + + //2. set the beginning of the array + dst += offset; + + //3. fill the octets + for (uint32_t i = 0; i < iterations; ++i, dst += N_32BITS_IN_256REG) { + _mm256_storeu_si256((__m256i*)dst, _mm256_set1_epi32(val)); + } + + //4. fill leftovers (in the first step we have to set the pointer to the place where the avx job is done) + int32_t leftovers = len - avxFilled; + while (leftovers--) *dst++ = val; +} + + +static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (surface->channelSize != sizeof(uint32_t)) { + TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); + return false; + } + + auto color = surface->join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + + uint32_t ialpha = 255 - a; + + auto avxColor = _mm_set1_epi32(color); + auto avxIalpha = _mm_set1_epi8(ialpha); + + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + + //1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required) + auto notAligned = ((uintptr_t)dst & 0xf) / 4; + if (notAligned) { + notAligned = (N_32BITS_IN_128REG - notAligned > w ? w : N_32BITS_IN_128REG - notAligned); + for (uint32_t x = 0; x < notAligned; ++x, ++dst) { + *dst = color + ALPHA_BLEND(*dst, ialpha); + } + } + + //2. fill the aligned memory - N_32BITS_IN_128REG pixels processed at once + uint32_t iterations = (w - notAligned) / N_32BITS_IN_128REG; + uint32_t avxFilled = iterations * N_32BITS_IN_128REG; + auto avxDst = (__m128i*)dst; + for (uint32_t x = 0; x < iterations; ++x, ++avxDst) { + *avxDst = _mm_add_epi32(avxColor, ALPHA_BLEND(*avxDst, avxIalpha)); + } + + //3. fill the remaining pixels + int32_t leftovers = w - notAligned - avxFilled; + dst += avxFilled; + while (leftovers--) { + *dst = color + ALPHA_BLEND(*dst, ialpha); + dst++; + } + } + return true; +} + + +static bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (surface->channelSize != sizeof(uint32_t)) { + TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); + return false; + } + + auto color = surface->join(r, g, b, a); + auto span = rle->spans; + uint32_t src; + + for (uint32_t i = 0; i < rle->size; ++i) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + + if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); + else src = color; + + auto ialpha = IA(src); + + //1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required) + auto notAligned = ((uintptr_t)dst & 0xf) / 4; + if (notAligned) { + notAligned = (N_32BITS_IN_128REG - notAligned > span->len ? span->len : N_32BITS_IN_128REG - notAligned); + for (uint32_t x = 0; x < notAligned; ++x, ++dst) { + *dst = src + ALPHA_BLEND(*dst, ialpha); + } + } + + //2. fill the aligned memory using avx - N_32BITS_IN_128REG pixels processed at once + //In order to avoid unnecessary avx variables declarations a check is made whether there are any iterations at all + uint32_t iterations = (span->len - notAligned) / N_32BITS_IN_128REG; + uint32_t avxFilled = 0; + if (iterations > 0) { + auto avxSrc = _mm_set1_epi32(src); + auto avxIalpha = _mm_set1_epi8(ialpha); + + avxFilled = iterations * N_32BITS_IN_128REG; + auto avxDst = (__m128i*)dst; + for (uint32_t x = 0; x < iterations; ++x, ++avxDst) { + *avxDst = _mm_add_epi32(avxSrc, ALPHA_BLEND(*avxDst, avxIalpha)); + } + } + + //3. fill the remaining pixels + int32_t leftovers = span->len - notAligned - avxFilled; + dst += avxFilled; + while (leftovers--) { + *dst = src + ALPHA_BLEND(*dst, ialpha); + dst++; + } + + ++span; + } + return true; +} + + +#endif + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwRasterC.h b/test/include/liblvgl/libs/thorvg/tvgSwRasterC.h new file mode 100644 index 00000000..bc5211e5 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwRasterC.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +template +static void inline cRasterPixels(PIXEL_T* dst, PIXEL_T val, uint32_t offset, int32_t len) +{ + dst += offset; + + //fix the misaligned memory + auto alignOffset = (long long) dst % 8; + if (alignOffset > 0) { + if (sizeof(PIXEL_T) == 4) alignOffset /= 4; + else if (sizeof(PIXEL_T) == 1) alignOffset = 8 - alignOffset; + while (alignOffset > 0 && len > 0) { + *dst++ = val; + --len; + --alignOffset; + } + } + + //64bits faster clear + if ((sizeof(PIXEL_T) == 4)) { + auto val64 = (uint64_t(val) << 32) | uint64_t(val); + while (len > 1) { + *reinterpret_cast(dst) = val64; + len -= 2; + dst += 2; + } + } else if (sizeof(PIXEL_T) == 1) { + auto val32 = (uint32_t(val) << 24) | (uint32_t(val) << 16) | (uint32_t(val) << 8) | uint32_t(val); + auto val64 = (uint64_t(val32) << 32) | val32; + while (len > 7) { + *reinterpret_cast(dst) = val64; + len -= 8; + dst += 8; + } + } + + //leftovers + while (len--) *dst++ = val; +} + + +static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + auto span = rle->spans; + + //32bit channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->join(r, g, b, a); + uint32_t src; + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); + else src = color; + auto ialpha = IA(src); + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = src + ALPHA_BLEND(*dst, ialpha); + } + } + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + uint8_t src; + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + if (span->coverage < 255) src = MULTIPLY(span->coverage, a); + else src = a; + auto ialpha = ~a; + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = src + MULTIPLY(*dst, ialpha); + } + } + } + return true; +} + + +static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + + //32bits channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + auto ialpha = 255 - a; + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + for (uint32_t x = 0; x < w; ++x, ++dst) { + *dst = color + ALPHA_BLEND(*dst, ialpha); + } + } + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; + auto ialpha = ~a; + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + for (uint32_t x = 0; x < w; ++x, ++dst) { + *dst = a + MULTIPLY(*dst, ialpha); + } + } + } + return true; +} + + +static bool inline cRasterABGRtoARGB(Surface* surface) +{ + TVGLOG("SW_ENGINE", "Convert ColorSpace ABGR - ARGB [Size: %d x %d]", surface->w, surface->h); + + //64bits faster converting + if (surface->w % 2 == 0) { + auto buffer = reinterpret_cast(surface->buf32); + for (uint32_t y = 0; y < surface->h; ++y, buffer += surface->stride / 2) { + auto dst = buffer; + for (uint32_t x = 0; x < surface->w / 2; ++x, ++dst) { + auto c = *dst; + //flip Blue, Red channels + *dst = (c & 0xff000000ff000000) + ((c & 0x00ff000000ff0000) >> 16) + (c & 0x0000ff000000ff00) + ((c & 0x000000ff000000ff) << 16); + } + } + //default converting + } else { + auto buffer = surface->buf32; + for (uint32_t y = 0; y < surface->h; ++y, buffer += surface->stride) { + auto dst = buffer; + for (uint32_t x = 0; x < surface->w; ++x, ++dst) { + auto c = *dst; + //flip Blue, Red channels + *dst = (c & 0xff000000) + ((c & 0x00ff0000) >> 16) + (c & 0x0000ff00) + ((c & 0x000000ff) << 16); + } + } + } + return true; +} + + +static bool inline cRasterARGBtoABGR(Surface* surface) +{ + //exactly same with ABGRtoARGB + return cRasterABGRtoARGB(surface); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwRasterNeon.h b/test/include/liblvgl/libs/thorvg/tvgSwRasterNeon.h new file mode 100644 index 00000000..a84bfe87 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwRasterNeon.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifdef THORVG_NEON_VECTOR_SUPPORT + +#include + +//TODO : need to support windows ARM + +#if defined(__ARM_64BIT_STATE) || defined(_M_ARM64) +#define TVG_AARCH64 1 +#else +#define TVG_AARCH64 0 +#endif + + +static inline uint8x8_t ALPHA_BLEND(uint8x8_t c, uint8x8_t a) +{ + uint16x8_t t = vmull_u8(c, a); + return vshrn_n_u16(t, 8); +} + + +static void neonRasterGrayscale8(uint8_t* dst, uint8_t val, uint32_t offset, int32_t len) +{ + dst += offset; + + int32_t i = 0; + const uint8x16_t valVec = vdupq_n_u8(val); +#if TVG_AARCH64 + uint8x16x4_t valQuad = {valVec, valVec, valVec, valVec}; + for (; i <= len - 16 * 4; i += 16 * 4) { + vst1q_u8_x4(dst + i, valQuad); + } +#else + for (; i <= len - 16; i += 16) { + vst1q_u8(dst + i, valVec); + } +#endif + for (; i < len; i++) { + dst[i] = val; + } +} + + +static void neonRasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) +{ + dst += offset; + + uint32x4_t vectorVal = vdupq_n_u32(val); + +#if TVG_AARCH64 + uint32_t iterations = len / 16; + uint32_t neonFilled = iterations * 16; + uint32x4x4_t valQuad = {vectorVal, vectorVal, vectorVal, vectorVal}; + for (uint32_t i = 0; i < iterations; ++i) { + vst4q_u32(dst, valQuad); + dst += 16; + } +#else + uint32_t iterations = len / 4; + uint32_t neonFilled = iterations * 4; + for (uint32_t i = 0; i < iterations; ++i) { + vst1q_u32(dst, vectorVal); + dst += 4; + } +#endif + int32_t leftovers = len - neonFilled; + while (leftovers--) *dst++ = val; +} + + +static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (surface->channelSize != sizeof(uint32_t)) { + TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); + return false; + } + + auto color = surface->join(r, g, b, a); + auto span = rle->spans; + uint32_t src; + uint8x8_t *vDst = nullptr; + uint16_t align; + + for (uint32_t i = 0; i < rle->size; ++i) { + if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); + else src = color; + + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto ialpha = IA(src); + + if ((((uintptr_t) dst) & 0x7) != 0) { + //fill not aligned byte + *dst = src + ALPHA_BLEND(*dst, ialpha); + vDst = (uint8x8_t*)(dst + 1); + align = 1; + } else { + vDst = (uint8x8_t*) dst; + align = 0; + } + + uint8x8_t vSrc = (uint8x8_t) vdup_n_u32(src); + uint8x8_t vIalpha = vdup_n_u8((uint8_t) ialpha); + + for (uint32_t x = 0; x < (span->len - align) / 2; ++x) + vDst[x] = vadd_u8(vSrc, ALPHA_BLEND(vDst[x], vIalpha)); + + auto leftovers = (span->len - align) % 2; + if (leftovers > 0) dst[span->len - 1] = src + ALPHA_BLEND(dst[span->len - 1], ialpha); + + ++span; + } + return true; +} + + +static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (surface->channelSize != sizeof(uint32_t)) { + TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); + return false; + } + + auto color = surface->join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + auto ialpha = 255 - a; + + auto vColor = vdup_n_u32(color); + auto vIalpha = vdup_n_u8((uint8_t) ialpha); + + uint8x8_t* vDst = nullptr; + uint32_t align; + + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + + if ((((uintptr_t) dst) & 0x7) != 0) { + //fill not aligned byte + *dst = color + ALPHA_BLEND(*dst, ialpha); + vDst = (uint8x8_t*) (dst + 1); + align = 1; + } else { + vDst = (uint8x8_t*) dst; + align = 0; + } + + for (uint32_t x = 0; x < (w - align) / 2; ++x) + vDst[x] = vadd_u8((uint8x8_t)vColor, ALPHA_BLEND(vDst[x], vIalpha)); + + auto leftovers = (w - align) % 2; + if (leftovers > 0) dst[w - 1] = color + ALPHA_BLEND(dst[w - 1], ialpha); + } + return true; +} + +#endif + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwRasterTexmap.h b/test/include/liblvgl/libs/thorvg/tvgSwRasterTexmap.h new file mode 100644 index 00000000..6ef2e320 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwRasterTexmap.h @@ -0,0 +1,1214 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +struct AALine +{ + int32_t x[2]; + int32_t coverage[2]; + int32_t length[2]; +}; + +struct AASpans +{ + AALine *lines; + int32_t yStart; + int32_t yEnd; +}; + +static inline void _swap(float& a, float& b, float& tmp) +{ + tmp = a; + a = b; + b = tmp; +} + + +//Careful! Shared resource, No support threading +static float dudx, dvdx; +static float dxdya, dxdyb, dudya, dvdya; +static float xa, xb, ua, va; + + +//Y Range exception handling +static bool _arrange(const SwImage* image, const SwBBox* region, int& yStart, int& yEnd) +{ + int32_t regionTop, regionBottom; + + if (region) { + regionTop = region->min.y; + regionBottom = region->max.y; + } else { + regionTop = image->rle->spans->y; + regionBottom = image->rle->spans[image->rle->size - 1].y; + } + + if (yStart >= regionBottom) return false; + + if (yStart < regionTop) yStart = regionTop; + if (yEnd > regionBottom) yEnd = regionBottom; + + return true; +} + + +static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity, uint8_t dirFlag = 0) +{ + return false; + +#if 0 //Enable it when GRAYSCALE image is supported + auto maskOp = _getMaskOp(surface->compositor->method); + auto direct = _direct(surface->compositor->method); + float _dudx = dudx, _dvdx = dvdx; + float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya; + float _xa = xa, _xb = xb, _ua = ua, _va = va; + auto sbuf = image->buf8; + int32_t sw = static_cast(image->stride); + int32_t sh = image->h; + int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay; + int32_t vv = 0, uu = 0; + int32_t minx = INT32_MAX, maxx = 0; + float dx, u, v, iptr; + SwSpan* span = nullptr; //used only when rle based. + + if (!_arrange(image, region, yStart, yEnd)) return false; + + //Loop through all lines in the segment + uint32_t spanIdx = 0; + + if (region) { + minx = region->min.x; + maxx = region->max.x; + } else { + span = image->rle->spans; + while (span->y < yStart) { + ++span; + ++spanIdx; + } + } + + y = yStart; + + while (y < yEnd) { + x1 = (int32_t)_xa; + x2 = (int32_t)_xb; + + if (!region) { + minx = INT32_MAX; + maxx = 0; + //one single row, could be consisted of multiple spans. + while (span->y == y && spanIdx < image->rle->size) { + if (minx > span->x) minx = span->x; + if (maxx < span->x + span->len) maxx = span->x + span->len; + ++span; + ++spanIdx; + } + } + if (x1 < minx) x1 = minx; + if (x2 > maxx) x2 = maxx; + + //Anti-Aliasing frames + ay = y - aaSpans->yStart; + if (aaSpans->lines[ay].x[0] > x1) aaSpans->lines[ay].x[0] = x1; + if (aaSpans->lines[ay].x[1] < x2) aaSpans->lines[ay].x[1] = x2; + + //Range allowed + if ((x2 - x1) >= 1 && (x1 < maxx) && (x2 > minx)) { + + //Perform subtexel pre-stepping on UV + dx = 1 - (_xa - x1); + u = _ua + dx * _dudx; + v = _va + dx * _dvdx; + + x = x1; + + auto cmp = &surface->compositor->image.buf8[y * surface->compositor->image.stride + x1]; + auto dst = &surface->buf8[y * surface->stride + x1]; + + if (opacity == 255) { + //Draw horizontal line + while (x++ < x2) { + uu = (int) u; + if (uu >= sw) continue; + vv = (int) v; + if (vv >= sh) continue; + + ar = (int)(255 * (1 - modff(u, &iptr))); + ab = (int)(255 * (1 - modff(v, &iptr))); + iru = uu + 1; + irv = vv + 1; + + px = *(sbuf + (vv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* right pixel */ + int px2 = *(sbuf + (vv * sw) + iru); + px = INTERPOLATE(px, px2, ar); + } + /* vertical interpolate */ + if (irv < sh) { + /* bottom pixel */ + int px2 = *(sbuf + (irv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* bottom right pixel */ + int px3 = *(sbuf + (irv * sw) + iru); + px2 = INTERPOLATE(px2, px3, ar); + } + px = INTERPOLATE(px, px2, ab); + } + if (direct) { + auto tmp = maskOp(px, *cmp, 0); //not use alpha + *dst = tmp + MULTIPLY(*dst, ~tmp); + ++dst; + } else { + *cmp = maskOp(px, *cmp, ~px); + } + ++cmp; + + //Step UV horizontally + u += _dudx; + v += _dvdx; + //range over? + if ((uint32_t)v >= image->h) break; + } + } else { + //Draw horizontal line + while (x++ < x2) { + uu = (int) u; + if (uu >= sw) continue; + vv = (int) v; + if (vv >= sh) continue; + + ar = (int)(255 * (1 - modff(u, &iptr))); + ab = (int)(255 * (1 - modff(v, &iptr))); + iru = uu + 1; + irv = vv + 1; + + px = *(sbuf + (vv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* right pixel */ + int px2 = *(sbuf + (vv * sw) + iru); + px = INTERPOLATE(px, px2, ar); + } + /* vertical interpolate */ + if (irv < sh) { + /* bottom pixel */ + int px2 = *(sbuf + (irv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* bottom right pixel */ + int px3 = *(sbuf + (irv * sw) + iru); + px2 = INTERPOLATE(px2, px3, ar); + } + px = INTERPOLATE(px, px2, ab); + } + + if (direct) { + auto tmp = maskOp(MULTIPLY(px, opacity), *cmp, 0); + *dst = tmp + MULTIPLY(*dst, ~tmp); + ++dst; + } else { + auto tmp = MULTIPLY(px, opacity); + *cmp = maskOp(tmp, *cmp, ~px); + } + ++cmp; + + //Step UV horizontally + u += _dudx; + v += _dvdx; + //range over? + if ((uint32_t)v >= image->h) break; + } + } + } + + //Step along both edges + _xa += _dxdya; + _xb += _dxdyb; + _ua += _dudya; + _va += _dvdya; + + if (!region && spanIdx >= image->rle->size) break; + + ++y; + } + xa = _xa; + xb = _xb; + ua = _ua; + va = _va; + + return true; +#endif +} + + +static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity) +{ + float _dudx = dudx, _dvdx = dvdx; + float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya; + float _xa = xa, _xb = xb, _ua = ua, _va = va; + auto sbuf = image->buf32; + auto dbuf = surface->buf32; + int32_t sw = static_cast(image->stride); + int32_t sh = image->h; + int32_t dw = surface->stride; + int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay; + int32_t vv = 0, uu = 0; + int32_t minx = INT32_MAX, maxx = 0; + float dx, u, v, iptr; + uint32_t* buf; + SwSpan* span = nullptr; //used only when rle based. + + if (!_arrange(image, region, yStart, yEnd)) return; + + //Loop through all lines in the segment + uint32_t spanIdx = 0; + + if (region) { + minx = region->min.x; + maxx = region->max.x; + } else { + span = image->rle->spans; + while (span->y < yStart) { + ++span; + ++spanIdx; + } + } + + y = yStart; + + while (y < yEnd) { + x1 = (int32_t)_xa; + x2 = (int32_t)_xb; + + if (!region) { + minx = INT32_MAX; + maxx = 0; + //one single row, could be consisted of multiple spans. + while (span->y == y && spanIdx < image->rle->size) { + if (minx > span->x) minx = span->x; + if (maxx < span->x + span->len) maxx = span->x + span->len; + ++span; + ++spanIdx; + } + } + if (x1 < minx) x1 = minx; + if (x2 > maxx) x2 = maxx; + + //Anti-Aliasing frames + ay = y - aaSpans->yStart; + if (aaSpans->lines[ay].x[0] > x1) aaSpans->lines[ay].x[0] = x1; + if (aaSpans->lines[ay].x[1] < x2) aaSpans->lines[ay].x[1] = x2; + + //Range allowed + if ((x2 - x1) >= 1 && (x1 < maxx) && (x2 > minx)) { + + //Perform subtexel pre-stepping on UV + dx = 1 - (_xa - x1); + u = _ua + dx * _dudx; + v = _va + dx * _dvdx; + + buf = dbuf + ((y * dw) + x1); + + x = x1; + + if (opacity == 255) { + //Draw horizontal line + while (x++ < x2) { + uu = (int) u; + if (uu >= sw) continue; + vv = (int) v; + if (vv >= sh) continue; + + ar = (int)(255 * (1 - modff(u, &iptr))); + ab = (int)(255 * (1 - modff(v, &iptr))); + iru = uu + 1; + irv = vv + 1; + + px = *(sbuf + (vv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* right pixel */ + int px2 = *(sbuf + (vv * sw) + iru); + px = INTERPOLATE(px, px2, ar); + } + /* vertical interpolate */ + if (irv < sh) { + /* bottom pixel */ + int px2 = *(sbuf + (irv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* bottom right pixel */ + int px3 = *(sbuf + (irv * sw) + iru); + px2 = INTERPOLATE(px2, px3, ar); + } + px = INTERPOLATE(px, px2, ab); + } + *buf = surface->blender(px, *buf, IA(px)); + ++buf; + + //Step UV horizontally + u += _dudx; + v += _dvdx; + //range over? + if ((uint32_t)v >= image->h) break; + } + } else { + //Draw horizontal line + while (x++ < x2) { + uu = (int) u; + if (uu >= sw) continue; + vv = (int) v; + if (vv >= sh) continue; + + ar = (int)(255 * (1 - modff(u, &iptr))); + ab = (int)(255 * (1 - modff(v, &iptr))); + iru = uu + 1; + irv = vv + 1; + + px = *(sbuf + (vv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* right pixel */ + int px2 = *(sbuf + (vv * sw) + iru); + px = INTERPOLATE(px, px2, ar); + } + /* vertical interpolate */ + if (irv < sh) { + /* bottom pixel */ + int px2 = *(sbuf + (irv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* bottom right pixel */ + int px3 = *(sbuf + (irv * sw) + iru); + px2 = INTERPOLATE(px2, px3, ar); + } + px = INTERPOLATE(px, px2, ab); + } + auto src = ALPHA_BLEND(px, opacity); + *buf = surface->blender(src, *buf, IA(src)); + ++buf; + + //Step UV horizontally + u += _dudx; + v += _dvdx; + //range over? + if ((uint32_t)v >= image->h) break; + } + } + } + + //Step along both edges + _xa += _dxdya; + _xb += _dxdyb; + _ua += _dudya; + _va += _dvdya; + + if (!region && spanIdx >= image->rle->size) break; + + ++y; + } + xa = _xa; + xb = _xb; + ua = _ua; + va = _va; +} + + +static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity, bool matting) +{ + float _dudx = dudx, _dvdx = dvdx; + float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya; + float _xa = xa, _xb = xb, _ua = ua, _va = va; + auto sbuf = image->buf32; + auto dbuf = surface->buf32; + int32_t sw = static_cast(image->stride); + int32_t sh = image->h; + int32_t dw = surface->stride; + int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay; + int32_t vv = 0, uu = 0; + int32_t minx = INT32_MAX, maxx = 0; + float dx, u, v, iptr; + uint32_t* buf; + SwSpan* span = nullptr; //used only when rle based. + + //for matting(composition) + auto csize = matting ? surface->compositor->image.channelSize: 0; + auto alpha = matting ? surface->alpha(surface->compositor->method) : nullptr; + uint8_t* cmp = nullptr; + + if (!_arrange(image, region, yStart, yEnd)) return; + + //Loop through all lines in the segment + uint32_t spanIdx = 0; + + if (region) { + minx = region->min.x; + maxx = region->max.x; + } else { + span = image->rle->spans; + while (span->y < yStart) { + ++span; + ++spanIdx; + } + } + + y = yStart; + + while (y < yEnd) { + x1 = (int32_t)_xa; + x2 = (int32_t)_xb; + + if (!region) { + minx = INT32_MAX; + maxx = 0; + //one single row, could be consisted of multiple spans. + while (span->y == y && spanIdx < image->rle->size) { + if (minx > span->x) minx = span->x; + if (maxx < span->x + span->len) maxx = span->x + span->len; + ++span; + ++spanIdx; + } + } + if (x1 < minx) x1 = minx; + if (x2 > maxx) x2 = maxx; + + //Anti-Aliasing frames + ay = y - aaSpans->yStart; + if (aaSpans->lines[ay].x[0] > x1) aaSpans->lines[ay].x[0] = x1; + if (aaSpans->lines[ay].x[1] < x2) aaSpans->lines[ay].x[1] = x2; + + //Range allowed + if ((x2 - x1) >= 1 && (x1 < maxx) && (x2 > minx)) { + + //Perform subtexel pre-stepping on UV + dx = 1 - (_xa - x1); + u = _ua + dx * _dudx; + v = _va + dx * _dvdx; + + buf = dbuf + ((y * dw) + x1); + + x = x1; + + if (matting) cmp = &surface->compositor->image.buf8[(y * surface->compositor->image.stride + x1) * csize]; + + if (opacity == 255) { + //Draw horizontal line + while (x++ < x2) { + uu = (int) u; + if (uu >= sw) continue; + vv = (int) v; + if (vv >= sh) continue; + + ar = (int)(255.0f * (1.0f - modff(u, &iptr))); + ab = (int)(255.0f * (1.0f - modff(v, &iptr))); + iru = uu + 1; + irv = vv + 1; + + px = *(sbuf + (vv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* right pixel */ + int px2 = *(sbuf + (vv * sw) + iru); + px = INTERPOLATE(px, px2, ar); + } + /* vertical interpolate */ + if (irv < sh) { + /* bottom pixel */ + int px2 = *(sbuf + (irv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* bottom right pixel */ + int px3 = *(sbuf + (irv * sw) + iru); + px2 = INTERPOLATE(px2, px3, ar); + } + px = INTERPOLATE(px, px2, ab); + } + uint32_t src; + if (matting) { + src = ALPHA_BLEND(px, alpha(cmp)); + cmp += csize; + } else { + src = px; + } + *buf = src + ALPHA_BLEND(*buf, IA(src)); + ++buf; + + //Step UV horizontally + u += _dudx; + v += _dvdx; + //range over? + if ((uint32_t)v >= image->h) break; + } + } else { + //Draw horizontal line + while (x++ < x2) { + uu = (int) u; + vv = (int) v; + + ar = (int)(255.0f * (1.0f - modff(u, &iptr))); + ab = (int)(255.0f * (1.0f - modff(v, &iptr))); + iru = uu + 1; + irv = vv + 1; + + if (vv >= sh) continue; + + px = *(sbuf + (vv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* right pixel */ + int px2 = *(sbuf + (vv * sw) + iru); + px = INTERPOLATE(px, px2, ar); + } + /* vertical interpolate */ + if (irv < sh) { + /* bottom pixel */ + int px2 = *(sbuf + (irv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* bottom right pixel */ + int px3 = *(sbuf + (irv * sw) + iru); + px2 = INTERPOLATE(px2, px3, ar); + } + px = INTERPOLATE(px, px2, ab); + } + uint32_t src; + if (matting) { + src = ALPHA_BLEND(px, MULTIPLY(opacity, alpha(cmp))); + cmp += csize; + } else { + src = ALPHA_BLEND(px, opacity); + } + *buf = src + ALPHA_BLEND(*buf, IA(src)); + ++buf; + + //Step UV horizontally + u += _dudx; + v += _dvdx; + //range over? + if ((uint32_t)v >= image->h) break; + } + } + } + + //Step along both edges + _xa += _dxdya; + _xb += _dxdyb; + _ua += _dudya; + _va += _dvdya; + + if (!region && spanIdx >= image->rle->size) break; + + ++y; + } + xa = _xa; + xb = _xb; + ua = _ua; + va = _va; +} + + +/* This mapping algorithm is based on Mikael Kalms's. */ +static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const SwBBox* region, Polygon& polygon, AASpans* aaSpans, uint8_t opacity) +{ + float x[3] = {polygon.vertex[0].pt.x, polygon.vertex[1].pt.x, polygon.vertex[2].pt.x}; + float y[3] = {polygon.vertex[0].pt.y, polygon.vertex[1].pt.y, polygon.vertex[2].pt.y}; + float u[3] = {polygon.vertex[0].uv.x, polygon.vertex[1].uv.x, polygon.vertex[2].uv.x}; + float v[3] = {polygon.vertex[0].uv.y, polygon.vertex[1].uv.y, polygon.vertex[2].uv.y}; + + float off_y; + float dxdy[3] = {0.0f, 0.0f, 0.0f}; + float tmp; + + auto upper = false; + + //Sort the vertices in ascending Y order + if (y[0] > y[1]) { + _swap(x[0], x[1], tmp); + _swap(y[0], y[1], tmp); + _swap(u[0], u[1], tmp); + _swap(v[0], v[1], tmp); + } + if (y[0] > y[2]) { + _swap(x[0], x[2], tmp); + _swap(y[0], y[2], tmp); + _swap(u[0], u[2], tmp); + _swap(v[0], v[2], tmp); + } + if (y[1] > y[2]) { + _swap(x[1], x[2], tmp); + _swap(y[1], y[2], tmp); + _swap(u[1], u[2], tmp); + _swap(v[1], v[2], tmp); + } + + //Y indexes + int yi[3] = {(int)y[0], (int)y[1], (int)y[2]}; + + //Skip drawing if it's too thin to cover any pixels at all. + if ((yi[0] == yi[1] && yi[0] == yi[2]) || ((int) x[0] == (int) x[1] && (int) x[0] == (int) x[2])) return; + + //Calculate horizontal and vertical increments for UV axes (these calcs are certainly not optimal, although they're stable (handles any dy being 0) + auto denom = ((x[2] - x[0]) * (y[1] - y[0]) - (x[1] - x[0]) * (y[2] - y[0])); + + //Skip poly if it's an infinitely thin line + if (mathZero(denom)) return; + + denom = 1 / denom; //Reciprocal for speeding up + dudx = ((u[2] - u[0]) * (y[1] - y[0]) - (u[1] - u[0]) * (y[2] - y[0])) * denom; + dvdx = ((v[2] - v[0]) * (y[1] - y[0]) - (v[1] - v[0]) * (y[2] - y[0])) * denom; + auto dudy = ((u[1] - u[0]) * (x[2] - x[0]) - (u[2] - u[0]) * (x[1] - x[0])) * denom; + auto dvdy = ((v[1] - v[0]) * (x[2] - x[0]) - (v[2] - v[0]) * (x[1] - x[0])) * denom; + + //Calculate X-slopes along the edges + if (y[1] > y[0]) dxdy[0] = (x[1] - x[0]) / (y[1] - y[0]); + if (y[2] > y[0]) dxdy[1] = (x[2] - x[0]) / (y[2] - y[0]); + if (y[2] > y[1]) dxdy[2] = (x[2] - x[1]) / (y[2] - y[1]); + + //Determine which side of the polygon the longer edge is on + auto side = (dxdy[1] > dxdy[0]) ? true : false; + + if (mathEqual(y[0], y[1])) side = x[0] > x[1]; + if (mathEqual(y[1], y[2])) side = x[2] > x[1]; + + auto regionTop = region ? region->min.y : image->rle->spans->y; //Normal Image or Rle Image? + auto compositing = _compositing(surface); //Composition required + auto blending = _blending(surface); //Blending required + + //Longer edge is on the left side + if (!side) { + //Calculate slopes along left edge + dxdya = dxdy[1]; + dudya = dxdya * dudx + dudy; + dvdya = dxdya * dvdx + dvdy; + + //Perform subpixel pre-stepping along left edge + auto dy = 1.0f - (y[0] - yi[0]); + xa = x[0] + dy * dxdya; + ua = u[0] + dy * dudya; + va = v[0] + dy * dvdya; + + //Draw upper segment if possibly visible + if (yi[0] < yi[1]) { + off_y = y[0] < regionTop ? (regionTop - y[0]) : 0; + xa += (off_y * dxdya); + ua += (off_y * dudya); + va += (off_y * dvdya); + + // Set right edge X-slope and perform subpixel pre-stepping + dxdyb = dxdy[0]; + xb = x[0] + dy * dxdyb + (off_y * dxdyb); + + if (compositing) { + if (_matting(surface)) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans, opacity, true); + else _rasterMaskedPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans, opacity, 1); + } else if (blending) { + _rasterBlendingPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans, opacity); + } else { + _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans, opacity, false); + } + upper = true; + } + //Draw lower segment if possibly visible + if (yi[1] < yi[2]) { + off_y = y[1] < regionTop ? (regionTop - y[1]) : 0; + if (!upper) { + xa += (off_y * dxdya); + ua += (off_y * dudya); + va += (off_y * dvdya); + } + // Set right edge X-slope and perform subpixel pre-stepping + dxdyb = dxdy[2]; + xb = x[1] + (1 - (y[1] - yi[1])) * dxdyb + (off_y * dxdyb); + if (compositing) { + if (_matting(surface)) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans, opacity, true); + else _rasterMaskedPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans, opacity, 2); + } else if (blending) { + _rasterBlendingPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans, opacity); + } else { + _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans, opacity, false); + } + } + //Longer edge is on the right side + } else { + //Set right edge X-slope and perform subpixel pre-stepping + dxdyb = dxdy[1]; + auto dy = 1.0f - (y[0] - yi[0]); + xb = x[0] + dy * dxdyb; + + //Draw upper segment if possibly visible + if (yi[0] < yi[1]) { + off_y = y[0] < regionTop ? (regionTop - y[0]) : 0; + xb += (off_y *dxdyb); + + // Set slopes along left edge and perform subpixel pre-stepping + dxdya = dxdy[0]; + dudya = dxdya * dudx + dudy; + dvdya = dxdya * dvdx + dvdy; + + xa = x[0] + dy * dxdya + (off_y * dxdya); + ua = u[0] + dy * dudya + (off_y * dudya); + va = v[0] + dy * dvdya + (off_y * dvdya); + + if (compositing) { + if (_matting(surface)) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans, opacity, true); + else _rasterMaskedPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans, opacity, 3); + } else if (blending) { + _rasterBlendingPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans, opacity); + } else { + _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans, opacity, false); + } + upper = true; + } + //Draw lower segment if possibly visible + if (yi[1] < yi[2]) { + off_y = y[1] < regionTop ? (regionTop - y[1]) : 0; + if (!upper) xb += (off_y *dxdyb); + + // Set slopes along left edge and perform subpixel pre-stepping + dxdya = dxdy[2]; + dudya = dxdya * dudx + dudy; + dvdya = dxdya * dvdx + dvdy; + dy = 1 - (y[1] - yi[1]); + xa = x[1] + dy * dxdya + (off_y * dxdya); + ua = u[1] + dy * dudya + (off_y * dudya); + va = v[1] + dy * dvdya + (off_y * dvdya); + + if (compositing) { + if (_matting(surface)) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans, opacity, true); + else _rasterMaskedPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans, opacity, 4); + } else if (blending) { + _rasterBlendingPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans, opacity); + } else { + _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans, opacity, false); + } + } + } +} + + +static AASpans* _AASpans(float ymin, float ymax, const SwImage* image, const SwBBox* region) +{ + auto yStart = static_cast(ymin); + auto yEnd = static_cast(ymax); + + if (!_arrange(image, region, yStart, yEnd)) return nullptr; + + auto aaSpans = static_cast(malloc(sizeof(AASpans))); + aaSpans->yStart = yStart; + aaSpans->yEnd = yEnd; + + //Initialize X range + auto height = yEnd - yStart; + + aaSpans->lines = static_cast(malloc(height * sizeof(AALine))); + + for (int32_t i = 0; i < height; i++) { + aaSpans->lines[i].x[0] = INT32_MAX; + aaSpans->lines[i].x[1] = 0; + aaSpans->lines[i].length[0] = 0; + aaSpans->lines[i].length[1] = 0; + } + return aaSpans; +} + + +static void _calcIrregularCoverage(AALine* lines, int32_t eidx, int32_t y, int32_t diagonal, int32_t edgeDist, bool reverse) +{ + if (eidx == 1) reverse = !reverse; + int32_t coverage = (255 / (diagonal + 2)); + int32_t tmp; + for (int32_t ry = 0; ry < (diagonal + 2); ry++) { + tmp = y - ry - edgeDist; + if (tmp < 0) return; + lines[tmp].length[eidx] = 1; + if (reverse) lines[tmp].coverage[eidx] = 255 - (coverage * ry); + else lines[tmp].coverage[eidx] = (coverage * ry); + } +} + + +static void _calcVertCoverage(AALine *lines, int32_t eidx, int32_t y, int32_t rewind, bool reverse) +{ + if (eidx == 1) reverse = !reverse; + int32_t coverage = (255 / (rewind + 1)); + int32_t tmp; + for (int ry = 1; ry < (rewind + 1); ry++) { + tmp = y - ry; + if (tmp < 0) return; + lines[tmp].length[eidx] = 1; + if (reverse) lines[tmp].coverage[eidx] = (255 - (coverage * ry)); + else lines[tmp].coverage[eidx] = (coverage * ry); + } +} + + +static void _calcHorizCoverage(AALine *lines, int32_t eidx, int32_t y, int32_t x, int32_t x2) +{ + if (lines[y].length[eidx] < abs(x - x2)) { + lines[y].length[eidx] = abs(x - x2); + lines[y].coverage[eidx] = (255 / (lines[y].length[eidx] + 1)); + } +} + + +/* + * This Anti-Aliasing mechanism is originated from Hermet Park's idea. + * To understand this AA logic, you can refer this page: + * www.hermet.pe.kr/122 (hermetpark@gmail.com) +*/ +static void _calcAAEdge(AASpans *aaSpans, int32_t eidx) +{ +//Previous edge direction: +#define DirOutHor 0x0011 +#define DirOutVer 0x0001 +#define DirInHor 0x0010 +#define DirInVer 0x0000 +#define DirNone 0x1000 + +#define PUSH_VERTEX() \ + do { \ + pEdge.x = lines[y].x[eidx]; \ + pEdge.y = y; \ + ptx[0] = tx[0]; \ + ptx[1] = tx[1]; \ + } while (0) + + int32_t y = 0; + SwPoint pEdge = {-1, -1}; //previous edge point + SwPoint edgeDiff = {0, 0}; //temporary used for point distance + + /* store bigger to tx[0] between prev and current edge's x positions. */ + int32_t tx[2] = {0, 0}; + /* back up prev tx values */ + int32_t ptx[2] = {0, 0}; + int32_t diagonal = 0; //straight diagonal pixels count + + auto yStart = aaSpans->yStart; + auto yEnd = aaSpans->yEnd; + auto lines = aaSpans->lines; + + int32_t prevDir = DirNone; + int32_t curDir = DirNone; + + yEnd -= yStart; + + //Start Edge + if (y < yEnd) { + pEdge.x = lines[y].x[eidx]; + pEdge.y = y; + } + + //Calculates AA Edges + for (y++; y < yEnd; y++) { + //Ready tx + if (eidx == 0) { + tx[0] = pEdge.x; + tx[1] = lines[y].x[0]; + } else { + tx[0] = lines[y].x[1]; + tx[1] = pEdge.x; + } + edgeDiff.x = (tx[0] - tx[1]); + edgeDiff.y = (y - pEdge.y); + + //Confirm current edge direction + if (edgeDiff.x > 0) { + if (edgeDiff.y == 1) curDir = DirOutHor; + else curDir = DirOutVer; + } else if (edgeDiff.x < 0) { + if (edgeDiff.y == 1) curDir = DirInHor; + else curDir = DirInVer; + } else curDir = DirNone; + + //straight diagonal increase + if ((curDir == prevDir) && (y < yEnd)) { + if ((abs(edgeDiff.x) == 1) && (edgeDiff.y == 1)) { + ++diagonal; + PUSH_VERTEX(); + continue; + } + } + + switch (curDir) { + case DirOutHor: { + _calcHorizCoverage(lines, eidx, y, tx[0], tx[1]); + if (diagonal > 0) { + _calcIrregularCoverage(lines, eidx, y, diagonal, 0, true); + diagonal = 0; + } + /* Increment direction is changed: Outside Vertical -> Outside Horizontal */ + if (prevDir == DirOutVer) _calcHorizCoverage(lines, eidx, pEdge.y, ptx[0], ptx[1]); + + //Trick, but fine-tunning! + if (y == 1) _calcHorizCoverage(lines, eidx, pEdge.y, tx[0], tx[1]); + PUSH_VERTEX(); + } + break; + case DirOutVer: { + _calcVertCoverage(lines, eidx, y, edgeDiff.y, true); + if (diagonal > 0) { + _calcIrregularCoverage(lines, eidx, y, diagonal, edgeDiff.y, false); + diagonal = 0; + } + /* Increment direction is changed: Outside Horizontal -> Outside Vertical */ + if (prevDir == DirOutHor) _calcHorizCoverage(lines, eidx, pEdge.y, ptx[0], ptx[1]); + PUSH_VERTEX(); + } + break; + case DirInHor: { + _calcHorizCoverage(lines, eidx, (y - 1), tx[0], tx[1]); + if (diagonal > 0) { + _calcIrregularCoverage(lines, eidx, y, diagonal, 0, false); + diagonal = 0; + } + /* Increment direction is changed: Outside Horizontal -> Inside Horizontal */ + if (prevDir == DirOutHor) _calcHorizCoverage(lines, eidx, pEdge.y, ptx[0], ptx[1]); + PUSH_VERTEX(); + } + break; + case DirInVer: { + _calcVertCoverage(lines, eidx, y, edgeDiff.y, false); + if (prevDir == DirOutHor) edgeDiff.y -= 1; //Weird, fine tuning????????????????????? + if (diagonal > 0) { + _calcIrregularCoverage(lines, eidx, y, diagonal, edgeDiff.y, true); + diagonal = 0; + } + /* Increment direction is changed: Outside Horizontal -> Inside Vertical */ + if (prevDir == DirOutHor) _calcHorizCoverage(lines, eidx, pEdge.y, ptx[0], ptx[1]); + PUSH_VERTEX(); + } + break; + } + if (curDir != DirNone) prevDir = curDir; + } + + //leftovers...? + if ((edgeDiff.y == 1) && (edgeDiff.x != 0)) { + if (y >= yEnd) y = (yEnd - 1); + _calcHorizCoverage(lines, eidx, y - 1, ptx[0], ptx[1]); + _calcHorizCoverage(lines, eidx, y, tx[0], tx[1]); + } else { + ++y; + if (y > yEnd) y = yEnd; + _calcVertCoverage(lines, eidx, y, (edgeDiff.y + 1), (prevDir & 0x00000001)); + } +} + + +static bool _apply(SwSurface* surface, AASpans* aaSpans) +{ + auto y = aaSpans->yStart; + uint32_t pixel; + uint32_t* dst; + int32_t pos; + + //left side + _calcAAEdge(aaSpans, 0); + //right side + _calcAAEdge(aaSpans, 1); + + while (y < aaSpans->yEnd) { + auto line = &aaSpans->lines[y - aaSpans->yStart]; + auto width = line->x[1] - line->x[0]; + if (width > 0) { + auto offset = y * surface->stride; + + //Left edge + dst = surface->buf32 + (offset + line->x[0]); + if (line->x[0] > 1) pixel = *(dst - 1); + else pixel = *dst; + + pos = 1; + while (pos <= line->length[0]) { + *dst = INTERPOLATE(*dst, pixel, line->coverage[0] * pos); + ++dst; + ++pos; + } + + //Right edge + dst = surface->buf32 + (offset + line->x[1] - 1); + if (line->x[1] < (int32_t)(surface->w - 1)) pixel = *(dst + 1); + else pixel = *dst; + + pos = width; + while ((int32_t)(width - line->length[1]) < pos) { + *dst = INTERPOLATE(*dst, pixel, 255 - (line->coverage[1] * (line->length[1] - (width - pos)))); + --dst; + --pos; + } + } + y++; + } + + free(aaSpans->lines); + free(aaSpans); + + return true; +} + + +/* + 2 triangles constructs 1 mesh. + below figure illustrates vert[4] index info. + If you need better quality, please divide a mesh by more number of triangles. + + 0 -- 1 + | / | + | / | + 3 -- 2 +*/ +static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox* region, uint8_t opacity) +{ + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon!"); + return false; + } + + //Exceptions: No dedicated drawing area? + if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false; + + /* Prepare vertices. + shift XY coordinates to match the sub-pixeling technique. */ + Vertex vertices[4]; + vertices[0] = {{0.0f, 0.0f}, {0.0f, 0.0f}}; + vertices[1] = {{float(image->w), 0.0f}, {float(image->w), 0.0f}}; + vertices[2] = {{float(image->w), float(image->h)}, {float(image->w), float(image->h)}}; + vertices[3] = {{0.0f, float(image->h)}, {0.0f, float(image->h)}}; + + float ys = FLT_MAX, ye = -1.0f; + for (int i = 0; i < 4; i++) { + if (transform) mathMultiply(&vertices[i].pt, transform); + if (vertices[i].pt.y < ys) ys = vertices[i].pt.y; + if (vertices[i].pt.y > ye) ye = vertices[i].pt.y; + } + + auto aaSpans = _AASpans(ys, ye, image, region); + if (!aaSpans) return true; + + Polygon polygon; + + //Draw the first polygon + polygon.vertex[0] = vertices[0]; + polygon.vertex[1] = vertices[1]; + polygon.vertex[2] = vertices[3]; + + _rasterPolygonImage(surface, image, region, polygon, aaSpans, opacity); + + //Draw the second polygon + polygon.vertex[0] = vertices[1]; + polygon.vertex[1] = vertices[2]; + polygon.vertex[2] = vertices[3]; + + _rasterPolygonImage(surface, image, region, polygon, aaSpans, opacity); + +#if 0 + if (_compositing(surface) && _masking(surface) && !_direct(surface->compositor->method)) { + _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); + } +#endif + return _apply(surface, aaSpans); +} + + +/* + Provide any number of triangles to draw a mesh using the supplied image. + Indexes are not used, so each triangle (Polygon) vertex has to be defined, even if they copy the previous one. + Example: + + 0 -- 1 0 -- 1 0 + | / | --> | / / | + | / | | / / | + 2 -- 3 2 1 -- 2 + + Should provide two Polygons, one for each triangle. + // TODO: region? +*/ +static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox* region, uint8_t opacity) +{ + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon mesh!"); + return false; + } + + //Exceptions: No dedicated drawing area? + if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false; + + // Step polygons once to transform + auto transformedTris = (Polygon*)malloc(sizeof(Polygon) * mesh->triangleCnt); + float ys = FLT_MAX, ye = -1.0f; + for (uint32_t i = 0; i < mesh->triangleCnt; i++) { + transformedTris[i] = mesh->triangles[i]; + mathMultiply(&transformedTris[i].vertex[0].pt, transform); + mathMultiply(&transformedTris[i].vertex[1].pt, transform); + mathMultiply(&transformedTris[i].vertex[2].pt, transform); + + if (transformedTris[i].vertex[0].pt.y < ys) ys = transformedTris[i].vertex[0].pt.y; + else if (transformedTris[i].vertex[0].pt.y > ye) ye = transformedTris[i].vertex[0].pt.y; + if (transformedTris[i].vertex[1].pt.y < ys) ys = transformedTris[i].vertex[1].pt.y; + else if (transformedTris[i].vertex[1].pt.y > ye) ye = transformedTris[i].vertex[1].pt.y; + if (transformedTris[i].vertex[2].pt.y < ys) ys = transformedTris[i].vertex[2].pt.y; + else if (transformedTris[i].vertex[2].pt.y > ye) ye = transformedTris[i].vertex[2].pt.y; + + // Convert normalized UV coordinates to image coordinates + transformedTris[i].vertex[0].uv.x *= (float)image->w; + transformedTris[i].vertex[0].uv.y *= (float)image->h; + transformedTris[i].vertex[1].uv.x *= (float)image->w; + transformedTris[i].vertex[1].uv.y *= (float)image->h; + transformedTris[i].vertex[2].uv.x *= (float)image->w; + transformedTris[i].vertex[2].uv.y *= (float)image->h; + } + + // Get AA spans and step polygons again to draw + if (auto aaSpans = _AASpans(ys, ye, image, region)) { + for (uint32_t i = 0; i < mesh->triangleCnt; i++) { + _rasterPolygonImage(surface, image, region, transformedTris[i], aaSpans, opacity); + } +#if 0 + if (_compositing(surface) && _masking(surface) && !_direct(surface->compositor->method)) { + _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); + } +#endif + _apply(surface, aaSpans); + } + free(transformedTris); + return true; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwRenderer.cpp b/test/include/liblvgl/libs/thorvg/tvgSwRenderer.cpp new file mode 100644 index 00000000..9a096542 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwRenderer.cpp @@ -0,0 +1,859 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" +#include "tvgSwCommon.h" +#include "tvgTaskScheduler.h" +#include "tvgSwRenderer.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ +static int32_t initEngineCnt = false; +static int32_t rendererCnt = 0; +static SwMpool* globalMpool = nullptr; +static uint32_t threadsCnt = 0; + +struct SwTask : Task +{ + SwSurface* surface = nullptr; + SwMpool* mpool = nullptr; + SwBBox bbox = {{0, 0}, {0, 0}}; //Whole Rendering Region + Matrix* transform = nullptr; + Array clips; + RenderUpdateFlag flags = RenderUpdateFlag::None; + uint8_t opacity; + bool pushed = false; //Pushed into task list? + bool disposed = false; //Disposed task? + + RenderRegion bounds() + { + //Can we skip the synchronization? + done(); + + RenderRegion region; + + //Range over? + region.x = bbox.min.x > 0 ? bbox.min.x : 0; + region.y = bbox.min.y > 0 ? bbox.min.y : 0; + region.w = bbox.max.x - region.x; + region.h = bbox.max.y - region.y; + if (region.w < 0) region.w = 0; + if (region.h < 0) region.h = 0; + + return region; + } + + virtual void dispose() = 0; + virtual bool clip(SwRleData* target) = 0; + virtual SwRleData* rle() = 0; + + virtual ~SwTask() + { + free(transform); + } +}; + + +struct SwShapeTask : SwTask +{ + SwShape shape; + const RenderShape* rshape = nullptr; + bool cmpStroking = false; + bool clipper = false; + + /* We assume that if the stroke width is greater than 2, + the shape's outline beneath the stroke could be adequately covered by the stroke drawing. + Therefore, antialiasing is disabled under this condition. + Additionally, the stroke style should not be dashed. */ + bool antialiasing(float strokeWidth) + { + return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst; + } + + float validStrokeWidth() + { + if (!rshape->stroke) return 0.0f; + + auto width = rshape->stroke->width; + if (mathZero(width)) return 0.0f; + + if (!rshape->stroke->fill && (MULTIPLY(rshape->stroke->color[3], opacity) == 0)) return 0.0f; + if (mathZero(rshape->stroke->trim.begin - rshape->stroke->trim.end)) return 0.0f; + + if (transform) return (width * sqrt(transform->e11 * transform->e11 + transform->e12 * transform->e12)); + else return width; + } + + + bool clip(SwRleData* target) override + { + if (shape.fastTrack) rleClipRect(target, &bbox); + else if (shape.rle) rleClipPath(target, shape.rle); + else return false; + + return true; + } + + SwRleData* rle() override + { + if (!shape.rle && shape.fastTrack) { + shape.rle = rleRender(&shape.bbox); + } + return shape.rle; + } + + void run(unsigned tid) override + { + if (opacity == 0 && !clipper) return; //Invisible + + auto strokeWidth = validStrokeWidth(); + bool visibleFill = false; + auto clipRegion = bbox; + + //This checks also for the case, if the invisible shape turned to visible by alpha. + auto prepareShape = false; + if (!shapePrepared(&shape) && (flags & RenderUpdateFlag::Color)) prepareShape = true; + + //Shape + if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) { + uint8_t alpha = 0; + rshape->fillColor(nullptr, nullptr, nullptr, &alpha); + alpha = MULTIPLY(alpha, opacity); + visibleFill = (alpha > 0 || rshape->fill); + if (visibleFill || clipper) { + shapeReset(&shape); + if (!shapePrepare(&shape, rshape, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) { + visibleFill = false; + } + } + } + //Fill + if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) { + if (visibleFill || clipper) { + if (!shapeGenRle(&shape, rshape, antialiasing(strokeWidth))) goto err; + } + if (auto fill = rshape->fill) { + auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false; + if (ctable) shapeResetFill(&shape); + if (!shapeGenFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err; + } else { + shapeDelFill(&shape); + } + } + //Stroke + if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { + if (strokeWidth > 0.0f) { + shapeResetStroke(&shape, rshape, transform); + if (!shapeGenStrokeRle(&shape, rshape, transform, clipRegion, bbox, mpool, tid)) goto err; + + if (auto fill = rshape->strokeFill()) { + auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false; + if (ctable) shapeResetStrokeFill(&shape); + if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err; + } else { + shapeDelStrokeFill(&shape); + } + } else { + shapeDelStroke(&shape); + } + } + + //Clear current task memorypool here if the clippers would use the same memory pool + shapeDelOutline(&shape, mpool, tid); + + //Clip Path + for (auto clip = clips.begin(); clip < clips.end(); ++clip) { + auto clipper = static_cast(*clip); + //Clip shape rle + if (shape.rle && !clipper->clip(shape.rle)) goto err; + //Clip stroke rle + if (shape.strokeRle && !clipper->clip(shape.strokeRle)) goto err; + } + return; + + err: + shapeReset(&shape); + shapeDelOutline(&shape, mpool, tid); + } + + void dispose() override + { + shapeFree(&shape); + } +}; + + +struct SwSceneTask : SwTask +{ + Array scene; //list of paints render data (SwTask) + SwRleData* sceneRle = nullptr; + + bool clip(SwRleData* target) override + { + //Only one shape + if (scene.count == 1) { + return static_cast(*scene.data)->clip(target); + } + + //More than one shapes + if (sceneRle) rleClipPath(target, sceneRle); + else TVGLOG("SW_ENGINE", "No clippers in a scene?"); + + return true; + } + + SwRleData* rle() override + { + return sceneRle; + } + + void run(unsigned tid) override + { + //TODO: Skip the run if the scene hasn't changed. + if (!sceneRle) sceneRle = static_cast(calloc(1, sizeof(SwRleData))); + else rleReset(sceneRle); + + //Merge shapes if it has more than one shapes + if (scene.count > 1) { + //Merge first two clippers + auto clipper1 = static_cast(*scene.data); + auto clipper2 = static_cast(*(scene.data + 1)); + + rleMerge(sceneRle, clipper1->rle(), clipper2->rle()); + + //Unify the remained clippers + for (auto rd = scene.begin() + 2; rd < scene.end(); ++rd) { + auto clipper = static_cast(*rd); + rleMerge(sceneRle, sceneRle, clipper->rle()); + } + } + } + + void dispose() override + { + rleFree(sceneRle); + } +}; + + +struct SwImageTask : SwTask +{ + SwImage image; + Surface* source; //Image source + const RenderMesh* mesh = nullptr; //Should be valid ptr in action + + bool clip(SwRleData* target) override + { + TVGERR("SW_ENGINE", "Image is used as ClipPath?"); + return true; + } + + SwRleData* rle() override + { + TVGERR("SW_ENGINE", "Image is used as Scene ClipPath?"); + return nullptr; + } + + void run(unsigned tid) override + { + auto clipRegion = bbox; + + //Convert colorspace if it's not aligned. + rasterConvertCS(source, surface->cs); + rasterPremultiply(source); + + image.data = source->data; + image.w = source->w; + image.h = source->h; + image.stride = source->stride; + image.channelSize = source->channelSize; + + //Invisible shape turned to visible by alpha. + if ((flags & (RenderUpdateFlag::Image | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) && (opacity > 0)) { + imageReset(&image); + if (!image.data || image.w == 0 || image.h == 0) goto end; + + if (!imagePrepare(&image, mesh, transform, clipRegion, bbox, mpool, tid)) goto end; + + // TODO: How do we clip the triangle mesh? Only clip non-meshed images for now + if (mesh->triangleCnt == 0 && clips.count > 0) { + if (!imageGenRle(&image, bbox, false)) goto end; + if (image.rle) { + //Clear current task memorypool here if the clippers would use the same memory pool + imageDelOutline(&image, mpool, tid); + for (auto clip = clips.begin(); clip < clips.end(); ++clip) { + auto clipper = static_cast(*clip); + if (!clipper->clip(image.rle)) goto err; + } + return; + } + } + } + goto end; + err: + rleReset(image.rle); + end: + imageDelOutline(&image, mpool, tid); + } + + void dispose() override + { + imageFree(&image); + } +}; + + +static void _termEngine() +{ + if (rendererCnt > 0) return; + + mpoolTerm(globalMpool); + globalMpool = nullptr; +} + + +static void _renderFill(SwShapeTask* task, SwSurface* surface, uint8_t opacity) +{ + uint8_t r, g, b, a; + if (auto fill = task->rshape->fill) { + rasterGradientShape(surface, &task->shape, fill->identifier()); + } else { + task->rshape->fillColor(&r, &g, &b, &a); + a = MULTIPLY(opacity, a); + if (a > 0) rasterShape(surface, &task->shape, r, g, b, a); + } +} + +static void _renderStroke(SwShapeTask* task, SwSurface* surface, uint8_t opacity) +{ + uint8_t r, g, b, a; + if (auto strokeFill = task->rshape->strokeFill()) { + rasterGradientStroke(surface, &task->shape, strokeFill->identifier()); + } else { + if (task->rshape->strokeColor(&r, &g, &b, &a)) { + a = MULTIPLY(opacity, a); + if (a > 0) rasterStroke(surface, &task->shape, r, g, b, a); + } + } +} + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +SwRenderer::~SwRenderer() +{ + clearCompositors(); + + delete(surface); + + if (!sharedMpool) mpoolTerm(mpool); + + --rendererCnt; + + if (rendererCnt == 0 && initEngineCnt == 0) _termEngine(); +} + + +bool SwRenderer::clear() +{ + for (auto task = tasks.begin(); task < tasks.end(); ++task) { + if ((*task)->disposed) { + delete(*task); + } else { + (*task)->done(); + (*task)->pushed = false; + } + } + tasks.clear(); + + if (!sharedMpool) mpoolClear(mpool); + + if (surface) { + vport.x = vport.y = 0; + vport.w = surface->w; + vport.h = surface->h; + } + + return true; +} + + +bool SwRenderer::sync() +{ + return true; +} + + +RenderRegion SwRenderer::viewport() +{ + return vport; +} + + +bool SwRenderer::viewport(const RenderRegion& vp) +{ + vport = vp; + return true; +} + + +bool SwRenderer::target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs) +{ + if (!data || stride == 0 || w == 0 || h == 0 || w > stride) return false; + + clearCompositors(); + + if (!surface) surface = new SwSurface; + + surface->data = data; + surface->stride = stride; + surface->w = w; + surface->h = h; + surface->cs = cs; + surface->channelSize = CHANNEL_SIZE(cs); + surface->premultiplied = true; + + return rasterCompositor(surface); +} + + +bool SwRenderer::preRender() +{ + return true; +} + + +void SwRenderer::clearCompositors() +{ + //Free Composite Caches + for (auto comp = compositors.begin(); comp < compositors.end(); ++comp) { + free((*comp)->compositor->image.data); + delete((*comp)->compositor); + delete(*comp); + } + compositors.reset(); +} + + +bool SwRenderer::postRender() +{ + //Unmultiply alpha if needed + if (surface->cs == ColorSpace::ABGR8888S || surface->cs == ColorSpace::ARGB8888S) { + rasterUnpremultiply(surface); + } + + for (auto task = tasks.begin(); task < tasks.end(); ++task) { + if ((*task)->disposed) delete(*task); + else (*task)->pushed = false; + } + tasks.clear(); + + return true; +} + + +bool SwRenderer::renderImage(RenderData data) +{ + auto task = static_cast(data); + task->done(); + + if (task->opacity == 0) return true; + + return rasterImage(surface, &task->image, task->mesh, task->transform, task->bbox, task->opacity); +} + + +bool SwRenderer::renderShape(RenderData data) +{ + auto task = static_cast(data); + if (!task) return false; + + task->done(); + + if (task->opacity == 0) return true; + + //Main raster stage + if (task->rshape->stroke && task->rshape->stroke->strokeFirst) { + _renderStroke(task, surface, task->opacity); + _renderFill(task, surface, task->opacity); + } else { + _renderFill(task, surface, task->opacity); + _renderStroke(task, surface, task->opacity); + } + + return true; +} + + +bool SwRenderer::blend(BlendMethod method) +{ + if (surface->blendMethod == method) return true; + surface->blendMethod = method; + + switch (method) { + case BlendMethod::Add: + surface->blender = opBlendAdd; + break; + case BlendMethod::Screen: + surface->blender = opBlendScreen; + break; + case BlendMethod::Multiply: + surface->blender = opBlendMultiply; + break; + case BlendMethod::Overlay: + surface->blender = opBlendOverlay; + break; + case BlendMethod::Difference: + surface->blender = opBlendDifference; + break; + case BlendMethod::Exclusion: + surface->blender = opBlendExclusion; + break; + case BlendMethod::SrcOver: + surface->blender = opBlendSrcOver; + break; + case BlendMethod::Darken: + surface->blender = opBlendDarken; + break; + case BlendMethod::Lighten: + surface->blender = opBlendLighten; + break; + case BlendMethod::ColorDodge: + surface->blender = opBlendColorDodge; + break; + case BlendMethod::ColorBurn: + surface->blender = opBlendColorBurn; + break; + case BlendMethod::HardLight: + surface->blender = opBlendHardLight; + break; + case BlendMethod::SoftLight: + surface->blender = opBlendSoftLight; + break; + default: + surface->blender = nullptr; + break; + } + return false; +} + + +RenderRegion SwRenderer::region(RenderData data) +{ + return static_cast(data)->bounds(); +} + + +bool SwRenderer::beginComposite(Compositor* cmp, CompositeMethod method, uint8_t opacity) +{ + if (!cmp) return false; + auto p = static_cast(cmp); + + p->method = method; + p->opacity = opacity; + + //Current Context? + if (p->method != CompositeMethod::None) { + surface = p->recoverSfc; + surface->compositor = p; + } + + return true; +} + + +bool SwRenderer::mempool(bool shared) +{ + if (shared == sharedMpool) return true; + + if (shared) { + if (!sharedMpool) { + if (!mpoolTerm(mpool)) return false; + mpool = globalMpool; + } + } else { + if (sharedMpool) mpool = mpoolInit(threadsCnt); + } + + sharedMpool = shared; + + if (mpool) return true; + return false; +} + + +const Surface* SwRenderer::mainSurface() +{ + return surface; +} + + +Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) +{ + auto x = region.x; + auto y = region.y; + auto w = region.w; + auto h = region.h; + auto sw = static_cast(surface->w); + auto sh = static_cast(surface->h); + + //Out of boundary + if (x >= sw || y >= sh || x + w < 0 || y + h < 0) return nullptr; + + SwSurface* cmp = nullptr; + + auto reqChannelSize = CHANNEL_SIZE(cs); + + //Use cached data + for (auto p = compositors.begin(); p < compositors.end(); ++p) { + if ((*p)->compositor->valid && (*p)->compositor->image.channelSize == reqChannelSize) { + cmp = *p; + break; + } + } + + //New Composition + if (!cmp) { + //Inherits attributes from main surface + cmp = new SwSurface(surface); + cmp->compositor = new SwCompositor; + + //TODO: We can optimize compositor surface size from (surface->stride x surface->h) to Parameter(w x h) + cmp->compositor->image.data = (pixel_t*)malloc(reqChannelSize * surface->stride * surface->h); + cmp->channelSize = cmp->compositor->image.channelSize = reqChannelSize; + + compositors.push(cmp); + } + + //Boundary Check + if (x + w > sw) w = (sw - x); + if (y + h > sh) h = (sh - y); + + cmp->compositor->recoverSfc = surface; + cmp->compositor->recoverCmp = surface->compositor; + cmp->compositor->valid = false; + cmp->compositor->bbox.min.x = x; + cmp->compositor->bbox.min.y = y; + cmp->compositor->bbox.max.x = x + w; + cmp->compositor->bbox.max.y = y + h; + cmp->compositor->image.stride = surface->stride; + cmp->compositor->image.w = surface->w; + cmp->compositor->image.h = surface->h; + cmp->compositor->image.direct = true; + + cmp->data = cmp->compositor->image.data; + cmp->w = cmp->compositor->image.w; + cmp->h = cmp->compositor->image.h; + + rasterClear(cmp, x, y, w, h); + + //Switch render target + surface = cmp; + + return cmp->compositor; +} + + +bool SwRenderer::endComposite(Compositor* cmp) +{ + if (!cmp) return false; + + auto p = static_cast(cmp); + p->valid = true; + + //Recover Context + surface = p->recoverSfc; + surface->compositor = p->recoverCmp; + + //Default is alpha blending + if (p->method == CompositeMethod::None) { + return rasterImage(surface, &p->image, nullptr, nullptr, p->bbox, p->opacity); + } + + return true; +} + + +ColorSpace SwRenderer::colorSpace() +{ + if (surface) return surface->cs; + else return ColorSpace::Unsupported; +} + + +void SwRenderer::dispose(RenderData data) +{ + auto task = static_cast(data); + if (!task) return; + task->done(); + task->dispose(); + + if (task->pushed) task->disposed = true; + else delete(task); +} + + +void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags) +{ + if (!surface) return task; + if (flags == RenderUpdateFlag::None) return task; + + //Finish previous task if it has duplicated request. + task->done(); + + //TODO: Failed threading them. It would be better if it's possible. + //See: https://github.com/thorvg/thorvg/issues/1409 + //Guarantee composition targets get ready. + for (auto clip = clips.begin(); clip < clips.end(); ++clip) { + static_cast(*clip)->done(); + } + + task->clips = clips; + + if (transform) { + if (!task->transform) task->transform = static_cast(malloc(sizeof(Matrix))); + *task->transform = transform->m; + } else { + if (task->transform) free(task->transform); + task->transform = nullptr; + } + + //zero size? + if (task->transform) { + if (task->transform->e11 == 0.0f && task->transform->e12 == 0.0f) return task; //zero width + if (task->transform->e21 == 0.0f && task->transform->e22 == 0.0f) return task; //zero height + } + + task->opacity = opacity; + task->surface = surface; + task->mpool = mpool; + task->flags = flags; + task->bbox.min.x = mathMax(static_cast(0), static_cast(vport.x)); + task->bbox.min.y = mathMax(static_cast(0), static_cast(vport.y)); + task->bbox.max.x = mathMin(static_cast(surface->w), static_cast(vport.x + vport.w)); + task->bbox.max.y = mathMin(static_cast(surface->h), static_cast(vport.y + vport.h)); + + if (!task->pushed) { + task->pushed = true; + tasks.push(task); + } + + TaskScheduler::request(task); + + return task; +} + + +RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) +{ + //prepare task + auto task = static_cast(data); + if (!task) task = new SwImageTask; + task->source = surface; + task->mesh = mesh; + return prepareCommon(task, transform, clips, opacity, flags); +} + + +RenderData SwRenderer::prepare(const Array& scene, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) +{ + //prepare task + auto task = static_cast(data); + if (!task) task = new SwSceneTask; + task->scene = scene; + + //TODO: Failed threading them. It would be better if it's possible. + //See: https://github.com/thorvg/thorvg/issues/1409 + //Guarantee composition targets get ready. + for (auto task = scene.begin(); task < scene.end(); ++task) { + static_cast(*task)->done(); + } + return prepareCommon(task, transform, clips, opacity, flags); +} + + +RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) +{ + //prepare task + auto task = static_cast(data); + if (!task) { + task = new SwShapeTask; + task->rshape = &rshape; + } + task->clipper = clipper; + + return prepareCommon(task, transform, clips, opacity, flags); +} + + +SwRenderer::SwRenderer():mpool(globalMpool) +{ +} + + +bool SwRenderer::init(uint32_t threads) +{ + if ((initEngineCnt++) > 0) return true; + + threadsCnt = threads; + + //Share the memory pool among the renderer + globalMpool = mpoolInit(threads); + if (!globalMpool) { + --initEngineCnt; + return false; + } + + return true; +} + + +int32_t SwRenderer::init() +{ + return initEngineCnt; +} + + +bool SwRenderer::term() +{ + if ((--initEngineCnt) > 0) return true; + + initEngineCnt = 0; + + _termEngine(); + + return true; +} + +SwRenderer* SwRenderer::gen() +{ + ++rendererCnt; + return new SwRenderer(); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwRenderer.h b/test/include/liblvgl/libs/thorvg/tvgSwRenderer.h new file mode 100644 index 00000000..593ba52e --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwRenderer.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SW_RENDERER_H_ +#define _TVG_SW_RENDERER_H_ + +#include "tvgRender.h" + +struct SwSurface; +struct SwTask; +struct SwCompositor; +struct SwMpool; + +namespace tvg +{ + +class SwRenderer : public RenderMethod +{ +public: + RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; + RenderData prepare(const Array& scene, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + bool preRender() override; + bool renderShape(RenderData data) override; + bool renderImage(RenderData data) override; + bool postRender() override; + void dispose(RenderData data) override; + RenderRegion region(RenderData data) override; + RenderRegion viewport() override; + bool viewport(const RenderRegion& vp) override; + bool blend(BlendMethod method) override; + ColorSpace colorSpace() override; + const Surface* mainSurface() override; + + bool clear() override; + bool sync() override; + bool target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs); + bool mempool(bool shared); + + Compositor* target(const RenderRegion& region, ColorSpace cs) override; + bool beginComposite(Compositor* cmp, CompositeMethod method, uint8_t opacity) override; + bool endComposite(Compositor* cmp) override; + void clearCompositors(); + + static SwRenderer* gen(); + static bool init(uint32_t threads); + static int32_t init(); + static bool term(); + +private: + SwSurface* surface = nullptr; //active surface + Array tasks; //async task list + Array compositors; //render targets cache list + SwMpool* mpool; //private memory pool + RenderRegion vport; //viewport + bool sharedMpool = true; //memory-pool behavior policy + + SwRenderer(); + ~SwRenderer(); + + RenderData prepareCommon(SwTask* task, const RenderTransform* transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags); +}; + +} + +#endif /* _TVG_SW_RENDERER_H_ */ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwRle.cpp b/test/include/liblvgl/libs/thorvg/tvgSwRle.cpp new file mode 100644 index 00000000..689f2fe1 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwRle.cpp @@ -0,0 +1,1134 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +/* + * The FreeType Project LICENSE + * ---------------------------- + + * 2006-Jan-27 + + * Copyright 1996-2002, 2006 by + * David Turner, Robert Wilhelm, and Werner Lemberg + + + + * Introduction + * ============ + + * The FreeType Project is distributed in several archive packages; + * some of them may contain, in addition to the FreeType font engine, + * various tools and contributions which rely on, or relate to, the + * FreeType Project. + + * This license applies to all files found in such packages, and + * which do not fall under their own explicit license. The license + * affects thus the FreeType font engine, the test programs, + * documentation and makefiles, at the very least. + + * This license was inspired by the BSD, Artistic, and IJG + * (Independent JPEG Group) licenses, which all encourage inclusion + * and use of free software in commercial and freeware products + * alike. As a consequence, its main points are that: + + * o We don't promise that this software works. However, we will be + * interested in any kind of bug reports. (`as is' distribution) + + * o You can use this software for whatever you want, in parts or + * full form, without having to pay us. (`royalty-free' usage) + + * o You may not pretend that you wrote this software. If you use + * it, or only parts of it, in a program, you must acknowledge + * somewhere in your documentation that you have used the + * FreeType code. (`credits') + + * We specifically permit and encourage the inclusion of this + * software, with or without modifications, in commercial products. + * We disclaim all warranties covering The FreeType Project and + * assume no liability related to The FreeType Project. + + + * Finally, many people asked us for a preferred form for a + * credit/disclaimer to use in compliance with this license. We thus + * encourage you to use the following text: + + * """ + * Portions of this software are copyright � The FreeType + * Project (www.freetype.org). All rights reserved. + * """ + + * Please replace with the value from the FreeType version you + * actually use. + +* Legal Terms +* =========== + +* 0. Definitions +* -------------- + +* Throughout this license, the terms `package', `FreeType Project', +* and `FreeType archive' refer to the set of files originally +* distributed by the authors (David Turner, Robert Wilhelm, and +* Werner Lemberg) as the `FreeType Project', be they named as alpha, +* beta or final release. + +* `You' refers to the licensee, or person using the project, where +* `using' is a generic term including compiling the project's source +* code as well as linking it to form a `program' or `executable'. +* This program is referred to as `a program using the FreeType +* engine'. + +* This license applies to all files distributed in the original +* FreeType Project, including all source code, binaries and +* documentation, unless otherwise stated in the file in its +* original, unmodified form as distributed in the original archive. +* If you are unsure whether or not a particular file is covered by +* this license, you must contact us to verify this. + +* The FreeType Project is copyright (C) 1996-2000 by David Turner, +* Robert Wilhelm, and Werner Lemberg. All rights reserved except as +* specified below. + +* 1. No Warranty +* -------------- + +* THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY +* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +* PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS +* BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO +* USE, OF THE FREETYPE PROJECT. + +* 2. Redistribution +* ----------------- + +* This license grants a worldwide, royalty-free, perpetual and +* irrevocable right and license to use, execute, perform, compile, +* display, copy, create derivative works of, distribute and +* sublicense the FreeType Project (in both source and object code +* forms) and derivative works thereof for any purpose; and to +* authorize others to exercise some or all of the rights granted +* herein, subject to the following conditions: + +* o Redistribution of source code must retain this license file +* (`FTL.TXT') unaltered; any additions, deletions or changes to +* the original files must be clearly indicated in accompanying +* documentation. The copyright notices of the unaltered, +* original files must be preserved in all copies of source +* files. + +* o Redistribution in binary form must provide a disclaimer that +* states that the software is based in part of the work of the +* FreeType Team, in the distribution documentation. We also +* encourage you to put an URL to the FreeType web page in your +* documentation, though this isn't mandatory. + +* These conditions apply to any software derived from or based on +* the FreeType Project, not just the unmodified files. If you use +* our work, you must acknowledge us. However, no fee need be paid +* to us. + +* 3. Advertising +* -------------- + +* Neither the FreeType authors and contributors nor you shall use +* the name of the other for commercial, advertising, or promotional +* purposes without specific prior written permission. + +* We suggest, but do not require, that you use one or more of the +* following phrases to refer to this software in your documentation +* or advertising materials: `FreeType Project', `FreeType Engine', +* `FreeType library', or `FreeType Distribution'. + +* As you have not signed this license, you are not required to +* accept it. However, as the FreeType Project is copyrighted +* material, only this license, or another one contracted with the +* authors, grants you the right to use, distribute, and modify it. +* Therefore, by using, distributing, or modifying the FreeType +* Project, you indicate that you understand and accept all the terms +* of this license. + +* 4. Contacts +* ----------- + +* There are two mailing lists related to FreeType: + +* o freetype@nongnu.org + +* Discusses general use and applications of FreeType, as well as +* future and wanted additions to the library and distribution. +* If you are looking for support, start in this list if you +* haven't found anything to help you in the documentation. + +* o freetype-devel@nongnu.org + +* Discusses bugs, as well as engine internals, design issues, +* specific licenses, porting, etc. + +* Our home page can be found at + +* http://www.freetype.org +*/ + +#include +#include +#include +#include "tvgSwCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +constexpr auto MAX_SPANS = 256; +constexpr auto PIXEL_BITS = 8; //must be at least 6 bits! +constexpr auto ONE_PIXEL = (1L << PIXEL_BITS); + +using Area = long; + +struct Band +{ + SwCoord min, max; +}; + +struct Cell +{ + SwCoord x; + SwCoord cover; + Area area; + Cell *next; +}; + +struct RleWorker +{ + SwRleData* rle; + + SwPoint cellPos; + SwPoint cellMin; + SwPoint cellMax; + SwCoord cellXCnt; + SwCoord cellYCnt; + + Area area; + SwCoord cover; + + Cell* cells; + ptrdiff_t maxCells; + ptrdiff_t cellsCnt; + + SwPoint pos; + + SwPoint bezStack[32 * 3 + 1]; + int levStack[32]; + + SwOutline* outline; + + SwSpan spans[MAX_SPANS]; + int spansCnt; + int ySpan; + + int bandSize; + int bandShoot; + + jmp_buf jmpBuf; + + void* buffer; + long bufferSize; + + Cell** yCells; + SwCoord yCnt; + + bool invalid; + bool antiAlias; +}; + + +static inline SwPoint UPSCALE(const SwPoint& pt) +{ + return {SwCoord(((unsigned long) pt.x) << (PIXEL_BITS - 6)), SwCoord(((unsigned long) pt.y) << (PIXEL_BITS - 6))}; +} + + +static inline SwPoint TRUNC(const SwPoint& pt) +{ + return {pt.x >> PIXEL_BITS, pt.y >> PIXEL_BITS}; +} + + +static inline SwCoord TRUNC(const SwCoord x) +{ + return x >> PIXEL_BITS; +} + + +static inline SwPoint SUBPIXELS(const SwPoint& pt) +{ + return {SwCoord(((unsigned long) pt.x) << PIXEL_BITS), SwCoord(((unsigned long) pt.y) << PIXEL_BITS)}; +} + + +static inline SwCoord SUBPIXELS(const SwCoord x) +{ + return SwCoord(((unsigned long) x) << PIXEL_BITS); +} + +/* + * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' + * algorithm. We use alpha = 1, beta = 3/8, giving us results with a + * largest error less than 7% compared to the exact value. + */ +static inline SwCoord HYPOT(SwPoint pt) +{ + if (pt.x < 0) pt.x = -pt.x; + if (pt.y < 0) pt.y = -pt.y; + return ((pt.x > pt.y) ? (pt.x + (3 * pt.y >> 3)) : (pt.y + (3 * pt.x >> 3))); +} + +static void _genSpan(SwRleData* rle, const SwSpan* spans, uint32_t count) +{ + auto newSize = rle->size + count; + + /* allocate enough memory for new spans */ + /* alloc is required to prevent free and reallocation */ + /* when the rle needs to be regenerated because of attribute change. */ + if (rle->alloc < newSize) { + rle->alloc = (newSize * 2); + //OPTIMIZE: use mempool! + rle->spans = static_cast(realloc(rle->spans, rle->alloc * sizeof(SwSpan))); + } + + //copy the new spans to the allocated memory + SwSpan* lastSpan = rle->spans + rle->size; + memcpy(lastSpan, spans, count * sizeof(SwSpan)); + + rle->size = newSize; +} + + +static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoord aCount) +{ + x += rw.cellMin.x; + y += rw.cellMin.y; + + //Clip Y range + if (y < rw.cellMin.y || y >= rw.cellMax.y) return; + + /* compute the coverage line's coverage, depending on the outline fill rule */ + /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ + auto coverage = static_cast(area >> (PIXEL_BITS * 2 + 1 - 8)); //range 0 - 255 + + if (coverage < 0) coverage = -coverage; + + if (rw.outline->fillRule == FillRule::EvenOdd) { + coverage &= 511; + if (coverage > 255) coverage = 511 - coverage; + } else { + //normal non-zero winding rule + if (coverage > 255) coverage = 255; + } + + //span has ushort coordinates. check limit overflow + if (x >= SHRT_MAX) { + TVGERR("SW_ENGINE", "X-coordinate overflow!"); + x = SHRT_MAX; + } + if (y >= SHRT_MAX) { + TVGERR("SW_ENGINE", "Y Coordinate overflow!"); + y = SHRT_MAX; + } + + if (coverage > 0) { + if (!rw.antiAlias) coverage = 255; + auto count = rw.spansCnt; + auto span = rw.spans + count - 1; + + //see whether we can add this span to the current list + if ((count > 0) && (rw.ySpan == y) && + (span->x + span->len == x) && (span->coverage == coverage)) { + + //Clip x range + SwCoord xOver = 0; + if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x); + if (x < rw.cellMin.x) xOver -= (rw.cellMin.x - x); + + //span->len += (aCount + xOver) - 1; + span->len += (aCount + xOver); + return; + } + + if (count >= MAX_SPANS) { + _genSpan(rw.rle, rw.spans, count); + rw.spansCnt = 0; + rw.ySpan = 0; + span = rw.spans; + } else { + ++span; + } + + //Clip x range + SwCoord xOver = 0; + if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x); + if (x < rw.cellMin.x) { + xOver -= (rw.cellMin.x - x); + x = rw.cellMin.x; + } + + //Nothing to draw + if (aCount + xOver <= 0) return; + + //add a span to the current list + span->x = x; + span->y = y; + span->len = (aCount + xOver); + span->coverage = coverage; + ++rw.spansCnt; + rw.ySpan = y; + } +} + + +static void _sweep(RleWorker& rw) +{ + if (rw.cellsCnt == 0) return; + + rw.spansCnt = 0; + rw.ySpan = 0; + + for (int y = 0; y < rw.yCnt; ++y) { + auto cover = 0; + auto x = 0; + auto cell = rw.yCells[y]; + + while (cell) { + if (cell->x > x && cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), cell->x - x); + cover += cell->cover; + auto area = cover * (ONE_PIXEL * 2) - cell->area; + if (area != 0 && cell->x >= 0) _horizLine(rw, cell->x, y, area, 1); + x = cell->x + 1; + cell = cell->next; + } + + if (cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), rw.cellXCnt - x); + } + + if (rw.spansCnt > 0) _genSpan(rw.rle, rw.spans, rw.spansCnt); +} + + +static Cell* _findCell(RleWorker& rw) +{ + auto x = rw.cellPos.x; + if (x > rw.cellXCnt) x = rw.cellXCnt; + + auto pcell = &rw.yCells[rw.cellPos.y]; + + while(true) { + Cell* cell = *pcell; + if (!cell || cell->x > x) break; + if (cell->x == x) return cell; + pcell = &cell->next; + } + + if (rw.cellsCnt >= rw.maxCells) longjmp(rw.jmpBuf, 1); + + auto cell = rw.cells + rw.cellsCnt++; + cell->x = x; + cell->area = 0; + cell->cover = 0; + cell->next = *pcell; + *pcell = cell; + + return cell; +} + + +static void _recordCell(RleWorker& rw) +{ + if (rw.area | rw.cover) { + auto cell = _findCell(rw); + cell->area += rw.area; + cell->cover += rw.cover; + } +} + + +static void _setCell(RleWorker& rw, SwPoint pos) +{ + /* Move the cell pointer to a new position. We set the `invalid' */ + /* flag to indicate that the cell isn't part of those we're interested */ + /* in during the render phase. This means that: */ + /* */ + /* . the new vertical position must be within min_ey..max_ey-1. */ + /* . the new horizontal position must be strictly less than max_ex */ + /* */ + /* Note that if a cell is to the left of the clipping region, it is */ + /* actually set to the (min_ex-1) horizontal position. */ + + /* All cells that are on the left of the clipping region go to the + min_ex - 1 horizontal position. */ + pos.x -= rw.cellMin.x; + pos.y -= rw.cellMin.y; + + if (pos.x > rw.cellMax.x) pos.x = rw.cellMax.x; + + //Are we moving to a different cell? + if (pos != rw.cellPos) { + //Record the current one if it is valid + if (!rw.invalid) _recordCell(rw); + } + + rw.area = 0; + rw.cover = 0; + rw.cellPos = pos; + rw.invalid = ((unsigned)pos.y >= (unsigned)rw.cellYCnt || pos.x >= rw.cellXCnt); +} + + +static void _startCell(RleWorker& rw, SwPoint pos) +{ + if (pos.x > rw.cellMax.x) pos.x = rw.cellMax.x; + if (pos.x < rw.cellMin.x) pos.x = rw.cellMin.x; + + rw.area = 0; + rw.cover = 0; + rw.cellPos = pos - rw.cellMin; + rw.invalid = false; + + _setCell(rw, pos); +} + + +static void _moveTo(RleWorker& rw, const SwPoint& to) +{ + //record current cell, if any */ + if (!rw.invalid) _recordCell(rw); + + //start to a new position + _startCell(rw, TRUNC(to)); + + rw.pos = to; +} + + +static void _lineTo(RleWorker& rw, const SwPoint& to) +{ +#define SW_UDIV(a, b) \ + static_cast(((unsigned long)(a) * (unsigned long)(b)) >> \ + (sizeof(long) * CHAR_BIT - PIXEL_BITS)) + + auto e1 = TRUNC(rw.pos); + auto e2 = TRUNC(to); + + //vertical clipping + if ((e1.y >= rw.cellMax.y && e2.y >= rw.cellMax.y) || (e1.y < rw.cellMin.y && e2.y < rw.cellMin.y)) { + rw.pos = to; + return; + } + + auto diff = to - rw.pos; + auto f1 = rw.pos - SUBPIXELS(e1); + SwPoint f2; + + //inside one cell + if (e1 == e2) { + ; + //any horizontal line + } else if (diff.y == 0) { + e1.x = e2.x; + _setCell(rw, e1); + } else if (diff.x == 0) { + //vertical line up + if (diff.y > 0) { + do { + f2.y = ONE_PIXEL; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * f1.x * 2; + f1.y = 0; + ++e1.y; + _setCell(rw, e1); + } while(e1.y != e2.y); + //vertical line down + } else { + do { + f2.y = 0; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * f1.x * 2; + f1.y = ONE_PIXEL; + --e1.y; + _setCell(rw, e1); + } while(e1.y != e2.y); + } + //any other line + } else { + Area prod = diff.x * f1.y - diff.y * f1.x; + + /* These macros speed up repetitive divisions by replacing them + with multiplications and right shifts. */ + auto dx_r = static_cast(ULONG_MAX >> PIXEL_BITS) / (diff.x); + auto dy_r = static_cast(ULONG_MAX >> PIXEL_BITS) / (diff.y); + + /* The fundamental value `prod' determines which side and the */ + /* exact coordinate where the line exits current cell. It is */ + /* also easily updated when moving from one cell to the next. */ + do { + auto px = diff.x * ONE_PIXEL; + auto py = diff.y * ONE_PIXEL; + + //left + if (prod <= 0 && prod - px > 0) { + f2 = {0, SW_UDIV(-prod, -dx_r)}; + prod -= py; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {ONE_PIXEL, f2.y}; + --e1.x; + //up + } else if (prod - px <= 0 && prod - px + py > 0) { + prod -= px; + f2 = {SW_UDIV(-prod, dy_r), ONE_PIXEL}; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {f2.x, 0}; + ++e1.y; + //right + } else if (prod - px + py <= 0 && prod + py >= 0) { + prod += py; + f2 = {ONE_PIXEL, SW_UDIV(prod, dx_r)}; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {0, f2.y}; + ++e1.x; + //down + } else { + f2 = {SW_UDIV(prod, -dy_r), 0}; + prod += px; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {f2.x, ONE_PIXEL}; + --e1.y; + } + + _setCell(rw, e1); + + } while(e1 != e2); + } + + f2 = {to.x - SUBPIXELS(e2.x), to.y - SUBPIXELS(e2.y)}; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + rw.pos = to; +} + + +static void _cubicTo(RleWorker& rw, const SwPoint& ctrl1, const SwPoint& ctrl2, const SwPoint& to) +{ + auto arc = rw.bezStack; + arc[0] = to; + arc[1] = ctrl2; + arc[2] = ctrl1; + arc[3] = rw.pos; + + //Short-cut the arc that crosses the current band + auto min = arc[0].y; + auto max = arc[0].y; + + SwCoord y; + for (auto i = 1; i < 4; ++i) { + y = arc[i].y; + if (y < min) min = y; + if (y > max) max = y; + } + + if (TRUNC(min) >= rw.cellMax.y || TRUNC(max) < rw.cellMin.y) goto draw; + + /* Decide whether to split or draw. See `Rapid Termination */ + /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */ + /* F. Hain, at */ + /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */ + while (true) { + { + //diff is the P0 - P3 chord vector + auto diff = arc[3] - arc[0]; + auto L = HYPOT(diff); + + //avoid possible arithmetic overflow below by splitting + if (L > SHRT_MAX) goto split; + + //max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1) + auto sLimit = L * (ONE_PIXEL / 6); + + auto diff1 = arc[1] - arc[0]; + auto s = diff.y * diff1.x - diff.x * diff1.y; + if (s < 0) s = -s; + if (s > sLimit) goto split; + + //s is L * the perpendicular distance from P2 to the line P0 - P3 + auto diff2 = arc[2] - arc[0]; + s = diff.y * diff2.x - diff.x * diff2.y; + if (s < 0) s = -s; + if (s > sLimit) goto split; + + /* Split super curvy segments where the off points are so far + from the chord that the angles P0-P1-P3 or P0-P2-P3 become + acute as detected by appropriate dot products */ + if (diff1.x * (diff1.x - diff.x) + diff1.y * (diff1.y - diff.y) > 0 || + diff2.x * (diff2.x - diff.x) + diff2.y * (diff2.y - diff.y) > 0) + goto split; + + //no reason to split + goto draw; + } + split: + mathSplitCubic(arc); + arc += 3; + continue; + + draw: + _lineTo(rw, arc[0]); + if (arc == rw.bezStack) return; + arc -= 3; + } +} + + +static void _decomposeOutline(RleWorker& rw) +{ + auto outline = rw.outline; + auto first = 0; //index of first point in contour + + for (auto cntr = outline->cntrs.begin(); cntr < outline->cntrs.end(); ++cntr) { + auto last = *cntr; + auto limit = outline->pts.data + last; + auto start = UPSCALE(outline->pts[first]); + auto pt = outline->pts.data + first; + auto types = outline->types.data + first; + + _moveTo(rw, UPSCALE(outline->pts[first])); + + while (pt < limit) { + ++pt; + ++types; + + //emit a single line_to + if (types[0] == SW_CURVE_TYPE_POINT) { + _lineTo(rw, UPSCALE(*pt)); + //types cubic + } else { + pt += 2; + types += 2; + + if (pt <= limit) { + _cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), UPSCALE(pt[0])); + continue; + } + _cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), start); + goto close; + } + } + _lineTo(rw, start); + close: + first = last + 1; + } +} + + +static int _genRle(RleWorker& rw) +{ + if (setjmp(rw.jmpBuf) == 0) { + _decomposeOutline(rw); + if (!rw.invalid) _recordCell(rw); + return 0; + } + return -1; //lack of cell memory +} + + +static SwSpan* _intersectSpansRegion(const SwRleData *clip, const SwRleData *target, SwSpan *outSpans, uint32_t outSpansCnt) +{ + auto out = outSpans; + auto spans = target->spans; + auto end = target->spans + target->size; + auto clipSpans = clip->spans; + auto clipEnd = clip->spans + clip->size; + + while (spans < end && clipSpans < clipEnd) { + //align y coordinates. + if (clipSpans->y > spans->y) { + ++spans; + continue; + } + if (spans->y > clipSpans->y) { + ++clipSpans; + continue; + } + + //Try clipping with all clip spans which have a same y coordinate. + auto temp = clipSpans; + while(temp < clipEnd && outSpansCnt > 0 && temp->y == clipSpans->y) { + auto sx1 = spans->x; + auto sx2 = sx1 + spans->len; + auto cx1 = temp->x; + auto cx2 = cx1 + temp->len; + + //The span must be left(x1) to right(x2) direction. Not intersected. + if (cx2 < sx1 || sx2 < cx1) { + ++temp; + continue; + } + + //clip span region. + auto x = sx1 > cx1 ? sx1 : cx1; + auto len = (sx2 < cx2 ? sx2 : cx2) - x; + if (len > 0) { + out->x = x; + out->y = temp->y; + out->len = len; + out->coverage = (uint8_t)(((spans->coverage * temp->coverage) + 0xff) >> 8); + ++out; + --outSpansCnt; + } + ++temp; + } + ++spans; + } + return out; +} + + +static SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRleData *targetRle, SwSpan *outSpans, uint32_t outSpansCnt) +{ + auto out = outSpans; + auto spans = targetRle->spans; + auto end = targetRle->spans + targetRle->size; + auto minx = static_cast(bbox->min.x); + auto miny = static_cast(bbox->min.y); + auto maxx = minx + static_cast(bbox->max.x - bbox->min.x) - 1; + auto maxy = miny + static_cast(bbox->max.y - bbox->min.y) - 1; + + while (outSpansCnt > 0 && spans < end) { + if (spans->y > maxy) { + spans = end; + break; + } + if (spans->y < miny || spans->x > maxx || spans->x + spans->len <= minx) { + ++spans; + continue; + } + if (spans->x < minx) { + out->len = (spans->len - (minx - spans->x)) < (maxx - minx + 1) ? (spans->len - (minx - spans->x)) : (maxx - minx + 1); + out->x = minx; + } + else { + out->x = spans->x; + out->len = spans->len < (maxx - spans->x + 1) ? spans->len : (maxx - spans->x + 1); + } + if (out->len > 0) { + out->y = spans->y; + out->coverage = spans->coverage; + ++out; + --outSpansCnt; + } + ++spans; + } + return out; +} + + +static SwSpan* _mergeSpansRegion(const SwRleData *clip1, const SwRleData *clip2, SwSpan *outSpans) +{ + auto out = outSpans; + auto spans1 = clip1->spans; + auto end1 = clip1->spans + clip1->size; + auto spans2 = clip2->spans; + auto end2 = clip2->spans + clip2->size; + + //list two spans up in y order + //TODO: Remove duplicated regions? + while (spans1 < end1 && spans2 < end2) { + while (spans1 < end1 && spans1->y <= spans2->y) { + *out = *spans1; + ++spans1; + ++out; + } + if (spans1 >= end1) break; + while (spans2 < end2 && spans2->y <= spans1->y) { + *out = *spans2; + ++spans2; + ++out; + } + } + + //Leftovers + while (spans1 < end1) { + *out = *spans1; + ++spans1; + ++out; + } + while (spans2 < end2) { + *out = *spans2; + ++spans2; + ++out; + } + + return out; +} + + +void _replaceClipSpan(SwRleData *rle, SwSpan* clippedSpans, uint32_t size) +{ + free(rle->spans); + rle->spans = clippedSpans; + rle->size = rle->alloc = size; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias) +{ + constexpr auto RENDER_POOL_SIZE = 16384L; + constexpr auto BAND_SIZE = 40; + + //TODO: We can preserve several static workers in advance + RleWorker rw; + Cell buffer[RENDER_POOL_SIZE / sizeof(Cell)]; + + //Init Cells + rw.buffer = buffer; + rw.bufferSize = sizeof(buffer); + rw.yCells = reinterpret_cast(buffer); + rw.cells = nullptr; + rw.maxCells = 0; + rw.cellsCnt = 0; + rw.area = 0; + rw.cover = 0; + rw.invalid = true; + rw.cellMin = renderRegion.min; + rw.cellMax = renderRegion.max; + rw.cellXCnt = rw.cellMax.x - rw.cellMin.x; + rw.cellYCnt = rw.cellMax.y - rw.cellMin.y; + rw.ySpan = 0; + rw.outline = const_cast(outline); + rw.bandSize = rw.bufferSize / (sizeof(Cell) * 8); //bandSize: 64 + rw.bandShoot = 0; + rw.antiAlias = antiAlias; + + if (!rle) rw.rle = reinterpret_cast(calloc(1, sizeof(SwRleData))); + else rw.rle = rle; + + //Generate RLE + Band bands[BAND_SIZE]; + Band* band; + + /* set up vertical bands */ + auto bandCnt = static_cast((rw.cellMax.y - rw.cellMin.y) / rw.bandSize); + if (bandCnt == 0) bandCnt = 1; + else if (bandCnt >= BAND_SIZE) bandCnt = (BAND_SIZE - 1); + + auto min = rw.cellMin.y; + auto yMax = rw.cellMax.y; + SwCoord max; + int ret; + + for (int n = 0; n < bandCnt; ++n, min = max) { + max = min + rw.bandSize; + if (n == bandCnt -1 || max > yMax) max = yMax; + + bands[0].min = min; + bands[0].max = max; + band = bands; + + while (band >= bands) { + rw.yCells = static_cast(rw.buffer); + rw.yCnt = band->max - band->min; + + int cellStart = sizeof(Cell*) * (int)rw.yCnt; + int cellMod = cellStart % sizeof(Cell); + + if (cellMod > 0) cellStart += sizeof(Cell) - cellMod; + + auto cellEnd = rw.bufferSize; + cellEnd -= cellEnd % sizeof(Cell); + + auto cellsMax = reinterpret_cast((char*)rw.buffer + cellEnd); + rw.cells = reinterpret_cast((char*)rw.buffer + cellStart); + + if (rw.cells >= cellsMax) goto reduce_bands; + + rw.maxCells = cellsMax - rw.cells; + if (rw.maxCells < 2) goto reduce_bands; + + for (int y = 0; y < rw.yCnt; ++y) + rw.yCells[y] = nullptr; + + rw.cellsCnt = 0; + rw.invalid = true; + rw.cellMin.y = band->min; + rw.cellMax.y = band->max; + rw.cellYCnt = band->max - band->min; + + ret = _genRle(rw); + if (ret == 0) { + _sweep(rw); + --band; + continue; + } else if (ret == 1) { + goto error; + } + + reduce_bands: + /* render pool overflow: we will reduce the render band by half */ + auto bottom = band->min; + auto top = band->max; + auto middle = bottom + ((top - bottom) >> 1); + + /* This is too complex for a single scanline; there must + be some problems */ + if (middle == bottom) goto error; + + if (bottom - top >= rw.bandSize) ++rw.bandShoot; + + band[1].min = bottom; + band[1].max = middle; + band[0].min = middle; + band[0].max = top; + ++band; + } + } + + if (rw.bandShoot > 8 && rw.bandSize > 16) + rw.bandSize = (rw.bandSize >> 1); + + return rw.rle; + +error: + free(rw.rle); + rw.rle = nullptr; + return nullptr; +} + + +SwRleData* rleRender(const SwBBox* bbox) +{ + auto width = static_cast(bbox->max.x - bbox->min.x); + auto height = static_cast(bbox->max.y - bbox->min.y); + + auto rle = static_cast(malloc(sizeof(SwRleData))); + rle->spans = static_cast(malloc(sizeof(SwSpan) * height)); + rle->size = height; + rle->alloc = height; + + auto span = rle->spans; + for (uint16_t i = 0; i < height; ++i, ++span) { + span->x = bbox->min.x; + span->y = bbox->min.y + i; + span->len = width; + span->coverage = 255; + } + + return rle; +} + + +void rleReset(SwRleData* rle) +{ + if (!rle) return; + rle->size = 0; +} + + +void rleFree(SwRleData* rle) +{ + if (!rle) return; + if (rle->spans) free(rle->spans); + free(rle); +} + + +void rleMerge(SwRleData* rle, SwRleData* clip1, SwRleData* clip2) +{ + if (!rle || (!clip1 && !clip2)) return; + if (clip1 && clip1->size == 0 && clip2 && clip2->size == 0) return; + + TVGLOG("SW_ENGINE", "Unifying Rle!"); + + //clip1 is empty, just copy clip2 + if (!clip1 || clip1->size == 0) { + if (clip2) { + auto spans = static_cast(malloc(sizeof(SwSpan) * (clip2->size))); + memcpy(spans, clip2->spans, clip2->size); + _replaceClipSpan(rle, spans, clip2->size); + } else { + _replaceClipSpan(rle, nullptr, 0); + } + return; + } + + //clip2 is empty, just copy clip1 + if (!clip2 || clip2->size == 0) { + if (clip1) { + auto spans = static_cast(malloc(sizeof(SwSpan) * (clip1->size))); + memcpy(spans, clip1->spans, clip1->size); + _replaceClipSpan(rle, spans, clip1->size); + } else { + _replaceClipSpan(rle, nullptr, 0); + } + return; + } + + auto spanCnt = clip1->size + clip2->size; + auto spans = static_cast(malloc(sizeof(SwSpan) * spanCnt)); + auto spansEnd = _mergeSpansRegion(clip1, clip2, spans); + + _replaceClipSpan(rle, spans, spansEnd - spans); +} + + +void rleClipPath(SwRleData *rle, const SwRleData *clip) +{ + if (rle->size == 0 || clip->size == 0) return; + auto spanCnt = rle->size > clip->size ? rle->size : clip->size; + auto spans = static_cast(malloc(sizeof(SwSpan) * (spanCnt))); + auto spansEnd = _intersectSpansRegion(clip, rle, spans, spanCnt); + + _replaceClipSpan(rle, spans, spansEnd - spans); + + TVGLOG("SW_ENGINE", "Using ClipPath!"); +} + + +void rleClipRect(SwRleData *rle, const SwBBox* clip) +{ + if (rle->size == 0) return; + auto spans = static_cast(malloc(sizeof(SwSpan) * (rle->size))); + auto spansEnd = _intersectSpansRect(clip, rle, spans, rle->size); + + _replaceClipSpan(rle, spans, spansEnd - spans); + + TVGLOG("SW_ENGINE", "Using ClipRect!"); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwShape.cpp b/test/include/liblvgl/libs/thorvg/tvgSwShape.cpp new file mode 100644 index 00000000..e2652c1e --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwShape.cpp @@ -0,0 +1,675 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgSwCommon.h" +#include "tvgMath.h" +#include "tvgLines.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static bool _outlineBegin(SwOutline& outline) +{ + //Make a contour if lineTo/curveTo without calling close or moveTo beforehand. + if (outline.pts.empty()) return false; + outline.cntrs.push(outline.pts.count - 1); + outline.closed.push(false); + outline.pts.push(outline.pts[outline.cntrs.last()]); + outline.types.push(SW_CURVE_TYPE_POINT); + return false; +} + + +static bool _outlineEnd(SwOutline& outline) +{ + if (outline.pts.empty()) return false; + outline.cntrs.push(outline.pts.count - 1); + outline.closed.push(false); + return false; +} + + +static bool _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform, bool closed = false) +{ + //make it a contour, if the last contour is not closed yet. + if (!closed) _outlineEnd(outline); + + outline.pts.push(mathTransform(to, transform)); + outline.types.push(SW_CURVE_TYPE_POINT); + return false; +} + + +static void _outlineLineTo(SwOutline& outline, const Point* to, const Matrix* transform) +{ + outline.pts.push(mathTransform(to, transform)); + outline.types.push(SW_CURVE_TYPE_POINT); +} + + +static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform) +{ + outline.pts.push(mathTransform(ctrl1, transform)); + outline.types.push(SW_CURVE_TYPE_CUBIC); + + outline.pts.push(mathTransform(ctrl2, transform)); + outline.types.push(SW_CURVE_TYPE_CUBIC); + + outline.pts.push(mathTransform(to, transform)); + outline.types.push(SW_CURVE_TYPE_POINT); +} + + +static bool _outlineClose(SwOutline& outline) +{ + uint32_t i; + if (outline.cntrs.count > 0) i = outline.cntrs.last() + 1; + else i = 0; + + //Make sure there is at least one point in the current path + if (outline.pts.count == i) return false; + + //Close the path + outline.pts.push(outline.pts[i]); + outline.cntrs.push(outline.pts.count - 1); + outline.types.push(SW_CURVE_TYPE_POINT); + outline.closed.push(true); + + return true; +} + + +static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* transform) +{ + Line cur = {dash.ptCur, *to}; + auto len = lineLength(cur.pt1, cur.pt2); + + if (mathZero(len)) { + _outlineMoveTo(*dash.outline, &dash.ptCur, transform); + //draw the current line fully + } else if (len < dash.curLen) { + dash.curLen -= len; + if (!dash.curOpGap) { + if (dash.move) { + _outlineMoveTo(*dash.outline, &dash.ptCur, transform); + dash.move = false; + } + _outlineLineTo(*dash.outline, to, transform); + } + //draw the current line partially + } else { + while (len - dash.curLen > 0.0001f) { + Line left, right; + if (dash.curLen > 0) { + len -= dash.curLen; + lineSplitAt(cur, dash.curLen, left, right); + if (!dash.curOpGap) { + if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLOAT_EPSILON) { + _outlineMoveTo(*dash.outline, &left.pt1, transform); + dash.move = false; + } + _outlineLineTo(*dash.outline, &left.pt2, transform); + } + } else { + right = cur; + } + dash.curIdx = (dash.curIdx + 1) % dash.cnt; + dash.curLen = dash.pattern[dash.curIdx]; + dash.curOpGap = !dash.curOpGap; + cur = right; + dash.ptCur = cur.pt1; + dash.move = true; + } + //leftovers + dash.curLen -= len; + if (!dash.curOpGap) { + if (dash.move) { + _outlineMoveTo(*dash.outline, &cur.pt1, transform); + dash.move = false; + } + _outlineLineTo(*dash.outline, &cur.pt2, transform); + } + if (dash.curLen < 1 && TO_SWCOORD(len) > 1) { + //move to next dash + dash.curIdx = (dash.curIdx + 1) % dash.cnt; + dash.curLen = dash.pattern[dash.curIdx]; + dash.curOpGap = !dash.curOpGap; + } + } + dash.ptCur = *to; +} + + +static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform) +{ + Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to}; + auto len = bezLength(cur); + + //draw the current line fully + if (mathZero(len)) { + _outlineMoveTo(*dash.outline, &dash.ptCur, transform); + } else if (len < dash.curLen) { + dash.curLen -= len; + if (!dash.curOpGap) { + if (dash.move) { + _outlineMoveTo(*dash.outline, &dash.ptCur, transform); + dash.move = false; + } + _outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform); + } + //draw the current line partially + } else { + while ((len - dash.curLen) > 0.0001f) { + Bezier left, right; + if (dash.curLen > 0) { + len -= dash.curLen; + bezSplitAt(cur, dash.curLen, left, right); + if (!dash.curOpGap) { + if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLOAT_EPSILON) { + _outlineMoveTo(*dash.outline, &left.start, transform); + dash.move = false; + } + _outlineCubicTo(*dash.outline, &left.ctrl1, &left.ctrl2, &left.end, transform); + } + } else { + right = cur; + } + dash.curIdx = (dash.curIdx + 1) % dash.cnt; + dash.curLen = dash.pattern[dash.curIdx]; + dash.curOpGap = !dash.curOpGap; + cur = right; + dash.ptCur = right.start; + dash.move = true; + } + //leftovers + dash.curLen -= len; + if (!dash.curOpGap) { + if (dash.move) { + _outlineMoveTo(*dash.outline, &cur.start, transform); + dash.move = false; + } + _outlineCubicTo(*dash.outline, &cur.ctrl1, &cur.ctrl2, &cur.end, transform); + } + if (dash.curLen < 1 && TO_SWCOORD(len) > 1) { + //move to next dash + dash.curIdx = (dash.curIdx + 1) % dash.cnt; + dash.curLen = dash.pattern[dash.curIdx]; + dash.curOpGap = !dash.curOpGap; + } + } + dash.ptCur = *to; +} + + +static void _dashClose(SwDashStroke& dash, const Matrix* transform) +{ + _dashLineTo(dash, &dash.ptStart, transform); +} + + +static void _dashMoveTo(SwDashStroke& dash, const Point* pts) +{ + dash.ptCur = *pts; + dash.ptStart = *pts; + dash.move = true; +} + + +static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const Point* pts) +{ + dash.curIdx = offIdx % dash.cnt; + dash.curLen = dash.pattern[dash.curIdx] - offset; + dash.curOpGap = offIdx % 2; + dash.ptStart = dash.ptCur = *pts; + dash.move = true; +} + + +static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* transform, float length, SwMpool* mpool, unsigned tid) +{ + const PathCommand* cmds = rshape->path.cmds.data; + auto cmdCnt = rshape->path.cmds.count; + const Point* pts = rshape->path.pts.data; + auto ptsCnt = rshape->path.pts.count; + + //No actual shape data + if (cmdCnt == 0 || ptsCnt == 0) return nullptr; + + SwDashStroke dash; + auto offset = 0.0f; + auto trimmed = false; + + dash.cnt = rshape->strokeDash((const float**)&dash.pattern, &offset); + + //dash by trimming. + if (length > 0.0f && dash.cnt == 0) { + auto begin = length * rshape->stroke->trim.begin; + auto end = length * rshape->stroke->trim.end; + + //TODO: mix trimming + dash style + + //default + if (end > begin) { + if (begin > 0.0f) dash.cnt += 4; + else dash.cnt += 2; + //looping + } else dash.cnt += 3; + + dash.pattern = (float*)malloc(sizeof(float) * dash.cnt); + + if (dash.cnt == 2) { + dash.pattern[0] = end - begin; + dash.pattern[1] = length - (end - begin); + } else if (dash.cnt == 3) { + dash.pattern[0] = end; + dash.pattern[1] = (begin - end); + dash.pattern[2] = length - begin; + } else { + dash.pattern[0] = 0; //zero dash to start with a space. + dash.pattern[1] = begin; + dash.pattern[2] = end - begin; + dash.pattern[3] = length - end; + } + + trimmed = true; + //just a dash style. + } else { + if (dash.cnt == 0) return nullptr; + } + + //offset? + auto patternLength = 0.0f; + uint32_t offIdx = 0; + if (!mathZero(offset)) { + for (size_t i = 0; i < dash.cnt; ++i) patternLength += dash.pattern[i]; + bool isOdd = dash.cnt % 2; + if (isOdd) patternLength *= 2; + + offset = fmodf(offset, patternLength); + if (offset < 0) offset += patternLength; + + for (size_t i = 0; i < dash.cnt * (1 + (size_t)isOdd); ++i, ++offIdx) { + auto curPattern = dash.pattern[i % dash.cnt]; + if (offset < curPattern) break; + offset -= curPattern; + } + } + + dash.outline = mpoolReqDashOutline(mpool, tid); + + //must begin with moveTo + if (cmds[0] == PathCommand::MoveTo) { + _dashMoveTo(dash, offIdx, offset, pts); + cmds++; + pts++; + } + + while (--cmdCnt > 0) { + switch (*cmds) { + case PathCommand::Close: { + _dashClose(dash, transform); + break; + } + case PathCommand::MoveTo: { + if (rshape->stroke->trim.individual) _dashMoveTo(dash, pts); + else _dashMoveTo(dash, offIdx, offset, pts); + ++pts; + break; + } + case PathCommand::LineTo: { + _dashLineTo(dash, pts, transform); + ++pts; + break; + } + case PathCommand::CubicTo: { + _dashCubicTo(dash, pts, pts + 1, pts + 2, transform); + pts += 3; + break; + } + } + ++cmds; + } + + _outlineEnd(*dash.outline); + + if (trimmed) free(dash.pattern); + + return dash.outline; +} + + +static float _outlineLength(const RenderShape* rshape) +{ + const PathCommand* cmds = rshape->path.cmds.data; + auto cmdCnt = rshape->path.cmds.count; + const Point* pts = rshape->path.pts.data; + auto ptsCnt = rshape->path.pts.count; + + //No actual shape data + if (cmdCnt == 0 || ptsCnt == 0) return 0.0f; + + const Point* close = nullptr; + auto length = 0.0f; + auto slength = -1.0f; + auto simultaneous = !rshape->stroke->trim.individual; + + //Compute the whole length + while (cmdCnt-- > 0) { + switch (*cmds) { + case PathCommand::Close: { + length += mathLength(pts - 1, close); + //retrieve the max length of the shape if the simultaneous mode. + if (simultaneous) { + if (slength < length) slength = length; + length = 0.0f; + } + break; + } + case PathCommand::MoveTo: { + close = pts; + ++pts; + break; + } + case PathCommand::LineTo: { + length += mathLength(pts - 1, pts); + ++pts; + break; + } + case PathCommand::CubicTo: { + length += bezLength({*(pts - 1), *pts, *(pts + 1), *(pts + 2)}); + pts += 3; + break; + } + } + ++cmds; + } + if (simultaneous && slength > length) return slength; + else return length; +} + + +static bool _axisAlignedRect(const SwOutline* outline) +{ + //Fast Track: axis-aligned rectangle? + if (outline->pts.count != 5) return false; + + auto pt1 = outline->pts.data + 0; + auto pt2 = outline->pts.data + 1; + auto pt3 = outline->pts.data + 2; + auto pt4 = outline->pts.data + 3; + + auto a = SwPoint{pt1->x, pt3->y}; + auto b = SwPoint{pt3->x, pt1->y}; + + if ((*pt2 == a && *pt4 == b) || (*pt2 == b && *pt4 == a)) return true; + + return false; +} + + +static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix* transform, SwMpool* mpool, unsigned tid, bool hasComposite) +{ + const PathCommand* cmds = rshape->path.cmds.data; + auto cmdCnt = rshape->path.cmds.count; + const Point* pts = rshape->path.pts.data; + auto ptsCnt = rshape->path.pts.count; + + //No actual shape data + if (cmdCnt == 0 || ptsCnt == 0) return false; + + shape->outline = mpoolReqOutline(mpool, tid); + auto outline = shape->outline; + auto closed = false; + + //Generate Outlines + while (cmdCnt-- > 0) { + switch (*cmds) { + case PathCommand::Close: { + if (!closed) closed = _outlineClose(*outline); + break; + } + case PathCommand::MoveTo: { + closed = _outlineMoveTo(*outline, pts, transform, closed); + ++pts; + break; + } + case PathCommand::LineTo: { + if (closed) closed = _outlineBegin(*outline); + _outlineLineTo(*outline, pts, transform); + ++pts; + break; + } + case PathCommand::CubicTo: { + if (closed) closed = _outlineBegin(*outline); + _outlineCubicTo(*outline, pts, pts + 1, pts + 2, transform); + pts += 3; + break; + } + } + ++cmds; + } + + if (!closed) _outlineEnd(*outline); + + outline->fillRule = rshape->rule; + shape->outline = outline; + + shape->fastTrack = (!hasComposite && _axisAlignedRect(shape->outline)); + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite) +{ + if (!_genOutline(shape, rshape, transform, mpool, tid, hasComposite)) return false; + if (!mathUpdateOutlineBBox(shape->outline, clipRegion, renderRegion, shape->fastTrack)) return false; + + //Keep it for Rasterization Region + shape->bbox = renderRegion; + + //Check valid region + if (renderRegion.max.x - renderRegion.min.x < 1 && renderRegion.max.y - renderRegion.min.y < 1) return false; + + //Check boundary + if (renderRegion.min.x >= clipRegion.max.x || renderRegion.min.y >= clipRegion.max.y || + renderRegion.max.x <= clipRegion.min.x || renderRegion.max.y <= clipRegion.min.y) return false; + + return true; +} + + +bool shapePrepared(const SwShape* shape) +{ + return shape->rle ? true : false; +} + + +bool shapeGenRle(SwShape* shape, TVG_UNUSED const RenderShape* rshape, bool antiAlias) +{ + //FIXME: Should we draw it? + //Case: Stroke Line + //if (shape.outline->opened) return true; + + //Case A: Fast Track Rectangle Drawing + if (shape->fastTrack) return true; + + //Case B: Normal Shape RLE Drawing + if ((shape->rle = rleRender(shape->rle, shape->outline, shape->bbox, antiAlias))) return true; + + return false; +} + + +void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid) +{ + mpoolRetOutline(mpool, tid); + shape->outline = nullptr; +} + + +void shapeReset(SwShape* shape) +{ + rleReset(shape->rle); + rleReset(shape->strokeRle); + shape->fastTrack = false; + shape->bbox.reset(); +} + + +void shapeFree(SwShape* shape) +{ + rleFree(shape->rle); + shape->rle = nullptr; + + shapeDelFill(shape); + + if (shape->stroke) { + rleFree(shape->strokeRle); + shape->strokeRle = nullptr; + strokeFree(shape->stroke); + shape->stroke = nullptr; + } +} + + +void shapeDelStroke(SwShape* shape) +{ + if (!shape->stroke) return; + rleFree(shape->strokeRle); + shape->strokeRle = nullptr; + strokeFree(shape->stroke); + shape->stroke = nullptr; +} + + +void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix* transform) +{ + if (!shape->stroke) shape->stroke = static_cast(calloc(1, sizeof(SwStroke))); + auto stroke = shape->stroke; + if (!stroke) return; + + strokeReset(stroke, rshape, transform); + rleReset(shape->strokeRle); +} + + +bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) +{ + SwOutline* shapeOutline = nullptr; + SwOutline* strokeOutline = nullptr; + auto dashStroking = false; + auto ret = true; + + auto length = rshape->strokeTrim() ? _outlineLength(rshape) : 0.0f; + + //Dash style (+trimming) + if (rshape->stroke->dashCnt > 0 || length > 0) { + shapeOutline = _genDashOutline(rshape, transform, length, mpool, tid); + if (!shapeOutline) return false; + dashStroking = true; + //Normal style + } else { + if (!shape->outline) { + if (!_genOutline(shape, rshape, transform, mpool, tid, false)) return false; + } + shapeOutline = shape->outline; + } + + if (!strokeParseOutline(shape->stroke, *shapeOutline)) { + ret = false; + goto clear; + } + + strokeOutline = strokeExportOutline(shape->stroke, mpool, tid); + + if (!mathUpdateOutlineBBox(strokeOutline, clipRegion, renderRegion, false)) { + ret = false; + goto clear; + } + + shape->strokeRle = rleRender(shape->strokeRle, strokeOutline, renderRegion, true); + +clear: + if (dashStroking) mpoolRetDashOutline(mpool, tid); + mpoolRetStrokeOutline(mpool, tid); + + return ret; +} + + +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable) +{ + return fillGenColorTable(shape->fill, fill, transform, surface, opacity, ctable); +} + + +bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable) +{ + return fillGenColorTable(shape->stroke->fill, fill, transform, surface, opacity, ctable); +} + + +void shapeResetFill(SwShape* shape) +{ + if (!shape->fill) { + shape->fill = static_cast(calloc(1, sizeof(SwFill))); + if (!shape->fill) return; + } + fillReset(shape->fill); +} + + +void shapeResetStrokeFill(SwShape* shape) +{ + if (!shape->stroke->fill) { + shape->stroke->fill = static_cast(calloc(1, sizeof(SwFill))); + if (!shape->stroke->fill) return; + } + fillReset(shape->stroke->fill); +} + + +void shapeDelFill(SwShape* shape) +{ + if (!shape->fill) return; + fillFree(shape->fill); + shape->fill = nullptr; +} + + +void shapeDelStrokeFill(SwShape* shape) +{ + if (!shape->stroke->fill) return; + fillFree(shape->stroke->fill); + shape->stroke->fill = nullptr; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgSwStroke.cpp b/test/include/liblvgl/libs/thorvg/tvgSwStroke.cpp new file mode 100644 index 00000000..954250c8 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgSwStroke.cpp @@ -0,0 +1,913 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include +#include +#include "tvgSwCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static constexpr auto SW_STROKE_TAG_POINT = 1; +static constexpr auto SW_STROKE_TAG_CUBIC = 2; +static constexpr auto SW_STROKE_TAG_BEGIN = 4; +static constexpr auto SW_STROKE_TAG_END = 8; + +static inline SwFixed SIDE_TO_ROTATE(const int32_t s) +{ + return (SW_ANGLE_PI2 - static_cast(s) * SW_ANGLE_PI); +} + + +static inline void SCALE(const SwStroke& stroke, SwPoint& pt) +{ + pt.x = static_cast(pt.x * stroke.sx); + pt.y = static_cast(pt.y * stroke.sy); +} + + +static void _growBorder(SwStrokeBorder* border, uint32_t newPts) +{ + auto maxOld = border->maxPts; + auto maxNew = border->ptsCnt + newPts; + + if (maxNew <= maxOld) return; + + auto maxCur = maxOld; + + while (maxCur < maxNew) + maxCur += (maxCur >> 1) + 16; + //OPTIMIZE: use mempool! + border->pts = static_cast(realloc(border->pts, maxCur * sizeof(SwPoint))); + border->tags = static_cast(realloc(border->tags, maxCur * sizeof(uint8_t))); + border->maxPts = maxCur; +} + + +static void _borderClose(SwStrokeBorder* border, bool reverse) +{ + auto start = border->start; + auto count = border->ptsCnt; + + //Don't record empty paths! + if (count <= start + 1U) { + border->ptsCnt = start; + } else { + /* Copy the last point to the start of this sub-path, + since it contains the adjusted starting coordinates */ + border->ptsCnt = --count; + border->pts[start] = border->pts[count]; + + if (reverse) { + //reverse the points + auto pt1 = border->pts + start + 1; + auto pt2 = border->pts + count - 1; + + while (pt1 < pt2) { + auto tmp = *pt1; + *pt1 = *pt2; + *pt2 = tmp; + ++pt1; + --pt2; + } + + //reverse the tags + auto tag1 = border->tags + start + 1; + auto tag2 = border->tags + count - 1; + + while (tag1 < tag2) { + auto tmp = *tag1; + *tag1 = *tag2; + *tag2 = tmp; + ++tag1; + --tag2; + } + } + + border->tags[start] |= SW_STROKE_TAG_BEGIN; + border->tags[count - 1] |= SW_STROKE_TAG_END; + } + + border->start = -1; + border->movable = false; +} + + +static void _borderCubicTo(SwStrokeBorder* border, const SwPoint& ctrl1, const SwPoint& ctrl2, const SwPoint& to) +{ + _growBorder(border, 3); + + auto pt = border->pts + border->ptsCnt; + auto tag = border->tags + border->ptsCnt; + + pt[0] = ctrl1; + pt[1] = ctrl2; + pt[2] = to; + + tag[0] = SW_STROKE_TAG_CUBIC; + tag[1] = SW_STROKE_TAG_CUBIC; + tag[2] = SW_STROKE_TAG_POINT; + + border->ptsCnt += 3; + border->movable = false; +} + + +static void _borderArcTo(SwStrokeBorder* border, const SwPoint& center, SwFixed radius, SwFixed angleStart, SwFixed angleDiff, SwStroke& stroke) +{ + constexpr SwFixed ARC_CUBIC_ANGLE = SW_ANGLE_PI / 2; + SwPoint a = {static_cast(radius), 0}; + mathRotate(a, angleStart); + SCALE(stroke, a); + a += center; + + auto total = angleDiff; + auto angle = angleStart; + auto rotate = (angleDiff >= 0) ? SW_ANGLE_PI2 : -SW_ANGLE_PI2; + + while (total != 0) { + auto step = total; + if (step > ARC_CUBIC_ANGLE) step = ARC_CUBIC_ANGLE; + else if (step < -ARC_CUBIC_ANGLE) step = -ARC_CUBIC_ANGLE; + + auto next = angle + step; + auto theta = step; + if (theta < 0) theta = -theta; + + theta >>= 1; + + //compute end point + SwPoint b = {static_cast(radius), 0}; + mathRotate(b, next); + SCALE(stroke, b); + b += center; + + //compute first and second control points + auto length = mathMulDiv(radius, mathSin(theta) * 4, (0x10000L + mathCos(theta)) * 3); + + SwPoint a2 = {static_cast(length), 0}; + mathRotate(a2, angle + rotate); + SCALE(stroke, a2); + a2 += a; + + SwPoint b2 = {static_cast(length), 0}; + mathRotate(b2, next - rotate); + SCALE(stroke, b2); + b2 += b; + + //add cubic arc + _borderCubicTo(border, a2, b2, b); + + //process the rest of the arc? + a = b; + total -= step; + angle = next; + } +} + + +static void _borderLineTo(SwStrokeBorder* border, const SwPoint& to, bool movable) +{ + if (border->movable) { + //move last point + border->pts[border->ptsCnt - 1] = to; + } else { + //don't add zero-length line_to + if (border->ptsCnt > 0 && (border->pts[border->ptsCnt - 1] - to).small()) return; + + _growBorder(border, 1); + border->pts[border->ptsCnt] = to; + border->tags[border->ptsCnt] = SW_STROKE_TAG_POINT; + border->ptsCnt += 1; + } + + border->movable = movable; +} + + +static void _borderMoveTo(SwStrokeBorder* border, SwPoint& to) +{ + //close current open path if any? + if (border->start >= 0) _borderClose(border, false); + + border->start = border->ptsCnt; + border->movable = false; + + _borderLineTo(border, to, false); +} + + +static void _arcTo(SwStroke& stroke, int32_t side) +{ + auto border = stroke.borders + side; + auto rotate = SIDE_TO_ROTATE(side); + auto total = mathDiff(stroke.angleIn, stroke.angleOut); + if (total == SW_ANGLE_PI) total = -rotate * 2; + + _borderArcTo(border, stroke.center, stroke.width, stroke.angleIn + rotate, total, stroke); + border->movable = false; +} + + +static void _outside(SwStroke& stroke, int32_t side, SwFixed lineLength) +{ + auto border = stroke.borders + side; + + if (stroke.join == StrokeJoin::Round) { + _arcTo(stroke, side); + } else { + //this is a mitered (pointed) or beveled (truncated) corner + auto rotate = SIDE_TO_ROTATE(side); + auto bevel = (stroke.join == StrokeJoin::Bevel) ? true : false; + SwFixed phi = 0; + SwFixed thcos = 0; + + if (!bevel) { + auto theta = mathDiff(stroke.angleIn, stroke.angleOut); + if (theta == SW_ANGLE_PI) { + theta = rotate; + phi = stroke.angleIn; + } else { + theta /= 2; + phi = stroke.angleIn + theta + rotate; + } + + thcos = mathCos(theta); + auto sigma = mathMultiply(stroke.miterlimit, thcos); + + //is miter limit exceeded? + if (sigma < 0x10000L) bevel = true; + } + + //this is a bevel (broken angle) + if (bevel) { + SwPoint delta = {static_cast(stroke.width), 0}; + mathRotate(delta, stroke.angleOut + rotate); + SCALE(stroke, delta); + delta += stroke.center; + border->movable = false; + _borderLineTo(border, delta, false); + //this is a miter (intersection) + } else { + auto length = mathDivide(stroke.width, thcos); + SwPoint delta = {static_cast(length), 0}; + mathRotate(delta, phi); + SCALE(stroke, delta); + delta += stroke.center; + _borderLineTo(border, delta, false); + + /* Now add and end point + Only needed if not lineto (lineLength is zero for curves) */ + if (lineLength == 0) { + delta = {static_cast(stroke.width), 0}; + mathRotate(delta, stroke.angleOut + rotate); + SCALE(stroke, delta); + delta += stroke.center; + _borderLineTo(border, delta, false); + } + } + } +} + + +static void _inside(SwStroke& stroke, int32_t side, SwFixed lineLength) +{ + auto border = stroke.borders + side; + auto theta = mathDiff(stroke.angleIn, stroke.angleOut) / 2; + SwPoint delta; + bool intersect = false; + + /* Only intersect borders if between two line_to's and both + lines are long enough (line length is zero for curves). */ + if (border->movable && lineLength > 0) { + //compute minimum required length of lines + SwFixed minLength = abs(mathMultiply(stroke.width, mathTan(theta))); + if (stroke.lineLength >= minLength && lineLength >= minLength) intersect = true; + } + + auto rotate = SIDE_TO_ROTATE(side); + + if (!intersect) { + delta = {static_cast(stroke.width), 0}; + mathRotate(delta, stroke.angleOut + rotate); + SCALE(stroke, delta); + delta += stroke.center; + border->movable = false; + } else { + //compute median angle + auto phi = stroke.angleIn + theta; + auto thcos = mathCos(theta); + delta = {static_cast(mathDivide(stroke.width, thcos)), 0}; + mathRotate(delta, phi + rotate); + SCALE(stroke, delta); + delta += stroke.center; + } + + _borderLineTo(border, delta, false); +} + + +void _processCorner(SwStroke& stroke, SwFixed lineLength) +{ + auto turn = mathDiff(stroke.angleIn, stroke.angleOut); + + //no specific corner processing is required if the turn is 0 + if (turn == 0) return; + + //when we turn to the right, the inside side is 0 + int32_t inside = 0; + + //otherwise, the inside is 1 + if (turn < 0) inside = 1; + + //process the inside + _inside(stroke, inside, lineLength); + + //process the outside + _outside(stroke, 1 - inside, lineLength); +} + + +void _firstSubPath(SwStroke& stroke, SwFixed startAngle, SwFixed lineLength) +{ + SwPoint delta = {static_cast(stroke.width), 0}; + mathRotate(delta, startAngle + SW_ANGLE_PI2); + SCALE(stroke, delta); + + auto pt = stroke.center + delta; + auto border = stroke.borders; + _borderMoveTo(border, pt); + + pt = stroke.center - delta; + ++border; + _borderMoveTo(border, pt); + + /* Save angle, position and line length for last join + lineLength is zero for curves */ + stroke.subPathAngle = startAngle; + stroke.firstPt = false; + stroke.subPathLineLength = lineLength; +} + + +static void _lineTo(SwStroke& stroke, const SwPoint& to) +{ + auto delta = to - stroke.center; + + //a zero-length lineto is a no-op; avoid creating a spurious corner + if (delta.zero()) return; + + /* The lineLength is used to determine the intersection of strokes outlines. + The scale needs to be reverted since the stroke width has not been scaled. + An alternative option is to scale the width of the stroke properly by + calculating the mixture of the sx/sy rating on the stroke direction. */ + delta.x = static_cast(delta.x / stroke.sx); + delta.y = static_cast(delta.y / stroke.sy); + auto lineLength = mathLength(delta); + auto angle = mathAtan(delta); + + delta = {static_cast(stroke.width), 0}; + mathRotate(delta, angle + SW_ANGLE_PI2); + SCALE(stroke, delta); + + //process corner if necessary + if (stroke.firstPt) { + /* This is the first segment of a subpath. We need to add a point to each border + at their respective starting point locations. */ + _firstSubPath(stroke, angle, lineLength); + } else { + //process the current corner + stroke.angleOut = angle; + _processCorner(stroke, lineLength); + } + + //now add a line segment to both the inside and outside paths + auto border = stroke.borders; + auto side = 1; + + while (side >= 0) { + auto pt = to + delta; + + //the ends of lineto borders are movable + _borderLineTo(border, pt, true); + + delta.x = -delta.x; + delta.y = -delta.y; + + --side; + ++border; + } + + stroke.angleIn = angle; + stroke.center = to; + stroke.lineLength = lineLength; +} + + +static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl2, const SwPoint& to) +{ + SwPoint bezStack[37]; //TODO: static? + auto limit = bezStack + 32; + auto arc = bezStack; + auto firstArc = true; + arc[0] = to; + arc[1] = ctrl2; + arc[2] = ctrl1; + arc[3] = stroke.center; + + while (arc >= bezStack) { + SwFixed angleIn, angleOut, angleMid; + + //initialize with current direction + angleIn = angleOut = angleMid = stroke.angleIn; + + if (arc < limit && !mathSmallCubic(arc, angleIn, angleMid, angleOut)) { + if (stroke.firstPt) stroke.angleIn = angleIn; + mathSplitCubic(arc); + arc += 3; + continue; + } + + if (firstArc) { + firstArc = false; + //process corner if necessary + if (stroke.firstPt) { + _firstSubPath(stroke, angleIn, 0); + } else { + stroke.angleOut = angleIn; + _processCorner(stroke, 0); + } + } else if (abs(mathDiff(stroke.angleIn, angleIn)) > (SW_ANGLE_PI / 8) / 4) { + //if the deviation from one arc to the next is too great add a round corner + stroke.center = arc[3]; + stroke.angleOut = angleIn; + stroke.join = StrokeJoin::Round; + + _processCorner(stroke, 0); + + //reinstate line join style + stroke.join = stroke.joinSaved; + } + + //the arc's angle is small enough; we can add it directly to each border + auto theta1 = mathDiff(angleIn, angleMid) / 2; + auto theta2 = mathDiff(angleMid, angleOut) / 2; + auto phi1 = mathMean(angleIn, angleMid); + auto phi2 = mathMean(angleMid, angleOut); + auto length1 = mathDivide(stroke.width, mathCos(theta1)); + auto length2 = mathDivide(stroke.width, mathCos(theta2)); + SwFixed alpha0 = 0; + + //compute direction of original arc + if (stroke.handleWideStrokes) { + alpha0 = mathAtan(arc[0] - arc[3]); + } + + auto border = stroke.borders; + int32_t side = 0; + + while (side < 2) { + auto rotate = SIDE_TO_ROTATE(side); + + //compute control points + SwPoint _ctrl1 = {static_cast(length1), 0}; + mathRotate(_ctrl1, phi1 + rotate); + SCALE(stroke, _ctrl1); + _ctrl1 += arc[2]; + + SwPoint _ctrl2 = {static_cast(length2), 0}; + mathRotate(_ctrl2, phi2 + rotate); + SCALE(stroke, _ctrl2); + _ctrl2 += arc[1]; + + //compute end point + SwPoint _end = {static_cast(stroke.width), 0}; + mathRotate(_end, angleOut + rotate); + SCALE(stroke, _end); + _end += arc[0]; + + if (stroke.handleWideStrokes) { + /* determine whether the border radius is greater than the radius of + curvature of the original arc */ + auto _start = border->pts[border->ptsCnt - 1]; + auto alpha1 = mathAtan(_end - _start); + + //is the direction of the border arc opposite to that of the original arc? + if (abs(mathDiff(alpha0, alpha1)) > SW_ANGLE_PI / 2) { + + //use the sine rule to find the intersection point + auto beta = mathAtan(arc[3] - _start); + auto gamma = mathAtan(arc[0] - _end); + auto bvec = _end - _start; + auto blen = mathLength(bvec); + auto sinA = abs(mathSin(alpha1 - gamma)); + auto sinB = abs(mathSin(beta - gamma)); + auto alen = mathMulDiv(blen, sinA, sinB); + + SwPoint delta = {static_cast(alen), 0}; + mathRotate(delta, beta); + delta += _start; + + //circumnavigate the negative sector backwards + border->movable = false; + _borderLineTo(border, delta, false); + _borderLineTo(border, _end, false); + _borderCubicTo(border, _ctrl2, _ctrl1, _start); + + //and then move to the endpoint + _borderLineTo(border, _end, false); + + ++side; + ++border; + continue; + } + } + _borderCubicTo(border, _ctrl1, _ctrl2, _end); + ++side; + ++border; + } + arc -= 3; + stroke.angleIn = angleOut; + } + stroke.center = to; +} + + +static void _addCap(SwStroke& stroke, SwFixed angle, int32_t side) +{ + if (stroke.cap == StrokeCap::Square) { + auto rotate = SIDE_TO_ROTATE(side); + auto border = stroke.borders + side; + + SwPoint delta = {static_cast(stroke.width), 0}; + mathRotate(delta, angle); + SCALE(stroke, delta); + + SwPoint delta2 = {static_cast(stroke.width), 0}; + mathRotate(delta2, angle + rotate); + SCALE(stroke, delta2); + delta += stroke.center + delta2; + + _borderLineTo(border, delta, false); + + delta = {static_cast(stroke.width), 0}; + mathRotate(delta, angle); + SCALE(stroke, delta); + + delta2 = {static_cast(stroke.width), 0}; + mathRotate(delta2, angle - rotate); + SCALE(stroke, delta2); + delta += delta2 + stroke.center; + + _borderLineTo(border, delta, false); + + } else if (stroke.cap == StrokeCap::Round) { + + stroke.angleIn = angle; + stroke.angleOut = angle + SW_ANGLE_PI; + _arcTo(stroke, side); + return; + + } else { //Butt + auto rotate = SIDE_TO_ROTATE(side); + auto border = stroke.borders + side; + + SwPoint delta = {static_cast(stroke.width), 0}; + mathRotate(delta, angle + rotate); + SCALE(stroke, delta); + delta += stroke.center; + + _borderLineTo(border, delta, false); + + delta = {static_cast(stroke.width), 0}; + mathRotate(delta, angle - rotate); + SCALE(stroke, delta); + delta += stroke.center; + + _borderLineTo(border, delta, false); + } +} + + +static void _addReverseLeft(SwStroke& stroke, bool opened) +{ + auto right = stroke.borders + 0; + auto left = stroke.borders + 1; + auto newPts = left->ptsCnt - left->start; + + if (newPts <= 0) return; + + _growBorder(right, newPts); + + auto dstPt = right->pts + right->ptsCnt; + auto dstTag = right->tags + right->ptsCnt; + auto srcPt = left->pts + left->ptsCnt - 1; + auto srcTag = left->tags + left->ptsCnt - 1; + + while (srcPt >= left->pts + left->start) { + *dstPt = *srcPt; + *dstTag = *srcTag; + + if (opened) { + dstTag[0] &= ~(SW_STROKE_TAG_BEGIN | SW_STROKE_TAG_END); + } else { + //switch begin/end tags if necessary + auto ttag = dstTag[0] & (SW_STROKE_TAG_BEGIN | SW_STROKE_TAG_END); + if (ttag == SW_STROKE_TAG_BEGIN || ttag == SW_STROKE_TAG_END) + dstTag[0] ^= (SW_STROKE_TAG_BEGIN | SW_STROKE_TAG_END); + } + --srcPt; + --srcTag; + ++dstPt; + ++dstTag; + } + + left->ptsCnt = left->start; + right->ptsCnt += newPts; + right->movable = false; + left->movable = false; +} + + +static void _beginSubPath(SwStroke& stroke, const SwPoint& to, bool closed) +{ + /* We cannot process the first point because there is not enough + information regarding its corner/cap. Later, it will be processed + in the _endSubPath() */ + + stroke.firstPt = true; + stroke.center = to; + stroke.closedSubPath = closed; + + /* Determine if we need to check whether the border radius is greater + than the radius of curvature of a curve, to handle this case specially. + This is only required if bevel joins or butt caps may be created because + round & miter joins and round & square caps cover the negative sector + created with wide strokes. */ + if ((stroke.join != StrokeJoin::Round) || (!stroke.closedSubPath && stroke.cap == StrokeCap::Butt)) + stroke.handleWideStrokes = true; + else + stroke.handleWideStrokes = false; + + stroke.ptStartSubPath = to; + stroke.angleIn = 0; +} + + +static void _endSubPath(SwStroke& stroke) +{ + if (stroke.closedSubPath) { + //close the path if needed + if (stroke.center != stroke.ptStartSubPath) + _lineTo(stroke, stroke.ptStartSubPath); + + //process the corner + stroke.angleOut = stroke.subPathAngle; + auto turn = mathDiff(stroke.angleIn, stroke.angleOut); + + //No specific corner processing is required if the turn is 0 + if (turn != 0) { + //when we turn to the right, the inside is 0 + int32_t inside = 0; + + //otherwise, the inside is 1 + if (turn < 0) inside = 1; + + _inside(stroke, inside, stroke.subPathLineLength); //inside + _outside(stroke, 1 - inside, stroke.subPathLineLength); //outside + } + + _borderClose(stroke.borders + 0, false); + _borderClose(stroke.borders + 1, true); + } else { + auto right = stroke.borders; + + /* all right, this is an opened path, we need to add a cap between + right & left, add the reverse of left, then add a final cap + between left & right */ + _addCap(stroke, stroke.angleIn, 0); + + //add reversed points from 'left' to 'right' + _addReverseLeft(stroke, true); + + //now add the final cap + stroke.center = stroke.ptStartSubPath; + _addCap(stroke, stroke.subPathAngle + SW_ANGLE_PI, 0); + + /* now end the right subpath accordingly. The left one is rewind + and doesn't need further processing */ + _borderClose(right, false); + } +} + + +static void _getCounts(SwStrokeBorder* border, uint32_t& ptsCnt, uint32_t& cntrsCnt) +{ + auto count = border->ptsCnt; + auto tags = border->tags; + uint32_t _ptsCnt = 0; + uint32_t _cntrsCnt = 0; + bool inCntr = false; + + while (count > 0) { + if (tags[0] & SW_STROKE_TAG_BEGIN) { + if (inCntr) goto fail; + inCntr = true; + } else if (!inCntr) goto fail; + + if (tags[0] & SW_STROKE_TAG_END) { + inCntr = false; + ++_cntrsCnt; + } + --count; + ++_ptsCnt; + ++tags; + } + + if (inCntr) goto fail; + + ptsCnt = _ptsCnt; + cntrsCnt = _cntrsCnt; + + return; + +fail: + ptsCnt = 0; + cntrsCnt = 0; +} + + +static void _exportBorderOutline(const SwStroke& stroke, SwOutline* outline, uint32_t side) +{ + auto border = stroke.borders + side; + if (border->ptsCnt == 0) return; + + memcpy(outline->pts.data + outline->pts.count, border->pts, border->ptsCnt * sizeof(SwPoint)); + + auto cnt = border->ptsCnt; + auto src = border->tags; + auto tags = outline->types.data + outline->types.count; + auto idx = outline->pts.count; + + while (cnt > 0) { + if (*src & SW_STROKE_TAG_POINT) *tags = SW_CURVE_TYPE_POINT; + else if (*src & SW_STROKE_TAG_CUBIC) *tags = SW_CURVE_TYPE_CUBIC; + else TVGERR("SW_ENGINE", "Invalid stroke tag was given! = %d", *src); + if (*src & SW_STROKE_TAG_END) outline->cntrs.push(idx); + ++src; + ++tags; + ++idx; + --cnt; + } + outline->pts.count += border->ptsCnt; + outline->types.count += border->ptsCnt; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void strokeFree(SwStroke* stroke) +{ + if (!stroke) return; + + //free borders + if (stroke->borders[0].pts) free(stroke->borders[0].pts); + if (stroke->borders[0].tags) free(stroke->borders[0].tags); + if (stroke->borders[1].pts) free(stroke->borders[1].pts); + if (stroke->borders[1].tags) free(stroke->borders[1].tags); + + fillFree(stroke->fill); + stroke->fill = nullptr; + + free(stroke); +} + + +void strokeReset(SwStroke* stroke, const RenderShape* rshape, const Matrix* transform) +{ + if (transform) { + stroke->sx = sqrtf(powf(transform->e11, 2.0f) + powf(transform->e21, 2.0f)); + stroke->sy = sqrtf(powf(transform->e12, 2.0f) + powf(transform->e22, 2.0f)); + } else { + stroke->sx = stroke->sy = 1.0f; + } + + stroke->width = HALF_STROKE(rshape->strokeWidth()); + stroke->cap = rshape->strokeCap(); + stroke->miterlimit = static_cast(rshape->strokeMiterlimit()) << 16; + + //Save line join: it can be temporarily changed when stroking curves... + stroke->joinSaved = stroke->join = rshape->strokeJoin(); + + stroke->borders[0].ptsCnt = 0; + stroke->borders[0].start = -1; + stroke->borders[1].ptsCnt = 0; + stroke->borders[1].start = -1; +} + + +bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline) +{ + uint32_t first = 0; + uint32_t i = 0; + + for (auto cntr = outline.cntrs.begin(); cntr < outline.cntrs.end(); ++cntr, ++i) { + auto last = *cntr; //index of last point in contour + auto limit = outline.pts.data + last; + + //Skip empty points + if (last <= first) { + first = last + 1; + continue; + } + + auto start = outline.pts[first]; + auto pt = outline.pts.data + first; + auto types = outline.types.data + first; + auto type = types[0]; + + //A contour cannot start with a cubic control point + if (type == SW_CURVE_TYPE_CUBIC) return false; + + auto closed = outline.closed.data ? outline.closed.data[i]: false; + + _beginSubPath(*stroke, start, closed); + + while (pt < limit) { + ++pt; + ++types; + + //emit a single line_to + if (types[0] == SW_CURVE_TYPE_POINT) { + _lineTo(*stroke, *pt); + //types cubic + } else { + if (pt + 1 > limit || types[1] != SW_CURVE_TYPE_CUBIC) return false; + + pt += 2; + types += 2; + + if (pt <= limit) { + _cubicTo(*stroke, pt[-2], pt[-1], pt[0]); + continue; + } + _cubicTo(*stroke, pt[-2], pt[-1], start); + goto close; + } + } + close: + if (!stroke->firstPt) _endSubPath(*stroke); + first = last + 1; + } + return true; +} + + +SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid) +{ + uint32_t count1, count2, count3, count4; + + _getCounts(stroke->borders + 0, count1, count2); + _getCounts(stroke->borders + 1, count3, count4); + + auto ptsCnt = count1 + count3; + auto cntrsCnt = count2 + count4; + + auto outline = mpoolReqStrokeOutline(mpool, tid); + outline->pts.reserve(ptsCnt); + outline->types.reserve(ptsCnt); + outline->cntrs.reserve(cntrsCnt); + + _exportBorderOutline(*stroke, outline, 0); //left + _exportBorderOutline(*stroke, outline, 1); //right + + return outline; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgTaskScheduler.cpp b/test/include/liblvgl/libs/thorvg/tvgTaskScheduler.cpp new file mode 100644 index 00000000..b5c7c2ed --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgTaskScheduler.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgArray.h" +#include "tvgInlist.h" +#include "tvgTaskScheduler.h" + +#ifdef THORVG_THREAD_SUPPORT + #include + #include +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +namespace tvg { + +struct TaskSchedulerImpl; +static TaskSchedulerImpl* inst = nullptr; + +#ifdef THORVG_THREAD_SUPPORT + +static thread_local bool _async = true; + +struct TaskQueue { + Inlist taskDeque; + mutex mtx; + condition_variable ready; + bool done = false; + + bool tryPop(Task** task) + { + unique_lock lock{mtx, try_to_lock}; + if (!lock || taskDeque.empty()) return false; + *task = taskDeque.front(); + return true; + } + + bool tryPush(Task* task) + { + { + unique_lock lock{mtx, try_to_lock}; + if (!lock) return false; + taskDeque.back(task); + } + ready.notify_one(); + return true; + } + + void complete() + { + { + lock_guard lock{mtx}; + done = true; + } + ready.notify_all(); + } + + bool pop(Task** task) + { + unique_lock lock{mtx}; + + while (taskDeque.empty() && !done) { + ready.wait(lock); + } + + if (taskDeque.empty()) return false; + + *task = taskDeque.front(); + return true; + } + + void push(Task* task) + { + { + lock_guard lock{mtx}; + taskDeque.back(task); + } + ready.notify_one(); + } +}; + + +struct TaskSchedulerImpl +{ + Array threads; + Array taskQueues; + atomic idx{0}; + + TaskSchedulerImpl(uint32_t threadCnt) + { + threads.reserve(threadCnt); + taskQueues.reserve(threadCnt); + + for (uint32_t i = 0; i < threadCnt; ++i) { + taskQueues.push(new TaskQueue); + threads.push(new thread); + } + for (uint32_t i = 0; i < threadCnt; ++i) { + *threads.data[i] = thread([&, i] { run(i); }); + } + } + + ~TaskSchedulerImpl() + { + for (auto tq = taskQueues.begin(); tq < taskQueues.end(); ++tq) { + (*tq)->complete(); + } + for (auto thread = threads.begin(); thread < threads.end(); ++thread) { + (*thread)->join(); + delete(*thread); + } + for (auto tq = taskQueues.begin(); tq < taskQueues.end(); ++tq) { + delete(*tq); + } + } + + void run(unsigned i) + { + Task* task; + + //Thread Loop + while (true) { + auto success = false; + for (uint32_t x = 0; x < threads.count * 2; ++x) { + if (taskQueues[(i + x) % threads.count]->tryPop(&task)) { + success = true; + break; + } + } + + if (!success && !taskQueues[i]->pop(&task)) break; + (*task)(i + 1); + } + } + + void request(Task* task) + { + //Async + if (threads.count > 0 && _async) { + task->prepare(); + auto i = idx++; + for (uint32_t n = 0; n < threads.count; ++n) { + if (taskQueues[(i + n) % threads.count]->tryPush(task)) return; + } + taskQueues[i % threads.count]->push(task); + //Sync + } else { + task->run(0); + } + } + + uint32_t threadCnt() + { + return threads.count; + } +}; + +#else //THORVG_THREAD_SUPPORT + +static bool _async = true; + +struct TaskSchedulerImpl +{ + TaskSchedulerImpl(TVG_UNUSED uint32_t threadCnt) {} + void request(Task* task) { task->run(0); } + uint32_t threadCnt() { return 0; } +}; + +#endif //THORVG_THREAD_SUPPORT + +} //namespace + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void TaskScheduler::init(uint32_t threads) +{ + if (inst) return; + inst = new TaskSchedulerImpl(threads); +} + + +void TaskScheduler::term() +{ + delete(inst); + inst = nullptr; +} + + +void TaskScheduler::request(Task* task) +{ + if (inst) inst->request(task); +} + + +uint32_t TaskScheduler::threads() +{ + if (inst) return inst->threadCnt(); + return 0; +} + + +void TaskScheduler::async(bool on) +{ + //toggle async tasking for each thread on/off + _async = on; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgTaskScheduler.h b/test/include/liblvgl/libs/thorvg/tvgTaskScheduler.h new file mode 100644 index 00000000..af1334b7 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgTaskScheduler.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_TASK_SCHEDULER_H_ +#define _TVG_TASK_SCHEDULER_H_ + +#include +#include + +#include "tvgCommon.h" +#include "tvgInlist.h" + +namespace tvg { + +#ifdef THORVG_THREAD_SUPPORT + +struct Task +{ +private: + mutex mtx; + condition_variable cv; + bool ready = true; + bool pending = false; + +public: + INLIST_ITEM(Task); + + virtual ~Task() = default; + + void done() + { + if (!pending) return; + + unique_lock lock(mtx); + while (!ready) cv.wait(lock); + pending = false; + } + +protected: + virtual void run(unsigned tid) = 0; + +private: + void operator()(unsigned tid) + { + run(tid); + + lock_guard lock(mtx); + ready = true; + cv.notify_one(); + } + + void prepare() + { + ready = false; + pending = true; + } + + friend struct TaskSchedulerImpl; +}; + +#else //THORVG_THREAD_SUPPORT + +struct Task +{ +public: + INLIST_ITEM(Task); + + virtual ~Task() = default; + void done() {} + +protected: + virtual void run(unsigned tid) = 0; + +private: + friend struct TaskSchedulerImpl; +}; + +#endif //THORVG_THREAD_SUPPORT + + +struct TaskScheduler +{ + static uint32_t threads(); + static void init(uint32_t threads); + static void term(); + static void request(Task* task); + static void async(bool on); +}; + +} //namespace + +#endif //_TVG_TASK_SCHEDULER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgText.cpp b/test/include/liblvgl/libs/thorvg/tvgText.cpp new file mode 100644 index 00000000..6cb2b4f7 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgText.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + + +#include "tvgText.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +Text::Text() : pImpl(new Impl) +{ + Paint::pImpl->id = TVG_CLASS_ID_TEXT; +} + + +Text::~Text() +{ + delete(pImpl); +} + + +Result Text::text(const char* text) noexcept +{ + return pImpl->text(text); +} + + +Result Text::font(const char* name, float size, const char* style) noexcept +{ + return pImpl->font(name, size, style); +} + + +Result Text::load(const std::string& path) noexcept +{ + bool invalid; //invalid path + if (!LoaderMgr::loader(path, &invalid)) { + if (invalid) return Result::InvalidArguments; + else return Result::NonSupport; + } + + return Result::Success; +} + + +Result Text::unload(const std::string& path) noexcept +{ + if (LoaderMgr::retrieve(path)) return Result::Success; + return Result::InsufficientCondition; +} + + +Result Text::fill(uint8_t r, uint8_t g, uint8_t b) noexcept +{ + if (!pImpl->paint) return Result::InsufficientCondition; + + return pImpl->fill(r, g, b); +} + + +Result Text::fill(unique_ptr f) noexcept +{ + if (!pImpl->paint) return Result::InsufficientCondition; + + auto p = f.release(); + if (!p) return Result::MemoryCorruption; + + return pImpl->fill(p); +} + + +unique_ptr Text::gen() noexcept +{ + return unique_ptr(new Text); +} + + +uint32_t Text::identifier() noexcept +{ + return TVG_CLASS_ID_TEXT; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgText.h b/test/include/liblvgl/libs/thorvg/tvgText.h new file mode 100644 index 00000000..89cef187 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgText.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_TEXT_H +#define _TVG_TEXT_H + +#include +#include "tvgShape.h" +#include "tvgFill.h" + +#ifdef THORVG_TTF_LOADER_SUPPORT + #include "tvgTtfLoader.h" +#else + #include "tvgLoader.h" +#endif + +struct Text::Impl +{ + FontLoader* loader = nullptr; + Shape* paint = nullptr; + char* utf8 = nullptr; + float fontSize; + bool italic = false; + bool changed = false; + + ~Impl() + { + free(utf8); + LoaderMgr::retrieve(loader); + delete(paint); + } + + Result fill(uint8_t r, uint8_t g, uint8_t b) + { + return paint->fill(r, g, b); + } + + Result fill(Fill* f) + { + return paint->fill(cast(f)); + } + + Result text(const char* utf8) + { + free(this->utf8); + if (utf8) this->utf8 = strdup(utf8); + else this->utf8 = nullptr; + changed = true; + + return Result::Success; + } + + Result font(const char* name, float size, const char* style) + { + auto loader = LoaderMgr::loader(name); + if (!loader) return Result::InsufficientCondition; + + //Same resource has been loaded. + if (this->loader == loader) { + this->loader->sharing--; //make it sure the reference counting. + return Result::Success; + } else if (this->loader) { + LoaderMgr::retrieve(this->loader); + } + this->loader = static_cast(loader); + + if (!paint) paint = Shape::gen().release(); + + fontSize = size; + if (style && strstr(style, "italic")) italic = true; + changed = true; + return Result::Success; + } + + RenderRegion bounds(RenderMethod* renderer) + { + if (paint) return P(paint)->bounds(renderer); + else return {0, 0, 0, 0}; + } + + bool render(RenderMethod* renderer) + { + if (paint) return PP(paint)->render(renderer); + return false; + } + + bool load() + { + if (!loader) return false; + + //reload + if (changed) { + loader->request(paint, utf8, italic); + loader->read(); + changed = false; + } + if (paint) { + loader->resize(paint, fontSize, fontSize); + return true; + } + return false; + } + + RenderData update(RenderMethod* renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + { + if (!load()) return nullptr; + + //transform the gradient coordinates based on the final scaled font. + if (P(paint)->flag & RenderUpdateFlag::Gradient) { + auto fill = P(paint)->rs.fill; + auto scale = 1.0f / loader->scale; + if (fill->identifier() == TVG_CLASS_ID_LINEAR) { + P(static_cast(fill))->x1 *= scale; + P(static_cast(fill))->y1 *= scale; + P(static_cast(fill))->x2 *= scale; + P(static_cast(fill))->y2 *= scale; + } else { + P(static_cast(fill))->cx *= scale; + P(static_cast(fill))->cy *= scale; + P(static_cast(fill))->r *= scale; + P(static_cast(fill))->fx *= scale; + P(static_cast(fill))->fy *= scale; + P(static_cast(fill))->fr *= scale; + } + } + return PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper); + } + + bool bounds(float* x, float* y, float* w, float* h, TVG_UNUSED bool stroking) + { + if (!load() || !paint) return false; + paint->bounds(x, y, w, h, true); + return true; + } + + Paint* duplicate() + { + load(); + + auto ret = Text::gen().release(); + auto dup = ret->pImpl; + if (paint) dup->paint = static_cast(paint->duplicate()); + + if (loader) { + dup->loader = loader; + ++dup->loader->sharing; + } + + dup->utf8 = strdup(utf8); + dup->italic = italic; + dup->fontSize = fontSize; + + return ret; + } + + Iterator* iterator() + { + return nullptr; + } +}; + + + +#endif //_TVG_TEXT_H + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgWgCanvas.cpp b/test/include/liblvgl/libs/thorvg/tvgWgCanvas.cpp new file mode 100644 index 00000000..3bdaec9e --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgWgCanvas.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgCanvas.h" + +#ifdef THORVG_WG_RASTER_SUPPORT + #include "tvgWgRenderer.h" +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct WgCanvas::Impl +{ +}; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +#ifdef THORVG_WG_RASTER_SUPPORT +WgCanvas::WgCanvas() : Canvas(WgRenderer::gen()), pImpl(new Impl) +#else +WgCanvas::WgCanvas() : Canvas(nullptr), pImpl(nullptr) +#endif +{ +} + +WgCanvas::~WgCanvas() +{ + delete pImpl; +} + +Result WgCanvas::target(void* window, uint32_t w, uint32_t h) noexcept +{ +#ifdef THORVG_WG_RASTER_SUPPORT + if (!window) return Result::InvalidArguments; + if ((w == 0) || (h == 0)) return Result::InvalidArguments; + + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast(Canvas::pImpl->renderer); + if (!renderer) return Result::MemoryCorruption; + + if (!renderer->target(window, w, h)) return Result::Unknown; + Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; + renderer->viewport(Canvas::pImpl->vport); + + //Paints must be updated again with this new target. + Canvas::pImpl->needRefresh(); + + return Result::Success; +#endif + return Result::NonSupport; +} + +unique_ptr WgCanvas::gen() noexcept +{ +#ifdef THORVG_WG_RASTER_SUPPORT + return unique_ptr(new WgCanvas); +#endif + return nullptr; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgXmlParser.cpp b/test/include/liblvgl/libs/thorvg/tvgXmlParser.cpp new file mode 100644 index 00000000..ffb9b5df --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgXmlParser.cpp @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include +#include +#include + +#ifdef _WIN32 + #include +#elif defined(__linux__) + #include +#else + #include +#endif + +#include "tvgXmlParser.h" +#include "tvgStr.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +bool _isIgnoreUnsupportedLogAttributes(TVG_UNUSED const char* tagAttribute, TVG_UNUSED const char* tagValue) +{ +#ifdef THORVG_LOG_ENABLED + const auto attributesNum = 6; + const struct + { + const char* tag; + bool tagWildcard; //If true, it is assumed that a wildcard is used after the tag. (ex: tagName*) + const char* value; + } attributes[] = { + {"id", false, nullptr}, + {"data-name", false, nullptr}, + {"overflow", false, "visible"}, + {"version", false, nullptr}, + {"xmlns", true, nullptr}, + {"xml:space", false, nullptr}, + }; + + for (unsigned int i = 0; i < attributesNum; ++i) { + if (!strncmp(tagAttribute, attributes[i].tag, attributes[i].tagWildcard ? strlen(attributes[i].tag) : strlen(tagAttribute))) { + if (attributes[i].value && tagValue) { + if (!strncmp(tagValue, attributes[i].value, strlen(tagValue))) { + return true; + } else continue; + } + return true; + } + } + return false; +#endif + return true; +} + + +static const char* _simpleXmlFindWhiteSpace(const char* itr, const char* itrEnd) +{ + for (; itr < itrEnd; itr++) { + if (isspace((unsigned char)*itr)) break; + } + return itr; +} + + +static const char* _simpleXmlSkipWhiteSpace(const char* itr, const char* itrEnd) +{ + for (; itr < itrEnd; itr++) { + if (!isspace((unsigned char)*itr)) break; + } + return itr; +} + + +static const char* _simpleXmlUnskipWhiteSpace(const char* itr, const char* itrStart) +{ + for (itr--; itr > itrStart; itr--) { + if (!isspace((unsigned char)*itr)) break; + } + return itr + 1; +} + + +static const char* _simpleXmlSkipXmlEntities(const char* itr, const char* itrEnd) +{ + auto p = itr; + while (itr < itrEnd && *itr == '&') { + for (int i = 0; i < NUMBER_OF_XML_ENTITIES; ++i) { + if (strncmp(itr, xmlEntity[i], xmlEntityLength[i]) == 0) { + itr += xmlEntityLength[i]; + break; + } + } + if (itr == p) break; + p = itr; + } + return itr; +} + + +static const char* _simpleXmlUnskipXmlEntities(const char* itr, const char* itrStart) +{ + auto p = itr; + while (itr > itrStart && *(itr - 1) == ';') { + for (int i = 0; i < NUMBER_OF_XML_ENTITIES; ++i) { + if (itr - xmlEntityLength[i] > itrStart && + strncmp(itr - xmlEntityLength[i], xmlEntity[i], xmlEntityLength[i]) == 0) { + itr -= xmlEntityLength[i]; + break; + } + } + if (itr == p) break; + p = itr; + } + return itr; +} + + +static const char* _skipWhiteSpacesAndXmlEntities(const char* itr, const char* itrEnd) +{ + itr = _simpleXmlSkipWhiteSpace(itr, itrEnd); + auto p = itr; + while (true) { + if (p != (itr = _simpleXmlSkipXmlEntities(itr, itrEnd))) p = itr; + else break; + if (p != (itr = _simpleXmlSkipWhiteSpace(itr, itrEnd))) p = itr; + else break; + } + return itr; +} + + +static const char* _unskipWhiteSpacesAndXmlEntities(const char* itr, const char* itrStart) +{ + itr = _simpleXmlUnskipWhiteSpace(itr, itrStart); + auto p = itr; + while (true) { + if (p != (itr = _simpleXmlUnskipXmlEntities(itr, itrStart))) p = itr; + else break; + if (p != (itr = _simpleXmlUnskipWhiteSpace(itr, itrStart))) p = itr; + else break; + } + return itr; +} + + +static const char* _simpleXmlFindStartTag(const char* itr, const char* itrEnd) +{ + return (const char*)memchr(itr, '<', itrEnd - itr); +} + + +static const char* _simpleXmlFindEndTag(const char* itr, const char* itrEnd) +{ + bool insideQuote[2] = {false, false}; // 0: ", 1: ' + for (; itr < itrEnd; itr++) { + if (*itr == '"' && !insideQuote[1]) insideQuote[0] = !insideQuote[0]; + if (*itr == '\'' && !insideQuote[0]) insideQuote[1] = !insideQuote[1]; + if (!insideQuote[0] && !insideQuote[1]) { + if ((*itr == '>') || (*itr == '<')) + return itr; + } + } + return nullptr; +} + + +static const char* _simpleXmlFindEndCommentTag(const char* itr, const char* itrEnd) +{ + for (; itr < itrEnd; itr++) { + if ((*itr == '-') && ((itr + 1 < itrEnd) && (*(itr + 1) == '-')) && ((itr + 2 < itrEnd) && (*(itr + 2) == '>'))) return itr + 2; + } + return nullptr; +} + + +static const char* _simpleXmlFindEndCdataTag(const char* itr, const char* itrEnd) +{ + for (; itr < itrEnd; itr++) { + if ((*itr == ']') && ((itr + 1 < itrEnd) && (*(itr + 1) == ']')) && ((itr + 2 < itrEnd) && (*(itr + 2) == '>'))) return itr + 2; + } + return nullptr; +} + + +static const char* _simpleXmlFindDoctypeChildEndTag(const char* itr, const char* itrEnd) +{ + for (; itr < itrEnd; itr++) { + if (*itr == '>') return itr; + } + return nullptr; +} + + +static SimpleXMLType _getXMLType(const char* itr, const char* itrEnd, size_t &toff) +{ + toff = 0; + if (itr[1] == '/') { + toff = 1; + return SimpleXMLType::Close; + } else if (itr[1] == '?') { + toff = 1; + return SimpleXMLType::Processing; + } else if (itr[1] == '!') { + if ((itr + sizeof("") - 1 < itrEnd) && (!memcmp(itr + 2, "DOCTYPE", sizeof("DOCTYPE") - 1)) && ((itr[2 + sizeof("DOCTYPE") - 1] == '>') || (isspace((unsigned char)itr[2 + sizeof("DOCTYPE") - 1])))) { + toff = sizeof("!DOCTYPE") - 1; + return SimpleXMLType::Doctype; + } else if ((itr + sizeof("") - 1 < itrEnd) && (!memcmp(itr + 2, "[CDATA[", sizeof("[CDATA[") - 1))) { + toff = sizeof("![CDATA[") - 1; + return SimpleXMLType::CData; + } else if ((itr + sizeof("") - 1 < itrEnd) && (!memcmp(itr + 2, "--", sizeof("--") - 1))) { + toff = sizeof("!--") - 1; + return SimpleXMLType::Comment; + } else if (itr + sizeof("") - 1 < itrEnd) { + toff = sizeof("!") - 1; + return SimpleXMLType::DoctypeChild; + } + return SimpleXMLType::Open; + } + return SimpleXMLType::Open; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +const char* simpleXmlNodeTypeToString(TVG_UNUSED SvgNodeType type) +{ +#ifdef THORVG_LOG_ENABLED + static const char* TYPE_NAMES[] = { + "Svg", + "G", + "Defs", + "Animation", + "Arc", + "Circle", + "Ellipse", + "Image", + "Line", + "Path", + "Polygon", + "Polyline", + "Rect", + "Text", + "TextArea", + "Tspan", + "Use", + "Video", + "ClipPath", + "Mask", + "Symbol", + "Unknown", + }; + return TYPE_NAMES[(int) type]; +#endif + return nullptr; +} + + +bool isIgnoreUnsupportedLogElements(TVG_UNUSED const char* tagName) +{ +#ifdef THORVG_LOG_ENABLED + const auto elementsNum = 1; + const char* const elements[] = { "title" }; + + for (unsigned int i = 0; i < elementsNum; ++i) { + if (!strncmp(tagName, elements[i], strlen(tagName))) { + return true; + } + } + return false; +#else + return true; +#endif +} + + +bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data) +{ + const char *itr = buf, *itrEnd = buf + bufLength; + char* tmpBuf = (char*)malloc(bufLength + 1); + + if (!buf || !func || !tmpBuf) goto error; + + while (itr < itrEnd) { + const char* p = _skipWhiteSpacesAndXmlEntities(itr, itrEnd); + const char *key, *keyEnd, *value, *valueEnd; + char* tval; + + if (p == itrEnd) goto success; + + key = p; + for (keyEnd = key; keyEnd < itrEnd; keyEnd++) { + if ((*keyEnd == '=') || (isspace((unsigned char)*keyEnd))) break; + } + if (keyEnd == itrEnd) goto error; + if (keyEnd == key) { // There is no key. This case is invalid, but explores the following syntax. + itr = keyEnd + 1; + continue; + } + + if (*keyEnd == '=') value = keyEnd + 1; + else { + value = (const char*)memchr(keyEnd, '=', itrEnd - keyEnd); + if (!value) goto error; + value++; + } + keyEnd = _simpleXmlUnskipXmlEntities(keyEnd, key); + + value = _skipWhiteSpacesAndXmlEntities(value, itrEnd); + if (value == itrEnd) goto error; + + if ((*value == '"') || (*value == '\'')) { + valueEnd = (const char*)memchr(value + 1, *value, itrEnd - value); + if (!valueEnd) goto error; + value++; + } else { + valueEnd = _simpleXmlFindWhiteSpace(value, itrEnd); + } + + itr = valueEnd + 1; + + value = _skipWhiteSpacesAndXmlEntities(value, itrEnd); + valueEnd = _unskipWhiteSpacesAndXmlEntities(valueEnd, value); + + memcpy(tmpBuf, key, keyEnd - key); + tmpBuf[keyEnd - key] = '\0'; + + tval = tmpBuf + (keyEnd - key) + 1; + int i = 0; + while (value < valueEnd) { + value = _simpleXmlSkipXmlEntities(value, valueEnd); + tval[i++] = *value; + value++; + } + tval[i] = '\0'; + + if (!func((void*)data, tmpBuf, tval)) { + if (!_isIgnoreUnsupportedLogAttributes(tmpBuf, tval)) { + TVGLOG("SVG", "Unsupported attributes used [Elements type: %s][Id : %s][Attribute: %s][Value: %s]", simpleXmlNodeTypeToString(((SvgLoaderData*)data)->svgParse->node->type), ((SvgLoaderData*)data)->svgParse->node->id ? ((SvgLoaderData*)data)->svgParse->node->id : "NO_ID", tmpBuf, tval ? tval : "NONE"); + } + } + } + +success: + free(tmpBuf); + return true; + +error: + free(tmpBuf); + return false; +} + + +bool simpleXmlParse(const char* buf, unsigned bufLength, bool strip, simpleXMLCb func, const void* data) +{ + const char *itr = buf, *itrEnd = buf + bufLength; + + if (!buf || !func) return false; + + while (itr < itrEnd) { + if (itr[0] == '<') { + //Invalid case + if (itr + 1 >= itrEnd) return false; + + size_t toff = 0; + SimpleXMLType type = _getXMLType(itr, itrEnd, toff); + + const char* p; + if (type == SimpleXMLType::CData) p = _simpleXmlFindEndCdataTag(itr + 1 + toff, itrEnd); + else if (type == SimpleXMLType::DoctypeChild) p = _simpleXmlFindDoctypeChildEndTag(itr + 1 + toff, itrEnd); + else if (type == SimpleXMLType::Comment) p = _simpleXmlFindEndCommentTag(itr + 1 + toff, itrEnd); + else p = _simpleXmlFindEndTag(itr + 1 + toff, itrEnd); + + if (p) { + //Invalid case: '<' nested + if (*p == '<' && type != SimpleXMLType::Doctype) return false; + const char *start, *end; + + start = itr + 1 + toff; + end = p; + + switch (type) { + case SimpleXMLType::Open: { + if (p[-1] == '/') { + type = SimpleXMLType::OpenEmpty; + end--; + } + break; + } + case SimpleXMLType::CData: { + if (!memcmp(p - 2, "]]", 2)) end -= 2; + break; + } + case SimpleXMLType::Processing: { + if (p[-1] == '?') end--; + break; + } + case SimpleXMLType::Comment: { + if (!memcmp(p - 2, "--", 2)) end -= 2; + break; + } + default: { + break; + } + } + + if (strip && (type != SimpleXMLType::CData)) { + start = _skipWhiteSpacesAndXmlEntities(start, end); + end = _unskipWhiteSpacesAndXmlEntities(end, start); + } + + if (!func((void*)data, type, start, (unsigned int)(end - start))) return false; + + itr = p + 1; + } else { + return false; + } + } else { + const char *p, *end; + + if (strip) { + p = itr; + p = _skipWhiteSpacesAndXmlEntities(p, itrEnd); + if (p) { + if (!func((void*)data, SimpleXMLType::Ignored, itr, (unsigned int)(p - itr))) return false; + itr = p; + } + } + + p = _simpleXmlFindStartTag(itr, itrEnd); + if (!p) p = itrEnd; + + end = p; + if (strip) end = _unskipWhiteSpacesAndXmlEntities(end, itr); + + if (itr != end && !func((void*)data, SimpleXMLType::Data, itr, (unsigned int)(end - itr))) return false; + + if (strip && (end < p) && !func((void*)data, SimpleXMLType::Ignored, end, (unsigned int)(p - end))) return false; + + itr = p; + } + } + return true; +} + + +bool simpleXmlParseW3CAttribute(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data) +{ + const char* end; + char* key; + char* val; + char* next; + + if (!buf) return false; + + end = buf + bufLength; + key = (char*)alloca(end - buf + 1); + val = (char*)alloca(end - buf + 1); + + if (buf == end) return true; + + do { + char* sep = (char*)strchr(buf, ':'); + next = (char*)strchr(buf, ';'); + if (sep >= end) { + next = nullptr; + sep = nullptr; + } + if (next >= end) next = nullptr; + + key[0] = '\0'; + val[0] = '\0'; + + if (next == nullptr && sep != nullptr) { + memcpy(key, buf, sep - buf); + key[sep - buf] = '\0'; + + memcpy(val, sep + 1, end - sep - 1); + val[end - sep - 1] = '\0'; + } else if (sep < next && sep != nullptr) { + memcpy(key, buf, sep - buf); + key[sep - buf] = '\0'; + + memcpy(val, sep + 1, next - sep - 1); + val[next - sep - 1] = '\0'; + } else if (next) { + memcpy(key, buf, next - buf); + key[next - buf] = '\0'; + } + + if (key[0]) { + key = const_cast(_simpleXmlSkipWhiteSpace(key, key + strlen(key))); + key[_simpleXmlUnskipWhiteSpace(key + strlen(key) , key) - key] = '\0'; + val = const_cast(_simpleXmlSkipWhiteSpace(val, val + strlen(val))); + val[_simpleXmlUnskipWhiteSpace(val + strlen(val) , val) - val] = '\0'; + + if (!func((void*)data, key, val)) { + if (!_isIgnoreUnsupportedLogAttributes(key, val)) { + TVGLOG("SVG", "Unsupported attributes used [Elements type: %s][Id : %s][Attribute: %s][Value: %s]", simpleXmlNodeTypeToString(((SvgLoaderData*)data)->svgParse->node->type), ((SvgLoaderData*)data)->svgParse->node->id ? ((SvgLoaderData*)data)->svgParse->node->id : "NO_ID", key, val ? val : "NONE"); + } + } + } + + buf = next + 1; + } while (next != nullptr); + + return true; +} + + +/* + * Supported formats: + * tag {}, .name {}, tag.name{} + */ +const char* simpleXmlParseCSSAttribute(const char* buf, unsigned bufLength, char** tag, char** name, const char** attrs, unsigned* attrsLength) +{ + if (!buf) return nullptr; + + *tag = *name = nullptr; + *attrsLength = 0; + + auto itr = _simpleXmlSkipWhiteSpace(buf, buf + bufLength); + auto itrEnd = (const char*)memchr(buf, '{', bufLength); + + if (!itrEnd || itr == itrEnd) return nullptr; + + auto nextElement = (const char*)memchr(itrEnd, '}', bufLength - (itrEnd - buf)); + if (!nextElement) return nullptr; + + *attrs = itrEnd + 1; + *attrsLength = nextElement - *attrs; + + const char *p; + + itrEnd = _simpleXmlUnskipWhiteSpace(itrEnd, itr); + if (*(itrEnd - 1) == '.') return nullptr; + + for (p = itr; p < itrEnd; p++) { + if (*p == '.') break; + } + + if (p == itr) *tag = strdup("all"); + else *tag = strDuplicate(itr, p - itr); + + if (p == itrEnd) *name = nullptr; + else *name = strDuplicate(p + 1, itrEnd - p - 1); + + return (nextElement ? nextElement + 1 : nullptr); +} + + +const char* simpleXmlFindAttributesTag(const char* buf, unsigned bufLength) +{ + const char *itr = buf, *itrEnd = buf + bufLength; + + for (; itr < itrEnd; itr++) { + if (!isspace((unsigned char)*itr)) { + //User skip tagname and already gave it the attributes. + if (*itr == '=') return buf; + } else { + itr = _simpleXmlUnskipXmlEntities(itr, buf); + if (itr == itrEnd) return nullptr; + return itr; + } + } + + return nullptr; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/test/include/liblvgl/libs/thorvg/tvgXmlParser.h b/test/include/liblvgl/libs/thorvg/tvgXmlParser.h new file mode 100644 index 00000000..be080686 --- /dev/null +++ b/test/include/liblvgl/libs/thorvg/tvgXmlParser.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * 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 "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_SIMPLE_XML_PARSER_H_ +#define _TVG_SIMPLE_XML_PARSER_H_ + +#include "tvgSvgLoaderCommon.h" + +#define NUMBER_OF_XML_ENTITIES 9 +const char* const xmlEntity[] = {" ", """, " ", "'", "&", "<", ">", "#", "'"}; +const int xmlEntityLength[] = {5, 6, 6, 6, 5, 4, 4, 6, 6}; + +enum class SimpleXMLType +{ + Open = 0, //!< \ + OpenEmpty, //!< \ + Close, //!< \ + Data, //!< tag text data + CData, //!< \ + Error, //!< error contents + Processing, //!< \ \ + Doctype, //!< \ + Ignored, //!< whatever is ignored by parser, like whitespace + DoctypeChild //!< \= 'width' +// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' +// +// If you don't do either of the above things, widths will be quantized to multiples +// of small integers to guarantee the algorithm doesn't run out of temporary storage. +// +// If you do #2, then the non-quantized algorithm will be used, but the algorithm +// may run out of temporary storage and be unable to pack some rectangles. + +STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context * context, int allow_out_of_mem); +// Optionally call this function after init but before doing any packing to +// change the handling of the out-of-temp-memory scenario, described above. +// If you call init again, this will be reset to the default (false). + +STBRP_DEF void stbrp_setup_heuristic(stbrp_context * context, int heuristic); +// Optionally select which packing heuristic the library should use. Different +// heuristics will produce better/worse results for different data sets. +// If you call init again, this will be reset to the default. + +enum { + STBRP_HEURISTIC_Skyline_default = 0, + STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, + STBRP_HEURISTIC_Skyline_BF_sortHeight +}; + +////////////////////////////////////////////////////////////////////////////// +// +// the details of the following structures don't matter to you, but they must +// be visible so you can handle the memory allocations for them + +struct stbrp_node { + stbrp_coord x, y; + stbrp_node * next; +}; + +struct stbrp_context { + int width; + int height; + int align; + int init_mode; + int heuristic; + int num_nodes; + stbrp_node * active_head; + stbrp_node * free_head; + stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' +}; + +#ifdef __cplusplus +} +#endif + +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// IMPLEMENTATION SECTION +// + +#ifdef STB_RECT_PACK_IMPLEMENTATION +#ifndef STBRP_SORT + #include + #define STBRP_SORT qsort +#endif + +#ifndef STBRP_ASSERT + #include + #define STBRP_ASSERT assert +#endif + +#ifdef _MSC_VER + #define STBRP__NOTUSED(v) (void)(v) + #define STBRP__CDECL __cdecl +#else + #define STBRP__NOTUSED(v) (void)sizeof(v) + #define STBRP__CDECL +#endif + +enum { + STBRP__INIT_skyline = 1 +}; + +STBRP_DEF void stbrp_setup_heuristic(stbrp_context * context, int heuristic) +{ + switch(context->init_mode) { + case STBRP__INIT_skyline: + STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); + context->heuristic = heuristic; + break; + default: + STBRP_ASSERT(0); + } +} + +STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context * context, int allow_out_of_mem) +{ + if(allow_out_of_mem) + // if it's ok to run out of memory, then don't bother aligning them; + // this gives better packing, but may fail due to OOM (even though + // the rectangles easily fit). @TODO a smarter approach would be to only + // quantize once we've hit OOM, then we could get rid of this parameter. + context->align = 1; + else { + // if it's not ok to run out of memory, then quantize the widths + // so that num_nodes is always enough nodes. + // + // I.e. num_nodes * align >= width + // align >= width / num_nodes + // align = ceil(width/num_nodes) + + context->align = (context->width + context->num_nodes - 1) / context->num_nodes; + } +} + +STBRP_DEF void stbrp_init_target(stbrp_context * context, int width, int height, stbrp_node * nodes, int num_nodes) +{ + int i; + + for(i = 0; i < num_nodes - 1; ++i) + nodes[i].next = &nodes[i + 1]; + nodes[i].next = NULL; + context->init_mode = STBRP__INIT_skyline; + context->heuristic = STBRP_HEURISTIC_Skyline_default; + context->free_head = &nodes[0]; + context->active_head = &context->extra[0]; + context->width = width; + context->height = height; + context->num_nodes = num_nodes; + stbrp_setup_allow_out_of_mem(context, 0); + + // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) + context->extra[0].x = 0; + context->extra[0].y = 0; + context->extra[0].next = &context->extra[1]; + context->extra[1].x = (stbrp_coord) width; + context->extra[1].y = (1 << 30); + context->extra[1].next = NULL; +} + +// find minimum y position if it starts at x1 +static int stbrp__skyline_find_min_y(stbrp_context * c, stbrp_node * first, int x0, int width, int * pwaste) +{ + stbrp_node * node = first; + int x1 = x0 + width; + int min_y, visited_width, waste_area; + + STBRP__NOTUSED(c); + + STBRP_ASSERT(first->x <= x0); + +#if 0 + // skip in case we're past the node + while(node->next->x <= x0) + ++node; +#else + STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency +#endif + + STBRP_ASSERT(node->x <= x0); + + min_y = 0; + waste_area = 0; + visited_width = 0; + while(node->x < x1) { + if(node->y > min_y) { + // raise min_y higher. + // we've accounted for all waste up to min_y, + // but we'll now add more waste for everything we've visited + waste_area += visited_width * (node->y - min_y); + min_y = node->y; + // the first time through, visited_width might be reduced + if(node->x < x0) + visited_width += node->next->x - x0; + else + visited_width += node->next->x - node->x; + } + else { + // add waste area + int under_width = node->next->x - node->x; + if(under_width + visited_width > width) + under_width = width - visited_width; + waste_area += under_width * (min_y - node->y); + visited_width += under_width; + } + node = node->next; + } + + *pwaste = waste_area; + return min_y; +} + +typedef struct { + int x, y; + stbrp_node ** prev_link; +} stbrp__findresult; + +static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context * c, int width, int height) +{ + int best_waste = (1 << 30), best_x, best_y = (1 << 30); + stbrp__findresult fr; + stbrp_node ** prev, * node, * tail, ** best = NULL; + + // align to multiple of c->align + width = (width + c->align - 1); + width -= width % c->align; + STBRP_ASSERT(width % c->align == 0); + + // if it can't possibly fit, bail immediately + if(width > c->width || height > c->height) { + fr.prev_link = NULL; + fr.x = fr.y = 0; + return fr; + } + + node = c->active_head; + prev = &c->active_head; + while(node->x + width <= c->width) { + int y, waste; + y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); + if(c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL + // bottom left + if(y < best_y) { + best_y = y; + best = prev; + } + } + else { + // best-fit + if(y + height <= c->height) { + // can only use it if it first vertically + if(y < best_y || (y == best_y && waste < best_waste)) { + best_y = y; + best_waste = waste; + best = prev; + } + } + } + prev = &node->next; + node = node->next; + } + + best_x = (best == NULL) ? 0 : (*best)->x; + + // if doing best-fit (BF), we also have to try aligning right edge to each node position + // + // e.g, if fitting + // + // ____________________ + // |____________________| + // + // into + // + // | | + // | ____________| + // |____________| + // + // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned + // + // This makes BF take about 2x the time + + if(c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { + tail = c->active_head; + node = c->active_head; + prev = &c->active_head; + // find first node that's admissible + while(tail->x < width) + tail = tail->next; + while(tail) { + int xpos = tail->x - width; + int y, waste; + STBRP_ASSERT(xpos >= 0); + // find the left position that matches this + while(node->next->x <= xpos) { + prev = &node->next; + node = node->next; + } + STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); + y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); + if(y + height <= c->height) { + if(y <= best_y) { + if(y < best_y || waste < best_waste || (waste == best_waste && xpos < best_x)) { + best_x = xpos; + STBRP_ASSERT(y <= best_y); + best_y = y; + best_waste = waste; + best = prev; + } + } + } + tail = tail->next; + } + } + + fr.prev_link = best; + fr.x = best_x; + fr.y = best_y; + return fr; +} + +static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context * context, int width, int height) +{ + // find best position according to heuristic + stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); + stbrp_node * node, * cur; + + // bail if: + // 1. it failed + // 2. the best node doesn't fit (we don't always check this) + // 3. we're out of memory + if(res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { + res.prev_link = NULL; + return res; + } + + // on success, create new node + node = context->free_head; + node->x = (stbrp_coord) res.x; + node->y = (stbrp_coord)(res.y + height); + + context->free_head = node->next; + + // insert the new node into the right starting point, and + // let 'cur' point to the remaining nodes needing to be + // stitched back in + + cur = *res.prev_link; + if(cur->x < res.x) { + // preserve the existing one, so start testing with the next one + stbrp_node * next = cur->next; + cur->next = node; + cur = next; + } + else { + *res.prev_link = node; + } + + // from here, traverse cur and free the nodes, until we get to one + // that shouldn't be freed + while(cur->next && cur->next->x <= res.x + width) { + stbrp_node * next = cur->next; + // move the current node to the free list + cur->next = context->free_head; + context->free_head = cur; + cur = next; + } + + // stitch the list back in + node->next = cur; + + if(cur->x < res.x + width) + cur->x = (stbrp_coord)(res.x + width); + +#ifdef _DEBUG + cur = context->active_head; + while(cur->x < context->width) { + STBRP_ASSERT(cur->x < cur->next->x); + cur = cur->next; + } + STBRP_ASSERT(cur->next == NULL); + + { + int count = 0; + cur = context->active_head; + while(cur) { + cur = cur->next; + ++count; + } + cur = context->free_head; + while(cur) { + cur = cur->next; + ++count; + } + STBRP_ASSERT(count == context->num_nodes + 2); + } +#endif + + return res; +} + +static int STBRP__CDECL rect_height_compare(const void * a, const void * b) +{ + const stbrp_rect * p = (const stbrp_rect *) a; + const stbrp_rect * q = (const stbrp_rect *) b; + if(p->h > q->h) + return -1; + if(p->h < q->h) + return 1; + return (p->w > q->w) ? -1 : (p->w < q->w); +} + +static int STBRP__CDECL rect_original_order(const void * a, const void * b) +{ + const stbrp_rect * p = (const stbrp_rect *) a; + const stbrp_rect * q = (const stbrp_rect *) b; + return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); +} + +STBRP_DEF int stbrp_pack_rects(stbrp_context * context, stbrp_rect * rects, int num_rects) +{ + int i, all_rects_packed = 1; + + // we use the 'was_packed' field internally to allow sorting/unsorting + for(i = 0; i < num_rects; ++i) { + rects[i].was_packed = i; + } + + // sort according to heuristic + STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); + + for(i = 0; i < num_rects; ++i) { + if(rects[i].w == 0 || rects[i].h == 0) { + rects[i].x = rects[i].y = 0; // empty rect needs no space + } + else { + stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); + if(fr.prev_link) { + rects[i].x = (stbrp_coord) fr.x; + rects[i].y = (stbrp_coord) fr.y; + } + else { + rects[i].x = rects[i].y = STBRP__MAXVAL; + } + } + } + + // unsort + STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); + + // set was_packed flags and all_rects_packed status + for(i = 0; i < num_rects; ++i) { + rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); + if(!rects[i].was_packed) + all_rects_packed = 0; + } + + // return the all_rects_packed status + return all_rects_packed; +} +#endif + +#if defined(__GNUC__) || defined(__clang__) + #pragma GCC diagnostic pop +#endif + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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. +------------------------------------------------------------------------------ +*/ diff --git a/test/include/liblvgl/libs/tiny_ttf/stb_truetype_htcw.h b/test/include/liblvgl/libs/tiny_ttf/stb_truetype_htcw.h new file mode 100644 index 00000000..1cd3e2ab --- /dev/null +++ b/test/include/liblvgl/libs/tiny_ttf/stb_truetype_htcw.h @@ -0,0 +1,5598 @@ +// stb_truetype.h - v1.26htcw (fork to enable streaming and low memory environments) +// stb_truetype.h - v1.26 - public domain +// authored from 2009-2021 by Sean Barrett / RAD Game Tools +// +// ======================================================================= +// +// NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES +// +// This library does no range checking of the offsets found in the file, +// meaning an attacker can use it to read arbitrary memory. +// +// ======================================================================= +// +// This library processes TrueType files: +// parse files +// extract glyph metrics +// extract glyph shapes +// render glyphs to one-channel bitmaps with antialiasing (box filter) +// render glyphs to one-channel SDF bitmaps (signed-distance field/function) +// +// Todo: +// non-MS cmaps +// crashproof on bad data +// hinting? (no longer patented) +// cleartype-style AA? +// optimize: use simple memory allocator for intermediates +// optimize: build edge-list directly from curves +// optimize: rasterize directly from curves? +// +// ADDITIONAL CONTRIBUTORS +// +// Mikko Mononen: compound shape support, more cmap formats +// Tor Andersson: kerning, subpixel rendering +// Dougall Johnson: OpenType / Type 2 font handling +// Daniel Ribeiro Maciel: basic GPOS-based kerning +// +// Misc other: +// Ryan Gordon +// Simon Glass +// github:IntellectualKitty +// Imanol Celaya +// Daniel Ribeiro Maciel +// +// Bug/warning reports/fixes: +// "Zer" on mollyrocket Fabian "ryg" Giesen github:NiLuJe +// Cass Everitt Martins Mozeiko github:aloucks +// stoiko (Haemimont Games) Cap Petschulat github:oyvindjam +// Brian Hook Omar Cornut github:vassvik +// Walter van Niftrik Ryan Griege +// David Gow Peter LaValle +// David Given Sergey Popov +// Ivan-Assen Ivanov Giumo X. Clanjor +// Anthony Pesch Higor Euripedes +// Johan Duparc Thomas Fields +// Hou Qiming Derek Vinyard +// Rob Loach Cort Stratton +// Kenney Phillis Jr. Brian Costabile +// Ken Voskuil (kaesve) +// +// VERSION HISTORY +// +// 1.26 (2021-08-28) fix broken rasterizer +// 1.25 (2021-07-11) many fixes +// 1.24 (2020-02-05) fix warning +// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS) +// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined +// 1.21 (2019-02-25) fix warning +// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics() +// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod +// 1.18 (2018-01-29) add missing function +// 1.17 (2017-07-23) make more arguments const; doc fix +// 1.16 (2017-07-12) SDF support +// 1.15 (2017-03-03) make more arguments const +// 1.14 (2017-01-16) num-fonts-in-TTC function +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts +// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual +// 1.11 (2016-04-02) fix unused-variable warning +// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef +// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly +// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges +// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; +// variant PackFontRanges to pack and render in separate phases; +// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); +// fixed an assert() bug in the new rasterizer +// replace assert() with STBTT_assert() in new rasterizer +// +// Full history can be found at the end of this file. +// +// LICENSE +// +// See end of file for license information. +// +// USAGE +// +// Include this file in whatever places need to refer to it. In ONE C/C++ +// file, write: +// #define STB_TRUETYPE_IMPLEMENTATION +// before the #include of this file. This expands out the actual +// implementation into that C/C++ file. +// +// To make the implementation private to the file that generates the implementation, +// #define STBTT_STATIC +// +// Simple 3D API (don't ship this, but it's fine for tools and quick start) +// stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture +// stbtt_GetBakedQuad() -- compute quad to draw for a given char +// +// Improved 3D API (more shippable): +// #include "stb_rect_pack.h" -- optional, but you really want it +// stbtt_PackBegin() +// stbtt_PackSetOversampling() -- for improved quality on small fonts +// stbtt_PackFontRanges() -- pack and renders +// stbtt_PackEnd() +// stbtt_GetPackedQuad() +// +// "Load" a font file from a memory buffer (you have to keep the buffer loaded) +// stbtt_InitFont() +// stbtt_GetFontOffsetForIndex() -- indexing for TTC font collections +// stbtt_GetNumberOfFonts() -- number of fonts for TTC font collections +// +// Render a unicode codepoint to a bitmap +// stbtt_GetCodepointBitmap() -- allocates and returns a bitmap +// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide +// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be +// +// Character advance/positioning +// stbtt_GetCodepointHMetrics() +// stbtt_GetFontVMetrics() +// stbtt_GetFontVMetricsOS2() +// stbtt_GetCodepointKernAdvance() +// +// Starting with version 1.06, the rasterizer was replaced with a new, +// faster and generally-more-precise rasterizer. The new rasterizer more +// accurately measures pixel coverage for anti-aliasing, except in the case +// where multiple shapes overlap, in which case it overestimates the AA pixel +// coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If +// this turns out to be a problem, you can re-enable the old rasterizer with +// #define STBTT_RASTERIZER_VERSION 1 +// which will incur about a 15% speed hit. +// +// ADDITIONAL DOCUMENTATION +// +// Immediately after this block comment are a series of sample programs. +// +// After the sample programs is the "header file" section. This section +// includes documentation for each API function. +// +// Some important concepts to understand to use this library: +// +// Codepoint +// Characters are defined by unicode codepoints, e.g. 65 is +// uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is +// the hiragana for "ma". +// +// Glyph +// A visual character shape (every codepoint is rendered as +// some glyph) +// +// Glyph index +// A font-specific integer ID representing a glyph +// +// Baseline +// Glyph shapes are defined relative to a baseline, which is the +// bottom of uppercase characters. Characters extend both above +// and below the baseline. +// +// Current Point +// As you draw text to the screen, you keep track of a "current point" +// which is the origin of each character. The current point's vertical +// position is the baseline. Even "baked fonts" use this model. +// +// Vertical Font Metrics +// The vertical qualities of the font, used to vertically position +// and space the characters. See docs for stbtt_GetFontVMetrics. +// +// Font Size in Pixels or Points +// The preferred interface for specifying font sizes in stb_truetype +// is to specify how tall the font's vertical extent should be in pixels. +// If that sounds good enough, skip the next paragraph. +// +// Most font APIs instead use "points", which are a common typographic +// measurement for describing font size, defined as 72 points per inch. +// stb_truetype provides a point API for compatibility. However, true +// "per inch" conventions don't make much sense on computer displays +// since different monitors have different number of pixels per +// inch. For example, Windows traditionally uses a convention that +// there are 96 pixels per inch, thus making 'inch' measurements have +// nothing to do with inches, and thus effectively defining a point to +// be 1.333 pixels. Additionally, the TrueType font data provides +// an explicit scale factor to scale a given font's glyphs to points, +// but the author has observed that this scale factor is often wrong +// for non-commercial fonts, thus making fonts scaled in points +// according to the TrueType spec incoherently sized in practice. +// +// DETAILED USAGE: +// +// Scale: +// Select how high you want the font to be, in points or pixels. +// Call ScaleForPixelHeight or ScaleForMappingEmToPixels to compute +// a scale factor SF that will be used by all other functions. +// +// Baseline: +// You need to select a y-coordinate that is the baseline of where +// your text will appear. Call GetFontBoundingBox to get the baseline-relative +// bounding box for all characters. SF*-y0 will be the distance in pixels +// that the worst-case character could extend above the baseline, so if +// you want the top edge of characters to appear at the top of the +// screen where y=0, then you would set the baseline to SF*-y0. +// +// Current point: +// Set the current point where the first character will appear. The +// first character could extend left of the current point; this is font +// dependent. You can either choose a current point that is the leftmost +// point and hope, or add some padding, or check the bounding box or +// left-side-bearing of the first character to be displayed and set +// the current point based on that. +// +// Displaying a character: +// Compute the bounding box of the character. It will contain signed values +// relative to . I.e. if it returns x0,y0,x1,y1, +// then the character should be displayed in the rectangle from +// to = 32 && *text < 128) { + stbtt_aligned_quad q; + stbtt_GetBakedQuad(cdata, 512, 512, *text - 32, &x, &y, &q, 1);//1=opengl & d3d10+,0=d3d9 + glTexCoord2f(q.s0, q.t0); + glVertex2f(q.x0, q.y0); + glTexCoord2f(q.s1, q.t0); + glVertex2f(q.x1, q.y0); + glTexCoord2f(q.s1, q.t1); + glVertex2f(q.x1, q.y1); + glTexCoord2f(q.s0, q.t1); + glVertex2f(q.x0, q.y1); + } + ++text; + } + glEnd(); +} +#endif +// +// +////////////////////////////////////////////////////////////////////////////// +// +// Complete program (this compiles): get a single bitmap, print as ASCII art +// +#if 0 +#include +#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation +#include "stb_truetype.h" + +char ttf_buffer[1 << 25]; + +int main(int argc, char ** argv) +{ + stbtt_fontinfo font; + unsigned char * bitmap; + int w, h, i, j, c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20); + + fread(ttf_buffer, 1, 1 << 25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb")); + + stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0)); + bitmap = stbtt_GetCodepointBitmap(&font, 0, stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0, 0); + + for(j = 0; j < h; ++j) { + for(i = 0; i < w; ++i) + putchar(" .:ioVM@"[bitmap[j * w + i] >> 5]); + putchar('\n'); + } + return 0; +} +#endif +// +// Output: +// +// .ii. +// @@@@@@. +// V@Mio@@o +// :i. V@V +// :oM@@M +// :@@@MM@M +// @@o o@M +// :@@. M@M +// @@@o@@@@ +// :M@@V:@@. +// +////////////////////////////////////////////////////////////////////////////// +// +// Complete program: print "Hello World!" banner, with bugs +// +#if 0 +char buffer[24 << 20]; +unsigned char screen[20][79]; + +int main(int arg, char ** argv) +{ + stbtt_fontinfo font; + int i, j, ascent, baseline, ch = 0; + float scale, xpos = 2; // leave a little padding in case the character extends left + char * text = "Heljo World!"; // intentionally misspelled to show 'lj' brokenness + + fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); + stbtt_InitFont(&font, buffer, 0); + + scale = stbtt_ScaleForPixelHeight(&font, 15); + stbtt_GetFontVMetrics(&font, &ascent, 0, 0); + baseline = (int)(ascent * scale); + + while(text[ch]) { + int advance, lsb, x0, y0, x1, y1; + float x_shift = xpos - (float)floor(xpos); + stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb); + stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale, scale, x_shift, 0, &x0, &y0, &x1, &y1); + stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int)xpos + x0], x1 - x0, y1 - y0, 79, scale, scale, + x_shift, 0, text[ch]); + // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong + // because this API is really for baking character bitmaps into textures. if you want to render + // a sequence of characters, you really need to render each bitmap to a temp buffer, then + // "alpha blend" that into the working buffer + xpos += (advance * scale); + if(text[ch + 1]) + xpos += scale * stbtt_GetCodepointKernAdvance(&font, text[ch], text[ch + 1]); + ++ch; + } + + for(j = 0; j < 20; ++j) { + for(i = 0; i < 78; ++i) + putchar(" .:ioVM@"[screen[j][i] >> 5]); + putchar('\n'); + } + + return 0; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +//// +//// INTEGRATION WITH YOUR CODEBASE +//// +//// The following sections allow you to supply alternate definitions +//// of C library functions used by stb_truetype, e.g. if you don't +//// link with the C runtime library. + +#ifdef STB_TRUETYPE_IMPLEMENTATION +// #define your own (u)stbtt_int8/16/32 before including to override this +#ifndef stbtt_uint8 + typedef unsigned char stbtt_uint8; + typedef signed char stbtt_int8; + typedef unsigned short stbtt_uint16; + typedef signed short stbtt_int16; + typedef unsigned int stbtt_uint32; + typedef signed int stbtt_int32; +#endif + +typedef char stbtt__check_size32[sizeof(stbtt_int32) == 4 ? 1 : -1]; +typedef char stbtt__check_size16[sizeof(stbtt_int16) == 2 ? 1 : -1]; + +// define STBTT_STDIO_STREAM to stream from a FILE object +// instead of from memory. Or define STBTT_STREAM_TYPE, +// STBTT_STREAM_READ and STBTT_STREAM_SEEK to implement +// another streaming source +#ifdef STBTT_STDIO_STREAM + #include + #define STBTT_STREAM_TYPE FILE* + #define STBTT_STREAM_READ(s,x,y) fread(x,1,y,s); + #define STBTT_STREAM_SEEK(s,x) fseek(s,x,SEEK_SET); +#endif + +// heap factor sizes for various counts of objects +// adjust for your platform. Below is suitable for +// modern PC class machines. +#ifndef STBTT_HEAP_FACTOR_SIZE_32 + #define STBTT_HEAP_FACTOR_SIZE_32 2000 +#endif + +#ifndef STBTT_HEAP_FACTOR_SIZE_128 + #define STBTT_HEAP_FACTOR_SIZE_128 800 +#endif + +#ifndef STBTT_HEAP_FACTOR_SIZE_DEFAULT + #define STBTT_HEAP_FACTOR_SIZE_DEFAULT 100 +#endif + +// e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h +#ifndef STBTT_ifloor + #include + #define STBTT_ifloor(x) ((int) floor(x)) + #define STBTT_iceil(x) ((int) ceil(x)) +#endif + +#ifndef STBTT_sqrt + #include + #define STBTT_sqrt(x) (float)sqrt(x) + #define STBTT_pow(x,y) pow(x,y) +#endif + +#ifndef STBTT_fmod + #include + #define STBTT_fmod(x,y) fmod(x,y) +#endif + +#ifndef STBTT_cos + #include + #define STBTT_cos(x) cos(x) + #define STBTT_acos(x) acos(x) +#endif + +#ifndef STBTT_fabs + #include + #define STBTT_fabs(x) (float)fabs(x) +#endif + +// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h +#ifndef STBTT_malloc + #include + #define STBTT_malloc(x,u) ((void)(u),malloc(x)) + #define STBTT_free(x,u) ((void)(u),free(x)) +#endif + +#ifndef STBTT_assert + #include + #define STBTT_assert(x) assert(x) +#endif + +#ifndef STBTT_strlen + #include + #define STBTT_strlen(x) strlen(x) +#endif + +#ifndef STBTT_memcpy + #include + #define STBTT_memcpy memcpy + #define STBTT_memset memset +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// +//// INTERFACE +//// +//// + +#ifndef __STB_INCLUDE_STB_TRUETYPE_H__ +#define __STB_INCLUDE_STB_TRUETYPE_H__ + +#ifdef STBTT_STATIC + #define STBTT_DEF static +#else + #define STBTT_DEF extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// private structure +typedef struct { +#ifdef STBTT_STREAM_TYPE + STBTT_STREAM_TYPE data; + stbtt_uint32 offset; +#else + unsigned char * data; +#endif + int cursor; + int size; +} stbtt__buf; + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// TEXTURE BAKING API +// +// If you use this API, you only have to call two functions ever. +// + +typedef struct { + unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap + float xoff, yoff, xadvance; +} stbtt_bakedchar; + +typedef struct { + float x0, y0, s0, t0; // top-left + float x1, y1, s1, t1; // bottom-right +} stbtt_aligned_quad; + +STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar * chardata, int pw, int ph, // same data as above + int char_index, // character to display + float * xpos, float * ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad * q, // output: quad to draw + int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier +// Call GetBakedQuad with char_index = 'character - first_char', and it +// creates the quad you need to draw and advances the current position. +// +// The coordinate system used assumes y increases downwards. +// +// Characters will extend both above and below the current position; +// see discussion of "BASELINE" above. +// +// It's inefficient; you might want to c&p it and optimize it. + +////////////////////////////////////////////////////////////////////////////// +// +// NEW TEXTURE BAKING API +// +// This provides options for packing multiple fonts into one atlas, not +// perfectly but better than nothing. + +typedef struct { + unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap + float xoff, yoff, xadvance; + float xoff2, yoff2; +} stbtt_packedchar; + +/// @cond +/** + * Tells Doxygen to ignore a duplicate declaration + */ +typedef struct stbtt_pack_context stbtt_pack_context; +typedef struct stbtt_fontinfo stbtt_fontinfo; +/// @endcond + +#ifndef STB_RECT_PACK_VERSION +/// @cond +/** + * Tells Doxygen to ignore a duplicate declaration + */ +typedef struct stbrp_rect stbrp_rect; +/// @endcond + +#endif +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context * spc, unsigned char * pixels, int width, int height, + int stride_in_bytes, int padding, void * alloc_context); + +// Initializes a packing context stored in the passed-in stbtt_pack_context. +// Future calls using this context will pack characters into the bitmap passed +// in here: a 1-channel bitmap that is width * height. stride_in_bytes is +// the distance from one row to the next (or 0 to mean they are packed tightly +// together). "padding" is the amount of padding to leave between each +// character (normally you want '1' for bitmaps you'll use as textures with +// bilinear filtering). +// +// Returns 0 on failure, 1 on success. + +STBTT_DEF void stbtt_PackEnd(stbtt_pack_context * spc); +// Cleans up the packing context and frees all memory. + +#define STBTT_POINT_SIZE(x) (-(x)) + +typedef struct { + float font_size; + int first_unicode_codepoint_in_range; // if non-zero, then the chars are continuous, and this is the first codepoint + int * array_of_unicode_codepoints; // if non-zero, then this is an array of unicode codepoints + int num_chars; + stbtt_packedchar * chardata_for_range; // output + unsigned char h_oversample, v_oversample; // don't set these, they're used internally +} stbtt_pack_range; + +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context * spc, unsigned int h_oversample, + unsigned int v_oversample); +// Oversampling a font increases the quality by allowing higher-quality subpixel +// positioning, and is especially valuable at smaller text sizes. +// +// This function sets the amount of oversampling for all following calls to +// stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given +// pack context. The default (no oversampling) is achieved by h_oversample=1 +// and v_oversample=1. The total number of pixels required is +// h_oversample*v_oversample larger than the default; for example, 2x2 +// oversampling requires 4x the storage of 1x1. For best results, render +// oversampled textures with bilinear filtering. Look at the readme in +// stb/tests/oversample for information about oversampled fonts +// +// To use with PackFontRangesGather etc., you must set it before calls +// call to PackFontRangesGatherRects. + +STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context * spc, int skip); +// If skip != 0, this tells stb_truetype to skip any codepoints for which +// there is no corresponding glyph. If skip=0, which is the default, then +// codepoints without a glyph received the font's "missing character" glyph, +// typically an empty box by convention. + +STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar * chardata, int pw, int ph, // same data as above + int char_index, // character to display + float * xpos, float * ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad * q, // output: quad to draw + int align_to_integer); + +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context * spc, const stbtt_fontinfo * info, + stbtt_pack_range * ranges, int num_ranges, stbrp_rect * rects); +STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context * spc, stbrp_rect * rects, int num_rects); +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context * spc, const stbtt_fontinfo * info, + stbtt_pack_range * ranges, int num_ranges, stbrp_rect * rects); +// Calling these functions in sequence is roughly equivalent to calling +// stbtt_PackFontRanges(). If you more control over the packing of multiple +// fonts, or if you want to pack custom data into a font texture, take a look +// at the source to of stbtt_PackFontRanges() and create a custom version +// using these functions, e.g. call GatherRects multiple times, +// building up a single array of rects, then call PackRects once, +// then call RenderIntoRects repeatedly. This may result in a +// better packing than calling PackFontRanges multiple times +// (or it may not). + +// this is an opaque structure that you shouldn't mess with which holds +// all the context needed from PackBegin to PackEnd. +struct stbtt_pack_context { + void * user_allocator_context; + void * pack_info; + int width; + int height; + int stride_in_bytes; + int padding; + int skip_missing; + unsigned int h_oversample, v_oversample; + unsigned char * pixels; + void * nodes; +}; + +////////////////////////////////////////////////////////////////////////////// +// +// FONT LOADING +// +// +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_GetNumberOfFonts(STBTT_STREAM_TYPE data); +#else +STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char * data); +#endif +// This function will determine the number of fonts in a font file. TrueType +// collection (.ttc) files may contain multiple fonts, while TrueType font +// (.ttf) files only contain one font. The number of fonts can be used for +// indexing with the previous function where the index is between zero and one +// less than the total fonts. If an error occurs, -1 is returned. +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_GetFontOffsetForIndex(STBTT_STREAM_TYPE, int index); +#else +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char * data, int index); +#endif + +// Each .ttf/.ttc file may have more than one font. Each font has a sequential +// index number starting from 0. Call this function to get the font offset for +// a given index; it returns -1 if the index is out of range. A regular .ttf +// file will only define one font and it always be at offset 0, so it will +// return '0' for index 0, and -1 for all other indices. + +// The following structure is defined publicly so you can declare one on +// the stack or as a global or etc, but you should treat it as opaque. +struct stbtt_fontinfo { + void * userdata; +#ifdef STBTT_STREAM_TYPE + STBTT_STREAM_TYPE data; +#else + unsigned char * data; // pointer to .ttf file +#endif + int fontstart; // offset of start of font + + int numGlyphs; // number of glyphs, needed for range checking + + int loca, head, glyf, hhea, hmtx, kern, gpos, svg; // table locations as offset from start of .ttf + int index_map; // a cmap mapping for our chosen character encoding + int indexToLocFormat; // format needed to map from glyph index to glyph + + stbtt__buf cff; // cff font data + stbtt__buf charstrings; // the charstring index + stbtt__buf gsubrs; // global charstring subroutines index + stbtt__buf subrs; // private charstring subroutines index + stbtt__buf fontdicts; // array of font dicts + stbtt__buf fdselect; // map from glyph to fontdict +}; +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo * info, STBTT_STREAM_TYPE data, int offset); +#else +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo * info, const unsigned char * data, int offset); +#endif +// Given an offset into the file that defines a font, this function builds +// the necessary cached info for the rest of the system. You must allocate +// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't +// need to do anything special to free it, because the contents are pure +// value data with no additional data structures. Returns 0 on failure. + +////////////////////////////////////////////////////////////////////////////// +// +// CHARACTER TO GLYPH-INDEX CONVERSIOn + +STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo * info, int unicode_codepoint); +// If you're going to perform multiple operations on the same character +// and you want a speed-up, call this function with the character you're +// going to process, then use glyph-based functions instead of the +// codepoint-based functions. +// Returns 0 if the character codepoint is not defined in the font. + +////////////////////////////////////////////////////////////////////////////// +// +// CHARACTER PROPERTIES +// + +STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo * info, float pixels); +// computes a scale factor to produce a font whose "height" is 'pixels' tall. +// Height is measured as the distance from the highest ascender to the lowest +// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics +// and computing: +// scale = pixels / (ascent - descent) +// so if you prefer to measure height by the ascent only, use a similar calculation. + +STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo * info, float pixels); +// computes a scale factor to produce a font whose EM size is mapped to +// 'pixels' tall. This is probably what traditional APIs compute, but +// I'm not positive. + +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo * info, int * ascent, int * descent, int * lineGap); +// ascent is the coordinate above the baseline the font extends; descent +// is the coordinate below the baseline the font extends (i.e. it is typically negative) +// lineGap is the spacing between one row's descent and the next row's ascent... +// so you should advance the vertical position by "*ascent - *descent + *lineGap" +// these are expressed in unscaled coordinates, so you must multiply by +// the scale factor for a given size + +STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo * info, int * typoAscent, int * typoDescent, + int * typoLineGap); +// analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2 +// table (specific to MS/Windows TTF files). +// +// Returns 1 on success (table present), 0 on failure. + +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo * info, int * x0, int * y0, int * x1, int * y1); +// the bounding box around all possible characters + +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo * info, int codepoint, int * advanceWidth, + int * leftSideBearing); +// leftSideBearing is the offset from the current horizontal position to the left edge of the character +// advanceWidth is the offset from the current horizontal position to the next horizontal position +// these are expressed in unscaled coordinates + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo * info, int ch1, int ch2); +// an additional amount to add to the 'advance' value between ch1 and ch2 + +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo * info, int codepoint, int * x0, int * y0, int * x1, int * y1); +// Gets the bounding box of the visible part of the glyph, in unscaled coordinates + +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo * info, int glyph_index, int * advanceWidth, + int * leftSideBearing); +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo * info, int glyph1, int glyph2); +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo * info, int glyph_index, int * x0, int * y0, int * x1, int * y1); +// as above, but takes one or more glyph indices for greater efficiency + +typedef struct _stbtt_kerningentry { + int glyph1; // use stbtt_FindGlyphIndex + int glyph2; + int advance; +} stbtt_kerningentry; + +STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo * info); +STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo * info, stbtt_kerningentry * table, int table_length); +// Retrieves a complete list of all of the kerning pairs provided by the font +// stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write. +// The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1) + +////////////////////////////////////////////////////////////////////////////// +// +// GLYPH SHAPES (you probably don't need these, but they have to go before +// the bitmaps for C declaration-order reasons) +// + +#ifndef STBTT_vmove // you can predefine these to use different values (but why?) +enum { + STBTT_vmove = 1, + STBTT_vline, + STBTT_vcurve, + STBTT_vcubic +}; +#endif + +#ifndef stbtt_vertex // you can predefine this to use different values +// (we share this with other code at RAD) +#define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file +typedef struct { + stbtt_vertex_type x, y, cx, cy, cx1, cy1; + unsigned char type, padding; +} stbtt_vertex; +#endif + +STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo * info, int glyph_index); +// returns non-zero if nothing is drawn for this glyph + +STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo * info, int unicode_codepoint, stbtt_vertex ** vertices); +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo * info, int glyph_index, stbtt_vertex ** vertices); +// returns # of vertices and fills *vertices with the pointer to them +// these are expressed in "unscaled" coordinates +// +// The shape is a series of contours. Each one starts with +// a STBTT_moveto, then consists of a series of mixed +// STBTT_lineto and STBTT_curveto segments. A lineto +// draws a line from previous endpoint to its x,y; a curveto +// draws a quadratic bezier from previous endpoint to +// its x,y, using cx,cy as the bezier control point. + +STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo * info, stbtt_vertex * vertices); +// frees the data allocated above + +STBTT_DEF stbtt_uint32 stbtt_FindSVGDoc(const stbtt_fontinfo * info, int gl); +STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo * info, int unicode_codepoint, stbtt_uint32 * svgOfs); +STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo * info, int gl, stbtt_uint32 * svgOfs); +// fills svg with the character's SVG data. +// returns data size or 0 if SVG not found. + +////////////////////////////////////////////////////////////////////////////// +// +// BITMAP RENDERING +// + +STBTT_DEF void stbtt_FreeBitmap(unsigned char * bitmap, void * userdata); +// frees the bitmap allocated below + +STBTT_DEF unsigned char * stbtt_GetCodepointBitmap(const stbtt_fontinfo * info, float scale_x, float scale_y, + int codepoint, int * width, int * height, int * xoff, int * yoff); +// allocates a large-enough single-channel 8bpp bitmap and renders the +// specified character/glyph at the specified scale into it, with +// antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). +// *width & *height are filled out with the width & height of the bitmap, +// which is stored left-to-right, top-to-bottom. +// +// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap + +STBTT_DEF unsigned char * stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo * info, float scale_x, float scale_y, + float shift_x, float shift_y, int codepoint, int * width, int * height, int * xoff, int * yoff); +// the same as stbtt_GetCodepointBitmap, but you can specify a subpixel +// shift for the character + +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h, + int out_stride, float scale_x, float scale_y, int codepoint); +// the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap +// in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap +// is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the +// width and height and positioning info for it first. + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo * info, unsigned char * output, int out_w, + int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); +// same as stbtt_MakeCodepointBitmap, but you can specify a subpixel +// shift for the character + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo * info, unsigned char * output, + int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, + int oversample_y, float * sub_x, float * sub_y, int codepoint); +// same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering +// is performed (see stbtt_PackSetOversampling) + +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo * font, int codepoint, float scale_x, float scale_y, + int * ix0, int * iy0, int * ix1, int * iy1); +// get the bbox of the bitmap centered around the glyph origin; so the +// bitmap width is ix1-ix0, height is iy1-iy0, and location to place +// the bitmap top left is (leftSideBearing*scale,iy0). +// (Note that the bitmap uses y-increases-down, but the shape uses +// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) + +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo * font, int codepoint, float scale_x, + float scale_y, float shift_x, float shift_y, int * ix0, int * iy0, int * ix1, int * iy1); +// same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel +// shift for the character + +// the following functions are equivalent to the above functions, but operate +// on glyph indices instead of Unicode codepoints (for efficiency) +STBTT_DEF unsigned char * stbtt_GetGlyphBitmap(const stbtt_fontinfo * info, float scale_x, float scale_y, int glyph, + int * width, int * height, int * xoff, int * yoff); +STBTT_DEF unsigned char * stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo * info, float scale_x, float scale_y, + float shift_x, float shift_y, int glyph, int * width, int * height, int * xoff, int * yoff); +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h, + int out_stride, float scale_x, float scale_y, int glyph); +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h, + int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo * info, unsigned char * output, int out_w, + int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, + int oversample_y, float * sub_x, float * sub_y, int glyph); +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo * font, int glyph, float scale_x, float scale_y, int * ix0, + int * iy0, int * ix1, int * iy1); +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo * font, int glyph, float scale_x, float scale_y, + float shift_x, float shift_y, int * ix0, int * iy0, int * ix1, int * iy1); + +// @TODO: don't expose this structure +typedef struct { + int w, h, stride; + unsigned char * pixels; +} stbtt__bitmap; + +// rasterize a shape with quadratic beziers into a bitmap +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap * result, // 1-channel bitmap to draw into + float flatness_in_pixels, // allowable error of curve in pixels + stbtt_vertex * vertices, // array of vertices defining shape + int num_verts, // number of vertices in above array + float scale_x, float scale_y, // scale applied to input vertices + float shift_x, float shift_y, // translation applied to input vertices + int x_off, int y_off, // another translation applied to input + int invert, // if non-zero, vertically flip shape + void * userdata); // context for to STBTT_MALLOC + +////////////////////////////////////////////////////////////////////////////// +// +// Signed Distance Function (or Field) rendering + +STBTT_DEF void stbtt_FreeSDF(unsigned char * bitmap, void * userdata); +// frees the SDF bitmap allocated below + +STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo * info, float scale, int glyph, int padding, + unsigned char onedge_value, float pixel_dist_scale, int * width, int * height, int * xoff, int * yoff); +STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo * info, float scale, int codepoint, int padding, + unsigned char onedge_value, float pixel_dist_scale, int * width, int * height, int * xoff, int * yoff); +// These functions compute a discretized SDF field for a single character, suitable for storing +// in a single-channel texture, sampling with bilinear filtering, and testing against +// larger than some threshold to produce scalable fonts. +// info -- the font +// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap +// glyph/codepoint -- the character to generate the SDF for +// padding -- extra "pixels" around the character which are filled with the distance to the character (not 0), +// which allows effects like bit outlines +// onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character) +// pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale) +// if positive, > onedge_value is inside; if negative, < onedge_value is inside +// width,height -- output height & width of the SDF bitmap (including padding) +// xoff,yoff -- output origin of the character +// return value -- a 2D array of bytes 0..255, width*height in size +// +// pixel_dist_scale & onedge_value are a scale & bias that allows you to make +// optimal use of the limited 0..255 for your application, trading off precision +// and special effects. SDF values outside the range 0..255 are clamped to 0..255. +// +// Example: +// scale = stbtt_ScaleForPixelHeight(22) +// padding = 5 +// onedge_value = 180 +// pixel_dist_scale = 180/5.0 = 36.0 +// +// This will create an SDF bitmap in which the character is about 22 pixels +// high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled +// shape, sample the SDF at each pixel and fill the pixel if the SDF value +// is greater than or equal to 180/255. (You'll actually want to antialias, +// which is beyond the scope of this example.) Additionally, you can compute +// offset outlines (e.g. to stroke the character border inside & outside, +// or only outside). For example, to fill outside the character up to 3 SDF +// pixels, you would compare against (180-36.0*3)/255 = 72/255. The above +// choice of variables maps a range from 5 pixels outside the shape to +// 2 pixels inside the shape to 0..255; this is intended primarily for apply +// outside effects only (the interior range is needed to allow proper +// antialiasing of the font at *smaller* sizes) +// +// The function computes the SDF analytically at each SDF pixel, not by e.g. +// building a higher-res bitmap and approximating it. In theory the quality +// should be as high as possible for an SDF of this size & representation, but +// unclear if this is true in practice (perhaps building a higher-res bitmap +// and computing from that can allow drop-out prevention). +// +// The algorithm has not been optimized at all, so expect it to be slow +// if computing lots of characters or very large sizes. + +////////////////////////////////////////////////////////////////////////////// +// +// Finding the right font... +// +// You should really just solve this offline, keep your own tables +// of what font is what, and don't try to get it out of the .ttf file. +// That's because getting it out of the .ttf file is really hard, because +// the names in the file can appear in many possible encodings, in many +// possible languages, and e.g. if you need a case-insensitive comparison, +// the details of that depend on the encoding & language in a complex way +// (actually underspecified in truetype, but also gigantic). +// +// But you can use the provided functions in two possible ways: +// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on +// unicode-encoded names to try to find the font you want; +// you can run this before calling stbtt_InitFont() +// +// stbtt_GetFontNameString() lets you get any of the various strings +// from the file yourself and do your own comparisons on them. +// You have to have called stbtt_InitFont() first. + +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_FindMatchingFont(STBTT_STREAM_TYPE fontdata, const char * name, int flags); +#else +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char * fontdata, const char * name, int flags); +#endif +// returns the offset (not index) of the font that matches, or -1 if none +// if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold". +// if you use any other flag, use a font name like "Arial"; this checks +// the 'macStyle' header field; i don't know if fonts set this consistently +#define STBTT_MACSTYLE_DONTCARE 0 +#define STBTT_MACSTYLE_BOLD 1 +#define STBTT_MACSTYLE_ITALIC 2 +#define STBTT_MACSTYLE_UNDERSCORE 4 +#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 + +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char * s1, int len1, STBTT_STREAM_TYPE s2, stbtt_uint32 s2offs, + int len2); +#else +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char * s1, int len1, const char * s2, stbtt_uint32 s2offs, + int len2); +#endif +// returns 1/0 whether the first string interpreted as utf8 is identical to +// the second string interpreted as big-endian utf16... useful for strings from next func + +STBTT_DEF stbtt_uint32 stbtt_GetFontNameString(const stbtt_fontinfo * font, int * length, int platformID, + int encodingID, int languageID, int nameID); + +// returns the string (which may be big-endian double byte, e.g. for unicode) +// and puts the length in bytes in *length. +// +// some of the values for the IDs are below; for more see the truetype spec: +// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html +// http://www.microsoft.com/typography/otspec/name.htm + +enum { // platformID + STBTT_PLATFORM_ID_UNICODE = 0, + STBTT_PLATFORM_ID_MAC = 1, + STBTT_PLATFORM_ID_ISO = 2, + STBTT_PLATFORM_ID_MICROSOFT = 3 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_UNICODE + STBTT_UNICODE_EID_UNICODE_1_0 = 0, + STBTT_UNICODE_EID_UNICODE_1_1 = 1, + STBTT_UNICODE_EID_ISO_10646 = 2, + STBTT_UNICODE_EID_UNICODE_2_0_BMP = 3, + STBTT_UNICODE_EID_UNICODE_2_0_FULL = 4 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT + STBTT_MS_EID_SYMBOL = 0, + STBTT_MS_EID_UNICODE_BMP = 1, + STBTT_MS_EID_SHIFTJIS = 2, + STBTT_MS_EID_UNICODE_FULL = 10 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes + STBTT_MAC_EID_ROMAN = 0, STBTT_MAC_EID_ARABIC = 4, + STBTT_MAC_EID_JAPANESE = 1, STBTT_MAC_EID_HEBREW = 5, + STBTT_MAC_EID_CHINESE_TRAD = 2, STBTT_MAC_EID_GREEK = 6, + STBTT_MAC_EID_KOREAN = 3, STBTT_MAC_EID_RUSSIAN = 7 +}; + +enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... + // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs + STBTT_MS_LANG_ENGLISH = 0x0409, STBTT_MS_LANG_ITALIAN = 0x0410, + STBTT_MS_LANG_CHINESE = 0x0804, STBTT_MS_LANG_JAPANESE = 0x0411, + STBTT_MS_LANG_DUTCH = 0x0413, STBTT_MS_LANG_KOREAN = 0x0412, + STBTT_MS_LANG_FRENCH = 0x040c, STBTT_MS_LANG_RUSSIAN = 0x0419, + STBTT_MS_LANG_GERMAN = 0x0407, STBTT_MS_LANG_SPANISH = 0x0409, + STBTT_MS_LANG_HEBREW = 0x040d, STBTT_MS_LANG_SWEDISH = 0x041D +}; + +enum { // languageID for STBTT_PLATFORM_ID_MAC + STBTT_MAC_LANG_ENGLISH = 0, STBTT_MAC_LANG_JAPANESE = 11, + STBTT_MAC_LANG_ARABIC = 12, STBTT_MAC_LANG_KOREAN = 23, + STBTT_MAC_LANG_DUTCH = 4, STBTT_MAC_LANG_RUSSIAN = 32, + STBTT_MAC_LANG_FRENCH = 1, STBTT_MAC_LANG_SPANISH = 6, + STBTT_MAC_LANG_GERMAN = 2, STBTT_MAC_LANG_SWEDISH = 5, + STBTT_MAC_LANG_HEBREW = 10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED = 33, + STBTT_MAC_LANG_ITALIAN = 3, STBTT_MAC_LANG_CHINESE_TRAD = 19 +}; + +#ifdef __cplusplus +} +#endif + +#endif // __STB_INCLUDE_STB_TRUETYPE_H__ + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// +//// IMPLEMENTATION +//// +//// + +#ifdef STB_TRUETYPE_IMPLEMENTATION + +#ifndef STBTT_MAX_OVERSAMPLE + #define STBTT_MAX_OVERSAMPLE 8 +#endif + +#if STBTT_MAX_OVERSAMPLE > 255 + #error "STBTT_MAX_OVERSAMPLE cannot be > 255" +#endif + +typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE - 1)) == 0 ? 1 : -1]; + +#ifndef STBTT_RASTERIZER_VERSION + #define STBTT_RASTERIZER_VERSION 2 +#endif + +#ifdef _MSC_VER + #define STBTT__NOTUSED(v) (void)(v) +#else + #define STBTT__NOTUSED(v) (void)sizeof(v) +#endif + +////////////////////////////////////////////////////////////////////////// +// +// stbtt__buf helpers to parse data from file +// + +static stbtt_uint8 stbtt__buf_get8(stbtt__buf * b) +{ + if(b->cursor >= b->size) + return 0; +#ifdef STBTT_STREAM_TYPE + long pos = (long)(b->cursor + b->offset); + STBTT_STREAM_SEEK(b->data, pos); + stbtt_uint8 result; + STBTT_STREAM_READ(b->data, &result, 1); + ++b->cursor; + return result; +#else + return b->data[b->cursor++]; +#endif + +} + +static stbtt_uint8 stbtt__buf_peek8(stbtt__buf * b) +{ + if(b->cursor >= b->size) + return 0; +#ifdef STBTT_STREAM_TYPE + long pos = (long)(b->cursor + b->offset); + STBTT_STREAM_SEEK(b->data, pos); + stbtt_uint8 result; + STBTT_STREAM_READ(b->data, &result, 1); + return result; +#else + return b->data[b->cursor]; +#endif + +} + +static void stbtt__buf_seek(stbtt__buf * b, int o) +{ + STBTT_assert(!(o > b->size || o < 0)); + b->cursor = (o > b->size || o < 0) ? b->size : o; +} + +static void stbtt__buf_skip(stbtt__buf * b, int o) +{ + stbtt__buf_seek(b, b->cursor + o); +} + +static stbtt_uint32 stbtt__buf_get(stbtt__buf * b, int n) +{ + stbtt_uint32 v = 0; + int i; + STBTT_assert(n >= 1 && n <= 4); + for(i = 0; i < n; i++) + v = (v << 8) | stbtt__buf_get8(b); + return v; +} +#ifdef STBTT_STREAM_TYPE + static stbtt__buf stbtt__new_buf(STBTT_STREAM_TYPE s, size_t size) +#else + static stbtt__buf stbtt__new_buf(const void * p, size_t size) +#endif +{ + stbtt__buf r; + STBTT_assert(size < 0x40000000); +#ifdef STBTT_STREAM_TYPE + r.data = s; + r.offset = 0; +#else + r.data = (stbtt_uint8 *)p; +#endif + r.size = (int)size; + r.cursor = 0; + return r; +} + +#define stbtt__buf_get16(b) stbtt__buf_get((b), 2) +#define stbtt__buf_get32(b) stbtt__buf_get((b), 4) + +static stbtt__buf stbtt__buf_range(const stbtt__buf * b, int o, int s) +{ + stbtt__buf r = stbtt__new_buf(NULL, 0); + if(o < 0 || s < 0 || o > b->size || s > b->size - o) return r; +#ifdef STBTT_STREAM_TYPE + r.data = b->data; + r.offset = b->offset + o; +#else + r.data = b->data + o; +#endif + r.size = s; + return r; +} + +static stbtt__buf stbtt__cff_get_index(stbtt__buf * b) +{ + int count, start, offsize; + start = b->cursor; + count = stbtt__buf_get16(b); + if(count) { + offsize = stbtt__buf_get8(b); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(b, offsize * count); + stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1); + } + return stbtt__buf_range(b, start, b->cursor - start); +} + +static stbtt_uint32 stbtt__cff_int(stbtt__buf * b) +{ + int b0 = stbtt__buf_get8(b); + if(b0 >= 32 && b0 <= 246) return b0 - 139; + else if(b0 >= 247 && b0 <= 250) return (b0 - 247) * 256 + stbtt__buf_get8(b) + 108; + else if(b0 >= 251 && b0 <= 254) return -(b0 - 251) * 256 - stbtt__buf_get8(b) - 108; + else if(b0 == 28) return stbtt__buf_get16(b); + else if(b0 == 29) return stbtt__buf_get32(b); + STBTT_assert(0); + return 0; +} + +static void stbtt__cff_skip_operand(stbtt__buf * b) +{ + int v, b0 = stbtt__buf_peek8(b); + STBTT_assert(b0 >= 28); + if(b0 == 30) { + stbtt__buf_skip(b, 1); + while(b->cursor < b->size) { + v = stbtt__buf_get8(b); + if((v & 0xF) == 0xF || (v >> 4) == 0xF) + break; + } + } + else { + stbtt__cff_int(b); + } +} + +static stbtt__buf stbtt__dict_get(stbtt__buf * b, int key) +{ + stbtt__buf_seek(b, 0); + while(b->cursor < b->size) { + int start = b->cursor, end, op; + while(stbtt__buf_peek8(b) >= 28) + stbtt__cff_skip_operand(b); + end = b->cursor; + op = stbtt__buf_get8(b); + if(op == 12) op = stbtt__buf_get8(b) | 0x100; + if(op == key) return stbtt__buf_range(b, start, end - start); + } + return stbtt__buf_range(b, 0, 0); +} + +static void stbtt__dict_get_ints(stbtt__buf * b, int key, int outcount, stbtt_uint32 * out) +{ + int i; + stbtt__buf operands = stbtt__dict_get(b, key); + for(i = 0; i < outcount && operands.cursor < operands.size; i++) + out[i] = stbtt__cff_int(&operands); +} + +static int stbtt__cff_index_count(stbtt__buf * b) +{ + stbtt__buf_seek(b, 0); + return stbtt__buf_get16(b); +} + +static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i) +{ + int count, offsize, start, end; + stbtt__buf_seek(&b, 0); + count = stbtt__buf_get16(&b); + offsize = stbtt__buf_get8(&b); + STBTT_assert(i >= 0 && i < count); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(&b, i * offsize); + start = stbtt__buf_get(&b, offsize); + end = stbtt__buf_get(&b, offsize); + return stbtt__buf_range(&b, 2 + (count + 1) * offsize + start, end - start); +} + +////////////////////////////////////////////////////////////////////////// +// +// accessors to parse data from file +// + +// on platforms that don't allow misaligned reads, if we want to allow +// truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE + +#ifdef STBTT_STREAM_TYPE +static stbtt_uint8 ttBYTE(STBTT_STREAM_TYPE s, stbtt_uint32 offset) +{ + STBTT_STREAM_SEEK(s, offset); + stbtt_uint8 r; + STBTT_STREAM_READ(s, &r, 1); + return r; +} +#define ttCHAR(s, offset) ((stbtt_int8)ttBYTE(s,offset)) +static stbtt_uint16 ttUSHORT(STBTT_STREAM_TYPE s, stbtt_uint32 offset) +{ + STBTT_STREAM_SEEK(s, offset); + stbtt_uint8 r[2]; + STBTT_STREAM_READ(s, &r, 2); + return r[0] * 256 + r[1]; +} +static stbtt_int16 ttSHORT(STBTT_STREAM_TYPE s, stbtt_uint32 offset) +{ + STBTT_STREAM_SEEK(s, offset); + stbtt_uint8 r[2]; + STBTT_STREAM_READ(s, &r, 2); + return r[0] * 256 + r[1]; +} +static stbtt_uint32 ttULONG(STBTT_STREAM_TYPE s, stbtt_uint32 offset) +{ + STBTT_STREAM_SEEK(s, offset); + stbtt_uint8 r[4]; + STBTT_STREAM_READ(s, &r, 4); + return (r[0] << 24) + (r[1] << 16) + (r[2] << 8) + r[3]; +} +static stbtt_int32 ttLONG(STBTT_STREAM_TYPE s, stbtt_uint32 offset) +{ + STBTT_STREAM_SEEK(s, offset); + stbtt_uint8 r[4]; + STBTT_STREAM_READ(s, &r, 4); + return (r[0] << 24) + (r[1] << 16) + (r[2] << 8) + r[3]; +} +#else +#define ttBYTE(p, offset) (* (stbtt_uint8 *) (p+offset)) +#define ttCHAR(p, offset) (* (stbtt_int8 *) (p+offset)) +static stbtt_uint16 ttUSHORT(const stbtt_uint8 * p, stbtt_uint32 offset) +{ + return p[offset + 0] * 256 + p[offset + 1]; +} +static stbtt_int16 ttSHORT(const stbtt_uint8 * p, stbtt_uint32 offset) +{ + return p[offset + 0] * 256 + p[offset + 1]; +} +static stbtt_uint32 ttULONG(const stbtt_uint8 * p, stbtt_uint32 offset) +{ + return (p[offset + 0] << 24) + (p[offset + 1] << 16) + (p[offset + 2] << 8) + p[offset + 3]; +} +static stbtt_int32 ttLONG(const stbtt_uint8 * p, stbtt_uint32 offset) +{ + return (p[offset + 0] << 24) + (p[offset + 1] << 16) + (p[offset + 2] << 8) + p[offset + 3]; +} +#endif +#define ttFixed(p, offset) ttLONG(p, offset) + +#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) +#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3]) +#ifdef STBTT_STREAM_TYPE + static int stbtt__isfont(STBTT_STREAM_TYPE stream, stbtt_uint32 offs) +#else + static int stbtt__isfont(stbtt_uint8 * font, stbtt_uint32 offs) +#endif +{ +#ifdef STBTT_STREAM_TYPE + stbtt_uint8 font[4]; + STBTT_STREAM_SEEK(stream, offs); + STBTT_STREAM_READ(stream, font, 4); +#else + font += offs; +#endif + // check the version number + if(stbtt_tag4(font, '1', 0, 0, 0)) return 1; // TrueType 1 + if(stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! + if(stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF + if(stbtt_tag4(font, 0, 1, 0, 0)) return 1; // OpenType 1.0 + if(stbtt_tag(font, "true")) return 1; // Apple specification for TrueType fonts + return 0; +} + +// @OPTIMIZE: binary search +#ifdef STBTT_STREAM_TYPE + static stbtt_uint32 stbtt__find_table(STBTT_STREAM_TYPE data, stbtt_uint32 fontstart, const char * tag) +#else + static stbtt_uint32 stbtt__find_table(stbtt_uint8 * data, stbtt_uint32 fontstart, const char * tag) +#endif +{ + stbtt_int32 num_tables = ttUSHORT(data, fontstart + 4); + stbtt_uint32 tabledir = fontstart + 12; + stbtt_int32 i; + for(i = 0; i < num_tables; ++i) { + stbtt_uint32 loc = tabledir + 16 * i; +#ifdef STBTT_STREAM_TYPE + stbtt_uint8 buf[4]; + STBTT_STREAM_SEEK(data, loc + 0); + STBTT_STREAM_READ(data, buf, 4); + if(stbtt_tag(buf, tag)) + return ttULONG(data, loc + 8); +#else + if(stbtt_tag(data + loc + 0, tag)) + return ttULONG(data, loc + 8); +#endif + } + return 0; +} +#ifdef STBTT_STREAM_TYPE + static int stbtt_GetFontOffsetForIndex_internal(STBTT_STREAM_TYPE font_collection, int index) +#else + static int stbtt_GetFontOffsetForIndex_internal(unsigned char * font_collection, int index) +#endif +{ + // if it's just a font, there's only one valid index + if(stbtt__isfont(font_collection, 0)) + return index == 0 ? 0 : -1; + + // check if it's a TTC +#ifdef STBTT_STREAM_TYPE + stbtt_uint8 buf[4]; + STBTT_STREAM_SEEK(font_collection, 0); + STBTT_STREAM_READ(font_collection, buf, 4); + if(stbtt_tag(buf, "ttcf")) { +#else + if(stbtt_tag(font_collection, "ttcf")) { +#endif + // version 1? + if(ttULONG(font_collection, 4) == 0x00010000 || ttULONG(font_collection, 4) == 0x00020000) { + stbtt_int32 n = ttLONG(font_collection, 8); + if(index >= n) + return -1; + return ttULONG(font_collection, 12 + index * 4); + } + } + return -1; +} +#ifdef STBTT_STREAM_TYPE + static int stbtt_GetNumberOfFonts_internal(STBTT_STREAM_TYPE font_collection) +#else + static int stbtt_GetNumberOfFonts_internal(unsigned char * font_collection) +#endif +{ + // if it's just a font, there's only one valid font + if(stbtt__isfont(font_collection, 0)) + return 1; + + // check if it's a TTC +#ifdef STBTT_STREAM_TYPE + stbtt_uint8 buf[4]; + STBTT_STREAM_SEEK(font_collection, 0); + STBTT_STREAM_READ(font_collection, buf, 4); + if(stbtt_tag(buf, "ttcf")) { +#else + if(stbtt_tag(font_collection, "ttcf")) { +#endif + // version 1? + if(ttULONG(font_collection, 4) == 0x00010000 || ttULONG(font_collection, 4) == 0x00020000) { + return ttLONG(font_collection, 8); + } + } + return 0; +} + +static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) +{ + stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 }; + stbtt__buf pdict; + stbtt__dict_get_ints(&fontdict, 18, 2, private_loc); + if(!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0); + pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]); + stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff); + if(!subrsoff) return stbtt__new_buf(NULL, 0); + stbtt__buf_seek(&cff, private_loc[1] + subrsoff); + return stbtt__cff_get_index(&cff); +} + +// since most people won't use this, find this table the first time it's needed +static int stbtt__get_svg(stbtt_fontinfo * info) +{ + stbtt_uint32 t; + if(info->svg < 0) { + t = stbtt__find_table(info->data, info->fontstart, "SVG "); + if(t) { + stbtt_uint32 offset = ttULONG(info->data, t + 2); + info->svg = t + offset; + } + else { + info->svg = 0; + } + } + return info->svg; +} +#ifdef STBTT_STREAM_TYPE + static int stbtt_InitFont_internal(stbtt_fontinfo * info, STBTT_STREAM_TYPE data, int fontstart) +#else + static int stbtt_InitFont_internal(stbtt_fontinfo * info, unsigned char * data, int fontstart) +#endif +{ + stbtt_uint32 cmap, t; + stbtt_int32 i, numTables; + + info->data = data; + info->fontstart = fontstart; + info->cff = stbtt__new_buf(NULL, 0); + + cmap = stbtt__find_table(data, fontstart, "cmap"); // required + info->loca = stbtt__find_table(data, fontstart, "loca"); // required + info->head = stbtt__find_table(data, fontstart, "head"); // required + info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required + info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required + info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required + info->kern = stbtt__find_table(data, fontstart, "kern"); // not required + info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required + + if(!cmap || !info->head || !info->hhea || !info->hmtx) + return 0; + if(info->glyf) { + // required for truetype + if(!info->loca) return 0; + } + else { + // initialization for CFF / Type2 fonts (OTF) + stbtt__buf b, topdict, topdictidx; + stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0; + stbtt_uint32 cff; + + cff = stbtt__find_table(data, fontstart, "CFF "); + if(!cff) return 0; + + info->fontdicts = stbtt__new_buf(NULL, 0); + info->fdselect = stbtt__new_buf(NULL, 0); + + // @TODO this should use size from table (not 512MB) + +#ifdef STBTT_STREAM_TYPE + info->cff = stbtt__new_buf(info->data, 512 * 1024 * 1024); + info->cff.offset = cff; +#else + info->cff = stbtt__new_buf(info->data + cff, 512 * 1024 * 1024); +#endif + b = info->cff; + + // read the header + stbtt__buf_skip(&b, 2); + stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize + + // @TODO the name INDEX could list multiple fonts, + // but we just use the first one. + stbtt__cff_get_index(&b); // name INDEX + topdictidx = stbtt__cff_get_index(&b); + topdict = stbtt__cff_index_get(topdictidx, 0); + stbtt__cff_get_index(&b); // string INDEX + info->gsubrs = stbtt__cff_get_index(&b); + + stbtt__dict_get_ints(&topdict, 17, 1, &charstrings); + stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype); + stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff); + stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff); + info->subrs = stbtt__get_subrs(b, topdict); + + // we only support Type 2 charstrings + if(cstype != 2) return 0; + if(charstrings == 0) return 0; + + if(fdarrayoff) { + // looks like a CID font + if(!fdselectoff) return 0; + stbtt__buf_seek(&b, fdarrayoff); + info->fontdicts = stbtt__cff_get_index(&b); + info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size - fdselectoff); + } + + stbtt__buf_seek(&b, charstrings); + info->charstrings = stbtt__cff_get_index(&b); + } + + t = stbtt__find_table(data, fontstart, "maxp"); + if(t) + info->numGlyphs = ttUSHORT(data, t + 4); + else + info->numGlyphs = 0xffff; + + info->svg = -1; + + // find a cmap encoding table we understand *now* to avoid searching + // later. (todo: could make this installable) + // the same regardless of glyph. + numTables = ttUSHORT(data, cmap + 2); + info->index_map = 0; + for(i = 0; i < numTables; ++i) { + stbtt_uint32 encoding_record = cmap + 4 + 8 * i; + // find an encoding we understand: + switch(ttUSHORT(data, encoding_record)) { + case STBTT_PLATFORM_ID_MICROSOFT: + switch(ttUSHORT(data, encoding_record + 2)) { + case STBTT_MS_EID_UNICODE_BMP: + case STBTT_MS_EID_UNICODE_FULL: + // MS/Unicode + info->index_map = cmap + ttULONG(data, encoding_record + 4); + break; + } + break; + case STBTT_PLATFORM_ID_UNICODE: + // Mac/iOS has these + // all the encodingIDs are unicode, so we don't bother to check it + info->index_map = cmap + ttULONG(data, encoding_record + 4); + break; + } + } + if(info->index_map == 0) + return 0; + + info->indexToLocFormat = ttUSHORT(data, info->head + 50); + return 1; +} + +STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo * info, int unicode_codepoint) +{ +#ifdef STBTT_STREAM_TYPE + STBTT_STREAM_TYPE data = info->data; +#else + stbtt_uint8 * data = info->data; +#endif + stbtt_uint32 index_map = info->index_map; + + stbtt_uint16 format = ttUSHORT(data, index_map + 0); + if(format == 0) { // apple byte encoding + stbtt_int32 bytes = ttUSHORT(data, index_map + 2); + if(unicode_codepoint < bytes - 6) + return ttBYTE(data, index_map + 6 + unicode_codepoint); + return 0; + } + else if(format == 6) { + stbtt_uint32 first = ttUSHORT(data, index_map + 6); + stbtt_uint32 count = ttUSHORT(data, index_map + 8); + if((stbtt_uint32)unicode_codepoint >= first && (stbtt_uint32)unicode_codepoint < first + count) + return ttUSHORT(data, index_map + 10 + (unicode_codepoint - first) * 2); + return 0; + } + else if(format == 2) { + STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean + return 0; + } + else if(format == 4) { // standard mapping for windows fonts: binary search collection of ranges + stbtt_uint16 segcount = ttUSHORT(data, index_map + 6) >> 1; + stbtt_uint16 searchRange = ttUSHORT(data, index_map + 8) >> 1; + stbtt_uint16 entrySelector = ttUSHORT(data, index_map + 10); + stbtt_uint16 rangeShift = ttUSHORT(data, index_map + 12) >> 1; + + // do a binary search of the segments + stbtt_uint32 endCount = index_map + 14; + stbtt_uint32 search = endCount; + + if(unicode_codepoint > 0xffff) + return 0; + + // they lie from endCount .. endCount + segCount + // but searchRange is the nearest power of two, so... + if(unicode_codepoint >= ttUSHORT(data, search + rangeShift * 2)) + search += rangeShift * 2; + + // now decrement to bias correctly to find smallest + search -= 2; + while(entrySelector) { + stbtt_uint16 end; + searchRange >>= 1; + end = ttUSHORT(data, search + searchRange * 2); + if(unicode_codepoint > end) + search += searchRange * 2; + --entrySelector; + } + search += 2; + + { + stbtt_uint16 offset, start, last; + stbtt_uint16 item = (stbtt_uint16)((search - endCount) >> 1); + + start = ttUSHORT(data, index_map + 14 + segcount * 2 + 2 + 2 * item); + last = ttUSHORT(data, endCount + 2 * item); + if(unicode_codepoint < start || unicode_codepoint > last) + return 0; + + offset = ttUSHORT(data, index_map + 14 + segcount * 6 + 2 + 2 * item); + if(offset == 0) + return (stbtt_uint16)(unicode_codepoint + ttSHORT(data, index_map + 14 + segcount * 4 + 2 + 2 * item)); + + return ttUSHORT(data, offset + (unicode_codepoint - start) * 2 + index_map + 14 + segcount * 6 + 2 + 2 * item); + } + } + else if(format == 12 || format == 13) { + stbtt_uint32 ngroups = ttULONG(data, index_map + 12); + stbtt_int32 low, high; + low = 0; + high = (stbtt_int32)ngroups; + // Binary search the right group. + while(low < high) { + stbtt_int32 mid = low + ((high - low) >> 1); // rounds down, so low <= mid < high + stbtt_uint32 start_char = ttULONG(data, index_map + 16 + mid * 12); + stbtt_uint32 end_char = ttULONG(data, index_map + 16 + mid * 12 + 4); + if((stbtt_uint32)unicode_codepoint < start_char) + high = mid; + else if((stbtt_uint32)unicode_codepoint > end_char) + low = mid + 1; + else { + stbtt_uint32 start_glyph = ttULONG(data, index_map + 16 + mid * 12 + 8); + if(format == 12) + return start_glyph + unicode_codepoint - start_char; + else // format == 13 + return start_glyph; + } + } + return 0; // not found + } + // @TODO + STBTT_assert(0); + return 0; +} + +STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo * info, int unicode_codepoint, stbtt_vertex * *vertices) +{ + return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); +} + +static void stbtt_setvertex(stbtt_vertex * v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, + stbtt_int32 cy) +{ + v->type = type; + v->x = (stbtt_int16)x; + v->y = (stbtt_int16)y; + v->cx = (stbtt_int16)cx; + v->cy = (stbtt_int16)cy; +} + +static int stbtt__GetGlyfOffset(const stbtt_fontinfo * info, int glyph_index) +{ + int g1, g2; + + STBTT_assert(!info->cff.size); + + if(glyph_index >= info->numGlyphs) return -1; // glyph index out of range + if(info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format + + if(info->indexToLocFormat == 0) { + g1 = info->glyf + ttUSHORT(info->data, info->loca + glyph_index * 2) * 2; + g2 = info->glyf + ttUSHORT(info->data, info->loca + glyph_index * 2 + 2) * 2; + } + else { + g1 = info->glyf + ttULONG(info->data, info->loca + glyph_index * 4); + g2 = info->glyf + ttULONG(info->data, info->loca + glyph_index * 4 + 4); + } + + return g1 == g2 ? -1 : g1; // if length is 0, return -1 +} + +static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo * info, int glyph_index, int * x0, int * y0, int * x1, int * y1); + +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo * info, int glyph_index, int * x0, int * y0, int * x1, int * y1) +{ + if(info->cff.size) { + stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1); + } + else { + int g = stbtt__GetGlyfOffset(info, glyph_index); + if(g < 0) return 0; + + if(x0) *x0 = ttSHORT(info->data, g + 2); + if(y0) *y0 = ttSHORT(info->data, g + 4); + if(x1) *x1 = ttSHORT(info->data, g + 6); + if(y1) *y1 = ttSHORT(info->data, g + 8); + } + return 1; +} + +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo * info, int codepoint, int * x0, int * y0, int * x1, int * y1) +{ + return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info, codepoint), x0, y0, x1, y1); +} + +STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo * info, int glyph_index) +{ + stbtt_int16 numberOfContours; + int g; + if(info->cff.size) + return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0; + g = stbtt__GetGlyfOffset(info, glyph_index); + if(g < 0) return 1; + numberOfContours = ttSHORT(info->data, g); + return numberOfContours == 0; +} + +static int stbtt__close_shape(stbtt_vertex * vertices, int num_vertices, int was_off, int start_off, + stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) +{ + if(start_off) { + if(was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + scx) >> 1, (cy + scy) >> 1, cx, cy); + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, scx, scy); + } + else { + if(was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, cx, cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, sx, sy, 0, 0); + } + return num_vertices; +} + +static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo * info, int glyph_index, stbtt_vertex * *pvertices) +{ + stbtt_int16 numberOfContours; + stbtt_uint32 endPtsOfContours; +#ifdef STBTT_STREAM_TYPE + STBTT_STREAM_TYPE data = info->data; +#else + stbtt_uint8 * data = info->data; +#endif + stbtt_vertex * vertices = 0; + int num_vertices = 0; + int g = stbtt__GetGlyfOffset(info, glyph_index); + + *pvertices = NULL; + + if(g < 0) return 0; + + numberOfContours = ttSHORT(data, g); + + if(numberOfContours > 0) { + stbtt_uint8 flags = 0, flagcount; + stbtt_int32 ins, i, j = 0, m, n, next_move, was_off = 0, off, start_off = 0; + stbtt_int32 x, y, cx, cy, sx, sy, scx, scy; + stbtt_uint32 points; + endPtsOfContours = (g + 10); + ins = ttUSHORT(data, g + 10 + numberOfContours * 2); + points = g + 10 + numberOfContours * 2 + 2 + ins; + + n = 1 + ttUSHORT(data, endPtsOfContours + numberOfContours * 2 - 2); + + m = n + 2 * numberOfContours; // a loose bound on how many vertices we might need + vertices = (stbtt_vertex *)STBTT_malloc(m * sizeof(vertices[0]), info->userdata); + if(vertices == 0) + return 0; + + next_move = 0; + flagcount = 0; + + // in first pass, we load uninterpreted data into the allocated array + // above, shifted to the end of the array so we won't overwrite it when + // we create our final data starting from the front + + off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated + + // first load flags + + for(i = 0; i < n; ++i) { + if(flagcount == 0) { + flags = ttBYTE(data, points++); + if(flags & 8) + flagcount = ttBYTE(data, points++); + } + else + --flagcount; + vertices[off + i].type = flags; + } + + // now load x coordinates + x = 0; + for(i = 0; i < n; ++i) { + flags = vertices[off + i].type; + if(flags & 2) { + stbtt_int16 dx = ttBYTE(data, points++); + x += (flags & 16) ? dx : -dx; // ??? + } + else { + if(!(flags & 16)) { + x = x + (stbtt_int16)(ttBYTE(data, points) * 256 + ttBYTE(data, points + 1)); + points += 2; + } + } + vertices[off + i].x = (stbtt_int16)x; + } + + // now load y coordinates + y = 0; + for(i = 0; i < n; ++i) { + flags = vertices[off + i].type; + if(flags & 4) { + stbtt_int16 dy = ttBYTE(data, points++); + y += (flags & 32) ? dy : -dy; // ??? + } + else { + if(!(flags & 32)) { + y = y + (stbtt_int16)(ttBYTE(data, points) * 256 + ttBYTE(data, points + 1)); + points += 2; + } + } + vertices[off + i].y = (stbtt_int16)y; + } + + // now convert them to our format + num_vertices = 0; + sx = sy = cx = cy = scx = scy = 0; + for(i = 0; i < n; ++i) { + flags = vertices[off + i].type; + x = (stbtt_int16)vertices[off + i].x; + y = (stbtt_int16)vertices[off + i].y; + + if(next_move == i) { + if(i != 0) + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy); + + // now start the new one + start_off = !(flags & 1); + if(start_off) { + // if we start off with an off-curve point, then when we need to find a point on the curve + // where we can start, and we need to save some state for when we wraparound. + scx = x; + scy = y; + if(!(vertices[off + i + 1].type & 1)) { + // next point is also a curve point, so interpolate an on-point curve + sx = (x + (stbtt_int32)vertices[off + i + 1].x) >> 1; + sy = (y + (stbtt_int32)vertices[off + i + 1].y) >> 1; + } + else { + // otherwise just use the next point as our start point + sx = (stbtt_int32)vertices[off + i + 1].x; + sy = (stbtt_int32)vertices[off + i + 1].y; + ++i; // we're using point i+1 as the starting point, so skip it + } + } + else { + sx = x; + sy = y; + } + stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove, sx, sy, 0, 0); + was_off = 0; + next_move = 1 + ttUSHORT(data, endPtsOfContours + j * 2); + ++j; + } + else { + if(!(flags & 1)) { // if it's a curve + if(was_off) // two off-curve control points in a row means interpolate an on-curve midpoint + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + x) >> 1, (cy + y) >> 1, cx, cy); + cx = x; + cy = y; + was_off = 1; + } + else { + if(was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x, y, cx, cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x, y, 0, 0); + was_off = 0; + } + } + } + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy); + } + else if(numberOfContours < 0) { + // Compound shapes. + int more = 1; + stbtt_uint32 comp = g + 10; + num_vertices = 0; + vertices = 0; + while(more) { + stbtt_uint16 flags, gidx; + int comp_num_verts = 0, i; + stbtt_vertex * comp_verts = 0, * tmp = 0; + float mtx[6] = { 1, 0, 0, 1, 0, 0 }, m, n; + + flags = ttSHORT(data, comp); + comp += 2; + gidx = ttSHORT(data, comp); + comp += 2; + + if(flags & 2) { // XY values + if(flags & 1) { // shorts + mtx[4] = ttSHORT(data, comp); + comp += 2; + mtx[5] = ttSHORT(data, comp); + comp += 2; + } + else { + mtx[4] = ttCHAR(data, comp); + comp += 1; + mtx[5] = ttCHAR(data, comp); + comp += 1; + } + } + else { + // @TODO handle matching point + STBTT_assert(0); + } + if(flags & (1 << 3)) { // WE_HAVE_A_SCALE + mtx[0] = mtx[3] = ttSHORT(data, comp) / 16384.0f; + comp += 2; + mtx[1] = mtx[2] = 0; + } + else if(flags & (1 << 6)) { // WE_HAVE_AN_X_AND_YSCALE + mtx[0] = ttSHORT(data, comp) / 16384.0f; + comp += 2; + mtx[1] = mtx[2] = 0; + mtx[3] = ttSHORT(data, comp) / 16384.0f; + comp += 2; + } + else if(flags & (1 << 7)) { // WE_HAVE_A_TWO_BY_TWO + mtx[0] = ttSHORT(data, comp) / 16384.0f; + comp += 2; + mtx[1] = ttSHORT(data, comp) / 16384.0f; + comp += 2; + mtx[2] = ttSHORT(data, comp) / 16384.0f; + comp += 2; + mtx[3] = ttSHORT(data, comp) / 16384.0f; + comp += 2; + } + + // Find transformation scales. + m = (float)STBTT_sqrt(mtx[0] * mtx[0] + mtx[1] * mtx[1]); + n = (float)STBTT_sqrt(mtx[2] * mtx[2] + mtx[3] * mtx[3]); + + // Get indexed glyph. + comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); + if(comp_num_verts > 0) { + // Transform vertices. + for(i = 0; i < comp_num_verts; ++i) { + stbtt_vertex * v = &comp_verts[i]; + stbtt_vertex_type x, y; + x = v->x; + y = v->y; + v->x = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4])); + v->y = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5])); + x = v->cx; + y = v->cy; + v->cx = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4])); + v->cy = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5])); + } + // Append vertices. + tmp = (stbtt_vertex *)STBTT_malloc((num_vertices + comp_num_verts) * sizeof(stbtt_vertex), info->userdata); + if(!tmp) { + if(vertices) STBTT_free(vertices, info->userdata); + if(comp_verts) STBTT_free(comp_verts, info->userdata); + return 0; + } + if(num_vertices > 0 && vertices) STBTT_memcpy(tmp, vertices, num_vertices * sizeof(stbtt_vertex)); + STBTT_memcpy(tmp + num_vertices, comp_verts, comp_num_verts * sizeof(stbtt_vertex)); + if(vertices) STBTT_free(vertices, info->userdata); + vertices = tmp; + STBTT_free(comp_verts, info->userdata); + num_vertices += comp_num_verts; + } + // More components ? + more = flags & (1 << 5); + } + } + else { + // numberOfCounters == 0, do nothing + } + + *pvertices = vertices; + return num_vertices; +} + +typedef struct { + int bounds; + int started; + float first_x, first_y; + float x, y; + stbtt_int32 min_x, max_x, min_y, max_y; + + stbtt_vertex * pvertices; + int num_vertices; +} stbtt__csctx; + +#define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0} + +static void stbtt__track_vertex(stbtt__csctx * c, stbtt_int32 x, stbtt_int32 y) +{ + if(x > c->max_x || !c->started) c->max_x = x; + if(y > c->max_y || !c->started) c->max_y = y; + if(x < c->min_x || !c->started) c->min_x = x; + if(y < c->min_y || !c->started) c->min_y = y; + c->started = 1; +} + +static void stbtt__csctx_v(stbtt__csctx * c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, + stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1) +{ + if(c->bounds) { + stbtt__track_vertex(c, x, y); + if(type == STBTT_vcubic) { + stbtt__track_vertex(c, cx, cy); + stbtt__track_vertex(c, cx1, cy1); + } + } + else { + stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy); + c->pvertices[c->num_vertices].cx1 = (stbtt_int16)cx1; + c->pvertices[c->num_vertices].cy1 = (stbtt_int16)cy1; + } + c->num_vertices++; +} + +static void stbtt__csctx_close_shape(stbtt__csctx * ctx) +{ + if(ctx->first_x != ctx->x || ctx->first_y != ctx->y) + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rmove_to(stbtt__csctx * ctx, float dx, float dy) +{ + stbtt__csctx_close_shape(ctx); + ctx->first_x = ctx->x = ctx->x + dx; + ctx->first_y = ctx->y = ctx->y + dy; + stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rline_to(stbtt__csctx * ctx, float dx, float dy) +{ + ctx->x += dx; + ctx->y += dy; + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rccurve_to(stbtt__csctx * ctx, float dx1, float dy1, float dx2, float dy2, float dx3, + float dy3) +{ + float cx1 = ctx->x + dx1; + float cy1 = ctx->y + dy1; + float cx2 = cx1 + dx2; + float cy2 = cy1 + dy2; + ctx->x = cx2 + dx3; + ctx->y = cy2 + dy3; + stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2); +} + +static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n) +{ + int count = stbtt__cff_index_count(&idx); + int bias = 107; + if(count >= 33900) + bias = 32768; + else if(count >= 1240) + bias = 1131; + n += bias; + if(n < 0 || n >= count) + return stbtt__new_buf(NULL, 0); + return stbtt__cff_index_get(idx, n); +} + +static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo * info, int glyph_index) +{ + stbtt__buf fdselect = info->fdselect; + int nranges, start, end, v, fmt, fdselector = -1, i; + + stbtt__buf_seek(&fdselect, 0); + fmt = stbtt__buf_get8(&fdselect); + if(fmt == 0) { + // untested + stbtt__buf_skip(&fdselect, glyph_index); + fdselector = stbtt__buf_get8(&fdselect); + } + else if(fmt == 3) { + nranges = stbtt__buf_get16(&fdselect); + start = stbtt__buf_get16(&fdselect); + for(i = 0; i < nranges; i++) { + v = stbtt__buf_get8(&fdselect); + end = stbtt__buf_get16(&fdselect); + if(glyph_index >= start && glyph_index < end) { + fdselector = v; + break; + } + start = end; + } + } + if(fdselector == -1) stbtt__new_buf(NULL, 0); + return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector)); +} + +static int stbtt__run_charstring(const stbtt_fontinfo * info, int glyph_index, stbtt__csctx * c) +{ + int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0; + int has_subrs = 0, clear_stack; + float s[48]; + stbtt__buf subr_stack[10], subrs = info->subrs, b; + float f; + +#define STBTT__CSERR(s) (0) + + // this currently ignores the initial width value, which isn't needed if we have hmtx + b = stbtt__cff_index_get(info->charstrings, glyph_index); + while(b.cursor < b.size) { + i = 0; + clear_stack = 1; + b0 = stbtt__buf_get8(&b); + switch(b0) { + // @TODO implement hinting + case 0x13: // hintmask + case 0x14: // cntrmask + if(in_header) + maskbits += (sp / 2); // implicit "vstem" + in_header = 0; + stbtt__buf_skip(&b, (maskbits + 7) / 8); + break; + + case 0x01: // hstem + case 0x03: // vstem + case 0x12: // hstemhm + case 0x17: // vstemhm + maskbits += (sp / 2); + break; + + case 0x15: // rmoveto + in_header = 0; + if(sp < 2) return STBTT__CSERR("rmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp - 2], s[sp - 1]); + break; + case 0x04: // vmoveto + in_header = 0; + if(sp < 1) return STBTT__CSERR("vmoveto stack"); + stbtt__csctx_rmove_to(c, 0, s[sp - 1]); + break; + case 0x16: // hmoveto + in_header = 0; + if(sp < 1) return STBTT__CSERR("hmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp - 1], 0); + break; + + case 0x05: // rlineto + if(sp < 2) return STBTT__CSERR("rlineto stack"); + for(; i + 1 < sp; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i + 1]); + break; + + // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical + // starting from a different place. + + case 0x07: // vlineto + if(sp < 1) return STBTT__CSERR("vlineto stack"); + goto vlineto; + case 0x06: // hlineto + if(sp < 1) return STBTT__CSERR("hlineto stack"); + for(;;) { + if(i >= sp) break; + stbtt__csctx_rline_to(c, s[i], 0); + i++; +vlineto: + if(i >= sp) break; + stbtt__csctx_rline_to(c, 0, s[i]); + i++; + } + break; + + case 0x1F: // hvcurveto + if(sp < 4) return STBTT__CSERR("hvcurveto stack"); + goto hvcurveto; + case 0x1E: // vhcurveto + if(sp < 4) return STBTT__CSERR("vhcurveto stack"); + for(;;) { + if(i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, 0, s[i], s[i + 1], s[i + 2], s[i + 3], (sp - i == 5) ? s[i + 4] : 0.0f); + i += 4; +hvcurveto: + if(i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, s[i], 0, s[i + 1], s[i + 2], (sp - i == 5) ? s[i + 4] : 0.0f, s[i + 3]); + i += 4; + } + break; + + case 0x08: // rrcurveto + if(sp < 6) return STBTT__CSERR("rcurveline stack"); + for(; i + 5 < sp; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]); + break; + + case 0x18: // rcurveline + if(sp < 8) return STBTT__CSERR("rcurveline stack"); + for(; i + 5 < sp - 2; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]); + if(i + 1 >= sp) return STBTT__CSERR("rcurveline stack"); + stbtt__csctx_rline_to(c, s[i], s[i + 1]); + break; + + case 0x19: // rlinecurve + if(sp < 8) return STBTT__CSERR("rlinecurve stack"); + for(; i + 1 < sp - 6; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i + 1]); + if(i + 5 >= sp) return STBTT__CSERR("rlinecurve stack"); + stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]); + break; + + case 0x1A: // vvcurveto + case 0x1B: // hhcurveto + if(sp < 4) return STBTT__CSERR("(vv|hh)curveto stack"); + f = 0.0; + if(sp & 1) { + f = s[i]; + i++; + } + for(; i + 3 < sp; i += 4) { + if(b0 == 0x1B) + stbtt__csctx_rccurve_to(c, s[i], f, s[i + 1], s[i + 2], s[i + 3], 0.0); + else + stbtt__csctx_rccurve_to(c, f, s[i], s[i + 1], s[i + 2], 0.0, s[i + 3]); + f = 0.0; + } + break; + + case 0x0A: // callsubr + if(!has_subrs) { + if(info->fdselect.size) + subrs = stbtt__cid_get_glyph_subrs(info, glyph_index); + has_subrs = 1; + } + // FALLTHROUGH + case 0x1D: // callgsubr + if(sp < 1) return STBTT__CSERR("call(g|)subr stack"); + v = (int)s[--sp]; + if(subr_stack_height >= 10) return STBTT__CSERR("recursion limit"); + subr_stack[subr_stack_height++] = b; + b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v); + if(b.size == 0) return STBTT__CSERR("subr not found"); + b.cursor = 0; + clear_stack = 0; + break; + + case 0x0B: // return + if(subr_stack_height <= 0) return STBTT__CSERR("return outside subr"); + b = subr_stack[--subr_stack_height]; + clear_stack = 0; + break; + + case 0x0E: // endchar + stbtt__csctx_close_shape(c); + return 1; + + case 0x0C: { // two-byte escape + float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6; + float dx, dy; + int b1 = stbtt__buf_get8(&b); + switch(b1) { + // @TODO These "flex" implementations ignore the flex-depth and resolution, + // and always draw beziers. + case 0x22: // hflex + if(sp < 7) return STBTT__CSERR("hflex stack"); + dx1 = s[0]; + dx2 = s[1]; + dy2 = s[2]; + dx3 = s[3]; + dx4 = s[4]; + dx5 = s[5]; + dx6 = s[6]; + stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0); + break; + + case 0x23: // flex + if(sp < 13) return STBTT__CSERR("flex stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = s[10]; + dy6 = s[11]; + //fd is s[12] + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + case 0x24: // hflex1 + if(sp < 9) return STBTT__CSERR("hflex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dx4 = s[5]; + dx5 = s[6]; + dy5 = s[7]; + dx6 = s[8]; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1 + dy2 + dy5)); + break; + + case 0x25: // flex1 + if(sp < 11) return STBTT__CSERR("flex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = dy6 = s[10]; + dx = dx1 + dx2 + dx3 + dx4 + dx5; + dy = dy1 + dy2 + dy3 + dy4 + dy5; + if(STBTT_fabs(dx) > STBTT_fabs(dy)) + dy6 = -dy; + else + dx6 = -dx; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + default: + return STBTT__CSERR("unimplemented"); + } + } + break; + + default: + if(b0 != 255 && b0 != 28 && b0 < 32) + return STBTT__CSERR("reserved operator"); + + // push immediate + if(b0 == 255) { + f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000; + } + else { + stbtt__buf_skip(&b, -1); + f = (float)(stbtt_int16)stbtt__cff_int(&b); + } + if(sp >= 48) return STBTT__CSERR("push stack overflow"); + s[sp++] = f; + clear_stack = 0; + break; + } + if(clear_stack) sp = 0; + } + return STBTT__CSERR("no endchar"); + +#undef STBTT__CSERR +} + +static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo * info, int glyph_index, stbtt_vertex * *pvertices) +{ + // runs the charstring twice, once to count and once to output (to avoid realloc) + stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1); + stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0); + if(stbtt__run_charstring(info, glyph_index, &count_ctx)) { + *pvertices = (stbtt_vertex *)STBTT_malloc(count_ctx.num_vertices * sizeof(stbtt_vertex), info->userdata); + output_ctx.pvertices = *pvertices; + if(stbtt__run_charstring(info, glyph_index, &output_ctx)) { + STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices); + return output_ctx.num_vertices; + } + } + *pvertices = NULL; + return 0; +} + +static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo * info, int glyph_index, int * x0, int * y0, int * x1, int * y1) +{ + stbtt__csctx c = STBTT__CSCTX_INIT(1); + int r = stbtt__run_charstring(info, glyph_index, &c); + if(x0) *x0 = r ? c.min_x : 0; + if(y0) *y0 = r ? c.min_y : 0; + if(x1) *x1 = r ? c.max_x : 0; + if(y1) *y1 = r ? c.max_y : 0; + return r ? c.num_vertices : 0; +} + +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo * info, int glyph_index, stbtt_vertex * *pvertices) +{ + if(!info->cff.size) + return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices); + else + return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices); +} + +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo * info, int glyph_index, int * advanceWidth, + int * leftSideBearing) +{ + stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data, info->hhea + 34); + if(glyph_index < numOfLongHorMetrics) { + if(advanceWidth) *advanceWidth = ttSHORT(info->data, info->hmtx + 4 * glyph_index); + if(leftSideBearing) *leftSideBearing = ttSHORT(info->data, info->hmtx + 4 * glyph_index + 2); + } + else { + if(advanceWidth) *advanceWidth = ttSHORT(info->data, info->hmtx + 4 * (numOfLongHorMetrics - 1)); + if(leftSideBearing) *leftSideBearing = ttSHORT(info->data, + info->hmtx + 4 * numOfLongHorMetrics + 2 * (glyph_index - numOfLongHorMetrics)); + } +} + +STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo * info) +{ + // we only look at the first table. it must be 'horizontal' and format 0. + if(!info->kern) + return 0; + if(ttUSHORT(info->data, 2 + info->kern) < 1) // number of tables, need at least 1 + return 0; + if(ttUSHORT(info->data, 8 + info->kern) != 1) // horizontal flag must be set in format + return 0; + + return ttUSHORT(info->data, 10 + info->kern); +} + +STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo * info, stbtt_kerningentry * table, int table_length) +{ + int k, length; + + // we only look at the first table. it must be 'horizontal' and format 0. + if(!info->kern) + return 0; + if(ttUSHORT(info->data, 2 + info->kern) < 1) // number of tables, need at least 1 + return 0; + if(ttUSHORT(info->data, 8 + info->kern) != 1) // horizontal flag must be set in format + return 0; + + length = ttUSHORT(info->data, 10 + info->kern); + if(table_length < length) + length = table_length; + + for(k = 0; k < length; k++) { + table[k].glyph1 = ttUSHORT(info->data, 18 + (k * 6) + info->kern); + table[k].glyph2 = ttUSHORT(info->data, 20 + (k * 6) + info->kern); + table[k].advance = ttSHORT(info->data, 22 + (k * 6) + info->kern); + } + + return length; +} + +static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo * info, int glyph1, int glyph2) +{ + stbtt_uint32 needle, straw; + int l, r, m; + + // we only look at the first table. it must be 'horizontal' and format 0. + if(!info->kern) + return 0; + if(ttUSHORT(info->data, info->kern + 2) < 1) // number of tables, need at least 1 + return 0; + if(ttUSHORT(info->data, info->kern + 8) != 1) // horizontal flag must be set in format + return 0; + + l = 0; + r = ttUSHORT(info->data, info->kern + 10) - 1; + needle = glyph1 << 16 | glyph2; + while(l <= r) { + m = (l + r) >> 1; + straw = ttULONG(info->data, info->kern + 18 + (m * 6)); // note: unaligned read + if(needle < straw) + r = m - 1; + else if(needle > straw) + l = m + 1; + else + return ttSHORT(info->data, info->kern + 22 + (m * 6)); + } + return 0; +} +#ifdef STBTT_STREAM_TYPE + static stbtt_int32 stbtt__GetCoverageIndex(STBTT_STREAM_TYPE data, stbtt_uint32 coverageTable, int glyph) +#else + static stbtt_int32 stbtt__GetCoverageIndex(const stbtt_uint8 * data, stbtt_uint32 coverageTable, int glyph) +#endif +{ + stbtt_uint16 coverageFormat = ttUSHORT(data, coverageTable); + switch(coverageFormat) { + case 1: { + stbtt_uint16 glyphCount = ttUSHORT(data, coverageTable + 2); + + // Binary search. + stbtt_int32 l = 0, r = glyphCount - 1, m; + int straw, needle = glyph; + while(l <= r) { + stbtt_uint32 glyphArray = coverageTable + 4; + stbtt_uint16 glyphID; + m = (l + r) >> 1; + glyphID = ttUSHORT(data, glyphArray + 2 * m); + straw = glyphID; + if(needle < straw) + r = m - 1; + else if(needle > straw) + l = m + 1; + else { + return m; + } + } + break; + } + + case 2: { + stbtt_uint16 rangeCount = ttUSHORT(data, coverageTable + 2); + stbtt_uint32 rangeArray = coverageTable + 4; + + // Binary search. + stbtt_int32 l = 0, r = rangeCount - 1, m; + int strawStart, strawEnd, needle = glyph; + while(l <= r) { + stbtt_uint32 rangeRecord; + m = (l + r) >> 1; + rangeRecord = rangeArray + 6 * m; + strawStart = ttUSHORT(data, rangeRecord); + strawEnd = ttUSHORT(data, rangeRecord + 2); + if(needle < strawStart) + r = m - 1; + else if(needle > strawEnd) + l = m + 1; + else { + stbtt_uint16 startCoverageIndex = ttUSHORT(data, rangeRecord + 4); + return startCoverageIndex + glyph - strawStart; + } + } + break; + } + + default: + return -1; // unsupported + } + + return -1; +} +#ifdef STBTT_STREAM_TYPE + static stbtt_int32 stbtt__GetGlyphClass(STBTT_STREAM_TYPE data, stbtt_uint32 classDefTable, int glyph) +#else + static stbtt_int32 stbtt__GetGlyphClass(const stbtt_uint8 * data, stbtt_uint32 classDefTable, int glyph) +#endif +{ + stbtt_uint16 classDefFormat = ttUSHORT(data, classDefTable); + switch(classDefFormat) { + case 1: { + stbtt_uint16 startGlyphID = ttUSHORT(data, classDefTable + 2); + stbtt_uint16 glyphCount = ttUSHORT(data, classDefTable + 4); + stbtt_uint32 classDef1ValueArray = classDefTable + 6; + + if(glyph >= startGlyphID && glyph < startGlyphID + glyphCount) + return (stbtt_int32)ttUSHORT(data, classDef1ValueArray + 2 * (glyph - startGlyphID)); + break; + } + + case 2: { + stbtt_uint16 classRangeCount = ttUSHORT(data, classDefTable + 2); + stbtt_uint32 classRangeRecords = classDefTable + 4; + + // Binary search. + stbtt_int32 l = 0, r = classRangeCount - 1, m; + int strawStart, strawEnd, needle = glyph; + while(l <= r) { + stbtt_uint32 classRangeRecord; + m = (l + r) >> 1; + classRangeRecord = classRangeRecords + 6 * m; + strawStart = ttUSHORT(data, classRangeRecord); + strawEnd = ttUSHORT(data, classRangeRecord + 2); + if(needle < strawStart) + r = m - 1; + else if(needle > strawEnd) + l = m + 1; + else + return (stbtt_int32)ttUSHORT(data, classRangeRecord + 4); + } + break; + } + + default: + return -1; // Unsupported definition type, return an error. + } + + // "All glyphs not assigned to a class fall into class 0". (OpenType spec) + return 0; +} + +// Define to STBTT_assert(x) if you want to break on unimplemented formats. +#define STBTT_GPOS_TODO_assert(x) + +static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo * info, int glyph1, int glyph2) +{ + stbtt_uint16 lookupListOffset; + stbtt_uint32 lookupList; + stbtt_uint16 lookupCount; +#ifdef STBTT_STREAM_TYPE + STBTT_STREAM_TYPE data = info->data; +#else + const stbtt_uint8 * data = info->data; +#endif + stbtt_int32 i, sti; + + if(!info->gpos) return 0; + + if(ttUSHORT(data, 0 + info->gpos) != 1) return 0; // Major version 1 + if(ttUSHORT(data, 2 + info->gpos) != 0) return 0; // Minor version 0 + + lookupListOffset = ttUSHORT(data, 8 + info->gpos); + lookupList = lookupListOffset; + lookupCount = ttUSHORT(data, lookupList); + + for(i = 0; i < lookupCount; ++i) { + stbtt_uint16 lookupOffset = ttUSHORT(data, lookupList + 2 + 2 * i); + stbtt_uint32 lookupTable = lookupList + lookupOffset; + + stbtt_uint16 lookupType = ttUSHORT(data, lookupTable); + stbtt_uint16 subTableCount = ttUSHORT(data, lookupTable + 4); + stbtt_uint32 subTableOffsets = lookupTable + 6; + if(lookupType != 2) // Pair Adjustment Positioning Subtable + continue; + + for(sti = 0; sti < subTableCount; sti++) { + stbtt_uint16 subtableOffset = ttUSHORT(data, subTableOffsets + 2 * sti); + stbtt_uint32 table = lookupTable + subtableOffset; + stbtt_uint16 posFormat = ttUSHORT(data, table); + stbtt_uint16 coverageOffset = ttUSHORT(data, table + 2); + stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(data, table + coverageOffset, glyph1); + if(coverageIndex == -1) continue; + + switch(posFormat) { + case 1: { + stbtt_int32 l, r, m; + int straw, needle; + stbtt_uint16 valueFormat1 = ttUSHORT(data, table + 4); + stbtt_uint16 valueFormat2 = ttUSHORT(data, table + 6); + if(valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats? + stbtt_int32 valueRecordPairSizeInBytes = 2; + stbtt_uint16 pairSetCount = ttUSHORT(data, table + 8); + stbtt_uint16 pairPosOffset = ttUSHORT(data, table + 10 + 2 * coverageIndex); + stbtt_uint32 pairValueTable = table + pairPosOffset; + stbtt_uint16 pairValueCount = ttUSHORT(data, pairValueTable); + stbtt_uint32 pairValueArray = pairValueTable + 2; + + if(coverageIndex >= pairSetCount) return 0; + + needle = glyph2; + r = pairValueCount - 1; + l = 0; + + // Binary search. + while(l <= r) { + stbtt_uint16 secondGlyph; + stbtt_uint32 pairValue; + m = (l + r) >> 1; + pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; + secondGlyph = ttUSHORT(data, pairValue); + straw = secondGlyph; + if(needle < straw) + r = m - 1; + else if(needle > straw) + l = m + 1; + else { + stbtt_int16 xAdvance = ttSHORT(data, pairValue + 2); + return xAdvance; + } + } + } + else + return 0; + break; + } + + case 2: { + stbtt_uint16 valueFormat1 = ttUSHORT(data, table + 4); + stbtt_uint16 valueFormat2 = ttUSHORT(data, table + 6); + if(valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats? + stbtt_uint16 classDef1Offset = ttUSHORT(data, table + 8); + stbtt_uint16 classDef2Offset = ttUSHORT(data, table + 10); + int glyph1class = stbtt__GetGlyphClass(data, table + classDef1Offset, glyph1); + int glyph2class = stbtt__GetGlyphClass(data, table + classDef2Offset, glyph2); + + stbtt_uint16 class1Count = ttUSHORT(data, table + 12); + stbtt_uint16 class2Count = ttUSHORT(data, table + 14); + stbtt_uint32 class1Records, class2Records; + stbtt_int16 xAdvance; + + if(glyph1class < 0 || glyph1class >= class1Count) return 0; // malformed + if(glyph2class < 0 || glyph2class >= class2Count) return 0; // malformed + + class1Records = table + 16; + class2Records = class1Records + 2 * (glyph1class * class2Count); + xAdvance = ttSHORT(data, class2Records + 2 * glyph2class); + return xAdvance; + } + else + return 0; + break; + } + + default: + return 0; // Unsupported position format + } + } + } + return 0; +} + +STBTT_DEF int stbtt_KernTableCheck(const stbtt_fontinfo * info) +{ + if(info->gpos) { + stbtt_uint16 lookupListOffset; + stbtt_uint32 lookupList; + stbtt_uint16 lookupCount; +#ifdef STBTT_STREAM_TYPE + STBTT_STREAM_TYPE data = info->data; +#else + const stbtt_uint8 * data = info->data; +#endif + stbtt_int32 i; + + if(!info->gpos) return 0; + + if(ttUSHORT(data, 0 + info->gpos) != 1) return 0; // Major version 1 + if(ttUSHORT(data, 2 + info->gpos) != 0) return 0; // Minor version 0 + + lookupListOffset = ttUSHORT(data, 8 + info->gpos); + lookupList = lookupListOffset; + lookupCount = ttUSHORT(data, lookupList); + + for(i = 0; i < lookupCount; ++i) { + stbtt_uint16 lookupOffset = ttUSHORT(data, lookupList + 2 + 2 * i); + stbtt_uint32 lookupTable = lookupList + lookupOffset; + + stbtt_uint16 lookupType = ttUSHORT(data, lookupTable); + + if(lookupType != 2) // Pair Adjustment Positioning Subtable + continue; + + return 1; // we have a usable lookup table. + } + return 0; + } + else if(info->kern) { + return 1; + } + return 0; +} + +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo * info, int g1, int g2) +{ + int xAdvance = 0; + + if(info->gpos) + xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); + else if(info->kern) + xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); + + return xAdvance; +} + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo * info, int ch1, int ch2) +{ + if(!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs + return 0; + return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info, ch1), stbtt_FindGlyphIndex(info, ch2)); +} + +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo * info, int codepoint, int * advanceWidth, + int * leftSideBearing) +{ + stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info, codepoint), advanceWidth, leftSideBearing); +} + +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo * info, int * ascent, int * descent, int * lineGap) +{ + if(ascent) *ascent = ttSHORT(info->data, info->hhea + 4); + if(descent) *descent = ttSHORT(info->data, info->hhea + 6); + if(lineGap) *lineGap = ttSHORT(info->data, info->hhea + 8); +} + +STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo * info, int * typoAscent, int * typoDescent, + int * typoLineGap) +{ + int tab = stbtt__find_table(info->data, info->fontstart, "OS/2"); + if(!tab) + return 0; + if(typoAscent) *typoAscent = ttSHORT(info->data, tab + 68); + if(typoDescent) *typoDescent = ttSHORT(info->data, tab + 70); + if(typoLineGap) *typoLineGap = ttSHORT(info->data, tab + 72); + return 1; +} + +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo * info, int * x0, int * y0, int * x1, int * y1) +{ + *x0 = ttSHORT(info->data, info->head + 36); + *y0 = ttSHORT(info->data, info->head + 38); + *x1 = ttSHORT(info->data, info->head + 40); + *y1 = ttSHORT(info->data, info->head + 42); +} + +STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo * info, float height) +{ + int fheight = ttSHORT(info->data, info->hhea + 4) - ttSHORT(info->data, info->hhea + 6); + return (float)height / fheight; +} + +STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo * info, float pixels) +{ + int unitsPerEm = ttUSHORT(info->data, info->head + 18); + return pixels / unitsPerEm; +} + +STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo * info, stbtt_vertex * v) +{ + STBTT_free(v, info->userdata); +} + +STBTT_DEF stbtt_uint32 stbtt_FindSVGDoc(const stbtt_fontinfo * info, int gl) +{ + int i; + stbtt_uint32 svg_doc_list = stbtt__get_svg((stbtt_fontinfo *)info); + + int numEntries = ttUSHORT(info->data, svg_doc_list); + stbtt_uint32 svg_docs = svg_doc_list + 2; + + for(i = 0; i < numEntries; i++) { + stbtt_uint32 svg_doc = svg_docs + (12 * i); + if((gl >= ttUSHORT(info->data, svg_doc)) && (gl <= ttUSHORT(info->data, svg_doc + 2))) + return svg_doc; + } + return 0; +} + +STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo * info, int gl, stbtt_uint32 * svgOfs) +{ + stbtt_uint32 svg_doc; + + if(info->svg == 0) + return 0; + + svg_doc = stbtt_FindSVGDoc(info, gl); + if(svg_doc != 0) { + *svgOfs = info->svg + ttULONG(info->data, svg_doc + 4); + return ttULONG(info->data, svg_doc + 8); + } + else { + return 0; + } +} + +STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo * info, int unicode_codepoint, stbtt_uint32 * svgOfs) +{ + return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svgOfs); +} + +////////////////////////////////////////////////////////////////////////////// +// +// antialiasing software rasterizer +// + +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo * font, int glyph, float scale_x, float scale_y, + float shift_x, float shift_y, int * ix0, int * iy0, int * ix1, int * iy1) +{ + int x0 = 0, y0 = 0, x1, y1; // =0 suppresses compiler warning + if(!stbtt_GetGlyphBox(font, glyph, &x0, &y0, &x1, &y1)) { + // e.g. space character + if(ix0) *ix0 = 0; + if(iy0) *iy0 = 0; + if(ix1) *ix1 = 0; + if(iy1) *iy1 = 0; + } + else { + // move to integral bboxes (treating pixels as little squares, what pixels get touched)? + if(ix0) *ix0 = STBTT_ifloor(x0 * scale_x + shift_x); + if(iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); + if(ix1) *ix1 = STBTT_iceil(x1 * scale_x + shift_x); + if(iy1) *iy1 = STBTT_iceil(-y0 * scale_y + shift_y); + } +} + +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo * font, int glyph, float scale_x, float scale_y, int * ix0, + int * iy0, int * ix1, int * iy1) +{ + stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1); +} + +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo * font, int codepoint, float scale_x, + float scale_y, float shift_x, float shift_y, int * ix0, int * iy0, int * ix1, int * iy1) +{ + stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font, codepoint), scale_x, scale_y, shift_x, shift_y, ix0, + iy0, ix1, iy1); +} + +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo * font, int codepoint, float scale_x, float scale_y, + int * ix0, int * iy0, int * ix1, int * iy1) +{ + stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Rasterizer + +typedef struct stbtt__hheap_chunk { + struct stbtt__hheap_chunk * next; +} stbtt__hheap_chunk; + +typedef struct stbtt__hheap { + struct stbtt__hheap_chunk * head; + void * first_free; + int num_remaining_in_head_chunk; +} stbtt__hheap; + +static void * stbtt__hheap_alloc(stbtt__hheap * hh, size_t size, void * userdata) +{ + if(hh->first_free) { + void * p = hh->first_free; + hh->first_free = *(void **)p; + return p; + } + else { + if(hh->num_remaining_in_head_chunk == 0) { + int count = (size < 32 ? STBTT_HEAP_FACTOR_SIZE_32 : size < 128 ? STBTT_HEAP_FACTOR_SIZE_128 : + STBTT_HEAP_FACTOR_SIZE_DEFAULT); + stbtt__hheap_chunk * c = (stbtt__hheap_chunk *)STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); + if(c == NULL) + return NULL; + c->next = hh->head; + hh->head = c; + hh->num_remaining_in_head_chunk = count; + } + --hh->num_remaining_in_head_chunk; + return (char *)(hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk; + } +} + +static void stbtt__hheap_free(stbtt__hheap * hh, void * p) +{ + *(void **)p = hh->first_free; + hh->first_free = p; +} + +static void stbtt__hheap_cleanup(stbtt__hheap * hh, void * userdata) +{ + stbtt__hheap_chunk * c = hh->head; + while(c) { + stbtt__hheap_chunk * n = c->next; + STBTT_free(c, userdata); + c = n; + } +} + +typedef struct stbtt__edge { + float x0, y0, x1, y1; + int invert; +} stbtt__edge; + +typedef struct stbtt__active_edge { + struct stbtt__active_edge * next; +#if STBTT_RASTERIZER_VERSION==1 + int x, dx; + float ey; + int direction; +#elif STBTT_RASTERIZER_VERSION==2 + float fx, fdx, fdy; + float direction; + float sy; + float ey; +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif +} stbtt__active_edge; + +#if STBTT_RASTERIZER_VERSION == 1 +#define STBTT_FIXSHIFT 10 +#define STBTT_FIX (1 << STBTT_FIXSHIFT) +#define STBTT_FIXMASK (STBTT_FIX-1) + +static stbtt__active_edge * stbtt__new_active(stbtt__hheap * hh, stbtt__edge * e, int off_x, float start_point, + void * userdata) +{ + stbtt__active_edge * z = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + if(!z) return z; + + // round dx down to avoid overshooting + if(dxdy < 0) + z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); + else + z->dx = STBTT_ifloor(STBTT_FIX * dxdy); + + z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - + e->y0)); // use z->dx so when we offset later it's by the same amount + z->x -= off_x * STBTT_FIX; + + z->ey = e->y1; + z->next = 0; + z->direction = e->invert ? 1 : -1; + return z; +} +#elif STBTT_RASTERIZER_VERSION == 2 +static stbtt__active_edge * stbtt__new_active(stbtt__hheap * hh, stbtt__edge * e, int off_x, float start_point, + void * userdata) +{ + stbtt__active_edge * z = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + //STBTT_assert(e->y0 <= start_point); + if(!z) return z; + z->fdx = dxdy; + z->fdy = dxdy != 0.0f ? (1.0f / dxdy) : 0.0f; + z->fx = e->x0 + dxdy * (start_point - e->y0); + z->fx -= off_x; + z->direction = e->invert ? 1.0f : -1.0f; + z->sy = e->y0; + z->ey = e->y1; + z->next = 0; + return z; +} +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + +#if STBTT_RASTERIZER_VERSION == 1 +// note: this routine clips fills that extend off the edges... ideally this +// wouldn't happen, but it could happen if the truetype glyph bounding boxes +// are wrong, or if the user supplies a too-small bitmap +static void stbtt__fill_active_edges(unsigned char * scanline, int len, stbtt__active_edge * e, int max_weight) +{ + // non-zero winding fill + int x0 = 0, w = 0; + + while(e) { + if(w == 0) { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; + w += e->direction; + } + else { + int x1 = e->x; + w += e->direction; + // if we went to zero, we need to draw + if(w == 0) { + int i = x0 >> STBTT_FIXSHIFT; + int j = x1 >> STBTT_FIXSHIFT; + + if(i < len && j >= 0) { + if(i == j) { + // x0,x1 are the same pixel, so compute combined coverage + scanline[i] = scanline[i] + (stbtt_uint8)((x1 - x0) * max_weight >> STBTT_FIXSHIFT); + } + else { + if(i >= 0) // add antialiasing for x0 + scanline[i] = scanline[i] + (stbtt_uint8)(((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT); + else + i = -1; // clip + + if(j < len) // add antialiasing for x1 + scanline[j] = scanline[j] + (stbtt_uint8)(((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT); + else + j = len; // clip + + for(++i; i < j; ++i) // fill pixels between x0 and x1 + scanline[i] = scanline[i] + (stbtt_uint8)max_weight; + } + } + } + } + + e = e->next; + } +} + +static void stbtt__rasterize_sorted_edges(stbtt__bitmap * result, stbtt__edge * e, int n, int vsubsample, int off_x, + int off_y, void * userdata) +{ + stbtt__hheap hh = { 0, 0, 0 }; + stbtt__active_edge * active = NULL; + int y, j = 0; + int max_weight = (255 / vsubsample); // weight per vertical scanline + int s; // vertical subsample index + unsigned char scanline_data[512], * scanline; + + if(result->w > 512) + scanline = (unsigned char *)STBTT_malloc(result->w, userdata); + else + scanline = scanline_data; + + y = off_y * vsubsample; + e[n].y0 = (off_y + result->h) * (float)vsubsample + 1; + + while(j < result->h) { + STBTT_memset(scanline, 0, result->w); + for(s = 0; s < vsubsample; ++s) { + // find center of pixel for this scanline + float scan_y = y + 0.5f; + stbtt__active_edge ** step = &active; + + // update all active edges; + // remove all active edges that terminate before the center of this scanline + while(*step) { + stbtt__active_edge * z = *step; + if(z->ey <= scan_y) { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } + else { + z->x += z->dx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + } + + // resort the list if needed + for(;;) { + int changed = 0; + step = &active; + while(*step && (*step)->next) { + if((*step)->x > (*step)->next->x) { + stbtt__active_edge * t = *step; + stbtt__active_edge * q = t->next; + + t->next = q->next; + q->next = t; + *step = q; + changed = 1; + } + step = &(*step)->next; + } + if(!changed) break; + } + + // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline + while(e->y0 <= scan_y) { + if(e->y1 > scan_y) { + stbtt__active_edge * z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); + if(z != NULL) { + // find insertion point + if(active == NULL) + active = z; + else if(z->x < active->x) { + // insert at front + z->next = active; + active = z; + } + else { + // find thing to insert AFTER + stbtt__active_edge * p = active; + while(p->next && p->next->x < z->x) + p = p->next; + // at this point, p->next->x is NOT < z->x + z->next = p->next; + p->next = z; + } + } + } + ++e; + } + + // now process all active edges in XOR fashion + if(active) + stbtt__fill_active_edges(scanline, result->w, active, max_weight); + + ++y; + } + STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); + ++j; + } + + stbtt__hheap_cleanup(&hh, userdata); + + if(scanline != scanline_data) + STBTT_free(scanline, userdata); +} + +#elif STBTT_RASTERIZER_VERSION == 2 + +// the edge passed in here does not cross the vertical line at x or the vertical line at x+1 +// (i.e. it has already been clipped to those) +static void stbtt__handle_clipped_edge(float * scanline, int x, stbtt__active_edge * e, float x0, float y0, float x1, + float y1) +{ + if(y0 == y1) return; + STBTT_assert(y0 < y1); + STBTT_assert(e->sy <= e->ey); + if(y0 > e->ey) return; + if(y1 < e->sy) return; + if(y0 < e->sy) { + x0 += (x1 - x0) * (e->sy - y0) / (y1 - y0); + y0 = e->sy; + } + if(y1 > e->ey) { + x1 += (x1 - x0) * (e->ey - y1) / (y1 - y0); + y1 = e->ey; + } + + if(x0 == x) + STBTT_assert(x1 <= x + 1); + else if(x0 == x + 1) + STBTT_assert(x1 >= x); + else if(x0 <= x) + STBTT_assert(x1 <= x); + else if(x0 >= x + 1) + STBTT_assert(x1 >= x + 1); + else + STBTT_assert(x1 >= x && x1 <= x + 1); + + if(x0 <= x && x1 <= x) + scanline[x] += e->direction * (y1 - y0); + else if(x0 >= x + 1 && x1 >= x + 1) { + /*Nothing to do*/; + } + else { + STBTT_assert(x0 >= x && x0 <= x + 1 && x1 >= x && x1 <= x + 1); + scanline[x] += e->direction * (y1 - y0) * (1 - ((x0 - x) + (x1 - x)) / 2); // coverage = 1 - average x position + } +} + +static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width) +{ + STBTT_assert(top_width >= 0); + STBTT_assert(bottom_width >= 0); + return (top_width + bottom_width) / 2.0f * height; +} + +static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1) +{ + return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0); +} + +static float stbtt__sized_triangle_area(float height, float width) +{ + return height * width / 2; +} + +static void stbtt__fill_active_edges_new(float * scanline, float * scanline_fill, int len, stbtt__active_edge * e, + float y_top) +{ + float y_bottom = y_top + 1; + + while(e) { + // brute force every pixel + + // compute intersection points with top & bottom + STBTT_assert(e->ey >= y_top); + + if(e->fdx == 0) { + float x0 = e->fx; + if(x0 < len) { + if(x0 >= 0) { + stbtt__handle_clipped_edge(scanline, (int)x0, e, x0, y_top, x0, y_bottom); + stbtt__handle_clipped_edge(scanline_fill - 1, (int)x0 + 1, e, x0, y_top, x0, y_bottom); + } + else { + stbtt__handle_clipped_edge(scanline_fill - 1, 0, e, x0, y_top, x0, y_bottom); + } + } + } + else { + float x0 = e->fx; + float dx = e->fdx; + float xb = x0 + dx; + float x_top, x_bottom; + float sy0, sy1; + float dy = e->fdy; + STBTT_assert(e->sy <= y_bottom && e->ey >= y_top); + + // compute endpoints of line segment clipped to this scanline (if the + // line segment starts on this scanline. x0 is the intersection of the + // line with y_top, but that may be off the line segment. + if(e->sy > y_top) { + x_top = x0 + dx * (e->sy - y_top); + sy0 = e->sy; + } + else { + x_top = x0; + sy0 = y_top; + } + if(e->ey < y_bottom) { + x_bottom = x0 + dx * (e->ey - y_top); + sy1 = e->ey; + } + else { + x_bottom = xb; + sy1 = y_bottom; + } + + if(x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) { + // from here on, we don't have to range check x values + + if((int)x_top == (int)x_bottom) { + float height; + // simple case, only spans one pixel + int x = (int)x_top; + height = (sy1 - sy0) * e->direction; + STBTT_assert(x >= 0 && x < len); + scanline[x] += stbtt__position_trapezoid_area(height, x_top, x + 1.0f, x_bottom, x + 1.0f); + scanline_fill[x] += height; // everything right of this pixel is filled + } + else { + int x, x1, x2; + float y_crossing, y_final, step, sign, area; + // covers 2+ pixels + if(x_top > x_bottom) { + // flip scanline vertically; signed area is the same + float t; + sy0 = y_bottom - (sy0 - y_top); + sy1 = y_bottom - (sy1 - y_top); + t = sy0, sy0 = sy1, sy1 = t; + t = x_bottom, x_bottom = x_top, x_top = t; + dx = -dx; + dy = -dy; + t = x0, x0 = xb, xb = t; + } + STBTT_assert(dy >= 0); + STBTT_assert(dx >= 0); + + x1 = (int)x_top; + x2 = (int)x_bottom; + // compute intersection with y axis at x1+1 + y_crossing = y_top + dy * (x1 + 1 - x0); + + // compute intersection with y axis at x2 + y_final = y_top + dy * (x2 - x0); + + // x1 x_top x2 x_bottom + // y_top +------|-----+------------+------------+--------|---+------------+ + // | | | | | | + // | | | | | | + // sy0 | Txxxxx|............|............|............|............| + // y_crossing | *xxxxx.......|............|............|............| + // | | xxxxx..|............|............|............| + // | | /- xx*xxxx........|............|............| + // | | dy < | xxxxxx..|............|............| + // y_final | | \- | xx*xxx.........|............| + // sy1 | | | | xxxxxB...|............| + // | | | | | | + // | | | | | | + // y_bottom +------------+------------+------------+------------+------------+ + // + // goal is to measure the area covered by '.' in each pixel + + // if x2 is right at the right edge of x1, y_crossing can blow up, github #1057 + // @TODO: maybe test against sy1 rather than y_bottom? + if(y_crossing > y_bottom) + y_crossing = y_bottom; + + sign = e->direction; + + // area of the rectangle covered from sy0..y_crossing + area = sign * (y_crossing - sy0); + + // area of the triangle (x_top,sy0), (x1+1,sy0), (x1+1,y_crossing) + scanline[x1] += stbtt__sized_triangle_area(area, x1 + 1 - x_top); + + // check if final y_crossing is blown up; no test case for this + if(y_final > y_bottom) { + y_final = y_bottom; + dy = (y_final - y_crossing) / (x2 - (x1 + 1)); // if denom=0, y_final = y_crossing, so y_final <= y_bottom + } + + // in second pixel, area covered by line segment found in first pixel + // is always a rectangle 1 wide * the height of that line segment; this + // is exactly what the variable 'area' stores. it also gets a contribution + // from the line segment within it. the THIRD pixel will get the first + // pixel's rectangle contribution, the second pixel's rectangle contribution, + // and its own contribution. the 'own contribution' is the same in every pixel except + // the leftmost and rightmost, a trapezoid that slides down in each pixel. + // the second pixel's contribution to the third pixel will be the + // rectangle 1 wide times the height change in the second pixel, which is dy. + + step = sign * dy * 1; // dy is dy/dx, change in y for every 1 change in x, + // which multiplied by 1-pixel-width is how much pixel area changes for each step in x + // so the area advances by 'step' every time + + for(x = x1 + 1; x < x2; ++x) { + scanline[x] += area + step / 2; // area of trapezoid is 1*step/2 + area += step; + } + STBTT_assert(STBTT_fabs(area) <= 1.01f); // accumulated error from area += step unless we round step down + STBTT_assert(sy1 > y_final - 0.01f); + + // area covered in the last pixel is the rectangle from all the pixels to the left, + // plus the trapezoid filled by the line segment in this pixel all the way to the right edge + scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1 - y_final, (float)x2, x2 + 1.0f, x_bottom, x2 + 1.0f); + + // the rest of the line is filled based on the total height of the line segment in this pixel + scanline_fill[x2] += sign * (sy1 - sy0); + } + } + else { + // if edge goes outside of box we're drawing, we require + // clipping logic. since this does not match the intended use + // of this library, we use a different, very slow brute + // force implementation + // note though that this does happen some of the time because + // x_top and x_bottom can be extrapolated at the top & bottom of + // the shape and actually lie outside the bounding box + int x; + for(x = 0; x < len; ++x) { + // cases: + // + // there can be up to two intersections with the pixel. any intersection + // with left or right edges can be handled by splitting into two (or three) + // regions. intersections with top & bottom do not necessitate case-wise logic. + // + // the old way of doing this found the intersections with the left & right edges, + // then used some simple logic to produce up to three segments in sorted order + // from top-to-bottom. however, this had a problem: if an x edge was epsilon + // across the x border, then the corresponding y position might not be distinct + // from the other y segment, and it might ignored as an empty segment. to avoid + // that, we need to explicitly produce segments based on x positions. + + // rename variables to clearly-defined pairs + float y0 = y_top; + float x1 = (float)(x); + float x2 = (float)(x + 1); + float x3 = xb; + float y3 = y_bottom; + + // x = e->x + e->dx * (y-y_top) + // (y-y_top) = (x - e->x) / e->dx + // y = (x - e->x) / e->dx + y_top + float y1 = (x - x0) / dx + y_top; + float y2 = (x + 1 - x0) / dx + y_top; + + if(x0 < x1 && x3 > x2) { // three segments descending down-right + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1); + stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x2, y2); + stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3); + } + else if(x3 < x1 && x0 > x2) { // three segments descending down-left + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2); + stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x1, y1); + stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3); + } + else if(x0 < x1 && x3 > x1) { // two segments across x, down-right + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1); + stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3); + } + else if(x3 < x1 && x0 > x1) { // two segments across x, down-left + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1); + stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3); + } + else if(x0 < x2 && x3 > x2) { // two segments across x+1, down-right + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2); + stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3); + } + else if(x3 < x2 && x0 > x2) { // two segments across x+1, down-left + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2); + stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3); + } + else { // one segment + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x3, y3); + } + } + } + } + e = e->next; + } +} + +// directly AA rasterize edges w/o supersampling +static void stbtt__rasterize_sorted_edges(stbtt__bitmap * result, stbtt__edge * e, int n, int vsubsample, int off_x, + int off_y, void * userdata) +{ + stbtt__hheap hh = { 0, 0, 0 }; + stbtt__active_edge * active = NULL; + int y, j = 0, i; + float scanline_data[129], * scanline, * scanline2; + + STBTT__NOTUSED(vsubsample); + + if(result->w > 64) + scanline = (float *)STBTT_malloc((result->w * 2 + 1) * sizeof(float), userdata); + else + scanline = scanline_data; + + scanline2 = scanline + result->w; + + y = off_y; + e[n].y0 = (float)(off_y + result->h) + 1; + + while(j < result->h) { + // find center of pixel for this scanline + float scan_y_top = y + 0.0f; + float scan_y_bottom = y + 1.0f; + stbtt__active_edge ** step = &active; + + STBTT_memset(scanline, 0, result->w * sizeof(scanline[0])); + STBTT_memset(scanline2, 0, (result->w + 1) * sizeof(scanline[0])); + + // update all active edges; + // remove all active edges that terminate before the top of this scanline + while(*step) { + stbtt__active_edge * z = *step; + if(z->ey <= scan_y_top) { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } + else { + step = &((*step)->next); // advance through list + } + } + + // insert all edges that start before the bottom of this scanline + while(e->y0 <= scan_y_bottom) { + if(e->y0 != e->y1) { + stbtt__active_edge * z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); + if(z != NULL) { + if(j == 0 && off_y != 0) { + if(z->ey < scan_y_top) { + // this can happen due to subpixel positioning and some kind of fp rounding error i think + z->ey = scan_y_top; + } + } + STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds + // insert at front + z->next = active; + active = z; + } + } + ++e; + } + + // now process all active edges + if(active) + stbtt__fill_active_edges_new(scanline, scanline2 + 1, result->w, active, scan_y_top); + + { + float sum = 0; + for(i = 0; i < result->w; ++i) { + float k; + int m; + sum += scanline2[i]; + k = scanline[i] + sum; + k = (float)STBTT_fabs(k) * 255 + 0.5f; + m = (int)k; + if(m > 255) m = 255; + result->pixels[j * result->stride + i] = (unsigned char)m; + } + } + // advance all the edges + step = &active; + while(*step) { + stbtt__active_edge * z = *step; + z->fx += z->fdx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + + ++y; + ++j; + } + + stbtt__hheap_cleanup(&hh, userdata); + + if(scanline != scanline_data) + STBTT_free(scanline, userdata); +} +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + +#define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0) + +static void stbtt__sort_edges_ins_sort(stbtt__edge * p, int n) +{ + int i, j; + for(i = 1; i < n; ++i) { + stbtt__edge t = p[i], * a = &t; + j = i; + while(j > 0) { + stbtt__edge * b = &p[j - 1]; + int c = STBTT__COMPARE(a, b); + if(!c) break; + p[j] = p[j - 1]; + --j; + } + if(i != j) + p[j] = t; + } +} + +static void stbtt__sort_edges_quicksort(stbtt__edge * p, int n) +{ + /* threshold for transitioning to insertion sort */ + while(n > 12) { + stbtt__edge t; + int c01, c12, c, m, i, j; + + /* compute median of three */ + m = n >> 1; + c01 = STBTT__COMPARE(&p[0], &p[m]); + c12 = STBTT__COMPARE(&p[m], &p[n - 1]); + /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ + if(c01 != c12) { + /* otherwise, we'll need to swap something else to middle */ + int z; + c = STBTT__COMPARE(&p[0], &p[n - 1]); + /* 0>mid && midn => n; 0 0 */ + /* 0n: 0>n => 0; 0 n */ + z = (c == c12) ? 0 : n - 1; + t = p[z]; + p[z] = p[m]; + p[m] = t; + } + /* now p[m] is the median-of-three */ + /* swap it to the beginning so it won't move around */ + t = p[0]; + p[0] = p[m]; + p[m] = t; + + /* partition loop */ + i = 1; + j = n - 1; + for(;;) { + /* handling of equality is crucial here */ + /* for sentinels & efficiency with duplicates */ + for(;; ++i) { + if(!STBTT__COMPARE(&p[i], &p[0])) break; + } + for(;; --j) { + if(!STBTT__COMPARE(&p[0], &p[j])) break; + } + /* make sure we haven't crossed */ + if(i >= j) break; + t = p[i]; + p[i] = p[j]; + p[j] = t; + + ++i; + --j; + } + /* recurse on smaller side, iterate on larger */ + if(j < (n - i)) { + stbtt__sort_edges_quicksort(p, j); + p = p + i; + n = n - i; + } + else { + stbtt__sort_edges_quicksort(p + i, n - i); + n = j; + } + } +} + +static void stbtt__sort_edges(stbtt__edge * p, int n) +{ + stbtt__sort_edges_quicksort(p, n); + stbtt__sort_edges_ins_sort(p, n); +} + +typedef struct { + float x, y; +} stbtt__point; + +static void stbtt__rasterize(stbtt__bitmap * result, stbtt__point * pts, int * wcount, int windings, float scale_x, + float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void * userdata) +{ + float y_scale_inv = invert ? -scale_y : scale_y; + stbtt__edge * e; + int n, i, j, k, m; +#if STBTT_RASTERIZER_VERSION == 1 + int vsubsample = result->h < 8 ? 15 : 5; +#elif STBTT_RASTERIZER_VERSION == 2 + int vsubsample = 1; +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + // vsubsample should divide 255 evenly; otherwise we won't reach full opacity + + // now we have to blow out the windings into explicit edge lists + n = 0; + for(i = 0; i < windings; ++i) + n += wcount[i]; + + e = (stbtt__edge *)STBTT_malloc(sizeof(*e) * (n + 1), userdata); // add an extra one as a sentinel + if(e == 0) return; + n = 0; + + m = 0; + for(i = 0; i < windings; ++i) { + stbtt__point * p = pts + m; + m += wcount[i]; + j = wcount[i] - 1; + for(k = 0; k < wcount[i]; j = k++) { + int a = k, b = j; + // skip the edge if horizontal + if(p[j].y == p[k].y) + continue; + // add edge from j to k to the list + e[n].invert = 0; + if(invert ? p[j].y > p[k].y : p[j].y < p[k].y) { + e[n].invert = 1; + a = j, b = k; + } + e[n].x0 = p[a].x * scale_x + shift_x; + e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; + e[n].x1 = p[b].x * scale_x + shift_x; + e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; + ++n; + } + } + + // now sort the edges by their highest point (should snap to integer, and then by x) + //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); + stbtt__sort_edges(e, n); + + // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule + stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); + + STBTT_free(e, userdata); +} + +static void stbtt__add_point(stbtt__point * points, int n, float x, float y) +{ + if(!points) return; // during first pass, it's unallocated + points[n].x = x; + points[n].y = y; +} + +// tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching +static int stbtt__tesselate_curve(stbtt__point * points, int * num_points, float x0, float y0, float x1, float y1, + float x2, float y2, float objspace_flatness_squared, int n) +{ + // midpoint + float mx = (x0 + 2 * x1 + x2) / 4; + float my = (y0 + 2 * y1 + y2) / 4; + // versus directly drawn line + float dx = (x0 + x2) / 2 - mx; + float dy = (y0 + y2) / 2 - my; + if(n > 16) // 65536 segments on one curve better be enough! + return 1; + if(dx * dx + dy * dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA + stbtt__tesselate_curve(points, num_points, x0, y0, (x0 + x1) / 2.0f, (y0 + y1) / 2.0f, mx, my, + objspace_flatness_squared, n + 1); + stbtt__tesselate_curve(points, num_points, mx, my, (x1 + x2) / 2.0f, (y1 + y2) / 2.0f, x2, y2, + objspace_flatness_squared, n + 1); + } + else { + stbtt__add_point(points, *num_points, x2, y2); + *num_points = *num_points + 1; + } + return 1; +} + +static void stbtt__tesselate_cubic(stbtt__point * points, int * num_points, float x0, float y0, float x1, float y1, + float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) +{ + // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough + float dx0 = x1 - x0; + float dy0 = y1 - y0; + float dx1 = x2 - x1; + float dy1 = y2 - y1; + float dx2 = x3 - x2; + float dy2 = y3 - y2; + float dx = x3 - x0; + float dy = y3 - y0; + float longlen = (float)(STBTT_sqrt(dx0 * dx0 + dy0 * dy0) + STBTT_sqrt(dx1 * dx1 + dy1 * dy1) + STBTT_sqrt( + dx2 * dx2 + dy2 * dy2)); + float shortlen = (float)STBTT_sqrt(dx * dx + dy * dy); + float flatness_squared = longlen * longlen - shortlen * shortlen; + + if(n > 16) // 65536 segments on one curve better be enough! + return; + + if(flatness_squared > objspace_flatness_squared) { + float x01 = (x0 + x1) / 2; + float y01 = (y0 + y1) / 2; + float x12 = (x1 + x2) / 2; + float y12 = (y1 + y2) / 2; + float x23 = (x2 + x3) / 2; + float y23 = (y2 + y3) / 2; + + float xa = (x01 + x12) / 2; + float ya = (y01 + y12) / 2; + float xb = (x12 + x23) / 2; + float yb = (y12 + y23) / 2; + + float mx = (xa + xb) / 2; + float my = (ya + yb) / 2; + + stbtt__tesselate_cubic(points, num_points, x0, y0, x01, y01, xa, ya, mx, my, objspace_flatness_squared, n + 1); + stbtt__tesselate_cubic(points, num_points, mx, my, xb, yb, x23, y23, x3, y3, objspace_flatness_squared, n + 1); + } + else { + stbtt__add_point(points, *num_points, x3, y3); + *num_points = *num_points + 1; + } +} + +// returns number of contours +static stbtt__point * stbtt_FlattenCurves(stbtt_vertex * vertices, int num_verts, float objspace_flatness, + int ** contour_lengths, int * num_contours, void * userdata) +{ + stbtt__point * points = 0; + int num_points = 0; + + float objspace_flatness_squared = objspace_flatness * objspace_flatness; + int i, n = 0, start = 0, pass; + + // count how many "moves" there are to get the contour count + for(i = 0; i < num_verts; ++i) + if(vertices[i].type == STBTT_vmove) + ++n; + + *num_contours = n; + if(n == 0) return 0; + + *contour_lengths = (int *)STBTT_malloc(sizeof(**contour_lengths) * n, userdata); + + if(*contour_lengths == 0) { + *num_contours = 0; + return 0; + } + + // make two passes through the points so we don't need to realloc + for(pass = 0; pass < 2; ++pass) { + float x = 0, y = 0; + if(pass == 1) { + points = (stbtt__point *)STBTT_malloc(num_points * sizeof(points[0]), userdata); + if(points == NULL) goto error; + } + num_points = 0; + n = -1; + for(i = 0; i < num_verts; ++i) { + switch(vertices[i].type) { + case STBTT_vmove: + // start the next contour + if(n >= 0) + (*contour_lengths)[n] = num_points - start; + ++n; + start = num_points; + + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x, y); + break; + case STBTT_vline: + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x, y); + break; + case STBTT_vcurve: + stbtt__tesselate_curve(points, &num_points, x, y, + vertices[i].cx, vertices[i].cy, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + case STBTT_vcubic: + stbtt__tesselate_cubic(points, &num_points, x, y, + vertices[i].cx, vertices[i].cy, + vertices[i].cx1, vertices[i].cy1, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + } + } + (*contour_lengths)[n] = num_points - start; + } + + return points; +error: + STBTT_free(points, userdata); + STBTT_free(*contour_lengths, userdata); + *contour_lengths = 0; + *num_contours = 0; + return NULL; +} + +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap * result, float flatness_in_pixels, stbtt_vertex * vertices, int num_verts, + float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void * userdata) +{ + float scale = scale_x > scale_y ? scale_y : scale_x; + int winding_count = 0; + int * winding_lengths = NULL; + stbtt__point * windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, + &winding_count, userdata); + if(windings) { + stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, + invert, userdata); + STBTT_free(winding_lengths, userdata); + STBTT_free(windings, userdata); + } +} + +STBTT_DEF void stbtt_FreeBitmap(unsigned char * bitmap, void * userdata) +{ + STBTT_free(bitmap, userdata); +} + +STBTT_DEF unsigned char * stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo * info, float scale_x, float scale_y, + float shift_x, float shift_y, int glyph, int * width, int * height, int * xoff, int * yoff) +{ + int ix0, iy0, ix1, iy1; + stbtt__bitmap gbm; + stbtt_vertex * vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + + if(scale_x == 0) scale_x = scale_y; + if(scale_y == 0) { + if(scale_x == 0) { + STBTT_free(vertices, info->userdata); + return NULL; + } + scale_y = scale_x; + } + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, &ix1, &iy1); + + // now we get the size + gbm.w = (ix1 - ix0); + gbm.h = (iy1 - iy0); + gbm.pixels = NULL; // in case we error + + if(width) *width = gbm.w; + if(height) *height = gbm.h; + if(xoff) *xoff = ix0; + if(yoff) *yoff = iy0; + + if(gbm.w && gbm.h) { + gbm.pixels = (unsigned char *)STBTT_malloc(gbm.w * gbm.h, info->userdata); + if(gbm.pixels) { + gbm.stride = gbm.w; + + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); + } + } + STBTT_free(vertices, info->userdata); + return gbm.pixels; +} + +STBTT_DEF unsigned char * stbtt_GetGlyphBitmap(const stbtt_fontinfo * info, float scale_x, float scale_y, int glyph, + int * width, int * height, int * xoff, int * yoff) +{ + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h, + int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) +{ + int ix0, iy0; + stbtt_vertex * vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + stbtt__bitmap gbm; + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, 0, 0); + gbm.pixels = output; + gbm.w = out_w; + gbm.h = out_h; + gbm.stride = out_stride; + + if(gbm.w && gbm.h) + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); + + STBTT_free(vertices, info->userdata); +} + +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h, + int out_stride, float scale_x, float scale_y, int glyph) +{ + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, glyph); +} + +STBTT_DEF unsigned char * stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo * info, float scale_x, float scale_y, + float shift_x, float shift_y, int codepoint, int * width, int * height, int * xoff, int * yoff) +{ + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint), + width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo * info, unsigned char * output, + int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, + int oversample_y, float * sub_x, float * sub_y, int codepoint) +{ + stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, + oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info, codepoint)); +} + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo * info, unsigned char * output, int out_w, + int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) +{ + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, + stbtt_FindGlyphIndex(info, codepoint)); +} + +STBTT_DEF unsigned char * stbtt_GetCodepointBitmap(const stbtt_fontinfo * info, float scale_x, float scale_y, + int codepoint, int * width, int * height, int * xoff, int * yoff) +{ + return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, codepoint, width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h, + int out_stride, float scale_x, float scale_y, int codepoint) +{ + stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, codepoint); +} + +////////////////////////////////////////////////////////////////////////////// +// +// bitmap baking +// +// This is SUPER-CRAPPY packing to keep source code small +#ifdef STBTT_STREAM_TYPE +static int stbtt_BakeFontBitmap_internal(STBTT_STREAM_TYPE data, + int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char * pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar * chardata) +#else +static int stbtt_BakeFontBitmap_internal(unsigned char * data, + int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char * pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar * chardata) +#endif +{ + float scale; + int x, y, bottom_y, i; + stbtt_fontinfo f; + f.userdata = NULL; + if(!stbtt_InitFont(&f, data, offset)) + return -1; + STBTT_memset(pixels, 0, pw * ph); // background of 0 around pixels + x = y = 1; + bottom_y = 1; + + scale = stbtt_ScaleForPixelHeight(&f, pixel_height); + + for(i = 0; i < num_chars; ++i) { + int advance, lsb, x0, y0, x1, y1, gw, gh; + int g = stbtt_FindGlyphIndex(&f, first_char + i); + stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); + stbtt_GetGlyphBitmapBox(&f, g, scale, scale, &x0, &y0, &x1, &y1); + gw = x1 - x0; + gh = y1 - y0; + if(x + gw + 1 >= pw) + y = bottom_y, x = 1; // advance to next row + if(y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row + return -i; + STBTT_assert(x + gw < pw); + STBTT_assert(y + gh < ph); + stbtt_MakeGlyphBitmap(&f, pixels + x + y * pw, gw, gh, pw, scale, scale, g); + chardata[i].x0 = (stbtt_int16)x; + chardata[i].y0 = (stbtt_int16)y; + chardata[i].x1 = (stbtt_int16)(x + gw); + chardata[i].y1 = (stbtt_int16)(y + gh); + chardata[i].xadvance = scale * advance; + chardata[i].xoff = (float)x0; + chardata[i].yoff = (float)y0; + x = x + gw + 1; + if(y + gh + 1 > bottom_y) + bottom_y = y + gh + 1; + } + return bottom_y; +} + +STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar * chardata, int pw, int ph, int char_index, float * xpos, + float * ypos, stbtt_aligned_quad * q, int opengl_fillrule) +{ + float d3d_bias = opengl_fillrule ? 0 : -0.5f; + float ipw = 1.0f / pw, iph = 1.0f / ph; + const stbtt_bakedchar * b = chardata + char_index; + int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); + int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); + + q->x0 = round_x + d3d_bias; + q->y0 = round_y + d3d_bias; + q->x1 = round_x + b->x1 - b->x0 + d3d_bias; + q->y1 = round_y + b->y1 - b->y0 + d3d_bias; + + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; + + *xpos += b->xadvance; +} + +////////////////////////////////////////////////////////////////////////////// +// +// rectangle packing replacement routines if you don't have stb_rect_pack.h +// + +#ifndef STB_RECT_PACK_VERSION + +typedef int stbrp_coord; + +//////////////////////////////////////////////////////////////////////////////////// +// // +// // +// COMPILER WARNING ?!?!? // +// // +// // +// if you get a compile warning due to these symbols being defined more than // +// once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" // +// // +//////////////////////////////////////////////////////////////////////////////////// + +typedef struct { + int width, height; + int x, y, bottom_y; +} stbrp_context; + +typedef struct { + unsigned char x; +} stbrp_node; + +struct stbrp_rect { + stbrp_coord x, y; + int id, w, h, was_packed; +}; + +static void stbrp_init_target(stbrp_context * con, int pw, int ph, stbrp_node * nodes, int num_nodes) +{ + con->width = pw; + con->height = ph; + con->x = 0; + con->y = 0; + con->bottom_y = 0; + STBTT__NOTUSED(nodes); + STBTT__NOTUSED(num_nodes); +} + +static void stbrp_pack_rects(stbrp_context * con, stbrp_rect * rects, int num_rects) +{ + int i; + for(i = 0; i < num_rects; ++i) { + if(con->x + rects[i].w > con->width) { + con->x = 0; + con->y = con->bottom_y; + } + if(con->y + rects[i].h > con->height) + break; + rects[i].x = con->x; + rects[i].y = con->y; + rects[i].was_packed = 1; + con->x += rects[i].w; + if(con->y + rects[i].h > con->bottom_y) + con->bottom_y = con->y + rects[i].h; + } + for(; i < num_rects; ++i) + rects[i].was_packed = 0; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// bitmap baking +// +// This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If +// stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy. + +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context * spc, unsigned char * pixels, int pw, int ph, int stride_in_bytes, + int padding, void * alloc_context) +{ + stbrp_context * context = (stbrp_context *)STBTT_malloc(sizeof(*context), alloc_context); + int num_nodes = pw - padding; + stbrp_node * nodes = (stbrp_node *)STBTT_malloc(sizeof(*nodes) * num_nodes, alloc_context); + + if(context == NULL || nodes == NULL) { + if(context != NULL) STBTT_free(context, alloc_context); + if(nodes != NULL) STBTT_free(nodes, alloc_context); + return 0; + } + + spc->user_allocator_context = alloc_context; + spc->width = pw; + spc->height = ph; + spc->pixels = pixels; + spc->pack_info = context; + spc->nodes = nodes; + spc->padding = padding; + spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; + spc->h_oversample = 1; + spc->v_oversample = 1; + spc->skip_missing = 0; + + stbrp_init_target(context, pw - padding, ph - padding, nodes, num_nodes); + + if(pixels) + STBTT_memset(pixels, 0, pw * ph); // background of 0 around pixels + + return 1; +} + +STBTT_DEF void stbtt_PackEnd(stbtt_pack_context * spc) +{ + STBTT_free(spc->nodes, spc->user_allocator_context); + STBTT_free(spc->pack_info, spc->user_allocator_context); +} + +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context * spc, unsigned int h_oversample, unsigned int v_oversample) +{ + STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); + STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); + if(h_oversample <= STBTT_MAX_OVERSAMPLE) + spc->h_oversample = h_oversample; + if(v_oversample <= STBTT_MAX_OVERSAMPLE) + spc->v_oversample = v_oversample; +} + +STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context * spc, int skip) +{ + spc->skip_missing = skip; +} + +#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) + +static void stbtt__h_prefilter(unsigned char * pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +{ + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_w = w - kernel_width; + int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for(j = 0; j < h; ++j) { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); + + total = 0; + + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch(kernel_width) { + case 2: + for(i = 0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 2); + } + break; + case 3: + for(i = 0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 3); + } + break; + case 4: + for(i = 0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 4); + } + break; + case 5: + for(i = 0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 5); + } + break; + default: + for(i = 0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / kernel_width); + } + break; + } + + for(; i < w; ++i) { + STBTT_assert(pixels[i] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i] = (unsigned char)(total / kernel_width); + } + + pixels += stride_in_bytes; + } +} + +static void stbtt__v_prefilter(unsigned char * pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +{ + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_h = h - kernel_width; + int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for(j = 0; j < w; ++j) { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); + + total = 0; + + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch(kernel_width) { + case 2: + for(i = 0; i <= safe_h; ++i) { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 2); + } + break; + case 3: + for(i = 0; i <= safe_h; ++i) { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 3); + } + break; + case 4: + for(i = 0; i <= safe_h; ++i) { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 4); + } + break; + case 5: + for(i = 0; i <= safe_h; ++i) { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 5); + } + break; + default: + for(i = 0; i <= safe_h; ++i) { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width); + } + break; + } + + for(; i < h; ++i) { + STBTT_assert(pixels[i * stride_in_bytes] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width); + } + + pixels += 1; + } +} + +static float stbtt__oversample_shift(int oversample) +{ + if(!oversample) + return 0.0f; + + // The prefilter is a box filter of width "oversample", + // which shifts phase by (oversample - 1)/2 pixels in + // oversampled space. We want to shift in the opposite + // direction to counter this. + return (float) - (oversample - 1) / (2.0f * (float)oversample); +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context * spc, const stbtt_fontinfo * info, + stbtt_pack_range * ranges, int num_ranges, stbrp_rect * rects) +{ + int i, j, k; + int missing_glyph_added = 0; + + k = 0; + for(i = 0; i < num_ranges; ++i) { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + ranges[i].h_oversample = (unsigned char)spc->h_oversample; + ranges[i].v_oversample = (unsigned char)spc->v_oversample; + for(j = 0; j < ranges[i].num_chars; ++j) { + int x0, y0, x1, y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : + ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + if(glyph == 0 && (spc->skip_missing || missing_glyph_added)) { + rects[k].w = rects[k].h = 0; + } + else { + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0, 0, + &x0, &y0, &x1, &y1); + rects[k].w = (stbrp_coord)(x1 - x0 + spc->padding + spc->h_oversample - 1); + rects[k].h = (stbrp_coord)(y1 - y0 + spc->padding + spc->v_oversample - 1); + if(glyph == 0) + missing_glyph_added = 1; + } + ++k; + } + } + + return k; +} + +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo * info, unsigned char * output, int out_w, + int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int prefilter_x, int prefilter_y, + float * sub_x, float * sub_y, int glyph) +{ + stbtt_MakeGlyphBitmapSubpixel(info, + output, + out_w - (prefilter_x - 1), + out_h - (prefilter_y - 1), + out_stride, + scale_x, + scale_y, + shift_x, + shift_y, + glyph); + + if(prefilter_x > 1) + stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x); + + if(prefilter_y > 1) + stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y); + + *sub_x = stbtt__oversample_shift(prefilter_x); + *sub_y = stbtt__oversample_shift(prefilter_y); +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context * spc, const stbtt_fontinfo * info, + stbtt_pack_range * ranges, int num_ranges, stbrp_rect * rects) +{ + int i, j, k, missing_glyph = -1, return_value = 1; + + // save current values + int old_h_over = spc->h_oversample; + int old_v_over = spc->v_oversample; + + k = 0; + for(i = 0; i < num_ranges; ++i) { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + float recip_h, recip_v, sub_x, sub_y; + spc->h_oversample = ranges[i].h_oversample; + spc->v_oversample = ranges[i].v_oversample; + recip_h = 1.0f / spc->h_oversample; + recip_v = 1.0f / spc->v_oversample; + sub_x = stbtt__oversample_shift(spc->h_oversample); + sub_y = stbtt__oversample_shift(spc->v_oversample); + for(j = 0; j < ranges[i].num_chars; ++j) { + stbrp_rect * r = &rects[k]; + if(r->was_packed && r->w != 0 && r->h != 0) { + stbtt_packedchar * bc = &ranges[i].chardata_for_range[j]; + int advance, lsb, x0, y0, x1, y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : + ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + stbrp_coord pad = (stbrp_coord)spc->padding; + + // pad on left and top + r->x += pad; + r->y += pad; + r->w -= pad; + r->h -= pad; + stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); + stbtt_GetGlyphBitmapBox(info, glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + &x0, &y0, &x1, &y1); + stbtt_MakeGlyphBitmapSubpixel(info, + spc->pixels + r->x + r->y * spc->stride_in_bytes, + r->w - spc->h_oversample + 1, + r->h - spc->v_oversample + 1, + spc->stride_in_bytes, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0, 0, + glyph); + + if(spc->h_oversample > 1) + stbtt__h_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->h_oversample); + + if(spc->v_oversample > 1) + stbtt__v_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->v_oversample); + + bc->x0 = (stbtt_int16)r->x; + bc->y0 = (stbtt_int16)r->y; + bc->x1 = (stbtt_int16)(r->x + r->w); + bc->y1 = (stbtt_int16)(r->y + r->h); + bc->xadvance = scale * advance; + bc->xoff = (float)x0 * recip_h + sub_x; + bc->yoff = (float)y0 * recip_v + sub_y; + bc->xoff2 = (x0 + r->w) * recip_h + sub_x; + bc->yoff2 = (y0 + r->h) * recip_v + sub_y; + + if(glyph == 0) + missing_glyph = j; + } + else if(spc->skip_missing) { + return_value = 0; + } + else if(r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) { + ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph]; + } + else { + return_value = 0; // if any fail, report failure + } + + ++k; + } + } + + // restore original values + spc->h_oversample = old_h_over; + spc->v_oversample = old_v_over; + + return return_value; +} + +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context * spc, STBTT_STREAM_TYPE fontdata, int font_index, + stbtt_pack_range * ranges, int num_ranges); +#else +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context * spc, const unsigned char * fontdata, int font_index, + stbtt_pack_range * ranges, int num_ranges); +#endif + +STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context * spc, stbrp_rect * rects, int num_rects) +{ + stbrp_pack_rects((stbrp_context *)spc->pack_info, rects, num_rects); +} +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context * spc, STBTT_STREAM_TYPE fontdata, int font_index, + stbtt_pack_range * ranges, int num_ranges) +#else +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context * spc, const unsigned char * fontdata, int font_index, + stbtt_pack_range * ranges, int num_ranges) +#endif +{ + stbtt_fontinfo info; + int i, j, n, return_value = 1; + //stbrp_context *context = (stbrp_context *) spc->pack_info; + stbrp_rect * rects; + + // flag all characters as NOT packed + for(i = 0; i < num_ranges; ++i) + for(j = 0; j < ranges[i].num_chars; ++j) + ranges[i].chardata_for_range[j].x0 = + ranges[i].chardata_for_range[j].y0 = + ranges[i].chardata_for_range[j].x1 = + ranges[i].chardata_for_range[j].y1 = 0; + + n = 0; + for(i = 0; i < num_ranges; ++i) + n += ranges[i].num_chars; + + rects = (stbrp_rect *)STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); + if(rects == NULL) + return 0; + + info.userdata = spc->user_allocator_context; + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, font_index)); + + n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); + + stbtt_PackFontRangesPackRects(spc, rects, n); + + return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); + + STBTT_free(rects, spc->user_allocator_context); + return return_value; +} + +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context * spc, STBTT_STREAM_TYPE fontdata, int font_index, float font_size, + int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar * chardata_for_range); +#else +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context * spc, const unsigned char * fontdata, int font_index, + float font_size, + int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar * chardata_for_range); +#endif + +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context * spc, STBTT_STREAM_TYPE fontdata, int font_index, float font_size, + int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar * chardata_for_range) +#else +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context * spc, const unsigned char * fontdata, int font_index, + float font_size, + int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar * chardata_for_range) +#endif +{ + stbtt_pack_range range; + range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range; + range.array_of_unicode_codepoints = NULL; + range.num_chars = num_chars_in_range; + range.chardata_for_range = chardata_for_range; + range.font_size = font_size; + return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); +} + +#ifdef STBTT_STREAM_TYPE +STBTT_DEF void stbtt_GetScaledFontVMetrics(STBTT_STREAM_TYPE fontdata, int index, float size, float * ascent, + float * descent, float * lineGap); +#else +STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char * fontdata, int index, float size, float * ascent, + float * descent, float * lineGap); +#endif + +#ifdef STBTT_STREAM_TYPE +STBTT_DEF void stbtt_GetScaledFontVMetrics(STBTT_STREAM_TYPE fontdata, int index, float size, float * ascent, + float * descent, float * lineGap) +#else +STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char * fontdata, int index, float size, float * ascent, + float * descent, float * lineGap) +#endif +{ + int i_ascent, i_descent, i_lineGap; + float scale; + stbtt_fontinfo info; + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index)); + scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size); + stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap); + *ascent = (float)i_ascent * scale; + *descent = (float)i_descent * scale; + *lineGap = (float)i_lineGap * scale; +} + +STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar * chardata, int pw, int ph, int char_index, float * xpos, + float * ypos, stbtt_aligned_quad * q, int align_to_integer) +{ + float ipw = 1.0f / pw, iph = 1.0f / ph; + const stbtt_packedchar * b = chardata + char_index; + + if(align_to_integer) { + float x = (float)STBTT_ifloor((*xpos + b->xoff) + 0.5f); + float y = (float)STBTT_ifloor((*ypos + b->yoff) + 0.5f); + q->x0 = x; + q->y0 = y; + q->x1 = x + b->xoff2 - b->xoff; + q->y1 = y + b->yoff2 - b->yoff; + } + else { + q->x0 = *xpos + b->xoff; + q->y0 = *ypos + b->yoff; + q->x1 = *xpos + b->xoff2; + q->y1 = *ypos + b->yoff2; + } + + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; + + *xpos += b->xadvance; +} + +////////////////////////////////////////////////////////////////////////////// +// +// sdf computation +// + +#define STBTT_min(a,b) ((a) < (b) ? (a) : (b)) +#define STBTT_max(a,b) ((a) < (b) ? (b) : (a)) + +static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2], + float hits[2][2]) +{ + float q0perp = q0[1] * ray[0] - q0[0] * ray[1]; + float q1perp = q1[1] * ray[0] - q1[0] * ray[1]; + float q2perp = q2[1] * ray[0] - q2[0] * ray[1]; + float roperp = orig[1] * ray[0] - orig[0] * ray[1]; + + float a = q0perp - 2 * q1perp + q2perp; + float b = q1perp - q0perp; + float c = q0perp - roperp; + + float s0 = 0., s1 = 0.; + int num_s = 0; + + if(a != 0.0f) { + float discr = b * b - a * c; + if(discr > 0.0f) { + float rcpna = -1 / a; + float d = (float)STBTT_sqrt(discr); + s0 = (b + d) * rcpna; + s1 = (b - d) * rcpna; + if(s0 >= 0.0f && s0 <= 1.0f) + num_s = 1; + if(d > 0.0f && s1 >= 0.0f && s1 <= 1.0f) { + if(num_s == 0) s0 = s1; + ++num_s; + } + } + } + else { + // 2*b*s + c = 0 + // s = -c / (2*b) + s0 = c / (-2 * b); + if(s0 >= 0.0f && s0 <= 1.0f) + num_s = 1; + } + + if(num_s == 0) + return 0; + else { + float rcp_len2 = 1 / (ray[0] * ray[0] + ray[1] * ray[1]); + float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2; + + float q0d = q0[0] * rayn_x + q0[1] * rayn_y; + float q1d = q1[0] * rayn_x + q1[1] * rayn_y; + float q2d = q2[0] * rayn_x + q2[1] * rayn_y; + float rod = orig[0] * rayn_x + orig[1] * rayn_y; + + float q10d = q1d - q0d; + float q20d = q2d - q0d; + float q0rd = q0d - rod; + + hits[0][0] = q0rd + s0 * (2.0f - 2.0f * s0) * q10d + s0 * s0 * q20d; + hits[0][1] = a * s0 + b; + + if(num_s > 1) { + hits[1][0] = q0rd + s1 * (2.0f - 2.0f * s1) * q10d + s1 * s1 * q20d; + hits[1][1] = a * s1 + b; + return 2; + } + else { + return 1; + } + } +} + +static int equal(float * a, float * b) +{ + return (a[0] == b[0] && a[1] == b[1]); +} + +static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex * verts) +{ + int i; + float orig[2], ray[2] = { 1, 0 }; + float y_frac; + int winding = 0; + + // make sure y never passes through a vertex of the shape + y_frac = (float)STBTT_fmod(y, 1.0f); + if(y_frac < 0.01f) + y += 0.01f; + else if(y_frac > 0.99f) + y -= 0.01f; + + orig[0] = x; + orig[1] = y; + + // test a ray from (-infinity,y) to (x,y) + for(i = 0; i < nverts; ++i) { + if(verts[i].type == STBTT_vline) { + int x0 = (int)verts[i - 1].x, y0 = (int)verts[i - 1].y; + int x1 = (int)verts[i].x, y1 = (int)verts[i].y; + if(y > STBTT_min(y0, y1) && y < STBTT_max(y0, y1) && x > STBTT_min(x0, x1)) { + float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0; + if(x_inter < x) + winding += (y0 < y1) ? 1 : -1; + } + } + if(verts[i].type == STBTT_vcurve) { + int x0 = (int)verts[i - 1].x, y0 = (int)verts[i - 1].y; + int x1 = (int)verts[i].cx, y1 = (int)verts[i].cy; + int x2 = (int)verts[i].x, y2 = (int)verts[i].y; + int ax = STBTT_min(x0, STBTT_min(x1, x2)), ay = STBTT_min(y0, STBTT_min(y1, y2)); + int by = STBTT_max(y0, STBTT_max(y1, y2)); + if(y > ay && y < by && x > ax) { + float q0[2], q1[2], q2[2]; + float hits[2][2]; + q0[0] = (float)x0; + q0[1] = (float)y0; + q1[0] = (float)x1; + q1[1] = (float)y1; + q2[0] = (float)x2; + q2[1] = (float)y2; + if(equal(q0, q1) || equal(q1, q2)) { + x0 = (int)verts[i - 1].x; + y0 = (int)verts[i - 1].y; + x1 = (int)verts[i].x; + y1 = (int)verts[i].y; + if(y > STBTT_min(y0, y1) && y < STBTT_max(y0, y1) && x > STBTT_min(x0, x1)) { + float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0; + if(x_inter < x) + winding += (y0 < y1) ? 1 : -1; + } + } + else { + int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits); + if(num_hits >= 1) + if(hits[0][0] < 0) + winding += (hits[0][1] < 0 ? -1 : 1); + if(num_hits >= 2) + if(hits[1][0] < 0) + winding += (hits[1][1] < 0 ? -1 : 1); + } + } + } + } + return winding; +} + +static float stbtt__cuberoot(float x) +{ + if(x < 0) + return -(float)STBTT_pow(-x, 1.0f / 3.0f); + else + return (float)STBTT_pow(x, 1.0f / 3.0f); +} + +// x^3 + a*x^2 + b*x + c = 0 +static int stbtt__solve_cubic(float a, float b, float c, float * r) +{ + float s = -a / 3; + float p = b - a * a / 3; + float q = a * (2 * a * a - 9 * b) / 27 + c; + float p3 = p * p * p; + float d = q * q + 4 * p3 / 27; + if(d >= 0) { + float z = (float)STBTT_sqrt(d); + float u = (-q + z) / 2; + float v = (-q - z) / 2; + u = stbtt__cuberoot(u); + v = stbtt__cuberoot(v); + r[0] = s + u + v; + return 1; + } + else { + float u = (float)STBTT_sqrt(-p / 3); + float v = (float)STBTT_acos(-STBTT_sqrt(-27 / p3) * q / 2) / 3; // p3 must be negative, since d is negative + float m = (float)STBTT_cos(v); + float n = (float)STBTT_cos(v - 3.141592f / 2) * 1.732050808f; + r[0] = s + u * 2 * m; + r[1] = s - u * (m + n); + r[2] = s - u * (m - n); + + //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f); // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe? + //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f); + //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f); + return 3; + } +} + +STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo * info, float scale, int glyph, int padding, + unsigned char onedge_value, float pixel_dist_scale, int * width, int * height, int * xoff, int * yoff) +{ + float scale_x = scale, scale_y = scale; + int ix0, iy0, ix1, iy1; + int w, h; + unsigned char * data; + + if(scale == 0) return NULL; + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f, 0.0f, &ix0, &iy0, &ix1, &iy1); + + // if empty, return NULL + if(ix0 == ix1 || iy0 == iy1) + return NULL; + + ix0 -= padding; + iy0 -= padding; + ix1 += padding; + iy1 += padding; + + w = (ix1 - ix0); + h = (iy1 - iy0); + + if(width) *width = w; + if(height) *height = h; + if(xoff) *xoff = ix0; + if(yoff) *yoff = iy0; + + // invert for y-downwards bitmaps + scale_y = -scale_y; + + { + int x, y, i, j; + float * precompute; + stbtt_vertex * verts; + int num_verts = stbtt_GetGlyphShape(info, glyph, &verts); + data = (unsigned char *)STBTT_malloc(w * h, info->userdata); + precompute = (float *)STBTT_malloc(num_verts * sizeof(float), info->userdata); + + for(i = 0, j = num_verts - 1; i < num_verts; j = i++) { + if(verts[i].type == STBTT_vline) { + float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y; + float x1 = verts[j].x * scale_x, y1 = verts[j].y * scale_y; + float dist = (float)STBTT_sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)); + precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist; + } + else if(verts[i].type == STBTT_vcurve) { + float x2 = verts[j].x * scale_x, y2 = verts[j].y * scale_y; + float x1 = verts[i].cx * scale_x, y1 = verts[i].cy * scale_y; + float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y; + float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2; + float len2 = bx * bx + by * by; + if(len2 != 0.0f) + precompute[i] = 1.0f / (bx * bx + by * by); + else + precompute[i] = 0.0f; + } + else + precompute[i] = 0.0f; + } + + for(y = iy0; y < iy1; ++y) { + for(x = ix0; x < ix1; ++x) { + float val; + float min_dist = 999999.0f; + float sx = (float)x + 0.5f; + float sy = (float)y + 0.5f; + float x_gspace = (sx / scale_x); + float y_gspace = (sy / scale_y); + + int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, + verts); // @OPTIMIZE: this could just be a rasterization, but needs to be line vs. non-tesselated curves so a new path + + for(i = 0; i < num_verts; ++i) { + float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y; + + if(verts[i].type == STBTT_vline && precompute[i] != 0.0f) { + float x1 = verts[i - 1].x * scale_x, y1 = verts[i - 1].y * scale_y; + + float dist, dist2 = (x0 - sx) * (x0 - sx) + (y0 - sy) * (y0 - sy); + if(dist2 < min_dist * min_dist) + min_dist = (float)STBTT_sqrt(dist2); + + // coarse culling against bbox + //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist && + // sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist) + dist = (float)STBTT_fabs((x1 - x0) * (y0 - sy) - (y1 - y0) * (x0 - sx)) * precompute[i]; + STBTT_assert(i != 0); + if(dist < min_dist) { + // check position along line + // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0) + // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy) + float dx = x1 - x0, dy = y1 - y0; + float px = x0 - sx, py = y0 - sy; + // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy + // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve + float t = -(px * dx + py * dy) / (dx * dx + dy * dy); + if(t >= 0.0f && t <= 1.0f) + min_dist = dist; + } + } + else if(verts[i].type == STBTT_vcurve) { + float x2 = verts[i - 1].x * scale_x, y2 = verts[i - 1].y * scale_y; + float x1 = verts[i].cx * scale_x, y1 = verts[i].cy * scale_y; + float box_x0 = STBTT_min(STBTT_min(x0, x1), x2); + float box_y0 = STBTT_min(STBTT_min(y0, y1), y2); + float box_x1 = STBTT_max(STBTT_max(x0, x1), x2); + float box_y1 = STBTT_max(STBTT_max(y0, y1), y2); + // coarse culling against bbox to avoid computing cubic unnecessarily + if(sx > box_x0 - min_dist && sx < box_x1 + min_dist && sy > box_y0 - min_dist && sy < box_y1 + min_dist) { + int num = 0; + float ax = x1 - x0, ay = y1 - y0; + float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2; + float mx = x0 - sx, my = y0 - sy; + float res[3] = { 0.f, 0.f, 0.f }; + float px, py, t, it, dist2; + float a_inv = precompute[i]; + if(a_inv == 0.0f) { // if a_inv is 0, it's 2nd degree so use quadratic formula + float a = 3 * (ax * bx + ay * by); + float b = 2 * (ax * ax + ay * ay) + (mx * bx + my * by); + float c = mx * ax + my * ay; + if(a == 0.0f) { // if a is 0, it's linear + if(b != 0.0f) { + res[num++] = -c / b; + } + } + else { + float discriminant = b * b - 4 * a * c; + if(discriminant < 0) + num = 0; + else { + float root = (float)STBTT_sqrt(discriminant); + res[0] = (-b - root) / (2 * a); + res[1] = (-b + root) / (2 * a); + num = 2; // don't bother distinguishing 1-solution case, as code below will still work + } + } + } + else { + float b = 3 * (ax * bx + ay * by) * a_inv; // could precompute this as it doesn't depend on sample point + float c = (2 * (ax * ax + ay * ay) + (mx * bx + my * by)) * a_inv; + float d = (mx * ax + my * ay) * a_inv; + num = stbtt__solve_cubic(b, c, d, res); + } + dist2 = (x0 - sx) * (x0 - sx) + (y0 - sy) * (y0 - sy); + if(dist2 < min_dist * min_dist) + min_dist = (float)STBTT_sqrt(dist2); + + if(num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) { + t = res[0], it = 1.0f - t; + px = it * it * x0 + 2 * t * it * x1 + t * t * x2; + py = it * it * y0 + 2 * t * it * y1 + t * t * y2; + dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy); + if(dist2 < min_dist * min_dist) + min_dist = (float)STBTT_sqrt(dist2); + } + if(num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) { + t = res[1], it = 1.0f - t; + px = it * it * x0 + 2 * t * it * x1 + t * t * x2; + py = it * it * y0 + 2 * t * it * y1 + t * t * y2; + dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy); + if(dist2 < min_dist * min_dist) + min_dist = (float)STBTT_sqrt(dist2); + } + if(num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) { + t = res[2], it = 1.0f - t; + px = it * it * x0 + 2 * t * it * x1 + t * t * x2; + py = it * it * y0 + 2 * t * it * y1 + t * t * y2; + dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy); + if(dist2 < min_dist * min_dist) + min_dist = (float)STBTT_sqrt(dist2); + } + } + } + } + if(winding == 0) + min_dist = -min_dist; // if outside the shape, value is negative + val = onedge_value + pixel_dist_scale * min_dist; + if(val < 0) + val = 0; + else if(val > 255) + val = 255; + data[(y - iy0) * w + (x - ix0)] = (unsigned char)val; + } + } + STBTT_free(precompute, info->userdata); + STBTT_free(verts, info->userdata); + } + return data; +} + +STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo * info, float scale, int codepoint, int padding, + unsigned char onedge_value, float pixel_dist_scale, int * width, int * height, int * xoff, int * yoff) +{ + return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, + width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_FreeSDF(unsigned char * bitmap, void * userdata) +{ + STBTT_free(bitmap, userdata); +} + +////////////////////////////////////////////////////////////////////////////// +// +// font name matching -- recommended not to use this +// + +// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string +#ifdef STBTT_STREAM_TYPE +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 * s1, stbtt_int32 len1, STBTT_STREAM_TYPE s2, + stbtt_uint32 s2offs, stbtt_int32 len2) +#else +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 * s1, stbtt_int32 len1, stbtt_uint8 * s2, + stbtt_uint32 s2offs, stbtt_int32 len2) +#endif +{ + stbtt_int32 i = 0; + + // convert utf16 to utf8 and compare the results while converting + while(len2) { + stbtt_uint16 ch = ttUSHORT(s2, s2offs); + if(ch < 0x80) { + if(i >= len1) return -1; + if(s1[i++] != ch) return -1; + } + else if(ch < 0x800) { + if(i + 1 >= len1) return -1; + if(s1[i++] != 0xc0 + (ch >> 6)) return -1; + if(s1[i++] != 0x80 + (ch & 0x3f)) return -1; + } + else if(ch >= 0xd800 && ch < 0xdc00) { + stbtt_uint32 c; + stbtt_uint16 ch2 = ttUSHORT(s2, s2offs + 2); + if(i + 3 >= len1) return -1; + c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; + if(s1[i++] != 0xf0 + (c >> 18)) return -1; + if(s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; + if(s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; + if(s1[i++] != 0x80 + ((c) & 0x3f)) return -1; + s2offs += 2; // plus another 2 below + len2 -= 2; + } + else if(ch >= 0xdc00 && ch < 0xe000) { + return -1; + } + else { + if(i + 2 >= len1) return -1; + if(s1[i++] != 0xe0 + (ch >> 12)) return -1; + if(s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1; + if(s1[i++] != 0x80 + ((ch) & 0x3f)) return -1; + } + s2offs += 2; + len2 -= 2; + } + return i; +} +#ifdef STBTT_STREAM_TYPE +static int stbtt_CompareUTF8toUTF16_bigendian_internal(char * s1, int len1, STBTT_STREAM_TYPE s2, stbtt_uint32 s2offs, + int len2) +{ + return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8 *)s1, len1, s2, s2offs, len2); +} +#else +static int stbtt_CompareUTF8toUTF16_bigendian_internal(char * s1, int len1, char * s2, stbtt_uint32 s2offs, int len2) +{ + return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8 *)s1, len1, (stbtt_uint8 *)s2, s2offs, len2); +} +#endif +// returns results in whatever encoding you request... but note that 2-byte encodings +// will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare +STBTT_DEF stbtt_uint32 stbtt_GetFontNameString(const stbtt_fontinfo * font, int * length, int platformID, + int encodingID, int languageID, int nameID) +{ + stbtt_int32 i, count, stringOffset; + stbtt_uint32 offset = font->fontstart; + stbtt_uint32 nm = stbtt__find_table(font->data, offset, "name"); + if(!nm) return 0; + + count = ttUSHORT(font->data, nm + 2); + stringOffset = nm + ttUSHORT(font->data, nm + 4); + for(i = 0; i < count; ++i) { + stbtt_uint32 loc = nm + 6 + 12 * i; + if(platformID == ttUSHORT(font->data, loc + 0) && encodingID == ttUSHORT(font->data, loc + 2) + && languageID == ttUSHORT(font->data, loc + 4) && nameID == ttUSHORT(font->data, loc + 6)) { + *length = ttUSHORT(font->data, loc + 8); + return stringOffset + ttUSHORT(font->data, loc + 10); + } + } + return 0; +} +#ifdef STBTT_STREAM_TYPE +static int stbtt__matchpair(STBTT_STREAM_TYPE fc, stbtt_uint32 nm, stbtt_uint8 * name, stbtt_int32 nlen, + stbtt_int32 target_id, stbtt_int32 next_id) +#else +static int stbtt__matchpair(stbtt_uint8 * fc, stbtt_uint32 nm, stbtt_uint8 * name, stbtt_int32 nlen, + stbtt_int32 target_id, stbtt_int32 next_id) +#endif +{ + stbtt_int32 i; + stbtt_int32 count = ttUSHORT(fc, nm + 2); + stbtt_int32 stringOffset = nm + ttUSHORT(fc, nm + 4); + + for(i = 0; i < count; ++i) { + stbtt_uint32 loc = nm + 6 + 12 * i; + stbtt_int32 id = ttUSHORT(fc, loc + 6); + if(id == target_id) { + // find the encoding + stbtt_int32 platform = ttUSHORT(fc, loc + 0), encoding = ttUSHORT(fc, loc + 2), language = ttUSHORT(fc, loc + 4); + + // is this a Unicode encoding? + if(platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { + stbtt_int32 slen = ttUSHORT(fc, loc + 8); + stbtt_int32 off = ttUSHORT(fc, loc + 10); + + // check if there's a prefix match + stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc, stringOffset + off, slen); + if(matchlen >= 0) { + // check for target_id+1 immediately following, with same encoding & language + if(i + 1 < count && ttUSHORT(fc, loc + 12 + 6) == next_id && ttUSHORT(fc, loc + 12) == platform && + ttUSHORT(fc, loc + 12 + 2) == encoding && ttUSHORT(fc, loc + 12 + 4) == language) { + slen = ttUSHORT(fc, loc + 12 + 8); + off = ttUSHORT(fc, loc + 12 + 10); + if(slen == 0) { + if(matchlen == nlen) + return 1; + } + else if(matchlen < nlen && name[matchlen] == ' ') { + ++matchlen; +#ifdef STBTT_STREAM_TYPE + if(stbtt_CompareUTF8toUTF16_bigendian_internal((char *)(name + matchlen), nlen - matchlen, fc, stringOffset + off, + slen)) +#else + if(stbtt_CompareUTF8toUTF16_bigendian_internal((char *)(name + matchlen), nlen - matchlen, (char *)fc, + stringOffset + off, slen)) +#endif + return 1; + } + } + else { + // if nothing immediately following + if(matchlen == nlen) + return 1; + } + } + } + + // @TODO handle other encodings + } + } + return 0; +} +#ifdef STBTT_STREAM_TYPE + static int stbtt__matches(STBTT_STREAM_TYPE fc, stbtt_uint32 offset, stbtt_uint8 * name, stbtt_int32 flags) +#else + static int stbtt__matches(stbtt_uint8 * fc, stbtt_uint32 offset, stbtt_uint8 * name, stbtt_int32 flags) +#endif + +{ + stbtt_int32 nlen = (stbtt_int32)STBTT_strlen((char *)name); + stbtt_uint32 nm, hd; + if(!stbtt__isfont(fc, offset)) return 0; + + // check italics/bold/underline flags in macStyle... + if(flags) { + hd = stbtt__find_table(fc, offset, "head"); + if((ttUSHORT(fc, hd + 44) & 7) != (flags & 7)) return 0; + } + + nm = stbtt__find_table(fc, offset, "name"); + if(!nm) return 0; + + if(flags) { + if(name == NULL) return 1; + // if we checked the macStyle flags, then just check the family and ignore the subfamily + if(stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; + if(stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; + if(stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } + else { + if(name == NULL) return 1; + if(stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; + if(stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; + if(stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } + + return 0; +} +#ifdef STBTT_STREAM_TYPE + static int stbtt_FindMatchingFont_internal(STBTT_STREAM_TYPE font_collection, char * name_utf8, stbtt_int32 flags) +#else + static int stbtt_FindMatchingFont_internal(unsigned char * font_collection, char * name_utf8, stbtt_int32 flags) +#endif +{ + stbtt_int32 i; + for(i = 0;; ++i) { + stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); + if(off < 0) return off; +#ifdef STBTT_STREAM_TYPE + if(stbtt__matches(font_collection, off, (stbtt_uint8 *)name_utf8, flags)) +#else + if(stbtt__matches((stbtt_uint8 *)font_collection, off, (stbtt_uint8 *)name_utf8, flags)) +#endif + return off; + } +} + +#if defined(__GNUC__) || defined(__clang__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-qual" +#endif + +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_BakeFontBitmap(STBTT_STREAM_TYPE data, int offset, + float pixel_height, unsigned char * pixels, int pw, int ph, + int first_char, int num_chars, stbtt_bakedchar * chardata); +#else +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char * data, int offset, + float pixel_height, unsigned char * pixels, int pw, int ph, + int first_char, int num_chars, stbtt_bakedchar * chardata); +#endif + +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_BakeFontBitmap(STBTT_STREAM_TYPE data, int offset, + float pixel_height, unsigned char * pixels, int pw, int ph, + int first_char, int num_chars, stbtt_bakedchar * chardata) +#else +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char * data, int offset, + float pixel_height, unsigned char * pixels, int pw, int ph, + int first_char, int num_chars, stbtt_bakedchar * chardata) +#endif +{ +#ifdef STBTT_STREAM_TYPE + return stbtt_BakeFontBitmap_internal(data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata); +#else + return stbtt_BakeFontBitmap_internal((unsigned char *)data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, + chardata); +#endif +} +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_GetFontOffsetForIndex(STBTT_STREAM_TYPE data, int index) +{ + return stbtt_GetFontOffsetForIndex_internal(data, index); +} +#else +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char * data, int index) +{ + return stbtt_GetFontOffsetForIndex_internal((unsigned char *)data, index); +} +#endif +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_GetNumberOfFonts(STBTT_STREAM_TYPE data) +{ + return stbtt_GetNumberOfFonts_internal(data); +} +#else +STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char * data) +{ + return stbtt_GetNumberOfFonts_internal((unsigned char *)data); +} +#endif +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo * info, STBTT_STREAM_TYPE data, int offset) +{ + return stbtt_InitFont_internal(info, data, offset); +} +#else +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo * info, const unsigned char * data, int offset) +{ + return stbtt_InitFont_internal(info, (unsigned char *)data, offset); +} +#endif +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_FindMatchingFont(STBTT_STREAM_TYPE fontdata, const char * name, int flags) +{ + return stbtt_FindMatchingFont_internal(fontdata, (char *)name, flags); +} +#else +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char * fontdata, const char * name, int flags) +{ + return stbtt_FindMatchingFont_internal((unsigned char *)fontdata, (char *)name, flags); +} +#endif +#ifdef STBTT_STREAM_TYPE +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char * s1, int len1, STBTT_STREAM_TYPE s2, stbtt_uint32 s2offs, + int len2) +{ + return stbtt_CompareUTF8toUTF16_bigendian_internal((char *)s1, len1, s2, s2offs, len2); +} +#else +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char * s1, int len1, const char * s2, stbtt_uint32 s2offs, + int len2) +{ + return stbtt_CompareUTF8toUTF16_bigendian_internal((char *)s1, len1, (char *)s2, s2offs, len2); +} +#endif + +#if defined(__GNUC__) || defined(__clang__) + #pragma GCC diagnostic pop + #pragma GCC diagnostic pop +#endif + +#endif // STB_TRUETYPE_IMPLEMENTATION + +// FULL VERSION HISTORY +// +// 1.25 (2021-07-11) many fixes +// 1.24 (2020-02-05) fix warning +// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS) +// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined +// 1.21 (2019-02-25) fix warning +// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics() +// 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod +// 1.18 (2018-01-29) add missing function +// 1.17 (2017-07-23) make more arguments const; doc fix +// 1.16 (2017-07-12) SDF support +// 1.15 (2017-03-03) make more arguments const +// 1.14 (2017-01-16) num-fonts-in-TTC function +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts +// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual +// 1.11 (2016-04-02) fix unused-variable warning +// 1.10 (2016-04-02) allow user-defined fabs() replacement +// fix memory leak if fontsize=0.0 +// fix warning from duplicate typedef +// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges +// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges +// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; +// allow PackFontRanges to pack and render in separate phases; +// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); +// fixed an assert() bug in the new rasterizer +// replace assert() with STBTT_assert() in new rasterizer +// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) +// also more precise AA rasterizer, except if shapes overlap +// remove need for STBTT_sort +// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC +// 1.04 (2015-04-15) typo in example +// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes +// 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++ +// 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match +// non-oversampled; STBTT_POINT_SIZE for packed case only +// 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling +// 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg) +// 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID +// 0.8b (2014-07-07) fix a warning +// 0.8 (2014-05-25) fix a few more warnings +// 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back +// 0.6c (2012-07-24) improve documentation +// 0.6b (2012-07-20) fix a few more warnings +// 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels, +// stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty +// 0.5 (2011-12-09) bugfixes: +// subpixel glyph renderer computed wrong bounding box +// first vertex of shape can be off-curve (FreeSans) +// 0.4b (2011-12-03) fixed an error in the font baking example +// 0.4 (2011-12-01) kerning, subpixel rendering (tor) +// bugfixes for: +// codepoint-to-glyph conversion using table fmt=12 +// codepoint-to-glyph conversion using table fmt=4 +// stbtt_GetBakedQuad with non-square texture (Zer) +// updated Hello World! sample to use kerning and subpixel +// fixed some warnings +// 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM) +// userdata, malloc-from-userdata, non-zero fill (stb) +// 0.2 (2009-03-11) Fix unsigned/signed char warnings +// 0.1 (2009-03-09) First public release +// + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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. +------------------------------------------------------------------------------ +*/ diff --git a/test/include/liblvgl/libs/tjpgd/lv_tjpgd.h b/test/include/liblvgl/libs/tjpgd/lv_tjpgd.h new file mode 100644 index 00000000..ec35800b --- /dev/null +++ b/test/include/liblvgl/libs/tjpgd/lv_tjpgd.h @@ -0,0 +1,45 @@ +/** + * @file lv_tjpgd.h + * + */ + +#ifndef LV_TJPGD_H +#define LV_TJPGD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#if LV_USE_TJPGD + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_tjpgd_init(void); + +void lv_tjpgd_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TJPGD*/ + +#ifdef __cplusplus +} +#endif + +#endif /* LV_TJPGD_H */ diff --git a/test/include/liblvgl/libs/tjpgd/tjpgd.h b/test/include/liblvgl/libs/tjpgd/tjpgd.h new file mode 100644 index 00000000..887038a2 --- /dev/null +++ b/test/include/liblvgl/libs/tjpgd/tjpgd.h @@ -0,0 +1,108 @@ +/*----------------------------------------------------------------------------/ +/ TJpgDec - Tiny JPEG Decompressor R0.03 include file (C)ChaN, 2021 +/----------------------------------------------------------------------------*/ +#ifndef DEF_TJPGDEC +#define DEF_TJPGDEC + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../lv_conf_internal.h" +#include "tjpgdcnf.h" + +#if LV_USE_TJPGD + +#include +#include + +#if JD_FASTDECODE >= 1 +typedef int16_t jd_yuv_t; +#else +typedef uint8_t jd_yuv_t; +#endif + + +/* Error code */ +typedef enum { + JDR_OK = 0, /* 0: Succeeded */ + JDR_INTR, /* 1: Interrupted by output function */ + JDR_INP, /* 2: Device error or wrong termination of input stream */ + JDR_MEM1, /* 3: Insufficient memory pool for the image */ + JDR_MEM2, /* 4: Insufficient stream input buffer */ + JDR_PAR, /* 5: Parameter error */ + JDR_FMT1, /* 6: Data format error (may be broken data) */ + JDR_FMT2, /* 7: Right format but not supported */ + JDR_FMT3 /* 8: Not supported JPEG standard */ +} JRESULT; + + + +/* Rectangular region in the output image */ +typedef struct { + uint16_t left; /* Left end */ + uint16_t right; /* Right end */ + uint16_t top; /* Top end */ + uint16_t bottom; /* Bottom end */ +} JRECT; + + + +/* Decompressor object structure */ +typedef struct JDEC JDEC; +struct JDEC { + size_t dctr; /* Number of bytes available in the input buffer */ + uint8_t * dptr; /* Current data read ptr */ + uint8_t * inbuf; /* Bit stream input buffer */ + uint8_t dbit; /* Number of bits available in wreg or reading bit mask */ + uint8_t scale; /* Output scaling ratio */ + uint8_t msx, msy; /* MCU size in unit of block (width, height) */ + uint8_t qtid[3]; /* Quantization table ID of each component, Y, Cb, Cr */ + uint8_t ncomp; /* Number of color components 1:grayscale, 3:color */ + int16_t dcv[3]; /* Previous DC element of each component */ + uint16_t nrst; /* Restart interval */ + uint16_t rst; /* Restart count*/ + uint16_t rsc; /* Expected restart sequence ID*/ + uint16_t width, height; /* Size of the input image (pixel) */ + uint8_t * huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ + uint16_t * huffcode[2][2]; /* Huffman code word tables [id][dcac] */ + uint8_t * huffdata[2][2]; /* Huffman decoded data tables [id][dcac] */ + int32_t * qttbl[4]; /* Dequantizer tables [id] */ +#if JD_FASTDECODE >= 1 + uint32_t wreg; /* Working shift register */ + uint8_t marker; /* Detected marker (0:None) */ +#if JD_FASTDECODE == 2 + uint8_t longofs[2][2]; /* Table offset of long code [id][dcac] */ + uint16_t * hufflut_ac[2]; /* Fast huffman decode tables for AC short code [id] */ + uint8_t * hufflut_dc[2]; /* Fast huffman decode tables for DC short code [id] */ +#endif +#endif + void * workbuf; /* Working buffer for IDCT and RGB output */ + jd_yuv_t * mcubuf; /* Working buffer for the MCU */ + void * pool; /* Pointer to available memory pool */ + void * pool_original; /* Pointer to original pool */ + size_t sz_pool; /* Size of memory pool (bytes available) */ + size_t (*infunc)(JDEC *, uint8_t *, size_t); /* Pointer to jpeg stream input function */ + void * device; /* Pointer to I/O device identifier for the session */ +}; + + + +/* TJpgDec API functions */ +JRESULT jd_prepare(JDEC * jd, size_t (*infunc)(JDEC *, uint8_t *, size_t), void * pool, size_t sz_pool, void * dev); + +JRESULT jd_decomp(JDEC * jd, int (*outfunc)(JDEC *, void *, JRECT *), uint8_t scale); + +JRESULT jd_mcu_load(JDEC * jd); + +JRESULT jd_mcu_output(JDEC * jd, int (*outfunc)(JDEC *, void *, JRECT *), unsigned int x, unsigned int y); + +JRESULT jd_restart(JDEC * jd, uint16_t rstn); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _TJPGDEC */ diff --git a/test/include/liblvgl/libs/tjpgd/tjpgdcnf.h b/test/include/liblvgl/libs/tjpgd/tjpgdcnf.h new file mode 100644 index 00000000..dc27d6a9 --- /dev/null +++ b/test/include/liblvgl/libs/tjpgd/tjpgdcnf.h @@ -0,0 +1,33 @@ +/*----------------------------------------------*/ +/* TJpgDec System Configurations R0.03 */ +/*----------------------------------------------*/ + +#define JD_SZBUF 512 +/* Specifies size of stream input buffer */ + +#define JD_FORMAT 0 +/* Specifies output pixel format. +/ 0: RGB888 (24-bit/pix) +/ 1: RGB565 (16-bit/pix) +/ 2: Grayscale (8-bit/pix) +*/ + +#define JD_USE_SCALE 0 +/* Switches output descaling feature. +/ 0: Disable +/ 1: Enable +*/ + +#define JD_TBLCLIP 1 +/* Use table conversion for saturation arithmetic. A bit faster, but increases 1 KB of code size. +/ 0: Disable +/ 1: Enable +*/ + +#define JD_FASTDECODE 1 +/* Optimization level +/ 0: Basic optimization. Suitable for 8/16-bit MCUs. +/ 1: + 32-bit barrel shifter. Suitable for 32-bit MCUs. +/ 2: + Table conversion for huffman decoding (wants 6 << HUFF_BIT bytes of RAM) +*/ + diff --git a/test/include/liblvgl/llemu.h b/test/include/liblvgl/llemu.h new file mode 100644 index 00000000..ce9b00b2 --- /dev/null +++ b/test/include/liblvgl/llemu.h @@ -0,0 +1,438 @@ +/** + * \file liblvgl/llemu.h + * \ingroup c-llemu + * + * Legacy LCD Emulator + * + * \details This file defines a high-level API for emulating the three-button, UART-based + * VEX LCD, containing a set of functions that facilitate the use of a software- + * emulated version of the classic VEX LCD module. + * + * Visit https://pros.cs.purdue.edu/v5/tutorials/topical/adi.html to learn more. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-llemu LLEMU C API + * @{ + * LLEMU - Legacy Lcd EMUlator + * + * \image html llemu/llemu-3.8.png + * + * LLEMU provides a virtual 40x8 LCD screen with 3 buttons. The user can set the + * text of the screen and set create functions that are run when the buttons are + * pressed. + * + * LLEMU is a emulation of the UART-based LCD screens that were available with + * VEX's cortex product line. + * @} + */ + +#ifndef _LIBLVGL_LLEMU_H_ +#define _LIBLVGL_LLEMU_H_ + +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wignored-qualifiers" +#include "liblvgl/lvgl.h" +#pragma GCC diagnostic pop + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +typedef void (*lcd_btn_cb_fn_t)(void); + +#define LCD_BTN_LEFT 4 +#define LCD_BTN_CENTER 2 +#define LCD_BTN_RIGHT 1 + +typedef struct lcd_s { + lv_obj_t* frame; + lv_obj_t* screen; + lv_obj_t* lcd_text[8]; + lv_obj_t* btn_container; + lv_obj_t* btns[3]; // < 0 => left; 1 => center; 2 => right + lcd_btn_cb_fn_t callbacks[3]; // < 0 => left; 1 => center; 2 => right + volatile uint8_t touch_bits; // < 4 => left; 2 => center; 1 => right (no + // multitouch support) +} lcd_s_t; + +/** + * \ingroup c-llemu + */ + +/** + * \addtogroup c-llemu + * @{ + */ + +/** + * \enum lcd_text_align_e + * + * @brief Represents how to align the text in the LCD + */ +typedef enum lcd_text_align_e { + /// Align the text to the left side of LCD line + LCD_TEXT_ALIGN_LEFT = 0, + /// Align the text to the center of the LCD line + LCD_TEXT_ALIGN_CENTER = 1, + /// Align the text to the right side of the LCD line + LCD_TEXT_ALIGN_RIGHT = 2 +} text_align_e_t; + +/// @} + +#ifdef __cplusplus + +/** + * \ingroup c-llemu + */ +namespace c { +#endif + +/** + * \ingroup c-llemu + */ + +/** + * \addtogroup c-llemu + * @{ + */ + +/** + * Checks whether the emulated three-button LCD has already been initialized. + * + * \return True if the LCD has been initialized or false if not. + * + * \b Example + * \code + * if (pros::c::lcd_is_initialized()) { + * pros::c::lcd_print("LLEMU!"); + * } + * else { + * printf("Error: LLEMU is not initialized\n"); + * } + * \endcode + */ +bool lcd_is_initialized(void); + +/** + * Creates an emulation of the three-button, UART-based VEX LCD on the display. + * + * \return True if the LCD was successfully initialized, or false if it has + * already been initialized. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * if (pros::c::lcd_initialize()) { + * pros::c::lcd_print("LLEMU!"); + * } + * else { + * printf("Error: LLEMU could not initailize\n"); + * } + * } + * \endcode + */ +bool lcd_initialize(void); + +/** + * Turns off the Legacy LCD Emulator. + * + * Calling this function will clear the entire display, and you will not be able + * to call any further LLEMU functions until another call to lcd_initialize. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void disabled() { + * pros::c::lcd_shutdown(); + * } + * \endcode + */ +bool lcd_shutdown(void); + +/** + * Displays a formatted string on the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line on which to display the text [0-7] + * \param fmt + * Format string + * \param ... + * Optional list of arguments for the format string + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_print(0, "My formatted text: %d!", 2); + * } + * \endcode + */ +bool lcd_print(int16_t line, const char* fmt, ...); + +/** + * Displays a string on the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line on which to display the text [0-7] + * \param text + * The text to display + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_set_text(0, "My custom LLEMU text!"); + * } + * \endcode + */ +bool lcd_set_text(int16_t line, const char* text); + +/** + * Clears the contents of the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_clear(); // Clear the LCD screen + * } + * \endcode + */ +bool lcd_clear(void); + +/** + * Clears the contents of a line of the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line to clear + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_clear_line(0); // Clear line 0 + * } + * \endcode + */ +bool lcd_clear_line(int16_t line); + +/** + * Registers a callback function for the leftmost button. + * + * When the leftmost button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t (void (*cb)(void)) + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void left_callback() { + * static int i = 0; + * + * i++; + * pros::c::lcd_print(0, "Left button pressed %i times", i); + * } + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_register_btn0_cb(); + * } + * \endcode + */ +bool lcd_register_btn0_cb(lcd_btn_cb_fn_t cb); + +/** + * Registers a callback function for the center button. + * + * When the center button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t (void (*cb)(void)) + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void center_callback() { + * static int i = 0; + * + * i++; + * pros::c::lcd_print(0, "Center button pressed %i times", i); + * } + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_register_btn1_cb(); + * } + * \endcode + */ +bool lcd_register_btn1_cb(lcd_btn_cb_fn_t cb); + +/** + * Registers a callback function for the rightmost button. + * + * When the rightmost button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t (void (*cb)(void)) + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void right_callback() { + * static int i = 0; + * + * i++; + * pros::c::lcd_print(0, "Right button pressed %i times", i); + * } + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_register_btn2_cb(); + * } + * \endcode + */ +bool lcd_register_btn2_cb(lcd_btn_cb_fn_t cb); + +/** + * Gets the button status from the emulated three-button LCD. + * + * The value returned is a 3-bit integer where 1 0 0 indicates the left button + * is pressed, 0 1 0 indicates the center button is pressed, and 0 0 1 + * indicates the right button is pressed. 0 is returned if no buttons are + * currently being pressed. + * + * Note that this function is provided for legacy API compatibility purposes, + * with the caveat that the V5 touch screen does not actually support pressing + * multiple points on the screen at the same time. + * + * \return The buttons pressed as a bit mask + */ +uint8_t lcd_read_buttons(void); + +/** + * Changes the alignment of text on the LCD background + * + * \param alignment + * An enum specifying the alignment. Available alignments are: + * TEXT_ALIGN_LEFT + * TEXT_ALIGN_RIGHT + * TEXT_ALIGN_CENTER + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_set_alignment(pros::c::lcd_Text_Align::LEFT); + * pros::c::lcd_print(0, "Left Aligned Text"); + * pros::c::lcd_set_alignment(pros::c::lcd_Text_Align::CENTER); + * pros::c::lcd_print(1, "Center Aligned Text"); + * pros::c::lcd_set_alignment(pros::c::lcd_Text_Align::RIGHT); + * pros::c::lcd_print(2, "Right Aligned Text"); + * } + * \endcode + */ +void lcd_set_text_align(text_align_e_t alignment); + + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} // extern "C" +#endif +#endif // _LIBLVGL_LLEMU_H_ \ No newline at end of file diff --git a/test/include/liblvgl/llemu.hpp b/test/include/liblvgl/llemu.hpp new file mode 100644 index 00000000..6e6d733d --- /dev/null +++ b/test/include/liblvgl/llemu.hpp @@ -0,0 +1,373 @@ +/** + * \file liblvgl/llemu.hpp + * + * \ingroup cpp-llemu + * + * Legacy LCD Emulator + * + * \details This file defines a high-level API for emulating the three-button, UART-based + * VEX LCD, containing a set of functions that facilitate the use of a software- + * emulated version of the classic VEX LCD module. + * + * Visit https://pros.cs.purdue.edu/v5/tutorials/topical/adi.html to learn more. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-llemu LLEMU C++ API + * @{ + * LLEMU - Legacy Lcd EMUlator + * + * \image html llemu/llemu-3.8.png + * + * LLEMU provides a virtual 40x8 LCD screen with 3 buttons. The user can set the + * text of the screen and set create functions that are run when the buttons are + * pressed. + * + * LLEMU is a emulation of the UART-based LCD screens that were available with + * VEX's cortex product line. + * @} + */ + +#ifndef _LIBLVGL_LLEMU_HPP_ +#define _LIBLVGL_LLEMU_HPP_ + +#include +#include + +#include "liblvgl/llemu.h" + +namespace pros { + +/** + * \ingroup cpp-llemu + */ +namespace lcd { + +/** + * \ingroup cpp-llemu + */ + +/** + * \addtogroup cpp-llemu + * @{ + */ + +/** + * \enum Text_Align + * + * @brief Represents how to align the text in the LCD + */ +enum class Text_Align { + /// Align the text to the left side of LCD line + LEFT = 0, + /// Align the text to the center of the LCD line + CENTER = 1, + /// Align the text to the right side of the LCD line + RIGHT = 2 +}; + +/** + * Checks whether the emulated three-button LCD has already been initialized. + * + * \return True if the LCD has been initialized or false if not. + * + * \b Example + * \code + * if (pros::lcd::is_initialized()) { + * pros::lcd::print("LLEMU!"); + * } + * else { + * printf("Error: LLEMU is not initialized\n"); + * } + * \endcode + */ +bool is_initialized(void); + +/** + * Creates an emulation of the three-button, UART-based VEX LCD on the display. + * + * \return True if the LCD was successfully initialized, or false if it has + * already been initialized. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * if (pros::lcd::initialize()) { + * pros::lcd::print("LLEMU!"); + * } + * else { + * printf("Error: LLEMU could not initailize\n"); + * } + * } + * \endcode + */ +bool initialize(void); + +/** + * Turns off the Legacy LCD Emulator. + * + * Calling this function will clear the entire display, and you will not be able + * to call any further LLEMU functions until another call to lcd_initialize. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void disabled() { + * pros::lcd::shutdown(); + * } + * \endcode + */ +bool shutdown(void); + +/** + * Displays a string on the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line on which to display the text [0-7] + * \param text + * The text to display + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::set_text(0, "My custom LLEMU text!"); + * } + * \endcode + */ +bool set_text(std::int16_t line, std::string text); + +/** + * Clears the contents of the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::clear(); // Clear the LCD screen + * } + * \endcode + */ +bool clear(void); + +/** + * Clears the contents of a line of the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line to clear + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::clear_line(0); // Clear line 0 + * } + * \endcode + */ +bool clear_line(std::int16_t line); + +using lcd_btn_cb_fn_t = void (*)(void); + +/** + * Registers a callback function for the leftmost button. + * + * When the leftmost button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t(void (*cb)(void)) + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void left_callback() { + * static int i = 0; + * + * pros::lcd::print(0, "Left button pressed %i times", i); + * i++ + * } + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::register_btn0_cb(); + * } + * \endcode + */ +void register_btn0_cb(lcd_btn_cb_fn_t cb); + +/** + * Registers a callback function for the center button. + * + * When the center button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t(void (*cb)(void)) + * + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void center_callback() { + * static int i = 0; + * + * pros::lcd::print(0, "Center button pressed %i times", i); + * i++ + * } + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::register_btn1_cb(); + * } + * \endcode + */ +void register_btn1_cb(lcd_btn_cb_fn_t cb); + +/** + * Registers a callback function for the rightmost button. + * + * When the rightmost button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t(void (*cb)(void)) + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void right_callback() { + * static int i = 0; + * + * pros::lcd::print(0, "Right button pressed %i times", i); + * i++ + * } + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::register_btn2_cb(); + * } + * \endcode + */ +void register_btn2_cb(lcd_btn_cb_fn_t cb); + +/** + * Sets the alignment to use for subsequent calls that print text to a line. + * + * \param alignment + * An enum specifying the alignment. Available alignments are: + * TEXT_ALIGN_LEFT + * TEXT_ALIGN_RIGHT + * TEXT_ALIGN_CENTER + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::set_alignment(pros::lcd::Text_Align::LEFT); + * pros::lcd::print(0, "Left Aligned Text"); + * pros::lcd::set_alignment(pros::lcd::Text_Align::CENTER); + * pros::lcd::print(1, "Center Aligned Text"); + * pros::lcd::set_alignment(pros::lcd::Text_Align::RIGHT); + * pros::lcd::print(2, "Right Aligned Text"); + * } + * \endcode + */ +void set_text_align(Text_Align alignment); + +/** + * Gets the button status from the emulated three-button LCD. + * + * The value returned is a 3-bit integer where 1 0 0 indicates the left button + * is pressed, 0 1 0 indicates the center button is pressed, and 0 0 1 + * indicates the right button is pressed. 0 is returned if no buttons are + * currently being pressed. + * + * Note that this function is provided for legacy API compatibility purposes, + * with the caveat that the V5 touch screen does not actually support pressing + * multiple points on the screen at the same time. + * + * \return The buttons pressed as a bit mask + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * } + * + * void opcontrol() { + * while(true) { + * std::uint8_t state = pros::lcd::read_buttons(); + * pros::lcd::print(0, "%d %d %d", + * (state & LCD_BTN_LEFT) >> 2 + * (state & LCD_BTN_CENTER) >> 1, + * (state & LCD_BTN_RIGHT) >> 0 + * ); + * + * pros::delay(10); + * } + * } + * \endcode + */ +std::uint8_t read_buttons(void); + +///@} + +} // namespace lcd +} // namespace pros + + +#endif // _LIBLVGL_LLEMU_HPP_ \ No newline at end of file diff --git a/test/include/liblvgl/lv_api_map_v8.h b/test/include/liblvgl/lv_api_map_v8.h new file mode 100644 index 00000000..822450f5 --- /dev/null +++ b/test/include/liblvgl/lv_api_map_v8.h @@ -0,0 +1,328 @@ +/** + * @file lv_api_map_v8.h + * + */ + +#ifndef LV_API_MAP_V8_H +#define LV_API_MAP_V8_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +#define LV_DISP_ROTATION_0 LV_DISPLAY_ROTATION_0 +#define LV_DISP_ROTATION_90 LV_DISPLAY_ROTATION_90 +#define LV_DISP_ROTATION_180 LV_DISPLAY_ROTATION_180 +#define LV_DISP_ROTATION_270 LV_DISPLAY_ROTATION_270 + +#define LV_DISP_RENDER_MODE_PARTIAL LV_DISPLAY_RENDER_MODE_PARTIAL +#define LV_DISP_RENDER_MODE_DIRECT LV_DISPLAY_RENDER_MODE_DIRECT +#define LV_DISP_RENDER_MODE_FULL LV_DISPLAY_RENDER_MODE_FULL + +#if LV_USE_BUTTONMATRIX +#define LV_BTNMATRIX_BTN_NONE LV_BUTTONMATRIX_BUTTON_NONE + +#define LV_BTNMATRIX_CTRL_HIDDEN LV_BUTTONMATRIX_CTRL_HIDDEN +#define LV_BTNMATRIX_CTRL_NO_REPEAT LV_BUTTONMATRIX_CTRL_NO_REPEAT +#define LV_BTNMATRIX_CTRL_DISABLED LV_BUTTONMATRIX_CTRL_DISABLED +#define LV_BTNMATRIX_CTRL_CHECKABLE LV_BUTTONMATRIX_CTRL_CHECKABLE +#define LV_BTNMATRIX_CTRL_CHECKED LV_BUTTONMATRIX_CTRL_CHECKED +#define LV_BTNMATRIX_CTRL_CLICK_TRIG LV_BUTTONMATRIX_CTRL_CLICK_TRIG +#define LV_BTNMATRIX_CTRL_POPOVER LV_BUTTONMATRIX_CTRL_POPOVER +#define LV_BTNMATRIX_CTRL_CUSTOM_1 LV_BUTTONMATRIX_CTRL_CUSTOM_1 +#define LV_BTNMATRIX_CTRL_CUSTOM_2 LV_BUTTONMATRIX_CTRL_CUSTOM_2 +#endif /* LV_USE_BUTTONMATRIX */ + +/********************** + * TYPEDEFS + **********************/ +typedef int32_t lv_coord_t; +typedef lv_result_t lv_res_t; +typedef lv_image_dsc_t lv_img_dsc_t; +typedef lv_display_t lv_disp_t; +typedef lv_display_rotation_t lv_disp_rotation_t; +typedef lv_display_render_mode_t lv_disp_render_t; +typedef lv_anim_completed_cb_t lv_anim_ready_cb_t; +typedef lv_screen_load_anim_t lv_scr_load_anim_t; + +#if LV_USE_BUTTONMATRIX +typedef lv_buttonmatrix_ctrl_t lv_btnmatrix_ctrl_t; +#endif /* LV_USE_BUTTONMATRIX */ + +#if LV_USE_IMAGEBUTTON +#define LV_IMGBTN_STATE_RELEASED LV_IMAGEBUTTON_STATE_RELEASED +#define LV_IMGBTN_STATE_PRESSED LV_IMAGEBUTTON_STATE_PRESSED +#define LV_IMGBTN_STATE_DISABLED LV_IMAGEBUTTON_STATE_DISABLED +#define LV_IMGBTN_STATE_CHECKED_RELEASED LV_IMAGEBUTTON_STATE_CHECKED_RELEASED +#define LV_IMGBTN_STATE_CHECKED_PRESSED LV_IMAGEBUTTON_STATE_CHECKED_PRESSED +#define LV_IMGBTN_STATE_CHECKED_DISABLED LV_IMAGEBUTTON_STATE_CHECKED_DISABLED +#endif /* LV_USE_IMAGEBUTTON */ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +static inline LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_task_handler(void) +{ + return lv_timer_handler(); +} + +/** + * Move the object to the foreground. + * It will look like if it was created as the last child of its parent. + * It also means it can cover any of the siblings. + * @param obj pointer to an object + */ +static inline void lv_obj_move_foreground(lv_obj_t * obj) +{ + lv_obj_t * parent = lv_obj_get_parent(obj); + if(!parent) { + LV_LOG_WARN("parent is NULL"); + return; + } + + lv_obj_move_to_index(obj, lv_obj_get_child_count(parent) - 1); +} + +/** + * Move the object to the background. + * It will look like if it was created as the first child of its parent. + * It also means any of the siblings can cover the object. + * @param obj pointer to an object + */ +static inline void lv_obj_move_background(lv_obj_t * obj) +{ + lv_obj_move_to_index(obj, 0); +} + +/********************** + * MACROS + **********************/ +#define LV_RES_OK LV_RESULT_OK +#define LV_RES_INV LV_RESULT_INVALID + +#define LV_INDEV_STATE_PR LV_INDEV_STATE_PRESSED +#define LV_INDEV_STATE_REL LV_INDEV_STATE_RELEASED + +#define lv_obj_del lv_obj_delete +#define lv_obj_del_async lv_obj_delete_async +#define lv_obj_clear_flag lv_obj_remove_flag +#define lv_obj_clear_state lv_obj_remove_state + +#define lv_indev_set_disp lv_indev_set_display +#define lv_indev_get_act lv_indev_active +#define lv_scr_act lv_screen_active +#define lv_disp_remove lv_display_delete +#define lv_disp_set_default lv_display_set_default +#define lv_disp_get_default lv_display_get_default +#define lv_disp_get_next lv_display_get_next +#define lv_disp_set_rotation lv_display_set_rotation +#define lv_disp_get_hor_res lv_display_get_horizontal_resolution +#define lv_disp_get_ver_res lv_display_get_vertical_resolution +#define lv_disp_get_physical_hor_res lv_display_get_physical_horizontal_resolution +#define lv_disp_get_physical_ver_res lv_display_get_physical_vertical_resolution +#define lv_disp_get_offset_x lv_display_get_offset_x +#define lv_disp_get_offset_y lv_display_get_offset_y +#define lv_disp_get_rotation lv_display_get_rotation +#define lv_disp_get_dpi lv_display_get_dpi +#define lv_disp_get_antialiasing lv_display_get_antialiasing +#define lv_disp_flush_ready lv_display_flush_ready +#define lv_disp_flush_is_last lv_display_flush_is_last +#define lv_disp_get_scr_act lv_display_get_screen_active +#define lv_disp_get_scr_prev lv_display_get_screen_prev +#define lv_disp_load_scr lv_screen_load +#define lv_scr_load lv_screen_load +#define lv_scr_load_anim lv_screen_load_anim +#define lv_disp_get_layer_top lv_display_get_layer_top +#define lv_disp_get_layer_sys lv_display_get_layer_sys +#define lv_disp_send_event lv_display_send_event +#define lv_disp_set_theme lv_display_set_theme +#define lv_disp_get_theme lv_display_get_theme +#define lv_disp_get_inactive_time lv_display_get_inactive_time +#define lv_disp_trig_activity lv_display_trigger_activity +#define lv_disp_enable_invalidation lv_display_enable_invalidation +#define lv_disp_is_invalidation_enabled lv_display_is_invalidation_enabled +#define lv_disp_refr_timer lv_display_refr_timer +#define lv_disp_get_refr_timer lv_display_get_refr_timer + +#define lv_timer_del lv_timer_delete + +#define lv_anim_del lv_anim_delete +#define lv_anim_del_all lv_anim_delete_all +#define lv_anim_set_ready_cb lv_anim_set_completed_cb + +#define lv_group_del lv_group_delete + +#if LV_USE_TEXTAREA +#define lv_txt_get_size lv_text_get_size +#define lv_txt_get_width lv_text_get_width +#endif /* LV_USE_TEXTAREA */ + +#if LV_USE_IMAGE +#define lv_img_create lv_image_create +#define lv_img_set_src lv_image_set_src +#define lv_img_set_offset_x lv_image_set_offset_x +#define lv_img_set_offset_y lv_image_set_offset_y +#define lv_img_set_angle lv_image_set_rotation +#define lv_img_set_pivot lv_image_set_pivot +#define lv_img_set_zoom lv_image_set_scale +#define lv_img_set_antialias lv_image_set_antialias +#define lv_img_get_src lv_image_get_src +#define lv_img_get_offset_x lv_image_get_offset_x +#define lv_img_get_offset_y lv_image_get_offset_y +#define lv_img_get_angle lv_image_get_rotation +#define lv_img_get_pivot lv_image_get_pivot +#define lv_img_get_zoom lv_image_get_scale +#define lv_img_get_antialias lv_image_get_antialias +#endif /* LV_USE_IMAGE */ + +#if LV_USE_IMAGEBUTTON +#define lv_imgbtn_create lv_imagebutton_create +#define lv_imgbtn_set_src lv_imagebutton_set_src +#define lv_imgbtn_set_state lv_imagebutton_set_state +#define lv_imgbtn_get_src_left lv_imagebutton_get_src_left +#define lv_imgbtn_get_src_middle lv_imagebutton_get_src_middle +#define lv_imgbtn_get_src_right lv_imagebutton_get_src_right +#endif /* LV_USE_IMAGEBUTTON */ + +#if LV_USE_LIST +#define lv_list_set_btn_text lv_list_set_button_text +#define lv_list_get_btn_text lv_list_get_button_text +#define lv_list_add_btn lv_list_add_button +#endif /* LV_USE_LIST */ + +#if LV_USE_BUTTON +#define lv_btn_create lv_button_create +#endif /* LV_USE_BUTTON */ + +#if LV_USE_BUTTONMATRIX +#define lv_btnmatrix_create lv_buttonmatrix_create +#define lv_btnmatrix_set_map lv_buttonmatrix_set_map +#define lv_btnmatrix_set_ctrl_map lv_buttonmatrix_set_ctrl_map +#define lv_btnmatrix_set_selected_btn lv_buttonmatrix_set_selected_button +#define lv_btnmatrix_set_btn_ctrl lv_buttonmatrix_set_button_ctrl +#define lv_btnmatrix_clear_btn_ctrl lv_buttonmatrix_clear_button_ctrl +#define lv_btnmatrix_set_btn_ctrl_all lv_buttonmatrix_set_button_ctrl_all +#define lv_btnmatrix_clear_btn_ctrl_all lv_buttonmatrix_clear_button_ctrl_all +#define lv_btnmatrix_set_btn_width lv_buttonmatrix_set_button_width +#define lv_btnmatrix_set_one_checked lv_buttonmatrix_set_one_checked +#define lv_btnmatrix_get_map lv_buttonmatrix_get_map +#define lv_btnmatrix_get_selected_btn lv_buttonmatrix_get_selected_button +#define lv_btnmatrix_get_btn_text lv_buttonmatrix_get_button_text +#define lv_btnmatrix_has_button_ctrl lv_buttonmatrix_has_button_ctrl +#define lv_btnmatrix_get_one_checked lv_buttonmatrix_get_one_checked +#endif /* LV_USE_BUTTONMATRIX */ + +#if LV_USE_TABVIEW +#define lv_tabview_get_tab_btns lv_tabview_get_tab_bar +#define lv_tabview_get_tab_act lv_tabview_get_tab_active +#define lv_tabview_set_act lv_tabview_set_active +#endif /* LV_USE_TABVIEW */ + +#if LV_USE_TILEVIEW +#define lv_tileview_get_tile_act lv_tileview_get_tile_active +#define lv_obj_set_tile_id lv_tileview_set_tile_by_index +#define lv_obj_set_tile lv_tileview_set_tile +#endif /* LV_USE_TILEVIEW */ + +#if LV_USE_ROLLER +#define lv_roller_set_visible_row_cnt lv_roller_set_visible_row_count +#define lv_roller_get_option_cnt lv_roller_get_option_count +#endif /* LV_USE_ROLLER */ + +#if LV_USE_TABLE +#define lv_table_set_col_cnt lv_table_set_column_count +#define lv_table_set_row_cnt lv_table_set_row_count +#define lv_table_get_col_cnt lv_table_get_column_count +#define lv_table_get_row_cnt lv_table_get_row_count +#define lv_table_set_col_width lv_table_set_column_width +#define lv_table_get_col_width lv_table_get_column_width +#endif /* LV_USE_TABLE */ + +#if LV_USE_DROPDOWN +#define lv_dropdown_get_option_cnt lv_dropdown_get_option_count +#endif /* LV_USE_DROPDOWN */ + +#define lv_obj_get_child_cnt lv_obj_get_child_count +#define lv_obj_get_disp lv_obj_get_display +#define lv_obj_delete_anim_ready_cb lv_obj_delete_anim_completed_cb + +#define LV_STYLE_ANIM_TIME LV_STYLE_ANIM_DURATION +#define LV_STYLE_IMG_OPA LV_STYLE_IMAGE_OPA +#define LV_STYLE_IMG_RECOLOR LV_STYLE_IMAGE_RECOLOR +#define LV_STYLE_IMG_RECOLOR_OPA LV_STYLE_IMAGE_RECOLOR_OPA +#define LV_STYLE_SHADOW_OFS_X LV_STYLE_SHADOW_OFFSET_X +#define LV_STYLE_SHADOW_OFS_Y LV_STYLE_SHADOW_OFFSET_Y +#define LV_STYLE_TRANSFORM_ANGLE LV_STYLE_TRANSFORM_ROTATION + +#define lv_obj_get_style_anim_time lv_obj_get_style_anim_duration +#define lv_obj_get_style_img_opa lv_obj_get_style_image_opa +#define lv_obj_get_style_img_recolor lv_obj_get_style_image_recolor +#define lv_obj_get_style_img_recolor_filtered lv_obj_get_style_image_recolor_filtered +#define lv_obj_get_style_img_recolor_opa lv_obj_get_style_image_recolor_opa +#define lv_obj_get_style_shadow_ofs_x lv_obj_get_style_shadow_offset_x +#define lv_obj_get_style_shadow_ofs_y lv_obj_get_style_shadow_offset_y +#define lv_obj_get_style_transform_angle lv_obj_get_style_transform_rotation +#define lv_obj_get_style_bg_img_src lv_obj_get_style_bg_image_src +#define lv_obj_get_style_bg_img_recolor lv_obj_get_style_bg_image_recolor +#define lv_obj_get_style_bg_img_recolor_opa lv_obj_get_style_bg_image_recolor_opa + +#define lv_obj_set_style_anim_time lv_obj_set_style_anim_duration +#define lv_obj_set_style_img_opa lv_obj_set_style_image_opa +#define lv_obj_set_style_img_recolor lv_obj_set_style_image_recolor +#define lv_obj_set_style_img_recolor_opa lv_obj_set_style_image_recolor_opa +#define lv_obj_set_style_shadow_ofs_x lv_obj_set_style_shadow_offset_x +#define lv_obj_set_style_shadow_ofs_y lv_obj_set_style_shadow_offset_y +#define lv_obj_set_style_transform_zoom lv_obj_set_style_transform_scale +#define lv_obj_set_style_transform_angle lv_obj_set_style_transform_rotation +#define lv_obj_set_style_bg_img_src lv_obj_set_style_bg_image_src +#define lv_obj_set_style_bg_img_recolor lv_obj_set_style_bg_image_recolor +#define lv_obj_set_style_bg_img_recolor_opa lv_obj_set_style_bg_image_recolor_opa + +#define lv_style_set_anim_time lv_style_set_anim_duration +#define lv_style_set_img_opa lv_style_set_image_opa +#define lv_style_set_img_recolor lv_style_set_image_recolor +#define lv_style_set_img_recolor_opa lv_style_set_image_recolor_opa +#define lv_style_set_shadow_ofs_x lv_style_set_shadow_offset_x +#define lv_style_set_shadow_ofs_y lv_style_set_shadow_offset_y +#define lv_style_set_transform_angle lv_style_set_transform_rotation +#define lv_style_set_transform_zoom lv_style_set_transform_scale +#define lv_style_set_bg_img_src lv_style_set_bg_image_src +#define lv_style_set_bg_img_recolor lv_style_set_bg_image_recolor +#define lv_style_set_bg_img_recolor_opa lv_style_set_bg_image_recolor_opa + +#if LV_USE_KEYBOARD +#define lv_keyboard_get_selected_btn lv_keyboard_get_selected_button +#define lv_keyboard_get_btn_text lv_keyboard_get_button_text +#endif /* LV_USE_KEYBOARD */ + +#define LV_ZOOM_NONE LV_SCALE_NONE + +#define lv_image_decoder_built_in_open lv_bin_decoder_open +#define lv_image_decoder_built_in_close lv_bin_decoder_close + +/********************** + * MACROS + **********************/ +/** Use this macro to declare an image in a C file*/ +#define LV_IMG_DECLARE(var_name) extern const lv_image_dsc_t var_name; + +/********************** + * DEPRECATED FUNCTIONS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_API_MAP_V8_H*/ diff --git a/test/include/liblvgl/lv_api_map_v9_0.h b/test/include/liblvgl/lv_api_map_v9_0.h new file mode 100644 index 00000000..b0d22cdf --- /dev/null +++ b/test/include/liblvgl/lv_api_map_v9_0.h @@ -0,0 +1,66 @@ +/** + * @file lv_api_map_v9_0.h + * + */ + +#ifndef LV_API_MAP_V9_0_H +#define LV_API_MAP_V9_0_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ +#define lv_image_set_align lv_image_set_inner_align +#define lv_image_get_align lv_image_get_inner_align + +#ifndef LV_DRAW_LAYER_SIMPLE_BUF_SIZE +#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE LV_DRAW_SW_LAYER_SIMPLE_BUF_SIZE +#endif + +#define lv_button_bind_checked lv_obj_bind_checked + +#define LV_DRAW_BUF_DEFINE LV_DRAW_BUF_DEFINE_STATIC + +#define _lv_utils_bsearch lv_utils_bsearch +#define lv_draw_buf_align_user lv_draw_buf_align_ex +#define lv_draw_buf_create_user lv_draw_buf_create_ex +#define lv_draw_buf_width_to_stride_user lv_draw_buf_width_to_stride_ex +#define lv_draw_buf_dup_user lv_draw_buf_dup_ex + +#define lv_draw_buf_invalidate_cache_user(handlers, drawbuf, area) lv_draw_buf_invalidate_cache(drawbuf, area) +#define lv_draw_buf_flush_cache_user(handlers, drawbuf, area) lv_draw_buf_flush_cache(drawbuf, area) +#define lv_draw_buf_destroy_user(handlers, drawbuf) lv_draw_buf_destroy(drawbuf) + +/********************** + * MACROS + **********************/ + +/********************** + * DEPRECATED FUNCTIONS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_API_MAP_V9_0_H*/ diff --git a/test/include/liblvgl/lv_api_map_v9_1.h b/test/include/liblvgl/lv_api_map_v9_1.h new file mode 100644 index 00000000..a142b406 --- /dev/null +++ b/test/include/liblvgl/lv_api_map_v9_1.h @@ -0,0 +1,90 @@ +/** + * @file lv_api_map_v9_1.h + * + */ + +#ifndef LV_API_MAP_V9_1_H +#define LV_API_MAP_V9_1_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * MACROS + **********************/ + +#define _LV_EVENT_LAST LV_EVENT_LAST +#define _lv_event_code_t lv_event_code_t +#define _lv_event_mark_deleted lv_event_mark_deleted +#define lv_obj_add_event lv_obj_add_event_cb + +#define _LV_STYLE_LAST_BUILT_IN_PROP LV_STYLE_LAST_BUILT_IN_PROP +#define _LV_FLEX_REVERSE LV_FLEX_REVERSE +#define _LV_FLEX_WRAP LV_FLEX_WRAP +#define _LV_FLEX_COLUMN LV_FLEX_COLUMN + +#define _lv_area_is_equal lv_area_is_equal +#define _lv_area_is_in lv_area_is_in +#define _lv_area_intersect lv_area_intersect +#define _lv_area_is_point_on lv_area_is_point_on +#define _lv_area_join lv_area_join +#define _lv_image_buf_get_transformed_area lv_image_buf_get_transformed_area + +#define _lv_ll_init lv_ll_init +#define _lv_ll_ins_head lv_ll_ins_head +#define _lv_ll_ins_prev lv_ll_ins_prev +#define _lv_ll_ins_tail lv_ll_ins_tail +#define _lv_ll_get_head lv_ll_get_head +#define _lv_ll_get_tail lv_ll_get_tail +#define _lv_ll_get_next lv_ll_get_next +#define _lv_ll_get_prev lv_ll_get_prev +#define _lv_ll_get_len lv_ll_get_len +#define _lv_ll_move_before lv_ll_move_before +#define _lv_ll_is_empty lv_ll_is_empty +#define _lv_ll_clear lv_ll_clear +#define _lv_ll_remove lv_ll_remove +#define _lv_ll_chg_list lv_ll_chg_list +#define _LV_LL_READ LV_LL_READ +#define _LV_LL_READ_BACK LV_LL_READ_BACK + +#define _lv_obj_scroll_by_raw lv_obj_scroll_by_raw +#define _lv_obj_get_ext_draw_size lv_obj_get_ext_draw_size +#define _lv_indev_scroll_handler lv_indev_scroll_handler + +#define _lv_display_refr_timer lv_disp_refr_timer +#define _lv_disp_refr_timer lv_disp_refr_timer +#define _lv_disp_get_refr_timer lv_disp_get_refr_timer + +#define _lv_inv_area lv_inv_area + +/********************** + * DEPRECATED FUNCTIONS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_API_MAP_V9_0_H*/ diff --git a/test/include/liblvgl/lv_conf.h b/test/include/liblvgl/lv_conf.h new file mode 100644 index 00000000..e4369823 --- /dev/null +++ b/test/include/liblvgl/lv_conf.h @@ -0,0 +1,790 @@ +/** + * @file lv_conf.h + * Configuration file for v7.11.0 + */ + +/* + * COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER + */ + +#if 1 /*Set it to "1" to enable content*/ + +#ifndef LV_CONF_H +#define LV_CONF_H +/* clang-format off */ + +#include + +/*==================== + Graphical settings + *====================*/ + +/* Maximal horizontal and vertical resolution to support by the library.*/ +#define LV_HOR_RES_MAX (480) +#define LV_VER_RES_MAX (240) + +/* Color depth: + * - 1: 1 byte per pixel + * - 8: RGB332 + * - 16: RGB565 + * - 32: ARGB8888 + */ +#define LV_COLOR_DEPTH 32 + +/* Swap the 2 bytes of RGB565 color. + * Useful if the display has a 8 bit interface (e.g. SPI)*/ +#define LV_COLOR_16_SWAP 0 + +/* 1: Enable screen transparency. + * Useful for OSD or other overlapping GUIs. + * Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/ +#define LV_COLOR_SCREEN_TRANSP 0 + +/*Images pixels with this color will not be drawn (with chroma keying)*/ +#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/ + +/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ +#define LV_ANTIALIAS 1 + +/* Default display refresh period. + * Can be changed in the display driver (`lv_disp_drv_t`).*/ +#define LV_DISP_DEF_REFR_PERIOD 40 /*[ms]*/ + +/* Dot Per Inch: used to initialize default sizes. + * E.g. a button with width = LV_DPI / 2 -> half inch wide + * (Not so important, you can adjust it to modify default sizes and spaces)*/ +#define LV_DPI 126 /*[px]*/ + +/* The the real width of the display changes some default values: + * default object sizes, layout of examples, etc. + * According to the width of the display (hor. res. / dpi) + * the displays fall in 4 categories. + * The 4th is extra large which has no upper limit so not listed here + * The upper limit of the categories are set below in 0.1 inch unit. + */ +#define LV_DISP_SMALL_LIMIT 30 +#define LV_DISP_MEDIUM_LIMIT 50 +#define LV_DISP_LARGE_LIMIT 70 + +/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */ +typedef int16_t lv_coord_t; + +/* Maximum buffer size to allocate for rotation. Only used if software rotation is enabled. */ +#define LV_DISP_ROT_MAX_BUF (10U * 1024U) + +/*========================= + Memory manager settings + *=========================*/ + +/* LittelvGL's internal memory manager's settings. + * The graphical objects and other related data are stored here. */ + +/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */ +#define LV_MEM_CUSTOM 0 +#if LV_MEM_CUSTOM == 0 +/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ +# define LV_MEM_SIZE (10U * 1024U * 1024U) + +/* Compiler prefix for a big array declaration */ +# define LV_MEM_ATTR + +/* Set an address for the memory pool instead of allocating it as an array. + * Can be in external SRAM too. */ +# define LV_MEM_ADR 0 + +/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */ +# define LV_MEM_AUTO_DEFRAG 1 +#else /*LV_MEM_CUSTOM*/ +# define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/ +# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/ +# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/ +#endif /*LV_MEM_CUSTOM*/ + +/* Use the standard memcpy and memset instead of LVGL's own functions. + * The standard functions might or might not be faster depending on their implementation. */ +#define LV_MEMCPY_MEMSET_STD 0 + +/* Garbage Collector settings + * Used if lvgl is binded to higher level language and the memory is managed by that language */ +#define LV_ENABLE_GC 0 +#if LV_ENABLE_GC != 0 +# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/ +# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/ +# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/ +#endif /* LV_ENABLE_GC */ + +/*======================= + Input device settings + *=======================*/ + +/* Input device default settings. + * Can be changed in the Input device driver (`lv_indev_drv_t`)*/ + +/* Input device read period in milliseconds */ +#define LV_INDEV_DEF_READ_PERIOD 50 + +/* Drag threshold in pixels */ +#define LV_INDEV_DEF_DRAG_LIMIT 10 + +/* Drag throw slow-down in [%]. Greater value -> faster slow-down */ +#define LV_INDEV_DEF_DRAG_THROW 20 + +/* Long press time in milliseconds. + * Time to send `LV_EVENT_LONG_PRESSED`) */ +#define LV_INDEV_DEF_LONG_PRESS_TIME 400 + +/* Repeated trigger period in long press [ms] + * Time between `LV_EVENT_LONG_PRESSED_REPEAT */ +#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100 + +/* Gesture threshold in pixels */ +#define LV_INDEV_DEF_GESTURE_LIMIT 50 + +/* Gesture min velocity at release before swipe (pixels)*/ +#define LV_INDEV_DEF_GESTURE_MIN_VELOCITY 3 + +/*================== + * Feature usage + *==================*/ + +/*1: Enable the Animations */ +#define LV_USE_ANIMATION 1 +#if LV_USE_ANIMATION + +/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_anim_user_data_t; + +#endif + +/* 1: Enable shadow drawing on rectangles*/ +#define LV_USE_SHADOW 1 +#if LV_USE_SHADOW +/* Allow buffering some shadow calculation + * LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, + * where shadow size is `shadow_width + radius` + * Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/ +#define LV_SHADOW_CACHE_SIZE 0 +#endif + +/*1: enable outline drawing on rectangles*/ +#define LV_USE_OUTLINE 1 + +/*1: enable pattern drawing on rectangles*/ +#define LV_USE_PATTERN 1 + +/*1: enable value string drawing on rectangles*/ +#define LV_USE_VALUE_STR 1 + +/* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/ +#define LV_USE_BLEND_MODES 1 + +/* 1: Use the `opa_scale` style property to set the opacity of an object and its children at once*/ +#define LV_USE_OPA_SCALE 1 + +/* 1: Use image zoom and rotation*/ +#define LV_USE_IMG_TRANSFORM 1 + +/* 1: Enable object groups (for keyboard/encoder navigation) */ +#define LV_USE_GROUP 1 +#if LV_USE_GROUP +typedef void * lv_group_user_data_t; +#endif /*LV_USE_GROUP*/ + +/* 1: Enable GPU interface*/ +#define LV_USE_GPU 0 /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */ +#define LV_USE_GPU_STM32_DMA2D 0 +/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor +e.g. "stm32f769xx.h" or "stm32f429xx.h" */ +#define LV_GPU_DMA2D_CMSIS_INCLUDE + +/*1: Use PXP for CPU off-load on NXP RTxxx platforms */ +#define LV_USE_GPU_NXP_PXP 0 + +/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c) + * and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS + * has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected. + *0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init() + * */ +#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0 + +/*1: Use VG-Lite for CPU offload on NXP RTxxx platforms */ +#define LV_USE_GPU_NXP_VG_LITE 0 + +/* 1: Enable file system (might be required for images */ +#define LV_USE_FILESYSTEM 1 +#if LV_USE_FILESYSTEM +/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_fs_drv_user_data_t; +#endif + +#define LV_USE_FS_STDIO 1 +#define LV_FS_STDIO_LETTER 'S' +#define LV_FS_STDIO_PATH "/usd/" +#define LV_FS_STDIO_CACHE_SIZE 0 + +#define LV_USE_LODEPNG 1 +#define LV_USE_GIF 1 +#define LV_USE_TJPGD 1 + +/*1: Add a `user_data` to drivers and objects*/ +#define LV_USE_USER_DATA 1 + +/*1: Show CPU usage and FPS count in the right bottom corner*/ +#define LV_USE_PERF_MONITOR 0 + +/*1: Use the functions and types from the older API if possible */ +#define LV_USE_API_EXTENSION_V6 1 +#define LV_USE_API_EXTENSION_V7 1 + +/*======================== + * Image decoder and cache + *========================*/ + +/* 1: Enable indexed (palette) images */ +#define LV_IMG_CF_INDEXED 1 + +/* 1: Enable alpha indexed images */ +#define LV_IMG_CF_ALPHA 1 + +/* Default image cache size. Image caching keeps the images opened. + * If only the built-in image formats are used there is no real advantage of caching. + * (I.e. no new image decoder is added) + * With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. + * However the opened images might consume additional RAM. + * Set it to 0 to disable caching */ +#define LV_IMG_CACHE_DEF_SIZE (8U * 1024U) + +/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_img_decoder_user_data_t; + +/*===================== + * Compiler settings + *====================*/ + +/* For big endian systems set to 1 */ +#define LV_BIG_ENDIAN_SYSTEM 0 + +/* Define a custom attribute to `lv_tick_inc` function */ +#define LV_ATTRIBUTE_TICK_INC + +/* Define a custom attribute to `lv_task_handler` function */ +#define LV_ATTRIBUTE_TASK_HANDLER + +/* Define a custom attribute to `lv_disp_flush_ready` function */ +#define LV_ATTRIBUTE_FLUSH_READY + +/* Required alignment size for buffers */ +#define LV_ATTRIBUTE_MEM_ALIGN_SIZE + +/* With size optimization (-Os) the compiler might not align data to + * 4 or 8 byte boundary. Some HW may need even 32 or 64 bytes. + * This alignment will be explicitly applied where needed. + * LV_ATTRIBUTE_MEM_ALIGN_SIZE should be used to specify required align size. + * E.g. __attribute__((aligned(LV_ATTRIBUTE_MEM_ALIGN_SIZE))) */ +#define LV_ATTRIBUTE_MEM_ALIGN + +/* Attribute to mark large constant arrays for example + * font's bitmaps */ +#define LV_ATTRIBUTE_LARGE_CONST + +/* Prefix performance critical functions to place them into a faster memory (e.g RAM) + * Uses 15-20 kB extra memory */ +#define LV_ATTRIBUTE_FAST_MEM + +/* Export integer constant to binding. + * This macro is used with constants in the form of LV_ that + * should also appear on lvgl binding API such as Micropython + * + * The default value just prevents a GCC warning. + */ +#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning + +/* Prefix variables that are used in GPU accelerated operations, often these need to be + * placed in RAM sections that are DMA accessible */ +#define LV_ATTRIBUTE_DMA + +/*=================== + * HAL settings + *==================*/ + +/* 1: use a custom tick source. + * It removes the need to manually update the tick with `lv_tick_inc`) */ +#define LV_TICK_CUSTOM 0 +#if LV_TICK_CUSTOM == 1 +#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/ +#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/ +#endif /*LV_TICK_CUSTOM*/ + +typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/ +typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/ + +/*================ + * Log settings + *===============*/ + +/*1: Enable the log module*/ +#define LV_USE_LOG 1 +#if LV_USE_LOG +/* How important log should be added: + * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information + * LV_LOG_LEVEL_INFO Log important events + * LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem + * LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail + * LV_LOG_LEVEL_NONE Do not log anything + */ +# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + +/* 1: Print the log with 'printf'; + * 0: user need to register a callback with `lv_log_register_print_cb`*/ +# define LV_LOG_PRINTF 1 +#endif /*LV_USE_LOG*/ + +/*================= + * Debug settings + *================*/ + +/* If Debug is enabled LittelvGL validates the parameters of the functions. + * If an invalid parameter is found an error log message is printed and + * the MCU halts at the error. (`LV_USE_LOG` should be enabled) + * If you are debugging the MCU you can pause + * the debugger to see exactly where the issue is. + * + * The behavior of asserts can be overwritten by redefining them here. + * E.g. #define LV_ASSERT_MEM(p) + */ +#define LV_USE_DEBUG 1 +#if LV_USE_DEBUG + +/*Check if the parameter is NULL. (Quite fast) */ +#define LV_USE_ASSERT_NULL 1 + +/*Checks is the memory is successfully allocated or no. (Quite fast)*/ +#define LV_USE_ASSERT_MEM 1 + +/*Check the integrity of `lv_mem` after critical operations. (Slow)*/ +#define LV_USE_ASSERT_MEM_INTEGRITY 0 + +/* Check the strings. + * Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow) + * If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */ +#define LV_USE_ASSERT_STR 0 + +/* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow) + * If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */ +#define LV_USE_ASSERT_OBJ 0 + +/*Check if the styles are properly initialized. (Fast)*/ +#define LV_USE_ASSERT_STYLE 0 + +#endif /*LV_USE_DEBUG*/ + +/*================== + * FONT USAGE + *===================*/ + +/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel. + * The symbols are available via `LV_SYMBOL_...` defines + * More info about fonts: https://docs.lvgl.io/v7/en/html/overview/font.html + * To create a new font go to: https://lvgl.com/ttf-font-to-c-array + */ + +/* Montserrat fonts with bpp = 4 + * https://fonts.google.com/specimen/Montserrat */ +#define LV_FONT_MONTSERRAT_8 0 +#define LV_FONT_MONTSERRAT_10 1 +#define LV_FONT_MONTSERRAT_12 1 +#define LV_FONT_MONTSERRAT_14 1 +#define LV_FONT_MONTSERRAT_16 1 +#define LV_FONT_MONTSERRAT_18 1 +#define LV_FONT_MONTSERRAT_20 1 +#define LV_FONT_MONTSERRAT_22 0 +#define LV_FONT_MONTSERRAT_24 1 +#define LV_FONT_MONTSERRAT_26 0 +#define LV_FONT_MONTSERRAT_28 0 +#define LV_FONT_MONTSERRAT_30 1 +#define LV_FONT_MONTSERRAT_32 0 +#define LV_FONT_MONTSERRAT_34 0 +#define LV_FONT_MONTSERRAT_36 1 +#define LV_FONT_MONTSERRAT_38 0 +#define LV_FONT_MONTSERRAT_40 1 +#define LV_FONT_MONTSERRAT_42 1 +#define LV_FONT_MONTSERRAT_44 0 +#define LV_FONT_MONTSERRAT_46 0 +#define LV_FONT_MONTSERRAT_48 1 + +/* Demonstrate special features */ +#define LV_FONT_MONTSERRAT_12_SUBPX 0 +#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ +#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, PErisan letters and all their forms*/ +#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ + +/*Pixel perfect monospace font + * http://pelulamu.net/unscii/ */ +#define LV_FONT_UNSCII_8 1 +#define LV_FONT_UNSCII_16 1 + +/* Optionally declare your custom fonts here. + * You can use these fonts as default font too + * and they will be available globally. E.g. + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ + * LV_FONT_DECLARE(my_font_2) + */ +#define LV_FONT_CUSTOM_DECLARE + +/* Enable it if you have fonts with a lot of characters. + * The limit depends on the font size, font face and bpp + * but with > 10,000 characters if you see issues probably you need to enable it.*/ +#define LV_FONT_FMT_TXT_LARGE 0 + +/* Enables/disables support for compressed fonts. If it's disabled, compressed + * glyphs cannot be processed by the library and won't be rendered. + */ +#define LV_USE_FONT_COMPRESSED 1 +#define LV_USE_QRCODE 0 + +/* Enable subpixel rendering */ +#define LV_USE_FONT_SUBPX 1 +#if LV_USE_FONT_SUBPX +/* Set the pixel order of the display. + * Important only if "subpx fonts" are used. + * With "normal" font it doesn't matter. + */ +#define LV_FONT_SUBPX_BGR 0 + +/* PROS adds the mono variant of DejaVu sans */ +#define USE_PROS_FONT_DEJAVU_MONO_10 1 + +#define USE_PROS_FONT_DEJAVU_MONO_18 1 // llemu font + +#define USE_PROS_FONT_DEJAVU_MONO_30 0 + +#define USE_PROS_FONT_DEJAVU_MONO_40 0 + +#endif + +/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_font_user_data_t; + +/*================ + * THEME USAGE + *================*/ + +/*Always enable at least on theme*/ + +/* No theme, you can apply your styles as you need + * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ +#define LV_USE_THEME_EMPTY 1 + +/*Simple to the create your theme based on it + * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ +#define LV_USE_THEME_TEMPLATE 1 + +/* A fast and impressive theme. + * Flags: + * LV_THEME_MATERIAL_FLAG_LIGHT: light theme + * LV_THEME_MATERIAL_FLAG_DARK: dark theme + * LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations) + * LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state) + * */ +#define LV_USE_THEME_MATERIAL 1 + +/* Mono-color theme for monochrome displays. + * If LV_THEME_DEFAULT_COLOR_PRIMARY is LV_COLOR_BLACK the + * texts and borders will be black and the background will be + * white. Else the colors are inverted. + * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ +#define LV_USE_THEME_MONO 1 + +#define LV_THEME_DEFAULT_INCLUDE /*Include a header for the init. function*/ +#define LV_THEME_DEFAULT_INIT lv_theme_material_init +#define LV_THEME_DEFAULT_COLOR_PRIMARY lv_color_hex(0x01a2b1) +#define LV_THEME_DEFAULT_COLOR_SECONDARY lv_color_hex(0x44d1b6) +#define LV_THEME_DEFAULT_FLAG LV_THEME_MATERIAL_FLAG_DARK +#define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_10 +#define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_20 +#define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_10 +#define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_30 + +#define CONFIG_LV_THEME_DEFAULT_DARK 1 + +/*================= + * Text settings + *=================*/ + +/* Select a character encoding for strings. + * Your IDE or editor should have the same character encoding + * - LV_TXT_ENC_UTF8 + * - LV_TXT_ENC_ASCII + * */ +#define LV_TXT_ENC LV_TXT_ENC_UTF8 + + /*Can break (wrap) texts on these chars*/ +#define LV_TXT_BREAK_CHARS " ,.;:-_" + +/* If a word is at least this long, will break wherever "prettiest" + * To disable, set to a value <= 0 */ +#define LV_TXT_LINE_BREAK_LONG_LEN 0 + +/* Minimum number of characters in a long word to put on a line before a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 + +/* Minimum number of characters in a long word to put on a line after a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 + +/* The control character to use for signalling text recoloring. */ +#define LV_TXT_COLOR_CMD "#" + +/* Support bidirectional texts. + * Allows mixing Left-to-Right and Right-to-Left texts. + * The direction will be processed according to the Unicode Bidirectional Algorithm: + * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ +#define LV_USE_BIDI 0 +#if LV_USE_BIDI +/* Set the default direction. Supported values: + * `LV_BIDI_DIR_LTR` Left-to-Right + * `LV_BIDI_DIR_RTL` Right-to-Left + * `LV_BIDI_DIR_AUTO` detect texts base direction */ +#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO +#endif + +/* Enable Arabic/Persian processing + * In these languages characters should be replaced with + * an other form based on their position in the text */ +#define LV_USE_ARABIC_PERSIAN_CHARS 0 + +/*Change the built in (v)snprintf functions*/ +#define LV_SPRINTF_CUSTOM 0 +#if LV_SPRINTF_CUSTOM +# define LV_SPRINTF_INCLUDE +# define lv_snprintf snprintf +# define lv_vsnprintf vsnprintf +#else /*!LV_SPRINTF_CUSTOM*/ +# define LV_SPRINTF_DISABLE_FLOAT 1 +#endif /*LV_SPRINTF_CUSTOM*/ + +/*=================== + * LV_OBJ SETTINGS + *==================*/ + +#if LV_USE_USER_DATA +/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_obj_user_data_t; +/*Provide a function to free user data*/ +#define LV_USE_USER_DATA_FREE 0 +#if LV_USE_USER_DATA_FREE +# define LV_USER_DATA_FREE_INCLUDE "something.h" /*Header for user data free function*/ +/* Function prototype : void user_data_free(lv_obj_t * obj); */ +# define LV_USER_DATA_FREE (user_data_free) /*Invoking for user data free function*/ +#endif +#endif + +/*1: enable `lv_obj_realign()` based on `lv_obj_align()` parameters*/ +#define LV_USE_OBJ_REALIGN 1 + +/* Enable to make the object clickable on a larger area. + * LV_EXT_CLICK_AREA_OFF or 0: Disable this feature + * LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px) + * LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px) + */ +#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_TINY + +#define LV_USE_FLEX 1 +#define LV_USE_GRID 1 + +/*================== + * LV OBJ X USAGE + *================*/ +/* + * Documentation of the object types: https://docs.lvgl.com/#Object-types + */ + +/*Arc (dependencies: -)*/ +#define LV_USE_ARC 1 + +/*Bar (dependencies: -)*/ +#define LV_USE_BAR 1 + +/*Button (dependencies: lv_cont*/ +#define LV_USE_BTN 1 + +/*Button matrix (dependencies: -)*/ +#define LV_USE_BTNMATRIX 1 + +/*Calendar (dependencies: -)*/ +#define LV_USE_CALENDAR 1 +#if LV_USE_CALENDAR +# define LV_CALENDAR_WEEK_STARTS_MONDAY 0 +#endif + +/*Canvas (dependencies: lv_img)*/ +#define LV_USE_CANVAS 1 + +/*Check box (dependencies: lv_btn, lv_label)*/ +#define LV_USE_CHECKBOX 1 + +/*Chart (dependencies: -)*/ +#define LV_USE_CHART 1 +#if LV_USE_CHART +# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 256 +#endif + +/*Container (dependencies: -*/ +#define LV_USE_CONT 1 + +/*Color picker (dependencies: -*/ +#define LV_USE_CPICKER 1 + +/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/ +#define LV_USE_DROPDOWN 1 +#if LV_USE_DROPDOWN != 0 +/*Open and close default animation time [ms] (0: no animation)*/ +# define LV_DROPDOWN_DEF_ANIM_TIME 200 +#endif + +/*Gauge (dependencies:lv_bar, lv_linemeter)*/ +#define LV_USE_GAUGE 1 + +/*Image (dependencies: lv_label*/ +#define LV_USE_IMG 1 + +/*Image Button (dependencies: lv_btn*/ +#define LV_USE_IMGBTN 1 +#if LV_USE_IMGBTN +/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/ +# define LV_IMGBTN_TILED 0 +#endif + +/*Keyboard (dependencies: lv_btnm)*/ +#define LV_USE_KEYBOARD 1 + +/*Label (dependencies: -*/ +#define LV_USE_LABEL 1 +#if LV_USE_LABEL != 0 +/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/ +# define LV_LABEL_DEF_SCROLL_SPEED 25 + +/* Waiting period at beginning/end of animation cycle */ +# define LV_LABEL_WAIT_CHAR_COUNT 3 + +/*Enable selecting text of the label */ +# define LV_LABEL_TEXT_SEL 0 + +/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/ +# define LV_LABEL_LONG_TXT_HINT 0 +#endif + +/*LED (dependencies: -)*/ +#define LV_USE_LED 1 +#if LV_USE_LED +# define LV_LED_BRIGHT_MIN 120 /*Minimal brightness*/ +# define LV_LED_BRIGHT_MAX 255 /*Maximal brightness*/ +#endif + +/*Line (dependencies: -*/ +#define LV_USE_LINE 1 + +/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/ +#define LV_USE_LIST 1 +#if LV_USE_LIST != 0 +/*Default animation time of focusing to a list element [ms] (0: no animation) */ +# define LV_LIST_DEF_ANIM_TIME 100 +#endif + +/*Line meter (dependencies: *;)*/ +#define LV_USE_LINEMETER 1 +#if LV_USE_LINEMETER +/* Draw line more precisely at cost of performance. + * Useful if there are lot of lines any minor are visible + * 0: No extra precision + * 1: Some extra precision + * 2: Best precision + */ +# define LV_LINEMETER_PRECISE 1 +#endif + +/*Mask (dependencies: -)*/ +#define LV_USE_OBJMASK 1 + +/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ +#define LV_USE_MSGBOX 1 + +/*Page (dependencies: lv_cont)*/ +#define LV_USE_PAGE 1 +#if LV_USE_PAGE != 0 +/*Focus default animation time [ms] (0: no animation)*/ +# define LV_PAGE_DEF_ANIM_TIME 400 +#endif + +/*Preload (dependencies: lv_arc, lv_anim)*/ +#define LV_USE_SPINNER 1 +#if LV_USE_SPINNER != 0 +# define LV_SPINNER_DEF_ARC_LENGTH 60 /*[deg]*/ +# define LV_SPINNER_DEF_SPIN_TIME 1000 /*[ms]*/ +# define LV_SPINNER_DEF_ANIM LV_SPINNER_TYPE_SPINNING_ARC +#endif + +/*Roller (dependencies: lv_ddlist)*/ +#define LV_USE_ROLLER 1 +#if LV_USE_ROLLER != 0 +/*Focus animation time [ms] (0: no animation)*/ +# define LV_ROLLER_DEF_ANIM_TIME 200 + +/*Number of extra "pages" when the roller is infinite*/ +# define LV_ROLLER_INF_PAGES 7 +#endif + +/*Slider (dependencies: lv_bar)*/ +#define LV_USE_SLIDER 1 + +/*Spinbox (dependencies: lv_ta)*/ +#define LV_USE_SPINBOX 1 + +/*Switch (dependencies: lv_slider)*/ +#define LV_USE_SWITCH 1 + +/*Text area (dependencies: lv_label, lv_page)*/ +#define LV_USE_TEXTAREA 1 +#if LV_USE_TEXTAREA != 0 +# define LV_TEXTAREA_DEF_CURSOR_BLINK_TIME 400 /*ms*/ +# define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ +#endif + +/*Table (dependencies: lv_label)*/ +#define LV_USE_TABLE 1 +#if LV_USE_TABLE +# define LV_TABLE_COL_MAX 12 +# define LV_TABLE_CELL_STYLE_CNT 4 +#endif + +/*Tab (dependencies: lv_page, lv_btnm)*/ +#define LV_USE_TABVIEW 1 +# if LV_USE_TABVIEW != 0 +/*Time of slide animation [ms] (0: no animation)*/ +# define LV_TABVIEW_DEF_ANIM_TIME 300 +#endif + +/*Tileview (dependencies: lv_page) */ +#define LV_USE_TILEVIEW 1 +#if LV_USE_TILEVIEW +/*Time of slide animation [ms] (0: no animation)*/ +# define LV_TILEVIEW_DEF_ANIM_TIME 300 +#endif + +/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ +#define LV_USE_WIN 1 + +/*================== + * Non-user section + *==================*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/ +# define _CRT_SECURE_NO_WARNINGS +#endif + +/*--END OF LV_CONF_H--*/ + +#endif /*LV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/test/include/liblvgl/lv_conf.old.h b/test/include/liblvgl/lv_conf.old.h new file mode 100644 index 00000000..16deedde --- /dev/null +++ b/test/include/liblvgl/lv_conf.old.h @@ -0,0 +1,341 @@ +/** + * @file lv_conf.h + * + */ + +#ifndef LV_CONF_H +#define LV_CONF_H + +/*---------------- + * Dynamic memory + *----------------*/ + +/* Memory size which will be used by the library + * to store the graphical objects and other data */ +#define LV_MEM_CUSTOM \ + 0 /*1: use custom malloc/free, 0: use the built-in \ + lv_mem_alloc/lv_mem_free*/ +#if LV_MEM_CUSTOM == 0 +#define LV_MEM_SIZE \ + (32U * 1024U) /*Size memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ +#define LV_MEM_ATTR /*Complier prefix for big array declaration*/ +#define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ +#else /*LV_MEM_CUSTOM*/ +#define LV_MEM_CUSTOM_INCLUDE \ + /*Header for the dynamic memory function*/ +#define LV_MEM_CUSTOM_ALLOC kmalloc /*Wrapper to malloc*/ +#define LV_MEM_CUSTOM_FREE kfree /*Wrapper to free*/ +#endif /*LV_MEM_CUSTOM*/ +#define LV_ENABLE_GC 0 + +/*=================== + Graphical settings + *===================*/ + +/* Horizontal and vertical resolution of the library.*/ +#define LV_HOR_RES (480) +#define LV_VER_RES (240) +#define LV_DPI 126 + +/* Size of VDB (Virtual Display Buffer: the internal graphics buffer). + * Required for buffered drawing, opacity and anti-aliasing + * VDB makes the double buffering, you don't need to deal with it! + * Typical size: ~1/10 screen */ +#define LV_VDB_SIZE \ + (LV_VER_RES * \ + LV_HOR_RES) /*Size of VDB in pixel count (1/10 screen size is good for \ + first)*/ +#define LV_VDB_ADR \ + 0 /*Place VDB to a specific address (e.g. in external RAM) (0: allocate \ + automatically into RAM)*/ + +/* Use two Virtual Display buffers (VDB) parallelize rendering and flushing + * (optional) + * The flushing should use DMA to write the frame buffer in the background*/ +#define LV_VDB_DOUBLE 0 /*1: Enable the use of 2 VDBs*/ +#define LV_VDB2_ADR \ + 0 /*Place VDB2 to a specific address (e.g. in external RAM) (0: allocate \ + automatically into RAM)*/ + +/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ +#define LV_ANTIALIAS 1 /*1: Enable anti-aliasing*/ + +/*Screen refresh settings*/ +#define LV_REFR_PERIOD 40 /*Screen refresh period in milliseconds*/ +#define LV_INV_FIFO_SIZE 32 /*The average count of objects on a screen */ + +/*================= + Misc. setting + *=================*/ + +/*Input device settings*/ +#define LV_INDEV_READ_PERIOD 50 /*Input device read period in milliseconds*/ +#define LV_INDEV_POINT_MARKER \ + 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/ +#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */ +#define LV_INDEV_DRAG_THROW \ + 20 /*Drag throw slow-down in [%]. Greater value means faster slow-down */ +#define LV_INDEV_LONG_PRESS_TIME 400 /*Long press time in milliseconds*/ +#define LV_INDEV_LONG_PRESS_REP_TIME \ + 100 /*Repeated trigger period in long press [ms] */ + +/*Color settings*/ +#define LV_COLOR_DEPTH 32 /*Color depth: 1/8/16/24*/ +#define LV_COLOR_TRANSP \ + LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma \ + keying)*/ + +/*Text settings*/ +#define LV_TXT_UTF8 1 /*Enable UTF-8 coded Unicode character usage */ +#define LV_TXT_BREAK_CHARS " ,.;:-_" /*Can break texts on these chars*/ +#define LV_TXT_LINE_BREAK_LONG_LEN 12 +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 1 + +/*Graphics feature usage*/ +#define USE_LV_ANIMATION 1 /*1: Enable all animations*/ +#define USE_LV_SHADOW 1 /*1: Enable shadows*/ +#define USE_LV_GROUP 1 /*1: Enable object groups (for keyboards)*/ +#define USE_LV_GPU 0 /*1: Enable GPU interface*/ +#define USE_LV_REAL_DRAW \ + 1 /*1: Enable function which draw directly to the frame buffer instead of \ + VDB (required if LV_VDB_SIZE = 0)*/ +#define USE_LV_FILESYSTEM 1 /*1: Enable file system (required by images*/ +#define USE_LV_MULTI_LANG 1 + +/*Compiler attributes*/ +#define LV_ATTRIBUTE_TICK_INC /* Define a custom attribute to tick increment \ + function */ +#define LV_ATTRIBUTE_TASK_HANDLER +#define LV_ATTRIBUTE_MEM_ALIGN +#define LV_COMPILER_VLA_SUPPORTED 1 +#define LV_COMPILER_NON_CONST_INIT_SUPPORTED 1 + +#define USE_LV_LOG 0 +/*================ + * THEME USAGE + *================*/ +#define LV_THEME_LIVE_UPDATE 1 +#define USE_LV_THEME_TEMPL 0 /*Just for test*/ +#define USE_LV_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/ +#define USE_LV_THEME_ALIEN 1 /*Dark futuristic theme*/ +#define USE_LV_THEME_NIGHT 1 /*Dark elegant theme*/ +#define USE_LV_THEME_MONO 1 /*Mono color theme for monochrome displays*/ +#define USE_LV_THEME_MATERIAL 1 /*Flat theme with bold colors and light shadows*/ +#define USE_LV_THEME_ZEN 1 /*Peaceful, mainly light theme */ + +/*================== + * FONT USAGE + *===================*/ + +/* More info about fonts: https://littlevgl.com/basics#fonts + * To enable a built-in font use 1,2,4 or 8 values + * which will determine the bit-per-pixel */ +#define LV_FONT_DEFAULT \ + &lv_font_dejavu_20 /*Always set a default font from the built-in fonts*/ + +#define USE_LV_FONT_DEJAVU_10 4 +#define USE_LV_FONT_DEJAVU_10_LATIN_SUP 4 +#define USE_LV_FONT_DEJAVU_10_CYRILLIC 4 +#define USE_LV_FONT_SYMBOL_10 4 + +#define USE_LV_FONT_DEJAVU_20 4 +#define USE_LV_FONT_DEJAVU_20_LATIN_SUP 4 +#define USE_LV_FONT_DEJAVU_20_CYRILLIC 4 +#define USE_LV_FONT_SYMBOL_20 4 + +#define USE_LV_FONT_DEJAVU_30 0 +#define USE_LV_FONT_DEJAVU_30_LATIN_SUP 0 +#define USE_LV_FONT_DEJAVU_30_CYRILLIC 0 +#define USE_LV_FONT_SYMBOL_30 0 + +#define USE_LV_FONT_DEJAVU_40 0 +#define USE_LV_FONT_DEJAVU_40_LATIN_SUP 0 +#define USE_LV_FONT_DEJAVU_40_CYRILLIC 0 +#define USE_LV_FONT_SYMBOL_40 0 + +/* PROS adds the mono variant of DejaVu sans */ +#define USE_PROS_FONT_DEJAVU_MONO_10 4 +#define USE_PROS_FONT_DEJAVU_MONO_10_LATIN_SUP 4 + +#define USE_PROS_FONT_DEJAVU_MONO_20 4 +#define USE_PROS_FONT_DEJAVU_MONO_LATIN_SUP_20 4 + +#define USE_PROS_FONT_DEJAVU_MONO_30 0 +#define USE_PROS_FONT_DEJAVU_MONO_30_LATIN_SUP 0 + +#define USE_PROS_FONT_DEJAVU_MONO_40 0 +#define USE_PROS_FONT_DEJAVU_MONO_40_LATIN_SUP 0 + +/*=================== + * LV_OBJ SETTINGS + *==================*/ +#define LV_OBJ_FREE_NUM_TYPE \ + uint32_t /*Type of free number attribute (comment out disable free number)*/ +#define LV_OBJ_FREE_PTR 1 /*Enable the free pointer attribute*/ + +/*================== + * LV OBJ X USAGE + *================*/ +/* + * Documentation of the object types: https://littlevgl.com/object-types + */ + +/***************** + * Simple object + *****************/ + +/*Label (dependencies: -*/ +#define USE_LV_LABEL 1 +#if USE_LV_LABEL != 0 +#define LV_LABEL_SCROLL_SPEED \ + 25 /*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_SCROLL/ROLL' \ + mode*/ +#endif + +/*Image (dependencies: lv_label*/ +#define USE_LV_IMG 1 +#if USE_LV_IMG != 0 +# define LV_IMG_CF_INDEXED 1 +# define LV_IMG_CF_ALPHA 1 +#endif + +/*Line (dependencies: -*/ +#define USE_LV_LINE 1 +#define USE_LV_ARC 1 + +/******************* + * Container objects + *******************/ + +/*Container (dependencies: -*/ +#define USE_LV_CONT 1 + +/*Page (dependencies: lv_cont)*/ +#define USE_LV_PAGE 1 + +/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ +#define USE_LV_WIN 1 + +/*Tab (dependencies: lv_page, lv_btnm)*/ +#define USE_LV_TABVIEW 1 +#if USE_LV_TABVIEW != 0 +#define LV_TABVIEW_ANIM_TIME \ + 300 /*Time of slide animation [ms] (0: no animation)*/ +#endif +#define USE_LV_TILEVIEW 1 +#if USE_LV_TILEVIEW +# define LV_TILEVIEW_ANIM_TIME 300 +#endif + + +/************************* + * Data visualizer objects + *************************/ + +/*Bar (dependencies: -)*/ +#define USE_LV_BAR 1 + +/*Line meter (dependencies: *;)*/ +#define USE_LV_LMETER 1 + +/*Gauge (dependencies:bar, lmeter)*/ +#define USE_LV_GAUGE 1 + +/*Chart (dependencies: -)*/ +#define USE_LV_CHART 1 + +#define USE_LV_TABLE 1 +#if USE_LV_TABLE +# define LV_TABLE_COL_MAX 12 +#endif + +/*LED (dependencies: -)*/ +#define USE_LV_LED 1 + +/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ +#define USE_LV_MBOX 1 + +/*Text area (dependencies: lv_label, lv_page)*/ +#define USE_LV_TA 1 +#if USE_LV_TA != 0 +#define LV_TA_CURSOR_BLINK_TIME 400 /*ms*/ +#define LV_TA_PWD_SHOW_TIME 1500 /*ms*/ +#endif + +#define USE_LV_SPINBOX 1 +#define USE_LV_CALENDAR 1 + +#define USE_PRELOAD 1 +#if USE_LV_PRELOAD != 0 +# define LV_PRELOAD_DEF_ARC_LENGTH 60 +# define LV_PRELOAD_DEF_SPIN_TIME 1000 +# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC +#endif + +#define USE_LV_CANVAS 1 +/************************* + * User input objects + *************************/ + +/*Button (dependencies: lv_cont*/ +#define USE_LV_BTN 1 +#if USE_LV_BTN != 0 +# define LV_BTN_INK_EFFECT 1 +#endif + +#define USE_LV_IMGBTN 1 +#if USE_LV_IMGBTN +# define LV_IMGBTN_TILED 0 +#endif + +/*Button matrix (dependencies: -)*/ +#define USE_LV_BTNM 1 + +/*Keyboard (dependencies: lv_btnm)*/ +#define USE_LV_KB 1 + +/*Check box (dependencies: lv_btn, lv_label)*/ +#define USE_LV_CB 1 + +/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons + * ))*/ +#define USE_LV_LIST 1 +#if USE_LV_LIST != 0 +#define LV_LIST_FOCUS_TIME \ + 100 /*Default animation time of focusing to a list element [ms] (0: no \ + animation) */ +#endif + +/*Drop down list (dependencies: lv_page, lv_label)*/ +#define USE_LV_DDLIST 1 +#if USE_LV_DDLIST != 0 +#define LV_DDLIST_ANIM_TIME \ + 200 /*Open and close default animation time [ms] (0: no animation)*/ +#endif + +/*Roller (dependencies: lv_ddlist)*/ +#define USE_LV_ROLLER 1 +#if USE_LV_ROLLER != 0 +#define LV_ROLLER_ANIM_TIME \ + 200 /*Focus animation time [ms] (0: no \ + animation)*/ +#endif + +/*Slider (dependencies: lv_bar)*/ +#define USE_LV_SLIDER 1 + +/*Switch (dependencies: lv_slider)*/ +#define USE_LV_SW 1 + +#if LV_INDEV_DRAG_THROW <= 0 +#warning "LV_INDEV_DRAG_THROW must be greater than 0" +#undef LV_INDEV_DRAG_THROW +#define LV_INDEV_DRAG_THROW 1 +#endif + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +# define _CRT_SECURE_NO_WARNINGS +#endif +#include "liblvgl/lv_conf_checker.h" +#endif /*LV_CONF_H*/ diff --git a/test/include/liblvgl/lv_conf_internal.h b/test/include/liblvgl/lv_conf_internal.h new file mode 100644 index 00000000..a8e28b15 --- /dev/null +++ b/test/include/liblvgl/lv_conf_internal.h @@ -0,0 +1,4078 @@ +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_conf_internal.h + * This file ensures all defines of lv_conf.h have a default value. + */ + +#ifndef LV_CONF_INTERNAL_H +#define LV_CONF_INTERNAL_H +/* clang-format off */ + +/* Config options */ +#define LV_OS_NONE 0 +#define LV_OS_PTHREAD 1 +#define LV_OS_FREERTOS 2 +#define LV_OS_CMSIS_RTOS2 3 +#define LV_OS_RTTHREAD 4 +#define LV_OS_WINDOWS 5 +#define LV_OS_MQX 6 +#define LV_OS_CUSTOM 255 + +#define LV_STDLIB_BUILTIN 0 +#define LV_STDLIB_CLIB 1 +#define LV_STDLIB_MICROPYTHON 2 +#define LV_STDLIB_RTTHREAD 3 +#define LV_STDLIB_CUSTOM 255 + +#define LV_DRAW_SW_ASM_NONE 0 +#define LV_DRAW_SW_ASM_NEON 1 +#define LV_DRAW_SW_ASM_HELIUM 2 +#define LV_DRAW_SW_ASM_CUSTOM 255 + +/** Handle special Kconfig options. */ +#ifndef LV_KCONFIG_IGNORE + #include "lv_conf_kconfig.h" + #if defined(CONFIG_LV_CONF_SKIP) && !defined(LV_CONF_SKIP) + #define LV_CONF_SKIP + #endif +#endif + +/* If "lv_conf.h" is available from here try to use it later. */ +#ifdef __has_include + #if __has_include("lv_conf.h") + #ifndef LV_CONF_INCLUDE_SIMPLE + #define LV_CONF_INCLUDE_SIMPLE + #endif + #endif +#endif + +/* If lv_conf.h is not skipped, include it. */ +#if !defined(LV_CONF_SKIP) || defined(LV_CONF_PATH) + #ifdef LV_CONF_PATH /* If there is a path defined for lv_conf.h, use it */ + #define __LV_TO_STR_AUX(x) #x + #define __LV_TO_STR(x) __LV_TO_STR_AUX(x) + #include __LV_TO_STR(LV_CONF_PATH) + #undef __LV_TO_STR_AUX + #undef __LV_TO_STR + #elif defined(LV_CONF_INCLUDE_SIMPLE) /* Or simply include lv_conf.h is enabled. */ + #include "lv_conf.h" + #else + #include "../../lv_conf.h" /* Else assume lv_conf.h is next to the lvgl folder. */ + #endif + #if !defined(LV_CONF_H) && !defined(LV_CONF_SUPPRESS_DEFINE_CHECK) + /* #include will sometimes silently fail when __has_include is used */ + /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80753 */ + #pragma message("Possible failure to include lv_conf.h, please read the comment in this file if you get errors") + #endif +#endif + +#ifdef CONFIG_LV_COLOR_DEPTH + #define LV_KCONFIG_PRESENT +#endif + +/*---------------------------------- + * Start parsing lv_conf_template.h + -----------------------------------*/ + +/* If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ +#if 0 && defined(__ASSEMBLY__) +#include "my_include.h" +#endif + +/*==================== + COLOR SETTINGS + *====================*/ + +/** Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888) */ +#ifndef LV_COLOR_DEPTH + #ifdef CONFIG_LV_COLOR_DEPTH + #define LV_COLOR_DEPTH CONFIG_LV_COLOR_DEPTH + #else + #define LV_COLOR_DEPTH 16 + #endif +#endif + +/*========================= + STDLIB WRAPPER SETTINGS + *=========================*/ + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +#ifndef LV_USE_STDLIB_MALLOC + #ifdef CONFIG_LV_USE_STDLIB_MALLOC + #define LV_USE_STDLIB_MALLOC CONFIG_LV_USE_STDLIB_MALLOC + #else + #define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN + #endif +#endif + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +#ifndef LV_USE_STDLIB_STRING + #ifdef CONFIG_LV_USE_STDLIB_STRING + #define LV_USE_STDLIB_STRING CONFIG_LV_USE_STDLIB_STRING + #else + #define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN + #endif +#endif + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +#ifndef LV_USE_STDLIB_SPRINTF + #ifdef CONFIG_LV_USE_STDLIB_SPRINTF + #define LV_USE_STDLIB_SPRINTF CONFIG_LV_USE_STDLIB_SPRINTF + #else + #define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN + #endif +#endif + +#ifndef LV_STDINT_INCLUDE + #ifdef CONFIG_LV_STDINT_INCLUDE + #define LV_STDINT_INCLUDE CONFIG_LV_STDINT_INCLUDE + #else + #define LV_STDINT_INCLUDE + #endif +#endif +#ifndef LV_STDDEF_INCLUDE + #ifdef CONFIG_LV_STDDEF_INCLUDE + #define LV_STDDEF_INCLUDE CONFIG_LV_STDDEF_INCLUDE + #else + #define LV_STDDEF_INCLUDE + #endif +#endif +#ifndef LV_STDBOOL_INCLUDE + #ifdef CONFIG_LV_STDBOOL_INCLUDE + #define LV_STDBOOL_INCLUDE CONFIG_LV_STDBOOL_INCLUDE + #else + #define LV_STDBOOL_INCLUDE + #endif +#endif +#ifndef LV_INTTYPES_INCLUDE + #ifdef CONFIG_LV_INTTYPES_INCLUDE + #define LV_INTTYPES_INCLUDE CONFIG_LV_INTTYPES_INCLUDE + #else + #define LV_INTTYPES_INCLUDE + #endif +#endif +#ifndef LV_LIMITS_INCLUDE + #ifdef CONFIG_LV_LIMITS_INCLUDE + #define LV_LIMITS_INCLUDE CONFIG_LV_LIMITS_INCLUDE + #else + #define LV_LIMITS_INCLUDE + #endif +#endif +#ifndef LV_STDARG_INCLUDE + #ifdef CONFIG_LV_STDARG_INCLUDE + #define LV_STDARG_INCLUDE CONFIG_LV_STDARG_INCLUDE + #else + #define LV_STDARG_INCLUDE + #endif +#endif + +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN + /** Size of memory available for `lv_malloc()` in bytes (>= 2kB) */ + #ifndef LV_MEM_SIZE + #ifdef CONFIG_LV_MEM_SIZE + #define LV_MEM_SIZE CONFIG_LV_MEM_SIZE + #else + #define LV_MEM_SIZE (64 * 1024U) /**< [bytes] */ + #endif + #endif + + /** Size of the memory expand for `lv_malloc()` in bytes */ + #ifndef LV_MEM_POOL_EXPAND_SIZE + #ifdef CONFIG_LV_MEM_POOL_EXPAND_SIZE + #define LV_MEM_POOL_EXPAND_SIZE CONFIG_LV_MEM_POOL_EXPAND_SIZE + #else + #define LV_MEM_POOL_EXPAND_SIZE 0 + #endif + #endif + + /** Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too. */ + #ifndef LV_MEM_ADR + #ifdef CONFIG_LV_MEM_ADR + #define LV_MEM_ADR CONFIG_LV_MEM_ADR + #else + #define LV_MEM_ADR 0 /**< 0: unused*/ + #endif + #endif + /* Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc */ + #if LV_MEM_ADR == 0 + #ifndef LV_MEM_POOL_INCLUDE + #ifdef CONFIG_LV_MEM_POOL_INCLUDE + #define LV_MEM_POOL_INCLUDE CONFIG_LV_MEM_POOL_INCLUDE + #else + #undef LV_MEM_POOL_INCLUDE + #endif + #endif + #ifndef LV_MEM_POOL_ALLOC + #ifdef CONFIG_LV_MEM_POOL_ALLOC + #define LV_MEM_POOL_ALLOC CONFIG_LV_MEM_POOL_ALLOC + #else + #undef LV_MEM_POOL_ALLOC + #endif + #endif + #endif +#endif /*LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN*/ + +/*==================== + HAL SETTINGS + *====================*/ + +/** Default display refresh, input device read and animation step period. */ +#ifndef LV_DEF_REFR_PERIOD + #ifdef CONFIG_LV_DEF_REFR_PERIOD + #define LV_DEF_REFR_PERIOD CONFIG_LV_DEF_REFR_PERIOD + #else + #define LV_DEF_REFR_PERIOD 33 /**< [ms] */ + #endif +#endif + +/** Default Dots Per Inch. Used to initialize default sizes such as widgets sized, style paddings. + * (Not so important, you can adjust it to modify default sizes and spaces.) */ +#ifndef LV_DPI_DEF + #ifdef CONFIG_LV_DPI_DEF + #define LV_DPI_DEF CONFIG_LV_DPI_DEF + #else + #define LV_DPI_DEF 130 /**< [px/inch] */ + #endif +#endif + +/*================= + * OPERATING SYSTEM + *=================*/ +/** Select operating system to use. Possible options: + * - LV_OS_NONE + * - LV_OS_PTHREAD + * - LV_OS_FREERTOS + * - LV_OS_CMSIS_RTOS2 + * - LV_OS_RTTHREAD + * - LV_OS_WINDOWS + * - LV_OS_MQX + * - LV_OS_CUSTOM */ +#ifndef LV_USE_OS + #ifdef CONFIG_LV_USE_OS + #define LV_USE_OS CONFIG_LV_USE_OS + #else + #define LV_USE_OS LV_OS_NONE + #endif +#endif + +#if LV_USE_OS == LV_OS_CUSTOM + #ifndef LV_OS_CUSTOM_INCLUDE + #ifdef CONFIG_LV_OS_CUSTOM_INCLUDE + #define LV_OS_CUSTOM_INCLUDE CONFIG_LV_OS_CUSTOM_INCLUDE + #else + #define LV_OS_CUSTOM_INCLUDE + #endif + #endif +#endif +#if LV_USE_OS == LV_OS_FREERTOS + /* + * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM + * than unblocking a task using an intermediary object such as a binary semaphore. + * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. + */ + #ifndef LV_USE_FREERTOS_TASK_NOTIFY + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_FREERTOS_TASK_NOTIFY + #define LV_USE_FREERTOS_TASK_NOTIFY CONFIG_LV_USE_FREERTOS_TASK_NOTIFY + #else + #define LV_USE_FREERTOS_TASK_NOTIFY 0 + #endif + #else + #define LV_USE_FREERTOS_TASK_NOTIFY 1 + #endif + #endif +#endif + +/*======================== + * RENDERING CONFIGURATION + *========================*/ + +/** Align stride of all layers and images to this bytes */ +#ifndef LV_DRAW_BUF_STRIDE_ALIGN + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_BUF_STRIDE_ALIGN + #define LV_DRAW_BUF_STRIDE_ALIGN CONFIG_LV_DRAW_BUF_STRIDE_ALIGN + #else + #define LV_DRAW_BUF_STRIDE_ALIGN 0 + #endif + #else + #define LV_DRAW_BUF_STRIDE_ALIGN 1 + #endif +#endif + +/** Align start address of draw_buf addresses to this bytes*/ +#ifndef LV_DRAW_BUF_ALIGN + #ifdef CONFIG_LV_DRAW_BUF_ALIGN + #define LV_DRAW_BUF_ALIGN CONFIG_LV_DRAW_BUF_ALIGN + #else + #define LV_DRAW_BUF_ALIGN 4 + #endif +#endif + +/** Using matrix for transformations. + * Requirements: + * - `LV_USE_MATRIX = 1`. + * - Rendering engine needs to support 3x3 matrix transformations. */ +#ifndef LV_DRAW_TRANSFORM_USE_MATRIX + #ifdef CONFIG_LV_DRAW_TRANSFORM_USE_MATRIX + #define LV_DRAW_TRANSFORM_USE_MATRIX CONFIG_LV_DRAW_TRANSFORM_USE_MATRIX + #else + #define LV_DRAW_TRANSFORM_USE_MATRIX 0 + #endif +#endif + +/* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode + * it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks. + * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers + * and can't be drawn in chunks. */ + +/** The target buffer size for simple layer chunks. */ +#ifndef LV_DRAW_LAYER_SIMPLE_BUF_SIZE + #ifdef CONFIG_LV_DRAW_LAYER_SIMPLE_BUF_SIZE + #define LV_DRAW_LAYER_SIMPLE_BUF_SIZE CONFIG_LV_DRAW_LAYER_SIMPLE_BUF_SIZE + #else + #define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /**< [bytes]*/ + #endif +#endif + +/** Stack size of drawing thread. + * NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more. + */ +#ifndef LV_DRAW_THREAD_STACK_SIZE + #ifdef CONFIG_LV_DRAW_THREAD_STACK_SIZE + #define LV_DRAW_THREAD_STACK_SIZE CONFIG_LV_DRAW_THREAD_STACK_SIZE + #else + #define LV_DRAW_THREAD_STACK_SIZE (8 * 1024) /**< [bytes]*/ + #endif +#endif + +#ifndef LV_USE_DRAW_SW + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_DRAW_SW + #define LV_USE_DRAW_SW CONFIG_LV_USE_DRAW_SW + #else + #define LV_USE_DRAW_SW 0 + #endif + #else + #define LV_USE_DRAW_SW 1 + #endif +#endif +#if LV_USE_DRAW_SW == 1 + /* + * Selectively disable color format support in order to reduce code size. + * NOTE: some features use certain color formats internally, e.g. + * - gradients use RGB888 + * - bitmaps with transparency may use ARGB8888 + */ + #ifndef LV_DRAW_SW_SUPPORT_RGB565 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_RGB565 + #define LV_DRAW_SW_SUPPORT_RGB565 CONFIG_LV_DRAW_SW_SUPPORT_RGB565 + #else + #define LV_DRAW_SW_SUPPORT_RGB565 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_RGB565 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_RGB565A8 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_RGB565A8 + #define LV_DRAW_SW_SUPPORT_RGB565A8 CONFIG_LV_DRAW_SW_SUPPORT_RGB565A8 + #else + #define LV_DRAW_SW_SUPPORT_RGB565A8 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_RGB565A8 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_RGB888 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_RGB888 + #define LV_DRAW_SW_SUPPORT_RGB888 CONFIG_LV_DRAW_SW_SUPPORT_RGB888 + #else + #define LV_DRAW_SW_SUPPORT_RGB888 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_RGB888 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_XRGB8888 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_XRGB8888 + #define LV_DRAW_SW_SUPPORT_XRGB8888 CONFIG_LV_DRAW_SW_SUPPORT_XRGB8888 + #else + #define LV_DRAW_SW_SUPPORT_XRGB8888 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_XRGB8888 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_ARGB8888 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_ARGB8888 + #define LV_DRAW_SW_SUPPORT_ARGB8888 CONFIG_LV_DRAW_SW_SUPPORT_ARGB8888 + #else + #define LV_DRAW_SW_SUPPORT_ARGB8888 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_ARGB8888 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_L8 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_L8 + #define LV_DRAW_SW_SUPPORT_L8 CONFIG_LV_DRAW_SW_SUPPORT_L8 + #else + #define LV_DRAW_SW_SUPPORT_L8 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_L8 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_AL88 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_AL88 + #define LV_DRAW_SW_SUPPORT_AL88 CONFIG_LV_DRAW_SW_SUPPORT_AL88 + #else + #define LV_DRAW_SW_SUPPORT_AL88 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_AL88 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_A8 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_A8 + #define LV_DRAW_SW_SUPPORT_A8 CONFIG_LV_DRAW_SW_SUPPORT_A8 + #else + #define LV_DRAW_SW_SUPPORT_A8 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_A8 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_I1 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_I1 + #define LV_DRAW_SW_SUPPORT_I1 CONFIG_LV_DRAW_SW_SUPPORT_I1 + #else + #define LV_DRAW_SW_SUPPORT_I1 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_I1 1 + #endif + #endif + + /** Set number of draw units. + * - > 1 requires operating system to be enabled in `LV_USE_OS`. + * - > 1 means multiple threads will render the screen in parallel. */ + #ifndef LV_DRAW_SW_DRAW_UNIT_CNT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_DRAW_UNIT_CNT + #define LV_DRAW_SW_DRAW_UNIT_CNT CONFIG_LV_DRAW_SW_DRAW_UNIT_CNT + #else + #define LV_DRAW_SW_DRAW_UNIT_CNT 0 + #endif + #else + #define LV_DRAW_SW_DRAW_UNIT_CNT 1 + #endif + #endif + + /** Use Arm-2D to accelerate software (sw) rendering. */ + #ifndef LV_USE_DRAW_ARM2D_SYNC + #ifdef CONFIG_LV_USE_DRAW_ARM2D_SYNC + #define LV_USE_DRAW_ARM2D_SYNC CONFIG_LV_USE_DRAW_ARM2D_SYNC + #else + #define LV_USE_DRAW_ARM2D_SYNC 0 + #endif + #endif + + /** Enable native helium assembly to be compiled. */ + #ifndef LV_USE_NATIVE_HELIUM_ASM + #ifdef CONFIG_LV_USE_NATIVE_HELIUM_ASM + #define LV_USE_NATIVE_HELIUM_ASM CONFIG_LV_USE_NATIVE_HELIUM_ASM + #else + #define LV_USE_NATIVE_HELIUM_ASM 0 + #endif + #endif + + /** + * - 0: Use a simple renderer capable of drawing only simple rectangles with gradient, images, text, and straight lines only. + * - 1: Use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too. */ + #ifndef LV_DRAW_SW_COMPLEX + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_COMPLEX + #define LV_DRAW_SW_COMPLEX CONFIG_LV_DRAW_SW_COMPLEX + #else + #define LV_DRAW_SW_COMPLEX 0 + #endif + #else + #define LV_DRAW_SW_COMPLEX 1 + #endif + #endif + + #if LV_DRAW_SW_COMPLEX == 1 + /** Allow buffering some shadow calculation. + * LV_DRAW_SW_SHADOW_CACHE_SIZE is the maximum shadow size to buffer, where shadow size is + * `shadow_width + radius`. Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost. */ + #ifndef LV_DRAW_SW_SHADOW_CACHE_SIZE + #ifdef CONFIG_LV_DRAW_SW_SHADOW_CACHE_SIZE + #define LV_DRAW_SW_SHADOW_CACHE_SIZE CONFIG_LV_DRAW_SW_SHADOW_CACHE_SIZE + #else + #define LV_DRAW_SW_SHADOW_CACHE_SIZE 0 + #endif + #endif + + /** Set number of maximally-cached circle data. + * The circumference of 1/4 circle are saved for anti-aliasing. + * `radius * 4` bytes are used per circle (the most often used radiuses are saved). + * - 0: disables caching */ + #ifndef LV_DRAW_SW_CIRCLE_CACHE_SIZE + #ifdef CONFIG_LV_DRAW_SW_CIRCLE_CACHE_SIZE + #define LV_DRAW_SW_CIRCLE_CACHE_SIZE CONFIG_LV_DRAW_SW_CIRCLE_CACHE_SIZE + #else + #define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4 + #endif + #endif + #endif + + #ifndef LV_USE_DRAW_SW_ASM + #ifdef CONFIG_LV_USE_DRAW_SW_ASM + #define LV_USE_DRAW_SW_ASM CONFIG_LV_USE_DRAW_SW_ASM + #else + #define LV_USE_DRAW_SW_ASM LV_DRAW_SW_ASM_NONE + #endif + #endif + + #if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM + #ifndef LV_DRAW_SW_ASM_CUSTOM_INCLUDE + #ifdef CONFIG_LV_DRAW_SW_ASM_CUSTOM_INCLUDE + #define LV_DRAW_SW_ASM_CUSTOM_INCLUDE CONFIG_LV_DRAW_SW_ASM_CUSTOM_INCLUDE + #else + #define LV_DRAW_SW_ASM_CUSTOM_INCLUDE "" + #endif + #endif + #endif + + /** Enable drawing complex gradients in software: linear at an angle, radial or conical */ + #ifndef LV_USE_DRAW_SW_COMPLEX_GRADIENTS + #ifdef CONFIG_LV_USE_DRAW_SW_COMPLEX_GRADIENTS + #define LV_USE_DRAW_SW_COMPLEX_GRADIENTS CONFIG_LV_USE_DRAW_SW_COMPLEX_GRADIENTS + #else + #define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 0 + #endif + #endif +#endif + +/*Use TSi's aka (Think Silicon) NemaGFX */ +#ifndef LV_USE_NEMA_GFX + #ifdef CONFIG_LV_USE_NEMA_GFX + #define LV_USE_NEMA_GFX CONFIG_LV_USE_NEMA_GFX + #else + #define LV_USE_NEMA_GFX 0 + #endif +#endif + +#if LV_USE_NEMA_GFX + #ifndef LV_NEMA_GFX_HAL_INCLUDE + #ifdef CONFIG_LV_NEMA_GFX_HAL_INCLUDE + #define LV_NEMA_GFX_HAL_INCLUDE CONFIG_LV_NEMA_GFX_HAL_INCLUDE + #else + #define LV_NEMA_GFX_HAL_INCLUDE + #endif + #endif + + /*Enable Vector Graphics Operations. Available only if NemaVG library is present*/ + #ifndef LV_USE_NEMA_VG + #ifdef CONFIG_LV_USE_NEMA_VG + #define LV_USE_NEMA_VG CONFIG_LV_USE_NEMA_VG + #else + #define LV_USE_NEMA_VG 0 + #endif + #endif + + #if LV_USE_NEMA_VG + /*Define application's resolution used for VG related buffer allocation */ + #ifndef LV_NEMA_GFX_MAX_RESX + #ifdef CONFIG_LV_NEMA_GFX_MAX_RESX + #define LV_NEMA_GFX_MAX_RESX CONFIG_LV_NEMA_GFX_MAX_RESX + #else + #define LV_NEMA_GFX_MAX_RESX 800 + #endif + #endif + #ifndef LV_NEMA_GFX_MAX_RESY + #ifdef CONFIG_LV_NEMA_GFX_MAX_RESY + #define LV_NEMA_GFX_MAX_RESY CONFIG_LV_NEMA_GFX_MAX_RESY + #else + #define LV_NEMA_GFX_MAX_RESY 600 + #endif + #endif + #endif +#endif + +/** Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ +#ifndef LV_USE_DRAW_VGLITE + #ifdef CONFIG_LV_USE_DRAW_VGLITE + #define LV_USE_DRAW_VGLITE CONFIG_LV_USE_DRAW_VGLITE + #else + #define LV_USE_DRAW_VGLITE 0 + #endif +#endif + +#if LV_USE_DRAW_VGLITE + /** Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ + #ifndef LV_USE_VGLITE_BLIT_SPLIT + #ifdef CONFIG_LV_USE_VGLITE_BLIT_SPLIT + #define LV_USE_VGLITE_BLIT_SPLIT CONFIG_LV_USE_VGLITE_BLIT_SPLIT + #else + #define LV_USE_VGLITE_BLIT_SPLIT 0 + #endif + #endif + + #if LV_USE_OS + /** Use additional draw thread for VG-Lite processing. */ + #ifndef LV_USE_VGLITE_DRAW_THREAD + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_VGLITE_DRAW_THREAD + #define LV_USE_VGLITE_DRAW_THREAD CONFIG_LV_USE_VGLITE_DRAW_THREAD + #else + #define LV_USE_VGLITE_DRAW_THREAD 0 + #endif + #else + #define LV_USE_VGLITE_DRAW_THREAD 1 + #endif + #endif + + #if LV_USE_VGLITE_DRAW_THREAD + /** Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ + #ifndef LV_USE_VGLITE_DRAW_ASYNC + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_VGLITE_DRAW_ASYNC + #define LV_USE_VGLITE_DRAW_ASYNC CONFIG_LV_USE_VGLITE_DRAW_ASYNC + #else + #define LV_USE_VGLITE_DRAW_ASYNC 0 + #endif + #else + #define LV_USE_VGLITE_DRAW_ASYNC 1 + #endif + #endif + #endif + #endif + + /** Enable VGLite asserts. */ + #ifndef LV_USE_VGLITE_ASSERT + #ifdef CONFIG_LV_USE_VGLITE_ASSERT + #define LV_USE_VGLITE_ASSERT CONFIG_LV_USE_VGLITE_ASSERT + #else + #define LV_USE_VGLITE_ASSERT 0 + #endif + #endif +#endif + +/** Use NXP's PXP on iMX RTxxx platforms. */ +#ifndef LV_USE_PXP + #ifdef CONFIG_LV_USE_PXP + #define LV_USE_PXP CONFIG_LV_USE_PXP + #else + #define LV_USE_PXP 0 + #endif +#endif + +#if LV_USE_PXP + /** Use PXP for drawing.*/ + #ifndef LV_USE_DRAW_PXP + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_DRAW_PXP + #define LV_USE_DRAW_PXP CONFIG_LV_USE_DRAW_PXP + #else + #define LV_USE_DRAW_PXP 0 + #endif + #else + #define LV_USE_DRAW_PXP 1 + #endif + #endif + + /** Use PXP to rotate display.*/ + #ifndef LV_USE_ROTATE_PXP + #ifdef CONFIG_LV_USE_ROTATE_PXP + #define LV_USE_ROTATE_PXP CONFIG_LV_USE_ROTATE_PXP + #else + #define LV_USE_ROTATE_PXP 0 + #endif + #endif + + #if LV_USE_DRAW_PXP && LV_USE_OS + /** Use additional draw thread for PXP processing.*/ + #ifndef LV_USE_PXP_DRAW_THREAD + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_PXP_DRAW_THREAD + #define LV_USE_PXP_DRAW_THREAD CONFIG_LV_USE_PXP_DRAW_THREAD + #else + #define LV_USE_PXP_DRAW_THREAD 0 + #endif + #else + #define LV_USE_PXP_DRAW_THREAD 1 + #endif + #endif + #endif + + /** Enable PXP asserts. */ + #ifndef LV_USE_PXP_ASSERT + #ifdef CONFIG_LV_USE_PXP_ASSERT + #define LV_USE_PXP_ASSERT CONFIG_LV_USE_PXP_ASSERT + #else + #define LV_USE_PXP_ASSERT 0 + #endif + #endif +#endif + +/** Use Renesas Dave2D on RA platforms. */ +#ifndef LV_USE_DRAW_DAVE2D + #ifdef CONFIG_LV_USE_DRAW_DAVE2D + #define LV_USE_DRAW_DAVE2D CONFIG_LV_USE_DRAW_DAVE2D + #else + #define LV_USE_DRAW_DAVE2D 0 + #endif +#endif + +/** Draw using cached SDL textures*/ +#ifndef LV_USE_DRAW_SDL + #ifdef CONFIG_LV_USE_DRAW_SDL + #define LV_USE_DRAW_SDL CONFIG_LV_USE_DRAW_SDL + #else + #define LV_USE_DRAW_SDL 0 + #endif +#endif + +/** Use VG-Lite GPU. */ +#ifndef LV_USE_DRAW_VG_LITE + #ifdef CONFIG_LV_USE_DRAW_VG_LITE + #define LV_USE_DRAW_VG_LITE CONFIG_LV_USE_DRAW_VG_LITE + #else + #define LV_USE_DRAW_VG_LITE 0 + #endif +#endif + +#if LV_USE_DRAW_VG_LITE + /** Enable VG-Lite custom external 'gpu_init()' function */ + #ifndef LV_VG_LITE_USE_GPU_INIT + #ifdef CONFIG_LV_VG_LITE_USE_GPU_INIT + #define LV_VG_LITE_USE_GPU_INIT CONFIG_LV_VG_LITE_USE_GPU_INIT + #else + #define LV_VG_LITE_USE_GPU_INIT 0 + #endif + #endif + + /** Enable VG-Lite assert. */ + #ifndef LV_VG_LITE_USE_ASSERT + #ifdef CONFIG_LV_VG_LITE_USE_ASSERT + #define LV_VG_LITE_USE_ASSERT CONFIG_LV_VG_LITE_USE_ASSERT + #else + #define LV_VG_LITE_USE_ASSERT 0 + #endif + #endif + + /** VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ + #ifndef LV_VG_LITE_FLUSH_MAX_COUNT + #ifdef CONFIG_LV_VG_LITE_FLUSH_MAX_COUNT + #define LV_VG_LITE_FLUSH_MAX_COUNT CONFIG_LV_VG_LITE_FLUSH_MAX_COUNT + #else + #define LV_VG_LITE_FLUSH_MAX_COUNT 8 + #endif + #endif + + /** Enable border to simulate shadow. + * NOTE: which usually improves performance, + * but does not guarantee the same rendering quality as the software. */ + #ifndef LV_VG_LITE_USE_BOX_SHADOW + #ifdef CONFIG_LV_VG_LITE_USE_BOX_SHADOW + #define LV_VG_LITE_USE_BOX_SHADOW CONFIG_LV_VG_LITE_USE_BOX_SHADOW + #else + #define LV_VG_LITE_USE_BOX_SHADOW 0 + #endif + #endif + + /** VG-Lite gradient maximum cache number. + * @note The memory usage of a single gradient image is 4K bytes. */ + #ifndef LV_VG_LITE_GRAD_CACHE_CNT + #ifdef CONFIG_LV_VG_LITE_GRAD_CACHE_CNT + #define LV_VG_LITE_GRAD_CACHE_CNT CONFIG_LV_VG_LITE_GRAD_CACHE_CNT + #else + #define LV_VG_LITE_GRAD_CACHE_CNT 32 + #endif + #endif + + /** VG-Lite stroke maximum cache number. */ + #ifndef LV_VG_LITE_STROKE_CACHE_CNT + #ifdef CONFIG_LV_VG_LITE_STROKE_CACHE_CNT + #define LV_VG_LITE_STROKE_CACHE_CNT CONFIG_LV_VG_LITE_STROKE_CACHE_CNT + #else + #define LV_VG_LITE_STROKE_CACHE_CNT 32 + #endif + #endif +#endif + +/** Accelerate blends, fills, etc. with STM32 DMA2D */ +#ifndef LV_USE_DRAW_DMA2D + #ifdef CONFIG_LV_USE_DRAW_DMA2D + #define LV_USE_DRAW_DMA2D CONFIG_LV_USE_DRAW_DMA2D + #else + #define LV_USE_DRAW_DMA2D 0 + #endif +#endif + +#if LV_USE_DRAW_DMA2D + #ifndef LV_DRAW_DMA2D_HAL_INCLUDE + #ifdef CONFIG_LV_DRAW_DMA2D_HAL_INCLUDE + #define LV_DRAW_DMA2D_HAL_INCLUDE CONFIG_LV_DRAW_DMA2D_HAL_INCLUDE + #else + #define LV_DRAW_DMA2D_HAL_INCLUDE "stm32h7xx_hal.h" + #endif + #endif + + /* if enabled, the user is required to call `lv_draw_dma2d_transfer_complete_interrupt_handler` + * upon receiving the DMA2D global interrupt + */ + #ifndef LV_USE_DRAW_DMA2D_INTERRUPT + #ifdef CONFIG_LV_USE_DRAW_DMA2D_INTERRUPT + #define LV_USE_DRAW_DMA2D_INTERRUPT CONFIG_LV_USE_DRAW_DMA2D_INTERRUPT + #else + #define LV_USE_DRAW_DMA2D_INTERRUPT 0 + #endif + #endif +#endif + +/** Draw using cached OpenGLES textures */ +#ifndef LV_USE_DRAW_OPENGLES + #ifdef CONFIG_LV_USE_DRAW_OPENGLES + #define LV_USE_DRAW_OPENGLES CONFIG_LV_USE_DRAW_OPENGLES + #else + #define LV_USE_DRAW_OPENGLES 0 + #endif +#endif + +/*======================= + * FEATURE CONFIGURATION + *=======================*/ + +/*------------- + * Logging + *-----------*/ + +/** Enable log module */ +#ifndef LV_USE_LOG + #ifdef CONFIG_LV_USE_LOG + #define LV_USE_LOG CONFIG_LV_USE_LOG + #else + #define LV_USE_LOG 0 + #endif +#endif +#if LV_USE_LOG + /** Set value to one of the following levels of logging detail: + * - LV_LOG_LEVEL_TRACE Log detailed information. + * - LV_LOG_LEVEL_INFO Log important events. + * - LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem. + * - LV_LOG_LEVEL_ERROR Log only critical issues, when system may fail. + * - LV_LOG_LEVEL_USER Log only custom log messages added by the user. + * - LV_LOG_LEVEL_NONE Do not log anything. */ + #ifndef LV_LOG_LEVEL + #ifdef CONFIG_LV_LOG_LEVEL + #define LV_LOG_LEVEL CONFIG_LV_LOG_LEVEL + #else + #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + #endif + #endif + + /** - 1: Print log with 'printf'; + * - 0: User needs to register a callback with `lv_log_register_print_cb()`. */ + #ifndef LV_LOG_PRINTF + #ifdef CONFIG_LV_LOG_PRINTF + #define LV_LOG_PRINTF CONFIG_LV_LOG_PRINTF + #else + #define LV_LOG_PRINTF 0 + #endif + #endif + + /** Set callback to print logs. + * E.g `my_print`. The prototype should be `void my_print(lv_log_level_t level, const char * buf)`. + * Can be overwritten by `lv_log_register_print_cb`. */ + //#define LV_LOG_PRINT_CB + + /** - 1: Enable printing timestamp; + * - 0: Disable printing timestamp. */ + #ifndef LV_LOG_USE_TIMESTAMP + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_USE_TIMESTAMP + #define LV_LOG_USE_TIMESTAMP CONFIG_LV_LOG_USE_TIMESTAMP + #else + #define LV_LOG_USE_TIMESTAMP 0 + #endif + #else + #define LV_LOG_USE_TIMESTAMP 1 + #endif + #endif + + /** - 1: Print file and line number of the log; + * - 0: Do not print file and line number of the log. */ + #ifndef LV_LOG_USE_FILE_LINE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_USE_FILE_LINE + #define LV_LOG_USE_FILE_LINE CONFIG_LV_LOG_USE_FILE_LINE + #else + #define LV_LOG_USE_FILE_LINE 0 + #endif + #else + #define LV_LOG_USE_FILE_LINE 1 + #endif + #endif + + /* Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs. */ + #ifndef LV_LOG_TRACE_MEM + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_TRACE_MEM + #define LV_LOG_TRACE_MEM CONFIG_LV_LOG_TRACE_MEM + #else + #define LV_LOG_TRACE_MEM 0 + #endif + #else + #define LV_LOG_TRACE_MEM 1 /**< Enable/disable trace logs in memory operations. */ + #endif + #endif + #ifndef LV_LOG_TRACE_TIMER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_TRACE_TIMER + #define LV_LOG_TRACE_TIMER CONFIG_LV_LOG_TRACE_TIMER + #else + #define LV_LOG_TRACE_TIMER 0 + #endif + #else + #define LV_LOG_TRACE_TIMER 1 /**< Enable/disable trace logs in timer operations. */ + #endif + #endif + #ifndef LV_LOG_TRACE_INDEV + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_TRACE_INDEV + #define LV_LOG_TRACE_INDEV CONFIG_LV_LOG_TRACE_INDEV + #else + #define LV_LOG_TRACE_INDEV 0 + #endif + #else + #define LV_LOG_TRACE_INDEV 1 /**< Enable/disable trace logs in input device operations. */ + #endif + #endif + #ifndef LV_LOG_TRACE_DISP_REFR + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_TRACE_DISP_REFR + #define LV_LOG_TRACE_DISP_REFR CONFIG_LV_LOG_TRACE_DISP_REFR + #else + #define LV_LOG_TRACE_DISP_REFR 0 + #endif + #else + #define LV_LOG_TRACE_DISP_REFR 1 /**< Enable/disable trace logs in display re-draw operations. */ + #endif + #endif + #ifndef LV_LOG_TRACE_EVENT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_TRACE_EVENT + #define LV_LOG_TRACE_EVENT CONFIG_LV_LOG_TRACE_EVENT + #else + #define LV_LOG_TRACE_EVENT 0 + #endif + #else + #define LV_LOG_TRACE_EVENT 1 /**< Enable/disable trace logs in event dispatch logic. */ + #endif + #endif + #ifndef LV_LOG_TRACE_OBJ_CREATE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_TRACE_OBJ_CREATE + #define LV_LOG_TRACE_OBJ_CREATE CONFIG_LV_LOG_TRACE_OBJ_CREATE + #else + #define LV_LOG_TRACE_OBJ_CREATE 0 + #endif + #else + #define LV_LOG_TRACE_OBJ_CREATE 1 /**< Enable/disable trace logs in object creation (core `obj` creation plus every widget). */ + #endif + #endif + #ifndef LV_LOG_TRACE_LAYOUT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_TRACE_LAYOUT + #define LV_LOG_TRACE_LAYOUT CONFIG_LV_LOG_TRACE_LAYOUT + #else + #define LV_LOG_TRACE_LAYOUT 0 + #endif + #else + #define LV_LOG_TRACE_LAYOUT 1 /**< Enable/disable trace logs in flex- and grid-layout operations. */ + #endif + #endif + #ifndef LV_LOG_TRACE_ANIM + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_TRACE_ANIM + #define LV_LOG_TRACE_ANIM CONFIG_LV_LOG_TRACE_ANIM + #else + #define LV_LOG_TRACE_ANIM 0 + #endif + #else + #define LV_LOG_TRACE_ANIM 1 /**< Enable/disable trace logs in animation logic. */ + #endif + #endif + #ifndef LV_LOG_TRACE_CACHE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LOG_TRACE_CACHE + #define LV_LOG_TRACE_CACHE CONFIG_LV_LOG_TRACE_CACHE + #else + #define LV_LOG_TRACE_CACHE 0 + #endif + #else + #define LV_LOG_TRACE_CACHE 1 /**< Enable/disable trace logs in cache operations. */ + #endif + #endif +#endif /*LV_USE_LOG*/ + +/*------------- + * Asserts + *-----------*/ + +/* Enable assertion failures if an operation fails or invalid data is found. + * If LV_USE_LOG is enabled, an error message will be printed on failure. */ +#ifndef LV_USE_ASSERT_NULL + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_ASSERT_NULL + #define LV_USE_ASSERT_NULL CONFIG_LV_USE_ASSERT_NULL + #else + #define LV_USE_ASSERT_NULL 0 + #endif + #else + #define LV_USE_ASSERT_NULL 1 /**< Check if the parameter is NULL. (Very fast, recommended) */ + #endif +#endif +#ifndef LV_USE_ASSERT_MALLOC + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_ASSERT_MALLOC + #define LV_USE_ASSERT_MALLOC CONFIG_LV_USE_ASSERT_MALLOC + #else + #define LV_USE_ASSERT_MALLOC 0 + #endif + #else + #define LV_USE_ASSERT_MALLOC 1 /**< Checks is the memory is successfully allocated or no. (Very fast, recommended) */ + #endif +#endif +#ifndef LV_USE_ASSERT_STYLE + #ifdef CONFIG_LV_USE_ASSERT_STYLE + #define LV_USE_ASSERT_STYLE CONFIG_LV_USE_ASSERT_STYLE + #else + #define LV_USE_ASSERT_STYLE 0 /**< Check if the styles are properly initialized. (Very fast, recommended) */ + #endif +#endif +#ifndef LV_USE_ASSERT_MEM_INTEGRITY + #ifdef CONFIG_LV_USE_ASSERT_MEM_INTEGRITY + #define LV_USE_ASSERT_MEM_INTEGRITY CONFIG_LV_USE_ASSERT_MEM_INTEGRITY + #else + #define LV_USE_ASSERT_MEM_INTEGRITY 0 /**< Check the integrity of `lv_mem` after critical operations. (Slow) */ + #endif +#endif +#ifndef LV_USE_ASSERT_OBJ + #ifdef CONFIG_LV_USE_ASSERT_OBJ + #define LV_USE_ASSERT_OBJ CONFIG_LV_USE_ASSERT_OBJ + #else + #define LV_USE_ASSERT_OBJ 0 /**< Check the object's type and existence (e.g. not deleted). (Slow) */ + #endif +#endif + +/** Add a custom handler when assert happens e.g. to restart MCU. */ +#ifndef LV_ASSERT_HANDLER_INCLUDE + #ifdef CONFIG_LV_ASSERT_HANDLER_INCLUDE + #define LV_ASSERT_HANDLER_INCLUDE CONFIG_LV_ASSERT_HANDLER_INCLUDE + #else + #define LV_ASSERT_HANDLER_INCLUDE + #endif +#endif +#ifndef LV_ASSERT_HANDLER + #ifdef CONFIG_LV_ASSERT_HANDLER + #define LV_ASSERT_HANDLER CONFIG_LV_ASSERT_HANDLER + #else + #define LV_ASSERT_HANDLER while(1); /**< Halt by default */ + #endif +#endif + +/*------------- + * Debug + *-----------*/ + +/** 1: Draw random colored rectangles over the redrawn areas. */ +#ifndef LV_USE_REFR_DEBUG + #ifdef CONFIG_LV_USE_REFR_DEBUG + #define LV_USE_REFR_DEBUG CONFIG_LV_USE_REFR_DEBUG + #else + #define LV_USE_REFR_DEBUG 0 + #endif +#endif + +/** 1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ +#ifndef LV_USE_LAYER_DEBUG + #ifdef CONFIG_LV_USE_LAYER_DEBUG + #define LV_USE_LAYER_DEBUG CONFIG_LV_USE_LAYER_DEBUG + #else + #define LV_USE_LAYER_DEBUG 0 + #endif +#endif + +/** 1: Adds the following behaviors for debugging: + * - Draw overlays with different colors for each draw_unit's tasks. + * - Draw index number of draw unit on white background. + * - For layers, draws index number of draw unit on black background. */ +#ifndef LV_USE_PARALLEL_DRAW_DEBUG + #ifdef CONFIG_LV_USE_PARALLEL_DRAW_DEBUG + #define LV_USE_PARALLEL_DRAW_DEBUG CONFIG_LV_USE_PARALLEL_DRAW_DEBUG + #else + #define LV_USE_PARALLEL_DRAW_DEBUG 0 + #endif +#endif + +/*------------- + * Others + *-----------*/ + +#ifndef LV_ENABLE_GLOBAL_CUSTOM + #ifdef CONFIG_LV_ENABLE_GLOBAL_CUSTOM + #define LV_ENABLE_GLOBAL_CUSTOM CONFIG_LV_ENABLE_GLOBAL_CUSTOM + #else + #define LV_ENABLE_GLOBAL_CUSTOM 0 + #endif +#endif +#if LV_ENABLE_GLOBAL_CUSTOM + /** Header to include for custom 'lv_global' function" */ + #ifndef LV_GLOBAL_CUSTOM_INCLUDE + #ifdef CONFIG_LV_GLOBAL_CUSTOM_INCLUDE + #define LV_GLOBAL_CUSTOM_INCLUDE CONFIG_LV_GLOBAL_CUSTOM_INCLUDE + #else + #define LV_GLOBAL_CUSTOM_INCLUDE + #endif + #endif +#endif + +/** Default cache size in bytes. + * Used by image decoders such as `lv_lodepng` to keep the decoded image in memory. + * If size is not set to 0, the decoder will fail to decode when the cache is full. + * If size is 0, the cache function is not enabled and the decoded memory will be + * released immediately after use. */ +#ifndef LV_CACHE_DEF_SIZE + #ifdef CONFIG_LV_CACHE_DEF_SIZE + #define LV_CACHE_DEF_SIZE CONFIG_LV_CACHE_DEF_SIZE + #else + #define LV_CACHE_DEF_SIZE 0 + #endif +#endif + +/** Default number of image header cache entries. The cache is used to store the headers of images + * The main logic is like `LV_CACHE_DEF_SIZE` but for image headers. */ +#ifndef LV_IMAGE_HEADER_CACHE_DEF_CNT + #ifdef CONFIG_LV_IMAGE_HEADER_CACHE_DEF_CNT + #define LV_IMAGE_HEADER_CACHE_DEF_CNT CONFIG_LV_IMAGE_HEADER_CACHE_DEF_CNT + #else + #define LV_IMAGE_HEADER_CACHE_DEF_CNT 0 + #endif +#endif + +/** Number of stops allowed per gradient. Increase this to allow more stops. + * This adds (sizeof(lv_color_t) + 1) bytes per additional stop. */ +#ifndef LV_GRADIENT_MAX_STOPS + #ifdef CONFIG_LV_GRADIENT_MAX_STOPS + #define LV_GRADIENT_MAX_STOPS CONFIG_LV_GRADIENT_MAX_STOPS + #else + #define LV_GRADIENT_MAX_STOPS 2 + #endif +#endif + +/** Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. + * - 0: round down, + * - 64: round up from x.75, + * - 128: round up from half, + * - 192: round up from x.25, + * - 254: round up */ +#ifndef LV_COLOR_MIX_ROUND_OFS + #ifdef CONFIG_LV_COLOR_MIX_ROUND_OFS + #define LV_COLOR_MIX_ROUND_OFS CONFIG_LV_COLOR_MIX_ROUND_OFS + #else + #define LV_COLOR_MIX_ROUND_OFS 0 + #endif +#endif + +/** Add 2 x 32-bit variables to each `lv_obj_t` to speed up getting style properties */ +#ifndef LV_OBJ_STYLE_CACHE + #ifdef CONFIG_LV_OBJ_STYLE_CACHE + #define LV_OBJ_STYLE_CACHE CONFIG_LV_OBJ_STYLE_CACHE + #else + #define LV_OBJ_STYLE_CACHE 0 + #endif +#endif + +/** Add `id` field to `lv_obj_t` */ +#ifndef LV_USE_OBJ_ID + #ifdef CONFIG_LV_USE_OBJ_ID + #define LV_USE_OBJ_ID CONFIG_LV_USE_OBJ_ID + #else + #define LV_USE_OBJ_ID 0 + #endif +#endif + +/** Automatically assign an ID when obj is created */ +#ifndef LV_OBJ_ID_AUTO_ASSIGN + #ifdef CONFIG_LV_OBJ_ID_AUTO_ASSIGN + #define LV_OBJ_ID_AUTO_ASSIGN CONFIG_LV_OBJ_ID_AUTO_ASSIGN + #else + #define LV_OBJ_ID_AUTO_ASSIGN LV_USE_OBJ_ID + #endif +#endif + +/** Use builtin obj ID handler functions: +* - lv_obj_assign_id: Called when a widget is created. Use a separate counter for each widget class as an ID. +* - lv_obj_id_compare: Compare the ID to decide if it matches with a requested value. +* - lv_obj_stringify_id: Return string-ified identifier, e.g. "button3". +* - lv_obj_free_id: Does nothing, as there is no memory allocation for the ID. +* When disabled these functions needs to be implemented by the user.*/ +#ifndef LV_USE_OBJ_ID_BUILTIN + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_OBJ_ID_BUILTIN + #define LV_USE_OBJ_ID_BUILTIN CONFIG_LV_USE_OBJ_ID_BUILTIN + #else + #define LV_USE_OBJ_ID_BUILTIN 0 + #endif + #else + #define LV_USE_OBJ_ID_BUILTIN 1 + #endif +#endif + +/** Use obj property set/get API. */ +#ifndef LV_USE_OBJ_PROPERTY + #ifdef CONFIG_LV_USE_OBJ_PROPERTY + #define LV_USE_OBJ_PROPERTY CONFIG_LV_USE_OBJ_PROPERTY + #else + #define LV_USE_OBJ_PROPERTY 0 + #endif +#endif + +/** Enable property name support. */ +#ifndef LV_USE_OBJ_PROPERTY_NAME + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_OBJ_PROPERTY_NAME + #define LV_USE_OBJ_PROPERTY_NAME CONFIG_LV_USE_OBJ_PROPERTY_NAME + #else + #define LV_USE_OBJ_PROPERTY_NAME 0 + #endif + #else + #define LV_USE_OBJ_PROPERTY_NAME 1 + #endif +#endif + +/* Use VG-Lite Simulator. + * - Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ +#ifndef LV_USE_VG_LITE_THORVG + #ifdef CONFIG_LV_USE_VG_LITE_THORVG + #define LV_USE_VG_LITE_THORVG CONFIG_LV_USE_VG_LITE_THORVG + #else + #define LV_USE_VG_LITE_THORVG 0 + #endif +#endif + +#if LV_USE_VG_LITE_THORVG + /** Enable LVGL's blend mode support */ + #ifndef LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT + #ifdef CONFIG_LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT + #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT CONFIG_LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT + #else + #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 + #endif + #endif + + /** Enable YUV color format support */ + #ifndef LV_VG_LITE_THORVG_YUV_SUPPORT + #ifdef CONFIG_LV_VG_LITE_THORVG_YUV_SUPPORT + #define LV_VG_LITE_THORVG_YUV_SUPPORT CONFIG_LV_VG_LITE_THORVG_YUV_SUPPORT + #else + #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 + #endif + #endif + + /** Enable Linear gradient extension support */ + #ifndef LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + #ifdef CONFIG_LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT CONFIG_LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + #else + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 + #endif + #endif + + /** Enable alignment on 16 pixels */ + #ifndef LV_VG_LITE_THORVG_16PIXELS_ALIGN + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_VG_LITE_THORVG_16PIXELS_ALIGN + #define LV_VG_LITE_THORVG_16PIXELS_ALIGN CONFIG_LV_VG_LITE_THORVG_16PIXELS_ALIGN + #else + #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 0 + #endif + #else + #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 + #endif + #endif + + /** Buffer address alignment */ + #ifndef LV_VG_LITE_THORVG_BUF_ADDR_ALIGN + #ifdef CONFIG_LV_VG_LITE_THORVG_BUF_ADDR_ALIGN + #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN CONFIG_LV_VG_LITE_THORVG_BUF_ADDR_ALIGN + #else + #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 + #endif + #endif + + /** Enable multi-thread render */ + #ifndef LV_VG_LITE_THORVG_THREAD_RENDER + #ifdef CONFIG_LV_VG_LITE_THORVG_THREAD_RENDER + #define LV_VG_LITE_THORVG_THREAD_RENDER CONFIG_LV_VG_LITE_THORVG_THREAD_RENDER + #else + #define LV_VG_LITE_THORVG_THREAD_RENDER 0 + #endif + #endif +#endif + +/*===================== + * COMPILER SETTINGS + *====================*/ + +/** For big endian systems set to 1 */ +#ifndef LV_BIG_ENDIAN_SYSTEM + #ifdef CONFIG_LV_BIG_ENDIAN_SYSTEM + #define LV_BIG_ENDIAN_SYSTEM CONFIG_LV_BIG_ENDIAN_SYSTEM + #else + #define LV_BIG_ENDIAN_SYSTEM 0 + #endif +#endif + +/** Define a custom attribute for `lv_tick_inc` function */ +#ifndef LV_ATTRIBUTE_TICK_INC + #ifdef CONFIG_LV_ATTRIBUTE_TICK_INC + #define LV_ATTRIBUTE_TICK_INC CONFIG_LV_ATTRIBUTE_TICK_INC + #else + #define LV_ATTRIBUTE_TICK_INC + #endif +#endif + +/** Define a custom attribute for `lv_timer_handler` function */ +#ifndef LV_ATTRIBUTE_TIMER_HANDLER + #ifdef CONFIG_LV_ATTRIBUTE_TIMER_HANDLER + #define LV_ATTRIBUTE_TIMER_HANDLER CONFIG_LV_ATTRIBUTE_TIMER_HANDLER + #else + #define LV_ATTRIBUTE_TIMER_HANDLER + #endif +#endif + +/** Define a custom attribute for `lv_display_flush_ready` function */ +#ifndef LV_ATTRIBUTE_FLUSH_READY + #ifdef CONFIG_LV_ATTRIBUTE_FLUSH_READY + #define LV_ATTRIBUTE_FLUSH_READY CONFIG_LV_ATTRIBUTE_FLUSH_READY + #else + #define LV_ATTRIBUTE_FLUSH_READY + #endif +#endif + +/** Align VG_LITE buffers on this number of bytes. + * @note vglite_src_buf_aligned() uses this value to validate alignment of passed buffer pointers. */ +#ifndef LV_ATTRIBUTE_MEM_ALIGN_SIZE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE + #define LV_ATTRIBUTE_MEM_ALIGN_SIZE CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE + #else + #define LV_ATTRIBUTE_MEM_ALIGN_SIZE 0 + #endif + #else + #define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1 + #endif +#endif + +/** Will be added where memory needs to be aligned (with -Os data might not be aligned to boundary by default). + * E.g. __attribute__((aligned(4)))*/ +#ifndef LV_ATTRIBUTE_MEM_ALIGN + #ifdef CONFIG_LV_ATTRIBUTE_MEM_ALIGN + #define LV_ATTRIBUTE_MEM_ALIGN CONFIG_LV_ATTRIBUTE_MEM_ALIGN + #else + #define LV_ATTRIBUTE_MEM_ALIGN + #endif +#endif + +/** Attribute to mark large constant arrays, for example for font bitmaps */ +#ifndef LV_ATTRIBUTE_LARGE_CONST + #ifdef CONFIG_LV_ATTRIBUTE_LARGE_CONST + #define LV_ATTRIBUTE_LARGE_CONST CONFIG_LV_ATTRIBUTE_LARGE_CONST + #else + #define LV_ATTRIBUTE_LARGE_CONST + #endif +#endif + +/** Compiler prefix for a large array declaration in RAM */ +#ifndef LV_ATTRIBUTE_LARGE_RAM_ARRAY + #ifdef CONFIG_LV_ATTRIBUTE_LARGE_RAM_ARRAY + #define LV_ATTRIBUTE_LARGE_RAM_ARRAY CONFIG_LV_ATTRIBUTE_LARGE_RAM_ARRAY + #else + #define LV_ATTRIBUTE_LARGE_RAM_ARRAY + #endif +#endif + +/** Place performance critical functions into a faster memory (e.g RAM) */ +#ifndef LV_ATTRIBUTE_FAST_MEM + #ifdef CONFIG_LV_ATTRIBUTE_FAST_MEM + #define LV_ATTRIBUTE_FAST_MEM CONFIG_LV_ATTRIBUTE_FAST_MEM + #else + #define LV_ATTRIBUTE_FAST_MEM + #endif +#endif + +/** Export integer constant to binding. This macro is used with constants in the form of LV_ that + * should also appear on LVGL binding API such as MicroPython. */ +#ifndef LV_EXPORT_CONST_INT + #ifdef CONFIG_LV_EXPORT_CONST_INT + #define LV_EXPORT_CONST_INT CONFIG_LV_EXPORT_CONST_INT + #else + #define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /**< The default value just prevents GCC warning */ + #endif +#endif + +/** Prefix all global extern data with this */ +#ifndef LV_ATTRIBUTE_EXTERN_DATA + #ifdef CONFIG_LV_ATTRIBUTE_EXTERN_DATA + #define LV_ATTRIBUTE_EXTERN_DATA CONFIG_LV_ATTRIBUTE_EXTERN_DATA + #else + #define LV_ATTRIBUTE_EXTERN_DATA + #endif +#endif + +/** Use `float` as `lv_value_precise_t` */ +#ifndef LV_USE_FLOAT + #ifdef CONFIG_LV_USE_FLOAT + #define LV_USE_FLOAT CONFIG_LV_USE_FLOAT + #else + #define LV_USE_FLOAT 0 + #endif +#endif + +/** Enable matrix support + * - Requires `LV_USE_FLOAT = 1` */ +#ifndef LV_USE_MATRIX + #ifdef CONFIG_LV_USE_MATRIX + #define LV_USE_MATRIX CONFIG_LV_USE_MATRIX + #else + #define LV_USE_MATRIX 0 + #endif +#endif + +/** Include `lvgl_private.h` in `lvgl.h` to access internal data and functions by default */ +#ifndef LV_USE_PRIVATE_API + #ifdef CONFIG_LV_USE_PRIVATE_API + #define LV_USE_PRIVATE_API CONFIG_LV_USE_PRIVATE_API + #else + #define LV_USE_PRIVATE_API 0 + #endif +#endif + +/*================== + * FONT USAGE + *===================*/ + +/* Montserrat fonts with ASCII range and some symbols using bpp = 4 + * https://fonts.google.com/specimen/Montserrat */ +#ifndef LV_FONT_MONTSERRAT_8 + #ifdef CONFIG_LV_FONT_MONTSERRAT_8 + #define LV_FONT_MONTSERRAT_8 CONFIG_LV_FONT_MONTSERRAT_8 + #else + #define LV_FONT_MONTSERRAT_8 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_10 + #ifdef CONFIG_LV_FONT_MONTSERRAT_10 + #define LV_FONT_MONTSERRAT_10 CONFIG_LV_FONT_MONTSERRAT_10 + #else + #define LV_FONT_MONTSERRAT_10 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_12 + #ifdef CONFIG_LV_FONT_MONTSERRAT_12 + #define LV_FONT_MONTSERRAT_12 CONFIG_LV_FONT_MONTSERRAT_12 + #else + #define LV_FONT_MONTSERRAT_12 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_14 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_FONT_MONTSERRAT_14 + #define LV_FONT_MONTSERRAT_14 CONFIG_LV_FONT_MONTSERRAT_14 + #else + #define LV_FONT_MONTSERRAT_14 0 + #endif + #else + #define LV_FONT_MONTSERRAT_14 1 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_16 + #ifdef CONFIG_LV_FONT_MONTSERRAT_16 + #define LV_FONT_MONTSERRAT_16 CONFIG_LV_FONT_MONTSERRAT_16 + #else + #define LV_FONT_MONTSERRAT_16 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_18 + #ifdef CONFIG_LV_FONT_MONTSERRAT_18 + #define LV_FONT_MONTSERRAT_18 CONFIG_LV_FONT_MONTSERRAT_18 + #else + #define LV_FONT_MONTSERRAT_18 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_20 + #ifdef CONFIG_LV_FONT_MONTSERRAT_20 + #define LV_FONT_MONTSERRAT_20 CONFIG_LV_FONT_MONTSERRAT_20 + #else + #define LV_FONT_MONTSERRAT_20 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_22 + #ifdef CONFIG_LV_FONT_MONTSERRAT_22 + #define LV_FONT_MONTSERRAT_22 CONFIG_LV_FONT_MONTSERRAT_22 + #else + #define LV_FONT_MONTSERRAT_22 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_24 + #ifdef CONFIG_LV_FONT_MONTSERRAT_24 + #define LV_FONT_MONTSERRAT_24 CONFIG_LV_FONT_MONTSERRAT_24 + #else + #define LV_FONT_MONTSERRAT_24 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_26 + #ifdef CONFIG_LV_FONT_MONTSERRAT_26 + #define LV_FONT_MONTSERRAT_26 CONFIG_LV_FONT_MONTSERRAT_26 + #else + #define LV_FONT_MONTSERRAT_26 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_28 + #ifdef CONFIG_LV_FONT_MONTSERRAT_28 + #define LV_FONT_MONTSERRAT_28 CONFIG_LV_FONT_MONTSERRAT_28 + #else + #define LV_FONT_MONTSERRAT_28 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_30 + #ifdef CONFIG_LV_FONT_MONTSERRAT_30 + #define LV_FONT_MONTSERRAT_30 CONFIG_LV_FONT_MONTSERRAT_30 + #else + #define LV_FONT_MONTSERRAT_30 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_32 + #ifdef CONFIG_LV_FONT_MONTSERRAT_32 + #define LV_FONT_MONTSERRAT_32 CONFIG_LV_FONT_MONTSERRAT_32 + #else + #define LV_FONT_MONTSERRAT_32 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_34 + #ifdef CONFIG_LV_FONT_MONTSERRAT_34 + #define LV_FONT_MONTSERRAT_34 CONFIG_LV_FONT_MONTSERRAT_34 + #else + #define LV_FONT_MONTSERRAT_34 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_36 + #ifdef CONFIG_LV_FONT_MONTSERRAT_36 + #define LV_FONT_MONTSERRAT_36 CONFIG_LV_FONT_MONTSERRAT_36 + #else + #define LV_FONT_MONTSERRAT_36 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_38 + #ifdef CONFIG_LV_FONT_MONTSERRAT_38 + #define LV_FONT_MONTSERRAT_38 CONFIG_LV_FONT_MONTSERRAT_38 + #else + #define LV_FONT_MONTSERRAT_38 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_40 + #ifdef CONFIG_LV_FONT_MONTSERRAT_40 + #define LV_FONT_MONTSERRAT_40 CONFIG_LV_FONT_MONTSERRAT_40 + #else + #define LV_FONT_MONTSERRAT_40 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_42 + #ifdef CONFIG_LV_FONT_MONTSERRAT_42 + #define LV_FONT_MONTSERRAT_42 CONFIG_LV_FONT_MONTSERRAT_42 + #else + #define LV_FONT_MONTSERRAT_42 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_44 + #ifdef CONFIG_LV_FONT_MONTSERRAT_44 + #define LV_FONT_MONTSERRAT_44 CONFIG_LV_FONT_MONTSERRAT_44 + #else + #define LV_FONT_MONTSERRAT_44 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_46 + #ifdef CONFIG_LV_FONT_MONTSERRAT_46 + #define LV_FONT_MONTSERRAT_46 CONFIG_LV_FONT_MONTSERRAT_46 + #else + #define LV_FONT_MONTSERRAT_46 0 + #endif +#endif +#ifndef LV_FONT_MONTSERRAT_48 + #ifdef CONFIG_LV_FONT_MONTSERRAT_48 + #define LV_FONT_MONTSERRAT_48 CONFIG_LV_FONT_MONTSERRAT_48 + #else + #define LV_FONT_MONTSERRAT_48 0 + #endif +#endif + +/* Demonstrate special features */ +#ifndef LV_FONT_MONTSERRAT_28_COMPRESSED + #ifdef CONFIG_LV_FONT_MONTSERRAT_28_COMPRESSED + #define LV_FONT_MONTSERRAT_28_COMPRESSED CONFIG_LV_FONT_MONTSERRAT_28_COMPRESSED + #else + #define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /**< bpp = 3 */ + #endif +#endif +#ifndef LV_FONT_DEJAVU_16_PERSIAN_HEBREW + #ifdef CONFIG_LV_FONT_DEJAVU_16_PERSIAN_HEBREW + #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW CONFIG_LV_FONT_DEJAVU_16_PERSIAN_HEBREW + #else + #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /**< Hebrew, Arabic, Persian letters and all their forms */ + #endif +#endif +#ifndef LV_FONT_SIMSUN_14_CJK + #ifdef CONFIG_LV_FONT_SIMSUN_14_CJK + #define LV_FONT_SIMSUN_14_CJK CONFIG_LV_FONT_SIMSUN_14_CJK + #else + #define LV_FONT_SIMSUN_14_CJK 0 /**< 1000 most common CJK radicals */ + #endif +#endif +#ifndef LV_FONT_SIMSUN_16_CJK + #ifdef CONFIG_LV_FONT_SIMSUN_16_CJK + #define LV_FONT_SIMSUN_16_CJK CONFIG_LV_FONT_SIMSUN_16_CJK + #else + #define LV_FONT_SIMSUN_16_CJK 0 /**< 1000 most common CJK radicals */ + #endif +#endif + +/** Pixel perfect monospaced fonts */ +#ifndef LV_FONT_UNSCII_8 + #ifdef CONFIG_LV_FONT_UNSCII_8 + #define LV_FONT_UNSCII_8 CONFIG_LV_FONT_UNSCII_8 + #else + #define LV_FONT_UNSCII_8 0 + #endif +#endif +#ifndef LV_FONT_UNSCII_16 + #ifdef CONFIG_LV_FONT_UNSCII_16 + #define LV_FONT_UNSCII_16 CONFIG_LV_FONT_UNSCII_16 + #else + #define LV_FONT_UNSCII_16 0 + #endif +#endif + +/** Optionally declare custom fonts here. + * + * You can use any of these fonts as the default font too and they will be available + * globally. Example: + * + * @code + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2) + * @endcode + */ +#ifndef LV_FONT_CUSTOM_DECLARE + #ifdef CONFIG_LV_FONT_CUSTOM_DECLARE + #define LV_FONT_CUSTOM_DECLARE CONFIG_LV_FONT_CUSTOM_DECLARE + #else + #define LV_FONT_CUSTOM_DECLARE + #endif +#endif + +/** Always set a default font */ +#ifndef LV_FONT_DEFAULT + #ifdef CONFIG_LV_FONT_DEFAULT + #define LV_FONT_DEFAULT CONFIG_LV_FONT_DEFAULT + #else + #define LV_FONT_DEFAULT &lv_font_montserrat_14 + #endif +#endif + +/** Enable handling large font and/or fonts with a lot of characters. + * The limit depends on the font size, font face and bpp. + * A compiler error will be triggered if a font needs it. */ +#ifndef LV_FONT_FMT_TXT_LARGE + #ifdef CONFIG_LV_FONT_FMT_TXT_LARGE + #define LV_FONT_FMT_TXT_LARGE CONFIG_LV_FONT_FMT_TXT_LARGE + #else + #define LV_FONT_FMT_TXT_LARGE 0 + #endif +#endif + +/** Enables/disables support for compressed fonts. */ +#ifndef LV_USE_FONT_COMPRESSED + #ifdef CONFIG_LV_USE_FONT_COMPRESSED + #define LV_USE_FONT_COMPRESSED CONFIG_LV_USE_FONT_COMPRESSED + #else + #define LV_USE_FONT_COMPRESSED 0 + #endif +#endif + +/** Enable drawing placeholders when glyph dsc is not found. */ +#ifndef LV_USE_FONT_PLACEHOLDER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_FONT_PLACEHOLDER + #define LV_USE_FONT_PLACEHOLDER CONFIG_LV_USE_FONT_PLACEHOLDER + #else + #define LV_USE_FONT_PLACEHOLDER 0 + #endif + #else + #define LV_USE_FONT_PLACEHOLDER 1 + #endif +#endif + +/*================= + * TEXT SETTINGS + *=================*/ + +/** + * Select a character encoding for strings. + * Your IDE or editor should have the same character encoding. + * - LV_TXT_ENC_UTF8 + * - LV_TXT_ENC_ASCII + */ +#ifndef LV_TXT_ENC + #ifdef CONFIG_LV_TXT_ENC + #define LV_TXT_ENC CONFIG_LV_TXT_ENC + #else + #define LV_TXT_ENC LV_TXT_ENC_UTF8 + #endif +#endif + +/** While rendering text strings, break (wrap) text on these chars. */ +#ifndef LV_TXT_BREAK_CHARS + #ifdef CONFIG_LV_TXT_BREAK_CHARS + #define LV_TXT_BREAK_CHARS CONFIG_LV_TXT_BREAK_CHARS + #else + #define LV_TXT_BREAK_CHARS " ,.;:-_)]}" + #endif +#endif + +/** If a word is at least this long, will break wherever "prettiest". + * To disable, set to a value <= 0. */ +#ifndef LV_TXT_LINE_BREAK_LONG_LEN + #ifdef CONFIG_LV_TXT_LINE_BREAK_LONG_LEN + #define LV_TXT_LINE_BREAK_LONG_LEN CONFIG_LV_TXT_LINE_BREAK_LONG_LEN + #else + #define LV_TXT_LINE_BREAK_LONG_LEN 0 + #endif +#endif + +/** Minimum number of characters in a long word to put on a line before a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN + #ifdef CONFIG_LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN + #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN CONFIG_LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN + #else + #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 + #endif +#endif + +/** Minimum number of characters in a long word to put on a line after a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN + #ifdef CONFIG_LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN + #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN CONFIG_LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN + #else + #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 + #endif +#endif + +/** Support bidirectional text. Allows mixing Left-to-Right and Right-to-Left text. + * The direction will be processed according to the Unicode Bidirectional Algorithm: + * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics */ +#ifndef LV_USE_BIDI + #ifdef CONFIG_LV_USE_BIDI + #define LV_USE_BIDI CONFIG_LV_USE_BIDI + #else + #define LV_USE_BIDI 0 + #endif +#endif +#if LV_USE_BIDI + /*Set the default direction. Supported values: + *`LV_BASE_DIR_LTR` Left-to-Right + *`LV_BASE_DIR_RTL` Right-to-Left + *`LV_BASE_DIR_AUTO` detect text base direction*/ + #ifndef LV_BIDI_BASE_DIR_DEF + #ifdef CONFIG_LV_BIDI_BASE_DIR_DEF + #define LV_BIDI_BASE_DIR_DEF CONFIG_LV_BIDI_BASE_DIR_DEF + #else + #define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO + #endif + #endif +#endif + +/** Enable Arabic/Persian processing + * In these languages characters should be replaced with another form based on their position in the text */ +#ifndef LV_USE_ARABIC_PERSIAN_CHARS + #ifdef CONFIG_LV_USE_ARABIC_PERSIAN_CHARS + #define LV_USE_ARABIC_PERSIAN_CHARS CONFIG_LV_USE_ARABIC_PERSIAN_CHARS + #else + #define LV_USE_ARABIC_PERSIAN_CHARS 0 + #endif +#endif + +/*The control character to use for signaling text recoloring*/ +#ifndef LV_TXT_COLOR_CMD + #ifdef CONFIG_LV_TXT_COLOR_CMD + #define LV_TXT_COLOR_CMD CONFIG_LV_TXT_COLOR_CMD + #else + #define LV_TXT_COLOR_CMD "#" + #endif +#endif + +/*================== + * WIDGETS + *================*/ +/* Documentation for widgets can be found here: https://docs.lvgl.io/latest/en/html/widgets/index.html . */ + +/** 1: Causes these widgets to be given default values at creation time. + * - lv_buttonmatrix_t: Get default maps: {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""}, else map not set. + * - lv_checkbox_t : String label set to "Check box", else set to empty string. + * - lv_dropdown_t : Options set to "Option 1", "Option 2", "Option 3", else no values are set. + * - lv_roller_t : Options set to "Option 1", "Option 2", "Option 3", "Option 4", "Option 5", else no values are set. + * - lv_label_t : Text set to "Text", else empty string. + * */ +#ifndef LV_WIDGETS_HAS_DEFAULT_VALUE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_WIDGETS_HAS_DEFAULT_VALUE + #define LV_WIDGETS_HAS_DEFAULT_VALUE CONFIG_LV_WIDGETS_HAS_DEFAULT_VALUE + #else + #define LV_WIDGETS_HAS_DEFAULT_VALUE 0 + #endif + #else + #define LV_WIDGETS_HAS_DEFAULT_VALUE 1 + #endif +#endif + +#ifndef LV_USE_ANIMIMG + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_ANIMIMG + #define LV_USE_ANIMIMG CONFIG_LV_USE_ANIMIMG + #else + #define LV_USE_ANIMIMG 0 + #endif + #else + #define LV_USE_ANIMIMG 1 + #endif +#endif + +#ifndef LV_USE_ARC + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_ARC + #define LV_USE_ARC CONFIG_LV_USE_ARC + #else + #define LV_USE_ARC 0 + #endif + #else + #define LV_USE_ARC 1 + #endif +#endif + +#ifndef LV_USE_BAR + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_BAR + #define LV_USE_BAR CONFIG_LV_USE_BAR + #else + #define LV_USE_BAR 0 + #endif + #else + #define LV_USE_BAR 1 + #endif +#endif + +#ifndef LV_USE_BUTTON + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_BUTTON + #define LV_USE_BUTTON CONFIG_LV_USE_BUTTON + #else + #define LV_USE_BUTTON 0 + #endif + #else + #define LV_USE_BUTTON 1 + #endif +#endif + +#ifndef LV_USE_BUTTONMATRIX + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_BUTTONMATRIX + #define LV_USE_BUTTONMATRIX CONFIG_LV_USE_BUTTONMATRIX + #else + #define LV_USE_BUTTONMATRIX 0 + #endif + #else + #define LV_USE_BUTTONMATRIX 1 + #endif +#endif + +#ifndef LV_USE_CALENDAR + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_CALENDAR + #define LV_USE_CALENDAR CONFIG_LV_USE_CALENDAR + #else + #define LV_USE_CALENDAR 0 + #endif + #else + #define LV_USE_CALENDAR 1 + #endif +#endif +#if LV_USE_CALENDAR + #ifndef LV_CALENDAR_WEEK_STARTS_MONDAY + #ifdef CONFIG_LV_CALENDAR_WEEK_STARTS_MONDAY + #define LV_CALENDAR_WEEK_STARTS_MONDAY CONFIG_LV_CALENDAR_WEEK_STARTS_MONDAY + #else + #define LV_CALENDAR_WEEK_STARTS_MONDAY 0 + #endif + #endif + #if LV_CALENDAR_WEEK_STARTS_MONDAY + #ifndef LV_CALENDAR_DEFAULT_DAY_NAMES + #ifdef CONFIG_LV_CALENDAR_DEFAULT_DAY_NAMES + #define LV_CALENDAR_DEFAULT_DAY_NAMES CONFIG_LV_CALENDAR_DEFAULT_DAY_NAMES + #else + #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} + #endif + #endif + #else + #ifndef LV_CALENDAR_DEFAULT_DAY_NAMES + #ifdef CONFIG_LV_CALENDAR_DEFAULT_DAY_NAMES + #define LV_CALENDAR_DEFAULT_DAY_NAMES CONFIG_LV_CALENDAR_DEFAULT_DAY_NAMES + #else + #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} + #endif + #endif + #endif + + #ifndef LV_CALENDAR_DEFAULT_MONTH_NAMES + #ifdef CONFIG_LV_CALENDAR_DEFAULT_MONTH_NAMES + #define LV_CALENDAR_DEFAULT_MONTH_NAMES CONFIG_LV_CALENDAR_DEFAULT_MONTH_NAMES + #else + #define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} + #endif + #endif + #ifndef LV_USE_CALENDAR_HEADER_ARROW + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_CALENDAR_HEADER_ARROW + #define LV_USE_CALENDAR_HEADER_ARROW CONFIG_LV_USE_CALENDAR_HEADER_ARROW + #else + #define LV_USE_CALENDAR_HEADER_ARROW 0 + #endif + #else + #define LV_USE_CALENDAR_HEADER_ARROW 1 + #endif + #endif + #ifndef LV_USE_CALENDAR_HEADER_DROPDOWN + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_CALENDAR_HEADER_DROPDOWN + #define LV_USE_CALENDAR_HEADER_DROPDOWN CONFIG_LV_USE_CALENDAR_HEADER_DROPDOWN + #else + #define LV_USE_CALENDAR_HEADER_DROPDOWN 0 + #endif + #else + #define LV_USE_CALENDAR_HEADER_DROPDOWN 1 + #endif + #endif + #ifndef LV_USE_CALENDAR_CHINESE + #ifdef CONFIG_LV_USE_CALENDAR_CHINESE + #define LV_USE_CALENDAR_CHINESE CONFIG_LV_USE_CALENDAR_CHINESE + #else + #define LV_USE_CALENDAR_CHINESE 0 + #endif + #endif +#endif /*LV_USE_CALENDAR*/ + +#ifndef LV_USE_CANVAS + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_CANVAS + #define LV_USE_CANVAS CONFIG_LV_USE_CANVAS + #else + #define LV_USE_CANVAS 0 + #endif + #else + #define LV_USE_CANVAS 1 + #endif +#endif + +#ifndef LV_USE_CHART + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_CHART + #define LV_USE_CHART CONFIG_LV_USE_CHART + #else + #define LV_USE_CHART 0 + #endif + #else + #define LV_USE_CHART 1 + #endif +#endif + +#ifndef LV_USE_CHECKBOX + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_CHECKBOX + #define LV_USE_CHECKBOX CONFIG_LV_USE_CHECKBOX + #else + #define LV_USE_CHECKBOX 0 + #endif + #else + #define LV_USE_CHECKBOX 1 + #endif +#endif + +#ifndef LV_USE_DROPDOWN + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_DROPDOWN + #define LV_USE_DROPDOWN CONFIG_LV_USE_DROPDOWN + #else + #define LV_USE_DROPDOWN 0 + #endif + #else + #define LV_USE_DROPDOWN 1 /**< Requires: lv_label */ + #endif +#endif + +#ifndef LV_USE_IMAGE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_IMAGE + #define LV_USE_IMAGE CONFIG_LV_USE_IMAGE + #else + #define LV_USE_IMAGE 0 + #endif + #else + #define LV_USE_IMAGE 1 /**< Requires: lv_label */ + #endif +#endif + +#ifndef LV_USE_IMAGEBUTTON + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_IMAGEBUTTON + #define LV_USE_IMAGEBUTTON CONFIG_LV_USE_IMAGEBUTTON + #else + #define LV_USE_IMAGEBUTTON 0 + #endif + #else + #define LV_USE_IMAGEBUTTON 1 + #endif +#endif + +#ifndef LV_USE_KEYBOARD + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_KEYBOARD + #define LV_USE_KEYBOARD CONFIG_LV_USE_KEYBOARD + #else + #define LV_USE_KEYBOARD 0 + #endif + #else + #define LV_USE_KEYBOARD 1 + #endif +#endif + +#ifndef LV_USE_LABEL + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_LABEL + #define LV_USE_LABEL CONFIG_LV_USE_LABEL + #else + #define LV_USE_LABEL 0 + #endif + #else + #define LV_USE_LABEL 1 + #endif +#endif +#if LV_USE_LABEL + #ifndef LV_LABEL_TEXT_SELECTION + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LABEL_TEXT_SELECTION + #define LV_LABEL_TEXT_SELECTION CONFIG_LV_LABEL_TEXT_SELECTION + #else + #define LV_LABEL_TEXT_SELECTION 0 + #endif + #else + #define LV_LABEL_TEXT_SELECTION 1 /**< Enable selecting text of the label */ + #endif + #endif + #ifndef LV_LABEL_LONG_TXT_HINT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LABEL_LONG_TXT_HINT + #define LV_LABEL_LONG_TXT_HINT CONFIG_LV_LABEL_LONG_TXT_HINT + #else + #define LV_LABEL_LONG_TXT_HINT 0 + #endif + #else + #define LV_LABEL_LONG_TXT_HINT 1 /**< Store some extra info in labels to speed up drawing of very long text */ + #endif + #endif + #ifndef LV_LABEL_WAIT_CHAR_COUNT + #ifdef CONFIG_LV_LABEL_WAIT_CHAR_COUNT + #define LV_LABEL_WAIT_CHAR_COUNT CONFIG_LV_LABEL_WAIT_CHAR_COUNT + #else + #define LV_LABEL_WAIT_CHAR_COUNT 3 /**< The count of wait chart */ + #endif + #endif +#endif + +#ifndef LV_USE_LED + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_LED + #define LV_USE_LED CONFIG_LV_USE_LED + #else + #define LV_USE_LED 0 + #endif + #else + #define LV_USE_LED 1 + #endif +#endif + +#ifndef LV_USE_LINE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_LINE + #define LV_USE_LINE CONFIG_LV_USE_LINE + #else + #define LV_USE_LINE 0 + #endif + #else + #define LV_USE_LINE 1 + #endif +#endif + +#ifndef LV_USE_LIST + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_LIST + #define LV_USE_LIST CONFIG_LV_USE_LIST + #else + #define LV_USE_LIST 0 + #endif + #else + #define LV_USE_LIST 1 + #endif +#endif + +#ifndef LV_USE_LOTTIE + #ifdef CONFIG_LV_USE_LOTTIE + #define LV_USE_LOTTIE CONFIG_LV_USE_LOTTIE + #else + #define LV_USE_LOTTIE 0 /**< Requires: lv_canvas, thorvg */ + #endif +#endif + +#ifndef LV_USE_MENU + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_MENU + #define LV_USE_MENU CONFIG_LV_USE_MENU + #else + #define LV_USE_MENU 0 + #endif + #else + #define LV_USE_MENU 1 + #endif +#endif + +#ifndef LV_USE_MSGBOX + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_MSGBOX + #define LV_USE_MSGBOX CONFIG_LV_USE_MSGBOX + #else + #define LV_USE_MSGBOX 0 + #endif + #else + #define LV_USE_MSGBOX 1 + #endif +#endif + +#ifndef LV_USE_ROLLER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_ROLLER + #define LV_USE_ROLLER CONFIG_LV_USE_ROLLER + #else + #define LV_USE_ROLLER 0 + #endif + #else + #define LV_USE_ROLLER 1 /**< Requires: lv_label */ + #endif +#endif + +#ifndef LV_USE_SCALE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_SCALE + #define LV_USE_SCALE CONFIG_LV_USE_SCALE + #else + #define LV_USE_SCALE 0 + #endif + #else + #define LV_USE_SCALE 1 + #endif +#endif + +#ifndef LV_USE_SLIDER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_SLIDER + #define LV_USE_SLIDER CONFIG_LV_USE_SLIDER + #else + #define LV_USE_SLIDER 0 + #endif + #else + #define LV_USE_SLIDER 1 /**< Requires: lv_bar */ + #endif +#endif + +#ifndef LV_USE_SPAN + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_SPAN + #define LV_USE_SPAN CONFIG_LV_USE_SPAN + #else + #define LV_USE_SPAN 0 + #endif + #else + #define LV_USE_SPAN 1 + #endif +#endif +#if LV_USE_SPAN + /** A line of text can contain this maximum number of span descriptors. */ + #ifndef LV_SPAN_SNIPPET_STACK_SIZE + #ifdef CONFIG_LV_SPAN_SNIPPET_STACK_SIZE + #define LV_SPAN_SNIPPET_STACK_SIZE CONFIG_LV_SPAN_SNIPPET_STACK_SIZE + #else + #define LV_SPAN_SNIPPET_STACK_SIZE 64 + #endif + #endif +#endif + +#ifndef LV_USE_SPINBOX + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_SPINBOX + #define LV_USE_SPINBOX CONFIG_LV_USE_SPINBOX + #else + #define LV_USE_SPINBOX 0 + #endif + #else + #define LV_USE_SPINBOX 1 + #endif +#endif + +#ifndef LV_USE_SPINNER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_SPINNER + #define LV_USE_SPINNER CONFIG_LV_USE_SPINNER + #else + #define LV_USE_SPINNER 0 + #endif + #else + #define LV_USE_SPINNER 1 + #endif +#endif + +#ifndef LV_USE_SWITCH + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_SWITCH + #define LV_USE_SWITCH CONFIG_LV_USE_SWITCH + #else + #define LV_USE_SWITCH 0 + #endif + #else + #define LV_USE_SWITCH 1 + #endif +#endif + +#ifndef LV_USE_TABLE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_TABLE + #define LV_USE_TABLE CONFIG_LV_USE_TABLE + #else + #define LV_USE_TABLE 0 + #endif + #else + #define LV_USE_TABLE 1 + #endif +#endif + +#ifndef LV_USE_TABVIEW + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_TABVIEW + #define LV_USE_TABVIEW CONFIG_LV_USE_TABVIEW + #else + #define LV_USE_TABVIEW 0 + #endif + #else + #define LV_USE_TABVIEW 1 + #endif +#endif + +#ifndef LV_USE_TEXTAREA + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_TEXTAREA + #define LV_USE_TEXTAREA CONFIG_LV_USE_TEXTAREA + #else + #define LV_USE_TEXTAREA 0 + #endif + #else + #define LV_USE_TEXTAREA 1 /**< Requires: lv_label */ + #endif +#endif +#if LV_USE_TEXTAREA != 0 + #ifndef LV_TEXTAREA_DEF_PWD_SHOW_TIME + #ifdef CONFIG_LV_TEXTAREA_DEF_PWD_SHOW_TIME + #define LV_TEXTAREA_DEF_PWD_SHOW_TIME CONFIG_LV_TEXTAREA_DEF_PWD_SHOW_TIME + #else + #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /**< [ms] */ + #endif + #endif +#endif + +#ifndef LV_USE_TILEVIEW + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_TILEVIEW + #define LV_USE_TILEVIEW CONFIG_LV_USE_TILEVIEW + #else + #define LV_USE_TILEVIEW 0 + #endif + #else + #define LV_USE_TILEVIEW 1 + #endif +#endif + +#ifndef LV_USE_WIN + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_WIN + #define LV_USE_WIN CONFIG_LV_USE_WIN + #else + #define LV_USE_WIN 0 + #endif + #else + #define LV_USE_WIN 1 + #endif +#endif + +/*================== + * THEMES + *==================*/ +/* Documentation for themes can be found here: https://docs.lvgl.io/master/overview/style.html#themes . */ + +/** A simple, impressive and very complete theme */ +#ifndef LV_USE_THEME_DEFAULT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_THEME_DEFAULT + #define LV_USE_THEME_DEFAULT CONFIG_LV_USE_THEME_DEFAULT + #else + #define LV_USE_THEME_DEFAULT 0 + #endif + #else + #define LV_USE_THEME_DEFAULT 1 + #endif +#endif +#if LV_USE_THEME_DEFAULT + /** 0: Light mode; 1: Dark mode */ + #ifndef LV_THEME_DEFAULT_DARK + #ifdef CONFIG_LV_THEME_DEFAULT_DARK + #define LV_THEME_DEFAULT_DARK CONFIG_LV_THEME_DEFAULT_DARK + #else + #define LV_THEME_DEFAULT_DARK 0 + #endif + #endif + + /** 1: Enable grow on press */ + #ifndef LV_THEME_DEFAULT_GROW + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_THEME_DEFAULT_GROW + #define LV_THEME_DEFAULT_GROW CONFIG_LV_THEME_DEFAULT_GROW + #else + #define LV_THEME_DEFAULT_GROW 0 + #endif + #else + #define LV_THEME_DEFAULT_GROW 1 + #endif + #endif + + /** Default transition time in ms. */ + #ifndef LV_THEME_DEFAULT_TRANSITION_TIME + #ifdef CONFIG_LV_THEME_DEFAULT_TRANSITION_TIME + #define LV_THEME_DEFAULT_TRANSITION_TIME CONFIG_LV_THEME_DEFAULT_TRANSITION_TIME + #else + #define LV_THEME_DEFAULT_TRANSITION_TIME 80 + #endif + #endif +#endif /*LV_USE_THEME_DEFAULT*/ + +/** A very simple theme that is a good starting point for a custom theme */ +#ifndef LV_USE_THEME_SIMPLE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_THEME_SIMPLE + #define LV_USE_THEME_SIMPLE CONFIG_LV_USE_THEME_SIMPLE + #else + #define LV_USE_THEME_SIMPLE 0 + #endif + #else + #define LV_USE_THEME_SIMPLE 1 + #endif +#endif + +/** A theme designed for monochrome displays */ +#ifndef LV_USE_THEME_MONO + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_THEME_MONO + #define LV_USE_THEME_MONO CONFIG_LV_USE_THEME_MONO + #else + #define LV_USE_THEME_MONO 0 + #endif + #else + #define LV_USE_THEME_MONO 1 + #endif +#endif + +/*================== + * LAYOUTS + *==================*/ +/* Documentation for layouts can be found here: https://docs.lvgl.io/master/layouts/index.html . */ + +/** A layout similar to Flexbox in CSS. */ +#ifndef LV_USE_FLEX + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_FLEX + #define LV_USE_FLEX CONFIG_LV_USE_FLEX + #else + #define LV_USE_FLEX 0 + #endif + #else + #define LV_USE_FLEX 1 + #endif +#endif + +/** A layout similar to Grid in CSS. */ +#ifndef LV_USE_GRID + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_GRID + #define LV_USE_GRID CONFIG_LV_USE_GRID + #else + #define LV_USE_GRID 0 + #endif + #else + #define LV_USE_GRID 1 + #endif +#endif + +/*==================== + * 3RD PARTS LIBRARIES + *====================*/ +/* Documentation for libraries can be found here: https://docs.lvgl.io/master/libs/index.html . */ + +/* File system interfaces for common APIs */ + +/** Setting a default driver letter allows skipping the driver prefix in filepaths. */ +#ifndef LV_FS_DEFAULT_DRIVE_LETTER + #ifdef CONFIG_LV_FS_DEFAULT_DRIVE_LETTER + #define LV_FS_DEFAULT_DRIVE_LETTER CONFIG_LV_FS_DEFAULT_DRIVE_LETTER + #else + #define LV_FS_DEFAULT_DRIVE_LETTER '\0' + #endif +#endif + +/** API for fopen, fread, etc. */ +#ifndef LV_USE_FS_STDIO + #ifdef CONFIG_LV_USE_FS_STDIO + #define LV_USE_FS_STDIO CONFIG_LV_USE_FS_STDIO + #else + #define LV_USE_FS_STDIO 0 + #endif +#endif +#if LV_USE_FS_STDIO + #ifndef LV_FS_STDIO_LETTER + #ifdef CONFIG_LV_FS_STDIO_LETTER + #define LV_FS_STDIO_LETTER CONFIG_LV_FS_STDIO_LETTER + #else + #define LV_FS_STDIO_LETTER '\0' /**< Set an upper cased letter on which the drive will accessible (e.g. 'A') */ + #endif + #endif + #ifndef LV_FS_STDIO_PATH + #ifdef CONFIG_LV_FS_STDIO_PATH + #define LV_FS_STDIO_PATH CONFIG_LV_FS_STDIO_PATH + #else + #define LV_FS_STDIO_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #endif + #endif + #ifndef LV_FS_STDIO_CACHE_SIZE + #ifdef CONFIG_LV_FS_STDIO_CACHE_SIZE + #define LV_FS_STDIO_CACHE_SIZE CONFIG_LV_FS_STDIO_CACHE_SIZE + #else + #define LV_FS_STDIO_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ + #endif + #endif +#endif + +/** API for open, read, etc. */ +#ifndef LV_USE_FS_POSIX + #ifdef CONFIG_LV_USE_FS_POSIX + #define LV_USE_FS_POSIX CONFIG_LV_USE_FS_POSIX + #else + #define LV_USE_FS_POSIX 0 + #endif +#endif +#if LV_USE_FS_POSIX + #ifndef LV_FS_POSIX_LETTER + #ifdef CONFIG_LV_FS_POSIX_LETTER + #define LV_FS_POSIX_LETTER CONFIG_LV_FS_POSIX_LETTER + #else + #define LV_FS_POSIX_LETTER '\0' /**< Set an upper cased letter on which the drive will accessible (e.g. 'A') */ + #endif + #endif + #ifndef LV_FS_POSIX_PATH + #ifdef CONFIG_LV_FS_POSIX_PATH + #define LV_FS_POSIX_PATH CONFIG_LV_FS_POSIX_PATH + #else + #define LV_FS_POSIX_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #endif + #endif + #ifndef LV_FS_POSIX_CACHE_SIZE + #ifdef CONFIG_LV_FS_POSIX_CACHE_SIZE + #define LV_FS_POSIX_CACHE_SIZE CONFIG_LV_FS_POSIX_CACHE_SIZE + #else + #define LV_FS_POSIX_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ + #endif + #endif +#endif + +/** API for CreateFile, ReadFile, etc. */ +#ifndef LV_USE_FS_WIN32 + #ifdef CONFIG_LV_USE_FS_WIN32 + #define LV_USE_FS_WIN32 CONFIG_LV_USE_FS_WIN32 + #else + #define LV_USE_FS_WIN32 0 + #endif +#endif +#if LV_USE_FS_WIN32 + #ifndef LV_FS_WIN32_LETTER + #ifdef CONFIG_LV_FS_WIN32_LETTER + #define LV_FS_WIN32_LETTER CONFIG_LV_FS_WIN32_LETTER + #else + #define LV_FS_WIN32_LETTER '\0' /**< Set an upper cased letter on which the drive will accessible (e.g. 'A') */ + #endif + #endif + #ifndef LV_FS_WIN32_PATH + #ifdef CONFIG_LV_FS_WIN32_PATH + #define LV_FS_WIN32_PATH CONFIG_LV_FS_WIN32_PATH + #else + #define LV_FS_WIN32_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #endif + #endif + #ifndef LV_FS_WIN32_CACHE_SIZE + #ifdef CONFIG_LV_FS_WIN32_CACHE_SIZE + #define LV_FS_WIN32_CACHE_SIZE CONFIG_LV_FS_WIN32_CACHE_SIZE + #else + #define LV_FS_WIN32_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ + #endif + #endif +#endif + +/** API for FATFS (needs to be added separately). Uses f_open, f_read, etc. */ +#ifndef LV_USE_FS_FATFS + #ifdef CONFIG_LV_USE_FS_FATFS + #define LV_USE_FS_FATFS CONFIG_LV_USE_FS_FATFS + #else + #define LV_USE_FS_FATFS 0 + #endif +#endif +#if LV_USE_FS_FATFS + #ifndef LV_FS_FATFS_LETTER + #ifdef CONFIG_LV_FS_FATFS_LETTER + #define LV_FS_FATFS_LETTER CONFIG_LV_FS_FATFS_LETTER + #else + #define LV_FS_FATFS_LETTER '\0' /**< Set an upper cased letter on which the drive will accessible (e.g. 'A') */ + #endif + #endif + #ifndef LV_FS_FATFS_CACHE_SIZE + #ifdef CONFIG_LV_FS_FATFS_CACHE_SIZE + #define LV_FS_FATFS_CACHE_SIZE CONFIG_LV_FS_FATFS_CACHE_SIZE + #else + #define LV_FS_FATFS_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ + #endif + #endif +#endif + +/** API for memory-mapped file access. */ +#ifndef LV_USE_FS_MEMFS + #ifdef CONFIG_LV_USE_FS_MEMFS + #define LV_USE_FS_MEMFS CONFIG_LV_USE_FS_MEMFS + #else + #define LV_USE_FS_MEMFS 0 + #endif +#endif +#if LV_USE_FS_MEMFS + #ifndef LV_FS_MEMFS_LETTER + #ifdef CONFIG_LV_FS_MEMFS_LETTER + #define LV_FS_MEMFS_LETTER CONFIG_LV_FS_MEMFS_LETTER + #else + #define LV_FS_MEMFS_LETTER '\0' /**< Set an upper cased letter on which the drive will accessible (e.g. 'A') */ + #endif + #endif +#endif + +/** API for LittleFs. */ +#ifndef LV_USE_FS_LITTLEFS + #ifdef CONFIG_LV_USE_FS_LITTLEFS + #define LV_USE_FS_LITTLEFS CONFIG_LV_USE_FS_LITTLEFS + #else + #define LV_USE_FS_LITTLEFS 0 + #endif +#endif +#if LV_USE_FS_LITTLEFS + #ifndef LV_FS_LITTLEFS_LETTER + #ifdef CONFIG_LV_FS_LITTLEFS_LETTER + #define LV_FS_LITTLEFS_LETTER CONFIG_LV_FS_LITTLEFS_LETTER + #else + #define LV_FS_LITTLEFS_LETTER '\0' /**< Set an upper cased letter on which the drive will accessible (e.g. 'A') */ + #endif + #endif +#endif + +/** API for Arduino LittleFs. */ +#ifndef LV_USE_FS_ARDUINO_ESP_LITTLEFS + #ifdef CONFIG_LV_USE_FS_ARDUINO_ESP_LITTLEFS + #define LV_USE_FS_ARDUINO_ESP_LITTLEFS CONFIG_LV_USE_FS_ARDUINO_ESP_LITTLEFS + #else + #define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0 + #endif +#endif +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + #ifndef LV_FS_ARDUINO_ESP_LITTLEFS_LETTER + #ifdef CONFIG_LV_FS_ARDUINO_ESP_LITTLEFS_LETTER + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER CONFIG_LV_FS_ARDUINO_ESP_LITTLEFS_LETTER + #else + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /**< Set an upper cased letter on which the drive will accessible (e.g. 'A') */ + #endif + #endif +#endif + +/** API for Arduino Sd. */ +#ifndef LV_USE_FS_ARDUINO_SD + #ifdef CONFIG_LV_USE_FS_ARDUINO_SD + #define LV_USE_FS_ARDUINO_SD CONFIG_LV_USE_FS_ARDUINO_SD + #else + #define LV_USE_FS_ARDUINO_SD 0 + #endif +#endif +#if LV_USE_FS_ARDUINO_SD + #ifndef LV_FS_ARDUINO_SD_LETTER + #ifdef CONFIG_LV_FS_ARDUINO_SD_LETTER + #define LV_FS_ARDUINO_SD_LETTER CONFIG_LV_FS_ARDUINO_SD_LETTER + #else + #define LV_FS_ARDUINO_SD_LETTER '\0' /**< Set an upper cased letter on which the drive will accessible (e.g. 'A') */ + #endif + #endif +#endif + +/** LODEPNG decoder library */ +#ifndef LV_USE_LODEPNG + #ifdef CONFIG_LV_USE_LODEPNG + #define LV_USE_LODEPNG CONFIG_LV_USE_LODEPNG + #else + #define LV_USE_LODEPNG 0 + #endif +#endif + +/** PNG decoder(libpng) library */ +#ifndef LV_USE_LIBPNG + #ifdef CONFIG_LV_USE_LIBPNG + #define LV_USE_LIBPNG CONFIG_LV_USE_LIBPNG + #else + #define LV_USE_LIBPNG 0 + #endif +#endif + +/** BMP decoder library */ +#ifndef LV_USE_BMP + #ifdef CONFIG_LV_USE_BMP + #define LV_USE_BMP CONFIG_LV_USE_BMP + #else + #define LV_USE_BMP 0 + #endif +#endif + +/** JPG + split JPG decoder library. + * Split JPG is a custom format optimized for embedded systems. */ +#ifndef LV_USE_TJPGD + #ifdef CONFIG_LV_USE_TJPGD + #define LV_USE_TJPGD CONFIG_LV_USE_TJPGD + #else + #define LV_USE_TJPGD 0 + #endif +#endif + +/** libjpeg-turbo decoder library. + * - Supports complete JPEG specifications and high-performance JPEG decoding. */ +#ifndef LV_USE_LIBJPEG_TURBO + #ifdef CONFIG_LV_USE_LIBJPEG_TURBO + #define LV_USE_LIBJPEG_TURBO CONFIG_LV_USE_LIBJPEG_TURBO + #else + #define LV_USE_LIBJPEG_TURBO 0 + #endif +#endif + +/** GIF decoder library */ +#ifndef LV_USE_GIF + #ifdef CONFIG_LV_USE_GIF + #define LV_USE_GIF CONFIG_LV_USE_GIF + #else + #define LV_USE_GIF 0 + #endif +#endif + #if LV_USE_GIF + /** GIF decoder accelerate */ + #ifndef LV_GIF_CACHE_DECODE_DATA + #ifdef CONFIG_LV_GIF_CACHE_DECODE_DATA + #define LV_GIF_CACHE_DECODE_DATA CONFIG_LV_GIF_CACHE_DECODE_DATA + #else + #define LV_GIF_CACHE_DECODE_DATA 0 + #endif + #endif +#endif + + +/** Decode bin images to RAM */ +#ifndef LV_BIN_DECODER_RAM_LOAD + #ifdef CONFIG_LV_BIN_DECODER_RAM_LOAD + #define LV_BIN_DECODER_RAM_LOAD CONFIG_LV_BIN_DECODER_RAM_LOAD + #else + #define LV_BIN_DECODER_RAM_LOAD 0 + #endif +#endif + +/** RLE decompress library */ +#ifndef LV_USE_RLE + #ifdef CONFIG_LV_USE_RLE + #define LV_USE_RLE CONFIG_LV_USE_RLE + #else + #define LV_USE_RLE 0 + #endif +#endif + +/** QR code library */ +#ifndef LV_USE_QRCODE + #ifdef CONFIG_LV_USE_QRCODE + #define LV_USE_QRCODE CONFIG_LV_USE_QRCODE + #else + #define LV_USE_QRCODE 0 + #endif +#endif + +/** Barcode code library */ +#ifndef LV_USE_BARCODE + #ifdef CONFIG_LV_USE_BARCODE + #define LV_USE_BARCODE CONFIG_LV_USE_BARCODE + #else + #define LV_USE_BARCODE 0 + #endif +#endif + +/** FreeType library */ +#ifndef LV_USE_FREETYPE + #ifdef CONFIG_LV_USE_FREETYPE + #define LV_USE_FREETYPE CONFIG_LV_USE_FREETYPE + #else + #define LV_USE_FREETYPE 0 + #endif +#endif +#if LV_USE_FREETYPE + /** Let FreeType use LVGL memory and file porting */ + #ifndef LV_FREETYPE_USE_LVGL_PORT + #ifdef CONFIG_LV_FREETYPE_USE_LVGL_PORT + #define LV_FREETYPE_USE_LVGL_PORT CONFIG_LV_FREETYPE_USE_LVGL_PORT + #else + #define LV_FREETYPE_USE_LVGL_PORT 0 + #endif + #endif + + /** Cache count of glyphs in FreeType, i.e. number of glyphs that can be cached. + * The higher the value, the more memory will be used. */ + #ifndef LV_FREETYPE_CACHE_FT_GLYPH_CNT + #ifdef CONFIG_LV_FREETYPE_CACHE_FT_GLYPH_CNT + #define LV_FREETYPE_CACHE_FT_GLYPH_CNT CONFIG_LV_FREETYPE_CACHE_FT_GLYPH_CNT + #else + #define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256 + #endif + #endif +#endif + +/** Built-in TTF decoder */ +#ifndef LV_USE_TINY_TTF + #ifdef CONFIG_LV_USE_TINY_TTF + #define LV_USE_TINY_TTF CONFIG_LV_USE_TINY_TTF + #else + #define LV_USE_TINY_TTF 0 + #endif +#endif +#if LV_USE_TINY_TTF + /* Enable loading TTF data from files */ + #ifndef LV_TINY_TTF_FILE_SUPPORT + #ifdef CONFIG_LV_TINY_TTF_FILE_SUPPORT + #define LV_TINY_TTF_FILE_SUPPORT CONFIG_LV_TINY_TTF_FILE_SUPPORT + #else + #define LV_TINY_TTF_FILE_SUPPORT 0 + #endif + #endif + #ifndef LV_TINY_TTF_CACHE_GLYPH_CNT + #ifdef CONFIG_LV_TINY_TTF_CACHE_GLYPH_CNT + #define LV_TINY_TTF_CACHE_GLYPH_CNT CONFIG_LV_TINY_TTF_CACHE_GLYPH_CNT + #else + #define LV_TINY_TTF_CACHE_GLYPH_CNT 256 + #endif + #endif +#endif + +/** Rlottie library */ +#ifndef LV_USE_RLOTTIE + #ifdef CONFIG_LV_USE_RLOTTIE + #define LV_USE_RLOTTIE CONFIG_LV_USE_RLOTTIE + #else + #define LV_USE_RLOTTIE 0 + #endif +#endif + +/** Enable Vector Graphic APIs + * - Requires `LV_USE_MATRIX = 1` */ +#ifndef LV_USE_VECTOR_GRAPHIC + #ifdef CONFIG_LV_USE_VECTOR_GRAPHIC + #define LV_USE_VECTOR_GRAPHIC CONFIG_LV_USE_VECTOR_GRAPHIC + #else + #define LV_USE_VECTOR_GRAPHIC 0 + #endif +#endif + +/** Enable ThorVG (vector graphics library) from the src/libs folder */ +#ifndef LV_USE_THORVG_INTERNAL + #ifdef CONFIG_LV_USE_THORVG_INTERNAL + #define LV_USE_THORVG_INTERNAL CONFIG_LV_USE_THORVG_INTERNAL + #else + #define LV_USE_THORVG_INTERNAL 0 + #endif +#endif + +/** Enable ThorVG by assuming that its installed and linked to the project */ +#ifndef LV_USE_THORVG_EXTERNAL + #ifdef CONFIG_LV_USE_THORVG_EXTERNAL + #define LV_USE_THORVG_EXTERNAL CONFIG_LV_USE_THORVG_EXTERNAL + #else + #define LV_USE_THORVG_EXTERNAL 0 + #endif +#endif + +/** Use lvgl built-in LZ4 lib */ +#ifndef LV_USE_LZ4_INTERNAL + #ifdef CONFIG_LV_USE_LZ4_INTERNAL + #define LV_USE_LZ4_INTERNAL CONFIG_LV_USE_LZ4_INTERNAL + #else + #define LV_USE_LZ4_INTERNAL 0 + #endif +#endif + +/** Use external LZ4 library */ +#ifndef LV_USE_LZ4_EXTERNAL + #ifdef CONFIG_LV_USE_LZ4_EXTERNAL + #define LV_USE_LZ4_EXTERNAL CONFIG_LV_USE_LZ4_EXTERNAL + #else + #define LV_USE_LZ4_EXTERNAL 0 + #endif +#endif + +/*SVG library*/ +#ifndef LV_USE_SVG + #ifdef CONFIG_LV_USE_SVG + #define LV_USE_SVG CONFIG_LV_USE_SVG + #else + #define LV_USE_SVG 0 + #endif +#endif +#ifndef LV_USE_SVG_ANIMATION + #ifdef CONFIG_LV_USE_SVG_ANIMATION + #define LV_USE_SVG_ANIMATION CONFIG_LV_USE_SVG_ANIMATION + #else + #define LV_USE_SVG_ANIMATION 0 + #endif +#endif +#ifndef LV_USE_SVG_DEBUG + #ifdef CONFIG_LV_USE_SVG_DEBUG + #define LV_USE_SVG_DEBUG CONFIG_LV_USE_SVG_DEBUG + #else + #define LV_USE_SVG_DEBUG 0 + #endif +#endif + +/** FFmpeg library for image decoding and playing videos. + * Supports all major image formats so do not enable other image decoder with it. */ +#ifndef LV_USE_FFMPEG + #ifdef CONFIG_LV_USE_FFMPEG + #define LV_USE_FFMPEG CONFIG_LV_USE_FFMPEG + #else + #define LV_USE_FFMPEG 0 + #endif +#endif +#if LV_USE_FFMPEG + /** Dump input information to stderr */ + #ifndef LV_FFMPEG_DUMP_FORMAT + #ifdef CONFIG_LV_FFMPEG_DUMP_FORMAT + #define LV_FFMPEG_DUMP_FORMAT CONFIG_LV_FFMPEG_DUMP_FORMAT + #else + #define LV_FFMPEG_DUMP_FORMAT 0 + #endif + #endif +#endif + +/*================== + * OTHERS + *==================*/ +/* Documentation for several of the below items can be found here: https://docs.lvgl.io/master/others/index.html . */ + +/** 1: Enable API to take snapshot for object */ +#ifndef LV_USE_SNAPSHOT + #ifdef CONFIG_LV_USE_SNAPSHOT + #define LV_USE_SNAPSHOT CONFIG_LV_USE_SNAPSHOT + #else + #define LV_USE_SNAPSHOT 0 + #endif +#endif + +/** 1: Enable system monitor component */ +#ifndef LV_USE_SYSMON + #ifdef CONFIG_LV_USE_SYSMON + #define LV_USE_SYSMON CONFIG_LV_USE_SYSMON + #else + #define LV_USE_SYSMON 0 + #endif +#endif +#if LV_USE_SYSMON + /** Get the idle percentage. E.g. uint32_t my_get_idle(void); */ + #ifndef LV_SYSMON_GET_IDLE + #ifdef CONFIG_LV_SYSMON_GET_IDLE + #define LV_SYSMON_GET_IDLE CONFIG_LV_SYSMON_GET_IDLE + #else + #define LV_SYSMON_GET_IDLE lv_timer_get_idle + #endif + #endif + + /** 1: Show CPU usage and FPS count. + * - Requires `LV_USE_SYSMON = 1` */ + #ifndef LV_USE_PERF_MONITOR + #ifdef CONFIG_LV_USE_PERF_MONITOR + #define LV_USE_PERF_MONITOR CONFIG_LV_USE_PERF_MONITOR + #else + #define LV_USE_PERF_MONITOR 0 + #endif + #endif + #if LV_USE_PERF_MONITOR + #ifndef LV_USE_PERF_MONITOR_POS + #ifdef CONFIG_LV_USE_PERF_MONITOR_POS + #define LV_USE_PERF_MONITOR_POS CONFIG_LV_USE_PERF_MONITOR_POS + #else + #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT + #endif + #endif + + /** 0: Displays performance data on the screen; 1: Prints performance data using log. */ + #ifndef LV_USE_PERF_MONITOR_LOG_MODE + #ifdef CONFIG_LV_USE_PERF_MONITOR_LOG_MODE + #define LV_USE_PERF_MONITOR_LOG_MODE CONFIG_LV_USE_PERF_MONITOR_LOG_MODE + #else + #define LV_USE_PERF_MONITOR_LOG_MODE 0 + #endif + #endif + #endif + + /** 1: Show used memory and memory fragmentation. + * - Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` + * - Requires `LV_USE_SYSMON = 1`*/ + #ifndef LV_USE_MEM_MONITOR + #ifdef CONFIG_LV_USE_MEM_MONITOR + #define LV_USE_MEM_MONITOR CONFIG_LV_USE_MEM_MONITOR + #else + #define LV_USE_MEM_MONITOR 0 + #endif + #endif + #if LV_USE_MEM_MONITOR + #ifndef LV_USE_MEM_MONITOR_POS + #ifdef CONFIG_LV_USE_MEM_MONITOR_POS + #define LV_USE_MEM_MONITOR_POS CONFIG_LV_USE_MEM_MONITOR_POS + #else + #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT + #endif + #endif + #endif +#endif /*LV_USE_SYSMON*/ + +/** 1: Enable runtime performance profiler */ +#ifndef LV_USE_PROFILER + #ifdef CONFIG_LV_USE_PROFILER + #define LV_USE_PROFILER CONFIG_LV_USE_PROFILER + #else + #define LV_USE_PROFILER 0 + #endif +#endif +#if LV_USE_PROFILER + /** 1: Enable the built-in profiler */ + #ifndef LV_USE_PROFILER_BUILTIN + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_PROFILER_BUILTIN + #define LV_USE_PROFILER_BUILTIN CONFIG_LV_USE_PROFILER_BUILTIN + #else + #define LV_USE_PROFILER_BUILTIN 0 + #endif + #else + #define LV_USE_PROFILER_BUILTIN 1 + #endif + #endif + #if LV_USE_PROFILER_BUILTIN + /** Default profiler trace buffer size */ + #ifndef LV_PROFILER_BUILTIN_BUF_SIZE + #ifdef CONFIG_LV_PROFILER_BUILTIN_BUF_SIZE + #define LV_PROFILER_BUILTIN_BUF_SIZE CONFIG_LV_PROFILER_BUILTIN_BUF_SIZE + #else + #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /**< [bytes] */ + #endif + #endif + #endif + + /** Header to include for profiler */ + #ifndef LV_PROFILER_INCLUDE + #ifdef CONFIG_LV_PROFILER_INCLUDE + #define LV_PROFILER_INCLUDE CONFIG_LV_PROFILER_INCLUDE + #else + #define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h" + #endif + #endif + + /** Profiler start point function */ + #ifndef LV_PROFILER_BEGIN + #ifdef CONFIG_LV_PROFILER_BEGIN + #define LV_PROFILER_BEGIN CONFIG_LV_PROFILER_BEGIN + #else + #define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN + #endif + #endif + + /** Profiler end point function */ + #ifndef LV_PROFILER_END + #ifdef CONFIG_LV_PROFILER_END + #define LV_PROFILER_END CONFIG_LV_PROFILER_END + #else + #define LV_PROFILER_END LV_PROFILER_BUILTIN_END + #endif + #endif + + /** Profiler start point function with custom tag */ + #ifndef LV_PROFILER_BEGIN_TAG + #ifdef CONFIG_LV_PROFILER_BEGIN_TAG + #define LV_PROFILER_BEGIN_TAG CONFIG_LV_PROFILER_BEGIN_TAG + #else + #define LV_PROFILER_BEGIN_TAG LV_PROFILER_BUILTIN_BEGIN_TAG + #endif + #endif + + /** Profiler end point function with custom tag */ + #ifndef LV_PROFILER_END_TAG + #ifdef CONFIG_LV_PROFILER_END_TAG + #define LV_PROFILER_END_TAG CONFIG_LV_PROFILER_END_TAG + #else + #define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG + #endif + #endif + + /*Enable layout profiler*/ + #ifndef LV_PROFILER_LAYOUT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_LAYOUT + #define LV_PROFILER_LAYOUT CONFIG_LV_PROFILER_LAYOUT + #else + #define LV_PROFILER_LAYOUT 0 + #endif + #else + #define LV_PROFILER_LAYOUT 1 + #endif + #endif + + /*Enable disp refr profiler*/ + #ifndef LV_PROFILER_REFR + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_REFR + #define LV_PROFILER_REFR CONFIG_LV_PROFILER_REFR + #else + #define LV_PROFILER_REFR 0 + #endif + #else + #define LV_PROFILER_REFR 1 + #endif + #endif + + /*Enable draw profiler*/ + #ifndef LV_PROFILER_DRAW + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_DRAW + #define LV_PROFILER_DRAW CONFIG_LV_PROFILER_DRAW + #else + #define LV_PROFILER_DRAW 0 + #endif + #else + #define LV_PROFILER_DRAW 1 + #endif + #endif + + /*Enable indev profiler*/ + #ifndef LV_PROFILER_INDEV + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_INDEV + #define LV_PROFILER_INDEV CONFIG_LV_PROFILER_INDEV + #else + #define LV_PROFILER_INDEV 0 + #endif + #else + #define LV_PROFILER_INDEV 1 + #endif + #endif + + /*Enable decoder profiler*/ + #ifndef LV_PROFILER_DECODER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_DECODER + #define LV_PROFILER_DECODER CONFIG_LV_PROFILER_DECODER + #else + #define LV_PROFILER_DECODER 0 + #endif + #else + #define LV_PROFILER_DECODER 1 + #endif + #endif + + /*Enable font profiler*/ + #ifndef LV_PROFILER_FONT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_FONT + #define LV_PROFILER_FONT CONFIG_LV_PROFILER_FONT + #else + #define LV_PROFILER_FONT 0 + #endif + #else + #define LV_PROFILER_FONT 1 + #endif + #endif + + /*Enable fs profiler*/ + #ifndef LV_PROFILER_FS + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_FS + #define LV_PROFILER_FS CONFIG_LV_PROFILER_FS + #else + #define LV_PROFILER_FS 0 + #endif + #else + #define LV_PROFILER_FS 1 + #endif + #endif + + /*Enable style profiler*/ + #ifndef LV_PROFILER_STYLE + #ifdef CONFIG_LV_PROFILER_STYLE + #define LV_PROFILER_STYLE CONFIG_LV_PROFILER_STYLE + #else + #define LV_PROFILER_STYLE 0 + #endif + #endif + + /*Enable timer profiler*/ + #ifndef LV_PROFILER_TIMER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_TIMER + #define LV_PROFILER_TIMER CONFIG_LV_PROFILER_TIMER + #else + #define LV_PROFILER_TIMER 0 + #endif + #else + #define LV_PROFILER_TIMER 1 + #endif + #endif + + /*Enable cache profiler*/ + #ifndef LV_PROFILER_CACHE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_CACHE + #define LV_PROFILER_CACHE CONFIG_LV_PROFILER_CACHE + #else + #define LV_PROFILER_CACHE 0 + #endif + #else + #define LV_PROFILER_CACHE 1 + #endif + #endif +#endif + +/** 1: Enable Monkey test */ +#ifndef LV_USE_MONKEY + #ifdef CONFIG_LV_USE_MONKEY + #define LV_USE_MONKEY CONFIG_LV_USE_MONKEY + #else + #define LV_USE_MONKEY 0 + #endif +#endif + +/** 1: Enable grid navigation */ +#ifndef LV_USE_GRIDNAV + #ifdef CONFIG_LV_USE_GRIDNAV + #define LV_USE_GRIDNAV CONFIG_LV_USE_GRIDNAV + #else + #define LV_USE_GRIDNAV 0 + #endif +#endif + +/** 1: Enable `lv_obj` fragment logic */ +#ifndef LV_USE_FRAGMENT + #ifdef CONFIG_LV_USE_FRAGMENT + #define LV_USE_FRAGMENT CONFIG_LV_USE_FRAGMENT + #else + #define LV_USE_FRAGMENT 0 + #endif +#endif + +/** 1: Support using images as font in label or span widgets */ +#ifndef LV_USE_IMGFONT + #ifdef CONFIG_LV_USE_IMGFONT + #define LV_USE_IMGFONT CONFIG_LV_USE_IMGFONT + #else + #define LV_USE_IMGFONT 0 + #endif +#endif + +/** 1: Enable an observer pattern implementation */ +#ifndef LV_USE_OBSERVER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_OBSERVER + #define LV_USE_OBSERVER CONFIG_LV_USE_OBSERVER + #else + #define LV_USE_OBSERVER 0 + #endif + #else + #define LV_USE_OBSERVER 1 + #endif +#endif + +/** 1: Enable Pinyin input method + * - Requires: lv_keyboard */ +#ifndef LV_USE_IME_PINYIN + #ifdef CONFIG_LV_USE_IME_PINYIN + #define LV_USE_IME_PINYIN CONFIG_LV_USE_IME_PINYIN + #else + #define LV_USE_IME_PINYIN 0 + #endif +#endif +#if LV_USE_IME_PINYIN + /** 1: Use default thesaurus. + * @note If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesaurus. */ + #ifndef LV_IME_PINYIN_USE_DEFAULT_DICT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_IME_PINYIN_USE_DEFAULT_DICT + #define LV_IME_PINYIN_USE_DEFAULT_DICT CONFIG_LV_IME_PINYIN_USE_DEFAULT_DICT + #else + #define LV_IME_PINYIN_USE_DEFAULT_DICT 0 + #endif + #else + #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 + #endif + #endif + /** Set maximum number of candidate panels that can be displayed. + * @note This needs to be adjusted according to size of screen. */ + #ifndef LV_IME_PINYIN_CAND_TEXT_NUM + #ifdef CONFIG_LV_IME_PINYIN_CAND_TEXT_NUM + #define LV_IME_PINYIN_CAND_TEXT_NUM CONFIG_LV_IME_PINYIN_CAND_TEXT_NUM + #else + #define LV_IME_PINYIN_CAND_TEXT_NUM 6 + #endif + #endif + + /** Use 9-key input (k9). */ + #ifndef LV_IME_PINYIN_USE_K9_MODE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_IME_PINYIN_USE_K9_MODE + #define LV_IME_PINYIN_USE_K9_MODE CONFIG_LV_IME_PINYIN_USE_K9_MODE + #else + #define LV_IME_PINYIN_USE_K9_MODE 0 + #endif + #else + #define LV_IME_PINYIN_USE_K9_MODE 1 + #endif + #endif + #if LV_IME_PINYIN_USE_K9_MODE == 1 + #ifndef LV_IME_PINYIN_K9_CAND_TEXT_NUM + #ifdef CONFIG_LV_IME_PINYIN_K9_CAND_TEXT_NUM + #define LV_IME_PINYIN_K9_CAND_TEXT_NUM CONFIG_LV_IME_PINYIN_K9_CAND_TEXT_NUM + #else + #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 + #endif + #endif + #endif /*LV_IME_PINYIN_USE_K9_MODE*/ +#endif + +/** 1: Enable file explorer. + * - Requires: lv_table */ +#ifndef LV_USE_FILE_EXPLORER + #ifdef CONFIG_LV_USE_FILE_EXPLORER + #define LV_USE_FILE_EXPLORER CONFIG_LV_USE_FILE_EXPLORER + #else + #define LV_USE_FILE_EXPLORER 0 + #endif +#endif +#if LV_USE_FILE_EXPLORER + /** Maximum length of path */ + #ifndef LV_FILE_EXPLORER_PATH_MAX_LEN + #ifdef CONFIG_LV_FILE_EXPLORER_PATH_MAX_LEN + #define LV_FILE_EXPLORER_PATH_MAX_LEN CONFIG_LV_FILE_EXPLORER_PATH_MAX_LEN + #else + #define LV_FILE_EXPLORER_PATH_MAX_LEN (128) + #endif + #endif + /** Quick access bar, 1:use, 0:do not use. + * - Requires: lv_list */ + #ifndef LV_FILE_EXPLORER_QUICK_ACCESS + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_FILE_EXPLORER_QUICK_ACCESS + #define LV_FILE_EXPLORER_QUICK_ACCESS CONFIG_LV_FILE_EXPLORER_QUICK_ACCESS + #else + #define LV_FILE_EXPLORER_QUICK_ACCESS 0 + #endif + #else + #define LV_FILE_EXPLORER_QUICK_ACCESS 1 + #endif + #endif +#endif + +/** 1: Enable freetype font manager + * - Requires: LV_USE_FREETYPE */ +#ifndef LV_USE_FONT_MANAGER + #ifdef CONFIG_LV_USE_FONT_MANAGER + #define LV_USE_FONT_MANAGER CONFIG_LV_USE_FONT_MANAGER + #else + #define LV_USE_FONT_MANAGER 0 + #endif +#endif +#if LV_USE_FONT_MANAGER + +/*Font manager name max length*/ +#ifndef LV_FONT_MANAGER_NAME_MAX_LEN + #ifdef CONFIG_LV_FONT_MANAGER_NAME_MAX_LEN + #define LV_FONT_MANAGER_NAME_MAX_LEN CONFIG_LV_FONT_MANAGER_NAME_MAX_LEN + #else + #define LV_FONT_MANAGER_NAME_MAX_LEN 32 + #endif +#endif + +#endif + +/*================== + * DEVICES + *==================*/ + +/** Use SDL to open window on PC and handle mouse and keyboard. */ +#ifndef LV_USE_SDL + #ifdef CONFIG_LV_USE_SDL + #define LV_USE_SDL CONFIG_LV_USE_SDL + #else + #define LV_USE_SDL 0 + #endif +#endif +#if LV_USE_SDL + #ifndef LV_SDL_INCLUDE_PATH + #ifdef CONFIG_LV_SDL_INCLUDE_PATH + #define LV_SDL_INCLUDE_PATH CONFIG_LV_SDL_INCLUDE_PATH + #else + #define LV_SDL_INCLUDE_PATH + #endif + #endif + #ifndef LV_SDL_RENDER_MODE + #ifdef CONFIG_LV_SDL_RENDER_MODE + #define LV_SDL_RENDER_MODE CONFIG_LV_SDL_RENDER_MODE + #else + #define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /**< LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance */ + #endif + #endif + #ifndef LV_SDL_BUF_COUNT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_SDL_BUF_COUNT + #define LV_SDL_BUF_COUNT CONFIG_LV_SDL_BUF_COUNT + #else + #define LV_SDL_BUF_COUNT 0 + #endif + #else + #define LV_SDL_BUF_COUNT 1 /**< 1 or 2 */ + #endif + #endif + #ifndef LV_SDL_ACCELERATED + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_SDL_ACCELERATED + #define LV_SDL_ACCELERATED CONFIG_LV_SDL_ACCELERATED + #else + #define LV_SDL_ACCELERATED 0 + #endif + #else + #define LV_SDL_ACCELERATED 1 /**< 1: Use hardware acceleration*/ + #endif + #endif + #ifndef LV_SDL_FULLSCREEN + #ifdef CONFIG_LV_SDL_FULLSCREEN + #define LV_SDL_FULLSCREEN CONFIG_LV_SDL_FULLSCREEN + #else + #define LV_SDL_FULLSCREEN 0 /**< 1: Make the window full screen by default */ + #endif + #endif + #ifndef LV_SDL_DIRECT_EXIT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_SDL_DIRECT_EXIT + #define LV_SDL_DIRECT_EXIT CONFIG_LV_SDL_DIRECT_EXIT + #else + #define LV_SDL_DIRECT_EXIT 0 + #endif + #else + #define LV_SDL_DIRECT_EXIT 1 /**< 1: Exit the application when all SDL windows are closed */ + #endif + #endif + #ifndef LV_SDL_MOUSEWHEEL_MODE + #ifdef CONFIG_LV_SDL_MOUSEWHEEL_MODE + #define LV_SDL_MOUSEWHEEL_MODE CONFIG_LV_SDL_MOUSEWHEEL_MODE + #else + #define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/ + #endif + #endif +#endif + +/** Use X11 to open window on Linux desktop and handle mouse and keyboard */ +#ifndef LV_USE_X11 + #ifdef CONFIG_LV_USE_X11 + #define LV_USE_X11 CONFIG_LV_USE_X11 + #else + #define LV_USE_X11 0 + #endif +#endif +#if LV_USE_X11 + #ifndef LV_X11_DIRECT_EXIT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_X11_DIRECT_EXIT + #define LV_X11_DIRECT_EXIT CONFIG_LV_X11_DIRECT_EXIT + #else + #define LV_X11_DIRECT_EXIT 0 + #endif + #else + #define LV_X11_DIRECT_EXIT 1 /**< Exit application when all X11 windows have been closed */ + #endif + #endif + #ifndef LV_X11_DOUBLE_BUFFER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_X11_DOUBLE_BUFFER + #define LV_X11_DOUBLE_BUFFER CONFIG_LV_X11_DOUBLE_BUFFER + #else + #define LV_X11_DOUBLE_BUFFER 0 + #endif + #else + #define LV_X11_DOUBLE_BUFFER 1 /**< Use double buffers for rendering */ + #endif + #endif + /* Select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!). */ + #ifndef LV_X11_RENDER_MODE_PARTIAL + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_X11_RENDER_MODE_PARTIAL + #define LV_X11_RENDER_MODE_PARTIAL CONFIG_LV_X11_RENDER_MODE_PARTIAL + #else + #define LV_X11_RENDER_MODE_PARTIAL 0 + #endif + #else + #define LV_X11_RENDER_MODE_PARTIAL 1 /**< Partial render mode (preferred) */ + #endif + #endif + #ifndef LV_X11_RENDER_MODE_DIRECT + #ifdef CONFIG_LV_X11_RENDER_MODE_DIRECT + #define LV_X11_RENDER_MODE_DIRECT CONFIG_LV_X11_RENDER_MODE_DIRECT + #else + #define LV_X11_RENDER_MODE_DIRECT 0 /**< Direct render mode */ + #endif + #endif + #ifndef LV_X11_RENDER_MODE_FULL + #ifdef CONFIG_LV_X11_RENDER_MODE_FULL + #define LV_X11_RENDER_MODE_FULL CONFIG_LV_X11_RENDER_MODE_FULL + #else + #define LV_X11_RENDER_MODE_FULL 0 /**< Full render mode */ + #endif + #endif +#endif + +/** Use Wayland to open a window and handle input on Linux or BSD desktops */ +#ifndef LV_USE_WAYLAND + #ifdef CONFIG_LV_USE_WAYLAND + #define LV_USE_WAYLAND CONFIG_LV_USE_WAYLAND + #else + #define LV_USE_WAYLAND 0 + #endif +#endif +#if LV_USE_WAYLAND + #ifndef LV_WAYLAND_WINDOW_DECORATIONS + #ifdef CONFIG_LV_WAYLAND_WINDOW_DECORATIONS + #define LV_WAYLAND_WINDOW_DECORATIONS CONFIG_LV_WAYLAND_WINDOW_DECORATIONS + #else + #define LV_WAYLAND_WINDOW_DECORATIONS 0 /**< Draw client side window decorations only necessary on Mutter/GNOME */ + #endif + #endif + #ifndef LV_WAYLAND_WL_SHELL + #ifdef CONFIG_LV_WAYLAND_WL_SHELL + #define LV_WAYLAND_WL_SHELL CONFIG_LV_WAYLAND_WL_SHELL + #else + #define LV_WAYLAND_WL_SHELL 0 /**< Use the legacy wl_shell protocol instead of the default XDG shell */ + #endif + #endif +#endif + +/** Driver for /dev/fb */ +#ifndef LV_USE_LINUX_FBDEV + #ifdef CONFIG_LV_USE_LINUX_FBDEV + #define LV_USE_LINUX_FBDEV CONFIG_LV_USE_LINUX_FBDEV + #else + #define LV_USE_LINUX_FBDEV 0 + #endif +#endif +#if LV_USE_LINUX_FBDEV + #ifndef LV_LINUX_FBDEV_BSD + #ifdef CONFIG_LV_LINUX_FBDEV_BSD + #define LV_LINUX_FBDEV_BSD CONFIG_LV_LINUX_FBDEV_BSD + #else + #define LV_LINUX_FBDEV_BSD 0 + #endif + #endif + #ifndef LV_LINUX_FBDEV_RENDER_MODE + #ifdef CONFIG_LV_LINUX_FBDEV_RENDER_MODE + #define LV_LINUX_FBDEV_RENDER_MODE CONFIG_LV_LINUX_FBDEV_RENDER_MODE + #else + #define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL + #endif + #endif + #ifndef LV_LINUX_FBDEV_BUFFER_COUNT + #ifdef CONFIG_LV_LINUX_FBDEV_BUFFER_COUNT + #define LV_LINUX_FBDEV_BUFFER_COUNT CONFIG_LV_LINUX_FBDEV_BUFFER_COUNT + #else + #define LV_LINUX_FBDEV_BUFFER_COUNT 0 + #endif + #endif + #ifndef LV_LINUX_FBDEV_BUFFER_SIZE + #ifdef CONFIG_LV_LINUX_FBDEV_BUFFER_SIZE + #define LV_LINUX_FBDEV_BUFFER_SIZE CONFIG_LV_LINUX_FBDEV_BUFFER_SIZE + #else + #define LV_LINUX_FBDEV_BUFFER_SIZE 60 + #endif + #endif +#endif + +/** Use Nuttx to open window and handle touchscreen */ +#ifndef LV_USE_NUTTX + #ifdef CONFIG_LV_USE_NUTTX + #define LV_USE_NUTTX CONFIG_LV_USE_NUTTX + #else + #define LV_USE_NUTTX 0 + #endif +#endif + +#if LV_USE_NUTTX + #ifndef LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP + #ifdef CONFIG_LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP + #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP CONFIG_LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP + #else + #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP 0 + #endif + #endif + + #ifndef LV_USE_NUTTX_LIBUV + #ifdef CONFIG_LV_USE_NUTTX_LIBUV + #define LV_USE_NUTTX_LIBUV CONFIG_LV_USE_NUTTX_LIBUV + #else + #define LV_USE_NUTTX_LIBUV 0 + #endif + #endif + + /** Use Nuttx custom init API to open window and handle touchscreen */ + #ifndef LV_USE_NUTTX_CUSTOM_INIT + #ifdef CONFIG_LV_USE_NUTTX_CUSTOM_INIT + #define LV_USE_NUTTX_CUSTOM_INIT CONFIG_LV_USE_NUTTX_CUSTOM_INIT + #else + #define LV_USE_NUTTX_CUSTOM_INIT 0 + #endif + #endif + + /** Driver for /dev/lcd */ + #ifndef LV_USE_NUTTX_LCD + #ifdef CONFIG_LV_USE_NUTTX_LCD + #define LV_USE_NUTTX_LCD CONFIG_LV_USE_NUTTX_LCD + #else + #define LV_USE_NUTTX_LCD 0 + #endif + #endif + #if LV_USE_NUTTX_LCD + #ifndef LV_NUTTX_LCD_BUFFER_COUNT + #ifdef CONFIG_LV_NUTTX_LCD_BUFFER_COUNT + #define LV_NUTTX_LCD_BUFFER_COUNT CONFIG_LV_NUTTX_LCD_BUFFER_COUNT + #else + #define LV_NUTTX_LCD_BUFFER_COUNT 0 + #endif + #endif + #ifndef LV_NUTTX_LCD_BUFFER_SIZE + #ifdef CONFIG_LV_NUTTX_LCD_BUFFER_SIZE + #define LV_NUTTX_LCD_BUFFER_SIZE CONFIG_LV_NUTTX_LCD_BUFFER_SIZE + #else + #define LV_NUTTX_LCD_BUFFER_SIZE 60 + #endif + #endif + #endif + + /** Driver for /dev/input */ + #ifndef LV_USE_NUTTX_TOUCHSCREEN + #ifdef CONFIG_LV_USE_NUTTX_TOUCHSCREEN + #define LV_USE_NUTTX_TOUCHSCREEN CONFIG_LV_USE_NUTTX_TOUCHSCREEN + #else + #define LV_USE_NUTTX_TOUCHSCREEN 0 + #endif + #endif +#endif + +/** Driver for /dev/dri/card */ +#ifndef LV_USE_LINUX_DRM + #ifdef CONFIG_LV_USE_LINUX_DRM + #define LV_USE_LINUX_DRM CONFIG_LV_USE_LINUX_DRM + #else + #define LV_USE_LINUX_DRM 0 + #endif +#endif + +/** Interface for TFT_eSPI */ +#ifndef LV_USE_TFT_ESPI + #ifdef CONFIG_LV_USE_TFT_ESPI + #define LV_USE_TFT_ESPI CONFIG_LV_USE_TFT_ESPI + #else + #define LV_USE_TFT_ESPI 0 + #endif +#endif + +/** Driver for evdev input devices */ +#ifndef LV_USE_EVDEV + #ifdef CONFIG_LV_USE_EVDEV + #define LV_USE_EVDEV CONFIG_LV_USE_EVDEV + #else + #define LV_USE_EVDEV 0 + #endif +#endif + +/** Driver for libinput input devices */ +#ifndef LV_USE_LIBINPUT + #ifdef CONFIG_LV_USE_LIBINPUT + #define LV_USE_LIBINPUT CONFIG_LV_USE_LIBINPUT + #else + #define LV_USE_LIBINPUT 0 + #endif +#endif + +#if LV_USE_LIBINPUT + #ifndef LV_LIBINPUT_BSD + #ifdef CONFIG_LV_LIBINPUT_BSD + #define LV_LIBINPUT_BSD CONFIG_LV_LIBINPUT_BSD + #else + #define LV_LIBINPUT_BSD 0 + #endif + #endif + + /** Full keyboard support */ + #ifndef LV_LIBINPUT_XKB + #ifdef CONFIG_LV_LIBINPUT_XKB + #define LV_LIBINPUT_XKB CONFIG_LV_LIBINPUT_XKB + #else + #define LV_LIBINPUT_XKB 0 + #endif + #endif + #if LV_LIBINPUT_XKB + /** "setxkbmap -query" can help find the right values for your keyboard */ + #ifndef LV_LIBINPUT_XKB_KEY_MAP + #ifdef CONFIG_LV_LIBINPUT_XKB_KEY_MAP + #define LV_LIBINPUT_XKB_KEY_MAP CONFIG_LV_LIBINPUT_XKB_KEY_MAP + #else + #define LV_LIBINPUT_XKB_KEY_MAP { .rules = NULL, .model = "pc101", .layout = "us", .variant = NULL, .options = NULL } + #endif + #endif + #endif +#endif + +/* Drivers for LCD devices connected via SPI/parallel port */ +#ifndef LV_USE_ST7735 + #ifdef CONFIG_LV_USE_ST7735 + #define LV_USE_ST7735 CONFIG_LV_USE_ST7735 + #else + #define LV_USE_ST7735 0 + #endif +#endif +#ifndef LV_USE_ST7789 + #ifdef CONFIG_LV_USE_ST7789 + #define LV_USE_ST7789 CONFIG_LV_USE_ST7789 + #else + #define LV_USE_ST7789 0 + #endif +#endif +#ifndef LV_USE_ST7796 + #ifdef CONFIG_LV_USE_ST7796 + #define LV_USE_ST7796 CONFIG_LV_USE_ST7796 + #else + #define LV_USE_ST7796 0 + #endif +#endif +#ifndef LV_USE_ILI9341 + #ifdef CONFIG_LV_USE_ILI9341 + #define LV_USE_ILI9341 CONFIG_LV_USE_ILI9341 + #else + #define LV_USE_ILI9341 0 + #endif +#endif + +#ifndef LV_USE_GENERIC_MIPI + #ifdef CONFIG_LV_USE_GENERIC_MIPI + #define LV_USE_GENERIC_MIPI CONFIG_LV_USE_GENERIC_MIPI + #else + #define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) + #endif +#endif + +/** Driver for Renesas GLCD */ +#ifndef LV_USE_RENESAS_GLCDC + #ifdef CONFIG_LV_USE_RENESAS_GLCDC + #define LV_USE_RENESAS_GLCDC CONFIG_LV_USE_RENESAS_GLCDC + #else + #define LV_USE_RENESAS_GLCDC 0 + #endif +#endif + +/** Driver for ST LTDC */ +#ifndef LV_USE_ST_LTDC + #ifdef CONFIG_LV_USE_ST_LTDC + #define LV_USE_ST_LTDC CONFIG_LV_USE_ST_LTDC + #else + #define LV_USE_ST_LTDC 0 + #endif +#endif +#if LV_USE_ST_LTDC + /* Only used for partial. */ + #ifndef LV_ST_LTDC_USE_DMA2D_FLUSH + #ifdef CONFIG_LV_ST_LTDC_USE_DMA2D_FLUSH + #define LV_ST_LTDC_USE_DMA2D_FLUSH CONFIG_LV_ST_LTDC_USE_DMA2D_FLUSH + #else + #define LV_ST_LTDC_USE_DMA2D_FLUSH 0 + #endif + #endif +#endif + +/** LVGL Windows backend */ +#ifndef LV_USE_WINDOWS + #ifdef CONFIG_LV_USE_WINDOWS + #define LV_USE_WINDOWS CONFIG_LV_USE_WINDOWS + #else + #define LV_USE_WINDOWS 0 + #endif +#endif + +/** Use OpenGL to open window on PC and handle mouse and keyboard */ +#ifndef LV_USE_OPENGLES + #ifdef CONFIG_LV_USE_OPENGLES + #define LV_USE_OPENGLES CONFIG_LV_USE_OPENGLES + #else + #define LV_USE_OPENGLES 0 + #endif +#endif +#if LV_USE_OPENGLES + #ifndef LV_USE_OPENGLES_DEBUG + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_OPENGLES_DEBUG + #define LV_USE_OPENGLES_DEBUG CONFIG_LV_USE_OPENGLES_DEBUG + #else + #define LV_USE_OPENGLES_DEBUG 0 + #endif + #else + #define LV_USE_OPENGLES_DEBUG 1 /**< Enable or disable debug for opengles */ + #endif + #endif +#endif + +/** QNX Screen display and input drivers */ +#ifndef LV_USE_QNX + #ifdef CONFIG_LV_USE_QNX + #define LV_USE_QNX CONFIG_LV_USE_QNX + #else + #define LV_USE_QNX 0 + #endif +#endif +#if LV_USE_QNX + #ifndef LV_QNX_BUF_COUNT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_QNX_BUF_COUNT + #define LV_QNX_BUF_COUNT CONFIG_LV_QNX_BUF_COUNT + #else + #define LV_QNX_BUF_COUNT 0 + #endif + #else + #define LV_QNX_BUF_COUNT 1 /**< 1 or 2 */ + #endif + #endif +#endif + +/*================== +* EXAMPLES +*==================*/ + +/** Enable examples to be built with the library. */ +#ifndef LV_BUILD_EXAMPLES + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_BUILD_EXAMPLES + #define LV_BUILD_EXAMPLES CONFIG_LV_BUILD_EXAMPLES + #else + #define LV_BUILD_EXAMPLES 0 + #endif + #else + #define LV_BUILD_EXAMPLES 1 + #endif +#endif + +/*=================== + * DEMO USAGE + ====================*/ + +/** Show some widgets. This might be required to increase `LV_MEM_SIZE`. */ +#ifndef LV_USE_DEMO_WIDGETS + #ifdef CONFIG_LV_USE_DEMO_WIDGETS + #define LV_USE_DEMO_WIDGETS CONFIG_LV_USE_DEMO_WIDGETS + #else + #define LV_USE_DEMO_WIDGETS 0 + #endif +#endif + +/** Demonstrate usage of encoder and keyboard. */ +#ifndef LV_USE_DEMO_KEYPAD_AND_ENCODER + #ifdef CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER + #define LV_USE_DEMO_KEYPAD_AND_ENCODER CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER + #else + #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 + #endif +#endif + +/** Benchmark your system */ +#ifndef LV_USE_DEMO_BENCHMARK + #ifdef CONFIG_LV_USE_DEMO_BENCHMARK + #define LV_USE_DEMO_BENCHMARK CONFIG_LV_USE_DEMO_BENCHMARK + #else + #define LV_USE_DEMO_BENCHMARK 0 + #endif +#endif + +/** Render test for each primitive. + * - Requires at least 480x272 display. */ +#ifndef LV_USE_DEMO_RENDER + #ifdef CONFIG_LV_USE_DEMO_RENDER + #define LV_USE_DEMO_RENDER CONFIG_LV_USE_DEMO_RENDER + #else + #define LV_USE_DEMO_RENDER 0 + #endif +#endif + +/** Stress test for LVGL */ +#ifndef LV_USE_DEMO_STRESS + #ifdef CONFIG_LV_USE_DEMO_STRESS + #define LV_USE_DEMO_STRESS CONFIG_LV_USE_DEMO_STRESS + #else + #define LV_USE_DEMO_STRESS 0 + #endif +#endif + +/** Music player demo */ +#ifndef LV_USE_DEMO_MUSIC + #ifdef CONFIG_LV_USE_DEMO_MUSIC + #define LV_USE_DEMO_MUSIC CONFIG_LV_USE_DEMO_MUSIC + #else + #define LV_USE_DEMO_MUSIC 0 + #endif +#endif +#if LV_USE_DEMO_MUSIC + #ifndef LV_DEMO_MUSIC_SQUARE + #ifdef CONFIG_LV_DEMO_MUSIC_SQUARE + #define LV_DEMO_MUSIC_SQUARE CONFIG_LV_DEMO_MUSIC_SQUARE + #else + #define LV_DEMO_MUSIC_SQUARE 0 + #endif + #endif + #ifndef LV_DEMO_MUSIC_LANDSCAPE + #ifdef CONFIG_LV_DEMO_MUSIC_LANDSCAPE + #define LV_DEMO_MUSIC_LANDSCAPE CONFIG_LV_DEMO_MUSIC_LANDSCAPE + #else + #define LV_DEMO_MUSIC_LANDSCAPE 0 + #endif + #endif + #ifndef LV_DEMO_MUSIC_ROUND + #ifdef CONFIG_LV_DEMO_MUSIC_ROUND + #define LV_DEMO_MUSIC_ROUND CONFIG_LV_DEMO_MUSIC_ROUND + #else + #define LV_DEMO_MUSIC_ROUND 0 + #endif + #endif + #ifndef LV_DEMO_MUSIC_LARGE + #ifdef CONFIG_LV_DEMO_MUSIC_LARGE + #define LV_DEMO_MUSIC_LARGE CONFIG_LV_DEMO_MUSIC_LARGE + #else + #define LV_DEMO_MUSIC_LARGE 0 + #endif + #endif + #ifndef LV_DEMO_MUSIC_AUTO_PLAY + #ifdef CONFIG_LV_DEMO_MUSIC_AUTO_PLAY + #define LV_DEMO_MUSIC_AUTO_PLAY CONFIG_LV_DEMO_MUSIC_AUTO_PLAY + #else + #define LV_DEMO_MUSIC_AUTO_PLAY 0 + #endif + #endif +#endif + +/** Flex layout demo */ +#ifndef LV_USE_DEMO_FLEX_LAYOUT + #ifdef CONFIG_LV_USE_DEMO_FLEX_LAYOUT + #define LV_USE_DEMO_FLEX_LAYOUT CONFIG_LV_USE_DEMO_FLEX_LAYOUT + #else + #define LV_USE_DEMO_FLEX_LAYOUT 0 + #endif +#endif + +/** Smart-phone like multi-language demo */ +#ifndef LV_USE_DEMO_MULTILANG + #ifdef CONFIG_LV_USE_DEMO_MULTILANG + #define LV_USE_DEMO_MULTILANG CONFIG_LV_USE_DEMO_MULTILANG + #else + #define LV_USE_DEMO_MULTILANG 0 + #endif +#endif + +/** Widget transformation demo */ +#ifndef LV_USE_DEMO_TRANSFORM + #ifdef CONFIG_LV_USE_DEMO_TRANSFORM + #define LV_USE_DEMO_TRANSFORM CONFIG_LV_USE_DEMO_TRANSFORM + #else + #define LV_USE_DEMO_TRANSFORM 0 + #endif +#endif + +/** Demonstrate scroll settings */ +#ifndef LV_USE_DEMO_SCROLL + #ifdef CONFIG_LV_USE_DEMO_SCROLL + #define LV_USE_DEMO_SCROLL CONFIG_LV_USE_DEMO_SCROLL + #else + #define LV_USE_DEMO_SCROLL 0 + #endif +#endif + +/** Vector graphic demo */ +#ifndef LV_USE_DEMO_VECTOR_GRAPHIC + #ifdef CONFIG_LV_USE_DEMO_VECTOR_GRAPHIC + #define LV_USE_DEMO_VECTOR_GRAPHIC CONFIG_LV_USE_DEMO_VECTOR_GRAPHIC + #else + #define LV_USE_DEMO_VECTOR_GRAPHIC 0 + #endif +#endif + +/*E-bike demo with Lottie animations (if LV_USE_LOTTIE is enabled)*/ +#ifndef LV_USE_DEMO_EBIKE + #ifdef CONFIG_LV_USE_DEMO_EBIKE + #define LV_USE_DEMO_EBIKE CONFIG_LV_USE_DEMO_EBIKE + #else + #define LV_USE_DEMO_EBIKE 0 + #endif +#endif +#if LV_USE_DEMO_EBIKE + #ifndef LV_DEMO_EBIKE_PORTRAIT + #ifdef CONFIG_LV_DEMO_EBIKE_PORTRAIT + #define LV_DEMO_EBIKE_PORTRAIT CONFIG_LV_DEMO_EBIKE_PORTRAIT + #else + #define LV_DEMO_EBIKE_PORTRAIT 0 /*0: for 480x270..480x320, 1: for 480x800..720x1280*/ + #endif + #endif +#endif + + + +/*---------------------------------- + * End of parsing lv_conf_template.h + -----------------------------------*/ + +#ifndef __ASSEMBLY__ +LV_EXPORT_CONST_INT(LV_DPI_DEF); +LV_EXPORT_CONST_INT(LV_DRAW_BUF_STRIDE_ALIGN); +LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); +#endif + +#undef LV_KCONFIG_PRESENT + +/* Set some defines if a dependency is disabled. */ +#if LV_USE_LOG == 0 + #define LV_LOG_LEVEL LV_LOG_LEVEL_NONE + #define LV_LOG_TRACE_MEM 0 + #define LV_LOG_TRACE_TIMER 0 + #define LV_LOG_TRACE_INDEV 0 + #define LV_LOG_TRACE_DISP_REFR 0 + #define LV_LOG_TRACE_EVENT 0 + #define LV_LOG_TRACE_OBJ_CREATE 0 + #define LV_LOG_TRACE_LAYOUT 0 + #define LV_LOG_TRACE_ANIM 0 +#endif /*LV_USE_LOG*/ + +#if LV_USE_SYSMON == 0 + #define LV_USE_PERF_MONITOR 0 + #define LV_USE_MEM_MONITOR 0 +#endif /*LV_USE_SYSMON*/ + +#ifndef LV_USE_LZ4 + #define LV_USE_LZ4 (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL) +#endif + +#ifndef LV_USE_THORVG + #define LV_USE_THORVG (LV_USE_THORVG_INTERNAL || LV_USE_THORVG_EXTERNAL) +#endif + +#if LV_USE_OS + #if (LV_USE_FREETYPE || LV_USE_THORVG) && LV_DRAW_THREAD_STACK_SIZE < (32 * 1024) + #warning "Increase LV_DRAW_THREAD_STACK_SIZE to at least 32KB for FreeType or ThorVG." + #endif + + #if defined(LV_DRAW_THREAD_STACKSIZE) && !defined(LV_DRAW_THREAD_STACK_SIZE) + #warning "LV_DRAW_THREAD_STACKSIZE was renamed to LV_DRAW_THREAD_STACK_SIZE. Please update lv_conf.h or run menuconfig again." + #define LV_DRAW_THREAD_STACK_SIZE LV_DRAW_THREAD_STACKSIZE + #endif +#endif + +/* If running without lv_conf.h, add typedefs with default value. */ +#ifdef LV_CONF_SKIP + #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /*Disable warnings for Visual Studio*/ + #define _CRT_SECURE_NO_WARNINGS + #endif +#endif /*defined(LV_CONF_SKIP)*/ + +#endif /*LV_CONF_INTERNAL_H*/ diff --git a/test/include/liblvgl/lv_conf_kconfig.h b/test/include/liblvgl/lv_conf_kconfig.h new file mode 100644 index 00000000..44e76959 --- /dev/null +++ b/test/include/liblvgl/lv_conf_kconfig.h @@ -0,0 +1,266 @@ +/** * @file lv_conf_kconfig.h * Configs that need special handling when LVGL is used with Kconfig */ + +#ifndef LV_CONF_KCONFIG_H +#define LV_CONF_KCONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef LV_CONF_KCONFIG_EXTERNAL_INCLUDE +# include LV_CONF_KCONFIG_EXTERNAL_INCLUDE +#else + +# ifdef ESP_PLATFORM +# include "sdkconfig.h" +# include "esp_attr.h" +# endif + +# ifdef __NuttX__ +# include +/* + * Make sure version number in Kconfig file is correctly set. + * Mismatch can happen when user manually copy lvgl/Kconfig file to their project, like what NuttX does. + */ +# include "../lv_version.h" + +# if CONFIG_LVGL_VERSION_MAJOR != LVGL_VERSION_MAJOR || CONFIG_LVGL_VERSION_MINOR != LVGL_VERSION_MINOR \ + || CONFIG_LVGL_VERSION_PATCH != LVGL_VERSION_PATCH +# warning "Version mismatch between Kconfig and lvgl/lv_version.h" +# endif +# elif defined(__RTTHREAD__) +# define LV_CONF_INCLUDE_SIMPLE +# include +# endif + +#endif /*LV_CONF_KCONFIG_EXTERNAL_INCLUDE*/ + +/******************* + * LV_USE_STDLIB_MALLOC + *******************/ + +#ifdef CONFIG_LV_USE_BUILTIN_MALLOC +# define CONFIG_LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN +#elif defined(CONFIG_LV_USE_CLIB_MALLOC) +# define CONFIG_LV_USE_STDLIB_MALLOC LV_STDLIB_CLIB +#elif defined(CONFIG_LV_USE_MICROPYTHON_MALLOC) +# define CONFIG_LV_USE_STDLIB_MALLOC LV_STDLIB_MICROPYTHON +#elif defined(CONFIG_LV_USE_RTTHREAD_MALLOC) +# define CONFIG_LV_USE_STDLIB_MALLOC LV_STDLIB_RTTHREAD +#elif defined (CONFIG_LV_USE_CUSTOM_MALLOC) +# define CONFIG_LV_USE_STDLIB_MALLOC LV_STDLIB_CUSTOM +#endif + +/******************* + * LV_USE_STDLIB_STRING + *******************/ + +#ifdef CONFIG_LV_USE_BUILTIN_STRING +# define CONFIG_LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN +#elif defined(CONFIG_LV_USE_CLIB_STRING) +# define CONFIG_LV_USE_STDLIB_STRING LV_STDLIB_CLIB +#elif defined(CONFIG_LV_USE_MICROPYTHON_STRING) +# define CONFIG_LV_USE_STDLIB_STRING LV_STDLIB_MICROPYTHON +#elif defined(CONFIG_LV_USE_RTTHREAD_STRING) +# define CONFIG_LV_USE_STDLIB_STRING LV_STDLIB_RTTHREAD +#elif defined (CONFIG_LV_USE_CUSTOM_STRING) +# define CONFIG_LV_USE_STDLIB_STRING LV_STDLIB_CUSTOM +#endif + +/******************* + * LV_USE_STDLIB_SPRINTF + *******************/ + +#ifdef CONFIG_LV_USE_BUILTIN_SPRINTF +# define CONFIG_LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN +#elif defined(CONFIG_LV_USE_CLIB_SPRINTF) +# define CONFIG_LV_USE_STDLIB_SPRINTF LV_STDLIB_CLIB +#elif defined(CONFIG_LV_USE_MICROPYTHON_SPRINTF) +# define CONFIG_LV_USE_STDLIB_SPRINTF LV_STDLIB_MICROPYTHON +#elif defined(CONFIG_LV_USE_RTTHREAD_SPRINTF) +# define CONFIG_LV_USE_STDLIB_SPRINTF LV_STDLIB_RTTHREAD +#elif defined (CONFIG_LV_USE_CUSTOM_SPRINTF) +# define CONFIG_LV_USE_STDLIB_SPRINTF LV_STDLIB_CUSTOM +#endif + +/******************* + * LV_MEM_SIZE + *******************/ + +#ifdef CONFIG_LV_MEM_SIZE_KILOBYTES +# if(CONFIG_LV_MEM_SIZE_KILOBYTES < 2) +# error "LV_MEM_SIZE >= 2kB is required" +# endif + +# define CONFIG_LV_MEM_SIZE (CONFIG_LV_MEM_SIZE_KILOBYTES * 1024U) +#endif + +#ifdef CONFIG_LV_MEM_POOL_EXPAND_SIZE_KILOBYTES +# define CONFIG_LV_MEM_POOL_EXPAND_SIZE (CONFIG_LV_MEM_POOL_EXPAND_SIZE_KILOBYTES * 1024U) +#endif + +/*------------------ + * MONITOR POSITION + *-----------------*/ + +#ifdef CONFIG_LV_PERF_MONITOR_ALIGN_TOP_LEFT +# define CONFIG_LV_USE_PERF_MONITOR_POS LV_ALIGN_TOP_LEFT +#elif defined(CONFIG_LV_USE_PERF_MONITOR_ALIGN_TOP_MID) +# define CONFIG_LV_USE_PERF_MONITOR_POS LV_ALIGN_TOP_MID +#elif defined(CONFIG_LV_PERF_MONITOR_ALIGN_TOP_RIGHT) +# define CONFIG_LV_USE_PERF_MONITOR_POS LV_ALIGN_TOP_RIGHT +#elif defined(CONFIG_LV_PERF_MONITOR_ALIGN_BOTTOM_LEFT) +# define CONFIG_LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_LEFT +#elif defined(CONFIG_LV_PERF_MONITOR_ALIGN_BOTTOM_MID) +# define CONFIG_LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_MID +#elif defined(CONFIG_LV_PERF_MONITOR_ALIGN_BOTTOM_RIGHT) +# define CONFIG_LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT +#elif defined(CONFIG_LV_PERF_MONITOR_ALIGN_LEFT_MID) +# define CONFIG_LV_USE_PERF_MONITOR_POS LV_ALIGN_LEFT_MID +#elif defined(CONFIG_LV_PERF_MONITOR_ALIGN_RIGHT_MID) +# define CONFIG_LV_USE_PERF_MONITOR_POS LV_ALIGN_RIGHT_MID +#elif defined(CONFIG_LV_PERF_MONITOR_ALIGN_CENTER) +# define CONFIG_LV_USE_PERF_MONITOR_POS LV_ALIGN_CENTER +#endif + +#ifdef CONFIG_LV_MEM_MONITOR_ALIGN_TOP_LEFT +# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_TOP_LEFT +#elif defined(CONFIG_LV_USE_MEM_MONITOR_ALIGN_TOP_MID) +# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_TOP_MID +#elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_TOP_RIGHT) +# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_TOP_RIGHT +#elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_BOTTOM_LEFT) +# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT +#elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_BOTTOM_MID) +# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_MID +#elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_BOTTOM_RIGHT) +# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT +#elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_LEFT_MID) +# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_LEFT_MID +#elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_RIGHT_MID) +# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_RIGHT_MID +#elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_CENTER) +# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_CENTER +#endif + +/******************** + * FONT SELECTION + *******************/ + +/** + * NOTE: In Kconfig instead of `LV_DEFAULT_FONT` + * `CONFIG_LV_FONT_DEFAULT_` is defined + * hence the large selection with if-s + */ + +/*------------------ + * DEFAULT FONT + *-----------------*/ +#ifdef CONFIG_LV_FONT_DEFAULT_MONTSERRAT_8 +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_8 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_10) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_10 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_12) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_12 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_14) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_14 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_16) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_16 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_18) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_18 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_20) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_20 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_22) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_22 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_24) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_24 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_26) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_26 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_28) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_28 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_30) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_30 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_32) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_32 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_34) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_34 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_36) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_36 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_38) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_38 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_40) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_40 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_42) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_42 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_44) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_44 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_46) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_46 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_48) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_48 +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_12_SUBPX) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_12_subpx +#elif defined(CONFIG_LV_FONT_DEFAULT_MONTSERRAT_28_COMPRESSED) +# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_28_compressed +#elif defined(CONFIG_LV_FONT_DEFAULT_DEJAVU_16_PERSIAN_HEBREW) +# define CONFIG_LV_FONT_DEFAULT &lv_font_dejavu_16_persian_hebrew +#elif defined(CONFIG_LV_FONT_DEFAULT_SIMSUN_14_CJK) +# define CONFIG_LV_FONT_DEFAULT &lv_font_simsun_14_cjk +#elif defined(CONFIG_LV_FONT_DEFAULT_SIMSUN_16_CJK) +# define CONFIG_LV_FONT_DEFAULT &lv_font_simsun_16_cjk +#elif defined(CONFIG_LV_FONT_DEFAULT_UNSCII_8) +# define CONFIG_LV_FONT_DEFAULT &lv_font_unscii_8 +#elif defined(CONFIG_LV_FONT_DEFAULT_UNSCII_16) +# define CONFIG_LV_FONT_DEFAULT &lv_font_unscii_16 +#endif + +/*------------------ + * TEXT ENCODING + *-----------------*/ +#ifdef CONFIG_LV_TXT_ENC_UTF8 +# define CONFIG_LV_TXT_ENC LV_TXT_ENC_UTF8 +#elif defined(CONFIG_LV_TXT_ENC_ASCII) +# define CONFIG_LV_TXT_ENC LV_TXT_ENC_ASCII +#endif + +/*------------------ + * BIDI DIRECTION + *-----------------*/ + +#ifdef CONFIG_LV_BASE_DIR_LTR +# define CONFIG_LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_LTR +#elif defined(CONFIG_LV_BASE_DIR_RTL) +# define CONFIG_LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_RTL +#elif defined(CONFIG_LV_BASE_DIR_AUTO) +# define CONFIG_LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO +#endif + +/*------------------ + * SDL + *-----------------*/ + +#ifdef CONFIG_LV_SDL_RENDER_MODE_PARTIAL +# define CONFIG_LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL +#elif defined(CONFIG_LV_SDL_RENDER_MODE_DIRECT) +# define CONFIG_LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT +#elif defined(CONFIG_LV_SDL_RENDER_MODE_FULL) +# define CONFIG_LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_FULL +#endif + +/*------------------ + * LINUX FBDEV + *-----------------*/ + +#ifdef CONFIG_LV_LINUX_FBDEV_RENDER_MODE_PARTIAL +# define CONFIG_LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL +#elif defined(CONFIG_LV_LINUX_FBDEV_RENDER_MODE_DIRECT) +# define CONFIG_LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT +#elif defined(CONFIG_LV_LINUX_FBDEV_RENDER_MODE_FULL) +# define CONFIG_LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_FULL +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CONF_KCONFIG_H*/ \ No newline at end of file diff --git a/test/include/liblvgl/lv_init.h b/test/include/liblvgl/lv_init.h new file mode 100644 index 00000000..0815142c --- /dev/null +++ b/test/include/liblvgl/lv_init.h @@ -0,0 +1,55 @@ +/** + * @file lv_init.h + * + */ + +#ifndef LV_INIT_H +#define LV_INIT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_conf_internal.h" +#include "misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize LVGL library. + * Should be called before any other LVGL related function. + */ +void lv_init(void); + +/** + * Deinit the 'lv' library + */ +void lv_deinit(void); + +/** + * Returns whether the 'lv' library is currently initialized + */ +bool lv_is_initialized(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_INIT_H*/ diff --git a/test/include/liblvgl/lv_version.h b/test/include/liblvgl/lv_version.h new file mode 100644 index 00000000..b3a4ac7d --- /dev/null +++ b/test/include/liblvgl/lv_version.h @@ -0,0 +1,66 @@ +/** + * @file lv_version.h + * + */ + +#ifndef LV_VERSION_H +#define LV_VERSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +/*Current version of LittlevGL*/ +#define LVGL_VERSION_MAJOR 9 +#define LVGL_VERSION_MINOR 2 +#define LVGL_VERSION_PATCH 0 +#define LVGL_VERSION_INFO "" + + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ +/* Gives 1 if the x.y.z version is supported in the current version + * Usage: + * + * - Require v6 + * #if LV_VERSION_CHECK(6,0,0) + * new_func_in_v6(); + * #endif + * + * + * - Require at least v5.3 + * #if LV_VERSION_CHECK(5,3,0) + * new_feature_from_v5_3(); + * #endif + * + * + * - Require v5.3.2 bugfixes + * #if LV_VERSION_CHECK(5,3,2) + * bugfix_in_v5_3_2(); + * #endif + * + * */ +#define LV_VERSION_CHECK(x,y,z) (x == LVGL_VERSION_MAJOR && (y < LVGL_VERSION_MINOR || (y == LVGL_VERSION_MINOR && z <= LVGL_VERSION_PATCH))) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_VERSION_H*/ diff --git a/test/include/liblvgl/lvgl.h b/test/include/liblvgl/lvgl.h new file mode 100644 index 00000000..9a6653b9 --- /dev/null +++ b/test/include/liblvgl/lvgl.h @@ -0,0 +1,195 @@ +/** + * @file lvgl.h + * Include all LVGL related headers + */ + +#ifndef LVGL_H +#define LVGL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************** + * CURRENT VERSION OF LVGL + ***************************/ +#include "lv_version.h" + +/********************* + * INCLUDES + *********************/ +#include "lvgl_private.h" +#include "liblvgl/lv_init.h" + +#include "liblvgl/stdlib/lv_mem.h" +#include "liblvgl/stdlib/lv_string.h" +#include "liblvgl/stdlib/lv_sprintf.h" + +#include "liblvgl/misc/lv_log.h" +#include "liblvgl/misc/lv_timer.h" +#include "liblvgl/misc/lv_math.h" +#include "liblvgl/misc/lv_array.h" +#include "liblvgl/misc/lv_async.h" +#include "liblvgl/misc/lv_anim_timeline.h" +#include "liblvgl/misc/lv_profiler_builtin.h" +#include "liblvgl/misc/lv_rb.h" +#include "liblvgl/misc/lv_utils.h" + +#include "liblvgl/tick/lv_tick.h" + +#include "liblvgl/core/lv_obj.h" +#include "liblvgl/core/lv_group.h" +#include "liblvgl/indev/lv_indev.h" +#include "liblvgl/core/lv_refr.h" +#include "liblvgl/display/lv_display.h" + +#include "liblvgl/font/lv_font.h" +#include "liblvgl/font/lv_binfont_loader.h" +#include "liblvgl/font/lv_font_fmt_txt.h" + +#include "liblvgl/widgets/animimage/lv_animimage.h" +#include "liblvgl/widgets/arc/lv_arc.h" +#include "liblvgl/widgets/bar/lv_bar.h" +#include "liblvgl/widgets/button/lv_button.h" +#include "liblvgl/widgets/buttonmatrix/lv_buttonmatrix.h" +#include "liblvgl/widgets/calendar/lv_calendar.h" +#include "liblvgl/widgets/canvas/lv_canvas.h" +#include "liblvgl/widgets/chart/lv_chart.h" +#include "liblvgl/widgets/checkbox/lv_checkbox.h" +#include "liblvgl/widgets/dropdown/lv_dropdown.h" +#include "liblvgl/widgets/image/lv_image.h" +#include "liblvgl/widgets/imagebutton/lv_imagebutton.h" +#include "liblvgl/widgets/keyboard/lv_keyboard.h" +#include "liblvgl/widgets/label/lv_label.h" +#include "liblvgl/widgets/led/lv_led.h" +#include "liblvgl/widgets/line/lv_line.h" +#include "liblvgl/widgets/list/lv_list.h" +#include "liblvgl/widgets/lottie/lv_lottie.h" +#include "liblvgl/widgets/menu/lv_menu.h" +#include "liblvgl/widgets/msgbox/lv_msgbox.h" +#include "liblvgl/widgets/roller/lv_roller.h" +#include "liblvgl/widgets/scale/lv_scale.h" +#include "liblvgl/widgets/slider/lv_slider.h" +#include "liblvgl/widgets/span/lv_span.h" +#include "liblvgl/widgets/spinbox/lv_spinbox.h" +#include "liblvgl/widgets/spinner/lv_spinner.h" +#include "liblvgl/widgets/switch/lv_switch.h" +#include "liblvgl/widgets/table/lv_table.h" +#include "liblvgl/widgets/tabview/lv_tabview.h" +#include "liblvgl/widgets/textarea/lv_textarea.h" +#include "liblvgl/widgets/tileview/lv_tileview.h" +#include "liblvgl/widgets/win/lv_win.h" + +#include "liblvgl/others/snapshot/lv_snapshot.h" +#include "liblvgl/others/sysmon/lv_sysmon.h" +#include "liblvgl/others/monkey/lv_monkey.h" +#include "liblvgl/others/gridnav/lv_gridnav.h" +#include "liblvgl/others/fragment/lv_fragment.h" +#include "liblvgl/others/imgfont/lv_imgfont.h" +#include "liblvgl/others/observer/lv_observer.h" +#include "liblvgl/others/ime/lv_ime_pinyin.h" +#include "liblvgl/others/file_explorer/lv_file_explorer.h" + +#include "liblvgl/libs/barcode/lv_barcode.h" +#include "liblvgl/libs/bin_decoder/lv_bin_decoder.h" +#include "liblvgl/libs/bmp/lv_bmp.h" +#include "liblvgl/libs/rle/lv_rle.h" +#include "liblvgl/libs/fsdrv/lv_fsdrv.h" +#include "liblvgl/libs/lodepng/lv_lodepng.h" +#include "liblvgl/libs/libpng/lv_libpng.h" +#include "liblvgl/libs/gif/lv_gif.h" +#include "liblvgl/libs/qrcode/lv_qrcode.h" +#include "liblvgl/libs/tjpgd/lv_tjpgd.h" +#include "liblvgl/libs/libjpeg_turbo/lv_libjpeg_turbo.h" +#include "liblvgl/libs/freetype/lv_freetype.h" +#include "liblvgl/libs/rlottie/lv_rlottie.h" +#include "liblvgl/libs/ffmpeg/lv_ffmpeg.h" +#include "liblvgl/libs/tiny_ttf/lv_tiny_ttf.h" + +#include "liblvgl/layouts/lv_layout.h" + +#include "liblvgl/draw/lv_draw.h" +#include "liblvgl/draw/lv_draw_buf.h" +#include "liblvgl/draw/lv_draw_vector.h" +#include "liblvgl/draw/sw/lv_draw_sw.h" + +#include "liblvgl/themes/lv_theme.h" + +#include "liblvgl/drivers/lv_drivers.h" + +// #include "liblvgl/lv_api_map_v8.h" +#include "liblvgl/lv_api_map_v9_0.h" +#include "liblvgl/lv_api_map_v9_1.h" + +#if LV_USE_PRIVATE_API +#include "liblvgl/lvgl_private.h" +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +/** Gives 1 if the x.y.z version is supported in the current version + * Usage: + * + * - Require v6 + * #if LV_VERSION_CHECK(6,0,0) + * new_func_in_v6(); + * #endif + * + * + * - Require at least v5.3 + * #if LV_VERSION_CHECK(5,3,0) + * new_feature_from_v5_3(); + * #endif + * + * + * - Require v5.3.2 bugfixes + * #if LV_VERSION_CHECK(5,3,2) + * bugfix_in_v5_3_2(); + * #endif + * + */ +#define LV_VERSION_CHECK(x,y,z) (x == LVGL_VERSION_MAJOR && (y < LVGL_VERSION_MINOR || (y == LVGL_VERSION_MINOR && z <= LVGL_VERSION_PATCH))) + +/** + * Wrapper functions for VERSION macros + */ + +static inline int lv_version_major(void) +{ + return LVGL_VERSION_MAJOR; +} + +static inline int lv_version_minor(void) +{ + return LVGL_VERSION_MINOR; +} + +static inline int lv_version_patch(void) +{ + return LVGL_VERSION_PATCH; +} + +static inline const char * lv_version_info(void) +{ + return LVGL_VERSION_INFO; +} + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LVGL_H*/ \ No newline at end of file diff --git a/test/include/liblvgl/lvgl_private.h b/test/include/liblvgl/lvgl_private.h new file mode 100644 index 00000000..8ab64e97 --- /dev/null +++ b/test/include/liblvgl/lvgl_private.h @@ -0,0 +1,125 @@ +/** + * @file lvgl_private.h + * + */ + +#ifndef LVGL_PRIVATE_H +#define LVGL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "core/lv_global.h" + +#include "display/lv_display_private.h" +#include "indev/lv_indev_private.h" +#include "misc/lv_text_private.h" +#include "misc/cache/lv_cache_entry_private.h" +#include "misc/cache/lv_cache_private.h" +#include "layouts/lv_layout_private.h" +#include "stdlib/lv_mem_private.h" +#include "others/file_explorer/lv_file_explorer_private.h" +#include "others/sysmon/lv_sysmon_private.h" +#include "others/monkey/lv_monkey_private.h" +#include "others/ime/lv_ime_pinyin_private.h" +#include "others/fragment/lv_fragment_private.h" +#include "others/observer/lv_observer_private.h" +#include "libs/qrcode/lv_qrcode_private.h" +#include "libs/barcode/lv_barcode_private.h" +#include "libs/gif/lv_gif_private.h" +#include "draw/lv_draw_triangle_private.h" +#include "draw/lv_draw_private.h" +#include "draw/lv_draw_rect_private.h" +#include "draw/lv_draw_image_private.h" +#include "draw/lv_image_decoder_private.h" +#include "draw/lv_draw_label_private.h" +#include "draw/lv_draw_vector_private.h" +#include "draw/lv_draw_buf_private.h" +#include "draw/lv_draw_mask_private.h" +#include "draw/sw/lv_draw_sw_gradient_private.h" +#include "draw/sw/lv_draw_sw_private.h" +#include "draw/sw/lv_draw_sw_mask_private.h" +#include "draw/sw/blend/lv_draw_sw_blend_private.h" +#include "drivers/libinput/lv_xkb_private.h" +#include "drivers/libinput/lv_libinput_private.h" +#include "font/lv_font_fmt_txt_private.h" +#include "themes/lv_theme_private.h" +#include "core/lv_refr_private.h" +#include "core/lv_obj_style_private.h" +#include "core/lv_obj_private.h" +#include "core/lv_obj_scroll_private.h" +#include "core/lv_obj_draw_private.h" +#include "core/lv_obj_class_private.h" +#include "core/lv_group_private.h" +#include "core/lv_obj_event_private.h" +#include "misc/lv_timer_private.h" +#include "misc/lv_area_private.h" +#include "misc/lv_fs_private.h" +#include "misc/lv_profiler_builtin_private.h" +#include "misc/lv_event_private.h" +#include "misc/lv_bidi_private.h" +#include "misc/lv_rb_private.h" +#include "misc/lv_style_private.h" +#include "misc/lv_color_op_private.h" +#include "misc/lv_anim_private.h" +#include "widgets/msgbox/lv_msgbox_private.h" +#include "widgets/buttonmatrix/lv_buttonmatrix_private.h" +#include "widgets/slider/lv_slider_private.h" +#include "widgets/switch/lv_switch_private.h" +#include "widgets/calendar/lv_calendar_private.h" +#include "widgets/imagebutton/lv_imagebutton_private.h" +#include "widgets/bar/lv_bar_private.h" +#include "widgets/image/lv_image_private.h" +#include "widgets/textarea/lv_textarea_private.h" +#include "widgets/table/lv_table_private.h" +#include "widgets/checkbox/lv_checkbox_private.h" +#include "widgets/roller/lv_roller_private.h" +#include "widgets/win/lv_win_private.h" +#include "widgets/keyboard/lv_keyboard_private.h" +#include "widgets/line/lv_line_private.h" +#include "widgets/animimage/lv_animimage_private.h" +#include "widgets/dropdown/lv_dropdown_private.h" +#include "widgets/menu/lv_menu_private.h" +#include "widgets/chart/lv_chart_private.h" +#include "widgets/button/lv_button_private.h" +#include "widgets/scale/lv_scale_private.h" +#include "widgets/led/lv_led_private.h" +#include "widgets/arc/lv_arc_private.h" +#include "widgets/tileview/lv_tileview_private.h" +#include "widgets/spinbox/lv_spinbox_private.h" +#include "widgets/span/lv_span_private.h" +#include "widgets/label/lv_label_private.h" +#include "widgets/canvas/lv_canvas_private.h" +#include "widgets/tabview/lv_tabview_private.h" +#include "tick/lv_tick_private.h" +#include "stdlib/builtin/lv_tlsf_private.h" +#include "libs/rlottie/lv_rlottie_private.h" +#include "libs/ffmpeg/lv_ffmpeg_private.h" +#include "widgets/lottie/lv_lottie_private.h" +#include "osal/lv_os_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LVGL_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/cache/lv_cache.h b/test/include/liblvgl/misc/cache/lv_cache.h new file mode 100644 index 00000000..0271c87f --- /dev/null +++ b/test/include/liblvgl/misc/cache/lv_cache.h @@ -0,0 +1,237 @@ +/** + * @file lv_cache.h + * + */ + +#ifndef LV_CACHE_H +#define LV_CACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_cache_entry.h" +#include "lv_cache_private.h" +#include "../lv_types.h" + +#include "lv_cache_lru_rb.h" + +#include "lv_image_cache.h" +#include "lv_image_header_cache.h" +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a cache object with the given parameters. + * @param cache_class The class of the cache. Currently only support one two builtin classes: + * - lv_cache_class_lru_rb_count for LRU-based cache with count-based eviction policy. + * - lv_cache_class_lru_rb_size for LRU-based cache with size-based eviction policy. + * @param node_size The node size is the size of the data stored in the cache.. + * @param max_size The max size is the maximum amount of memory or count that the cache can hold. + * - lv_cache_class_lru_rb_count: max_size is the maximum count of nodes in the cache. + * - lv_cache_class_lru_rb_size: max_size is the maximum size of the cache in bytes. + * @param ops A set of operations that can be performed on the cache. See lv_cache_ops_t for details. + * @return Returns a pointer to the created cache object on success, `NULL` on error. + */ +lv_cache_t * lv_cache_create(const lv_cache_class_t * cache_class, + size_t node_size, size_t max_size, + lv_cache_ops_t ops); + +/** + * Destroy a cache object. + * @param cache The cache object pointer to destroy. + * @param user_data A user data pointer that will be passed to the free callback. + */ +void lv_cache_destroy(lv_cache_t * cache, void * user_data); + +/** + * Acquire a cache entry with the given key. If entry not in cache, it will return `NULL` (not found). + * If the entry is found, it's priority will be changed by the cache's policy. And the `lv_cache_entry_t::ref_cnt` will be incremented. + * @param cache The cache object pointer to acquire the entry. + * @param key The key of the entry to acquire. + * @param user_data A user data pointer that will be passed to the create callback. + * @return Returns a pointer to the acquired cache entry on success with `lv_cache_entry_t::ref_cnt` incremented, `NULL` on error. + */ +lv_cache_entry_t * lv_cache_acquire(lv_cache_t * cache, const void * key, void * user_data); + +/** + * Acquire a cache entry with the given key. If the entry is not in the cache, it will create a new entry with the given key. + * If the entry is found, it's priority will be changed by the cache's policy. And the `lv_cache_entry_t::ref_cnt` will be incremented. + * If you want to use this API to simplify the code, you should provide a `lv_cache_ops_t::create_cb` that creates a new entry with the given key. + * This API is a combination of lv_cache_acquire() and lv_cache_add(). The effect is the same as calling lv_cache_acquire() and lv_cache_add() separately. + * And the internal impact on cache is also consistent with these two APIs. + * @param cache The cache object pointer to acquire the entry. + * @param key The key of the entry to acquire or create. + * @param user_data A user data pointer that will be passed to the create callback. + * @return Returns a pointer to the acquired or created cache entry on success with `lv_cache_entry_t::ref_cnt` incremented, `NULL` on error. + */ +lv_cache_entry_t * lv_cache_acquire_or_create(lv_cache_t * cache, const void * key, void * user_data); + +/** + * Add a new cache entry with the given key and data. If the cache is full, the cache's policy will be used to evict an entry. + * @param cache The cache object pointer to add the entry. + * @param key The key of the entry to add. + * @param user_data A user data pointer that will be passed to the create callback. + * @return Returns a pointer to the added cache entry on success with `lv_cache_entry_t::ref_cnt` incremented, `NULL` on error. + */ +lv_cache_entry_t * lv_cache_add(lv_cache_t * cache, const void * key, void * user_data); + +/** + * Release a cache entry. The `lv_cache_entry_t::ref_cnt` will be decremented. If the `lv_cache_entry_t::ref_cnt` is zero, it will issue an error. + * If the entry passed to this function is the last reference to the data and the entry is marked as invalid, the cache's policy will be used to evict the entry. + * @param cache The cache object pointer to release the entry. + * @param entry The cache entry pointer to release. + * @param user_data A user data pointer that will be passed to the free callback. + */ +void lv_cache_release(lv_cache_t * cache, lv_cache_entry_t * entry, void * user_data); + +/** + * Reserve a certain amount of memory/count in the cache. This function is useful when you want to reserve a certain amount of memory/count in advance, + * for example, when you know that you will need it later. + * When the current cache size is max than the reserved size, the function will evict entries until the reserved size is reached. + * @param cache The cache object pointer to reserve. + * @param reserved_size The amount of memory/count to reserve. + * @param user_data A user data pointer that will be passed to the free callback. + */ +void lv_cache_reserve(lv_cache_t * cache, uint32_t reserved_size, void * user_data); + +/** + * Drop a cache entry with the given key. If the entry is not in the cache, nothing will happen to it. + * If the entry is found, it will be removed from the cache and its data will be freed when the last reference to it is released. + * @note The data will not be freed immediately but when the last reference to it is released. But this entry will not be found by lv_cache_acquire(). + * If you want cache a same key again, you should use lv_cache_add() or lv_cache_acquire_or_create(). + * @param cache The cache object pointer to drop the entry. + * @param key The key of the entry to drop. + * @param user_data A user data pointer that will be passed to the free callback. + */ +void lv_cache_drop(lv_cache_t * cache, const void * key, void * user_data); + +/** + * Drop all cache entries. All entries will be removed from the cache and their data will be freed when the last reference to them is released. + * @note If some entries are still referenced by other objects, it will issue an error. And this case shouldn't happen in normal cases.. + * @param cache The cache object pointer to drop all entries. + * @param user_data A user data pointer that will be passed to the free callback. + */ +void lv_cache_drop_all(lv_cache_t * cache, void * user_data); + +/** + * Evict one entry from the cache. The eviction policy will be used to select the entry to evict. + * @param cache The cache object pointer to evict an entry. + * @param user_data A user data pointer that will be passed to the free callback. + * @return Returns true if an entry is evicted, false if no entry is evicted. + */ +bool lv_cache_evict_one(lv_cache_t * cache, void * user_data); + +/** + * Set the maximum size of the cache. + * If the current cache size is greater than the new maximum size, the cache's policy will be used to evict entries until the new maximum size is reached. + * If set to 0, the cache will be disabled. + * @note But this behavior will happen only new entries are added to the cache. + * @param cache The cache object pointer to set the maximum size. + * @param max_size The new maximum size of the cache. + * @param user_data A user data pointer that will be passed to the free callback. + */ +void lv_cache_set_max_size(lv_cache_t * cache, size_t max_size, void * user_data); + +/** + * Get the maximum size of the cache. + * @param cache The cache object pointer to get the maximum size. + * @param user_data A user data pointer that will be passed to the free callback. + * @return Returns the maximum size of the cache. + */ +size_t lv_cache_get_max_size(lv_cache_t * cache, void * user_data); + +/** + * Get the current size of the cache. + * @param cache The cache object pointer to get the current size. + * @param user_data A user data pointer that will be passed to the free callback. + * @return Returns the current size of the cache. + */ +size_t lv_cache_get_size(lv_cache_t * cache, void * user_data); + +/** + * Get the free size of the cache. + * @param cache The cache object pointer to get the free size. + * @param user_data A user data pointer that will be passed to the free callback. + * @return Returns the free size of the cache. + */ +size_t lv_cache_get_free_size(lv_cache_t * cache, void * user_data); + +/** + * Return true if the cache is enabled. + * Disabled cache means that when the max_size of the cache is 0. In this case, all cache operations will be no-op. + * @param cache The cache object pointer to check if it's disabled. + * @return Returns true if the cache is enabled, false otherwise. + */ +bool lv_cache_is_enabled(lv_cache_t * cache); + +/** + * Set the compare callback of the cache. + * @param cache The cache object pointer to set the compare callback. + * @param compare_cb The compare callback to set. + * @param user_data A user data pointer. + */ +void lv_cache_set_compare_cb(lv_cache_t * cache, lv_cache_compare_cb_t compare_cb, void * user_data); + +/** + * Set the create callback of the cache. + * @param cache The cache object pointer to set the create callback. + * @param alloc_cb The create callback to set. + * @param user_data A user data pointer. + */ +void lv_cache_set_create_cb(lv_cache_t * cache, lv_cache_create_cb_t alloc_cb, void * user_data); + +/** + * Set the free callback of the cache. + * @param cache The cache object pointer to set the free callback. + * @param free_cb The free callback to set. + * @param user_data A user data pointer. + */ +void lv_cache_set_free_cb(lv_cache_t * cache, lv_cache_free_cb_t free_cb, void * user_data); + +/** + * Give a name for a cache object. Only the pointer of the string is saved. + * @param cache The cache object pointer to set the name. + * @param name The name of the cache. + */ +void lv_cache_set_name(lv_cache_t * cache, const char * name); + +/** + * Get the name of a cache object. + * @param cache The cache object pointer to get the name. + * @return Returns the name of the cache. + */ +const char * lv_cache_get_name(lv_cache_t * cache); + +/** + * Create an iterator for the cache object. The iterator is used to iterate over all cache entries. + * @param cache The cache object pointer to create the iterator. + * @return Returns a pointer to the created iterator on success, `NULL` on error. + */ +lv_iter_t * lv_cache_iter_create(lv_cache_t * cache); + +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_CACHE_H */ diff --git a/test/include/liblvgl/misc/cache/lv_cache_entry.h b/test/include/liblvgl/misc/cache/lv_cache_entry.h new file mode 100644 index 00000000..947f71d7 --- /dev/null +++ b/test/include/liblvgl/misc/cache/lv_cache_entry.h @@ -0,0 +1,114 @@ +/** +* @file lv_cache_entry.h +* + */ + +#ifndef LV_CACHE_ENTRY_H +#define LV_CACHE_ENTRY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../osal/lv_os.h" +#include "../lv_types.h" +#include "lv_cache_private.h" +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the size of a cache entry. + * @param node_size The size of the node in the cache. + * @return The size of the cache entry. + */ +uint32_t lv_cache_entry_get_size(const uint32_t node_size); + +/** + * Get the reference count of a cache entry. + * @param entry The cache entry to get the reference count of. + * @return The reference count of the cache entry. + */ +int32_t lv_cache_entry_get_ref(lv_cache_entry_t * entry); + +/** + * Get the node size of a cache entry. Which is the same size with lv_cache_entry_get_size()'s node_size parameter. + * @param entry The cache entry to get the node size of. + * @return The node size of the cache entry. + */ +uint32_t lv_cache_entry_get_node_size(lv_cache_entry_t * entry); + +/** + * Check if a cache entry is invalid. + * @param entry The cache entry to check. + * @return True: the cache entry is invalid. False: the cache entry is valid. + */ +bool lv_cache_entry_is_invalid(lv_cache_entry_t * entry); + +/** + * Get the data of a cache entry. + * @param entry The cache entry to get the data of. + * @return The pointer to the data of the cache entry. + */ +void * lv_cache_entry_get_data(lv_cache_entry_t * entry); + +/** + * Get the cache instance of a cache entry. + * @param entry The cache entry to get the cache instance of. + * @return The pointer to the cache instance of the cache entry. + */ +const lv_cache_t * lv_cache_entry_get_cache(const lv_cache_entry_t * entry); + +/** + * Get the cache entry of a data. The data should be allocated by the cache instance. + * @param data The data to get the cache entry of. + * @param node_size The size of the node in the cache. + * @return The pointer to the cache entry of the data. + */ +lv_cache_entry_t * lv_cache_entry_get_entry(void * data, const uint32_t node_size); + +/** + * Allocate a cache entry. + * @param node_size The size of the node in the cache. + * @param cache The cache instance to allocate the cache entry from. + * @return The pointer to the allocated cache entry. + */ +lv_cache_entry_t * lv_cache_entry_alloc(const uint32_t node_size, const lv_cache_t * cache); + +/** + * Initialize a cache entry. + * @param entry The cache entry to initialize. + * @param cache The cache instance to allocate the cache entry from. + * @param node_size The size of the node in the cache. + */ +void lv_cache_entry_init(lv_cache_entry_t * entry, const lv_cache_t * cache, const uint32_t node_size); + +/** + * Deallocate a cache entry. And the data of the cache entry will be freed. + * @param entry The cache entry to deallocate. + */ +void lv_cache_entry_delete(lv_cache_entry_t * entry); +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CACHE_ENTRY_H*/ diff --git a/test/include/liblvgl/misc/cache/lv_cache_entry_private.h b/test/include/liblvgl/misc/cache/lv_cache_entry_private.h new file mode 100644 index 00000000..f8d41bb9 --- /dev/null +++ b/test/include/liblvgl/misc/cache/lv_cache_entry_private.h @@ -0,0 +1,50 @@ +/** + * @file lv_cache_entry_private.h + * + */ + +#ifndef LV_CACHE_ENTRY_PRIVATE_H +#define LV_CACHE_ENTRY_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_types.h" +#include "../../osal/lv_os.h" +#include "../lv_profiler.h" +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void lv_cache_entry_reset_ref(lv_cache_entry_t * entry); +void lv_cache_entry_inc_ref(lv_cache_entry_t * entry); +void lv_cache_entry_dec_ref(lv_cache_entry_t * entry); +void lv_cache_entry_set_node_size(lv_cache_entry_t * entry, uint32_t node_size); +void lv_cache_entry_set_invalid(lv_cache_entry_t * entry, bool is_invalid); +void lv_cache_entry_set_cache(lv_cache_entry_t * entry, const lv_cache_t * cache); +void * lv_cache_entry_acquire_data(lv_cache_entry_t * entry); +void lv_cache_entry_release_data(lv_cache_entry_t * entry, void * user_data); +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_CACHE_ENTRY_PRIVATE_H */ diff --git a/test/include/liblvgl/misc/cache/lv_cache_lru_rb.h b/test/include/liblvgl/misc/cache/lv_cache_lru_rb.h new file mode 100644 index 00000000..c0f44f39 --- /dev/null +++ b/test/include/liblvgl/misc/cache/lv_cache_lru_rb.h @@ -0,0 +1,44 @@ +/** +* @file lv_cache_lru_rb.h +* +*/ + +#ifndef LV_CACHE_LRU_RB_H +#define LV_CACHE_LRU_RB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_cache_entry.h" +#include "lv_cache_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/************************* + * GLOBAL VARIABLES + *************************/ +LV_ATTRIBUTE_EXTERN_DATA extern const lv_cache_class_t lv_cache_class_lru_rb_count; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_cache_class_t lv_cache_class_lru_rb_size; +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CACHE_LRU_RB_H*/ diff --git a/test/include/liblvgl/misc/cache/lv_cache_private.h b/test/include/liblvgl/misc/cache/lv_cache_private.h new file mode 100644 index 00000000..d197fbf6 --- /dev/null +++ b/test/include/liblvgl/misc/cache/lv_cache_private.h @@ -0,0 +1,201 @@ +/** +* @file lv_cache_private.h +* +*/ + +#ifndef LV_CACHE_PRIVATE_H +#define LV_CACHE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_types.h" +#include "../../osal/lv_os.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * The result of the cache reserve condition callback + */ +typedef enum { + LV_CACHE_RESERVE_COND_OK, /**< The condition is met and no entries need to be evicted */ + LV_CACHE_RESERVE_COND_TOO_LARGE, /**< The condition is not met and the reserve size is too large */ + LV_CACHE_RESERVE_COND_NEED_VICTIM, /**< The condition is not met and a victim is needed to be evicted */ + LV_CACHE_RESERVE_COND_ERROR /**< An error occurred while checking the condition */ +} lv_cache_reserve_cond_res_t; + +struct _lv_cache_ops_t; +struct _lv_cache_t; +struct _lv_cache_class_t; +struct _lv_cache_entry_t; + +typedef struct _lv_cache_ops_t lv_cache_ops_t; +typedef struct _lv_cache_t lv_cache_t; +typedef struct _lv_cache_class_t lv_cache_class_t; +typedef struct _lv_cache_entry_t lv_cache_entry_t; + +typedef int8_t lv_cache_compare_res_t; +typedef bool (*lv_cache_create_cb_t)(void * node, void * user_data); +typedef void (*lv_cache_free_cb_t)(void * node, void * user_data); +typedef lv_cache_compare_res_t (*lv_cache_compare_cb_t)(const void * a, const void * b); + +/** + * The cache instance allocation function, used by the cache class to allocate memory for cache instances. + * @return It should return a pointer to the allocated instance. + */ +typedef void * (*lv_cache_alloc_cb_t)(void); + +/** + * The cache instance initialization function, used by the cache class to initialize the cache instance. + * @return It should return true if the initialization is successful, false otherwise. + */ +typedef bool (*lv_cache_init_cb_t)(lv_cache_t * cache); + +/** + * The cache instance destruction function, used by the cache class to destroy the cache instance. + */ +typedef void (*lv_cache_destroy_cb_t)(lv_cache_t * cache, void * user_data); + +/** + * The cache get function, used by the cache class to get a cache entry by its key. + * @return `NULL` if the key is not found. + */ +typedef lv_cache_entry_t * (*lv_cache_get_cb_t)(lv_cache_t * cache, const void * key, void * user_data); + +/** + * The cache add function, used by the cache class to add a cache entry with a given key. + * This function only cares about how to add the entry, it doesn't check if the entry already exists and doesn't care about is it a victim or not. + * @return the added cache entry, or NULL if the entry is not added. + */ +typedef lv_cache_entry_t * (*lv_cache_add_cb_t)(lv_cache_t * cache, const void * key, void * user_data); + +/** + * The cache remove function, used by the cache class to remove a cache entry from the cache but doesn't free the memory.. + * This function only cares about how to remove the entry, it doesn't care about is it a victim or not. + */ +typedef void (*lv_cache_remove_cb_t)(lv_cache_t * cache, lv_cache_entry_t * entry, void * user_data); + +/** + * The cache drop function, used by the cache class to remove a cache entry from the cache and free the memory. + */ +typedef void (*lv_cache_drop_cb_t)(lv_cache_t * cache, const void * key, void * user_data); + +/** + * The cache drop all function, used by the cache class to remove all cache entries from the cache and free the memory. + */ +typedef void (*lv_cache_drop_all_cb_t)(lv_cache_t * cache, void * user_data); + +/** + * The cache get victim function, used by the cache class to get a victim entry to be evicted. + */ +typedef lv_cache_entry_t * (*lv_cache_get_victim_cb)(lv_cache_t * cache, void * user_data); + +/** + * The cache reserve condition function, used by the cache class to check if a new entry can be added to the cache without exceeding its maximum size. + * See lv_cache_reserve_cond_res_t for the possible results. + */ +typedef lv_cache_reserve_cond_res_t (*lv_cache_reserve_cond_cb)(lv_cache_t * cache, const void * key, size_t size, + void * user_data); + +/** + * The cache iterator creation function, used by the cache class to create an iterator for the cache. + * @return A pointer to the created iterator, or NULL if the iterator cannot be created. + */ +typedef lv_iter_t * (*lv_cache_iter_create_cb)(lv_cache_t * cache); + +/** + * The cache operations struct + */ +struct _lv_cache_ops_t { + lv_cache_compare_cb_t compare_cb; /**< Compare function for keys */ + lv_cache_create_cb_t create_cb; /**< Create function for nodes */ + lv_cache_free_cb_t free_cb; /**< Free function for nodes */ +}; + +/** + * The cache entry struct + */ +struct _lv_cache_t { + const lv_cache_class_t * clz; /**< Cache class. There are two built-in classes: + * - lv_cache_class_lru_rb_count for LRU-based cache with count-based eviction policy. + * - lv_cache_class_lru_rb_size for LRU-based cache with size-based eviction policy. */ + + uint32_t node_size; /**< Size of a node */ + + uint32_t max_size; /**< Maximum size of the cache */ + uint32_t size; /**< Current size of the cache */ + + lv_cache_ops_t ops; /**< Cache operations struct _lv_cache_ops_t */ + + lv_mutex_t lock; /**< Cache lock used to protect the cache in multithreading environments */ + + const char * name; /**< Name of the cache */ +}; + +/** + * Cache class struct for building custom cache classes + * + * Examples: + * - lv_cache_class_lru_rb_count for LRU-based cache with count-based eviction policy. + * - lv_cache_class_lru_rb_size for LRU-based cache with size-based eviction policy. + */ +struct _lv_cache_class_t { + lv_cache_alloc_cb_t alloc_cb; /**< The allocation function for cache entries */ + lv_cache_init_cb_t init_cb; /**< The initialization function for cache entries */ + lv_cache_destroy_cb_t destroy_cb; /**< The destruction function for cache entries */ + + lv_cache_get_cb_t get_cb; /**< The get function for cache entries */ + lv_cache_add_cb_t add_cb; /**< The add function for cache entries */ + lv_cache_remove_cb_t remove_cb; /**< The remove function for cache entries */ + lv_cache_drop_cb_t drop_cb; /**< The drop function for cache entries */ + lv_cache_drop_all_cb_t drop_all_cb; /**< The drop all function for cache entries */ + lv_cache_get_victim_cb get_victim_cb; /**< The get victim function for cache entries */ + lv_cache_reserve_cond_cb reserve_cond_cb; /**< The reserve condition function for cache entries */ + + lv_cache_iter_create_cb iter_create_cb; /**< The iterator creation function for cache entries */ +}; + +/*----------------- + * Cache entry slot + *----------------*/ + +struct _lv_cache_slot_size_t; + +typedef struct _lv_cache_slot_size_t lv_cache_slot_size_t; + +/** + * Cache entry slot struct + * + * To add new fields to the cache entry, add them to a new struct and add it to the first + * field of the cache data struct. And this one is a size slot for the cache entry. + */ +struct _lv_cache_slot_size_t { + size_t size; +}; +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CACHE_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/cache/lv_image_cache.h b/test/include/liblvgl/misc/cache/lv_image_cache.h new file mode 100644 index 00000000..8ae20fe6 --- /dev/null +++ b/test/include/liblvgl/misc/cache/lv_image_cache.h @@ -0,0 +1,82 @@ +/** +* @file lv_image_cache.h +* + */ + +#ifndef LV_IMAGE_CACHE_H +#define LV_IMAGE_CACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#include "../lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize image cache. + * @param size size of the cache in bytes. + * @return LV_RESULT_OK: initialization succeeded, LV_RESULT_INVALID: failed. + */ +lv_result_t lv_image_cache_init(uint32_t size); + +/** + * Resize image cache. + * If set to 0, the cache will be disabled. + * @param new_size new size of the cache in bytes. + * @param evict_now true: evict the images should be removed by the eviction policy, false: wait for the next cache cleanup. + */ +void lv_image_cache_resize(uint32_t new_size, bool evict_now); + +/** + * Invalidate image cache. Use NULL to invalidate all images. + * @param src pointer to an image source. + */ +void lv_image_cache_drop(const void * src); + +/** + * Return true if the image cache is enabled. + * @return true: enabled, false: disabled. + */ +bool lv_image_cache_is_enabled(void); + +/** + * Create an iterator to iterate over the image cache. + * @return an iterator to iterate over the image cache. + */ +lv_iter_t * lv_image_cache_iter_create(void); + +/** + * Dump the content of the image cache in a human-readable format with cache order. + */ +void lv_image_cache_dump(void); + +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGE_CACHE_H*/ diff --git a/test/include/liblvgl/misc/cache/lv_image_header_cache.h b/test/include/liblvgl/misc/cache/lv_image_header_cache.h new file mode 100644 index 00000000..1886be38 --- /dev/null +++ b/test/include/liblvgl/misc/cache/lv_image_header_cache.h @@ -0,0 +1,83 @@ +/** +* @file lv_image_header_cache.h +* + */ + +#ifndef LV_IMAGE_HEADER_CACHE_H +#define LV_IMAGE_HEADER_CACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#include "../lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize image header cache. + * @param count initial size of the cache in count of image headers. + * @return LV_RESULT_OK: initialization succeeded, LV_RESULT_INVALID: failed. + */ +lv_result_t lv_image_header_cache_init(uint32_t count); + +/** + * Resize image header cache. + * If set to 0, the cache is disabled. + * @param count new max count of cached image headers. + * @param evict_now true: evict the image headers should be removed by the eviction policy, false: wait for the next cache cleanup. + */ +void lv_image_header_cache_resize(uint32_t count, bool evict_now); + +/** + * Invalidate image header cache. Use NULL to invalidate all image headers. + * It's also automatically called when an image is invalidated. + * @param src pointer to an image source. + */ +void lv_image_header_cache_drop(const void * src); + +/** + * Return true if the image header cache is enabled. + * @return true: enabled, false: disabled. + */ +bool lv_image_header_cache_is_enabled(void); + +/** + * Create an iterator to iterate over the image header cache. + * @return an iterator to iterate over the image header cache. + */ +lv_iter_t * lv_image_header_cache_iter_create(void); + +/** + * Dump the content of the image header cache in a human-readable format with cache order. + */ +void lv_image_header_cache_dump(void); + +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGE_HEADER_CACHE_H*/ diff --git a/test/include/liblvgl/misc/lv_anim.h b/test/include/liblvgl/misc/lv_anim.h new file mode 100644 index 00000000..84602e41 --- /dev/null +++ b/test/include/liblvgl/misc/lv_anim.h @@ -0,0 +1,525 @@ +/** + * @file lv_anim.h + * + */ + +#ifndef LV_ANIM_H +#define LV_ANIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "lv_types.h" +#include "lv_math.h" +#include "lv_timer.h" +#include "lv_ll.h" + +/********************* + * DEFINES + *********************/ + +#define LV_ANIM_REPEAT_INFINITE 0xFFFFFFFF +#define LV_ANIM_PLAYTIME_INFINITE 0xFFFFFFFF + +/* + * Macros used to set cubic-bezier anim parameter. + * Parameters come from https://easings.net/ + * + * Usage: + * + * lv_anim_t a; + * lv_anim_init(&a); + * ... + * lv_anim_set_path_cb(&a, lv_anim_path_custom_bezier3); + * LV_ANIM_SET_EASE_IN_SINE(&a); //Set cubic-bezier anim parameter to easeInSine + * ... + * lv_anim_start(&a); + */ + +#define _PARA(a, x1, y1, x2, y2) ((a)->parameter.bezier3 = \ +(lv_anim_bezier3_para_t) { \ + LV_BEZIER_VAL_FLOAT(x1), LV_BEZIER_VAL_FLOAT(y1), \ + LV_BEZIER_VAL_FLOAT(x2), LV_BEZIER_VAL_FLOAT(y2) } \ + ) + +#define LV_ANIM_SET_EASE_IN_SINE(a) _PARA(a, 0.12, 0, 0.39, 0) +#define LV_ANIM_SET_EASE_OUT_SINE(a) _PARA(a, 0.61, 1, 0.88, 1) +#define LV_ANIM_SET_EASE_IN_OUT_SINE(a) _PARA(a, 0.37, 0, 0.63, 1) +#define LV_ANIM_SET_EASE_IN_QUAD(a) _PARA(a, 0.11, 0, 0.5, 0) +#define LV_ANIM_SET_EASE_OUT_QUAD(a) _PARA(a, 0.5, 1, 0.89, 1) +#define LV_ANIM_SET_EASE_IN_OUT_QUAD(a) _PARA(a, 0.45, 0, 0.55, 1) +#define LV_ANIM_SET_EASE_IN_CUBIC(a) _PARA(a, 0.32, 0, 0.67, 0) +#define LV_ANIM_SET_EASE_OUT_CUBIC(a) _PARA(a, 0.33, 1, 0.68, 1) +#define LV_ANIM_SET_EASE_IN_OUT_CUBIC(a) _PARA(a, 0.65, 0, 0.35, 1) +#define LV_ANIM_SET_EASE_IN_QUART(a) _PARA(a, 0.5, 0, 0.75, 0) +#define LV_ANIM_SET_EASE_OUT_QUART(a) _PARA(a, 0.25, 1, 0.5, 1) +#define LV_ANIM_SET_EASE_IN_OUT_QUART(a) _PARA(a, 0.76, 0, 0.24, 1) +#define LV_ANIM_SET_EASE_IN_QUINT(a) _PARA(a, 0.64, 0, 0.78, 0) +#define LV_ANIM_SET_EASE_OUT_QUINT(a) _PARA(a, 0.22, 1, 0.36, 1) +#define LV_ANIM_SET_EASE_IN_OUT_QUINT(a) _PARA(a, 0.83, 0, 0.17, 1) +#define LV_ANIM_SET_EASE_IN_EXPO(a) _PARA(a, 0.7, 0, 0.84, 0) +#define LV_ANIM_SET_EASE_OUT_EXPO(a) _PARA(a, 0.16, 1, 0.3, 1) +#define LV_ANIM_SET_EASE_IN_OUT_EXPO(a) _PARA(a, 0.87, 0, 0.13, 1) +#define LV_ANIM_SET_EASE_IN_CIRC(a) _PARA(a, 0.55, 0, 1, 0.45) +#define LV_ANIM_SET_EASE_OUT_CIRC(a) _PARA(a, 0, 0.55, 0.45, 1) +#define LV_ANIM_SET_EASE_IN_OUT_CIRC(a) _PARA(a, 0.85, 0, 0.15, 1) +#define LV_ANIM_SET_EASE_IN_BACK(a) _PARA(a, 0.36, 0, 0.66, -0.56) +#define LV_ANIM_SET_EASE_OUT_BACK(a) _PARA(a, 0.34, 1.56, 0.64, 1) +#define LV_ANIM_SET_EASE_IN_OUT_BACK(a) _PARA(a, 0.68, -0.6, 0.32, 1.6) + +LV_EXPORT_CONST_INT(LV_ANIM_REPEAT_INFINITE); +LV_EXPORT_CONST_INT(LV_ANIM_PLAYTIME_INFINITE); + +/********************** + * TYPEDEFS + **********************/ + +/** Can be used to indicate if animations are enabled or disabled in a case*/ +typedef enum { + LV_ANIM_OFF, + LV_ANIM_ON, +} lv_anim_enable_t; + +/** Get the current value during an animation*/ +typedef int32_t (*lv_anim_path_cb_t)(const lv_anim_t *); + +/** Generic prototype of "animator" functions. + * First parameter is the variable to animate. + * Second parameter is the value to set. + * Compatible with `lv_xxx_set_yyy(obj, value)` functions + * The `x` in `_xcb_t` means it's not a fully generic prototype because + * it doesn't receive `lv_anim_t *` as its first argument*/ +typedef void (*lv_anim_exec_xcb_t)(void *, int32_t); + +/** Same as `lv_anim_exec_xcb_t` but receives `lv_anim_t *` as the first parameter. + * It's more consistent but less convenient. Might be used by binding generator functions.*/ +typedef void (*lv_anim_custom_exec_cb_t)(lv_anim_t *, int32_t); + +/** Callback to call when the animation is ready*/ +typedef void (*lv_anim_completed_cb_t)(lv_anim_t *); + +/** Callback to call when the animation really stars (considering `delay`)*/ +typedef void (*lv_anim_start_cb_t)(lv_anim_t *); + +/** Callback used when the animation values are relative to get the current value*/ +typedef int32_t (*lv_anim_get_value_cb_t)(lv_anim_t *); + +/** Callback used when the animation is deleted*/ +typedef void (*lv_anim_deleted_cb_t)(lv_anim_t *); + +/** Parameter used when path is custom_bezier */ +typedef struct { + int16_t x1; + int16_t y1; + int16_t x2; + int16_t y2; +} lv_anim_bezier3_para_t; + +/** Describes an animation*/ +struct _lv_anim_t { + void * var; /**< Variable to animate*/ + lv_anim_exec_xcb_t exec_cb; /**< Function to execute to animate*/ + lv_anim_custom_exec_cb_t custom_exec_cb; /**< Function to execute to animate, + * same purpose as exec_cb but different parameters*/ + lv_anim_start_cb_t start_cb; /**< Call it when the animation is starts (considering `delay`)*/ + lv_anim_completed_cb_t completed_cb; /**< Call it when the animation is fully completed*/ + lv_anim_deleted_cb_t deleted_cb; /**< Call it when the animation is deleted*/ + lv_anim_get_value_cb_t get_value_cb; /**< Get the current value in relative mode*/ + void * user_data; /**< Custom user data*/ + lv_anim_path_cb_t path_cb; /**< Describe the path (curve) of animations*/ + int32_t start_value; /**< Start value*/ + int32_t current_value; /**< Current value*/ + int32_t end_value; /**< End value*/ + int32_t duration; /**< Animation time in ms*/ + int32_t act_time; /**< Current time in animation. Set to negative to make delay.*/ + uint32_t playback_delay; /**< Wait before play back*/ + uint32_t playback_duration; /**< Duration of playback animation*/ + uint32_t repeat_delay; /**< Wait before repeat*/ + uint32_t repeat_cnt; /**< Repeat count for the animation*/ + union _lv_anim_path_para_t { + lv_anim_bezier3_para_t bezier3; /**< Parameter used when path is custom_bezier*/ + } parameter; + + /* Animation system use these - user shouldn't set */ + uint32_t last_timer_run; + uint8_t playback_now : 1; /**< Play back is in progress*/ + uint8_t run_round : 1; /**< Indicates the animation has run in this round*/ + uint8_t start_cb_called : 1; /**< Indicates that the `start_cb` was already called*/ + uint8_t early_apply : 1; /**< 1: Apply start value immediately even is there is `delay`*/ +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize an animation variable. + * E.g.: + * lv_anim_t a; + * lv_anim_init(&a); + * lv_anim_set_...(&a); + * lv_anim_start(&a); + * @param a pointer to an `lv_anim_t` variable to initialize + */ +void lv_anim_init(lv_anim_t * a); + +/** + * Set a variable to animate + * @param a pointer to an initialized `lv_anim_t` variable + * @param var pointer to a variable to animate + */ +void lv_anim_set_var(lv_anim_t * a, void * var); + +/** + * Set a function to animate `var` + * @param a pointer to an initialized `lv_anim_t` variable + * @param exec_cb a function to execute during animation + * LVGL's built-in functions can be used. + * E.g. lv_obj_set_x + */ +void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_xcb_t exec_cb); + +/** + * Set the duration of an animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param duration duration of the animation in milliseconds + */ +void lv_anim_set_duration(lv_anim_t * a, uint32_t duration); + +/** + * Legacy `lv_anim_set_time` API will be removed soon, use `lv_anim_set_duration` instead. + */ +void lv_anim_set_time(lv_anim_t * a, uint32_t duration); + +/** + * Set a delay before starting the animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param delay delay before the animation in milliseconds + */ +void lv_anim_set_delay(lv_anim_t * a, uint32_t delay); + +/** + * Set the start and end values of an animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param start the start value + * @param end the end value + */ +void lv_anim_set_values(lv_anim_t * a, int32_t start, int32_t end); + +/** + * Similar to `lv_anim_set_exec_cb` but `lv_anim_custom_exec_cb_t` receives + * `lv_anim_t * ` as its first parameter instead of `void *`. + * This function might be used when LVGL is bound to other languages because + * it's more consistent to have `lv_anim_t *` as first parameter. + * @param a pointer to an initialized `lv_anim_t` variable + * @param exec_cb a function to execute. + */ +void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb); + +/** + * Set the path (curve) of the animation. + * @param a pointer to an initialized `lv_anim_t` variable + * @param path_cb a function to set the current value of the animation. + */ +void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb); + +/** + * Set a function call when the animation really starts (considering `delay`) + * @param a pointer to an initialized `lv_anim_t` variable + * @param start_cb a function call when the animation starts + */ +void lv_anim_set_start_cb(lv_anim_t * a, lv_anim_start_cb_t start_cb); + +/** + * Set a function to use the current value of the variable and make start and end value + * relative to the returned current value. + * @param a pointer to an initialized `lv_anim_t` variable + * @param get_value_cb a function call when the animation starts + */ +void lv_anim_set_get_value_cb(lv_anim_t * a, lv_anim_get_value_cb_t get_value_cb); + +/** + * Set a function call when the animation is completed + * @param a pointer to an initialized `lv_anim_t` variable + * @param completed_cb a function call when the animation is fully completed + */ +void lv_anim_set_completed_cb(lv_anim_t * a, lv_anim_completed_cb_t completed_cb); + +/** + * Set a function call when the animation is deleted. + * @param a pointer to an initialized `lv_anim_t` variable + * @param deleted_cb a function call when the animation is deleted + */ +void lv_anim_set_deleted_cb(lv_anim_t * a, lv_anim_deleted_cb_t deleted_cb); + +/** + * Make the animation to play back to when the forward direction is ready + * @param a pointer to an initialized `lv_anim_t` variable + * @param duration duration of playback animation in milliseconds. 0: disable playback + */ +void lv_anim_set_playback_duration(lv_anim_t * a, uint32_t duration); + +/** + * Legacy `lv_anim_set_playback_time` API will be removed soon, use `lv_anim_set_playback_duration` instead. + */ +void lv_anim_set_playback_time(lv_anim_t * a, uint32_t duration); + +/** + * Make the animation to play back to when the forward direction is ready + * @param a pointer to an initialized `lv_anim_t` variable + * @param delay delay in milliseconds before starting the playback animation. + */ +void lv_anim_set_playback_delay(lv_anim_t * a, uint32_t delay); + +/** + * Make the animation repeat itself. + * @param a pointer to an initialized `lv_anim_t` variable + * @param cnt repeat count or `LV_ANIM_REPEAT_INFINITE` for infinite repetition. 0: to disable repetition. + */ +void lv_anim_set_repeat_count(lv_anim_t * a, uint32_t cnt); + +/** + * Set a delay before repeating the animation. + * @param a pointer to an initialized `lv_anim_t` variable + * @param delay delay in milliseconds before repeating the animation. + */ +void lv_anim_set_repeat_delay(lv_anim_t * a, uint32_t delay); + +/** + * Set a whether the animation's should be applied immediately or only when the delay expired. + * @param a pointer to an initialized `lv_anim_t` variable + * @param en true: apply the start value immediately in `lv_anim_start`; + * false: apply the start value only when `delay` ms is elapsed and the animations really starts + */ +void lv_anim_set_early_apply(lv_anim_t * a, bool en); + +/** + * Set the custom user data field of the animation. + * @param a pointer to an initialized `lv_anim_t` variable + * @param user_data pointer to the new user_data. + */ +void lv_anim_set_user_data(lv_anim_t * a, void * user_data); + +/** + * Set parameter for cubic bezier path + * @param a pointer to an initialized `lv_anim_t` variable + * @param x1 first control point X + * @param y1 first control point Y + * @param x2 second control point X + * @param y2 second control point Y + */ +void lv_anim_set_bezier3_param(lv_anim_t * a, int16_t x1, int16_t y1, int16_t x2, int16_t y2); + +/** + * Create an animation + * @param a an initialized 'anim_t' variable. Not required after call. + * @return pointer to the created animation (different from the `a` parameter) + */ +lv_anim_t * lv_anim_start(const lv_anim_t * a); + +/** + * Get a delay before starting the animation + * @param a pointer to an initialized `lv_anim_t` variable + * @return delay before the animation in milliseconds + */ +uint32_t lv_anim_get_delay(const lv_anim_t * a); + +/** + * Get the time used to play the animation. + * @param a pointer to an animation. + * @return the play time in milliseconds. + */ +uint32_t lv_anim_get_playtime(const lv_anim_t * a); + +/** + * Get the duration of an animation + * @param a pointer to an initialized `lv_anim_t` variable + * @return the duration of the animation in milliseconds + */ +uint32_t lv_anim_get_time(const lv_anim_t * a); + +/** + * Get the repeat count of the animation. + * @param a pointer to an initialized `lv_anim_t` variable + * @return the repeat count or `LV_ANIM_REPEAT_INFINITE` for infinite repetition. 0: disabled repetition. + */ +uint32_t lv_anim_get_repeat_count(const lv_anim_t * a); + +/** + * Get the user_data field of the animation + * @param a pointer to an initialized `lv_anim_t` variable + * @return the pointer to the custom user_data of the animation + */ +void * lv_anim_get_user_data(const lv_anim_t * a); + +/** + * Delete animation(s) of a variable with a given animator function + * @param var pointer to variable + * @param exec_cb a function pointer which is animating 'var', + * or NULL to ignore it and delete all the animations of 'var + * @return true: at least 1 animation is deleted, false: no animation is deleted + */ +bool lv_anim_delete(void * var, lv_anim_exec_xcb_t exec_cb); + +/** + * Delete all the animations + */ +void lv_anim_delete_all(void); + +/** + * Get the animation of a variable and its `exec_cb`. + * @param var pointer to variable + * @param exec_cb a function pointer which is animating 'var', or NULL to return first matching 'var' + * @return pointer to the animation. + */ +lv_anim_t * lv_anim_get(void * var, lv_anim_exec_xcb_t exec_cb); + +/** + * Get global animation refresher timer. + * @return pointer to the animation refresher timer. + */ +lv_timer_t * lv_anim_get_timer(void); + +/** + * Delete an animation by getting the animated variable from `a`. + * Only animations with `exec_cb` will be deleted. + * This function exists because it's logical that all anim. functions receives an + * `lv_anim_t` as their first parameter. It's not practical in C but might make + * the API more consequent and makes easier to generate bindings. + * @param a pointer to an animation. + * @param exec_cb a function pointer which is animating 'var', + * or NULL to ignore it and delete all the animations of 'var + * @return true: at least 1 animation is deleted, false: no animation is deleted + */ +bool lv_anim_custom_delete(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb); + +/** + * Get the animation of a variable and its `exec_cb`. + * This function exists because it's logical that all anim. functions receives an + * `lv_anim_t` as their first parameter. It's not practical in C but might make + * the API more consequent and makes easier to generate bindings. + * @param a pointer to an animation. + * @param exec_cb a function pointer which is animating 'var', or NULL to return first matching 'var' + * @return pointer to the animation. + */ +lv_anim_t * lv_anim_custom_get(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb); + +/** + * Get the number of currently running animations + * @return the number of running animations + */ +uint16_t lv_anim_count_running(void); + +/** + * Store the speed as a special value which can be used as time in animations. + * It will be converted to time internally based on the start and end values + * @param speed the speed of the animation in with unit / sec resolution in 0..10k range + * @return a special value which can be used as an animation time + */ +uint32_t lv_anim_speed(uint32_t speed); + +/** + * Store the speed as a special value which can be used as time in animations. + * It will be converted to time internally based on the start and end values + * @param speed the speed of the animation in as unit / sec resolution in 0..10k range + * @param min_time the minimum time in 0..10k range + * @param max_time the maximum time in 0..10k range + * @return a special value in where all three values are stored and can be used as an animation time + * @note internally speed is stored as 10 unit/sec + * @note internally min/max_time are stored with 10 ms unit + * + */ +uint32_t lv_anim_speed_clamped(uint32_t speed, uint32_t min_time, uint32_t max_time); + +/** + * Calculate the time of an animation based on its speed, start and end values. + * @param speed the speed of the animation + * @param start the start value + * @param end the end value + * @return the time of the animation in milliseconds + */ +uint32_t lv_anim_speed_to_time(uint32_t speed, int32_t start, int32_t end); + +/** + * Manually refresh the state of the animations. + * Useful to make the animations running in a blocking process where + * `lv_timer_handler` can't run for a while. + * Shouldn't be used directly because it is called in `lv_refr_now()`. + */ +void lv_anim_refr_now(void); + +/** + * Calculate the current value of an animation applying linear characteristic + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_linear(const lv_anim_t * a); + +/** + * Calculate the current value of an animation slowing down the start phase + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_ease_in(const lv_anim_t * a); + +/** + * Calculate the current value of an animation slowing down the end phase + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_ease_out(const lv_anim_t * a); + +/** + * Calculate the current value of an animation applying an "S" characteristic (cosine) + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_ease_in_out(const lv_anim_t * a); + +/** + * Calculate the current value of an animation with overshoot at the end + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_overshoot(const lv_anim_t * a); + +/** + * Calculate the current value of an animation with 3 bounces + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_bounce(const lv_anim_t * a); + +/** + * Calculate the current value of an animation applying step characteristic. + * (Set end value on the end of the animation) + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_step(const lv_anim_t * a); + +/** + * A custom cubic bezier animation path, need to specify cubic-parameters in a->parameter.bezier3 + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_custom_bezier3(const lv_anim_t * a); + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ANIM_H*/ diff --git a/test/include/liblvgl/misc/lv_anim_private.h b/test/include/liblvgl/misc/lv_anim_private.h new file mode 100644 index 00000000..5c258501 --- /dev/null +++ b/test/include/liblvgl/misc/lv_anim_private.h @@ -0,0 +1,56 @@ +/** + * @file lv_anim_private.h + * + */ + +#ifndef LV_ANIM_PRIVATE_H +#define LV_ANIM_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_anim.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + bool anim_list_changed; + bool anim_run_round; + lv_timer_t * timer; + lv_ll_t anim_ll; +} lv_anim_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Init the animation module + */ +void lv_anim_core_init(void); + +/** + * Deinit the animation module + */ +void lv_anim_core_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ANIM_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_anim_timeline.h b/test/include/liblvgl/misc/lv_anim_timeline.h new file mode 100644 index 00000000..0e9651d5 --- /dev/null +++ b/test/include/liblvgl/misc/lv_anim_timeline.h @@ -0,0 +1,136 @@ +/** + * @file lv_anim_timeline.h + * + */ + +#ifndef LV_ANIM_TIMELINE_H +#define LV_ANIM_TIMELINE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_anim.h" + +/********************* + * DEFINES + *********************/ + +#define LV_ANIM_TIMELINE_PROGRESS_MAX 0xFFFF + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_anim_timeline_t lv_anim_timeline_t; + +/********************** +* GLOBAL PROTOTYPES +**********************/ + +/** + * Create an animation timeline. + * @return pointer to the animation timeline. + */ +lv_anim_timeline_t * lv_anim_timeline_create(void); + +/** + * Delete animation timeline. + * @param at pointer to the animation timeline. + */ +void lv_anim_timeline_delete(lv_anim_timeline_t * at); + +/** + * Add animation to the animation timeline. + * @param at pointer to the animation timeline. + * @param start_time the time the animation started on the timeline, note that start_time will override the value of delay. + * @param a pointer to an animation. + */ +void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, const lv_anim_t * a); + +/** + * Start the animation timeline. + * @param at pointer to the animation timeline. + * @return total time spent in animation timeline. + */ +uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at); + +/** + * Pause the animation timeline. + * @param at pointer to the animation timeline. + */ +void lv_anim_timeline_pause(lv_anim_timeline_t * at); + +/** + * Set the playback direction of the animation timeline. + * @param at pointer to the animation timeline. + * @param reverse whether to play in reverse. + */ +void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse); + +/** + * Make the animation timeline repeat itself. + * @param at pointer to the animation timeline. + * @param cnt repeat count or `LV_ANIM_REPEAT_INFINITE` for infinite repetition. 0: to disable repetition. + */ +void lv_anim_timeline_set_repeat_count(lv_anim_timeline_t * at, uint32_t cnt); + +/** + * Set a delay before repeating the animation timeline. + * @param at pointer to the animation timeline. + * @param delay delay in milliseconds before repeating the animation timeline. + */ +void lv_anim_timeline_set_repeat_delay(lv_anim_timeline_t * at, uint32_t delay); + +/** + * Set the progress of the animation timeline. + * @param at pointer to the animation timeline. + * @param progress set value 0~65535 to map 0~100% animation progress. + */ +void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress); + +/** + * Get the time used to play the animation timeline. + * @param at pointer to the animation timeline. + * @return total time spent in animation timeline. + */ +uint32_t lv_anim_timeline_get_playtime(lv_anim_timeline_t * at); + +/** + * Get whether the animation timeline is played in reverse. + * @param at pointer to the animation timeline. + * @return return true if it is reverse playback. + */ +bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at); + +/** + * Get the progress of the animation timeline. + * @param at pointer to the animation timeline. + * @return return value 0~65535 to map 0~100% animation progress. + */ +uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at); + +/** + * Get repeat count of the animation timeline. + * @param at pointer to the animation timeline. + */ +uint32_t lv_anim_timeline_get_repeat_count(lv_anim_timeline_t * at); + +/** + * Get repeat delay of the animation timeline. + * @param at pointer to the animation timeline. + */ +uint32_t lv_anim_timeline_get_repeat_delay(lv_anim_timeline_t * at); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ANIM_TIMELINE_H*/ diff --git a/test/include/liblvgl/misc/lv_area.h b/test/include/liblvgl/misc/lv_area.h new file mode 100644 index 00000000..0798c74f --- /dev/null +++ b/test/include/liblvgl/misc/lv_area.h @@ -0,0 +1,254 @@ +/** + * @file lv_area.h + * + */ + +#ifndef LV_AREA_H +#define LV_AREA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "lv_types.h" +#include "lv_math.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Represents a point on the screen. + */ +typedef struct { + int32_t x; + int32_t y; +} lv_point_t; + +typedef struct { + lv_value_precise_t x; + lv_value_precise_t y; +} lv_point_precise_t; + +/** Represents an area of the screen.*/ +typedef struct { + int32_t x1; + int32_t y1; + int32_t x2; + int32_t y2; +} lv_area_t; + +/** Alignments*/ + +typedef enum { + LV_ALIGN_DEFAULT = 0, + LV_ALIGN_TOP_LEFT, + LV_ALIGN_TOP_MID, + LV_ALIGN_TOP_RIGHT, + LV_ALIGN_BOTTOM_LEFT, + LV_ALIGN_BOTTOM_MID, + LV_ALIGN_BOTTOM_RIGHT, + LV_ALIGN_LEFT_MID, + LV_ALIGN_RIGHT_MID, + LV_ALIGN_CENTER, + + LV_ALIGN_OUT_TOP_LEFT, + LV_ALIGN_OUT_TOP_MID, + LV_ALIGN_OUT_TOP_RIGHT, + LV_ALIGN_OUT_BOTTOM_LEFT, + LV_ALIGN_OUT_BOTTOM_MID, + LV_ALIGN_OUT_BOTTOM_RIGHT, + LV_ALIGN_OUT_LEFT_TOP, + LV_ALIGN_OUT_LEFT_MID, + LV_ALIGN_OUT_LEFT_BOTTOM, + LV_ALIGN_OUT_RIGHT_TOP, + LV_ALIGN_OUT_RIGHT_MID, + LV_ALIGN_OUT_RIGHT_BOTTOM, +} lv_align_t; + +typedef enum { + LV_DIR_NONE = 0x00, + LV_DIR_LEFT = (1 << 0), + LV_DIR_RIGHT = (1 << 1), + LV_DIR_TOP = (1 << 2), + LV_DIR_BOTTOM = (1 << 3), + LV_DIR_HOR = LV_DIR_LEFT | LV_DIR_RIGHT, + LV_DIR_VER = LV_DIR_TOP | LV_DIR_BOTTOM, + LV_DIR_ALL = LV_DIR_HOR | LV_DIR_VER, +} lv_dir_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize an area + * @param area_p pointer to an area + * @param x1 left coordinate of the area + * @param y1 top coordinate of the area + * @param x2 right coordinate of the area + * @param y2 bottom coordinate of the area + */ +void lv_area_set(lv_area_t * area_p, int32_t x1, int32_t y1, int32_t x2, int32_t y2); + +/** + * Copy an area + * @param dest pointer to the destination area + * @param src pointer to the source area + */ +inline static void lv_area_copy(lv_area_t * dest, const lv_area_t * src) +{ + dest->x1 = src->x1; + dest->y1 = src->y1; + dest->x2 = src->x2; + dest->y2 = src->y2; +} + +/** + * Get the width of an area + * @param area_p pointer to an area + * @return the width of the area (if x1 == x2 -> width = 1) + */ +int32_t lv_area_get_width(const lv_area_t * area_p); + +/** + * Get the height of an area + * @param area_p pointer to an area + * @return the height of the area (if y1 == y2 -> height = 1) + */ +int32_t lv_area_get_height(const lv_area_t * area_p); + +/** + * Set the width of an area + * @param area_p pointer to an area + * @param w the new width of the area (w == 1 makes x1 == x2) + */ +void lv_area_set_width(lv_area_t * area_p, int32_t w); + +/** + * Set the height of an area + * @param area_p pointer to an area + * @param h the new height of the area (h == 1 makes y1 == y2) + */ +void lv_area_set_height(lv_area_t * area_p, int32_t h); + +/** + * Return with area of an area (x * y) + * @param area_p pointer to an area + * @return size of area + */ +uint32_t lv_area_get_size(const lv_area_t * area_p); + +void lv_area_increase(lv_area_t * area, int32_t w_extra, int32_t h_extra); + +void lv_area_move(lv_area_t * area, int32_t x_ofs, int32_t y_ofs); + +/** + * Align an area to another + * @param base an area where the other will be aligned + * @param to_align the area to align + * @param align `LV_ALIGN_...` + * @param ofs_x X offset + * @param ofs_y Y offset + */ +void lv_area_align(const lv_area_t * base, lv_area_t * to_align, lv_align_t align, int32_t ofs_x, int32_t ofs_y); + +/** + * Transform a point + * @param point pointer to a point + * @param angle angle with 0.1 resolutions (123 means 12.3°) + * @param scale_x horizontal zoom, 256 means 100% + * @param scale_y vertical zoom, 256 means 100% + * @param pivot pointer to the pivot point of the transformation + * @param zoom_first true: zoom first and rotate after that; else: opposite order + */ +void lv_point_transform(lv_point_t * point, int32_t angle, int32_t scale_x, int32_t scale_y, const lv_point_t * pivot, + bool zoom_first); + +/** + * Transform an array of points + * @param points pointer to an array of points + * @param count number of points in the array + * @param angle angle with 0.1 resolutions (123 means 12.3°) + * @param scale_x horizontal zoom, 256 means 100% + * @param scale_y vertical zoom, 256 means 100% + * @param pivot pointer to the pivot point of the transformation + * @param zoom_first true: zoom first and rotate after that; else: opposite order + */ +void lv_point_array_transform(lv_point_t * points, size_t count, int32_t angle, int32_t scale_x, int32_t scale_y, + const lv_point_t * pivot, + bool zoom_first); + +lv_point_t lv_point_from_precise(const lv_point_precise_t * p); + +lv_point_precise_t lv_point_to_precise(const lv_point_t * p); + +void lv_point_set(lv_point_t * p, int32_t x, int32_t y); + +void lv_point_precise_set(lv_point_precise_t * p, lv_value_precise_t x, lv_value_precise_t y); + +void lv_point_swap(lv_point_t * p1, lv_point_t * p2); + +void lv_point_precise_swap(lv_point_precise_t * p1, lv_point_precise_t * p2); + +/********************** + * MACROS + **********************/ + +#define LV_COORD_TYPE_SHIFT (29U) + +#define LV_COORD_TYPE_MASK (3 << LV_COORD_TYPE_SHIFT) +#define LV_COORD_TYPE(x) ((x) & LV_COORD_TYPE_MASK) /*Extract type specifiers*/ +#define LV_COORD_PLAIN(x) ((x) & ~LV_COORD_TYPE_MASK) /*Remove type specifiers*/ + +#define LV_COORD_TYPE_PX (0 << LV_COORD_TYPE_SHIFT) +#define LV_COORD_TYPE_SPEC (1 << LV_COORD_TYPE_SHIFT) +#define LV_COORD_TYPE_PX_NEG (3 << LV_COORD_TYPE_SHIFT) + +#define LV_COORD_IS_PX(x) (LV_COORD_TYPE(x) == LV_COORD_TYPE_PX || LV_COORD_TYPE(x) == LV_COORD_TYPE_PX_NEG) +#define LV_COORD_IS_SPEC(x) (LV_COORD_TYPE(x) == LV_COORD_TYPE_SPEC) + +#define LV_COORD_SET_SPEC(x) ((x) | LV_COORD_TYPE_SPEC) + +/** Max coordinate value */ +#define LV_COORD_MAX ((1 << LV_COORD_TYPE_SHIFT) - 1) +#define LV_COORD_MIN (-LV_COORD_MAX) + +/*Special coordinates*/ +#define LV_SIZE_CONTENT LV_COORD_SET_SPEC(LV_COORD_MAX) +#define LV_PCT_STORED_MAX (LV_COORD_MAX - 1) +#if LV_PCT_STORED_MAX % 2 != 0 +#error LV_PCT_STORED_MAX should be an even number +#endif +#define LV_PCT_POS_MAX (LV_PCT_STORED_MAX / 2) +#define LV_PCT(x) (LV_COORD_SET_SPEC(((x) < 0 ? (LV_PCT_POS_MAX - LV_MAX((x), -LV_PCT_POS_MAX)) : LV_MIN((x), LV_PCT_POS_MAX)))) +#define LV_COORD_IS_PCT(x) ((LV_COORD_IS_SPEC(x) && LV_COORD_PLAIN(x) <= LV_PCT_STORED_MAX)) +#define LV_COORD_GET_PCT(x) (LV_COORD_PLAIN(x) > LV_PCT_POS_MAX ? LV_PCT_POS_MAX - LV_COORD_PLAIN(x) : LV_COORD_PLAIN(x)) + +LV_EXPORT_CONST_INT(LV_COORD_MAX); +LV_EXPORT_CONST_INT(LV_COORD_MIN); +LV_EXPORT_CONST_INT(LV_SIZE_CONTENT); + +/** + * Convert a percentage value to `int32_t`. + * Percentage values are stored in special range + * @param x the percentage (0..1000) + * @return a coordinate that stores the percentage + */ +int32_t lv_pct(int32_t x); + +int32_t lv_pct_to_px(int32_t v, int32_t base); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/test/include/liblvgl/misc/lv_area_private.h b/test/include/liblvgl/misc/lv_area_private.h new file mode 100644 index 00000000..bebca594 --- /dev/null +++ b/test/include/liblvgl/misc/lv_area_private.h @@ -0,0 +1,115 @@ +/** + * @file lv_area_private.h + * + */ + +#ifndef LV_AREA_PRIVATE_H +#define LV_AREA_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_area.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Set the position of an area (width and height will be kept) + * @param area_p pointer to an area + * @param x the new x coordinate of the area + * @param y the new y coordinate of the area + */ +void lv_area_set_pos(lv_area_t * area_p, int32_t x, int32_t y); + +/** + * Get the common parts of two areas + * @param res_p pointer to an area, the result will be stored her + * @param a1_p pointer to the first area + * @param a2_p pointer to the second area + * @return false: the two area has NO common parts, res_p is invalid + */ +bool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p); + +/** + * Get resulting sub areas after removing the common parts of two areas from the first area + * @param res_p pointer to an array of areas with a count of 4, the resulting areas will be stored here + * @param a1_p pointer to the first area + * @param a2_p pointer to the second area + * @return number of results (max 4) or -1 if no intersect + */ +int8_t lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * a2_p); + +/** + * Join two areas into a third which involves the other two + * @param a_res_p pointer to an area, the result will be stored here + * @param a1_p pointer to the first area + * @param a2_p pointer to the second area + */ +void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p); + +/** + * Check if a point is on an area + * @param a_p pointer to an area + * @param p_p pointer to a point + * @param radius radius of area (e.g. for rounded rectangle) + * @return false:the point is out of the area + */ +bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, int32_t radius); + +/** + * Check if two area has common parts + * @param a1_p pointer to an area. + * @param a2_p pointer to another area + * @return false: a1_p and a2_p has no common parts + */ +bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p); + +/** + * Check if an area is fully on another + * @param ain_p pointer to an area which could be in 'aholder_p' + * @param aholder_p pointer to an area which could involve 'ain_p' + * @param radius radius of `aholder_p` (e.g. for rounded rectangle) + * @return true: `ain_p` is fully inside `aholder_p` + */ +bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, int32_t radius); + +/** + * Check if an area is fully out of another + * @param aout_p pointer to an area which could be in 'aholder_p' + * @param aholder_p pointer to an area which could involve 'ain_p' + * @param radius radius of `aholder_p` (e.g. for rounded rectangle) + * @return true: `aout_p` is fully outside `aholder_p` + */ +bool lv_area_is_out(const lv_area_t * aout_p, const lv_area_t * aholder_p, int32_t radius); + +/** + * Check if 2 area is the same + * @param a pointer to an area + * @param b pointer to another area + */ +bool lv_area_is_equal(const lv_area_t * a, const lv_area_t * b); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_AREA_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_array.h b/test/include/liblvgl/misc/lv_array.h new file mode 100644 index 00000000..78f7ac3d --- /dev/null +++ b/test/include/liblvgl/misc/lv_array.h @@ -0,0 +1,205 @@ +/** + * @file lv_array.h + * Array. The elements are dynamically allocated by the 'lv_mem' module. + */ + +#ifndef LV_ARRAY_H +#define LV_ARRAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +#ifndef LV_ARRAY_DEFAULT_CAPACITY +#define LV_ARRAY_DEFAULT_CAPACITY 4 +#endif + +#ifndef LV_ARRAY_DEFAULT_SHRINK_RATIO +#define LV_ARRAY_DEFAULT_SHRINK_RATIO 2 +#endif + +/********************** + * TYPEDEFS + **********************/ + +/** Description of a array*/ +struct _lv_array_t { + uint8_t * data; + uint32_t size; + uint32_t capacity; + uint32_t element_size; + + bool inner_alloc; /* true: data is allocated by the array; false: data is allocated by the user */ +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Init an array. + * @param array pointer to an `lv_array_t` variable to initialize + * @param capacity the initial capacity of the array + * @param element_size the size of an element in bytes + */ +void lv_array_init(lv_array_t * array, uint32_t capacity, uint32_t element_size); + +/** + * Init an array from a buffer. + * @note The buffer must be large enough to store `capacity` elements. The array will not release the buffer and reallocate it. + * The user must ensure that the buffer is valid during the lifetime of the array. And release the buffer when the array is no longer needed. + * @param array pointer to an `lv_array_t` variable to initialize + * @param buf pointer to a buffer to use as the array's data + * @param capacity the initial capacity of the array + * @param element_size the size of an element in bytes + */ +void lv_array_init_from_buf(lv_array_t * array, void * buf, uint32_t capacity, uint32_t element_size); + +/** + * Resize the array to the given capacity. + * @note if the new capacity is smaller than the current size, the array will be truncated. + * @param array pointer to an `lv_array_t` variable + * @param new_capacity the new capacity of the array + */ +bool lv_array_resize(lv_array_t * array, uint32_t new_capacity); + +/** + * Deinit the array, and free the allocated memory + * @param array pointer to an `lv_array_t` variable to deinitialize + */ +void lv_array_deinit(lv_array_t * array); + +/** + * Return how many elements are stored in the array. + * @param array pointer to an `lv_array_t` variable + * @return the number of elements stored in the array + */ +uint32_t lv_array_size(const lv_array_t * array); + +/** + * Return the capacity of the array, i.e. how many elements can be stored. + * @param array pointer to an `lv_array_t` variable + * @return the capacity of the array + */ +uint32_t lv_array_capacity(const lv_array_t * array); + +/** + * Return if the array is empty + * @param array pointer to an `lv_array_t` variable + * @return true: array is empty; false: array is not empty + */ +bool lv_array_is_empty(const lv_array_t * array); + +/** + * Return if the array is full + * @param array pointer to an `lv_array_t` variable + * @return true: array is full; false: array is not full + */ +bool lv_array_is_full(const lv_array_t * array); + +/** + * Copy an array to another. + * @note this will create a new array with the same capacity and size as the source array. + * @param target pointer to an `lv_array_t` variable to copy to + * @param source pointer to an `lv_array_t` variable to copy from + */ +void lv_array_copy(lv_array_t * target, const lv_array_t * source); + +/** + * Remove all elements in array. + * @param array pointer to an `lv_array_t` variable + */ +void lv_array_clear(lv_array_t * array); + +/** + * Shrink the memory capacity of array if necessary. + * @param array pointer to an `lv_array_t` variable + */ +void lv_array_shrink(lv_array_t * array); + +/** + * Remove the element at the specified position in the array. + * @param array pointer to an `lv_array_t` variable + * @param index the index of the element to remove + * @return LV_RESULT_OK: success, otherwise: error + */ +lv_result_t lv_array_remove(lv_array_t * array, uint32_t index); + +/** + * Remove from the array either a single element or a range of elements ([start, end)). + * @note This effectively reduces the container size by the number of elements removed. + * @note When start equals to end, the function has no effect. + * @param array pointer to an `lv_array_t` variable + * @param start the index of the first element to be removed + * @param end the index of the first element that is not to be removed + * @return LV_RESULT_OK: success, otherwise: error + */ +lv_result_t lv_array_erase(lv_array_t * array, uint32_t start, uint32_t end); + +/** + * Concatenate two arrays. Adds new elements to the end of the array. + * @note The destination array is automatically expanded as necessary. + * @param array pointer to an `lv_array_t` variable + * @param other pointer to the array to concatenate + * @return LV_RESULT_OK: success, otherwise: error + */ +lv_result_t lv_array_concat(lv_array_t * array, const lv_array_t * other); + +/** + * Push back element. Adds a new element to the end of the array. + * If the array capacity is not enough for the new element, the array will be resized automatically. + * @note If the element is NULL, it will be added as an empty element. + * @param array pointer to an `lv_array_t` variable + * @param element pointer to the element to add. NULL to push an empty element. + * @return LV_RESULT_OK: success, otherwise: error + */ +lv_result_t lv_array_push_back(lv_array_t * array, const void * element); + +/** + * Assigns one content to the array, replacing its current content. + * @param array pointer to an `lv_array_t` variable + * @param index the index of the element to replace + * @param value pointer to the elements to add + * @return true: success; false: error + */ +lv_result_t lv_array_assign(lv_array_t * array, uint32_t index, const void * value); + +/** + * Returns a pointer to the element at position n in the array. + * @param array pointer to an `lv_array_t` variable + * @param index the index of the element to return + * @return a pointer to the requested element, NULL if `index` is out of range + */ +void * lv_array_at(const lv_array_t * array, uint32_t index); + +/** + * Returns a pointer to the first element in the array. + * @param array pointer to an `lv_array_t` variable + * @return a pointer to the first element in the array + */ +void * lv_array_front(const lv_array_t * array); + +/** + * Returns a pointer to the last element in the array. + * @param array pointer to an `lv_array_t` variable + */ +void * lv_array_back(const lv_array_t * array); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/test/include/liblvgl/misc/lv_assert.h b/test/include/liblvgl/misc/lv_assert.h new file mode 100644 index 00000000..c9dc849c --- /dev/null +++ b/test/include/liblvgl/misc/lv_assert.h @@ -0,0 +1,87 @@ +/** + * @file lv_assert.h + * + */ + +#ifndef LV_ASSERT_H +#define LV_ASSERT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "lv_log.h" +#include "../stdlib/lv_mem.h" +#include LV_ASSERT_HANDLER_INCLUDE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#define LV_ASSERT(expr) \ + do { \ + if(!(expr)) { \ + LV_LOG_ERROR("Asserted at expression: %s", #expr); \ + LV_ASSERT_HANDLER \ + } \ + } while(0) + +#define LV_ASSERT_MSG(expr, msg) \ + do { \ + if(!(expr)) { \ + LV_LOG_ERROR("Asserted at expression: %s (%s)", #expr, msg); \ + LV_ASSERT_HANDLER \ + } \ + } while(0) + +#define LV_ASSERT_FORMAT_MSG(expr, format, ...) \ + do { \ + if(!(expr)) { \ + LV_LOG_ERROR("Asserted at expression: %s " format , #expr, __VA_ARGS__); \ + LV_ASSERT_HANDLER \ + } \ + } while(0) + +/*----------------- + * ASSERTS + *-----------------*/ + +#if LV_USE_ASSERT_NULL +# define LV_ASSERT_NULL(p) LV_ASSERT_MSG(p != NULL, "NULL pointer"); +#else +# define LV_ASSERT_NULL(p) +#endif + +#if LV_USE_ASSERT_MALLOC +# define LV_ASSERT_MALLOC(p) LV_ASSERT_MSG(p != NULL, "Out of memory"); +#else +# define LV_ASSERT_MALLOC(p) +#endif + +#if LV_USE_ASSERT_MEM_INTEGRITY +# define LV_ASSERT_MEM_INTEGRITY() LV_ASSERT_MSG(lv_mem_test() == LV_RESULT_OK, "Memory integrity error"); +#else +# define LV_ASSERT_MEM_INTEGRITY() +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ASSERT_H*/ diff --git a/test/include/liblvgl/misc/lv_async.h b/test/include/liblvgl/misc/lv_async.h new file mode 100644 index 00000000..362a0ffa --- /dev/null +++ b/test/include/liblvgl/misc/lv_async.h @@ -0,0 +1,61 @@ +/** + * @file lv_async.h + * + */ + +#ifndef LV_ASYNC_H +#define LV_ASYNC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Type for async callback. + */ +typedef void (*lv_async_cb_t)(void *); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Call an asynchronous function the next time lv_timer_handler() is run. This function is likely to return + * **before** the call actually happens! + * @param async_xcb a callback which is the task itself. + * (the 'x' in the argument name indicates that it's not a fully generic function because it not follows + * the `func_name(object, callback, ...)` convention) + * @param user_data custom parameter + */ +lv_result_t lv_async_call(lv_async_cb_t async_xcb, void * user_data); + +/** + * Cancel an asynchronous function call + * @param async_xcb a callback which is the task itself. + * @param user_data custom parameter + */ +lv_result_t lv_async_call_cancel(lv_async_cb_t async_xcb, void * user_data); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ASYNC_H*/ diff --git a/test/include/liblvgl/misc/lv_bidi.h b/test/include/liblvgl/misc/lv_bidi.h new file mode 100644 index 00000000..77575efb --- /dev/null +++ b/test/include/liblvgl/misc/lv_bidi.h @@ -0,0 +1,83 @@ +/** + * @file lv_bidi.h + * + */ + +#ifndef LV_BIDI_H +#define LV_BIDI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "lv_types.h" +#include "lv_text.h" + +/********************* + * DEFINES + *********************/ +/** Special non printable strong characters. + * They can be inserted to texts to affect the run's direction */ +#define LV_BIDI_LRO "\xE2\x80\xAD" /*U+202D*/ +#define LV_BIDI_RLO "\xE2\x80\xAE" /*U+202E*/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_BASE_DIR_LTR = 0x00, + LV_BASE_DIR_RTL = 0x01, + LV_BASE_DIR_AUTO = 0x02, + + LV_BASE_DIR_NEUTRAL = 0x20, + LV_BASE_DIR_WEAK = 0x21, +} lv_base_dir_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ +#if LV_USE_BIDI + +/** + * Get the real text alignment from the a text alignment, base direction and a text. + * @param align LV_TEXT_ALIGN_..., write back the calculated align here (LV_TEXT_ALIGN_LEFT/RIGHT/CENTER) + * @param base_dir LV_BASE_DIR_..., write the calculated base dir here (LV_BASE_DIR_LTR/RTL) + * @param txt a text, used with LV_BASE_DIR_AUTO to determine the base direction + */ +void lv_bidi_calculate_align(lv_text_align_t * align, lv_base_dir_t * base_dir, const char * txt); + +/** + * Set custom neutrals string + * @param neutrals default " \t\n\r.,:;'\"`!?%/\\-=()[]{}<>@#&$|" + */ +void lv_bidi_set_custom_neutrals_static(const char * neutrals); + +/********************** + * MACROS + **********************/ + +#else /*LV_USE_BIDI*/ +/** + * For compatibility if LV_USE_BIDI = 0 + * Get the real text alignment from the a text alignment, base direction and a text. + * @param align For LV_TEXT_ALIGN_AUTO give LV_TEXT_ALIGN_LEFT else leave unchanged, write back the calculated align here + * @param base_dir Unused + * @param txt Unused + */ +static inline void lv_bidi_calculate_align(lv_text_align_t * align, lv_base_dir_t * base_dir, const char * txt) +{ + LV_UNUSED(txt); + LV_UNUSED(base_dir); + if(*align == LV_TEXT_ALIGN_AUTO) * align = LV_TEXT_ALIGN_LEFT; +} +#endif /*LV_USE_BIDI*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BIDI_H*/ diff --git a/test/include/liblvgl/misc/lv_bidi_private.h b/test/include/liblvgl/misc/lv_bidi_private.h new file mode 100644 index 00000000..0b684dae --- /dev/null +++ b/test/include/liblvgl/misc/lv_bidi_private.h @@ -0,0 +1,101 @@ +/** + * @file lv_bidi_private.h + * + */ + +#ifndef LV_BIDI_PRIVATE_H +#define LV_BIDI_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_bidi.h" +#if LV_USE_BIDI + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Convert a text to get the characters in the correct visual order according to + * Unicode Bidirectional Algorithm + * @param str_in the text to process + * @param str_out store the result here. Has the be `strlen(str_in)` length + * @param base_dir `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` + */ +void lv_bidi_process(const char * str_in, char * str_out, lv_base_dir_t base_dir); + +/** + * Auto-detect the direction of a text based on the first strong character + * @param txt the text to process + * @return `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` + */ +lv_base_dir_t lv_bidi_detect_base_dir(const char * txt); + +/** + * Get the logical position of a character in a line + * @param str_in the input string. Can be only one line. + * @param bidi_txt internally the text is bidi processed which buffer can be get here. + * If not required anymore has to freed with `lv_free()` + * Can be `NULL` is unused + * @param len length of the line in character count + * @param base_dir base direction of the text: `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` + * @param visual_pos the visual character position which logical position should be get + * @param is_rtl tell the char at `visual_pos` is RTL or LTR context + * @return the logical character position + */ +uint16_t lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t len, lv_base_dir_t base_dir, + uint32_t visual_pos, bool * is_rtl); + +/** + * Get the visual position of a character in a line + * @param str_in the input string. Can be only one line. + * @param bidi_txt internally the text is bidi processed which buffer can be get here. + * If not required anymore has to freed with `lv_free()` + * Can be `NULL` is unused + * @param len length of the line in character count + * @param base_dir base direction of the text: `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` + * @param logical_pos the logical character position which visual position should be get + * @param is_rtl tell the char at `logical_pos` is RTL or LTR context + * @return the visual character position + */ +uint16_t lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t len, lv_base_dir_t base_dir, + uint32_t logical_pos, bool * is_rtl); + +/** + * Bidi process a paragraph of text + * @param str_in the string to process + * @param str_out store the result here + * @param len length of the text + * @param base_dir base dir of the text + * @param pos_conv_out an `uint16_t` array to store the related logical position of the character. + * Can be `NULL` is unused + * @param pos_conv_len length of `pos_conv_out` in element count + */ +void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_base_dir_t base_dir, + uint16_t * pos_conv_out, uint16_t pos_conv_len); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_BIDI*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BIDI_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_circle_buf.h b/test/include/liblvgl/misc/lv_circle_buf.h new file mode 100644 index 00000000..61490008 --- /dev/null +++ b/test/include/liblvgl/misc/lv_circle_buf.h @@ -0,0 +1,191 @@ +/** +* @file lv_circle_buf.h +* + */ + + +#ifndef LV_CIRCLE_BUF_H +#define LV_CIRCLE_BUF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef bool (*lv_circle_buf_fill_cb_t)(void * buf, uint32_t buff_len, int32_t index, void * user_data); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a circle buffer + * @param capacity the maximum number of elements in the buffer + * @param element_size the size of an element in bytes + * @return pointer to the created buffer + */ +lv_circle_buf_t * lv_circle_buf_create(uint32_t capacity, uint32_t element_size); + +/** + * Create a circle buffer from an existing buffer + * @param buf pointer to a buffer + * @param capacity the maximum number of elements in the buffer + * @param element_size the size of an element in bytes + * @return pointer to the created buffer + */ +lv_circle_buf_t * lv_circle_buf_create_from_buf(void * buf, uint32_t capacity, uint32_t element_size); + +/** + * Create a circle buffer from an existing array + * @param array pointer to an array + * @return pointer to the created buffer + */ +lv_circle_buf_t * lv_circle_buf_create_from_array(const lv_array_t * array); + +/** + * Resize the buffer + * @param circle_buf pointer to a buffer + * @param capacity the new capacity of the buffer + * @return LV_RESULT_OK: the buffer is resized; LV_RESULT_INVALID: the buffer is not resized + */ +lv_result_t lv_circle_buf_resize(lv_circle_buf_t * circle_buf, uint32_t capacity); + +/** + * Destroy a circle buffer + * @param circle_buf pointer to buffer + */ +void lv_circle_buf_destroy(lv_circle_buf_t * circle_buf); + +/** + * Get the size of the buffer + * @param circle_buf pointer to buffer + * @return the number of elements in the buffer + */ +uint32_t lv_circle_buf_size(const lv_circle_buf_t * circle_buf); + +/** + * Get the capacity of the buffer + * @param circle_buf pointer to buffer + * @return the maximum number of elements in the buffer + */ +uint32_t lv_circle_buf_capacity(const lv_circle_buf_t * circle_buf); + +/** + * Get the remaining space in the buffer + * @param circle_buf pointer to buffer + * @return the number of elements that can be written to the buffer + */ +uint32_t lv_circle_buf_remain(const lv_circle_buf_t * circle_buf); + +/** + * Check if the buffer is empty + * @param circle_buf pointer to buffer + * @return true: the buffer is empty; false: the buffer is not empty + */ +bool lv_circle_buf_is_empty(const lv_circle_buf_t * circle_buf); + +/** + * Check if the buffer is full + * @param circle_buf pointer to buffer + * @return true: the buffer is full; false: the buffer is not full + */ +bool lv_circle_buf_is_full(const lv_circle_buf_t * circle_buf); + +/** + * Reset the buffer + * @param circle_buf pointer to buffer + * @return LV_RESULT_OK: the buffer is reset; LV_RESULT_INVALID: the buffer is not reset + */ +void lv_circle_buf_reset(lv_circle_buf_t * circle_buf); + +/** + * Get the head of the buffer + * @param circle_buf pointer to buffer + * @return pointer to the head of the buffer + */ +void * lv_circle_buf_head(const lv_circle_buf_t * circle_buf); + +/** + * Get the tail of the buffer + * @param circle_buf pointer to buffer + * @return pointer to the tail of the buffer + */ +void * lv_circle_buf_tail(const lv_circle_buf_t * circle_buf); + +/** + * Read a value + * @param circle_buf pointer to buffer + * @param data pointer to a variable to store the read value + * @return LV_RESULT_OK: the value is read; LV_RESULT_INVALID: the value is not read + */ +lv_result_t lv_circle_buf_read(lv_circle_buf_t * circle_buf, void * data); + +/** + * Write a value + * @param circle_buf pointer to buffer + * @param data pointer to the value to write + * @return LV_RESULT_OK: the value is written; LV_RESULT_INVALID: the value is not written + */ +lv_result_t lv_circle_buf_write(lv_circle_buf_t * circle_buf, const void * data); + +/** + * Fill the buffer with values + * @param circle_buf pointer to buffer + * @param count the number of values to fill + * @param fill_cb the callback function to fill the buffer + * @param user_data + * @return the number of values filled + */ +uint32_t lv_circle_buf_fill(lv_circle_buf_t * circle_buf, uint32_t count, lv_circle_buf_fill_cb_t fill_cb, + void * user_data); + +/** + * Skip a value + * @param circle_buf pointer to buffer + * @return LV_RESULT_OK: the value is skipped; LV_RESULT_INVALID: the value is not skipped + */ +lv_result_t lv_circle_buf_skip(lv_circle_buf_t * circle_buf); + +/** + * Peek a value + * @param circle_buf pointer to buffer + * @param data pointer to a variable to store the peeked value + * @return LV_RESULT_OK: the value is peeked; LV_RESULT_INVALID: the value is not peeked + */ +lv_result_t lv_circle_buf_peek(const lv_circle_buf_t * circle_buf, void * data); + +/** + * Peek a value at an index + * @param circle_buf pointer to buffer + * @param index the index of the value to peek, if the index is greater than the size of the buffer, it will return looply. + * @param data pointer to a variable to store the peeked value + * @return LV_RESULT_OK: the value is peeked; LV_RESULT_INVALID: the value is not peeked + */ +lv_result_t lv_circle_buf_peek_at(const lv_circle_buf_t * circle_buf, uint32_t index, void * data); + +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CIRCLE_BUF_H*/ diff --git a/test/include/liblvgl/misc/lv_color.h b/test/include/liblvgl/misc/lv_color.h new file mode 100644 index 00000000..d5222400 --- /dev/null +++ b/test/include/liblvgl/misc/lv_color.h @@ -0,0 +1,429 @@ +/** + * @file lv_color.h + * + */ + +#ifndef LV_COLOR_H +#define LV_COLOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "lv_assert.h" +#include "lv_math.h" +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ +LV_EXPORT_CONST_INT(LV_COLOR_DEPTH); + +#if LV_COLOR_DEPTH == 8 +#define LV_COLOR_NATIVE_WITH_ALPHA_SIZE 2 +#elif LV_COLOR_DEPTH == 16 +#define LV_COLOR_NATIVE_WITH_ALPHA_SIZE 3 +#elif LV_COLOR_DEPTH == 24 +#define LV_COLOR_NATIVE_WITH_ALPHA_SIZE 4 +#elif LV_COLOR_DEPTH == 32 +#define LV_COLOR_NATIVE_WITH_ALPHA_SIZE 4 +#endif + +/** + * Opacity percentages. + */ + +enum { + LV_OPA_TRANSP = 0, + LV_OPA_0 = 0, + LV_OPA_10 = 25, + LV_OPA_20 = 51, + LV_OPA_30 = 76, + LV_OPA_40 = 102, + LV_OPA_50 = 127, + LV_OPA_60 = 153, + LV_OPA_70 = 178, + LV_OPA_80 = 204, + LV_OPA_90 = 229, + LV_OPA_100 = 255, + LV_OPA_COVER = 255, +}; + +#define LV_OPA_MIN 2 /**< Opacities below this will be transparent */ +#define LV_OPA_MAX 253 /**< Opacities above this will fully cover */ + +/** + * Get the pixel size of a color format in bits, bpp + * @param cf a color format (`LV_COLOR_FORMAT_...`) + * @return the pixel size in bits + * @sa lv_color_format_get_bpp + */ +#define LV_COLOR_FORMAT_GET_BPP(cf) ( \ + (cf) == LV_COLOR_FORMAT_I1 ? 1 : \ + (cf) == LV_COLOR_FORMAT_A1 ? 1 : \ + (cf) == LV_COLOR_FORMAT_I2 ? 2 : \ + (cf) == LV_COLOR_FORMAT_A2 ? 2 : \ + (cf) == LV_COLOR_FORMAT_I4 ? 4 : \ + (cf) == LV_COLOR_FORMAT_A4 ? 4 : \ + (cf) == LV_COLOR_FORMAT_L8 ? 8 : \ + (cf) == LV_COLOR_FORMAT_A8 ? 8 : \ + (cf) == LV_COLOR_FORMAT_I8 ? 8 : \ + (cf) == LV_COLOR_FORMAT_AL88 ? 16 : \ + (cf) == LV_COLOR_FORMAT_RGB565 ? 16 : \ + (cf) == LV_COLOR_FORMAT_RGB565A8 ? 16 : \ + (cf) == LV_COLOR_FORMAT_YUY2 ? 16 : \ + (cf) == LV_COLOR_FORMAT_ARGB8565 ? 24 : \ + (cf) == LV_COLOR_FORMAT_RGB888 ? 24 : \ + (cf) == LV_COLOR_FORMAT_ARGB8888 ? 32 : \ + (cf) == LV_COLOR_FORMAT_XRGB8888 ? 32 : \ + 0 \ + ) + +/** + * Get the pixel size of a color format in bytes + * @param cf a color format (`LV_COLOR_FORMAT_...`) + * @return the pixel size in bytes + * @sa lv_color_format_get_size + */ +#define LV_COLOR_FORMAT_GET_SIZE(cf) ((LV_COLOR_FORMAT_GET_BPP(cf) + 7) >> 3) + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint8_t blue; + uint8_t green; + uint8_t red; +} lv_color_t; + +typedef struct { + uint16_t blue : 5; + uint16_t green : 6; + uint16_t red : 5; +} lv_color16_t; + +typedef struct { + uint8_t blue; + uint8_t green; + uint8_t red; + uint8_t alpha; +} lv_color32_t; + +typedef struct { + uint16_t h; + uint8_t s; + uint8_t v; +} lv_color_hsv_t; + +typedef struct { + uint8_t lumi; + uint8_t alpha; +} lv_color16a_t; + +typedef enum { + LV_COLOR_FORMAT_UNKNOWN = 0, + + LV_COLOR_FORMAT_RAW = 0x01, + LV_COLOR_FORMAT_RAW_ALPHA = 0x02, + + /*<=1 byte (+alpha) formats*/ + LV_COLOR_FORMAT_L8 = 0x06, + LV_COLOR_FORMAT_I1 = 0x07, + LV_COLOR_FORMAT_I2 = 0x08, + LV_COLOR_FORMAT_I4 = 0x09, + LV_COLOR_FORMAT_I8 = 0x0A, + LV_COLOR_FORMAT_A8 = 0x0E, + + /*2 byte (+alpha) formats*/ + LV_COLOR_FORMAT_RGB565 = 0x12, + LV_COLOR_FORMAT_ARGB8565 = 0x13, /**< Not supported by sw renderer yet. */ + LV_COLOR_FORMAT_RGB565A8 = 0x14, /**< Color array followed by Alpha array*/ + LV_COLOR_FORMAT_AL88 = 0x15, /**< L8 with alpha >*/ + + /*3 byte (+alpha) formats*/ + LV_COLOR_FORMAT_RGB888 = 0x0F, + LV_COLOR_FORMAT_ARGB8888 = 0x10, + LV_COLOR_FORMAT_XRGB8888 = 0x11, + + /*Formats not supported by software renderer but kept here so GPU can use it*/ + LV_COLOR_FORMAT_A1 = 0x0B, + LV_COLOR_FORMAT_A2 = 0x0C, + LV_COLOR_FORMAT_A4 = 0x0D, + + /* reference to https://wiki.videolan.org/YUV/ */ + /*YUV planar formats*/ + LV_COLOR_FORMAT_YUV_START = 0x20, + LV_COLOR_FORMAT_I420 = LV_COLOR_FORMAT_YUV_START, /*YUV420 planar(3 plane)*/ + LV_COLOR_FORMAT_I422 = 0x21, /*YUV422 planar(3 plane)*/ + LV_COLOR_FORMAT_I444 = 0x22, /*YUV444 planar(3 plane)*/ + LV_COLOR_FORMAT_I400 = 0x23, /*YUV400 no chroma channel*/ + LV_COLOR_FORMAT_NV21 = 0x24, /*YUV420 planar(2 plane), UV plane in 'V, U, V, U'*/ + LV_COLOR_FORMAT_NV12 = 0x25, /*YUV420 planar(2 plane), UV plane in 'U, V, U, V'*/ + + /*YUV packed formats*/ + LV_COLOR_FORMAT_YUY2 = 0x26, /*YUV422 packed like 'Y U Y V'*/ + LV_COLOR_FORMAT_UYVY = 0x27, /*YUV422 packed like 'U Y V Y'*/ + + LV_COLOR_FORMAT_YUV_END = LV_COLOR_FORMAT_UYVY, + + /*Color formats in which LVGL can render*/ +#if LV_COLOR_DEPTH == 1 + LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_I1, + LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_I1, +#elif LV_COLOR_DEPTH == 8 + LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_L8, + LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_AL88, +#elif LV_COLOR_DEPTH == 16 + LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_RGB565, + LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_RGB565A8, +#elif LV_COLOR_DEPTH == 24 + LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_RGB888, + LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_ARGB8888, +#elif LV_COLOR_DEPTH == 32 + LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_XRGB8888, + LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_ARGB8888, +#else +#error "LV_COLOR_DEPTH should be 1, 8, 16, 24 or 32" +#endif + +} lv_color_format_t; + +#define LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf) ((cf) >= LV_COLOR_FORMAT_A1 && (cf) <= LV_COLOR_FORMAT_A8) +#define LV_COLOR_FORMAT_IS_INDEXED(cf) ((cf) >= LV_COLOR_FORMAT_I1 && (cf) <= LV_COLOR_FORMAT_I8) +#define LV_COLOR_FORMAT_IS_YUV(cf) ((cf) >= LV_COLOR_FORMAT_YUV_START && (cf) <= LV_COLOR_FORMAT_YUV_END) +#define LV_COLOR_INDEXED_PALETTE_SIZE(cf) ((cf) == LV_COLOR_FORMAT_I1 ? 2 :\ + (cf) == LV_COLOR_FORMAT_I2 ? 4 :\ + (cf) == LV_COLOR_FORMAT_I4 ? 16 :\ + (cf) == LV_COLOR_FORMAT_I8 ? 256 : 0) + +/********************** + * MACROS + **********************/ + +#define LV_COLOR_MAKE(r8, g8, b8) {b8, g8, r8} + +#define LV_OPA_MIX2(a1, a2) (((int32_t)(a1) * (a2)) >> 8) +#define LV_OPA_MIX3(a1, a2, a3) (((int32_t)(a1) * (a2) * (a3)) >> 16) + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the pixel size of a color format in bits, bpp + * @param cf a color format (`LV_COLOR_FORMAT_...`) + * @return the pixel size in bits + * @sa LV_COLOR_FORMAT_GET_BPP + */ +uint8_t lv_color_format_get_bpp(lv_color_format_t cf); + +/** + * Get the pixel size of a color format in bytes + * @param cf a color format (`LV_COLOR_FORMAT_...`) + * @return the pixel size in bytes + * @sa LV_COLOR_FORMAT_GET_SIZE + */ +uint8_t lv_color_format_get_size(lv_color_format_t cf); + +/** + * Check if a color format has alpha channel or not + * @param src_cf a color format (`LV_COLOR_FORMAT_...`) + * @return true: has alpha channel; false: doesn't have alpha channel + */ +bool lv_color_format_has_alpha(lv_color_format_t src_cf); + +/** + * Create an ARGB8888 color from RGB888 + alpha + * @param color an RGB888 color + * @param opa the alpha value + * @return the ARGB8888 color + */ +lv_color32_t lv_color_to_32(lv_color_t color, lv_opa_t opa); + +/** + * Convert an RGB888 color to an integer + * @param c an RGB888 color + * @return `c` as an integer + */ +uint32_t lv_color_to_int(lv_color_t c); + +/** + * Check if two RGB888 color are equal + * @param c1 the first color + * @param c2 the second color + * @return true: equal + */ +bool lv_color_eq(lv_color_t c1, lv_color_t c2); + +/** + * Check if two ARGB8888 color are equal + * @param c1 the first color + * @param c2 the second color + * @return true: equal + */ +bool lv_color32_eq(lv_color32_t c1, lv_color32_t c2); + +/** + * Create a color from 0x000000..0xffffff input + * @param c the hex input + * @return the color + */ +lv_color_t lv_color_hex(uint32_t c); + +/** + * Create an RGB888 color + * @param r the red channel (0..255) + * @param g the green channel (0..255) + * @param b the blue channel (0..255) + * @return the color + */ +lv_color_t lv_color_make(uint8_t r, uint8_t g, uint8_t b); + +/** + * Create an ARGB8888 color + * @param r the red channel (0..255) + * @param g the green channel (0..255) + * @param b the blue channel (0..255) + * @param a the alpha channel (0..255) + * @return the color + */ +lv_color32_t lv_color32_make(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + +/** + * Create a color from 0x000..0xfff input + * @param c the hex input (e.g. 0x123 will be 0x112233) + * @return the color + */ +lv_color_t lv_color_hex3(uint32_t c); + +/** + * Convert am RGB888 color to RGB565 stored in `uint16_t` + * @param color and RGB888 color + * @return `color` as RGB565 on `uin16_t` + */ +uint16_t lv_color_to_u16(lv_color_t color); + +/** + * Convert am RGB888 color to XRGB8888 stored in `uint32_t` + * @param color and RGB888 color + * @return `color` as XRGB8888 on `uin32_t` (the alpha channel is always set to 0xFF) + */ +uint32_t lv_color_to_u32(lv_color_t color); + +/** + * Mix two RGB565 colors + * @param c1 the first color (typically the foreground color) + * @param c2 the second color (typically the background color) + * @param mix 0..255, or LV_OPA_0/10/20... + * @return mix == 0: c2 + * mix == 255: c1 + * mix == 128: 0.5 x c1 + 0.5 x c2 + */ +uint16_t LV_ATTRIBUTE_FAST_MEM lv_color_16_16_mix(uint16_t c1, uint16_t c2, uint8_t mix); + +/** + * Mix white to a color + * @param c the base color + * @param lvl the intensity of white (0: no change, 255: fully white) + * @return the mixed color + */ +lv_color_t lv_color_lighten(lv_color_t c, lv_opa_t lvl); + +/** + * Mix black to a color + * @param c the base color + * @param lvl the intensity of black (0: no change, 255: fully black) + * @return the mixed color + */ +lv_color_t lv_color_darken(lv_color_t c, lv_opa_t lvl); + +/** + * Convert a HSV color to RGB + * @param h hue [0..359] + * @param s saturation [0..100] + * @param v value [0..100] + * @return the given RGB color in RGB (with LV_COLOR_DEPTH depth) + */ +lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v); + +/** + * Convert a 32-bit RGB color to HSV + * @param r8 8-bit red + * @param g8 8-bit green + * @param b8 8-bit blue + * @return the given RGB color in HSV + */ +lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8); + +/** + * Convert a color to HSV + * @param color color + * @return the given color in HSV + */ +lv_color_hsv_t lv_color_to_hsv(lv_color_t color); + +/*Source: https://vuetifyjs.com/en/styles/colors/#material-colors*/ + +/** + * A helper for white color + * @return a white color + */ +lv_color_t lv_color_white(void); + +/** + * A helper for black color + * @return a black color + */ +lv_color_t lv_color_black(void); + +void lv_color_premultiply(lv_color32_t * c); + +void lv_color16_premultiply(lv_color16_t * c, lv_opa_t a); + +/** + * Get the luminance of a color: luminance = 0.3 R + 0.59 G + 0.11 B + * @param c a color + * @return the brightness [0..255] + */ +uint8_t lv_color_luminance(lv_color_t c); + +/** + * Get the luminance of a color16: luminance = 0.3 R + 0.59 G + 0.11 B + * @param c a color + * @return the brightness [0..255] + */ +uint8_t lv_color16_luminance(const lv_color16_t c); + +/** + * Get the luminance of a color24: luminance = 0.3 R + 0.59 G + 0.11 B + * @param c a color + * @return the brightness [0..255] + */ +uint8_t lv_color24_luminance(const uint8_t * c); + +/** + * Get the luminance of a color32: luminance = 0.3 R + 0.59 G + 0.11 B + * @param c a color + * @return the brightness [0..255] + */ +uint8_t lv_color32_luminance(lv_color32_t c); + +/********************** + * MACROS + **********************/ + +#include "lv_palette.h" +#include "lv_color_op.h" + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_color_filter_dsc_t lv_color_filter_shade; + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_COLOR_H*/ diff --git a/test/include/liblvgl/misc/lv_color_op.h b/test/include/liblvgl/misc/lv_color_op.h new file mode 100644 index 00000000..72a0e696 --- /dev/null +++ b/test/include/liblvgl/misc/lv_color_op.h @@ -0,0 +1,82 @@ +/** + * @file lv_color_op.h + * + */ + +#ifndef LV_COLOR_OP_H +#define LV_COLOR_OP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_assert.h" +#include "lv_math.h" +#include "lv_color.h" +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_color_filter_dsc_t; + +typedef lv_color_t (*lv_color_filter_cb_t)(const struct _lv_color_filter_dsc_t *, lv_color_t, lv_opa_t); + +struct _lv_color_filter_dsc_t { + lv_color_filter_cb_t filter_cb; + void * user_data; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Mix two colors with a given ratio. + * @param c1 the first color to mix (usually the foreground) + * @param c2 the second color to mix (usually the background) + * @param mix The ratio of the colors. 0: full `c2`, 255: full `c1`, 127: half `c1` and half`c2` + * @return the mixed color + */ +lv_color_t LV_ATTRIBUTE_FAST_MEM lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix); + +/** + * + * @param fg + * @param bg + * @return + * @note Use bg.alpha in the return value + * @note Use fg.alpha as mix ratio + */ +lv_color32_t lv_color_mix32(lv_color32_t fg, lv_color32_t bg); + +/** + * Get the brightness of a color + * @param c a color + * @return brightness in range [0..255] + */ +uint8_t lv_color_brightness(lv_color_t c); + +void lv_color_filter_dsc_init(lv_color_filter_dsc_t * dsc, lv_color_filter_cb_t cb); + +/********************** + * PREDEFINED COLORS + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_COLOR_H*/ diff --git a/test/include/liblvgl/misc/lv_color_op_private.h b/test/include/liblvgl/misc/lv_color_op_private.h new file mode 100644 index 00000000..d6516ebd --- /dev/null +++ b/test/include/liblvgl/misc/lv_color_op_private.h @@ -0,0 +1,39 @@ +/** + * @file lv_color_op_private.h + * + */ + +#ifndef LV_COLOR_OP_PRIVATE_H +#define LV_COLOR_OP_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_color_op.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_COLOR_OP_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_event.h b/test/include/liblvgl/misc/lv_event.h new file mode 100644 index 00000000..89aee8ab --- /dev/null +++ b/test/include/liblvgl/misc/lv_event.h @@ -0,0 +1,224 @@ +/** + * @file lv_event.h + * + */ + +#ifndef LV_EVENT_H +#define LV_EVENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_types.h" +#include "../lv_conf_internal.h" + +#include "lv_array.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef void (*lv_event_cb_t)(lv_event_t * e); + +/** + * Type of event being sent to the object. + */ +typedef enum { + LV_EVENT_ALL = 0, + + /** Input device events*/ + LV_EVENT_PRESSED, /**< The object has been pressed*/ + LV_EVENT_PRESSING, /**< The object is being pressed (called continuously while pressing)*/ + LV_EVENT_PRESS_LOST, /**< The object is still being pressed but slid cursor/finger off of the object */ + LV_EVENT_SHORT_CLICKED, /**< The object was pressed for a short period of time, then released it. Not called if scrolled.*/ + LV_EVENT_SINGLE_CLICKED, /**< Called for the first short click within a small distance and short time*/ + LV_EVENT_DOUBLE_CLICKED, /**< Called for the second short click within small distance and short time*/ + LV_EVENT_TRIPLE_CLICKED, /**< Called for the third short click within small distance and short time*/ + LV_EVENT_LONG_PRESSED, /**< Object has been pressed for at least `long_press_time`. Not called if scrolled.*/ + LV_EVENT_LONG_PRESSED_REPEAT, /**< Called after `long_press_time` in every `long_press_repeat_time` ms. Not called if scrolled.*/ + LV_EVENT_CLICKED, /**< Called on release if not scrolled (regardless to long press)*/ + LV_EVENT_RELEASED, /**< Called in every cases when the object has been released*/ + LV_EVENT_SCROLL_BEGIN, /**< Scrolling begins. The event parameter is a pointer to the animation of the scroll. Can be modified*/ + LV_EVENT_SCROLL_THROW_BEGIN, + LV_EVENT_SCROLL_END, /**< Scrolling ends*/ + LV_EVENT_SCROLL, /**< Scrolling*/ + LV_EVENT_GESTURE, /**< A gesture is detected. Get the gesture with `lv_indev_get_gesture_dir(lv_indev_active());` */ + LV_EVENT_KEY, /**< A key is sent to the object. Get the key with `lv_indev_get_key(lv_indev_active());`*/ + LV_EVENT_ROTARY, /**< An encoder or wheel was rotated. Get the rotation count with `lv_event_get_rotary_diff(e);`*/ + LV_EVENT_FOCUSED, /**< The object is focused*/ + LV_EVENT_DEFOCUSED, /**< The object is defocused*/ + LV_EVENT_LEAVE, /**< The object is defocused but still selected*/ + LV_EVENT_HIT_TEST, /**< Perform advanced hit-testing*/ + LV_EVENT_INDEV_RESET, /**< Indev has been reset*/ + LV_EVENT_HOVER_OVER, /**< Indev hover over object*/ + LV_EVENT_HOVER_LEAVE, /**< Indev hover leave object*/ + + /** Drawing events*/ + LV_EVENT_COVER_CHECK, /**< Check if the object fully covers an area. The event parameter is `lv_cover_check_info_t *`.*/ + LV_EVENT_REFR_EXT_DRAW_SIZE, /**< Get the required extra draw area around the object (e.g. for shadow). The event parameter is `int32_t *` to store the size.*/ + LV_EVENT_DRAW_MAIN_BEGIN, /**< Starting the main drawing phase*/ + LV_EVENT_DRAW_MAIN, /**< Perform the main drawing*/ + LV_EVENT_DRAW_MAIN_END, /**< Finishing the main drawing phase*/ + LV_EVENT_DRAW_POST_BEGIN, /**< Starting the post draw phase (when all children are drawn)*/ + LV_EVENT_DRAW_POST, /**< Perform the post draw phase (when all children are drawn)*/ + LV_EVENT_DRAW_POST_END, /**< Finishing the post draw phase (when all children are drawn)*/ + LV_EVENT_DRAW_TASK_ADDED, /**< Adding a draw task */ + + /** Special events*/ + LV_EVENT_VALUE_CHANGED, /**< The object's value has changed (i.e. slider moved)*/ + LV_EVENT_INSERT, /**< A text is inserted to the object. The event data is `char *` being inserted.*/ + LV_EVENT_REFRESH, /**< Notify the object to refresh something on it (for the user)*/ + LV_EVENT_READY, /**< A process has finished*/ + LV_EVENT_CANCEL, /**< A process has been cancelled */ + + /** Other events*/ + LV_EVENT_CREATE, /**< Object is being created*/ + LV_EVENT_DELETE, /**< Object is being deleted*/ + LV_EVENT_CHILD_CHANGED, /**< Child was removed, added, or its size, position were changed */ + LV_EVENT_CHILD_CREATED, /**< Child was created, always bubbles up to all parents*/ + LV_EVENT_CHILD_DELETED, /**< Child was deleted, always bubbles up to all parents*/ + LV_EVENT_SCREEN_UNLOAD_START, /**< A screen unload started, fired immediately when scr_load is called*/ + LV_EVENT_SCREEN_LOAD_START, /**< A screen load started, fired when the screen change delay is expired*/ + LV_EVENT_SCREEN_LOADED, /**< A screen was loaded*/ + LV_EVENT_SCREEN_UNLOADED, /**< A screen was unloaded*/ + LV_EVENT_SIZE_CHANGED, /**< Object coordinates/size have changed*/ + LV_EVENT_STYLE_CHANGED, /**< Object's style has changed*/ + LV_EVENT_LAYOUT_CHANGED, /**< The children position has changed due to a layout recalculation*/ + LV_EVENT_GET_SELF_SIZE, /**< Get the internal size of a widget*/ + + /** Events of optional LVGL components*/ + LV_EVENT_INVALIDATE_AREA, + LV_EVENT_RESOLUTION_CHANGED, + LV_EVENT_COLOR_FORMAT_CHANGED, + LV_EVENT_REFR_REQUEST, + LV_EVENT_REFR_START, + LV_EVENT_REFR_READY, + LV_EVENT_RENDER_START, + LV_EVENT_RENDER_READY, + LV_EVENT_FLUSH_START, + LV_EVENT_FLUSH_FINISH, + LV_EVENT_FLUSH_WAIT_START, + LV_EVENT_FLUSH_WAIT_FINISH, + + LV_EVENT_VSYNC, + + LV_EVENT_LAST, /** Number of default events*/ + + LV_EVENT_PREPROCESS = 0x8000, /** This is a flag that can be set with an event so it's processed + before the class default event processing */ + LV_EVENT_MARKED_DELETING = 0x10000, +} lv_event_code_t; + +typedef struct { + lv_array_t array; + uint8_t is_traversing: 1; /**< True: the list is being nested traversed */ + uint8_t has_marked_deleting: 1; /**< True: the list has marked deleting objects + when some of events are marked as deleting */ +} lv_event_list_t; + +/** + * @brief Event callback. + * Events are used to notify the user of some action being taken on the object. + * For details, see ::lv_event_t. + */ + +lv_result_t lv_event_send(lv_event_list_t * list, lv_event_t * e, bool preprocess); + +lv_event_dsc_t * lv_event_add(lv_event_list_t * list, lv_event_cb_t cb, lv_event_code_t filter, void * user_data); +bool lv_event_remove_dsc(lv_event_list_t * list, lv_event_dsc_t * dsc); + +uint32_t lv_event_get_count(lv_event_list_t * list); + +lv_event_dsc_t * lv_event_get_dsc(lv_event_list_t * list, uint32_t index); + +lv_event_cb_t lv_event_dsc_get_cb(lv_event_dsc_t * dsc); + +void * lv_event_dsc_get_user_data(lv_event_dsc_t * dsc); + +bool lv_event_remove(lv_event_list_t * list, uint32_t index); + +void lv_event_remove_all(lv_event_list_t * list); + +/** + * Get the object originally targeted by the event. It's the same even if the event is bubbled. + * @param e pointer to the event descriptor + * @return the target of the event_code + */ +void * lv_event_get_target(lv_event_t * e); + +/** + * Get the current target of the event. It's the object which event handler being called. + * If the event is not bubbled it's the same as "normal" target. + * @param e pointer to the event descriptor + * @return pointer to the current target of the event_code + */ +void * lv_event_get_current_target(lv_event_t * e); + +/** + * Get the event code of an event + * @param e pointer to the event descriptor + * @return the event code. (E.g. `LV_EVENT_CLICKED`, `LV_EVENT_FOCUSED`, etc) + */ +lv_event_code_t lv_event_get_code(lv_event_t * e); + +/** + * Get the parameter passed when the event was sent + * @param e pointer to the event descriptor + * @return pointer to the parameter + */ +void * lv_event_get_param(lv_event_t * e); + +/** + * Get the user_data passed when the event was registered on the object + * @param e pointer to the event descriptor + * @return pointer to the user_data + */ +void * lv_event_get_user_data(lv_event_t * e); + +/** + * Stop the event from bubbling. + * This is only valid when called in the middle of an event processing chain. + * @param e pointer to the event descriptor + */ +void lv_event_stop_bubbling(lv_event_t * e); + +/** + * Stop processing this event. + * This is only valid when called in the middle of an event processing chain. + * @param e pointer to the event descriptor + */ +void lv_event_stop_processing(lv_event_t * e); + +/** + * Register a new, custom event ID. + * It can be used the same way as e.g. `LV_EVENT_CLICKED` to send custom events + * @return the new event id + * + * Example: + * @code + * uint32_t LV_EVENT_MINE = 0; + * ... + * e = lv_event_register_id(); + * ... + * lv_obj_send_event(obj, LV_EVENT_MINE, &some_data); + * @endcode + */ +uint32_t lv_event_register_id(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_EVENT_H*/ diff --git a/test/include/liblvgl/misc/lv_event_private.h b/test/include/liblvgl/misc/lv_event_private.h new file mode 100644 index 00000000..5ba0e5a5 --- /dev/null +++ b/test/include/liblvgl/misc/lv_event_private.h @@ -0,0 +1,73 @@ +/** + * @file lv_event_private.h + * + */ + +#ifndef LV_EVENT_PRIVATE_H +#define LV_EVENT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_event.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_event_dsc_t { + lv_event_cb_t cb; + void * user_data; + uint32_t filter; +}; + +struct _lv_event_t { + void * current_target; + void * original_target; + lv_event_code_t code; + void * user_data; + void * param; + lv_event_t * prev; + uint8_t deleted : 1; + uint8_t stop_processing : 1; + uint8_t stop_bubbling : 1; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_event_push(lv_event_t * e); + +void lv_event_pop(lv_event_t * e); + +/** + * Nested events can be called and one of them might belong to an object that is being deleted. + * Mark this object's `event_temp_data` deleted to know that its `lv_obj_send_event` should return `LV_RESULT_INVALID` + * @param target pointer to an event target which was deleted + */ +void lv_event_mark_deleted(void * target); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_EVENT_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_fs.h b/test/include/liblvgl/misc/lv_fs.h new file mode 100644 index 00000000..075171b4 --- /dev/null +++ b/test/include/liblvgl/misc/lv_fs.h @@ -0,0 +1,258 @@ +/** + * @file lv_fs.h + * + */ + +#ifndef LV_FS_H +#define LV_FS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ +#define LV_FS_MAX_FN_LENGTH 64 +#define LV_FS_MAX_PATH_LENGTH 256 + +#define LV_FS_CACHE_FROM_BUFFER UINT32_MAX + +/********************** + * TYPEDEFS + **********************/ + +/** + * Errors in the file system module. + */ +typedef enum { + LV_FS_RES_OK = 0, + LV_FS_RES_HW_ERR, /*Low level hardware error*/ + LV_FS_RES_FS_ERR, /*Error in the file system structure*/ + LV_FS_RES_NOT_EX, /*Driver, file or directory is not exists*/ + LV_FS_RES_FULL, /*Disk full*/ + LV_FS_RES_LOCKED, /*The file is already opened*/ + LV_FS_RES_DENIED, /*Access denied. Check 'fs_open' modes and write protect*/ + LV_FS_RES_BUSY, /*The file system now can't handle it, try later*/ + LV_FS_RES_TOUT, /*Process time outed*/ + LV_FS_RES_NOT_IMP, /*Requested function is not implemented*/ + LV_FS_RES_OUT_OF_MEM, /*Not enough memory for an internal operation*/ + LV_FS_RES_INV_PARAM, /*Invalid parameter among arguments*/ + LV_FS_RES_UNKNOWN, /*Other unknown error*/ +} lv_fs_res_t; + +/** + * File open mode. + */ +typedef enum { + LV_FS_MODE_WR = 0x01, + LV_FS_MODE_RD = 0x02, +} lv_fs_mode_t; + +/** + * Seek modes. + */ +typedef enum { + LV_FS_SEEK_SET = 0x00, /**< Set the position from absolutely (from the start of file)*/ + LV_FS_SEEK_CUR = 0x01, /**< Set the position from the current position*/ + LV_FS_SEEK_END = 0x02, /**< Set the position from the end of the file*/ +} lv_fs_whence_t; + +struct _lv_fs_drv_t; +typedef struct _lv_fs_drv_t lv_fs_drv_t; +struct _lv_fs_drv_t { + char letter; + uint32_t cache_size; + bool (*ready_cb)(lv_fs_drv_t * drv); + + void * (*open_cb)(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode); + lv_fs_res_t (*close_cb)(lv_fs_drv_t * drv, void * file_p); + lv_fs_res_t (*read_cb)(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); + lv_fs_res_t (*write_cb)(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); + lv_fs_res_t (*seek_cb)(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); + lv_fs_res_t (*tell_cb)(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); + + void * (*dir_open_cb)(lv_fs_drv_t * drv, const char * path); + lv_fs_res_t (*dir_read_cb)(lv_fs_drv_t * drv, void * rddir_p, char * fn, uint32_t fn_len); + lv_fs_res_t (*dir_close_cb)(lv_fs_drv_t * drv, void * rddir_p); + + void * user_data; /**< Custom file user data*/ +}; + +typedef struct { + void * file_d; + lv_fs_drv_t * drv; + lv_fs_file_cache_t * cache; +} lv_fs_file_t; + + +typedef struct { + void * dir_d; + lv_fs_drv_t * drv; +} lv_fs_dir_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a file system driver with default values. + * It is used to ensure all fields have known values and not memory junk. + * After it you can set the fields. + * @param drv pointer to driver variable to initialize + */ +void lv_fs_drv_init(lv_fs_drv_t * drv); + +/** + * Add a new drive + * @param drv pointer to an lv_fs_drv_t structure which is inited with the + * corresponding function pointers. Only pointer is saved, so the + * driver should be static or dynamically allocated. + */ +void lv_fs_drv_register(lv_fs_drv_t * drv); + +/** + * Give a pointer to a driver from its letter + * @param letter the driver letter + * @return pointer to a driver or NULL if not found + */ +lv_fs_drv_t * lv_fs_get_drv(char letter); + +/** + * Test if a drive is ready or not. If the `ready` function was not initialized `true` will be + * returned. + * @param letter letter of the drive + * @return true: drive is ready; false: drive is not ready + */ +bool lv_fs_is_ready(char letter); + +/** + * Open a file + * @param file_p pointer to a lv_fs_file_t variable + * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt) + * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR + * @return LV_FS_RES_OK or any error from lv_fs_res_t enum + */ +lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode); + +/** + * Make a path object for the memory-mapped file compatible with the file system interface + * @param path path to a lv_fs_path_ex object + * @param letter the letter of the driver. E.g. `LV_FS_MEMFS_LETTER` + * @param buf address of the memory buffer + * @param size size of the memory buffer in bytes + */ +void lv_fs_make_path_from_buffer(lv_fs_path_ex_t * path, char letter, const void * buf, uint32_t size); + +/** + * Close an already opened file + * @param file_p pointer to a lv_fs_file_t variable + * @return LV_FS_RES_OK or any error from lv_fs_res_t enum + */ +lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p); + +/** + * Read from a file + * @param file_p pointer to a lv_fs_file_t variable + * @param buf pointer to a buffer where the read bytes are stored + * @param btr Bytes To Read + * @param br the number of real read bytes (Bytes Read). NULL if unused. + * @return LV_FS_RES_OK or any error from lv_fs_res_t enum + */ +lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br); + +/** + * Write into a file + * @param file_p pointer to a lv_fs_file_t variable + * @param buf pointer to a buffer with the bytes to write + * @param btw Bytes To Write + * @param bw the number of real written bytes (Bytes Written). NULL if unused. + * @return LV_FS_RES_OK or any error from lv_fs_res_t enum + */ +lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw); + +/** + * Set the position of the 'cursor' (read write pointer) in a file + * @param file_p pointer to a lv_fs_file_t variable + * @param pos the new position expressed in bytes index (0: start of file) + * @param whence tells from where to set position. See lv_fs_whence_t + * @return LV_FS_RES_OK or any error from lv_fs_res_t enum + */ +lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence); + +/** + * Give the position of the read write pointer + * @param file_p pointer to a lv_fs_file_t variable + * @param pos pointer to store the position of the read write pointer + * @return LV_FS_RES_OK or any error from 'fs_res_t' + */ +lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos); + +/** + * Initialize a 'fs_dir_t' variable for directory reading + * @param rddir_p pointer to a 'lv_fs_dir_t' variable + * @param path path to a directory + * @return LV_FS_RES_OK or any error from lv_fs_res_t enum + */ +lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path); + +/** + * Read the next filename form a directory. + * The name of the directories will begin with '/' + * @param rddir_p pointer to an initialized 'fs_dir_t' variable + * @param fn pointer to a buffer to store the filename + * @param fn_len length of the buffer to store the filename + * @return LV_FS_RES_OK or any error from lv_fs_res_t enum + */ +lv_fs_res_t lv_fs_dir_read(lv_fs_dir_t * rddir_p, char * fn, uint32_t fn_len); + +/** + * Close the directory reading + * @param rddir_p pointer to an initialized 'fs_dir_t' variable + * @return LV_FS_RES_OK or any error from lv_fs_res_t enum + */ +lv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p); + +/** + * Fill a buffer with the letters of existing drivers + * @param buf buffer to store the letters ('\0' added after the last letter) + * @return the buffer + */ +char * lv_fs_get_letters(char * buf); + +/** + * Return with the extension of the filename + * @param fn string with a filename + * @return pointer to the beginning extension or empty string if no extension + */ +const char * lv_fs_get_ext(const char * fn); + +/** + * Step up one level + * @param path pointer to a file name + * @return the truncated file name + */ +char * lv_fs_up(char * path); + +/** + * Get the last element of a path (e.g. U:/folder/file -> file) + * @param path pointer to a file name + * @return pointer to the beginning of the last element in the path + */ +const char * lv_fs_get_last(const char * path); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FS_H*/ diff --git a/test/include/liblvgl/misc/lv_fs_private.h b/test/include/liblvgl/misc/lv_fs_private.h new file mode 100644 index 00000000..c6b21374 --- /dev/null +++ b/test/include/liblvgl/misc/lv_fs_private.h @@ -0,0 +1,63 @@ +/** + * @file lv_fs_private.h + * + */ + +#ifndef LV_FS_PRIVATE_H +#define LV_FS_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_fs.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_fs_file_cache_t { + uint32_t start; + uint32_t end; + uint32_t file_position; + void * buffer; +}; + +/** Extended path object to specify buffer for memory-mapped files */ +struct _lv_fs_path_ex_t { + char path[4]; /**< This is needed to make it compatible with a normal path */ + const void * buffer; + uint32_t size; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the File system interface + */ +void lv_fs_init(void); + +/** + * Deinitialize the File system interface + */ +void lv_fs_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FS_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_iter.h b/test/include/liblvgl/misc/lv_iter.h new file mode 100644 index 00000000..469d441e --- /dev/null +++ b/test/include/liblvgl/misc/lv_iter.h @@ -0,0 +1,120 @@ +/** +* @file lv_iter.h +* + */ + + +#ifndef LV_ITER_H +#define LV_ITER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef lv_result_t (*lv_iter_next_cb)(void * instance, void * context, void * elem); +typedef void (*lv_iter_inspect_cb)(void * elem); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an iterator based on an instance, and then the next element of the iterator can be obtained through lv_iter_next, + * In order to obtain the next operation in a unified and abstract way. + * @param instance The instance to be iterated + * @param elem_size The size of the element to be iterated in bytes + * @param context_size The size of the context to be passed to the next_cb in bytes + * @param next_cb The callback function to get the next element + * @return The iterator object + */ +lv_iter_t * lv_iter_create(void * instance, uint32_t elem_size, uint32_t context_size, lv_iter_next_cb next_cb); + +/** + * Get the context of the iterator. You can use it to store some temporary variables associated with current iterator.. + * @param iter `lv_iter_t` object create before + * @return the iter context + */ +void * lv_iter_get_context(const lv_iter_t * iter); + +/** + * Destroy the iterator object, and release the context. Other resources allocated by the user are not released. + * The user needs to release it by itself. + * @param iter `lv_iter_t` object create before + */ +void lv_iter_destroy(lv_iter_t * iter); + +/** + * Get the next element of the iterator. + * @param iter `lv_iter_t` object create before + * @param elem The pointer to store the next element + * @return LV_RESULT_OK: Get the next element successfully + * LV_RESULT_INVALID: The next element is invalid + */ +lv_result_t lv_iter_next(lv_iter_t * iter, void * elem); + +/** + * Make the iterator peekable, which means that the user can peek the next element without advancing the iterator. + * @param iter `lv_iter_t` object create before + * @param capacity The capacity of the peek buffer + */ +void lv_iter_make_peekable(lv_iter_t * iter, uint32_t capacity); + +/** + * Peek the next element of the iterator without advancing the iterator. + * @param iter `lv_iter_t` object create before + * @param elem The pointer to store the next element + * @return LV_RESULT_OK: Peek the next element successfully + * LV_RESULT_INVALID: The next element is invalid + */ +lv_result_t lv_iter_peek(lv_iter_t * iter, void * elem); + +/** + * Only advance the iterator without getting the next element. + * @param iter `lv_iter_t` object create before + * @return LV_RESULT_OK: Peek the next element successfully + * LV_RESULT_INVALID: The next element is invalid + */ +lv_result_t lv_iter_peek_advance(lv_iter_t * iter); + +/** + * Reset the peek cursor to the `next` cursor. + * @param iter `lv_iter_t` object create before + * @return LV_RESULT_OK: Reset the peek buffer successfully + * LV_RESULT_INVALID: The peek buffer is invalid + */ +lv_result_t lv_iter_peek_reset(lv_iter_t * iter); + +/** + * Inspect the element of the iterator. The callback function will be called for each element of the iterator. + * @param iter `lv_iter_t` object create before + * @param inspect_cb The callback function to inspect the element + */ +void lv_iter_inspect(lv_iter_t * iter, lv_iter_inspect_cb inspect_cb); + +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ITER_H*/ diff --git a/test/include/liblvgl/misc/lv_ll.h b/test/include/liblvgl/misc/lv_ll.h new file mode 100644 index 00000000..ee0836ef --- /dev/null +++ b/test/include/liblvgl/misc/lv_ll.h @@ -0,0 +1,169 @@ +/** + * @file lv_ll.h + * Handle linked lists. The nodes are dynamically allocated by the 'lv_mem' module. + */ + +#ifndef LV_LL_H +#define LV_LL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Dummy type to make handling easier*/ +typedef uint8_t lv_ll_node_t; + +/** Description of a linked list*/ +typedef struct { + uint32_t n_size; + lv_ll_node_t * head; + lv_ll_node_t * tail; +} lv_ll_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize linked list + * @param ll_p pointer to lv_ll_t variable + * @param node_size the size of 1 node in bytes + */ +void lv_ll_init(lv_ll_t * ll_p, uint32_t node_size); + +/** + * Add a new head to a linked list + * @param ll_p pointer to linked list + * @return pointer to the new head + */ +void * lv_ll_ins_head(lv_ll_t * ll_p); + +/** + * Insert a new node in front of the n_act node + * @param ll_p pointer to linked list + * @param n_act pointer a node + * @return pointer to the new node + */ +void * lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act); + +/** + * Add a new tail to a linked list + * @param ll_p pointer to linked list + * @return pointer to the new tail + */ +void * lv_ll_ins_tail(lv_ll_t * ll_p); + +/** + * Remove the node 'node_p' from 'll_p' linked list. + * It does not free the memory of node. + * @param ll_p pointer to the linked list of 'node_p' + * @param node_p pointer to node in 'll_p' linked list + */ +void lv_ll_remove(lv_ll_t * ll_p, void * node_p); + +void lv_ll_clear_custom(lv_ll_t * ll_p, void(*cleanup)(void *)); + +/** + * Remove and free all elements from a linked list. The list remain valid but become empty. + * @param ll_p pointer to linked list + */ +void lv_ll_clear(lv_ll_t * ll_p); + +/** + * Move a node to a new linked list + * @param ll_ori_p pointer to the original (old) linked list + * @param ll_new_p pointer to the new linked list + * @param node pointer to a node + * @param head true: be the head in the new list + * false be the tail in the new list + */ +void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool head); + +/** + * Return with head node of the linked list + * @param ll_p pointer to linked list + * @return pointer to the head of 'll_p' + */ +void * lv_ll_get_head(const lv_ll_t * ll_p); + +/** + * Return with tail node of the linked list + * @param ll_p pointer to linked list + * @return pointer to the tail of 'll_p' + */ +void * lv_ll_get_tail(const lv_ll_t * ll_p); + +/** + * Return with the pointer of the next node after 'n_act' + * @param ll_p pointer to linked list + * @param n_act pointer a node + * @return pointer to the next node + */ +void * lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act); + +/** + * Return with the pointer of the previous node after 'n_act' + * @param ll_p pointer to linked list + * @param n_act pointer a node + * @return pointer to the previous node + */ +void * lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act); + +/** + * Return the length of the linked list. + * @param ll_p pointer to linked list + * @return length of the linked list + */ +uint32_t lv_ll_get_len(const lv_ll_t * ll_p); + +/* + * TODO + * @param ll_p + * @param n1_p + * @param n2_p +void lv_ll_swap(lv_ll_t * ll_p, void * n1_p, void * n2_p); + */ + +/** + * Move a node before another node in the same linked list + * + * @param ll_p pointer to a linked list + * @param n_act pointer to node to move + * @param n_after pointer to a node which should be after `n_act` + */ +void lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after); + +/** + * Check if a linked list is empty + * @param ll_p pointer to a linked list + * @return true: the linked list is empty; false: not empty + */ +bool lv_ll_is_empty(lv_ll_t * ll_p); + +/********************** + * MACROS + **********************/ + +#define LV_LL_READ(list, i) for(i = lv_ll_get_head(list); i != NULL; i = lv_ll_get_next(list, i)) + +#define LV_LL_READ_BACK(list, i) for(i = lv_ll_get_tail(list); i != NULL; i = lv_ll_get_prev(list, i)) + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/test/include/liblvgl/misc/lv_log.h b/test/include/liblvgl/misc/lv_log.h new file mode 100644 index 00000000..7774ba6f --- /dev/null +++ b/test/include/liblvgl/misc/lv_log.h @@ -0,0 +1,162 @@ +/** + * @file lv_log.h + * + */ + +#ifndef LV_LOG_H +#define LV_LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/*Possible log level. For compatibility declare it independently from `LV_USE_LOG`*/ + +#define LV_LOG_LEVEL_TRACE 0 /**< Log detailed information. */ +#define LV_LOG_LEVEL_INFO 1 /**< Log important events. */ +#define LV_LOG_LEVEL_WARN 2 /**< Log if something unwanted happened but didn't caused problem. */ +#define LV_LOG_LEVEL_ERROR 3 /**< Log only critical issues, when system may fail. */ +#define LV_LOG_LEVEL_USER 4 /**< Log only custom log messages added by the user. */ +#define LV_LOG_LEVEL_NONE 5 /**< Do not log anything. */ +#define LV_LOG_LEVEL_NUM 6 /**< Number of log levels */ + +LV_EXPORT_CONST_INT(LV_LOG_LEVEL_TRACE); +LV_EXPORT_CONST_INT(LV_LOG_LEVEL_INFO); +LV_EXPORT_CONST_INT(LV_LOG_LEVEL_WARN); +LV_EXPORT_CONST_INT(LV_LOG_LEVEL_ERROR); +LV_EXPORT_CONST_INT(LV_LOG_LEVEL_USER); +LV_EXPORT_CONST_INT(LV_LOG_LEVEL_NONE); + +typedef int8_t lv_log_level_t; + +#if LV_USE_LOG + +#if LV_LOG_USE_FILE_LINE +#define LV_LOG_FILE __FILE__ +#define LV_LOG_LINE __LINE__ +#else +#define LV_LOG_FILE NULL +#define LV_LOG_LINE 0 +#endif + +/********************** + * TYPEDEFS + **********************/ + +/** + * Log print function. Receives a string buffer to print". + */ +typedef void (*lv_log_print_g_cb_t)(lv_log_level_t level, const char * buf); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Register custom print/write function to call when a log is added. + * It can format its "File path", "Line number" and "Description" as required + * and send the formatted log message to a console or serial port. + * @param print_cb a function pointer to print a log + */ +void lv_log_register_print_cb(lv_log_print_g_cb_t print_cb); + +/** + * Print a log message via `printf` if enabled with `LV_LOG_PRINTF` in `lv_conf.h` + * and/or a print callback if registered with `lv_log_register_print_cb` + * @param format printf-like format string + * @param ... parameters for `format` + */ +void lv_log(const char * format, ...) LV_FORMAT_ATTRIBUTE(1, 2); + +/** + * Add a log + * @param level the level of log. (From `lv_log_level_t` enum) + * @param file name of the file when the log added + * @param line line number in the source code where the log added + * @param func name of the function when the log added + * @param format printf-like format string + * @param ... parameters for `format` + */ +void lv_log_add(lv_log_level_t level, const char * file, int line, + const char * func, const char * format, ...) LV_FORMAT_ATTRIBUTE(5, 6); + +/********************** + * MACROS + **********************/ +#ifndef LV_LOG_TRACE +# if LV_LOG_LEVEL <= LV_LOG_LEVEL_TRACE +# define LV_LOG_TRACE(...) lv_log_add(LV_LOG_LEVEL_TRACE, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) +# else +# define LV_LOG_TRACE(...) do {}while(0) +# endif +#endif + +#ifndef LV_LOG_INFO +# if LV_LOG_LEVEL <= LV_LOG_LEVEL_INFO +# define LV_LOG_INFO(...) lv_log_add(LV_LOG_LEVEL_INFO, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) +# else +# define LV_LOG_INFO(...) do {}while(0) +# endif +#endif + +#ifndef LV_LOG_WARN +# if LV_LOG_LEVEL <= LV_LOG_LEVEL_WARN +# define LV_LOG_WARN(...) lv_log_add(LV_LOG_LEVEL_WARN, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) +# else +# define LV_LOG_WARN(...) do {}while(0) +# endif +#endif + +#ifndef LV_LOG_ERROR +# if LV_LOG_LEVEL <= LV_LOG_LEVEL_ERROR +# define LV_LOG_ERROR(...) lv_log_add(LV_LOG_LEVEL_ERROR, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) +# else +# define LV_LOG_ERROR(...) do {}while(0) +# endif +#endif + +#ifndef LV_LOG_USER +# if LV_LOG_LEVEL <= LV_LOG_LEVEL_USER +# define LV_LOG_USER(...) lv_log_add(LV_LOG_LEVEL_USER, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) +# else +# define LV_LOG_USER(...) do {}while(0) +# endif +#endif + +#ifndef LV_LOG +# if LV_LOG_LEVEL < LV_LOG_LEVEL_NONE +# define LV_LOG(...) lv_log(__VA_ARGS__) +# else +# define LV_LOG(...) do {} while(0) +# endif +#endif + +#else /*LV_USE_LOG*/ + +/*Do nothing if `LV_USE_LOG 0`*/ +#define lv_log_add(level, file, line, ...) +#define LV_LOG_TRACE(...) do {}while(0) +#define LV_LOG_INFO(...) do {}while(0) +#define LV_LOG_WARN(...) do {}while(0) +#define LV_LOG_ERROR(...) do {}while(0) +#define LV_LOG_USER(...) do {}while(0) +#define LV_LOG(...) do {}while(0) + +#endif /*LV_USE_LOG*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LOG_H*/ diff --git a/test/include/liblvgl/misc/lv_lru.h b/test/include/liblvgl/misc/lv_lru.h new file mode 100644 index 00000000..fe41322d --- /dev/null +++ b/test/include/liblvgl/misc/lv_lru.h @@ -0,0 +1,83 @@ +/** + * @file lv_lru.h + * + */ + +#ifndef LV_LRU_H +#define LV_LRU_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lv_conf_internal.h" + +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_LRU_OK = 0, + LV_LRU_MISSING_CACHE, + LV_LRU_MISSING_KEY, + LV_LRU_MISSING_VALUE, + LV_LRU_LOCK_ERROR, + LV_LRU_VALUE_TOO_LARGE +} lv_lru_res_t; + +typedef void (*lv_lru_free_cb_t)(void * v); + +typedef struct _lv_lru_item_t lv_lru_item_t; + +typedef struct _lv_lru_t { + lv_lru_item_t ** items; + uint64_t access_count; + size_t free_memory; + size_t total_memory; + size_t average_item_length; + size_t hash_table_size; + uint32_t seed; + lv_lru_free_cb_t value_free; + lv_lru_free_cb_t key_free; + lv_lru_item_t * free_items; +} lv_lru_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_lru_t * lv_lru_create(size_t cache_size, size_t average_length, lv_lru_free_cb_t value_free, + lv_lru_free_cb_t key_free); + +void lv_lru_delete(lv_lru_t * cache); + +lv_lru_res_t lv_lru_set(lv_lru_t * cache, const void * key, size_t key_length, void * value, size_t value_length); + +lv_lru_res_t lv_lru_get(lv_lru_t * cache, const void * key, size_t key_size, void ** value); + +lv_lru_res_t lv_lru_remove(lv_lru_t * cache, const void * key, size_t key_size); + +/** + * remove the least recently used item + * + * @todo we can optimise this by finding the n lru items, where n = required_space / average_length + */ +void lv_lru_remove_lru_item(lv_lru_t * cache); +/********************** + * MACROS + **********************/ +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LRU_H*/ diff --git a/test/include/liblvgl/misc/lv_math.h b/test/include/liblvgl/misc/lv_math.h new file mode 100644 index 00000000..ef226f4d --- /dev/null +++ b/test/include/liblvgl/misc/lv_math.h @@ -0,0 +1,181 @@ +/** + * @file lv_math.h + * + */ + +#ifndef LV_MATH_H +#define LV_MATH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ +#define LV_TRIGO_SIN_MAX 32768 +#define LV_TRIGO_SHIFT 15 /**< >> LV_TRIGO_SHIFT to normalize*/ + +#define LV_BEZIER_VAL_SHIFT 10 /**< log2(LV_BEZIER_VAL_MAX): used to normalize up scaled values*/ +#define LV_BEZIER_VAL_MAX (1L << LV_BEZIER_VAL_SHIFT) /**< Max time in Bezier functions (not [0..1] to use integers)*/ +#define LV_BEZIER_VAL_FLOAT(f) ((int32_t)((f) * LV_BEZIER_VAL_MAX)) /**< Convert const float number cubic-bezier values to fix-point value*/ + +/** Align up value x to align, align must be a power of two */ +#define LV_ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) + +/** Round up value x to round, round can be any integer number */ +#define LV_ROUND_UP(x, round) ((((x) + ((round) - 1)) / (round)) * (round)) + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint16_t i; + uint16_t f; +} lv_sqrt_res_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +//! @cond Doxygen_Suppress +/** + * Return with sinus of an angle + * @param angle + * @return sinus of 'angle'. sin(-90) = -32767, sin(90) = 32767 + */ +int32_t /* LV_ATTRIBUTE_FAST_MEM */ lv_trigo_sin(int16_t angle); + +int32_t LV_ATTRIBUTE_FAST_MEM lv_trigo_cos(int16_t angle); + +//! @endcond + +/** + * Calculate the y value of cubic-bezier(x1, y1, x2, y2) function as specified x. + * @param x time in range of [0..LV_BEZIER_VAL_MAX] + * @param x1 x of control point 1 in range of [0..LV_BEZIER_VAL_MAX] + * @param y1 y of control point 1 in range of [0..LV_BEZIER_VAL_MAX] + * @param x2 x of control point 2 in range of [0..LV_BEZIER_VAL_MAX] + * @param y2 y of control point 2 in range of [0..LV_BEZIER_VAL_MAX] + * @return the value calculated + */ +int32_t lv_cubic_bezier(int32_t x, int32_t x1, int32_t y1, int32_t x2, int32_t y2); + +/** + * Calculate a value of a Cubic Bezier function. + * @param t time in range of [0..LV_BEZIER_VAL_MAX] + * @param u0 must be 0 + * @param u1 control value 1 values in range of [0..LV_BEZIER_VAL_MAX] + * @param u2 control value 2 in range of [0..LV_BEZIER_VAL_MAX] + * @param u3 must be LV_BEZIER_VAL_MAX + * @return the value calculated from the given parameters in range of [0..LV_BEZIER_VAL_MAX] + */ +int32_t lv_bezier3(int32_t t, int32_t u0, uint32_t u1, int32_t u2, int32_t u3); + + +/** + * Calculate the atan2 of a vector. + * @param x + * @param y + * @return the angle in degree calculated from the given parameters in range of [0..360] + */ +uint16_t lv_atan2(int x, int y); + +//! @cond Doxygen_Suppress + +/** + * Get the square root of a number + * @param x integer which square root should be calculated + * @param q store the result here. q->i: integer part, q->f: fractional part in 1/256 unit + * @param mask optional to skip some iterations if the magnitude of the root is known. + * Set to 0x8000 by default. + * If root < 16: mask = 0x80 + * If root < 256: mask = 0x800 + * Else: mask = 0x8000 + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_sqrt(uint32_t x, lv_sqrt_res_t * q, uint32_t mask); + +//! @endcond + +/** + * Alternative (fast, approximate) implementation for getting the square root of an integer. + * @param x integer which square root should be calculated + */ +int32_t /* LV_ATTRIBUTE_FAST_MEM */ lv_sqrt32(uint32_t x); + +/** + * Calculate the square of an integer (input range is 0..32767). + * @param x input + * @return square + */ +static inline int32_t lv_sqr(int32_t x) +{ + return x * x; +} + +/** + * Calculate the integer exponents. + * @param base + * @param exp + * @return base raised to the power exponent + */ +int64_t lv_pow(int64_t base, int8_t exp); + +/** + * Get the mapped of a number given an input and output range + * @param x integer which mapped value should be calculated + * @param min_in min input range + * @param max_in max input range + * @param min_out max output range + * @param max_out max output range + * @return the mapped number + */ +int32_t lv_map(int32_t x, int32_t min_in, int32_t max_in, int32_t min_out, int32_t max_out); + +/** + * Set the seed of the pseudo random number generator + * @param seed a number to initialize the random generator + */ +void lv_rand_set_seed(uint32_t seed); + +/** + * Get a pseudo random number in the given range + * @param min the minimum value + * @param max the maximum value + * @return return the random number. min <= return_value <= max + */ +uint32_t lv_rand(uint32_t min, uint32_t max); + +/********************** + * MACROS + **********************/ +#define LV_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define LV_MIN3(a, b, c) (LV_MIN(LV_MIN(a,b), c)) +#define LV_MIN4(a, b, c, d) (LV_MIN(LV_MIN(a,b), LV_MIN(c,d))) + +#define LV_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define LV_MAX3(a, b, c) (LV_MAX(LV_MAX(a,b), c)) +#define LV_MAX4(a, b, c, d) (LV_MAX(LV_MAX(a,b), LV_MAX(c,d))) + +#define LV_CLAMP(min, val, max) (LV_MAX(min, (LV_MIN(val, max)))) + +#define LV_ABS(x) ((x) > 0 ? (x) : (-(x))) +#define LV_UDIV255(x) (((x) * 0x8081U) >> 0x17) + +#define LV_IS_SIGNED(t) (((t)(-1)) < ((t)0)) +#define LV_UMAX_OF(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | (0xFULL << ((sizeof(t) * 8ULL) - 4ULL))) +#define LV_SMAX_OF(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | (0x7ULL << ((sizeof(t) * 8ULL) - 4ULL))) +#define LV_MAX_OF(t) ((unsigned long)(LV_IS_SIGNED(t) ? LV_SMAX_OF(t) : LV_UMAX_OF(t))) + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/test/include/liblvgl/misc/lv_matrix.h b/test/include/liblvgl/misc/lv_matrix.h new file mode 100644 index 00000000..7b8bb7f4 --- /dev/null +++ b/test/include/liblvgl/misc/lv_matrix.h @@ -0,0 +1,129 @@ +/** + * @file lv_matrix.h + * + */ + +#ifndef LV_MATRIX_H +#define LV_MATRIX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lv_conf_internal.h" + +#if LV_USE_MATRIX + +#include "lv_types.h" +#include "lv_area.h" + +/********************* + * DEFINES + *********************/ + +#if !LV_USE_FLOAT +#error "LV_USE_FLOAT is required for lv_matrix" +#endif + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_matrix_t { + float m[3][3]; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Set matrix to identity matrix + * @param matrix pointer to a matrix + */ +void lv_matrix_identity(lv_matrix_t * matrix); + +/** + * Translate the matrix to new position + * @param matrix pointer to a matrix + * @param tx the amount of translate in x direction + * @param tx the amount of translate in y direction + */ +void lv_matrix_translate(lv_matrix_t * matrix, float tx, float ty); + +/** + * Change the scale factor of the matrix + * @param matrix pointer to a matrix + * @param scale_x the scale factor for the X direction + * @param scale_y the scale factor for the Y direction + */ +void lv_matrix_scale(lv_matrix_t * matrix, float scale_x, float scale_y); + +/** + * Rotate the matrix with origin + * @param matrix pointer to a matrix + * @param degree angle to rotate + */ +void lv_matrix_rotate(lv_matrix_t * matrix, float degree); + +/** + * Change the skew factor of the matrix + * @param matrix pointer to a matrix + * @param skew_x the skew factor for x direction + * @param skew_y the skew factor for y direction + */ +void lv_matrix_skew(lv_matrix_t * matrix, float skew_x, float skew_y); + +/** + * Multiply two matrix and store the result to the first one + * @param matrix pointer to a matrix + * @param matrix2 pointer to another matrix + */ +void lv_matrix_multiply(lv_matrix_t * matrix, const lv_matrix_t * mul); + +/** + * Invert the matrix + * @param matrix pointer to a matrix + * @param m pointer to another matrix (optional) + * @return true: the matrix is invertible, false: the matrix is singular and cannot be inverted + */ +bool lv_matrix_inverse(lv_matrix_t * matrix, const lv_matrix_t * m); + +/** + * Transform a point by a matrix + * @param matrix pointer to a matrix + * @param point pointer to a point + * @return the transformed point + */ +lv_point_precise_t lv_matrix_transform_precise_point(const lv_matrix_t * matrix, const lv_point_precise_t * point); + +/** + * Transform an area by a matrix + * @param matrix pointer to a matrix + * @param area pointer to an area + * @return the transformed area + */ +lv_area_t lv_matrix_transform_area(const lv_matrix_t * matrix, const lv_area_t * area); + +/** + * Check if the matrix is identity or translation matrix + * @param matrix pointer to a matrix + * @return true: the matrix is identity or translation matrix, false: the matrix is not identity or translation matrix + */ +bool lv_matrix_is_identity_or_translation(const lv_matrix_t * matrix); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_MATRIX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MATRIX_H*/ diff --git a/test/include/liblvgl/misc/lv_palette.h b/test/include/liblvgl/misc/lv_palette.h new file mode 100644 index 00000000..d2f408ca --- /dev/null +++ b/test/include/liblvgl/misc/lv_palette.h @@ -0,0 +1,68 @@ +/** + * @file lv_palette.h + * + */ + +#ifndef LV_PALETTE_H +#define LV_PALETTE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_color.h" +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_PALETTE_RED, + LV_PALETTE_PINK, + LV_PALETTE_PURPLE, + LV_PALETTE_DEEP_PURPLE, + LV_PALETTE_INDIGO, + LV_PALETTE_BLUE, + LV_PALETTE_LIGHT_BLUE, + LV_PALETTE_CYAN, + LV_PALETTE_TEAL, + LV_PALETTE_GREEN, + LV_PALETTE_LIGHT_GREEN, + LV_PALETTE_LIME, + LV_PALETTE_YELLOW, + LV_PALETTE_AMBER, + LV_PALETTE_ORANGE, + LV_PALETTE_DEEP_ORANGE, + LV_PALETTE_BROWN, + LV_PALETTE_BLUE_GREY, + LV_PALETTE_GREY, + LV_PALETTE_LAST, + LV_PALETTE_NONE = 0xff, +} lv_palette_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/*Source: https://vuetifyjs.com/en/styles/colors/#material-colors*/ + +lv_color_t lv_palette_main(lv_palette_t p); +lv_color_t lv_palette_lighten(lv_palette_t p, uint8_t lvl); +lv_color_t lv_palette_darken(lv_palette_t p, uint8_t lvl); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_PALETTE_H*/ diff --git a/test/include/liblvgl/misc/lv_profiler.h b/test/include/liblvgl/misc/lv_profiler.h new file mode 100644 index 00000000..84be4e1f --- /dev/null +++ b/test/include/liblvgl/misc/lv_profiler.h @@ -0,0 +1,172 @@ +/** + * @file lv_profiler.h + * + */ + +#ifndef LV_PROFILER_H +#define LV_PROFILER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lv_conf_internal.h" + +#if LV_USE_PROFILER + +#include LV_PROFILER_INCLUDE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#else + +#define LV_PROFILER_BEGIN +#define LV_PROFILER_END +#define LV_PROFILER_BEGIN_TAG(tag) LV_UNUSED(tag) +#define LV_PROFILER_END_TAG(tag) LV_UNUSED(tag) + +#endif /*LV_USE_PROFILER*/ + +#if LV_USE_PROFILER && LV_PROFILER_LAYOUT +#define LV_PROFILER_LAYOUT_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_LAYOUT_END LV_PROFILER_END +#define LV_PROFILER_LAYOUT_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_LAYOUT_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_LAYOUT_BEGIN +#define LV_PROFILER_LAYOUT_END +#define LV_PROFILER_LAYOUT_BEGIN_TAG(tag) +#define LV_PROFILER_LAYOUT_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_STYLE +#define LV_PROFILER_STYLE_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_STYLE_END LV_PROFILER_END +#define LV_PROFILER_STYLE_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_STYLE_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_STYLE_BEGIN +#define LV_PROFILER_STYLE_END +#define LV_PROFILER_STYLE_BEGIN_TAG(tag) +#define LV_PROFILER_STYLE_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_DRAW +#define LV_PROFILER_DRAW_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_DRAW_END LV_PROFILER_END +#define LV_PROFILER_DRAW_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_DRAW_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_DRAW_BEGIN +#define LV_PROFILER_DRAW_END +#define LV_PROFILER_DRAW_BEGIN_TAG(tag) +#define LV_PROFILER_DRAW_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_DECODER +#define LV_PROFILER_DECODER_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_DECODER_END LV_PROFILER_END +#define LV_PROFILER_DECODER_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_DECODER_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_DECODER_BEGIN +#define LV_PROFILER_DECODER_END +#define LV_PROFILER_DECODER_BEGIN_TAG(tag) +#define LV_PROFILER_DECODER_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_REFR +#define LV_PROFILER_REFR_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_REFR_END LV_PROFILER_END +#define LV_PROFILER_REFR_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_REFR_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_REFR_BEGIN +#define LV_PROFILER_REFR_END +#define LV_PROFILER_REFR_BEGIN_TAG(tag) +#define LV_PROFILER_REFR_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_INDEV +#define LV_PROFILER_INDEV_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_INDEV_END LV_PROFILER_END +#define LV_PROFILER_INDEV_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_INDEV_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_INDEV_BEGIN +#define LV_PROFILER_INDEV_END +#define LV_PROFILER_INDEV_BEGIN_TAG(tag) +#define LV_PROFILER_INDEV_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_FONT +#define LV_PROFILER_FONT_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_FONT_END LV_PROFILER_END +#define LV_PROFILER_FONT_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_FONT_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_FONT_BEGIN +#define LV_PROFILER_FONT_END +#define LV_PROFILER_FONT_BEGIN_TAG(tag) +#define LV_PROFILER_FONT_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_CACHE +#define LV_PROFILER_CACHE_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_CACHE_END LV_PROFILER_END +#define LV_PROFILER_CACHE_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_CACHE_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_CACHE_BEGIN +#define LV_PROFILER_CACHE_END +#define LV_PROFILER_CACHE_BEGIN_TAG(tag) +#define LV_PROFILER_CACHE_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_FS +#define LV_PROFILER_FS_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_FS_END LV_PROFILER_END +#define LV_PROFILER_FS_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_FS_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_FS_BEGIN +#define LV_PROFILER_FS_END +#define LV_PROFILER_FS_BEGIN_TAG(tag) +#define LV_PROFILER_FS_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_TIMER +#define LV_PROFILER_TIMER_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_TIMER_END LV_PROFILER_END +#define LV_PROFILER_TIMER_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_TIMER_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_TIMER_BEGIN +#define LV_PROFILER_TIMER_END +#define LV_PROFILER_TIMER_BEGIN_TAG(tag) +#define LV_PROFILER_TIMER_END_TAG(tag) +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_PROFILER_H*/ diff --git a/test/include/liblvgl/misc/lv_profiler_builtin.h b/test/include/liblvgl/misc/lv_profiler_builtin.h new file mode 100644 index 00000000..aa0220b2 --- /dev/null +++ b/test/include/liblvgl/misc/lv_profiler_builtin.h @@ -0,0 +1,85 @@ +/** + * @file lv_profiler_builtin.h + * + */ + +#ifndef LV_PROFILER_BUILTIN_H +#define LV_PROFILER_BUILTIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lv_conf_internal.h" + +#if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN + +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +#define LV_PROFILER_BUILTIN_BEGIN_TAG(tag) lv_profiler_builtin_write((tag), 'B') +#define LV_PROFILER_BUILTIN_END_TAG(tag) lv_profiler_builtin_write((tag), 'E') +#define LV_PROFILER_BUILTIN_BEGIN LV_PROFILER_BUILTIN_BEGIN_TAG(__func__) +#define LV_PROFILER_BUILTIN_END LV_PROFILER_BUILTIN_END_TAG(__func__) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Initialize the configuration of the built-in profiler + * @param config Pointer to the configuration structure of the built-in profiler + */ +void lv_profiler_builtin_config_init(lv_profiler_builtin_config_t * config); + +/** + * @brief Initialize the built-in profiler with the given configuration + * @param config Pointer to the configuration structure of the built-in profiler + */ +void lv_profiler_builtin_init(const lv_profiler_builtin_config_t * config); + +/** + * @brief Uninitialize the built-in profiler + */ +void lv_profiler_builtin_uninit(void); + +/** + * @brief Enable or disable the built-in profiler + * @param enable true to enable the built-in profiler, false to disable + */ +void lv_profiler_builtin_set_enable(bool enable); + +/** + * @brief Flush the profiling data to the console + */ +void lv_profiler_builtin_flush(void); + +/** + * @brief Write the profiling data for a function with the given tag + * @param func Name of the function being profiled + * @param tag Tag to associate with the profiling data for the function + */ +void lv_profiler_builtin_write(const char * func, char tag); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_PROFILER_BUILTIN*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_PROFILER_BUILTIN_H*/ diff --git a/test/include/liblvgl/misc/lv_profiler_builtin_private.h b/test/include/liblvgl/misc/lv_profiler_builtin_private.h new file mode 100644 index 00000000..a134620d --- /dev/null +++ b/test/include/liblvgl/misc/lv_profiler_builtin_private.h @@ -0,0 +1,56 @@ +/** + * @file lv_profiler_builtin_private.h + * + */ + +#ifndef LV_PROFILER_BUILTIN_PRIVATE_H +#define LV_PROFILER_BUILTIN_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_profiler_builtin.h" + +#if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * @brief LVGL profiler built-in configuration structure + */ +struct _lv_profiler_builtin_config_t { + size_t buf_size; /**< The size of the buffer used for profiling data */ + uint32_t tick_per_sec; /**< The number of ticks per second */ + uint32_t (*tick_get_cb)(void); /**< Callback function to get the current tick count */ + void (*flush_cb)(const char * buf); /**< Callback function to flush the profiling data */ + int (*tid_get_cb)(void); /**< Callback function to get the current thread ID */ + int (*cpu_get_cb)(void); /**< Callback function to get the current CPU */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_PROFILER_BUILTIN_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_rb.h b/test/include/liblvgl/misc/lv_rb.h new file mode 100644 index 00000000..bec0a788 --- /dev/null +++ b/test/include/liblvgl/misc/lv_rb.h @@ -0,0 +1,66 @@ +/** + * @file lv_rb.h + * + */ + +#ifndef LV_RB_H +#define LV_RB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_types.h" +#include "lv_assert.h" +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_RB_COLOR_RED, + LV_RB_COLOR_BLACK +} lv_rb_color_t; + +typedef int8_t lv_rb_compare_res_t; + +typedef lv_rb_compare_res_t (*lv_rb_compare_t)(const void * a, const void * b); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +bool lv_rb_init(lv_rb_t * tree, lv_rb_compare_t compare, size_t node_size); +lv_rb_node_t * lv_rb_insert(lv_rb_t * tree, void * key); +lv_rb_node_t * lv_rb_find(lv_rb_t * tree, const void * key); +void * lv_rb_remove_node(lv_rb_t * tree, lv_rb_node_t * node); +void * lv_rb_remove(lv_rb_t * tree, const void * key); +bool lv_rb_drop_node(lv_rb_t * tree, lv_rb_node_t * node); +bool lv_rb_drop(lv_rb_t * tree, const void * key); +lv_rb_node_t * lv_rb_minimum(lv_rb_t * node); +lv_rb_node_t * lv_rb_maximum(lv_rb_t * node); +lv_rb_node_t * lv_rb_minimum_from(lv_rb_node_t * node); +lv_rb_node_t * lv_rb_maximum_from(lv_rb_node_t * node); +void lv_rb_destroy(lv_rb_t * tree); + +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_RB_H*/ diff --git a/test/include/liblvgl/misc/lv_rb_private.h b/test/include/liblvgl/misc/lv_rb_private.h new file mode 100644 index 00000000..492ca2e2 --- /dev/null +++ b/test/include/liblvgl/misc/lv_rb_private.h @@ -0,0 +1,54 @@ +/** + * @file lv_rb_private.h + * + */ + +#ifndef LV_RB_PRIVATE_H +#define LV_RB_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_rb.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_rb_node_t { + struct _lv_rb_node_t * parent; + struct _lv_rb_node_t * left; + struct _lv_rb_node_t * right; + lv_rb_color_t color; + void * data; +}; + +struct _lv_rb_t { + lv_rb_node_t * root; + lv_rb_compare_t compare; + size_t size; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_RB_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_style.h b/test/include/liblvgl/misc/lv_style.h new file mode 100644 index 00000000..19909dbe --- /dev/null +++ b/test/include/liblvgl/misc/lv_style.h @@ -0,0 +1,640 @@ +/** + * @file lv_style.h + * + */ + +#ifndef LV_STYLE_H +#define LV_STYLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../font/lv_font.h" +#include "lv_color.h" +#include "lv_area.h" +#include "lv_anim.h" +#include "lv_text.h" +#include "lv_types.h" +#include "lv_assert.h" +#include "lv_bidi.h" +#include "../layouts/lv_layout.h" + +/********************* + * DEFINES + *********************/ + +#define LV_STYLE_SENTINEL_VALUE 0xAABBCCDD + +/* + * Flags for style behavior + */ +#define LV_STYLE_PROP_FLAG_NONE (0) /**< No special behavior */ +#define LV_STYLE_PROP_FLAG_INHERITABLE (1 << 0) /**< Inherited */ +#define LV_STYLE_PROP_FLAG_EXT_DRAW_UPDATE (1 << 1) /**< Requires ext. draw size update when changed */ +#define LV_STYLE_PROP_FLAG_LAYOUT_UPDATE (1 << 2) /**< Requires layout update when changed */ +#define LV_STYLE_PROP_FLAG_PARENT_LAYOUT_UPDATE (1 << 3) /**< Requires layout update on parent when changed */ +#define LV_STYLE_PROP_FLAG_LAYER_UPDATE (1 << 4) /**< Affects layer handling */ +#define LV_STYLE_PROP_FLAG_TRANSFORM (1 << 5) /**< Affects the object's transformation */ +#define LV_STYLE_PROP_FLAG_ALL (0x3F) /**< Indicating all flags */ + +/* + * Other constants + */ +#define LV_SCALE_NONE 256 /**< Value for not zooming the image */ +LV_EXPORT_CONST_INT(LV_SCALE_NONE); + +// *INDENT-OFF* +#if LV_USE_ASSERT_STYLE +#define LV_STYLE_CONST_INIT(var_name, prop_array) \ + const lv_style_t var_name = { \ + .sentinel = LV_STYLE_SENTINEL_VALUE, \ + .values_and_props = (void*)prop_array, \ + .has_group = 0xFFFFFFFF, \ + .prop_cnt = 255 \ + } +#else +#define LV_STYLE_CONST_INIT(var_name, prop_array) \ + const lv_style_t var_name = { \ + .values_and_props = prop_array, \ + .has_group = 0xFFFFFFFF, \ + .prop_cnt = 255, \ + } +#endif +// *INDENT-ON* + +#define LV_STYLE_CONST_PROPS_END { .prop = LV_STYLE_PROP_INV, .value = { .num = 0 } } + +/********************** + * TYPEDEFS + **********************/ + +/** + * Possible options for blending opaque drawings + */ +typedef enum { + LV_BLEND_MODE_NORMAL, /**< Simply mix according to the opacity value*/ + LV_BLEND_MODE_ADDITIVE, /**< Add the respective color channels*/ + LV_BLEND_MODE_SUBTRACTIVE,/**< Subtract the foreground from the background*/ + LV_BLEND_MODE_MULTIPLY, /**< Multiply the foreground and background*/ +} lv_blend_mode_t; + +/** + * Some options to apply decorations on texts. + * 'OR'ed values can be used. + */ +typedef enum { + LV_TEXT_DECOR_NONE = 0x00, + LV_TEXT_DECOR_UNDERLINE = 0x01, + LV_TEXT_DECOR_STRIKETHROUGH = 0x02, +} lv_text_decor_t; + +/** + * Selects on which sides border should be drawn + * 'OR'ed values can be used. + */ +typedef enum { + LV_BORDER_SIDE_NONE = 0x00, + LV_BORDER_SIDE_BOTTOM = 0x01, + LV_BORDER_SIDE_TOP = 0x02, + LV_BORDER_SIDE_LEFT = 0x04, + LV_BORDER_SIDE_RIGHT = 0x08, + LV_BORDER_SIDE_FULL = 0x0F, + LV_BORDER_SIDE_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/ +} lv_border_side_t; + +/** + * The direction of the gradient. + */ +typedef enum { + LV_GRAD_DIR_NONE, /**< No gradient (the `grad_color` property is ignored)*/ + LV_GRAD_DIR_VER, /**< Simple vertical (top to bottom) gradient*/ + LV_GRAD_DIR_HOR, /**< Simple horizontal (left to right) gradient*/ + LV_GRAD_DIR_LINEAR, /**< Linear gradient defined by start and end points. Can be at any angle.*/ + LV_GRAD_DIR_RADIAL, /**< Radial gradient defined by start and end circles*/ + LV_GRAD_DIR_CONICAL, /**< Conical gradient defined by center point, start and end angles*/ +} lv_grad_dir_t; + +/** + * Gradient behavior outside the defined range. +*/ +typedef enum { + LV_GRAD_EXTEND_PAD, /**< Repeat the same color*/ + LV_GRAD_EXTEND_REPEAT, /**< Repeat the pattern*/ + LV_GRAD_EXTEND_REFLECT, /**< Repeat the pattern mirrored*/ +} lv_grad_extend_t; + +/** A gradient stop definition. + * This matches a color and a position in a virtual 0-255 scale. + */ +typedef struct { + lv_color_t color; /**< The stop color */ + lv_opa_t opa; /**< The opacity of the color*/ + uint8_t frac; /**< The stop position in 1/255 unit */ +} lv_gradient_stop_t; + +/** A descriptor of a gradient. */ +typedef struct { + lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ + uint8_t stops_count; /**< The number of used stops in the array */ + lv_grad_dir_t dir : 3; /**< The gradient direction. + * Any of LV_GRAD_DIR_NONE, LV_GRAD_DIR_VER, LV_GRAD_DIR_HOR, + * LV_GRAD_TYPE_LINEAR, LV_GRAD_TYPE_RADIAL, LV_GRAD_TYPE_CONICAL */ + lv_grad_extend_t extend : 2; /**< Behaviour outside the defined range. + * LV_GRAD_EXTEND_NONE, LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT, LV_GRAD_EXTEND_REFLECT */ +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + union { + /*Linear gradient parameters*/ + struct { + lv_point_t start; /**< Linear gradient vector start point */ + lv_point_t end; /**< Linear gradient vector end point */ + } linear; + /*Radial gradient parameters*/ + struct { + lv_point_t focal; /**< Center of the focal (starting) circle in local coordinates */ + /* (can be the same as the ending circle to create concentric circles) */ + lv_point_t focal_extent; /**< Point on the circle (can be the same as the center) */ + lv_point_t end; /**< Center of the ending circle in local coordinates */ + lv_point_t end_extent; /**< Point on the circle determining the radius of the gradient */ + } radial; + /*Conical gradient parameters*/ + struct { + lv_point_t center; /**< Conical gradient center point */ + int16_t start_angle; /**< Start angle 0..3600 */ + int16_t end_angle; /**< End angle 0..3600 */ + } conical; + } params; + void * state; +#endif +} lv_grad_dsc_t; + +/** + * A common type to handle all the property types in the same way. + */ +typedef union { + int32_t num; /**< Number integer number (opacity, enums, booleans or "normal" numbers)*/ + const void * ptr; /**< Constant pointers (font, cone text, etc)*/ + lv_color_t color; /**< Colors*/ +} lv_style_value_t; + +/** + * Enumeration of all built in style properties + * + * Props are split into groups of 16. When adding a new prop to a group, ensure it does not overflow into the next one. + */ +enum { + LV_STYLE_PROP_INV = 0, + + /*Group 0*/ + LV_STYLE_WIDTH = 1, + LV_STYLE_HEIGHT = 2, + LV_STYLE_LENGTH = 3, + + LV_STYLE_MIN_WIDTH = 4, + LV_STYLE_MAX_WIDTH = 5, + LV_STYLE_MIN_HEIGHT = 6, + LV_STYLE_MAX_HEIGHT = 7, + + LV_STYLE_X = 8, + LV_STYLE_Y = 9, + LV_STYLE_ALIGN = 10, + + LV_STYLE_RADIUS = 12, + + /*Group 1*/ + LV_STYLE_PAD_TOP = 16, + LV_STYLE_PAD_BOTTOM = 17, + LV_STYLE_PAD_LEFT = 18, + LV_STYLE_PAD_RIGHT = 19, + + LV_STYLE_PAD_ROW = 20, + LV_STYLE_PAD_COLUMN = 21, + LV_STYLE_LAYOUT = 22, + + LV_STYLE_MARGIN_TOP = 24, + LV_STYLE_MARGIN_BOTTOM = 25, + LV_STYLE_MARGIN_LEFT = 26, + LV_STYLE_MARGIN_RIGHT = 27, + + /*Group 2*/ + LV_STYLE_BG_COLOR = 28, + LV_STYLE_BG_OPA = 29, + + LV_STYLE_BG_GRAD_DIR = 32, + LV_STYLE_BG_MAIN_STOP = 33, + LV_STYLE_BG_GRAD_STOP = 34, + LV_STYLE_BG_GRAD_COLOR = 35, + + LV_STYLE_BG_MAIN_OPA = 36, + LV_STYLE_BG_GRAD_OPA = 37, + LV_STYLE_BG_GRAD = 38, + LV_STYLE_BASE_DIR = 39, + + LV_STYLE_BG_IMAGE_SRC = 40, + LV_STYLE_BG_IMAGE_OPA = 41, + LV_STYLE_BG_IMAGE_RECOLOR = 42, + LV_STYLE_BG_IMAGE_RECOLOR_OPA = 43, + + LV_STYLE_BG_IMAGE_TILED = 44, + LV_STYLE_CLIP_CORNER = 45, + + /*Group 3*/ + LV_STYLE_BORDER_WIDTH = 48, + LV_STYLE_BORDER_COLOR = 49, + LV_STYLE_BORDER_OPA = 50, + + LV_STYLE_BORDER_SIDE = 52, + LV_STYLE_BORDER_POST = 53, + + LV_STYLE_OUTLINE_WIDTH = 56, + LV_STYLE_OUTLINE_COLOR = 57, + LV_STYLE_OUTLINE_OPA = 58, + LV_STYLE_OUTLINE_PAD = 59, + + /*Group 4*/ + LV_STYLE_SHADOW_WIDTH = 60, + LV_STYLE_SHADOW_COLOR = 61, + LV_STYLE_SHADOW_OPA = 62, + + LV_STYLE_SHADOW_OFFSET_X = 64, + LV_STYLE_SHADOW_OFFSET_Y = 65, + LV_STYLE_SHADOW_SPREAD = 66, + + LV_STYLE_IMAGE_OPA = 68, + LV_STYLE_IMAGE_RECOLOR = 69, + LV_STYLE_IMAGE_RECOLOR_OPA = 70, + + LV_STYLE_LINE_WIDTH = 72, + LV_STYLE_LINE_DASH_WIDTH = 73, + LV_STYLE_LINE_DASH_GAP = 74, + LV_STYLE_LINE_ROUNDED = 75, + LV_STYLE_LINE_COLOR = 76, + LV_STYLE_LINE_OPA = 77, + + /*Group 5*/ + LV_STYLE_ARC_WIDTH = 80, + LV_STYLE_ARC_ROUNDED = 81, + LV_STYLE_ARC_COLOR = 82, + LV_STYLE_ARC_OPA = 83, + LV_STYLE_ARC_IMAGE_SRC = 84, + + LV_STYLE_TEXT_COLOR = 88, + LV_STYLE_TEXT_OPA = 89, + LV_STYLE_TEXT_FONT = 90, + + LV_STYLE_TEXT_LETTER_SPACE = 91, + LV_STYLE_TEXT_LINE_SPACE = 92, + LV_STYLE_TEXT_DECOR = 93, + LV_STYLE_TEXT_ALIGN = 94, + + LV_STYLE_OPA = 95, + LV_STYLE_OPA_LAYERED = 96, + LV_STYLE_COLOR_FILTER_DSC = 97, + LV_STYLE_COLOR_FILTER_OPA = 98, + LV_STYLE_ANIM = 99, + LV_STYLE_ANIM_DURATION = 100, + LV_STYLE_TRANSITION = 102, + LV_STYLE_BLEND_MODE = 103, + LV_STYLE_TRANSFORM_WIDTH = 104, + LV_STYLE_TRANSFORM_HEIGHT = 105, + LV_STYLE_TRANSLATE_X = 106, + LV_STYLE_TRANSLATE_Y = 107, + LV_STYLE_TRANSFORM_SCALE_X = 108, + LV_STYLE_TRANSFORM_SCALE_Y = 109, + LV_STYLE_TRANSFORM_ROTATION = 110, + LV_STYLE_TRANSFORM_PIVOT_X = 111, + LV_STYLE_TRANSFORM_PIVOT_Y = 112, + LV_STYLE_TRANSFORM_SKEW_X = 113, + LV_STYLE_TRANSFORM_SKEW_Y = 114, + LV_STYLE_BITMAP_MASK_SRC = 115, + LV_STYLE_ROTARY_SENSITIVITY = 116, + + LV_STYLE_FLEX_FLOW = 125, + LV_STYLE_FLEX_MAIN_PLACE = 126, + LV_STYLE_FLEX_CROSS_PLACE = 127, + LV_STYLE_FLEX_TRACK_PLACE = 128, + LV_STYLE_FLEX_GROW = 129, + + LV_STYLE_GRID_COLUMN_ALIGN = 130, + LV_STYLE_GRID_ROW_ALIGN = 131, + LV_STYLE_GRID_ROW_DSC_ARRAY = 132, + LV_STYLE_GRID_COLUMN_DSC_ARRAY = 133, + LV_STYLE_GRID_CELL_COLUMN_POS = 134, + LV_STYLE_GRID_CELL_COLUMN_SPAN = 135, + LV_STYLE_GRID_CELL_X_ALIGN = 136, + LV_STYLE_GRID_CELL_ROW_POS = 137, + LV_STYLE_GRID_CELL_ROW_SPAN = 138, + LV_STYLE_GRID_CELL_Y_ALIGN = 139, + + LV_STYLE_LAST_BUILT_IN_PROP = 140, + + LV_STYLE_NUM_BUILT_IN_PROPS = LV_STYLE_LAST_BUILT_IN_PROP + 1, + + LV_STYLE_PROP_ANY = 0xFF, + LV_STYLE_PROP_CONST = 0xFF /* magic value for const styles */ +}; + +typedef enum { + LV_STYLE_RES_NOT_FOUND, + LV_STYLE_RES_FOUND, +} lv_style_res_t; + +/** + * Descriptor for style transitions + */ +typedef struct { + const lv_style_prop_t * props; /**< An array with the properties to animate.*/ + void * user_data; /**< A custom user data that will be passed to the animation's user_data */ + lv_anim_path_cb_t path_xcb; /**< A path for the animation.*/ + uint32_t time; /**< Duration of the transition in [ms]*/ + uint32_t delay; /**< Delay before the transition in [ms]*/ +} lv_style_transition_dsc_t; + +/** + * Descriptor of a constant style property. + */ +typedef struct { + lv_style_prop_t prop; + lv_style_value_t value; +} lv_style_const_prop_t; + +/** + * Descriptor of a style (a collection of properties and values). + */ +typedef struct { + +#if LV_USE_ASSERT_STYLE + uint32_t sentinel; +#endif + + void * values_and_props; + + uint32_t has_group; + uint8_t prop_cnt; /**< 255 means it's a constant style*/ +} lv_style_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a style + * @param style pointer to a style to initialize + * @note Do not call `lv_style_init` on styles that already have some properties + * because this function won't free the used memory, just sets a default state for the style. + * In other words be sure to initialize styles only once! + */ +void lv_style_init(lv_style_t * style); + +/** + * Clear all properties from a style and free all allocated memories. + * @param style pointer to a style + */ +void lv_style_reset(lv_style_t * style); + +/** + * Check if a style is constant + * @param style pointer to a style + * @return true: the style is constant + */ +static inline bool lv_style_is_const(const lv_style_t * style) +{ + if(style->prop_cnt == 255) return true; + return false; +} + +/** + * Register a new style property for custom usage + * @return a new property ID, or LV_STYLE_PROP_INV if there are no more available. + * + * Example: + * @code + * lv_style_prop_t MY_PROP; + * static inline void lv_style_set_my_prop(lv_style_t * style, lv_color_t value) { + * lv_style_value_t v = {.color = value}; lv_style_set_prop(style, MY_PROP, v); } + * + * ... + * MY_PROP = lv_style_register_prop(); + * ... + * lv_style_set_my_prop(&style1, lv_palette_main(LV_PALETTE_RED)); + * @endcode + */ +lv_style_prop_t lv_style_register_prop(uint8_t flag); + +/** + * Get the number of custom properties that have been registered thus far. + */ +lv_style_prop_t lv_style_get_num_custom_props(void); + +/** + * Remove a property from a style + * @param style pointer to a style + * @param prop a style property ORed with a state. + * @return true: the property was found and removed; false: the property wasn't found + */ +bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop); + +/** + * Set the value of property in a style. + * This function shouldn't be used directly by the user. + * Instead use `lv_style_set_()`. E.g. `lv_style_set_bg_color()` + * @param style pointer to style + * @param prop the ID of a property (e.g. `LV_STYLE_BG_COLOR`) + * @param value `lv_style_value_t` variable in which a field is set according to the type of `prop` + */ +void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value); + +/** + * Get the value of a property + * @param style pointer to a style + * @param prop the ID of a property + * @param value pointer to a `lv_style_value_t` variable to store the value + * @return LV_RESULT_INVALID: the property wasn't found in the style (`value` is unchanged) + * LV_RESULT_OK: the property was fond, and `value` is set accordingly + * @note For performance reasons there are no sanity check on `style` + */ +lv_style_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value); + +/** + * Initialize a transition descriptor. + * @param tr pointer to a transition descriptor to initialize + * @param props an array with the properties to transition. The last element must be zero. + * @param path_cb an animation path (ease) callback. If `NULL` liner path will be used. + * @param time duration of the transition in [ms] + * @param delay delay before the transition in [ms] + * @param user_data any custom data that will be saved in the transition animation and will be available when `path_cb` is called + * + * Example: + * @code + * const static lv_style_prop_t trans_props[] = { LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR, 0 }; + * static lv_style_transition_dsc_t trans1; + * lv_style_transition_dsc_init(&trans1, trans_props, NULL, 300, 0, NULL); + * @endcode + */ +void lv_style_transition_dsc_init(lv_style_transition_dsc_t * tr, const lv_style_prop_t props[], + lv_anim_path_cb_t path_cb, uint32_t time, uint32_t delay, void * user_data); + +/** + * Get the default value of a property + * @param prop the ID of a property + * @return the default value + */ +lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop); + +/** + * Get the value of a property + * @param style pointer to a style + * @param prop the ID of a property + * @param value pointer to a `lv_style_value_t` variable to store the value + * @return LV_RESULT_INVALID: the property wasn't found in the style (`value` is unchanged) + * LV_RESULT_OK: the property was fond, and `value` is set accordingly + * @note For performance reasons there are no sanity check on `style` + * @note This function is the same as ::lv_style_get_prop but inlined. Use it only on performance critical places + */ +static inline lv_style_res_t lv_style_get_prop_inlined(const lv_style_t * style, lv_style_prop_t prop, + lv_style_value_t * value) +{ + if(lv_style_is_const(style)) { + lv_style_const_prop_t * props = (lv_style_const_prop_t *)style->values_and_props; + uint32_t i; + for(i = 0; props[i].prop != LV_STYLE_PROP_INV; i++) { + if(props[i].prop == prop) { + *value = props[i].value; + return LV_STYLE_RES_FOUND; + } + } + } + else { + lv_style_prop_t * props = (lv_style_prop_t *)style->values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + uint32_t i; + for(i = 0; i < style->prop_cnt; i++) { + if(props[i] == prop) { + lv_style_value_t * values = (lv_style_value_t *)style->values_and_props; + *value = values[i]; + return LV_STYLE_RES_FOUND; + } + } + } + return LV_STYLE_RES_NOT_FOUND; +} + +/** + * Checks if a style is empty (has no properties) + * @param style pointer to a style + * @return true if the style is empty + */ +bool lv_style_is_empty(const lv_style_t * style); + +/** + * Tell the group of a property. If the a property from a group is set in a style the (1 << group) bit of style->has_group is set. + * It allows early skipping the style if the property is not exists in the style at all. + * @param prop a style property + * @return the group [0..30] 30 means all the custom properties with index > 120 + */ +static inline uint32_t lv_style_get_prop_group(lv_style_prop_t prop) +{ + uint32_t group = prop >> 2; + if(group > 30) group = 31; /*The MSB marks all the custom properties*/ + return group; + +} + +/** + * Get the flags of a built-in or custom property. + * + * @param prop a style property + * @return the flags of the property + */ +uint8_t lv_style_prop_lookup_flags(lv_style_prop_t prop); + +#include "lv_style_gen.h" + +static inline void lv_style_set_size(lv_style_t * style, int32_t width, int32_t height) +{ + lv_style_set_width(style, width); + lv_style_set_height(style, height); +} + +static inline void lv_style_set_pad_all(lv_style_t * style, int32_t value) +{ + lv_style_set_pad_left(style, value); + lv_style_set_pad_right(style, value); + lv_style_set_pad_top(style, value); + lv_style_set_pad_bottom(style, value); +} + +static inline void lv_style_set_pad_hor(lv_style_t * style, int32_t value) +{ + lv_style_set_pad_left(style, value); + lv_style_set_pad_right(style, value); +} + +static inline void lv_style_set_pad_ver(lv_style_t * style, int32_t value) +{ + lv_style_set_pad_top(style, value); + lv_style_set_pad_bottom(style, value); +} + +static inline void lv_style_set_pad_gap(lv_style_t * style, int32_t value) +{ + lv_style_set_pad_row(style, value); + lv_style_set_pad_column(style, value); +} + +static inline void lv_style_set_margin_all(lv_style_t * style, int32_t value) +{ + lv_style_set_margin_left(style, value); + lv_style_set_margin_right(style, value); + lv_style_set_margin_top(style, value); + lv_style_set_margin_bottom(style, value); +} + +static inline void lv_style_set_transform_scale(lv_style_t * style, int32_t value) +{ + lv_style_set_transform_scale_x(style, value); + lv_style_set_transform_scale_y(style, value); +} + +/** + * @brief Check if the style property has a specified behavioral flag. + * + * Do not pass multiple flags to this function as backwards-compatibility is not guaranteed + * for that. + * + * @param prop Property ID + * @param flag Flag + * @return true if the flag is set for this property + */ +static inline bool lv_style_prop_has_flag(lv_style_prop_t prop, uint8_t flag) +{ + return lv_style_prop_lookup_flags(prop) & flag; +} + +/************************* + * GLOBAL VARIABLES + *************************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t lv_style_const_prop_id_inv; + +/********************** + * MACROS + **********************/ + +#if LV_USE_ASSERT_STYLE +# define LV_ASSERT_STYLE(style_p) \ + do { \ + LV_ASSERT_MSG(style_p != NULL, "The style is NULL"); \ + LV_ASSERT_MSG(style_p->sentinel == LV_STYLE_SENTINEL_VALUE, "Style is not initialized or corrupted"); \ + } while(0) +#else +# define LV_ASSERT_STYLE(p) do{}while(0) +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_STYLE_H*/ diff --git a/test/include/liblvgl/misc/lv_style_gen.h b/test/include/liblvgl/misc/lv_style_gen.h new file mode 100644 index 00000000..5714e74d --- /dev/null +++ b/test/include/liblvgl/misc/lv_style_gen.h @@ -0,0 +1,694 @@ + +/* + ********************************************************************** + * DO NOT EDIT + * This file is automatically generated by "style_api_gen.py" + ********************************************************************** + */ + + +#ifndef LV_STYLE_GEN_H +#define LV_STYLE_GEN_H + +#ifdef __cplusplus +extern "C" { +#endif + +void lv_style_set_width(lv_style_t * style, int32_t value); +void lv_style_set_min_width(lv_style_t * style, int32_t value); +void lv_style_set_max_width(lv_style_t * style, int32_t value); +void lv_style_set_height(lv_style_t * style, int32_t value); +void lv_style_set_min_height(lv_style_t * style, int32_t value); +void lv_style_set_max_height(lv_style_t * style, int32_t value); +void lv_style_set_length(lv_style_t * style, int32_t value); +void lv_style_set_x(lv_style_t * style, int32_t value); +void lv_style_set_y(lv_style_t * style, int32_t value); +void lv_style_set_align(lv_style_t * style, lv_align_t value); +void lv_style_set_transform_width(lv_style_t * style, int32_t value); +void lv_style_set_transform_height(lv_style_t * style, int32_t value); +void lv_style_set_translate_x(lv_style_t * style, int32_t value); +void lv_style_set_translate_y(lv_style_t * style, int32_t value); +void lv_style_set_transform_scale_x(lv_style_t * style, int32_t value); +void lv_style_set_transform_scale_y(lv_style_t * style, int32_t value); +void lv_style_set_transform_rotation(lv_style_t * style, int32_t value); +void lv_style_set_transform_pivot_x(lv_style_t * style, int32_t value); +void lv_style_set_transform_pivot_y(lv_style_t * style, int32_t value); +void lv_style_set_transform_skew_x(lv_style_t * style, int32_t value); +void lv_style_set_transform_skew_y(lv_style_t * style, int32_t value); +void lv_style_set_pad_top(lv_style_t * style, int32_t value); +void lv_style_set_pad_bottom(lv_style_t * style, int32_t value); +void lv_style_set_pad_left(lv_style_t * style, int32_t value); +void lv_style_set_pad_right(lv_style_t * style, int32_t value); +void lv_style_set_pad_row(lv_style_t * style, int32_t value); +void lv_style_set_pad_column(lv_style_t * style, int32_t value); +void lv_style_set_margin_top(lv_style_t * style, int32_t value); +void lv_style_set_margin_bottom(lv_style_t * style, int32_t value); +void lv_style_set_margin_left(lv_style_t * style, int32_t value); +void lv_style_set_margin_right(lv_style_t * style, int32_t value); +void lv_style_set_bg_color(lv_style_t * style, lv_color_t value); +void lv_style_set_bg_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_bg_grad_color(lv_style_t * style, lv_color_t value); +void lv_style_set_bg_grad_dir(lv_style_t * style, lv_grad_dir_t value); +void lv_style_set_bg_main_stop(lv_style_t * style, int32_t value); +void lv_style_set_bg_grad_stop(lv_style_t * style, int32_t value); +void lv_style_set_bg_main_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_bg_grad_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_bg_grad(lv_style_t * style, const lv_grad_dsc_t * value); +void lv_style_set_bg_image_src(lv_style_t * style, const void * value); +void lv_style_set_bg_image_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_bg_image_recolor(lv_style_t * style, lv_color_t value); +void lv_style_set_bg_image_recolor_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_bg_image_tiled(lv_style_t * style, bool value); +void lv_style_set_border_color(lv_style_t * style, lv_color_t value); +void lv_style_set_border_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_border_width(lv_style_t * style, int32_t value); +void lv_style_set_border_side(lv_style_t * style, lv_border_side_t value); +void lv_style_set_border_post(lv_style_t * style, bool value); +void lv_style_set_outline_width(lv_style_t * style, int32_t value); +void lv_style_set_outline_color(lv_style_t * style, lv_color_t value); +void lv_style_set_outline_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_outline_pad(lv_style_t * style, int32_t value); +void lv_style_set_shadow_width(lv_style_t * style, int32_t value); +void lv_style_set_shadow_offset_x(lv_style_t * style, int32_t value); +void lv_style_set_shadow_offset_y(lv_style_t * style, int32_t value); +void lv_style_set_shadow_spread(lv_style_t * style, int32_t value); +void lv_style_set_shadow_color(lv_style_t * style, lv_color_t value); +void lv_style_set_shadow_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_image_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_image_recolor(lv_style_t * style, lv_color_t value); +void lv_style_set_image_recolor_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_line_width(lv_style_t * style, int32_t value); +void lv_style_set_line_dash_width(lv_style_t * style, int32_t value); +void lv_style_set_line_dash_gap(lv_style_t * style, int32_t value); +void lv_style_set_line_rounded(lv_style_t * style, bool value); +void lv_style_set_line_color(lv_style_t * style, lv_color_t value); +void lv_style_set_line_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_arc_width(lv_style_t * style, int32_t value); +void lv_style_set_arc_rounded(lv_style_t * style, bool value); +void lv_style_set_arc_color(lv_style_t * style, lv_color_t value); +void lv_style_set_arc_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_arc_image_src(lv_style_t * style, const void * value); +void lv_style_set_text_color(lv_style_t * style, lv_color_t value); +void lv_style_set_text_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_text_font(lv_style_t * style, const lv_font_t * value); +void lv_style_set_text_letter_space(lv_style_t * style, int32_t value); +void lv_style_set_text_line_space(lv_style_t * style, int32_t value); +void lv_style_set_text_decor(lv_style_t * style, lv_text_decor_t value); +void lv_style_set_text_align(lv_style_t * style, lv_text_align_t value); +void lv_style_set_radius(lv_style_t * style, int32_t value); +void lv_style_set_clip_corner(lv_style_t * style, bool value); +void lv_style_set_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_opa_layered(lv_style_t * style, lv_opa_t value); +void lv_style_set_color_filter_dsc(lv_style_t * style, const lv_color_filter_dsc_t * value); +void lv_style_set_color_filter_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value); +void lv_style_set_anim_duration(lv_style_t * style, uint32_t value); +void lv_style_set_transition(lv_style_t * style, const lv_style_transition_dsc_t * value); +void lv_style_set_blend_mode(lv_style_t * style, lv_blend_mode_t value); +void lv_style_set_layout(lv_style_t * style, uint16_t value); +void lv_style_set_base_dir(lv_style_t * style, lv_base_dir_t value); +void lv_style_set_bitmap_mask_src(lv_style_t * style, const void * value); +void lv_style_set_rotary_sensitivity(lv_style_t * style, uint32_t value); +#if LV_USE_FLEX +void lv_style_set_flex_flow(lv_style_t * style, lv_flex_flow_t value); +void lv_style_set_flex_main_place(lv_style_t * style, lv_flex_align_t value); +void lv_style_set_flex_cross_place(lv_style_t * style, lv_flex_align_t value); +void lv_style_set_flex_track_place(lv_style_t * style, lv_flex_align_t value); +void lv_style_set_flex_grow(lv_style_t * style, uint8_t value); +#endif /*LV_USE_FLEX*/ + +#if LV_USE_GRID +void lv_style_set_grid_column_dsc_array(lv_style_t * style, const int32_t * value); +void lv_style_set_grid_column_align(lv_style_t * style, lv_grid_align_t value); +void lv_style_set_grid_row_dsc_array(lv_style_t * style, const int32_t * value); +void lv_style_set_grid_row_align(lv_style_t * style, lv_grid_align_t value); +void lv_style_set_grid_cell_column_pos(lv_style_t * style, int32_t value); +void lv_style_set_grid_cell_x_align(lv_style_t * style, lv_grid_align_t value); +void lv_style_set_grid_cell_column_span(lv_style_t * style, int32_t value); +void lv_style_set_grid_cell_row_pos(lv_style_t * style, int32_t value); +void lv_style_set_grid_cell_y_align(lv_style_t * style, lv_grid_align_t value); +void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value); +#endif /*LV_USE_GRID*/ + + +#define LV_STYLE_CONST_WIDTH(val) \ + { \ + .prop = LV_STYLE_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_MIN_WIDTH(val) \ + { \ + .prop = LV_STYLE_MIN_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_MAX_WIDTH(val) \ + { \ + .prop = LV_STYLE_MAX_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_HEIGHT(val) \ + { \ + .prop = LV_STYLE_HEIGHT, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_MIN_HEIGHT(val) \ + { \ + .prop = LV_STYLE_MIN_HEIGHT, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_MAX_HEIGHT(val) \ + { \ + .prop = LV_STYLE_MAX_HEIGHT, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_LENGTH(val) \ + { \ + .prop = LV_STYLE_LENGTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_X(val) \ + { \ + .prop = LV_STYLE_X, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_Y(val) \ + { \ + .prop = LV_STYLE_Y, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_ALIGN(val) \ + { \ + .prop = LV_STYLE_ALIGN, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSFORM_WIDTH(val) \ + { \ + .prop = LV_STYLE_TRANSFORM_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSFORM_HEIGHT(val) \ + { \ + .prop = LV_STYLE_TRANSFORM_HEIGHT, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSLATE_X(val) \ + { \ + .prop = LV_STYLE_TRANSLATE_X, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSLATE_Y(val) \ + { \ + .prop = LV_STYLE_TRANSLATE_Y, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSFORM_SCALE_X(val) \ + { \ + .prop = LV_STYLE_TRANSFORM_SCALE_X, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSFORM_SCALE_Y(val) \ + { \ + .prop = LV_STYLE_TRANSFORM_SCALE_Y, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSFORM_ROTATION(val) \ + { \ + .prop = LV_STYLE_TRANSFORM_ROTATION, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSFORM_PIVOT_X(val) \ + { \ + .prop = LV_STYLE_TRANSFORM_PIVOT_X, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSFORM_PIVOT_Y(val) \ + { \ + .prop = LV_STYLE_TRANSFORM_PIVOT_Y, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSFORM_SKEW_X(val) \ + { \ + .prop = LV_STYLE_TRANSFORM_SKEW_X, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSFORM_SKEW_Y(val) \ + { \ + .prop = LV_STYLE_TRANSFORM_SKEW_Y, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_PAD_TOP(val) \ + { \ + .prop = LV_STYLE_PAD_TOP, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_PAD_BOTTOM(val) \ + { \ + .prop = LV_STYLE_PAD_BOTTOM, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_PAD_LEFT(val) \ + { \ + .prop = LV_STYLE_PAD_LEFT, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_PAD_RIGHT(val) \ + { \ + .prop = LV_STYLE_PAD_RIGHT, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_PAD_ROW(val) \ + { \ + .prop = LV_STYLE_PAD_ROW, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_PAD_COLUMN(val) \ + { \ + .prop = LV_STYLE_PAD_COLUMN, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_MARGIN_TOP(val) \ + { \ + .prop = LV_STYLE_MARGIN_TOP, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_MARGIN_BOTTOM(val) \ + { \ + .prop = LV_STYLE_MARGIN_BOTTOM, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_MARGIN_LEFT(val) \ + { \ + .prop = LV_STYLE_MARGIN_LEFT, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_MARGIN_RIGHT(val) \ + { \ + .prop = LV_STYLE_MARGIN_RIGHT, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BG_COLOR(val) \ + { \ + .prop = LV_STYLE_BG_COLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_BG_OPA(val) \ + { \ + .prop = LV_STYLE_BG_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BG_GRAD_COLOR(val) \ + { \ + .prop = LV_STYLE_BG_GRAD_COLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_BG_GRAD_DIR(val) \ + { \ + .prop = LV_STYLE_BG_GRAD_DIR, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BG_MAIN_STOP(val) \ + { \ + .prop = LV_STYLE_BG_MAIN_STOP, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BG_GRAD_STOP(val) \ + { \ + .prop = LV_STYLE_BG_GRAD_STOP, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BG_MAIN_OPA(val) \ + { \ + .prop = LV_STYLE_BG_MAIN_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BG_GRAD_OPA(val) \ + { \ + .prop = LV_STYLE_BG_GRAD_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BG_GRAD(val) \ + { \ + .prop = LV_STYLE_BG_GRAD, .value = { .ptr = val } \ + } + +#define LV_STYLE_CONST_BG_IMAGE_SRC(val) \ + { \ + .prop = LV_STYLE_BG_IMAGE_SRC, .value = { .ptr = val } \ + } + +#define LV_STYLE_CONST_BG_IMAGE_OPA(val) \ + { \ + .prop = LV_STYLE_BG_IMAGE_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BG_IMAGE_RECOLOR(val) \ + { \ + .prop = LV_STYLE_BG_IMAGE_RECOLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_BG_IMAGE_RECOLOR_OPA(val) \ + { \ + .prop = LV_STYLE_BG_IMAGE_RECOLOR_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BG_IMAGE_TILED(val) \ + { \ + .prop = LV_STYLE_BG_IMAGE_TILED, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BORDER_COLOR(val) \ + { \ + .prop = LV_STYLE_BORDER_COLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_BORDER_OPA(val) \ + { \ + .prop = LV_STYLE_BORDER_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BORDER_WIDTH(val) \ + { \ + .prop = LV_STYLE_BORDER_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BORDER_SIDE(val) \ + { \ + .prop = LV_STYLE_BORDER_SIDE, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BORDER_POST(val) \ + { \ + .prop = LV_STYLE_BORDER_POST, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_OUTLINE_WIDTH(val) \ + { \ + .prop = LV_STYLE_OUTLINE_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_OUTLINE_COLOR(val) \ + { \ + .prop = LV_STYLE_OUTLINE_COLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_OUTLINE_OPA(val) \ + { \ + .prop = LV_STYLE_OUTLINE_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_OUTLINE_PAD(val) \ + { \ + .prop = LV_STYLE_OUTLINE_PAD, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_SHADOW_WIDTH(val) \ + { \ + .prop = LV_STYLE_SHADOW_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_SHADOW_OFFSET_X(val) \ + { \ + .prop = LV_STYLE_SHADOW_OFFSET_X, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_SHADOW_OFFSET_Y(val) \ + { \ + .prop = LV_STYLE_SHADOW_OFFSET_Y, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_SHADOW_SPREAD(val) \ + { \ + .prop = LV_STYLE_SHADOW_SPREAD, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_SHADOW_COLOR(val) \ + { \ + .prop = LV_STYLE_SHADOW_COLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_SHADOW_OPA(val) \ + { \ + .prop = LV_STYLE_SHADOW_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_IMAGE_OPA(val) \ + { \ + .prop = LV_STYLE_IMAGE_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_IMAGE_RECOLOR(val) \ + { \ + .prop = LV_STYLE_IMAGE_RECOLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_IMAGE_RECOLOR_OPA(val) \ + { \ + .prop = LV_STYLE_IMAGE_RECOLOR_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_LINE_WIDTH(val) \ + { \ + .prop = LV_STYLE_LINE_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_LINE_DASH_WIDTH(val) \ + { \ + .prop = LV_STYLE_LINE_DASH_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_LINE_DASH_GAP(val) \ + { \ + .prop = LV_STYLE_LINE_DASH_GAP, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_LINE_ROUNDED(val) \ + { \ + .prop = LV_STYLE_LINE_ROUNDED, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_LINE_COLOR(val) \ + { \ + .prop = LV_STYLE_LINE_COLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_LINE_OPA(val) \ + { \ + .prop = LV_STYLE_LINE_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_ARC_WIDTH(val) \ + { \ + .prop = LV_STYLE_ARC_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_ARC_ROUNDED(val) \ + { \ + .prop = LV_STYLE_ARC_ROUNDED, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_ARC_COLOR(val) \ + { \ + .prop = LV_STYLE_ARC_COLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_ARC_OPA(val) \ + { \ + .prop = LV_STYLE_ARC_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_ARC_IMAGE_SRC(val) \ + { \ + .prop = LV_STYLE_ARC_IMAGE_SRC, .value = { .ptr = val } \ + } + +#define LV_STYLE_CONST_TEXT_COLOR(val) \ + { \ + .prop = LV_STYLE_TEXT_COLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_TEXT_OPA(val) \ + { \ + .prop = LV_STYLE_TEXT_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TEXT_FONT(val) \ + { \ + .prop = LV_STYLE_TEXT_FONT, .value = { .ptr = val } \ + } + +#define LV_STYLE_CONST_TEXT_LETTER_SPACE(val) \ + { \ + .prop = LV_STYLE_TEXT_LETTER_SPACE, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TEXT_LINE_SPACE(val) \ + { \ + .prop = LV_STYLE_TEXT_LINE_SPACE, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TEXT_DECOR(val) \ + { \ + .prop = LV_STYLE_TEXT_DECOR, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TEXT_ALIGN(val) \ + { \ + .prop = LV_STYLE_TEXT_ALIGN, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_RADIUS(val) \ + { \ + .prop = LV_STYLE_RADIUS, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_CLIP_CORNER(val) \ + { \ + .prop = LV_STYLE_CLIP_CORNER, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_OPA(val) \ + { \ + .prop = LV_STYLE_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_OPA_LAYERED(val) \ + { \ + .prop = LV_STYLE_OPA_LAYERED, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_COLOR_FILTER_DSC(val) \ + { \ + .prop = LV_STYLE_COLOR_FILTER_DSC, .value = { .ptr = val } \ + } + +#define LV_STYLE_CONST_COLOR_FILTER_OPA(val) \ + { \ + .prop = LV_STYLE_COLOR_FILTER_OPA, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_ANIM(val) \ + { \ + .prop = LV_STYLE_ANIM, .value = { .ptr = val } \ + } + +#define LV_STYLE_CONST_ANIM_DURATION(val) \ + { \ + .prop = LV_STYLE_ANIM_DURATION, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TRANSITION(val) \ + { \ + .prop = LV_STYLE_TRANSITION, .value = { .ptr = val } \ + } + +#define LV_STYLE_CONST_BLEND_MODE(val) \ + { \ + .prop = LV_STYLE_BLEND_MODE, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_LAYOUT(val) \ + { \ + .prop = LV_STYLE_LAYOUT, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BASE_DIR(val) \ + { \ + .prop = LV_STYLE_BASE_DIR, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_BITMAP_MASK_SRC(val) \ + { \ + .prop = LV_STYLE_BITMAP_MASK_SRC, .value = { .ptr = val } \ + } + +#define LV_STYLE_CONST_ROTARY_SENSITIVITY(val) \ + { \ + .prop = LV_STYLE_ROTARY_SENSITIVITY, .value = { .num = (int32_t)val } \ + } +#if LV_USE_FLEX + +#define LV_STYLE_CONST_FLEX_FLOW(val) \ + { \ + .prop = LV_STYLE_FLEX_FLOW, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_FLEX_MAIN_PLACE(val) \ + { \ + .prop = LV_STYLE_FLEX_MAIN_PLACE, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_FLEX_CROSS_PLACE(val) \ + { \ + .prop = LV_STYLE_FLEX_CROSS_PLACE, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_FLEX_TRACK_PLACE(val) \ + { \ + .prop = LV_STYLE_FLEX_TRACK_PLACE, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_FLEX_GROW(val) \ + { \ + .prop = LV_STYLE_FLEX_GROW, .value = { .num = (int32_t)val } \ + } +#endif /*LV_USE_FLEX*/ + +#if LV_USE_GRID + +#define LV_STYLE_CONST_GRID_COLUMN_DSC_ARRAY(val) \ + { \ + .prop = LV_STYLE_GRID_COLUMN_DSC_ARRAY, .value = { .ptr = val } \ + } + +#define LV_STYLE_CONST_GRID_COLUMN_ALIGN(val) \ + { \ + .prop = LV_STYLE_GRID_COLUMN_ALIGN, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_GRID_ROW_DSC_ARRAY(val) \ + { \ + .prop = LV_STYLE_GRID_ROW_DSC_ARRAY, .value = { .ptr = val } \ + } + +#define LV_STYLE_CONST_GRID_ROW_ALIGN(val) \ + { \ + .prop = LV_STYLE_GRID_ROW_ALIGN, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_GRID_CELL_COLUMN_POS(val) \ + { \ + .prop = LV_STYLE_GRID_CELL_COLUMN_POS, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_GRID_CELL_X_ALIGN(val) \ + { \ + .prop = LV_STYLE_GRID_CELL_X_ALIGN, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_GRID_CELL_COLUMN_SPAN(val) \ + { \ + .prop = LV_STYLE_GRID_CELL_COLUMN_SPAN, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_GRID_CELL_ROW_POS(val) \ + { \ + .prop = LV_STYLE_GRID_CELL_ROW_POS, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_GRID_CELL_Y_ALIGN(val) \ + { \ + .prop = LV_STYLE_GRID_CELL_Y_ALIGN, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_GRID_CELL_ROW_SPAN(val) \ + { \ + .prop = LV_STYLE_GRID_CELL_ROW_SPAN, .value = { .num = (int32_t)val } \ + } +#endif /*LV_USE_GRID*/ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_STYLE_GEN_H */ diff --git a/test/include/liblvgl/misc/lv_style_private.h b/test/include/liblvgl/misc/lv_style_private.h new file mode 100644 index 00000000..8a88185d --- /dev/null +++ b/test/include/liblvgl/misc/lv_style_private.h @@ -0,0 +1,39 @@ +/** + * @file lv_style_private.h + * + */ + +#ifndef LV_STYLE_PRIVATE_H +#define LV_STYLE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_style.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_STYLE_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_templ.h b/test/include/liblvgl/misc/lv_templ.h new file mode 100644 index 00000000..f7e3c268 --- /dev/null +++ b/test/include/liblvgl/misc/lv_templ.h @@ -0,0 +1,37 @@ +/** + * @file lv_templ.h + * + */ + +#ifndef LV_TEMPL_H +#define LV_TEMPL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEMPL_H*/ diff --git a/test/include/liblvgl/misc/lv_text.h b/test/include/liblvgl/misc/lv_text.h new file mode 100644 index 00000000..1381c36b --- /dev/null +++ b/test/include/liblvgl/misc/lv_text.h @@ -0,0 +1,125 @@ +/** + * @file lv_text.h + * + */ + +#ifndef LV_TEXT_H +#define LV_TEXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include "lv_types.h" +#include "lv_area.h" +#include "../font/lv_font.h" +#include "../stdlib/lv_sprintf.h" + +/********************* + * DEFINES + *********************/ +#ifndef LV_TXT_COLOR_CMD +#define LV_TXT_COLOR_CMD "#" +#endif + +#define LV_TXT_ENC_UTF8 1 +#define LV_TXT_ENC_ASCII 2 + +/********************** + * TYPEDEFS + **********************/ + +/** + * Options for text rendering. + */ + +typedef enum { + LV_TEXT_FLAG_NONE = 0x00, + LV_TEXT_FLAG_EXPAND = 0x01, /**< Ignore max-width to avoid automatic word wrapping*/ + LV_TEXT_FLAG_FIT = 0x02, /**< Max-width is already equal to the longest line. (Used to skip some calculation)*/ + LV_TEXT_FLAG_BREAK_ALL = 0x04, /**< To prevent overflow, insert breaks between any two characters. + Otherwise breaks are inserted at word boundaries, as configured via LV_TXT_BREAK_CHARS + or according to LV_TXT_LINE_BREAK_LONG_LEN, LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN, + and LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN.*/ + LV_TEXT_FLAG_RECOLOR = 0x08, /**< Enable parsing of recolor command*/ +} lv_text_flag_t; + +/** Label align policy*/ +typedef enum { + LV_TEXT_ALIGN_AUTO, /**< Align text auto*/ + LV_TEXT_ALIGN_LEFT, /**< Align text to left*/ + LV_TEXT_ALIGN_CENTER, /**< Align text to center*/ + LV_TEXT_ALIGN_RIGHT, /**< Align text to right*/ +} lv_text_align_t; + +/** State machine for text renderer. */ +typedef enum { + LV_TEXT_CMD_STATE_WAIT, /**< Waiting for command*/ + LV_TEXT_CMD_STATE_PAR, /**< Processing the parameter*/ + LV_TEXT_CMD_STATE_IN, /**< Processing the command*/ +} lv_text_cmd_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get size of a text + * @param size_res pointer to a 'point_t' variable to store the result + * @param text pointer to a text + * @param font pointer to font of the text + * @param letter_space letter space of the text + * @param line_space line space of the text + * @param max_width max width of the text (break the lines to fit this size). Set COORD_MAX to avoid + * @param flag settings for the text from ::lv_text_flag_t + + * line breaks + */ +void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, int32_t letter_space, + int32_t line_space, int32_t max_width, lv_text_flag_t flag); + +/** + * Give the length of a text with a given font + * @param txt a '\0' terminate string + * @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in + * UTF-8) + * @param font pointer to a font + * @param letter_space letter space + * @return length of a char_num long text + */ +int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space); + +/** + * Give the length of a text with a given font with text flags + * @param txt a '\0' terminate string + * @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in + * UTF-8) + * @param font pointer to a font + * @param letter_space letter space + * @param flags settings for the text from ::lv_text_flag_t + * @return length of a char_num long text + */ +int32_t lv_text_get_width_with_flags(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space, + lv_text_flag_t flags); + +/** + * Check if c is command state + * @param state + * @param c + * @return True if c is state + */ +bool lv_text_is_cmd(lv_text_cmd_state_t * state, uint32_t c); +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEXT_H*/ diff --git a/test/include/liblvgl/misc/lv_text_ap.h b/test/include/liblvgl/misc/lv_text_ap.h new file mode 100644 index 00000000..cac7c712 --- /dev/null +++ b/test/include/liblvgl/misc/lv_text_ap.h @@ -0,0 +1,49 @@ +/** + * @file lv_text_ap.h + * + */ + +#ifndef LV_TEXT_AP_H +#define LV_TEXT_AP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_text.h" +#include "lv_types.h" +#include "../draw/lv_draw.h" + +#if LV_USE_ARABIC_PERSIAN_CHARS == 1 + +/********************* + * DEFINES + *********************/ + +#define LV_UNDEF_ARABIC_PERSIAN_CHARS (UINT32_MAX) +#define LV_AP_ALPHABET_BASE_CODE 0x0622 +#define LV_AP_END_CHARS_LIST {0,0,0,0,0,{0,0}} +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +uint32_t lv_text_ap_calc_bytes_count(const char * txt); +void lv_text_ap_proc(const char * txt, char * txt_out); + +/********************** + * MACROS + **********************/ + +#endif // LV_USE_ARABIC_PERSIAN_CHARS + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEXT_AP_H*/ diff --git a/test/include/liblvgl/misc/lv_text_private.h b/test/include/liblvgl/misc/lv_text_private.h new file mode 100644 index 00000000..858f5938 --- /dev/null +++ b/test/include/liblvgl/misc/lv_text_private.h @@ -0,0 +1,273 @@ +/** + * @file lv_text_private.h + * + */ + +#ifndef LV_TEXT_PRIVATE_H +#define LV_TEXT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_text.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the next line of text. Check line length and break chars too. + * @param txt a '\0' terminated string + * @param font pointer to a font + * @param letter_space letter space + * @param max_width max width of the text (break the lines to fit this size). Set COORD_MAX to avoid + * line breaks + * @param used_width When used_width != NULL, save the width of this line if + * flag == LV_TEXT_FLAG_NONE, otherwise save -1. + * @param flag settings for the text from 'txt_flag_type' enum + * @return the index of the first char of the new line (in byte index not letter index. With UTF-8 + * they are different) + */ +uint32_t lv_text_get_next_line(const char * txt, const lv_font_t * font, int32_t letter_space, + int32_t max_width, int32_t * used_width, lv_text_flag_t flag); + +/** + * Insert a string into another + * @param txt_buf the original text (must be big enough for the result text and NULL terminated) + * @param pos position to insert (0: before the original text, 1: after the first char etc.) + * @param ins_txt text to insert, must be '\0' terminated + */ +void lv_text_ins(char * txt_buf, uint32_t pos, const char * ins_txt); + +/** + * Delete a part of a string + * @param txt string to modify, must be '\0' terminated and should point to a heap or stack frame, not read-only memory. + * @param pos position where to start the deleting (0: before the first char, 1: after the first + * char etc.) + * @param len number of characters to delete + */ +void lv_text_cut(char * txt, uint32_t pos, uint32_t len); + +/** + * return a new formatted text. Memory will be allocated to store the text. + * @param fmt `printf`-like format + * @param ap items to print + + * @return pointer to the allocated text string. + */ +char * lv_text_set_text_vfmt(const char * fmt, va_list ap) LV_FORMAT_ATTRIBUTE(1, 0); + +/** + * Decode two encoded character from a string. + * @param txt pointer to '\0' terminated string + * @param letter the first decoded Unicode character or 0 on invalid data code + * @param letter_next the second decoded Unicode character or 0 on invalid data code + * @param ofs start index in 'txt' where to start. + * After the call it will point to the next encoded char in 'txt'. + * NULL to use txt[0] as index + */ +void lv_text_encoded_letter_next_2(const char * txt, uint32_t * letter, uint32_t * letter_next, uint32_t * ofs); + +/** + * Test if char is break char or not (a text can broken here or not) + * @param letter a letter + * @return false: 'letter' is not break char + */ +static inline bool lv_text_is_break_char(uint32_t letter) +{ + uint8_t i; + bool ret = false; + + /*Compare the letter to TXT_BREAK_CHARS*/ + for(i = 0; LV_TXT_BREAK_CHARS[i] != '\0'; i++) { + if(letter == (uint32_t)LV_TXT_BREAK_CHARS[i]) { + ret = true; /*If match then it is break char*/ + break; + } + } + + return ret; +} + +/** + * Test if char is break char or not (a text can broken here or not) + * @param letter a letter + * @return false: 'letter' is not break char + */ +static inline bool lv_text_is_a_word(uint32_t letter) +{ + /*Cheap check on invalid letter*/ + if(letter == 0) return false; + + /*CJK Unified Ideographs*/ + if(letter >= 0x4E00 && letter <= 0x9FFF) { + return true; + } + + /*Fullwidth ASCII variants*/ + if(letter >= 0xFF01 && letter <= 0xFF5E) { + return true; + } + + /*CJK symbols and punctuation*/ + if(letter >= 0x3000 && letter <= 0x303F) { + return true; + } + + /*CJK Radicals Supplement*/ + if(letter >= 0x2E80 && letter <= 0x2EFF) { + return true; + } + + /*CJK Strokes*/ + if(letter >= 0x31C0 && letter <= 0x31EF) { + return true; + } + + /*Hiragana and Katakana*/ + if(letter >= 0x3040 && letter <= 0x30FF) { + return true; + } + + /*Chinese Vertical Forms*/ + if(letter >= 0xFE10 && letter <= 0xFE1F) { + return true; + } + + /*CJK Compatibility Forms*/ + if(letter >= 0xFE30 && letter <= 0xFE4F) { + return true; + } + + return false; +} + +/** + * Test if character can be treated as marker, and don't need to be rendered. + * Note, this is not a full list. Add your findings to the list. + * + * @param letter a letter + * @return true if so + */ +static inline bool lv_text_is_marker(uint32_t letter) +{ + if(letter < 0x20) return true; + + /*U+061C ARABIC LETTER MARK, see https://www.compart.com/en/unicode/block/U+0600*/ + if(letter == 0x061C) return true; + + /*U+115F HANGUL CHOSEONG FILLER, See https://www.compart.com/en/unicode/block/U+1100*/ + if(letter == 0x115F) return true; + /*U+1160 HANGUL JUNGSEONG FILLER*/ + if(letter == 0x1160) return true; + + /*See https://www.compart.com/en/unicode/block/U+1800*/ + if(letter >= 0x180B && letter <= 0x180E) return true; + + /*See https://www.compart.com/en/unicode/block/U+2000*/ + if(letter >= 0x200B && letter <= 0x200F) return true; + if(letter >= 0x2028 && letter <= 0x202F) return true; + if(letter >= 0x205F && letter <= 0x206F) return true; + + /*U+FEFF ZERO WIDTH NO-BREAK SPACE, see https://www.compart.com/en/unicode/block/U+FE70*/ + if(letter == 0xFEFF) return true; + + if(letter == 0xF8FF) return true; /*LV_SYMBOL_DUMMY*/ + + return false; +} + +/*************************************************************** + * GLOBAL FUNCTION POINTERS FOR CHARACTER ENCODING INTERFACE + ***************************************************************/ + +/** + * Give the size of an encoded character + * @param txt pointer to a character in a string + * @return length of the encoded character (1,2,3 ...). O in invalid + */ +extern uint8_t (*const lv_text_encoded_size)(const char * txt); + +/** + * Convert a Unicode letter to encoded + * @param letter_uni a Unicode letter + * @return Encoded character in Little Endian to be compatible with C chars (e.g. 'Á', 'Ü') + */ +extern uint32_t (*const lv_text_unicode_to_encoded)(uint32_t letter_uni); + +/** + * Convert a wide character, e.g. 'Á' little endian to be compatible with the encoded format. + * @param c a wide character + * @return `c` in the encoded format + */ +extern uint32_t (*const lv_text_encoded_conv_wc)(uint32_t c); + +/** + * Decode the next encoded character from a string. + * @param txt pointer to '\0' terminated string + * @param i_start start index in 'txt' where to start. + * After the call it will point to the next encoded char in 'txt'. + * NULL to use txt[0] as index + * @return the decoded Unicode character or 0 on invalid data code + */ +extern uint32_t (*const lv_text_encoded_next)(const char * txt, uint32_t * i_start); + +/** + * Get the previous encoded character form a string. + * + * @param txt pointer to '\0' terminated string + * @param i_start index in 'txt' where to start. After the call it will point to the previous + * encoded char in 'txt'. + * + * @return the decoded Unicode character or 0 on invalid data + */ +extern uint32_t (*const lv_text_encoded_prev)(const char * txt, uint32_t * i_start); + +/** + * Convert a letter index (in the encoded text) to byte index. + * E.g. in UTF-8 "AÁRT" index of 'R' is 2 but start at byte 3 because 'Á' is 2 bytes long + * @param txt a '\0' terminated UTF-8 string + * @param utf8_id character index + * @return byte index of the 'enc_id'th letter + */ +extern uint32_t (*const lv_text_encoded_get_byte_id)(const char * txt, uint32_t utf8_id); + +/** + * Convert a byte index (in an encoded text) to character index. + * E.g. in UTF-8 "AÁRT" index of 'R' is 2 but start at byte 3 because 'Á' is 2 bytes long + * @param txt a '\0' terminated UTF-8 string + * @param byte_id byte index + * @return character index of the letter at 'byte_id'th position + */ +extern uint32_t (*const lv_text_encoded_get_char_id)(const char * txt, uint32_t byte_id); + +/** + * Get the number of characters (and NOT bytes) in a string. + * E.g. in UTF-8 "ÁBC" is 3 characters (but 4 bytes) + * @param txt a '\0' terminated char string + * @return number of characters + */ +extern uint32_t (*const lv_text_get_encoded_length)(const char * txt); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEXT_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_timer.h b/test/include/liblvgl/misc/lv_timer.h new file mode 100644 index 00000000..be250033 --- /dev/null +++ b/test/include/liblvgl/misc/lv_timer.h @@ -0,0 +1,210 @@ +/** + * @file lv_timer.h + */ + +#ifndef LV_TIMER_H +#define LV_TIMER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "../tick/lv_tick.h" +#include "lv_types.h" +#include "lv_ll.h" + +/********************* + * DEFINES + *********************/ +#ifndef LV_ATTRIBUTE_TIMER_HANDLER +#define LV_ATTRIBUTE_TIMER_HANDLER +#endif + +#define LV_NO_TIMER_READY 0xFFFFFFFF + +/********************** + * TYPEDEFS + **********************/ + +/** + * Timers execute this type of functions. + */ +typedef void (*lv_timer_cb_t)(lv_timer_t *); + +/** + * Timer handler resume this type of function. + */ +typedef void (*lv_timer_handler_resume_cb_t)(void * data); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +//! @cond Doxygen_Suppress + +/** + * Call it periodically to handle lv_timers. + * @return time till it needs to be run next (in ms) + */ +LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void); + +//! @endcond + +/** + * Call it in the super-loop of main() or threads. It will run lv_timer_handler() + * with a given period in ms. You can use it with sleep or delay in OS environment. + * This function is used to simplify the porting. + * @param period the period for running lv_timer_handler() + * @return the time after which it must be called again + */ +LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler_run_in_period(uint32_t period); + +/** + * Call it in the super-loop of main() or threads. It will automatically call lv_timer_handler() at the right time. + * This function is used to simplify the porting. + */ +LV_ATTRIBUTE_TIMER_HANDLER void lv_timer_periodic_handler(void); + +/** + * Set the resume callback to the timer handler + * @param cb the function to call when timer handler is resumed + * @param data pointer to a resume data + */ +void lv_timer_handler_set_resume_cb(lv_timer_handler_resume_cb_t cb, void * data); + +/** + * Create an "empty" timer. It needs to be initialized with at least + * `lv_timer_set_cb` and `lv_timer_set_period` + * @return pointer to the created timer + */ +lv_timer_t * lv_timer_create_basic(void); + +/** + * Create a new lv_timer + * @param timer_xcb a callback to call periodically. + * (the 'x' in the argument name indicates that it's not a fully generic function because it not follows + * the `func_name(object, callback, ...)` convention) + * @param period call period in ms unit + * @param user_data custom parameter + * @return pointer to the new timer + */ +lv_timer_t * lv_timer_create(lv_timer_cb_t timer_xcb, uint32_t period, void * user_data); + +/** + * Delete a lv_timer + * @param timer pointer to an lv_timer + */ +void lv_timer_delete(lv_timer_t * timer); + +/** + * Pause a timer. + * @param timer pointer to an lv_timer + */ +void lv_timer_pause(lv_timer_t * timer); + +/** + * Resume a timer. + * @param timer pointer to an lv_timer + */ +void lv_timer_resume(lv_timer_t * timer); + +/** + * Set the callback to the timer (the function to call periodically) + * @param timer pointer to a timer + * @param timer_cb the function to call periodically + */ +void lv_timer_set_cb(lv_timer_t * timer, lv_timer_cb_t timer_cb); + +/** + * Set new period for a lv_timer + * @param timer pointer to a lv_timer + * @param period the new period + */ +void lv_timer_set_period(lv_timer_t * timer, uint32_t period); + +/** + * Make a lv_timer ready. It will not wait its period. + * @param timer pointer to a lv_timer. + */ +void lv_timer_ready(lv_timer_t * timer); + +/** + * Set the number of times a timer will repeat. + * @param timer pointer to a lv_timer. + * @param repeat_count -1 : infinity; 0 : stop ; n>0: residual times + */ +void lv_timer_set_repeat_count(lv_timer_t * timer, int32_t repeat_count); + +/** + * Set whether a lv_timer will be deleted automatically when it is called `repeat_count` times. + * @param timer pointer to a lv_timer. + * @param auto_delete true: auto delete; false: timer will be paused when it is called `repeat_count` times. + */ +void lv_timer_set_auto_delete(lv_timer_t * timer, bool auto_delete); + +/** + * Set custom parameter to the lv_timer. + * @param timer pointer to a lv_timer. + * @param user_data custom parameter + */ +void lv_timer_set_user_data(lv_timer_t * timer, void * user_data); + +/** + * Reset a lv_timer. + * It will be called the previously set period milliseconds later. + * @param timer pointer to a lv_timer. + */ +void lv_timer_reset(lv_timer_t * timer); + +/** + * Enable or disable the whole lv_timer handling + * @param en true: lv_timer handling is running, false: lv_timer handling is suspended + */ +void lv_timer_enable(bool en); + +/** + * Get idle percentage + * @return the lv_timer idle in percentage + */ +uint32_t lv_timer_get_idle(void); + +/** + * Get the time remaining until the next timer will run + * @return the time remaining in ms + */ +uint32_t lv_timer_get_time_until_next(void); + +/** + * Iterate through the timers + * @param timer NULL to start iteration or the previous return value to get the next timer + * @return the next timer or NULL if there is no more timer + */ +lv_timer_t * lv_timer_get_next(lv_timer_t * timer); + +/** + * Get the user_data passed when the timer was created + * @param timer pointer to the lv_timer + * @return pointer to the user_data + */ +void * lv_timer_get_user_data(lv_timer_t * timer); + +/** + * Get the pause state of a timer + * @param timer pointer to a lv_timer + * @return true: timer is paused; false: timer is running + */ +bool lv_timer_get_paused(lv_timer_t * timer); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/test/include/liblvgl/misc/lv_timer_private.h b/test/include/liblvgl/misc/lv_timer_private.h new file mode 100644 index 00000000..9f7269f5 --- /dev/null +++ b/test/include/liblvgl/misc/lv_timer_private.h @@ -0,0 +1,81 @@ +/** + * @file lv_timer_private.h + * + */ + +#ifndef LV_TIMER_PRIVATE_H +#define LV_TIMER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_timer.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Descriptor of a lv_timer + */ +struct _lv_timer_t { + uint32_t period; /**< How often the timer should run */ + uint32_t last_run; /**< Last time the timer ran */ + lv_timer_cb_t timer_cb; /**< Timer function */ + void * user_data; /**< Custom user data */ + int32_t repeat_count; /**< 1: One time; -1 : infinity; n>0: residual times */ + uint32_t paused : 1; + uint32_t auto_delete : 1; +}; + +typedef struct { + lv_ll_t timer_ll; /**< Linked list to store the lv_timers */ + + bool lv_timer_run; + uint8_t idle_last; + bool timer_deleted; + bool timer_created; + uint32_t timer_time_until_next; + + bool already_running; + uint32_t periodic_last_tick; + uint32_t busy_time; + uint32_t idle_period_start; + uint32_t run_cnt; + + lv_timer_handler_resume_cb_t resume_cb; + void * resume_data; +} lv_timer_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Init the lv_timer module + */ +void lv_timer_core_init(void); + +/** + * Deinit the lv_timer module + */ +void lv_timer_core_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TIMER_PRIVATE_H*/ diff --git a/test/include/liblvgl/misc/lv_tree.h b/test/include/liblvgl/misc/lv_tree.h new file mode 100644 index 00000000..e058a03c --- /dev/null +++ b/test/include/liblvgl/misc/lv_tree.h @@ -0,0 +1,105 @@ +/** + * @file lv_tree.h + * Tree. The tree nodes are dynamically allocated by the 'lv_mem' module. + */ + +#ifndef LV_TREE_H +#define LV_TREE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +#define LV_TREE_NODE(n) ((lv_tree_node_t*)(n)) + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_tree_node_t; + +/** + * Describe the common methods of every object. + * Similar to a C++ class. + */ +typedef struct _lv_tree_class_t { + const struct _lv_tree_class_t * base_class; + uint32_t instance_size; + void (*constructor_cb)(const struct _lv_tree_class_t * class_p, struct _lv_tree_node_t * node); + void (*destructor_cb)(const struct _lv_tree_class_t * class_p, struct _lv_tree_node_t * node); +} lv_tree_class_t; + +/** Description of a tree node*/ +typedef struct _lv_tree_node_t { + struct _lv_tree_node_t * parent; + struct _lv_tree_node_t ** children; + uint32_t child_cnt; + uint32_t child_cap; + const struct _lv_tree_class_t * class_p; +} lv_tree_node_t; + +enum { + LV_TREE_WALK_PRE_ORDER = 0, + LV_TREE_WALK_POST_ORDER, +}; +typedef uint8_t lv_tree_walk_mode_t; + +typedef bool (*lv_tree_traverse_cb_t)(const lv_tree_node_t * node, void * user_data); +typedef bool (*lv_tree_before_cb_t)(const lv_tree_node_t * node, void * user_data); +typedef void (*lv_tree_after_cb_t)(const lv_tree_node_t * node, void * user_data); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +extern const lv_tree_class_t lv_tree_node_class; + +/** + * @brief Create a tree node + * @param class_p pointer to a class of the node + * @param parent pointer to the parent node (or NULL if it's the root node) + * @return pointer to the new node + */ +lv_tree_node_t * lv_tree_node_create(const lv_tree_class_t * class_p, lv_tree_node_t * parent); + +/** + * @brief Delete a tree node and all its children recursively + * @param node pointer to the node to delete + */ +void lv_tree_node_delete(lv_tree_node_t * node); + +/** + * @brief Walk the tree recursively and call a callback function on each node + * @param node pointer to the root node of the tree + * @param mode LV_TREE_WALK_PRE_ORDER or LV_TREE_WALK_POST_ORDER + * @param cb callback function to call on each node + * @param bcb callback function to call before visiting a node + * @param acb callback function to call after visiting a node + * @param user_data user data to pass to the callback functions + * @return true: traversal is finished; false: traversal breaked + */ +bool lv_tree_walk(const lv_tree_node_t * node, + lv_tree_walk_mode_t mode, + lv_tree_traverse_cb_t cb, + lv_tree_before_cb_t bcb, + lv_tree_after_cb_t acb, + void * user_data); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/test/include/liblvgl/misc/lv_types.h b/test/include/liblvgl/misc/lv_types.h new file mode 100644 index 00000000..d86284a7 --- /dev/null +++ b/test/include/liblvgl/misc/lv_types.h @@ -0,0 +1,381 @@ +/** + * @file lv_types.h + * + */ + +#ifndef LV_TYPES_H +#define LV_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#ifndef __ASSEMBLY__ +#include LV_STDINT_INCLUDE +#include LV_STDDEF_INCLUDE +#include LV_STDBOOL_INCLUDE +#include LV_INTTYPES_INCLUDE +#include LV_LIMITS_INCLUDE +#include LV_STDARG_INCLUDE +#endif + +/********************* + * DEFINES + *********************/ + +/*If __UINTPTR_MAX__ or UINTPTR_MAX are available, use them to determine arch size*/ +#if defined(__UINTPTR_MAX__) && __UINTPTR_MAX__ > 0xFFFFFFFF +#define LV_ARCH_64 + +#elif defined(UINTPTR_MAX) && UINTPTR_MAX > 0xFFFFFFFF +#define LV_ARCH_64 + +/*Otherwise use compiler-dependent means to determine arch size*/ +#elif defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__) || defined (__aarch64__) +#define LV_ARCH_64 + +#endif + +/********************** + * TYPEDEFS + **********************/ + +/* Exclude C enum and struct definitions when included by assembly code */ +#ifndef __ASSEMBLY__ + +/** + * LVGL error codes. + */ +typedef enum { + LV_RESULT_INVALID = 0, /*Typically indicates that the object is deleted (become invalid) in the action + function or an operation was failed*/ + LV_RESULT_OK, /*The object is valid (no deleted) after the action*/ +} lv_result_t; + +#if defined(__cplusplus) || __STDC_VERSION__ >= 199901L +/*If c99 or newer, use the definition of uintptr_t directly from */ +typedef uintptr_t lv_uintptr_t; +typedef intptr_t lv_intptr_t; + +#else + +/*Otherwise, use the arch size determination*/ +#ifdef LV_ARCH_64 +typedef uint64_t lv_uintptr_t; +typedef int64_t lv_intptr_t; +#else +typedef uint32_t lv_uintptr_t; +typedef int32_t lv_intptr_t; +#endif + +#endif + +#if LV_USE_FLOAT +typedef float lv_value_precise_t; +#else +typedef int32_t lv_value_precise_t; +#endif + +/** + * Typedefs from various lvgl modules. + * They are defined here to avoid circular dependencies. + */ + +typedef struct _lv_obj_t lv_obj_t; + +typedef uint16_t lv_state_t; +typedef uint32_t lv_part_t; + +typedef uint8_t lv_opa_t; + +typedef uint8_t lv_style_prop_t; + +typedef struct _lv_obj_class_t lv_obj_class_t; + +typedef struct _lv_group_t lv_group_t; + +typedef struct _lv_display_t lv_display_t; + +typedef struct _lv_layer_t lv_layer_t; +typedef struct _lv_draw_unit_t lv_draw_unit_t; +typedef struct _lv_draw_task_t lv_draw_task_t; + +typedef struct _lv_indev_t lv_indev_t; + +typedef struct _lv_event_t lv_event_t; + +typedef struct _lv_timer_t lv_timer_t; + +typedef struct _lv_theme_t lv_theme_t; + +typedef struct _lv_anim_t lv_anim_t; + +typedef struct _lv_font_t lv_font_t; + +typedef struct _lv_image_decoder_t lv_image_decoder_t; + +typedef struct _lv_image_decoder_dsc_t lv_image_decoder_dsc_t; + +typedef struct _lv_fragment_t lv_fragment_t; +typedef struct _lv_fragment_class_t lv_fragment_class_t; +typedef struct _lv_fragment_managed_states_t lv_fragment_managed_states_t; + +typedef struct _lv_profiler_builtin_config_t lv_profiler_builtin_config_t; + +typedef struct _lv_rb_node_t lv_rb_node_t; + +typedef struct _lv_rb_t lv_rb_t; + +typedef struct _lv_color_filter_dsc_t lv_color_filter_dsc_t; + +typedef struct _lv_event_dsc_t lv_event_dsc_t; + +typedef struct _lv_fs_file_cache_t lv_fs_file_cache_t; + +typedef struct _lv_fs_path_ex_t lv_fs_path_ex_t; + +typedef struct _lv_image_decoder_args_t lv_image_decoder_args_t; + +typedef struct _lv_image_cache_data_t lv_image_cache_data_t; + +typedef struct _lv_image_header_cache_data_t lv_image_header_cache_data_t; + +typedef struct _lv_draw_mask_t lv_draw_mask_t; + +typedef struct _lv_grad_t lv_grad_t; + +typedef struct _lv_draw_label_hint_t lv_draw_label_hint_t; + +typedef struct _lv_draw_glyph_dsc_t lv_draw_glyph_dsc_t; + +typedef struct _lv_draw_image_sup_t lv_draw_image_sup_t; + +typedef struct _lv_draw_mask_rect_dsc_t lv_draw_mask_rect_dsc_t; + +typedef struct _lv_obj_style_t lv_obj_style_t; + +typedef struct _lv_obj_style_transition_dsc_t lv_obj_style_transition_dsc_t; + +typedef struct _lv_hit_test_info_t lv_hit_test_info_t; + +typedef struct _lv_cover_check_info_t lv_cover_check_info_t; + +typedef struct _lv_obj_spec_attr_t lv_obj_spec_attr_t; + +typedef struct _lv_image_t lv_image_t; + +typedef struct _lv_animimg_t lv_animimg_t; + +typedef struct _lv_arc_t lv_arc_t; + +typedef struct _lv_label_t lv_label_t; + +typedef struct _lv_bar_anim_t lv_bar_anim_t; + +typedef struct _lv_bar_t lv_bar_t; + +typedef struct _lv_button_t lv_button_t; + +typedef struct _lv_buttonmatrix_t lv_buttonmatrix_t; + +typedef struct _lv_calendar_t lv_calendar_t; + +typedef struct _lv_canvas_t lv_canvas_t; + +typedef struct _lv_chart_series_t lv_chart_series_t; + +typedef struct _lv_chart_cursor_t lv_chart_cursor_t; + +typedef struct _lv_chart_t lv_chart_t; + +typedef struct _lv_checkbox_t lv_checkbox_t; + +typedef struct _lv_dropdown_t lv_dropdown_t; + +typedef struct _lv_dropdown_list_t lv_dropdown_list_t; + +typedef struct _lv_imagebutton_src_info_t lv_imagebutton_src_info_t; + +typedef struct _lv_imagebutton_t lv_imagebutton_t; + +typedef struct _lv_keyboard_t lv_keyboard_t; + +typedef struct _lv_led_t lv_led_t; + +typedef struct _lv_line_t lv_line_t; + +typedef struct _lv_menu_load_page_event_data_t lv_menu_load_page_event_data_t; + +typedef struct _lv_menu_history_t lv_menu_history_t; + +typedef struct _lv_menu_t lv_menu_t; + +typedef struct _lv_menu_page_t lv_menu_page_t; + +typedef struct _lv_msgbox_t lv_msgbox_t; + +typedef struct _lv_roller_t lv_roller_t; + +typedef struct _lv_scale_section_t lv_scale_section_t; + +typedef struct _lv_scale_t lv_scale_t; + +typedef struct _lv_slider_t lv_slider_t; + +typedef struct _lv_span_t lv_span_t; + +typedef struct _lv_spangroup_t lv_spangroup_t; + +typedef struct _lv_textarea_t lv_textarea_t; + +typedef struct _lv_spinbox_t lv_spinbox_t; + +typedef struct _lv_switch_t lv_switch_t; + +typedef struct _lv_table_cell_t lv_table_cell_t; + +typedef struct _lv_table_t lv_table_t; + +typedef struct _lv_tabview_t lv_tabview_t; + +typedef struct _lv_tileview_t lv_tileview_t; + +typedef struct _lv_tileview_tile_t lv_tileview_tile_t; + +typedef struct _lv_win_t lv_win_t; + +typedef struct _lv_observer_t lv_observer_t; + +typedef struct _lv_monkey_config_t lv_monkey_config_t; + +typedef struct _lv_ime_pinyin_t lv_ime_pinyin_t; + +typedef struct _lv_file_explorer_t lv_file_explorer_t; + +typedef struct _lv_barcode_t lv_barcode_t; + +typedef struct _lv_gif_t lv_gif_t; + +typedef struct _lv_qrcode_t lv_qrcode_t; + +typedef struct _lv_freetype_outline_vector_t lv_freetype_outline_vector_t; + +typedef struct _lv_freetype_outline_event_param_t lv_freetype_outline_event_param_t; + +typedef struct _lv_fpoint_t lv_fpoint_t; + +typedef struct _lv_matrix_t lv_matrix_t; + +typedef struct _lv_vector_path_t lv_vector_path_t; + +typedef struct _lv_vector_gradient_t lv_vector_gradient_t; + +typedef struct _lv_vector_fill_dsc_t lv_vector_fill_dsc_t; + +typedef struct _lv_vector_stroke_dsc_t lv_vector_stroke_dsc_t; + +typedef struct _lv_vector_draw_dsc_t lv_vector_draw_dsc_t; + +typedef struct _lv_draw_vector_task_dsc_t lv_draw_vector_task_dsc_t; + +typedef struct _lv_vector_dsc_t lv_vector_dsc_t; + +typedef struct _lv_xkb_t lv_xkb_t; + +typedef struct _lv_libinput_event_t lv_libinput_event_t; + +typedef struct _lv_libinput_t lv_libinput_t; + +typedef struct _lv_draw_sw_unit_t lv_draw_sw_unit_t; + +typedef struct _lv_draw_sw_mask_common_dsc_t lv_draw_sw_mask_common_dsc_t; + +typedef struct _lv_draw_sw_mask_line_param_t lv_draw_sw_mask_line_param_t; + +typedef struct _lv_draw_sw_mask_angle_param_t lv_draw_sw_mask_angle_param_t; + +typedef struct _lv_draw_sw_mask_radius_param_t lv_draw_sw_mask_radius_param_t; + +typedef struct _lv_draw_sw_mask_fade_param_t lv_draw_sw_mask_fade_param_t; + +typedef struct _lv_draw_sw_mask_map_param_t lv_draw_sw_mask_map_param_t; + +typedef struct _lv_draw_sw_blend_dsc_t lv_draw_sw_blend_dsc_t; + +typedef struct _lv_draw_sw_blend_fill_dsc_t lv_draw_sw_blend_fill_dsc_t; + +typedef struct _lv_draw_sw_blend_image_dsc_t lv_draw_sw_blend_image_dsc_t; + +typedef struct _lv_draw_buf_handlers_t lv_draw_buf_handlers_t; + +typedef struct _lv_rlottie_t lv_rlottie_t; + +typedef struct _lv_ffmpeg_player_t lv_ffmpeg_player_t; + +typedef struct _lv_glfw_window_t lv_glfw_window_t; +typedef struct _lv_glfw_texture_t lv_glfw_texture_t; + +typedef uint32_t lv_prop_id_t; + +typedef struct _lv_array_t lv_array_t; + +typedef struct _lv_iter_t lv_iter_t; + +typedef struct _lv_circle_buf_t lv_circle_buf_t; + +typedef struct _lv_draw_buf_t lv_draw_buf_t; + +#if LV_USE_OBJ_PROPERTY +typedef struct _lv_property_name_t lv_property_name_t; +#endif + +#if LV_USE_SYSMON + +typedef struct _lv_sysmon_backend_data_t lv_sysmon_backend_data_t; + +#if LV_USE_PERF_MONITOR +typedef struct _lv_sysmon_perf_info_t lv_sysmon_perf_info_t; +#endif /*LV_USE_PERF_MONITOR*/ + +#endif /*LV_USE_SYSMON*/ + +#endif /*__ASSEMBLY__*/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#define LV_UNUSED(x) ((void)x) + +#define _LV_CONCAT(x, y) x ## y +#define LV_CONCAT(x, y) _LV_CONCAT(x, y) +#undef _LV_CONCAT + +#define _LV_CONCAT3(x, y, z) x ## y ## z +#define LV_CONCAT3(x, y, z) _LV_CONCAT3(x, y, z) +#undef _LV_CONCAT3 + +#if defined(PYCPARSER) || defined(__CC_ARM) +#define LV_FORMAT_ATTRIBUTE(fmtstr, vararg) +#elif defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __GNUC__ > 4) +#define LV_FORMAT_ATTRIBUTE(fmtstr, vararg) __attribute__((format(gnu_printf, fmtstr, vararg))) +#elif (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) || defined(__IAR_SYSTEMS_ICC__)) +#define LV_FORMAT_ATTRIBUTE(fmtstr, vararg) __attribute__((format(printf, fmtstr, vararg))) +#else +#define LV_FORMAT_ATTRIBUTE(fmtstr, vararg) +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TYPES_H*/ diff --git a/test/include/liblvgl/misc/lv_utils.h b/test/include/liblvgl/misc/lv_utils.h new file mode 100644 index 00000000..7a8d6101 --- /dev/null +++ b/test/include/liblvgl/misc/lv_utils.h @@ -0,0 +1,68 @@ +/** + * @file lv_utils.h + * + */ + +#ifndef LV_UTILS_H +#define LV_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_types.h" +#include "../draw/lv_draw_buf.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** Searches base[0] to base[n - 1] for an item that matches *key. + * + * @note The function cmp must return negative if it's first + * argument (the search key) is less that it's second (a table entry), + * zero if equal, and positive if greater. + * + * @note Items in the array must be in ascending order. + * + * @param key Pointer to item being searched for + * @param base Pointer to first element to search + * @param n Number of elements + * @param size Size of each element + * @param cmp Pointer to comparison function (see unicode_list_compare() + * as a comparison function example) + * + * @return a pointer to a matching item, or NULL if none exists. + */ +void * lv_utils_bsearch(const void * key, const void * base, size_t n, size_t size, + int (*cmp)(const void * pRef, const void * pElement)); + +/** + * Save a draw buf to a file + * @param draw_buf pointer to a draw buffer + * @param path path to the file to save + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: error + */ +lv_result_t lv_draw_buf_save_to_file(const lv_draw_buf_t * draw_buf, const char * path); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/test/include/liblvgl/osal/lv_cmsis_rtos2.h b/test/include/liblvgl/osal/lv_cmsis_rtos2.h new file mode 100644 index 00000000..62481e7e --- /dev/null +++ b/test/include/liblvgl/osal/lv_cmsis_rtos2.h @@ -0,0 +1,53 @@ +/** + * @file lv_cmsis_rtos2.h + * + */ + +/* + * Copyright (C) 2023 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef LV_CMSIS_RTOS2_H +#define LV_CMSIS_RTOS2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#if LV_USE_OS == LV_OS_CMSIS_RTOS2 + +#include "cmsis_os2.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef osThreadId_t lv_thread_t; + +typedef osMutexId_t lv_mutex_t; + +typedef osEventFlagsId_t lv_thread_sync_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OS == LV_OS_CMSIS_RTOS2*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OS_CMSIS_RTOS2*/ diff --git a/test/include/liblvgl/osal/lv_freertos.h b/test/include/liblvgl/osal/lv_freertos.h new file mode 100644 index 00000000..67a5a1e7 --- /dev/null +++ b/test/include/liblvgl/osal/lv_freertos.h @@ -0,0 +1,105 @@ +/** + * @file lv_freertos.h + * + */ + +/** + * Copyright 2023 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_FREERTOS_H +#define LV_FREERTOS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_os.h" + +#if LV_USE_OS == LV_OS_FREERTOS + +#if (ESP_PLATFORM) +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#else +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + void (*pvStartRoutine)(void *); /**< Application thread function. */ + void * pTaskArg; /**< Arguments for application thread function. */ + TaskHandle_t xTaskHandle; /**< FreeRTOS task handle. */ +} lv_thread_t; + +typedef struct { + BaseType_t xIsInitialized; /**< Set to pdTRUE if this mutex is initialized, pdFALSE otherwise. */ + SemaphoreHandle_t xMutex; /**< FreeRTOS mutex. */ +} lv_mutex_t; + +typedef struct { + BaseType_t + xIsInitialized; /**< Set to pdTRUE if this condition variable is initialized, pdFALSE otherwise. */ + BaseType_t xSyncSignal; /**< Set to pdTRUE if the thread is signaled, pdFALSE otherwise. */ +#if LV_USE_FREERTOS_TASK_NOTIFY + TaskHandle_t xTaskToNotify; /**< The task waiting to be signalled. NULL if nothing is waiting. */ +#else + SemaphoreHandle_t xCondWaitSemaphore; /**< Threads block on this semaphore in lv_thread_sync_wait. */ + uint32_t ulWaitingThreads; /**< The number of threads currently waiting on this condition variable. */ + SemaphoreHandle_t xSyncMutex; /**< Threads take this mutex before accessing the condition variable. */ +#endif +} lv_thread_sync_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Set it for `traceTASK_SWITCHED_IN()` as + * `lv_freertos_task_switch_in(pxCurrentTCB->pcTaskName)` + * to save the start time stamp of a task + * @param name the name of the which is switched in + */ +void lv_freertos_task_switch_in(const char * name); + +/** + * Set it for `traceTASK_SWITCHED_OUT()` as + * `lv_freertos_task_switch_out()` + * to save finish time stamp of a task + */ +void lv_freertos_task_switch_out(void); + +/** + * Set it for `LV_SYSMON_GET_IDLE` to show the CPU usage + * as reported based the usage of FreeRTOS's idle task + * If it's important when a GPU is used. + * @return the idle percentage since the last call + */ +uint32_t lv_os_get_idle_percent(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OS == LV_OS_FREERTOS*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FREERTOS_H*/ diff --git a/test/include/liblvgl/osal/lv_mqx.h b/test/include/liblvgl/osal/lv_mqx.h new file mode 100644 index 00000000..601f596a --- /dev/null +++ b/test/include/liblvgl/osal/lv_mqx.h @@ -0,0 +1,51 @@ +/** + * @file lv_mqx.h + * + */ + +#ifndef LV_MQX_H +#define LV_MQX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_os.h" + +#if LV_USE_OS == LV_OS_MQX + +#include "mqx.h" +#include "mutex.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef _task_id lv_thread_t; + +typedef MUTEX_STRUCT lv_mutex_t; + +typedef LWSEM_STRUCT lv_thread_sync_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OS == LV_OS_MQX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MQX_H*/ diff --git a/test/include/liblvgl/osal/lv_os.h b/test/include/liblvgl/osal/lv_os.h new file mode 100644 index 00000000..d0a4e02f --- /dev/null +++ b/test/include/liblvgl/osal/lv_os.h @@ -0,0 +1,186 @@ +/** + * @file lv_os.h + * + */ + +#ifndef LV_OS_H +#define LV_OS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * OS OPTIONS + *********************/ + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include "../misc/lv_types.h" + +#if LV_USE_OS == LV_OS_NONE +#include "lv_os_none.h" +#elif LV_USE_OS == LV_OS_PTHREAD +#include "lv_pthread.h" +#elif LV_USE_OS == LV_OS_FREERTOS +#include "lv_freertos.h" +#elif LV_USE_OS == LV_OS_CMSIS_RTOS2 +#include "lv_cmsis_rtos2.h" +#elif LV_USE_OS == LV_OS_RTTHREAD +#include "lv_rtthread.h" +#elif LV_USE_OS == LV_OS_WINDOWS +#include "lv_windows.h" +#elif LV_USE_OS == LV_OS_MQX +#include "lv_mqx.h" +#elif LV_USE_OS == LV_OS_CUSTOM +#include LV_OS_CUSTOM_INCLUDE +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_THREAD_PRIO_LOWEST, + LV_THREAD_PRIO_LOW, + LV_THREAD_PRIO_MID, + LV_THREAD_PRIO_HIGH, + LV_THREAD_PRIO_HIGHEST, +} lv_thread_prio_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/*---------------------------------------- + * These functions needs to be implemented + * for specific operating systems + *---------------------------------------*/ + +/** + * Create a new thread + * @param thread a variable in which the thread will be stored + * @param prio priority of the thread + * @param callback function of the thread + * @param stack_size stack size in bytes + * @param user_data arbitrary data, will be available in the callback + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, + void * user_data); + +/** + * Delete a thread + * @param thread the thread to delete + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_delete(lv_thread_t * thread); + +/** + * Create a mutex + * @param mutex a variable in which the thread will be stored + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_mutex_init(lv_mutex_t * mutex); + +/** + * Lock a mutex + * @param mutex the mutex to lock + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_mutex_lock(lv_mutex_t * mutex); + +/** + * Lock a mutex from interrupt + * @param mutex the mutex to lock + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex); + +/** + * Unlock a mutex + * @param mutex the mutex to unlock + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_mutex_unlock(lv_mutex_t * mutex); + +/** + * Delete a mutex + * @param mutex the mutex to delete + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_mutex_delete(lv_mutex_t * mutex); + +/** + * Create a thread synchronization object + * @param sync a variable in which the sync will be stored + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync); + +/** + * Wait for a "signal" on a sync object + * @param sync a sync object + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync); + +/** + * Send a wake-up signal to a sync object + * @param sync a sync object + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync); + +/** + * Send a wake-up signal to a sync object from interrupt + * @param sync a sync object + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync); + +/** + * Delete a sync object + * @param sync a sync object to delete + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync); + +/** + * Lock LVGL's general mutex. + * LVGL is not thread safe, so a mutex is used to avoid executing multiple LVGL functions at the same time + * from different threads. It shall be called when calling LVGL functions from threads + * different than lv_timer_handler's thread. It doesn't need to be called in LVGL events because + * they are called from lv_timer_handler(). + * It is called internally in lv_timer_handler(). + */ +void lv_lock(void); + +/** + * Same as `lv_lock()` but can be called from an interrupt. + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_lock_isr(void); + +/** + * The pair of `lv_lock()` and `lv_lock_isr()`. + * It unlocks LVGL general mutex. + * It is called internally in lv_timer_handler(). + */ +void lv_unlock(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OS_H*/ diff --git a/test/include/liblvgl/osal/lv_os_none.h b/test/include/liblvgl/osal/lv_os_none.h new file mode 100644 index 00000000..e08a0dc4 --- /dev/null +++ b/test/include/liblvgl/osal/lv_os_none.h @@ -0,0 +1,43 @@ +/** + * @file lv_os_none.h + * + */ + +#ifndef LV_OS_NONE_H +#define LV_OS_NONE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#if LV_USE_OS == LV_OS_NONE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef int lv_mutex_t; +typedef int lv_thread_t; +typedef int lv_thread_sync_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OS == LV_OS_NONE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OS_NONE_H*/ diff --git a/test/include/liblvgl/osal/lv_os_private.h b/test/include/liblvgl/osal/lv_os_private.h new file mode 100644 index 00000000..4fe08cd2 --- /dev/null +++ b/test/include/liblvgl/osal/lv_os_private.h @@ -0,0 +1,47 @@ +/** + * @file lv_os_private.h + * + */ + +#ifndef LV_OS_PRIVATE_H +#define LV_OS_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * OS OPTIONS + *********************/ + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the OS layer + */ +void lv_os_init(void); + + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OS_PRIVATE_H*/ diff --git a/test/include/liblvgl/osal/lv_pthread.h b/test/include/liblvgl/osal/lv_pthread.h new file mode 100644 index 00000000..e7abc90c --- /dev/null +++ b/test/include/liblvgl/osal/lv_pthread.h @@ -0,0 +1,57 @@ +/** + * @file lv_pthread.h + * + */ + +#ifndef LV_PTHREAD_H +#define LV_PTHREAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#if LV_USE_OS == LV_OS_PTHREAD + +#include +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + pthread_t thread; + void (*callback)(void *); + void * user_data; +} lv_thread_t; + +typedef pthread_mutex_t lv_mutex_t; + +typedef struct { + pthread_mutex_t mutex; + pthread_cond_t cond; + bool v; +} lv_thread_sync_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OS == LV_OS_PTHREAD*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_PTHREAD_H*/ diff --git a/test/include/liblvgl/osal/lv_rtthread.h b/test/include/liblvgl/osal/lv_rtthread.h new file mode 100644 index 00000000..255a47af --- /dev/null +++ b/test/include/liblvgl/osal/lv_rtthread.h @@ -0,0 +1,54 @@ +/** + * @file lv_rtthread.h + * + */ + +#ifndef LV_RTTHREAD_H +#define LV_RTTHREAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#if LV_USE_OS == LV_OS_RTTHREAD + +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + rt_thread_t thread; +} lv_thread_t; + +typedef struct { + rt_mutex_t mutex; +} lv_mutex_t; + +typedef struct { + rt_sem_t sem; +} lv_thread_sync_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OS == LV_OS_RTTHREAD*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_RTTHREAD_H*/ diff --git a/test/include/liblvgl/osal/lv_windows.h b/test/include/liblvgl/osal/lv_windows.h new file mode 100644 index 00000000..9d864535 --- /dev/null +++ b/test/include/liblvgl/osal/lv_windows.h @@ -0,0 +1,54 @@ +/** + * @file lv_windows.h + * + */ + +#ifndef LV_WINDOWS_H +#define LV_WINDOWS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#if LV_USE_OS == LV_OS_WINDOWS + +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef HANDLE lv_thread_t; + +typedef CRITICAL_SECTION lv_mutex_t; + +typedef struct { + CRITICAL_SECTION cs; + CONDITION_VARIABLE cv; + bool v; +} lv_thread_sync_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OS == LV_OS_WINDOWS*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WINDOWS_H*/ diff --git a/test/include/liblvgl/others/file_explorer/lv_file_explorer.h b/test/include/liblvgl/others/file_explorer/lv_file_explorer.h new file mode 100644 index 00000000..8dd7762f --- /dev/null +++ b/test/include/liblvgl/others/file_explorer/lv_file_explorer.h @@ -0,0 +1,168 @@ +/** + * @file lv_file_explorer.h + * + */ + +#ifndef LV_FILE_EXPLORER_H +#define LV_FILE_EXPLORER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../core/lv_obj.h" + +#if LV_USE_FILE_EXPLORER != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_EXPLORER_SORT_NONE, + LV_EXPLORER_SORT_KIND, +} lv_file_explorer_sort_t; + +#if LV_FILE_EXPLORER_QUICK_ACCESS +typedef enum { + LV_EXPLORER_HOME_DIR, + LV_EXPLORER_MUSIC_DIR, + LV_EXPLORER_PICTURES_DIR, + LV_EXPLORER_VIDEO_DIR, + LV_EXPLORER_DOCS_DIR, + LV_EXPLORER_FS_DIR, +} lv_file_explorer_dir_t; +#endif + +extern const lv_obj_class_t lv_file_explorer_class; + +/*********************** + * GLOBAL VARIABLES + ***********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +lv_obj_t * lv_file_explorer_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +#if LV_FILE_EXPLORER_QUICK_ACCESS +/** + * Set file_explorer + * @param obj pointer to a label object + * @param dir the dir from 'lv_file_explorer_dir_t' enum. + * @param path path + + */ +void lv_file_explorer_set_quick_access_path(lv_obj_t * obj, lv_file_explorer_dir_t dir, const char * path); +#endif + +/** + * Set file_explorer sort + * @param obj pointer to a file explorer object + * @param sort the sort from 'lv_file_explorer_sort_t' enum. + */ +void lv_file_explorer_set_sort(lv_obj_t * obj, lv_file_explorer_sort_t sort); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get file explorer Selected file + * @param obj pointer to a file explorer object + * @return pointer to the file explorer selected file name + */ +const char * lv_file_explorer_get_selected_file_name(const lv_obj_t * obj); + +/** + * Get file explorer cur path + * @param obj pointer to a file explorer object + * @return pointer to the file explorer cur path + */ +const char * lv_file_explorer_get_current_path(const lv_obj_t * obj); + +/** + * Get file explorer head area obj + * @param obj pointer to a file explorer object + * @return pointer to the file explorer head area obj(lv_obj) + */ +lv_obj_t * lv_file_explorer_get_header(lv_obj_t * obj); + +/** + * Get file explorer head area obj + * @param obj pointer to a file explorer object + * @return pointer to the file explorer quick access area obj(lv_obj) + */ +lv_obj_t * lv_file_explorer_get_quick_access_area(lv_obj_t * obj); + +/** + * Get file explorer path obj(label) + * @param obj pointer to a file explorer object + * @return pointer to the file explorer path obj(lv_label) + */ +lv_obj_t * lv_file_explorer_get_path_label(lv_obj_t * obj); + +#if LV_FILE_EXPLORER_QUICK_ACCESS +/** + * Get file explorer places list obj(lv_list) + * @param obj pointer to a file explorer object + * @return pointer to the file explorer places list obj(lv_list) + */ +lv_obj_t * lv_file_explorer_get_places_list(lv_obj_t * obj); + +/** + * Get file explorer device list obj(lv_list) + * @param obj pointer to a file explorer object + * @return pointer to the file explorer device list obj(lv_list) + */ +lv_obj_t * lv_file_explorer_get_device_list(lv_obj_t * obj); +#endif + +/** + * Get file explorer file list obj(lv_table) + * @param obj pointer to a file explorer object + * @return pointer to the file explorer file table obj(lv_table) + */ +lv_obj_t * lv_file_explorer_get_file_table(lv_obj_t * obj); + +/** + * Set file_explorer sort + * @param obj pointer to a file explorer object + * @return the current mode from 'lv_file_explorer_sort_t' + */ +lv_file_explorer_sort_t lv_file_explorer_get_sort(const lv_obj_t * obj); + +/*===================== + * Other functions + *====================*/ + +/** + * Open a specified path + * @param obj pointer to a file explorer object + * @param dir pointer to the path + */ +void lv_file_explorer_open_dir(lv_obj_t * obj, const char * dir); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_FILE_EXPLORER*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FILE_EXPLORER_H*/ diff --git a/test/include/liblvgl/others/file_explorer/lv_file_explorer_private.h b/test/include/liblvgl/others/file_explorer/lv_file_explorer_private.h new file mode 100644 index 00000000..430debb5 --- /dev/null +++ b/test/include/liblvgl/others/file_explorer/lv_file_explorer_private.h @@ -0,0 +1,69 @@ +/** + * @file lv_file_explorer_private.h + * + */ + +#ifndef LV_FILE_EXPLORER_PRIVATE_H +#define LV_FILE_EXPLORER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_file_explorer.h" + +#if LV_USE_FILE_EXPLORER != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/*Data of canvas*/ +struct _lv_file_explorer_t { + lv_obj_t obj; + lv_obj_t * cont; + lv_obj_t * head_area; + lv_obj_t * browser_area; + lv_obj_t * file_table; + lv_obj_t * path_label; +#if LV_FILE_EXPLORER_QUICK_ACCESS + lv_obj_t * quick_access_area; + lv_obj_t * list_device; + lv_obj_t * list_places; + char * home_dir; + char * music_dir; + char * pictures_dir; + char * video_dir; + char * docs_dir; + char * fs_dir; +#endif + const char * sel_fn; + char current_path[LV_FILE_EXPLORER_PATH_MAX_LEN]; + lv_file_explorer_sort_t sort; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_FILE_EXPLORER != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FILE_EXPLORER_PRIVATE_H*/ diff --git a/test/include/liblvgl/others/font_manager/lv_font_manager.h b/test/include/liblvgl/others/font_manager/lv_font_manager.h new file mode 100644 index 00000000..b5e33b9f --- /dev/null +++ b/test/include/liblvgl/others/font_manager/lv_font_manager.h @@ -0,0 +1,106 @@ +/** + * @file lv_font_manager.h + * + */ +#ifndef LV_FONT_MANAGER_H +#define LV_FONT_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../misc/lv_types.h" + +#if LV_USE_FONT_MANAGER + +#if !LV_USE_FREETYPE +#error "LV_USE_FONT_MANAGER requires LV_USE_FREETYPE" +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_font_manager_t lv_font_manager_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create main font manager. + * @param recycle_cache_size number of fonts that were recently deleted from the cache. + * @return pointer to main font manager. + */ +lv_font_manager_t * lv_font_manager_create(uint32_t recycle_cache_size); + +/** + * Delete main font manager. + * @param manager pointer to main font manager. + * @return return true if the deletion was successful. + */ +bool lv_font_manager_delete(lv_font_manager_t * manager); + +/** + * Add the font file path. + * @param manager pointer to main font manager. + * @param name font name. + * @param path font file path. + */ +void lv_font_manager_add_path(lv_font_manager_t * manager, const char * name, const char * path); + +/** + * Add the font file path with static memory. + * @param manager pointer to main font manager. + * @param name font name. + * @param path font file path. + */ +void lv_font_manager_add_path_static(lv_font_manager_t * manager, const char * name, const char * path); + +/** + * Remove the font file path. + * @param manager pointer to main font manager. + * @param name font name. + * @return return true if the remove was successful. + */ +bool lv_font_manager_remove_path(lv_font_manager_t * manager, const char * name); + +/** + * Create font. + * @param manager pointer to main font manager. + * @param font_family font family name. + * @param render_mode font render mode, see lv_freetype_font_render_mode_t. + * @param size font size. + * @param style font style, see lv_freetype_font_style_t. + * @return point to the created font + */ +lv_font_t * lv_font_manager_create_font(lv_font_manager_t * manager, const char * font_family, uint16_t render_mode, + uint32_t size, uint16_t style); + +/** + * Delete font. + * @param manager pointer to main font manager. + * @param font point to the font. + * @return return true if the deletion was successful. + */ +void lv_font_manager_delete_font(lv_font_manager_t * manager, lv_font_t * font); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_FONT_MANAGER */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* FONT_MANAGER_MANAGER_H */ diff --git a/test/include/liblvgl/others/font_manager/lv_font_manager_recycle.h b/test/include/liblvgl/others/font_manager/lv_font_manager_recycle.h new file mode 100644 index 00000000..57d41ec4 --- /dev/null +++ b/test/include/liblvgl/others/font_manager/lv_font_manager_recycle.h @@ -0,0 +1,78 @@ +/** + * @file lv_font_manager_recycle.h + * + */ + +#ifndef LV_FONT_MANAGER_RECYCLE_H +#define LV_FONT_MANAGER_RECYCLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_font_manager_utils.h" + +#if LV_USE_FONT_MANAGER + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_font_manager_recycle_t lv_font_manager_recycle_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create font recycle manager. + * @param max_size recycle size. + * @return pointer to font recycle manager. + */ +lv_font_manager_recycle_t * lv_font_manager_recycle_create(uint32_t max_size); + +/** + * Delete font recycle manager. + * @param manager pointer to font recycle manager. + */ +void lv_font_manager_recycle_delete(lv_font_manager_recycle_t * manager); + +/** + * Get a reusable font. + * @param manager pointer to font recycle manager. + * @param ft_info font info. + * @return returns true on success. + */ +lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manager, const lv_freetype_info_t * ft_info); + +/** + * Set fonts to be reused. + * @param manager pointer to font recycle manager. + * @param ft_info font info. + */ +void lv_font_manager_recycle_set_reuse(lv_font_manager_recycle_t * manager, lv_font_t * font, + const lv_freetype_info_t * ft_info); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_FONT_MANAGER */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_FONT_MANAGER_RECYCLE_H */ diff --git a/test/include/liblvgl/others/font_manager/lv_font_manager_utils.h b/test/include/liblvgl/others/font_manager/lv_font_manager_utils.h new file mode 100644 index 00000000..a04b287e --- /dev/null +++ b/test/include/liblvgl/others/font_manager/lv_font_manager_utils.h @@ -0,0 +1,59 @@ +/** + * @file lv_font_manager_utils.h + * + */ +#ifndef LV_FONT_MANAGER_UTILS_H +#define LV_FONT_MANAGER_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../misc/lv_types.h" + +#if LV_USE_FONT_MANAGER + +#include "../../libs/freetype/lv_freetype.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const char * name; + lv_freetype_font_render_mode_t render_mode; + lv_freetype_font_style_t style; + uint32_t size; +} lv_freetype_info_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Compare font information. + * @param ft_info_1 font information 1. + * @param ft_info_2 font information 2. + * @return return true if the fonts are equal. + */ +bool lv_freetype_info_is_equal(const lv_freetype_info_t * ft_info_1, const lv_freetype_info_t * ft_info_2); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_FONT_MANAGER*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_FONT_MANAGER_UTILS_H */ diff --git a/test/include/liblvgl/others/fragment/README.md b/test/include/liblvgl/others/fragment/README.md new file mode 100644 index 00000000..e69de29b diff --git a/test/include/liblvgl/others/fragment/lv_fragment.h b/test/include/liblvgl/others/fragment/lv_fragment.h new file mode 100644 index 00000000..1e7d29fc --- /dev/null +++ b/test/include/liblvgl/others/fragment/lv_fragment.h @@ -0,0 +1,297 @@ +/** + * Public header for Fragment + * @file lv_fragment.h + */ + +#ifndef LV_FRAGMENT_H +#define LV_FRAGMENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_FRAGMENT + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_fragment_manager_t lv_fragment_manager_t; + +struct _lv_fragment_t { + /** + * Class of this fragment + */ + const lv_fragment_class_t * cls; + /** + * Managed fragment states. If not null, then this fragment is managed. + * + * @warning Don't modify values inside this struct! + */ + lv_fragment_managed_states_t * managed; + /** + * Child fragment manager + */ + lv_fragment_manager_t * child_manager; + /** + * lv_obj returned by create_obj_cb + */ + lv_obj_t * obj; + +}; + +struct _lv_fragment_class_t { + /** + * Constructor function for fragment class + * @param self Fragment instance + * @param args Arguments assigned by fragment manager + */ + void (*constructor_cb)(lv_fragment_t * self, void * args); + + /** + * Destructor function for fragment class + * @param self Fragment instance, will be freed after this call + */ + void (*destructor_cb)(lv_fragment_t * self); + + /** + * Fragment attached to manager + * @param self Fragment instance + */ + void (*attached_cb)(lv_fragment_t * self); + + /** + * Fragment detached from manager + * @param self Fragment instance + */ + void (*detached_cb)(lv_fragment_t * self); + + /** + * Create objects + * @param self Fragment instance + * @param container Container of the objects should be created upon + * @return Created object, NULL if multiple objects has been created + */ + lv_obj_t * (*create_obj_cb)(lv_fragment_t * self, lv_obj_t * container); + + /** + * + * @param self Fragment instance + * @param obj lv_obj returned by create_obj_cb + */ + void (*obj_created_cb)(lv_fragment_t * self, lv_obj_t * obj); + + /** + * Called before objects in the fragment will be deleted. + * + * @param self Fragment instance + * @param obj object with this fragment + */ + void (*obj_will_delete_cb)(lv_fragment_t * self, lv_obj_t * obj); + + /** + * Called when the object created by fragment received `LV_EVENT_DELETE` event + * @param self Fragment instance + * @param obj object with this fragment + */ + void (*obj_deleted_cb)(lv_fragment_t * self, lv_obj_t * obj); + + /** + * Handle event + * @param self Fragment instance + * @param which User-defined ID of event + * @param data1 User-defined data + * @param data2 User-defined data + */ + bool (*event_cb)(lv_fragment_t * self, int code, void * userdata); + + /** + * *REQUIRED*: Allocation size of fragment + */ + size_t instance_size; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create fragment manager instance + * @param parent Parent fragment if this manager is placed inside another fragment, can be null. + * @return Fragment manager instance + */ +lv_fragment_manager_t * lv_fragment_manager_create(lv_fragment_t * parent); + +/** + * Destroy fragment manager instance + * @param manager Fragment manager instance + */ +void lv_fragment_manager_delete(lv_fragment_manager_t * manager); + +/** + * Create object of all fragments managed by this manager. + * @param manager Fragment manager instance + */ +void lv_fragment_manager_create_obj(lv_fragment_manager_t * manager); + +/** + * Delete object created by all fragments managed by this manager. Instance of fragments will not be deleted. + * @param manager Fragment manager instance + */ +void lv_fragment_manager_delete_obj(lv_fragment_manager_t * manager); + +/** + * Attach fragment to manager, and add to container. + * @param manager Fragment manager instance + * @param fragment Fragment instance + * @param container Pointer to container object for manager to add objects to + */ +void lv_fragment_manager_add(lv_fragment_manager_t * manager, lv_fragment_t * fragment, lv_obj_t * const * container); + +/** + * Detach and destroy fragment. If fragment is in navigation stack, remove from it. + * @param manager Fragment manager instance + * @param fragment Fragment instance + */ +void lv_fragment_manager_remove(lv_fragment_manager_t * manager, lv_fragment_t * fragment); + +/** + * Attach fragment to manager and add to navigation stack. + * @param manager Fragment manager instance + * @param fragment Fragment instance + * @param container Pointer to container object for manager to add objects to + */ +void lv_fragment_manager_push(lv_fragment_manager_t * manager, lv_fragment_t * fragment, lv_obj_t * const * container); + +/** + * Remove the top-most fragment for stack + * @param manager Fragment manager instance + * @return true if there is fragment to pop + */ +bool lv_fragment_manager_pop(lv_fragment_manager_t * manager); + +/** + * Replace fragment. Old item in the stack will be removed. + * @param manager Fragment manager instance + * @param fragment Fragment instance + * @param container Pointer to container object for manager to add objects to + */ +void lv_fragment_manager_replace(lv_fragment_manager_t * manager, lv_fragment_t * fragment, + lv_obj_t * const * container); + +/** + * Send event to top-most fragment + * @param manager Fragment manager instance + * @param code User-defined ID of event + * @param userdata User-defined data + * @return true if fragment returned true + */ +bool lv_fragment_manager_send_event(lv_fragment_manager_t * manager, int code, void * userdata); + +/** + * Get stack size of this fragment manager + * @param manager Fragment manager instance + * @return Stack size of this fragment manager + */ +size_t lv_fragment_manager_get_stack_size(lv_fragment_manager_t * manager); + +/** + * Get top most fragment instance + * @param manager Fragment manager instance + * @return Top most fragment instance + */ +lv_fragment_t * lv_fragment_manager_get_top(lv_fragment_manager_t * manager); + +/** + * Find first fragment instance in the container + * @param manager Fragment manager instance + * @param container Container which target fragment added to + * @return First fragment instance in the container + */ +lv_fragment_t * lv_fragment_manager_find_by_container(lv_fragment_manager_t * manager, const lv_obj_t * container); + +/** + * Get parent fragment + * @param manager Fragment manager instance + * @return Parent fragment instance + */ +lv_fragment_t * lv_fragment_manager_get_parent_fragment(lv_fragment_manager_t * manager); + +/** + * Create a fragment instance. + * + * @param cls Fragment class. This fragment must return non null object. + * @param args Arguments assigned by fragment manager + * @return Fragment instance + */ +lv_fragment_t * lv_fragment_create(const lv_fragment_class_t * cls, void * args); + +/** + * Destroy a fragment. + * @param fragment Fragment instance. + */ +void lv_fragment_delete(lv_fragment_t * fragment); + +/** + * Get associated manager of this fragment + * @param fragment Fragment instance + * @return Fragment manager instance + */ +lv_fragment_manager_t * lv_fragment_get_manager(lv_fragment_t * fragment); + +/** + * Get container object of this fragment + * @param fragment Fragment instance + * @return Reference to container object + */ +lv_obj_t * const * lv_fragment_get_container(lv_fragment_t * fragment); + +/** + * Get parent fragment of this fragment + * @param fragment Fragment instance + * @return Parent fragment + */ +lv_fragment_t * lv_fragment_get_parent(lv_fragment_t * fragment); + +/** + * Create object by fragment. + * + * @param fragment Fragment instance. + * @param container Container of the objects should be created upon. + * @return Created object + */ +lv_obj_t * lv_fragment_create_obj(lv_fragment_t * fragment, lv_obj_t * container); + +/** + * Delete created object of a fragment + * + * @param fragment Fragment instance. + */ +void lv_fragment_delete_obj(lv_fragment_t * fragment); + +/** + * Destroy obj in fragment, and recreate them. + * @param fragment Fragment instance + */ +void lv_fragment_recreate_obj(lv_fragment_t * fragment); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_FRAGMENT*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FRAGMENT_H*/ diff --git a/test/include/liblvgl/others/fragment/lv_fragment_private.h b/test/include/liblvgl/others/fragment/lv_fragment_private.h new file mode 100644 index 00000000..bf0d23f4 --- /dev/null +++ b/test/include/liblvgl/others/fragment/lv_fragment_private.h @@ -0,0 +1,77 @@ +/** + * @file lv_fragment_private.h + * + */ + +#ifndef LV_FRAGMENT_PRIVATE_H +#define LV_FRAGMENT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_fragment.h" + +#if LV_USE_FRAGMENT + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Fragment states + */ +struct _lv_fragment_managed_states_t { + /** + * Class of the fragment + */ + const lv_fragment_class_t * cls; + /** + * Manager the fragment attached to + */ + lv_fragment_manager_t * manager; + /** + * Container object the fragment adding view to + */ + lv_obj_t * const * container; + /** + * Fragment instance + */ + lv_fragment_t * instance; + /** + * true between `create_obj_cb` and `obj_deleted_cb` + */ + bool obj_created; + /** + * true before `lv_fragment_delete_obj` is called. Don't touch any object if this is true + */ + bool destroying_obj; + /** + * true if this fragment is in navigation stack that can be popped + */ + bool in_stack; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_FRAGMENT */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FRAGMENT_PRIVATE_H*/ diff --git a/test/include/liblvgl/others/gridnav/lv_gridnav.h b/test/include/liblvgl/others/gridnav/lv_gridnav.h new file mode 100644 index 00000000..65bd1e09 --- /dev/null +++ b/test/include/liblvgl/others/gridnav/lv_gridnav.h @@ -0,0 +1,95 @@ +/** + * @file lv_gridnav.h + * + */ + +#ifndef LV_GRIDNAV_H +#define LV_GRIDNAV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_GRIDNAV + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_GRIDNAV_CTRL_NONE = 0x0, + + /** + * If there is no next/previous object in a direction, + * the focus goes to the object in the next/previous row (on left/right keys) + * or first/last row (on up/down keys) + */ + LV_GRIDNAV_CTRL_ROLLOVER = 0x1, + + /** + * If an arrow is pressed and the focused object can be scrolled in that direction + * then it will be scrolled instead of going to the next/previous object. + * If there is no more room for scrolling the next/previous object will be focused normally */ + LV_GRIDNAV_CTRL_SCROLL_FIRST = 0x2, + + /** + * Only use left/right keys for grid navigation. Up/down key events will be sent to the + * focused object. + */ + LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY = 0x4, + + /** + * Only use up/down keys for grid navigation. Left/right key events will be sent to the + * focused object. + */ + LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY = 0x8 + +} lv_gridnav_ctrl_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Add grid navigation feature to an object. It expects the children to be arranged + * into a grid-like layout. Although it's not required to have pixel perfect alignment. + * This feature makes possible to use keys to navigate among the children and focus them. + * The keys other than arrows and press/release related events + * are forwarded to the focused child. + * @param obj pointer to an object on which navigation should be applied. + * @param ctrl control flags from `lv_gridnav_ctrl_t`. + */ +void lv_gridnav_add(lv_obj_t * obj, lv_gridnav_ctrl_t ctrl); + +/** + * Remove the grid navigation support from an object + * @param obj pointer to an object + */ +void lv_gridnav_remove(lv_obj_t * obj); + +/** + * Manually focus an object on gridnav container + * @param cont pointer to a gridnav container + * @param to_focus pointer to an object to focus + * @param anim_en LV_ANIM_ON/OFF + */ +void lv_gridnav_set_focused(lv_obj_t * cont, lv_obj_t * to_focus, lv_anim_enable_t anim_en); + +/********************** + * MACROS + **********************/ +#endif /*LV_USE_GRIDNAV*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_GRIDNAV_H */ diff --git a/test/include/liblvgl/others/ime/lv_ime_pinyin.h b/test/include/liblvgl/others/ime/lv_ime_pinyin.h new file mode 100644 index 00000000..ff85eee8 --- /dev/null +++ b/test/include/liblvgl/others/ime/lv_ime_pinyin.h @@ -0,0 +1,121 @@ +/** + * @file lv_ime_pinyin.h + * + */ +#ifndef LV_IME_PINYIN_H +#define LV_IME_PINYIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../core/lv_obj.h" + +#if LV_USE_IME_PINYIN != 0 + +/********************* + * DEFINES + *********************/ +#define LV_IME_PINYIN_K9_MAX_INPUT 7 + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_IME_PINYIN_MODE_K26, + LV_IME_PINYIN_MODE_K9, + LV_IME_PINYIN_MODE_K9_NUMBER, +} lv_ime_pinyin_mode_t; + +/*Data of pinyin_dict*/ +typedef struct { + const char * const py; + const char * const py_mb; +} lv_pinyin_dict_t; + +/*Data of 9-key input(k9) mode*/ +typedef struct { + char py_str[7]; +} ime_pinyin_k9_py_str_t; + +/*********************** + * GLOBAL VARIABLES + ***********************/ + +extern const lv_obj_class_t lv_ime_pinyin_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ +lv_obj_t * lv_ime_pinyin_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the keyboard of Pinyin input method. + * @param obj pointer to a Pinyin input method object + * @param kb pointer to a Pinyin input method keyboard + */ +void lv_ime_pinyin_set_keyboard(lv_obj_t * obj, lv_obj_t * kb); + +/** + * Set the dictionary of Pinyin input method. + * @param obj pointer to a Pinyin input method object + * @param dict pointer to a Pinyin input method dictionary + */ +void lv_ime_pinyin_set_dict(lv_obj_t * obj, lv_pinyin_dict_t * dict); + +/** + * Set mode, 26-key input(k26) or 9-key input(k9). + * @param obj pointer to a Pinyin input method object + * @param mode the mode from 'lv_ime_pinyin_mode_t' + */ +void lv_ime_pinyin_set_mode(lv_obj_t * obj, lv_ime_pinyin_mode_t mode); + +/*===================== + * Getter functions + *====================*/ + +/** + * Set the dictionary of Pinyin input method. + * @param obj pointer to a Pinyin IME object + * @return pointer to the Pinyin IME keyboard + */ +lv_obj_t * lv_ime_pinyin_get_kb(lv_obj_t * obj); + +/** + * Set the dictionary of Pinyin input method. + * @param obj pointer to a Pinyin input method object + * @return pointer to the Pinyin input method candidate panel + */ +lv_obj_t * lv_ime_pinyin_get_cand_panel(lv_obj_t * obj); + +/** + * Set the dictionary of Pinyin input method. + * @param obj pointer to a Pinyin input method object + * @return pointer to the Pinyin input method dictionary + */ +const lv_pinyin_dict_t * lv_ime_pinyin_get_dict(lv_obj_t * obj); + +/*===================== + * Other functions + *====================*/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_IME_PINYIN*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_USE_IME_PINYIN*/ diff --git a/test/include/liblvgl/others/ime/lv_ime_pinyin_private.h b/test/include/liblvgl/others/ime/lv_ime_pinyin_private.h new file mode 100644 index 00000000..f422438e --- /dev/null +++ b/test/include/liblvgl/others/ime/lv_ime_pinyin_private.h @@ -0,0 +1,68 @@ +/** + * @file lv_ime_pinyin_private.h + * + */ + +#ifndef LV_IME_PINYIN_PRIVATE_H +#define LV_IME_PINYIN_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_ime_pinyin.h" + +#if LV_USE_IME_PINYIN != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/*Data of lv_ime_pinyin*/ +struct _lv_ime_pinyin_t { + lv_obj_t obj; + lv_obj_t * kb; + lv_obj_t * cand_panel; + const lv_pinyin_dict_t * dict; + lv_ll_t k9_legal_py_ll; + char * cand_str; /* Candidate string */ + char input_char[16]; /* Input box character */ +#if LV_IME_PINYIN_USE_K9_MODE + char k9_input_str[LV_IME_PINYIN_K9_MAX_INPUT + 1]; /* 9-key input(k9) mode input string */ + uint16_t k9_py_ll_pos; /* Current pinyin map pages(k9) */ + uint16_t k9_legal_py_count; /* Count of legal Pinyin numbers(k9) */ + uint16_t k9_input_str_len; /* 9-key input(k9) mode input string max len */ +#endif + uint16_t ta_count; /* The number of characters entered in the text box this time */ + uint16_t cand_num; /* Number of candidates */ + uint16_t py_page; /* Current pinyin map pages(k26) */ + uint16_t py_num[26]; /* Number and length of Pinyin */ + uint16_t py_pos[26]; /* Pinyin position */ + lv_ime_pinyin_mode_t mode; /* Set mode, 1: 26-key input(k26), 0: 9-key input(k9). Default: 1. */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_IME_PINYIN != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IME_PINYIN_PRIVATE_H*/ diff --git a/test/include/liblvgl/others/imgfont/lv_imgfont.h b/test/include/liblvgl/others/imgfont/lv_imgfont.h new file mode 100644 index 00000000..68c317a6 --- /dev/null +++ b/test/include/liblvgl/others/imgfont/lv_imgfont.h @@ -0,0 +1,63 @@ +/** + * @file lv_imgfont.h + * + */ + +#ifndef LV_IMGFONT_H +#define LV_IMGFONT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../font/lv_font.h" + +#if LV_USE_IMGFONT + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/* gets the image path name of this character */ +typedef const void * (*lv_imgfont_get_path_cb_t)(const lv_font_t * font, + uint32_t unicode, uint32_t unicode_next, + int32_t * offset_y, void * user_data); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Creates a image font with info parameter specified. + * @param height font size + * @param path_cb a function to get the image path name of character. + * @param user_data pointer to user data + * @return pointer to the new imgfont or NULL if create error. + */ +lv_font_t * lv_imgfont_create(uint16_t height, lv_imgfont_get_path_cb_t path_cb, void * user_data); + +/** + * Destroy a image font that has been created. + * @param font pointer to image font handle. + */ +void lv_imgfont_destroy(lv_font_t * font); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_IMGFONT*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_IMGFONT_H */ diff --git a/test/include/liblvgl/others/monkey/lv_monkey.h b/test/include/liblvgl/others/monkey/lv_monkey.h new file mode 100644 index 00000000..97fc6e37 --- /dev/null +++ b/test/include/liblvgl/others/monkey/lv_monkey.h @@ -0,0 +1,117 @@ +/** + * @file lv_monkey.h + * + */ +#ifndef LV_MONKEY_H +#define LV_MONKEY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_MONKEY != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_monkey_t lv_monkey_t; + +struct _lv_monkey_config_t { + /**< Input device type*/ + lv_indev_type_t type; + + /**< Monkey execution period*/ + struct { + //! @cond Doxygen_Suppress + uint32_t min; + uint32_t max; + //! @endcond + } period_range; + + /**< The range of input value*/ + struct { + int32_t min; + int32_t max; + } input_range; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a monkey config with default values + * @param config pointer to 'lv_monkey_config_t' variable to initialize + */ +void lv_monkey_config_init(lv_monkey_config_t * config); + +/** + * Create monkey for test + * @param config pointer to 'lv_monkey_config_t' variable + * @return pointer to the created monkey + */ +lv_monkey_t * lv_monkey_create(const lv_monkey_config_t * config); + +/** + * Get monkey input device + * @param monkey pointer to a monkey + * @return pointer to the input device + */ +lv_indev_t * lv_monkey_get_indev(lv_monkey_t * monkey); + +/** + * Enable monkey + * @param monkey pointer to a monkey + * @param en set to true to enable + */ +void lv_monkey_set_enable(lv_monkey_t * monkey, bool en); + +/** + * Get whether monkey is enabled + * @param monkey pointer to a monkey + * @return return true if monkey enabled + */ +bool lv_monkey_get_enable(lv_monkey_t * monkey); + +/** + * Set the user_data field of the monkey + * @param monkey pointer to a monkey + * @param user_data pointer to the new user_data. + */ +void lv_monkey_set_user_data(lv_monkey_t * monkey, void * user_data); + +/** + * Get the user_data field of the monkey + * @param monkey pointer to a monkey + * @return the pointer to the user_data of the monkey + */ +void * lv_monkey_get_user_data(lv_monkey_t * monkey); + +/** + * Delete monkey + * @param monkey pointer to monkey + */ +void lv_monkey_delete(lv_monkey_t * monkey); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_MONKEY*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MONKEY_H*/ diff --git a/test/include/liblvgl/others/monkey/lv_monkey_private.h b/test/include/liblvgl/others/monkey/lv_monkey_private.h new file mode 100644 index 00000000..a08ea073 --- /dev/null +++ b/test/include/liblvgl/others/monkey/lv_monkey_private.h @@ -0,0 +1,43 @@ +/** + * @file lv_monkey_private.h + * + */ + +#ifndef LV_MONKEY_PRIVATE_H +#define LV_MONKEY_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_monkey.h" + +#if LV_USE_MONKEY != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_MONKEY != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MONKEY_PRIVATE_H*/ diff --git a/test/include/liblvgl/others/observer/lv_observer.h b/test/include/liblvgl/others/observer/lv_observer.h new file mode 100644 index 00000000..cec77fee --- /dev/null +++ b/test/include/liblvgl/others/observer/lv_observer.h @@ -0,0 +1,406 @@ +/** + * @file lv_observer.h + * + */ + +#ifndef LV_OBSERVER_H +#define LV_OBSERVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj.h" +#if LV_USE_OBSERVER + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Values for lv_submect_t's `type` field. + */ +typedef enum { + LV_SUBJECT_TYPE_INVALID = 0, /**< indicates subject not initialized yet*/ + LV_SUBJECT_TYPE_NONE = 1, /**< a null value like None or NILt*/ + LV_SUBJECT_TYPE_INT = 2, /**< an int32_t*/ + LV_SUBJECT_TYPE_POINTER = 3, /**< a void pointer*/ + LV_SUBJECT_TYPE_COLOR = 4, /**< an lv_color_t*/ + LV_SUBJECT_TYPE_GROUP = 5, /**< an array of subjects*/ + LV_SUBJECT_TYPE_STRING = 6, /**< a char pointer*/ +} lv_subject_type_t; + +/** + * A common type to handle all the various observable types in the same way + */ +typedef union { + int32_t num; /**< Integer number (opacity, enums, booleans or "normal" numbers)*/ + const void * pointer; /**< Constant pointer (string buffer, format string, font, cone text, etc)*/ + lv_color_t color; /**< Color */ +} lv_subject_value_t; + +/** + * The subject (an observable value) + */ +typedef struct { + lv_ll_t subs_ll; /**< Subscribers*/ + uint32_t type : 4; + uint32_t size : 28; /**< Might be used to store a size related to `type`*/ + lv_subject_value_t value; /**< Actual value*/ + lv_subject_value_t prev_value; /**< Previous value*/ + uint32_t notify_restart_query : 1; /**< If an observer deleted start notifying from the beginning. */ + void * user_data; /**< Additional parameter, can be used freely by the user*/ +} lv_subject_t; + +/** + * Callback called when the observed value changes + * @param observer pointer to the observer of the callback + * @param subject pointer to the subject of the observer + */ +typedef void (*lv_observer_cb_t)(lv_observer_t * observer, lv_subject_t * subject); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize an integer type subject + * @param subject pointer to the subject + * @param value initial value + */ +void lv_subject_init_int(lv_subject_t * subject, int32_t value); + +/** + * Set the value of an integer subject. It will notify all the observers as well. + * @param subject pointer to the subject + * @param value the new value + */ +void lv_subject_set_int(lv_subject_t * subject, int32_t value); + +/** + * Get the current value of an integer subject + * @param subject pointer to the subject + * @return the current value + */ +int32_t lv_subject_get_int(lv_subject_t * subject); + +/** + * Get the previous value of an integer subject + * @param subject pointer to the subject + * @return the current value + */ +int32_t lv_subject_get_previous_int(lv_subject_t * subject); + +/** + * Initialize a string type subject + * @param subject pointer to the subject + * @param buf pointer to a buffer to store the string + * @param prev_buf pointer to a buffer to store the previous string, can be NULL if not used + * @param size size of the buffer + * @param value initial value as a string, e.g. "hello" + * @note the string subject stores the whole string, not only a pointer + */ +void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, size_t size, const char * value); + +/** + * Copy a string to a subject. It will notify all the observers as well. + * @param subject pointer to the subject + * @param buf the new string + */ +void lv_subject_copy_string(lv_subject_t * subject, const char * buf); + +/** + * Get the current value of an string subject + * @param subject pointer to the subject + * @return pointer to the buffer containing the current value + */ +const char * lv_subject_get_string(lv_subject_t * subject); + +/** + * Get the previous value of an string subject + * @param subject pointer to the subject + * @return pointer to the buffer containing the current value + * @note NULL will be returned if NULL was passed in `lv_subject_init_string()` + * as `prev_buf` + */ +const char * lv_subject_get_previous_string(lv_subject_t * subject); + +/** + * Initialize an pointer type subject + * @param subject pointer to the subject + * @param value initial value + */ +void lv_subject_init_pointer(lv_subject_t * subject, void * value); + +/** + * Set the value of a pointer subject. It will notify all the observers as well. + * @param subject pointer to the subject + * @param ptr new value + */ +void lv_subject_set_pointer(lv_subject_t * subject, void * ptr); + +/** + * Get the current value of a pointer subject + * @param subject pointer to the subject + * @return current value + */ +const void * lv_subject_get_pointer(lv_subject_t * subject); + +/** + * Get the previous value of a pointer subject + * @param subject pointer to the subject + * @return current value + */ +const void * lv_subject_get_previous_pointer(lv_subject_t * subject); + +/** + * Initialize an color type subject + * @param subject pointer to the subject + * @param color initial value + */ +void lv_subject_init_color(lv_subject_t * subject, lv_color_t color); + +/** + * Set the value of a color subject. It will notify all the observers as well. + * @param subject pointer to the subject + * @param color new value + */ +void lv_subject_set_color(lv_subject_t * subject, lv_color_t color); + +/** + * Get the current value of a color subject + * @param subject pointer to the subject + * @return current value + */ +lv_color_t lv_subject_get_color(lv_subject_t * subject); + +/** + * Get the previous value of a color subject + * @param subject pointer to the subject + * @return current value + */ +lv_color_t lv_subject_get_previous_color(lv_subject_t * subject); + +/** + * Initialize a subject group + * @param subject pointer to the subject + * @param list list of other subject addresses, any of these changes `subject` will be notified + * @param list_len number of elements in `list` + */ +void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32_t list_len); + +/** + * Remove all the observers from a subject and free all allocated memories in it + * @param subject pointer to the subject + * @note objects added with `lv_subject_add_observer_obj` should be already deleted or + * removed manually. + */ +void lv_subject_deinit(lv_subject_t * subject); + +/** + * Get an element from the subject group's list + * @param subject pointer to the subject + * @param index index of the element to get + * @return pointer a subject from the list, or NULL if the index is out of bounds + */ +lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t index); + +/** + * Add an observer to a subject. When the subject changes `observer_cb` will be called. + * @param subject pointer to the subject + * @param observer_cb callback to call + * @param user_data optional user data + * @return pointer to the created observer + */ +lv_observer_t * lv_subject_add_observer(lv_subject_t * subject, lv_observer_cb_t observer_cb, void * user_data); + +/** + * Add an observer to a subject for an object. + * When the object is deleted, it will be removed from the subject automatically. + * @param subject pointer to the subject + * @param observer_cb callback to call + * @param obj pointer to an object + * @param user_data optional user data + * @return pointer to the created observer + */ +lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_cb_t observer_cb, lv_obj_t * obj, + void * user_data); + +/** + * Add an observer to a subject and also save a target. + * @param subject pointer to the subject + * @param observer_cb callback to call + * @param target pointer to any data + * @param user_data optional user data + * @return pointer to the created observer + */ +lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_observer_cb_t observer_cb, + void * target, void * user_data); + +/** + * Remove an observer from its subject + * @param observer pointer to an observer + */ +void lv_observer_remove(lv_observer_t * observer); + +/** + * Remove the observers of an object from a subject or all subjects + * @param obj the object whose observers should be removed + * @param subject the subject to remove the object from, or `NULL` to remove from all subjects + * @note This function can be used e.g. when an object's subject(s) needs to be replaced by other subject(s) + */ +void lv_obj_remove_from_subject(lv_obj_t * obj, lv_subject_t * subject); + +/** + * Get the target of an observer + * @param observer pointer to an observer + * @return pointer to the saved target + */ +void * lv_observer_get_target(lv_observer_t * observer); + +/** + * Get the target object of the observer. + * It's the same as `lv_observer_get_target` and added only + * for semantic reasons + * @param observer pointer to an observer + * @return pointer to the saved object target + */ +lv_obj_t * lv_observer_get_target_obj(lv_observer_t * observer); + +/** + * Get the user data of the observer. + * @param observer pointer to an observer + * @return void pointer to the saved user data +*/ +void * lv_observer_get_user_data(const lv_observer_t * observer); + +/** + * Notify all observers of subject + * @param subject pointer to a subject + */ +void lv_subject_notify(lv_subject_t * subject); + +/** + * Set an object flag if an integer subject's value is equal to a reference value, clear the flag otherwise + * @param obj pointer to an object + * @param subject pointer to a subject + * @param flag flag to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) + * @param ref_value reference value to compare the subject's value with + * @return pointer to the created observer + */ +lv_observer_t * lv_obj_bind_flag_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value); + +/** + * Set an object flag if an integer subject's value is not equal to a reference value, clear the flag otherwise + * @param obj pointer to an object + * @param subject pointer to a subject + * @param flag flag to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) + * @param ref_value reference value to compare the subject's value with + * @return pointer to the created observer + */ +lv_observer_t * lv_obj_bind_flag_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, + int32_t ref_value); + +/** + * Set an object state if an integer subject's value is equal to a reference value, clear the flag otherwise + * @param obj pointer to an object + * @param subject pointer to a subject + * @param state state to set or clear (e.g. `LV_STATE_CHECKED`) + * @param ref_value reference value to compare the subject's value with + * @return pointer to the created observer + */ +lv_observer_t * lv_obj_bind_state_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value); + +/** + * Set an object state if an integer subject's value is not equal to a reference value, clear the flag otherwise + * @param obj pointer to an object + * @param subject pointer to a subject + * @param state state to set or clear (e.g. `LV_STATE_CHECKED`) + * @param ref_value reference value to compare the subject's value with + * @return pointer to the created observer + */ +lv_observer_t * lv_obj_bind_state_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, + int32_t ref_value); + +/** + * Set an integer subject to 1 when an object is checked and set it 0 when unchecked. + * @param obj pointer to an object + * @param subject pointer to a subject + * @return pointer to the created observer + * @note Ensure the object's `LV_OBJ_FLAG_CHECKABLE` flag is set + */ +lv_observer_t * lv_obj_bind_checked(lv_obj_t * obj, lv_subject_t * subject); + +#if LV_USE_LABEL +/** + * Bind an integer, string, or pointer subject to a label. + * @param obj pointer to a label + * @param subject pointer to a subject + * @param fmt optional format string with 1 format specifier (e.g. "%d °C") + * or NULL to bind the value directly. + * @return pointer to the created observer + * @note fmt == NULL can be used only with string and pointer subjects. + * @note if the subject is a pointer must point to a `\0` terminated string. + */ +lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const char * fmt); +#endif + +#if LV_USE_ARC +/** + * Bind an integer subject to an arc's value + * @param obj pointer to an arc + * @param subject pointer to a subject + * @return pointer to the created observer + */ +lv_observer_t * lv_arc_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + +#if LV_USE_SLIDER +/** + * Bind an integer subject to a slider's value + * @param obj pointer to a slider + * @param subject pointer to a subject + * @return pointer to the created observer + */ +lv_observer_t * lv_slider_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + +#if LV_USE_ROLLER +/** + * Bind an integer subject to a roller's value + * @param obj pointer to a roller + * @param subject pointer to a subject + * @return pointer to the created observer + */ +lv_observer_t * lv_roller_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + +#if LV_USE_DROPDOWN +/** + * Bind an integer subject to a dropdown's value + * @param obj pointer to a drop down + * @param subject pointer to a subject + * @return pointer to the created observer + */ +lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OBSERVER*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBSERVER_H*/ diff --git a/test/include/liblvgl/others/observer/lv_observer_private.h b/test/include/liblvgl/others/observer/lv_observer_private.h new file mode 100644 index 00000000..40a22dac --- /dev/null +++ b/test/include/liblvgl/others/observer/lv_observer_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_observer_private.h + * + */ + +#ifndef LV_OBSERVER_PRIVATE_H +#define LV_OBSERVER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_observer.h" + +#if LV_USE_OBSERVER + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * The observer object: a descriptor returned when subscribing LVGL widgets to subjects + */ +struct _lv_observer_t { + lv_subject_t * subject; /**< The observed value */ + lv_observer_cb_t cb; /**< Callback that should be called when the value changes*/ + void * target; /**< A target for the observer, e.g. a widget or style*/ + void * user_data; /**< Additional parameter supplied when subscribing*/ + uint32_t auto_free_user_data : 1; /**< Automatically free user data when the observer is removed */ + uint32_t notified : 1; /**< Mark if this observer was already notified*/ + uint32_t for_obj : 1; /**< `target` is an `lv_obj_t *`*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_OBSERVER */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBSERVER_PRIVATE_H*/ diff --git a/test/include/liblvgl/others/snapshot/lv_snapshot.h b/test/include/liblvgl/others/snapshot/lv_snapshot.h new file mode 100644 index 00000000..90de106c --- /dev/null +++ b/test/include/liblvgl/others/snapshot/lv_snapshot.h @@ -0,0 +1,101 @@ +/** + * @file lv_snapshot.h + * + */ + +#ifndef LV_SNAPSHOT_H +#define LV_SNAPSHOT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_SNAPSHOT + +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Take snapshot for object with its children, create the draw buffer as needed. + * @param obj the object to generate snapshot. + * @param cf color format for generated image. + * @return a pointer to an draw buffer containing snapshot image, or NULL if failed. + */ +lv_draw_buf_t * lv_snapshot_take(lv_obj_t * obj, lv_color_format_t cf); + +/** + * Create a draw buffer to store the snapshot image for object. + * @param obj the object to generate snapshot. + * @param cf color format for generated image. + * @return a pointer to an draw buffer ready for taking snapshot, or NULL if failed. + */ +lv_draw_buf_t * lv_snapshot_create_draw_buf(lv_obj_t * obj, lv_color_format_t cf); + +/** + * Reshape the draw buffer to prepare for taking snapshot for obj. + * This is usually used to check if the existing draw buffer is enough for + * obj snapshot. If return LV_RESULT_INVALID, you should create a new one. + * @param draw_buf the draw buffer to reshape. + * @param obj the object to generate snapshot. + */ +lv_result_t lv_snapshot_reshape_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf); + +/** + * Take snapshot for object with its children, save image info to provided buffer. + * @param obj the object to generate snapshot. + * @param cf color format for new snapshot image. + * It could differ with cf of `draw_buf` as long as the new cf will fit in. + * @param draw_buf the draw buffer to store the image result. It's reshaped automatically. + * @return LV_RESULT_OK on success, LV_RESULT_INVALID on error. + */ +lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, lv_draw_buf_t * draw_buf); + +/** + * @deprecated Use `lv_draw_buf_destroy` instead. + * + * Free the snapshot image returned by @ref lv_snapshot_take + * @param dsc the image descriptor generated by lv_snapshot_take. + */ +void lv_snapshot_free(lv_image_dsc_t * dsc); + +/** + * Take snapshot for object with its children, save image info to provided buffer. + * @param obj the object to generate snapshot. + * @param cf color format for generated image. + * @param dsc image descriptor to store the image result. + * @param buf the buffer to store image data. It must meet align requirement. + * @param buf_size provided buffer size in bytes. + * @return LV_RESULT_OK on success, LV_RESULT_INVALID on error. + * @deprecated Use lv_snapshot_take_to_draw_buf instead. + */ +lv_result_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_color_format_t cf, lv_image_dsc_t * dsc, + void * buf, + uint32_t buf_size); + +/********************** + * MACROS + **********************/ +#endif /*LV_USE_SNAPSHOT*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/test/include/liblvgl/others/sysmon/lv_sysmon.h b/test/include/liblvgl/others/sysmon/lv_sysmon.h new file mode 100644 index 00000000..0859c064 --- /dev/null +++ b/test/include/liblvgl/others/sysmon/lv_sysmon.h @@ -0,0 +1,91 @@ +/** + * @file lv_sysmon.h + * + */ + +#ifndef LV_SYSMON_H +#define LV_SYSMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../misc/lv_timer.h" +#include "../../others/observer/lv_observer.h" + +#if LV_USE_SYSMON + +#if LV_USE_LABEL == 0 +#error "lv_sysmon: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) " +#endif + +#if LV_USE_OBSERVER == 0 +#error "lv_observer: lv_observer is required. Enable it in lv_conf.h (LV_USE_OBSERVER 1) " +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a new system monitor label + * @param disp create the sys. mon. on this display's system layer + * @return the create label + */ +lv_obj_t * lv_sysmon_create(lv_display_t * disp); + +#if LV_USE_PERF_MONITOR + +/** + * Show system performance monitor: CPU usage and FPS count + * @param disp target display, NULL: use the default displays + */ +void lv_sysmon_show_performance(lv_display_t * disp); + +/** + * Hide system performance monitor + * @param disp target display, NULL: use the default + */ +void lv_sysmon_hide_performance(lv_display_t * disp); + +#endif /*LV_USE_PERF_MONITOR*/ + +#if LV_USE_MEM_MONITOR + +/** + * Show system memory monitor: used memory and the memory fragmentation + * @param disp target display, NULL: use the default displays + */ +void lv_sysmon_show_memory(lv_display_t * disp); + +/** + * Hide system memory monitor + * @param disp target display, NULL: use the default displays + */ +void lv_sysmon_hide_memory(lv_display_t * disp); + +#endif /*LV_USE_MEM_MONITOR*/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SYSMON*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SYSMON_H*/ diff --git a/test/include/liblvgl/others/sysmon/lv_sysmon_private.h b/test/include/liblvgl/others/sysmon/lv_sysmon_private.h new file mode 100644 index 00000000..b4fa3877 --- /dev/null +++ b/test/include/liblvgl/others/sysmon/lv_sysmon_private.h @@ -0,0 +1,91 @@ +/** + * @file lv_sysmon_private.h + * + */ + +#ifndef LV_SYSMON_PRIVATE_H +#define LV_SYSMON_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_sysmon.h" + +#if LV_USE_SYSMON + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_sysmon_backend_data_t { + lv_subject_t subject; + lv_timer_t * timer; +}; + +#if LV_USE_PERF_MONITOR +struct _lv_sysmon_perf_info_t { + struct { + bool inited; + uint32_t refr_start; + uint32_t refr_interval_sum; + uint32_t refr_elaps_sum; + uint32_t refr_cnt; + uint32_t render_start; + uint32_t render_elaps_sum; /*Contains the flush time too*/ + uint32_t render_cnt; + uint32_t flush_in_render_start; + uint32_t flush_in_render_elaps_sum; + uint32_t flush_not_in_render_start; + uint32_t flush_not_in_render_elaps_sum; + uint32_t last_report_timestamp; + uint32_t render_in_progress : 1; + } measured; + + struct { + uint32_t fps; + uint32_t cpu; + uint32_t refr_avg_time; + uint32_t render_avg_time; /**< Pure rendering time without flush time*/ + uint32_t flush_avg_time; /**< Pure flushing time without rendering time*/ + uint32_t cpu_avg_total; + uint32_t fps_avg_total; + uint32_t run_cnt; + } calculated; + +}; +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize built-in system monitor, such as performance and memory monitor. + */ +void lv_sysmon_builtin_init(void); + +/** + * DeInitialize built-in system monitor, such as performance and memory monitor. + */ +void lv_sysmon_builtin_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SYSMON */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SYSMON_PRIVATE_H*/ diff --git a/test/include/liblvgl/others/vg_lite_tvg/vg_lite.h b/test/include/liblvgl/others/vg_lite_tvg/vg_lite.h new file mode 100644 index 00000000..abbd6e86 --- /dev/null +++ b/test/include/liblvgl/others/vg_lite_tvg/vg_lite.h @@ -0,0 +1,1387 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* 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, sub license, 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 (including the +* next paragraph) 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 NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS 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 _vg_lite_h_ +#define _vg_lite_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * causes MSVC error C1189. + * Not needed because "The __inline keyword is equivalent to inline." + * See: https://learn.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-170 +*/ +/* +#if defined(_MSC_VER) +#define inline __inline +#endif +*/ + +#include +#include + + +/* VGLite API Constants *******************************************************************************************************************/ + +#define VGLITE_HEADER_VERSION 7 + +#ifndef VGLITE_VERSION_3_0 +#define VGLITE_VERSION_3_0 1 + +#define VGLITE_MAKE_VERSION(major, minor, patch) (((major) << 16) | ((minor) << 8) | (patch)) +#define VGLITE_VERSION_MAJOR(version) (((uint32_t)(version) >> 16) & 0xff) +#define VGLITE_VERSION_MINOR(version) (((uint32_t)(version) >> 8) & 0xff) +#define VGLITE_VERSION_PATCH(version) ((uint32_t)(version) & 0xff) + +#define VGLITE_API_VERSION_3_0 VGLITE_MAKE_VERSION(3, 0, 0) + +#define VGLITE_RELEASE_VERSION VGLITE_MAKE_VERSION(4,0,47) + +#define VGL_FALSE 0 +#define VGL_TRUE 1 + +/* Path command (op code). */ +#define VLC_OP_END 0x00 +#define VLC_OP_CLOSE 0x01 +#define VLC_OP_MOVE 0x02 +#define VLC_OP_MOVE_REL 0x03 +#define VLC_OP_LINE 0x04 +#define VLC_OP_LINE_REL 0x05 +#define VLC_OP_QUAD 0x06 +#define VLC_OP_QUAD_REL 0x07 +#define VLC_OP_CUBIC 0x08 +#define VLC_OP_CUBIC_REL 0x09 +#define VLC_OP_BREAK 0x0A +#define VLC_OP_HLINE 0x0B +#define VLC_OP_HLINE_REL 0x0C +#define VLC_OP_VLINE 0x0D +#define VLC_OP_VLINE_REL 0x0E +#define VLC_OP_SQUAD 0x0F +#define VLC_OP_SQUAD_REL 0x10 +#define VLC_OP_SCUBIC 0x11 +#define VLC_OP_SCUBIC_REL 0x12 +#define VLC_OP_SCCWARC 0x13 +#define VLC_OP_SCCWARC_REL 0x14 +#define VLC_OP_SCWARC 0x15 +#define VLC_OP_SCWARC_REL 0x16 +#define VLC_OP_LCCWARC 0x17 +#define VLC_OP_LCCWARC_REL 0x18 +#define VLC_OP_LCWARC 0x19 +#define VLC_OP_LCWARC_REL 0x1A + +/* Macros for path manipulating: See path definitions. */ +#define VLM_PATH_ENABLE_UPLOAD(path) (path).uploaded.property |= 1 +#define VLM_PATH_DISABLE_UPLOAD(path) (path).uploaded.property &= (~1) +#define VLM_PATH_GET_UPLOAD_BIT(path) ((path).uploaded.property & 1) + +/* Gradient constants. */ +#define VLC_MAX_COLOR_RAMP_STOPS 256 /*! The max number of radial gradient stops. */ +#define VLC_MAX_GRADIENT_STOPS 16 /*! The max number of gradient stops. */ +#define VLC_GRADIENT_BUFFER_WIDTH 1024 /*! The internal gradient buffer width.*/ + + +/* API name defines for backward compatibility to VGLite 2.0 APIs */ +#define vg_lite_buffer_upload vg_lite_upload_buffer +#define vg_lite_path_append vg_lite_append_path +#define vg_lite_path_calc_length vg_lite_get_path_length +#define vg_lite_set_ts_buffer vg_lite_set_tess_buffer +#define vg_lite_set_draw_path_type vg_lite_set_path_type +#define vg_lite_create_mask_layer vg_lite_create_masklayer +#define vg_lite_fill_mask_layer vg_lite_fill_masklayer +#define vg_lite_blend_mask_layer vg_lite_blend_masklayer +#define vg_lite_generate_mask_layer_by_path vg_lite_render_masklayer +#define vg_lite_set_mask_layer vg_lite_set_masklayer +#define vg_lite_destroy_mask_layer vg_lite_destroy_masklayer +#define vg_lite_enable_mask vg_lite_enable_masklayer +#define vg_lite_enable_color_transformation vg_lite_enable_color_transform +#define vg_lite_set_color_transformation vg_lite_set_color_transform +#define vg_lite_set_image_global_alpha vg_lite_source_global_alpha +#define vg_lite_set_dest_global_alpha vg_lite_dest_global_alpha +#define vg_lite_clear_rad_grad vg_lite_clear_radial_grad +#define vg_lite_update_rad_grad vg_lite_update_radial_grad +#define vg_lite_get_rad_grad_matrix vg_lite_get_radial_grad_matrix +#define vg_lite_set_rad_grad vg_lite_set_radial_grad +#define vg_lite_draw_linear_gradient vg_lite_draw_linear_grad +#define vg_lite_draw_radial_gradient vg_lite_draw_radial_grad +#define vg_lite_draw_gradient vg_lite_draw_grad +#define vg_lite_mem_avail vg_lite_get_mem_size +#define vg_lite_set_update_stroke vg_lite_update_stroke + +#define vg_lite_buffer_image_mode_t vg_lite_image_mode_t +#define vg_lite_draw_path_type_t vg_lite_path_type_t +#define vg_lite_linear_gradient_ext_t vg_lite_ext_linear_gradient_t +#define vg_lite_buffer_transparency_mode_t vg_lite_transparency_t + + +/* VGLite API Types ***********************************************************************************************************************/ + +typedef unsigned char vg_lite_uint8_t; +typedef char vg_lite_int8_t; +typedef short vg_lite_int16_t; +typedef unsigned short vg_lite_uint16_t; +typedef int vg_lite_int32_t; +typedef unsigned int vg_lite_uint32_t; +typedef unsigned long long vg_lite_uint64_t; +typedef float vg_lite_float_t; +typedef double vg_lite_double_t; +typedef char vg_lite_char; +typedef char* vg_lite_string; +typedef void* vg_lite_pointer; +typedef void vg_lite_void; +typedef unsigned int vg_lite_color_t; + + +/* VGLite API Enumerations ****************************************************************************************************************/ + +#ifndef VG_LITE_ERROR +#define VG_LITE_ERROR 1 + + /* Error codes that the vg_lite functions can return. */ + typedef enum vg_lite_error + { + VG_LITE_SUCCESS = 0, /*! Success. */ + VG_LITE_INVALID_ARGUMENT, /*! An invalid argument was specified. */ + VG_LITE_OUT_OF_MEMORY, /*! Out of memory. */ + VG_LITE_NO_CONTEXT, /*! No context or an unintialized context specified. */ + VG_LITE_TIMEOUT, /*! A timeout has occurred during a wait. */ + VG_LITE_OUT_OF_RESOURCES, /*! Out of system resources. */ + VG_LITE_GENERIC_IO, /*! Cannot communicate with the kernel driver. */ + VG_LITE_NOT_SUPPORT, /*! Function call not supported. */ + VG_LITE_ALREADY_EXISTS, /*! Object already exists */ + VG_LITE_NOT_ALIGNED, /*! Data alignment error */ + VG_LITE_FLEXA_TIME_OUT, /*! VG timeout requesting for segment buffer */ + VG_LITE_FLEXA_HANDSHAKE_FAIL, /*! VG and SBI synchronizer handshake failed */ + } vg_lite_error_t; +#endif + + /* Chip features bit */ + typedef enum vg_lite_feature + { + gcFEATURE_BIT_VG_IM_INDEX_FORMAT, + gcFEATURE_BIT_VG_SCISSOR, + gcFEATURE_BIT_VG_BORDER_CULLING, + gcFEATURE_BIT_VG_RGBA2_FORMAT, + gcFEATURE_BIT_VG_QUALITY_8X, + gcFEATURE_BIT_VG_IM_FASTCLAER, + gcFEATURE_BIT_VG_RADIAL_GRADIENT, + gcFEATURE_BIT_VG_GLOBAL_ALPHA, + gcFEATURE_BIT_VG_RGBA8_ETC2_EAC, + gcFEATURE_BIT_VG_COLOR_KEY, + gcFEATURE_BIT_VG_DOUBLE_IMAGE, + gcFEATURE_BIT_VG_YUV_OUTPUT, + gcFEATURE_BIT_VG_FLEXA, + gcFEATURE_BIT_VG_24BIT, + gcFEATURE_BIT_VG_DITHER, + gcFEATURE_BIT_VG_USE_DST, + gcFEATURE_BIT_VG_PE_CLEAR, + gcFEATURE_BIT_VG_IM_INPUT, + gcFEATURE_BIT_VG_DEC_COMPRESS, + gcFEATURE_BIT_VG_LINEAR_GRADIENT_EXT, + gcFEATURE_BIT_VG_MASK, + gcFEATURE_BIT_VG_MIRROR, + gcFEATURE_BIT_VG_GAMMA, + gcFEATURE_BIT_VG_NEW_BLEND_MODE, + gcFEATURE_BIT_VG_STENCIL, + gcFEATURE_BIT_VG_SRC_PREMULTIPLIED, /*! Valid only if gcFEATURE_BIT_VG_HW_PREMULTIPLY is 0 */ + gcFEATURE_BIT_VG_HW_PREMULTIPLY, /*! HW multiplier can accept either premultiplied or not */ + gcFEATURE_BIT_VG_COLOR_TRANSFORMATION, + gcFEATURE_BIT_VG_LVGL_SUPPORT, + gcFEATURE_BIT_VG_INDEX_ENDIAN, + gcFEATURE_BIT_VG_24BIT_PLANAR, + gcFEATURE_BIT_VG_PIXEL_MATRIX, + gcFEATURE_BIT_VG_NEW_IMAGE_INDEX, + gcFEATURE_BIT_VG_PARALLEL_PATHS, + gcFEATURE_BIT_VG_STRIPE_MODE, + gcFEATURE_BIT_VG_IM_DEC_INPUT, + gcFEATURE_BIT_VG_GAUSSIAN_BLUR, + gcFEATURE_BIT_VG_RECTANGLE_TILED_OUT, + gcFEATURE_BIT_VG_TESSELLATION_TILED_OUT, + gcFEATURE_BIT_VG_IM_REPEAT_REFLECT, + gcFEATURE_BIT_VG_YUY2_INPUT, + gcFEATURE_BIT_VG_YUV_INPUT, + gcFEATURE_BIT_VG_YUV_TILED_INPUT, + gcFEATURE_BIT_VG_AYUV_INPUT, + gcFEATURE_BIT_VG_16PIXELS_ALIGN, + gcFEATURE_BIT_VG_DEC_COMPRESS_2_0, + gcFEATURE_COUNT + } vg_lite_feature_t; + + /* Rendering quality enums. */ + typedef enum vg_lite_quality + { + VG_LITE_HIGH, /*! High quality 16x anti-aliasing path. */ + VG_LITE_UPPER, /*! Upper quality 8x anti-aliasing path. */ + VG_LITE_MEDIUM, /*! Medium quality 4x anti-aliasing path. */ + VG_LITE_LOW, /*! Low quality path without any anti-aliasing. */ + } vg_lite_quality_t; + + /* Format of path coordinates. */ + typedef enum vg_lite_format + { + VG_LITE_S8, /*! Signed 8-bit coordinates. */ + VG_LITE_S16, /*! Signed 16-bit coordinates. */ + VG_LITE_S32, /*! Signed 32-bit coordinates. */ + VG_LITE_FP32, /*! 32-bit floating point coordinates. */ + } vg_lite_format_t; + + /* Format of pixel buffer. */ + typedef enum vg_lite_buffer_format + { + /* OpenVG VGImageFormat enums: + * Note: The bits for each color channel are stored within a machine word + * from MSB to LSB in the order indicated by the pixel format name. + * This is opposite of VG_LITE_* formats (from LSB to MSB). + */ + + /* RGB{A,X} channel ordering */ + VG_sRGBX_8888 = 0, + VG_sRGBA_8888 = 1, + VG_sRGBA_8888_PRE = 2, + VG_sRGB_565 = 3, + VG_sRGBA_5551 = 4, + VG_sRGBA_4444 = 5, + VG_sL_8 = 6, + VG_lRGBX_8888 = 7, + VG_lRGBA_8888 = 8, + VG_lRGBA_8888_PRE = 9, + VG_lL_8 = 10, + VG_A_8 = 11, + VG_BW_1 = 12, + VG_A_1 = 13, + VG_A_4 = 14, + + VG_sRGBX_8888_PRE = 15, + VG_sRGB_565_PRE = 16, + VG_sRGBA_5551_PRE = 17, + VG_sRGBA_4444_PRE = 18, + VG_lRGBX_8888_PRE = 19, + VG_lRGB_565 = 20, + VG_lRGB_565_PRE = 21, + VG_lRGBA_5551 = 22, + VG_lRGBA_5551_PRE = 23, + VG_lRGBA_4444 = 24, + VG_lRGBA_4444_PRE = 25, + + /* {A,X}RGB channel ordering */ + VG_sXRGB_8888 = 0 | (1 << 6), + VG_sARGB_8888 = 1 | (1 << 6), + VG_sARGB_8888_PRE = 2 | (1 << 6), + VG_sARGB_1555 = 4 | (1 << 6), + VG_sARGB_4444 = 5 | (1 << 6), + VG_lXRGB_8888 = 7 | (1 << 6), + VG_lARGB_8888 = 8 | (1 << 6), + VG_lARGB_8888_PRE = 9 | (1 << 6), + + /* BGR{A,X} channel ordering */ + VG_sBGRX_8888 = 0 | (1 << 7), + VG_sBGRA_8888 = 1 | (1 << 7), + VG_sBGRA_8888_PRE = 2 | (1 << 7), + VG_sBGR_565 = 3 | (1 << 7), + VG_sBGRA_5551 = 4 | (1 << 7), + VG_sBGRA_4444 = 5 | (1 << 7), + VG_lBGRX_8888 = 7 | (1 << 7), + VG_lBGRA_8888 = 8 | (1 << 7), + VG_lBGRA_8888_PRE = 9 | (1 << 7), + + /* {A,X}BGR channel ordering */ + VG_sXBGR_8888 = 0 | (1 << 6) | (1 << 7), + VG_sABGR_8888 = 1 | (1 << 6) | (1 << 7), + VG_sABGR_8888_PRE = 2 | (1 << 6) | (1 << 7), + VG_sABGR_1555 = 4 | (1 << 6) | (1 << 7), + VG_sABGR_4444 = 5 | (1 << 6) | (1 << 7), + VG_lXBGR_8888 = 7 | (1 << 6) | (1 << 7), + VG_lABGR_8888 = 8 | (1 << 6) | (1 << 7), + VG_lABGR_8888_PRE = 9 | (1 << 6) | (1 << 7), + + /* Original VGLite API image format enums: + * Note: The bits for each color channel are stored within a machine word + * from LSB to MSB in the order indicated by the pixel format name. + * This is opposite of OPENVG VG_* formats (from MSB to LSB). + */ + VG_LITE_RGBA8888 = 0 | (1 << 10), + VG_LITE_BGRA8888 = 1 | (1 << 10), + VG_LITE_RGBX8888 = 2 | (1 << 10), + VG_LITE_BGRX8888 = 3 | (1 << 10), + VG_LITE_RGB565 = 4 | (1 << 10), + VG_LITE_BGR565 = 5 | (1 << 10), + VG_LITE_RGBA4444 = 6 | (1 << 10), + VG_LITE_BGRA4444 = 7 | (1 << 10), + VG_LITE_BGRA5551 = 8 | (1 << 10), + VG_LITE_A4 = 9 | (1 << 10), + VG_LITE_A8 = 10 | (1 << 10), + VG_LITE_L8 = 11 | (1 << 10), + VG_LITE_YUYV = 12 | (1 << 10), + VG_LITE_YUY2 = 13 | (1 << 10), + VG_LITE_ANV12 = 14 | (1 << 10), + VG_LITE_AYUY2 = 15 | (1 << 10), + VG_LITE_NV12 = 16 | (1 << 10), + VG_LITE_YV12 = 17 | (1 << 10), + VG_LITE_YV24 = 18 | (1 << 10), + VG_LITE_YV16 = 19 | (1 << 10), + VG_LITE_NV16 = 20 | (1 << 10), + VG_LITE_YUY2_TILED = 21 | (1 << 10), + VG_LITE_NV12_TILED = 22 | (1 << 10), + VG_LITE_ANV12_TILED = 23 | (1 << 10), + VG_LITE_AYUY2_TILED = 24 | (1 << 10), + VG_LITE_RGBA2222 = 25 | (1 << 10), + VG_LITE_BGRA2222 = 26 | (1 << 10), + VG_LITE_ABGR2222 = 27 | (1 << 10), + VG_LITE_ARGB2222 = 28 | (1 << 10), + VG_LITE_ABGR4444 = 29 | (1 << 10), + VG_LITE_ARGB4444 = 30 | (1 << 10), + VG_LITE_ABGR8888 = 31 | (1 << 10), + VG_LITE_ARGB8888 = 32 | (1 << 10), + VG_LITE_ABGR1555 = 33 | (1 << 10), + VG_LITE_RGBA5551 = 34 | (1 << 10), + VG_LITE_ARGB1555 = 35 | (1 << 10), + VG_LITE_XBGR8888 = 36 | (1 << 10), + VG_LITE_XRGB8888 = 37 | (1 << 10), + VG_LITE_RGBA8888_ETC2_EAC = 38 | (1 << 10), + VG_LITE_RGB888 = 39 | (1 << 10), + VG_LITE_BGR888 = 40 | (1 << 10), + VG_LITE_ABGR8565 = 41 | (1 << 10), + VG_LITE_BGRA5658 = 42 | (1 << 10), + VG_LITE_ARGB8565 = 43 | (1 << 10), + VG_LITE_RGBA5658 = 44 | (1 << 10), + VG_LITE_ABGR8565_PLANAR = 45 | (1 << 10), + VG_LITE_BGRA5658_PLANAR = 46 | (1 << 10), + VG_LITE_ARGB8565_PLANAR = 47 | (1 << 10), + VG_LITE_RGBA5658_PLANAR = 48 | (1 << 10), + + VG_LITE_INDEX_1 = 0 | (1 << 11), /*! Indexed format. */ + VG_LITE_INDEX_2 = 1 | (1 << 11), + VG_LITE_INDEX_4 = 2 | (1 << 11), + VG_LITE_INDEX_8 = 3 | (1 << 11), + + } vg_lite_buffer_format_t; + + /* Swizzle of packed YUV format UV channels. */ + typedef enum vg_lite_swizzle + { + VG_LITE_SWIZZLE_UV, + VG_LITE_SWIZZLE_VU, + } vg_lite_swizzle_t; + + /* The YUV<->RGB conversion rule. */ + typedef enum vg_lite_yuv2rgb + { + VG_LITE_YUV601, + VG_LITE_YUV709, + } vg_lite_yuv2rgb_t; + + /* The pixel layout in a buffer. */ + typedef enum vg_lite_buffer_layout + { + VG_LITE_LINEAR, + VG_LITE_TILED, + } vg_lite_buffer_layout_t; + + /* The image (buffer) rendering mode. Match OpenVG enum VGImageMode */ + typedef enum vg_lite_image_mode + { + /* For enum value backward compatibility */ + VG_LITE_ZERO = 0, + VG_LITE_NORMAL_IMAGE_MODE = 0x1F00, + VG_LITE_MULTIPLY_IMAGE_MODE = 0x1F01, + VG_LITE_STENCIL_MODE = 0x1F02, + VG_LITE_NONE_IMAGE_MODE = 0x1F03, + VG_LITE_RECOLOR_MODE = 0x1F04, + } vg_lite_image_mode_t; + + /* The image (buffer) transparency mode. */ + typedef enum vg_lite_transparency + { + VG_LITE_IMAGE_OPAQUE, + VG_LITE_IMAGE_TRANSPARENT + } vg_lite_transparency_t; + + /* Blending modes. VG_BLEND_* match OpenVG enum VGBlendMode. + * S and D represent source and destination color channels. + * Sa and Da represent the source and destination alpha channels. + */ + typedef enum vg_lite_blend + { + VG_LITE_BLEND_NONE = 0, /*! S, No blend, Non-premultiplied */ + VG_LITE_BLEND_SRC_OVER = 1, /*! S + (1 - Sa) * D , Non-premultiplied */ + VG_LITE_BLEND_DST_OVER = 2, /*! (1 - Da) * S + D , Non-premultiplied */ + VG_LITE_BLEND_SRC_IN = 3, /*! Da * S , Non-premultiplied */ + VG_LITE_BLEND_DST_IN = 4, /*! Sa * D , Non-premultiplied */ + VG_LITE_BLEND_MULTIPLY = 5, /*! S * (1 - Da) + D * (1 - Sa) + S * D , Non-premultiplied */ + VG_LITE_BLEND_SCREEN = 6, /*! S + D - S * D , Non-premultiplied */ + VG_LITE_BLEND_DARKEN = 7, /*! min(SrcOver, DstOver) , Non-premultiplied */ + VG_LITE_BLEND_LIGHTEN = 8, /*! max(SrcOver, DstOver) , Non-premultiplied */ + VG_LITE_BLEND_ADDITIVE = 9, /*! S + D , Non-premultiplied */ + VG_LITE_BLEND_SUBTRACT = 10, /*! D * (1 - Sa) , Non-premultiplied */ + VG_LITE_BLEND_SUBTRACT_LVGL = 11, /*! D - S , Non-premultiplied */ + VG_LITE_BLEND_NORMAL_LVGL = 12, /*! S * Sa + (1 - Sa) * D , Non-premultiplied */ + VG_LITE_BLEND_ADDITIVE_LVGL = 13, /*! (S + D) * Sa + D * (1 - Sa) , Non-premultiplied */ + VG_LITE_BLEND_MULTIPLY_LVGL = 14, /*! (S * D) * Sa + D * (1 - Sa) , Non-premultiplied */ + VG_LITE_BLEND_PREMULTIPLY_SRC_OVER = 15, /*! S * Sa + (1 - Sa) * D , Non-premultiplied */ + + OPENVG_BLEND_SRC = 0x2000, /*! Copy SRC, no blend, Premultiplied */ + OPENVG_BLEND_SRC_OVER = 0x2001, /*! Porter-Duff SRC_OVER blend, Premultiplied */ + OPENVG_BLEND_DST_OVER = 0x2002, /*! Porter-Duff DST_OVER blend, Premultiplied */ + OPENVG_BLEND_SRC_IN = 0x2003, /*! Porter-Duff SRC_IN blend, Premultiplied */ + OPENVG_BLEND_DST_IN = 0x2004, /*! Porter-Duff DST_IN blend, Premultiplied */ + OPENVG_BLEND_MULTIPLY = 0x2005, /*! Porter-Duff MULTIPLY blend, Premultiplied */ + OPENVG_BLEND_SCREEN = 0x2006, /*! Porter-Duff SCREEN blend, Premultiplied */ + OPENVG_BLEND_DARKEN = 0x2007, /*! Porter-Duff DARKEN blend, Premultiplied */ + OPENVG_BLEND_LIGHTEN = 0x2008, /*! Porter-Duff LIGHTEN blend, Premultiplied */ + OPENVG_BLEND_ADDITIVE = 0x2009, /*! Porter-Duff ADDITIVE blend, Premultiplied */ + } vg_lite_blend_t; + + /* Fill rules. Match OpenVG enum VGFillRule */ + typedef enum vg_lite_fill + { + VG_LITE_FILL_EVEN_ODD = 0x1900, /*! A pixel is drawn it it crosses an odd number of path pixels. */ + VG_LITE_FILL_NON_ZERO = 0x1901, /*! A pixel is drawn if it crosses at least one path pixel. */ + } vg_lite_fill_t; + + /* Global alpha modes. */ + typedef enum vg_lite_global_alpha + { + VG_LITE_NORMAL = 0, /*! Use original src/dst alpha value. */ + VG_LITE_GLOBAL, /*! Use global src/dst alpha value to replace original src/dst alpha value. */ + VG_LITE_SCALED, /*! Multiply global src/dst alpha value and original src/dst alpha value. */ + } vg_lite_global_alpha_t; + + /* Filter modes. */ + typedef enum vg_lite_filter + { + VG_LITE_FILTER_POINT = 0, /*! Fetch the nearest image pixel. */ + VG_LITE_FILTER_LINEAR = 0x1000, /*! Used for linear paint. */ + VG_LITE_FILTER_BI_LINEAR = 0x2000, /*! Use a 2x2 box around the image pixel and perform an interpolation. */ + VG_LITE_FILTER_GAUSSIAN = 0x3000, /*! Perform 3x3 gaussian blur with the convolution for image pixel. */ + } vg_lite_filter_t; + + /* Pattern padding mode. Match OpenVG enum VGTilingMode. */ + typedef enum vg_lite_pattern_mode + { + VG_LITE_PATTERN_COLOR = 0x1D00, /*! Pixel outside the bounds of sourceimage should be taken as the color */ + VG_LITE_PATTERN_PAD = 0x1D01, /*! Pixel outside the bounds of sourceimage should be taken as having the same color as the closest edge pixel */ + VG_LITE_PATTERN_REPEAT = 0x1D02, /*! Pixel outside the bounds of sourceimage should be repeated indefinitely in all directions */ + VG_LITE_PATTERN_REFLECT = 0x1D03, /*! Pixel outside the bounds of sourceimage should be reflected indefinitely in all directions */ + } vg_lite_pattern_mode_t; + + /* Paint type. Match OpenVG enum VGPaintType. */ + typedef enum vg_lite_paint_type + { + /* For enum value backward compatibility */ + VG_LITE_PAINT_ZERO = 0, + VG_LITE_PAINT_COLOR = 0x1B00, + VG_LITE_PAINT_LINEAR_GRADIENT = 0x1B01, + VG_LITE_PAINT_RADIAL_GRADIENT = 0x1B02, + VG_LITE_PAINT_PATTERN = 0x1B03, + } vg_lite_paint_type_t; + + /* Radial gradient padding mode. Match OpenVG enum VGColorRampSpreadMode */ + typedef enum + { + VG_LITE_GRADIENT_SPREAD_FILL = 0, + VG_LITE_GRADIENT_SPREAD_PAD = 0x1C00, + VG_LITE_GRADIENT_SPREAD_REPEAT = 0x1C01, + VG_LITE_GRADIENT_SPREAD_REFLECT = 0x1C02, + } vg_lite_gradient_spreadmode_t; + + /* Decnano Compress mode. */ + typedef enum vg_lite_compress_mode + { + VG_LITE_DEC_DISABLE = 0, /*! disable compress */ + VG_LITE_DEC_NON_SAMPLE, /*! compress ratio is 1.6 if use ARGB8888, compress ratio is 2 if use XRGB8888 */ + VG_LITE_DEC_HSAMPLE, /*! compress ratio is 2 if use ARGB8888, compress ratio is 2.6 if use XRGB8888 */ + VG_LITE_DEC_HV_SAMPLE, /*! compress ratio is 2.6 if use ARGB8888, compress ratio is 4 if use XRGB8888 */ + } vg_lite_compress_mode_t; + + /* Draw path type. Match OpenVG enum VGPaintMode */ + typedef enum vg_lite_path_type + { + /* For enum value backward compatibility */ + VG_LITE_DRAW_ZERO = 0, + VG_LITE_DRAW_STROKE_PATH = (1<<0), + VG_LITE_DRAW_FILL_PATH = (1<<1), + VG_LITE_DRAW_FILL_STROKE_PATH = (1<<1 | 1<<0), + } vg_lite_path_type_t; + + /* End cap style. Match OpenVG enum VGCapStyle */ + typedef enum vg_lite_cap_style + { + VG_LITE_CAP_BUTT = 0x1700, + VG_LITE_CAP_ROUND = 0x1701, + VG_LITE_CAP_SQUARE = 0x1702, + } vg_lite_cap_style_t; + + /* Line join styles. Match OpenVG enum VGJoinStyle */ + typedef enum vg_lite_join_style + { + VG_LITE_JOIN_MITER = 0x1800, + VG_LITE_JOIN_ROUND = 0x1801, + VG_LITE_JOIN_BEVEL = 0x1802, + } vg_lite_join_style_t; + + /* Mask operation mode. Match OpenVG enum VGMaskOperation */ + typedef enum vg_lite_mask_operation + { + VG_LITE_CLEAR_MASK = 0x1500, /*! Set all dest mask values to 0 */ + VG_LITE_FILL_MASK = 0x1501, /*! Set all dest mask values to 1 */ + VG_LITE_SET_MASK = 0x1502, /*! Copy from src masklayer to dest masklayer. */ + VG_LITE_UNION_MASK = 0x1503, /*! Replace dest masklayer by its union with src masklayer. */ + VG_LITE_INTERSECT_MASK = 0x1504, /*! Replace dest masklayer by its intersection with src masklayer. */ + VG_LITE_SUBTRACT_MASK = 0x1505, /*! Subtract src mask in dest masklayer */ + } vg_lite_mask_operation_t; + + /* Mirror orientation mode. */ + typedef enum vg_lite_orientation + { + VG_LITE_ORIENTATION_TOP_BOTTOM, + VG_LITE_ORIENTATION_BOTTOM_TOP, + } vg_lite_orientation_t; + + /* Gamma conversion mode. */ + typedef enum vg_lite_gamma_conversion + { + VG_LITE_GAMMA_NO_CONVERSION, /*! Leave color as is. */ + VG_LITE_GAMMA_LINEAR, /*! Convert from sRGB to linear space. */ + VG_LITE_GAMMA_NON_LINEAR /*! Convert from linear to sRGB space. */ + } vg_lite_gamma_conversion_t; + + /* Index endian */ + typedef enum vg_lite_index_endian + { + VG_LITE_INDEX_LITTLE_ENDIAN, /*! Parse the index pixel from low to high, + *! when using index1, the parsing order is bit0~bit7. + *! when using index2, the parsing order is bit0:1,bit2:3,bit4:5.bit6:7. + *! when using index4, the parsing order is bit0:3,bit4:7. + */ + VG_LITE_INDEX_BIG_ENDIAN, /*! Parse the index pixel from low to high, + *! when using index1, the parsing order is bit7~bit0. + *! when using index2, the parsing order is bit7:6,bit5:4,bit3:2.bit1:0. + *! when using index4, the parsing order is bit4:7,bit0:3. + */ + } vg_lite_index_endian_t; + + /* Map flag*/ + typedef enum vg_lite_map_flag + { + VG_LITE_MAP_USER_MEMORY = 0, + VG_LITE_MAP_DMABUF = 0x01, + } vg_lite_map_flag_t; + + /*VGLite parameters variable*/ + typedef enum vg_lite_param_type + { + VG_LITE_SCISSOR_RECT, /*! count must be 4n for x, y, right, bottom */ + VG_LITE_GPU_IDLE_STATE, /*! 0: busy, 1: idle */ + } vg_lite_param_type_t; + +/* VGLite API Structures ******************************************************************************************************************/ + + /* VGLite driver information */ + typedef struct vg_lite_info { + vg_lite_uint32_t api_version; + vg_lite_uint32_t header_version; + vg_lite_uint32_t release_version; + vg_lite_uint32_t reserved; + } vg_lite_info_t; + + /* A 2D Point definition. */ + typedef struct vg_lite_point { + vg_lite_int32_t x; + vg_lite_int32_t y; + } vg_lite_point_t; + + /* Four 2D Point that form a polygon */ + typedef vg_lite_point_t vg_lite_point4_t[4]; + + /* A rectangle.*/ + typedef struct vg_lite_rectangle { + vg_lite_int32_t x; /*! Left coordinate of rectangle. */ + vg_lite_int32_t y; /*! Top coordinate of rectangle. */ + vg_lite_int32_t width; /*! Width of rectangle. */ + vg_lite_int32_t height; /*! Height of rectangle. */ + } vg_lite_rectangle_t; + + typedef struct vg_lite_matrix { + vg_lite_float_t m[3][3]; /*! The 3x3 matrix is in [row][column] order. */ + vg_lite_float_t scaleX; + vg_lite_float_t scaleY; + vg_lite_float_t angle; + } vg_lite_matrix_t; + + typedef struct vg_lite_yuvinfo + { + vg_lite_swizzle_t swizzle; /*! UV swizzle. */ + vg_lite_yuv2rgb_t yuv2rgb; /*! 601 or 709 conversion standard. */ + vg_lite_uint32_t uv_planar; /*! UV(U) planar address. */ + vg_lite_uint32_t v_planar; /*! V planar address. */ + vg_lite_uint32_t alpha_planar; /*! Alpha planar address. */ + vg_lite_uint32_t uv_stride; /*! UV(U) stride. */ + vg_lite_uint32_t v_stride; /*! V stride. */ + vg_lite_uint32_t alpha_stride; /*! Alpha stride. */ + vg_lite_uint32_t uv_height; /*! UV(U) height. */ + vg_lite_uint32_t v_height; /*! V height. */ + vg_lite_pointer uv_memory; /*! The logical pointer to the UV(U) planar memory. */ + vg_lite_pointer v_memory; /*! The logical pointer to the V planar memory. */ + vg_lite_pointer uv_handle; /*! The memory handle of the UV(U) planar. */ + vg_lite_pointer v_handle; /*! The memory handle of the V planar. */ + } vg_lite_yuvinfo_t; + + typedef struct vg_lite_path_point* vg_lite_path_point_ptr; + typedef struct vg_lite_path_point + { + /* X coordinate. */ + vg_lite_float_t x; + + /* Y coordinate. */ + vg_lite_float_t y; + + /* Flatten flag for flattened path. */ + vg_lite_uint8_t flatten_flag; + + /* Curve type for stroke path. */ + vg_lite_uint8_t curve_type; + + /* X tangent. */ + vg_lite_float_t tangentX; + + /* Y tangent. */ + vg_lite_float_t tangentY; + + /* Length of the line. */ + vg_lite_float_t length; + + /* Pointer to next point node. */ + vg_lite_path_point_ptr next; + + /* Pointer to previous point node. */ + vg_lite_path_point_ptr prev; + + } vg_lite_path_point_t; + + typedef struct vg_lite_sub_path* vg_lite_sub_path_ptr; + typedef struct vg_lite_sub_path + { + /* Pointer to next sub path. */ + vg_lite_sub_path_ptr next; + + /* Number of points. */ + vg_lite_uint32_t point_count; + + /* Point list. */ + vg_lite_path_point_ptr point_list; + + /* Last point. */ + vg_lite_path_point_ptr end_point; + + /* Whether is path is closed. */ + vg_lite_uint8_t closed; + + /* Sub path length. */ + vg_lite_float_t length; + + } vg_lite_sub_path_t; + + /* Save divided path data according to MOVE/MOVE_REL. */ + typedef struct vg_lite_path_list* vg_lite_path_list_ptr; + typedef struct vg_lite_path_list + { + vg_lite_path_point_ptr path_points; + vg_lite_path_point_ptr path_end; + vg_lite_uint32_t point_count; + vg_lite_path_list_ptr next; + vg_lite_uint8_t closed; + + } vg_lite_path_list_t; + + typedef struct vg_lite_stroke + { + /* Stroke parameters */ + vg_lite_cap_style_t cap_style; + vg_lite_join_style_t join_style; + vg_lite_float_t line_width; + vg_lite_float_t miter_limit; + vg_lite_float_t *dash_pattern; + vg_lite_uint32_t pattern_count; + vg_lite_float_t dash_phase; + vg_lite_float_t dash_length; + vg_lite_uint32_t dash_index; + vg_lite_float_t half_width; + + /* Total length of stroke dash patterns. */ + vg_lite_float_t pattern_length; + + /* For fast checking. */ + vg_lite_float_t miter_square; + + /* Temp storage of stroke subPath. */ + vg_lite_path_point_ptr path_points; + vg_lite_path_point_ptr path_end; + vg_lite_uint32_t point_count; + vg_lite_path_point_ptr left_point; + vg_lite_path_point_ptr right_point; + vg_lite_path_point_ptr stroke_points; + vg_lite_path_point_ptr stroke_end; + vg_lite_uint32_t stroke_count; + + /* Divide stroke path according to move or move_rel for avoiding implicit closure. */ + vg_lite_path_list_ptr path_list_divide; + + /* pointer to current divided path data. */ + vg_lite_path_list_ptr cur_list; + + /* Flag that add end_path in driver. */ + vg_lite_uint8_t add_end; + vg_lite_uint8_t dash_reset; + + /* Sub path list. */ + vg_lite_sub_path_ptr stroke_paths; + + /* Last sub path. */ + vg_lite_sub_path_ptr last_stroke; + + /* Swing area handling. */ + vg_lite_uint32_t swing_handling; + vg_lite_float_t swing_deltax; + vg_lite_float_t swing_deltay; + vg_lite_path_point_ptr swing_start; + vg_lite_path_point_ptr swing_stroke; + vg_lite_float_t swing_length; + vg_lite_float_t swing_centlen; + vg_lite_uint32_t swing_count; + vg_lite_uint8_t need_swing; + vg_lite_uint8_t swing_ccw; + + vg_lite_float_t stroke_length; + vg_lite_uint32_t stroke_size; + + /* The stroke line is fat line. */ + vg_lite_uint8_t fattened; + vg_lite_uint8_t closed; + + } vg_lite_stroke_t; + + /* Fast clear buffer. */ + typedef struct vg_lite_fc_buffer + { + vg_lite_int32_t width; /*! Width of the buffer in pixels. */ + vg_lite_int32_t height; /*! height of the buffer in pixels. */ + vg_lite_int32_t stride; /*! The number of bytes to move from one line in the buffer to the next line. */ + vg_lite_pointer handle; /*! The memory handle of the buffer's memory as allocated by the VGLite kernel. */ + vg_lite_pointer memory; /*! The logical pointer to the buffer's memory for the CPU. */ + vg_lite_uint32_t address; /*! The address to the buffer's memory for the hardware. */ + vg_lite_uint32_t color; /*! The fastclear color value. */ + } vg_lite_fc_buffer_t; + + /* Structure for any image or render target. */ + typedef struct vg_lite_buffer + { + vg_lite_int32_t width; /*! Width of the buffer in pixels. */ + vg_lite_int32_t height; /*! Height of the buffer in pixels. */ + vg_lite_int32_t stride; /*! The number of bytes to move from one line in the buffer to the next line. */ + vg_lite_buffer_layout_t tiled; /*! Indicating the buffer memory layout is linear or tiled. */ + vg_lite_buffer_format_t format; /*! The pixel format of the buffer. */ + vg_lite_pointer handle; /*! The memory handle of the buffer's memory as allocated by the VGLite kernel. */ + vg_lite_pointer memory; /*! The logical pointer to the buffer's memory for the CPU. */ + vg_lite_uint32_t address; /*! The address to the buffer's memory for the hardware. */ + vg_lite_yuvinfo_t yuv; /*! The yuv format details. */ + vg_lite_image_mode_t image_mode; /*! The blit image mode. */ + vg_lite_transparency_t transparency_mode; /*! image transparency mode. */ + vg_lite_fc_buffer_t fc_buffer[3]; /*! 3 fastclear buffers,reserved YUV format. */ + vg_lite_compress_mode_t compress_mode; /*! Refer to the definition by vg_lite_compress_mode_t. */ + vg_lite_index_endian_t index_endian; /*! Refer to the definition by vg_lite_index_endian_t. */ + vg_lite_paint_type_t paintType; /*! Get paintcolor from different paint types. */ + vg_lite_uint8_t fc_enable; /*! enable im fastclear. */ + vg_lite_uint8_t scissor_layer; /*! The buffer is scissor buffer. */ + vg_lite_uint8_t premultiplied; /*! The RGB pixel values are alpha-premultiplied */ + } vg_lite_buffer_t; + + /* Memory allocation info by kernel. */ + typedef struct vg_lite_hw_memory + { + vg_lite_pointer handle; /*! gpu memory object handle. */ + vg_lite_pointer memory; /*! logical memory address. */ + vg_lite_uint32_t address; /*! GPU memory address. */ + vg_lite_uint32_t bytes; /*! Size of memory. */ + vg_lite_uint32_t property; /*! Currently bit0 is used for path upload state: + *! 1 : enable auto path data uploading. + *! 0 : disable path data uploading. path data is embedded in command buffer. */ + } vg_lite_hw_memory_t; + + /* Path info for drawing command. */ + typedef struct vg_lite_path + { + vg_lite_float_t bounding_box[4]; /*! Bounding box specified as left, top, right, and bottom. */ + vg_lite_quality_t quality; /*! Quality hint for the path. */ + vg_lite_format_t format; /*! Coordinate format. */ + vg_lite_hw_memory_t uploaded; /*! Path data that has been upload into GPU addressable memory. */ + vg_lite_uint32_t path_length; /*! Number of bytes in the path data. */ + vg_lite_pointer path; /*! Pointer to the physical description of the path. */ + vg_lite_int8_t path_changed; /*! Indicate whether path data is synced with command buffer (uploaded) or not. */ + vg_lite_int8_t pdata_internal; /*! Indicate whether path data memory is allocated by driver. */ + vg_lite_path_type_t path_type; /*! Refer to the definition by vg_lite_path_type_t. */ + vg_lite_stroke_t *stroke; /*! Pointer to a vg_lite_stroke_t structure.*/ + vg_lite_pointer stroke_path; /*! Pointer to the physical description of the stroke path. */ + vg_lite_uint32_t stroke_size; /*! Number of bytes in the stroke path data. */ + vg_lite_color_t stroke_color; /*! The stroke path fill color. */ + vg_lite_int8_t add_end; /*! Flag that add end_path in driver. */ + } vg_lite_path_t; + + /* Color ramp definition. */ + typedef struct vg_lite_color_ramp + { + vg_lite_float_t stop; /*! Value for the color stop. */ + vg_lite_float_t red; /*! Red color channel value for the color stop. */ + vg_lite_float_t green; /*! Green color channel value for the color stop. */ + vg_lite_float_t blue; /*! Blue color channel value for the color stop. */ + vg_lite_float_t alpha; /*! Alpha color channel value for the color stop. */ + } vg_lite_color_ramp_t; + + /* Linear gradient parameter */ + typedef struct vg_lite_linear_gradient_parameter + { + vg_lite_float_t X0; + vg_lite_float_t Y0; + vg_lite_float_t X1; + vg_lite_float_t Y1; + } vg_lite_linear_gradient_parameter_t; + + typedef struct vg_lite_radial_gradient_parameter + { + vg_lite_float_t cx; /*! x coordinate of the center point. */ + vg_lite_float_t cy; /*! y coordinate of the center point. */ + vg_lite_float_t r; /*! radius. */ + vg_lite_float_t fx; /*! x coordinate of the focal point. */ + vg_lite_float_t fy; /*! y coordinate of the focal point. */ + } vg_lite_radial_gradient_parameter_t; + + /* Linear gradient definition. */ + typedef struct vg_lite_linear_gradient { + vg_lite_uint32_t colors[VLC_MAX_GRADIENT_STOPS]; /*! Colors for stops. */ + vg_lite_uint32_t count; /*! Count of colors, up to 16. */ + vg_lite_uint32_t stops[VLC_MAX_GRADIENT_STOPS]; /*! Color stops, value from 0 to 255. */ + vg_lite_matrix_t matrix; /*! The matrix to transform the gradient. */ + vg_lite_buffer_t image; /*! The image for rendering as gradient pattern. */ + } vg_lite_linear_gradient_t; + + /* Extended linear gradient definition. */ + typedef struct vg_lite_ext_linear_gradient { + vg_lite_uint32_t count; /*! Count of colors, up to 256. */ + vg_lite_matrix_t matrix; /*! The matrix to transform the gradient. */ + vg_lite_buffer_t image; /*! The image for rendering as gradient pattern. */ + vg_lite_linear_gradient_parameter_t linear_grad; /*! Include center point,focal point and radius.*/ + + vg_lite_uint32_t ramp_length; /*! Color ramp for gradient paints provided to driver. */ + vg_lite_color_ramp_t color_ramp[VLC_MAX_COLOR_RAMP_STOPS]; + + vg_lite_uint32_t converted_length; /*! Converted internal color ramp. */ + vg_lite_color_ramp_t converted_ramp[VLC_MAX_COLOR_RAMP_STOPS + 2]; + + vg_lite_uint8_t pre_multiplied; /*! If color values of color_ramp[] are multiply by alpha value of color_ramp[]. */ + vg_lite_gradient_spreadmode_t spread_mode; /*! The spread mode that applied to the pixels out of the image after transformed. */ + } vg_lite_ext_linear_gradient_t; + + /* Radial gradient definition. */ + typedef struct vg_lite_radial_gradient + { + vg_lite_uint32_t count; /*! Count of colors, up to 256. */ + vg_lite_matrix_t matrix; /*! The matrix to transform the gradient. */ + vg_lite_buffer_t image; /*! The image for rendering as gradient pattern. */ + vg_lite_radial_gradient_parameter_t radial_grad; /*! Include center point,focal point and radius.*/ + + vg_lite_uint32_t ramp_length; /*! Color ramp for gradient paints provided to the driver. */ + vg_lite_color_ramp_t color_ramp[VLC_MAX_COLOR_RAMP_STOPS]; + + vg_lite_uint32_t converted_length; /*! Converted internal color ramp. */ + vg_lite_color_ramp_t converted_ramp[VLC_MAX_COLOR_RAMP_STOPS + 2]; + + vg_lite_uint8_t pre_multiplied; /*! If color values of color_ramp[] are multiply by alpha value of color_ramp[]. */ + vg_lite_gradient_spreadmode_t spread_mode; /*! The spread mode that applied to the pixels out of the image after transformed. */ + } vg_lite_radial_gradient_t; + + /* Colorkey definition */ + typedef struct vg_lite_color_key + { + vg_lite_uint8_t enable; /*! The color key is effective only when "enable" is true, */ + vg_lite_uint8_t low_r; /*! The R channel of low_rgb. */ + vg_lite_uint8_t low_g; /*! The G channel of low_rgb. */ + vg_lite_uint8_t low_b; /*! The B channel of low_rgb. */ + vg_lite_uint8_t alpha; /*! The alpha channel to replace destination pixel alpha channel.*/ + vg_lite_uint8_t hign_r; /*! The R channel of hign_rgb. */ + vg_lite_uint8_t hign_g; /*! The G channel of hign_rgb. */ + vg_lite_uint8_t hign_b; /*! The B channel of hign_rgb. */ + } vg_lite_color_key_t; + + /* Four colorkey definition. + * rgb_hi_0, rgb_lo_0, alpha_0, enable_0; + * rgb_hi_1, rgb_lo_1, alpha_1, enable_1; + * rgb_hi_2, rgb_lo_2, alpha_2, enable_2; + * rgb_hi_3, rgb_lo_3, alpha_3, enable_3; + * Priority order: color_key_0 > color_key_1 > color_key_2 > color_key_3. + */ + typedef vg_lite_color_key_t vg_lite_color_key4_t[4]; + + /* Pixel matrix values */ + typedef vg_lite_float_t vg_lite_pixel_matrix_t[20]; + + /* HW pixel channel enable flags */ + typedef struct vg_lite_pixel_channel_enable + { + vg_lite_uint8_t enable_a; /*! Enable A channel.*/ + vg_lite_uint8_t enable_b; /*! Enable B channel. */ + vg_lite_uint8_t enable_g; /*! Enable G channel. */ + vg_lite_uint8_t enable_r; /*! Enable R channel. */ + } vg_lite_pixel_channel_enable_t; + + /* Pixel color transform */ + typedef struct vg_lite_color_transform + { + vg_lite_float_t a_scale; + vg_lite_float_t a_bias; + vg_lite_float_t r_scale; + vg_lite_float_t r_bias; + vg_lite_float_t g_scale; + vg_lite_float_t g_bias; + vg_lite_float_t b_scale; + vg_lite_float_t b_bias; + } vg_lite_color_transform_t; + +/* VGLite API Functions *******************************************************************************************************************/ + + /* Initialize a vglite context. */ + vg_lite_error_t vg_lite_init(vg_lite_int32_t tess_width, vg_lite_int32_t tess_height); + + /* Destroy a vglite context. */ + vg_lite_error_t vg_lite_close(void); + + /* Get the VGLite driver information. */ + vg_lite_error_t vg_lite_get_info(vg_lite_info_t* info); + + /* Get the GPU chip information. */ + vg_lite_uint32_t vg_lite_get_product_info(vg_lite_char *name, vg_lite_uint32_t *chip_id, vg_lite_uint32_t *chip_rev); + + /* Query if a specific feature is supported. */ + vg_lite_uint32_t vg_lite_query_feature(vg_lite_feature_t feature); + + /* Flush command buffer and wait for GPU to complete. */ + vg_lite_error_t vg_lite_finish(void); + + /* Flush the command buffer without waiting for GPU to complete. */ + vg_lite_error_t vg_lite_flush(void); + + /* Get the value of register from register's address. */ + vg_lite_error_t vg_lite_get_register(vg_lite_uint32_t address, vg_lite_uint32_t* result); + + /* Generate a 3x3 homogenous matrix to transform 4 source coordinates to 4 target coordinates. */ + vg_lite_error_t vg_lite_get_transform_matrix(vg_lite_point4_t src, vg_lite_point4_t dst, vg_lite_matrix_t *mat); + + /* Allocate a buffer from GPU hardware accessible memory. */ + vg_lite_error_t vg_lite_allocate(vg_lite_buffer_t *buffer); + + /* Free a buffer allocated by vg_lite_allocate() */ + vg_lite_error_t vg_lite_free(vg_lite_buffer_t *buffer); + + /* Upload RGB or YUV pixel data to an allocated buffer. */ + vg_lite_error_t vg_lite_upload_buffer(vg_lite_buffer_t *buffer, vg_lite_uint8_t *data[3], vg_lite_uint32_t stride[3]); + + /* Map a buffer into hardware accessible address space. */ + vg_lite_error_t vg_lite_map(vg_lite_buffer_t *buffer, vg_lite_map_flag_t flag, int32_t fd); + + /* Unmap a buffer that is mapped */ + vg_lite_error_t vg_lite_unmap(vg_lite_buffer_t *buffer); + + /* flush cache */ + vg_lite_error_t vg_lite_flush_mapped_buffer(vg_lite_buffer_t * buffer); + + /* Fill a buffer rectangle area with a specified color. */ + vg_lite_error_t vg_lite_clear(vg_lite_buffer_t *target, vg_lite_rectangle_t *rect, vg_lite_color_t color); + + /* Copy a source image to target buffer with transformation, blending, color mixing, and filtering. */ + vg_lite_error_t vg_lite_blit(vg_lite_buffer_t *target, + vg_lite_buffer_t *source, + vg_lite_matrix_t *matrix, + vg_lite_blend_t blend, + vg_lite_color_t color, + vg_lite_filter_t filter); + + /* Copy a rectangle area of source image to target buffer with transformation, blending, color mixing, and filtering. */ + vg_lite_error_t vg_lite_blit_rect(vg_lite_buffer_t *target, + vg_lite_buffer_t *source, + vg_lite_rectangle_t *rect, + vg_lite_matrix_t *matrix, + vg_lite_blend_t blend, + vg_lite_color_t color, + vg_lite_filter_t filter); + + /* Copy two source images to the target buffer with transformation, blending, and filtering. */ + vg_lite_error_t vg_lite_blit2(vg_lite_buffer_t *target, + vg_lite_buffer_t *source0, + vg_lite_buffer_t *source1, + vg_lite_matrix_t *matrix0, + vg_lite_matrix_t *matrix1, + vg_lite_blend_t blend, + vg_lite_filter_t filter); + + /* Copy a rectangle area of source image to target buffer without transformation, blending, color mixing, and filtering. */ + vg_lite_error_t vg_lite_copy_image(vg_lite_buffer_t *target, + vg_lite_buffer_t *source, + vg_lite_int32_t sx, + vg_lite_int32_t sy, + vg_lite_int32_t dx, + vg_lite_int32_t dy, + vg_lite_int32_t width, + vg_lite_int32_t height); + + /* Draw a path to a target buffer with transformation, color, and blending */ + vg_lite_error_t vg_lite_draw(vg_lite_buffer_t *target, + vg_lite_path_t *path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t *matrix, + vg_lite_blend_t blend, + vg_lite_color_t color); + + /* Set stroke path attributes. */ + vg_lite_error_t vg_lite_set_stroke(vg_lite_path_t *path, + vg_lite_cap_style_t cap_style, + vg_lite_join_style_t join_style, + vg_lite_float_t line_width, + vg_lite_float_t miter_limit, + vg_lite_float_t *dash_pattern, + vg_lite_uint32_t pattern_count, + vg_lite_float_t dash_phase, + vg_lite_color_t color); + + /* Update stroke path. */ + vg_lite_error_t vg_lite_update_stroke(vg_lite_path_t *path); + + /* Set path type. */ + vg_lite_error_t vg_lite_set_path_type(vg_lite_path_t *path, vg_lite_path_type_t path_type); + + /* Clears all attributes of a path. */ + vg_lite_error_t vg_lite_clear_path(vg_lite_path_t *path); + + /* Upload a path to GPU memory so GPU can access it directly. */ + vg_lite_error_t vg_lite_upload_path(vg_lite_path_t *path); + + /* Initialize a path object with attributes. */ + vg_lite_error_t vg_lite_init_path(vg_lite_path_t *path, + vg_lite_format_t format, + vg_lite_quality_t quality, + vg_lite_uint32_t length, + vg_lite_pointer data, + vg_lite_float_t min_x, + vg_lite_float_t min_y, + vg_lite_float_t max_x, + vg_lite_float_t max_y); + + /* Initializes a arc path with attributes. */ + vg_lite_error_t vg_lite_init_arc_path(vg_lite_path_t *path, + vg_lite_format_t format, + vg_lite_quality_t quality, + vg_lite_uint32_t length, + vg_lite_pointer data, + vg_lite_float_t min_x, + vg_lite_float_t min_y, + vg_lite_float_t max_x, + vg_lite_float_t max_y); + + /* Return the size (in bytes) of command buffer for a path opcode array. */ + vg_lite_uint32_t vg_lite_get_path_length(vg_lite_uint8_t *opcode, + vg_lite_uint32_t count, + vg_lite_format_t format); + + /* Generate command buffer for the (path) based on input opcodes (opcode) and coordinates (data). */ + vg_lite_error_t vg_lite_append_path(vg_lite_path_t *path, + vg_lite_uint8_t *opcode, + vg_lite_pointer data, + vg_lite_uint32_t seg_count); + + /* Set CLUT (Color Look Up Table) for index image. The (colors) is in ARGB format. */ + vg_lite_error_t vg_lite_set_CLUT(vg_lite_uint32_t count, vg_lite_uint32_t *colors); + + /* Draw a path that is filled by a transformed image pattern. */ + vg_lite_error_t vg_lite_draw_pattern(vg_lite_buffer_t *target, + vg_lite_path_t *path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t *path_matrix, + vg_lite_buffer_t *pattern_image, + vg_lite_matrix_t *pattern_matrix, + vg_lite_blend_t blend, + vg_lite_pattern_mode_t pattern_mode, + vg_lite_color_t pattern_color, + vg_lite_color_t color, + vg_lite_filter_t filter); + + /* Initialize a linear gradient object with default attributes. */ + vg_lite_error_t vg_lite_init_grad(vg_lite_linear_gradient_t *grad); + + /* Reset a linear gradient object attributes. */ + vg_lite_error_t vg_lite_clear_grad(vg_lite_linear_gradient_t *grad); + + /* Update a linear gradient object. */ + vg_lite_error_t vg_lite_update_grad(vg_lite_linear_gradient_t *grad); + + /* Return pointer to a linear gradient object's matrix. */ + vg_lite_matrix_t* vg_lite_get_grad_matrix(vg_lite_linear_gradient_t *grad); + + /* Set attributes for a linear gradient object. */ + vg_lite_error_t vg_lite_set_grad(vg_lite_linear_gradient_t *grad, + vg_lite_uint32_t count, + vg_lite_uint32_t *colors, + vg_lite_uint32_t *stops); + + /* Draw a path with a linear gradient object pattern. */ + vg_lite_error_t vg_lite_draw_grad(vg_lite_buffer_t *target, + vg_lite_path_t *path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t *matrix, + vg_lite_linear_gradient_t *grad, + vg_lite_blend_t blend); + + /* Reset an extended linear gradient object attributes and free image buffer. */ + vg_lite_error_t vg_lite_clear_linear_grad(vg_lite_ext_linear_gradient_t *grad); + + /* Update an extended linear gradient object. */ + vg_lite_error_t vg_lite_update_linear_grad(vg_lite_ext_linear_gradient_t *grad); + + /* Return pointer to an extended linear gradient object's matrix. */ + vg_lite_matrix_t* vg_lite_get_linear_grad_matrix(vg_lite_ext_linear_gradient_t *grad); + + /* Set attributes for an extended linear gradient object. */ + vg_lite_error_t vg_lite_set_linear_grad(vg_lite_ext_linear_gradient_t *grad, + vg_lite_uint32_t count, + vg_lite_color_ramp_t *color_ramp, + vg_lite_linear_gradient_parameter_t grad_param, + vg_lite_gradient_spreadmode_t spread_mode, + vg_lite_uint8_t pre_mult); + + /* Draw a path with an extended linear gradient object. */ + vg_lite_error_t vg_lite_draw_linear_grad(vg_lite_buffer_t *target, + vg_lite_path_t *path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t *path_matrix, + vg_lite_ext_linear_gradient_t *grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter); + + /* Reset a radial gradient object attributes and free image buffer. */ + vg_lite_error_t vg_lite_clear_radial_grad(vg_lite_radial_gradient_t *grad); + + /* Update a radial gradient object. */ + vg_lite_error_t vg_lite_update_radial_grad(vg_lite_radial_gradient_t *grad); + + /* Return pointer to a radial gradient object's matrix. */ + vg_lite_matrix_t* vg_lite_get_radial_grad_matrix(vg_lite_radial_gradient_t *grad); + + /* Set attributes for a radial gradient object. */ + vg_lite_error_t vg_lite_set_radial_grad(vg_lite_radial_gradient_t *grad, + vg_lite_uint32_t count, + vg_lite_color_ramp_t *color_ramp, + vg_lite_radial_gradient_parameter_t grad_param, + vg_lite_gradient_spreadmode_t spread_mode, + vg_lite_uint8_t pre_mult); + + /* Draw a path with a radial gradient object pattern. */ + vg_lite_error_t vg_lite_draw_radial_grad(vg_lite_buffer_t *target, + vg_lite_path_t *path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t *path_matrix, + vg_lite_radial_gradient_t *grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter); + + /* Load an identity matrix. */ + vg_lite_error_t vg_lite_identity(vg_lite_matrix_t *matrix); + + /* Translate a matrix. */ + vg_lite_error_t vg_lite_translate(vg_lite_float_t x, vg_lite_float_t y, vg_lite_matrix_t *matrix); + + /* Scale a matrix. */ + vg_lite_error_t vg_lite_scale(vg_lite_float_t scale_x, vg_lite_float_t scale_y, vg_lite_matrix_t *matrix); + + /* Rotate a matrix. */ + vg_lite_error_t vg_lite_rotate(vg_lite_float_t degrees, vg_lite_matrix_t *matrix); + + /* Set and enable a scissor rectangle for render target. */ + vg_lite_error_t vg_lite_set_scissor(vg_lite_int32_t x, vg_lite_int32_t y, vg_lite_int32_t right, vg_lite_int32_t bottom); + + /* Set scissor rectangles on mask layer. Scissor rects are enabled/disabled by following APIs. */ + vg_lite_error_t vg_lite_scissor_rects(vg_lite_uint32_t nums, vg_lite_rectangle_t rect[]); + + /* Enable scissor rects defined on mask layer. */ + vg_lite_error_t vg_lite_enable_scissor(void); + + /* Disable scissor rects defined on mask layer. */ + vg_lite_error_t vg_lite_disable_scissor(void); + + /* Query size of available contiguous video memory. */ + vg_lite_error_t vg_lite_get_mem_size(vg_lite_uint32_t *size); + + /* Set global alpha value for source image */ + vg_lite_error_t vg_lite_source_global_alpha(vg_lite_global_alpha_t alpha_mode, vg_lite_uint8_t alpha_value); + + /* Set global alpha value for destination image. */ + vg_lite_error_t vg_lite_dest_global_alpha(vg_lite_global_alpha_t alpha_mode, vg_lite_uint8_t alpha_value); + + /* Set colorkey. */ + vg_lite_error_t vg_lite_set_color_key(vg_lite_color_key4_t colorkey); + + /* Enable dither function. Dither is OFF by default. */ + vg_lite_error_t vg_lite_enable_dither(void); + + /* Disable dither function. Dither is OFF by default. */ + vg_lite_error_t vg_lite_disable_dither(void); + + /* Set a 64-byte aligned memory buffer (physical) as VGLite tessellation buffer. */ + vg_lite_error_t vg_lite_set_tess_buffer(vg_lite_uint32_t physical, vg_lite_uint32_t size); + + /* Can be called before vg_lite_init() to overwrite the default VG_LITE_COMMAND_BUFFER_SIZE */ + vg_lite_error_t vg_lite_set_command_buffer_size(vg_lite_uint32_t size); + + /* Set a user-defined external memory buffer (physical, 64-byte aligned) as VGLite command buffer. */ + vg_lite_error_t vg_lite_set_command_buffer(vg_lite_uint32_t physical, vg_lite_uint32_t size); + + /* Setup a pixel transform matrix m[20] which transforms each pixel as following: + * + * |a'| |m0 m1 m2 m3 m4 | |a| + * |r'| |m5 m6 m7 m8 m9 | |r| + * |g'| = |m10 m11 m12 m13 m14|.|g| + * |b'| |m15 m16 m17 m18 m19| |b| + * |1 | |0 0 0 0 1 | |1| + * + * The pixel transform for A, R, G, B channel can be enabled/disabled individually with (channel) parameter. + */ + vg_lite_error_t vg_lite_set_pixel_matrix(vg_lite_pixel_matrix_t matrix, vg_lite_pixel_channel_enable_t *channel); + + /* Setup 3x3 gaussian blur weight values to filter image pixels. + * + * Parameters w0, w1, w2 define a 3x3 gaussian blur weight matrix as below + * + * | w2 w1 w2 | + * | w1 w0 w1 | + * | w2 w1 w2 | + * + * The sum of 9 kernel weights must be 1.0 to avoid convolution overflow ( w0 + 4*w1 + 4*w2 = 1.0 ). + * The 3x3 weight matrix applies to a 3x3 pixel block + * + * | pixel[i-1][j-1] pixel[i][j-1] pixel[i+1][j-1]| + * | pixel[i-1][j] pixel[i][j] pixel[i+1][j] | + * | pixel[i-1][j+1] pixel[i][j+1] pixel[i+1][j+1]| + * + * With the following dot product equation: + * + * color[i][j] = w2*pixel[i-1][j-1] + w1*pixel[i][j-1] + w2*pixel[i+1][j-1] + * + w1*pixel[i-1][j] + w0*pixel[i][j] + w1*pixel[i+1][j] + * + w2*pixel[i-1][j+1] + w1*pixel[i][j+1] + w2*pixel[i+1][j+1]; + */ + vg_lite_error_t vg_lite_gaussian_filter(vg_lite_float_t w0, vg_lite_float_t w1, vg_lite_float_t w2); + + /* Enable masklayer function. Masklayer is OFF by default. */ + vg_lite_error_t vg_lite_enable_masklayer(void); + + /* Disable masklayer function. Masklayer is OFF by default. */ + vg_lite_error_t vg_lite_disable_masklayer(void); + + /* Setup a masklayer. */ + vg_lite_error_t vg_lite_set_masklayer(vg_lite_buffer_t *masklayer); + + /* Free a masklayer and disable mask operation. */ + vg_lite_error_t vg_lite_destroy_masklayer(vg_lite_buffer_t *masklayer); + + /* Create a masklayer with default format A8 and default pixel value 255. */ + vg_lite_error_t vg_lite_create_masklayer(vg_lite_buffer_t *masklayer, + vg_lite_uint32_t width, + vg_lite_uint32_t height); + + /* Set pixel values for a rectangle area in a masklayer */ + vg_lite_error_t vg_lite_fill_masklayer(vg_lite_buffer_t *masklayer, + vg_lite_rectangle_t *rect, + vg_lite_uint8_t value); + + /* Blend a rectangle area of src masklayer with dst masklayer according to (operation). */ + vg_lite_error_t vg_lite_blend_masklayer(vg_lite_buffer_t *dst, + vg_lite_buffer_t *src, + vg_lite_mask_operation_t operation, + vg_lite_rectangle_t *rect); + + /* Render a (path) with (fill_rule), (color), (matrix) to the masklayer. */ + vg_lite_error_t vg_lite_render_masklayer(vg_lite_buffer_t *masklayer, + vg_lite_mask_operation_t operation, + vg_lite_path_t *path, + vg_lite_fill_t fill_rule, + vg_lite_color_t color, + vg_lite_matrix_t *matrix); + + /* Set mirror orientation. */ + vg_lite_error_t vg_lite_set_mirror(vg_lite_orientation_t orientation); + + /* Set gamma value. */ + vg_lite_error_t vg_lite_set_gamma(vg_lite_gamma_conversion_t gamma_value); + + /* Enable color transformation, which is OFF by default. */ + vg_lite_error_t vg_lite_enable_color_transform(void); + + /* Disable color transformation, which is OFF by default. */ + vg_lite_error_t vg_lite_disable_color_transform(void); + + /* Set pixel color transformation scale and bias values for each pixel channel. */ + vg_lite_error_t vg_lite_set_color_transform(vg_lite_color_transform_t *values); + + /* Set flexa stream id. */ + vg_lite_error_t vg_lite_flexa_set_stream(vg_lite_uint8_t stream_id); + + /* set flexa background buffer.*/ + vg_lite_error_t vg_lite_flexa_bg_buffer(vg_lite_uint8_t stream_id, + vg_lite_buffer_t *buffer, + vg_lite_uint32_t seg_count, + vg_lite_uint32_t seg_size); + + /* Enable flexa. */ + vg_lite_error_t vg_lite_flexa_enable(void); + + /* Disable flexa.*/ + vg_lite_error_t vg_lite_flexa_disable(void); + + /* Set flexa stop flag after the last frame. */ + vg_lite_error_t vg_lite_flexa_stop_frame(void); + + /* Dump command buffer */ + vg_lite_error_t vg_lite_dump_command_buffer(void); + + /* Return VGLite parameters in params[] array */ + vg_lite_error_t vg_lite_get_parameter(vg_lite_param_type_t type, + vg_lite_int32_t count, + vg_lite_float_t* params); + +#endif /* VGLITE_VERSION_3_0 */ + +#ifdef __cplusplus +} +#endif +#endif /* _vg_lite_h_ */ diff --git a/test/include/liblvgl/others/vg_lite_tvg/vg_lite_tvg.cpp b/test/include/liblvgl/others/vg_lite_tvg/vg_lite_tvg.cpp new file mode 100644 index 00000000..47d1930c --- /dev/null +++ b/test/include/liblvgl/others/vg_lite_tvg/vg_lite_tvg.cpp @@ -0,0 +1,2854 @@ +/** + * @file vg_lite_tvg.cpp + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_VG_LITE && LV_USE_VG_LITE_THORVG + +#include "vg_lite.h" +#include "../../lvgl.h" +#include "../../libs/thorvg/thorvg.h" +#include +#include +#include +#include +#include +#include + +#if LV_VG_LITE_THORVG_YUV_SUPPORT + #include +#endif + +/********************* + * DEFINES + *********************/ + +#define TVG_CANVAS_ENGINE CanvasEngine::Sw +#define TVG_COLOR(COLOR) B(COLOR), G(COLOR), R(COLOR), A(COLOR) +#define TVG_IS_VG_FMT_SUPPORT(fmt) ((fmt) == VG_LITE_BGRA8888 || (fmt) == VG_LITE_BGRX8888) + +#define TVG_CHECK_RETURN_VG_ERROR(FUNC) \ + do { \ + Result res = FUNC; \ + if (res != Result::Success) { \ + LV_LOG_ERROR("Executed '" #FUNC "' error: %d", (int)res); \ + return vg_lite_error_conv(res); \ + } \ + } while (0) +#define TVG_CHECK_RETURN_RESULT(FUNC) \ + do { \ + Result res = FUNC; \ + if (res != Result::Success) { \ + LV_LOG_ERROR("Executed '" #FUNC "' error: %d", (int)res);\ + return res; \ + } \ + } while (0) + +/* clang-format off */ + +#define IS_INDEX_FMT(fmt) \ + ((fmt) == VG_LITE_INDEX_1 \ + || (fmt) == VG_LITE_INDEX_2 \ + || (fmt) == VG_LITE_INDEX_4 \ + || (fmt) == VG_LITE_INDEX_8) + +#define VLC_GET_ARG(CUR, INDEX) vlc_get_arg((cur + (INDEX) * fmt_len), path->format); +#define VLC_GET_OP_CODE(ptr) (*((uint8_t*)ptr)) +#define VLC_OP_ARG_LEN(OP, LEN) \ + case VLC_OP_##OP: \ + return (LEN) + +#define A(color) ((color) >> 24) +#define R(color) (((color) & 0x00ff0000) >> 16) +#define G(color) (((color) & 0x0000ff00) >> 8) +#define B(color) ((color) & 0xff) +#define ARGB(a, r, g, b) ((a) << 24) | ((r) << 16) | ((g) << 8) | (b) +#define MIN(a, b) (a) > (b) ? (b) : (a) +#define MAX(a, b) (a) > (b) ? (a) : (b) +#define UDIV255(x) (((x) * 0x8081U) >> 0x17) +#define LERP(v1, v2, w) ((v1) * (w) + (v2) * (1.0f - (w))) +#define CLAMP(x, min, max) (((x) < (min)) ? (min) : ((x) > (max)) ? (max) : (x)) +#define COLOR_FROM_RAMP(ColorRamp) (((vg_lite_float_t*)ColorRamp) + 1) + +#define VG_LITE_RETURN_ERROR(func) \ + if ((error = func) != VG_LITE_SUCCESS) \ + return error + +#define VG_LITE_ALIGN(number, align_bytes) \ + (((number) + ((align_bytes)-1)) & ~((align_bytes)-1)) + +#define VG_LITE_IS_ALIGNED(num, align) (((uintptr_t)(num) & ((align)-1)) == 0) + +#define VG_LITE_IS_ALPHA_FORMAT(format) \ + ((format) == VG_LITE_A8 || (format) == VG_LITE_A4) + +/* clang-format on */ + +/********************** + * TYPEDEFS + **********************/ + +using namespace tvg; + +#pragma pack(1) +typedef struct { + uint8_t blue; + uint8_t green; + uint8_t red; +} vg_color24_t; + +typedef struct { + uint16_t blue : 5; + uint16_t green : 6; + uint16_t red : 5; +} vg_color16_t; + +typedef struct { + vg_color16_t c; + uint8_t alpha; +} vg_color16_alpha_t; + +typedef struct { + uint8_t blue; + uint8_t green; + uint8_t red; + uint8_t alpha; +} vg_color32_t; + +typedef struct { + vg_lite_float_t x; + vg_lite_float_t y; +} vg_lite_fpoint_t; + +#pragma pack() + +class vg_lite_ctx +{ + public: + std::unique_ptr canvas; + void * target_buffer; + void * tvg_target_buffer; + vg_lite_uint32_t target_px_size; + vg_lite_buffer_format_t target_format; + vg_lite_rectangle_t scissor_rect; + bool scissor_is_set; + + public: + vg_lite_ctx() + : target_buffer { nullptr } + , tvg_target_buffer { nullptr } + , target_px_size { 0 } + , target_format { VG_LITE_BGRA8888 } + , scissor_rect { 0, 0, 0, 0 } + , scissor_is_set { false } + , clut_2colors { 0 } + , clut_4colors { 0 } + , clut_16colors { 0 } + , clut_256colors { 0 } + { + canvas = SwCanvas::gen(); + } + + vg_lite_uint32_t * get_image_buffer(vg_lite_uint32_t w, vg_lite_uint32_t h) + { + src_buffer.resize(w * h); + return src_buffer.data(); + } + + vg_lite_uint32_t * get_temp_target_buffer(vg_lite_uint32_t w, vg_lite_uint32_t h) + { + vg_lite_uint32_t px_size = w * h; + if(px_size > dest_buffer.size()) { + dest_buffer.resize(w * h); + } + return dest_buffer.data(); + } + + vg_lite_uint32_t * get_temp_target_buffer() + { + return dest_buffer.data(); + } + + void set_CLUT(vg_lite_uint32_t count, const vg_lite_uint32_t * colors) + { + switch(count) { + case 2: + memcpy(clut_2colors, colors, sizeof(clut_2colors)); + break; + case 4: + memcpy(clut_4colors, colors, sizeof(clut_4colors)); + break; + case 16: + memcpy(clut_16colors, colors, sizeof(clut_16colors)); + break; + case 256: + memcpy(clut_256colors, colors, sizeof(clut_256colors)); + break; + default: + LV_ASSERT(false); + break; + } + } + + const vg_lite_uint32_t * get_CLUT(vg_lite_buffer_format_t format) + { + switch(format) { + case VG_LITE_INDEX_1: + return clut_2colors; + + case VG_LITE_INDEX_2: + return clut_2colors; + + case VG_LITE_INDEX_4: + return clut_4colors; + + case VG_LITE_INDEX_8: + return clut_256colors; + + default: + break; + } + + LV_ASSERT(false); + return nullptr; + } + + static vg_lite_ctx * get_instance() + { + static vg_lite_ctx instance; + return &instance; + } + + private: + /* */ + std::vector src_buffer; + std::vector dest_buffer; + + vg_lite_uint32_t clut_2colors[2]; + vg_lite_uint32_t clut_4colors[4]; + vg_lite_uint32_t clut_16colors[16]; + vg_lite_uint32_t clut_256colors[256]; +}; + +template +class vg_lite_converter +{ + public: + typedef void (*converter_cb_t)(DEST_TYPE * dest, const SRC_TYPE * src, vg_lite_uint32_t px_size, + vg_lite_uint32_t color); + + public: + vg_lite_converter(converter_cb_t converter) + : _converter_cb(converter) + { + } + + void convert(vg_lite_buffer_t * dest_buf, const vg_lite_buffer_t * src_buf, vg_lite_uint32_t color = 0) + { + LV_ASSERT(_converter_cb); + uint8_t * dest = (uint8_t *)dest_buf->memory; + const uint8_t * src = (const uint8_t *)src_buf->memory; + vg_lite_uint32_t h = src_buf->height; + + while(h--) { + _converter_cb((DEST_TYPE *)dest, (const SRC_TYPE *)src, src_buf->width, color); + dest += dest_buf->stride; + src += src_buf->stride; + } + } + + private: + converter_cb_t _converter_cb; +}; + +typedef vg_lite_float_t FLOATVECTOR4[4]; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static vg_lite_error_t vg_lite_error_conv(Result result); +static Matrix matrix_conv(const vg_lite_matrix_t * matrix); +static FillRule fill_rule_conv(vg_lite_fill_t fill); +static BlendMethod blend_method_conv(vg_lite_blend_t blend); +static StrokeCap stroke_cap_conv(vg_lite_cap_style_t cap); +static StrokeJoin stroke_join_conv(vg_lite_join_style_t join); +static FillSpread fill_spread_conv(vg_lite_gradient_spreadmode_t spread); +static Result shape_append_path(std::unique_ptr & shape, vg_lite_path_t * path, vg_lite_matrix_t * matrix); +static Result shape_append_rect(std::unique_ptr & shape, const vg_lite_buffer_t * target, + const vg_lite_rectangle_t * rect); +static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target); +static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture, const vg_lite_buffer_t * source, + vg_lite_color_t color = 0); + +static inline bool math_zero(float a) +{ + return (fabs(a) < FLT_EPSILON); +} + +static inline bool math_equal(float a, float b) +{ + return math_zero(a - b); +} + +static void ClampColor(FLOATVECTOR4 Source, FLOATVECTOR4 Target, uint8_t Premultiplied); +static uint8_t PackColorComponent(vg_lite_float_t value); +static void get_format_bytes(vg_lite_buffer_format_t format, + vg_lite_uint32_t * mul, + vg_lite_uint32_t * div, + vg_lite_uint32_t * bytes_align); + +static vg_lite_fpoint_t matrix_transform_point(const vg_lite_matrix_t * matrix, const vg_lite_fpoint_t * point); +static bool vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix); +static void vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult); + +/********************** + * STATIC VARIABLES + **********************/ + +/* color converters */ + +static vg_lite_converter conv_bgra8888_to_bgr565( + [](vg_color16_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + dest->red = src->red * 0x1F / 0xFF; + dest->green = src->green * 0x3F / 0xFF; + dest->blue = src->blue * 0x1F / 0xFF; + src++; + dest++; + } +}); + +static vg_lite_converter conv_bgra8888_to_bgra5658( + [](vg_color16_alpha_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + dest->c.red = src->red * 0x1F / 0xFF; + dest->c.green = src->green * 0x3F / 0xFF; + dest->c.blue = src->blue * 0x1F / 0xFF; + dest->alpha = src->alpha; + src++; + dest++; + } +}); + +static vg_lite_converter conv_bgr565_to_bgra8888( + [](vg_color32_t * dest, const vg_color16_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + dest->red = src->red * 0xFF / 0x1F; + dest->green = src->green * 0xFF / 0x3F; + dest->blue = src->blue * 0xFF / 0x1F; + dest->alpha = 0xFF; + src++; + dest++; + } +}); + +static vg_lite_converter conv_bgra5658_to_bgra8888( + [](vg_color32_t * dest, const vg_color16_alpha_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + dest->red = src->c.red * 0xFF / 0x1F; + dest->green = src->c.green * 0xFF / 0x3F; + dest->blue = src->c.blue * 0xFF / 0x1F; + dest->alpha = src->alpha; + src++; + dest++; + } +}); + +static vg_lite_converter conv_bgrx8888_to_bgra8888( + [](vg_color32_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + *dest = *src; + dest->alpha = 0xFF; + dest++; + src++; + } +}); + +static vg_lite_converter conv_bgr888_to_bgra8888( + [](vg_color32_t * dest, const vg_color24_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + dest->red = src->red; + dest->green = src->green; + dest->blue = src->blue; + dest->alpha = 0xFF; + src++; + dest++; + } +}); + +static vg_lite_converter conv_alpha8_to_bgra8888( + [](vg_color32_t * dest, const uint8_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t color) +{ + while(px_size--) { + uint8_t alpha = *src; + dest->alpha = alpha; + dest->red = UDIV255(B(color) * alpha); + dest->green = UDIV255(G(color) * alpha); + dest->blue = UDIV255(R(color) * alpha); + dest++; + src++; + } +}); + +static vg_lite_converter conv_alpha4_to_bgra8888( + [](vg_color32_t * dest, const uint8_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t color) +{ + /* 1 byte -> 2 px */ + px_size /= 2; + + while(px_size--) { + /* high 4bit */ + uint8_t alpha = (*src & 0xF0); + dest->alpha = alpha; + dest->red = UDIV255(B(color) * alpha); + dest->green = UDIV255(G(color) * alpha); + dest->blue = UDIV255(R(color) * alpha); + dest++; + + /* low 4bit */ + alpha = (*src & 0x0F) << 4; + dest->alpha = alpha; + dest->red = UDIV255(B(color) * alpha); + dest->green = UDIV255(G(color) * alpha); + dest->blue = UDIV255(R(color) * alpha); + + dest++; + src++; + } +}); + +static vg_lite_converter conv_l8_to_bgra8888( + [](vg_color32_t * dest, const uint8_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + dest->alpha = 0xFF; + dest->red = *src; + dest->green = *src; + dest->blue = *src; + dest++; + src++; + } +}); + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +extern "C" { + + void gpu_init(void) + { + vg_lite_init(0, 0); + } + + vg_lite_error_t vg_lite_allocate(vg_lite_buffer_t * buffer) + { + if(buffer->format == VG_LITE_RGBA8888_ETC2_EAC && (buffer->width % 16 || buffer->height % 4)) { + return VG_LITE_INVALID_ARGUMENT; + } + + /* Reset planar. */ + buffer->yuv.uv_planar = buffer->yuv.v_planar = buffer->yuv.alpha_planar = 0; + + /* Align height in case format is tiled. */ + if(buffer->format >= VG_LITE_YUY2 && buffer->format <= VG_LITE_NV16) { + buffer->height = VG_LITE_ALIGN(buffer->height, 4); + buffer->yuv.swizzle = VG_LITE_SWIZZLE_UV; + } + + if(buffer->format >= VG_LITE_YUY2_TILED && buffer->format <= VG_LITE_AYUY2_TILED) { + buffer->height = VG_LITE_ALIGN(buffer->height, 4); + buffer->tiled = VG_LITE_TILED; + buffer->yuv.swizzle = VG_LITE_SWIZZLE_UV; + } + + vg_lite_uint32_t mul, div, align; + get_format_bytes(buffer->format, &mul, &div, &align); + vg_lite_uint32_t stride = VG_LITE_ALIGN((buffer->width * mul / div), align); + + buffer->stride = stride; + + /* Size must be multiple of align, See: https://en.cppreference.com/w/c/memory/aligned_alloc */ + size_t size = VG_LITE_ALIGN(buffer->height * stride, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN); +#ifndef _WIN32 + buffer->memory = aligned_alloc(LV_VG_LITE_THORVG_BUF_ADDR_ALIGN, size); +#else + buffer->memory = _aligned_malloc(size, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN); +#endif + LV_ASSERT(buffer->memory); + buffer->address = (vg_lite_uint32_t)(uintptr_t)buffer->memory; + buffer->handle = buffer->memory; + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_free(vg_lite_buffer_t * buffer) + { + LV_ASSERT(buffer->memory); +#ifndef _WIN32 + free(buffer->memory); +#else + _aligned_free(buffer->memory); +#endif + memset(buffer, 0, sizeof(vg_lite_buffer_t)); + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_upload_buffer(vg_lite_buffer_t * buffer, vg_lite_uint8_t * data[3], vg_lite_uint32_t stride[3]) + { + LV_UNUSED(buffer); + LV_UNUSED(data); + LV_UNUSED(stride); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_map(vg_lite_buffer_t * buffer, vg_lite_map_flag_t flag, int32_t fd) + { + LV_UNUSED(buffer); + LV_UNUSED(flag); + LV_UNUSED(fd); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_unmap(vg_lite_buffer_t * buffer) + { + LV_UNUSED(buffer); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_clear(vg_lite_buffer_t * target, vg_lite_rectangle_t * rectangle, vg_lite_color_t color) + { + auto ctx = vg_lite_ctx::get_instance(); + TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target)); + + auto shape = Shape::gen(); + TVG_CHECK_RETURN_VG_ERROR(shape_append_rect(shape, target, rectangle)); + TVG_CHECK_RETURN_VG_ERROR(shape->blend(BlendMethod::SrcOver)); + TVG_CHECK_RETURN_VG_ERROR(shape->fill(TVG_COLOR(color))); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(shape))); + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_blit(vg_lite_buffer_t * target, + vg_lite_buffer_t * source, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color, + vg_lite_filter_t filter) + { + LV_UNUSED(filter); + auto ctx = vg_lite_ctx::get_instance(); + canvas_set_target(ctx, target); + + auto picture = Picture::gen(); + + TVG_CHECK_RETURN_VG_ERROR(picture_load(ctx, picture, source, color)); + TVG_CHECK_RETURN_VG_ERROR(picture->transform(matrix_conv(matrix))); + TVG_CHECK_RETURN_VG_ERROR(picture->blend(blend_method_conv(blend))); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(picture))); + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_blit2(vg_lite_buffer_t * target, + vg_lite_buffer_t * source0, + vg_lite_buffer_t * source1, + vg_lite_matrix_t * matrix0, + vg_lite_matrix_t * matrix1, + vg_lite_blend_t blend, + vg_lite_filter_t filter) + { + if(!vg_lite_query_feature(gcFEATURE_BIT_VG_DOUBLE_IMAGE)) { + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t error; + + VG_LITE_RETURN_ERROR(vg_lite_blit(target, source0, matrix0, blend, 0, filter)); + VG_LITE_RETURN_ERROR(vg_lite_blit(target, source1, matrix1, blend, 0, filter)); + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_blit_rect(vg_lite_buffer_t * target, + vg_lite_buffer_t * source, + vg_lite_rectangle_t * rect, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color, + vg_lite_filter_t filter) + { + LV_UNUSED(filter); + auto ctx = vg_lite_ctx::get_instance(); + TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target)); + + auto shape = Shape::gen(); + TVG_CHECK_RETURN_VG_ERROR(shape_append_rect(shape, target, rect)); + TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(matrix))); + + auto picture = tvg::Picture::gen(); + TVG_CHECK_RETURN_VG_ERROR(picture_load(ctx, picture, source, color)); + TVG_CHECK_RETURN_VG_ERROR(picture->transform(matrix_conv(matrix))); + TVG_CHECK_RETURN_VG_ERROR(picture->blend(blend_method_conv(blend))); + TVG_CHECK_RETURN_VG_ERROR(picture->composite(std::move(shape), CompositeMethod::ClipPath)); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(picture))); + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_init(int32_t tessellation_width, int32_t tessellation_height) + { + LV_UNUSED(tessellation_width); + LV_UNUSED(tessellation_height); +#if LV_VG_LITE_THORVG_THREAD_RENDER + /* Threads Count */ + auto threads = std::thread::hardware_concurrency(); + if(threads > 0) { + --threads; /* Allow the designated main thread capacity */ + } +#endif + + /* Initialize ThorVG Engine */ + TVG_CHECK_RETURN_VG_ERROR(Initializer::init(TVG_CANVAS_ENGINE, 0)); + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_close(void) + { + TVG_CHECK_RETURN_VG_ERROR(Initializer::term(TVG_CANVAS_ENGINE)); + return VG_LITE_SUCCESS; + } + + static void picture_bgra8888_to_bgr565(vg_color16_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) + { + while(px_size--) { + dest->red = src->red * 0x1F / 0xFF; + dest->green = src->green * 0x3F / 0xFF; + dest->blue = src->blue * 0x1F / 0xFF; + src++; + dest++; + } + } + + static void picture_bgra8888_to_bgra5658(vg_color16_alpha_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) + { + while(px_size--) { + dest->c.red = src->red * 0x1F / 0xFF; + dest->c.green = src->green * 0x3F / 0xFF; + dest->c.blue = src->blue * 0x1F / 0xFF; + dest->alpha = src->alpha; + src++; + dest++; + } + } + + static void picture_bgra8888_to_bgr888(vg_color24_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) + { + while(px_size--) { + dest->red = src->red; + dest->green = src->green; + dest->blue = src->blue; + src++; + dest++; + } + } + + static void picture_bgra8888_to_l8(uint8_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) + { + while(px_size--) { + *dest = (src->red * 19595 + src->green * 38469 + src->blue * 7472) >> 16; + src++; + dest++; + } + } + + static void picture_bgra8888_to_alpha8(uint8_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) + { + while(px_size--) { + *dest = src->alpha; + src++; + dest++; + } + } + + vg_lite_error_t vg_lite_finish(void) + { + vg_lite_ctx * ctx = vg_lite_ctx::get_instance(); + + if(ctx->canvas->draw() == Result::InsufficientCondition) { + return VG_LITE_SUCCESS; + } + + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->sync()); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->clear(true)); + + /* make sure target buffer is valid */ + LV_ASSERT_NULL(ctx->target_buffer); + + /* If target_buffer is not in a format supported by thorvg, software conversion is required. */ + switch(ctx->target_format) { + case VG_LITE_BGR565: + picture_bgra8888_to_bgr565( + (vg_color16_t *)ctx->target_buffer, + (const vg_color32_t *)ctx->get_temp_target_buffer(), + ctx->target_px_size); + break; + case VG_LITE_BGRA5658: + picture_bgra8888_to_bgra5658( + (vg_color16_alpha_t *)ctx->target_buffer, + (const vg_color32_t *)ctx->get_temp_target_buffer(), + ctx->target_px_size); + break; + case VG_LITE_BGR888: + picture_bgra8888_to_bgr888( + (vg_color24_t *)ctx->target_buffer, + (const vg_color32_t *)ctx->get_temp_target_buffer(), + ctx->target_px_size); + break; + case VG_LITE_L8: + picture_bgra8888_to_l8( + (uint8_t *)ctx->target_buffer, + (const vg_color32_t *)ctx->get_temp_target_buffer(), + ctx->target_px_size); + break; + case VG_LITE_A8: + picture_bgra8888_to_alpha8( + (uint8_t *)ctx->target_buffer, + (const vg_color32_t *)ctx->get_temp_target_buffer(), + ctx->target_px_size); + break; + case VG_LITE_BGRA8888: + case VG_LITE_BGRX8888: + /* No conversion required. */ + break; + default: + LV_LOG_ERROR("unsupported format: %d", ctx->target_format); + LV_ASSERT(false); + break; + } + + /* finish convert, clean target buffer info */ + ctx->target_buffer = nullptr; + ctx->tvg_target_buffer = nullptr; + ctx->target_px_size = 0; + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_flush(void) + { + return vg_lite_finish(); + } + + vg_lite_error_t vg_lite_draw(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color) + { + auto ctx = vg_lite_ctx::get_instance(); + TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target)); + + auto shape = Shape::gen(); + TVG_CHECK_RETURN_VG_ERROR(shape_append_path(shape, path, matrix)); + TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(matrix))); + TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule));); + TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend))); + TVG_CHECK_RETURN_VG_ERROR(shape->fill(TVG_COLOR(color))); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(shape))); + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_set_stroke(vg_lite_path_t * path, + vg_lite_cap_style_t cap_style, + vg_lite_join_style_t join_style, + vg_lite_float_t line_width, + vg_lite_float_t miter_limit, + vg_lite_float_t * dash_pattern, + vg_lite_uint32_t pattern_count, + vg_lite_float_t dash_phase, + vg_lite_color_t color) + { + if(!path || line_width <= 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(miter_limit < 1.0f) { + miter_limit = 1.0f; + } + + if(!path->stroke) { + path->stroke = (vg_lite_stroke_t *)lv_malloc_zeroed(sizeof(vg_lite_stroke_t)); + + if(!path->stroke) { + return VG_LITE_OUT_OF_RESOURCES; + } + } + + path->stroke->cap_style = cap_style; + path->stroke->join_style = join_style; + path->stroke->line_width = line_width; + path->stroke->miter_limit = miter_limit; + path->stroke->half_width = line_width / 2.0f; + path->stroke->miter_square = path->stroke->miter_limit * path->stroke->miter_limit; + path->stroke->dash_pattern = dash_pattern; + path->stroke->pattern_count = pattern_count; + path->stroke->dash_phase = dash_phase; + path->stroke_color = color; + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_update_stroke(vg_lite_path_t * path) + { + LV_UNUSED(path); + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_set_path_type(vg_lite_path_t * path, vg_lite_path_type_t path_type) + { + if(!path || + (path_type != VG_LITE_DRAW_FILL_PATH && + path_type != VG_LITE_DRAW_STROKE_PATH && + path_type != VG_LITE_DRAW_FILL_STROKE_PATH) + ) + return VG_LITE_INVALID_ARGUMENT; + + path->path_type = path_type; + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_get_register(vg_lite_uint32_t address, vg_lite_uint32_t * result) + { + LV_UNUSED(address); + LV_UNUSED(result); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_get_info(vg_lite_info_t * info) + { + info->api_version = VGLITE_API_VERSION_3_0; + info->header_version = VGLITE_HEADER_VERSION; + info->release_version = VGLITE_RELEASE_VERSION; + info->reserved = 0; + return VG_LITE_SUCCESS; + } + + vg_lite_uint32_t vg_lite_get_product_info(char * name, vg_lite_uint32_t * chip_id, vg_lite_uint32_t * chip_rev) + { + strcpy(name, "GCNanoLiteV"); + *chip_id = 0x265; + *chip_rev = 0x2000; + return 1; + } + + vg_lite_uint32_t vg_lite_query_feature(vg_lite_feature_t feature) + { + switch(feature) { + case gcFEATURE_BIT_VG_IM_INDEX_FORMAT: + case gcFEATURE_BIT_VG_BORDER_CULLING: + case gcFEATURE_BIT_VG_RGBA2_FORMAT: + case gcFEATURE_BIT_VG_IM_FASTCLAER: + case gcFEATURE_BIT_VG_GLOBAL_ALPHA: + case gcFEATURE_BIT_VG_COLOR_KEY: + case gcFEATURE_BIT_VG_24BIT: + case gcFEATURE_BIT_VG_DITHER: + case gcFEATURE_BIT_VG_USE_DST: + case gcFEATURE_BIT_VG_RADIAL_GRADIENT: + case gcFEATURE_BIT_VG_IM_REPEAT_REFLECT: + case gcFEATURE_BIT_VG_SCISSOR: + +#if LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT + case gcFEATURE_BIT_VG_LVGL_SUPPORT: +#endif + +#if LV_VG_LITE_THORVG_YUV_SUPPORT + case gcFEATURE_BIT_VG_YUV_INPUT: +#endif + +#if LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + case gcFEATURE_BIT_VG_LINEAR_GRADIENT_EXT: +#endif + +#if LV_VG_LITE_THORVG_16PIXELS_ALIGN + case gcFEATURE_BIT_VG_16PIXELS_ALIGN: +#endif + return 1; + default: + break; + } + return 0; + } + + vg_lite_error_t vg_lite_init_path(vg_lite_path_t * path, + vg_lite_format_t data_format, + vg_lite_quality_t quality, + vg_lite_uint32_t path_length, + void * path_data, + vg_lite_float_t min_x, vg_lite_float_t min_y, + vg_lite_float_t max_x, vg_lite_float_t max_y) + { + if(!path) { + return VG_LITE_INVALID_ARGUMENT; + } + + lv_memzero(path, sizeof(vg_lite_path_t)); + + path->format = data_format; + path->quality = quality; + path->bounding_box[0] = min_x; + path->bounding_box[1] = min_y; + path->bounding_box[2] = max_x; + path->bounding_box[3] = max_y; + + path->path_length = path_length; + path->path = path_data; + + path->path_changed = 1; + path->uploaded.address = 0; + path->uploaded.bytes = 0; + path->uploaded.handle = NULL; + path->uploaded.memory = NULL; + path->pdata_internal = 0; + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_init_arc_path(vg_lite_path_t * path, + vg_lite_format_t data_format, + vg_lite_quality_t quality, + vg_lite_uint32_t path_length, + void * path_data, + vg_lite_float_t min_x, vg_lite_float_t min_y, + vg_lite_float_t max_x, vg_lite_float_t max_y) + { + LV_UNUSED(path); + LV_UNUSED(data_format); + LV_UNUSED(quality); + LV_UNUSED(path_length); + LV_UNUSED(path_data); + LV_UNUSED(min_x); + LV_UNUSED(min_y); + LV_UNUSED(max_x); + LV_UNUSED(max_y); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_clear_path(vg_lite_path_t * path) + { + LV_ASSERT_NULL(path); + + if(path->stroke) { + lv_free(path->stroke); + path->stroke = NULL; + } + + return VG_LITE_SUCCESS; + } + + vg_lite_uint32_t vg_lite_get_path_length(vg_lite_uint8_t * opcode, + vg_lite_uint32_t count, + vg_lite_format_t format) + { + LV_UNUSED(opcode); + LV_UNUSED(count); + LV_UNUSED(format); + return 0; + } + + vg_lite_error_t vg_lite_append_path(vg_lite_path_t * path, + uint8_t * cmd, + void * data, + vg_lite_uint32_t seg_count) + { + LV_UNUSED(path); + LV_UNUSED(cmd); + LV_UNUSED(data); + LV_UNUSED(seg_count); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_upload_path(vg_lite_path_t * path) + { + LV_UNUSED(path); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_set_CLUT(vg_lite_uint32_t count, + vg_lite_uint32_t * colors) + { + if(!vg_lite_query_feature(gcFEATURE_BIT_VG_IM_INDEX_FORMAT)) { + return VG_LITE_NOT_SUPPORT; + } + LV_ASSERT(colors); + + auto ctx = vg_lite_ctx::get_instance(); + ctx->set_CLUT(count, colors); + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_draw_pattern(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_buffer_t * pattern_image, + vg_lite_matrix_t * pattern_matrix, + vg_lite_blend_t blend, + vg_lite_pattern_mode_t pattern_mode, + vg_lite_color_t pattern_color, + vg_lite_color_t color, + vg_lite_filter_t filter) + { + LV_UNUSED(pattern_mode); + LV_UNUSED(pattern_color); + LV_UNUSED(filter); + + auto ctx = vg_lite_ctx::get_instance(); + TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target)); + + auto shape = Shape::gen(); + TVG_CHECK_RETURN_VG_ERROR(shape_append_path(shape, path, path_matrix)); + TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule))); + TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(path_matrix))); + + auto picture = tvg::Picture::gen(); + TVG_CHECK_RETURN_VG_ERROR(picture_load(ctx, picture, pattern_image, color)); + TVG_CHECK_RETURN_VG_ERROR(picture->transform(matrix_conv(pattern_matrix))); + TVG_CHECK_RETURN_VG_ERROR(picture->blend(blend_method_conv(blend))); + TVG_CHECK_RETURN_VG_ERROR(picture->composite(std::move(shape), CompositeMethod::ClipPath)); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(picture))); + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_init_grad(vg_lite_linear_gradient_t * grad) + { + vg_lite_error_t error = VG_LITE_SUCCESS; + + /* Set the member values according to driver defaults. */ + grad->image.width = VLC_GRADIENT_BUFFER_WIDTH; + grad->image.height = 1; + grad->image.stride = 0; + grad->image.format = VG_LITE_BGRA8888; + + /* Allocate the image for gradient. */ + error = vg_lite_allocate(&grad->image); + + grad->count = 0; + + return error; + } + + vg_lite_error_t vg_lite_set_linear_grad(vg_lite_ext_linear_gradient_t * grad, + vg_lite_uint32_t count, + vg_lite_color_ramp_t * color_ramp, + vg_lite_linear_gradient_parameter_t linear_gradient, + vg_lite_gradient_spreadmode_t spread_mode, + vg_lite_uint8_t pre_multiplied) + { + static vg_lite_color_ramp_t default_ramp[] = { + { + 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }, + { + 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f + } + }; + + vg_lite_uint32_t i, trg_count; + vg_lite_float_t prev_stop; + vg_lite_color_ramp_t * src_ramp; + vg_lite_color_ramp_t * src_ramp_last; + vg_lite_color_ramp_t * trg_ramp; + + /* Reset the count. */ + trg_count = 0; + + if((linear_gradient.X0 == linear_gradient.X1) && (linear_gradient.Y0 == linear_gradient.Y1)) + return VG_LITE_INVALID_ARGUMENT; + + grad->linear_grad = linear_gradient; + grad->pre_multiplied = pre_multiplied; + grad->spread_mode = spread_mode; + + if(!count || count > VLC_MAX_COLOR_RAMP_STOPS || color_ramp == NULL) + goto Empty_sequence_handler; + + for(i = 0; i < count; i++) + grad->color_ramp[i] = color_ramp[i]; + grad->ramp_length = count; + + /* Determine the last source ramp. */ + src_ramp_last + = grad->color_ramp + + grad->ramp_length; + + /* Set the initial previous stop. */ + prev_stop = -1; + + /* Reset the count. */ + trg_count = 0; + + /* Walk through the source ramp. */ + for( + src_ramp = grad->color_ramp, trg_ramp = grad->converted_ramp; + (src_ramp < src_ramp_last) && (trg_count < VLC_MAX_COLOR_RAMP_STOPS + 2); + src_ramp += 1) { + /* Must be in increasing order. */ + if(src_ramp->stop < prev_stop) { + /* Ignore the entire sequence. */ + trg_count = 0; + break; + } + + /* Update the previous stop value. */ + prev_stop = src_ramp->stop; + + /* Must be within [0..1] range. */ + if((src_ramp->stop < 0.0f) || (src_ramp->stop > 1.0f)) { + /* Ignore. */ + continue; + } + + /* Clamp color. */ + ClampColor(COLOR_FROM_RAMP(src_ramp), COLOR_FROM_RAMP(trg_ramp), 0); + + /* First stop greater than zero? */ + if((trg_count == 0) && (src_ramp->stop > 0.0f)) { + /* Force the first stop to 0.0f. */ + trg_ramp->stop = 0.0f; + + /* Replicate the entry. */ + trg_ramp[1] = *trg_ramp; + trg_ramp[1].stop = src_ramp->stop; + + /* Advance. */ + trg_ramp += 2; + trg_count += 2; + } + else { + /* Set the stop value. */ + trg_ramp->stop = src_ramp->stop; + + /* Advance. */ + trg_ramp += 1; + trg_count += 1; + } + } + + /* Empty sequence? */ + if(trg_count == 0) { + memcpy(grad->converted_ramp, default_ramp, sizeof(default_ramp)); + grad->converted_length = sizeof(default_ramp) / 5; + } + else { + /* The last stop must be at 1.0. */ + if(trg_ramp[-1].stop != 1.0f) { + /* Replicate the last entry. */ + *trg_ramp = trg_ramp[-1]; + + /* Force the last stop to 1.0f. */ + trg_ramp->stop = 1.0f; + + /* Update the final entry count. */ + trg_count += 1; + } + + /* Set new length. */ + grad->converted_length = trg_count; + } + return VG_LITE_SUCCESS; + +Empty_sequence_handler: + memcpy(grad->converted_ramp, default_ramp, sizeof(default_ramp)); + grad->converted_length = sizeof(default_ramp) / 5; + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_update_linear_grad(vg_lite_ext_linear_gradient_t * grad) + { + vg_lite_uint32_t ramp_length; + vg_lite_color_ramp_t * color_ramp; + vg_lite_uint32_t common, stop; + vg_lite_uint32_t i, width; + uint8_t * bits; + vg_lite_float_t x0, y0, x1, y1, length; + vg_lite_error_t error = VG_LITE_SUCCESS; + + /* Get shortcuts to the color ramp. */ + ramp_length = grad->converted_length; + color_ramp = grad->converted_ramp; + + x0 = grad->linear_grad.X0; + y0 = grad->linear_grad.Y0; + x1 = grad->linear_grad.X1; + y1 = grad->linear_grad.Y1; + length = (vg_lite_float_t)sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)); + + if(length <= 0) + return VG_LITE_INVALID_ARGUMENT; + /* Find the common denominator of the color ramp stops. */ + if(length < 1) { + common = 1; + } + else { + common = (vg_lite_uint32_t)length; + } + + for(i = 0; i < ramp_length; ++i) { + if(color_ramp[i].stop != 0.0f) { + vg_lite_float_t mul = common * color_ramp[i].stop; + vg_lite_float_t frac = mul - (vg_lite_float_t)floor(mul); + if(frac > 0.00013f) { /* Suppose error for zero is 0.00013 */ + common = MAX(common, (vg_lite_uint32_t)(1.0f / frac + 0.5f)); + } + } + } + + /* Compute the width of the required color array. */ + width = common + 1; + + /* Allocate the color ramp surface. */ + memset(&grad->image, 0, sizeof(grad->image)); + grad->image.width = width; + grad->image.height = 1; + grad->image.stride = 0; + grad->image.image_mode = VG_LITE_NONE_IMAGE_MODE; + grad->image.format = VG_LITE_ABGR8888; + + /* Allocate the image for gradient. */ + VG_LITE_RETURN_ERROR(vg_lite_allocate(&grad->image)); + memset(grad->image.memory, 0, grad->image.stride * grad->image.height); + width = common + 1; + /* Set pointer to color array. */ + bits = (uint8_t *)grad->image.memory; + + /* Start filling the color array. */ + stop = 0; + for(i = 0; i < width; ++i) { + vg_lite_float_t gradient; + vg_lite_float_t color[4]; + vg_lite_float_t color1[4]; + vg_lite_float_t color2[4]; + vg_lite_float_t weight; + + if(i == 241) + i = 241; + /* Compute gradient for current color array entry. */ + gradient = (vg_lite_float_t)i / (vg_lite_float_t)(width - 1); + + /* Find the entry in the color ramp that matches or exceeds this + ** gradient. */ + while(gradient > color_ramp[stop].stop) { + ++stop; + } + + if(gradient == color_ramp[stop].stop) { + /* Perfect match weight 1.0. */ + weight = 1.0f; + + /* Use color ramp color. */ + color1[3] = color_ramp[stop].alpha; + color1[2] = color_ramp[stop].blue; + color1[1] = color_ramp[stop].green; + color1[0] = color_ramp[stop].red; + + color2[3] = color2[2] = color2[1] = color2[0] = 0.0f; + } + else { + if(stop == 0) { + return VG_LITE_INVALID_ARGUMENT; + } + /* Compute weight. */ + weight = (color_ramp[stop].stop - gradient) + / (color_ramp[stop].stop - color_ramp[stop - 1].stop); + + /* Grab color ramp color of previous stop. */ + color1[3] = color_ramp[stop - 1].alpha; + color1[2] = color_ramp[stop - 1].blue; + color1[1] = color_ramp[stop - 1].green; + color1[0] = color_ramp[stop - 1].red; + + /* Grab color ramp color of current stop. */ + color2[3] = color_ramp[stop].alpha; + color2[2] = color_ramp[stop].blue; + color2[1] = color_ramp[stop].green; + color2[0] = color_ramp[stop].red; + } + + if(grad->pre_multiplied) { + /* Pre-multiply the first color. */ + color1[2] *= color1[3]; + color1[1] *= color1[3]; + color1[0] *= color1[3]; + + /* Pre-multiply the second color. */ + color2[2] *= color2[3]; + color2[1] *= color2[3]; + color2[0] *= color2[3]; + } + + /* Filter the colors per channel. */ + color[3] = LERP(color1[3], color2[3], weight); + color[2] = LERP(color1[2], color2[2], weight); + color[1] = LERP(color1[1], color2[1], weight); + color[0] = LERP(color1[0], color2[0], weight); + + /* Pack the final color. */ + *bits++ = PackColorComponent(color[3]); + *bits++ = PackColorComponent(color[2]); + *bits++ = PackColorComponent(color[1]); + *bits++ = PackColorComponent(color[0]); + } + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_draw_linear_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_ext_linear_gradient_t * grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter) + { + LV_UNUSED(paint_color); + LV_UNUSED(filter); + + auto ctx = vg_lite_ctx::get_instance(); + TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target)); + + auto shape = Shape::gen(); + TVG_CHECK_RETURN_VG_ERROR(shape_append_path(shape, path, path_matrix)); + TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(path_matrix))); + TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule));); + TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend))); + + auto linearGrad = LinearGradient::gen(); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->linear(grad->linear_grad.X0, grad->linear_grad.Y0, grad->linear_grad.X1, + grad->linear_grad.Y1)); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->transform(matrix_conv(&grad->matrix))); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->spread(fill_spread_conv(grad->spread_mode))); + + tvg::Fill::ColorStop colorStops[VLC_MAX_COLOR_RAMP_STOPS]; + for(vg_lite_uint32_t i = 0; i < grad->ramp_length; i++) { + colorStops[i].offset = grad->color_ramp[i].stop; + colorStops[i].r = grad->color_ramp[i].red * 255.0f; + colorStops[i].g = grad->color_ramp[i].green * 255.0f; + colorStops[i].b = grad->color_ramp[i].blue * 255.0f; + colorStops[i].a = grad->color_ramp[i].alpha * 255.0f; + } + TVG_CHECK_RETURN_VG_ERROR(linearGrad->colorStops(colorStops, grad->ramp_length)); + + TVG_CHECK_RETURN_VG_ERROR(shape->fill(std::move(linearGrad))); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(shape))); + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_set_radial_grad(vg_lite_radial_gradient_t * grad, + vg_lite_uint32_t count, + vg_lite_color_ramp_t * color_ramp, + vg_lite_radial_gradient_parameter_t radial_grad, + vg_lite_gradient_spreadmode_t spread_mode, + vg_lite_uint8_t pre_multiplied) + { + static vg_lite_color_ramp_t defaultRamp[] = { + { + 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }, + { + 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f + } + }; + + vg_lite_uint32_t i, trgCount; + vg_lite_float_t prevStop; + vg_lite_color_ramp_t * srcRamp; + vg_lite_color_ramp_t * srcRampLast; + vg_lite_color_ramp_t * trgRamp; + + /* Reset the count. */ + trgCount = 0; + + if(radial_grad.r <= 0) + return VG_LITE_INVALID_ARGUMENT; + + grad->radial_grad = radial_grad; + grad->pre_multiplied = pre_multiplied; + grad->spread_mode = spread_mode; + + if(!count || count > VLC_MAX_COLOR_RAMP_STOPS || color_ramp == NULL) + goto Empty_sequence_handler; + + for(i = 0; i < count; i++) + grad->color_ramp[i] = color_ramp[i]; + grad->ramp_length = count; + + /* Determine the last source ramp. */ + srcRampLast + = grad->color_ramp + + grad->ramp_length; + + /* Set the initial previous stop. */ + prevStop = -1; + + /* Reset the count. */ + trgCount = 0; + + /* Walk through the source ramp. */ + for( + srcRamp = grad->color_ramp, trgRamp = grad->converted_ramp; + (srcRamp < srcRampLast) && (trgCount < VLC_MAX_COLOR_RAMP_STOPS + 2); + srcRamp += 1) { + /* Must be in increasing order. */ + if(srcRamp->stop < prevStop) { + /* Ignore the entire sequence. */ + trgCount = 0; + break; + } + + /* Update the previous stop value. */ + prevStop = srcRamp->stop; + + /* Must be within [0..1] range. */ + if((srcRamp->stop < 0.0f) || (srcRamp->stop > 1.0f)) { + /* Ignore. */ + continue; + } + + /* Clamp color. */ + ClampColor(COLOR_FROM_RAMP(srcRamp), COLOR_FROM_RAMP(trgRamp), 0); + + /* First stop greater than zero? */ + if((trgCount == 0) && (srcRamp->stop > 0.0f)) { + /* Force the first stop to 0.0f. */ + trgRamp->stop = 0.0f; + + /* Replicate the entry. */ + trgRamp[1] = *trgRamp; + trgRamp[1].stop = srcRamp->stop; + + /* Advance. */ + trgRamp += 2; + trgCount += 2; + } + else { + /* Set the stop value. */ + trgRamp->stop = srcRamp->stop; + + /* Advance. */ + trgRamp += 1; + trgCount += 1; + } + } + + /* Empty sequence? */ + if(trgCount == 0) { + memcpy(grad->converted_ramp, defaultRamp, sizeof(defaultRamp)); + grad->converted_length = sizeof(defaultRamp) / 5; + } + else { + /* The last stop must be at 1.0. */ + if(trgRamp[-1].stop != 1.0f) { + /* Replicate the last entry. */ + *trgRamp = trgRamp[-1]; + + /* Force the last stop to 1.0f. */ + trgRamp->stop = 1.0f; + + /* Update the final entry count. */ + trgCount += 1; + } + + /* Set new length. */ + grad->converted_length = trgCount; + } + return VG_LITE_SUCCESS; + +Empty_sequence_handler: + memcpy(grad->converted_ramp, defaultRamp, sizeof(defaultRamp)); + grad->converted_length = sizeof(defaultRamp) / 5; + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_update_radial_grad(vg_lite_radial_gradient_t * grad) + { + vg_lite_uint32_t ramp_length; + vg_lite_color_ramp_t * colorRamp; + vg_lite_uint32_t common, stop; + vg_lite_uint32_t i, width; + uint8_t * bits; + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_uint32_t align, mul, div; + + /* Get shortcuts to the color ramp. */ + ramp_length = grad->converted_length; + colorRamp = grad->converted_ramp; + + if(grad->radial_grad.r <= 0) + return VG_LITE_INVALID_ARGUMENT; + + /* Find the common denominator of the color ramp stops. */ + if(grad->radial_grad.r < 1) { + common = 1; + } + else { + common = (vg_lite_uint32_t)grad->radial_grad.r; + } + + for(i = 0; i < ramp_length; ++i) { + if(colorRamp[i].stop != 0.0f) { + vg_lite_float_t m = common * colorRamp[i].stop; + vg_lite_float_t frac = m - (vg_lite_float_t)floor(m); + if(frac > 0.00013f) { /* Suppose error for zero is 0.00013 */ + common = MAX(common, (vg_lite_uint32_t)(1.0f / frac + 0.5f)); + } + } + } + + /* Compute the width of the required color array. */ + width = common + 1; + width = (width + 15) & (~0xf); + + /* Allocate the color ramp surface. */ + memset(&grad->image, 0, sizeof(grad->image)); + grad->image.width = width; + grad->image.height = 1; + grad->image.stride = 0; + grad->image.image_mode = VG_LITE_NONE_IMAGE_MODE; + grad->image.format = VG_LITE_ABGR8888; + + /* Allocate the image for gradient. */ + VG_LITE_RETURN_ERROR(vg_lite_allocate(&grad->image)); + + get_format_bytes(VG_LITE_ABGR8888, &mul, &div, &align); + width = grad->image.stride * div / mul; + + /* Set pointer to color array. */ + bits = (uint8_t *)grad->image.memory; + + /* Start filling the color array. */ + stop = 0; + for(i = 0; i < width; ++i) { + vg_lite_float_t gradient; + vg_lite_float_t color[4]; + vg_lite_float_t color1[4]; + vg_lite_float_t color2[4]; + vg_lite_float_t weight; + + /* Compute gradient for current color array entry. */ + gradient = (vg_lite_float_t)i / (vg_lite_float_t)(width - 1); + + /* Find the entry in the color ramp that matches or exceeds this + ** gradient. */ + while(gradient > colorRamp[stop].stop) { + ++stop; + } + + if(gradient == colorRamp[stop].stop) { + /* Perfect match weight 1.0. */ + weight = 1.0f; + + /* Use color ramp color. */ + color1[3] = colorRamp[stop].alpha; + color1[2] = colorRamp[stop].blue; + color1[1] = colorRamp[stop].green; + color1[0] = colorRamp[stop].red; + + color2[3] = color2[2] = color2[1] = color2[0] = 0.0f; + } + else { + /* Compute weight. */ + weight = (colorRamp[stop].stop - gradient) + / (colorRamp[stop].stop - colorRamp[stop - 1].stop); + + /* Grab color ramp color of previous stop. */ + color1[3] = colorRamp[stop - 1].alpha; + color1[2] = colorRamp[stop - 1].blue; + color1[1] = colorRamp[stop - 1].green; + color1[0] = colorRamp[stop - 1].red; + + /* Grab color ramp color of current stop. */ + color2[3] = colorRamp[stop].alpha; + color2[2] = colorRamp[stop].blue; + color2[1] = colorRamp[stop].green; + color2[0] = colorRamp[stop].red; + } + + if(grad->pre_multiplied) { + /* Pre-multiply the first color. */ + color1[2] *= color1[3]; + color1[1] *= color1[3]; + color1[0] *= color1[3]; + + /* Pre-multiply the second color. */ + color2[2] *= color2[3]; + color2[1] *= color2[3]; + color2[0] *= color2[3]; + } + + /* Filter the colors per channel. */ + color[3] = LERP(color1[3], color2[3], weight); + color[2] = LERP(color1[2], color2[2], weight); + color[1] = LERP(color1[1], color2[1], weight); + color[0] = LERP(color1[0], color2[0], weight); + + /* Pack the final color. */ + *bits++ = PackColorComponent(color[3]); + *bits++ = PackColorComponent(color[2]); + *bits++ = PackColorComponent(color[1]); + *bits++ = PackColorComponent(color[0]); + } + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_set_grad(vg_lite_linear_gradient_t * grad, + vg_lite_uint32_t count, + vg_lite_uint32_t * colors, + vg_lite_uint32_t * stops) + { + vg_lite_uint32_t i; + + grad->count = 0; /* Opaque B&W gradient */ + if(!count || count > VLC_MAX_GRADIENT_STOPS || colors == NULL || stops == NULL) + return VG_LITE_SUCCESS; + + /* Check stops validity */ + for(i = 0; i < count; i++) + if(stops[i] < VLC_GRADIENT_BUFFER_WIDTH) { + if(!grad->count || stops[i] > grad->stops[grad->count - 1]) { + grad->stops[grad->count] = stops[i]; + grad->colors[grad->count] = colors[i]; + grad->count++; + } + else if(stops[i] == grad->stops[grad->count - 1]) { + /* Equal stops : use the color corresponding to the last stop + in the sequence */ + grad->colors[grad->count - 1] = colors[i]; + } + } + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_update_grad(vg_lite_linear_gradient_t * grad) + { + vg_lite_error_t error = VG_LITE_SUCCESS; + int32_t r0, g0, b0, a0; + int32_t r1, g1, b1, a1; + int32_t lr, lg, lb, la; + vg_lite_uint32_t i; + int32_t j; + int32_t ds, dr, dg, db, da; + vg_lite_uint32_t * buffer = (vg_lite_uint32_t *)grad->image.memory; + + if(grad->count == 0) { + /* If no valid stops have been specified (e.g., due to an empty input + * array, out-of-range, or out-of-order stops), a stop at 0 with color + * 0xFF000000 (opaque black) and a stop at 255 with color 0xFFFFFFFF + * (opaque white) are implicitly defined. */ + grad->stops[0] = 0; + grad->colors[0] = 0xFF000000; /* Opaque black */ + grad->stops[1] = 255; + grad->colors[1] = 0xFFFFFFFF; /* Opaque white */ + grad->count = 2; + } + else if(grad->count && grad->stops[0] != 0) { + /* If at least one valid stop has been specified, but none has been + * defined with an offset of 0, an implicit stop is added with an + * offset of 0 and the same color as the first user-defined stop. */ + for(i = 0; i < grad->stops[0]; i++) + buffer[i] = grad->colors[0]; + } + a0 = A(grad->colors[0]); + r0 = R(grad->colors[0]); + g0 = G(grad->colors[0]); + b0 = B(grad->colors[0]); + + /* Calculate the colors for each pixel of the image. */ + for(i = 0; i < grad->count - 1; i++) { + buffer[grad->stops[i]] = grad->colors[i]; + ds = grad->stops[i + 1] - grad->stops[i]; + a1 = A(grad->colors[i + 1]); + r1 = R(grad->colors[i + 1]); + g1 = G(grad->colors[i + 1]); + b1 = B(grad->colors[i + 1]); + + da = a1 - a0; + dr = r1 - r0; + dg = g1 - g0; + db = b1 - b0; + + for(j = 1; j < ds; j++) { + la = a0 + da * j / ds; + lr = r0 + dr * j / ds; + lg = g0 + dg * j / ds; + lb = b0 + db * j / ds; + + buffer[grad->stops[i] + j] = ARGB(la, lr, lg, lb); + } + + a0 = a1; + r0 = r1; + g0 = g1; + b0 = b1; + } + + /* If at least one valid stop has been specified, but none has been defined + * with an offset of 255, an implicit stop is added with an offset of 255 + * and the same color as the last user-defined stop. */ + for(i = grad->stops[grad->count - 1]; i < VLC_GRADIENT_BUFFER_WIDTH; i++) + buffer[i] = grad->colors[grad->count - 1]; + + return error; + } + + vg_lite_error_t vg_lite_clear_linear_grad(vg_lite_ext_linear_gradient_t * grad) + { + vg_lite_error_t error = VG_LITE_SUCCESS; + + grad->count = 0; + /* Release the image resource. */ + if(grad->image.handle != NULL) { + error = vg_lite_free(&grad->image); + } + + return error; + } + + vg_lite_error_t vg_lite_clear_grad(vg_lite_linear_gradient_t * grad) + { + vg_lite_error_t error = VG_LITE_SUCCESS; + + grad->count = 0; + /* Release the image resource. */ + if(grad->image.handle != NULL) { + error = vg_lite_free(&grad->image); + } + + return error; + } + + vg_lite_error_t vg_lite_clear_radial_grad(vg_lite_radial_gradient_t * grad) + { + vg_lite_error_t error = VG_LITE_SUCCESS; + + grad->count = 0; + /* Release the image resource. */ + if(grad->image.handle != NULL) { + error = vg_lite_free(&grad->image); + } + + return error; + } + + vg_lite_matrix_t * vg_lite_get_linear_grad_matrix(vg_lite_ext_linear_gradient_t * grad) + { + return &grad->matrix; + } + + vg_lite_matrix_t * vg_lite_get_grad_matrix(vg_lite_linear_gradient_t * grad) + { + return &grad->matrix; + } + + vg_lite_matrix_t * vg_lite_get_radial_grad_matrix(vg_lite_radial_gradient_t * grad) + { + return &grad->matrix; + } + + vg_lite_error_t vg_lite_draw_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * matrix, + vg_lite_linear_gradient_t * grad, + vg_lite_blend_t blend) + { + auto ctx = vg_lite_ctx::get_instance(); + TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target)); + + auto shape = Shape::gen(); + TVG_CHECK_RETURN_VG_ERROR(shape_append_path(shape, path, matrix)); + TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(matrix))); + TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule));); + TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend))); + + vg_lite_matrix_t grad_matrix; + vg_lite_identity(&grad_matrix); + vg_lite_matrix_inverse(&grad_matrix, matrix); + vg_lite_matrix_multiply(&grad_matrix, &grad->matrix); + + vg_lite_fpoint_t p1 = {0.0f, 0.0f}; + vg_lite_fpoint_t p2 = {1.0f, 0}; + + vg_lite_fpoint_t p1_trans = p1; + vg_lite_fpoint_t p2_trans = p2; + + p1_trans = matrix_transform_point(&grad_matrix, &p1); + p2_trans = matrix_transform_point(&grad_matrix, &p2); + float dx = (p2_trans.x - p1_trans.x); + float dy = (p2_trans.y - p1_trans.y); + float scale = sqrtf(dx * dx + dy * dy); + float angle = (float)(atan2f(dy, dx)); + float dlen = 256 * scale; + float x_min = grad_matrix.m[0][2]; + float y_min = grad_matrix.m[1][2]; + float x_max = x_min + dlen * cosf(angle); + float y_max = y_min + dlen * sinf(angle); + LV_LOG_TRACE("linear gradient {%.2f, %.2f} ~ {%.2f, %.2f}", x_min, y_min, x_max, y_max); + auto linearGrad = LinearGradient::gen(); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->linear(x_min, y_min, x_max, y_max)); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->spread(FillSpread::Pad)); + + tvg::Fill::ColorStop colorStops[VLC_MAX_GRADIENT_STOPS]; + for(vg_lite_uint32_t i = 0; i < grad->count; i++) { + colorStops[i].offset = grad->stops[i] / 255.0f; + colorStops[i].r = R(grad->colors[i]); + colorStops[i].g = G(grad->colors[i]); + colorStops[i].b = B(grad->colors[i]); + colorStops[i].a = A(grad->colors[i]); + } + TVG_CHECK_RETURN_VG_ERROR(linearGrad->colorStops(colorStops, grad->count)); + + TVG_CHECK_RETURN_VG_ERROR(shape->fill(std::move(linearGrad))); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(shape))); + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_draw_radial_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_radial_gradient_t * grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter) + { + LV_UNUSED(paint_color); + LV_UNUSED(filter); + + auto ctx = vg_lite_ctx::get_instance(); + TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target)); + + auto shape = Shape::gen(); + TVG_CHECK_RETURN_VG_ERROR(shape_append_path(shape, path, path_matrix)); + TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(path_matrix))); + TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule));); + TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend))); + + auto radialGrad = RadialGradient::gen(); + TVG_CHECK_RETURN_VG_ERROR(radialGrad->transform(matrix_conv(&grad->matrix))); + TVG_CHECK_RETURN_VG_ERROR(radialGrad->radial(grad->radial_grad.cx, grad->radial_grad.cy, grad->radial_grad.r)); + TVG_CHECK_RETURN_VG_ERROR(radialGrad->spread(fill_spread_conv(grad->spread_mode))); + + tvg::Fill::ColorStop colorStops[VLC_MAX_COLOR_RAMP_STOPS]; + for(vg_lite_uint32_t i = 0; i < grad->ramp_length; i++) { + colorStops[i].offset = grad->color_ramp[i].stop; + colorStops[i].r = grad->color_ramp[i].red * 255.0f; + colorStops[i].g = grad->color_ramp[i].green * 255.0f; + colorStops[i].b = grad->color_ramp[i].blue * 255.0f; + colorStops[i].a = grad->color_ramp[i].alpha * 255.0f; + } + TVG_CHECK_RETURN_VG_ERROR(radialGrad->colorStops(colorStops, grad->ramp_length)); + + TVG_CHECK_RETURN_VG_ERROR(shape->fill(std::move(radialGrad))); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(shape))); + + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_set_command_buffer_size(vg_lite_uint32_t size) + { + LV_UNUSED(size); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_set_scissor(vg_lite_int32_t x, vg_lite_int32_t y, vg_lite_int32_t right, vg_lite_int32_t bottom) + { + auto ctx = vg_lite_ctx::get_instance(); + vg_lite_int32_t width = right - x; + vg_lite_int32_t height = bottom - y; + + if(width <= 0 || height <= 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(ctx->scissor_rect.x == x && ctx->scissor_rect.y == y && + ctx->scissor_rect.width == width && ctx->scissor_rect.height == height) { + return VG_LITE_SUCCESS; + } + + /*Finish the previous rendering before setting the new scissor*/ + vg_lite_error_t error; + VG_LITE_RETURN_ERROR(vg_lite_finish()); + + ctx->scissor_rect.x = x; + ctx->scissor_rect.y = y; + ctx->scissor_rect.width = width; + ctx->scissor_rect.height = height; + ctx->scissor_is_set = true; + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_enable_scissor(void) + { + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_disable_scissor(void) + { + return VG_LITE_SUCCESS; + } + + vg_lite_error_t vg_lite_get_mem_size(vg_lite_uint32_t * size) + { + *size = 0; + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_source_global_alpha(vg_lite_global_alpha_t alpha_mode, uint8_t alpha_value) + { + LV_UNUSED(alpha_mode); + LV_UNUSED(alpha_value); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_dest_global_alpha(vg_lite_global_alpha_t alpha_mode, uint8_t alpha_value) + { + LV_UNUSED(alpha_mode); + LV_UNUSED(alpha_value); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_set_color_key(vg_lite_color_key4_t colorkey) + { + LV_UNUSED(colorkey); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_set_flexa_stream_id(uint8_t stream_id) + { + LV_UNUSED(stream_id); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_set_flexa_current_background_buffer(uint8_t stream_id, + vg_lite_buffer_t * buffer, + vg_lite_uint32_t background_segment_count, + vg_lite_uint32_t background_segment_size) + { + LV_UNUSED(stream_id); + LV_UNUSED(buffer); + LV_UNUSED(background_segment_count); + LV_UNUSED(background_segment_size); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_enable_flexa(void) + { + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_disable_flexa(void) + { + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_set_flexa_stop_frame(void) + { + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_enable_dither(void) + { + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_disable_dither(void) + { + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_set_tess_buffer(vg_lite_uint32_t physical, vg_lite_uint32_t size) + { + LV_UNUSED(physical); + LV_UNUSED(size); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_set_command_buffer(vg_lite_uint32_t physical, vg_lite_uint32_t size) + { + LV_UNUSED(physical); + LV_UNUSED(size); + return VG_LITE_NOT_SUPPORT; + } + + vg_lite_error_t vg_lite_get_parameter(vg_lite_param_type_t type, + vg_lite_int32_t count, + vg_lite_float_t * params) + { + switch(type) { + case VG_LITE_GPU_IDLE_STATE: + if(count != 1 || params == NULL) { + return VG_LITE_INVALID_ARGUMENT; + } + + *(vg_lite_uint32_t *)params = 1; + return VG_LITE_SUCCESS; + + default: + break; + } + + return VG_LITE_NOT_SUPPORT; + } +} /* extern "C" */ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static vg_lite_error_t vg_lite_error_conv(Result result) +{ + switch(result) { + case Result::Success: + return VG_LITE_SUCCESS; + + case Result::InvalidArguments: + return VG_LITE_INVALID_ARGUMENT; + + case Result::InsufficientCondition: + return VG_LITE_OUT_OF_RESOURCES; + + case Result::FailedAllocation: + return VG_LITE_OUT_OF_MEMORY; + + case Result::NonSupport: + return VG_LITE_NOT_SUPPORT; + + default: + break; + } + + return VG_LITE_TIMEOUT; +} + +static Matrix matrix_conv(const vg_lite_matrix_t * matrix) +{ + return *(Matrix *)matrix; +} + +static FillRule fill_rule_conv(vg_lite_fill_t fill) +{ + if(fill == VG_LITE_FILL_EVEN_ODD) { + return FillRule::EvenOdd; + } + + return FillRule::Winding; +} + +static BlendMethod blend_method_conv(vg_lite_blend_t blend) +{ + switch(blend) { + case VG_LITE_BLEND_NONE: + return BlendMethod::SrcOver; + + case VG_LITE_BLEND_NORMAL_LVGL: + return BlendMethod::Normal; + + case VG_LITE_BLEND_SRC_OVER: + return BlendMethod::Normal; + + case VG_LITE_BLEND_SCREEN: + return BlendMethod::Screen; + + case VG_LITE_BLEND_ADDITIVE: + return BlendMethod::Add; + + case VG_LITE_BLEND_MULTIPLY: + return BlendMethod::Multiply; + + default: + break; + } + + return BlendMethod::Normal; +} + +static StrokeCap stroke_cap_conv(vg_lite_cap_style_t cap) +{ + switch(cap) { + case VG_LITE_CAP_SQUARE: + return StrokeCap::Square; + case VG_LITE_CAP_ROUND: + return StrokeCap::Round; + case VG_LITE_CAP_BUTT: + return StrokeCap::Butt; + default: + break; + } + + return StrokeCap::Square; +} + +static StrokeJoin stroke_join_conv(vg_lite_join_style_t join) +{ + switch(join) { + case VG_LITE_JOIN_BEVEL: + return StrokeJoin::Bevel; + case VG_LITE_JOIN_ROUND: + return StrokeJoin::Round; + case VG_LITE_JOIN_MITER: + return StrokeJoin::Miter; + default: + break; + } + + return StrokeJoin::Bevel; +} + +static FillSpread fill_spread_conv(vg_lite_gradient_spreadmode_t spread) +{ + switch(spread) { + case VG_LITE_GRADIENT_SPREAD_PAD: + return FillSpread::Pad; + case VG_LITE_GRADIENT_SPREAD_REPEAT: + return FillSpread::Repeat; + case VG_LITE_GRADIENT_SPREAD_REFLECT: + return FillSpread::Reflect; + default: + return FillSpread::Pad; + } +} + +static float vlc_get_arg(const void * data, vg_lite_format_t format) +{ + switch(format) { + case VG_LITE_S8: + return *((int8_t *)data); + + case VG_LITE_S16: + return *((int16_t *)data); + + case VG_LITE_S32: + return *((int32_t *)data); + + case VG_LITE_FP32: + return *((float *)data); + + default: + LV_LOG_ERROR("UNKNOW_FORMAT: %d", format); + break; + } + + return 0; +} + +static uint8_t vlc_format_len(vg_lite_format_t format) +{ + switch(format) { + case VG_LITE_S8: + return 1; + case VG_LITE_S16: + return 2; + case VG_LITE_S32: + return 4; + case VG_LITE_FP32: + return 4; + default: + LV_LOG_ERROR("UNKNOW_FORMAT: %d", format); + LV_ASSERT(false); + break; + } + + return 0; +} + +static uint8_t vlc_op_arg_len(uint8_t vlc_op) +{ + switch(vlc_op) { + VLC_OP_ARG_LEN(END, 0); + VLC_OP_ARG_LEN(CLOSE, 0); + VLC_OP_ARG_LEN(MOVE, 2); + VLC_OP_ARG_LEN(MOVE_REL, 2); + VLC_OP_ARG_LEN(LINE, 2); + VLC_OP_ARG_LEN(LINE_REL, 2); + VLC_OP_ARG_LEN(QUAD, 4); + VLC_OP_ARG_LEN(QUAD_REL, 4); + VLC_OP_ARG_LEN(CUBIC, 6); + VLC_OP_ARG_LEN(CUBIC_REL, 6); + VLC_OP_ARG_LEN(SCCWARC, 5); + VLC_OP_ARG_LEN(SCCWARC_REL, 5); + VLC_OP_ARG_LEN(SCWARC, 5); + VLC_OP_ARG_LEN(SCWARC_REL, 5); + VLC_OP_ARG_LEN(LCCWARC, 5); + VLC_OP_ARG_LEN(LCCWARC_REL, 5); + VLC_OP_ARG_LEN(LCWARC, 5); + VLC_OP_ARG_LEN(LCWARC_REL, 5); + default: + LV_LOG_ERROR("UNKNOW_VLC_OP: 0x%x", vlc_op); + LV_ASSERT(false); + break; + } + + return 0; +} + +static Result shape_set_stroke(std::unique_ptr & shape, const vg_lite_path_t * path) +{ + switch(path->path_type) { + case VG_LITE_DRAW_ZERO: + case VG_LITE_DRAW_FILL_PATH: + /* if path is not a stroke, return */ + return Result::Success; + + case VG_LITE_DRAW_STROKE_PATH: + case VG_LITE_DRAW_FILL_STROKE_PATH: + break; + + default: + LV_LOG_ERROR("unknown path type: %d", path->path_type); + return Result::InvalidArguments; + } + + LV_ASSERT_NULL(path->stroke); + TVG_CHECK_RETURN_RESULT(shape->stroke(path->stroke->line_width)); + TVG_CHECK_RETURN_RESULT(shape->strokeMiterlimit(path->stroke->miter_limit)); + TVG_CHECK_RETURN_RESULT(shape->stroke(stroke_cap_conv(path->stroke->cap_style))); + TVG_CHECK_RETURN_RESULT(shape->stroke(stroke_join_conv(path->stroke->join_style))); + TVG_CHECK_RETURN_RESULT(shape->stroke(TVG_COLOR(path->stroke_color))); + + if(path->stroke->pattern_count) { + LV_ASSERT_NULL(path->stroke->dash_pattern); + TVG_CHECK_RETURN_RESULT(shape->stroke(path->stroke->dash_pattern, path->stroke->pattern_count)); + } + + return Result::Success; +} + +static Result shape_append_path(std::unique_ptr & shape, vg_lite_path_t * path, vg_lite_matrix_t * matrix) +{ + uint8_t fmt_len = vlc_format_len(path->format); + uint8_t * cur = (uint8_t *)path->path; + uint8_t * end = cur + path->path_length; + + while(cur < end) { + /* get op code */ + uint8_t op_code = VLC_GET_OP_CODE(cur); + + /* get arguments length */ + uint8_t arg_len = vlc_op_arg_len(op_code); + + /* skip op code */ + cur += fmt_len; + + switch(op_code) { + case VLC_OP_MOVE: { + float x = VLC_GET_ARG(cur, 0); + float y = VLC_GET_ARG(cur, 1); + TVG_CHECK_RETURN_RESULT(shape->moveTo(x, y)); + } + break; + + case VLC_OP_LINE: { + float x = VLC_GET_ARG(cur, 0); + float y = VLC_GET_ARG(cur, 1); + TVG_CHECK_RETURN_RESULT(shape->lineTo(x, y)); + } + break; + + case VLC_OP_QUAD: { + /* hack pre point */ + float qcx0 = VLC_GET_ARG(cur, -3); + float qcy0 = VLC_GET_ARG(cur, -2); + float qcx1 = VLC_GET_ARG(cur, 0); + float qcy1 = VLC_GET_ARG(cur, 1); + float x = VLC_GET_ARG(cur, 2); + float y = VLC_GET_ARG(cur, 3); + + qcx0 += (qcx1 - qcx0) * 2 / 3; + qcy0 += (qcy1 - qcy0) * 2 / 3; + qcx1 = x + (qcx1 - x) * 2 / 3; + qcy1 = y + (qcy1 - y) * 2 / 3; + + TVG_CHECK_RETURN_RESULT(shape->cubicTo(qcx0, qcy0, qcx1, qcy1, x, y)); + } + break; + + case VLC_OP_CUBIC: { + float cx1 = VLC_GET_ARG(cur, 0); + float cy1 = VLC_GET_ARG(cur, 1); + float cx2 = VLC_GET_ARG(cur, 2); + float cy2 = VLC_GET_ARG(cur, 3); + float x = VLC_GET_ARG(cur, 4); + float y = VLC_GET_ARG(cur, 5); + TVG_CHECK_RETURN_RESULT(shape->cubicTo(cx1, cy1, cx2, cy2, x, y)); + } + break; + + case VLC_OP_CLOSE: + TVG_CHECK_RETURN_RESULT(shape->close()); + break; + + default: + break; + } + + cur += arg_len * fmt_len; + } + + TVG_CHECK_RETURN_RESULT(shape_set_stroke(shape, path)); + + float x_min = path->bounding_box[0]; + float y_min = path->bounding_box[1]; + float x_max = path->bounding_box[2]; + float y_max = path->bounding_box[3]; + + if(math_equal(x_min, FLT_MIN) && math_equal(y_min, FLT_MIN) + && math_equal(x_max, FLT_MAX) && math_equal(y_max, FLT_MAX)) { + return Result::Success; + } + + auto cilp = Shape::gen(); + TVG_CHECK_RETURN_RESULT(cilp->appendRect(x_min, y_min, x_max - x_min, y_max - y_min, 0, 0)); + TVG_CHECK_RETURN_RESULT(cilp->transform(matrix_conv(matrix))); + TVG_CHECK_RETURN_RESULT(shape->composite(std::move(cilp), CompositeMethod::ClipPath)); + + return Result::Success; +} + +static Result shape_append_rect(std::unique_ptr & shape, const vg_lite_buffer_t * target, + const vg_lite_rectangle_t * rect) +{ + if(rect) { + TVG_CHECK_RETURN_RESULT(shape->appendRect(rect->x, rect->y, rect->width, rect->height, 0, 0)); + } + else if(target) { + TVG_CHECK_RETURN_RESULT(shape->appendRect(0, 0, target->width, target->height, 0, 0)); + } + else { + return Result::InvalidArguments; + } + + return Result::Success; +} + +static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target) +{ + /* if target_buffer needs to be changed, finish current drawing */ + if(ctx->target_buffer && ctx->target_buffer != target->memory) { + vg_lite_finish(); + } + + ctx->target_buffer = target->memory; + ctx->target_format = target->format; + ctx->target_px_size = target->width * target->height; + + void * canvas_target_buffer; + if(TVG_IS_VG_FMT_SUPPORT(target->format)) { + /* if target format is supported by VG, use target buffer directly */ + canvas_target_buffer = target->memory; + } + else { + /* if target format is not supported by VG, use internal buffer */ + canvas_target_buffer = ctx->get_temp_target_buffer(target->width, target->height); + } + + /* Prevent repeated target setting */ + if(ctx->tvg_target_buffer == canvas_target_buffer) { + return Result::Success; + } + + ctx->tvg_target_buffer = canvas_target_buffer; + + TVG_CHECK_RETURN_RESULT(ctx->canvas->target( + (uint32_t *)ctx->tvg_target_buffer, + target->width, + target->width, + target->height, + SwCanvas::ARGB8888)); + + if(ctx->scissor_is_set) { + TVG_CHECK_RETURN_RESULT( + ctx->canvas->viewport( + ctx->scissor_rect.x, ctx->scissor_rect.y, + ctx->scissor_rect.width, ctx->scissor_rect.height)); + } + + return Result::Success; +} + +static vg_lite_uint32_t width_to_stride(vg_lite_uint32_t w, vg_lite_buffer_format_t color_format) +{ + if(vg_lite_query_feature(gcFEATURE_BIT_VG_16PIXELS_ALIGN)) { + w = VG_LITE_ALIGN(w, 16); + } + + vg_lite_uint32_t mul, div, align; + get_format_bytes(color_format, &mul, &div, &align); + return VG_LITE_ALIGN((w * mul / div), align); +} + +static bool decode_indexed_line( + vg_lite_buffer_format_t color_format, + const vg_lite_uint32_t * palette, + int32_t x, int32_t y, + int32_t w_px, const uint8_t * in, vg_lite_uint32_t * out) +{ + uint8_t px_size; + uint16_t mask; + + vg_lite_uint32_t w_byte = width_to_stride(w_px, color_format); + + in += w_byte * y; /*First pixel*/ + out += w_px * y; + + int8_t shift = 0; + switch(color_format) { + case VG_LITE_INDEX_1: + px_size = 1; + in += x / 8; /*8pixel per byte*/ + shift = 7 - (x & 0x7); + break; + case VG_LITE_INDEX_2: + px_size = 2; + in += x / 4; /*4pixel per byte*/ + shift = 6 - 2 * (x & 0x3); + break; + case VG_LITE_INDEX_4: + px_size = 4; + in += x / 2; /*2pixel per byte*/ + shift = 4 - 4 * (x & 0x1); + break; + case VG_LITE_INDEX_8: + px_size = 8; + in += x; + shift = 0; + break; + default: + LV_ASSERT(false); + return false; + } + + mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/ + + int32_t i; + for(i = 0; i < w_px; i++) { + uint8_t val_act = (*in >> shift) & mask; + out[i] = palette[val_act]; + + shift -= px_size; + if(shift < 0) { + shift = 8 - px_size; + in++; + } + } + return true; +} + +static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture, const vg_lite_buffer_t * source, + vg_lite_color_t color) +{ + vg_lite_uint32_t * image_buffer; + LV_ASSERT(VG_LITE_IS_ALIGNED(source->memory, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN)); + +#if LV_VG_LITE_THORVG_16PIXELS_ALIGN + LV_ASSERT(VG_LITE_IS_ALIGNED(source->width, 16)); +#endif + + if(source->format == VG_LITE_BGRA8888 && source->image_mode == VG_LITE_NORMAL_IMAGE_MODE) { + image_buffer = (vg_lite_uint32_t *)source->memory; + } + else { + vg_lite_uint32_t width = source->width; + vg_lite_uint32_t height = source->height; + vg_lite_uint32_t px_size = width * height; + image_buffer = ctx->get_image_buffer(width, height); + + vg_lite_buffer_t target; + memset(&target, 0, sizeof(target)); + target.memory = image_buffer; + target.format = VG_LITE_BGRA8888; + target.width = width; + target.height = height; + target.stride = width_to_stride(width, target.format); + + switch(source->format) { + case VG_LITE_INDEX_1: + case VG_LITE_INDEX_2: + case VG_LITE_INDEX_4: + case VG_LITE_INDEX_8: { + const vg_lite_uint32_t * clut_colors = ctx->get_CLUT(source->format); + for(vg_lite_uint32_t y = 0; y < height; y++) { + decode_indexed_line(source->format, clut_colors, 0, y, width, (uint8_t *)source->memory, image_buffer); + } + } + break; + + case VG_LITE_A4: { + conv_alpha4_to_bgra8888.convert(&target, source, color); + } + break; + + case VG_LITE_A8: { + conv_alpha8_to_bgra8888.convert(&target, source, color); + } + break; + + case VG_LITE_L8: { + conv_l8_to_bgra8888.convert(&target, source); + } + break; + + case VG_LITE_BGRX8888: { + conv_bgrx8888_to_bgra8888.convert(&target, source); + } + break; + + case VG_LITE_BGR888: { + conv_bgr888_to_bgra8888.convert(&target, source); + } + break; + + case VG_LITE_BGRA5658: { + conv_bgra5658_to_bgra8888.convert(&target, source); + } + break; + + case VG_LITE_BGR565: { + conv_bgr565_to_bgra8888.convert(&target, source); + } + break; + +#if LV_VG_LITE_THORVG_YUV_SUPPORT + case VG_LITE_NV12: { + libyuv::NV12ToARGB((const uint8_t *)source->memory, source->stride, (const uint8_t *)source->yuv.uv_memory, + source->yuv.uv_stride, + (uint8_t *)image_buffer, source->width * sizeof(vg_lite_uint32_t), width, height); + } + break; +#endif + + case VG_LITE_BGRA8888: { + memcpy(image_buffer, source->memory, px_size * sizeof(vg_color32_t)); + } + break; + + default: + LV_LOG_ERROR("unsupported format: %d", source->format); + LV_ASSERT(false); + break; + } + + /* multiply color */ + if(source->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE && !VG_LITE_IS_ALPHA_FORMAT(source->format)) { + vg_color32_t * dest = (vg_color32_t *)image_buffer; + while(px_size--) { + dest->alpha = UDIV255(dest->alpha * A(color)); + dest->red = UDIV255(dest->red * B(color)); + dest->green = UDIV255(dest->green * G(color)); + dest->blue = UDIV255(dest->blue * R(color)); + dest++; + } + } + } + + TVG_CHECK_RETURN_RESULT(picture->load((uint32_t *)image_buffer, source->width, source->height, true)); + + return Result::Success; +} + +static void ClampColor(FLOATVECTOR4 Source, FLOATVECTOR4 Target, uint8_t Premultiplied) +{ + vg_lite_float_t colorMax; + /* Clamp the alpha channel. */ + Target[3] = CLAMP(Source[3], 0.0f, 1.0f); + + /* Determine the maximum value for the color channels. */ + colorMax = Premultiplied ? Target[3] : 1.0f; + + /* Clamp the color channels. */ + Target[0] = CLAMP(Source[0], 0.0f, colorMax); + Target[1] = CLAMP(Source[1], 0.0f, colorMax); + Target[2] = CLAMP(Source[2], 0.0f, colorMax); +} + +static uint8_t PackColorComponent(vg_lite_float_t value) +{ + /* Compute the rounded normalized value. */ + vg_lite_float_t rounded = value * 255.0f + 0.5f; + + /* Get the integer part. */ + int32_t roundedInt = (int32_t)rounded; + + /* Clamp to 0..1 range. */ + uint8_t clamped = (uint8_t)CLAMP(roundedInt, 0, 255); + + /* Return result. */ + return clamped; +} + +/* Get the bpp information of a color format. */ +static void get_format_bytes(vg_lite_buffer_format_t format, + vg_lite_uint32_t * mul, + vg_lite_uint32_t * div, + vg_lite_uint32_t * bytes_align) +{ + *mul = *div = 1; + *bytes_align = 4; + switch(format) { + case VG_LITE_L8: + case VG_LITE_A8: + case VG_LITE_RGBA8888_ETC2_EAC: + break; + + case VG_LITE_A4: + *div = 2; + break; + + case VG_LITE_ABGR1555: + case VG_LITE_ARGB1555: + case VG_LITE_BGRA5551: + case VG_LITE_RGBA5551: + case VG_LITE_RGBA4444: + case VG_LITE_BGRA4444: + case VG_LITE_ABGR4444: + case VG_LITE_ARGB4444: + case VG_LITE_RGB565: + case VG_LITE_BGR565: + case VG_LITE_YUYV: + case VG_LITE_YUY2: + case VG_LITE_YUY2_TILED: + /* AYUY2 buffer memory = YUY2 + alpha. */ + case VG_LITE_AYUY2: + case VG_LITE_AYUY2_TILED: + /* ABGR8565_PLANAR buffer memory = RGB565 + alpha. */ + case VG_LITE_ABGR8565_PLANAR: + case VG_LITE_ARGB8565_PLANAR: + case VG_LITE_RGBA5658_PLANAR: + case VG_LITE_BGRA5658_PLANAR: + *mul = 2; + break; + + case VG_LITE_RGBA8888: + case VG_LITE_BGRA8888: + case VG_LITE_ABGR8888: + case VG_LITE_ARGB8888: + case VG_LITE_RGBX8888: + case VG_LITE_BGRX8888: + case VG_LITE_XBGR8888: + case VG_LITE_XRGB8888: + *mul = 4; + break; + + case VG_LITE_NV12: + case VG_LITE_NV12_TILED: + *mul = 3; + break; + + case VG_LITE_ANV12: + case VG_LITE_ANV12_TILED: + *mul = 4; + break; + + case VG_LITE_INDEX_1: + *div = 8; + *bytes_align = 8; + break; + + case VG_LITE_INDEX_2: + *div = 4; + *bytes_align = 8; + break; + + case VG_LITE_INDEX_4: + *div = 2; + *bytes_align = 8; + break; + + case VG_LITE_INDEX_8: + *bytes_align = 1; + break; + + case VG_LITE_RGBA2222: + case VG_LITE_BGRA2222: + case VG_LITE_ABGR2222: + case VG_LITE_ARGB2222: + *mul = 1; + break; + + case VG_LITE_RGB888: + case VG_LITE_BGR888: + case VG_LITE_ABGR8565: + case VG_LITE_BGRA5658: + case VG_LITE_ARGB8565: + case VG_LITE_RGBA5658: + *mul = 3; + break; + + /* OpenVG format*/ + case VG_sRGBX_8888: + case VG_sRGBA_8888: + case VG_sRGBA_8888_PRE: + case VG_lRGBX_8888: + case VG_lRGBA_8888: + case VG_lRGBA_8888_PRE: + case VG_sXRGB_8888: + case VG_sARGB_8888: + case VG_sARGB_8888_PRE: + case VG_lXRGB_8888: + case VG_lARGB_8888: + case VG_lARGB_8888_PRE: + case VG_sBGRX_8888: + case VG_sBGRA_8888: + case VG_sBGRA_8888_PRE: + case VG_lBGRX_8888: + case VG_lBGRA_8888: + case VG_sXBGR_8888: + case VG_sABGR_8888: + case VG_lBGRA_8888_PRE: + case VG_sABGR_8888_PRE: + case VG_lXBGR_8888: + case VG_lABGR_8888: + case VG_lABGR_8888_PRE: + *mul = 4; + break; + + case VG_sRGBA_5551: + case VG_sRGBA_4444: + case VG_sARGB_1555: + case VG_sARGB_4444: + case VG_sBGRA_5551: + case VG_sBGRA_4444: + case VG_sABGR_1555: + case VG_sABGR_4444: + case VG_sRGB_565: + case VG_sBGR_565: + *mul = 2; + break; + + case VG_sL_8: + case VG_lL_8: + case VG_A_8: + break; + + case VG_BW_1: + case VG_A_4: + case VG_A_1: + *div = 2; + break; + + default: + break; + } +} + +static vg_lite_fpoint_t matrix_transform_point(const vg_lite_matrix_t * matrix, const vg_lite_fpoint_t * point) +{ + vg_lite_fpoint_t p; + p.x = (vg_lite_float_t)(point->x * matrix->m[0][0] + point->y * matrix->m[0][1] + matrix->m[0][2]); + p.y = (vg_lite_float_t)(point->x * matrix->m[1][0] + point->y * matrix->m[1][1] + matrix->m[1][2]); + return p; +} + +static bool vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix) +{ + vg_lite_float_t det00, det01, det02; + vg_lite_float_t d; + bool is_affine; + + /* Test for identity matrix. */ + if(matrix == NULL) { + result->m[0][0] = 1.0f; + result->m[0][1] = 0.0f; + result->m[0][2] = 0.0f; + result->m[1][0] = 0.0f; + result->m[1][1] = 1.0f; + result->m[1][2] = 0.0f; + result->m[2][0] = 0.0f; + result->m[2][1] = 0.0f; + result->m[2][2] = 1.0f; + + /* Success. */ + return true; + } + + det00 = (matrix->m[1][1] * matrix->m[2][2]) - (matrix->m[2][1] * matrix->m[1][2]); + det01 = (matrix->m[2][0] * matrix->m[1][2]) - (matrix->m[1][0] * matrix->m[2][2]); + det02 = (matrix->m[1][0] * matrix->m[2][1]) - (matrix->m[2][0] * matrix->m[1][1]); + + /* Compute determinant. */ + d = (matrix->m[0][0] * det00) + (matrix->m[0][1] * det01) + (matrix->m[0][2] * det02); + + /* Return 0 if there is no inverse matrix. */ + if(d == 0.0f) + return false; + + /* Compute reciprocal. */ + d = 1.0f / d; + + /* Determine if the matrix is affine. */ + is_affine = (matrix->m[2][0] == 0.0f) && (matrix->m[2][1] == 0.0f) && (matrix->m[2][2] == 1.0f); + + result->m[0][0] = d * det00; + result->m[0][1] = d * ((matrix->m[2][1] * matrix->m[0][2]) - (matrix->m[0][1] * matrix->m[2][2])); + result->m[0][2] = d * ((matrix->m[0][1] * matrix->m[1][2]) - (matrix->m[1][1] * matrix->m[0][2])); + result->m[1][0] = d * det01; + result->m[1][1] = d * ((matrix->m[0][0] * matrix->m[2][2]) - (matrix->m[2][0] * matrix->m[0][2])); + result->m[1][2] = d * ((matrix->m[1][0] * matrix->m[0][2]) - (matrix->m[0][0] * matrix->m[1][2])); + result->m[2][0] = is_affine ? 0.0f : d * det02; + result->m[2][1] = is_affine ? 0.0f : d * ((matrix->m[2][0] * matrix->m[0][1]) - (matrix->m[0][0] * matrix->m[2][1])); + result->m[2][2] = is_affine ? 1.0f : d * ((matrix->m[0][0] * matrix->m[1][1]) - (matrix->m[1][0] * matrix->m[0][1])); + + /* Success. */ + return true; +} + +static void vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult) +{ + vg_lite_matrix_t temp; + int row, column; + + /* Process all rows. */ + for(row = 0; row < 3; row++) { + /* Process all columns. */ + for(column = 0; column < 3; column++) { + /* Compute matrix entry. */ + temp.m[row][column] = (matrix->m[row][0] * mult->m[0][column]) + + (matrix->m[row][1] * mult->m[1][column]) + + (matrix->m[row][2] * mult->m[2][column]); + } + } + + /* Copy temporary matrix into result. */ + lv_memcpy(matrix->m, &temp.m, sizeof(temp.m)); +} + +#endif diff --git a/test/include/liblvgl/stdlib/builtin/lv_tlsf.h b/test/include/liblvgl/stdlib/builtin/lv_tlsf.h new file mode 100644 index 00000000..bfaf0843 --- /dev/null +++ b/test/include/liblvgl/stdlib/builtin/lv_tlsf.h @@ -0,0 +1,97 @@ +#include "../../lv_conf_internal.h" +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN + +#ifndef LV_TLSF_H +#define LV_TLSF_H + +/* +** 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 "../../osal/lv_os.h" +#include "../../misc/lv_ll.h" +#include "../../misc/lv_types.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* lv_tlsf_t: a TLSF structure. Can contain 1 to N pools. */ +/* lv_pool_t: a block of memory that TLSF can manage. */ +typedef void * lv_tlsf_t; +typedef void * lv_pool_t; + +/* Create/destroy a memory pool. */ +lv_tlsf_t lv_tlsf_create(void * mem); +lv_tlsf_t lv_tlsf_create_with_pool(void * mem, size_t bytes); +void lv_tlsf_destroy(lv_tlsf_t tlsf); +lv_pool_t lv_tlsf_get_pool(lv_tlsf_t tlsf); + +/* Add/remove memory pools. */ +lv_pool_t lv_tlsf_add_pool(lv_tlsf_t tlsf, void * mem, size_t bytes); +void lv_tlsf_remove_pool(lv_tlsf_t tlsf, lv_pool_t pool); + +/* malloc/memalign/realloc/free replacements. */ +void * lv_tlsf_malloc(lv_tlsf_t tlsf, size_t bytes); +void * lv_tlsf_memalign(lv_tlsf_t tlsf, size_t align, size_t bytes); +void * lv_tlsf_realloc(lv_tlsf_t tlsf, void * ptr, size_t size); +size_t lv_tlsf_free(lv_tlsf_t tlsf, const void * ptr); + +/* Returns internal block size, not original request size */ +size_t lv_tlsf_block_size(void * ptr); + +/* Overheads/limits of internal structures. */ +size_t lv_tlsf_size(void); +size_t lv_tlsf_align_size(void); +size_t lv_tlsf_block_size_min(void); +size_t lv_tlsf_block_size_max(void); +size_t lv_tlsf_pool_overhead(void); +size_t lv_tlsf_alloc_overhead(void); + +/* Debugging. */ +typedef void (*lv_tlsf_walker)(void * ptr, size_t size, int used, void * user); +void lv_tlsf_walk_pool(lv_pool_t pool, lv_tlsf_walker walker, void * user); +/* Returns nonzero if any internal consistency check fails. */ +int lv_tlsf_check(lv_tlsf_t tlsf); +int lv_tlsf_check_pool(lv_pool_t pool); + +#if defined(__cplusplus) +}; +#endif + +#endif /*LV_TLSF_H*/ + +#endif /*LV_STDLIB_BUILTIN*/ diff --git a/test/include/liblvgl/stdlib/builtin/lv_tlsf_private.h b/test/include/liblvgl/stdlib/builtin/lv_tlsf_private.h new file mode 100644 index 00000000..036e9d73 --- /dev/null +++ b/test/include/liblvgl/stdlib/builtin/lv_tlsf_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_tlsf_private.h + * + */ + +#ifndef LV_TLSF_PRIVATE_H +#define LV_TLSF_PRIVATE_H + +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_tlsf.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { +#if LV_USE_OS + lv_mutex_t mutex; +#endif + lv_tlsf_t tlsf; + size_t cur_used; + size_t max_used; + lv_ll_t pool_ll; +} lv_tlsf_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN*/ + +#endif /*LV_TLSF_PRIVATE_H*/ diff --git a/test/include/liblvgl/stdlib/lv_mem.h b/test/include/liblvgl/stdlib/lv_mem.h new file mode 100644 index 00000000..e136aad6 --- /dev/null +++ b/test/include/liblvgl/stdlib/lv_mem.h @@ -0,0 +1,156 @@ +/** + * @file lv_mem.h + * + */ + +#ifndef LV_MEM_H +#define LV_MEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include "lv_string.h" + +#include "../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef void * lv_mem_pool_t; + +/** + * Heap information structure. + */ +typedef struct { + size_t total_size; /**< Total heap size */ + size_t free_cnt; + size_t free_size; /**< Size of available memory */ + size_t free_biggest_size; + size_t used_cnt; + size_t max_used; /**< Max size of Heap memory used */ + uint8_t used_pct; /**< Percentage used */ + uint8_t frag_pct; /**< Amount of fragmentation */ +} lv_mem_monitor_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize to use malloc/free/realloc etc + */ +void lv_mem_init(void); + +/** + * Drop all dynamically allocated memory and reset the memory pools' state + */ +void lv_mem_deinit(void); + +lv_mem_pool_t lv_mem_add_pool(void * mem, size_t bytes); + +void lv_mem_remove_pool(lv_mem_pool_t pool); + +/** + * Allocate memory dynamically + * @param size requested size in bytes + * @return pointer to allocated uninitialized memory, or NULL on failure + */ +void * lv_malloc(size_t size); + +/** + * Allocate a block of zeroed memory dynamically + * @param num requested number of element to be allocated. + * @param size requested size of each element in bytes. + * @return pointer to allocated zeroed memory, or NULL on failure + */ +void * lv_calloc(size_t num, size_t size); + +/** + * Allocate zeroed memory dynamically + * @param size requested size in bytes + * @return pointer to allocated zeroed memory, or NULL on failure + */ +void * lv_zalloc(size_t size); + +/** + * Allocate zeroed memory dynamically + * @param size requested size in bytes + * @return pointer to allocated zeroed memory, or NULL on failure + */ +void * lv_malloc_zeroed(size_t size); + +/** + * Free an allocated data + * @param data pointer to an allocated memory + */ +void lv_free(void * data); + +/** + * Reallocate a memory with a new size. The old content will be kept. + * @param data_p pointer to an allocated memory. + * Its content will be copied to the new memory block and freed + * @param new_size the desired new size in byte + * @return pointer to the new memory, NULL on failure + */ +void * lv_realloc(void * data_p, size_t new_size); + +/** + * Used internally to execute a plain `malloc` operation + * @param size size in bytes to `malloc` + */ +void * lv_malloc_core(size_t size); + +/** + * Used internally to execute a plain `free` operation + * @param p memory address to free + */ +void lv_free_core(void * p); + +/** + * Used internally to execute a plain realloc operation + * @param p memory address to realloc + * @param new_size size in bytes to realloc + */ +void * lv_realloc_core(void * p, size_t new_size); + +/** + * Used internally by lv_mem_monitor() to gather LVGL heap state information. + * @param mon_p pointer to lv_mem_monitor_t object to be populated. + */ +void lv_mem_monitor_core(lv_mem_monitor_t * mon_p); + +lv_result_t lv_mem_test_core(void); + +/** + * @brief Tests the memory allocation system by allocating and freeing a block of memory. + * @return LV_RESULT_OK if the memory allocation system is working properly, or LV_RESULT_INVALID if there is an error. + */ +lv_result_t lv_mem_test(void); + +/** + * Give information about the work memory of dynamic allocation + * @param mon_p pointer to a lv_mem_monitor_t variable, + * the result of the analysis will be stored here + */ +void lv_mem_monitor(lv_mem_monitor_t * mon_p); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MEM_H*/ diff --git a/test/include/liblvgl/stdlib/lv_mem_private.h b/test/include/liblvgl/stdlib/lv_mem_private.h new file mode 100644 index 00000000..9e70ae1a --- /dev/null +++ b/test/include/liblvgl/stdlib/lv_mem_private.h @@ -0,0 +1,39 @@ +/** + * @file lv_mem_private.h + * + */ + +#ifndef LV_MEM_PRIVATE_H +#define LV_MEM_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_mem.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MEM_PRIVATE_H*/ diff --git a/test/include/liblvgl/stdlib/lv_sprintf.h b/test/include/liblvgl/stdlib/lv_sprintf.h new file mode 100644 index 00000000..a7f2188d --- /dev/null +++ b/test/include/liblvgl/stdlib/lv_sprintf.h @@ -0,0 +1,45 @@ +/** + * @file lv_sprintf.h + * + */ + +#ifndef LV_SPRINTF_H +#define LV_SPRINTF_H + +#if defined(__has_include) + #if __has_include(LV_INTTYPES_INCLUDE) + #include LV_INTTYPES_INCLUDE + /* platform-specific printf format for int32_t, usually "d" or "ld" */ + #define LV_PRId32 PRId32 + #define LV_PRIu32 PRIu32 + #define LV_PRIx32 PRIx32 + #define LV_PRIX32 PRIX32 + #else + #define LV_PRId32 "d" + #define LV_PRIu32 "u" + #define LV_PRIx32 "x" + #define LV_PRIX32 "X" + #endif +#else + /* hope this is correct for ports without __has_include or without inttypes.h */ + #define LV_PRId32 "d" + #define LV_PRIu32 "u" + #define LV_PRIx32 "x" + #define LV_PRIX32 "X" +#endif + +#include "../misc/lv_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int lv_snprintf(char * buffer, size_t count, const char * format, ...); + +int lv_vsnprintf(char * buffer, size_t count, const char * format, va_list va); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_SPRINTF_H */ diff --git a/test/include/liblvgl/stdlib/lv_string.h b/test/include/liblvgl/stdlib/lv_string.h new file mode 100644 index 00000000..ce73502e --- /dev/null +++ b/test/include/liblvgl/stdlib/lv_string.h @@ -0,0 +1,166 @@ +/** + * @file lv_string.h + * + */ + +#ifndef LV_STRING_H +#define LV_STRING_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Copies a block of memory from a source address to a destination address. + * @param dst Pointer to the destination array where the content is to be copied. + * @param src Pointer to the source of data to be copied. + * @param len Number of bytes to copy. + * @return Pointer to the destination array. + * @note The function does not check for any overlapping of the source and destination memory blocks. + */ +void * lv_memcpy(void * dst, const void * src, size_t len); + +/** + * @brief Fills a block of memory with a specified value. + * @param dst Pointer to the destination array to fill with the specified value. + * @param v Value to be set. The value is passed as an int, but the function fills + * the block of memory using the unsigned char conversion of this value. + * @param len Number of bytes to be set to the value. + */ +void lv_memset(void * dst, uint8_t v, size_t len); + +/** + * @brief Move a block of memory from source to destination + * @param dst Pointer to the destination array where the content is to be copied. + * @param src Pointer to the source of data to be copied. + * @param len Number of bytes to copy + * @return Pointer to the destination array. + */ +void * lv_memmove(void * dst, const void * src, size_t len); + +/** + * @brief This function will compare two memory blocks + * @param p1 Pointer to the first memory block + * @param p2 Pointer to the second memory block + * @param len Number of bytes to compare + * @return The difference between the value of the first unmatching byte. + */ +int lv_memcmp(const void * p1, const void * p2, size_t len); + +/** + * Same as `memset(dst, 0x00, len)`. + * @param dst pointer to the destination buffer + * @param len number of byte to set + */ +static inline void lv_memzero(void * dst, size_t len) +{ + lv_memset(dst, 0x00, len); +} + +/** + * @brief Computes the length of the string str up to, but not including the terminating null character. + * @param str Pointer to the null-terminated byte string to be examined. + * @return The length of the string in bytes. + */ +size_t lv_strlen(const char * str); + +/** + * @brief Copies up to dst_size-1 (non-null) characters from src to dst. A null terminator is always added. + * @param dst Pointer to the destination array where the content is to be copied. + * @param src Pointer to the source of data to be copied. + * @param dst_size Maximum number of characters to be copied to dst, including the null character. + * @return The length of src. The return value is equivalent to the value returned by lv_strlen(src) + */ +size_t lv_strlcpy(char * dst, const char * src, size_t dst_size); + +/** + * @brief Copies up to dest_size characters from the string pointed to by src to the character array pointed to by dst + * and fills the remaining length with null bytes. + * @param dst Pointer to the destination array where the content is to be copied. + * @param src Pointer to the source of data to be copied. + * @param dest_size Maximum number of characters to be copied to dst. + * @return A pointer to the destination array, which is dst. + * @note dst will not be null terminated if dest_size bytes were copied from src before the end of src was reached. + */ +char * lv_strncpy(char * dst, const char * src, size_t dest_size); + +/** + * @brief Copies the string pointed to by src, including the terminating null character, + * to the character array pointed to by dst. + * @param dst Pointer to the destination array where the content is to be copied. + * @param src Pointer to the source of data to be copied. + * @return A pointer to the destination array, which is dst. + */ +char * lv_strcpy(char * dst, const char * src); + +/** + * @brief This function will compare two strings without specified length. + * @param s1 pointer to the first string + * @param s2 pointer to the second string + * @return the difference between the value of the first unmatching character. + */ +int lv_strcmp(const char * s1, const char * s2); + +/** + * @brief Duplicate a string by allocating a new one and copying the content. + * @param src Pointer to the source of data to be copied. + * @return A pointer to the new allocated string. NULL if failed. + */ +char * lv_strdup(const char * src); + +/** + * @brief Copies the string pointed to by src, including the terminating null character, + * to the end of the string pointed to by dst. + * @param dst Pointer to the destination string where the content is to be appended. + * @param src Pointer to the source of data to be copied. + * @return A pointer to the destination string, which is dst. + */ +char * lv_strcat(char * dst, const char * src); + +/** + * @brief Copies up to src_len characters from the string pointed to by src + * to the end of the string pointed to by dst. + * A terminating null character is appended to dst even if no null character + * was encountered in src after src_len characters were copied. + * @param dst Pointer to the destination string where the content is to be appended. + * @param src Pointer to the source of data to be copied. + * @param src_len Maximum number of characters from src to be copied to the end of dst. + * @return A pointer to the destination string, which is dst. + */ +char * lv_strncat(char * dst, const char * src, size_t src_len); + +/** + * @brief Searches for the first occurrence of character c in the string str. + * @param str Pointer to the null-terminated byte string to be searched. + * @param c The character to be searched for. + * @return A pointer to the first occurrence of character c in the string str, or a null pointer if c is not found. + */ +char * lv_strchr(const char * str, int c); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_STRING_H*/ diff --git a/test/include/liblvgl/themes/default/lv_theme_default.h b/test/include/liblvgl/themes/default/lv_theme_default.h new file mode 100644 index 00000000..72d9acbf --- /dev/null +++ b/test/include/liblvgl/themes/default/lv_theme_default.h @@ -0,0 +1,71 @@ +/** + * @file lv_theme_default.h + * + */ + +#ifndef LV_THEME_DEFAULT_H +#define LV_THEME_DEFAULT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_theme.h" + +#if LV_USE_THEME_DEFAULT + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the theme + * @param disp pointer to display + * @param color_primary the primary color of the theme + * @param color_secondary the secondary color for the theme + * @param dark + * @param font pointer to a font to use. + * @return a pointer to reference this theme later + */ +lv_theme_t * lv_theme_default_init(lv_display_t * disp, lv_color_t color_primary, lv_color_t color_secondary, bool dark, + const lv_font_t * font); + +/** + * Get default theme + * @return a pointer to default theme, or NULL if this is not initialized + */ +lv_theme_t * lv_theme_default_get(void); + +/** + * Check if default theme is initialized + * @return true if default theme is initialized, false otherwise + */ +bool lv_theme_default_is_inited(void); + +/** + * Deinitialize the default theme + */ +void lv_theme_default_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_THEME_DEFAULT_H*/ diff --git a/test/include/liblvgl/themes/lv_theme.h b/test/include/liblvgl/themes/lv_theme.h new file mode 100644 index 00000000..21cb09b1 --- /dev/null +++ b/test/include/liblvgl/themes/lv_theme.h @@ -0,0 +1,108 @@ +/** + *@file lv_theme.h + * + */ + +#ifndef LV_THEME_H +#define LV_THEME_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../core/lv_obj.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef void (*lv_theme_apply_cb_t)(lv_theme_t *, lv_obj_t *); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the theme assigned to the display of the object + * @param obj pointer to a theme object + * @return the theme of the object's display (can be NULL) + */ +lv_theme_t * lv_theme_get_from_obj(lv_obj_t * obj); + +/** + * Apply the active theme on an object + * @param obj pointer to an object + */ +void lv_theme_apply(lv_obj_t * obj); + +/** + * Set a base theme for a theme. + * The styles from the base them will be added before the styles of the current theme. + * Arbitrary long chain of themes can be created by setting base themes. + * @param new_theme pointer to theme which base should be set + * @param parent pointer to the base theme + */ +void lv_theme_set_parent(lv_theme_t * new_theme, lv_theme_t * parent); + +/** + * Set an apply callback for a theme. + * The apply callback is used to add styles to different objects + * @param theme pointer to theme which callback should be set + * @param apply_cb pointer to the callback + */ +void lv_theme_set_apply_cb(lv_theme_t * theme, lv_theme_apply_cb_t apply_cb); + +/** + * Get the small font of the theme + * @param obj pointer to an object + * @return pointer to the font + */ +const lv_font_t * lv_theme_get_font_small(lv_obj_t * obj); +/** + * Get the normal font of the theme + * @param obj pointer to an object + * @return pointer to the font + */ +const lv_font_t * lv_theme_get_font_normal(lv_obj_t * obj); + +/** + * Get the subtitle font of the theme + * @param obj pointer to an object + * @return pointer to the font + */ +const lv_font_t * lv_theme_get_font_large(lv_obj_t * obj); + +/** + * Get the primary color of the theme + * @param obj pointer to an object + * @return the color + */ +lv_color_t lv_theme_get_color_primary(lv_obj_t * obj); + +/** + * Get the secondary color of the theme + * @param obj pointer to an object + * @return the color + */ +lv_color_t lv_theme_get_color_secondary(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#include "default/lv_theme_default.h" +#include "mono/lv_theme_mono.h" +#include "simple/lv_theme_simple.h" + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_THEME_H*/ diff --git a/test/include/liblvgl/themes/lv_theme_private.h b/test/include/liblvgl/themes/lv_theme_private.h new file mode 100644 index 00000000..f7bb24cd --- /dev/null +++ b/test/include/liblvgl/themes/lv_theme_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_theme_private.h + * + */ + +#ifndef LV_THEME_PRIVATE_H +#define LV_THEME_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_theme.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_theme_t { + lv_theme_apply_cb_t apply_cb; + lv_theme_t * parent; /**< Apply the current theme's style on top of this theme. */ + void * user_data; + lv_display_t * disp; + lv_color_t color_primary; + lv_color_t color_secondary; + const lv_font_t * font_small; + const lv_font_t * font_normal; + const lv_font_t * font_large; + uint32_t flags; /**< Any custom flag used by the theme */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_THEME_PRIVATE_H*/ diff --git a/test/include/liblvgl/themes/mono/lv_theme_mono.h b/test/include/liblvgl/themes/mono/lv_theme_mono.h new file mode 100644 index 00000000..30ac4c48 --- /dev/null +++ b/test/include/liblvgl/themes/mono/lv_theme_mono.h @@ -0,0 +1,62 @@ +/** + * @file lv_theme_mono.h + * + */ + +#ifndef LV_THEME_MONO_H +#define LV_THEME_MONO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_theme.h" + +#if LV_USE_THEME_MONO + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the theme + * @param disp pointer to display + * @param dark_bg + * @param font pointer to a font to use. + * @return a pointer to reference this theme later + */ +lv_theme_t * lv_theme_mono_init(lv_display_t * disp, bool dark_bg, const lv_font_t * font); + +/** +* Check if the theme is initialized +* @return true if default theme is initialized, false otherwise +*/ +bool lv_theme_mono_is_inited(void); + +/** + * Deinitialize the mono theme + */ +void lv_theme_mono_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_THEME_MONO_H */ diff --git a/test/include/liblvgl/themes/simple/lv_theme_simple.h b/test/include/liblvgl/themes/simple/lv_theme_simple.h new file mode 100644 index 00000000..67173665 --- /dev/null +++ b/test/include/liblvgl/themes/simple/lv_theme_simple.h @@ -0,0 +1,67 @@ +/** + * @file lv_theme_simple.h + * + */ + +#ifndef LV_THEME_SIMPLE_H +#define LV_THEME_SIMPLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_theme.h" +#include "../../display/lv_display.h" + +#if LV_USE_THEME_SIMPLE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the theme + * @param disp pointer to display to attach the theme + * @return a pointer to reference this theme later + */ +lv_theme_t * lv_theme_simple_init(lv_display_t * disp); + +/** +* Check if the theme is initialized +* @return true if default theme is initialized, false otherwise +*/ +bool lv_theme_simple_is_inited(void); + +/** + * Get simple theme + * @return a pointer to simple theme, or NULL if this is not initialized + */ +lv_theme_t * lv_theme_simple_get(void); + +/** + * Deinitialize the simple theme + */ +void lv_theme_simple_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_THEME_SIMPLE_H*/ diff --git a/test/include/liblvgl/tick/lv_tick.h b/test/include/liblvgl/tick/lv_tick.h new file mode 100644 index 00000000..048b93a3 --- /dev/null +++ b/test/include/liblvgl/tick/lv_tick.h @@ -0,0 +1,85 @@ +/** + * @file lv_tick.h + * Provide access to the system tick with 1 millisecond resolution + */ + +#ifndef LV_TICK_H +#define LV_TICK_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include "../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ +#ifndef LV_ATTRIBUTE_TICK_INC +#define LV_ATTRIBUTE_TICK_INC +#endif + +/********************** + * TYPEDEFS + **********************/ +typedef uint32_t (*lv_tick_get_cb_t)(void); + +typedef void (*lv_delay_cb_t)(uint32_t ms); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * You have to call this function periodically + * @param tick_period the call period of this function in milliseconds + */ +LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period); + +/** + * Get the elapsed milliseconds since start up + * @return the elapsed milliseconds + */ +uint32_t lv_tick_get(void); + +/** + * Get the elapsed milliseconds since a previous time stamp + * @param prev_tick a previous time stamp (return value of lv_tick_get() ) + * @return the elapsed milliseconds since 'prev_tick' + */ +uint32_t lv_tick_elaps(uint32_t prev_tick); + +/** + * Delay for the given milliseconds. + * By default it's a blocking delay, but with `lv_delay_set_cb()` + * a custom delay function can be set too + * @param ms the number of milliseconds to delay + */ +void lv_delay_ms(uint32_t ms); + +/** + * Set the custom callback for 'lv_tick_get' + * @param cb call this callback on 'lv_tick_get' + */ +void lv_tick_set_cb(lv_tick_get_cb_t cb); + +/** + * Set a custom callback for 'lv_delay_ms' + * @param cb call this callback in 'lv_delay_ms' + */ +void lv_delay_set_cb(lv_delay_cb_t cb); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TICK_H*/ diff --git a/test/include/liblvgl/tick/lv_tick_private.h b/test/include/liblvgl/tick/lv_tick_private.h new file mode 100644 index 00000000..cf8ae9b0 --- /dev/null +++ b/test/include/liblvgl/tick/lv_tick_private.h @@ -0,0 +1,46 @@ +/** + * @file lv_tick_private.h + * + */ + +#ifndef LV_TICK_PRIVATE_H +#define LV_TICK_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_tick.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint32_t sys_time; + volatile uint8_t sys_irq_flag; + lv_tick_get_cb_t tick_get_cb; + lv_delay_cb_t delay_cb; +} lv_tick_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TICK_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/animimage/lv_animimage.h b/test/include/liblvgl/widgets/animimage/lv_animimage.h new file mode 100644 index 00000000..a2f1926c --- /dev/null +++ b/test/include/liblvgl/widgets/animimage/lv_animimage.h @@ -0,0 +1,129 @@ +/** + * @file lv_animimage.h + * + */ + +#ifndef LV_ANIMIMAGE_H +#define LV_ANIMIMAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../image/lv_image.h" +#include "../../misc/lv_types.h" + +#if LV_USE_ANIMIMG != 0 + +/*Testing of dependencies*/ +#if LV_USE_IMAGE == 0 +#error "lv_animimg: lv_img is required. Enable it in lv_conf.h (LV_USE_IMAGE 1)" +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_animimg_class; + +/** Image parts */ +typedef enum { + LV_ANIM_IMAGE_PART_MAIN, +} lv_animimg_part_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an animation image objects + * @param parent pointer to an object, it will be the parent of the new button + * @return pointer to the created animation image object + */ +lv_obj_t * lv_animimg_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the image animation images source. + * @param img pointer to an animation image object + * @param dsc pointer to a series images + * @param num images' number + */ +void lv_animimg_set_src(lv_obj_t * img, const void * dsc[], size_t num); + +/** + * Startup the image animation. + * @param obj pointer to an animation image object + */ +void lv_animimg_start(lv_obj_t * obj); + +/** + * Set the image animation duration time. unit:ms + * @param img pointer to an animation image object + * @param duration the duration in milliseconds + */ +void lv_animimg_set_duration(lv_obj_t * img, uint32_t duration); + +/** + * Set the image animation repeatedly play times. + * @param img pointer to an animation image object + * @param count the number of times to repeat the animation + */ +void lv_animimg_set_repeat_count(lv_obj_t * img, uint32_t count); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the image animation images source. + * @param img pointer to an animation image object + * @return a pointer that will point to a series images + */ +const void ** lv_animimg_get_src(lv_obj_t * img); + +/** + * Get the image animation images source. + * @param img pointer to an animation image object + * @return the number of source images + */ +uint8_t lv_animimg_get_src_count(lv_obj_t * img); + +/** + * Get the image animation duration time. unit:ms + * @param img pointer to an animation image object + * @return the animation duration time + */ +uint32_t lv_animimg_get_duration(lv_obj_t * img); + +/** + * Get the image animation repeat play times. + * @param img pointer to an animation image object + * @return the repeat count + */ +uint32_t lv_animimg_get_repeat_count(lv_obj_t * img); + +/** + * Get the image animation underlying animation. + * @param img pointer to an animation image object + * @return the animation reference + */ +lv_anim_t * lv_animimg_get_anim(lv_obj_t * img); + +#endif /*LV_USE_ANIMIMG*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_ANIMIMAGE_H*/ diff --git a/test/include/liblvgl/widgets/animimage/lv_animimage_private.h b/test/include/liblvgl/widgets/animimage/lv_animimage_private.h new file mode 100644 index 00000000..a5ef5ebb --- /dev/null +++ b/test/include/liblvgl/widgets/animimage/lv_animimage_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_animimage_private.h + * + */ + +#ifndef LV_ANIMIMAGE_PRIVATE_H +#define LV_ANIMIMAGE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../image/lv_image_private.h" +#include "../../misc/lv_anim_private.h" +#include "lv_animimage.h" + +#if LV_USE_ANIMIMG != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of the animimage */ +struct _lv_animimg_t { + lv_image_t img; + lv_anim_t anim; + /* picture sequence */ + const void ** dsc; + int8_t pic_count; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_ANIMIMG != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ANIMIMAGE_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/arc/lv_arc.h b/test/include/liblvgl/widgets/arc/lv_arc.h new file mode 100644 index 00000000..f241745f --- /dev/null +++ b/test/include/liblvgl/widgets/arc/lv_arc.h @@ -0,0 +1,247 @@ +/** + * @file lv_arc.h + * + */ + +#ifndef LV_ARC_H +#define LV_ARC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_ARC != 0 + +#include "../../core/lv_obj.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_ARC_MODE_NORMAL, + LV_ARC_MODE_SYMMETRICAL, + LV_ARC_MODE_REVERSE +} lv_arc_mode_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_arc_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an arc object + * @param parent pointer to an object, it will be the parent of the new arc + * @return pointer to the created arc + */ +lv_obj_t * lv_arc_create(lv_obj_t * parent); + +/*====================== + * Add/remove functions + *=====================*/ + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the start angle of an arc. 0 deg: right, 90 bottom, etc. + * @param obj pointer to an arc object + * @param start the start angle. (if `LV_USE_FLOAT` is enabled it can be fractional too.) + */ +void lv_arc_set_start_angle(lv_obj_t * obj, lv_value_precise_t start); + +/** + * Set the end angle of an arc. 0 deg: right, 90 bottom, etc. + * @param obj pointer to an arc object + * @param end the end angle (if `LV_USE_FLOAT` is enabled it can be fractional too.) + */ +void lv_arc_set_end_angle(lv_obj_t * obj, lv_value_precise_t end); + +/** + * Set the start and end angles + * @param obj pointer to an arc object + * @param start the start angle (if `LV_USE_FLOAT` is enabled it can be fractional too.) + * @param end the end angle (if `LV_USE_FLOAT` is enabled it can be fractional too.) + */ +void lv_arc_set_angles(lv_obj_t * obj, lv_value_precise_t start, lv_value_precise_t end); + +/** + * Set the start angle of an arc background. 0 deg: right, 90 bottom, etc. + * @param obj pointer to an arc object + * @param start the start angle (if `LV_USE_FLOAT` is enabled it can be fractional too.) + */ +void lv_arc_set_bg_start_angle(lv_obj_t * obj, lv_value_precise_t start); + +/** + * Set the start angle of an arc background. 0 deg: right, 90 bottom etc. + * @param obj pointer to an arc object + * @param end the end angle (if `LV_USE_FLOAT` is enabled it can be fractional too.) + */ +void lv_arc_set_bg_end_angle(lv_obj_t * obj, lv_value_precise_t end); + +/** + * Set the start and end angles of the arc background + * @param obj pointer to an arc object + * @param start the start angle (if `LV_USE_FLOAT` is enabled it can be fractional too.) + * @param end the end angle (if `LV_USE_FLOAT` is enabled it can be fractional too.) + */ +void lv_arc_set_bg_angles(lv_obj_t * obj, lv_value_precise_t start, lv_value_precise_t end); + +/** + * Set the rotation for the whole arc + * @param obj pointer to an arc object + * @param rotation rotation angle + */ +void lv_arc_set_rotation(lv_obj_t * obj, int32_t rotation); + +/** + * Set the type of arc. + * @param obj pointer to arc object + * @param type arc's mode + */ +void lv_arc_set_mode(lv_obj_t * obj, lv_arc_mode_t type); + +/** + * Set a new value on the arc + * @param obj pointer to an arc object + * @param value new value + */ +void lv_arc_set_value(lv_obj_t * obj, int32_t value); + +/** + * Set minimum and the maximum values of an arc + * @param obj pointer to the arc object + * @param min minimum value + * @param max maximum value + */ +void lv_arc_set_range(lv_obj_t * obj, int32_t min, int32_t max); + +/** + * Set a change rate to limit the speed how fast the arc should reach the pressed point. + * @param obj pointer to an arc object + * @param rate the change rate + */ +void lv_arc_set_change_rate(lv_obj_t * obj, uint32_t rate); + +/** + * Set an offset angle for the knob + * @param obj pointer to an arc object + * @param offset knob offset from main arc in degrees + */ +void lv_arc_set_knob_offset(lv_obj_t * obj, int32_t offset); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the start angle of an arc. + * @param obj pointer to an arc object + * @return the start angle [0..360] (if `LV_USE_FLOAT` is enabled it can be fractional too.) + */ +lv_value_precise_t lv_arc_get_angle_start(lv_obj_t * obj); + +/** + * Get the end angle of an arc. + * @param obj pointer to an arc object + * @return the end angle [0..360] (if `LV_USE_FLOAT` is enabled it can be fractional too.) + */ +lv_value_precise_t lv_arc_get_angle_end(lv_obj_t * obj); + +/** + * Get the start angle of an arc background. + * @param obj pointer to an arc object + * @return the start angle [0..360] (if `LV_USE_FLOAT` is enabled it can be fractional too.) + */ +lv_value_precise_t lv_arc_get_bg_angle_start(lv_obj_t * obj); + +/** + * Get the end angle of an arc background. + * @param obj pointer to an arc object + * @return the end angle [0..360] (if `LV_USE_FLOAT` is enabled it can be fractional too.) + */ +lv_value_precise_t lv_arc_get_bg_angle_end(lv_obj_t * obj); + +/** + * Get the value of an arc + * @param obj pointer to an arc object + * @return the value of the arc + */ +int32_t lv_arc_get_value(const lv_obj_t * obj); + +/** + * Get the minimum value of an arc + * @param obj pointer to an arc object + * @return the minimum value of the arc + */ +int32_t lv_arc_get_min_value(const lv_obj_t * obj); + +/** + * Get the maximum value of an arc + * @param obj pointer to an arc object + * @return the maximum value of the arc + */ +int32_t lv_arc_get_max_value(const lv_obj_t * obj); + +/** + * Get whether the arc is type or not. + * @param obj pointer to an arc object + * @return arc's mode + */ +lv_arc_mode_t lv_arc_get_mode(const lv_obj_t * obj); + +/** + * Get the rotation for the whole arc + * @param obj pointer to an arc object + * @return arc's current rotation + */ +int32_t lv_arc_get_rotation(const lv_obj_t * obj); + +/** + * Get the current knob angle offset + * @param obj pointer to an arc object + * @return arc's current knob offset + */ +int32_t lv_arc_get_knob_offset(const lv_obj_t * obj); + +/*===================== + * Other functions + *====================*/ + +/** + * Align an object to the current position of the arc (knob) + * @param obj pointer to an arc object + * @param obj_to_align pointer to an object to align + * @param r_offset consider the radius larger with this value (< 0: for smaller radius) + */ +void lv_arc_align_obj_to_angle(const lv_obj_t * obj, lv_obj_t * obj_to_align, int32_t r_offset); + +/** + * Rotate an object to the current position of the arc (knob) + * @param obj pointer to an arc object + * @param obj_to_rotate pointer to an object to rotate + * @param r_offset consider the radius larger with this value (< 0: for smaller radius) + */ +void lv_arc_rotate_obj_to_angle(const lv_obj_t * obj, lv_obj_t * obj_to_rotate, int32_t r_offset); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_ARC*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ARC_H*/ diff --git a/test/include/liblvgl/widgets/arc/lv_arc_private.h b/test/include/liblvgl/widgets/arc/lv_arc_private.h new file mode 100644 index 00000000..71f576a4 --- /dev/null +++ b/test/include/liblvgl/widgets/arc/lv_arc_private.h @@ -0,0 +1,64 @@ +/** + * @file lv_arc_private.h + * + */ + +#ifndef LV_ARC_PRIVATE_H +#define LV_ARC_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj_private.h" +#include "lv_arc.h" + +#if LV_USE_ARC != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_arc_t { + lv_obj_t obj; + int32_t rotation; + lv_value_precise_t indic_angle_start; + lv_value_precise_t indic_angle_end; + lv_value_precise_t bg_angle_start; + lv_value_precise_t bg_angle_end; + int32_t value; /**< Current value of the arc */ + int32_t min_value; /**< Minimum value of the arc */ + int32_t max_value; /**< Maximum value of the arc */ + uint32_t dragging : 1; + uint32_t type : 2; + uint32_t min_close : 1; /**< 1: the last pressed angle was closer to minimum end */ + uint32_t in_out : 1; /**< 1: The click was within the background arc angles. 0: Click outside */ + uint32_t chg_rate; /**< Drag angle rate of change of the arc (degrees/sec) */ + uint32_t last_tick; /**< Last dragging event timestamp of the arc */ + lv_value_precise_t last_angle; /**< Last dragging angle of the arc */ + int16_t knob_offset; /**< knob offset from the main arc */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_ARC != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ARC_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/bar/lv_bar.h b/test/include/liblvgl/widgets/bar/lv_bar.h new file mode 100644 index 00000000..93c88786 --- /dev/null +++ b/test/include/liblvgl/widgets/bar/lv_bar.h @@ -0,0 +1,162 @@ +/** + * @file lv_bar.h + * + */ + +#ifndef LV_BAR_H +#define LV_BAR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_BAR != 0 + +#include "../../core/lv_obj.h" +#include "../../misc/lv_anim.h" +#include "../label/lv_label.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_BAR_MODE_NORMAL, + LV_BAR_MODE_SYMMETRICAL, + LV_BAR_MODE_RANGE +} lv_bar_mode_t; + +typedef enum { + LV_BAR_ORIENTATION_AUTO, + LV_BAR_ORIENTATION_HORIZONTAL, + LV_BAR_ORIENTATION_VERTICAL +} lv_bar_orientation_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_bar_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a bar object + * @param parent pointer to an object, it will be the parent of the new bar + * @return pointer to the created bar + */ +lv_obj_t * lv_bar_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set a new value on the bar + * @param obj pointer to a bar object + * @param value new value + * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + */ +void lv_bar_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim); + +/** + * Set a new start value on the bar + * @param obj pointer to a bar object + * @param start_value new start value + * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + */ +void lv_bar_set_start_value(lv_obj_t * obj, int32_t start_value, lv_anim_enable_t anim); + +/** + * Set minimum and the maximum values of a bar + * @param obj pointer to the bar object + * @param min minimum value + * @param max maximum value + * @note If min is greater than max, the drawing direction becomes to the opposite direction. + */ +void lv_bar_set_range(lv_obj_t * obj, int32_t min, int32_t max); + +/** + * Set the type of bar. + * @param obj pointer to bar object + * @param mode bar type from ::lv_bar_mode_t + */ +void lv_bar_set_mode(lv_obj_t * obj, lv_bar_mode_t mode); + +/** + * Set the orientation of bar. + * @param obj pointer to bar object + * @param orientation bar orientation from `lv_bar_orientation_t` + */ +void lv_bar_set_orientation(lv_obj_t * obj, lv_bar_orientation_t orientation); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the value of a bar + * @param obj pointer to a bar object + * @return the value of the bar + */ +int32_t lv_bar_get_value(const lv_obj_t * obj); + +/** + * Get the start value of a bar + * @param obj pointer to a bar object + * @return the start value of the bar + */ +int32_t lv_bar_get_start_value(const lv_obj_t * obj); + +/** + * Get the minimum value of a bar + * @param obj pointer to a bar object + * @return the minimum value of the bar + */ +int32_t lv_bar_get_min_value(const lv_obj_t * obj); + +/** + * Get the maximum value of a bar + * @param obj pointer to a bar object + * @return the maximum value of the bar + */ +int32_t lv_bar_get_max_value(const lv_obj_t * obj); + +/** + * Get the type of bar. + * @param obj pointer to bar object + * @return bar type from ::lv_bar_mode_t + */ +lv_bar_mode_t lv_bar_get_mode(lv_obj_t * obj); + +/** + * Get the orientation of bar. + * @param obj pointer to bar object + * @return bar orientation from ::lv_bar_orientation_t + */ +lv_bar_orientation_t lv_bar_get_orientation(lv_obj_t * obj); + +/** + * Give the bar is in symmetrical mode or not + * @param obj pointer to bar object + * @return true: in symmetrical mode false : not in +*/ +bool lv_bar_is_symmetrical(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_BAR*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BAR_H*/ diff --git a/test/include/liblvgl/widgets/bar/lv_bar_private.h b/test/include/liblvgl/widgets/bar/lv_bar_private.h new file mode 100644 index 00000000..c403805f --- /dev/null +++ b/test/include/liblvgl/widgets/bar/lv_bar_private.h @@ -0,0 +1,66 @@ +/** + * @file lv_bar_private.h + * + */ + +#ifndef LV_BAR_PRIVATE_H +#define LV_BAR_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_bar.h" + +#if LV_USE_BAR != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_bar_anim_t { + lv_obj_t * bar; + int32_t anim_start; + int32_t anim_end; + int32_t anim_state; +}; + +struct _lv_bar_t { + lv_obj_t obj; + int32_t cur_value; /**< Current value of the bar*/ + int32_t min_value; /**< Minimum value of the bar*/ + int32_t max_value; /**< Maximum value of the bar*/ + int32_t start_value; /**< Start value of the bar*/ + lv_area_t indic_area; /**< Save the indicator area. Might be used by derived types*/ + bool val_reversed; /**< Whether value been reversed */ + lv_bar_anim_t cur_value_anim; + lv_bar_anim_t start_value_anim; + lv_bar_mode_t mode : 3; /**< Type of bar*/ + lv_bar_orientation_t orientation : 3; /**< Orientation of bar*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_BAR != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BAR_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/button/lv_button.h b/test/include/liblvgl/widgets/button/lv_button.h new file mode 100644 index 00000000..eb7a0a57 --- /dev/null +++ b/test/include/liblvgl/widgets/button/lv_button.h @@ -0,0 +1,48 @@ +/** + * @file lv_button.h + * + */ + +#ifndef LV_BUTTON_H +#define LV_BUTTON_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_BUTTON != 0 +#include "../../core/lv_obj.h" + +/********************* + * DEFINES + *********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_button_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a button object + * @param parent pointer to an object, it will be the parent of the new button + * @return pointer to the created button + */ +lv_obj_t * lv_button_create(lv_obj_t * parent); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_BUTTON*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BUTTON_H*/ diff --git a/test/include/liblvgl/widgets/button/lv_button_private.h b/test/include/liblvgl/widgets/button/lv_button_private.h new file mode 100644 index 00000000..c89c93aa --- /dev/null +++ b/test/include/liblvgl/widgets/button/lv_button_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_button_private.h + * + */ + +#ifndef LV_BUTTON_PRIVATE_H +#define LV_BUTTON_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_button.h" + +#if LV_USE_BUTTON != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_button_t { + lv_obj_t obj; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_BUTTON != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BUTTON_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/buttonmatrix/lv_buttonmatrix.h b/test/include/liblvgl/widgets/buttonmatrix/lv_buttonmatrix.h new file mode 100644 index 00000000..8333b564 --- /dev/null +++ b/test/include/liblvgl/widgets/buttonmatrix/lv_buttonmatrix.h @@ -0,0 +1,202 @@ +/** + * @file lv_buttonmatrix.h + * + */ + +#ifndef LV_BUTTONMATRIX_H +#define LV_BUTTONMATRIX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_BUTTONMATRIX != 0 + +#include "../../core/lv_obj.h" + +/********************* + * DEFINES + *********************/ +#define LV_BUTTONMATRIX_BUTTON_NONE 0xFFFF +LV_EXPORT_CONST_INT(LV_BUTTONMATRIX_BUTTON_NONE); + +/********************** + * TYPEDEFS + **********************/ + +/** Type to store button control bits (disabled, hidden etc.) + * The first 3 bits are used to store the width*/ +typedef enum { + LV_BUTTONMATRIX_CTRL_HIDDEN = 0x0010, /**< Button hidden*/ + LV_BUTTONMATRIX_CTRL_NO_REPEAT = 0x0020, /**< Do not repeat press this button.*/ + LV_BUTTONMATRIX_CTRL_DISABLED = 0x0040, /**< Disable this button.*/ + LV_BUTTONMATRIX_CTRL_CHECKABLE = 0x0080, /**< The button can be toggled.*/ + LV_BUTTONMATRIX_CTRL_CHECKED = 0x0100, /**< Button is currently toggled (e.g. checked).*/ + LV_BUTTONMATRIX_CTRL_CLICK_TRIG = 0x0200, /**< 1: Send LV_EVENT_VALUE_CHANGE on CLICK, 0: Send LV_EVENT_VALUE_CHANGE on PRESS*/ + LV_BUTTONMATRIX_CTRL_POPOVER = 0x0400, /**< Show a popover when pressing this key*/ + LV_BUTTONMATRIX_CTRL_RECOLOR = 0x0800, /**< Enable text recoloring with `#color`*/ + LV_BUTTONMATRIX_CTRL_RESERVED_2 = 0x1000, /**< Reserved for later use*/ + LV_BUTTONMATRIX_CTRL_RESERVED_3 = 0x2000, /**< Reserved for later use*/ + LV_BUTTONMATRIX_CTRL_CUSTOM_1 = 0x4000, /**< Custom free to use flag*/ + LV_BUTTONMATRIX_CTRL_CUSTOM_2 = 0x8000, /**< Custom free to use flag*/ +} lv_buttonmatrix_ctrl_t; + +typedef bool (*lv_buttonmatrix_button_draw_cb_t)(lv_obj_t * btnm, uint32_t btn_id, const lv_area_t * draw_area, + const lv_area_t * clip_area); + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_buttonmatrix_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a button matrix object + * @param parent pointer to an object, it will be the parent of the new button matrix + * @return pointer to the created button matrix + */ +lv_obj_t * lv_buttonmatrix_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set a new map. Buttons will be created/deleted according to the map. The + * button matrix keeps a reference to the map and so the string array must not + * be deallocated during the life of the matrix. + * @param obj pointer to a button matrix object + * @param map pointer a string array. The last string has to be: "". Use "\n" to make a line break. + */ +void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * const map[]); + +/** + * Set the button control map (hidden, disabled etc.) for a button matrix. + * The control map array will be copied and so may be deallocated after this + * function returns. + * @param obj pointer to a button matrix object + * @param ctrl_map pointer to an array of `lv_button_ctrl_t` control bytes. The + * length of the array and position of the elements must match + * the number and order of the individual buttons (i.e. excludes + * newline entries). + * An element of the map should look like e.g.: + * `ctrl_map[0] = width | LV_BUTTONMATRIX_CTRL_NO_REPEAT | LV_BUTTONMATRIX_CTRL_TGL_ENABLE` + */ +void lv_buttonmatrix_set_ctrl_map(lv_obj_t * obj, const lv_buttonmatrix_ctrl_t ctrl_map[]); + +/** + * Set the selected buttons + * @param obj pointer to button matrix object + * @param btn_id 0 based index of the button to modify. (Not counting new lines) + */ +void lv_buttonmatrix_set_selected_button(lv_obj_t * obj, uint32_t btn_id); + +/** + * Set the attributes of a button of the button matrix + * @param obj pointer to button matrix object + * @param btn_id 0 based index of the button to modify. (Not counting new lines) + * @param ctrl OR-ed attributes. E.g. `LV_BUTTONMATRIX_CTRL_NO_REPEAT | LV_BUTTONMATRIX_CTRL_CHECKABLE` + */ +void lv_buttonmatrix_set_button_ctrl(lv_obj_t * obj, uint32_t btn_id, lv_buttonmatrix_ctrl_t ctrl); + +/** + * Clear the attributes of a button of the button matrix + * @param obj pointer to button matrix object + * @param btn_id 0 based index of the button to modify. (Not counting new lines) + * @param ctrl OR-ed attributes. E.g. `LV_BUTTONMATRIX_CTRL_NO_REPEAT | LV_BUTTONMATRIX_CTRL_CHECKABLE` + */ +void lv_buttonmatrix_clear_button_ctrl(lv_obj_t * obj, uint32_t btn_id, lv_buttonmatrix_ctrl_t ctrl); + +/** + * Set attributes of all buttons of a button matrix + * @param obj pointer to a button matrix object + * @param ctrl attribute(s) to set from `lv_buttonmatrix_ctrl_t`. Values can be ORed. + */ +void lv_buttonmatrix_set_button_ctrl_all(lv_obj_t * obj, lv_buttonmatrix_ctrl_t ctrl); + +/** + * Clear the attributes of all buttons of a button matrix + * @param obj pointer to a button matrix object + * @param ctrl attribute(s) to set from `lv_buttonmatrix_ctrl_t`. Values can be ORed. + */ +void lv_buttonmatrix_clear_button_ctrl_all(lv_obj_t * obj, lv_buttonmatrix_ctrl_t ctrl); + +/** + * Set a single button's relative width. + * This method will cause the matrix be regenerated and is a relatively + * expensive operation. It is recommended that initial width be specified using + * `lv_buttonmatrix_set_ctrl_map` and this method only be used for dynamic changes. + * @param obj pointer to button matrix object + * @param btn_id 0 based index of the button to modify. + * @param width relative width compared to the buttons in the same row. [1..15] + */ +void lv_buttonmatrix_set_button_width(lv_obj_t * obj, uint32_t btn_id, uint32_t width); + +/** + * Make the button matrix like a selector widget (only one button may be checked at a time). + * `LV_BUTTONMATRIX_CTRL_CHECKABLE` must be enabled on the buttons to be selected using + * `lv_buttonmatrix_set_ctrl()` or `lv_buttonmatrix_set_button_ctrl_all()`. + * @param obj pointer to a button matrix object + * @param en whether "one check" mode is enabled + */ +void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the current map of a button matrix + * @param obj pointer to a button matrix object + * @return the current map + */ +const char * const * lv_buttonmatrix_get_map(const lv_obj_t * obj); + +/** + * Get the index of the lastly "activated" button by the user (pressed, released, focused etc) + * Useful in the `event_cb` to get the text of the button, check if hidden etc. + * @param obj pointer to button matrix object + * @return index of the last released button (LV_BUTTONMATRIX_BUTTON_NONE: if unset) + */ +uint32_t lv_buttonmatrix_get_selected_button(const lv_obj_t * obj); + +/** + * Get the button's text + * @param obj pointer to button matrix object + * @param btn_id the index a button not counting new line characters. + * @return text of btn_index` button + */ +const char * lv_buttonmatrix_get_button_text(const lv_obj_t * obj, uint32_t btn_id); + +/** + * Get the whether a control value is enabled or disabled for button of a button matrix + * @param obj pointer to a button matrix object + * @param btn_id the index of a button not counting new line characters. + * @param ctrl control values to check (ORed value can be used) + * @return true: the control attribute is enabled false: disabled + */ +bool lv_buttonmatrix_has_button_ctrl(lv_obj_t * obj, uint32_t btn_id, lv_buttonmatrix_ctrl_t ctrl); + +/** + * Tell whether "one check" mode is enabled or not. + * @param obj Button matrix object + * @return true: "one check" mode is enabled; false: disabled + */ +bool lv_buttonmatrix_get_one_checked(const lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_BUTTONMATRIX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BUTTONMATRIX_H*/ diff --git a/test/include/liblvgl/widgets/buttonmatrix/lv_buttonmatrix_private.h b/test/include/liblvgl/widgets/buttonmatrix/lv_buttonmatrix_private.h new file mode 100644 index 00000000..824bdcb0 --- /dev/null +++ b/test/include/liblvgl/widgets/buttonmatrix/lv_buttonmatrix_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_buttonmatrix_private.h + * + */ + +#ifndef LV_BUTTONMATRIX_PRIVATE_H +#define LV_BUTTONMATRIX_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_buttonmatrix.h" + +#if LV_USE_BUTTONMATRIX != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of button matrix */ +struct _lv_buttonmatrix_t { + lv_obj_t obj; + const char * const * map_p; /**< Pointer to the current map */ + lv_area_t * button_areas; /**< Array of areas of buttons */ + lv_buttonmatrix_ctrl_t * ctrl_bits; /**< Array of control bytes */ + uint32_t btn_cnt; /**< Number of button in 'map_p'(Handled by the library) */ + uint32_t row_cnt; /**< Number of rows in 'map_p'(Handled by the library) */ + uint32_t btn_id_sel; /**< Index of the active button (being pressed/released etc) or LV_BUTTONMATRIX_BUTTON_NONE */ + uint32_t one_check : 1; /**< Single button toggled at once */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_BUTTONMATRIX != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BUTTONMATRIX_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/calendar/lv_calendar.h b/test/include/liblvgl/widgets/calendar/lv_calendar.h new file mode 100644 index 00000000..38c5d644 --- /dev/null +++ b/test/include/liblvgl/widgets/calendar/lv_calendar.h @@ -0,0 +1,160 @@ +/** + * @file lv_calendar.h + * + */ + +#ifndef LV_CALENDAR_H +#define LV_CALENDAR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../buttonmatrix/lv_buttonmatrix.h" + +#if LV_USE_CALENDAR + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Represents a date on the calendar object (platform-agnostic). + */ +typedef struct { + uint16_t year; + int8_t month; /**< 1..12 */ + int8_t day; /**< 1..31 */ +} lv_calendar_date_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_calendar_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a calendar widget + * @param parent pointer to an object, it will be the parent of the new calendar + * @return pointer the created calendar + */ +lv_obj_t * lv_calendar_create(lv_obj_t * parent); + +/*====================== + * Add/remove functions + *=====================*/ + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the today's date + * @param obj pointer to a calendar object + * @param year today's year + * @param month today's month [1..12] + * @param day today's day [1..31] + */ +void lv_calendar_set_today_date(lv_obj_t * obj, uint32_t year, uint32_t month, uint32_t day); + +/** + * Set the currently showed + * @param obj pointer to a calendar object + * @param year today's year + * @param month today's month [1..12] + */ +void lv_calendar_set_showed_date(lv_obj_t * obj, uint32_t year, uint32_t month); + +/** + * Set the highlighted dates + * @param obj pointer to a calendar object + * @param highlighted pointer to an `lv_calendar_date_t` array containing the dates. + * Only the pointer will be saved so this variable can't be local which will be destroyed later. + * @param date_num number of dates in the array + */ +void lv_calendar_set_highlighted_dates(lv_obj_t * obj, lv_calendar_date_t highlighted[], size_t date_num); + +/** + * Set the name of the days + * @param obj pointer to a calendar object + * @param day_names pointer to an array with the names. + * E.g. `const char * days[7] = {"Sun", "Mon", ...}` + * Only the pointer will be saved so this variable can't be local which will be destroyed later. + */ +void lv_calendar_set_day_names(lv_obj_t * obj, const char ** day_names); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the button matrix object of the calendar. + * It shows the dates and day names. + * @param obj pointer to a calendar object + * @return pointer to a the button matrix + */ +lv_obj_t * lv_calendar_get_btnmatrix(const lv_obj_t * obj); + +/** + * Get the today's date + * @param calendar pointer to a calendar object + * @return return pointer to an `lv_calendar_date_t` variable containing the date of today. + */ +const lv_calendar_date_t * lv_calendar_get_today_date(const lv_obj_t * calendar); + +/** + * Get the currently showed + * @param calendar pointer to a calendar object + * @return pointer to an `lv_calendar_date_t` variable containing the date is being shown. + */ +const lv_calendar_date_t * lv_calendar_get_showed_date(const lv_obj_t * calendar); + +/** + * Get the highlighted dates + * @param calendar pointer to a calendar object + * @return pointer to an `lv_calendar_date_t` array containing the dates. + */ +lv_calendar_date_t * lv_calendar_get_highlighted_dates(const lv_obj_t * calendar); + +/** + * Get the number of the highlighted dates + * @param calendar pointer to a calendar object + * @return number of highlighted days + */ +size_t lv_calendar_get_highlighted_dates_num(const lv_obj_t * calendar); + +/** + * Get the currently pressed day + * @param calendar pointer to a calendar object + * @param date store the pressed date here + * @return LV_RESULT_OK: there is a valid pressed date + * LV_RESULT_INVALID: there is no pressed data + */ +lv_result_t lv_calendar_get_pressed_date(const lv_obj_t * calendar, lv_calendar_date_t * date); + +/*===================== + * Other functions + *====================*/ + +/********************** + * MACROS + **********************/ + +#include "lv_calendar_header_arrow.h" +#include "lv_calendar_header_dropdown.h" +#include "lv_calendar_chinese.h" + +#endif /*LV_USE_CALENDAR*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CALENDAR_H*/ diff --git a/test/include/liblvgl/widgets/calendar/lv_calendar_chinese.h b/test/include/liblvgl/widgets/calendar/lv_calendar_chinese.h new file mode 100644 index 00000000..fb7a1bc0 --- /dev/null +++ b/test/include/liblvgl/widgets/calendar/lv_calendar_chinese.h @@ -0,0 +1,68 @@ +/** + * @file lv_calendar_chinese.h + * + */ + +#ifndef LV_CALENDAR_CHINESE_H +#define LV_CALENDAR_CHINESE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" +#include "lv_calendar.h" +#if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_calendar_date_t today; + bool leep_month; +} lv_calendar_chinese_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Enable the chinese calendar. + * @param obj pointer to a calendar object. + * @param en true: enable chinese calendar; false: disable + */ +void lv_calendar_set_chinese_mode(lv_obj_t * obj, bool en); + +/** + * Get the name of the day + * @param gregorian to obtain the gregorian time for the name + * @return return the name of the day + */ +const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian); + +/** + * Get the chinese time of the gregorian time (reference: https://www.cnblogs.com/liyang31tg/p/4123171.html) + * @param gregorian_time need to convert to chinese time in gregorian time + * @param chinese_time the chinese time convert from gregorian time + */ +void lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian_time, lv_calendar_chinese_t * chinese_time); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_CALENDAR_CHINESE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CALENDAR_CHINESE_H*/ diff --git a/test/include/liblvgl/widgets/calendar/lv_calendar_chinese_private.h b/test/include/liblvgl/widgets/calendar/lv_calendar_chinese_private.h new file mode 100644 index 00000000..5572259e --- /dev/null +++ b/test/include/liblvgl/widgets/calendar/lv_calendar_chinese_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_calendar_chinese_private.h + * + */ + +#ifndef LV_CALENDAR_CHINESE_PRIVATE_H +#define LV_CALENDAR_CHINESE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_calendar_chinese.h" + +#if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_calendar_chinese_t { + lv_calendar_date_t today; + bool leep_month; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CALENDAR_CHINESE_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/calendar/lv_calendar_header_arrow.h b/test/include/liblvgl/widgets/calendar/lv_calendar_header_arrow.h new file mode 100644 index 00000000..a04b355c --- /dev/null +++ b/test/include/liblvgl/widgets/calendar/lv_calendar_header_arrow.h @@ -0,0 +1,49 @@ +/** + * @file lv_calendar_header_arrow.h + * + */ + +#ifndef LV_CALENDAR_HEADER_ARROW_H +#define LV_CALENDAR_HEADER_ARROW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" +#if LV_USE_CALENDAR && LV_USE_CALENDAR_HEADER_ARROW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_calendar_header_arrow_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a calendar header with drop-drowns to select the year and month + * @param parent pointer to a calendar object. + * @return the created header + */ +lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_CALENDAR_HEADER_ARROW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CALENDAR_HEADER_ARROW_H*/ diff --git a/test/include/liblvgl/widgets/calendar/lv_calendar_header_dropdown.h b/test/include/liblvgl/widgets/calendar/lv_calendar_header_dropdown.h new file mode 100644 index 00000000..1ca87762 --- /dev/null +++ b/test/include/liblvgl/widgets/calendar/lv_calendar_header_dropdown.h @@ -0,0 +1,62 @@ +/** + * @file lv_calendar_header_dropdown.h + * + */ + +#ifndef LV_CALENDAR_HEADER_DROPDOWN_H +#define LV_CALENDAR_HEADER_DROPDOWN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" +#if LV_USE_CALENDAR && LV_USE_CALENDAR_HEADER_DROPDOWN + +#if LV_USE_DROPDOWN == 0 +#error "LV_USE_DROPDOWN needs to be enabled" +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_calendar_header_dropdown_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a calendar header with drop-drowns to select the year and month + * @param parent pointer to a calendar object. + * @return the created header + */ +lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent); + +/** + * Sets a custom calendar year list + * @param parent pointer to a calendar object + * @param years_list pointer to an const char array with the years list, see lv_dropdown set_options for more information. + * E.g. `const char * years = "2023\n2022\n2021\n2020\n2019" + * Only the pointer will be saved so this variable can't be local which will be destroyed later. + */ +void lv_calendar_header_dropdown_set_year_list(lv_obj_t * parent, const char * years_list); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_CALENDAR_HEADER_ARROW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CALENDAR_HEADER_DROPDOWN_H*/ diff --git a/test/include/liblvgl/widgets/calendar/lv_calendar_private.h b/test/include/liblvgl/widgets/calendar/lv_calendar_private.h new file mode 100644 index 00000000..0a5b8a2e --- /dev/null +++ b/test/include/liblvgl/widgets/calendar/lv_calendar_private.h @@ -0,0 +1,70 @@ +/** + * @file lv_calendar_private.h + * + */ + +#ifndef LV_CALENDAR_PRIVATE_H +#define LV_CALENDAR_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_calendar.h" + +#if LV_USE_CALENDAR + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of calendar */ +struct _lv_calendar_t { + lv_obj_t obj; + /* New data for this type */ + lv_obj_t * btnm; + lv_calendar_date_t today; /**< Date of today */ + lv_calendar_date_t showed_date; /**< Currently visible month (day is ignored) */ + lv_calendar_date_t * highlighted_dates; /**< Apply different style on these days (pointer to user-defined array) */ + size_t highlighted_dates_num; /**< Number of elements in `highlighted_days` */ + const char * map[8 * 7]; +#ifdef LV_USE_CALENDAR_CHINESE + bool use_chinese_calendar; + + /** 7 * 6: A week has 7 days, and the calendar displays 6 weeks in total. + * 20: Including the number of dates, line breaks, names for each day, + * and reserving several spaces for addresses. */ + char nums [7 * 6][20]; +#else + /** 7 * 6: A week has 7 days, and the calendar displays 6 weeks in total. + * 6: Including the number of dates, and reserving several spaces for + * addresses.*/ + char nums [7 * 6][4]; +#endif +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_CALENDAR */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CALENDAR_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/canvas/lv_canvas.h b/test/include/liblvgl/widgets/canvas/lv_canvas.h new file mode 100644 index 00000000..d669b177 --- /dev/null +++ b/test/include/liblvgl/widgets/canvas/lv_canvas.h @@ -0,0 +1,185 @@ +/** + * @file lv_canvas.h + * + */ + +#ifndef LV_CANVAS_H +#define LV_CANVAS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_CANVAS != 0 + +#include "../image/lv_image.h" +#include "../../draw/lv_draw_image.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_canvas_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a canvas object + * @param parent pointer to an object, it will be the parent of the new canvas + * @return pointer to the created canvas + */ +lv_obj_t * lv_canvas_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set a buffer for the canvas. + * + * Use lv_canvas_set_draw_buf() instead if you need to set a buffer with alignment requirement. + * + * @param obj pointer to a canvas object + * @param buf buffer where content of canvas will be. + * The required size is (lv_image_color_format_get_px_size(cf) * w) / 8 * h) + * It can be allocated with `lv_malloc()` or + * it can be statically allocated array (e.g. static lv_color_t buf[100*50]) or + * it can be an address in RAM or external SRAM + * @param w width of canvas + * @param h height of canvas + * @param cf color format. `LV_COLOR_FORMAT...` + */ +void lv_canvas_set_buffer(lv_obj_t * obj, void * buf, int32_t w, int32_t h, lv_color_format_t cf); + +/** + * Set a draw buffer for the canvas. A draw buffer either can be allocated by `lv_draw_buf_create()` + * or defined statically by `LV_DRAW_BUF_DEFINE_STATIC`. When buffer start address and stride has alignment + * requirement, it's recommended to use `lv_draw_buf_create`. + * @param obj pointer to a canvas object + * @param draw_buf pointer to a draw buffer + */ +void lv_canvas_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf); + +/** + * Set a pixel's color and opacity + * @param obj pointer to a canvas + * @param x X coordinate of the pixel + * @param y Y coordinate of the pixel + * @param color the color + * @param opa the opacity + * @note The following color formats are supported + * LV_COLOR_FORMAT_I1/2/4/8, LV_COLOR_FORMAT_A8, + * LV_COLOR_FORMAT_RGB565, LV_COLOR_FORMAT_RGB888, + * LV_COLOR_FORMAT_XRGB8888, LV_COLOR_FORMAT_ARGB8888 + */ +void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv_opa_t opa); + +/** + * Set the palette color of a canvas for index format. Valid only for `LV_COLOR_FORMAT_I1/2/4/8` + * @param obj pointer to canvas object + * @param index the palette color to set: + * - for `LV_COLOR_FORMAT_I1`: 0..1 + * - for `LV_COLOR_FORMAT_I2`: 0..3 + * - for `LV_COLOR_FORMAT_I4`: 0..15 + * - for `LV_COLOR_FORMAT_I8`: 0..255 + * @param color the color to set + */ +void lv_canvas_set_palette(lv_obj_t * obj, uint8_t index, lv_color32_t color); + +/*===================== + * Getter functions + *====================*/ + +lv_draw_buf_t * lv_canvas_get_draw_buf(lv_obj_t * obj); + +/** + * Get a pixel's color and opacity + * @param obj pointer to a canvas + * @param x X coordinate of the pixel + * @param y Y coordinate of the pixel + * @return ARGB8888 color of the pixel + */ +lv_color32_t lv_canvas_get_px(lv_obj_t * obj, int32_t x, int32_t y); + +/** + * Get the image of the canvas as a pointer to an `lv_image_dsc_t` variable. + * @param canvas pointer to a canvas object + * @return pointer to the image descriptor. + */ +lv_image_dsc_t * lv_canvas_get_image(lv_obj_t * canvas); + +/** + * Return the pointer for the buffer. + * It's recommended to use this function instead of the buffer form the + * return value of lv_canvas_get_image() as is can be aligned + * @param canvas pointer to a canvas object + * @return pointer to the buffer + */ +const void * lv_canvas_get_buf(lv_obj_t * canvas); + +/*===================== + * Other functions + *====================*/ + +/** + * Copy a buffer to the canvas + * @param obj pointer to a canvas object + * @param canvas_area the area of the canvas to copy + * @param dest_buf pointer to a buffer to store the copied data + * @param dest_area the area of the destination buffer to copy to. If omitted NULL, copy to the whole `dest_buf` + */ +void lv_canvas_copy_buf(lv_obj_t * obj, const lv_area_t * canvas_area, lv_draw_buf_t * dest_buf, + const lv_area_t * dest_area); + +/** + * Fill the canvas with color + * @param obj pointer to a canvas + * @param color the background color + * @param opa the desired opacity + */ +void lv_canvas_fill_bg(lv_obj_t * obj, lv_color_t color, lv_opa_t opa); + +/** + * Initialize a layer to use LVGL's generic draw functions (lv_draw_rect/label/...) on the canvas. + * Needs to be usd in pair with `lv_canvas_finish_layer`. + * @param canvas pointer to a canvas + * @param layer pointer to a layer variable to initialize + */ +void lv_canvas_init_layer(lv_obj_t * canvas, lv_layer_t * layer); + +/** + * Wait until all the drawings are finished on layer. + * Needs to be usd in pair with `lv_canvas_init_layer`. + * @param canvas pointer to a canvas + * @param layer pointer to a layer to finalize + */ +void lv_canvas_finish_layer(lv_obj_t * canvas, lv_layer_t * layer); + +/********************** + * MACROS + **********************/ + +#define LV_CANVAS_BUF_SIZE(w, h, bpp, stride) (((((w * bpp + 7) >> 3) + stride - 1) & ~(stride - 1)) * h + LV_DRAW_BUF_ALIGN) + +/** + * Just a wrapper to `LV_CANVAS_BUF_SIZE` for bindings. + */ +uint32_t lv_canvas_buf_size(int32_t w, int32_t h, uint8_t bpp, uint8_t stride); + +#endif /*LV_USE_CANVAS*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CANVAS_H*/ diff --git a/test/include/liblvgl/widgets/canvas/lv_canvas_private.h b/test/include/liblvgl/widgets/canvas/lv_canvas_private.h new file mode 100644 index 00000000..55b30547 --- /dev/null +++ b/test/include/liblvgl/widgets/canvas/lv_canvas_private.h @@ -0,0 +1,52 @@ +/** + * @file lv_canvas_private.h + * + */ + +#ifndef LV_CANVAS_PRIVATE_H +#define LV_CANVAS_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../image/lv_image_private.h" +#include "lv_canvas.h" + +#if LV_USE_CANVAS != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Canvas data */ +struct _lv_canvas_t { + lv_image_t img; + lv_draw_buf_t * draw_buf; + lv_draw_buf_t static_buf; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_CANVAS != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CANVAS_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/chart/lv_chart.h b/test/include/liblvgl/widgets/chart/lv_chart.h new file mode 100644 index 00000000..de258314 --- /dev/null +++ b/test/include/liblvgl/widgets/chart/lv_chart.h @@ -0,0 +1,358 @@ +/** + * @file lv_chart.h + * + */ + +#ifndef LV_CHART_H +#define LV_CHART_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../core/lv_obj.h" + +#if LV_USE_CHART != 0 + +/********************* + * DEFINES + *********************/ + +/**Default value of points. Can be used to not draw a point*/ +#define LV_CHART_POINT_NONE (INT32_MAX) +LV_EXPORT_CONST_INT(LV_CHART_POINT_NONE); + +/********************** + * TYPEDEFS + **********************/ + +/** + * Chart types + */ +typedef enum { + LV_CHART_TYPE_NONE, /**< Don't draw the series*/ + LV_CHART_TYPE_LINE, /**< Connect the points with lines*/ + LV_CHART_TYPE_BAR, /**< Draw columns*/ + LV_CHART_TYPE_SCATTER, /**< Draw points and lines in 2D (x,y coordinates)*/ +} lv_chart_type_t; + +/** + * Chart update mode for `lv_chart_set_next` + */ +typedef enum { + LV_CHART_UPDATE_MODE_SHIFT, /**< Shift old data to the left and add the new one the right*/ + LV_CHART_UPDATE_MODE_CIRCULAR, /**< Add the new data in a circular way*/ +} lv_chart_update_mode_t; + +/** + * Enumeration of the axis' + */ +typedef enum { + LV_CHART_AXIS_PRIMARY_Y = 0x00, + LV_CHART_AXIS_SECONDARY_Y = 0x01, + LV_CHART_AXIS_PRIMARY_X = 0x02, + LV_CHART_AXIS_SECONDARY_X = 0x04, + LV_CHART_AXIS_LAST +} lv_chart_axis_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_chart_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a chart object + * @param parent pointer to an object, it will be the parent of the new chart + * @return pointer to the created chart + */ +lv_obj_t * lv_chart_create(lv_obj_t * parent); + +/** + * Set a new type for a chart + * @param obj pointer to a chart object + * @param type new type of the chart (from 'lv_chart_type_t' enum) + */ +void lv_chart_set_type(lv_obj_t * obj, lv_chart_type_t type); +/** + * Set the number of points on a data line on a chart + * @param obj pointer to a chart object + * @param cnt new number of points on the data lines + */ +void lv_chart_set_point_count(lv_obj_t * obj, uint32_t cnt); + +/** + * Set the minimal and maximal y values on an axis + * @param obj pointer to a chart object + * @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y` + * @param min minimum value of the y axis + * @param max maximum value of the y axis + */ +void lv_chart_set_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, int32_t max); + +/** + * Set update mode of the chart object. Affects + * @param obj pointer to a chart object + * @param update_mode the update mode + */ +void lv_chart_set_update_mode(lv_obj_t * obj, lv_chart_update_mode_t update_mode); + +/** + * Set the number of horizontal and vertical division lines + * @param obj pointer to a chart object + * @param hdiv number of horizontal division lines + * @param vdiv number of vertical division lines + */ +void lv_chart_set_div_line_count(lv_obj_t * obj, uint8_t hdiv, uint8_t vdiv); + +/** + * Get the type of a chart + * @param obj pointer to chart object + * @return type of the chart (from 'lv_chart_t' enum) + */ +lv_chart_type_t lv_chart_get_type(const lv_obj_t * obj); + +/** + * Get the data point number per data line on chart + * @param obj pointer to chart object + * @return point number on each data line + */ +uint32_t lv_chart_get_point_count(const lv_obj_t * obj); + +/** + * Get the current index of the x-axis start point in the data array + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @return the index of the current x start point in the data array + */ +uint32_t lv_chart_get_x_start_point(const lv_obj_t * obj, lv_chart_series_t * ser); + +/** + * Get the position of a point to the chart. + * @param obj pointer to a chart object + * @param ser pointer to series + * @param id the index. + * @param p_out store the result position here + */ +void lv_chart_get_point_pos_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, lv_point_t * p_out); + +/** + * Refresh a chart if its data line has changed + * @param obj pointer to chart object + */ +void lv_chart_refresh(lv_obj_t * obj); + +/*====================== + * Series + *=====================*/ + +/** + * Allocate and add a data series to the chart + * @param obj pointer to a chart object + * @param color color of the data series + * @param axis the y axis to which the series should be attached (::LV_CHART_AXIS_PRIMARY_Y or ::LV_CHART_AXIS_SECONDARY_Y) + * @return pointer to the allocated data series or NULL on failure + */ +lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_chart_axis_t axis); + +/** + * Deallocate and remove a data series from a chart + * @param obj pointer to a chart object + * @param series pointer to a data series on 'chart' + */ +void lv_chart_remove_series(lv_obj_t * obj, lv_chart_series_t * series); + +/** + * Hide/Unhide a single series of a chart. + * @param chart pointer to a chart object. + * @param series pointer to a series object + * @param hide true: hide the series + */ +void lv_chart_hide_series(lv_obj_t * chart, lv_chart_series_t * series, bool hide); + +/** + * Change the color of a series + * @param chart pointer to a chart object. + * @param series pointer to a series object + * @param color the new color of the series + */ +void lv_chart_set_series_color(lv_obj_t * chart, lv_chart_series_t * series, lv_color_t color); + +/** + * Get the color of a series + * @param chart pointer to a chart object. + * @param series pointer to a series object + * @return the color of the series + */ +lv_color_t lv_chart_get_series_color(lv_obj_t * chart, const lv_chart_series_t * series); + +/** + * Set the index of the x-axis start point in the data array. + * This point will be considers the first (left) point and the other points will be drawn after it. + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @param id the index of the x point in the data array + */ +void lv_chart_set_x_start_point(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id); + +/** + * Get the next series. + * @param chart pointer to a chart + * @param ser the previous series or NULL to get the first + * @return the next series or NULL if there is no more. + */ +lv_chart_series_t * lv_chart_get_series_next(const lv_obj_t * chart, const lv_chart_series_t * ser); + +/*===================== + * Cursor + *====================*/ + +/** + * Add a cursor with a given color + * @param obj pointer to chart object + * @param color color of the cursor + * @param dir direction of the cursor. `LV_DIR_RIGHT/LEFT/TOP/DOWN/HOR/VER/ALL`. OR-ed values are possible + * @return pointer to the created cursor + */ +lv_chart_cursor_t * lv_chart_add_cursor(lv_obj_t * obj, lv_color_t color, lv_dir_t dir); + +/** + * Set the coordinate of the cursor with respect to the paddings + * @param chart pointer to a chart object + * @param cursor pointer to the cursor + * @param pos the new coordinate of cursor relative to the chart + */ +void lv_chart_set_cursor_pos(lv_obj_t * chart, lv_chart_cursor_t * cursor, lv_point_t * pos); + +/** + * Stick the cursor to a point + * @param chart pointer to a chart object + * @param cursor pointer to the cursor + * @param ser pointer to a series + * @param point_id the point's index or `LV_CHART_POINT_NONE` to not assign to any points. + */ +void lv_chart_set_cursor_point(lv_obj_t * chart, lv_chart_cursor_t * cursor, lv_chart_series_t * ser, + uint32_t point_id); + +/** + * Get the coordinate of the cursor with respect to the paddings + * @param chart pointer to a chart object + * @param cursor pointer to cursor + * @return coordinate of the cursor as lv_point_t + */ +lv_point_t lv_chart_get_cursor_point(lv_obj_t * chart, lv_chart_cursor_t * cursor); + +/*===================== + * Set/Get value(s) + *====================*/ + +/** + * Initialize all data points of a series with a value + * @param obj pointer to chart object + * @param ser pointer to a data series on 'chart' + * @param value the new value for all points. `LV_CHART_POINT_NONE` can be used to hide the points. + */ +void lv_chart_set_all_value(lv_obj_t * obj, lv_chart_series_t * ser, int32_t value); + +/** + * Set the next point's Y value according to the update mode policy. + * @param obj pointer to chart object + * @param ser pointer to a data series on 'chart' + * @param value the new value of the next data + */ +void lv_chart_set_next_value(lv_obj_t * obj, lv_chart_series_t * ser, int32_t value); + +/** + * Set the next point's X and Y value according to the update mode policy. + * @param obj pointer to chart object + * @param ser pointer to a data series on 'chart' + * @param x_value the new X value of the next data + * @param y_value the new Y value of the next data + */ +void lv_chart_set_next_value2(lv_obj_t * obj, lv_chart_series_t * ser, int32_t x_value, int32_t y_value); + +/** + * Set an individual point's y value of a chart's series directly based on its index + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @param id the index of the x point in the array + * @param value value to assign to array point + */ +void lv_chart_set_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t value); + +/** + * Set an individual point's x and y value of a chart's series directly based on its index + * Can be used only with `LV_CHART_TYPE_SCATTER`. + * @param obj pointer to chart object + * @param ser pointer to a data series on 'chart' + * @param id the index of the x point in the array + * @param x_value the new X value of the next data + * @param y_value the new Y value of the next data + */ +void lv_chart_set_value_by_id2(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t x_value, + int32_t y_value); + +/** + * Set an external array for the y data points to use for the chart + * NOTE: It is the users responsibility to make sure the `point_cnt` matches the external array size. + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @param array external array of points for chart + */ +void lv_chart_set_ext_y_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]); + +/** + * Set an external array for the x data points to use for the chart + * NOTE: It is the users responsibility to make sure the `point_cnt` matches the external array size. + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @param array external array of points for chart + */ +void lv_chart_set_ext_x_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]); + +/** + * Get the array of y values of a series + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @return the array of values with 'point_count' elements + */ +int32_t * lv_chart_get_y_array(const lv_obj_t * obj, lv_chart_series_t * ser); + +/** + * Get the array of x values of a series + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @return the array of values with 'point_count' elements + */ +int32_t * lv_chart_get_x_array(const lv_obj_t * obj, lv_chart_series_t * ser); + +/** + * Get the index of the currently pressed point. It's the same for every series. + * @param obj pointer to a chart object + * @return the index of the point [0 .. point count] or LV_CHART_POINT_ID_NONE if no point is being pressed + */ +uint32_t lv_chart_get_pressed_point(const lv_obj_t * obj); + +/** + * Get the overall offset from the chart's side to the center of the first point. + * In case of a bar chart it will be the center of the first column group + * @param obj pointer to a chart object + * @return the offset of the center + */ +int32_t lv_chart_get_first_point_center_offset(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_CHART*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CHART_H*/ diff --git a/test/include/liblvgl/widgets/chart/lv_chart_private.h b/test/include/liblvgl/widgets/chart/lv_chart_private.h new file mode 100644 index 00000000..4380db21 --- /dev/null +++ b/test/include/liblvgl/widgets/chart/lv_chart_private.h @@ -0,0 +1,85 @@ +/** + * @file lv_chart_private.h + * + */ + +#ifndef LV_CHART_PRIVATE_H +#define LV_CHART_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_chart.h" + +#if LV_USE_CHART != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Descriptor a chart series + */ +struct _lv_chart_series_t { + int32_t * x_points; + int32_t * y_points; + lv_color_t color; + uint32_t start_point; + uint32_t hidden : 1; + uint32_t x_ext_buf_assigned : 1; + uint32_t y_ext_buf_assigned : 1; + uint32_t x_axis_sec : 1; + uint32_t y_axis_sec : 1; +}; + +struct _lv_chart_cursor_t { + lv_point_t pos; + int32_t point_id; + lv_color_t color; + lv_chart_series_t * ser; + lv_dir_t dir; + uint32_t pos_set: 1; /**< 1: pos is set; 0: point_id is set*/ +}; + +struct _lv_chart_t { + lv_obj_t obj; + lv_ll_t series_ll; /**< Linked list for the series (stores lv_chart_series_t)*/ + lv_ll_t cursor_ll; /**< Linked list for the cursors (stores lv_chart_cursor_t)*/ + int32_t ymin[2]; + int32_t ymax[2]; + int32_t xmin[2]; + int32_t xmax[2]; + int32_t pressed_point_id; + uint32_t hdiv_cnt; /**< Number of horizontal division lines*/ + uint32_t vdiv_cnt; /**< Number of vertical division lines*/ + uint32_t point_cnt; /**< Point number in a data line*/ + lv_chart_type_t type : 3; /**< Line or column chart*/ + lv_chart_update_mode_t update_mode : 1; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_CHART != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CHART_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/checkbox/lv_checkbox.h b/test/include/liblvgl/widgets/checkbox/lv_checkbox.h new file mode 100644 index 00000000..804ff600 --- /dev/null +++ b/test/include/liblvgl/widgets/checkbox/lv_checkbox.h @@ -0,0 +1,79 @@ +/** + * @file lv_checkbox.h + * + */ + +#ifndef LV_CHECKBOX_H +#define LV_CHECKBOX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../core/lv_obj.h" + +#if LV_USE_CHECKBOX != 0 + +/********************* + * DEFINES + *********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_checkbox_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a check box object + * @param parent pointer to an object, it will be the parent of the new button + * @return pointer to the created check box + */ +lv_obj_t * lv_checkbox_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the text of a check box. `txt` will be copied and may be deallocated + * after this function returns. + * @param obj pointer to a check box + * @param txt the text of the check box. NULL to refresh with the current text. + */ +void lv_checkbox_set_text(lv_obj_t * obj, const char * txt); + +/** + * Set the text of a check box. `txt` must not be deallocated during the life + * of this checkbox. + * @param obj pointer to a check box + * @param txt the text of the check box. + */ +void lv_checkbox_set_text_static(lv_obj_t * obj, const char * txt); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the text of a check box + * @param obj pointer to check box object + * @return pointer to the text of the check box + */ +const char * lv_checkbox_get_text(const lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_CHECKBOX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CHECKBOX_H*/ diff --git a/test/include/liblvgl/widgets/checkbox/lv_checkbox_private.h b/test/include/liblvgl/widgets/checkbox/lv_checkbox_private.h new file mode 100644 index 00000000..a7167c9d --- /dev/null +++ b/test/include/liblvgl/widgets/checkbox/lv_checkbox_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_checkbox_private.h + * + */ + +#ifndef LV_CHECKBOX_PRIVATE_H +#define LV_CHECKBOX_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_checkbox.h" + +#if LV_USE_CHECKBOX != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_checkbox_t { + lv_obj_t obj; + char * txt; + uint32_t static_txt : 1; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_CHECKBOX != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CHECKBOX_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/dropdown/lv_dropdown.h b/test/include/liblvgl/widgets/dropdown/lv_dropdown.h new file mode 100644 index 00000000..c9f55be1 --- /dev/null +++ b/test/include/liblvgl/widgets/dropdown/lv_dropdown.h @@ -0,0 +1,246 @@ +/** + * @file lv_dropdown.h + * + */ + +#ifndef LV_DROPDOWN_H +#define LV_DROPDOWN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_DROPDOWN != 0 + +/*Testing of dependencies*/ + +#if LV_USE_LABEL == 0 +#error "lv_dropdown: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1)" +#endif + +#include "../label/lv_label.h" + +/********************* + * DEFINES + *********************/ +#define LV_DROPDOWN_POS_LAST 0xFFFF +LV_EXPORT_CONST_INT(LV_DROPDOWN_POS_LAST); + +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(DROPDOWN, TEXT, LV_PROPERTY_TYPE_TEXT, 0), + LV_PROPERTY_ID(DROPDOWN, OPTIONS, LV_PROPERTY_TYPE_TEXT, 1), + LV_PROPERTY_ID(DROPDOWN, OPTION_COUNT, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(DROPDOWN, SELECTED, LV_PROPERTY_TYPE_INT, 3), + // LV_PROPERTY_ID(DROPDOWN, SELECTED_STR, LV_PROPERTY_TYPE_TEXT, 4), + LV_PROPERTY_ID(DROPDOWN, DIR, LV_PROPERTY_TYPE_INT, 5), + LV_PROPERTY_ID(DROPDOWN, SYMBOL, LV_PROPERTY_TYPE_TEXT, 6), + LV_PROPERTY_ID(DROPDOWN, SELECTED_HIGHLIGHT, LV_PROPERTY_TYPE_INT, 7), + LV_PROPERTY_ID(DROPDOWN, LIST, LV_PROPERTY_TYPE_OBJ, 8), + LV_PROPERTY_ID(DROPDOWN, IS_OPEN, LV_PROPERTY_TYPE_BOOL, 9), + LV_PROPERTY_DROPDOWN_END, +}; +#endif + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_dropdown_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_dropdownlist_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a drop-down list object + * @param parent pointer to an object, it will be the parent of the new drop-down list + * @return pointer to the created drop-down list + */ +lv_obj_t * lv_dropdown_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set text of the drop-down list's button. + * If set to `NULL` the selected option's text will be displayed on the button. + * If set to a specific text then that text will be shown regardless of the selected option. + * @param obj pointer to a drop-down list object + * @param txt the text as a string (Only its pointer is saved) + */ +void lv_dropdown_set_text(lv_obj_t * obj, const char * txt); + +/** + * Set the options in a drop-down list from a string. + * The options will be copied and saved in the object so the `options` can be destroyed after calling this function + * @param obj pointer to drop-down list object + * @param options a string with '\n' separated options. E.g. "One\nTwo\nThree" + */ +void lv_dropdown_set_options(lv_obj_t * obj, const char * options); + +/** + * Set the options in a drop-down list from a static string (global, static or dynamically allocated). + * Only the pointer of the option string will be saved. + * @param obj pointer to drop-down list object + * @param options a static string with '\n' separated options. E.g. "One\nTwo\nThree" + */ +void lv_dropdown_set_options_static(lv_obj_t * obj, const char * options); + +/** + * Add an options to a drop-down list from a string. Only works for non-static options. + * @param obj pointer to drop-down list object + * @param option a string without '\n'. E.g. "Four" + * @param pos the insert position, indexed from 0, LV_DROPDOWN_POS_LAST = end of string + */ +void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos); + +/** + * Clear all options in a drop-down list. Works with both static and dynamic options. + * @param obj pointer to drop-down list object + */ +void lv_dropdown_clear_options(lv_obj_t * obj); + +/** + * Set the selected option + * @param obj pointer to drop-down list object + * @param sel_opt id of the selected option (0 ... number of option - 1); + */ +void lv_dropdown_set_selected(lv_obj_t * obj, uint32_t sel_opt); + +/** + * Set the direction of the a drop-down list + * @param obj pointer to a drop-down list object + * @param dir LV_DIR_LEFT/RIGHT/TOP/BOTTOM + */ +void lv_dropdown_set_dir(lv_obj_t * obj, lv_dir_t dir); + +/** + * Set an arrow or other symbol to display when on drop-down list's button. Typically a down caret or arrow. + * @param obj pointer to drop-down list object + * @param symbol a text like `LV_SYMBOL_DOWN`, an image (pointer or path) or NULL to not draw symbol icon + * @note angle and zoom transformation can be applied if the symbol is an image. + * E.g. when drop down is checked (opened) rotate the symbol by 180 degree + */ +void lv_dropdown_set_symbol(lv_obj_t * obj, const void * symbol); + +/** + * Set whether the selected option in the list should be highlighted or not + * @param obj pointer to drop-down list object + * @param en true: highlight enabled; false: disabled + */ +void lv_dropdown_set_selected_highlight(lv_obj_t * obj, bool en); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the list of a drop-down to allow styling or other modifications + * @param obj pointer to a drop-down list object + * @return pointer to the list of the drop-down + */ +lv_obj_t * lv_dropdown_get_list(lv_obj_t * obj); + +/** + * Get text of the drop-down list's button. + * @param obj pointer to a drop-down list object + * @return the text as string, `NULL` if no text + */ +const char * lv_dropdown_get_text(lv_obj_t * obj); + +/** + * Get the options of a drop-down list + * @param obj pointer to drop-down list object + * @return the options separated by '\n'-s (E.g. "Option1\nOption2\nOption3") + */ +const char * lv_dropdown_get_options(const lv_obj_t * obj); + +/** + * Get the index of the selected option + * @param obj pointer to drop-down list object + * @return index of the selected option (0 ... number of option - 1); + */ +uint32_t lv_dropdown_get_selected(const lv_obj_t * obj); + +/** + * Get the total number of options + * @param obj pointer to drop-down list object + * @return the total number of options in the list + */ +uint32_t lv_dropdown_get_option_count(const lv_obj_t * obj); + +/** + * Get the current selected option as a string + * @param obj pointer to drop-down object + * @param buf pointer to an array to store the string + * @param buf_size size of `buf` in bytes. 0: to ignore it. + */ +void lv_dropdown_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_size); + +/** + * Get the index of an option. + * @param obj pointer to drop-down object + * @param option an option as string + * @return index of `option` in the list of all options. -1 if not found. + */ +int32_t lv_dropdown_get_option_index(lv_obj_t * obj, const char * option); + +/** + * Get the symbol on the drop-down list. Typically a down caret or arrow. + * @param obj pointer to drop-down list object + * @return the symbol or NULL if not enabled + */ +const char * lv_dropdown_get_symbol(lv_obj_t * obj); + +/** + * Get whether the selected option in the list should be highlighted or not + * @param obj pointer to drop-down list object + * @return true: highlight enabled; false: disabled + */ +bool lv_dropdown_get_selected_highlight(lv_obj_t * obj); + +/** + * Get the direction of the drop-down list + * @param obj pointer to a drop-down list object + * @return LV_DIR_LEF/RIGHT/TOP/BOTTOM + */ +lv_dir_t lv_dropdown_get_dir(const lv_obj_t * obj); + +/*===================== + * Other functions + *====================*/ + +/** + * Open the drop.down list + * @param dropdown_obj pointer to drop-down list object + */ +void lv_dropdown_open(lv_obj_t * dropdown_obj); + +/** + * Close (Collapse) the drop-down list + * @param obj pointer to drop-down list object + */ +void lv_dropdown_close(lv_obj_t * obj); + +/** + * Tells whether the list is opened or not + * @param obj pointer to a drop-down list object + * @return true if the list os opened + */ +bool lv_dropdown_is_open(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DROPDOWN*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DROPDOWN_H*/ diff --git a/test/include/liblvgl/widgets/dropdown/lv_dropdown_private.h b/test/include/liblvgl/widgets/dropdown/lv_dropdown_private.h new file mode 100644 index 00000000..8229758b --- /dev/null +++ b/test/include/liblvgl/widgets/dropdown/lv_dropdown_private.h @@ -0,0 +1,69 @@ +/** + * @file lv_dropdown_private.h + * + */ + +#ifndef LV_DROPDOWN_PRIVATE_H +#define LV_DROPDOWN_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_dropdown.h" + +#if LV_USE_DROPDOWN != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_dropdown_t { + lv_obj_t obj; + lv_obj_t * list; /**< The dropped down list*/ + const char * text; /**< Text to display on the dropdown's button*/ + const void * symbol; /**< Arrow or other icon when the drop-down list is closed*/ + char * options; /**< Options in a '\n' separated list*/ + uint32_t option_cnt; /**< Number of options*/ + uint32_t sel_opt_id; /**< Index of the currently selected option*/ + uint32_t sel_opt_id_orig; /**< Store the original index on focus*/ + uint32_t pr_opt_id; /**< Index of the currently pressed option*/ + uint8_t dir : 4; /**< Direction in which the list should open*/ + uint8_t static_txt : 1; /**< 1: Only a pointer is saved in `options`*/ + uint8_t selected_highlight: 1; /**< 1: Make the selected option highlighted in the list*/ +}; + +struct _lv_dropdown_list_t { + lv_obj_t obj; + lv_obj_t * dropdown; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DROPDOWN != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DROPDOWN_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/image/lv_image.h b/test/include/liblvgl/widgets/image/lv_image.h new file mode 100644 index 00000000..abc52177 --- /dev/null +++ b/test/include/liblvgl/widgets/image/lv_image.h @@ -0,0 +1,310 @@ +/** + * @file lv_image.h + * + */ + +#ifndef LV_IMAGE_H +#define LV_IMAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_IMAGE != 0 + +/*Testing of dependencies*/ +#if LV_USE_LABEL == 0 +#error "lv_img: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1)" +#endif + +#include "../../core/lv_obj.h" +#include "../../misc/lv_fs.h" +#include "../../draw/lv_draw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_image_class; + +/** + * Image size mode, when image size and object size is different + */ +typedef enum { + LV_IMAGE_ALIGN_DEFAULT = 0, + LV_IMAGE_ALIGN_TOP_LEFT, + LV_IMAGE_ALIGN_TOP_MID, + LV_IMAGE_ALIGN_TOP_RIGHT, + LV_IMAGE_ALIGN_BOTTOM_LEFT, + LV_IMAGE_ALIGN_BOTTOM_MID, + LV_IMAGE_ALIGN_BOTTOM_RIGHT, + LV_IMAGE_ALIGN_LEFT_MID, + LV_IMAGE_ALIGN_RIGHT_MID, + LV_IMAGE_ALIGN_CENTER, + LV_IMAGE_ALIGN_AUTO_TRANSFORM, + LV_IMAGE_ALIGN_STRETCH, + LV_IMAGE_ALIGN_TILE, +} lv_image_align_t; + +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(IMAGE, SRC, LV_PROPERTY_TYPE_IMGSRC, 0), + LV_PROPERTY_ID(IMAGE, OFFSET_X, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(IMAGE, OFFSET_Y, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(IMAGE, ROTATION, LV_PROPERTY_TYPE_INT, 3), + LV_PROPERTY_ID(IMAGE, PIVOT, LV_PROPERTY_TYPE_POINT, 4), + LV_PROPERTY_ID(IMAGE, SCALE, LV_PROPERTY_TYPE_INT, 5), + LV_PROPERTY_ID(IMAGE, SCALE_X, LV_PROPERTY_TYPE_INT, 6), + LV_PROPERTY_ID(IMAGE, SCALE_Y, LV_PROPERTY_TYPE_INT, 7), + LV_PROPERTY_ID(IMAGE, BLEND_MODE, LV_PROPERTY_TYPE_INT, 8), + LV_PROPERTY_ID(IMAGE, ANTIALIAS, LV_PROPERTY_TYPE_INT, 9), + LV_PROPERTY_ID(IMAGE, INNER_ALIGN, LV_PROPERTY_TYPE_INT, 10), + LV_PROPERTY_IMAGE_END, +}; +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an image object + * @param parent pointer to an object, it will be the parent of the new image + * @return pointer to the created image + */ +lv_obj_t * lv_image_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the image data to display on the object + * @param obj pointer to an image object + * @param src 1) pointer to an ::lv_image_dsc_t descriptor (converted by LVGL's image converter) (e.g. &my_img) or + * 2) path to an image file (e.g. "S:/dir/img.bin")or + * 3) a SYMBOL (e.g. LV_SYMBOL_OK) + */ +void lv_image_set_src(lv_obj_t * obj, const void * src); + +/** + * Set an offset for the source of an image so the image will be displayed from the new origin. + * @param obj pointer to an image + * @param x the new offset along x axis. + */ +void lv_image_set_offset_x(lv_obj_t * obj, int32_t x); + +/** + * Set an offset for the source of an image. + * so the image will be displayed from the new origin. + * @param obj pointer to an image + * @param y the new offset along y axis. + */ +void lv_image_set_offset_y(lv_obj_t * obj, int32_t y); + +/** + * Set the rotation angle of the image. + * The image will be rotated around the set pivot set by `lv_image_set_pivot()` + * Note that indexed and alpha only images can't be transformed. + * @param obj pointer to an image object + * @param angle rotation in degree with 0.1 degree resolution (0..3600: clock wise) + * @note if image_align is `LV_IMAGE_ALIGN_STRETCH` or `LV_IMAGE_ALIGN_FIT` + * rotation will be set to 0 automatically. + * + */ +void lv_image_set_rotation(lv_obj_t * obj, int32_t angle); + +/** + * Set the rotation center of the image. + * The image will be rotated around this point. + * x, y can be set with value of LV_PCT, lv_image_get_pivot will return the true pixel coordinate of pivot in this case. + * @param obj pointer to an image object + * @param x rotation center x of the image + * @param y rotation center y of the image + */ +void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y); + +/** + * Set the zoom factor of the image. + * Note that indexed and alpha only images can't be transformed. + * @param obj pointer to an image object + * @param zoom the zoom factor. Example values: + * - 256 or LV_ZOOM_IMAGE_NONE: no zoom + * - <256: scale down + * - >256: scale up + * - 128: half size + * - 512: double size + */ +void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom); + +/** + * Set the horizontal zoom factor of the image. + * Note that indexed and alpha only images can't be transformed. + * @param obj pointer to an image object + * @param zoom the zoom factor. Example values: + * - 256 or LV_ZOOM_IMAGE_NONE: no zoom + * - <256: scale down + * - >256: scale up + * - 128: half size + * - 512: double size + */ +void lv_image_set_scale_x(lv_obj_t * obj, uint32_t zoom); + +/** + * Set the vertical zoom factor of the image. + * Note that indexed and alpha only images can't be transformed. + * @param obj pointer to an image object + * @param zoom the zoom factor. Example values: + * - 256 or LV_ZOOM_IMAGE_NONE: no zoom + * - <256: scale down + * - >256: scale up + * - 128: half size + * - 512: double size + */ +void lv_image_set_scale_y(lv_obj_t * obj, uint32_t zoom); + +/** + * Set the blend mode of an image. + * @param obj pointer to an image object + * @param blend_mode the new blend mode + */ +void lv_image_set_blend_mode(lv_obj_t * obj, lv_blend_mode_t blend_mode); + +/** + * Enable/disable anti-aliasing for the transformations (rotate, zoom) or not. + * The quality is better with anti-aliasing looks better but slower. + * @param obj pointer to an image object + * @param antialias true: anti-aliased; false: not anti-aliased + */ +void lv_image_set_antialias(lv_obj_t * obj, bool antialias); + +/** + * Set the image object size mode. + * @param obj pointer to an image object + * @param align the new align mode. + * @note if image_align is `LV_IMAGE_ALIGN_STRETCH` or `LV_IMAGE_ALIGN_FIT` + * rotation, scale and pivot will be overwritten and controlled internally. + */ +void lv_image_set_inner_align(lv_obj_t * obj, lv_image_align_t align); + +/** + * Set an A8 bitmap mask for the image. + * @param obj pointer to an image object + * @param src an lv_image_dsc_t bitmap mask source. + */ +void lv_image_set_bitmap_map_src(lv_obj_t * obj, const lv_image_dsc_t * src); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the source of the image + * @param obj pointer to an image object + * @return the image source (symbol, file name or ::lv-img_dsc_t for C arrays) + */ +const void * lv_image_get_src(lv_obj_t * obj); + +/** + * Get the offset's x attribute of the image object. + * @param obj pointer to an image + * @return offset X value. + */ +int32_t lv_image_get_offset_x(lv_obj_t * obj); + +/** + * Get the offset's y attribute of the image object. + * @param obj pointer to an image + * @return offset Y value. + */ +int32_t lv_image_get_offset_y(lv_obj_t * obj); + +/** + * Get the rotation of the image. + * @param obj pointer to an image object + * @return rotation in 0.1 degrees (0..3600) + * @note if image_align is `LV_IMAGE_ALIGN_STRETCH` or `LV_IMAGE_ALIGN_FIT` + * rotation will be set to 0 automatically. + */ +int32_t lv_image_get_rotation(lv_obj_t * obj); + +/** + * Get the pivot (rotation center) of the image. + * If pivot is set with LV_PCT, convert it to px before return. + * @param obj pointer to an image object + * @param pivot store the rotation center here + */ +void lv_image_get_pivot(lv_obj_t * obj, lv_point_t * pivot); + +/** + * Get the zoom factor of the image. + * @param obj pointer to an image object + * @return zoom factor (256: no zoom) + */ +int32_t lv_image_get_scale(lv_obj_t * obj); + +/** + * Get the horizontal zoom factor of the image. + * @param obj pointer to an image object + * @return zoom factor (256: no zoom) + */ +int32_t lv_image_get_scale_x(lv_obj_t * obj); + +/** + * Get the vertical zoom factor of the image. + * @param obj pointer to an image object + * @return zoom factor (256: no zoom) + */ +int32_t lv_image_get_scale_y(lv_obj_t * obj); + +/** + * Get the current blend mode of the image + * @param obj pointer to an image object + * @return the current blend mode + */ +lv_blend_mode_t lv_image_get_blend_mode(lv_obj_t * obj); + +/** + * Get whether the transformations (rotate, zoom) are anti-aliased or not + * @param obj pointer to an image object + * @return true: anti-aliased; false: not anti-aliased + */ +bool lv_image_get_antialias(lv_obj_t * obj); + +/** + * Get the size mode of the image + * @param obj pointer to an image object + * @return element of `lv_image_align_t` + */ +lv_image_align_t lv_image_get_inner_align(lv_obj_t * obj); + +/** + * Get the bitmap mask source. + * @param obj pointer to an image object + * @return an lv_image_dsc_t bitmap mask source. + */ +const lv_image_dsc_t * lv_image_get_bitmap_map_src(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +/** Use this macro to declare an image in a C file*/ +#define LV_IMAGE_DECLARE(var_name) extern const lv_image_dsc_t var_name + +#endif /*LV_USE_IMAGE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGE_H*/ diff --git a/test/include/liblvgl/widgets/image/lv_image_private.h b/test/include/liblvgl/widgets/image/lv_image_private.h new file mode 100644 index 00000000..c13acf4e --- /dev/null +++ b/test/include/liblvgl/widgets/image/lv_image_private.h @@ -0,0 +1,66 @@ +/** + * @file lv_image_private.h + * + */ + +#ifndef LV_IMAGE_PRIVATE_H +#define LV_IMAGE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_image.h" + +#if LV_USE_IMAGE != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Data of image + */ +struct _lv_image_t { + lv_obj_t obj; + const void * src; /**< Image source: Pointer to an array or a file or a symbol*/ + const lv_image_dsc_t * bitmap_mask_src; /**< Pointer to an A8 bitmap mask */ + lv_point_t offset; + int32_t w; /**< Width of the image (Handled by the library)*/ + int32_t h; /**< Height of the image (Handled by the library)*/ + uint32_t rotation; /**< Rotation angle of the image*/ + uint32_t scale_x; /**< 256 means no zoom, 512 double size, 128 half size*/ + uint32_t scale_y; /**< 256 means no zoom, 512 double size, 128 half size*/ + lv_point_t pivot; /**< Rotation center of the image*/ + uint32_t src_type : 2; /**< See: lv_image_src_t*/ + uint32_t cf : 5; /**< Color format from `lv_color_format_t`*/ + uint32_t antialias : 1; /**< Apply anti-aliasing in transformations (rotate, zoom)*/ + uint32_t align: 4; /**< Image size mode when image size and object size is different. See lv_image_align_t*/ + uint32_t blend_mode: 4; /**< Element of `lv_blend_mode_t`*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_IMAGE != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGE_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/imagebutton/lv_imagebutton.h b/test/include/liblvgl/widgets/imagebutton/lv_imagebutton.h new file mode 100644 index 00000000..ed6dc3a5 --- /dev/null +++ b/test/include/liblvgl/widgets/imagebutton/lv_imagebutton.h @@ -0,0 +1,121 @@ +/** + * @file lv_imagebutton.h + * + */ + +#ifndef LV_IMAGEBUTTON_H +#define LV_IMAGEBUTTON_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_IMAGEBUTTON != 0 + +/********************* + * DEFINES + *********************/ +typedef enum { + LV_IMAGEBUTTON_STATE_RELEASED, + LV_IMAGEBUTTON_STATE_PRESSED, + LV_IMAGEBUTTON_STATE_DISABLED, + LV_IMAGEBUTTON_STATE_CHECKED_RELEASED, + LV_IMAGEBUTTON_STATE_CHECKED_PRESSED, + LV_IMAGEBUTTON_STATE_CHECKED_DISABLED, + LV_IMAGEBUTTON_STATE_NUM, +} lv_imagebutton_state_t; + +/********************** + * TYPEDEFS + **********************/ +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_imagebutton_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an image button object + * @param parent pointer to an object, it will be the parent of the new image button + * @return pointer to the created image button + */ +lv_obj_t * lv_imagebutton_create(lv_obj_t * parent); + +/*====================== + * Add/remove functions + *=====================*/ + +/*===================== + * Setter functions + *====================*/ + +/** + * Set images for a state of the image button + * @param imagebutton pointer to an image button object + * @param state for which state set the new image + * @param src_left pointer to an image source for the left side of the button (a C array or path to + * a file) + * @param src_mid pointer to an image source for the middle of the button (ideally 1px wide) (a C + * array or path to a file) + * @param src_right pointer to an image source for the right side of the button (a C array or path + * to a file) + */ +void lv_imagebutton_set_src(lv_obj_t * imagebutton, lv_imagebutton_state_t state, const void * src_left, + const void * src_mid, + const void * src_right); + +/** + * Use this function instead of `lv_obj_add/remove_state` to set a state manually + * @param imagebutton pointer to an image button object + * @param state the new state + */ +void lv_imagebutton_set_state(lv_obj_t * imagebutton, lv_imagebutton_state_t state); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the left image in a given state + * @param imagebutton pointer to an image button object + * @param state the state where to get the image (from `lv_button_state_t`) ` + * @return pointer to the left image source (a C array or path to a file) + */ +const void * lv_imagebutton_get_src_left(lv_obj_t * imagebutton, lv_imagebutton_state_t state); + +/** + * Get the middle image in a given state + * @param imagebutton pointer to an image button object + * @param state the state where to get the image (from `lv_button_state_t`) ` + * @return pointer to the middle image source (a C array or path to a file) + */ +const void * lv_imagebutton_get_src_middle(lv_obj_t * imagebutton, lv_imagebutton_state_t state); + +/** + * Get the right image in a given state + * @param imagebutton pointer to an image button object + * @param state the state where to get the image (from `lv_button_state_t`) ` + * @return pointer to the left image source (a C array or path to a file) + */ +const void * lv_imagebutton_get_src_right(lv_obj_t * imagebutton, lv_imagebutton_state_t state); + +/*===================== + * Other functions + *====================*/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_IMAGEBUTTON*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGEBUTTON_H*/ diff --git a/test/include/liblvgl/widgets/imagebutton/lv_imagebutton_private.h b/test/include/liblvgl/widgets/imagebutton/lv_imagebutton_private.h new file mode 100644 index 00000000..107f49df --- /dev/null +++ b/test/include/liblvgl/widgets/imagebutton/lv_imagebutton_private.h @@ -0,0 +1,58 @@ +/** + * @file lv_imagebutton_private.h + * + */ + +#ifndef LV_IMAGEBUTTON_PRIVATE_H +#define LV_IMAGEBUTTON_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_imagebutton.h" + +#if LV_USE_IMAGEBUTTON != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_imagebutton_src_info_t { + const void * img_src; + lv_image_header_t header; +}; + +/** Data of image button */ +struct _lv_imagebutton_t { + lv_obj_t obj; + lv_imagebutton_src_info_t src_mid[LV_IMAGEBUTTON_STATE_NUM]; /**< Store center images to each state */ + lv_imagebutton_src_info_t src_left[LV_IMAGEBUTTON_STATE_NUM]; /**< Store left side images to each state */ + lv_imagebutton_src_info_t src_right[LV_IMAGEBUTTON_STATE_NUM]; /**< Store right side images to each state */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_IMAGEBUTTON != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGEBUTTON_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/keyboard/lv_keyboard.h b/test/include/liblvgl/widgets/keyboard/lv_keyboard.h new file mode 100644 index 00000000..f177c184 --- /dev/null +++ b/test/include/liblvgl/widgets/keyboard/lv_keyboard.h @@ -0,0 +1,183 @@ +/** + * @file lv_keyboard.h + * + */ + +#ifndef LV_KEYBOARD_H +#define LV_KEYBOARD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../buttonmatrix/lv_buttonmatrix.h" + +#if LV_USE_KEYBOARD + +/*Testing of dependencies*/ +#if LV_USE_BUTTONMATRIX == 0 +#error "lv_buttonmatrix is required. Enable it in lv_conf.h (LV_USE_BUTTONMATRIX 1) " +#endif + +#if LV_USE_TEXTAREA == 0 +#error "lv_textarea is required. Enable it in lv_conf.h (LV_USE_TEXTAREA 1) " +#endif + +/********************* + * DEFINES + *********************/ +#define LV_KEYBOARD_CTRL_BUTTON_FLAGS (LV_BUTTONMATRIX_CTRL_NO_REPEAT | LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKED) + +/********************** + * TYPEDEFS + **********************/ + +/** Current keyboard mode.*/ +typedef enum { + LV_KEYBOARD_MODE_TEXT_LOWER, + LV_KEYBOARD_MODE_TEXT_UPPER, + LV_KEYBOARD_MODE_SPECIAL, + LV_KEYBOARD_MODE_NUMBER, + LV_KEYBOARD_MODE_USER_1, + LV_KEYBOARD_MODE_USER_2, + LV_KEYBOARD_MODE_USER_3, + LV_KEYBOARD_MODE_USER_4, +#if LV_USE_ARABIC_PERSIAN_CHARS == 1 + LV_KEYBOARD_MODE_TEXT_ARABIC +#endif +} lv_keyboard_mode_t; + +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(KEYBOARD, TEXTAREA, LV_PROPERTY_TYPE_OBJ, 0), + LV_PROPERTY_ID(KEYBOARD, MODE, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(KEYBOARD, POPOVERS, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(KEYBOARD, SELECTED_BUTTON, LV_PROPERTY_TYPE_INT, 3), + LV_PROPERTY_KEYBOARD_END, +}; +#endif + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_keyboard_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a Keyboard object + * @param parent pointer to an object, it will be the parent of the new keyboard + * @return pointer to the created keyboard + */ +lv_obj_t * lv_keyboard_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Assign a Text Area to the Keyboard. The pressed characters will be put there. + * @param kb pointer to a Keyboard object + * @param ta pointer to a Text Area object to write there + */ +void lv_keyboard_set_textarea(lv_obj_t * kb, lv_obj_t * ta); + +/** + * Set a new a mode (text or number map) + * @param kb pointer to a Keyboard object + * @param mode the mode from 'lv_keyboard_mode_t' + */ +void lv_keyboard_set_mode(lv_obj_t * kb, lv_keyboard_mode_t mode); + +/** + * Show the button title in a popover when pressed. + * @param kb pointer to a Keyboard object + * @param en whether "popovers" mode is enabled + */ +void lv_keyboard_set_popovers(lv_obj_t * kb, bool en); + +/** + * Set a new map for the keyboard + * @param kb pointer to a Keyboard object + * @param mode keyboard map to alter 'lv_keyboard_mode_t' + * @param map pointer to a string array to describe the map. + * See 'lv_buttonmatrix_set_map()' for more info. + * @param ctrl_map See 'lv_buttonmatrix_set_ctrl_map()' for more info. + + */ +void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * const map[], + const lv_buttonmatrix_ctrl_t ctrl_map[]); + +/*===================== + * Getter functions + *====================*/ + +/** + * Assign a Text Area to the Keyboard. The pressed characters will be put there. + * @param kb pointer to a Keyboard object + * @return pointer to the assigned Text Area object + */ +lv_obj_t * lv_keyboard_get_textarea(const lv_obj_t * kb); + +/** + * Set a new a mode (text or number map) + * @param kb pointer to a Keyboard object + * @return the current mode from 'lv_keyboard_mode_t' + */ +lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * kb); + +/** + * Tell whether "popovers" mode is enabled or not. + * @param obj pointer to a Keyboard object + * @return true: "popovers" mode is enabled; false: disabled + */ +bool lv_keyboard_get_popovers(const lv_obj_t * obj); + +/** + * Get the current map of a keyboard + * @param kb pointer to a keyboard object + * @return the current map + */ +const char * const * lv_keyboard_get_map_array(const lv_obj_t * kb); + +/** + * Get the index of the lastly "activated" button by the user (pressed, released, focused etc) + * Useful in the `event_cb` to get the text of the button, check if hidden etc. + * @param obj pointer to button matrix object + * @return index of the last released button (LV_BUTTONMATRIX_BUTTON_NONE: if unset) + */ +uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj); + +/** + * Get the button's text + * @param obj pointer to button matrix object + * @param btn_id the index a button not counting new line characters. + * @return text of btn_index` button + */ +const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id); + +/*===================== + * Other functions + *====================*/ + +/** + * Default keyboard event to add characters to the Text area and change the map. + * If a custom `event_cb` is added to the keyboard this function can be called from it to handle the + * button clicks + * @param e the triggering event + */ +void lv_keyboard_def_event_cb(lv_event_t * e); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_KEYBOARD*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_KEYBOARD_H*/ diff --git a/test/include/liblvgl/widgets/keyboard/lv_keyboard_private.h b/test/include/liblvgl/widgets/keyboard/lv_keyboard_private.h new file mode 100644 index 00000000..3de02734 --- /dev/null +++ b/test/include/liblvgl/widgets/keyboard/lv_keyboard_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_keyboard_private.h + * + */ + +#ifndef LV_KEYBOARD_PRIVATE_H +#define LV_KEYBOARD_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../buttonmatrix/lv_buttonmatrix_private.h" +#include "lv_keyboard.h" + +#if LV_USE_KEYBOARD + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of keyboard */ +struct _lv_keyboard_t { + lv_buttonmatrix_t btnm; + lv_obj_t * ta; /**< Pointer to the assigned text area */ + lv_keyboard_mode_t mode; /**< Key map type */ + uint8_t popovers : 1; /**< Show button titles in popovers on press */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_KEYBOARD */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_KEYBOARD_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/label/lv_label.h b/test/include/liblvgl/widgets/label/lv_label.h new file mode 100644 index 00000000..d9fddd81 --- /dev/null +++ b/test/include/liblvgl/widgets/label/lv_label.h @@ -0,0 +1,238 @@ +/** + * @file lv_label.h + * + */ + +#ifndef LV_LABEL_H +#define LV_LABEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_LABEL != 0 + +#include "../../misc/lv_types.h" +#include "../../core/lv_obj.h" +#include "../../font/lv_font.h" +#include "../../font/lv_symbol_def.h" +#include "../../misc/lv_text.h" +#include "../../draw/lv_draw.h" + +/********************* + * DEFINES + *********************/ +#define LV_LABEL_DOT_NUM 3 +#define LV_LABEL_POS_LAST 0xFFFF +#define LV_LABEL_TEXT_SELECTION_OFF LV_DRAW_LABEL_NO_TXT_SEL +#if LV_WIDGETS_HAS_DEFAULT_VALUE +#define LV_LABEL_DEFAULT_TEXT "Text" +#else +#define LV_LABEL_DEFAULT_TEXT "" +#endif + +LV_EXPORT_CONST_INT(LV_LABEL_DOT_NUM); +LV_EXPORT_CONST_INT(LV_LABEL_POS_LAST); +LV_EXPORT_CONST_INT(LV_LABEL_TEXT_SELECTION_OFF); + +/********************** + * TYPEDEFS + **********************/ + +/** Long mode behaviors. Used in 'lv_label_ext_t'*/ +typedef enum { + LV_LABEL_LONG_WRAP, /**< Keep the object width, wrap lines longer than object width and expand the object height*/ + LV_LABEL_LONG_DOT, /**< Keep the size and write dots at the end if the text is too long*/ + LV_LABEL_LONG_SCROLL, /**< Keep the size and roll the text back and forth*/ + LV_LABEL_LONG_SCROLL_CIRCULAR, /**< Keep the size and roll the text circularly*/ + LV_LABEL_LONG_CLIP, /**< Keep the size and clip the text out of it*/ +} lv_label_long_mode_t; + +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(LABEL, TEXT, LV_PROPERTY_TYPE_TEXT, 0), + LV_PROPERTY_ID(LABEL, LONG_MODE, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(LABEL, TEXT_SELECTION_START, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(LABEL, TEXT_SELECTION_END, LV_PROPERTY_TYPE_INT, 3), + LV_PROPERTY_LABEL_END, +}; +#endif + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_label_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a label object + * @param parent pointer to an object, it will be the parent of the new label. + * @return pointer to the created button + */ +lv_obj_t * lv_label_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set a new text for a label. Memory will be allocated to store the text by the label. + * @param obj pointer to a label object + * @param text '\0' terminated character string. NULL to refresh with the current text. + */ +void lv_label_set_text(lv_obj_t * obj, const char * text); + +/** + * Set a new formatted text for a label. Memory will be allocated to store the text by the label. + * @param obj pointer to a label object + * @param fmt `printf`-like format + * + * Example: + * @code + * lv_label_set_text_fmt(label1, "%d user", user_num); + * @endcode + */ +void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...) LV_FORMAT_ATTRIBUTE(2, 3); + +/** + * Set a static text. It will not be saved by the label so the 'text' variable + * has to be 'alive' while the label exists. + * @param obj pointer to a label object + * @param text pointer to a text. NULL to refresh with the current text. + */ +void lv_label_set_text_static(lv_obj_t * obj, const char * text); + +/** + * Set the behavior of the label with text longer than the object size + * @param obj pointer to a label object + * @param long_mode the new mode from 'lv_label_long_mode' enum. + * In LV_LONG_WRAP/DOT/SCROLL/SCROLL_CIRC the size of the label should be set AFTER this function + */ +void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode); + +/** + * Set where text selection should start + * @param obj pointer to a label object + * @param index character index from where selection should start. `LV_LABEL_TEXT_SELECTION_OFF` for no selection + */ +void lv_label_set_text_selection_start(lv_obj_t * obj, uint32_t index); + +/** + * Set where text selection should end + * @param obj pointer to a label object + * @param index character index where selection should end. `LV_LABEL_TEXT_SELECTION_OFF` for no selection + */ +void lv_label_set_text_selection_end(lv_obj_t * obj, uint32_t index); + +/** + * Enable the recoloring by in-line commands + * @param obj pointer to a label object + * @param en true: enable recoloring, false: disable + * @example "This is a #ff0000 red# word" + */ +void lv_label_set_recolor(lv_obj_t * obj, bool en); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the text of a label + * @param obj pointer to a label object + * @return the text of the label + */ +char * lv_label_get_text(const lv_obj_t * obj); + +/** + * Get the long mode of a label + * @param obj pointer to a label object + * @return the current long mode + */ +lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * obj); + +/** + * Get the relative x and y coordinates of a letter + * @param obj pointer to a label object + * @param char_id index of the character [0 ... text length - 1]. + * Expressed in character index, not byte index (different in UTF-8) + * @param pos store the result here (E.g. index = 0 gives 0;0 coordinates if the text if aligned to the left) + */ +void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t * pos); + +/** + * Get the index of letter on a relative point of a label. + * @param obj pointer to label object + * @param pos_in pointer to point with coordinates on a the label + * @param bidi whether to use bidi processed + * @return The index of the letter on the 'pos_p' point (E.g. on 0;0 is the 0. letter if aligned to the left) + * Expressed in character index and not byte index (different in UTF-8) + */ +uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool bidi); + +/** + * Check if a character is drawn under a point. + * @param obj pointer to a label object + * @param pos Point to check for character under + * @return whether a character is drawn under the point + */ +bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos); + +/** + * @brief Get the selection start index. + * @param obj pointer to a label object. + * @return selection start index. `LV_LABEL_TEXT_SELECTION_OFF` if nothing is selected. + */ +uint32_t lv_label_get_text_selection_start(const lv_obj_t * obj); + +/** + * @brief Get the selection end index. + * @param obj pointer to a label object. + * @return selection end index. `LV_LABEL_TXT_SEL_OFF` if nothing is selected. + */ +uint32_t lv_label_get_text_selection_end(const lv_obj_t * obj); + +/** + * @brief Get the recoloring attribute + * @param obj pointer to a label object. + * @return true: recoloring is enabled, false: recoloring is disabled + */ +bool lv_label_get_recolor(const lv_obj_t * obj); + +/*===================== + * Other functions + *====================*/ + +/** + * Insert a text to a label. The label text cannot be static. + * @param obj pointer to a label object + * @param pos character index to insert. Expressed in character index and not byte index. + * 0: before first char. LV_LABEL_POS_LAST: after last char. + * @param txt pointer to the text to insert + */ +void lv_label_ins_text(lv_obj_t * obj, uint32_t pos, const char * txt); + +/** + * Delete characters from a label. The label text cannot be static. + * @param obj pointer to a label object + * @param pos character index from where to cut. Expressed in character index and not byte index. + * 0: start in front of the first character + * @param cnt number of characters to cut + */ +void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_LABEL*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LABEL_H*/ diff --git a/test/include/liblvgl/widgets/label/lv_label_private.h b/test/include/liblvgl/widgets/label/lv_label_private.h new file mode 100644 index 00000000..d3c3cc88 --- /dev/null +++ b/test/include/liblvgl/widgets/label/lv_label_private.h @@ -0,0 +1,74 @@ +/** + * @file lv_label_private.h + * + */ + +#ifndef LV_LABEL_PRIVATE_H +#define LV_LABEL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../draw/lv_draw_label_private.h" +#include "../../core/lv_obj_private.h" +#include "lv_label.h" + +#if LV_USE_LABEL != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_label_t { + lv_obj_t obj; + char * text; + union { + char * tmp_ptr; /**< Pointer to the allocated memory containing the character replaced by dots */ + char tmp[LV_LABEL_DOT_NUM + 1]; /**< Directly store the characters if <=4 characters */ + } dot; + uint32_t dot_end; /**< The real text length, used in dot mode */ + +#if LV_LABEL_LONG_TXT_HINT + lv_draw_label_hint_t hint; +#endif + +#if LV_LABEL_TEXT_SELECTION + uint32_t sel_start; + uint32_t sel_end; +#endif + + lv_point_t size_cache; /**< Text size cache */ + lv_point_t offset; /**< Text draw position offset */ + lv_label_long_mode_t long_mode : 3; /**< Determine what to do with the long texts */ + uint8_t static_txt : 1; /**< Flag to indicate the text is static */ + uint8_t recolor : 1; /**< Enable in-line letter re-coloring*/ + uint8_t expand : 1; /**< Ignore real width (used by the library with LV_LABEL_LONG_SCROLL) */ + uint8_t dot_tmp_alloc : 1; /**< 1: dot is allocated, 0: dot directly holds up to 4 chars */ + uint8_t invalid_size_cache : 1; /**< 1: Recalculate size and update cache */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LABEL != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LABEL_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/led/lv_led.h b/test/include/liblvgl/widgets/led/lv_led.h new file mode 100644 index 00000000..c085a97f --- /dev/null +++ b/test/include/liblvgl/widgets/led/lv_led.h @@ -0,0 +1,99 @@ +/** + * @file lv_led.h + * + */ + +#ifndef LV_LED_H +#define LV_LED_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_LED + +/********************* + * DEFINES + *********************/ +/** Brightness when the LED if OFF */ +#ifndef LV_LED_BRIGHT_MIN +# define LV_LED_BRIGHT_MIN 80 +#endif + +/** Brightness when the LED if ON */ +#ifndef LV_LED_BRIGHT_MAX +# define LV_LED_BRIGHT_MAX 255 +#endif + +/********************** + * TYPEDEFS + **********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_led_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a led object + * @param parent pointer to an object, it will be the parent of the new led + * @return pointer to the created led + */ +lv_obj_t * lv_led_create(lv_obj_t * parent); + +/** + * Set the color of the LED + * @param led pointer to a LED object + * @param color the color of the LED + */ +void lv_led_set_color(lv_obj_t * led, lv_color_t color); + +/** + * Set the brightness of a LED object + * @param led pointer to a LED object + * @param bright LV_LED_BRIGHT_MIN (max. dark) ... LV_LED_BRIGHT_MAX (max. light) + */ +void lv_led_set_brightness(lv_obj_t * led, uint8_t bright); + +/** + * Light on a LED + * @param led pointer to a LED object + */ +void lv_led_on(lv_obj_t * led); + +/** + * Light off a LED + * @param led pointer to a LED object + */ +void lv_led_off(lv_obj_t * led); + +/** + * Toggle the state of a LED + * @param led pointer to a LED object + */ +void lv_led_toggle(lv_obj_t * led); + +/** + * Get the brightness of a LED object + * @param obj pointer to LED object + * @return bright 0 (max. dark) ... 255 (max. light) + */ +uint8_t lv_led_get_brightness(const lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_LED*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LED_H*/ diff --git a/test/include/liblvgl/widgets/led/lv_led_private.h b/test/include/liblvgl/widgets/led/lv_led_private.h new file mode 100644 index 00000000..77b5490f --- /dev/null +++ b/test/include/liblvgl/widgets/led/lv_led_private.h @@ -0,0 +1,52 @@ +/** + * @file lv_led_private.h + * + */ + +#ifndef LV_LED_PRIVATE_H +#define LV_LED_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_led.h" + +#if LV_USE_LED +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of led */ +struct _lv_led_t { + lv_obj_t obj; + lv_color_t color; + uint8_t bright; /**< Current brightness of the LED (0..255)*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LED */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LED_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/line/lv_line.h b/test/include/liblvgl/widgets/line/lv_line.h new file mode 100644 index 00000000..d6a1d603 --- /dev/null +++ b/test/include/liblvgl/widgets/line/lv_line.h @@ -0,0 +1,118 @@ +/** + * @file lv_line.h + * + */ + +#ifndef LV_LINE_H +#define LV_LINE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" +#if LV_USE_LINE != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_line_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a line object + * @param parent pointer to an object, it will be the parent of the new line + * @return pointer to the created line + */ +lv_obj_t * lv_line_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set an array of points. The line object will connect these points. + * @param obj pointer to a line object + * @param points an array of points. Only the address is saved, so the array needs to be alive while the line exists + * @param point_num number of points in 'point_a' + */ +void lv_line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num); + +/** + * Set a non-const array of points. Identical to `lv_line_set_points` except the array may be retrieved by `lv_line_get_points_mutable`. + * @param obj pointer to a line object + * @param points a non-const array of points. Only the address is saved, so the array needs to be alive while the line exists. + * @param point_num number of points in 'point_a' + */ +void lv_line_set_points_mutable(lv_obj_t * obj, lv_point_precise_t points[], uint32_t point_num); + +/** + * Enable (or disable) the y coordinate inversion. + * If enabled then y will be subtracted from the height of the object, + * therefore the y = 0 coordinate will be on the bottom. + * @param obj pointer to a line object + * @param en true: enable the y inversion, false:disable the y inversion + */ +void lv_line_set_y_invert(lv_obj_t * obj, bool en); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the pointer to the array of points. + * @param obj pointer to a line object + * @return const pointer to the array of points + */ +const lv_point_precise_t * lv_line_get_points(lv_obj_t * obj); + +/** + * Get the number of points in the array of points. + * @param obj pointer to a line object + * @return number of points in array of points + */ +uint32_t lv_line_get_point_count(lv_obj_t * obj); + +/** + * Check the mutability of the stored point array pointer. + * @param obj pointer to a line object + * @return true: the point array pointer is mutable, false: constant + */ +bool lv_line_is_point_array_mutable(lv_obj_t * obj); + +/** + * Get a pointer to the mutable array of points or NULL if it is not mutable + * @param obj pointer to a line object + * @return pointer to the array of points. NULL if not mutable. + */ +lv_point_precise_t * lv_line_get_points_mutable(lv_obj_t * obj); + +/** + * Get the y inversion attribute + * @param obj pointer to a line object + * @return true: y inversion is enabled, false: disabled + */ +bool lv_line_get_y_invert(const lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_LINE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LINE_H*/ diff --git a/test/include/liblvgl/widgets/line/lv_line_private.h b/test/include/liblvgl/widgets/line/lv_line_private.h new file mode 100644 index 00000000..4899392b --- /dev/null +++ b/test/include/liblvgl/widgets/line/lv_line_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_line_private.h + * + */ + +#ifndef LV_LINE_PRIVATE_H +#define LV_LINE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_line.h" + +#if LV_USE_LINE != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of line */ +struct _lv_line_t { + lv_obj_t obj; + union { + const lv_point_precise_t * constant; + lv_point_precise_t * mut; + } point_array; /**< Pointer to an array with the points of the line*/ + uint32_t point_num; /**< Number of points in 'point_array'*/ + uint32_t y_inv : 1; /**< 1: y == 0 will be on the bottom*/ + uint32_t point_array_is_mutable : 1; /**< whether the point array is const or mutable*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LINE != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LINE_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/list/lv_list.h b/test/include/liblvgl/widgets/list/lv_list.h new file mode 100644 index 00000000..0c3894d0 --- /dev/null +++ b/test/include/liblvgl/widgets/list/lv_list.h @@ -0,0 +1,85 @@ +/** + * @file lv_list.h + * + */ + +#ifndef LV_LIST_H +#define LV_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_LIST + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_list_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_list_text_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_list_button_class; +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a list object + * @param parent pointer to an object, it will be the parent of the new list + * @return pointer to the created list + */ +lv_obj_t * lv_list_create(lv_obj_t * parent); + +/** + * Add text to a list + * @param list pointer to a list, it will be the parent of the new label + * @param txt text of the new label + * @return pointer to the created label + */ +lv_obj_t * lv_list_add_text(lv_obj_t * list, const char * txt); + +/** + * Add button to a list + * @param list pointer to a list, it will be the parent of the new button + * @param icon icon for the button, when NULL it will have no icon + * @param txt text of the new button, when NULL no text will be added + * @return pointer to the created button + */ +lv_obj_t * lv_list_add_button(lv_obj_t * list, const void * icon, const char * txt); + +/** + * Get text of a given list button + * @param list pointer to a list + * @param btn pointer to the button + * @return text of btn, if btn doesn't have text "" will be returned + */ +const char * lv_list_get_button_text(lv_obj_t * list, lv_obj_t * btn); + +/** + * Set text of a given list button + * @param list pointer to a list + * @param btn pointer to the button + * @param txt pointer to the text + */ +void lv_list_set_button_text(lv_obj_t * list, lv_obj_t * btn, const char * txt); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_LIST*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LIST_H*/ diff --git a/test/include/liblvgl/widgets/lottie/lv_lottie.h b/test/include/liblvgl/widgets/lottie/lv_lottie.h new file mode 100644 index 00000000..1ccfe164 --- /dev/null +++ b/test/include/liblvgl/widgets/lottie/lv_lottie.h @@ -0,0 +1,102 @@ +/** + * @file lv_lottie.h + * + */ + +#ifndef LV_LOTTIE_H +#define LV_LOTTIE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#if LV_USE_LOTTIE + +/*Testing of dependencies*/ +#if LV_USE_CANVAS == 0 +#error "lv_lottie: lv_canvas is required. Enable it in lv_conf.h (LV_USE_CANVAS 1)" +#endif + +#if LV_USE_THORVG == 0 +#error "lv_lottie: ThorVG is required. Enable it in lv_conf.h (LV_USE_THORVG_INTERNAL/EXTERNAL 1)" +#endif + +#include "../../draw/lv_draw_buf.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a lottie animation + * @param parent pointer to the parent widget + * @return pointer to the created Lottie animation widget + */ +lv_obj_t * lv_lottie_create(lv_obj_t * parent); + +/** + * Set a buffer for the animation. It also defines the size of the animation + * @param obj pointer to a lottie widget + * @param w width of the animation and buffer + * @param h height of the animation and buffer + * @param buf a static buffer with `width x height x 4` byte size + */ +void lv_lottie_set_buffer(lv_obj_t * obj, int32_t w, int32_t h, void * buf); + +/** + * Set a draw buffer for the animation. It also defines the size of the animation + * @param obj pointer to a lottie widget + * @param draw_buf an initialized draw buffer with ARGB8888 color format + */ +void lv_lottie_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf); + +/** + * Set the source for the animation as an array + * @param obj pointer to a lottie widget + * @param src the lottie animation converted to an nul terminated array + * @param src_size size of the source array in bytes + */ +void lv_lottie_set_src_data(lv_obj_t * obj, const void * src, size_t src_size); + +/** + * Set the source for the animation as a path. + * Lottie doesn't use LVGL's File System API. + * @param obj pointer to a lottie widget + * @param src path to a json file, e.g. "path/to/file.json" + */ +void lv_lottie_set_src_file(lv_obj_t * obj, const char * src); + +/** + * Get the LVGL animation which controls the lottie animation + * @param obj pointer to a lottie widget + * @return the LVGL animation + */ +lv_anim_t * lv_lottie_get_anim(lv_obj_t * obj); + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_LOTTIE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LOTTIE_H*/ diff --git a/test/include/liblvgl/widgets/lottie/lv_lottie_private.h b/test/include/liblvgl/widgets/lottie/lv_lottie_private.h new file mode 100644 index 00000000..6362afb8 --- /dev/null +++ b/test/include/liblvgl/widgets/lottie/lv_lottie_private.h @@ -0,0 +1,60 @@ +/** + * @file lv_lottie_private.h + * + */ + +#ifndef LV_LOTTIE_PRIVATE_H +#define LV_LOTTIE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_LOTTIE + +#include "lv_lottie.h" +#include "../canvas/lv_canvas_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +#if LV_USE_THORVG_EXTERNAL +#include +#else +#include "../../libs/thorvg/thorvg_capi.h" +#endif + +typedef struct { + lv_canvas_t canvas; + Tvg_Paint * tvg_paint; + Tvg_Canvas * tvg_canvas; + Tvg_Animation * tvg_anim; + lv_anim_t * anim; + int32_t last_rendered_time; +} lv_lottie_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_LOTTIE_H*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LOTTIE_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/menu/lv_menu.h b/test/include/liblvgl/widgets/menu/lv_menu.h new file mode 100644 index 00000000..3d75f8d9 --- /dev/null +++ b/test/include/liblvgl/widgets/menu/lv_menu.h @@ -0,0 +1,213 @@ +/** + * @file lv_menu.h + * + */ + +#ifndef LV_MENU_H +#define LV_MENU_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_MENU + +#if LV_USE_FLEX == 0 +#error "LV_USE_FLEX needs to be enabled" +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_MENU_HEADER_TOP_FIXED, /**< Header is positioned at the top */ + LV_MENU_HEADER_TOP_UNFIXED, /**< Header is positioned at the top and can be scrolled out of view*/ + LV_MENU_HEADER_BOTTOM_FIXED /**< Header is positioned at the bottom */ +} lv_menu_mode_header_t; + +typedef enum { + LV_MENU_ROOT_BACK_BUTTON_DISABLED, + LV_MENU_ROOT_BACK_BUTTON_ENABLED +} lv_menu_mode_root_back_button_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_page_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_cont_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_section_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_separator_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_sidebar_cont_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_main_cont_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_sidebar_header_cont_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_main_header_cont_class; +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a menu object + * @param parent pointer to an object, it will be the parent of the new menu + * @return pointer to the created menu + */ +lv_obj_t * lv_menu_create(lv_obj_t * parent); + +/** + * Create a menu page object + * @param parent pointer to menu object + * @param title pointer to text for title in header (NULL to not display title) + * @return pointer to the created menu page + */ +lv_obj_t * lv_menu_page_create(lv_obj_t * parent, char const * const title); + +/** + * Create a menu cont object + * @param parent pointer to an object, it will be the parent of the new menu cont object + * @return pointer to the created menu cont + */ +lv_obj_t * lv_menu_cont_create(lv_obj_t * parent); + +/** + * Create a menu section object + * @param parent pointer to an object, it will be the parent of the new menu section object + * @return pointer to the created menu section + */ +lv_obj_t * lv_menu_section_create(lv_obj_t * parent); + +/** + * Create a menu separator object + * @param parent pointer to an object, it will be the parent of the new menu separator object + * @return pointer to the created menu separator + */ +lv_obj_t * lv_menu_separator_create(lv_obj_t * parent); +/*===================== + * Setter functions + *====================*/ +/** + * Set menu page to display in main + * @param obj pointer to the menu + * @param page pointer to the menu page to set (NULL to clear main and clear menu history) + */ +void lv_menu_set_page(lv_obj_t * obj, lv_obj_t * page); + +/** + * Set menu page title + * @param page pointer to the menu page + * @param title pointer to text for title in header (NULL to not display title) + */ +void lv_menu_set_page_title(lv_obj_t * page, char const * const title); + +/** + * Set menu page title with a static text. It will not be saved by the label so the 'text' variable + * has to be 'alive' while the page exists. + * @param page pointer to the menu page + * @param title pointer to text for title in header (NULL to not display title) + */ +void lv_menu_set_page_title_static(lv_obj_t * page, char const * const title); + +/** + * Set menu page to display in sidebar + * @param obj pointer to the menu + * @param page pointer to the menu page to set (NULL to clear sidebar) + */ +void lv_menu_set_sidebar_page(lv_obj_t * obj, lv_obj_t * page); + +/** + * Set the how the header should behave and its position + * @param obj pointer to a menu + * @param mode LV_MENU_HEADER_TOP_FIXED/TOP_UNFIXED/BOTTOM_FIXED + */ +void lv_menu_set_mode_header(lv_obj_t * obj, lv_menu_mode_header_t mode); + +/** + * Set whether back button should appear at root + * @param obj pointer to a menu + * @param mode LV_MENU_ROOT_BACK_BUTTON_DISABLED/ENABLED + */ +void lv_menu_set_mode_root_back_button(lv_obj_t * obj, lv_menu_mode_root_back_button_t mode); + +/** + * Add menu to the menu item + * @param menu pointer to the menu + * @param obj pointer to the obj + * @param page pointer to the page to load when obj is clicked + */ +void lv_menu_set_load_page_event(lv_obj_t * menu, lv_obj_t * obj, lv_obj_t * page); + +/*===================== + * Getter functions + *====================*/ +/** +* Get a pointer to menu page that is currently displayed in main +* @param obj pointer to the menu +* @return pointer to current page +*/ +lv_obj_t * lv_menu_get_cur_main_page(lv_obj_t * obj); + +/** +* Get a pointer to menu page that is currently displayed in sidebar +* @param obj pointer to the menu +* @return pointer to current page +*/ +lv_obj_t * lv_menu_get_cur_sidebar_page(lv_obj_t * obj); + +/** +* Get a pointer to main header obj +* @param obj pointer to the menu +* @return pointer to main header obj +*/ +lv_obj_t * lv_menu_get_main_header(lv_obj_t * obj); + +/** +* Get a pointer to main header back btn obj +* @param obj pointer to the menu +* @return pointer to main header back btn obj +*/ +lv_obj_t * lv_menu_get_main_header_back_button(lv_obj_t * obj); + +/** +* Get a pointer to sidebar header obj +* @param obj pointer to the menu +* @return pointer to sidebar header obj +*/ +lv_obj_t * lv_menu_get_sidebar_header(lv_obj_t * obj); + +/** +* Get a pointer to sidebar header obj +* @param obj pointer to the menu +* @return pointer to sidebar header back btn obj +*/ +lv_obj_t * lv_menu_get_sidebar_header_back_button(lv_obj_t * obj); + +/** + * Check if an obj is a root back btn + * @param menu pointer to the menu + * @param obj pointer to the back button + * @return true if it is a root back btn + */ +bool lv_menu_back_button_is_root(lv_obj_t * menu, lv_obj_t * obj); + +/** + * Clear menu history + * @param obj pointer to the menu + */ +void lv_menu_clear_history(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_MENU*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MENU_H*/ diff --git a/test/include/liblvgl/widgets/menu/lv_menu_private.h b/test/include/liblvgl/widgets/menu/lv_menu_private.h new file mode 100644 index 00000000..51229371 --- /dev/null +++ b/test/include/liblvgl/widgets/menu/lv_menu_private.h @@ -0,0 +1,84 @@ +/** + * @file lv_menu_private.h + * + */ + +#ifndef LV_MENU_PRIVATE_H +#define LV_MENU_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_menu.h" + +#if LV_USE_MENU + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_menu_load_page_event_data_t { + lv_obj_t * menu; + lv_obj_t * page; +}; + +struct _lv_menu_history_t { + lv_obj_t * page; +}; + +struct _lv_menu_t { + lv_obj_t obj; + lv_obj_t * storage; /**< a pointer to obj that is the parent of all pages not displayed */ + lv_obj_t * main; + lv_obj_t * main_page; + lv_obj_t * main_header; + lv_obj_t * + main_header_back_btn; /**< a pointer to obj that on click triggers back btn event handler, can be same as 'main_header' */ + lv_obj_t * main_header_title; + lv_obj_t * sidebar; + lv_obj_t * sidebar_page; + lv_obj_t * sidebar_header; + lv_obj_t * + sidebar_header_back_btn; /**< a pointer to obj that on click triggers back btn event handler, can be same as 'sidebar_header' */ + lv_obj_t * sidebar_header_title; + lv_obj_t * selected_tab; + lv_ll_t history_ll; + uint8_t cur_depth; + uint8_t prev_depth; + uint8_t sidebar_generated : 1; + lv_menu_mode_header_t mode_header : 2; + lv_menu_mode_root_back_button_t mode_root_back_btn : 1; +}; + +struct _lv_menu_page_t { + lv_obj_t obj; + char * title; + bool static_title; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_MENU */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MENU_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/msgbox/lv_msgbox.h b/test/include/liblvgl/widgets/msgbox/lv_msgbox.h new file mode 100644 index 00000000..5605b802 --- /dev/null +++ b/test/include/liblvgl/widgets/msgbox/lv_msgbox.h @@ -0,0 +1,141 @@ +/** + * @file lv_msgbox.h + * + */ + +#ifndef LV_MSGBOX_H +#define LV_MSGBOX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_MSGBOX + +/*Testing of dependencies*/ +#if LV_USE_BUTTONMATRIX == 0 +#error "lv_mbox: lv_buttonmatrix is required. Enable it in lv_conf.h (LV_USE_BUTTONMATRIX 1) " +#endif + +#if LV_USE_LABEL == 0 +#error "lv_mbox: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) " +#endif + +/********************* + * DEFINES + *********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_header_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_content_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_footer_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_header_button_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_footer_button_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_backdrop_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an empty message box + * @param parent the parent or NULL to create a modal msgbox + * @return the created message box + */ +lv_obj_t * lv_msgbox_create(lv_obj_t * parent); + +/** + * Add title to the message box. It also creates a header for the title. + * @param obj pointer to a message box + * @param title the text of the tile + * @return the created title label + */ +lv_obj_t * lv_msgbox_add_title(lv_obj_t * obj, const char * title); + +/** + * Add a button to the header of to the message box. It also creates a header. + * @param obj pointer to a message box + * @param icon the icon of the button + * @return the created button + */ +lv_obj_t * lv_msgbox_add_header_button(lv_obj_t * obj, const void * icon); + +/** + * Add a text to the content area of message box. Multiple texts will be created below each other. + * @param obj pointer to a message box + * @param text text to add + * @return the created button + */ +lv_obj_t * lv_msgbox_add_text(lv_obj_t * obj, const char * text); + +/** + * Add a button to the footer of to the message box. It also creates a footer. + * @param obj pointer to a message box + * @param text the text of the button + * @return the created button + */ +lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * obj, const char * text); + +/** + * Add a close button to the message box. It also creates a header. + * @param obj pointer to a message box + * @return the created close button + */ +lv_obj_t * lv_msgbox_add_close_button(lv_obj_t * obj); + +/** + * Get the header widget + * @param obj pointer to a message box + * @return the header, or NULL if not exists + */ +lv_obj_t * lv_msgbox_get_header(lv_obj_t * obj); + +/** + * Get the footer widget + * @param obj pointer to a message box + * @return the footer, or NULL if not exists + */ +lv_obj_t * lv_msgbox_get_footer(lv_obj_t * obj); + +/** + * Get the content widget + * @param obj pointer to a message box + * @return the content + */ +lv_obj_t * lv_msgbox_get_content(lv_obj_t * obj); + +/** + * Get the title label + * @param obj pointer to a message box + * @return the title, or NULL if it does not exist + */ +lv_obj_t * lv_msgbox_get_title(lv_obj_t * obj); + +/** + * Close a message box + * @param mbox pointer to a message box + */ +void lv_msgbox_close(lv_obj_t * mbox); + +/** + * Close a message box in the next call of the message box + * @param mbox pointer to a message box + */ +void lv_msgbox_close_async(lv_obj_t * mbox); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_MSGBOX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MSGBOX_H*/ diff --git a/test/include/liblvgl/widgets/msgbox/lv_msgbox_private.h b/test/include/liblvgl/widgets/msgbox/lv_msgbox_private.h new file mode 100644 index 00000000..4799ea3c --- /dev/null +++ b/test/include/liblvgl/widgets/msgbox/lv_msgbox_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_msgbox_private.h + * + */ + +#ifndef LV_MSGBOX_PRIVATE_H +#define LV_MSGBOX_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_msgbox.h" + +#if LV_USE_MSGBOX +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_msgbox_t { + lv_obj_t obj; + lv_obj_t * header; + lv_obj_t * content; + lv_obj_t * footer; + lv_obj_t * title; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_MSGBOX */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MSGBOX_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/objx_templ/lv_objx_templ.h b/test/include/liblvgl/widgets/objx_templ/lv_objx_templ.h new file mode 100644 index 00000000..ccf1e1c3 --- /dev/null +++ b/test/include/liblvgl/widgets/objx_templ/lv_objx_templ.h @@ -0,0 +1,81 @@ +/** + * @file lv_templ.h + * + */ + +/** + * TODO Remove these instructions + * Search and replace: templ -> object short name with lower case(e.g. btn, label etc) + * TEMPL -> object short name with upper case (e.g. BTN, LABEL etc.) + * + */ + +#ifndef LV_TEMPL_H +#define LV_TEMPL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#if LV_USE_TEMPL != 0 + +#include "../core/lv_obj.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +/*Data of template*/ +typedef struct { + lv_ANCESTOR_t ancestor; /*The ancestor widget, e.g. lv_slider_t slider*/ + /*New data for this type*/ +} lv_templ_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_templ_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a templ object + * @param parent pointer to an object, it will be the parent of the new templ + * @return pointer to the created bar + */ +lv_obj_t * lv_templ_create(lv_obj_t * parent); + +/*====================== + * Add/remove functions + *=====================*/ + +/*===================== + * Setter functions + *====================*/ + +/*===================== + * Getter functions + *====================*/ + +/*===================== + * Other functions + *====================*/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TEMPL*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEMPL_H*/ diff --git a/test/include/liblvgl/widgets/property/lv_obj_property_names.h b/test/include/liblvgl/widgets/property/lv_obj_property_names.h new file mode 100644 index 00000000..4b4ff67a --- /dev/null +++ b/test/include/liblvgl/widgets/property/lv_obj_property_names.h @@ -0,0 +1,22 @@ + +/** + * @file lv_obj_property_names.h + * GENERATED FILE, DO NOT EDIT IT! + */ +#ifndef LV_OBJ_PROPERTY_NAMES_H +#define LV_OBJ_PROPERTY_NAMES_H + +#include "../../misc/lv_types.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + + extern const lv_property_name_t lv_dropdown_property_names[9]; + extern const lv_property_name_t lv_image_property_names[11]; + extern const lv_property_name_t lv_keyboard_property_names[4]; + extern const lv_property_name_t lv_label_property_names[4]; + extern const lv_property_name_t lv_obj_property_names[73]; + extern const lv_property_name_t lv_roller_property_names[3]; + extern const lv_property_name_t lv_style_property_names[112]; + extern const lv_property_name_t lv_textarea_property_names[15]; +#endif +#endif diff --git a/test/include/liblvgl/widgets/property/lv_style_properties.h b/test/include/liblvgl/widgets/property/lv_style_properties.h new file mode 100644 index 00000000..146f35ad --- /dev/null +++ b/test/include/liblvgl/widgets/property/lv_style_properties.h @@ -0,0 +1,130 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_style_properties.h + */ +#ifndef LV_STYLE_PROPERTIES_H +#define LV_STYLE_PROPERTIES_H + +#include "../../core/lv_obj_property.h" +#if LV_USE_OBJ_PROPERTY + + +/* *INDENT-OFF* */ +enum { + LV_PROPERTY_ID(STYLE, ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_ALIGN), + LV_PROPERTY_ID(STYLE, ANIM, LV_PROPERTY_TYPE_INT, LV_STYLE_ANIM), + LV_PROPERTY_ID(STYLE, ANIM_DURATION, LV_PROPERTY_TYPE_INT, LV_STYLE_ANIM_DURATION), + LV_PROPERTY_ID(STYLE, ARC_COLOR, LV_PROPERTY_TYPE_INT, LV_STYLE_ARC_COLOR), + LV_PROPERTY_ID(STYLE, ARC_IMAGE_SRC, LV_PROPERTY_TYPE_INT, LV_STYLE_ARC_IMAGE_SRC), + LV_PROPERTY_ID(STYLE, ARC_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_ARC_OPA), + LV_PROPERTY_ID(STYLE, ARC_ROUNDED, LV_PROPERTY_TYPE_INT, LV_STYLE_ARC_ROUNDED), + LV_PROPERTY_ID(STYLE, ARC_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_ARC_WIDTH), + LV_PROPERTY_ID(STYLE, BASE_DIR, LV_PROPERTY_TYPE_INT, LV_STYLE_BASE_DIR), + LV_PROPERTY_ID(STYLE, BG_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_BG_COLOR), + LV_PROPERTY_ID(STYLE, BG_GRAD, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_GRAD), + LV_PROPERTY_ID(STYLE, BG_GRAD_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_BG_GRAD_COLOR), + LV_PROPERTY_ID(STYLE, BG_GRAD_DIR, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_GRAD_DIR), + LV_PROPERTY_ID(STYLE, BG_GRAD_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_GRAD_OPA), + LV_PROPERTY_ID(STYLE, BG_GRAD_STOP, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_GRAD_STOP), + LV_PROPERTY_ID(STYLE, BG_IMAGE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_IMAGE_OPA), + LV_PROPERTY_ID(STYLE, BG_IMAGE_RECOLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_BG_IMAGE_RECOLOR), + LV_PROPERTY_ID(STYLE, BG_IMAGE_RECOLOR_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_IMAGE_RECOLOR_OPA), + LV_PROPERTY_ID(STYLE, BG_IMAGE_SRC, LV_PROPERTY_TYPE_IMGSRC, LV_STYLE_BG_IMAGE_SRC), + LV_PROPERTY_ID(STYLE, BG_IMAGE_TILED, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_IMAGE_TILED), + LV_PROPERTY_ID(STYLE, BG_MAIN_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_MAIN_OPA), + LV_PROPERTY_ID(STYLE, BG_MAIN_STOP, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_MAIN_STOP), + LV_PROPERTY_ID(STYLE, BG_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_OPA), + LV_PROPERTY_ID(STYLE, BITMAP_MASK_SRC, LV_PROPERTY_TYPE_INT, LV_STYLE_BITMAP_MASK_SRC), + LV_PROPERTY_ID(STYLE, BLEND_MODE, LV_PROPERTY_TYPE_INT, LV_STYLE_BLEND_MODE), + LV_PROPERTY_ID(STYLE, BORDER_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_BORDER_COLOR), + LV_PROPERTY_ID(STYLE, BORDER_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BORDER_OPA), + LV_PROPERTY_ID(STYLE, BORDER_POST, LV_PROPERTY_TYPE_INT, LV_STYLE_BORDER_POST), + LV_PROPERTY_ID(STYLE, BORDER_SIDE, LV_PROPERTY_TYPE_INT, LV_STYLE_BORDER_SIDE), + LV_PROPERTY_ID(STYLE, BORDER_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_BORDER_WIDTH), + LV_PROPERTY_ID(STYLE, CLIP_CORNER, LV_PROPERTY_TYPE_INT, LV_STYLE_CLIP_CORNER), + LV_PROPERTY_ID(STYLE, COLOR_FILTER_DSC, LV_PROPERTY_TYPE_INT, LV_STYLE_COLOR_FILTER_DSC), + LV_PROPERTY_ID(STYLE, COLOR_FILTER_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_COLOR_FILTER_OPA), + LV_PROPERTY_ID(STYLE, FLEX_CROSS_PLACE, LV_PROPERTY_TYPE_INT, LV_STYLE_FLEX_CROSS_PLACE), + LV_PROPERTY_ID(STYLE, FLEX_FLOW, LV_PROPERTY_TYPE_INT, LV_STYLE_FLEX_FLOW), + LV_PROPERTY_ID(STYLE, FLEX_GROW, LV_PROPERTY_TYPE_INT, LV_STYLE_FLEX_GROW), + LV_PROPERTY_ID(STYLE, FLEX_MAIN_PLACE, LV_PROPERTY_TYPE_INT, LV_STYLE_FLEX_MAIN_PLACE), + LV_PROPERTY_ID(STYLE, FLEX_TRACK_PLACE, LV_PROPERTY_TYPE_INT, LV_STYLE_FLEX_TRACK_PLACE), + LV_PROPERTY_ID(STYLE, GRID_CELL_COLUMN_POS, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_COLUMN_POS), + LV_PROPERTY_ID(STYLE, GRID_CELL_COLUMN_SPAN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_COLUMN_SPAN), + LV_PROPERTY_ID(STYLE, GRID_CELL_ROW_POS, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_ROW_POS), + LV_PROPERTY_ID(STYLE, GRID_CELL_ROW_SPAN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_ROW_SPAN), + LV_PROPERTY_ID(STYLE, GRID_CELL_X_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_X_ALIGN), + LV_PROPERTY_ID(STYLE, GRID_CELL_Y_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_Y_ALIGN), + LV_PROPERTY_ID(STYLE, GRID_COLUMN_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_COLUMN_ALIGN), + LV_PROPERTY_ID(STYLE, GRID_COLUMN_DSC_ARRAY, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_COLUMN_DSC_ARRAY), + LV_PROPERTY_ID(STYLE, GRID_ROW_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_ROW_ALIGN), + LV_PROPERTY_ID(STYLE, GRID_ROW_DSC_ARRAY, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_ROW_DSC_ARRAY), + LV_PROPERTY_ID(STYLE, HEIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_HEIGHT), + LV_PROPERTY_ID(STYLE, IMAGE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_IMAGE_OPA), + LV_PROPERTY_ID(STYLE, IMAGE_RECOLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_IMAGE_RECOLOR), + LV_PROPERTY_ID(STYLE, IMAGE_RECOLOR_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_IMAGE_RECOLOR_OPA), + LV_PROPERTY_ID(STYLE, LAST_BUILT_IN_PROP, LV_PROPERTY_TYPE_INT, LV_STYLE_LAST_BUILT_IN_PROP), + LV_PROPERTY_ID(STYLE, LAYOUT, LV_PROPERTY_TYPE_INT, LV_STYLE_LAYOUT), + LV_PROPERTY_ID(STYLE, LENGTH, LV_PROPERTY_TYPE_INT, LV_STYLE_LENGTH), + LV_PROPERTY_ID(STYLE, LINE_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_LINE_COLOR), + LV_PROPERTY_ID(STYLE, LINE_DASH_GAP, LV_PROPERTY_TYPE_INT, LV_STYLE_LINE_DASH_GAP), + LV_PROPERTY_ID(STYLE, LINE_DASH_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_LINE_DASH_WIDTH), + LV_PROPERTY_ID(STYLE, LINE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_LINE_OPA), + LV_PROPERTY_ID(STYLE, LINE_ROUNDED, LV_PROPERTY_TYPE_INT, LV_STYLE_LINE_ROUNDED), + LV_PROPERTY_ID(STYLE, LINE_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_LINE_WIDTH), + LV_PROPERTY_ID(STYLE, MARGIN_BOTTOM, LV_PROPERTY_TYPE_INT, LV_STYLE_MARGIN_BOTTOM), + LV_PROPERTY_ID(STYLE, MARGIN_LEFT, LV_PROPERTY_TYPE_INT, LV_STYLE_MARGIN_LEFT), + LV_PROPERTY_ID(STYLE, MARGIN_RIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_MARGIN_RIGHT), + LV_PROPERTY_ID(STYLE, MARGIN_TOP, LV_PROPERTY_TYPE_INT, LV_STYLE_MARGIN_TOP), + LV_PROPERTY_ID(STYLE, MAX_HEIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_MAX_HEIGHT), + LV_PROPERTY_ID(STYLE, MAX_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_MAX_WIDTH), + LV_PROPERTY_ID(STYLE, MIN_HEIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_MIN_HEIGHT), + LV_PROPERTY_ID(STYLE, MIN_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_MIN_WIDTH), + LV_PROPERTY_ID(STYLE, OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_OPA), + LV_PROPERTY_ID(STYLE, OPA_LAYERED, LV_PROPERTY_TYPE_INT, LV_STYLE_OPA_LAYERED), + LV_PROPERTY_ID(STYLE, OUTLINE_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_OUTLINE_COLOR), + LV_PROPERTY_ID(STYLE, OUTLINE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_OUTLINE_OPA), + LV_PROPERTY_ID(STYLE, OUTLINE_PAD, LV_PROPERTY_TYPE_INT, LV_STYLE_OUTLINE_PAD), + LV_PROPERTY_ID(STYLE, OUTLINE_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_OUTLINE_WIDTH), + LV_PROPERTY_ID(STYLE, PAD_BOTTOM, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_BOTTOM), + LV_PROPERTY_ID(STYLE, PAD_COLUMN, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_COLUMN), + LV_PROPERTY_ID(STYLE, PAD_LEFT, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_LEFT), + LV_PROPERTY_ID(STYLE, PAD_RIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_RIGHT), + LV_PROPERTY_ID(STYLE, PAD_ROW, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_ROW), + LV_PROPERTY_ID(STYLE, PAD_TOP, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_TOP), + LV_PROPERTY_ID(STYLE, PROP_INV, LV_PROPERTY_TYPE_INT, LV_STYLE_PROP_INV), + LV_PROPERTY_ID(STYLE, RADIUS, LV_PROPERTY_TYPE_INT, LV_STYLE_RADIUS), + LV_PROPERTY_ID(STYLE, ROTARY_SENSITIVITY, LV_PROPERTY_TYPE_INT, LV_STYLE_ROTARY_SENSITIVITY), + LV_PROPERTY_ID(STYLE, SHADOW_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_SHADOW_COLOR), + LV_PROPERTY_ID(STYLE, SHADOW_OFFSET_X, LV_PROPERTY_TYPE_INT, LV_STYLE_SHADOW_OFFSET_X), + LV_PROPERTY_ID(STYLE, SHADOW_OFFSET_Y, LV_PROPERTY_TYPE_INT, LV_STYLE_SHADOW_OFFSET_Y), + LV_PROPERTY_ID(STYLE, SHADOW_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_SHADOW_OPA), + LV_PROPERTY_ID(STYLE, SHADOW_SPREAD, LV_PROPERTY_TYPE_INT, LV_STYLE_SHADOW_SPREAD), + LV_PROPERTY_ID(STYLE, SHADOW_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_SHADOW_WIDTH), + LV_PROPERTY_ID(STYLE, TEXT_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_ALIGN), + LV_PROPERTY_ID(STYLE, TEXT_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_TEXT_COLOR), + LV_PROPERTY_ID(STYLE, TEXT_DECOR, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_DECOR), + LV_PROPERTY_ID(STYLE, TEXT_FONT, LV_PROPERTY_TYPE_FONT, LV_STYLE_TEXT_FONT), + LV_PROPERTY_ID(STYLE, TEXT_LETTER_SPACE, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_LETTER_SPACE), + LV_PROPERTY_ID(STYLE, TEXT_LINE_SPACE, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_LINE_SPACE), + LV_PROPERTY_ID(STYLE, TEXT_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_OPA), + LV_PROPERTY_ID(STYLE, TRANSFORM_HEIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_HEIGHT), + LV_PROPERTY_ID(STYLE, TRANSFORM_PIVOT_X, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_PIVOT_X), + LV_PROPERTY_ID(STYLE, TRANSFORM_PIVOT_Y, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_PIVOT_Y), + LV_PROPERTY_ID(STYLE, TRANSFORM_ROTATION, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_ROTATION), + LV_PROPERTY_ID(STYLE, TRANSFORM_SCALE_X, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_SCALE_X), + LV_PROPERTY_ID(STYLE, TRANSFORM_SCALE_Y, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_SCALE_Y), + LV_PROPERTY_ID(STYLE, TRANSFORM_SKEW_X, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_SKEW_X), + LV_PROPERTY_ID(STYLE, TRANSFORM_SKEW_Y, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_SKEW_Y), + LV_PROPERTY_ID(STYLE, TRANSFORM_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_WIDTH), + LV_PROPERTY_ID(STYLE, TRANSITION, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSITION), + LV_PROPERTY_ID(STYLE, TRANSLATE_X, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSLATE_X), + LV_PROPERTY_ID(STYLE, TRANSLATE_Y, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSLATE_Y), + LV_PROPERTY_ID(STYLE, WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_WIDTH), + LV_PROPERTY_ID(STYLE, X, LV_PROPERTY_TYPE_INT, LV_STYLE_X), + LV_PROPERTY_ID(STYLE, Y, LV_PROPERTY_TYPE_INT, LV_STYLE_Y), +}; + +#endif +#endif diff --git a/test/include/liblvgl/widgets/roller/lv_roller.h b/test/include/liblvgl/widgets/roller/lv_roller.h new file mode 100644 index 00000000..e6a94b29 --- /dev/null +++ b/test/include/liblvgl/widgets/roller/lv_roller.h @@ -0,0 +1,133 @@ +/** + * @file lv_roller.h + * + */ + +#ifndef LV_ROLLER_H +#define LV_ROLLER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_ROLLER != 0 + +/*Testing of dependencies*/ +#if LV_USE_LABEL == 0 +#error "lv_roller: lv_label is required. Enable it in lv_conf.h (LV_USE_ROLLER 1)" +#endif + +#include "../label/lv_label.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Roller mode. */ +typedef enum { + LV_ROLLER_MODE_NORMAL, /**< Normal mode (roller ends at the end of the options). */ + LV_ROLLER_MODE_INFINITE, /**< Infinite mode (roller can be scrolled forever). */ +} lv_roller_mode_t; + +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(ROLLER, OPTIONS, LV_PROPERTY_TYPE_TEXT, 0), + LV_PROPERTY_ID(ROLLER, SELECTED, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(ROLLER, VISIBLE_ROW_COUNT, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ROLLER_END, +}; +#endif + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_roller_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a roller object + * @param parent pointer to an object, it will be the parent of the new roller. + * @return pointer to the created roller + */ +lv_obj_t * lv_roller_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the options on a roller + * @param obj pointer to roller object + * @param options a string with '\n' separated options. E.g. "One\nTwo\nThree" + * @param mode `LV_ROLLER_MODE_NORMAL` or `LV_ROLLER_MODE_INFINITE` + */ +void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_t mode); + +/** + * Set the selected option + * @param obj pointer to a roller object + * @param sel_opt index of the selected option (0 ... number of option - 1); + * @param anim LV_ANIM_ON: set with animation; LV_ANOM_OFF set immediately + */ +void lv_roller_set_selected(lv_obj_t * obj, uint32_t sel_opt, lv_anim_enable_t anim); + +/** + * Set the height to show the given number of rows (options) + * @param obj pointer to a roller object + * @param row_cnt number of desired visible rows + */ +void lv_roller_set_visible_row_count(lv_obj_t * obj, uint32_t row_cnt); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the index of the selected option + * @param obj pointer to a roller object + * @return index of the selected option (0 ... number of option - 1); + */ +uint32_t lv_roller_get_selected(const lv_obj_t * obj); + +/** + * Get the current selected option as a string. + * @param obj pointer to roller object + * @param buf pointer to an array to store the string + * @param buf_size size of `buf` in bytes. 0: to ignore it. + */ +void lv_roller_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_size); + +/** + * Get the options of a roller + * @param obj pointer to roller object + * @return the options separated by '\n'-s (E.g. "Option1\nOption2\nOption3") + */ +const char * lv_roller_get_options(const lv_obj_t * obj); + +/** + * Get the total number of options + * @param obj pointer to a roller object + * @return the total number of options + */ +uint32_t lv_roller_get_option_count(const lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_ROLLER*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ROLLER_H*/ diff --git a/test/include/liblvgl/widgets/roller/lv_roller_private.h b/test/include/liblvgl/widgets/roller/lv_roller_private.h new file mode 100644 index 00000000..686c0d50 --- /dev/null +++ b/test/include/liblvgl/widgets/roller/lv_roller_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_roller_private.h + * + */ + +#ifndef LV_ROLLER_PRIVATE_H +#define LV_ROLLER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_roller.h" + +#if LV_USE_ROLLER != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_roller_t { + lv_obj_t obj; + uint32_t option_cnt; /**< Number of options*/ + uint32_t sel_opt_id; /**< Index of the current option*/ + uint32_t sel_opt_id_ori; /**< Store the original index on focus*/ + uint32_t inf_page_cnt; /**< Number of extra pages added to make the roller look infinite */ + lv_roller_mode_t mode : 2; + uint32_t moved : 1; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_ROLLER != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ROLLER_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/scale/lv_scale.h b/test/include/liblvgl/widgets/scale/lv_scale.h new file mode 100644 index 00000000..ad1bd2b4 --- /dev/null +++ b/test/include/liblvgl/widgets/scale/lv_scale.h @@ -0,0 +1,258 @@ +/** + * @file lv_scale.h + * + */ + +#ifndef LV_SCALE_H +#define LV_SCALE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_SCALE != 0 + +#include "../../core/lv_obj.h" +#include "../line/lv_line.h" +#include "../image/lv_image.h" + +/********************* + * DEFINES + *********************/ + +/**Default value of total minor ticks. */ +#define LV_SCALE_TOTAL_TICK_COUNT_DEFAULT (11U) +LV_EXPORT_CONST_INT(LV_SCALE_TOTAL_TICK_COUNT_DEFAULT); + +/**Default value of major tick every nth ticks. */ +#define LV_SCALE_MAJOR_TICK_EVERY_DEFAULT (5U) +LV_EXPORT_CONST_INT(LV_SCALE_MAJOR_TICK_EVERY_DEFAULT); + +/**Default value of scale label enabled. */ +#define LV_SCALE_LABEL_ENABLED_DEFAULT (1U) +LV_EXPORT_CONST_INT(LV_SCALE_LABEL_ENABLED_DEFAULT); + +/********************** + * TYPEDEFS + **********************/ + +/** + * Scale mode + */ +typedef enum { + LV_SCALE_MODE_HORIZONTAL_TOP = 0x00U, + LV_SCALE_MODE_HORIZONTAL_BOTTOM = 0x01U, + LV_SCALE_MODE_VERTICAL_LEFT = 0x02U, + LV_SCALE_MODE_VERTICAL_RIGHT = 0x04U, + LV_SCALE_MODE_ROUND_INNER = 0x08U, + LV_SCALE_MODE_ROUND_OUTER = 0x10U, + LV_SCALE_MODE_LAST +} lv_scale_mode_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_scale_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an scale object + * @param parent pointer to an object, it will be the parent of the new scale + * @return pointer to the created scale + */ +lv_obj_t * lv_scale_create(lv_obj_t * parent); + +/*====================== + * Add/remove functions + *=====================*/ + +/*===================== + * Setter functions + *====================*/ + +/** + * Set scale mode. See lv_scale_mode_t + * @param obj pointer the scale object + * @param mode the new scale mode + */ +void lv_scale_set_mode(lv_obj_t * obj, lv_scale_mode_t mode); + +/** + * Set scale total tick count (including minor and major ticks) + * @param obj pointer the scale object + * @param total_tick_count New total tick count + */ +void lv_scale_set_total_tick_count(lv_obj_t * obj, uint32_t total_tick_count); + +/** + * Sets how often the major tick will be drawn + * @param obj pointer the scale object + * @param major_tick_every the new count for major tick drawing + */ +void lv_scale_set_major_tick_every(lv_obj_t * obj, uint32_t major_tick_every); + +/** + * Sets label visibility + * @param obj pointer the scale object + * @param show_label true/false to enable tick label + */ +void lv_scale_set_label_show(lv_obj_t * obj, bool show_label); + +/** + * Set the minimal and maximal values on a scale + * @param obj pointer to a scale object + * @param min minimum value of the scale + * @param max maximum value of the scale + */ +void lv_scale_set_range(lv_obj_t * obj, int32_t min, int32_t max); + +/** + * Set properties specific to round scale + * @param obj pointer to a scale object + * @param angle_range the angular range of the scale + */ +void lv_scale_set_angle_range(lv_obj_t * obj, uint32_t angle_range); + +/** + * Set properties specific to round scale + * @param obj pointer to a scale object + * @param rotation the angular offset from the 3 o'clock position (clock-wise) + */ +void lv_scale_set_rotation(lv_obj_t * obj, int32_t rotation); + +/** + * Point the needle to the corresponding value through the line + * @param obj pointer to a scale object + * @param needle_line needle_line of the scale. The line points will be allocated and + * managed by the scale unless the line point array was previously set + * using `lv_line_set_points_mutable`. + * @param needle_length length of the needle + * needle_length>0 needle_length=needle_length; + * needle_length<0 needle_length=radius-|needle_length|; + * @param value needle to point to the corresponding value + */ +void lv_scale_set_line_needle_value(lv_obj_t * obj, lv_obj_t * needle_line, int32_t needle_length, + int32_t value); + +/** + * Point the needle to the corresponding value through the image, + image must point to the right. E.g. -O------> + * @param obj pointer to a scale object + * @param needle_img needle_img of the scale + * @param value needle to point to the corresponding value + */ +void lv_scale_set_image_needle_value(lv_obj_t * obj, lv_obj_t * needle_img, int32_t value); + +/** + * Set custom text source for major ticks labels + * @param obj pointer to a scale object + * @param txt_src pointer to an array of strings which will be display at major ticks + */ +void lv_scale_set_text_src(lv_obj_t * obj, const char * txt_src[]); + +/** + * Draw the scale after all the children are drawn + * @param obj pointer to a scale object + * @param en true: enable post draw + */ +void lv_scale_set_post_draw(lv_obj_t * obj, bool en); + +/** + * Draw the scale ticks on top of all parts + * @param obj pointer to a scale object + * @param en true: enable draw ticks on top of all parts + */ +void lv_scale_set_draw_ticks_on_top(lv_obj_t * obj, bool en); + +/** + * Add a section to the given scale + * @param obj pointer to a scale object + * @return pointer to the new section + */ +lv_scale_section_t * lv_scale_add_section(lv_obj_t * obj); + +/** + * Set the range for the given scale section + * @param section pointer to a scale section object + * @param minor_range section new minor range + * @param major_range section new major range + */ +void lv_scale_section_set_range(lv_scale_section_t * section, int32_t minor_range, int32_t major_range); + +/** + * Set the style of the part for the given scale section + * @param section pointer to a scale section object + * @param part the part for the section, e.g. LV_PART_INDICATOR + * @param section_part_style Pointer to the section part style + */ +void lv_scale_section_set_style(lv_scale_section_t * section, lv_part_t part, lv_style_t * section_part_style); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get scale mode. See lv_scale_mode_t + * @param obj pointer the scale object + * @return Scale mode + */ +lv_scale_mode_t lv_scale_get_mode(lv_obj_t * obj); + +/** + * Get scale total tick count (including minor and major ticks) + * @param obj pointer the scale object + * @return Scale total tick count + */ +int32_t lv_scale_get_total_tick_count(lv_obj_t * obj); + +/** + * Gets how often the major tick will be drawn + * @param obj pointer the scale object + * @return Scale major tick every count + */ +int32_t lv_scale_get_major_tick_every(lv_obj_t * obj); + +/** + * Gets label visibility + * @param obj pointer the scale object + * @return true if tick label is enabled, false otherwise + */ +bool lv_scale_get_label_show(lv_obj_t * obj); + +/** + * Get angle range of a round scale + * @param obj pointer to a scale object + * @return Scale angle_range + */ +uint32_t lv_scale_get_angle_range(lv_obj_t * obj); + +/** + * Get the min range for the given scale section + * @param obj pointer to a scale section object + * @return section minor range + */ +int32_t lv_scale_get_range_min_value(lv_obj_t * obj); + +/** + * Get the max range for the given scale section + * @param obj pointer to a scale section object + * @return section max range + */ +int32_t lv_scale_get_range_max_value(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SCALE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SCALE_H*/ diff --git a/test/include/liblvgl/widgets/scale/lv_scale_private.h b/test/include/liblvgl/widgets/scale/lv_scale_private.h new file mode 100644 index 00000000..c60cf196 --- /dev/null +++ b/test/include/liblvgl/widgets/scale/lv_scale_private.h @@ -0,0 +1,82 @@ +/** + * @file lv_scale_private.h + * + */ + +#ifndef LV_SCALE_PRIVATE_H +#define LV_SCALE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_scale.h" + +#if LV_USE_SCALE != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_scale_section_t { + lv_style_t * main_style; + lv_style_t * indicator_style; + lv_style_t * items_style; + int32_t minor_range; + int32_t major_range; + uint32_t first_tick_idx_in_section; + uint32_t last_tick_idx_in_section; + uint32_t first_tick_idx_is_major; + uint32_t last_tick_idx_is_major; + int32_t first_tick_in_section_width; + int32_t last_tick_in_section_width; + lv_point_t first_tick_in_section; + lv_point_t last_tick_in_section; +}; + +struct _lv_scale_t { + lv_obj_t obj; + lv_ll_t section_ll; /**< Linked list for the sections (stores lv_scale_section_t)*/ + const char ** txt_src; + lv_scale_mode_t mode; + int32_t range_min; + int32_t range_max; + uint32_t total_tick_count : 15; + uint32_t major_tick_every : 15; + uint32_t label_enabled : 1; + uint32_t post_draw : 1; + uint32_t draw_ticks_on_top : 1; + /* Round scale */ + uint32_t angle_range; + int32_t rotation; + /* Private properties */ + int32_t custom_label_cnt; + int32_t last_tick_width; + int32_t first_tick_width; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SCALE != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SCALE_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/slider/lv_slider.h b/test/include/liblvgl/widgets/slider/lv_slider.h new file mode 100644 index 00000000..5f08a5c5 --- /dev/null +++ b/test/include/liblvgl/widgets/slider/lv_slider.h @@ -0,0 +1,149 @@ +/** + * @file lv_slider.h + * + */ + +#ifndef LV_SLIDER_H +#define LV_SLIDER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../bar/lv_bar.h" + +#if LV_USE_SLIDER != 0 + +/*Testing of dependencies*/ +#if LV_USE_BAR == 0 +#error "lv_slider: lv_bar is required. Enable it in lv_conf.h (LV_USE_BAR 1)" +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_SLIDER_MODE_NORMAL = LV_BAR_MODE_NORMAL, + LV_SLIDER_MODE_SYMMETRICAL = LV_BAR_MODE_SYMMETRICAL, + LV_SLIDER_MODE_RANGE = LV_BAR_MODE_RANGE +} lv_slider_mode_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_slider_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a slider object + * @param parent pointer to an object, it will be the parent of the new slider. + * @return pointer to the created slider + */ +lv_obj_t * lv_slider_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set a new value on the slider + * @param obj pointer to a slider object + * @param value the new value + * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + */ +void lv_slider_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim); + +/** + * Set a new value for the left knob of a slider + * @param obj pointer to a slider object + * @param value new value + * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + */ +void lv_slider_set_left_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim); + +/** + * Set minimum and the maximum values of a bar + * @param obj pointer to the slider object + * @param min minimum value + * @param max maximum value + */ +void lv_slider_set_range(lv_obj_t * obj, int32_t min, int32_t max); + +/** + * Set the mode of slider. + * @param obj pointer to a slider object + * @param mode the mode of the slider. See ::lv_slider_mode_t + */ +void lv_slider_set_mode(lv_obj_t * obj, lv_slider_mode_t mode); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the value of the main knob of a slider + * @param obj pointer to a slider object + * @return the value of the main knob of the slider + */ +int32_t lv_slider_get_value(const lv_obj_t * obj); + +/** + * Get the value of the left knob of a slider + * @param obj pointer to a slider object + * @return the value of the left knob of the slider + */ +int32_t lv_slider_get_left_value(const lv_obj_t * obj); + +/** + * Get the minimum value of a slider + * @param obj pointer to a slider object + * @return the minimum value of the slider + */ +int32_t lv_slider_get_min_value(const lv_obj_t * obj); + +/** + * Get the maximum value of a slider + * @param obj pointer to a slider object + * @return the maximum value of the slider + */ +int32_t lv_slider_get_max_value(const lv_obj_t * obj); + +/** + * Give the slider is being dragged or not + * @param obj pointer to a slider object + * @return true: drag in progress false: not dragged + */ +bool lv_slider_is_dragged(const lv_obj_t * obj); + +/** + * Get the mode of the slider. + * @param slider pointer to a slider object + * @return see ::lv_slider_mode_t + */ +lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider); + +/** + * Give the slider is in symmetrical mode or not + * @param obj pointer to slider object + * @return true: in symmetrical mode false : not in +*/ +bool lv_slider_is_symmetrical(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SLIDER*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SLIDER_H*/ diff --git a/test/include/liblvgl/widgets/slider/lv_slider_private.h b/test/include/liblvgl/widgets/slider/lv_slider_private.h new file mode 100644 index 00000000..0b4464db --- /dev/null +++ b/test/include/liblvgl/widgets/slider/lv_slider_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_slider_private.h + * + */ + +#ifndef LV_SLIDER_PRIVATE_H +#define LV_SLIDER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../bar/lv_bar_private.h" +#include "lv_slider.h" + +#if LV_USE_SLIDER != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_slider_t { + lv_bar_t bar; /**< Add the ancestor's type first */ + lv_area_t left_knob_area; + lv_area_t right_knob_area; + lv_point_t pressed_point; + int32_t * value_to_set; /**< Which bar value to set */ + uint8_t dragging : 1; /**< 1: the slider is being dragged */ + uint8_t left_knob_focus : 1; /**< 1: with encoder now the right knob can be adjusted */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SLIDER != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SLIDER_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/span/lv_span.h b/test/include/liblvgl/widgets/span/lv_span.h new file mode 100644 index 00000000..17bcf51e --- /dev/null +++ b/test/include/liblvgl/widgets/span/lv_span.h @@ -0,0 +1,284 @@ +/** + * @file lv_span.h + * + */ + +#ifndef LV_SPAN_H +#define LV_SPAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../core/lv_obj.h" + +#if LV_USE_SPAN != 0 + +/********************* + * DEFINES + *********************/ +#ifndef LV_SPAN_SNIPPET_STACK_SIZE +#define LV_SPAN_SNIPPET_STACK_SIZE 64 +#endif + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_SPAN_OVERFLOW_CLIP, + LV_SPAN_OVERFLOW_ELLIPSIS, + LV_SPAN_OVERFLOW_LAST, /**< Fence member*/ +} lv_span_overflow_t; + +typedef enum { + LV_SPAN_MODE_FIXED, /**< fixed the obj size */ + LV_SPAN_MODE_EXPAND, /**< Expand the object size to the text size */ + LV_SPAN_MODE_BREAK, /**< Keep width, break the too long lines and expand height */ + LV_SPAN_MODE_LAST /**< Fence member */ +} lv_span_mode_t; + +/** Coords of a span */ +typedef struct _lv_span_coords_t { + lv_area_t heading; + lv_area_t middle; + lv_area_t trailing; +} lv_span_coords_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_spangroup_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_span_stack_init(void); +void lv_span_stack_deinit(void); + +/** + * Create a spangroup object + * @param parent pointer to an object, it will be the parent of the new spangroup + * @return pointer to the created spangroup + */ +lv_obj_t * lv_spangroup_create(lv_obj_t * parent); + +/** + * Create a span string descriptor and add to spangroup. + * @param obj pointer to a spangroup object. + * @return pointer to the created span. + */ +lv_span_t * lv_spangroup_new_span(lv_obj_t * obj); + +/** + * Remove the span from the spangroup and free memory. + * @param obj pointer to a spangroup object. + * @param span pointer to a span. + */ +void lv_spangroup_delete_span(lv_obj_t * obj, lv_span_t * span); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set a new text for a span. Memory will be allocated to store the text by the span. + * @param span pointer to a span. + * @param text pointer to a text. + */ +void lv_span_set_text(lv_span_t * span, const char * text); + +/** + * Set a static text. It will not be saved by the span so the 'text' variable + * has to be 'alive' while the span exist. + * @param span pointer to a span. + * @param text pointer to a text. + */ +void lv_span_set_text_static(lv_span_t * span, const char * text); + +/** + * Set the align of the spangroup. + * @param obj pointer to a spangroup object. + * @param align see lv_text_align_t for details. + */ +void lv_spangroup_set_align(lv_obj_t * obj, lv_text_align_t align); + +/** + * Set the overflow of the spangroup. + * @param obj pointer to a spangroup object. + * @param overflow see lv_span_overflow_t for details. + */ +void lv_spangroup_set_overflow(lv_obj_t * obj, lv_span_overflow_t overflow); + +/** + * Set the indent of the spangroup. + * @param obj pointer to a spangroup object. + * @param indent the first line indentation + */ +void lv_spangroup_set_indent(lv_obj_t * obj, int32_t indent); + +/** + * Set the mode of the spangroup. + * @param obj pointer to a spangroup object. + * @param mode see lv_span_mode_t for details. + */ +void lv_spangroup_set_mode(lv_obj_t * obj, lv_span_mode_t mode); + +/** + * Set maximum lines of the spangroup. + * @param obj pointer to a spangroup object. + * @param lines max lines that can be displayed in LV_SPAN_MODE_BREAK mode. < 0 means no limit. + */ +void lv_spangroup_set_max_lines(lv_obj_t * obj, int32_t lines); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get a pointer to the style of a span + * @param span pointer to the span + * @return pointer to the style. valid as long as the span is valid +*/ +lv_style_t * lv_span_get_style(lv_span_t * span); + +/** + * Get a pointer to the text of a span + * @param span pointer to the span + * @return pointer to the text +*/ +const char * lv_span_get_text(lv_span_t * span); + +/** + * Get a spangroup child by its index. + * + * @param obj The spangroup object + * @param id the index of the child. + * 0: the oldest (firstly created) child + * 1: the second oldest + * child count-1: the youngest + * -1: the youngest + * -2: the second youngest + * @return The child span at index `id`, or NULL if the ID does not exist + */ +lv_span_t * lv_spangroup_get_child(const lv_obj_t * obj, int32_t id); + +/** + * Get number of spans + * @param obj the spangroup object to get the child count of. + * @return the span count of the spangroup. + */ +uint32_t lv_spangroup_get_span_count(const lv_obj_t * obj); + +/** + * Get the align of the spangroup. + * @param obj pointer to a spangroup object. + * @return the align value. + */ +lv_text_align_t lv_spangroup_get_align(lv_obj_t * obj); + +/** + * Get the overflow of the spangroup. + * @param obj pointer to a spangroup object. + * @return the overflow value. + */ +lv_span_overflow_t lv_spangroup_get_overflow(lv_obj_t * obj); + +/** + * Get the indent of the spangroup. + * @param obj pointer to a spangroup object. + * @return the indent value. + */ +int32_t lv_spangroup_get_indent(lv_obj_t * obj); + +/** + * Get the mode of the spangroup. + * @param obj pointer to a spangroup object. + */ +lv_span_mode_t lv_spangroup_get_mode(lv_obj_t * obj); + +/** + * Get maximum lines of the spangroup. + * @param obj pointer to a spangroup object. + * @return the max lines value. + */ +int32_t lv_spangroup_get_max_lines(lv_obj_t * obj); + +/** + * Get max line height of all span in the spangroup. + * @param obj pointer to a spangroup object. + */ +int32_t lv_spangroup_get_max_line_height(lv_obj_t * obj); + +/** + * Get the text content width when all span of spangroup on a line. + * @param obj pointer to a spangroup object. + * @param max_width if text content width >= max_width, return max_width + * to reduce computation, if max_width == 0, returns the text content width. + * @return text content width or max_width. + */ +uint32_t lv_spangroup_get_expand_width(lv_obj_t * obj, uint32_t max_width); + +/** + * Get the text content height with width fixed. + * @param obj pointer to a spangroup object. + * @param width the width of the span group. + + */ +int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width); + +/** + * Get the span's coords in the spangroup. + * @note Before calling this function, please make sure that the layout of span group has been updated. + * Like calling lv_obj_update_layout() like function. + * + * +--------+ + * |Heading +--->------------------+ + * | Pos | | Heading | + * +--------+---+------------------+ + * | | + * | | + * | | + * | Middle +--------+| + * | |Trailing|| + * | +-| Pos || + * | | +--------+| + * +-------------------v-----------+ + * | Trailing | + * +-------------------+ + * @param obj pointer to a spangroup object. + * @param span pointer to a span. + * @return the span's coords in the spangroup. + */ +lv_span_coords_t lv_spangroup_get_span_coords(lv_obj_t * obj, const lv_span_t * span); + +/** + * Get the span object by point. + * @param obj pointer to a spangroup object. + * @param point pointer to point containing absolute coordinates + * @return pointer to the span under the point or `NULL` if not found. + */ +lv_span_t * lv_spangroup_get_span_by_point(lv_obj_t * obj, const lv_point_t * point); + +/*===================== + * Other functions + *====================*/ + +/** + * Update the mode of the spangroup. + * @param obj pointer to a spangroup object. + */ +void lv_spangroup_refr_mode(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SPAN*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_SPAN_H*/ diff --git a/test/include/liblvgl/widgets/span/lv_span_private.h b/test/include/liblvgl/widgets/span/lv_span_private.h new file mode 100644 index 00000000..6e80405e --- /dev/null +++ b/test/include/liblvgl/widgets/span/lv_span_private.h @@ -0,0 +1,68 @@ +/** + * @file lv_span_private.h + * + */ + +#ifndef LV_SPAN_PRIVATE_H +#define LV_SPAN_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_span.h" + +#if LV_USE_SPAN != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_span_t { + char * txt; /**< a pointer to display text */ + lv_obj_t * spangroup; /**< a pointer to spangroup */ + lv_style_t style; /**< display text style */ + uint32_t static_flag : 1; /**< the text is static flag */ + + lv_point_t trailing_pos; + int32_t trailing_height; +}; + +/** Data of label*/ +struct _lv_spangroup_t { + lv_obj_t obj; + int32_t lines; + int32_t indent; /**< first line indent */ + int32_t cache_w; /**< the cache automatically calculates the width */ + int32_t cache_h; /**< similar cache_w */ + lv_ll_t child_ll; + uint32_t mode : 2; /**< details see lv_span_mode_t */ + uint32_t overflow : 1; /**< details see lv_span_overflow_t */ + uint32_t refresh : 1; /**< the spangroup need refresh cache_w and cache_h */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SPAN != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SPAN_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/spinbox/lv_spinbox.h b/test/include/liblvgl/widgets/spinbox/lv_spinbox.h new file mode 100644 index 00000000..ae3fdb0c --- /dev/null +++ b/test/include/liblvgl/widgets/spinbox/lv_spinbox.h @@ -0,0 +1,164 @@ +/** + * @file lv_spinbox.h + * + */ + +#ifndef LV_SPINBOX_H +#define LV_SPINBOX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../textarea/lv_textarea.h" + +#if LV_USE_SPINBOX + +/*Testing of dependencies*/ +#if LV_USE_TEXTAREA == 0 +#error "lv_spinbox: lv_ta is required. Enable it in lv_conf.h (LV_USE_TEXTAREA 1) " +#endif + +/********************* + * DEFINES + *********************/ +#define LV_SPINBOX_MAX_DIGIT_COUNT 10 + +/********************** + * TYPEDEFS + **********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_spinbox_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a spinbox object + * @param parent pointer to an object, it will be the parent of the new spinbox + * @return pointer to the created spinbox + */ +lv_obj_t * lv_spinbox_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set spinbox value + * @param obj pointer to spinbox + * @param v value to be set + */ +void lv_spinbox_set_value(lv_obj_t * obj, int32_t v); + +/** + * Set spinbox rollover function + * @param obj pointer to spinbox + * @param rollover true or false to enable or disable (default) + */ +void lv_spinbox_set_rollover(lv_obj_t * obj, bool rollover); + +/** + * Set spinbox digit format (digit count and decimal format) + * @param obj pointer to spinbox + * @param digit_count number of digit excluding the decimal separator and the sign + * @param sep_pos number of digit before the decimal point. If 0, decimal point is not + * shown + */ +void lv_spinbox_set_digit_format(lv_obj_t * obj, uint32_t digit_count, uint32_t sep_pos); + +/** + * Set spinbox step + * @param obj pointer to spinbox + * @param step steps on increment/decrement. Can be 1, 10, 100, 1000, etc the digit that will change. + */ +void lv_spinbox_set_step(lv_obj_t * obj, uint32_t step); + +/** + * Set spinbox value range + * @param obj pointer to spinbox + * @param range_min maximum value, inclusive + * @param range_max minimum value, inclusive + */ +void lv_spinbox_set_range(lv_obj_t * obj, int32_t range_min, int32_t range_max); + +/** + * Set cursor position to a specific digit for edition + * @param obj pointer to spinbox + * @param pos selected position in spinbox + */ +void lv_spinbox_set_cursor_pos(lv_obj_t * obj, uint32_t pos); + +/** + * Set direction of digit step when clicking an encoder button while in editing mode + * @param obj pointer to spinbox + * @param direction the direction (LV_DIR_RIGHT or LV_DIR_LEFT) + */ +void lv_spinbox_set_digit_step_direction(lv_obj_t * obj, lv_dir_t direction); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get spinbox rollover function status + * @param obj pointer to spinbox + */ +bool lv_spinbox_get_rollover(lv_obj_t * obj); + +/** + * Get the spinbox numeral value (user has to convert to float according to its digit format) + * @param obj pointer to spinbox + * @return value integer value of the spinbox + */ +int32_t lv_spinbox_get_value(lv_obj_t * obj); + +/** + * Get the spinbox step value (user has to convert to float according to its digit format) + * @param obj pointer to spinbox + * @return value integer step value of the spinbox + */ +int32_t lv_spinbox_get_step(lv_obj_t * obj); + +/*===================== + * Other functions + *====================*/ + +/** + * Select next lower digit for edition by dividing the step by 10 + * @param obj pointer to spinbox + */ +void lv_spinbox_step_next(lv_obj_t * obj); + +/** + * Select next higher digit for edition by multiplying the step by 10 + * @param obj pointer to spinbox + */ +void lv_spinbox_step_prev(lv_obj_t * obj); + +/** + * Increment spinbox value by one step + * @param obj pointer to spinbox + */ +void lv_spinbox_increment(lv_obj_t * obj); + +/** + * Decrement spinbox value by one step + * @param obj pointer to spinbox + */ +void lv_spinbox_decrement(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SPINBOX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif +#endif /*LV_SPINBOX_H*/ diff --git a/test/include/liblvgl/widgets/spinbox/lv_spinbox_private.h b/test/include/liblvgl/widgets/spinbox/lv_spinbox_private.h new file mode 100644 index 00000000..333bd506 --- /dev/null +++ b/test/include/liblvgl/widgets/spinbox/lv_spinbox_private.h @@ -0,0 +1,59 @@ +/** + * @file lv_spinbox_private.h + * + */ + +#ifndef LV_SPINBOX_PRIVATE_H +#define LV_SPINBOX_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../textarea/lv_textarea_private.h" +#include "lv_spinbox.h" + +#if LV_USE_SPINBOX + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of spinbox */ +struct _lv_spinbox_t { + lv_textarea_t ta; /**< Ext. of ancestor */ + /*New data for this type*/ + int32_t value; + int32_t range_max; + int32_t range_min; + int32_t step; + uint32_t digit_count : 4; + uint32_t dec_point_pos : 4; /**< if 0, there is no separator and the number is an integer */ + uint32_t rollover : 1; /**< Set to true for rollover functionality */ + uint32_t digit_step_dir : 2; /**< the direction the digit will step on encoder button press when editing */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SPINBOX */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SPINBOX_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/spinner/lv_spinner.h b/test/include/liblvgl/widgets/spinner/lv_spinner.h new file mode 100644 index 00000000..92445631 --- /dev/null +++ b/test/include/liblvgl/widgets/spinner/lv_spinner.h @@ -0,0 +1,63 @@ +/** + * @file lv_spinner.h + * + */ + +#ifndef LV_SPINNER_H +#define LV_SPINNER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_SPINNER + +/*Testing of dependencies*/ +#if LV_USE_ARC == 0 +#error "lv_spinner: lv_arc is required. Enable it in lv_conf.h (LV_USE_ARC 1) " +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_spinner_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a spinner widget + * @param parent pointer to an object, it will be the parent of the new spinner. + * @return the created spinner + */ +lv_obj_t * lv_spinner_create(lv_obj_t * parent); + +/** + * Set the animation time and arc length of the spinner + * @param obj pointer to a spinner + * @param t the animation time in milliseconds + * @param angle the angle of the arc in degrees + */ +void lv_spinner_set_anim_params(lv_obj_t * obj, uint32_t t, uint32_t angle); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SPINNER*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SPINNER_H*/ diff --git a/test/include/liblvgl/widgets/switch/lv_switch.h b/test/include/liblvgl/widgets/switch/lv_switch.h new file mode 100644 index 00000000..3cc0d284 --- /dev/null +++ b/test/include/liblvgl/widgets/switch/lv_switch.h @@ -0,0 +1,84 @@ +/** + * @file lv_switch.h + * + */ + +#ifndef LV_SWITCH_H +#define LV_SWITCH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_SWITCH != 0 + +#include "../../core/lv_obj.h" + +/********************* + * DEFINES + *********************/ + +/** Switch knob extra area correction factor */ +#define LV_SWITCH_KNOB_EXT_AREA_CORRECTION 2 + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_switch_class; + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_SWITCH_ORIENTATION_AUTO, + LV_SWITCH_ORIENTATION_HORIZONTAL, + LV_SWITCH_ORIENTATION_VERTICAL +} lv_switch_orientation_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a switch object + * @param parent pointer to an object, it will be the parent of the new switch + * @return pointer to the created switch + */ +lv_obj_t * lv_switch_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the orientation of switch. + * @param obj pointer to switch object + * @param orientation switch orientation from `lv_switch_orientation_t` + */ +void lv_switch_set_orientation(lv_obj_t * obj, lv_switch_orientation_t orientation); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the orientation of switch. + * @param obj pointer to switch object + * @return switch orientation from ::lv_switch_orientation_t + */ +lv_switch_orientation_t lv_switch_get_orientation(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SWITCH*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SWITCH_H*/ diff --git a/test/include/liblvgl/widgets/switch/lv_switch_private.h b/test/include/liblvgl/widgets/switch/lv_switch_private.h new file mode 100644 index 00000000..66e90d32 --- /dev/null +++ b/test/include/liblvgl/widgets/switch/lv_switch_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_switch_private.h + * + */ + +#ifndef LV_SWITCH_PRIVATE_H +#define LV_SWITCH_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_switch.h" + +#if LV_USE_SWITCH != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_switch_t { + lv_obj_t obj; + int32_t anim_state; + lv_switch_orientation_t orientation : 3; /**< Orientation of switch*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SWITCH != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SWITCH_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/table/lv_table.h b/test/include/liblvgl/widgets/table/lv_table.h new file mode 100644 index 00000000..0d615a1b --- /dev/null +++ b/test/include/liblvgl/widgets/table/lv_table.h @@ -0,0 +1,214 @@ +/** + * @file lv_table.h + * + */ + +#ifndef LV_TABLE_H +#define LV_TABLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../label/lv_label.h" + +#if LV_USE_TABLE != 0 + +/*Testing of dependencies*/ +#if LV_USE_LABEL == 0 +#error "lv_table: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1)" +#endif + +/********************* + * DEFINES + *********************/ +#define LV_TABLE_CELL_NONE 0XFFFF +LV_EXPORT_CONST_INT(LV_TABLE_CELL_NONE); + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_TABLE_CELL_CTRL_MERGE_RIGHT = 1 << 0, + LV_TABLE_CELL_CTRL_TEXT_CROP = 1 << 1, + LV_TABLE_CELL_CTRL_CUSTOM_1 = 1 << 4, + LV_TABLE_CELL_CTRL_CUSTOM_2 = 1 << 5, + LV_TABLE_CELL_CTRL_CUSTOM_3 = 1 << 6, + LV_TABLE_CELL_CTRL_CUSTOM_4 = 1 << 7, +} lv_table_cell_ctrl_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_table_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a table object + * @param parent pointer to an object, it will be the parent of the new table + * @return pointer to the created table + */ +lv_obj_t * lv_table_create(lv_obj_t * parent); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the value of a cell. + * @param obj pointer to a Table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @param txt text to display in the cell. It will be copied and saved so this variable is not required after this function call. + * @note New roes/columns are added automatically if required + */ +void lv_table_set_cell_value(lv_obj_t * obj, uint32_t row, uint32_t col, const char * txt); + +/** + * Set the value of a cell. Memory will be allocated to store the text by the table. + * @param obj pointer to a Table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @param fmt `printf`-like format + * @note New roes/columns are added automatically if required + */ +void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint32_t row, uint32_t col, const char * fmt, + ...) LV_FORMAT_ATTRIBUTE(4, 5); + +/** + * Set the number of rows + * @param obj table pointer to a Table object + * @param row_cnt number of rows + */ +void lv_table_set_row_count(lv_obj_t * obj, uint32_t row_cnt); + +/** + * Set the number of columns + * @param obj table pointer to a Table object + * @param col_cnt number of columns. + */ +void lv_table_set_column_count(lv_obj_t * obj, uint32_t col_cnt); + +/** + * Set the width of a column + * @param obj table pointer to a Table object + * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1] + * @param w width of the column + */ +void lv_table_set_column_width(lv_obj_t * obj, uint32_t col_id, int32_t w); + +/** + * Add control bits to the cell. + * @param obj pointer to a Table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @param ctrl OR-ed values from ::lv_table_cell_ctrl_t + */ +void lv_table_add_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl); + +/** + * Clear control bits of the cell. + * @param obj pointer to a Table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @param ctrl OR-ed values from ::lv_table_cell_ctrl_t + */ +void lv_table_clear_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl); + +/** + * Add custom user data to the cell. + * @param obj pointer to a Table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @param user_data pointer to the new user_data. + * Should be allocated by `lv_malloc`, + * and it will be freed automatically when the table is deleted or + * when the cell is dropped due to lower row or column count. + */ +void lv_table_set_cell_user_data(lv_obj_t * obj, uint16_t row, uint16_t col, void * user_data); + +/** + * Set the selected cell + * @param obj pointer to a table object + * @param row id of the cell row to select + * @param col id of the cell column to select + */ +void lv_table_set_selected_cell(lv_obj_t * obj, uint16_t row, uint16_t col); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the value of a cell. + * @param obj pointer to a Table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @return text in the cell + */ +const char * lv_table_get_cell_value(lv_obj_t * obj, uint32_t row, uint32_t col); + +/** + * Get the number of rows. + * @param obj table pointer to a Table object + * @return number of rows. + */ +uint32_t lv_table_get_row_count(lv_obj_t * obj); + +/** + * Get the number of columns. + * @param obj table pointer to a Table object + * @return number of columns. + */ +uint32_t lv_table_get_column_count(lv_obj_t * obj); + +/** + * Get the width of a column + * @param obj table pointer to a Table object + * @param col id of the column [0 .. LV_TABLE_COL_MAX -1] + * @return width of the column + */ +int32_t lv_table_get_column_width(lv_obj_t * obj, uint32_t col); + +/** + * Get whether a cell has the control bits + * @param obj pointer to a Table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @param ctrl OR-ed values from ::lv_table_cell_ctrl_t + * @return true: all control bits are set; false: not all control bits are set + */ +bool lv_table_has_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl); + +/** + * Get the selected cell (pressed and or focused) + * @param obj pointer to a table object + * @param row pointer to variable to store the selected row (LV_TABLE_CELL_NONE: if no cell selected) + * @param col pointer to variable to store the selected column (LV_TABLE_CELL_NONE: if no cell selected) + */ +void lv_table_get_selected_cell(lv_obj_t * obj, uint32_t * row, uint32_t * col); + +/** + * Get custom user data to the cell. + * @param obj pointer to a Table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + */ +void * lv_table_get_cell_user_data(lv_obj_t * obj, uint16_t row, uint16_t col); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TABLE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TABLE_H*/ diff --git a/test/include/liblvgl/widgets/table/lv_table_private.h b/test/include/liblvgl/widgets/table/lv_table_private.h new file mode 100644 index 00000000..816de1e7 --- /dev/null +++ b/test/include/liblvgl/widgets/table/lv_table_private.h @@ -0,0 +1,64 @@ +/** + * @file lv_table_private.h + * + */ + +#ifndef LV_TABLE_PRIVATE_H +#define LV_TABLE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_table.h" + +#if LV_USE_TABLE != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Cell data */ +struct _lv_table_cell_t { + lv_table_cell_ctrl_t ctrl; + void * user_data; /**< Custom user data */ + char txt[1]; /**< Variable length array */ +}; + +/** Table data */ +struct _lv_table_t { + lv_obj_t obj; + uint32_t col_cnt; + uint32_t row_cnt; + lv_table_cell_t ** cell_data; + int32_t * row_h; + int32_t * col_w; + uint32_t col_act; + uint32_t row_act; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_TABLE != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TABLE_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/tabview/lv_tabview.h b/test/include/liblvgl/widgets/tabview/lv_tabview.h new file mode 100644 index 00000000..f9bfdcc1 --- /dev/null +++ b/test/include/liblvgl/widgets/tabview/lv_tabview.h @@ -0,0 +1,115 @@ +/** + * @file lv_tabview.h + * + */ + +#ifndef LV_TABVIEW_H +#define LV_TABVIEW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../core/lv_obj.h" + +#if LV_USE_TABVIEW + +/********************* + * DEFINES + *********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_tabview_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a tabview widget + * @param parent pointer to a parent widget + * @return the created tabview + */ +lv_obj_t * lv_tabview_create(lv_obj_t * parent); + +/** + * Add a tab to the tabview + * @param obj pointer to a tabview widget + * @param name the name of the tab, it will be displayed on the tab bar + * @return the widget where the content of the tab can be created + */ +lv_obj_t * lv_tabview_add_tab(lv_obj_t * obj, const char * name); + +/** + * Change the name of the tab + * @param obj pointer to a tabview widget + * @param idx the index of the tab to rename + * @param new_name the new name as a string + */ +void lv_tabview_rename_tab(lv_obj_t * obj, uint32_t idx, const char * new_name); + +/** + * Show a tab + * @param obj pointer to a tabview widget + * @param idx the index of the tab to show + * @param anim_en LV_ANIM_ON/OFF + */ +void lv_tabview_set_active(lv_obj_t * obj, uint32_t idx, lv_anim_enable_t anim_en); + +/** + * Set the position of the tab bar + * @param obj pointer to a tabview widget + * @param dir LV_DIR_TOP/BOTTOM/LEFT/RIGHT + */ +void lv_tabview_set_tab_bar_position(lv_obj_t * obj, lv_dir_t dir); + +/** + * Set the width or height of the tab bar + * @param obj pointer to tabview widget + * @param size size of the tab bar in pixels or percentage. + * will be used as width or height based on the position of the tab bar) + */ +void lv_tabview_set_tab_bar_size(lv_obj_t * obj, int32_t size); + +/** + * Get the number of tabs + * @param obj pointer to a tabview widget + * @return the number of tabs + */ +uint32_t lv_tabview_get_tab_count(lv_obj_t * obj); + +/** + * Get the current tab's index + * @param obj pointer to a tabview widget + * @return the zero based index of the current tab + */ +uint32_t lv_tabview_get_tab_active(lv_obj_t * obj); + +/** + * Get the widget where the container of each tab is created + * @param obj pointer to a tabview widget + * @return the main container widget + */ +lv_obj_t * lv_tabview_get_content(lv_obj_t * obj); + +/** + * Get the tab bar where the buttons are created + * @param obj pointer to a tabview widget + * @return the tab bar + */ +lv_obj_t * lv_tabview_get_tab_bar(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TABVIEW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TABVIEW_H*/ diff --git a/test/include/liblvgl/widgets/tabview/lv_tabview_private.h b/test/include/liblvgl/widgets/tabview/lv_tabview_private.h new file mode 100644 index 00000000..0e00351c --- /dev/null +++ b/test/include/liblvgl/widgets/tabview/lv_tabview_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_tabview_private.h + * + */ + +#ifndef LV_TABVIEW_PRIVATE_H +#define LV_TABVIEW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_tabview.h" + +#if LV_USE_TABVIEW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_tabview_t { + lv_obj_t obj; + uint32_t tab_cur; + lv_dir_t tab_pos; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_TABVIEW */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TABVIEW_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/textarea/lv_textarea.h b/test/include/liblvgl/widgets/textarea/lv_textarea.h new file mode 100644 index 00000000..0804029d --- /dev/null +++ b/test/include/liblvgl/widgets/textarea/lv_textarea.h @@ -0,0 +1,353 @@ +/** + * @file lv_textarea.h + * + */ + +#ifndef LV_TEXTAREA_H +#define LV_TEXTAREA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../label/lv_label.h" + +#if LV_USE_TEXTAREA != 0 + +/*Testing of dependencies*/ +#if LV_USE_LABEL == 0 +#error "lv_textarea: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1)" +#endif + +/********************* + * DEFINES + *********************/ +#define LV_TEXTAREA_CURSOR_LAST (0x7FFF) /*Put the cursor after the last character*/ + +LV_EXPORT_CONST_INT(LV_TEXTAREA_CURSOR_LAST); + +/********************** + * TYPEDEFS + **********************/ + +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(TEXTAREA, TEXT, LV_PROPERTY_TYPE_TEXT, 0), + LV_PROPERTY_ID(TEXTAREA, PLACEHOLDER_TEXT, LV_PROPERTY_TYPE_TEXT, 1), + LV_PROPERTY_ID(TEXTAREA, CURSOR_POS, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(TEXTAREA, CURSOR_CLICK_POS, LV_PROPERTY_TYPE_INT, 3), + LV_PROPERTY_ID(TEXTAREA, PASSWORD_MODE, LV_PROPERTY_TYPE_INT, 4), + LV_PROPERTY_ID(TEXTAREA, PASSWORD_BULLET, LV_PROPERTY_TYPE_TEXT, 5), + LV_PROPERTY_ID(TEXTAREA, ONE_LINE, LV_PROPERTY_TYPE_BOOL, 6), + LV_PROPERTY_ID(TEXTAREA, ACCEPTED_CHARS, LV_PROPERTY_TYPE_TEXT, 7), + LV_PROPERTY_ID(TEXTAREA, MAX_LENGTH, LV_PROPERTY_TYPE_INT, 8), + LV_PROPERTY_ID(TEXTAREA, INSERT_REPLACE, LV_PROPERTY_TYPE_TEXT, 9), + LV_PROPERTY_ID(TEXTAREA, TEXT_SELECTION, LV_PROPERTY_TYPE_BOOL, 10), + LV_PROPERTY_ID(TEXTAREA, PASSWORD_SHOW_TIME, LV_PROPERTY_TYPE_INT, 11), + LV_PROPERTY_ID(TEXTAREA, LABEL, LV_PROPERTY_TYPE_OBJ, 12), + LV_PROPERTY_ID(TEXTAREA, TEXT_IS_SELECTED, LV_PROPERTY_TYPE_INT, 13), + LV_PROPERTY_ID(TEXTAREA, CURRENT_CHAR, LV_PROPERTY_TYPE_INT, 14), + LV_PROPERTY_TEXTAREA_END, +}; +#endif + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_textarea_class; + +enum { + LV_PART_TEXTAREA_PLACEHOLDER = LV_PART_CUSTOM_FIRST, +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a text area object + * @param parent pointer to an object, it will be the parent of the new text area + * @return pointer to the created text area + */ +lv_obj_t * lv_textarea_create(lv_obj_t * parent); + +/*====================== + * Add/remove functions + *=====================*/ + +/** + * Insert a character to the current cursor position. + * To add a wide char, e.g. 'Á' use `lv_text_encoded_conv_wc('Á')` + * @param obj pointer to a text area object + * @param c a character (e.g. 'a') + */ +void lv_textarea_add_char(lv_obj_t * obj, uint32_t c); + +/** + * Insert a text to the current cursor position + * @param obj pointer to a text area object + * @param txt a '\0' terminated string to insert + */ +void lv_textarea_add_text(lv_obj_t * obj, const char * txt); + +/** + * Delete a the left character from the current cursor position + * @param obj pointer to a text area object + */ +void lv_textarea_delete_char(lv_obj_t * obj); + +/** + * Delete the right character from the current cursor position + * @param obj pointer to a text area object + */ +void lv_textarea_delete_char_forward(lv_obj_t * obj); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the text of a text area + * @param obj pointer to a text area object + * @param txt pointer to the text + */ +void lv_textarea_set_text(lv_obj_t * obj, const char * txt); + +/** + * Set the placeholder text of a text area + * @param obj pointer to a text area object + * @param txt pointer to the text + */ +void lv_textarea_set_placeholder_text(lv_obj_t * obj, const char * txt); + +/** + * Set the cursor position + * @param obj pointer to a text area object + * @param pos the new cursor position in character index + * < 0 : index from the end of the text + * LV_TEXTAREA_CURSOR_LAST: go after the last character + */ +void lv_textarea_set_cursor_pos(lv_obj_t * obj, int32_t pos); + +/** + * Enable/Disable the positioning of the cursor by clicking the text on the text area. + * @param obj pointer to a text area object + * @param en true: enable click positions; false: disable + */ +void lv_textarea_set_cursor_click_pos(lv_obj_t * obj, bool en); + +/** + * Enable/Disable password mode + * @param obj pointer to a text area object + * @param en true: enable, false: disable + */ +void lv_textarea_set_password_mode(lv_obj_t * obj, bool en); + +/** + * Set the replacement characters to show in password mode + * @param obj pointer to a text area object + * @param bullet pointer to the replacement text + */ +void lv_textarea_set_password_bullet(lv_obj_t * obj, const char * bullet); + +/** + * Configure the text area to one line or back to normal + * @param obj pointer to a text area object + * @param en true: one line, false: normal + */ +void lv_textarea_set_one_line(lv_obj_t * obj, bool en); + +/** + * Set a list of characters. Only these characters will be accepted by the text area + * @param obj pointer to a text area object + * @param list list of characters. Only the pointer is saved. E.g. "+-.,0123456789" + */ +void lv_textarea_set_accepted_chars(lv_obj_t * obj, const char * list); + +/** + * Set max length of a Text Area. + * @param obj pointer to a text area object + * @param num the maximal number of characters can be added (`lv_textarea_set_text` ignores it) + */ +void lv_textarea_set_max_length(lv_obj_t * obj, uint32_t num); + +/** + * In `LV_EVENT_INSERT` the text which planned to be inserted can be replaced by another text. + * It can be used to add automatic formatting to the text area. + * @param obj pointer to a text area object + * @param txt pointer to a new string to insert. If `""` no text will be added. + * The variable must be live after the `event_cb` exists. (Should be `global` or `static`) + */ +void lv_textarea_set_insert_replace(lv_obj_t * obj, const char * txt); + +/** + * Enable/disable selection mode. + * @param obj pointer to a text area object + * @param en true or false to enable/disable selection mode + */ +void lv_textarea_set_text_selection(lv_obj_t * obj, bool en); + +/** + * Set how long show the password before changing it to '*' + * @param obj pointer to a text area object + * @param time show time in milliseconds. 0: hide immediately. + */ +void lv_textarea_set_password_show_time(lv_obj_t * obj, uint32_t time); + +/** + * @deprecated Use the normal text_align style property instead + * Set the label's alignment. + * It sets where the label is aligned (in one line mode it can be smaller than the text area) + * and how the lines of the area align in case of multiline text area + * @param obj pointer to a text area object + * @param align the align mode from ::lv_text_align_t + */ +void lv_textarea_set_align(lv_obj_t * obj, lv_text_align_t align); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the text of a text area. In password mode it gives the real text (not '*'s). + * @param obj pointer to a text area object + * @return pointer to the text + */ +const char * lv_textarea_get_text(const lv_obj_t * obj); + +/** + * Get the placeholder text of a text area + * @param obj pointer to a text area object + * @return pointer to the text + */ +const char * lv_textarea_get_placeholder_text(lv_obj_t * obj); + +/** + * Get the label of a text area + * @param obj pointer to a text area object + * @return pointer to the label object + */ +lv_obj_t * lv_textarea_get_label(const lv_obj_t * obj); + +/** + * Get the current cursor position in character index + * @param obj pointer to a text area object + * @return the cursor position + */ +uint32_t lv_textarea_get_cursor_pos(const lv_obj_t * obj); + +/** + * Get whether the cursor click positioning is enabled or not. + * @param obj pointer to a text area object + * @return true: enable click positions; false: disable + */ +bool lv_textarea_get_cursor_click_pos(lv_obj_t * obj); + +/** + * Get the password mode attribute + * @param obj pointer to a text area object + * @return true: password mode is enabled, false: disabled + */ +bool lv_textarea_get_password_mode(const lv_obj_t * obj); + +/** + * Get the replacement characters to show in password mode + * @param obj pointer to a text area object + * @return pointer to the replacement text + */ +const char * lv_textarea_get_password_bullet(lv_obj_t * obj); + +/** + * Get the one line configuration attribute + * @param obj pointer to a text area object + * @return true: one line configuration is enabled, false: disabled + */ +bool lv_textarea_get_one_line(const lv_obj_t * obj); + +/** + * Get a list of accepted characters. + * @param obj pointer to a text area object + * @return list of accented characters. + */ +const char * lv_textarea_get_accepted_chars(lv_obj_t * obj); + +/** + * Get max length of a Text Area. + * @param obj pointer to a text area object + * @return the maximal number of characters to be add + */ +uint32_t lv_textarea_get_max_length(lv_obj_t * obj); + +/** + * Find whether text is selected or not. + * @param obj pointer to a text area object + * @return whether text is selected or not + */ +bool lv_textarea_text_is_selected(const lv_obj_t * obj); + +/** + * Find whether selection mode is enabled. + * @param obj pointer to a text area object + * @return true: selection mode is enabled, false: disabled + */ +bool lv_textarea_get_text_selection(lv_obj_t * obj); + +/** + * Set how long show the password before changing it to '*' + * @param obj pointer to a text area object + * @return show time in milliseconds. 0: hide immediately. + */ +uint32_t lv_textarea_get_password_show_time(lv_obj_t * obj); + +/** + * Get a the character from the current cursor position + * @param obj pointer to a text area object + * @return a the character or 0 + */ +uint32_t lv_textarea_get_current_char(lv_obj_t * obj); + +/*===================== + * Other functions + *====================*/ + +/** + * Clear the selection on the text area. + * @param obj pointer to a text area object + */ +void lv_textarea_clear_selection(lv_obj_t * obj); + +/** + * Move the cursor one character right + * @param obj pointer to a text area object + */ +void lv_textarea_cursor_right(lv_obj_t * obj); + +/** + * Move the cursor one character left + * @param obj pointer to a text area object + */ +void lv_textarea_cursor_left(lv_obj_t * obj); + +/** + * Move the cursor one line down + * @param obj pointer to a text area object + */ +void lv_textarea_cursor_down(lv_obj_t * obj); + +/** + * Move the cursor one line up + * @param obj pointer to a text area object + */ +void lv_textarea_cursor_up(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TEXTAREA_H*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEXTAREA_H*/ diff --git a/test/include/liblvgl/widgets/textarea/lv_textarea_private.h b/test/include/liblvgl/widgets/textarea/lv_textarea_private.h new file mode 100644 index 00000000..68102e8c --- /dev/null +++ b/test/include/liblvgl/widgets/textarea/lv_textarea_private.h @@ -0,0 +1,75 @@ +/** + * @file lv_textarea_private.h + * + */ + +#ifndef LV_TEXTAREA_PRIVATE_H +#define LV_TEXTAREA_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_textarea.h" + +#if LV_USE_TEXTAREA != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of text area */ +struct _lv_textarea_t { + lv_obj_t obj; + lv_obj_t * label; /**< Label of the text area */ + char * placeholder_txt; /**< Place holder label. only visible if text is an empty string */ + char * pwd_tmp; /**< Used to store the original text in password mode */ + char * pwd_bullet; /**< Replacement characters displayed in password mode */ + const char * accepted_chars; /**< Only these characters will be accepted. NULL: accept all */ + uint32_t max_length; /**< The max. number of characters. 0: no limit */ + uint32_t pwd_show_time; /**< Time to show characters in password mode before change them to '*' */ + struct { + int32_t valid_x; /**< Used when stepping up/down to a shorter line. + *(Used by the library) */ + uint32_t pos; /**< The current cursor position + *(0: before 1st letter; 1: before 2nd letter ...) */ + lv_area_t area; /**< Cursor area relative to the Text Area */ + uint32_t txt_byte_pos; /**< Byte index of the letter after (on) the cursor */ + uint8_t show : 1; /**< Cursor is visible now or not (Handled by the library) */ + uint8_t click_pos : 1; /**< 1: Enable positioning the cursor by clicking the text area */ + } cursor; +#if LV_LABEL_TEXT_SELECTION + uint32_t sel_start; /**< Temporary values for text selection */ + uint32_t sel_end; + uint8_t text_sel_in_prog : 1; /**< User is in process of selecting */ + uint8_t text_sel_en : 1; /**< Text can be selected on this text area */ +#endif + uint8_t pwd_mode : 1; /**< Replace characters with '*' */ + uint8_t one_line : 1; /**< One line mode (ignore line breaks) */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_TEXTAREA != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEXTAREA_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/tileview/lv_tileview.h b/test/include/liblvgl/widgets/tileview/lv_tileview.h new file mode 100644 index 00000000..4058bb65 --- /dev/null +++ b/test/include/liblvgl/widgets/tileview/lv_tileview.h @@ -0,0 +1,86 @@ +/** + * @file lv_tileview.h + * + */ + +#ifndef LV_TILEVIEW_H +#define LV_TILEVIEW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_TILEVIEW + +/********************* + * DEFINES + *********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_tileview_class; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_tileview_tile_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a tileview object + * @param parent pointer to an object, it will be the parent of the new tileview + * @return pointer to the created tileview + */ +lv_obj_t * lv_tileview_create(lv_obj_t * parent); + +/** + * Add a tile to the tileview + * @param tv pointer to the tileview object + * @param col_id column id of the tile + * @param row_id row id of the tile + * @param dir direction to move to the next tile + * @return pointer to the added tile object + */ +lv_obj_t * lv_tileview_add_tile(lv_obj_t * tv, uint8_t col_id, uint8_t row_id, lv_dir_t dir); + +/** + * Set the active tile in the tileview. + * @param parent pointer to the tileview object + * @param tile_obj pointer to the tile object to be set as active + * @param anim_en animation enable flag (LV_ANIM_ON or LV_ANIM_OFF) + */ +void lv_tileview_set_tile(lv_obj_t * tv, lv_obj_t * tile_obj, lv_anim_enable_t anim_en); + +/** + * Set the active tile by index in the tileview + * @param tv pointer to the tileview object + * @param col_id column id of the tile to be set as active + * @param row_id row id of the tile to be set as active + * @param anim_en animation enable flag (LV_ANIM_ON or LV_ANIM_OFF) + */ +void lv_tileview_set_tile_by_index(lv_obj_t * tv, uint32_t col_id, uint32_t row_id, lv_anim_enable_t anim_en); + +/** + * Get the currently active tile in the tileview + * @param obj pointer to the tileview object + * @return pointer to the currently active tile object + */ +lv_obj_t * lv_tileview_get_tile_active(lv_obj_t * obj); + +/*===================== + * Other functions + *====================*/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TILEVIEW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TILEVIEW_H*/ diff --git a/test/include/liblvgl/widgets/tileview/lv_tileview_private.h b/test/include/liblvgl/widgets/tileview/lv_tileview_private.h new file mode 100644 index 00000000..e343db0c --- /dev/null +++ b/test/include/liblvgl/widgets/tileview/lv_tileview_private.h @@ -0,0 +1,58 @@ +/** + * @file lv_tileview_private.h + * + */ + +#ifndef LV_TILEVIEW_PRIVATE_H +#define LV_TILEVIEW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_tileview.h" + +#if LV_USE_TILEVIEW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ +struct _lv_tileview_t { + lv_obj_t obj; + lv_obj_t * tile_act; +}; + +struct _lv_tileview_tile_t { + lv_obj_t obj; + lv_dir_t dir; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_TILEVIEW */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TILEVIEW_PRIVATE_H*/ diff --git a/test/include/liblvgl/widgets/win/lv_win.h b/test/include/liblvgl/widgets/win/lv_win.h new file mode 100644 index 00000000..366a8b1b --- /dev/null +++ b/test/include/liblvgl/widgets/win/lv_win.h @@ -0,0 +1,74 @@ +/** + * @file lv_win.h + * + */ + +#ifndef LV_WIN_H +#define LV_WIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#include "../../core/lv_obj.h" +#if LV_USE_WIN +/********************* + * DEFINES + *********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_win_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a window widget + * @param parent pointer to a parent widget + * @return the created window + */ +lv_obj_t * lv_win_create(lv_obj_t * parent); + +/** + * Add a title to the window + * @param obj pointer to a window widget + * @param txt the text of the title + * @return the widget where the content of the title can be created + */ +lv_obj_t * lv_win_add_title(lv_obj_t * win, const char * txt); + +/** + * Add a button to the window + * @param obj pointer to a window widget + * @param icon an icon to be displayed on the button + * @param btn_w width of the button + * @return the widget where the content of the button can be created + */ +lv_obj_t * lv_win_add_button(lv_obj_t * win, const void * icon, int32_t btn_w); + +/** + * Get the header of the window + * @param win pointer to a window widget + * @return the header of the window + */ +lv_obj_t * lv_win_get_header(lv_obj_t * win); + +/** + * Get the content of the window + * @param win pointer to a window widget + * @return the content of the window + */ +lv_obj_t * lv_win_get_content(lv_obj_t * win); +/********************** + * MACROS + **********************/ +#endif /*LV_USE_WIN*/ +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WIN_H*/ diff --git a/test/include/liblvgl/widgets/win/lv_win_private.h b/test/include/liblvgl/widgets/win/lv_win_private.h new file mode 100644 index 00000000..25e40c59 --- /dev/null +++ b/test/include/liblvgl/widgets/win/lv_win_private.h @@ -0,0 +1,52 @@ +/** + * @file lv_win_private.h + * + */ + +#ifndef LV_WIN_PRIVATE_H +#define LV_WIN_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_win.h" + +#if LV_USE_WIN + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ +struct _lv_win_t { + lv_obj_t obj; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_WIN */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WIN_PRIVATE_H*/ diff --git a/test/include/main.h b/test/include/main.h new file mode 100644 index 00000000..2e0f3a8e --- /dev/null +++ b/test/include/main.h @@ -0,0 +1,80 @@ +/** + * \file main.h + * + * Contains common definitions and header files used throughout your PROS + * project. + * + * \copyright Copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef _PROS_MAIN_H_ +#define _PROS_MAIN_H_ + +/** + * If defined, some commonly used enums will have preprocessor macros which give + * a shorter, more convenient naming pattern. If this isn't desired, simply + * comment the following line out. + * + * For instance, E_CONTROLLER_MASTER has a shorter name: CONTROLLER_MASTER. + * E_CONTROLLER_MASTER is pedantically correct within the PROS styleguide, but + * not convenient for most student programmers. + */ +#define PROS_USE_SIMPLE_NAMES + +/** + * If defined, C++ literals will be available for use. All literals are in the + * pros::literals namespace. + * + * For instance, you can do `4_mtr = 50` to set motor 4's target velocity to 50 + */ +#define PROS_USE_LITERALS + +#include "api.h" + +/** + * You should add more #includes here + */ +//#include "okapi/api.hpp" + +/** + * If you find doing pros::Motor() to be tedious and you'd prefer just to do + * Motor, you can use the namespace with the following commented out line. + * + * IMPORTANT: Only the okapi or pros namespace may be used, not both + * concurrently! The okapi namespace will export all symbols inside the pros + * namespace. + */ +// using namespace pros; +// using namespace pros::literals; +// using namespace okapi; + +/** + * Prototypes for the competition control tasks are redefined here to ensure + * that they can be called from user code (i.e. calling autonomous from a + * button press in opcontrol() for testing purposes). + */ +#ifdef __cplusplus +extern "C" { +#endif +void autonomous(void); +void initialize(void); +void disabled(void); +void competition_initialize(void); +void opcontrol(void); +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +/** + * You can add C++-only headers here + */ +//#include +#endif + +#endif // _PROS_MAIN_H_ diff --git a/test/include/pros/abstract_motor.hpp b/test/include/pros/abstract_motor.hpp new file mode 100644 index 00000000..fd8e8034 --- /dev/null +++ b/test/include/pros/abstract_motor.hpp @@ -0,0 +1,1182 @@ +/** + * \file abstract_motor.hpp + * \ingroup cpp-abstract-motor + * + * Contains prototypes for AbstractMotor, the abstract base class of both + * motors and motor groups. Abstract motors cannot be directly constructed, but + * you can use motors and motor groups as abstract motors. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright Copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef _PROS_ABSTRACT_MOTORS_HPP_ +#define _PROS_ABSTRACT_MOTORS_HPP_ + +#include +#include + +#include "pros/device.hpp" +#include "pros/motors.h" +#include "rtos.hpp" + +namespace pros { +inline namespace v5 { + +/** + * \enum MotorBrake + * Indicates the current 'brake mode' of a motor. + */ +enum class MotorBrake { + coast = 0, ///< Motor coasts when stopped, traditional behavior + brake = 1, ///< Motor brakes when stopped + hold = 2, ///< Motor actively holds position when stopped + invalid = INT32_MAX ///< Invalid brake mode +}; + +/** + * \enum MotorEncoderUnits + * Indicates the units used by the motor encoders. + */ +enum class MotorEncoderUnits { + degrees = 0, ///< Position is recorded as angle in degrees as a floating point number + deg = 0, ///< Position is recorded as angle in degrees as a floating point number + rotations = 1, ///< Position is recorded as angle in rotations as a floating point number + counts = 2, ///< Position is recorded as raw encoder ticks as a whole number + invalid = INT32_MAX ///< Invalid motor encoder units +}; + +// Alias for MotorEncoderUnits +using MotorUnits = MotorEncoderUnits; + +enum class MotorGears { + ratio_36_to_1 = 0, ///< 36:1, 100 RPM, Red gear set + red = ratio_36_to_1, ///< 36:1, 100 RPM, Red gear set + rpm_100 = ratio_36_to_1, ///< 36:1, 100 RPM, Red gear set + ratio_18_to_1 = 1, ///< 18:1, 200 RPM, Green gear set + green = ratio_18_to_1, ///< 18:1, 200 RPM, Green gear set + rpm_200 = ratio_18_to_1, ///< 18:1, 200 RPM, Green gear set + ratio_6_to_1 = 2, ///< 6:1, 600 RPM, Blue gear set + blue = ratio_6_to_1, ///< 6:1, 600 RPM, Blue gear set + rpm_600 = ratio_6_to_1, ///< 6:1, 600 RPM, Blue gear set + invalid = INT32_MAX ///< Error return code +}; + +/** + * \enum MotorType + * Indicates the type of a motor + */ +enum class MotorType { + v5 = 0, ///< 11w motor + exp = 1, ///< 5.5w motor + invalid = INT32_MAX ///< Error return code +}; + + +// Provide Aliases for MotorGears +using MotorGearset = MotorGears; +using MotorCart = MotorGears; +using MotorCartridge = MotorGears; +using MotorGear = MotorGears; + +/** + * \ingroup cpp-abstract-motor + */ +class AbstractMotor { + /** + * \addtogroup cpp-abstract-motor + * @{ + */ + public: + /// \name Motor movement functions + /// These functions allow programmers to make motors move + ///@{ + + /** + * Sets the voltage for the motor from -127 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is + * analogous to use of motor_move(), or motorSet() from the PROS 2 API. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param voltage + * The new motor voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t move(std::int32_t voltage) const = 0; + + /** + * Sets the target absolute position for the motor to move to. + * + * This movement is relative to the position of the motor when initialized or + * the position when it was most recently reset with + * pros::Motor::set_zero_position(). + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The absolute position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t move_absolute(const double position, const std::int32_t velocity) const = 0; + + /** + * Sets the relative target position for the motor to move to. + * + * This movement is relative to the current position of the motor as given in + * pros::Motor::motor_get_position(). Providing 10.0 as the position parameter + * would result in the motor moving clockwise 10 units, no matter what the + * current position is. + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The relative position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t move_relative(const double position, const std::int32_t velocity) const = 0; + + /** + * Sets the velocity for the motor. + * + * This velocity corresponds to different actual speeds depending on the + * gearset used for the motor. This results in a range of +-100 for + * E_MOTOR_GEARSET_36, +-200 for E_MOTOR_GEARSET_18, and +-600 for + * E_MOTOR_GEARSET_6. The velocity is held with PID to ensure consistent + * speed, as opposed to setting the motor's voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param velocity + * The new motor velocity from -+-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t move_velocity(const std::int32_t velocity) const = 0; + + /** + * Sets the output voltage for the motor from -12000 to 12000 in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * \param voltage + * The new voltage value from -12000 to 12000 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t move_voltage(const std::int32_t voltage) const = 0; + + /** + * Stops the motor using the currently configured brake mode. + * + * This function sets motor velocity to zero, which will cause it to act + * according to the set brake mode. If brake mode is set to MOTOR_BRAKE_HOLD, + * this function may behave differently than calling move_absolute(0) + * or motor_move_relative(0). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + */ + virtual std::int32_t brake(void) const = 0; + + /** + * Changes the output velocity for a profiled movement (motor_move_absolute or + * motor_move_relative). This will have no effect if the motor is not following + * a profiled movement. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param velocity + * The new motor velocity from +-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t modify_profiled_velocity(const std::int32_t velocity) const = 0; + + /** + * Gets the target position set for the motor by the user, with a parameter + * for the motor index. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The target position in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + */ + virtual double get_target_position(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the target position(s) set for the motor(s) by the user + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing the target position(s) in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + */ + virtual std::vector get_target_position_all(void) const = 0; + + /** + * Gets the velocity commanded to the motor by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The commanded motor velocity from +-100, +-200, or +-600, or + * PROS_ERR if the operation failed, setting errno. + */ + virtual std::int32_t get_target_velocity(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the velocity/velocities commanded to the motor(s) by the user + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the commanded motor velocity/velocities from +-100, + * +-200, or +-600, or PROS_ERR if the operation failed, setting errno. + */ + virtual std::vector get_target_velocity_all(void) const = 0; + + ///@} + + /// \name Motor telemetry functions + /// \addtogroup cpp-motor-telemetry + /// These functions allow programmers to collect telemetry from motors + ///@{ + + /** + * Gets the actual velocity of the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's actual velocity in RPM or PROS_ERR_F if the operation + * failed, setting errno. + */ + virtual double get_actual_velocity(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the actual velocity/velocities of the motor(s) + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's/motors' actual velocity/velocities in RPM or PROS_ERR_F + * if the operation failed, setting errno. + */ + virtual std::vector get_actual_velocity_all(void) const = 0; + + /** + * Gets the current drawn by the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's current in mA or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::int32_t get_current_draw(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the current(s) drawn by the motor(s) in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector conatining the motor's/motors' current(s) in mA or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::vector get_current_draw_all(void) const = 0; + + /** + * Gets the direction of movement for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. + */ + virtual std::int32_t get_direction(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the direction(s) of movement for the motor(s). + * + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. + */ + virtual std::vector get_direction_all(void) const = 0; + + /** + * Gets the efficiency of the motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + */ + virtual double get_efficiency(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the efficiency/efficiencies of the motor(s) in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing the motor's/motors' efficiency/efficiencies in percent or PROS_ERR_F if the operation + * failed, setting errno. + */ + virtual std::vector get_efficiency_all(void) const = 0; + + /** + * Gets the faults experienced by the motor. + * + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A bitfield containing the motor's faults. + */ + virtual std::uint32_t get_faults(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the faults experienced by the motor(s). + * + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \return A bitfield containing the motor's/motors' faults. + */ + virtual std::vector get_faults_all(void) const = 0; + /** + * Gets the flags set by the motor's operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A bitfield containing the motor's flags. + */ + virtual std::uint32_t get_flags(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the flags set by the motor's/motors' operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A bitfield containing the motor's/motors' flags. + */ + virtual std::vector get_flags_all(void) const = 0; + + /** + * Gets the absolute position of the motor in its encoder units. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + */ + virtual double get_position(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the absolute position(s) of the motor(s) in its encoder units. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + + * + * \return A vector containing the motor's/motors' absolute position(s) in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + */ + virtual std::vector get_position_all(void) const = 0; + + /** + * Gets the power drawn by the motor in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + */ + virtual double get_power(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the power(s) drawn by the motor(s) in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's/motors' power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + */ + virtual std::vector get_power_all(void) const = 0; + + /** + * Gets the raw encoder count of the motor at a given timestamp. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param[in] timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. + */ + virtual std::int32_t get_raw_position(std::uint32_t* const timestamp, const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the raw encoder count(s) of the motor(s) at a given timestamp. + * + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \param timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \return A vector containing the raw encoder count(s) at the given timestamp or PROS_ERR if the + * operation failed. + */ + virtual std::vector get_raw_position_all(std::uint32_t* const timestamp) const = 0; + + /** + * Gets the temperature of the motor in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + */ + virtual double get_temperature(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the temperature(s) of the motor(s) in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing the motor's/motors' temperature(s) in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + */ + virtual std::vector get_temperature_all(void) const = 0; + /** + * Gets the torque generated by the motor in Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. + */ + virtual double get_torque(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the torque(s) generated by the motor(s) in Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing the motor's/motors' torque(s) in Nm or PROS_ERR_F if the operation failed, + * setting errno. + */ + virtual std::vector get_torque_all(void) const = 0; + /** + * Gets the voltage delivered to the motor in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. + */ + virtual std::int32_t get_voltage(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the voltage(s) delivered to the motor(s) in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing the motor's/motors' voltage(s) in mV or PROS_ERR_F if the operation failed, + * setting errno. + */ + virtual std::vector get_voltage_all(void) const = 0; + + /** + * Checks if the motor is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. + */ + virtual std::int32_t is_over_current(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of whether each motor is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. + */ + virtual std::vector is_over_current_all(void) const = 0; + + /** + * Gets the temperature limit flag for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. + */ + virtual std::int32_t is_over_temp(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the temperature limit flag(s) for the motor(s). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. + */ + virtual std::vector is_over_temp_all(void) const = 0; + + ///@} + + /// \name Motor configuration functions + /// \addtogroup cpp-motor-configuration + /// These functions allow programmers to configure the behavior of motors + ///@{ + + /** + * Gets the brake mode that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return One of MotorBrake, according to what was set for the + * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + */ + virtual MotorBrake get_brake_mode(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the brake mode(s) that was set for the motor(s). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing MotorBrake(s), according to what was set for the + * motor(s), or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + */ + virtual std::vector get_brake_mode_all(void) const = 0; + + /** + * Gets the current limit for the motor in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::int32_t get_current_limit(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the current limit(s) for the motor(s) in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing the motor's/motors' current limit(s) in mA or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::vector get_current_limit_all(void) const = 0; + + /** + * Gets the encoder units that were set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return One of MotorUnits according to what is set for the + * motor or E_MOTOR_ENCODER_INVALID if the operation failed. + */ + virtual MotorUnits get_encoder_units(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the encoder units that were set for the motor(s). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector of MotorUnits according to what is set for the + * motor(s) or E_MOTOR_ENCODER_INVALID if the operation failed. + */ + virtual std::vector get_encoder_units_all(void) const = 0; + + /** + * Gets the gearset that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return One of MotorGears according to what is set for the motor, + * or pros::MotorGears::invalid if the operation failed. + */ + virtual MotorGears get_gearing(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the gearset(s) that was/were set for the motor(s). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector of MotorGears according to what is set for the motor(s), + * or pros::MotorGears::invalid if the operation failed. + */ + virtual std::vector get_gearing_all(void) const = 0; + + /** + * @brief Gets returns a vector with all the port numbers in the motor group. + * + * @return std::vector + */ + virtual std::vector get_port_all(void) const = 0; + + /** + * Gets the voltage limit set by the user. + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's voltage limit in V or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::int32_t get_voltage_limit(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the voltage limit(s) set by the user. + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing the motor's/motors' voltage limit(s) in V or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::vector get_voltage_limit_all(void) const = 0; + + /** + * Gets the operation direction of the motor as set by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. + */ + virtual std::int32_t is_reversed(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the operation direction(s) of the motor(s) as set by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. + */ + virtual std::vector is_reversed_all(void) const = 0; + + /** + * Gets the type of the motor + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return One of MotorType according to the type of the motor, + * or pros::MotorType::invalid if the operation failed + */ + virtual MotorType get_type(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the type(s) of the motor(s). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector of MotorType according to the type(s) of the motor(s), + * or pros::MotorType::invalid if the operation failed. + */ + virtual std::vector get_type_all(void) const = 0; + + /** + * Sets one of MotorBrake to the motor. Works with the C enum + * and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param mode + * The MotorBrake to set for the motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_brake_mode(const MotorBrake mode, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_brake_mode_all(const MotorBrake mode) const = 0; + virtual std::int32_t set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const = 0; + /** + * Sets the current limit for the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param limit + * The new current limit in mA + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_current_limit(const std::int32_t limit, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_current_limit_all(const std::int32_t limit) const = 0; + /** + * Sets one of MotorUnits for the motor encoder. Works with the C + * enum and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param units + * The new motor encoder units + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_encoder_units(const MotorUnits units, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_encoder_units_all(const MotorUnits units) const = 0; + virtual std::int32_t set_encoder_units_all(const pros::motor_encoder_units_e_t units) const = 0; + /** + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param gearset + * The new motor gearset + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_gearing(const MotorGears gearset, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_gearing(const pros::motor_gearset_e_t gearset, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_gearing_all(const MotorGears gearset) const = 0; + virtual std::int32_t set_gearing_all(const pros::motor_gearset_e_t gearset) const = 0; + + /** + * Sets the reverse flag for the motor. + * + * This will invert its movements and the values returned for its position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param reverse + * True reverses the motor, false is default + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_reversed(const bool reverse, const std::uint8_t index = 0) = 0; + virtual std::int32_t set_reversed_all(const bool reverse) = 0; + + /** + * Sets the voltage limit for the motor in Volts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param limit + * The new voltage limit in Volts + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_voltage_limit(const std::int32_t limit, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_voltage_limit_all(const std::int32_t limit) const = 0; + + /** + * Sets the position for the motor in its encoder units. + * + * This will be the future reference point for the motor's "absolute" + * position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The new reference position in its encoder units + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_zero_position(const double position, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_zero_position_all(const double position) const = 0; + + /** + * Sets the "absolute" zero position of the motor to its current position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t tare_position(const std::uint8_t index = 0) const = 0; + virtual std::int32_t tare_position_all(void) const = 0; + virtual std::int8_t get_port(const std::uint8_t index = 0) const = 0; + /** + * @brief Returns the number of objects + * + * @return std::int8_t + */ + virtual std::int8_t size(void) const = 0; + + ///@} + private: +}; + +} // namespace v5 +} // namespace pros + +///@} + +#endif diff --git a/test/include/pros/adi.h b/test/include/pros/adi.h new file mode 100644 index 00000000..0b45e57d --- /dev/null +++ b/test/include/pros/adi.h @@ -0,0 +1,1383 @@ +/** + * \file pros/adi.h + * \ingroup c-adi + * + * Contains prototypes for interfacing with the ADI. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-adi ADI (TriPort) C API + * \note The external ADI API can be found [here.](@ref ext-adi) + * \note Additional example code for this module can be found in its [Tutorial.](@ref adi) + */ + +#ifndef _PROS_ADI_H_ +#define _PROS_ADI_H_ + +#include +#include +#ifndef PROS_ERR +#define PROS_ERR (INT32_MAX) +#endif + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \ingroup c-adi + */ + +/** + * \addtogroup c-adi + * @{ + */ + +/** + * \enum adi_port_config_e + * Represents the port type for an ADI port. + */ +typedef enum adi_port_config_e { + E_ADI_ANALOG_IN = 0, + E_ADI_ANALOG_OUT = 1, + E_ADI_DIGITAL_IN = 2, + E_ADI_DIGITAL_OUT = 3, + +#ifdef _INTELLISENSE +#define _DEPRECATE_DIGITAL_IN = E_ADI_DIGITAL_IN +#define _DEPRECATE_ANALOG_IN = E_ADI_ANALOG_IN +#else +#define _DEPRECATE_DIGITAL_IN __attribute__((deprecated("use E_ADI_DIGITAL_IN instead"))) = E_ADI_DIGITAL_IN +#define _DEPRECATE_ANALOG_IN __attribute__((deprecated("use E_ADI_ANALOG_IN instead"))) = E_ADI_ANALOG_IN +#endif + + E_ADI_SMART_BUTTON _DEPRECATE_DIGITAL_IN, + E_ADI_SMART_POT _DEPRECATE_ANALOG_IN, + + E_ADI_LEGACY_BUTTON _DEPRECATE_DIGITAL_IN, + E_ADI_LEGACY_POT _DEPRECATE_ANALOG_IN, + E_ADI_LEGACY_LINE_SENSOR _DEPRECATE_ANALOG_IN, + E_ADI_LEGACY_LIGHT_SENSOR _DEPRECATE_ANALOG_IN, + E_ADI_LEGACY_GYRO = 10, + E_ADI_LEGACY_ACCELEROMETER _DEPRECATE_ANALOG_IN, + +#undef _DEPRECATE_DIGITAL_IN +#undef _DEPRECATE_ANALOG_IN + + E_ADI_LEGACY_SERVO = 12, + E_ADI_LEGACY_PWM = 13, + + E_ADI_LEGACY_ENCODER = 14, + E_ADI_LEGACY_ULTRASONIC = 15, + + E_ADI_TYPE_UNDEFINED = 255, + E_ADI_ERR = PROS_ERR +} adi_port_config_e_t; + +/** + * \enum adi_potentiometer_type_e_t + * Represents the potentiometer version type. + */ +typedef enum adi_potentiometer_type_e { + E_ADI_POT_EDR = 0, + E_ADI_POT_V2 +} adi_potentiometer_type_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define ADI_ANALOG_IN pros::E_ADI_ANALOG_IN +#define ADI_ANALOG_OUT pros::E_ADI_ANALOG_OUT +#define ADI_DIGITAL_IN pros::E_ADI_DIGITAL_IN +#define ADI_DIGITAL_OUT pros::E_ADI_DIGITAL_OUT +#define ADI_SMART_BUTTON pros::E_ADI_SMART_BUTTON +#define ADI_SMART_POT pros::E_ADI_SMART_POT +#define ADI_LEGACY_BUTTON pros::E_ADI_LEGACY_BUTTON +#define ADI_LEGACY_POT pros::E_ADI_LEGACY_POT +#define ADI_LEGACY_LINE_SENSOR pros::E_ADI_LEGACY_LINE_SENSOR +#define ADI_LEGACY_LIGHT_SENSOR pros::E_ADI_LEGACY_LIGHT_SENSOR +#define ADI_LEGACY_GYRO pros::E_ADI_LEGACY_GYRO +#define ADI_LEGACY_ACCELEROMETER pros::E_ADI_LEGACY_ACCELEROMETER +#define ADI_LEGACY_SERVO pros::E_ADI_LEGACY_SERVO +#define ADI_LEGACY_PWM pros::E_ADI_LEGACY_PWM +#define ADI_LEGACY_ENCODER pros::E_ADI_LEGACY_ENCODER +#define ADI_LEGACY_ULTRASONIC pros::E_ADI_LEGACY_ULTRASONIC +#define ADI_TYPE_UNDEFINED pros::E_ADI_TYPE_UNDEFINED +#define ADI_ERR pros::E_ADI_ERR +#else +#define ADI_ANALOG_IN E_ADI_ANALOG_IN +#define ADI_ANALOG_OUT E_ADI_ANALOG_OUT +#define ADI_DIGITAL_IN E_ADI_DIGITAL_IN +#define ADI_DIGITAL_OUT E_ADI_DIGITAL_OUT +#define ADI_SMART_BUTTON E_ADI_SMART_BUTTON +#define ADI_SMART_POT E_ADI_SMART_POT +#define ADI_LEGACY_BUTTON E_ADI_LEGACY_BUTTON +#define ADI_LEGACY_POT E_ADI_LEGACY_POT +#define ADI_LEGACY_LINE_SENSOR E_ADI_LEGACY_LINE_SENSOR +#define ADI_LEGACY_LIGHT_SENSOR E_ADI_LEGACY_LIGHT_SENSOR +#define ADI_LEGACY_GYRO E_ADI_LEGACY_GYRO +#define ADI_LEGACY_ACCELEROMETER E_ADI_LEGACY_ACCELEROMETER +#define ADI_LEGACY_SERVO E_ADI_LEGACY_SERVO +#define ADI_LEGACY_PWM E_ADI_LEGACY_PWM +#define ADI_LEGACY_ENCODER E_ADI_LEGACY_ENCODER +#define ADI_LEGACY_ULTRASONIC E_ADI_LEGACY_ULTRASONIC +#define ADI_TYPE_UNDEFINED E_ADI_TYPE_UNDEFINED +#define ADI_ERR E_ADI_ERR +#endif +#endif + +#define INTERNAL_ADI_PORT 22 +#define NUM_ADI_PORTS 8 + +#ifdef __cplusplus +namespace c { +#endif + +/** @} Add to group c-adi*/ + +/** + * \ingroup c-adi + */ + +/** + * \addtogroup c-adi + * @{ + */ + +/** + * Gets the configuration for the given ADI port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports. + * + * \param port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which to return + * the configuration + * + * \return The ADI configuration for the given port + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * adi_port_set_config(ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * // Displays the value of E_ADI_ANALOG_IN + * printf("Port Type: %d\n", adi_port_get_config(ANALOG_SENSOR_PORT)); + * } + * \endcode + */ +adi_port_config_e_t adi_port_get_config(uint8_t port); + +/** + * Gets the value for the given ADI port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports. + * + * \param port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which the value + * will be returned + * + * \return The value stored for the given port + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * adi_port_set_config(ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * printf("Port Value: %d\n", adi_get_value(ANALOG_SENSOR_PORT)); + * } + * \endcode + */ +int32_t adi_port_get_value(uint8_t port); + +/** + * Configures an ADI port to act as a given sensor type. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports. + * + * \param port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param type + * The configuration type for the port + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * adi_port_set_config(ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * } + * \endcode + */ +int32_t adi_port_set_config(uint8_t port, adi_port_config_e_t type); + +/** + * Sets the value for the given ADI port. + * + * This only works on ports configured as outputs, and the behavior will change + * depending on the configuration of the port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports. + * + * \param port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which the value + * will be set + * \param value + * The value to set the ADI port to + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void initialize() { + * adi_port_set_config(DIGITAL_SENSOR_PORT, E_ADI_DIGITAL_OUT); + * adi_set_value(DIGITAL_SENSOR_PORT, HIGH); + * } + * \endcode + */ +int32_t adi_port_set_value(uint8_t port, int32_t value); + +/** + * Calibrates the analog sensor on the specified port and returns the new + * calibration value. + * + * This method assumes that the true sensor value is not actively changing at + * this time and computes an average from approximately 500 samples, 1 ms apart, + * for a 0.5 s period of calibration. The average value thus calculated is + * returned and stored for later calls to the adi_analog_read_calibrated() and + * adi_analog_read_calibrated_HR() functions. These functions will return + * the difference between this value and the current sensor value when called. + * + * Do not use this function when the sensor value might be unstable + * (gyro rotation, accelerometer movement). + * + * \note The ADI currently returns data at 10ms intervals, in constrast to the + * calibrate function’s 1ms sample rate. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * + * \param port + * The ADI port to calibrate (from 1-8, 'a'-'h', 'A'-'H') + * + * \return The average sensor value computed by this function + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * adi_analog_calibrate(ANALOG_SENSOR_PORT); + * printf("Calibrated Reading: %d\n", adi_analog_read_calibrated(ANALOG_SENSOR_PORT)); + * // All readings from then on will be calibrated + * } + * \endcode + */ +int32_t adi_analog_calibrate(uint8_t port); + +/** + * Gets the 12-bit value of the specified port. + * + * The value returned is undefined if the analog pin has been switched to a + * different mode. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an analog input + * + * \param port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The analog sensor value, where a value of 0 reflects an input voltage + * of nearly 0 V and a value of 4095 reflects an input voltage of nearly 5 V + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Sensor Reading: %d\n", adi_analog_read(ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_analog_read(uint8_t port); + +/** + * Gets the 12 bit calibrated value of an analog input port. + * + * The adi_analog_calibrate() function must be run first. This function is + * inappropriate for sensor values intended for integration, as round-off error + * can accumulate causing drift over time. Use adi_analog_read_calibrated_HR() + * instead. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an analog input + * + * \param port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The difference of the sensor value from its calibrated default from + * -4095 to 4095 + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Sensor Reading: %d\n", adi_analog_read_calibrated(ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_analog_read_calibrated(uint8_t port); + +/** + * Gets the 16 bit calibrated value of an analog input port. + * + * The adi_analog_calibrate() function must be run first. This is intended for + * integrated sensor values such as gyros and accelerometers to reduce drift due + * to round-off, and should not be used on a sensor such as a line tracker + * or potentiometer. + * + * The value returned actually has 16 bits of "precision", even though the ADC + * only reads 12 bits, so that error induced by the average value being between + * two values when integrated over time is trivial. Think of the value as the + * true value times 16. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an analog input + * + * \param port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The difference of the sensor value from its calibrated default from + * -16384 to 16384 + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * adi_analog_calibrate(ANALOG_SENSOR_PORT); + * printf("Sensor Reading: %d\n", adi_analog_read_calibrated_HR(ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_analog_read_calibrated_HR(uint8_t port); + +/** + * Gets the digital value (1 or 0) of a port configured as a digital input. + * + * If the port is configured as some other mode, the digital value which + * reflects the current state of the port is returned, which may or may not + * differ from the currently set value. The return value is undefined for ports + * configured as any mode other than a Digital Input. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a digital input + * + * \param port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * + * \return True if the pin is HIGH, or false if it is LOW + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Sensor Value: %d\n", adi_digital_read(DIGITAL_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_digital_read(uint8_t port); + +/** + * Gets a rising-edge case for a digital button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under the + * same circumstances, so only one task should call this function for any given + * button. E.g., Task A calls this function for buttons 1 and 2. Task B may call + * this function for button 3, but should not for buttons 1 or 2. A typical + * use-case for this function is to call inside opcontrol to detect new button + * presses, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a digital input + * + * \param port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * + * \return 1 if the button is pressed and had not been pressed + * the last time this function was called, 0 otherwise. + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * if (adi_digital_get_new_press(DIGITAL_SENSOR_PORT)) { + * // Toggle pneumatics or other state operations + * } + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_digital_get_new_press(uint8_t port); + +/** + * Sets the digital value (1 or 0) of a port configured as a digital output. + * + * If the port is configured as some other mode, behavior is undefined. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a digital output + * + * \param port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * \param value + * An expression evaluating to "true" or "false" to set the output to + * HIGH or LOW respectively, or the constants HIGH or LOW themselves + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT + * + * void opcontrol() { + * bool state = LOW; + * while (true) { + * state != state; + * adi_digital_write(DIGITAL_SENSOR_PORT, state); + * delay(5); // toggle the sensor value every 50ms + * } + * } + * \endcode + */ +int32_t adi_digital_write(uint8_t port, bool value); + +/** + * Configures the port as an input or output with a variety of settings. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * + * \param port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * \param mode + * One of INPUT, INPUT_ANALOG, INPUT_FLOATING, OUTPUT, or OUTPUT_OD + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * adi_pin_mode(ANALOG_SENSOR_PORT, INPUT_ANALOG); + * } + * \endcode + */ +int32_t adi_pin_mode(uint8_t port, uint8_t mode); + +/** + * Sets the speed of the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an motor + * + * \param port + * The ADI port to set (from 1-8, 'a'-'h', 'A'-'H') + * \param speed + * The new signed speed; -127 is full reverse and 127 is full forward, + * with 0 being off + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * adi_motor_set(MOTOR_PORT, 127); // Go full speed forward + * delay(1000); + * adi_motor_set(MOTOR_PORT, 0); // Stop the motor + * } + * \endcode + */ +int32_t adi_motor_set(uint8_t port, int8_t speed); + +/** + * Gets the last set speed of the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an motor + * + * \param port + * The ADI port to get (from 1-8, 'a'-'h', 'A'-'H') + * + * \return The last set speed of the motor on the given port + * + * \b Example + * \code + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * adi_motor_set(MOTOR_PORT, 127); // Go full speed forward + * printf("Commanded Motor Power: %d\n", adi_motor_get(MOTOR_PORT)); // Will display 127 + * delay(1000); + * adi_motor_set(MOTOR_PORT, 0); // Stop the motor + * } + * \endcode + */ +int32_t adi_motor_get(uint8_t port); + +/** + * Stops the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an motor + * + * \param port + * The ADI port to set (from 1-8, 'a'-'h', 'A'-'H') + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * adi_motor_set(MOTOR_PORT, 127); // Go full speed forward + * delay(1000); + * // adi_motor_set(MOTOR_PORT, 0); // Stop the motor + * adi_motor_stop(MOTOR_PORT); // use this instead + * } + * \endcode + */ +int32_t adi_motor_stop(uint8_t port); + +/** + * Reference type for an initialized encoder. + * + * This merely contains the port number for the encoder. + */ +typedef int32_t adi_encoder_t; + +/** + * Gets the number of ticks recorded by the encoder. + * + * There are 360 ticks in one revolution. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an encoder + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to read + * + * \return The signed and cumulative number of counts since the last start or + * reset + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); + * while (true) { + * printf("Encoder Value: %d\n", adi_encoder_get(enc)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_encoder_get(adi_encoder_t enc); + +/** + * Creates an encoder object and configures the specified ports accordingly. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an encoder + + * + * \param port_top + * The "top" wire from the encoder sensor with the removable cover side + * up. This should be in port 1, 3, 5, or 7 ('A', 'C', 'E', or 'G'). + * \param port_bottom + * The "bottom" wire from the encoder sensor + * \param reverse + * If "true", the sensor will count in the opposite direction + * + * \return An adi_encoder_t object to be stored and used for later calls to + * encoder functions + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); + * while (true) { + * printf("Encoder Value: %d\n", adi_encoder_get(enc)); + * delay(5); + * } + * } + * \endcode + */ +adi_encoder_t adi_encoder_init(uint8_t port_top, uint8_t port_bottom, bool reverse); + +/** + * Sets the encoder value to zero. + * + * It is safe to use this method while an encoder is enabled. It is not + * necessary to call this method before stopping or starting an encoder. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an encoder + + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to reset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); + * delay(1000); // Move the encoder around in this time + * adi_encoder_reset(enc); // The encoder is now zero again + * } + * \endcode + */ +int32_t adi_encoder_reset(adi_encoder_t enc); + +/** + * Disables the encoder and voids the configuration on its ports. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an encoder + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to stop + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); + * // Use the encoder + * adi_encoder_shutdown(enc); + * } + * \endcode + */ +int32_t adi_encoder_shutdown(adi_encoder_t enc); + +/** + * Reference type for an initialized ultrasonic. + * + * This merely contains the port number for the ultrasonic. + */ +typedef int32_t adi_ultrasonic_t; + +/** + * Gets the current ultrasonic sensor value in centimeters. + * + * If no object was found, zero is returned. If the ultrasonic sensor was never + * started, the return value is undefined. Round and fluffy objects can cause + * inaccurate values to be returned. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param ult + * The adi_ultrasonic_t object from adi_ultrasonic_init() to read + * + * \return The distance to the nearest object in m^-4 (10000 indicates 1 meter), + * measured from the sensor's mounting points. + * + * \b Example + * \code + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * + * void opcontrol() { + * adi_ultrasonic_t ult = adi_ultrasonic_init(PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", adi_ultrasonic_get(ult)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_ultrasonic_get(adi_ultrasonic_t ult); + +/** + * Creates an ultrasonic object and configures the specified ports accordingly. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param port_ping + * The port connected to the orange OUTPUT cable. This should be in port + * 1, 3, 5, or 7 ('A', 'C', 'E', 'G'). + * \param port_echo + * The port connected to the yellow INPUT cable. This should be in the + * next highest port following port_ping. + * + * \return An adi_ultrasonic_t object to be stored and used for later calls to + * ultrasonic functions + * + * \b Example + * \code + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * + * void opcontrol() { + * adi_ultrasonic_t ult = adi_ultrasonic_init(PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", adi_ultrasonic_get(ult)); + * delay(5); + * } + * } + * \endcode + */ +adi_ultrasonic_t adi_ultrasonic_init(uint8_t port_ping, uint8_t port_echo); + +/** + * Disables the ultrasonic sensor and voids the configuration on its ports. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param ult + * The adi_ultrasonic_t object from adi_ultrasonic_init() to stop + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * + * void opcontrol() { + * adi_ultrasonic_t ult = adi_ultrasonic_init(PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", adi_ultrasonic_get(ult)); + * delay(5); + * } + * adi_ultrasonic_shutdown(ult); + * } + * \endcode + */ +int32_t adi_ultrasonic_shutdown(adi_ultrasonic_t ult); + +/** + * Reference type for an initialized gyroscope. + * + * This merely contains the port number for the gyroscope. + */ +typedef int32_t adi_gyro_t; + +/** + * Gets the current gyro angle in tenths of a degree. Unless a multiplier is + * applied to the gyro, the return value will be a whole number representing + * the number of degrees of rotation times 10. + * + * There are 360 degrees in a circle, thus the gyro will return 3600 for one + * whole rotation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object for which the angle will be returned + * + * \return The gyro angle in degrees. + * + * \b Example + * \code + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * + * void opcontrol() { + * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", adi_gyro_get(gyro)); + * delay(5); + * } + * } + * \endcode + */ +double adi_gyro_get(adi_gyro_t gyro); + +/** + * Initializes a gyroscope on the given port. If the given port has not + * previously been configured as a gyro, then this function starts a 1300 ms + * calibration period. + * + * It is highly recommended that this function be called from initialize() when + * the robot is stationary to ensure proper calibration. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a gyro + * + * \param port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * \param multiplier + * A scalar value that will be multiplied by the gyro heading value + * supplied by the ADI + * + * \return An adi_gyro_t object containing the given port, or PROS_ERR if the + * initialization failed. + * + * \b Example + * \code + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * + * void opcontrol() { + * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", adi_gyro_get(gyro)); + * delay(5); + * } + * } + * \endcode + */ +adi_gyro_t adi_gyro_init(uint8_t port, double multiplier); + +/** + * Resets the gyroscope value to zero. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object for which the angle will be returned + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * + * void opcontrol() { + * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); + * uint32_t now = millis(); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", adi_gyro_get(gyro)); + * + * if (millis() - now > 2000) { + * // Reset the gyro every 2 seconds + * adi_gyro_reset(gyro); + * now = millis(); + * } + * + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_gyro_reset(adi_gyro_t gyro); + +/** + * Disables the gyro and voids the configuration on its port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object to be shut down + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * + * void opcontrol() { + * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); + * uint32_t now = millis(); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", adi_gyro_get(gyro)); + * + * if (millis() - now > 2000) { + * adi_gyro_shutdown(gyro); + * // Shut down the gyro after two seconds + * break; + * } + * + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_gyro_shutdown(adi_gyro_t gyro); + +/** + * Reference type for an initialized potentiometer. + * + * This merely contains the port number for the potentiometer. + */ +typedef int32_t adi_potentiometer_t; + +/** + * Initializes a potentiometer on the given port of the original potentiometer. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \param port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * + * \return An adi_potentiometer_t object containing the given port, or PROS_ERR if the + * initialization failed. + * + * \b Example + * \code + * #define POTENTIOMETER_PORT 1 + * + * void opcontrol() { + * adi_potentiometer_t potentiometer = adi_potentiometer_init(POTENTIOMETER_PORT); + * while (true) { + * // Print the potentiometer's angle + * printf("Angle: %lf\n", adi_potentiometer_get_angle(potentiometer)); + * delay(5); + * } + * } + * \endcode + */ +adi_potentiometer_t adi_potentiometer_init(uint8_t port); + +/** + * Initializes a potentiometer on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \param port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * \param potentiometer_type + * An adi_potentiometer_type_e_t enum value specifying the potentiometer version type + * + * \return An adi_potentiometer_t object containing the given port, or PROS_ERR if the + * initialization failed. + * + * \b Example + * \code + * #define POTENTIOMETER_PORT 1 + * #define POTENTIOMETER_TYPE E_ADI_POT_EDR + * + * void opcontrol() { + * adi_potentiometer_t potentiometer = adi_potentiometer_type_init(POTENTIOMETER_PORT, POTENTIOMETER_TYPE); + * while (true) { + * // Print the potentiometer's angle + * printf("Angle: %lf\n", adi_potentiometer_get_angle(potentiometer)); + * delay(5); + * } + * } + * \endcode + */ +adi_potentiometer_t adi_potentiometer_type_init(uint8_t port, adi_potentiometer_type_e_t potentiometer_type); + +/** + * Gets the current potentiometer angle in tenths of a degree. + * + * The original potentiometer rotates 250 degrees thus returning an angle between 0-250 degrees. + * Potentiometer V2 rotates 330 degrees thus returning an angle between 0-330 degrees. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \param potentiometer + * The adi_potentiometer_t object for which the angle will be returned + * + * \return The potentiometer angle in degrees. + * + * \b Example + * \code + * #define POTENTIOMETER_PORT 1 + * + * void opcontrol() { + * adi_potentiometer_t potentiometer = adi_potentiometer_t(POTENTIOMETER_PORT); + * while (true) { + * // Print the potnetiometer's angle + * printf("Angle: %lf\n", adi_potentiometer_get_angle(potentiometer)); + * delay(5); + * } + * } + * \endcode + */ +double adi_potentiometer_get_angle(adi_potentiometer_t potentiometer); + +/** + * Reference type for an initialized addressable led. + * + * This merely contains the port number for the led, unlike its use as an + * object to store led data in the C++ API. + */ +typedef int32_t adi_led_t; + +/** + * Initializes a led on the given port of the original led. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - The ADI port given is not a valid port as defined below + * EADDRINUSE - The port is not configured for ADI output + * + * \param port + * The ADI port to initialize as a led (from 1-8, 'a'-'h', 'A'-'H') + * + * \return An adi_led_t object containing the given port, or PROS_ERR if the + * initialization failed, setting errno + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the led to the colors in the buffer + * adi_led_set(led, buffer, 10); + * delay(5); + * } + * } + * \endcode + */ +adi_led_t adi_led_init(uint8_t port); + +/** + * @brief Clear the entire led strip of color + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the led to the colors in the buffer + * adi_led_set(led, buffer, 10); + * delay(5); + * + * // Clear the led strip + * adi_led_clear(led); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_led_clear_all(adi_led_t led, uint32_t* buffer, uint32_t buffer_length); + +/** + * @brief Set the entire led strip using the colors contained in the buffer + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the led strip to the colors in the buffer + * adi_led_set(led, buffer, 10); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_led_set(adi_led_t led, uint32_t* buffer, uint32_t buffer_length); + +/** + * @brief Set the entire led strip to one color + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @param color color to set all the led strip value to + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the led strip to red + * adi_led_set_all(led, buffer, 10, 0xFF0000); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_led_set_all(adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color); + +/** + * @brief Set one pixel on the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of the input buffer + * @param color color to clear all the led strip to + * @param pixel_position position of the pixel to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the first pixel to red + * adi_led_set_pixel(led, buffer, 10, 0xFF0000, 0); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_led_set_pixel(adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color, uint32_t pixel_position); + +/** + * @brief Clear one pixel on the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of the input buffer + * @param pixel_position position of the pixel to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the first pixel to red + * adi_led_set_pixel(led, buffer, 10, 0xFF0000, 0); + * delay(5); + * + * // Clear the first pixel + * adi_led_clear_pixel(led, buffer, 10, 0); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_led_clear_pixel(adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t pixel_position); + +/** + * \name Ease of use macro definitions + * These functions provide ease of use definitions for the ADI functions. + * @{ + */ + +/** + * Used for adi_digital_write() to specify a logic HIGH state to output. + * + * In reality, using any non-zero expression or "true" will work to set a pin to + * HIGH. + */ +#define HIGH 1 +/** + * Used for adi_digital_write() to specify a logic LOW state to output. + * + * In reality, using a zero expression or "false" will work to set a pin to LOW. + */ +#define LOW 0 + +/** + * adi_pin_mode() state for a digital input. + */ +#define INPUT 0x00 +/** + * adi_pin_mode() state for a digital output. + */ +#define OUTPUT 0x01 +/** + * adi_pin_mode() state for an analog input. + */ +#define INPUT_ANALOG 0x02 + +/** + * adi_pin_mode() state for an analog output. + */ +#define OUTPUT_ANALOG 0x03 + +/** @} Name: Ease of use macro definitions*/ + +/** @} Add to group: c-adi*/ + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_ADI_H_ diff --git a/test/include/pros/adi.hpp b/test/include/pros/adi.hpp new file mode 100644 index 00000000..f01615d7 --- /dev/null +++ b/test/include/pros/adi.hpp @@ -0,0 +1,2036 @@ +/** + * \file pros/adi.hpp + * \ingroup cpp-adi + * + * Contains prototypes for interfacing with the ADI. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-adi ADI (TriPort) C++ API + * \note The external ADI API can be found [here.](@ref ext-adi) + * \note Additional example code for this module can be found in its [Tutorial.](@ref adi) + */ + +#ifndef _PROS_ADI_HPP_ +#define _PROS_ADI_HPP_ + +#include +#include +#include +#include +#include + +#include "pros/adi.h" + +#define LEGACY_TYPEDEF(old_name, new_name) using old_name [[deprecated("use " #new_name " instead")]] = new_name + +namespace pros { +namespace adi { + +/** type definition for the pair of smart port and adi port for the basic adi devices */ +using ext_adi_port_pair_t = std::pair; + +/** type definition for the triplet of smart port and two adi ports for the two wire adi devices*/ +using ext_adi_port_tuple_t = std::tuple; + +/** + * \ingroup cpp-adi + */ +class Port { + /** + * \addtogroup cpp-adi + * @{ + */ + + public: + /** + * Configures an ADI port to act as a given sensor type. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param type + * The configuration type for the port + * + * \b Example + * \code + * #define POTENTIOMETER_PORT 1 + * #define POTENTIOMETER_TYPE pros::E_ADI_POT_EDR + * + * void opcontrol() { + * pros::ADIPotentiometer potentiometer (POTENTIOMETER_PORT, POTENTIOMETER_TYPE); + * while (true) { + * // Get the potentiometer angle + * std::cout << "Angle: " << potnetiometer.get_angle(); + * pros::delay(10); + * } + * } + * \endcode + */ + explicit Port(std::uint8_t adi_port, adi_port_config_e_t type = E_ADI_TYPE_UNDEFINED); + + /** + * Configures an ADI port on an adi expander to act as a given sensor type. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param port_pair + * The pair of the smart port number (from 1-22) and the ADI port number + * (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param type + * The configuration type for the port + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 'a' + * #define EXT_ADI_SMART_PORT 1 + * + * void initialize() { + * pros::adi::Port sensor ({EXT_ADI_SMART_PORT, ANALOG_SENSOR_PORT}, E_ADI_ANALOG_IN); + * // Displays the value of E_ADI_ANALOG_IN + * std::cout << "Port Type: " << sensor.get_config(); + * } + * \endcode + */ + explicit Port(ext_adi_port_pair_t port_pair, adi_port_config_e_t type = E_ADI_TYPE_UNDEFINED); + + /** + * Gets the configuration for the given ADI port. + * + * \return The ADI configuration for the given port + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * void initialize() { + * adi_port_set_config(ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * // Displays the value of E_ADI_ANALOG_IN + * printf("Port Type: %d\n", adi_port_get_config(ANALOG_SENSOR_PORT)); + * } + * \endcode + */ + std::int32_t get_config() const; + + /** + * Gets the value for the given ADI port. + * + * \return The value stored for the given port + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * pros::adi::Port sensor (ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * std::cout << "Port Value: " << sensor.get_value(); + * } + * \endcode + */ + std::int32_t get_value() const; + + /** + * Configures an ADI port to act as a given sensor type. + * + * \param type + * The configuration type for the port + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * pros::adi::Port sensor (ANALOG_SENSOR_PORT, E_ADI_DIGITAL_IN); + * // Do things as a digital sensor + * // Digital is unplugged and an analog is plugged in + * sensor.set_config(E_ADI_ANALOG_IN); + * } + * \endcode + */ + std::int32_t set_config(adi_port_config_e_t type) const; + + /** + * Sets the value for the given ADI port. + * + * This only works on ports configured as outputs, and the behavior will + * change depending on the configuration of the port. + * + * \param value + * The value to set the ADI port to + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void initialize() { + * pros::adi::Port sensor (DIGITAL_SENSOR_PORT, E_ADI_DIGITAL_OUT); + * sensor.set_value(DIGITAL_SENSOR_PORT, HIGH); + * } + * \endcode + */ + std::int32_t set_value(std::int32_t value) const; + + /** + * Gets the port of the sensor. + * + * \return returns a tuple of integer ports. + * + * \note The parts of the tuple are {smart port, adi port, second adi port (when applicable)}. + * + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 // 'A' + * + * void initialize() { + * pros::adi::AnalogIn sensor (DIGITAL_SENSOR_PORT); + * + * // Getting values from the tuple using std::get + * int sensorSmartPort = std::get<0>(sensor.get_port()); // First value + * int sensorAdiPort = std::get<1>(sensor.get_port()); // Second value + * + * // Prints the first and second value from the port tuple (The Adi Port. The first value is the Smart Port) + * printf("Sensor Smart Port: %d\n", sensorSmartPort); + * printf("Sensor Adi Port: %d\n", sensorAdiPort); + * } + * \endcode + */ + virtual ext_adi_port_tuple_t get_port() const; + + protected: + std::uint8_t _smart_port; + std::uint8_t _adi_port; +}; +///@} + +class AnalogIn : protected Port { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * Configures an ADI port to act as an Analog Input. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * pros::ADIAnalogIn sensor (ANALOG_SENSOR_PORT); + * while (true) { + * // Use the sensor + * } + * } + * \endcode + */ + explicit AnalogIn(std::uint8_t adi_port); + + /** + * Configures an ADI port to act as an Analog Input. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define EXT_ADI_SENSOR_PORT 1 + * #define ADI_PORT 'a' + * + * void opcontrol() { + * pros::ADIAnalogIn sensor ({EXT_ADI_SMART_PORT, ADI_PORT}); + * while (true) { + * // Use the sensor + * } + * } + * \endcode + */ + explicit AnalogIn(ext_adi_port_pair_t port_pair); + + /** + * Calibrates the analog sensor on the specified port and returns the new + * calibration value. + * + * This method assumes that the true sensor value is not actively changing at + * this time and computes an average from approximately 500 samples, 1 ms + * apart, for a 0.5 s period of calibration. The average value thus calculated + * is returned and stored for later calls to the + * pros::AnalogIn::get_value_calibrated() and + * pros::AnalogIn::get_value_calibrated_HR() functions. These functions + * will return the difference between this value and the current sensor value + * when called. + * + * Do not use this function when the sensor value might be unstable (gyro + * rotation, accelerometer movement). + * + * \note The ADI currently returns data at 10ms intervals, in contrast to the + * calibrate function’s 1ms sample rate. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as an analog input + * + * \return The average sensor value computed by this function + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * pros::adi::AnalogIn sensor (ANALOG_SENSOR_PORT); + * sensor.calibrate(ANALOG_SENSOR_PORT); + * std::cout << "Calibrated Reading:" << sensor.get_value_calibrated(); + * // All readings from then on will be calibrated + * } + * \endcode + */ + std::int32_t calibrate() const; + + /** + * Gets the 12 bit calibrated value of an analog input port. + * + * The pros::adi::AnalogIn::calibrate() function must be run first. This + * function is inappropriate for sensor values intended for integration, as + * round-off error can accumulate causing drift over time. Use + * pros::adi::AnalogIn::get_value_calibrated_HR() instead. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as an analog input + * + * \return The difference of the sensor value from its calibrated default from + * -4095 to 4095 + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * pros::adi::AnalogIn sensor (ANALOG_SENSOR_PORT); + * sensor.calibrate(ANALOG_SENSOR_PORT); + * std::cout << "Calibrated Reading:" << sensor.get_value_calibrated(); + * // All readings from then on will be calibrated + * } + * \endcode + */ + std::int32_t get_value_calibrated() const; + + /** + * Gets the 16 bit calibrated value of an analog input port. + * + * The pros::adi::AnalogIn::calibrate() function must be run first. This is + * intended for integrated sensor values such as gyros and accelerometers to + * reduce drift due to round-off, and should not be used on a sensor such as a + * line tracker or potentiometer. + * + * The value returned actually has 16 bits of "precision", even though the ADC + * only reads 12 bits, so that error induced by the average value being + * between two values when integrated over time is trivial. Think of the value + * as the true value times 16. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as an analog input + * + * \return The difference of the sensor value from its calibrated default from + * -16384 to 16384 + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * pros::adi::AnalogIn sensor (ANALOG_SENSOR_PORT); + * sensor.calibrate(ANALOG_SENSOR_PORT); + * std::cout << "Calibrated Reading:" << sensor.get_value_calibrated(); + * // All readings from then on will be calibrated + * } + * \endcode + */ + std::int32_t get_value_calibrated_HR() const; + + /** + * Reads an analog input channel and returns the 12-bit value. + * + * The value returned is undefined if the analog pin has been switched to a different mode. The meaning of the + * returned value varies depending on the sensor attached. + * + * Inherited from ADIPort::get_value. + * + * This function uses the following values of errno when an error state is reached: + * EADDRINUSE - The port is not configured as an analog input (e.g. the port has been reconfigured) + * + * \return The analog sensor value, where a value of 0 reflects an input + * voltage of nearly 0 V and a value of 4095 reflects an input voltage of + * nearly 5 V + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * pros::adi::AnalogIn sensor (ANALOG_SENSOR_PORT); + * std::cout << "Sensor Reading:" << sensor.get_value(); + * } + * \endcode + */ + using Port::get_value; + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format(this below is all in one line with no new line): + * AnalogIn [smart_port: analog_in._smart_port, adi_port: analog_in._adi_port, + * value calibrated: (12 bit calibrated value), + * value calibrated HR: (16 bit calibrated value), value: (12 bit value)] + */ + friend std::ostream& operator<<(std::ostream& os, pros::adi::AnalogIn& analog_in); + + using Port::get_port; +}; + +///@} + +// using ADIPotentiometer = ADIAnalogIn; +using LineSensor = AnalogIn; +using LightSensor = AnalogIn; +using Accelerometer = AnalogIn; + +class AnalogOut : private Port { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * Configures an ADI port to act as an Analog Output. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * pros::AnalogOut sensor (ANALOG_SENSOR_PORT); + * // Use the sensor + * } + * @endcode + */ + explicit AnalogOut(std::uint8_t adi_port); + + /** + * Configures an ADI port on an adi_expander to act as an Analog Output. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param port_pair + * The pair of the smart port number (from 1-22) and the + * ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * + * \b Example + * \code + * #define EXT_ADI_SMART_PORT 1 + * #define ADI_PORT 'a' + * + * void opcontrol() { + * pros::AnalogOut sensor ({EXT_ADI_SMART_PORT, ADI_PORT}); + * // Use the sensor + * } + * \endcode + */ + explicit AnalogOut(ext_adi_port_pair_t port_pair); + + /** + * Sets the output for the Analog Output from 0 (0V) to 4095 (5V). + * + * Inherited from ADIPort::set_value. + * + * This function uses the following values of errno when an error state is reached: + * EACCES - Another resource is currently trying to access the ADI. + * + * \param value + * The value to set the ADI port to + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * pros::AnalogOut sensor (ANALOG_SENSOR_PORT); + * sensor.set_value(4095); // Set the port to 5V + * } + * \endcode + */ + using Port::set_value; + + using Port::get_port; + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format(this below is all in one line with no new line): + * AnalogOut [smart_port: analog_out._smart_port, adi_port: analog_out._adi_port, + * value: (value)] + */ + friend std::ostream& operator<<(std::ostream& os, pros::adi::AnalogOut& analog_out); +}; +///@} + +class DigitalOut : private Port { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * Configures an ADI port to act as a Digital Output. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param init_state + * The initial state for the port + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * bool state = LOW; + * pros::adi::DigitalOut sensor (DIGITAL_SENSOR_PORT, state); + * while (true) { + * state != state; + * sensor.set_value(state); + * pros::delay(10); // toggle the sensor value every 50ms + * } + * } + * \endcode + */ + explicit DigitalOut(std::uint8_t adi_port, bool init_state = LOW); + + /** + * Configures an ADI port on an adi_expander to act as a Digital Output. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param port_pair + * The pair of the smart port number (from 1-22) and the + * ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param init_state + * The initial state for the port + * + * \b Example + * \code + * #define EXT_ADI_SMART_PORT 1 + * #define ADI_PORT 'a' + * + * void opcontrol() { + * bool state = LOW; + * pros::adi::DigitalOut sensor ({EXT_ADI_SMART_PORT , ADI_PORT}); + * while (true) { + * state != state; + * sensor.set_value(state); + * pros::delay(10); // toggle the sensor value every 50ms + * } + * } + * \endcode + */ + explicit DigitalOut(ext_adi_port_pair_t port_pair, bool init_state = LOW); + + /** + * Sets the digital value (1 or 0) of a pin. + * + * Inherited from ADIPort::set_value. + * + * This function uses the following values of errno when an error state is + * reached: + * EADDRINUSE - The port is not configured as a digital output (e.g. the port has been reconfigured) + * + * \param value + * The value to set the ADI port to + * + * \return if the operation was successful or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * bool state = LOW; + * pros::adi::DigitalOut sensor (DIGITAL_SENSOR_PORT); + * while (true) { + * state != state; + * sensor.set_value(state); + * pros::delay(10); // toggle the sensor value every 50ms + * } + * } + * \endcode + */ + using Port::set_value; + + using Port::get_port; + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format(this below is all in one line with no new line): + * DigitalOut [smart_port: digital_out._smart_port, adi_port: digital_out._adi_port, + * value: (value)] + */ + friend std::ostream& operator<<(std::ostream& os, pros::adi::DigitalOut& digital_out); +}; +///@} + +class DigitalIn : private Port { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * Configures an ADI port to act as a Digital Input. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * pros::adi::DigitalIn sensor (ANALOG_SENSOR_PORT); + * // Use the sensor + * } + * \endcode + */ + explicit DigitalIn(std::uint8_t adi_port); + + /** + * Configures an ADI port on an adi_expander to act as a Digital Input. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param port_pair + * The pair of the smart port number (from 1-22) and the + * ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * + * \b Example + * \code + * #define EXT_ADI_SMART_PORT 1 + * #define ADI_PORT 'a' + * + * void opcontrol() { + * pros::adi::DigitalIn sensor ({EXT_ADI_SMART_PORT, ADI_PORT}); + * // Use the sensor + * } + * \endcode + */ + explicit DigitalIn(ext_adi_port_pair_t port_pair); + + /** + * Gets a rising-edge case for a digital button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under + * the same circumstances, so only one task should call this function for any + * given button. E.g., Task A calls this function for buttons 1 and 2. Task B + * may call this function for button 3, but should not for buttons 1 or 2. A + * typical use-case for this function is to call inside opcontrol to detect + * new button presses, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a digital input + * + * \return 1 if the button is pressed and had not been pressed the last time + * this function was called, 0 otherwise. + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * pros::adi::DigitalIn sensor (DIGITAL_SENSOR_PORT); + * while (true) { + * if (sensor.get_new_press()) { + * // Toggle pneumatics or other state operations + * } + * pros::delay(10); + * } + * } + * \endcode + */ + std::int32_t get_new_press() const; + + /** + * Gets the digital value (1 or 0) of a pin. + * + * Inherited from ADIPort::get_value. + * + * This function uses the following values of errno when an error state is reached: + * + * EADDRINUSE - The port is not configured as a digital input (e.g. the port has been reconfigured) + * + * Analogous to adi_digital_read. + * + * \return The value stored for the given port + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * pros::adi::DigitalIn sensor (DIGITAL_SENSOR_PORT); + * while (true) { + * std::cout << "Sensor Value:" << sensor.get_value(); + * pros::delay(10); + * } + * } + * \endcode + */ + using Port::get_value; + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format(this below is all in one line with no new line): + * DigitalIn [smart_port: digital_in._smart_port, adi_port: digital_in._adi_port, + * value: (value)] + */ + friend std::ostream& operator<<(std::ostream& os, pros::adi::DigitalIn& digital_in); + + using Port::get_port; +}; + +///@} + +// Derived Class(es) from DigitalIn +using Button = DigitalIn; + +class Motor : private Port { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * Configures an ADI port to act as a Motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * + * \b Example + * \code + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * pros::adi::Motor motor (MOTOR_PORT); + * motor.set_value(127); // Go full speed forward + * std::cout << "Commanded Motor Power: " << motor.get_value(); // Will display 127 + * delay(1000); + * motor.set_value(0); // Stop the motor + * } + * \endcode + */ + explicit Motor(std::uint8_t adi_port); + + /** + * Configures an ADI port on an adi_expander to act as a Motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param port_pair + * The pair of the smart port number (from 1-22) and the + * ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * + * \b Example + * \code + * #define EXT_ADI_SMART_PORT 1 + * #define ADI_MOTOR_PORT 'a' + * + * void opcontrol() { + * pros::adi::Motor motor ({EXT_ADI_SMART_PORT, ADI_MOTOR_PORT}); + * motor.set_value(127); // Go full speed forward + * std::cout << "Commanded Motor Power: " << motor.get_value(); // Will display 127 + * delay(1000); + * motor.set_value(0); // Stop the motor + * } + * \endcode + */ + explicit Motor(ext_adi_port_pair_t port_pair); + + /** + * Stops the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * pros::adi::Motor motor (MOTOR_PORT); + * motor.set_value(127); // Go full speed forward + * std::cout << "Commanded Motor Power: " << motor.get_value(); // Will display 127 + * delay(1000); + * motor.stop(); // Stop the motor + * } + * \endcode + */ + std::int32_t stop() const; + + /** + * Sets the speed of the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a motor + * + * \param value + * The new signed speed; -127 is full reverse and 127 is full forward, + * with 0 being off + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * pros::adi::Motor motor (MOTOR_PORT); + * motor.set_value(127); // Go full speed forward + * std::cout << "Commanded Motor Power: " << motor.get_value(); // Will display 127 + * delay(1000); + * motor.set_value(0); // Stop the motor + * } + * \endcode + */ + using Port::set_value; + + /** + * Gets the last set speed of the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a motor + * + * \return The last set speed of the motor on the given + * + * \b Example + * \code + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * pros::adi::Motor motor (MOTOR_PORT); + * motor.set_value(127); // Go full speed forward + * std::cout << "Commanded Motor Power: " << motor.get_value(); // Will display 127 + * delay(1000); + * motor.set_value(0); // Stop the motor + * } + * \endcode + */ + using Port::get_value; + + using Port::get_port; +}; + +///@} + +class Encoder : private Port { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * Configures a set of ADI ports to act as an Encoder. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port_top + * The "top" wire from the encoder sensor with the removable cover side up + * \param adi_port_bottom + * The "bottom" wire from the encoder sensor + * \param reverse + * If "true", the sensor will count in the opposite direction + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * pros::adi::Encoder sensor (PORT_TOP, PORT_BOTTOM, false); + * // Use the sensor + * } + * \endcode + */ + explicit Encoder(std::uint8_t adi_port_top, std::uint8_t adi_port_bottom, bool reversed = false); + + /** + * Configures a set of ADI ports on an adi_expander to act as an Encoder. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param port_tuple + * The tuple of the smart port number, the "top" wire from the encoder + * sensor with the removable cover side up, and the "bottom" wire from + * the encoder sensor + * \param reverse + * If "true", the sensor will count in theopposite direction + * + * \b Example + * \code + * #define PORT_TOP 'A' + * #define PORT_BOTTOM 'B' + * #define SMART_PORT 1 + * + * void opcontrol() { + * pros::adi::Encoder sensor ({ SMART_PORT, PORT_TOP, PORT_BOTTOM }, false); + * // Use the sensor + * } + * \endcode + */ + explicit Encoder(ext_adi_port_tuple_t port_tuple, bool reversed = false); + + /** + * Sets the encoder value to zero. + * + * It is safe to use this method while an encoder is enabled. It is not + * necessary to call this method before stopping or starting an encoder. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * pros::adi::Encoder sensor (PORT_TOP, PORT_BOTTOM, false); + * delay(1000); // Move the encoder around in this time + * sensor.reset(); // The encoder is now zero again + * } + * \endcode + */ + std::int32_t reset() const; + + /** + * Gets the number of ticks recorded by the encoder. + * + * There are 360 ticks in one revolution. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a motor + * + * \return The signed and cumulative number of counts since the last start or + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * pros::adi::Encoder sensor (PORT_TOP, PORT_BOTTOM, false); + * while (true) { + * std::cout << "Encoder Value: " << sensor.get_value(); + * pros::delay(10); + * } + * } + * \endcode + */ + std::int32_t get_value() const; + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format(this below is all in one line with no new line): + * Encoder [smart_port: encoder._smart_port, adi_port: encoder._adi_port, + * value: (value)] + */ + friend std::ostream& operator<<(std::ostream& os, pros::adi::Encoder& encoder); + ext_adi_port_tuple_t get_port() const override; + + private: + ext_adi_port_pair_t _port_pair; +}; + +///@} + +class Ultrasonic : private Port { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * Configures a set of ADI ports to act as an Ultrasonic sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param port_ping + * The port connected to the orange OUTPUT cable. This should be in port + * 1, 3, 5, or 7 ('A', 'C', 'E', 'G'). + * \param port_echo + * The port connected to the yellow INPUT cable. This should be in the + * next highest port following port_ping. + * + * \b Example + * \code + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * + * void opcontrol() { + * pros::adi::Ultrasonic sensor (PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * std::cout << "Distance: " << sensor.get_value(); + * pros::delay(10); + * } + * } + * \endcode + */ + explicit Ultrasonic(std::uint8_t adi_port_ping, std::uint8_t adi_port_echo); + + /** + * Configures a set of ADI ports on an adi_expander to act as an Ultrasonic sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param port_tuple + * The tuple of the smart port number, the port connected to the orange + * OUTPUT cable (1, 3, 5, 7 or 'A', 'C', 'E', 'G'), and the port + * connected to the yellow INPUT cable (the next) highest port + * following port_ping). + * + * \b Example + * \code + * #define PORT_PING 'A' + * #define PORT_ECHO 'B' + * #define SMART_PORT 1 + * + * void opcontrol() { + * pros::adi::Ultrasonic sensor ( {{ SMART_PORT, PORT_PING, PORT_ECHO }} ); + * while (true) { + * // Print the distance read by the ultrasonic + * std::cout << "Distance: " << sensor.get_value(); + * pros::delay(10); + * } + * } + * \endcode + */ + explicit Ultrasonic(ext_adi_port_tuple_t port_tuple); + + /** + * Gets the current ultrasonic sensor value in centimeters. + * + * If no object was found, zero is returned. If the ultrasonic sensor was + * never started, the return value is undefined. Round and fluffy objects can + * cause inaccurate values to be returned. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as an ultrasonic + * + * \return The distance to the nearest object in m^-4 (10000 indicates 1 + * meter), measured from the sensor's mounting points. + * + * \b Example + * \code + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * + * void opcontrol() { + * pros::adi::Ultrasonic sensor (PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * std::cout << "Distance: " << sensor.get_value(); + * pros::delay(10); + * } + * } + * \endcode + */ + std::int32_t get_value() const; + + using Port::get_port; +}; + +///@} + +class Gyro : private Port { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * Initializes a gyroscope on the given port. If the given port has not + * previously been configured as a gyro, then this function starts a 1300ms + * calibration period. + * + * It is highly recommended that an Gyro object be created in initialize() + * when the robot is stationary to ensure proper calibration. If an Gyro + * object is declared at the global scope, a hardcoded 1300ms delay at the + * beginning of initialize will be necessary to ensure that the gyro's + * returned values are correct at the beginning of autonomous/opcontrol. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * \param multiplier + * A scalar value that will be multiplied by the gyro heading value + * supplied by the + * + * \b Example + * \code + * #define GYRO_PORT 1 + * + * void opcontrol() { + * pros::adi::Gyro gyro (GYRO_PORT); + * while (true) { + * // Get the gyro heading + * std::cout << "Distance: " << gyro.get_value(); + * pros::delay(10); + * } + * } + * \endcode + */ + explicit Gyro(std::uint8_t adi_port, double multiplier = 1); + + /** + * Initializes a gyroscope on the given port of an adi expander. If the given + * port has not previously been configured as a gyro, then this function starts + * a 1300ms calibration period. + * + * It is highly recommended that an adi::Gyro object be created in initialize() + * when the robot is stationary to ensure proper calibration. If an adi::Gyro + * object is declared at the global scope, a hardcoded 1300ms delay at the + * beginning of initialize will be necessary to ensure that the gyro's + * returned values are correct at the beginning of autonomous/opcontrol. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param port_pair + * The pair of the smart port number (from 1-22) and the + * ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param multiplier + * A scalar value that will be multiplied by the gyro heading value + * supplied by the + * + * \b Example + * \code + * #define ADI_GYRO_PORT 'a' + * #define SMART_PORT 1 + * + * void opcontrol() { + * pros::adi::Gyro gyro ({SMART_PORT ,ADI_GYRO_PORT}); + * while (true) { + * // Get the gyro heading + * std::cout << "Distance: " << gyro.get_value(); + * pros::delay(10); + * } + * } + * \endcode + */ + explicit Gyro(ext_adi_port_pair_t port_pair, double multiplier = 1); + + /** + * Gets the current gyro angle in tenths of a degree. Unless a multiplier is + * applied to the gyro, the return value will be a whole number representing + * the number of degrees of rotation times 10. + * + * There are 360 degrees in a circle, thus the gyro will return 3600 for one + * whole rotation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a gyro + * + * \return The gyro angle in degrees. + * + * \b Example + * \code + * #define GYRO_PORT 1 + * + * void opcontrol() { + * pros::adi::Gyro gyro (GYRO_PORT); + * while (true) { + * // Get the gyro heading + * std::cout << "Distance: " << gyro.get_value(); + * pros::delay(10); + * } + * } + * \endcode + */ + double get_value() const; + + /** + * Resets the gyroscope value to zero. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a gyro + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GYRO_PORT 1 + * + * void opcontrol() { + * pros::adi::Gyro gyro (GYRO_PORT); + * std::uint32_t now = pros::millis(); + * while (true) { + * // Get the gyro heading + * std::cout << "Distance: " << gyro.get_value(); + * + * if (pros::millis() - now > 2000) { + * // Reset the gyro every 2 seconds + * gyro.reset(); + * now = pros::millis(); + * } + * + * pros::delay(10); + * } + * } + * \endcode + */ + std::int32_t reset() const; + + using Port::get_port; +}; + +///@} + +class Potentiometer : public AnalogIn { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * Configures an ADI port to act as a Potentiometer. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param potentiometer_type + * An adi_potentiometer_type_e_t enum value specifying the potentiometer version type + * + * \b Example + * \code + * #define POTENTIOMETER_PORT 1 + * #define POTENTIOMETER_TYPE pros::E_ADI_POT_EDR + * + * void opcontrol() { + * pros::adi::Potentiometer potentiometer (POTENTIOMETER_PORT, POTENTIOMETER_TYPE); + * while (true) { + * // Get the potentiometer angle + * std::cout << "Angle: " << potentiometer.get_angle(); + * pros::delay(10); + * } + * } + * \endcode + */ + explicit Potentiometer(std::uint8_t adi_port, adi_potentiometer_type_e_t potentiometer_type = E_ADI_POT_EDR); + + /** + * Configures an ADI port on an adi_expander to act as a Potentiometer. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The pair of the smart port number (from 1-22) and the + * ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param potentiometer_type + * An adi_potentiometer_type_e_t enum value specifying the potentiometer version type + * + * \b Example + * \code + * #define ADI_POTENTIOMETER_PORT 'a' + * #define SMART_PORT 1 + * + * void opcontrol() { + * pros::adi::Potentiometer potentiometer ({SMART_PORT, ADI_POTENTIOMETER_PORT}); + * while (true) { + * // Get the potentiometer angle + * std::cout << "Angle: " << potentiometer.get_angle(); + * pros::delay(10); + * } + * } + * \endcode + */ + explicit Potentiometer(ext_adi_port_pair_t port_pair, adi_potentiometer_type_e_t potentiometer_type = E_ADI_POT_EDR); + + /** + * Gets the current potentiometer angle in tenths of a degree. + * + * The original potentiometer rotates 250 degrees thus returning an angle between 0-250 degrees. + * Potentiometer V2 rotates 330 degrees thus returning an angle between 0-330 degrees. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \return The potentiometer angle in degrees. + * + * \b Example + * \code + * #define ADI_POTENTIOMETER_PORT 'a' + * #define SMART_PORT 1 + * + * void opcontrol() { + * pros::adi::Potentiometer potentiometer ({{ SMART_PORT , ADI_POTENTIOMETER_PORT }}); + * while (true) { + * // Get the potentiometer angle + * std::cout << "Angle: " << potentiometer.get_angle(); + * pros::delay(10); + * } + * } + * \endcode + */ + double get_angle() const; + + /** + * Gets the 12-bit value of the specified port. + * + * The value returned is undefined if the analog pin has been switched to a + * different mode. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a potentiometer + * + * \return The analog sensor value, where a value of 0 reflects an input + * voltage of nearly 0 V and a value of 4095 reflects an input voltage of + * nearly 5 V + */ + using AnalogIn::get_value; + + /** + * Calibrates the potentiometer on the specified port and returns the new + * calibration value. + * + * This method assumes that the potentiometer value is not actively changing at + * this time and computes an average from approximately 500 samples, 1 ms + * apart, for a 0.5 s period of calibration. The average value thus calculated + * is returned and stored for later calls to the + * pros::adi::Potentiometer::get_value_calibrated() function. This function + * will return the difference between this value and the current sensor value + * when called. + * + * Do not use this function when the potentiometer value might be unstable (rotating the potentiometer) + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a potentiometer + * + * \return The average potentiometer value computed by this function + */ + using AnalogIn::calibrate; + + /** + * Gets the 12 bit calibrated value of a potentiometer port. + * + * The pros::adi::Potentiometer::calibrate() function must be run first. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port is not configured as a potentiometer + * + * \return The difference of the potentiometer value from its calibrated default from + * -4095 to 4095 + */ + using AnalogIn::get_value_calibrated; + + /** + * This is the overload for the << operator for printing to streams + * Potentiometer [value: (value), value calibrated: (calibrated value), + * angle: (angle)] + * Prints in format(this below is all in one line with no new line): + */ + friend std::ostream& operator<<(std::ostream& os, pros::adi::Potentiometer& potentiometer); + + using Port::get_port; +}; + +///@} + +class Led : protected Port { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * @brief Configures an ADI port to act as a LED. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param length + * The number of LEDs in the chain + * + * \b Example: + * \code + * #define LED_PORT 'a' + * #define LED_LENGTH 3 + * + * void opcontrol() { + * pros::Led led (LED_PORT, LED_LENGTH); + * while (true) { + * // Set entire LED strip to red + * led.set_all(0xFF0000); + * pros::delay(20); + * } + * } + * \endcode + * + */ + explicit Led(std::uint8_t adi_port, std::uint32_t length); + + /** + * @brief Configures an ADI port on a adi_expander to act as a LED. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param port_pair + * The pair of the smart port number (from 1-22) and the + * ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param length + * The number of LEDs in the chain + * + * \b Example: + * \code + * #define LED_PORT 'a' + * #define SMART_PORT 1 + * #define LED_LENGTH 3 + * + * void opcontrol() { + * pros::Led led ({SMART_PORT, LED_PORT}, LED_LENGTH); + * while (true) { + * // Set entire LED strip to red + * led.set_all(0xFF0000); + * pros::delay(20); + * } + * } + * \endcode + */ + explicit Led(ext_adi_port_pair_t port_pair, std::uint32_t length); + + /** + * @brief Operator overload to access the buffer in the ADILed class, it is + * recommended that you call .update(); after doing any operations with this. + * + * @param i 0 indexed pixel of the lED + * @return uint32_t& the address of the buffer at i to modify + * + * \b Example: + * \code + * #define LED_PORT 'a' + * #define LED_LENGTH 3 + * + * void opcontrol() { + * pros::Led led (LED_PORT, LED_LENGTH); + * while (true) { + * // Set the first 3 pixels to red, green, and blue + * led.set_pixel(0xFF0000, 0); + * led.set_pixel(0x00FF00, 1); + * led.set_pixel(0x0000FF, 2); + * pros::delay(20); + * + * // Use the [] operator to set the first pixel to black + * led.operator[](0) = 0x000000; + * led.update(); + * pros::delay(20); + * } + * } + */ + std::uint32_t& operator[](size_t i); + + /** + * @brief Clear the entire led strip of color + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A parameter is out of bounds/incorrect + * EADDRINUSE - The port is not configured for ADI output + * + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define LED_PORT 'a' + * #define LED_LENGTH 3 + * + * void opcontrol() { + * pros::Led led (LED_PORT, LED_LENGTH); + * while (true) { + * // Set the first 3 pixels to red, green, and blue + * led.set_pixel(0xFF0000, 0); + * led.set_pixel(0x00FF00, 1); + * led.set_pixel(0x0000FF, 2); + * pros::delay(20); + * + * // Clear the led strip of color + * led.clear(); + * pros::delay(20); + * } + * } + * \endcode + */ + std::int32_t clear_all(); + std::int32_t clear(); + + /** + * @brief Force the LED strip to update with the current buffered values, this + * should be called after any changes to the buffer using the [] operator. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A parameter is out of bounds/incorrect + * EADDRINUSE - The port is not configured for ADI output + * + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define LED_PORT 'a' + * #define LED_LENGTH 3 + * + * void opcontrol() { + * pros::Led led (LED_PORT, LED_LENGTH); + * while (true) { + * // Set the first 3 pixels to red, green, and blue + * led.set_pixel(0xFF0000, 0); + * led.set_pixel(0x00FF00, 1); + * led.set_pixel(0x0000FF, 2); + * pros::delay(20); + * + * // Use the [] operator to set the first pixel to black + * led.operator[](0) = 0x000000; + * // Update the led strip with the new values + * led.update(); + * pros::delay(20); + * } + * } + * \endcode + */ + std::int32_t update() const; + + /** + * @brief Set the entire led strip to one color + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A parameter is out of bounds/incorrect + * EADDRINUSE - The port is not configured for ADI output + * + * @param color color to set all the led strip value to + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define LED_PORT 'a' + * #define LED_LENGTH 3 + * + * void opcontrol() { + * pros::Led led (LED_PORT, LED_LENGTH); + * while (true) { + * // Set the entire led strip to blue + * led.set_all(0x0000FF); + * pros::delay(20); + * } + * } + * \endcode + */ + std::int32_t set_all(uint32_t color); + + /** + * @brief Set one pixel on the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A parameter is out of bounds/incorrect + * EADDRINUSE - The port is not configured for ADI output + * + * @param color color to clear all the led strip to + * @param pixel_position position of the pixel to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define LED_PORT 'a' + * #define LED_LENGTH 3 + * + * void opcontrol() { + * pros::Led led (LED_PORT, LED_LENGTH); + * while (true) { + * // Set the first pixel to blue + * led.set_pixel(0x0000FF, 0); + * pros::delay(20); + * } + * } + * \endcode + */ + std::int32_t set_pixel(uint32_t color, uint32_t pixel_position); + + /** + * @brief Clear one pixel on the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A parameter is out of bounds/incorrect + * EADDRINUSE - The port is not configured for ADI output + * + * @param pixel_position position of the pixel to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define LED_PORT 'a' + * #define LED_LENGTH 3 + * + * void opcontrol() { + * pros::Led led (LED_PORT, LED_LENGTH); + * while (true) { + * // Set the first pixel to blue + * led.set_pixel(0x0000FF, 0); + * pros::delay(20); + * + * // Clear the first pixel + * led.clear_pixel(0); + * pros::delay(20); + * } + * } + * \endcode + */ + std::int32_t clear_pixel(uint32_t pixel_position); + + /** + * @brief Get the length of the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A parameter is out of bounds/incorrect + * EADDRINUSE - The port is not configured for ADI output + * + * @return The length (in pixels) of the LED strip + * + * \b Example: + * \code + * #define LED_PORT 'a' + * #define LED_LENGTH 3 + * + * void opcontrol() { + * pros::Led led (LED_PORT, LED_LENGTH); + * while (true) { + * // Get the length of the led strip + * int length = led.length(); + * pros::lcd::print(1, "Length: %d", length); + * pros::delay(20); + * } + * } + * \endcode + */ + std::int32_t length(); + + using Port::get_port; + + protected: + std::vector _buffer; +}; +///@} + +/// @brief Alias for ADILed +using LED = Led; + +class Pneumatics : public DigitalOut { + /** + * \addtogroup cpp-adi + * @{ + */ + public: + /** + * Creates a Pneumatics object for the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param start_extended + * If true, the pneumatic will start extended when the program starts. + * By default, the piston starts retracted when the program starts. + * \param extended_is_low + * A flag to set whether the the pneumatic is extended when the ADI + * it receives a high or a low value. When true, the extended state + * corresponds to a output low on the ADI port. This allows the user + * to reverse the behavior of the pneumatics if needed. + * + * /b Example: + * \code + * void opcontrol() { + * pros::adi::Pneumatics left_piston('a', false); // Starts retracted, extends when the ADI port is high + * pros::adi::Pneumatics right_piston('b', false, true); // Starts retracted, extends when the ADI port is low + * + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * + * while (true) { + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_L1)) { + * left_piston.extend(); + * } + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_L2)) { + * left_piston.retract(); + * } + * + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_R1)) { + * left_piston.extend(); + * } + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_2)) { + * left_piston.retract(); + * } + * + * pros::delay(10); + * } + * + * \endcode + */ + explicit Pneumatics(std::uint8_t adi_port, bool start_extended, bool extended_is_low = false); + + /** + * Creates a Pneumatics object for the given port pair. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * + * \param port_pair + * The pair of the smart port number (from 1-22) and the + * ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param start_extended + * If true, the pneumatic will start extended when the program starts. + * By default, the piston starts retracted when the program starts. + * \param extended_is_low + * A flag to set whether the the pneumatic is extended when the ADI + * it receives a high or a low value. When true, the extended state + * corresponds to a output low on the ADI port. This allows the user + * to reverse the behavior of the pneumatics if needed. + * + * /b Example: + * \code + * void opcontrol() { + * pros::adi::Pneumatics left_piston({1, 'a'}, false); // Starts retracted, extends when the ADI port is high + * pros::adi::Pneumatics right_piston({1, 'b'}, false, true); // Starts retracted, extends when the ADI port is + *low + * + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * + * while (true) { + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_L1)) { + * left_piston.extend(); + * } + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_L2)) { + * left_piston.retract(); + * } + * + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_R1)) { + * left_piston.extend(); + * } + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_R2)) { + * left_piston.retract(); + * } + * + * pros::delay(10); + * } + * } + * \endcode + */ + explicit Pneumatics(ext_adi_port_pair_t port_pair, bool start_extended, bool extended_is_low = false); + + /** + * Extends the piston, if not already extended. + * + * \return 1 if the piston newly extended, 0 if the piston was already + * extended, or PROS_ERR is the operation failed, setting errno. + * + * \b Example: + * \code + * void opcontrol() { + * pros::adi::Pneumatics piston({1, 'a'}, false); // Starts retracted, extends when the ADI port is high + * + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * + * while (true) { + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_X)) { + * left_piston.extend(); + * } + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_B)) { + * left_piston.retract(); + * } + * if(mastetr.get_digital(pros::E_CONTROLLER_DIGITAL_A)) { + * left_piston.toggle(); + * } + * + * pros::delay(10); + * } + * } + * \endcode + */ + std::int32_t extend(); + + /** + * Retracts the piston, if not already retracted. + * + * \return 1 if the piston newly retracted, 0 if the piston was already + * retracted, or PROS_ERR is the operation failed, setting errno. + * + * \b Example: + * \code + * void opcontrol() { + * pros::adi::Pneumatics piston({1, 'a'}, false); // Starts retracted, extends when the ADI port is high + * + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * + * while (true) { + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_X)) { + * left_piston.extend(); + * } + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_B)) { + * left_piston.retract(); + * } + * if(mastetr.get_digital(pros::E_CONTROLLER_DIGITAL_A)) { + * left_piston.toggle(); + * } + * + * pros::delay(10); + * } + * } + * \endcode + */ + std::int32_t retract(); + + /** + * Puts the piston into the opposite state of its current state. + * If it is retracted, it will extend. If it is extended, it will retract. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \return 1 if the piston successfully toggled, or PROS_ERR if the + * operation failed, setting errno. + * + *\b Example: + * \code + * void opcontrol() { + * pros::adi::Pneumatics piston({1, 'a'}, false); // Starts retracted, extends when the ADI port is high + * + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * + * while (true) { + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_X)) { + * left_piston.extend(); + * } + * if(master.get_digital(pros::E_CONTROLLER_DIGITAL_B)) { + * left_piston.retract(); + * } + * if(mastetr.get_digital(pros::E_CONTROLLER_DIGITAL_A)) { + * left_piston.toggle(); + * } + * + * pros::delay(10); + * } + * } + * \endcode + */ + std::int32_t toggle(); + + /** + * Returns whether the piston is extended or not. + * + * \return true if the piston is extended, false if it is retracted. + * + * \b Example + * \code + * #define ADI_PNEUMATICS_PORT 'a' + * + * void opcontrol() { + * pros::adi::Pneumatics pneumatics (ADI_PNEUMATICS_PORT); + * while (true) { + * // Check if the piston is extended + * if (pneumatics.is_extended()) { + * printf("The pneumatic is extended\n"); + * } + * else { + * printf("The pneumatic is not extended\n"); + * } + * + * pros::delay(10); + * } + * } + * \endcode + */ + bool is_extended() const; + + private: + bool state; // Holds the physical state of the ADI port + bool extended_is_low; // A flag that sets whether extended corresponds to + // a low signal +}; +///@} + +} // namespace adi + +/* +Pros4 upgrade backwards compatibility for ADI api. + +Prints a deprecated warning when user uses old pros::ADIDevice style API. +Remove when and if fully removing old API. +*/ +LEGACY_TYPEDEF(ADIPort, pros::adi::Port); +LEGACY_TYPEDEF(ADIAnalogIn, pros::adi::AnalogIn); +LEGACY_TYPEDEF(ADIAnalogOut, pros::adi::AnalogOut); +LEGACY_TYPEDEF(ADIDigitalIn, pros::adi::DigitalIn); +LEGACY_TYPEDEF(ADIDigitalOut, pros::adi::DigitalOut); +LEGACY_TYPEDEF(ADIMotor, pros::adi::Motor); +LEGACY_TYPEDEF(ADIGyro, pros::adi::Gyro); +LEGACY_TYPEDEF(ADIEncoder, pros::adi::Encoder); +LEGACY_TYPEDEF(ADIUltrasonic, pros::adi::Ultrasonic); +LEGACY_TYPEDEF(LED, pros::adi::Led); + +// Backwards Compatibility for Derived Classes +LEGACY_TYPEDEF(ADIPotentiometer, pros::adi::Potentiometer); +LEGACY_TYPEDEF(ADILineSensor, pros::adi::LineSensor); +LEGACY_TYPEDEF(ADILightSensor, pros::adi::LightSensor); +LEGACY_TYPEDEF(ADIAccelerometer, pros::adi::Accelerometer); +LEGACY_TYPEDEF(ADIButton, pros::adi::Button); +LEGACY_TYPEDEF(ADIPneumatics, pros::adi::Pneumatics); +LEGACY_TYPEDEF(ADILED, pros::adi::Led); +LEGACY_TYPEDEF(ADILed, pros::adi::Led); + +} // namespace pros + +#endif // _PROS_ADI_HPP_ \ No newline at end of file diff --git a/test/include/pros/ai_vision.h b/test/include/pros/ai_vision.h new file mode 100644 index 00000000..5deea418 --- /dev/null +++ b/test/include/pros/ai_vision.h @@ -0,0 +1,502 @@ +/** + * \file pros/aivision.h + * \ingroup c-aivision + * + * Contains prototypes for the VEX AI Vision Sensor-related functions. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-aivision AI Vision Sensor C API + * \note Additional example code for this module can be found in its [Tutorial.](@ref aivision) + */ + +#ifndef _PROS_AIVISION_H_ +#define _PROS_AIVISION_H_ + +/** + * \addtogroup c-aivision + * @{ + */ + +/// \name Macros +/// Parameters given by VEX +///@{ + +#define AIVISION_MAX_OBJECT_COUNT 24 +#define AIVISION_MAX_CLASSNAME_COUNT 20 +#define AIVISION_MODE_TAG_SET_BIT (1 << 29) + +///@} + +///@} + +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \addtogroup c-aivision + * @{ + */ + +/** + * \enum aivision_detected_type_e_t + * This enumeration defines what kind of object is stored inside the union in aivision_object_s + */ +typedef enum aivision_detected_type { + E_AIVISION_DETECTED_COLOR = (1 << 0), + E_AIVISION_DETECTED_CODE = (1 << 1), + E_AIVISION_DETECTED_OBJECT = (1 << 2), + E_AIVISION_DETECTED_TAG = (1 << 3) +} aivision_detected_type_e_t; + +/** + * \enum aivision_mode_type_e_t + * This enumeration defines what kinds of objects the ai vision sensor will scan for: + * tags (april tags), colors (user defined colors), and objects (game elements), and all (all objects) + */ + +typedef enum aivision_mode_type { + E_AIVISION_MODE_TAGS = (1 << 0), + E_AIVISION_MODE_COLORS = (1 << 1), + E_AIVISION_MODE_OBJECTS = (1 << 2), + E_AIVISION_MODE_COLOR_MERGE = (1 << 4), + E_AIVISION_MODE_ALL = (1 << 0) | (1 << 1) | (1 << 2), +} aivision_mode_type_e_t; + +/** + * \struct aivision_color_s_t + * This structure contains the parameters used by the AI Vision Sensor to define a color. hue_range and saturation_range + * are ranges for hue and saturation that are acceptable. + * For example, if a large hue range is specified for a blue color, colors that are more magenta or teal may be detected + * as "blue". + */ +typedef struct aivision_color_s { + uint8_t id; /**< id of color descriptor, can range from 1-7 */ + uint8_t red; /**< red value of color */ + uint8_t green; /**< green value of color */ + uint8_t blue; /**< blue value of color */ + float hue_range; /**< range by which detected color's hue can vary from the base color, can range from 1-40 */ + float saturation_range; /**< range by which detected color's saturation can vary from base color, can range from 0.1-1 */ +} aivision_color_s_t; + +/** + * \struct aivision_code_s_t + * This structure contains the parameters used by the AI Vision sensor to define a code. + * Codes are a combination of color descriptors, and tells the AI Vision sensor to merge objects + * close to each other that belong to the given color descriptors into a single object that matches + * the code descriptor. + * Codes must use at least 2, and no greater than 5, color descriptors. + */ +typedef struct aivision_code_s { + uint8_t id; /**< id of code descriptor, can range from 1-5 */ + uint8_t length; /**< number of color descriptors used by this code. */ + int16_t c1; /**< id of first color descriptor */ + int16_t c2; /**< id of second color descriptor */ + int16_t c3; /**< id of third color descriptor */ + int16_t c4; /**< id of fourth color descriptor */ + int16_t c5; /**< id of fifth color descriptor */ +} aivision_code_s_t; + +/** + * \enum aivision_tag_family_e_t + * This enumeration corresponds to a family of AprilTags. + * \see https://april.eecs.umich.edu/software/apriltag + */ +typedef enum aivision_tag_family_e { + TAG_CIRCLE_21H7 = 0, + TAG_16H5 = 1, + TAG_25H9 = 2, + TAG_61H11 = 3 +} aivision_tag_family_e_t; + +/** + * \struct aivision_object_color_s_t + * This structure contains a detected color. + */ +typedef struct __attribute__((packed)) aivision_object_color_s { + uint16_t xoffset; // left edge (from camera's view) + uint16_t yoffset; // top edge + uint16_t width; + uint16_t height; + uint16_t angle; // angle, in tenths of a degree +} aivision_object_color_s_t; + +/** + * \struct aivision_object_tag_s_t + * This structure contains a detected tag. + */ +typedef struct __attribute__((packed)) aivision_object_tag_s { + int16_t x0; + int16_t y0; + int16_t x1; + int16_t y1; + int16_t x2; + int16_t y2; + int16_t x3; + int16_t y3; +} aivision_object_tag_s_t; + +typedef struct __attribute__((packed)) aivision_object_element_s { + uint16_t xoffset; // left + uint16_t yoffset; // top + uint16_t width; + uint16_t height; + uint16_t score; // confidence that this struct is +} aivision_object_element_s_t; +/** + * \struct aivision_object_s_t + * This structure contains one of aivision_detected_type_e_t, stored in type + * + * If the object is a color, id stores the color's id + * If the object is an April Tag, id stores the tag's id + * If the object is an AI model element, id stores the element id as per + * https://api.vex.com/v5/home/cpp/AiVision/AiObjdesc.html + */ +typedef struct __attribute__((packed)) aivision_object_s { + uint8_t id; // object id + uint8_t type; // object type + union { + aivision_object_color_s_t color; + aivision_object_tag_s_t tag; + aivision_object_element_s_t element; + } object; +} aivision_object_s_t; +/// @} + +#ifdef __cplusplus +namespace c { +#endif + +/** + * \addtogroup c-aivision + * @{ + */ +/// \name Functions + +/** + * Resets the AI Vision sensor to the initial state. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * aivision_reset(AIVISION_PORT); + * } + * \endcode + */ +int32_t aivision_reset(uint8_t port); + +/** + * Returns a bitfield of the types of objects the AI vision sensor is currently searching for, + * as per aivision_mode_type_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \return the bitfield if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * aivision_get_enabled_detection_types(AIVISION_PORT); + * } + * \endcode + */ +int32_t aivision_get_enabled_detection_types(uint8_t port); + +/** + * Modifies the types of objects the AI vision sensor is currently searching for, as per aivision_mode_type_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \b Example + * aivision_set_enabled_detection_types(1, 0b010, 0b101) would disable the detection of tags and objects, + * and leave the setting of colors alone. + * + * \param port The V5 port number from 1-21 + * \param bits the bits to set + * \param bitmask the bitmask to apply + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ +int32_t aivision_set_enabled_detection_types(uint8_t port, uint8_t bits, uint8_t bitmask); + +/** + * Enable detecting these types of objects, a bitmask as per aivision_mode_type_e_t. + * Enabling any given type of object will not disable the detection of other objects. + * This must be done explicitly. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \b Example + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * // start or continue looking for AI model objects + * aivision_enable_detection_types(AIVISION_PORT, aivision_mode_type_e_t::E_AIVISION_MODE_OBJECTS); + * } + * \endcode + * + * \param port The V5 port number from 1-21 + * \param types_mask The types to enable + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ +int32_t aivision_enable_detection_types(uint8_t port, uint8_t types_mask); + +/** + * Disable detecting these types of objects, a bitmask as per aivision_mode_type_e_t. + * Disabling any given type of object will not affect the detection of other objects. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \b Example + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * // stop looking for AI model objects (competition elements, for example) + * aivision_disable_detection_types(AIVISION_PORT, aivision_mode_type_e_t::E_AIVISION_MODE_OBJECTS); + * } + * \endcode + * + * \param port The V5 port number from 1-21 + * \param types_mask The types to enable + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ +int32_t aivision_disable_detection_types(uint8_t port, uint8_t types_mask); + +/** + * Sets the april tag family to detect. Use this function will override the enabled apriltag + * detection family. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \param family the tag family to configure the AI Vision sensor to detect + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ +int32_t aivision_set_tag_family_override(uint8_t port, aivision_tag_family_e_t family); + +/** + * Sets the april tag family to detect. Use this function will allow multiple apriltags + * to be detected. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \param family the tag family to configure the AI Vision sensor to detect + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ +int32_t aivision_set_tag_family(uint8_t port, aivision_tag_family_e_t family); + +/** + * Set a color configuration that the AI vision sensor will detect. + * The color detection type must be separately enabled. + * If a color with the same ID already is stored in the sensor, it will be overwritten. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \param color the color to configure the AI Vision sensor to detect + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ +int32_t aivision_set_color(uint8_t port, const aivision_color_s_t* color); + +/** + * Get a color configuration that the AI vision sensor has stored. + * If you attempt to get a color configuration that has not been previously used, the + * behavior is not defined. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \param id the id of color from 1-7 + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ +aivision_color_s_t aivision_get_color(uint8_t port, uint32_t id); + +/** + * Get a class name that the AI vision sensor has stored. + * The AI Vision sensor may not correctly report classnames for the first several hundred milliseconds + * of being plugged in. + * By passing in -1 for the id, the function will return the number of class names the AI vision sensor reports. + * For other values of id, the function return value is undefined + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \param id the id of the class name from 0-(AIVISION_MAX_CLASSNAME_COUNT - 1) + * \param class_name a string of length >=20 to store the classname. + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ +int32_t aivision_get_class_name(uint8_t port, int32_t id, uint8_t* class_name); + +/** + * Enable or disable the bounding box overlay the AI Vision sensor outputs on the USB port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \param enabled if the overlay is enabled or disabled + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ +int32_t aivision_set_usb_bounding_box_overlay(uint8_t port, bool enabled); + +/** + * Runs auto white balance to adjust to different lighting conditions. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ +int32_t aivision_start_awb(uint8_t port); + +/** + * Get a code that the AI vision sensor has stored. + * + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \param id The id from 1-5 + * \return the code, or a struct with an invalid ID if the operation failed, setting errno + */ +aivision_code_s_t aivision_get_code(uint8_t port, uint32_t id); + +/** + * Set a code that the AI vision sensor will detect for. + * The id of the code is stored in the aivision_code_s_t struct. If there is already a code + * stored in the AI vision sensor with the id, this function will overwrite. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \param code The code to set + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ +int32_t aivision_set_code(uint8_t port, const aivision_code_s_t* wcode); + +/** + * Get the current number of objects detected by the AI vision sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \return the number of objects if the operation was successful or PROS_ERR if the operation failed, setting errno + */ +int32_t aivision_get_object_count(uint8_t port); + +/** + * Get the detected object at a given object index; there are aivision_get_object_count objects and the index starts + * from 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * @param port The V5 port number from 1-21 + * @param object_index the object index + * @return the detected object if the operation was successful or an invalid object type if the operation failed, + * setting errno + */ +aivision_object_s_t aivision_get_object(uint8_t port, uint32_t object_index); + +/** + * Get the current reported temperature of the AI Vision sensor in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port The V5 port number from 1-21 + * \return the temperature if the operation was successful or PROS_ERR_F if the operation failed, setting errno + */ +double aivision_get_temperature(uint8_t port); + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_VISION_H_ \ No newline at end of file diff --git a/test/include/pros/ai_vision.hpp b/test/include/pros/ai_vision.hpp new file mode 100644 index 00000000..30863d55 --- /dev/null +++ b/test/include/pros/ai_vision.hpp @@ -0,0 +1,600 @@ +/** + * \file pros/aivision.hpp + * \ingroup cpp-aivision + * + * Contains prototypes for the VEX AI Vision Sensor-related functions in C++. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-aivision AI Vision Sensor C++ API + * \note Additional example code for this module can be found in its [Tutorial.](@ref aivision) + */ + +#ifndef _PROS_AIVISION_HPP_ +#define _PROS_AIVISION_HPP_ + +#include +#include +#include + +#include "pros/ai_vision.h" +#include "pros/device.hpp" + +namespace pros { +inline namespace v5 { + +/** + * \enum AivisionDetectType + * \ingroup cpp-aivision + * Enum class for describing detection type of objects detected by the AI Vision Sensor. + */ +enum class AivisionDetectType : uint8_t { + color = (1 << 0), /**< object was detected based on color descriptor */ + code = (1 << 1), /**< object was detected based on code descriptor */ + object = (1 << 2), /**< object was detected using AI model */ + tag = (1 << 3) /**< object was detected as an AprilTag */ +}; + +/** + * \enum AivisionModeType + * \ingroup cpp-aivision + * Enum class for enabling/disabling detection types of AI Vision Sensor. + */ +enum class AivisionModeType : uint8_t { + tags = (1 << 0), /**< AprilTag detection */ + colors = (1 << 1), /**< color and code detection */ + objects = (1 << 2), /**< AI model object detection */ + color_merge = (1 << 4), /**< merge adjacent color detections */ + all = (1 << 0) | (1 << 1) | (1 << 2), +}; + +/** + * \enum AivisionTagFamily + * \ingroup cpp-aivision + * Enum class for describing family of apriltags to detect. + */ +enum class AivisionTagFamily { tag_21H7 = 0, tag_16H5 = 1, tag_25H9 = 2, tag_61H11 = 3 }; + +/** + * \ingroup cpp-aivision + */ +class AIVision : public Device { + /** + * \addtogroup cpp-aivision + * @{ + */ + public: + + using Color = aivision_color_s_t; + using Code = aivision_code_s_t; + using Object = aivision_object_s_t; + + /** + * Create a AI Vision Sensor object on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an AI vision sensor + * + * \param port + * The V5 port number from 1-21 + * + * \b Example + * \code + * void opcontrol() { + * pros::AIVision ai_sensor(2); // Creates a vision sensor on port two + * } + * \endcode + */ + explicit AIVision(const std::uint8_t port); + + AIVision(const Device& device) : AIVision(device.get_port()){}; + + /** + * Gets all vision sensors. + * + * \return A vector of AIVision sensor objects. + * + * \b Example + * \code + * void opcontrol() { + * std::vector aivision_all = pros::AIVision::get_all_devices(); // All AI vision sensors that are + * connected + * } + * \endcode + */ + static std::vector get_all_devices(); + + /** + * Check if the dected type is the same as the given type. + * + * \return true if the type is the same, false otherwise + * + * \b Example + * \code + * void opcontrol() { + * pros::AIVision aivision(1); + * pros::AIVision::Object object = aivision.get_object(0); + * if (AIVision::is_type(AivisionDetectType::color, object)) { + * printf("is color\n"); + * } else if (AIVision::is_type(AivisionDetectType::object, object)) { + * printf("is object\n"); + * } else if (AIVision::is_type(AivisionDetectType::code, object)) { + * printf("is code\n"); + * } else if (AIVision::is_type(AivisionDetectType::tag, object)) { + * printf("is tag\n"); + * } else { + * printf("unknown\n"); + * } + * } + * \endcode + */ + static bool is_type(const Object& object, AivisionDetectType type); + + /** + * Resets the AI Vision sensor to the initial state. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + + * + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * pros::AIVision aivision(AIVISION_PORT); + * aivision.reset(); + * } + * \endcode + */ + int32_t reset(); + + /** + * Returns a bitfield of the types of objects the AI vision sensor is currently searching for, + * as per AivisionModeType. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + + * \return the bitfield if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * pros::AIVision aivision(AIVISION_PORT); + * int32_t enabled_types = aivision.get_enabled_detection_types(); + * printf("is tag: %d\n", enabled_types | AivisionModeType::tags); + * } + * \endcode + */ + int32_t get_enabled_detection_types(); + + /** + * Enable detecting these types of objects, a bitmask as per aivision_mode_type_e_t. + * Enabling any given type of object will not disable the detection of other objects. + * This must be done explicitly. + * + * For this function you must use bitwise or to combine the types you want to enable. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \b Example + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * pros::AIVision aivision(AIVISION_PORT); + * // start or continue looking for AI model objects + * // enable aivision to look for tags and objects + * aivision.enable_detection_types(AivisionModeType::tags | AivisionModeType::objects); + * } + * \endcode + * + * \param types_mask The types to enable + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + int32_t enable_detection_types(AivisionModeType types_mask); + + /** + * Enable detecting these types of objects, a bitmask as per aivision_mode_type_e_t. + * Enabling any given type of object will not disable the detection of other objects. + * This must be done explicitly. + * + * For this function you can use comma separated values to combine the types you want to enable. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \b Example + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * pros::AIVision aivision(AIVISION_PORT); + * // start or continue looking for AI model objects + * // enable aivision to look for tags and objects + * aivision.enable_detection_types(AivisionModeType::tags, AivisionModeType::objects); + * } + * \endcode + * + * \param types_mask The types to enable + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + template + requires((std::conjunction_v...>)) + int32_t enable_detection_types(Flags... flags) { + auto types_mask = (static_cast(flags) | ...); + return c::aivision_enable_detection_types(this->_port, static_cast(types_mask)); + } + + /** + * Disable detecting these types of objects, a bitmask as per aivision_mode_type_e_t. + * Disabling any given type of object will not affect the detection of other objects. + * + * For this function you must use bitwise or to combine the types you want to disable. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \b Example + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * pros::AIVision aivision(AIVISION_PORT); + * // stop looking for AI model objects (competition elements, for example) + * // disable aivision to look for tags and objects + * aivision.disable_detection_types(AivisionModeType::tags | AivisionModeType::objects); + * } + * \endcode + * + * \param types_mask The types to enable + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + int32_t disable_detection_types(AivisionModeType types_mask); + + /** + * Disable detecting these types of objects, a bitmask as per aivision_mode_type_e_t. + * Disabling any given type of object will not affect the detection of other objects. + * + * For this function you can use comma separated values to combine the types you want to disable. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \b Example + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * pros::AIVision aivision(AIVISION_PORT); + * // stop looking for AI model objects (competition elements, for example) + * // disable aivision to look for tags and objects + * aivision.disable_detection_types(AivisionModeType::tags | AivisionModeType::objects); + * } + * \endcode + * + * \param types_mask The types to enable + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + template + requires((std::conjunction_v...>)) + int32_t disable_detection_types(Flags... flags) { + auto types_mask = (static_cast(flags) | ...); + return c::aivision_disable_detection_types(this->_port, static_cast(types_mask)); + } + + /** + * Sets the april tag family to detect. + * If override is true, the AI vision sensor will only look for the given family. + * Otherwise, it will add the given tag to the list of enabled tags. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \code + * #define AIVISION_PORT 1 + * void initialize() { + * pros::AIVision aivision(AIVISION_PORT); + * // set the only tag family to look for to 21H7 + * aivision.set_tag_family(AivisionTagFamily::tag_21H7); + * // add 16H5 to the list of enabled tag families + * aivision.set_tag_family(AivisionTagFamily::tag_16H5); + * // set the only tag family to look for to 25H9 + * aivision.set_tag_family(AivisionTagFamily::tag_25H9, true); + * } + * \endcode + * + * \param family the tag family to configure the AI Vision sensor to detect + * \param override if true, the given family will be set as the only enabled tag family. + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + int32_t set_tag_family(AivisionTagFamily family, bool override = false); + + /** + * Set a color configuration that the AI vision sensor will detect. + * The color detection type must be separately enabled. + * If a color with the same ID already is stored in the sensor, it will be overwritten. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \code + * #define AIVISION_PORT 1 + * void opcontrol() { + * pros::AIVision aivision(AIVISION_PORT); + * AIVision::Color color = {1, 207, 19, 25, 10.00, 0.20}; + * aivision.set_color(color); + * } + * \endcode + * + * \param color the color to configure the AI Vision sensor to detect + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ + int32_t set_color(const Color& color); + + /** + * Get a color configuration that the AI vision sensor has stored. + * If you attempt to get a color configuration that has not been previously used, the + * behavior is not defined. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * + * #define AIVISION_PORT 1 + * void opcontrol() { + * pros::AIVision aivision(AIVISION_PORT); + * AIVision::Code color = aivision.get_color(0); + * printf("id: %d, red: %d, green: %d, blue: %d, hue_range: %f, saturation_range: %f\n", + * color.id, color.red, color.green, color.blue, color.hue_range, color.saturation_range); + * } + * + * \param id the id of color from 1-7 + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ + AIVision::Color get_color(uint32_t id); + + /** + * Set a code that the AI vision sensor will detect for. + * The id of the code is stored in the aivision_code_s_t struct. If there is already a code + * stored in the AI vision sensor with the id, this function will overwrite. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \code + * + * #define AIVISION_PORT 1 + * void opcontrol() { + * pros::AIVision aivision(AIVISION_PORT); + * AIVision::Code code = {1, 207, 19, 25, 10.00, 0.20}; + * aivision.set_code(code); + * } + * + * \endcode + * + * \param code The code to set + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ + uint32_t set_code(const Code& code); + + /** + * Get a code that the AI vision sensor has stored. + * + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \code + * + * #define AIVISION_PORT 1 + * void opcontrol() { + * pros::AIVision aivision(AIVISION_PORT); + * AIVision::Code code = aivision.get_code(0); + * printf("id: %d, length: %d, c1: %d, c2: %d, c3: %d, c4: %d, c5: %d\n", + * code.id, code.length, code.c1, code.c2, code.c3, code.c4, code.c5); + * ) + * } + * + * \endcode + * + * \param id The id from 1-5 + * \return the code, or a struct with an invalid ID if the operation failed, setting errno + */ + AIVision::Code get_code(uint32_t id); + + /** + * Runs auto white balance to adjust to different lighting conditions. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ + int32_t start_awb(); + + /** + * Get a class name that the AI vision sensor has stored. + * The AI Vision sensor may not correctly report classnames for the first several hundred milliseconds + * of being plugged in. + * By passing in -1 for the id, the function will return the number of class names the AI vision sensor reports. + * For other values of id, the function return value is undefined + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * \code + * #define AIVISION_PORT 1 + * void opcontrol() { + * pros::AIVision aivision(AIVISION_PORT); + * char* class_name = new char[21]; + * aivision.get_class_name(0, class_name); + * printf("%s\n", class_name); + * delete[] class_name; + * } + * + * \endcode + * + * \param id the id of the class name from 0-(AIVISION_MAX_CLASSNAME_COUNT - 1) + * \param class_name a string of length >=20 to store the classname. + * \return PROS_SUCCESS if the operation was successful or PROS_ERR if the operation + * failed, setting errno + */ + int32_t get_class_name(int32_t id, char* class_name); + + /** + * Get a class name that the AI vision sensor has stored. + * The AI Vision sensor may not correctly report classnames for the first several hundred milliseconds + * of being plugged in. + * By passing in -1 for the id, the function will return the number of class names the AI vision sensor reports. + * For other values of id, the function return value is undefined + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * \code + * #define AIVISION_PORT 1 + * void opcontrol() { + * pros::AIVision aivision(AIVISION_PORT); + * auto name = aivision.get_class_name(1); + * + * if(name.has_value()) { + * printf("Class name: %s\n", name.value().c_str()); + * } else { + * printf("Error: %ld\n", errno); + * } + * } + * + * \endcode + * + * \param id the id of the class name from 0-(AIVISION_MAX_CLASSNAME_COUNT - 1) + * \return the class name string in std::optional if the operation was successful + * or an empty optional if the operation failed, setting errno + */ + std::optional get_class_name(int32_t id); + + /** + * Get the current number of objects detected by the AI vision sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \code + * #define AIVISION_PORT 1 + * void opcontrol() { + * pros::AIVision aivision(AIVISION_PORT); + * int32_t object_count = aivision.get_object_count(); + * printf("%d\n", object_count); + * } + * \endcode + * + * \return the number of objects if the operation was successful or PROS_ERR if the operation failed, setting errno + */ + int32_t get_object_count(); + + /** + * Get the detected object at a given object index; there are aivision_get_object_count objects and the index starts + * from 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \code + * #define AIVISION_PORT 1 + * void opcontrol() { + * pros::AIVision aivision(AIVISION_PORT); + * int32_t object_count = aivision.get_object_count(); + * for (int i = 0; i < object_count; i++) { + * pros::AIVision::Object object = aivision.get_object(i); + * printf("Object %d: %d\n", i, object.type); + * } + * } + * + * \endcode + * + * @param object_index the object index + * @return the detected object if the operation was successful or an invalid object type if the operation failed, + * setting errno + */ + Object get_object(uint32_t object_index); + + /** + * Get all detected objects in a vector. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \code + * #define AIVISION_PORT 1 + * void opcontrol() { + * pros::AIVision aivision(AIVISION_PORT); + * auto objects = aivision.get_all_objects(); + * for (const auto& object : objects) { + * printf("Object %d: %d\n", object.id, object.type); + * } + * } + * \endcode + * + * @return a vector of all detected objects + */ + std::vector get_all_objects(); + /// @} +}; +} // namespace v5 +} // namespace pros +#endif // _PROS_VISION_HPP_ diff --git a/test/include/pros/apix.h b/test/include/pros/apix.h new file mode 100644 index 00000000..dc6c5b00 --- /dev/null +++ b/test/include/pros/apix.h @@ -0,0 +1,901 @@ +/** + * \file pros/apix.h + * \ingroup apix + * + * PROS Extended API header + * + * Contains additional declarations for use by advaned users of PROS. These + * functions do not typically have as much error handling or require deeper + * knowledge of real time operating systems. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup apix Extended API + * \note Also included in the Extended API is [LVGL.](https://lvgl.io/) + */ + +#ifndef _PROS_API_EXTENDED_H_ +#define _PROS_API_EXTENDED_H_ + +#include "api.h" +#include "pros/device.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wall" +#pragma GCC diagnostic pop +#include "pros/serial.h" + +#ifdef __cplusplus +#include "pros/serial.hpp" +namespace pros::c { +extern "C" { +#endif + +/** + * \ingroup apix + */ + +/** + * \addtogroup apix + * @{ + */ + +/// \name RTOS Facilities +///@{ + +typedef void* queue_t; +typedef void* sem_t; + +/** + * Unblocks a task in the Blocked state (e.g. waiting for a delay, on a + * semaphore, etc.). + * + * \param task + * The task to unblock + * + * \return True if the task was unblocked, false otherwise + * + * \b Example: + * \code + * task_t task = task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * task_delay(1000); + * // in another task somewhere else, this will abort the task_delay bove: + * task_abort_delay(task); + * \endcode + */ +bool task_abort_delay(task_t task); + +/** + * Notify a task when a target task is being deleted. + * + * \param target_task + * The task being watched for deletion + * \param task_to_notify + * The task to notify when target_task is deleted + * \param value + * The value to supply to task_notify_ext + * \param notify_action + * The action to supply to task_notify_ext + * + * \b Example: + * \code + * task_t task_to_delete = task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * task_t task_to_notify = task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn2"); + * + * task_notify_ext(task_to_notify, 0, NOTIFY_ACTION_INCREMENT, NULL); + * + * task_notify_when_deleting(task_to_delete, task_get_current(), 0, NOTIFY_ACTION_NONE); + * task_delete(task_to_delete); + * \endcode + */ +void task_notify_when_deleting(task_t target_task, task_t task_to_notify, uint32_t value, + notify_action_e_t notify_action); + +/** + * Returns a handle to the current owner of a mutex. + * + * \param mutex + * A mutex handle + * + * \return A handle to the current task that owns the mutex, or NULL if the + * mutex isn't owned. + * + * \b Example: + * \code + * mutex_t mutex = mutex_create(); + * + * void task_fn(void* param) { + * while(1) { + * mutex_take(mutex, 1000); + * // critical section + * mutex_give(mutex); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * void opcontrol(void) { +* while (1) { +* if (joystick_get_digital(1, 7, JOY_UP)) { +* task_t owner = mutex_get_owner(mutex); +* if (owner != NULL) { +* printf("Mutex is owned by task %s", task_get_name(owner)); +* } else { +* printf("Mutex is not owned"); +* } +* } +* task_delay(20); +* } +* } + * \endcode + */ +task_t mutex_get_owner(mutex_t mutex); + +/** + * Creates a counting sempahore. + * + * \param max_count + * The maximum count value that can be reached. + * \param init_count + * The initial count value assigned to the new semaphore. + * + * \return A newly created semaphore. If an error occurred, NULL will be + * returned and errno can be checked for hints as to why sem_create failed. + * + * \b Example: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_create(1, 0); + * + * void task_fn(void* param) { + * while(1) { + * sem_take(sem, 1000); + * // critical section + * sem_give(sem); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +sem_t sem_create(uint32_t max_count, uint32_t init_count); + +/** + * Deletes a semaphore (or binary semaphore) + * + * \param sem + * Semaphore to delete + * + * \b Example: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_create(1, 0); + * + * void task_fn(void* param) { + * while(1) { + * sem_take(sem, 1000); + * // critical section + * sem_give(sem); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * void opcontrol(void) { + * while (1) { + * if (joystick_get_digital(1, 7, JOY_UP)) { + * // honestly this is a bad example because you should never + * // delete a semaphore like this + * sem_delete(sem); + * } + * task_delay(20); + * } + * } + * + * \endcode + */ +void sem_delete(sem_t sem); + +/** + * Creates a binary semaphore. + * + * \return A newly created semaphore. + * + * \b Example: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_binary_create(); + * + * void task_fn(void* param) { + * while(1) { + * sem_take(sem, 1000); + * // critical section + * sem_give(sem); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +sem_t sem_binary_create(void); + +/** + * Waits for the semaphore's value to be greater than 0. If the value is already + * greater than 0, this function immediately returns. + * + * \param sem + * Semaphore to wait on + * \param timeout + * Time to wait before the semaphore's becomes available. A timeout of 0 + * can be used to poll the sempahore. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the semaphore was successfully take, false otherwise. If + * false is returned, then errno is set with a hint about why the sempahore + * couldn't be taken. + * + * \b Example: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_create(1, 0); + * + * void task_fn(void* param) { + * while(1) { + * if(!sem_wait(sem, 1000)) { + * printf("Failed to take semaphore"); + * task_delay(1000); + * continue; + * } + * // critical section + * sem_give(sem); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * void opcontrol(void) { + * while (1) { + * if (sem_wait(sem, 0))) { + * printf("Semaphore is available"); + * } + * task_delay(20); + * } + * } + * \endcode + */ +bool sem_wait(sem_t sem, uint32_t timeout); + +/** + * Increments a semaphore's value. + * + * \param sem + * Semaphore to post + * + * \return True if the value was incremented, false otherwise. If false is + * returned, then errno is set with a hint about why the semaphore couldn't be + * taken. + * + * \b Example: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_create(1, 0); + * + * void task_fn(void* param) { + * while(1) { + * sem_post(sem); // increments, mimicking to "claim" + * // critical section + * sem_give(sem); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +bool sem_post(sem_t sem); + +/** + * Returns the current value of the semaphore. + * + * \param sem + * A semaphore handle + * + * \return The current value of the semaphore (e.g. the number of resources + * available) + * + * \b Example of sem_get_count: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_create(1, 0); + * printf("semaphore count: %d", sem_get_count(sem)); + * // semaphore count: 0 + * sem_take(sem, 1000); + * printf("semaphore count: %d", sem_get_count(sem)); + * // semaphore count: 1 + * sem_give(sem); + * printf("semaphore count: %d", sem_get_count(sem)); + * // semaphore count: 0 + * + * \endcode + */ +uint32_t sem_get_count(sem_t sem); + +/** + * Creates a queue. + * + * \param length + * The maximum number of items that the queue can contain. + * \param item_size + * The number of bytes each item in the queue will require. + * + * \return A handle to a newly created queue, or NULL if the queue cannot be + * created. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * printf("queue length: %d", queue_get_length(queue)); + * } + * \endcode + */ +queue_t queue_create(uint32_t length, uint32_t item_size); + +/** + * Posts an item to the front of a queue. The item is queued by copy, not by + * reference. + * + * \param queue + * The queue handle + * \param item + * A pointer to the item that will be placed on the queue. + * \param timeout + * Time to wait for space to become available. A timeout of 0 can be used + * to attempt to post without blocking. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the item was preprended, false otherwise. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * printf("queue length: %d", queue_get_length(queue)); + * } + */ +bool queue_prepend(queue_t queue, const void* item, uint32_t timeout); + +/** + * Posts an item to the end of a queue. The item is queued by copy, not by + * reference. + * + * \param queue + * The queue handle + * \param item + * A pointer to the item that will be placed on the queue. + * \param timeout + * Time to wait for space to become available. A timeout of 0 can be used + * to attempt to post without blocking. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the item was preprended, false otherwise. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * printf("queue length: %d", queue_get_length(queue)); + * } + * \endcode + */ +bool queue_append(queue_t queue, const void* item, uint32_t timeout); + +/** + * Receive an item from a queue without removing the item from the queue. + * + * \param queue + * The queue handle + * \param buffer + * Pointer to a buffer to which the received item will be copied + * \param timeout + * The maximum amount of time the task should block waiting for an item to receive should the queue be empty at + * the time of the call. TIMEOUT_MAX can be used to block indefinitely. + * + * \return True if an item was copied into the buffer, false otherwise. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * char* item = "Hello! this is a test"; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * char* recv = malloc(sizeof("Hello! this is a test")); + * queue_peek(queue, recv, 1000); + * printf("Queue: %s", recv); + * free(recv); + * } + * \endcode + */ +bool queue_peek(queue_t queue, void* const buffer, uint32_t timeout); + +/** + * Receive an item from the queue. + * + * \param queue + * The queue handle + * \param buffer + * Pointer to a buffer to which the received item will be copied + * \param timeout + * The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. queue_recv() will return immediately if timeout + * is zero and the queue is empty. + * + * \return True if an item was copied into the buffer, false otherwise. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * char* item = "Hello! this is a test"; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * char* recv = malloc(sizeof("Hello! this is a test")); + * queue_recv(queue, recv, 1000); + * printf("Queue: %s", recv); + * free(recv); + * } + * \endcode + */ +bool queue_recv(queue_t queue, void* const buffer, uint32_t timeout); + +/** + * Return the number of messages stored in a queue. + * + * \param queue + * The queue handle. + * + * \return The number of messages available in the queue. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * printf("queue waiting: %d", queue_get_waiting(queue)); + * } + * \endcode + */ +uint32_t queue_get_waiting(const queue_t queue); + +/** + * Return the number of spaces left in a queue. + * + * \param queue + * The queue handle. + * + * \return The number of spaces available in the queue. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * printf("queue available: %d", queue_get_available(queue)); + * } + * \endcode + */ +uint32_t queue_get_available(const queue_t queue); + +/** + * Delete a queue. + * + * \param queue + * Queue handle to delete + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * queue_delete(queue); + * } + * \endcode + */ +void queue_delete(queue_t queue); + +/** + * Resets a queue to an empty state + * + * \param queue + * Queue handle to reset + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * queue_reset(queue); + * } + * \endcode + */ +void queue_reset(queue_t queue); + +///@} + +/// \name Device Registration +///@{ + +/** + * Registers a device in the given zero-indexed port + * + * Registers a device of the given type in the given port into the registry, if + * that type of device is detected to be plugged in to that port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (0-20), or a + * a different device than specified is plugged in. + * EADDRINUSE - The port is already registered to another device. + * + * \param port + * The port number to register the device + * \param device + * The type of device to register + * + * \return 1 upon success, PROS_ERR upon failure + * + * \b Example: + * \code + * void opcontrol(void) { + * registry_bind_port(1, E_DEVICE_MOTOR); + * } + * \endcode + */ +int registry_bind_port(uint8_t port, v5_device_e_t device_type); + +/** + * Deregisters a devices from the given zero-indexed port + * + * Removes the device registed in the given port, if there is one. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (0-20). + * + * \param port + * The port number to deregister + * + * \return 1 upon success, PROS_ERR upon failure + * + * \b Example: + * \code + * void opcontrol(void) { + * registry_bind_port(1, E_DEVICE_MOTOR); + * registry_unbind_port(1); + * } + * \endcode + */ +int registry_unbind_port(uint8_t port); + +/** + * Returns the type of device registered to the zero-indexed port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (0-20). + * + * \param port + * The V5 port number from 0-20 + * + * \return The type of device that is registered into the port (NOT what is + * plugged in) + * + * \b Example: + * \code + * void opcontrol(void) { + * registry_bind_port(1, E_DEVICE_MOTOR); + * printf("port 1 is registered to a motor: %d", registry_get_bound_type(1) == E_DEVICE_MOTOR); + * } + * \endcode + */ +v5_device_e_t registry_get_bound_type(uint8_t port); + +/** + * Returns the type of the device plugged into the zero-indexed port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (0-20). + * + * \param port + * The V5 port number from 0-20 + * + * \return The type of device that is plugged into the port (NOT what is + * registered) + * + * \b Example: + * \code + * void opcontrol(void) { + * registry_bind_port(1, E_DEVICE_MOTOR); + * printf("port 1 is registered to a motor: %d", registry_get_plugged_type(1) == E_DEVICE_MOTOR); + * } + * \endcode + */ +v5_device_e_t registry_get_plugged_type(uint8_t port); + +///@} + +/// \name Startup options +///@{ + +/** + * Enable/disable the PROS banner printed to the serial stream. + * + * \warning This function must be called BEFORE the PROS daemon starts. + * The easiest way to acheive this is to NOT call this function directly, + * and instead use the BANNER_ENABLE macro. + * + * \param enable + * Whether the banner should be enabled or disabled. + */ +void enable_banner(bool enabled); + +/** + * This priority value, when used with __attribute__((constructor( ))), is + * guaranteed to run before PROS initializes. + */ +#define PRE_PROS_INIT_PRIORITY 101 + +/** + * Enable/disable the PROS banner printed to the serial stream. + * + * \warning This macro must be used in global scope, outside of any function. + * + * \param enable + * Whether the banner should be enabled or disabled. + */ +#ifdef __cplusplus +#define ENABLE_BANNER(enabled) static_assert(!__builtin_strcmp(__FUNCTION__, "top level"), \ + "Cannot use ENABLE_BANNER inside a function!"); \ + __attribute__((constructor(PRE_PROS_INIT_PRIORITY))) static void _enable_banner_impl() \ + { pros::c::enable_banner(enabled); } +#else +#define ENABLE_BANNER(enabled) static_assert(!__builtin_strcmp(__FUNCTION__, "top level"), \ + "Cannot use ENABLE_BANNER inside a function!"); \ + __attribute__((constructor(PRE_PROS_INIT_PRIORITY))) static void _enable_banner_impl() \ + { enable_banner(enabled); } +#endif +///@} + +/// \name Filesystem +///@{ + +/** + * Control settings of the serial driver. + * + * \param action + * An action to perform on the serial driver. See the SERCTL_* macros for + * details on the different actions. + * \param extra_arg + * An argument to pass in based on the action + * + * \b Example: + * \code + * void opcontrol(void) { + * serctl(SERCTL_SET_BAUDRATE, (void*) 9600); + * } + */ +int32_t serctl(const uint32_t action, void* const extra_arg); + +/* + * Control settings of the microSD card driver. + * + * \param action + * An action to perform on the microSD card driver. See the USDCTL_* macros + * for details on the different actions. + * \param extra_arg + * An argument to pass in based on the action + */ +// Not yet implemented +// int32_t usdctl(const uint32_t action, void* const extra_arg); + +/** + * Control settings of the way the file's driver treats the file + * + * \param file + * A valid file descriptor number + * \param action + * An action to perform on the file's driver. See the *CTL_* macros for + * details on the different actions. Note that the action passed in must + * match the correct driver (e.g. don't perform a SERCTL_* action on a + * microSD card file) + * \param extra_arg + * An argument to pass in based on the action + * + * \b Example: + * \code + * void opcontrol(void) { + * int32_t fd = open("serial", O_RDWR); + * fdctl(fd, SERCTL_SET_BAUDRATE, (void*) 9600); + * } + * \endcode + */ +int32_t fdctl(int file, const uint32_t action, void* const extra_arg); + +/** + * Sets the reverse flag for the motor. + * + * This will invert its movements and the values returned for its position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * \param reverse + * True reverses the motor, false is default + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_set_reversed(1, true); + * printf("Is this motor reversed? %d\n", motor_is_reversed(1)); + * } + * \endcode + */ +int32_t motor_set_reversed(int8_t port, const bool reverse); + +/** + * Gets the operation direction of the motor as set by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * + * \return 1 if the motor has been reversed and 0 if the motor was not reversed, + * or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * printf("Is the motor reversed? %d\n", motor_is_reversed(1)); + * // Prints "Is the motor reversed? 0" + * } + * \endcode + */ +int32_t motor_is_reversed(int8_t port); + +/** + * Action macro to pass into serctl or fdctl that activates the stream + * identifier. + * + * When used with serctl, the extra argument must be the little endian + * representation of the stream identifier (e.g. "sout" -> 0x74756f73) + * + */ +#define SERCTL_ACTIVATE 10 + +/** + * Action macro to pass into serctl or fdctl that deactivates the stream + * identifier. + * + * When used with serctl, the extra argument must be the little endian + * representation of the stream identifier (e.g. "sout" -> 0x74756f73) + * + */ +#define SERCTL_DEACTIVATE 11 + +/** + * Action macro to pass into fdctl that enables blocking writes for the file + * + * The extra argument is not used with this action, provide any value (e.g. + * NULL) instead + * + */ +#define SERCTL_BLKWRITE 12 + +/** + * Action macro to pass into fdctl that makes writes non-blocking for the file + * + * The extra argument is not used with this action, provide any value (e.g. + * NULL) instead + * + */ +#define SERCTL_NOBLKWRITE 13 + +/** + * Action macro to pass into serctl that enables advanced stream multiplexing + * capabilities + * + * The extra argument is not used with this action, provide any value (e.g. + * NULL) instead + * + */ +#define SERCTL_ENABLE_COBS 14 + +/** + * Action macro to pass into serctl that disables advanced stream multiplexing + * capabilities + * + * The extra argument is not used with this action, provide any value (e.g. + * NULL) instead + * + */ +#define SERCTL_DISABLE_COBS 15 + +/** + * Action macro to check if there is data available from the Generic Serial + * Device + * + */ +#define DEVCTL_FIONREAD 16 + +/** + * Action macro to check if there is space available in the Generic Serial + * Device's output buffer + * + */ +#define DEVCTL_FIONWRITE 18 + +/** + * Action macro to set the Generic Serial Device's baudrate. + * + * The extra argument is the baudrate. + */ +#define DEVCTL_SET_BAUDRATE 17 + +///@} + +///@} + +#ifdef __cplusplus +} +} +#endif + +#endif // _PROS_API_EXTENDED_H_ diff --git a/test/include/pros/colors.h b/test/include/pros/colors.h new file mode 100644 index 00000000..431d9d85 --- /dev/null +++ b/test/include/pros/colors.h @@ -0,0 +1,204 @@ +/** + * \file pros/colors.h + * + * Contains macro definitions of colors (as `uint32_t`) + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License v. 2.0. If a copy of the MPL was not distributed with this + * file You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-colors Colors C API + */ + +/** + * \ingroup c-colors + * \note These functions can be used for dynamic device instantiation. + */ + +/** + * \addtogroup c-colors + * @{ + */ + +#ifndef _PROS_COLORS_H_ +#define _PROS_COLORS_H_ + +#define RGB2COLOR(R, G, B) ((R & 0xff) << 16 | (G & 0xff) << 8 | (B & 0xff)) +#define COLOR2R(COLOR) ((COLOR >> 16) & 0xff) +#define COLOR2G(COLOR) ((COLOR >> 8) & 0xff) +#define COLOR2B(COLOR) (COLOR & 0xff) + +#ifdef __cplusplus +namespace pros { +namespace c { +#endif + +/** + * \enum color_e_t + * @brief + * Enum of possible colors + * + * Contains common colors, all members are self descriptive. + */ +typedef enum color_e { + COLOR_ALICE_BLUE = 0x00F0F8FF, + COLOR_ANTIQUE_WHITE = 0x00FAEBD7, + COLOR_AQUA = 0x0000FFFF, + COLOR_AQUAMARINE = 0x007FFFD4, + COLOR_AZURE = 0x00F0FFFF, + COLOR_BEIGE = 0x00F5F5DC, + COLOR_BISQUE = 0x00FFE4C4, + COLOR_BLACK = 0x00000000, + COLOR_BLANCHED_ALMOND = 0x00FFEBCD, + COLOR_BLUE = 0x000000FF, + COLOR_BLUE_VIOLET = 0x008A2BE2, + COLOR_BROWN = 0x00A52A2A, + COLOR_BURLY_WOOD = 0x00DEB887, + COLOR_CADET_BLUE = 0x005F9EA0, + COLOR_CHARTREUSE = 0x007FFF00, + COLOR_CHOCOLATE = 0x00D2691E, + COLOR_CORAL = 0x00FF7F50, + COLOR_CORNFLOWER_BLUE = 0x006495ED, + COLOR_CORNSILK = 0x00FFF8DC, + COLOR_CRIMSON = 0x00DC143C, + COLOR_CYAN = 0x0000FFFF, + COLOR_DARK_BLUE = 0x0000008B, + COLOR_DARK_CYAN = 0x00008B8B, + COLOR_DARK_GOLDENROD = 0x00B8860B, + COLOR_DARK_GRAY = 0x00A9A9A9, + COLOR_DARK_GREY = COLOR_DARK_GRAY, + COLOR_DARK_GREEN = 0x00006400, + COLOR_DARK_KHAKI = 0x00BDB76B, + COLOR_DARK_MAGENTA = 0x008B008B, + COLOR_DARK_OLIVE_GREEN = 0x00556B2F, + COLOR_DARK_ORANGE = 0x00FF8C00, + COLOR_DARK_ORCHID = 0x009932CC, + COLOR_DARK_RED = 0x008B0000, + COLOR_DARK_SALMON = 0x00E9967A, + COLOR_DARK_SEA_GREEN = 0x008FBC8F, + COLOR_DARK_SLATE_GRAY = 0x002F4F4F, + COLOR_DARK_SLATE_GREY = COLOR_DARK_SLATE_GRAY, + COLOR_DARK_TURQUOISE = 0x0000CED1, + COLOR_DARK_VIOLET = 0x009400D3, + COLOR_DEEP_PINK = 0x00FF1493, + COLOR_DEEP_SKY_BLUE = 0x0000BFFF, + COLOR_DIM_GRAY = 0x00696969, + COLOR_DIM_GREY = COLOR_DIM_GRAY, + COLOR_DODGER_BLUE = 0x001E90FF, + COLOR_FIRE_BRICK = 0x00B22222, + COLOR_FLORAL_WHITE = 0x00FFFAF0, + COLOR_FOREST_GREEN = 0x00228B22, + COLOR_FUCHSIA = 0x00FF00FF, + COLOR_GAINSBORO = 0x00DCDCDC, + COLOR_GHOST_WHITE = 0x00F8F8FF, + COLOR_GOLD = 0x00FFD700, + COLOR_GOLDENROD = 0x00DAA520, + COLOR_GRAY = 0x00808080, + COLOR_GREY = COLOR_GRAY, + COLOR_GREEN = 0x00008000, + COLOR_GREEN_YELLOW = 0x00ADFF2F, + COLOR_HONEYDEW = 0x00F0FFF0, + COLOR_HOT_PINK = 0x00FF69B4, + COLOR_INDIAN_RED = 0x00CD5C5C, + COLOR_INDIGO = 0x004B0082, + COLOR_IVORY = 0x00FFFFF0, + COLOR_KHAKI = 0x00F0E68C, + COLOR_LAVENDER = 0x00E6E6FA, + COLOR_LAVENDER_BLUSH = 0x00FFF0F5, + COLOR_LAWN_GREEN = 0x007CFC00, + COLOR_LEMON_CHIFFON = 0x00FFFACD, + COLOR_LIGHT_BLUE = 0x00ADD8E6, + COLOR_LIGHT_CORAL = 0x00F08080, + COLOR_LIGHT_CYAN = 0x00E0FFFF, + COLOR_LIGHT_GOLDENROD_YELLOW = 0x00FAFAD2, + COLOR_LIGHT_GREEN = 0x0090EE90, + COLOR_LIGHT_GRAY = 0x00D3D3D3, + COLOR_LIGHT_GREY = COLOR_LIGHT_GRAY, + COLOR_LIGHT_PINK = 0x00FFB6C1, + COLOR_LIGHT_SALMON = 0x00FFA07A, + COLOR_LIGHT_SEA_GREEN = 0x0020B2AA, + COLOR_LIGHT_SKY_BLUE = 0x0087CEFA, + COLOR_LIGHT_SLATE_GRAY = 0x00778899, + COLOR_LIGHT_SLATE_GREY = COLOR_LIGHT_SLATE_GRAY, + COLOR_LIGHT_STEEL_BLUE = 0x00B0C4DE, + COLOR_LIGHT_YELLOW = 0x00FFFFE0, + COLOR_LIME = 0x0000FF00, + COLOR_LIME_GREEN = 0x0032CD32, + COLOR_LINEN = 0x00FAF0E6, + COLOR_MAGENTA = 0x00FF00FF, + COLOR_MAROON = 0x00800000, + COLOR_MEDIUM_AQUAMARINE = 0x0066CDAA, + COLOR_MEDIUM_BLUE = 0x000000CD, + COLOR_MEDIUM_ORCHID = 0x00BA55D3, + COLOR_MEDIUM_PURPLE = 0x009370DB, + COLOR_MEDIUM_SEA_GREEN = 0x003CB371, + COLOR_MEDIUM_SLATE_BLUE = 0x007B68EE, + COLOR_MEDIUM_SPRING_GREEN = 0x0000FA9A, + COLOR_MEDIUM_TURQUOISE = 0x0048D1CC, + COLOR_MEDIUM_VIOLET_RED = 0x00C71585, + COLOR_MIDNIGHT_BLUE = 0x00191970, + COLOR_MINT_CREAM = 0x00F5FFFA, + COLOR_MISTY_ROSE = 0x00FFE4E1, + COLOR_MOCCASIN = 0x00FFE4B5, + COLOR_NAVAJO_WHITE = 0x00FFDEAD, + COLOR_NAVY = 0x00000080, + COLOR_OLD_LACE = 0x00FDF5E6, + COLOR_OLIVE = 0x00808000, + COLOR_OLIVE_DRAB = 0x006B8E23, + COLOR_ORANGE = 0x00FFA500, + COLOR_ORANGE_RED = 0x00FF4500, + COLOR_ORCHID = 0x00DA70D6, + COLOR_PALE_GOLDENROD = 0x00EEE8AA, + COLOR_PALE_GREEN = 0x0098FB98, + COLOR_PALE_TURQUOISE = 0x00AFEEEE, + COLOR_PALE_VIOLET_RED = 0x00DB7093, + COLOR_PAPAY_WHIP = 0x00FFEFD5, + COLOR_PEACH_PUFF = 0x00FFDAB9, + COLOR_PERU = 0x00CD853F, + COLOR_PINK = 0x00FFC0CB, + COLOR_PLUM = 0x00DDA0DD, + COLOR_POWDER_BLUE = 0x00B0E0E6, + COLOR_PURPLE = 0x00800080, + COLOR_RED = 0x00FF0000, + COLOR_ROSY_BROWN = 0x00BC8F8F, + COLOR_ROYAL_BLUE = 0x004169E1, + COLOR_SADDLE_BROWN = 0x008B4513, + COLOR_SALMON = 0x00FA8072, + COLOR_SANDY_BROWN = 0x00F4A460, + COLOR_SEA_GREEN = 0x002E8B57, + COLOR_SEASHELL = 0x00FFF5EE, + COLOR_SIENNA = 0x00A0522D, + COLOR_SILVER = 0x00C0C0C0, + COLOR_SKY_BLUE = 0x0087CEEB, + COLOR_SLATE_BLUE = 0x006A5ACD, + COLOR_SLATE_GRAY = 0x00708090, + COLOR_SLATE_GREY = COLOR_SLATE_GRAY, + COLOR_SNOW = 0x00FFFAFA, + COLOR_SPRING_GREEN = 0x0000FF7F, + COLOR_STEEL_BLUE = 0x004682B4, + COLOR_TAN = 0x00D2B48C, + COLOR_TEAL = 0x00008080, + COLOR_THISTLE = 0x00D8BFD8, + COLOR_TOMATO = 0x00FF6347, + COLOR_TURQUOISE = 0x0040E0D0, + COLOR_VIOLET = 0x00EE82EE, + COLOR_WHEAT = 0x00F5DEB3, + COLOR_WHITE = 0x00FFFFFF, + COLOR_WHITE_SMOKE = 0x00F5F5F5, + COLOR_YELLOW = 0x00FFFF00, + COLOR_YELLOW_GREEN = 0x009ACD32, +} color_e_t; + + ///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +#endif + +#endif // _PROS_COLORS_H_ diff --git a/test/include/pros/colors.hpp b/test/include/pros/colors.hpp new file mode 100644 index 00000000..c19ec6e6 --- /dev/null +++ b/test/include/pros/colors.hpp @@ -0,0 +1,190 @@ +/** + * \file pros/colors.hpp + * + * Contains enum class definitions of colors + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License v. 2.0. If a copy of the MPL was not distributed with this + * file You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-colors C++ Color API + */ +#ifndef _PROS_COLORS_HPP_ +#define _PROS_COLORS_HPP_ + + +namespace pros{ +/** + * \ingroup cpp-colors + */ + +/** + * \addtogroup cpp-colors + * @{ + */ + +/** + * \enum Color + * @brief + * Enum class of possible colors + * + * Contains common colors, all members are self descriptive. + */ +enum class Color { + alice_blue = 0x00F0F8FF, + antique_white = 0x00FAEBD7, + aqua = 0x0000FFFF, + aquamarine = 0x007FFFD4, + azure = 0x00F0FFFF, + beige = 0x00F5F5DC, + bisque = 0x00FFE4C4, + black = 0x00000000, + blanched_almond = 0x00FFEBCD, + blue = 0x000000FF, + blue_violet = 0x008A2BE2, + brown = 0x00A52A2A, + burly_wood = 0x00DEB887, + cadet_blue = 0x005F9EA0, + chartreuse = 0x007FFF00, + chocolate = 0x00D2691E, + coral = 0x00FF7F50, + cornflower_blue = 0x006495ED, + cornsilk = 0x00FFF8DC, + crimson = 0x00DC143C, + cyan = 0x0000FFFF, + dark_blue = 0x0000008B, + dark_cyan = 0x00008B8B, + dark_goldenrod = 0x00B8860B, + dark_gray = 0x00A9A9A9, + dark_grey = dark_gray, + dark_green = 0x00006400, + dark_khaki = 0x00BDB76B, + dark_magenta = 0x008B008B, + dark_olive_green = 0x00556B2F, + dark_orange = 0x00FF8C00, + dark_orchid = 0x009932CC, + dark_red = 0x008B0000, + dark_salmon = 0x00E9967A, + dark_sea_green = 0x008FBC8F, + dark_slate_gray = 0x002F4F4F, + dark_slate_grey = dark_slate_gray, + dark_turquoise = 0x0000CED1, + dark_violet = 0x009400D3, + deep_pink = 0x00FF1493, + deep_sky_blue = 0x0000BFFF, + dim_gray = 0x00696969, + dim_grey = dim_gray, + dodger_blue = 0x001E90FF, + fire_brick = 0x00B22222, + floral_white = 0x00FFFAF0, + forest_green = 0x00228B22, + fuchsia = 0x00FF00FF, + gainsboro = 0x00DCDCDC, + ghost_white = 0x00F8F8FF, + gold = 0x00FFD700, + goldenrod = 0x00DAA520, + gray = 0x00808080, + grey = gray, + green = 0x00008000, + green_yellow = 0x00ADFF2F, + honeydew = 0x00F0FFF0, + hot_pink = 0x00FF69B4, + indian_red = 0x00CD5C5C, + indigo = 0x004B0082, + ivory = 0x00FFFFF0, + khaki = 0x00F0E68C, + lavender = 0x00E6E6FA, + lavender_blush = 0x00FFF0F5, + lawn_green = 0x007CFC00, + lemon_chiffon = 0x00FFFACD, + light_blue = 0x00ADD8E6, + light_coral = 0x00F08080, + light_cyan = 0x00E0FFFF, + light_goldenrod_yellow = 0x00FAFAD2, + light_green = 0x0090EE90, + light_gray = 0x00D3D3D3, + light_grey = light_gray, + light_pink = 0x00FFB6C1, + light_salmon = 0x00FFA07A, + light_sea_green = 0x0020B2AA, + light_sky_blue = 0x0087CEFA, + light_slate_gray = 0x00778899, + light_slate_grey = light_slate_gray, + light_steel_blue = 0x00B0C4DE, + light_yellow = 0x00FFFFE0, + lime = 0x0000FF00, + lime_green = 0x0032CD32, + linen = 0x00FAF0E6, + magenta = 0x00FF00FF, + maroon = 0x00800000, + medium_aquamarine = 0x0066CDAA, + medium_blue = 0x000000CD, + medium_orchid = 0x00BA55D3, + medium_purple = 0x009370DB, + medium_sea_green = 0x003CB371, + medium_slate_blue = 0x007B68EE, + medium_spring_green = 0x0000FA9A, + medium_turquoise = 0x0048D1CC, + medium_violet_red = 0x00C71585, + midnight_blue = 0x00191970, + mint_cream = 0x00F5FFFA, + misty_rose = 0x00FFE4E1, + moccasin = 0x00FFE4B5, + navajo_white = 0x00FFDEAD, + navy = 0x00000080, + old_lace = 0x00FDF5E6, + olive = 0x00808000, + olive_drab = 0x006B8E23, + orange = 0x00FFA500, + orange_red = 0x00FF4500, + orchid = 0x00DA70D6, + pale_goldenrod = 0x00EEE8AA, + pale_green = 0x0098FB98, + pale_turquoise = 0x00AFEEEE, + pale_violet_red = 0x00DB7093, + papay_whip = 0x00FFEFD5, + peach_puff = 0x00FFDAB9, + peru = 0x00CD853F, + pink = 0x00FFC0CB, + plum = 0x00DDA0DD, + powder_blue = 0x00B0E0E6, + purple = 0x00800080, + red = 0x00FF0000, + rosy_brown = 0x00BC8F8F, + royal_blue = 0x004169E1, + saddle_brown = 0x008B4513, + salmon = 0x00FA8072, + sandy_brown = 0x00F4A460, + sea_green = 0x002E8B57, + seashell = 0x00FFF5EE, + sienna = 0x00A0522D, + silver = 0x00C0C0C0, + sky_blue = 0x0087CEEB, + slate_blue = 0x006A5ACD, + slate_gray = 0x00708090, + slate_grey = slate_gray, + snow = 0x00FFFAFA, + spring_green = 0x0000FF7F, + steel_blue = 0x004682B4, + tan = 0x00D2B48C, + teal = 0x00008080, + thistle = 0x00D8BFD8, + tomato = 0x00FF6347, + turquoise = 0x0040E0D0, + violet = 0x00EE82EE, + wheat = 0x00F5DEB3, + white = 0x00FFFFFF, + white_smoke = 0x00F5F5F5, + yellow = 0x00FFFF00, + yellow_green = 0x009ACD32, +}; +} // namespace pros + + ///@} + +#endif //_PROS_COLORS_HPP_ diff --git a/test/include/pros/device.h b/test/include/pros/device.h new file mode 100644 index 00000000..c6fb5bfb --- /dev/null +++ b/test/include/pros/device.h @@ -0,0 +1,92 @@ +/** + * \file pros/device.h + * + * Contains functions for interacting with VEX devices. + * + * + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-device VEX Generic Device C API (For Advanced Users) + */ + +#ifndef _PROS_DEVICE_H_ +#define _PROS_DEVICE_H_ + +#include + +#ifdef __cplusplus +namespace pros::c { +extern "C" { +#endif + +/** + * \ingroup c-device + * \note These functions can be used for dynamic device instantiation. + */ + +/** + * \addtogroup c-device + * @{ + */ + +/** + * \enum v5_device_e + * \brief + * List of possible v5 devices + * + * This list contains all current V5 Devices, and mirrors V5_DeviceType from the + * api. + */ +typedef enum v5_device_e { + E_DEVICE_NONE = 0, ///< No device is plugged into the port + E_DEVICE_MOTOR = 2, ///< A motor is plugged into the port + E_DEVICE_ROTATION = 4, ///< A rotation sensor is plugged into the port + E_DEVICE_IMU = 6, ///< An inertial sensor is plugged into the port + E_DEVICE_DISTANCE = 7, ///< A distance sensor is plugged into the port + E_DEVICE_RADIO = 8, ///< A radio is plugged into the port + E_DEVICE_VISION = 11, ///< A vision sensor is plugged into the port + E_DEVICE_ADI = 12, ///< This port is an ADI expander + E_DEVICE_OPTICAL = 16, ///< An optical sensor is plugged into the port + E_DEVICE_GPS = 20, ///< A GPS sensor is plugged into the port + E_DEVICE_AIVISION = 29, ///< An AI Vision sensor is plugged into the port + E_DEVICE_SERIAL = 129, ///< A serial device is plugged into the port + E_DEVICE_GENERIC __attribute__((deprecated("use E_DEVICE_SERIAL instead"))) = E_DEVICE_SERIAL, + E_DEVICE_UNDEFINED = 255 ///< The device type is not defined, or is not a valid device +} v5_device_e_t; + +/** + * Gets the type of device on given port. + * + * \return The device type as an enum. + * + * \b Example + * \code + * #define DEVICE_PORT 1 + * + * void opcontrol() { + * while (true) { + * v5_device_e_t pt = get_plugged_type(DEVICE_PORT); + * printf("device plugged type: {plugged type: %d}\n", pt); + * delay(20); + * } + * } + * \endcode +*/ +v5_device_e_t get_plugged_type(uint8_t port); + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +#endif + +#endif // _PROS_DEVICE_H_ diff --git a/test/include/pros/device.hpp b/test/include/pros/device.hpp new file mode 100644 index 00000000..560e03fd --- /dev/null +++ b/test/include/pros/device.hpp @@ -0,0 +1,206 @@ +/** + * \file pros/device.hpp + * + * Base class for all smart devices. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-device VEX Generic Device C++ API (For Advanced Users) + */ + +#ifndef _PROS_DEVICE_HPP_ +#define _PROS_DEVICE_HPP_ + +#include "pros/misc.hpp" +#include "pros/rtos.hpp" + +namespace pros { +inline namespace v5 { +/** + * \ingroup cpp-device + * \note These functions can be used for dynamic device instantiation. + */ + +/** + * \addtogroup cpp-device + * @{ + */ + +/** + * \enum DeviceType + * \brief + * Enum of possible v5 devices. + * + * Contains all current V5 Devices. + */ +enum class DeviceType { + none = 0, ///< No device is plugged into the port + motor = 2, ///< A motor is plugged into the port + rotation = 4, ///< A rotation sensor is plugged into the port + imu = 6, ///< An inertial sensor is plugged into the port + distance = 7, ///< A distance sensor is plugged into the port + radio = 8, ///< A radio is plugged into the port + vision = 11, ///< A vision sensor is plugged into the port + adi = 12, ///< This port is an ADI expander + optical = 16, ///< An optical sensor is plugged into the port + gps = 20, ///< A GPS sensor is plugged into the port + aivision = 29, ///< An AI vision sensor is plugged into the port + serial = 129, ///< A serial device is plugged into the port + undefined = 255 ///< The device type is not defined, or is not a valid device +}; + +class Device { + public: + /** + * Creates a Device object. + * + * \param port The V5 port number from 1-21 + * + * \b Example + * \code + * #define DEVICE_PORT 1 + * + * void opcontrol() { + * Device device(DEVICE_PORT); + * } + * \endcode + */ + explicit Device(const std::uint8_t port); + + /** + * Gets the port number of the Smart Device. + * + * \return The smart device's port number. + * + * \b Example + * \code + * void opcontrol() { + * #define DEVICE_PORT 1 + * while (true) { + * Device device(DEVICE_PORT); + * printf("device plugged type: {port: %d}\n", device.get_port()); + * delay(20); + * } + * } + * \endcode + */ + std::uint8_t get_port(void) const; + + /** + * Checks if the device is installed. + * + * \return true if the corresponding device is installed, false otherwise. + * \b Example + * + * \code + * #define DEVICE_PORT 1 + * + * void opcontrol() { + * Device device(DEVICE_PORT); + * while (true) { + * printf("device plugged type: {is_installed: %d}\n", device.is_installed()); + * delay(20); + * } + * } + * \endcode + */ + virtual bool is_installed(); + + /** + * Gets the type of device. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Mutex of port cannot be taken (access denied). + * + * \return The device type as an enum. + * + * \b Example + * \code + * #define DEVICE_PORT 1 + * + * void opcontrol() { + Device device(DEVICE_PORT); + * while (true) { + * DeviceType dt = device.get_plugged_type(); + * printf("device plugged type: {plugged type: %d}\n", dt); + * delay(20); + * } + * } + * \endcode + */ + pros::DeviceType get_plugged_type() const; + + + /** + * Gets the type of device on a given port. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Mutex of port cannot be taken (access denied). + * + * \param port The V5 port number from 1-21 + * + * \return The device type as an enum. + * + * \b Example + * \code + * #define DEVICE_PORT 1 + * + * void opcontrol() { + * while (true) { + * DeviceType dt = pros::Device::get_plugged_type(DEVICE_PORT); + * printf("device plugged type: {plugged type: %d}\n", dt); + * delay(20); + * } + * } + * \endcode + */ + static pros::DeviceType get_plugged_type(std::uint8_t port); + + /** + * Gets all devices of a given device type. + * + * \param device_type The pros::DeviceType enum that matches the type of device desired. + * + * \return A vector of Device objects for the given device type. + * + * \b Example + * \code + * void opcontrol() { + * std::vector motor_devices = pros::Device::get_all_devices(pros::DeviceType::motor); // All Device objects are motors + * } + * \endcode + */ + + static std::vector get_all_devices(pros::DeviceType device_type = pros::DeviceType::undefined); + + protected: + /** + * Creates a Device object. + * + * \param port The V5 port number from 1-21 + * + * \param deviceType The type of the constructed device + */ + Device(const std::uint8_t port, const enum DeviceType deviceType) : + _port(port), + _deviceType(deviceType) {} + + protected: + const std::uint8_t _port; + const enum DeviceType _deviceType = pros::DeviceType::none; + + ///@} +}; +} // namespace v5 +} // namespace pros + +#endif diff --git a/test/include/pros/distance.h b/test/include/pros/distance.h new file mode 100644 index 00000000..e64f0d90 --- /dev/null +++ b/test/include/pros/distance.h @@ -0,0 +1,160 @@ +/** + * \file pros/distance.h + * \ingroup c-distance + * + * Contains prototypes for functions related to the VEX Distance sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-distance VEX Distance Sensor C API + */ + +#ifndef _PROS_DISTANCE_H_ +#define _PROS_DISTANCE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \ingroup c-distance + */ + +/** + * \addtogroup c-distance + * @{ + */ + +/** + * Get the currently measured distance from the sensor in mm + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \param port The V5 Distance Sensor port number from 1-21 + * \return The distance value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Distance Value: %d mm\n", distance_get(DISTANCE_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t distance_get(uint8_t port); + +/** + * Get the confidence in the distance reading + * + * This is a value that has a range of 0 to 63. 63 means high confidence, + * lower values imply less confidence. Confidence is only available + * when distance is > 200mm (the value 10 is returned in this scenario). + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \param port The V5 Distance Sensor port number from 1-21 + * \return The confidence value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Distance Confidence Value: %d\n", distance_get_confidence(DISTANCE_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t distance_get_confidence(uint8_t port); + +/** + * Get the current guess at relative object size + * + * This is a value that has a range of 0 to 400. + * A 18" x 30" grey card will return a value of approximately 75 + * in typical room lighting. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \param port The V5 Distance Sensor port number from 1-21 + * \return The size value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Distance Object Size: %d\n", distance_get_object_size(DISTANCE_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t distance_get_object_size(uint8_t port); + +/** + * Get the object velocity in m/s + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \param port The V5 Distance Sensor port number from 1-21 + * \return The velocity value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Distance Object Velocity: %f\n", distance_get_object_velocity(DISTANCE_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double distance_get_object_velocity(uint8_t port); + +///@} + +#ifdef __cplusplus +} +} +} +#endif + +#endif diff --git a/test/include/pros/distance.hpp b/test/include/pros/distance.hpp new file mode 100644 index 00000000..3e110b44 --- /dev/null +++ b/test/include/pros/distance.hpp @@ -0,0 +1,247 @@ +/** + * \file pros/distance.hpp + * \ingroup cpp-distance + * + * Contains prototypes for the V5 Distance Sensor-related functions. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-distance VEX Distance Sensor C++ API + */ + +#ifndef _PROS_DISTANCE_HPP_ +#define _PROS_DISTANCE_HPP_ + +#include +#include + +#include "pros/device.hpp" +#include "pros/distance.h" + +namespace pros { +inline namespace v5 { +/** + * \ingroup cpp-distance + */ +class Distance : public Device { + /** + * \addtogroup cpp-distance + * @{ + */ + public: + /** + * Creates a Distance Sensor object for the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a Distance Sensor + * + * \param port + * The V5 port number from 1-21 + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + * Distance distance(DISTANCE_PORT); + * } + * \endcode + */ + Distance(const std::uint8_t port); + + Distance(const Device& device) : Distance(device.get_port()){}; + /** + * Get the currently measured distance from the sensor in mm + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \return The distance value or PROS_ERR if the operation failed, setting + * errno. Will return 9999 if the sensor can not detect an object. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + Distance distance(DISTANCE_PORT); + * while (true) { + * printf("Distance: %d\n", distance.get()); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t get(); + + /** + * Get the currently measured distance from the sensor in mm. + * \note This function is identical to get(). + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \return The distance value or PROS_ERR if the operation failed, setting + * errno. Will return 9999 if the sensor can not detect an object. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + Distance distance(DISTANCE_PORT); + * while (true) { + * printf("Distance: %d\n", distance.get_distance()); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t get_distance(); + + /** + * Gets all distance sensors. + * + * \return A vector of Distance sensor objects. + * + * \b Example + * \code + * void opcontrol() { + * std::vector distance_all = pros::Distance::get_all_devices(); // All distance sensors that are + * connected + * } + * \endcode + */ + static std::vector get_all_devices(); + + /** + * Get the confidence in the distance reading + * + * This is a value that has a range of 0 to 63. 63 means high confidence, + * lower values imply less confidence. Confidence is only available + * when distance is > 200mm. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \return The confidence value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + Distance distance(DISTANCE_PORT); + * while (true) { + * printf("Distance confidence: %d\n", distance.get_confidence()); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t get_confidence(); + + /** + * Get the current guess at relative object size + * + * This is a value that has a range of 0 to 400. + * A 18" x 30" grey card will return a value of approximately 75 + * in typical room lighting. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \return The size value or PROS_ERR if the operation failed, setting + * errno. Will return -1 if the sensor is not able to determine object size. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + Distance distance(DISTANCE_PORT); + * while (true) { + * printf("Distance object size: %d\n", distance.get_object_size()); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t get_object_size(); + + /** + * Get the object velocity in m/s + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \return The velocity value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * + * void opcontrol() { + * Distance distance(DISTANCE_PORT); + * while (true) { + * printf("Distance object velocity: %f\n", distance.get_object_velocity()); + * delay(20); + * } + * } + * \endcode + */ + virtual double get_object_velocity(); + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format(this below is all in one line with no new line): + * Distance [port: (port number), distance: (distance), confidence: (confidence), + * object size: (object size), object velocity: (object velocity)] + */ + friend std::ostream& operator<<(std::ostream& os, pros::Distance& distance); + + private: + ///@} +}; + +namespace literals { +/** + * Constructs a Distance sensor object from a literal ending in _dist via calling the constructor + * + * \return a pros::Distance for the corresponding port + * + * \b Example + * \code + * using namespace pros::literals; + * void opcontrol() { + * pros::Distance dist = 2_dist; //Makes an dist object on port 2 + * } + * \endcode + */ +const pros::Distance operator""_dist(const unsigned long long int d); +} // namespace literals +} // namespace v5 +} // namespace pros + +#endif diff --git a/test/include/pros/error.h b/test/include/pros/error.h new file mode 100644 index 00000000..e1d03b6b --- /dev/null +++ b/test/include/pros/error.h @@ -0,0 +1,42 @@ +/** + * \file pros/error.h + * + * Contains macro definitions for return types, mostly errors + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright Copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#ifndef _PROS_ERROR_H_ +#define _PROS_ERROR_H_ + +#include "limits.h" + +// Different Byte Size Errors + +/// @brief +/// Return This on Byte Sized Return Error +#define PROS_ERR_BYTE (INT8_MAX) + +/// @brief +/// Return This on 2 Byte Sized Return Error +#define PROS_ERR_2_BYTE (INT16_MAX) + +/// @brief +/// Return This on 4 Byte Sized Return Error +#define PROS_ERR (INT32_MAX) + +/// @brief +/// Return This on 8 Byte Sized Return Error +#define PROS_ERR_F (INFINITY) + +/// @brief +/// Return This on Success (1) +#define PROS_SUCCESS (1) + +#endif diff --git a/test/include/pros/ext_adi.h b/test/include/pros/ext_adi.h new file mode 100644 index 00000000..18fde003 --- /dev/null +++ b/test/include/pros/ext_adi.h @@ -0,0 +1,1330 @@ +/** + * \file pros/ext_adi.h + * \ingroup ext-adi + * + * Contains prototypes for interfacing with the 3-Wire Expander. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup ext-adi ADI Expander C API + * \note The internal ADI API can be found [here.](@ref c-adi) + */ + +#ifndef _PROS_EXT_ADI_H_ +#define _PROS_EXT_ADI_H_ + +#include +#include + +#include "adi.h" +#include "pros/adi.h" +#ifndef PROS_ERR +#define PROS_ERR (INT32_MAX) +#endif + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +#ifdef __cplusplus +namespace c { +#endif + +/** + * \ingroup ext-adi + */ + +/** + * \addtogroup ext-adi + * @{ + */ + +/******************************************************************************/ +/** General ADI Use Functions **/ +/** **/ +/** These functions allow for interaction with any ADI port type **/ +/******************************************************************************/ + +/** + * Gets the configuration for the given ADI port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which to return + * the configuration + * + * \return The ADI configuration for the given port + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * ext_adi_port_set_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * // Displays the value of E_ADI_ANALOG_IN + * printf("Port Type: %d\n", ext_adi_port_get_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * } + * \endcode + */ +adi_port_config_e_t ext_adi_port_get_config(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets the value for the given ADI port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which to return + * the configuration + * + * \return The value stored for the given port + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * ext_adi_port_set_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * printf("Port Value: %d\n", ext_adi_get_value(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * } + * \endcode + */ +int32_t ext_adi_port_get_value(uint8_t smart_port, uint8_t adi_port); + +/** + * Configures an ADI port to act as a given sensor type. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param type + * The configuration type for the port + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * ext_adi_port_set_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * } + * \endcode + */ +int32_t ext_adi_port_set_config(uint8_t smart_port, uint8_t adi_port, adi_port_config_e_t type); + +/** + * Sets the value for the given ADI port. + * + * This only works on ports configured as outputs, and the behavior will change + * depending on the configuration of the port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which the value + * will be set + * \param value + * The value to set the ADI port to + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define DIGITAL_SENSOR_PORT 1 + * + * void initialize() { + * ext_adi_port_set_config(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT, E_ADI_DIGITAL_OUT); + * ext_adi_set_value(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT, HIGH); + * } + * \endcode + */ +int32_t ext_adi_port_set_value(uint8_t smart_port, uint8_t adi_port, int32_t value); + +/** + * Calibrates the analog sensor on the specified port and returns the new + * calibration value. + * + * This method assumes that the true sensor value is not actively changing at + * this time and computes an average from approximately 500 samples, 1 ms apart, + * for a 0.5 s period of calibration. The average value thus calculated is + * returned and stored for later calls to the adi_analog_read_calibrated() and + * adi_analog_read_calibrated_HR() functions. These functions will return + * the difference between this value and the current sensor value when called. + * + * Do not use this function when the sensor value might be unstable + * (gyro rotation, accelerometer movement). + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to calibrate (from 1-8, 'a'-'h', 'A'-'H') + * + * \return The average sensor value computed by this function + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * ext_adi_analog_calibrate(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT); + * printf("Calibrated Reading: %d\n", + * ext_adi_analog_read_calibrated(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * // All readings from then on will be calibrated + * } + * \endcode + */ +int32_t ext_adi_analog_calibrate(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets the 12-bit value of the specified port. + * + * The value returned is undefined if the analog pin has been switched to a + * different mode. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an analog input + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The analog sensor value, where a value of 0 reflects an input voltage + * of nearly 0 V and a value of 4095 reflects an input voltage of nearly 5 V + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Sensor Reading: %d\n", ext_adi_analog_read(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_analog_read(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets the 12 bit calibrated value of an analog input port. + * + * The adi_analog_calibrate() function must be run first. This function is + * inappropriate for sensor values intended for integration, as round-off error + * can accumulate causing drift over time. Use adi_analog_read_calibrated_HR() + * instead. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an analog input + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The difference of the sensor value from its calibrated default from + * -4095 to 4095 + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Sensor Reading: %d\n", ext_adi_analog_read_calibrated(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_analog_read_calibrated(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets the 16 bit calibrated value of an analog input port. + * + * The adi_analog_calibrate() function must be run first. This is intended for + * integrated sensor values such as gyros and accelerometers to reduce drift due + * to round-off, and should not be used on a sensor such as a line tracker + * or potentiometer. + * + * The value returned actually has 16 bits of "precision", even though the ADC + * only reads 12 bits, so that error induced by the average value being between + * two values when integrated over time is trivial. Think of the value as the + * true value times 16. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an analog input + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The difference of the sensor value from its calibrated default from + * -16384 to 16384 + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * ext_adi_analog_calibrate(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT); + * + * printf("Sensor Reading: %d\n", ext_adi_analog_read_calibrated_HR(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_analog_read_calibrated_HR(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets the digital value (1 or 0) of a port configured as a digital input. + * + * If the port is configured as some other mode, the digital value which + * reflects the current state of the port is returned, which may or may not + * differ from the currently set value. The return value is undefined for ports + * configured as any mode other than a Digital Input. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a digital input + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * + * \return True if the pin is HIGH, or false if it is LOW + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf(“Sensor Value: %dn”, + * ext_adi_digital_read(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_digital_read(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets a rising-edge case for a digital button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under the + * same circumstances, so only one task should call this function for any given + * button. E.g., Task A calls this function for buttons 1 and 2. Task B may call + * this function for button 3, but should not for buttons 1 or 2. A typical + * use-case for this function is to call inside opcontrol to detect new button + * presses, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a digital input + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * + * \return 1 if the button is pressed and had not been pressed + * the last time this function was called, 0 otherwise. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * if (ext_adi_digital_get_new_press(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT)) { + * // Toggle pneumatics or other state operations + * } + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_digital_get_new_press(uint8_t smart_port, uint8_t adi_port); + +/** + * Sets the digital value (1 or 0) of a port configured as a digital output. + * + * If the port is configured as some other mode, behavior is undefined. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a digital output + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param value + * An expression evaluating to "true" or "false" to set the output to + * HIGH or LOW respectively, or the constants HIGH or LOW themselves + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * bool state = LOW; + * while (true) { + * state != state; + * ext_adi_digital_write(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT, state); + * + * delay(5); // toggle the sensor value every 50ms + * } + * } + * \endcode + */ +int32_t ext_adi_digital_write(uint8_t smart_port, uint8_t adi_port, bool value); + +/** + * Configures the port as an input or output with a variety of settings. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param mode + * One of INPUT, INPUT_ANALOG, INPUT_FLOATING, OUTPUT, or OUTPUT_OD + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * ext_adi_pin_mode(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, INPUT_ANALOG); + * } + * \endcode + */ +int32_t ext_adi_pin_mode(uint8_t smart_port, uint8_t adi_port, uint8_t mode); + +/** + * Sets the speed of the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an motor + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param speed + * The new signed speed; -127 is full reverse and 127 is full forward, + * with 0 being off + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 127); // Go full speed forward + * delay(1000); + * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 0); // Stop the motor + * } + * \endcode + */ +int32_t ext_adi_motor_set(uint8_t smart_port, uint8_t adi_port, int8_t speed); + +/** + * Gets the last set speed of the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an motor + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to get (from 1-8, 'a'-'h', 'A'-'H') + * + * \return The last set speed of the motor on the given port + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 # + * define MOTOR_PORT 1 + * + * void opcontrol() { + * ext_adi_motor_set(ADI_EXPANDER_PORT, + * MOTOR_PORT, 127); // Go full speed forward + * printf(“Commanded Motor Power: %dn”, + * ext_adi_motor_get(ADI_EXPANDER_PORT, MOTOR_PORT)); // Will display 127 + * delay(1000); + * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 0); // Stop the motor + * } + * \endcode + */ +int32_t ext_adi_motor_get(uint8_t smart_port, uint8_t adi_port); + +/** + * Stops the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an motor + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to set (from 1-8, 'a'-'h', 'A'-'H') + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 127); // Go full speed forward + * delay(1000); + * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 0); // Stop the motor + * ext_adi_motor_stop(ADI_EXPANDER_PORT, MOTOR_PORT); // use this instead + * } + * \endcode + */ +int32_t ext_adi_motor_stop(uint8_t smart_port, uint8_t adi_port); + +/** + * Reference type for an initialized encoder. + * + * This merely contains the port number for the encoder. + */ +typedef int32_t ext_adi_encoder_t; + +/** + * Gets the number of ticks recorded by the encoder. + * + * There are 360 ticks in one revolution. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an encoder + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to read + * + * \return The signed and cumulative number of counts since the last start or + * reset + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define PORT_TOP 1 #define PORT_BOTTOM 2 + * + * void opcontrol() { + * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, + * PORT_TOP, PORT_BOTTOM, false); + * while (true) { + * printf(“Encoder Value: %dn”, + * ext_adi_encoder_get(enc)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_encoder_get(ext_adi_encoder_t enc); + +/** + * Creates an encoder object and configures the specified ports accordingly. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an encoder + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port_top + * The "top" wire from the encoder sensor with the removable cover side + * up. This should be in port 1, 3, 5, or 7 ('A', 'C', 'E', or 'G'). + * \param adi_port_bottom + * The "bottom" wire from the encoder sensor + * \param reverse + * If "true", the sensor will count in the opposite direction + * + * \return An adi_encoder_t object to be stored and used for later calls to + * encoder functions + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, PORT_TOP, PORT_BOTTOM, false); + * while (true) { + * printf("Encoder Value: %d\n", ext_adi_encoder_get(enc)); + * delay(5); + * } + * } + * \endcode + */ +ext_adi_encoder_t ext_adi_encoder_init(uint8_t smart_port, uint8_t adi_port_top, uint8_t adi_port_bottom, bool reverse); + +/** + * Sets the encoder value to zero. + * + * It is safe to use this method while an encoder is enabled. It is not + * necessary to call this method before stopping or starting an encoder. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an encoder + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to reset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, PORT_TOP, PORT_BOTTOM, false); + * delay(1000); // Move the encoder around in this time + * ext_adi_encoder_reset(enc); // The encoder is now zero again + * } + * \endcode + */ +int32_t ext_adi_encoder_reset(ext_adi_encoder_t enc); + +/** + * Disables the encoder and voids the configuration on its ports. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an encoder + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to stop + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, PORT_TOP, PORT_BOTTOM, false); + * // Use the encoder + * ext_adi_encoder_shutdown(enc); + * } + * \endcode + */ +int32_t ext_adi_encoder_shutdown(ext_adi_encoder_t enc); + +/** + * Reference type for an initialized ultrasonic. + * + * This merely contains the port number for the ultrasonic. + */ +typedef int32_t ext_adi_ultrasonic_t; + +/** + * Gets the current ultrasonic sensor value in centimeters. + * + * If no object was found, zero is returned. If the ultrasonic sensor was never + * started, the return value is undefined. Round and fluffy objects can cause + * inaccurate values to be returned. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param ult + * The adi_ultrasonic_t object from adi_ultrasonic_init() to read + * + * \return The distance to the nearest object in m^-4 (10000 indicates 1 meter), + * measured from the sensor's mounting points. + * + * \b Example + * \code + * + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_ultrasonic_t ult = ext_adi_ultrasonic_init(ADI_EXPANDER_PORT, PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", ext_adi_ultrasonic_get(ult)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_ultrasonic_get(ext_adi_ultrasonic_t ult); + +/** + * Creates an ultrasonic object and configures the specified ports accordingly. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port_ping + * The port connected to the orange OUTPUT cable. This should be in port + * 1, 3, 5, or 7 ('A', 'C', 'E', 'G'). + * \param adi_port_echo + * The port connected to the yellow INPUT cable. This should be in the + * next highest port following port_ping. + * + * \return An adi_ultrasonic_t object to be stored and used for later calls to + * ultrasonic functions + * + * \b Example + * \code + * + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_ultrasonic_t ult = ext_adi_ultrasonic_init(ADI_EXPANDER_PORT, PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", ext_adi_ultrasonic_get(ult)); + * delay(5); + * } + * } + * \endcode + */ +ext_adi_ultrasonic_t ext_adi_ultrasonic_init(uint8_t smart_port, uint8_t adi_port_ping, uint8_t adi_port_echo); + +/** + * Disables the ultrasonic sensor and voids the configuration on its ports. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param ult + * The adi_ultrasonic_t object from adi_ultrasonic_init() to stop + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_ultrasonic_t ult = ext_adi_ultrasonic_init(ADI_EXPANDER_PORT, PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", ext_adi_ultrasonic_get(ult)); + * delay(5); + * } + * ext_adi_ultrasonic_shutdown(ult); + * } + * \endcode + */ +int32_t ext_adi_ultrasonic_shutdown(ext_adi_ultrasonic_t ult); + +/** + * Reference type for an initialized gyroscope. + * + * This merely contains the port number for the gyroscope. + * + * (Might Be useless with the wire expander.) + */ +typedef int32_t ext_adi_gyro_t; + +/** + * Gets the current gyro angle in tenths of a degree. Unless a multiplier is + * applied to the gyro, the return value will be a whole number representing + * the number of degrees of rotation times 10. + * + * There are 360 degrees in a circle, thus the gyro will return 3600 for one + * whole rotation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object for which the angle will be returned + * + * \return The gyro angle in degrees. + * + * \b Example + * \code + * + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); + * delay(5); + * } + * } + * \endcode + */ +double ext_adi_gyro_get(ext_adi_gyro_t gyro); + +/** + * Initializes a gyroscope on the given port. If the given port has not + * previously been configured as a gyro, then this function starts a 1300 ms + * calibration period. + * + * It is highly recommended that this function be called from initialize() when + * the robot is stationary to ensure proper calibration. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a gyro + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * \param multiplier + * A scalar value that will be multiplied by the gyro heading value + * supplied by the ADI + * + * \return An adi_gyro_t object containing the given port, or PROS_ERR if the + * initialization failed. + * + * \b Example + * \code + * + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); + * delay(5); + * } + * } + * \endcode + */ +ext_adi_gyro_t ext_adi_gyro_init(uint8_t smart_port, uint8_t adi_port, double multiplier); + +/** + * Resets the gyroscope value to zero. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object for which the angle will be returned + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); + * uint32_t now = millis(); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); + * + * if (millis() - now > 2000) { + * // Reset the gyro every 2 seconds + * ext_adi_gyro_reset(gyro); + * now = millis(); + * } + * + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_gyro_reset(ext_adi_gyro_t gyro); + +/** + * Disables the gyro and voids the configuration on its port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object to be shut down + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); + * uint32_t now = millis(); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); + * + * if (millis() - now > 2000) { + * ext_adi_gyro_shutdown(gyro); + * // Shut down the gyro after two seconds + * break; + * } + * + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_gyro_shutdown(ext_adi_gyro_t gyro); + +/** + * Reference type for an initialized potentiometer. + * + * This merely contains the port number for the potentiometer. + */ +typedef int32_t ext_adi_potentiometer_t; + +/** + * Initializes a potentiometer on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \param port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * \param potentiometer_type + * An adi_potentiometer_type_e_t enum value specifying the potentiometer version type + * + * \return An adi_potentiometer_t object containing the given port, or PROS_ERR if the + * initialization failed. + */ +ext_adi_potentiometer_t ext_adi_potentiometer_init(uint8_t smart_port, uint8_t adi_port, adi_potentiometer_type_e_t potentiometer_type); + +/** + * Gets the current potentiometer angle in tenths of a degree. + * + * The original potentiometer rotates 250 degrees thus returning an angle between 0-250 degrees. + * Potentiometer V2 rotates 333 degrees thus returning an angle between 0-333 degrees. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \param potentiometer + * The adi_potentiometer_t object for which the angle will be returned + * + * \return The potentiometer angle in degrees. + */ +double ext_adi_potentiometer_get_angle(ext_adi_potentiometer_t potentiometer); + +/** + * Reference type for an initialized addressable led. + * + * This merely contains the port number for the led, unlike its use as an + * object to store led data in the C++ API. + */ +typedef int32_t ext_adi_led_t; + +/** + * Initializes a led on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * \param smart_port + * The smart port with the adi expander (1-21) + * \param adi_port + * The ADI port to initialize as a led (from 1-8, 'a'-'h', 'A'-'H') + * + * \return An ext_adi_led_t object containing the given port, or PROS_ERR if the + * initialization failed. + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with a single color of red + * uint32_t buffer[1] = {0xFF0000}; + * + * while (true) { + * // Set the led to colors in the buffer + * ext_adi_led_set(led, buffer, 1); + * delay(5); + * } + * } + * \endcode + */ +ext_adi_led_t ext_adi_led_init(uint8_t smart_port, uint8_t adi_port); + +/** + * @brief Clear the entire led strip of color + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with a single color of red + * uint32_t buffer[1] = {0xFF0000}; + * + * while (true) { + * // Set the led to colors in the buffer + * ext_adi_led_set(led, buffer, 1); + * delay(5); + * + * // Clear the led + * ext_adi_led_clear_all(led, buffer, 1); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_led_clear_all(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length); + +/** + * @brief Set the entire led strip using the colors contained in the buffer + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with a single color of red + * uint32_t buffer[1] = {0xFF0000}; + * + * while (true) { + * // Set the led to colors in the buffer + * ext_adi_led_set(led, buffer, 1); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_led_set(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length); + +/** + * @brief Set the entire led strip to one color + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @param color color to set all the led strip value to + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with a single color of red + * uint32_t buffer[1] = {0xFF0000}; + * + * while (true) { + * // Set the entire led strip to red + * ext_adi_led_set_all(led, buffer, 1, 0xFF0000); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_led_set_all(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color); + +/** + * @brief Set one pixel on the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of the input buffer + * @param color color to clear all the led strip to + * @param pixel_position position of the pixel to clear (0 indexed) + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with multiple colors + * uint32_t buffer[3] = {0xFF0000, 0x00FF00, 0x0000FF}; + * + * while (true) { + * // Set the first pixel to red + * ext_adi_led_set_pixel(led, buffer, 3, 0xFF0000, 0); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_led_set_pixel(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color, uint32_t pixel_position); + +/** + * @brief Clear one pixel on the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of the input buffer + * @param pixel_position position of the pixel to clear (0 indexed) + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with multiple colors + * uint32_t buffer[3] = {0xFF0000, 0x00FF00, 0x0000FF}; + * + * while (true) { + * // Set the first pixel to red + * ext_adi_led_set_pixel(led, buffer, 3, 0xFF0000, 0); + * delay(5); + * + * // Clear the first pixel + * ext_adi_led_clear_pixel(led, buffer, 3, 0); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_led_clear_pixel(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t pixel_position); + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_ADI_H_ diff --git a/test/include/pros/gps.h b/test/include/pros/gps.h new file mode 100644 index 00000000..5cc5eef3 --- /dev/null +++ b/test/include/pros/gps.h @@ -0,0 +1,884 @@ +/** + * \file pros/gps.h + * \ingroup c-gps + * + * Contains prototypes for functions related to the VEX GPS. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-gps VEX GPS Sensor C API + * \note For a pros-specific usage guide on the GPS, please check out our article [here.](@ref gps) + */ + +#ifndef _PROS_GPS_H_ +#define _PROS_GPS_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \ingroup c-gps + */ + +/** + * \addtogroup c-gps + * @{ + */ + +/** + * \struct gps_position_s_t + */ +typedef struct __attribute__((__packed__)) gps_position_s { + /// X Position (meters) + double x; + /// Y Position (meters) + double y; +} gps_position_s_t; + +/** + * \struct gps_status_s_t + */ +typedef struct __attribute__((__packed__)) gps_status_s { + /// X Position (meters) + double x; + /// Y Position (meters) + double y; + /// Perceived Pitch based on GPS + IMU + double pitch; + /// Perceived Roll based on GPS + IMU + double roll; + /// Perceived Yaw based on GPS + IMU + double yaw; +} gps_status_s_t; + +/** + * \struct gps_orientation_s_t + */ +typedef struct __attribute__((__packed__)) gps_orientation_s { + /// Perceived Pitch based on GPS + IMU + double pitch; + /// Perceived Roll based on GPS + IMU + double roll; + /// Perceived Yaw based on GPS + IMU + double yaw; +} gps_orientation_s_t; + + +/** + * \struct gps_raw_s + */ +struct gps_raw_s { + /// Perceived Pitch based on GPS + IMU + double x; + /// Perceived Roll based on GPS + IMU + double y; + /// Perceived Yaw based on GPS + IMU + double z; +}; + +/** + * \struct gps_accel_s_t + * + */ +typedef struct gps_raw_s gps_accel_s_t; + +/** + * \struct gps_gyro_s_t + * + */ +typedef struct gps_raw_s gps_gyro_s_t; + +#ifdef __cplusplus +namespace c { +#endif + + +/** + * Set the GPS's offset relative to the center of turning in meters, + * as well as its initial position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \param xOffset + * Cartesian 4-Quadrant X offset from center of turning (meters) + * \param yOffset + * Cartesian 4-Quadrant Y offset from center of turning (meters) + * \param xInitial + * Initial 4-Quadrant X Position, with (0,0) being at the center of the field (meters) + * \param yInitial + * Initial 4-Quadrant Y Position, with (0,0) being at the center of the field (meters) + * \param headingInitial + * Heading with 0 being north on the field, in degrees [0,360) going clockwise + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * #define X_OFFSET .225 + * #define Y_OFFSET .223 + * #define X_INITIAL 1.54 + * #define Y_INITIAL 1.14 + * #define HEADING_INITIAL 90 + * + * void initialize() { + * gps_initialize_full(GPS_PORT, X_OFFSET, Y_OFFSET, X_INITIAL, Y_INITIAL, HEADING_INITIAL); + * } + * \endcode + */ +int32_t gps_initialize_full(uint8_t port, double xInitial, double yInitial, double headingInitial, double xOffset, + double yOffset); + +/** + * Set the GPS's offset relative to the center of turning in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \param xOffset + * Cartesian 4-Quadrant X offset from center of turning (meters) + * \param yOffset + * Cartesian 4-Quadrant Y offset from center of turning (meters) + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * #define X_OFFSET -.225 + * #define Y_OFFSET .225 + * + * void initialize() { + * gps_set_offset(GPS_PORT, X_OFFSET, Y_OFFSET); + * } + * \endcode + */ +int32_t gps_set_offset(uint8_t port, double xOffset, double yOffset); + +/** + * Get the GPS's cartesian location relative to the center of turning/origin in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return A struct (gps_position_s_t) containing the X and Y values if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_position_s_t pos; + * + * while (true) { + * pos = gps_get_offset(GPS_PORT); + * screen_print(TEXT_MEDIUM, 1, "X Offset: %4d, Y Offset: %4d", pos.x, pos.y); + * delay(20); + * } + * } + * \endcode + */ +gps_position_s_t gps_get_offset(uint8_t port); + +/** + * Sets the robot's location relative to the center of the field in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \param xInitial + * Initial 4-Quadrant X Position, with (0,0) being at the center of the field (meters) + * \param yInitial + * Initial 4-Quadrant Y Position, with (0,0) being at the center of the field (meters) + * \param headingInitial + * Heading with 0 being north on the field, in degrees [0,360) going clockwise + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * #define X_INITIAL -1.15 + * #define Y_INITIAL 1.45 + * #define HEADING_INITIAL 90 + * + * void initialize() { + * gps_set_position(GPS_PORT, X_INITIAL, Y_INITIAL, HEADING_INITIAL); + * } + * \endcode + */ +int32_t gps_set_position(uint8_t port, double xInitial, double yInitial, double headingInitial); + +/** + * Set the GPS sensor's data rate in milliseconds, only applies to IMU on GPS. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \param rate + * Data rate in milliseconds (Minimum: 5 ms) + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * #define GPS_DATA_RATE 5 + * + * void initialize() { + * gps_set_data_rate(GPS_PORT, GPS_DATA_RATE); + * while (true) { + * // Do something + * } + * } + * \endcode + */ +int32_t gps_set_data_rate(uint8_t port, uint32_t rate); + +/** + * Get the possible RMS (Root Mean Squared) error in meters for GPS position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return Possible RMS (Root Mean Squared) error in meters for GPS position. + * If the operation failed, returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double error; + * error = gps_get_error(GPS_PORT); + * screen_print(TEXT_MEDIUM, 1, "Error: %4d", error); + * } + * \endcode + */ +double gps_get_error(uint8_t port); + +/** + * Gets the position and roll, yaw, and pitch of the GPS. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return A struct (gps_status_s_t) containing values mentioned above. + * If the operation failed, all the structure's members are filled with + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_status_s_t status; + * + * while (true) { + * status = gps_get_position_and_orientation(GPS_PORT); + * printf("X: %f, Y: %f, Pitch: %f, Roll: %f, Yaw: %f\n", status.x, status.y, status.pitch, status.roll, status.yaw); + * delay(20); + * } + * } + * \endcode + */ +gps_status_s_t gps_get_position_and_orientation(uint8_t port); + +/** + * Gets the x and y position on the field of the GPS in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return A struct (gps_position_s_t) containing values mentioned above. + * If the operation failed, all the structure's members are filled with + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_position_s_t position; + * + * while (true) { + * position = gps_get_position(GPS_PORT); + * printf("X: %f, Y: %f\n", position.x, position.y); + * delay(20); + * } + * } + * \endcode + */ +gps_position_s_t gps_get_position(uint8_t port); + +/** + * Gets the X position in meters of the robot relative to the starting position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return The X position in meters. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double pos_x; + * + * while (true) { + * pos_x = gps_get_position_x(GPS_PORT); + * printf("X: %f\n", pos_x); + * delay(20); + * } + * } + * \endcode + */ +double gps_get_position_x(uint8_t port); + +/** + * Gets the Y position in meters of the robot relative to the starting position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return The Y position in meters. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double pos_y; + * + * while (true) { + * pos_y = gps_get_position_y(GPS_PORT); + * printf("Y: %f\n", pos_y); + * delay(20); + * } + * } + * \endcode + */ +double gps_get_position_y(uint8_t port); + +/** + * Gets the pitch, roll, and yaw of the GPS relative to the starting orientation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return A struct (gps_orientation_s_t) containing values mentioned above. + * If the operation failed, all the structure's members are filled with + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_orientation_s_t orientation; + * + * while (true) { + * orientation = gps_get_orientation(GPS_PORT); + * printf("pitch: %f, roll: %f, yaw: %f\n", orientation.pitch, orientation.roll, orientation.yaw); + * delay(20); + * } + * } + * \endcode +*/ +gps_orientation_s_t gps_get_orientation(uint8_t port); + +/** + * Gets the pitch of the robot in degrees relative to the starting oreintation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return The pitch in [0,360) degree values. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double pitch; + * + * while (true) { + * pitch = gps_get_pitch(GPS_PORT); + * printf("pitch: %f\n", pitch); + * delay(20); + * } + * } + * \endcode + */ +double gps_get_pitch(uint8_t port); + +/** + * Gets the roll of the robot in degrees relative to the starting oreintation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return The roll in [0,360) degree values. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double roll; + * + * while (true) { + * roll = gps_get_roll(GPS_PORT); + * printf("roll: %f\n", roll); + * delay(20); + * } + * } + * \endcode + */ +double gps_get_roll(uint8_t port); + +/** + * Gets the yaw of the robot in degrees relative to the starting oreintation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return The yaw in [0,360) degree values. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double yaw; + * + * while (true) { + * yaw = gps_get_yaw(GPS_PORT); + * printf("yaw: %f\n", yaw); + * delay(20); + * } + * } + * \endcode + */ +double gps_get_yaw(uint8_t port); + +/** + * Get the heading in [0,360) degree values. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return The heading in [0,360) degree values. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double heading; + * + * while (true) { + * heading = gps_get_heading(GPS_PORT); + * printf("heading: %f\n", heading); + * delay(20); + * } + * } + * \endcode + */ +double gps_get_heading(uint8_t port); + +/** + * Get the heading in the max double value and min double value scale. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return The heading in [DOUBLE_MIN, DOUBLE_MAX] values. If the operation + * fails, returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double heading_raw; + * + * while (true) { + * heading_raw = gps_get_heading_raw(GPS_PORT); + * printf("heading_raw: %f\n", heading_raw); + * delay(20); + * } + * } + * \endcode + */ +double gps_get_heading_raw(uint8_t port); + +/** + * Get the GPS's raw gyroscope values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return A struct (gps_gyro_s_t) containing values mentioned above. + * If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_gyro_s_t gyro; + * + * while (true) { + * gyro = gps_get_gyro(GPS_PORT); + * printf("Gyro: %f %f %f\n", gyro.x, gyro.y, gyro.z); + * delay(20); + * } + * } + * \endcode + */ +gps_gyro_s_t gps_get_gyro_rate(uint8_t port); + +/** + * Get the GPS's raw gyroscope value in x-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return The raw gyroscope value in x-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double gyro_x; + * + * while (true) { + * gyro_x = gps_get_gyro_x(GPS_PORT); + * printf("gyro_x: %f\n", gyro_x); + * delay(20); + * } + * } + * \endcode +*/ +double gps_get_gyro_rate_x(uint8_t port); + +/** + * Get the GPS's raw gyroscope value in y-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return The raw gyroscope value in y-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double gyro_y; + * + * while (true) { + * gyro_y = gps_get_gyro_y(GPS_PORT); + * printf("gyro_y: %f\n", gyro_y); + * delay(20); + * } + * } + * \endcode +*/ +double gps_get_gyro_rate_y(uint8_t port); + +/** + * Get the GPS's raw gyroscope value in z-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return The raw gyroscope value in z-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double gyro_z; + * + * while (true) { + * gyro_z = gps_get_gyro_z(GPS_PORT); + * printf("gyro_z: %f\n", gyro_z); + * delay(20); + * } + * } + * \endcode +*/ +double gps_get_gyro_rate_z(uint8_t port); + +/** + * Get the GPS's raw accelerometer values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS's port number from 1-21 + * \return A struct (gps_accel_s_t) containing values mentioned above. + * If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_accel_s_t accel; + * + * while (true) { + * accel = gps_get_accel(GPS_PORT); + * printf("X: %f, Y: %f, Z: %f\n", accel.x, accel.y, accel.z); + * delay(20); + * } + * } + * \endcode + */ +gps_accel_s_t gps_get_accel(uint8_t port); + +/** + * Get the GPS's raw accelerometer value in x-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS's port number from 1-21 + * \return The raw accelerometer value in x-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double accel_x; + * + * while (true) { + * accel_x = gps_get_accel_x(GPS_PORT); + * printf("accel_x: %f\n", accel_x); + * delay(20); + * } + * } + * \endcode +*/ +double gps_get_accel_x(uint8_t port); + +/** + * Get the GPS's raw accelerometer value in y-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS's port number from 1-21 + * \return The raw accelerometer value in y-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double accel_y; + * + * while (true) { + * accel_y = gps_get_accel_y(GPS_PORT); + * printf("accel_y: %f\n", accel_y); + * delay(20); + * } + * } + * \endcode +*/ +double gps_get_accel_y(uint8_t port); + +/** + * Get the GPS's raw accelerometer value in z-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS's port number from 1-21 + * \return The raw accelerometer value in z-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double accel_z; + * + * while (true) { + * accel_z = gps_get_accel_z(GPS_PORT); + * printf("accel_z: %f\n", accel_z); + * delay(20); + * } + * } + * \endcode +*/ +double gps_get_accel_z(uint8_t port); + +#ifdef __cplusplus +} +} +} +#endif + +#endif diff --git a/test/include/pros/gps.hpp b/test/include/pros/gps.hpp new file mode 100644 index 00000000..b9fc7b5a --- /dev/null +++ b/test/include/pros/gps.hpp @@ -0,0 +1,937 @@ +/** + * \file pros/gps.hpp + * \ingroup cpp-gps + * + * Contains prototypes for functions related to the VEX GPS. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-gps VEX GPS Sensor C API + * \note For a pros-specific usage guide on the GPS, please check out our article [here.](@ref gps) + */ + +#ifndef _PROS_GPS_HPP_ +#define _PROS_GPS_HPP_ + +#include + +#include +#include + +#include "pros/device.hpp" +#include "pros/gps.h" + +namespace pros { +inline namespace v5 { +/** + * \ingroup cpp-gps + * @{ + */ +class Gps : public Device { + /** + * \addtogroup cpp-gps + * @{ + */ + + public: + /** + * Creates a GPS object for the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 port number from 1-21 + * \b Example: + * \code + * pros::Gps gps(1); + * \endcode + * + */ + Gps(const std::uint8_t port) : Device(port, DeviceType::gps){}; + + Gps(const Device& device) : Gps(device.get_port()){}; + + /** + * Creates a GPS object for the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 port number from 1-21 + * \param xInitial + * Cartesian 4-Quadrant X initial position (meters) + * \param yInitial + * Cartesian 4-Quadrant Y initial position (meters) + * \param headingInitial + * Initial heading (degrees) + * + * \b Example: + * \code + * pros::Gps gps(1, 1.30, 1.20, 90); + * \endcode + * + */ + explicit Gps(const std::uint8_t port, double xInitial, double yInitial, double headingInitial) + : Device(port, DeviceType::gps) { + pros::c::gps_set_position(port, xInitial, yInitial, headingInitial); + }; + + /** + * Creates a GPS object for the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 port number from 1-21 + * \param xOffset + * Cartesian 4-Quadrant X offset from center of turning (meters) + * \param yOffset + * Cartesian 4-Quadrant Y offset from center of turning (meters) + * + * \b Example: + * \code + * pros::Gps gps(1, 1.30, 1.20); + * \endcode + * + */ + explicit Gps(const std::uint8_t port, double xOffset, double yOffset) : Device(port, DeviceType::gps) { + pros::c::gps_set_offset(port, xOffset, yOffset); + }; + + /** + * Creates a GPS object for the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 port number from 1-21 + * \param xInitial + * Initial 4-Quadrant X Position, with (0,0) being at the center of the field (meters) + * \param yInitial + * Initial 4-Quadrant Y Position, with (0,0) being at the center of the field (meters) + * \param headingInitial + * Initial Heading, with 0 being North, 90 being East, 180 being South, and 270 being West (degrees) + * \param xOffset + * Cartesian 4-Quadrant X offset from center of turning (meters) + * \param yOffset + * Cartesian 4-Quadrant Y offset from center of turning (meters) + * + * \b Example: + * \code + * pros::Gps gps(1, 1.30, 1.20, 180, 1.30, 1.20); + * \endcode + * + */ + explicit Gps(const std::uint8_t port, double xInitial, double yInitial, double headingInitial, double xOffset, + double yOffset) + : Device(port, DeviceType::gps) { + pros::c::gps_initialize_full(port, xInitial, yInitial, headingInitial, xOffset, yOffset); + }; + + /** + * Set the GPS's offset relative to the center of turning in meters, + * as well as its initial position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param xOffset + * Cartesian 4-Quadrant X offset from center of turning (meters) + * \param yOffset + * Cartesian 4-Quadrant Y offset from center of turning (meters) + * \param xInitial + * Initial 4-Quadrant X Position, with (0,0) being at the center of the field (meters) + * \param yInitial + * Initial 4-Quadrant Y Position, with (0,0) being at the center of the field (meters) + * \param headingInitial + * Heading with 0 being north on the field, in degrees [0,360) going clockwise + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT, 1.1, 1.2, 180, .4, .4); + * // this is equivalent to the above line + * gps.initialize_full(1.1, 1.2, 180, .4, .4); + * while (true) { + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t initialize_full(double xInitial, double yInitial, double headingInitial, double xOffset, + double yOffset) const; + + /** + * Set the GPS's offset relative to the center of turning in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param xOffset + * Cartesian 4-Quadrant X offset from center of turning (meters) + * \param yOffset + * Cartesian 4-Quadrant Y offset from center of turning (meters) + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT, 1.1, 1.2, 180, .4, .4); + * // this is equivalent to the above line + * gps.set_offset(.4, .4); + * while (true) { + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t set_offset(double xOffset, double yOffset) const; + + /** + + * Gets all GPS sensors. + * + * \return A vector of Gps sensor objects. + * + * \b Example + * \code + * void opcontrol() { + * std::vector gps_all = pros::Gps::get_all_devices(); // All GPS sensors that are connected + * } + * \endcode + */ + static std::vector get_all_devices(); + + /** + * Get the GPS's cartesian location relative to the center of turning/origin in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return A struct (gps_position_s_t) containing the X and Y values if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_position_s_t pos; + * Gps gps(GPS_PORT); + * while (true) { + * pos = gps.get_offset(); + * screen_print(TEXT_MEDIUM, 1, "X Offset: %4d, Y Offset: %4d", pos.x, pos.y); + * delay(20); + * } + * } + * \endcode + */ + virtual pros::gps_position_s_t get_offset() const; + + /** + * Sets the robot's location relative to the center of the field in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param xInitial + * Initial 4-Quadrant X Position, with (0,0) being at the center of the field (meters) + * \param yInitial + * Initial 4-Quadrant Y Position, with (0,0) being at the center of the field (meters) + * \param headingInitial + * Heading with 0 being north on the field, in degrees [0,360) going clockwise + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * gps.set_position(1.3, 1.4, 180); + * while (true) { + * printf("X: %f, Y: %f, Heading: %f\n", gps.get_position().x, + * gps.get_position().y, gps.get_position().heading); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t set_position(double xInitial, double yInitial, double headingInitial) const; + + /** + * Set the GPS sensor's data rate in milliseconds, only applies to IMU on GPS. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param rate + * Data rate in milliseconds (Minimum: 5 ms) + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * gps.set_data_rate(10); + * while (true) { + * printf("X: %f, Y: %f, Heading: %f\n", gps.get_position().x, + * gps.get_position().y, gps.get_position().heading); + * delay(10); + * } + * } + * \endcode + */ + virtual std::int32_t set_data_rate(std::uint32_t rate) const; + + /** + * Get the possible RMS (Root Mean Squared) error in meters for GPS position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return Possible RMS (Root Mean Squared) error in meters for GPS position. + * If the operation failed, returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * double error = gps.get_error(); + * printf("Error: %f\n", error); + * pros::delay(20); + * } + * \endcode + */ + virtual double get_error() const; + + /** + * Gets the position and roll, yaw, and pitch of the GPS. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * + * \return A struct (gps_status_s_t) containing values mentioned above. + * If the operation failed, all the structure's members are filled with + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * gps_status_s_t status; + * while (true) { + * status = gps.get_position_and_orientation(); + * printf("X: %f, Y: %f, Roll: %f, Pitch: %f, Yaw: %f\n", + * status.x, status.y, status.roll, status.pitch, status.yaw); + * delay(20); + * } + * } + * \endcode + */ + virtual pros::gps_status_s_t get_position_and_orientation() const; + + /** + * Gets the x and y position on the field of the GPS in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return A struct (gps_position_s_t) containing values mentioned above. + * If the operation failed, all the structure's members are filled with + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * gps_position_s_t position; + * while (true) { + * position = gps.get_position(); + * printf("X: %f, Y: %f\n", position.x, position.y); + * delay(20); + * } + * } + * \endcode + */ + virtual pros::gps_position_s_t get_position() const; + + /** + * Gets the X position in meters of the robot relative to the starting position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return The X position in meters. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double pos_x = gps.get_position_x(); + * printf("X: %f\n", pos_x); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_position_x() const; + + /** + * Gets the Y position in meters of the robot relative to the starting position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return The Y position in meters. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double pos_y = gps.get_position_y(); + * printf("Y: %f\n", pos_y); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_position_y() const; + + /** + * Gets the pitch, roll, and yaw of the GPS relative to the starting orientation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return A struct (gps_orientation_s_t) containing values mentioned above. + * If the operation failed, all the structure's members are filled with + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * gps_orientation_s_t orientation; + * while (true) { + * orientation = gps.get_orientation(); + * printf("pitch: %f, roll: %f, yaw: %f\n", orientation.pitch, + * orientation.roll, orientation.yaw); + * delay(20); + * } + * } + * \endcode + */ + virtual pros::gps_orientation_s_t get_orientation() const; + + /** + * Gets the pitch of the robot in degrees relative to the starting oreintation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return The pitch in [0,360) degree values. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double pitch = gps.get_pitch(); + * printf("pitch: %f\n", pitch); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_pitch() const; + + /** + * Gets the roll of the robot in degrees relative to the starting oreintation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return The roll in [0,360) degree values. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double roll = gps.get_roll(); + * printf("roll: %f\n", roll); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_roll() const; + + /** + * Gets the yaw of the robot in degrees relative to the starting oreintation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return The yaw in [0,360) degree values. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double yaw = gps.get_yaw(); + * printf("yaw: %f\n", yaw); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_yaw() const; + + /** + * Get the heading in [0,360) degree values. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * + * \return The heading in [0,360) degree values. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double heading = gps.get_heading(); + * printf("Heading: %f\n", heading); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_heading() const; + + /** + * Get the heading in the max double value and min double value scale. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return The heading in [DOUBLE_MIN, DOUBLE_MAX] values. If the operation + * fails, returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double heading = gps.get_heading_raw(); + * printf("Heading: %f\n", heading); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_heading_raw() const; + + /** + * Get the GPS's raw gyroscope value in z-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return The raw gyroscope value in z-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double gyro_z = gps.get_gyro_z(); + * printf("gyro_z: %f\n", gyro_z); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual pros::gps_gyro_s_t get_gyro_rate() const; + + /** + * Get the GPS's raw gyroscope value in x-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return The raw gyroscope value in x-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double gyro_x = gps.get_gyro_x(); + * printf("gyro_x: %f\n", gyro_x); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_gyro_rate_x() const; + + /** + * Get the GPS's raw gyroscope value in y-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return The raw gyroscope value in y-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double gyro_y = gps.get_gyro_y(); + * printf("gyro_y: %f\n", gyro_y); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_gyro_rate_y() const; + + /** + * Get the GPS's raw gyroscope value in z-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \return The raw gyroscope value in z-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double gyro_z = gps.get_gyro_z(); + * printf("gyro_z: %f\n", gyro_z); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_gyro_rate_z() const; + + /** + * Get the GPS's raw accelerometer values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an GPS + * EAGAIN - The sensor is still calibrating + * + * \return The raw accelerometer values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + */ + virtual pros::gps_accel_s_t get_accel() const; + + /** + * Get the GPS's raw accelerometer value in x-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an GPS + * EAGAIN - The sensor is still calibrating + * + * \return The raw accelerometer value in x-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double accel_x = gps.get_accel_x(); + * printf("accel_x: %f\n", accel_x); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_accel_x() const; + + /** + * Get the GPS's raw accelerometer value in y-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an GPS + * EAGAIN - The sensor is still calibrating + * + * \return The raw accelerometer value in y-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double accel_y = gps.get_accel_y(); + * printf("accel_y: %f\n", accel_y); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_accel_y() const; + + /** + * Get the GPS's raw accelerometer value in z-axis + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an GPS + * EAGAIN - The sensor is still calibrating + * + * \return The raw accelerometer value in z-axis. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * double accel_z = gps.get_accel_z(); + * printf("accel_z: %f\n", accel_z); + * pros::delay(20); + * } + * } + * \endcode + */ + virtual double get_accel_z() const; + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format: + * Gps [port: gps._port, x: (x position), y: (y position), heading: (gps heading), rotation: (gps rotation)] + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * Gps gps(GPS_PORT); + * while(true) { + * std::cout << gps << std::endl; + * pros::delay(20); + * } + * } + * \endcode + */ + friend std::ostream& operator<<(std::ostream& os, const pros::Gps& gps); + + /** + * Gets a gps sensor that is plugged in to the brain + * + * \note The first time this function is called it returns the gps sensor at the lowest port + * If this function is called multiple times, it will cycle through all the ports. + * For example, if you have 1 gps sensor on the robot + * this function will always return a gps sensor object for that port. + * If you have 2 gps sensors, all the odd numered calls to this function will return objects + * for the lower port number, + * all the even number calls will return gps objects for the higher port number + * + * + * This functions uses the following values of errno when an error state is + * reached: + * ENODEV - No gps sensor is plugged into the brain + * + * \return A gps object corresponding to a port that a gps sensor is connected to the brain + * If no gps sensor is plugged in, it returns a gps sensor on port PROS_ERR_BYTE + * + */ + static Gps get_gps(); + ///@} +}; // Gps Class + +namespace literals { +/** + * Constructs a Gps object with the given port number + * + * \b Example + * \code + * using namespace literals; + * + * void opcontrol() { + * pros::Gps gps = 1_gps; + * while (true) { + * pos = gps.get_position(); + * screen_print(TEXT_MEDIUM, 1, "X Position: %4d, Y Position: %4d", pos.x, pos.y); + * delay(20); + * } + * } + * \endcode + */ +const pros::Gps operator""_gps(const unsigned long long int g); +} // namespace literals + +/// @brief +/// Alias for Gps is GPS for user convenience. +using GPS = Gps; + +} // namespace v5 +} // namespace pros + +#endif diff --git a/test/include/pros/imu.h b/test/include/pros/imu.h new file mode 100644 index 00000000..00ed1647 --- /dev/null +++ b/test/include/pros/imu.h @@ -0,0 +1,974 @@ +/** + * \file pros/imu.h + * \ingroup c-imu + * + * Contains prototypes for functions related to the VEX Inertial sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-imu VEX Inertial Sensor C API + */ + +#ifndef _PROS_IMU_H_ +#define _PROS_IMU_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \ingroup c-imu + * */ + +/** + * \addtogroup c-imu + * @{ + */ + +/** + * \enum imu_status_e_t + * @brief Indicates IMU status. + */ +typedef enum imu_status_e { + E_IMU_STATUS_READY = 0, // IMU is connected but not currently calibrating + /** The IMU is calibrating */ + E_IMU_STATUS_CALIBRATING = 1, + /** Used to indicate that an error state was reached in the imu_get_status function,\ + not that the IMU is necessarily in an error state */ + E_IMU_STATUS_ERROR = 0xFF, +} imu_status_e_t; + +typedef enum imu_orientation_e { + E_IMU_Z_UP = 0, // IMU has the Z axis UP (VEX Logo facing DOWN) + E_IMU_Z_DOWN = 1, // IMU has the Z axis DOWN (VEX Logo facing UP) + E_IMU_X_UP = 2, // IMU has the X axis UP + E_IMU_X_DOWN = 3, // IMU has the X axis DOWN + E_IMU_Y_UP = 4, // IMU has the Y axis UP + E_IMU_Y_DOWN = 5, // IMU has the Y axis DOWN + E_IMU_ORIENTATION_ERROR = 0xFF // NOTE: used for returning an error from the get_physical_orientation function, not + // that the IMU is necessarily in an error state +} imu_orientation_e_t; + +/** + * \struct quaternion_s_t + */ +typedef struct __attribute__((__packed__)) quaternion_s { + double x; + double y; + double z; + double w; +} quaternion_s_t; + +/** + * \struct imu_raw_s + * + */ +struct imu_raw_s { + double x; + double y; + double z; +}; + +/** + * \struct imu_gyro_s_t + * + */ +typedef struct imu_raw_s imu_gyro_s_t; + +/** + * \struct imu_accel_s_t + * + */ +typedef struct imu_raw_s imu_accel_s_t; + +/** + * \struct euler_s_t + * + */ +typedef struct __attribute__((__packed__)) euler_s { + double pitch; + double roll; + double yaw; +} euler_s_t; + +#ifdef __cplusplus +namespace c { +#endif +/** + * \def IMU_MINIMUM_DATA_RATE + */ +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define IMU_STATUS_CALIBRATING pros::E_IMU_STATUS_CALIBRATING +#define IMU_STATUS_ERROR pros::E_IMU_STATUS_ERROR +#else +#define IMU_STATUS_CALIBRATING E_IMU_STATUS_CALIBRATING +#define IMU_STATUS_ERROR E_IMU_STATUS_ERROR +#endif +#endif + +#define IMU_MINIMUM_DATA_RATE 5 + +/** + * Calibrate IMU + * + * Calibration takes approximately 2 seconds, but this function only blocks + * until the IMU status flag is set properly to E_IMU_STATUS_CALIBRATING, + * with a minimum blocking time of 5ms. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is already calibrating, or time out setting the status flag. + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void initialize() { + * imu_reset(IMU_PORT); + * int time = millis(); + * int iter = 0; + * while (imu_get_status(IMU_PORT) & E_IMU_STATUS_CALIBRATING) { + * printf("IMU calibrating... %d\n", iter); + * iter += 10; + * delay(10); + * } + * // should print about 2000 ms + * printf("IMU is done calibrating (took %d ms)\n", iter - time); + * } + * \endcode + */ +int32_t imu_reset(uint8_t port); + +/** + * Calibrate IMU and Blocks while Calibrating + * + * Calibration takes approximately 2 seconds and blocks during this period, + * with a timeout for this operation being set a 3 seconds as a safety margin. + * Like the other reset function, this function also blocks until the IMU + * status flag is set properly to E_IMU_STATUS_CALIBRATING, with a minimum + * blocking time of 5ms and a timeout of 1 second if it's never set. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is already calibrating, or time out setting the status flag. + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed (timing out or port claim failure), setting errno. + */ +int32_t imu_reset_blocking(uint8_t port); +/** + * Set the Inertial Sensor's refresh interval in milliseconds. + * + * The rate may be specified in increments of 5ms, and will be rounded down to + * the nearest increment. The minimum allowable refresh rate is 5ms. The default + * rate is 10ms. + * + * As values are copied into the shared memory buffer only at 10ms intervals, + * setting this value to less than 10ms does not mean that you can poll the + * sensor's values any faster. However, it will guarantee that the data is as + * recent as possible. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param rate The data refresh interval in milliseconds + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * \endcode + */ +int32_t imu_set_data_rate(uint8_t port, uint32_t rate); + +/** + * Get the total number of degrees the Inertial Sensor has spun about the z-axis + * + * This value is theoretically unbounded. Clockwise rotations are represented + * with positive degree values, while counterclockwise rotations are represented + * with negative ones. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The degree value or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("IMU get rotation: %f degrees\n", imu_get_rotation(IMU_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double imu_get_rotation(uint8_t port); + +/** + * Get the Inertial Sensor's heading relative to the initial direction of its + * x-axis + * + * This value is bounded by [0,360). Clockwise rotations are represented with + * positive degree values, while counterclockwise rotations are represented with + * negative ones. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The degree value or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("IMU get heading: %f degrees\n", imu_get_heading(IMU_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double imu_get_heading(uint8_t port); + +/** + * Get a quaternion representing the Inertial Sensor's orientation + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The quaternion representing the sensor's orientation. If the + * operation failed, all the quaternion's members are filled with PROS_ERR_F and + * errno is set. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * quaternion_s_t qt = imu_get_quaternion(IMU_PORT); + * printf("IMU quaternion: {x: %f, y: %f, z: %f, w: %f}\n", qt.x, qt.y, qt.z, qt.w); + * delay(20); + * } + * } + * \endcode + */ +quaternion_s_t imu_get_quaternion(uint8_t port); + +/** + * Get the Euler angles representing the Inertial Sensor's orientation + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The Euler angles representing the sensor's orientation. If the + * operation failed, all the structure's members are filled with PROS_ERR_F and + * errno is set. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * euler_s_t eu = imu_get_euler(IMU_PORT); + * printf("IMU euler angles: {pitch: %f, roll: %f, yaw: %f}\n", eu.pitch, eu.roll, eu.yaw); + * delay(20); + * } + * } + * \endcode + */ +euler_s_t imu_get_euler(uint8_t port); + +/** + * Get the Inertial Sensor's raw gyroscope values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The pitch angle, or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("IMU pitch: %f\n", imu_get_pitch(IMU_PORT)); + * delay(20); + * } + * } + * \endcode + */ +imu_gyro_s_t imu_get_gyro_rate(uint8_t port); + +/** + * Get the Inertial Sensor's raw acceleroneter values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The roll angle, or PROS_ERR_F if the operation failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("IMU roll: %f\n", imu_get_roll(IMU_PORT)); + * delay(20); + * } + * } + * \endcode + */ +imu_accel_s_t imu_get_accel(uint8_t port); + +/** + * Get the Inertial Sensor's status + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The yaw angle, or PROS_ERR_F if the operation failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("IMU yaw: %f\n", imu_get_yaw(IMU_PORT)); + * delay(20); + * } + * } + * \endcode + */ +imu_status_e_t imu_get_status(uint8_t port); + +// Value set functions: +/** + * Sets the current reading of the Inertial Sensor's euler values to + * target euler values. Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The raw gyroscope values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * int32_t val = imu_set_euler(IMU_PORT, {45, 60, 90}); + * printf("IMU : {gyro vals: %d}\n", val); + * delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_euler(uint8_t port, euler_s_t target); + +/** + * Get the Inertial Sensor's pitch angle bounded by (-180,180) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The raw accelerometer values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * imu_accel_s_t accel = imu_get_accel(IMU_PORT); + * printf("IMU accel values: {x: %f, y: %f, z: %f}\n", accel.x, accel.y, accel.z); + * delay(20); + * } + * } + * \endcode + */ +double imu_get_pitch(uint8_t port); + +/** + * Get the Inertial Sensor's roll angle bounded by (-180,180) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The Inertial Sensor's status code, or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void initialize() { + * imu_reset(IMU_PORT); + * int time = millis(); + * int iter = 0; + * while (imu_get_status(IMU_PORT) & E_IMU_STATUS_CALIBRATING) { + * printf("IMU calibrating... %d\n", iter); + * iter += 10; + * delay(10); + * } + * // should print about 2000 ms + * printf("IMU is done calibrating (took %d ms)\n", iter - time); + * } + * \endcode + */ +double imu_get_roll(uint8_t port); + +/** + * Get the Inertial Sensor's yaw angle bounded by (-180,180) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The yaw angle, or PROS_ERR_F if the operation failed, setting errno. + */ +double imu_get_yaw(uint8_t port); + +// NOTE: not used +// void imu_set_mode(uint8_t port, uint32_t mode); +// uint32_t imu_get_mode(uint8_t port); + +/** + * \name Value Reset Functions + * @{ + */ + +/** + * Resets the current reading of the Inertial Sensor's heading to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_heading(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_heading(uint8_t port); + +/** + * Resets the current reading of the Inertial Sensor's rotation to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_rotation(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_rotation(uint8_t port); + +/** + * Resets the current reading of the Inertial Sensor's pitch to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_pitch(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_pitch(uint8_t port); + +/** + * Resets the current reading of the Inertial Sensor's roll to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_roll(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_roll(uint8_t port); + +/** + * Resets the current reading of the Inertial Sensor's yaw to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_yaw(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_yaw(uint8_t port); + +/** + * Reset all 3 euler values of the Inertial Sensor to 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_euler(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_euler(uint8_t port); + +/** + * Resets all 5 values of the Inertial Sensor to 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare(uint8_t port); + +/** @} */ + +/** + * \name Value Set Functions + * @{ + */ + +/** + * Sets the current reading of the Inertial Sensor's euler values to + * target euler values. Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target euler values for the euler values to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_euler(IMU_PORT, {45,45,45}); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_euler(uint8_t port, euler_s_t target); + +/** + * Sets the current reading of the Inertial Sensor's rotation to target value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the rotation value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_rotation(IMU_PORT, 45); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_rotation(uint8_t port, double target); + +/** + * Sets the current reading of the Inertial Sensor's heading to target value + * Target will default to 360 if above 360 and default to 0 if below 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the heading value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_heading(IMU_PORT, 45); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_heading(uint8_t port, double target); + +/** + * Sets the current reading of the Inertial Sensor's pitch to target value + * Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the pitch value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_pitch(IMU_PORT, 45); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_pitch(uint8_t port, double target); + +/** + * Sets the current reading of the Inertial Sensor's roll to target value + * Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the roll value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_roll(IMU_PORT, 45); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_roll(uint8_t port, double target); + +/** + * Sets the current reading of the Inertial Sensor's yaw to target value + * Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the yaw value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1void opcontrol() { + * + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_yaw(IMU_PORT, 45); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_yaw(uint8_t port, double target); + +/** + * Returns the physical orientation of the IMU + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \returns The orientation of the Inertial Sensor or PROS_ERR if an error occured. + * + */ +imu_orientation_e_t imu_get_physical_orientation(uint8_t port); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +} +} +#endif + +#endif diff --git a/test/include/pros/imu.hpp b/test/include/pros/imu.hpp new file mode 100644 index 00000000..c98e42ad --- /dev/null +++ b/test/include/pros/imu.hpp @@ -0,0 +1,1077 @@ +/** + * \file pros/imu.hpp + * \ingroup cpp-imu + * + * Contains prototypes for functions related to the VEX Inertial sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-imu VEX Inertial Sensor C++ API + */ +#ifndef _PROS_IMU_HPP_ +#define _PROS_IMU_HPP_ + +#include +#include + +#include "pros/device.hpp" +#include "pros/imu.h" + +namespace pros { +/** + * \ingroup cpp-imu + * */ + +/** + * \addtogroup cpp-imu + * @{ + */ + +/** + * \enum Imu_Status + * @brief Indicates IMU status. + */ + +enum class ImuStatus { + ready = 0, + /** The IMU is calibrating */ + calibrating = 19, + /** Used to indicate that an error state was reached in the imu_get_status function,\ + not that the IMU is necessarily in an error state */ + error = 0xFF, +}; + +inline namespace v5 { +/** + * \ingroup cpp-imu + */ +class Imu : public Device { + /** + * \addtogroup cpp-imu + * @{ + */ + + public: + /** + * Creates an Imu object for the given port + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Do something with the sensor data + * } + * } + * \endcode + */ + + + Imu(const std::uint8_t port) : Device(port, DeviceType::imu){}; + + Imu(const Device& device) : Imu(device.get_port()){}; + + /** + * Gets a IMU sensor that is plugged in to the brain + * + * \note The first time this function is called it returns the IMU sensor at the lowest port + * If this function is called multiple times, it will cycle through all the ports. + * For example, if you have 1 IMU sensor on the robot + * this function will always return a IMU sensor object for that port. + * If you have 2 IMU sensors, all the odd numered calls to this function will return objects + * for the lower port number, + * all the even number calls will return IMU objects for the higher port number + * + * + * This functions uses the following values of errno when an error state is + * reached: + * ENODEV - No IMU sensor is plugged into the brain + * + * \return A IMU object corresponding to a port that a IMU sensor is connected to the brain + * If no IMU sensor is plugged in, it returns a IMU sensor on port PROS_ERR_BYTE + * + */ + static Imu get_imu(); + /** + * Calibrate IMU + * + * Calibration takes approximately 2 seconds and blocks during this period if + * the blocking param is true, with a timeout for this operation being set a 3 + * seconds as a safety margin. This function also blocks until the IMU + * status flag is set properly to E_IMU_STATUS_CALIBRATING, with a minimum + * blocking time of 5ms and a timeout of 1 second if it's never set. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is already calibrating, or time out setting the status flag. + * + * \param blocking + * Whether this function blocks during calibration. + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * // Block until calibration is complete + * imu.reset(true); + * } + * \endcode + */ + virtual std::int32_t reset(bool blocking = false) const; + /** + * Set the Inertial Sensor's refresh interval in milliseconds. + * + * The rate may be specified in increments of 5ms, and will be rounded down to + * the nearest increment. The minimum allowable refresh rate is 5ms. The default + * rate is 10ms. + * + * As values are copied into the shared memory buffer only at 10ms intervals, + * setting this value to less than 10ms does not mean that you can poll the + * sensor's values any faster. However, it will guarantee that the data is as + * recent as possible. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param rate The data refresh interval in milliseconds + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the refresh rate to 5ms + * std::int32_t status = imu.set_data_rate(5); + * delay(20); + * + * // Check if the operation was successful + * if (status == PROS_ERR) { + * // Do something with the error + * } + * + * // Do something with the sensor data + * } + * } + * \endcode + */ + virtual std::int32_t set_data_rate(std::uint32_t rate) const; + + + /** + * Gets all IMU sensors. + * + * \return A vector of Imu sensor objects. + * + * \b Example + * \code + * void opcontrol() { + * std::vector imu_all = pros::Imu::get_all_devices(); // All IMU sensors that are connected + * } + * \endcode + */ + + static std::vector get_all_devices(); + + /** + * Get the total number of degrees the Inertial Sensor has spun about the z-axis + * + * This value is theoretically unbounded. Clockwise rotations are represented + * with positive degree values, while counterclockwise rotations are represented + * with negative ones. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The degree value or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Get the total number of degrees the sensor has spun + * printf("Total rotation: %f\n", imu.get_rotation()); + * delay(20); + * } + * } + * \endcode + */ + virtual double get_rotation() const; + /** + * Get the Inertial Sensor's heading relative to the initial direction of its + * x-axis + * + * This value is bounded by [0,360). Clockwise rotations are represented with + * positive degree values, while counterclockwise rotations are represented with + * negative ones. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The degree value or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Get the sensor's heading + * printf("Heading: %f\n", imu.get_heading()); + * delay(20); + * } + * } + * \endcode + */ + virtual double get_heading() const; + /** + * Get a quaternion representing the Inertial Sensor's orientation + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The quaternion representing the sensor's orientation. If the + * operation failed, all the quaternion's members are filled with PROS_ERR_F and + * errno is set. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Get the sensor's quaternion + * pros::quaternion_s_t quat = imu.get_quaternion(); + * cout << "Quaternion: " << quat.w << ", " << quat.x << ", " << quat.y << ", " << quat.z << endl; + * delay(20); + * } + * } + * \endcode + */ + virtual pros::quaternion_s_t get_quaternion() const; + /** + * Get the Euler angles representing the Inertial Sensor's orientation + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The Euler angles representing the sensor's orientation. If the + * operation failed, all the structure's members are filled with PROS_ERR_F and + * errno is set. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Get the sensor's Euler angles + * pros::euler_s_t euler = imu.get_euler(); + * cout << "Euler: " << euler.roll << ", " << euler.pitch << ", " << euler.yaw << endl; + * delay(20); + * } + * } + * \endcode + */ + virtual pros::euler_s_t get_euler() const; + /** + * Get the Inertial Sensor's pitch angle bounded by (-180,180) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The pitch angle, or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Get the sensor's pitch + * printf("Pitch: %f\n", imu.get_pitch()); + * delay(20); + * } + * } + * \endcode + */ + virtual double get_pitch() const; + /** + * Get the Inertial Sensor's roll angle bounded by (-180,180) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The roll angle, or PROS_ERR_F if the operation failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Get the sensor's roll + * printf("Roll: %f\n", imu.get_roll()); + * delay(20); + * } + * } + * \endcode + */ + virtual double get_roll() const; + /** + * Get the Inertial Sensor's yaw angle bounded by (-180,180) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The yaw angle, or PROS_ERR_F if the operation failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Get the sensor's yaw + * printf("Yaw: %f\n", imu.get_yaw()); + * delay(20); + * } + * } + * \endcode + */ + virtual double get_yaw() const; + /** + * Get the Inertial Sensor's raw gyroscope values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The raw gyroscope values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Get the sensor's raw gyroscope values + * pros::imu_gyro_s_t gyro = imu.get_gyro_rate(); + * cout << "Gyro: " << gyro.x << ", " << gyro.y << ", " << gyro.z << endl; + * delay(20); + * } + * } + * \endcode + */ + virtual pros::imu_gyro_s_t get_gyro_rate() const; + /** + * Resets the current reading of the Inertial Sensor's rotation to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's rotation value to 10 + * imu.set_rotation(10); + * delay(20); + * + * // Do something with sensor + * + * // Reset the sensor's rotation value to 0 + * imu.tare_rotation(); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t tare_rotation() const; + /** + * Resets the current reading of the Inertial Sensor's heading to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's heading value to 10 + * imu.set_heading(10); + * delay(20); + * + * // Do something with sensor + * + * // Reset the sensor's heading value to 0 + * imu.tare_heading(); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t tare_heading() const; + /** + * Resets the current reading of the Inertial Sensor's pitch to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's pitch value to 10 + * imu.set_pitch(10); + * delay(20); + * + * // Do something with sensor + * + * // Reset the sensor's pitch value to 0 + * imu.tare_pitch(); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t tare_pitch() const; + /** + * Resets the current reading of the Inertial Sensor's yaw to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's yaw value to 10 + * imu.set_yaw(10); + * delay(20); + * + * // Do something with sensor + * + * // Reset the sensor's yaw value to 0 + * imu.tare_yaw(); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t tare_yaw() const; + /** + * Resets the current reading of the Inertial Sensor's roll to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's roll value to 10 + * imu.set_roll(10); + * delay(20); + * + * // Do something with sensor + * + * // Reset the sensor's roll value to 0 + * imu.tare_roll(); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t tare_roll() const; + /** + * Resets all 5 values of the Inertial Sensor to 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Reset all values of the sensor to 0 + * imu.tare(); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t tare() const; + /** + * Reset all 3 euler values of the Inertial Sensor to 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Reset all euler values of the sensor to 0 + * imu.tare_euler(); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t tare_euler() const; + /** + * Sets the current reading of the Inertial Sensor's heading to target value + * Target will default to 360 if above 360 and default to 0 if below 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the heading value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's heading value to 10 + * imu.set_heading(10); + * delay(20); + * + * // Do something with sensor + * } + * } + * \endcode + */ + virtual std::int32_t set_heading(const double target) const; + /** + * Sets the current reading of the Inertial Sensor's rotation to target value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the rotation value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's rotation value to 10 + * imu.set_rotation(10); + * delay(20); + * + * // Do something with sensor + * } + * } + * \endcode + */ + virtual std::int32_t set_rotation(const double target) const; + /** + * Sets the current reading of the Inertial Sensor's yaw to target value + * Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for yaw value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's yaw value to 10 + * imu.set_yaw(10); + * delay(20); + * + * // Do something with sensor + * } + * } + * \endcode + */ + virtual std::int32_t set_yaw(const double target) const; + /** + * Sets the current reading of the Inertial Sensor's pitch to target value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the pitch value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's pitch value to 10 + * imu.set_pitch(10); + * delay(20); + * + * // Do something with sensor + * } + * } + * \endcode + */ + virtual std::int32_t set_pitch(const double target) const; + /** + * Sets the current reading of the Inertial Sensor's roll to target value + * Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target euler values for the euler values to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's roll value to 100 + * imu.set_roll(100); + * delay(20); + * + * // Do something with sensor + * } + * } + * \endcode + */ + virtual std::int32_t set_roll(const double target) const; + /** + * Sets the current reading of the Inertial Sensor's euler values to + * target euler values. Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target euler values for the euler values to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Set the sensor's euler values to 50 + * imu.set_euler(50); + * delay(20); + * + * // Do something with sensor + * } + * } + * \endcode + */ + virtual std::int32_t set_euler(const pros::euler_s_t target) const; + /** + * Get the Inertial Sensor's raw accelerometer values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The raw accelerometer values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Get the sensor's raw accelerometer values + * pros::imu_accel_s_t accel = imu.get_accel(); + * printf("x: %f, y: %f, z: %f\n", accel.x, accel.y, accel.z); + * delay(20); + * + * // Do something with sensor + * } + * } + * \endcode + */ + virtual pros::imu_accel_s_t get_accel() const; + /** + * Get the Inertial Sensor's status + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The Inertial Sensor's status code, or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Get the sensor's status + * pros::ImuStatus status = imu.get_status(); + * cout << "Status: " << status << endl; + * delay(20); + * + * // Do something with sensor + * } + * } + * \endcode + */ + virtual pros::ImuStatus get_status() const; + /** + * Check whether the IMU is calibrating + * + * \return true if the V5 Inertial Sensor is calibrating or false + * false if it is not. + * + * \b Example + * \code + * + * #define IMU_PORT 1 + * + * void opcontrol() { + * pros::Imu imu(IMU_PORT); + * + * while (true) { + * // Calibrate the sensor + * imu.reset(); + * delay(20); + * + * // Check if the sensor is calibrating + * if (imu.is_calibrating()) { + * printf("Calibrating...\n"); + * } + * + * // Do something with sensor + * } + * } + * \endcode + */ + virtual bool is_calibrating() const; + /** + * Returns the physical orientation of the IMU + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \returns The physical orientation of the Inertial Sensor or PROS_ERR if an error occured. + * + */ + virtual imu_orientation_e_t get_physical_orientation() const; + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format(this below is all in one line with no new line): + * Imu [port: imu._port, rotation: (rotation), heading: (heading), + * pitch: (pitch angle), roll: (roll angle), yaw: (yaw angle), + * gyro rate: {x,y,z}, get accel: {x,y,z}, calibrating: (calibrating boolean)] + */ + friend std::ostream& operator<<(std::ostream& os, const pros::Imu& imu); + + ///@} +}; + +namespace literals { +/** + * Constructs a Imu from a literal ending in _imu via calling the constructor + * + * \return a pros::Imu for the corresponding port + * + * \b Example + * \code + * using namespace pros::literals; + * void opcontrol() { + * pros::Imu imu = 2_imu; //Makes an IMU object on port 2 + * } + * \endcode + */ +const pros::Imu operator""_imu(const unsigned long long int i); +} // namespace literals + +using IMU = Imu; +} // namespace v5 +} // namespace pros + +#endif diff --git a/test/include/pros/link.h b/test/include/pros/link.h new file mode 100644 index 00000000..e4a1472c --- /dev/null +++ b/test/include/pros/link.h @@ -0,0 +1,421 @@ +/** + * \file pros/link.h + * \ingroup c-link + * + * Contains prototypes for functions related to the robot to robot communications. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-link VEX Link C API + */ + +#ifndef _PROS_LINK_H_ +#define _PROS_LINK_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \ingroup c-link + * */ + +/** + * \addtogroup c-link + * @{ + */ + +/** + * \enum link_type_e_t + * \brief Enum for the type of link (TX or RX) + */ +typedef enum link_type_e { + E_LINK_RECIEVER = 0, ///< Indicates that the radio is a reciever. + E_LINK_TRANSMITTER, ///< Indicates that the link is a transmitter. + E_LINK_RX = E_LINK_RECIEVER, ///< Alias for E_LINK_RECIEVER + E_LINK_TX = E_LINK_TRANSMITTER ///< Alias for E_LINK_TRANSMITTER +} link_type_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define LINK_RECEIVER pros::E_LINK_RECEIVER +#define LINK_TRANSMITTER pros::E_LINK_TRANSMITTER +#define LINK_RX pros::E_LINK_RX +#define LINK_TX pros::E_LINK_TX +#else +#define LINK_RECEIVER E_LINK_RECEIVER +#define LINK_TRANSMITTER E_LINK_TRANSMITTER +#define LINK_RX E_LINK_RX +#define LINK_TX E_LINK_TX +#endif +#endif + +/// @brief +/// The maximum size of a link buffer +#define LINK_BUFFER_SIZE 512 + +#ifdef __cplusplus +namespace c { +#endif + +/** + * Initializes a link on a radio port, with an indicated type. There might be a + * 1 to 2 second delay from when this function is called to when the link is initializes. + * PROS currently only supports the use of one radio per brain. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \param port + * The port of the radio for the intended link. + * \param link_id + * Unique link ID in the form of a string, needs to be different from other links in + * the area. + * \param type + * Indicates whether the radio link on the brain is a transmitter or receiver, + * with the transmitter having double the transmitting bandwidth as the receiving + * end (1040 bytes/s vs 520 bytes/s). + * + * \return PROS_ERR if initialization fails, 1 if the initialization succeeds. + * + * \b Example + * \code + * #define LINK_TRANSMITTER_PORT 1 + * #define LINK_ID "ROBOT1" + * + * void initialize() { + * link_init(LINK_TRANSMITTER_PORT, LINK_ID, E_LINK_TRANSMITTER); + * } + * \endcode + */ +uint32_t link_init(uint8_t port, const char* link_id, link_type_e_t type); + +/** + * Initializes a link on a radio port, with an indicated type and the ability for + * vexlink to override the controller radio. There might be a 1 to 2 second delay + * from when this function is called to when the link is initializes. + * PROS currently only supports the use of one radio per brain. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \param port + * The port of the radio for the intended link. + * \param link_id + * Unique link ID in the form of a string, needs to be different from other links in + * the area. + * \param type + * Indicates whether the radio link on the brain is a transmitter or receiver, + * with the transmitter having double the transmitting bandwidth as the receiving + * end (1040 bytes/s vs 520 bytes/s). + * + * \return PROS_ERR if initialization fails, 1 if the initialization succeeds. + * + * \b Example + * \code + * #define LINK_PORT 1 + * #define LINK_ID "ROBOT1" + * + * void initialize() { + * link_init(LINK_PORT, LINK_ID, E_LINK_TRANSMITTER); + * link_init_override(LINK_PORT, LINK_ID, E_LINK_TRANSMITTER); + * } + * \endcode + */ +uint32_t link_init_override(uint8_t port, const char* link_id, link_type_e_t type); + +/** + * Checks if a radio link on a port is active or not. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \param port + * The port of the radio for the intended link. + * + * \return If a radio is connected to a port and it's connected to a link. + * + * \b Example + * \code + * #define LINK_TRANSMITTER_PORT 1 + * + * void opcontrol() { + * while (true) { + * if (link_connected(LINK_TRANSMITTER_PORT)) { + * screen_print(TEXT_MEDIUM, 1, "Link connected!"); + * } + * delay(20); + * } + * } + * \endcode + */ +bool link_connected(uint8_t port); + +/** + * Returns the bytes of data available to be read + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \param port + * The port of the radio for the intended link. + * + * \return PROS_ERR if port is not a link/radio, else the bytes available to be + * read by the user. + * + * \b Example + * \code + * #define LINK_RECIVER_PORT 1 + * + * void opcontrol() { + * while (true) { + * uint32_t receiveable_size = link_raw_receivable_size(LINK_RECIVER_PORT); + * screen_print(TEXT_MEDIUM, 1, "link_raw_receiveable_size: %d", receiveable_size); + * delay(20); + * } + * } + * \endcode + */ +uint32_t link_raw_receivable_size(uint8_t port); + +/** + * Returns the bytes of data available in transmission buffer. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \param port + * The port of the radio for the intended link. + * + * \return PROS_ERR if port is not a link/radio, + * + * \b Example + * \code + * #define LINK_TRANSMITTER_PORT 1 + * + * void opcontrol() { + * while (true) { + * uint32_t transmittable_size = link_raw_transmittable_size(LINK_TRANSMITTER_PORT); + * screen_print(TEXT_MEDIUM, 1, "link_raw_transmittable_size: %d", transmittable_size); + * delay(20); + * } + * } + * \endcode + */ +uint32_t link_raw_transmittable_size(uint8_t port); + +/** + * Send raw serial data through vexlink. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * EBUSY - The transmitter buffer is still busy with a previous transmission, and there is no + * room in the FIFO buffer (queue) to transmit the data. + * EINVAL - The data given is NULL + * + * \param port + * The port of the radio for the intended link. + * \param data + * Buffer with data to send + * \param data_size + * Bytes of data to be read to the destination buffer + * + * \return PROS_ERR if port is not a link, and the successfully transmitted + * data size if it succeeded. + * + * \b Example + * \code + * #define LINK_TRANSMITTER_PORT 1 + * + * void opcontrol() { + * while (true) { + * char* data = "Hello!"; + * link_transmit_raw(LINK_TRANSMITTER_PORT, (void*)data, sizeof(*data) * sizeof(data)); + * delay(20); + * } + * } + * \endcode + */ +uint32_t link_transmit_raw(uint8_t port, void* data, uint16_t data_size); + +/** + * Receive raw serial data through vexlink. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * EINVAL - The destination given is NULL, or the size given is larger than the FIFO buffer + * or destination buffer. + * + * \param port + * The port of the radio for the intended link. + * \param dest + * Destination buffer to read data to + * \param data_size + * Bytes of data to be read to the destination buffer + * + * \return PROS_ERR if port is not a link, and the successfully received + * data size if it succeeded. + * + * \b Example + * \code + * #define LINK_RECIVER_PORT 1 + * + * void opcontrol() { + * while (true) { + * char* result; + * char* expected = "Hello!"; + * link_receive_raw(LINK_RECIVER_PORT, (void*)result, sizeof(*expected) * sizeof(expected)); + * delay(20); + * } + * } + * \endcode + */ +uint32_t link_receive_raw(uint8_t port, void* dest, uint16_t data_size); + +/** + * Send packeted message through vexlink, with a checksum and start byte. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * EBUSY - The transmitter buffer is still busy with a previous transmission, and there is no + * room in the FIFO buffer (queue) to transmit the data. + * EINVAL - The data given is NULL + * + * \param port + * The port of the radio for the intended link. + * \param data + * Buffer with data to send + * \param data_size + * Bytes of data to be read to the destination buffer + * + * \return PROS_ERR if port is not a link, and the successfully transmitted + * data size if it succeeded. + * + * \b Example + * \code + * #define LINK_TRANSMITTER_PORT 1 + * + * void opcontrol() { + * while (true) { + * char* data = "Hello!"; + * link_transmit(LINK_TRANSMITTER_PORT, (void*)data, sizeof(*data) * sizeof(data)); + * delay(20); + * } + * } + * \endcode + */ +uint32_t link_transmit(uint8_t port, void* data, uint16_t data_size); + +/** + * Receive packeted message through vexlink, with a checksum and start byte. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * EINVAL - The destination given is NULL, or the size given is larger than the FIFO buffer + * or destination buffer. + * EBADMSG - Protocol error related to start byte, data size, or checksum. + * + * \param port + * The port of the radio for the intended link. + * \param dest + * Destination buffer to read data to + * \param data_size + * Bytes of data to be read to the destination buffer + * + * \return PROS_ERR if port is not a link or protocol error, and the successfully + * transmitted data size if it succeeded. + * + * \b Example + * \code + * #define LINK_RECIVER_PORT 1 + * + * void opcontrol() { + * while (true) { + * char* result; + * char* expected = "Hello!"; + * link_receive(LINK_RECIVER_PORT, (void*)result, sizeof(*expected) * sizeof(expected)); + * delay(20); + * } + * } + * \endcode + */ +uint32_t link_receive(uint8_t port, void* dest, uint16_t data_size); + +/** + * Clear the receive buffer of the link, and discarding the data. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \param port + * The port of the radio for the intended link. + * + * \return PROS_ERR if port is not a link, and the successfully received + * data size if it succeeded. + * + * \b Example + * \code + * #define LINK_TRANSMITTER_PORT 1 + * + * void opcontrol() { + * while (true) { + * char* data = "Hello!"; + * link_transmit(LINK_TRANSMITTER_PORT, (void*)data, sizeof(*data) * sizeof(data)); + * link_clear_receive_buf(LINK_TRANSMITTER_PORT); + * delay(20); + * } + * } + * \endcode + */ +uint32_t link_clear_receive_buf(uint8_t port); + +///@} + +#ifdef __cplusplus +} +} +} +#endif + +#endif diff --git a/test/include/pros/link.hpp b/test/include/pros/link.hpp new file mode 100644 index 00000000..995d433b --- /dev/null +++ b/test/include/pros/link.hpp @@ -0,0 +1,283 @@ +/** + * \file pros/link.hpp + * \ingroup cpp-link + * + * Contains prototypes for functions related to robot to robot communications. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-link VEX Link C++ API + */ +#ifndef _PROS_LINK_HPP_ +#define _PROS_LINK_HPP_ + +#include +#include + +#include "pros/link.h" +#include "pros/device.hpp" + +namespace pros { +/** + * \ingroup cpp-link + */ +class Link : public Device { + /** + * \addtogroup cpp-link + * ///@{ + */ + private: + + public: + /** + * Initializes a link on a radio port, with an indicated type. There might be a + * 1 to 2 second delay from when this function is called to when the link is initializes. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \param port + * The port of the radio for the intended link. + * \param link_id + * Unique link ID in the form of a string, needs to be different from other links in + * the area. + * \param type + * Indicates whether the radio link on the brain is a transmitter or receiver, + * with the transmitter having double the transmitting bandwidth as the receiving + * end (1040 bytes/s vs 520 bytes/s). + * \param ov + * Indicates if the radio on the given port needs vexlink to override the controller radio. Defualts to True. + * + * \return PROS_ERR if initialization fails, 1 if the initialization succeeds. + * + * \b Example: + * \code + * pros::Link link(1, "my_link", pros::E_LINK_TX); + * \endcode + */ + explicit Link(const std::uint8_t port, const std::string link_id, link_type_e_t type, bool ov = true); + + /** + * Checks if a radio link on a port is active or not. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \return If a radio is connected to a port and it's connected to a link. + * + * \b Example: + * \code + * pros::Link link(1, "my_link", pros::E_LINK_TX); + * if (link.connected()) { + * // do something + * } + * \endcode + */ + bool connected(); + + /** + * Returns the bytes of data number of without protocol available to be read + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \return PROS_ERR if port is not a link/radio, else the bytes available to be + * read by the user. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Link link(1, "my_link", pros::E_LINK_TX); + * printf("Bytes available to read: %d", link.receivable_size()); + * } + * \endcode + */ + std::uint32_t raw_receivable_size(); + + /** + * Returns the bytes of data available in transmission buffer. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \return PROS_ERR if port is not a link/radio, + * else the bytes available to be transmitted by the user. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Link link(1, "my_link", pros::E_LINK_TX); + * printf("Bytes available to transmit: %d", link.transmittable_size()); + * } + */ + std::uint32_t raw_transmittable_size(); + + /** + * Send raw serial data through vexlink. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * EBUSY - The transmitter buffer is still busy with a previous transmission, and there is no + * room in the FIFO buffer (queue) to transmit the data. + * EINVAL - The data given is NULL + * + * \param data + * Buffer with data to send + * \param data_size + * Buffer with data to send + * + * \return PROS_ERR if port is not a link, and the successfully transmitted + * data size if it succeeded. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Link link(1, "my_link", pros::E_LINK_TX); + * std::uint8_t data[4] = {0x01, 0x02, 0x03, 0x04}; + * link.transmit_raw(data, 4); + * } + * + * \endcode + */ + std::uint32_t transmit_raw(void* data, std::uint16_t data_size); + + /** + * Receive raw serial data through vexlink. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * EINVAL - The destination given is NULL, or the size given is larger than the FIFO buffer + * or destination buffer. + * + * \param dest + * Destination buffer to read data to + * \param data_size + * Bytes of data to be read to the destination buffer + * + * \return PROS_ERR if port is not a link, and the successfully received + * data size if it succeeded. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Link link(1, "my_link", pros::E_LINK_TX); + * std::uint8_t data[4]; + * link.receive_raw(data, 4); + * } + * \endcode + */ + std::uint32_t receive_raw(void* dest, std::uint16_t data_size); + + /** + * Send packeted message through vexlink, with a checksum and start byte. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * EBUSY - The transmitter buffer is still busy with a previous transmission, and there is no + * room in the FIFO buffer (queue) to transmit the data. + * EINVAL - The data given is NULL + * + * \param data + * Buffer with data to send + * \param data_size + * Bytes of data to be read to the destination buffer + * + * \return PROS_ERR if port is not a link, and the successfully transmitted + * data size if it succeeded. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Link link(1, "my_link", pros::E_LINK_TX); + * std::uint8_t data[4] = {0x01, 0x02, 0x03, 0x04}; + * link.transmit(data, 4); + * } + * \endcode + */ + std::uint32_t transmit(void* data, std::uint16_t data_size); + + /** + * Receive packeted message through vexlink, with a checksum and start byte. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * EINVAL - The destination given is NULL, or the size given is larger than the FIFO buffer + * or destination buffer. + * EBADMSG - Protocol error related to start byte, data size, or checksum. + + * \param dest + * Destination buffer to read data to + * \param data_size + * Bytes of data to be read to the destination buffer + * + * \return PROS_ERR if port is not a link, and the successfully received + * data size if it succeeded. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Link link(1, "my_link", pros::E_LINK_TX); + * std::uint8_t data[4]; + * link.receive(data, 4); + * } + * \endcode + */ + std::uint32_t receive(void* dest, std::uint16_t data_size); + + /** + * Clear the receive buffer of the link, and discarding the data. + * + * \note This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a radio. + * ENXIO - The sensor is still calibrating, or no link is connected via the radio. + * + * \return PROS_ERR if port is not a link, 1 if the operation succeeded. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Link link(1, "my_link", pros::E_LINK_TX); + * link.clear_receive_buf(); + * } + * \endcode + */ + std::uint32_t clear_receive_buf(); + + ///@} +}; +} // namespace pros + +#endif diff --git a/test/include/pros/llemu.h b/test/include/pros/llemu.h new file mode 100644 index 00000000..1f3ee4a3 --- /dev/null +++ b/test/include/pros/llemu.h @@ -0,0 +1,55 @@ +#ifndef _PROS_LLEMU_H_ +#define _PROS_LLEMU_H_ + +// TODO:? Should there be weak symbols for the C api in here as well? + +#include "stdbool.h" +#include "stdint.h" + +/******************************************************************************/ +/** LLEMU Conditional Include **/ +/** **/ +/** When the libvgl versions of llemu.h is present, common.mk will **/ +/** define a macro which lets this file know that liblvgl's llemu.h is **/ +/** present. If it is, we conditionally include it so that it gets **/ +/** included into api.h. **/ +/******************************************************************************/ +#ifdef _PROS_INCLUDE_LIBLVGL_LLEMU_H +#include "liblvgl/llemu.h" +#endif + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif//__cplusplus + +/** + * Displays a formatted string on the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line on which to display the text [0-7] + * \param fmt + * Format string + * \param ... + * Optional list of arguments for the format string + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + */ +bool __attribute__((weak)) lcd_print(__attribute__((unused)) int16_t line, __attribute__((unused)) const char* fmt, ...) { + return false; +} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} // extern "C" +#endif//__cplusplus + +#endif // _PROS_LLEMU_H_ diff --git a/test/include/pros/llemu.hpp b/test/include/pros/llemu.hpp new file mode 100644 index 00000000..6e860176 --- /dev/null +++ b/test/include/pros/llemu.hpp @@ -0,0 +1,147 @@ +/** + * \file pros/llemu.hpp + * \ingroup cpp-llemu + * + * Legacy LCD Emulator + * + * \details This file defines a high-level API for emulating the three-button, UART-based + * VEX LCD, containing a set of functions that facilitate the use of a software- + * emulated version of the classic VEX LCD module. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef _PROS_LLEMU_HPP_ +#define _PROS_LLEMU_HPP_ + +#include +#include + +/******************************************************************************/ +/** LLEMU Conditional Include **/ +/** **/ +/** When the libvgl versions of llemu.hpp is present, common.mk will **/ +/** define a macro which lets this file know that liblvgl's llemu.hpp is **/ +/** present. If it is, we conditionally include it so that it gets **/ +/** included into api.h. **/ +/******************************************************************************/ +#ifdef _PROS_INCLUDE_LIBLVGL_LLEMU_HPP +#include "liblvgl/llemu.hpp" +#endif + +/******************************************************************************/ +/** LLEMU Weak Stubs **/ +/** **/ +/** These functions allow main.cpp to be compiled without LVGL present **/ +/******************************************************************************/ + +namespace pros { + +/** + * \ingroup cpp-llemu + */ +#if defined(_PROS_KERNEL_SUPPRESS_LLEMU_WARNING) || defined(_PROS_INCLUDE_LIBLVGL_LLEMU_HPP) +namespace lcd { +#else +namespace [[deprecated("Without liblvgl, LLEMU functions will not display anything. To install liblvgl run \"pros c install liblvgl\" in the PROS terminal.")]] lcd { +#endif + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" + namespace { + template + T convert_args(T arg) { + return arg; + } + const char* convert_args(const std::string& arg) { + return arg.c_str(); + } + } // namespace + #pragma GCC diagnostic pop + + using lcd_btn_cb_fn_t = void (*)(void); + + /* + * These weak symbols allow the example main.cpp in to compile even when + * the liblvgl template is missing from the project. + * + * For documentation on these functions, please see the doxygen comments for + * these functions in the libvgl llemu headers. + */ + extern __attribute__((weak)) bool is_initialized(void); + extern __attribute__((weak)) bool initialize(void); + extern __attribute__((weak)) bool shutdown(void); + extern __attribute__((weak)) bool set_text(std::int16_t line, std::string text); + extern __attribute__((weak)) bool clear(void); + extern __attribute__((weak)) bool clear_line(std::int16_t line); + // TODO: Text_Align is defined in liblvgl so this ain't going to compile for now. + // extern __attribute__((weak)) void set_text_align(Text_Align text_align); + extern __attribute__((weak)) void register_btn0_cb(lcd_btn_cb_fn_t cb); + extern __attribute__((weak)) void register_btn1_cb(lcd_btn_cb_fn_t cb); + extern __attribute__((weak)) void register_btn2_cb(lcd_btn_cb_fn_t cb); + extern __attribute__((weak)) std::uint8_t read_buttons(void); + + /** + * \addtogroup cpp-llemu + * @{ + */ + + /* + * Note: This template resides in this file since the + */ + + /** + * Displays a formatted string on the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line on which to display the text [0-7] + * \param fmt + * Format string + * \param ...args + * Optional list of arguments for the format string + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::print(0, "My formatted text: %d!", 2); + * } + * \endcode + */ + template + bool print(std::int16_t line, const char* fmt, Params... args) { + return pros::c::lcd_print(line, fmt, convert_args(args)...); + } + + #ifndef LCD_BTN_LEFT + #define LCD_BTN_LEFT 4 + #endif + + #ifndef LCD_BTN_CENTER + #define LCD_BTN_CENTER 2 + #endif + + #ifndef LCD_BTN_RIGHT + #define LCD_BTN_RIGHT 1 + #endif + /// @} +} // namespace lcd +} // namespace pros + +#endif // _PROS_LLEMU_HPP_ diff --git a/test/include/pros/misc.h b/test/include/pros/misc.h new file mode 100644 index 00000000..8123fbfd --- /dev/null +++ b/test/include/pros/misc.h @@ -0,0 +1,876 @@ +/** + * \file pros/misc.h + * \ingroup c-misc + * + * Contains prototypes for miscellaneous functions pertaining to the controller, + * battery, and competition control. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reservered. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-misc Miscellaneous C API + * \note Additional example code for this module can be found in its [Tutorial.](@ref controller) + */ + +#ifndef _PROS_MISC_H_ +#define _PROS_MISC_H_ + +#include + +#define NUM_V5_PORTS (22) + +/** + * \ingroup c-misc + */ + +/** + * \addtogroup c-misc + * @{ + */ + +/// \name V5 Competition +//@{ + +/*#define COMPETITION_DISABLED (1 << 0) +#define COMPETITION_AUTONOMOUS (1 << 1) +#define COMPETITION_CONNECTED (1 << 2) +#define COMPETITION_SYSTEM (1 << 3)*/ +typedef enum { + COMPETITION_DISABLED = 1 << 0, + COMPETITION_CONNECTED = 1 << 2, + COMPETITION_AUTONOMOUS = 1 << 1, + COMPETITION_SYSTEM = 1 << 3, +} competition_status; + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \fn competition_get_status(void) + * Get the current status of the competition control. + * + * \return The competition control status as a mask of bits with + * COMPETITION_{ENABLED,AUTONOMOUS,CONNECTED}. + * + * \b Example + * \code + * void initialize() { + * if (competition_get_status() & COMPETITION_CONNECTED == true) { + * // Field Control is Connected + * // Run LCD Selector code or similar + * } + * } + * \endcode + */ +uint8_t competition_get_status(void); + +/** + * \fn competition_is_disabled() + * + * \return True if the V5 Brain is disabled, false otherwise. + * + * \b Example + * \code + * void my_task_fn(void* ignore) { + * while (!competition_is_disabled()) { + * // Run competition tasks (like Lift Control or similar) + * } + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIO_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * \endcode + */ +uint8_t competition_is_disabled(void); + +/** + * \return True if the V5 Brain is connected to competition control, false otherwise. + * + * \b Example + * \code + * void initialize() { + * if (competition_is_connected()) { + * // Field Control is Connected + * // Run LCD Selector code or similar + * } + * } + * \endcode + */ +uint8_t competition_is_connected(void); + +/** + * \return True if the V5 Brain is in autonomous mode, false otherwise. + * + * \b Example + * \code + * void my_task_fn(void* ignore) { + * while (!competition_is_autonomous()) { + * // Wait to do anything until autonomous starts + * delay(2); + * } + * while (competition_is_autonomous()) { + * // Run whatever code is desired to just execute in autonomous + * } + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIO_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * \endcode + */ +uint8_t competition_is_autonomous(void); + +/** + * \return True if the V5 Brain is connected to VEXnet Field Controller, false otherwise. + * + * \b Example + * \code + * void initialize() { + * if (competition_is_field()) { + * // connected to VEXnet Field Controller + * } + * } + * \endcode + */ +uint8_t competition_is_field(void); + +/** + * \return True if the V5 Brain is connected to VEXnet Competition Switch, false otherwise. + * + * \b Example + * \code + * void initialize() { + * if (competition_is_switch()) { + * // connected to VEXnet Competition Switch + * } + * } + */ +uint8_t competition_is_switch(void); + +#ifdef __cplusplus +} +} +} +#endif +///@} + +/// \name V5 Controller +///@{ +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \enum + */ +typedef enum { + /// The master controller. + E_CONTROLLER_MASTER = 0, + /// The partner controller. + E_CONTROLLER_PARTNER +} controller_id_e_t; + +/** + * \enum + */ +typedef enum { + /// The horizontal axis of the controller’s left analog stick. + E_CONTROLLER_ANALOG_LEFT_X = 0, + /// The vertical axis of the controller’s left analog stick. + E_CONTROLLER_ANALOG_LEFT_Y, + /// The horizontal axis of the controller’s right analog stick. + E_CONTROLLER_ANALOG_RIGHT_X, + /// The vertical axis of the controller’s right analog stick. + E_CONTROLLER_ANALOG_RIGHT_Y +} controller_analog_e_t; + +/** + * \enum + */ +typedef enum { + /// The first trigger on the left side of the controller. + E_CONTROLLER_DIGITAL_L1 = 6, + /// The second trigger on the left side of the controller. + E_CONTROLLER_DIGITAL_L2, + /// The first trigger on the right side of the controller. + E_CONTROLLER_DIGITAL_R1, + /// The second trigger on the right side of the controller. + E_CONTROLLER_DIGITAL_R2, + /// The up arrow on the left arrow pad of the controller. + E_CONTROLLER_DIGITAL_UP, + /// The down arrow on the left arrow pad of the controller. + E_CONTROLLER_DIGITAL_DOWN, + /// The left arrow on the left arrow pad of the controller. + E_CONTROLLER_DIGITAL_LEFT, + /// The right arrow on the left arrow pad of the controller. + E_CONTROLLER_DIGITAL_RIGHT, + /// The ‘X’ button on the right button pad of the controller. + E_CONTROLLER_DIGITAL_X, + /// The ‘B’ button on the right button pad of the controller. + E_CONTROLLER_DIGITAL_B, + /// The ‘Y’ button on the right button pad of the controller. + E_CONTROLLER_DIGITAL_Y, + /// The ‘A’ button on the right button pad of the controller. + E_CONTROLLER_DIGITAL_A, + /// The power button on the front of the controller. + E_CONTROLLER_DIGITAL_POWER +} controller_digital_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define CONTROLLER_MASTER pros::E_CONTROLLER_MASTER +#define CONTROLLER_PARTNER pros::E_CONTROLLER_PARTNER +#define ANALOG_LEFT_X pros::E_CONTROLLER_ANALOG_LEFT_X +#define ANALOG_LEFT_Y pros::E_CONTROLLER_ANALOG_LEFT_Y +#define ANALOG_RIGHT_X pros::E_CONTROLLER_ANALOG_RIGHT_X +#define ANALOG_RIGHT_Y pros::E_CONTROLLER_ANALOG_RIGHT_Y +#define DIGITAL_L1 pros::E_CONTROLLER_DIGITAL_L1 +#define DIGITAL_L2 pros::E_CONTROLLER_DIGITAL_L2 +#define DIGITAL_R1 pros::E_CONTROLLER_DIGITAL_R1 +#define DIGITAL_R2 pros::E_CONTROLLER_DIGITAL_R2 +#define DIGITAL_UP pros::E_CONTROLLER_DIGITAL_UP +#define DIGITAL_DOWN pros::E_CONTROLLER_DIGITAL_DOWN +#define DIGITAL_LEFT pros::E_CONTROLLER_DIGITAL_LEFT +#define DIGITAL_RIGHT pros::E_CONTROLLER_DIGITAL_RIGHT +#define DIGITAL_X pros::E_CONTROLLER_DIGITAL_X +#define DIGITAL_B pros::E_CONTROLLER_DIGITAL_B +#define DIGITAL_Y pros::E_CONTROLLER_DIGITAL_Y +#define DIGITAL_A pros::E_CONTROLLER_DIGITAL_A +#define DIGITAL_POWER pros::E_CONTROLLER_DIGITAL_POWER +#else +#define CONTROLLER_MASTER E_CONTROLLER_MASTER +#define CONTROLLER_PARTNER E_CONTROLLER_PARTNER +#define ANALOG_LEFT_X E_CONTROLLER_ANALOG_LEFT_X +#define ANALOG_LEFT_Y E_CONTROLLER_ANALOG_LEFT_Y +#define ANALOG_RIGHT_X E_CONTROLLER_ANALOG_RIGHT_X +#define ANALOG_RIGHT_Y E_CONTROLLER_ANALOG_RIGHT_Y +#define DIGITAL_L1 E_CONTROLLER_DIGITAL_L1 +#define DIGITAL_L2 E_CONTROLLER_DIGITAL_L2 +#define DIGITAL_R1 E_CONTROLLER_DIGITAL_R1 +#define DIGITAL_R2 E_CONTROLLER_DIGITAL_R2 +#define DIGITAL_UP E_CONTROLLER_DIGITAL_UP +#define DIGITAL_DOWN E_CONTROLLER_DIGITAL_DOWN +#define DIGITAL_LEFT E_CONTROLLER_DIGITAL_LEFT +#define DIGITAL_RIGHT E_CONTROLLER_DIGITAL_RIGHT +#define DIGITAL_X E_CONTROLLER_DIGITAL_X +#define DIGITAL_B E_CONTROLLER_DIGITAL_B +#define DIGITAL_Y E_CONTROLLER_DIGITAL_Y +#define DIGITAL_A E_CONTROLLER_DIGITAL_A +#endif +#endif + +/** + * \def Given an id and a port, this macro sets the port variable based on the id and allows the mutex to take that + * port. + * + * \returns error (in the function/scope it's in) if the controller failed to connect or an invalid id is given. + */ +#define CONTROLLER_PORT_MUTEX_TAKE(id, port) \ + switch (id) { \ + case E_CONTROLLER_MASTER: \ + port = V5_PORT_CONTROLLER_1; \ + break; \ + case E_CONTROLLER_PARTNER: \ + port = V5_PORT_CONTROLLER_2; \ + break; \ + default: \ + errno = EINVAL; \ + return PROS_ERR; \ + } \ + if (!internal_port_mutex_take(port)) { \ + errno = EACCES; \ + return PROS_ERR; \ + } + +#ifdef __cplusplus +namespace c { +#endif + +/** + * Checks if the controller is connected. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * + * \return 1 if the controller is connected, 0 otherwise + * + * \b Example + * \code + * void initialize() { + * if (competition_is_connected()) { + * // Field Control is Connected + * // Run LCD Selector code or similar + * } + * } + * \endcode + */ +int32_t controller_is_connected(controller_id_e_t id); + +/** + * Gets the value of an analog channel (joystick) on a controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param channel + * The analog channel to get. + * Must be one of ANALOG_LEFT_X, ANALOG_LEFT_Y, ANALOG_RIGHT_X, + * ANALOG_RIGHT_Y + * + * \return The current reading of the analog channel: [-127, 127]. + * If the controller was not connected, then 0 is returned + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_get_analog(controller_id_e_t id, controller_analog_e_t channel); + +/** + * Gets the battery capacity of the given controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER + * + * \return The controller's battery capacity + * + * \b Example + * \code + * void initialize() { + * printf("Battery Capacity: %d\n", controller_get_battery_capacity(E_CONTROLLER_MASTER)); + * } + * \endcode + */ +int32_t controller_get_battery_capacity(controller_id_e_t id); + +/** + * Gets the battery level of the given controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER + * + * \return The controller's battery level + * + * \b Example + * \code + * void initialize() { + * printf("Battery Level: %d\n", controller_get_battery_level(E_CONTROLLER_MASTER)); + * } + * \endcode + */ +int32_t controller_get_battery_level(controller_id_e_t id); + +/** + * Checks if a digital channel (button) on the controller is currently pressed. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param button + * The button to read. + * Must be one of DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} + * + * \return 1 if the button on the controller is pressed. + * If the controller was not connected, then 0 is returned + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * if (controller_get_digital(E_CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_A)) { + * motor_set(1, 100); + * } + * else { + * motor_set(1, 0); + * } + * delay(2); + * } + * } + + * \endcode + */ +int32_t controller_get_digital(controller_id_e_t id, controller_digital_e_t button); + +/** + * Returns a rising-edge case for a controller button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under the + * same circumstances, so only one task should call this function for any given + * button. E.g., Task A calls this function for buttons 1 and 2. Task B may call + * this function for button 3, but should not for buttons 1 or 2. A typical + * use-case for this function is to call inside opcontrol to detect new button + * presses, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param button + * The button to read. Must be one of + * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} + * + * \return 1 if the button on the controller is pressed and had not been pressed + * the last time this function was called, 0 otherwise. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * if (controller_get_digital_new_press(E_CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_A)) { + * // Toggle pneumatics or other similar actions + * } + * + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_get_digital_new_press(controller_id_e_t id, controller_digital_e_t button); + +/** + * Returns a falling-edge case for a controller button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under + * the same circumstances, so only one task should call this function for any + * given button. E.g., Task A calls this function for buttons 1 and 2. + * Task B may call this function for button 3, but should not for buttons + * 1 or 2. A typical use-case for this function is to call inside opcontrol + * to detect new button releases, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param button + * The button to read. Must be one of + * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} + * + * \return 1 if the button on the controller is not pressed and had been + * pressed the last time this function was called, 0 otherwise. + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (master.get_digital_new_release(pros::E_CONTROLLER_DIGITAL_A)) { + * // Toggle pneumatics or other similar actions + * } + * + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_get_digital_new_release(controller_id_e_t id, controller_digital_e_t button); + +/** + * Sets text to the controller LCD screen. + * + * \note Controller text setting is a slow process, so updates faster than 10ms + * when on a wired connection or 50ms over Vexnet will not be applied to the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * EAGAIN - Could not send the text to the controller. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param line + * The line number at which the text will be displayed [0-2] + * \param col + * The column number at which the text will be displayed [0-14] + * \param fmt + * The format string to print to the controller + * \param ... + * The argument list for the format string + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * while (true) { + * if (!(count % 25)) { + * // Only print every 50ms, the controller text update rate is slow + * controller_print(E_CONTROLLER_MASTER, 0, 0, "Counter: %d", count); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_print(controller_id_e_t id, uint8_t line, uint8_t col, const char* fmt, ...); + +/** + * Sets text to the controller LCD screen. + * + * \note Controller text setting is a slow process, so updates faster than 10ms + * when on a wired connection or 50ms over Vexnet will not be applied to the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * EAGAIN - Could not send the text to the controller. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param line + * The line number at which the text will be displayed [0-2] + * \param col + * The column number at which the text will be displayed [0-14] + * \param str + * The pre-formatted string to print to the controller + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * while (true) { + * if (!(count % 25)) { + * // Only print every 50ms, the controller text update rate is slow + * controller_set_text(E_CONTROLLER_MASTER, 0, 0, "Example text"); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_set_text(controller_id_e_t id, uint8_t line, uint8_t col, const char* str); + +/** + * Clears an individual line of the controller screen. + * + * \note Controller text setting is currently in beta, so continuous, fast + * updates will not work well. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param line + * The line number to clear [0-2] + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * controller_set_text(E_CONTROLLER_MASTER, 0, 0, "Example"); + * delay(100); + * controller_clear_line(E_CONTROLLER_MASTER, 0); + * } + * \endcode + */ +int32_t controller_clear_line(controller_id_e_t id, uint8_t line); + +/** + * Clears all of the lines on the controller screen. + * + * \note Controller text setting is a slow process, so updates faster than 10ms + * when on a wired connection or 50ms over Vexnet will not be applied to the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * EAGAIN - Could not send the text to the controller. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * controller_set_text(E_CONTROLLER_MASTER, 0, 0, "Example"); + * delay(100); + * controller_clear(E_CONTROLLER_MASTER); + * } + * \endcode + */ +int32_t controller_clear(controller_id_e_t id); + +/** + * Rumble the controller. + * + * \note Controller rumble activation is a slow process, so updates faster than 10ms + * when on a wired connection or 50ms over Vexnet will not be applied to the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param rumble_pattern + * A string consisting of the characters '.', '-', and ' ', where dots + * are short rumbles, dashes are long rumbles, and spaces are pauses. + * Maximum supported length is 8 characters. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * while (true) { + * if (!(count % 25)) { + * // Only send every 50ms, the controller update rate is slow + * controller_rumble(E_CONTROLLER_MASTER, ". - . -"); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_rumble(controller_id_e_t id, const char* rumble_pattern); + +/** + * Gets the current voltage of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current voltage of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery's Voltage: %d\n", battery_get_voltage()); + * } + * \endcode + */ +int32_t battery_get_voltage(void); + +/** + * Gets the current current of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current current of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery Current: %d\n", battery_get_current()); + * } + * \endcode + */ +int32_t battery_get_current(void); + +/** + * Gets the current temperature of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current temperature of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery's Temperature: %d\n", battery_get_temperature()); + * } + * \endcode + */ +double battery_get_temperature(void); + +/** + * Gets the current capacity of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current capacity of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery Level: %d\n", battery_get_capacity()); + * } + * \endcode + */ +double battery_get_capacity(void); + +/** + * Checks if the SD card is installed. + * + * \return 1 if the SD card is installed, 0 otherwise + * + * \b Example + * \code + * void opcontrol() { + * printf("%i", usd_is_installed()); + * } + * \endcode + */ +int32_t usd_is_installed(void); + +/** + * Lists the files in a directory specified by the path + * Puts the list of file names (NOT DIRECTORIES) into the buffer seperated by newlines + * + * This function uses the following values of errno when an error state is + * reached: + * + * EIO - Hard error occured in the low level disk I/O layer + * EINVAL - file or directory is invalid, or length is invalid + * EBUSY - THe physical drinve cannot work + * ENOENT - cannot find the path or file + * EINVAL - the path name format is invalid + * EACCES - Access denied or directory full + * EEXIST - Access denied + * EROFS - SD card is write protected + * ENXIO - drive number is invalid or not a FAT32 drive + * ENOBUFS - drive has no work area + * ENFILE - too many open files + * + * + * + * \note use a path of "\" to list the files in the main directory NOT "/usd/" + * DO NOT PREPEND YOUR PATHS WITH "/usd/" + * + * \return 1 on success or PROS_ERR on failure setting errno + * + * \b Example + * \code + * void opcontrol() { + * char* test = (char*) malloc(128); + * pros::c::usd_list_files("/", test, 128); + * pros::delay(200); + * printf("%s\n", test); //Prints the file names in the root directory seperated by newlines + * pros::delay(100); + * pros::c::usd_list_files("/test", test, 128); + * pros::delay(200); + * printf("%s\n", test); //Prints the names of files in the folder named test seperated by newlines + * pros::delay(100); + * } + * \endcode + */ +int32_t usd_list_files(const char* path, char* buffer, int32_t len); + +/******************************************************************************/ +/** Date and Time **/ +/******************************************************************************/ + +extern const char* baked_date; +extern const char* baked_time; + +typedef struct { + uint16_t year; // Year - 1980 + uint8_t day; + uint8_t month; // 1 = January +} date_s_t; + +typedef struct { + uint8_t hour; + uint8_t min; + uint8_t sec; + uint8_t sec_hund; // hundredths of a second +} time_s_t; + +///@} + +///@} + +#ifdef __cplusplus +} +} // namespace pros +} +#endif + +#endif // _PROS_MISC_H_ diff --git a/test/include/pros/misc.hpp b/test/include/pros/misc.hpp new file mode 100644 index 00000000..b0a115e4 --- /dev/null +++ b/test/include/pros/misc.hpp @@ -0,0 +1,616 @@ +/** + * \file pros/misc.hpp + * \ingroup cpp-pros + * + * Contains prototypes for miscellaneous functions pertaining to the controller, + * battery, and competition control. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reservered. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-misc Miscellaneous C++ API + * \note Additional example code for this module can be found in its [Tutorial.](@ref controller) + */ + +#ifndef _PROS_MISC_HPP_ +#define _PROS_MISC_HPP_ + +#include +#include + +#include "pros/misc.h" + +namespace pros { +inline namespace v5 { +/** + * \ingroup cpp-misc + */ +class Controller { + /** + * \addtogroup cpp-misc + * ///@{ + */ + public: + /** + * Creates a controller object for the given controller id. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + */ + explicit Controller(controller_id_e_t id); + + /** + * Checks if the controller is connected. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \return 1 if the controller is connected, 0 otherwise + * + * \b Example + * \code + * void status_display_controller(){ + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * if(!master.is_connected()) { + * pros::lcd::print(0, "Main controller is not connected!"); + * } + * } + * \endcode + */ + std::int32_t is_connected(void); + + /** + * Gets the value of an analog channel (joystick) on a controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param channel + * The analog channel to get. + * Must be one of ANALOG_LEFT_X, ANALOG_LEFT_Y, ANALOG_RIGHT_X, + * ANALOG_RIGHT_Y + * + * \return The current reading of the analog channel: [-127, 127]. + * If the controller was not connected, then 0 is returned + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * motor_move(1, master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * delay(2); + * } + * } + * \endcode + */ + std::int32_t get_analog(controller_analog_e_t channel); + + /** + * Gets the battery capacity of the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \return The controller's battery capacity + * + * \b Example + * \code + * void initialize() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * printf("Battery Capacity: %d\n", master.get_battery_capacity()); + * } + * \endcode + */ + std::int32_t get_battery_capacity(void); + + /** + * Gets the battery level of the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \return The controller's battery level + * + * \b Example + * \code + * void initialize() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * printf("Battery Level: %d\n", master.get_battery_level()); + * } + * \endcode + */ + std::int32_t get_battery_level(void); + + /** + * Checks if a digital channel (button) on the controller is currently + * pressed. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param button + * The button to read. Must be one of + * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} + * + * \return 1 if the button on the controller is pressed. + * If the controller was not connected, then 0 is returned + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (master.get_digital(pros::E_CONTROLLER_DIGITAL_A)) { + * motor_set(1, 100); + * } + * else { + * motor_set(1, 0); + * } + * delay(2); + * } + * } + * \endcode + */ + std::int32_t get_digital(controller_digital_e_t button); + + /** + * Returns a rising-edge case for a controller button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under + * the same circumstances, so only one task should call this function for any + * given button. E.g., Task A calls this function for buttons 1 and 2. + * Task B may call this function for button 3, but should not for buttons + * 1 or 2. A typical use-case for this function is to call inside opcontrol + * to detect new button presses, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param button + * The button to read. Must be one of + * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} + * + * \return 1 if the button on the controller is pressed and had not been + * pressed the last time this function was called, 0 otherwise. + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (master.get_digital_new_press(pros::E_CONTROLLER_DIGITAL_A)) { + * // Toggle pneumatics or other similar actions + * } + * + * delay(2); + * } + * } + * \endcode + */ + std::int32_t get_digital_new_press(controller_digital_e_t button); + + /** + * Returns a falling-edge case for a controller button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under + * the same circumstances, so only one task should call this function for any + * given button. E.g., Task A calls this function for buttons 1 and 2. + * Task B may call this function for button 3, but should not for buttons + * 1 or 2. A typical use-case for this function is to call inside opcontrol + * to detect new button releases, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param button + * The button to read. Must be one of + * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} + * + * \return 1 if the button on the controller is not pressed and had been + * pressed the last time this function was called, 0 otherwise. + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (master.get_digital_new_release(pros::E_CONTROLLER_DIGITAL_A)) { + * // Toggle pneumatics or other similar actions + * } + * + * delay(2); + * } + * } + * \endcode + */ + std::int32_t get_digital_new_release(controller_digital_e_t button); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" + template + T convert_args(T arg) { + return arg; + } + const char* convert_args(const std::string& arg) { + return arg.c_str(); + } +#pragma GCC diagnostic pop + + /** + * Sets text to the controller LCD screen. + * + * \note Controller text setting is currently in beta, so continuous, fast + * updates will not work well. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param line + * The line number at which the text will be displayed [0-2] + * \param col + * The column number at which the text will be displayed [0-14] + * \param fmt + * The format string to print to the controller + * \param ... + * The argument list for the format string + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (!(count % 25)) { + * // Only print every 50ms, the controller text update rate is slow + * master.print(0, 0, "Counter: %d", count); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ + template + std::int32_t print(std::uint8_t line, std::uint8_t col, const char* fmt, Params... args) { + return pros::c::controller_print(_id, line, col, fmt, convert_args(args)...); + } + + /** + * Sets text to the controller LCD screen. + * + * \note Controller text setting is currently in beta, so continuous, fast + * updates will not work well. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param line + * The line number at which the text will be displayed [0-2] + * \param col + * The column number at which the text will be displayed [0-14] + * \param str + * The pre-formatted string to print to the controller + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (!(count % 25)) { + * // Only print every 50ms, the controller text update rate is slow + * master.set_text(0, 0, "Example text"); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ + std::int32_t set_text(std::uint8_t line, std::uint8_t col, const char* str); + std::int32_t set_text(std::uint8_t line, std::uint8_t col, const std::string& str); + + /** + * Clears an individual line of the controller screen. + * + * \note Controller text setting is currently in beta, so continuous, fast + * updates will not work well. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param line + * The line number to clear [0-2] + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * master.set_text(0, 0, "Example"); + * delay(100); + * master.clear_line(0); + * } + * \endcode + */ + std::int32_t clear_line(std::uint8_t line); + + /** + * Rumble the controller. + * + * \note Controller rumble activation is currently in beta, so continuous, fast + * updates will not work well. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param rumble_pattern + * A string consisting of the characters '.', '-', and ' ', where dots + * are short rumbles, dashes are long rumbles, and spaces are pauses. + * Maximum supported length is 8 characters. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (!(count % 25)) { + * // Only send every 50ms, the controller update rate is slow + * master.rumble(". - . -"); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ + std::int32_t rumble(const char* rumble_pattern); + + /** + * Clears all of the lines on the controller screen. + * + * \note Controller text setting is currently in beta, so continuous, fast + * updates will not work well. On vexOS version 1.0.0 this function will + * block for 110ms. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * master.set_text(0, 0, "Example"); + * delay(100); + * master.clear(); + * } + * \endcode + */ + std::int32_t clear(void); + + private: + controller_id_e_t _id; + ///@} +}; +} // namespace v5 + +namespace battery { +/** + * \addtogroup cpp-misc + * ///@{ + */ +/** + * Gets the current voltage of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current voltage of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery Level: %.2f\n", get_capacity()); + * } + * \endcode + */ +double get_capacity(void); + +/** + * Gets the current current of the battery in milliamps, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current current of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery Current: %d\n", get_current()); + * } + * \endcode + */ +int32_t get_current(void); + +/** + * Gets the current temperature of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current temperature of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery's Temperature: %.2f\n", get_temperature()); + * } + * \endcode + */ +double get_temperature(void); + +/** + * Gets the current capacity of the battery in millivolts, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current capacity of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery's Voltage: %d\n", get_voltage()); + * } + * \endcode + */ +int32_t get_voltage(void); +///@} +} // namespace battery + +namespace competition { +/** + * Get the current status of the competition control. + * + * \return The competition control status as a mask of bits with + * COMPETITION_{ENABLED,AUTONOMOUS,CONNECTED}. + * + * \b Example + * \code + * void status_display_task(){ + * if(!is_connected()) { + * pros::lcd::print(0, "V5 Brain is not connected!"); + * } + * if(is_autonomous()) { + * pros::lcd::print(0, "V5 Brain is in autonomous mode!"); + * } + * if(!is_disabled()) { + * pros::lcd::print(0, "V5 Brain is disabled!"); + * } + * \endcode + */ +std::uint8_t get_status(void); +std::uint8_t is_autonomous(void); +std::uint8_t is_connected(void); +std::uint8_t is_disabled(void); +std::uint8_t is_field_control(void); +std::uint8_t is_competition_switch(void); +} // namespace competition + +namespace usd { +/** + * Checks if the SD card is installed. + * + * \return 1 if the SD card is installed, 0 otherwise + * + * \b Example + * \code + * void opcontrol() { + * printf("%i", is_installed()); + * } + * \endcode + */ +std::int32_t is_installed(void); +/** + * Lists the files in a directory specified by the path + * Puts the list of file names (NOT DIRECTORIES) into the buffer seperated by newlines + * + * This function uses the following values of errno when an error state is + * reached: + * + * EIO - Hard error occured in the low level disk I/O layer + * EINVAL - file or directory is invalid, or length is invalid + * EBUSY - THe physical drinve cannot work + * ENOENT - cannot find the path or file + * EINVAL - the path name format is invalid + * EACCES - Access denied or directory full + * EEXIST - Access denied + * EROFS - SD card is write protected + * ENXIO - drive number is invalid or not a FAT32 drive + * ENOBUFS - drive has no work area + * ENFILE - too many open files + * + * + * + * \note use a path of "\" to list the files in the main directory NOT "/usd/" + * DO NOT PREPEND YOUR PATHS WITH "/usd/" + * + * \return 1 on success or PROS_ERR on failure setting errno + * + * \b Example + * \code + * void opcontrol() { + * char* test = (char*) malloc(128); + * pros::usd::list_files("/", test, 128); + * pros::delay(200); + * printf("%s\n", test); //Prints the file names in the root directory seperated by newlines + * pros::delay(100); + * pros::list_files("/test", test, 128); + * pros::delay(200); + * printf("%s\n", test); //Prints the names of files in the folder named test seperated by newlines + * pros::delay(100); + * } + * \endcode + */ + +std::int32_t list_files(const char* path, char* buffer, std::int32_t len); +} // namespace usd + +} // namespace pros + +#endif // _PROS_MISC_HPP_ diff --git a/test/include/pros/motor_group.hpp b/test/include/pros/motor_group.hpp new file mode 100644 index 00000000..c9a4a1a0 --- /dev/null +++ b/test/include/pros/motor_group.hpp @@ -0,0 +1,2423 @@ +/** + * \file pros/motor_group.hpp + * \ingroup cpp-motor-group + * + * Contains prototypes for the V5 Motor-related functions. + * + * Visit https://pros.cs.purdue.edu/v5/tutorials/topical/motors.html to learn + * more. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-motor-group Motors C++ API + * \note Additional example code for this module can be found in its [Tutorial](@ref motors). + */ + +#ifndef _PROS_MOTOR_GROUP_HPP_ +#define _PROS_MOTOR_GROUP_HPP_ + +#include +#include + +#include "pros/abstract_motor.hpp" +#include "pros/colors.hpp" +#include "pros/device.hpp" +#include "pros/motors.h" +#include "pros/motors.hpp" +#include "rtos.hpp" + +namespace pros { +inline namespace v5 { +class MotorGroup : public virtual AbstractMotor { + /** + * \addtogroup cpp-motor-group + * @{ + */ + public: + /** + * Constructs a new MotorGroup object. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * A initializer list of V5 port numbers from 1 to 21, or from -21 to -1 for reversed motors. + * A reversed motor will reverse the input or output movement functions and movement related + * telemetry in order to produce consistant behavior with non-reversed motors + * + * \param gearset = pros::v5::MotorGears::invalid + * Optional parameter for the gearset for the motor. + * Does not explicitly set the motor gearset if it is invalid or not specified + * + * \param encoder_units = pros::v5::MotorUnits::invalid + * Optional parameter for the encoder units of the motor + * Does not explicitly set the motor units if it is invalid or not specified + * + * \b Example + * \code + * void opcontrol() { + * MotorGroup first_mg({1, -2}); //Creates a motor on port 1 and a reversed motor on port 2 + * MotorGroup rotations_mg({4, 5}, pros::v5::MotorGears::blue, pros::v5::MotorUnits::rotations); + * //Creates a motor group on ports 4 and 5 with blue motors using rotaions as the encoder units + * } + * \endcode + */ + MotorGroup(const std::initializer_list, + const pros::v5::MotorGears gearset = pros::v5::MotorGears::invalid, + const pros::v5::MotorUnits encoder_units = pros::v5::MotorUnits::invalid); + /** + * Constructs a new MotorGroup object. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * + * ENODEV - The port cannot be configured as a motor + * + * EDOM - The motor group is empty + * + * \param port + * A initializer list of V5 port numbers from 1 to 21, or from -21 to -1 for reversed motors. + * A reversed motor will reverse the input or output movement functions and movement related + * telemetry in order to produce consistant behavior with non-reversed motors + * + * \param gearset = pros::v5::MotorGears::invalid + * \param gearset = pros::v5::MotorGears::green + * Optional parameter for the gearset for the motor. + * Does not explicitly set the motor gearset if it is invalid or not specified + * + * \param encoder_units = pros::v5::MotorUnits::invalid + * Optional parameter for the encoder units of the motor + * Does not explicitly set the motor units if it is invalid or not specified + * + * \b Example + * \code + * void opcontrol() { + * MotorGroup first_mg({1, -2}); //Creates a motor on port 1 and a reversed motor on port 2 with + * with both motors using the green gearset and degrees as the encoder units + * MotorGroup rotations_mg({4, 5}, pros::v5::MotorGears::blue, pros::v5::MotorUnits::rotations); + * //Creates a motor group on ports 4 and 5 with blue motors using rotaions as the encoder units + * } + * \endcode + */ + MotorGroup(const std::vector& ports, const pros::v5::MotorGears gearset = pros::v5::MotorGears::invalid, + const pros::v5::MotorUnits encoder_units = pros::v5::MotorUnits::invalid); + + /** + * Constructs a new MotorGroup object from an abstract motor. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * + * ENODEV - The port cannot be configured as a motor + * + * EDOM - The motor group is empty + * + * \param abstract_motor + * The abstract motor to turn into a motor group + * Uses abstract_motor.get_port_all() to get the vector of ports + * + * + * \b Example + * \code + * void opcontrol() { + * MotorGroup first_mg({1, -2}); //Creates a motor on port 1 and a reversed motor on port 2 with + * with both motors using the green gearset and degrees as the encoder units + * AbstractMotor abs_mtr_group = first_mg; + * MotorGroup new_mg = (MotorGroup) abs_mtr_group; + * } + * \endcode + */ + + MotorGroup(AbstractMotor& motor_group); + + /// \name Motor movement functions + /// These functions allow programmers to make motors move + ///@{ + + /** + * Sets the voltage for the motor group from -127 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is + * analogous to use of motor_move() + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param voltage + * The new voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup MotorGroup ({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg.move(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t move(std::int32_t voltage) const; + + /** + * Sets the target absolute position for the motor group to move to. + * + * This movement is relative to the position of the motor when initialized or + * the position when it was most recently reset with + * pros::Motor::set_zero_position(). + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - the motor group has size 0 + * + * \param position + * The absolute position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg ({1,3}); + * mg.move_absolute(100, 100); // Moves 100 units forward + * while (!((mg.get_position() < 105) && (mg.get_position() > 95))) { + * // Continue running this loop as long as the mg is not within +-5 units of its goal + * pros::delay(2); + * } + * mg.move_absolute(100, 100); // This does not cause a movement + * while (!((mg.get_position() < 105) && (mg.get_position() > 95))) { + * pros::delay(2); + * } + * mg.tare_position(); + * mg.move_absolute(100, 100); // Moves 100 units forward + * while (!((mg.get_position() < 105) && (mg.get_position() > 95))) { + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t move_absolute(const double position, const std::int32_t velocity) const; + + /** + * Sets the relative target position for the motor group to move to. + * + * This movement is relative to the current position of each motor as given in + * pros::MotorGroup::get_position(). Providing 10.0 as the position parameter + * would result in the motor moving 10 units, no matter what the + * current position is. + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param position + * The relative position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg({1,3}); + * mg.move_relative(100, 100); // Moves 100 units forward + * while (!((mg.get_position() < 105) && (mg.get_position() > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * pros::delay(2); + * } + * mg.move_relative(100, 100); // Also moves 100 units forward + * while (!((mg.get_position() < 205) && (mg.get_position() > 195))) { + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t move_relative(const double position, const std::int32_t velocity) const; + + /** + * Sets the velocity for the motor group. + * + * This velocity corresponds to different actual speeds depending on the + * gearset used for the motor. This results in a range of +-100 for + * E_MOTOR_GEARSET_36, +-200 for E_MOTOR_GEARSET_18, and +-600 for + * E_MOTOR_GEARSET_6. The velocity is held with PID to ensure consistent + * speed, as opposed to setting the motor's voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param velocity + * The new velocity from +-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg({1,3}); + * mg.move_velocity(100); + * pros::delay(1000); // Move at 100 RPM for 1 second + * mg.move_velocity(0); + * } + * \endcode + */ + std::int32_t move_velocity(const std::int32_t velocity) const; + + /** + * Sets the output voltage for the motor group from -12000 to 12000 in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param voltage + * The new voltage value from -12000 to 12000 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * mg.move_voltage(12000); + * pros::delay(1000); // Move at max voltage for 1 second + * mg.move_voltage(0); + * } + * \endcode + */ + std::int32_t move_voltage(const std::int32_t voltage) const; + + /** + * Stops the motor group using the currently configured brake mode. + * + * This function sets motor velocity to zero, which will cause it to act + * according to the set brake mode. If brake mode is set to MOTOR_BRAKE_HOLD, + * this function may behave differently than calling move_absolute(0) + * or motor_move_relative(0). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - The motor group is empty + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * Motor motor(1); + * mg.move_voltage(12000); + * pros::delay(1000); // Move at max voltage for 1 second + * motor.brake(); + * } + * \endcode + */ + std::int32_t brake(void) const; + + /** + * Changes the output velocity for a profiled movement (move_absolute or + * move_relative). This will have no effect if the motor group is not following + * a profiled movement. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param velocity + * The new motor velocity from +-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg ({1,3}); + * mg.move_absolute(100, 100); + * pros::delay(100); + * mg.modify_profiled_velocity(0); // Stop the motor group early + * } + * \endcode + */ + std::int32_t modify_profiled_velocity(const std::int32_t velocity) const; + + /** + * Gets the target position set for a motor in the motor group, with a parameter + * for the motor index. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The target position in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg({1,3}); + * mg.move_absolute(100, 100); + * // get the target position from motor at index 1. (port 3) + * std::cout << "Motor Target: " << mg.get_target_position(1); + * // Prints 100 + * } + * \endcode + */ + double get_target_position(const std::uint8_t index) const; + + /** + * Gets a vector of the the target positions set for the motor group + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The Motor group is empty + * + * \return The a vector of the target positions in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg({1,3}); + * mg.move_absolute(100, 100); + * std::cout << "Motor Target: " << mg.get_target_position_all()[0]; + * // Prints 100 + * } + * \endcode + */ + std::vector get_target_position_all(void) const; + + /** + * Gets the velocity commanded to the motor by the user at the index specified. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * EDOM - The motor group was empty + * + * \param index Optional parameter. + * The zero indexed index of the motor in the motor group + * + * \return The commanded motor velocity from +-100, +-200, or +-600, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg ({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * // get the target velocity from motor at index 1. (port 3) + * std::cout << "Motor Velocity: " << mg.get_target_velocity(1); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_target_velocity(const std::uint8_t index = 0) const; + + /** + * Gets a vector of the velocity commanded to the motor by the user + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - THe motor group is empty + * + * \return A vector of the commanded motor velocity from +-100, +-200, or +-600, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg ({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * std::cout << "Motor Velocity: " << mg.get_target_velocity_all(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_target_velocity_all(void) const; + + ///@} + + /// \name Motor telemetry functions + /// These functions allow programmers to collect telemetry from motors + ///@{ + + /** + * Gets the actual velocity of a motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - THe motor group is empty + * + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter. + * The zero indexed index of the motor in the motor group + * + * \return The motor's actual velocity in RPM or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * while (true) { + * mg = controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y); + * // get the actual velocity from motor at index 1. (port 3) + * printf("Actual velocity: %lf\n", mg.get_actual_velocity(1)); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_actual_velocity(const std::uint8_t index = 0) const; + + /** + * Gets a vector of the the actual velocity of each motor the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - THe motor group is empty + * + * \return A vector of the each motor's actual velocity in RPM or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * while (true) { + * mg = controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y); + * // get the target velocity from motor at index 1. (port 3) + * printf("Actual velocity: %lf\n", mg.get_actual_velocity(1)); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_actual_velocity_all(void) const; + + /** + * Gets the current drawn by a motor in the motor group in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - The motor group is empty + * + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter. + * The zero indexed index of the motor in the motor group + * + * \return The motor's current in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * //Print the current draw for the motor at index 1. (port 3) + * std::cout << "Motor Current Draw: " << mg.get_current_draw(1); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_current_draw(const std::uint8_t index = 0) const; + /** + * Gets a vector of the current drawn each motor in the motor group in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - The motor group is empty + * + * + * \return A vector with each motor's current in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Current Draw: " << mg.get_current_draw_all(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_current_draw_all(void) const; + + /** + * Gets the direction of movement for a motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - The motor group is empty + * + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * //Print the motor direction for the motor at index 1. (port 3) + * std::cout << "Motor Direction: " << mg.get_direction(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_direction(const std::uint8_t index = 0) const; + /** + * Gets a vector of the directions of movement for each motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - The motor group is empty + * + * \return 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Direction: " << mg.get_direction_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_direction_all(void) const; + + /** + * Gets the efficiency of a motor in the motor group in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - The motor group is empty + * + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * //Prints the efficiency of the motor at index 1 (port 3) + * std::cout << "Motor Efficiency: " << mg.get_efficiency(1); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_efficiency(const std::uint8_t index = 0) const; + /** + * Gets a vector of the efficiency of each motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - THe motor group is empty + * + * \return A vector containing each motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Efficiency: " << mg.get_efficiency_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_efficiency_all(void) const; + + /** + * Gets the faults experienced by a motor in the motor group. + * + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - The motor group is empty + * + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return A bitfield containing the motor's faults. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << mg.get_faults(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::uint32_t get_faults(const std::uint8_t index = 0) const; + /** + * Gets a vector of the faults experienced by each motor in the motor group. + * + * Compare these bitfields to the bitmasks in pros::motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * EDOM - The motor group is empty + * + * + * \return A vector containing the bitfields containing each motor's faults. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << mg.get_faults_all(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_faults_all(void) const; + /** + * Gets the flags set by a motor in the motor group's operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return A bitfield containing the motor's flags. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << mg.get_faults(1); + * pros::delay(2); + * } + * } + * \endcode + */ + std::uint32_t get_flags(const std::uint8_t index = 0) const; + + /** + * Gets a vector of the flags set by each motor in the motor groups's operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A bitfield containing the motor's flags. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << mg.get_faults_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_flags_all(void) const; + + /** + * Gets the absolute position of a motor in the motor group in its encoder units. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << mg.get_position(1); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_position(const std::uint8_t index = 0) const; + /** + * Gets a vector of the absolute position of each motor in its encoder units. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A vector of the motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << mg.get_position_all(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_position_all(void) const; + + /** + * Gets the power drawn by a motor in the motor group in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Power: " << mg.get_power(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_power(const std::uint8_t index = 0) const; + /** + * Gets a vector of the power drawn by each motor in the motor group in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A vector of each motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Power: " << mg.get_power_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_power_all(void) const; + /** + * Gets the raw encoder count of a motor in the motor group at a given timestamp. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * + * \param timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. + * + * \b Example + * \code + * void opcontrol() { + * std::uint32_t now = pros::millis(); + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << mg.get_raw_position(&now); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_raw_position(std::uint32_t* const timestamp, const std::uint8_t index = 0) const; + /** + * Gets the raw encoder count of each motor at a given timestamp. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \return A vector of each raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. + * + * \b Example + * \code + * void opcontrol() { + * std::uint32_t now = pros::millis(); + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << mg.get_raw_position_all(&now)[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_raw_position_all(std::uint32_t* const timestamp) const; + + /** + * Gets the temperature of a motor in the motor group in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Temperature: " << mg.get_temperature(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_temperature(const std::uint8_t index = 0) const; + /** + * Gets the temperature of each motor in the motor group in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A vector of each motor's temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Temperature: " << mg.get_temperature_all()[1]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_temperature_all(void) const; + /** + * Gets the torque generated by a motor in the motor groupin Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Torque: " << mg.get_torque(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_torque(const std::uint8_t index = 0) const; + /** + * Gets a vector of the torque generated by each motor in Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A vector containing each motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Torque: " << mg.get_torque(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_torque_all(void) const; + /** + * Gets the voltage delivered to a motor in the motor group in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Voltage: " << mg.get_voltage(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_voltage(const std::uint8_t index = 0) const; + /** + * Gets a vector of the voltage delivered to each motor in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A vector of each motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Voltage: " << mg.get_voltage_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_voltage_all(void) const; + + /** + * Checks if a motor in the motor group is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its current limit?: " << mg.is_over_current(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t is_over_current(const std::uint8_t index = 0) const; + /** + * Checks if each motor in the motor group is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A vector containing the following for each motor: 1 if the motor's current limit is being exceeded and 0 if + * the current limit is not exceeded, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its current limit?: " << motor.is_over_current_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector is_over_current_all(void) const; + + /** + * Gets the temperature limit flag for a motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its temperature limit?: " << motor.is_over_temp(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t is_over_temp(const std::uint8_t index = 0) const; + /** + * Gets a vector with the temperature limit flag for each motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its temperature limit?: " << motor.is_over_temp(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector is_over_temp_all(void) const; + + ///@} + + /// \name Motor configuration functions + /// These functions allow programmers to configure the behavior of motors + ///@{ + + /** + * Gets the brake mode that was set for a motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return One of MotorBrake, according to what was set for the + * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << mg.get_brake_mode(); + * } + * \endcode + */ + MotorBrake get_brake_mode(const std::uint8_t index = 0) const; + /** + * Gets a vector with the brake mode that was set for each motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A vector with one of MotorBrake for each motor in the motor group, according to what was set for the + * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << mg.get_brake_mode_all()[0]; + * } + * \endcode + */ + std::vector get_brake_mode_all(void) const; + + /** + * Gets the current limit for a motor in the motor group in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * while (true) { + * std::cout << "Motor Current Limit: " << mg.get_current_limit(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_current_limit(const std::uint8_t index = 0) const; + + /** + * Gets a vector of the current limit for each motor in the motor group in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A vector of each motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * while (true) { + * std::cout << "Motor Current Limit: " << mg.get_current_limit_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_current_limit_all(void) const; + + /** + * Gets the encoder units that were set for a motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return One of MotorUnits according to what is set for the + * motor or E_MOTOR_ENCODER_INVALID if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg ({1,3}, E_MOTOR_GEARSET_06, false, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Encoder Units: " << mg.get_encoder_units(); + * } + * \endcode + */ + MotorUnits get_encoder_units(const std::uint8_t index = 0) const; + + /** + * Gets a vector of the encoder units that were set for each motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A vector with the following for each motor, One of MotorUnits according to what is set for the + * motor or E_MOTOR_ENCODER_INVALID if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg ({1,3}, E_MOTOR_GEARSET_06, false, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Encoder Units: " << mg.get_encoder_units_all()[0]; + * } + * \endcode + */ + std::vector get_encoder_units_all(void) const; + + /** + * Gets the gearset that was set for a motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + *\param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return One of MotorGears according to what is set for the motor, + * or pros::MotorGears::invalid if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg ({1,3}, E_MOTOR_GEARSET_06, false, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Gearing: " << mg.get_gearing(); + * } + * \endcode + */ + MotorGears get_gearing(const std::uint8_t index = 0) const; + /** + * Gets a vector of the gearset that was set for each motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * + * \return A vector with one of MotorGears according to what is set for the motor, + * or pros::MotorGears::invalid if the operation failed for each motor. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg ({1,3}, E_MOTOR_GEARSET_06, false, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Gearing: " << mg.get_gearing_all()[0]; + * } + * \endcode + */ + std::vector get_gearing_all(void) const; + + /** + * Gets a vector with all the port numbers in the motor group. + * A port will be negative if the motor in the motor group is reversed + * + * @return a vector with all the port numbers for the motor group + */ + std::vector get_port_all(void) const; + + /** + * Gets the voltage limit of a motor in the motor group set by the user. + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + *\param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The motor's voltage limit in V or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * std::cout << "Motor Voltage Limit: " << mg.get_voltage_limit(1); + * } + * \endcode + */ + std::int32_t get_voltage_limit(const std::uint8_t index = 0) const; + + /** + * Gets a vector of the voltage limit of each motor in the motor group + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The Motor group is empty + * + * \return The motor's voltage limit in V or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * std::cout << "Motor Voltage Limit: " << mg.get_voltage_limit_all()[0]; + * } + * \endcode + */ + std::vector get_voltage_limit_all(void) const; + + /** + * Gets the operation direction of a motor in the motor group as set by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + *\param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * std::cout << "Is the motor reversed? " << motor.is_reversed(); + * // Prints "0" + * } + * \endcode + */ + std::int32_t is_reversed(const std::uint8_t index = 0) const; + /** + * Gets a vector of the operation direction of each motor in the motor group as set by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * EDOM - The motor group is empty + * + * \return A vector conatining the following for each motor: 1 if the motor has been reversed and 0 if the motor was + * not reversed, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * std::cout << "Is the motor reversed? " << motor.is_reversed_all()[0]; + * // Prints "0" + * } + * \endcode + */ + std::vector is_reversed_all(void) const; + + /** + * Gets the type of a motor in the motor group. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + *\param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return One of MotorType according to the type of the motor, + * or pros::MotorType::invalid if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg ({1,3}, E_MOTOR_GEARSET_06, false, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Type: " << mg.get_type(); + * } + * \endcode + */ + MotorType get_type(const std::uint8_t index = 0) const; + /** + * Gets a vector of the type of each motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \return A vector with one of MotorType according to the type of the motor, + * or pros::MotorType::invalid if the operation failed for each motor. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg ({1,3}, E_MOTOR_GEARSET_06, false, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Type: " << mg.get_type_all()[0]; + * } + * \endcode + */ + std::vector get_type_all(void) const; + + /** + * Sets one of MotorBrake to a motor in the motor group. Works with the C enum + * and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param mode + * The MotorBrake to set for the motor + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_brake_mode(pros::MotorBrake::brake, 1); + * std::cout << "Brake Mode: " << mg.get_brake_mode(); + * } + * \endcode + */ + std::int32_t set_brake_mode(const MotorBrake mode, const std::uint8_t index = 0) const; + /** + * Sets one of MotorBrake to a motor in the motor group. Works with the C enum + * and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param mode + * The MotorBrake to set for the motor + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD, 1); + * std::cout << "Brake Mode: " << mg.get_brake_mode(); + * } + * \endcode + */ + std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index = 0) const; + /** + * Sets one of MotorBrake all the motors in the motor group. Works with the C enum + * and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param mode + * The MotorBrake to set for the motor + * + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_brake_mode_all(pros::MotorBrake:brake); + * std::cout << "Brake Mode: " << mg.get_brake_mode(); + * } + * \endcode + */ + std::int32_t set_brake_mode_all(const MotorBrake mode) const; + /** + * Sets one of MotorBrake to a motor in the motor group. Works with the C enum + * and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param mode + * The MotorBrake to set for the motor + * + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_brake_mode_all(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << mg.get_brake_mode(); + * } + * \endcode + */ + std::int32_t set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const; + /** + * Sets the current limit for one motor in the motor group in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param limit + * The new current limit in mA + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * mg.set_current_limit(1000); + * while (true) { + * mg = controller_get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will reduce its output at 1000 mA instead of the default 2500 mA + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t set_current_limit(const std::int32_t limit, const std::uint8_t index = 0) const; + /** + * Sets the current limit for every motor in the motor group in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group was empty + * + * \param limit + * The new current limit in mA + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * mg.set_current_limit_all(1000); + * while (true) { + * mg = controller_get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will reduce its output at 1000 mA instead of the default 2500 mA + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t set_current_limit_all(const std::int32_t limit) const; + /** + * Sets one of MotorUnits for one motor in the motor group's motor encoder. Works with the C + * enum and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param units + * The new motor encoder units + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_encoder_units(E_MOTOR_ENCODER_DEGREES, 1); + * std::cout << "Encoder Units: " << mg.get_encoder_units(); + * } + * \endcode + */ + std::int32_t set_encoder_units(const MotorUnits units, const std::uint8_t index = 0) const; + /** + * Sets one of MotorUnits for one motor in the motor group's motor encoder. Works with the C + * enum and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param units + * The new motor encoder units + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_encoder_units(E_MOTOR_ENCODER_DEGREES, 1); + * std::cout << "Encoder Units: " << mg.get_encoder_units(); + * } + * \endcode + */ + std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index = 0) const; + /** + * Sets one of MotorUnits for every motor in the motor group's motor encoder. Works with the C + * enum and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param units + * The new motor encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_encoder_units_all(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << mg.get_encoder_units(); + * } + * \endcode + */ + std::int32_t set_encoder_units_all(const MotorUnits units) const; + /** + * Sets one of MotorUnits for every motor in the motor group's motor encoder. Works with the C + * enum and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param units + * The new motor encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_encoder_units_all(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << mg.get_encoder_units(); + * } + * \endcode + */ + std::int32_t set_encoder_units_all(const pros::motor_encoder_units_e_t units) const; + + /** + * Sets one of the gear cartridge (red, green, blue) for one motor in the motor group. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * E2BIG - The size of the vector mismatches the number of motors in the motor group + * + * \note If there are more motors than gearsets passed in, + * only the first n motors will have their gearsets changed where n is the number of gearsets passed in. + * If there are more gearsets passed in than motors, then the only the first m gearsets will be used, + * where m is the number of motors. In either case, errno will be set to E2BIG, but the operation still occurs + * + * + * \param gearset + * The new geatset of the motor + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_gearing(pros::MotorGears::blue, 1); + * std::cout << "Gearset: " << mg.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing(std::vector gearsets) const; + /** + * Sets one of the gear cartridge (red, green, blue) for one motor in the motor group. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param gearset + * The new geatset of the motor + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_gearing(E_MOTOR_GEARSET_06, 1); + * std::cout << "Gearset: " << mg.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing(const pros::motor_gearset_e_t gearset, const std::uint8_t index = 0) const; + + /** + * Sets the gear cartridge (red, green, blue) for each motor in the motor group by taking in a vector of the + * cartridges. Usable with the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * E2BIG - The size of the vector mismatches the number of motors in the motor group + * + * \note If there are more motors than gearsets passed in, + * only the first n motors will have their gearsets changed where n is the number of gearsets passed in. + * If there are more gearsets passed in than motors, then the only the first m gearsets will be used, + * where m is the number of motors. In either case, errno will be set to E2BIG, but the operation still occurs + * + * \param gearset + * The a vector containing the new geatsets of the motors + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_gearing(pros::MotorGears::blue, 1); + * std::cout << "Gearset: " << mg.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing(std::vector gearsets) const; + + /** + * Sets one of the gear cartridge (red, green, blue) for one motor in the motor group. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param gearset + * The new geatset of the motor + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_gearing(E_MOTOR_GEARSET_06, 1); + * std::cout << "Gearset: " << mg.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing(const MotorGears gearset, const std::uint8_t index = 0) const; + /** + * Sets one of the gear cartridge (red, green, blue) for one motor in the motor group. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param gearset + * The new geatset of the motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_gearing_all(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << mg.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing_all(const MotorGears gearset) const; + /** + * Sets one of the gear cartridge (red, green, blue) for every motor in the motor group. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param gearset + * The new geatset of the motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_gearing_all(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << mg.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing_all(const pros::motor_gearset_e_t gearset) const; + + /** + * sets the reversal for a motor in the motor group. + * + * This will invert its movements and the values returned for its position. + * + * This function uses the following values of errno when an error state is + * reached: + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param reverse + * True reverses the motor, false is default + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * //reverse the motor at index 1 (port 3) + * mg.set_reversed(true, 1); + * std::cout << "Is this motor reversed? " << motor.is_reversed(1); + * pros::delay(100); + * // unreverse the motor at index 1 (port 3) + * mg.set_reversed(false, 1); + * std::cout << "Is this motor reversed? " << motor.is_reversed(1); + * } + * \endcode + */ + std::int32_t set_reversed(const bool reverse, const std::uint8_t index = 0); + /** + * Sets the reversal for all the motors in the motor group. + * + * This will invert its movements and the values returned for its position. + * + * This function uses the following values of errno when an error state is + * reached: + * EDOM - The motor group is empty + * + * \param reverse + * True reverses the motor, false is default + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::MotorGroup mg({1,3}); + * mg.set_reversed_all(true); + * std::cout << "Is this motor reversed? " << motor.is_reversed(); + * } + * \endcode + */ + std::int32_t set_reversed_all(const bool reverse); + + /** + * Sets the voltage limit for a motor in the motor group in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param limit + * The new voltage limit in Volts + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * mg.set_voltage_limit(10000, 1); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor on at index 1 (port 3) will not output more than 10 V + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t set_voltage_limit(const std::int32_t limit, const std::uint8_t index = 0) const; + + /** + * Sets the voltage limit for every motor in the motor group in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param limit + * The new voltage limit in Volts + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg({1,3}); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * mg.set_voltage_limit_all(10000); + * while (true) { + * mg = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will not output more than 10 V + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t set_voltage_limit_all(const std::int32_t limit) const; + + /** + * Sets the position for a motor in the motor group in its encoder units. + * + * This will be the future reference point for the motor's "absolute" + * position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param position + * The new reference position in its encoder units + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg({1,3}); + * mg.move_absolute(100, 100); // Moves 100 units forward + * mg.move_absolute(100, 100); // This does not cause a movement + * mg.set_zero_position(80); + * mg.set_zero_position(80, 1); + * mg.move_absolute(100, 100); // Moves 20 units forward + * } + * \endcode + * + */ + std::int32_t set_zero_position(const double position, const std::uint8_t index = 0) const; + /** + * Sets the position for every motor in the motor group in its encoder units. + * + * This will be the future reference point for the motor's "absolute" + * position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * + * \param position + * The new reference position in its encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg({1,3}); + * mg.move_absolute(100, 100); // Moves 100 units forward + * mg.move_absolute(100, 100); // This does not cause a movement + * + * mg.set_zero_position_all(80); + * mg.move_absolute(100, 100); // Moves 20 units forward + * } + * \endcode + * + */ + std::int32_t set_zero_position_all(const double position) const; + + /** + * Sets the "absolute" zero position of a motor in the motor group to its current position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EDOM - The motor group is empty + * EOVERFLOW - The index is greater than or equal to MotorGroup::size() + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg({1,3}); + * mg.move_absolute(100, 100); // Moves 100 units forward + * mg.move_absolute(100, 100); // This does not cause a movement + * + * mg.tare_position(); + * mg.tare_position(1); + * + * mg.move_absolute(100, 100); // Moves 100 units forward + * } + * \endcode + */ + std::int32_t tare_position(const std::uint8_t index = 0) const; + + /** + * Sets the "absolute" zero position of every motor in the motor group to its current position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::MotorGroup mg({1,3}); + * mg.move_absolute(100, 100); // Moves 100 units forward + * mg.move_absolute(100, 100); // This does not cause a movement + * mg.tare_position_all(); + * mg.move_absolute(100, 100); // Moves 100 units forward + * } + * \endcode + */ + std::int32_t tare_position_all(void) const; + + /** + * Returns the number of motors in the motor group + * + * \return the number of motors in the motor group + */ + std::int8_t size(void) const; + + /** + * Gets the port of a motor in the motor group via index + * + * \param index Optional parameter, 0 by default. + * The zero indexed index of the motor in the motor group + * + * \return The port of the motor at the specified index. + * The return value is negative if the corresponding motor is reversed + */ + std::int8_t get_port(const std::uint8_t index = 0) const; + + /** + * Appends all the motors in the other motor group reference to this motor group + * + * Maintains the order of the other motor group + * + */ + void operator+=(AbstractMotor&); + + /** + * Appends all the motors in the other motor group reference to this motor group + * + * Maintains the order of the other motor group + * + */ + void append(AbstractMotor&); + + /** + * Removes the all motors on the port (regardless of reversal) from the motor group + * + * \param port The port to remove from the motor group + * + */ + void erase_port(std::int8_t port); + + ///@} + private: + /** + * The ordered vector of ports used by the motor group + */ + std::vector _ports; + mutable pros::Mutex _MotorGroup_mutex; +}; +} // namespace v5 +} // namespace pros +#endif \ No newline at end of file diff --git a/test/include/pros/motors.h b/test/include/pros/motors.h new file mode 100644 index 00000000..3c99f03b --- /dev/null +++ b/test/include/pros/motors.h @@ -0,0 +1,1381 @@ +/** + * \file pros/motors.h + * \ingroup c-motors + * + * Contains prototypes for the V5 Motor-related functions. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-motors Motors C API + * \note Additional example code for this module can be found in its [Tutorial](@ref motors). + */ + +#ifndef _PROS_MOTORS_H_ +#define _PROS_MOTORS_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \ingroup c-motors + */ + +/** + * \addtogroup c-motors + * @{ + */ + +/// \name Motor movement functions +/// These functions allow programmers to make motors move +///@{ + +/** + * Sets the voltage for the motor from -127 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is analogous + * to use of motor_move_voltage(). + * + * \note This function will not respect brake modes, and simply sets the voltage to the desired value. + * + * \note A negative port will negate the input voltage + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param voltage + * The new motor voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_move(int8_t port, int32_t voltage); + +/** + * Stops the motor using the currently configured brake mode. + * + * This function sets motor velocity to zero, which will cause it to act + * according to the set brake mode. If brake mode is set to MOTOR_BRAKE_HOLD, + * this function may behave differently than calling motor_move_absolute(port, 0) + * or motor_move_relative(port, 0). + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move(1, 127); + * delay(1000); + * motor_break(1); + * } + * \endcode + */ +int32_t motor_brake(int8_t port); + +/** + * Sets the target absolute position for the motor to move to. + * + * This movement is relative to the position of the motor when initialized or + * the position when it was most recently reset with motor_set_zero_position(). + * + * \note This function simply sets the target for the motor, it does not block program + * execution until the movement finishes. The example code shows how to block until a movement is finished. + * + * \note A negative port number will negate the target position + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param position + * The absolute position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_absolute(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * delay(2); + * } + * motor_move_absolute(1, 100, 100); // This will not cause a movement + * while(!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { + * delay(2); + * } + * + * motor_tare_position(1); + * motor_move_absolute(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_move_absolute(int8_t port, double position, const int32_t velocity); + +/** + * Sets the relative target position for the motor to move to. + * + * This movement is relative to the current position of the motor as given in + * motor_get_position(). Providing 10.0 as the position parameter would result + * in the motor moving clockwise 10 units, no matter what the current position + * is. + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. The example code shows how to + * block until a movement is finished. + * + * \note A negative port will negate the target position + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param position + * The relative position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_relative(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * delay(2); + * } + * + * motor_move_relative(1, 100, 100); // Also moves 100 units forward + * while (!((motor_get_position(1) < 205) && (motor_get_position(1) > 195))) { + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_move_relative(int8_t port, double position, const int32_t velocity); + +/** + * Sets the velocity for the motor. + * + * This velocity corresponds to different actual speeds depending on the gearset + * used for the motor. This results in a range of +-100 for E_MOTOR_GEARSET_36, + * +-200 for E_MOTOR_GEARSET_18, and +-600 for E_MOTOR_GEARSET_6. The velocity + * is held with PID to ensure consistent speed, as opposed to setting the + * motor's voltage. + * + * \note A negative port will negate the velocity + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param velocity + * The new motor velocity from +-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_velocity(1, 100); + * delay(1000); // Move at 100 RPM for 1 second + * motor_move_velocity(1, 0); + * } + * \endcode + */ +int32_t motor_move_velocity(int8_t port, const int32_t velocity); + +/** + * Sets the output voltage for the motor from -12000 to 12000 in millivolts. + * + * \note A negative port negates the voltage + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \note This function will not respect brake modes, and simply sets the + * voltage to the desired value. + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param voltage + * The new voltage value from -12000 to 12000 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_voltage(1, 12000); + * delay(1000); // Move at max voltage for 1 second + * motor_move_voltage(1, 0); + * } + * \endcode + */ +int32_t motor_move_voltage(int8_t port, const int32_t voltage); + +/** + * Changes the output velocity for a profiled movement (motor_move_absolute or + * motor_move_relative). This will have no effect if the motor is not following + * a profiled movement. + * + * \note A negative port negates the velocity + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param velocity + * The new motor velocity from +-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_absolute(1, 100, 100); + * delay(100); + * motor_modify_profiled_velocity(1, 0); // Stop the motor early + * } + * \endcode + */ +int32_t motor_modify_profiled_velocity(int8_t port, const int32_t velocity); + +/** + * Gets the target position set for the motor by the user. + * + * \note A negative port negates the return value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The target position in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_absolute(1, 100, 100); + * printf("Motor Target: %d\n", motor_get_target_position(1)); + * // Prints 100 + * } + * \endcode + */ +double motor_get_target_position(int8_t port); + +/** + * Gets the velocity commanded to the motor by the user. + * + * \note A negative port negates the return value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The commanded motor velocity from +-100, +-200, or +-600, or PROS_ERR + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move_velocity(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Commanded Velocity: %d\n", motor_get_target_velocity(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_get_target_velocity(int8_t port); + +///@} + +/// \name Motor telemetry functions +/// These functions allow programmers to collect telemetry from motors +///@{ + +/** + * Gets the actual velocity of the motor. + * + * \note A negative port negates the return value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's actual velocity in RPM or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Actual velocity: %lf\n", motor_get_actual_velocity(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_actual_velocity(int8_t port); + +/** + * Gets the current drawn by the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's current in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Current Draw: %d\n", motor_get_current_draw(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_get_current_draw(int8_t port); + +/** + * Gets the direction of movement for the motor. + * + * \note A negative port number negates the return value. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return 1 for moving in the positive direction, -1 for moving in the + * negative direction, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Direction: %d\n", motor_get_direction(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_get_direction(int8_t port); + +/** + * Gets the efficiency of the motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Efficiency: %d\n", motor_get_efficiency(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_efficiency(int8_t port); + +/** + * Checks if the motor is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return 1 if the motor's current limit is being exceeded and 0 if the current + * limit is not exceeded, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Current Limit Hit?: %d\n", motor_is_over_current(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_is_over_current(int8_t port); + +/** + * Checks if the motor's temperature is above its limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return 1 if the temperature limit is exceeded and 0 if the the temperature + * is below the limit, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Temp Limit: %d\n", motor_is_over_temp(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_is_over_temp(int8_t port); + + + +#ifdef __cplusplus +} // namespace c +#endif + +/** + * \enum motor_fault_e_t + */ +typedef enum motor_fault_e { + /// No faults + E_MOTOR_FAULT_NO_FAULTS = 0x00, + /// Analogous to motor_is_over_temp() + E_MOTOR_FAULT_MOTOR_OVER_TEMP = 0x01, + /// Indicates a motor h-bridge fault + E_MOTOR_FAULT_DRIVER_FAULT = 0x02, + /// Analogous to motor_is_over_current() + E_MOTOR_FAULT_OVER_CURRENT = 0x04, + /// Indicates an h-bridge over current + E_MOTOR_FAULT_DRV_OVER_CURRENT = 0x08 +} motor_fault_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define MOTOR_FAULT_NO_FAULTS pros::E_MOTOR_FAULT_NO_FAULTS +#define MOTOR_FAULT_MOTOR_OVER_TEMP pros::E_MOTOR_FAULT_MOTOR_OVER_TEMP +#define MOTOR_FAULT_DRIVER_FAULT pros::E_MOTOR_FAULT_DRIVER_FAULT +#define MOTOR_FAULT_OVER_CURRENT pros::E_MOTOR_FAULT_DRV_OVER_CURRENT +#define MOTOR_FAULT_DRV_OVER_CURRENT pros::E_MOTOR_FAULT_DRV_OVER_CURRENT +#else +#define MOTOR_FAULT_NO_FAULTS E_MOTOR_FAULT_NO_FAULTS +#define MOTOR_FAULT_MOTOR_OVER_TEMP E_MOTOR_FAULT_MOTOR_OVER_TEMP +#define MOTOR_FAULT_DRIVER_FAULT E_MOTOR_FAULT_DRIVER_FAULT +#define MOTOR_FAULT_OVER_CURRENT E_MOTOR_FAULT_DRV_OVER_CURRENT +#define MOTOR_FAULT_DRV_OVER_CURRENT E_MOTOR_FAULT_DRV_OVER_CURRENT +#endif +#endif + +#ifdef __cplusplus +namespace c { +#endif + +/** + * Gets the faults experienced by the motor. + * + * Compare this bitfield to the bitmasks in motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * + * \return A bitfield containing the motor's faults. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Faults: %d\n", motor_get_faults(1)); + * delay(2); + * } + * } + * \endcode + */ +uint32_t motor_get_faults(int8_t port); + +#ifdef __cplusplus +} // namespace c +#endif + +/** + * \enum motor_flag_e_t + * + */ +typedef enum motor_flag_e { + ///There are no flags raised + E_MOTOR_FLAGS_NONE = 0x00, + /// Cannot currently communicate to the motor + E_MOTOR_FLAGS_BUSY = 0x01, + /// Analogous to motor_is_stopped() + E_MOTOR_FLAGS_ZERO_VELOCITY = 0x02, + /// Analogous to motor_get_zero_position_flag() + E_MOTOR_FLAGS_ZERO_POSITION = 0x04 +} motor_flag_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define MOTOR_FLAGS_NONE pros::E_MOTOR_FLAGS_NONE +#define MOTOR_FLAGS_BUSY pros::E_MOTOR_FLAGS_BUSY +#define MOTOR_FLAGS_ZERO_VELOCITY pros::E_MOTOR_FLAGS_ZERO_VELOCITY +#define MOTOR_FLAGS_ZERO_POSITION pros::E_MOTOR_FLAGS_ZERO_POSITION +#else +#define MOTOR_FLAGS_NONE E_MOTOR_FLAGS_NONE +#define MOTOR_FLAGS_BUSY E_MOTOR_FLAGS_BUSY +#define MOTOR_FLAGS_ZERO_VELOCITY E_MOTOR_FLAGS_ZERO_VELOCITY +#define MOTOR_FLAGS_ZERO_POSITION E_MOTOR_FLAGS_ZERO_POSITION +#endif +#endif + +#ifdef __cplusplus +namespace c { +#endif + +/** + * Gets the flags set by the motor's operation. + * + * Compare this bitfield to the bitmasks in motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return A bitfield containing the motor's flags. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Flags: %d\n", motor_get_flags(1)); + * delay(2); + * } + * } + * \endcode + */ +uint32_t motor_get_flags(int8_t port); + +/** + * Gets the raw encoder count of the motor at a given timestamp. + * + * \note A negative port value negates the return value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param[in] timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \return The raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. + * + * \b Example + * \code + * void opcontrol() { + * uint32_t now = millis(); + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Encoder Count: %d\n", motor_get_raw_position(1, &now)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_get_raw_position(int8_t port, uint32_t* const timestamp); + +/** + * Gets the absolute position of the motor in its encoder units. + * + * \note A negative port value negates the return value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Position: %lf\n", motor_get_position(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_position(int8_t port); + +/** + * Gets the power drawn by the motor in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * uint32_t now = millis(); + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Power: %lf\n", motor_get_power(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_power(int8_t port); + +/** + * Gets the temperature of the motor in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Temperature: %lf\n", motor_get_temperature(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_temperature(int8_t port); + +/** + * Gets the torque generated by the motor in Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Torque: %lf\n", motor_get_torque(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_torque(int8_t port); + +/** + * Gets the voltage delivered to the motor in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Voltage: %lf\n", motor_get_voltage(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_get_voltage(int8_t port); + +///@} + +/// \name Motor configuration functions +/// These functions allow programmers to configure the behavior of motors +///@{ + +#ifdef __cplusplus +} // namespace c +#endif + +/** + * \enum motor_brake_mode_e_t + * Indicates the current 'brake mode' of a motor. + */ +typedef enum motor_brake_mode_e { + /// Motor coasts when stopped, traditional behavior + E_MOTOR_BRAKE_COAST = 0, + /// Motor brakes when stopped + E_MOTOR_BRAKE_BRAKE = 1, + /// Motor actively holds position when stopped + E_MOTOR_BRAKE_HOLD = 2, + /// Invalid brake mode + E_MOTOR_BRAKE_INVALID = INT32_MAX +} motor_brake_mode_e_t; + +/** + * \enum motor_encoder_units_e_t + * Indicates the units used by the motor encoders. + */ +typedef enum motor_encoder_units_e { + /// Position is recorded as angle in degrees as a floating point number + E_MOTOR_ENCODER_DEGREES = 0, + /// Position is recorded as angle in rotations as a floating point number + E_MOTOR_ENCODER_ROTATIONS = 1, + /// Position is recorded as raw encoder ticks as a whole number + E_MOTOR_ENCODER_COUNTS = 2, + ///Invalid motor encoder units + E_MOTOR_ENCODER_INVALID = INT32_MAX +} motor_encoder_units_e_t; + +/** + * \enum motor_gearset_e_t + * Indicates the current internal gear ratio of a motor. + */ +typedef enum motor_gearset_e { + E_MOTOR_GEARSET_36 = 0, // 36:1, 100 RPM, Red gear set + E_MOTOR_GEAR_RED = E_MOTOR_GEARSET_36, // 36:1, 100 RPM, Red gear set + E_MOTOR_GEAR_100 = E_MOTOR_GEARSET_36, // 36:1, 100 RPM, Red gear set + E_MOTOR_GEARSET_18 = 1, // 18:1, 200 RPM, Green gear set + E_MOTOR_GEAR_GREEN = E_MOTOR_GEARSET_18, // 18:1, 200 RPM, Green gear set + E_MOTOR_GEAR_200 = E_MOTOR_GEARSET_18, // 18:1, 200 RPM, Green gear set + E_MOTOR_GEARSET_06 = 2, // 6:1, 600 RPM, Blue gear set + E_MOTOR_GEAR_BLUE = E_MOTOR_GEARSET_06, // 6:1, 600 RPM, Blue gear set + E_MOTOR_GEAR_600 = E_MOTOR_GEARSET_06, // 6:1, 600 RPM, Blue gear set + E_MOTOR_GEARSET_INVALID = INT32_MAX, // Error: Invalid Gearset +} motor_gearset_e_t; + +/** + * \enum motor_type_e_t + * Indicates the type of a motor + */ +typedef enum motor_type_e { + E_MOTOR_TYPE_V5 = 0, // 11 watt V5 motor + E_MOTOR_TYPE_EXP = 1, // 5.5 watt EXP motor + E_MOTOR_TYPE_INVALID = INT32_MAX, // Error: invalid type +} motor_type_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define MOTOR_BRAKE_COAST pros::E_MOTOR_BRAKE_COAST +#define MOTOR_BRAKE_BRAKE pros::E_MOTOR_BRAKE_BRAKE +#define MOTOR_BRAKE_HOLD pros::E_MOTOR_BRAKE_HOLD +#define MOTOR_BRAKE_INVALID pros::E_MOTOR_BRAKE_INVALID +#define MOTOR_ENCODER_DEGREES pros::E_MOTOR_ENCODER_DEGREES +#define MOTOR_ENCODER_ROTATIONS pros::E_MOTOR_ENCODER_ROTATIONS +#define MOTOR_ENCODER_COUNTS pros::E_MOTOR_ENCODER_COUNTS +#define MOTOR_ENCODER_INVALID pros::E_MOTOR_ENCODER_INVALID +#define MOTOR_GEARSET_36 pros::E_MOTOR_GEARSET_36 +#define MOTOR_GEAR_RED pros::E_MOTOR_GEAR_RED +#define MOTOR_GEAR_100 pros::E_MOTOR_GEAR_100 +#define MOTOR_GEARSET_18 pros::E_MOTOR_GEARSET_18 +#define MOTOR_GEAR_GREEN pros::E_MOTOR_GEAR_GREEN +#define MOTOR_GEAR_200 pros::E_MOTOR_GEAR_200 +#define MOTOR_GEARSET_06 pros::E_MOTOR_GEARSET_06 +#define MOTOR_GEARSET_6 pros::E_MOTOR_GEARSET_06 +#define MOTOR_GEAR_BLUE pros::E_MOTOR_GEAR_BLUE +#define MOTOR_GEAR_600 pros::E_MOTOR_GEAR_600 +#define MOTOR_GEARSET_INVALID pros::E_MOTOR_GEARSET_INVALID +#define MOTOR_TYPE_V5 pros::E_MOTOR_TYPE_V5 +#define MOTOR_TYPE_EXP pros::E_MOTOR_TYPE_EXP +#define MOTOR_TYPE_INVALID pros::E_MOTOR_TYPE_INVALID +#else +#define MOTOR_BRAKE_COAST E_MOTOR_BRAKE_COAST +#define MOTOR_BRAKE_BRAKE E_MOTOR_BRAKE_BRAKE +#define MOTOR_BRAKE_HOLD E_MOTOR_BRAKE_HOLD +#define MOTOR_BRAKE_INVALID E_MOTOR_BRAKE_INVALID +#define MOTOR_ENCODER_DEGREES E_MOTOR_ENCODER_DEGREES +#define MOTOR_ENCODER_ROTATIONS E_MOTOR_ENCODER_ROTATIONS +#define MOTOR_ENCODER_COUNTS E_MOTOR_ENCODER_COUNTS +#define MOTOR_ENCODER_INVALID E_MOTOR_ENCODER_INVALID +#define MOTOR_GEARSET_36 E_MOTOR_GEARSET_36 +#define MOTOR_GEAR_RED E_MOTOR_GEAR_RED +#define MOTOR_GEAR_100 E_MOTOR_GEAR_100 +#define MOTOR_GEARSET_18 E_MOTOR_GEARSET_18 +#define MOTOR_GEAR_GREEN E_MOTOR_GEAR_GREEN +#define MOTOR_GEAR_200 E_MOTOR_GEAR_200 +#define MOTOR_GEARSET_06 E_MOTOR_GEARSET_06 +#define MOTOR_GEARSET_6 E_MOTOR_GEARSET_06 +#define MOTOR_GEAR_BLUE E_MOTOR_GEAR_BLUE +#define MOTOR_GEAR_600 E_MOTOR_GEAR_600 +#define MOTOR_GEARSET_INVALID E_MOTOR_GEARSET_INVALID +#define MOTOR_TYPE_V5 E_MOTOR_TYPE_V5 +#define MOTOR_TYPE_EXP E_MOTOR_TYPE_EXP +#define MOTOR_TYPE_INVALID E_MOTOR_TYPE_INVALID +#endif +#endif + +/** + * \struct motor_pid_full_s_t + * + * Holds the information about a Motor's position or velocity PID controls. + * + * These values are in 4.4 format, meaning that a value of 0x20 represents 2.0, + * 0x21 represents 2.0625, 0x22 represents 2.125, etc. + */ +typedef struct motor_pid_full_s { + /// The feedforward constant + uint8_t kf; + /// The proportional constant + uint8_t kp; + /// The integral constants + uint8_t ki; + /// The derivative constant + uint8_t kd; + /// A constant used for filtering the profile acceleration + uint8_t filter; + /// The integral limit + uint16_t limit; + /// The threshold for determining if a position movement hasreached its goa l. This has no effect for velocity PID calculations. + uint8_t threshold; + /// The rate at which the PID computation is run in ms + uint8_t loopspeed; +} motor_pid_full_s_t; + +/** + * \struct motor_pid_s_t + * + * Holds just the constants for a Motor's position or velocity PID controls. + * + * These values are in 4.4 format, meaning that a value of 0x20 represents 2.0, + * 0x21 represents 2.0625, 0x22 represents 2.125, etc. + */ +typedef struct motor_pid_s { + /// The feedforward constant + uint8_t kf; + /// The proportional constant + uint8_t kp; + /// The integral constants + uint8_t ki; + /// The derivative constant + uint8_t kd; +} motor_pid_s_t; + +#ifdef __cplusplus +namespace c { +#endif + +/** + * Sets the position for the motor in its encoder units. + * + * This will be the future reference point for the motor's "absolute" position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param position + * The new reference position in its encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * + * \code + * void autonomous() { + * motor_move_absolute(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * delay(2); + * } + * motor_move_absolute(1, 100, 100); // This does not cause a movement + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * delay(2); + * } + * + * motor_set_zero_position(1, 80); + * motor_move_absolute(1, 100, 100); // Moves 20 units forward + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_set_zero_position(int8_t port, const double position); + +/** + * Sets the "absolute" zero position of the motor to its current position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_absolute(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * delay(2); + * } + * motor_move_absolute(1, 100, 100); // This does not cause a movement + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * delay(2); + * } + * + * motor_tare_position(1); + * motor_move_absolute(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_tare_position(int8_t port); + +/** + * Sets one of motor_brake_mode_e_t to the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param mode + * The motor_brake_mode_e_t to set for the motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * motor_set_brake_mode(1, E_MOTOR_BRAKE_HOLD); + * printf("Brake Mode: %d\n", motor_get_brake_mode(1)); + * } + * \endcode + */ +int32_t motor_set_brake_mode(int8_t port, const motor_brake_mode_e_t mode); + +/** + * Sets the current limit for the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param limit + * The new current limit in mA + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * motor_set_current_limit(1, 1000); + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * // The motor will reduce its output at 1000 mA instead of the default 2500 mA + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_set_current_limit(int8_t port, const int32_t limit); + +/** + * Sets one of motor_encoder_units_e_t for the motor encoder. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param units + * The new motor encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * motor_set_encoder_units(1, E_MOTOR_ENCODER_DEGREES); + * printf("Encoder Units: %d\n", motor_get_encoder_units(1)); + * } + * \endcode + */ +int32_t motor_set_encoder_units(int8_t port, const motor_encoder_units_e_t units); + +/** + * Sets one of motor_gearset_e_t for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param gearset + * The new motor gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * motor_set_gearing(1, E_MOTOR_GEARSET_06); + * printf("Brake Mode: %d\n", motor_get_gearing(1)); + * } + * \endcode + */ +int32_t motor_set_gearing(int8_t port, const motor_gearset_e_t gearset); + +/** + * Sets the voltage limit for the motor in Volts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param limit + * The new voltage limit in Volts + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_set_voltage_limit(1, 10000); + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * // The motor will not output more than 10 V + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_set_voltage_limit(int8_t port, const int32_t limit); + +/** + * Gets the brake mode that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return One of motor_brake_mode_e_t, according to what was set for the motor, + * or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * motor_set_brake_mode(1, E_MOTOR_BRAKE_HOLD); + * printf("Brake Mode: %d\n", motor_get_brake_mode(1)); + * } + * \endcode + */ +motor_brake_mode_e_t motor_get_brake_mode(int8_t port); + +/** + * Gets the current limit for the motor in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void initialize() { + * printf("Motor Current Limit: %d\n", motor_get_current_limit(1)); + * // Prints "Motor Current Limit: 2500" + * } + * \endcode + */ +int32_t motor_get_current_limit(int8_t port); + +/** + * Gets the encoder units that were set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return One of motor_encoder_units_e_t according to what is set for the motor + * or E_MOTOR_ENCODER_INVALID if the operation failed. + */ +motor_encoder_units_e_t motor_get_encoder_units(int8_t port); + +/** + * Gets the gearset that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return One of motor_gearset_e_t according to what is set for the motor, + * or E_GEARSET_INVALID if the operation failed. + * + * \b Example + * \code + * void initialize() { + * printf("Motor Encoder Units: %d\n", motor_get_encoder_units(1)); + * // Prints E_MOTOR_ENCODER_DEGREES by default + * } + * \endcode + */ +motor_gearset_e_t motor_get_gearing(int8_t port); + +/** + * Gets the voltage limit set by the user. + * + * Default value is 0V, which means that there is no software limitation imposed + * on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's voltage limit in V or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void initialize() { + * printf("Motor Voltage Limit: %d\n", motor_get_voltage_limit(1)); + * // Prints 0 by default, indicating no limit + * } + * \endcode + */ +int32_t motor_get_voltage_limit(int8_t port); + +/** + * Get the type of the motor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21| + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return One of motor_type_e_t according to the type of the motor, or + * E_MOTOR_TYPE_INVALID if the operation failed. + * + * \b Example + * \code + * void initialize() { + * printf("Motor Type: %d\n", motor_get_type(1)); + * // Prints the type of the motor + * } + * \endcode + */ +motor_type_e_t motor_get_type(int8_t port); + +///@} + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_MOTORS_H_ diff --git a/test/include/pros/motors.hpp b/test/include/pros/motors.hpp new file mode 100644 index 00000000..02ae233c --- /dev/null +++ b/test/include/pros/motors.hpp @@ -0,0 +1,2477 @@ +/** + * \file pros/motors.hpp + * \ingroup cpp-motors + * + * Contains prototypes for the V5 Motor-related functions. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-motors Motors C++ API + * \note Additional example code for this module can be found in its [Tutorial](@ref motors). + */ + +#ifndef _PROS_MOTORS_HPP_ +#define _PROS_MOTORS_HPP_ + +#include +#include + +#include "pros/abstract_motor.hpp" +#include "pros/device.hpp" +#include "pros/motors.h" +#include "rtos.hpp" + +namespace pros { +inline namespace v5 { + +class Motor : public AbstractMotor, public Device { + public: + /** + * \addtogroup cpp-motors + * @{ + */ + + /** + * Constructs a new Motor object. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors. + * A reversed motor will reverse the input or output movement functions and movement related + * telemetry in order to produce consistant behavior with non-reversed motors + * + * \param gearset = pros::v5::MotorGears::green + * Optional parameter for the gearset for the motor. + * Does not explicitly set the gearset if not specified or if the gearset is invalid + * + * \param encoder_units = pros::v5::MotorUnits::degrees + * Optional parameter for the encoder units of the motor + * Does not explicitly set the gearset if not specified or if the gearset is invalid + * + * \b Example + * \code + * void opcontrol() { + * Motor first_motor(1); //Creates a motor on port 1 without altering gearset or encoder units + * Motor reversed_motor(-2); //Creates a reversed motor on port 1 port 1 without altering gearset or encoder units + * Motor blue_motor(3, pros::v5::MotorGears::blue); //Creates a motor on port 3 with blue gear set + * Motor rotations_motor(4, pros::v5::MotorGears::green, pros::v5::MotorUnits::rotations); //port 4 w/ rotations + * + * } + * \endcode + * + */ + Motor(const std::int8_t port, const pros::v5::MotorGears gearset = pros::v5::MotorGears::invalid, + const pros::v5::MotorUnits encoder_units = pros::v5::MotorUnits::invalid); + + Motor(const Device& device) : Motor(device.get_port()){}; + + /// \name Motor movement functions + /// These functions allow programmers to make motors move + ///@{ + + /** + * Sets the voltage for the motor from -127 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is + * analogous to use of motor_move(). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param voltage + * The new motor voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor Motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor.move(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t move(std::int32_t voltage) const; + + /** + * Sets the target absolute position for the motor to move to. + * + * This movement is relative to the position of the motor when initialized or + * the position when it was most recently reset with + * pros::Motor::set_zero_position(). + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The absolute position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * pros::delay(2); + * } + * motor.move_absolute(100, 100); // This does not cause a movement + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * pros::delay(2); + * } + * motor.tare_position(); + * motor.move_absolute(100, 100); // Moves 100 units forward + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t move_absolute(const double position, const std::int32_t velocity) const; + + /** + * Sets the relative target position for the motor to move to. + * + * This movement is relative to the current position of the motor as given in + * pros::Motor::motor_get_position(). Providing 10.0 as the position parameter + * would result in the motor moving clockwise 10 units (counter clockwise if reversed), + * no matter what the current position is. + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The relative position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_relative(100, 100); // Moves 100 units forward + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * pros::delay(2); + * } + * motor.move_relative(100, 100); // Also moves 100 units forward + * while (!((motor.get_position() < 205) && (motor.get_position() > 195))) { + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t move_relative(const double position, const std::int32_t velocity) const; + + /** + * Sets the velocity for the motor. + * + * This velocity corresponds to different actual speeds depending on the + * gearset used for the motor. This results in a range of +-100 for + * E_MOTOR_GEARSET_36, +-200 for E_MOTOR_GEARSET_18, and +-600 for + * E_MOTOR_GEARSET_6. The velocity is held with PID to ensure consistent + * speed, as opposed to setting the motor's voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param velocity + * The new motor velocity from -+-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_velocity(100); + * pros::delay(1000); // Move at 100 RPM for 1 second + * motor.move_velocity(0); + * } + * \endcode + */ + std::int32_t move_velocity(const std::int32_t velocity) const; + + /** + * Sets the output voltage for the motor from -12000 to 12000 in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * \param voltage + * The new voltage value from -12000 to 12000 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor.move_voltage(12000); + * pros::delay(1000); // Move at max voltage for 1 second + * motor.move_voltage(0); + * } + * \endcode + */ + std::int32_t move_voltage(const std::int32_t voltage) const; + + /** + * Stops the motor using the currently configured brake mode. + * + * This function sets motor velocity to zero, which will cause it to act + * according to the set brake mode. If brake mode is set to MOTOR_BRAKE_HOLD, + * this function may behave differently than calling move_absolute(0) + * or motor_move_relative(0). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * Motor motor(1); + * motor.move_voltage(12000); + * pros::delay(1000); // Move at max voltage for 1 second + * motor.brake(); + * } + * \endcode + */ + std::int32_t brake(void) const; + + /** + * Changes the output velocity for a profiled movement (motor_move_absolute or + * motor_move_relative). This will have no effect if the motor is not following + * a profiled movement. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param velocity + * The new motor velocity from +-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); + * pros::delay(100); + * motor.modify_profiled_velocity(0); // Stop the motor early + * } + * \endcode + */ + std::int32_t modify_profiled_velocity(const std::int32_t velocity) const; + + ///@} + + /// \name Motor telemetry functions + /// These functions allow programmers to collect telemetry from motors + ///@{ + + /** + * Gets the target position set for the motor by the user + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The target position in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); + * std::cout << "Motor Target: " << motor.get_target_position(); + * // Prints 100 + * } + * \endcode + */ + double get_target_position(const std::uint8_t index = 0) const; + + /** + * Gets the velocity commanded to the motor by the user at the index specified. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The commanded motor velocity from +-100, +-200, or +-600, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * std::cout << "Motor Velocity: " << motor.get_target_velocity(); + * // Prints the value of E_CONTROLLER_ANALOG_LEFT_Y + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_target_velocity(const std::uint8_t index = 0) const; + + /** + * Gets the actual velocity of the motor. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The motor's actual velocity in RPM or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * while (true) { + * motor = controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y); + * printf("Actual velocity: %lf\n", motor.get_actual_velocity()); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_actual_velocity(const std::uint8_t index = 0) const; + + /** + * Gets the current drawn by the motor in mA. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The motor's current in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Current Draw: " << motor.get_current_draw(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_current_draw(const std::uint8_t index = 0) const; + + /** + * Gets the direction of movement for the motor. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Direction: " << motor.get_direction(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_direction(const std::uint8_t index = 0) const; + + /** + * Gets the efficiency of the motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Efficiency: " << motor.get_efficiency(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_efficiency(const std::uint8_t index = 0) const; + + /** + * Gets the faults experienced by the motor. + * + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * + * \return A bitfield containing the motor's faults. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << motor.get_faults();pros::delay(2); + * } + * } + * \endcode + */ + std::uint32_t get_faults(const std::uint8_t index = 0) const; + + /** + * Gets the flags set by the motor's operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return A bitfield containing the motor's flags. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << motor.get_faults(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::uint32_t get_flags(const std::uint8_t index = 0) const; + + /** + * Gets the absolute position of the motor in its encoder units. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << motor.get_position(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_position(const std::uint8_t index = 0) const; + + /** + * Gets the power drawn by the motor in Watts. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Power: " << motor.get_power(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_power(const std::uint8_t index = 0) const; + + /** + * Gets the raw encoder count of the motor at a given timestamp. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * + * \param timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * + * + * \return The raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. + * + * \b Example + * \code + * void opcontrol() { + * std::uint32_t now = pros::millis(); + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << motor.get_raw_position(&now); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_raw_position(std::uint32_t* const timestamp, const std::uint8_t index = 0) const; + + /** + * Gets the temperature of the motor in degrees Celsius. + + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Temperature: " << motor.get_temperature(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_temperature(const std::uint8_t index = 0) const; + + /** + * Gets the torque generated by the motor in Newton Meters (Nm). + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Torque: " << motor.get_torque(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_torque(const std::uint8_t index = 0) const; + + /** + * Gets the voltage delivered to the motor in millivolts. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Voltage: " << motor.get_voltage(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_voltage(const std::uint8_t index = 0) const; + + /** + * Checks if the motor is drawing over its current limit. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its current limit?: " << motor.is_over_current(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t is_over_current(const std::uint8_t index = 0) const; + + /** + * Gets the temperature limit flag for the motor. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its temperature limit?: " << motor.is_over_temp(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t is_over_temp(const std::uint8_t index = 0) const; + + ///@} + + /// \name Motor configuration functions + /// These functions allow programmers to configure the behavior of motors + ///@{ + + /** + * Gets the brake mode that was set for the motor. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return One of MotorBrake, according to what was set for the + * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * } + * \endcode + */ + MotorBrake get_brake_mode(const std::uint8_t index = 0) const; + + /** + * Gets the current limit for the motor in mA. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return The motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * while (true) { + * std::cout << "Motor Current Limit: " << motor.get_current_limit(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_current_limit(const std::uint8_t index = 0) const; + + /** + * Gets the encoder units that were set for the motor. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return One of MotorUnits according to what is set for the + * motor or E_MOTOR_ENCODER_INVALID if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Encoder Units: " << motor.get_encoder_units(); + * } + * \endcode + */ + MotorUnits get_encoder_units(const std::uint8_t index = 0) const; + + /** + * Gets the gearset that was set for the motor. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return One of MotorGears according to what is set for the motor, + * or pros::MotorGears::invalid if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Gearing: " << motor.get_gearing(); + * } + * \endcode + */ + MotorGears get_gearing(const std::uint8_t index = 0) const; + + /** + * Gets the voltage limit set by the user. + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * std::cout << "Motor Voltage Limit: " << motor.get_voltage_limit(); + * } + * \endcode + */ + std::int32_t get_voltage_limit(const std::uint8_t index = 0) const; + + /** + * Gets whether the motor is reversed or not + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * std::cout << "Is the motor reversed? " << motor.is_reversed(); + * // Prints "0" + * } + * \endcode + */ + std::int32_t is_reversed(const std::uint8_t index = 0) const; + + /** + * Gets the type of the motor + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the type of. + * By default index is 0, and will return an error for a non-zero index + * + * \return One of MotorType according to the type of the motor, + * or pros::MotorType::invalid if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Type: " << motor.get_type(); + * } + * \endcode + */ + MotorType get_type(const std::uint8_t index = 0) const; + + /** + * Sets one of Motor_Brake to the motor. + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * + * \param mode + * The MotorBrake to set for the motor + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * } + * \endcode + */ + std::int32_t set_brake_mode(const MotorBrake mode, const std::uint8_t index = 0) const; + /** + * Sets one of MotorBrake to the motor. + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * + * \param mode + * The MotorBrake to set for the motor + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * } + * \endcode + */ + std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index = 0) const; + /** + * Sets the current limit for the motor in mA. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param limit + * The new current limit in mA + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * motor.set_current_limit(1000); + * while (true) { + * motor = controller_get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will reduce its output at 1000 mA instead of the default 2500 mA + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t set_current_limit(const std::int32_t limit, const std::uint8_t index = 0) const; + + /** + * Sets one of MotorUnits for the motor encoder. Works with the C + * enum and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param units + * The new motor encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_encoder_units(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << motor.get_encoder_units(); + * } + * \endcode + */ + std::int32_t set_encoder_units(const MotorUnits units, const std::uint8_t index = 0) const; + /** + * Sets one of MotorUnits for the motor encoder. Works with the C + * enum and the C++ enum class. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * * \param units + * The new motor encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_encoder_units(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << motor.get_encoder_units(); + * } + * \endcode + */ + std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index = 0) const; + /** + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * \param gearset + * The new motor gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_gearing(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << motor.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing(const MotorGears gearset, const std::uint8_t index = 0) const; + + /** + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. + + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param gearset + * The new motor gearset + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_gearing(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << motor.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing(const pros::motor_gearset_e_t gearset, const std::uint8_t index = 0) const; + + /** + * Sets the reverse flag for the motor. + * + * This will invert its movements and the values returned for its position. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * EOVERFLOW - The index is non 0 + * + * \param reverse + * True reverses the motor, false is default direction + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_reversed(true); + * std::cout << "Is this motor reversed? " << motor.is_reversed(); + * } + * \endcode + */ + std::int32_t set_reversed(const bool reverse, const std::uint8_t index = 0); + + /** + * Sets the voltage limit for the motor in Volts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param limit + * The new voltage limit in Volts + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * motor.set_voltage_limit(10000); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will not output more than 10 V + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t set_voltage_limit(const std::int32_t limit, const std::uint8_t index = 0) const; + + /** + * Sets the position for the motor in its encoder units. + * + * This will be the future reference point for the motor's "absolute" + * position. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param position + * The new reference position in its encoder units + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * motor.move_absolute(100, 100); // This does not cause a movement + * + * motor.set_zero_position(80); + * motor.move_absolute(100, 100); // Moves 20 units forward + * } + * \endcode + * + */ + std::int32_t set_zero_position(const double position, const std::uint8_t index = 0) const; + + /** + * Sets the "absolute" zero position of the motor to its current position. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * motor.move_absolute(100, 100); // This does not cause a movement + * + * motor.tare_position(); + * motor.move_absolute(100, 100); // Moves 100 units forward + * } + * \endcode + */ + std::int32_t tare_position(const std::uint8_t index = 0) const; + + /** + * Gets the number of motors. + * + * \return Always returns 1 + * + */ + std::int8_t size(void) const; + + /** + * Gets all motors. + * + * \return A vector of Motor objects. + * + * \b Example + * \code + * void opcontrol() { + * std::vector motor_all = pros::Motor::get_all_devices(); // All motors that are connected + * } + * \endcode + */ + static std::vector get_all_devices(); + + /** + * gets the port number of the motor + * + * \return The signed port of the motor. (negative if the motor is reversed) + * + */ + std::int8_t get_port(const std::uint8_t index = 0) const; + + ///@} + + /// \name Additional motor functions + /// These functions allow for motors and motor groups to be used interchangeably + ///@{ + /** + * Gets a vector containing the target position set for the motor by the user + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing the target position in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); + * std::cout << "Motor Target: " << motor.get_target_position_all()[0]; + * // Prints 100 + * } + * \endcode + */ + std::vector get_target_position_all(void) const; + + /** + * Gets a vector containing the velocity commanded to the motor by the user + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the commanded motor velocity from +-100, + * +-200, or +-600, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * std::cout << "Motor Velocity: " << motor.get_target_velocity_all()[0]; + * // Prints the value of E_CONTROLLER_ANALOG_LEFT_Y + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_target_velocity_all(void) const; + + /** + * Gets a vector containing the actual velocity commanded of the motor + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's actual velocity in RPM or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * std::cout << "Motor Velocity: " << motor.get_actual_velocity_all()[0]; + * // Prints the value of E_CONTROLLER_ANALOG_LEFT_Y + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_actual_velocity_all(void) const; + + /** + * Gets a vector containing the current drawn by the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing the motor's current in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Current Draw: " << motor.get_current_draw_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_current_draw_all(void) const; + + /** + * Gets a vector containing the direction of movement for the motor. + * + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Direction: " << motor.get_direction_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_direction_all(void) const; + + /** + * Gets a vector containing the efficiency of the motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Efficiency: " << motor.get_efficiency(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_efficiency_all(void) const; + + /** + * Gets a vector of the faults experienced by the motor. + * + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \return A bitfield containing the motor's faults. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << motor.get_faults_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_faults_all(void) const; + + /** + * Gets a vector of the flags set by the motor's operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A bitfield containing the motor's flags. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << motor.get_faults_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_flags_all(void) const; + + /** + * Gets a vector containing the absolute position of the motor in its encoder units. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + + * + * \return A vector containing the motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << motor.get_position_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_position_all(void) const; + + /** + * Gets a vector containing the power drawn by the motor in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Power: " << motor.get_power_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_power_all(void) const; + + /** + * Gets a vector of the raw encoder count of the motor at a given timestamp. + * + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \param timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \return A vector containing the raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. + * + * \b Example + * \code + * void opcontrol() { + * std::uint32_t now = pros::millis(); + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << motor.get_raw_position(&now); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_raw_position_all(std::uint32_t* const timestamp) const; + + /** + * Gets a vector of the temperature of the motor in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector contaioning the motor's temperature in degrees Celsius + * or PROS_ERR_F if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Temperature: " << motor.get_temperature_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_temperature_all(void) const; + + /** + * Gets a vector of the torque generated by the motor in Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Torque: " << motor.get_torque(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_torque_all(void) const; + + /** + * Gets a vector of the voltage delivered to the motor in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector of the motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Voltage: " << motor.get_voltage_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_voltage_all(void) const; + + /** + * Checks if the motor is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its current limit?: " << motor.is_over_current_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector is_over_current_all(void) const; + + /** + * Gets the temperature limit flag for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its temperature limit?: " << motor.is_over_temp_all(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector is_over_temp_all(void) const; + + /** + * Gets a vector containing the brake mode that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return One of Motor_Brake, according to what was set for the + * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * } + * \endcode + */ + std::vector get_brake_mode_all(void) const; + + /** + * Gets a vector containing the current limit for the motor in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * while (true) { + * std::cout << "Motor Current Limit: " << motor.get_current_limit_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_current_limit_all(void) const; + + /** + * Gets a vector containing the encoder units that were set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing One of Motor_Units according to what is set for the + * motor or E_MOTOR_ENCODER_INVALID if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Encoder Units: " << motor.get_encoder_units_all()[0]; + * } + * \endcode + */ + std::vector get_encoder_units_all(void) const; + + /** + * Gets a vector containing the gearset that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing one of Motor_Gears according to what is set for the motor, + * or pros::Motor_Gears::invalid if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Gearing: " << motor.get_gearing_all()[0]; + * } + * \endcode + */ + std::vector get_gearing_all(void) const; + + /** + * Gets returns a vector with all the port numbers in the motor group. + * + * \return A vector containing the signed port of the motor. (negative if the motor is reversed) + */ + std::vector get_port_all(void) const; + + /** + * Gets a vector of the voltage limit set by the user. + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's voltage limit in V or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * std::cout << "Motor Voltage Limit: " << motor.get_voltage_limit_all()[0]; + * } + * \endcode + */ + std::vector get_voltage_limit_all(void) const; + + /** + * Gets a vector containg whether the motor is reversed or not + * + * \return A vector containing 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * std::cout << "Is the motor reversed? " << motor.is_reversed_all()[0]; + * // Prints "0" + * } + * \endcode + */ + std::vector is_reversed_all(void) const; + + /** + * Gets a vector containing the type of the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing one of MotorType according to the type of the motor, + * or pros::MotorType::invalid if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Type: " << motor.get_type_all()[0]; + * } + * \endcode + */ + std::vector get_type_all(void) const; + + /** + * Sets one of Motor_Brake to the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param mode + * The Motor_Brake to set for the motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_brake_mode_all(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * } + * \endcode + */ + std::int32_t set_brake_mode_all(const MotorBrake mode) const; + + /** + * Sets one of Motor_Brake to the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param mode + * The Motor_Brake to set for the motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_brake_mode_all(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * } + * \endcode + */ + std::int32_t set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const; + + /** + * Sets the current limit for the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param limit + * The new current limit in mA + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * motor.set_current_limit_all(1000); + * while (true) { + * motor = controller_get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will reduce its output at 1000 mA instead of the default 2500 mA + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t set_current_limit_all(const std::int32_t limit) const; + + /** + * Sets one of Motor_Units for the motor encoder. Works with the C + * enum and the C++ enum class. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * * \param units + * The new motor encoder units + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_encoder_units_all(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << motor.get_encoder_units(); + * } + * \endcode + */ + std::int32_t set_encoder_units_all(const MotorUnits units) const; + + /** + * Sets one of Motor_Units for the motor encoder. Works with the C + * enum and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param units + * The new motor encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_encoder_units_all(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << motor.get_encoder_units(); + * } + * \endcode + */ + std::int32_t set_encoder_units_all(const pros::motor_encoder_units_e_t units) const; + + /** + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param gearset + * The new motor gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_gearing_all(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << motor.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing_all(const MotorGears gearset) const; + + /** + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param gearset + * The new motor gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_gearing_all(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << motor.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing_all(const pros::motor_gearset_e_t gearset) const; + + /** + * Sets the reverse flag for the motor. + * + * This will invert its movements and the values returned for its position. + * + * + * \param reverse + * True reverses the motor, false is default direction + * + * \return 1 + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_reversed_all(true); + * std::cout << "Is this motor reversed? " << motor.is_reversed(); + * } + * \endcode + */ + std::int32_t set_reversed_all(const bool reverse); + + /** + * Sets the voltage limit for the motor in Volts. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param limit + * The new voltage limit in Volts + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * motor.set_voltage_limit_all(10000); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will not output more than 10 V + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t set_voltage_limit_all(const std::int32_t limit) const; + + /** + * Sets the position for the motor in its encoder units. + * + * This will be the future reference point for the motor's "absolute" + * position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The new reference position in its encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * motor.move_absolute(100, 100); // This does not cause a movement + * + * motor.set_zero_position_all(80); + * motor.move_absolute(100, 100); // Moves 20 units forward + * } + * \endcode + * + */ + std::int32_t set_zero_position_all(const double position) const; + + /** + * Sets the "absolute" zero position of the motor to its current position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * motor.move_absolute(100, 100); // This does not cause a movement + * + * motor.tare_position_all(); + * motor.move_absolute(100, 100); // Moves 100 units forward + * } + * \endcode + */ + std::int32_t tare_position_all(void) const; + + ///@} + + private: + /** + * The port of the motor. Negative ports indicate that the motor is reversed + */ + std::int8_t _port; +}; +namespace literals { +/** + * Constructs a Motor from a literal ending in _mtr + * + * \return a pros::Motor for the corresponding port + * + * \b Example + * \code + * using namespace pros::literals; + * void opcontrol() { + * pros::Motor motor = 2_mtr; //Makes an Motor object on port 2 + * } + * \endcode + */ +const pros::Motor operator""_mtr(const unsigned long long int m); +/** + * Constructs a reversed Motor from a literal ending in _rmtr + * + * \return a pros::Motor for the corresponding port that is reversed + * + * \b Example + * \code + * using namespace pros::literals; + * void opcontrol() { + * pros::motor motor = 2_rmtr; //Makes an reversed Motor object on port 2 + * } + * \endcode + */ +const pros::Motor operator""_rmtr(const unsigned long long int m); +} // namespace literals +} // namespace v5 +} // namespace pros +#endif // _PROS_MOTORS_HPP_ diff --git a/test/include/pros/optical.h b/test/include/pros/optical.h new file mode 100644 index 00000000..bc124919 --- /dev/null +++ b/test/include/pros/optical.h @@ -0,0 +1,506 @@ +/** + * \file pros/optical.h + * \ingroup c-optical + * + * Contains prototypes for functions related to the VEX Optical sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-optical VEX Optical Sensor C API + */ + +#ifndef _PROS_OPTICAL_H_ +#define _PROS_OPTICAL_H_ + +#include +#include +#include "error.h" + +#define OPT_GESTURE_ERR (INT8_MAX) +#define OPT_COUNT_ERR (INT16_MAX) +#define OPT_TIME_ERR PROS_ERR + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \ingroup c-optical + */ + +/** + * \addtogroup c-optical + * @{ + */ + +/** + * \enum optical_direction_e_t + */ +typedef enum optical_direction_e { NO_GESTURE = 0, + /// The direction indicating an upward gesture. + UP = 1, + /// The direction indicating a downward gesture. + DOWN = 2, + /// The direction indicating a rightward gesture. + RIGHT = 3, + /// The direction indicating a leftward gesture. + LEFT = 4, + ERROR = PROS_ERR +} optical_direction_e_t; + +/** + * \struct optical_rgb_s_t + * The RGB and Brightness values for the optical sensor. + */ +typedef struct optical_rgb_s { + double red; + double green; + double blue; + double brightness; +} optical_rgb_s_t; + +/** + * \struct optical_raw_s_t + * The RGB and clear values for the optical sensor. + */ +typedef struct optical_raw_s { + uint32_t clear; + uint32_t red; + uint32_t green; + uint32_t blue; +} optical_raw_s_t; + +/** + * \struct optical_gesture_s_t + * This structure contains the raw gesture data. + */ +typedef struct optical_gesture_s { + uint8_t udata; ///Up data + uint8_t ddata; ///Down data + uint8_t ldata; ///Left data + uint8_t rdata; ///Right data + uint8_t type; ///Type of gesture + uint8_t pad; ///Padding + uint16_t count; ///Number of gestures + uint32_t time; ///Time since gesture recognized +} optical_gesture_s_t; + +/** + * \name Functions + * @{ + */ + +/** + * Get the detected color hue + * + * This is not available if gestures are being detected. Hue has a + * range of 0 to 359.999 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return hue value if the operation was successful or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Hue value: %lf \n", optical_get_hue(OPTICAL_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double optical_get_hue(uint8_t port); + +/** + * Get the detected color saturation + * + * This is not available if gestures are being detected. Saturation has a + * range of 0 to 1.0 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return saturation value if the operation was successful or PROS_ERR_F if + * the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Saturation value: %lf \n", optical_get_saturation(OPTICAL_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double optical_get_saturation(uint8_t port); + +/** + * Get the detected color brightness + * + * This is not available if gestures are being detected. Brightness has a + * range of 0 to 1.0 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return brightness value if the operation was successful or PROS_ERR_F if + * the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Brightness value: %lf \n", optical_get_brightness(OPTICAL_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double optical_get_brightness(uint8_t port); + +/** + * Get the detected proximity value + * + * This is not available if gestures are being detected. proximity has + * a range of 0 to 255. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return poximity value if the operation was successful or PROS_ERR if + * the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Proximity value: %d \n", optical_get_proximity(OPTICAL_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t optical_get_proximity(uint8_t port); + +/** + * Set the pwm value of the White LED + * + * value that ranges from 0 to 100 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * optical_set_led_pwm(OPTICAL_PORT, 50); + * delay(20); + * } + * } + * \endcode + */ +int32_t optical_set_led_pwm(uint8_t port, uint8_t value); + +/** + * Get the pwm value of the White LED + * + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return LED pwm value that ranges from 0 to 100 if the operation was + * successful or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("PWM Value: %d \n", optical_get_led_pwm(OPTICAL_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t optical_get_led_pwm(uint8_t port); + +/** + * Get the processed RGBC data from the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return rgb value if the operation was successful or an optical_rgb_s_t with + * all fields set to PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * optical_rgb_s_t RGB_values; + * void opcontrol() { + * while (true) { + * RGB_values = optical_get_rgb(OPTICAL_PORT); + * printf("Red value: %lf \n", RGB_values.red); + * printf("Green value: %lf \n", RGB_values.green); + * printf("Blue value: %lf \n", RGB_values.blue); + * printf("Brightness value: %lf \n", RGB_values.brightness); + * delay(20); + * } + * } + * \endcode + */ +optical_rgb_s_t optical_get_rgb(uint8_t port); + +/** + * Get the raw, unprocessed RGBC data from the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return raw rgb value if the operation was successful or an optical_raw_s_t + * with all fields set to PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * optical_raw_s_t raw_values; + * void opcontrol() { + * while (true) { + * raw_values = optical_get_raw(OPTICAL_PORT); + * printf("Red value: %ld \n", raw_values.red); + * printf("Green value: %ld \n", raw_values.green); + * printf("Blue value: %ld \n", raw_values.blue); + * printf("Clear value: %ld \n", raw_values.clear); + * delay(20); + * } + * } + * \endcode + */ +optical_raw_s_t optical_get_raw(uint8_t port); + +/** + * Get the most recent gesture data from the sensor + * + * Gestures will be cleared after 500mS + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return gesture value if the operation was successful or PROS_ERR if + * the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * optical_direction_e_t gesture; + * void opcontrol() { + * while (true) { + * gesture = optical_get_gesture(OPTICAL_PORT); + * printf("Gesture value: %d \n", gesture); + * delay(20); + * } + * } + * \endcode + */ +optical_direction_e_t optical_get_gesture(uint8_t port); + +/** + * Get the most recent raw gesture data from the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return gesture value if the operation was successful or an optical_gesture_s_t + * with all fields set to PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * optical_gesture_s_t raw_gesture; + * void opcontrol() { + * while (true) { + * raw_gesture = optical_get_gesture_raw(OPTICAL_PORT); + * printf("Up data: %u \n", raw_gesture.udata); + * printf("Down data: %u \n", raw_gesture.ddata); + * printf("Left data: %u \n", raw_gesture.ldata); + * printf("Right data: %u \n", raw_gesture.rdata); + * printf("Type: %u \n", raw_gesture.type); + * printf("Count: %u \n", raw_gesture.count); + * printf("Time: %lu \n", raw_gesture.time); + * delay(20); + * } + * } + * \endcode + */ +optical_gesture_s_t optical_get_gesture_raw(uint8_t port); + +/** + * Enable gesture detection on the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * optical_enable_gesture(OPTICAL_PORT); + * delay(20); + * } + * } + * \endcode + */ +int32_t optical_enable_gesture(uint8_t port); + +/** + * Disable gesture detection on the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * optical_disable_gesture(OPTICAL_PORT); + * delay(20); + * } + * } + * \endcode + */ +int32_t optical_disable_gesture(uint8_t port); + +/** + * Get integration time (update rate) of the optical sensor in milliseconds, with + * minimum time being + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return Integration time in milliseconds if the operation is successful + * or PROS_ERR_F if the operation failed, setting errno. + */ +double optical_get_integration_time(uint8_t port); + +/** + * Set integration time (update rate) of the optical sensor in milliseconds. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \param time + * The desired integration time in milliseconds + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + */ +int32_t optical_set_integration_time(uint8_t port, double time); + +///@} + +///@} + +#ifdef __cplusplus +} +} +} +#endif + +#endif diff --git a/test/include/pros/optical.hpp b/test/include/pros/optical.hpp new file mode 100644 index 00000000..c2402f63 --- /dev/null +++ b/test/include/pros/optical.hpp @@ -0,0 +1,468 @@ +/** + * \file pros/optical.hpp + * \ingroup cpp-optical + * + * Contains prototypes for functions related to the VEX Optical sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-optical VEX Optical Sensor C++ API + */ + +#ifndef _PROS_OPTICAL_HPP_ +#define _PROS_OPTICAL_HPP_ + +#include + +#include +#include + +#include "pros/device.hpp" +#include "pros/optical.h" + +namespace pros { +inline namespace v5 { +/** + * \ingroup cpp-optical + */ +class Optical : public Device { + /** + * \addtogroup cpp-optical + * @{ + */ + public: + /** + * Creates an Optical Sensor object for the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 port number from 1-21 + * + * \b Example: + * \code{.cpp} + * pros::Optical optical(1); + * \endcode + */ + Optical(const std::uint8_t port); + + Optical(const Device& device) : Optical(device.get_port()){}; + + + /** + * Gets all optical sensors. + * + * \return A vector of Optical sensor objects. + * + * \b Example + * \code + * void opcontrol() { + * std::vector optical_all = pros::Optical::get_all_devices(); // All optical sensors that are connected + * } + * \endcode + */ + static std::vector get_all_devices(); + + /** + * Get the detected color hue + * + * This is not available if gestures are being detected. Hue has a + * range of 0 to 359.999 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return hue value if the operation was successful or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * std::cout << "Hue: " << optical.get_hue() << std::endl; + * } + * \endcode + */ + virtual double get_hue(); + + /** + * Get the detected color saturation + * + * This is not available if gestures are being detected. Saturation has a + * range of 0 to 1.0 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return saturation value if the operation was successful or PROS_ERR_F if + * the operation failed, setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * std::cout << "Saturation: " << optical.get_saturation() << std::endl; + * } + * \endcode + */ + virtual double get_saturation(); + + /** + * Get the detected color brightness + * + * This is not available if gestures are being detected. Brightness has a + * range of 0 to 1.0 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return brightness value if the operation was successful or PROS_ERR_F if + * the operation failed, setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * std::cout << "Brightness: " << optical.get_brightness() << std::endl; + * } + * \endcode + */ + virtual double get_brightness(); + + /** + * Get the detected proximity value + * + * This is not available if gestures are being detected. proximity has + * a range of 0 to 255. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return Proximity value if the operation was successful or PROS_ERR if + * the operation failed, setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * std::cout << "Proximity: " << optical.get_proximity() << std::endl; + * } + * \endcode + */ + virtual std::int32_t get_proximity(); + + /** + * Set the pwm value of the White LED on the sensor + * + * value that ranges from 0 to 100 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return The Error code encountered or PROS_SUCCESS. + * + * \b Example: + * \code{.cpp} + * void initialize() { + * pros::Optical optical(1); + * optical.set_led_pwm(100); + * } + * \endcode + */ + virtual std::int32_t set_led_pwm(uint8_t value); + + /** + * Get the pwm value of the White LED on the sensor + * + * value that ranges from 0 to 100 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return LED pwm value if the operation was successful or PROS_ERR if + * the operation failed, setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * optical.set_led_pwm(100); + * std::cout << "LED PWM: " << optical.get_led_pwm() << std::endl; + * } + * \endcode + */ + virtual std::int32_t get_led_pwm(); + + /** + * Get the processed RGBC data from the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return rgb value if the operation was successful or an optical_rgb_s_t + * with all fields set to PROS_ERR if the operation failed, setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * pros::c::optical_rgb_s_t rgb = optical.get_rgb(); + * while(1) { + * std::cout << "Red: " << rgb.red << std::endl; + * std::cout << "Green: " << rgb.green << std::endl; + * std::cout << "Blue: " << rgb.blue << std::endl; + * std::cout << "Brightness: " << rgb.brightness << std::endl; + * pros::delay(20); + * } + * } + * \endcode + */ + virtual pros::c::optical_rgb_s_t get_rgb(); + + /** + * Get the raw un-processed RGBC data from the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return raw rgb value if the operation was successful or an optical_raw_s_t + * with all fields set to PROS_ERR if the operation failed, setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * pros::c::optical_raw_s_t raw = optical.get_raw(); + * while (1) { + * std::cout << "Red: " << raw.red << std::endl; + * std::cout << "Green: " << raw.green << std::endl; + * std::cout << "Blue: " << raw.blue << std::endl; + * std::cout << "Clear: " << raw.clear << std::endl; + * pros::delay(20); + * } + * } + * \endcode + */ + virtual pros::c::optical_raw_s_t get_raw(); + + /** + * Get the most recent gesture data from the sensor + * + * Gestures will be cleared after 500mS + * + * + * 0 = no gesture, + * 1 = up (towards cable), + * 2 = down, + * 3 = right, + * 4 = left + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return gesture value if the operation was successful or PROS_ERR if + * the operation failed, setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * while(1) { + * std::cout << "Gesture: " << optical.get_gesture() << std::endl; + * pros::delay(20); + * } + * } + * \endcode + */ + virtual pros::c::optical_direction_e_t get_gesture(); + + /** + * Get the most recent raw gesture data from the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return gesture value if the operation was successful or an optical_gesture_s_t + * with all fields set to PROS_ERR if the operation failed, setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * optical.enable_gesture(); + * while(1) { + * pros::c::optical_gesture_s_t gesture = optical.get_gesture_raw(); + * std::cout << "Gesture raw data: " << std::endl; + * std::cout << "Up data: " << gesture.udata << std::endl; + * std::cout << "Down data: " << gesture.ddata << std::endl; + * std::cout << "Left data: " << gesture.ldata << std::endl; + * std::cout << "Right data: " << gesture.rdata << std::endl; + * std::cout << "Type: " << gesture.type << std::endl; + * std::cout << "Count: " << gesture.count << std::endl; + * std::cout << "Time: " << gesture.time << std::endl; + * pros::delay(20); + * } + * } + * \endcode + */ + virtual pros::c::optical_gesture_s_t get_gesture_raw(); + + /** + * Enable gesture detection on the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * optical.enable_gesture(); + * while(1) { + * pros::c::optical_gesture_s_t gesture = optical.get_gesture_raw(); + * std::cout << "Gesture raw data: " << std::endl; + * std::cout << "Up data: " << gesture.udata << std::endl; + * std::cout << "Down data: " << gesture.ddata << std::endl; + * std::cout << "Left data: " << gesture.ldata << std::endl; + * std::cout << "Right data: " << gesture.rdata << std::endl; + * std::cout << "Type: " << gesture.type << std::endl; + * std::cout << "Count: " << gesture.count << std::endl; + * std::cout << "Time: " << gesture.time << std::endl; + * pros::delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t enable_gesture(); + + /** + * Disable gesture detection on the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code{.cpp} + * void opcontrol() { + * pros::Optical optical(1); + * optical.enable_gesture(); + * while(1) { + * if(optical.get_gesture() != 0) { + * std::cout << "Gesture detected!"<< std::endl; + * optical.disable_gesture(); + * } + * pros::delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t disable_gesture(); + + /** + * Get integration time (update rate) of the optical sensor in milliseconds. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \return Integration time in milliseconds if the operation is successful + * or PROS_ERR_F if the operation failed, setting errno. + */ + double get_integration_time(); + + /** + * Set integration time (update rate) of the optical sensor in milliseconds, with + * minimum time being 3 ms and maximum time being 712 ms. Default is 100 ms, with the + * optical sensor communciating with the V5 brain every 20 ms. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param time The desired integration time in milliseconds + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + */ + std::int32_t set_integration_time(double time); + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format(this below is all in one line with no new line): + * Optical [port: (port number), hue: (hue), saturation: (saturation), + * brightness: (brightness), proximity: (proximity), rgb: {red, green, blue}] + * + * \b Example: + * \code{.cpp} + * pros::Optical optical(1); + * std::cout << optical << std::endl; + * \endcode + */ + friend std::ostream& operator<<(std::ostream& os, pros::Optical& optical); + + private: + ///@} +}; + +namespace literals { +/** + * Constructs a Optical sensor from a literal ending in _opt + * + * \return a pros::Optical for the corresponding port + * + * \b Example + * \code + * using namespace pros::literals; + * void opcontrol() { + * pros::Optical opt = 2_opt; //Makes an Optical object on port 2 + * } + * \endcode + */ +const pros::Optical operator""_opt(const unsigned long long int o); +} // namespace literals +} // namespace v5 +} // namespace pros + +#endif diff --git a/test/include/pros/rotation.h b/test/include/pros/rotation.h new file mode 100644 index 00000000..5a904414 --- /dev/null +++ b/test/include/pros/rotation.h @@ -0,0 +1,390 @@ +/** + * \file pros/rotation.h + * \ingroup c-rotation + * + * Contains prototypes for functions related to the VEX Rotation Sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-rotation VEX Rotation Sensor C API + */ + +#ifndef _PROS_ROTATION_H_ +#define _PROS_ROTATION_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \ingroup c-rotation + */ + +/** + * \addtogroup c-rotation + * @{ + */ + +#define ROTATION_MINIMUM_DATA_RATE 5 + +/** + * Reset Rotation Sensor + * + * Reset the current absolute position to be the same as the + * Rotation Sensor angle. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_reset(ROTATION_PORT); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_reset(uint8_t port); + +/** + * Set the Rotation Sensor's refresh interval in milliseconds. + * + * The rate may be specified in increments of 5ms, and will be rounded down to + * the nearest increment. The minimum allowable refresh rate is 5ms. The default + * rate is 10ms. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \param rate The data refresh interval in milliseconds + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void initialize() { + * pros::Rotation rotation_sensor(ROTATION_PORT); + * rotation_set_data_rate(ROTATION_PORT, 5); + * } + * \endcode + */ +int32_t rotation_set_data_rate(uint8_t port, uint32_t rate); + +/** + * Set the Rotation Sensor position reading to a desired rotation value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \param position + * The position in terms of ticks + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_set_position(ROTATION_PORT, 600); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_set_position(uint8_t port, int32_t position); + +/** + * Reset the Rotation Sensor position to 0 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_reset_position(ROTATION_PORT); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_reset_position(uint8_t port); + +/** + * Get the Rotation Sensor's current position in centidegrees + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \return The position value or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Position: %d centidegrees \n", rotation_get_position(ROTATION_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_get_position(uint8_t port); + +/** + * Get the Rotation Sensor's current velocity in centidegrees per second + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \return The velocity value or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Velocity: %d centidegrees per second \n", rotation_get_velocity(ROTATION_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_get_velocity(uint8_t port); + +/** + * Get the Rotation Sensor's current angle in centidegrees (0-36000) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \return The angle value (0-36000) or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Angle: %d centidegrees \n", rotation_get_angle(ROTATION_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_get_angle(uint8_t port); + +/** + * Set the Rotation Sensor's direction reversed flag + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \param value + * Determines if the direction of the Rotation Sensor is reversed or not. + * + * \return 1 if operation succeeded or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * Rotation rotation_sensor(ROTATION_PORT); + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_set_reversed(ROTATION_PORT, true); // Reverses the Rotation Sensor on ROTATION_PORT + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_set_reversed(uint8_t port, bool value); + +/** + * Reverse the Rotation Sensor's direction + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * Rotation rotation_sensor(ROTATION_PORT); + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_reverse(ROTATION_PORT); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_reverse(uint8_t port); + +/** + * Initialize the Rotation Sensor with a reverse flag + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \param reverse_flag + * Determines if the Rotation Sensor is reversed or not. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * Rotation rotation_sensor(ROTATION_PORT); + * bool reverse_flag = true; + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_init_reverse(ROTATION_PORT, reverse_flag); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_init_reverse(uint8_t port, bool reverse_flag); + +/** + * Get the Rotation Sensor's reversed flag + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * + * \return Boolean value of if the Rotation Sensor's direction is reversed or not + * or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * Rotation rotation_sensor(ROTATION_PORT); + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_get_reversed(ROTATION_PORT); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_get_reversed(uint8_t port); + +///@} + +#ifdef __cplusplus +} //namespace C +} //namespace pros +} //extern "C" +#endif + +#endif diff --git a/test/include/pros/rotation.hpp b/test/include/pros/rotation.hpp new file mode 100644 index 00000000..3832cb1e --- /dev/null +++ b/test/include/pros/rotation.hpp @@ -0,0 +1,394 @@ +/** + * \file pros/rotation.hpp + * \ingroup cpp-rotation + * + * Contains prototypes for functions related to the VEX Rotation Sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-rotation VEX Rotation Sensor C++ API + */ +#ifndef _PROS_ROTATION_HPP_ +#define _PROS_ROTATION_HPP_ + +#include +#include + +#include "pros/device.hpp" +#include "pros/rotation.h" + +namespace pros { +inline namespace v5 { +/** + * \ingroup cpp-rotation + */ +class Rotation : public Device { + /** + * \addtogroup cpp-rotation + * @{ + */ + + public: + /** + * Constructs a new Rotation Sensor object + * + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a Rotation Sensor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed Rotation Sensors. + * + * \b Example + * \code + * void opcontrol() { + * pros::Rotation rotation_sensor(1); //Creates a Rotation Sensor on port 1 + * pros::Rotation reversed_rotation_sensor(-2); //Creates a reversed Rotation Sensor on port 2 + * } + * \endcode + */ + Rotation(const std::int8_t port); + + Rotation(const Device& device) : Rotation(device.get_port()){}; + + + /** + * Reset the Rotation Sensor + * + * Reset the current absolute position to be the same as the + * Rotation Sensor angle. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Rotation rotation_sensor(1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * if(master.get_analog(E_CONTROLLER_DIGITAL_X) { + * rotation_sensor.reset(); + * } + * pros::delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t reset(); + + /** + * Set the Rotation Sensor's refresh interval in milliseconds. + * + * The rate may be specified in increments of 5ms, and will be rounded down to + * the nearest increment. The minimum allowable refresh rate is 5ms. The default + * rate is 10ms. + * + * As values are copied into the shared memory buffer only at 10ms intervals, + * setting this value to less than 10ms does not mean that you can poll the + * sensor's values any faster. However, it will guarantee that the data is as + * recent as possible. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param rate The data refresh interval in milliseconds + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Rotation rotation_sensor(1); + * rotation_sensor.set_data_rate(5); + * } + * \endcode + */ + virtual std::int32_t set_data_rate(std::uint32_t rate) const; + + /** + * Set the Rotation Sensor position reading to a desired rotation value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param position + * The position in terms of ticks + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Rotation rotation_sensor(1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * if(master.get_analog(E_CONTROLLER_DIGITAL_X) { + * rotation_sensor.set_position(600); + * } + * pros::delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t set_position(std::int32_t position) const; + + /** + * Reset the Rotation Sensor position to 0 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param position + * The position in terms of ticks + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Rotation rotation_sensor(1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * if(master.get_analog(E_CONTROLLER_DIGITAL_X) { + * rotation_sensor.reset_position(); + * } + * pros::delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t reset_position(void) const; + + /** + * Gets all rotation sensors. + * + * \return A vector of Rotation sensor objects. + * + * \b Example + * \code + * void opcontrol() { + * std::vector rotation_all = pros::Rotation::get_all_devices(); // All rotation sensors that are connected + * } + * \endcode + */ + static std::vector get_all_devices(); + + /** + * Get the Rotation Sensor's current position in centidegrees + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \return The position value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Rotation rotation_sensor(1); + * while (true) { + * printf("Position: %d Ticks \n", rotation_sensor.get_position()); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t get_position() const; + + /** + * Get the Rotation Sensor's current velocity in centidegrees per second + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \return The velocity value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Rotation rotation_sensor(1); + * while (true) { + * printf("Velocity: %d centidegrees per second \n", rotation_sensor.get_velocity)); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t get_velocity() const; + + /** + * Get the Rotation Sensor's current position in centidegrees + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \return The angle value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Rotation rotation_sensor(1); + * while (true) { + * printf("Angle: %d centidegrees \n", rotation_sensor.get_angle()); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t get_angle() const; + + /** + * Set the Rotation Sensor's direction reversed flag + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param value + * Determines if the direction of the rotational sensor is + * reversed or not. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Rotation rotation_sensor(1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * if(master.get_analog(E_CONTROLLER_DIGITAL_X) { + * rotation_sensor.set_reversed(true); // Reverses the Rotation Sensor + * } + * pros::delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t set_reversed(bool value) const; + + /** + * Reverse the Rotation Sensor's direction. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Rotation rotation_sensor(1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * if(master.get_analog(E_CONTROLLER_DIGITAL_X) { + * rotation_sensor.reverse(); + * } + * pros::delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t reverse() const; + + /** + * Get the Rotation Sensor's reversed flag + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \return Reversed value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Rotation rotation_sensor(1); + * while (true) { + * printf("Reversed: %d \n", rotation_sensor.get_reversed()); + * delay(20); + * } + * } + * \endcode + */ + virtual std::int32_t get_reversed() const; + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format(this below is all in one line with no new line): + * Rotation [port: rotation._port, position: (rotation position), velocity: (rotation velocity), + * angle: (rotation angle), reversed: (reversed boolean)] + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * pros::Rotation rotation_sensor(1); + * while(true) { + * std::cout << rotation_sensor << std::endl; + * pros::delay(20); + * } + * } + * \endcode + */ + friend std::ostream& operator<<(std::ostream& os, const pros::Rotation& rotation); + + ///@} +}; + +namespace literals { +/** + * Constructs a Rotation sensor from a literal ending in _rot + * + * \return a pros::Rotation for the corresponding port + * + * \b Example + * \code + * using namespace pros::literals; + * void opcontrol() { + * pros::Rotation rotation = 2_rot; //Makes an Motor object on port 2 + * } + * \endcode + */ +const pros::Rotation operator""_rot(const unsigned long long int r); +} // namespace literals +} // namespace v5 +} // namespace pros + +#endif diff --git a/test/include/pros/rtos.h b/test/include/pros/rtos.h new file mode 100644 index 00000000..b5ae33bf --- /dev/null +++ b/test/include/pros/rtos.h @@ -0,0 +1,1188 @@ +/** + * \file pros/rtos.h + * \ingroup c-rtos + * + * Contains declarations for the PROS RTOS kernel for use by typical VEX + * programmers. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-rtos RTOS Facilities C API + * \note Additional example code for this module can be found in its [Tutorial.](@ref multitasking) + */ + +#ifndef _PROS_RTOS_H_ +#define _PROS_RTOS_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/// \ingroup c-rtos + +/// \addtogroup c-rtos +/// @{ + +/// \name Macros +/// @{ + +/** + * The highest priority that can be assigned to a task. + * + * A task with this priority will always run if it is available to. Beware of + * deadlocks when using this priority. + */ +#define TASK_PRIORITY_MAX 16 + +/** + * The lowest priority that can be assigned to a task. + * + * This can cause severe performance problems and is generally not recommended + * that users use this priority. + */ +#define TASK_PRIORITY_MIN 1 + +/** + * The default task priority, which should be used for most tasks unless you + * have a specific need for a higher or lower priority task. + * + * The default tasks, such as autonomous(), are run with this priority + */ +#define TASK_PRIORITY_DEFAULT 8 + +/** + * The recommended stack size for a new task. + * + * This stack size is used for the default tasks such as autonomous(). This + * size is 8,192 words, or 32,768 bytes. This should be enough for the majority + * of tasks + */ +#define TASK_STACK_DEPTH_DEFAULT 0x2000 + +/** + * The minimal stack size for a task. + * + * This equates to 512 words, or 2,048 bytes. + */ +#define TASK_STACK_DEPTH_MIN 0x200 + +/** + * The maximum number of characters allowed in a task's name. + */ +#define TASK_NAME_MAX_LEN 32 + +/** + * The maximum timeout value that can be given to, for instance, a mutex grab. + */ +#define TIMEOUT_MAX ((uint32_t)0xffffffffUL) + +/// @} Name: Macros + +/// \name Typedefs +/// @{ + +/** + * An opaque type that points to a task handle. This is used for referencing a + * task. + */ +typedef void* task_t; + +/** + * A pointer to a task's function. + * + * Such a function is called when a task starts, and exiting said function will + * terminate the task. + */ +typedef void (*task_fn_t)(void*); + +/// @} Name: Typedefs + + +/// \name Enumerations +/// @{ + +/** + * The state of a task. + */ +typedef enum { + E_TASK_STATE_RUNNING = 0, /**< The task is actively executing. */ + E_TASK_STATE_READY, /**< The task exists and is available to run, but is not currently running. */ + E_TASK_STATE_BLOCKED, /**< The task is delayed or blocked by a mutex, semaphore, or I/O operation. */ + E_TASK_STATE_SUSPENDED, /**< The task is supended using task_suspend. */ + E_TASK_STATE_DELETED, /**< The task has been deleted using task_delete. */ + E_TASK_STATE_INVALID /**< The task handle does not point to a current or past task.*/ +} task_state_e_t; + +/** + * brief The action to take when a task is notified. + */ +typedef enum { + E_NOTIFY_ACTION_NONE, /**< The task’s notification value will not be touched.*/ + E_NOTIFY_ACTION_BITS, /**< The task’s notification value will be bitwise ORed with the new value.*/ + E_NOTIFY_ACTION_INCR, /**< The task’s notification value will be incremented by one, effectively using it as a notification counter.*/ + E_NOTIFY_ACTION_OWRITE, /**< The task’s notification value will be unconditionally set to the new value.*/ + E_NOTIFY_ACTION_NO_OWRITE /**< The task’s notification value will be set to the new value if the task does not already have a pending notification.*/ +} notify_action_e_t; + +/// @} Name: Enumerations + +/// \name Simple enum names +/// @{ + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define TASK_STATE_RUNNING pros::E_TASK_STATE_RUNNING +#define TASK_STATE_READY pros::E_TASK_STATE_READY +#define TASK_STATE_BLOCKED pros::E_TASK_STATE_BLOCKED +#define TASK_STATE_SUSPENDED pros::E_TASK_STATE_SUSPENDED +#define TASK_STATE_DELETED pros::E_TASK_STATE_DELETED +#define TASK_STATE_INVALID pros::E_TASK_STATE_INVALID +#define NOTIFY_ACTION_NONE pros::E_NOTIFY_ACTION_NONE +#define NOTIFY_ACTION_BITS pros::E_NOTIFY_ACTION_BITS +#define NOTIFY_ACTION_INCR pros::E_NOTIFY_ACTION_INCR +#define NOTIFY_ACTION_OWRITE pros::E_NOTIFY_ACTION_OWRITE +#define NOTIFY_ACTION_NO_OWRITE pros::E_NOTIFY_ACTION_NO_OWRITE +#else +#define TASK_STATE_RUNNING E_TASK_STATE_RUNNING +#define TASK_STATE_READY E_TASK_STATE_READY +#define TASK_STATE_BLOCKED E_TASK_STATE_BLOCKED +#define TASK_STATE_SUSPENDED E_TASK_STATE_SUSPENDED +#define TASK_STATE_DELETED E_TASK_STATE_DELETED +#define TASK_STATE_INVALID E_TASK_STATE_INVALID +#define NOTIFY_ACTION_NONE E_NOTIFY_ACTION_NONE +#define NOTIFY_ACTION_BITS E_NOTIFY_ACTION_BITS +#define NOTIFY_ACTION_INCR E_NOTIFY_ACTION_INCR +#define NOTIFY_ACTION_OWRITE E_NOTIFY_ACTION_OWRITE +#define NOTIFY_ACTION_NO_OWRITE E_NOTIFY_ACTION_NO_OWRITE +#endif +#endif + +/// @} Name: Simple enum names + +/// \name Typedefs + +/** + * A [mutex.](@ref multitasking) + * + * A mutex is a synchronization object that can be used to protect a shared + * resource from being accessed by multiple tasks at the same time. A mutex can + * be claimed by a task, which will prevent other tasks from claiming it until + * that task releases it. + */ +typedef void* mutex_t; + +/// @} Name: Typedefs + +/** + * The task handle of the currently running task. + */ +#ifdef __cplusplus +#define CURRENT_TASK ((pros::task_t)NULL) +#else +#define CURRENT_TASK ((task_t)NULL) +#endif + +/// @} (add to group: c-rtos) + +#ifdef __cplusplus +namespace c { +#endif + +/// \ingroup c-rtos +/// \addtogroup c-rtos +/// @{ + +/** + * Gets the number of milliseconds since PROS initialized. + * + * \return The number of milliseconds since PROS initialized + * + * \b Example + * \code + * void opcontrol() { + * uint32_t now = millis(); + * while (true) { + * // Do opcontrol things + * task_delay_until(&now, 2); + * } + * } + * \endcode + */ +uint32_t millis(void); + +/** + * Gets the number of microseconds since PROS initialized, + * + * \return The number of microseconds since PROS initialized + * + * \b Example + * \code + * void opcontrol() { + * uint64_t now = micros(); + * while (true) { + * // Do opcontrol things + * task_delay_until(&now, 2000); + * } + * } + * \endcode + */ +uint64_t micros(void); + +/** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Pointer to the task entry function + * \param parameters + * Pointer to memory that will be used as a parameter for the task being + * created. This memory should not typically come from stack, but rather + * from dynamically (i.e., malloc'd) or statically allocated memory. + * \param prio + * The priority at which the task should run. + * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. + * \param stack_depth + * The number of words (i.e. 4 * stack_depth) available on the task's + * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficienct. + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \return A handle by which the newly created task can be referenced. If an + * error occurred, NULL will be returned and errno can be checked for hints as + * to why task_create failed. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * \endcode + */ +task_t task_create(task_fn_t function, void* const parameters, uint32_t prio, const uint16_t stack_depth, + const char* const name); + +/** + * Removes a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * Memory dynamically allocated by the task is not automatically freed, and + * should be freed before the task is deleted. + * + * \param task + * The handle of the task to be deleted. Passing NULL will cause the + * calling task to be deleted. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * // Do other things + * task_delete(my_task); + * } + * \endcode + */ +void task_delete(task_t task); + +/** + * Delays the current task for a given number of milliseconds. + * + * This is not the best method to have a task execute code at predefined + * intervals, as the delay time is measured from when the delay is requested. + * To delay cyclically, use task_delay_until(). + * + * \param milliseconds + * The number of milliseconds to wait (1000 milliseconds per second) + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * // Do opcontrol things + * task_delay(2); + * } + * } + * \endcode + */ +void task_delay(const uint32_t milliseconds); + +/** + * Delays the current task for a given number of milliseconds. + * + * This is not the best method to have a task execute code at predefined + * intervals, as the delay time is measured from when the delay is requested. + * To delay cyclically, use task_delay_until(). + * + * \param milliseconds + * The number of milliseconds to wait (1000 milliseconds per second) + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * // Do opcontrol things + * delay(2); + * } + * } + * \endcode + */ +void delay(const uint32_t milliseconds); + +/** + * Delays the current task until a specified time. This function can be used + * by periodic tasks to ensure a constant execution frequency. + * + * The task will be woken up at the time *prev_time + delta, and *prev_time will + * be updated to reflect the time at which the task will unblock. + * + * \param prev_time + * A pointer to the location storing the setpoint time. This should + * typically be initialized to the return value of millis(). + * \param delta + * The number of milliseconds to wait (1000 milliseconds per second) + * + * \b Example + * \code + * void opcontrol() { + * uint32_t now = millis(); + * while (true) { + * // Do opcontrol things + * task_delay_until(&now, 2); + * } + * } + * \endcode + */ +void task_delay_until(uint32_t* const prev_time, const uint32_t delta); + +/** + * Gets the priority of the specified task. + * + * \param task + * The task to check + * + * \return The priority of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * printf("Task Priority: %d\n", task_get_priority(my_task)); + * } + * \endcode + */ +uint32_t task_get_priority(task_t task); + +/** + * Sets the priority of the specified task. + * + * If the specified task's state is available to be scheduled (e.g. not blocked) + * and new priority is higher than the currently running task, a context switch + * may occur. + * + * \param task + * The task to set + * \param prio + * The new priority of the task + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * // Do things + * } + * + * void opcontrol() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "Example Task"); + * task_set_priority(my_task, TASK_PRIORITY_DEFAULT + 1); + * } + * \endcode + */ +void task_set_priority(task_t task, uint32_t prio); + +/** + * Gets the state of the specified task. + * + * \param task + * The task to check + * + * \return The state of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * printf("Task's State: %d\n", task_get_state(my_task)); + * } + * \endcode + */ +task_state_e_t task_get_state(task_t task); + +/** + * Suspends the specified task, making it ineligible to be scheduled. + * + * \param task + * The task to suspend + * + * \b Example + * \code + * mutex_t counter_mutex; + * int counter = 0; + * + * void my_task_fn(void* param) { + * while(true) { + * mutex_take(counter_mutex, TIMEOUT_MAX);// Mutexes are used for protecting shared resources + * counter++; + * mutex_give(counter_mutex); + * pros::delay(10); + * } + * } + * + * void opcontrol() { + * task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,; + * + * while(true) { + * mutex_take(counter_mutex, TIMEOUT_MAX); + * if(counter > 100) { + * task_suspepend(task); + * } + * mutex_give(counter_mutex); + * pros::delay(10); + * } + * } + * \endcode + */ +void task_suspend(task_t task); + +/** + * Resumes the specified task, making it eligible to be scheduled. + * + * \param task + * The task to resume + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while(true) { + * // Do stuff + * delay(10); + * } + * } + * + * task_t task; + * + * void initialize() { + * task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * + * void autonomous() { + * task_resume(task); + * + * // Run autonomous , then suspend the task so it doesn't interfere run + * + * // outside of autonomous or opcontrol + * task_suspend(task); + * } + * + * void opcontrol() { + * task_resume(task); + * // Opctonrol code here + * task_suspend(task); + * } + * + * \endcode + */ +void task_resume(task_t task); + +/** + * Gets the number of tasks the kernel is currently managing, including all + * ready, blocked, or suspended tasks. A task that has been deleted, but not yet + * reaped by the idle task will also be included in the count. Tasks recently + * created may take one context switch to be counted. + * + * \return The number of tasks that are currently being managed by the kernel. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * printf("Number of Running Tasks: %d\n", task_get_count()); + * } + * \endcode + */ +uint32_t task_get_count(void); + +/** + * Gets the name of the specified task. + * + * \param task + * The task to check + * + * \return A pointer to the name of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * printf("Task Name: %d\n", task_get_name(my_task)); + * } + * \endcode + */ +char* task_get_name(task_t task); + +/** + * Gets a task handle from the specified name + * + * The operation takes a relatively long time and should be used sparingly. + * + * \param name + * The name to query + * + * \return A task handle with a matching name, or NULL if none were found. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * // Do other things + * task_delete(task_get_by_name("My Task")); + * } + * \endcode + */ +task_t task_get_by_name(const char* name); + +/** + * Get the currently running task handle. This could be useful if a task + * wants to tell another task about itself. + * + * \return The currently running task handle. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * task_t this_task = task_get_current(); + * if (task_get_state(this_take) == E_TASK_STATE_RUNNING) { + * printf("This task is currently running\n"); + * } + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * \endcode + */ +task_t task_get_current(); + +/** + * Sends a simple notification to task and increments the notification counter. + * + * \param task + * The task to notify + * + * \return Always returns true. + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * while(task_notify_take(true) == 0) { + * // Code while waiting + * } + * puts("I was unblocked!"); + * } + * + * void opcontrol() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "Notify me! Task"); + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task_notify(my_task); + * } + * } + * } + * \endcode + */ +uint32_t task_notify(task_t task); + +/** + * + * Utilizes task notifications to wait until specified task is complete and deleted, + * then continues to execute the program. Analogous to std::thread::join in C++. + * + * \param task + * The handle of the task to wait on. + * + * \return void + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * lcd_print(1, "%s running", task_get_name(NULL)); + * task_delay(1000); + * lcd_print(2, "End of %s", task_get_name(NULL)); + * } + * + * void opcontrol() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "Example Task"); + * lcd_set_text(0, "Running task."); + * task_join(my_task); + * lcd_set_text(3, "Task completed."); + * } + * \endcode + */ +void task_join(task_t task); + +/** + * Sends a notification to a task, optionally performing some action. Will also + * retrieve the value of the notification in the target task before modifying + * the notification value. + * + * \param task + * The task to notify + * \param value + * The value used in performing the action + * \param action + * An action to optionally perform on the receiving task's notification + * value + * \param prev_value + * A pointer to store the previous value of the target task's + * notification, may be NULL + * + * \return Dependent on the notification action. + * For NOTIFY_ACTION_NO_WRITE: return 0 if the value could be written without + * needing to overwrite, 1 otherwise. + * For all other NOTIFY_ACTION values: always return 0 + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while(true) { + * // Wait until we have been notified 20 times before running the code + * if(task_notify_take(false, TIMEOUT_MAX) == 20) { + * // ... Code to do stuff here ... + * + * // Reset the notification counter + * task_notify_take(true, TIMEOUT_MAX); + * } + * delay(10); + * } + * } + * + * void opcontrol() { + * task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * + * int count = 0; + * + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task_notify_ext(task, 1, NOTIFY_ACTION_INCREMENT, &count); + * } + * + * delay(20); + * } + * } + * \endcode + */ +uint32_t task_notify_ext(task_t task, uint32_t value, notify_action_e_t action, uint32_t* prev_value); + +/** + * Waits for a notification to be nonzero. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \param clear_on_exit + * If true (1), then the notification value is cleared. + * If false (0), then the notification value is decremented. + * \param timeout + * Specifies the amount of time to be spent waiting for a notification + * to occur. + * + * \return The value of the task's notification value before it is decremented + * or cleared + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * task_t current_task = task_get_current(); + * while(task_notify_take(current_task, true, TIMEOUT_MAX)) { + * puts("I was unblocked!"); + * } + * } + * + * void opcontrol() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "Notify me! Task"); + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task_notify(my_task); + * } + * } + * } + * \endcode + */ +uint32_t task_notify_take(bool clear_on_exit, uint32_t timeout); + +/** + * Clears the notification for a task. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \param task + * The task to clear + * + * \return False if there was not a notification waiting, true if there was + * + * \b Example + * \code + * void my_task_fn(void* param) { + * task_t task = task_get_current(); + * while(true) { + * printf("Waiting for notification...\n"); + * printf("Got a notification: %d\n", task_notify_take(task, false, TIMEOUT_MAX)); + * + * task_notify_clear(task); + * delay(10): + * } + * } + * + * void opcontrol() { + * task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task_notify(task); + * } + * delay(10); + * } + * } + * \endcode + */ +bool task_notify_clear(task_t task); + +/** + * Creates a mutex. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \return A handle to a newly created mutex. If an error occurred, NULL will be + * returned and errno can be checked for hints as to why mutex_create failed. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * mutex_t odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * mutex_take(odom_mutex, MAX_DELAY); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * mutex_give(odom_mutex); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * mutex_take(odom_mutex, MAX_DELAY); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * mutex_give(odom_mutex); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * mutex_take(odom_mutex, MAX_DELAY); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * mutex_give(odom_mutex); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = mutex_create(); + * + * task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task"); + * task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task"); + * } + * \endcode + */ +mutex_t mutex_create(void); + +/** + * Takes and locks a mutex, waiting for up to a certain number of milliseconds + * before timing out. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \param mutex + * Mutex to attempt to lock. + * \param timeout + * Time to wait before the mutex becomes available. A timeout of 0 can + * be used to poll the mutex. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the mutex was successfully taken, false otherwise. If false + * is returned, then errno is set with a hint about why the the mutex + * couldn't be taken. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * mutex_t odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * mutex_take(odom_mutex, MAX_DELAY); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * mutex_give(odom_mutex); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * mutex_take(odom_mutex, MAX_DELAY); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * mutex_give(odom_mutex); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * mutex_take(odom_mutex, MAX_DELAY); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * mutex_give(odom_mutex); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = mutex_create(); + * + * task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task"); + * task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task"); + * } + * \endcode + */ +bool mutex_take(mutex_t mutex, uint32_t timeout); + +/** + * Unlocks a mutex. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \param mutex + * Mutex to unlock. + * + * \return True if the mutex was successfully returned, false otherwise. If + * false is returned, then errno is set with a hint about why the mutex + * couldn't be returned. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * mutex_t odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * mutex_take(odom_mutex, MAX_DELAY); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * mutex_give(odom_mutex); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * mutex_take(odom_mutex, MAX_DELAY); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * mutex_give(odom_mutex); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * mutex_take(odom_mutex, MAX_DELAY); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * mutex_give(odom_mutex); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = mutex_create(); + * + * task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task"); + * task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task"); + * } + * \endcode + */ +bool mutex_give(mutex_t mutex); + +/** + * Creates a recursive mutex which can be locked recursively by the owner. + * + * \return A newly created recursive mutex. + * + * \b Example: + * \code + * mutex_t mutex = mutex_recursive_create(); + * + * void task_fn(void* param) { + * while(1) { + * mutex_recursive_take(mutex, 1000); + * // critical section + * mutex_recursive_give(mutex); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +mutex_t mutex_recursive_create(void); + +/** + * Takes a recursive mutex. + * + * \param mutex + * A mutex handle created by mutex_recursive_create + * \param wait_time + * Amount of time to wait before timing out + * + * \return 1 if the mutex was obtained, 0 otherwise + * + * \b Example: + * \code + * mutex_t mutex = mutex_recursive_create(); + * + * void task_fn(void* param) { + * while(1) { + * mutex_recursive_take(mutex, 1000); + * // critical section + * mutex_recursive_give(mutex); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +bool mutex_recursive_take(mutex_t mutex, uint32_t timeout); + +/** + * Gives a recursive mutex. + * + * \param mutex + * A mutex handle created by mutex_recursive_create + * + * \return 1 if the mutex was obtained, 0 otherwise + * + * \b Example: + * \code + * mutex_t mutex = mutex_recursive_create(); + * + * void task_fn(void* param) { + * while(1) { + * mutex_recursive_take(mutex, 1000); + * // critical section + * mutex_recursive_give(mutex); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +bool mutex_recursive_give(mutex_t mutex); + +/** + * Deletes a mutex or recursive mutex + * + * \param mutex + * Mutex to unlock. + * + * \b Example + * \code + * mutex_t mutex = mutex_create(); + * // Acquire the mutex; other tasks using this command will wait until the mutex is released + * // timeout can specify the maximum time to wait, or MAX_DELAY to wait forever + * // If the timeout expires, "false" will be returned, otherwise "true" + * mutex_take(mutex, MAX_DELAY); + * // do some work + * // Release the mutex for other tasks + * mutex_give(mutex); + * // Delete the mutex + * mutex_delete(mutex); + * \endcode + */ +void mutex_delete(mutex_t mutex); + +/// @} Add to group: c-rtos + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_RTOS_H_ diff --git a/test/include/pros/rtos.hpp b/test/include/pros/rtos.hpp new file mode 100644 index 00000000..d6c2d890 --- /dev/null +++ b/test/include/pros/rtos.hpp @@ -0,0 +1,2121 @@ +/** + * \file pros/rtos.hpp + * \ingroup cpp-rtos + * + * Contains declarations for the PROS RTOS kernel for use by typical VEX + * programmers. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-rtos RTOS Facilities C++ API + * \note Additional example code for this module can be found in its [Tutorial.](@ref multitasking) + */ + +#ifndef _PROS_RTOS_HPP_ +#define _PROS_RTOS_HPP_ + +#include "pros/rtos.h" +#undef delay +#include +#include +#include +#include +#include +#include +#include +#include + +namespace pros { +inline namespace rtos { +/** + * \ingroup cpp-rtos + */ +class Task { + /** + * \addtogroup cpp-rtos + * @{ + */ + public: + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Pointer to the task entry function + * \param parameters + * Pointer to memory that will be used as a parameter for the task + * being created. This memory should not typically come from stack, + * but rather from dynamically (i.e., malloc'd) or statically + * allocated memory. + * \param prio + * The priority at which the task should run. + * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. + * \param stack_depth + * The number of words (i.e. 4 * stack_depth) available on the task's + * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficienct. + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, (void*)"PROS"); + * } + * \endcode + */ + Task(task_fn_t function, void* parameters = nullptr, std::uint32_t prio = TASK_PRIORITY_DEFAULT, + std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = ""); + + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Pointer to the task entry function + * \param parameters + * Pointer to memory that will be used as a parameter for the task + * being created. This memory should not typically come from stack, + * but rather from dynamically (i.e., malloc'd) or statically + * allocated memory. + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, (void*)"PROS", "My Task"); + * } + * \endcode + */ + Task(task_fn_t function, void* parameters, const char* name); + + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Callable object to use as entry function + * \param prio + * The priority at which the task should run. + * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. + * \param stack_depth + * The number of words (i.e. 4 * stack_depth) available on the task's + * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficienct. + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::c::task_t my_task = pros::Task::create(my_task_fn, (void*)"PROS"); + * } + * \endcode + */ + template + static task_t create(F&& function, std::uint32_t prio = TASK_PRIORITY_DEFAULT, + std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = "") { + static_assert(std::is_invocable_r_v); + return pros::c::task_create( + [](void* parameters) { + std::unique_ptr> ptr{static_cast*>(parameters)}; + (*ptr)(); + }, + new std::function(std::forward(function)), prio, stack_depth, name); + } + + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Callable object to use as entry function + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); + * } + * \endcode + */ + template + static task_t create(F&& function, const char* name) { + return Task::create(std::forward(function), TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, name); + } + + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Callable object to use as entry function + * \param prio + * The priority at which the task should run. + * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. + * \param stack_depth + * The number of words (i.e. 4 * stack_depth) available on the task's + * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficient. + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * + * void initialize() { + * // Create a task function using lambdas + * auto task_fn = [](void* param) { + * printf("Hello %s\n", (char*)param); + * } + * + * pros::Task my_task(task_fn, (void*)"PROS", "My Task"); + * } + * \endcode + */ + template + explicit Task(F&& function, std::uint32_t prio = TASK_PRIORITY_DEFAULT, + std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = "") + : Task( + [](void* parameters) { + std::unique_ptr> ptr{static_cast*>(parameters)}; + (*ptr)(); + }, + new std::function(std::forward(function)), prio, stack_depth, name) { + static_assert(std::is_invocable_r_v); + } + + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Callable object to use as entry function + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task( + * [](void* param) { + * printf("Inside the task!\n"); + * }, + * "My Task" + * ); + * } + * \endcode + */ + template + Task(F&& function, const char* name) + : Task(std::forward(function), TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, name) {} + + /** + * Create a C++ task object from a task handle + * + * \param task + * A task handle from task_create() for which to create a pros::Task + * object. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); + * + * pros::Task my_task_cpp(my_task); + * } + * \endcode + */ + explicit Task(task_t task); + + /** + * Get the currently running Task + * + * @return The currently running Task. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("The name of this task is \"%s\"\n", pros::Task::current().get_name() + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, pros::TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * \endcode + */ + static Task current(); + + /** + * Creates a task object from the passed task handle. + * + * \param in + * A task handle from task_create() for which to create a pros::Task + * object. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("The name of this task is \"%s\"\n", pros::Task::current().get_name() + * } + * + * void initialize() { + * pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); + * + * pros::Task my_task_cpp = my_task; + * } + * \endcode + */ + Task& operator=(task_t in); + + /** + * Removes the Task from the RTOS real time kernel's management. This task + * will be removed from all ready, blocked, suspended and event lists. + * + * Memory dynamically allocated by the task is not automatically freed, and + * should be freed before the task is deleted. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * + * my_task.remove(); + * } + * \endcode + */ + void remove(); + + /** + * Gets the priority of the specified task. + * + * \return The priority of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * + * printf("Task Priority: %d\n", my_task.get_priority()); + * } + * \endcode + */ + std::uint32_t get_priority(); + + /** + * Sets the priority of the specified task. + * + * If the specified task's state is available to be scheduled (e.g. not + * blocked) and new priority is higher than the currently running task, + * a context switch may occur. + * + * \param prio + * The new priority of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * + * Task.set_priority(pros::DEFAULT_PRIORITY + 1); + * } + * \endcode + */ + void set_priority(std::uint32_t prio); + + /** + * Gets the state of the specified task. + * + * \return The state of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * + * printf("Task State: %d\n", my_task.get_state()); + * } + * \endcode + */ + std::uint32_t get_state(); + + /** + * Suspends the specified task, making it ineligible to be scheduled. + * + * \b Example + * \code + * pros::Mutex counter_mutex; + * int counter = 0; + * + * void my_task_fn(void* param) { + * while(true) { + * counter_mutex.take(); // Mutexes are used for protecting shared resources + * counter++; + * counter_mutex.give(); + * pros::delay(10); + * } + * } + * + * void opcontrol() { + * pros::Task task(my_task_fn, "My Task"); + * + * while(true) { + * counter_mutex.take(); + * if(counter > 100) { + * task_suspepend(task); + * } + * counter_mutex.give(); + * pros::delay(10); + * } + * } + * \endcode + */ + void suspend(); + + /** + * Resumes the specified task, making it eligible to be scheduled. + * + * \param task + * The task to resume + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while(true) { + * // Do stuff + * pros::delay(10); + * } + * } + * + * pros::Task task(my_task_fn); + * + * void autonomous() { + * task.resume(); + * + * // Run autonomous , then suspend the task so it doesn't interfere run + * // outside of autonomous or opcontrol + * task.suspend(); + * } + * + * void opcontrol() { + * task.resume(); + * // Opctonrol code here + * task.suspend(); + * } + * + * \endcode + */ + void resume(); + + /** + * Gets the name of the specified task. + * + * \return A pointer to the name of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * printf("Number of Running Tasks: %d\n", my_task.get_name()); + * } + * \endcode + */ + const char* get_name(); + + /** + * Convert this object to a C task_t handle + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * + * pros::c::task_t my_task_c = (pros::c::task_t)my_task; + * } + * \endcode + */ + explicit operator task_t() { + return task; + } + + /** + * Sends a simple notification to task and increments the notification + * counter. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \return Always returns true. + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * while(pros::Task::current_task().notify_take(true) == 0) { + * // Code while waiting + * } + * puts("I was unblocked!"); + * } + * + * void opcontrol() { + * pros::Task my_task(my_task_fn); + * + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * my_task.notify(); + * } + * } + * } + * \endcode + */ + std::uint32_t notify(); + + /** + * Utilizes task notifications to wait until specified task is complete and deleted, + * then continues to execute the program. Analogous to std::thread::join in C++. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \return void + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * lcd_print(1, "%s running", pros::Task::current_task().get_name()); + * task_delay(1000); + * lcd_print(2, "End of %s", pros::Task::current_task().get_name()); + * } + * + * void opcontrol() { + * pros::Task my_task(my_task_fn); + * pros::lcd::set_text(0, "Running task."); + * my_task.join(); + * pros::lcd::lcd_set_text(3, "Task completed."); + * } + * \endcode + */ + void join(); + + /** + * Sends a notification to a task, optionally performing some action. Will + * also retrieve the value of the notification in the target task before + * modifying the notification value. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \param value + * The value used in performing the action + * \param action + * An action to optionally perform on the receiving task's notification + * value + * \param prev_value + * A pointer to store the previous value of the target task's + * notification, may be NULL + * + * \return Dependent on the notification action. + * For NOTIFY_ACTION_NO_WRITE: return 0 if the value could be written without + * needing to overwrite, 1 otherwise. + * For all other NOTIFY_ACTION values: always return 0 + * + * \b Example + * \code + * void my_task_fn(void* param) { + * pros::Task task = pros::Task::current(); + * + * while(true) { + * // Wait until we have been notified 20 times before running the code + * if(task.notify_take(false, TIMEOUT_MAX) == 20) { + * // ... Code to do stuff here ... + * + * // Reset the notification counter + * task.notify_clear(); + * } + * delay(10); + * } + * } + * + * void opcontrol() { + * pros::Task task(my_task_fn); + * + * int count = 0; + * + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task.notify_ext(1, NOTIFY_ACTION_INCREMENT, &count); + * } + * + * delay(20); + * } + * } + * \endcode + */ + std::uint32_t notify_ext(std::uint32_t value, notify_action_e_t action, std::uint32_t* prev_value); + + /** + * Waits for a notification to be nonzero. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \param clear_on_exit + * If true (1), then the notification value is cleared. + * If false (0), then the notification value is decremented. + * \param timeout + * Specifies the amount of time to be spent waiting for a notification + * to occur. + * + * \return The value of the task's notification value before it is decremented + * or cleared + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * pros::Task task = pros::task::current(); + * while(task.notify_take(true, TIMEOUT_MAX)) { + * puts("I was unblocked!"); + * } + * } + * + * void opcontrol() { + * pros::Task task(my_task_fn); + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task.notify(my_task); + * } + * } + * } + * \endcode + */ + static std::uint32_t notify_take(bool clear_on_exit, std::uint32_t timeout); + + /** + * Clears the notification for a task. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \return False if there was not a notification waiting, true if there was + * \b Example + * \code + * void my_task_fn(void* param) { + * pros::Task task = pros::Task::current(); + * while(true) { + * printf("Waiting for notification...\n"); + * printf("Got a notification: %d\n", task.notify_take(false, TIMEOUT_MAX)); + * + * tasK_notify(task); + * delay(10): + * } + * } + * + * void opcontrol() { + * pros::Task task(my_task_fn); + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task.notify(); + * } + * delay(10); + * } + * } + * \endcode + */ + bool notify_clear(); + + /** + * Delays the current task for a specified number of milliseconds. + * + * This is not the best method to have a task execute code at predefined + * intervals, as the delay time is measured from when the delay is requested. + * To delay cyclically, use task_delay_until(). + * + * \param milliseconds + * The number of milliseconds to wait (1000 milliseconds per second) + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * // Do opcontrol things + * pros::Task::delay(2); + * } + * \endcode + */ + static void delay(const std::uint32_t milliseconds); + + /** + * Delays the current Task until a specified time. This function can be used by + * periodic tasks to ensure a constant execution frequency. + * + * The task will be woken up at the time *prev_time + delta, and *prev_time + * will be updated to reflect the time at which the task will unblock. + * + * \param prev_time + * A pointer to the location storing the setpoint time. This should + * typically be initialized to the return value from pros::millis(). + * \param delta + * The number of milliseconds to wait (1000 milliseconds per second) + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * // Do opcontrol things + * pros::Task::delay(2); + * } + * } + * \endcode + */ + static void delay_until(std::uint32_t* const prev_time, const std::uint32_t delta); + + /** + * Gets the number of tasks the kernel is currently managing, including all + * ready, blocked, or suspended tasks. A task that has been deleted, but not + * yet reaped by the idle task will also be included in the count. + * Tasks recently created may take one context switch to be counted. + * + * \return The number of tasks that are currently being managed by the kernel. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void opcontrol() { + * pros::Task my_task(my_task_fn); + * printf("There are %d tasks running\n", pros::Task::get_count()); + * } + * \endcode + */ + static std::uint32_t get_count(); + + private: + task_t task{}; +}; + +// STL Clock compliant clock +struct Clock { + using rep = std::uint32_t; + using period = std::milli; + using duration = std::chrono::duration; + using time_point = std::chrono::time_point; + const bool is_steady = true; + + /** + * Gets the current time. + * + * Effectively a wrapper around pros::millis() + * + * \return The current time + * + * \b Example + * \code + * void opcontrol() { + * pros::Clock::time_point start = pros::Clock::now(); + * pros::Clock::time_point end = pros::Clock::now(); + * pros::Clock::duration duration = end - start; + * printf("Duration: %d\n", duration.count()); + * + * if(duration.count() == 500) { + * // If you see this comment in the DOCS, ping @pros in VTOW. + * // If you are the first person to do so, you will receive a free PROS + * // holo! + * printf("Duration is 500 milliseconds\n"); + * } + * } + * \endcode + */ + static time_point now(); +}; + +class Mutex { + std::atomic mutex{nullptr}; + mutex_t lazy_init(); + public: + constexpr Mutex() { + if (!std::is_constant_evaluated()) { + lazy_init(); + } + } + + // disable copy and move construction and assignment per Mutex requirements + // (see https://en.cppreference.com/w/cpp/named_req/Mutex) + Mutex(const Mutex&) = delete; + Mutex(Mutex&&) = delete; + + Mutex& operator=(const Mutex&) = delete; + Mutex& operator=(Mutex&&) = delete; + + /** + * Takes and locks a mutex indefinetly. + * + * See + * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \return True if the mutex was successfully taken, false otherwise. If false + * is returned, then errno is set with a hint about why the the mutex + * couldn't be taken + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::Mutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.take(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.give(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.take(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.give(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.take(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.give(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + bool take(); + + /** + * Takes and locks a mutex, waiting for up to a certain number of milliseconds + * before timing out. + * + * See + * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \param timeout + * Time to wait before the mutex becomes available. A timeout of 0 can + * be used to poll the mutex. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the mutex was successfully taken, false otherwise. If false + * is returned, then errno is set with a hint about why the the mutex + * couldn't be taken. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::Mutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.take(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.give(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.take(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.give(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.take(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.give(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + bool take(std::uint32_t timeout); + + /** + * Unlocks a mutex. + * + * See + * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \return True if the mutex was successfully returned, false otherwise. If + * false is returned, then errno is set with a hint about why the mutex + * couldn't be returned. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::Mutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.take(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.give(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.take(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.give(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.take(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.give(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + bool give(); + + /** + * Takes and locks a mutex, waiting for up to TIMEOUT_MAX milliseconds. + * + * Effectively equivalent to calling pros::Mutex::take with TIMEOUT_MAX as + * the parameter. + * + * Conforms to named requirment BasicLockable + * \see https://en.cppreference.com/w/cpp/named_req/BasicLockable + * + * \note Consider using a std::unique_lock, std::lock_guard, or + * std::scoped_lock instead of interacting with the Mutex directly. + * + * \exception std::system_error Mutex could not be locked within TIMEOUT_MAX + * milliseconds. see errno for details. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::Mutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.lock(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.unlock(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.lock(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.unlock(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.lock(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.unlock(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + void lock(); + + /** + * Unlocks a mutex. + * + * Equivalent to calling pros::Mutex::give. + * + * Conforms to named requirement BasicLockable + * \see https://en.cppreference.com/w/cpp/named_req/BasicLockable + * + * \note Consider using a std::unique_lock, std::lock_guard, or + * std::scoped_lock instead of interacting with the Mutex direcly. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::Mutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.lock(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.unlock(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.lock(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.unlock(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.lock(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.unlock(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + void unlock(); + + /** + * Try to lock a mutex. + * + * Returns immediately if unsucessful. + * + * Conforms to named requirement Lockable + * \see https://en.cppreference.com/w/cpp/named_req/Lockable + * + * \return True when lock was acquired succesfully, or false otherwise. + * + * pros::Mutex mutex; + * + * void my_task_fn(void* param) { + * while (true) { + * if(mutex.try_lock()) { + * printf("Mutex aquired successfully!\n"); + * // Do stuff that requires the protected resource here + * } + * else { + * printf("Mutex not aquired!\n"); + * } + * } + * } + */ + [[nodiscard]] bool try_lock(); + + /** + * Takes and locks a mutex, waiting for a specified duration. + * + * Equivalent to calling pros::Mutex::take with a duration specified in + * milliseconds. + * + * Conforms to named requirement TimedLockable + * \see https://en.cppreference.com/w/cpp/named_req/TimedLockable + * + * \param rel_time Time to wait before the mutex becomes available. + * \return True if the lock was acquired succesfully, otherwise false. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while (true) { + * if(mutex.try_lock_for(std::chrono::milliseconds(100))) { + * printf("Mutex aquired successfully!\n"); + * // Do stuff that requires the protected resource here + * } + * else { + * printf("Mutex not aquired after 100 milliseconds!\n"); + * } + * } + * } + * \endcode + */ + template + [[nodiscard]] bool try_lock_for(const std::chrono::duration& rel_time) { + return take(std::chrono::duration_cast(rel_time).count()); + } + + /** + * Takes and locks a mutex, waiting until a specified time. + * + * Conforms to named requirement TimedLockable + * \see https://en.cppreference.com/w/cpp/named_req/TimedLockable + * + * \param abs_time Time point until which to wait for the mutex. + * \return True if the lock was acquired succesfully, otherwise false. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while (true) { + * // Get the current time point + * auto now = std::chrono::system_clock::now(); + * + * // Calculate the time point 100 milliseconds from now + * auto abs_time = now + std::chrono::milliseconds(100); + * + * if(mutex.try_lock_until(abs_time)) { + * printf("Mutex aquired successfully!\n"); + * // Do stuff that requires the protected resource here + * } + * else { + * printf("Mutex not aquired after 100 milliseconds!\n"); + * } + * } + * } + * \endcode + */ + template + bool try_lock_until(const std::chrono::time_point& abs_time) { + return take(std::max(static_cast(0), (abs_time - Clock::now()).count())); + } + ~Mutex(); + ///@} +}; + +class RecursiveMutex { + std::atomic mutex{nullptr}; + mutex_t lazy_init(); + public: + constexpr RecursiveMutex() { + if (!std::is_constant_evaluated()) { + lazy_init(); + } + } + + // disable copy and move construction and assignment per Mutex requirements + // (see https://en.cppreference.com/w/cpp/named_req/Mutex) + RecursiveMutex(const RecursiveMutex&) = delete; + RecursiveMutex(RecursiveMutex&&) = delete; + + RecursiveMutex& operator=(const RecursiveMutex&) = delete; + RecursiveMutex& operator=(RecursiveMutex&&) = delete; + + /** + * Takes and locks a mutex indefinetly. + * + * See + * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \return True if the mutex was successfully taken, false otherwise. If false + * is returned, then errno is set with a hint about why the the mutex + * couldn't be taken + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::RecursiveMutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.take(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.give(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.take(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.give(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.take(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.give(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::RecursiveMutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + bool take(); + + /** + * Takes and locks a mutex, waiting for up to a certain number of milliseconds + * before timing out. + * + * See + * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \param timeout + * Time to wait before the mutex becomes available. A timeout of 0 can + * be used to poll the mutex. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the mutex was successfully taken, false otherwise. If false + * is returned, then errno is set with a hint about why the the mutex + * couldn't be taken. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::RecursiveMutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.take(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.give(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.take(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.give(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.take(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.give(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::RecursiveMutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + bool take(std::uint32_t timeout); + + /** + * Unlocks a mutex. + * + * See + * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \return True if the mutex was successfully returned, false otherwise. If + * false is returned, then errno is set with a hint about why the mutex + * couldn't be returned. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::RecursiveMutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.take(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.give(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.take(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.give(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.take(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.give(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::RecursiveMutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + bool give(); + + /** + * Takes and locks a mutex, waiting for up to TIMEOUT_MAX milliseconds. + * + * Effectively equivalent to calling pros::RecursiveMutex::take with TIMEOUT_MAX as + * the parameter. + * + * Conforms to named requirment BasicLockable + * \see https://en.cppreference.com/w/cpp/named_req/BasicLockable + * + * \note Consider using a std::unique_lock, std::lock_guard, or + * std::scoped_lock instead of interacting with the Mutex directly. + * + * \exception std::system_error Mutex could not be locked within TIMEOUT_MAX + * milliseconds. see errno for details. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::RecursiveMutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.lock(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.unlock(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.lock(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.unlock(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.lock(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.unlock(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::RecursiveMutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + void lock(); + + /** + * Unlocks a mutex. + * + * Equivalent to calling pros::RecursiveMutex::give. + * + * Conforms to named requirement BasicLockable + * \see https://en.cppreference.com/w/cpp/named_req/BasicLockable + * + * \note Consider using a std::unique_lock, std::lock_guard, or + * std::scoped_lock instead of interacting with the Mutex direcly. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::RecursiveMutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.lock(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.unlock(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.lock(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.unlock(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.lock(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.unlock(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::RecursiveMutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + void unlock(); + + /** + * Try to lock a mutex. + * + * Returns immediately if unsucessful. + * + * Conforms to named requirement Lockable + * \see https://en.cppreference.com/w/cpp/named_req/Lockable + * + * \return True when lock was acquired succesfully, or false otherwise. + * + * pros::RecursiveMutex mutex; + * + * void my_task_fn(void* param) { + * while (true) { + * if(mutex.try_lock()) { + * printf("Mutex aquired successfully!\n"); + * // Do stuff that requires the protected resource here + * } + * else { + * printf("Mutex not aquired!\n"); + * } + * } + * } + */ + [[nodiscard]] bool try_lock(); + + /** + * Takes and locks a mutex, waiting for a specified duration. + * + * Equivalent to calling pros::RecursiveMutex::take with a duration specified in + * milliseconds. + * + * Conforms to named requirement TimedLockable + * \see https://en.cppreference.com/w/cpp/named_req/TimedLockable + * + * \param rel_time Time to wait before the mutex becomes available. + * \return True if the lock was acquired succesfully, otherwise false. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while (true) { + * if(mutex.try_lock_for(std::chrono::milliseconds(100))) { + * printf("Mutex aquired successfully!\n"); + * // Do stuff that requires the protected resource here + * } + * else { + * printf("Mutex not aquired after 100 milliseconds!\n"); + * } + * } + * } + * \endcode + */ + template + [[nodiscard]] bool try_lock_for(const std::chrono::duration& rel_time) { + return take(std::chrono::duration_cast(rel_time).count()); + } + + /** + * Takes and locks a mutex, waiting until a specified time. + * + * Conforms to named requirement TimedLockable + * \see https://en.cppreference.com/w/cpp/named_req/TimedLockable + * + * \param abs_time Time point until which to wait for the mutex. + * \return True if the lock was acquired succesfully, otherwise false. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while (true) { + * // Get the current time point + * auto now = std::chrono::system_clock::now(); + * + * // Calculate the time point 100 milliseconds from now + * auto abs_time = now + std::chrono::milliseconds(100); + * + * if(mutex.try_lock_until(abs_time)) { + * printf("Mutex aquired successfully!\n"); + * // Do stuff that requires the protected resource here + * } + * else { + * printf("Mutex not aquired after 100 milliseconds!\n"); + * } + * } + * } + * \endcode + */ + template + bool try_lock_until(const std::chrono::time_point& abs_time) { + return take(std::max(static_cast(0), (abs_time - Clock::now()).count())); + } + + ~RecursiveMutex(); + ///@} +}; + +template +class MutexVar; + +template +class MutexVarLock { + Mutex& mutex; + Var& var; + + friend class MutexVar; + + constexpr MutexVarLock(Mutex& mutex, Var& var) : mutex(mutex), var(var) {} + + public: + /** + * Accesses the value of the mutex-protected variable. + */ + constexpr Var& operator*() const { + return var; + } + + /** + * Accesses the value of the mutex-protected variable. + */ + constexpr Var* operator->() const { + return &var; + } + + ~MutexVarLock() { + mutex.unlock(); + } +}; + +template +class MutexVar { + Mutex mutex; + Var var; + + public: + /** + * Creates a mutex-protected variable which is initialized with the given + * constructor arguments. + * + * \param args + * The arguments to provide to the Var constructor. + * + * \b Example + * \code + * // We create a pose class to contain all our odometry data in a single + * // variable that can be protected by a MutexVar. Otherwise, we would have + * // three seperate variables which could not be protected in a single + * // MutexVar + * struct Pose { + * double x; + * double y; + * double heading; + * } + * + * pros::MutexVar odom_pose(0.0, 0.0, 0.0); + * + * void odom_task(void* param) { + * while(true) { + * Pose old_pose = *odom_pose.lock(); + * + * Pose new_pose{0.0, 0.0, 0.0}; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * + * *odom_pose.take() = new_pose; + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * + * Pose cur_pose = *odom_pose.take(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * + * \endcode + */ + template + MutexVar(Args&&... args) : mutex(), var(std::forward(args)...) {} + + /** + * Try to lock the mutex-protected variable. + * + * \param timeout + * Time to wait before the mutex becomes available, in milliseconds. A + * timeout of 0 can be used to poll the mutex. + * + * \return A std::optional which contains a MutexVarLock providing access to + * the protected variable if locking is successful. + * + * \b Example + * \code + * pros::MutexVar odom_pose; + * + * void my_task(void* param) { + * while(true) { + * std::optional> cur_pose_opt = odom_pose.try_lock(100); + * + * if(cur_pose_opt.has_value()) { + * Pose* cur_pose = **cur_pose_opt; + * } + * else { + * printf("Could not lock the mutex var!"); + * } + * + * pros::delay(10); + * } + * } + * \endcode + */ + std::optional> try_lock(std::uint32_t timeout) { + if (mutex.take(timeout)) { + return {{mutex, var}}; + } else { + return {}; + } + } + + /** + * Try to lock the mutex-protected variable. + * + * \param timeout + * Time to wait before the mutex becomes available. A timeout of 0 can + * be used to poll the mutex. + * + * \return A std::optional which contains a MutexVarLock providing access to + * the protected variable if locking is successful. + * + * \b Example + * \code + * pros::MutexVar odom_pose; + * + * void my_task(void* param) { + * while(true) { + * std::chrono::duration timeout(100); + * std::optional> cur_pose_opt = odom_pose.try_lock(timeout); + * + * if(cur_pose_opt.has_value()) { + * Pose* cur_pose = **cur_pose_opt; + * } + * else { + * printf("Could not lock the mutex var!"); + * } + * + * pros::delay(10); + * } + * } + * \endcode + */ + template + std::optional> try_lock(const std::chrono::duration& rel_time) { + try_lock(std::chrono::duration_cast(rel_time).count()); + } + + /** + * Lock the mutex-protected variable, waiting indefinitely. + * + * \return A MutexVarLock providing access to the protected variable. + * + * \b Example + * \code + * pros::MutexVar odom_pose; + * + * void my_task(void* param) { + * while(true) { + * pros::delay(10); + * + * pros::MutexVarLock cur_pose = odom_pose.lock(); + * Pose cur_pose = *cur_pose; + * + * // do stuff with cur_pose + * } + * } + * \endcode + */ + MutexVarLock lock() { + while (!mutex.take(TIMEOUT_MAX)) + ; + return {mutex, var}; + } +}; + +/** + * Gets the number of milliseconds since PROS initialized. + * + * \return The number of milliseconds since PROS initialized + */ +using pros::c::millis; + +/** + * Gets the number of microseconds since PROS initialized. + * + * \return The number of microseconds since PROS initialized + */ +using pros::c::micros; + +/** + * Delays a task for a given number of milliseconds. + * + * This is not the best method to have a task execute code at predefined + * intervals, as the delay time is measured from when the delay is requested. + * To delay cyclically, use task_delay_until(). + * + * \param milliseconds + * The number of milliseconds to wait (1000 milliseconds per second) + */ +using pros::c::delay; +} // namespace rtos +} // namespace pros + +#endif // _PROS_RTOS_HPP_ diff --git a/test/include/pros/screen.h b/test/include/pros/screen.h new file mode 100644 index 00000000..c1e567bc --- /dev/null +++ b/test/include/pros/screen.h @@ -0,0 +1,791 @@ +/** + * \file screen.h + * \ingroup c-screen + * + * Brain screen display and touch functions. + * + * Contains user calls to the v5 screen for touching and displaying graphics. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-screen Simplified Brain Screen C API + * + */ + +#ifndef _PROS_SCREEN_H_ +#define _PROS_SCREEN_H_ + +#include +#include +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include + +#include "pros/colors.h" // c color macros + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \ingroup c-screen + */ + +/** + * \addtogroup c-screen + * @{ + */ + +/** + * \enum text_format_e_t + * Different font sizes that can be used in printing text. + */ +typedef enum { + /// Small text font size + E_TEXT_SMALL = 0, + /// Normal/Medium text font size + E_TEXT_MEDIUM, + /// Large text font size + E_TEXT_LARGE, + /// Medium centered text + E_TEXT_MEDIUM_CENTER, + /// Large centered text + E_TEXT_LARGE_CENTER +} text_format_e_t; + +/** + * \enum last_touch_e_t + * Enum indicating what the current touch status is for the touchscreen. + */ +typedef enum { + /// Last interaction with screen was a quick press + E_TOUCH_RELEASED = 0, + /// Last interaction with screen was a release + E_TOUCH_PRESSED, + /// User is holding screen down + E_TOUCH_HELD, + /// An error occured while taking/returning the mutex + E_TOUCH_ERROR +} last_touch_e_t; + +/** + * \struct screen_touch_status_s_t + * Struct representing screen touch status, screen last x, screen last y, press count, release count. + */ +typedef struct screen_touch_status_s { + last_touch_e_t touch_status; ///< Represents if the screen is being held, released, or pressed. + int16_t x; ///< Represents the x value of the location of the touch. + int16_t y; ///< Represents the y value of the location of the touch. + int32_t press_count; ///< Represents how many times the screen has be pressed. + int32_t release_count; ///< Represents how many times the user released after a touch on the screen. +} screen_touch_status_s_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define TEXT_SMALL pros::E_TEXT_SMALL +#define TEXT_MEDIUM pros::E_TEXT_MEDIUM +#define TEXT_LARGE pros::E_TEXT_LARGE +#define TEXT_MEDIUM_CENTER pros::E_TEXT_MEDIUM_CENTER +#define TEXT_LARGE_CENTER pros::E_TEXT_LARGE_CENTER +#define TOUCH_RELEASED pros::E_TOUCH_RELEASED +#define TOUCH_PRESSED pros::E_TOUCH_PRESSED +#define TOUCH_HELD pros::E_TOUCH_HELD +#else +#define TEXT_SMALL E_TEXT_SMALL +#define TEXT_MEDIUM E_TEXT_MEDIUM +#define TEXT_LARGE E_TEXT_LARGE +#define TEXT_MEDIUM_CENTER E_TEXT_MEDIUM_CENTER +#define TEXT_LARGE_CENTER E_TEXT_LARGE_CENTER +#define TOUCH_RELEASED E_TOUCH_RELEASED +#define TOUCH_PRESSED E_TOUCH_PRESSED +#define TOUCH_HELD E_TOUCH_HELD +#endif +#endif + +typedef void (*touch_event_cb_fn_t)(); + +#ifdef __cplusplus +namespace c { +#endif + +/// \name Screen Graphical Display Functions +/// These functions allow programmers to display shapes on the v5 screen +///@{ + +/** + * Set the pen color for subsequent graphics operations + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The pen color to set (it is recommended to use values + * from the enum defined in colors.h) + * + * \return Returns 1 if the mutex was successfully returned, or PROS_ERR if + * there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * screen_set_pen(COLOR_RED); + * } + * + * void opcontrol() { + * int iter = 0; + * while(1){ + * // This should print in red. + * screen_print(TEXT_MEDIUM, 1, "%d", iter++); + * } + * } + * \endcode + */ +uint32_t screen_set_pen(uint32_t color); + +/** + * Set the eraser color for erasing and the current background. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The background color to set (it is recommended to use values + * from the enum defined in colors.h) + * + * \return Returns 1 if the mutex was successfully returned, or + * PROS_ERR if there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * screen_set_eraser(COLOR_RED); + * } + * + * void opcontrol() { + * while(1){ + * // This should turn the screen red. + * screen_erase(); + * } + * } + * \endcode + */ +uint32_t screen_set_eraser(uint32_t color); + +/** + * Get the current pen color. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return The current pen color in the form of a value from the enum defined + * in colors.h, or PROS_ERR if there was an error taking or returning + * the screen mutex. + * + * \b Example + * \code + * void initialize() { + * screen_set_pen(COLOR_RED); + * } + * + * void opcontrol() { + * while(1){ + * // Should print number equivalent to COLOR_RED defined in colors.h. + * screen_print(TEXT_MEDIUM, 1, "%d", screen_get_pen()); + * } + * } + * \endcode + */ +uint32_t screen_get_pen(void); + +/** + * Get the current eraser color. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return The current eraser color in the form of a value from the enum + * defined in colors.h, or PROS_ERR if there was an error taking or + * returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * screen_set_eraser(COLOR_RED); + * } + * + * void opcontrol() { + * while(1){ + * // Should print number equivalent to COLOR_RED defined in colors.h. + * screen_print(TEXT_MEDIUM, 1, "%d", screen_get_eraser()); + * } + * } + * \endcode + */ +uint32_t screen_get_eraser(void); + +/** + * Clear display with eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * screen_set_eraser(COLOR_RED); + * } + * + * void opcontrol() { + * while(1){ + * // This should turn the screen red. + * screen_erase(); + * } + * } + * \endcode + */ +uint32_t screen_erase(void); + +/** + * Scroll lines on the display upwards. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param start_line The line from which scrolling will start + * \param lines The number of lines to scroll up + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_print(TEXT_MEDIUM, 4, "Line Here"); + * // Scroll 3 lines + * screen_scroll(4, 3); + * } + * \endcode + */ +uint32_t screen_scroll(int16_t start_line, int16_t lines); + +/** + * Scroll lines within a region on the display + * + * This function behaves in the same way as `screen_scroll`, except that you + * specify a rectangular region within which to scroll lines instead of a start + * line. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first corner of the + * rectangular region + * \param x1, y1 The (x,y) coordinates of the second corner of the + * rectangular region + * \param lines The number of lines to scroll upwards + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_print(TEXT_MEDIUM, 1, "Line Here"); + * // Scrolls area of screen upwards slightly. including line of text + * screen_scroll_area(0,0, 400, 200, 3); + * } + * \endcode + */ +uint32_t screen_scroll_area(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t lines); + +/** + * Copy a screen region (designated by a rectangle) from an off-screen buffer + * to the screen + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first corner of the + * rectangular region of the screen + * \param x1, y1 The (x,y) coordinates of the second corner of the + * rectangular region of the screen + * \param buf Off-screen buffer containing screen data + * \param stride Off-screen buffer width in pixels, such that image size + * is stride-padding + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * uint32_t* buf = malloc(sizeof(uint32_t) * 400 * 200); + * screen_print(TEXT_MEDIUM, 1, "Line Here"); + * // Copies area of the screen including text + * screen_copy_area(0, 0, 400, 200, (uint32_t*)buf, 400 + 1); + * // Equation for stride is x2 - x1 + 1 + * } + * \endcode + */ +uint32_t screen_copy_area(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint32_t* buf, int32_t stride); + +/** + * Draw a single pixel on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the pixel + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * int i = 0; + * void opcontrol() { + * while(i < 200){ + * screen_draw_pixel(100,i++); + * // Draws a line at x = 100 gradually down the screen, pixel by pixel + * delay(200); + * } + * } + * \endcode + */ +uint32_t screen_draw_pixel(int16_t x, int16_t y); + +/** + * Erase a pixel from the screen (Sets the location) + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the erased + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Color the Screen in Red + * screen_set_pen(COLOR_RED); + * screen_fill_rect(0,0,400,200); + * int i = 0; + * while(i < 200){ + * screen_erase_pixel(100,i++); + * // Erases a line at x = 100 gradually down the screen, pixel by pixel + * delay(200); + * } + * } + * \endcode + */ +uint32_t screen_erase_pixel(int16_t x, int16_t y); + +/** + * Draw a line on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x, y) coordinates of the first point of the line + * \param x1, y1 The (x, y) coordinates of the second point of the line + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_set_pen(COLOR_RED); + * // Draw line down the screen at x = 100 + * screen_draw_line(100,0,100,200); + * } + * \endcode + */ +uint32_t screen_draw_line(int16_t x0, int16_t y0, int16_t x1, int16_t y1); + +/** + * Erase a line on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x, y) coordinates of the first point of the line + * \param x1, y1 The (x, y) coordinates of the second point of the line + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Color the Screen in Red + * screen_set_pen(COLOR_RED); + * screen_fill_rect(0,0,400,200); + * // Erase line down the screen at x = 100 + * screen_erase_line(100,0,100,200); + * } + * \endcode + */ +uint32_t screen_erase_line(int16_t x0, int16_t y0, int16_t x1, int16_t y1); + +/** + * Draw a rectangle on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_set_pen(COLOR_RED); + * screen_draw_rect(1,1,480,200); + * } + * \endcode + */ +uint32_t screen_draw_rect(int16_t x0, int16_t y0, int16_t x1, int16_t y1); + +/** + * Erase a rectangle on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Draw Box Around Half the Screen in Red + * screen_set_eraser(COLOR_RED); + * screen_erase_rect(5,5,240,200); + * } + * \endcode + */ +uint32_t screen_erase_rect(int16_t x0, int16_t y0, int16_t x1, int16_t y1); + +/** + * Fill a rectangular region of the screen using the current pen + * color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Fill Around Half the Screen in Red + * screen_set_pen(COLOR_RED); + * screen_fill_rect(5,5,240,200); + * } + * \endcode + */ +uint32_t screen_fill_rect(int16_t x0, int16_t y0, int16_t x1, int16_t y1); + +/** + * Draw a circle on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Draw a circle with radius of 100 in red + * screen_set_pen(COLOR_RED); + * screen_draw_circle(240, 200, 100); + * } + * \endcode + */ +uint32_t screen_draw_circle(int16_t x, int16_t y, int16_t radius); + +/** + * Erase a circle on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_set_pen(COLOR_RED); + * screen_fill_rect(5,5,240,200); + * // Erase a circle with radius of 100 in COLOR_BLUE + * screen_set_pen(COLOR_BLUE); + * screen_erase_circle(240, 200, 100); + * } + * \endcode + */ +uint32_t screen_erase_circle(int16_t x, int16_t y, int16_t radius); + +/** + * Fill a circular region of the screen using the current pen + * color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_set_pen(COLOR_RED); + * screen_fill_rect(5,5,240,200); + * // Fill a circlular area with radius of 100 in COLOR_BLUE + * screen_set_pen(COLOR_BLUE); + * screen_fill_circle(240, 200, 100); + * } + * \endcode + */ +uint32_t screen_fill_circle(int16_t x, int16_t y, int16_t radius); + +///@} + +/// \name Screen Text Display Functions +/// These functions allow programmers to display text on the v5 screen +///@{ + +/** + * Print a formatted string to the screen on the specified line + * + * Will default to a medium sized font by default if invalid txt_fmt is given. + * + * \param txt_fmt Text format enum that determines if the text is medium, large, medium_center, or large_center. (DOES + * NOT SUPPORT SMALL) \param line The line number on which to print \param text Format string \param ... Optional list + * of arguments for the format string + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * int i = 0; + * + * screen_set_pen(COLOR_BLUE); + * while(1){ + * // Will print seconds started since program started on line 3 + * screen_print(TEXT_MEDIUM, 3, "Seconds Passed: %3d", i++); + * delay(1000); + * } + * } + * \endcode + */ +uint32_t screen_print(text_format_e_t txt_fmt, const int16_t line, const char* text, ...); + +/** + * Print a formatted string to the screen at the specified point + * + * Will default to a medium sized font by default if invalid txt_fmt is given. + * + * Text formats medium_center and large_center will default to medium and large respectively. + * + * \param txt_fmt Text format enum that determines if the text is small, medium, or large. + * \param x The y coordinate of the top left corner of the string + * \param y The x coordinate of the top left corner of the string + * \param text Format string + * \param ... Optional list of arguments for the format string + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * int i = 0; + * + * screen_set_pen(COLOR_BLUE); + * while(1){ + * // Will print seconds started since program started. + * screen_print_at(TEXT_SMALL, 3, "Seconds Passed: %3d", i++); + * delay(1000); + * } + * } + * \endcode + */ +uint32_t screen_print_at(text_format_e_t txt_fmt, const int16_t x, const int16_t y, const char* text, ...); + +/** + * Print a formatted string to the screen on the specified line + * + * Same as `display_printf` except that this uses a `va_list` instead of the + * ellipsis operator so this can be used by other functions. + * + * Will default to a medium sized font by default if invalid txt_fmt is given. + * Exposed mostly for writing libraries and custom functions. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param txt_fmt Text format enum that determines if the text is medium, large, medium_center, or large_center. (DOES + * NOT SUPPORT SMALL) \param line The line number on which to print \param text Format string \param args List of + * arguments for the format string + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * while taking or returning the screen mutex. + * + * + */ +uint32_t screen_vprintf(text_format_e_t txt_fmt, const int16_t line, const char* text, va_list args); + +/** + * Print a formatted string to the screen at the specified coordinates + * + * Same as `display_printf_at` except that this uses a `va_list` instead of the + * ellipsis operator so this can be used by other functions. + * + * Will default to a medium sized font by default if invalid txt_fmt is given. + * + * Text formats medium_center and large_center will default to medium and large respectively. + * Exposed mostly for writing libraries and custom functions. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param txt_fmt Text format enum that determines if the text is small, medium, or large. + * \param x, y The (x,y) coordinates of the top left corner of the string + * \param text Format string + * \param args List of arguments for the format string + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * while taking or returning the screen mutex. + * + */ +uint32_t screen_vprintf_at(text_format_e_t txt_fmt, const int16_t x, const int16_t y, const char* text, va_list args); + +///@} + +/// \name Screen Touch Functions +/// These functions allow programmers to access information about screen touches +///@{ + +/** + * Gets the touch status of the last touch of the screen. + * + * \return The last_touch_e_t enum specifier that indicates the last touch status of the screen (E_TOUCH_EVENT_RELEASE, + * E_TOUCH_EVENT_PRESS, or E_TOUCH_EVENT_PRESS_AND_HOLD). This will be released by default if no action was taken. If an + * error occured, the screen_touch_status_s_t will have its last_touch_e_t enum specifier set to E_TOUCH_ERR, and other + * values set to -1. + * + * \b Example + * \code + * void opcontrol() { + * int i = 0; + * screen_touch_status_s_t status; + * while(1){ + * status = screen_touch_status(); + * + * // Will print various information about the last touch + * screen_print(TEXT_MEDIUM, 1, "Touch Status (Type): %d", status.touch_status); + * screen_print(TEXT_MEDIUM, 2, "Last X: %d", status.x); + * screen_print(TEXT_MEDIUM, 3, "Last Y: %d", status.y); + * screen_print(TEXT_MEDIUM, 4, "Press Count: %d", status.press_count); + * screen_print(TEXT_MEDIUM, 5, "Release Count: %d", status.release_count); + * delay(20); + * } + * } + * \endcode + */ +screen_touch_status_s_t screen_touch_status(void); + +/** + * Assigns a callback function to be called when a certain touch event happens. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param cb Function pointer to callback when event type happens + * \param event_type Touch event that will trigger the callback. + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * while taking or returning the screen mutex. + * + * \b Example + * \code + * touch_event_cb_fn_t changePixel(){ + * screen_touch_status_s_t status = screen_touch_status(); + * screen_draw_pixel(status.x,status.y); + * return NULL; + * } + * + * void opcontrol() { + * screen_touch_callback(changePixel(), TOUCH_PRESSED); + * while(1) delay(20); + * } + * \endcode + */ +uint32_t screen_touch_callback(touch_event_cb_fn_t cb, last_touch_e_t event_type); + +///@} + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif diff --git a/test/include/pros/screen.hpp b/test/include/pros/screen.hpp new file mode 100644 index 00000000..cbfe2fcf --- /dev/null +++ b/test/include/pros/screen.hpp @@ -0,0 +1,717 @@ +/** + * \file screen.hpp + * \ingroup cpp-screen + * + * Brain screen display and touch functions. + * + * Contains user calls to the v5 screen for touching and displaying graphics. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-screen Simplified Brain Screen C++ API + */ + +#ifndef _PROS_SCREEN_HPP_ +#define _PROS_SCREEN_HPP_ + +#include "pros/screen.h" +#include "pros/colors.hpp" +#include +#include + +namespace pros { +namespace screen { + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" + +namespace { +template +T convert_args(T arg) { + return arg; +} +const char* convert_args(const std::string& arg) { + return arg.c_str(); +} +} // namespace + +#pragma GCC diagnostic pop + +/** + * \ingroup cpp-screen + */ + +/** + * \addtogroup cpp-screen + * @{ + */ + + /******************************************************************************/ + /** Screen Graphical Display Functions **/ + /** **/ + /** These functions allow programmers to display shapes on the v5 screen **/ + /******************************************************************************/ + + /** + * Set the pen color for subsequent graphics operations + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The pen color to set (it is recommended to use values + * from the enum defined in colors.hpp) + * + * \return Returns 1 if the mutex was successfully returned, or PROS_ERR if + * there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * pros::screen::set_pen(red); + * } + * + * void opcontrol() { + * int iter = 0; + * while(1){ + * // This should print in red. + * pros::screen::print(TEXT_MEDIUM, 1, "%d", iter++); + * } + * } + * + * \endcode + */ + std::uint32_t set_pen(pros::Color color); + + /** + * Set the pen color for subsequent graphics operations + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The pen color to set (in hex form) + * + * \return Returns 1 if the mutex was successfully returned, or PROS_ERR if + * there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * //set pen color to red + * pros::screen::set_pen(0x00FF0000); + * } + * + * void opcontrol() { + * int iter = 0; + * while(1){ + * // This should print in red. + * pros::screen::print(TEXT_MEDIUM, 1, "%d", iter++); + * } + * } + * + * \endcode + */ + std::uint32_t set_pen(std::uint32_t color); + + /** + * Set the eraser color for erasing and the current background. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The background color to set (it is recommended to use values + * from the enum defined in colors.hpp) + * + * \return Returns 1 if the mutex was successfully returned, or PROS_ERR + * if there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * //set eraser color to red + * set_eraser(red); + * } + * + * void opcontrol() { + * int iter = 0; + * while(1){ + * // This should print in red. + * pros::screen::print(TEXT_MEDIUM, 1, "%d", iter++); + * } + * } + * + * \endcode + */ + std::uint32_t set_eraser(pros::Color color); + + /** + * Set the eraser color for erasing and the current background. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The background color to set to set (in hex form) + * + * \return Returns 1 if the mutex was successfully returned, or PROS_ERR + * if there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * //set eraser color to red + * pros::screen::set_eraser(0x00FF0000); + * } + * + * void opcontrol() { + * while(1){ + * // This should turn the screen red. + * pros::screen::erase(); + * } + * } + * \endcode + */ + std::uint32_t set_eraser(std::uint32_t color); + + /** + * Get the current pen color. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return The current pen color in the form of a value from the enum + * defined in colors.h, or PROS_ERR if there was an error taking or + * returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * pros::screen::set_pen(red); + * } + * + * void opcontrol() { + * while(1){ + * // Should print number equivalent to red defined in colors.hpp. + * pros::screen::print(TEXT_MEDIUM, 1, "%d", get_pen()); + * } + * } + * \endcode + */ + std::uint32_t get_pen(); + + /** + * Get the current eraser color. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return The current eraser color in the form of a value from the enum + * defined in colors.h, or PROS_ERR if there was an error taking or + * returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * pros::screen::set_eraser(red); + * } + * + * void opcontrol() { + * while(1){ + * // Should print number equivalent to red defined in colors.h. + * pros::screen::print(TEXT_MEDIUM, 1, "%d", get_eraser()); + * } + * } + * \endcode + */ + std::uint32_t get_eraser(); + + /** + * Clear display with eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * * \b Example + * \code + * void initialize() { + * pros::screen::set_eraser(red); + * } + * + * void opcontrol() { + * while(1){ + * // This should turn the screen red. + * pros::screen::erase(); + * } + * } + * \endcode + */ + std::uint32_t erase(); + + /** + * Scroll lines on the display upwards. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param start_line The line from which scrolling will start + * \param lines The number of lines to scroll up + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::print(TEXT_MEDIUM, 4, "Line Here"); + * // Scroll 3 lines + * pros::screen::scroll(4, 3); + * } + * \endcode + */ + std::uint32_t scroll(const std::int16_t start_line, const std::int16_t lines); + + /** + * Scroll lines within a region on the display + * + * This function behaves in the same way as `screen_scroll`, except that you + * specify a rectangular region within which to scroll lines instead of a start + * line. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first corner of the + * rectangular region + * \param x1, y1 The (x,y) coordinates of the second corner of the + * rectangular region + * \param lines The number of lines to scroll upwards + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::print(TEXT_MEDIUM, 1, "Line Here"); + * // Scrolls area of screen upwards slightly. including line of text + * pros::screen::scroll_area(0,0, 400, 200, 3); + * } + * \endcode + */ + std::uint32_t scroll_area(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1, std::int16_t lines); + + /** + * Copy a screen region (designated by a rectangle) from an off-screen buffer + * to the screen + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first corner of the + * rectangular region of the screen + * \param x1, y1 The (x,y) coordinates of the second corner of the + * rectangular region of the screen + * \param buf Off-screen buffer containing screen data + * \param stride Off-screen buffer width in pixels, such that image size + * is stride-padding + * + * \return 1 if there were no errors, or PROS_ERR if an error occured taking + * or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * uint32_t* buf = malloc(sizeof(uint32_t) * 400 * 200); + * pros::screen::print(TEXT_MEDIUM, 1, "Line Here"); + * // Copies area of the screen including text + * pros::screen::copy_area(0, 0, 400, 200, (uint32_t*)buf, 400 + 1); + * // Equation for stride is x2 - x1 + 1 + * } + * \endcode + */ + std::uint32_t copy_area(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1, uint32_t* buf, const std::int32_t stride); + + /** + * Draw a single pixel on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the pixel + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * int i = 0; + * void opcontrol() { + * while(i < 200){ + * pros::screen::draw_pixel(100,i++); + * // Draws a line at x = 100 gradually down the screen, pixel by pixel + * pros::delay(200); + * } + * } + * \endcode + */ + std::uint32_t draw_pixel(const std::int16_t x, const std::int16_t y); + + /** + * Erase a pixel from the screen (Sets the location) + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the erased + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Color the Screen in Red + * pros::screen::set_pen(red); + * pros::screen::fill_rect(0,0,400,200); + * int i = 0; + * while(i < 200){ + * pros::screen::erase_pixel(100,i++); + * // Erases a line at x = 100 gradually down the screen, pixel by pixel + * pros::delay(200); + * } + * } + * \endcode + */ + std::uint32_t erase_pixel(const std::int16_t x, const std::int16_t y); + + /** + * Draw a line on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x, y) coordinates of the first point of the line + * \param x1, y1 The (x, y) coordinates of the second point of the line + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::set_pen(red); + * // Draw line down the screen at x = 100 + * pros::screen::draw_line(100,0,100,200); + * } + * \endcode + */ + std::uint32_t draw_line(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); + + /** + * Erase a line on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x, y) coordinates of the first point of the line + * \param x1, y1 The (x, y) coordinates of the second point of the line + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Color the Screen in Red + * pros::screen::set_pen(red); + * pros::screen::fill_rect(0,0,400,200); + * // Erase line down the screen at x = 100 + * pros::screen::erase_line(100,0,100,200); + * } + * \endcode + */ + std::uint32_t erase_line(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); + + /** + * Draw a rectangle on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::set_pen(red); + * pros::screen::draw_rect(1,1,480,200); + * } + * \endcode + */ + std::uint32_t draw_rect(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); + + /** + * Erase a rectangle on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Draw Box Around Half the Screen in Red + * pros::screen::set_eraser(red); + * pros::screen::erase_rect(5,5,240,200); + * } + * \endcode + */ + std::uint32_t erase_rect(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); + + /** + * Fill a rectangular region of the screen using the current pen + * color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Fill Around Half the Screen in Red + * pros::screen::set_pen(red); + * pros::screen::fill_rect(5,5,240,200); + * } + * \endcode + */ + std::uint32_t fill_rect(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); + + /** + * Draw a circle on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Draw a circle with radius of 100 in red + * pros::screen::set_pen(red); + * pros::screen::draw_circle(240, 200, 100); + * } + * \endcode + */ + std::uint32_t draw_circle(const std::int16_t x, const std::int16_t y, const std::int16_t radius); + + /** + * Erase a circle on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::set_pen(red); + * pros::screen::fill_rect(5,5,240,200); + * // Erase a circle with radius of 100 in blue + * pros::screen::set_pen(blue); + * pros::screen::erase_circle(240, 200, 100); + * } + * \endcode + */ + std::uint32_t erase_circle(const std::int16_t x, const std::int16_t y, const std::int16_t radius); + + /** + * Fill a circular region of the screen using the current pen + * color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::set_pen(red); + * pros::screen::fill_rect(5,5,240,200); + * // Fill a circlular area with radius of 100 in blue + * pros::screen::set_pen(blue); + * pros::screen::fill_circle(240, 200, 100); + * } + * \endcode + */ + std::uint32_t fill_circle(const std::int16_t x, const std::int16_t y, const std::int16_t radius); + + /******************************************************************************/ + /** Screen Text Display Functions **/ + /** **/ + /** These functions allow programmers to display text on the v5 screen **/ + /******************************************************************************/ + + /** + * Print a formatted string to the screen, overwrite available for printing at location too. + * + * Will default to a medium sized font by default if invalid txt_fmt is given. + * + * \param txt_fmt Text format enum that determines if the text is medium, large, medium_center, or large_center. (DOES NOT SUPPORT SMALL) + * \param line The line number on which to print + * \param x The (x,y) coordinates of the top left corner of the string + * \param y The (x,y) coordinates of the top left corner of the string + * \param fmt Format string + * \param ... Optional list of arguments for the format string + * + * \b Example + * \code + * void opcontrol() { + * int i = 0; + * pros::screen::set_pen(blue); + * while(1){ + * // Will print seconds started since program started on line 3 + * pros::screen::print(pros::TEXT_MEDIUM, 3, "Seconds Passed: %3d", i++); + * pros::delay(1000); + * } + * } + */ + template + void print(pros::text_format_e_t txt_fmt, const std::int16_t line, const char* text, Params... args){ + pros::c::screen_print(txt_fmt, line, text, convert_args(args)...); + } + + template + void print(pros::text_format_e_t txt_fmt, const std::int16_t x, const std::int16_t y, const char* text, Params... args){ + pros::c::screen_print_at(txt_fmt, x, y, text, convert_args(args)...); + } + + /******************************************************************************/ + /** Screen Touch Functions **/ + /** **/ + /** These functions allow programmers to access **/ + /** information about screen touches **/ + /******************************************************************************/ + + /** + * Gets the touch status of the last touch of the screen. + * + * \return The last_touch_e_t enum specifier that indicates the last touch status of the screen (E_TOUCH_EVENT_RELEASE, E_TOUCH_EVENT_PRESS, or E_TOUCH_EVENT_PRESS_AND_HOLD). + * This will be released by default if no action was taken. + * If an error occured, the screen_touch_status_s_t will have its + * last_touch_e_t enum specifier set to E_TOUCH_ERR, and other values set to -1. + * + * \b Example + * \code + * void opcontrol() { + * int i = 0; + * pros::screen_touch_status_s_t status; + * while(1){ + * status = pros::touch_status(); + * + * // Will print various information about the last touch + * pros::screen::print(TEXT_MEDIUM, 1, "Touch Status (Type): %d", status.touch_status); + * pros::screen::print(TEXT_MEDIUM, 2, "Last X: %d", status.x); + * pros::screen::print(TEXT_MEDIUM, 3, "Last Y: %d", status.y); + * pros::screen::print(TEXT_MEDIUM, 4, "Press Count: %d", status.press_count); + * pros::screen::print(TEXT_MEDIUM, 5, "Release Count: %d", status.release_count); + * pros::delay(20); + * } + * } + * \endcode + */ + screen_touch_status_s_t touch_status(); + + /** + * Assigns a callback function to be called when a certain touch event happens. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param cb Function pointer to callback when event type happens + * \param event_type Touch event that will trigger the callback. + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * while taking or returning the screen mutex. + * + * \b Example + * \code + * touch_event_cb_fn_t changePixel(){ + * pros::screen_touch_status_s_t status = pros::screen::touch_status(); + * pros::screen::draw_pixel(status.x,status.y); + * return NULL; + * } + * + * void opcontrol() { + * pros::screen::touch_callback(changePixel(), TOUCH_PRESSED); + * while(1) { + * pros::delay(20); + * } + * } + * \endcode + */ + std::uint32_t touch_callback(touch_event_cb_fn_t cb, last_touch_e_t event_type); + +} // namespace screen + + +} // namespace pros + +extern __attribute__((weak)) void lvgl_init() {} +///@} +#endif //header guard diff --git a/test/include/pros/serial.h b/test/include/pros/serial.h new file mode 100644 index 00000000..4bda6069 --- /dev/null +++ b/test/include/pros/serial.h @@ -0,0 +1,410 @@ +/** + * \file pros/serial.h + * \ingroup c-serial + * + * Contains prototypes for the V5 Generic Serial related functions. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-serial Generic Serial C API + */ + +#ifndef _PROS_SERIAL_H_ +#define _PROS_SERIAL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \ingroup c-serial + */ + +/** + * \addtogroup c-serial + * @{ + */ + +/// \name Serial communication functions +/// These functions allow programmers to communicate using UART over RS485 +///@{ + +/** + * Enables generic serial on the given port. + * + * \note This function must be called before any of the generic serial + * functions will work. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * } + * \endcode + */ +int32_t serial_enable(uint8_t port); + +/** + * Sets the baudrate for the serial port to operate at. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * \param baudrate + * The baudrate to operate at + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * serial_write(1, "Hello World!", 12); + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_set_baudrate(uint8_t port, int32_t baudrate); + +/** + * Clears the internal input and output FIFO buffers. + * + * This can be useful to reset state and remove old, potentially unneeded data + * from the input FIFO buffer or to cancel sending any data in the output FIFO + * buffer. + * + * \note This function does not cause the data in the output buffer to be + * written, it simply clears the internal buffers. Unlike stdout, generic + * serial does not use buffered IO (the FIFO buffers are written as soon + * as possible). + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * serial_flush(1); + * serial_write(1, "Hello World!", 12); + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_flush(uint8_t port); + +/** + * Returns the number of bytes available to be read in the the port's FIFO + * input buffer. + * + * \note This function does not actually read any bytes, is simply returns the + * number of bytes available to be read. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return The number of bytes avaliable to be read or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_get_read_avail(1) >= 12) { + * char buffer[12]; + * serial_read(1, buffer, 12); + * printf("%s", buffer); + * } + * delay(100); + * } + * } + * \endcode + + */ +int32_t serial_get_read_avail(uint8_t port); + +/** + * Returns the number of bytes free in the port's FIFO output buffer. + * + * \note This function does not actually write any bytes, is simply returns the + * number of bytes free in the port's buffer. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return The number of bytes free or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_get_write_free(1) >= 12) { + * serial_write(1, "Hello World!", 12); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_get_write_free(uint8_t port); + +/** + * Reads the next byte avaliable in the port's input buffer without removing it. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return The next byte avaliable to be read, -1 if none are available, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_peek_byte(1) == 'H') { + * char buffer[12]; + * serial_read(1, buffer, 12); + * printf("%s", buffer); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_peek_byte(uint8_t port); + +/** + * Reads the next byte avaliable in the port's input buffer. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return The next byte avaliable to be read, -1 if none are available, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_read_byte(1) == 'H') { + * char buffer[12]; + * serial_read(1, buffer, 12); + * printf("%s", buffer); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_read_byte(uint8_t port); + +/** + * Reads up to the next length bytes from the port's input buffer and places + * them in the user supplied buffer. + * + * \note This function will only return bytes that are currently avaliable to be + * read and will not block waiting for any to arrive. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * \param buffer + * The location to place the data read + * \param length + * The maximum number of bytes to read + * + * \return The number of bytes read or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_get_read_avail(1) >= 12) { + * char buffer[12]; + * serial_read(1, buffer, 12); + * printf("%s", buffer); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_read(uint8_t port, uint8_t* buffer, int32_t length); + +/** + * Write the given byte to the port's output buffer. + * + * \note Data in the port's output buffer is written to the serial port as soon + * as possible on a FIFO basis and can not be done manually by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * EIO - Serious internal write error. + * + * \param port + * The V5 port number from 1-21 + * \param buffer + * The byte to write + * + * \return The number of bytes written or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_get_write_free(1) >= 12) { + * serial_write_byte(1, 'H'); + * serial_write_byte(1, 'e'); + * serial_write_byte(1, 'l'); + * serial_write_byte(1, 'l'); + * serial_write_byte(1, 'o'); + * serial_write_byte(1, ' '); + * serial_write_byte(1, 'W'); + * serial_write_byte(1, 'o'); + * serial_write_byte(1, 'r'); + * serial_write_byte(1, 'l'); + * serial_write_byte(1, 'd'); + * serial_write_byte(1, '!'); + * serial_write_byte(1, '\n'); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_write_byte(uint8_t port, uint8_t buffer); + +/** + * Writes up to length bytes from the user supplied buffer to the port's output + * buffer. + * + * \note Data in the port's output buffer is written to the serial port as soon + * as possible on a FIFO basis and can not be done manually by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * EIO - Serious internal write error. + * + * \param port + * The V5 port number from 1-21 + * \param buffer + * The data to write + * \param length + * The maximum number of bytes to write + * + * \return The number of bytes written or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_get_write_free(1) >= 12) { + * serial_write(1, "Hello World!\n", 12); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_write(uint8_t port, uint8_t* buffer, int32_t length); + +///@} + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_SERIAL_H_ \ No newline at end of file diff --git a/test/include/pros/serial.hpp b/test/include/pros/serial.hpp new file mode 100644 index 00000000..a7df8e77 --- /dev/null +++ b/test/include/pros/serial.hpp @@ -0,0 +1,344 @@ +/** + * \file pros/serial.hpp + * \ingroup cpp-serial + * + * Contains prototypes for the V5 Generic Serial related functions. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-serial Generic Serial C++ API + */ + +#ifndef _PROS_SERIAL_HPP_ +#define _PROS_SERIAL_HPP_ + +#include + +#include "pros/device.hpp" +#include "pros/serial.h" + +namespace pros { +/** + * \ingroup cpp-serial + * @{ + */ +class Serial : public Device { + /** + * \addtogroup cpp-serial + * @{ + */ + public: + /** + * Creates a Serial object for the given port and specifications. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * \param baudrate + * The baudrate to run the port at + * + * \b Example: + * \code + * pros::Serial serial(1, 9600); + * \endcode + */ + explicit Serial(std::uint8_t port, std::int32_t baudrate); + + /** + * Creates a Serial object for the given port without a set baudrate. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \b Example: + * \code + * pros::Serial serial(1); + * \endcode + */ + explicit Serial(std::uint8_t port); + + /******************************************************************************/ + /** Serial communication functions **/ + /** **/ + /** These functions allow programmers to communicate using UART over RS485 **/ + /******************************************************************************/ + + /** + * Sets the baudrate for the serial port to operate at. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param baudrate + * The baudrate to operate at + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code + * pros::Serial serial(1); + * serial.set_baudrate(9600); + * \endcode + */ + virtual std::int32_t set_baudrate(std::int32_t baudrate) const; + + /** + * Clears the internal input and output FIFO buffers. + * + * This can be useful to reset state and remove old, potentially unneeded data + * from the input FIFO buffer or to cancel sending any data in the output FIFO + * buffer. + * + * \note This function does not cause the data in the output buffer to be + * written, it simply clears the internal buffers. Unlike stdout, generic + * serial does not use buffered IO (the FIFO buffers are written as soon + * as possible). + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code + * pros::Serial serial(1); + * serial.flush(); + * \endcode + */ + virtual std::int32_t flush() const; + + /** + * Returns the number of bytes available to be read in the the port's FIFO + * input buffer. + * + * \note This function does not actually read any bytes, is simply returns the + * number of bytes available to be read. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \return The number of bytes avaliable to be read or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Serial serial(1); + * if(serial.get_read_avail() > 0) { + * std::uint8_t byte = serial.read_byte(); + * } + * } + * \endcode + */ + virtual std::int32_t get_read_avail() const; + + /** + * Returns the number of bytes free in the port's FIFO output buffer. + * + * \note This function does not actually write any bytes, is simply returns the + * number of bytes free in the port's buffer. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \return The number of bytes free or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Serial serial(1); + * if(serial.get_write_free() > 0) { + * serial.write_byte(0x01); + * pros::delay(10); + * } + * } + * \endcode + */ + virtual std::int32_t get_write_free() const; + + /** + * Reads the next byte avaliable in the port's input buffer without removing it. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \return The next byte avaliable to be read, -1 if none are available, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Serial serial(1); + * if(serial.peek_byte() == 0x01) { + * serial.read_byte(); + * } + * } + * \endcode + */ + virtual std::int32_t peek_byte() const; + + /** + * Reads the next byte avaliable in the port's input buffer. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \return The next byte avaliable to be read, -1 if none are available, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Serial serial(1); + * if(serial.read_byte() == 0x01) { + * // Do something + * } + * } + * \endcode + */ + virtual std::int32_t read_byte() const; + + /** + * Reads up to the next length bytes from the port's input buffer and places + * them in the user supplied buffer. + * + * \note This function will only return bytes that are currently avaliable to be + * read and will not block waiting for any to arrive. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param buffer + * The location to place the data read + * \param length + * The maximum number of bytes to read + * + * \return The number of bytes read or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Serial serial(1); + * std::uint8_t buffer[10]; + * serial.read(buffer, 10); + * } + * \endcode + */ + virtual std::int32_t read(std::uint8_t* buffer, std::int32_t length) const; + + /** + * Write the given byte to the port's output buffer. + * + * \note Data in the port's output buffer is written to the serial port as soon + * as possible on a FIFO basis and can not be done manually by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * EIO - Serious internal write error. + * + * \param buffer + * The byte to write + * + * \return The number of bytes written or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Serial serial(1); + * serial.write_byte(0x01); + * } + * \endcode + */ + virtual std::int32_t write_byte(std::uint8_t buffer) const; + + /** + * Writes up to length bytes from the user supplied buffer to the port's output + * buffer. + * + * \note Data in the port's output buffer is written to the serial port as soon + * as possible on a FIFO basis and can not be done manually by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * EIO - Serious internal write error. + * + * \param buffer + * The data to write + * \param length + * The maximum number of bytes to write + * + * \return The number of bytes written or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code + * void opcontrol() { + * pros::Serial serial(1); + * std::uint8_t buffer[10]; + * serial.write(buffer, 10); + * } + * \endcode + */ + virtual std::int32_t write(std::uint8_t* buffer, std::int32_t length) const; + + private: + ///@} +}; + +namespace literals { +/** + * Constructs a Serial device from a litteral ending in _ser + * + * \return a pros::Serial for the corresponding port + * + * \b Example + * \code + * using namespace pros::literals; + * void opcontrol() { + * pros::Serial serial = 2_ser; //Makes an Serial device object on port 2 + * } + * \endcode + */ +const pros::Serial operator""_ser(const unsigned long long int m); +} // namespace literals +} // namespace pros +#endif // _PROS_SERIAL_HPP_ diff --git a/test/include/pros/version.h b/test/include/pros/version.h new file mode 100644 index 00000000..cc4887cc --- /dev/null +++ b/test/include/pros/version.h @@ -0,0 +1,23 @@ +/** +* \file version.h +* +* PROS Version Information +* +* Contains PROS kernel version information +* +* +* \copyright Copyright (c) 2017-2024, Purdue University ACM SIGBots. +* All rights reserved. +* +* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#pragma once + +#define PROS_VERSION_MAJOR 4 +#define PROS_VERSION_MINOR 2 + +#define PROS_VERSION_PATCH 2 +#define PROS_VERSION_STRING "4.2.2" diff --git a/test/include/pros/vision.h b/test/include/pros/vision.h new file mode 100644 index 00000000..6b3f104c --- /dev/null +++ b/test/include/pros/vision.h @@ -0,0 +1,851 @@ +/** + * \file pros/vision.h + * \ingroup c-vision + * + * Contains prototypes for the VEX Vision Sensor-related functions. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-vision Vision Sensor C API + * \note Additional example code for this module can be found in its [Tutorial.](@ref vision) + */ + +#ifndef _PROS_VISION_H_ +#define _PROS_VISION_H_ + +/** + * \ingroup c-vision + */ + +/** + * \addtogroup c-vision + * @{ + */ + +/// \name Macros +///Parameters given by VEX +///@{ + +#define VISION_OBJECT_ERR_SIG 255 + +/** + * The width of the Vision Sensor’s field of view. + */ +#define VISION_FOV_WIDTH 316 + +/** + * The height of the Vision Sensor’s field of view. + */ +#define VISION_FOV_HEIGHT 212 + +///@} + +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \enum vision_object_type_e_t + * This enumeration defines the different types of objects that can be detected by the Vision Sensor + */ +typedef enum vision_object_type { + E_VISION_OBJECT_NORMAL = 0, + E_VISION_OBJECT_COLOR_CODE = 1, + E_VISION_OBJECT_LINE = 2 +} vision_object_type_e_t; + +/** + * \struct vision_signature_s_t + * This structure contains the parameters used by the Vision Sensor to detect objects. + */ +typedef struct __attribute__((__packed__)) vision_signature { + uint8_t id; + uint8_t _pad[3]; + float range; + int32_t u_min; + int32_t u_max; + int32_t u_mean; + int32_t v_min; + int32_t v_max; + int32_t v_mean; + uint32_t rgb; + uint32_t type; +} vision_signature_s_t; + +/** + * \typedef vision_color_code_t + * Color codes are just signatures with multiple IDs and a different type. + */ +typedef uint16_t vision_color_code_t; + +/** + * \struct vision_object_s_t + * This structure contains a descriptor of an object detected by the Vision Sensor + */ +typedef struct __attribute__((__packed__)) vision_object { + /// Object signature + uint16_t signature; + /// Object type, e.g. normal, color code, or line detection + vision_object_type_e_t type; + /// Left boundary coordinate of the object + int16_t left_coord; + /// Top boundary coordinate of the object + int16_t top_coord; + /// Width of the object + int16_t width; + /// Height of the object + int16_t height; + /// Angle of a color code object in 0.1 degree units (e.g. 10 -> 1 degree, 155 -> 15.5 degrees) + uint16_t angle; + /// Coordinates of the middle of the object (computed from the values above) + int16_t x_middle_coord; + /// Coordinates of the middle of the object (computed from the values above) + int16_t y_middle_coord; +} vision_object_s_t; + +/** + * \enum vision_zero + * This enumeration defines different zero points for returned vision objects. + */ +typedef enum vision_zero { + /// (0,0) coordinate is the top left of the FOV + E_VISION_ZERO_TOPLEFT = 0, + /// (0,0) coordinate is the center of the FOV + E_VISION_ZERO_CENTER = 1 +} vision_zero_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define VISION_OBJECT_NORMAL pros::E_VISION_OBJECT_NORMAL +#define VISION_OBJECT_COLOR_CODE pros::E_VISION_OBJECT_COLOR_CODE +#define VISION_OBJECT_LINE pros::E_VISION_OBJECT_LINE +#define VISION_ZERO_TOPLEFT pros::E_VISION_ZERO_TOPLEFT +#define VISION_ZERO_CENTER pros::E_VISION_ZERO_CENTER +#else +#define VISION_OBJECT_NORMAL E_VISION_OBJECT_NORMAL +#define VISION_OBJECT_COLOR_CODE E_VISION_OBJECT_COLOR_CODE +#define VISION_OBJECT_LINE E_VISION_OBJECT_LINE +#define VISION_ZERO_TOPLEFT E_VISION_ZERO_TOPLEFT +#define VISION_ZERO_CENTER E_VISION_ZERO_CENTER +#endif +#endif + +#ifdef __cplusplus +namespace c { +#endif + +/// \name Functions +///@{ + +/** + * Clears the vision sensor LED color, reseting it back to its default behavior, + * displaying the most prominent object signature color. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * void initialize() { + * vision_clear_led(VISION_PORT); + * } + * \endcode + */ +int32_t vision_clear_led(uint8_t port); + +/** + * Creates a signature from the vision sensor utility + * + * \param id + * The signature ID + * \param u_min + * Minimum value on U axis + * \param u_max + * Maximum value on U axis + * \param u_mean + * Mean value on U axis + * \param v_min + * Minimum value on V axis + * \param v_max + * Maximum value on V axis + * \param v_mean + * Mean value on V axis + * \param range + * Scale factor + * \param type + * Signature type + * + * \return A vision_signature_s_t that can be set using vision_set_signature + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * // values acquired from the vision utility + * vision_signature_s_t RED_SIG = + * vision_signature_from_utility(EXAMPLE_SIG, 8973, 11143, 10058, -2119, -1053, -1586, 5.4, 0); + * vision_set_signature(VISION_PORT, EXAMPLE_SIG, &RED_SIG); + * while (true) { + * vision_signature_s_t rtn = vision_get_by_sig(VISION_PORT, 0, EXAMPLE_SIG); + * // Gets the largest object of the EXAMPLE_SIG signature + * printf("sig: %d", rtn.signature); + * // Prints "sig: 1" + * delay(2); + * } + * } + * \endcode + */ +vision_signature_s_t vision_signature_from_utility(const int32_t id, const int32_t u_min, const int32_t u_max, + const int32_t u_mean, const int32_t v_min, const int32_t v_max, + const int32_t v_mean, const float range, const int32_t type); + +/** + * Creates a color code that represents a combination of the given signature + * IDs. If fewer than 5 signatures are to be a part of the color code, pass 0 + * for the additional function parameters. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - Fewer than two signatures have been provided or one of the + * signatures is out of its [1-7] range (or 0 when omitted). + * + * \param port + * The V5 port number from 1-21 + * \param sig_id1 + * The first signature id [1-7] to add to the color code + * \param sig_id2 + * The second signature id [1-7] to add to the color code + * \param sig_id3 + * The third signature id [1-7] to add to the color code + * \param sig_id4 + * The fourth signature id [1-7] to add to the color code + * \param sig_id5 + * The fifth signature id [1-7] to add to the color code + * + * \return A vision_color_code_t object containing the color code information. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define OTHER_SIG 2 + * + * void opcontrol() { + * vision_color_code_t code1 = vision_create_color_code(VISION_PORT, EXAMPLE_SIG, OTHER_SIG); + * } + * \endcode + */ +vision_color_code_t vision_create_color_code(uint8_t port, const uint32_t sig_id1, const uint32_t sig_id2, + const uint32_t sig_id3, const uint32_t sig_id4, const uint32_t sig_id5); + +/** + * Gets the nth largest object according to size_id. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * EDOM - size_id is greater than the number of available objects. + * EHOSTDOWN - Reading the vision sensor failed for an unknown reason. + * + * \param port + * The V5 port number from 1-21 + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * + * \return The vision_object_s_t object corresponding to the given size id, or + * PROS_ERR if an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void opcontrol() { + * while (true) { + * vision_object_s_t rtn = vision_get_by_size(VISION_PORT, 0); + * // Gets the largest object + * printf("sig: %d", rtn.signature); + * delay(2); + * } + * } + * \endcode + */ +vision_object_s_t vision_get_by_size(uint8_t port, const uint32_t size_id); + +/** + * Gets the nth largest object of the given signature according to size_id. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * EINVAL - sig_id is outside the range [1-8] + * EDOM - size_id is greater than the number of available objects. + * EAGAIN - Reading the vision sensor failed for an unknown reason. + * + * \param port + * The V5 port number from 1-21 + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param signature + * The signature ID [1-7] for which an object will be returned. + * + * \return The vision_object_s_t object corresponding to the given signature and + * size_id, or PROS_ERR if an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * while (true) { + * vision_object_s_t rtn = vision_get_by_sig(VISION_PORT, 0, EXAMPLE_SIG); + * // Gets the largest object of the EXAMPLE_SIG signature + * printf("sig: %d", rtn.signature); + * // Prints "sig: 1" + * delay(2); + * } + * } + * \endcode + */ +vision_object_s_t vision_get_by_sig(uint8_t port, const uint32_t size_id, const uint32_t sig_id); + +/** + * Gets the nth largest object of the given color code according to size_id. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * EAGAIN - Reading the vision sensor failed for an unknown reason. + * + * \param port + * The V5 port number from 1-21 + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param color_code + * The vision_color_code_t for which an object will be returned + * + * \return The vision_object_s_t object corresponding to the given color code + * and size_id, or PROS_ERR if an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define OTHER_SIG 2 + * + * void opcontrol() { + * vision_color_code_t code1 = vision_create_color_code(VISION_PORT, EXAMPLE_SIG, OTHER_SIG); + * while (true) { + * vision_object_s_t rtn = vision_get_by_code(VISION_PORT, 0, code1); + * // Gets the largest object + * printf("sig: %d", rtn.signature); + * delay(2); + * } + * } + * \endcode + */ +vision_object_s_t vision_get_by_code(uint8_t port, const uint32_t size_id, const vision_color_code_t color_code); + +/** + * Gets the exposure parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * + * \return The current exposure setting from [0,150], PROS_ERR if an error + * occurred + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * if (vision_get_exposure(VISION_PORT) < 50) + * vision_set_exposure(VISION_PORT, 50); + * } + * \endcode + */ +int32_t vision_get_exposure(uint8_t port); + +/** + * Gets the number of objects currently detected by the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * + * \return The number of objects detected on the specified vision sensor. + * Returns PROS_ERR if the port was invalid or an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Number of Objects Detected: %d\n", vision_get_object_count(VISION_PORT)); + * delay(2); + * } + * } + * \endcode + */ +int32_t vision_get_object_count(uint8_t port); + +/** + * Get the white balance parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * + * \return The current RGB white balance setting of the sensor + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define VISION_WHITE 0xff + * + * void initialize() { + * if (vision_get_white_balance(VISION_PORT) != VISION_WHITE) + * vision_set_white_balance(VISION_PORT, VISION_WHITE); + * } + * \endcode + */ +int32_t vision_get_white_balance(uint8_t port); + +/** + * Prints the contents of the signature as an initializer list to the terminal. + * + * \param sig + * The signature for which the contents will be printed + * + * \return 1 if no errors occured, PROS_ERR otherwise + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * vision_signature_s_t sig = vision_get_signature(VISION_PORT, EXAMPLE_SIG); + * vision_print_signature(sig); + * } + * \endcode + */ +int32_t vision_print_signature(const vision_signature_s_t sig); + +/** + * Reads up to object_count object descriptors into object_arr. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21), or + * fewer than object_count number of objects were found. + * ENODEV - The port cannot be configured as a vision sensor + * EDOM - size_id is greater than the number of available objects. + * + * \param port + * The V5 port number from 1-21 + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param object_count + * The number of objects to read + * \param[out] object_arr + * A pointer to copy the objects into + * + * \return The number of object signatures copied. This number will be less than + * object_count if there are fewer objects detected by the vision sensor. + * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects + * than size_id were found. All objects in object_arr that were not found are + * given VISION_OBJECT_ERR_SIG as their signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define NUM_VISION_OBJECTS 4 + * + * void opcontrol() { + * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; + * while (true) { + * vision_read_by_size(VISION_PORT, 0, NUM_VISION_OBJECTS, object_arr); + * printf("sig: %d", object_arr[0].signature); + * // Prints the signature of the largest object found + * delay(2); + * } + * } + * \endcode + */ +int32_t vision_read_by_size(uint8_t port, const uint32_t size_id, const uint32_t object_count, + vision_object_s_t* const object_arr); + +/** + * Reads up to object_count object descriptors into object_arr. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21), or + * fewer than object_count number of objects were found. + * ENODEV - The port cannot be configured as a vision sensor + * EDOM - size_id is greater than the number of available objects. + * + * \param port + * The V5 port number from 1-21 + * \param object_count + * The number of objects to read + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param signature + * The signature ID [1-7] for which objects will be returned. + * \param[out] object_arr + * A pointer to copy the objects into + * + * \return The number of object signatures copied. This number will be less than + * object_count if there are fewer objects detected by the vision sensor. + * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects + * than size_id were found. All objects in object_arr that were not found are + * given VISION_OBJECT_ERR_SIG as their signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define NUM_VISION_OBJECTS 4 + * + * void opcontrol() { + * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; + * while (true) { + * vision_read_by_sig(VISION_PORT, 0, EXAMPLE_SIG, NUM_VISION_OBJECTS, object_arr); + * printf("sig: %d", object_arr[0].signature); + * // Prints "sig: 1" + * delay(2); + * } + * } + * \endcode + */ +int32_t vision_read_by_sig(uint8_t port, const uint32_t size_id, const uint32_t sig_id, const uint32_t object_count, + vision_object_s_t* const object_arr); + +/** + * Reads up to object_count object descriptors into object_arr. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21), or + * fewer than object_count number of objects were found. + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param object_count + * The number of objects to read + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param color_code + * The vision_color_code_t for which objects will be returned + * \param[out] object_arr + * A pointer to copy the objects into + * + * \return The number of object signatures copied. This number will be less than + * object_count if there are fewer objects detected by the vision sensor. + * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects + * than size_id were found. All objects in object_arr that were not found are + * given VISION_OBJECT_ERR_SIG as their signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define OTHER_SIG 2 + * #define NUM_VISION_OBJECTS 4 + * + * void opcontrol() { + * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; + * vision_color_code_t code1 = vision_create_color_code(VISION_PORT, EXAMPLE_SIG, OTHER_SIG, 0, 0, 0); + * while (true) { + * vision_read_by_code(VISION_PORT, 0, code1, NUM_VISION_OBJECTS, object_arr); + * printf("sig: %d", object_arr[0].signature); + * // Prints the signature of the largest object found + * delay(2); + * } + * } + * \endcode + */ +int32_t vision_read_by_code(uint8_t port, const uint32_t size_id, const vision_color_code_t color_code, + const uint32_t object_count, vision_object_s_t* const object_arr); + +/** + * Gets the object detection signature with the given id number. + * + * \param port + * The V5 port number from 1-21 + * \param signature_id + * The signature id to read + * + * \return A vision_signature_s_t containing information about the signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * vision_signature_s_t sig = vision_get_signature(VISION_PORT, EXAMPLE_SIG); + * vision_print_signature(sig); + * } + * \endcode + */ +vision_signature_s_t vision_get_signature(uint8_t port, const uint8_t signature_id); + +/** + * Stores the supplied object detection signature onto the vision sensor. + * + * \note This saves the signature in volatile memory, and the signature will be + * lost as soon as the sensor is powered down. + * + * \param port + * The V5 port number from 1-21 + * \param signature_id + * The signature id to store into + * \param[in] signature_ptr + * A pointer to the signature to save + * + * \return 1 if no errors occured, PROS_ERR otherwise + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * vision_signature_s_t sig = vision_get_signature(VISION_PORT, EXAMPLE_SIG); + * sig.range = 10.0; + * vision_set_signature(VISION_PORT, EXAMPLE_SIG, &sig); + * } + * \endcode + */ +int32_t vision_set_signature(uint8_t port, const uint8_t signature_id, vision_signature_s_t* const signature_ptr); + +/** + * Enables/disables auto white-balancing on the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * EINVAL - enable was not 0 or 1 + * + * \param port + * The V5 port number from 1-21 + * \param enabled + * Pass 0 to disable, 1 to enable + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * vision_set_auto_white_balance(VISION_PORT, true); + * } + * \endcode + */ +int32_t vision_set_auto_white_balance(uint8_t port, const uint8_t enable); + +/** + * Sets the exposure parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param percent + * The new exposure setting from [0,150] + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * if (vision_get_exposure(VISION_PORT) < 50) + * vision_set_exposure(VISION_PORT, 50); + * } + * \endcode + */ +int32_t vision_set_exposure(uint8_t port, const uint8_t exposure); + +/** + * Sets the vision sensor LED color, overriding the automatic behavior. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param rgb + * An RGB code to set the LED to + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * vision_set_led(VISION_PORT, COLOR_BLANCHED_ALMOND); + * } + * \endcode + */ +int32_t vision_set_led(uint8_t port, const int32_t rgb); + +/** + * Sets the white balance parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param rgb + * The new RGB white balance setting of the sensor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define VISION_WHITE 0xff + * + * void initialize() { + * vision_set_white_balance(VISION_PORT, VISION_WHITE); + * } + * \endcode + */ +int32_t vision_set_white_balance(uint8_t port, const int32_t rgb); + +/** + * Sets the (0,0) coordinate for the Field of View. + * + * This will affect the coordinates returned for each request for a + * vision_object_s_t from the sensor, so it is recommended that this function + * only be used to configure the sensor at the beginning of its use. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param zero_point + * One of vision_zero_e_t to set the (0,0) coordinate for the FOV + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * vision_set_zero_point(VISION_PORT, E_VISION_ZERO_CENTER); + * } + * \endcode + */ +int32_t vision_set_zero_point(uint8_t port, vision_zero_e_t zero_point); + +/** + * Sets the Wi-Fi mode of the Vision sensor + * + * This functions uses the following values of errno when an error state is + * reached: + * ENXIO - The given port is not within the range of V5 ports (1-21) + * EACCESS - Anothe resources is currently trying to access the port + * + * \param port + * The V5 port number from 1-21 + * \param enable + * Disable Wi-Fi on the Vision sensor if 0, enable otherwise (e.g. 1) + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * vision_set_wifi_mode(VISION_PORT, 0); + * } + * \endcode + */ +int32_t vision_set_wifi_mode(uint8_t port, const uint8_t enable); + +///@} + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_VISION_H_ diff --git a/test/include/pros/vision.hpp b/test/include/pros/vision.hpp new file mode 100644 index 00000000..06d858ff --- /dev/null +++ b/test/include/pros/vision.hpp @@ -0,0 +1,787 @@ +/** + * \file pros/vision.hpp + * \ingroup cpp-vision + * + * Contains prototypes for the VEX Vision Sensor-related functions in C++. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2024, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-vision Vision Sensor C++ API + * \note Additional example code for this module can be found in its [Tutorial.](@ref vision) + */ + +#ifndef _PROS_VISION_HPP_ +#define _PROS_VISION_HPP_ + +#include + +#include "pros/device.hpp" +#include "pros/vision.h" + +namespace pros { +inline namespace v5 { +/** + * \ingroup cpp-vision + */ +class Vision : public Device { + /** + * \addtogroup cpp-vision + * @{ + */ + public: + /** + * Create a Vision Sensor object on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param zero_point + * One of vision_zero_e_t to set the (0,0) coordinate for the FOV + * + * \b Example + * \code + * void opcontrol() { + * pros::Vision vision_sensor(1); // Creates a vision sensor on port one, with the zero point set to top left + * } + * \endcode + */ + Vision(std::uint8_t port, vision_zero_e_t zero_point = E_VISION_ZERO_TOPLEFT); + + Vision(const Device& device) : Vision(device.get_port()){}; + + /** + * Clears the vision sensor LED color, reseting it back to its default + * behavior, displaying the most prominent object signature color. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Vision vision_sensor(1); + * vision_sensor.clear_led(); + * } + * \endcode + */ + std::int32_t clear_led(void) const; + + /** + * Creates a signature from the vision sensor utility + * + * \param id + * The signature ID + * \param u_min + * Minimum value on U axis + * \param u_max + * Maximum value on U axis + * \param u_mean + * Mean value on U axis + * \param v_min + * Minimum value on V axis + * \param v_max + * Maximum value on V axis + * \param v_mean + * Mean value on V axis + * \param rgb + * Scale factor + * \param type + * Signature type + * + * \return A vision_signature_s_t that can be set using Vision::set_signature + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * // values acquired from the vision utility + * vision_signature_s_t RED_SIG = + * vision_signature_from_utility(EXAMPLE_SIG, 8973, 11143, 10058, -2119, -1053, -1586, 5.4, 0); + * vision_sensor.set_signature(EXAMPLE_SIG, &RED_SIG); + * while (true) { + * vision_signature_s_t rtn = vision_sensor.get_by_sig(VISION_PORT, 0, EXAMPLE_SIG); + * // Gets the largest object of the EXAMPLE_SIG signature + * printf("sig: %d", rtn.signature); + * // Prints "sig: 1" + * delay(2); + * } + * } + * \endcode + */ + static vision_signature_s_t signature_from_utility(const std::int32_t id, const std::int32_t u_min, + const std::int32_t u_max, const std::int32_t u_mean, + const std::int32_t v_min, const std::int32_t v_max, + const std::int32_t v_mean, const float range, + const std::int32_t type); + + /** + * Creates a color code that represents a combination of the given signature + * IDs. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - Fewer than two signatures have been provided or one of the + * signatures is out of its [1-7] range (or 0 when omitted). + * + * \param sig_id1 + * The first signature id [1-7] to add to the color code + * \param sig_id2 + * The second signature id [1-7] to add to the color code + * \param sig_id3 + * The third signature id [1-7] to add to the color code + * \param sig_id4 + * The fourth signature id [1-7] to add to the color code + * \param sig_id5 + * The fifth signature id [1-7] to add to the color code + * + * \return A vision_color_code_t object containing the color code information. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define OTHER_SIG 2 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_color_code_t code1 = vision_sensor.create_color_code(EXAMPLE_SIG, OTHER_SIG); + * } + * \endcode + */ + vision_color_code_t create_color_code(const std::uint32_t sig_id1, const std::uint32_t sig_id2, + const std::uint32_t sig_id3 = 0, const std::uint32_t sig_id4 = 0, + const std::uint32_t sig_id5 = 0) const; + + /** + * Gets all vision sensors. + * + * \return A vector of Vision sensor objects. + * + * \b Example + * \code + * void opcontrol() { + * std::vector vision_all = pros::Vision::get_all_devices(); // All vision sensors that are connected + * } + * \endcode + */ + static std::vector get_all_devices(); + + /** + * Gets the nth largest object according to size_id. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * EDOM - size_id is greater than the number of available objects. + * EAGAIN - Reading the vision sensor failed for an unknown reason. + * + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * + * \return The vision_object_s_t object corresponding to the given size id, or + * PROS_ERR if an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * while (true) { + * vision_object_s_t rtn = vision_sensor.get_by_size(0); + * // Gets the largest object + * printf("sig: %d", rtn.signature); + * delay(2); + * } + * } + * \endcode + */ + vision_object_s_t get_by_size(const std::uint32_t size_id) const; + + /** + * Gets the nth largest object of the given signature according to size_id. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * EDOM - size_id is greater than the number of available objects. + * EINVAL - sig_id is outside the range [1-8] + * EAGAIN - Reading the vision sensor failed for an unknown reason. + * + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param signature + * The vision_signature_s_t signature for which an object will be + * returned. + * + * \return The vision_object_s_t object corresponding to the given signature + * and size_id, or PROS_ERR if an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * while (true) { + * vision_object_s_t rtn = vision_sensor.get_by_sig(0, EXAMPLE_SIG); + * // Gets the largest object of the EXAMPLE_SIG signature + * printf("sig: %d", rtn.signature); + * // Prints "sig: 1" + * delay(2); + * } + * } + * \endcode + */ + vision_object_s_t get_by_sig(const std::uint32_t size_id, const std::uint32_t sig_id) const; + + /** + * Gets the nth largest object of the given color code according to size_id. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * EAGAIN - Reading the Vision Sensor failed for an unknown reason. + * + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param color_code + * The vision_color_code_t for which an object will be returned + * + * \return The vision_object_s_t object corresponding to the given color code + * and size_id, or PROS_ERR if an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define OTHER_SIG 2 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_color_code_t code1 = vision_sensor.create_color_code(EXAMPLE_SIG, OTHER_SIG); + * while (true) { + * vision_object_s_t rtn = vision_sensor.get_by_code(0, code1); + * // Gets the largest object + * printf("sig: %d", rtn.signature); + * delay(2); + * } + * } + * \endcode + */ + vision_object_s_t get_by_code(const std::uint32_t size_id, const vision_color_code_t color_code) const; + + /** + * Gets the exposure parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \return The current exposure parameter from [0,150], + * PROS_ERR if an error occurred + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * pros::Vision vision_sensor(VISION_PORT); + * if (vision_sensor.get_exposure() < 50) + * vision_sensor.set_exposure(50); + * } + * \endcode + */ + std::int32_t get_exposure(void) const; + + /** + * Gets the number of objects currently detected by the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \return The number of objects detected on the specified vision sensor. + * Returns PROS_ERR if the port was invalid or an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * while (true) { + * printf("Number of Objects Detected: %d\n", vision_sensor.get_object_count()); + * delay(2); + * } + * } + * \endcode + */ + std::int32_t get_object_count(void) const; + + /** + * Gets the object detection signature with the given id number. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \param signature_id + * The signature id to read + * + * \return A vision_signature_s_t containing information about the signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_signature_s_t sig = vision_sensor.get_signature(EXAMPLE_SIG); + * vision_sensor.print_signature(sig); + * } + * \endcode + */ + vision_signature_s_t get_signature(const std::uint8_t signature_id) const; + + /** + * Get the white balance parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \return The current RGB white balance setting of the sensor + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define VISION_WHITE 0xff + * + * void initialize() { + * pros::Vision vision_sensor(VISION_PORT); + * if (vision_sensor.get_white_balance() != VISION_WHITE) + * vision_sensor.set_white_balance(VISION_WHITE); + * } + * \endcode + */ + std::int32_t get_white_balance(void) const; + + /** + * Reads up to object_count object descriptors into object_arr. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * EDOM - size_id is greater than the number of available objects. + * EAGAIN - Reading the vision sensor failed for an unknown reason. + * + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param object_count + * The number of objects to read + * \param[out] object_arr + * A pointer to copy the objects into + * + * \return The number of object signatures copied. This number will be less than + * object_count if there are fewer objects detected by the vision sensor. + * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects + * than size_id were found. All objects in object_arr that were not found are + * given VISION_OBJECT_ERR_SIG as their signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define NUM_VISION_OBJECTS 4 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; + * while (true) { + * vision_sensor.read_by_size(0, NUM_VISION_OBJECTS, object_arr); + * printf("sig: %d", object_arr[0].signature); + * // Prints the signature of the largest object found + * delay(2); + * } + * } + * \endcode + */ + std::int32_t read_by_size(const std::uint32_t size_id, const std::uint32_t object_count, + vision_object_s_t* const object_arr) const; + + /** + * Reads up to object_count object descriptors into object_arr. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * EDOM - size_id is greater than the number of available objects. + * EINVAL - sig_id is outside the range [1-8] + * EAGAIN - Reading the vision sensor failed for an unknown reason. + * + * \param object_count + * The number of objects to read + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param signature + * The vision_signature_s_t signature for which an object will be + * returned. + * \param[out] object_arr + * A pointer to copy the objects into + * + * \return The number of object signatures copied. This number will be less than + * object_count if there are fewer objects detected by the vision sensor. + * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects + * than size_id were found. All objects in object_arr that were not found are + * given VISION_OBJECT_ERR_SIG as their signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define NUM_VISION_OBJECTS 4 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; + * while (true) { + * vision_sensor.read_by_sig(0, EXAMPLE_SIG, NUM_VISION_OBJECTS, object_arr); + * printf("sig: %d", object_arr[0].signature); + * // Prints "sig: 1" + * delay(2); + * } + * } + * \endcode + */ + std::int32_t read_by_sig(const std::uint32_t size_id, const std::uint32_t sig_id, const std::uint32_t object_count, + vision_object_s_t* const object_arr) const; + + /** + * Reads up to object_count object descriptors into object_arr. + * + * This function uses the following values of errno when an error state is + * reached: + * EDOM - size_id is greater than the number of available objects. + * ENODEV - The port cannot be configured as a vision sensor + * EAGAIN - Reading the vision sensor failed for an unknown reason. + * + * \param object_count + * The number of objects to read + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param color_code + * The vision_color_code_t for which objects will be returned + * \param[out] object_arr + * A pointer to copy the objects into + * + * \return The number of object signatures copied. This number will be less than + * object_count if there are fewer objects detected by the vision sensor. + * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects + * than size_id were found. All objects in object_arr that were not found are + * given VISION_OBJECT_ERR_SIG as their signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define OTHER_SIG 2 + * #define NUM_VISION_OBJECTS 4 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; + * vision_color_code_t code1 = vision_sensor.create_color_code(EXAMPLE_SIG, OTHER_SIG, 0, 0, 0); + * while (true) { + * vision_sensor.read_by_code(0, code1, NUM_VISION_OBJECTS, object_arr); + * printf("sig: %d", object_arr[0].signature); + * // Prints the signature of the largest object found + * delay(2); + * } + * } + * \endcode + */ + int32_t read_by_code(const std::uint32_t size_id, const vision_color_code_t color_code, + const std::uint32_t object_count, vision_object_s_t* const object_arr) const; + + /** + * Prints the contents of the signature as an initializer list to the terminal. + * + * \param sig + * The signature for which the contents will be printed + * + * \return 1 if no errors occured, PROS_ERR otherwise + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_signature_s_t sig = visionsensor.get_signature(EXAMPLE_SIG); + * vision_print_signature(sig); + * } + * \endcode + */ + static std::int32_t print_signature(const vision_signature_s_t sig); + + /** + * Enables/disables auto white-balancing on the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \param enabled + * Pass 0 to disable, 1 to enable + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_sensor.set_auto_white_balance(true); + * } + * \endcode + */ + std::int32_t set_auto_white_balance(const std::uint8_t enable) const; + + /** + * Sets the exposure parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \param percent + * The new exposure setting from [0,150]. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * pros::Vision vision_sensor(VISION_PORT); + * if (vision_sensor.get_exposure() < 50) + * vision_sensor.set_exposure(50); + * } + * \endcode + */ + std::int32_t set_exposure(const std::uint8_t exposure) const; + + /** + * Sets the vision sensor LED color, overriding the automatic behavior. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \param rgb + * An RGB code to set the LED to + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_sensor.set_led(COLOR_BLANCHED_ALMOND); + * } + * \endcode + */ + std::int32_t set_led(const std::int32_t rgb) const; + + /** + * Stores the supplied object detection signature onto the vision sensor. + * + * NOTE: This saves the signature in volatile memory, and the signature will be + * lost as soon as the sensor is powered down. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * EINVAL - sig_id is outside the range [1-8] + * + * \param signature_id + * The signature id to store into + * \param[in] signature_ptr + * A pointer to the signature to save + * + * \return 1 if no errors occured, PROS_ERR otherwise + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_signature_s_t sig = vision_sensor.get_signature(EXAMPLE_SIG); + * sig.range = 10.0; + * vision_sensor.set_signature(EXAMPLE_SIG, &sig); + * } + * \endcode + */ + std::int32_t set_signature(const std::uint8_t signature_id, vision_signature_s_t* const signature_ptr) const; + + /** + * Sets the white balance parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \param rgb + * The new RGB white balance setting of the sensor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define VISION_WHITE 0xff + * + * void initialize() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_sensor.set_white_balance(VISION_WHITE); + * } + * \endcode + */ + std::int32_t set_white_balance(const std::int32_t rgb) const; + + /** + * Sets the (0,0) coordinate for the Field of View. + * + * This will affect the coordinates returned for each request for a + * vision_object_s_t from the sensor, so it is recommended that this function + * only be used to configure the sensor at the beginning of its use. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \param zero_point + * One of vision_zero_e_t to set the (0,0) coordinate for the FOV + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_sensor.set_zero_point(E_VISION_ZERO_CENTER); + * } + * \endcode + */ + std::int32_t set_zero_point(vision_zero_e_t zero_point) const; + + /** + * Sets the Wi-Fi mode of the Vision sensor + * + * This functions uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a vision sensor + * + * \param enable + * Disable Wi-Fi on the Vision sensor if 0, enable otherwise (e.g. 1) + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * pros::Vision vision_sensor(VISION_PORT); + * vision_sensor.set_wifi_mode(0); + * } + * \endcode + */ + std::int32_t set_wifi_mode(const std::uint8_t enable) const; + + /** + * Gets a vision sensor that is plugged in to the brain + * + * \note The first time this function is called it returns the vision sensor at the lowest port + * If this function is called multiple times, it will cycle through all the ports. + * For example, if you have 1 vision sensor on the robot + * this function will always return a vision sensor object for that port. + * If you have 2 vision sensors, all the odd numered calls to this function will return objects + * for the lower port number, + * all the even number calls will return vision objects for the higher port number + * + * + * This functions uses the following values of errno when an error state is + * reached: + * ENODEV - No vision sensor is plugged into the brain + * + * \return A vision object corresponding to a port that a vision sensor is connected to the brain + * If no vision sensor is plugged in, it returns a vision sensor on port PROS_ERR_BYTE + * + */ + static Vision get_vision(); + + private: + ///@} +}; +} // namespace v5 +namespace literals { +/** + * Constructs a Vision sensor from a litteral ending in _vis + * + * \return a pros::Vision for the corresponding port + * + * \b Example + * \code + * using namespace pros::literals; + * void opcontrol() { + * pros::Vision vision = 2_vis; //Makes an Vision sensor object on port 2 + * } + * \endcode + */ +const pros::Vision operator""_vis(const unsigned long long int m); +} // namespace literals +} // namespace pros +#endif // _PROS_VISION_HPP_ diff --git a/test/project.pros b/test/project.pros new file mode 100644 index 00000000..47e53f8b --- /dev/null +++ b/test/project.pros @@ -0,0 +1,597 @@ +{ + "py/object": "pros.conductor.project.Project", + "py/state": { + "project_name": "test", + "target": "v5", + "templates": { + "kernel": { + "location": "/Users/ronilmitra/Library/Application Support/PROS/templates/kernel@4.2.2", + "metadata": { + "cold_addr": "58720256", + "cold_output": "bin/cold.package.bin", + "hot_addr": "125829120", + "hot_output": "bin/hot.package.bin", + "origin": "pros-mainline", + "output": "bin/monolith.bin" + }, + "name": "kernel", + "py/object": "pros.conductor.templates.local_template.LocalTemplate", + "supported_kernels": null, + "system_files": [ + "common.mk", + "include/pros/device.hpp", + "include/pros/colors.h", + "include/pros/link.hpp", + "include/pros/vision.hpp", + "include/pros/screen.h", + "include/pros/rotation.hpp", + "include/pros/rtos.h", + "firmware/libpros.a", + "include/pros/rotation.h", + "include/pros/ai_vision.h", + "include/pros/imu.hpp", + "include/pros/motor_group.hpp", + "include/pros/misc.hpp", + "include/pros/device.h", + "include/pros/optical.h", + "include/pros/abstract_motor.hpp", + "include/pros/version.h", + "include/pros/serial.hpp", + "firmware/libc.a", + "include/pros/ai_vision.hpp", + "include/pros/error.h", + "include/pros/gps.h", + "include/pros/apix.h", + "include/pros/misc.h", + "include/pros/llemu.h", + "include/pros/rtos.hpp", + "include/pros/motors.h", + "include/pros/vision.h", + "firmware/v5-common.ld", + "include/pros/adi.hpp", + "include/pros/motors.hpp", + "include/pros/distance.hpp", + "include/pros/screen.hpp", + "include/pros/adi.h", + "include/api.h", + "firmware/v5-hot.ld", + "firmware/libm.a", + "include/pros/distance.h", + "include/pros/imu.h", + "include/pros/llemu.hpp", + "include/pros/serial.h", + "include/pros/colors.hpp", + "firmware/v5.ld", + "include/pros/ext_adi.h", + "include/pros/optical.hpp", + "include/pros/gps.hpp", + "include/pros/link.h" + ], + "target": "v5", + "user_files": [ + "src/main.c", + ".gitignore", + "src/main.cpp", + "include/main.hh", + "src/main.cc", + "include/main.hpp", + "include/main.h", + "Makefile" + ], + "version": "4.2.2" + }, + "liblvgl": { + "location": "/Users/ronilmitra/Library/Application Support/PROS/templates/liblvgl@9.2.0", + "metadata": { + "origin": "pros-mainline" + }, + "name": "liblvgl", + "py/object": "pros.conductor.templates.local_template.LocalTemplate", + "supported_kernels": ">=4.2.0", + "system_files": [ + "include/liblvgl/libs/thorvg/tvgSvgLoaderCommon.h", + "include/liblvgl/libs/thorvg/tvgText.cpp", + "include/liblvgl/libs/thorvg/rapidjson/internal/biginteger.h", + "include/liblvgl/libs/thorvg/tvgSwCommon.h", + "include/liblvgl/draw/sw/lv_draw_sw_gradient.h", + "include/liblvgl/libs/svg/lv_svg_parser.h", + "include/liblvgl/draw/lv_image_decoder.h", + "include/liblvgl/libs/thorvg/tvgGlCanvas.cpp", + "include/liblvgl/libs/libpng/lv_libpng.h", + "include/liblvgl/libs/freetype/lv_freetype.h", + "include/liblvgl/libs/thorvg/rapidjson/fwd.h", + "include/liblvgl/tick/lv_tick.h", + "include/liblvgl/drivers/windows/lv_windows_context.h", + "include/liblvgl/misc/cache/lv_cache.h", + "include/liblvgl/libs/thorvg/thorvg_lottie.h", + "include/liblvgl/others/font_manager/lv_font_manager_utils.h", + "include/liblvgl/misc/lv_lru.h", + "include/liblvgl/lv_init.h", + "include/liblvgl/libs/thorvg/tvgLottieParser.h", + "include/liblvgl/libs/thorvg/tvgIteratorAccessor.h", + "include/liblvgl/widgets/arc/lv_arc.h", + "include/liblvgl/libs/thorvg/tvgCapi.cpp", + "include/liblvgl/misc/lv_assert.h", + "include/liblvgl/libs/thorvg/tvgRender.h", + "include/liblvgl/libs/thorvg/tvgLines.cpp", + "include/liblvgl/widgets/led/lv_led_private.h", + "include/liblvgl/indev/lv_indev.h", + "include/liblvgl/widgets/image/lv_image.h", + "include/liblvgl/core/lv_group_private.h", + "include/liblvgl/drivers/qnx/lv_qnx.h", + "include/liblvgl/libs/thorvg/rapidjson/internal/ieee754.h", + "include/liblvgl/libs/thorvg/rapidjson/filereadstream.h", + "include/liblvgl/libs/tjpgd/lv_tjpgd.h", + "include/liblvgl/draw/lv_draw_triangle.h", + "include/liblvgl/widgets/tileview/lv_tileview_private.h", + "include/liblvgl/widgets/calendar/lv_calendar_chinese.h", + "include/liblvgl/misc/lv_iter.h", + "include/liblvgl/drivers/windows/lv_windows_display.h", + "include/liblvgl/draw/nxp/pxp/lv_pxp_osa.h", + "include/liblvgl/drivers/x11/lv_x11.h", + "include/liblvgl/osal/lv_os_private.h", + "include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h", + "include/liblvgl/core/lv_obj_draw.h", + "firmware/liblvgl.a", + "include/liblvgl/libs/thorvg/tvgSvgCssStyle.h", + "include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h", + "include/liblvgl/libs/qrcode/qrcodegen.h", + "include/liblvgl/misc/lv_utils.h", + "include/liblvgl/misc/lv_bidi_private.h", + "include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h", + "include/liblvgl/libs/thorvg/tvgCanvas.cpp", + "include/liblvgl/draw/sdl/lv_draw_sdl.h", + "include/liblvgl/widgets/table/lv_table_private.h", + "include/liblvgl/libs/rlottie/lv_rlottie.h", + "include/liblvgl/draw/nema_gfx/lv_draw_nema_gfx.h", + "include/liblvgl/libs/thorvg/tvgStr.h", + "include/liblvgl/widgets/calendar/lv_calendar_header_arrow.h", + "include/liblvgl/drivers/display/st7735/lv_st7735.h", + "include/liblvgl/widgets/textarea/lv_textarea.h", + "include/liblvgl/libs/thorvg/rapidjson/msinttypes/inttypes.h", + "include/liblvgl/libs/thorvg/tvgPicture.cpp", + "include/liblvgl/widgets/menu/lv_menu.h", + "include/liblvgl/osal/lv_os.h", + "include/liblvgl/widgets/slider/lv_slider.h", + "include/liblvgl/draw/renesas/dave2d/lv_draw_dave2d_utils.h", + "include/liblvgl/libs/rle/lv_rle.h", + "include/liblvgl/widgets/button/lv_button.h", + "include/liblvgl/libs/thorvg/tvgSwRasterNeon.h", + "include/liblvgl/libs/thorvg/tvgSwMemPool.cpp", + "include/liblvgl/widgets/calendar/lv_calendar.h", + "include/liblvgl/draw/sw/lv_draw_sw_mask.h", + "include/liblvgl/layouts/lv_layout.h", + "include/liblvgl/others/file_explorer/lv_file_explorer_private.h", + "include/liblvgl/stdlib/lv_mem_private.h", + "include/liblvgl/libs/thorvg/tvgSvgLoader.cpp", + "include/liblvgl/misc/lv_event.h", + "include/liblvgl/widgets/slider/lv_slider_private.h", + "include/liblvgl/libs/rlottie/lv_rlottie_private.h", + "include/liblvgl/widgets/line/lv_line.h", + "include/liblvgl/indev/lv_indev_scroll.h", + "include/liblvgl/libs/thorvg/tvgLottieExpressions.h", + "include/liblvgl/font/lv_font.h", + "include/liblvgl/widgets/imagebutton/lv_imagebutton.h", + "include/liblvgl/libs/thorvg/tvgSwMath.cpp", + "include/liblvgl/draw/lv_draw_label.h", + "include/liblvgl/draw/lv_draw_label_private.h", + "include/liblvgl/libs/svg/lv_svg_token.h", + "include/liblvgl/others/monkey/lv_monkey_private.h", + "include/liblvgl/core/lv_obj_event_private.h", + "include/liblvgl/misc/lv_event_private.h", + "include/liblvgl/widgets/calendar/lv_calendar_private.h", + "include/liblvgl/widgets/roller/lv_roller.h", + "include/liblvgl/draw/sw/arm2d/lv_draw_sw_arm2d.h", + "include/liblvgl/widgets/tileview/lv_tileview.h", + "include/liblvgl/libs/fsdrv/lv_fsdrv.h", + "include/liblvgl/drivers/sdl/lv_sdl_keyboard.h", + "include/liblvgl/indev/lv_indev_private.h", + "include/liblvgl/others/imgfont/lv_imgfont.h", + "include/liblvgl/llemu.h", + "include/liblvgl/font/lv_font_fmt_txt_private.h", + "include/liblvgl/others/snapshot/lv_snapshot.h", + "include/liblvgl/libs/thorvg/tvgSvgUtil.cpp", + "include/liblvgl/others/gridnav/lv_gridnav.h", + "include/liblvgl/libs/gif/gifdec.h", + "include/liblvgl/widgets/property/lv_style_properties.h", + "include/liblvgl/widgets/property/lv_obj_property_names.h", + "include/liblvgl/misc/lv_array.h", + "include/liblvgl/core/lv_refr.h", + "include/liblvgl/misc/lv_timer_private.h", + "include/liblvgl/libs/thorvg/tvgCompressor.cpp", + "include/liblvgl/draw/sw/blend/lv_draw_sw_blend_private.h", + "include/liblvgl/display/lv_display_private.h", + "include/liblvgl/libs/thorvg/tvgArray.h", + "include/liblvgl/libs/thorvg/tvgLottieProperty.h", + "include/liblvgl/draw/nema_gfx/lv_draw_nema_gfx_utils.h", + "include/liblvgl/widgets/keyboard/lv_keyboard_private.h", + "include/liblvgl/libs/tjpgd/tjpgd.h", + "include/liblvgl/widgets/canvas/lv_canvas.h", + "include/liblvgl/libs/thorvg/rapidjson/msinttypes/stdint.h", + "include/liblvgl/draw/vg_lite/lv_vg_lite_utils.h", + "include/liblvgl/llemu.hpp", + "include/liblvgl/widgets/label/lv_label.h", + "include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h", + "include/liblvgl/themes/default/lv_theme_default.h", + "include/liblvgl/tick/lv_tick_private.h", + "include/liblvgl/drivers/sdl/lv_sdl_mouse.h", + "include/liblvgl/libs/thorvg/tvgXmlParser.h", + "include/liblvgl/core/lv_global.h", + "include/liblvgl/libs/thorvg/tvgLottieInterpolator.cpp", + "include/liblvgl/draw/lv_draw_private.h", + "include/liblvgl/libs/thorvg/tvgFill.h", + "include/liblvgl/widgets/spinbox/lv_spinbox.h", + "include/liblvgl/lv_conf_kconfig.h", + "include/liblvgl/draw/vg_lite/lv_vg_lite_decoder.h", + "include/liblvgl/drivers/sdl/lv_sdl_mousewheel.h", + "include/liblvgl/draw/sw/lv_draw_sw_mask_private.h", + "include/liblvgl/draw/renesas/dave2d/lv_draw_dave2d.h", + "include/liblvgl/libs/thorvg/tvgSwRle.cpp", + "include/liblvgl/libs/thorvg/rapidjson/internal/meta.h", + "include/liblvgl/libs/thorvg/tvgLottieLoader.h", + "include/liblvgl/stdlib/lv_string.h", + "include/liblvgl/draw/sw/blend/neon/lv_blend_neon.h", + "include/liblvgl/misc/lv_profiler.h", + "include/liblvgl/libs/barcode/lv_barcode_private.h", + "include/liblvgl/libs/barcode/code128.h", + "include/liblvgl/misc/lv_bidi.h", + "include/liblvgl/libs/thorvg/add_lvgl_if.sh", + "include/liblvgl/draw/vg_lite/lv_draw_vg_lite.h", + "include/liblvgl/libs/thorvg/rapidjson/cursorstreamwrapper.h", + "include/liblvgl/draw/dma2d/lv_draw_dma2d.h", + "include/liblvgl/libs/thorvg/tvgInlist.h", + "include/liblvgl/drivers/sdl/lv_sdl_window.h", + "include/liblvgl/libs/thorvg/tvgLottieLoader.cpp", + "include/liblvgl/others/sysmon/lv_sysmon.h", + "include/liblvgl/drivers/nuttx/lv_nuttx_cache.h", + "include/liblvgl/widgets/buttonmatrix/lv_buttonmatrix.h", + "include/liblvgl/libs/thorvg/tvgLottieModel.h", + "include/liblvgl/misc/cache/lv_cache_lru_rb.h", + "include/liblvgl/drivers/glfw/lv_glfw_window_private.h", + "include/liblvgl/draw/lv_draw_triangle_private.h", + "include/liblvgl/draw/lv_draw_image_private.h", + "include/liblvgl/draw/vg_lite/lv_vg_lite_grad.h", + "include/liblvgl/font/lv_symbol_def.h", + "include/liblvgl/libs/thorvg/tvgLottieParserHandler.cpp", + "include/liblvgl/draw/vg_lite/lv_vg_lite_math.h", + "include/liblvgl/draw/lv_draw_buf_private.h", + "include/liblvgl/libs/gif/lv_gif.h", + "include/liblvgl/libs/thorvg/rapidjson/error/en.h", + "include/liblvgl/themes/lv_theme.h", + "include/liblvgl/libs/thorvg/rapidjson/writer.h", + "include/liblvgl/drivers/nuttx/lv_nuttx_touchscreen.h", + "include/liblvgl/core/lv_obj_property.h", + "include/liblvgl/libs/thorvg/tvgSaver.cpp", + "include/liblvgl/widgets/calendar/lv_calendar_header_dropdown.h", + "include/liblvgl/core/lv_obj_private.h", + "include/liblvgl/libs/thorvg/tvgLottieAnimation.cpp", + "include/liblvgl/misc/lv_tree.h", + "include/liblvgl/widgets/scale/lv_scale_private.h", + "include/liblvgl/draw/lv_draw_rect.h", + "include/liblvgl/libs/tjpgd/tjpgdcnf.h", + "include/liblvgl/misc/lv_rb.h", + "include/liblvgl/libs/thorvg/tvgAnimation.h", + "include/liblvgl/drivers/libinput/lv_xkb_private.h", + "include/liblvgl/libs/thorvg/tvgLottieParserHandler.h", + "include/liblvgl/libs/fsdrv/lv_fs_arduino_sd.cpp", + "include/liblvgl/core/lv_obj_style.h", + "include/liblvgl/libs/gif/lv_gif_private.h", + "include/liblvgl/draw/sw/lv_draw_sw_gradient_private.h", + "include/liblvgl/libs/thorvg/tvgStr.cpp", + "include/liblvgl/drivers/libinput/lv_libinput.h", + "include/liblvgl/libs/thorvg/rapidjson/ostreamwrapper.h", + "include/liblvgl/misc/cache/lv_cache_entry_private.h", + "include/liblvgl/lvgl.h", + "include/liblvgl/libs/thorvg/tvgFill.cpp", + "include/liblvgl/libs/freetype/arial.ttf", + "include/liblvgl/others/vg_lite_tvg/vg_lite.h", + "include/liblvgl/widgets/spinbox/lv_spinbox_private.h", + "include/liblvgl/misc/lv_math.h", + "include/liblvgl/libs/thorvg/tvgMath.cpp", + "include/liblvgl/libs/thorvg/tvgRender.cpp", + "include/liblvgl/draw/vg_lite/lv_vg_lite_stroke.h", + "include/liblvgl/widgets/dropdown/lv_dropdown_private.h", + "include/liblvgl/core/lv_obj_scroll.h", + "include/liblvgl/libs/libjpeg_turbo/lv_libjpeg_turbo.h", + "include/liblvgl/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp", + "include/liblvgl/themes/mono/lv_theme_mono.h", + "include/liblvgl/misc/lv_circle_buf.h", + "include/liblvgl/drivers/nuttx/lv_nuttx_fbdev.h", + "include/liblvgl/libs/thorvg/tvgCanvas.h", + "include/liblvgl/widgets/imagebutton/lv_imagebutton_private.h", + "include/liblvgl/libs/thorvg/rapidjson/istreamwrapper.h", + "include/liblvgl/libs/thorvg/tvgAccessor.cpp", + "include/liblvgl/libs/thorvg/tvgMath.h", + "include/liblvgl/misc/lv_async.h", + "include/liblvgl/themes/lv_theme_private.h", + "include/liblvgl/libs/thorvg/tvgSvgSceneBuilder.h", + "include/liblvgl/libs/thorvg/tvgSwRaster.cpp", + "include/liblvgl/draw/lv_draw_arc.h", + "include/liblvgl/libs/thorvg/tvgInitializer.cpp", + "include/liblvgl/widgets/textarea/lv_textarea_private.h", + "include/liblvgl/widgets/label/lv_label_private.h", + "include/liblvgl/drivers/windows/lv_windows_input.h", + "include/liblvgl/libs/thorvg/tvgLottieInterpolator.h", + "include/liblvgl/drivers/glfw/lv_opengles_driver.h", + "include/liblvgl/lv_version.h", + "include/liblvgl/libs/ffmpeg/lv_ffmpeg_private.h", + "include/liblvgl/libs/thorvg/rapidjson/stream.h", + "include/liblvgl/drivers/nuttx/lv_nuttx_image_cache.h", + "include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_argb8888.h", + "include/liblvgl/libs/thorvg/tvgLoadModule.h", + "include/liblvgl/widgets/line/lv_line_private.h", + "include/liblvgl/misc/cache/lv_cache_private.h", + "include/liblvgl/libs/thorvg/tvgFrameModule.h", + "include/liblvgl/osal/lv_freertos.h", + "include/liblvgl/libs/thorvg/tvgSvgSceneBuilder.cpp", + "include/liblvgl/osal/lv_rtthread.h", + "include/liblvgl/draw/vg_lite/lv_draw_vg_lite_type.h", + "include/liblvgl/widgets/animimage/lv_animimage_private.h", + "include/liblvgl/libs/barcode/lv_barcode.h", + "include/liblvgl/stdlib/builtin/lv_tlsf.h", + "include/liblvgl/widgets/objx_templ/lv_objx_templ.h", + "include/liblvgl/others/fragment/README.md", + "include/liblvgl/libs/svg/lv_svg.h", + "include/liblvgl/widgets/image/lv_image_private.h", + "include/liblvgl/libs/qrcode/lv_qrcode.h", + "include/liblvgl/libs/thorvg/rapidjson/uri.h", + "include/liblvgl/osal/lv_os_none.h", + "include/liblvgl/misc/cache/lv_image_header_cache.h", + "include/liblvgl/widgets/span/lv_span_private.h", + "include/liblvgl/widgets/switch/lv_switch_private.h", + "include/liblvgl/libs/thorvg/tvgTaskScheduler.h", + "include/liblvgl/drivers/nuttx/lv_nuttx_profiler.h", + "include/liblvgl/draw/sw/arm2d/lv_draw_sw_helium.h", + "include/liblvgl/drivers/nuttx/lv_nuttx_libuv.h", + "include/liblvgl/libs/thorvg/tvgShape.h", + "include/liblvgl/drivers/nuttx/lv_nuttx_lcd.h", + "include/liblvgl/drivers/nuttx/lv_nuttx_entry.h", + "include/liblvgl/draw/sw/blend/lv_draw_sw_blend.h", + "include/liblvgl/widgets/canvas/lv_canvas_private.h", + "include/liblvgl/libs/thorvg/rapidjson/memorystream.h", + "include/liblvgl/others/fragment/lv_fragment_private.h", + "include/liblvgl/widgets/table/lv_table.h", + "include/liblvgl/drivers/windows/lv_windows_input_private.h", + "include/liblvgl/misc/lv_matrix.h", + "include/liblvgl/libs/thorvg/rapidjson/rapidjson.h", + "include/liblvgl/others/ime/lv_ime_pinyin_private.h", + "include/liblvgl/drivers/display/tft_espi/lv_tft_espi.cpp", + "include/liblvgl/libs/thorvg/tvgSwRasterTexmap.h", + "include/liblvgl/libs/thorvg/config.h", + "include/liblvgl/stdlib/builtin/lv_tlsf_private.h", + "include/liblvgl/libs/thorvg/rapidjson/internal/pow10.h", + "include/liblvgl/libs/thorvg/rapidjson/memorybuffer.h", + "include/liblvgl/lv_api_map_v9_1.h", + "include/liblvgl/libs/thorvg/rapidjson/internal/strtod.h", + "include/liblvgl/widgets/win/lv_win.h", + "include/liblvgl/misc/cache/lv_cache_entry.h", + "include/liblvgl/libs/thorvg/tvgCompressor.h", + "include/liblvgl/libs/thorvg/tvgPaint.cpp", + "include/liblvgl/misc/lv_style_private.h", + "include/liblvgl/draw/lv_draw_rect_private.h", + "include/liblvgl/libs/thorvg/tvgSvgLoader.h", + "include/liblvgl/widgets/span/lv_span.h", + "include/liblvgl/misc/lv_anim_private.h", + "include/liblvgl/draw/sw/lv_draw_sw_private.h", + "include/liblvgl/libs/bmp/lv_bmp.h", + "include/liblvgl/drivers/display/st7789/lv_st7789.h", + "include/liblvgl/libs/thorvg/tvgLoader.cpp", + "include/liblvgl/lvgl_private.h", + "include/liblvgl/libs/thorvg/rapidjson/internal/swap.h", + "include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_i1.h", + "include/liblvgl/misc/lv_rb_private.h", + "include/liblvgl/others/vg_lite_tvg/vg_lite_tvg.cpp", + "include/liblvgl/widgets/msgbox/lv_msgbox.h", + "include/liblvgl/drivers/glfw/lv_glfw_window.h", + "include/liblvgl/libs/thorvg/tvgRawLoader.h", + "include/liblvgl/themes/simple/lv_theme_simple.h", + "include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_al88.h", + "include/liblvgl/draw/lv_draw_buf.h", + "include/liblvgl/others/fragment/lv_fragment.h", + "include/liblvgl/libs/thorvg/tvgXmlParser.cpp", + "include/liblvgl/draw/dma2d/lv_draw_dma2d_private.h", + "include/liblvgl/misc/lv_color.h", + "include/liblvgl/libs/thorvg/rapidjson/pointer.h", + "include/liblvgl/libs/thorvg/rapidjson/encodedstream.h", + "include/liblvgl/others/observer/lv_observer.h", + "include/liblvgl/misc/lv_palette.h", + "include/liblvgl/libs/thorvg/tvgScene.h", + "include/liblvgl/draw/sw/blend/helium/lv_blend_helium.h", + "include/liblvgl/misc/lv_ll.h", + "include/liblvgl/libs/thorvg/tvgSwShape.cpp", + "include/liblvgl/drivers/display/st_ltdc/lv_st_ltdc.h", + "include/liblvgl/libs/bin_decoder/lv_bin_decoder.h", + "include/liblvgl/libs/lodepng/lv_lodepng.h", + "include/liblvgl/others/font_manager/lv_font_manager_recycle.h", + "include/liblvgl/libs/thorvg/rapidjson/stringbuffer.h", + "include/liblvgl/libs/thorvg/tvgSvgPath.h", + "include/liblvgl/stdlib/lv_sprintf.h", + "include/liblvgl/widgets/roller/lv_roller_private.h", + "include/liblvgl/font/lv_binfont_loader.h", + "include/liblvgl/libs/thorvg/tvgSwRasterAvx.h", + "include/liblvgl/libs/thorvg/rapidjson/internal/dtoa.h", + "include/liblvgl/drivers/libinput/lv_libinput_private.h", + "include/liblvgl/draw/lv_draw_mask.h", + "include/liblvgl/drivers/lv_drivers.h", + "include/liblvgl/libs/freetype/ftmodule.h", + "include/liblvgl/widgets/tabview/lv_tabview_private.h", + "include/liblvgl/draw/sw/lv_draw_sw.h", + "include/liblvgl/misc/lv_color_op_private.h", + "include/liblvgl/libs/freetype/ftoption.h", + "include/liblvgl/widgets/lottie/lv_lottie.h", + "include/liblvgl/layouts/flex/lv_flex.h", + "include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_l8.h", + "include/liblvgl/libs/thorvg/tvgRawLoader.cpp", + "include/liblvgl/widgets/calendar/lv_calendar_chinese_private.h", + "include/liblvgl/display/lv_display.h", + "include/liblvgl/drivers/display/st7796/lv_st7796.h", + "include/liblvgl/osal/lv_windows.h", + "include/liblvgl/misc/lv_text.h", + "include/liblvgl/misc/lv_style_gen.h", + "include/liblvgl/widgets/tabview/lv_tabview.h", + "include/liblvgl/draw/nxp/vglite/lv_vglite_path.h", + "include/liblvgl/libs/thorvg/tvgSwImage.cpp", + "include/liblvgl/core/lv_obj_pos.h", + "include/liblvgl/others/ime/lv_ime_pinyin.h", + "include/liblvgl/drivers/display/lcd/lv_lcd_generic_mipi.h", + "include/liblvgl/widgets/list/lv_list.h", + "include/liblvgl/layouts/lv_layout_private.h", + "include/liblvgl/libs/thorvg/tvgLottieBuilder.h", + "include/liblvgl/others/font_manager/lv_font_manager.h", + "include/liblvgl/stdlib/lv_mem.h", + "include/liblvgl/libs/thorvg/tvgSvgUtil.h", + "include/liblvgl/libs/thorvg/tvgLottieExpressions.cpp", + "include/liblvgl/libs/thorvg/tvgSwRasterC.h", + "include/liblvgl/core/lv_obj_scroll_private.h", + "include/liblvgl/misc/lv_fs_private.h", + "include/liblvgl/libs/thorvg/tvgSwFill.cpp", + "include/liblvgl/libs/thorvg/tvgSwRenderer.h", + "include/liblvgl/drivers/display/tft_espi/lv_tft_espi.h", + "include/liblvgl/widgets/dropdown/lv_dropdown.h", + "include/liblvgl/libs/thorvg/rapidjson/document.h", + "include/liblvgl/libs/thorvg/rapidjson/prettywriter.h", + "include/liblvgl/libs/thorvg/rapidjson/internal/strfunc.h", + "include/liblvgl/drivers/glfw/lv_opengles_debug.h", + "include/liblvgl/draw/lv_draw_vector_private.h", + "include/liblvgl/libs/thorvg/rapidjson/reader.h", + "include/liblvgl/libs/thorvg/tvgSaveModule.h", + "include/liblvgl/libs/thorvg/rapidjson/error/error.h", + "include/liblvgl/libs/thorvg/tvgSvgCssStyle.cpp", + "include/liblvgl/draw/lv_draw_mask_private.h", + "include/liblvgl/libs/thorvg/tvgTaskScheduler.cpp", + "include/liblvgl/libs/thorvg/tvgSvgPath.cpp", + "include/liblvgl/layouts/grid/lv_grid.h", + "include/liblvgl/drivers/glfw/lv_opengles_texture.h", + "include/liblvgl/widgets/checkbox/lv_checkbox_private.h", + "include/liblvgl/libs/tiny_ttf/lv_tiny_ttf.h", + "include/liblvgl/draw/sw/blend/arm2d/lv_blend_arm2d.h", + "include/liblvgl/misc/lv_timer.h", + "include/liblvgl/draw/nxp/pxp/lv_pxp_utils.h", + "include/liblvgl/widgets/switch/lv_switch.h", + "include/liblvgl/widgets/led/lv_led.h", + "include/liblvgl/libs/lz4/LICENSE", + "include/liblvgl/libs/thorvg/rapidjson/internal/regex.h", + "include/liblvgl/libs/thorvg/rapidjson/internal/diyfp.h", + "include/liblvgl/draw/nxp/pxp/lv_pxp_cfg.h", + "include/liblvgl/libs/gif/gifdec_mve.h", + "include/liblvgl/misc/lv_profiler_builtin_private.h", + "include/liblvgl/libs/thorvg/tvgBinaryDesc.h", + "include/liblvgl/core/lv_obj_tree.h", + "include/liblvgl/misc/lv_fs.h", + "include/liblvgl/libs/thorvg/tvgPaint.h", + "include/liblvgl/osal/lv_pthread.h", + "include/liblvgl/libs/thorvg/tvgText.h", + "include/liblvgl/draw/lv_draw_line.h", + "include/liblvgl/libs/ffmpeg/lv_ffmpeg.h", + "include/liblvgl/misc/lv_anim_timeline.h", + "include/liblvgl/draw/lv_image_dsc.h", + "include/liblvgl/widgets/chart/lv_chart.h", + "include/liblvgl/libs/thorvg/thorvg_capi.h", + "include/liblvgl/widgets/win/lv_win_private.h", + "include/liblvgl/core/lv_group.h", + "include/liblvgl/draw/nxp/vglite/lv_vglite_matrix.h", + "include/liblvgl/libs/thorvg/tvgAnimation.cpp", + "include/liblvgl/misc/lv_text_ap.h", + "include/liblvgl/widgets/menu/lv_menu_private.h", + "include/liblvgl/draw/lv_image_decoder_private.h", + "include/liblvgl/draw/lv_draw_vector.h", + "include/liblvgl/lv_conf.old.h", + "include/liblvgl/widgets/spinner/lv_spinner.h", + "include/liblvgl/libs/lz4/lz4.h", + "include/liblvgl/libs/thorvg/tvgCommon.h", + "include/liblvgl/libs/thorvg/tvgLottieBuilder.cpp", + "include/liblvgl/core/lv_obj.h", + "include/liblvgl/drivers/display/fb/lv_linux_fbdev.h", + "include/liblvgl/drivers/wayland/lv_wayland_smm.h", + "include/liblvgl/drivers/display/ili9341/lv_ili9341.h", + "include/liblvgl/libs/thorvg/rapidjson/schema.h", + "include/liblvgl/core/lv_obj_class_private.h", + "include/liblvgl/misc/lv_profiler_builtin.h", + "include/liblvgl/libs/thorvg/rapidjson/internal/stack.h", + "include/liblvgl/libs/qrcode/lv_qrcode_private.h", + "include/liblvgl/libs/thorvg/rapidjson/filewritestream.h", + "include/liblvgl/others/sysmon/lv_sysmon_private.h", + "include/liblvgl/libs/thorvg/tvgSwCanvas.cpp", + "include/liblvgl/libs/thorvg/tvgPicture.h", + "include/liblvgl/widgets/lottie/lv_lottie_private.h", + "include/liblvgl/widgets/checkbox/lv_checkbox.h", + "include/liblvgl/others/observer/lv_observer_private.h", + "include/liblvgl/widgets/arc/lv_arc_private.h", + "include/liblvgl/widgets/bar/lv_bar.h", + "include/liblvgl/libs/thorvg/tvgLoader.h", + "include/liblvgl/lv_conf_internal.h", + "include/liblvgl/widgets/msgbox/lv_msgbox_private.h", + "include/liblvgl/misc/lv_log.h", + "include/liblvgl/libs/freetype/lv_freetype_private.h", + "include/liblvgl/drivers/display/renesas_glcdc/lv_renesas_glcdc.h", + "include/liblvgl/widgets/keyboard/lv_keyboard.h", + "include/liblvgl/libs/thorvg/tvgLottieModel.cpp", + "include/liblvgl/others/monkey/lv_monkey.h", + "include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_rgb565.h", + "include/liblvgl/widgets/bar/lv_bar_private.h", + "include/liblvgl/core/lv_obj_style_gen.h", + "include/liblvgl/libs/thorvg/tvgLottieParser.cpp", + "include/liblvgl/drivers/libinput/lv_xkb.h", + "include/liblvgl/misc/lv_area.h", + "include/liblvgl/misc/lv_area_private.h", + "include/liblvgl/misc/lv_templ.h", + "include/liblvgl/misc/lv_style.h", + "include/liblvgl/drivers/display/drm/lv_linux_drm.h", + "include/liblvgl/core/lv_obj_class.h", + "include/liblvgl/libs/thorvg/tvgLock.h", + "include/liblvgl/libs/tiny_ttf/stb_rect_pack.h", + "include/liblvgl/core/lv_refr_private.h", + "include/liblvgl/font/lv_font_fmt_txt.h", + "include/liblvgl/osal/lv_mqx.h", + "include/liblvgl/lv_api_map_v8.h", + "include/liblvgl/widgets/chart/lv_chart_private.h", + "include/liblvgl/draw/vg_lite/lv_vg_lite_pending.h", + "include/liblvgl/libs/thorvg/rapidjson/allocators.h", + "include/liblvgl/misc/lv_types.h", + "include/liblvgl/widgets/animimage/lv_animimage.h", + "include/liblvgl/libs/thorvg/tvgSwStroke.cpp", + "include/liblvgl/misc/lv_anim.h", + "include/liblvgl/widgets/scale/lv_scale.h", + "include/liblvgl/drivers/README.md", + "include/liblvgl/libs/thorvg/rapidjson/encodings.h", + "include/liblvgl/draw/lv_draw_image.h", + "include/liblvgl/libs/thorvg/rapidjson/internal/clzll.h", + "include/liblvgl/libs/thorvg/tvgSwRenderer.cpp", + "include/liblvgl/draw/vg_lite/lv_vg_lite_path.h", + "include/liblvgl/lv_conf.h", + "include/liblvgl/draw/opengles/lv_draw_opengles.h", + "include/liblvgl/libs/thorvg/thorvg.h", + "include/liblvgl/libs/lodepng/lodepng.h", + "include/liblvgl/osal/lv_cmsis_rtos2.h", + "include/liblvgl/libs/thorvg/tvgWgCanvas.cpp", + "include/liblvgl/core/lv_obj_draw_private.h", + "include/liblvgl/libs/thorvg/rapidjson/internal/itoa.h", + "include/liblvgl/misc/lv_color_op.h", + "include/liblvgl/widgets/buttonmatrix/lv_buttonmatrix_private.h", + "include/liblvgl/core/lv_obj_style_private.h", + "include/liblvgl/others/file_explorer/lv_file_explorer.h", + "include/liblvgl/drivers/evdev/lv_evdev.h", + "include/liblvgl/draw/lv_draw.h", + "include/liblvgl/draw/sw/blend/lv_draw_sw_blend_to_rgb888.h", + "include/liblvgl/libs/tiny_ttf/stb_truetype_htcw.h", + "include/liblvgl/drivers/wayland/lv_wayland.h", + "include/liblvgl/misc/cache/lv_image_cache.h", + "include/liblvgl/misc/lv_text_private.h", + "include/liblvgl/widgets/button/lv_button_private.h", + "include/liblvgl/drivers/sdl/lv_sdl_private.h", + "include/liblvgl/libs/svg/lv_svg_render.h", + "include/liblvgl/libs/thorvg/tvgScene.cpp", + "include/liblvgl/core/lv_obj_event.h", + "include/liblvgl/lv_api_map_v9_0.h", + "include/liblvgl/libs/thorvg/tvgShape.cpp", + "include/liblvgl/libs/thorvg/tvgLines.h" + ], + "target": "v5", + "user_files": [], + "version": "9.2.0" + } + }, + "upload_options": {}, + "use_early_access": false + } +} \ No newline at end of file diff --git a/test/src/main.cpp b/test/src/main.cpp new file mode 100644 index 00000000..7fb87394 --- /dev/null +++ b/test/src/main.cpp @@ -0,0 +1,94 @@ +#include "main.h" + +/** + * A callback function for LLEMU's center button. + * + * When this callback is fired, it will toggle line 2 of the LCD text between + * "I was pressed!" and nothing. + */ +void on_center_button() { + static bool pressed = false; + pressed = !pressed; + if (pressed) { + pros::lcd::set_text(2, "I was pressed!"); + } else { + pros::lcd::clear_line(2); + } +} + +/** + * Runs initialization code. This occurs as soon as the program is started. + * + * All other competition modes are blocked by initialize; it is recommended + * to keep execution time for this mode under a few seconds. + */ +void initialize() { + pros::lcd::initialize(); + pros::lcd::set_text(1, "Hello PROS User!"); + + pros::lcd::register_btn1_cb(on_center_button); +} + +/** + * Runs while the robot is in the disabled state of Field Management System or + * the VEX Competition Switch, following either autonomous or opcontrol. When + * the robot is enabled, this task will exit. + */ +void disabled() {} + +/** + * Runs after initialize(), and before autonomous when connected to the Field + * Management System or the VEX Competition Switch. This is intended for + * competition-specific initialization routines, such as an autonomous selector + * on the LCD. + * + * This task will exit when the robot is enabled and autonomous or opcontrol + * starts. + */ +void competition_initialize() {} + +/** + * Runs the user autonomous code. This function will be started in its own task + * with the default priority and stack size whenever the robot is enabled via + * the Field Management System or the VEX Competition Switch in the autonomous + * mode. Alternatively, this function may be called in initialize or opcontrol + * for non-competition testing purposes. + * + * If the robot is disabled or communications is lost, the autonomous task + * will be stopped. Re-enabling the robot will restart the task, not re-start it + * from where it left off. + */ +void autonomous() {} + +/** + * Runs the operator control code. This function will be started in its own task + * with the default priority and stack size whenever the robot is enabled via + * the Field Management System or the VEX Competition Switch in the operator + * control mode. + * + * If no competition control is connected, this function will run immediately + * following initialize(). + * + * If the robot is disabled or communications is lost, the + * operator control task will be stopped. Re-enabling the robot will restart the + * task, not resume it from where it left off. + */ +void opcontrol() { + pros::Controller master(pros::E_CONTROLLER_MASTER); + pros::MotorGroup left_mg({1, -2, 3}); // Creates a motor group with forwards ports 1 & 3 and reversed port 2 + pros::MotorGroup right_mg({-4, 5, -6}); // Creates a motor group with forwards port 5 and reversed ports 4 & 6 + + + while (true) { + pros::lcd::print(0, "%d %d %d", (pros::lcd::read_buttons() & LCD_BTN_LEFT) >> 2, + (pros::lcd::read_buttons() & LCD_BTN_CENTER) >> 1, + (pros::lcd::read_buttons() & LCD_BTN_RIGHT) >> 0); // Prints status of the emulated screen LCDs + + // Arcade control scheme + int dir = master.get_analog(ANALOG_LEFT_Y); // Gets amount forward/backward from left joystick + int turn = master.get_analog(ANALOG_RIGHT_X); // Gets the turn left/right from right joystick + left_mg.move(dir - turn); // Sets left motor voltage + right_mg.move(dir + turn); // Sets right motor voltage + pros::delay(20); // Run for 20 ms then update + } +} \ No newline at end of file

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%0DKBFRp3W z9<7Gx<2iFu_~t~J2zk!D6ux<>{12q!3sU%!qwP7zrSKh>svp-&$%px@3K_>6{+~&rSSb-D*wt9zAIDtpHIcFO5wXImH&kl zzAvQm|2`GJHihrnRQ}!+zP(buGAy+>3^Cw2`%>}iQ~0k><$o!K|4S+SUrLq#aw>jP z3ja;1{F_twZ%*akl8S#dh3~7W{I8|(eJz#$^;G=!6u#S2`QJ$4`$j7NTdDXzr11Si zD*rnveBVjs-s= z`0h*P-=B*AIEC-Wsr(01_#RB<|0ETEIEC-wRQ}IW_K(qtEv2d zPqqK=4kd!(xEX&L=igK1|05NDBZdEsRQ{VO{BKJ6XxH>+s{C82_}eM`3HJ*4?YavR zHC&hcIX6r*`H#lp%s(dNryI^Z7J)w|754>SSl#hc`Po$a*;IaEDqfVrSCq;xN#QF= z<&R0l%ToBtQu$+3@$sp6c`8036`z!fADoIGl8PUiidUxM)7CSnn{Jp989f|TsIQvuiKiB+;g6|mT=|uT?&Yx4| z3!%%IWZFN@nG))DN4#D0HQ(Sn(OIVPoZw&Td@vEObGB=oazEZ#<6MEb{g7W@PQ|~Y z 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≥hRl^J8wQIy$FjwMvOQFPDJ_TFq9lZ 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