From 2b725a8ceb01bdba5d32616cf193912ac469c6e6 Mon Sep 17 00:00:00 2001 From: Gondos Date: Fri, 10 Jan 2025 14:51:45 +0100 Subject: [PATCH 01/51] [ImGui]Integrate Dear ImGui library --- Extern/CMakeLists.txt | 1 + Extern/imgui/CMakeLists.txt | 16 ++++ Extern/imgui/imconfig.h | 155 +++++++++++++++++++++++++++++++ OVP/D3D9Client/CMakeLists.txt | 4 + OVP/D3D9Client/D3D9Client.cpp | 38 +++++++- OVP/D3D9Client/D3D9Client.h | 4 + Orbitersdk/include/GraphicsAPI.h | 21 +++++ Src/Orbiter/CMakeLists.txt | 4 +- Src/Orbiter/DlgMgr.cpp | 89 +++++++++++++++++- Src/Orbiter/DlgMgr.h | 80 +++++++++++++++- Src/Orbiter/Orbiter.cpp | 28 ++++++ Src/Orbitersdk/CMakeLists.txt | 6 ++ 12 files changed, 440 insertions(+), 6 deletions(-) create mode 100644 Extern/imgui/CMakeLists.txt create mode 100644 Extern/imgui/imconfig.h diff --git a/Extern/CMakeLists.txt b/Extern/CMakeLists.txt index a8690b14e..fcbee56b4 100644 --- a/Extern/CMakeLists.txt +++ b/Extern/CMakeLists.txt @@ -6,6 +6,7 @@ endif(NOT DEFINED ORBITER_BINARY_ROOT_DIR) add_subdirectory(Lua) add_subdirectory(zlib) +add_subdirectory(imgui) ## LFS add_library(lfs SHARED luafilesystem/src/lfs.c) diff --git a/Extern/imgui/CMakeLists.txt b/Extern/imgui/CMakeLists.txt new file mode 100644 index 000000000..c7ef5f598 --- /dev/null +++ b/Extern/imgui/CMakeLists.txt @@ -0,0 +1,16 @@ +project(imgui) + +Include(FetchContent) + +FetchContent_Declare( + imgui + GIT_REPOSITORY https://github.com/ocornut/imgui.git + GIT_TAG v1.91.6-docking + PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/imconfig.h . + UPDATE_DISCONNECTED 1 +) +FetchContent_MakeAvailable(imgui) + +install(FILES ${imgui_SOURCE_DIR}/misc/fonts/Roboto-Medium.ttf + DESTINATION ${ORBITER_INSTALL_ROOT_DIR} +) diff --git a/Extern/imgui/imconfig.h b/Extern/imgui/imconfig.h new file mode 100644 index 000000000..f923f8ccc --- /dev/null +++ b/Extern/imgui/imconfig.h @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// DEAR IMGUI COMPILE-TIME OPTIONS +// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. +// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. +//----------------------------------------------------------------------------- +// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it) +// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template. +//----------------------------------------------------------------------------- +// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp +// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. +// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. +// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using. +//----------------------------------------------------------------------------- + +#pragma once + +//---- Define assertion handler. Defaults to calling assert(). +// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. +//#define IM_ASSERT(_EXPR) MyAssert(_EXPR) +//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts + +//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows +// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. +// - Windows DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions() +// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details. +//#define IMGUI_API __declspec(dllexport) // MSVC Windows: DLL export +//#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import +//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden + +//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names. +//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS + +//---- Disable all of Dear ImGui or don't implement standard windows/tools. +// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp. +//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. +//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. +//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty. + +//---- Don't implement some functions to reduce linkage requirements. +//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) +//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW) +//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a) +//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME). +//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). +//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")). +//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) +//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. +//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) +//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. +//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). +//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert. +//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available + +//---- Enable Test Engine / Automation features. +//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details. + +//---- Include imgui_user.h at the end of imgui.h as a convenience +// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included. +//#define IMGUI_INCLUDE_IMGUI_USER_H +//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h" + +//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support. +//#define IMGUI_USE_BGRA_PACKED_COLOR + +//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate. +//#define IMGUI_USE_LEGACY_CRC32_ADLER + +//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...) +//#define IMGUI_USE_WCHAR32 + +//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version +// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files. +//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" +//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" +//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined. +//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION +//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION +//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined. + +//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined) +// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h. +//#define IMGUI_USE_STB_SPRINTF + +//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui) +// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided). +// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'. +//#define IMGUI_ENABLE_FREETYPE + +//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT) +// Only works in combination with IMGUI_ENABLE_FREETYPE. +// - lunasvg is currently easier to acquire/install, as e.g. it is part of vcpkg. +// - plutosvg will support more fonts and may load them faster. It currently requires to be built manually but it is fairly easy. See misc/freetype/README for instructions. +// - Both require headers to be available in the include path + program to be linked with the library code (not provided). +// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement) +//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG +//#define IMGUI_ENABLE_FREETYPE_LUNASVG + +//---- Use stb_truetype to build and rasterize the font atlas (default) +// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend. +//#define IMGUI_ENABLE_STB_TRUETYPE + +//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. +// This will be inlined as part of ImVec2 and ImVec4 class declarations. +/* +#define IM_VEC2_CLASS_EXTRA \ + constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \ + operator MyVec2() const { return MyVec2(x,y); } + +#define IM_VEC4_CLASS_EXTRA \ + constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \ + operator MyVec4() const { return MyVec4(x,y,z,w); } +*/ +//---- ...Or use Dear ImGui's own very basic math operators. +//#define IMGUI_DEFINE_MATH_OPERATORS + +//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. +// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices). +// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. +// Read about ImGuiBackendFlags_RendererHasVtxOffset for details. +//#define ImDrawIdx unsigned int + +//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly) +//struct ImDrawList; +//struct ImDrawCmd; +//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); +//#define ImDrawCallback MyImDrawCallback + +//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase) +// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) +//#define IM_DEBUG_BREAK IM_ASSERT(0) +//#define IM_DEBUG_BREAK __debugbreak() + +//---- Debug Tools: Enable slower asserts +//#define IMGUI_DEBUG_PARANOID + +//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files) +/* +namespace ImGui +{ + void MyFunction(const char* name, MyMatrix44* mtx); +} +*/ + +// Orbiter specific : +// The ImGuiContext is owned by the main exe, libraries are importing it. +// The ImGui code is stored in the Orbiter SDK so that modules can use it. +struct ImGuiContext; + +#ifdef EXPORT_IMGUI_CONTEXT +extern __declspec(dllexport) struct ImGuiContext* GImGui; // Current implicit context pointer +#else +extern __declspec(dllimport) struct ImGuiContext* GImGui; // Current implicit context pointer +#endif + +#define GImGui GImGui diff --git a/OVP/D3D9Client/CMakeLists.txt b/OVP/D3D9Client/CMakeLists.txt index ddbaf2e1c..f868c49c5 100644 --- a/OVP/D3D9Client/CMakeLists.txt +++ b/OVP/D3D9Client/CMakeLists.txt @@ -2,6 +2,7 @@ project(D3D9Client VERSION 31.0) configure_file(D3D9ClientConfig.h.in D3D9ClientConfig.h) +FetchContent_MakeAvailable(imgui) # specify the C++ standard # set(CMAKE_CXX_STANDARD 11) @@ -67,6 +68,7 @@ set(SourceFiles WindowMgr.cpp ZTreeMgr.cpp Tilemgr2_imp.hpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_dx9.cpp ) set(IncludeFiles @@ -171,6 +173,8 @@ add_library(D3D9Client MODULE target_include_directories(D3D9Client PUBLIC ${ORBITER_SOURCE_SDK_INCLUDE_DIR} ${DXSDK_DIR}/Include + ${imgui_SOURCE_DIR}/ + ${imgui_SOURCE_DIR}/backends/ ) target_link_directories(D3D9Client PUBLIC diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index 8307faaac..f0fac11f8 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -40,7 +40,9 @@ #include "gcConst.h" #include #include - +#include "imgui.h" +#include "imgui_impl_dx9.h" +#include "imgui_impl_win32.h" #if defined(_MSC_VER) && (_MSC_VER <= 1700 ) // Microsoft Visual Studio Version 2012 and lower #define round(v) floor(v+0.5) @@ -2724,6 +2726,40 @@ bool D3D9Client::clbkFilterElevation(OBJHANDLE hPlanet, int ilat, int ilng, int _TRACE; return FilterElevationPhysics(hPlanet, lvl, ilat, ilng, elev_res, elev); } +void D3D9Client::clbkImGuiNewFrame() +{ + _TRACE; + ImGui_ImplDX9_NewFrame(); +} +void D3D9Client::clbkImGuiRenderDrawData() +{ + _TRACE; + + if (pDevice->BeginScene() >= 0) + { + ImGui::Render(); + ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); + pDevice->EndScene(); + } + + // Update and Render additional Platform Windows + ImGuiIO& io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } +} +void D3D9Client::clbkImGuiInit() +{ + _TRACE; + ImGui_ImplDX9_Init(pDevice); +} +void D3D9Client::clbkImGuiShutdown() +{ + _TRACE; + ImGui_ImplDX9_Shutdown(); +} // ======================================================================= diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index c1015c2eb..131937995 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -1037,6 +1037,10 @@ class D3D9Client : public GraphicsClient bool clbkFilterElevation(OBJHANDLE hPlanet, int ilat, int ilng, int lvl, double elev_res, INT16* elev); // @} + void clbkImGuiNewFrame() override; + void clbkImGuiRenderDrawData() override; + void clbkImGuiInit() override; + void clbkImGuiShutdown() override; HWND GetRenderWindow () const { return hRenderWnd; } CD3DFramework9 * GetFramework() const { return pFramework; } diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index ba7d4fbac..7cdfd6aba 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -1481,6 +1481,11 @@ class OAPIFUNC GraphicsClient: public Module { virtual bool clbkFilterElevation(OBJHANDLE hPlanet, int ilat, int ilng, int lvl, double elev_res, INT16* elev) { return false; } // @} + virtual void clbkImGuiNewFrame () = 0; + virtual void clbkImGuiRenderDrawData () = 0; + virtual void clbkImGuiInit () = 0; + virtual void clbkImGuiShutdown() = 0; + protected: /** \brief Launchpad video tab indicator * @@ -2056,4 +2061,20 @@ OAPIFUNC bool oapiRegisterGraphicsClient (oapi::GraphicsClient *gc); OAPIFUNC bool oapiUnregisterGraphicsClient (oapi::GraphicsClient *gc); +class OAPIFUNC DialogImGui { +public: + virtual ~DialogImGui() = default; + bool IsActive() { return active; } + void Activate() { active = true; } + void Display() { + Draw(); + if (!active) OnClose(); + } + virtual void OnClose() {}; +private: + virtual void Draw() = 0; +protected: + bool active = false; +}; + #endif // !__GRAPHICSAPI_H \ No newline at end of file diff --git a/Src/Orbiter/CMakeLists.txt b/Src/Orbiter/CMakeLists.txt index 597b1e4e5..2a4bf503b 100644 --- a/Src/Orbiter/CMakeLists.txt +++ b/Src/Orbiter/CMakeLists.txt @@ -3,6 +3,7 @@ # SAFESEH linker flag must be turned off because the DX7 libraries don't support it' set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -SAFESEH:NO") +FetchContent_MakeAvailable(imgui) # Sources for all Orbiter executable targets set(common_src @@ -119,6 +120,7 @@ set(common_src # Resources Orbiter.rc Orbiter.ico + ${imgui_SOURCE_DIR}/backends/imgui_impl_win32.cpp ) set(Orbiter_includes @@ -163,7 +165,7 @@ set_target_properties(Orbiter FOLDER Core ) -target_include_directories(Orbiter PUBLIC ${Orbiter_includes}) +target_include_directories(Orbiter PUBLIC ${Orbiter_includes} ${imgui_SOURCE_DIR}/ ${imgui_SOURCE_DIR}/backends) target_link_libraries(Orbiter ${Orbiter_common_libs} ${Orbiter_libs}) diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index c4ae7e0bb..383ea0185 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -1,12 +1,15 @@ -// Copyright (c) Martin Schweiger +// Copyright (c) Martin Schweiger // Licensed under the MIT License +#define EXPORT_IMGUI_CONTEXT #include #include "GraphicsAPI.h" #include "DlgMgr.h" #include "Resource.h" #include "Orbiter.h" #include "Log.h" +#include "imgui.h" +#include "imgui_impl_win32.h" using namespace oapi; @@ -49,11 +52,13 @@ DialogManager::DialogManager (Orbiter *orbiter, HWND hAppWnd) nList = nListBuf = 0; firstEntry = NULL; lastEntry = NULL; + InitImGui(); } DialogManager::~DialogManager () { Clear(); + ShutdownImGui(); } @@ -395,3 +400,85 @@ DWORD WINAPI DlgThreadProc (void *data) // ==================================================================== // End tread management // ==================================================================== +// +// ==================================================================== +// ImGui +// ==================================================================== + +DLLEXPORT ImGuiContext* GImGui = NULL; + +const ImWchar* GetGlyphRangesOrbiter() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x00A0, 0x02D9, // Polish characters + 0x0393, 0x03C2, // Greek characters + 0x221A, 0x221A, // √ + 0x222B, 0x222B, // ∫ + 0x2260, 0x2264, // ≠ ≤ ≥ + 0x02DD, 0x02DD, // ˝ + 0, + }; + return &ranges[0]; +} + +static void ImGuiSetStyle() +{ + // Setup Dear ImGui style + ImGui::StyleColorsClassic(); +} + +void DialogManager::InitImGui() +{ + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + // Viewports don't play nice when in full screen mode + if(!pOrbiter->IsFullscreen()) + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + //io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + + ImGuiSetStyle(); + + ImFontConfig config; + + ImFontConfig icons_config; + icons_config.MergeMode = true; + icons_config.PixelSnapH = true; + icons_config.FontDataOwnedByAtlas = false; + + io.Fonts->AddFontFromFileTTF("Roboto-Medium.ttf", 18.0f, &config, GetGlyphRangesOrbiter()); + io.Fonts->Build(); + + ImGui_ImplWin32_Init(hWnd); + gc->clbkImGuiInit(); +} + +void DialogManager::ShutdownImGui() +{ + gc->clbkImGuiShutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); +} + +void DialogManager::ImGuiNewFrame() +{ + gc->clbkImGuiNewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + //ImGui::ShowDemoWindow(); + + // We can't use a range-based loop here because Show() may unregister the current dialog + for (auto it = DlgImGuiList.begin(); it != DlgImGuiList.end();) + { + auto current = it++; + if ((*current)->IsActive()) { + (*current)->Display(); + } + } + ImGui::EndFrame(); +} diff --git a/Src/Orbiter/DlgMgr.h b/Src/Orbiter/DlgMgr.h index 697c67661..b350bd276 100644 --- a/Src/Orbiter/DlgMgr.h +++ b/Src/Orbiter/DlgMgr.h @@ -9,6 +9,9 @@ #include "DialogWin.h" #include "Orbiter.h" +#include +#include "imgui.h" +class DialogImGui; class oapi::GraphicsClient; extern Orbiter *g_pOrbiter; @@ -29,7 +32,7 @@ class DialogManager { // Make sure that a dialog of type DlgType is open and return a pointer to it. // This opens the dialog if not yet present. // Use this function for dialogs that should only have a single instance - template + template, bool> = true> DlgType *EnsureEntry (HINSTANCE hInst = 0, void *context = 0) { if (!hInst) hInst = g_pOrbiter->GetInstance(); @@ -41,7 +44,7 @@ class DialogManager { // Create a new instance of dialog type DlgType and return a pointer to it. // This opens a new dialog, even if one of this type was open already. // Use this function for dialogs that can have multiple instances. - template + template, bool> = true> DlgType *MakeEntry (HINSTANCE hInst = 0, void *context = 0) { if (!hInst) hInst = g_pOrbiter->GetInstance(); @@ -53,7 +56,7 @@ class DialogManager { // Returns a pointer to the first instance of dialog type DlgType, // or 0 if no instance exists. - template + template, bool> = true> DlgType *EntryExists (HINSTANCE hInst) { DIALOGENTRY *tmp = firstEntry; @@ -149,6 +152,77 @@ class DialogManager { // End tread management // ==================================================================== + + // ==================================================================== + // ImGui management + // ==================================================================== + std::list DlgImGuiList; +public: + // Make sure that a dialog of type DlgType is open and return a pointer to it. + // This opens the dialog if not yet present. + // Use this function for dialogs that should only have a single instance + template, bool> = true> + T* EnsureEntry() + { + T* dlg = EntryExists(); + if(!dlg) + dlg = MakeEntry(); + if(dlg) + dlg->Activate(); + return dlg; + } + + // Create a new instance of dialog type DlgType and return a pointer to it. + // This opens a new dialog, even if one of this type was open already. + // Use this function for dialogs that can have multiple instances. + template, bool> = true> + T* MakeEntry() + { + T* pDlg = new T(); + AddEntry(pDlg); + return pDlg; + } + + // Returns a pointer to the first instance of dialog type DlgType, + // or 0 if no instance exists. + template, bool> = true> + T* EntryExists() + { + for (auto& e : DlgImGuiList) { + T *dlg = dynamic_cast(e); + if(dlg) return dlg; + } + return nullptr; + } + + void AddEntry(DialogImGui* dlg) + { + for (auto& e : DlgImGuiList) { + if (e == dlg) { + return; + } + } + DlgImGuiList.push_back(dlg); + } + + bool DelEntry(DialogImGui* dlg) + { + for (auto it = DlgImGuiList.begin(); it != DlgImGuiList.end(); ) { + if (*it == dlg) { + it = DlgImGuiList.erase(it); + return true; + } + else { + ++it; + } + } + return false; + } + + void ImGuiNewFrame(); +private: + void InitImGui(); + void ShutdownImGui(); }; INT_PTR OrbiterDefDialogProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 966aab155..3c12e4c65 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -43,12 +43,16 @@ #include "DlgCtrl.h" #include "GraphicsAPI.h" #include "ConsoleManager.h" +#include "imgui.h" +#include "imgui_impl_win32.h" #include namespace fs = std::filesystem; using namespace std; using namespace oapi; +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + #define OUTPUT_DBG #define LOADSTATUSCOL 0xC08080 //0xFFD0D0 @@ -974,8 +978,10 @@ void Orbiter::BroadcastGlobalInit () HRESULT Orbiter::Render3DEnvironment () { if (gclient) { + pDlgMgr->ImGuiNewFrame(); gclient->clbkRenderScene (); Output2DData (); + gclient->clbkImGuiRenderDrawData(); gclient->clbkDisplayFrame (); } return S_OK; @@ -2557,6 +2563,9 @@ void Orbiter::BroadcastBufferedKeyboardEvent (char *kstate, DIDEVICEOBJECTDATA * LRESULT Orbiter::MsgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + if (ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam)) + return true; + WORD kmod; switch (uMsg) { @@ -2566,6 +2575,10 @@ LRESULT Orbiter::MsgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return 0; case WM_CHAR: + if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureKeyboard) { + return 0; + } + // make dialogs modal to avoid complications if (g_input && g_input->IsActive()) { if (g_input->ConsumeKey (uMsg, wParam) != Select::key_ignore) bRenderOnce = TRUE; @@ -2579,6 +2592,9 @@ LRESULT Orbiter::MsgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // *** User Keyboard Input *** case WM_KEYDOWN: + if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureKeyboard) { + return 0; + } // modifiers kmod = 0; @@ -2601,10 +2617,18 @@ LRESULT Orbiter::MsgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_RBUTTONDOWN: case WM_LBUTTONUP: case WM_RBUTTONUP: { + if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureMouse) { + return 0; + } + if (MouseEvent(uMsg, wParam, LOWORD(lParam), HIWORD(lParam))) break; //return 0; } break; case WM_MOUSEWHEEL: { + if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureMouse) { + return 0; + } + int x = LOWORD(lParam); int y = HIWORD(lParam); if (!bFullscreen) { @@ -2617,6 +2641,10 @@ LRESULT Orbiter::MsgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; //return 0; } break; case WM_MOUSEMOVE: { + if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureMouse) { + return 0; + } + int x = LOWORD(lParam); int y = HIWORD(lParam); MouseEvent(uMsg, wParam, x, y); diff --git a/Src/Orbitersdk/CMakeLists.txt b/Src/Orbitersdk/CMakeLists.txt index 92414bde2..601dabd9d 100644 --- a/Src/Orbitersdk/CMakeLists.txt +++ b/Src/Orbitersdk/CMakeLists.txt @@ -3,9 +3,15 @@ # Static library containing the DLL entry point for Orbiter plugins. # To be included by all Orbiter plugin DLLs. +FetchContent_MakeAvailable(imgui) add_library(Orbitersdk STATIC Orbitersdk.cpp + ${imgui_SOURCE_DIR}/imgui.cpp + ${imgui_SOURCE_DIR}/imgui_demo.cpp + ${imgui_SOURCE_DIR}/imgui_draw.cpp + ${imgui_SOURCE_DIR}/imgui_tables.cpp + ${imgui_SOURCE_DIR}/imgui_widgets.cpp ) set_target_properties(Orbitersdk From 5810406150bbd1c52f3ec1b9fa50bbca2555c9b4 Mon Sep 17 00:00:00 2001 From: Gondos Date: Wed, 15 Jan 2025 19:18:56 +0100 Subject: [PATCH 02/51] [ImGui]Replace InputBox and Select --- Src/Orbiter/Mfd.h | 3 +- Src/Orbiter/Orbiter.cpp | 49 +- Src/Orbiter/Select.cpp | 1001 +++++++-------------------------------- Src/Orbiter/Select.h | 236 ++------- 4 files changed, 205 insertions(+), 1084 deletions(-) diff --git a/Src/Orbiter/Mfd.h b/Src/Orbiter/Mfd.h index 8fdc646b0..78bc9501a 100644 --- a/Src/Orbiter/Mfd.h +++ b/Src/Orbiter/Mfd.h @@ -21,6 +21,7 @@ #include "Vessel.h" #include "Element.h" #include "Select.h" +#include #define ELN 256 // polygon resolution for orbit trajectory #define ELNH (ELN/2) @@ -42,8 +43,6 @@ struct MFDMODE { // MFD mode (for builtin and user-defined modes) }; class Pane; -class InputBox; -class Select; class oapi::GraphicsClient; static char work_kstate[256]; diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 3c12e4c65..c100f549c 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -763,10 +763,11 @@ HWND Orbiter::CreateRenderWindow (Config *pCfg, const char *scenario) pDlgMgr = new DialogManager (this, hRenderWnd); // global dialog resources - InlineDialog::GlobalInit (gclient); - g_select = new Select (gclient, hRenderWnd); TRACENEW - g_input = new InputBox (gclient, hRenderWnd, 256); TRACENEW - + g_select = new Select(); TRACENEW + pDlgMgr->AddEntry(g_select); + g_input = new InputBox(); TRACENEW + pDlgMgr->AddEntry(g_input); + // playback screen annotation manager snote_playback = gclient->clbkCreateAnnotation (); } @@ -901,7 +902,6 @@ void Orbiter::CloseSession () snote = NULL; nsnote = 0; } - InlineDialog::GlobalExit (gclient); if (g_input) { delete g_input; g_input = 0; } if (g_select) { delete g_select; g_select = 0; } @@ -1777,8 +1777,6 @@ VOID Orbiter::Output2DData () for (DWORD i = 0; i < nsnote; i++) snote[i]->Render(); if (snote_playback && pConfig->CfgRecPlayPrm.bShowNotes) snote_playback->Render(); - if (g_select->IsActive()) g_select->Display(0/*oclient->m_pddsRenderTarget*/); - if (g_input->IsActive()) g_input->Display(0/*oclient->m_pddsRenderTarget*/); } } @@ -2508,10 +2506,6 @@ bool Orbiter::MouseEvent (UINT event, DWORD state, DWORD x, DWORD y) if (event == WM_MOUSEMOVE) return false; // may be lifted later if (bRunning) { - if (event == WM_LBUTTONDOWN || event == WM_RBUTTONDOWN) { - if (g_input && g_input->IsActive()) g_input->Close(); - if (g_select && g_select->IsActive()) g_select->Clear (true); - } if (g_pane->ProcessMouse_OnRunning (event, state, x, y, simkstate)) return true; } if (g_pane->ProcessMouse_System(event, state, x, y, simkstate)) return true; @@ -2566,50 +2560,19 @@ LRESULT Orbiter::MsgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam)) return true; - WORD kmod; - switch (uMsg) { case WM_ACTIVATE: bActive = (wParam != WA_INACTIVE); return 0; - case WM_CHAR: - if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureKeyboard) { - return 0; - } - - // make dialogs modal to avoid complications - if (g_input && g_input->IsActive()) { - if (g_input->ConsumeKey (uMsg, wParam) != Select::key_ignore) bRenderOnce = TRUE; - return 0; - } - if (g_select && g_select->IsActive()) { - if (g_select->ConsumeKey (uMsg, wParam) != Select::key_ignore) bRenderOnce = TRUE; - return 0; - } - break; - // *** User Keyboard Input *** + case WM_CHAR: case WM_KEYDOWN: if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureKeyboard) { return 0; } - // modifiers - kmod = 0; - if (GetKeyState (VK_SHIFT) & 0x8000) kmod |= 0x01; - if (GetKeyState (VK_CONTROL) & 0x8000) kmod |= 0x02; - - // make dialogs modal to avoid complications - if (g_input && g_input->IsActive()) { - if (g_input->ConsumeKey (uMsg, wParam, kmod) != Select::key_ignore) bRenderOnce = TRUE; - return 0; - } - if (g_select && g_select->IsActive()) { - if (g_select->ConsumeKey (uMsg, wParam, kmod) != Select::key_ignore) bRenderOnce = TRUE; - return 0; - } break; // Mouse event handler diff --git a/Src/Orbiter/Select.cpp b/Src/Orbiter/Select.cpp index e7bd09aec..fdecc5d00 100644 --- a/Src/Orbiter/Select.cpp +++ b/Src/Orbiter/Select.cpp @@ -1,855 +1,172 @@ // Copyright (c) Martin Schweiger // Licensed under the MIT License -#define STRICT 1 - -#include -#include -#include "Orbiter.h" -#include "Config.h" #include "Select.h" -#include "Util.h" -#include "Log.h" - -using std::max; - -extern Orbiter *g_pOrbiter; -extern char DBG_MSG[256]; -COLORREF titlecol = RGB(255,255,255); -COLORREF enablecol = RGB(210,210,210); -COLORREF disablecol = RGB(130,130,130); -COLORREF enablehi = RGB(255,255,255); -COLORREF disablehi = RGB(150,150,150); -COLORREF markcol = RGB(96,96,96); - -// ======================================================================= -// local prototypes - -//SURFHANDLE AllocSurface (oapi::GraphicsClient *gc, int w, int h); -void ReleaseSurface (LPDIRECTDRAWSURFACE7 &surf); -void ClearSurface (oapi::GraphicsClient *gc, SURFHANDLE surf, int h = 0); - -// ======================================================================= -// Base class for inline dialog box resources - -struct InlineDialog::DRAWRESRC InlineDialog::draw = {0,0,0,0,0}; - -InlineDialog::InlineDialog (oapi::GraphicsClient *gclient, HWND hwnd) -{ - gc = gclient; - hWnd = hwnd; -}; - -InlineDialog::~InlineDialog() -{ -} - -void InlineDialog::GlobalInit (oapi::GraphicsClient *gclient) -{ - if (!gclient) return; // sanity check - - draw.pen1 = gclient->clbkCreatePen (1, 0, 0x808080); - draw.pen2 = gclient->clbkCreatePen (1, 0, 0xFFFFFF); - draw.brushMark = gclient->clbkCreateBrush (markcol); - - DWORD viewH = g_pOrbiter->ViewH(); - double scale = g_pOrbiter->Cfg()->CfgFontPrm.dlgFont_Scale; - char *face1 = g_pOrbiter->Cfg()->CfgFontPrm.dlgFont1_Face; - - draw.fontH = (int)(viewH*0.02*scale); - if (draw.fontH < 8) draw.fontH = 8; - draw.fontNorm = gclient->clbkCreateFont (draw.fontH, true, face1); - draw.fontInactive = gclient->clbkCreateFont (draw.fontH, true, face1, FONT_ITALIC); - draw.fontInput = gclient->clbkCreateFont (draw.fontH, false, "Courier New"); -} - -void InlineDialog::GlobalExit (oapi::GraphicsClient *gclient) -{ - if (draw.pen1) gclient->clbkReleasePen (draw.pen1); - if (draw.pen2) gclient->clbkReleasePen (draw.pen2); - if (draw.brushMark) gclient->clbkReleaseBrush (draw.brushMark); - if (draw.fontNorm) gclient->clbkReleaseFont (draw.fontNorm); - if (draw.fontInactive) gclient->clbkReleaseFont (draw.fontInactive); - if (draw.fontInput) gclient->clbkReleaseFont (draw.fontInput); -} - -// ======================================================================= -// menu dialog box - -Select::Select (oapi::GraphicsClient *gclient, HWND hwnd): InlineDialog (gclient, hwnd) -{ - alen = llen = level = 0; - cbk_submenu = 0; - cbk_enter = 0; - cntx = cnty = -1; - surf = 0; - Clear (); - lineh = draw.fontH; - arrow = lineh/3; -} - -Select::~Select () -{ - if (alen) { - for (int i = 0; i < alen; i++) { - delete []buf[i]; - buf[i] = NULL; - } - delete []buf; - buf = NULL; - delete []buflen; - buflen = 0; - } - if (llen) { - for (int i = 0; i < llen; i++) { - delete []lbuf[i]; - lbuf[i] = NULL; - } - delete []lbuf; - lbuf = NULL; - delete []lbuflen; - lbuflen = 0; - delete []lcur; - lcur = 0; - } -} - -void Select::Activate () -{ - DWORD viewW = g_pOrbiter->ViewW(), viewH = g_pOrbiter->ViewH(); - int i, colh, itemh; - bool submenu = false; - DWORD textW; - - // remove trailing separator - buf[len-1][0] &= ~ITEM_SEPARATOR; - - // find width of longest entry - oapi::Sketchpad *skp = gc->clbkGetSketchpad (NULL); - if (skp) { - oapi::Font *nfnt, *ofnt = 0; - - colh = 0; - surfw = lineh; // left and right frame borders - surfh = 0; - ncol = 0; - col[ncol].nitem = 0; - col[ncol].w = 0; - for (i = 0; i < len; i++) { - nfnt = (buf[i][0] & ITEM_NOHILIGHT ? draw.fontInactive : draw.fontNorm); - if (nfnt != ofnt) skp->SetFont (ofnt = nfnt); - textW = skp->GetTextWidth (buf[i]+1); - itemh = (buf[i][0] & ITEM_SEPARATOR ? lineh+3 : lineh); - if (colh + itemh + 2*lineh > viewH) { // new column - if (submenu) col[ncol].w += lineh/2+arrow; - surfw += col[ncol].w + lineh; // column and vertical divider - ncol++; - col[ncol].w = textW; - surfh = max (surfh, colh); - colh = itemh; - submenu = false; - } else { - col[ncol].w = max (col[ncol].w, (int)textW); - colh += itemh; - } - col[ncol].nitem++; - if (buf[i][0] & ITEM_SUBMENU) submenu = true; - } - if (submenu) col[ncol].w += lineh/2+arrow; - surfw += col[ncol].w; - surfh = max (surfh, colh) + lineh + 4; - - if (ofnt != draw.fontNorm) skp->SetFont (draw.fontNorm); - textW = skp->GetTextWidth (title); - if (textW+lineh > surfw) surfw = textW+lineh; - gc->clbkReleaseSketchpad (skp); - } - - X0 = (cntx >= 0 ? cntx : viewW/2) - surfw/2; - if (X0 < 0) X0 = 0; - else if (X0+surfw >= viewW) X0 = viewW-surfw-1; - Y0 = (cnty >= 0 ? cnty : viewH/2) - surfh/2; - if (Y0 < 0) Y0 = 0; - else if (Y0+surfh >= viewH) Y0 = viewH-surfh-1; +#include "imgui.h" + +Select::Select() { + active = false; + opened = false; + title = "Selection"; + currententry = nullptr; +} + +void Select::Open(const char *_title, Callbk submenu_cbk, Callbk enter_cbk, void *_userdata, int cntx, int cnty) { + title = _title; + + cbSubmenu = submenu_cbk; + cbEnter = enter_cbk; + userdata = _userdata; + + rootmenu.clear(); + currententry = &rootmenu; - // allocate and init surface - surf = gc->clbkCreateSurface (surfw, surfh); - RefreshSurface (); - SetFocus (g_pOrbiter->GetRenderWnd()); + submenu_cbk(this, 0, nullptr, _userdata); + opened = true; + active = true; } -void Select::Open (const char *_title, Callbk submenu_cbk, Callbk enter_cbk, - void *_userdata, int _cntx, int _cnty) -{ - if (surf) Clear (true); // this line was commented. why? - SetTitle (_title); - SetSubmenuCallback (submenu_cbk); - SetEnterCallback (enter_cbk); - userdata = _userdata; - cntx = _cntx, cnty = _cnty; - submenu_cbk (this, 0, 0, userdata); - Activate (); -} - -void Select::Clear (bool resetlevel) -{ - len = 0; // keep buffered entries around - cur = 0; - listw = listh = 0; - if (resetlevel) level = 0; - if (surf) { - gc->clbkReleaseSurface (surf); - surf = 0; - } -} - -void Select::MarkItem (int item) -{ - gc->clbkFillSurface (surf, 0, item*lineh, surfw, lineh, - gc->clbkGetDeviceColour (0x80, 0x80, 0x80)); - //RECT r = {0, item*lineh, surfw, item*lineh+lineh}; - //DDBLTFX bltfx; - //ZeroMemory (&bltfx, sizeof(bltfx)); - //bltfx.dwSize = sizeof(bltfx); - //bltfx.dwFillColor = GetSurfColour (0x80,0x80,0x80); - //surf->Blt (&r, NULL, NULL, DDBLT_COLORFILL, &bltfx); -} - -void Select::Display (LPDIRECTDRAWSURFACE7 pdds) -{ - if (!surf) return; // sanity check - gc->clbkBlt (0, X0, Y0, surf, 0); +void Select::Append(const char *str, int flags) { + SelectEntry e; + e.m_Flags = flags; + e.m_Text = str; + + currententry->emplace_back(e); } -void Select::RefreshSurface () -{ - if (!surf) return; // sanity check - ClearSurface (gc, surf, lineh); - - // draw list - int i, cl, item0, item1, ay, x = lineh/2, y = 2; - int subx = surfw-lineh/2-arrow; - oapi::Font *ofnt, *nfnt; - oapi::Sketchpad *skp = gc->clbkGetSketchpad (surf); - if (skp) { - skp->SetFont (ofnt = draw.fontNorm); - skp->SetBackgroundMode (oapi::Sketchpad::BK_TRANSPARENT); - skp->SetTextColor (titlecol); - skp->SetPen (draw.pen1); - skp->Text (x, y-1, title, strlen(title)), y += lineh; - cl = 0; - item0 = 0; item1 = col[0].nitem; - for (i = 0; i < len; i++) { - nfnt = (buf[i][0] & ITEM_NOHILIGHT ? draw.fontInactive : draw.fontNorm); - if (nfnt != ofnt) skp->SetFont (ofnt = nfnt); - if (i == item1) { - skp->Line (x + col[cl].w + lineh/2, lineh+2, x + col[cl].w + lineh/2, surfh); - x += col[cl].w + lineh; - subx += col[cl].w + lineh; - y = 2+lineh; - item0 = item1; - item1 += col[++cl].nitem; - } - if (i == cur) { - int x0 = x-lineh/2; - int x1 = (cl == ncol ? surfw : x0+col[cl].w+lineh); - oapi::Brush *pbrush = skp->SetBrush (draw.brushMark); - skp->Rectangle (x0+2, y, x1-2, y+lineh); - skp->SetBrush (pbrush); - } - if (i == cur) skp->SetTextColor (buf[i][0] & ITEM_NOHILIGHT ? disablehi : enablehi); - else skp->SetTextColor (buf[i][0] & ITEM_NOHILIGHT ? disablecol : enablecol); - skp->Text (x, y, buf[i]+1, strlen (buf[i]+1)); - - if (buf[i][0] & ITEM_SUBMENU) { // submenu indicator - ay = y+lineh/2; - skp->MoveTo (subx, ay-arrow); - if (i == cur) skp->SetPen (draw.pen2); - skp->LineTo (subx+arrow, ay); - skp->LineTo (subx, ay+arrow); - skp->LineTo (subx, ay-arrow); - if (i == cur) skp->SetPen (draw.pen1); - } - y += lineh; - if (buf[i][0] & ITEM_SEPARATOR) { // separator indicator - skp->Line (0, y+1, surfw, y+1); - y += 3; - } - } - skp->Rectangle (0, 0, surfw, surfh); - gc->clbkReleaseSketchpad (skp); - } -} +void Select::AppendSeparator() { + SelectEntry e; + e.m_Flags = ITEM_SEPARATOR; -int Select::Append (const char *_str, BYTE flag) -{ - if (len == alen) { // need to allocate new entry - char **ctmp = new char*[alen+1]; TRACENEW - memcpy (ctmp, buf, alen*sizeof(char*)); - if (alen) delete []buf; - buf = ctmp; - int *itmp = new int[alen+1]; TRACENEW - memcpy (itmp, buflen, alen*sizeof(int)); - if (alen) delete []buflen; - buflen = itmp; - buflen[alen++] = 0; - } - int nlen = strlen (_str)+2; // reserve space for flag and EOL - if (buflen[len] < nlen) { // need to (re)allocate space for entry - if (buflen[len]) delete []buf[len]; - buf[len] = new char[buflen[len] = nlen]; TRACENEW - } - memcpy (buf[len]+1, _str, nlen-1); - buf[len][0] = (char)flag; - listh += lineh; - if (flag & ITEM_SEPARATOR) listh += 3; - return len++; -} - -void Select::AppendSeparator () -{ - if (!len) return; - if (buf[len-1][0] & ITEM_SEPARATOR) return; // got a separator already - buf[len-1][0] |= ITEM_SEPARATOR; - listh += 3; -} - -void Select::SetTitle (const char *_title) -{ - strncpy(title, _title, select_strlen); - title[select_strlen - 1] = '\0'; -} - -void Select::Push () -{ - if (level == llen) { // grow stack - char **ctmp = new char*[llen+1]; TRACENEW - memcpy (ctmp, lbuf, llen*sizeof(char*)); - if (llen) delete []lbuf; - lbuf = ctmp; - int *itmp = new int[llen+1]; TRACENEW - memcpy (itmp, lbuflen, llen*sizeof(int)); - if (llen) delete []lbuflen; - lbuflen = itmp; - lbuflen[llen] = 0; - itmp = new int[llen+1]; TRACENEW - memcpy (itmp, lcur, llen*sizeof(int)); - if (llen) delete []lcur; - lcur = itmp; - llen++; - } - if (lbuflen[level] < buflen[cur]) { // grow stack entry - if (lbuflen[level]) delete lbuf[level]; - lbuf[level] = new char[lbuflen[level] = buflen[cur]]; TRACENEW - } - memcpy (lbuf[level], buf[cur], buflen[cur]); - lcur[level++] = cur; -} - -void Select::Pop () -{ - if (!level) return; // sanity check - cur = lcur[--level]; -} - -int Select::ConsumeKey (UINT uMsg, WPARAM wParam, WORD mod) -{ - if (!IsActive() || uMsg != WM_KEYDOWN || mod) return key_ignore; - - switch (wParam) { - case VK_RETURN: - if (!(buf[cur][0] & ITEM_NOHILIGHT) && - (!cbk_enter || cbk_enter (this, cur, buf[cur]+1, userdata))) { - Clear (true); - return key_ok; - } else return key_consume; - case VK_ESCAPE: - Clear (true); - return key_cancel; - case VK_DOWN: - if (cur < len-1) { - cur++; - RefreshSurface (); - } - return key_consume; - case VK_UP: - if (cur > 0) { - cur--; - RefreshSurface (); - } - return key_consume; - case VK_RIGHT: - if ((buf[cur][0] & ITEM_SUBMENU) && cbk_submenu) { - Push (); // push current level to stack - Clear (); - if (cbk_submenu (this, lcur[level-1], lbuf[level-1]+1, userdata)) { - Activate (); - return key_consume; - } - } else return key_ignore; - // fall through - case VK_LEFT: - if (level && cbk_submenu) { - Clear (); - Pop (); // get previous level from stack - if (level) cbk_submenu (this, lcur[level-1], lbuf[level-1]+1, userdata); - else cbk_submenu (this, 0, 0, userdata); // main menu - Activate (); - } - return key_consume; - default: - return key_ignore; - } -} - -// ======================================================================= - -SelectionList::SelectionList (oapi::GraphicsClient *gclient, HWND hwnd): InlineDialog (gclient, hwnd) -{ - clbk = 0; - userdata = 0; - listflag = 0; - list = 0; - nlist = 0; - title = 0; - lineh = draw.fontH; - arrow = lineh/3; - surf = 0; - cur = 0; + currententry->emplace_back(e); } -void SelectionList::Open (LISTENTRY *_list, DWORD _nlist, char *_title, Listentry_clbk _clbk, - DWORD flag, void *_userdata) -{ - Clear (); - - clbk = _clbk; - userdata = _userdata; - listflag = flag; - list = new LISTENTRY[nlist = _nlist]; - memcpy (list, _list, nlist*sizeof(LISTENTRY)); - - if (_title) { - title = new char[strlen(_title)+1]; - strcpy (title, _title); - } - - AllocSurface(); -} - -void SelectionList::Clear () -{ - clbk = 0; - userdata = 0; - listflag = 0; - if (nlist) { - delete []list; - list = 0; - nlist = 0; - } - if (title) { - delete []title; - title = 0; - } - if (surf) { - gc->clbkReleaseSurface (surf); - surf = 0; - } -} - -void SelectionList::AllocSurface () -{ - DWORD viewW = g_pOrbiter->ViewW(), viewH = g_pOrbiter->ViewH(); - int colh, itemh; - DWORD i, textw; - bool submenu = false; - - // remove trailing separator - list[nlist-1].flag &= ~LISTENTRY_SEPARATOR; - - // find width of longest entry - oapi::Sketchpad *skp = gc->clbkGetSketchpad (NULL); - if (skp) { - oapi::Font *nfnt, *ofnt = 0; - colh = 0; - surfw = lineh; - surfh = 0; - ncol = 0; - col[ncol].nitem = 0; - col[ncol].w = 0; - for (i = 0; i < nlist; i++) { - nfnt = (list[i].flag & LISTENTRY_INACTIVE ? draw.fontInactive : draw.fontNorm); - if (nfnt != ofnt) skp->SetFont (ofnt = nfnt); - textw = skp->GetTextWidth (list[i].name); - itemh = (list[i].flag & LISTENTRY_SEPARATOR ? lineh+3 : lineh); - if (colh + itemh + 2*lineh > viewH) { // new column - if (submenu) col[ncol].w += lineh/2+arrow; - surfw += col[ncol].w + lineh; // column and vertical divider - ncol++; - col[ncol].w = textw; - surfh = max (surfh, colh); - colh = itemh; - submenu = false; - } else { - col[ncol].w = max ((DWORD)col[ncol].w, textw); - colh += itemh; - } - col[ncol].nitem++; - if (list[i].flag & LISTENTRY_SUBITEM) submenu = true; - } - if (submenu) col[ncol].w += lineh/2+arrow; - surfw += col[ncol].w; - surfh = max (surfh, colh) + lineh + 4; - - if (ofnt != draw.fontNorm) skp->SetFont (draw.fontNorm); - textw = skp->GetTextWidth (title); - if (textw+lineh > surfw) surfw = textw+lineh; - gc->clbkReleaseSketchpad (skp); - } - - surfx = viewW/2 - surfw/2; - if (surfx < 0) surfx = 0; - else if (surfx+surfw >= viewW) surfx = viewW-surfw-1; - surfy = viewH/2 - surfh/2; - if (surfy < 0) surfy = 0; - else if (surfy+surfh >= viewH) surfy = viewH-surfh-1; - - if (surf) gc->clbkReleaseSurface (surf); - surf = gc->clbkCreateSurface (surfw, surfh); -} - -void SelectionList::RefreshSurface () -{ - if (!surf) return; // sanity check - ClearSurface (gc, surf, lineh); - - // draw list - int i, cl, item0, item1, ay, x = lineh/2, y = 2; - int subx = surfw-lineh/2-arrow; - oapi::Font *ofnt, *nfnt; - oapi::Sketchpad *skp = gc->clbkGetSketchpad (surf); - if (skp) { - skp->SetFont (ofnt = draw.fontNorm); - skp->SetBackgroundMode (oapi::Sketchpad::BK_TRANSPARENT); - skp->SetTextColor (titlecol); - skp->SetPen (draw.pen1); - skp->Text (x, y-1, title, strlen(title)), y += lineh; - cl = 0; - item0 = 0; item1 = col[0].nitem; - for (i = 0; i < nlist; i++) { - nfnt = (list[i].flag & LISTENTRY_INACTIVE ? draw.fontInactive : draw.fontNorm); - if (nfnt != ofnt) skp->SetFont (ofnt = nfnt); - if (i == item1) { - skp->Line (x + col[cl].w + lineh/2, lineh+2, x + col[cl].w + lineh/2, surfh); - x += col[cl].w + lineh; - subx += col[cl].w + lineh; - y = 2+lineh; - item0 = item1; - item1 += col[++cl].nitem; - } - if (i == cur) { - int x0 = x-lineh/2; - int x1 = (cl == ncol ? surfw : x0+col[cl].w+lineh); - oapi::Brush *pbrush = skp->SetBrush (draw.brushMark); - skp->Rectangle (x0+2, y, x1-2, y+lineh); - skp->SetBrush (pbrush); - } - if (i == cur) skp->SetTextColor (list[i].flag & LISTENTRY_INACTIVE ? disablehi : enablehi); - else skp->SetTextColor (list[i].flag & LISTENTRY_INACTIVE ? disablecol : enablecol); - skp->Text (x, y, list[i].name, strlen (list[i].name)); - - if (list[i].flag & LISTENTRY_SUBITEM) { // submenu indicator - ay = y+lineh/2; - skp->MoveTo (subx, ay-arrow); - if (i == cur) skp->SetPen (draw.pen2); - skp->LineTo (subx+arrow, ay); - skp->LineTo (subx, ay+arrow); - skp->LineTo (subx, ay-arrow); - if (i == cur) skp->SetPen (draw.pen1); - } - y += lineh; - if (list[i].flag & LISTENTRY_SEPARATOR) { // separator indicator - skp->Line (0, y+1, surfw, y+1); - y += 3; - } - } - skp->Rectangle (0, 0, surfw, surfh); - gc->clbkReleaseSketchpad (skp); - } -} - -// ======================================================================= - -InputBox::InputBox (oapi::GraphicsClient *gclient, HWND hwnd, int _buflen): InlineDialog (gclient, hwnd) -{ - buflen = _buflen; - titlelen = 20; // can grow as required - title = new char[titlelen+1]; title[0] = '\0'; TRACENEW - buf = new char[buflen+1]; buf[0] = '\0'; TRACENEW - slen = vis0 = cur = 0; - vislen = 20; // arbitrary default - surf = 0; - cbk_enter = 0; - cbk_cancel = 0; - userdata = 0; - lineh = draw.fontH; - cw = g_gdires->dlgF2W; // replace this! -} - -InputBox::~InputBox () -{ - delete []buf; - buf = NULL; - delete []title; - title = NULL; -} - -void InputBox::SetTitle (const char *_title) -{ - int len = (_title ? strlen(_title) : 0); - if (len > titlelen) { - if (titlelen) delete []title; - title = new char[(titlelen=len)+1]; TRACENEW - } - if (len) strcpy (title, _title); - else title[0] = '\0'; -} - -void InputBox::InitBuffer (int _vislen, char *_buf) -{ - vislen = _vislen; - vis0 = 0; - if (_buf) { - slen = cur = strlen(_buf); - strcpy (buf, _buf); - } else { - slen = cur = 0; - buf[0] = '\0'; - } -} - -void InputBox::Activate (int cntx, int cnty) -{ - DWORD viewW = g_pOrbiter->ViewW(), viewH = g_pOrbiter->ViewH(); - DWORD textW; - oapi::Sketchpad *skp = gc->clbkGetSketchpad (NULL); - if (skp) { - skp->SetFont (draw.fontNorm); - textW = skp->GetTextWidth (title); - surfw = textW + lineh; - boxw = cw*vislen; - if (boxw+lineh > surfw) surfw = boxw+lineh; - surfh = 4*lineh; - gc->clbkReleaseSketchpad (skp); - } - X0 = (cntx >= 0 ? cntx : viewW/2) - surfw/2; - if (X0 < 0) X0 = 0; - else if (X0+surfw >= viewW) X0 = viewW-surfw-1; - Y0 = (cnty >= 0 ? cnty : viewH/2) - surfh/2; - if (Y0 < 0) Y0 = 0; - else if (Y0+surfh >= viewH) Y0 = viewH-surfh-1; - - // allocate and init surface - if (surf) gc->clbkReleaseSurface (surf); - surf = gc->clbkCreateSurface (surfw, surfh); - RefreshSurface (); -} - -void InputBox::Open (const char *_title, char *_buf, int _vislen, - Callbk cbk, void *_userdata, int cntx, int cnty) -{ - OpenEx (_title, _buf, _vislen, cbk, 0, _userdata, 0, cntx, cnty); -} - -bool InputBox::OpenEx (const char *_title, char *_buf, int _vislen, - Callbk enter_cbk, Callbk cancel_cbk, void *_userdata, DWORD flags, int cntx, int cnty) -{ - if (surf) { - if (flags & USRINPUT_NEEDANSWER) return false; - // can't open new input box if currently open one requires an answer - if (cbk_cancel) cbk_cancel (this, buf, userdata); - Close(); - } - SetTitle (_title); - InitBuffer (_vislen, _buf); - SetEnterCallback (enter_cbk); - cbk_cancel = cancel_cbk; - flag = flags; - userdata = _userdata; - Activate (cntx, cnty); - return true; -} - -bool InputBox::Close (bool onEnter) -{ - if (!onEnter && (flag & USRINPUT_NEEDANSWER)) return false; - if (surf) { - gc->clbkReleaseSurface (surf); - surf = 0; - } - userdata = 0; - return true; -} - -void InputBox::RefreshSurface () -{ - if (!surf) return; // sanity check - ClearSurface (gc, surf, lineh); - - oapi::Sketchpad *skp = gc->clbkGetSketchpad (surf); - if (skp) { - int x = lineh/2, y = 2; - skp->SetFont (draw.fontNorm); - skp->SetPen (draw.pen1); - skp->SetBackgroundMode (oapi::Sketchpad::BK_TRANSPARENT); - skp->SetTextColor (titlecol); - skp->Text (x, y-1, title, strlen(title)); y += 2*lineh; - skp->SetTextColor (enablecol); - skp->SetFont (draw.fontInput); - int n = slen-vis0; - if (n > vislen) n = vislen; - skp->Text (x, y, buf+vis0, n); - skp->SetBackgroundMode (oapi::Sketchpad::BK_OPAQUE); - skp->SetTextColor (0); - skp->Text (x+(cur-vis0)*cw, y, cur < slen ? buf+cur : " ", 1); - skp->Rectangle (0, 0, surfw, surfh); - skp->Rectangle (x-2, y-2, x+boxw+2, y+lineh+2); - gc->clbkReleaseSketchpad (skp); - } -} - -void InputBox::Display (LPDIRECTDRAWSURFACE7 pdds) -{ - if (!surf) return; // sanity check - gc->clbkBlt (0, X0, Y0, surf, 0); - //pdds->BltFast (X0, Y0, surf, NULL, DDBLTFAST_WAIT); -} - -int InputBox::ConsumeKey (UINT uMsg, WPARAM wParam, WORD mod) -{ - int i; - - if (!IsActive()) return key_ignore; - - switch (uMsg) { - case WM_CHAR: - if (isgraph(wParam) || wParam == VK_SPACE) { - if (slen < buflen) { - for (i = slen; i >= cur; i--) buf[i+1] = buf[i]; - buf[cur] = wParam; - slen++; - if (++cur == vislen+vis0) vis0++; - RefreshSurface(); - } - return key_consume; - } - return key_ignore; - case WM_KEYDOWN: - if (!mod) { - switch (wParam) { - case VK_RETURN: - if (!cbk_enter || cbk_enter (this, buf, userdata)) { - Close (true); - return key_ok; - } else { - MessageBeep (-1); - return key_consume; - } - case VK_ESCAPE: - if (flag & USRINPUT_NEEDANSWER) { - return key_consume; - } else { - if (cbk_cancel) cbk_cancel (this, buf, userdata); - Close (); - return key_cancel; - } - case VK_LEFT: - if (cur > 0) { - if (--cur < vis0) vis0 = cur; - RefreshSurface(); - } - return key_consume; - case VK_RIGHT: - if (cur < slen) { - if (++cur == vislen+vis0) vis0++; - RefreshSurface(); - } - return key_consume; - case VK_BACK: - if (cur > 0) { - for (i = cur; i <= slen; i++) buf[i-1] = buf[i]; - slen--; - if (--cur < vis0) vis0 = cur; - RefreshSurface(); - } - return key_consume; - case VK_DELETE: - if (cur < slen) { - for (i = cur+1; i <= slen; i++) buf[i-1] = buf[i]; - slen--; - RefreshSurface(); - } - return key_consume; - case VK_HOME: - if (cur > 0) { - cur = 0; - if (vis0 > 0) vis0 = 0; - RefreshSurface(); - } - return key_consume; - case VK_END: - if (cur < slen) { - if ((cur = slen) >= vislen+vis0) vis0 = cur-vislen+1; - RefreshSurface(); - } - return key_consume; - default: - // trap unmodified and shift keys - if (!(mod & 0x02)) return key_consume; - break; - } - } - } - return key_ignore; -} - -// ======================================================================= -// auxiliary routines - -#ifdef UNDEF -SURFHANDLE AllocSurface (oapi::GraphicsClient *gc, int w, int h) -{ - return NULL; -} -#endif - -void ReleaseSurface (LPDIRECTDRAWSURFACE7 &surf) -{ - if (surf) { - surf->Release (); - surf = 0; - } -} - -void ClearSurface (oapi::GraphicsClient *gc, SURFHANDLE surf, int h) -{ - gc->clbkFillSurface (surf, gc->clbkGetDeviceColour (0x50, 0x50, 0x50)); - //DDBLTFX bltfx; - //ZeroMemory (&bltfx, sizeof(bltfx)); - //bltfx.dwSize = sizeof(bltfx); - //bltfx.dwFillColor = GetSurfColour (0x50,0x50,0x50); - //surf->Blt (NULL, NULL, NULL, DDBLT_COLORFILL, &bltfx); - - if (h) { // paint title bar - DWORD width, height; - gc->clbkGetSurfaceSize (surf, &width, &height); - gc->clbkFillSurface (surf, 0, 0, width, h+1, - gc->clbkGetDeviceColour (0x60, 0x20, 0x20)); - //DDSURFACEDESC2 ddsd; - //ddsd.dwSize = sizeof(ddsd); - //surf->GetSurfaceDesc (&ddsd); - //RECT r = {0, 0, ddsd.dwWidth, h+1}; - //bltfx.dwFillColor = GetSurfColour (0x60,0x20,0x20); - //surf->Blt (&r, NULL, NULL, DDBLT_COLORFILL, &bltfx); - } +void Select::DrawMenu(std::list& entries) { + int i = 0; + for (auto& e : entries) { + if (e.m_Flags & ITEM_SEPARATOR) { + ImGui::Separator(); + } + else if (e.m_Flags & ITEM_SUBMENU) { + if (e.m_SubEntries.size() == 0) { + currententry = &e.m_SubEntries; + cbSubmenu(this, i, const_cast(e.m_Text.c_str()), userdata); + } + if (ImGui::BeginMenu(e.m_Text.c_str(), e.m_SubEntries.size() != 0)) { + DrawMenu(e.m_SubEntries); + ImGui::EndMenu(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly) && !(e.m_Flags & ITEM_NOHILIGHT)) { + if (ImGui::IsMouseReleased(0)) { + cbEnter(this, i, const_cast(e.m_Text.c_str()), userdata); + active = false; + ImGui::CloseCurrentPopup(); + } + } + } + i++; + } + else { + if (ImGui::MenuItem(e.m_Text.c_str())) { + cbEnter(this, i, const_cast(e.m_Text.c_str()), userdata); + active = false; + } + i++; + } + } +} + +void Select::Draw() { + auto& io = ImGui::GetIO(); + + if (io.MouseDown[0] && opened) { + return; + } + + if (opened) { + ImGui::OpenPopup(title.c_str()); + opened = false; + } + + if (ImGui::BeginPopup(title.c_str())) + { + ImGui::TextUnformatted(title.c_str()); + ImGui::Separator(); + DrawMenu(rootmenu); + ImGui::EndPopup(); + } + else { + active = false; + } +} + +InputBox::InputBox() { + active = false; + opened = false; + title = "InputBox"; +} + +void InputBox::Open(const char *_title, char *_buf, int _vislen, + Callbk cbk, void *_userdata, int cntx, int cnty) +{ + OpenEx(_title, _buf, _vislen, cbk, 0, _userdata, 0, cntx, cnty); +} + +bool InputBox::OpenEx(const char *_title, char *_buf, int _vislen, + Callbk enter_cbk, Callbk cancel_cbk, void *_userdata, + int flags, int cntx, int cnty) { + + title = _title; + + cbEnter = enter_cbk; + cbCancel = cancel_cbk; + userdata = _userdata; + + opened = true; + active = true; + + if (_buf) + strcpy(inputbuf, _buf); + else + inputbuf[0] = '\0'; + + return true; +} + +void InputBox::Draw() { + char buf[256]; + sprintf(buf, "%s###InputBox", title.c_str()); + + bool firstTime = false; + if (opened) { + ImGui::OpenPopup(buf); + opened = false; + firstTime = true; + } + + if (ImGui::BeginPopup(buf)) + { + ImGui::TextUnformatted(title.c_str()); + ImGui::Separator(); + ImGui::SetNextItemWidth(-FLT_MIN); + if (firstTime) + ImGui::SetKeyboardFocusHere(); + bool entered = ImGui::InputText("##InputText", inputbuf, IM_ARRAYSIZE(inputbuf), ImGuiInputTextFlags_EnterReturnsTrue); + + if (ImGui::Button("OK") || entered) { + cbEnter(this, inputbuf, userdata); + ImGui::CloseCurrentPopup(); + active = false; + } + ImGui::SameLine(); + if (ImGui::Button("Cancel")) { + if (cbCancel) + cbCancel(this, inputbuf, userdata); + ImGui::CloseCurrentPopup(); + active = false; + } + ImGui::EndPopup(); + } + else { + active = false; + } } diff --git a/Src/Orbiter/Select.h b/Src/Orbiter/Select.h index f1f4c31ba..181953302 100644 --- a/Src/Orbiter/Select.h +++ b/Src/Orbiter/Select.h @@ -4,215 +4,57 @@ #ifndef __SELECT_H #define __SELECT_H -#define STRICT 1 -#include -#include #include "OrbiterAPI.h" #include "GraphicsAPI.h" +#include #define ITEM_SUBMENU 0x01 #define ITEM_NOHILIGHT 0x02 #define ITEM_SEPARATOR 0x04 -const int select_strlen = 100; -const int select_chunk = 32; -const int select_maxlevel = 10; -const int maxcol = 20; - -// ======================================================================= -// Base class for inline dialog box resources - -class InlineDialog { -public: - InlineDialog (oapi::GraphicsClient *gclient, HWND hwnd); - virtual ~InlineDialog(); - - // initialise global drawing resources - static void GlobalInit (oapi::GraphicsClient *gclient); - - // release global drawing resources - static void GlobalExit (oapi::GraphicsClient *gclient); - -protected: - static struct DRAWRESRC { // global drawing resources - oapi::Pen *pen1, *pen2; - oapi::Brush *brushMark; - oapi::Font *fontNorm, *fontInactive, *fontInput; - int fontH; - } draw; - - oapi::GraphicsClient *gc; // graphics client instance - HWND hWnd; // render window handle +struct SelectEntry { + int m_Flags; + std::string m_Text; + std::list m_SubEntries; }; -// ======================================================================= -// menu dialog box - -class Select: public InlineDialog { +class Select : public DialogImGui { public: - Select (oapi::GraphicsClient *gclient, HWND hwnd); - ~Select (); - void Activate (); - void Clear (bool resetlevel = false); - void Display (LPDIRECTDRAWSURFACE7 pdds); - bool IsActive() { return (len > 0); } - int Len() const { return len; } - int Cur() const { return cur; } - char *Str (int i) const { return buf[i]+1; } - int ParentCur () const { return (level > 0 ? lcur[level-1] : 0); } - const char *ParentStr () const { return (level > 0 ? lbuf[level-1]+1 : 0); } - const char *StackStr (int lev) { return (lev >= 0 && lev < level ? lbuf[lev]+1 : 0); } - bool HasSubmenu (int i) const { return buf[i][0] & 0x01; } - int Level() const { return level; } - int Append (const char *_str, BYTE flag = 0); - void AppendSeparator (); - void SetTitle (const char *_title); - const char *Title () const { return title; } - int ConsumeKey (UINT uMsg, WPARAM wParam, WORD mod = 0); - enum { key_ignore, key_consume, key_ok, key_cancel }; - typedef bool (*Callbk)(Select*, int, char*, void*); - void SetSubmenuCallback (Callbk cbk) { cbk_submenu = cbk; } - void SetEnterCallback (Callbk cbk) { cbk_enter = cbk; } - - void Open (const char *_title = 0, Callbk submenu_cbk = 0, Callbk enter_cbk = 0, - void *_userdata = 0, int cntx = -1, int cnty = -1); - // activates the menu with the specified parameters (menu items must have - // been added with Append before) - -private: - void RefreshSurface (); - void MarkItem (int item); - void Push (); - void Pop (); - - SURFHANDLE surf; // drawing surface - int surfw, surfh; // surface dimensions - int cntx, cnty; // centre coords - int X0, Y0; // upper left corner of input box - int lineh; // font height - int arrow; // arrow size - int listw; // pixel width of longest list entry - int listh; // pixel height of full list (w/o title) - int len; // number of active entries - int alen; // number of allocated entries - struct COL { // column specs - int nitem; // # items in column - int w; // column width - } col[maxcol]; - int ncol; // # columns - int llen; // level stack size - int level; // current submenu level (0=top level) - int cur; // selected entry index - int *lcur; // entry index stack (length llen) - char **buf; // array of string buffers (length alen) - int *buflen; // array buffer sizes (length alen); - char **lbuf; // entry stack (length llen); - int *lbuflen; // array of stack entry sizes (length llen) - char title[select_strlen]; - void *userdata; - Callbk cbk_submenu; - Callbk cbk_enter; + typedef bool (*Callbk)(Select*, int, char*, void*); + Select(); + void Draw() override; + bool opened; + std::string title; + std::list rootmenu; + std::list *currententry; + Callbk cbSubmenu; + Callbk cbEnter; + void *userdata; + + void Open(const char *_title = 0, Callbk submenu_cbk = 0, Callbk enter_cbk = 0, void *_userdata = 0, int cntx = -1, int cnty = -1); + void Append(const char *str, int flags = 0); + void AppendSeparator(); + void DrawMenu(std::list& entries); }; -// ======================================================================= -// selection list - -class SelectionList: public InlineDialog { +class InputBox : public DialogImGui { public: - SelectionList (oapi::GraphicsClient *gclient, HWND hwnd); - - void Open (LISTENTRY *list, DWORD nlist, char *_title, Listentry_clbk _clbk, - DWORD flag = 0, void *_userdata = 0); - - void Clear(); - -private: - void AllocSurface(); - void RefreshSurface(); - - Listentry_clbk clbk; - void *userdata; - DWORD listflag; - LISTENTRY *list; // entries in selection list - DWORD nlist; // number of entries - char *title; - SURFHANDLE surf; // drawing surface - int surfw, surfh; // surface dimensions - int surfx, surfy; // display location - int lineh; // font height - int arrow; // arrow size - int cur; // selected entry index - int ncol; // number of columns - struct COL { // column specs - int nitem; // # items in column - int w; // column width - } col[maxcol]; -}; - -// ======================================================================= -// text input dialog box - -class InputBox: public InlineDialog { -public: - InputBox (oapi::GraphicsClient *gclient, HWND hwnd, int _buflen); - // construct an input box resource for hwnd, allocating - // an input buffer of size _buflen - - ~InputBox (); - - typedef bool (*Callbk)(InputBox*, char*, void*); - // template for callback function. Returns pointer to calling input box, - // input box string and user-defined data - - void SetTitle (const char *_title); - void InitBuffer (int _vislen, char *str); - - void Activate (int cntx = -1, int cnty = -1); - // activate intput box centered at position cntx, cnty (default is viewport centre) - - bool IsActive() { return (surf != 0); } - - void Display (LPDIRECTDRAWSURFACE7 pdds); - // copy input box onto viewport surface - - enum { key_ignore, key_consume, key_ok, key_cancel }; - - int ConsumeKey (UINT uMsg, WPARAM wParam, WORD mod = 0); - // Processes WM_CHAR and WM_KEYDOWN messages - - void SetEnterCallback (Callbk cbk) { cbk_enter = cbk; } - // set callback function for accepting input - - void Open (const char *_title = 0, char *_buf = 0, int _vislen = 20, - Callbk cbk = 0, void *_userdata = 0, int cntx = -1, int cnty = -1); - // activates the input box with the specified parameters - // combines SetTitle, InitBuffer, SetEnterCallback and Activate - - bool OpenEx (const char *_title = 0, char *_buf = 0, int _vislen = 20, - Callbk enter_cbk = 0, Callbk cancel_cbk = 0, void *_userdata = 0, - DWORD flags = 0, int cntx = -1, int cnty = -1); - // This version also provides a callback function for cancelling the - // input box - - bool Close (bool onEnter = false); - // de-activates the input box - -private: - void RefreshSurface (); - - SURFHANDLE surf; // drawing surface - int surfw, surfh; // surface dimensions - int X0, Y0; // upper left corner of input box - int lineh; // font height - int boxw; // input box width - int cw; // fixed character width - char *title, *buf; - int titlelen, buflen, vislen, vis0, slen; - int cur; // cursor position - void *userdata; - DWORD flag; - Callbk cbk_enter; - Callbk cbk_cancel; + typedef bool (*Callbk)(InputBox*, char*, void*); + InputBox(); + void Draw() override; + bool opened; + std::string title; + Callbk cbEnter; + Callbk cbCancel; + void *userdata; + char inputbuf[128]; + + void Open(const char *_title = 0, char *_buf = 0, int _vislen = 20, + Callbk cbk = 0, void *_userdata = 0, int cntx = -1, int cnty = -1); + + bool OpenEx(const char *_title = 0, char *_buf = 0, int _vislen = 20, + Callbk enter_cbk = 0, Callbk cancel_cbk = 0, void *_userdata = 0, + int flags = 0, int cntx = -1, int cnty = -1); }; -#endif // !__SELECT_H \ No newline at end of file +#endif From a55858ce58733095d8bb8b56c282b79268892e9f Mon Sep 17 00:00:00 2001 From: Gondos Date: Wed, 15 Jan 2025 20:34:08 +0100 Subject: [PATCH 03/51] [ImGui]Add support in OAPI --- Extern/imgui/CMakeLists.txt | 5 +++++ Orbitersdk/include/OrbiterAPI.h | 15 +++++++++++++++ Src/Orbiter/OrbiterAPI.cpp | 11 +++++++++++ 3 files changed, 31 insertions(+) diff --git a/Extern/imgui/CMakeLists.txt b/Extern/imgui/CMakeLists.txt index c7ef5f598..578fe683d 100644 --- a/Extern/imgui/CMakeLists.txt +++ b/Extern/imgui/CMakeLists.txt @@ -14,3 +14,8 @@ FetchContent_MakeAvailable(imgui) install(FILES ${imgui_SOURCE_DIR}/misc/fonts/Roboto-Medium.ttf DESTINATION ${ORBITER_INSTALL_ROOT_DIR} ) + +install(FILES ${imgui_SOURCE_DIR}/imgui.h ${imgui_SOURCE_DIR}/imconfig.h + DESTINATION ${ORBITER_INSTALL_SDK_DIR}/include +) + diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index d2f24c2bd..7229a4584 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -120,6 +120,7 @@ class VESSEL; class CELBODY; class ExternMFD; class Interpreter; +class DialogImGui; namespace oapi { class Module; @@ -6033,6 +6034,14 @@ OAPIFUNC bool oapiUnregisterCustomCmd (int cmdId); */ OAPIFUNC HWND oapiOpenDialog (HINSTANCE hDLLInst, int resourceId, DLGPROC msgProc, void *context = 0); + /** + * \brief Open a dialog box specified by a DialogImGui object. + * \param dlg pointer to a DialogImGui object responsible for drawing the dialog box. + * \note Only one instance of a dialog box can be open at a time. A second call to + * oapiOpenDialog() with the same dialog will do nothing. + */ +OAPIFUNC void oapiOpenDialog (DialogImGui *dlg); + /** * \brief Open a dialog box defined as a Windows resource. This version provides additional * functionality compared to oapiOpenDialog(). @@ -6072,6 +6081,12 @@ OAPIFUNC HWND oapiFindDialog (HINSTANCE hDLLInst, int resourceId); */ OAPIFUNC void oapiCloseDialog (HWND hDlg); + /** + * \brief Close a dialog box. + * \param dlg object pointer that was used to open the dialog box. + */ +OAPIFUNC void oapiCloseDialog (DialogImGui *dlg); + /** * \brief Retrieves the context pointer of a dialog box which has been defined during the call to oapiOpenDialog(). * \param hDlg dialog window handle diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index 78464c29e..39cdd55cd 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -2159,6 +2159,12 @@ DLLEXPORT HWND oapiOpenDialogEx (HINSTANCE hDLLInst, int resourceId, DLGPROC msg return g_pOrbiter->OpenDialogEx (hDLLInst, resourceId, msgProc, flag, context); } +DLLEXPORT void oapiOpenDialog(DialogImGui *e) +{ + g_pOrbiter->DlgMgr()->AddEntry(e); + e->Activate(); +} + DLLEXPORT HWND oapiFindDialog (HINSTANCE hDLLInst, int resourceId) { return g_pOrbiter->IsDialog (hDLLInst, resourceId); @@ -2169,6 +2175,11 @@ DLLEXPORT void oapiCloseDialog (HWND hDlg) g_pOrbiter->CloseDialog (hDlg); } +DLLEXPORT void oapiCloseDialog(DialogImGui *e) +{ + g_pOrbiter->DlgMgr()->DelEntry(e); +} + DLLEXPORT void *oapiGetDialogContext (HWND hDlg) { DialogManager *dlgmgr = g_pOrbiter->DlgMgr(); From 52926e64deea6a30530cdaad833e4a2580071549 Mon Sep 17 00:00:00 2001 From: Gondos Date: Fri, 17 Jan 2025 20:43:05 +0100 Subject: [PATCH 04/51] [ImGui]Declare as a cmake INTERFACE + initialise DlgMgr before loading the scenario to prevent calling oapiOpenDialog before it exists --- Extern/imgui/CMakeLists.txt | 5 +++++ Src/Orbiter/Orbiter.cpp | 36 ++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Extern/imgui/CMakeLists.txt b/Extern/imgui/CMakeLists.txt index 578fe683d..e27301649 100644 --- a/Extern/imgui/CMakeLists.txt +++ b/Extern/imgui/CMakeLists.txt @@ -19,3 +19,8 @@ install(FILES ${imgui_SOURCE_DIR}/imgui.h ${imgui_SOURCE_DIR}/imconfig.h DESTINATION ${ORBITER_INSTALL_SDK_DIR}/include ) +add_library(imgui INTERFACE) + +set(IMGUI_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include) +file(COPY ${imgui_SOURCE_DIR}/imgui.h ${imgui_SOURCE_DIR}/imconfig.h DESTINATION ${IMGUI_INCLUDE_DIR}) +target_include_directories(imgui INTERFACE ${IMGUI_INCLUDE_DIR}) diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index c100f549c..01508cf79 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -714,6 +714,24 @@ HWND Orbiter::CreateRenderWindow (Config *pCfg, const char *scenario) plZ4 = 1; // invalidate } + if (gclient) { + // GDI resources - NOT VALID FOR ALL CLIENTS! + InitializeGDIResources (hRenderWnd); + pDlgMgr = new DialogManager (this, hRenderWnd); + + // global dialog resources + g_select = new Select(); TRACENEW + pDlgMgr->AddEntry(g_select); + g_input = new InputBox(); TRACENEW + pDlgMgr->AddEntry(g_input); + + // playback screen annotation manager + snote_playback = gclient->clbkCreateAnnotation (); + } + else { + pDlgMgr = new DialogManager(this, m_pConsole->WindowHandle()); + } + // read simulation environment state strcpy (ScenarioName, scenario); g_qsaveid = 0; @@ -757,24 +775,6 @@ HWND Orbiter::CreateRenderWindow (Config *pCfg, const char *scenario) } LOGOUT ("Finished initialising camera"); - if (gclient) { - // GDI resources - NOT VALID FOR ALL CLIENTS! - InitializeGDIResources (hRenderWnd); - pDlgMgr = new DialogManager (this, hRenderWnd); - - // global dialog resources - g_select = new Select(); TRACENEW - pDlgMgr->AddEntry(g_select); - g_input = new InputBox(); TRACENEW - pDlgMgr->AddEntry(g_input); - - // playback screen annotation manager - snote_playback = gclient->clbkCreateAnnotation (); - } - else { - pDlgMgr = new DialogManager(this, m_pConsole->WindowHandle()); - } - bSession = true; bVisible = (hRenderWnd != NULL); bRunning = bRequestRunning = true; From fdc7699ab512832dfe90b64af4dc26765613107e Mon Sep 17 00:00:00 2001 From: Gondos Date: Fri, 24 Jan 2025 17:06:28 +0100 Subject: [PATCH 05/51] [ImGui][test]Demo for Graphics dialog --- OVP/D3D9Client/D3D9Config.h | 16 +- OVP/D3D9Client/DebugControls.cpp | 332 +++++-------------------------- OVP/D3D9Client/DebugControls.h | 2 + 3 files changed, 63 insertions(+), 287 deletions(-) diff --git a/OVP/D3D9Client/D3D9Config.h b/OVP/D3D9Client/D3D9Config.h index c23be7f34..8f10ce7f2 100644 --- a/OVP/D3D9Client/D3D9Config.h +++ b/OVP/D3D9Client/D3D9Config.h @@ -54,7 +54,7 @@ class D3D9Config { double Separation; ///< StereoScopic 3D depth of field separation \[m\] (10.0...100.0, default=65) double SunAngle; ///< Sun-angle above horizon when night-lights set it \[deg\] (0.1...20.0, default=10) double BumpAmp; ///< Bump map amplification setting (0.1...10.0, default=1) - double PlanetGlow; ///< Intensity of planet glow effect (0.01...2.0, default=0.7) + float PlanetGlow; ///< Intensity of planet glow effect (0.01...2.0, default=0.7) double FrameRate; ///< Frame-rate limiter double OrbitalShadowMult; ///< Multiplier for cloud shadows for Orbital flight int EnableLimiter; ///< Enable frame-rate limiter @@ -100,13 +100,13 @@ class D3D9Config { int NoPlanetAA; ///< Disable planet surface anti-aliasing to prevent white pixels at horizon char *DebugFont; ///< Font face for debug lines (default="Fixed") char *SolCfg; ///< Solar system to use (default="Sol") - double GFXIntensity; ///< Post Processing | Light glow intensity (0.0...1.0, default=0.5) - double GFXDistance; ///< Post Processing | Light glow distance (0.0...1.0, default=0.8) - double GFXThreshold; ///< Post Processing | Glow threshold (0.5...2.0, default=1.1) - double GFXGamma; ///< Post Processing | Gamma (0.3...2.5, default=1.0) - double GFXSunIntensity; ///< Light Configuration| Sunlight Intensity (0.5...2.5, default=1.2) - double GFXLocalMax; ///< Light Configuration| Local Lights Max (0.001...1.0, default=0.5) - double GFXGlare; ///< Sun glare intensity| (0.001...1.0, default=0.5) + float GFXIntensity; ///< Post Processing | Light glow intensity (0.0...1.0, default=0.5) + float GFXDistance; ///< Post Processing | Light glow distance (0.0...1.0, default=0.8) + float GFXThreshold; ///< Post Processing | Glow threshold (0.5...2.0, default=1.1) + float GFXGamma; ///< Post Processing | Gamma (0.3...2.5, default=1.0) + float GFXSunIntensity; ///< Light Configuration| Sunlight Intensity (0.5...2.5, default=1.2) + float GFXLocalMax; ///< Light Configuration| Local Lights Max (0.001...1.0, default=0.5) + float GFXGlare; ///< Sun glare intensity| (0.001...1.0, default=0.5) std::map AtmoCfg; diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index dad0ce16e..e364f1937 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -18,6 +18,7 @@ #include "MaterialMgr.h" #include "VectorHelpers.h" #include +#include enum scale { LIN, SQRT, SQR }; @@ -40,7 +41,7 @@ float cpr, cpg, cpb, cpa; double resbias = 4.0; char visual[64]; int origwidth; -HWND hGfxDlg = NULL; +GFXDialog *gfxDlg; HWND hDlg = NULL; HWND hDataWnd = NULL; vObject *vObj = NULL; @@ -57,10 +58,53 @@ char OpenFileName[255]; char SaveFileName[255]; void UpdateMaterialDisplay(bool bSetup=false); -void SetGFXSliders(); -INT_PTR CALLBACK WndProcGFX(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + void OpenGFXDlgClbk(void *context); +class GFXDialog: public DialogImGui +{ + // Resettable slider from https://github.com/ocornut/imgui/issues/1751 + static bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format = "%.3f") + { + bool ret = ImGui::SliderFloat(label, v, v_min, v_max, display_format); + if (ImGui::BeginPopupContextItem(label)) + { + char buf[64]; + sprintf(buf, "Reset to %f", v_default); + if (ImGui::MenuItem(buf)) + *v = v_default; + ImGui::MenuItem("Close"); + ImGui::EndPopup(); + } + return ret; + } +public: + void Draw() { + if(ImGui::Begin("Graphics controls", &active)) { + ImGui::PushItemWidth(150.0); + ImGui::SeparatorText("Post Processing Configuration"); + + SliderFloatReset("Light glow intensity", &Config->GFXIntensity, 0.0f, 1.0f, 0.5f, "%1.2f"); + SliderFloatReset("Light glow distance", &Config->GFXDistance, 0.0f, 1.0f, 0.8f, "%1.2f"); + SliderFloatReset("Glow threshold", &Config->GFXThreshold, 0.0f, 1.1f, 1.1f, "%1.2f"); + SliderFloatReset("Gamma", &Config->GFXGamma, 0.0f, 1.0f, 1.0f, "%1.2f"); + + ImGui::SeparatorText("Light Configuration"); + + SliderFloatReset("Sunlight Intensity", &Config->GFXSunIntensity, 0.0f, 1.0f, 1.2f, "%1.2f"); + SliderFloatReset("Indirect Lighting", &Config->PlanetGlow, 0.0f, 1.0f, 1.0f, "%1.2f"); + SliderFloatReset("Local Lights Max", &Config->GFXLocalMax, 0.0f, 1.0f, 0.5f, "%1.2f"); + SliderFloatReset("Sun Glare Intensity", &Config->GFXGlare, 0.0f, 1.0f, 0.3f, "%1.2f"); + + if(ImGui::Button("Recrete Sun/Glares")) { + g_client->GetScene()->CreateSunGlare(); + } + ImGui::PopItemWidth(); + } + ImGui::End(); + } +}; + struct _Variable { float min, max, extmax, def; @@ -158,7 +202,6 @@ void Create() { vObj = NULL; hDlg = NULL; - hGfxDlg = NULL; nMesh = 0; nGroup = 0; sMesh = 0; @@ -179,7 +222,8 @@ void Create() dwCmd = 0; } - dwGFX = oapiRegisterCustomCmd((char*)"D3D9 Graphics Controls", (char*)"This dialog allows to control various graphics options", OpenGFXDlgClbk, NULL); + gfxDlg = new GFXDialog; + dwGFX = oapiRegisterCustomCmd((char*)"D3D9 Graphics Controls", (char*)"This dialog allows to control various graphics options", OpenGFXDlgClbk, gfxDlg); resbias = 4.0 + Config->LODBias; @@ -269,7 +313,8 @@ void Release() { vObj = NULL; hDlg = NULL; - hGfxDlg = NULL; + delete gfxDlg; + gfxDlg = NULL; if (dwCmd) oapiUnregisterCustomCmd(dwCmd); if (dwGFX) oapiUnregisterCustomCmd(dwGFX); dwCmd = NULL; @@ -2059,285 +2104,14 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return oapiDefDialogProc(hWnd, uMsg, wParam, lParam); } - - - - - -// ============================================================================================= -// -void CloseGFX() -{ - if (hGfxDlg != NULL) { - oapiCloseDialog(hGfxDlg); - hGfxDlg = NULL; - } -} - // ============================================================================================= // void OpenGFXDlgClbk(void *context) { - HWND l_hDlg = oapiOpenDialog(g_hInst, IDD_GRAPHICS, WndProcGFX); - if (l_hDlg) hGfxDlg = l_hDlg; // otherwise open already - else return; - - // slider - SendDlgItemMessage(hGfxDlg, IDC_GFX_INTENSITY, TBM_SETRANGEMAX, 1, 255); - SendDlgItemMessage(hGfxDlg, IDC_GFX_INTENSITY, TBM_SETRANGEMIN, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_INTENSITY, TBM_SETTICFREQ, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_INTENSITY, TBM_SETPOS, 1, 0); - - // slider - SendDlgItemMessage(hGfxDlg, IDC_GFX_DISTANCE, TBM_SETRANGEMAX, 1, 255); - SendDlgItemMessage(hGfxDlg, IDC_GFX_DISTANCE, TBM_SETRANGEMIN, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_DISTANCE, TBM_SETTICFREQ, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_DISTANCE, TBM_SETPOS, 1, 0); - - // slider - SendDlgItemMessage(hGfxDlg, IDC_GFX_THRESHOLD, TBM_SETRANGEMAX, 1, 255); - SendDlgItemMessage(hGfxDlg, IDC_GFX_THRESHOLD, TBM_SETRANGEMIN, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_THRESHOLD, TBM_SETTICFREQ, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_THRESHOLD, TBM_SETPOS, 1, 0); - - // slider - SendDlgItemMessage(hGfxDlg, IDC_GFX_GAMMA, TBM_SETRANGEMAX, 1, 255); - SendDlgItemMessage(hGfxDlg, IDC_GFX_GAMMA, TBM_SETRANGEMIN, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_GAMMA, TBM_SETTICFREQ, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_GAMMA, TBM_SETPOS, 1, 0); - - // slider - SendDlgItemMessage(hGfxDlg, IDC_GFX_SUNLIGHT, TBM_SETRANGEMAX, 1, 255); - SendDlgItemMessage(hGfxDlg, IDC_GFX_SUNLIGHT, TBM_SETRANGEMIN, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_SUNLIGHT, TBM_SETTICFREQ, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_SUNLIGHT, TBM_SETPOS, 1, 0); - - // slider - SendDlgItemMessage(hGfxDlg, IDC_GFX_IRRADIANCE, TBM_SETRANGEMAX, 1, 255); - SendDlgItemMessage(hGfxDlg, IDC_GFX_IRRADIANCE, TBM_SETRANGEMIN, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_IRRADIANCE, TBM_SETTICFREQ, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_IRRADIANCE, TBM_SETPOS, 1, 0); - - // slider - SendDlgItemMessage(hGfxDlg, IDC_GFX_LOCALMAX, TBM_SETRANGEMAX, 1, 255); - SendDlgItemMessage(hGfxDlg, IDC_GFX_LOCALMAX, TBM_SETRANGEMIN, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_LOCALMAX, TBM_SETTICFREQ, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_LOCALMAX, TBM_SETPOS, 1, 0); - - // slider - SendDlgItemMessage(hGfxDlg, IDC_GFX_GLARE, TBM_SETRANGEMAX, 1, 255); - SendDlgItemMessage(hGfxDlg, IDC_GFX_GLARE, TBM_SETRANGEMIN, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_GLARE, TBM_SETTICFREQ, 1, 0); - SendDlgItemMessage(hGfxDlg, IDC_GFX_GLARE, TBM_SETPOS, 1, 0); - - - - // reset-button(s) - HANDLE hImg = LoadImage(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT | LR_DEFAULTSIZE); - SendMessage(GetDlgItem(hGfxDlg, IDC_GFX_INTENSITY_RESET), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImg); - SendMessage(GetDlgItem(hGfxDlg, IDC_GFX_DISTANCE_RESET), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImg); - SendMessage(GetDlgItem(hGfxDlg, IDC_GFX_THRESHOLD_RESET), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImg); - SendMessage(GetDlgItem(hGfxDlg, IDC_GFX_GAMMA_RESET), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImg); - - SendMessage(GetDlgItem(hGfxDlg, IDC_GFX_SUNLIGHT_RESET), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImg); - SendMessage(GetDlgItem(hGfxDlg, IDC_GFX_IRRADIANCE_RESET), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImg); - SendMessage(GetDlgItem(hGfxDlg, IDC_GFX_LOCALMAX_RESET), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImg); - SendMessage(GetDlgItem(hGfxDlg, IDC_GFX_GLARE_RESET), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImg); - - CreateToolTip(IDC_GFX_INTENSITY_RESET, hGfxDlg, (char*)"Reset to default"); - CreateToolTip(IDC_GFX_DISTANCE_RESET, hGfxDlg, (char*)"Reset to default"); - CreateToolTip(IDC_GFX_THRESHOLD_RESET, hGfxDlg, (char*)"Reset to default"); - CreateToolTip(IDC_GFX_GAMMA_RESET, hGfxDlg, (char*)"Reset to default"); - CreateToolTip(IDC_GFX_SUNLIGHT_RESET, hGfxDlg, (char*)"Reset to default"); - CreateToolTip(IDC_GFX_IRRADIANCE_RESET, hGfxDlg, (char*)"Reset to default"); - CreateToolTip(IDC_GFX_LOCALMAX_RESET, hGfxDlg, (char*)"Reset to default"); - CreateToolTip(IDC_GFX_GLARE_RESET, hGfxDlg, (char*)"Reset to default"); - - SetGFXSliders(); -} - -void SetGFXSliders() -{ - char lbl[32]; - double fpos; - - fpos = Config->GFXIntensity; - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL1), lbl); - SendDlgItemMessage(hGfxDlg, IDC_GFX_INTENSITY, TBM_SETPOS, 1, WORD(fpos*255.0)); - - fpos = Config->GFXDistance; - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL2), lbl); - SendDlgItemMessage(hGfxDlg, IDC_GFX_DISTANCE, TBM_SETPOS, 1, WORD(fpos*255.0)); - - fpos = Config->GFXThreshold; - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL3), lbl); - SendDlgItemMessage(hGfxDlg, IDC_GFX_THRESHOLD, TBM_SETPOS, 1, WORD(fpos*255.0 / 2.0)); - - fpos = Config->GFXGamma; - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL4), lbl); - SendDlgItemMessage(hGfxDlg, IDC_GFX_GAMMA, TBM_SETPOS, 1, WORD(fpos*255.0 / 2.5)); - - fpos = Config->GFXSunIntensity; - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL5), lbl); - SendDlgItemMessage(hGfxDlg, IDC_GFX_SUNLIGHT, TBM_SETPOS, 1, WORD(fpos*255.0 / 2.0)); - - fpos = Config->PlanetGlow; - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL6), lbl); - SendDlgItemMessage(hGfxDlg, IDC_GFX_IRRADIANCE, TBM_SETPOS, 1, WORD(fpos*255.0 / 2.0)); - - fpos = Config->GFXLocalMax; - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL7), lbl); - SendDlgItemMessage(hGfxDlg, IDC_GFX_LOCALMAX, TBM_SETPOS, 1, WORD(fpos*255.0)); - - fpos = Config->GFXGlare; - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL8), lbl); - SendDlgItemMessage(hGfxDlg, IDC_GFX_GLARE, TBM_SETPOS, 1, WORD(fpos * 255.0)); -} - -void ReadGFXSliders() -{ - char lbl[32]; - double fpos; - - fpos = (1.0 / 255.0) * double(SendDlgItemMessage(hGfxDlg, IDC_GFX_INTENSITY, TBM_GETPOS, 0, 0)); - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL1), lbl); - Config->GFXIntensity = fpos; - - fpos = (1.0 / 255.0) * double(SendDlgItemMessage(hGfxDlg, IDC_GFX_DISTANCE, TBM_GETPOS, 0, 0)); - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL2), lbl); - Config->GFXDistance = fpos; - - fpos = (2.0 / 255.0) * double(SendDlgItemMessage(hGfxDlg, IDC_GFX_THRESHOLD, TBM_GETPOS, 0, 0)); - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL3), lbl); - Config->GFXThreshold = fpos; - - fpos = (2.5 / 255.0) * double(SendDlgItemMessage(hGfxDlg, IDC_GFX_GAMMA, TBM_GETPOS, 0, 0)); - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL4), lbl); - Config->GFXGamma = fpos; - - fpos = (2.0 / 255.0) * double(SendDlgItemMessage(hGfxDlg, IDC_GFX_SUNLIGHT, TBM_GETPOS, 0, 0)); - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL5), lbl); - Config->GFXSunIntensity = fpos; - - fpos = (2.0 / 255.0) * double(SendDlgItemMessage(hGfxDlg, IDC_GFX_IRRADIANCE, TBM_GETPOS, 0, 0)); - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL6), lbl); - Config->PlanetGlow = fpos; - - fpos = (1.0 / 255.0) * double(SendDlgItemMessage(hGfxDlg, IDC_GFX_LOCALMAX, TBM_GETPOS, 0, 0)); - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL7), lbl); - Config->GFXLocalMax = fpos; - - fpos = (1.0 / 255.0) * double(SendDlgItemMessage(hGfxDlg, IDC_GFX_GLARE, TBM_GETPOS, 0, 0)); - sprintf_s(lbl, 32, "%1.2f", fpos); - SetWindowTextA(GetDlgItem(hGfxDlg, IDC_GFX_VAL8), lbl); - Config->GFXGlare = fpos; + GFXDialog *gfx = (GFXDialog *)context; + oapiOpenDialog(gfx); } -INT_PTR CALLBACK WndProcGFX(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - - case WM_INITDIALOG: - { - return TRUE; // All Init actions are done in OpenDlgClbk(); - } - - case WM_HSCROLL: - { - if (LOWORD(wParam) == TB_THUMBTRACK || LOWORD(wParam) == TB_ENDTRACK) { - if (HWND(lParam) == GetDlgItem(hWnd, IDC_GFX_INTENSITY)) ReadGFXSliders(); - if (HWND(lParam) == GetDlgItem(hWnd, IDC_GFX_DISTANCE)) ReadGFXSliders(); - if (HWND(lParam) == GetDlgItem(hWnd, IDC_GFX_THRESHOLD)) ReadGFXSliders(); - if (HWND(lParam) == GetDlgItem(hWnd, IDC_GFX_GAMMA)) ReadGFXSliders(); - if (HWND(lParam) == GetDlgItem(hWnd, IDC_GFX_SUNLIGHT)) ReadGFXSliders(); - if (HWND(lParam) == GetDlgItem(hWnd, IDC_GFX_IRRADIANCE)) ReadGFXSliders(); - if (HWND(lParam) == GetDlgItem(hWnd, IDC_GFX_LOCALMAX)) ReadGFXSliders(); - if (HWND(lParam) == GetDlgItem(hWnd, IDC_GFX_GLARE)) ReadGFXSliders(); - } - return false; - } - - case WM_COMMAND: - - switch (LOWORD(wParam)) { - - case IDCANCEL: - CloseGFX(); - break; - - case IDC_GFX_RECOMPILE: - g_client->GetScene()->CreateSunGlare(); - break; - - - case IDC_GFX_INTENSITY_RESET: - Config->GFXIntensity = 0.5; - SetGFXSliders(); - break; - - case IDC_GFX_DISTANCE_RESET: - Config->GFXDistance = 0.8; - SetGFXSliders(); - break; - - case IDC_GFX_THRESHOLD_RESET: - Config->GFXThreshold = 1.1; - SetGFXSliders(); - break; - - case IDC_GFX_GAMMA_RESET: - Config->GFXGamma = 1.0; - SetGFXSliders(); - break; - - case IDC_GFX_SUNLIGHT_RESET: - Config->GFXSunIntensity = 1.2; - SetGFXSliders(); - break; - - case IDC_GFX_IRRADIANCE_RESET: - Config->PlanetGlow = 1.0; - SetGFXSliders(); - break; - - case IDC_GFX_LOCALMAX_RESET: - Config->GFXLocalMax = 0.5; - SetGFXSliders(); - break; - - case IDC_GFX_GLARE_RESET: - Config->GFXGlare = 0.3; - SetGFXSliders(); - break; - - default: - LogErr("WndProcGFX() LOWORD(%hu), HIWORD(0x%hX)", LOWORD(wParam), HIWORD(wParam)); - break; - } - break; - } - - return oapiDefDialogProc(hWnd, uMsg, wParam, lParam); -} - - - - } //namespace diff --git a/OVP/D3D9Client/DebugControls.h b/OVP/D3D9Client/DebugControls.h index b05e4a676..60f245e41 100644 --- a/OVP/D3D9Client/DebugControls.h +++ b/OVP/D3D9Client/DebugControls.h @@ -69,6 +69,7 @@ class vObject; // ============================================================== namespace DebugControls { + class GFXDialog; extern DWORD sMesh; extern DWORD sGroup; @@ -79,6 +80,7 @@ namespace DebugControls { extern double camSpeed; extern double resbias; extern std::map Emitters; + extern GFXDialog *gfxDlg; /** * \brief Same functionality than 'official' GetConfigParam, but for From 9c48d3793905812637b0e54a715f29ab73944094 Mon Sep 17 00:00:00 2001 From: Gondos Date: Sat, 25 Jan 2025 19:21:31 +0100 Subject: [PATCH 06/51] [ImGui]Bump version to 1.91.7 --- Extern/imgui/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extern/imgui/CMakeLists.txt b/Extern/imgui/CMakeLists.txt index e27301649..3bf4c8051 100644 --- a/Extern/imgui/CMakeLists.txt +++ b/Extern/imgui/CMakeLists.txt @@ -5,7 +5,7 @@ Include(FetchContent) FetchContent_Declare( imgui GIT_REPOSITORY https://github.com/ocornut/imgui.git - GIT_TAG v1.91.6-docking + GIT_TAG v1.91.7-docking PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/imconfig.h . UPDATE_DISCONNECTED 1 ) From f157a06877ffcd38698e7fabee4a5ac63ba83917 Mon Sep 17 00:00:00 2001 From: Gondos Date: Sat, 25 Jan 2025 19:28:23 +0100 Subject: [PATCH 07/51] [ImGui]Rename DialogImGui->ImGuiDialog --- OVP/D3D9Client/DebugControls.cpp | 3 ++- Orbitersdk/include/GraphicsAPI.h | 4 ++-- Orbitersdk/include/OrbiterAPI.h | 10 +++++----- Src/Orbiter/DlgMgr.cpp | 2 +- Src/Orbiter/DlgMgr.h | 14 +++++++------- Src/Orbiter/OrbiterAPI.cpp | 4 ++-- Src/Orbiter/Select.h | 4 ++-- 7 files changed, 21 insertions(+), 20 deletions(-) diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index e364f1937..41658a349 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -61,7 +61,7 @@ void UpdateMaterialDisplay(bool bSetup=false); void OpenGFXDlgClbk(void *context); -class GFXDialog: public DialogImGui +class GFXDialog: public ImGuiDialog { // Resettable slider from https://github.com/ocornut/imgui/issues/1751 static bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format = "%.3f") @@ -313,6 +313,7 @@ void Release() { vObj = NULL; hDlg = NULL; + oapiCloseDialog(gfxDlg); delete gfxDlg; gfxDlg = NULL; if (dwCmd) oapiUnregisterCustomCmd(dwCmd); diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 7cdfd6aba..6d7e25ffe 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -2061,9 +2061,9 @@ OAPIFUNC bool oapiRegisterGraphicsClient (oapi::GraphicsClient *gc); OAPIFUNC bool oapiUnregisterGraphicsClient (oapi::GraphicsClient *gc); -class OAPIFUNC DialogImGui { +class OAPIFUNC ImGuiDialog { public: - virtual ~DialogImGui() = default; + virtual ~ImGuiDialog() = default; bool IsActive() { return active; } void Activate() { active = true; } void Display() { diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 7229a4584..5ac79cbe7 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -120,7 +120,7 @@ class VESSEL; class CELBODY; class ExternMFD; class Interpreter; -class DialogImGui; +class ImGuiDialog; namespace oapi { class Module; @@ -6035,12 +6035,12 @@ OAPIFUNC bool oapiUnregisterCustomCmd (int cmdId); OAPIFUNC HWND oapiOpenDialog (HINSTANCE hDLLInst, int resourceId, DLGPROC msgProc, void *context = 0); /** - * \brief Open a dialog box specified by a DialogImGui object. - * \param dlg pointer to a DialogImGui object responsible for drawing the dialog box. + * \brief Open a dialog box specified by an ImGuiDialog object. + * \param dlg pointer to an ImGuiDialog object responsible for drawing the dialog box. * \note Only one instance of a dialog box can be open at a time. A second call to * oapiOpenDialog() with the same dialog will do nothing. */ -OAPIFUNC void oapiOpenDialog (DialogImGui *dlg); +OAPIFUNC void oapiOpenDialog (ImGuiDialog *dlg); /** * \brief Open a dialog box defined as a Windows resource. This version provides additional @@ -6085,7 +6085,7 @@ OAPIFUNC void oapiCloseDialog (HWND hDlg); * \brief Close a dialog box. * \param dlg object pointer that was used to open the dialog box. */ -OAPIFUNC void oapiCloseDialog (DialogImGui *dlg); +OAPIFUNC void oapiCloseDialog (ImGuiDialog *dlg); /** * \brief Retrieves the context pointer of a dialog box which has been defined during the call to oapiOpenDialog(). diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index 383ea0185..bde9568f4 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -450,7 +450,7 @@ void DialogManager::InitImGui() icons_config.PixelSnapH = true; icons_config.FontDataOwnedByAtlas = false; - io.Fonts->AddFontFromFileTTF("Roboto-Medium.ttf", 18.0f, &config, GetGlyphRangesOrbiter()); + io.Fonts->AddFontFromFileTTF("Roboto-Medium.ttf", 14.0f, &config, GetGlyphRangesOrbiter()); io.Fonts->Build(); ImGui_ImplWin32_Init(hWnd); diff --git a/Src/Orbiter/DlgMgr.h b/Src/Orbiter/DlgMgr.h index b350bd276..790cd86fd 100644 --- a/Src/Orbiter/DlgMgr.h +++ b/Src/Orbiter/DlgMgr.h @@ -11,7 +11,7 @@ #include "Orbiter.h" #include #include "imgui.h" -class DialogImGui; +class ImGuiDialog; class oapi::GraphicsClient; extern Orbiter *g_pOrbiter; @@ -156,12 +156,12 @@ class DialogManager { // ==================================================================== // ImGui management // ==================================================================== - std::list DlgImGuiList; + std::list DlgImGuiList; public: // Make sure that a dialog of type DlgType is open and return a pointer to it. // This opens the dialog if not yet present. // Use this function for dialogs that should only have a single instance - template, bool> = true> + template, bool> = true> T* EnsureEntry() { T* dlg = EntryExists(); @@ -175,7 +175,7 @@ class DialogManager { // Create a new instance of dialog type DlgType and return a pointer to it. // This opens a new dialog, even if one of this type was open already. // Use this function for dialogs that can have multiple instances. - template, bool> = true> + template, bool> = true> T* MakeEntry() { T* pDlg = new T(); @@ -185,7 +185,7 @@ class DialogManager { // Returns a pointer to the first instance of dialog type DlgType, // or 0 if no instance exists. - template, bool> = true> + template, bool> = true> T* EntryExists() { for (auto& e : DlgImGuiList) { @@ -195,7 +195,7 @@ class DialogManager { return nullptr; } - void AddEntry(DialogImGui* dlg) + void AddEntry(ImGuiDialog* dlg) { for (auto& e : DlgImGuiList) { if (e == dlg) { @@ -205,7 +205,7 @@ class DialogManager { DlgImGuiList.push_back(dlg); } - bool DelEntry(DialogImGui* dlg) + bool DelEntry(ImGuiDialog* dlg) { for (auto it = DlgImGuiList.begin(); it != DlgImGuiList.end(); ) { if (*it == dlg) { diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index 39cdd55cd..08ed0090d 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -2159,7 +2159,7 @@ DLLEXPORT HWND oapiOpenDialogEx (HINSTANCE hDLLInst, int resourceId, DLGPROC msg return g_pOrbiter->OpenDialogEx (hDLLInst, resourceId, msgProc, flag, context); } -DLLEXPORT void oapiOpenDialog(DialogImGui *e) +DLLEXPORT void oapiOpenDialog(ImGuiDialog *e) { g_pOrbiter->DlgMgr()->AddEntry(e); e->Activate(); @@ -2175,7 +2175,7 @@ DLLEXPORT void oapiCloseDialog (HWND hDlg) g_pOrbiter->CloseDialog (hDlg); } -DLLEXPORT void oapiCloseDialog(DialogImGui *e) +DLLEXPORT void oapiCloseDialog(ImGuiDialog *e) { g_pOrbiter->DlgMgr()->DelEntry(e); } diff --git a/Src/Orbiter/Select.h b/Src/Orbiter/Select.h index 181953302..797700707 100644 --- a/Src/Orbiter/Select.h +++ b/Src/Orbiter/Select.h @@ -18,7 +18,7 @@ struct SelectEntry { std::list m_SubEntries; }; -class Select : public DialogImGui { +class Select : public ImGuiDialog { public: typedef bool (*Callbk)(Select*, int, char*, void*); Select(); @@ -37,7 +37,7 @@ class Select : public DialogImGui { void DrawMenu(std::list& entries); }; -class InputBox : public DialogImGui { +class InputBox : public ImGuiDialog { public: typedef bool (*Callbk)(InputBox*, char*, void*); InputBox(); From a00f9cd8c6699f2851a1fa9bcb817152e092feef Mon Sep 17 00:00:00 2001 From: Gondos Date: Sat, 25 Jan 2025 19:36:20 +0100 Subject: [PATCH 08/51] [ImGui]Move ImGuiDialog from GraphicsAPI.h to OrbiterAPI.h --- Orbitersdk/include/GraphicsAPI.h | 16 ---------------- Orbitersdk/include/OrbiterAPI.h | 18 +++++++++++++++++- Src/Orbiter/DlgMgr.cpp | 1 - Src/Orbiter/Select.h | 1 - 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 6d7e25ffe..3e49944eb 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -2061,20 +2061,4 @@ OAPIFUNC bool oapiRegisterGraphicsClient (oapi::GraphicsClient *gc); OAPIFUNC bool oapiUnregisterGraphicsClient (oapi::GraphicsClient *gc); -class OAPIFUNC ImGuiDialog { -public: - virtual ~ImGuiDialog() = default; - bool IsActive() { return active; } - void Activate() { active = true; } - void Display() { - Draw(); - if (!active) OnClose(); - } - virtual void OnClose() {}; -private: - virtual void Draw() = 0; -protected: - bool active = false; -}; - #endif // !__GRAPHICSAPI_H \ No newline at end of file diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 5ac79cbe7..ee747d963 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -120,7 +120,6 @@ class VESSEL; class CELBODY; class ExternMFD; class Interpreter; -class ImGuiDialog; namespace oapi { class Module; @@ -650,6 +649,23 @@ typedef struct { } PARTICLESTREAMSPEC; +class OAPIFUNC ImGuiDialog { +public: + virtual ~ImGuiDialog() = default; + bool IsActive() { return active; } + void Activate() { active = true; } + void Display() { + Draw(); + if (!active) OnClose(); + } + virtual void OnClose() {}; +private: + virtual void Draw() = 0; +protected: + bool active = false; +}; + + /** * \defgroup locallight Local lighting interface * diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index bde9568f4..b920c7738 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -3,7 +3,6 @@ #define EXPORT_IMGUI_CONTEXT #include -#include "GraphicsAPI.h" #include "DlgMgr.h" #include "Resource.h" #include "Orbiter.h" diff --git a/Src/Orbiter/Select.h b/Src/Orbiter/Select.h index 797700707..33f3d6ada 100644 --- a/Src/Orbiter/Select.h +++ b/Src/Orbiter/Select.h @@ -5,7 +5,6 @@ #define __SELECT_H #include "OrbiterAPI.h" -#include "GraphicsAPI.h" #include #define ITEM_SUBMENU 0x01 From 475cc676c9717081af6ea0b33696aa8144b1f4e4 Mon Sep 17 00:00:00 2001 From: Gondos Date: Sat, 25 Jan 2025 20:53:11 +0100 Subject: [PATCH 09/51] [ImGui]Handle dialog visibility from Orbiter core --- OVP/D3D9Client/DebugControls.cpp | 36 ++++++++++++++-------------- Orbitersdk/include/OrbiterAPI.h | 40 ++++++++++++++++++++++++-------- Src/Orbiter/DlgMgr.cpp | 15 ++++++++++++ Src/Orbiter/Select.cpp | 8 +++---- Src/Orbiter/Select.h | 13 +++++++++-- 5 files changed, 77 insertions(+), 35 deletions(-) diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 41658a349..1531eb55f 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -79,29 +79,27 @@ class GFXDialog: public ImGuiDialog return ret; } public: - void Draw() { - if(ImGui::Begin("Graphics controls", &active)) { - ImGui::PushItemWidth(150.0); - ImGui::SeparatorText("Post Processing Configuration"); + GFXDialog(const char *name):ImGuiDialog(name) {} + void OnDraw() override { + ImGui::PushItemWidth(150.0); + ImGui::SeparatorText("Post Processing Configuration"); - SliderFloatReset("Light glow intensity", &Config->GFXIntensity, 0.0f, 1.0f, 0.5f, "%1.2f"); - SliderFloatReset("Light glow distance", &Config->GFXDistance, 0.0f, 1.0f, 0.8f, "%1.2f"); - SliderFloatReset("Glow threshold", &Config->GFXThreshold, 0.0f, 1.1f, 1.1f, "%1.2f"); - SliderFloatReset("Gamma", &Config->GFXGamma, 0.0f, 1.0f, 1.0f, "%1.2f"); + SliderFloatReset("Light glow intensity", &Config->GFXIntensity, 0.0f, 1.0f, 0.5f, "%1.2f"); + SliderFloatReset("Light glow distance", &Config->GFXDistance, 0.0f, 1.0f, 0.8f, "%1.2f"); + SliderFloatReset("Glow threshold", &Config->GFXThreshold, 0.0f, 1.1f, 1.1f, "%1.2f"); + SliderFloatReset("Gamma", &Config->GFXGamma, 0.0f, 1.0f, 1.0f, "%1.2f"); - ImGui::SeparatorText("Light Configuration"); + ImGui::SeparatorText("Light Configuration"); - SliderFloatReset("Sunlight Intensity", &Config->GFXSunIntensity, 0.0f, 1.0f, 1.2f, "%1.2f"); - SliderFloatReset("Indirect Lighting", &Config->PlanetGlow, 0.0f, 1.0f, 1.0f, "%1.2f"); - SliderFloatReset("Local Lights Max", &Config->GFXLocalMax, 0.0f, 1.0f, 0.5f, "%1.2f"); - SliderFloatReset("Sun Glare Intensity", &Config->GFXGlare, 0.0f, 1.0f, 0.3f, "%1.2f"); + SliderFloatReset("Sunlight Intensity", &Config->GFXSunIntensity, 0.0f, 1.0f, 1.2f, "%1.2f"); + SliderFloatReset("Indirect Lighting", &Config->PlanetGlow, 0.0f, 1.0f, 1.0f, "%1.2f"); + SliderFloatReset("Local Lights Max", &Config->GFXLocalMax, 0.0f, 1.0f, 0.5f, "%1.2f"); + SliderFloatReset("Sun Glare Intensity", &Config->GFXGlare, 0.0f, 1.0f, 0.3f, "%1.2f"); - if(ImGui::Button("Recrete Sun/Glares")) { - g_client->GetScene()->CreateSunGlare(); - } - ImGui::PopItemWidth(); + if(ImGui::Button("Recrete Sun/Glares")) { + g_client->GetScene()->CreateSunGlare(); } - ImGui::End(); + ImGui::PopItemWidth(); } }; @@ -222,7 +220,7 @@ void Create() dwCmd = 0; } - gfxDlg = new GFXDialog; + gfxDlg = new GFXDialog("Graphic Controls"); dwGFX = oapiRegisterCustomCmd((char*)"D3D9 Graphics Controls", (char*)"This dialog allows to control various graphics options", OpenGFXDlgClbk, gfxDlg); resbias = 4.0 + Config->LODBias; diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index ee747d963..a203c59ca 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -648,24 +648,44 @@ typedef struct { SURFHANDLE tex; ///< particle texture handle (NULL for default) } PARTICLESTREAMSPEC; - +/** + * \defgroup imguidialog ImGui dialog + * + * This group defines ImGuiDialog definition. + */ +//@{ +/** + * \brief Base class for defining an ImGui dialog. + */ class OAPIFUNC ImGuiDialog { + const std::string name; public: - virtual ~ImGuiDialog() = default; + /** + * \brief Create an ImGui dialog object. + * \param name Name of the dialog window + * \note This class must by derived from in order to define a custom ImGui dialog + */ + ImGuiDialog(const char *n):name(n) {} + virtual ~ImGuiDialog(); bool IsActive() { return active; } void Activate() { active = true; } - void Display() { - Draw(); - if (!active) OnClose(); - } - virtual void OnClose() {}; -private: - virtual void Draw() = 0; + virtual void Display(); protected: + /** + * \brief Callback that is executed when the dialog is closed. + * \note The default behavior is to do nothing + */ + virtual void OnClose() {}; + /** + * \brief Callback that is executed when the dialog should be drawn. + * \note Orbiter takes care of doing the ImGui::Begin() / ImGui::End() pair + * required to create the window and handle its visibility. + * \note ImGui documentation is available at https://github.com/ocornut/imgui + */ + virtual void OnDraw() = 0; bool active = false; }; - /** * \defgroup locallight Local lighting interface * diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index b920c7738..9c90c3872 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -2,7 +2,9 @@ // Licensed under the MIT License #define EXPORT_IMGUI_CONTEXT +#define OAPI_IMPLEMENTATION #include +#include "OrbiterAPI.h" #include "DlgMgr.h" #include "Resource.h" #include "Orbiter.h" @@ -481,3 +483,16 @@ void DialogManager::ImGuiNewFrame() } ImGui::EndFrame(); } + +ImGuiDialog::~ImGuiDialog(){ + // Make sure this dialog is no longer referenced in the DialogManager + oapiCloseDialog(this); +} + +void ImGuiDialog::Display() { + if(ImGui::Begin(name.c_str(), &active)) { + OnDraw(); + } + ImGui::End(); + if (!active) OnClose(); +} diff --git a/Src/Orbiter/Select.cpp b/Src/Orbiter/Select.cpp index fdecc5d00..8415a7d8f 100644 --- a/Src/Orbiter/Select.cpp +++ b/Src/Orbiter/Select.cpp @@ -4,7 +4,7 @@ #include "Select.h" #include "imgui.h" -Select::Select() { +Select::Select():ImGuiDialog("Select") { active = false; opened = false; title = "Selection"; @@ -75,7 +75,7 @@ void Select::DrawMenu(std::list& entries) { } } -void Select::Draw() { +void Select::OnDraw() { auto& io = ImGui::GetIO(); if (io.MouseDown[0] && opened) { @@ -99,7 +99,7 @@ void Select::Draw() { } } -InputBox::InputBox() { +InputBox::InputBox():ImGuiDialog("InputBox") { active = false; opened = false; title = "InputBox"; @@ -132,7 +132,7 @@ bool InputBox::OpenEx(const char *_title, char *_buf, int _vislen, return true; } -void InputBox::Draw() { +void InputBox::OnDraw() { char buf[256]; sprintf(buf, "%s###InputBox", title.c_str()); diff --git a/Src/Orbiter/Select.h b/Src/Orbiter/Select.h index 33f3d6ada..e4e6e009c 100644 --- a/Src/Orbiter/Select.h +++ b/Src/Orbiter/Select.h @@ -21,7 +21,12 @@ class Select : public ImGuiDialog { public: typedef bool (*Callbk)(Select*, int, char*, void*); Select(); - void Draw() override; + void Display() override { + OnDraw(); + if (!active) OnClose(); + } + + void OnDraw() override; bool opened; std::string title; std::list rootmenu; @@ -40,7 +45,11 @@ class InputBox : public ImGuiDialog { public: typedef bool (*Callbk)(InputBox*, char*, void*); InputBox(); - void Draw() override; + void Display() override { + OnDraw(); + if (!active) OnClose(); + } + void OnDraw() override; bool opened; std::string title; Callbk cbEnter; From 9e8b4e0249dce4b69962cd8cef99588b5a1b82ef Mon Sep 17 00:00:00 2001 From: Gondos Date: Sat, 25 Jan 2025 20:58:20 +0100 Subject: [PATCH 10/51] [ImGui]Fix values for the gfx controls --- OVP/D3D9Client/DebugControls.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 1531eb55f..5a19b95ab 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -84,17 +84,18 @@ class GFXDialog: public ImGuiDialog ImGui::PushItemWidth(150.0); ImGui::SeparatorText("Post Processing Configuration"); + SliderFloatReset("Light glow intensity", &Config->GFXIntensity, 0.0f, 1.0f, 0.5f, "%1.2f"); SliderFloatReset("Light glow distance", &Config->GFXDistance, 0.0f, 1.0f, 0.8f, "%1.2f"); - SliderFloatReset("Glow threshold", &Config->GFXThreshold, 0.0f, 1.1f, 1.1f, "%1.2f"); - SliderFloatReset("Gamma", &Config->GFXGamma, 0.0f, 1.0f, 1.0f, "%1.2f"); + SliderFloatReset("Glow threshold", &Config->GFXThreshold, 0.5f, 2.0f, 1.1f, "%1.2f"); + SliderFloatReset("Gamma", &Config->GFXGamma, 0.3f, 2.5f, 1.0f, "%1.2f"); ImGui::SeparatorText("Light Configuration"); - SliderFloatReset("Sunlight Intensity", &Config->GFXSunIntensity, 0.0f, 1.0f, 1.2f, "%1.2f"); - SliderFloatReset("Indirect Lighting", &Config->PlanetGlow, 0.0f, 1.0f, 1.0f, "%1.2f"); - SliderFloatReset("Local Lights Max", &Config->GFXLocalMax, 0.0f, 1.0f, 0.5f, "%1.2f"); - SliderFloatReset("Sun Glare Intensity", &Config->GFXGlare, 0.0f, 1.0f, 0.3f, "%1.2f"); + SliderFloatReset("Sunlight Intensity", &Config->GFXSunIntensity, 0.5f, 2.5f, 1.2f, "%1.2f"); + SliderFloatReset("Indirect Lighting", &Config->PlanetGlow, 0.01f, 2.0f, 0.7f, "%1.2f"); + SliderFloatReset("Local Lights Max", &Config->GFXLocalMax, 0.001f, 1.0f, 0.5f, "%1.2f"); + SliderFloatReset("Sun Glare Intensity", &Config->GFXGlare, 0.001f, 1.0f, 0.5f, "%1.2f"); if(ImGui::Button("Recrete Sun/Glares")) { g_client->GetScene()->CreateSunGlare(); From 2bbae112b7e5a673637b3f5cd3e48c5dcec76540 Mon Sep 17 00:00:00 2001 From: Gondos Date: Sat, 25 Jan 2025 21:21:49 +0100 Subject: [PATCH 11/51] [ImGui]Add SliderFloatReset helper to the core --- OVP/D3D9Client/DebugControls.cpp | 35 +++++++++----------------------- Orbitersdk/include/OrbiterAPI.h | 4 ++++ Src/Orbiter/DlgMgr.cpp | 19 +++++++++++++++++ 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 5a19b95ab..2802ceff1 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -63,39 +63,24 @@ void OpenGFXDlgClbk(void *context); class GFXDialog: public ImGuiDialog { - // Resettable slider from https://github.com/ocornut/imgui/issues/1751 - static bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format = "%.3f") - { - bool ret = ImGui::SliderFloat(label, v, v_min, v_max, display_format); - if (ImGui::BeginPopupContextItem(label)) - { - char buf[64]; - sprintf(buf, "Reset to %f", v_default); - if (ImGui::MenuItem(buf)) - *v = v_default; - ImGui::MenuItem("Close"); - ImGui::EndPopup(); - } - return ret; - } public: - GFXDialog(const char *name):ImGuiDialog(name) {} + GFXDialog():ImGuiDialog("Graphics Controls") {} void OnDraw() override { ImGui::PushItemWidth(150.0); ImGui::SeparatorText("Post Processing Configuration"); - SliderFloatReset("Light glow intensity", &Config->GFXIntensity, 0.0f, 1.0f, 0.5f, "%1.2f"); - SliderFloatReset("Light glow distance", &Config->GFXDistance, 0.0f, 1.0f, 0.8f, "%1.2f"); - SliderFloatReset("Glow threshold", &Config->GFXThreshold, 0.5f, 2.0f, 1.1f, "%1.2f"); - SliderFloatReset("Gamma", &Config->GFXGamma, 0.3f, 2.5f, 1.0f, "%1.2f"); + ImGui::SliderFloatReset("Light glow intensity", &Config->GFXIntensity, 0.0f, 1.0f, 0.5f, "%1.2f"); + ImGui::SliderFloatReset("Light glow distance", &Config->GFXDistance, 0.0f, 1.0f, 0.8f, "%1.2f"); + ImGui::SliderFloatReset("Glow threshold", &Config->GFXThreshold, 0.5f, 2.0f, 1.1f, "%1.2f"); + ImGui::SliderFloatReset("Gamma", &Config->GFXGamma, 0.3f, 2.5f, 1.0f, "%1.2f"); ImGui::SeparatorText("Light Configuration"); - SliderFloatReset("Sunlight Intensity", &Config->GFXSunIntensity, 0.5f, 2.5f, 1.2f, "%1.2f"); - SliderFloatReset("Indirect Lighting", &Config->PlanetGlow, 0.01f, 2.0f, 0.7f, "%1.2f"); - SliderFloatReset("Local Lights Max", &Config->GFXLocalMax, 0.001f, 1.0f, 0.5f, "%1.2f"); - SliderFloatReset("Sun Glare Intensity", &Config->GFXGlare, 0.001f, 1.0f, 0.5f, "%1.2f"); + ImGui::SliderFloatReset("Sunlight Intensity", &Config->GFXSunIntensity, 0.5f, 2.5f, 1.2f, "%1.2f"); + ImGui::SliderFloatReset("Indirect Lighting", &Config->PlanetGlow, 0.01f, 2.0f, 0.7f, "%1.2f"); + ImGui::SliderFloatReset("Local Lights Max", &Config->GFXLocalMax, 0.001f, 1.0f, 0.5f, "%1.2f"); + ImGui::SliderFloatReset("Sun Glare Intensity", &Config->GFXGlare, 0.001f, 1.0f, 0.5f, "%1.2f"); if(ImGui::Button("Recrete Sun/Glares")) { g_client->GetScene()->CreateSunGlare(); @@ -221,7 +206,7 @@ void Create() dwCmd = 0; } - gfxDlg = new GFXDialog("Graphic Controls"); + gfxDlg = new GFXDialog(); dwGFX = oapiRegisterCustomCmd((char*)"D3D9 Graphics Controls", (char*)"This dialog allows to control various graphics options", OpenGFXDlgClbk, gfxDlg); resbias = 4.0 + Config->LODBias; diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index a203c59ca..f05b98815 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -7629,6 +7629,10 @@ inline VECTOR3 POINTERTOREF (VECTOR3 *p) return v; } +// ImGui extras +namespace ImGui { + OAPIFUNC bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format = "%.3f"); +}; // ====================================================================== // Internal data structures // ====================================================================== diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index 9c90c3872..c2c8a24e3 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -496,3 +496,22 @@ void ImGuiDialog::Display() { ImGui::End(); if (!active) OnClose(); } + +// ImGui utils +namespace ImGui { + // Resettable slider from https://github.com/ocornut/imgui/issues/1751 + DLLEXPORT bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format) + { + bool ret = ImGui::SliderFloat(label, v, v_min, v_max, display_format); + if (ImGui::BeginPopupContextItem(label)) + { + char buf[64]; + sprintf(buf, "Reset to %f", v_default); + if (ImGui::MenuItem(buf)) + *v = v_default; + ImGui::MenuItem("Close"); + ImGui::EndPopup(); + } + return ret; + } +} From 56d502d7ed3596f68a4a99428d7efe802065a8b2 Mon Sep 17 00:00:00 2001 From: Gondos Date: Sun, 26 Jan 2025 02:24:27 +0100 Subject: [PATCH 12/51] [ImGui]Add icon font + helper for 'help' --- Doc/Orbiter User Manual/CREDITS.tex | 5 + Extern/imgui/CMakeLists.txt | 6 +- Extern/imgui/IconsFontAwesome6.h | 1416 +++++++++++++++++++++++++++ Extern/imgui/License-FA.txt | 165 ++++ Extern/imgui/fa-solid-900.ttf | Bin 0 -> 426112 bytes Html/Main/Credit/credit.htm | 6 +- Orbitersdk/include/OrbiterAPI.h | 1 + Src/Orbiter/DlgMgr.cpp | 19 + 8 files changed, 1614 insertions(+), 4 deletions(-) create mode 100644 Extern/imgui/IconsFontAwesome6.h create mode 100644 Extern/imgui/License-FA.txt create mode 100644 Extern/imgui/fa-solid-900.ttf diff --git a/Doc/Orbiter User Manual/CREDITS.tex b/Doc/Orbiter User Manual/CREDITS.tex index eb1424183..cdfba6051 100644 --- a/Doc/Orbiter User Manual/CREDITS.tex +++ b/Doc/Orbiter User Manual/CREDITS.tex @@ -32,6 +32,11 @@ \subsection{Libraries, code, data, algorithms} Jean-loup Gailly \href{mailto:jloup@gzip.org}{jloup@gzip.org}\\ Mark Adler \href{mailto:madler@alumni.caltech.edu}{madler@alumni.caltech.edu}\\ \\ +\textbf{Font Awesome}\\ +Icons font\\ +Fonticons, Inc. \url{https://fontawesome.com}\\ +CC BY 4.0 License \url{https://creativecommons.org/licenses/by/4.0/}\\ +\\ \textbf{VSOP87}\\ Planetary perturbation terms for Mercury to Neptune\\ Bureau des Longitudes, CNRS URA 707\\ diff --git a/Extern/imgui/CMakeLists.txt b/Extern/imgui/CMakeLists.txt index 3bf4c8051..3acefef93 100644 --- a/Extern/imgui/CMakeLists.txt +++ b/Extern/imgui/CMakeLists.txt @@ -6,16 +6,16 @@ FetchContent_Declare( imgui GIT_REPOSITORY https://github.com/ocornut/imgui.git GIT_TAG v1.91.7-docking - PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/imconfig.h . + PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/imconfig.h ${CMAKE_CURRENT_SOURCE_DIR}/IconsFontAwesome6.h . UPDATE_DISCONNECTED 1 ) FetchContent_MakeAvailable(imgui) -install(FILES ${imgui_SOURCE_DIR}/misc/fonts/Roboto-Medium.ttf +install(FILES ${imgui_SOURCE_DIR}/misc/fonts/Roboto-Medium.ttf fa-solid-900.ttf DESTINATION ${ORBITER_INSTALL_ROOT_DIR} ) -install(FILES ${imgui_SOURCE_DIR}/imgui.h ${imgui_SOURCE_DIR}/imconfig.h +install(FILES ${imgui_SOURCE_DIR}/imgui.h ${imgui_SOURCE_DIR}/imconfig.h IconsFontAwesome6.h DESTINATION ${ORBITER_INSTALL_SDK_DIR}/include ) diff --git a/Extern/imgui/IconsFontAwesome6.h b/Extern/imgui/IconsFontAwesome6.h new file mode 100644 index 000000000..bc878361a --- /dev/null +++ b/Extern/imgui/IconsFontAwesome6.h @@ -0,0 +1,1416 @@ +// Generated by https://github.com/juliettef/IconFontCppHeaders script GenerateIconFontCppHeaders.py +// for C and C++ +// from codepoints https://github.com/FortAwesome/Font-Awesome/raw/6.x/metadata/icons.yml +// for use with font https://github.com/FortAwesome/Font-Awesome/blob/6.x/webfonts/fa-regular-400.ttf, https://github.com/FortAwesome/Font-Awesome/blob/6.x/webfonts/fa-solid-900.ttf + +#pragma once + +#define FONT_ICON_FILE_NAME_FAR "fa-regular-400.ttf" +#define FONT_ICON_FILE_NAME_FAS "fa-solid-900.ttf" + +#define ICON_MIN_FA 0xe005 +#define ICON_MAX_16_FA 0xf8ff +#define ICON_MAX_FA 0xf8ff + +#define ICON_FA_0 "0" // U+0030 +#define ICON_FA_1 "1" // U+0031 +#define ICON_FA_2 "2" // U+0032 +#define ICON_FA_3 "3" // U+0033 +#define ICON_FA_4 "4" // U+0034 +#define ICON_FA_5 "5" // U+0035 +#define ICON_FA_6 "6" // U+0036 +#define ICON_FA_7 "7" // U+0037 +#define ICON_FA_8 "8" // U+0038 +#define ICON_FA_9 "9" // U+0039 +#define ICON_FA_A "A" // U+0041 +#define ICON_FA_ADDRESS_BOOK "\xef\x8a\xb9" // U+f2b9 +#define ICON_FA_ADDRESS_CARD "\xef\x8a\xbb" // U+f2bb +#define ICON_FA_ALIGN_CENTER "\xef\x80\xb7" // U+f037 +#define ICON_FA_ALIGN_JUSTIFY "\xef\x80\xb9" // U+f039 +#define ICON_FA_ALIGN_LEFT "\xef\x80\xb6" // U+f036 +#define ICON_FA_ALIGN_RIGHT "\xef\x80\xb8" // U+f038 +#define ICON_FA_ANCHOR "\xef\x84\xbd" // U+f13d +#define ICON_FA_ANCHOR_CIRCLE_CHECK "\xee\x92\xaa" // U+e4aa +#define ICON_FA_ANCHOR_CIRCLE_EXCLAMATION "\xee\x92\xab" // U+e4ab +#define ICON_FA_ANCHOR_CIRCLE_XMARK "\xee\x92\xac" // U+e4ac +#define ICON_FA_ANCHOR_LOCK "\xee\x92\xad" // U+e4ad +#define ICON_FA_ANGLE_DOWN "\xef\x84\x87" // U+f107 +#define ICON_FA_ANGLE_LEFT "\xef\x84\x84" // U+f104 +#define ICON_FA_ANGLE_RIGHT "\xef\x84\x85" // U+f105 +#define ICON_FA_ANGLE_UP "\xef\x84\x86" // U+f106 +#define ICON_FA_ANGLES_DOWN "\xef\x84\x83" // U+f103 +#define ICON_FA_ANGLES_LEFT "\xef\x84\x80" // U+f100 +#define ICON_FA_ANGLES_RIGHT "\xef\x84\x81" // U+f101 +#define ICON_FA_ANGLES_UP "\xef\x84\x82" // U+f102 +#define ICON_FA_ANKH "\xef\x99\x84" // U+f644 +#define ICON_FA_APPLE_WHOLE "\xef\x97\x91" // U+f5d1 +#define ICON_FA_ARCHWAY "\xef\x95\x97" // U+f557 +#define ICON_FA_ARROW_DOWN "\xef\x81\xa3" // U+f063 +#define ICON_FA_ARROW_DOWN_1_9 "\xef\x85\xa2" // U+f162 +#define ICON_FA_ARROW_DOWN_9_1 "\xef\xa2\x86" // U+f886 +#define ICON_FA_ARROW_DOWN_A_Z "\xef\x85\x9d" // U+f15d +#define ICON_FA_ARROW_DOWN_LONG "\xef\x85\xb5" // U+f175 +#define ICON_FA_ARROW_DOWN_SHORT_WIDE "\xef\xa2\x84" // U+f884 +#define ICON_FA_ARROW_DOWN_UP_ACROSS_LINE "\xee\x92\xaf" // U+e4af +#define ICON_FA_ARROW_DOWN_UP_LOCK "\xee\x92\xb0" // U+e4b0 +#define ICON_FA_ARROW_DOWN_WIDE_SHORT "\xef\x85\xa0" // U+f160 +#define ICON_FA_ARROW_DOWN_Z_A "\xef\xa2\x81" // U+f881 +#define ICON_FA_ARROW_LEFT "\xef\x81\xa0" // U+f060 +#define ICON_FA_ARROW_LEFT_LONG "\xef\x85\xb7" // U+f177 +#define ICON_FA_ARROW_POINTER "\xef\x89\x85" // U+f245 +#define ICON_FA_ARROW_RIGHT "\xef\x81\xa1" // U+f061 +#define ICON_FA_ARROW_RIGHT_ARROW_LEFT "\xef\x83\xac" // U+f0ec +#define ICON_FA_ARROW_RIGHT_FROM_BRACKET "\xef\x82\x8b" // U+f08b +#define ICON_FA_ARROW_RIGHT_LONG "\xef\x85\xb8" // U+f178 +#define ICON_FA_ARROW_RIGHT_TO_BRACKET "\xef\x82\x90" // U+f090 +#define ICON_FA_ARROW_RIGHT_TO_CITY "\xee\x92\xb3" // U+e4b3 +#define ICON_FA_ARROW_ROTATE_LEFT "\xef\x83\xa2" // U+f0e2 +#define ICON_FA_ARROW_ROTATE_RIGHT "\xef\x80\x9e" // U+f01e +#define ICON_FA_ARROW_TREND_DOWN "\xee\x82\x97" // U+e097 +#define ICON_FA_ARROW_TREND_UP "\xee\x82\x98" // U+e098 +#define ICON_FA_ARROW_TURN_DOWN "\xef\x85\x89" // U+f149 +#define ICON_FA_ARROW_TURN_UP "\xef\x85\x88" // U+f148 +#define ICON_FA_ARROW_UP "\xef\x81\xa2" // U+f062 +#define ICON_FA_ARROW_UP_1_9 "\xef\x85\xa3" // U+f163 +#define ICON_FA_ARROW_UP_9_1 "\xef\xa2\x87" // U+f887 +#define ICON_FA_ARROW_UP_A_Z "\xef\x85\x9e" // U+f15e +#define ICON_FA_ARROW_UP_FROM_BRACKET "\xee\x82\x9a" // U+e09a +#define ICON_FA_ARROW_UP_FROM_GROUND_WATER "\xee\x92\xb5" // U+e4b5 +#define ICON_FA_ARROW_UP_FROM_WATER_PUMP "\xee\x92\xb6" // U+e4b6 +#define ICON_FA_ARROW_UP_LONG "\xef\x85\xb6" // U+f176 +#define ICON_FA_ARROW_UP_RIGHT_DOTS "\xee\x92\xb7" // U+e4b7 +#define ICON_FA_ARROW_UP_RIGHT_FROM_SQUARE "\xef\x82\x8e" // U+f08e +#define ICON_FA_ARROW_UP_SHORT_WIDE "\xef\xa2\x85" // U+f885 +#define ICON_FA_ARROW_UP_WIDE_SHORT "\xef\x85\xa1" // U+f161 +#define ICON_FA_ARROW_UP_Z_A "\xef\xa2\x82" // U+f882 +#define ICON_FA_ARROWS_DOWN_TO_LINE "\xee\x92\xb8" // U+e4b8 +#define ICON_FA_ARROWS_DOWN_TO_PEOPLE "\xee\x92\xb9" // U+e4b9 +#define ICON_FA_ARROWS_LEFT_RIGHT "\xef\x81\xbe" // U+f07e +#define ICON_FA_ARROWS_LEFT_RIGHT_TO_LINE "\xee\x92\xba" // U+e4ba +#define ICON_FA_ARROWS_ROTATE "\xef\x80\xa1" // U+f021 +#define ICON_FA_ARROWS_SPIN "\xee\x92\xbb" // U+e4bb +#define ICON_FA_ARROWS_SPLIT_UP_AND_LEFT "\xee\x92\xbc" // U+e4bc +#define ICON_FA_ARROWS_TO_CIRCLE "\xee\x92\xbd" // U+e4bd +#define ICON_FA_ARROWS_TO_DOT "\xee\x92\xbe" // U+e4be +#define ICON_FA_ARROWS_TO_EYE "\xee\x92\xbf" // U+e4bf +#define ICON_FA_ARROWS_TURN_RIGHT "\xee\x93\x80" // U+e4c0 +#define ICON_FA_ARROWS_TURN_TO_DOTS "\xee\x93\x81" // U+e4c1 +#define ICON_FA_ARROWS_UP_DOWN "\xef\x81\xbd" // U+f07d +#define ICON_FA_ARROWS_UP_DOWN_LEFT_RIGHT "\xef\x81\x87" // U+f047 +#define ICON_FA_ARROWS_UP_TO_LINE "\xee\x93\x82" // U+e4c2 +#define ICON_FA_ASTERISK "*" // U+002a +#define ICON_FA_AT "@" // U+0040 +#define ICON_FA_ATOM "\xef\x97\x92" // U+f5d2 +#define ICON_FA_AUDIO_DESCRIPTION "\xef\x8a\x9e" // U+f29e +#define ICON_FA_AUSTRAL_SIGN "\xee\x82\xa9" // U+e0a9 +#define ICON_FA_AWARD "\xef\x95\x99" // U+f559 +#define ICON_FA_B "B" // U+0042 +#define ICON_FA_BABY "\xef\x9d\xbc" // U+f77c +#define ICON_FA_BABY_CARRIAGE "\xef\x9d\xbd" // U+f77d +#define ICON_FA_BACKWARD "\xef\x81\x8a" // U+f04a +#define ICON_FA_BACKWARD_FAST "\xef\x81\x89" // U+f049 +#define ICON_FA_BACKWARD_STEP "\xef\x81\x88" // U+f048 +#define ICON_FA_BACON "\xef\x9f\xa5" // U+f7e5 +#define ICON_FA_BACTERIA "\xee\x81\x99" // U+e059 +#define ICON_FA_BACTERIUM "\xee\x81\x9a" // U+e05a +#define ICON_FA_BAG_SHOPPING "\xef\x8a\x90" // U+f290 +#define ICON_FA_BAHAI "\xef\x99\xa6" // U+f666 +#define ICON_FA_BAHT_SIGN "\xee\x82\xac" // U+e0ac +#define ICON_FA_BAN "\xef\x81\x9e" // U+f05e +#define ICON_FA_BAN_SMOKING "\xef\x95\x8d" // U+f54d +#define ICON_FA_BANDAGE "\xef\x91\xa2" // U+f462 +#define ICON_FA_BANGLADESHI_TAKA_SIGN "\xee\x8b\xa6" // U+e2e6 +#define ICON_FA_BARCODE "\xef\x80\xaa" // U+f02a +#define ICON_FA_BARS "\xef\x83\x89" // U+f0c9 +#define ICON_FA_BARS_PROGRESS "\xef\xa0\xa8" // U+f828 +#define ICON_FA_BARS_STAGGERED "\xef\x95\x90" // U+f550 +#define ICON_FA_BASEBALL "\xef\x90\xb3" // U+f433 +#define ICON_FA_BASEBALL_BAT_BALL "\xef\x90\xb2" // U+f432 +#define ICON_FA_BASKET_SHOPPING "\xef\x8a\x91" // U+f291 +#define ICON_FA_BASKETBALL "\xef\x90\xb4" // U+f434 +#define ICON_FA_BATH "\xef\x8b\x8d" // U+f2cd +#define ICON_FA_BATTERY_EMPTY "\xef\x89\x84" // U+f244 +#define ICON_FA_BATTERY_FULL "\xef\x89\x80" // U+f240 +#define ICON_FA_BATTERY_HALF "\xef\x89\x82" // U+f242 +#define ICON_FA_BATTERY_QUARTER "\xef\x89\x83" // U+f243 +#define ICON_FA_BATTERY_THREE_QUARTERS "\xef\x89\x81" // U+f241 +#define ICON_FA_BED "\xef\x88\xb6" // U+f236 +#define ICON_FA_BED_PULSE "\xef\x92\x87" // U+f487 +#define ICON_FA_BEER_MUG_EMPTY "\xef\x83\xbc" // U+f0fc +#define ICON_FA_BELL "\xef\x83\xb3" // U+f0f3 +#define ICON_FA_BELL_CONCIERGE "\xef\x95\xa2" // U+f562 +#define ICON_FA_BELL_SLASH "\xef\x87\xb6" // U+f1f6 +#define ICON_FA_BEZIER_CURVE "\xef\x95\x9b" // U+f55b +#define ICON_FA_BICYCLE "\xef\x88\x86" // U+f206 +#define ICON_FA_BINOCULARS "\xef\x87\xa5" // U+f1e5 +#define ICON_FA_BIOHAZARD "\xef\x9e\x80" // U+f780 +#define ICON_FA_BITCOIN_SIGN "\xee\x82\xb4" // U+e0b4 +#define ICON_FA_BLENDER "\xef\x94\x97" // U+f517 +#define ICON_FA_BLENDER_PHONE "\xef\x9a\xb6" // U+f6b6 +#define ICON_FA_BLOG "\xef\x9e\x81" // U+f781 +#define ICON_FA_BOLD "\xef\x80\xb2" // U+f032 +#define ICON_FA_BOLT "\xef\x83\xa7" // U+f0e7 +#define ICON_FA_BOLT_LIGHTNING "\xee\x82\xb7" // U+e0b7 +#define ICON_FA_BOMB "\xef\x87\xa2" // U+f1e2 +#define ICON_FA_BONE "\xef\x97\x97" // U+f5d7 +#define ICON_FA_BONG "\xef\x95\x9c" // U+f55c +#define ICON_FA_BOOK "\xef\x80\xad" // U+f02d +#define ICON_FA_BOOK_ATLAS "\xef\x95\x98" // U+f558 +#define ICON_FA_BOOK_BIBLE "\xef\x99\x87" // U+f647 +#define ICON_FA_BOOK_BOOKMARK "\xee\x82\xbb" // U+e0bb +#define ICON_FA_BOOK_JOURNAL_WHILLS "\xef\x99\xaa" // U+f66a +#define ICON_FA_BOOK_MEDICAL "\xef\x9f\xa6" // U+f7e6 +#define ICON_FA_BOOK_OPEN "\xef\x94\x98" // U+f518 +#define ICON_FA_BOOK_OPEN_READER "\xef\x97\x9a" // U+f5da +#define ICON_FA_BOOK_QURAN "\xef\x9a\x87" // U+f687 +#define ICON_FA_BOOK_SKULL "\xef\x9a\xb7" // U+f6b7 +#define ICON_FA_BOOK_TANAKH "\xef\xa0\xa7" // U+f827 +#define ICON_FA_BOOKMARK "\xef\x80\xae" // U+f02e +#define ICON_FA_BORDER_ALL "\xef\xa1\x8c" // U+f84c +#define ICON_FA_BORDER_NONE "\xef\xa1\x90" // U+f850 +#define ICON_FA_BORDER_TOP_LEFT "\xef\xa1\x93" // U+f853 +#define ICON_FA_BORE_HOLE "\xee\x93\x83" // U+e4c3 +#define ICON_FA_BOTTLE_DROPLET "\xee\x93\x84" // U+e4c4 +#define ICON_FA_BOTTLE_WATER "\xee\x93\x85" // U+e4c5 +#define ICON_FA_BOWL_FOOD "\xee\x93\x86" // U+e4c6 +#define ICON_FA_BOWL_RICE "\xee\x8b\xab" // U+e2eb +#define ICON_FA_BOWLING_BALL "\xef\x90\xb6" // U+f436 +#define ICON_FA_BOX "\xef\x91\xa6" // U+f466 +#define ICON_FA_BOX_ARCHIVE "\xef\x86\x87" // U+f187 +#define ICON_FA_BOX_OPEN "\xef\x92\x9e" // U+f49e +#define ICON_FA_BOX_TISSUE "\xee\x81\x9b" // U+e05b +#define ICON_FA_BOXES_PACKING "\xee\x93\x87" // U+e4c7 +#define ICON_FA_BOXES_STACKED "\xef\x91\xa8" // U+f468 +#define ICON_FA_BRAILLE "\xef\x8a\xa1" // U+f2a1 +#define ICON_FA_BRAIN "\xef\x97\x9c" // U+f5dc +#define ICON_FA_BRAZILIAN_REAL_SIGN "\xee\x91\xac" // U+e46c +#define ICON_FA_BREAD_SLICE "\xef\x9f\xac" // U+f7ec +#define ICON_FA_BRIDGE "\xee\x93\x88" // U+e4c8 +#define ICON_FA_BRIDGE_CIRCLE_CHECK "\xee\x93\x89" // U+e4c9 +#define ICON_FA_BRIDGE_CIRCLE_EXCLAMATION "\xee\x93\x8a" // U+e4ca +#define ICON_FA_BRIDGE_CIRCLE_XMARK "\xee\x93\x8b" // U+e4cb +#define ICON_FA_BRIDGE_LOCK "\xee\x93\x8c" // U+e4cc +#define ICON_FA_BRIDGE_WATER "\xee\x93\x8e" // U+e4ce +#define ICON_FA_BRIEFCASE "\xef\x82\xb1" // U+f0b1 +#define ICON_FA_BRIEFCASE_MEDICAL "\xef\x91\xa9" // U+f469 +#define ICON_FA_BROOM "\xef\x94\x9a" // U+f51a +#define ICON_FA_BROOM_BALL "\xef\x91\x98" // U+f458 +#define ICON_FA_BRUSH "\xef\x95\x9d" // U+f55d +#define ICON_FA_BUCKET "\xee\x93\x8f" // U+e4cf +#define ICON_FA_BUG "\xef\x86\x88" // U+f188 +#define ICON_FA_BUG_SLASH "\xee\x92\x90" // U+e490 +#define ICON_FA_BUGS "\xee\x93\x90" // U+e4d0 +#define ICON_FA_BUILDING "\xef\x86\xad" // U+f1ad +#define ICON_FA_BUILDING_CIRCLE_ARROW_RIGHT "\xee\x93\x91" // U+e4d1 +#define ICON_FA_BUILDING_CIRCLE_CHECK "\xee\x93\x92" // U+e4d2 +#define ICON_FA_BUILDING_CIRCLE_EXCLAMATION "\xee\x93\x93" // U+e4d3 +#define ICON_FA_BUILDING_CIRCLE_XMARK "\xee\x93\x94" // U+e4d4 +#define ICON_FA_BUILDING_COLUMNS "\xef\x86\x9c" // U+f19c +#define ICON_FA_BUILDING_FLAG "\xee\x93\x95" // U+e4d5 +#define ICON_FA_BUILDING_LOCK "\xee\x93\x96" // U+e4d6 +#define ICON_FA_BUILDING_NGO "\xee\x93\x97" // U+e4d7 +#define ICON_FA_BUILDING_SHIELD "\xee\x93\x98" // U+e4d8 +#define ICON_FA_BUILDING_UN "\xee\x93\x99" // U+e4d9 +#define ICON_FA_BUILDING_USER "\xee\x93\x9a" // U+e4da +#define ICON_FA_BUILDING_WHEAT "\xee\x93\x9b" // U+e4db +#define ICON_FA_BULLHORN "\xef\x82\xa1" // U+f0a1 +#define ICON_FA_BULLSEYE "\xef\x85\x80" // U+f140 +#define ICON_FA_BURGER "\xef\xa0\x85" // U+f805 +#define ICON_FA_BURST "\xee\x93\x9c" // U+e4dc +#define ICON_FA_BUS "\xef\x88\x87" // U+f207 +#define ICON_FA_BUS_SIMPLE "\xef\x95\x9e" // U+f55e +#define ICON_FA_BUSINESS_TIME "\xef\x99\x8a" // U+f64a +#define ICON_FA_C "C" // U+0043 +#define ICON_FA_CABLE_CAR "\xef\x9f\x9a" // U+f7da +#define ICON_FA_CAKE_CANDLES "\xef\x87\xbd" // U+f1fd +#define ICON_FA_CALCULATOR "\xef\x87\xac" // U+f1ec +#define ICON_FA_CALENDAR "\xef\x84\xb3" // U+f133 +#define ICON_FA_CALENDAR_CHECK "\xef\x89\xb4" // U+f274 +#define ICON_FA_CALENDAR_DAY "\xef\x9e\x83" // U+f783 +#define ICON_FA_CALENDAR_DAYS "\xef\x81\xb3" // U+f073 +#define ICON_FA_CALENDAR_MINUS "\xef\x89\xb2" // U+f272 +#define ICON_FA_CALENDAR_PLUS "\xef\x89\xb1" // U+f271 +#define ICON_FA_CALENDAR_WEEK "\xef\x9e\x84" // U+f784 +#define ICON_FA_CALENDAR_XMARK "\xef\x89\xb3" // U+f273 +#define ICON_FA_CAMERA "\xef\x80\xb0" // U+f030 +#define ICON_FA_CAMERA_RETRO "\xef\x82\x83" // U+f083 +#define ICON_FA_CAMERA_ROTATE "\xee\x83\x98" // U+e0d8 +#define ICON_FA_CAMPGROUND "\xef\x9a\xbb" // U+f6bb +#define ICON_FA_CANDY_CANE "\xef\x9e\x86" // U+f786 +#define ICON_FA_CANNABIS "\xef\x95\x9f" // U+f55f +#define ICON_FA_CAPSULES "\xef\x91\xab" // U+f46b +#define ICON_FA_CAR "\xef\x86\xb9" // U+f1b9 +#define ICON_FA_CAR_BATTERY "\xef\x97\x9f" // U+f5df +#define ICON_FA_CAR_BURST "\xef\x97\xa1" // U+f5e1 +#define ICON_FA_CAR_ON "\xee\x93\x9d" // U+e4dd +#define ICON_FA_CAR_REAR "\xef\x97\x9e" // U+f5de +#define ICON_FA_CAR_SIDE "\xef\x97\xa4" // U+f5e4 +#define ICON_FA_CAR_TUNNEL "\xee\x93\x9e" // U+e4de +#define ICON_FA_CARAVAN "\xef\xa3\xbf" // U+f8ff +#define ICON_FA_CARET_DOWN "\xef\x83\x97" // U+f0d7 +#define ICON_FA_CARET_LEFT "\xef\x83\x99" // U+f0d9 +#define ICON_FA_CARET_RIGHT "\xef\x83\x9a" // U+f0da +#define ICON_FA_CARET_UP "\xef\x83\x98" // U+f0d8 +#define ICON_FA_CARROT "\xef\x9e\x87" // U+f787 +#define ICON_FA_CART_ARROW_DOWN "\xef\x88\x98" // U+f218 +#define ICON_FA_CART_FLATBED "\xef\x91\xb4" // U+f474 +#define ICON_FA_CART_FLATBED_SUITCASE "\xef\x96\x9d" // U+f59d +#define ICON_FA_CART_PLUS "\xef\x88\x97" // U+f217 +#define ICON_FA_CART_SHOPPING "\xef\x81\xba" // U+f07a +#define ICON_FA_CASH_REGISTER "\xef\x9e\x88" // U+f788 +#define ICON_FA_CAT "\xef\x9a\xbe" // U+f6be +#define ICON_FA_CEDI_SIGN "\xee\x83\x9f" // U+e0df +#define ICON_FA_CENT_SIGN "\xee\x8f\xb5" // U+e3f5 +#define ICON_FA_CERTIFICATE "\xef\x82\xa3" // U+f0a3 +#define ICON_FA_CHAIR "\xef\x9b\x80" // U+f6c0 +#define ICON_FA_CHALKBOARD "\xef\x94\x9b" // U+f51b +#define ICON_FA_CHALKBOARD_USER "\xef\x94\x9c" // U+f51c +#define ICON_FA_CHAMPAGNE_GLASSES "\xef\x9e\x9f" // U+f79f +#define ICON_FA_CHARGING_STATION "\xef\x97\xa7" // U+f5e7 +#define ICON_FA_CHART_AREA "\xef\x87\xbe" // U+f1fe +#define ICON_FA_CHART_BAR "\xef\x82\x80" // U+f080 +#define ICON_FA_CHART_COLUMN "\xee\x83\xa3" // U+e0e3 +#define ICON_FA_CHART_DIAGRAM "\xee\x9a\x95" // U+e695 +#define ICON_FA_CHART_GANTT "\xee\x83\xa4" // U+e0e4 +#define ICON_FA_CHART_LINE "\xef\x88\x81" // U+f201 +#define ICON_FA_CHART_PIE "\xef\x88\x80" // U+f200 +#define ICON_FA_CHART_SIMPLE "\xee\x91\xb3" // U+e473 +#define ICON_FA_CHECK "\xef\x80\x8c" // U+f00c +#define ICON_FA_CHECK_DOUBLE "\xef\x95\xa0" // U+f560 +#define ICON_FA_CHECK_TO_SLOT "\xef\x9d\xb2" // U+f772 +#define ICON_FA_CHEESE "\xef\x9f\xaf" // U+f7ef +#define ICON_FA_CHESS "\xef\x90\xb9" // U+f439 +#define ICON_FA_CHESS_BISHOP "\xef\x90\xba" // U+f43a +#define ICON_FA_CHESS_BOARD "\xef\x90\xbc" // U+f43c +#define ICON_FA_CHESS_KING "\xef\x90\xbf" // U+f43f +#define ICON_FA_CHESS_KNIGHT "\xef\x91\x81" // U+f441 +#define ICON_FA_CHESS_PAWN "\xef\x91\x83" // U+f443 +#define ICON_FA_CHESS_QUEEN "\xef\x91\x85" // U+f445 +#define ICON_FA_CHESS_ROOK "\xef\x91\x87" // U+f447 +#define ICON_FA_CHEVRON_DOWN "\xef\x81\xb8" // U+f078 +#define ICON_FA_CHEVRON_LEFT "\xef\x81\x93" // U+f053 +#define ICON_FA_CHEVRON_RIGHT "\xef\x81\x94" // U+f054 +#define ICON_FA_CHEVRON_UP "\xef\x81\xb7" // U+f077 +#define ICON_FA_CHILD "\xef\x86\xae" // U+f1ae +#define ICON_FA_CHILD_COMBATANT "\xee\x93\xa0" // U+e4e0 +#define ICON_FA_CHILD_DRESS "\xee\x96\x9c" // U+e59c +#define ICON_FA_CHILD_REACHING "\xee\x96\x9d" // U+e59d +#define ICON_FA_CHILDREN "\xee\x93\xa1" // U+e4e1 +#define ICON_FA_CHURCH "\xef\x94\x9d" // U+f51d +#define ICON_FA_CIRCLE "\xef\x84\x91" // U+f111 +#define ICON_FA_CIRCLE_ARROW_DOWN "\xef\x82\xab" // U+f0ab +#define ICON_FA_CIRCLE_ARROW_LEFT "\xef\x82\xa8" // U+f0a8 +#define ICON_FA_CIRCLE_ARROW_RIGHT "\xef\x82\xa9" // U+f0a9 +#define ICON_FA_CIRCLE_ARROW_UP "\xef\x82\xaa" // U+f0aa +#define ICON_FA_CIRCLE_CHECK "\xef\x81\x98" // U+f058 +#define ICON_FA_CIRCLE_CHEVRON_DOWN "\xef\x84\xba" // U+f13a +#define ICON_FA_CIRCLE_CHEVRON_LEFT "\xef\x84\xb7" // U+f137 +#define ICON_FA_CIRCLE_CHEVRON_RIGHT "\xef\x84\xb8" // U+f138 +#define ICON_FA_CIRCLE_CHEVRON_UP "\xef\x84\xb9" // U+f139 +#define ICON_FA_CIRCLE_DOLLAR_TO_SLOT "\xef\x92\xb9" // U+f4b9 +#define ICON_FA_CIRCLE_DOT "\xef\x86\x92" // U+f192 +#define ICON_FA_CIRCLE_DOWN "\xef\x8d\x98" // U+f358 +#define ICON_FA_CIRCLE_EXCLAMATION "\xef\x81\xaa" // U+f06a +#define ICON_FA_CIRCLE_H "\xef\x91\xbe" // U+f47e +#define ICON_FA_CIRCLE_HALF_STROKE "\xef\x81\x82" // U+f042 +#define ICON_FA_CIRCLE_INFO "\xef\x81\x9a" // U+f05a +#define ICON_FA_CIRCLE_LEFT "\xef\x8d\x99" // U+f359 +#define ICON_FA_CIRCLE_MINUS "\xef\x81\x96" // U+f056 +#define ICON_FA_CIRCLE_NODES "\xee\x93\xa2" // U+e4e2 +#define ICON_FA_CIRCLE_NOTCH "\xef\x87\x8e" // U+f1ce +#define ICON_FA_CIRCLE_PAUSE "\xef\x8a\x8b" // U+f28b +#define ICON_FA_CIRCLE_PLAY "\xef\x85\x84" // U+f144 +#define ICON_FA_CIRCLE_PLUS "\xef\x81\x95" // U+f055 +#define ICON_FA_CIRCLE_QUESTION "\xef\x81\x99" // U+f059 +#define ICON_FA_CIRCLE_RADIATION "\xef\x9e\xba" // U+f7ba +#define ICON_FA_CIRCLE_RIGHT "\xef\x8d\x9a" // U+f35a +#define ICON_FA_CIRCLE_STOP "\xef\x8a\x8d" // U+f28d +#define ICON_FA_CIRCLE_UP "\xef\x8d\x9b" // U+f35b +#define ICON_FA_CIRCLE_USER "\xef\x8a\xbd" // U+f2bd +#define ICON_FA_CIRCLE_XMARK "\xef\x81\x97" // U+f057 +#define ICON_FA_CITY "\xef\x99\x8f" // U+f64f +#define ICON_FA_CLAPPERBOARD "\xee\x84\xb1" // U+e131 +#define ICON_FA_CLIPBOARD "\xef\x8c\xa8" // U+f328 +#define ICON_FA_CLIPBOARD_CHECK "\xef\x91\xac" // U+f46c +#define ICON_FA_CLIPBOARD_LIST "\xef\x91\xad" // U+f46d +#define ICON_FA_CLIPBOARD_QUESTION "\xee\x93\xa3" // U+e4e3 +#define ICON_FA_CLIPBOARD_USER "\xef\x9f\xb3" // U+f7f3 +#define ICON_FA_CLOCK "\xef\x80\x97" // U+f017 +#define ICON_FA_CLOCK_ROTATE_LEFT "\xef\x87\x9a" // U+f1da +#define ICON_FA_CLONE "\xef\x89\x8d" // U+f24d +#define ICON_FA_CLOSED_CAPTIONING "\xef\x88\x8a" // U+f20a +#define ICON_FA_CLOUD "\xef\x83\x82" // U+f0c2 +#define ICON_FA_CLOUD_ARROW_DOWN "\xef\x83\xad" // U+f0ed +#define ICON_FA_CLOUD_ARROW_UP "\xef\x83\xae" // U+f0ee +#define ICON_FA_CLOUD_BOLT "\xef\x9d\xac" // U+f76c +#define ICON_FA_CLOUD_MEATBALL "\xef\x9c\xbb" // U+f73b +#define ICON_FA_CLOUD_MOON "\xef\x9b\x83" // U+f6c3 +#define ICON_FA_CLOUD_MOON_RAIN "\xef\x9c\xbc" // U+f73c +#define ICON_FA_CLOUD_RAIN "\xef\x9c\xbd" // U+f73d +#define ICON_FA_CLOUD_SHOWERS_HEAVY "\xef\x9d\x80" // U+f740 +#define ICON_FA_CLOUD_SHOWERS_WATER "\xee\x93\xa4" // U+e4e4 +#define ICON_FA_CLOUD_SUN "\xef\x9b\x84" // U+f6c4 +#define ICON_FA_CLOUD_SUN_RAIN "\xef\x9d\x83" // U+f743 +#define ICON_FA_CLOVER "\xee\x84\xb9" // U+e139 +#define ICON_FA_CODE "\xef\x84\xa1" // U+f121 +#define ICON_FA_CODE_BRANCH "\xef\x84\xa6" // U+f126 +#define ICON_FA_CODE_COMMIT "\xef\x8e\x86" // U+f386 +#define ICON_FA_CODE_COMPARE "\xee\x84\xba" // U+e13a +#define ICON_FA_CODE_FORK "\xee\x84\xbb" // U+e13b +#define ICON_FA_CODE_MERGE "\xef\x8e\x87" // U+f387 +#define ICON_FA_CODE_PULL_REQUEST "\xee\x84\xbc" // U+e13c +#define ICON_FA_COINS "\xef\x94\x9e" // U+f51e +#define ICON_FA_COLON_SIGN "\xee\x85\x80" // U+e140 +#define ICON_FA_COMMENT "\xef\x81\xb5" // U+f075 +#define ICON_FA_COMMENT_DOLLAR "\xef\x99\x91" // U+f651 +#define ICON_FA_COMMENT_DOTS "\xef\x92\xad" // U+f4ad +#define ICON_FA_COMMENT_MEDICAL "\xef\x9f\xb5" // U+f7f5 +#define ICON_FA_COMMENT_NODES "\xee\x9a\x96" // U+e696 +#define ICON_FA_COMMENT_SLASH "\xef\x92\xb3" // U+f4b3 +#define ICON_FA_COMMENT_SMS "\xef\x9f\x8d" // U+f7cd +#define ICON_FA_COMMENTS "\xef\x82\x86" // U+f086 +#define ICON_FA_COMMENTS_DOLLAR "\xef\x99\x93" // U+f653 +#define ICON_FA_COMPACT_DISC "\xef\x94\x9f" // U+f51f +#define ICON_FA_COMPASS "\xef\x85\x8e" // U+f14e +#define ICON_FA_COMPASS_DRAFTING "\xef\x95\xa8" // U+f568 +#define ICON_FA_COMPRESS "\xef\x81\xa6" // U+f066 +#define ICON_FA_COMPUTER "\xee\x93\xa5" // U+e4e5 +#define ICON_FA_COMPUTER_MOUSE "\xef\xa3\x8c" // U+f8cc +#define ICON_FA_COOKIE "\xef\x95\xa3" // U+f563 +#define ICON_FA_COOKIE_BITE "\xef\x95\xa4" // U+f564 +#define ICON_FA_COPY "\xef\x83\x85" // U+f0c5 +#define ICON_FA_COPYRIGHT "\xef\x87\xb9" // U+f1f9 +#define ICON_FA_COUCH "\xef\x92\xb8" // U+f4b8 +#define ICON_FA_COW "\xef\x9b\x88" // U+f6c8 +#define ICON_FA_CREDIT_CARD "\xef\x82\x9d" // U+f09d +#define ICON_FA_CROP "\xef\x84\xa5" // U+f125 +#define ICON_FA_CROP_SIMPLE "\xef\x95\xa5" // U+f565 +#define ICON_FA_CROSS "\xef\x99\x94" // U+f654 +#define ICON_FA_CROSSHAIRS "\xef\x81\x9b" // U+f05b +#define ICON_FA_CROW "\xef\x94\xa0" // U+f520 +#define ICON_FA_CROWN "\xef\x94\xa1" // U+f521 +#define ICON_FA_CRUTCH "\xef\x9f\xb7" // U+f7f7 +#define ICON_FA_CRUZEIRO_SIGN "\xee\x85\x92" // U+e152 +#define ICON_FA_CUBE "\xef\x86\xb2" // U+f1b2 +#define ICON_FA_CUBES "\xef\x86\xb3" // U+f1b3 +#define ICON_FA_CUBES_STACKED "\xee\x93\xa6" // U+e4e6 +#define ICON_FA_D "D" // U+0044 +#define ICON_FA_DATABASE "\xef\x87\x80" // U+f1c0 +#define ICON_FA_DELETE_LEFT "\xef\x95\x9a" // U+f55a +#define ICON_FA_DEMOCRAT "\xef\x9d\x87" // U+f747 +#define ICON_FA_DESKTOP "\xef\x8e\x90" // U+f390 +#define ICON_FA_DHARMACHAKRA "\xef\x99\x95" // U+f655 +#define ICON_FA_DIAGRAM_NEXT "\xee\x91\xb6" // U+e476 +#define ICON_FA_DIAGRAM_PREDECESSOR "\xee\x91\xb7" // U+e477 +#define ICON_FA_DIAGRAM_PROJECT "\xef\x95\x82" // U+f542 +#define ICON_FA_DIAGRAM_SUCCESSOR "\xee\x91\xba" // U+e47a +#define ICON_FA_DIAMOND "\xef\x88\x99" // U+f219 +#define ICON_FA_DIAMOND_TURN_RIGHT "\xef\x97\xab" // U+f5eb +#define ICON_FA_DICE "\xef\x94\xa2" // U+f522 +#define ICON_FA_DICE_D20 "\xef\x9b\x8f" // U+f6cf +#define ICON_FA_DICE_D6 "\xef\x9b\x91" // U+f6d1 +#define ICON_FA_DICE_FIVE "\xef\x94\xa3" // U+f523 +#define ICON_FA_DICE_FOUR "\xef\x94\xa4" // U+f524 +#define ICON_FA_DICE_ONE "\xef\x94\xa5" // U+f525 +#define ICON_FA_DICE_SIX "\xef\x94\xa6" // U+f526 +#define ICON_FA_DICE_THREE "\xef\x94\xa7" // U+f527 +#define ICON_FA_DICE_TWO "\xef\x94\xa8" // U+f528 +#define ICON_FA_DISEASE "\xef\x9f\xba" // U+f7fa +#define ICON_FA_DISPLAY "\xee\x85\xa3" // U+e163 +#define ICON_FA_DIVIDE "\xef\x94\xa9" // U+f529 +#define ICON_FA_DNA "\xef\x91\xb1" // U+f471 +#define ICON_FA_DOG "\xef\x9b\x93" // U+f6d3 +#define ICON_FA_DOLLAR_SIGN "$" // U+0024 +#define ICON_FA_DOLLY "\xef\x91\xb2" // U+f472 +#define ICON_FA_DONG_SIGN "\xee\x85\xa9" // U+e169 +#define ICON_FA_DOOR_CLOSED "\xef\x94\xaa" // U+f52a +#define ICON_FA_DOOR_OPEN "\xef\x94\xab" // U+f52b +#define ICON_FA_DOVE "\xef\x92\xba" // U+f4ba +#define ICON_FA_DOWN_LEFT_AND_UP_RIGHT_TO_CENTER "\xef\x90\xa2" // U+f422 +#define ICON_FA_DOWN_LONG "\xef\x8c\x89" // U+f309 +#define ICON_FA_DOWNLOAD "\xef\x80\x99" // U+f019 +#define ICON_FA_DRAGON "\xef\x9b\x95" // U+f6d5 +#define ICON_FA_DRAW_POLYGON "\xef\x97\xae" // U+f5ee +#define ICON_FA_DROPLET "\xef\x81\x83" // U+f043 +#define ICON_FA_DROPLET_SLASH "\xef\x97\x87" // U+f5c7 +#define ICON_FA_DRUM "\xef\x95\xa9" // U+f569 +#define ICON_FA_DRUM_STEELPAN "\xef\x95\xaa" // U+f56a +#define ICON_FA_DRUMSTICK_BITE "\xef\x9b\x97" // U+f6d7 +#define ICON_FA_DUMBBELL "\xef\x91\x8b" // U+f44b +#define ICON_FA_DUMPSTER "\xef\x9e\x93" // U+f793 +#define ICON_FA_DUMPSTER_FIRE "\xef\x9e\x94" // U+f794 +#define ICON_FA_DUNGEON "\xef\x9b\x99" // U+f6d9 +#define ICON_FA_E "E" // U+0045 +#define ICON_FA_EAR_DEAF "\xef\x8a\xa4" // U+f2a4 +#define ICON_FA_EAR_LISTEN "\xef\x8a\xa2" // U+f2a2 +#define ICON_FA_EARTH_AFRICA "\xef\x95\xbc" // U+f57c +#define ICON_FA_EARTH_AMERICAS "\xef\x95\xbd" // U+f57d +#define ICON_FA_EARTH_ASIA "\xef\x95\xbe" // U+f57e +#define ICON_FA_EARTH_EUROPE "\xef\x9e\xa2" // U+f7a2 +#define ICON_FA_EARTH_OCEANIA "\xee\x91\xbb" // U+e47b +#define ICON_FA_EGG "\xef\x9f\xbb" // U+f7fb +#define ICON_FA_EJECT "\xef\x81\x92" // U+f052 +#define ICON_FA_ELEVATOR "\xee\x85\xad" // U+e16d +#define ICON_FA_ELLIPSIS "\xef\x85\x81" // U+f141 +#define ICON_FA_ELLIPSIS_VERTICAL "\xef\x85\x82" // U+f142 +#define ICON_FA_ENVELOPE "\xef\x83\xa0" // U+f0e0 +#define ICON_FA_ENVELOPE_CIRCLE_CHECK "\xee\x93\xa8" // U+e4e8 +#define ICON_FA_ENVELOPE_OPEN "\xef\x8a\xb6" // U+f2b6 +#define ICON_FA_ENVELOPE_OPEN_TEXT "\xef\x99\x98" // U+f658 +#define ICON_FA_ENVELOPES_BULK "\xef\x99\xb4" // U+f674 +#define ICON_FA_EQUALS "=" // U+003d +#define ICON_FA_ERASER "\xef\x84\xad" // U+f12d +#define ICON_FA_ETHERNET "\xef\x9e\x96" // U+f796 +#define ICON_FA_EURO_SIGN "\xef\x85\x93" // U+f153 +#define ICON_FA_EXCLAMATION "!" // U+0021 +#define ICON_FA_EXPAND "\xef\x81\xa5" // U+f065 +#define ICON_FA_EXPLOSION "\xee\x93\xa9" // U+e4e9 +#define ICON_FA_EYE "\xef\x81\xae" // U+f06e +#define ICON_FA_EYE_DROPPER "\xef\x87\xbb" // U+f1fb +#define ICON_FA_EYE_LOW_VISION "\xef\x8a\xa8" // U+f2a8 +#define ICON_FA_EYE_SLASH "\xef\x81\xb0" // U+f070 +#define ICON_FA_F "F" // U+0046 +#define ICON_FA_FACE_ANGRY "\xef\x95\x96" // U+f556 +#define ICON_FA_FACE_DIZZY "\xef\x95\xa7" // U+f567 +#define ICON_FA_FACE_FLUSHED "\xef\x95\xb9" // U+f579 +#define ICON_FA_FACE_FROWN "\xef\x84\x99" // U+f119 +#define ICON_FA_FACE_FROWN_OPEN "\xef\x95\xba" // U+f57a +#define ICON_FA_FACE_GRIMACE "\xef\x95\xbf" // U+f57f +#define ICON_FA_FACE_GRIN "\xef\x96\x80" // U+f580 +#define ICON_FA_FACE_GRIN_BEAM "\xef\x96\x82" // U+f582 +#define ICON_FA_FACE_GRIN_BEAM_SWEAT "\xef\x96\x83" // U+f583 +#define ICON_FA_FACE_GRIN_HEARTS "\xef\x96\x84" // U+f584 +#define ICON_FA_FACE_GRIN_SQUINT "\xef\x96\x85" // U+f585 +#define ICON_FA_FACE_GRIN_SQUINT_TEARS "\xef\x96\x86" // U+f586 +#define ICON_FA_FACE_GRIN_STARS "\xef\x96\x87" // U+f587 +#define ICON_FA_FACE_GRIN_TEARS "\xef\x96\x88" // U+f588 +#define ICON_FA_FACE_GRIN_TONGUE "\xef\x96\x89" // U+f589 +#define ICON_FA_FACE_GRIN_TONGUE_SQUINT "\xef\x96\x8a" // U+f58a +#define ICON_FA_FACE_GRIN_TONGUE_WINK "\xef\x96\x8b" // U+f58b +#define ICON_FA_FACE_GRIN_WIDE "\xef\x96\x81" // U+f581 +#define ICON_FA_FACE_GRIN_WINK "\xef\x96\x8c" // U+f58c +#define ICON_FA_FACE_KISS "\xef\x96\x96" // U+f596 +#define ICON_FA_FACE_KISS_BEAM "\xef\x96\x97" // U+f597 +#define ICON_FA_FACE_KISS_WINK_HEART "\xef\x96\x98" // U+f598 +#define ICON_FA_FACE_LAUGH "\xef\x96\x99" // U+f599 +#define ICON_FA_FACE_LAUGH_BEAM "\xef\x96\x9a" // U+f59a +#define ICON_FA_FACE_LAUGH_SQUINT "\xef\x96\x9b" // U+f59b +#define ICON_FA_FACE_LAUGH_WINK "\xef\x96\x9c" // U+f59c +#define ICON_FA_FACE_MEH "\xef\x84\x9a" // U+f11a +#define ICON_FA_FACE_MEH_BLANK "\xef\x96\xa4" // U+f5a4 +#define ICON_FA_FACE_ROLLING_EYES "\xef\x96\xa5" // U+f5a5 +#define ICON_FA_FACE_SAD_CRY "\xef\x96\xb3" // U+f5b3 +#define ICON_FA_FACE_SAD_TEAR "\xef\x96\xb4" // U+f5b4 +#define ICON_FA_FACE_SMILE "\xef\x84\x98" // U+f118 +#define ICON_FA_FACE_SMILE_BEAM "\xef\x96\xb8" // U+f5b8 +#define ICON_FA_FACE_SMILE_WINK "\xef\x93\x9a" // U+f4da +#define ICON_FA_FACE_SURPRISE "\xef\x97\x82" // U+f5c2 +#define ICON_FA_FACE_TIRED "\xef\x97\x88" // U+f5c8 +#define ICON_FA_FAN "\xef\xa1\xa3" // U+f863 +#define ICON_FA_FAUCET "\xee\x80\x85" // U+e005 +#define ICON_FA_FAUCET_DRIP "\xee\x80\x86" // U+e006 +#define ICON_FA_FAX "\xef\x86\xac" // U+f1ac +#define ICON_FA_FEATHER "\xef\x94\xad" // U+f52d +#define ICON_FA_FEATHER_POINTED "\xef\x95\xab" // U+f56b +#define ICON_FA_FERRY "\xee\x93\xaa" // U+e4ea +#define ICON_FA_FILE "\xef\x85\x9b" // U+f15b +#define ICON_FA_FILE_ARROW_DOWN "\xef\x95\xad" // U+f56d +#define ICON_FA_FILE_ARROW_UP "\xef\x95\xb4" // U+f574 +#define ICON_FA_FILE_AUDIO "\xef\x87\x87" // U+f1c7 +#define ICON_FA_FILE_CIRCLE_CHECK "\xee\x96\xa0" // U+e5a0 +#define ICON_FA_FILE_CIRCLE_EXCLAMATION "\xee\x93\xab" // U+e4eb +#define ICON_FA_FILE_CIRCLE_MINUS "\xee\x93\xad" // U+e4ed +#define ICON_FA_FILE_CIRCLE_PLUS "\xee\x92\x94" // U+e494 +#define ICON_FA_FILE_CIRCLE_QUESTION "\xee\x93\xaf" // U+e4ef +#define ICON_FA_FILE_CIRCLE_XMARK "\xee\x96\xa1" // U+e5a1 +#define ICON_FA_FILE_CODE "\xef\x87\x89" // U+f1c9 +#define ICON_FA_FILE_CONTRACT "\xef\x95\xac" // U+f56c +#define ICON_FA_FILE_CSV "\xef\x9b\x9d" // U+f6dd +#define ICON_FA_FILE_EXCEL "\xef\x87\x83" // U+f1c3 +#define ICON_FA_FILE_EXPORT "\xef\x95\xae" // U+f56e +#define ICON_FA_FILE_FRAGMENT "\xee\x9a\x97" // U+e697 +#define ICON_FA_FILE_HALF_DASHED "\xee\x9a\x98" // U+e698 +#define ICON_FA_FILE_IMAGE "\xef\x87\x85" // U+f1c5 +#define ICON_FA_FILE_IMPORT "\xef\x95\xaf" // U+f56f +#define ICON_FA_FILE_INVOICE "\xef\x95\xb0" // U+f570 +#define ICON_FA_FILE_INVOICE_DOLLAR "\xef\x95\xb1" // U+f571 +#define ICON_FA_FILE_LINES "\xef\x85\x9c" // U+f15c +#define ICON_FA_FILE_MEDICAL "\xef\x91\xb7" // U+f477 +#define ICON_FA_FILE_PDF "\xef\x87\x81" // U+f1c1 +#define ICON_FA_FILE_PEN "\xef\x8c\x9c" // U+f31c +#define ICON_FA_FILE_POWERPOINT "\xef\x87\x84" // U+f1c4 +#define ICON_FA_FILE_PRESCRIPTION "\xef\x95\xb2" // U+f572 +#define ICON_FA_FILE_SHIELD "\xee\x93\xb0" // U+e4f0 +#define ICON_FA_FILE_SIGNATURE "\xef\x95\xb3" // U+f573 +#define ICON_FA_FILE_VIDEO "\xef\x87\x88" // U+f1c8 +#define ICON_FA_FILE_WAVEFORM "\xef\x91\xb8" // U+f478 +#define ICON_FA_FILE_WORD "\xef\x87\x82" // U+f1c2 +#define ICON_FA_FILE_ZIPPER "\xef\x87\x86" // U+f1c6 +#define ICON_FA_FILL "\xef\x95\xb5" // U+f575 +#define ICON_FA_FILL_DRIP "\xef\x95\xb6" // U+f576 +#define ICON_FA_FILM "\xef\x80\x88" // U+f008 +#define ICON_FA_FILTER "\xef\x82\xb0" // U+f0b0 +#define ICON_FA_FILTER_CIRCLE_DOLLAR "\xef\x99\xa2" // U+f662 +#define ICON_FA_FILTER_CIRCLE_XMARK "\xee\x85\xbb" // U+e17b +#define ICON_FA_FINGERPRINT "\xef\x95\xb7" // U+f577 +#define ICON_FA_FIRE "\xef\x81\xad" // U+f06d +#define ICON_FA_FIRE_BURNER "\xee\x93\xb1" // U+e4f1 +#define ICON_FA_FIRE_EXTINGUISHER "\xef\x84\xb4" // U+f134 +#define ICON_FA_FIRE_FLAME_CURVED "\xef\x9f\xa4" // U+f7e4 +#define ICON_FA_FIRE_FLAME_SIMPLE "\xef\x91\xaa" // U+f46a +#define ICON_FA_FISH "\xef\x95\xb8" // U+f578 +#define ICON_FA_FISH_FINS "\xee\x93\xb2" // U+e4f2 +#define ICON_FA_FLAG "\xef\x80\xa4" // U+f024 +#define ICON_FA_FLAG_CHECKERED "\xef\x84\x9e" // U+f11e +#define ICON_FA_FLAG_USA "\xef\x9d\x8d" // U+f74d +#define ICON_FA_FLASK "\xef\x83\x83" // U+f0c3 +#define ICON_FA_FLASK_VIAL "\xee\x93\xb3" // U+e4f3 +#define ICON_FA_FLOPPY_DISK "\xef\x83\x87" // U+f0c7 +#define ICON_FA_FLORIN_SIGN "\xee\x86\x84" // U+e184 +#define ICON_FA_FOLDER "\xef\x81\xbb" // U+f07b +#define ICON_FA_FOLDER_CLOSED "\xee\x86\x85" // U+e185 +#define ICON_FA_FOLDER_MINUS "\xef\x99\x9d" // U+f65d +#define ICON_FA_FOLDER_OPEN "\xef\x81\xbc" // U+f07c +#define ICON_FA_FOLDER_PLUS "\xef\x99\x9e" // U+f65e +#define ICON_FA_FOLDER_TREE "\xef\xa0\x82" // U+f802 +#define ICON_FA_FONT "\xef\x80\xb1" // U+f031 +#define ICON_FA_FONT_AWESOME "\xef\x8a\xb4" // U+f2b4 +#define ICON_FA_FOOTBALL "\xef\x91\x8e" // U+f44e +#define ICON_FA_FORWARD "\xef\x81\x8e" // U+f04e +#define ICON_FA_FORWARD_FAST "\xef\x81\x90" // U+f050 +#define ICON_FA_FORWARD_STEP "\xef\x81\x91" // U+f051 +#define ICON_FA_FRANC_SIGN "\xee\x86\x8f" // U+e18f +#define ICON_FA_FROG "\xef\x94\xae" // U+f52e +#define ICON_FA_FUTBOL "\xef\x87\xa3" // U+f1e3 +#define ICON_FA_G "G" // U+0047 +#define ICON_FA_GAMEPAD "\xef\x84\x9b" // U+f11b +#define ICON_FA_GAS_PUMP "\xef\x94\xaf" // U+f52f +#define ICON_FA_GAUGE "\xef\x98\xa4" // U+f624 +#define ICON_FA_GAUGE_HIGH "\xef\x98\xa5" // U+f625 +#define ICON_FA_GAUGE_SIMPLE "\xef\x98\xa9" // U+f629 +#define ICON_FA_GAUGE_SIMPLE_HIGH "\xef\x98\xaa" // U+f62a +#define ICON_FA_GAVEL "\xef\x83\xa3" // U+f0e3 +#define ICON_FA_GEAR "\xef\x80\x93" // U+f013 +#define ICON_FA_GEARS "\xef\x82\x85" // U+f085 +#define ICON_FA_GEM "\xef\x8e\xa5" // U+f3a5 +#define ICON_FA_GENDERLESS "\xef\x88\xad" // U+f22d +#define ICON_FA_GHOST "\xef\x9b\xa2" // U+f6e2 +#define ICON_FA_GIFT "\xef\x81\xab" // U+f06b +#define ICON_FA_GIFTS "\xef\x9e\x9c" // U+f79c +#define ICON_FA_GLASS_WATER "\xee\x93\xb4" // U+e4f4 +#define ICON_FA_GLASS_WATER_DROPLET "\xee\x93\xb5" // U+e4f5 +#define ICON_FA_GLASSES "\xef\x94\xb0" // U+f530 +#define ICON_FA_GLOBE "\xef\x82\xac" // U+f0ac +#define ICON_FA_GOLF_BALL_TEE "\xef\x91\x90" // U+f450 +#define ICON_FA_GOPURAM "\xef\x99\xa4" // U+f664 +#define ICON_FA_GRADUATION_CAP "\xef\x86\x9d" // U+f19d +#define ICON_FA_GREATER_THAN ">" // U+003e +#define ICON_FA_GREATER_THAN_EQUAL "\xef\x94\xb2" // U+f532 +#define ICON_FA_GRIP "\xef\x96\x8d" // U+f58d +#define ICON_FA_GRIP_LINES "\xef\x9e\xa4" // U+f7a4 +#define ICON_FA_GRIP_LINES_VERTICAL "\xef\x9e\xa5" // U+f7a5 +#define ICON_FA_GRIP_VERTICAL "\xef\x96\x8e" // U+f58e +#define ICON_FA_GROUP_ARROWS_ROTATE "\xee\x93\xb6" // U+e4f6 +#define ICON_FA_GUARANI_SIGN "\xee\x86\x9a" // U+e19a +#define ICON_FA_GUITAR "\xef\x9e\xa6" // U+f7a6 +#define ICON_FA_GUN "\xee\x86\x9b" // U+e19b +#define ICON_FA_H "H" // U+0048 +#define ICON_FA_HAMMER "\xef\x9b\xa3" // U+f6e3 +#define ICON_FA_HAMSA "\xef\x99\xa5" // U+f665 +#define ICON_FA_HAND "\xef\x89\x96" // U+f256 +#define ICON_FA_HAND_BACK_FIST "\xef\x89\x95" // U+f255 +#define ICON_FA_HAND_DOTS "\xef\x91\xa1" // U+f461 +#define ICON_FA_HAND_FIST "\xef\x9b\x9e" // U+f6de +#define ICON_FA_HAND_HOLDING "\xef\x92\xbd" // U+f4bd +#define ICON_FA_HAND_HOLDING_DOLLAR "\xef\x93\x80" // U+f4c0 +#define ICON_FA_HAND_HOLDING_DROPLET "\xef\x93\x81" // U+f4c1 +#define ICON_FA_HAND_HOLDING_HAND "\xee\x93\xb7" // U+e4f7 +#define ICON_FA_HAND_HOLDING_HEART "\xef\x92\xbe" // U+f4be +#define ICON_FA_HAND_HOLDING_MEDICAL "\xee\x81\x9c" // U+e05c +#define ICON_FA_HAND_LIZARD "\xef\x89\x98" // U+f258 +#define ICON_FA_HAND_MIDDLE_FINGER "\xef\xa0\x86" // U+f806 +#define ICON_FA_HAND_PEACE "\xef\x89\x9b" // U+f25b +#define ICON_FA_HAND_POINT_DOWN "\xef\x82\xa7" // U+f0a7 +#define ICON_FA_HAND_POINT_LEFT "\xef\x82\xa5" // U+f0a5 +#define ICON_FA_HAND_POINT_RIGHT "\xef\x82\xa4" // U+f0a4 +#define ICON_FA_HAND_POINT_UP "\xef\x82\xa6" // U+f0a6 +#define ICON_FA_HAND_POINTER "\xef\x89\x9a" // U+f25a +#define ICON_FA_HAND_SCISSORS "\xef\x89\x97" // U+f257 +#define ICON_FA_HAND_SPARKLES "\xee\x81\x9d" // U+e05d +#define ICON_FA_HAND_SPOCK "\xef\x89\x99" // U+f259 +#define ICON_FA_HANDCUFFS "\xee\x93\xb8" // U+e4f8 +#define ICON_FA_HANDS "\xef\x8a\xa7" // U+f2a7 +#define ICON_FA_HANDS_ASL_INTERPRETING "\xef\x8a\xa3" // U+f2a3 +#define ICON_FA_HANDS_BOUND "\xee\x93\xb9" // U+e4f9 +#define ICON_FA_HANDS_BUBBLES "\xee\x81\x9e" // U+e05e +#define ICON_FA_HANDS_CLAPPING "\xee\x86\xa8" // U+e1a8 +#define ICON_FA_HANDS_HOLDING "\xef\x93\x82" // U+f4c2 +#define ICON_FA_HANDS_HOLDING_CHILD "\xee\x93\xba" // U+e4fa +#define ICON_FA_HANDS_HOLDING_CIRCLE "\xee\x93\xbb" // U+e4fb +#define ICON_FA_HANDS_PRAYING "\xef\x9a\x84" // U+f684 +#define ICON_FA_HANDSHAKE "\xef\x8a\xb5" // U+f2b5 +#define ICON_FA_HANDSHAKE_ANGLE "\xef\x93\x84" // U+f4c4 +#define ICON_FA_HANDSHAKE_SIMPLE "\xef\x93\x86" // U+f4c6 +#define ICON_FA_HANDSHAKE_SIMPLE_SLASH "\xee\x81\x9f" // U+e05f +#define ICON_FA_HANDSHAKE_SLASH "\xee\x81\xa0" // U+e060 +#define ICON_FA_HANUKIAH "\xef\x9b\xa6" // U+f6e6 +#define ICON_FA_HARD_DRIVE "\xef\x82\xa0" // U+f0a0 +#define ICON_FA_HASHTAG "#" // U+0023 +#define ICON_FA_HAT_COWBOY "\xef\xa3\x80" // U+f8c0 +#define ICON_FA_HAT_COWBOY_SIDE "\xef\xa3\x81" // U+f8c1 +#define ICON_FA_HAT_WIZARD "\xef\x9b\xa8" // U+f6e8 +#define ICON_FA_HEAD_SIDE_COUGH "\xee\x81\xa1" // U+e061 +#define ICON_FA_HEAD_SIDE_COUGH_SLASH "\xee\x81\xa2" // U+e062 +#define ICON_FA_HEAD_SIDE_MASK "\xee\x81\xa3" // U+e063 +#define ICON_FA_HEAD_SIDE_VIRUS "\xee\x81\xa4" // U+e064 +#define ICON_FA_HEADING "\xef\x87\x9c" // U+f1dc +#define ICON_FA_HEADPHONES "\xef\x80\xa5" // U+f025 +#define ICON_FA_HEADPHONES_SIMPLE "\xef\x96\x8f" // U+f58f +#define ICON_FA_HEADSET "\xef\x96\x90" // U+f590 +#define ICON_FA_HEART "\xef\x80\x84" // U+f004 +#define ICON_FA_HEART_CIRCLE_BOLT "\xee\x93\xbc" // U+e4fc +#define ICON_FA_HEART_CIRCLE_CHECK "\xee\x93\xbd" // U+e4fd +#define ICON_FA_HEART_CIRCLE_EXCLAMATION "\xee\x93\xbe" // U+e4fe +#define ICON_FA_HEART_CIRCLE_MINUS "\xee\x93\xbf" // U+e4ff +#define ICON_FA_HEART_CIRCLE_PLUS "\xee\x94\x80" // U+e500 +#define ICON_FA_HEART_CIRCLE_XMARK "\xee\x94\x81" // U+e501 +#define ICON_FA_HEART_CRACK "\xef\x9e\xa9" // U+f7a9 +#define ICON_FA_HEART_PULSE "\xef\x88\x9e" // U+f21e +#define ICON_FA_HELICOPTER "\xef\x94\xb3" // U+f533 +#define ICON_FA_HELICOPTER_SYMBOL "\xee\x94\x82" // U+e502 +#define ICON_FA_HELMET_SAFETY "\xef\xa0\x87" // U+f807 +#define ICON_FA_HELMET_UN "\xee\x94\x83" // U+e503 +#define ICON_FA_HEXAGON_NODES "\xee\x9a\x99" // U+e699 +#define ICON_FA_HEXAGON_NODES_BOLT "\xee\x9a\x9a" // U+e69a +#define ICON_FA_HIGHLIGHTER "\xef\x96\x91" // U+f591 +#define ICON_FA_HILL_AVALANCHE "\xee\x94\x87" // U+e507 +#define ICON_FA_HILL_ROCKSLIDE "\xee\x94\x88" // U+e508 +#define ICON_FA_HIPPO "\xef\x9b\xad" // U+f6ed +#define ICON_FA_HOCKEY_PUCK "\xef\x91\x93" // U+f453 +#define ICON_FA_HOLLY_BERRY "\xef\x9e\xaa" // U+f7aa +#define ICON_FA_HORSE "\xef\x9b\xb0" // U+f6f0 +#define ICON_FA_HORSE_HEAD "\xef\x9e\xab" // U+f7ab +#define ICON_FA_HOSPITAL "\xef\x83\xb8" // U+f0f8 +#define ICON_FA_HOSPITAL_USER "\xef\xa0\x8d" // U+f80d +#define ICON_FA_HOT_TUB_PERSON "\xef\x96\x93" // U+f593 +#define ICON_FA_HOTDOG "\xef\xa0\x8f" // U+f80f +#define ICON_FA_HOTEL "\xef\x96\x94" // U+f594 +#define ICON_FA_HOURGLASS "\xef\x89\x94" // U+f254 +#define ICON_FA_HOURGLASS_END "\xef\x89\x93" // U+f253 +#define ICON_FA_HOURGLASS_HALF "\xef\x89\x92" // U+f252 +#define ICON_FA_HOURGLASS_START "\xef\x89\x91" // U+f251 +#define ICON_FA_HOUSE "\xef\x80\x95" // U+f015 +#define ICON_FA_HOUSE_CHIMNEY "\xee\x8e\xaf" // U+e3af +#define ICON_FA_HOUSE_CHIMNEY_CRACK "\xef\x9b\xb1" // U+f6f1 +#define ICON_FA_HOUSE_CHIMNEY_MEDICAL "\xef\x9f\xb2" // U+f7f2 +#define ICON_FA_HOUSE_CHIMNEY_USER "\xee\x81\xa5" // U+e065 +#define ICON_FA_HOUSE_CHIMNEY_WINDOW "\xee\x80\x8d" // U+e00d +#define ICON_FA_HOUSE_CIRCLE_CHECK "\xee\x94\x89" // U+e509 +#define ICON_FA_HOUSE_CIRCLE_EXCLAMATION "\xee\x94\x8a" // U+e50a +#define ICON_FA_HOUSE_CIRCLE_XMARK "\xee\x94\x8b" // U+e50b +#define ICON_FA_HOUSE_CRACK "\xee\x8e\xb1" // U+e3b1 +#define ICON_FA_HOUSE_FIRE "\xee\x94\x8c" // U+e50c +#define ICON_FA_HOUSE_FLAG "\xee\x94\x8d" // U+e50d +#define ICON_FA_HOUSE_FLOOD_WATER "\xee\x94\x8e" // U+e50e +#define ICON_FA_HOUSE_FLOOD_WATER_CIRCLE_ARROW_RIGHT "\xee\x94\x8f" // U+e50f +#define ICON_FA_HOUSE_LAPTOP "\xee\x81\xa6" // U+e066 +#define ICON_FA_HOUSE_LOCK "\xee\x94\x90" // U+e510 +#define ICON_FA_HOUSE_MEDICAL "\xee\x8e\xb2" // U+e3b2 +#define ICON_FA_HOUSE_MEDICAL_CIRCLE_CHECK "\xee\x94\x91" // U+e511 +#define ICON_FA_HOUSE_MEDICAL_CIRCLE_EXCLAMATION "\xee\x94\x92" // U+e512 +#define ICON_FA_HOUSE_MEDICAL_CIRCLE_XMARK "\xee\x94\x93" // U+e513 +#define ICON_FA_HOUSE_MEDICAL_FLAG "\xee\x94\x94" // U+e514 +#define ICON_FA_HOUSE_SIGNAL "\xee\x80\x92" // U+e012 +#define ICON_FA_HOUSE_TSUNAMI "\xee\x94\x95" // U+e515 +#define ICON_FA_HOUSE_USER "\xee\x86\xb0" // U+e1b0 +#define ICON_FA_HRYVNIA_SIGN "\xef\x9b\xb2" // U+f6f2 +#define ICON_FA_HURRICANE "\xef\x9d\x91" // U+f751 +#define ICON_FA_I "I" // U+0049 +#define ICON_FA_I_CURSOR "\xef\x89\x86" // U+f246 +#define ICON_FA_ICE_CREAM "\xef\xa0\x90" // U+f810 +#define ICON_FA_ICICLES "\xef\x9e\xad" // U+f7ad +#define ICON_FA_ICONS "\xef\xa1\xad" // U+f86d +#define ICON_FA_ID_BADGE "\xef\x8b\x81" // U+f2c1 +#define ICON_FA_ID_CARD "\xef\x8b\x82" // U+f2c2 +#define ICON_FA_ID_CARD_CLIP "\xef\x91\xbf" // U+f47f +#define ICON_FA_IGLOO "\xef\x9e\xae" // U+f7ae +#define ICON_FA_IMAGE "\xef\x80\xbe" // U+f03e +#define ICON_FA_IMAGE_PORTRAIT "\xef\x8f\xa0" // U+f3e0 +#define ICON_FA_IMAGES "\xef\x8c\x82" // U+f302 +#define ICON_FA_INBOX "\xef\x80\x9c" // U+f01c +#define ICON_FA_INDENT "\xef\x80\xbc" // U+f03c +#define ICON_FA_INDIAN_RUPEE_SIGN "\xee\x86\xbc" // U+e1bc +#define ICON_FA_INDUSTRY "\xef\x89\xb5" // U+f275 +#define ICON_FA_INFINITY "\xef\x94\xb4" // U+f534 +#define ICON_FA_INFO "\xef\x84\xa9" // U+f129 +#define ICON_FA_ITALIC "\xef\x80\xb3" // U+f033 +#define ICON_FA_J "J" // U+004a +#define ICON_FA_JAR "\xee\x94\x96" // U+e516 +#define ICON_FA_JAR_WHEAT "\xee\x94\x97" // U+e517 +#define ICON_FA_JEDI "\xef\x99\xa9" // U+f669 +#define ICON_FA_JET_FIGHTER "\xef\x83\xbb" // U+f0fb +#define ICON_FA_JET_FIGHTER_UP "\xee\x94\x98" // U+e518 +#define ICON_FA_JOINT "\xef\x96\x95" // U+f595 +#define ICON_FA_JUG_DETERGENT "\xee\x94\x99" // U+e519 +#define ICON_FA_K "K" // U+004b +#define ICON_FA_KAABA "\xef\x99\xab" // U+f66b +#define ICON_FA_KEY "\xef\x82\x84" // U+f084 +#define ICON_FA_KEYBOARD "\xef\x84\x9c" // U+f11c +#define ICON_FA_KHANDA "\xef\x99\xad" // U+f66d +#define ICON_FA_KIP_SIGN "\xee\x87\x84" // U+e1c4 +#define ICON_FA_KIT_MEDICAL "\xef\x91\xb9" // U+f479 +#define ICON_FA_KITCHEN_SET "\xee\x94\x9a" // U+e51a +#define ICON_FA_KIWI_BIRD "\xef\x94\xb5" // U+f535 +#define ICON_FA_L "L" // U+004c +#define ICON_FA_LAND_MINE_ON "\xee\x94\x9b" // U+e51b +#define ICON_FA_LANDMARK "\xef\x99\xaf" // U+f66f +#define ICON_FA_LANDMARK_DOME "\xef\x9d\x92" // U+f752 +#define ICON_FA_LANDMARK_FLAG "\xee\x94\x9c" // U+e51c +#define ICON_FA_LANGUAGE "\xef\x86\xab" // U+f1ab +#define ICON_FA_LAPTOP "\xef\x84\x89" // U+f109 +#define ICON_FA_LAPTOP_CODE "\xef\x97\xbc" // U+f5fc +#define ICON_FA_LAPTOP_FILE "\xee\x94\x9d" // U+e51d +#define ICON_FA_LAPTOP_MEDICAL "\xef\xa0\x92" // U+f812 +#define ICON_FA_LARI_SIGN "\xee\x87\x88" // U+e1c8 +#define ICON_FA_LAYER_GROUP "\xef\x97\xbd" // U+f5fd +#define ICON_FA_LEAF "\xef\x81\xac" // U+f06c +#define ICON_FA_LEFT_LONG "\xef\x8c\x8a" // U+f30a +#define ICON_FA_LEFT_RIGHT "\xef\x8c\xb7" // U+f337 +#define ICON_FA_LEMON "\xef\x82\x94" // U+f094 +#define ICON_FA_LESS_THAN "<" // U+003c +#define ICON_FA_LESS_THAN_EQUAL "\xef\x94\xb7" // U+f537 +#define ICON_FA_LIFE_RING "\xef\x87\x8d" // U+f1cd +#define ICON_FA_LIGHTBULB "\xef\x83\xab" // U+f0eb +#define ICON_FA_LINES_LEANING "\xee\x94\x9e" // U+e51e +#define ICON_FA_LINK "\xef\x83\x81" // U+f0c1 +#define ICON_FA_LINK_SLASH "\xef\x84\xa7" // U+f127 +#define ICON_FA_LIRA_SIGN "\xef\x86\x95" // U+f195 +#define ICON_FA_LIST "\xef\x80\xba" // U+f03a +#define ICON_FA_LIST_CHECK "\xef\x82\xae" // U+f0ae +#define ICON_FA_LIST_OL "\xef\x83\x8b" // U+f0cb +#define ICON_FA_LIST_UL "\xef\x83\x8a" // U+f0ca +#define ICON_FA_LITECOIN_SIGN "\xee\x87\x93" // U+e1d3 +#define ICON_FA_LOCATION_ARROW "\xef\x84\xa4" // U+f124 +#define ICON_FA_LOCATION_CROSSHAIRS "\xef\x98\x81" // U+f601 +#define ICON_FA_LOCATION_DOT "\xef\x8f\x85" // U+f3c5 +#define ICON_FA_LOCATION_PIN "\xef\x81\x81" // U+f041 +#define ICON_FA_LOCATION_PIN_LOCK "\xee\x94\x9f" // U+e51f +#define ICON_FA_LOCK "\xef\x80\xa3" // U+f023 +#define ICON_FA_LOCK_OPEN "\xef\x8f\x81" // U+f3c1 +#define ICON_FA_LOCUST "\xee\x94\xa0" // U+e520 +#define ICON_FA_LUNGS "\xef\x98\x84" // U+f604 +#define ICON_FA_LUNGS_VIRUS "\xee\x81\xa7" // U+e067 +#define ICON_FA_M "M" // U+004d +#define ICON_FA_MAGNET "\xef\x81\xb6" // U+f076 +#define ICON_FA_MAGNIFYING_GLASS "\xef\x80\x82" // U+f002 +#define ICON_FA_MAGNIFYING_GLASS_ARROW_RIGHT "\xee\x94\xa1" // U+e521 +#define ICON_FA_MAGNIFYING_GLASS_CHART "\xee\x94\xa2" // U+e522 +#define ICON_FA_MAGNIFYING_GLASS_DOLLAR "\xef\x9a\x88" // U+f688 +#define ICON_FA_MAGNIFYING_GLASS_LOCATION "\xef\x9a\x89" // U+f689 +#define ICON_FA_MAGNIFYING_GLASS_MINUS "\xef\x80\x90" // U+f010 +#define ICON_FA_MAGNIFYING_GLASS_PLUS "\xef\x80\x8e" // U+f00e +#define ICON_FA_MANAT_SIGN "\xee\x87\x95" // U+e1d5 +#define ICON_FA_MAP "\xef\x89\xb9" // U+f279 +#define ICON_FA_MAP_LOCATION "\xef\x96\x9f" // U+f59f +#define ICON_FA_MAP_LOCATION_DOT "\xef\x96\xa0" // U+f5a0 +#define ICON_FA_MAP_PIN "\xef\x89\xb6" // U+f276 +#define ICON_FA_MARKER "\xef\x96\xa1" // U+f5a1 +#define ICON_FA_MARS "\xef\x88\xa2" // U+f222 +#define ICON_FA_MARS_AND_VENUS "\xef\x88\xa4" // U+f224 +#define ICON_FA_MARS_AND_VENUS_BURST "\xee\x94\xa3" // U+e523 +#define ICON_FA_MARS_DOUBLE "\xef\x88\xa7" // U+f227 +#define ICON_FA_MARS_STROKE "\xef\x88\xa9" // U+f229 +#define ICON_FA_MARS_STROKE_RIGHT "\xef\x88\xab" // U+f22b +#define ICON_FA_MARS_STROKE_UP "\xef\x88\xaa" // U+f22a +#define ICON_FA_MARTINI_GLASS "\xef\x95\xbb" // U+f57b +#define ICON_FA_MARTINI_GLASS_CITRUS "\xef\x95\xa1" // U+f561 +#define ICON_FA_MARTINI_GLASS_EMPTY "\xef\x80\x80" // U+f000 +#define ICON_FA_MASK "\xef\x9b\xba" // U+f6fa +#define ICON_FA_MASK_FACE "\xee\x87\x97" // U+e1d7 +#define ICON_FA_MASK_VENTILATOR "\xee\x94\xa4" // U+e524 +#define ICON_FA_MASKS_THEATER "\xef\x98\xb0" // U+f630 +#define ICON_FA_MATTRESS_PILLOW "\xee\x94\xa5" // U+e525 +#define ICON_FA_MAXIMIZE "\xef\x8c\x9e" // U+f31e +#define ICON_FA_MEDAL "\xef\x96\xa2" // U+f5a2 +#define ICON_FA_MEMORY "\xef\x94\xb8" // U+f538 +#define ICON_FA_MENORAH "\xef\x99\xb6" // U+f676 +#define ICON_FA_MERCURY "\xef\x88\xa3" // U+f223 +#define ICON_FA_MESSAGE "\xef\x89\xba" // U+f27a +#define ICON_FA_METEOR "\xef\x9d\x93" // U+f753 +#define ICON_FA_MICROCHIP "\xef\x8b\x9b" // U+f2db +#define ICON_FA_MICROPHONE "\xef\x84\xb0" // U+f130 +#define ICON_FA_MICROPHONE_LINES "\xef\x8f\x89" // U+f3c9 +#define ICON_FA_MICROPHONE_LINES_SLASH "\xef\x94\xb9" // U+f539 +#define ICON_FA_MICROPHONE_SLASH "\xef\x84\xb1" // U+f131 +#define ICON_FA_MICROSCOPE "\xef\x98\x90" // U+f610 +#define ICON_FA_MILL_SIGN "\xee\x87\xad" // U+e1ed +#define ICON_FA_MINIMIZE "\xef\x9e\x8c" // U+f78c +#define ICON_FA_MINUS "\xef\x81\xa8" // U+f068 +#define ICON_FA_MITTEN "\xef\x9e\xb5" // U+f7b5 +#define ICON_FA_MOBILE "\xef\x8f\x8e" // U+f3ce +#define ICON_FA_MOBILE_BUTTON "\xef\x84\x8b" // U+f10b +#define ICON_FA_MOBILE_RETRO "\xee\x94\xa7" // U+e527 +#define ICON_FA_MOBILE_SCREEN "\xef\x8f\x8f" // U+f3cf +#define ICON_FA_MOBILE_SCREEN_BUTTON "\xef\x8f\x8d" // U+f3cd +#define ICON_FA_MONEY_BILL "\xef\x83\x96" // U+f0d6 +#define ICON_FA_MONEY_BILL_1 "\xef\x8f\x91" // U+f3d1 +#define ICON_FA_MONEY_BILL_1_WAVE "\xef\x94\xbb" // U+f53b +#define ICON_FA_MONEY_BILL_TRANSFER "\xee\x94\xa8" // U+e528 +#define ICON_FA_MONEY_BILL_TREND_UP "\xee\x94\xa9" // U+e529 +#define ICON_FA_MONEY_BILL_WAVE "\xef\x94\xba" // U+f53a +#define ICON_FA_MONEY_BILL_WHEAT "\xee\x94\xaa" // U+e52a +#define ICON_FA_MONEY_BILLS "\xee\x87\xb3" // U+e1f3 +#define ICON_FA_MONEY_CHECK "\xef\x94\xbc" // U+f53c +#define ICON_FA_MONEY_CHECK_DOLLAR "\xef\x94\xbd" // U+f53d +#define ICON_FA_MONUMENT "\xef\x96\xa6" // U+f5a6 +#define ICON_FA_MOON "\xef\x86\x86" // U+f186 +#define ICON_FA_MORTAR_PESTLE "\xef\x96\xa7" // U+f5a7 +#define ICON_FA_MOSQUE "\xef\x99\xb8" // U+f678 +#define ICON_FA_MOSQUITO "\xee\x94\xab" // U+e52b +#define ICON_FA_MOSQUITO_NET "\xee\x94\xac" // U+e52c +#define ICON_FA_MOTORCYCLE "\xef\x88\x9c" // U+f21c +#define ICON_FA_MOUND "\xee\x94\xad" // U+e52d +#define ICON_FA_MOUNTAIN "\xef\x9b\xbc" // U+f6fc +#define ICON_FA_MOUNTAIN_CITY "\xee\x94\xae" // U+e52e +#define ICON_FA_MOUNTAIN_SUN "\xee\x94\xaf" // U+e52f +#define ICON_FA_MUG_HOT "\xef\x9e\xb6" // U+f7b6 +#define ICON_FA_MUG_SAUCER "\xef\x83\xb4" // U+f0f4 +#define ICON_FA_MUSIC "\xef\x80\x81" // U+f001 +#define ICON_FA_N "N" // U+004e +#define ICON_FA_NAIRA_SIGN "\xee\x87\xb6" // U+e1f6 +#define ICON_FA_NETWORK_WIRED "\xef\x9b\xbf" // U+f6ff +#define ICON_FA_NEUTER "\xef\x88\xac" // U+f22c +#define ICON_FA_NEWSPAPER "\xef\x87\xaa" // U+f1ea +#define ICON_FA_NOT_EQUAL "\xef\x94\xbe" // U+f53e +#define ICON_FA_NOTDEF "\xee\x87\xbe" // U+e1fe +#define ICON_FA_NOTE_STICKY "\xef\x89\x89" // U+f249 +#define ICON_FA_NOTES_MEDICAL "\xef\x92\x81" // U+f481 +#define ICON_FA_O "O" // U+004f +#define ICON_FA_OBJECT_GROUP "\xef\x89\x87" // U+f247 +#define ICON_FA_OBJECT_UNGROUP "\xef\x89\x88" // U+f248 +#define ICON_FA_OIL_CAN "\xef\x98\x93" // U+f613 +#define ICON_FA_OIL_WELL "\xee\x94\xb2" // U+e532 +#define ICON_FA_OM "\xef\x99\xb9" // U+f679 +#define ICON_FA_OTTER "\xef\x9c\x80" // U+f700 +#define ICON_FA_OUTDENT "\xef\x80\xbb" // U+f03b +#define ICON_FA_P "P" // U+0050 +#define ICON_FA_PAGER "\xef\xa0\x95" // U+f815 +#define ICON_FA_PAINT_ROLLER "\xef\x96\xaa" // U+f5aa +#define ICON_FA_PAINTBRUSH "\xef\x87\xbc" // U+f1fc +#define ICON_FA_PALETTE "\xef\x94\xbf" // U+f53f +#define ICON_FA_PALLET "\xef\x92\x82" // U+f482 +#define ICON_FA_PANORAMA "\xee\x88\x89" // U+e209 +#define ICON_FA_PAPER_PLANE "\xef\x87\x98" // U+f1d8 +#define ICON_FA_PAPERCLIP "\xef\x83\x86" // U+f0c6 +#define ICON_FA_PARACHUTE_BOX "\xef\x93\x8d" // U+f4cd +#define ICON_FA_PARAGRAPH "\xef\x87\x9d" // U+f1dd +#define ICON_FA_PASSPORT "\xef\x96\xab" // U+f5ab +#define ICON_FA_PASTE "\xef\x83\xaa" // U+f0ea +#define ICON_FA_PAUSE "\xef\x81\x8c" // U+f04c +#define ICON_FA_PAW "\xef\x86\xb0" // U+f1b0 +#define ICON_FA_PEACE "\xef\x99\xbc" // U+f67c +#define ICON_FA_PEN "\xef\x8c\x84" // U+f304 +#define ICON_FA_PEN_CLIP "\xef\x8c\x85" // U+f305 +#define ICON_FA_PEN_FANCY "\xef\x96\xac" // U+f5ac +#define ICON_FA_PEN_NIB "\xef\x96\xad" // U+f5ad +#define ICON_FA_PEN_RULER "\xef\x96\xae" // U+f5ae +#define ICON_FA_PEN_TO_SQUARE "\xef\x81\x84" // U+f044 +#define ICON_FA_PENCIL "\xef\x8c\x83" // U+f303 +#define ICON_FA_PEOPLE_ARROWS "\xee\x81\xa8" // U+e068 +#define ICON_FA_PEOPLE_CARRY_BOX "\xef\x93\x8e" // U+f4ce +#define ICON_FA_PEOPLE_GROUP "\xee\x94\xb3" // U+e533 +#define ICON_FA_PEOPLE_LINE "\xee\x94\xb4" // U+e534 +#define ICON_FA_PEOPLE_PULLING "\xee\x94\xb5" // U+e535 +#define ICON_FA_PEOPLE_ROBBERY "\xee\x94\xb6" // U+e536 +#define ICON_FA_PEOPLE_ROOF "\xee\x94\xb7" // U+e537 +#define ICON_FA_PEPPER_HOT "\xef\xa0\x96" // U+f816 +#define ICON_FA_PERCENT "%" // U+0025 +#define ICON_FA_PERSON "\xef\x86\x83" // U+f183 +#define ICON_FA_PERSON_ARROW_DOWN_TO_LINE "\xee\x94\xb8" // U+e538 +#define ICON_FA_PERSON_ARROW_UP_FROM_LINE "\xee\x94\xb9" // U+e539 +#define ICON_FA_PERSON_BIKING "\xef\xa1\x8a" // U+f84a +#define ICON_FA_PERSON_BOOTH "\xef\x9d\x96" // U+f756 +#define ICON_FA_PERSON_BREASTFEEDING "\xee\x94\xba" // U+e53a +#define ICON_FA_PERSON_BURST "\xee\x94\xbb" // U+e53b +#define ICON_FA_PERSON_CANE "\xee\x94\xbc" // U+e53c +#define ICON_FA_PERSON_CHALKBOARD "\xee\x94\xbd" // U+e53d +#define ICON_FA_PERSON_CIRCLE_CHECK "\xee\x94\xbe" // U+e53e +#define ICON_FA_PERSON_CIRCLE_EXCLAMATION "\xee\x94\xbf" // U+e53f +#define ICON_FA_PERSON_CIRCLE_MINUS "\xee\x95\x80" // U+e540 +#define ICON_FA_PERSON_CIRCLE_PLUS "\xee\x95\x81" // U+e541 +#define ICON_FA_PERSON_CIRCLE_QUESTION "\xee\x95\x82" // U+e542 +#define ICON_FA_PERSON_CIRCLE_XMARK "\xee\x95\x83" // U+e543 +#define ICON_FA_PERSON_DIGGING "\xef\xa1\x9e" // U+f85e +#define ICON_FA_PERSON_DOTS_FROM_LINE "\xef\x91\xb0" // U+f470 +#define ICON_FA_PERSON_DRESS "\xef\x86\x82" // U+f182 +#define ICON_FA_PERSON_DRESS_BURST "\xee\x95\x84" // U+e544 +#define ICON_FA_PERSON_DROWNING "\xee\x95\x85" // U+e545 +#define ICON_FA_PERSON_FALLING "\xee\x95\x86" // U+e546 +#define ICON_FA_PERSON_FALLING_BURST "\xee\x95\x87" // U+e547 +#define ICON_FA_PERSON_HALF_DRESS "\xee\x95\x88" // U+e548 +#define ICON_FA_PERSON_HARASSING "\xee\x95\x89" // U+e549 +#define ICON_FA_PERSON_HIKING "\xef\x9b\xac" // U+f6ec +#define ICON_FA_PERSON_MILITARY_POINTING "\xee\x95\x8a" // U+e54a +#define ICON_FA_PERSON_MILITARY_RIFLE "\xee\x95\x8b" // U+e54b +#define ICON_FA_PERSON_MILITARY_TO_PERSON "\xee\x95\x8c" // U+e54c +#define ICON_FA_PERSON_PRAYING "\xef\x9a\x83" // U+f683 +#define ICON_FA_PERSON_PREGNANT "\xee\x8c\x9e" // U+e31e +#define ICON_FA_PERSON_RAYS "\xee\x95\x8d" // U+e54d +#define ICON_FA_PERSON_RIFLE "\xee\x95\x8e" // U+e54e +#define ICON_FA_PERSON_RUNNING "\xef\x9c\x8c" // U+f70c +#define ICON_FA_PERSON_SHELTER "\xee\x95\x8f" // U+e54f +#define ICON_FA_PERSON_SKATING "\xef\x9f\x85" // U+f7c5 +#define ICON_FA_PERSON_SKIING "\xef\x9f\x89" // U+f7c9 +#define ICON_FA_PERSON_SKIING_NORDIC "\xef\x9f\x8a" // U+f7ca +#define ICON_FA_PERSON_SNOWBOARDING "\xef\x9f\x8e" // U+f7ce +#define ICON_FA_PERSON_SWIMMING "\xef\x97\x84" // U+f5c4 +#define ICON_FA_PERSON_THROUGH_WINDOW "\xee\x96\xa9" // U+e5a9 +#define ICON_FA_PERSON_WALKING "\xef\x95\x94" // U+f554 +#define ICON_FA_PERSON_WALKING_ARROW_LOOP_LEFT "\xee\x95\x91" // U+e551 +#define ICON_FA_PERSON_WALKING_ARROW_RIGHT "\xee\x95\x92" // U+e552 +#define ICON_FA_PERSON_WALKING_DASHED_LINE_ARROW_RIGHT "\xee\x95\x93" // U+e553 +#define ICON_FA_PERSON_WALKING_LUGGAGE "\xee\x95\x94" // U+e554 +#define ICON_FA_PERSON_WALKING_WITH_CANE "\xef\x8a\x9d" // U+f29d +#define ICON_FA_PESETA_SIGN "\xee\x88\xa1" // U+e221 +#define ICON_FA_PESO_SIGN "\xee\x88\xa2" // U+e222 +#define ICON_FA_PHONE "\xef\x82\x95" // U+f095 +#define ICON_FA_PHONE_FLIP "\xef\xa1\xb9" // U+f879 +#define ICON_FA_PHONE_SLASH "\xef\x8f\x9d" // U+f3dd +#define ICON_FA_PHONE_VOLUME "\xef\x8a\xa0" // U+f2a0 +#define ICON_FA_PHOTO_FILM "\xef\xa1\xbc" // U+f87c +#define ICON_FA_PIGGY_BANK "\xef\x93\x93" // U+f4d3 +#define ICON_FA_PILLS "\xef\x92\x84" // U+f484 +#define ICON_FA_PIZZA_SLICE "\xef\xa0\x98" // U+f818 +#define ICON_FA_PLACE_OF_WORSHIP "\xef\x99\xbf" // U+f67f +#define ICON_FA_PLANE "\xef\x81\xb2" // U+f072 +#define ICON_FA_PLANE_ARRIVAL "\xef\x96\xaf" // U+f5af +#define ICON_FA_PLANE_CIRCLE_CHECK "\xee\x95\x95" // U+e555 +#define ICON_FA_PLANE_CIRCLE_EXCLAMATION "\xee\x95\x96" // U+e556 +#define ICON_FA_PLANE_CIRCLE_XMARK "\xee\x95\x97" // U+e557 +#define ICON_FA_PLANE_DEPARTURE "\xef\x96\xb0" // U+f5b0 +#define ICON_FA_PLANE_LOCK "\xee\x95\x98" // U+e558 +#define ICON_FA_PLANE_SLASH "\xee\x81\xa9" // U+e069 +#define ICON_FA_PLANE_UP "\xee\x88\xad" // U+e22d +#define ICON_FA_PLANT_WILT "\xee\x96\xaa" // U+e5aa +#define ICON_FA_PLATE_WHEAT "\xee\x95\x9a" // U+e55a +#define ICON_FA_PLAY "\xef\x81\x8b" // U+f04b +#define ICON_FA_PLUG "\xef\x87\xa6" // U+f1e6 +#define ICON_FA_PLUG_CIRCLE_BOLT "\xee\x95\x9b" // U+e55b +#define ICON_FA_PLUG_CIRCLE_CHECK "\xee\x95\x9c" // U+e55c +#define ICON_FA_PLUG_CIRCLE_EXCLAMATION "\xee\x95\x9d" // U+e55d +#define ICON_FA_PLUG_CIRCLE_MINUS "\xee\x95\x9e" // U+e55e +#define ICON_FA_PLUG_CIRCLE_PLUS "\xee\x95\x9f" // U+e55f +#define ICON_FA_PLUG_CIRCLE_XMARK "\xee\x95\xa0" // U+e560 +#define ICON_FA_PLUS "+" // U+002b +#define ICON_FA_PLUS_MINUS "\xee\x90\xbc" // U+e43c +#define ICON_FA_PODCAST "\xef\x8b\x8e" // U+f2ce +#define ICON_FA_POO "\xef\x8b\xbe" // U+f2fe +#define ICON_FA_POO_STORM "\xef\x9d\x9a" // U+f75a +#define ICON_FA_POOP "\xef\x98\x99" // U+f619 +#define ICON_FA_POWER_OFF "\xef\x80\x91" // U+f011 +#define ICON_FA_PRESCRIPTION "\xef\x96\xb1" // U+f5b1 +#define ICON_FA_PRESCRIPTION_BOTTLE "\xef\x92\x85" // U+f485 +#define ICON_FA_PRESCRIPTION_BOTTLE_MEDICAL "\xef\x92\x86" // U+f486 +#define ICON_FA_PRINT "\xef\x80\xaf" // U+f02f +#define ICON_FA_PUMP_MEDICAL "\xee\x81\xaa" // U+e06a +#define ICON_FA_PUMP_SOAP "\xee\x81\xab" // U+e06b +#define ICON_FA_PUZZLE_PIECE "\xef\x84\xae" // U+f12e +#define ICON_FA_Q "Q" // U+0051 +#define ICON_FA_QRCODE "\xef\x80\xa9" // U+f029 +#define ICON_FA_QUESTION "?" // U+003f +#define ICON_FA_QUOTE_LEFT "\xef\x84\x8d" // U+f10d +#define ICON_FA_QUOTE_RIGHT "\xef\x84\x8e" // U+f10e +#define ICON_FA_R "R" // U+0052 +#define ICON_FA_RADIATION "\xef\x9e\xb9" // U+f7b9 +#define ICON_FA_RADIO "\xef\xa3\x97" // U+f8d7 +#define ICON_FA_RAINBOW "\xef\x9d\x9b" // U+f75b +#define ICON_FA_RANKING_STAR "\xee\x95\xa1" // U+e561 +#define ICON_FA_RECEIPT "\xef\x95\x83" // U+f543 +#define ICON_FA_RECORD_VINYL "\xef\xa3\x99" // U+f8d9 +#define ICON_FA_RECTANGLE_AD "\xef\x99\x81" // U+f641 +#define ICON_FA_RECTANGLE_LIST "\xef\x80\xa2" // U+f022 +#define ICON_FA_RECTANGLE_XMARK "\xef\x90\x90" // U+f410 +#define ICON_FA_RECYCLE "\xef\x86\xb8" // U+f1b8 +#define ICON_FA_REGISTERED "\xef\x89\x9d" // U+f25d +#define ICON_FA_REPEAT "\xef\x8d\xa3" // U+f363 +#define ICON_FA_REPLY "\xef\x8f\xa5" // U+f3e5 +#define ICON_FA_REPLY_ALL "\xef\x84\xa2" // U+f122 +#define ICON_FA_REPUBLICAN "\xef\x9d\x9e" // U+f75e +#define ICON_FA_RESTROOM "\xef\x9e\xbd" // U+f7bd +#define ICON_FA_RETWEET "\xef\x81\xb9" // U+f079 +#define ICON_FA_RIBBON "\xef\x93\x96" // U+f4d6 +#define ICON_FA_RIGHT_FROM_BRACKET "\xef\x8b\xb5" // U+f2f5 +#define ICON_FA_RIGHT_LEFT "\xef\x8d\xa2" // U+f362 +#define ICON_FA_RIGHT_LONG "\xef\x8c\x8b" // U+f30b +#define ICON_FA_RIGHT_TO_BRACKET "\xef\x8b\xb6" // U+f2f6 +#define ICON_FA_RING "\xef\x9c\x8b" // U+f70b +#define ICON_FA_ROAD "\xef\x80\x98" // U+f018 +#define ICON_FA_ROAD_BARRIER "\xee\x95\xa2" // U+e562 +#define ICON_FA_ROAD_BRIDGE "\xee\x95\xa3" // U+e563 +#define ICON_FA_ROAD_CIRCLE_CHECK "\xee\x95\xa4" // U+e564 +#define ICON_FA_ROAD_CIRCLE_EXCLAMATION "\xee\x95\xa5" // U+e565 +#define ICON_FA_ROAD_CIRCLE_XMARK "\xee\x95\xa6" // U+e566 +#define ICON_FA_ROAD_LOCK "\xee\x95\xa7" // U+e567 +#define ICON_FA_ROAD_SPIKES "\xee\x95\xa8" // U+e568 +#define ICON_FA_ROBOT "\xef\x95\x84" // U+f544 +#define ICON_FA_ROCKET "\xef\x84\xb5" // U+f135 +#define ICON_FA_ROTATE "\xef\x8b\xb1" // U+f2f1 +#define ICON_FA_ROTATE_LEFT "\xef\x8b\xaa" // U+f2ea +#define ICON_FA_ROTATE_RIGHT "\xef\x8b\xb9" // U+f2f9 +#define ICON_FA_ROUTE "\xef\x93\x97" // U+f4d7 +#define ICON_FA_RSS "\xef\x82\x9e" // U+f09e +#define ICON_FA_RUBLE_SIGN "\xef\x85\x98" // U+f158 +#define ICON_FA_RUG "\xee\x95\xa9" // U+e569 +#define ICON_FA_RULER "\xef\x95\x85" // U+f545 +#define ICON_FA_RULER_COMBINED "\xef\x95\x86" // U+f546 +#define ICON_FA_RULER_HORIZONTAL "\xef\x95\x87" // U+f547 +#define ICON_FA_RULER_VERTICAL "\xef\x95\x88" // U+f548 +#define ICON_FA_RUPEE_SIGN "\xef\x85\x96" // U+f156 +#define ICON_FA_RUPIAH_SIGN "\xee\x88\xbd" // U+e23d +#define ICON_FA_S "S" // U+0053 +#define ICON_FA_SACK_DOLLAR "\xef\xa0\x9d" // U+f81d +#define ICON_FA_SACK_XMARK "\xee\x95\xaa" // U+e56a +#define ICON_FA_SAILBOAT "\xee\x91\x85" // U+e445 +#define ICON_FA_SATELLITE "\xef\x9e\xbf" // U+f7bf +#define ICON_FA_SATELLITE_DISH "\xef\x9f\x80" // U+f7c0 +#define ICON_FA_SCALE_BALANCED "\xef\x89\x8e" // U+f24e +#define ICON_FA_SCALE_UNBALANCED "\xef\x94\x95" // U+f515 +#define ICON_FA_SCALE_UNBALANCED_FLIP "\xef\x94\x96" // U+f516 +#define ICON_FA_SCHOOL "\xef\x95\x89" // U+f549 +#define ICON_FA_SCHOOL_CIRCLE_CHECK "\xee\x95\xab" // U+e56b +#define ICON_FA_SCHOOL_CIRCLE_EXCLAMATION "\xee\x95\xac" // U+e56c +#define ICON_FA_SCHOOL_CIRCLE_XMARK "\xee\x95\xad" // U+e56d +#define ICON_FA_SCHOOL_FLAG "\xee\x95\xae" // U+e56e +#define ICON_FA_SCHOOL_LOCK "\xee\x95\xaf" // U+e56f +#define ICON_FA_SCISSORS "\xef\x83\x84" // U+f0c4 +#define ICON_FA_SCREWDRIVER "\xef\x95\x8a" // U+f54a +#define ICON_FA_SCREWDRIVER_WRENCH "\xef\x9f\x99" // U+f7d9 +#define ICON_FA_SCROLL "\xef\x9c\x8e" // U+f70e +#define ICON_FA_SCROLL_TORAH "\xef\x9a\xa0" // U+f6a0 +#define ICON_FA_SD_CARD "\xef\x9f\x82" // U+f7c2 +#define ICON_FA_SECTION "\xee\x91\x87" // U+e447 +#define ICON_FA_SEEDLING "\xef\x93\x98" // U+f4d8 +#define ICON_FA_SERVER "\xef\x88\xb3" // U+f233 +#define ICON_FA_SHAPES "\xef\x98\x9f" // U+f61f +#define ICON_FA_SHARE "\xef\x81\xa4" // U+f064 +#define ICON_FA_SHARE_FROM_SQUARE "\xef\x85\x8d" // U+f14d +#define ICON_FA_SHARE_NODES "\xef\x87\xa0" // U+f1e0 +#define ICON_FA_SHEET_PLASTIC "\xee\x95\xb1" // U+e571 +#define ICON_FA_SHEKEL_SIGN "\xef\x88\x8b" // U+f20b +#define ICON_FA_SHIELD "\xef\x84\xb2" // U+f132 +#define ICON_FA_SHIELD_CAT "\xee\x95\xb2" // U+e572 +#define ICON_FA_SHIELD_DOG "\xee\x95\xb3" // U+e573 +#define ICON_FA_SHIELD_HALVED "\xef\x8f\xad" // U+f3ed +#define ICON_FA_SHIELD_HEART "\xee\x95\xb4" // U+e574 +#define ICON_FA_SHIELD_VIRUS "\xee\x81\xac" // U+e06c +#define ICON_FA_SHIP "\xef\x88\x9a" // U+f21a +#define ICON_FA_SHIRT "\xef\x95\x93" // U+f553 +#define ICON_FA_SHOE_PRINTS "\xef\x95\x8b" // U+f54b +#define ICON_FA_SHOP "\xef\x95\x8f" // U+f54f +#define ICON_FA_SHOP_LOCK "\xee\x92\xa5" // U+e4a5 +#define ICON_FA_SHOP_SLASH "\xee\x81\xb0" // U+e070 +#define ICON_FA_SHOWER "\xef\x8b\x8c" // U+f2cc +#define ICON_FA_SHRIMP "\xee\x91\x88" // U+e448 +#define ICON_FA_SHUFFLE "\xef\x81\xb4" // U+f074 +#define ICON_FA_SHUTTLE_SPACE "\xef\x86\x97" // U+f197 +#define ICON_FA_SIGN_HANGING "\xef\x93\x99" // U+f4d9 +#define ICON_FA_SIGNAL "\xef\x80\x92" // U+f012 +#define ICON_FA_SIGNATURE "\xef\x96\xb7" // U+f5b7 +#define ICON_FA_SIGNS_POST "\xef\x89\xb7" // U+f277 +#define ICON_FA_SIM_CARD "\xef\x9f\x84" // U+f7c4 +#define ICON_FA_SINK "\xee\x81\xad" // U+e06d +#define ICON_FA_SITEMAP "\xef\x83\xa8" // U+f0e8 +#define ICON_FA_SKULL "\xef\x95\x8c" // U+f54c +#define ICON_FA_SKULL_CROSSBONES "\xef\x9c\x94" // U+f714 +#define ICON_FA_SLASH "\xef\x9c\x95" // U+f715 +#define ICON_FA_SLEIGH "\xef\x9f\x8c" // U+f7cc +#define ICON_FA_SLIDERS "\xef\x87\x9e" // U+f1de +#define ICON_FA_SMOG "\xef\x9d\x9f" // U+f75f +#define ICON_FA_SMOKING "\xef\x92\x8d" // U+f48d +#define ICON_FA_SNOWFLAKE "\xef\x8b\x9c" // U+f2dc +#define ICON_FA_SNOWMAN "\xef\x9f\x90" // U+f7d0 +#define ICON_FA_SNOWPLOW "\xef\x9f\x92" // U+f7d2 +#define ICON_FA_SOAP "\xee\x81\xae" // U+e06e +#define ICON_FA_SOCKS "\xef\x9a\x96" // U+f696 +#define ICON_FA_SOLAR_PANEL "\xef\x96\xba" // U+f5ba +#define ICON_FA_SORT "\xef\x83\x9c" // U+f0dc +#define ICON_FA_SORT_DOWN "\xef\x83\x9d" // U+f0dd +#define ICON_FA_SORT_UP "\xef\x83\x9e" // U+f0de +#define ICON_FA_SPA "\xef\x96\xbb" // U+f5bb +#define ICON_FA_SPAGHETTI_MONSTER_FLYING "\xef\x99\xbb" // U+f67b +#define ICON_FA_SPELL_CHECK "\xef\xa2\x91" // U+f891 +#define ICON_FA_SPIDER "\xef\x9c\x97" // U+f717 +#define ICON_FA_SPINNER "\xef\x84\x90" // U+f110 +#define ICON_FA_SPLOTCH "\xef\x96\xbc" // U+f5bc +#define ICON_FA_SPOON "\xef\x8b\xa5" // U+f2e5 +#define ICON_FA_SPRAY_CAN "\xef\x96\xbd" // U+f5bd +#define ICON_FA_SPRAY_CAN_SPARKLES "\xef\x97\x90" // U+f5d0 +#define ICON_FA_SQUARE "\xef\x83\x88" // U+f0c8 +#define ICON_FA_SQUARE_ARROW_UP_RIGHT "\xef\x85\x8c" // U+f14c +#define ICON_FA_SQUARE_BINARY "\xee\x9a\x9b" // U+e69b +#define ICON_FA_SQUARE_CARET_DOWN "\xef\x85\x90" // U+f150 +#define ICON_FA_SQUARE_CARET_LEFT "\xef\x86\x91" // U+f191 +#define ICON_FA_SQUARE_CARET_RIGHT "\xef\x85\x92" // U+f152 +#define ICON_FA_SQUARE_CARET_UP "\xef\x85\x91" // U+f151 +#define ICON_FA_SQUARE_CHECK "\xef\x85\x8a" // U+f14a +#define ICON_FA_SQUARE_ENVELOPE "\xef\x86\x99" // U+f199 +#define ICON_FA_SQUARE_FULL "\xef\x91\x9c" // U+f45c +#define ICON_FA_SQUARE_H "\xef\x83\xbd" // U+f0fd +#define ICON_FA_SQUARE_MINUS "\xef\x85\x86" // U+f146 +#define ICON_FA_SQUARE_NFI "\xee\x95\xb6" // U+e576 +#define ICON_FA_SQUARE_PARKING "\xef\x95\x80" // U+f540 +#define ICON_FA_SQUARE_PEN "\xef\x85\x8b" // U+f14b +#define ICON_FA_SQUARE_PERSON_CONFINED "\xee\x95\xb7" // U+e577 +#define ICON_FA_SQUARE_PHONE "\xef\x82\x98" // U+f098 +#define ICON_FA_SQUARE_PHONE_FLIP "\xef\xa1\xbb" // U+f87b +#define ICON_FA_SQUARE_PLUS "\xef\x83\xbe" // U+f0fe +#define ICON_FA_SQUARE_POLL_HORIZONTAL "\xef\x9a\x82" // U+f682 +#define ICON_FA_SQUARE_POLL_VERTICAL "\xef\x9a\x81" // U+f681 +#define ICON_FA_SQUARE_ROOT_VARIABLE "\xef\x9a\x98" // U+f698 +#define ICON_FA_SQUARE_RSS "\xef\x85\x83" // U+f143 +#define ICON_FA_SQUARE_SHARE_NODES "\xef\x87\xa1" // U+f1e1 +#define ICON_FA_SQUARE_UP_RIGHT "\xef\x8d\xa0" // U+f360 +#define ICON_FA_SQUARE_VIRUS "\xee\x95\xb8" // U+e578 +#define ICON_FA_SQUARE_XMARK "\xef\x8b\x93" // U+f2d3 +#define ICON_FA_STAFF_SNAKE "\xee\x95\xb9" // U+e579 +#define ICON_FA_STAIRS "\xee\x8a\x89" // U+e289 +#define ICON_FA_STAMP "\xef\x96\xbf" // U+f5bf +#define ICON_FA_STAPLER "\xee\x96\xaf" // U+e5af +#define ICON_FA_STAR "\xef\x80\x85" // U+f005 +#define ICON_FA_STAR_AND_CRESCENT "\xef\x9a\x99" // U+f699 +#define ICON_FA_STAR_HALF "\xef\x82\x89" // U+f089 +#define ICON_FA_STAR_HALF_STROKE "\xef\x97\x80" // U+f5c0 +#define ICON_FA_STAR_OF_DAVID "\xef\x9a\x9a" // U+f69a +#define ICON_FA_STAR_OF_LIFE "\xef\x98\xa1" // U+f621 +#define ICON_FA_STERLING_SIGN "\xef\x85\x94" // U+f154 +#define ICON_FA_STETHOSCOPE "\xef\x83\xb1" // U+f0f1 +#define ICON_FA_STOP "\xef\x81\x8d" // U+f04d +#define ICON_FA_STOPWATCH "\xef\x8b\xb2" // U+f2f2 +#define ICON_FA_STOPWATCH_20 "\xee\x81\xaf" // U+e06f +#define ICON_FA_STORE "\xef\x95\x8e" // U+f54e +#define ICON_FA_STORE_SLASH "\xee\x81\xb1" // U+e071 +#define ICON_FA_STREET_VIEW "\xef\x88\x9d" // U+f21d +#define ICON_FA_STRIKETHROUGH "\xef\x83\x8c" // U+f0cc +#define ICON_FA_STROOPWAFEL "\xef\x95\x91" // U+f551 +#define ICON_FA_SUBSCRIPT "\xef\x84\xac" // U+f12c +#define ICON_FA_SUITCASE "\xef\x83\xb2" // U+f0f2 +#define ICON_FA_SUITCASE_MEDICAL "\xef\x83\xba" // U+f0fa +#define ICON_FA_SUITCASE_ROLLING "\xef\x97\x81" // U+f5c1 +#define ICON_FA_SUN "\xef\x86\x85" // U+f185 +#define ICON_FA_SUN_PLANT_WILT "\xee\x95\xba" // U+e57a +#define ICON_FA_SUPERSCRIPT "\xef\x84\xab" // U+f12b +#define ICON_FA_SWATCHBOOK "\xef\x97\x83" // U+f5c3 +#define ICON_FA_SYNAGOGUE "\xef\x9a\x9b" // U+f69b +#define ICON_FA_SYRINGE "\xef\x92\x8e" // U+f48e +#define ICON_FA_T "T" // U+0054 +#define ICON_FA_TABLE "\xef\x83\x8e" // U+f0ce +#define ICON_FA_TABLE_CELLS "\xef\x80\x8a" // U+f00a +#define ICON_FA_TABLE_CELLS_COLUMN_LOCK "\xee\x99\xb8" // U+e678 +#define ICON_FA_TABLE_CELLS_LARGE "\xef\x80\x89" // U+f009 +#define ICON_FA_TABLE_CELLS_ROW_LOCK "\xee\x99\xba" // U+e67a +#define ICON_FA_TABLE_CELLS_ROW_UNLOCK "\xee\x9a\x91" // U+e691 +#define ICON_FA_TABLE_COLUMNS "\xef\x83\x9b" // U+f0db +#define ICON_FA_TABLE_LIST "\xef\x80\x8b" // U+f00b +#define ICON_FA_TABLE_TENNIS_PADDLE_BALL "\xef\x91\x9d" // U+f45d +#define ICON_FA_TABLET "\xef\x8f\xbb" // U+f3fb +#define ICON_FA_TABLET_BUTTON "\xef\x84\x8a" // U+f10a +#define ICON_FA_TABLET_SCREEN_BUTTON "\xef\x8f\xba" // U+f3fa +#define ICON_FA_TABLETS "\xef\x92\x90" // U+f490 +#define ICON_FA_TACHOGRAPH_DIGITAL "\xef\x95\xa6" // U+f566 +#define ICON_FA_TAG "\xef\x80\xab" // U+f02b +#define ICON_FA_TAGS "\xef\x80\xac" // U+f02c +#define ICON_FA_TAPE "\xef\x93\x9b" // U+f4db +#define ICON_FA_TARP "\xee\x95\xbb" // U+e57b +#define ICON_FA_TARP_DROPLET "\xee\x95\xbc" // U+e57c +#define ICON_FA_TAXI "\xef\x86\xba" // U+f1ba +#define ICON_FA_TEETH "\xef\x98\xae" // U+f62e +#define ICON_FA_TEETH_OPEN "\xef\x98\xaf" // U+f62f +#define ICON_FA_TEMPERATURE_ARROW_DOWN "\xee\x80\xbf" // U+e03f +#define ICON_FA_TEMPERATURE_ARROW_UP "\xee\x81\x80" // U+e040 +#define ICON_FA_TEMPERATURE_EMPTY "\xef\x8b\x8b" // U+f2cb +#define ICON_FA_TEMPERATURE_FULL "\xef\x8b\x87" // U+f2c7 +#define ICON_FA_TEMPERATURE_HALF "\xef\x8b\x89" // U+f2c9 +#define ICON_FA_TEMPERATURE_HIGH "\xef\x9d\xa9" // U+f769 +#define ICON_FA_TEMPERATURE_LOW "\xef\x9d\xab" // U+f76b +#define ICON_FA_TEMPERATURE_QUARTER "\xef\x8b\x8a" // U+f2ca +#define ICON_FA_TEMPERATURE_THREE_QUARTERS "\xef\x8b\x88" // U+f2c8 +#define ICON_FA_TENGE_SIGN "\xef\x9f\x97" // U+f7d7 +#define ICON_FA_TENT "\xee\x95\xbd" // U+e57d +#define ICON_FA_TENT_ARROW_DOWN_TO_LINE "\xee\x95\xbe" // U+e57e +#define ICON_FA_TENT_ARROW_LEFT_RIGHT "\xee\x95\xbf" // U+e57f +#define ICON_FA_TENT_ARROW_TURN_LEFT "\xee\x96\x80" // U+e580 +#define ICON_FA_TENT_ARROWS_DOWN "\xee\x96\x81" // U+e581 +#define ICON_FA_TENTS "\xee\x96\x82" // U+e582 +#define ICON_FA_TERMINAL "\xef\x84\xa0" // U+f120 +#define ICON_FA_TEXT_HEIGHT "\xef\x80\xb4" // U+f034 +#define ICON_FA_TEXT_SLASH "\xef\xa1\xbd" // U+f87d +#define ICON_FA_TEXT_WIDTH "\xef\x80\xb5" // U+f035 +#define ICON_FA_THERMOMETER "\xef\x92\x91" // U+f491 +#define ICON_FA_THUMBS_DOWN "\xef\x85\xa5" // U+f165 +#define ICON_FA_THUMBS_UP "\xef\x85\xa4" // U+f164 +#define ICON_FA_THUMBTACK "\xef\x82\x8d" // U+f08d +#define ICON_FA_THUMBTACK_SLASH "\xee\x9a\x8f" // U+e68f +#define ICON_FA_TICKET "\xef\x85\x85" // U+f145 +#define ICON_FA_TICKET_SIMPLE "\xef\x8f\xbf" // U+f3ff +#define ICON_FA_TIMELINE "\xee\x8a\x9c" // U+e29c +#define ICON_FA_TOGGLE_OFF "\xef\x88\x84" // U+f204 +#define ICON_FA_TOGGLE_ON "\xef\x88\x85" // U+f205 +#define ICON_FA_TOILET "\xef\x9f\x98" // U+f7d8 +#define ICON_FA_TOILET_PAPER "\xef\x9c\x9e" // U+f71e +#define ICON_FA_TOILET_PAPER_SLASH "\xee\x81\xb2" // U+e072 +#define ICON_FA_TOILET_PORTABLE "\xee\x96\x83" // U+e583 +#define ICON_FA_TOILETS_PORTABLE "\xee\x96\x84" // U+e584 +#define ICON_FA_TOOLBOX "\xef\x95\x92" // U+f552 +#define ICON_FA_TOOTH "\xef\x97\x89" // U+f5c9 +#define ICON_FA_TORII_GATE "\xef\x9a\xa1" // U+f6a1 +#define ICON_FA_TORNADO "\xef\x9d\xaf" // U+f76f +#define ICON_FA_TOWER_BROADCAST "\xef\x94\x99" // U+f519 +#define ICON_FA_TOWER_CELL "\xee\x96\x85" // U+e585 +#define ICON_FA_TOWER_OBSERVATION "\xee\x96\x86" // U+e586 +#define ICON_FA_TRACTOR "\xef\x9c\xa2" // U+f722 +#define ICON_FA_TRADEMARK "\xef\x89\x9c" // U+f25c +#define ICON_FA_TRAFFIC_LIGHT "\xef\x98\xb7" // U+f637 +#define ICON_FA_TRAILER "\xee\x81\x81" // U+e041 +#define ICON_FA_TRAIN "\xef\x88\xb8" // U+f238 +#define ICON_FA_TRAIN_SUBWAY "\xef\x88\xb9" // U+f239 +#define ICON_FA_TRAIN_TRAM "\xee\x96\xb4" // U+e5b4 +#define ICON_FA_TRANSGENDER "\xef\x88\xa5" // U+f225 +#define ICON_FA_TRASH "\xef\x87\xb8" // U+f1f8 +#define ICON_FA_TRASH_ARROW_UP "\xef\xa0\xa9" // U+f829 +#define ICON_FA_TRASH_CAN "\xef\x8b\xad" // U+f2ed +#define ICON_FA_TRASH_CAN_ARROW_UP "\xef\xa0\xaa" // U+f82a +#define ICON_FA_TREE "\xef\x86\xbb" // U+f1bb +#define ICON_FA_TREE_CITY "\xee\x96\x87" // U+e587 +#define ICON_FA_TRIANGLE_EXCLAMATION "\xef\x81\xb1" // U+f071 +#define ICON_FA_TROPHY "\xef\x82\x91" // U+f091 +#define ICON_FA_TROWEL "\xee\x96\x89" // U+e589 +#define ICON_FA_TROWEL_BRICKS "\xee\x96\x8a" // U+e58a +#define ICON_FA_TRUCK "\xef\x83\x91" // U+f0d1 +#define ICON_FA_TRUCK_ARROW_RIGHT "\xee\x96\x8b" // U+e58b +#define ICON_FA_TRUCK_DROPLET "\xee\x96\x8c" // U+e58c +#define ICON_FA_TRUCK_FAST "\xef\x92\x8b" // U+f48b +#define ICON_FA_TRUCK_FIELD "\xee\x96\x8d" // U+e58d +#define ICON_FA_TRUCK_FIELD_UN "\xee\x96\x8e" // U+e58e +#define ICON_FA_TRUCK_FRONT "\xee\x8a\xb7" // U+e2b7 +#define ICON_FA_TRUCK_MEDICAL "\xef\x83\xb9" // U+f0f9 +#define ICON_FA_TRUCK_MONSTER "\xef\x98\xbb" // U+f63b +#define ICON_FA_TRUCK_MOVING "\xef\x93\x9f" // U+f4df +#define ICON_FA_TRUCK_PICKUP "\xef\x98\xbc" // U+f63c +#define ICON_FA_TRUCK_PLANE "\xee\x96\x8f" // U+e58f +#define ICON_FA_TRUCK_RAMP_BOX "\xef\x93\x9e" // U+f4de +#define ICON_FA_TTY "\xef\x87\xa4" // U+f1e4 +#define ICON_FA_TURKISH_LIRA_SIGN "\xee\x8a\xbb" // U+e2bb +#define ICON_FA_TURN_DOWN "\xef\x8e\xbe" // U+f3be +#define ICON_FA_TURN_UP "\xef\x8e\xbf" // U+f3bf +#define ICON_FA_TV "\xef\x89\xac" // U+f26c +#define ICON_FA_U "U" // U+0055 +#define ICON_FA_UMBRELLA "\xef\x83\xa9" // U+f0e9 +#define ICON_FA_UMBRELLA_BEACH "\xef\x97\x8a" // U+f5ca +#define ICON_FA_UNDERLINE "\xef\x83\x8d" // U+f0cd +#define ICON_FA_UNIVERSAL_ACCESS "\xef\x8a\x9a" // U+f29a +#define ICON_FA_UNLOCK "\xef\x82\x9c" // U+f09c +#define ICON_FA_UNLOCK_KEYHOLE "\xef\x84\xbe" // U+f13e +#define ICON_FA_UP_DOWN "\xef\x8c\xb8" // U+f338 +#define ICON_FA_UP_DOWN_LEFT_RIGHT "\xef\x82\xb2" // U+f0b2 +#define ICON_FA_UP_LONG "\xef\x8c\x8c" // U+f30c +#define ICON_FA_UP_RIGHT_AND_DOWN_LEFT_FROM_CENTER "\xef\x90\xa4" // U+f424 +#define ICON_FA_UP_RIGHT_FROM_SQUARE "\xef\x8d\x9d" // U+f35d +#define ICON_FA_UPLOAD "\xef\x82\x93" // U+f093 +#define ICON_FA_USER "\xef\x80\x87" // U+f007 +#define ICON_FA_USER_ASTRONAUT "\xef\x93\xbb" // U+f4fb +#define ICON_FA_USER_CHECK "\xef\x93\xbc" // U+f4fc +#define ICON_FA_USER_CLOCK "\xef\x93\xbd" // U+f4fd +#define ICON_FA_USER_DOCTOR "\xef\x83\xb0" // U+f0f0 +#define ICON_FA_USER_GEAR "\xef\x93\xbe" // U+f4fe +#define ICON_FA_USER_GRADUATE "\xef\x94\x81" // U+f501 +#define ICON_FA_USER_GROUP "\xef\x94\x80" // U+f500 +#define ICON_FA_USER_INJURED "\xef\x9c\xa8" // U+f728 +#define ICON_FA_USER_LARGE "\xef\x90\x86" // U+f406 +#define ICON_FA_USER_LARGE_SLASH "\xef\x93\xba" // U+f4fa +#define ICON_FA_USER_LOCK "\xef\x94\x82" // U+f502 +#define ICON_FA_USER_MINUS "\xef\x94\x83" // U+f503 +#define ICON_FA_USER_NINJA "\xef\x94\x84" // U+f504 +#define ICON_FA_USER_NURSE "\xef\xa0\xaf" // U+f82f +#define ICON_FA_USER_PEN "\xef\x93\xbf" // U+f4ff +#define ICON_FA_USER_PLUS "\xef\x88\xb4" // U+f234 +#define ICON_FA_USER_SECRET "\xef\x88\x9b" // U+f21b +#define ICON_FA_USER_SHIELD "\xef\x94\x85" // U+f505 +#define ICON_FA_USER_SLASH "\xef\x94\x86" // U+f506 +#define ICON_FA_USER_TAG "\xef\x94\x87" // U+f507 +#define ICON_FA_USER_TIE "\xef\x94\x88" // U+f508 +#define ICON_FA_USER_XMARK "\xef\x88\xb5" // U+f235 +#define ICON_FA_USERS "\xef\x83\x80" // U+f0c0 +#define ICON_FA_USERS_BETWEEN_LINES "\xee\x96\x91" // U+e591 +#define ICON_FA_USERS_GEAR "\xef\x94\x89" // U+f509 +#define ICON_FA_USERS_LINE "\xee\x96\x92" // U+e592 +#define ICON_FA_USERS_RAYS "\xee\x96\x93" // U+e593 +#define ICON_FA_USERS_RECTANGLE "\xee\x96\x94" // U+e594 +#define ICON_FA_USERS_SLASH "\xee\x81\xb3" // U+e073 +#define ICON_FA_USERS_VIEWFINDER "\xee\x96\x95" // U+e595 +#define ICON_FA_UTENSILS "\xef\x8b\xa7" // U+f2e7 +#define ICON_FA_V "V" // U+0056 +#define ICON_FA_VAN_SHUTTLE "\xef\x96\xb6" // U+f5b6 +#define ICON_FA_VAULT "\xee\x8b\x85" // U+e2c5 +#define ICON_FA_VECTOR_SQUARE "\xef\x97\x8b" // U+f5cb +#define ICON_FA_VENUS "\xef\x88\xa1" // U+f221 +#define ICON_FA_VENUS_DOUBLE "\xef\x88\xa6" // U+f226 +#define ICON_FA_VENUS_MARS "\xef\x88\xa8" // U+f228 +#define ICON_FA_VEST "\xee\x82\x85" // U+e085 +#define ICON_FA_VEST_PATCHES "\xee\x82\x86" // U+e086 +#define ICON_FA_VIAL "\xef\x92\x92" // U+f492 +#define ICON_FA_VIAL_CIRCLE_CHECK "\xee\x96\x96" // U+e596 +#define ICON_FA_VIAL_VIRUS "\xee\x96\x97" // U+e597 +#define ICON_FA_VIALS "\xef\x92\x93" // U+f493 +#define ICON_FA_VIDEO "\xef\x80\xbd" // U+f03d +#define ICON_FA_VIDEO_SLASH "\xef\x93\xa2" // U+f4e2 +#define ICON_FA_VIHARA "\xef\x9a\xa7" // U+f6a7 +#define ICON_FA_VIRUS "\xee\x81\xb4" // U+e074 +#define ICON_FA_VIRUS_COVID "\xee\x92\xa8" // U+e4a8 +#define ICON_FA_VIRUS_COVID_SLASH "\xee\x92\xa9" // U+e4a9 +#define ICON_FA_VIRUS_SLASH "\xee\x81\xb5" // U+e075 +#define ICON_FA_VIRUSES "\xee\x81\xb6" // U+e076 +#define ICON_FA_VOICEMAIL "\xef\xa2\x97" // U+f897 +#define ICON_FA_VOLCANO "\xef\x9d\xb0" // U+f770 +#define ICON_FA_VOLLEYBALL "\xef\x91\x9f" // U+f45f +#define ICON_FA_VOLUME_HIGH "\xef\x80\xa8" // U+f028 +#define ICON_FA_VOLUME_LOW "\xef\x80\xa7" // U+f027 +#define ICON_FA_VOLUME_OFF "\xef\x80\xa6" // U+f026 +#define ICON_FA_VOLUME_XMARK "\xef\x9a\xa9" // U+f6a9 +#define ICON_FA_VR_CARDBOARD "\xef\x9c\xa9" // U+f729 +#define ICON_FA_W "W" // U+0057 +#define ICON_FA_WALKIE_TALKIE "\xef\xa3\xaf" // U+f8ef +#define ICON_FA_WALLET "\xef\x95\x95" // U+f555 +#define ICON_FA_WAND_MAGIC "\xef\x83\x90" // U+f0d0 +#define ICON_FA_WAND_MAGIC_SPARKLES "\xee\x8b\x8a" // U+e2ca +#define ICON_FA_WAND_SPARKLES "\xef\x9c\xab" // U+f72b +#define ICON_FA_WAREHOUSE "\xef\x92\x94" // U+f494 +#define ICON_FA_WATER "\xef\x9d\xb3" // U+f773 +#define ICON_FA_WATER_LADDER "\xef\x97\x85" // U+f5c5 +#define ICON_FA_WAVE_SQUARE "\xef\xa0\xbe" // U+f83e +#define ICON_FA_WEB_AWESOME "\xee\x9a\x82" // U+e682 +#define ICON_FA_WEIGHT_HANGING "\xef\x97\x8d" // U+f5cd +#define ICON_FA_WEIGHT_SCALE "\xef\x92\x96" // U+f496 +#define ICON_FA_WHEAT_AWN "\xee\x8b\x8d" // U+e2cd +#define ICON_FA_WHEAT_AWN_CIRCLE_EXCLAMATION "\xee\x96\x98" // U+e598 +#define ICON_FA_WHEELCHAIR "\xef\x86\x93" // U+f193 +#define ICON_FA_WHEELCHAIR_MOVE "\xee\x8b\x8e" // U+e2ce +#define ICON_FA_WHISKEY_GLASS "\xef\x9e\xa0" // U+f7a0 +#define ICON_FA_WIFI "\xef\x87\xab" // U+f1eb +#define ICON_FA_WIND "\xef\x9c\xae" // U+f72e +#define ICON_FA_WINDOW_MAXIMIZE "\xef\x8b\x90" // U+f2d0 +#define ICON_FA_WINDOW_MINIMIZE "\xef\x8b\x91" // U+f2d1 +#define ICON_FA_WINDOW_RESTORE "\xef\x8b\x92" // U+f2d2 +#define ICON_FA_WINE_BOTTLE "\xef\x9c\xaf" // U+f72f +#define ICON_FA_WINE_GLASS "\xef\x93\xa3" // U+f4e3 +#define ICON_FA_WINE_GLASS_EMPTY "\xef\x97\x8e" // U+f5ce +#define ICON_FA_WON_SIGN "\xef\x85\x99" // U+f159 +#define ICON_FA_WORM "\xee\x96\x99" // U+e599 +#define ICON_FA_WRENCH "\xef\x82\xad" // U+f0ad +#define ICON_FA_X "X" // U+0058 +#define ICON_FA_X_RAY "\xef\x92\x97" // U+f497 +#define ICON_FA_XMARK "\xef\x80\x8d" // U+f00d +#define ICON_FA_XMARKS_LINES "\xee\x96\x9a" // U+e59a +#define ICON_FA_Y "Y" // U+0059 +#define ICON_FA_YEN_SIGN "\xef\x85\x97" // U+f157 +#define ICON_FA_YIN_YANG "\xef\x9a\xad" // U+f6ad +#define ICON_FA_Z "Z" // U+005a diff --git a/Extern/imgui/License-FA.txt b/Extern/imgui/License-FA.txt new file mode 100644 index 000000000..aa78d8533 --- /dev/null +++ b/Extern/imgui/License-FA.txt @@ -0,0 +1,165 @@ +Fonticons, Inc. (https://fontawesome.com) + +-------------------------------------------------------------------------------- + +Font Awesome Free License + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license/free. + +-------------------------------------------------------------------------------- + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) + +The Font Awesome Free download is licensed under a Creative Commons +Attribution 4.0 International License and applies to all icons packaged +as SVG and JS file types. + +-------------------------------------------------------------------------------- + +# Fonts: SIL OFL 1.1 License + +In the Font Awesome Free download, the SIL OFL license applies to all icons +packaged as web and desktop font files. + +Copyright (c) 2023 Fonticons, Inc. (https://fontawesome.com) +with Reserved Font Name: "Font Awesome". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +SIL OPEN FONT LICENSE +Version 1.1 - 26 February 2007 + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting in part or in whole any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +-------------------------------------------------------------------------------- + +# Code: MIT License (https://opensource.org/licenses/MIT) + +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +Copyright 2023 Fonticons, Inc. + +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. + +-------------------------------------------------------------------------------- + +# Attribution + +Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +-------------------------------------------------------------------------------- + +# Brand Icons + +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/Extern/imgui/fa-solid-900.ttf b/Extern/imgui/fa-solid-900.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a0414182dca34041fdd585c0c4b4bd7a3a2753e2 GIT binary patch literal 426112 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

%HINjzu*e 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�Nl|_$ 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

E7E^ziYWPY-|AaZEuP^7qG)} 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ⅅIax?h{^SOTl9itAdhIJqp0ae;3t3bUFpdyF44JjU;7}%~| zFF-Fkd_-UTFJTMpdKm!Ht1*fNu0q`4H1BXF&7z)t2G?Bm4Uajcb zVQ>{#H;1bVPc@Mk8F`1JtO4g=)PVZd!g?IgpE19LpAP+U=ws-APFStEyVemWy!MzG z-;x`kG%@O{nz3feYUg)G1wAutga0M=kZ1o8Y+l_V-lCg z3dSrUtILfXVHos3?0eu{8x5h4LNVpEr%|u2W)z;rDTUTXAh~WC1y>y5cWmV{tMvIF z_iS$T`x~3xfTVWyxqp!r_?%t?Ee)PUsW{)0BX6J>=i}pWE4-TD1nU9N9w#R|LwB>D ztk*l&3R*uDn5>oJ)Zrb=nmhD`U(9;^v?E+6e>G`rBgkb^!3~6Ysf3H#d8CpHSPSXh z)6n6p8~1=hCjY!%E+LV3tW>U#j`Zj0?WRh8UOT2dNxta)`uP1keo`NQJ_$0Mj7MJH z%4D;d*2`g20Mnew#K;@Q@FL^K4fNZvdEmY>*2Z^$N6vs-31JQuwLc2*2+0re3HG82 z3-;7J&wy+Ndtw-pG1=?;*YaQ?fHi=FR?ZjI&tP48$_6i-hHVBb)SPrG7PqL&&M;>= z;zdx0ZN+1$w1bsuiDWVz^(;G;AwQb}F7ILtX#JuCKEyM0+get-C`+$Xzte1%!-W`K z&m-yJ88{RZFoAfn74Q^otsXoZNPG!`UJiHZ`+(FrG~n=f2Z)#u3c&jcm!QZQ+hH5R zgt8q?4iNvAPsUw%AGzy*9DN-MOe|5fC&FOqplFP!@C1;lnK!~SwmlOzT^4#xX}>8*DlPuFBMVVmGeg-R z0P6}Blo$*Ghn=UXQwATXsv|5ChYJHEYCI0f0scC{P+^#98kJ#``ACTYcVZBM%VZCt zun0$YdMO@&Od{TjxI0f2@ELf0}X;7JT+aBJ@NSewtRXBme$c1qD+qv%9OyJ8{s9(ux zy7dZ@4opnh3a*jJaV5HU+6+Gl-tBi`Gn|6%_I}6(PXHodb088$^zfpEVbv^tei0c7 z5TjU=^6BifH7!Xnpb^l%$NKUNBub2fjOz++DXh^>M;yT-3qvJ112;KAIp?sR&z&QG zDSuyqG!)9K!B>$MJCZzXIq-s5Rc z^;xSIH|<1ko5h_(awdVZjuq~xGdIiM8%=ZFDW>x0l{%kK6`l3L*YCdj?tN)UerEic zqPuPw>u&KGoFuLEzPm9dJj%(Y&PqAiL|8zg$uovj^!YKRKBMkceMBgt&nw|F(5?h~ zIB|nNCP$ld;4n}mG9|Z6T^MKENXteVMc+(xlOR=1ryQOQTSa=u<=is)VYDPaB3Av& zVU~=Nv~f8JWN*wi(o=ed69ISd1hKft%q81`Ig4_dj|3EO#~S&0_&n$z7oI>*M=xvt zhxd`+(%KT(M4>F8YJs?);9RHSYO`<=$umDJVz*MrLpdGZl`Kh@ELJgWWv#TMA8*4zj<0Nx=ELeg` zAe&2yh7Zh(8#&utK)`HBJGt;|kbOrbXRR#D%$i}hZ)q)Uw- zP`wj{-iZrp8uP9BE8hqeEU!!d%H zr?RD5vDNByXQ4@StwaQ+qV&pT>-E{$R;yBmo)SeW7IUmU1q8jLV41B=cv;P6WxZMr zEEq~vqp-(vVxD{jJ|a;rw_CHb^*UnAQBMYm1bH(Nd$rSQ6>FvJ)OFr#_R$R1yCS>Z z#3R80<-#EL$7hh)V%?tw^hOsPt#t*!8!LosMv>DZixxL1Sd7jI)H`olT3lLLc{Y{$ zm2fv_Ii*3b~X7V06V6w$Zzhz=y?%Fqxo zp!>tSK`@MWqdJx(HJ*O@X@mxgJ}q<)7iE#gmPq-1oNl6A6cZabV4Kj41XhR!isIiz zc>1n5uH4N9$bjvKeh??Pgp6EccB^8DIonDBS?;-n2$(Wc+ z3xN1otinepXyN(aq%e=w`DVt%SYSlVOn>L;Z4d)?lziuov&=Vr{a^lE5B!#Xpbvp4 zBfGV=p)YQ3>itGwPVVEphdYA())nVik>Tt?@F#tna_l`MPjx_?fKCk7+de&wGUV0VWH$WCQ%wKG?9gRrsd^ak;)zdXc{Tn zF1l8w*_>nKzy$<09Q@3LQVWnAthr{hV!0PYC!@bOSfL>*8bm)Xmk|;9%LuGgP9`=J z$#Uv6G`4laj>LMROxdzQn5txAC)f5))c34SlB2DbD=m8vf)5I*>Y1^Q$5V9K;d(Zo z&(;sCe@0yUTx|kNR2vhuTa5^rL?~u6OBbxR`YB^o}a^l3!F6+{;#w51RFe(Z# z0l7E!_%e7ZZS7=T{tm3P(5&WU^jn~Ao@1TED0cB4xgBppPpDPCIq=A6r2V!aQAt=Z zk(Bs7_^~atAr={6E`E(~Tf$ob9x&9SKwGrQ7S`08;P{4N)7uAO_fj^v2Vp9ZBN++W zYWu5k%@z^nVOxQW>!vErO59asP<|nn4%B5WNJr4GdBfliZ~{#vZ8io02JW9ANs7FQ zX{FMQ#tPkJ(#1}#>Ln}yl`TF=^1z#5UjfDX74pzTc5y`g)og>H{p}GSua77>tj>k|n<%te8 z1_S2|D>5ZTP78vP21G4~Za*-)iV!JJo!$#NR#MXsJn+Ek>|9wb>^=R|;JmuV3Ow`i z#~;77?LF{@H@xB3;>!naS(#sgFY)7Edue{xdPM&KA87a zVa_`jjh^#<4{9MGt@YO!Yl65+uUS`jzW(*EFD0s9?FV4e|7tZ+dVSnG=iy)c&y&@c zvhF_|{4j5QX*GH9AAH_q8+t&llj>qU>-D`*1NN0Rq7fg08IFPAFpRVJ#oa6Sg4Y|l zRt~m$8vE-l`NZM5&uZ!O-JMR!i3WTa>iKPL>07ooaJ8Y2xg(!Ie(Z{G_WkPgBAp%n zx6sQ#Lj%gm?-dh_&|?4V*b!rwu2C8NOZ)5A&QJfQ-g^{gV!RpuTlME%yWjB52IX1x zKK1*M)@~wa1XY_Lc_3Yf&c&j?!)yYICSU?Q8T*+aifhcVL4B{5hgb_*S^(x`qcN%U z_R(Uo7(uev`>=>45>2Jz2P@@yg!hVd5lOGIdat$&U9Lr({C6*?jqw21pNEbdi#?)e zcpGnDm})|Mk$YKvvYzi~^OdSpGxtD{q;33ngqJ>y7_5ktA*Kb8K7bzIlOzR$!s&%C z(E^qROyBILui&fO_+o9&=;JTWqP1nXDiA z&0P7GXt?SY`dC{NUWm1t3vbkeyH1pOchvjIFw^_WKP&u`k;vUF_ZRNIaiQ6YErcUp zs$X!c;pi>p+<%l8z@l}LL41AxGGcze5q(!6_v^beG>0WO9fAx3T1lIzPWU2!EbIz8RUnJqscXUOXjW{wp2rROfpU0TIqjZ(TV}&$__F?&D(F{Z{?wo;|(tRyOK+ z-#c>JW77}QN}Kpsc*O<$tnRNx#0Gud9;34cL4-X9fZ-$^k(PkwfCyZpCpG}lP*ftc zB$7BrquEl);Ia)3OxRxYTN}KIH_vot3y9b`+nE{Oga!hdp~t?87(F*(jZ3J=gf~D5 zKoQjc*qj*h>hOg#q01!3m;rU*7v;IIct;IEDQ$8(1e?I2d-+32wbYAms&a2yWS&MP zzaNrxG?wg>dT)(g_^u_jCBA_A%0#VstOGZbix(T&Zhb$6rff>RCslw!3IspZfIs}` z%DtUqmyxg_rR5%678((H?k|iUc!52V5q(w2`j}p8(d5SfgN~6r!MfR^PWLCadO@Ky z?T*h5^o@^UXh$F=RaJzKDSTdc^ygm-NjUoIefn(QRQCAYZy;FC&1vAApVzQIey+X~ z0VnnN4t_ElR_ROnL`_~$EoeS>yJys<|Giu4In3wT&`ZH}%J=e{DZmhW4VSAg@tb^n zHq)67J~o)w_&994;E%gbFo7MHgm3SX@7DaN32ZZI zST_R$g_mJTvcmSUaQGNjP^y@@45`w-*)k@#boGoy_W|G07RLRIe#WDg)kDxg1u107 zv`#a9c+)VNhz)C>w#+3uA>(2%1ZyAc{KzS^g;j%D#CN|FmcLiPYvtQ9Q-SBPuBZd1 zn+uNU0=TwJHbKyxtU+>S#sDE0RH`cYz3iC)a2zyJLe{QRq`_*?yHtTf^&*DgISCGTkA zZRwnnxR#!4n`mOQMyE#>#tNJj|9~&&V+4X*jV%ifQM5-%i#zNm`;y$!v1AR zOAjP~iU20KNZ#?l% zdybQ8M3FKp9Brh=k7)&Ys5JeZf8E!!t^e2GIbC{a5LVH_KdNZMvTjafo)lJ93Q&l~ zpUfm~wyehEu3IxAwOYiejgHVgh~yZoUCD>)SON5EM1g(+KF3doei-Ws-UDoj&jzLw z<(n|rqJ1ELAz|DQ$C-xE(G^+v)`p{?2CXaIQ3L!!-Mhvu#7eLNLS$?&0;ssmmAB$@ zQG?o=20XGb0BuJD9%}+9`y(BYuM67LE}d#)=zblb%E5P=wF#t8I5cU;qR!-@6w;3b z=P{e-Zx$dtUa!|r*4kW_1{4RpC6kF0=*@C>bOlCz;z!8T?&0N6kj!wXD9yih!O#QpxQLe>2l#la0Ltqel5Ai zGHvz=*b>bIT>DHj!mOp^H&PwU&Rx~?0kBG>A%qqDfOt+V6O%GKFa~FN#R3O`9k2^k zZEYsLC{z0a{fkjvzOe`f7?G_YMuZ)#v#=*S$cF>ePc;;se+;wJSYQC!TUG}Wr^QGD_nuDnC+lN{+a4TJ7#4HhCi}_&*X4#6f#zZGO~>Gd`V1{_z)gI_UjRzDA(9P9SM#EE;hkS25^BtUkt5G4qxq(iG1 zO5sg}lL1ttvjxXMl2qs+mB}WbIvI%SC!b1Y-@JxDhHzY4V*tnTWAz>{H`svQG5(mK zVBYpv+Q#)*cR~DHB@Rl12+4UR5y=) zcX z7bY9D0U3z10Vu%amUHwo9*Fa8Fb#0RE~q9#MuhG6QnLPu%#+-`Ir9j24`!YVrF6`{ zAu-qvj&{Vz`cDXD?xvghd^6)9ocZ2#d@&7VzZg&N?W?_mKT&)0&(mDKlyUXHj& z!FuX%&b!Z7iV@=2#T*9`gVnVTksqP6NKTK3&WscAE(OdcaxbDI0_QS=UhcdwXFROo z^d&eoi2%AuY%j3i`M;}oN%aKWTjICg8i%{eBae(9zYzC2)eR6nfBK+C5Eli-RFIF2-yTW0({S6V%+D=vCewRs@W)gjHSsEh zohm&2piDz(-C!uY!BDCY;^BwG4IlNq>-9b^0|xtxDy$=Dm+ix+w=#2g2M<8ur0o=I z{T$tf)6=#+jTM{`WPGa>>hYHZ?GAy4G>G|);OR#>5_$n@|H(x0v$e*5Ouk1smO@GS zvH%U$tK+=WPELx7G%#G9<~O=C@W_T1N&**jjhSxu^H^hq2&x(Xi$Z#jQzsS44mQ=r z%a<>IwzzL&LqZ+k){TvQ#m`=TR;3$oL=P~ttbfO?{bVxLNOLKP&m%H_^Asc<-&cWf zje(QZxj@ZegfNuy6E?=Qg@4y5SOYw_5c`>7+K5LO!0Wh;C;BBo+uxAuCO`*_t~xHwPnBB}~2@?J)8S8R;AD~Mo_S|VSlgD1qAXZmG)3e@Lr#w)-@La!!0 zw9s=pXp*bHoP8i10|te|G81qP*ppdX#r>o$4iCj7h1;zc*fle*k+|DMdYzfDDF$Vs zvHXHqw2GW=Ww2s?jin_lH+Jt%7+}tBzS(hiWSWFT|GfS8$>8p_v~*2C(al7;)JUUo z@2+9v;}8AgalQTa^Y*at-2f=8j)TVed%2=x4YNbTyOt94JkiQ|jidB2XNfj9XbFQ( zgW9nI=jd+E3l0yptTGgk+&MgC1xTwj3~J;AR1CwKrc~3^+HoBjB}kI44#_Kd(qx+0 zgO*&4EK&O*N)R7frUq25y@2yyo_j93- z0ylvLE=cc*KnFh3!FT|;{T`h`4^9Vl#2FvLUJ<+~s2ux?Tobx~h1wh4&r6h2R%Y4& zc}+Z8;{UR=OcC5iUzka}7vY{zNEHCjWWG=s2a5C6q|$l^fCoxteYv3G(lKWMpF9`dF)y~&1;%S#hp6|WfC zeCIpg8M7Of=UNYf*lb4dQt)8v zPq@xw_&%fj*kg}jipPwcfiH_b^UO0?bpr2V@0m#Ccd=&WqU&BniI#Cc0o3@r(B{qQ z3S#n8zI2!F+o@YHA4nNF&f3x35!I#)|_am;cU!FAIK##2O;!=95kk_3y=6XU~2E)DgSUG5jK(CB!QR!VW(8TbYaL` zs3sEeA>MfbF&qjd5~a!BE4H_{^;G_@Z1%hK(O+d2B?$|gNg++^rGR4XA0L;)PlX{ZW1?LzZK>=wY+EJPiUQI%jZkD{!eN zyT;$5gNEr@wz{U>3(zWYsVE^a?`6o>V9tf&2yh&k+sgnA7rOiFhr~6iP|3y{s`*G6 zxwj@K_qPUJ@Lm9NivccvJfW<;`(TsVzkk0`NZW%a3MW$V7~ek$E3%b9{0s{XPZ{9q7xtf6IJDv-;VLj8 zvT01iMasLkwzP-YJdTuLVs@c|MW<2ks0M%^Shd##r?&yYLJEM^{2z${%$IOf0M?;5 z9Xkvi$8xYJJjPGR$EH_>BT(FS%LwWNU2PfO`PlLd-dwzR9$8DEQi;#*1s0rqwIz#n4kFGbde`ILZx}Bg2zclE^kvo0zCYfIaFS<~*H*J0L8VPS-KDiI!h49i(@rV8tMaQflIsipPxby8N@C|li|2p{okU!LKdi>uq(KA}ji{uimVc;44w?c$!&nG3E@dHV);58a zH!f3n*An~&|2|3uI#Lf&Xm?UvmcR|p;4{Jt*nL0PLiSEOrrha@ipR5ic)DkJ`bu=1 z2y=CyDx?ptqbE1`oDCrHi+r?f5SejfV;c=3C5}px>u}b&(Wm-Z>%qIk+;BQJk%e`R zZ#H(;XirYIWtbW(dy$aZ-MfM_&V5;L0yMf6N`)G*FrAYa3V{oi@43CKQ-Auyfx_jH zwoea%$o0itOC6Y+$zWsFiz)!)fl(Z%r89yWI1C&kj=8=%LI+#ulO9I`|9QBj_j=pk zagxa7Qp^vMfyR_6@W=vJ@`%pCF1=58*g^K?K?y3zmM&aioA{68AX{!yE9zgW5o!us1 zuRl7ASq_)o#MKyy#2L$=Ft4Y zR3zo5)1^e>KH0kI!CU_JZ~xYEX1vI!i&G8yNmst;G-pbU*j@`!nDQ|-Ge5nUaubPC zI(?sP-SiKB>QkR`aF6}93X>-_rXbOTFe3unVg~-9tMIVAAJ)aULYn-!(656s{&DEP zhW+UC zw$$%nU4N1!89UcByE{);Mpt-Y<$v4NgDTlirTWB_FKnOEAHa|H(V{Fl=#66qS;Z7w zMg2>|wKH3oU-!_vZB6W>WS2F0$J__Z&=FLtx@LeLfFL@=mBb6g5V)Gv;(bsXNChw^ zcZfEjV>X-3fU=B&oc3P(+Se8re=H1~sg9WD%l*^o`xj=Z&v@?Q1KO512+;g~R_2QnP!xJ>Hf+ZmW!K=f>KSR&#?djCU3APdH>f z_X*IB&w)d~750=zg?m~Bh5+sWmLVyjpf*N=*)^I+M=c7m0du28vMy#kQR#~CTA~DD zHTEMLoLS3~IuQYjJcxOzmjF3ixW^(Bzi|Mre|yu-HVU&VIWzPkTi?|N6(a1GaszNDH;d0q@X_s@uBwV~b{ zdNTAbc!Ina8921(%#wT(=?(301uCJyaS$7lYt(%+Iz~sxkKCkY7z?<6C;vjGac2oS zRCl0AdR!e3*ek+-h0%dhODhF%t`G5mD@xQ)!Zcx;4a88P{TB-yQh9K7FiwGO>&X^A zk_MJ1fzd$LUGx{JZx3BpZ?(ww@Guk2XPtse)wXk}fv7rg#Y!Y@35MxDJz7TLK4BNp zQkS!x|J9E`G47;jNsecWDF?}r%X39Mo9Ujo&6tpjOVd1TVWCMBPvaBu;B&FqIeql# zT-J%^7c;p#4j#lx7^vUF>GW>}4;>~2zQ9JL<={0)do}OS1Ml!E(A>~8m`HI>qR=b~ zKT-|YH$>ppTP+;$D*1V`6(WyniPC2(Ky_Ad#kYI}nqa0fMiHZ9l}atBf&kh1Xf_QWvb{?Oz^-6L&9MmDnh2XELw&#Q%lFs!8NW8( zKcasyjzi~moA|fVi3$EkoXFS*uF*5n1%O6$hnBAN%%|!GY8xyjU?c>QhJ^2yb>WWD zgG)J7FXWitH1pzU?0dlOI!Eq~*psiOgu?GbfDCY!-s}9&U5TkJ_(ZBrUhmx$kG;%+ zz3|SPz1RVfqS#;}vh6A7foc6kkME1dG0yysZQ!^~jomP}I3IKPhQNGIBRs!pbgpBz zbMQvm2-JZlj&t<@Wr!hr!5ZV|dKC{_W2@8+7uMFEC^z@yp&5#PRlnPtmrdiOKFozx zqtV^7w#N=kp!OA&-?VhS%IaJWw$*&bcNj&~AM_ZSPNondSGBCb25Y^*YMdM9bI)Od z9EWXV7E;9tbfRV>0R#LV^x>-Xj7$Q6zpr&d-#EbNsG_kwqW96BhCaiTQjKpvcC1o? zQfTQ#ZYNtrvM#5X?YJ*mLX^`=<=C-r-x^w{~>#H8MN$U>IVJ^b*)-&=~uTZB993q!fg z1xNoBrC!>r$)&CU8*@61IM*?6GN68{7DiV!?@GWUFH0-x^{$UVu{p;1%H3RRP0G?{ zYIk`L6@so|Lp!a(KHm)@srS2qo5p5v&{d&b3i}#{pBuY&abrXE*enza+M%t_HhkGl zoIs?24gvbgZe<#VM^^@DOa7!^Nq09x2SR@u`iszCgQKHeM>u{88tkWG|M@%`$f9Um zw9Z{zEFBqfO<4h_gkn%>3IKAVH5aB_&xK;ADK>LMsB2_8ZVe6LPGE%01@_+e;`y=W$;y<&+8;b@bIcyTPY zF$yW<9*DUvRMPP*;yV#7`XqDHs3$V)a7_vG`8K?>!-?F<`FU9QCYG0usm-HH%k>Fn zwMGz_M5Ws5k?dk=CrEJtsg6l`5ghPf5!k9+inwk*d#i3ug5~SOe+CT-$Ksj1yc(Vl zv=j?FVdSg{lMczj5-QnXf>}oob2l}e@iY`B8z~`cubQq+#7ql-6HYEKpH|0~mM7|1 zxnEyiItp{bL>?(x3kEzOz?)DzuMkKIDoP?gtaqu*WHJ*f^2UIk;j8o^aU1@F_yf1) zLKC4I06n(!FQfT#>e~79Yt?9E z>*fQ?XU;4ixEV`+K!49X^w61>4t6y>em0hYwrDyN!>aRS6oWJ{*DvAI{iIA0sKRr{T^~IJ6F7|B6l{)aRK0|_vB}Q)bME}+5)sd;3ERY za`_KV2X~1448lim_7O#76RhTdIULI=@~LD2aSt${*?SRw$d1Qj(eMQP@Dqn7tyr;C z&uhTR=RLc0sGH7oTgWWIr3%IN4L97NFP^Sr&2crF-N~zOq#h{ba`Bb(Y?4hsL}_*E zj+n6D9A}kHu4a>#Y8LfMilQ$Kt7^qg*XDx0+BSN?6L zpjkW4Sbe#PRd`%Ap-~EXc4Tx70nAd8bBlQGf@FRdcu%FvKTiRC@T}^~3i#wdBCZ_@ zE~yKMS&Ua+A7aydbs#!lPExCkQkU04dmH4jab(q zC95`pL9_}(t3m*cA_ovccS$D+oiwc6!_nl>5A9`u4BSLAE#yy*Y(NAc0T4sNtp^^V zZ7*m!fH)r$&zPON@y5AX!(Zp3$MT|{f_gjnLkIZkH+};f2WF1g5Bxw32GZTi6p&3V zUC?b5(zR+U@a*Z1H%PW{c>aBC?EHB)%m>_b6C2*G41l1X`=5xt`IP!STA~oIOp$f( zD9B1yGHa}-V#(~kTuQ~%M^dptH<`uJb7tHSGtO3|iQ$l49$2{ZIcK%)^h z8du*}xl!)J)V<=qZakKA5pV!vhHW`msno^&>b(We&feXs9IC4Dp`7Iv4pt($T%>Za z;90ptVO2d;Y2BT*y~15qxG~Gsjg{&wVgcUuP2AT_VA(AUO<`Au3U=X04JoRW=%O7A zSI7y)pbze2zD&Z-cnXrsy`erL)A;-=*;4*AACK|CPv%V%@hIr+$P$hfYvF?LXWPLk zu|{z^5Tl2o8;XI14HTg%hWdC5SV1M>d!R2BYk6qalC#>&b$aaP_4+?Ip=2GL7Ei@6`R7Z5}- z5V7rX5*gBVHS(_1Z2X7NuY`V=@GrPf_#{9raimzCh2a;t1{7*8ikQ-o)f8CMa9CArL z)|zfv0amnf#TKkP3zcNmGxqt<#7peuf$lRdqM26%9B$8iwq#wkq{mrZ!HQf6mztp zDkb+F2-TXeAaf)Fu#T!qNZ}O1^x-6<5`h!%+1I@0HL=o7Gv$f7$wu;ymq>zmI6P2y z@v3C}$B!Ov!u8@L`z&=w98pDZs7}8iJI360R6y+AdRmPm|Fz^qAE^yh`dH`08Vod3TEJAoopjHIhkx^ zXC4pA290rfb!YehNWB199YtTYdNrkLy_P6Vl(c#2dUCIpKONA#J+QgH0jt&gb$ytb zntpJI)X*R;bJ-V?me!_CYHskUkWNGmF0(e6gXoB5I@4Y6Izsw9UlZzb8fLQiJz?N6 z#~S=MM4ySwN1_)HRG^LMMA?RIB$sV_IZ5?3+{x%iW)FT5jNnzJw(%GO4p(iv>acQf zq<%Y|aIrQm?Bo%ZB?eETcp ziLKB)d~LBJK?P7B$de=CUT3}wriY#P!wwU+h`8W@GE_q85NJM%#N?r~LQsnX=i9l4 zLhGnZL~Wl{lIXj@V56MIyg-XdBcMQo4NZf@Ex<>1+wlDhuKSn$9dBoQn|eRolDzQ_ zTpRG(*!i#yu5DbS9Cb*)wN93Oxe8l0;1xdh1R^b$+Z};KpIOy(#HR_QL71MP8=w(P z&&ab?3O0oHqI!lR0zNwui$%P}xaD|m>F2VQa_+ut_I>5a$;n)D5tMrH?4oF;y9{EwKW$ zPqK>V7m=)P{6yBhEI^5uGtKPeWY#o6SDl3bYT&>`lsi*QR4Pqz3KQ>kUkk*LR7j5t zC4dnGMx;*>N*6DCW2`r81OCc{l>X)8jkD5gy7E8O=%#al$I>+%_Z1lA}!xzM4%m zB8a%vh-UiFcL-LaUf&-tmm8wsaJe{0l}j_FTrP%1@dj2V!@<7}W0~u5tP+qejHq zE|nb)ogOIU&Zw@V@*-`@yWY~586iCgm}^!liQ)`D4IeI7(20XBhq1=mc0#Yvw%eOm zoWBLWUOS5fkx~&CiE?(OQ|KH{I5;l*nD{_Ad_0OU-jqhbD4Fr-@vBRy)4r+{K3lMD zeoScE95C@s$l3V7H`RLu0wa_Mz`@1k@e>-9g9`byOnjbR%F%uz5T8YDe|J!7pOE(jQ(<&A} z!JB92lArNaIX@h;ooJz0&(_E<5B@HZ?WQ9yVDsJ2zko-}xNie~I2n2!qB?&(^p_&z z>S;_4mlkzm1MnY#%R0^gzT_)9Ol9ly7el)s<<^;wHuLP1Z|UGZF7LuANk}+38ZdK! z2ZWsxt_4p6N!IpNgr$OfMN8uI)`GNMBv0@Hs`iio1knul?PGR%i|fs7gwgv-<5(vL z_hYy_#JsE<9c<2e$@xT@ZbB+{PS&GrK)3{PCKI^n@B0jWYeY&|(Qc#}2o(uRXom-W zGfR=zUHg(@e$VypRGX=&W$fK+Sg~XdD&RAoTB`8X_=@GIeeVNFw+01BvXD(aU?VOY zV(s-bt2x@g3tR~z1(+#hz%=lka7{N0DHMdkwOsqkwXcDe3*3mz`~#4wehOI!e+h6C z__K0W7sTj?=k_&?g%i(2^s z1$LkZ0g2LjsbL8R@6-)z?U|V=FO7u{3nz}JCYzOV>fG%u9v{8w*y)2SSD&d|>y}eD z^uR<@`Ht;SB_&=PR4BnyP3x70B@&K3l}=PLnXv1*nWgr<=V-uW^W<&<`|N!83=dt)Kv7MO(?IAw_=zYj6%h z3JxM6tzu+|qxJl5fwptrLX;Opx#q34grzxWPDnk%LI1P2Lq>P;ToN4Yt&5As__1mL z!xqcsVu7}};Ha-ZLT{hF{m{Xu|o&f*AE^{Frh~r$K6Un-&UxMj(omZ_dVn! zuFHj9n!F7tbC8XiAEXs&UO7kTUF=hL$U`>VpC`y$yR&;`(H@zSVj_x(l5fGL16A=%>n8{^Ch%ZdR zipdy;eYRVV>pnX zMMWn98UeE45U_=ZAGZWw;f;mEAkQc2Q>a-X0j?1b1wKT2Ulh2kxed% zJAJ@{q&qys7hnZPJl@25UewJb?NX^ZSuDEs+y)i^0394Q>R4L>eR8u@vXiKifr4bZ zQnCNivEPO~((1L$5VL_CD?AcB9QbU!95#h9e5uroSRd(Dh4 z1l6ys?D&f*pTAiSi0bLEb9#`~p7~qOoIii&mU%46)0&7@>+qp7(!Kf|DrTye{j2Dr zP5)4QDYUPGE-@AsPM%y?FjQZMu=8hnUpKEG6_n|h*kYFlMS&SKIOjX`z=Zkm=X*uS zQ-d--jZY;!l2_6Fo(>(xTFf5|eNlK^s`9nUo?Pt8v}PO86<6}1;9UgCV$UfL0p|r( z1uhm<-Sakx)Va+u*BX(bgLrbB2pW0qWSw_mr9=GSZGQQ`Y^%+%5u3nLMP#r7qgO67 zR1};iu}-cQGs5qnm;W`d|HO5!8R4xh_+5a-@dq2?_Ww`YcfiMS)cfDe&g}Kx)P1Ta z+d5gYEXj6kM^1BkoJty?lXNPvq`Tam>^LMr5FQEL5D0`SN`O$qqXz<_JbDQM9-SxP z0iiwM(c9(!{mtxNv7G|%^N*w3+1c6I-QWD?*XK8+$rE9jz<{h<$5rOA#{i7cXvRim z*d?!3AejTL`NZB3QB*L2U|Hi)uRhA1YpH`I|4>W;o{F{jI?Lx!ie7}?!#+;d`SN<; z6Pd>&S!J`42dMCmTB z*eCdy3JW5;YgHn&VuFZ{D>;%VypzzCWQ|cvBd2{YkX6Q__cmo$VZch-43AlMJtA+~ zmPZ}h988a6O#-ZyD(hs=A-fLuhsowcqaO}11rCHrDNqoYP-Fxq)fB7$f~O%0GwMVX4Dmx#eT(-Eo=+sN$vH*>0CWgz`*wkl9iQS z9)~A;m^`>T+Kb2+J{lT=_O20GBceuXxszN)MA9(JDKi^N^(zVJ1Y-n2`kjGy*JP`=2hQnW>wyUdjRRu1q zg39wz;is|NkTvakM9Pqtov0HsgyD#PcqJ2bN^=N$LB(BBqjGt`b4jF$?f_H%S8hW< zjK1-oeIq?e+X^8}lj5u$V}A%issJ@iuaa!zdgjFl|Sm5s-L zN5DsS_)3sWCme-ci6Uk|Nio`btTi{PPDzCb7EKKP!7(=TJ)Jv|f|Ouq$BC=}?~JTkJmClJDF zB7^&TW6AYotS5j_=&Sc2?5_y{PN9%*2#G#i+n=^~@80cLVeK8FI-jqph0Sk{$71o# z`ga%I*3!|@g47MzFDT?`4SITdJi%6a&IggCsIN)iID`la-`S`bJ==$XjUoMz=3a{i z-v^%a0lPXoMxp<3p8MlP1L|Qo(|A(8ud3f=N+>ENyN~ ze@08ofCov6S5$~hN^{jzIGozFd2?o93nGfb;f*!K*w(p)kv*)biG0H9*RgYOu!GW5 z+>@$lb`yO)-L0+IGCa`Q+TGJPfrr)IGgRLj(QNtf!|?0whkfRJco^s53%VVcK%%17 z^uadq?)X^xK%xZzfc_<~I_CcfzHD5Twa$-}RH`j~I$cj6hgMYE-3LKi(Tgr!0PzQi z5UWMlr>@|{+2wpYZ2UajwP^=3(h295oxA!v+uFuWs31GXI*>bHbSJFh=6G9MXWy=! zTTSF(kBxS8g>jSN=Exn`);2uc)`kTINJ&x;hTR_C;f==q0W%Tr@;I*>=*5l|u~-7} z+Ssk4Z|ifs9o*yebj1_2&03VL^KA$EJ4Lu-2PNU{W4rf)w-{KQ>28a(v_xRV=S~9* zXYX#-N9lZbbc97`|AB32(9_q~iUsp6tz@lcl?I>xiz11(e(Y(!wWp`q<6~1{pEv4- zog?b?h5y*!mWcQ~%{@I^X}_@=ZzVf$4r8QabO?@W(=cTOQ!t0>is-1?Wm`0*i*yMi zLtGh<##Gkhpd~0mWvx@wHEKRe8ezRL0FnCp_gl8?n*D%+HG#j1UlE6~1FPv++r~ig zsWp;8l(w%C{^0)o={{0NNw}oIH(gD^ps1|!whdcQr(^Xw#J)BxxkJfKgN{=j7Xdc5 zFGELoDrr$gcGA~sc1!4HUv*-FhwB(`7+6S znDT^FHvXBfnIIt^KcFv8*!e%KWcaP%Gp8ay#3j()XB-q6r7dLGliZ>#lq8Fct{PE^ z)o6+{o*n})F~NMwjEH(1yWzGFJEX|>9lhD*aIDX=FZyqo(gZ%s-Q8((4(%Vpis z7~isWVry@!UDrASJaaq!@v8<02mPKwSFjz7#&GU)^DDrEI`(c_#CgZwjyZi`dj!Xl zSNGScL+a#f$*%6r=ET-5JQ=p@!WX;6UhFNnZxj)r9{*s_c?vSeVGHU&=#sv^zGz?c zbbZ+0+l!6bDO6wiL^P}hkZ;YlFk<>bz5?bdO~+E^Y4$2FtD5m-(lW`(3o#9In-biD zC@Vo4#9KM)0a$9vu7RZ(nG9+7gLb6-$EH2*XtXtn#3eAnx{(SGsZVB4P47WehIjlX z6MLK7wu8!hXS!o?){8Y1_qoI2WIOJUdc5`>)T!#g)zlh|qSL4I!M$FDCyiJB81#9~ zQ+LqGoN1tMp|0t9Gx_1t^o0{Xk`)dW@QS-&QB2qbzoj zaP-2gMn()wUX5#7l~ZB2S_C9(2gXioakk!vBM_2q8-X&b6dxe3eN{(ALc}CGjdpz+ zopt=YdH{4N-~rv&%|3(ub6{Ev1bqGHAWNj#W18pmgOi4!(RxvZ3e=v{?+XO5IPloR zj*~V%cI@QMVU#=Bm5JK(dZqO|yv1WSuD%=^TlQ_z9sO9{y9wFWNfI{|rV|GmAMQ@V zdqo>*AcCWNL?s%ef}N%dvFH+{uogT^DFAGi-&rk_fb}PGDl*V z)jkXK0r3$l#R17D-Q!wDNh_I!zFC>}O)|0p;qUQ9M>}SJ=9@HOOgBRQGG~Ww#!;R#Go3IBKS^dw<3~-~Xv(N2~`2om29*rW~ zb`beTZA%1Ot3p*l`E2Ye(b|LzDj^S_0QjL2`Oa%@Yi&K>5}#}!yFJ}--@BddTeb|^ z7X4k@hEgu1@;74ZZB0!`G2&}#LTpkr8fnFt5YL9;jjduVR6bx$fN7f2WFwL3(Moj$ z7%erj*+(Uo(pW$SB^{EE4gd(^PeYb{b*hnt5QzTPahkIJHuQ!f1tMpK6Mv6uZFNAM zs2J9D#J+tJYi181=kYU;rRtTyHi}s#0Rn>!0%jkzzf-TP98rs}l^-6=L%S{Mo^g^w zG>6%qgvO-r(O|N}69~0xdpoP=qzS2vL{f)RD-RK|D?&hZg88qW0c8BFjKvYvOAF!L zZP9=)+?KEf$GfohHZFRwk#1Yq7l<~yUfA2=ekx1YPOzQC%IDy7K?XuCpL8? zyF21B7`#wtxE!VvpFo^~&_J2*LckXm~EDsLR^(x+0qRsKx1s|VF{53Vv~^yu@DCj+uO ztqS3czRVz+4Z!;ZBe*1+pVKwlg3`bxZ!a2p;I?-USN+l4%q$b^qQ6b!_V3O|Ao zK_u}$*h>MggH@wWl4v5Kj;0+ zR+B)E9~y7?Ssc(-S;`T|N-Kxn?n^Ddz!DxP4n)Q~N7W`^$JY{325D76Cpg++Rkiaq z)ao|)U9CS+&wY5qu@0P8&#lYfSQi5{QuDFZ)lSs+)X;71(U0_Mm`fBJ?!>w>of(EG zxuz~8K`11mUmz6z0n4m^fWtV&5)eYC)0CkXtu&osUkQhY1PfgNyJizo^m{!1bX%7x zw`_%|)(R_-+n)$GB`(-3#ZVy7UwOFR497kgpyj`tFGw_n6O4+axc@KphAiUOpbHN6N_fV>$uK|Egrs=_+nbJkfRe1fg=A%1)w4^Wjgkzrdd8!>-j=AVczNK|KJ$bYEJ-)LDOm z)k6ejrPC2ytM9GI2JWGM$|68-u4n>j62zwweBVd19>{_*ff zpY954Ir}hxdWf+avChoe5I&V-TyZmup|1@r*yA=Z|B-jx>1&N3k+81s09*`M{-kid zgvOACBdw6FKw2%0vdQ`ZZa7(|e5pxv+i<(xZOXcU zEfON#K7Ug*{1SRe*oLcbNrGkd?N55)ntC{3Jh@{6KD|-)K4rOakS;>dq@mIrfI`e^ zFlY=&5=sNX$Q{&`?!xM6L>}_xN4`UHe zq`6ycZs`oikd0Jkl7PI46@~Qb?}JO+JT_2zU7u%PQe}<{Fb9fkNP)l8ceO8wHwkyN{N4~wmo81 z356+K*bT2JaLM*>r=aUOdcl)1Clx+vv$GQRlx(4JOX^(7dL(oNm5vA=g%^8+_WC+S z@^t?xVtZeoKNXI37=-HKiz@4wSSkY>j+G7Yfr&3hW2f||5l_-Fd`m2ebbzhRkt-%N zhp>29s!r}{!~30seKJWCCtw40lavKf+sX0LP$&D+a8PI?6*bXfnEoYDTLvgClu*Jf zjqNAz3uy+i0}eKp!jfIc)3q{fw?x4N>lBm_vV)O^8g>U>YrLg)JKPot80tI>xsD** zH=GcNRHxKC#lukF%B)S}Jo(UZ&Fk(Z`H;bP_%M4h{M~(k)By!2NNHN;hSZI(M0m4B z7RdXj>^F%K+UBzlTofb(ZSW7`T3Q{P)MRY@n|=IP0MZXu%k^Wag!AnFMC5Gjap)f$ z9UVl%C+FFb1gR~&?`$Ww+Ujq?_CYRpV56RDF`3wguNxg0*n~U?zMEg-y%`#}8H<@X z-0VHLEpf9C2@p073{dPVHZ-ca)T}+)6g{B*|IUQ1ddaa04yHT`zySnq+9D>A2@s0# znDPkL8D^o^lF>Gigw;{u3f)6?OwvJ=SfQ*5#GZ*6k7FW3%pxG6A<}K0ECCL4>=+n; z$k;Lf23;-HM7mmOCu{9NVhC^A$K9^L*=2AH`ojm+21 zo)&Ix>!l|ITWx91WJX3ZndX*S=}|TkbfiM3`ncihCV&p_+qVyZCPOj~`|v?D7~L+! zj_(U~rf{O4f?v=C3B6_=`XA+jB5&(8$U@raiB=&n8s_i~m=-P(CvwQgCd)LbtYiTUxrhT3WmvbSL(o z;MiQ#+CVI%yJ^fXRe1n}Rm1WXLFlGl{|xlGXryBX5e3+-;}!baDua4oQ6^{hK!P`T zfGg10C!tBSGEzUEoQlR`(bSUzxSh4SOy{KT!4B5Na6w=Ht0g;YPYz;yEP2dH`Wn!i zBv4gSx`NgpRMIY`N$8T2ph=d7OpO^r{)^#s6uK*2cBbvZ&%)u!K;Y_7@4!%hz`Gc> z?U8sb7FrB=;*ro*s>xO3n8>usef+A|0JZm>z3+|sK(h5@IDAzo688iaLlD+1>=Poq z=<)Xt4fF=D(oM$ce)#mpud2MZp%3koQ#7FiYx>DPs~MA`U|4rclbHAc{i70vWa)MM z3azZb2xXyA)Pve7+L0VjC>v0H7t{gCA4H(5&Qbbc+i7|$QZ%;Je@Oehm-9gPX4Ux~FX(c5-Kcb}!%D4g03|X3N2gSE@OE zEjt0$CapVKv5IFL)Y8E~;I)RY4QE%5??|%2YTcQ_4m2bsi zixY~`(KI@!=TcpPt)q2I<%@Px?U1<=Az(D=^v@%dX|HvXOYHBU2;*~cqq(#w9gzau5(2)wNDRv_nXU zs-)tC?wjcF-vEPkMTd7Grg#cFge$!bY)lhQr$%}usbRVjOllNyl+31p3EUM#RYxhL zFQG_*o*X;IrPA9JStV0D2}(eOq$HMz`JiqmKx@^)2_dtNFK^(5U(N7EF( zFoxjF*m)>z!}jrT-d>`TT)5fk0qlMh3`Vaaq57%_=wRh{rfI@o890S(FME6;)9*6< zjkJ_}cD${v`K&#)^*I+LT3e$?TO9bo6<1sl^d&CUdH*IwkRw1t`P0HYz&oH8gSq+l zkVWMbFSI~xP^#$U`>-^X_}U1f>Kb7w$MC7zKdVyIKoC+8wLTuYM!J`@RYgd~tg8fF zlyN7(ggP1)fDM0S7)|3J-G{sMSR~oa^&qS~(--^H;CTsS2@xmUz5QwNL@@3{+}XfD z_tY`SuD%I7{M zHHNngCaz;_=T@RVw=wo=#@QYK3vC3!!w%&n6UFJ#NI0q(lHpxq_ zjJZ6w&<<5i!8EJ32$@10{vB7*Im1AOE#aZhL6(oZR z)wFAPxI-qoyEY5NZ=IuOI)s-d>%NE707f>Y(Jg4j7wEmpOSu7_zUJ76?0R=NJ_vnuObPN7-bWl-YtDo}^qq)@>mG{R+qRKm zL;oYWo}iN$0ZYfNN_$myZhSb=NaF3v{yuX!m#U>$nlm0qA_mAA>T%ZWuqFcx_R`nsb-JJ-CPP?X4GRATWPPFm@t z6(=~x;To{71rZ@qe-URdL;j9#+93|mjgo91RRqxEbs~Tsd98QvMjmT;dsO+%9lb5s zCk_kf5$6ssWiav!xI^g%?5!B}MH^0fAE6$NOvKJ?qt$&Xa$=~(G+Tz~9Vcl6JCa5J z0^NZjm&Mh{e{cio4N9ES1hSq;+TI}mPv=6goe@N434fKRh)65sIE>~v*fITD^Z+#m zNHLLCQrZag&V~Tb2chXWo40f{-9j1AK_5+vygeu3UZ1vG^wHl(3xJBpKlBxtuX^MGvu z)zMTNLz4P{5UvwyqIL~QjcO)AN5;cdco^0@UJk5q4$+4v;~r;h=Q&JpImG#3D1K)= zG>FCQ606J4*-2SYlGJS21k!kkRuJ9rt`Hv4Uo}W3WY?USP;!VPmk@SFR!$g(%x%6< zyr0H2hDXOeO)2b2C^HAn%mf0NGY@1iu7OmOH-=}&s8xSF1jA0e$zE8}6wl~qV>dJV zq199b3c;xsR$=vmLDmEbL&8C2goQNd66lwcWL8eOKRj4pUUuB<(77BOlsb$yH-M=R zC5(&hlg237R2!BoJA!IQn(T!(fVDnG`4|Y(K?6beh!e)aNy&}BBMov$UTY$VwS+C5 zPJ1Ae_ORh*BAsHa~^TOvDe6hnLJx$juG|ly_@%Ov`cOyX-yK zcOgK4UqH>tnpj&a#2gzmuJrd!eZVdecFnw9!&VW6H8J__FMQz(SmK2a3g82WC_A`q zOlwJuv_zpl(sRcyz5IZ^q5FYIVssPso;8-}Hv9Q>RO$phpt?UtHJYkgQ{}PHE7lO% zb4pcftfj@%#>}|IH^>5Eaf^DnTFcW8yfvH9Y|ze#x3;FwS2br_#hLB=vM%TYem8V! z11*X7Rqe3b5NCKbqQ14A)3zKFc3{*M-zLKp1zFO#61yR}9Z{rAiJzqRLg3U~k?5x7 zh=u$`Tbp9$jv^Sb%It_nC`iF9houWWiB`lJctXq(f|)iaw#4Ml!))F{d1m*|%c6=1FR=S~o~VLkub)1HNLBB4xY49HGgE zvSFunfbI{wpA(88%^*Nh2>@uL_y_7BUy}3*%BcDy=t97yS=E=mC>-qfdk;E&V@n`d zkpiLRgxg(+HZ>=f-1DczkYK&NEq2)F+V^7iOE{)o=7e717e3$o%>$$_fP=j z&O8-~EO$B4HAD%6!nxVySXUnpMY_8NDjW7B15TOBj>kcdXdk%CAyXc~ju9tYm1^mc zHnuBmQA=K=1Or-1g#rChY7fbwgpXR3 z+u+E#lpO{!{^I;GEP9AvWxu^>i}m%5ZtcSOQ+&#O$Pf4lcmysceGT&jV~JNo-Y4s* zBm=w>EfK?O;;1*2uALLzpqNL@G2E%|R!5}acz-0Yt>yAe1}lKuw+&v^-R|W^@QO^P z-RRghbYF}z3>!ney-oh4KN2>vEP2Qn9vd5R2M4qb5cZLE?A*RX zWvtOS+o{MlA`>77#cQcdJ2A`CVQY;BZDXQ!A+lu?Ki1e=!(nX=AzrQU87LB;R6W2pcEXLS4~1`} z8@(1|>0o`z$xe=TJrC*E(&wstq0h-2-Fx|0>0?;yIEiPN>g()Xq3o{Jbb=Z7k@tVXjU*I3 z=1}sweWEHKr5B+gJ#lBK$^+KcV#ke1ZO14@Hz?ZR#66-;Rbp)F_#OzRn%A!aZ+l>& zJp*=4;`KC|S}r`%Osh#r{KRwu5Yj=DN%RA5<3z86BXrR8XFUb0QJ)QKo!^;Wy4TwT z30Z0W`nO?!qai3#*r|omKLpo7|JD&X(WVAd5nn2?3F@>BzFiBIH9|M+nRKtc!kK@{wH^-k^*9yr)bSHm&)vtRN$d4E$6*OZ z9^b6i4q^VRL*Aq;=+NC@v1pX-m9K?tt|XTz*uWXrdjO*Ey^c0V20JbHrH26u`codMahlFrq%fTZR6szM;0dS!dg};pY-vW4 zdMu#AawlvY+}yHt>sYVH?e%pdl@%Ts47Cj*%3|BLvEBPl-8#Vez}8du?H=2<4LdWj z>#!T1t9$$K0KHgWW&i=_8fPbfvz^G&O6wYH@qY1PO`WuJgme#@Y@>+%gbGUb+;N?v z3zkP%ATXqKBpo;Wm@O$*_Mfg#PN-8}G&G*n-kFJwiHS99 zIO(AN)>Oy|PF8DGh&>Ns55M0)7i@UPeM=4Ogr22UXh2^V zfwH0 zsM@NeU({`g_!V=c;D@>w_;3br!S=A(8WVjP5nI@uX`(ARitKzOKar@bBc5~)pe`qg zzJ1*fVQUP3R6PL1+U4N1G^8a+*J71s2?*m8bzRXn62aI4L*W^^Bj8Vowy?u z?dUrtEuo*nojQ@CzI;)HYrh9w6R%OW^a+e@1}hvL%zkTnTf$2kAie68hz{NxF);M5 z%Ijbd>7sF`FHk8ym;-pjut~?zP71Md@XoHCL)g!Q1iFb|hnN{W!g^$wL45 zAp;=|@EJFgm$i+Ko<4Ef={t6`T_%}(hNGJbR_8b+(s&?GQ*%H%p=?_+0R)qErEgrwIZwpbsL3jcs#*x2jNR;X-&_jY1#EU-TnY! zqSEtKcv>jh)7BoE+@MFIwy{Iq_XG9YpnMTMqGQz`I=11b`RvV(=R01FF;5Vuwf3SQ zNHG-z@1zfR4iACH=zrR2FjQ5I?0Q0G%2%(U0W$+YH4b-`LJC!;5^*p6PnR^>kEM}x zkYO5V?nmB%G`#}aDBm?3PP3mSla;mR6eP4JHra&z?*@@o9xhZQu}7$mM5-}gAc1XF z1NNCe#t;O6MFfwx-QOu5kEKH4@R!0(P2tcx>_TND#O}ePn=5O{BpumgGI1&L-p~rs@!5f8xQ_cn4WDF@N6|diKeV69y5Tk(uhX@ zw^!^a3|GKbC`k+IXhLF{9LrZ%vtua>FoqCn?B{lgRep=@v1udF1(3~@%Vn=qM;3E5 zw42d!^}z=pq}v}nYM-Mxkp3`Gz6PUchzwFY z)z9tptK&Yj`arkULMp&!U~VD)44SGB)#wu2hOFrNI=<;sjscYiWQ>GK_%GT!p*?`~uFyCd$F_V$*6{cR8neNFJ{ zCl10F?DM&Th$?r*eU*FeyYD_l@`f%M+=iU#5oApf-TOo zasVk{m~(L3x#wN`6CJ1|We)3H-0Y?eJw(=cVa%%M$LdemM=3shK9_nT>D@#BCA>aD7vt!HV6t?Du&8M|?q7gE=~NxF``>P$FsVRHyaOd|{*?&JZt%ZVzN`#=h}bajvK zyu|ivU9xk$yDLH&%CC%Yj?LGdzD*ro4^~xSg&W+^47qzmD1u+Ov8)#UREN)l>qz5{ z6>>&6;zTSP@Kfanu%VHd4=6>sT78#9gcX` z*@?`YwIxjOhQTv7o+h;sz74fiy0YXeO#-tPcn*1yoM%c)2K|LLkxY)j;!2Gv!X!o#+|??P`s+c+du#yX5o| zwet2TC1j7XODCKMsbTt=#5A6nrrQrX|K;zpCK6GXbol@FT{TAgPkffrC>4*NIQfSG z=Tv;+IxvpL3;W1M;a*g%RMAn$-@`F0D2cuT>J^fCYcfF;luQS4=NPpm_KPcujaxb9 zsm0?r&QG$~q}Mx%G}V+wxu+Kks$s+=3*=fV>^tDY|KaT&o5)yOxrLTzZR*%Q86vV7 z!v9XFWYr>@*u8sq+}$HYk2}6wh<-a?a=#GOq`0Bb%cTE&kLP^93~k;#jvmqT_~y+a z)&#}q_%2oNKyk~CzY4t+k-1jPvPSQ)vZZL$w$YtTnmSlX)6m9q-F9>p2)PEVoW#-M znp8Z#%JxH7Y#%jlp*CpBCanTh+3PJ#cZJ)7O$3H^zqmFLx`x%*5lOMb2NfyZpY8X{mPfZiU@1eOto`||oRt6@*ua3}5V ziSv#6M0m9f|FzO%T?f7(_7XNKXiA8P4m(=l>Dmh^<>`Cuwz( zzET=@_3vc;$s?85AL&AU{r{~en>*_sZQ`ZR8m~3HOv6cIyT{!}N>5+?J5hhqnB!W- z>{q{dwV`3dZ4H+i?`n)wXuQ^NTjQf2x%-AIsrq+nxYBU4`uLg=|DtsnnjY!Bu&;y` za0_y_ya6k9wS}K}04>I-3Hg-V2OHkjWeu=-#Yw8VYrcj@X_eM1H;A*4cY#{QYvI!L z3Uq1o#8wXdsW6;dDZwhrOSx7Lf%W>6$@-IqE2-+x*Ecz??6C0nV10i7%Ds>0*7`OL z@0Y57#%lcuWKGx*KElty+HfD@rLfBl>{vB^s$?yao563vwDsCvDp6>MlC6~)gu*>& ztpn*$3Fy2ef)G`v6(!0l3KrgnmIw-Ypgv^vQ`jyq*}6Twsl(rWQI|Iyf=uG_L>_iv z$(%FfiKdd3dt=T^k(M7@iYOMjw^tx*3nDeekT-<|LUjxNUmC-%kz29-V4`=fYY;2Z z*T~)+42Du+*700V{933(uK1*e(s?a;>V!Hw)=9c5+5gE-wC-O(^Rs+)!Z_ z;TWMEY%%QjJ`xygDPyw!gg31Pe3d7_-t7+W3%h--wywBt7g|^95sV>_D7_Ogc+ORr z|3zJ~@^+s$3v*~wyrnhj@kCo&kbs}XC)o!*!DDu3blep^Tz@**Y^Dr%Z=i5UvN2H-f96Wm}Zh4?Fm?9V;)ZocG*OGM{))@$W;8D17noN z$=Eo8Gia(QdlZd`1{f(mNdgzGOCBF**C0|kcqI~)?Aepc-Q12n@Jur}*&6L1-LkoP zIPUIeZwi_wcEM}EIhWhB2boE(M0};$?~V^QZ{9N6A8nnq@L$vEX5^+l&Nib}O7%>H z2`hz}tf6?mRkl1|<9J6ajpA{_-!&m;OnRDI#$p~A=M0|+TARiM24K`bt}zXL)<8Q? zY^JN?2Ai!?J%XXkci_YETXRLTuBco=eEzbCn1d~W@;uKWgTe^IdtN}<76mCjvcOI2T7#|pt0XFqfPq($hu zb^{gTL+d|2$Zta)pA7iVmEb?1AW5c7FuhsWQuj6 zcIl{ExvJT_9yX;);xhP9IvRvs^dS9Kel;*>!Yb_#z_RI;0e{nr-%6WQnb*JBv(ovb z9%O0MpSz|HTf$=<>_a{*ys02oGUbjjNs~W!|jrhu%rVm;R zTB`jKste7PL2A)4<(dQ;M_Kb-FfO1ppzr|?9D-LOngHP*evc&?q~JpIQr(re6EelI zi0@nr0=1LLsAnQXER$BEIIl!j8vF+fXK2C`jrI5UBlWh&GfBNtPd#i;lmQf4!3 zPww|lvO7_S*yqqW8cKE%R zg(>n>)naZ}<4ly14-?fE_3Raa%03*&Ja!Vq07u=OGA!GjkTE$8ZZ-~U@#BEs$hiST z-1i z31@*K1|ByS0(WYNXY1S8HS7Oa`?5zz#y7+At6^XrKg~$X0duj(P}BhCH9gQxLjT zd)W1O5w+$C4?C^BM?D2k>qsOiKg&sA9VI#5hDw^Kr=_xm8yLsfh*A;i*iO|=S6%1< z4nqWZEC~$)5-UMjjTDhmXP*j5oup8_K0Vr^DuGK;Mc#^6hUHPjgL^6~fP5kaqt2*gfA?bc0^^J81STCrb zHSSI(I&1*SVfj3fckM8SkA#9gQR;g$uq09~#&DW4C{ zMc_1dJlcmO_R*X1?FUulb(34gaRUUCo-~ z-%r9OF+kb~^a?^Upb#(%iZ@QvnE#|`TFV$}HQiP-eao@>Ag~*f)i@xv3~JI2^r0h5 z79Of^yjmZW)}5(uN;li*neMgvhKO1J2aE}~g0A%;B13C&DsBMr1@sTEO;bo|+ek)@ z8cJ1-FM&}yN%I8%)MwK7(O0SOKr=QG^TJOMYL3Q`n*(m#Eh+3*8;drFU@q~- zzS6T}$C+pD813#$1wsLl+}gWu-?i87+t)LY6sSn`u~iNc%jEt2BRhH#7KU`Py*ozw z`?(2mi+?$a0A%ckg{5gew_U!JUwf2nB>1*fd|NMh6)1KaE_#Th z5+WDg+lne7X-S9i5|y?-t&C*t#A>TcSU*d)W@Cd1|W zSfA@I(n;7xY58J(?d`Fc`}N5{knixO|4h2eC)%5m zoBgdF>NT}*m~=#+qa8L68X0uqKDuhy$q>LUyX{2`a3w zQ-C&jGifTmQA^*!dH?W4P+cBiPVOXufKoy;8j|`}XdZSSral=Zt z?jG(XWY$9t6oB)~4&8+0S$_f?sa;{ejtN(ya%sSeFi8SeRr~ufi#@d-n-SJm-Jb+O zy{j~*@q^+d73t@Nu0%}SBHYnVv3ShZ1+`Xp@yF_MT2L%z7M>{J}R6>XhSpk9l@(_+&R|feY?w8VsAxPCUsQTv-%IwV)vT!!_ z^vW2zj9qIR$xy&4D)A^KAL-w-Z`Y_|5&kL%paRVsq2>+Imd%J7e-gX|jj@NAmNnfM z`@w4BXjvc0Ttjo4pg?ko*7}JL#<5!x7D`pQsy5}Q>rqfF%y@JKq$Gn^7duGP*piJ? zm@-zPfso>k@N2H72rvYv34GOt{<2l;Fj;T;V~V2^(OA<^wd1SkIUB#3RNt>}R0|iV zKdW0L_O8pCM6hu<5-dQG0P4RM$K6($!TvR9m1!4>%~sjK9uyz7%A&4~MAXFrtKP)= zA`m9kqX%5}s8#kNH~IIia>x-yE8Qln`ZpX*kVLtIpNi-kDl^A+cCl6F4i7tEl?}%} zUb4!fu8nleuv@Kq6VLsFRrWZpWIwgaUdJGRmsJiq`dFt`4paYU<(JF*kK{`ErQFzA z#au3PX?}5GhH6t*b!sd{7aplTr7m2NE0z}W%c=44(ZQkNU8BIR(Nup!H-~kT-Knv` z@xkqzFPqP$j^w7&rPNZsR8AH0g_Xr@F|{y_UP`%gD!V+BD(CZyhZf3%r{@btiwkq} zIpK3(58&OPgi#y#a#=IIXr{f_T%o&INDG?9&(RV z-w4rq2+`so`&;N4WxQ<(A&}efZ&tl&8E;rWmb7UMjVk_A0u1QkcQAKP@}GPPCN84= znSdqS?+7r-OokMyh@0>*FT=VQ7J$Dp#KO=+x>X*bX+z#@IO9$#${b>=d?#?PdGe zsaSfkA8{I|voqM4>@0SGoz2c+=d$zI`RoFAA-f1h=8M@S>{50aVmYp0PheNFtJu}- z8g?yvB9hlU8R0QmHpQmd49l@uHivkR1$G@f#1`2STSnM^fnCpvti;M}g&k%`*bVF` zyAd%VHz6l))+4I=**$db)_Cod|b_aVg zdkMRfy_CI--NjzcUcp|;UWI&KuYv2~wb(!N_3RDoZuUm@CiZ4_4|@xHD|;JzJ9`Iv zC)O~%i~T!$H+v6zFMA(*Kl=dtAiIx!h<%vd&pv`k<#qNk_Hp(J_DS|1>{IO1>@)1M z>~rk%>`Uy+>;d)__8|Kz`x^T?`%m@__D%LJ_HFhZ_FeWp_I>tWY=ixP{gC~L z{WtqD`w9Cgdx-sv{ha-R{gVBP{SW&!)|&m6{V)3+`#t*u`y=}k`!lk#|CRlX{hj@T zRoKH=SAASf98MTf8~GU zf9L<;75=c{Fqna?Mo4fY4LCFmmx28!46otCo)ZBhXoQTg5kW%qm=QM;M$%|9nvE8t z)o3%2alzPRq>N6Z%jhz_`%3$T(q}EXuQa{!+5dr65~$erN+yQyNs6`uP|O|yvlgB@fu^zc&+g| z- zu~}>pTg8CLh(WPU42fZ}U5tnwVpNQYaj{eE61&AIVvpD>_K8!)gxD`m6Q_$a#F^qO zaX_3c&JpK|^The$0&$_ZNE{Rwi%Z0%;xci$xI#QZTq&*+SBq=Jwc?55N#e<3Qe?%H zm=-f4CuYT*m=_D;I&nxWiY2iu@}eNF7e!GLWw9a-izDI&aa7zWo+54%H$zo@s#q0I z6Hgbnif4#_6VDX4iQC1q#Iwb7#B;^-#Ph`q#4+(g@gi}Dc(HhixKq4TyiD9BUM^lC zUMXHBUM*fD*2HVY>%{BD8^qn>jp9w>&Eg*M7V%c`Ht}}x4)IQLuXvaEckyoV9`RoB zKJk9>0r5d`pZJjYu()4*M0`}Ni;szqi%*D8ivJLw5}y{I5uX*G6Q37f5MLBu5?>Y% zh_8qT#aG4G#Mi}tif@Q-if@T;i|>f%z*ga^7rx&@{jUQ^3U=w@~`r5^6&B=vLYWg9VRn5vegPx znkF<^m+3Y=rq}eDeluVO&5#*3BWBc$nQ=2=Ce0?Z*=#Xe%{H^$>@YW(DYMh;GP|+0 zVz1d}rpa z-#pDc-8{oQ(>%*OV4iKBW1efCXP$3fU|wimWF9mxHZL(RH7_$SH?J_CU|wlnWnOJw zV_s`M(R`BmWOLHYnp5VqIb-I`S#!>uHy6z7%tPj)xnwSzd9z?%Zx+pxSvFV9!`|Et z(~H@qY#Dl+b3R*|FK6exGxsgNsX z%PYlPCR;4#k7UqfId)?8O2Jt!W)~K7Mb}hz8ZWw#bz6m%CC^m;hD>>(R9eZ!@JTb7 z`TXL{!tz{ZDL1n)on7>+%2FX)JcRF7XQj;4%G4Cj5_GLJpFNZVu$BsoI4lB&!MbXF zp3Bal#SFeDzcM!;pKmQ?$Ubm@Sm^1@Gd@@?0sS z+WHH*JiU#AO37PT%r0B6<}0i$73@!QtCLbbTkw_U7jla;`fgELSUx0lH99_$ElWaa%Eq3rG(*KRQQT&+?89*9nJ#O(bYjrVYa8t5+kiwosk6{?=4>~dB^+f68&naxh;+)E4iSh~%-l&7gX zh4YeUIlBN5Q?$RrxM=*d3)43pqy@cT_6my_K%VmGV ztn^xEgqYS9i;4iNmNle2g~gRpW@%x0rQ|AsC;^Ge&QflgD6m9(#o{1@#lcc^O^i~4(I^#w*nL+ z+7tq6fh=jnqE~aPX}*}BK4eYW>HOh^nXsO~s;qB}0>|d_Rh-29oj%muSXakej%%$k z*lJDBYSvSmCVd9;J3C#>gU8SqM;fnChb0C}6pak)A0MXDIuuQw0pP0(#Hp^D`ifH{?p7$J2*E9n7iX!pvL_=tu_}N%TlJ z*42-6;}t#9RvitV&nl}Yn^Ty-xv~H{mRhG)7BuIzuu%`2`r7#M*VId#a7W#1oN$MF z5r4Ix*~Ki_fc-@MV)ohcTs~O6q&cIvdcLw;yN&2(pn63S6*;w1ES1e^$WQrY4;{)Y z%gedNAS4+uSlFGXvSknsmpTWh^I2cJ43<%fOfN1J6kEwCW&xTI1yNst^e~@4LQGYG z&4q3XD?n}k^vV>*3uF;soQda_59b#1g~p+B=WZx~FQ6+qn=2NNChKQ>9mK-*^@={l z>TB%x@v2G-DzghfFMRQGuIQd6;yb&rT=D?6U} zy_GBm999CCErrpEn|`KOW@k%Y&Az5+az}O9Zm8g?B)C#lgwvo6gV+-v*EEhKfk;D* z!lkB$syeVVwpDOx?2w3NVF5$3>qgBIBqid)#3QqZvk=VibbVUH zWC^wSARO&RLnt0iW11FA~|o`^Wu;__S= zAF6br3`lo|zS_hOeU<{DrY8h6rA-i|0#=zM zTEN0SE#{}Da>b)|%VIu1+iXcn8cvF_TTH3(3Z}o3=Bf9Xb3Jj?-8 z`1XZd(W_6CgcVlh`cF;P*VMm6eZ6{uTh*xVR3*rshjJyOxH9J{K{(JlW3&X3J-=vw zxcbiK#=5$P9M@Vs#%r}!WYj9tL;V<2G6I0zmlvjCDp2MG&{DfNlb^GV42siwK$f5> zXO?Fd5?0Yd0QmkPMdW6DR<$-D0C2OjnbIBhZTlKw9w8k1bV*GRSL^ zek=s5r#|tz`kLqtt5LPJ5~-DlUaQo?zod#%(6)Hwi{&iLKp}k&3T{<+$|S30ra?%< zx|pAWqzF|WLYN!Wo&>b=Q4JUgA$rqP=3U9P7SArFVq+mtU0=f)Rj{;b4y|Ae;v!O=yViULW zJjBMidCMvYjoQWqC(s1yP0>U4KIlczk&|kS)L@h>TaIGvvHE&49;&&6U=)0eii8Q4 z=U0}dNV3)nZ{qkHR+bg!YsK7Bxc!jKmk5=VIPX{A1ar(B)oE2*6Lm!c{qwmSvU9K| zXxYEv4A!Z|vfr8lQwz(W@lnVVAn^;900Qf0`KVl4DJ@Kgju$|rnqz{fjiB)qc#)-W z{RhCLGY9(#;je~`N0%2DN@c0QFEz-I?;0}?Jn@8DMG4&nh4}f|S(7Y1*+nr2(OW8U zPC}2FJ|u`ZxoAEvq97NRp>SFnzBa#U?bfgG-_{5MRpbOBm&!tQL=?z_&zvdD!^~9j z940dzWWCv0y9jB@Yt_y}U^K5Uk}=K+!b?X3mTr)axso6|pvyJ}$^wjPq`#3#P*BJa zt}o7*;Ia_sy=53&GV?i-KRv2^WMQT}@4>Y>%rY=SpDvQQ2gF^UC^qQVlTV=zY@PW-Ij2PqVChxrzeW_>BmtR9 zk-Qpx^TXbK=m^Y}&=qrq+Sx4VH5tX#HGzqAR2E=Q%>i}t1t%<+bdS$E!oCNKt$jir z$=r3I8?a5~4#Nhg0N}Sz)K`10S0|*gHC=@&_K89=`$XYg(7MGIwCpYxmS^)GWfvlA zUCDr@&ZEgBeWtd#XzX$6>Xm|ZonRqhrZ479=)w@lmHtd}mDEC?^~8G8HMcMeM9XDo zF?EVL12z~p{xl_smEl1kTA8W4Ln^upTk;}ga%d|vpsmi*JhaxuoYSHTCQX|hOu!br zRti`)s>UZMfZW{rCdi|mO0aLCkv7Z~J{Q$2NMQ6KY*eozU>e-@u~L+i^GiSJ8A zCwx(~r8@sY)vamu-{M zNNU-56s3@JS(vMcyuttuzrs?s-~z`jLTt){3W2`3mB$7nKh=O{n4ZJ5bph2uO~LbtySj_H!s5{kl-xj-lc`Y>px_0s z@``~(=n1oINmznNytf1gRIxM-A285qWlEP!aAOQ5+?O}r2)bKXfTP2+v_PE^`w!KM znnc5sLQ*kMSd(MOl2A6lyg^V`V5r1blf5lhj#|^%CdmY(*l~3VTK2rR8?F?Nzg3Nf z_Gtt(J<9-AWPDe|s|5Z5j~-@mX`vLh3$P7=oZ&TXg$QKN=6J-8OajOg69HdBpmg0+=-s=X$tT6jZVXJ+OAOss~Rtk}Z zbB)fq70aCo5~OI3c4d0%+=@rZKnHmVbtHXK(RIXfiISiS^dk$H(pfAIFnw1ho4L_f zeR-T%?qGEdViD?~vk7e*)0|)jPfgAq7Ms$BsvZgLx-JFaE1X%;;^Z`lEYv0Vh360+n7sk0sl6@` z`cW_n*&~9S3Q~C%AdyTTg>T9L5Y9NIV+!-pr3R`nGYjKC-UjL(oX=E( zTm+YgzDg>A;=uZn5^uE=;l>5>qU-AH%FIGu7nK;SdsL)kabXtrP)uA~OoRh@dfux8 z4wTdtR=Pz!Z*h`lfLp*ip?wvzg?Xp4trtsPjqqCKvJkkg3hZcU%A8#(gDn~5@=*_T zFIa$~E|nl2ugtlZb4LJmytg<4DFm!>k*I1F{1rJdG)`|r$iH;<()8`hT znU<#z(J>F%43Q%+WzHa$1VSN6ec--XOL_y5vnrL!Ue3>v$O#3Xbmp%Fd)#z%i3LrYL&YG3Jh?jzuzx-L`Y z1955L{KPKIDg+h8F(g`bni8anRHlX$6Kf@=CXg+=@yn$q$hH9jD>orT;>{C{eX9^f zSTn%_5UnJ~8#vJ1kVWPU!U(WJf2N#LJQ)d5)-L|a@^Hv-Xkr{LgVT+5MnT~?(02<< zxjsw;uA>$#)w6g;XPB(7N$lB|ixj&vm3Q;Jh#dr&iEe<~7U{)h-s4InGL88W8#?&X zSH8)Z|JvX2*`Pn2D;xUKKQ|ioYk!{^H?T_KoSNgj8=aa02z_3;HV=u-kLp-`l-(Gr zO5(GqN!g_U-_Be)85OoRZ92i zSb8chGX!-bY;t(53cr%v3}i%X#!fKqJ>TnTTOKDJTpUFhIT5So=GP&1@JAn68zTD} zOAGu&%(7P)L*JRo4nIa~G3mduKW6Stra4;LXE(YWuR0H`Rsho&kBu>2%fi`N9Qo5- zyvA8LBnCJh;d(v58=bj&@PuYvfA={QN>gY{AIu~-#?Squ+oj`=v+Zj;h4(6)LmWQf zYgAWkK$rQRsRtYFLr!z!>ul`=(We2nOMg+nDK^1-+dzUru|FJ8J1CyBuZ>Ui{QxkD z4Rs0(Sc!(jwrQ#E#|7oFP{tUo&RO?eY#UmH_IT&AM1DrCKrfJf!F0_p&`5GpszVhL ze)pOk->NI=dsTWGLi0@q4J3R5Sbj8(p4_^r1UFe5=7rg%4|Jj#*JmFa! z1JP?R5h9^*6poGNbre{sTH|qUuz|{g;+WO7q={!WPoR3yO-~?KOR{w+=QpF2F?SN_ z;73Md21fdayJMv4Y(~2Nf;rLvIq_!qt*aJHwoSYXhvxiTAZPSM9wjnwmdKM{#!%ds zPrF?A{aFQ_cxFpxNm$bpI2#dRJe(!6IQ0v`?hQo>#?}0wdu;*&<`J01j_Ik|ZrP$K zI&7=;8cq-#bcU9p{Uv2Qi_J&z?f$RL0&H4W5&(2%^&@AmQW(2p1vJ z9g0u+Md=+A>uhBfDg4;dP$KgNcb#9(9!YRFyvL4MRpC%lr0Ljpk|6x3LAQnNi}h9M z=PHo;DTaT16FmMscRI=go$t13^b6CAh#TO3T{dL8>x)CdOO0z982t9<9k@ny8Ud+= zvC;A&Z5E24O{p#c2CWze@FFu6Vs6MoM{Sc2Q(rD-{c)Id!c{83I znse7ckg1Cm24PRkpW$cldKQ@mhQTQHn$uFmF;z#t-3rF5#6!(-%iqhxNNeu#Dw-x0 z)rRvId;^ny4EdMWbB+)X1-gsOpps%K1-6%;VXz0e8b`AN1$)G9^L6=w-a+Ni71|XH zg+WpTPbpm=38SuaGN$q(-t5JpWK_MjC!KSC2IopjMk=u3n%i=?;m%bF@Xp0p=Gp+rs=(fvhd8q z{XwLgvojr!lG^DFdQI?Az714i+mlySUmN^KqW+T7!3NQWyye|bJ4-uD;m{Vk_d zY-AKv^ypZqa=+phmAcA7yF7z>*=-r?)*G(N{P^{8RKqOX@bj0)PD@3hw*$Z76@Go3 z;XAT34-))6bXOVgr?DOHT?Zz7dntc=T*r50ez|Wy?N@f`J-a0vZgg7cPsh|s{u#T@ z(Y}mrLUTA%pV@jAc=C>LaK5ag&Wa}ZxjYQMOQz-Djl~MVZ>Fv6@u6&}d(&vb7a;zuFu4*x#vthA#1~kDVYqyz4Pnt({Ol;(^CNAcHPtyD!@TFo}R;w}Ai8 z)})`k-?1g&VQLw*Z9r;R(|Bho1i@9kM3!)Xo#sY!LCFy-TGo05syg~Z*d1NudUGFX ztFG3z$D-WAsJsl@t`Nqqd{oeKXsJ-RUJswS6$VsPoA$o2C)7aGKf5Z}IXyb*+{QnP z^)~Fo%|b)O2LGbWeuB=U6#``1>?Yv^^iqLIpafdH$il2Uimj>d{%8cnZxHW(k=KQC z8mt&q99+ey8EzGI7?8$9(7=y^EKP7R8Gghl_6BD<6!23Z``t3N!St}3-Qr5NAV)IA z0LEp+iV+>XFwGI*c>n3Gdk4|OwrXw0Y9C_FO}&U`xXPpAZ~4+e1=ObSIxPVia!hSM z?PzD(h}_o1wk2S-!&=MsBEnMmOl~N~@huXG-k7kubxugV5i<{WWG+c|tBREEJITN> z)R$z5%qFWoth+z3)okA3v5wtH(p2W%^4FLoUbDN#!9YW^4q?>rzmQ(wi$q(ng z>9xpfe_)5va?uV%#KGSb55rz~f#Adp5!m19GIMRT9;qAH)Z)A%*gV14(ZPQdoq6$$ zi;&Tj2G5{R{ldG z3|sJJ05d5A#Jx$f&l4swmS1zU<^QV#QihQ_1{MeBeB$Tt6hU9?Nxy^M=-Xi)Duf36 z9BzNO7vRs;DlpyjGChN2%!fU!oEC5GsQWR>@|WiLJGQpnfqE)HxP2vHspQfF7>P}Z zMv}jf*J=`oX#VQPEZaDAk+o9-YG)7hL|2k;az&#s!G=Eaul--%um0^PRg%B|Uw+!3 zEN&3M>LEP~_y>xcwQf>Hy_#`}7XVuYkpYWjZbc4;orHUhc#Hfp2Yu;*anT%u0;?g> z!iI*|idoF(QG;ZZ#F!Vz?x3bc#Os;yBK{JF*61i4Px6bppz9(n7HXF%P?<#_>K?%_ z*?N#m{j_Or4y=oR{Sy|S?_2!)38Cc>ufyM#LNLZE8z34L(9I>xnjwl!xO$y0W_Ylr z?R_3%9%TG6Gk@8$d{JiXeF(t#uHFBSyS zB7Jhoad>GTYx7S_atIh#+&WE*ojryoZ}=GJv31EWA)ioO2~E{3Ifzb$%O6Xsl5@#p z$M?r0&pUKbz)17$U!K z7LKkXPcX2&1f#pYFZ4&>3lG?qlXcbXa?Sqp`ha@3WA#xsExG}Er9CEF7nU^v;=-m< zFu~KN9>JI}WmK>Ttdk<>B5hDawsgf+^=W~ER97^zFhrtBN^50U5Srli?_S48sH#r$ ziGVL?W_28kiPB~lQHFH;N#U_)W!4Ex2B}15g^XZ%3pOmARg9`lMW-_iD&#!P5b6|? zY$R0&$ZbO3qp~FT63Lcs$5_0!xVA~a=fOp)`_h)GXF8A0&yPt(W{t_#!=6hL3gXm< zeZ?rP2=Eco&=$`ghJy$q>KiT9H#hU|sTB8-vgraK+VZ=ZueJh4af$tP2$ zOV=5)`WeWjWzVekKw`Jurc9=0BTEA*>{=(Sj+GIWUf&>_wRKd1QuTbN`Q?fo=P;No zBH%>9khq;6mvOC6d?s{7Ty%OW)r!^3&Q6qoL@K?_%#`w;GicKD%1EN~{SLpNQl@H$ zfdI366C%}MZ$88Y1YK$Lpw6)nRD+hvnTUf3+|oR+Er=5GTVj|bGTh5HYa-k#Zo|`C z%OlweWvj3jE&F<)|2U@t`Ev6B literal 0 HcmV?d00001 diff --git a/Html/Main/Credit/credit.htm b/Html/Main/Credit/credit.htm index 569aa846f..e8104a5d5 100644 --- a/Html/Main/Credit/credit.htm +++ b/Html/Main/Credit/credit.htm @@ -359,5 +359,9 @@

Zlib

Adler

Jean-loup Gailly jloup@gzip.org

Mark Adler madler@alumni.caltech.edu

+

Font Awesome

+

Icons font

+

Fonticons, Inc. https://fontawesome.com

+

CC BY 4.0 License https://creativecommons.org/licenses/by/4.0/

- \ No newline at end of file + diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index f05b98815..9b5517020 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -7632,6 +7632,7 @@ inline VECTOR3 POINTERTOREF (VECTOR3 *p) // ImGui extras namespace ImGui { OAPIFUNC bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format = "%.3f"); + OAPIFUNC void HelpMarker(const char* desc, bool sameline = true); }; // ====================================================================== // Internal data structures diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index c2c8a24e3..8dce942cf 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -11,6 +11,7 @@ #include "Log.h" #include "imgui.h" #include "imgui_impl_win32.h" +#include "IconsFontAwesome6.h" using namespace oapi; @@ -446,13 +447,16 @@ void DialogManager::InitImGui() ImFontConfig config; + static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; ImFontConfig icons_config; icons_config.MergeMode = true; icons_config.PixelSnapH = true; icons_config.FontDataOwnedByAtlas = false; io.Fonts->AddFontFromFileTTF("Roboto-Medium.ttf", 14.0f, &config, GetGlyphRangesOrbiter()); + io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", 14.0f, &icons_config, icons_ranges); io.Fonts->Build(); + ImGui_ImplWin32_Init(hWnd); gc->clbkImGuiInit(); @@ -514,4 +518,19 @@ namespace ImGui { } return ret; } + + // From imgui_demo.cpp, with added sameline argument + DLLEXPORT void HelpMarker(const char* desc, bool sameline) + { + if(sameline) + ImGui::SameLine(); + ImGui::TextDisabled(ICON_FA_CIRCLE_QUESTION); + if (ImGui::BeginItemTooltip()) + { + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); + ImGui::TextUnformatted(desc); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + } } From 8a9cbb9df4fee561522add25ba8e535f4f5bdae0 Mon Sep 17 00:00:00 2001 From: Gondos Date: Sun, 26 Jan 2025 14:01:39 +0100 Subject: [PATCH 13/51] [ImGui]Example for style customisation --- Src/Orbiter/DlgMgr.cpp | 89 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index 8dce942cf..13004c0ef 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -425,10 +425,91 @@ const ImWchar* GetGlyphRangesOrbiter() return &ranges[0]; } -static void ImGuiSetStyle() +// Styling adapted from https://gist.github.com/dougbinks/8089b4bbaccaaf6fa204236978d165a9 +static void ImGuiSetStyle(bool bStyleDark_, float alpha_) { - // Setup Dear ImGui style - ImGui::StyleColorsClassic(); + // Setup Dear ImGui style + ImGui::StyleColorsClassic(); + + ImGuiStyle& style = ImGui::GetStyle(); + + style.Alpha = 1.0f; + style.FrameRounding = 3.0f; + style.WindowRounding = 3.0f; + style.ChildRounding = 3.0f; + style.PopupRounding = 3.0f; + style.ScrollbarRounding = 3.0f; + style.GrabRounding = 3.0f; + style.TabRounding = 3.0f; + // light style from Pacôme Danhiez (user itamago) https://github.com/ocornut/imgui/pull/511#issuecomment-175719267 + style.Colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + style.Colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 0.94f); + style.Colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f); + style.Colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.39f); + style.Colors[ImGuiCol_BorderShadow] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f); + style.Colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f); + style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + style.Colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f); + style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f); + style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f); + style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f); + style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f); + style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 1.00f); + style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.59f, 0.59f, 0.59f, 1.00f); + style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f); + style.Colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); + style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + style.Colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + style.Colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); + style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + style.Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.50f); + style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + style.Colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + + if( bStyleDark_ ) + { + for (int i = 0; i <= ImGuiCol_COUNT; i++) + { + ImVec4& col = style.Colors[i]; + float H, S, V; + ImGui::ColorConvertRGBtoHSV( col.x, col.y, col.z, H, S, V ); + + if( S < 0.1f ) + { + V = 1.0f - V; + } + ImGui::ColorConvertHSVtoRGB( H, S, V, col.x, col.y, col.z ); + if( col.w < 1.00f ) + { + col.w *= alpha_; + } + } + } + else + { + for (int i = 0; i <= ImGuiCol_COUNT; i++) + { + ImVec4& col = style.Colors[i]; + if( col.w < 1.00f ) + { + col.x *= alpha_; + col.y *= alpha_; + col.z *= alpha_; + col.w *= alpha_; + } + } + } } void DialogManager::InitImGui() @@ -443,7 +524,7 @@ void DialogManager::InitImGui() //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls //io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; - ImGuiSetStyle(); + ImGuiSetStyle(true, 1.0f); // Dark, alpha ImFontConfig config; From 52f1db90aba60eb7b9112d5a77363e21da6ae595 Mon Sep 17 00:00:00 2001 From: Gondos Date: Sun, 26 Jan 2025 17:49:02 +0100 Subject: [PATCH 14/51] [ImGui]Add font config option in Orbiter.cfg --- Src/Orbiter/Config.cpp | 10 +++++++++- Src/Orbiter/Config.h | 2 ++ Src/Orbiter/DlgMgr.cpp | 7 ++++--- Src/Orbiter/Orbiter.cfg.in | 4 ++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Src/Orbiter/Config.cpp b/Src/Orbiter/Config.cpp index e0f243ac2..83aeac230 100644 --- a/Src/Orbiter/Config.cpp +++ b/Src/Orbiter/Config.cpp @@ -227,7 +227,9 @@ CFG_DEMOPRM CfgDemoPrm_default = { CFG_FONTPRM CfgFontPrm_default = { 1.0f, // dlgFont_Scale (scaling factor for inline dialog fonts) - "Arial" // dlgFont1_Face (default dialog font face name) + "Arial", // dlgFont1_Face (default dialog font face name) + 14.0f, // ImGui_FontSize + "Roboto-Medium.ttf" // ImGui_FontFile }; CFG_CAMERAPRM CfgCameraPrm_default = { @@ -758,6 +760,8 @@ bool Config::Load(const char *fname) // font characteristics if (GetReal (ifs, "DialogFont_Scale", d)) CfgFontPrm.dlgFont_Scale = (float)d; GetString (ifs, "DialogFont1_Face", CfgFontPrm.dlgFont1_Face); + if (GetReal (ifs, "ImGui_FontSize", d)) CfgFontPrm.ImGui_FontSize = (float)d; + GetString (ifs, "ImGui_FontFile", CfgFontPrm.ImGui_FontFile); // misc. options if (GetString (ifs, "LPadRect", cbuf)) { @@ -1332,6 +1336,10 @@ BOOL Config::Write (const char *fname) const ofs << "DialogFont_Scale = " << CfgFontPrm.dlgFont_Scale << '\n'; if (strcmp (CfgFontPrm.dlgFont1_Face, CfgFontPrm_default.dlgFont1_Face) || bEchoAll) ofs << "DialogFont1_Face = " << CfgFontPrm.dlgFont1_Face << '\n'; + if (CfgFontPrm.ImGui_FontSize != CfgFontPrm_default.ImGui_FontSize || bEchoAll) + ofs << "ImGui_FontSize = " << CfgFontPrm.ImGui_FontSize << '\n'; + if (strcmp (CfgFontPrm.ImGui_FontFile, CfgFontPrm_default.ImGui_FontFile) || bEchoAll) + ofs << "ImGui_FontFile = " << CfgFontPrm.ImGui_FontFile << '\n'; } if (memcmp (&CfgWindowPos, &CfgWindowPos_default, sizeof(CFG_WINDOWPOS)) || bEchoAll) { diff --git a/Src/Orbiter/Config.h b/Src/Orbiter/Config.h index c41db2263..7927f63ab 100644 --- a/Src/Orbiter/Config.h +++ b/Src/Orbiter/Config.h @@ -253,6 +253,8 @@ struct CFG_DEMOPRM { struct CFG_FONTPRM { float dlgFont_Scale; // font scaling factor char dlgFont1_Face[64]; // dialog font face name + float ImGui_FontSize; // Font size for ImGui dialogs + char ImGui_FontFile[256]; // Font file for ImGui default font }; struct CFG_CAMERAPRM { diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index 13004c0ef..075fc52d5 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -533,9 +533,10 @@ void DialogManager::InitImGui() icons_config.MergeMode = true; icons_config.PixelSnapH = true; icons_config.FontDataOwnedByAtlas = false; - - io.Fonts->AddFontFromFileTTF("Roboto-Medium.ttf", 14.0f, &config, GetGlyphRangesOrbiter()); - io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", 14.0f, &icons_config, icons_ranges); + + const CFG_FONTPRM &prm = g_pOrbiter->Cfg()->CfgFontPrm; + io.Fonts->AddFontFromFileTTF(prm.ImGui_FontFile, prm.ImGui_FontSize, &config, ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, &icons_config, icons_ranges); io.Fonts->Build(); diff --git a/Src/Orbiter/Orbiter.cfg.in b/Src/Orbiter/Orbiter.cfg.in index c2fa0a009..d75343db8 100644 --- a/Src/Orbiter/Orbiter.cfg.in +++ b/Src/Orbiter/Orbiter.cfg.in @@ -3,3 +3,7 @@ EchoAllParams = FALSE ; === Subdirectory locations PlanetTexDir = ${ORBITER_PLANET_TEXTURE_INSTALL_DIR_W} + +; === Font parameters === +ImGui_FontFile = Roboto-Medium.ttf +ImGui_FontSize = 14 From 0b9d9abcd80201ebd31e0313be591814e0f6812d Mon Sep 17 00:00:00 2001 From: Gondos Date: Sun, 26 Jan 2025 18:15:18 +0100 Subject: [PATCH 15/51] [ImGui]Don't show dialogs on the 'Current State' scenario preview --- Src/Orbiter/Orbiter.cpp | 14 ++++++++++---- Src/Orbiter/Orbiter.h | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 01508cf79..110cfe0bd 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -857,8 +857,12 @@ void Orbiter::PreCloseSession() // DEBUG if (pDlgMgr) { pDlgMgr->Clear(); } - if (gclient && pConfig->CfgDebugPrm.bSaveExitScreen) + if (gclient && pConfig->CfgDebugPrm.bSaveExitScreen) { + // Render the scene once without the ImGui dialogs shown + // so they don't appear on the preview + Render3DEnvironment(true); gclient->clbkSaveSurfaceToImage (0, "Images\\CurrentState", oapi::IMAGE_JPG); + } } //----------------------------------------------------------------------------- @@ -975,13 +979,15 @@ void Orbiter::BroadcastGlobalInit () // Render3DEnvironment() // Draws the scene -HRESULT Orbiter::Render3DEnvironment () +HRESULT Orbiter::Render3DEnvironment (bool hidedialogs) { if (gclient) { - pDlgMgr->ImGuiNewFrame(); + if(!hidedialogs) + pDlgMgr->ImGuiNewFrame(); gclient->clbkRenderScene (); Output2DData (); - gclient->clbkImGuiRenderDrawData(); + if(!hidedialogs) + gclient->clbkImGuiRenderDrawData(); gclient->clbkDisplayFrame (); } return S_OK; diff --git a/Src/Orbiter/Orbiter.h b/Src/Orbiter/Orbiter.h index 8bffadca8..e85b62a25 100644 --- a/Src/Orbiter/Orbiter.h +++ b/Src/Orbiter/Orbiter.h @@ -62,7 +62,7 @@ class Orbiter { bool InitializeWorld (char *name); void ScreenToClient (POINT *pt) const; LRESULT MsgProc (HWND, UINT, WPARAM, LPARAM); - HRESULT Render3DEnvironment(); + HRESULT Render3DEnvironment(bool hidedialogs = false); VOID Output2DData (); void OutputLoadStatus (const char *msg, int line); void OutputLoadTick (int line, bool ok = true); From d277895a67354e36d390e0c17a42dd6a9540851a Mon Sep 17 00:00:00 2001 From: Gondos Date: Tue, 28 Jan 2025 00:32:12 +0100 Subject: [PATCH 16/51] [ImGui]Add support for notifications --- Orbitersdk/include/OrbiterAPI.h | 23 ++ Src/Module/LuaScript/LuaInline/LuaInline.cpp | 8 - .../LuaScript/LuaInterpreter/Interpreter.cpp | 32 ++- .../LuaScript/LuaInterpreter/Interpreter.h | 3 +- Src/Module/LuaScript/LuaInterpreter/types.lua | 7 + Src/Orbiter/DlgMgr.cpp | 245 +++++++++++++++++- Src/Orbiter/Orbiter.cpp | 5 +- Src/Plugin/ScriptMFD/ScriptMFD.cpp | 6 +- Src/Vessel/ScriptVessel/ScriptVessel.cpp | 6 +- 9 files changed, 312 insertions(+), 23 deletions(-) diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 9b5517020..42a7fa541 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -355,6 +355,20 @@ typedef struct { #define OAPISURFACE_SHARED 0x1000 ///< Create a shared resource //@} + +/** + * \ingroup defines + * \defgroup notification Notification type + * These constants specified the type of notification to display. + * \sa oapiAddNotification + */ +//@{ +#define OAPINOTIF_SUCCESS 0 ///< Success +#define OAPINOTIF_WARNING 1 ///< Warning +#define OAPINOTIF_ERROR 2 ///< Error +#define OAPINOTIF_INFO 3 ///< Info +//@} + /** * \ingroup defines * \defgroup grpedit Mesh group editing flags @@ -6123,6 +6137,15 @@ OAPIFUNC void oapiCloseDialog (HWND hDlg); */ OAPIFUNC void oapiCloseDialog (ImGuiDialog *dlg); + /** + * \brief Show a notification. + * \param type Type of notification + * \param title One liner title of the notification + * \param content Content of the notification (possibly multiline) + * \note title and content are copied and can be safely overwritten/freed after the call + */ +OAPIFUNC void oapiAddNotification(int type, const char *title, const char *content = ""); + /** * \brief Retrieves the context pointer of a dialog box which has been defined during the call to oapiOpenDialog(). * \param hDlg dialog window handle diff --git a/Src/Module/LuaScript/LuaInline/LuaInline.cpp b/Src/Module/LuaScript/LuaInline/LuaInline.cpp index 4f3e6ee67..f30eac185 100644 --- a/Src/Module/LuaScript/LuaInline/LuaInline.cpp +++ b/Src/Module/LuaScript/LuaInline/LuaInline.cpp @@ -29,7 +29,6 @@ // ============================================================== // class InterpreterList::Environment: implementation -static NOTEHANDLE errorbox; InterpreterList::Environment::Environment() { @@ -37,7 +36,6 @@ InterpreterList::Environment::Environment() singleCmd = false; hThread = NULL; interp = CreateInterpreter (); - interp->SetErrorBox(errorbox); } InterpreterList::Environment::~Environment() @@ -108,17 +106,11 @@ InterpreterList::~InterpreterList () void InterpreterList::clbkSimulationStart (RenderMode mode) { - errorbox = ::oapiCreateAnnotation(false, 1, _V(1.0,0,0)); - ::oapiAnnotationSetPos (errorbox, 0, 0.75, 1, 1); - - for (int i = 0; i < nlist; i++) // prune all finished interpreters - list[i]->interp->SetErrorBox(errorbox); } void InterpreterList::clbkSimulationEnd () { while (nlist) DelInterpreter(list[0]); - oapiDelAnnotation(errorbox); } void InterpreterList::clbkPostStep (double simt, double simdt, double mjd) diff --git a/Src/Module/LuaScript/LuaInterpreter/Interpreter.cpp b/Src/Module/LuaScript/LuaInterpreter/Interpreter.cpp index eadc56ec1..b8d17b470 100644 --- a/Src/Module/LuaScript/LuaInterpreter/Interpreter.cpp +++ b/Src/Module/LuaScript/LuaInterpreter/Interpreter.cpp @@ -96,7 +96,7 @@ int Interpreter::LuaCall(lua_State *L, int narg, int nres) lua_remove(L, base); if(res != 0) { oapiWriteLogError("%s", lua_tostring(L, -1)); - oapiAnnotationSetText(errorbox, const_cast(lua_tostring(L, -1))); + oapiAddNotification(OAPINOTIF_ERROR, "Lua error", lua_tostring(L, -1)); } return res; } @@ -806,6 +806,7 @@ void Interpreter::LoadAPI () {"open_inputbox", oapiOpenInputBox}, {"receive_input", oapiReceiveInput}, {"open_inputboxex", oapi_open_inputboxex}, + {"add_notification", oapi_add_notification}, {"del_vessel", oapi_del_vessel}, {"create_vessel", oapi_create_vessel}, {"set_focusobject", oapi_set_focusobject}, @@ -1344,6 +1345,13 @@ void Interpreter::LoadAPI () lua_createtable (L, 0, 1); lua_pushnumber (L, MESHPROPERTY_MODULATEMATALPHA); lua_setfield (L, -2, "MODULATEMATALPHA"); lua_setglobal (L, "MESHPROPERTY"); + + lua_createtable (L, 0, 4); + lua_pushnumber (L, OAPINOTIF_SUCCESS); lua_setfield (L, -2, "SUCCESS"); + lua_pushnumber (L, OAPINOTIF_WARNING); lua_setfield (L, -2, "WARNING"); + lua_pushnumber (L, OAPINOTIF_ERROR); lua_setfield (L, -2, "ERROR"); + lua_pushnumber (L, OAPINOTIF_INFO); lua_setfield (L, -2, "INFO"); + lua_setglobal (L, "OAPINOTIF"); } void Interpreter::LoadMFDAPI () @@ -4019,6 +4027,28 @@ int Interpreter::oapi_open_inputboxex (lua_State *L) return 0; } +/*** +Display a notification on the screen + +Error notifications are persistant and must be acknowledged + +@function add_notification +@tparam number type Notification type (see table OAPINOTIF) +@tparam string title Notification title +@tparam[opt=""] string content Notification content +*/ +int Interpreter::oapi_add_notification (lua_State *L) +{ + int type = luaL_checkinteger(L, 1); + const char *title = luaL_checkstring(L, 2); + const char *content = ""; + if(lua_gettop (L) >= 3) { + content = luaL_checkstring(L, 3); + } + oapiAddNotification(type, title, content); + return 0; +} + /*** Return the equatorial coordinates with respect to an object of a point given in the global reference frame. diff --git a/Src/Module/LuaScript/LuaInterpreter/Interpreter.h b/Src/Module/LuaScript/LuaInterpreter/Interpreter.h index d9c199db7..f780f4417 100644 --- a/Src/Module/LuaScript/LuaInterpreter/Interpreter.h +++ b/Src/Module/LuaScript/LuaInterpreter/Interpreter.h @@ -234,10 +234,8 @@ class INTERPRETERLIB Interpreter { void term_setverbosity (int level) { term_verbose = level; } static int LuaCall(lua_State *L, int nargs, int nres); - void SetErrorBox(NOTEHANDLE eb) { errorbox = eb; } static void DeleteVessel (OBJHANDLE hVessel); protected: - static inline NOTEHANDLE errorbox; lua_State *L; // Lua main context /** @@ -403,6 +401,7 @@ class INTERPRETERLIB Interpreter { static int oapiOpenInputBox (lua_State *L); static int oapiReceiveInput (lua_State *L); static int oapi_open_inputboxex (lua_State *L); + static int oapi_add_notification (lua_State *L); static int oapi_global_to_equ(lua_State* L); static int oapi_global_to_local(lua_State* L); static int oapi_local_to_equ(lua_State* L); diff --git a/Src/Module/LuaScript/LuaInterpreter/types.lua b/Src/Module/LuaScript/LuaInterpreter/types.lua index 317332e5e..cf3745246 100644 --- a/Src/Module/LuaScript/LuaInterpreter/types.lua +++ b/Src/Module/LuaScript/LuaInterpreter/types.lua @@ -295,6 +295,13 @@ -- @field NOISE Enable/Setup Noise generation -- @table PRM +--- Notification types +-- @field NOTIF_SUCCESS +-- @field NOTIF_WARNING +-- @field NOTIF_ERROR +-- @field NOTIF_INFO +-- @table OAPINOTIF + --- PlaybackType. -- -- Determines how a given sound will be played back (i.e., where it will be audible) diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index 075fc52d5..10e0e0552 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -12,6 +12,10 @@ #include "imgui.h" #include "imgui_impl_win32.h" #include "IconsFontAwesome6.h" +#include +#include +#include +#include using namespace oapi; @@ -24,6 +28,7 @@ static int x_fixedframe = GetSystemMetrics (SM_CXFIXEDFRAME); static int y_fixedframe = GetSystemMetrics (SM_CYFIXEDFRAME); static bool doflip = true; +void RenderNotifications(); // dialog thread messages #define TM_OPENDIALOG WM_USER @@ -430,7 +435,6 @@ static void ImGuiSetStyle(bool bStyleDark_, float alpha_) { // Setup Dear ImGui style ImGui::StyleColorsClassic(); - ImGuiStyle& style = ImGui::GetStyle(); style.Alpha = 1.0f; @@ -441,6 +445,7 @@ static void ImGuiSetStyle(bool bStyleDark_, float alpha_) style.ScrollbarRounding = 3.0f; style.GrabRounding = 3.0f; style.TabRounding = 3.0f; + // light style from Pacôme Danhiez (user itamago) https://github.com/ocornut/imgui/pull/511#issuecomment-175719267 style.Colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); @@ -558,6 +563,13 @@ void DialogManager::ImGuiNewFrame() ImGui::NewFrame(); //ImGui::ShowDemoWindow(); + + // Render notifications + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.f); // Round borders + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(43.f / 255.f, 43.f / 255.f, 43.f / 255.f, 240.f / 255.f)); // Background color + RenderNotifications(); // <-- Here we render all notifications + ImGui::PopStyleVar(1); // Don't forget to Pop() + ImGui::PopStyleColor(1); // We can't use a range-based loop here because Show() may unregister the current dialog for (auto it = DlgImGuiList.begin(); it != DlgImGuiList.end();) @@ -583,6 +595,237 @@ void ImGuiDialog::Display() { if (!active) OnClose(); } +/* +Notification handling, borrowed heavily from https://github.com/patrickcjk/imgui-notify +Added: +- permanent discardable notifications +- copy text to clipboard (permanent notifications) +- deduplication +- fall animation +- limit notification box to the main viewport + +MIT License + +Copyright (c) 2021 Patrick + +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. +*/ + +using namespace std::chrono_literals; +using duration_t = std::chrono::duration; +using time_point_t = std::chrono::time_point; + +const float NOTIFY_PADDING_X = 20.f; // Bottom-left X padding +const float NOTIFY_PADDING_Y = 20.f; // Bottom-left Y padding +const float NOTIFY_PADDING_MESSAGE_Y = 10.f; // Padding Y between each message +const uint32_t NOTIFICATION_FLAGS = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing; +const duration_t FADE_TIME = 0.5s; +static const ImVec4 notifcolors[4] = { + { 0, 255, 0, 255 }, // Success + { 255, 255, 0, 255 }, // Warning + { 255, 0, 0, 255 }, // Error + { 0, 157, 255, 255 } // Info +}; + +static const char *notificons[4] = { + ICON_FA_CIRCLE_CHECK, // Success + ICON_FA_TRIANGLE_EXCLAMATION, // Warning + ICON_FA_CIRCLE_EXCLAMATION, // Error + ICON_FA_CIRCLE_INFO // Info +}; + +static duration_t notifduration[4] = { + 3.0s, // Success + 10.0s, // Warning + 86400.0s, // Error - basically permanent and needs to be acknowledged + 7.0s // Info +}; + + +struct Notification +{ + uint32_t occurrences; + std::string title; + std::string content; + size_t hash; + ImVec4 color; + bool expired = false; + bool permanent = false; + const char *icon; + duration_t duration; + time_point_t creation; + float height; + float speed; + + Notification(uint32_t type, const char *title_, const char *content_, size_t hash_):title(title_),content(content_),hash(hash_) + { + if(type >= OAPINOTIF_INFO) type = OAPINOTIF_INFO; + color = notifcolors[type]; + icon = notificons[type]; + duration = notifduration[type]; + creation = std::chrono::steady_clock::now(); + occurrences = 1; + expired = false; + permanent = type == OAPINOTIF_ERROR; + speed = 1.0f; + height = -1.0; + } + void ReTrigger() { + occurrences++; + creation = std::chrono::steady_clock::now() - FADE_TIME; + } + void UpdateState(time_point_t now, float h, duration_t dt) { + duration_t elapsed = now - creation; + // Update alpha/expiration base on elapsed time + if(elapsed > FADE_TIME + duration + FADE_TIME) { // expired + color.w = 0.0f; + expired = true; + } else if(elapsed < FADE_TIME) { // appearing + color.w = elapsed / FADE_TIME; + } else if(elapsed > FADE_TIME + duration) { // disappearing + color.w = 1.0f - (elapsed - FADE_TIME - duration) / FADE_TIME; + } else { // steady + color.w = 1.0; + } + + if(h < height) { + height -= speed; + speed += std::chrono::duration_cast(dt).count() * 0.001; + if(height <= h) { + height = h; + speed = 0.0f; + } + } else { + height = h; + speed = 0.0f; + } + } +}; + +static std::vector notifications; + +static void RenderNotifications() +{ + ImVec2 vp_size = ImGui::GetMainViewport()->Size; + vp_size.x += ImGui::GetMainViewport()->Pos.x; + vp_size.y += ImGui::GetMainViewport()->Pos.y; + float height = 0.0f; + + int i = 0; + static time_point_t last = std::chrono::steady_clock::now(); + auto now = std::chrono::steady_clock::now(); + duration_t dt = now - last; + for (auto ¬if: notifications) + { + notif.UpdateState(now, height, dt); + + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, notif.color.w); + ImGui::SetNextWindowPos(ImVec2(vp_size.x - NOTIFY_PADDING_X, vp_size.y - NOTIFY_PADDING_Y - notif.height), ImGuiCond_Always, ImVec2(1.0f, 1.0f)); + + // Generate new unique name for this toast + char window_name[32]; + sprintf(window_name, "##NOTIF%d", i); + i++; + ImGuiWindowFlags wf = NOTIFICATION_FLAGS; + if(notif.permanent) { + wf &= ~ImGuiWindowFlags_NoInputs; + } + + // Prevent the notification from spawning outside the main window + ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID); + ImGui::Begin(window_name, NULL, wf); + + ImGui::PushTextWrapPos(vp_size.x / 2.0f); + + ImGui::PushStyleColor(ImGuiCol_Text, notif.color); + ImGui::TextUnformatted(notif.icon); + ImGui::PopStyleColor(); + + ImGui::SameLine(); + if(notif.occurrences > 1) { + ImGui::Text("%s (x%d)", notif.title.c_str(), notif.occurrences); + } else { + ImGui::TextUnformatted(notif.title.c_str()); + } + + if(notif.permanent) + { + ImGui::SameLine(); + if (ImGui::SmallButton(ICON_FA_XMARK)) + { + // Change duration so that the notification will expire right now; + notif.duration = now - notif.creation - FADE_TIME; + } + } + + // In case ANYTHING was rendered in the top, we want to add a small padding so the text (or icon) looks centered vertically + if (!notif.content.empty()) + { + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5.0f); // Must be a better way to do this!!!! + ImGui::Separator(); + ImGui::TextUnformatted(notif.content.c_str()); // Render content text + + // Allow copying error messages to the clipboard + if(notif.permanent) { + char popup_name[32]; + sprintf(popup_name, "##POPUP%d", i); + + if (ImGui::BeginPopupContextItem(popup_name)) + { + if (ImGui::MenuItem("Copy")) { + ImGui::SetClipboardText(notif.content.c_str()); + } + ImGui::EndPopup(); + } + } + } + + ImGui::PopTextWrapPos(); + + ImGui::PopStyleVar(); + // Save height for next notification + height += ImGui::GetWindowHeight() + NOTIFY_PADDING_MESSAGE_Y; + + // End + ImGui::End(); + } + // Remove expired notifications + notifications.erase(std::remove_if(notifications.begin(), notifications.end(), + [=](auto ¬if){return notif.expired;}), + notifications.end()); + +} + + +// OAPI implementation +DLLEXPORT void oapiAddNotification(int type, const char *title, const char *content) { + const size_t hash = std::hash{}(title) ^ std::hash{}(content); + for (auto ¬if: notifications) { + if(notif.hash == hash && notif.title == title && notif.content == content) { + notif.ReTrigger(); + return; + } + } + notifications.emplace_back(type, title, content, hash); +} + + // ImGui utils namespace ImGui { // Resettable slider from https://github.com/ocornut/imgui/issues/1751 diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 110cfe0bd..8a4563711 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -1485,7 +1485,10 @@ VOID Orbiter::Quicksave () for (i = strlen(ScenarioName)-1; i > 0; i--) if (ScenarioName[i-1] == '\\') break; sprintf (fname, "Quicksave\\%s %04d", ScenarioName+i, ++g_qsaveid); - SaveScenario (fname, desc, 0); + if(SaveScenario (fname, desc, 0)) + oapiAddNotification(OAPINOTIF_SUCCESS, "Scenario saved successfully", fname); + else + oapiAddNotification(OAPINOTIF_ERROR, "Failed to save scenario", fname); } //----------------------------------------------------------------------------- diff --git a/Src/Plugin/ScriptMFD/ScriptMFD.cpp b/Src/Plugin/ScriptMFD/ScriptMFD.cpp index 8602964b3..9e844cd6b 100644 --- a/Src/Plugin/ScriptMFD/ScriptMFD.cpp +++ b/Src/Plugin/ScriptMFD/ScriptMFD.cpp @@ -29,7 +29,6 @@ int g_MFDmode; // identifier for new MFD mode SCRIPTMFDMODESPEC *modespec; int nmode = 0; -static NOTEHANDLE errorbox; struct VINTERP { // list of vessel-based interpreters INTERPRETERHANDLE hInterp; @@ -73,7 +72,7 @@ int LuaCall(lua_State *L, int narg, int nres) lua_remove(L, base); if(res != 0) { oapiWriteLogError("%s", lua_tostring(L, -1)); - oapiAnnotationSetText(errorbox, const_cast(lua_tostring(L, -1))); + oapiAddNotification(OAPINOTIF_ERROR, "Lua MFD error", lua_tostring(L, -1)); } return res; } @@ -140,13 +139,10 @@ DLLCLBK void ExitModule (HINSTANCE hDLL) DLLCLBK void opcOpenRenderViewport(HWND,DWORD,DWORD,BOOL) { - errorbox = ::oapiCreateAnnotation(false, 1, _V(1.0,0,0)); - ::oapiAnnotationSetPos (errorbox, 0, 0.75, 1, 1); } DLLCLBK void opcCloseRenderViewport () { - oapiDelAnnotation(errorbox); ClearVinterpList(); } diff --git a/Src/Vessel/ScriptVessel/ScriptVessel.cpp b/Src/Vessel/ScriptVessel/ScriptVessel.cpp index 4bc426cca..67a770dab 100644 --- a/Src/Vessel/ScriptVessel/ScriptVessel.cpp +++ b/Src/Vessel/ScriptVessel/ScriptVessel.cpp @@ -96,16 +96,12 @@ const char *CLBKNAME[NCLBK] = { "getradiationforce" }; -static NOTEHANDLE errorbox; DLLCLBK void InitModule (HINSTANCE hDLL) { - errorbox = ::oapiCreateAnnotation(false, 1, _V(1.0,0,0)); - ::oapiAnnotationSetPos (errorbox, 0, 0.75, 1, 1); } DLLCLBK void ExitModule (HINSTANCE hDLL) { - oapiDelAnnotation(errorbox); } static VECTOR3 lua_tovector(lua_State* L, int idx) @@ -260,7 +256,7 @@ int ScriptVessel::LuaCall(lua_State *L, int narg, int nres) lua_remove(L, base); if(res != 0) { oapiWriteLogError("%s", lua_tostring(L, -1)); - oapiAnnotationSetText(errorbox, const_cast(lua_tostring(L, -1))); + oapiAddNotification(OAPINOTIF_ERROR, "Lua vessel error", lua_tostring(L, -1)); } return res; } From 25aa2f4ea26d1f315d0650a78310fd9a832e8c07 Mon Sep 17 00:00:00 2001 From: Gondos Date: Fri, 31 Jan 2025 00:45:18 +0100 Subject: [PATCH 17/51] [ImGui]Convert DlgCamera --- OVP/D3D9Client/DebugControls.cpp | 1 + Orbitersdk/include/OrbiterAPI.h | 15 +- Orbitersdk/include/imgui_extras.h | 11 + Src/Orbiter/DlgCamera.cpp | 1543 ++++++++--------------------- Src/Orbiter/DlgCamera.h | 173 +--- Src/Orbiter/DlgMgr.cpp | 101 +- 6 files changed, 532 insertions(+), 1312 deletions(-) create mode 100644 Orbitersdk/include/imgui_extras.h diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 2802ceff1..828323d06 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -19,6 +19,7 @@ #include "VectorHelpers.h" #include #include +#include enum scale { LIN, SQRT, SQR }; diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 42a7fa541..378627f66 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -672,14 +672,17 @@ typedef struct { * \brief Base class for defining an ImGui dialog. */ class OAPIFUNC ImGuiDialog { - const std::string name; + struct ImGuiDefaultSize { + float width; + float height; + }; public: /** * \brief Create an ImGui dialog object. * \param name Name of the dialog window * \note This class must by derived from in order to define a custom ImGui dialog */ - ImGuiDialog(const char *n):name(n) {} + ImGuiDialog(const char *n, ImGuiDefaultSize ds = {350.0,280.0}):name(n),defaultSize(ds) {} virtual ~ImGuiDialog(); bool IsActive() { return active; } void Activate() { active = true; } @@ -698,6 +701,9 @@ class OAPIFUNC ImGuiDialog { */ virtual void OnDraw() = 0; bool active = false; +private: + const std::string name; + ImGuiDefaultSize defaultSize; }; /** @@ -7652,11 +7658,6 @@ inline VECTOR3 POINTERTOREF (VECTOR3 *p) return v; } -// ImGui extras -namespace ImGui { - OAPIFUNC bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format = "%.3f"); - OAPIFUNC void HelpMarker(const char* desc, bool sameline = true); -}; // ====================================================================== // Internal data structures // ====================================================================== diff --git a/Orbitersdk/include/imgui_extras.h b/Orbitersdk/include/imgui_extras.h new file mode 100644 index 000000000..6ce7bbff5 --- /dev/null +++ b/Orbitersdk/include/imgui_extras.h @@ -0,0 +1,11 @@ +#pragma once + +#include "imgui.h" + +// ImGui extras +namespace ImGui { + OAPIFUNC bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format = "%.3f"); + OAPIFUNC void HelpMarker(const char* desc, bool sameline = true); + OAPIFUNC void BeginGroupPanel(const char* name, const ImVec2& size = ImVec2(-1.0f, -1.0f)); + OAPIFUNC void EndGroupPanel(); +}; diff --git a/Src/Orbiter/DlgCamera.cpp b/Src/Orbiter/DlgCamera.cpp index dec3b3d46..4efa3226a 100644 --- a/Src/Orbiter/DlgCamera.cpp +++ b/Src/Orbiter/DlgCamera.cpp @@ -1,1204 +1,437 @@ -// Copyright (c) Martin Schweiger -// Licensed under the MIT License - -// ====================================================================== -// Camera configuration dialog -// ====================================================================== - -#define STRICT 1 - #include "DlgCamera.h" -#include "DlgMgr.h" -#include "Resource.h" -#include "Resource2.h" +#include "OrbiterAPI.h" #include "Orbiter.h" +#include "Celbody.h" #include "Psys.h" -#include "Camera.h" -#include "Uxtheme.h" -#include "DlgCtrl.h" +#include "imgui.h" +#include "imgui_extras.h" -using std::min; -using std::max; - -extern Orbiter *g_pOrbiter; extern PlanetarySystem *g_psys; extern Camera *g_camera; -extern Vessel *g_focusobj; extern TimeData td; -extern HELPCONTEXT DefHelpContext; - -// ====================================================================== - -DlgCamera::DlgCamera (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_CAMERA, 0, 0, context) -{ - nTab = 0; - hcontext = 0; - pos = &g_pOrbiter->Cfg()->CfgWindowPos.DlgCamera; -} - -// ====================================================================== - -DlgCamera::~DlgCamera () -{ - Clear (); -} - -// ====================================================================== - -void DlgCamera::Update () -{ - for (int i = 0; i < nTab; i++) - pTab[i]->Update (); -} - -// ====================================================================== - -void DlgCamera::ModeChanged () -{ - pTabControl->ModeChanged (); -} - -// ====================================================================== - -void DlgCamera::FovChanged (double fov) -{ - pTabFov->FovChanged (fov); -} - -// ====================================================================== - -void DlgCamera::GObserverChanged (const char *str) -{ - pTabGround->GObserverChanged (str); -} - -// ====================================================================== - -void DlgCamera::Refresh (const Camera *cam) -{ - pTabGround->LockChanged (cam->GroundObserver_TargetLock()); - //pTabFov->FovChanged (cam->Aperture() * 2.0*DEG); -} - -// ====================================================================== - -BOOL DlgCamera::OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam) -{ - HWND hTabFrame = hDlg; - - AddTab (hDlg, pTabControl = new TabControl (hTabFrame), "Control"); - AddTab (hDlg, new TabTarget (hTabFrame), "Target"); - AddTab (hDlg, new TabView (hTabFrame), "Track"); - AddTab (hDlg, pTabGround = new TabGround (hTabFrame), "Ground"); - AddTab (hDlg, pTabFov = new TabFov (hTabFrame), "FoV"); - AddTab (hDlg, new TabPreset (hTabFrame), "Preset"); - - SwitchTab (hDlg); - return TRUE; -} - -// ====================================================================== - -BOOL DlgCamera::OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl) -{ - switch (id) { - case IDHELP: - DefHelpContext.topic = HelpContext (); - g_pOrbiter->OpenHelp (&DefHelpContext); - return TRUE; - } - return DialogWin::OnCommand (hDlg, id, code, hControl); -} - -// ====================================================================== - -BOOL DlgCamera::OnNotify (HWND hDlg, int idCtrl, LPNMHDR pnmh) -{ - if (pnmh->idFrom == IDC_CAM_TAB) { - if (pnmh->code == TCN_SELCHANGE) SwitchTab (hDlg); - return TRUE; - } - return MSG_DEFAULT; -} - -// ====================================================================== - -BOOL DlgCamera::OnApp (HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - switch (LOWORD (wParam)) { - case 0: // FOV change notification - FovChanged (2.0*DEG * *(double*)lParam); - return TRUE; - case 1: // Ground observer position changed - GObserverChanged ((const char*)lParam); - return TRUE; - case 2: // Ground camera target lock mode changed - Refresh ((const Camera*)lParam); - return TRUE; - case 3: // Camera mode changed - ModeChanged (); - return TRUE; - } - return FALSE; -} - -// ====================================================================== - -void DlgCamera::Clear () -{ - if (nTab) { - for (int i = 0; i < nTab; i++) - delete pTab[i]; - delete []pTab; - pTab = NULL; - nTab = 0; - } -} - -// ====================================================================== - -int DlgCamera::AddTab (HWND hDlg, CameraTab *tab, const char *label) -{ - char cbuf[256]; - strcpy (cbuf, label); - TC_ITEM tie; - tie.mask = TCIF_TEXT; - tie.iImage = -1; - tie.pszText = cbuf; - SendDlgItemMessage (hDlg, IDC_CAM_TAB, TCM_INSERTITEM, nTab, (LPARAM)&tie); - - CameraTab **tmp = new CameraTab*[nTab+1]; - if (nTab) { - memcpy (tmp, pTab, nTab*sizeof(CameraTab*)); - delete []pTab; - } - pTab = tmp; - pTab[nTab] = tab; - return nTab++; -} - -// ====================================================================== - -void DlgCamera::SwitchTab (HWND hDlg) -{ - int pg, cpg = TabCtrl_GetCurSel (GetDlgItem (hDlg, IDC_CAM_TAB)); - for (pg = 0; pg < nTab; pg++) - if (pg != cpg) pTab[pg]->Show (false); - pTab[cpg]->Show (true); - hcontext = pTab[cpg]->HelpContext(); -} - -// ====================================================================== -// ====================================================================== - -CameraTab::CameraTab (HWND hParentTab, int dlgId, DLGPROC dlgProc) -{ - active = false; - hParent = hParentTab; - hTab = CreateDialogParam (g_pOrbiter->GetInstance(), MAKEINTRESOURCE(dlgId), hParentTab, dlgProc, (LPARAM)this); -} - -// ====================================================================== - -CameraTab::~CameraTab () -{ - DestroyWindow (hTab); -} - -// ====================================================================== - -void CameraTab::Show (bool show) -{ - ShowWindow (hTab, show ? SW_SHOW : SW_HIDE); - active = show; -} - -// ====================================================================== - -INT_PTR CALLBACK CameraTab::DlgProcInit (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_INITDIALOG: - EnableThemeDialogTexture (hWnd, ETDT_ENABLETAB); - SetWindowLongPtr (hWnd, DWLP_USER, lParam); - return TRUE; - } - return FALSE; -} - - -// ====================================================================== -// ====================================================================== - -TabControl::TabControl (HWND hParentTab): CameraTab (hParentTab, IDD_CAM_PG_CONTROL, DlgProc) -{ -} - -// ====================================================================== - -char *TabControl::HelpContext () const -{ - return (char*)"/cam_control.htm"; -} - -// ====================================================================== - -BOOL TabControl::Init (HWND hWnd) -{ - HICON hIcon; - HINSTANCE hInst = g_pOrbiter->GetInstance (); - hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_LARROW)); - SendDlgItemMessage (hWnd, IDC_CAM_CTRL_ROTL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_RARROW)); - SendDlgItemMessage (hWnd, IDC_CAM_CTRL_ROTR, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_UARROW)); - SendDlgItemMessage (hWnd, IDC_CAM_CTRL_ROTU, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - SendDlgItemMessage (hWnd, IDC_CAM_CTRL_MOVEU, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_DARROW)); - SendDlgItemMessage (hWnd, IDC_CAM_CTRL_ROTD, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - SendDlgItemMessage (hWnd, IDC_CAM_CTRL_MOVED, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_UARROW_TILT)); - SendDlgItemMessage (hWnd, IDC_CAM_CTRL_MOVEIN, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_DARROW_TILT)); - SendDlgItemMessage (hWnd, IDC_CAM_CTRL_MOVEOUT, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_LARROW_TILT)); - SendDlgItemMessage (hWnd, IDC_CAM_CTRL_MOVEL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_RARROW_TILT)); - SendDlgItemMessage (hWnd, IDC_CAM_CTRL_MOVER, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - - GAUGEPARAM gp = { 0, 60, GAUGEPARAM::LEFT, GAUGEPARAM::BLACK }; - oapiSetGaugeParams (GetDlgItem (hWnd, IDC_CAM_CTRL_SENSITIVITY), &gp, true); - int pos = max (0, min (100, (int)((log10 (g_camera->GroundObserver_PanSpeed())+1.0)*10.0))); - oapiSetGaugePos (GetDlgItem (hWnd, IDC_CAM_CTRL_SENSITIVITY), pos); - - return TRUE; -} - -// ====================================================================== - -void TabControl::Show (bool show) -{ - CameraTab::Show (show); - if (show) { - GetCamMode (); - SetLayout (); - } -} - -// ====================================================================== - -void TabControl::Update () -{ - double dt = td.SysDT; +extern Orbiter *g_pOrbiter; +extern Vessel *g_focusobj; - // Get press status of control buttons - if (SendDlgItemMessage (hTab, IDC_CAM_CTRL_ROTL, BM_GETSTATE, 0, 0) & BST_PUSHED) { - if (rot_is_tilt) g_camera->Rotate ( dt, 0); - else g_camera->ShiftPhi (-dt); - } - else if (SendDlgItemMessage (hTab, IDC_CAM_CTRL_ROTR, BM_GETSTATE, 0, 0) & BST_PUSHED) { - if (rot_is_tilt) g_camera->Rotate (-dt, 0); - else g_camera->ShiftPhi ( dt); - } - else if (SendDlgItemMessage (hTab, IDC_CAM_CTRL_ROTU, BM_GETSTATE, 0, 0) & BST_PUSHED) { - if (rot_is_tilt) g_camera->Rotate ( 0, dt); - else g_camera->ShiftTheta (-dt); - } - else if (SendDlgItemMessage (hTab, IDC_CAM_CTRL_ROTD, BM_GETSTATE, 0, 0) & BST_PUSHED) { - if (rot_is_tilt) g_camera->Rotate ( 0, -dt); - else g_camera->ShiftTheta ( dt); - } - else if (SendDlgItemMessage (hTab, IDC_CAM_CTRL_MOVEIN, BM_GETSTATE, 0, 0) & BST_PUSHED) { - if (rot_is_pan) g_camera->ShiftTheta (-dt); - else g_camera->ShiftDist (-dt); - } - else if (SendDlgItemMessage (hTab, IDC_CAM_CTRL_MOVEOUT, BM_GETSTATE, 0, 0) & BST_PUSHED) { - if (rot_is_pan) g_camera->ShiftTheta ( dt); - else g_camera->ShiftDist (dt); - } - else if (SendDlgItemMessage (hTab, IDC_CAM_CTRL_MOVEL, BM_GETSTATE, 0, 0) & BST_PUSHED) { - g_camera->AddPhi (-dt); - } - else if (SendDlgItemMessage (hTab, IDC_CAM_CTRL_MOVER, BM_GETSTATE, 0, 0) & BST_PUSHED) { - g_camera->AddPhi ( dt); - } - else if (SendDlgItemMessage (hTab, IDC_CAM_CTRL_MOVEU, BM_GETSTATE, 0, 0) & BST_PUSHED) { - g_camera->ChangeDist (1.0+dt); - } - else if (SendDlgItemMessage (hTab, IDC_CAM_CTRL_MOVED, BM_GETSTATE, 0, 0) & BST_PUSHED) { - g_camera->ChangeDist (1.0/(1.0+dt)); - } +DlgCamera::DlgCamera() : ImGuiDialog("Orbiter: Camera", {512,359}) { + m_SelectedPreset = -1; } -// ====================================================================== - -void TabControl::SetLayout () -{ - const int nCockpitCtrl = 5; - const int CockpitCtrl[nCockpitCtrl] = { - IDC_CAM_CTRL_ROTL, IDC_CAM_CTRL_ROTR, IDC_CAM_CTRL_ROTU, IDC_CAM_CTRL_ROTD, - IDC_CAM_CTRL_FORWARD - }; - const int nTrackCtrl = 6; - const int TrackCtrl[nTrackCtrl] = { - IDC_CAM_CTRL_ROTL, IDC_CAM_CTRL_ROTR, IDC_CAM_CTRL_ROTU, IDC_CAM_CTRL_ROTD, - IDC_CAM_CTRL_MOVEIN, IDC_CAM_CTRL_MOVEOUT - }; - const int nToFromCtrl = 2; - const int ToFromCtrl[nToFromCtrl] = { - IDC_CAM_CTRL_MOVEIN, IDC_CAM_CTRL_MOVEOUT - }; - const int nGroundFreeCtrl = 12; - const int GroundFreeCtrl[nGroundFreeCtrl] = { - IDC_CAM_CTRL_ROTL, IDC_CAM_CTRL_ROTR, IDC_CAM_CTRL_ROTU, IDC_CAM_CTRL_ROTD, - IDC_CAM_CTRL_MOVEIN, IDC_CAM_CTRL_MOVEOUT, IDC_CAM_CTRL_MOVEL, IDC_CAM_CTRL_MOVER, - IDC_CAM_CTRL_MOVEU, IDC_CAM_CTRL_MOVED, - IDC_CAM_CTRL_SENSITIVITY, IDC_CAM_CTRL_SENSITIVITYLABEL - }; - const int nGroundLockCtrl = 8; - const int GroundLockCtrl[nGroundLockCtrl] = { - IDC_CAM_CTRL_ROTL, IDC_CAM_CTRL_ROTR, - IDC_CAM_CTRL_MOVEIN, IDC_CAM_CTRL_MOVEOUT, - IDC_CAM_CTRL_MOVEU, IDC_CAM_CTRL_MOVED, - IDC_CAM_CTRL_SENSITIVITY, IDC_CAM_CTRL_SENSITIVITYLABEL - }; - - int i, nCtrl = 0; - const int *Ctrl = 0; +void DlgCamera::OnDraw() { + extmode = g_camera->GetExtMode (); + intmode = g_camera->GetIntMode (); + extcam = (g_camera->GetMode () != CAM_COCKPIT); + ground_lock = g_camera->GroundObserver_TargetLock(); + rot_is_tilt = (!extcam || (extmode == CAMERA_GROUNDOBSERVER && !ground_lock)); + rot_is_pan = (extcam && extmode == CAMERA_GROUNDOBSERVER); + + if(followterrain[0]=='\0') + sprintf (followterrain, "%0.0lf", g_camera->GroundObserver_TerrainLimit()); + + + const char *tabs[] = { + "Control", "Target", "Track", "Ground", "FoV", "Preset" + }; + + void (DlgCamera::* func[])() = { + &DlgCamera::DrawControl, &DlgCamera::DrawTarget, &DlgCamera::DrawTrack, &DlgCamera::DrawGround, &DlgCamera::DrawFoV, &DlgCamera::DrawPreset + }; + + ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None; + if (ImGui::BeginTabBar("CameraTabBar", tab_bar_flags)) + { + for(size_t i = 0; i < sizeof(tabs)/sizeof(tabs[0]); i++) { + if(ImGui::BeginTabItem(tabs[i])) { + (this->*func[i])(); + ImGui::EndTabItem(); + } + } + ImGui::EndTabBar(); + } +} + +void DlgCamera::DrawControl() { + const char *cameraMode = "Internal"; if (extcam) { switch (extmode) { case CAMERA_TARGETRELATIVE: + cameraMode = "Target Relative"; break; case CAMERA_ABSDIRECTION: + cameraMode = "Absolute Direction"; break; case CAMERA_GLOBALFRAME: - nCtrl = nTrackCtrl; - Ctrl = TrackCtrl; - break; + cameraMode = "Global Frame"; break; case CAMERA_TARGETTOOBJECT: + cameraMode = "Target Object"; break; case CAMERA_TARGETFROMOBJECT: - nCtrl = nToFromCtrl; - Ctrl = ToFromCtrl; - break; + cameraMode = "Target from Object"; break; case CAMERA_GROUNDOBSERVER: if (ground_lock) { - nCtrl = nGroundLockCtrl; - Ctrl = GroundLockCtrl; + cameraMode = "Ground Observer (locked)"; break; } else { - nCtrl = nGroundFreeCtrl; - Ctrl = GroundFreeCtrl; - } - break; - } - } else { - nCtrl = nCockpitCtrl; - Ctrl = CockpitCtrl; - } - - for (i = IDC_CAM_CTRL_MIN; i < IDC_CAM_CTRL_MAX; i++) - ShowWindow (GetDlgItem (hTab, i), SW_HIDE); - for (i = 0; i < nCtrl; i++) - ShowWindow (GetDlgItem (hTab, Ctrl[i]), SW_SHOW); - - SetWindowText (GetDlgItem (hTab, IDC_CAM_CTRL_ROTGROUP), rot_is_tilt ? "Tilt" : "Rotate"); -} - -// ====================================================================== - -void TabControl::ModeChanged () -{ - if (active) { - GetCamMode (); - SetLayout (); - } -} - -// ====================================================================== - -void TabControl::GetCamMode () -{ - extmode = g_camera->GetExtMode (); - intmode = g_camera->GetIntMode (); - extcam = (g_camera->GetMode () != CAM_COCKPIT); - ground_lock = g_camera->GroundObserver_TargetLock(); - rot_is_tilt = (!extcam || (extmode == CAMERA_GROUNDOBSERVER && !ground_lock)); - rot_is_pan = (extcam && extmode == CAMERA_GROUNDOBSERVER); -} - -// ====================================================================== - -INT_PTR CALLBACK TabControl::DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - CameraTab::DlgProcInit (hWnd, uMsg, wParam, lParam); - TabControl *pTab = (TabControl*)(uMsg == WM_INITDIALOG ? lParam : GetWindowLongPtr(hWnd,DWLP_USER)); - - switch (uMsg) { - case WM_INITDIALOG: - return pTab->Init (hWnd); - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CAM_CTRL_FORWARD: - g_camera->ResetCockpitDir(); - return TRUE; - } - break; - case WM_HSCROLL: - switch (GetDlgCtrlID ((HWND)lParam)) { - case IDC_CAM_CTRL_SENSITIVITY: - switch (LOWORD(wParam)) { - case SB_THUMBTRACK: - case SB_LINELEFT: - case SB_LINERIGHT: - g_camera->SetGroundObserver_PanSpeed (pow (10, HIWORD(wParam)/10.0-1.0)); - return 0; - } - break; - } - break; - } - return FALSE; -} - - -// ====================================================================== -// ====================================================================== - -TabTarget::TabTarget (HWND hParentTab): CameraTab (hParentTab, IDD_CAM_PG_TARGET, DlgProc) -{ -} - -// ====================================================================== - -char *TabTarget::HelpContext () const -{ - return (char*)"/cam_target.htm"; -} - -// ====================================================================== - -void TabTarget::AddCbodyNode (HWND hWnd, const CelestialBody *cbody, HTREEITEM parent) -{ - char cbuf[256]; cbuf[255] = '\0'; - TV_INSERTSTRUCT tvis; - tvis.hParent = parent; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN; - tvis.item.pszText = cbuf; - tvis.item.cChildren = (cbody->nSecondary() ? 1:0); - strncpy (cbuf, cbody->Name(), 255); - HTREEITEM hti = (HTREEITEM)SendDlgItemMessage (hWnd, IDC_CAM_TGT_TREE, TVM_INSERTITEM, 0, (LPARAM)&tvis); - - // recursively add children - for (DWORD i = 0; i < cbody->nSecondary(); i++) { - AddCbodyNode (hWnd, cbody->Secondary(i), hti); - } -} - -// ====================================================================== - -void TabTarget::AddVessels (HWND hWnd) -{ - char cbuf[256]; cbuf[255] = '\0'; - HTREEITEM hti; - TV_INSERTSTRUCT tvis; - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN; - tvis.item.pszText = cbuf; - tvis.item.cChildren = 1; - strcpy (cbuf, "Vessels"); - hti = (HTREEITEM)SendDlgItemMessage (hWnd, IDC_CAM_TGT_TREE, TVM_INSERTITEM, 0, (LPARAM)&tvis); - tvis.hParent = hti; - tvis.item.cChildren = 0; - for (DWORD i = 0; i < g_psys->nVessel(); i++) { - strncpy (cbuf, g_psys->GetVessel(i)->Name(), 255); - SendDlgItemMessage (hWnd, IDC_CAM_TGT_TREE, TVM_INSERTITEM, 0, (LPARAM)&tvis); - } -} - -// ====================================================================== - -void TabTarget::AddSurfbases (HWND hWnd) -{ - int i, j; - char cbuf[256]; cbuf[255] = '\0'; - HTREEITEM hti; - TV_INSERTSTRUCT tvis; - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN; - tvis.item.pszText = cbuf; - tvis.item.cChildren = 1; - strcpy (cbuf, "Spaceports"); - hti = (HTREEITEM)SendDlgItemMessage (hWnd, IDC_CAM_TGT_TREE, TVM_INSERTITEM, 0, (LPARAM)&tvis); - tvis.hParent = hti; - tvis.item.cChildren = 0; - for (i = 0; i < g_psys->nGrav(); i++) { - Body *obj = g_psys->GetGravObj (i); - if (obj->Type() != OBJTP_PLANET) continue; - Planet *planet = (Planet*)obj; - for (j = 0; j < g_psys->nBase(planet); j++) { - strncpy (cbuf, g_psys->GetBase (planet,j)->Name(), 255); - SendDlgItemMessage (hWnd, IDC_CAM_TGT_TREE, TVM_INSERTITEM, 0, (LPARAM)&tvis); - } - } -} - -// ====================================================================== - -void TabTarget::Show (bool show) -{ - CameraTab::Show (show); - - if (show) - SetWindowText (GetDlgItem (hTab, IDC_CAM_TGT_INPUT), g_camera->Target()->Name()); -} - -// ====================================================================== - -BOOL TabTarget::Init (HWND hWnd) -{ - int i; - - // Fill tree list - for (i = 0; i < g_psys->nStar(); i++) - AddCbodyNode (hWnd, g_psys->GetStar(i), NULL); - AddSurfbases (hWnd); - AddVessels (hWnd); - - return TRUE; -} - -// ====================================================================== - -INT_PTR CALLBACK TabTarget::DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - CameraTab::DlgProcInit (hWnd, uMsg, wParam, lParam); - TabTarget *pTab = (TabTarget*)(uMsg == WM_INITDIALOG ? lParam : GetWindowLongPtr(hWnd,DWLP_USER)); - - switch (uMsg) { - case WM_INITDIALOG: - return pTab->Init (hWnd); - case WM_COMMAND: - switch (LOWORD (wParam)) { - case IDC_CAM_TGT_APPLY: { - char cbuf[256]; - GetWindowText (GetDlgItem (hWnd, IDC_CAM_TGT_INPUT), cbuf, 256); - Body *obj = g_psys->GetObj (cbuf, true); - if (!obj) obj = g_psys->GetBase (cbuf, true); - if (obj) { - g_camera->SetDistance(2.0); - g_pOrbiter->SetView(obj, 1); - } - else { - SetWindowText (GetDlgItem (hWnd, IDC_CAM_TGT_INPUT), g_camera->Target()->Name()); - MessageBeep (MB_ICONEXCLAMATION); - } - } return TRUE; - case IDC_CAM_TGT_FCOCKPIT: - if (HIWORD(wParam) == BN_CLICKED) { - g_camera->SetDistance(2.0); - g_pOrbiter->SetView (g_focusobj, 0); - return TRUE; + cameraMode = "Ground Observer"; break; } break; - case IDC_CAM_TGT_FEXTERN: - if (HIWORD(wParam) == BN_CLICKED) { - g_camera->SetDistance(2.0); - g_pOrbiter->SetView (g_focusobj, 1); - return TRUE; - } - break; - } - break; - case WM_NOTIFY: { - NM_TREEVIEW *pnmtv = (NM_TREEVIEW FAR *)lParam; - if (pnmtv->hdr.code == TVN_SELCHANGING) { - HTREEITEM hti = pnmtv->itemNew.hItem; - TV_ITEM tvi; - char cbuf[256]; - tvi.mask = TVIF_HANDLE|TVIF_TEXT; - tvi.hItem = hti; - tvi.pszText = cbuf; - tvi.cchTextMax = 256; - SendDlgItemMessage (hWnd, IDC_CAM_TGT_TREE, TVM_GETITEM, 0, (LPARAM)&tvi); - SetWindowText (GetDlgItem (hWnd, IDC_CAM_TGT_INPUT), cbuf); } - } break; - } - return FALSE; -} - - -// ====================================================================== -// ====================================================================== - -TabView::TabView (HWND hParentTab): CameraTab (hParentTab, IDD_CAM_PG_VIEW, DlgProc) -{ -} - -// ====================================================================== - -char *TabView::HelpContext () const -{ - return (char*)"/cam_track.htm"; -} - -// ====================================================================== - -BOOL TabView::Init (HWND hWnd) -{ - int i, j; - DWORD k; - - // Fill camera reference combo box - for (i = 0; i < g_psys->nStar(); i++) - SendDlgItemMessage (hWnd, IDC_CAM_VIEW_REFLIST, CB_ADDSTRING, 0, (LPARAM)g_psys->GetStar(i)->Name()); - for (i = 0; i < g_psys->nPlanet(); i++) { - Planet *planet = g_psys->GetPlanet(i); - if (planet->isMoon()) continue; - SendDlgItemMessage (hWnd, IDC_CAM_VIEW_REFLIST, CB_ADDSTRING, 0, (LPARAM)planet->Name()); - for (j = 0; j < planet->nSecondary(); j++) - SendDlgItemMessage (hWnd, IDC_CAM_VIEW_REFLIST, CB_ADDSTRING, 0, (LPARAM)planet->Secondary(j)->Name()); - } - for (k = 0; k < g_psys->nVessel(); k++) - SendDlgItemMessage (hWnd, IDC_CAM_VIEW_REFLIST, CB_ADDSTRING, 0, (LPARAM)g_psys->GetVessel(k)->Name()); - for (k = 0; k < g_psys->nGrav(); k++) { - if (g_psys->GetGravObj(k)->Type() != OBJTP_PLANET) continue; - Planet *planet = (Planet*)g_psys->GetGravObj(k); - for (j = 0; j < g_psys->nBase(planet); j++) - SendDlgItemMessage (hWnd, IDC_CAM_VIEW_REFLIST, CB_ADDSTRING, 0, (LPARAM)g_psys->GetBase(planet,j)->Name()); } - // remove camera target from list - //i = SendDlgItemMessage (hWnd, IDC_CAM_VIEW_REFLIST, CB_FINDSTRINGEXACT, 0, (LPARAM)g_camera->Target()->Name()); - //if (i != CB_ERR) SendDlgItemMessage (hWnd, IDC_CAM_VIEW_REFLIST, CB_DELETESTRING, i, 0); - - // select first item, usually the central star - SendDlgItemMessage (hWnd, IDC_CAM_VIEW_REFLIST, CB_SETCURSEL, 0, 0); - return TRUE; + ImGui::Text("Camera mode : %s", cameraMode); - return TRUE; -} + ImVec2 pos; + double dt = td.SysDT; -// ====================================================================== + pos.x = 50; + pos.y = 75; + ImGui::SetCursorPos(pos); + ImGui::ArrowButton("##up", ImGuiDir_Up); + if(ImGui::IsItemActive()){ + if (rot_is_tilt) g_camera->Rotate ( 0, dt); + else g_camera->ShiftTheta (-dt); + } -INT_PTR CALLBACK TabView::DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - CameraTab::DlgProcInit (hWnd, uMsg, wParam, lParam); - TabView *pTab = (TabView*)(uMsg == WM_INITDIALOG ? lParam : GetWindowLongPtr(hWnd,DWLP_USER)); + pos.x = 50; + pos.y = 125; + ImGui::SetCursorPos(pos); + ImGui::ArrowButton("##down", ImGuiDir_Down); + if(ImGui::IsItemActive()){ + if (rot_is_tilt) g_camera->Rotate ( 0, -dt); + else g_camera->ShiftTheta ( dt); + } + + pos.x = 25; + pos.y = 100; + ImGui::SetCursorPos(pos); + ImGui::ArrowButton("##left", ImGuiDir_Left); + if(ImGui::IsItemActive()){ + if (rot_is_tilt) g_camera->Rotate ( dt, 0); + else g_camera->ShiftPhi (-dt); + } - switch (uMsg) { - case WM_INITDIALOG: - pTab->Init(hWnd); - return FALSE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CAM_VIEW_TGTREL: - g_camera->SetTrackMode (CAMERA_TARGETRELATIVE); - return FALSE; - case IDC_CAM_VIEW_ABSDIR: - g_camera->SetTrackMode (CAMERA_ABSDIRECTION); - return FALSE; - case IDC_CAM_VIEW_GLOBAL: - g_camera->SetTrackMode (CAMERA_GLOBALFRAME); - return FALSE; - case IDC_CAM_VIEW_TGTTO: - case IDC_CAM_VIEW_TGTFROM: { - SetFocus(GetDlgItem(hWnd, LOWORD(wParam))); - char cbuf[256]; - GetWindowText (GetDlgItem (hWnd, IDC_CAM_VIEW_REFLIST), cbuf, 256); - Body *obj = g_psys->GetObj (cbuf, true); - if (!obj) obj = g_psys->GetBase (cbuf, true); + pos.x = 75; + pos.y = 100; + ImGui::SetCursorPos(pos); + ImGui::ArrowButton("##right", ImGuiDir_Right); + if(ImGui::IsItemActive()){ + if (rot_is_tilt) g_camera->Rotate (-dt, 0); + else g_camera->ShiftPhi ( dt); + } + + pos.x = 35; + pos.y = 155; + ImGui::SetCursorPos(pos); + if(ImGui::Button("Forward")) { + g_camera->ResetCockpitDir(); + } +} + +void DlgCamera::AddCbodyNode(const CelestialBody *cbody) { + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth; + const bool is_selected = m_SelectedTarget == cbody->Name(); + if (is_selected) + node_flags |= ImGuiTreeNodeFlags_Selected; + if(cbody->nSecondary()) { + bool node_open = ImGui::TreeNodeEx(cbody->Name(), node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + m_SelectedTarget = cbody->Name(); + if(node_open) { + for (int i = 0; i < cbody->nSecondary(); i++) { + AddCbodyNode (cbody->Secondary(i)); + } + ImGui::TreePop(); + } + } else { + ImGui::TreeNodeEx(cbody->Name(), node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + m_SelectedTarget = cbody->Name(); + } +} + +void DlgCamera::DrawTarget() { + const ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_Border | ImGuiChildFlags_ResizeX; + + ImGui::BeginChild("ChildL", ImVec2(250, 0), window_flags); + for (int i = 0; i < g_psys->nStar(); i++) + AddCbodyNode (g_psys->GetStar(i)); + + if (ImGui::TreeNode("Spaceports")) { + for (int i = 0; i < g_psys->nGrav(); i++) { + Body *obj = g_psys->GetGravObj (i); + if (obj->Type() != OBJTP_PLANET) continue; + Planet *planet = (Planet*)obj; + if (g_psys->nBase(planet) > 0) { + if(ImGui::TreeNode(planet->Name())) { + for (int j = 0; j < g_psys->nBase(planet); j++) { + const char *name = g_psys->GetBase (planet,j)->Name(); + const bool is_selected = m_SelectedTarget == name; + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + ImGui::TreeNodeEx(name, node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + m_SelectedTarget = name; + } + ImGui::TreePop(); + } + } + } + ImGui::TreePop(); + } + if (ImGui::TreeNode("Vessels")) { + for (int i = 0; i < g_psys->nVessel(); i++) { + const char *name = g_psys->GetVessel(i)->Name(); + const bool is_selected = m_SelectedTarget == name; + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + ImGui::TreeNodeEx(name, node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + m_SelectedTarget = name; + } + ImGui::TreePop(); + } + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("ChildR"); + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + ImGui::Text("Target : %s", m_SelectedTarget.c_str()); + if(ImGui::Button("Apply", button_sz)) { + Body *obj = g_psys->GetObj (m_SelectedTarget.c_str(), true); + if (!obj) obj = g_psys->GetBase (m_SelectedTarget.c_str(), true); + if ( obj) g_pOrbiter->SetView (obj, 1); + } + if(ImGui::Button("Focus Cockpit", button_sz)) { + g_pOrbiter->SetView (g_focusobj, 0); + } + if(ImGui::Button("Focus Extern", button_sz)) { + g_pOrbiter->SetView (g_focusobj, 1); + } + ImGui::EndChild(); +} +void DlgCamera::DrawTrack() { + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGui::BeginChild("ChildL", ImVec2(250, 0), window_flags); + { + ImGui::BeginGroupPanel("Moveable modes"); + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + + if(ImGui::Button("Target Relative", button_sz)) { + g_camera->SetTrackMode (CAMERA_TARGETRELATIVE); + } + if(ImGui::Button("Absolute Direction", button_sz)) { + g_camera->SetTrackMode (CAMERA_ABSDIRECTION); + } + if(ImGui::Button("Global Frame", button_sz)) { + g_camera->SetTrackMode (CAMERA_GLOBALFRAME); + } + ImGui::EndGroupPanel(); + } + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("ChildR"); + ImGui::BeginGroupPanel("Fixed modes"); + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + + if(ImGui::Button("Target From...", button_sz)) { + Body *obj = g_psys->GetObj (m_SelectedTarget.c_str(), true); + if (!obj) obj = g_psys->GetBase (m_SelectedTarget.c_str(), true); if (obj && obj != g_camera->Target()) - g_camera->SetTrackMode (LOWORD(wParam) == IDC_CAM_VIEW_TGTTO ? CAMERA_TARGETTOOBJECT : CAMERA_TARGETFROMOBJECT, obj); - } return FALSE; - } - break; - } - return FALSE; -} - - -// ====================================================================== -// ====================================================================== - -TabGround::TabGround (HWND hParentTab): CameraTab (hParentTab, IDD_CAM_PG_GROUND, DlgProc) -{ -} - -// ====================================================================== - -void TabGround::Show (bool show) -{ - EchoCurrentGroundpos (hTab); - CameraTab::Show (show); -} - -// ====================================================================== - -char *TabGround::HelpContext () const -{ - return (char*)"/cam_ground.htm"; -} - -// ====================================================================== - -void TabGround::SelectPlanet (HWND hWnd, int idx) -{ - int i; - char cbuf[256]; - SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_GETLBTEXT, idx, (LPARAM)cbuf); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_SITE, CB_RESETCONTENT, 0, 0); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_ADDR, CB_RESETCONTENT, 0, 0); - Planet *planet = g_psys->GetPlanet (cbuf); - if (!planet) return; - - for (i = 0; i < planet->nGroundObserver(); i++) { - const GROUNDOBSERVERSPEC *go = planet->GetGroundObserver (i); - if (SendDlgItemMessage (hWnd, IDC_CAM_GRND_SITE, CB_FINDSTRINGEXACT, 0, (LPARAM)go->site) == CB_ERR) - SendDlgItemMessage (hWnd, IDC_CAM_GRND_SITE, CB_ADDSTRING, 0, (LPARAM)go->site); - } - if (i) { - SendDlgItemMessage (hWnd, IDC_CAM_GRND_SITE, CB_SETCURSEL, 0, 0); - SelectSite (hWnd, 0); - } -} - -// ====================================================================== - -void TabGround::SelectSite (HWND hWnd, int idx) -{ - int i; - char cbuf[256]; - bool found = false; - double lng, lat, alt; - int pidx = SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_GETCURSEL, 0, 0); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_GETLBTEXT, pidx, (LPARAM)cbuf); - Planet *planet = g_psys->GetPlanet (cbuf); - if (!planet) return; - - SendDlgItemMessage (hWnd, IDC_CAM_GRND_SITE, CB_GETLBTEXT, idx, (LPARAM)cbuf); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_ADDR, CB_RESETCONTENT, 0, 0); - - for (i = 0; i < planet->nGroundObserver(); i++) { - const GROUNDOBSERVERSPEC *go = planet->GetGroundObserver (i); - if (!strcmp (go->site, cbuf)) { - SendDlgItemMessage (hWnd, IDC_CAM_GRND_ADDR, CB_ADDSTRING, 0, (LPARAM)go->addr); - if (!found) { - lng = go->lng; - lat = go->lat; - alt = go->alt; - } - found = true; - } - } - if (found) { - SendDlgItemMessage (hWnd, IDC_CAM_GRND_ADDR, CB_SETCURSEL, 0, 0); - EchoGroundpos (hWnd, lng, lat, alt); - } -} - -// ====================================================================== - -void TabGround::SelectAddr (HWND hWnd, int idx) -{ - char cbuf[256], sitestr[256], addrstr[256]; - - int pidx = SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_GETCURSEL, 0, 0); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_GETLBTEXT, pidx, (LPARAM)cbuf); - Planet *planet = g_psys->GetPlanet (cbuf); - if (!planet) return; - - GetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_SITE), sitestr, 256); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_ADDR, CB_GETLBTEXT, idx, (LPARAM)addrstr); - const GROUNDOBSERVERSPEC *go = planet->GetGroundObserver (sitestr, addrstr); - if (go) { - EchoGroundpos (hWnd, go->lng, go->lat, go->alt); - } -} - -// ====================================================================== - -void TabGround::EchoCurrentGroundpos (HWND hWnd) -{ - char cbuf[256]; - SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, WM_GETTEXT, 256, (LPARAM)cbuf); - Planet *planet = g_psys->GetPlanet (cbuf); - if (!planet) return; - - double lng, lat, alt; - planet->GlobalToEquatorial (*g_camera->GPosPtr(), lng, lat, alt); - alt -= planet->Size() + planet->Elevation (lng, lat); - bool changed = EchoGroundpos (hWnd, lng, lat, alt); - - if (changed) { - SetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_SITE), ""); - SetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_ADDR), ""); - } -} - -// ====================================================================== - -bool TabGround::EchoGroundpos (HWND hWnd, double lng, double lat, double alt) -{ - bool changed = false; - char cbuf[256], ccbuf[256]; - - sprintf (cbuf, "%+0.6f", lng*DEG); - GetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_LNG), ccbuf, 256); - if (strcmp (cbuf, ccbuf)) { - SetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_LNG), cbuf); - changed = true; - } - sprintf (cbuf, "%+0.6f", lat*DEG); - GetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_LAT), ccbuf, 256); - if (strcmp (cbuf, ccbuf)) { - SetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_LAT), cbuf); - changed = true; - } - sprintf (cbuf, "%0.4g", alt); - GetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_ALT), ccbuf, 256); - if (strcmp (cbuf, ccbuf)) { - SetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_ALT), cbuf); - changed = true; - } - return changed; -} - -// ====================================================================== - -void TabGround::ApplyObserver (HWND hWnd) -{ - char cbuf[256], site[256], addr[256]; - SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, WM_GETTEXT, 256, (LPARAM)cbuf); - Planet *planet = g_psys->GetPlanet (cbuf); + g_camera->SetTrackMode (CAMERA_TARGETFROMOBJECT, obj); + } + if(ImGui::Button("Target To...", button_sz)) { + Body *obj = g_psys->GetObj (m_SelectedTarget.c_str(), true); + if (!obj) obj = g_psys->GetBase (m_SelectedTarget.c_str(), true); + if (obj && obj != g_camera->Target()) + g_camera->SetTrackMode (CAMERA_TARGETTOOBJECT, obj); + } + for (int i = 0; i < g_psys->nStar(); i++) + AddCbodyNode (g_psys->GetStar(i)); + + if (ImGui::TreeNode("Spaceports")) { + for (int i = 0; i < g_psys->nGrav(); i++) { + Body *obj = g_psys->GetGravObj (i); + if (obj->Type() != OBJTP_PLANET) continue; + Planet *planet = (Planet*)obj; + if (g_psys->nBase(planet) > 0) { + if(ImGui::TreeNode(planet->Name())) { + for (int j = 0; j < g_psys->nBase(planet); j++) { + const char *name = g_psys->GetBase (planet,j)->Name(); + const bool is_selected = m_SelectedTarget == name; + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + ImGui::TreeNodeEx(name, node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + m_SelectedTarget = name; + } + ImGui::TreePop(); + } + } + } + ImGui::TreePop(); + } + if (ImGui::TreeNode("Vessels")) { + for (int i = 0; i < g_psys->nVessel(); i++) { + const char *name = g_psys->GetVessel(i)->Name(); + const bool is_selected = m_SelectedTarget == name; + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + ImGui::TreeNodeEx(name, node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + m_SelectedTarget = name; + } + ImGui::TreePop(); + } + ImGui::EndGroupPanel(); + ImGui::EndChild(); +} +void DlgCamera::DrawGround() { + const ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX;; + ImGui::BeginChild("ChildL", ImVec2(250, 0), window_flags); + { + ImGui::BeginGroupPanel("Ground Location"); + for (int i = 0; i < g_psys->nGrav(); i++) { + Body *obj = g_psys->GetGravObj (i); + if (obj->Type() != OBJTP_PLANET) continue; + Planet *planet = (Planet*)obj; + + + if (planet->nGroundObserver() > 0) { + if(ImGui::TreeNode(planet->Name())) { + for (int j = 0; j < planet->nGroundObserver(); j++) { + const GROUNDOBSERVERSPEC *go = planet->GetGroundObserver (j); + std::string name = std::string(go->site) + "-" + go->addr; + const bool is_selected = m_SelectedSite == name; + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + ImGui::TreeNodeEx(name.c_str(), node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) { + m_SelectedSite = name; + m_SitePlanet = planet->Name(); + sprintf(longitude, "%+0.6f", go->lng * 180.0/PI); + sprintf(latitude, "%+0.6f", go->lat * 180.0/PI); + sprintf(altitude, "%0.4g", go->alt); + } + } + ImGui::TreePop(); + } + } + } + ImGui::EndGroupPanel(); + } + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("ChildR"); + ImGui::BeginGroupPanel("Coordinates"); + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + ImGui::InputText("Longitude", longitude, 64, ImGuiInputTextFlags_CharsDecimal); + ImGui::InputText("Latitude", latitude, 64, ImGuiInputTextFlags_CharsDecimal); + ImGui::InputText("Altitude", altitude, 64, ImGuiInputTextFlags_CharsDecimal); + + ImGui::InputText("Follow Terrain", followterrain, 64, ImGuiInputTextFlags_CharsDecimal); + + if(ImGui::Button("Current", button_sz)) { + const Planet *planet = g_psys->GetPlanet (m_SitePlanet.c_str()); + if(!planet) { + planet = g_camera->ProxyPlanet(); + m_SitePlanet = planet->Name(); + } + if (planet) { + double lng, lat, alt; + planet->GlobalToEquatorial (*g_camera->GPosPtr(), lng, lat, alt); + alt -= planet->Size() + planet->Elevation (lng, lat); + sprintf(longitude, "%+0.6f", lng * 180.0/PI); + sprintf(latitude, "%+0.6f", lat * 180.0/PI); + sprintf(altitude, "%0.4g", alt); + } + SetCurrentGroundpos(); + } + if(ImGui::Button("Apply", button_sz)) { + ApplyObserver(); + } + + ImGui::Checkbox("Target lock", &m_TargetLock); + ImGui::EndGroupPanel(); + ImGui::EndChild(); +} + +void DlgCamera::ApplyObserver() { + Planet *planet = g_psys->GetPlanet (m_SitePlanet.c_str()); if (!planet) return; double lng, lat, alt = 1.7; bool ok; - GetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_LNG), cbuf, 256); - ok = (sscanf (cbuf, "%lf", &lng) == 1); - GetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_LAT), cbuf, 256); - ok = ok && (sscanf (cbuf, "%lf", &lat) == 1); - GetWindowText (GetDlgItem (hWnd, IDC_CAM_GRND_ALT), cbuf, 256); - ok = ok && (sscanf (cbuf, "%lf", &alt) == 1); + ok = (sscanf (longitude, "%lf", &lng) == 1); + ok = ok && (sscanf (latitude, "%lf", &lat) == 1); + ok = ok && (sscanf (altitude, "%lf", &alt) == 1); double altlimit; - GetWindowText (GetDlgItem (hWnd, IDC_EDIT1), cbuf, 256); - if (sscanf (cbuf, "%lf", &altlimit)) - g_camera->SetGroundObserver_TerrainLimit (max(1.0,altlimit)); + if (sscanf (followterrain, "%lf", &altlimit)) + g_camera->SetGroundObserver_TerrainLimit (std::max(1.0,altlimit)); if (ok) g_camera->SetGroundMode (CAMERA_GROUNDOBSERVER, planet, lng*RAD, lat*RAD, alt, NULL); - return; - - - SendDlgItemMessage (hWnd, IDC_CAM_GRND_SITE, WM_GETTEXT, 256, (LPARAM)site); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_ADDR, WM_GETTEXT, 256, (LPARAM)addr); - - if (sscanf (site, "%lf%lf%lf", &lng, &lat, &alt) >= 2) { - lng *= RAD; lat *= RAD; alt = max (alt, 1.0); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_ADDR, WM_SETTEXT, 0, (LPARAM)""); - } else { - const GROUNDOBSERVERSPEC *go = planet->GetGroundObserver (site, addr); - if (!go) return; - lng = go->lng, lat = go->lat, alt = go->alt; - } - - Camera::GroundObserverSite gos; - strncpy (gos.planet, cbuf, 63); - strncpy (gos.site, site, 63); - strncpy (gos.addr, addr, 63); - g_camera->SetGroundMode (CAMERA_GROUNDOBSERVER, planet, lng, lat, alt, &gos); } -// ====================================================================== - -void TabGround::SetCurrentGroundpos (HWND hWnd) -{ - EchoCurrentGroundpos (hWnd); +void DlgCamera::SetCurrentGroundpos() { if (g_camera->GetExtMode() == CAMERA_GROUNDOBSERVER) return; // nothing to do - ApplyObserver (hWnd); - if (SendDlgItemMessage (hWnd, IDC_CAM_GRND_LOCK, BM_GETCHECK, 0, 0) == BST_UNCHECKED) { + ApplyObserver (); + + if (!m_TargetLock) { // force lock to target to initialise camera direction g_camera->SetGroundObserver_TargetLock (true); g_camera->SetGroundObserver_TargetLock (false); } - char cbuf[256]; double alt; - GetWindowText (GetDlgItem (hWnd, IDC_EDIT1), cbuf, 256); - if (sscanf (cbuf, "%lf", &alt)) - g_camera->SetGroundObserver_TerrainLimit (max(1.0,alt)); -} - -// ====================================================================== - -void TabGround::GObserverChanged (const char *str) -{ - if (active) - EchoCurrentGroundpos (hTab); -} - -// ====================================================================== - -void TabGround::LockChanged (bool lock) -{ - SendDlgItemMessage (hTab, IDC_CAM_GRND_LOCK, BM_SETCHECK, lock ? BST_CHECKED : BST_UNCHECKED, 0); -} - -// ====================================================================== - -BOOL TabGround::Init (HWND hWnd) -{ - int i, j; - - for (i = 0; i < g_psys->nPlanet(); i++) { - Planet *planet = g_psys->GetPlanet(i); - if (planet->isMoon()) continue; - SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_ADDSTRING, 0, (LPARAM)planet->Name()); - for (j = 0; j < planet->nSecondary(); j++) - SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_ADDSTRING, 0, (LPARAM)planet->Secondary(j)->Name()); - } - SelectPlanet (hWnd, 0); - - // restore last ground observer address - const Camera::GroundObserverSite *gos = g_camera->GetGroundObserverSite(); - if (gos->planet[0]) { - i = SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_FINDSTRINGEXACT, -1, (LPARAM)gos->planet); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_SETCURSEL, i, 0); - SelectPlanet (hWnd, i); - i = SendDlgItemMessage (hWnd, IDC_CAM_GRND_SITE, CB_FINDSTRINGEXACT, -1, (LPARAM)gos->site); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_SITE, CB_SETCURSEL, i, 0); - SelectSite (hWnd, i); - i = SendDlgItemMessage (hWnd, IDC_CAM_GRND_ADDR, CB_FINDSTRINGEXACT, -1, (LPARAM)gos->addr); - SendDlgItemMessage (hWnd, IDC_CAM_GRND_ADDR, CB_SETCURSEL, i, 0); - } else { // nothing stored; use planet closest to camera instead - i = SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_FINDSTRINGEXACT, -1, (LPARAM)g_camera->ProxyPlanet()->Name()); - if (i == CB_ERR) i = 0; - SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_SETCURSEL, i, 0); - SelectPlanet (hWnd, i); - } - - SendDlgItemMessage (hWnd, IDC_CAM_GRND_LOCK, BM_SETCHECK, (WPARAM)g_camera->GroundObserver_TargetLock(), 0); - - char cbuf[256]; - sprintf (cbuf, "%0.0lf", g_camera->GroundObserver_TerrainLimit()); - SetWindowText (GetDlgItem (hWnd, IDC_EDIT1), cbuf); - - return TRUE; -} - -// ====================================================================== - -INT_PTR CALLBACK TabGround::DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - CameraTab::DlgProcInit (hWnd, uMsg, wParam, lParam); - TabGround *pTab = (TabGround*)(uMsg == WM_INITDIALOG ? lParam : GetWindowLongPtr (hWnd, DWLP_USER)); - - switch (uMsg) { - case WM_INITDIALOG: - return pTab->Init (hWnd); - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CAM_GRND_REFBODY: - if (HIWORD(wParam) == CBN_SELCHANGE) { - int idx = SendDlgItemMessage (hWnd, IDC_CAM_GRND_REFBODY, CB_GETCURSEL, 0, 0); - pTab->SelectPlanet (hWnd, idx); - } - return TRUE; - case IDC_CAM_GRND_SITE: - if (HIWORD(wParam) == CBN_SELCHANGE) { - int idx = SendDlgItemMessage (hWnd, IDC_CAM_GRND_SITE, CB_GETCURSEL, 0, 0); - pTab->SelectSite (hWnd, idx); - } - return TRUE; - case IDC_CAM_GRND_ADDR: - if (HIWORD(wParam) == CBN_SELCHANGE) { - int idx = SendDlgItemMessage (hWnd, IDC_CAM_GRND_ADDR, CB_GETCURSEL, 0, 0); - pTab->SelectAddr (hWnd, idx); - } - return TRUE; - case IDC_CAM_GRND_CURRENT: - pTab->SetCurrentGroundpos (hWnd); - return TRUE; - case IDC_CAM_GRND_APPLY: - pTab->ApplyObserver (hWnd); - return TRUE; - case IDC_CAM_GRND_LOCK: { - int idx = SendDlgItemMessage (hWnd, IDC_CAM_GRND_LOCK, BM_GETCHECK, 0, 0); - g_camera->SetGroundObserver_TargetLock (idx == BST_CHECKED ? true : false); - } return TRUE; - case IDC_EDIT1: { - char cbuf[256]; - double alt; - GetWindowText (GetDlgItem (hWnd, IDC_EDIT1), cbuf, 256); - if (sscanf (cbuf, "%lf", &alt)) g_camera->SetGroundObserver_TerrainLimit (alt); - } return TRUE; - } - break; - } - return FALSE; -} - + if (sscanf (followterrain, "%lf", &alt)) + g_camera->SetGroundObserver_TerrainLimit (std::max(1.0,alt)); +} + +void DlgCamera::DrawFoV() { + float fov=oapiCameraAperture()/RAD/0.5; + if(ImGui::SliderFloat("Field of View", &fov, 10.0, 90.0, "%.1f")) { + if(fov < 10.0f) fov = 10.0f; + else if(fov>90.0f) fov = 90.0f; + oapiCameraSetAperture(fov*RAD*0.5); + } +} +void DlgCamera::DrawPreset() { + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX;;; + static float sz1 = 0.0; + float sz2; + // ImGui::Splitter(true, 0.5f, 8.0f, &sz1, &sz2, 8, 8, ImGui::GetContentRegionAvail().y); + ImGui::BeginChild("ChildL", ImVec2(250, 0), window_flags); + { + if (ImGui::BeginListBox("##listbox preset", ImVec2(ImGui::GetContentRegionAvail().x*0.99, ImGui::GetContentRegionAvail().y*0.99))) + { + for (int i = 0; i < g_camera->nPreset(); i++) { + char buf[256]; + g_camera->GetPreset(i)->GetDescr (buf, 256); + + const bool is_selected = (m_SelectedPreset == i); + ImGui::PushID(i); + if (ImGui::Selectable(buf, is_selected)) + m_SelectedPreset = i; + ImGui::PopID(); + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndListBox(); + //ImGui::Text("Selected %d", m_SelectedPreset); + } + } + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("ChildR"); + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + if(ImGui::Button("Add", button_sz)) { + g_camera->AddPreset(); + } + if(ImGui::Button("Delete", button_sz)) { + g_camera->DelPreset(m_SelectedPreset); + } + if(ImGui::Button("Clear", button_sz)) { + g_camera->ClearPresets(); + } + if(ImGui::Button("Recall", button_sz)) { + g_camera->RecallPreset (m_SelectedPreset); + } + + ImGui::EndChild(); -// ====================================================================== -// ====================================================================== - -TabFov::TabFov (HWND hParentTab): CameraTab (hParentTab, IDD_CAM_PG_FOV, DlgProc) -{ -} - -// ====================================================================== - -char *TabFov::HelpContext () const -{ - return (char*)"/cam_fov.htm"; -} - -// ====================================================================== - -void TabFov::FovChanged (double fov) -{ - RegisterFov (hTab, fov); -} - -// ====================================================================== - -void TabFov::RegisterFov (HWND hWnd, double fov) -{ - char cbuf[128]; - SendDlgItemMessage (hWnd, IDC_CAM_FOV_SLIDER, TBM_SETPOS, TRUE, (LONG)fov); - GetWindowText (GetDlgItem (hWnd, IDC_CAM_FOV_INPUT), cbuf, 127); - if (fabs (fov-atof(cbuf)) > 1e-5) { - sprintf (cbuf, "%0.2f", fov); - SetWindowText (GetDlgItem (hWnd, IDC_CAM_FOV_INPUT), cbuf); - } -} - -// ====================================================================== - -void TabFov::SetFov (double fov_deg) -{ - if (fov_deg >= 10.0 && fov_deg <= 90.0) - g_pOrbiter->SetFOV (fov_deg * 0.5*RAD); -} - -// ====================================================================== - -INT_PTR CALLBACK TabFov::DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - CameraTab::DlgProcInit (hWnd, uMsg, wParam, lParam); - TabFov *pTab = (TabFov*)(uMsg == WM_INITDIALOG ? lParam : GetWindowLongPtr(hWnd,DWLP_USER)); - - switch (uMsg) { - case WM_INITDIALOG: - // initialise the slider - SendDlgItemMessage (hWnd, IDC_CAM_FOV_SLIDER, TBM_SETRANGE, FALSE, MAKELONG(10,90)); - SendDlgItemMessage (hWnd, IDC_CAM_FOV_SLIDER, TBM_SETPAGESIZE, 0, 10L); - SendDlgItemMessage (hWnd, IDC_CAM_FOV_SLIDER, TBM_SETTICFREQ, 10, 0); - // set controls to current FOV setting - pTab->RegisterFov (hWnd, g_camera->Aperture()*2.0*DEG); - return TRUE; - case WM_COMMAND: - switch (LOWORD (wParam)) { - case IDC_CAM_FOV_30: - case IDC_CAM_FOV_40: - case IDC_CAM_FOV_50: - case IDC_CAM_FOV_60: - case IDC_CAM_FOV_70: - pTab->SetFov ((LOWORD(wParam)-IDC_CAM_FOV_30+3)*10.0); - return TRUE; - } - case IDC_CAM_FOV_INPUT: - if (HIWORD (wParam) == EN_UPDATE) { - char cbuf[256]; - GetWindowText ((HWND)lParam, cbuf, 256); - pTab->SetFov (atof(cbuf)); - return TRUE; - } - break; - break; - case WM_HSCROLL: // trackbar notifications - if (LOWORD (wParam) == TB_THUMBTRACK) { - pTab->SetFov ((double)SendDlgItemMessage (hWnd, IDC_CAM_FOV_SLIDER, TBM_GETPOS, 0, 0)); - return TRUE; - } - break; - } - return FALSE; -} - - -// ====================================================================== -// ====================================================================== - -TabPreset::TabPreset (HWND hParentTab): CameraTab (hParentTab, IDD_CAM_PG_PRESET, DlgProc) -{ -} - -// ====================================================================== - -char *TabPreset::HelpContext () const -{ - return (char*)"/cam_preset.htm"; -} - -// ====================================================================== - -INT_PTR CALLBACK TabPreset::DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - CameraTab::DlgProcInit (hWnd, uMsg, wParam, lParam); - - DWORD i, j; - char cbuf[256]; - - switch (uMsg) { - case WM_INITDIALOG: - for (i = 0; i < g_camera->nPreset(); i++) { - g_camera->GetPreset(i)->GetDescr (cbuf, 256); - SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_ADDSTRING, 0, (LPARAM)cbuf); - } - if (i) SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_SETCURSEL, 0, 0); - return TRUE; - - case WM_COMMAND: - switch (LOWORD (wParam)) { - case IDHELP: - DefHelpContext.topic = (char*)"/cam_preset.htm"; - g_pOrbiter->OpenHelp (&DefHelpContext); - return TRUE; - case IDC_CAM_PRE_NEW: - i = g_camera->AddPreset(); - g_camera->GetPreset(i)->GetDescr (cbuf, 256); - SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_ADDSTRING, 0, (LPARAM)cbuf); - SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_SETCURSEL, i, 0); - return TRUE; - case IDC_CAM_PRE_DEL: - i = SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_GETCURSEL, 0, 0); - if (i != LB_ERR && g_camera->DelPreset (i)) { - SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_DELETESTRING, i, 0); - j = SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_GETCOUNT, 0, 0); - if (j > i) SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_SETCURSEL, i, 0); - else if (i > 0) SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_SETCURSEL, i-1, 0); - } - return TRUE; - case IDC_CAM_PRE_RECALL: - i = SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_GETCURSEL, 0, 0); - if (i != LB_ERR) g_camera->RecallPreset (i); - return TRUE; - case IDC_CAM_PRE_CLEAR: - g_camera->ClearPresets(); - SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_RESETCONTENT, 0, 0); - return TRUE; - case IDC_CAM_PRE_LIST: - if (HIWORD(wParam) == LBN_DBLCLK) { - i = SendDlgItemMessage (hWnd, IDC_CAM_PRE_LIST, LB_GETCURSEL, 0, 0); - if (i != LB_ERR) g_camera->RecallPreset (i); - return TRUE; - } - break; - } - break; - } - return FALSE; } diff --git a/Src/Orbiter/DlgCamera.h b/Src/Orbiter/DlgCamera.h index c66c58920..26fdbd243 100644 --- a/Src/Orbiter/DlgCamera.h +++ b/Src/Orbiter/DlgCamera.h @@ -8,166 +8,41 @@ #ifndef __DLGCAMERA_H #define __DLGCAMERA_H -#include "DialogWin.h" -#include "CommCtrl.h" -#include "Celbody.h" +#include "DlgMgr.h" #include "Camera.h" -class CameraTab; -class TabControl; -class TabFov; -class TabGround; - -// ====================================================================== - -class DlgCamera: public DialogWin { +class CelestialBody; +class DlgCamera : public ImGuiDialog { public: - DlgCamera (HINSTANCE hInstance, HWND hParent, void *context); - ~DlgCamera (); - void Update (); - void ModeChanged (); - void FovChanged (double fov); - void GObserverChanged (const char *str); - void Refresh (const Camera *cam); - char *HelpContext () const { return hcontext; } - BOOL OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam); - BOOL OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl); - BOOL OnNotify (HWND hDlg, int idCtrl, LPNMHDR pnmh); - BOOL OnApp (HWND hDlg, WPARAM wParam, LPARAM lParam); - -protected: - void Clear (); - int AddTab (HWND hDlg, CameraTab *tab, const char *label); - void SwitchTab (HWND hDlg); - + DlgCamera(); + void OnDraw() override; + static const std::string etype; private: - int nTab; - CameraTab **pTab; - TabControl *pTabControl; - TabFov *pTabFov; - TabGround *pTabGround; - char *hcontext; -}; - -// ====================================================================== -// Base class for camera dialog tabs - -class CameraTab { -public: - CameraTab (HWND hParentTab, int dlgId, DLGPROC dlgProc); - virtual ~CameraTab (); - virtual void Show (bool show); - virtual void Update () {} - virtual char *HelpContext() const = 0; - -protected: - static INT_PTR CALLBACK DlgProcInit (HWND, UINT, WPARAM, LPARAM); - HWND hParent; - HWND hTab; - bool active; -}; + void DrawControl(); + void DrawTarget(); + void DrawTrack(); + void DrawGround(); + void DrawFoV(); + void DrawPreset(); -// ====================================================================== -// Camera control tab - -class TabControl: public CameraTab { -public: - TabControl (HWND hParentTab); - char *HelpContext () const; - void Show (bool show); - void Update (); - void ModeChanged (); - BOOL Init (HWND hWnd); - -protected: - void GetCamMode (); - void SetLayout (); - static INT_PTR CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM); ExtCamMode extmode; IntCamMode intmode; bool extcam; bool ground_lock; bool rot_is_tilt, rot_is_pan; -}; + std::string m_SelectedTarget; + std::string m_SelectedSite; + std::string m_SitePlanet; + int m_SelectedPreset; -// ====================================================================== -// Camera target selection tab + char longitude[64]=""; + char latitude[64]=""; + char altitude[64]=""; + char followterrain[64]=""; + bool m_TargetLock; -class TabTarget: public CameraTab { -public: - TabTarget (HWND hParentTab); - char *HelpContext () const; - void Show (bool show); - BOOL Init (HWND hWnd); - -protected: - void AddCbodyNode (HWND hWnd, const CelestialBody *cbody, HTREEITEM parent); - void AddVessels (HWND hWnd); - void AddSurfbases (HWND hWnd); - static INT_PTR CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM); + void AddCbodyNode(const CelestialBody *body); + void ApplyObserver(); + void SetCurrentGroundpos(); }; - -// ====================================================================== -// Camera track mode tab - -class TabView: public CameraTab { -public: - TabView (HWND hParentTab); - char *HelpContext () const; - BOOL Init (HWND hWnd); - -protected: - static INT_PTR CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM); -}; - -// ====================================================================== -// Camera ground mode tab - -class TabGround: public CameraTab { -public: - TabGround (HWND hParentTab); - void GObserverChanged (const char *str); - void LockChanged (bool lock); - void Show (bool show); - char *HelpContext () const; - BOOL Init (HWND hWnd); - -protected: - void SelectPlanet (HWND hWnd, int idx); - void SelectSite (HWND hWnd, int idx); - void SelectAddr (HWND hWnd, int idx); - void ApplyObserver (HWND hWnd); - void SetCurrentGroundpos (HWND hWnd); - bool EchoGroundpos (HWND hWnd, double lng, double lat, double alt); - void EchoCurrentGroundpos (HWND hWnd); - static INT_PTR CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM); -}; - -// ====================================================================== -// Camera field of view tab - -class TabFov: public CameraTab { -public: - TabFov (HWND hParentTab); - void FovChanged (double fov); - char *HelpContext () const; - -protected: - void RegisterFov (HWND hWnd, double fov); - void SetFov (double fov_deg); - static INT_PTR CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM); -}; - -// ====================================================================== -// Camera preset position management tab - -class TabPreset: public CameraTab { -public: - TabPreset (HWND hParentTab); - char *HelpContext () const; - -protected: - static INT_PTR CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM); -}; - #endif // !__DLGCAMERA_H \ No newline at end of file diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index 10e0e0552..63a881e91 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -3,6 +3,7 @@ #define EXPORT_IMGUI_CONTEXT #define OAPI_IMPLEMENTATION +#define IMGUI_DEFINE_MATH_OPERATORS #include #include "OrbiterAPI.h" #include "DlgMgr.h" @@ -445,7 +446,7 @@ static void ImGuiSetStyle(bool bStyleDark_, float alpha_) style.ScrollbarRounding = 3.0f; style.GrabRounding = 3.0f; style.TabRounding = 3.0f; - + return; // light style from Pacôme Danhiez (user itamago) https://github.com/ocornut/imgui/pull/511#issuecomment-175719267 style.Colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); @@ -588,6 +589,8 @@ ImGuiDialog::~ImGuiDialog(){ } void ImGuiDialog::Display() { + ImGui::SetNextWindowSize(ImVec2(defaultSize.width, defaultSize.height), ImGuiCond_FirstUseEver); + if(ImGui::Begin(name.c_str(), &active)) { OnDraw(); } @@ -825,6 +828,7 @@ DLLEXPORT void oapiAddNotification(int type, const char *title, const char *cont notifications.emplace_back(type, title, content, hash); } +#include "imgui_internal.h" // ImGui utils namespace ImGui { @@ -858,4 +862,99 @@ namespace ImGui { ImGui::EndTooltip(); } } + + // Code from thedmd: https://github.com/ocornut/imgui/issues/1496 + static ImVector s_GroupPanelLabelStack; + DLLEXPORT void BeginGroupPanel(const char* name, const ImVec2& size) + { + ImGui::BeginGroup(); + auto cursorPos = ImGui::GetCursorScreenPos(); + auto itemSpacing = ImGui::GetStyle().ItemSpacing; + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); + auto frameHeight = ImGui::GetFrameHeight(); + // workaround for incorrect capture of columns/table width by placing + // zero-sized dummy element in the same group, this ensure + // max X cursor position is updated correctly + ImGui::SameLine(0.0f, 0.0f); + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + ImGui::BeginGroup(); + ImVec2 effectiveSize = size; + if (size.x < 0.0f) + effectiveSize.x = ImGui::GetContentRegionAvail().x; + else + effectiveSize.x = size.x; + ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f)); + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::SameLine(0.0f, 0.0f); + ImGui::BeginGroup(); + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::SameLine(0.0f, 0.0f); + ImGui::TextUnformatted(name); + auto labelMin = ImGui::GetItemRectMin(); + auto labelMax = ImGui::GetItemRectMax(); + ImGui::SameLine(0.0f, 0.0f); + ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y)); + ImGui::BeginGroup(); + //ImGui::GetWindowDrawList()->AddRect(labelMin, labelMax, IM_COL32(255, 0, 255, 255)); + ImGui::PopStyleVar(2); + ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f; + ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f; + ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f; + ImGui::GetCurrentWindow()->Size.x -= frameHeight; + auto itemWidth = ImGui::CalcItemWidth(); + ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight)); + s_GroupPanelLabelStack.push_back(ImRect(labelMin, labelMax)); + } + DLLEXPORT void EndGroupPanel() + { + ImGui::PopItemWidth(); + auto itemSpacing = ImGui::GetStyle().ItemSpacing; + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); + auto frameHeight = ImGui::GetFrameHeight(); + ImGui::EndGroup(); + //ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(0, 255, 0, 64), 4.0f); + ImGui::EndGroup(); + ImGui::SameLine(0.0f, 0.0f); + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y)); + ImGui::EndGroup(); + auto itemMin = ImGui::GetItemRectMin(); + auto itemMax = ImGui::GetItemRectMax(); + //ImGui::GetWindowDrawList()->AddRectFilled(itemMin, itemMax, IM_COL32(255, 0, 0, 64), 4.0f); + auto labelRect = s_GroupPanelLabelStack.back(); + s_GroupPanelLabelStack.pop_back(); + ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f; + ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f)); + labelRect.Min.x -= itemSpacing.x; + labelRect.Max.x += itemSpacing.x; + for (int i = 0; i < 4; ++i) + { + switch (i) + { + // left half-plane + case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break; + // right half-plane + case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break; + // top + case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, -FLT_MAX), ImVec2(labelRect.Max.x, labelRect.Min.y), true); break; + // bottom + case 3: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break; + } + ImGui::GetWindowDrawList()->AddRect( + frameRect.Min, frameRect.Max, + ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)), + halfFrame.x); + ImGui::PopClipRect(); + } + ImGui::PopStyleVar(2); + ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f; + ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f; + ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f; + ImGui::GetCurrentWindow()->Size.x += frameHeight; + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + ImGui::EndGroup(); + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + } } From 49f054093c5473ee2e763b57d5fa7bc50886c883 Mon Sep 17 00:00:00 2001 From: Gondos Date: Fri, 31 Jan 2025 11:56:28 +0100 Subject: [PATCH 18/51] [ImGui]Convert DlgFocus --- Src/Orbiter/DlgFocus.cpp | 760 +++++++++++---------------------------- Src/Orbiter/DlgFocus.h | 44 +-- 2 files changed, 215 insertions(+), 589 deletions(-) diff --git a/Src/Orbiter/DlgFocus.cpp b/Src/Orbiter/DlgFocus.cpp index fc18e3c1c..c84b07e12 100644 --- a/Src/Orbiter/DlgFocus.cpp +++ b/Src/Orbiter/DlgFocus.cpp @@ -5,571 +5,221 @@ // Focus vessel selection dialog // ====================================================================== -#define STRICT 1 - #include "DlgFocus.h" -#include "Resource.h" -#include "Orbiter.h" #include "Psys.h" -#include "SuperVessel.h" -#include "Pane.h" +#include "OrbiterAPI.h" +#include "Orbiter.h" #include "Camera.h" -#include "Util.h" -#include "Uxtheme.h" -#include +#include "imgui.h" +#include -extern Orbiter *g_pOrbiter; +extern Camera *g_camera; extern PlanetarySystem *g_psys; +extern Orbiter *g_pOrbiter; extern Vessel *g_focusobj, *g_pfocusobj; -extern Camera *g_camera; -extern HELPCONTEXT DefHelpContext; -extern char DBG_MSG[256]; - -// ====================================================================== - -DlgFocus::DlgFocus (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_JUMPVESSEL, 0, 0, context) -{ - pos = &g_pOrbiter->Cfg()->CfgWindowPos.DlgFocus; - irange = g_pOrbiter->Cfg()->CfgUIPrm.SelVesselRange; - unroll_assemblies = g_pOrbiter->Cfg()->CfgUIPrm.bSelVesselFlat; -} - -// ====================================================================== - -DlgFocus::~DlgFocus () -{ - g_pOrbiter->Cfg()->CfgUIPrm.SelVesselTab = ctab; - g_pOrbiter->Cfg()->CfgUIPrm.SelVesselRange = irange; - g_pOrbiter->Cfg()->CfgUIPrm.bSelVesselFlat = unroll_assemblies; -} - -// ====================================================================== - -BOOL DlgFocus::OnInitDialog (HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - EnableThemeDialogTexture (hWnd, ETDT_ENABLETAB); - - const int ntab = 4; - const char *label[ntab] = {"All", "Nearby", "Location", "Class"}; - TC_ITEM tie; - tie.mask = TCIF_TEXT; - tie.iImage = -1; - for (int i = 0; i < ntab; i++) { - tie.pszText = (char*)label[i]; - SendDlgItemMessage (hWnd, IDC_TAB1, TCM_INSERTITEM, i, (LPARAM)&tie); - } - ctab = g_pOrbiter->Cfg()->CfgUIPrm.SelVesselTab; - - GetClientRect (hWnd, &rClient); - rTab = GetClientPos (hWnd, GetDlgItem (hWnd, IDC_TAB1)); - rEdit = GetClientPos (hWnd, GetDlgItem (hWnd, IDC_EDIT1)); - rTree = GetClientPos (hWnd, GetDlgItem (hWnd, IDC_TREE1)); - rAppl = GetClientPos (hWnd, GetDlgItem (hWnd, IDOK)); - rPrev = GetClientPos (hWnd, GetDlgItem (hWnd, IDC_BUTTON1)); - rHelp = GetClientPos (hWnd, GetDlgItem (hWnd, IDHELP)); - rClse = GetClientPos (hWnd, GetDlgItem (hWnd, IDCANCEL)); - rSldr = GetClientPos (hWnd, GetDlgItem (hWnd, IDC_SLIDER1)); - rLabl = GetClientPos (hWnd, GetDlgItem (hWnd, IDC_STATIC1)); - rChck = GetClientPos (hWnd, GetDlgItem (hWnd, IDC_CHECK1)); - - SetWindowText (GetDlgItem (hWnd, IDC_EDIT1), g_focusobj->Name()); - TabCtrl_SetCurSel (GetDlgItem (hWnd, IDC_TAB1), ctab); - SwitchTab (hWnd); - EnableWindow (GetDlgItem (hWnd, IDC_BUTTON1), g_pfocusobj ? TRUE:FALSE); - EnableWindow (GetDlgItem (hWnd, IDOK), FALSE); - - SendDlgItemMessage (hWnd, IDC_CHECK1, BM_SETCHECK, unroll_assemblies ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hWnd, IDC_SLIDER1, TBM_SETRANGE, FALSE, MAKELONG(1,8)); - SendDlgItemMessage (hWnd, IDC_SLIDER1, TBM_SETPAGESIZE, 0, 1L); - SendDlgItemMessage (hWnd, IDC_SLIDER1, TBM_SETTICFREQ, 1, 0); - SendDlgItemMessage (hWnd, IDC_SLIDER1, TBM_SETPOS, TRUE, (LONG)irange); - SetRangeLabel (hWnd, irange); - - return TRUE; -} - -// ====================================================================== - -BOOL DlgFocus::OnSize (HWND hDlg, WPARAM wParam, int w, int h) -{ - RECT r; - int i; - const int nSizeElm = 9; - const int SizeElm[nSizeElm] = { - IDC_EDIT1, IDC_TREE1, IDOK, IDC_BUTTON1, IDC_SLIDER1, IDC_STATIC1, IDC_CHECK1, IDCANCEL, IDHELP - }; - - GetClientRect (hDlg, &r); - int dw = r.right - rClient.right; - int dh = r.bottom - rClient.bottom; - for (i = 0; i < nSizeElm; i++) - ShowWindow (GetDlgItem (hDlg, SizeElm[i]), SW_HIDE); - r = rTab; r.right += dw; r.bottom += dh; - SetClientPos (hDlg, GetDlgItem (hDlg, IDC_TAB1), r); - r = rEdit; r.right += dw; - SetClientPos (hDlg, GetDlgItem (hDlg, IDC_EDIT1), r); - r = rTree; r.right += dw; r.bottom += dh; - SetClientPos (hDlg, GetDlgItem (hDlg, IDC_TREE1), r); - r = rAppl; r.left += dw; r.right += dw; - SetClientPos (hDlg, GetDlgItem (hDlg, IDOK), r); - r = rPrev; r.left += dw; r.right += dw; - SetClientPos (hDlg, GetDlgItem (hDlg, IDC_BUTTON1), r); - r = rClse; r.left += dw; r.right += dw; r.top += dh; r.bottom += dh; - SetClientPos (hDlg, GetDlgItem (hDlg, IDCANCEL), r); - r = rHelp; r.left += dw; r.right += dw; r.top += dh; r.bottom += dh; - SetClientPos (hDlg, GetDlgItem (hDlg, IDHELP), r); - r = rSldr; r.left += dw; r.right += dw; r.top += dh; r.bottom += dh; - SetClientPos (hDlg, GetDlgItem (hDlg, IDC_SLIDER1), r); - r = rLabl; r.left += dw; r.right += dw; r.top += dh; r.bottom += dh; - SetClientPos (hDlg, GetDlgItem (hDlg, IDC_STATIC1), r); - r = rChck; r.left += dw; r.right += dw; r.top += dh; r.bottom += dh; - SetClientPos (hDlg, GetDlgItem (hDlg, IDC_CHECK1), r); - for (i = 0; i < nSizeElm; i++) { - if (ctab != 1 && (SizeElm[i] == IDC_SLIDER1 || SizeElm[i] == IDC_STATIC1)) continue; - if (ctab == 3 && SizeElm[i] == IDC_CHECK1) continue; - ShowWindow (GetDlgItem (hDlg, SizeElm[i]), SW_SHOW); - } - return DialogWin::OnSize (hDlg, wParam, w, h); -} - -// ====================================================================== - -BOOL DlgFocus::OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl) -{ - switch (id) { - case IDC_EDIT1: - if (code == EN_CHANGE) WatchEdit (hDlg); - return TRUE; - case IDC_CHECK1: - if (code == BN_CLICKED) WatchAssemblyUnroll (hDlg); - return TRUE; - case IDC_BUTTON1: - SelectPreviousVessel (hDlg); - return TRUE; - case IDHELP: - DefHelpContext.topic = (char*)"/selvessel.htm"; - g_pOrbiter->OpenHelp (&DefHelpContext); - return TRUE; - case IDOK: - return SelectVessel (hDlg); - } - return DialogWin::OnCommand (hDlg, id, code, hControl); -} - -// ====================================================================== - -BOOL DlgFocus::OnNotify (HWND hDlg, int idCtrl, LPNMHDR pnmh) -{ - switch (pnmh->idFrom) { - case IDC_TAB1: - return OnNotifyTab (hDlg, pnmh); - case IDC_TREE1: - return OnNotifyTree (hDlg, pnmh); - } - return FALSE; -} - -// ====================================================================== - -BOOL DlgFocus::OnNotifyTab (HWND hDlg, LPNMHDR pnmh) -{ - if (pnmh->code == TCN_SELCHANGE) SwitchTab (hDlg); - return FALSE; -} - -// ====================================================================== - -BOOL DlgFocus::OnNotifyTree (HWND hDlg, LPNMHDR pnmh) -{ - NM_TREEVIEW *pnmtv = (NM_TREEVIEW FAR *)pnmh; - if (pnmtv->hdr.code == TVN_SELCHANGED) { - HTREEITEM hti = pnmtv->itemNew.hItem; - bool ok = true; - if (ctab >= 2) - ok = (SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hti) != 0); - if (ok) { - TVITEM tvi; - char cbuf[256]; - tvi.hItem = hti; - tvi.pszText = cbuf; - tvi.cchTextMax = 256; - tvi.mask = TVIF_TEXT; - BOOL res = SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETITEM, 0, (LPARAM)&tvi); - Vessel *vessel = g_psys->GetVessel (cbuf, true); - if (!vessel) vessel = g_focusobj; - strcpy (cbuf, vessel->Name()); - SetWindowText (GetDlgItem (hDlg, IDC_EDIT1), cbuf); - EnableWindow (GetDlgItem (hDlg, IDOK), vessel == g_focusobj ? FALSE : TRUE); - } - } - return FALSE; -} - -// ====================================================================== - -BOOL DlgFocus::OnHScroll (HWND hDlg, WORD request, WORD curpos, HWND hControl) -{ - int irange_old = irange; - irange = SendDlgItemMessage (hDlg, IDC_SLIDER1, TBM_GETPOS, 0, 0); - if (irange != irange_old) { - SetRangeLabel (hDlg, irange); - RescanTree_Nearby (hDlg); - return TRUE; - } - return DialogWin::OnHScroll (hDlg, request, curpos, hControl); -} - -// ====================================================================== - -void DlgFocus::SetRangeLabel (HWND hDlg, int irange) -{ - char cbuf[256] = "Range: "; - if (irange == 1) strcpy (cbuf+7, "0.1"); - else if (irange <= 4) { - int i, e=1; - for (i = 2; i < irange; i++) e *= 10; - sprintf (cbuf+7, "%d", e); - } else sprintf (cbuf+7, "1E%d", irange-2); - strcat (cbuf, " km"); - SetWindowText (GetDlgItem (hDlg, IDC_STATIC1), cbuf); -} - -// ====================================================================== - -void DlgFocus::WatchEdit (HWND hDlg) -{ - char cbuf[256]; - GetWindowText (GetDlgItem (hDlg, IDC_EDIT1), cbuf, 256); - Vessel *vessel = g_psys->GetVessel (cbuf, true); - EnableWindow (GetDlgItem (hDlg, IDOK), vessel && vessel != g_focusobj ? TRUE:FALSE); -} - -// ====================================================================== - -void DlgFocus::WatchAssemblyUnroll (HWND hDlg) -{ - bool old_unroll = unroll_assemblies; - unroll_assemblies = (SendDlgItemMessage (hDlg, IDC_CHECK1, BM_GETCHECK, 0, 0) == BST_CHECKED); - if (unroll_assemblies != old_unroll) { - SwitchTab (hDlg); - } -} - -// ====================================================================== - -BOOL DlgFocus::OnUserMessage (HWND hDlg, WPARAM wParam, LPARAM lParam) -{ - EnableWindow (GetDlgItem (hWnd, IDC_BUTTON1), g_pfocusobj ? TRUE:FALSE); - switch (wParam) { - case MSG_CREATEVESSEL: - case MSG_KILLVESSEL: - SwitchTab (hDlg); - return TRUE; - case MSG_FOCUSVESSEL: - UpdateFocus (hDlg); - return TRUE; - } - return FALSE; -} - -// ====================================================================== - -void DlgFocus::SwitchTab (HWND hDlg) -{ - HWND hTab = GetDlgItem (hDlg, IDC_TAB1); - HWND hTree = GetDlgItem (hDlg, IDC_TREE1); - ctab = TabCtrl_GetCurSel (hTab); - - LONG ws = GetWindowLongPtr (hTree, GWL_STYLE); - if (ctab < 2) ws &= ~TVS_LINESATROOT; - else ws |= TVS_LINESATROOT; - SetWindowLongPtr (hTree, GWL_STYLE, ws); - - switch (ctab) { - case 0: - RescanTree_All (hDlg); - break; - case 1: - RescanTree_Nearby (hDlg); - break; - case 2: - RescanTree_Location (hDlg); - break; - case 3: - RescanTree_Class (hDlg); - break; - } - SetWindowText (GetDlgItem (hDlg, IDC_EDIT1), g_focusobj->Name()); - - int showrange = (ctab == 1 ? SW_SHOW : SW_HIDE); - ShowWindow (GetDlgItem (hDlg, IDC_STATIC1), showrange); - ShowWindow (GetDlgItem (hDlg, IDC_SLIDER1), showrange); - ShowWindow (GetDlgItem (hDlg, IDC_CHECK1), ctab == 3 ? SW_HIDE : SW_SHOW); -} - -// ====================================================================== - -void DlgFocus::RescanTree_All (HWND hDlg) -{ - char cbuf[256]; cbuf[255] = '\0'; - HTREEITEM hti, hti_focus = NULL; - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_DELETEITEM, 0, 0); - for (DWORD i = 0; i < g_psys->nVessel(); i++) { - Vessel *vessel = g_psys->GetVessel(i); - if (vessel->GetEnableFocus()) { - hti = AddVesselToTree (hDlg, NULL, vessel); - if (hti) hti_focus = hti; - } - } - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hti_focus); -} - -// ====================================================================== - -void DlgFocus::RescanTree_Nearby (HWND hDlg) -{ - double range = pow(10.0,(double)(irange+1)); - char cbuf[256]; cbuf[255] = '\0'; - HTREEITEM hti, hti_focus = NULL; - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_DELETEITEM, 0, 0); - const Vector &campos = g_camera->GPos(); - for (DWORD i = 0; i < g_psys->nVessel(); i++) { - Vessel *vessel = g_psys->GetVessel(i); - if (vessel->GetEnableFocus()) { - double dst = campos.dist (vessel->GPos()); - if (dst <= range) { - hti = AddVesselToTree (hDlg, NULL, vessel); - if (hti) hti_focus = hti; - } - } - } - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hti_focus); -} - -// ====================================================================== - -void DlgFocus::RescanTree_Location (HWND hDlg) -{ - HTREEITEM hti, hti_ref, hti_focus = NULL; - TV_INSERTSTRUCT tvis; - TVITEM tvi; - char cbuf[256]; cbuf[255] = '\0'; - - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_DELETEITEM, 0, 0); - - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN; - tvis.item.cChildren = 1; - - tvi.mask = TVIF_TEXT; - tvi.pszText = cbuf; - tvi.cchTextMax = 255; - - for (DWORD i = 0; i < g_psys->nVessel(); i++) { +DlgFocus::DlgFocus() : ImGuiDialog("Orbiter: Select spacecraft", {300, 320}) { +} + +void DlgFocus::OnDraw() { + const char *tabs[] = { + "All", "Nearby", "Location", "Class" + }; + + void (DlgFocus::* func[])() = { + &DlgFocus::DrawAll, &DlgFocus::DrawNearby, &DlgFocus::DrawLocation, &DlgFocus::DrawClass + }; + + ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None; + if (ImGui::BeginTabBar("FocusTabBar", tab_bar_flags)) + { + for(size_t i = 0; i*func[i])(); + ImGui::EndTabItem(); + } + } + ImGui::EndTabBar(); + } +} + +void DlgFocus::DrawAll() { + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGui::Text("Spacecraft : %s", m_SelectedShip.c_str()); + ImGui::BeginChild("ChildL", ImVec2(150, 0), true, window_flags); + + for (int i = 0; i < g_psys->nVessel(); i++) { + Vessel *vessel = g_psys->GetVessel(i); + if (vessel->GetEnableFocus()) { + std::string name = vessel->Name(); + const bool is_selected = m_SelectedShip == name; + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + ImGui::TreeNodeEx(vessel->Name(), node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) { + m_SelectedShip = vessel->Name(); + } + } + } + + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("ChildR"); + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + if(ImGui::Button("Select", button_sz)) { + Vessel *vessel = g_psys->GetVessel (m_SelectedShip.c_str(), true); + if (vessel) { + g_pOrbiter->SetFocusObject (vessel); + } + } + if(ImGui::Button("Previous", button_sz)) { + if (g_pfocusobj) { + g_pOrbiter->SetFocusObject (g_pfocusobj); + m_SelectedShip = g_pfocusobj->Name(); + } + } + ImGui::EndChild(); +} +void DlgFocus::DrawNearby() { + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGui::Text("Spacecraft : %s", m_SelectedShip.c_str()); + ImGui::BeginChild("ChildL", ImVec2(150, 0), true, window_flags); + + const Vector &campos = g_camera->GPos(); + for (int i = 0; i < g_psys->nVessel(); i++) { + Vessel *vessel = g_psys->GetVessel(i); + if (vessel->GetEnableFocus()) { + double dst = campos.dist (vessel->GPos()); + if (dst <= m_Range * 1000.0f) { + std::string name = vessel->Name(); + const bool is_selected = m_SelectedShip == name; + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + char cbuf[128]; + sprintf(cbuf,"%s (%.1fkm)", vessel->Name(), dst/1000.0f); + ImGui::TreeNodeEx(cbuf, node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) { + m_SelectedShip = vessel->Name(); + } + } + } + } + + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("ChildR"); + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + if(ImGui::Button("Select", button_sz)) { + Vessel *vessel = g_psys->GetVessel (m_SelectedShip.c_str(), true); + if (vessel) { + g_pOrbiter->SetFocusObject (vessel); + } + } + if(ImGui::Button("Previous", button_sz)) { + if (g_pfocusobj) { + g_pOrbiter->SetFocusObject (g_pfocusobj); + m_SelectedShip = g_pfocusobj->Name(); + } + } + + ImGui::SetNextItemWidth(-FLT_MIN); + if(ImGui::SliderFloat("##slider warp", &m_Range, 1.0f, 1000000.0f, "%.1fkm", ImGuiSliderFlags_Logarithmic)) { + } + + ImGui::EndChild(); +} +void DlgFocus::DrawLocation() { + std::map> vesselMap; + for (int i = 0; i < g_psys->nVessel(); i++) { Vessel *vessel = g_psys->GetVessel(i); if (vessel->GetEnableFocus()) { const CelestialBody *ref = vessel->ElRef(); - // enter under reference body - hti_ref = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETNEXTITEM, TVGN_ROOT, 0); - while (hti_ref) { - tvi.hItem = hti_ref; - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETITEM, 0, (LPARAM)&tvi); - if (!strcmp (tvi.pszText, ref->Name())) - break; - hti_ref = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hti_ref); - } - if (!hti_ref) { - tvis.item.pszText = (char*)ref->Name(); - hti_ref = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_INSERTITEM, 0, (LPARAM)&tvis); - } - hti = AddVesselToTree (hDlg, hti_ref, vessel); - if (hti) hti_focus = hti; - } - } - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hti_focus); -} - -// ====================================================================== - -void DlgFocus::RescanTree_Class (HWND hDlg) -{ - HTREEITEM hti, hti_ref, hti_focus = NULL; - TV_INSERTSTRUCT tvis; - TVITEM tvi; - char cbuf[256]; cbuf[255] = '\0'; - - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_DELETEITEM, 0, 0); - - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN; - tvis.item.cChildren = 1; - - tvi.mask = TVIF_TEXT; - tvi.pszText = cbuf; - tvi.cchTextMax = 255; - - for (DWORD i = 0; i < g_psys->nVessel(); i++) { + vesselMap[ref->Name()].push_back(vessel); + } + } + + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGui::Text("Spacecraft : %s", m_SelectedShip.c_str()); + ImGui::BeginChild("ChildL", ImVec2(150,0), true, window_flags); + + for(auto &kw : vesselMap) { + if(ImGui::TreeNodeEx(kw.first)) { + for(auto &vessel: kw.second) { + const bool is_selected = m_SelectedShip == vessel->Name(); + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + ImGui::TreeNodeEx(vessel->Name(), node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) { + m_SelectedShip = vessel->Name(); + } + } + + ImGui::TreePop(); + } + } + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("ChildR"); + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + if(ImGui::Button("Select", button_sz)) { + Vessel *vessel = g_psys->GetVessel (m_SelectedShip.c_str(), true); + if (vessel) { + g_pOrbiter->SetFocusObject (vessel); + } + } + if(ImGui::Button("Previous", button_sz)) { + if (g_pfocusobj) { + g_pOrbiter->SetFocusObject (g_pfocusobj); + m_SelectedShip = g_pfocusobj->Name(); + } + } + + ImGui::EndChild(); +} +void DlgFocus::DrawClass() { + std::map> vesselMap; + for (int i = 0; i < g_psys->nVessel(); i++) { Vessel *vessel = g_psys->GetVessel(i); if (vessel->GetEnableFocus()) { - // enter under reference body - hti_ref = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETNEXTITEM, TVGN_ROOT, 0); - while (hti_ref) { - tvi.hItem = hti_ref; - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETITEM, 0, (LPARAM)&tvi); - if (!_stricmp (tvi.pszText, vessel->ClassName())) - break; - hti_ref = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hti_ref); - } - if (!hti_ref) { - strncpy (cbuf, vessel->ClassName(), 255); - tvis.item.pszText = cbuf; - hti_ref = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_INSERTITEM, 0, (LPARAM)&tvis); - } - hti = AddVesselToTree (hDlg, hti_ref, vessel); - if (hti) hti_focus = hti; - } - } - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hti_focus); -} - -// ====================================================================== - -HTREEITEM DlgFocus::AddVesselToTree (HWND hDlg, HTREEITEM hti, Vessel *vessel, bool force) -{ - bool unroll = (unroll_assemblies || ctab == 3); - if (!unroll && vessel->isAttached() && !force) return NULL; - HTREEITEM hti_focus = NULL; - DWORD i; - - SuperVessel *assembly = NULL; - if (!unroll && (assembly = vessel->SuperStruct())) { - char cbuf[256], assembly_name[256]; - Vessel *vessel0 = assembly->GetVessel(0); - sprintf (assembly_name, "%s [assembly]", vessel0->Name()); - TVITEM tvi; - tvi.mask = TVIF_TEXT; - tvi.pszText = cbuf; - tvi.cchTextMax = 255; - HTREEITEM hti_assembly = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hti); - while (hti_assembly) { - tvi.hItem = hti_assembly; - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETITEM, 0, (LPARAM)&tvi); - if (!_stricmp (tvi.pszText, assembly_name)) - break; - hti_assembly = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hti_assembly); - } - if (!hti_assembly) { - TV_INSERTSTRUCT tvis; - tvis.hParent = hti; - tvis.hInsertAfter = TVI_SORT; - tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN; - tvis.item.cChildren = 1; - tvis.item.pszText = assembly_name; - hti_assembly = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_INSERTITEM, 0, (LPARAM)&tvis); - } - hti = hti_assembly; - } - TV_INSERTSTRUCT tvis; - tvis.hParent = hti; - tvis.hInsertAfter = TVI_SORT; - tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN; - tvis.item.pszText = (char*)vessel->Name(); - tvis.item.cChildren = 0; - if (!unroll) { - for (i = 0; ; i++) { - AttachmentSpec *as = vessel->GetAttachmentFromIndex (false, i); - if (!as) break; - if (as->mate) {tvis.item.cChildren = 1; break; } - } - } - HTREEITEM hti_vessel = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_INSERTITEM, 0, (LPARAM)&tvis); - if (tvis.item.cChildren) { - for (i = 0; ; i++) { - AttachmentSpec *as = vessel->GetAttachmentFromIndex (false, i); - if (!as) break; - if (as->mate) { - HTREEITEM hti_child = AddVesselToTree (hDlg, hti_vessel, as->mate, true); - if (hti_child) hti_focus = hti_child; - } - } - } - return (vessel == g_focusobj ? hti_vessel : hti_focus); -} - -// ====================================================================== - -BOOL DlgFocus::SelectVessel (HWND hDlg) -{ - char cbuf[256]; - GetWindowText (GetDlgItem (hDlg, IDC_EDIT1), cbuf, 256); - Vessel *vessel = g_psys->GetVessel (cbuf, true); - if (vessel) { - SetWindowText (GetDlgItem (hDlg, IDC_EDIT1), vessel->Name()); - g_pOrbiter->SetFocusObject (vessel); - HTREEITEM hti = FindItem (hDlg, vessel->Name(), 0); - if (hti) - PostMessage (GetDlgItem (hDlg, IDC_TREE1), TVM_SELECTITEM, TVGN_CARET, (LPARAM)hti); - } else { - SetWindowText (GetDlgItem (hDlg, IDC_EDIT1), g_focusobj->Name()); - MessageBeep (MB_ICONEXCLAMATION); - } - WatchEdit (hDlg); - return TRUE; + vesselMap[vessel->ClassName()].push_back(vessel); + } + } + + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGui::Text("Spacecraft : %s", m_SelectedShip.c_str()); + ImGui::BeginChild("ChildL", ImVec2(150,0), true, window_flags); + + for(auto &kw : vesselMap) { + if(ImGui::TreeNodeEx(kw.first.c_str())) { + for(auto &vessel: kw.second) { + const bool is_selected = m_SelectedShip == vessel->Name(); + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + ImGui::TreeNodeEx(vessel->Name(), node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) { + m_SelectedShip = vessel->Name(); + } + } + + ImGui::TreePop(); + } + } + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("ChildR"); + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + if(ImGui::Button("Select", button_sz)) { + Vessel *vessel = g_psys->GetVessel (m_SelectedShip.c_str(), true); + if (vessel) { + g_pOrbiter->SetFocusObject (vessel); + } + } + if(ImGui::Button("Previous", button_sz)) { + if (g_pfocusobj) { + g_pOrbiter->SetFocusObject (g_pfocusobj); + m_SelectedShip = g_pfocusobj->Name(); + } + } + + ImGui::EndChild(); } - -// ====================================================================== - -void DlgFocus::SelectPreviousVessel (HWND hDlg) -{ - if (g_pfocusobj) { - SetWindowText (GetDlgItem (hDlg, IDC_EDIT1), g_pfocusobj->Name()); - SelectVessel (hDlg); - } -} - -// ====================================================================== - -void DlgFocus::UpdateFocus (HWND hDlg) -{ - char cbuf[256]; - GetWindowText (GetDlgItem (hDlg, IDC_EDIT1), cbuf, 256); - if (strcmp (cbuf, g_focusobj->Name())) { - SetWindowText (GetDlgItem (hDlg, IDC_EDIT1), g_focusobj->Name()); - HTREEITEM hti = FindItem (hDlg, g_focusobj->Name(), 0); - if (hti) - PostMessage (GetDlgItem (hDlg, IDC_TREE1), TVM_SELECTITEM, TVGN_CARET, (LPARAM)hti); - } -} - -// ====================================================================== - -HTREEITEM DlgFocus::FindItem (HWND hDlg, const char *str, HTREEITEM hti_first) -{ - HTREEITEM hti_match = NULL; - TVITEM tvi; - - char cbuf[256]; cbuf[255] = '\0'; - tvi.mask = TVIF_TEXT | TVIF_CHILDREN; - tvi.pszText = cbuf; - tvi.cchTextMax = 255; - - if (!hti_first) - hti_first = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETNEXTITEM, TVGN_ROOT, 0); - - do { - tvi.hItem = hti_first; - SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETITEM, 0, (LPARAM)&tvi); - if (tvi.cChildren) { - hti_match = FindItem (hDlg, str, (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hti_first)); - if (hti_match) return hti_match; - } else { - if (!strcmp (cbuf, str)) return hti_first; - } - hti_first = (HTREEITEM)SendDlgItemMessage (hDlg, IDC_TREE1, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hti_first); - } while (hti_first); - return NULL; -} \ No newline at end of file diff --git a/Src/Orbiter/DlgFocus.h b/Src/Orbiter/DlgFocus.h index 933a072d2..9d9a3eca2 100644 --- a/Src/Orbiter/DlgFocus.h +++ b/Src/Orbiter/DlgFocus.h @@ -8,42 +8,18 @@ #ifndef __DLGFOCUS_H #define __DLGFOCUS_H -#include "DialogWin.h" -#include "CommCtrl.h" +#include "OrbiterAPI.h" -class DlgFocus: public DialogWin { +class DlgFocus : public ImGuiDialog { public: - DlgFocus (HINSTANCE hInstance, HWND hParent, void *context); - ~DlgFocus (); - BOOL OnInitDialog (HWND hWnd, WPARAM wParam, LPARAM lParam); - BOOL OnSize (HWND hDlg, WPARAM wParam, int w, int h); - BOOL OnCommand (HWND hWnd, WORD id, WORD code, HWND hControl); - BOOL OnUserMessage (HWND hWnd, WPARAM wParam, LPARAM lParam); - BOOL OnNotify (HWND hDlg, int idCtrl, LPNMHDR pnmh); - BOOL OnHScroll (HWND hDlg, WORD request, WORD curpos, HWND hControl); - -protected: - BOOL OnNotifyTab (HWND hDlg, LPNMHDR pnmh); - BOOL OnNotifyTree (HWND hDlg, LPNMHDR pnmh); - void SwitchTab (HWND hDlg); - void RescanTree_All (HWND hDlg); - void RescanTree_Nearby (HWND hDlg); - void RescanTree_Location (HWND hDlg); - void RescanTree_Class (HWND hDlg); - HTREEITEM AddVesselToTree (HWND hDlg, HTREEITEM hti, Vessel *vessel, bool force = false); - BOOL SelectVessel (HWND hDlg); - void SelectPreviousVessel (HWND hDlg); - void UpdateFocus (HWND hDlg); - void WatchEdit (HWND hDlg); - void WatchAssemblyUnroll (HWND hDlg); - void SetRangeLabel (HWND hDlg, int irange); - HTREEITEM FindItem (HWND hDlg, const char *str, HTREEITEM hti_first); - -private: - int ctab; - int irange; - bool unroll_assemblies; - RECT rClient, rTab, rEdit, rTree, rAppl, rPrev, rHelp, rClse, rSldr, rLabl, rChck; + DlgFocus(); + void OnDraw() override; + void DrawAll(); + void DrawNearby(); + void DrawLocation(); + void DrawClass(); + std::string m_SelectedShip; + float m_Range = 1.0; }; #endif // !__DLGFOCUS_H \ No newline at end of file From f2822163bdeff168ae82db62afc1997cf49e34bb Mon Sep 17 00:00:00 2001 From: Gondos Date: Fri, 31 Jan 2025 12:12:18 +0100 Subject: [PATCH 19/51] [ImGui]Convert DlgFunction --- Src/Orbiter/DlgFunction.cpp | 90 +++++++------------------------------ Src/Orbiter/DlgFunction.h | 15 ++----- 2 files changed, 21 insertions(+), 84 deletions(-) diff --git a/Src/Orbiter/DlgFunction.cpp b/Src/Orbiter/DlgFunction.cpp index bcff7a976..1e6ff5d68 100644 --- a/Src/Orbiter/DlgFunction.cpp +++ b/Src/Orbiter/DlgFunction.cpp @@ -5,84 +5,28 @@ // Custom function selection dialog // ====================================================================== -#define STRICT 1 - #include "DlgFunction.h" #include "Orbiter.h" -#include "Resource.h" -#include "Resource2.h" +#include "imgui.h" extern Orbiter *g_pOrbiter; -extern HELPCONTEXT DefHelpContext; - -// ====================================================================== - -DlgFunction::DlgFunction (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_CUSTOMCMD, 0, 0, context) -{ -} - -// ====================================================================== - -void DlgFunction::ScanFunctions (HWND hDlg) -{ - DWORD i, idx; - SendDlgItemMessage (hDlg, IDC_CUSTOMCMD_LIST, LB_RESETCONTENT, 0, 0); - for (i = 0; i < g_pOrbiter->ncustomcmd; i++) - idx = SendDlgItemMessage (hDlg, IDC_CUSTOMCMD_LIST, LB_ADDSTRING, 0, (LPARAM)g_pOrbiter->customcmd[i].label); - if (i) SendDlgItemMessage (hDlg, IDC_CUSTOMCMD_LIST, LB_SETCURSEL, 0, 0); -} - -// ====================================================================== -void DlgFunction::RunFunction (HWND hDlg) -{ - int idx = SendDlgItemMessage (hDlg, IDC_CUSTOMCMD_LIST, LB_GETCURSEL, 0, 0); - if (idx != LB_ERR) g_pOrbiter->customcmd[idx].func (g_pOrbiter->customcmd[idx].context); +DlgFunction::DlgFunction() : ImGuiDialog("Orbiter: Custom functions", {340, 290}) { } -// ====================================================================== - -void DlgFunction::ShowDescription (HWND hDlg) -{ - int idx = SendDlgItemMessage (hDlg, IDC_CUSTOMCMD_LIST, LB_GETCURSEL, 0, 0); - if (idx != LB_ERR) - SetWindowText (GetDlgItem (hDlg, IDC_CUSTOMCMD_DESCR), g_pOrbiter->customcmd[idx].desc); -} - -// ====================================================================== - -BOOL DlgFunction::OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam) -{ - ScanFunctions (hDlg); - ShowDescription (hDlg); - return TRUE; -} - -// ====================================================================== - -BOOL DlgFunction::OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl) -{ - switch (id) { - case IDHELP: - DefHelpContext.topic = (char*)"/customcmd.htm"; - g_pOrbiter->OpenHelp (&DefHelpContext); - return TRUE; - case IDOK: - RunFunction (hDlg); - g_pOrbiter->CloseDialog (hDlg); - return TRUE; - case IDC_CUSTOMCMD_LIST: - switch (code) { - case LBN_DBLCLK: - RunFunction (hDlg); - g_pOrbiter->CloseDialog (hDlg); - return TRUE; - case LBN_SELCHANGE: - ShowDescription (hDlg); - return TRUE; - } - break; - } - return DialogWin::OnCommand (hDlg, id, code, hControl); +void DlgFunction::OnDraw() { + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + for (int i = 0; i < g_pOrbiter->ncustomcmd; i++) { + if(ImGui::Button(g_pOrbiter->customcmd[i].label, button_sz)) { + g_pOrbiter->customcmd[i].func (g_pOrbiter->customcmd[i].context); + } + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); + ImGui::TextUnformatted(g_pOrbiter->customcmd[i].desc); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + } } diff --git a/Src/Orbiter/DlgFunction.h b/Src/Orbiter/DlgFunction.h index 16c9fac57..bd638e23a 100644 --- a/Src/Orbiter/DlgFunction.h +++ b/Src/Orbiter/DlgFunction.h @@ -8,18 +8,11 @@ #ifndef __DLGFUNCTION_H #define __DLGFUNCTION_H -#include "DialogWin.h" +#include "OrbiterAPI.h" -class DlgFunction: public DialogWin { +class DlgFunction : public ImGuiDialog { public: - DlgFunction (HINSTANCE hInstance, HWND hParent, void *context); - BOOL OnInitDialog (HWND hWnd, WPARAM wParam, LPARAM lParam); - BOOL OnCommand (HWND hWnd, WORD id, WORD code, HWND hControl); - -protected: - void ScanFunctions (HWND hDlg); - void RunFunction (HWND hDlg); - void ShowDescription (HWND hDlg); + DlgFunction(); + void OnDraw() override; }; - #endif // !__DLGFUNCTION_H \ No newline at end of file From b87d4570700eaba87a77753717ae8ff8cd7ef5c3 Mon Sep 17 00:00:00 2001 From: Gondos Date: Fri, 31 Jan 2025 14:13:01 +0100 Subject: [PATCH 20/51] [ImGui]Convert DlgInfo --- Src/Orbiter/Astro.cpp | 2 +- Src/Orbiter/DlgInfo.cpp | 1893 ++++++++++++++++++--------------------- Src/Orbiter/DlgInfo.h | 85 +- Src/Orbiter/DlgMap.cpp | 4 - 4 files changed, 868 insertions(+), 1116 deletions(-) diff --git a/Src/Orbiter/Astro.cpp b/Src/Orbiter/Astro.cpp index f236a05d6..13eb3cd9a 100644 --- a/Src/Orbiter/Astro.cpp +++ b/Src/Orbiter/Astro.cpp @@ -208,7 +208,7 @@ char *SciStr (double f, int precision, char prefix) for (i = 0; i < len; i++) { if (strbuf[i] == 'e') { sscanf(strbuf+i+1, "%d", &e); - sprintf (strbuf+i, "10^%d", e); + sprintf (strbuf+i, u8"10^%d", e); } } return strbuf; diff --git a/Src/Orbiter/DlgInfo.cpp b/Src/Orbiter/DlgInfo.cpp index 87c574342..2dba97c85 100644 --- a/Src/Orbiter/DlgInfo.cpp +++ b/Src/Orbiter/DlgInfo.cpp @@ -1,856 +1,673 @@ -// Copyright (c) Martin Schweiger +// Copyright (c) Martin Schweiger // Licensed under the MIT License // ====================================================================== // Object info window // ====================================================================== - -#define STRICT 1 -#define _WIN32_WINNT 0x0501 -#define OAPI_IMPLEMENTATION - -#include #include "DlgInfo.h" -#include "Dialogs.h" -#include "Resource.h" -#include "DlgMgr.h" // to be removed -#include "Orbiter.h" -#include "Vessel.h" -#include "Camera.h" -#include "Psys.h" #include "Celbody.h" -#include -#include -#include +#include "Psys.h" +#include "Astro.h" #include "Element.h" +#include "imgui.h" -extern Orbiter *g_pOrbiter; -extern Vessel *g_focusobj; -extern Camera *g_camera; extern PlanetarySystem *g_psys; -extern TimeData td; -extern HELPCONTEXT DefHelpContext; -extern char DBG_MSG[256]; - -const char *na = "N/A"; - -// ====================================================================== - -DlgInfo::DlgInfo (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_OBJINFO, 0, 0, context) -{ - upd_t = 0.0; - upd_dt = 1.0; - body = NULL; - listmode = LIST_NONE; - pos = &g_pOrbiter->Cfg()->CfgWindowPos.DlgInfo; - - // note: shared icon resources should probably be loaded globally by orbiter - hIcon_dd = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_DDOWN)); - hIcon_du = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_DUP)); -} - -// ====================================================================== - -void DlgInfo::Init (HWND hDlg) -{ - RECT r; - POINT pt; - PARAFORMAT2 pfmt; - pfmt.cbSize = sizeof(PARAFORMAT2); - pfmt.dwMask = PFM_TABSTOPS; - pfmt.cTabCount = 1; - pfmt.rgxTabs[0] = 200; - int objtp = 0; - - SendDlgItemMessage (hDlg, IDC_INFO_TYPE, CB_ADDSTRING, 0, (LPARAM)"Focus vessel"); - SendDlgItemMessage (hDlg, IDC_INFO_TYPE, CB_ADDSTRING, 0, (LPARAM)"Camera target"); - SendDlgItemMessage (hDlg, IDC_INFO_TYPE, CB_ADDSTRING, 0, (LPARAM)"Vessel"); - SendDlgItemMessage (hDlg, IDC_INFO_TYPE, CB_ADDSTRING, 0, (LPARAM)"Base"); - SendDlgItemMessage (hDlg, IDC_INFO_TYPE, CB_ADDSTRING, 0, (LPARAM)"Celestial body"); - if (body) { - switch (body->Type()) { - case OBJTP_VESSEL: objtp = 2; break; - case OBJTP_SURFBASE: objtp = 3; break; - case OBJTP_PLANET: - case OBJTP_STAR: objtp = 4; break; - } - } - SendDlgItemMessage (hDlg, IDC_INFO_TYPE, CB_SETCURSEL, objtp, 0); - - SendDlgItemMessage (hDlg, IDC_INFO_DDN, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon_dd); - SendDlgItemMessage (hDlg, IDC_INFO_DUP, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon_du); - - int res = SendDlgItemMessage (hDlg, IDC_INFOBOX, EM_SETPARAFORMAT, 0, (LPARAM)&pfmt); - GetClientRect (hDlg, &r); - client_w = r.right; - client_h = r.bottom; - GetWindowRect (GetDlgItem (hDlg, IDC_INFOLIST), &r); - list_w = r.right-r.left; - list_h = r.bottom-r.top; - pt.x = r.left; - pt.y = r.top; - ScreenToClient (hDlg, &pt); - list_top = pt.y; - pl.OnInitDialog (hDlg, IDC_INFOLIST); - pl.SetColWidth (0, 180); - - Body *b = body; - if (!b) b = g_focusobj; - body = NULL; - - SetBody (hDlg, b); - BuildObjectList (hDlg, b); - if (objtp) { - int idx = SendDlgItemMessage (hDlg, IDC_INFO_NAME, CB_FINDSTRINGEXACT, 0, (LPARAM)body->Name()); - if (idx != CB_ERR) - SendDlgItemMessage (hDlg, IDC_INFO_NAME, CB_SETCURSEL, idx, 0); - } -} - -// ====================================================================== - -void DlgInfo::SetBody (Body *bd) -{ - SetBody (hWnd, bd); - Init (hWnd); -} - -// ====================================================================== - -void DlgInfo::BuildObjectList (HWND hDlg, Body *b) -{ - Body *obj; - char cbuf[256]; - int j; - DWORD k; - int idx = SendDlgItemMessage (hDlg, IDC_INFO_TYPE, CB_GETCURSEL, 0, 0); - SendDlgItemMessage (hDlg, IDC_INFO_NAME, CB_RESETCONTENT, 0, 0); - - switch (idx) { - case 0: // focus vessel - strcpy (cbuf, g_focusobj->Name()); - SendDlgItemMessage (hDlg, IDC_INFO_NAME, CB_ADDSTRING, 0, (LPARAM)cbuf); - break; - case 1: // camera target - strcpy (cbuf, g_camera->Target()->Name()); - SendDlgItemMessage (hDlg, IDC_INFO_NAME, CB_ADDSTRING, 0, (LPARAM)cbuf); - break; - case 2: // vessels - for (k = 0; k < g_psys->nVessel(); k++) { - strcpy (cbuf, g_psys->GetVessel(k)->Name()); - SendDlgItemMessage (hDlg, IDC_INFO_NAME, CB_ADDSTRING, 0, (LPARAM)cbuf); - } - break; - case 3: // spaceports - for (k = 0; k < g_psys->nGrav(); k++) { - obj = g_psys->GetGravObj (k); - if (obj->Type() != OBJTP_PLANET) continue; - Planet *planet = (Planet*)obj; - for (j = 0; j < g_psys->nBase(planet); j++) { - strcpy (cbuf, g_psys->GetBase (planet,j)->Name()); - SendDlgItemMessage (hDlg, IDC_INFO_NAME, CB_ADDSTRING, 0, (LPARAM)cbuf); - } - } - break; - case 4: // celestial bodies - CBodySelectComboBox::BuildListFromNode (hDlg, IDC_INFO_NAME, (CelestialBody*)b); - return; - } - SendDlgItemMessage (hDlg, IDC_INFO_NAME, CB_SETCURSEL, 0, 0); - //Info_ShowData (hDlg); -} - -// ====================================================================== - -int DlgInfo::Size (DWORD width, DWORD height) -{ - int i, id; - RECT r; - POINT pt; - GetClientRect (hWnd, &r); - int dw = r.right-client_w; - int dh = r.bottom-client_h; - list_w += dw; - list_h += dh; - client_w = r.right; - client_h = r.bottom; - pl.Move (0, list_top, list_w, list_h); - - const int nbtl = 2; - const int btlid[nbtl] = {IDC_INFO_DDN, IDC_INFO_DUP}; - for (i = 0; i < nbtl; i++) { - id = btlid[i]; - GetWindowRect (GetDlgItem (hWnd, id), &r); - pt.x = r.left; - pt.y = r.top; - ScreenToClient (hWnd, &pt); - MoveWindow (GetDlgItem (hWnd, id), pt.x, pt.y+dh, r.right-r.left, r.bottom-r.top, TRUE); - } - const int nbtr = 3; - const int btrid[nbtr] = {IDC_INFO_MAP, IDCANCEL, IDHELP}; - for (i = 0; i < nbtr; i++) ShowWindow (GetDlgItem (hWnd, btrid[i]), SW_HIDE); - for (i = 0; i < nbtr; i++) { - id = btrid[i]; - GetWindowRect (GetDlgItem (hWnd, id), &r); - pt.x = r.left; - pt.y = r.top; - ScreenToClient (hWnd, &pt); - MoveWindow (GetDlgItem (hWnd, id), pt.x+dw, pt.y+dh, r.right-r.left, r.bottom-r.top, TRUE); - } - for (i = 0; i < nbtr; i++) ShowWindow (GetDlgItem (hWnd, btrid[i]), SW_SHOW); - return 0; -} - -// ====================================================================== - -void DlgInfo::OpenMap () -{ - if (body) { - DlgMap *pMap = g_pOrbiter->DlgMgr()->EnsureEntry (); - pMap->SetSelection (body); - } -} - -// ====================================================================== - -void DlgInfo::ExpandAll (HWND hDlg) -{ - pl.ExpandAll (true); -} - -// ====================================================================== -void DlgInfo::CollapseAll (HWND hDlg) -{ - pl.ExpandAll (false); +DlgInfo::DlgInfo() : ImGuiDialog("Orbiter: Object info", {340, 290}) { } -// ====================================================================== - -void DlgInfo::Update () -{ - if (td.SysT0 > upd_t + upd_dt || td.SysT0 < upd_t) { - switch (listmode) { - case LIST_VESSEL: - UpdateItems_vessel (); - break; - case LIST_CBODY: - UpdateItems_celbody (); - break; - case LIST_BASE: - UpdateItems_base (); - break; - } - pl.Update (); - upd_t = td.SysT0; - } +void DlgInfo::AddCbodyNode(const CelestialBody *cbody) { + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth; + const bool is_selected = m_SelectedTarget == cbody->Name(); + if (is_selected) + node_flags |= ImGuiTreeNodeFlags_Selected; + if(cbody->nSecondary()) { + bool node_open = ImGui::TreeNodeEx(cbody->Name(), node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + m_SelectedTarget = cbody->Name(); + if(node_open) { + for (int i = 0; i < cbody->nSecondary(); i++) { + AddCbodyNode (cbody->Secondary(i)); + } + ImGui::TreePop(); + } + } else { + ImGui::TreeNodeEx(cbody->Name(), node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + m_SelectedTarget = cbody->Name(); + } } -// ====================================================================== - -void DlgInfo::SelectionChanged (HWND hDlg) -{ - char cbuf[256]; - int i, j; - - int tp = SendDlgItemMessage (hDlg, IDC_INFO_TYPE, CB_GETCURSEL, 0, 0); - GetWindowText (GetDlgItem (hDlg, IDC_INFO_NAME), cbuf, 256); - - if (tp == 1) { // camera target - Body *b = g_psys->GetObj (cbuf); - if (!b) b = g_psys->GetBase (cbuf); - if (!b) return; - switch (b->Type()) { - case OBJTP_VESSEL: - tp = 2; - break; - case OBJTP_SURFBASE: - tp = 3; - break; - case OBJTP_STAR: - case OBJTP_PLANET: - tp = 4; - break; - } - } - switch (tp) { - case 0: // focus vessel - SetBody (hDlg, g_focusobj); - break; - case 2: // vessel - SetBody (hDlg, g_psys->GetVessel (cbuf)); - break; - case 3: // surface base - for (i = 0; i < g_psys->nGrav(); i++) { - Body *obj; - obj = g_psys->GetGravObj (i); - if (obj->Type() != OBJTP_PLANET) continue; - Planet *planet = (Planet*)obj; - for (j = 0; j < g_psys->nBase(planet); j++) { - if (!_stricmp (g_psys->GetBase (planet,j)->Name(), cbuf)) { - SetBody (hDlg, g_psys->GetBase (planet,j)); - break; +void DlgInfo::DrawTree() { + for (int i = 0; i < g_psys->nStar(); i++) + AddCbodyNode (g_psys->GetStar(i)); + + if (ImGui::TreeNode("Spaceports")) { + for (int i = 0; i < g_psys->nGrav(); i++) { + Body *obj = g_psys->GetGravObj (i); + if (obj->Type() != OBJTP_PLANET) continue; + Planet *planet = (Planet*)obj; + if (g_psys->nBase(planet) > 0) { + if(ImGui::TreeNode(planet->Name())) { + for (int j = 0; j < g_psys->nBase(planet); j++) { + const char *name = g_psys->GetBase (planet,j)->Name(); + const bool is_selected = m_SelectedTarget == name; + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + ImGui::TreeNodeEx(name, node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + m_SelectedTarget = name; + } + ImGui::TreePop(); } - } - } - break; - case 4: { // celestial bodies - CelestialBody *cbody = CBodySelectComboBox::OnSelectionChanged (hDlg, IDC_INFO_NAME); - if (cbody) SetBody (hDlg, cbody); - } break; - } + } + } + ImGui::TreePop(); + } + if (ImGui::TreeNode("Vessels")) { + for (int i = 0; i < g_psys->nVessel(); i++) { + const char *name = g_psys->GetVessel(i)->Name(); + const bool is_selected = m_SelectedTarget == name; + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + if(is_selected) node_flags |= ImGuiTreeNodeFlags_Selected; + ImGui::TreeNodeEx(name, node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + m_SelectedTarget = name; + } + ImGui::TreePop(); + } } -// ====================================================================== - -void DlgInfo::SetBody (HWND hDlg, Body *bd) -{ - if (bd == body) return; // nothing to do - body = bd; - switch (bd->Type()) { - case OBJTP_VESSEL: - listmode = LIST_VESSEL; - break; - case OBJTP_STAR: - case OBJTP_PLANET: - listmode = LIST_CBODY; - break; - case OBJTP_SURFBASE: - listmode = LIST_BASE; - break; - } - switch (listmode) { - case LIST_VESSEL: - InitItems_vessel (hDlg, (Vessel*)body); - UpdateItems_vessel (); - break; - case LIST_CBODY: - InitItems_celbody (hDlg, (CelestialBody*)body); - UpdateItems_celbody (); - break; - case LIST_BASE: - InitItems_base (hDlg, (Base*)body); - UpdateItems_base (); - break; - } - pl.Redraw(); +void DlgInfo::DrawInfo() { + Vessel *vessel = g_psys->GetVessel(m_SelectedTarget.c_str(), true); + if(vessel) { + DrawInfoVessel(vessel); + return; + } + CelestialBody *cb = g_psys->GetGravObj(m_SelectedTarget.c_str(), true); + if(cb) { + DrawInfoCelestialBody(cb); + return; + } + Base *base = g_psys->GetBase(m_SelectedTarget.c_str(), true); + if(base) { + DrawInfoBase(base); + return; + } + ImGui::Text("Select an object on the left panel"); } -// ====================================================================== - -void DlgInfo::InitItems_vessel (HWND hDlg, const Vessel *vessel) -{ - const int nlabel_des = 3; - const char *label_des[nlabel_des] = { - "Name", - "Class", - "Transponder frequency" - }; - const int nlabel_prm = 5; - const char *label_prm[nlabel_prm] = { - "Total mass", - "Dry mass", - "Propellant mass", - "Mean radius", - "P. moments of inertia" - }; - const int nlabel_thr = 3; - const char *label_thr[nlabel_thr] = { - "Main", - "Retro", - "Hover" - }; - const int nlabel_els = 7; - const char *label_els[nlabel_els] = { - "Reference", - "Semi-major axis (a)", - "Eccentricity (e)", - "Inclination (i)", - "Longitude of asc. node", - "Longitude of periapsis", - "Mean longitude" - }; - const int nlabel_srf = 8; - const char *label_srf[nlabel_srf] = { - "Reference", - "Position", - "Altitude", - "Ground speed", - "Vertical speed", - "Heading", - "Pitch", - "Bank" - }; - const int nlabel_atm = 3; - const char *label_atm[nlabel_atm] = { - "Temperature", - "Density", - "Pressure" - }; - const int nlabel_aer = 8; - const char *label_aer[nlabel_aer] = { - "Dynamic pressure", - "True airspeed", - "Mach number", - "Lift", - "Drag", - "Weight", - "Lift/drag ratio", - "Angle of attack" - }; - const int nlabel_prp = 4; - const char *label_prp[nlabel_prp] = { - "Update mode", - "State propagator", - "Subsamples", - "Gravity sources" - }; - - int i; - PropertyItem *item; - pl.ClearGroups(); - - vlist.des = pl.AppendGroup(); - vlist.des->SetTitle ("Designation"); - for (i = 0; i < nlabel_des; i++) { - item = pl.AppendItem (vlist.des); - item->SetLabel (label_des[i]); - } - - vlist.prm = pl.AppendGroup(); - vlist.prm->SetTitle ("Physical parameters"); - for (i = 0; i < nlabel_prm; i++) { - item = pl.AppendItem (vlist.prm); - item->SetLabel (label_prm[i]); - } - - const THGROUP_TYPE thgrp[3] = {THGROUP_MAIN, THGROUP_RETRO, THGROUP_HOVER}; - bool showthgrp = false; - for (i = 0; i < 3; i++) { - showth[i] = (vessel->GetThrusterGroupMaxth (thgrp[i]) > 0.0); - if (showth[i]) showthgrp = true; - } - if (showthgrp) { - vlist.thr = pl.AppendGroup(); - vlist.thr->SetTitle ("Thruster group ratings (vacuum)"); - for (i = 0; i < nlabel_thr; i++) { - if (showth[i]) { - item = pl.AppendItem (vlist.thr); - item->SetLabel (label_thr[i]); - } - } - } else vlist.thr = NULL; - - vlist.els = pl.AppendGroup (); - vlist.els->SetTitle ("Osculating elements (ecliptic frame)"); - for (i = 0; i < nlabel_els; i++) { - item = pl.AppendItem (vlist.els); - item->SetLabel (label_els[i]); - } - - vlist.srf = pl.AppendGroup(); - vlist.srf->SetTitle ("Surface-relative parameters"); - for (i = 0; i < nlabel_srf; i++) { - item = pl.AppendItem (vlist.srf); - item->SetLabel (label_srf[i]); - } - - vlist.atm = pl.AppendGroup(); - vlist.atm->SetTitle ("Atmospheric parameters"); - for (i = 0; i < nlabel_atm; i++) { - item = pl.AppendItem (vlist.atm); - item->SetLabel (label_atm[i]); - } - - vlist.aer = pl.AppendGroup(); - vlist.aer->SetTitle ("Aerodynamic parameters"); - for (i = 0; i < nlabel_aer; i++) { - item = pl.AppendItem (vlist.aer); - item->SetLabel (label_aer[i]); - } - - if (vessel->nDock()) { - vlist.dck = pl.AppendGroup(); - vlist.dck->SetTitle ("Docking ports"); - char cbuf[64]; - for (i = 0; i < vessel->nDock(); i++) { - item = pl.AppendItem (vlist.dck); - sprintf (cbuf, "Port %d", i+1); - item->SetLabel (cbuf); - } - } else vlist.dck = NULL; - - vlist.prp = pl.AppendGroup(); - vlist.prp->SetTitle ("State propagation"); - for (i = 0; i < nlabel_prp; i++) { - item = pl.AppendItem (vlist.prp); - item->SetLabel (label_prp[i]); - } -} - -// ====================================================================== - -void DlgInfo::UpdateItems_vessel () -{ - const THGROUP_TYPE thgrp[3] = {THGROUP_MAIN, THGROUP_RETRO, THGROUP_HOVER}; - int i, j; - float f; - char cbuf[256]; - - Vessel *vessel = (Vessel*)body; - const Body *ref = vessel->ElRef(); - - vlist.des->GetItem (0)->SetValue (vessel->Name()); - vlist.des->GetItem (1)->SetValue (vessel->ClassName()); - if (vessel->GetXpdrFreq (f)) sprintf (cbuf, "%0.2fMHz", f); - else strcpy (cbuf, na); - vlist.des->GetItem (2)->SetValue (cbuf); - - sprintf (cbuf, "%g kg", vessel->Mass()); - vlist.prm->GetItem (0)->SetValue (cbuf); - sprintf (cbuf, "%g kg", vessel->EmptyMass()); - vlist.prm->GetItem (1)->SetValue (cbuf); - sprintf (cbuf, "%g kg", vessel->FuelMass()); - vlist.prm->GetItem (2)->SetValue (cbuf); - strcpy (cbuf, DistStr (vessel->Size())+1); strcat (cbuf, "m"); - vlist.prm->GetItem (3)->SetValue (cbuf); - sprintf (cbuf, "(%4g, %4g, %4g) m", vessel->PMI().x, vessel->PMI().y, vessel->PMI().z); - vlist.prm->GetItem (4)->SetValue (cbuf); - - if (vlist.thr) { - for (i = j = 0; i < 3; i++) { - if (showth[i]) { - double th = vessel->GetThrusterGroupMaxth (thgrp[i]); - if (th) { - sprintf (cbuf, "%sN", FloatStr (th)+1); - vlist.thr->GetItem (j)->SetValue (cbuf); - } else vlist.thr->GetItem (j)->SetValue (na); - j++; - } - } - } - - const Elements *el = vessel->Els(); - if (el && ref) { - vlist.els->GetItem (0)->SetValue (ref->Name()); - sprintf (cbuf, "%s m", SciStr (el->a, 5)); - vlist.els->GetItem (1)->SetValue (cbuf); - sprintf (cbuf, "%g", el->e); - vlist.els->GetItem (2)->SetValue (cbuf); - sprintf (cbuf, "%0.2f", el->i*DEG); - vlist.els->GetItem (3)->SetValue (cbuf); - sprintf (cbuf, "%0.2f", el->theta*DEG); - vlist.els->GetItem (4)->SetValue (cbuf); - sprintf (cbuf, "%0.2f", el->omegab*DEG); - vlist.els->GetItem (5)->SetValue (cbuf); - sprintf (cbuf, "%0.2f", el->MeanLng()*DEG); - vlist.els->GetItem (6)->SetValue (cbuf); - } else { - for (i = 0; i < 7; i++) - vlist.els->GetItem (i)->SetValue (na); - } - - const SurfParam *sp = vessel->GetSurfParam(); - if (sp) { - vlist.srf->GetItem (0)->SetValue (sp->ref->Name()); - sprintf (cbuf, "%07.3f%c %06.3f%c", fabs(sp->lng)*DEG, sp->lng >= 0.0 ? 'E':'W', fabs(sp->lat)*DEG, sp->lat >= 0.0 ? 'N':'S'); - vlist.srf->GetItem (1)->SetValue (cbuf); - strcpy (cbuf, DistStr (sp->alt)); strcat (cbuf, "m"); - vlist.srf->GetItem (2)->SetValue (cbuf+1); - sprintf (cbuf, "%sm/s", FloatStr (sp->groundspd)+1); - vlist.srf->GetItem (3)->SetValue (cbuf); - Vector V (mul (sp->L2H, tmul (vessel->ProxyBody()->GRot(), sp->groundvel_glob))); - sprintf (cbuf, "%sm/s", FloatStr (V.y)+1); - vlist.srf->GetItem (4)->SetValue (cbuf); - sprintf (cbuf, "%0.0f", sp->dir*DEG); - vlist.srf->GetItem (5)->SetValue (cbuf); - sprintf (cbuf, "%0.0f", sp->pitch*DEG); - vlist.srf->GetItem (6)->SetValue (cbuf); - sprintf (cbuf, "%0.0f %s", fabs(sp->bank)*DEG, sp->bank >= 0.0 ? "left":"right"); - vlist.srf->GetItem (7)->SetValue (cbuf); - } else { - for (i = 0; i < 8; i++) - vlist.srf->GetItem (i)->SetValue (na); - } - - if (vessel->isInAtmosphere()) { - double T, rho, p; - vessel->AtmTemperature (T); - vessel->AtmPressureAndDensity (p, rho); - sprintf (cbuf, "%0.2f K", T); - vlist.atm->GetItem (0)->SetValue (cbuf); - sprintf (cbuf, "%0.4g kg/m^3", rho); - vlist.atm->GetItem (1)->SetValue (cbuf); - sprintf (cbuf, "%sPa", FloatStr(p)+1); - vlist.atm->GetItem (2)->SetValue (cbuf); - } else { - for (i = 0; i < 3; i++) - vlist.atm->GetItem (i)->SetValue (na); - } - - if (vessel->isInAtmosphere()) { - double dynp, M, L, D; - vessel->DynPressure (dynp); - L = vessel->GetLift(); - D = vessel->GetDrag(); - sprintf (cbuf, "%sPa", FloatStr(dynp)+1); - vlist.aer->GetItem (0)->SetValue (cbuf); - if (sp) sprintf (cbuf, "%sm/s", FloatStr(sp->airspd)+1); - else strcpy (cbuf, na); - vlist.aer->GetItem (1)->SetValue (cbuf); - vessel->MachNumber (M); - sprintf (cbuf, "%g", M); - vlist.aer->GetItem (2)->SetValue (cbuf); - sprintf (cbuf, "%sN", FloatStr(L)+(L >= 0 ? 1:0)); - vlist.aer->GetItem (3)->SetValue (cbuf); - sprintf (cbuf, "%sN", FloatStr(D)+1); - vlist.aer->GetItem (4)->SetValue (cbuf); - sprintf (cbuf, "%sN", FloatStr(vessel->GetWeight())+1); - vlist.aer->GetItem (5)->SetValue (cbuf); - if (D) sprintf (cbuf, "%g", L/D); - else strcpy (cbuf, na); - vlist.aer->GetItem (6)->SetValue (cbuf); - if (sp) sprintf (cbuf, "%+0.1f", -atan2 (sp->groundvel_ship.y, sp->groundvel_ship.z)*DEG); - else strcpy (cbuf, na); - vlist.aer->GetItem (7)->SetValue (cbuf); - } else { - for (i = 0; i < 8; i++) - vlist.aer->GetItem (i)->SetValue (na); - } - - if (vlist.dck) { - for (i = 0; i < vlist.dck->ItemCount(); i++) { - if (i < vessel->nDock()) { - if (vessel->GetDockParams(i)->ids) - sprintf (cbuf, "IDS %06.2f ", vessel->GetDockParams(i)->ids->GetFreq()); - else cbuf[0] = '\0'; - Vessel *mate = vessel->DockMate (i); - if (mate) sprintf (cbuf+strlen(cbuf), "[Docked to %s]", mate->Name()); - else strcat (cbuf, "[free]"); - vlist.dck->GetItem (i)->SetValue (cbuf); - } else vlist.dck->GetItem (i)->SetValue (na); - } - } - if (vessel->GetStatus() == FLIGHTSTATUS_LANDED) { - vlist.prp->GetItem (0)->SetValue ("IDLE (landed)"); - for (i = 1; i < 4; i++) vlist.prp->GetItem (i)->SetValue (na); - } else if (vessel->isAttached()) { - vlist.prp->GetItem (0)->SetValue ("PASSIVE (attached)"); - for (i = 1; i < 4; i++) vlist.prp->GetItem (i)->SetValue (na); - } else { - vlist.prp->GetItem (0)->SetValue ("ACTIVE (dynamic)"); - vlist.prp->GetItem (1)->SetValue (vessel->isOrbitStabilised() ? "stabilised" : vessel->CurPropagatorStr()); - sprintf (cbuf, "%d", vessel->CurPropagatorSubsamples()); - vlist.prp->GetItem (2)->SetValue (cbuf); - cbuf[0] = '\0'; - const GFieldData &gfd = vessel->GetGFieldData(); - for (i = 0; i < gfd.ngrav; i++) { - if (i) strcat (cbuf, ", "); - strcat (cbuf, g_psys->GetGravObj(gfd.gravidx[i])->Name()); - } - vlist.prp->GetItem (3)->SetValue (cbuf); - } -} - -// ====================================================================== - -void DlgInfo::InitItems_celbody (HWND hDlg, const CelestialBody *cbody) -{ - const int nlabel_des = 3; - const char *label_des[nlabel_des] = { - "Name", - "Primary", - "Solar system" - }; - const int nlabel_prm = 7; - const char *label_prm[nlabel_prm] = { - "Mass", - "Mean radius", - "Gravitational moments", - "Siderial day", - "Orbit period", - "Obliquity of ecliptic", - "Atmosphere" - }; - const int nlabel_atm = 5; - const char *label_atm[nlabel_atm] = { - "Atmosphere model", - "Surface pressure", - "Surface density", - "Specific gas constant", - "Specific heat ratio" - }; - const int nlabel_els = 6; - const char *label_els[nlabel_els] = { - "Semi-major axis (a)", - "Eccentricity (e)", - "Inclination (i)", - "Longitude of asc. node", - "Longitude of periapsis", - "Mean longitude" - }; - const int nlabel_loc = 2; - const char *label_loc[nlabel_loc] = { - "Right ascension (RA)", - "Declination (Dec)" - }; - const int nlabel_ecl = 3; - const char *label_ecl[nlabel_ecl] = { - "Longitude", - "Latitude", - "Radial distance" - }; - const int nlabel_prp = 2; - const char *label_prp[nlabel_prp] = { - "Mode", - "Gravity sources" - }; - - int i; - PropertyItem *item; - pl.ClearGroups(); - - cblist.des = pl.AppendGroup(); - cblist.des->SetTitle ("Designation"); - for (i = 0; i < nlabel_des; i++) { - item = pl.AppendItem (cblist.des); - item->SetLabel (label_des[i]); - } - cblist.prm = pl.AppendGroup(); - cblist.prm->SetTitle ("Physical parameters"); - for (i = 0; i < nlabel_prm; i++) { - item = pl.AppendItem (cblist.prm); - item->SetLabel (label_prm[i]); - } - if (cbody->Type() == OBJTP_PLANET && ((Planet*)cbody)->AtmParams()) { - cblist.atm = pl.AppendGroup(); - cblist.atm->SetTitle ("Atmosphere"); - for (i = 0; i < nlabel_atm; i++) { - item = pl.AppendItem (cblist.atm); - item->SetLabel (label_atm[i]); - } - } else cblist.atm = NULL; - cblist.els = pl.AppendGroup(); - cblist.els->SetTitle ("Osculating elements (ecliptic frame)"); - for (i = 0; i < nlabel_els; i++) { - item = pl.AppendItem (cblist.els); - item->SetLabel (label_els[i]); - } - if (strcmp (cbody->Name(), "Earth")) { - cblist.loc = pl.AppendGroup(); - cblist.loc->SetTitle ("Geocentric celestial position"); - for (i = 0; i < nlabel_loc; i++) { - item = pl.AppendItem (cblist.loc); - item->SetLabel (label_loc[i]); - } - } else cblist.loc = NULL; - if (cbody->Els()) { - cblist.ecl = pl.AppendGroup(); - cblist.ecl->SetTitle ("Ecliptic position from primary"); - for (i = 0; i < nlabel_ecl; i++) { - item = pl.AppendItem (cblist.ecl); - item->SetLabel (label_ecl[i]); - } - } else cblist.ecl = NULL; - cblist.prp = pl.AppendGroup(); - cblist.prp->SetTitle ("State propagation"); - for (i = 0; i < nlabel_prp - (cbody->canDynamicPosVel() ? 0:1); i++) { - item = pl.AppendItem (cblist.prp); - item->SetLabel (label_prp[i]); - } +void DlgInfo::DrawInfoVessel(Vessel *vessel) { + ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg; + if(ImGui::CollapsingHeader("Designation", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table Designation", 2, flags)) + { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Name"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(vessel->Name()); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Class"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(vessel->ClassName()); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Transponder Frequency"); + ImGui::TableSetColumnIndex(1); + float f; + if (vessel->GetXpdrFreq (f)) + ImGui::Text("%0.2fMHz", f); + else + ImGui::TextUnformatted("N/A"); + ImGui::EndTable(); + } + } + if(ImGui::CollapsingHeader("Physical Parameters", ImGuiTreeNodeFlags_DefaultOpen)) { + // Total mass, dry mass, propellant mass, mean radius, P. moment of inertias + if (ImGui::BeginTable("table Physical Parameters", 2, flags)) + { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Total mass"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%g kg", vessel->Mass()); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Dry mass"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%g kg", vessel->EmptyMass()); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Propellant mass"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%g kg", vessel->FuelMass()); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Mean radius"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%s m", DistStr (vessel->Size())+1); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("P. moments of inertia"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"(%4g, %4g, %4g) kg.m²", vessel->PMI().x, vessel->PMI().y, vessel->PMI().z); + + ImGui::EndTable(); + } + } + if(ImGui::CollapsingHeader("Thrusters Group Ratings (vacuum)", ImGuiTreeNodeFlags_DefaultOpen)) { + //Main, retro, hover + const THGROUP_TYPE thgrp[3] = {THGROUP_MAIN, THGROUP_RETRO, THGROUP_HOVER}; + const char *thrtype[] = {"Main", "Retro", "Hover"}; + if (ImGui::BeginTable("table Thrusters Group Ratings", 2, flags)) + { + for (int i = 0; i < 3; i++) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted(thrtype[i]); + ImGui::TableSetColumnIndex(1); + double th = vessel->GetThrusterGroupMaxth (thgrp[i]); + if (th > 0.0) { + ImGui::Text("%sN", FloatStr (th)+1); + } else { + ImGui::Text("N/A"); + } + } + ImGui::EndTable(); + } + + } + + const Body *ref = vessel->ElRef(); + const Elements *el = vessel->Els(); + if(el && ref && ImGui::CollapsingHeader("Osculating Elements (Ecliptic Frame)", ImGuiTreeNodeFlags_DefaultOpen)) { + //Reference, semi major axis, excentricity, inclination, longitude of AN, longitude of periapsis, mean longitude + if (ImGui::BeginTable("table Osculating Elements", 2, flags)) + { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Reference"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(ref->Name()); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Semi-major Axis (a)"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%s m", SciStr (el->a, 5)); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Excentricity (e)"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%g", el->e); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted(u8"Inclination (igg)"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.2f°", el->i*DEG); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Longitude of Ascending Node"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.2f°", el->theta*DEG); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Longitude of Periapsis"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.2f°", el->omegab*DEG); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Mean longitude"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.2f°", el->MeanLng()*DEG); + ImGui::EndTable(); + } + } + + const SurfParam *sp = vessel->GetSurfParam(); + if(sp && ImGui::CollapsingHeader("Surface-relative Parameters", ImGuiTreeNodeFlags_DefaultOpen)) { + //reference, position, altitude, ground speed, vertical speed, heading, pitch, bank + if (ImGui::BeginTable("table Surface-relative Parameters", 2, flags)) + { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Reference"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(sp->ref->Name()); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Position"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%07.3f°%c %06.3f°%c", fabs(sp->lng)*DEG, sp->lng >= 0.0 ? 'E':'W', fabs(sp->lat)*DEG, sp->lat >= 0.0 ? 'N':'S'); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Altitude"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%sm", DistStr (sp->alt)+1); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Ground Speed"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%sm/s", FloatStr (sp->groundspd)+1); + + Vector V (mul (sp->L2H, tmul (vessel->ProxyBody()->GRot(), sp->groundvel_glob))); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Vertical Speed"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%sm/s", FloatStr (V.y)+1); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Heading"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.0f°", sp->dir*DEG); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Pitch"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.0f°", sp->pitch*DEG); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Bank"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.0f° %s", fabs(sp->bank)*DEG, sp->bank >= 0.0 ? "left":"right"); + + ImGui::EndTable(); + } + } + + if (vessel->isInAtmosphere()) { + if(ImGui::CollapsingHeader("Atmospheric Parameters", ImGuiTreeNodeFlags_DefaultOpen)) { + // Temperature, density, pressure + if (ImGui::BeginTable("table Atmospheric Parameters", 2, flags)) + { + double T, rho, p; + vessel->AtmTemperature (T); + vessel->AtmPressureAndDensity (p, rho); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Temperature"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%0.2f K", T); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Density"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%0.4g kg/m^3", rho); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Pressure"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%sPa", FloatStr(p)+1); + + ImGui::EndTable(); + } + } + if(ImGui::CollapsingHeader("Aerodynamic Parameters", ImGuiTreeNodeFlags_DefaultOpen)) { + // Dynamic pressure, true airspeed, mach number, lift, drag, weight, lift/drag ratio, angle of attack + if (ImGui::BeginTable("table Aerodynamic Parameters", 2, flags)) + { + double dynp, M, L, D; + vessel->DynPressure (dynp); + L = vessel->GetLift(); + D = vessel->GetDrag(); + vessel->MachNumber (M); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Dynamic Pressure"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%sPa", FloatStr(dynp)+1); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("True Airspeed"); + ImGui::TableSetColumnIndex(1); + ImGui::Text( "%sm/s", FloatStr(sp->airspd)+1); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Mach Number"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%g", M); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Lift"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%sN", FloatStr(L)+(L >= 0 ? 1:0)); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Drag"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%sN", FloatStr(D)+1); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Weight"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%sN", FloatStr(vessel->GetWeight())+1); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Lift/Drag Ratio"); + ImGui::TableSetColumnIndex(1); + if (D) + ImGui::Text("%g", L/D); + else + ImGui::TextUnformatted("N/A"); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Angle of Attack"); + ImGui::TableSetColumnIndex(1); + if(sp) + ImGui::Text(u8"%+0.1f°", -atan2 (sp->groundvel_ship.y, sp->groundvel_ship.z)*DEG); + else + ImGui::TextUnformatted("N/A"); + + ImGui::EndTable(); + } + } + } + + if (vessel->nDock()) { + if(ImGui::CollapsingHeader("Docking Ports", ImGuiTreeNodeFlags_DefaultOpen)) { + // port 1,2,3... + if (ImGui::BeginTable("table Docking Ports", 2, flags)) + { + for(int i = 0;inDock();i++) { + char buf[128]; + if (vessel->GetDockParams(i)->ids) + sprintf (buf, "IDS %06.2f ", vessel->GetDockParams(i)->ids->GetFreq()); + else + buf[0]='\0'; + Vessel *mate = vessel->DockMate (i); + if (mate) sprintf (buf+strlen(buf), "[Docked to %s]", mate->Name()); + else strcat (buf, "[free]"); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::Text("Port %d", i+1); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(buf); + } + + ImGui::EndTable(); + } + } + } + + if(ImGui::CollapsingHeader("State Propagation", ImGuiTreeNodeFlags_DefaultOpen)) { + // update mode, state propagator, subsamples, gravity sources + if (ImGui::BeginTable("table State Propagation", 2, flags)) + { + if (vessel->GetStatus() == FLIGHTSTATUS_LANDED) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Update mode"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted("IDLE (landed)"); + } else if (vessel->isAttached()) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Update mode"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted("PASSIVE (attached)"); + } else { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Update mode"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted("ACTIVE (dynamic)"); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("State Propagator"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(vessel->isOrbitStabilised() ? "stabilised" : vessel->CurPropagatorStr()); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Subsamples"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%d", vessel->CurPropagatorSubsamples()); + + char cbuf[256]; + cbuf[0] = '\0'; + const GFieldData &gfd = vessel->GetGFieldData(); + for (int i = 0; i < gfd.ngrav; i++) { + if (i) strcat (cbuf, ", "); + strcat (cbuf, g_psys->GetGravObj(gfd.gravidx[i])->Name()); + } + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Gravity Sources"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(cbuf); + + } + ImGui::EndTable(); + } + } } -// ====================================================================== -void DlgInfo::UpdateItems_celbody () -{ - CelestialBody *cbody = (CelestialBody*)body; - CELBODY *cb = cbody->GetModuleInterface(); - Planet *planet = 0; - const Elements *el = 0; - char cbuf[256]; - int i, nj; - - switch (body->Type()) { - case OBJTP_PLANET: - planet = (Planet*)body; - el = planet->Els(); - break; - } - - cblist.des->GetItem (0)->SetValue (cbody->Name()); - cblist.des->GetItem (1)->SetValue (cbody->ElRef() ? cbody->ElRef()->Name() : na); - const std::string& psys_name = g_psys->Name(); - cblist.des->GetItem (2)->SetValue (psys_name.empty() ? na : psys_name.c_str()); - - sprintf (cbuf, "%s kg", SciStr (cbody->Mass(), 4)); - cblist.prm->GetItem (0)->SetValue (cbuf); - sprintf (cbuf, "%s m", SciStr (cbody->Size(), 4)); - cblist.prm->GetItem (1)->SetValue (cbuf); - if (nj = cbody->nJcoeff()) { - cbuf[0] = '\0'; - for (i = 0; i < nj; i++) { - sprintf (cbuf + strlen(cbuf), "J%d=%s", i+2, SciStr (cbody->Jcoeff (i),3)); - if (i < nj-1) strcat (cbuf, ", "); - } - } else strcpy (cbuf, na); - cblist.prm->GetItem (2)->SetValue (cbuf); - sprintf (cbuf, "%s s", SciStr (cbody->RotT(), 4)); - cblist.prm->GetItem (3)->SetValue (cbuf); - if (el) sprintf (cbuf, "%s s", SciStr (el->OrbitT(), 4)); - else strcpy (cbuf, na); - cblist.prm->GetItem (4)->SetValue (cbuf); - if (planet) sprintf (cbuf, "%0.2f", planet->Obliquity()*DEG); - else strcpy (cbuf, na); - cblist.prm->GetItem (5)->SetValue (cbuf); - cblist.prm->GetItem (6)->SetValue (planet && cblist.atm ? "Yes":"No"); - - if (planet && cblist.atm) { - const ATMCONST *ap = planet->AtmParams(); - if (ap) { - strcpy (cbuf, "Generic"); - if (cb && cb->Version() >= 2) { - CELBODY2 *cb2 = (CELBODY2*)cb; - ATMOSPHERE *atm = cb2->GetAtmosphere(); - if (atm) strcpy (cbuf, atm->clbkName()); - } - cblist.atm->GetItem (0)->SetValue (cbuf); - sprintf (cbuf, "%sPa", FloatStr (ap->p0)+1); - cblist.atm->GetItem (1)->SetValue (cbuf); - sprintf (cbuf, "%skg/m^3", SciStr (ap->rho0)); - cblist.atm->GetItem (2)->SetValue (cbuf); - sprintf (cbuf, "%0.2fJ/(K kg)", ap->R); - cblist.atm->GetItem (3)->SetValue (cbuf); - sprintf (cbuf, "%0.2f", ap->gamma); - cblist.atm->GetItem (4)->SetValue (cbuf); - } else { - for (i = 0; i < 5; i++) - cblist.atm->GetItem (i)->SetValue (na); - } - } - - if (el) { - sprintf (cbuf, "%s m", SciStr (el->a, 5)); - cblist.els->GetItem (0)->SetValue (cbuf); - sprintf (cbuf, "%0.5g", el->e); - cblist.els->GetItem (1)->SetValue (cbuf); - sprintf (cbuf, "%0.2f", el->i*DEG); - cblist.els->GetItem (2)->SetValue (cbuf); - sprintf (cbuf, "%0.2f", el->theta*DEG); - cblist.els->GetItem (3)->SetValue (cbuf); - sprintf (cbuf, "%0.2f", el->omegab*DEG); - cblist.els->GetItem (4)->SetValue (cbuf); - sprintf (cbuf, "%0.2f", el->MeanLng()*DEG); - cblist.els->GetItem (5)->SetValue (cbuf); - } else { - for (i = 0; i < 6; i++) - cblist.els->GetItem (i)->SetValue (na); - } - - if (cblist.loc) { - Planet *earth = g_psys->GetPlanet ("Earth"); - if (earth && earth != cbody) { +void DlgInfo::DrawInfoCelestialBody(CelestialBody *cbody) { + const Elements *el = nullptr; + const Planet *planet = nullptr; + const CELBODY *cb = cbody->GetModuleInterface(); + + switch (cbody->Type()) { + case OBJTP_PLANET: + planet = (Planet*)cbody; + el = planet->Els(); + break; + } + + ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg; + if(ImGui::CollapsingHeader("Designation", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table celbody designation", 2, flags)) + { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Name"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(cbody->Name()); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Primary"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(cbody->ElRef() ? cbody->ElRef()->Name() : "N/A"); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Solar System"); + ImGui::TableSetColumnIndex(1); + const char *psys_name = g_psys->Name().c_str(); + ImGui::TextUnformatted(psys_name ? psys_name : "N/A"); + + ImGui::EndTable(); + } + } + if(ImGui::CollapsingHeader("Physical Parameters", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table celbody Physical parameters", 2, flags)) + { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Mass"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%s kg", SciStr (cbody->Mass(), 4)); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Mean Radius"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%s m", SciStr (cbody->Size(), 4)); + + int nj; + char cbuf[128]; + if ((nj = cbody->nJcoeff())) { + cbuf[0] = '\0'; + for (int i = 0; i < nj; i++) { + sprintf (cbuf + strlen(cbuf), "J%d=%s", i+2, SciStr (cbody->Jcoeff (i),3)); + if (i < nj-1) strcat (cbuf, ", "); + } + } else strcpy (cbuf, "N/A"); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Gravitational Moments"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(cbuf); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Siderial day"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%s s", SciStr (cbody->RotT(), 4)); + + if (el) sprintf (cbuf, "%s s", SciStr (el->OrbitT(), 4)); + else strcpy (cbuf, "N/A"); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Orbit Period"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(cbuf); + + if (planet) sprintf (cbuf, u8"%0.2f°", planet->Obliquity()*DEG); + else strcpy (cbuf, "N/A"); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Obliquity of Ecliptic"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(cbuf); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Atmosphere"); + ImGui::TableSetColumnIndex(1); + if(planet && planet->AtmParams()) { + ImGui::TextUnformatted("Yes"); + } else { + ImGui::TextUnformatted("No"); + } + + + ImGui::EndTable(); + } + } + if(planet && planet->AtmParams() && ImGui::CollapsingHeader("Atmosphere", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table celbody Atmosphere", 2, flags)) + { + char cbuf[128]; + const ATMCONST *ap = planet->AtmParams(); + strcpy (cbuf, "Generic"); + if (cb && cb->Version() >= 2) { + CELBODY2 *cb2 = (CELBODY2*)cb; + ATMOSPHERE *atm = cb2->GetAtmosphere(); + if (atm) strcpy (cbuf, atm->clbkName()); + } + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Atmosphere Model"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(cbuf); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Surface Pressure"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%sPa", FloatStr (ap->p0)+1); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Surface density"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%skg/m^3", SciStr (ap->rho0)); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Specific Gas Constant"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%0.2fJ/(K kg)", ap->R); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Specific Heat Ratio"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%0.2f", ap->gamma); + + ImGui::EndTable(); + } + } + + if(el && ImGui::CollapsingHeader("Osculating Elements (Ecliptic Frame)", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table celbody Osculating elements (ecliptic frame)", 2, flags)) + { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Semi-major Axis (a)"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%s m", SciStr (el->a, 5)); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Eccentricity (e)"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%0.5g", el->e); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Inclination (i)"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.2f°", el->i*DEG); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Longitude of Ascending Node"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.2f°", el->theta*DEG); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Longitude of Periapsis"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.2f°", el->omegab*DEG); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Mean Longitude"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.2f°", el->MeanLng()*DEG); + + ImGui::EndTable(); + } + } + if(strcmp(cbody->Name(), "Earth") && ImGui::CollapsingHeader("Geocentric Celestial Position", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table celbody Geocentric Celestial Position", 2, flags)) + { + char cbuf[128]; + Planet *earth = g_psys->GetPlanet ("Earth"); Vector p (cbody->GPos() - earth->GPos()); double r = p.length(); double lng = atan2 (p.z, p.x); @@ -863,225 +680,221 @@ void DlgInfo::UpdateItems_celbody () ras = modf (ram, &ram) * 60.0; dcm = fabs (modf (dc*DEG, &dcd)) * 60.0; dcs = modf (dcm, &dcm) * 60.0; - sprintf (cbuf, "%02.0fh %02.0fm %02.2fs", rah, ram, ras); - cblist.loc->GetItem (0)->SetValue (cbuf); - sprintf (cbuf, "%+02.0f %02.0f' %02.2f''", dcd, dcm, dcs); - cblist.loc->GetItem (1)->SetValue (cbuf); - } else { - for (i = 0; i < 2; i++) - cblist.loc->GetItem (i)->SetValue (na); - } - } - - if (cblist.ecl) { - if (el) { + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Right Ascension (RA)"); + ImGui::TableSetColumnIndex(1); + sprintf (cbuf, "%02.0fh %02.0fm %02.2fs", rah, ram, ras); + ImGui::TextUnformatted(cbuf); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Declination (Dec)"); + ImGui::TableSetColumnIndex(1); + sprintf (cbuf, u8"%+02.0f° %02.0f' %02.2f''", dcd, dcm, dcs); + ImGui::TextUnformatted(cbuf); + + ImGui::EndTable(); + } + } + + if(el && ImGui::CollapsingHeader("Ecliptic position from primary", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table celbody Ecliptic position from primary", 2, flags)) + { Vector p (cbody->GPos() - cbody->ElRef()->GPos()); double r = p.length(); double lng = atan2 (p.z, p.x); double lat = p.y/r; - sprintf (cbuf, "%0.3f", DEG*posangle(lng)); - cblist.ecl->GetItem (0)->SetValue (cbuf); - sprintf (cbuf, "%0.3f", DEG*lat); - cblist.ecl->GetItem (1)->SetValue (cbuf); - sprintf (cbuf, "%s m", SciStr (r)); - cblist.ecl->GetItem (2)->SetValue (cbuf); - } else { - for (i = 0; i < 3; i++) - cblist.ecl->GetItem (i)->SetValue (na); - } - } - - if (cbody->canDynamicPosVel()) { - cblist.prp->GetItem (0)->SetValue ("Numerical"); - if (cblist.prp->ItemCount() > 1) { - const GFieldData &gfd = cbody->GetGFieldData(); - if (gfd.ngrav) { - cbuf[0] = '\0'; - for (i = 0; i < gfd.ngrav; i++) { - strcat (cbuf, g_psys->GetGravObj(gfd.gravidx[i])->Name()); - if (i < gfd.ngrav-1) strcat (cbuf, ", "); - } - cblist.prp->GetItem (1)->SetValue (cbuf); - } else { - cblist.prp->GetItem (1)->SetValue (na); - } - } - } else { - sprintf (cbuf, "Analytic (%s)", cb ? "from module" : "2-body"); - cblist.prp->GetItem (0)->SetValue (cbuf); - } -} -// ====================================================================== + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Longitude"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.3f°", DEG*posangle(lng)); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Latitude"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%0.3f°", DEG*lat); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Radial Distance"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%s m", SciStr (r)); + + ImGui::EndTable(); + } + } + if(ImGui::CollapsingHeader("State Propagation", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table celbody State propagation", 2, flags)) + { + if (cbody->canDynamicPosVel()) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Mode"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted("Numerical"); + + const GFieldData &gfd = cbody->GetGFieldData(); + if (gfd.ngrav) { + char cbuf[128]; + cbuf[0] = '\0'; + for (int i = 0; i < gfd.ngrav; i++) { + strcat (cbuf, g_psys->GetGravObj(gfd.gravidx[i])->Name()); + if (i < gfd.ngrav-1) strcat (cbuf, ", "); + } + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Gravity Sources"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(cbuf); + + } + } else { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Mode"); + ImGui::TableSetColumnIndex(1); + ImGui::Text("Analytic (%s)", cb ? "from module" : "2-body"); + } + + ImGui::EndTable(); + } + } -void DlgInfo::InitItems_base (HWND hDlg, const Base *base) -{ - const int nlabel_des = 3; - const char *label_des[nlabel_des] = { - "Name", - "Located on", - "Position" - }; - - int i; - DWORD j; - PropertyItem *item; - pl.ClearGroups(); - blist.des = pl.AppendGroup(); - blist.des->SetTitle ("Designation"); - for (i = 0; i < nlabel_des; i++) { - item = pl.AppendItem (blist.des); - item->SetLabel (label_des[i]); - } - if (base->nPad()) { - char cbuf[64]; - blist.pad = pl.AppendGroup(); - blist.pad->SetTitle ("Landing pads"); - for (i = 0; i < base->nPad(); i++) { - item = pl.AppendItem (blist.pad); - sprintf (cbuf, "Pad %d", i+1); - item->SetLabel (cbuf); - } - } else blist.pad = NULL; - - if (base->nRwy()) { - char cbuf[64]; - blist.rwy = pl.AppendGroup(); - blist.rwy->SetTitle ("Runways"); - for (j = 0; j < base->nRwy(); j++) { - item = pl.AppendItem (blist.rwy); - const RwySpec *rwy = base->RwyStatus (j); - int dir = (int)(posangle(rwy->appr1)*DEG*0.1+0.5); - sprintf (cbuf, "Runway %02d/%02d", dir, (dir+18)%36); - item->SetLabel (cbuf); - } - } else blist.rwy = NULL; - - if (base->nVOR()) { - for (j = 0; j < base->nVOR(); j++) - if (base->VOR(j)->Type() == TRANSMITTER_VOR) - break; - if (j < base->nVOR()) { - blist.vor = pl.AppendGroup(); - blist.vor->SetTitle ("VOR transmitters"); - for (j = 0; j < base->nVOR(); j++) { - const Nav *nav = base->VOR(j); - if (nav->Type() == TRANSMITTER_VOR) { - item = pl.AppendItem (blist.vor); - item->SetLabel (nav->GetId()); - } - } - } - } else blist.vor = NULL; } - -// ====================================================================== - -void DlgInfo::UpdateItems_base () -{ - const char *c, *statusstr[3] = {"free", "", "reserved"}; - char cbuf[256]; - double lng, lat; - int i, j, status; - - Base *base = (Base*)body; - blist.des->GetItem (0)->SetValue (base->Name()); - blist.des->GetItem (1)->SetValue (base->RefPlanet()->Name()); - base->EquPos (lng, lat); - sprintf (cbuf, "%07.3f%c %06.3f%c", - fabs(lng)*DEG, lng >= 0.0 ? 'E':'W', - fabs(lat)*DEG, lat >= 0.0 ? 'N':'S' - ); - blist.des->GetItem (2)->SetValue (cbuf); - - if (blist.pad) { - for (i = 0; i < blist.pad->ItemCount(); i++) { - if (i < base->nPad()) { - cbuf[0] = '\0'; - status = base->PadStatus(i)->status; - if (status == 1) c = base->PadStatus(i)->vessel->Name(); - else c = statusstr[status]; - if (base->PadStatus(i)->nav) - sprintf (cbuf, "ILS %06.2f ", base->PadStatus(i)->nav->GetFreq()); - sprintf (cbuf+strlen (cbuf), "[%s]", c); - blist.pad->GetItem(i)->SetValue(cbuf); - } else blist.pad->GetItem(i)->SetValue(na); - } - } - - if (blist.rwy) { - for (i = 0; i < blist.rwy->ItemCount(); i++) { - if (i < base->nRwy()) { - const RwySpec *rwy = base->RwyStatus (i); - char ils1[20], ils2[20]; - if (rwy->ils1) sprintf (ils1, "%06.2f", rwy->ils1->GetFreq()); - else strcpy (ils1, "--"); - if (rwy->ils2) sprintf (ils2, "%06.2f", rwy->ils2->GetFreq()); - else strcpy (ils2, "--"); - sprintf (cbuf, "ILS %s/%s, length %0.0fm", ils1, ils2, rwy->length); - blist.rwy->GetItem(i)->SetValue(cbuf); - } else blist.rwy->GetItem(i)->SetValue(na); - } - } - - if (blist.vor) { - for (i = j = 0; i < base->nVOR(); i++) { - const Nav *nav = base->VOR(i); - if (nav->Type() == TRANSMITTER_VOR && j < blist.vor->ItemCount()) { - sprintf (cbuf, "%06.2f, range %sm", nav->GetFreq(), DistStr (nav->GetRange())); - blist.vor->GetItem(j++)->SetValue(cbuf); - } - } - } +void DlgInfo::DrawInfoBase(Base *base) { + ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg; + if(ImGui::CollapsingHeader("Designation", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table base designation", 2, flags)) + { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Name"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(base->Name()); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Located on"); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(base->RefPlanet()->Name()); + + double lng, lat; + base->EquPos (lng, lat); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted("Position"); + ImGui::TableSetColumnIndex(1); + ImGui::Text(u8"%07.3f°%c %06.3f°%c",fabs(lng)*DEG, lng >= 0.0 ? 'E':'W',fabs(lat)*DEG, lat >= 0.0 ? 'N':'S'); + + ImGui::EndTable(); + } + } + + // Landing pads + // pad 1 + // pad xxx + if(base->nPad()) { + if(ImGui::CollapsingHeader("Landing Pads", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table Landing Pads", 2, flags)) + { + const char *c, *statusstr[3] = {"free", "", "reserved"}; + for(int i=0;inPad();i++) { + char cbuf[256]; + cbuf[0] = '\0'; + int status = base->PadStatus(i)->status; + if (status == 1) c = base->PadStatus(i)->vessel->Name(); + else c = statusstr[status]; + if (base->PadStatus(i)->nav) + sprintf (cbuf, "ILS %06.2f ", base->PadStatus(i)->nav->GetFreq()); + sprintf (cbuf+strlen (cbuf), "[%s]", c); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::Text("Pad %d", i+1); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(cbuf); + } + ImGui::EndTable(); + } + } + } + + // Runways + if(base->nRwy()) { + if(ImGui::CollapsingHeader("Runways", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table Runways", 2, flags)) + { + for(int i=0;inRwy();i++) { + char cbuf[256]; + const RwySpec *rwy = base->RwyStatus (i); + int dir = (int)(posangle(rwy->appr1)*DEG*0.1+0.5); + char ils1[20], ils2[20]; + if (rwy->ils1) sprintf (ils1, "%06.2f", rwy->ils1->GetFreq()); + else strcpy (ils1, "--"); + if (rwy->ils2) sprintf (ils2, "%06.2f", rwy->ils2->GetFreq()); + else strcpy (ils2, "--"); + sprintf (cbuf, "ILS %s/%s, length %0.0fm", ils1, ils2, rwy->length); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::Text("Runway %02d/%02d", dir, (dir+18)%36); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(cbuf); + } + ImGui::EndTable(); + } + } + } + + // VOR + if(base->nVOR()) { + if(ImGui::CollapsingHeader("VOR Transmitters", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("table VOR", 2, flags)) + { + for(int i=0;inVOR();i++) { + const Nav *nav = base->VOR(i); + if(nav->Type() == TRANSMITTER_VOR) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted(nav->GetId()); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%06.2f, range %sm", nav->GetFreq(), DistStr (nav->GetRange())); + } + } + ImGui::EndTable(); + } + } + } } -// ====================================================================== - -BOOL DlgInfo::OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam) -{ - Init (hDlg); - return TRUE; -} - -// ====================================================================== - -BOOL DlgInfo::OnSize (HWND hDlg, WPARAM wParam, int w, int h) -{ - Size (w, h); - return DialogWin::OnSize (hDlg, wParam, w, h); // allow default processing +void DlgInfo::OnDraw() { + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGui::BeginChild("ChildL", ImVec2(250, 0), true, window_flags); + { + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x/2, 20)); + + ImGui::Button("Focus Vessel"); + ImGui::SameLine(); + ImGui::Button("Camera Target"); + DrawTree(); + } + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("ChildR", ImVec2(0, 0), true); + ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x, 20)); + ImGui::Text("Object: %s", m_SelectedTarget.c_str()); + + DrawInfo(); + + ImGui::EndChild(); } -// ====================================================================== - -BOOL DlgInfo::OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl) -{ - switch (id) { - case IDHELP: - DefHelpContext.topic = (char*)"/objinfo.htm"; - g_pOrbiter->OpenHelp (&DefHelpContext); - return TRUE; - case IDC_INFO_MAP: - OpenMap(); - return TRUE; - case IDC_INFO_DDN: - ExpandAll (hDlg); - return TRUE; - case IDC_INFO_DUP: - CollapseAll (hDlg); - return TRUE; - case IDC_INFO_TYPE: - if (code == CBN_SELCHANGE) { - BuildObjectList (hDlg); - SelectionChanged (hDlg); - return TRUE; - } - break; - case IDC_INFO_NAME: - if (code == CBN_SELCHANGE) { - SelectionChanged (hDlg); - return TRUE; - } - break; - } - return DialogWin::OnCommand (hDlg, id, code, hControl); +void DlgInfo::SetBody(Body *body) { + m_SelectedTarget = body->Name(); } diff --git a/Src/Orbiter/DlgInfo.h b/Src/Orbiter/DlgInfo.h index 1b03557d8..2a863c8df 100644 --- a/Src/Orbiter/DlgInfo.h +++ b/Src/Orbiter/DlgInfo.h @@ -7,81 +7,24 @@ #ifndef __DLGINFO_H #define __DLGINFO_H +#include "OrbiterAPI.h" -#include "DialogWin.h" -#include "DlgCtrl.h" - -class Body; class CelestialBody; +class Vessel; class Base; - -// ====================================================================== - -class DlgInfo: public DialogWin { +class Body; +class DlgInfo : public ImGuiDialog { public: - DlgInfo (HINSTANCE hInstance, HWND hParent, void *context); - void SetBody (Body *bd); - -protected: - void Init (HWND hDlg); - void BuildObjectList (HWND hDlg, Body *b = NULL); - int Size (DWORD width, DWORD height); - void ExpandAll (HWND hDlg); - void CollapseAll (HWND hDlg); - void Update (); - void SelectionChanged (HWND hDlg); - void SetBody (HWND hDlg, Body *bd); - void InitItems_vessel (HWND hDlg, const Vessel *vessel); - void InitItems_celbody (HWND hDlg, const CelestialBody *cbody); - void InitItems_base (HWND hDlg, const Base *base); - void UpdateItems_vessel (); - void UpdateItems_celbody (); - void UpdateItems_base (); - void OpenMap (); - BOOL OnInitDialog (HWND hWnd, WPARAM wParam, LPARAM lParam); - BOOL OnSize (HWND hWnd, WPARAM wParam, int w, int h); - BOOL OnCommand (HWND hWnd, WORD id, WORD code, HWND hControl); - -private: - Body *body; - int list_top, list_w, list_h; - int client_w, client_h; - PropertyList pl; - double upd_t; - double upd_dt; - bool showth[3]; - HICON hIcon_dd, hIcon_du; - - enum ListMode { LIST_NONE, LIST_VESSEL, LIST_CBODY, LIST_BASE } listmode; - - struct VesselList { - PropertyGroup *des; - PropertyGroup *prm; - PropertyGroup *thr; - PropertyGroup *els; - PropertyGroup *srf; - PropertyGroup *atm; - PropertyGroup *aer; - PropertyGroup *dck; - PropertyGroup *prp; - } vlist; - - struct CBodyList { - PropertyGroup *des; - PropertyGroup *prm; - PropertyGroup *atm; - PropertyGroup *els; - PropertyGroup *loc; - PropertyGroup *ecl; - PropertyGroup *prp; - } cblist; - - struct BaseList { - PropertyGroup *des; - PropertyGroup *pad; - PropertyGroup *rwy; - PropertyGroup *vor; - } blist; + DlgInfo(); + void OnDraw() override; + void AddCbodyNode(const CelestialBody *cbody); + void DrawTree(); + void DrawInfo(); + void DrawInfoVessel(Vessel *); + void DrawInfoCelestialBody(CelestialBody *); + void DrawInfoBase(Base *); + void SetBody(Body *); + std::string m_SelectedTarget; }; #endif // !__DLGINFO_H \ No newline at end of file diff --git a/Src/Orbiter/DlgMap.cpp b/Src/Orbiter/DlgMap.cpp index e8b946e3e..4204290c3 100644 --- a/Src/Orbiter/DlgMap.cpp +++ b/Src/Orbiter/DlgMap.cpp @@ -636,10 +636,6 @@ void DlgMap::OpenInfo () if (obj.type == DISP_BASE || obj.type == DISP_VESSEL || obj.type == DISP_MOON) { DlgInfo *pInfo = g_pOrbiter->DlgMgr()->EnsureEntry (); pInfo->SetBody ((Body*)obj.obj); - - RECT r; - GetWindowRect (hWnd, &r); - SetWindowPos (pInfo->GetHwnd(), NULL, r.right, r.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } } From 6eaef8188622b46d1e9766c820e1da4f9451de0b Mon Sep 17 00:00:00 2001 From: Gondos Date: Fri, 31 Jan 2025 14:43:47 +0100 Subject: [PATCH 21/51] [ImGui]Convert DlgRecorder --- Src/Orbiter/Dialogs.cpp | 21 --- Src/Orbiter/Dialogs.h | 4 - Src/Orbiter/DlgCamera.h | 1 - Src/Orbiter/DlgRecorder.cpp | 261 +++++++++++------------------------- Src/Orbiter/DlgRecorder.h | 22 ++- Src/Orbiter/Orbiter.cpp | 11 +- Src/Orbiter/Orbiter.h | 2 +- 7 files changed, 96 insertions(+), 226 deletions(-) diff --git a/Src/Orbiter/Dialogs.cpp b/Src/Orbiter/Dialogs.cpp index 35b94e9b1..dfad4e9cb 100644 --- a/Src/Orbiter/Dialogs.cpp +++ b/Src/Orbiter/Dialogs.cpp @@ -109,27 +109,6 @@ INT_PTR CALLBACK Navaid_DlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa } #endif -// ====================================================================== -// "Recorder/player" dialog -// ====================================================================== - -INT_PTR CALLBACK FRecorderMsg_DlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - g_pOrbiter->ToggleRecorder (true); - // fall through - case IDCANCEL: - g_pOrbiter->CloseDialog (hDlg); - break; - } - break; - } - return OrbiterDefDialogProc (hDlg, uMsg, wParam, lParam); -} - // ========================================================================= // Set up a combo box dialog control for selecting a celestial body diff --git a/Src/Orbiter/Dialogs.h b/Src/Orbiter/Dialogs.h index d0ec2b948..fe3e660a9 100644 --- a/Src/Orbiter/Dialogs.h +++ b/Src/Orbiter/Dialogs.h @@ -14,10 +14,6 @@ #include "DlgCapture.h" #include "DlgOptions.h" -//INT_PTR CALLBACK Navaid_DlgProc (HWND, UINT, WPARAM, LPARAM); - -INT_PTR CALLBACK FRecorderMsg_DlgProc (HWND, UINT, WPARAM, LPARAM); - // ========================================================================= // Set up a combo box dialog control for selecting a celestial body diff --git a/Src/Orbiter/DlgCamera.h b/Src/Orbiter/DlgCamera.h index 26fdbd243..089d17177 100644 --- a/Src/Orbiter/DlgCamera.h +++ b/Src/Orbiter/DlgCamera.h @@ -16,7 +16,6 @@ class DlgCamera : public ImGuiDialog { public: DlgCamera(); void OnDraw() override; - static const std::string etype; private: void DrawControl(); void DrawTarget(); diff --git a/Src/Orbiter/DlgRecorder.cpp b/Src/Orbiter/DlgRecorder.cpp index 068912f47..6e742bd42 100644 --- a/Src/Orbiter/DlgRecorder.cpp +++ b/Src/Orbiter/DlgRecorder.cpp @@ -5,207 +5,110 @@ // Flight recorder dialog // ====================================================================== -#define STRICT 1 - #include "DlgRecorder.h" #include "Orbiter.h" -#include "Resource.h" -#include "Resource2.h" +#include "OrbiterAPI.h" +#include "imgui.h" -extern Orbiter *g_pOrbiter; extern Vessel *g_focusobj; -extern HELPCONTEXT DefHelpContext; - -static int RecItemEx[4] = {IDC_REC_GRPADVANCED, IDC_REC_WARP, IDC_REC_SYSSAMPLE, IDC_REC_RECFOCUS}; -static int RecItemStd[3] = {IDC_REC_ROLLDOWN, IDC_REC_HELP1, IDC_REC_CANCEL1}; - -// ====================================================================== - -DlgRecorder::DlgRecorder (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_RECPLAY, 0, 0, context) -{ -} - -// ====================================================================== - -void DlgRecorder::SetupDialog (HWND hDlg) -{ - static int RecItem[4] = {IDC_REC_GRPRECORD, IDC_REC_SCNLABEL, IDC_REC_SCENARIO, IDC_REC_ROLLDOWN}; - static int RecItem2[3] = {IDC_REC_SCNLABEL, IDC_REC_SCENARIO, IDC_REC_SYSSAMPLE}; - static int PlayItem[6] = {IDC_REC_GRPREPLAY, IDC_REC_SHOWNOTES, IDC_REC_PLAYRECSPEED, IDC_REC_USECAM, IDC_REC_USEFOCUS, IDC_REC_EDITOR}; - static const char *statestr[3] = {"Status:\nNormal", "Status:\nRecording", "Status:\nPlaying"}; - - int i, status = g_pOrbiter->RecorderStatus(); - - for (i = 0; i < 3; i++) - EnableWindow (GetDlgItem (hDlg, RecItem2[i]), status != 1); - if (status == 2) { - for (i = 0; i < 4; i++) ShowWindow (GetDlgItem (hDlg, RecItem[i]), FALSE); - for (i = 0; i < 6; i++) ShowWindow (GetDlgItem (hDlg, PlayItem[i]), TRUE); - } else { - for (i = 0; i < 6; i++) ShowWindow (GetDlgItem (hDlg, PlayItem[i]), FALSE); - for (i = 0; i < 4; i++) ShowWindow (GetDlgItem (hDlg, RecItem[i]), TRUE); - ShowWindow (GetDlgItem (hDlg, IDC_REC_ROLLDOWN), IsWindowVisible (GetDlgItem (hDlg, IDC_REC_GRPADVANCED)) ? FALSE:TRUE); - } - - int img = (status == 0 ? IDI_REC_ICON : IDI_STOP_ICON); - SendDlgItemMessage (hDlg, IDC_REC_CTRL, BM_SETIMAGE, IMAGE_ICON, - (LPARAM)LoadImage (g_pOrbiter->GetInstance(), MAKEINTRESOURCE(img), IMAGE_ICON, 32, 32, LR_SHARED)); - SetWindowText (GetDlgItem (hDlg, IDC_REC_STATUS), statestr[status]); - SendDlgItemMessage (hDlg, IDC_REC_WARP, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.bRecordWarp ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_REC_PLAYRECSPEED, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayWarp ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_REC_RECFOCUS, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.bRecordFocus ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_REC_USEFOCUS, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayFocus ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_REC_USECAM, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayCam ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_REC_SYSSAMPLE, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.bSysInterval ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_REC_SHOWNOTES, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.bShowNotes ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_REC_ATTECL, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordAttFrame == 0 ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_REC_ATTHOR, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordAttFrame == 1 ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_REC_POSECL, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordPosFrame == 0 ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_REC_POSEQU, BM_SETCHECK, g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordPosFrame == 1 ? BST_CHECKED:BST_UNCHECKED, 0); -} - -// ====================================================================== - -void DlgRecorder::GetRecordName (char *str, int maxlen) const -{ - GetWindowText (GetDlgItem (hWnd, IDC_REC_SCENARIO), str, maxlen); -} - -// ====================================================================== +extern Orbiter *g_pOrbiter; -void DlgRecorder::ShowAdvancedRec (HWND hDlg) -{ - int i; - SetWindowPos (hDlg, HWND_TOP, 0, 0, RecorderDlg_w, RecorderDlg_h2, SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); - for (i = 0; i < 3; i++) - ShowWindow (GetDlgItem (hDlg, RecItemStd[i]), SW_HIDE); - for (i = 0; i < 4; i++) - ShowWindow (GetDlgItem (hDlg, RecItemEx[i]), SW_SHOW); +DlgRecorder::DlgRecorder() : ImGuiDialog("Flight recorder/player", {330, 320}) { + strcpy(m_ScenarioFile, "test_record"); } -// ====================================================================== +void DlgRecorder::OnDraw() { + int status = g_pOrbiter->RecorderStatus(); + static const char *statestr[3] = {"Status: Normal", "Status: Recording", "Status: Playing"}; + ImGui::TextUnformatted(statestr[status]); -void DlgRecorder::HideAdvancedRec (HWND hDlg) -{ - int i; - SetWindowPos (hDlg, HWND_TOP, 0, 0, RecorderDlg_w, RecorderDlg_h1, SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); - for (i = 0; i < 4; i++) - ShowWindow (GetDlgItem (hDlg, RecItemEx[i]), SW_HIDE); - for (i = 0; i < 3; i++) - ShowWindow (GetDlgItem (hDlg, RecItemStd[i]), SW_SHOW); + switch(status) { + case 0: DrawNormalRecording(false); break; + case 1: DrawNormalRecording(true); break; + case 2: DrawPlaying(); break; + } } -// ====================================================================== - -BOOL DlgRecorder::OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam) -{ - RECT r1, r2; - GetWindowRect (hDlg, &r1); - GetWindowRect (GetDlgItem (hDlg, IDC_REC_ROLLDOWN), &r2); - RecorderDlg_w = r1.right-r1.left; - RecorderDlg_h2 = r1.bottom-r1.top; - RecorderDlg_h1 = r2.bottom-r1.top + ((r2.bottom-r2.top)*2)/3; - HideAdvancedRec (hDlg); - SetupDialog (hDlg); - SetWindowText (GetDlgItem (hDlg, IDC_REC_SCENARIO), g_pOrbiter->GetDefRecordName()); - SendDlgItemMessage (hDlg, IDC_REC_ROLLDOWN, BM_SETIMAGE, IMAGE_BITMAP, - (LPARAM)LoadImage (hInst, MAKEINTRESOURCE(IDB_DNARROW), IMAGE_BITMAP, 0, 0, LR_SHARED|LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS)); - SendDlgItemMessage (hDlg, IDC_REC_ROLLUP, BM_SETIMAGE, IMAGE_BITMAP, - (LPARAM)LoadImage (hInst, MAKEINTRESOURCE(IDB_UPARROW), IMAGE_BITMAP, 0, 0, LR_SHARED|LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS)); - - return TRUE; +void DlgRecorder::DrawNormalRecording(bool recording) { + if(recording) { + if(ImGui::Button("STOP")) { + g_pOrbiter->ToggleRecorder (); + } + } else { + if(ImGui::Button("REC")) { + if(!g_pOrbiter->ToggleRecorder ()) + ImGui::OpenPopup("Warning"); + } + } + + bool unused_open = true; + if (ImGui::BeginPopupModal("Warning", &unused_open)) + { + ImGui::TextUnformatted("A flight record under this name already exists!"); + if(ImGui::Button("Overwrite")) { + g_pOrbiter->ToggleRecorder (true); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if(ImGui::Button("Cancel")) { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + + ImGui::Separator(); + ImGui::InputText("Scenario", m_ScenarioFile, sizeof(m_ScenarioFile)); + if(ImGui::CollapsingHeader("Advanced")) { + ImGui::Checkbox("Record Time Acceleration", &g_pOrbiter->Cfg()->CfgRecPlayPrm.bRecordWarp); + ImGui::Checkbox("Record Focus Events", &g_pOrbiter->Cfg()->CfgRecPlayPrm.bRecordFocus); + ImGui::BeginDisabled(recording); + ImGui::Checkbox("Sampling in System Time Steps", &g_pOrbiter->Cfg()->CfgRecPlayPrm.bSysInterval); + //char buf[20]=""; + //ImGui::InputText("sec. sampling", buf, 20); + ImGui::Separator(); + ImGui::TextUnformatted("Attitude Data"); + ImGui::RadioButton("Ecliptic Frame###ef1", &g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordAttFrame, 0); + ImGui::RadioButton("Local Horizon Frame", &g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordAttFrame, 1); + + ImGui::Separator(); + ImGui::TextUnformatted("Position / Velocity Data"); + ImGui::RadioButton("Ecliptic Frame###ef2", &g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordPosFrame, 0); + ImGui::RadioButton("Equatorial Frame", &g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordPosFrame, 1); + ImGui::EndDisabled(); + } } -// ====================================================================== - -BOOL DlgRecorder::OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl) -{ - switch (id) { - case IDC_REC_CTRL: - switch (g_pOrbiter->RecorderStatus()) { - case 0: - case 1: - g_pOrbiter->ToggleRecorder (); - break; - case 2: - g_pOrbiter->EndPlayback(); - break; - } - break; - case IDC_REC_ROLLDOWN: - ShowAdvancedRec (hDlg); - break; - case IDC_REC_ROLLUP: - HideAdvancedRec (hDlg); - break; - case IDC_REC_EDITOR: - g_pOrbiter->FRecorder_ToggleEditor(); - break; - case IDC_REC_WARP: - g_pOrbiter->Cfg()->CfgRecPlayPrm.bRecordWarp = (SendDlgItemMessage (hDlg, IDC_REC_WARP, BM_GETCHECK, 0, 0) == BST_CHECKED); - break; - case IDC_REC_PLAYRECSPEED: - g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayWarp = (SendDlgItemMessage (hDlg, IDC_REC_PLAYRECSPEED, BM_GETCHECK, 0, 0) == BST_CHECKED); +void DlgRecorder::DrawPlaying() { + if(ImGui::Button("STOP")) { + g_pOrbiter->EndPlayback (); + } + ImGui::Separator(); + ImGui::TextUnformatted("Replay Options"); + ImGui::Checkbox("Show Inflight Notes", &g_pOrbiter->Cfg()->CfgRecPlayPrm.bShowNotes); + if(ImGui::Checkbox("Play at Recording Speed", &g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayWarp)) { if (g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayWarp) { extern double RecordingSpeed; g_pOrbiter->SetWarpFactor (RecordingSpeed, true); } - break; - case IDC_REC_USEFOCUS: - g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayFocus = (SendDlgItemMessage (hDlg, IDC_REC_USEFOCUS, BM_GETCHECK, 0, 0) == BST_CHECKED); + } + if(ImGui::Checkbox("Use Recorded Camera Settings", &g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayCam)) { + if (g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayCam) { + // should set camera according to current playback status here! + } + } + if(ImGui::Checkbox("Use Recorded Focus Events", &g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayFocus)) { if (g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayFocus) { extern Vessel *vfocus; if (vfocus && vfocus != g_focusobj) g_pOrbiter->SetFocusObject (vfocus); // do we need to check if vfocus is valid? } - break; - case IDC_REC_USECAM: - g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayCam = (SendDlgItemMessage (hDlg, IDC_REC_USECAM, BM_GETCHECK, 0, 0) == BST_CHECKED); - if (g_pOrbiter->Cfg()->CfgRecPlayPrm.bReplayCam) { - // should set camera according to current playback status here! - } - break; - case IDC_REC_SYSSAMPLE: - g_pOrbiter->Cfg()->CfgRecPlayPrm.bSysInterval = (SendDlgItemMessage (hDlg, IDC_REC_SYSSAMPLE, BM_GETCHECK, 0, 0) == BST_CHECKED); - break; - case IDC_REC_SHOWNOTES: - g_pOrbiter->Cfg()->CfgRecPlayPrm.bShowNotes = (SendDlgItemMessage (hDlg, IDC_REC_SHOWNOTES, BM_GETCHECK, 0, 0) == BST_CHECKED); - break; - case IDC_REC_ATTECL: - if (SendDlgItemMessage (hDlg, IDC_REC_ATTECL, BM_GETCHECK, 0, 0) == BST_CHECKED) - g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordAttFrame = 0; - break; - case IDC_REC_ATTHOR: - if (SendDlgItemMessage (hDlg, IDC_REC_ATTHOR, BM_GETCHECK, 0, 0) == BST_CHECKED) - g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordAttFrame = 1; - break; - case IDC_REC_POSECL: - if (SendDlgItemMessage (hDlg, IDC_REC_POSECL, BM_GETCHECK, 0, 0) == BST_CHECKED) - g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordPosFrame = 0; - break; - case IDC_REC_POSEQU: - if (SendDlgItemMessage (hDlg, IDC_REC_POSEQU, BM_GETCHECK, 0, 0) == BST_CHECKED) - g_pOrbiter->Cfg()->CfgRecPlayPrm.RecordPosFrame = 1; - break; - case IDC_REC_HELP1: - case IDC_REC_HELP2: - DefHelpContext.topic = (char*)"/recorder.htm"; - g_pOrbiter->OpenHelp (&DefHelpContext); - return TRUE; - case IDCANCEL: - case IDC_REC_CANCEL1: - case IDC_REC_CANCEL2: - g_pOrbiter->CloseDialog (hDlg); - break; - } - return DialogWin::OnCommand (hDlg, id, code, hControl); + } + if(ImGui::Button("Editor")) { + g_pOrbiter->FRecorder_ToggleEditor(); + } } -// ====================================================================== - -BOOL DlgRecorder::OnUser1 (HWND hDlg, WPARAM wParam, LPARAM lParam) +void DlgRecorder::GetRecordName (char *str, int maxlen) const { - SetupDialog (hDlg); - return TRUE; + strncpy(str, m_ScenarioFile, maxlen); } diff --git a/Src/Orbiter/DlgRecorder.h b/Src/Orbiter/DlgRecorder.h index 30d66c638..5b6a12252 100644 --- a/Src/Orbiter/DlgRecorder.h +++ b/Src/Orbiter/DlgRecorder.h @@ -8,23 +8,17 @@ #ifndef __DLGRECORDER_H #define __DLGRECORDER_H -#include "DialogWin.h" +#include "OrbiterAPI.h" -class DlgRecorder: public DialogWin { +class DlgRecorder : public ImGuiDialog { public: - DlgRecorder (HINSTANCE hInstance, HWND hParent, void *context); - BOOL OnInitDialog (HWND hWnd, WPARAM wParam, LPARAM lParam); - BOOL OnCommand (HWND hWnd, WORD id, WORD code, HWND hControl); - BOOL OnUser1 (HWND hWnd, WPARAM wParam, LPARAM lParam); - void GetRecordName (char *str, int maxlen) const; + DlgRecorder(); + void OnDraw() override; + void DrawNormalRecording(bool recording); + void DrawPlaying(); -protected: - void SetupDialog (HWND hDlg); - void ShowAdvancedRec (HWND hDlg); - void HideAdvancedRec (HWND hDlg); - -private: - int RecorderDlg_w, RecorderDlg_h1, RecorderDlg_h2; + char m_ScenarioFile[128]; + void GetRecordName (char *str, int maxlen) const; }; #endif // !__DLGRECORDER_H \ No newline at end of file diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 8a4563711..0232ad72a 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -1556,11 +1556,11 @@ const char *Orbiter::GetDefRecordName (void) const return playbackdir+i; } -void Orbiter::ToggleRecorder (bool force, bool append) +bool Orbiter::ToggleRecorder (bool force, bool append) { - if (bPlayback) return; // don't allow recording during playback + if (bPlayback) return true; // don't allow recording during playback - DlgRecorder *pDlg = (pDlgMgr ? pDlgMgr->EntryExists (hInst) : NULL); + DlgRecorder *pDlg = (pDlgMgr ? pDlgMgr->EntryExists () : NULL); int i, n = g_psys->nVessel(); const char *sname; char cbuf[256]; @@ -1572,8 +1572,7 @@ void Orbiter::ToggleRecorder (bool force, bool append) } else sname = GetDefRecordName(); if (!append && !FRecorder_PrepareDir (sname, force)) { bStartRecorder = false; - OpenDialogEx (IDD_MSG_FRECORDER, (DLGPROC)FRecorderMsg_DlgProc, DLG_CAPTIONCLOSE); - return; + return false; } } else sname = 0; FRecorder_Activate (bStartRecorder, sname, append); @@ -1581,7 +1580,7 @@ void Orbiter::ToggleRecorder (bool force, bool append) g_psys->GetVessel(i)->FRecorder_Activate (bStartRecorder, sname, append); if (bStartRecorder) SavePlaybackScn (sname); - if (pDlg) PostMessage (pDlg->GetHwnd(), WM_USER+1, 0, 0); + return true; } void Orbiter::EndPlayback () diff --git a/Src/Orbiter/Orbiter.h b/Src/Orbiter/Orbiter.h index e85b62a25..204f3ce5b 100644 --- a/Src/Orbiter/Orbiter.h +++ b/Src/Orbiter/Orbiter.h @@ -210,7 +210,7 @@ class Orbiter { std::ifstream *FRsys_stream; // system event playback file double frec_sys_simt; // system event timer PlaybackEditor *FReditor; // playback editor instance - void ToggleRecorder (bool force = false, bool append = false); + bool ToggleRecorder (bool force = false, bool append = false); void EndPlayback (); inline int RecorderStatus() const { return (bRecord ? 1 : bPlayback ? 2 : 0); } inline bool IsPlayback() const { return bPlayback; } From 3d076ddf36ec4f6f0e8cf0639118ab4835ab0705 Mon Sep 17 00:00:00 2001 From: Gondos Date: Fri, 31 Jan 2025 15:12:25 +0100 Subject: [PATCH 22/51] [ImGui]Convert DlgTacc --- Src/Orbiter/DlgInfo.cpp | 2 +- Src/Orbiter/DlgRecorder.cpp | 2 +- Src/Orbiter/DlgTacc.cpp | 152 ++++++++++-------------------------- Src/Orbiter/DlgTacc.h | 12 +-- Src/Orbiter/Orbiter.cpp | 2 - 5 files changed, 47 insertions(+), 123 deletions(-) diff --git a/Src/Orbiter/DlgInfo.cpp b/Src/Orbiter/DlgInfo.cpp index 2dba97c85..37dc1f887 100644 --- a/Src/Orbiter/DlgInfo.cpp +++ b/Src/Orbiter/DlgInfo.cpp @@ -13,7 +13,7 @@ extern PlanetarySystem *g_psys; -DlgInfo::DlgInfo() : ImGuiDialog("Orbiter: Object info", {340, 290}) { +DlgInfo::DlgInfo() : ImGuiDialog("Orbiter: Object info", {753,423}) { } void DlgInfo::AddCbodyNode(const CelestialBody *cbody) { diff --git a/Src/Orbiter/DlgRecorder.cpp b/Src/Orbiter/DlgRecorder.cpp index 6e742bd42..3e480ebac 100644 --- a/Src/Orbiter/DlgRecorder.cpp +++ b/Src/Orbiter/DlgRecorder.cpp @@ -13,7 +13,7 @@ extern Vessel *g_focusobj; extern Orbiter *g_pOrbiter; -DlgRecorder::DlgRecorder() : ImGuiDialog("Flight recorder/player", {330, 320}) { +DlgRecorder::DlgRecorder() : ImGuiDialog("Flight recorder/player", {329,354}) { strcpy(m_ScenarioFile, "test_record"); } diff --git a/Src/Orbiter/DlgTacc.cpp b/Src/Orbiter/DlgTacc.cpp index 16b63ebcb..f5ad50953 100644 --- a/Src/Orbiter/DlgTacc.cpp +++ b/Src/Orbiter/DlgTacc.cpp @@ -5,123 +5,53 @@ // Time acceleration dialog // ====================================================================== -#define STRICT 1 - #include "DlgTacc.h" #include "Orbiter.h" -#include "resource.h" -#include "resource2.h" +#include "imgui.h" -extern Orbiter *g_pOrbiter; extern TimeData td; -extern HELPCONTEXT DefHelpContext; - -// ====================================================================== - -DlgTacc::DlgTacc (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_TIMEWARP, 0, 0, context) -{ - pos = &g_pOrbiter->Cfg()->CfgWindowPos.DlgTacc; -} - -// ====================================================================== - -void DlgTacc::Message (DWORD msg, void *data) -{ - bool paused = (data != 0); - SetWindowText (GetDlgItem (hWnd, IDC_WARP_PAUSE), paused ? "Resume" : "Pause"); -} - -// ====================================================================== - -void DlgTacc::RegisterWarp (HWND hDlg, double warp, bool commit, bool edit, bool slide) -{ - if (commit) g_pOrbiter->SetWarpFactor (warp); - if (slide) { - int sliderpos; - if (warp <= 1.0) sliderpos = (int)(warp*10.0); - else if (warp <= 10.0) sliderpos = (int)(warp+9.0); - else if (warp <= 100.0) sliderpos = (int)(0.1*warp+18.0); - else sliderpos = (int)(0.01*warp+27.0); - SendDlgItemMessage (hDlg, IDC_WARP_SLIDER, TBM_SETPOS, TRUE, (LONG)sliderpos); - } - if (edit) { - char cbuf[256]; - double pwarp; - GetWindowText (GetDlgItem (hDlg, IDC_WARP_EDIT), cbuf, 256); - int res = sscanf (cbuf, "%lf", &pwarp); - if (res != 1 || fabs (warp-pwarp) > 1e-8) { - sprintf (cbuf, "%0.1f", warp); - SetWindowText (GetDlgItem (hDlg, IDC_WARP_EDIT), cbuf); - } - } -} - -// ====================================================================== - -BOOL DlgTacc::OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam) -{ - SendDlgItemMessage (hDlg, IDC_WARP_SLIDER, TBM_SETRANGE, FALSE, MAKELONG(1,37)); - SendDlgItemMessage (hDlg, IDC_WARP_SLIDER, TBM_SETPAGESIZE, 0, 9L); - SendDlgItemMessage (hDlg, IDC_WARP_SLIDER, TBM_SETTICFREQ, 9, 0); - RegisterWarp (hDlg, td.Warp(), false); - SetWindowText (GetDlgItem (hDlg, IDC_WARP_PAUSE), g_pOrbiter->IsRunning() ? "Pause": "Resume"); - return TRUE; -} - -// ====================================================================== +extern Orbiter *g_pOrbiter; -BOOL DlgTacc::OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl) -{ - switch (id) { - case IDHELP: - DefHelpContext.topic = (char*)"/timeacc.htm"; - g_pOrbiter->OpenHelp (&DefHelpContext); - return TRUE; - case IDC_WARP_01: - RegisterWarp (hDlg, 0.1); - return TRUE; - case IDC_WARP_1: - RegisterWarp (hDlg, 1.0); - return TRUE; - case IDC_WARP_10: - RegisterWarp (hDlg, 10.0); - return TRUE; - case IDC_WARP_100: - RegisterWarp (hDlg, 100.0); - return TRUE; - case IDC_WARP_1000: - RegisterWarp (hDlg, 1000.0); - return TRUE; - case IDC_WARP_EDIT: - if (code == EN_UPDATE) { - double warp; - char cbuf[256]; - GetWindowText (hControl, cbuf, 256); - warp = atof (cbuf); - if (warp >= 0.1 && warp <= 1e5) - RegisterWarp (hDlg, warp, true, false); - return TRUE; - } - break; - case IDC_WARP_PAUSE: - g_pOrbiter->TogglePause(); - return TRUE; - } - return DialogWin::OnCommand (hDlg, id, code, hControl); +DlgTacc::DlgTacc() : ImGuiDialog("Orbiter: Time acceleration",{357,135}) { } -// ====================================================================== +void DlgTacc::OnDraw() { + const ImVec2 button_sz(ImVec2(50, 20)); + + if(ImGui::Button("0.1x", button_sz)) { + g_pOrbiter->SetWarpFactor (0.1); + } + ImGui::SameLine(); + if(ImGui::Button("1x", button_sz)) { + g_pOrbiter->SetWarpFactor (1.0); + } + ImGui::SameLine(); + if(ImGui::Button("10x", button_sz)) { + g_pOrbiter->SetWarpFactor (10.0); + } + ImGui::SameLine(); + if(ImGui::Button("100x", button_sz)) { + g_pOrbiter->SetWarpFactor (100.0); + } + ImGui::SameLine(); + if(ImGui::Button("1000x", button_sz)) { + g_pOrbiter->SetWarpFactor (1000.0); + } + ImGui::SameLine(); + if(ImGui::Button("10000x", button_sz)) { + g_pOrbiter->SetWarpFactor (10000.0); + } + + float warp = td.Warp(); + ImGui::SetNextItemWidth(-FLT_MIN); + if(ImGui::SliderFloat("##slider warp", &warp, 0.1f, 10000.0f, "%.1f", ImGuiSliderFlags_Logarithmic)) { + g_pOrbiter->SetWarpFactor (warp); + } + + ImGui::NewLine(); + + ImGui::SetCursorPosX((ImGui::GetWindowSize().x - button_sz.x) * 0.5f); + if(ImGui::Button(g_pOrbiter->IsRunning()?"Pause":"Resume", button_sz)) + g_pOrbiter->TogglePause(); -BOOL DlgTacc::OnHScroll (HWND hDlg, WORD request, WORD curpos, HWND hControl) -{ - if (request == TB_THUMBTRACK) { - int sliderpos = SendDlgItemMessage (hDlg, IDC_WARP_SLIDER, TBM_GETPOS, 0, 0); - if (sliderpos <= 10) RegisterWarp (hDlg, sliderpos*0.1); - else if (sliderpos <= 19) RegisterWarp (hDlg, sliderpos-9); - else if (sliderpos <= 28) RegisterWarp (hDlg, (sliderpos-18)*10); - else RegisterWarp (hDlg, (sliderpos-27)*100); - return TRUE; - } - return DialogWin::OnHScroll (hDlg, request, curpos, hControl); } diff --git a/Src/Orbiter/DlgTacc.h b/Src/Orbiter/DlgTacc.h index efaf15bd5..2e025ec74 100644 --- a/Src/Orbiter/DlgTacc.h +++ b/Src/Orbiter/DlgTacc.h @@ -8,16 +8,12 @@ #ifndef __DLGTACC_H #define __DLGTACC_H -#include "DialogWin.h" +#include "OrbiterAPI.h" -class DlgTacc: public DialogWin { +class DlgTacc : public ImGuiDialog { public: - DlgTacc (HINSTANCE hInstance, HWND hParent, void *context); - void Message (DWORD msg, void *data); - void RegisterWarp (HWND hDlg, double warp, bool commit = true, bool edit = true, bool slide = true); - BOOL OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam); - BOOL OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl); - BOOL OnHScroll (HWND hDlg, WORD request, WORD curpos, HWND hControl); + DlgTacc(); + void OnDraw() override; }; #endif // !__DLGTACC_H \ No newline at end of file diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 0232ad72a..3ccb2bcfc 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -1351,8 +1351,6 @@ void Orbiter::SetWarpFactor (double warp, bool force, double delay) if (fabs (warp-td.Warp()) > EPS) { td.SetWarp (warp, delay); if (td.WarpChanged()) ApplyWarpFactor(); - DlgTacc *pDlg = (pDlgMgr ? pDlgMgr->EntryExists (hInst) : NULL); - if (pDlg) pDlg->RegisterWarp(pDlg->GetHwnd(), warp, false, true, true); if (bRecord && pConfig->CfgRecPlayPrm.bRecordWarp) { char cbuf[256]; if (delay) sprintf (cbuf, "%f %f", warp, delay); From 1093986481b8aaf88c8102be9f49d04dfd1c58bc Mon Sep 17 00:00:00 2001 From: Gondos Date: Fri, 31 Jan 2025 19:55:04 +0100 Subject: [PATCH 23/51] [ImGui]Convert DlgCapture --- Src/Orbiter/DlgCapture.cpp | 194 ++++++++----------------------------- Src/Orbiter/DlgCapture.h | 17 +--- 2 files changed, 46 insertions(+), 165 deletions(-) diff --git a/Src/Orbiter/DlgCapture.cpp b/Src/Orbiter/DlgCapture.cpp index c853c0cb5..466bbe241 100644 --- a/Src/Orbiter/DlgCapture.cpp +++ b/Src/Orbiter/DlgCapture.cpp @@ -5,186 +5,74 @@ // Screen capture dialog // ====================================================================== -#define STRICT 1 - -#include #include "DlgCapture.h" #include "Orbiter.h" -#include "Resource.h" -#include "Resource2.h" -#include extern Orbiter *g_pOrbiter; -extern HELPCONTEXT DefHelpContext; // ====================================================================== -DlgCapture::DlgCapture (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_CAPTURE, 0, 0, context) -{ -} - -// ====================================================================== +#include "imgui.h" +#include "imgui_extras.h" -DlgCapture::~DlgCapture () -{ +DlgCapture::DlgCapture() : ImGuiDialog("Orbiter: Capture frames",{323,343}) { } -// ====================================================================== - -BOOL DlgCapture::OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam) -{ - const char *fmtstr[4] = {".bmp",".png",".jpg",".tif"}; - char cbuf[256]; - int i; +void DlgCapture::OnDraw() { CFG_CAPTUREPRM &prm = g_pOrbiter->Cfg()->CfgCapturePrm; - SendDlgItemMessage (hDlg, IDC_CAP_TOCLIP, BM_SETCHECK, prm.ImageTgt == 0 ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_CAP_TOFILE, BM_SETCHECK, prm.ImageTgt == 0 ? BST_UNCHECKED : BST_CHECKED, 0); - EnableWindow (GetDlgItem (hDlg, IDC_CAP_FNAME), prm.ImageTgt == 0 ? FALSE:TRUE); - SetWindowText (GetDlgItem (hDlg, IDC_CAP_FNAME), prm.ImageFile); - SetWindowText (GetDlgItem (hDlg, IDC_CAP_DNAME), prm.SequenceDir); - sprintf (cbuf, "%05d", prm.SequenceStart); - SetWindowText (GetDlgItem (hDlg, IDC_CAP_STARTCOUNT), cbuf); - sprintf (cbuf, "%d", prm.SequenceSkip); - SetWindowText (GetDlgItem (hDlg, IDC_CAP_SKIPFRAME), cbuf); - - SendDlgItemMessage (hDlg, IDC_COMBO1, CB_RESETCONTENT, 0, 0); - for (i = 0; i < 4; i++) - SendDlgItemMessage (hDlg, IDC_COMBO1, CB_INSERTSTRING, -1, (LPARAM)fmtstr[i]); - SendDlgItemMessage (hDlg, IDC_COMBO1, CB_SETCURSEL, prm.ImageFormat, 0); - EnableWindow (GetDlgItem (hDlg, IDC_COMBO2), prm.ImageFormat == 2 ? TRUE:FALSE); - SendDlgItemMessage (hDlg, IDC_COMBO2, CB_RESETCONTENT, 0, 0); - for (i = 1; i <= 10; i++) { - SendDlgItemMessage(hDlg, IDC_COMBO2, CB_INSERTSTRING, -1, (LPARAM)std::to_string(i).data()); - } - SendDlgItemMessage (hDlg, IDC_COMBO2, CB_SETCURSEL, prm.ImageQuality-1, 0); - - return TRUE; -} - -// ====================================================================== - -BOOL DlgCapture::OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl) -{ - switch (id) { - case IDCANCEL: - Take (hDlg); - g_pOrbiter->CloseDialog (hDlg); - return TRUE; - case IDC_COMBO1: - if (code == CBN_SELCHANGE) { - int idx = SendDlgItemMessage (hDlg, id, CB_GETCURSEL, 0, 0); - g_pOrbiter->Cfg()->CfgCapturePrm.ImageFormat = idx; - EnableWindow (GetDlgItem (hDlg, IDC_COMBO2), idx == 2 ? TRUE:FALSE); - return TRUE; - } - break; - case IDC_COMBO2: - if (code == CBN_SELCHANGE) { - int idx = SendDlgItemMessage (hDlg, id, CB_GETCURSEL, 0, 0); - g_pOrbiter->Cfg()->CfgCapturePrm.ImageQuality = idx+1; - return TRUE; + ImGui::BeginGroupPanel("Save snapshots"); + ImGui::RadioButton("To the clipboard", &prm.ImageTgt, 0); + ImGui::RadioButton("To file", &prm.ImageTgt, 1); + if(prm.ImageTgt == 1) { + ImGui::SameLine(); + ImGui::InputText("##File", prm.ImageFile, 128); } - break; - case IDC_CAP_SNAPSHOT: { - oapi::GraphicsClient *gclient = g_pOrbiter->GetGraphicsClient(); - if (gclient) { - Take (hDlg); - if (g_pOrbiter->Cfg()->CfgCapturePrm.ImageTgt) { - oapi::ImageFileFormat fmt = (oapi::ImageFileFormat)g_pOrbiter->Cfg()->CfgCapturePrm.ImageFormat; - float quality = (float)g_pOrbiter->Cfg()->CfgCapturePrm.ImageQuality/10.0f; - gclient->clbkSaveSurfaceToImage (0, g_pOrbiter->Cfg()->CfgCapturePrm.ImageFile, fmt, quality); - AutoIncrement (hDlg); - GetWindowText (GetDlgItem (hDlg, IDC_CAP_FNAME), g_pOrbiter->Cfg()->CfgCapturePrm.ImageFile, 128); - } else + if(ImGui::Button("Take snapshot")) { + oapi::GraphicsClient *gclient = g_pOrbiter->GetGraphicsClient(); + if (prm.ImageTgt) { + oapi::ImageFileFormat fmt = (oapi::ImageFileFormat)prm.ImageFormat; + float quality = (float)prm.ImageQuality/10.0f; + gclient->clbkSaveSurfaceToImage (0, prm.ImageFile, fmt, quality); + AutoIncrement (prm.ImageFile); + } else { gclient->clbkSaveSurfaceToImage (0, NULL, oapi::IMAGE_BMP); + } } - } return TRUE; - case IDC_CAP_RECORD: - if (g_pOrbiter->IsCapturingFrames()) { - g_pOrbiter->StopCaptureFrames(); - SetWindowText (GetDlgItem (hDlg, IDC_CAP_RECORD), "Start recording"); - } else if (Take (hDlg)) { - g_pOrbiter->StartCaptureFrames(); - SetWindowText (GetDlgItem (hDlg, IDC_CAP_RECORD), "Stop recording"); - } - return TRUE; - case IDC_BUTTON1: - g_pOrbiter->Cfg()->SetDefaults_Capture(); - OnInitDialog (hDlg, 0, 0); - return TRUE; - case IDHELP: { - char *topic = (char*)"/capture.htm"; - DefHelpContext.topic = topic; - g_pOrbiter->OpenHelp (&DefHelpContext); - } return TRUE; - case IDC_CAP_TOCLIP: - case IDC_CAP_TOFILE: - if (code == BN_CLICKED) { - Take (hDlg); - return TRUE; - } - break; - } - return DialogWin::OnCommand (hDlg, id, code, hControl); -} + ImGui::EndGroupPanel(); -// ====================================================================== + ImGui::BeginGroupPanel("Save frame sequence"); + ImGui::InputText("To directory", prm.SequenceDir, 128); + ImGui::InputInt("Counter start", &prm.SequenceStart); + ImGui::InputInt("Skip frames", &prm.SequenceSkip); -void DlgCapture::Update () -{ - if (g_pOrbiter->IsCapturingFrames()) { - char cbuf[256]; - int curframe = g_pOrbiter->Cfg()->CfgCapturePrm.SequenceStart; - int showframe; - GetWindowText (GetDlgItem (hWnd, IDC_CAP_STARTCOUNT), cbuf, 256); - if (!sscanf (cbuf, "%d", &showframe) || showframe != curframe) { - sprintf (cbuf, "%05d", curframe); - SetWindowText (GetDlgItem (hWnd, IDC_CAP_STARTCOUNT), cbuf); + if (g_pOrbiter->IsCapturingFrames()) { + if(ImGui::Button("Stop recording")) + g_pOrbiter->StopCaptureFrames(); + } else if (ImGui::Button("Start recording")) { + g_pOrbiter->StartCaptureFrames(); } - } -} + ImGui::EndGroupPanel(); -// ====================================================================== + ImGui::BeginGroupPanel("File settings"); + const char* const formats[] = { "BMP", "PNG", "JPG", "TIF" }; + ImGui::Combo("File format", &prm.ImageFormat, formats, IM_ARRAYSIZE(formats)); + ImGui::BeginDisabled(prm.ImageFormat != 2); + ImGui::SliderInt("Image quality", &prm.ImageQuality, 1, 10); + ImGui::EndDisabled(); + ImGui::EndGroupPanel(); -bool DlgCapture::Take (HWND hDlg) -{ - bool ok = true; - char cbuf[256]; - CFG_CAPTUREPRM &prm = g_pOrbiter->Cfg()->CfgCapturePrm; - bool isClipbd = (SendDlgItemMessage (hDlg, IDC_CAP_TOCLIP, BM_GETCHECK, 0, 0) == TRUE); - prm.ImageTgt = (isClipbd ? 0 : 1); - EnableWindow (GetDlgItem (hDlg, IDC_CAP_FNAME), isClipbd ? FALSE:TRUE); - GetWindowText (GetDlgItem (hDlg, IDC_CAP_FNAME), prm.ImageFile, 128); - GetWindowText (GetDlgItem (hDlg, IDC_CAP_DNAME), prm.SequenceDir, 128); - GetWindowText (GetDlgItem (hDlg, IDC_CAP_STARTCOUNT), cbuf, 256); - if (!sscanf (cbuf, "%d", &prm.SequenceStart)) { - prm.SequenceStart = 0; - ok = false; - } - GetWindowText (GetDlgItem (hDlg, IDC_CAP_SKIPFRAME), cbuf, 256); - if (!sscanf (cbuf, "%d", &prm.SequenceSkip)) { - prm.SequenceSkip = 0; - ok = false; - } - return ok; + if(ImGui::Button("Reset")) + g_pOrbiter->Cfg()->SetDefaults_Capture(); } -// ====================================================================== - -bool DlgCapture::AutoIncrement (HWND hDlg) +void DlgCapture::AutoIncrement (char *cbuf) { - char cbuf[256]; - GetWindowText (GetDlgItem (hDlg, IDC_CAP_FNAME), cbuf, 256); int i, count, len = strlen(cbuf); for (i = len; i > 0; i--) if (cbuf[i-1] == '\\') break; if (sscanf (cbuf+i, "%d", &count) == 1) { int w = len-i; sprintf (cbuf+i, "%0*d", w, count+1); - SetWindowText (GetDlgItem (hDlg, IDC_CAP_FNAME), cbuf); - return true; } - return false; -} \ No newline at end of file +} diff --git a/Src/Orbiter/DlgCapture.h b/Src/Orbiter/DlgCapture.h index 3e293414c..4985df820 100644 --- a/Src/Orbiter/DlgCapture.h +++ b/Src/Orbiter/DlgCapture.h @@ -8,22 +8,15 @@ #ifndef __DLGCAPTURE_H #define __DLGCAPTURE_H -#include "DialogWin.h" - +#include "OrbiterAPI.h" // ====================================================================== // Class for screen capture dialog -class DlgCapture: public DialogWin { +class DlgCapture : public ImGuiDialog { + void AutoIncrement(char *); public: - DlgCapture (HINSTANCE hInstance, HWND hParent, void *context); - ~DlgCapture (); - void Update (); - BOOL OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam); - BOOL OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl); - -protected: - bool Take (HWND hDlg); - bool AutoIncrement (HWND hDlg); + DlgCapture(); + void OnDraw() override; }; #endif // !__DLGCAPTURE_H \ No newline at end of file From 79d585c7907fc91834594d5c5fe7ea26dd96b5df Mon Sep 17 00:00:00 2001 From: Gondos Date: Sat, 1 Feb 2025 00:46:57 +0100 Subject: [PATCH 24/51] [ImGui]Convert DlgMenuCfg --- Src/Orbiter/Config.cpp | 4 +- Src/Orbiter/Config.h | 14 +-- Src/Orbiter/DlgCamera.cpp | 8 +- Src/Orbiter/DlgFocus.cpp | 8 +- Src/Orbiter/DlgInfo.cpp | 2 +- Src/Orbiter/DlgMenuCfg.cpp | 248 ++++++++++--------------------------- Src/Orbiter/DlgMenuCfg.h | 11 +- 7 files changed, 89 insertions(+), 206 deletions(-) diff --git a/Src/Orbiter/Config.cpp b/Src/Orbiter/Config.cpp index 83aeac230..8dfd28897 100644 --- a/Src/Orbiter/Config.cpp +++ b/Src/Orbiter/Config.cpp @@ -721,14 +721,14 @@ bool Config::Load(const char *fname) GetBool (ifs, "ShowWarpAlways", CfgUIPrm.bWarpAlways); GetBool (ifs, "ShowWarpScientific", CfgUIPrm.bWarpScientific); if (GetInt (ifs, "InfobarMode", i) && i >= 0 && i <= 2) - CfgUIPrm.InfoMode = (DWORD)i; + CfgUIPrm.InfoMode = i; if (GetString (ifs, "InfoAuxIdx", cbuf)) { sscanf (cbuf, "%d%d", CfgUIPrm.InfoAuxIdx+0, CfgUIPrm.InfoAuxIdx+1); for (i = 0; i < 2; i++) if (CfgUIPrm.InfoAuxIdx[i] > 3) CfgUIPrm.InfoAuxIdx[i] = 0; } if (GetInt (ifs, "MenubarOpacity", i) && i >= 0 && i <= 10) - CfgUIPrm.MenuOpacity = (DWORD)i; + CfgUIPrm.MenuOpacity = i; if (GetInt (ifs, "InfobarOpacity", i) && i >= 0 && i <= 10) CfgUIPrm.InfoOpacity = (DWORD)i; if (GetInt (ifs, "MenubarSpeed", i) && i >= 1 && i <= 20) diff --git a/Src/Orbiter/Config.h b/Src/Orbiter/Config.h index 7927f63ab..edad56299 100644 --- a/Src/Orbiter/Config.h +++ b/Src/Orbiter/Config.h @@ -227,16 +227,16 @@ struct CFG_JOYSTICKPRM { struct CFG_UIPRM { // user interface options DWORD MouseFocusMode; // 0: focus requires click; 1: focus requires click for child windows only; 2: focus follow mouse - DWORD MenuMode; // 0=show, 1=hide, 2=auto-hide + int MenuMode; // 0=show, 1=hide, 2=auto-hide bool bMenuLabelOnly; // display only menu labels? bool bWarpAlways; // always display time acceleration != 1 bool bWarpScientific; // display time acceleration in scientific notation? - DWORD InfoMode; // 0=show, 1=hide, 2=auto-hide - DWORD InfoAuxIdx[2]; // index for auxiliary info bars left/right (0=none) - DWORD MenuOpacity; // menubar opacity (0-10) - DWORD InfoOpacity; // infobar opacity (0-20) - DWORD MenuScrollspeed; // menubar scroll speed (1-20) - DWORD PauseIndMode; // 0=flash on pause/resume, 1=show on pause, 2=don't show + int InfoMode; // 0=show, 1=hide, 2=auto-hide + int InfoAuxIdx[2]; // index for auxiliary info bars left/right (0=none) + int MenuOpacity; // menubar opacity (0-10) + int InfoOpacity; // infobar opacity (0-20) + int MenuScrollspeed; // menubar scroll speed (1-20) + int PauseIndMode; // 0=flash on pause/resume, 1=show on pause, 2=don't show int SelVesselTab; // tab to open in vessel selection dialog int SelVesselRange; // "nearby" range for vessel selection dialog bool bSelVesselFlat; // flat assemblies for vessel selection dialog diff --git a/Src/Orbiter/DlgCamera.cpp b/Src/Orbiter/DlgCamera.cpp index 4efa3226a..1077fd62d 100644 --- a/Src/Orbiter/DlgCamera.cpp +++ b/Src/Orbiter/DlgCamera.cpp @@ -144,7 +144,7 @@ void DlgCamera::AddCbodyNode(const CelestialBody *cbody) { } void DlgCamera::DrawTarget() { - const ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_Border | ImGuiChildFlags_ResizeX; + const ImGuiWindowFlags window_flags = ImGuiChildFlags_Border | ImGuiChildFlags_ResizeX; ImGui::BeginChild("ChildL", ImVec2(250, 0), window_flags); for (int i = 0; i < g_psys->nStar(); i++) @@ -203,7 +203,7 @@ void DlgCamera::DrawTarget() { ImGui::EndChild(); } void DlgCamera::DrawTrack() { - ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGuiWindowFlags window_flags = ImGuiChildFlags_ResizeX; ImGui::BeginChild("ChildL", ImVec2(250, 0), window_flags); { ImGui::BeginGroupPanel("Moveable modes"); @@ -279,7 +279,7 @@ void DlgCamera::DrawTrack() { ImGui::EndChild(); } void DlgCamera::DrawGround() { - const ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX;; + const ImGuiWindowFlags window_flags = ImGuiChildFlags_ResizeX;; ImGui::BeginChild("ChildL", ImVec2(250, 0), window_flags); { ImGui::BeginGroupPanel("Ground Location"); @@ -390,7 +390,7 @@ void DlgCamera::DrawFoV() { } } void DlgCamera::DrawPreset() { - ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX;;; + ImGuiWindowFlags window_flags = ImGuiChildFlags_ResizeX;;; static float sz1 = 0.0; float sz2; // ImGui::Splitter(true, 0.5f, 8.0f, &sz1, &sz2, 8, 8, ImGui::GetContentRegionAvail().y); diff --git a/Src/Orbiter/DlgFocus.cpp b/Src/Orbiter/DlgFocus.cpp index c84b07e12..fba754011 100644 --- a/Src/Orbiter/DlgFocus.cpp +++ b/Src/Orbiter/DlgFocus.cpp @@ -44,7 +44,7 @@ void DlgFocus::OnDraw() { } void DlgFocus::DrawAll() { - ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGuiWindowFlags window_flags = ImGuiChildFlags_ResizeX; ImGui::Text("Spacecraft : %s", m_SelectedShip.c_str()); ImGui::BeginChild("ChildL", ImVec2(150, 0), true, window_flags); @@ -81,7 +81,7 @@ void DlgFocus::DrawAll() { ImGui::EndChild(); } void DlgFocus::DrawNearby() { - ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGuiWindowFlags window_flags = ImGuiChildFlags_ResizeX; ImGui::Text("Spacecraft : %s", m_SelectedShip.c_str()); ImGui::BeginChild("ChildL", ImVec2(150, 0), true, window_flags); @@ -138,7 +138,7 @@ void DlgFocus::DrawLocation() { } } - ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGuiWindowFlags window_flags = ImGuiChildFlags_ResizeX; ImGui::Text("Spacecraft : %s", m_SelectedShip.c_str()); ImGui::BeginChild("ChildL", ImVec2(150,0), true, window_flags); @@ -185,7 +185,7 @@ void DlgFocus::DrawClass() { } } - ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGuiWindowFlags window_flags = ImGuiChildFlags_ResizeX; ImGui::Text("Spacecraft : %s", m_SelectedShip.c_str()); ImGui::BeginChild("ChildL", ImVec2(150,0), true, window_flags); diff --git a/Src/Orbiter/DlgInfo.cpp b/Src/Orbiter/DlgInfo.cpp index 37dc1f887..7b1000be9 100644 --- a/Src/Orbiter/DlgInfo.cpp +++ b/Src/Orbiter/DlgInfo.cpp @@ -874,7 +874,7 @@ void DlgInfo::DrawInfoBase(Base *base) { } void DlgInfo::OnDraw() { - ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiChildFlags_ResizeX; + ImGuiWindowFlags window_flags = ImGuiChildFlags_ResizeX; ImGui::BeginChild("ChildL", ImVec2(250, 0), true, window_flags); { ImVec2 button_sz(ImVec2(ImGui::GetContentRegionAvail().x/2, 20)); diff --git a/Src/Orbiter/DlgMenuCfg.cpp b/Src/Orbiter/DlgMenuCfg.cpp index 765c65f48..6317aae63 100644 --- a/Src/Orbiter/DlgMenuCfg.cpp +++ b/Src/Orbiter/DlgMenuCfg.cpp @@ -5,194 +5,80 @@ // Menu bar configuration dialog // ====================================================================== -#define STRICT 1 - -#include "Orbiter.h" -#include "Pane.h" -#include "MenuInfoBar.h" #include "DlgMenuCfg.h" -#include "Resource.h" -#include "Resource2.h" -#include "DlgCtrl.h" +#include "MenuInfoBar.h" +#include "Pane.h" +#include "imgui.h" +#include "imgui_extras.h" +#include "Orbiter.h" extern Orbiter *g_pOrbiter; extern Pane *g_pane; -extern HELPCONTEXT DefHelpContext; - -// ====================================================================== - -DlgMenuCfg::DlgMenuCfg (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_MENU_CONFIG, 0, 0, context) -{ -} - -// ====================================================================== -DlgMenuCfg::~DlgMenuCfg () +DlgMenuCfg::DlgMenuCfg(): ImGuiDialog("Orbiter: Configure menu bars") { } -// ====================================================================== - -BOOL DlgMenuCfg::OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam) -{ - SendDlgItemMessage (hDlg, IDC_MNUCFG_SHOWMENU + g_pOrbiter->Cfg()->CfgUIPrm.MenuMode, - BM_SETCHECK, BST_CHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MNUCFG_SHOWINFO + g_pOrbiter->Cfg()->CfgUIPrm.InfoMode, - BM_SETCHECK, BST_CHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MNUCFG_LABELONLY, BM_SETCHECK, - g_pOrbiter->Cfg()->CfgUIPrm.bMenuLabelOnly ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MNUCFG_SHOWWARP, BM_SETCHECK, - g_pOrbiter->Cfg()->CfgUIPrm.bWarpAlways ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MNUCFG_SCIWARP, BM_SETCHECK, - g_pOrbiter->Cfg()->CfgUIPrm.bWarpScientific ? BST_CHECKED : BST_UNCHECKED, 0); - for (int i = 0; i < 2; i++) { - int id = IDC_MNUCFG_LINFO+i; - SendDlgItemMessage (hDlg, id, CB_RESETCONTENT, 0, 0); - SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)"None"); - SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)"Frame rate"); - SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)"Render statistics"); - SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)"Viewport info"); - SendDlgItemMessage (hDlg, id, CB_SETCURSEL, g_pOrbiter->Cfg()->CfgUIPrm.InfoAuxIdx[i], 0); - } - SendDlgItemMessage (hDlg, IDC_PAUSEINDICATOR, CB_RESETCONTENT, 0, 0); - SendDlgItemMessage (hDlg, IDC_PAUSEINDICATOR, CB_ADDSTRING, 0, (LPARAM)"Flash on action"); - SendDlgItemMessage (hDlg, IDC_PAUSEINDICATOR, CB_ADDSTRING, 0, (LPARAM)"Show on pause/record/playback"); - SendDlgItemMessage (hDlg, IDC_PAUSEINDICATOR, CB_ADDSTRING, 0, (LPARAM)"Don't show"); - SendDlgItemMessage (hDlg, IDC_PAUSEINDICATOR, CB_SETCURSEL, g_pOrbiter->Cfg()->CfgUIPrm.PauseIndMode, 0); - - GAUGEPARAM gp1 = { 0, 10, GAUGEPARAM::LEFT, GAUGEPARAM::BLACK }; - oapiSetGaugeParams (GetDlgItem (hDlg, IDC_MNUCFG_MENUOPACITY), &gp1); - int scl = g_pOrbiter->Cfg()->CfgUIPrm.MenuOpacity; - oapiSetGaugePos (GetDlgItem (hDlg, IDC_MNUCFG_MENUOPACITY), scl); - - GAUGEPARAM gp2 = { 0, 10, GAUGEPARAM::LEFT, GAUGEPARAM::BLACK }; - oapiSetGaugeParams (GetDlgItem (hDlg, IDC_MNUCFG_INFOOPACITY), &gp2); - scl = g_pOrbiter->Cfg()->CfgUIPrm.InfoOpacity; - oapiSetGaugePos (GetDlgItem (hDlg, IDC_MNUCFG_INFOOPACITY), scl); - - GAUGEPARAM gp3 = { 1, 20, GAUGEPARAM::LEFT, GAUGEPARAM::BLACK }; - oapiSetGaugeParams (GetDlgItem (hDlg, IDC_MNUCFG_SCROLLSPEED), &gp3); - scl = g_pOrbiter->Cfg()->CfgUIPrm.MenuScrollspeed; - oapiSetGaugePos (GetDlgItem (hDlg, IDC_MNUCFG_SCROLLSPEED), scl); - - return TRUE; -} - -// ====================================================================== - -BOOL DlgMenuCfg::OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl) -{ - switch (id) { - case IDHELP: - DefHelpContext.topic = (char*)"/menucfg.htm"; - g_pOrbiter->OpenHelp (&DefHelpContext); - return TRUE; - case IDC_MNUCFG_SHOWMENU: - case IDC_MNUCFG_SHOWMENU+1: - case IDC_MNUCFG_SHOWMENU+2: - if (code == BN_CLICKED) { - int mode = id-IDC_MNUCFG_SHOWMENU; - g_pOrbiter->Cfg()->CfgUIPrm.MenuMode = mode; - g_pane->MIBar()->SetMenuMode (mode); - } - break; - case IDC_MNUCFG_SHOWINFO: - case IDC_MNUCFG_SHOWINFO+1: - case IDC_MNUCFG_SHOWINFO+2: - if (code == BN_CLICKED) { - int mode = id-IDC_MNUCFG_SHOWINFO; - g_pOrbiter->Cfg()->CfgUIPrm.InfoMode = mode; - g_pane->MIBar()->SetInfoMode (mode); - return TRUE; - } - break; - case IDC_MNUCFG_LABELONLY: - if (code == BN_CLICKED) { - bool check = (SendDlgItemMessage (hDlg, id, BM_GETCHECK, 0, 0) == TRUE); - g_pOrbiter->Cfg()->CfgUIPrm.bMenuLabelOnly = check; - g_pane->MIBar()->SetLabelOnly (check); - return TRUE; - } - break; - case IDC_MNUCFG_SHOWWARP: - if (code == BN_CLICKED) { - bool check = (SendDlgItemMessage (hDlg, id, BM_GETCHECK, 0, 0) == TRUE); - g_pOrbiter->Cfg()->CfgUIPrm.bWarpAlways = check; - g_pane->MIBar()->SetWarpAlways (check); - return TRUE; - } - break; - case IDC_MNUCFG_SCIWARP: - if (code == BN_CLICKED) { - bool check = (SendDlgItemMessage (hDlg, id, BM_GETCHECK, 0, 0) == TRUE); - g_pOrbiter->Cfg()->CfgUIPrm.bWarpScientific = check; - g_pane->MIBar()->SetWarpScientific (check); - return TRUE; - } - break; - case IDC_MNUCFG_LINFO: - case IDC_MNUCFG_RINFO: - if (code == CBN_SELCHANGE) { - int side = id-IDC_MNUCFG_LINFO; - int idx = SendDlgItemMessage (hDlg, IDC_MNUCFG_LINFO+side, CB_GETCURSEL, 0, 0); - if (idx != CB_ERR) g_pOrbiter->Cfg()->CfgUIPrm.InfoAuxIdx[side] = idx; - if (idx && g_pOrbiter->Cfg()->CfgUIPrm.InfoAuxIdx[1-side] == idx) { - g_pOrbiter->Cfg()->CfgUIPrm.InfoAuxIdx[1-side] = 0; - g_pane->MIBar()->SetAuxInfobar (1-side,0); - SendDlgItemMessage (hDlg, IDC_MNUCFG_LINFO+1-side, CB_SETCURSEL, 0, 0); - } - g_pane->MIBar()->SetAuxInfobar (side,idx); - return TRUE; - } - break; - case IDC_PAUSEINDICATOR: - if (code == CBN_SELCHANGE) { - int idx = SendDlgItemMessage (hDlg, IDC_PAUSEINDICATOR, CB_GETCURSEL, 0, 0); - if (idx != CB_ERR && idx != g_pOrbiter->Cfg()->CfgUIPrm.PauseIndMode) { - g_pOrbiter->Cfg()->CfgUIPrm.PauseIndMode = idx; - g_pane->MIBar()->SetPauseIndicatorMode (idx); - } - } - } - return DialogWin::OnCommand (hDlg, id, code, hControl); -} - -// ====================================================================== - -BOOL DlgMenuCfg::OnHScroll (HWND hDlg, WORD request, WORD curpos, HWND hControl) +void DlgMenuCfg::OnDraw() { - switch (GetDlgCtrlID (hControl)) { - case IDC_MNUCFG_MENUOPACITY: - switch (request) { - case SB_THUMBTRACK: - case SB_LINELEFT: - case SB_LINERIGHT: - g_pOrbiter->Cfg()->CfgUIPrm.MenuOpacity = curpos; - g_pane->MIBar()->SetOpacity (curpos); - return 0; - } - break; - case IDC_MNUCFG_INFOOPACITY: - switch (request) { - case SB_THUMBTRACK: - case SB_LINELEFT: - case SB_LINERIGHT: - g_pOrbiter->Cfg()->CfgUIPrm.InfoOpacity = curpos; - g_pane->MIBar()->SetOpacityInfo (curpos); - return 0; - } - break; - case IDC_MNUCFG_SCROLLSPEED: - switch (request) { - case SB_THUMBTRACK: - case SB_LINELEFT: - case SB_LINERIGHT: - g_pOrbiter->Cfg()->CfgUIPrm.MenuScrollspeed = curpos; - g_pane->MIBar()->SetScrollspeed (curpos); - return 0; - } - break; - } - return DialogWin::OnHScroll (hDlg, request, curpos, hControl); + const char *modes[] = {"Show", "Hide", "Auto-hide"}; + + CFG_UIPRM &prm = g_pOrbiter->Cfg()->CfgUIPrm; + MenuInfoBar *mib = g_pane->MIBar(); + + ImGui::BeginGroupPanel("Menu bar"); + ImGui::PushID(1); + ImGui::RadioButton("Show", &prm.MenuMode, 0); + ImGui::SameLine(); + ImGui::RadioButton("Hide", &prm.MenuMode, 1); + ImGui::SameLine(); + ImGui::RadioButton("Auto-hide", &prm.MenuMode, 2); + mib->SetMenuMode (prm.MenuMode); + + if(ImGui::Checkbox("Labels only", &prm.bMenuLabelOnly)) + mib->SetLabelOnly (prm.bMenuLabelOnly); + + if(ImGui::SliderInt("Opacity", &prm.MenuOpacity, 0, 10)) + mib->SetOpacity (prm.MenuOpacity); + + if(ImGui::SliderInt("Scroll speed", &prm.MenuScrollspeed, 1, 20)) + mib->SetScrollspeed (prm.MenuScrollspeed); + ImGui::PopID(); + ImGui::EndGroupPanel(); + + + ImGui::BeginGroupPanel("Info bars"); + ImGui::PushID(2); + ImGui::RadioButton("Show", &prm.InfoMode, 0); + ImGui::SameLine(); + ImGui::RadioButton("Hide", &prm.InfoMode, 1); + ImGui::SameLine(); + ImGui::RadioButton("Auto-hide", &prm.InfoMode, 2); + mib->SetInfoMode (prm.InfoMode); + + if(ImGui::Checkbox("Always show warp factor", &prm.bWarpAlways)) + mib->SetWarpAlways (prm.bWarpAlways); + + if(ImGui::Checkbox("Use scientific notation for warp", &prm.bWarpScientific)) + mib->SetWarpScientific (prm.bWarpScientific); + + if(ImGui::SliderInt("Opacity", &prm.InfoOpacity, 0, 10)) + mib->SetOpacityInfo (prm.InfoOpacity); + ImGui::PopID(); + ImGui::EndGroupPanel(); + + ImGui::BeginGroupPanel("Auxiliary info bars"); + const char *auxmode[]={"None", "Frame rate", "Render statistics", "Viewport info"}; + ImGui::Combo("Left", &prm.InfoAuxIdx[0], auxmode, IM_ARRAYSIZE(auxmode)); + mib->SetAuxInfobar (0, prm.InfoAuxIdx[0]); + ImGui::Combo("Right", &prm.InfoAuxIdx[1], auxmode, IM_ARRAYSIZE(auxmode)); + mib->SetAuxInfobar (1, prm.InfoAuxIdx[1]); + + ImGui::EndGroupPanel(); + + ImGui::BeginGroupPanel("Action indicator"); + const char *actionmode[]={"Flash on action", "Show on pause/record/playback", "Don't show"}; + ImGui::Combo("Mode", &prm.PauseIndMode, actionmode, IM_ARRAYSIZE(actionmode)); + mib->SetPauseIndicatorMode (prm.PauseIndMode); + ImGui::EndGroupPanel(); } diff --git a/Src/Orbiter/DlgMenuCfg.h b/Src/Orbiter/DlgMenuCfg.h index 90212d7aa..e8954dc50 100644 --- a/Src/Orbiter/DlgMenuCfg.h +++ b/Src/Orbiter/DlgMenuCfg.h @@ -8,15 +8,12 @@ #ifndef __DLGMENUCFG_H #define __DLGMENUCFG_H -#include "DialogWin.h" +#include "OrbiterAPI.h" -class DlgMenuCfg: public DialogWin { +class DlgMenuCfg: public ImGuiDialog { public: - DlgMenuCfg (HINSTANCE hInstance, HWND hParent, void *context); - ~DlgMenuCfg (); - BOOL OnInitDialog (HWND hWnd, WPARAM wParam, LPARAM lParam); - BOOL OnCommand (HWND hWnd, WORD id, WORD code, HWND hControl); - BOOL OnHScroll (HWND hWnd, WORD request, WORD curpos, HWND hControl); + DlgMenuCfg (); + void OnDraw(); }; #endif // !__DLGMENUCFG_H \ No newline at end of file From 9974b51dfac7cb8ef0f6af63e78b286598151493 Mon Sep 17 00:00:00 2001 From: Gondos Date: Sun, 2 Feb 2025 01:13:58 +0100 Subject: [PATCH 25/51] [ImGui]Convert ExtMFD --- Extern/imgui/CMakeLists.txt | 6 +- OVP/D3D9Client/D3D9Client.cpp | 18 +- OVP/D3D9Client/D3D9Client.h | 2 + Orbitersdk/include/GraphicsAPI.h | 7 + .../include}/IconsFontAwesome6.h | 0 Orbitersdk/include/OrbiterAPI.h | 20 +- Orbitersdk/include/imgui_extras.h | 1 + Src/Orbiter/DlgMgr.cpp | 22 ++ Src/Orbiter/OrbiterAPI.cpp | 8 + Src/Plugin/ExtMFD/Bitmaps/bt_stick.bmp | Bin 700 -> 0 bytes Src/Plugin/ExtMFD/CMakeLists.txt | 3 +- Src/Plugin/ExtMFD/ExtMFD.cpp | 42 +- Src/Plugin/ExtMFD/ExtMFD.rc | 115 ------ Src/Plugin/ExtMFD/MFDWindow.cpp | 360 ++++++++---------- Src/Plugin/ExtMFD/MFDWindow.h | 32 +- Src/Plugin/ExtMFD/resource.h | 39 -- 16 files changed, 248 insertions(+), 427 deletions(-) rename {Extern/imgui => Orbitersdk/include}/IconsFontAwesome6.h (100%) delete mode 100644 Src/Plugin/ExtMFD/Bitmaps/bt_stick.bmp delete mode 100644 Src/Plugin/ExtMFD/ExtMFD.rc delete mode 100644 Src/Plugin/ExtMFD/resource.h diff --git a/Extern/imgui/CMakeLists.txt b/Extern/imgui/CMakeLists.txt index 3acefef93..27244b3c7 100644 --- a/Extern/imgui/CMakeLists.txt +++ b/Extern/imgui/CMakeLists.txt @@ -6,8 +6,8 @@ FetchContent_Declare( imgui GIT_REPOSITORY https://github.com/ocornut/imgui.git GIT_TAG v1.91.7-docking - PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/imconfig.h ${CMAKE_CURRENT_SOURCE_DIR}/IconsFontAwesome6.h . - UPDATE_DISCONNECTED 1 + PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/imconfig.h . +# UPDATE_DISCONNECTED 1 ) FetchContent_MakeAvailable(imgui) @@ -15,7 +15,7 @@ install(FILES ${imgui_SOURCE_DIR}/misc/fonts/Roboto-Medium.ttf fa-solid-900.ttf DESTINATION ${ORBITER_INSTALL_ROOT_DIR} ) -install(FILES ${imgui_SOURCE_DIR}/imgui.h ${imgui_SOURCE_DIR}/imconfig.h IconsFontAwesome6.h +install(FILES ${imgui_SOURCE_DIR}/imgui.h ${imgui_SOURCE_DIR}/imconfig.h DESTINATION ${ORBITER_INSTALL_SDK_DIR}/include ) diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index f0fac11f8..32ea4999b 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -2749,6 +2749,11 @@ void D3D9Client::clbkImGuiRenderDrawData() ImGui::UpdatePlatformWindows(); ImGui::RenderPlatformWindowsDefault(); } + + for(auto &surf: ImTextures) { + clbkReleaseSurface(surf); + } + ImTextures.clear(); } void D3D9Client::clbkImGuiInit() { @@ -2758,9 +2763,20 @@ void D3D9Client::clbkImGuiInit() void D3D9Client::clbkImGuiShutdown() { _TRACE; + // Clean up also here just in case + for(auto &surf: ImTextures) { + clbkReleaseSurface(surf); + } + ImTextures.clear(); ImGui_ImplDX9_Shutdown(); } - +uint64_t D3D9Client::clbkImGuiSurfaceTexture(SURFHANDLE surf) +{ + ImTextures.push_back(surf); + clbkIncrSurfaceRef(surf); + LPDIRECT3DTEXTURE9 pTxt = SURFACE(surf)->GetTexture(); + return (uint64_t)pTxt; +} // ======================================================================= bool D3D9Client::clbkSplashLoadMsg (const char *msg, int line) diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 131937995..9109f8b85 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -1041,6 +1041,7 @@ class D3D9Client : public GraphicsClient void clbkImGuiRenderDrawData() override; void clbkImGuiInit() override; void clbkImGuiShutdown() override; + uint64_t clbkImGuiSurfaceTexture(SURFHANDLE surf) override; HWND GetRenderWindow () const { return hRenderWnd; } CD3DFramework9 * GetFramework() const { return pFramework; } @@ -1345,6 +1346,7 @@ class D3D9Client : public GraphicsClient std::vector RenderProcs; std::vector GenericProcs; + std::vector ImTextures; mutable std::list RenderStack; HFONT hLblFont1; diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 3e49944eb..9c33af69c 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -1485,6 +1485,13 @@ class OAPIFUNC GraphicsClient: public Module { virtual void clbkImGuiRenderDrawData () = 0; virtual void clbkImGuiInit () = 0; virtual void clbkImGuiShutdown() = 0; + // Returns an ImTextureID from a surface so that it can be used in + // ImGui widgets. + // Note: we use uint64_t so we don't have to include imgui.h + // This method should make sure the texture won't be released + // before the frame is ended by e.g. incrementing its reference + // counter and releasing it once the frame has been rendered. + virtual uint64_t clbkImGuiSurfaceTexture(SURFHANDLE surf) = 0; protected: /** \brief Launchpad video tab indicator diff --git a/Extern/imgui/IconsFontAwesome6.h b/Orbitersdk/include/IconsFontAwesome6.h similarity index 100% rename from Extern/imgui/IconsFontAwesome6.h rename to Orbitersdk/include/IconsFontAwesome6.h diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 378627f66..6035b385c 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -701,7 +701,6 @@ class OAPIFUNC ImGuiDialog { */ virtual void OnDraw() = 0; bool active = false; -private: const std::string name; ImGuiDefaultSize defaultSize; }; @@ -6152,10 +6151,29 @@ OAPIFUNC void oapiCloseDialog (ImGuiDialog *dlg); */ OAPIFUNC void oapiAddNotification(int type, const char *title, const char *content = ""); + /** + * \brief Retreives a texture ID for use with ImGui. + * \param surf surface handle + * \return The value returned can be used where ImGui expects an ImTextureID argument. + */ +OAPIFUNC uint64_t oapiGetImTextureID (SURFHANDLE surf); /** * \brief Retrieves the context pointer of a dialog box which has been defined during the call to oapiOpenDialog(). * \param hDlg dialog window handle * \note This function returns NULL if no context pointer was specified in oapiOpenDialog(). + * \n Typical usage:\n + * \code + * SURFHANDLE surf = m_mfd->GetDisplaySurface(); + * if (surf) { + * ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left + * ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right + * ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint + * ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.0f); + * ImTextureID txt = oapiGetImTextureID(surf); + * ImGui::Image(txt, ImVec2(sz.x, sz.y), uv_min, uv_max, tint_col, border_col); + * } + * \endcode + * */ OAPIFUNC void *oapiGetDialogContext (HWND hDlg); diff --git a/Orbitersdk/include/imgui_extras.h b/Orbitersdk/include/imgui_extras.h index 6ce7bbff5..92034c4c8 100644 --- a/Orbitersdk/include/imgui_extras.h +++ b/Orbitersdk/include/imgui_extras.h @@ -8,4 +8,5 @@ namespace ImGui { OAPIFUNC void HelpMarker(const char* desc, bool sameline = true); OAPIFUNC void BeginGroupPanel(const char* name, const ImVec2& size = ImVec2(-1.0f, -1.0f)); OAPIFUNC void EndGroupPanel(); + OAPIFUNC bool MenuButton(const char *label, const char *tooltip = NULL); }; diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index 63a881e91..d22ace95f 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -436,6 +436,7 @@ static void ImGuiSetStyle(bool bStyleDark_, float alpha_) { // Setup Dear ImGui style ImGui::StyleColorsClassic(); + //ImGui::StyleColorsLight(); ImGuiStyle& style = ImGui::GetStyle(); style.Alpha = 1.0f; @@ -957,4 +958,25 @@ namespace ImGui { ImGui::EndGroup(); ImGui::Dummy(ImVec2(0.0f, 0.0f)); } + + DLLEXPORT bool MenuButton(const char *label, const char *tooltip) + { + ImGuiContext& g = *GImGui; + const ImGuiWindow* window = ImGui::GetCurrentWindow(); + const ImRect titleBarRect = window->TitleBarRect(); + const ImGuiStyle& style = g.Style; + ImGuiLastItemData last_item_backup = g.LastItemData; + ImGui::PushClipRect( titleBarRect.Min, titleBarRect.Max, false ); + float width = strlen(label) * g.FontSize; + float offset = titleBarRect.Max.x - width - titleBarRect.Min.x - g.Style.FramePadding.x; + ImGui::SetCursorPos( ImVec2( offset, 0.0f ) ); + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0,0,0,0)); + bool ret = ImGui::Button( label ); + ImGui::PopStyleColor(); + if(tooltip && ImGui::IsItemHovered()) + ImGui::SetTooltip(tooltip); + ImGui::PopClipRect(); + g.LastItemData = last_item_backup; + return ret; + } } diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index 08ed0090d..617ca3941 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -1966,6 +1966,14 @@ DLLEXPORT HDC oapiGetDC (SURFHANDLE surf) return hDC; } +DLLEXPORT uint64_t oapiGetImTextureID (SURFHANDLE surf) +{ + oapi::GraphicsClient *gc = g_pOrbiter->GetGraphicsClient(); + if (gc && surf) + return gc->clbkImGuiSurfaceTexture (surf); + return 0; +} + DLLEXPORT void oapiReleaseDC (SURFHANDLE surf, HDC hDC) { oapi::GraphicsClient *gc = g_pOrbiter->GetGraphicsClient(); diff --git a/Src/Plugin/ExtMFD/Bitmaps/bt_stick.bmp b/Src/Plugin/ExtMFD/Bitmaps/bt_stick.bmp deleted file mode 100644 index a3d8849687d162346354abc6322e3ca5a502b44b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 700 zcmZva%`XE%7{;G%i*8%(+O^gStzE48H{2zgh^vHS59-jkaKOzGH;Icw{{aUjI5>*n zf^eY~;n0IaeKcLxJ2ND@Jjpwm-@G65OfsWm`yp`M(3+)4QKTs(L}?XL;{b~hLKaNE z@58J6IGUQqMSd1Xu8Ruo4<;vZmdoL~P(XQc5tZd-Jg%&uRw|)UF2k!Ms1TZ%O#MLjvuBPk=B zjB31|In%?k+@^{9xl@zea6iHK1-M^Sf3Ft)o~S;JAyML kM~LM!1Koqezt{}q+2p2v;^6$?{j7)Uuixh9S@Z+H01{n?nE(I) diff --git a/Src/Plugin/ExtMFD/CMakeLists.txt b/Src/Plugin/ExtMFD/CMakeLists.txt index aa5f15332..90f6632f2 100644 --- a/Src/Plugin/ExtMFD/CMakeLists.txt +++ b/Src/Plugin/ExtMFD/CMakeLists.txt @@ -3,7 +3,6 @@ add_library(ExtMFD SHARED ExtMFD.cpp - ExtMFD.rc MFDWindow.cpp ) @@ -15,11 +14,13 @@ target_include_directories(ExtMFD target_link_libraries(ExtMFD ${ORBITER_LIB} ${ORBITER_SDK_LIB} + imgui ) add_dependencies(ExtMFD ${OrbiterTgt} Orbitersdk + imgui ) set_target_properties(ExtMFD diff --git a/Src/Plugin/ExtMFD/ExtMFD.cpp b/Src/Plugin/ExtMFD/ExtMFD.cpp index 49ab879ce..275365c6f 100644 --- a/Src/Plugin/ExtMFD/ExtMFD.cpp +++ b/Src/Plugin/ExtMFD/ExtMFD.cpp @@ -12,20 +12,14 @@ // Open multifunctional displays (MFD) in external windows // ============================================================== -#define STRICT 1 #define ORBITER_MODULE -#include #include "MFDWindow.h" #include "orbitersdk.h" -#include "resource.h" -#include // ============================================================== // Global variables // ============================================================== -HINSTANCE g_hInst; // module instance handle -HBITMAP g_hPin; // "pin" button bitmap DWORD g_dwCmd; // custom function identifier // ============================================================== @@ -33,9 +27,6 @@ DWORD g_dwCmd; // custom function identifier // ============================================================== void OpenDlgClbk (void *context); -INT_PTR CALLBACK MsgProc (HWND, UINT, WPARAM, LPARAM); -extern LRESULT FAR PASCAL MFD_WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -extern LRESULT FAR PASCAL MFD_BtnProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // ============================================================== // API interface @@ -47,36 +38,12 @@ extern LRESULT FAR PASCAL MFD_BtnProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPAR DLLCLBK void InitModule (HINSTANCE hDLL) { - g_hInst = hDLL; // remember the instance handle - // To allow the user to open our new dialog box, we create // an entry in the "Custom Functions" list which is accessed // in Orbiter via Ctrl-F4. g_dwCmd = oapiRegisterCustomCmd ((char*)"External MFD", (char*)"Opens a multifunctional display in an external window", OpenDlgClbk, NULL); - - // Load the bitmap for the "pin" title button - g_hPin = (HBITMAP)LoadImage (g_hInst, MAKEINTRESOURCE(IDB_PIN), IMAGE_BITMAP, 15, 30, 0); - - // Register a window classes for the MFD display and buttons - WNDCLASS wndClass; - wndClass.style = CS_HREDRAW | CS_VREDRAW; - wndClass.lpfnWndProc = MFD_WndProc; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = hDLL; - wndClass.hIcon = NULL; - wndClass.hCursor = LoadCursor (NULL, MAKEINTRESOURCE(IDC_ARROW)); - wndClass.hbrBackground = (HBRUSH)GetStockObject (BLACK_BRUSH); - wndClass.lpszMenuName = NULL; - wndClass.lpszClassName = "ExtMFD_Display"; - RegisterClass (&wndClass); - - wndClass.lpfnWndProc = MFD_BtnProc; - wndClass.hbrBackground = (HBRUSH)GetStockObject (LTGRAY_BRUSH); - wndClass.lpszClassName = "ExtMFD_Button"; - RegisterClass (&wndClass); } // ============================================================== @@ -85,13 +52,6 @@ DLLCLBK void InitModule (HINSTANCE hDLL) DLLCLBK void ExitModule (HINSTANCE hDLL) { - // Unregister window classes - UnregisterClass ("ExtMFD_Display", g_hInst); - UnregisterClass ("ExtMFD_Button", g_hInst); - - // Free bitmap resources - DeleteObject (g_hPin); - // Unregister the custom function in Orbiter oapiUnregisterCustomCmd (g_dwCmd); } @@ -124,7 +84,7 @@ DLLCLBK void opcLoadState (FILEHANDLE scn) void OpenDlgClbk (void *context) { MFDSPEC spec = {{0,0,100,100},6,6,10,10}; - oapiRegisterExternMFD (new MFDWindow (g_hInst, spec), spec); + oapiRegisterExternMFD (new MFDWindow (spec), spec); } // ============================================================== diff --git a/Src/Plugin/ExtMFD/ExtMFD.rc b/Src/Plugin/ExtMFD/ExtMFD.rc deleted file mode 100644 index c7dab66b6..000000000 --- a/Src/Plugin/ExtMFD/ExtMFD.rc +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) Martin Schweiger -// Licensed under the MIT License - -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.K.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_MFD DIALOGEX 0, 0, 238, 185 -STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE -CAPTION "MFD" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - CONTROL "",IDC_DISPLAY,"ExtMFD_Display",WS_TABSTOP,31,2,175,157 - CONTROL "",IDC_BUTTON1,"ExtMFD_Button",WS_TABSTOP,0,17,30,14 - CONTROL "",IDC_BUTTON2,"ExtMFD_Button",WS_TABSTOP,0,41,30,14 - CONTROL "",IDC_BUTTON3,"ExtMFD_Button",WS_TABSTOP,0,65,30,14 - CONTROL "",IDC_BUTTON4,"ExtMFD_Button",WS_TABSTOP,0,89,30,14 - CONTROL "",IDC_BUTTON5,"ExtMFD_Button",WS_TABSTOP,0,113,30,14 - CONTROL "",IDC_BUTTON6,"ExtMFD_Button",WS_TABSTOP,0,137,30,14 - CONTROL "",IDC_BUTTON7,"ExtMFD_Button",WS_TABSTOP,208,17,30,14 - CONTROL "",IDC_BUTTON8,"ExtMFD_Button",WS_TABSTOP,208,41,30,14 - CONTROL "",IDC_BUTTON9,"ExtMFD_Button",WS_TABSTOP,208,65,30,14 - CONTROL "",IDC_BUTTON10,"ExtMFD_Button",WS_TABSTOP,208,89,30,14 - CONTROL "",IDC_BUTTON11,"ExtMFD_Button",WS_TABSTOP,208,113,30,14 - CONTROL "",IDC_BUTTON12,"ExtMFD_Button",WS_TABSTOP,208,137,30,14 - CONTROL "",IDC_BUTTON_SEL,"ExtMFD_Button",WS_TABSTOP,106,171,30,14 - CONTROL "",IDC_BUTTON_PWR,"ExtMFD_Button",WS_TABSTOP,67,171,30,14 - CONTROL "",IDC_BUTTON_MNU,"ExtMFD_Button",WS_TABSTOP,145,171,30,14 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_PIN BITMAP "Bitmaps\\bt_stick.bmp" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_INFO "EXTERNAL MFD:\r\n\r\nProvides support for displaying MFD (multi-functional display) instruments in separate windows.\r\n\r\nExternal MFD windows can be opened by selecting the ""External MFD"" entry in the Custom Functions dialog (Ctrl-F4)." - IDS_TYPE "Tools and dialogs" -END - -#endif // English (U.K.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Src/Plugin/ExtMFD/MFDWindow.cpp b/Src/Plugin/ExtMFD/MFDWindow.cpp index df3d95666..fcdf5abdb 100644 --- a/Src/Plugin/ExtMFD/MFDWindow.cpp +++ b/Src/Plugin/ExtMFD/MFDWindow.cpp @@ -12,260 +12,212 @@ // Class implementation for MFDWindow. Defines the properties and // state of an MFD display in a dialog box // ============================================================== - #include "MFDWindow.h" -#include "resource.h" -#include // temporary - -using std::min; -using std::max; +#include +#include +#include "imgui.h" +#include "imgui_extras.h" +#include "IconsFontAwesome6.h" // ============================================================== -// prototype definitions +// class MFDWindow -INT_PTR CALLBACK DlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +const int button_yoffset = 30; -// ============================================================== -// class MFDWindow +class DlgExtMFD : public ImGuiDialog { +public: + DlgExtMFD(const std::string& name, MFDWindow* mfd); + void OnDraw() override; + void Display() override; + void OnClose() override { + oapiUnregisterExternMFD(m_mfd); + } + MFDWindow* m_mfd; + ImVec2 m_oldSize; +}; -MFDWindow::MFDWindow (HINSTANCE _hInst, const MFDSPEC &spec): ExternMFD (spec), hInst(_hInst) -{ - hBtnFnt = 0; - fnth = 0; - vstick = false; - oapiOpenDialogEx (hInst, IDD_MFD, DlgProc, - DLG_ALLOWMULTI, this); +DlgExtMFD::DlgExtMFD(const std::string& name, MFDWindow* mfd) : ImGuiDialog(name.c_str(), {382,366}) { + m_mfd = mfd; + m_oldSize = ImVec2(0, 0); } -MFDWindow::~MFDWindow () -{ - oapiCloseDialog (hDlg); - if (hBtnFnt) DeleteObject (hBtnFnt); +void DlgExtMFD::Display() { + ImGui::SetNextWindowSize(ImVec2(defaultSize.width, defaultSize.height), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSizeConstraints(ImVec2(382,366), ImVec2(FLT_MAX, FLT_MAX)); + + char cbuf[256] = "MFD ["; + oapiGetObjectName(m_mfd->GetVessel(), cbuf + 5, 250); + strcat(cbuf, "]###"); + strcat(cbuf, name.c_str()); + + bool visible = ImGui::Begin(cbuf, &active); + bool stick = m_mfd->GetStickToVessel(); + if(ImGui::MenuButton(stick ? ICON_FA_THUMBTACK : ICON_FA_THUMBTACK_SLASH, stick ? "Unpin this MFD from the vessel":"Pin this MFD to the current vessel")) + { + m_mfd->ToggleStickToVessel(); + } + + if(visible) { + OnDraw(); + } + ImGui::End(); + if (!active) OnClose(); } -void MFDWindow::Initialise (HWND _hDlg) -{ - extern HBITMAP g_hPin; - hDlg = _hDlg; - hDsp = GetDlgItem (hDlg, IDC_DISPLAY); - for (int i = 0; i < 15; i++) - SetWindowLongPtr (GetDlgItem (hDlg, IDC_BUTTON1+i), GWLP_USERDATA, i); - oapiAddTitleButton (IDSTICK, g_hPin, DLG_CB_TWOSTATE); - SetTitle (); - gap = 3; - Resize (false); -} -void MFDWindow::SetVessel (OBJHANDLE hV) -{ - ExternMFD::SetVessel (hV); - SetTitle (); -} +void DlgExtMFD::OnDraw() { -void MFDWindow::SetTitle () -{ - char cbuf[256] = "MFD ["; - oapiGetObjectName (hVessel, cbuf+5, 250); - strcat (cbuf, "]"); - SetWindowText (hDlg, cbuf); -} + const int button_row_width = 50; + const int button_bottom_height = 50; + const ImVec2 button_sz = ImVec2(40, 20); -void MFDWindow::Resize (bool fixaspect) -{ - RECT r; - GetClientRect (hDlg, &r); - int bw = (r.right*35)/300; - BW = max (30, min (60, bw)); - BH = max (15, min (40, (bw*2)/3)); - int dspw = r.right-2*(BW+gap), dsph = r.bottom-(BH+2*gap); - int ds = min (dspw, dsph); - if (fixaspect && dspw != dsph) { // force aspect adjustment - RECT wr; - ds = max (50, ds); - GetWindowRect (hDlg, &wr); - SetWindowPos (hDlg, NULL, 0, 0, wr.right-wr.left-r.right+ds+2*(BW+gap), wr.bottom-wr.top-r.bottom+ds+(BH+2*gap), SWP_NOMOVE|SWP_NOOWNERZORDER); - return; + + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar; + ImGui::BeginChild("ChildL", ImVec2(button_row_width, ImGui::GetContentRegionAvail().y - button_bottom_height), false, window_flags); + + ImVec2 sz = ImGui::GetContentRegionAvail(); + + for (int i = 0; i < 6; i++) { + const char* label = m_mfd->GetButtonLabel(i); + if (label) { + ImGui::PushID(i); + ImGui::SetCursorPosY((i * sz.y - button_yoffset) / 6 + button_yoffset); + ImGui::Button(label, button_sz); + if (ImGui::IsItemHovered()) { + if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { + m_mfd->ProcessButton(i, PANEL_MOUSE_LBDOWN); + } + else if (ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { + m_mfd->ProcessButton(i, PANEL_MOUSE_LBUP); + } + } + ImGui::PopID(); + } } - int fh = BW/3; - if (fh != fnth) { - if (hBtnFnt) DeleteObject (hBtnFnt); - hBtnFnt = CreateFont (fnth = fh, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, - DEFAULT_PITCH|FF_DONTCARE, "Arial"); + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("ChildM", ImVec2(ImGui::GetContentRegionAvail().x - button_row_width, ImGui::GetContentRegionAvail().y - button_bottom_height), false, window_flags); + sz = ImGui::GetContentRegionAvail(); + + if (sz.x != m_oldSize.x || sz.y != m_oldSize.y) { + if (sz.x > 80 && sz.y > 80) { + MFDSPEC spec = { {0,0,(int)sz.x,(int)sz.y},6,6,button_yoffset,(int)(sz.y / 6.0) }; + m_mfd->Resize(spec); + m_oldSize = sz; + } + } + SURFHANDLE surf = m_mfd->GetDisplaySurface(); + if (surf) { + ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left + ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right + ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint + ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.0f); + ImTextureID txt = oapiGetImTextureID(surf); + ImGui::Image(txt, ImVec2(sz.x, sz.y), uv_min, uv_max, tint_col, border_col); + } + ImGui::EndChild(); + ImGui::SameLine(); + + ImGui::BeginChild("ChildR", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y - button_bottom_height), false, window_flags); + + for (int i = 6; i < 12; i++) { + const char* label = m_mfd->GetButtonLabel(i); + if (label) { + ImGui::PushID(i); + ImGui::SetCursorPosY(((i - 6) * sz.y - button_yoffset) / 6 + button_yoffset); + ImGui::Button(label, button_sz); + if (ImGui::IsItemHovered()) { + if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { + m_mfd->ProcessButton(i, PANEL_MOUSE_LBDOWN); + } + else if (ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { + m_mfd->ProcessButton(i, PANEL_MOUSE_LBUP); + } + } + ImGui::PopID(); + } } - r.right = ds + (r.left = (r.right-ds)/2); - r.bottom = ds + (r.top = gap); - SetWindowPos (hDsp, NULL, r.left, r.top, DW = (r.right-r.left), DH = (r.bottom-r.top), SWP_SHOWWINDOW); - - int x1 = r.left-BW-gap; - int x2 = r.right+gap; - int dy = (DH*2)/13, y0 = DH/7, y1 = r.top+y0-BH/2; - for (int i = 0; i < 6; i++) { - SetWindowPos (GetDlgItem (hDlg, IDC_BUTTON1+i), NULL, x1, y1+i*dy, BW, BH, SWP_SHOWWINDOW); - SetWindowPos (GetDlgItem (hDlg, IDC_BUTTON7+i), NULL, x2, y1+i*dy, BW, BH, SWP_SHOWWINDOW); + ImGui::EndChild(); + ImGui::BeginChild("ChildB", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y), false, window_flags); + + //sz = ImGui::GetContentRegionAvail(); + + //sz.x - button_sz.x * 4 + ImGui::SetCursorPosX(60); + + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.9, 0, 0, 1)); + if (ImGui::Button("PWR", button_sz)) { + m_mfd->ProcessButton(12, PANEL_MOUSE_LBDOWN); + + } + ImGui::PopStyleColor(); + ImGui::SameLine(); + if (ImGui::Button("SEL", button_sz)) { + m_mfd->ProcessButton(13, PANEL_MOUSE_LBDOWN); + } + ImGui::SameLine(); + if (ImGui::Button("MNU", button_sz)) { + m_mfd->ProcessButton(14, PANEL_MOUSE_LBDOWN); } - y1 = r.top+DH+gap; - SetWindowPos (GetDlgItem (hDlg, IDC_BUTTON_PWR), NULL, r.left + DW/2 - (BW*7)/4, y1, BW, BH, SWP_SHOWWINDOW); - SetWindowPos (GetDlgItem (hDlg, IDC_BUTTON_SEL), NULL, r.left + DW/2 - BW/2, y1, BW, BH, SWP_SHOWWINDOW); - SetWindowPos (GetDlgItem (hDlg, IDC_BUTTON_MNU), NULL, r.left + DW/2 + (BW*3)/4, y1, BW, BH, SWP_SHOWWINDOW); + ImGui::EndChild(); +} + - MFDSPEC spec = {{0,0,DW,DH},6,6,y0,dy}; - ExternMFD::Resize (spec); - InvalidateRect (hDlg, NULL, FALSE); +MFDWindow::MFDWindow(const MFDSPEC& spec) : ExternMFD(spec) +{ + fnth = 0; + vstick = false; + char cbuf[128]; + sprintf(cbuf, "ExtMFD%lld", (uint64_t)Id()); + m_window = std::make_unique(cbuf, this); + oapiOpenDialog(m_window.get()); } -void MFDWindow::RepaintDisplay (HWND hWnd) +MFDWindow::~MFDWindow() { - PAINTSTRUCT ps; - HDC hDCtgt = BeginPaint (hWnd, &ps); - SURFHANDLE surf = GetDisplaySurface(); - if (surf) { - HDC hDCsrc = oapiGetDC (surf); - BitBlt (hDCtgt, 0, 0, DW, DH, hDCsrc, 0, 0, SRCCOPY); - oapiReleaseDC (surf, hDCsrc); - } else { - SelectObject (hDCtgt, GetStockObject (BLACK_BRUSH)); - Rectangle (hDCtgt, 0, 0, DW, DH); - } - EndPaint (hWnd, &ps); + oapiCloseDialog(m_window.get()); } -void MFDWindow::RepaintButton (HWND hWnd) +void MFDWindow::SetVessel(OBJHANDLE hV) { - int id = GetWindowLongPtr (hWnd, GWLP_USERDATA); - PAINTSTRUCT ps; - HDC hDC = BeginPaint (hWnd, &ps); - SelectObject (hDC, GetStockObject (BLACK_PEN)); - Rectangle (hDC, 0, 0, BW, BH); - SetTextAlign (hDC, TA_CENTER); - const char *label; - if (id < 12) { - label = GetButtonLabel (id); - } else { - static const char *lbl[3] = {"PWR","SEL","MNU"}; - label = lbl[id-12]; - if (id == 12) SetTextColor (hDC, 0x0000FF); - } - if (label) { - SetBkMode (hDC, TRANSPARENT); - HFONT pFont = (HFONT)SelectObject (hDC, hBtnFnt); - TextOut (hDC, BW/2, (BH-fnth)/2, label, strlen(label)); - SelectObject (hDC, pFont); - } - EndPaint (hWnd, &ps); + ExternMFD::SetVessel(hV); } -void MFDWindow::ProcessButton (int bt, int event) +void MFDWindow::ProcessButton(int bt, int event) { switch (bt) { case 12: if (event == PANEL_MOUSE_LBDOWN) - SendKey (OAPI_KEY_ESCAPE); + SendKey(OAPI_KEY_ESCAPE); break; case 13: if (event == PANEL_MOUSE_LBDOWN) - SendKey (OAPI_KEY_F1); + SendKey(OAPI_KEY_F1); break; case 14: if (event == PANEL_MOUSE_LBDOWN) - SendKey (OAPI_KEY_GRAVE); + SendKey(OAPI_KEY_GRAVE); break; default: - ExternMFD::ProcessButton (bt, event); + ExternMFD::ProcessButton(bt, event); break; } } -void MFDWindow::clbkRefreshDisplay (SURFHANDLE) -{ - InvalidateRect (hDsp, NULL, FALSE); -} - -void MFDWindow::clbkRefreshButtons () -{ - for (int i = 0; i < 12; i++) - InvalidateRect (GetDlgItem (hDlg, IDC_BUTTON1+i), NULL, FALSE); -} - -void MFDWindow::clbkFocusChanged (OBJHANDLE hFocus) +void MFDWindow::clbkFocusChanged(OBJHANDLE hFocus) { if (!vstick) { - ExternMFD::clbkFocusChanged (hFocus); - //SetTitle (); + ExternMFD::clbkFocusChanged(hFocus); } } -void MFDWindow::StickToVessel (bool stick) +void MFDWindow::ToggleStickToVessel() { - vstick = stick; + vstick = !vstick; if (!vstick) { - SetVessel (oapiGetFocusObject()); - //SetTitle (); - } -} - -// ============================================================== -// Windows message handler for the dialog box - -INT_PTR CALLBACK DlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_INITDIALOG: - ((MFDWindow*)lParam)->Initialise (hDlg); - return TRUE; - case WM_SIZE: - ((MFDWindow*)oapiGetDialogContext(hDlg))->Resize (true); - return TRUE; - case WM_COMMAND: - switch (LOWORD (wParam)) { - case IDCANCEL: - oapiUnregisterExternMFD ((MFDWindow*)oapiGetDialogContext (hDlg)); - return TRUE; - case IDHELP: - ((MFDWindow*)oapiGetDialogContext(hDlg))->OpenModeHelp (); - return TRUE; - case IDSTICK: - ((MFDWindow*)oapiGetDialogContext(hDlg))->StickToVessel (HIWORD(wParam) != 0); - return TRUE; - } - break; + SetVessel(oapiGetFocusObject()); } - return oapiDefDialogProc (hDlg, uMsg, wParam, lParam); } - -LRESULT FAR PASCAL MFD_WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_PAINT: { - MFDWindow *mfdw = (MFDWindow*)oapiGetDialogContext (GetParent (hWnd)); - mfdw->RepaintDisplay (hWnd); - } return 0; - } - - return DefWindowProc (hWnd, uMsg, wParam, lParam); -} - -LRESULT FAR PASCAL MFD_BtnProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_PAINT: { - MFDWindow *mfdw = (MFDWindow*)oapiGetDialogContext (GetParent (hWnd)); - mfdw->RepaintButton (hWnd); - } return 0; - case WM_LBUTTONDOWN: { - MFDWindow *mfdw = (MFDWindow*)oapiGetDialogContext (GetParent (hWnd)); - mfdw->ProcessButton (GetWindowLongPtr (hWnd, GWLP_USERDATA), PANEL_MOUSE_LBDOWN); - SetCapture (hWnd); - } return 0; - case WM_LBUTTONUP: { - MFDWindow *mfdw = (MFDWindow*)oapiGetDialogContext (GetParent (hWnd)); - mfdw->ProcessButton (GetWindowLongPtr (hWnd, GWLP_USERDATA), PANEL_MOUSE_LBUP); - ReleaseCapture(); - } return 0; - } - - return DefWindowProc (hWnd, uMsg, wParam, lParam); -} \ No newline at end of file diff --git a/Src/Plugin/ExtMFD/MFDWindow.h b/Src/Plugin/ExtMFD/MFDWindow.h index 5b8048407..70b12bd0d 100644 --- a/Src/Plugin/ExtMFD/MFDWindow.h +++ b/Src/Plugin/ExtMFD/MFDWindow.h @@ -16,35 +16,23 @@ #ifndef __MFDWINDOW_H #define __MFDWINDOW_H -#define STRICT 1 -#include -#include "orbitersdk.h" +#include "GraphicsAPI.h" -class MFDWindow: public ExternMFD { +class MFDWindow : public ExternMFD { public: - MFDWindow (HINSTANCE _hInst, const MFDSPEC &spec); - ~MFDWindow (); - void Initialise (HWND _hDlg); - void SetVessel (OBJHANDLE hV); - void SetTitle (); - void Resize (bool fixaspect); - void RepaintDisplay (HWND hWnd); - void RepaintButton (HWND hWnd); - void ProcessButton (int bt, int event); - void StickToVessel (bool stick); - - void clbkRefreshDisplay (SURFHANDLE); - void clbkRefreshButtons (); - void clbkFocusChanged (OBJHANDLE hFocus); + MFDWindow(const MFDSPEC& spec); + virtual ~MFDWindow(); + void SetVessel(OBJHANDLE hV) override; + void ProcessButton(int bt, int event); + void ToggleStickToVessel(); + bool GetStickToVessel() { return vstick; } + void clbkFocusChanged(OBJHANDLE hFocus) override; private: - HINSTANCE hInst; // instance handle - HWND hDlg, hDsp; // dialog and MFD display handles - HFONT hBtnFnt; // button font int BW, BH; // button width and height - int gap; // geometry parameters int fnth; // button font height bool vstick; // stick to vessel + std::unique_ptr m_window; }; #endif // !__MFDWINDOW_H \ No newline at end of file diff --git a/Src/Plugin/ExtMFD/resource.h b/Src/Plugin/ExtMFD/resource.h deleted file mode 100644 index 12cced644..000000000 --- a/Src/Plugin/ExtMFD/resource.h +++ /dev/null @@ -1,39 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by ExtMFD.rc -// -#define IDD_MFD 101 -#define IDB_PIN 104 -#define IDSTICK 999 -#define IDC_WHOAMI 1000 -#define IDS_INFO 1000 -#define IDC_IAM 1001 -#define IDS_TYPE 1001 -#define IDC_REMEMBER 1002 -#define IDC_DISPLAY 1003 -#define IDC_BUTTON1 1004 -#define IDC_BUTTON2 1005 -#define IDC_BUTTON3 1006 -#define IDC_BUTTON4 1007 -#define IDC_BUTTON5 1008 -#define IDC_BUTTON6 1009 -#define IDC_BUTTON7 1010 -#define IDC_BUTTON8 1011 -#define IDC_BUTTON9 1012 -#define IDC_BUTTON10 1013 -#define IDC_BUTTON11 1014 -#define IDC_BUTTON12 1015 -#define IDC_BUTTON_PWR 1016 -#define IDC_BUTTON_SEL 1017 -#define IDC_BUTTON_MNU 1018 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 106 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1022 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif From 24dcef9ba08285c8eb41f18a5ba27ba6cf47a4a2 Mon Sep 17 00:00:00 2001 From: Gondos Date: Tue, 4 Feb 2025 23:25:22 +0100 Subject: [PATCH 26/51] [ImGui]Convert LuaConsole --- Extern/imgui/CMakeLists.txt | 2 +- Orbitersdk/include/imgui_extras.h | 9 + Src/Orbiter/DlgMgr.cpp | 18 +- Src/Orbiter/DlgMgr.h | 4 + Src/Orbiter/Orbiter.cpp | 30 +- Src/Plugin/LuaConsole/CMakeLists.txt | 4 +- Src/Plugin/LuaConsole/ConsoleCfg.cpp | 99 --- Src/Plugin/LuaConsole/ConsoleCfg.h | 36 - Src/Plugin/LuaConsole/ConsoleInterpreter.cpp | 4 +- Src/Plugin/LuaConsole/LuaConsole.cpp | 697 ++++++------------- Src/Plugin/LuaConsole/LuaConsole.h | 52 +- Src/Plugin/LuaConsole/LuaConsole.rc | 126 ---- Src/Plugin/LuaConsole/resource.h | 24 - 13 files changed, 262 insertions(+), 843 deletions(-) delete mode 100644 Src/Plugin/LuaConsole/ConsoleCfg.cpp delete mode 100644 Src/Plugin/LuaConsole/ConsoleCfg.h delete mode 100644 Src/Plugin/LuaConsole/LuaConsole.rc delete mode 100644 Src/Plugin/LuaConsole/resource.h diff --git a/Extern/imgui/CMakeLists.txt b/Extern/imgui/CMakeLists.txt index 27244b3c7..fbd0e3d7e 100644 --- a/Extern/imgui/CMakeLists.txt +++ b/Extern/imgui/CMakeLists.txt @@ -11,7 +11,7 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(imgui) -install(FILES ${imgui_SOURCE_DIR}/misc/fonts/Roboto-Medium.ttf fa-solid-900.ttf +install(FILES ${imgui_SOURCE_DIR}/misc/fonts/Roboto-Medium.ttf fa-solid-900.ttf ${imgui_SOURCE_DIR}/misc/fonts/Cousine-Regular.ttf DESTINATION ${ORBITER_INSTALL_ROOT_DIR} ) diff --git a/Orbitersdk/include/imgui_extras.h b/Orbitersdk/include/imgui_extras.h index 92034c4c8..73598b0a2 100644 --- a/Orbitersdk/include/imgui_extras.h +++ b/Orbitersdk/include/imgui_extras.h @@ -3,10 +3,19 @@ #include "imgui.h" // ImGui extras + +enum class ImGuiFont { + DEFAULT, + MONO +}; + + namespace ImGui { + OAPIFUNC bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format = "%.3f"); OAPIFUNC void HelpMarker(const char* desc, bool sameline = true); OAPIFUNC void BeginGroupPanel(const char* name, const ImVec2& size = ImVec2(-1.0f, -1.0f)); OAPIFUNC void EndGroupPanel(); OAPIFUNC bool MenuButton(const char *label, const char *tooltip = NULL); + OAPIFUNC void PushFont(ImGuiFont); }; diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index d22ace95f..fa93d0f93 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -11,6 +11,7 @@ #include "Orbiter.h" #include "Log.h" #include "imgui.h" +#include "imgui_extras.h" #include "imgui_impl_win32.h" #include "IconsFontAwesome6.h" #include @@ -542,8 +543,9 @@ void DialogManager::InitImGui() icons_config.FontDataOwnedByAtlas = false; const CFG_FONTPRM &prm = g_pOrbiter->Cfg()->CfgFontPrm; - io.Fonts->AddFontFromFileTTF(prm.ImGui_FontFile, prm.ImGui_FontSize, &config, ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + defaultFont = io.Fonts->AddFontFromFileTTF(prm.ImGui_FontFile, prm.ImGui_FontSize, &config, ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, &icons_config, icons_ranges); + monoFont = io.Fonts->AddFontFromFileTTF("Cousine-Regular.ttf", prm.ImGui_FontSize, &config, ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); io.Fonts->Build(); @@ -584,6 +586,15 @@ void DialogManager::ImGuiNewFrame() ImGui::EndFrame(); } +ImFont *DialogManager::GetFont(ImGuiFont f) +{ + switch(f) { + case ImGuiFont::MONO: return monoFont; + case ImGuiFont::DEFAULT: return defaultFont; + default: return defaultFont; + } +} + ImGuiDialog::~ImGuiDialog(){ // Make sure this dialog is no longer referenced in the DialogManager oapiCloseDialog(this); @@ -849,6 +860,11 @@ namespace ImGui { return ret; } + DLLEXPORT void PushFont(ImGuiFont f) + { + ImGui::PushFont(g_pOrbiter->DlgMgr()->GetFont(f)); + } + // From imgui_demo.cpp, with added sameline argument DLLEXPORT void HelpMarker(const char* desc, bool sameline) { diff --git a/Src/Orbiter/DlgMgr.h b/Src/Orbiter/DlgMgr.h index 790cd86fd..292cf6ad6 100644 --- a/Src/Orbiter/DlgMgr.h +++ b/Src/Orbiter/DlgMgr.h @@ -11,6 +11,7 @@ #include "Orbiter.h" #include #include "imgui.h" +#include "imgui_extras.h" class ImGuiDialog; class oapi::GraphicsClient; @@ -220,9 +221,12 @@ class DialogManager { } void ImGuiNewFrame(); + ImFont *GetFont(ImGuiFont f); private: void InitImGui(); void ShutdownImGui(); + ImFont *defaultFont; + ImFont *monoFont; }; INT_PTR OrbiterDefDialogProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 3ccb2bcfc..066b959a4 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -2060,11 +2060,14 @@ HRESULT Orbiter::UserInput () (g_select && g_select->IsActive())) skipkbd = true; if (didev = GetDInput()->GetKbdDevice()) { + ImGuiIO& io = ImGui::GetIO(); // keyboard input: immediate key interpretation hr = didev->GetDeviceState (sizeof(buffer), &buffer); if ((hr == DIERR_NOTACQUIRED || hr == DIERR_INPUTLOST) && SUCCEEDED (didev->Acquire())) hr = didev->GetDeviceState (sizeof(buffer), &buffer); - if (SUCCEEDED (hr)) + + // Direct input bypasses the proc loop so we skip it here + if (SUCCEEDED (hr) && !io.WantCaptureKeyboard) for (i = 0; i < 256; i++) simkstate[i] |= buffer[i]; bool consume = BroadcastImmediateKeyboardEvent (simkstate); @@ -2077,7 +2080,7 @@ HRESULT Orbiter::UserInput () hr = didev->GetDeviceData (sizeof(DIDEVICEOBJECTDATA), dod, &dwItems, 0); if ((hr == DIERR_NOTACQUIRED || hr == DIERR_INPUTLOST) && SUCCEEDED (didev->Acquire())) hr = didev->GetDeviceData (sizeof(DIDEVICEOBJECTDATA), dod, &dwItems, 0); - if (SUCCEEDED (hr)) { + if (SUCCEEDED (hr) && !io.WantCaptureKeyboard) { BroadcastBufferedKeyboardEvent (buffer, dod, dwItems); if (!skipkbd) { KbdInputBuffered_System (buffer, dod, dwItems); @@ -2564,7 +2567,7 @@ void Orbiter::BroadcastBufferedKeyboardEvent (char *kstate, DIDEVICEOBJECTDATA * LRESULT Orbiter::MsgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam)) - return true; + return 0; switch (uMsg) { @@ -2610,18 +2613,19 @@ LRESULT Orbiter::MsgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; //return 0; } break; case WM_MOUSEMOVE: { - if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureMouse) { - return 0; - } + if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureMouse) { + return 0; + } - int x = LOWORD(lParam); - int y = HIWORD(lParam); - MouseEvent(uMsg, wParam, x, y); - if (!bKeepFocus && pConfig->CfgUIPrm.MouseFocusMode != 0 && GetFocus() != hWnd) { - if (GetWindowThreadProcessId(hWnd, NULL) == GetWindowThreadProcessId(GetFocus(), NULL)) - SetFocus(hWnd); + int x = LOWORD(lParam); + int y = HIWORD(lParam); + MouseEvent(uMsg, wParam, x, y); + if (!bKeepFocus && pConfig->CfgUIPrm.MouseFocusMode != 0 && GetFocus() != hWnd) { + if (GetWindowThreadProcessId(hWnd, NULL) == GetWindowThreadProcessId(GetFocus(), NULL)) + SetFocus(hWnd); + } } - }return 0; + return 0; #ifdef UNDEF // These messages could be intercepted to suspend the simulation diff --git a/Src/Plugin/LuaConsole/CMakeLists.txt b/Src/Plugin/LuaConsole/CMakeLists.txt index fb9bcffa6..ff39c4ed5 100644 --- a/Src/Plugin/LuaConsole/CMakeLists.txt +++ b/Src/Plugin/LuaConsole/CMakeLists.txt @@ -3,14 +3,11 @@ add_library(LuaConsole SHARED LuaConsole.cpp - LuaConsole.rc ConsoleInterpreter.cpp - ConsoleCfg.cpp ) target_include_directories(LuaConsole PUBLIC ${ORBITER_SOURCE_SDK_INCLUDE_DIR} - PUBLIC ${MODULE_COMMON_DIR} PUBLIC ${ORBITER_SOURCE_ROOT_DIR}/Src/Module/LuaScript/LuaInterpreter ) @@ -19,6 +16,7 @@ target_link_libraries(LuaConsole ${ORBITER_SDK_LIB} lua::lib ${LUAINTERPRETER_LIB} + imgui ) add_dependencies(LuaConsole diff --git a/Src/Plugin/LuaConsole/ConsoleCfg.cpp b/Src/Plugin/LuaConsole/ConsoleCfg.cpp deleted file mode 100644 index 69dc72122..000000000 --- a/Src/Plugin/LuaConsole/ConsoleCfg.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) Martin Schweiger -// Licensed under the MIT License - -#include "ConsoleCfg.h" -#include "resource.h" - -ConsoleConfig *ConsoleConfig::cc = 0; -const char *ConsoleConfig::cfgfile = "Modules\\Console.cfg"; - -ConsoleConfig::ConsoleConfig (HINSTANCE hDLL): LaunchpadItem () -{ - hModule = hDLL; - SetDefault (); - ReadConfig (); -} - -char *ConsoleConfig::Name () -{ - return (char*)"Console Configuration"; -} - -char *ConsoleConfig::Description () -{ - return (char*)"Customize the appearance and behaviour of the inline Lua Console.\r\n\r\nThe console allows to run scripts during a simulation session."; - bool clbkOpen (HWND hLaunchpad); -} - -bool ConsoleConfig::clbkOpen (HWND hLaunchpad) -{ - cc = this; // keep a global pointer to be used by the message handlers (ugly) - return OpenDialog (hModule, hLaunchpad, IDD_CONFIG, DlgProc); -} - -int ConsoleConfig::clbkWriteConfig () -{ - FILEHANDLE hFile = oapiOpenFile (cfgfile, FILE_OUT, CONFIG); - if (!hFile) return 1; - oapiWriteItem_int (hFile, (char*)"FSIZE", fontsize); - oapiCloseFile (hFile, FILE_OUT); - return 0; -} - -void ConsoleConfig::InitDialog (HWND hDlg) -{ - char cbuf[256]; - sprintf (cbuf, "%d", fontsize); - SetWindowText (GetDlgItem (hDlg, IDC_FONTSIZE), cbuf); -} - -void ConsoleConfig::CloseDialog (HWND hDlg) -{ - EndDialog (hDlg, 0); -} - -void ConsoleConfig::SetDefault () -{ - fontsize = 14; -} - -bool ConsoleConfig::ReadConfig () -{ - int d; - FILEHANDLE hFile = oapiOpenFile (cfgfile, FILE_IN, CONFIG); - if (!hFile) { - MessageBeep (-1); - return false; - } - if (oapiReadItem_int (hFile, (char*)"FSIZE", d)) fontsize = (DWORD)d; - oapiCloseFile (hFile, FILE_IN); - return true; -} - -void ConsoleConfig::Apply (HWND hDlg) -{ - char cbuf[256]; - DWORD d; - GetWindowText (GetDlgItem (hDlg, IDC_FONTSIZE), cbuf, 256); - if (sscanf (cbuf, "%d", &d) == 1) fontsize = d; -} - -INT_PTR CALLBACK ConsoleConfig::DlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_INITDIALOG: - cc->InitDialog (hDlg); - break; - case WM_COMMAND: - switch (LOWORD (wParam)) { - case IDOK: - cc->Apply (hDlg); - // fall through - case IDCANCEL: - cc->CloseDialog (hDlg); - return 0; - } - break; - } - return 0; -} diff --git a/Src/Plugin/LuaConsole/ConsoleCfg.h b/Src/Plugin/LuaConsole/ConsoleCfg.h deleted file mode 100644 index 88ef94b1c..000000000 --- a/Src/Plugin/LuaConsole/ConsoleCfg.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Martin Schweiger -// Licensed under the MIT License - -#ifndef __CONSOLECFG_H -#define __CONSOLECFG_H - -//#include "Orbitersdk.h" -#include "LuaConsole.h" - -class ConsoleConfig: public LaunchpadItem { - friend class LuaConsole; - -public: - ConsoleConfig (HINSTANCE hDLL); - char *Name (); - char *Description (); - bool clbkOpen (HWND hLaunchpad); - int clbkWriteConfig (); - void InitDialog (HWND hDlg); - void CloseDialog (HWND hDlg); - void SetDefault(); - bool ReadConfig (); - void Apply (HWND hDlg); - -protected: - DWORD fontsize; - -private: - static INT_PTR CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM); - - static ConsoleConfig *cc; - static const char *cfgfile; - HINSTANCE hModule; -}; - -#endif // !__CONSOLECFG_H diff --git a/Src/Plugin/LuaConsole/ConsoleInterpreter.cpp b/Src/Plugin/LuaConsole/ConsoleInterpreter.cpp index e3d8da97b..76a7b4f21 100644 --- a/Src/Plugin/LuaConsole/ConsoleInterpreter.cpp +++ b/Src/Plugin/LuaConsole/ConsoleInterpreter.cpp @@ -41,11 +41,11 @@ void ConsoleInterpreter::term_strout (const char *str, bool iserr) strcpy (cbuf, str); char *s = strtok (cbuf, "\n"); while (s) { - console->AddLine (s, iserr ? 2:1); + console->AddLine (s, iserr ? LineType::LUA_OUT_ERROR:LineType::LUA_OUT); s = strtok (NULL, "\n"); } delete []cbuf; - } else console->AddLine (str, iserr ? 2:1); + } else console->AddLine (str, iserr ? LineType::LUA_OUT_ERROR:LineType::LUA_OUT); } void ConsoleInterpreter::term_clear() { diff --git a/Src/Plugin/LuaConsole/LuaConsole.cpp b/Src/Plugin/LuaConsole/LuaConsole.cpp index 7807aa6ed..b765567d4 100644 --- a/Src/Plugin/LuaConsole/LuaConsole.cpp +++ b/Src/Plugin/LuaConsole/LuaConsole.cpp @@ -4,71 +4,215 @@ #define ORBITER_MODULE #include "Orbitersdk.h" #include "LuaConsole.h" -#include "ConsoleCfg.h" -#include "resource.h" +#include +#include +#include "imgui.h" +#include "imgui_extras.h" +#include "IconsFontAwesome6.h" +#include #include -#include using std::min; using std::max; using namespace oapi; + +// ============================================================== +class LuaConsoleDlg: public ImGuiDialog { + const size_t MAX_HISTORY = 100; + const size_t MAX_LINES = 10000; + + + struct LineData { + std::string text; + LineType type; + LineData(std::string &&s, LineType t):text(s), type(t) {} + }; + std::deque lines; + std::deque history; + int idx_history; + char cmd[4096]; + ImGuiInputTextFlags flags; + char *cConsoleCmd; +public: + LuaConsoleDlg(char *cmdbuf):ImGuiDialog("Lua Terminal"){ + cConsoleCmd = cmdbuf; + cmd[0] = '\0'; + flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CtrlEnterForNewLine; + idx_history = -1; + } + + + void AddLine(const char *str, LineType type = LineType::LUA_OUT) { + std::stringstream ss(str); + std::string line; + + if(str[0]=='\0') + lines.emplace_back("", type); + else while(std::getline(ss,line)) { + lines.emplace_back(std::move(line), type); + } + + while(lines.size() > MAX_LINES) { + lines.pop_front(); + } + } + + void ExecuteCommandBuffer() { + history.push_back(cmd); + AddLine(cmd, LineType::LUA_IN); + strcpy(cConsoleCmd, cmd); + cmd[0] = '\0'; + + if(history.size() > MAX_HISTORY) { + history.pop_front(); + } + + idx_history = history.size() - 1; + } + + void HistoryClear() { + history.clear(); + idx_history = 0; + } + + void HistoryPrev() { + if(history.size() == 0) return; + if(idx_history >= 0) { + strncpy(cmd, history[idx_history].c_str(), sizeof(cmd)); + idx_history--; + if(idx_history < 0) idx_history = 0; + } + } + + void HistoryNext() { + if(history.size() == 0) return; + if(idx_history < history.size()) { + strncpy(cmd, history[idx_history].c_str(), sizeof(cmd)); + idx_history++; + if(idx_history >= history.size()) idx_history = history.size() - 1; + } + } + void Clear() { + lines.clear(); + } + void Display() { + ImGui::SetNextWindowSize(ImVec2(800,600)); + bool visible = ImGui::Begin("Lua Console", &active); + if(ImGui::MenuButton(ICON_FA_TRASH, "Clear console")) { + lines.clear(); + } + if(visible) { + OnDraw(); + } + ImGui::End(); + if (!active) OnClose(); + } + + void DrawConsole() { + ImGui::SetNextWindowSize(ImVec2(0,440)); + ImGui::BeginChild("##LuaConsole", ImVec2(0.0f, 0.0f), ImGuiChildFlags_ResizeY, ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_AlwaysVerticalScrollbar); + ImGui::PushFont(ImGuiFont::MONO); + ImGuiListClipper clipper; + clipper.Begin(lines.size()); + while (clipper.Step()) { + for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++) { + LineType type = lines[line_no].type; + + switch(type) { + case LineType::LUA_IN: + ImGui::Text("%%%s", lines[line_no].text.c_str()); + break; + case LineType::LUA_OUT: + ImGui::TextColored(ImVec4(0,1,0,1), " %s", lines[line_no].text.c_str()); + break; + case LineType::LUA_OUT_ERROR: + ImGui::TextColored(ImVec4(1,0,0,1), " %s", lines[line_no].text.c_str()); + break; + } + } + } + ImGui::PopFont(); + if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) + ImGui::SetScrollHereY(1.0f); + ImGui::EndChild(); + } + + void DrawInput() { + ImGui::BeginChild("##LuaInput"); + ImGui::PushFont(ImGuiFont::MONO); + if(ImGui::InputTextMultiline("##LuaPrompt", cmd, sizeof(cmd), ImVec2(0,0), flags)) { + ImGui::SetKeyboardFocusHere(-1); + ExecuteCommandBuffer(); + } + ImGui::PopFont(); + + ImGui::SetItemDefaultFocus(); // This does not seem to work... + + ImGui::SameLine(); + ImGui::BeginChild("##LuaTermCommands"); + if(ImGui::Button(ICON_FA_PLAY)) { + ExecuteCommandBuffer(); + } + ImGui::SetItemTooltip("Execute the command buffer"); + ImGui::SameLine(); + ImGui::CheckboxFlags("Single line", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine); + + ImGui::SetItemTooltip("When checked, the command buffer is sent when pressing Enter\n" + "Otherwise, you can enter multiple lines at once and execute\n" + "them with Ctrl-Enter or the " ICON_FA_PLAY " button"); + + ImGui::BeginGroupPanel("History", ImVec2(0,0)); + if(ImGui::Button(ICON_FA_ARROW_UP)) { + HistoryPrev(); + } + ImGui::SetItemTooltip("Previous command"); + + ImGui::SameLine(); + if(ImGui::Button(ICON_FA_ARROW_DOWN)) { + HistoryNext(); + } + ImGui::SetItemTooltip("Next command"); + + ImGui::SameLine(); + if(ImGui::Button(ICON_FA_TRASH)) { + HistoryClear(); + } + ImGui::SetItemTooltip("Clear history"); + ImGui::EndGroupPanel(); + + ImGui::EndChild(); + + ImGui::EndChild(); + } + + void OnDraw() { + DrawConsole(); + DrawInput(); + } +}; + // ============================================================== // Global parameters LuaConsole *g_Module = NULL; ConsoleConfig *g_Config = NULL; -char cConsoleCmd[1024] = "\0"; - // ============================================================== // class LuaConsole LuaConsole::LuaConsole (HINSTANCE hDLL): Module (hDLL) { - hWnd = NULL; hThread = NULL; interp = NULL; - bRefresh = false; - fW = 0; - - SetParams (); // may not be necessary here + cConsoleCmd[0]=0; // Register a custom command for opening the console window dwCmd = oapiRegisterCustomCmd ((char*)"Lua console window", (char*)"Open a Lua script interpreter window.", OpenDlgClbk, this); - // terminal history buffer - for (DWORD i = 0; i < NLINE; i++) { - line[i].buf = NULL; - line[i].mode = 0; - } - line0 = 0; - hline = 0; - nline = 0; - tline = 0; - topline = 0; - - // input buffer - inp = new char[1024]; - memset (inp, 0, 1024); - caret = 0; - ninp = 0; - - // Register a window class for the terminal display - WNDCLASS wc; - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = TermProcHook; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hDLL; - wc.hIcon = NULL; - wc.hCursor = LoadCursor (NULL, IDC_IBEAM); - wc.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = "ConsoleDsp"; - RegisterClass (&wc); + hDlg = new LuaConsoleDlg(cConsoleCmd); } // ============================================================== @@ -78,32 +222,14 @@ LuaConsole::~LuaConsole () // Unregister the custom function in Orbiter oapiUnregisterCustomCmd (dwCmd); - // Unregister the terminal window class - UnregisterClass ("ConsoleDsp", hModule); - - // Delete terminal buffer - for (DWORD i = 0; i < NLINE; i++) - if (line[i].buf) delete []line[i].buf; - // Delete input buffer - delete []inp; + delete hDlg; } // ============================================================== void LuaConsole::clbkSimulationStart (RenderMode mode) { - // Read configuration parameters, if available - SetParams (); - - // GDI resources - hFont = CreateFont (-(int)fH, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, 3, 2, 1, 49, "Courier New"); - - // make user-selectable - col[0] = 0x000000; - col[1] = 0x008000; - col[2] = 0x0000FF; - AddLine ("==== Orbiter Terminal (" LUA_RELEASE ") ===="); AddLine ("Type 'help()' for help."); AddLine (""); @@ -129,9 +255,6 @@ void LuaConsole::clbkSimulationEnd () delete interp; interp = NULL; } - - // Free GDI resources - DeleteObject (hFont); } // ============================================================== @@ -144,11 +267,6 @@ void LuaConsole::clbkPreStep (double simt, double simdt, double mjd) // At this point the interpreter is performing one cycle interp->WaitExec(); // orbiter waits to get back control } - if (bRefresh) { - UpdateScrollbar(); - RefreshTerminal(); - bRefresh = false; - } interp->PostStep (simt, simdt, mjd); } } @@ -157,22 +275,13 @@ void LuaConsole::clbkPreStep (double simt, double simdt, double mjd) HWND LuaConsole::Open () { - // open the terminal dialog - if (oapiFindDialog (hModule, IDD_CONSOLE)) return NULL; // console open already - hWnd = oapiOpenDialogEx (hModule, IDD_CONSOLE, DlgProc, 0, this); - hTerm = GetDlgItem (hWnd, IDC_TERM); - - // get some text parameters - SetFontGeometry (hTerm); - - // get geometry information - SetTermGeometry (hTerm); + oapiOpenDialog(hDlg); // create the interpreter and execution thread if (!interp) interp = CreateInterpreter (); - return hWnd; + return NULL; } // ============================================================== @@ -183,426 +292,25 @@ void LuaConsole::Close () // console window. Any active tasks (e.g. autopilots will continue // running in the background. - oapiCloseDialog (hWnd); - hWnd = NULL; - hTerm = NULL; - tline = 0; -} - -// ============================================================== - -bool LuaConsole::SetParams () -{ - // Set defaults in case they are not defined in the file - fH = 14; // font size - - if (!g_Config) return false; - fH = g_Config->fontsize; - return true; -} - -// ============================================================== - -void LuaConsole::SetFontSize (DWORD size) -{ - if (size == fH) return; // nothing to do - fH = size; - if (hFont) DeleteObject (hFont); - hFont = CreateFont (-(int)fH, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, 3, 2, 1, 49, "Courier New"); - - // get some text parameters - SetFontGeometry (hTerm); -} - -// ============================================================== - -void LuaConsole::Resize (DWORD w, DWORD h) -{ - if (hTerm) { - SetWindowPos (hTerm, hWnd, - 0, 0, w, h, - SWP_NOZORDER); - } - SetTermGeometry (hTerm); - - // adjust scrollbar - UpdateScrollbar(); -} - -// ============================================================== - -void LuaConsole::SetFontGeometry (HWND hTerm) -{ - HDC hDC = GetDC (hTerm); - HFONT pFont = (HFONT)SelectObject (hDC, hFont); - if (!fW) { - TEXTMETRIC tm; - GetTextMetrics (hDC, &tm); - fW = tm.tmAveCharWidth; - } - SelectObject (hDC, pFont); - ReleaseDC (hTerm, hDC); -} - -// ============================================================== - -void LuaConsole::SetTermGeometry (HWND hTerm) -{ - RECT rc; - GetClientRect (hTerm, &rc); - int w = rc.right, h = rc.bottom; - tline = h/fH; // terminal lines -} - -// ============================================================== - -void LuaConsole::RefreshTerminal () -{ - if (hTerm) { - InvalidateRect (hTerm, NULL, TRUE); - UpdateWindow (hTerm); - PaintTerminal (); - } -} - -// ============================================================== - -void LuaConsole::PaintTerminal () -{ - if (!tline) return; - - bool bPrompt = !interp->IsBusy(); - DWORD i, idx, x0, x, y; - DWORD nnline = nline; - if (bPrompt) nnline++; - HFONT pFont; - HDC hDC = GetDC (hTerm); - SelectObject (hDC, GetStockObject (NULL_BRUSH)); - SelectObject (hDC, GetStockObject (BLACK_PEN)); - pFont = (HFONT)SelectObject (hDC, hFont); - SetTextColor (hDC, col[0]); - int pmode = 0; - SetBkMode (hDC, TRANSPARENT); - x0 = x = 2; y = 1; - int dtop = (topline-line0+NLINE)%NLINE; - DWORD ndisp = min (nline-dtop,tline-1); - for (i = 0; i < ndisp; i++) { - idx = (topline+i)%NLINE; - if (!i || line[idx].mode != pmode) { - pmode = line[idx].mode; - SetTextColor (hDC, col[pmode]); - x = (!pmode ? x0+fW : x0); - } - if (!pmode) TextOut (hDC, x0, y, "%", 1); - TextOut (hDC, x, y, line[idx].buf, strlen(line[idx].buf)); - y += fH; - } - if (bPrompt && nline-dtop >= 0 && nline-dtop < tline) { - x = x0+fW; - if (pmode) SetTextColor (hDC, col[0]); - TextOut (hDC, x0, y, "%", 1); - if (inp[0]) - TextOut (hDC, x, y, inp, ninp); - // draw caret - MoveToEx (hDC, x+fW*caret, y, NULL); - LineTo (hDC, x+fW*caret, y+fH); - } - - SelectObject (hDC, pFont); - ReleaseDC (hTerm, hDC); -} - -// ============================================================== - -void LuaConsole::Clear () -{ - // Clean terminal history buffer, keeping only *unique* *inputs* - std::set s; - for (int i = 0, j = 0; i < nline/*NLINE*/; ++i) - { - if (!line[i].mode && // mode == input ...AND... - line[i].buf && *line[i].buf && // buffer neither NULL nor empty ...AND... - s.insert(line[i].buf).second ) // unique - { // => keep! - if (i != j) // move? - { - line[j] = line[i]; - line[i].buf = NULL; - } - ++j; - } - else // remove! - { - delete[] line[i].buf; - line[i].buf = NULL; - line[i].mode = 0; - } - } - - // Set parameter for a 'clean' terminal - line0 = 0; // buffer index of first line - - nline = // number of lines in input buffer - topline = // topmost displayed line - hline = s.size(); // current history scan line - - PaintTerminal(); -} - -// ============================================================== - -void LuaConsole::AddLine (const char *str, int mode) -{ - int idx = (line0+nline)%NLINE; - LineSpec *ln = line + idx; - if (ln->buf) delete []ln->buf; - int ncol = strlen(str); - ln->mode = mode; - ln->buf = new char[ncol+1]; - strcpy (ln->buf, str); - int dtop = (topline-line0+NLINE)%NLINE; - int ddsp = nline-dtop; - bool vis = (ddsp >= 0 && ddsp < tline); - if (nline == NLINE) line0 = (line0+1)%NLINE; - else nline++; - if (!mode || vis) AutoScroll(); - bRefresh = true; -} - -// ============================================================== - -void LuaConsole::AutoScroll () -{ - if (!tline) return; - int dtop = (topline-line0+NLINE)%NLINE; - if (nline < dtop) { - ScrollTo ((line0+dtop)%NLINE); - } else if (nline-dtop >= tline) { - ScrollTo ((line0+nline-tline+1)%NLINE); - } -} - -// ============================================================== - -void LuaConsole::ScrollTo (int pos) -{ - pos = max (0, min (nline-1, pos)); - pos = (pos+line0)%NLINE; - if (pos != topline) { - topline = pos; - bRefresh = true; - } -} - -// ============================================================== - -void LuaConsole::ScrollBy (int dpos) -{ - int dtop = (topline-line0+NLINE)%NLINE; - int pos = dtop+dpos; - ScrollTo (pos); -} - -// ============================================================== - -void LuaConsole::UpdateScrollbar () -{ - if (!tline) return; - static SCROLLINFO si = { - sizeof(SCROLLINFO), - SIF_POS | SIF_RANGE, - 0, 0, 0, 0, 0 - }; - si.nMax = max (0, nline-1); - si.nPos = (topline-line0+NLINE)%NLINE; - SetScrollInfo (hTerm, SB_VERT, &si, TRUE); -} - -// ============================================================== - -void LuaConsole::InputLine (const char *str) -{ - AddLine (str, 0); - hline = nline; - strcpy (cConsoleCmd, str); -} - -// ============================================================== - -bool LuaConsole::ScanHistory (int step) -{ - DWORD ln = nline, phline = hline; - bool found = false; - if (step < 0) { // step back - if (!hline) return false; - for (--hline; hline != (DWORD)-1; hline--) { - ln = (line0+hline)%NLINE; - if (!line[ln].mode && line[ln].buf) { found = true; break; } - } - } else { // step forward - if (hline == nline) return false; - for (++hline; hline != nline; hline++) { - ln = (line0+hline)%NLINE; - if (!line[ln].mode && line[ln].buf) { found = true; break; } - } - } - if (found) { - if (ln == nline) { - inp[0] = '\0'; - ninp = caret = 0; - } else { - strncpy (inp, line[ln].buf, 1024); - ninp = caret = min (strlen (line[ln].buf), (size_t)1024); - } - } else if (step > 0) { - inp[0] = '\0'; - ninp = caret = 0; - } else { - hline = phline; - return false; - } - - bRefresh = true; - return true; + oapiCloseDialog (hDlg); } -// ============================================================== - -LRESULT WINAPI LuaConsole::TermProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +void LuaConsole::OpenDlgClbk (void *context) { - switch (uMsg) { - case WM_CHAR: - switch (wParam) { - case 8: // Backspace - if (caret) { - for (int i = caret; i < ninp; i++) - inp[i-1] = inp[i]; - caret--; ninp--; - } else return 0; - break; - case 13: // Enter - inp[ninp] = '\0'; - InputLine (inp); - inp[0] = '\0'; - caret = ninp = 0; - return 0; - default: - if (isprint (wParam)) { - for (int i = ninp; i > caret; i--) - inp[i] = inp[i-1]; - inp[caret++] = (char)wParam; - ninp++; - //} else { // debugging only - // sprintf (oapiDebugString(), "c=%c, id=%d", wParam, wParam); - } - break; - } - AutoScroll(); - RefreshTerminal(); - return 0; - case WM_KEYDOWN: - switch (wParam) { - case 37: // left arrow - if (caret) caret--; - else return 0; - break; - case 39: // right arrow - if (caret < ninp) caret++; - else return 0; - break; - case 38: // up arrow (command history) - if (!ScanHistory(-1)) return 0; - break; - case 40: // down arrow (command history) - if (!ScanHistory(1)) return 0; - break; - case 46: // Del - if (ninp > caret) { - ninp--; - for (int i = caret; i < ninp; ++i) - inp[i] = inp[i + 1]; - } else return 0; - break; - case 35: // End - caret = ninp; - break; - case 36: // Pos1 - caret = 0; - break; - //default: // debugging only - // sprintf (oapiDebugString(), "virt=%d", wParam); - // return 0; - } - AutoScroll(); - RefreshTerminal(); - return 0; - case WM_VSCROLL: - switch (LOWORD(wParam)) { - case SB_THUMBPOSITION: - case SB_THUMBTRACK: - ScrollTo (HIWORD(wParam)); - break; - case SB_LINEDOWN: - ScrollBy (1); - break; - case SB_LINEUP: - ScrollBy (-1); - break; - case SB_PAGEDOWN: - ScrollBy (10); - break; - case SB_PAGEUP: - ScrollBy (-10); - break; - } - return 0; - } - return DefWindowProc (hWnd, uMsg, wParam, lParam); -} - -// ============================================================== + LuaConsole *pConsole = (LuaConsole*)context; + pConsole->Open(); -LRESULT WINAPI LuaConsole::TermProcHook (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - LuaConsole *pConsole = (LuaConsole*)GetWindowLongPtr (hWnd, GWLP_USERDATA); - return pConsole->TermProc (hWnd, uMsg, wParam, lParam); +// static LuaConsoleDlg *dlg = new LuaConsoleDlg(); +// oapiOpenDialog(dlg); } -// ============================================================== - -INT_PTR CALLBACK LuaConsole::DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +void LuaConsole::AddLine(const char *str, LineType type) { - LuaConsole *pConsole = (LuaConsole*)oapiGetDialogContext (hWnd); - - switch (uMsg) { - case WM_INITDIALOG: - SetFocus (GetDlgItem (hWnd, IDC_TERM)); - pConsole = (LuaConsole*)lParam; - SetWindowLongPtr (GetDlgItem (hWnd, IDC_TERM), GWLP_USERDATA, (LONG_PTR)pConsole); - return FALSE; - case WM_COMMAND: - switch (LOWORD (wParam)) { - case IDCANCEL: - pConsole->Close(); - return TRUE; - } - break; - case WM_PAINT: - pConsole->RefreshTerminal(); - break; - case WM_SIZE: - pConsole->Resize (LOWORD(lParam), HIWORD(lParam)); - return 0; - } - return oapiDefDialogProc (hWnd, uMsg, wParam, lParam); + hDlg->AddLine(str, type); } - -// ============================================================== - -void LuaConsole::OpenDlgClbk (void *context) +void LuaConsole::Clear() { - LuaConsole *pConsole = (LuaConsole*)context; - pConsole->Open(); + hDlg->Clear(); } // ============================================================== @@ -610,10 +318,6 @@ void LuaConsole::OpenDlgClbk (void *context) DLLCLBK void InitModule (HINSTANCE hDLL) { - // Create the configurator - g_Config = new ConsoleConfig (hDLL); - oapiRegisterLaunchpadItem (g_Config, NULL); - // Create the console instance g_Module = new LuaConsole (hDLL); oapiRegisterModule (g_Module); @@ -621,8 +325,6 @@ DLLCLBK void InitModule (HINSTANCE hDLL) DLLCLBK void ExitModule (HINSTANCE hDLL) { - // Delete the configurator - oapiUnregisterLaunchpadItem (g_Config); delete g_Config; } @@ -648,10 +350,9 @@ unsigned int WINAPI LuaConsole::InterpreterThreadProc (LPVOID context) for (;;) { interp->WaitExec(); // wait for execution permission if (console->termInterp) break; // close thread requested - res = interp->RunChunk (cConsoleCmd, strlen (cConsoleCmd)); // run command from buffer + res = interp->RunChunk (console->cConsoleCmd, strlen (console->cConsoleCmd)); // run command from buffer if (interp->Status() == 1) break; // close thread requested - cConsoleCmd[0] = '\0'; // free buffer - console->bRefresh = (res != -1); // signal terminal refresh + console->cConsoleCmd[0] = '\0'; // free buffer interp->EndExec(); // return control } interp->EndExec(); // release mutex (is this necessary?) diff --git a/Src/Plugin/LuaConsole/LuaConsole.h b/Src/Plugin/LuaConsole/LuaConsole.h index ff30028f8..047d51b15 100644 --- a/Src/Plugin/LuaConsole/LuaConsole.h +++ b/Src/Plugin/LuaConsole/LuaConsole.h @@ -7,13 +7,20 @@ #include "OrbiterAPI.h" #include "ModuleAPI.h" #include "ConsoleInterpreter.h" +#include #define NLINE 100 // number of buffered lines +class LuaConsoleDlg; +enum class LineType { + LUA_IN, + LUA_OUT, + LUA_OUT_ERROR, +}; + class LuaConsole: public oapi::Module { friend class ConsoleInterpreter; friend class ConsoleConfig; - public: LuaConsole (HINSTANCE hDLL); ~LuaConsole (); @@ -24,56 +31,21 @@ class LuaConsole: public oapi::Module { HWND Open (); void Close (); - void SetFontSize (DWORD size); - void Resize (DWORD w, DWORD h); - void RefreshTerminal (); - void PaintTerminal (); -protected: - bool SetParams (); - void SetTermGeometry (HWND hTerm); - void SetFontGeometry (HWND hTerm); - void AutoScroll (); - void ScrollTo (int pos); - void ScrollBy (int dpos); - void UpdateScrollbar (); - LRESULT WINAPI TermProc (HWND, UINT, WPARAM, LPARAM); + void AddLine(const char *str, LineType type = LineType::LUA_OUT); + void Clear(); private: - static INT_PTR CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM); - static LRESULT WINAPI TermProcHook (HWND, UINT, WPARAM, LPARAM); static unsigned int WINAPI InterpreterThreadProc (LPVOID context); static void OpenDlgClbk (void *context); // called when user requests console window Interpreter *CreateInterpreter (); - void AddLine (const char *str, int mode=1); // add line to buffer - void Clear (); - void InputLine (const char *str); // user input - bool ScanHistory (int step); // recall previous command to input buffer HANDLE hThread; // interpreter thread handle bool termInterp; Interpreter *interp; // interpreter instance - HWND hWnd; // console window handle - HWND hTerm; // terminal text sub-window - HFONT hFont; // font resource - DWORD fW, fH; // font width, height DWORD dwCmd; // custom command id - - struct LineSpec { // terminal history buffer - char *buf; - int mode; // 0=input, 1=output, 2=error output - //bool isInp; - } line[NLINE]; - char *inp; // input buffer - int line0; // buffer index of first line - int hline; // current history scan line - int nline; // number of lines in input buffer - int ninp; // number of characters in input buffer - int tline; // number of lines visible in terminal window - int topline; // topmost displayed line - int caret; // caret position in input buffer - bool bRefresh; // display refresh flag - COLORREF col[3]; // colour for input/output/error text + LuaConsoleDlg *hDlg; + char cConsoleCmd[4096]; }; #endif // !__LUA_CONSOLE_H \ No newline at end of file diff --git a/Src/Plugin/LuaConsole/LuaConsole.rc b/Src/Plugin/LuaConsole/LuaConsole.rc deleted file mode 100644 index a59760c97..000000000 --- a/Src/Plugin/LuaConsole/LuaConsole.rc +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) Martin Schweiger -// Licensed under the MIT License - -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.K.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_CONSOLE DIALOGEX 0, 0, 334, 217 -STYLE DS_SETFONT | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_TOOLWINDOW -CAPTION "Orbiter Console" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - CONTROL "",IDC_TERM,"ConsoleDsp",WS_VSCROLL | WS_TABSTOP,0,0,333,217 -END - -IDD_CONFIG DIALOGEX 0, 0, 148, 66 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_TOOLWINDOW -CAPTION "Console Configuration" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,38,45,50,14 - PUSHBUTTON "Cancel",IDCANCEL,91,45,50,14 - LTEXT "Size:",IDC_STATIC,18,20,16,8 - EDITTEXT IDC_FONTSIZE,41,19,40,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_ARROWKEYS,82,19,11,14 - GROUPBOX "Font",IDC_STATIC,7,7,134,34 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_CONFIG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 141 - TOPMARGIN, 7 - BOTTOMMARGIN, 59 - END -END -#endif // APSTUDIO_INVOKED - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_INFO "LUA CONSOLE:\r\n\r\nProvides a console window for entering Lua commands or running scripts. The Lua script interface can be used for a variety of tasks, such as querying and setting spacecraft parameters.\r\n\r\nThe console window can be opened by selecting the ""Lua console window"" entry in the Custom Functions dialog (Ctrl-F4)." - IDS_TYPE "Script tools and drivers" -END - -#endif // English (U.K.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Src/Plugin/LuaConsole/resource.h b/Src/Plugin/LuaConsole/resource.h deleted file mode 100644 index 4537d0d60..000000000 --- a/Src/Plugin/LuaConsole/resource.h +++ /dev/null @@ -1,24 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by LuaConsole.rc -// -#define IDD_CONSOLE 101 -#define IDD_CONFIG 102 -#define IDC_EDIT1 1000 -#define IDC_FONTSIZE 1000 -#define IDS_INFO 1000 -#define IDS_TYPE 1001 -#define IDC_TERM 1002 -#define IDC_SPIN1 1003 -#define IDC_SCROLLBAR1 1004 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 104 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1005 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif From 5ecba8a7f5a2cc46d94c85aef296f6552514f335 Mon Sep 17 00:00:00 2001 From: Gondos Date: Wed, 5 Feb 2025 16:35:50 +0100 Subject: [PATCH 27/51] [ImGui]Convert PlaybackEd --- Src/Orbiter/FlightRecorder.cpp | 13 +- Src/Orbiter/PlaybackEd.cpp | 1260 ++++++++++++-------------------- Src/Orbiter/PlaybackEd.h | 205 +++--- 3 files changed, 554 insertions(+), 924 deletions(-) diff --git a/Src/Orbiter/FlightRecorder.cpp b/Src/Orbiter/FlightRecorder.cpp index 96c8ffc3c..8f748f58e 100644 --- a/Src/Orbiter/FlightRecorder.cpp +++ b/Src/Orbiter/FlightRecorder.cpp @@ -15,6 +15,7 @@ #include "Pane.h" #include "State.h" #include "MenuInfoBar.h" +#include "DlgMgr.h" #include #include #include @@ -934,14 +935,10 @@ void Orbiter::FRecorder_Play () } void Orbiter::FRecorder_ToggleEditor () -{ - if (FReditor) { - delete FReditor; - FReditor = 0; - } else { - const char *playbackdir = pState->PlaybackDir(); - FReditor = new PlaybackEditor (this, playbackdir); TRACENEW - } +{ + DlgPlaybackEditor *m_DlgPlaybackEditor = g_pOrbiter->DlgMgr()->EnsureEntry(); + const char *playbackdir = pState->PlaybackDir(); + m_DlgPlaybackEditor->Load(playbackdir); } // ================================================================ diff --git a/Src/Orbiter/PlaybackEd.cpp b/Src/Orbiter/PlaybackEd.cpp index 6290d6a95..2e65ac0b8 100644 --- a/Src/Orbiter/PlaybackEd.cpp +++ b/Src/Orbiter/PlaybackEd.cpp @@ -2,23 +2,231 @@ // Licensed under the MIT License #include "PlaybackEd.h" -#include "DlgMgr.h" // remove #include "Camera.h" #include "Log.h" -#include "Resource.h" +#include "imgui_extras.h" using namespace std; extern Orbiter *g_pOrbiter; extern Camera *g_camera; extern TimeData td; -extern char DBG_MSG[256]; -INT_PTR CALLBACK RecPlayAnn_DlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +static bool CompareEvents (const PlaybackEvent *first, const PlaybackEvent *second) +{ + return first->T0() < second->T0(); +} + +DlgPlaybackEditor::DlgPlaybackEditor() : ImGuiDialog("Playback Editor", {900,600}) { + m_sysfname = nullptr; + m_SelectedEvent = nullptr; +} + +DlgPlaybackEditor::~DlgPlaybackEditor() { + ClearEvents(); +} + +void DlgPlaybackEditor::OnDraw() { + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar; + + ImGui::Text("Playback Editor - Simulation time : %f", td.SimT0); + ImGui::BeginChild("ChildL", ImVec2(ImGui::GetContentRegionAvail().x/2.0, 0), ImGuiChildFlags_ResizeX, window_flags); + + const ImGuiTableFlags flags = ImGuiTableFlags_SizingStretchProp|ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable; + + ImVec2 outer_size = ImVec2(0.0f, ImGui::GetContentRegionAvail().y - 100); + if (ImGui::BeginTable("table_scrolly", 3, flags, outer_size)) + { + ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible + ImGui::TableSetupColumn("Timestamp", ImGuiTableColumnFlags_None, 0.5f); + ImGui::TableSetupColumn("Event", ImGuiTableColumnFlags_None, 0.5f); + ImGui::TableSetupColumn("Details", ImGuiTableColumnFlags_None, 2.0f); + ImGui::TableHeadersRow(); + + int i = 0; + bool ts_drawn = false; + if(m_Events.size() == 0) { + ImGui::TableNextRow(); + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, ImColor(1.0,0,0)); + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, ImColor(1.0,0,0)); + ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImColor(1.0,0,0)); + ImGui::TableSetColumnIndex(0); + ImGui::Text("%0.2f", td.SimT0); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted("NOW"); + } + for(auto &e : m_Events) { + i++; + const bool item_is_selected = e == m_SelectedEvent; + + if(e->T0() > td.SimT0 && !ts_drawn) { + ts_drawn = true; + ImGui::TableNextRow(); + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, ImColor(1.0,0,0)); + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, ImColor(1.0,0,0)); + ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImColor(1.0,0,0)); + ImGui::TableSetColumnIndex(0); + ImGui::Text("%0.2f", td.SimT0); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted("NOW"); + } + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + char label[32]; + sprintf(label, "%0.2f###line%d", e->T0(),i); + ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SpanAllColumns; + if (ImGui::Selectable(label, item_is_selected, selectable_flags)) + { + m_SelectedEvent = e; + } + + char tag[32]; + e->TagStr(tag); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%s",tag); + ImGui::TableSetColumnIndex(2); + e->DrawPreview(); + } + + ImGui::EndTable(); + } + + ImGui::BeginGroupPanel("Insert event"); + if(ImGui::Button("NOTE")) { + InsertEvent(new NoteEvent (td.SimT0, "New note")); + } + ImGui::SameLine(); + if(ImGui::Button("NOTEOFF")) { + InsertEvent(new NoteoffEvent (td.SimT0)); + } + ImGui::SameLine(); + if(ImGui::Button("NOTEPOS")) { + InsertEvent(new NoteposEvent (td.SimT0, 0.1,0.1,0.9,0.9)); + } + ImGui::SameLine(); + if(ImGui::Button("NOTECOL")) { + InsertEvent(new NotecolEvent (td.SimT0, 1.0, 1.0, 1.0)); + } + ImGui::SameLine(); + if(ImGui::Button("NOTESIZE")) { + InsertEvent(new NotesizeEvent (td.SimT0, 1.0)); + } + if(ImGui::Button("TACC")) { + InsertEvent(new TaccEvent (td.SimT0, 1.0, 0.0)); + } + ImGui::SameLine(); + if(ImGui::Button("CAMERA")) { + InsertEvent(new CameraEvent (td.SimT0)); + } + ImGui::SameLine(); + if(ImGui::Button("")) { + InsertEvent(new GenericEvent (td.SimT0, "", "")); + } + ImGui::EndGroupPanel(); + if(ImGui::Button("Delete")) { + DeleteSelectedEvent(); + } + ImGui::EndChild(); + ImGui::SameLine(); +// ImGui::BeginChild("ChildR", ImVec2(sz2, ImGui::GetContentRegionAvail().y), false, window_flags); + ImGui::BeginChild("ChildR", ImVec2(0,0), 0, window_flags); + ImGui::BeginChild("ChildRT", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y - 40), true, window_flags); + if(m_SelectedEvent) { + m_SelectedEvent->DrawEdit(); + if(ImGui::Button("Apply")) { + m_SelectedEvent->ApplyChanges(); + m_Events.sort(CompareEvents); + } + + } + ImGui::EndChild(); + ImGui::BeginChild("ChildRB", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y), true, window_flags); + if(ImGui::Button("Commit changes")) { + SaveEventFile(); + } + ImGui::SameLine(); + if(ImGui::Button("Discard uncommited changes")) { + ClearEvents(); + ScanEventFile(); + } + + ImGui::EndChild(); + ImGui::EndChild(); +} + +void DlgPlaybackEditor::InsertEvent(PlaybackEvent *e) { + m_Events.push_back(e); + m_Events.sort(CompareEvents); + m_SelectedEvent = e; +} + +void DlgPlaybackEditor::DeleteSelectedEvent() { + if(m_SelectedEvent==nullptr) return; + PlaybackEvent *prev = nullptr; + for(auto it = m_Events.begin(); it!=m_Events.end();++it) { + if(*it==m_SelectedEvent) { + m_Events.erase(it); + if(prev) { + m_SelectedEvent = prev; + } else if(m_Events.size()>0) { + m_SelectedEvent = m_Events.front(); + } else { + m_SelectedEvent = nullptr; + } + return; + } + prev = *it; + } +} + +void DlgPlaybackEditor::Load(const char *ScnName) { + char fname[1024]; + int i; + for (i = strlen(ScnName)-1; i > 0; i--) + if (ScnName[i-1] == '/' || ScnName[i-1] == '\\') break; + sprintf (fname, "Flights/%s/system.dat", ScnName+i); + + if(m_sysfname) free(m_sysfname); + m_sysfname = strdup(fname); + ClearEvents(); + ScanEventFile(); +} + +void DlgPlaybackEditor::ScanEventFile () +{ + char line[2048]; + ifstream ifs (m_sysfname); + while (ifs.getline (line, 2048)) { + PlaybackEvent *pe = PlaybackEvent::Create (line); + if (pe) { + m_Events.push_back(pe); + } + } +} + +void DlgPlaybackEditor::SaveEventFile () +{ + g_pOrbiter->FRecorder_SuspendPlayback(); + ofstream ofs (m_sysfname); + for (auto &e: m_Events) { + e->Write (ofs); + } + ofs.close(); + g_pOrbiter->FRecorder_RescanPlayback(); +} + +void DlgPlaybackEditor::ClearEvents() { + for(auto &e : m_Events) { + delete e; + } + m_Events.clear(); + m_SelectedEvent = nullptr; +} // ========================================================= -PlaybackEvent *PlaybackEvent::Create (PlaybackEditor *editor, char *event) +PlaybackEvent *PlaybackEvent::Create (char *event) { char *s; double t; @@ -33,45 +241,47 @@ PlaybackEvent *PlaybackEvent::Create (PlaybackEditor *editor, char *event) s = strtok (NULL, " \t\n"); if (!s || sscanf (s, "%lf", &delay) != 1) delay = 0.0; - TRACENEW; return new TaccEvent (editor, t, acc, delay); + TRACENEW; return new TaccEvent (t, acc, delay); } else if (!_stricmp (s, "CAMERA")) { - DWORD pr; + int32_t pr; s = strtok (NULL, " \t\n"); if (!s) return NULL; if (!_stricmp (s, "PRESET")) { s = strtok (NULL, " \t\n"); if (!s || sscanf (s, "%d", &pr) != 1) return NULL; - TRACENEW; return new CameraEvent (editor, t, pr); + TRACENEW; return new CameraEvent (t, pr); } else if (!strcmp (s, "SET")) { - TRACENEW; return new CameraEvent (editor, t, s+4); + TRACENEW; return new CameraEvent (t, s+4); } } else if (!_stricmp (s, "NOTE")) { - TRACENEW; return new NoteEvent (editor, t, strtok (NULL, "\n")); + TRACENEW; return new NoteEvent (t, strtok (NULL, "\n")); + } else if (!_stricmp (s, "NOTEOFF")) { + TRACENEW; return new NoteoffEvent (t); } else if (!_stricmp (s, "NOTEPOS")) { double x0, y0, x1, y1; int res = sscanf (s+8, "%lf %lf %lf %lf", &x0, &y0, &x1, &y1); if (res != 4) return NULL; - else { TRACENEW; return new NoteposEvent (editor, t, x0, y0, x1, y1); } + else { TRACENEW; return new NoteposEvent (t, x0, y0, x1, y1); } } else if (!_stricmp (s, "NOTECOL")) { double r, g, b; int res = sscanf (s+8, "%lf %lf %lf", &r, &g, &b); if (res != 3) return NULL; - else { TRACENEW; return new NotecolEvent (editor, t, r, g, b); } + else { TRACENEW; return new NotecolEvent (t, r, g, b); } } else if (!_stricmp (s, "NOTESIZE")) { double scale; int res = sscanf (s+9, "%lf", &scale); if (!res) return NULL; - else { TRACENEW; return new NotesizeEvent (editor, t, scale); } + else { TRACENEW; return new NotesizeEvent (t, scale); } } else { - TRACENEW; return new GenericEvent (editor, t, s, strtok (NULL, "\n")); + TRACENEW; return new GenericEvent (t, s, strtok (NULL, "\n")); } return NULL; } -PlaybackEvent::PlaybackEvent (PlaybackEditor *_editor, double _t0) +PlaybackEvent::PlaybackEvent (double _t0) { - editor = _editor; t0 = _t0; + sprintf(m_tmp_t0, "%0.2f", t0); } void PlaybackEvent::TimeStr (char *str) @@ -86,58 +296,16 @@ void PlaybackEvent::WriteEvent (ofstream &ofs, const char *eventtype, const char ofs << endl; } -void PlaybackEvent::EditEvent (PlaybackEditor *editor) -{ - HWND hEditor = editor->EditTab(); - if (hEditor) { - char cbuf[64]; - sprintf (cbuf, "%0.3f", t0); - SetWindowText (GetDlgItem (hEditor, IDC_EVTIME), cbuf); - } -} - -void PlaybackEvent::CommitEdit () -{ - HWND hEdit = editor->EditTab(); - if (hEdit) { - char cbuf[256]; - double t; - GetWindowText (GetDlgItem (hEdit, IDC_EVTIME), cbuf, 256); - if (sscanf (cbuf, "%lf", &t) == 1 && fabs (t-t0) > 1e-3) { - t0 = t; - // check if we need to re-sort the event list - editor->SortEvent (this); - } - } +void PlaybackEvent::DrawEdit() { + ImGui::InputText("Event Time", m_tmp_t0, sizeof(m_tmp_t0), ImGuiInputTextFlags_CharsDecimal); } -INT_PTR PlaybackEvent::MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_NOTIFY: - if (((NMHDR*)lParam)->idFrom == IDC_SPIN1) { - if (((NMHDR*)lParam)->code == UDN_DELTAPOS) { - NMUPDOWN *nmud = (NMUPDOWN*)lParam; - char cbuf[256]; - double et; - GetWindowText (GetDlgItem (hDlg, IDC_EVTIME), cbuf, 256); - if (sscanf (cbuf, "%lf", &et)) { - et -= nmud->iDelta; - et = max (et, 0.0); - sprintf (cbuf, "%f", et); - SetWindowText (GetDlgItem (hDlg, IDC_EVTIME), cbuf); - CommitEdit(); - } - } - } - break; - } - return FALSE; +void PlaybackEvent::ApplyChanges() { + t0 = atof(m_tmp_t0); } - // ========================================================= -GenericEvent::GenericEvent (PlaybackEditor *_editor, double _t0, const char *_tag, const char *_content): PlaybackEvent (_editor, _t0) +GenericEvent::GenericEvent (double _t0, const char *_tag, const char *_content): PlaybackEvent (_t0) { content = tag = 0; SetTag (_tag); @@ -146,22 +314,13 @@ GenericEvent::GenericEvent (PlaybackEditor *_editor, double _t0, const char *_ta GenericEvent::~GenericEvent () { - if (tag) { - delete []tag; - tag = NULL; - } - if (content) { - delete []content; - content = NULL; - } + if (tag) delete []tag; + if (content) delete []content; } void GenericEvent::SetTag (const char *_tag) { - if (tag) { - delete []tag; - tag = NULL; - } + if (tag) delete []tag; if (_tag) { tag = new char[strlen(_tag)+1]; TRACENEW strcpy (tag, _tag); @@ -170,10 +329,7 @@ void GenericEvent::SetTag (const char *_tag) void GenericEvent::SetContent (const char *_content) { - if (content) { - delete []content; - content = NULL; - } + if (content) delete []content; if (_content) { content = new char[strlen(_content)+1]; TRACENEW strcpy (content, _content); @@ -196,58 +352,36 @@ void GenericEvent::Write (ofstream &ofs) WriteEvent (ofs, tag, content); } -void GenericEvent::EditEvent (PlaybackEditor *editor) -{ - editor->OpenEditTab (this, IDD_PBEDITOR_GENERIC, EditProc); - PlaybackEvent::EditEvent (editor); - if (tag) - SetWindowText (GetDlgItem (editor->EditTab(), IDC_EDIT3), tag); +void GenericEvent::DrawPreview() { if (content) - SetWindowText (GetDlgItem (editor->EditTab(), IDC_EDIT1), content); -} - -void GenericEvent::CommitEdit () -{ - PlaybackEvent::CommitEdit(); - char cbuf[2048]; - HWND hEdit = editor->EditTab(); - GetWindowText (GetDlgItem (hEdit, IDC_EDIT3), cbuf, 2048); - SetTag (cbuf); - GetWindowText (GetDlgItem (hEdit, IDC_EDIT1), cbuf, 2048); - SetContent (cbuf); -} - -INT_PTR GenericEvent::MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - return PlaybackEvent::MsgProc (hDlg, uMsg, wParam, lParam); + ImGui::TextUnformatted(content); + else + ImGui::TextUnformatted("---"); } -INT_PTR CALLBACK GenericEvent::EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - GenericEvent *event = (uMsg == WM_INITDIALOG ? - (GenericEvent*)lParam : (GenericEvent*)GetWindowLongPtr (hDlg, GWLP_USERDATA)); - return (event ? event->MsgProc (hDlg, uMsg, wParam, lParam) : FALSE); +void GenericEvent::DrawEdit() { + PlaybackEvent::DrawEdit(); + char ltag[4096]; + char lcontent[4096]; + if(tag) strncpy(ltag, tag, 4095); + if(content) strncpy(lcontent, content, 4095); + ltag[4095]='\0'; + lcontent[4095]='\0'; + if(ImGui::InputText("Tag", ltag, sizeof(ltag))) { + SetTag(ltag); + } + if(ImGui::InputText("Content", lcontent, sizeof(lcontent))) { + SetContent(lcontent); + } } // ========================================================= -TaccEvent::TaccEvent (PlaybackEditor *_editor, double _t0, double _tacc, double _delay): PlaybackEvent (_editor, _t0) +TaccEvent::TaccEvent (double _t0, double _tacc, float _delay): PlaybackEvent (_t0) { - tacc = _tacc; + tmp_tacc = tacc = _tacc; delay = _delay; -} - -void TaccEvent::SetTacc (double _tacc) -{ - tacc = min (1e5, max (0.1, _tacc)); - char cbuf[256]; - sprintf (cbuf, "%0.2f", tacc); - SetWindowText (GetDlgItem (editor->EditTab(), IDC_EDIT1), cbuf); -} - -void TaccEvent::SetDelay (double _delay) -{ - delay = max (0.0, _delay); + sprintf(tmp_delay, "%f", delay); } void TaccEvent::TagStr (char *str) @@ -272,72 +406,31 @@ void TaccEvent::Write (ofstream &ofs) WriteEvent (ofs, "TACC", cbuf); } -void TaccEvent::EditEvent (PlaybackEditor *editor) -{ - editor->OpenEditTab (this, IDD_PBEDITOR_TACC, EditProc); - PlaybackEvent::EditEvent (editor); - char cbuf[128]; - sprintf (cbuf, "%0.2f", tacc); - SetWindowText (GetDlgItem (editor->EditTab(), IDC_EDIT1), cbuf); - sprintf (cbuf, "%0.2f", delay); - SetWindowText (GetDlgItem (editor->EditTab(), IDC_EDIT2), cbuf); -} - -void TaccEvent::CommitEdit () -{ - PlaybackEvent::CommitEdit(); - char cbuf[2048]; - double ta, dl; - HWND hEdit = editor->EditTab(); - GetWindowText (GetDlgItem (hEdit, IDC_EDIT1), cbuf, 2048); - sscanf (cbuf, "%lf", &ta); - SetTacc (ta); - GetWindowText (GetDlgItem (hEdit, IDC_EDIT2), cbuf, 2048); - sscanf (cbuf, "%lf", &dl); - SetDelay (dl); -} - -INT_PTR TaccEvent::MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_BUTTON1: - SetTacc (0.1); - return FALSE; - case IDC_BUTTON2: - SetTacc (1.0); - return FALSE; - case IDC_BUTTON3: - SetTacc (10.0); - return FALSE; - case IDC_BUTTON4: - SetTacc (1e2); - return FALSE; - case IDC_BUTTON5: - SetTacc (1e3); - return FALSE; - case IDC_BUTTON6: - SetTacc (1e4); - return FALSE; - } - break; +void TaccEvent::DrawPreview() { + if (delay) { + ImGui::Text ("%0.2fx (delay %0.1f)", tacc, delay); + } else { + ImGui::Text ("%0.2fx", tacc); } - return PlaybackEvent::MsgProc (hDlg, uMsg, wParam, lParam); } -INT_PTR CALLBACK TaccEvent::EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - TaccEvent *event = (uMsg == WM_INITDIALOG ? - (TaccEvent*)lParam : (TaccEvent*)GetWindowLongPtr (hDlg, GWLP_USERDATA)); - return (event ? event->MsgProc (hDlg, uMsg, wParam, lParam) : FALSE); -} +void TaccEvent::DrawEdit() { + PlaybackEvent::DrawEdit(); + ImGui::SliderFloat("Time Acceleration", &tmp_tacc, 0.1f, 10000.0f, "%.1f", ImGuiSliderFlags_Logarithmic); + ImGui::InputText("Delay (s)", tmp_delay, sizeof(tmp_delay), ImGuiInputTextFlags_CharsDecimal); + +} +void TaccEvent::ApplyChanges() { + PlaybackEvent::ApplyChanges(); + tacc = tmp_tacc; + delay = atof(tmp_delay); +} // ========================================================= -CameraEvent::CameraEvent (PlaybackEditor *_editor, double _t0, DWORD _preset): PlaybackEvent (_editor, _t0) +CameraEvent::CameraEvent (double _t0, int _preset): PlaybackEvent (_t0) { - if (_preset != (DWORD)-1) { + if (_preset != -1) { SetPreset (_preset); } else { char cbuf[256]; @@ -347,22 +440,27 @@ CameraEvent::CameraEvent (PlaybackEditor *_editor, double _t0, DWORD _preset): P } } -CameraEvent::CameraEvent (PlaybackEditor *_editor, double _t0, char *_modestr): PlaybackEvent (_editor, _t0) +CameraEvent::CameraEvent (double _t0, char *_modestr): PlaybackEvent (_t0) { SetInlineMode (_modestr); } -void CameraEvent::SetPreset (DWORD _preset) +void CameraEvent::SetPreset (int _preset, bool editmode) { - preset = _preset; - sprintf (modestr, "PRESET %d", preset); + if(!editmode) { + sprintf (modestr, "PRESET %d", _preset); + } + sprintf (m_tmp_modestr, "PRESET %d", _preset); } -void CameraEvent::SetInlineMode (char *mode) +void CameraEvent::SetInlineMode (char *mode, bool editmode) { - preset = (DWORD)-1; - strcpy (modestr, "SET "); - strcat (modestr, mode); + if(!editmode) { + strcpy (modestr, "SET "); + strcat (modestr, mode); + } + strcpy (m_tmp_modestr, "SET "); + strcat (m_tmp_modestr, mode); } void CameraEvent::TagStr (char *str) @@ -380,111 +478,58 @@ void CameraEvent::Write (ofstream &ofs) WriteEvent (ofs, "CAMERA", modestr); } -void CameraEvent::EditEvent (PlaybackEditor *editor) -{ - editor->OpenEditTab (this, IDD_PBEDITOR_CAMPRESET, EditProc); - PlaybackEvent::EditEvent (editor); - if (preset != (DWORD)-1) - SendDlgItemMessage (editor->EditTab(), IDC_COMBO1, CB_SETCURSEL, preset, 0); -} - -void CameraEvent::CommitEdit () -{ - PlaybackEvent::CommitEdit(); - HWND hEdit = editor->EditTab(); - DWORD idx = SendDlgItemMessage (hEdit, IDC_COMBO1, CB_GETCURSEL, 0, 0); - if (idx != CB_ERR) SetPreset (idx); -} - -void CameraEvent::ScanPresets (HWND hTab) -{ - // populate the list of available presets - DWORD i, np = g_camera->nPreset(); - char cbuf[256], descr[256]; - SendDlgItemMessage (hTab, IDC_COMBO1, CB_RESETCONTENT, 0, 0); - for (i = 0; i < np; i++) { - CameraMode *cm = g_camera->GetPreset (i); - cm->GetDescr (descr, 256); - sprintf (cbuf, "%d (%s)", i, descr); - SendDlgItemMessage (hTab, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)cbuf); +void CameraEvent::DrawPreview() { + ImGui::TextUnformatted (modestr); +} + +void CameraEvent::DrawEdit() { + PlaybackEvent::DrawEdit(); + ImGui::Text("Camera configuration: "); + ImGui::SameLine(); + ImGui::TextUnformatted(m_tmp_modestr); + + char descr[256]; + int np = g_camera->nPreset(); + if(np) { + ImGui::Separator(); + ImGui::TextUnformatted("Presets:"); + for(int i=0;iGetPreset (i); + cm->GetDescr (descr, 256); + char cbuf[280]; + sprintf(cbuf, "%d (%s)", i, descr); + if(ImGui::Button(cbuf)) { + SetPreset(i, true); + } + } } - if (preset < np) - SendDlgItemMessage (hTab, IDC_COMBO1, CB_SETCURSEL, preset, 0); - else - SetWindowText (GetDlgItem (hTab, IDC_EDIT1), modestr+4); -} - -void CameraEvent::AddCurrentView (HWND hTab) -{ - char cbuf[256]; + ImGui::Separator(); + ImGui::Text("Current view: "); CameraMode *cm = g_camera->GetCMode(); + char cbuf[256]; cm->Store (cbuf); - SetInlineMode (cbuf); - SendDlgItemMessage (hTab, IDC_COMBO1, CB_SETCURSEL, -1, 0); - SetWindowText (GetDlgItem (hTab, IDC_EDIT1), cbuf); -} - -INT_PTR CameraEvent::MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_INITDIALOG: - ScanPresets (hDlg); - return FALSE; - case WM_COMMAND: - switch (LOWORD (wParam)) { - case IDC_COMBO1: - if (HIWORD (wParam) == CBN_SELCHANGE) { - DWORD idx = SendDlgItemMessage (hDlg, IDC_COMBO1, CB_GETCURSEL, 0, 0); - SetPreset (idx); - SetWindowText (GetDlgItem (hDlg, IDC_EDIT1), ""); - return FALSE; - } - break; - case IDC_BUTTON1: - AddCurrentView (hDlg); - return FALSE; - } - break; + ImGui::SameLine(); + if(ImGui::Button(cbuf)) { + SetInlineMode (cbuf, true); } - return PlaybackEvent::MsgProc (hDlg, uMsg, wParam, lParam); } +void CameraEvent::ApplyChanges() { + PlaybackEvent::ApplyChanges(); - -INT_PTR CALLBACK CameraEvent::EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - CameraEvent *event = (uMsg == WM_INITDIALOG ? - (CameraEvent*)lParam : (CameraEvent*)GetWindowLongPtr (hDlg, GWLP_USERDATA)); - return (event ? event->MsgProc (hDlg, uMsg, wParam, lParam) : FALSE); + strcpy(modestr, m_tmp_modestr); } // ========================================================= -NoteEvent::NoteEvent (PlaybackEditor *_editor, double _t0, const char *_note): PlaybackEvent (_editor, _t0) +NoteEvent::NoteEvent (double _t0, const char *_note): PlaybackEvent (_t0) { - note = NULL; - SetNote (_note); + note = strdup(_note); + strncpy(m_tmp_note, note, sizeof(m_tmp_note)); } NoteEvent::~NoteEvent () { - if (note) { - delete []note; - note = NULL; - } -} - -void NoteEvent::SetNote (const char *_note) -{ - if (note) { - delete []note; - note = NULL; - } - if (_note) { - note = new char[strlen(_note)+1]; TRACENEW - strcpy (note, _note); - } else { - note = 0; - } + if (note) free(note); } void NoteEvent::TagStr (char *str) @@ -503,37 +548,28 @@ void NoteEvent::Write (ofstream &ofs) WriteEvent (ofs, "NOTE", note ? note : ""); } -void NoteEvent::EditEvent (PlaybackEditor *editor) -{ - editor->OpenEditTab (this, IDD_PBEDITOR_NOTE, EditProc); - PlaybackEvent::EditEvent (editor); - SetWindowText (GetDlgItem (editor->EditTab(), IDC_EDIT1), note); +void NoteEvent::DrawPreview() { + if (note) { + ImGui::TextUnformatted (note); + } else { + ImGui::TextUnformatted ("---"); + } } -void NoteEvent::CommitEdit () -{ - PlaybackEvent::CommitEdit(); - char cbuf[2048]; - HWND hEdit = editor->EditTab(); - GetWindowText (GetDlgItem (hEdit, IDC_EDIT1), cbuf, 2048); - SetNote (cbuf); +void NoteEvent::DrawEdit() { + PlaybackEvent::DrawEdit(); + ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput; + ImGui::InputTextMultiline("##NoteEvent", m_tmp_note, IM_ARRAYSIZE(m_tmp_note), ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y - 30), flags); } - -INT_PTR CALLBACK NoteEvent::EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - NoteEvent *event = (uMsg == WM_INITDIALOG ? - (NoteEvent*)lParam : (NoteEvent*)GetWindowLongPtr (hDlg, GWLP_USERDATA)); - return (event ? event->MsgProc (hDlg, uMsg, wParam, lParam) : FALSE); +void NoteEvent::ApplyChanges() { + PlaybackEvent::ApplyChanges(); + if(note) free(note); + note = strdup(m_tmp_note); } // ========================================================= -NoteposEvent::NoteposEvent (PlaybackEditor *_editor, double _t0, double _x0, double _y0, double _x1, double _y1): PlaybackEvent (_editor, _t0) -{ - SetPos (_x0, _y0, _x1, _y1); -} - -void NoteposEvent::SetPos (double _x0, double _y0, double _x1, double _y1) +NoteposEvent::NoteposEvent (double _t0, double _x0, double _y0, double _x1, double _y1): PlaybackEvent (_t0) { x0 = _x0; y0 = _y0; @@ -558,50 +594,93 @@ void NoteposEvent::Write (ofstream &ofs) WriteEvent (ofs, "NOTEPOS", cbuf); } -void NoteposEvent::EditEvent (PlaybackEditor *editor) -{ - char cbuf[256]; - editor->OpenEditTab (this, IDD_PBEDITOR_NOTEPOS, EditProc); - PlaybackEvent::EditEvent (editor); - HWND hEdit = editor->EditTab(); - sprintf (cbuf, "%0.2f", x0); SetWindowText (GetDlgItem (hEdit, IDC_EDIT1), cbuf); - sprintf (cbuf, "%0.2f", y0); SetWindowText (GetDlgItem (hEdit, IDC_EDIT2), cbuf); - sprintf (cbuf, "%0.2f", x1); SetWindowText (GetDlgItem (hEdit, IDC_EDIT3), cbuf); - sprintf (cbuf, "%0.2f", y1); SetWindowText (GetDlgItem (hEdit, IDC_EDIT4), cbuf); +void NoteposEvent::DrawPreview() { + ImGui::Text ("%g %g %g %g", x0, y0, x1, y1); } -void NoteposEvent::CommitEdit () -{ - PlaybackEvent::CommitEdit(); - char cbuf[256]; - HWND hEdit = editor->EditTab(); - double _x0, _y0, _x1, _y1; - GetWindowText (GetDlgItem (hEdit, IDC_EDIT1), cbuf, 256); sscanf (cbuf, "%lf", &_x0); - GetWindowText (GetDlgItem (hEdit, IDC_EDIT2), cbuf, 256); sscanf (cbuf, "%lf", &_y0); - GetWindowText (GetDlgItem (hEdit, IDC_EDIT3), cbuf, 256); sscanf (cbuf, "%lf", &_x1); - GetWindowText (GetDlgItem (hEdit, IDC_EDIT4), cbuf, 256); sscanf (cbuf, "%lf", &_y1); - SetPos (_x0, _y0, _x1, _y1); +void NoteposEvent::DrawEdit() { + PlaybackEvent::DrawEdit(); + + ImVec2 virtual_screen_size(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().x * 3.0f/4.0f); + ImGui::InvisibleButton("##empty", virtual_screen_size); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const ImVec2 p0 = ImGui::GetItemRectMin(); + const ImVec2 p1 = ImGui::GetItemRectMax(); + draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255)); + + ImVec2 wpos1 = ImVec2(m_offsetPos.x+p0.x+x0 * virtual_screen_size.x,m_offsetPos.y+ p0.y+y0 * virtual_screen_size.y); + ImVec2 wpos2 = ImVec2(m_offsetPos.x+p0.x+m_offsetSize.x+x1 * virtual_screen_size.x,m_offsetPos.y+ p0.y+m_offsetSize.y+y1 * virtual_screen_size.y); + + ImGui::PushClipRect(p0, p1, true); + draw_list->AddRectFilled(wpos1, wpos2, IM_COL32(70, 70, 100, 255)); + ImVec2 tri1 = ImVec2(wpos2.x - 10, wpos2.y); + ImVec2 tri2 = ImVec2(wpos2.x, wpos2.y - 10); + draw_list->AddRect(wpos1, wpos2, IM_COL32(20, 20, 40, 255)); + draw_list->AddTriangleFilled(wpos2, tri1, tri2, IM_COL32(20, 20, 40, 255)); + ImGui::PopClipRect(); + + float mx = ImGui::GetIO().MousePos.x; + float my = ImGui::GetIO().MousePos.y; + + if(wpos1.xMsgProc (hDlg, uMsg, wParam, lParam) : FALSE); + m_offsetPos = {0,0}; + m_offsetSize = {0,0}; + m_state = 0; } // ========================================================= -NotecolEvent::NotecolEvent (PlaybackEditor *_editor, double _t0, double _r, double _g, double _b): PlaybackEvent (_editor, _t0) -{ - SetCol (_r, _g, _b); -} - -void NotecolEvent::SetCol (double _r, double _g, double _b) +NotecolEvent::NotecolEvent (double _t0, double _r, double _g, double _b): PlaybackEvent (_t0) { r = _r; g = _g; b = _b; + m_tmp[0] = (float)r; + m_tmp[1] = (float)g; + m_tmp[2] = (float)b; } void NotecolEvent::TagStr (char *str) @@ -621,75 +700,29 @@ void NotecolEvent::Write (ofstream &ofs) WriteEvent (ofs, "NOTECOL", cbuf); } -void NotecolEvent::EditEvent (PlaybackEditor *editor) -{ - char cbuf[256]; - editor->OpenEditTab (this, IDD_PBEDITOR_NOTECOL, EditProc); - PlaybackEvent::EditEvent (editor); - HWND hEdit = editor->EditTab(); - sprintf (cbuf, "%g", r); SetWindowText (GetDlgItem (hEdit, IDC_EDIT1), cbuf); - sprintf (cbuf, "%g", g); SetWindowText (GetDlgItem (hEdit, IDC_EDIT2), cbuf); - sprintf (cbuf, "%g", b); SetWindowText (GetDlgItem (hEdit, IDC_EDIT3), cbuf); +void NotecolEvent::DrawPreview() { + ImVec4 col = { (float)r,(float)g,(float)b,1.0 }; + ImGui::TextColored(col, "COLOR"); } -void NotecolEvent::CommitEdit () -{ - PlaybackEvent::CommitEdit(); - char cbuf[256]; - HWND hEdit = editor->EditTab(); - double _r, _g, _b; - GetWindowText (GetDlgItem (hEdit, IDC_EDIT1), cbuf, 256); sscanf (cbuf, "%lf", &_r); - GetWindowText (GetDlgItem (hEdit, IDC_EDIT2), cbuf, 256); sscanf (cbuf, "%lf", &_g); - GetWindowText (GetDlgItem (hEdit, IDC_EDIT3), cbuf, 256); sscanf (cbuf, "%lf", &_b); - SetCol (_r, _g, _b); +void NotecolEvent::DrawEdit() { + PlaybackEvent::DrawEdit(); + ImGui::Text("Note Color"); + ImGui::ColorPicker3("Color", m_tmp, ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoLabel); } - -INT_PTR NotecolEvent::MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_NOTIFY: { - int editid = 0; - switch (((NMHDR*)lParam)->idFrom) { - case IDC_SPIN2: editid = IDC_EDIT1; break; - case IDC_SPIN3: editid = IDC_EDIT2; break; - case IDC_SPIN4: editid = IDC_EDIT3; break; - } - if (editid) { - if (((NMHDR*)lParam)->code == UDN_DELTAPOS) { - NMUPDOWN *nmud = (NMUPDOWN*)lParam; - char cbuf[256]; - double col; - GetWindowText (GetDlgItem (hDlg, editid), cbuf, 256); - if (sscanf (cbuf, "%lf", &col)) { - col -= nmud->iDelta*0.1; - col = min (max (col, 0.0), 1.0); - sprintf (cbuf, "%f", col); - SetWindowText (GetDlgItem (hDlg, editid), cbuf); - } - } - } - } break; - } - return PlaybackEvent::MsgProc (hDlg, uMsg, wParam, lParam); -} - -INT_PTR CALLBACK NotecolEvent::EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - NotecolEvent *event = (uMsg == WM_INITDIALOG ? - (NotecolEvent*)lParam : (NotecolEvent*)GetWindowLongPtr (hDlg, GWLP_USERDATA)); - return (event ? event->MsgProc (hDlg, uMsg, wParam, lParam) : FALSE); +void NotecolEvent::ApplyChanges() { + PlaybackEvent::ApplyChanges(); + r = m_tmp[0]; + g = m_tmp[1]; + b = m_tmp[2]; } // ========================================================= -NotesizeEvent::NotesizeEvent (PlaybackEditor *_editor, double _t0, double _size): PlaybackEvent (_editor, _t0) -{ - SetSize (_size); -} - -void NotesizeEvent::SetSize (double _size) +NotesizeEvent::NotesizeEvent (double _t0, double _size): PlaybackEvent (_t0) { size = _size; + sprintf(m_tmp_size,"%f",size); } void NotesizeEvent::TagStr (char *str) @@ -709,442 +742,47 @@ void NotesizeEvent::Write (ofstream &ofs) WriteEvent (ofs, "NOTESIZE", cbuf); } -void NotesizeEvent::EditEvent (PlaybackEditor *editor) -{ - char cbuf[256]; - editor->OpenEditTab (this, IDD_PBEDITOR_NOTESIZE, EditProc); - PlaybackEvent::EditEvent (editor); - HWND hEdit = editor->EditTab(); - sprintf (cbuf, "%g", size); SetWindowText (GetDlgItem (hEdit, IDC_EDIT1), cbuf); -} - -void NotesizeEvent::CommitEdit () -{ - PlaybackEvent::CommitEdit(); - char cbuf[256]; - HWND hEdit = editor->EditTab(); - double _size; - GetWindowText (GetDlgItem (hEdit, IDC_EDIT1), cbuf, 256); sscanf (cbuf, "%lf", &_size); - SetSize (_size); +void NotesizeEvent::DrawPreview() { + ImGui::Text ("%g", size); } -INT_PTR NotesizeEvent::MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_NOTIFY: - if (((NMHDR*)lParam)->code == UDN_DELTAPOS) { - NMUPDOWN *nmud = (NMUPDOWN*)lParam; - char cbuf[256]; - double _size; - GetWindowText (GetDlgItem (hDlg, IDC_EDIT1), cbuf, 256); - if (sscanf (cbuf, "%lf", &_size)) { - _size -= nmud->iDelta*0.1; - _size = max (_size, 0.0); - sprintf (cbuf, "%f", _size); - SetWindowText (GetDlgItem (hDlg, IDC_EDIT1), cbuf); - } - } - break; - } - return PlaybackEvent::MsgProc (hDlg, uMsg, wParam, lParam); +void NotesizeEvent::DrawEdit() { + PlaybackEvent::DrawEdit(); + ImGui::InputText("Note Size", m_tmp_size, sizeof(m_tmp_size), ImGuiInputTextFlags_CharsDecimal); } - -INT_PTR CALLBACK NotesizeEvent::EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - NotesizeEvent *event = (uMsg == WM_INITDIALOG ? - (NotesizeEvent*)lParam : (NotesizeEvent*)GetWindowLongPtr (hDlg, GWLP_USERDATA)); - return (event ? event->MsgProc (hDlg, uMsg, wParam, lParam) : FALSE); +void NotesizeEvent::ApplyChanges() { + PlaybackEvent::ApplyChanges(); + size = atof(m_tmp_size); } // ========================================================= -// ========================================================= - -PlaybackEditor::PlaybackEditor (Orbiter *ob, const char *ScnName) -{ - int i; - char fname[1024]; - - orbiter = ob; - Efirst = Elast = 0; - timer = 0; - - for (i = strlen(ScnName)-1; i > 0; i--) - if (ScnName[i-1] == '\\') break; - sprintf (fname, "Flights\\%s\\system.dat", ScnName+i); - - sysfname = new char[strlen(fname)+1]; TRACENEW - strcpy (sysfname, fname); - - hDlg = OpenDialog(); - hEdit = NULL; - - ScanEventFile (); - RefreshEventList (); - InsertTMarker (); -} - -PlaybackEditor::~PlaybackEditor () -{ - if (hEdit) { - CommitEdit(); - DestroyWindow (hEdit); - } - CloseDialog(); - if (timer) KillTimer (hDlg, timer); -} -HWND PlaybackEditor::OpenDialog () +NoteoffEvent::NoteoffEvent (double _t0): PlaybackEvent (_t0) { - return orbiter->OpenDialogEx (IDD_RECPLAY_ANNOTATE, RecPlayAnn_DlgProc, DLG_CAPTIONCLOSE | DLG_CAPTIONHELP, this); } -void PlaybackEditor::CloseDialog () +void NoteoffEvent::TagStr (char *str) { - if (hDlg) { - orbiter->CloseDialog (hDlg); - hDlg = 0; - } + strcpy (str, "NOTEOFF"); } -HWND PlaybackEditor::OpenEditTab (PlaybackEvent *event, int resid, DLGPROC tabproc) +void NoteoffEvent::DescStr (char *str) { - if (hEdit) { - RegisterEdit (hEdit); // save current edits - DestroyWindow (hEdit); // remove current edit tab - } - if (resid) { - hEdit = CreateDialogParam (orbiter->GetInstance(), MAKEINTRESOURCE(resid), hDlg, tabproc, (LPARAM)event); - SetWindowLongPtr (hEdit, GWLP_USERDATA, (LONG_PTR)event); - } else { - hEdit = NULL; - } - return hEdit; + str[0] = '\0'; } -void PlaybackEditor::RegisterEdit (HWND hEdit) +void NoteoffEvent::Write (ofstream &ofs) { - PlaybackEvent *e = (PlaybackEvent*)GetWindowLongPtr (hEdit, GWLP_USERDATA); - if (e) e->CommitEdit(); - int idx = SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETCURSEL, 0, 0); - if (idx != LB_ERR) - e = (PlaybackEvent*)SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETITEMDATA, idx, 0); - else e = 0; - RefreshEventList (e); - InsertTMarker(); + WriteEvent (ofs, "NOTEOFF", ""); } -INT_PTR PlaybackEditor::DlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_INITDIALOG: { - INT tabs[2] = {40, 80}; - SendDlgItemMessage (hDlg, IDC_LIST1, LB_SETTABSTOPS, 2, (LPARAM)tabs); - CreateInsertEventList (hDlg); - timer = SetTimer (hDlg, 1, 100, NULL); - } return 0; - case WM_TIMER: - RefreshTMarker(); - break; - case WM_COMMAND: - switch (LOWORD (wParam)) { - case IDHELP: { - extern HELPCONTEXT DefHelpContext; - DefHelpContext.topic = (char*)"/playbackedit.htm"; - orbiter->OpenHelp (&DefHelpContext); - } return TRUE; - case IDCANCEL: - orbiter->CloseDialog (hDlg); - orbiter->FRecorder_ToggleEditor(); - return FALSE; - case IDC_BUTTON1: // delete event - DeleteEvent(); - break; - case IDC_BUTTON2: // insert event - InsertEvent(); - break; - case IDC_BUTTON3: // commit edits - SaveEventFile(); - break; - case IDC_LIST1: - switch (HIWORD (wParam)) { - case LBN_SELCHANGE: { - int idx = SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETCURSEL, 0, 0); - if (idx != LB_ERR && idx != tmarkidx) { - PlaybackEvent *e = (PlaybackEvent*)SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETITEMDATA, idx, 0); - if (e) e->EditEvent (this); - } - } break; - } - break; - } - break; - } - return OrbiterDefDialogProc (hDlg, uMsg, wParam, lParam); +void NoteoffEvent::DrawPreview() { + ImGui::Text ("---", size); } -void PlaybackEditor::CreateInsertEventList (HWND hDlg) -{ - const int nevent = 7; - static const char *events[nevent] = { - "NOTE (annotation text)", - "NOTEPOS (bounding box)", - "NOTECOL (text colour)", - "NOTESIZE (text size)", - "TACC (time acceleration)", - "CAMERA (view position)", - "" - }; - SendDlgItemMessage (hDlg, IDC_COMBO1, CB_RESETCONTENT, 0, 0); - for (int i = 0; i < nevent; i++) - SendDlgItemMessage (hDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)events[i]); - SendDlgItemMessage (hDlg, IDC_COMBO1, CB_SETCURSEL, 0, 0); -} - -void PlaybackEditor::ScanEventFile () -{ - char line[2048]; - ifstream ifs (sysfname); - while (ifs.getline (line, 2048)) { - PlaybackEvent *pe = PlaybackEvent::Create (this, line); - if (pe) { - Event *event = new Event; TRACENEW - event->e = pe; - event->next = NULL; - if (Elast) Elast->next = event; - else Efirst = event; - Elast = event; - } - } +void NoteoffEvent::DrawEdit() { + PlaybackEvent::DrawEdit(); } - -void PlaybackEditor::SaveEventFile () -{ - CommitEdit(); // commit last edits - orbiter->FRecorder_SuspendPlayback(); - ofstream ofs (sysfname); - Event *ev; - for (ev = Efirst; ev; ev = ev->next) { - ev->e->Write (ofs); - } - ofs.close(); - orbiter->FRecorder_RescanPlayback(); +void NoteoffEvent::ApplyChanges() { + PlaybackEvent::ApplyChanges(); } - -void PlaybackEditor::CommitEdit () -{ - PlaybackEvent *e = NULL; - if (hEdit) - e = (PlaybackEvent*)GetWindowLongPtr (hEdit, GWLP_USERDATA); - if (e) { - e->CommitEdit(); - RefreshEventList (e); - InsertTMarker(); - } -} - -void PlaybackEditor::RefreshEventList (PlaybackEvent *emark) -{ - SendDlgItemMessage (hDlg, IDC_LIST1, LB_RESETCONTENT, 0, 0); - Event *event; - char cbuf[1024], tstr[64], tagstr[64], descstr[1024]; - int idx; - for (event = Efirst; event; event = event->next) { - event->e->TimeStr (tstr); - event->e->TagStr (tagstr); - event->e->DescStr (descstr); - sprintf (cbuf, "%s\t%s\t%s", tstr, tagstr, descstr); - idx = SendDlgItemMessage (hDlg, IDC_LIST1, LB_ADDSTRING, 0, (LPARAM)cbuf); - SendDlgItemMessage (hDlg, IDC_LIST1, LB_SETITEMDATA, idx, (LPARAM)event->e); - if (event->e == emark) - SendDlgItemMessage (hDlg, IDC_LIST1, LB_SETCURSEL, idx, 0); - } -} - -int PlaybackEditor::InsertTMarker () -{ - int i; - char cbuf[1024]; - char tstr[1024]; - sprintf (tstr, "%0.1f\t< < < < < < < < < < < < < < < < < < <", td.SimT0); - double t; - for (i = 0;; i++) { - if (SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETTEXT, i, (LPARAM)cbuf) == LB_ERR) - break; - if (sscanf (cbuf, "%lf", &t) != 1) continue; - if (t >= td.SimT0) { - SendDlgItemMessage (hDlg, IDC_LIST1, LB_INSERTSTRING, i, (LPARAM)tstr); - tmarkidx = i; - return i; - } - } - return -1; -} - -void PlaybackEditor::RefreshTMarker () -{ - char cbuf[1024]; - char tstr[1024]; - double t, dummy; - if (orbiter->IsRunning()) { - bool blink = (modf (td.SysT0, &dummy) > 0.5); - if (blink) sprintf (tstr, "%0.0f", td.SimT0); - else sprintf (tstr, "%0.0f\t< < < < < < < < < < < < < < < < < < <", td.SimT0); - } else { - sprintf (tstr, "%0.2f\t< < < < < < < < < < < < < < < < < < < [Paused]", td.SimT0); - } - int i, topidx; - for (i = tmarkidx+1;; i++) { - if (SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETTEXT, i, (LPARAM)cbuf) == LB_ERR) - break; - if (sscanf (cbuf, "%lf", &t) != 1) continue; - if (t >= td.SimT0) break; - } - bool replace = (tmarkidx != i-1); - if (!replace) { - SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETTEXT, tmarkidx, (LPARAM)cbuf); - replace = (strcmp (cbuf, tstr) != 0); - } - if (replace) { - topidx = SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETTOPINDEX, 0, 0); - SendDlgItemMessage (hDlg, IDC_LIST1, LB_DELETESTRING, tmarkidx, 0); - SendDlgItemMessage (hDlg, IDC_LIST1, LB_INSERTSTRING, tmarkidx = i-1, (LPARAM)tstr); - SendDlgItemMessage (hDlg, IDC_LIST1, LB_SETTOPINDEX, topidx, 0); - } - if (orbiter->IsRunning()) { - topidx = SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETTOPINDEX, 0, 0); - if (topidx < max (tmarkidx-14, 0)) { - SendDlgItemMessage (hDlg, IDC_LIST1, LB_SETTOPINDEX, max (0, tmarkidx-14), 0); - } else if (topidx > tmarkidx-4) { - SendDlgItemMessage (hDlg, IDC_LIST1, LB_SETTOPINDEX, tmarkidx-4, 0); - } - } -} - -void PlaybackEditor::InsertEvent () -{ - PlaybackEvent *e = 0; - const double eps = 1e-3; - double newtime = td.SimT0-eps; // make sure the event is read when scanning the event list to current time - char cbuf[1024], eventstr[1024]; - GetWindowText (GetDlgItem (hDlg, IDC_COMBO1), cbuf, 1024); - sscanf (cbuf, "%s", eventstr); - if (!_stricmp (eventstr, "NOTE")) { - e = new NoteEvent (this, newtime, ""); TRACENEW - } else if (!_stricmp (eventstr, "NOTEPOS")) { - e = new NoteposEvent (this, newtime, 0, 0, 1, 1); TRACENEW - } else if (!_stricmp (eventstr, "NOTECOL")) { - e = new NotecolEvent (this, newtime, 1, 1, 1); TRACENEW - } else if (!_stricmp (eventstr, "NOTESIZE")) { - e = new NotesizeEvent (this, newtime, 1); TRACENEW - } else if (!_stricmp (eventstr, "TACC")) { - e = new TaccEvent (this, newtime, 1, 0); TRACENEW - } else if (!_stricmp (eventstr, "CAMERA")) { - e = new CameraEvent (this, newtime); TRACENEW - } else if (!_stricmp (eventstr, "")) { - e = new GenericEvent (this, newtime, "", ""); TRACENEW - } - if (e) { - Event *ev, *pev = 0, *event = new Event; TRACENEW - event->e = e; - event->next = NULL; - if (!Efirst) { - Efirst = event; - } else { - for (ev = Efirst; ev; ev = ev->next) { - if (ev->e->T0() > event->e->T0()) { - if (pev) { - pev->next = event; - } else { - Efirst = event; - } - event->next = ev; - break; - } - pev = ev; - } - if (!ev) { // add event to end of list - event->next = NULL; - if (pev) pev->next = event; - Elast->next = event; - } - } - if (!event->next) Elast = event; - } - RefreshEventList (e); - InsertTMarker (); - if (e) e->EditEvent (this); -} - -void PlaybackEditor::DeleteEvent () -{ - LRESULT idx = SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETCURSEL, 0, 0); - if (idx == LB_ERR || idx == tmarkidx) return; - - LRESULT res = SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETITEMDATA, idx, 0); - if (res == LB_ERR || res == 0) return; - - PlaybackEvent *e = (PlaybackEvent*)res; - Event *ev, *pev = 0; - for (ev = Efirst; ev; ev = ev->next) { - if (ev->e == e) { - if (hEdit) { - DestroyWindow (hEdit); - hEdit = NULL; - } - if (pev) pev->next = ev->next; - if (Efirst == ev) Efirst = ev->next; - if (Elast == ev) Elast = pev; - delete ev->e; - delete ev; - RefreshEventList (); - InsertTMarker (); - break; - } - pev = ev; - } -} - -void PlaybackEditor::SortEvent (PlaybackEvent *e) -{ - Event *event, *ev, *pev = 0; - bool needsort = false; - for (ev = Efirst; ev; ev = ev->next) { - if (ev->e == e) { - if (pev && pev->e->T0() > e->T0()) { needsort = true; break; } - if (ev->next && ev->next->e->T0() < e->T0()) { needsort = true; break; } - } - pev = ev; - } - if (needsort) { - event = ev; - // prise the event out of the list - if (pev) pev->next = ev->next; - if (Efirst == ev) Efirst = ev->next; - if (Elast == ev) Elast = pev; - // and re-insert in new place - event->next = NULL; - for (ev = Efirst, pev = 0; ev; ev = ev->next) { - if (ev->e->T0() > e->T0()) { - if (pev) pev->next = event; - else Efirst = event; - event->next = ev; - break; - } - pev = ev; - } - if (!event->next) Elast = event; - } -} - -// ====================================================================== - -INT_PTR CALLBACK RecPlayAnn_DlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - PlaybackEditor *pe = g_pOrbiter->FReditor; - if (uMsg == WM_INITDIALOG) { - pe = (PlaybackEditor*)lParam; - } - if (pe) return pe->DlgProc (hDlg, uMsg, wParam, lParam); - else return OrbiterDefDialogProc (hDlg, uMsg, wParam, lParam); -} - diff --git a/Src/Orbiter/PlaybackEd.h b/Src/Orbiter/PlaybackEd.h index dd6fc5ea8..c47cb6477 100644 --- a/Src/Orbiter/PlaybackEd.h +++ b/Src/Orbiter/PlaybackEd.h @@ -5,15 +5,34 @@ #define __PLAYBACKED_H #include "Orbiter.h" +#include "imgui.h" class PlaybackEditor; // ========================================================= +class PlaybackEvent; +class DlgPlaybackEditor : public ImGuiDialog { +public: + DlgPlaybackEditor(); + ~DlgPlaybackEditor(); + void OnDraw() override; + + void Load(const char *scenario); + void ScanEventFile(); + void SaveEventFile(); + char *m_sysfname; // system event file name + std::list m_Events; + PlaybackEvent *m_SelectedEvent; + + void ClearEvents(); + void InsertEvent(PlaybackEvent *); + void DeleteSelectedEvent(); +}; class PlaybackEvent { public: - static PlaybackEvent *Create (PlaybackEditor *editor, char *event); - PlaybackEvent (PlaybackEditor *_editor, double _t0); + static PlaybackEvent *Create (char *event); + PlaybackEvent (double _t0); virtual ~PlaybackEvent () {} inline double T0() const { return t0; } void TimeStr (char *str); @@ -21,12 +40,11 @@ class PlaybackEvent { virtual void DescStr (char *str) { str[0] = '\0'; } virtual void Write (std::ofstream &ofs) = 0; void WriteEvent (std::ofstream &ofs, const char *eventtype, const char *event); - virtual void EditEvent (PlaybackEditor *editor); - virtual void CommitEdit (); - virtual INT_PTR MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - + virtual void DrawPreview() = 0; + virtual void DrawEdit(); + virtual void ApplyChanges(); + char m_tmp_t0[32]; protected: - PlaybackEditor *editor; double t0; // event start time }; @@ -34,17 +52,15 @@ class PlaybackEvent { class GenericEvent: public PlaybackEvent { public: - GenericEvent (PlaybackEditor *_editor, double _t0, const char *_tag, const char *_content); + GenericEvent (double _t0, const char *_tag, const char *_content); ~GenericEvent (); void SetTag (const char *_tag); void SetContent (const char *_content); - void TagStr (char *str); - void DescStr (char *str); - void Write (std::ofstream &ofs); - void EditEvent (PlaybackEditor *editor); - void CommitEdit (); - INT_PTR MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + void TagStr (char *str) override; + void DescStr (char *str) override; + void Write (std::ofstream &ofs) override; + void DrawPreview() override; + void DrawEdit() override; private: char *tag; @@ -55,153 +71,132 @@ class GenericEvent: public PlaybackEvent { class TaccEvent: public PlaybackEvent { public: - TaccEvent (PlaybackEditor *_editor, double _t0, double _tacc, double _delay = 0.0); + TaccEvent (double _t0, double _tacc, float _delay = 0.0); inline double Tacc() const { return tacc; } - void SetTacc (double _tacc); - void SetDelay (double _delay); - void TagStr (char *str); - void DescStr (char *str); - void Write (std::ofstream &ofs); - void EditEvent (PlaybackEditor *editor); - void CommitEdit (); - INT_PTR MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + void TagStr (char *str) override; + void DescStr (char *str) override; + void Write (std::ofstream &ofs) override; + void DrawPreview() override; + void DrawEdit() override; + void ApplyChanges() override; private: double tacc; // time acceleration factor double delay; // delay time + float tmp_tacc; + char tmp_delay[20]; }; // ========================================================= class CameraEvent: public PlaybackEvent { public: - CameraEvent (PlaybackEditor *_editor, double _t0, DWORD _preset = (DWORD)-1); - CameraEvent (PlaybackEditor *_editor, double _t0, char *_modestr); - inline DWORD Preset() const { return preset; } - void SetPreset (DWORD _preset); - void SetInlineMode (char *mode); - void TagStr (char *str); - void DescStr (char *str); - void Write (std::ofstream &ofs); - void EditEvent (PlaybackEditor *editor); - void CommitEdit (); - INT_PTR MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + CameraEvent (double _t0, int _preset = -1); + CameraEvent (double _t0, char *_modestr); + void SetPreset (int _preset, bool editmode = false); + void SetInlineMode (char *mode, bool editmode = false); + void TagStr (char *str) override; + void DescStr (char *str) override; + void Write (std::ofstream &ofs) override; + void DrawPreview() override; + void DrawEdit() override; + void ApplyChanges() override; private: - void ScanPresets (HWND hTab); - void AddCurrentView (HWND hTab); - DWORD preset; char modestr[256]; + char m_tmp_modestr[256]; }; // ========================================================= class NoteEvent: public PlaybackEvent { public: - NoteEvent (PlaybackEditor *_editor, double _t0, const char *_note); + NoteEvent (double _t0, const char *_note); ~NoteEvent (); - void SetNote (const char *_note); - void TagStr (char *str); - void DescStr (char *str); - void Write (std::ofstream &ofs); - void EditEvent (PlaybackEditor *editor); - void CommitEdit (); - static INT_PTR CALLBACK EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + void TagStr (char *str) override; + void DescStr (char *str) override; + void Write (std::ofstream &ofs) override; + void DrawPreview() override; + void DrawEdit() override; + void ApplyChanges() override; private: char *note; + char m_tmp_note[2048]; }; // ========================================================= class NoteposEvent: public PlaybackEvent { public: - NoteposEvent (PlaybackEditor *_editor, double _t0, double _x0, double _y0, double _x1, double _y1); - void SetPos (double _x0, double _y0, double _x1, double _y1); - void TagStr (char *str); - void DescStr (char *str); - void Write (std::ofstream &ofs); - void EditEvent (PlaybackEditor *editor); - void CommitEdit (); - static INT_PTR CALLBACK EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + NoteposEvent (double _t0, double _x0, double _y0, double _x1, double _y1); + void TagStr (char *str) override; + void DescStr (char *str) override; + void Write (std::ofstream &ofs) override; + void DrawPreview() override; + void DrawEdit() override; + void ApplyChanges() override; private: double x0, y0, x1, y1; + ImVec2 m_offsetPos = {0,0}; + ImVec2 m_offsetSize = {0,0}; + int m_state = 0; + double m_tmp_x0; + double m_tmp_y0; + double m_tmp_x1; + double m_tmp_y1; }; // ========================================================= class NotecolEvent: public PlaybackEvent { public: - NotecolEvent (PlaybackEditor *_editor, double _t0, double _r, double _g, double _b); - void SetCol (double _r, double _g, double _b); - void TagStr (char *str); - void DescStr (char *str); - void Write (std::ofstream &ofs); - void EditEvent (PlaybackEditor *editor); - void CommitEdit (); - INT_PTR MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + NotecolEvent (double _t0, double _r, double _g, double _b); + void TagStr (char *str) override; + void DescStr (char *str) override; + void Write (std::ofstream &ofs) override; + void DrawPreview() override; + void DrawEdit() override; + void ApplyChanges() override; private: double r, g, b; + float m_tmp[3]; }; // ========================================================= class NotesizeEvent: public PlaybackEvent { public: - NotesizeEvent (PlaybackEditor *_editor, double _t0, double _size); - void SetSize (double _size); - void TagStr (char *str); - void DescStr (char *str); - void Write (std::ofstream &ofs); - void EditEvent (PlaybackEditor *editor); - void CommitEdit (); - INT_PTR MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK EditProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + NotesizeEvent (double _t0, double _size); + void TagStr (char *str) override; + void DescStr (char *str) override; + void Write (std::ofstream &ofs) override; + void DrawPreview() override; + void DrawEdit() override; + void ApplyChanges() override; private: double size; + char m_tmp_size[20]; }; -// ========================================================= // ========================================================= -class PlaybackEditor { +class NoteoffEvent: public PlaybackEvent { public: - PlaybackEditor (Orbiter *ob, const char *ScnName); - ~PlaybackEditor (); - INT_PTR DlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - HWND OpenEditTab (PlaybackEvent *event, int resid, DLGPROC tabproc); - HWND EditTab () const { return hEdit; } - void SortEvent (PlaybackEvent *e); + NoteoffEvent (double _t0); + void TagStr (char *str) override; + void DescStr (char *str) override; + void Write (std::ofstream &ofs) override; + void DrawPreview() override; + void DrawEdit() override; + void ApplyChanges() override; private: - HWND OpenDialog (); - void CloseDialog (); - void ScanEventFile (); - void SaveEventFile (); - void RefreshEventList (PlaybackEvent *emark = 0); - int InsertTMarker (); - void RefreshTMarker (); - void CreateInsertEventList (HWND hDlg); - void InsertEvent (); - void DeleteEvent (); - void CommitEdit (); - void RegisterEdit (HWND hEdit); - Orbiter *orbiter; - char *sysfname; // system event file name - HWND hDlg; // editor dialog handle - HWND hEdit; // currently displayed edit tab - UINT timer; // timer identifier - int tmarkidx; // list index of "current time" marker - struct Event { - PlaybackEvent *e; - struct Event *next; - } *Efirst, *Elast; // linked list of events + double size; + char m_tmp_size[20]; }; -#endif // !__PLAYBACKED_H \ No newline at end of file +#endif // !__PLAYBACKED_H From 217a9a51d32b8ab770ca9acbc20dbf3b57ebf84a Mon Sep 17 00:00:00 2001 From: Gondos Date: Thu, 6 Feb 2025 20:11:04 +0100 Subject: [PATCH 28/51] [ImGui]Convert DlgMap --- OVP/D3D9Client/D3D9Pad.cpp | 3 +- Src/Orbiter/DlgCamera.cpp | 3 +- Src/Orbiter/DlgCapture.cpp | 3 +- Src/Orbiter/DlgFocus.cpp | 3 +- Src/Orbiter/DlgFunction.cpp | 3 +- Src/Orbiter/DlgInfo.cpp | 3 +- Src/Orbiter/DlgMap.cpp | 1220 ++++++++------------------ Src/Orbiter/DlgMap.h | 149 +--- Src/Orbiter/DlgMenuCfg.cpp | 3 +- Src/Orbiter/DlgMgr.cpp | 14 +- Src/Orbiter/DlgRecorder.cpp | 3 +- Src/Orbiter/DlgTacc.cpp | 3 +- Src/Orbiter/MfdMap.cpp | 13 +- Src/Orbiter/Orbiter.cpp | 1 - Src/Orbiter/Select.cpp | 16 +- Src/Orbiter/VectorMap.cpp | 620 +++++-------- Src/Orbiter/VectorMap.h | 146 ++- Src/Plugin/ExtMFD/MFDWindow.cpp | 4 +- Src/Plugin/LuaConsole/LuaConsole.cpp | 2 +- 19 files changed, 717 insertions(+), 1495 deletions(-) diff --git a/OVP/D3D9Client/D3D9Pad.cpp b/OVP/D3D9Client/D3D9Pad.cpp index e16640939..73360e1c5 100644 --- a/OVP/D3D9Client/D3D9Pad.cpp +++ b/OVP/D3D9Client/D3D9Pad.cpp @@ -1304,7 +1304,8 @@ void D3D9Pad::Polygon (const IVECTOR2 *pt, int npt) #endif if (npt<3) return; - if (HasBrush() && npt > 64) return; + // The VectorMap drawing code creates polygons with at least 68 points + if (HasBrush() && npt > 70) return; // Create filled polygon interior ----------------------------------------- diff --git a/Src/Orbiter/DlgCamera.cpp b/Src/Orbiter/DlgCamera.cpp index 1077fd62d..d57e580e1 100644 --- a/Src/Orbiter/DlgCamera.cpp +++ b/Src/Orbiter/DlgCamera.cpp @@ -5,6 +5,7 @@ #include "Psys.h" #include "imgui.h" #include "imgui_extras.h" +#include "IconsFontAwesome6.h" extern PlanetarySystem *g_psys; extern Camera *g_camera; @@ -12,7 +13,7 @@ extern TimeData td; extern Orbiter *g_pOrbiter; extern Vessel *g_focusobj; -DlgCamera::DlgCamera() : ImGuiDialog("Orbiter: Camera", {512,359}) { +DlgCamera::DlgCamera() : ImGuiDialog(ICON_FA_VIDEO " Orbiter: Camera", {512,359}) { m_SelectedPreset = -1; } diff --git a/Src/Orbiter/DlgCapture.cpp b/Src/Orbiter/DlgCapture.cpp index 466bbe241..e3c7d34b9 100644 --- a/Src/Orbiter/DlgCapture.cpp +++ b/Src/Orbiter/DlgCapture.cpp @@ -7,6 +7,7 @@ #include "DlgCapture.h" #include "Orbiter.h" +#include "IconsFontAwesome6.h" extern Orbiter *g_pOrbiter; @@ -15,7 +16,7 @@ extern Orbiter *g_pOrbiter; #include "imgui.h" #include "imgui_extras.h" -DlgCapture::DlgCapture() : ImGuiDialog("Orbiter: Capture frames",{323,343}) { +DlgCapture::DlgCapture() : ImGuiDialog(ICON_FA_VOICEMAIL " Orbiter: Capture frames",{323,343}) { } void DlgCapture::OnDraw() { diff --git a/Src/Orbiter/DlgFocus.cpp b/Src/Orbiter/DlgFocus.cpp index fba754011..51a609f4d 100644 --- a/Src/Orbiter/DlgFocus.cpp +++ b/Src/Orbiter/DlgFocus.cpp @@ -12,13 +12,14 @@ #include "Camera.h" #include "imgui.h" #include +#include "IconsFontAwesome6.h" extern Camera *g_camera; extern PlanetarySystem *g_psys; extern Orbiter *g_pOrbiter; extern Vessel *g_focusobj, *g_pfocusobj; -DlgFocus::DlgFocus() : ImGuiDialog("Orbiter: Select spacecraft", {300, 320}) { +DlgFocus::DlgFocus() : ImGuiDialog(ICON_FA_ROCKET " Orbiter: Select spacecraft", {300, 320}) { } void DlgFocus::OnDraw() { diff --git a/Src/Orbiter/DlgFunction.cpp b/Src/Orbiter/DlgFunction.cpp index 1e6ff5d68..29e692508 100644 --- a/Src/Orbiter/DlgFunction.cpp +++ b/Src/Orbiter/DlgFunction.cpp @@ -8,10 +8,11 @@ #include "DlgFunction.h" #include "Orbiter.h" #include "imgui.h" +#include "IconsFontAwesome6.h" extern Orbiter *g_pOrbiter; -DlgFunction::DlgFunction() : ImGuiDialog("Orbiter: Custom functions", {340, 290}) { +DlgFunction::DlgFunction() : ImGuiDialog(ICON_FA_PUZZLE_PIECE " Orbiter: Custom functions", {340, 290}) { } void DlgFunction::OnDraw() { diff --git a/Src/Orbiter/DlgInfo.cpp b/Src/Orbiter/DlgInfo.cpp index 7b1000be9..ff4c1cb34 100644 --- a/Src/Orbiter/DlgInfo.cpp +++ b/Src/Orbiter/DlgInfo.cpp @@ -10,10 +10,11 @@ #include "Astro.h" #include "Element.h" #include "imgui.h" +#include "IconsFontAwesome6.h" extern PlanetarySystem *g_psys; -DlgInfo::DlgInfo() : ImGuiDialog("Orbiter: Object info", {753,423}) { +DlgInfo::DlgInfo() : ImGuiDialog(ICON_FA_CIRCLE_INFO " Orbiter: Object info", {753,423}) { } void DlgInfo::AddCbodyNode(const CelestialBody *cbody) { diff --git a/Src/Orbiter/DlgMap.cpp b/Src/Orbiter/DlgMap.cpp index 4204290c3..797fb6631 100644 --- a/Src/Orbiter/DlgMap.cpp +++ b/Src/Orbiter/DlgMap.cpp @@ -4,502 +4,110 @@ // ====================================================================== // "Map" dialog // ====================================================================== - -#define STRICT 1 - -#include #include "DlgMap.h" -#include "Dialogs.h" #include "Orbiter.h" #include "Psys.h" -#include "Planet.h" -#include "Resource.h" -#include "DlgMgr.h" // to be removed -#include "Pane.h" -#include "Util.h" - -using std::min; -using std::max; +#include "Celbody.h" +#include "Psys.h" +#include "imgui.h" +#include "IconsFontAwesome6.h" +#include "DlgInfo.h" -extern Orbiter *g_pOrbiter; extern TimeData td; -extern Vessel *g_focusobj; -extern PlanetarySystem *g_psys; -extern HELPCONTEXT DefHelpContext; -extern char DBG_MSG[256]; - -static int count = 0; - -inline bool GetMapPos (double lng, double lat, int &x, int &y); - -MapWin *MapWin::map_in_creation = 0; - -// ====================================================================== - -MapWin::MapWin (DlgMap *pDlg): VectorMap () -{ - dlg = pDlg; - hWnd = NULL; - bPaintPending = false; - bForceUpdate = false; - bDragActive = false; - storeflag = dispflag; - mousemode = MOUSE_DRAG; - RegisterWindow (pDlg->GetHinst()); -} - -// ====================================================================== - -MapWin::~MapWin () -{ - UnregisterWindow (dlg->GetHinst()); -} - -// ====================================================================== - -void MapWin::RegisterWindow (HINSTANCE hInst) -{ - // Register map window class - WNDCLASS wndClass; - wndClass.style = CS_HREDRAW | CS_VREDRAW; - wndClass.lpfnWndProc = Map_WndProc; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = hInst; - wndClass.hIcon = NULL; - wndClass.hCursor = NULL; - wndClass.hbrBackground = NULL; - wndClass.lpszMenuName = NULL; - wndClass.lpszClassName = "MapWindow"; - RegisterClass (&wndClass); -} - -// ====================================================================== - -void MapWin::UnregisterWindow (HINSTANCE hInst) -{ - UnregisterClass ("MapWindow", hInst); -} - -// ====================================================================== - -int MapWin::Create () -{ - DlgMap::MAP_PARAM *prm = &dlg->MapPrm; - font = CreateFont (-9, 0, 0, 0, 400, 0, 0, 0, 0, 3, 2, 1, 49, "Arial"); - pen[0] = CreatePen (PS_SOLID, 3, 0xffff00); - pen[1] = CreatePen (PS_SOLID, 1, 0xff0000); - - return 0; -} - -// ====================================================================== - -int MapWin::Destroy () -{ - int i; - - DeleteObject (font); - for (i = 0; i < 2; i++) DeleteObject (pen[i]); - return 0; -} - -// ====================================================================== - -void MapWin::PostCreation (HWND hw) -{ - hWnd = hw; - SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG_PTR)this); -} - -// ====================================================================== - -void MapWin::Update (bool force) -{ - const double updDT = 1.0; - static double updTmin = 0.0, updTmax = 0.0; - - if (!hWnd) return; - if (force) bForceUpdate = true; - -#ifdef ASYNC_DRAWMAP - // needs a rethink - if (!ThreadBusy()) { - bPaintPending = true; - InvalidateRect (hWnd, NULL, FALSE); - } - if (!bPaintPending && (bForceUpdate || td.SysT > updTmax || td.SysT < updTmin)) { - updTmax = td.SysT + updDT; - updTmin = td.SysT - updDT; - VectorMap::Update (); - AsyncDrawMap (); - bForceUpdate = false; - } -#else - if (bForceUpdate || td.SysT1 > updTmax || td.SysT1 < updTmin) { - updTmax = td.SysT1 + updDT; - updTmin = td.SysT1 - updDT; - VectorMap::Update (); - DrawMap(); - InvalidateRect(hWnd, NULL, FALSE); - bPaintPending = true; // ? - bForceUpdate = false; - } -#endif -} - -// ====================================================================== - -bool MapWin::SetCBody (const CelestialBody *body) -{ - bool redraw; - if (redraw = VectorMap::SetCBody (body)) { - for (int i = 0; i < mkrset.nset; i++) - mkrset.set[i].active = true; - if (hWnd) Update (true); - } - return redraw; -} - -// ====================================================================== - -int MapWin::Paint () -{ - HDC hDCtgt; - PAINTSTRUCT ps; - - hDCtgt = BeginPaint (hWnd, &ps); - if (bPaintPending) { - HDC hDCsrc = GetDeviceContext(); - HBITMAP pBmp = (HBITMAP)SelectObject (hDCsrc, GetMap()); - BitBlt (hDCtgt, 0, 0, cw, ch, hDCsrc, 0, 0, SRCCOPY); - SelectObject (hDCsrc, pBmp); - } - EndPaint (hWnd, &ps); - bPaintPending = false; - return 0; -} - -// ====================================================================== - -int MapWin::Size (DWORD w, DWORD h) -{ - HDC hDC = GetDC(NULL); - SetCanvas (hDC, w, h); - ReleaseDC (NULL, hDC); - Update (true); - return 0; -} - -// ====================================================================== - -void MapWin::Pan (int dx, int dy) -{ - double lng = lngc - dx/scalefac; - double lat = max (-Pi05, min (Pi05, latc + dy/scalefac)); - if (lng != lngc || lat != latc) { - SetCenter (lng, lat); - Update(true); - } -} - -// ====================================================================== -void MapWin::OnLButtonDown (int mx, int my) -{ - if (mousemode == MOUSE_DRAG) { - bDragActive = true; - mousex = mx; - mousey = my; - storeflag = GetDisplayFlags(); - SetDisplayFlags (storeflag & ~(DISP_NAVAID | DISP_CUSTOM1)); - Update(true); - } else { - FindTarget (mx, my); - } -} - -// ====================================================================== - -void MapWin::OnLButtonUp (int mx, int my) -{ - if (bDragActive) { - bDragActive = false; - SetDisplayFlags (storeflag); - dlg->prm_store.lngcnt = lngc; - dlg->prm_store.latcnt = latc; - Update(true); - } -} - -// ====================================================================== - -void MapWin::OnMouseMove (int mx, int my) -{ - if (GetForegroundWindow() == dlg->hWnd) SetFocus (hWnd); - SetCursor (LoadCursor (NULL, mousemode == MOUSE_DRAG ? IDC_HAND : IDC_CROSS)); - if (bDragActive) { - int dx = mx-mousex; - int dy = my-mousey; - mousex = mx; - mousey = my; - Pan (dx, dy); - } -} - -// ====================================================================== - -void MapWin::OnMouseWheel (int wdelta) -{ - if (!wdelta) return; // sanity check - double zscale; - if (wdelta > 0) - zscale = (double)wdelta/(double)WHEEL_DELTA*2.0; - else - zscale = -(double)WHEEL_DELTA/(double)wdelta*0.5; - int z = (int)(ZoomFac() * zscale + 0.5); - dlg->SetZoom (z); -} - -// ====================================================================== - -void MapWin::SetMouseMode (MouseMode mode) -{ - mousemode = mode; -} - -// ====================================================================== - -bool MapWin::FindTarget (int mx, int my) -{ - const OBJTYPE obj = FindObject (mx, my); - if (obj.type) { - SetSelection (obj); - dlg->EchoSelection (obj); - } - dlg->EnableInfo (obj.type == DISP_BASE || obj.type == DISP_VESSEL || obj.type == DISP_MOON); - - Update (true); - return (obj.type != 0); -} - -// ====================================================================== - -MapWin *MapWin::GetMapInstance (HWND hw) -{ - MapWin *map = (MapWin*)GetWindowLongPtr (hw, GWLP_USERDATA); - if (!map) map = map_in_creation; - return map; -} - -// ====================================================================== - -LRESULT FAR PASCAL MapWin::Map_WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_CREATE: - return GetMapInstance (hWnd)->Create (); - case WM_DESTROY: - return GetMapInstance (hWnd)->Destroy (); - case WM_SIZE: - return GetMapInstance (hWnd)->Size (LOWORD(lParam), HIWORD(lParam)); - case WM_PAINT: - return GetMapInstance (hWnd)->Paint (); - //case WM_LBUTTONDBLCLK: - // return GetMapInstance (hWnd)->GetInfo (LOWORD(lParam), HIWORD(lParam)); - case WM_LBUTTONDOWN: - SetCapture (hWnd); - GetMapInstance(hWnd)->OnLButtonDown (LOWORD(lParam), HIWORD(lParam)); - return 0; - case WM_LBUTTONUP: - ReleaseCapture(); - GetMapInstance(hWnd)->OnLButtonUp (LOWORD(lParam), HIWORD(lParam)); - return 0; - case WM_MOUSEMOVE: - GetMapInstance(hWnd)->OnMouseMove (LOWORD(lParam), HIWORD(lParam)); - return 0; - case WM_MOUSEWHEEL: - GetMapInstance(hWnd)->OnMouseWheel (GET_WHEEL_DELTA_WPARAM(wParam)); - return 0; - } - return DefWindowProc (hWnd, uMsg, wParam, lParam); -} - -// ====================================================================== -// ====================================================================== - -const int nbtl = 1; -const int btlid[nbtl] = {IDC_MAP_TRACK}; -const int nbtr = 4; -const int btrid[nbtr] = {IDC_MAP_INFO, IDC_MAP_OPTIONS, IDCANCEL, IDHELP}; +extern PlanetarySystem *g_psys; -DlgMap::MapPrmPersist DlgMap::prm_store = { NULL }; +DlgMap::DlgMap() : ImGuiDialog(ICON_FA_GLOBE " Orbiter: Map", {640, 400}) { + planet = "Select..."; + enableInfo = false; + searchbuf[0] = '\0'; + selectionfilter = DISP_MOON | DISP_VESSEL | DISP_BASE; -DlgMap::DlgMap (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_MAP, 0, 0, context) -{ - map = new MapWin (this); prm = &g_pOrbiter->Cfg()->CfgMapPrm; - pos = &g_pOrbiter->Cfg()->CfgWindowPos.DlgMap; - memset (&MapPrm, 0, sizeof(MAP_PARAM)); -} - -// ====================================================================== - -DlgMap::~DlgMap () -{ - prm_store.sel = map->GetSelection(); - prm_store.track = (map->GetCenterMode() != 0); - delete map; -} - -// ====================================================================== - -void DlgMap::GlobalInit () -{ - prm_store.cbody = NULL; - prm_store.sel.obj = NULL; - prm_store.sel.type = 0; - prm_store.zoom = 1; - prm_store.lngcnt = 0.0; - prm_store.latcnt = 0.0; - prm_store.track = false; } - -#ifdef UNDEF -// ====================================================================== - -HWND DlgMap::Open () -{ - DialogManager *dlgmgr = g_pOrbiter->DlgMgr(); - if (!dlgmgr) return 0; - HINSTANCE hInst = g_pOrbiter->GetInstance(); - HWND hParent = g_pOrbiter->GetRenderWnd(); - if (dlgmgr->IsEntry (hInst, IDD_MAP)) return 0; // already open - DlgMap *dlg = new DlgMap (hInst, hParent); - return dlgmgr->AddEntry (dlg); -} -#endif - -// ====================================================================== - -HWND DlgMap::OpenWindow () -{ - MapWin::map_in_creation = map; - HWND hw = DialogWin::OpenWindow (); - HWND hMap = GetDlgItem (hw, IDC_MAP); - map->PostCreation (hMap); - MapWin::map_in_creation = 0; - return hw; -} - -// ====================================================================== - -void DlgMap::Update () -{ - map->Update(); -} - -// ====================================================================== - -void DlgMap::VesselDeleting (Vessel *v) -{ - if (v == map->GetSelection().obj) { - VectorMap::OBJTYPE nullobj = {NULL,0}; - EchoSelection (nullobj); - map->UnsetSelection(); - } -} - -// ====================================================================== - -void DlgMap::SetCBody (CelestialBody *cbody) -{ - if (cbody != prm_store.cbody) { - prm_store.cbody = cbody; - map->SetCBody (cbody); - VectorMap::OBJTYPE nullobj = {NULL,0}; - EchoSelection (nullobj); - } -} - -// ====================================================================== - -void DlgMap::SetPlanet (const char *name) -{ - CelestialBody *cbody = g_psys->GetGravObj (name, true); - if (cbody != prm_store.cbody) { - prm_store.cbody = cbody; - map->SetCBody (cbody); - } -} - -// ====================================================================== - -void DlgMap::EchoSelection (const VectorMap::OBJTYPE &obj) -{ - HWND hNameBox = GetDlgItem (hWnd, IDC_MAP_FINDNAME); - switch (obj.type) { - case DISP_VESSEL: - case DISP_BASE: - case DISP_MOON: - SetWindowText (hNameBox, ((Body*)obj.obj)->Name()); - break; - case DISP_NAVAID: - SetWindowText (hNameBox, ((Nav*)obj.obj)->GetId()); - break; - default: - SetWindowText (hNameBox, ""); - break; - } -} - -// ====================================================================== - -void DlgMap::SetSelection (const Body *body) -{ - const CelestialBody *ref; - VectorMap::OBJTYPE sel; - sel.obj = body; - switch (body->Type()) { - case OBJTP_VESSEL: - sel.type = DISP_VESSEL; - ref = ((Vessel*)body)->ElRef(); - break; - case OBJTP_PLANET: - sel.type = DISP_MOON; - ref = ((CelestialBody*)body)->ElRef(); - break; - case OBJTP_STAR: - // Only way for this is to select the target as the cbody, and drop the selection - ref = (const CelestialBody*)body; - sel.obj = NULL; - sel.type = 0; - break; - case OBJTP_SURFBASE: - sel.type = DISP_BASE; - ref = ((Base*)body)->RefPlanet(); - break; - } - const CelestialBody *cbody = GetMapWin()->GetCBody(); - if (cbody != ref) { - GetMapWin()->SetCBody(ref); - CBodySelectComboBox::BuildListFromNode (GetHwnd(), IDC_MAP_REFERENCE, ref); - } - SetSelection (sel); -} - -// ====================================================================== - -void DlgMap::SetSelection (const VectorMap::OBJTYPE &obj) -{ - if (map->SetSelection (obj)) - EchoSelection (obj); -} - -// ====================================================================== - -bool DlgMap::SetSelection (const char *name, int type) +void DlgMap::Display() { + ImGui::SetNextWindowSize(ImVec2(defaultSize.width, defaultSize.height), ImGuiCond_FirstUseEver); + + bool visible = ImGui::Begin(name.c_str(), &active); + if(ImGui::MenuButton(ICON_FA_ARROW_ROTATE_LEFT, "Reset map")) { + Reset(); + } + + if(visible) { + OnDraw(); + } + ImGui::End(); + if (!active) OnClose(); +} + +void DlgMap::Reset() +{ + zoom=1.0; + vectormap->SetZoom(zoom); + vectormap->SetCenter(0.0,0.0); + vectormap->UnsetSelection(); + vectormap->Update(); + vectormap->DrawMap (); + searchbuf[0] = '\0'; + enableInfo = false; + selectionfilter = DISP_MOON | DISP_VESSEL | DISP_BASE; +} + +void DlgMap::AddCbodyNode(const CelestialBody *cbody) { + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth; + const bool is_selected = planet == cbody->Name(); + if (is_selected) + node_flags |= ImGuiTreeNodeFlags_Selected; + + if(cbody->nSecondary()) { + if(!strcmp(cbody->Name(), "Sun")) + node_flags|=ImGuiTreeNodeFlags_DefaultOpen; + + bool node_open = ImGui::TreeNodeEx(cbody->Name(), node_flags); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) { + planet = cbody->Name(); + SetBody(cbody->Name()); + ImGui::CloseCurrentPopup(); + } + if(node_open) { + for (int i = 0; i < cbody->nSecondary(); i++) { + AddCbodyNode (cbody->Secondary(i)); + } + ImGui::TreePop(); + } + } else { + ImGui::TreeNodeEx(cbody->Name(), node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) { + planet = cbody->Name(); + SetBody(cbody->Name()); + ImGui::CloseCurrentPopup(); + } + } +} + +void DlgMap::DrawTree() { + for (int i = 0; i < g_psys->nStar(); i++) + AddCbodyNode (g_psys->GetStar(i)); +} + + +void DlgMap::SetBody(const char *body) { + planet = body; + if(vectormap) { + Planet *b = g_psys->GetPlanet (body); + if(b) { + vectormap->SetCBody(b); + vectormap->Update(); + vectormap->DrawMap (); + + for (int i = 0; i < vectormap->GetCustomMarkerSet().nset; i++) + vectormap->GetCustomMarkerSet().set[i].active = true; + + } + } +} + +bool DlgMap::SetSelection(const char *name) { if (!name[0]) return false; // sanity check @@ -510,7 +118,7 @@ bool DlgMap::SetSelection (const char *name, int type) VectorMap::OBJTYPE sel; bool found_exact = false; - if ((type == 1 || type == 0) && map->GetDisplayFlags() & DISP_VESSEL) { // search for vessel + if ((selectionfilter & DISP_VESSEL) && (vectormap->GetDisplayFlags() & DISP_VESSEL)) { // search for vessel for (i = 0; i < g_psys->nVessel(); i++) { Vessel *v = g_psys->GetVessel(i); if (!_strnicmp (v->Name(), name, len)) { @@ -524,8 +132,8 @@ bool DlgMap::SetSelection (const char *name, int type) } } } - if ((type == 2 || type == 0) && map->GetDisplayFlags() & DISP_BASE) { // search for bases - const Planet *planet = map->GetPlanet(); + if ((selectionfilter & DISP_BASE) && (vectormap->GetDisplayFlags() & DISP_BASE)) { // search for bases + const Planet *planet = vectormap->GetPlanet(); if (planet) { for (i = 0; i < planet->nBase(); i++) { const Base *base = planet->GetBase(i); @@ -541,8 +149,8 @@ bool DlgMap::SetSelection (const char *name, int type) } } } - if ((type == 3 || type == 0) && map->GetDisplayFlags() & DISP_NAVAID) { // search for VOR transmitters - const Planet *planet = map->GetPlanet(); + if ((selectionfilter & DISP_NAVAID) && vectormap->GetDisplayFlags() & DISP_NAVAID) { // search for VOR transmitters + const Planet *planet = vectormap->GetPlanet(); if (planet) { for (i = 0; i < planet->nNav(); i++) { const Nav *nav = planet->NavMgr().GetNav(i); @@ -561,9 +169,9 @@ bool DlgMap::SetSelection (const char *name, int type) } } } - if ((type == 5 || type == 0) && map->GetDisplayFlags() & DISP_MOON) { // search for moons - for (i = 0; i < map->GetCBody()->nSecondary(); i++) { - const CelestialBody *moon = map->GetCBody()->Secondary (i); + if ((selectionfilter & DISP_MOON) && vectormap->GetDisplayFlags() & DISP_MOON) { // search for moons + for (i = 0; i < vectormap->GetCBody()->nSecondary(); i++) { + const CelestialBody *moon = vectormap->GetCBody()->Secondary (i); if (!_strnicmp (moon->Name(), name, len)) { if (nhit < maxhit) hitstr[nhit] = moon->Name(); nhit++; @@ -576,397 +184,269 @@ bool DlgMap::SetSelection (const char *name, int type) } } - SendDlgItemMessage (hWnd, IDC_MAP_FINDNAME, CB_RESETCONTENT, 0, 0); - if (found_exact) { - map->SetSelection (sel); - SendDlgItemMessage (hWnd, IDC_MAP_FINDNAME, CB_ADDSTRING, 0, (LPARAM)name); - SendDlgItemMessage (hWnd, IDC_MAP_FINDNAME, CB_SHOWDROPDOWN, FALSE, 0); - SendDlgItemMessage (hWnd, IDC_MAP_FINDNAME, CB_SETCURSEL, 0, 0); - EnableInfo (sel.type == DISP_BASE || sel.type == DISP_VESSEL || sel.type == DISP_MOON); - } else { - if (nhit <= maxhit) { - for (i = 0; i < nhit; i++) - SendDlgItemMessage (hWnd, IDC_MAP_FINDNAME, CB_ADDSTRING, 0, (LPARAM)hitstr[i]); - SendDlgItemMessage (hWnd, IDC_MAP_FINDNAME, CB_SHOWDROPDOWN, nhit > 0 ? TRUE:FALSE, 0); - } - SetWindowText (GetDlgItem (hWnd, IDC_MAP_FINDNAME), name); + vectormap->SetSelection (sel); + enableInfo = (sel.type == DISP_BASE || sel.type == DISP_VESSEL || sel.type == DISP_MOON); } - SendDlgItemMessage (hWnd, IDC_MAP_FINDNAME, CB_SETEDITSEL, 0, MAKELPARAM(len,len)); - SendMessage (GetDlgItem (hWnd, IDC_MAP_FINDNAME), WM_SETCURSOR, 0, 0); return found_exact; } -// ====================================================================== - -void DlgMap::ToggleDispFlags (DWORD dflag) -{ - SetDispFlags (prm->DispFlag ^ dflag); -} - -// ====================================================================== - -void DlgMap::SetDispFlags (DWORD flag) -{ - prm->DispFlag = flag; - map->SetDisplayFlags (prm->DispFlag); - map->Update (true); -} - -// ====================================================================== - -void DlgMap::SetDragMode (bool drag) -{ - map->SetMouseMode (drag ? MapWin::MOUSE_DRAG : MapWin::MOUSE_SELECT); -} - -// ====================================================================== - -void DlgMap::EnableInfo (bool enable) -{ - EnableWindow (GetDlgItem (hWnd, IDC_MAP_INFO), enable ? 1:0); -} - -// ====================================================================== - -void DlgMap::OpenInfo () -{ - VectorMap::OBJTYPE obj = map->GetSelection (); - if (obj.type == DISP_BASE || obj.type == DISP_VESSEL || obj.type == DISP_MOON) { - DlgInfo *pInfo = g_pOrbiter->DlgMgr()->EnsureEntry (); - pInfo->SetBody ((Body*)obj.obj); - } -} - -// ====================================================================== - -BOOL DlgMap::OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam) +bool DlgMap::FindTarget(int mx, int my) { - int i; - RECT rect; - char cbuf[64]; - - SendDlgItemMessage (hDlg, IDC_MAP_SELECT, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIcon (g_pOrbiter->GetInstance(), MAKEINTRESOURCE(IDI_CROSS))); - SendDlgItemMessage (hDlg, IDC_MAP_DRAG, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIcon (g_pOrbiter->GetInstance(), MAKEINTRESOURCE(IDI_FINGER))); - SendDlgItemMessage (hDlg, IDC_MAP_DRAG, BM_SETCHECK, BST_CHECKED, 0); - map->SetZoom (prm_store.zoom); - sprintf (cbuf, "Zoom %dx", prm_store.zoom); - SetWindowText (GetDlgItem (hDlg, IDC_MAP_ZOOMBOX), cbuf); - map->SetDisplayFlags (prm->DispFlag); - GetClientRect (hDlg, &rect); - MapPrm.dlgw = rect.right, MapPrm.dlgh = rect.bottom; - GetWindowRect (GetDlgItem (hDlg, IDC_MAP), &rect); - MapPrm.mapw = rect.right-rect.left, MapPrm.maph = rect.bottom-rect.top; - for (i = 0; i < nbtl; i++) { - GetWindowRect (GetDlgItem (hDlg, btlid[i]), &rect); - MapPrm.btlp[i].x = rect.left, MapPrm.btlp[i].y = rect.top; - ScreenToClient (hDlg, &MapPrm.btlp[i]); - } - for (i = 0; i < nbtr; i++) { - GetWindowRect (GetDlgItem (hDlg, btrid[i]), &rect); - MapPrm.btrp[i].x = rect.left, MapPrm.btrp[i].y = rect.top; - ScreenToClient (hDlg, &MapPrm.btrp[i]); - } + const VectorMap::OBJTYPE obj = vectormap->FindObject(mx, my); + if(obj.type) { + vectormap->SetSelection (obj); + enableInfo = (obj.type == DISP_BASE || obj.type == DISP_VESSEL || obj.type == DISP_MOON); - if (!prm_store.cbody) prm_store.cbody = g_focusobj->ProxyPlanet(); - CBodySelectComboBox::BuildListFromNode (hDlg, IDC_MAP_REFERENCE, prm_store.cbody); - map->SetCBody (prm_store.cbody); - map->SetCenter (prm_store.lngcnt, prm_store.latcnt); - if (map->SetSelection (prm_store.sel)) - EchoSelection (prm_store.sel); - if (prm_store.track) { - SendDlgItemMessage (hDlg, IDC_MAP_TRACK, BM_SETCHECK, BST_CHECKED, 0); - map->SetCenterMode (2); + switch (obj.type) { + case DISP_VESSEL: + case DISP_BASE: + case DISP_MOON: + strcpy(searchbuf, ((Body*)obj.obj)->Name()); + break; + case DISP_NAVAID: + strcpy(searchbuf, ((Nav*)obj.obj)->GetId()); + break; + default: + strcpy (searchbuf, ""); + break; + } } - SendDlgItemMessage (hDlg, IDC_MAP_FINDTYPE, CB_RESETCONTENT, 0, 0); - const char *tpstr[6] = {"Any", "Vessel", "Base", "VOR", "Marker", "Moons"}; - for (i = 0; i < 6; i++) - SendDlgItemMessage (hDlg, IDC_MAP_FINDTYPE, CB_ADDSTRING, 0, (LPARAM)tpstr[i]); - SendDlgItemMessage (hDlg, IDC_MAP_FINDTYPE, CB_SETCURSEL, 0, 0); - - return TRUE; -} - -// ====================================================================== - -BOOL DlgMap::OnSize (HWND hDlg, WPARAM wParam, int w, int h) -{ - RECT rect; - int i, dx, dy; - - GetClientRect (hWnd, &rect); - dx = rect.right - MapPrm.dlgw, dy = rect.bottom - MapPrm.dlgh; - SetWindowPos (GetDlgItem (hWnd, IDC_MAP), HWND_TOP, 0, 0, MapPrm.mapw+dx, MapPrm.maph+dy, SWP_NOMOVE); - for (i = 0; i < nbtr; i++) ShowWindow (GetDlgItem (hWnd, btrid[i]), SW_HIDE); - for (i = 0; i < nbtr; i++) - SetWindowPos (GetDlgItem (hWnd, btrid[i]), HWND_TOP, MapPrm.btrp[i].x+dx, MapPrm.btrp[i].y+dy, 0, 0, SWP_NOSIZE); - for (i = 0; i < nbtr; i++) ShowWindow (GetDlgItem (hWnd, btrid[i]), SW_SHOW); - for (i = 0; i < nbtl; i++) - SetWindowPos (GetDlgItem (hWnd, btlid[i]), HWND_TOP, MapPrm.btlp[i].x, MapPrm.btlp[i].y+dy, 0, 0, SWP_NOSIZE); - return DialogWin::OnSize (hDlg, wParam, w, h); + return (obj.type != 0); } -// ====================================================================== - -BOOL DlgMap::OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl) -{ - char cbuf[1024]; - int i; - - switch (id) { - case IDHELP: - DefHelpContext.topic = (char*)"/map.htm"; - g_pOrbiter->OpenHelp (&DefHelpContext); - return TRUE; - case IDC_MAP_OPTIONS: - g_pOrbiter->DlgMgr()->EnsureEntry (0, this); - return TRUE; - case IDC_MAP_INFO: - OpenInfo(); - return TRUE; - case IDC_MAP_REFERENCE: - if (code == CBN_SELCHANGE) { - CelestialBody *cbody = CBodySelectComboBox::OnSelectionChanged (hDlg, IDC_MAP_REFERENCE); - if (cbody) SetCBody (cbody); - } - break; - case IDC_MAP_FINDTYPE: - if (code == CBN_SELCHANGE) { - SetFindMask (); - } - break; - case IDC_MAP_FINDNAME: - if (code == CBN_EDITCHANGE) { - GetWindowText (GetDlgItem (hDlg, IDC_MAP_FINDNAME), cbuf, 256); - i = SendDlgItemMessage (hDlg, IDC_MAP_FINDTYPE, CB_GETCURSEL, 0, 0); - SetSelection (cbuf, i); - } else if (code == CBN_SELCHANGE) { - i = SendDlgItemMessage (hDlg, IDC_MAP_FINDNAME, CB_GETCURSEL, 0, 0); - if (i != CB_ERR) { - SendDlgItemMessage (hDlg, IDC_MAP_FINDNAME, CB_GETLBTEXT, i, (LPARAM)cbuf); - i = SendDlgItemMessage (hDlg, IDC_MAP_FINDTYPE, CB_GETCURSEL, 0, 0); - SetSelection (cbuf, i); +void DlgMap::DrawMap() { + ImVec2 sz = ImGui::GetContentRegionAvail(); + if(sz.x>=1.0f && sz.y >= 1.0f) { + static ImVec2 oldsz = sz;//ImVec2(512,256); + + if(!vectormap) { + Planet *earth = g_psys->GetPlanet ("Earth"); + if(earth) { + planet = "Earth"; + vectormap=std::make_unique(earth); + vectormap->SetCBody(earth); + vectormap->SetCanvas(nullptr, sz.x, sz.y); + vectormap->SetDisplayFlags(prm->DispFlag); + + SetBody("Earth"); + } + } + + if(sz.x != oldsz.x || sz.y != oldsz.y) { + vectormap->SetCanvas(nullptr, sz.x, sz.y); + + vectormap->Update(); + vectormap->DrawMap (); + + oldsz = sz; + } + + const double updDT = 1.0; + if (td.SysT1 > updTmax || td.SysT1 < updTmin) { + updTmax = td.SysT1 + updDT; + updTmin = td.SysT1 - updDT; + + vectormap->Update(); + vectormap->DrawMap (); + } + + ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left + ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right + ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint + ImVec4 border_col = ImVec4(0.0f, 0.0f, 0.0f, 0.0f); // 50% opaque white + + ImTextureID map = oapiGetImTextureID(vectormap->GetMap()); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); + ImGui::ImageButton("##VectorMap", map, ImVec2(sz.x, sz.y), uv_min, uv_max, border_col, tint_col); + ImGui::PopStyleVar(); + + ImGuiIO& io = ImGui::GetIO(); + bool updateMap = false; + if (ImGui::IsItemHovered() && io.MouseWheel != 0.0) { + zoom+=io.MouseWheel; + if(zoom<1.0) zoom=1.0; + + vectormap->SetZoom(zoom); + updateMap = true; + } + if (ImGui::IsItemActive()) { + if(ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { + ImVec2 mousepos = ImGui::GetMousePos(); + ImVec2 imagepos = ImGui::GetItemRectMin(); + if(FindTarget(mousepos.x-imagepos.x, mousepos.y-imagepos.y)) + updateMap = true; + } else { + double lngc = vectormap->CntLng(); + double latc = vectormap->CntLat(); + + double scale = std::min (sz.x, 2.0f*sz.y); + double scalefac = vectormap->ZoomFac()*scale/Pi2; + + double lng = lngc - io.MouseDelta.x/scalefac; + double lat = std::max (-Pi05, std::min (Pi05, latc + io.MouseDelta.y/scalefac)); + if (lng != lngc || lat != latc) { + vectormap->SetCenter (lng, lat); + updateMap = true; + } } - } else if (code == CBN_SELENDCANCEL) { - i = SendDlgItemMessage (hDlg, IDC_MAP_FINDNAME, CB_GETCURSEL, 0, 0); - if (i == CB_ERR) return 0; + } + + if(updateMap) { + vectormap->Update(); + vectormap->DrawMap (); + } + } +} + +void DlgMap::DrawMenu() { + ImGui::SetNextItemWidth(160.0f); + if(ImGui::BeginCombo("##dlgmap_planet", planet.c_str(), ImGuiComboFlags_HeightLargest)) { + DrawTree(); + ImGui::EndCombo(); + } + + ImGui::SameLine(); + + ImGui::SetNextItemWidth(160.0f); + if(ImGui::BeginCombo("##dlgmap_options", "Options", ImGuiComboFlags_HeightLargest)) { + int df = vectormap->GetDisplayFlags(); + int olddf = df; + + ImGui::Text("Vessels"); + int vesselmode = (df & DISP_VESSEL ? df & DISP_FOCUSONLY ? 1:0:2); + ImGui::RadioButton("All", &vesselmode, 0); ImGui::SameLine(); + ImGui::RadioButton("Focus Only", &vesselmode, 1); ImGui::SameLine(); + ImGui::RadioButton("None", &vesselmode, 2); + ImGui::Separator(); + int vmode = (vesselmode==1 ? DISP_VESSEL | DISP_FOCUSONLY : vesselmode==2 ? 0 : DISP_VESSEL); + df &= ~(DISP_VESSEL | DISP_FOCUSONLY); + df |= vmode; + + ImGui::Text("Orbit Display"); + if (ImGui::BeginTable("table orbit display", 2, ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::CheckboxFlags("Focus Vessel", &df, DISP_ORBITFOCUS); + ImGui::TableSetColumnIndex(1); + ImGui::CheckboxFlags("Target", &df, DISP_ORBITSEL); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + int orbitmode=(df & DISP_ORBITPLANE) ? 0 : 1; + ImGui::RadioButton("Orbit Plane", &orbitmode, 0); + ImGui::TableSetColumnIndex(1); + ImGui::RadioButton("Ground Track", &orbitmode, 1); + df &= ~(DISP_GROUNDTRACK | DISP_ORBITPLANE); + df |= (orbitmode == 0)? DISP_ORBITPLANE:DISP_GROUNDTRACK; + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::CheckboxFlags("Horizon Line", &df, DISP_HORIZONLINE); + ImGui::EndTable(); + } + ImGui::Separator(); + + ImGui::Text("Terminator"); + if (ImGui::BeginTable("table1", 2, ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::CheckboxFlags("Line", &df, DISP_TERMINATOR_LINE); + ImGui::TableSetColumnIndex(1); + ImGui::CheckboxFlags("Shaded", &df, DISP_TERMINATOR_SHADE); + ImGui::EndTable(); + } + ImGui::Separator(); + + ImGui::Text("Surface Markers"); + if (ImGui::BeginTable("table2", 2, ImGuiTableFlags_SizingStretchSame)) { + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::CheckboxFlags("Grid Line", &df, DISP_GRIDLINE); + ImGui::TableSetColumnIndex(1); + ImGui::CheckboxFlags("Surface Bases", &df, DISP_BASE); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::CheckboxFlags("Coastlines", &df, DISP_COASTLINE); + ImGui::TableSetColumnIndex(1); + ImGui::CheckboxFlags("VOR Transmitters", &df, DISP_NAVAID); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::CheckboxFlags("Contour Lines", &df,DISP_CONTOURS); + ImGui::TableSetColumnIndex(1); + ImGui::CheckboxFlags("Landmarks", &df, DISP_CUSTOMMARKER); + + ImGui::EndTable(); + } + ImGui::Separator(); + + ImGui::Text("Other"); + ImGui::CheckboxFlags("Natural Satellites", &df, DISP_MOON); + + ImGui::EndCombo(); + + vectormap->SetDisplayFlags(df); + + if(df!=olddf) { + vectormap->Update(); + vectormap->DrawMap (); + prm->DispFlag = df; } - break; - case IDC_MAP_TRACK: - if (code == BN_CLICKED) { - bool track = (SendDlgItemMessage (hDlg, IDC_MAP_TRACK, BM_GETCHECK, 0, 0) == BST_CHECKED); - map->SetCenterMode (track ? 2:0); - } - return TRUE; - case IDC_MAP_DRAG: - case IDC_MAP_SELECT: - if (code == BN_CLICKED) - SetDragMode (id == IDC_MAP_DRAG); - return TRUE; - } - return DialogWin::OnCommand (hDlg, id, code, hControl); -} - -// ====================================================================== - -BOOL DlgMap::OnNotify (HWND hWnd, int idCtrl, LPNMHDR pnmh) -{ - if (pnmh->code == UDN_DELTAPOS) { - NMUPDOWN *nmud = (NMUPDOWN*)pnmh; - switch (pnmh->idFrom) { - case IDC_MAP_ZOOM: - if (nmud->iDelta < 0) ZoomIn(); - else ZoomOut(); - break; + } + + ImGui::SameLine(); + + if(ImGui::Button(ICON_FA_FILTER)) { + ImGui::OpenPopup("dlgmap_search_filter"); + } + ImVec2 btn_pos = ImGui::GetItemRectMin(); + btn_pos.x-=4; + btn_pos.y-=5; + ImGui::SetNextWindowPos(btn_pos); + + if (ImGui::BeginPopup("dlgmap_search_filter")) + { + ImGui::Text(ICON_FA_FILTER " Search filter"); + ImGui::Separator(); + + ImGui::CheckboxFlags("Moons", &selectionfilter, DISP_MOON); + ImGui::CheckboxFlags("Vessels", &selectionfilter, DISP_VESSEL); + ImGui::CheckboxFlags("VOR", &selectionfilter, DISP_NAVAID); + ImGui::CheckboxFlags("Landmarks", &selectionfilter, DISP_CUSTOMMARKER); + ImGui::CheckboxFlags("Bases", &selectionfilter, DISP_BASE); + + ImGui::EndPopup(); + } + + ImGui::SameLine(); + ImGui::SetNextItemWidth(160); + if(ImGui::InputText("##search", searchbuf, sizeof(searchbuf), ImGuiInputTextFlags_EnterReturnsTrue)) { + SetSelection(searchbuf); + } + ImGui::SameLine(); + if(ImGui::Button(ICON_FA_MAGNIFYING_GLASS)) { + SetSelection(searchbuf); + } + ImGui::SetItemTooltip("Search object"); + + ImGui::BeginDisabled(!enableInfo); + ImGui::SameLine(); + if(ImGui::Button(ICON_FA_CIRCLE_INFO)) { + VectorMap::OBJTYPE obj = vectormap->GetSelection (); + if (obj.type == DISP_BASE || obj.type == DISP_VESSEL || obj.type == DISP_MOON) { + DlgInfo *pInfo = g_pOrbiter->DlgMgr()->EnsureEntry (); + pInfo->SetBody ((Body*)obj.obj); } } - return DialogWin::OnNotify (hWnd, idCtrl, pnmh); -} - -// ====================================================================== - -BOOL DlgMap::OnUserMessage (HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - switch (wParam) { - case MSG_KILLVESSEL: - VesselDeleting ((Vessel*)lParam); - break; - } - return DialogWin::OnUserMessage (hWnd, wParam, lParam); -} - -// ====================================================================== - -BOOL DlgMap::OnMouseWheel (HWND hDlg, int vk, int dist, int x, int y) -{ - PostMessage (GetDlgItem (hDlg, IDC_MAP), WM_MOUSEWHEEL, MAKEWPARAM(vk,dist), MAKELPARAM(x,y)); - return 1; -} - -// ====================================================================== - -void DlgMap::SetZoom (int zoom) -{ - char cbuf[32]; - zoom = max(1, min (128, zoom)); - if (zoom != prm_store.zoom) { - map->SetZoom (zoom); - prm_store.zoom = zoom; - map->Update (true); - sprintf (cbuf, "Zoom %dx", zoom); - SetWindowText (GetDlgItem (hWnd, IDC_MAP_ZOOMBOX), cbuf); - InvalidateRect (GetDlgItem (hWnd, IDC_MAP), NULL, FALSE); - } -} - -// ====================================================================== - -void DlgMap::ZoomIn () -{ - SetZoom (prm_store.zoom*2); + if(enableInfo) + ImGui::SetItemTooltip("Open info dialog for object"); + ImGui::EndDisabled(); } -// ====================================================================== - -void DlgMap::ZoomOut () -{ - SetZoom (prm_store.zoom/2); -} - -// ====================================================================== - -void DlgMap::SetFindMask () -{ - DWORD mask; - int idx = SendDlgItemMessage (hWnd, IDC_MAP_FINDTYPE, CB_GETCURSEL, 0, 0); - switch (idx) { - case 0: mask = DISP_NAVAID | DISP_BASE | DISP_CUSTOM1 | DISP_VESSEL | DISP_MOON; break; - case 1: mask = DISP_VESSEL; break; - case 2: mask = DISP_BASE; break; - case 3: mask = DISP_NAVAID; break; - case 4: mask = DISP_CUSTOM1; break; - case 5: mask = DISP_MOON; break; - } - map->SetFindFlags (mask); -} - -// ====================================================================== -// ====================================================================== - -DlgMapOpt::DlgMapOpt (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_MAP_CONFIG, 0, 0, context) -{ - dlgmap = (DlgMap*)context; -} - -// ====================================================================== - -BOOL DlgMapOpt::OnInitDialog (HWND hDlg, WPARAM wParam, LPARAM lParam) -{ - DWORD dispflag = GetMapDlg()->GetMapWin()->GetDisplayFlags(); - SendDlgItemMessage (hDlg, IDC_MAPOPT_ORBITFOCUS, BM_SETCHECK, dispflag & DISP_ORBITFOCUS ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_ORBITSEL, BM_SETCHECK, dispflag & DISP_ORBITSEL ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_ORBITPLANE, BM_SETCHECK, dispflag & DISP_ORBITPLANE ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_ORBITGTRACK, BM_SETCHECK, dispflag & DISP_GROUNDTRACK ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_HORIZON, BM_SETCHECK, dispflag & DISP_HORIZONLINE ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_TLINE, BM_SETCHECK, dispflag & DISP_TERMINATOR_LINE ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_TSHADE, BM_SETCHECK, dispflag & DISP_TERMINATOR_SHADE ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_GRIDLINES, BM_SETCHECK, dispflag & DISP_GRIDLINE ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_COASTLINES, BM_SETCHECK, dispflag & DISP_COASTLINE ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_CONTOURS, BM_SETCHECK, dispflag & DISP_CONTOURS ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_BASES, BM_SETCHECK, dispflag & DISP_BASE ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_VORS, BM_SETCHECK, dispflag & DISP_NAVAID ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_LANDMARKS, BM_SETCHECK, dispflag & DISP_CUSTOM1 ? BST_CHECKED:BST_UNCHECKED, 0); - SendDlgItemMessage (hDlg, IDC_MAPOPT_SATELLITES, BM_SETCHECK, dispflag & DISP_MOON ? BST_CHECKED:BST_UNCHECKED, 0); - int i, vesselmode = (dispflag & DISP_VESSEL ? dispflag & DISP_FOCUSONLY ? 1:0:2); - const int modeid[3] = {IDC_MAPOPT_VESSELALL, IDC_MAPOPT_VESSELFOCUS, IDC_MAPOPT_VESSELNONE}; - for (i = 0; i < 3; i++) - SendDlgItemMessage (hDlg, modeid[i], BM_SETCHECK, i==vesselmode ? BST_CHECKED:BST_UNCHECKED, 0); - return 0; -} - -// ====================================================================== - -BOOL DlgMapOpt::OnCommand (HWND hDlg, WORD id, WORD code, HWND hControl) -{ - switch (id) { - case IDC_MAPOPT_VESSELALL: - case IDC_MAPOPT_VESSELFOCUS: - case IDC_MAPOPT_VESSELNONE: { - int i, vmode; - const int modeid[3] = {IDC_MAPOPT_VESSELALL, IDC_MAPOPT_VESSELFOCUS, IDC_MAPOPT_VESSELNONE}; - for (i = 0; i < 3; i++) - if (SendDlgItemMessage (hDlg, modeid[i], BM_GETCHECK, 0, 0) == BST_CHECKED) - break; - vmode = (i==1 ? DISP_VESSEL | DISP_FOCUSONLY : i==2 ? 0 : DISP_VESSEL); - SetVesselMode (vmode); - } return TRUE; - case IDC_MAPOPT_ORBITFOCUS: - ToggleDispFlag (DISP_ORBITFOCUS); - return TRUE; - case IDC_MAPOPT_ORBITSEL: - ToggleDispFlag (DISP_ORBITSEL); - return TRUE; - case IDC_MAPOPT_ORBITPLANE: - case IDC_MAPOPT_ORBITGTRACK: - SetOrbitMode (SendDlgItemMessage (hDlg, IDC_MAPOPT_ORBITPLANE, BM_GETCHECK, 0, 0) == BST_CHECKED ? DISP_ORBITPLANE : DISP_GROUNDTRACK); - return TRUE; - case IDC_MAPOPT_HORIZON: - ToggleDispFlag (DISP_HORIZONLINE); - return TRUE; - case IDC_MAPOPT_TLINE: - ToggleDispFlag (DISP_TERMINATOR_LINE); - return TRUE; - case IDC_MAPOPT_TSHADE: - ToggleDispFlag (DISP_TERMINATOR_SHADE); - return TRUE; - case IDC_MAPOPT_GRIDLINES: - ToggleDispFlag (DISP_GRIDLINE); - return TRUE; - case IDC_MAPOPT_COASTLINES: - ToggleDispFlag (DISP_COASTLINE); - return TRUE; - case IDC_MAPOPT_CONTOURS: - ToggleDispFlag (DISP_CONTOURS); - return TRUE; - case IDC_MAPOPT_BASES: - ToggleDispFlag (DISP_BASE); - return TRUE; - case IDC_MAPOPT_VORS: - ToggleDispFlag (DISP_NAVAID); - return TRUE; - case IDC_MAPOPT_LANDMARKS: - ToggleDispFlag (DISP_CUSTOM1); - return TRUE; - case IDC_MAPOPT_SATELLITES: - ToggleDispFlag (DISP_MOON); - return TRUE; - } - return DialogWin::OnCommand (hDlg, id, code, hControl); -} - -// ====================================================================== - -void DlgMapOpt::ToggleDispFlag (DWORD flag) -{ - dlgmap->ToggleDispFlags (flag); -} - -// ====================================================================== - -void DlgMapOpt::SetOrbitMode (DWORD flag) -{ - DWORD dflag = dlgmap->GetMapWin()->GetDisplayFlags(); - dflag &= ~(DISP_ORBITPLANE|DISP_GROUNDTRACK); - dlgmap->SetDispFlags (dflag | flag); -} - -// ====================================================================== - -void DlgMapOpt::SetVesselMode (DWORD flag) -{ - DWORD dflag = dlgmap->GetMapWin()->GetDisplayFlags(); - dflag &= ~(DISP_VESSEL | DISP_FOCUSONLY); - dlgmap->SetDispFlags (dflag | flag); +void DlgMap::OnDraw() { + DrawMenu(); + DrawMap(); } diff --git a/Src/Orbiter/DlgMap.h b/Src/Orbiter/DlgMap.h index e0b058cdf..08651a10a 100644 --- a/Src/Orbiter/DlgMap.h +++ b/Src/Orbiter/DlgMap.h @@ -8,135 +8,32 @@ #ifndef __DLGMAP_H #define __DLGMAP_H -#include "DialogWin.h" +#include "DlgMgr.h" #include "VectorMap.h" -// ====================================================================== -// Class for map window inside the dialog box - -class MapWin: public VectorMap { - friend class DlgMap; - -public: - MapWin (DlgMap *pDlg); - ~MapWin (); - - int Create (); - int Destroy (); - void PostCreation (HWND hw); - void Update (bool force = false); - bool SetCBody (const CelestialBody *body); - int Paint (); - int Size (DWORD w, DWORD h); - void Pan (int dx, int dy); - -protected: - enum MouseMode { - MOUSE_DRAG, MOUSE_SELECT - }; - - void RegisterWindow (HINSTANCE hInst); - void UnregisterWindow (HINSTANCE hInst); - - void OnLButtonDown (int mx, int my); - void OnLButtonUp (int mx, int my); - void OnMouseMove (int mx, int my); - void OnMouseWheel (int wdelta); - void SetMouseMode (MouseMode mode); - bool FindTarget (int mx, int my); - static MapWin *GetMapInstance (HWND hw); - static MapWin *map_in_creation; - static LRESULT FAR PASCAL Map_WndProc (HWND, UINT, WPARAM, LPARAM); - -private: - DlgMap *dlg; - HWND hWnd; - HFONT font; - HPEN pen[3]; - bool bPaintPending; - bool bForceUpdate; - bool bDragActive; - int mousex, mousey; - MouseMode mousemode; - DWORD storeflag; -}; - -// ====================================================================== -// Map dialog - -class DlgMap: public DialogWin { - friend class MapWin; - friend class DlgMapOpt; - +class CelestialBody; +class DlgMap : public ImGuiDialog { + void Reset(); public: - DlgMap (HINSTANCE hInstance, HWND hParent, void *context); - ~DlgMap (); - static void GlobalInit (); - void SetSelection (const Body *body); - HWND OpenWindow (); - void Update (); - void VesselDeleting (Vessel *v); - void SetCBody (CelestialBody *cbody); - void SetPlanet (const char *name); - void EchoSelection (const VectorMap::OBJTYPE &obj); - void SetSelection (const VectorMap::OBJTYPE &obj); - bool SetSelection (const char *name, int type = 0); - void ToggleDispFlags (DWORD dflag); - void SetDispFlags (DWORD flag); - void SetDragMode (bool drag); - void EnableInfo (bool enable); - void OpenInfo (); - MapWin *GetMapWin() { return map; } - - BOOL OnInitDialog (HWND hWnd, WPARAM wParam, LPARAM lParam); - BOOL OnCommand (HWND hWnd, WORD id, WORD code, HWND hControl); - BOOL OnNotify (HWND hWnd, int idCtrl, LPNMHDR pnmh); - BOOL OnUserMessage (HWND hWnd, WPARAM wParam, LPARAM lParam); - BOOL OnMouseWheel (HWND hWnd, int vk, int dist, int x, int y); - - struct MapPrmPersist { - const CelestialBody *cbody; - VectorMap::OBJTYPE sel; - int zoom; - double lngcnt, latcnt; - bool track; - }; - - struct MAP_PARAM { - int dlgw, dlgh, mapw, maph; - POINT btlp[1], btrp[4]; - }; - -protected: - BOOL OnSize (HWND hDlg, WPARAM wParam, int w, int h); - void SetZoom (int zoom); - void ZoomIn (); - void ZoomOut (); - void SetFindMask (); - -private: - MapWin *map; - MAP_PARAM MapPrm; + DlgMap(); + void Display() override; + void OnDraw() override; + void DrawMap(); + void DrawMenu(); + void SetBody(const char *body); + void AddCbodyNode(const CelestialBody *cbody); + void DrawTree(); + bool FindTarget(int mx, int my); + bool SetSelection(const char *name); + + std::unique_ptr vectormap; + double updTmin = 0.0, updTmax = 0.0; + std::string planet; + double zoom = 1.0; + bool enableInfo; + int selectionfilter; + char searchbuf[128]; CFG_MAPPRM *prm; - static MapPrmPersist prm_store; -}; - -// ====================================================================== -// Map options dialog - -class DlgMapOpt: public DialogWin { -public: - DlgMapOpt (HINSTANCE hInstance, HWND hParent, void *context); - DlgMap *GetMapDlg() { return dlgmap; } - void ToggleDispFlag (DWORD flag); - void SetOrbitMode (DWORD flag); - void SetVesselMode (DWORD flag); - - BOOL OnInitDialog (HWND hWnd, WPARAM wParam, LPARAM lParam); - BOOL OnCommand (HWND hWnd, WORD id, WORD code, HWND hControl); - -private: - DlgMap *dlgmap; }; -#endif // !__DLGMAP_H \ No newline at end of file +#endif // !__DLGMAP_H diff --git a/Src/Orbiter/DlgMenuCfg.cpp b/Src/Orbiter/DlgMenuCfg.cpp index 6317aae63..94f9d6830 100644 --- a/Src/Orbiter/DlgMenuCfg.cpp +++ b/Src/Orbiter/DlgMenuCfg.cpp @@ -11,11 +11,12 @@ #include "imgui.h" #include "imgui_extras.h" #include "Orbiter.h" +#include "IconsFontAwesome6.h" extern Orbiter *g_pOrbiter; extern Pane *g_pane; -DlgMenuCfg::DlgMenuCfg(): ImGuiDialog("Orbiter: Configure menu bars") +DlgMenuCfg::DlgMenuCfg(): ImGuiDialog(ICON_FA_SLIDERS " Orbiter: Configure menu bars") { } diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index fa93d0f93..e8e991a7f 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -437,7 +437,7 @@ static void ImGuiSetStyle(bool bStyleDark_, float alpha_) { // Setup Dear ImGui style ImGui::StyleColorsClassic(); - //ImGui::StyleColorsLight(); + ImGui::StyleColorsLight(); ImGuiStyle& style = ImGui::GetStyle(); style.Alpha = 1.0f; @@ -448,6 +448,7 @@ static void ImGuiSetStyle(bool bStyleDark_, float alpha_) style.ScrollbarRounding = 3.0f; style.GrabRounding = 3.0f; style.TabRounding = 3.0f; + style.WindowMenuButtonPosition = ImGuiDir_Right; return; // light style from Pacôme Danhiez (user itamago) https://github.com/ocornut/imgui/pull/511#issuecomment-175719267 style.Colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); @@ -522,6 +523,8 @@ static void ImGuiSetStyle(bool bStyleDark_, float alpha_) void DialogManager::InitImGui() { + if(!gc) return; + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); @@ -555,6 +558,8 @@ void DialogManager::InitImGui() void DialogManager::ShutdownImGui() { + if(!gc) return; + gc->clbkImGuiShutdown(); ImGui_ImplWin32_Shutdown(); ImGui::DestroyContext(); @@ -562,6 +567,8 @@ void DialogManager::ShutdownImGui() void DialogManager::ImGuiNewFrame() { + if(!gc) return; + gc->clbkImGuiNewFrame(); ImGui_ImplWin32_NewFrame(); ImGui::NewFrame(); @@ -704,6 +711,7 @@ struct Notification void ReTrigger() { occurrences++; creation = std::chrono::steady_clock::now() - FADE_TIME; + duration = 86400.0s; } void UpdateState(time_point_t now, float h, duration_t dt) { duration_t elapsed = now - creation; @@ -972,7 +980,7 @@ namespace ImGui { ImGui::GetCurrentWindow()->Size.x += frameHeight; ImGui::Dummy(ImVec2(0.0f, 0.0f)); ImGui::EndGroup(); - ImGui::Dummy(ImVec2(0.0f, 0.0f)); + //ImGui::Dummy(ImVec2(0.0f, 0.0f)); } DLLEXPORT bool MenuButton(const char *label, const char *tooltip) @@ -983,7 +991,7 @@ namespace ImGui { const ImGuiStyle& style = g.Style; ImGuiLastItemData last_item_backup = g.LastItemData; ImGui::PushClipRect( titleBarRect.Min, titleBarRect.Max, false ); - float width = strlen(label) * g.FontSize; + float width = (strlen(label)+1) * g.FontSize; float offset = titleBarRect.Max.x - width - titleBarRect.Min.x - g.Style.FramePadding.x; ImGui::SetCursorPos( ImVec2( offset, 0.0f ) ); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0,0,0,0)); diff --git a/Src/Orbiter/DlgRecorder.cpp b/Src/Orbiter/DlgRecorder.cpp index 3e480ebac..6009047ed 100644 --- a/Src/Orbiter/DlgRecorder.cpp +++ b/Src/Orbiter/DlgRecorder.cpp @@ -9,11 +9,12 @@ #include "Orbiter.h" #include "OrbiterAPI.h" #include "imgui.h" +#include "IconsFontAwesome6.h" extern Vessel *g_focusobj; extern Orbiter *g_pOrbiter; -DlgRecorder::DlgRecorder() : ImGuiDialog("Flight recorder/player", {329,354}) { +DlgRecorder::DlgRecorder() : ImGuiDialog(ICON_FA_FILM " Flight recorder/player", {329,354}) { strcpy(m_ScenarioFile, "test_record"); } diff --git a/Src/Orbiter/DlgTacc.cpp b/Src/Orbiter/DlgTacc.cpp index f5ad50953..ca2fda329 100644 --- a/Src/Orbiter/DlgTacc.cpp +++ b/Src/Orbiter/DlgTacc.cpp @@ -8,11 +8,12 @@ #include "DlgTacc.h" #include "Orbiter.h" #include "imgui.h" +#include "IconsFontAwesome6.h" extern TimeData td; extern Orbiter *g_pOrbiter; -DlgTacc::DlgTacc() : ImGuiDialog("Orbiter: Time acceleration",{357,135}) { +DlgTacc::DlgTacc() : ImGuiDialog(ICON_FA_CLOCK " Orbiter: Time acceleration",{357,135}) { } void DlgTacc::OnDraw() { diff --git a/Src/Orbiter/MfdMap.cpp b/Src/Orbiter/MfdMap.cpp index cacba0d80..73d20c098 100644 --- a/Src/Orbiter/MfdMap.cpp +++ b/Src/Orbiter/MfdMap.cpp @@ -518,15 +518,8 @@ void Instrument_Map::UpdateBlt () if (disp_mode) return; if (!gc) return; map->Update (); -#ifdef ASYNC_DRAWMAP - if (!map->ThreadBusy()) { - gc->clbkCopyBitmap (surf, map->GetMap(), 0, 0, IW, IH); - map->AsyncDrawMap (); - } -#else map->DrawMap (); - gc->clbkCopyBitmap (surf, map->GetMap(), 0, 0, IW, IH); -#endif + oapiBlt (surf, map->GetMap(), 0, 0, 0, 0, IW, IH); } // ======================================================================= @@ -654,8 +647,8 @@ bool Instrument_Map::ToggleDispParam (int which) int i; for (i = 0; i < cms.nset; i++) if (cms.set[i].active) break; - if (i < cms.nset) dispflag = dispflag | DISP_CUSTOM1; - else dispflag = dispflag & ~DISP_CUSTOM1; + if (i < cms.nset) dispflag = dispflag | DISP_CUSTOMMARKER; + else dispflag = dispflag & ~DISP_CUSTOMMARKER; } return true; } diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 066b959a4..8ecd78032 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -972,7 +972,6 @@ void Orbiter::GetRenderParameters () void Orbiter::BroadcastGlobalInit () { Instrument::GlobalInit (gclient); - DlgMap::GlobalInit(); } // ======================================================================= diff --git a/Src/Orbiter/Select.cpp b/Src/Orbiter/Select.cpp index 8415a7d8f..ddb7513cf 100644 --- a/Src/Orbiter/Select.cpp +++ b/Src/Orbiter/Select.cpp @@ -76,12 +76,24 @@ void Select::DrawMenu(std::list& entries) { } void Select::OnDraw() { - auto& io = ImGui::GetIO(); - + ImGuiIO& io = ImGui::GetIO(); + if (io.MouseDown[0] && opened) { return; } + // Open the context menu inside the focused viewport + // so it's not hidden by it in case it's opened from + // a secondary viewport but its draw area fits inside + // the main viewport + ImGuiPlatformIO& pio = ImGui::GetPlatformIO(); + for (ImGuiViewport *viewport : pio.Viewports) { + if(viewport->Flags & ImGuiViewportFlags_IsFocused) { + ImGui::SetNextWindowViewport(viewport->ID); + break; + } + } + if (opened) { ImGui::OpenPopup(title.c_str()); opened = false; diff --git a/Src/Orbiter/VectorMap.cpp b/Src/Orbiter/VectorMap.cpp index 257345325..9341246af 100644 --- a/Src/Orbiter/VectorMap.cpp +++ b/Src/Orbiter/VectorMap.cpp @@ -1,16 +1,16 @@ // Copyright (c) Martin Schweiger // Licensed under the MIT License -#ifdef OAPIFUNC -#undef OAPIFUNC -#endif #include "DrawAPI.h" #include "VectorMap.h" #include "Psys.h" -#include "MFD.h" +#include "Mfd.h" #include "Util.h" +#include +#include + #define OUTLINE_COAST 1 #define OUTLINE_CONTOUR 2 #define OUTLINE_HORIZON 3 @@ -24,17 +24,11 @@ using namespace std; extern PlanetarySystem *g_psys; extern Vessel *g_focusobj; extern TimeData td; -extern char DBG_MSG[256]; bool VectorMap::bsetup = true; double VectorMap::cosp[NVTX_CIRCLE] = {0}; double VectorMap::sinp[NVTX_CIRCLE] = {0}; -//static COLORREF ObjectCol[3] = { -// Instrument::draw[0][0].col, -// Instrument::draw[1][0].col, -// Instrument::draw[2][0].col -//}; static COLORREF labelcol[6] = {0x00FFFF, 0xFFFF00, 0x4040FF, 0xFF00FF, 0x40FF40, 0xFF8080}; // ======================================================================= @@ -55,24 +49,9 @@ VectorMap::VectorMap (const Planet *pl) VectorMap::~VectorMap () { -#ifdef ASYNC_DRAWMAP - WaitThread (true); - WaitForSingleObject (hCommMutex, INFINITE); - threaddata.taskid = TASKID_TERMINATE; - ReleaseMutex (hCommMutex); - SetEvent (hActivateThread); - DWORD res = WaitForSingleObject (hRedrawThread, 100); // wait for thread termination - if (res == WAIT_TIMEOUT) - TerminateThread (hRedrawThread, 0); // force termination - - CloseHandle (hRedrawThread); - CloseHandle (hActivateThread); - CloseHandle (hCommMutex); -#endif + if(hMap) + oapiDestroySurface(hMap); - if (hBmpDraw) DeleteObject (hBmpDraw); - if (hDCmem) DeleteDC (hDCmem); - CloseGDIResources(); } // ======================================================================= @@ -94,7 +73,7 @@ void VectorMap::SetDefaults () latmax = latc+dlat; centermode = 0; dispflag = DISP_GRIDLINE | DISP_COASTLINE | DISP_CONTOURS | DISP_BASE | DISP_VESSEL | DISP_ORBITFOCUS | DISP_ORBITSEL | DISP_ORBITPLANE; - findflag = DISP_BASE | DISP_NAVAID | DISP_CUSTOM1 | DISP_VESSEL | DISP_MOON; + findflag = DISP_BASE | DISP_NAVAID | DISP_CUSTOMMARKER | DISP_VESSEL | DISP_MOON; drawdata.focus_disp = drawdata.tgtv_disp = drawdata.tgtb_disp = drawdata.sun_disp = false; selection.obj = NULL; selection.type = 0; @@ -108,19 +87,8 @@ void VectorMap::SetDefaults () bsetup = false; } - hDCmem = NULL; - hBmpDraw = NULL; + hMap = NULL; InitGDIResources(); - -#ifdef ASYNC_DRAWMAP - // Initialise the redraw thread - threaddata.taskid = 0; - DWORD id; - hActivateThread = CreateEvent (NULL, FALSE, TRUE, "MapEvent"); - hCommMutex = CreateMutex (NULL, FALSE, "MapCommMutex"); - hRedrawThread = CreateThread (NULL, 2048, Redraw_ThreadProc, this, 0, &id); - SetThreadPriority (hRedrawThread, THREAD_PRIORITY_IDLE); -#endif } // ======================================================================= @@ -134,26 +102,26 @@ void VectorMap::InitGDIResources () int screenh = GetSystemMetrics(SM_CYSCREEN); labelsize = screenh / 100; SetLabelSize(labelsize); - - penGridline = CreatePen (PS_SOLID, 1, 0x505050); - penCoast = CreatePen (PS_SOLID, 1, Instrument::draw[4][0].col); - penContour = CreatePen (PS_SOLID, 1, 0x0070C0); - penTerminator = CreatePen (PS_SOLID, 1, 0xC0C0C0); + + penGridline = oapiCreatePen(1, 1, 0x505050); + penCoast = oapiCreatePen (1, 1, Instrument::draw[4][0].col); + penContour = oapiCreatePen (1, 1, 0x0070C0); + penTerminator = oapiCreatePen (1, 1, 0xC0C0C0); int idx[3] = {0,1,3}; for (i = 0; i < 3; i++) { - penOrbitFuture[i] = CreatePen (PS_SOLID, 1, Instrument::draw[idx[i]][0].col); - penOrbitPast[i] = CreatePen (PS_SOLID, 1, Instrument::draw[idx[i]][1].col); - } - penFocusHorizon = CreatePen (PS_SOLID, 1, Instrument::draw[0][1].col); - penTargetHorizon = CreatePen (PS_SOLID, 1, Instrument::draw[1][1].col); - penNavmkr = CreatePen (PS_SOLID, 1, col_navaid); - penBase = CreatePen (PS_SOLID, 1, Instrument::draw[2][0].col); - penSelection = CreatePen (PS_SOLID, 1, Instrument::draw[1][0].col); + penOrbitFuture[i] = oapiCreatePen (1, 1, Instrument::draw[idx[i]][0].col); + penOrbitPast[i] = oapiCreatePen (1, 1, Instrument::draw[idx[i]][1].col); + } + penFocusHorizon = oapiCreatePen (1, 1, Instrument::draw[0][1].col); + penTargetHorizon = oapiCreatePen (1, 1, Instrument::draw[1][1].col); + penNavmkr = oapiCreatePen (1, 1, col_navaid); + penBase = oapiCreatePen (1, 1, Instrument::draw[2][0].col); + penSelection = oapiCreatePen (1, 1, Instrument::draw[1][0].col); for (i = 0; i < 3; i++) - penMarker[i] = CreatePen (PS_SOLID, 3, Instrument::draw[idx[i]][0].col); + penMarker[i] = oapiCreatePen (1, 3, Instrument::draw[idx[i]][0].col); nCustomMkr = 0; - LOGBRUSH lb = {BS_SOLID, 0x303030, 0}; - brushDay = CreateBrushIndirect (&lb); +// LOGBRUSH lb = {BS_SOLID, 0x303030, 0}; + brushDay = oapiCreateBrush(0x303030);//CreateBrushIndirect (&lb); } // ======================================================================= @@ -162,12 +130,12 @@ void VectorMap::SetLabelSize(int size) { if (fontLabel) { if (size == labelsize) return; // nothing to do - else DeleteObject(fontLabel); + else oapiReleaseFont(fontLabel); } labelsize = size; - fontLabel = CreateFont(-labelsize, 0, 0, 0, 400, 0, 0, 0, 0, 3, 2, 1, 49, "Arial"); -} + fontLabel = oapiCreateFont(-labelsize, true, "Arial", FONT_NORMAL); +} // ======================================================================= void VectorMap::AllocCustomResources () @@ -176,7 +144,7 @@ void VectorMap::AllocCustomResources () if (nCustomMkr) { for (i = 0; i < nCustomMkr; i++) - DeleteObject (penCustomMkr[i]); + oapiReleasePen (penCustomMkr[i]); delete []penCustomMkr; penCustomMkr = NULL; delete []colCustomMkr; @@ -184,11 +152,11 @@ void VectorMap::AllocCustomResources () } nCustomMkr = mkrset.nset; if (nCustomMkr) { - penCustomMkr = new HPEN[nCustomMkr]; + penCustomMkr = new oapi::Pen *[nCustomMkr]; colCustomMkr = new COLORREF[nCustomMkr]; for (i = 0; i < nCustomMkr; i++) { colCustomMkr[i] = labelcol[mkrset.set[i].list->colour]; - penCustomMkr[i] = CreatePen (PS_SOLID, 1, colCustomMkr[i]); + penCustomMkr[i] = oapiCreatePen (1, 1, colCustomMkr[i]); } } } @@ -198,30 +166,30 @@ void VectorMap::AllocCustomResources () void VectorMap::CloseGDIResources () { DWORD i; - DeleteObject (fontLabel); - DeleteObject (penGridline); - DeleteObject (penCoast); - DeleteObject (penContour); - DeleteObject (penTerminator); + oapiReleaseFont (fontLabel); + oapiReleasePen (penGridline); + oapiReleasePen (penCoast); + oapiReleasePen (penContour); + oapiReleasePen (penTerminator); //DeleteObject (penFocusGroundtrackFuture); //DeleteObject (penFocusGroundtrackPast); - DeleteObject (penFocusHorizon); + oapiReleasePen (penFocusHorizon); //DeleteObject (penTargetGroundtrackFuture); //DeleteObject (penTargetGroundtrackPast); - DeleteObject (penTargetHorizon); - DeleteObject (penNavmkr); - DeleteObject (penBase); - DeleteObject (penSelection); - DeleteObject (brushDay); + oapiReleasePen (penTargetHorizon); + oapiReleasePen (penNavmkr); + oapiReleasePen (penBase); + oapiReleasePen (penSelection); + oapiReleaseBrush (brushDay); for (i = 0; i < 3; i++) { - DeleteObject(penOrbitFuture[i]); - DeleteObject(penOrbitPast[i]); + oapiReleasePen(penOrbitFuture[i]); + oapiReleasePen(penOrbitPast[i]); } for (i = 0; i < 3; i++) - DeleteObject (penMarker[i]); + oapiReleasePen (penMarker[i]); if (nCustomMkr) { for (i = 0; i < nCustomMkr; i++) - DeleteObject (penCustomMkr[i]); + oapiReleasePen (penCustomMkr[i]); delete []penCustomMkr; penCustomMkr = NULL; delete []colCustomMkr; @@ -234,12 +202,6 @@ void VectorMap::CloseGDIResources () void VectorMap::Update () { -#ifdef ASYNC_DRAWMAP - if (ThreadBusy()) return; - // Don't update data if drawing in progress - // Should we rather wait here until the thread is free again? -#endif - double lng, lat, rad; if (!cbody) return; @@ -291,9 +253,6 @@ void VectorMap::Update () #ifdef UNDEF void VectorMap::UpdateGroundtrack () { -#ifdef ASYNC_DRAWMAP - if (ThreadBusy()) return; -#endif if (drawdata.focus_disp) gt_this.Update(); if (selection.type == DISP_VESSEL) gt_tgt.Update(); @@ -334,33 +293,18 @@ bool VectorMap::SetCBody (const CelestialBody *body) void VectorMap::SetCanvas (void *device_context, int w, int h) { -#ifdef ASYNC_DRAWMAP - WaitThread (true); - // make sure the drawing thread is not busy before replacing the bitmap -#endif - cw = w; ch = h; cntx = w/2; cnty = h/2; SetZoom (zoom); - // Create the drawing bitmap - HDC hDCtgt = GetDC (NULL); - if (hDCmem) { - DeleteDC (hDCmem); // delete current memory DC - } - if (hBmpDraw) DeleteObject (hBmpDraw); // delete drawing bitmap - if (hDCtgt) { - hDCmem = CreateCompatibleDC (hDCtgt); - hBmpDraw = CreateCompatibleBitmap (hDCtgt, w, h); // create new drawing bitmap - SetBkMode (hDCmem, TRANSPARENT); - SelectObject (hDCmem, GetStockObject (NULL_BRUSH)); - } else { - hDCmem = NULL; - hBmpDraw = NULL; + if(hMap != NULL) { + oapiDestroySurface(hMap); } - ReleaseDC (NULL, hDCtgt); + + hMap = oapiCreateSurface(w,h); + } // ======================================================================= @@ -511,7 +455,7 @@ bool VectorMap::GetObjPos (const OBJTYPE &obj, double &lng, double &lat) const Nav_VOR *vor = (const Nav_VOR*)obj.obj; vor->GetEquPos (lng, lat); } return true; - case DISP_CUSTOM1: { + case DISP_CUSTOMMARKER: { const VPoint *vp = (const VPoint*)obj.obj; lng = vp->lng; lat = vp->lat; @@ -594,7 +538,7 @@ const VectorMap::OBJTYPE VectorMap::FindObject (int x, int y) const } } - if (dispflag & DISP_CUSTOM1 && findflag & DISP_CUSTOM1) { + if (dispflag & DISP_CUSTOMMARKER && findflag & DISP_CUSTOMMARKER) { for (i = 0; i < mkrset.nset; i++) { if (mkrset.set[i].active) { const CustomMkrSpec *set = mkrset.set+i; @@ -606,7 +550,7 @@ const VectorMap::OBJTYPE VectorMap::FindObject (int x, int y) const if (dst2 < dst2min) { dst2min = dst2; obj.obj = set->vtx+j; - obj.type = DISP_CUSTOM1; + obj.type = DISP_CUSTOMMARKER; } } } @@ -657,32 +601,15 @@ const VectorMap::OBJTYPE VectorMap::FindObject (int x, int y) const // ======================================================================= -HBITMAP VectorMap::GetMap () +SURFHANDLE VectorMap::GetMap () { -#ifdef ASYNC_DRAWMAP - //WaitThread(); // wait for thread to finish drawing -#endif - return hBmpDraw; -} - -// ======================================================================= - -HDC VectorMap::GetDeviceContext () -{ -#ifdef ASYNC_DRAWMAP - WaitThread(); // wait for thread to finish drawing -#endif - return hDCmem; + return hMap; } // ======================================================================= void VectorMap::DrawMap () { -#ifdef ASYNC_DRAWMAP - if (ThreadBusy()) return; -#endif - DrawMap_engine(); } @@ -691,97 +618,94 @@ void VectorMap::DrawMap () void VectorMap::DrawMap_engine () { // called either directly (by DrawMap) or from the drawing thread - - tic(); - - // clear the bitmap - HBITMAP pBmp = (HBITMAP)SelectObject (hDCmem, hBmpDraw); - BitBlt (hDCmem, 0, 0, cw, ch, NULL, 0, 0, BLACKNESS); - HFONT pFont = (HFONT)SelectObject (hDCmem, fontLabel); - - // terminator line - if (planet && dispflag & DISP_TERMINATOR) { - switch (dispflag & DISP_TERMINATOR) { - case DISP_TERMINATOR_LINE: - DrawTerminatorLine (drawdata.sunlng, drawdata.sunlat); - break; - case DISP_TERMINATOR_SHADE: - DrawSunnySide (drawdata.sunlng, drawdata.sunlat, false); - break; - case DISP_TERMINATOR_BOTH: - DrawSunnySide (drawdata.sunlng, drawdata.sunlat, true); - break; + oapiClearSurface(hMap); + oapi::Sketchpad *skp = oapiGetSketchpad(hMap); + if(skp) { + skp->SetFont(fontLabel); + + // terminator line + if (planet && dispflag & DISP_TERMINATOR) { + switch (dispflag & DISP_TERMINATOR) { + case DISP_TERMINATOR_LINE: + DrawTerminatorLine (skp, drawdata.sunlng, drawdata.sunlat); + break; + case DISP_TERMINATOR_SHADE: + DrawSunnySide (skp, drawdata.sunlng, drawdata.sunlat, false); + break; + case DISP_TERMINATOR_BOTH: + DrawSunnySide (skp, drawdata.sunlng, drawdata.sunlat, true); + break; + } } - } - // grid lines - if (dispflag & DISP_GRIDLINE) - DrawGridlines (); + // grid lines + if (dispflag & DISP_GRIDLINE) + DrawGridlines (skp); - if (planet) { + if (planet) { - // coastlines - if (dispflag & DISP_COASTLINE) - DrawPolySet (&coast); + // coastlines + if (dispflag & DISP_COASTLINE) + DrawPolySet (skp, &coast); - // contour lines - if (dispflag & DISP_CONTOURS) - DrawPolySet (&contour); + // contour lines + if (dispflag & DISP_CONTOURS) + DrawPolySet (skp, &contour); - // navaids - if (dispflag & DISP_NAVAID) - DrawNavaids (); + // navaids + if (dispflag & DISP_NAVAID) + DrawNavaids (skp); - // custom marker sets - if (dispflag & DISP_CUSTOM1) { - for (DWORD i = 0; i < mkrset.nset; i++) { - if (mkrset.set[i].active) - DrawCustomMarkerSet (i); + // custom marker sets + if (dispflag & DISP_CUSTOMMARKER) { + for (DWORD i = 0; i < mkrset.nset; i++) { + if (mkrset.set[i].active) + DrawCustomMarkerSet (skp, i); + } } - } - // base markers - if (dispflag & DISP_BASE) - DrawBases (); + // base markers + if (dispflag & DISP_BASE) + DrawBases (skp); - // target base - if (drawdata.tgtb_disp) { - DrawMarker (drawdata.tgtblng, drawdata.tgtblat, drawdata.basename, 2); - } + // target base + if (drawdata.tgtb_disp) { + DrawMarker (skp, drawdata.tgtblng, drawdata.tgtblat, drawdata.basename, 2); + } - // natural satellites - if (dispflag & DISP_MOON || selection.type == DISP_MOON) - DrawMoons (); + // natural satellites + if (dispflag & DISP_MOON || selection.type == DISP_MOON) + DrawMoons (skp); - // vessels - if (dispflag & DISP_VESSEL) - DrawVessels (); - } + // vessels + if (dispflag & DISP_VESSEL) + DrawVessels (skp); + } - // target orbiter - if (drawdata.tgtv_disp) { - if (dispflag & DISP_HORIZONLINE) - DrawHorizon (drawdata.tgtvlng, drawdata.tgtvlat, drawdata.tgtvrad, false); - if (dispflag & DISP_GROUNDTRACK) - DrawGroundtrack (gt_tgt, 1); - else if (dispflag & DISP_ORBITPLANE) - DrawOrbitPlane (&drawdata.tgtvel, 1); - DrawMarker (drawdata.tgtvlng, drawdata.tgtvlat, drawdata.tgtname, 1); - } + // target orbiter + if (drawdata.tgtv_disp) { + if (dispflag & DISP_HORIZONLINE) + DrawHorizon (skp, drawdata.tgtvlng, drawdata.tgtvlat, drawdata.tgtvrad, false); + if (dispflag & DISP_GROUNDTRACK) + DrawGroundtrack (skp, gt_tgt, 1); + else if (dispflag & DISP_ORBITPLANE) + DrawOrbitPlane (skp, &drawdata.tgtvel, 1); + DrawMarker (skp, drawdata.tgtvlng, drawdata.tgtvlat, drawdata.tgtname, 1); + } - // selection marker - if (selection.type) - DrawSelectionMarker (selection); + // selection marker + if (selection.type) + DrawSelectionMarker (skp, selection); - SelectObject (hDCmem, pFont); - SelectObject (hDCmem, pBmp); + oapiReleaseSketchpad (skp); + } } // ======================================================================= -void VectorMap::DrawGridlines () +void VectorMap::DrawGridlines (oapi::Sketchpad *skp) { - HPEN ppen = (HPEN)SelectObject (hDCmem, penGridline); + oapi::Pen *ppen = skp->SetPen(penGridline); const double step = 30.0/DEG; const double eps = 1e-8; double lat0 = max(latmin,-Pi05); @@ -794,49 +718,50 @@ void VectorMap::DrawGridlines () double lat = ceil(lat0/step) * step; while (lat < lat1+eps) { y = mapy(lat); - MoveToEx (hDCmem, x0, y, NULL); - LineTo (hDCmem, x1, y); + skp->MoveTo (x0, y); + skp->LineTo (x1, y); lat += step; } double lng = ceil(lng0/step) * step; while (lng < lng1) { x = mapx(lng); - MoveToEx (hDCmem, x, y0, NULL); - LineTo (hDCmem, x, y1); + skp->MoveTo (x, y0); + skp->LineTo (x, y1); lng += step; } + + if(ppen) skp->SetPen(ppen); } // ======================================================================= -void VectorMap::DrawPolySet (const PolyLineSet *pls) +void VectorMap::DrawPolySet (oapi::Sketchpad *skp, const PolyLineSet *pls) { int j, n; int mapw = (int)(cw*PI/dlng); VPoint *v0; - HGDIOBJ ppen = NULL; - + oapi::Pen *ppen = NULL; switch (pls->type) { case OUTLINE_COAST: - ppen = SelectObject (hDCmem, penCoast); + ppen = skp->SetPen(penCoast); break; case OUTLINE_CONTOUR: - ppen = SelectObject (hDCmem, penContour); + ppen = skp->SetPen(penContour); break; } for (j = 0; j < pls->npoly; j++) { v0 = pls->vtx + pls->poly[j].vofs; n = (pls->poly[j].close ? pls->poly[j].nvtx : pls->poly[j].nvtx-1); - DrawPolyline (0, v0, n); + DrawPolyline (skp, 0, v0, n); } - if (ppen) SelectObject (hDCmem, ppen); + if(ppen) skp->SetPen(ppen); } // ======================================================================= -void VectorMap::DrawPolyline (int type, VPoint *vp, int n, bool close) +void VectorMap::DrawPolyline (oapi::Sketchpad *skp, int type, VPoint *vp, int n, bool close) { int i, x0, x1, y0, y1; int mapw = (int)(cw*PI/dlng); @@ -863,14 +788,14 @@ void VectorMap::DrawPolyline (int type, VPoint *vp, int n, bool close) y0 = mapy (va->lat); y1 = mapy (vb->lat); if ((y0 < 0 && y1 < 0) || (y0 >= ch && y1 >= ch)) continue; - MoveToEx (hDCmem, x0, y0, NULL); - LineTo (hDCmem, x1, y1); + skp->MoveTo ( x0, y0); + skp->LineTo ( x1, y1); } } // ======================================================================= -void VectorMap::DrawGroundtrackLine (int type, VPointGT *vp, int n, int n0, int n1) +void VectorMap::DrawGroundtrackLine (oapi::Sketchpad *skp, int type, VPointGT *vp, int n, int n0, int n1) { int i, x0, x1, y0, y1; int mapw = (int)(cw*PI/dlng); @@ -904,40 +829,39 @@ void VectorMap::DrawGroundtrackLine (int type, VPointGT *vp, int n, int n0, int double scl = (1.0-va->rad)/(vb->rad-va->rad); x0 += (int)((x1-x0)*scl); y0 += (int)((y1-y0)*scl); - Rectangle (hDCmem, x0-2, y0-2, x0+3, y0+3); + skp->Rectangle (x0-2, y0-2, x0+3, y0+3); if (replicate) - Rectangle (hDCmem, x0-2-mapw, y0-2, x0+3-mapw, y0+3); + skp->Rectangle (x0-2-mapw, y0-2, x0+3-mapw, y0+3); } else if (vb->rad < 1.0) { double scl = (1.0-vb->rad)/(vb->rad-va->rad); x1 += (int)((x1-x0)*scl); y1 += (int)((y1-y0)*scl); - Rectangle (hDCmem, x1-2, y1-2, x1+3, y1+3); + skp->Rectangle (x1-2, y1-2, x1+3, y1+3); if (replicate) - Rectangle (hDCmem, x1-2-mapw, y1-2, x1+3-mapw, y1+3); + skp->Rectangle (x1-2-mapw, y1-2, x1+3-mapw, y1+3); } if (replicate && x0 != x1) { int xm = (cw-mapw)/2; if (x0 > cntx) xm += mapw; int ym = y0 + ((xm-x0)*(y1-y0))/(x1-x0); - MoveToEx (hDCmem, x0, y0, NULL); - LineTo (hDCmem, xm, ym); + skp->MoveTo (x0, y0); + skp->LineTo (xm, ym); int dx = (x0 > cntx ? -mapw:mapw); - MoveToEx (hDCmem, xm+dx, ym, NULL); - LineTo (hDCmem, x1+dx, y1); + skp->MoveTo (xm+dx, ym); + skp->LineTo (x1+dx, y1); } else { - MoveToEx (hDCmem, x0, y0, NULL); - LineTo (hDCmem, x1, y1); + skp->MoveTo (x0, y0); + skp->LineTo (x1, y1); } } } // ======================================================================= -void VectorMap::DrawNavaids () +void VectorMap::DrawNavaids (oapi::Sketchpad *skp) { - SetTextColor (hDCmem, col_navaid); - HPEN ppen = (HPEN)SelectObject (hDCmem, penNavmkr); - SelectObject (hDCmem, GetStockObject (NULL_BRUSH)); + skp->SetTextColor (col_navaid); + oapi::Pen *ppen = skp->SetPen (penNavmkr); if (planet && planet->nNav()) { static char cbuf[32]; @@ -953,12 +877,12 @@ void VectorMap::DrawNavaids () vor->GetEquPos (lng, lat); if (GetMapPos (lng, lat, x, y)) { if (drawdot) { - SetPixel (hDCmem, x, y, col_navaid); + skp->Pixel (x, y, col_navaid); } else { - Ellipse (hDCmem, x-2, y-2, x+3, y+3); + skp->Ellipse (x-2, y-2, x+3, y+3); if (drawlabel) { sprintf (cbuf, "%s %0.2f", vor->GetId(), vor->GetFreq()); - TextOut (hDCmem, x+3, y, cbuf, strlen(cbuf)); + skp->Text (x+3, y, cbuf, strlen(cbuf)); } } } @@ -967,31 +891,31 @@ void VectorMap::DrawNavaids () } } - SelectObject (hDCmem, ppen); + if(ppen) skp->SetPen (ppen); } // ======================================================================= -void VectorMap::DrawVesselOrbit (Vessel *v) +void VectorMap::DrawVesselOrbit (oapi::Sketchpad *skp, Vessel *v) { bool isfocus = (v == g_focusobj); if (dispflag & DISP_HORIZONLINE) { const SurfParam *sp = v->GetSurfParam(); if (sp && sp->ref == cbody) { - DrawHorizon (sp->lng, sp->lat, sp->rad/cbody->Size(), isfocus); + DrawHorizon (skp, sp->lng, sp->lat, sp->rad/cbody->Size(), isfocus); } } if (v->ElRef() == cbody) { if (dispflag & DISP_GROUNDTRACK) - DrawGroundtrack (isfocus ? gt_this : gt_tgt, isfocus ? 0:1); + DrawGroundtrack (skp, isfocus ? gt_this : gt_tgt, isfocus ? 0:1); if (dispflag & DISP_ORBITPLANE) - DrawOrbitPlane (v->Els(), isfocus ? 0:1); + DrawOrbitPlane (skp, v->Els(), isfocus ? 0:1); } } // ======================================================================= -void VectorMap::DrawVessels () +void VectorMap::DrawVessels (oapi::Sketchpad *skp) { Vessel *v; bool focus_drawn = false; @@ -999,12 +923,12 @@ void VectorMap::DrawVessels () if (dispflag & DISP_ORBITSEL && selection.type == DISP_VESSEL) { v = (Vessel*)selection.obj; if (v == g_focusobj || !(dispflag & DISP_FOCUSONLY)) { - DrawVesselOrbit (v); + DrawVesselOrbit (skp, v); focus_drawn = (v == g_focusobj); } } if (dispflag & DISP_ORBITFOCUS && !focus_drawn) - DrawVesselOrbit (g_focusobj); + DrawVesselOrbit (skp, g_focusobj); for (DWORD i = 0; i < g_psys->nVessel(); i++) { v = g_psys->GetVessel(i); @@ -1012,14 +936,14 @@ void VectorMap::DrawVessels () continue; const SurfParam *sp = v->GetSurfParam(); if (sp && sp->ref == planet) { - DrawMarker (sp->lng, sp->lat, v->Name(), v == g_focusobj ? 0:1); + DrawMarker (skp, sp->lng, sp->lat, v->Name(), v == g_focusobj ? 0:1); } } } // ======================================================================= -void VectorMap::DrawMoons () +void VectorMap::DrawMoons (oapi::Sketchpad *skp) { const CelestialBody *moon; double lng, lat, rad; @@ -1028,9 +952,9 @@ void VectorMap::DrawMoons () moon = (const CelestialBody*)selection.obj; if (moon->ElRef() == cbody) { if (dispflag & DISP_GROUNDTRACK) { - DrawGroundtrack (gt_tgt, 2); + DrawGroundtrack (skp, gt_tgt, 2); } if (dispflag & DISP_ORBITPLANE) { - DrawOrbitPlane (moon->Els(), 2); + DrawOrbitPlane (skp, moon->Els(), 2); } } } @@ -1039,17 +963,17 @@ void VectorMap::DrawMoons () for (DWORD i = 0; i < cbody->nSecondary(); i++) { moon = cbody->Secondary (i); cbody->GlobalToEquatorial (moon->GPos(), lng, lat, rad); - DrawMarker (lng, lat, moon->Name(), 2); + DrawMarker (skp, lng, lat, moon->Name(), 2); } } // ======================================================================= -void VectorMap::DrawBases () +void VectorMap::DrawBases (oapi::Sketchpad *skp) { bool drawlabel = (mapx_scale > 700); - if (drawlabel) SetTextColor (hDCmem, Instrument::draw[2][0].col); - HPEN ppen = (HPEN)SelectObject (hDCmem, penBase); + if (drawlabel) skp->SetTextColor (Instrument::draw[2][0].col); + oapi::Pen *ppen = skp->SetPen (penBase); if (planet && g_psys->nBase (planet)) { int x, y; @@ -1058,21 +982,21 @@ void VectorMap::DrawBases () Base *base = g_psys->GetBase (planet, i); base->EquPos (lng, lat); if (GetMapPos (lng, lat, x, y)) { - Rectangle (hDCmem, x-3, y-3, x+4, y+4); + skp->Rectangle (x-3, y-3, x+4, y+4); if (drawlabel) - TextOut (hDCmem, x+3, y, base->Name(), strlen(base->Name())); + skp->Text (x+3, y, base->Name(), strlen(base->Name())); } } } - SelectObject (hDCmem, ppen); + if(ppen) skp->SetPen (ppen); } // ======================================================================= -void VectorMap::DrawCustomMarkerSet (int idx) +void VectorMap::DrawCustomMarkerSet (oapi::Sketchpad *skp, int idx) { - HPEN ppen = NULL; + oapi::Pen *ppen = NULL; int i, x, y; const char *label; @@ -1082,79 +1006,79 @@ void VectorMap::DrawCustomMarkerSet (int idx) bool drawdot = (mapx_scale < 400); bool drawlabel = (mapx_scale > 1400); - if (drawlabel) SetTextColor (hDCmem, colCustomMkr[idx]); - if (!drawdot) ppen = (HPEN)SelectObject (hDCmem, penCustomMkr[idx]); + if (drawlabel) skp->SetTextColor (colCustomMkr[idx]); + if (!drawdot) ppen = skp->SetPen (penCustomMkr[idx]); for (i = 0; i < set->nvtx; i++) { if (GetMapPos (set->vtx[i].lng, set->vtx[i].lat, x, y)) { if (drawdot) { - SetPixel (hDCmem, x, y, colCustomMkr[idx]); + skp->Pixel (x, y, colCustomMkr[idx]); } else { - Ellipse (hDCmem, x-2, y-2, x+3, y+3); + skp->Ellipse (x-2, y-2, x+3, y+3); if (drawlabel && set->list->marker[i].label[0].size()) { WCHAR wlabel[256]; MultiByteToWideChar(CP_UTF8, 0, set->list->marker[i].label[0].c_str(), -1, wlabel, 256); - TextOutW (hDCmem, x+3, y, wlabel, wcslen(wlabel)); + skp->TextW (x+3, y, wlabel, wcslen(wlabel)); } } } } - if (ppen) SelectObject (hDCmem, ppen); + if (ppen) skp->SetPen (ppen); } // ======================================================================= -void VectorMap::DrawMarker (double lng, double lat, const char *name, int which) +void VectorMap::DrawMarker (oapi::Sketchpad *skp, double lng, double lat, const char *name, int which) { int x, y; if (!GetMapPos (lng, lat, x, y)) return; // position not on map - HPEN ppen = (HPEN)SelectObject (hDCmem, penMarker[which]); - MoveToEx (hDCmem, x-10, y, NULL); - LineTo (hDCmem, x+11, y); - MoveToEx (hDCmem, x, y-10, NULL); - LineTo (hDCmem, x, y+11); - SelectObject (hDCmem, ppen); - SetTextColor (hDCmem, Instrument::draw[which][0].col); - TextOut (hDCmem, x+3, which==2 ? y:y-labelsize-3, name, min((size_t)64,strlen(name))); + oapi::Pen *ppen = skp->SetPen(penMarker[which]); + skp->MoveTo (x-10, y); + skp->LineTo (x+11, y); + skp->MoveTo (x, y-10); + skp->LineTo (x, y+11); + if (ppen) skp->SetPen (ppen); + skp->SetTextColor (Instrument::draw[which][0].col); + skp->Text (x+3, which==2 ? y:y-labelsize-3, name, min(64,(int)strlen(name))); } // ======================================================================= -void VectorMap::DrawSelectionMarker (const OBJTYPE obj) +void VectorMap::DrawSelectionMarker (oapi::Sketchpad *skp, const OBJTYPE obj) { double lng, lat; int x, y; if (GetObjPos (obj, lng, lat)) if (GetMapPos (lng, lat, x, y)) { - HPEN ppen = (HPEN)SelectObject (hDCmem, penSelection); - Ellipse (hDCmem, x-5, y-5, x+6, y+6); - Ellipse (hDCmem, x-8, y-8, x+9, y+9); - SelectObject (hDCmem, ppen); + oapi::Pen *ppen = skp->SetPen(penSelection); + skp->Ellipse (x-5, y-5, x+6, y+6); + skp->Ellipse (x-8, y-8, x+9, y+9); + if (ppen) skp->SetPen (ppen); } } // ======================================================================= -void VectorMap::DrawTerminatorLine (double sunlng, double sunlat) +void VectorMap::DrawTerminatorLine (oapi::Sketchpad *skp, double sunlng, double sunlat) { - HPEN ppen = (HPEN)SelectObject (hDCmem, penTerminator); + oapi::Pen *ppen = skp->SetPen(penTerminator); VPoint *p = GreatCircle (sunlng, sunlat); - DrawPolyline (0, p, NVTX_CIRCLE); - SelectObject (hDCmem, ppen); + DrawPolyline (skp, 0, p, NVTX_CIRCLE); + if (ppen) skp->SetPen (ppen); } // ======================================================================= -void VectorMap::DrawSunnySide (double sunlng, double sunlat, bool terminator) +void VectorMap::DrawSunnySide (oapi::Sketchpad *skp, double sunlng, double sunlat, bool terminator) { int i, cut, ybase, idx0, idx1; int mapw = (int)(cw*PI/dlng); if (sunlat >= 0) ybase = max (0, mapy(Pi05)); else ybase = min (ch, mapy(-Pi05)); VPoint *p = GreatCircle (sunlng, sunlat); - POINT pt[NVTX_CIRCLE], ptt[NVTX_CIRCLE+4]; + oapi::IVECTOR2 pt[NVTX_CIRCLE+4], ptt[NVTX_CIRCLE+4]; for (i = 0; i < NVTX_CIRCLE; i++) { pt[i].x = mapx(p[i].lng); pt[i].y = mapy(p[i].lat); @@ -1176,7 +1100,7 @@ void VectorMap::DrawSunnySide (double sunlng, double sunlat, bool terminator) idx0 = 1; } else { for (idx0 = 2; idx0 < NVTX_CIRCLE+1; idx0++) { - if (ptt[idx0+1].x > 0) break; + if (ptt[idx0+1].x >= 0) break; } } if (ptt[NVTX_CIRCLE+1].x < cw) { @@ -1185,44 +1109,51 @@ void VectorMap::DrawSunnySide (double sunlng, double sunlat, bool terminator) idx1 = NVTX_CIRCLE+2; } else { for (idx1 = NVTX_CIRCLE+1; idx1 > 2; idx1--) { - if (ptt[idx1-1].x < cw) break; + if (ptt[idx1-1].x <= cw) break; } } if (idx1 <= idx0) return; ptt[idx0-1].x = ptt[idx0].x; - ptt[idx0-1].y = ybase; + ptt[idx0-1].y = 10000;//ybase - 10000; ptt[idx1+1].x = ptt[idx1].x; - ptt[idx1+1].y = ybase; + ptt[idx1+1].y = 10000;//ybase - 10000; + + oapi::Pen *ppen = NULL; + if(terminator) + ppen = skp->SetPen(penTerminator); + else { + //FIXME NULL_PEN + //ppen = skp->SetPen(penTerminator); + } + skp->SetBrush(brushDay); + skp->Polygon (ptt+(idx0-1), idx1-idx0+3); + if (ppen) skp->SetPen(ppen); - HPEN ppen = (HPEN)SelectObject (hDCmem, terminator ? penTerminator : GetStockObject (NULL_PEN)); - SelectObject (hDCmem, brushDay); - Polygon (hDCmem, ptt+(idx0-1), idx1-idx0+3); - SelectObject (hDCmem, ppen); - SelectObject (hDCmem, GetStockObject (NULL_BRUSH)); } // ======================================================================= -void VectorMap::DrawOrbitPlane (const Elements *el, int which) +void VectorMap::DrawOrbitPlane (oapi::Sketchpad *skp, const Elements *el, int which) { - HPEN ppen = (HPEN)SelectObject (hDCmem, penOrbitFuture[which]); + oapi::Pen *ppen = skp->SetPen(penOrbitFuture[which]); + static VPoint p[NVTX_CIRCLE]; CalcOrbitProj (el, cbody, p); - DrawPolyline (OUTLINE_ORBITPLANE, p, NVTX_CIRCLE); - SelectObject (hDCmem, ppen); + DrawPolyline (skp, OUTLINE_ORBITPLANE, p, NVTX_CIRCLE); + if (ppen) skp->SetPen(ppen); } // ======================================================================= -void VectorMap::DrawGroundtrack (Groundtrack >, int which) +void VectorMap::DrawGroundtrack (oapi::Sketchpad *skp, Groundtrack >, int which) { - DrawGroundtrack_past (gt, which); - DrawGroundtrack_future (gt, which); + DrawGroundtrack_past (skp, gt, which); + DrawGroundtrack_future (skp, gt, which); } -void VectorMap::DrawGroundtrack_past (Groundtrack >, int which) +void VectorMap::DrawGroundtrack_past (oapi::Sketchpad *skp, Groundtrack >, int which) { - HPEN ppen = (HPEN)SelectObject (hDCmem, penOrbitPast[which]); + oapi::Pen *ppen = skp->SetPen(penOrbitPast[which]); #ifdef UNDEF if (gt.vfirst <= gt.vcurr) { DrawGroundtrackLine (OUTLINE_GROUNDTRACK, gt.vtx+gt.vfirst, gt.vcurr-gt.vfirst+1); @@ -1233,13 +1164,13 @@ void VectorMap::DrawGroundtrack_past (Groundtrack >, int which) LineTo (hDCmem, mapx(gt.vtx[0].lng), mapy(gt.vtx[0].lat)); } #endif - DrawGroundtrackLine (OUTLINE_GROUNDTRACK, gt.vtx, gt.nvtx, gt.vfirst, gt.vcurr); - SelectObject (hDCmem, ppen); + DrawGroundtrackLine (skp, OUTLINE_GROUNDTRACK, gt.vtx, gt.nvtx, gt.vfirst, gt.vcurr); + if (ppen) skp->SetPen(ppen); } -void VectorMap::DrawGroundtrack_future (Groundtrack >, int which) +void VectorMap::DrawGroundtrack_future (oapi::Sketchpad *skp, Groundtrack >, int which) { - HPEN ppen = (HPEN)SelectObject (hDCmem, penOrbitFuture[which]); + oapi::Pen *ppen = skp->SetPen(penOrbitFuture[which]); #ifdef UNDEF if (gt.vcurr <= gt.vlast) { DrawGroundtrackLine (OUTLINE_GROUNDTRACK, gt.vtx+gt.vcurr, gt.vlast-gt.vcurr+1); @@ -1250,19 +1181,23 @@ void VectorMap::DrawGroundtrack_future (Groundtrack >, int which) LineTo (hDCmem, mapx(gt.vtx[0].lng), mapy(gt.vtx[0].lat)); } #endif - DrawGroundtrackLine (OUTLINE_GROUNDTRACK, gt.vtx, gt.nvtx, gt.vcurr, gt.vlast); - SelectObject (hDCmem, ppen); + DrawGroundtrackLine (skp, OUTLINE_GROUNDTRACK, gt.vtx, gt.nvtx, gt.vcurr, gt.vlast); + if (ppen) skp->SetPen(ppen); } // ======================================================================= -void VectorMap::DrawHorizon (double lng, double lat, double rad, bool focus) +void VectorMap::DrawHorizon (oapi::Sketchpad *skp, double lng, double lat, double rad, bool focus) { - HPEN ppen = (HPEN)SelectObject (hDCmem, focus ? penFocusHorizon:penTargetHorizon); + // If the vessel is below ground, we need to bail out to prevent NaN issues further down the line + if(rad < 1.0) { + return; + } + oapi::Pen *ppen = skp->SetPen(focus ? penFocusHorizon:penTargetHorizon); double dst = 1.0/rad; VPoint *vp = SmallCircle (lng, lat, dst); - DrawPolyline (OUTLINE_HORIZON, vp, NVTX_CIRCLE); - SelectObject (hDCmem, ppen); + DrawPolyline (skp, OUTLINE_HORIZON, vp, NVTX_CIRCLE); + if (ppen) skp->SetPen(ppen); } // ======================================================================= @@ -1346,77 +1281,6 @@ VPoint *VectorMap::SmallCircle (double lng, double lat, double dst) return vp; } - -// ======================================================================= -// Thread interface -// ======================================================================= -#ifdef ASYNC_DRAWMAP -// ======================================================================= - -void VectorMap::WaitThread (bool abortOp) -{ - if (!ThreadBusy()) return; - if (abortOp) { - WaitForSingleObject (hCommMutex, INFINITE); - threaddata.taskid = TASKID_ABORT; - ReleaseMutex (hCommMutex); - } - while (ThreadBusy()) { - Sleep(10); - } -} - -// ======================================================================= -// Sends a request for a redraw to the draw thread and returns immediately - -bool VectorMap::AsyncDrawMap () -{ - if (ThreadBusy()) return false; // redraw is already in progress - DWORD res = WaitForSingleObject (hCommMutex, 10); - if (res == WAIT_TIMEOUT) return false; // could not get mutex in time - threaddata.taskid = TASKID_DRAW; - ReleaseMutex (hCommMutex); - SetEvent (hActivateThread); - return true; -} - -// ======================================================================= - -void VectorMap::thEngine () -{ - const DWORD idle = 100; - DWORD flag; - bool keep_going = true; - while (keep_going) { - WaitForSingleObject (hActivateThread, INFINITE); // wait for task - WaitForSingleObject (hCommMutex, INFINITE); // secure comm data - flag = threaddata.taskid; - ReleaseMutex (hCommMutex); - switch (flag) { - case TASKID_TERMINATE: - keep_going = false; - break; - case TASKID_DRAW: - DrawMap_engine (); - break; - } - WaitForSingleObject (hCommMutex, INFINITE); - threaddata.taskid = 0; // signal task complete - ReleaseMutex (hCommMutex); - } -} - -// ======================================================================= - -DWORD WINAPI VectorMap::Redraw_ThreadProc (void *data) -{ - VectorMap *map = (VectorMap*)data; - map->thEngine(); - return 0; -} -#endif // ASYNC_DRAWMAP - - // ======================================================================= // ======================================================================= @@ -1681,4 +1545,4 @@ void Groundtrack::Update () vupdt = (vupdt+1) % nvtx; } omega_updt = fabs (omega_updt); -} \ No newline at end of file +} diff --git a/Src/Orbiter/VectorMap.h b/Src/Orbiter/VectorMap.h index d4bef4013..68db517fd 100644 --- a/Src/Orbiter/VectorMap.h +++ b/Src/Orbiter/VectorMap.h @@ -16,21 +16,21 @@ #define NVTX_CIRCLE 64 -#define DISP_GRIDLINE 0x0001 -#define DISP_COASTLINE 0x0002 -#define DISP_CONTOURS 0x0004 -#define DISP_VESSEL 0x0008 -#define DISP_FOCUSONLY 0x0010 -#define DISP_HORIZONLINE 0x0020 -#define DISP_NAVAID 0x0040 -#define DISP_BASE 0x0080 -#define DISP_MOON 0x0100 -#define DISP_CUSTOM1 0x0200 -#define DISP_ORBITPLANE 0x0400 -#define DISP_GROUNDTRACK 0x0800 -#define DISP_ORBITFOCUS 0x1000 -#define DISP_ORBITSEL 0x2000 -#define DISP_TERMINATOR 0xC000 +#define DISP_GRIDLINE 0x0001 +#define DISP_COASTLINE 0x0002 +#define DISP_CONTOURS 0x0004 +#define DISP_VESSEL 0x0008 +#define DISP_FOCUSONLY 0x0010 +#define DISP_HORIZONLINE 0x0020 +#define DISP_NAVAID 0x0040 +#define DISP_BASE 0x0080 +#define DISP_MOON 0x0100 +#define DISP_CUSTOMMARKER 0x0200 +#define DISP_ORBITPLANE 0x0400 +#define DISP_GROUNDTRACK 0x0800 +#define DISP_ORBITFOCUS 0x1000 +#define DISP_ORBITSEL 0x2000 +#define DISP_TERMINATOR 0xC000 #define DISP_TERMINATOR_NONE 0x0000 #define DISP_TERMINATOR_LINE 0x4000 @@ -138,10 +138,9 @@ class VectorMap { void SetFindFlags (DWORD flag) { findflag = flag; } DWORD GetFindFlags () const { return findflag; } - // Returns the drawing bitmap and HDC. + // Returns the drawing bitmap SURFHANDLE. // Note: waits for the drawing thread to finish - HBITMAP GetMap (); - HDC GetDeviceContext(); + SURFHANDLE GetMap (); void DrawMap (); // redraw directly @@ -200,28 +199,28 @@ class VectorMap { // drawing logical object sets void DrawMap_engine ();// redraw map - void DrawGridlines (); - void DrawPolySet (const PolyLineSet *pls); - void DrawPolyline (int type, VPoint *vp, int n, bool close = true); - void DrawNavaids (); - void DrawVessels (); - void DrawMoons (); - void DrawVesselOrbit (Vessel *v); - void DrawBases (); - void DrawCustomMarkerSet (int idx); - void DrawTerminatorLine (double sunlng, double sunlat); - void DrawSunnySide (double sunlng, double sunlat, bool terminator); - void DrawOrbitPlane (const Elements *el, int which); - void DrawGroundtrack (Groundtrack >, int which); - void DrawGroundtrack_past (Groundtrack >, int which); - void DrawGroundtrack_future (Groundtrack >, int which); - void DrawHorizon (double lng, double lat, double rad, bool focus); - void DrawGroundtrackLine (int type, VPointGT *vp, int n, int n0, int n1); + void DrawGridlines (oapi::Sketchpad *skp); + void DrawPolySet (oapi::Sketchpad *skp, const PolyLineSet *pls); + void DrawPolyline (oapi::Sketchpad *skp, int type, VPoint *vp, int n, bool close = true); + void DrawNavaids (oapi::Sketchpad *skp); + void DrawVessels (oapi::Sketchpad *skp); + void DrawMoons (oapi::Sketchpad *skp); + void DrawVesselOrbit (oapi::Sketchpad *skp, Vessel *v); + void DrawBases (oapi::Sketchpad *skp); + void DrawCustomMarkerSet (oapi::Sketchpad *skp, int idx); + void DrawTerminatorLine (oapi::Sketchpad *skp, double sunlng, double sunlat); + void DrawSunnySide (oapi::Sketchpad *skp, double sunlng, double sunlat, bool terminator); + void DrawOrbitPlane (oapi::Sketchpad *skp, const Elements *el, int which); + void DrawGroundtrack (oapi::Sketchpad *skp, Groundtrack >, int which); + void DrawGroundtrack_past (oapi::Sketchpad *skp, Groundtrack >, int which); + void DrawGroundtrack_future (oapi::Sketchpad *skp, Groundtrack >, int which); + void DrawHorizon (oapi::Sketchpad *skp, double lng, double lat, double rad, bool focus); + void DrawGroundtrackLine (oapi::Sketchpad *skp, int type, VPointGT *vp, int n, int n0, int n1); // drawing primitives - void DrawMarker (double lng, double lat, const char *name, int which); // which: 0=focusobj, 1=orbittarget, 2=basetarget + void DrawMarker (oapi::Sketchpad *skp, double lng, double lat, const char *name, int which); // which: 0=focusobj, 1=orbittarget, 2=basetarget - void DrawSelectionMarker (const OBJTYPE obj); + void DrawSelectionMarker (oapi::Sketchpad *skp, const OBJTYPE obj); // calculate the vertex points of a great circle on the sphere // The circle describes the intersection of the sphere with an @@ -272,67 +271,28 @@ class VectorMap { // ------------------------------------------------------------------ // Drawing resources - HDC hDCmem; // memory device context - HBITMAP hBmpDraw; // bitmap for background drawing - HPEN penGridline; - HPEN penCoast; - HPEN penContour; - HPEN penTerminator; - HPEN penOrbitFuture[3]; // 0=focus, 1=vessel, 2=moon - HPEN penOrbitPast[3]; // 0=focus, 1=vessel, 2=moon - HPEN penFocusHorizon; - HPEN penTargetHorizon; - HPEN penNavmkr; - HPEN penBase; - HPEN penSelection; - HPEN penMarker[3]; - HPEN *penCustomMkr; - HBRUSH brushDay; - HFONT fontLabel; + SURFHANDLE hMap; // bitmap for background drawing + oapi::Pen *penGridline; + oapi::Pen *penCoast; + oapi::Pen *penContour; + oapi::Pen *penTerminator; + oapi::Pen *penOrbitFuture[3]; // 0=focus, 1=vessel, 2=moon + oapi::Pen *penOrbitPast[3]; // 0=focus, 1=vessel, 2=moon + oapi::Pen *penFocusHorizon; + oapi::Pen *penTargetHorizon; + oapi::Pen *penNavmkr; + oapi::Pen *penBase; + oapi::Pen *penSelection; + oapi::Pen *penMarker[3]; + oapi::Pen **penCustomMkr; + oapi::Brush *brushDay; + oapi::Font *fontLabel; COLORREF *colCustomMkr; DWORD nCustomMkr; private: void InitGDIResources(); void CloseGDIResources(); - -#ifdef ASYNC_DRAWMAP - // ------------------------------------------------------------------ - // Thread interface for asynchronous drawing -protected: - HANDLE hRedrawThread; // redraw thread handle - HANDLE hActivateThread; // thread activation event handle; set by the main thread to start thread execution - HANDLE hCommMutex; // mutex for protecting communication between main and drawing threads - - // Blocking wait: returns after thread has completed its current operation (if any) - // abortOp: this flag asks the thread to terminate its current operation. Use this - // if the results of the current operation are obsolete and you want the function - // to return as quickly as possible - void WaitThread (bool abortOp = false); - - // Thread communication data. This structure should only be accessed - // after acquiring the hCommMutex. - struct THREADDATA { - int taskid; // task identifier - } threaddata; - -public: - // Returns true if thread is busy, false if waiting - // is it safe to do this without locking the mutex? - inline bool ThreadBusy () const - { return threaddata.taskid != 0; } - - // Request asynchronous map redraw - bool AsyncDrawMap (); - -protected: - // the following functions (th*) are accessed only by the thread - void thEngine (); // redraw thread loop - -private: - static DWORD WINAPI Redraw_ThreadProc (void*); // thread entry point - // ------------------------------------------------------------------ -#endif // ASYNC_DRAWMAP }; -#endif // !__VECTORMAP_H \ No newline at end of file +#endif // !__VECTORMAP_H diff --git a/Src/Plugin/ExtMFD/MFDWindow.cpp b/Src/Plugin/ExtMFD/MFDWindow.cpp index fcdf5abdb..bc5ca3cf2 100644 --- a/Src/Plugin/ExtMFD/MFDWindow.cpp +++ b/Src/Plugin/ExtMFD/MFDWindow.cpp @@ -45,8 +45,8 @@ void DlgExtMFD::Display() { ImGui::SetNextWindowSize(ImVec2(defaultSize.width, defaultSize.height), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSizeConstraints(ImVec2(382,366), ImVec2(FLT_MAX, FLT_MAX)); - char cbuf[256] = "MFD ["; - oapiGetObjectName(m_mfd->GetVessel(), cbuf + 5, 250); + char cbuf[256] = ICON_FA_TABLET_SCREEN_BUTTON " MFD ["; + oapiGetObjectName(m_mfd->GetVessel(), cbuf + 9, 246); strcat(cbuf, "]###"); strcat(cbuf, name.c_str()); diff --git a/Src/Plugin/LuaConsole/LuaConsole.cpp b/Src/Plugin/LuaConsole/LuaConsole.cpp index b765567d4..6c24f86d5 100644 --- a/Src/Plugin/LuaConsole/LuaConsole.cpp +++ b/Src/Plugin/LuaConsole/LuaConsole.cpp @@ -98,7 +98,7 @@ class LuaConsoleDlg: public ImGuiDialog { } void Display() { ImGui::SetNextWindowSize(ImVec2(800,600)); - bool visible = ImGui::Begin("Lua Console", &active); + bool visible = ImGui::Begin(ICON_FA_TERMINAL " Lua Console", &active); if(ImGui::MenuButton(ICON_FA_TRASH, "Clear console")) { lines.clear(); } From 3218cafdc84403e287d2f45dd91f4e01ba6587c4 Mon Sep 17 00:00:00 2001 From: Gondos Date: Sun, 9 Feb 2025 23:32:44 +0100 Subject: [PATCH 29/51] [ImGui]Convert DlgHelp --- Orbitersdk/include/OrbiterAPI.h | 10 ++ Orbitersdk/include/imgui_extras.h | 2 +- Src/Orbiter/DlgCamera.cpp | 14 +- Src/Orbiter/DlgCamera.h | 16 ++ Src/Orbiter/DlgCapture.cpp | 1 + Src/Orbiter/DlgFocus.cpp | 1 + Src/Orbiter/DlgFunction.cpp | 1 + Src/Orbiter/DlgHelp.cpp | 267 ++---------------------------- Src/Orbiter/DlgHelp.h | 18 +- Src/Orbiter/DlgInfo.cpp | 1 + Src/Orbiter/DlgMap.cpp | 5 +- Src/Orbiter/DlgMenuCfg.cpp | 1 + Src/Orbiter/DlgMgr.cpp | 26 ++- Src/Orbiter/DlgRecorder.cpp | 1 + Src/Orbiter/DlgTacc.cpp | 1 + Src/Orbiter/Orbiter.cpp | 12 +- Src/Orbiter/Orbiter.h | 2 +- Src/Orbiter/OrbiterAPI.cpp | 2 +- Src/Orbiter/PlaybackEd.cpp | 2 + Src/Orbiter/TabOptions.h | 2 - Src/Plugin/ExtMFD/MFDWindow.cpp | 7 +- 21 files changed, 109 insertions(+), 283 deletions(-) diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 6035b385c..57fa3bced 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -687,6 +687,14 @@ class OAPIFUNC ImGuiDialog { bool IsActive() { return active; } void Activate() { active = true; } virtual void Display(); + void SetHelp(const char *file, const char *topic = NULL) { + helpfile = file; + if(topic) + helptopic = topic; + else + helptopic.clear(); + } + bool HandleHelpButton(); protected: /** * \brief Callback that is executed when the dialog is closed. @@ -703,6 +711,8 @@ class OAPIFUNC ImGuiDialog { bool active = false; const std::string name; ImGuiDefaultSize defaultSize; + std::string helpfile; + std::string helptopic; }; /** diff --git a/Orbitersdk/include/imgui_extras.h b/Orbitersdk/include/imgui_extras.h index 73598b0a2..95b0aa86c 100644 --- a/Orbitersdk/include/imgui_extras.h +++ b/Orbitersdk/include/imgui_extras.h @@ -16,6 +16,6 @@ namespace ImGui { OAPIFUNC void HelpMarker(const char* desc, bool sameline = true); OAPIFUNC void BeginGroupPanel(const char* name, const ImVec2& size = ImVec2(-1.0f, -1.0f)); OAPIFUNC void EndGroupPanel(); - OAPIFUNC bool MenuButton(const char *label, const char *tooltip = NULL); + OAPIFUNC bool MenuButton(const char *label, const char *tooltip = NULL, float xoffset = 0.0f); OAPIFUNC void PushFont(ImGuiFont); }; diff --git a/Src/Orbiter/DlgCamera.cpp b/Src/Orbiter/DlgCamera.cpp index d57e580e1..8d390af3f 100644 --- a/Src/Orbiter/DlgCamera.cpp +++ b/Src/Orbiter/DlgCamera.cpp @@ -28,21 +28,13 @@ void DlgCamera::OnDraw() { if(followterrain[0]=='\0') sprintf (followterrain, "%0.0lf", g_camera->GroundObserver_TerrainLimit()); - - const char *tabs[] = { - "Control", "Target", "Track", "Ground", "FoV", "Preset" - }; - - void (DlgCamera::* func[])() = { - &DlgCamera::DrawControl, &DlgCamera::DrawTarget, &DlgCamera::DrawTrack, &DlgCamera::DrawGround, &DlgCamera::DrawFoV, &DlgCamera::DrawPreset - }; - ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None; if (ImGui::BeginTabBar("CameraTabBar", tab_bar_flags)) { for(size_t i = 0; i < sizeof(tabs)/sizeof(tabs[0]); i++) { - if(ImGui::BeginTabItem(tabs[i])) { - (this->*func[i])(); + if(ImGui::BeginTabItem(tabs[i].name)) { + SetHelp("html/orbiter.chm", tabs[i].helptopic); + (this->*tabs[i].func)(); ImGui::EndTabItem(); } } diff --git a/Src/Orbiter/DlgCamera.h b/Src/Orbiter/DlgCamera.h index 089d17177..7e5ba9814 100644 --- a/Src/Orbiter/DlgCamera.h +++ b/Src/Orbiter/DlgCamera.h @@ -43,5 +43,21 @@ class DlgCamera : public ImGuiDialog { void AddCbodyNode(const CelestialBody *body); void ApplyObserver(); void SetCurrentGroundpos(); + + struct CameraTab { + const char *name; + const char *helptopic; + void (DlgCamera::* func)(); + }; + + static inline CameraTab tabs[] = { + {"Control", "/cam_control.htm", &DlgCamera::DrawControl}, + {"Target", "/cam_target.htm", &DlgCamera::DrawTarget}, + {"Track", "/cam_track.htm", &DlgCamera::DrawTrack}, + {"Ground", "/cam_ground.htm", &DlgCamera::DrawGround}, + {"FoV", "/cam_fov.htm", &DlgCamera::DrawFoV}, + {"Preset", "/cam_preset.htm", &DlgCamera::DrawPreset}, + }; + }; #endif // !__DLGCAMERA_H \ No newline at end of file diff --git a/Src/Orbiter/DlgCapture.cpp b/Src/Orbiter/DlgCapture.cpp index e3c7d34b9..24c69fadd 100644 --- a/Src/Orbiter/DlgCapture.cpp +++ b/Src/Orbiter/DlgCapture.cpp @@ -17,6 +17,7 @@ extern Orbiter *g_pOrbiter; #include "imgui_extras.h" DlgCapture::DlgCapture() : ImGuiDialog(ICON_FA_VOICEMAIL " Orbiter: Capture frames",{323,343}) { + SetHelp("html/orbiter.chm", "/capture.htm"); } void DlgCapture::OnDraw() { diff --git a/Src/Orbiter/DlgFocus.cpp b/Src/Orbiter/DlgFocus.cpp index 51a609f4d..74c3f0ad5 100644 --- a/Src/Orbiter/DlgFocus.cpp +++ b/Src/Orbiter/DlgFocus.cpp @@ -20,6 +20,7 @@ extern Orbiter *g_pOrbiter; extern Vessel *g_focusobj, *g_pfocusobj; DlgFocus::DlgFocus() : ImGuiDialog(ICON_FA_ROCKET " Orbiter: Select spacecraft", {300, 320}) { + SetHelp("html/orbiter.chm", "/selvessel.htm"); } void DlgFocus::OnDraw() { diff --git a/Src/Orbiter/DlgFunction.cpp b/Src/Orbiter/DlgFunction.cpp index 29e692508..0c80f91b9 100644 --- a/Src/Orbiter/DlgFunction.cpp +++ b/Src/Orbiter/DlgFunction.cpp @@ -13,6 +13,7 @@ extern Orbiter *g_pOrbiter; DlgFunction::DlgFunction() : ImGuiDialog(ICON_FA_PUZZLE_PIECE " Orbiter: Custom functions", {340, 290}) { + SetHelp("html/orbiter.chm", "/customcmd.htm"); } void DlgFunction::OnDraw() { diff --git a/Src/Orbiter/DlgHelp.cpp b/Src/Orbiter/DlgHelp.cpp index 5da8fd73b..2fcc7ebe2 100644 --- a/Src/Orbiter/DlgHelp.cpp +++ b/Src/Orbiter/DlgHelp.cpp @@ -4,264 +4,29 @@ // ====================================================================== // Help window // ====================================================================== - -#define STRICT 1 - #include "DlgHelp.h" -#include "DlgMgr.h" -#include "Orbiter.h" -#include "Resource.h" #include #include +#include "imgui.h" -extern Orbiter *g_pOrbiter; -extern HELPCONTEXT DefHelpContext; - -static char helpf[256] = "html/orbiter.chm"; -static char deftopic[256] = "html/orbiter.chm::/intro.htm"; -static char vstopic[256] = ""; -static char jmp2url[256] = ""; -static char topic[256] = "/intro.htm"; -static DWORD_PTR pTopic = (DWORD_PTR)topic; -static bool bScnHelp = false; -static bool bVsHelp = false; -static HWND hHelpClient = NULL; - -// ====================================================================== - -DlgHelp::DlgHelp (HINSTANCE hInstance, HWND hParent, void *context) -: DialogWin (hInstance, hParent, IDD_HELP, (DLGPROC)DlgProc, 0, context) -{ - hfooter = 0; - RegisterClientClass (hInstance); -} - -// ====================================================================== - -DlgHelp::~DlgHelp () -{ - UnregisterClientClass (hInst); -} - -// ====================================================================== - -void DlgHelp::RegisterClientClass (HINSTANCE hInstance) -{ - // Register help window class - WNDCLASS wndClass; - wndClass.style = CS_HREDRAW | CS_VREDRAW; - wndClass.lpfnWndProc = ClientProc; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = hInstance; - wndClass.hIcon = NULL; - wndClass.hCursor = NULL; - wndClass.hbrBackground = (HBRUSH)GetStockObject (HOLLOW_BRUSH); - wndClass.lpszMenuName = NULL; - wndClass.lpszClassName = "OrbiterHelp"; - RegisterClass (&wndClass); -} - -// ====================================================================== - -void DlgHelp::UnregisterClientClass (HINSTANCE hInstance) -{ - UnregisterClass ("OrbiterHelp", hInstance); -} - -// ====================================================================== - -void DlgHelp::SetScenarioHelp (const char *_helpf) -{ - if (_helpf) { - char cbuf[256]; - strcpy (cbuf, _helpf); - sprintf (helpf, "html/Scenarios/%s.chm", strtok (cbuf, ",")); - if (_access(helpf,0) == 0) { - sprintf (deftopic, "%s::/%s.htm", helpf, strtok (NULL, ",")); - pTopic = 0; - bScnHelp = true; - return; - } - } - strcpy (helpf, "html/orbiter.chm"); - strcpy (deftopic, "html/orbiter.chm::/intro.htm"); - pTopic = (DWORD_PTR)topic; - bScnHelp = false; -} - -// ====================================================================== - -void DlgHelp::SetVesselHelp (const char *_helpf) -{ - if (_helpf) { - char cbuf[256]; - strcpy (cbuf, _helpf); - sprintf (vstopic, "html/Vessels/%s.chm", strtok (cbuf, ",")); - sprintf (jmp2url, "%s::/%s.htm", vstopic, strtok (NULL, ",")); - bVsHelp = true; - } else { - bVsHelp = false; - } -} - -// ====================================================================== +// This is just a placeholder to call the HtmlHelp API +// We draw nothing ourselves +DlgHelp::DlgHelp():ImGuiDialog("Orbiter: Help") {} +void DlgHelp::Display() {} +void DlgHelp::OnDraw() {} -void DlgHelp::InitHelp (HWND hWnd, HELPCONTEXT *hcontext) +void DlgHelp::OpenHelp(const HELPCONTEXT *hc) { - HH_WINTYPE hhwt; - memset (&hhwt, 0, sizeof(hhwt)); - hhwt.cbStruct = sizeof (hhwt); - hhwt.fUniCodeStrings = FALSE; - hhwt.pszType = "Default"; - hhwt.fsValidMembers = HHWIN_PARAM_PROPERTIES | HHWIN_PARAM_TB_FLAGS | - HHWIN_PARAM_STYLES | HHWIN_PARAM_EXSTYLES; - hhwt.fsWinProperties = HHWIN_PROP_TRI_PANE | HHWIN_PROP_NOTITLEBAR | - HHWIN_PROP_TAB_SEARCH | HHWIN_PROP_AUTO_SYNC | HHWIN_PROP_NODEF_STYLES; - hhwt.pszCaption = "Orbiter Help"; - hhwt.dwStyles = WS_CHILD | WS_VISIBLE; - hhwt.dwExStyles = WS_EX_NOPARENTNOTIFY; - hhwt.nShowState = WS_VISIBLE; - hhwt.hwndHelp = NULL; - hhwt.hwndCaller = hWnd; - hhwt.hwndToolBar = NULL; - hhwt.hwndNavigation = NULL; - hhwt.hwndHTML = NULL; - hhwt.iNavWidth = 0; - if (hcontext) { - hhwt.pszToc = (hcontext->toc ? hcontext->toc : "html/orbiter.chm::/Orbiter.hhc"); - hhwt.pszIndex = (hcontext->index ? hcontext->index : "html/orbiter.chm::/Orbiter.hhk"); - hhwt.pszFile = hcontext->helpfile; - hhwt.pszHome = "html/orbiter.chm::/intro.htm"; - } else { - hhwt.pszToc = "html/orbiter.chm::/Orbiter.hhc"; - hhwt.pszIndex = "html/orbiter.chm::/Orbiter.hhk"; - hhwt.pszFile = helpf; - hhwt.pszHome = "html/orbiter.chm::/intro.htm"; - } - hhwt.fsToolBarFlags = HHWIN_BUTTON_EXPAND | HHWIN_BUTTON_BACK | - HHWIN_BUTTON_FORWARD | HHWIN_BUTTON_HOME; - if (bScnHelp) hhwt.fsToolBarFlags |= HHWIN_BUTTON_JUMP1; - if (bVsHelp) hhwt.fsToolBarFlags |= HHWIN_BUTTON_JUMP2; - hhwt.fNotExpanded = FALSE; - hhwt.curNavType = 0; - hhwt.tabpos = 0; - hhwt.idNotify = 0; - hhwt.cHistory = 0; - hhwt.pszJump1 = "Scenario"; - hhwt.pszJump2 = "Vessel"; - hhwt.pszUrlJump1 = deftopic; - hhwt.pszUrlJump2 = jmp2url; - hhwt.rcMinSize.left = 0; - hhwt.rcMinSize.right = 0; - hhwt.rcMinSize.top = 0; - hhwt.rcMinSize.bottom = 0; - - HtmlHelp (hWnd, NULL, HH_SET_WIN_TYPE, (DWORD_PTR)&hhwt); -} - -// ====================================================================== + char buf[256]; + HWND hWnd = (HWND)(ImGui::GetMainViewport()->PlatformHandle); + if(hc->topic) + snprintf(buf, 256, "%s::%s", hc->helpfile, hc->topic); + else + snprintf(buf, 256, "%s", hc->helpfile); -BOOL DlgHelp::OnInitdialog (HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - RECT r, rh; - GetClientRect (hWnd, &r); - dlgw = r.right, dlgh = r.bottom; - GetWindowRect (GetDlgItem (hWnd, IDC_CUSTOM1), &rh); - hfooter = r.bottom - (rh.bottom-rh.top); - GetWindowRect (GetDlgItem (hWnd, IDCANCEL), &rh); - pClose.x = rh.left, pClose.y = rh.top; - ScreenToClient (hWnd, &pClose); - - return OnRequest (hWnd, wParam, lParam); -} - -// ====================================================================== - -BOOL DlgHelp::OnRequest (HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - SendDlgItemMessage (hWnd, IDC_CUSTOM1, WM_USER, wParam, lParam); - return TRUE; -} + buf[255] = '\0'; -// ====================================================================== - -BOOL DlgHelp::OnSize (HWND hWnd, WPARAM wParam, int w, int h) -{ - RECT r; - GetClientRect (hWnd, &r); - int dx = r.right - dlgw, dy = r.bottom - dlgh; - SetWindowPos (GetDlgItem (hWnd, IDC_CUSTOM1), HWND_TOP, 0, 0, r.right, r.bottom-hfooter, SWP_SHOWWINDOW); - SetWindowPos (GetDlgItem (hWnd, IDCANCEL), HWND_TOP, pClose.x+dx, pClose.y+dy, 0, 0, SWP_NOSIZE); - return DialogWin::OnSize (hWnd, wParam, w, h); -} - -// ====================================================================== - -INT_PTR CALLBACK DlgHelp::DlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_INITDIALOG: - return ((DlgHelp*)GetDialogWin (hDlg))->OnInitdialog (hDlg, wParam, lParam); - case WM_USER+1: - return ((DlgHelp*)GetDialogWin (hDlg))->OnRequest (hDlg, wParam, lParam); - case WM_SIZE: - return ((DlgHelp*)GetDialogWin (hDlg))->OnSize (hDlg, wParam, LOWORD (lParam), HIWORD (lParam)); - case WM_COMMAND: - switch (LOWORD (wParam)) { - case IDHELP: - DefHelpContext.topic = (char*)"/help.htm"; - g_pOrbiter->OpenHelp (&DefHelpContext); - return TRUE; - case IDCANCEL: - g_pOrbiter->CloseDialog (hDlg); - return TRUE; - } - break; + if(!HtmlHelp (hWnd, buf, HH_DISPLAY_TOPIC, NULL)) { + oapiAddNotification(OAPINOTIF_ERROR, "Failed to open help", buf); } - return OrbiterDefDialogProc (hDlg, uMsg, wParam, lParam); } - -// ====================================================================== - -LRESULT FAR PASCAL DlgHelp::ClientProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - RECT r; - - switch (msg) { - case WM_CREATE: - //InitHelp (hwnd); - return 0; - case WM_USER: { - char cbuf[256]; - if (lParam == 0) { - DlgHelp::InitHelp (hwnd); - strcpy (cbuf, helpf); strcat (cbuf, ">Default"); - hHelpClient = HtmlHelp (hwnd, cbuf, HH_DISPLAY_TOPIC, pTopic); - } else { - HELPCONTEXT *hcontext = (HELPCONTEXT*)lParam; - InitHelp (hwnd, hcontext); - strcpy (cbuf, hcontext->helpfile); - strcat (cbuf, ">Default"); - hHelpClient = HtmlHelp (hwnd, cbuf, HH_DISPLAY_TOPIC, (DWORD_PTR)hcontext->topic); - } - GetClientRect (hwnd, &r); - SetWindowPos (hHelpClient, HWND_TOP, 0, 0, r.right, r.bottom, 0); - } break; - case WM_SIZE: - case WM_PAINT: - GetClientRect (hwnd, &r); - SetWindowPos (hHelpClient, HWND_TOP, 0, 0, r.right, r.bottom, SWP_HIDEWINDOW); - SetWindowPos (hHelpClient, HWND_TOP, 0, 0, r.right, r.bottom, SWP_SHOWWINDOW); - // there must be something better! (everything else I tried produces artefacts) - break; - case WM_NOTIFY: - // if (wParam == NEWTOPIC) { - // InitHelp (hwnd); - // hHelpClient = HtmlHelp (hwnd, "orbiter.chm>Default", HH_DISPLAY_TOPIC, (DWORD)topic); - // } - return TRUE; - } - return DefWindowProc (hwnd, msg, wParam, lParam); -} - diff --git a/Src/Orbiter/DlgHelp.h b/Src/Orbiter/DlgHelp.h index a862fe39e..65f8b7820 100644 --- a/Src/Orbiter/DlgHelp.h +++ b/Src/Orbiter/DlgHelp.h @@ -7,11 +7,12 @@ #ifndef __DLGHELP_H #define __DLGHELP_H +#include "OrbiterAPI.h" -#include "DialogWin.h" +//#include "DialogWin.h" // ====================================================================== - +/* class DlgHelp: public DialogWin { public: DlgHelp (HINSTANCE hInstance, HWND hParent, void *context); @@ -34,5 +35,16 @@ class DlgHelp: public DialogWin { int dlgw, dlgh; POINT pClose; }; +*/ -#endif // !__DLGHELP_H \ No newline at end of file +class DlgHelp: public ImGuiDialog +{ +public: + DlgHelp(); + void OnDraw() override; + void Display() override; + void OpenHelp(const HELPCONTEXT *hc); +// static void SetScenarioHelp (const char *_helpf); +// static void SetVesselHelp (const char *_helpf); +}; +#endif // !__DLGHELP_H diff --git a/Src/Orbiter/DlgInfo.cpp b/Src/Orbiter/DlgInfo.cpp index ff4c1cb34..157bdb8c1 100644 --- a/Src/Orbiter/DlgInfo.cpp +++ b/Src/Orbiter/DlgInfo.cpp @@ -15,6 +15,7 @@ extern PlanetarySystem *g_psys; DlgInfo::DlgInfo() : ImGuiDialog(ICON_FA_CIRCLE_INFO " Orbiter: Object info", {753,423}) { + SetHelp("html/orbiter.chm", "/objinfo.htm"); } void DlgInfo::AddCbodyNode(const CelestialBody *cbody) { diff --git a/Src/Orbiter/DlgMap.cpp b/Src/Orbiter/DlgMap.cpp index 797fb6631..4e34ddde1 100644 --- a/Src/Orbiter/DlgMap.cpp +++ b/Src/Orbiter/DlgMap.cpp @@ -24,12 +24,15 @@ DlgMap::DlgMap() : ImGuiDialog(ICON_FA_GLOBE " Orbiter: Map", {640, 400}) { selectionfilter = DISP_MOON | DISP_VESSEL | DISP_BASE; prm = &g_pOrbiter->Cfg()->CfgMapPrm; + + SetHelp("html/orbiter.chm", "/map.htm"); } void DlgMap::Display() { ImGui::SetNextWindowSize(ImVec2(defaultSize.width, defaultSize.height), ImGuiCond_FirstUseEver); bool visible = ImGui::Begin(name.c_str(), &active); - if(ImGui::MenuButton(ICON_FA_ARROW_ROTATE_LEFT, "Reset map")) { + HandleHelpButton(); + if(ImGui::MenuButton(ICON_FA_ARROW_ROTATE_LEFT, "Reset map", ImGui::GetFontSize()*1.5f)) { Reset(); } diff --git a/Src/Orbiter/DlgMenuCfg.cpp b/Src/Orbiter/DlgMenuCfg.cpp index 94f9d6830..edc8ff876 100644 --- a/Src/Orbiter/DlgMenuCfg.cpp +++ b/Src/Orbiter/DlgMenuCfg.cpp @@ -18,6 +18,7 @@ extern Pane *g_pane; DlgMenuCfg::DlgMenuCfg(): ImGuiDialog(ICON_FA_SLIDERS " Orbiter: Configure menu bars") { + SetHelp("html/orbiter.chm", "/menucfg.htm"); } void DlgMenuCfg::OnDraw() diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index e8e991a7f..c10a6357e 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -30,7 +30,7 @@ static int x_fixedframe = GetSystemMetrics (SM_CXFIXEDFRAME); static int y_fixedframe = GetSystemMetrics (SM_CYFIXEDFRAME); static bool doflip = true; -void RenderNotifications(); +static void RenderNotifications(); // dialog thread messages #define TM_OPENDIALOG WM_USER @@ -577,10 +577,10 @@ void DialogManager::ImGuiNewFrame() // Render notifications ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.f); // Round borders - ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(43.f / 255.f, 43.f / 255.f, 43.f / 255.f, 240.f / 255.f)); // Background color +// ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(43.f / 255.f, 43.f / 255.f, 43.f / 255.f, 240.f / 255.f)); // Background color RenderNotifications(); // <-- Here we render all notifications ImGui::PopStyleVar(1); // Don't forget to Pop() - ImGui::PopStyleColor(1); +// ImGui::PopStyleColor(1); // We can't use a range-based loop here because Show() may unregister the current dialog for (auto it = DlgImGuiList.begin(); it != DlgImGuiList.end();) @@ -607,10 +607,27 @@ ImGuiDialog::~ImGuiDialog(){ oapiCloseDialog(this); } +bool ImGuiDialog::HandleHelpButton() { + if(!helpfile.empty()) { + HELPCONTEXT hc; + hc.helpfile = const_cast(helpfile.c_str()); + hc.topic = helptopic.empty() ? NULL : const_cast(helptopic.c_str()); + hc.toc = (char*)"html/orbiter.chm::/orbiter.hhc"; + hc.index = (char*)"html/orbiter.chm::/orbiter.hhk"; + + if(ImGui::MenuButton(ICON_FA_CIRCLE_QUESTION, "Help")) { + g_pOrbiter->OpenHelp(&hc); + } + return true; + } + return false; +} + void ImGuiDialog::Display() { ImGui::SetNextWindowSize(ImVec2(defaultSize.width, defaultSize.height), ImGuiCond_FirstUseEver); if(ImGui::Begin(name.c_str(), &active)) { + HandleHelpButton(); OnDraw(); } ImGui::End(); @@ -983,7 +1000,7 @@ namespace ImGui { //ImGui::Dummy(ImVec2(0.0f, 0.0f)); } - DLLEXPORT bool MenuButton(const char *label, const char *tooltip) + DLLEXPORT bool MenuButton(const char *label, const char *tooltip, float xoffset) { ImGuiContext& g = *GImGui; const ImGuiWindow* window = ImGui::GetCurrentWindow(); @@ -993,6 +1010,7 @@ namespace ImGui { ImGui::PushClipRect( titleBarRect.Min, titleBarRect.Max, false ); float width = (strlen(label)+1) * g.FontSize; float offset = titleBarRect.Max.x - width - titleBarRect.Min.x - g.Style.FramePadding.x; + offset -= xoffset; ImGui::SetCursorPos( ImVec2( offset, 0.0f ) ); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0,0,0,0)); bool ret = ImGui::Button( label ); diff --git a/Src/Orbiter/DlgRecorder.cpp b/Src/Orbiter/DlgRecorder.cpp index 6009047ed..78b365421 100644 --- a/Src/Orbiter/DlgRecorder.cpp +++ b/Src/Orbiter/DlgRecorder.cpp @@ -15,6 +15,7 @@ extern Vessel *g_focusobj; extern Orbiter *g_pOrbiter; DlgRecorder::DlgRecorder() : ImGuiDialog(ICON_FA_FILM " Flight recorder/player", {329,354}) { + SetHelp("html/orbiter.chm", "/recorder.htm"); strcpy(m_ScenarioFile, "test_record"); } diff --git a/Src/Orbiter/DlgTacc.cpp b/Src/Orbiter/DlgTacc.cpp index ca2fda329..e2a3559ce 100644 --- a/Src/Orbiter/DlgTacc.cpp +++ b/Src/Orbiter/DlgTacc.cpp @@ -14,6 +14,7 @@ extern TimeData td; extern Orbiter *g_pOrbiter; DlgTacc::DlgTacc() : ImGuiDialog(ICON_FA_CLOCK " Orbiter: Time acceleration",{357,135}) { + SetHelp("html/orbiter.chm", "/timeacc.htm"); } void DlgTacc::OnDraw() { diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 8ecd78032..b9d78a584 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -666,7 +666,7 @@ VOID Orbiter::Launch (const char *scenario) LOGOUT_ERR ("Scenario not found: %s", scenario); TerminateOnError(); } - DlgHelp::SetScenarioHelp (pState->ScnHelp()); + //DlgHelp::SetScenarioHelp (pState->ScnHelp()); long m0 = memstat->HeapUsage(); CreateRenderWindow (pConfig, scenario); @@ -1214,7 +1214,7 @@ Vessel *Orbiter::SetFocusObject (Vessel *vessel, bool setview) it->pModule->clbkFocusChanged(g_focusobj, g_pfocusobj); if (pDlgMgr) pDlgMgr->BroadcastMessage (MSG_FOCUSVESSEL, vessel); - DlgHelp::SetVesselHelp (g_focusobj->HelpContext()); + //DlgHelp::SetVesselHelp (g_focusobj->HelpContext()); return g_pfocusobj; } @@ -2788,14 +2788,12 @@ HWND Orbiter::OpenDialogEx (HINSTANCE hInstance, int id, DLGPROC pDlg, DWORD fla return (pDlgMgr ? pDlgMgr->OpenDialogEx (hInstance, id, hRenderWnd, pDlg, flag, context) : NULL); } -HWND Orbiter::OpenHelp (const HELPCONTEXT *hcontext) +void Orbiter::OpenHelp (const HELPCONTEXT *hcontext) { if (pDlgMgr) { DlgHelp *pHelp = pDlgMgr->EnsureEntry (); - HWND hHelp = pHelp->GetHwnd(); - PostMessage (hHelp, WM_USER+1, 0, (LPARAM)hcontext); - return hHelp; - } else return NULL; + pHelp->OpenHelp(hcontext); + } } void Orbiter::OpenLaunchpadHelp (HELPCONTEXT *hcontext) diff --git a/Src/Orbiter/Orbiter.h b/Src/Orbiter/Orbiter.h index 204f3ce5b..e0e2498b8 100644 --- a/Src/Orbiter/Orbiter.h +++ b/Src/Orbiter/Orbiter.h @@ -96,7 +96,7 @@ class Orbiter { HWND OpenDialog (HINSTANCE hInst, int id, DLGPROC pDlg, void *context = 0); // use this version for for calls from external dlls HWND OpenDialogEx (int id, DLGPROC pDlg, DWORD flag = 0, void *context = 0); // extended version HWND OpenDialogEx (HINSTANCE hInst, int id, DLGPROC pDlg, DWORD flag = 0, void *context = 0); // extended version - HWND OpenHelp (const HELPCONTEXT *hcontext); + void OpenHelp (const HELPCONTEXT *hcontext); void OpenLaunchpadHelp (HELPCONTEXT *hcontext); HELPCONTEXT DefaultHelpPage(const char* topic); //void OpenDialogAsync (int id, DLGPROC pDlg, void *context = 0); diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index 617ca3941..15fc17055 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -2224,7 +2224,7 @@ DLLEXPORT INT_PTR oapiDefDialogProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM DLLEXPORT bool oapiOpenHelp (HELPCONTEXT *hcontext) { - HWND hDlg = g_pOrbiter->OpenHelp (hcontext); + g_pOrbiter->OpenHelp (hcontext); return true; } diff --git a/Src/Orbiter/PlaybackEd.cpp b/Src/Orbiter/PlaybackEd.cpp index 2e65ac0b8..4186059d6 100644 --- a/Src/Orbiter/PlaybackEd.cpp +++ b/Src/Orbiter/PlaybackEd.cpp @@ -18,6 +18,8 @@ static bool CompareEvents (const PlaybackEvent *first, const PlaybackEvent *seco } DlgPlaybackEditor::DlgPlaybackEditor() : ImGuiDialog("Playback Editor", {900,600}) { + SetHelp("html/orbiter.chm", "/playbackedit.htm"); + m_sysfname = nullptr; m_SelectedEvent = nullptr; } diff --git a/Src/Orbiter/TabOptions.h b/Src/Orbiter/TabOptions.h index 455bfeb31..9a864035d 100644 --- a/Src/Orbiter/TabOptions.h +++ b/Src/Orbiter/TabOptions.h @@ -11,8 +11,6 @@ #include "LpadTab.h" #include "OptionsPages.h" -#include "CustomControls.h" -#include "DlgOptions.h" namespace orbiter { diff --git a/Src/Plugin/ExtMFD/MFDWindow.cpp b/Src/Plugin/ExtMFD/MFDWindow.cpp index bc5ca3cf2..d55638e16 100644 --- a/Src/Plugin/ExtMFD/MFDWindow.cpp +++ b/Src/Plugin/ExtMFD/MFDWindow.cpp @@ -52,7 +52,12 @@ void DlgExtMFD::Display() { bool visible = ImGui::Begin(cbuf, &active); bool stick = m_mfd->GetStickToVessel(); - if(ImGui::MenuButton(stick ? ICON_FA_THUMBTACK : ICON_FA_THUMBTACK_SLASH, stick ? "Unpin this MFD from the vessel":"Pin this MFD to the current vessel")) + + if(ImGui::MenuButton(ICON_FA_CIRCLE_QUESTION, "Help")) { + m_mfd->OpenModeHelp(); + } + + if(ImGui::MenuButton(stick ? ICON_FA_THUMBTACK : ICON_FA_THUMBTACK_SLASH, stick ? "Unpin this MFD from the vessel":"Pin this MFD to the current vessel", ImGui::GetFontSize()*1.7f)) { m_mfd->ToggleStickToVessel(); } From b10293f18639370af2d669e640ed3effa8907a3e Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Tue, 11 Feb 2025 15:15:06 -0600 Subject: [PATCH 30/51] SDL3 Port [WIP] Beginnings of SDL3 port [WIP] Start refactor of launchpad Start Scn tab & change font Move Src/Bitmaps to Textures/OrbiterCore Scn desc & better ImGui ctx Also started porting some old HTMLHelp/HYPERDESC scenarios to the new Markdown system Finished porting scn's Update scn. dev docs Disable imgui ini and logfile ConsumeEvent quit outparam & launchpad config Fix markdown h2s Unload images on scn reselect Checklists/Quickstart: h2s Save scenario dialog Also, some fixes to ScnPath that 1. makes it thread-safe and 2. makes it not crash half the time with long strings Detour: modernize paths & some assoc. strings Remove some now irrelevant comments [WIP] Testing the waters Nothing builds yet. This commit may be reverted but it removes (most) of the windows-specific includes Revert "[WIP] Testing the waters" This reverts commit fde97e13e0f98bb3ddba199c089f072e90329495. Safety wrappers [WIP] MFDAPI: De-Windowsify Can't guarantee this works right now, hence WIP UIUtil: Make ImCtx more generic More work Sorry, I don't really know what to call this commit. And it breaks things. And it's too many unrelated things. It'll probably be squashed anyway eventually so it probably won't matter (famous last words) Enforce C++ standard TabModule: oops forgot the buttons TabModule: oops forgot locked items Automatically convert many files to UTF-8 About tab work and fix module loading Oops, more printf issues Properly center about tab (Mostly) finish about tab Remove old about tab code comments Refactor away some complicating templates Options tab This also messes around with some other stuff I found while doing the options tab (e.g., Markdown link color, the theme, cross-platform paths, etc.) Revert "[WIP] MFDAPI: De-Windowsify" This reverts commit 0109d670 Remove some overreaching changes Per feedback. D3D9Client still does not work, but I'm working on it :P Revert oapi::Font::{Width, Height} Probably could be better in a different PR sdl::UnmanagedWindow: not a stopgap for now SDLWrappers.cpp: fix build on release UI options: font size Start getting things working again Some small fixes No point in switching to float SliderScalar exists; making a "Reset" variation isn't the *best* way to do this but, hey, it works Sadly we can't do templates across the DLL boundary :( Probably helps to test changes first Fix a few things Reintroduces one breaking change but like, it only happens in D3D9Client and is a <5 line change solution so it's not a *huge* deal --- .gitignore | 3 + CMakeLists.txt | 4 +- Extern/CMakeLists.txt | 2 + Extern/SDL3/CMakeLists.txt | 28 + Extern/SDL3_image/CMakeLists.txt | 39 + Extern/imgui/CMakeLists.txt | 3 +- Extern/imgui/Inter-Bold.ttf | Bin 0 -> 420428 bytes Extern/imgui/Inter-BoldItalic.ttf | Bin 0 -> 425296 bytes Extern/imgui/Inter-Italic.ttf | Bin 0 -> 417388 bytes Extern/imgui/Inter-Regular.ttf | Bin 0 -> 411640 bytes Extern/imgui/License-Inter.txt | 92 + OVP/D3D9Client/CMakeLists.txt | 8 +- OVP/D3D9Client/D3D9Client.cpp | 442 +- OVP/D3D9Client/D3D9Client.h | 29 +- OVP/D3D9Client/D3D9Config.h | 18 +- OVP/D3D9Client/DebugControls.cpp | 163 +- OVP/D3D9Client/Log.cpp | 2 +- OVP/D3D9Client/WindowMgr.cpp | 479 +-- OVP/D3D9Client/WindowMgr.h | 18 +- OVP/D3D9Client/gcConst.cpp | 16 +- OVP/D3D9Client/gcCore.cpp | 20 +- OVP/GDIClient/CMakeLists.txt | 4 +- OVP/GDIClient/GDIClient.cpp | 20 +- Orbitersdk/CMakeLists.txt | 2 + Orbitersdk/include/GraphicsAPI.h | 121 +- Orbitersdk/include/ModuleAPI.h | 11 +- Orbitersdk/include/SDLWrappers.h | 63 + Orbitersdk/include/imgui_extras.h | 1 + Sound/XRSound/LICENSE | 2 +- Sound/XRSound/src/CMakeLists.txt | 7 +- Src/Celbody/Vsop87/CMakeLists.txt | 4 +- Src/Orbiter/CMakeLists.txt | 6 +- Src/Orbiter/Camera.cpp | 96 +- Src/Orbiter/Camera.h | 22 +- Src/Orbiter/Config.cpp | 40 +- Src/Orbiter/Config.h | 33 +- Src/Orbiter/Defpanel.cpp | 35 +- Src/Orbiter/Defpanel.h | 4 +- Src/Orbiter/DlgMgr.cpp | 247 +- Src/Orbiter/DlgMgr.h | 16 +- Src/Orbiter/FlightRecorder.cpp | 2 +- Src/Orbiter/GraphicsAPI.cpp | 327 +- Src/Orbiter/Keymap.cpp | 166 +- Src/Orbiter/Keymap.h | 18 +- Src/Orbiter/MenuInfoBar.cpp | 12 +- Src/Orbiter/MenuInfoBar.h | 4 +- Src/Orbiter/MfdMap_old.cpp | 10 +- Src/Orbiter/ModuleAPI.cpp | 2 +- Src/Orbiter/Orbiter.cpp | 565 +-- Src/Orbiter/Orbiter.h | 28 +- Src/Orbiter/OrbiterAPI.cpp | 5 +- Src/Orbiter/Pane.cpp | 34 +- Src/Orbiter/Pane.h | 14 +- Src/Orbiter/Panel.cpp | 30 +- Src/Orbiter/Panel.h | 6 +- Src/Orbiter/Panel2D.cpp | 53 +- Src/Orbiter/Panel2D.h | 14 +- Src/Orbiter/SDLWrappers.cpp | 72 + Src/Orbiter/VCockpit.cpp | 30 +- Src/Orbiter/VCockpit.h | 6 +- Src/Orbiter/cmdline.cpp | 36 +- Src/Orbiter/cmdline.h | 20 +- Src/Orbiter/imgui_md.cpp | 912 ++++ Src/Orbiter/imgui_md.h | 173 + Src/Orbiter/md4c.c | 6492 +++++++++++++++++++++++++++++ Src/Orbiter/md4c.h | 407 ++ Src/Orbitersdk/CMakeLists.txt | 2 +- 67 files changed, 9932 insertions(+), 1608 deletions(-) create mode 100644 Extern/SDL3/CMakeLists.txt create mode 100644 Extern/SDL3_image/CMakeLists.txt create mode 100644 Extern/imgui/Inter-Bold.ttf create mode 100644 Extern/imgui/Inter-BoldItalic.ttf create mode 100644 Extern/imgui/Inter-Italic.ttf create mode 100644 Extern/imgui/Inter-Regular.ttf create mode 100644 Extern/imgui/License-Inter.txt create mode 100644 Orbitersdk/include/SDLWrappers.h create mode 100644 Src/Orbiter/SDLWrappers.cpp create mode 100644 Src/Orbiter/imgui_md.cpp create mode 100644 Src/Orbiter/imgui_md.h create mode 100644 Src/Orbiter/md4c.c create mode 100644 Src/Orbiter/md4c.h diff --git a/.gitignore b/.gitignore index e94cb6340..6677091c7 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,9 @@ Sound/XRSound/**/Release-with-OrbiterRelease/ .kdev/ [Bb]uild/ +# CLion-specific files +.idea + Extern/irrKlang Doc/**/*.log diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f1c284ac..478eee3ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.19) project (Orbiter VERSION 21.7.24) set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) #Add /permissive if using C++20 or higher @@ -83,7 +83,7 @@ set(ORBITER_INSTALL_DOC_DIR ${ORBITER_INSTALL_ROOT_DIR}/Doc) set(ORBITER_INSTALL_UTILS_DIR ${ORBITER_INSTALL_ROOT_DIR}/Utils) set(ORBITER_INSTALL_SDK_DIR ${ORBITER_INSTALL_ROOT_DIR}/Orbitersdk) -set(ORBITER_SDK_LIB $) +set(ORBITER_SDK_LIB $ SDL3::SDL3 SDL3_image::SDL3_image) set(ORBITER_DLGCTRL_LIB $) set(LUAINTERPRETER_LIB $) set(GDICLIENT_LIB $) diff --git a/Extern/CMakeLists.txt b/Extern/CMakeLists.txt index fcbee56b4..0dea842f3 100644 --- a/Extern/CMakeLists.txt +++ b/Extern/CMakeLists.txt @@ -7,6 +7,8 @@ endif(NOT DEFINED ORBITER_BINARY_ROOT_DIR) add_subdirectory(Lua) add_subdirectory(zlib) add_subdirectory(imgui) +add_subdirectory(SDL3) +add_subdirectory(SDL3_image) ## LFS add_library(lfs SHARED luafilesystem/src/lfs.c) diff --git a/Extern/SDL3/CMakeLists.txt b/Extern/SDL3/CMakeLists.txt new file mode 100644 index 000000000..89615a043 --- /dev/null +++ b/Extern/SDL3/CMakeLists.txt @@ -0,0 +1,28 @@ +project(SDL3) + +Include(FetchContent) + +FetchContent_Declare( + SDL3 + GIT_REPOSITORY https://github.com/libsdl-org/SDL.git + GIT_TAG release-3.2.4 +) +FetchContent_MakeAvailable(SDL3) + +set_target_properties(SDL3-shared PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${ORBITER_BINARY_ROOT_DIR} + LIBRARY_OUTPUT_DIRECTORY ${ORBITER_BINARY_ROOT_DIR} + RUNTIME_OUTPUT_DIRECTORY ${ORBITER_BINARY_ROOT_DIR} +) + +set_target_properties(SDL3_Headers PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${ORBITER_INSTALL_SDK_DIR}/include" + LIBRARY_OUTPUT_DIRECTORY "${ORBITER_INSTALL_SDK_DIR}/include" + RUNTIME_OUTPUT_DIRECTORY "${ORBITER_INSTALL_SDK_DIR}/include" +) + +file(GLOB SDL3_HEADERS "${SDL3_SOURCE_DIR}/include/SDL3/*.h" "${SDL3_BINARY_DIR}/include-revision/SDL3/*.h") +file(COPY ${SDL3_HEADERS} DESTINATION "${ORBITER_BINARY_SDK_DIR}/include/SDL3") + +install(TARGETS SDL3_Headers RUNTIME DESTINATION "${ORBITER_INSTALL_SDK_DIR}/include") +install(TARGETS SDL3-shared RUNTIME DESTINATION ${ORBITER_INSTALL_ROOT_DIR}) \ No newline at end of file diff --git a/Extern/SDL3_image/CMakeLists.txt b/Extern/SDL3_image/CMakeLists.txt new file mode 100644 index 000000000..6947b0a41 --- /dev/null +++ b/Extern/SDL3_image/CMakeLists.txt @@ -0,0 +1,39 @@ +project(SDL3_image) + +Include(FetchContent) + +# These formats we need +set(SDLIMAGE_BMP ON) +set(SDLIMAGE_JPG ON) +set(SDLIMAGE_PNG ON) +set(SDLIMAGE_GIF ON) +# Disable auto-enabled formats that we don't need (which add some additional dependencies) +set(SDLIMAGE_AVIF OFF) +set(SDLIMAGE_LBM OFF) +set(SDLIMAGE_PCX OFF) +set(SDLIMAGE_PNM OFF) +set(SDLIMAGE_QOI OFF) +set(SDLIMAGE_SVG OFF) +set(SDLIMAGE_TGA OFF) +set(SDLIMAGE_TIF OFF) +set(SDLIMAGE_WEBP OFF) +set(SDLIMAGE_XCF OFF) +set(SDLIMAGE_XPM OFF) +set(SDLIMAGE_XV OFF) + +FetchContent_Declare( + SDL3_image + GIT_REPOSITORY https://github.com/libsdl-org/SDL_Image.git + GIT_TAG release-3.2.0 +) +FetchContent_MakeAvailable(SDL3_image) + +set_target_properties(SDL3_image-shared PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${ORBITER_BINARY_ROOT_DIR} + LIBRARY_OUTPUT_DIRECTORY ${ORBITER_BINARY_ROOT_DIR} + RUNTIME_OUTPUT_DIRECTORY ${ORBITER_BINARY_ROOT_DIR} +) +file(GLOB SDL3_image_HEADERS "${SDL3_image_SOURCE_DIR}/include/SDL3_image/*.h") +file(COPY ${SDL3_image_HEADERS} DESTINATION "${ORBITER_BINARY_SDK_DIR}/include/SDL3_image") + +install(TARGETS SDL3_image-shared RUNTIME DESTINATION ${ORBITER_INSTALL_ROOT_DIR}) \ No newline at end of file diff --git a/Extern/imgui/CMakeLists.txt b/Extern/imgui/CMakeLists.txt index fbd0e3d7e..fe7b6f581 100644 --- a/Extern/imgui/CMakeLists.txt +++ b/Extern/imgui/CMakeLists.txt @@ -11,9 +11,10 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(imgui) -install(FILES ${imgui_SOURCE_DIR}/misc/fonts/Roboto-Medium.ttf fa-solid-900.ttf ${imgui_SOURCE_DIR}/misc/fonts/Cousine-Regular.ttf +install(FILES Inter-Regular.ttf Inter-Italic.ttf Inter-Bold.ttf Inter-BoldItalic.ttf fa-solid-900.ttf ${imgui_SOURCE_DIR}/misc/fonts/Cousine-Regular.ttf DESTINATION ${ORBITER_INSTALL_ROOT_DIR} ) +file(COPY Inter-Regular.ttf Inter-Italic.ttf Inter-Bold.ttf Inter-BoldItalic.ttf ${imgui_SOURCE_DIR}/misc/fonts/Cousine-Regular.ttf fa-solid-900.ttf DESTINATION ${ORBITER_BINARY_ROOT_DIR}) install(FILES ${imgui_SOURCE_DIR}/imgui.h ${imgui_SOURCE_DIR}/imconfig.h DESTINATION ${ORBITER_INSTALL_SDK_DIR}/include diff --git a/Extern/imgui/Inter-Bold.ttf b/Extern/imgui/Inter-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9fb9b751e5b2441054f6eef670da7b3f53a3505a GIT binary patch literal 420428 zcmeFa3%pH58$UklGPBk?$K?=*gpPCFXYYN^kq&X(@0XB}bdw56k|aq;MM)~D@JhP4 zB=tr@Lh|aSNGa*^mM*Wnl5~?Ko%Q=Z&)VDG`<#7lq~71}|KIaj-}S6#o_S{0ta)Z; z&7N5!G$BMafGLtXcj(w@#@Tmw5<;sBMy1ZZ&gs*2#*$ZrkUpVZvb%Gi^V&JrJuZcI zMI|9F?RQR}yhbUtpL|kin+8G4z$>n~Y~=Vv-y=YVgRRZrV7Z zuDTfV-wRFXq6#SdjIE#_#qm#YmubmD(`swefYY^q03X&q0)C?X2K-&`A~e05z5uvL zUj$sDzX9B$Zv(!oZwKzwcLVq6M}dU~eIkWKII!X5#M5hfUnIx!imn_=33^xYhg*@W19az;DeTfIpc( z0S`(%XlY2KM^=`Vfk`q6SY4h1tSM^&PnGq7SuzV4ltEywJOg;9L^@?t*%VkHTLN3l zw!p5kEAVW2Ht-yI4)9#r8+d`d0C%Z z0&cfZHmvup_ksJY!@%FH--KaHdx+5Nt8Bz&@3MCRzq0=e{yuv@=pXGLh2{vS3b3kE zRT$2xP94y7oqE6&Cl#3PAh(@t2c^O}(?LEvXF14cr=^2@cG@^?fbE?2z>ZEwU{|Lr zu!qwFc#eZScg}Ur1@>|J0MB>M2VUeL=bdYvQNRh#t-#xzJArpOxKrnT=V{Y(I1+npW2kDZT!pE+LxzezypP3W62Mi>bMc>7uGIIynrff=R_#~csRPK-{~-4J6J{nnknmu_LkY7ImM6TB@KVBm5`KfW0gx6V zMHGkxxL#teSSeVk&Fa#7fjH0<}k7)WkT8XG7-|q4Vm{d2Q&t zLA(b!suvY%P)&S1x z=7q?f%u=H>`ldgTF(bWpdSAHu=>s!9&Fqjd3RL~{A?fWx?m|9an7KZEKcog`R!P4w z#&yX^N$&}VGh6|jN*|ftGjrlG4daecq|?)vo>`dghnoy{Awu`XL01FQpGm(ryNtn$hs(2@=ME_R#og|1NMe`J)kfZKwcdntaqF5+;ee#Y`$ecQC-&^s zJCyrW0z3;Ysm!`(#)hRUs&~Ub_t`KNIlC`MXpail67B=xde)s@xEIH-5y|MM?pb5_ zKHT1j^9J{uh-@@PWiO<^GVzIy)V5oyy6_xdY=`RP^LWT<82d)#}&gVp^b~Ssu=mQE@JhaR+e~t|8U;M z_xwh z*Z$pV5j|ll-g{Em@2@<&A4kXL{wMnCB++O6iF!}{6LrN=RsMMJps57Tk|BDv{)cU%gh0!9A=5XG(lS#n;u&mj-civLwVdfyEH+#fZVe>jjT*s(idvKscYjf3+|x@b%8kADYGIGZ?_5=(E2dW+ zD_{JI-n!i%irY+a$uK86r{X=mq9Y68aM5RssiW?tQRid%AJs#1zaUv^5qXq&5?vMl zd2K7Dyjb4`|CV|`_uep7zO%b16pmZfvc@DM)>Z7^!DQ0oep0?zOO|qO@m;OkV|vlIxt3mAEgK?1yLhZrC@vPv_1Hb0cSWRiyrn zaQ|wmd^u3oe{?63>e5r-ZbP1y(CSwp){=Wb6;Kji)T@Q!`~5ZC6YtxfcskuU|L`BD zR;>Ut^f0GsE>IMFK{U-@0_S1oUl$d*E1@FZR9q!TQaqn($b{ z8q7}m7XO=A@J0Wq0JU4eCLx+9;EWNq0+gzP9SCn?_7duFnz9+FjyP%(GmeU92tA4rrsbAG9Od2IDv5ckNBnG5cy;We3?ouZ=ly zNMqfY5N)g` zGl>u1NsQ|_6mc@q=YR&0A#~EC-i4elSGdcdZvZIxgPIQNes>)tZh%}@_Zf8#`Z&5; z;C`r<;U5!{n}gJ>5C+M~T{u3+e}{&e>8@1|xWA}5=s6i`4dh?Mu@D8-(dZLvx`(J+1~wGc5(N}2i*V4_X@v}?-x#2KjNK58MEC5 zi1!BhPgfun&E;X-iG@3f7v>udVx3hhxy$5dh;J8;&)pjk*BtAJdxQNpj%_%$BcB|^FiCEK#5SDY!Fi`k zcQeT<#MyNx+4yf-RDz!E(6b$SwyOl>R3eVbIFfMGa({u|?a;d&dbdOGc2Sx0dWAa= z`k#XS>Cpca^iPL=O5+MVuVskmDa11!@jQiiri&`_UEIZX9G|(bAih@+-z)UQq5l=z za2MDnj<-Q?!?E3c#Yu7(IMqW5m@AM+=T~0OD+p z_?jp9+!YDg?ux`VC=W>pF$p0$$*p*%Z}W5QB=;b{ZRERyqq6%R?)5!Y4fJxP2c->~ zIzdw>8)3v5n2+31yIXYR`_95S54qnE#~C=9;<`DG7C2hs?pnENvMtW-kQeQ7?uer^ zjxIR5;^+qdvvKYY|DHH6f{x_~yTTnHU&8qt;Ao4Z9gg-m=ne+p{0ID9cUfX@(Gj&kH_=t}K}~Qe=0+x>Citgl zES8B^MLTVbHb(TT8<9XMQVczv} z@wm|i^Q)Kgoa(1}PW4*Mrk*KYG8>tV#CEeUW_*`A6E)-v?i`B*AD|M;5RQyK` zQ&)@KJS%t)W&-QtTkAUOIsjkr@uRieS}uOFR$42? z&(_PI@uOR^W(i?rJIGJBbJn*F@}yjIs?Yw6BpXNs2LJm5T}WjT*Jk7|Brm9tt4IBT7?T8{IQvq8&sHaZ)%hBT*FJHvU; z*`eh-hnz#&SqUmZX_!+iMjNxuM45&hMDEF!vXyKvJIYS73ubcnkhjU( zQ67|sBW_-G%MX|Y&El5SS_tqR%@$`)z)ffwYLUXN31`rLd&&PXw`DT7Xep2J%`N{cp8@D*7X>8*dm!BHB z&i6GI`MLS|`33oH@;l{s&+pxMGI(Q)amVKOZwzCK=kf>T zzDiNg*Lx!2{G|Mw7tWW^{Y37>ORJZ@8I5Zr5B$e8R>xHngsvSzKk~djcqG#hyoQaZ zfin%%Jk*cFa5N9qj|J!_y(R{sr}Uv1EI!6EfH7KI)RIqX6SaxrGi{0XhS;Tjgw-j9 zSe^2{aIre2zE)FD)7xsz^!|E(tv}V9+6DS^`U>qPeWm`ob~CM1(e9;{D%wmV+32i2 zX!J4qXs;U&7_+oDunOgUZ3|YR9M&!4sBu)ULn}}8)6BEXv-G-VN3)||k5-B3^=So& z-cX(*Ptnhyx>avP>oN2*u@WOoZ%lQl-bCf8JpC-n9KES(uA1x3RBP2*FTmQ2{(5t& zPxTgRpc<&RR72Ddy_FiShU=}>NHtP#Lv^d(){>UeJJBi&y$e=ZT&s7b8dmRS-DusY zpKVRBCg|O*TdZ639@g#F?Rrn^PU}wn9IU%|M(;&+u70ky%37uOw$@qe^gh;0)=PR{ z>tEKt^z*FOtk?8@SbdS8pHDTfeu;gmU01)%PPhH~V7sy1QXg)2usi8D*xl?t`dF%k z_1o;r?IHRd_I37+`rYqn_>`nSA`!)M@eYO3jy+vPRe`|lMufxiXbbURo*3e&~I$D1jD=x0pH#)PN+4{en ze>nfpUvZvrp3q;VI$D2?>S+CS=N0EweY5k1^M?MG^Odt(-{O4Ze4}r3_B;Facbo&x z0sUR)N9RXosg){Q4=m6fps zYpTvNUNYO7ZHYJGPw06pD zjI~pFW)te6m`$;2s)gB%Y|Lx{8*5{>q7_bNf2?r2&b-VrEM;Ctc4FQDI~i$?u|`=p znq#e-tO@2sSjbfKc38zf&3mk6)++Np>ji6_IScmiy7@4zMlu({5-OQ1?JBn4TyF>M ze&)w0@k6AEl}XRZ>h?-|wY-SRv>ZTXT3$wFT3$|NT3$hAS`J2;-YAz0i=}d8^$Z5`<&YkjZ z=OJgdoKBV??{gk@9+oqlN1R9G{mx^~V{#^JW1)P&S?#Qrv&cf^Y_bqJhb%lrOJNlgwd!mS zH?ciTrd5R6Otyq~X%(UN18iWR-b%k5?mT@EN^w6f_Y=9?-^S(sL0Vm?Kg1<|6_@xI zxx}yI68{#L_%Er%8v!oy&A7z3=MvwWOZ<6U;;*4~g~nPg>)W}kzfbE5jZe75|C>wv zr?jrn_>tBX8V6}zp>c@T6&gpduCTpPNH$OdPDOWtT(J_J}YaY5kzAiuHpp$?EE5^|CyLRuRe?w2DyHq*a8n7Of(bwQ2pJ zJe5`s$~t7L@^o4`C{t+VplnVn2W3lIIVfAv%0bzhRu0OGXyu^1gjNp90c5N4Qd%=8 zN6?x<`7W&)RAD@uiAgfakkkzT#v>s5+Axl$_lclLA$kNmTSlVxDA=#LEifl|Rg^k(j zX<8eomeG1ZwVc)is^`ew)Jn29wTjjNs@1gaPraaj60CBf&Tsk?{7L>~e_ekYf2!XX z)|XxAQE~i($Mf^&27~_o{(S$d{sP3*$=}`I+u#3~raOXg{sDv~JO5nB4Dt{2kMxi6 zkN4l^pX$Gt!#zkoa81j0{>S`_{m=MU_}BP1AT4iE2>-kOogA`J@K19A;s4bCm4C1Q zfd8QX28P8zdlesP&-hcBm(KosS`XQ7ibs?-ywKnE+u#( zZfJ06#ay6Cuoc|szrb|}F85rZMVPAKd0cQ@pj{AnoGvq1rVDg|43+YW%N56nK+oXi zfxdwY0|Ns?0>cBN0%HRc1Cs;O0y6@$0`me-1Q!OD1fC7746Ho*DZVwn||2dV=b?^ZFr?UY~j&mIb5D1B_sA}hn`B* zv+!~$x*RW!lN&+QD3ni4gF{hzMnp-pf=`EFH}HG04c-B%%W*|=BsrR8>CPtMm>!&o zGCK#y{NTdiQu#t4^F&=%^{m=i^|R8m{83CdL-@s2mVPbHt=fWV}(UDiigyRvp??aTTh>rmEFpH3lswyz3@oEeC6!I81fSHo8a zobjwo#zD!@x*T~n@*NXJ|Iz+Vlx`Cck-1&O>`UU34cfN}Q zg>hY@zzI0tvw_VNnjQ^^Ne2_KhQd-z4G$S`~NcC;0PC4=HGZ z_3+2-0v*WtW_ssiYw5#l{JnD%-yGi@UX@QP^N-5~bA1Z~-O^k5=40(XoNr-zi$J%) zC&is_sc&iY{RAJ2zVhhQDkZr`xiH%K)(4P|l3ie_ZyNZxMVj_@M6--zRhqJ{XOhIk_ml51Lap}|5*Bfr0>$0M0e0D@cdjT>K4m8q&$;q)0+$D; z1}=vi8W@_LL>P9#f{-gx2gcTj-c@#TaC~4yF*h!|e|B9sUv_SGes)22o9s^6-LrdV zrxxS%4<-c0We*6}4JKy~${rR>3KRyrSKMWf4EC;=D^ETJ`&Z0mk0BR040o*6MqcJ; zkI%j>=nKqG+nYT#kePiiTHV6z2dTx+o}2wx_Tubk(hg*Qn!O@>P4F_v|5*P-|78C({|x^u|2(vMnSpWsC(h z|Lgv(Op(t=>6O6W<=^e!7pUR?0pSked^8IK>4B6$4LCbcCA~URbX6z4Hu%)1m>C?2 zmT(T*AgZ@eKf#(-!zMO`dqsT4{ZmgToLA}f1JgtO3hpVOrH3A`E#}rYwq^BNzHmE7 zty-}bEI7z(kGLJ;_J`Y*>EZrEbdy3gI_jKIZB2EpS3<(IBWlV}-FK}1im822i+Hs} zq=xWnfsma?**Duy2nXj}H8Vo=_6{9^-<^!McG-!QAwA z!Tg9E*WIN)34}`yY=)MR>3-yHA)e8WU@qF1F9Lf4`|(T;!xD$#pnMw;Ob8}XOvuSp z#N-R+Qj8QQ?xGF8Gt(};VXzbIwl^r$Ot6~)c$UNP^v0m3xGgv}crV(GcF4QAsa4dA zfs_VA8Z-%1VV8nZlhWWq&?$TX8?15@4R$x!*I*xWaoymDK&#X$ z4GyLCZg4bJ_dnqum1?I}p|GhnaMXcINzKfeMJ}}wTrhNQ8jqKko0pr~3a$gr-Ej0G zj^|P@POF=GdFs&A5vik7$E8k6y(6_>>cx4vMY)jnrA|-%0yq=LW_EK@x20~z)qK8M znCF8VgzHaIzeru0UORPp+M2B4sjE}hr*4A8w$vS|pTPHvz!zx+C^K|UC6~G<&6k!M z_#$;bU;RWrsfSYw)6BGlw4}6T|Jby;@bRVPrsY%Ev`%SlaKPmj<`$-PPwUR--dS67 z3-b!n`sWpp3tUW?HXv;f&fU|7rH#z%9(FnN(#E8X2abokEoWZX<>jZ{3pX`=a@xIl z`NR#3OZznK8SX)Io0aw;EN>hgM5WCopR~u=|5#m}O z)80yZmqYFZ_fw`mP5TOEY;W2D-yKxK(vAei<+e%}bik?fO1Z59({WWjy>`wM^fpF_ zBR%H{a&%7j=XS{LklqkS6QXc#;T!5v)F_(-J4Xn<~PoJ1RIWM1FZnyN6aI^6BsA=gdbGzYs2IK4C&BK?V zmZU!m|F!8G(_hc+ma{Saz4Wa(-pkn-cBnn}1oouw1|ClTD1BG>3LI)3_hi`M@AGI- zKcpXGn*89>k7npNLn@nI2 zhI&^SBXAD8WTG-gXN=1j$2_`DM!4j>{uy&J?#P&#F&)Qz9CLsRbB>bBSPr)|bY7jY zK4U%VQFgWJ)~cJaDcC7vGu$?ucX<4a{k2jvKJnE6e!=wq@i<|hyfJxW zGVyYnnVXrPH>OtIEJ5idmsdA;PAwd{b21CUyqrUM!*ajKY{NOtt$SuC%6B@5%Ir=) znZ3Oy6UNN`nf)Un;2#PR_K!V7|Cr1{IEH181dh)fpI0|$3AxPMGH(M;r33EX%m;Ip z1joSVS#p_kGv^ZGcr3)hIdgI5GdU}BR%WgsWNJ<5ydh_8*k!)zQJHTwXqfqK<^kZ& z%)RVB&D`6dA-V9GsLZcCUKmLde1xMM%RETA=H*`U@^IeKnRp%&MR}chB=-|f!pr&K zgL(b46x!FtS(SLKsWy#A1s4Yw=N_g}socZCS24cyDzF8OH)S;>im#h6uO0bj^~~yv zF{Aguf0rCajRxWvLUe9QU|iOctl@BDvnC!J^Pv%+QN=h*vYw^!o7|MFjTpaqJ+~F= z^L~MGd2_Sg!|_q>#pLn|ayww0W*3drpl(aaYm@bZZ(P=)+zxq3<#9B!6D60NmrP?k zzAAa3qTI2XAY3DqekQA_l}h$i)RB#ad{Zzo14mCF_DOlqgv)>E`Q)Wm%;nA`$ELNE z^lrW58jXQ zhU+WLHnS75ld_ZXb{Bq|i+;oFpFM!yqQ(db`OjMDK1K-f^bEO~jkd41U+4_Z#nhXEHc5@Xj(3$1JAlnz-Iu z&~E<^{(0zwEy4TEv!Lni=P1s*{2Te*hx~u=e?)IT;1NxZxchJ%@*l;!k4^nD>Ye1w z%WakOgjX-tqPpf;)DUaAPg?`&tb=1xZV>M}!Msj^M!_R^8)=32j2(EpK(8%Fq z@_eKTZwHs>bq@?hA7w;Nee@yFvu8IcfF~4~p7TUtCLMt}xgF@OD%PPbUrKLSIkov6 zYjbY5z&7+&cjUA{@5}4aQ=gvRN~u?GqGulN&!?h|%Jq8j)PK(zRV$U=zQc8Wuy@{= zVE zNluHLb~#;gdL}Q;>6>$5&cK`@Im2^C;c6^fDC@|Xm@_$NTF#8ppBML8UeDQ@^IpzJ zIlEBz)XmwQ*FR@p&JQ_cn+#WZ?J zc$U3#`=MsLJa=gBh}_Y+<8miK;*Q+uY|~V?&(B?$yA<}hJa={O`rJ)<{c|_xZp+<~ z`$_V0Y9Vv?s|u)L9InaAhdmNzx;UbqJlVs7&4yvHyjqyy$c-7SPM+n6nM%#%pOssNgOZ1U`5 zCG#-**pm4&UnKDC<3!n9w#H2Owz8e5h8eXz#VK-_946|@;c~dBhwmSc5cTDC@;Y%k z=GopOQsitoTLk4?`KZW|kITo!nR0<#Eb{Sn7}W^x(kbr)d%?en4q=HR|0 zTFIB?%c29#!lilMa=Yk^8Mr&eIhcj}x#%UolwXQIa<|+g`pUiXTX8;S}IuKFZCbC==DWOq_x;u>kZ!xe)wCa*;@si&07( zE+r0^60GEq%S3C;(_W5ySs_;l8)ao3;#x1)3qR&;zXX~}jDZsK7FJPgky}twF@qcH zFt*8U;JhQ>0q0$mrvxrfSkZywO1WP7UuSJ6zx0nammg=$-WV*ea7Nj;`P-{Y8>dB)y<&CtMQ;Gs0pH_ny4m< zX6hE$fDRkLY)Z^azY7&AeRaGJ+e2HnhZNYuL!vq6tj`inVHI=W`w!SgL$-|?Y#W(u z8$q^>nlzUk>zgo}9Z0revu)V0jTWFWw_PM+c6)navYnWi-F`$^*6-F)Au-SW4^ahk z-3vt}%e7ol1#{l2f+~vO_6n z%9)}eTVoBj#`{0esm+h?{+gn|>w|Z=Ey8KE03`w#&DSwf_fF|41 zPjkn1DtL06t>AEwn@o0na(z8vrVS6O`gIwnZ!1E zI@_ed-|lb3mYKkonZ}mcnr-qlw#fvx$rfyrn70O-Oi;a5Z&6G2#aI4ou}zw6jdj=# zO}4}4Y=>vD9hz*1Cfnf|Y=_Bey1EB8e;@V$$YyIiRXwO4M6E$K*^F(niJGlui(IzG z>THdvY>j!AhLul-RoTMYLMzFtCUmw&i>=XOYqZ!JZMH_kI^Q~9VVhKJlMdTt4SR=;wWe&D%Kp&)P$;&~M7GZiw$CiK&kVNDEVj=~wok=vqs5jf zxox!AGOMy>;>+=W+<~0XwBeY~s%i8UJnfI$E$le($F0^^;Lw_QP0L{ZET$8grmz2C zRV<m`(V{)3P>jIiWU2Vok2Ll4brys83)zndw~; z`KsSQ=`jik%~J^Ft&EEqpCU9~A=CyC>W?yFJuKw$RR~}g#$3j;35}tQlL+N&ggULf z*Np#iyk`=vVdX5aE^$!CKwCM?`Imt&>ub+3p3V5L!mY$%Jev^f2=OI;ZL4uD=-Y@^ zS2E6a3lZZa#`{T|fp3<8GlOv~^QSU@33Kiw)URTEoKT}Lp z{w2wOtMA1f2|{}W;{%Li8D|lyeT3EvBrnJ4ur>i^3L{H7AV`8@v?E5|SZW?@4H9QC!wLnx}Ip?(|k2JFVCQnSUE0*4p4+>=t}Shv;5Zkoo;t<|abL z_ky)KB$>~W-?1dyo!m?^@;u_08AO{yG^E_%95zR=?^X(B+(EQ~h7B@Y_QWKn>6>Yq z!R1iBPqbXh8mQUt7qD>Ogdu|Li2IP*BQM~Z?f+mLfw06p2ZzvnQF|xp6Tj@auT6|?+O5q66&p) zrj=!y$<|~(Ks03lkn;*PHE8sm2rnVjIEDISM4PFMof)}aGOi@rxP?&1mjXaP%IH}T z%j5kAeCz{6*p1K}!Z?x8$YtcP`U;};XW6$gBg;##Y=24|$#;bJ3es~Xb6zFXS24cJ z$X0A{&0zkUIEtUUx{heP{{W3Cgyw66SY1rWWxzU@XpQByE0}*aq4=~Ad*Wz!5N+IB zI34sDmgKZ)yI9iG?A4Q8yK40cuY~+TLY->^Z9Rv2x)A*=oy)4efprdI4c8EwdCXy* zW<%z5Bt$Qf@FPYp1CsB~{FOO;zeWntuwxiR2%>0iTHxr7z`s3igLMZk!|7pfX zjGr@ZBh;^8dIQs5EGwC_l0e2-`8MZCGpe2BLqwbX2<5$uOBk0jKF0VU<9&?xxPL%$ z8q=d0xgIckGCh`&%N|BFds4rOn=O{oY5=8T#B?_#L;Rozdh4WFka6b z&L5*P)0{v0n8NdrLbhCuYXkja_8m`Xv}T&?H2r(#RAJ6HjGqvyW=!uSG@fFb>lrza z>E4W-hlXeMU5SG|+en_DlvbZ*jxzpC`Kf#Pa1YC@A=Es(@a(QT^Ep?wB~(}I6Sno>A{Q#+nhcoT>EgHTRlT*RDB zj7JF(7OB-oF+GZ7oWZ_Tn65%`8C5uzqa5#1j_WAjV{?);+cA!3e1K44^F3e&VUUXWugkjhb}t_@)AA{XWtRM1Gp5uuL1~&u0E?&f(ddl6lN$&HAJ4`zZ7I zuJvb_^9-k|9!nnJ(sF>)e}MHIV43eJwMJEz`GZrQNqjStdC5N7OF(R%0B@ zzJpnQFv}0&cn7n#!Tdh^9L6U#Z8>9q#>F0O?F9chLVXNt7{l+vW4!d6RN8N*bZXV; zu7PAP)%b~cZ^5-VRml`D-lLIb?GC=Lksh+nb65jguEsX2dHKxcR!b($#sZQt7IV%l z=1>zD@f8@PVKk>_G~eB5=8xvP8%<+Ky7xA{j#Ivleb;g9lNkdX`Wy@GSHUF1KFo_dL<^BgPGk|7PFAOtS?UDMafZF#mp!X8mt5rxSD5Gj3)Mk7gLZ z5N%9m{wIvzFvnqfJg0v=r@uMpNe&^(3GPKpX8t3b8#l1;c}yoV&EqEqmm;GnbDktL zxisp%m@`_|MeJ!D*HXqQj4K%DFh0mQi}5Z(Z70Sl(a&UDDSyLVpQX+PXDiX#D5hU# zx{cZg&UT{lJ)Skd-IfFV+C$>#53}UQjGGDds!V^tIDl~pq4-5%WLNuyIok;JVN7pe z+{O4j<5AMAeZ;t%aS!84tt+KgdmO%7iPlCj{W8;SbnIuSZ6{jn(os8!-TDQTTB7xb zS>|KL&4hYYraxdDz_^4^{GxpbJ)baV8=*do=?#p#7@uc6N}9Eg7S1yhl#IFCp0?9)(F*=!#>66^#N8f zy@b%@HX7dpBK`L;dU4&yH0zhQGd+!Q6rp*PX>Qpiml?I4IXAFxAEqZT-okh%BbR@S z)>B+}FivIUx=v1HdK@A8X{hUfH!+SQBtCjvL=Rvb&objZnnR6Z`Y4AwN;G;Mg!Q8AF1wv{pn{W14F}eK5-pX8FM+kCupRY7CFr zR-<^))=(_fC>GQk(2O>M^iN-KYqXk6mO=G-6C@$2! zpn;^5W7m7LZ*Su0S2KOJNAtaOX1X)eQ#jr!EHj1pXd{rfK#D7w;~LNDZ@{_t4WZeI z>Di1w6XJOR^-mZ#Gj3=8WJ2UH`3~ZA-oSAsGmd6#%Q%$KXv*{l9ExSM0#4N;LRb*p z(Maa>ryMq_P<|Sf`Pn_ndHW{cS6f1@1Gj_8g!?bt-B{;HmcN*K6h>?Ioxpn7n)LNdvu&bvqyB)yoY@?T-(U3oL?aK$cP#VS zHuZ0~FV~4%tJ#d7Fm5L_CNq7IBz9X)G^q)Dk-1{}E zGk*Y~v4;6c+~RXDLhsIDlUZgo>r5j1G8Qv`C--(%Qcp=+Nj*$$2h&_b>U&vRP28hC zct7p-dc(l0?hrSNVR$Ev{OFCAe)RSp?{`%^Ci8AD(I?g;BlfbyD;kT6{m}?VIDG=& z_$${BUo;e=28p^fibdzz?m#ApemzXlnf7#|ed_qUn|86}(9t4-_Q3P_?xe7Xi|;Fj z>EdU6!TTF;4?NG$+X*l3E>1KSieDss-gU|7e&+eP1*PpJ5&33$go@Tl`&xwb(1=Vq ze)tOe_c32or;(*nf2E}_en5A+J16F=@|p4FO5oND^YLBMxWCAb3E^CfE9NmnPbO9( zIyd8$fbhPl6e_fr=aR^m(p?(QJLbdGv&S7>KhP_39B+FLgK?7W?2*$2DJVn>>MqP-u5N4T3PcHXN5+BLIy~3Xy}bKhl91cX@t5=~1D)ta_~EXCI@Ei6ZO<+NU5C zBHnHV>+mh#l(0nnb5XrfyTo0BZw=!Y&foaqPmnwN1jAP}czNsck1DD-TAp^m^K#8A zG0}b}fsS)e?({!7o(Um+J^y6AC8>*ZPcfn?sJBo$VYNPYH~XZ7{ZX5*5>DtU!lice zbmkJT8jcjQd9Q6n-7y_?vrjZ&2>@yv)Qqt|mVY;v7x#+o20kru_>M^gz4)V_P0YSL z((5;%wo41w7G7AYlQ?dq7r#&);rSK8MqF1uM_k;~B-HBlqb0&UlV~0!aZjYb+`qJ< zlF@ZU^!-6^io4uh;$8|0Uv{Q&h4U$m_*Hi&xI3fwA%;&(D#HC9)cZ?Z`nLtULq*3# z9EyQYG2q@%cpH2=g*A|8^d2dmFj6)zCYX0|E}f7P`adP^&mD-;@-piBJa-tiClrf& z75)K52=^fz>q7N6{R71{fww0M+MSo-2Whbup+U2MC2C7zf9}9S`adi5BRTgDv}@D2 z?LvDKCl@?j>yWaU;g;CVBL#$7DpTC{frEC;ofoc~!e{X4zp~ITytf9P31ThjSNLt% z$9s;^8p1xMpNsBg6y1}dkdYXo^@LMLym0zT-&-*{G>2MMlvD2OjId;M%OB=d_#EmD zl^m}4vyLb0URBy2Kao9wVzou~_YLosQ~rC3wWml7@lr>;($ZH_m_LWl7We0&^R5UhDc(nR7eeAamMhZEl%2m}t)-pAHA87K@%*CSULz$WTwA-%BdLq{hV^iZ z9|ykCC7{AzZJ~ormiP5^^sWRnh+my$Lgi>xGB{E?F3x2y2M=M5t(u5iU`&bx*wh zfa{BnJrvsO?-fZ&tY+vw;l5E(jVJ3mx^Gl+9L07CO$y7R2U$vwFDzB|xmXMc;+FDG84N#&W%@=(ZjDxL@qqSgfV-u9WYG!r)AjZZG%0#rBkAdxBrgyIj1O zPkxskm&s8YxPuV^ruU_TNi#`Qsibp6Cr;THKy^vmRSC zUEy+zT0Zm(l_iwm=%3qx$4;9=UvJ{$y&1pgaR9!aL`XmPa(97yk=wz$@;HnpVIkQ^ zD1CJ8{ffU)hkZi+F*Zg##Bq#Q+=@mBkvR?1?1quQrfkJu}!@k`JUD_HcZ z>`=w(aZ*w0djJWzI~XxO8R<3hC?iH--JLwnN&=x@X#6oTd@Zs;ZKt$(t(!Mu=RSSR zAB4NZy)gQkXpC(B8(4uBCQ9}a5s5#f7&{%7>ldY^sQmdw8GrFL$6reN!pRAb2iFWU zikwSsQEx9Id7_tPm94V;`QLL+L_POtY+^9BiZ-F_G9Met(-qAt`JJ#ry6Z*jBs%)P z&sab2-wYlz`Mrn_#(j(b;-!N_^K+#CHHwA_{a;d)jq7;2;)s>ND!DGl|EO!-ZS=2f z_{{<%Mxk1aY#r8oFswAHAHZ)Utd;&Ny#^YZlN9~~m=u-{pJ@g~(I4J4@qZ89e~C3R zVnE8)Mq)pvBTj!Wwl#5Y#}4h!@<=+ZPQkD6+i<_Zy&HNbF_Qs4;hKuAFXV^N(BR!u z?Wp?>1w;&1M2EYTXm?%VJHXQJslK}vDf@3EfrqnEyY#5nUH6PTW1mLWPL% zyp5v#qSqXn@3wGPoO}Ads61Vlv+au)v@9OgSt%?uw3z5xa3+MfBwkiAJn0M96!C5# z+REbj|NT5~UQKK|-0`K|Q>^Ttf5mfOFv3`J8x%jzPz|&lAxoH>gK!eQUltFKn(hnY zhUVrJ5eV<8UeZ5A$7;_a;fi0nH^uT|+oY47>nB@()V&=~4HOkz(5l7oFVf>15oZ1G zonMfcr;8o|x1#Y=9T^LVQ(H_b7A8^;7xStZBb>U@L%FZfdlQd{U~hF$d}pPF zDK5dGxy^Meg~wbn`XX{gC8B&LA+G6|5mXuf z&5)f}Mmnx9UYix=6uk~>bYtF5JZ{n2s-&=C9idPQVy}x|6>qye&0g7y?GJ|MpcL0q zHm8v5zgW5O`&caZ1 z8}*N7manWuhd43X>-k2{?1nvkc49jJZwMWCgtth-z4!d0wLw@YGG8prq4VERDkn$B ze?oND356~pa9Oi^ILB&G;LwP8h1Lp{5b2-r9O8}}6&<;V8@>CPx1J)dX9bz@dh-=5 zW5?S13Pv3k&%jK%it9Kn9Qm8UK* zpQgW3>aT9;Pwu^8CD;Ut0i*a6h~gEU%qb~ePd+3$HJ()DEtoYI8PAFrB0eu16KjbY z&F1S;(-_j17OOY9{w+RU?~M({hWKB&@m!g_v~7ZG>PN70b~yVsF>3R7+;Z@wp` zIeKi+^QZnHQJA|iz3jUR>nvL`EK$;kU|E{}w&#!=PWfMdF8)taBn|Gd_Q7oy;hub| ztmky{Q}9>E@IPB){|W6A&n^Fj{!xkiCqz{A%F_5Fj`5#Di<64y)TsJ7NK*Icf%9Eqhm3gn5uC4PE1RML%Vxpf*3JZrCgN#A3RI&IB`f# zlVa*>73CCvJ1;6x+BJoaH)pA|Fn^QZkiRM3@vEX z_>#}zc-q8pFA3@N(soG^zo^TTWeI=QsCC8D7k4h@kKtR6jBAEDG3VHvit+keF2d`h zI+a)gE0`>|b_E0ce?YwKK1IoyP|Di2k^`0DQ{I(To*J6-6{2>BsnX7&F-UJcS7^0F zq&J4VIIXnMVZVy>n7sc7kIh@kIHqG#m@4TUJ=#%%OqmuNuLf~97S&dfHIhZcp5*Jl zbe?6r+Oy>Qb6*MjxhujH&feD=qZof4iP?Oy<9nHZp6*yp;hsw@_r$N<$4^|x|AK~c z*k%QiS!N$LN#s>P-3f`7wx;WN6vvyJb3A%ZAWW&>QY}$$+22wvF(`S&t9eTe5bIfH z%^oZM=Uc}mmHRZ z9^d!(V(#g0yTCVO&pEM|$f#6Gb>OVDF_d^o>;0bD@8NWVf4>O=G? zdSm@g{Vx4H{cimpy}y2+{xJOJ>u>8r^>_3S^*Q>-`p^2~`Y-xXeZ5|2So*7mVzm3D-9yM)awwYj7 zF&3IhW)gPd378GBBX}dTxv|`AX|^=hnr+N(#yYcy+0%I4>}_6eY&LH&Z!q?m^UQh1 zx8{6vzOmnY++1vYXD%_HH-0u(nY#_w+#_pXhrDE2#~dK*%KGLNGD~J*pRhc6hIysT zm-*%}*;F<)ua?baD|5JPE8ChQWhdFyyiT4i&o*z6J!DUFj2tG1nPcT}Io!NSj*uhF zaq>EOoq4moP2OXUm$T(;bE=#xA2siikITo+`{V+-*qkAk$R*~3a;aQuJ|vgP<>oB8 zLOyTKk!$2j=3M!*eA#?Vz9L`6zO8S`?dAfxQ|>gMmY>Pb&1dA7@=J4>+%5N*%jI7A zt@*q>AP<`_$lsMTHz`|HG2d26s+ze&)l&7$oywb zR~^isR1ej|JgCl9=bFE$KB|v-NS&v~o4=}C)a~+gb%&ZN)75gdTxMCeRZ04+6f0fk zSdFd5vXRxyY9`OLT3GF6zIDFUA3Mknum;Fh);?>WY;Eng4$C&y5nIR}wqbXXeeIt1 zqjIkOxV=d3x0l%~siKmcBnNlq)OG5r3@61&QJGG*ldZCxCQcLObJ{p8SipXQ#6Y zIK7>|D(GC~T%_`x0nPx`(7Dzbsm^dlIiu8>&ID(Q%6IN`rmL3Dea?NVy>q{Fzv|#T z;LKJXoqsrURX67mXTIw0EN~X6p3WlYX?2eCPv=?H&spiLRQ;XR&RTVWv)J+}Y{uRM$A)I0w}T=dg2FjZ3JNP)psM;7iC>;}gzI$X62++a$J8lM=fn zc2l<|c2DfCZcFT)*hk$ibnQ1-W*dB)p{?kGefYYHKG>D1ufQH)*p=yK;AC+Za2i}) zaW|YM?tvwnu;kZ4zX5x$1$)L$(&BCLF6iyzeb76^2cUO~k3s(%u9ny>z6S1v)5JG$ zwNMApPKOCv72(&aYBfOD)M|>VTC&y{bQ7(KsH>f&wE^80`;VL2joJjz6SZ4FPtuSo zZJKtssHsiYrh~pm`-eD1o2$(Q{jjzGdKPI<0+(oS2uItjy(Q{tTeR&WReKM64c5>; z()Nfd+PB(%;P=}1z#p_DqK@{vUPoB^Y5Hlx(Cg}{pwslWLf6~r?XU}12c7mN?4}O_ zXRtn4oJsW*=sWd0MNprrPlfMY`dy%>>Gy!XPse^>`V8z&9@J;*4?}Xkz7U*6`XXWL zi}fdk(wFGV!Ff)9UR2Xp>Z?VX{(`;+^o#n7@Lj8~2mKOuPEXTc*8c^16ZY!92z!mc z0?w=Y>)^bB-PP;rZ|ZMBev7^ZoUQs+_`a>b4f-AZ9r(Vde*oO6W1mITo1X!9>AS?~ z`sX@!rqsXIzed35DCTy#s@+gJB<%Pe`I_t8ldj}0{Eq|Tbyou zZTt%UVdF4ljv9Y}E;Ma%n(3Gc*uO2&Ocd#6C9{$+%_?RUa8S#Gu5MNr-BH&EL_ITT z=767v{pj<}hS-U|25SFCqKA2=iPC5`F`IyYmU$LJH8q=p)68s!Pz7cIIL*!G;IuGX zh^lBOP-4xtW?Rth%=Vx=m>ocOG&_OrY<7m8E+%Zv>}qyJ*luPw(A`bsp4k&Sr<-OU zvkx@)HTxpedFHi3H%FQyg<)Q2UMDUvN13BU3-fyOdQr(7ZH^Z8sT~46#+(HDR`XVI zm3f=_56Gis63Nsu0nsu6mzd80|7reHv^STT%Y-tQo6kdXrMVJ1SDC92*J^V$_%E27 z!GF_y3!E+H7BSG=YW_!5Hg}u5MS}UY`L#I5++*&A%s1vYkl$zS69MyEbH6y<{LcIi zp$?co!}p+h5Wc^dzry#hiLxZ=GcZbOQWLt=r6Eq2rZmCFPuNmPCC-(Ww1p)dnFxL* zSqbu$Wo1!KR*_XfC&?rckkw>0_*R$Iq30BN3g{ZLhNvWK%4E>Bup^x=PnD-ZzAkob zO_23uJ<(g%m-WS&)CP;1)CP+TYJEXBmo0!TWlK>YTgg_U6Sc&mt86FRiI&*UyCe9W zWG8XC>?}KrKG+AeD>&U`H%OwLhGciy9g;m{4>3sgls!d9d9}P+WXWsfHNb1-wLrAl zA_;Bw6j2>}cHRkks+=lL#V($Afu1Js27kJo4*DK>5BM|XOwo^8chL;3`&`jZJ}e&w zJx|U9{fK--G?DY=d~ue1R6YtCZ9nJ*aslXtav|tNauM$FN%3MRlY596nd!nSgs+z0ww`7P)J z@<-hDPuNpANgk935!WyB7tn{~uizh+he7`?3qiX|h$N*cO`NK9rGqw<6g<$@0sOwLve{ZLp1{DOqDOrK#!*}WSXcZ zpwCigfo`grf^MdoiObLvDiA|d3)Mn&Q!Q0XaiwadT8W{mwQ3Dc7u8j?R=rhk(OmUa zeSznxexidqU!5<`Qx~Y~M4}p{ZWOiEO=_HIrN*oApeL${;tJ|Nfkyucc$d0M^rv2w z=xb?~CTd!hu`_6rm1I>D)u}Hf(y1>6Y+AEJ>} zXcdYa%e7q5$QCyCGeghJ6xp`46NI!A?MgzkE8CTYX;-n)?%Or(nxK>_EOYS$69 z?9*)QnrWxoe((b}cEz^y>_*}g`%F7uRJ9x1ErnyZvRjFIc5Az>NVVJ9?L`f{gWX9~ zu{+ycL>=@3`v}YKYoCX({p^c{ZeL>CkktbH@+@%AK9$-dRT9Ws;c>B6?}vF{NH_PzED z(ZIgno+(bZAFv++XO=x%oMz9lA3@mp_I&7n)LsOg%j{*q<@R#i>2vmTxW^Ut3Z#Ff zy%PLY_9}4DTScf1_6EfGvb_=XCVLa;SM66tvi+LzO3+d0KKMRaj$IyHglC5yAEe=Mp}{}?hY zotC05ddcWJIqjVG2#a1a_`RLp(Amf7BicKCoxb3p#|&Ten1Rm8);HGno=@dNuE+kZn@pklb$6> zk|gK?AhddiSuH+bNm~=ZT$LaV6OFiYjb+ zB_wQmrJ1nlm26?tE6s#WubeDwdd0z}@2g}bUyytOHnygPvFtn3+@6koZ%g|=3;W*V ztzUgv3@rT%*zTuX#`Zv^Sn(@=!0xxP`lqnI16#ixw*GA9V$ER*D32(QDwgsXORBPz zMVHopo+9l2JZbUgNn1Zp+WL9Y%FmPby@P!pRDx=@TA<{sP1UAY|*U1&hB>TKoZN@t-3t{s0z#Id=TL*!@}3?$5;Te@IEi z;;&E~^IRg6Bb7i)sRWKk3A~QR*oGd+MGt(Xq(}|WRB8ZC zYJd~b08NO?e3Zb6D1iv7pq18|^+~7#UF)WigGKL!Qb^y#rOF`fa_tJmFI9mmdM}h_ z^j_S_I;uqp=PvCoVyb70TrZetW^j;sSqMkA^1=T+xYb# z+CP*WsSR?ZHqg)p@3H426hdLGLimL3uh0pnR_g?z5Hu8mf~Bsa6T;{Oi#@h(D~0sO zAgHBg(CCF}#Qsc_gAe79jm4j%=O};D8|zrZ^wacInxQ57ujUd--5=l&=~h{ zowHFImq?{ig3?&Vp2zja*;84oHJ5U{wMmUO0xc${u$T# zx&9s7LV+}s3M3f?qGD}phNcu6I%>pE4^t90v``~$s?|uUk*e6$YDDOemgta(l4YD| zwBksiM$V9GBv-1DE~t@qO3*k3O_EiuMuZMYsiQ;AK!H%_8fT$B&XC%J_gDW!Zw#a# zt441W)0@>-=^|A}OH>E#rO_YN(Lkz>EU7w%O4V_>R2}J3Z>UmTG?wb3u~Zk0rMhS= z)rDy+HI^#Z*U=a%>f$Ms!x3GfN?kEh>WYR^S0tk-K2g$*Pf-*}Qc;{L6~%EVirw7N zSH@Rpi9N<1CCB*M_?kU?Q5QL=i*MQ9kH)aj7zfz?-uRyFgT_I&e=vSv`;c*nFn=_D zWY1yaFni*t5lyO*B&kMJsYZ^IYUEU@Ms%r0G}MTVif~LH$0wOdSk=jBk`7Xn_@pLL z(Ii-wsF6mBDs_lPpP!#S0W-j!AZp}9)JQh}n`7p%M`)5{sYwP)P103rlB>`pt(8BT zZBQoXiQYl1WT8(+Nqusz)F(ZpK4~uXi7Pe9HBytfW)Cz;52;36sY9-nI)t7>b2yed zeTS^+J7g_%NQTrQjie6AkUAtJbx4NPA&sOC$uNZu37JBH6iEfrPb!cisX+Qk1=39_ zkh7!$=_VD(SyF*?lM3W4sX$IK7n_SYFa43M>5pVB6v!A;D3Io+P#|rj0?9yuRB^^< z(IJ13IwT}@NQTrQA*n+;OC55W)FBysN;Tq1HPTnA5l^a-zEX`el4>MFs*#XXBN6)Btxo^ zMyL@JO(N7tcd16slxid-)yPFsjhrIY$VF0(beC%6OsPgXNj1`3s*w@skmHs1R!gg; z(%U)#HPT+Hkt?Md>4Oewqg;RjISCcf79G+X1=5~lg!bqowa3*`b&Rz-S)G(|QhN-L z+T%K@J;qDzF~I6-byaQX0kw%}qjkB-<&dh>%^tc2m0<+d_@Bk!qxkR3mMq z8aYL(k>;Y8SLrF$NOP%13Q!}vl%V~k{iTv`e}ys$NM(|VGWlA`L7D7RH2YihNs`nj z>FARK=o6t#T1#cpN-C4iQkk44l}Tr*Oiq)^XsC#TbfGUqM=**qXaHNx2RILG?Tg|EOm<}b&F5xmI%7#k7%J9#ZrRu5sF1a zv5e<`uSc;YNyU<0N3rNqu_Q~y(n2bhtETuU8J6ABK1tF)H5kk$>i2iGPzR8A-QnPjPFRHO==s}w;pYyNo{kS)HW*GW|Pv+ z_Yw*xC>2h!7@go;yL?}AY0$#Gi{`v=_>V%F7-@v zMeY133Pmx8rcV2xSdv>FvutP2_G6Zt8ZAn-QnsXpQnt|bRL_#!EV)_M41aNbzx~|4 zGkZ4-*8Uz$Zc@8l&p8smr4=OyYnIfCW0&;7fz?oy{cK`syeHTtW$wQZxBeqi<{lFl z$Hva@vuAU1-DP{$j1y+$wac23x3k5XCJUMuWzEQ%(X2^$de)4ZyZ<$xsoT@HrI)7+ zsk@}Ds9CZOfr|a zYrfa{oSVYZusFYeC_VWAIj))b-XJBvf6f-U)v>{_(B=li#BbtPv54cvH~IVQnyutX zN0yXT$&)CvN#YKZo25tCswrvmGZ9X5vm-H(*b>*}FRr<|%t6V`>PaVJIV+MC`MG%b z&woo9S2v7;{;A!?BCag4_0x4qZp}UYvd`*#)~cTTR-2!G_O~_E*=thQBv&52h8H6Tgt(7A5lCk#(DoawnziOWvMpwQP~Ry~EN}YJ#j8N!$EeWL;;8U$PFQ zjY!%?>Wa9qlC~vNzg5STsK4i?ZkONaMf$Ilrk`5*vOlD99 zrYDX`-g(?j;+Vw3`8Zl`4@(`83@MMMJj!~CTy~`FD9lVQPF^H9WtRvyV@BdEHRs9L zbUHSZdBIK2!FIg|kj425OhoiuA$cGU^nO?^3&qGRA#y7vj!p z@2-v=ldvR?vKR@+?Yg-D9YK$H^;@|DC)&Z3S0D zDIy1m>k)Z$wK!gs9PwF`{wY(4?HyPr^~EiDCAkU9_Dt=>9^}pL+`%+LY9`jH-9>DP zCAETcZBA~PHA9|tZgNX$Nm38+D{XqJm9|1$5o^K_i@csme53Y~`>2WPTxlW>#Wl|* z?J78?I_6Thv&gg)p;gD`4w*~H@#GlFSn|$POHnObDW$KiA@l0Rx-Y##De;TwO9yJw zk69MsY2s|0_fEEMjh7p9`G2vml>ZpZR%`a{#JiGaejKmjze<@O^k6)uE+$kFN?$?| z$F7>%z!KUXKdvCrgv7Up|A3!vA8 zC9hmpUR2K2zEs-!a+GrwLwkxlAU2rk;+kQ6?i&2=ir=}1LXL42!`u`fYi^E@wSR;- zS7#W!N4m}#WAd0%jw$7sQjRI*n1=CtjML+9a~JRXj_0Zj&NGlJE3dxu680?T%zsOq zovZthkqE9@eIGu69rC{tS2*m*6%ul5LKZPvZi=TO4B}!qaWP!Pm2pD#xxDHa=quwy z93x|y|CawLuaFrU@v+8J@lIS}RNlLco9cT%mysP2TOxjr#7JUqp?Y7ugfL4uZwc{K zsF)nrR=5Kn*3mq;xTf;SYs(Hb&?JgmMR0w45{=YqX7T;hsw9 zIc>=QR9~6doV(l=uasA45o02~1`>x0**lipQf}qT(C#BY)Z~fx;wAiA#hn*32P!!p z(}Nr@;{HKW?&EljUrYGk(!>$m4M(CA32pU!>pUIp_+d4D2qqUHf&fcR08xh_}6 zoXAUmgHbxwGbISw_UsqMX!wbltGWi2VACkFLFve;M{q zuf#hh>=g3SksR<2IpAHWlM_g<64I-L^eQ2}N|aP(s?wV|fV~;H>aA^rS79qq18T3s z8%l5HqV;ChMsNDSdNbbKTmDy+|BCWoQT{8+e?|GPDE}4ZzoPtCl>dtIUs3)m%6~-} zGyF-(HlHB%x00j&4%;X(ACr0qM7}%xtwoNt0_3O$$K>62NZ&-wc1%9z{;IgYD(RsY#ea(&a#ZgBH6b)4hGvR7fcu@v{m$fmXL7$Yx!;-G?@aD@Cigp2)DPVAOi^=i z-!r-InWBc}-e>X_)(gp3#fW>+5t|7E^wzZM_Wn0scu)a*Ww~( zU1plhQ8FkI3ypd4Dq}wU6&?WIn`|rs%C)f=D&S#Q0*}C>q83o@bk-6l8(<^xl0lpt zsj0S*OUMnB?pui2TgWlD)Rcc>^cG5H2_;kHoLh+5TZq|PD5WKo(h^2tALnW-;R$#e zR)DyJDiC+^9IOUfNs$uTT0YmodUy$5p**Eh@&?0|Fcjt!TYfbw9##JW^WZ+15BI|Y z_$xdB3*kXn3=dIPbcQpbJM@c3os*$mJSyr=-|cV@wY&(qoRG^2xtx&83Avn*%L%!h zkjn|VoRG^2xtx&83Avn*%L!Su$>oGxPRQkiTu#X4gj`O@xgdQXG7@@}qJx1s;LXQ!8jL>6*9wYP^p~ndQ zOhoj=2d#FGD#aV_EL&J%o;l$8zVrV!qG@KY3P7DnvhK3VE!-=7Uz3>p9)iwiX z8BR#>@2p1Ys7C zTKb%LYn|)XKaE%EaZ*+V4ea<*!-2W+V(g8mvFz}-(iY@tQp$B-a|f;W$MIsycQI{V zlzT~ur*Nh@TBG>cT2A~rtrs=UMKAy^haoTwC_P$L{3%(RHi<{|3kbbGZS39D+E|%{ zT5f*I_O5tqb079WwO!)t%2{%yeepY#jhcE%S|4@G3HH}fWhGBs=P`D{HSuBQB$y0$ zKop*U=ip=bjC9Rj%nkri7)4j z%Q@q6&bXX2F6WHPIpgx5w0+At<8sc(QxtFj;_>C2aXDvP&KZ|;#^p8bB4=LCnU{0s z<(zprGk$*Bx?U5X&za|Q=J}j?K4+fKndfun`9C@He9k=m57g0oj}_6p8k!PzT*a`p<&UcuQb zIC}+Wui)$zoV|jxS8(tCfxjJSzmo5Zk9Vlq{l{wj;>ar9j!JONL`3RnqM@GLwBtKoTA3+rG#yaca6 zwUve);|WU*TgJnd@vvn)Y#ERFW_9hYYp`G^!DP4tq7Z{8;5n$97ieEaoktm|qKs5g zMye3^kR8Ez3ef)jv23V#Hq>NNiMyebaKxGyw)qij{z&PqvJYb!aOL&pp%Z@hHt!wUymvvgeIF2yqW$|2K7u3d;8^1B zCF1TS;;OIx19i+H^3p5uzT~OC&Z}&1k$J1H^9G;)h{uwshnTA<)Wz@7Lf4lgL=TQ= zwQF+4k=9$}h~i(ABWU64<^-AYM_sk{ZhXPNv@Jg1w;k{yd<4SQI2>P!y|L8boh#TJ zOR+hY8afzYf(7;1AjTK*1;(!U0#gGWYVPjHUDeto&fW0^&J36xU+T<>FZFGVFE~1` zf5TM^E2)aBuHvezxaumdx{9l=;;O5->ME|f3d^a=sAD<(#;dO4s;lHxw>qj8no3P@ zwD$9k(SED@Z6fhvtLYMi+{+IHVV(9C=Ovegw1m&3eRFF zzHV?9Tnfc78YFpYRsE4cp-zco*J-_u&KB0UyFg@G*P>UjY5TDDJWJ3yl@M-o|Orne8)y(FWrJ zzW0ldMa7Oq#g28l$aZ%u>U=Efd@PD-EUI>_kJ=bzI~KJ*7PUUs_a)zV18Uy42W#Q< zy19|sxAbS)j8fW+Qre7C+Kf^?(PsRn97^q5N}Ewin^8)eA;&pni}+h|EGm^YrIa@1 z-{xFu?o!#l_ac3ZN#A19x0v)TCVh)Z-(u3YnDi|seTzxoV$!#m^erZRi%H)Y=^G<` zV=DHLO7EunI=lhf;2-cNeM+cz(!HE?FDKp0N%wNny_|F}C*8|Q_j1y`oOCZI-OEY$ za?-t=bT22}%Srcg(tSDU9-}{fp&UCnjqT2q@iU=2T)_8!@nX`ynDj3u{bNoydX~-t z`mx9d<>Z5Mr&9Jb6_Xc=eUsT{Qi~^m6L=!vdhU zQ>V96r?*pI1S0Ik@DR}Bsng@B)8nZ>0`z$5kHJ#FuGW{q<4_4$Q?>mjztNU4u^4{V zewj!qyB)Ccoyjl-u=Aa%a3^5z*Vs16y(nEC`RrHs>ygjqkEtQ>OV|zMEqxDs4SV4m*azRj ze)tX!!H+Tz#>j*7sC(v-_m1>6Uch(y8*4^y4Dzs(3e`A2e%t!@ zu~L7J{CUI%ueD}nULBxO>NHB7_6*RDX|!Y7$3Q!weGMp8?HfwjC2&3505`&);byo6 zO5s+R0Ji}pMyJH+lo*{7qf=sxYsg!aUdCp}8lUsIk5Wf!GJaoWqHN6ukPSJ|7_N!G zjjDbdRsFWf|D&wmMp?gY-o^F|c!KQ}d~)69N~nTo;W_rdz~@@{nC;K_+zF!P*~|BD zK%DzqJ`X@V{x-_{ZHrnB_5C*L`)$ik?reOgwhJ}sj@Eu%gyqdqO8J}sj@ zEu%gyqdqO8J}sj@Eu%gyqdqO8J}sj@Eu%gyqdqO8J}sj@Eu%gyqdqO8J}sj@Eu%gy zqdqO8J}sj@Eu%gyqdqO8J}sj@Eu%gyqdqO8J}r~=Y5n>6_tA=Gyo}U6w$B8s<#$)e z6XRvn-DT9>Wz^ke)ZJy&-DT9>Wz^ke)ZJx2)u%#L3$;i2C{wOcH2S-BFu(*0L{GZ| zK1hOONP$#Hg9eZe4Iu*>K_)N)ruZQMLCA(2XbicK2lT}&`4ECI6hKpG28GZZj)N8; z<~X#36CeU7LMvzuZQvwm3yhj6jG8H@Kzle9I>2er5jp`QZOZAuh`e$J(9cf~UUlomNgiyWgx zj?p5=Xpv*I$T3>v7}j42)?W$MUkTP<3D#c;)?W$MUkTP<3D#eU`T^{K58)&D7(Rh7 zfSDUue;?Qv>2TK+0p{wiAj zDq8+3TK+0p{wiAjDq8+3TK+0p{wiAjDq8+3TK+0p{wiAjDq8+3TK+1m&k|bxQsXqJ zJMMY`-x+(Q#jm2pud;%S(CRT+EPzrhfEX4)3=1HJMOuPIT7pGdf;CX( zOoK9*4l`jEU^ikJB*t>F>9Gu=Sg9pgsU=tlRagjBSO`^E2vt}JrC121SO}$92&KY5 z8ohRCW6EZXvWagN5VN_^#+1z%Wiv+Ej8QgYl+74rGe+5rQ8r_g%@}1fM%j!}He-~{ z7-f@jQ{WCMn=#5}jItS{Y{n>?G0J9)vKgan#weRH%4UqR8KZ2*D4Q|LW{k2Kqin_~ zn=#5}jItS{Y|^_3t)Mlufs>#uFm_AXj8QgYl+74rGe+5rQ8r_g%@}1fM%j!}He-~{ z7-cg?*^JfKJO3MVc{#bfoLpY6V*jgO!(R9X_QAKXAHD--bEx0LLHa1(0KOZUqb2Ds-E6h$%=oN2GPi|{^a$8fjW0dU}Wm}AAi@u50 z%sY$PamuwGSD3AUn;UWz=}Vc9QRZWm`50xsZtg30&gOd$cqQK2*$l76TQjpkVP=CO zbJ^9{os4@@N5s%XVvJwZ6)|#FIXSDGoK;TFDyQycsX;22!;cl1#Ghr6o1G8Zcl*7HS z42VyI_{5V^p+S5a#HaBL5T^!lY7nQ!-(VFGw+3-*5Vyt}cmarCgZMRwUt|M%fyaP2z)waY&yW@R-hge)Q(Q(pSV=ut zNj+FeJy=OSSV=utNj+FeJy=OSSV=utNj+FeJy=OSSV=utNj+FeJy=OSSV=vIHxGUqp*vM2lZUi(f>GUqp*vM2lZU zi(f>GUqp*vM2lZUi(f>GUqp*vM15OIeOpR>TS|RfN_|^OeOpR>TS|RfN_|^OeOpR> zTS|RfNqt*MU0Xz5Tf!{VDmm}6J)fuX{YXDiiE%djE?^&hMa)?)q3*1t?yRKltfcO& zr0%Sw?yRiSk5od-T|&!ULd#u3pHh@Qr6?_U5iNKTEqD=iYbkYWDSb;~_Ej;qR%Lbn zlBiEBsZUF)`B1_ykQ3@9}n6{e#ibyTFD4h zoDY5A0_X=9LVp+lC^-Ex7ziji{SPn*E{DNz1q^|iT-z+51wp4p(P>e1S`?iYMW;p4 zX;E}q6rC1Dr$y0eQFK}qofbu>MbT+dbXpXh7DcB;(P>e1S`?iYMW;p4X;E}q6rC1D zr$y0eQFK}qofbu>MbT+d9s9@_1*lO2HEK)*RJVcZHc;Kh6u1NEr!wfLGNOPTW?+XI z*kJ~Cn1SXpP}2tXm@x~m$Bfx92k6H$?uDhW3?7F{cmhzi2DX`jZDydpjVgE+{syby zIam$P!y0%2*1|ei4;x@3V89c%1{uV4>+4cM&4H*f&HhlB6~V6z&+W+lHE z*0P(F}G(+ zJO!&I1*@eKR!b*2L+S&16zCgg{JE6z=TdqbmeboX-~2rOCOr=G%`f<*q|@v0@8<#8 z@z&P$@q17@_t5K5I~T~_hw}MWj`?@8e_$s5AxfYgPr)KeajwFC9tl?i`M?3k{B;9WxTx9M;!ZzW2~zbtg94XU$(gh-(q+O9)>0G2s{Sl10Uz{k?y`XU>m(6 zfp{qznJofyKj@QWTF%!eeTGW}CgN+@!pQzob(9qrRm~RJJQ0 za>OTiM!j1RK2c|>KD;8`BmE)0h9{((RpHUJg1vY%QUmxgdR=Xe-{c(ibm5&yoq%7W z{_5>`NWMgU1}{WI)GFbBNL?rV52+vHe<-ScCVY^pJB5cKbr-&c9#p@?lh7;bx6+ex zW4!)+s5QgK&u*=?@av&qWGPU!C{~qmP;kie<49`7% zw5h^dk9IeHdM?st;G1WNHXDCD_}bC_A-pha zZwb#j+WUCZIiP)lFJ@Ky9)CG0S{z@U4RxRJ 45vPrwCj8&%8F=IDq-RRM%sJ98 zb7SGpMsJP}o2&KX@K`fi?~ZTGTlFGit}$2dCw(+uD16oE{iToQi=>a{fzn5FiSRe0 z-)nqns`@SB1|NeT(q9qQ8c>l{@sU_*S_~-)7!z-mSlB z-ecaQ|5Nx@(ci+W%6rj_{$Pzl-;j#rk`~Z;Jkb@SCFV5FS(X5Am4tg#MB6 zmC3cn@>RgR?@7XC|YBT4uyF?c8nFVAWCCdoA#Sov1Ik%x?Yn`NKFx z`1~+V6+SSl8(Fac+yA2P&9p4)L zgqIHE65+eqxD-DeNycD&Z!|E53x6BNRl*;jF%nOJCm7e@OQVx90sk32j63m=G0>QU zCyX17hwy1J-B^q7iu;Y%g~w;(1N>4{8lMP{&&FrMhn}%hczia#zzfBT#vb7%&)AQ* ziPwzp@GbF%aY%TTFb?BMf@DgF#!b^nd^JV+8&17F=U#^+rYwl}qrU`El zW&_~|!b}%_Ak2os@3Wa9ygry&!sD~)7oHx>pz!!?W($wcW`XeBV79<#!yNN?;p^Ev zQTTc`TMG{j=1IcWv)NYodNxlJp5@F=cw%_Q?2O-qRc2Q_E^IK*!oR{xW>4W$!8}j+ zR4{uBkI&}$!aJOKsqm>_UM9T5nFED41@jN$nO5_1;Z4CDEW9b0R|t>K<`8B8p2;kP zZg3WK2eF9vE}jiNpdW}C7X9HOxEL;h0dOf?1_PlO{s4pEa$uIc!gDIh5V#VUEw3>1 zK^X=mFdY5_Bj73+30K1?xCTbUwJ-+8!Z^4N#>4e+BTR(bVG>M+DR2ke34etLU?D7m z2VpTh1QqZwEP+ShQFsiNLJXDxPYWnKEuiqUfWk95%5vbD9EB$b6rLPVo&la7P^y5Z z2Na&ZQFvBI;VA-zrwA0DB2d=A3$PZ}!Fu4CH9Tay3QrVJ_q){nuEKK@_{nx@0bJ!D z@Fx5dK7*Z#t2TgiXb2h52r|JB0SH1ic*}^j-u6hP^h3jBETn{$@X{X)jHt2VV7DJaD^O1w0H(;1PHf$QK&Rs?8tJ5w zM%r8OHf)D?;5~RBK7bv}t@)78kKhyd6h4E`VJCb6yWmUM4PU`N_!joVcW?l{hlB6~ z9Ab8n0xFyb};2h8ZvuX2Cr$8|FYc+zZ63{uh`B z_W|*x6JI*68$M?F`s zgeMf&@Iex!K?F_&@)h3fTzuKN26@Wp1YLo2#&?}-kj@6_jPE+v=n1`m`!`KE4)`CF z|G{&!ix)Ax_{y1Au1y}a3CBJY2+JlcyBK!Cmq5JZLCVE*lxy#WZ-6*=k|71SMtncH zPC7J%3}^(I;D-PNp)uqF=XIJuK7=3)1<({u0Pfe}e(?=h zevw?C1EdGOkX-Q$EuM~CJhr-cGjj3A>iYf+H^Z$k0d51X0UxU_zKC4kG$;e|58i%U zeEqn-&tWHg0ph&GEnZ7qypp>3Bz5sf>Z(iszifHL%t=z^e{JhS3jHoEPZlXi?*AWc zecCf0nwHKR1K)WqyB!BbE}~WX-_mN)QuCBg{jJwv_Fuv5>>+R^+e1Oj7B1m) zIQ$7l0OjR(YqgH2brCHVv%!D1)w-Qy>T9{Mgnm)$Ro!xFU1_;IG?RyB^3Y5kb*hJE z^3Y5kn#n^md1xjN&E%n(JT#MsX7bQX9-7HRGkItx56$GEnLIR;hi3B7OdguaLo<13 zCJ)Wzp_x21lZR&V&`chh$wM=FXeJNM7Q!NU5EjEjK#hZL5_8l&bd!f} z@|4G5Da2qI@LT}8$wN1J=q3-{;j=N6Y1*nLIR;hi3B7OdguaLo<13CJ)Wzp_x21lZR&V&`chh z$wM=FXeJNM#0*AdAT5_i%jKb)Jam(XZt~Dg9=gdxH+kqL58dRUn>=)rhi>xFO&+?* zLpOQoCJ)`@p_@E(lZS5d&`ln?$wN1J=q3-{>79<7&0>*djUd9+?0t(SMy6Z_b()vZ_kPw$hDq_2#lTd#z- zinaXjI#>@IU?aQ)FGHgBa)s}Lx=(P>dUsYe)7kBBEt7*~%lt{!1rJ;JzpgmLu<e9Ts^|L zdW2TdV{ARb*m{Jq^$26@5xpN=2>oFITnd)~Z^>Y6J;K;}L>~l~!(g}qhQK(&B9Ed! zJ@luC{`AnF9{STme|qRo5B=$(KRxuP$5?!X7S==mdFVe6{pT4c0_6k!=b`^R^q*%? z9*oXB8BH1B`O|^4upTX}M+-ZU7S^MM_0WPITF^radT2q97IvU9its1EZ7>mThe^O2 zxr`~m+qf9#k1)<3VVpn0IDdq3{s`mz5ytr=jPpkr=Z`SXA7Pw7!Z?3~asG%g2g>1I zSO$*+kAvLqmILXb%nTp`krAw1WAR^3xh%g5tg7)^%-X7Z9LwkE@Zx8M5p}jq{x5pfb2y-MN zXmF3`r3Yfo$fv`wW<2IiM9|?Lb0;EbaStu-p~XG4xQ7<^c(!^VR*i=q_t4`WdfY>g zdpvJF5Ua*xzD0!j77^xKM3`?8VZKF#`4$o8TSS;|5n;YX1l{hT+dbx8M3{FGLBD(G zcMtvUq2E39yN7=F(C!}EUDRjTyg%D(d=B%AdcwKT3(kYya6a?_5BdVnef&S!!#owc zMCkmxxc+HS2Gikgm;p0k7Tg0o$)oTL8kW`n&K~JaTo{LEc~~V6tK?y|A6y9i z;Uc&gE`b4XDO?5vp&0%EgWz%)3|GJqxDtlKA7L1jz;O5zjDV|PBrw-c9R=6GXt)-} zz*rau*I`|bhwI@6xDjpwdh*np`TZ6sW&2i`0QBf#Io99n9%Vnh!aQ5{tGpYj6`bQ? zSOSm0qwp9kg%~V@$DtCQfG1%&JOxj~3U~%qLKQpwlx~<=>AKJg$W3dkHbKGDLq%i2jxk{VgH-TSD}=gy?4p(a#d1pC!bs z$`BT62n#iYg}M$4bsZLJ2v+C+9nTl9`=9Px!8&!ZPMHe;I?$tx zb?RcBx>%=ow``3F4n1wb?RcBx>%SCR`Sf?)5X<}5P zH=pN2AE37w>(s?Mb+JxetWy{3)Wte=u})pAQy1&h#X5DdPF<{17wgo;I{o#dBd82! zs~0m{y_nhR#mq)8W;S{;v(bxr4y~Bk=*7%NFJ?A+F|*N&nT=k|Z1iGgqZcz9y;%Pm z_QE%?559%{@Esh2ADOpCyvWgy6y_HbA4a;IXWWUoZ^c-{iP4bO${3!LTzJ%|NPG63 z%CYnvF)yyzU=B4_vMc8$pB`_T=!;^GayRy!1;YQA%ctmzI-CFP!6$WE-O&?+`i%K> z#bPcqmb1&VOi`?77wg%@dUmm%U94vp>)FM6cCnsatY;VN*~NNxv7TM5XBX?)#d>zJ zo?WbG7wg%@dUmm%U94vp>)FM6cCnsatY;VN*~NNxv7TM5XBX?)#d>zJo?WbG7wg%@ zdUmm%U94vp>)FM6cCnsatY;VN*)`SyiVo}9#d>y`#b3;^UQ73~^3Q3SjB z{0jEK*RU79fp7V3KYRxV`2IZ{gdgA#{0QW8tZEml+Qq7Nv8r9HYSE7uGSl&GNgl?s zcCoBoENhpi2#W2U%=O+yf8CeBxv`Ls9$nhU_iur7){ZizGPj$&@GnQ2viP0wf7NIc zbN8J>Xb#5#bHAPAp(UI^Smd?Zk*JfIG1U%E;kWicK65$%bJrd6nZsOthdJyHbM<)| zqPX6XtHHcM@Jbj8e^k~T)8}^;=Nk!E19=TA+r`Ruv9evPY?mh~ig|jXn5QR-d3vH4 zt2^{>`v_@652uO7zGng zZM0|mbY-3FPwdM!^$!+!{i9(MtLNTRK8_g`yPNr>*n>W7K{+R%{O`Mu?ZtdP1P{X! zcmy7UCpmrvJOku+EOZwO{m97LYwUl6@7v&W*a=?%`Hgv~#mqx3W*%xW^H7UxN8K*K zu2U67Nm4c|ya%^?QLldLvm-7aGg4ix4B!oTTX@^u`|4-B?e2ia3tF^vEvSXG7A$SF z4q8{eh1Nq`t@U9>*&uD1HVj6=cqoM_FdfQa0r386Z3V|~)V64EYVR8b+GormJ75mc z73OR?db%FeLwXCnjov};s`oI0dLQ25Hb@_)kJ88MrTP?oI&WcHpjYV2^cDJQeWSjG zH?F79`qV3~xN4M9dd0XlC+X8!x7BB} zK3Si~x}E+2>r?a!*6sDBtWVXSWZgku$@(;X^%dhzYNM}beUkn%>$dt<)+g(4vTmop zJ7h%3AB`bHMqYiD{?X9UmtSE_A93{+BlMkey+^M1j~si|X#LRDqlb(%MvUT%p=!a7o_Bt)knv{U^Un*J5t+VfZYzbU0g4*f zpZIPLP%QD?cT?iKGfgqX_we6Q601R_}kbdVf*kvq5Hcchkhdht7v-ho5ArjD$>z9orIS}J+}HJ@fh;`o%e_;k3Ag2X2+o%~Kq zXNdjAlEiVzym?k!Z}No1XIgcU6=yN8-Bi;4Q&5yaYFU+c zE?veN&nm1N$u-_k*v7{RYod;IhFqU6*JsIfLwgMSyW8T9T^SEWwn&Y$ZINes*uz<$ zV-I89(;mwDT=`#}X?OYM`VZY>?StLHbP% zC#Iz|Xwl%Q^jQt(r!{HNxxvfnk2YM9+9$0|gFb29QU|5=YcQn2j`X!@L(|4L7~kMP z`u2uf8${F7()Xn|Ynak-SHor*RwFHKYI?_poijp>nq)fZeH!-5=-8-ZX7lu+4M$}3 zYt%opyQ0M7T#L9zjjLvwC)aJ0jy_t1WMVW`NmF<;w8DF#iSbPCBAfeY%$?+MFZtX} znEPqU9TgJJaom*%@wi_RV%C2lOcC3^_jLw-L6~ZGAL2^Qt|T_q?2*jb7VA{jU5H`U z_B__q5aN6G4M3^QrsQR}2i|9z-4@7+*_6_3@?tinJ)2UHP3^;XExQ|gwCpkX?4Qc0 zik4l0uS~w z3@j=wxT5i%><*3hus_uJV!|PBF|^)bBnD`!WxDBB8g z&rvxQiW(dzj}-e(6#KHLg1`Ddc`Gj8c=sItl?Y4h5$EHb&N;JlW(QZx&>C~ZP{j$Q zgl-PqoI5&qQ|_k5pR_*6-XV&Uos;b})`Fh}R|VGuw*|Lz-Gg~-@*MLLtDAMLb*Ht+ zo@u|veH~UD-rknQ+uR!Y8Zu{ByuD4!?#Zz|%>h<-Ypivbwb-6zZ)I-}_VzL_v(B+@ zux40~*t6}|*;~Zk^UQ%(FYC|NJ=Ritj{OFEyR)~qS#0&OZnf^UD(!N68+*I4_gwQ* z>ulbDINf^KzQ_K%yf-Z{El3&%dvKrPUbVo)ATb;4Q2kvcZH?@?VhOC3cb`{%T>rp9 z5jSvB^`4%z<%vDC`(i7*18$*;6H8!x;IKgd-6+Be4@T)jFOzcj>-~1i=9r{%LPCcsMrBBn#u+{En zR7VRArY4!Al=I~BT;(syJmo%RzH+~^z&S^pH_%m4{Y&^vTwMo_U#X;MmD-Br^LQ`u zdTkTi8?YBQXd9AyS6@XR#SV@;viKLs>u6g2Yg@$$UR-zaPmsSC65EHA)cUTHw-zp< zw_e6#V6Wl}{^ZZ!O@?q>^$}Z?q`>~4F8+`_=6LR4Iv(G@!m|BZ+shLY`*=cPzxJJW zK>J=hsQtj~^9Q(+*8|;ih90+5NzGaj=u!W|QM`5DT4+6JJ!Dl_ORPt&$E+Cd%Y58= z%6i&*##&)5x1O+`wasVHP`wJS2jjz zWaU_me@U1*=}I2&)ck^Z_+Q$)d6(uM=Hl{q^14k+I%2bCX`L&}fJVI@vAtg0HXpXOl()lzNMQGHHNXC-mC zMQO_OG0n6>t+{p_3g>vOrFMcA(M}Za@kZ~Qq_x#f*4k;OXzjIAQ9q|?9kotcXYF*Y zi*|dbZi;>_dz9Lh!QA3pNy{HaNGzF;sO^-a`-wSTIxYij>gVe8cXF^8ef zpPF9hi=s9>>YK2LYX4MWH`V^BnYEj2s9ANsX@RB6@%oecv-)fLI{hjA1%0{xjQ)!L zG@9!r{Z;hW^ZMWP=TKo)`pfz%{qOopeXG7%U!$+p*Q3l{)HmrHoW;&VPKEQZv&4DC zdDMB#S*mFHo0SuII^+^-fOV;LnKjTVw*FuZvM#pPqbQzH{kOA+qTxpRy*VEoZyZ>OakC|GHMtuT!)pMM~TM<{3n*m}m|2x+*90 zrsaps3iDx}7J9^dlxKrho6nnT#M43MI&;0b!Q5!RXznn-HxKe2<3r|;=3((BW8Pz| ziT4-t^iK-U?}Y6F@t$70&~9!YXScAAw@1=A# z!OH1=&2RaW{AvCSzu%wZZ{jcTH}|*nxAM33xA%AScky@g7x{bod;9zP`}+s@i~WQB zL;b`3BmJZO;7nuFb3(fxKMdroS@I%Zi&0%HVawlfgBO-x6t*otE7s@N7;bFgVyVdk`tMHhW2) zKadpc9~hQBI(t?2#N5uo!GV$4tpa1R4+pmdZV)NTmFa}>q<=rQPolLDdmacr;NOWw zMEfbPUJp(WPWQjd9{h{SJ!(@_YxX4Ct9AuTtM?3G<9aHFgRiV*?imOB}etkvw>TD?y#ApL_w72Tid&kQH>fFA4{>>EaJ1+g*aF)TJ+d;{TTy4PMU7a!WTFT%C-IxOVvAa{ddVcU z_^oEYM%^lxOk#uI68lYREV+boNXfm58hVo-WFGUsr5MzZETPr4*QioUsQxvIo;fOW zl-TBId7qgVhog7*Y?5y-7OQVbVWq8dmnfs3{jk@zo|LR}3 zjx2gnvpz~J`I~C5OKUVfe;L1SQuIdS6WjccxO2Txaiik=+5CoIlf+i_FJ|Vn#L}p@ zqGs%1Z_QnrnPU=5qmKNt`KVt8WXh!x3N1tAx5WQwc|Ga%y4oIPUt^E9ueHb6W9@PF zb@q7sdiw_ZM*AlF&-TssEq1AWt3AQK&7NrAZcnl&+f(d2?5XyhcGSMho@STX)9t(M z8CVjtYVGlR?YZ_}?0GEr+4JrD?FIHbtiZO|Mxp$Z-uns=XI-X`?YUO9nB}ux<=kjV`WPGAIiTkCX*1_f7iz z9&-fq8RziYo|e_-$U$+!3I zPwY?a5ABcakLA{9_U9s}Wh_3jG^G7XuhIJ=f7lsQjw}ty3F&onf}Jt^$kMPqzv7j; zI?dI*!%DILGHje-SU6*_Z%PCEuy3MRH|5wii~LK1%>sw~%dl*o#je@t-yAgjuLn~o zv+rZo?4o2Jpq(?YMAETCa=w)n%nIgG%P$Bl4m=v%6{rjz%yt4R zs1Mf$HU+i>wgt8ab_6~P?8d4;%#81PdJz6oTiMtCKh=AQezTvm>g(%m_)k?8Jytck zc|fgl?p~{%$JVOnyK43G;#viLq|DalTjv}UuvD(j{i1gw(HnBCb`vT&|089$V>^zM z~wL?aJo8YI%hfEobHb6;IGH&!BhX|JAE9_>FZqJlsorU-`Ram zKj%WHzjKjuu`|HA)Va*LguC7440MW}LC)oP2^j2L;S6zxI#)V>biVM}PKh(z=Qw|I zMmP(6J{d1pIU{{Z&ehH+XS8#jGuFAr8Rv}mB|FzUH#j%?Qk2&U#|^E@zrk=1g~HICtZxV3u=_GuxSiH-h!f zI_ICxo6cL#cIRzptMhkfv+zscyz2bJ*@AC^m#qh^D(5q2r}MeBYW^133Ru(m+u%*{tI7L}>0JC;thM*$@r-Wdua)+f zszx{tJ(2&J_(hDB@E^P6`g_*8I$a;ZI~n*z%@+TiUk>7Y^I*Q%FMQ<4R#lawhpK&* z_&@gIFQ?}0>`|>dSR3X{{I$$634u{HO+8cnLHCR8#PQBRLLCXC*vG^Q^#}2(p2;y< z{^0y!tcQu;3HJ#_&mWmTj(r><6uP)}@(}NF5Wj1a6*GTGe((JL`NjD?Y<2jmaUACx~roI&_|;Y|^n&A*Fpyj%HnlkrUY2+m^LWz^W>e;vYq(tJwx1+Aec zK*Ws0=N^>*kN9lyiS(BH(D?M3ji%3eA-3TLxvz`ahhDTX^g=&~wYX94>t7t`ZbN{{v9SeB$O=RMQxOOM=j^k`RLd2SNd zEqnxFmfxyRk#|81G2?1be=xU+kujxV zz2#AqM$uogNA!V+qw4K3r|+E}c+nTX!g_|IQnbglr?qF8;j&J9QF{rGNv~(U6)GGhY{C)Y0@>k`L$&cpuAiYBQ?V23QPiyjWlkH8GHCff9yvd>_B2PB5?x?pn zpFVtg@-qyUg@^<9y%)2>n zB6n_R@ADiI?`GuPe1G?sqMByn%T=FEU>9lJ<(Wx#r%*-Dr>N<}Zll=J_|}Ps*R3KbJUK zn!h4{P5#UI+w$Mf-$|?;4mqKWP;RJss75((wfch=;I6Z^93>C`SGh_)c0pey#BU~Z^w&{>Ht>9)ieIhIl?*JE zY$b%9vWyX}6MlM@(A3bZ(ELzEs510yXnkl)=&jI4q1~YaVJ(~z_J>2^mf?2cF5w>G zzTwNlL&KxOH-smKr-jQyNnCeMs36ob)D}DTg!~=(yYlyk6!vF^nuJ<}+J-uZib8!t z142VWBSYgu6GG9@?9hVHlF*Z(RiTZct)cCqPeOY_2g61bL24i5iCbj?3$+2H#%0q)DX2u zi2Dl}KrI+@fSMtc0%?#A89?tzh&ntJgdE6)CJ=%GKxc-~+o2ZF5+cwF+5kNip?1(7 zIzUJ03|*irbOZVjLPgL6dO|Pg4Sk?5^n?CzF${pqpcn?hU>E{JVHgaD5ik-)!Dtu* z<6u1805`$SPzn=ZB20oQFcqRO4W`2km<6+;9OlA2m=6o!0ayf!p#qk`qp%c~K_xs1 zPr(XU3D3eRSPg4nEv$!)unAs<&9DWw!t1b2=@2>;w!-P*oN%*nt8j;Kw{WlA1-VOd zpUhpAyD@ib?)KbIa`)sO%ro-R@`8BjcYJPX?v&i=x#giZbBA!oW6FMRtK1H`-Ew>7 z_Rk%ZJ3Mzx?#&!OBX?fz;@oAqD|6T8Zq9u(cSr87-2Hhri`Y>~3tc7S~0&G{u@4d=TZ&6l+?h(UdbwteLekksLIgZ&O0k zXhr5yyD#S3{Lmt5`DLM}CsDwJEzCA*{vDyu`1U?6z^>5V(1Fll zzU`+3XkmxeAXBkueKKejnot^ADmJY{3ra=1aK~`ha1q}-Q$Bixdx!gl2ZRUly+5tf z;P9~U$nY5Y!)@BBap9Z76T(wyt7h?iYIu5hc6eU+fpA55Dc=``mxPyvp9()4UK8F( zY_TLWqJX!!@yTZ^PIzhf$?(eX>hSvT%i*ozH`yaU!|#Sa3hxZ>3GZi*{0tu|&g5CxF3I-GmDi~TYqF^*5 z7`}r4!`pknSxu~e_%oR#hsgpWs35TC?Cv?cC?EnND%NYouGkx*V#D6B_uh~uDmDbM zU>8KJAU5o%hz((vCUvokmH+eRJ=uHp-rxQGJA9t`&Q3DPZv$|+%ZmJnxb9>D_HTTy{sClwxGN}*LJX-T~&6Jv#YhJ5)yJlw1 z?3y{IqGnFb{F)^-jWs{i{8}`{xY)edy4a4k;LCTuQ_Axw zTmx_K{PTaj8@!j})qC!?)Xh4@j>Qrd?^V;Wrlw|tnr=0{YWmb{SF>}?9yR@H4zB56 zGcaorrtRNT{@F%q#{7G0Fzt$;73+&jir*Ahm&|`|7sWh#?_BI&>|NZdxIH=6qdYam z4T{~0y^4K`+ZA^%?osSlJh<4uIIuXVczSVg@uK1t#p{YgiX)4oi(^cO+DWx9*1lHz zZtbkvIkgLGSJeJcyuUc1_+)W%@x|iw;*8?^#aYEKD97UBisE<0)x|$cVJRWsU-H!c zUKiFiuUm%_&n+%2E~Csp6@M=UrDmm;rFBZ}OI4-1QrA*X)1hQaajAK!b*Wt`Un-S4 zm%5jFm$oWxU+P=htF(XV(9(d?aix<>XO_+@T~fNLbVF%qX;kSh@(n7TUK(7wsB}f? zy3&x+$kOQ2n9>8KM@vtarj%YTy;gd=G_y3jG^aGbw4~Hn`l0k|t*MPokXy#kmLRv> zbIr}IU=~G?Tgg0%AlJxP-ypY&xfDU}8_$}I_uzMeF&~VNV%$e(!o%Y(gh#|(3H!(V zt}qUSUlGQE(Ef7YG7CCjLuUl7i3#@NDWVY4p@Cq%~)J`x>II5j$*Ew5obbHK3Kb&3Ds zTND22+mI6awF#YXMQA-w_ss$scNiVr>{G&DqB9A9jm{$cEn++#<1Ef0{4+Y2lGx}1 z!XUbk&_x#!hS9}@QFIAm^XO8-`{J>L&&MyY$6x$fgugfY#5l&+bc)-dN5$QlZ{rwM z(;@DK9>)k6MrU$9AJyyw^qAal&1NzhbO3kx8#5<9jIW9wiua37Aa-^1aJ+wXBC#p) zz0rVX@0o}v{&75+{)6j9#FPGbp7nQ#_8~r)5o$x?ouYk-pUXYTE%DA#KjP9na%;MSsKxMT7b48b-&B zX4J|7GCDoJmZ$YQ8NqU3bUxQNdG7z42L!MB?p%H4x?7Q6cUyAZz2B_GmGBYPpNKD} zE%iOsv`e3g*O$>0rUT&Jy?}TfTH4H5aD?-A!q8VXQkr1}3SetO2iggL|6?wv{ z3a;W6wH395on#h6MfZvxgxgkZOSpf<{)8u1oJe>^#TjzfWVSZ{;GNa`^LC=^&CTXM z^SVv!T6TR~vR(0W$y=x|vp1*jp`Kyiu^%ym=$rp|z2Eg;`Y}e}D|-x&!$f}3R_ZT+ zj68|2=U1&ou6?dUu4AreZWH#tJr-^8zm#D|%X>weO7SrBn9Akgw`!fB@GrktHyOd zSF2Pp_DU_&_irV-?f=!f`M*=9z!aK%Fg5sKwhsoHPTVJ4ZFWmNbc2GMc^}Y8!7ahl z=Hy@!K8m6EC|))r@lm{PMpGwmnK9x=Gvn|}%;l>z_4uwP2fqiuGtc=?x4(JA9q10V zmF{pi*w%25aiQIsH;7+nw-axO-9x+~b{}eQwLRJW5jL~K!ULlA_HKDgcW_KD&c(q% z-sRjfIM#3GPYq7-5BRr&@%{t9m^}xn2SvtiR^VN1Ce}0~@fa;N&(Y$qH*@SwcAP!j zj<=2WY-Y&)YF~E0xZmtsp%3@B??#nTpP(JBrGL;{-ryY^j8FKk;1GE)cW_M1BVRBu zeldP2I5wUdPYsTbUx}v&C&V-28Ns0V?fAXmqeMOL8`&Ixn8-=g7bJk_BO#q zxgB$R1efOa&g~yumpdqTWH7`V9|yPjcJyf8!`r0C2QT@z{rkLg$nqYszj$r_hr6}U zu`J%4wDq@Wx@$Xv`?gcDD&C#{_3rJTBe=wOD)(_*J2{{K-7A!hLi;Zx%`(4{HTm80 z`{(=TPspE{zbJoAerSF)KGMhYQ}WaCn$FJG=a=Pw$p2YrR%l)5Sg0#>FZ96|xL4s| zyyz$6HNUKILt$j$p29=;%U&$JQJ9IhY+<3Xu(~SX32(isDxTtX4HJdJ?LVd z3w|wzJZ-e&KC>(Lo!b?6EAG$zDecI;-od4#xz8J1x{Q0gk)?Y|4{;~=V(AU;;=U*?rF z+RnATYPYHFTidVp@Y>^QPp`e8_Nv+;wYS%ft$nn1a_zL*x4CznTf3z8JMKc`x>j}V z>q>Rq>Nc<2zHX1Y1M3FV4XQi4?vlFe>W0_dRrf&Mla-zEbM&d)9*;{uJRL_@4#MYh z0ltnKDu?5B8CyBw-+a{HRsNa}@=3lmUhJBD=X}q6pZxZft?}OED@&Y(Tk|V}XOpw< zbv*Xsv8_lwwjJ$gdW1TsSC}rTm$z@~<<)D;?x{y{58CwtvsdcH=$Cpi_Dj7OhtaAp zFo&mo1N~Fa>2ay&bPyvaw=vg<_r+X`H=K8d?KITU8#+aKJ(|CXx!kET` z%`NnJ>|loCo!QxNpA+{r!|~GWZbsm#+1rfd9_egzD|bZano-;foo{aA&gUX?JNGtx z$&I_Go6KnLm2NS2a+fsB+{Hc7NOL!LJ-3^CxVsu}?&V(UAv1=%s0rpi?wKAlW4SAO z%8a9jM{|ckx z-(+n3r|xq%*UfYD-2(TuTj{eX{mTegxfhbYr+MYkx{IR4>Gg0<{8hXl zUK}rtSNYeIb$FA1&*X;W#^fgMBZnnVai{olGBsJAG$yN(Z<6o0AN(QtG5NWoS%t4C z$bDW#iTk|n^rP;;S@plw@Lm6>ocp(zt^SK zs*`MI=OXo>*dqT>ORq0<6PL1v)ye+zmaC92yj*2+mGD4n#?D|~240ABcf2ZRBj9DwklXtW-Cr{oh zbNC+0;jcM75X2??HHUwKa6_JozbWeVAS({ud zbInuz247#u-=t6yd1jLT%o5IZEw88gYx?&e4g6)j!g||A@XR>mSUgC~vnZ z_G>vNThXPm9f^^zoF=g>EnDvo*&o*dJU40CC|)@p5M$i@-o`}Y6S z(sXX^f6c`+_rLuY`&Rs0>fiVGKdoVMc)_AcX*ikCiC?0uk}7{|`lNFDq;zd3BRkUN zlgsIo%juIzPiQY}hb38TQd2BjD%;bgvc)WxEtRcmnrt_V=~8l*mr6{RN-SHNZJF&h zEtS&BR%ASiZdqbk-mJ_lD=(FpE|r+(W&Nh5*_I_OTbgZ|tu^J9E!U=30=X9bnyX7K zsyeCs_vErpE$g(hPDeYHEt$n6kETg3jY&R@NluMrdBrZ8Cf3MeS>8!p1GBU&?<8hz zX__2)7R&O=v1Msl-pS1M%F?pDQ=9TmZQAeDro4E)$~k17nC6|@wBKn>d8akyoz|3h zT2tO>O?js^<(=M?cY0Ia=}md3H|3q)ly`cX_c5-!r{*3{L&m8PXXHHLQ)&2g8ZtAM zlxNa#avDCHhEvk;xiow}4aI+YYVO4}d?^iIPD4gpkv=UAUrEF1Y4~ayzLtisr{NoE z_+}c;NJBgbcr{G`uAZho<4MG#s9WBhqkW8s3_Q zqtfuUG`u|x??}VZX~;bX<>Wqt@a{CcCk^jS!!c=iUmA`}!~4^4Y#Kh4h7YIV_%wVV z4IfOy32FF98qz<(uQmM>X((55`Ae?as*};R%GZ`GCd)J}TPjx%O_Qrf7R#2(^+D6* zDwxGs%5!y)+{%+(kPNdGgv0Hz^eZe2+DUqV4U=KKwOhh(2=8%yWNEak#G^wbG}}rF zZ%PT`m6kRTFXJ7PvbDE}H(Jhuc$KA9lR~Rbh6dHLPEbX-k~bK#$3T{jaC=F*+gsLj zwE4Kv(dOe-j@C;GZ8aGhZYb-7oh2^*;A9xjsH|glq<6ZFt(B#=PSR~BNe_0Gc(6+v z?Mx=~L;_r_-eqWhw8j2@>AoPI!;mL)J8V5+BYJyjV%B zI)X0`NO(}1a&Vf98mwqz4kfOH;ll9ASST9BzM1m;NOC4Wxvl11b4EL0bEPlyi8n z58<#tj%7qZsR$2GQ;v|lLH{)Gk;In<)I~)UQg^fp>Mj`;MzVew6Alk^vVPc1);B{X zg|BA@$w<5yVv`ZF1^l|KZ@3y@u~CF8ZF`B^4zg69N;o1~Y;upSBxRK?$kr^aw<5A! z4QMA^ACl3$HJ|P9&U{&aOu8ml2G$%aYX)qe<6`^C$lx|vC%B#T!NDEGM+Bo;e_3!R z;mUw325WMCApMba%|~Tx!DGaS29J}=2DAiP%a^jIllHUR(SB$fw60{Rn=858Jjvzi ziQj53m!lChG)CBv-Iha>+9qWo{t6 zCs;0P1}oDw8wn#v?XY*Lou!W2;ary5S>dRiWQ{vY@;c5G$}=!6IVE8oO2Yb-Eg9`7 z59?4K)}cHc9pz!m*O5NdZbW*c?MArFZY;TMciDpNL43LGDS7QC#8=r~lGkz`k(V~W zxzn6*nQK9~l=qCve%B(toOg}N9@i$m%C%1S*e1<2C|&;~mJW9(6OMMLrg=|E^PZOG zIz7#G2J3fnXA)M~A(G49BDt)zw9%F}MmdK`E=x+O!@m z^~jM*tu43I8f%KRN7?zr8?DsuN}JZKy_MeFWo&Phamfgdf!g8-f0u1BCQ@1eHALyz zI>-49;VSp7Y|DK|ywR;7TZ4+vM9nWT&~ z9}?b)?~pQ>*@UC;B2rHCG4T;*7V#D46XI*k+t{lEenyuJWvjF(_CSjwPK#m>#}E!R zv@5oKEb)=}DrKw36W(b~ARK}3QnpP^v7fVuH<}X(R~YJ=JxE=THq6>6A` zxKVH^VYfiavm%i4tO+O&*TAz07X{}KE(`{lg4R*tEv=)XgQZ1qesS%heT^nu=I&%2JZOYN-L0fF zy1NKhy1Pjk>Fy!C)!j?@n;S!Tr=wJ~N=ikmypM2%8%y|u8%Ow~yPxoTH=gik_W*0I za1Rn+;~tVSxQC?-jw7WE9BH!JaikU9?K9Y9D91NB)n)csQI29t`uB3noa?v|yG#{Z z(PkpHyd3|7w51%|8IFHL+J+-O6dwX*#xoF96nSQs*43Ppk@P@IyIPl&Rc1ZnqfCKy zI-8cnNAR{ZX;-a@uQ6>1hwFX_X@6HAS3PkgA|mH0}#8}X5L zcf#N7j)eEvLr7m`4<$~ICgBLXC*hrTZ_-!TeTc8I`w#uON#Mihw!XI2G*6HCkAU@1(NcfZMOt{*0A-&dhCBDdQM7U7iaF(8Hc=XWa@-DOV zTx*~H-Do|&WqSRpj^zTNyFDmV{ zU)mm5+Wq-k@*Plap9hN4Dh`r%O06E8>arZiiLXM!$!Rz(4W|>TCrDM+P*0HR)bii5 zwxsL&;vJE{#W$iV+myd`{YjCokB1>m7k`N?7jKEGuFs62^544t?~N=)-gO!q4ufGlrjXGzQQW_FgeEN^CK@hN6`v zW@kyu@@95sSySH3&XShp&Dyi1WqGsqEPl&uznPsSEz6tPS<?~?~>7elt5uTDD)xkk*X&ZnL~BZ%WJZW_FhKvb>p{#oL?Z&Fm~`S>DXfl9uJo?9A4h z@@96Hv@CCCXGzn%?6q8GiRpeNre&6x=9QS*N@7{w%+BJ2&hlnmRVwIXNhTEiK(3>mgUXt%wC)FW_FgeEN^CKNz3wP zcBY(7c{4jpT9!Anv!rEtGdpu+O?fjrOInsUv$LdSc{4j>i>ADpoh2>Ho7q{?vb-F7 zT1Qx~DQ{+HNz3wPc9yj1^znt!?mS0F%%RvMe2>3Js|N3xm-+G`-LB0XseuXWO|qt+ zxo-`BRfFlb-=6!KG4dwm+_XP=dt+{zZKPY3JZ!XoByYN^;yFZmVx_0n@b=|2&U>_^ zmsb9EcytYahwE)l&iN$f%zTzyVji`9?W@85!G*z9jEuRT@h*vL?$&Z`+`6uVEAsaJ zuDpGJ2gbXc#z?74d86x1?mkAYeC2*}zlP_BcZX}DjazQZytWpV9V&OI+_iE~=Ct*z zJh<|(%3~|X<04yrn`>Wr!(Rd-cAQT0qZBTB~JeN%0#9kc#?b(`w8 z%yFu#?!qjmp4D4c?^%6h^`+I*4$o<7-QF|*rj+`@!H~z#Scow(g~#xO3P};)=sFMSo>`4 zOSP}mzFGTD?FY4sYgg47#=dP;cU0Z6btl!0>C~oE+fD~|8rbQ&POCcox?!8nn|F!3 zwCU2ZOR4KcT`%2eO}BOr-232~hr89A`ilB4^}E&YU4M9e|N24om(^ceKdgRK{kZy< z>ffzjT>oQ3+>kV^)zGG)T|-SnsiAYjW(`|69N5sm;h2V38|F1M%ztzKXY=PY<{Fd6 z){W~lwr#9!+^KPw#xokPYP_ZKj>fwhA87ojadzX}#)h9>{c{a(-j;t=w4KN8Zua%y zz~GYL8b&xj;Nrj3aUFHMncLp&%$TOL-35$)xrsOSj&pPPj>0eQ_wcfC%wOtw7wUL# z>i9tF_~>#SPp$l{atZS$f6w1tXjN#(T=oqL+cB$spK=`^$=J*53Qra$GwO17;j6-T z>8$5gRU4;ue0tT{RYR-BR6SKSh56K9rgdzn<0!4;^_b6A$BgQ%j`v}l<(1U&(CUX7 zVL6d8mRiR$%S`JyqK?=8OC1laxwYu1>HXltliMIp*pSOE)APEY}0U1TE`zXP|5RW%>TU6Hu}cqX&qNK)=|fO8_#UKwsC0V z=*GJnA8h=%@w3KxrMb1WwVN4Jdo*w@?tJKmi=-qQ&f9R#hO;*Oc*FPWPB5m9<0;K5#kG5F zct%~Zu2UV?arw8-z3a?a_mp*qwC&Kgqx{|RHJILUf5MRrT&kO>w~+3Np4B_ zMYNjtnD51$sB3cD%lg^B+%{Q^y55{|;X9-I@HV%(xq9B%+}Lc1uleU13~rePv&+ca z`S|D2Bo-=m)Rg9b$oec9U4kuBuI`ok^pNEq6A>9(Uu27|9?%9zgrG!dGf!ewLH1y zP}1*7a}c&1t4rf=8MXHwGhQm=namA%SKhe6`&GYV+~-6_em?OZ=gTxO(@5UMvXT*S zcty?s_1P!)Mo&lg#R=0MzW5*J0sQw_o8y?fa6c{bJ7%cnqpIlfs1Q9B=i@nX%eY;% zERN$Aaedr2`YC;v@@MY0xMQ>^{+cn;>qpC(-|$jAJsQm&QOw;)$URCk#&+*+2H?p* z8V~+E^clQo-t-;qMs{br3->8I*zKbq?2dMVeZ)S>=-@9x?*<30?C(Jsv}XkHdd%h7 zGdM9A6r99}UwISBi@~Ju0DkQ{xQ?!puL-q{est@*JKSh@CnI#11-sHWQi1ogIlj*p zcs}=_$8k^k8~38Oac}w>4-5|T?Sli&K)n3N;^RLK5C8G__fNpPKa~EvVf5Y&r|)hA zJ$K{irF%Gd$h=Pv$p`e0%%peZ!(f{ED0teJg7<7i@R4m5eD3?%_Q4X{Ay{fV2FrY1 z@U^WD8f-V$+-~ez*zT^S-Hg|#@9Oe)H&?K`yDB@_^|hC~!|fIB2z#aLZ-=-+_7-=N zyraktbEnw5+~xLecZJ{3U1lG5x7sJ%UG_~~>kzYink+w5R=_U(cleP@4!>Bl^rJJX{AGOh~Ls&;0wNzvF_F8maq$7;{MFM zW!v(lrulw9zme_jD(qQyC)eI@;194Dx;=eYdxty6=l!2P@wK)X%=Vp_t+S44894KC@CtKw zs_i6qpMA!SwUgaA`>ea)PI2Rdt9hq>bJGg{@-{)084`?Sme3t`?cfW$r>n7hxuUQ3 zI|Lv5_4y|GQRY^9Qy=%;Y!CYRJU;JjgKB%M<1P7krd#8eK9Sy+LG-=MqW|iX;8nY~ zD=|-~)?Vd~v{$@ z?7ptf_H&)=er^N1zuVA$;vw^(E1+!Xug^GrtfLa z4^FVngSYIZZa;gIJJ2q0OM?!~L)tvp$sZIP6ddfg^4s};goDF#x$i!Yx9g1Xy9RfK z3;hE_g1ylQ-=wV0ObozrQoi25Y#R&v7TeliSrF=nr-W`9t`E)}ihYcdR?k zo#40j`}%FTtH03Q?oaloxKG>{ZZ$Kb0>8cA(eLK>_Ivq0x!4~Qo)g^dPnTI&!5^-l z-`(#S9L-#*{{B#RNifXs;s^R;ec#}L;K8_?zmPYqZ|*Ph7x?peqx!bdm(iSx-qAZ1 zn^tUHu~o%p6`LnrlCH@{N#}TOyr`m2vN-uVSyHi0#g-LYRP?OqRk2CZE7>I3Iq8=4 zNV>-jjB;NXFNx>HpC@}Jdn85P-M&S7H(8o2OEyhok$KX5VHbt#gm>{w);CPT3Ui_T#XJ!*E!;Wy!r;p*^L zw{y70?Gx-D8TWl;-NGo0;>bry)I4etRYa|$Hqko46~UFkeg1){tvj1peeVXJM6IH= zgE9UQKf(PFMgBVfsJ}j1%irK1^Edj({Z0M}f3ttm5Ajd=Tl~|0sGk^a=5`GCi#qyY zev%*VcJuf9w~`X`X)j1FOfE_;PR>ovvs;I&{P?J)y}<1eZWJ!@m-&anJ)(8P9^nc< z!arlz3%?6{h2PtC!yn8e;cw=#@b_@fXuWXnsGT3_C;MCdvwoDH;&1cM*-s)DZWXN` zZWHCgZKG!4cEOY3K2dvryMNx_;Ya%y!cD_({hi@YW&&S@d^G&i-{oJl8-%|wN3lmx zX?g~Evt3YQt_!XT_w_INyZy`l9zWIJ>!*eNq7HUT|BBtpPq$~fUF_NZReO$q&5!Y~ z^Bnf0`;}+z-`vmsKL3Wl)IaFQ`ZvRF;Zi$03j8=fgYO*3R}OmcWrN=7_Y4Lw3!X0~ z_$4x5IGN6T;g^!vlGl?rk~fnX$x+E$$=k_0$-BvW$@|PAp2=L~W0HZ%vB`(YN6Fx1 zUQ*Aj;`wGB`s%i4%+wCSE@sD|uh}Q)XAWZQ&B4JD<`Bl+92y*H4hse_WAkit3cb~* z(pP;NJ=LcN%nf3!*eJ%ZjAzu!1Hq%_K}M{M#oO@^V^-c~q}7bz8QVJe(zXfa*mZ)h zY-O zJgsTfSGw; znYm`3sW%OHoEF$+;rrnS;mq*E@T2hKa8~$9xNf*!*fwkzt{=7!JA@s>0sgD-GCw!G z$J*MMl1;wyEjOSBo|`TbMrK&Eb&nmT+h|EF2z=2uGS1%}eHG zGu2EpubAoP)$r5sv+(oqi}1^EPWV+gH_V5Huqvz$Yr*VU>+T{B1wea=u4ZkpaDttP8Gn`?U+ZA>tbAc~TXJy?S&JP#ZQ|;+tW!NUHONJy@ zCRIr_^K$T&M$aaNq$ZskEAL9vx2Am@H;X-Uc3w!tyX@t?2pq`e;lvHo85!BN`PAk1J)yPqIEU#M&nv zlKqm7NoA7feT^Ic<@+Xl)r4=G$X8B!{l{;s@I@8gryyTgIhc2K92cMF&*BXoNApe& z`AW<2@_m+M->7@kGwKs{i8kdsfSsbvqs~$9;Mk}XZ5VA5^@=u#HjcVR8$~^$x~Mj) zi8hOh(H7BGNk8VQy~udlQ{zwKSvecGvNzfr;?{ASc)>rjp;vq$!UJFqGF$9 zrOeu^*f)JQy1XNuH>0O-4wtutFXnCGydykXU=q73Xvcf*u1|i+)tfi${k(trdcFjA zV{lV2B>sxGs!!yd;>-T!i%rYZZ#HFLZ2CU8x?(^1N>lE4`EHYZzp0r`ey!-A`=w$J z-tsW0;-qFl#aR_+r`~0=*Ua+MD$lS@|L{(jDkb$TRTGD31S;MGh{W4nRHDbwk`h&- zwMs18u2Z66XeT9l7u^6hWIK1G_zi?uzLV5NiM~VSc^;y#(2W${&tbURPKoBC8!OQh zXm{wz`dg!$0KTT^A82pbg7{7-z9b=PK;`?75G_Q-Uj@+$RPsag4Z4jItwgs~qTA5z z6rR!zPw5JmeY1TTN!y{!uIP?s@B$erhj1i_-$THcWOgZYGs+vdQtm?~zwkPUZv||E z?ygw*PShTXT_4?3u~H{{DOPN`w_>Gi`zZEYbYI0@g7#DFW$1p2mGVfr!QP1;pxB2{ zd?bRMfgYsTcTn;Efc*$PM6vjy%%O@E+a9Jw_}q9xO^KdHk5D2x_WnvN$1C=NIEM~U z;xEvn6#E-`v=T@?9HRtcvw=z=Wj|I4jzh}?*AhQo35KI5D8W7GiAwMkI!FmVKu=PF zPtlW=pdLL%3I0S+Ra}Igrtk(}V@_9`)ZrP5lX^H)aboYY6es06TXE;3=O}IjI#_YD zP^n9BV(0S|*MLeMaEs9k6enf7P>IH&7b($`=*3EOKYEE0twzTv@pq`y4Mex1W0fe6 z%C;b?LM1;$kE7$2sDM78L}Jeem00phdxCfl`mhqWL?-q_{0jP#5{tg9#M9BK3cfRArh%kI@M@V5eXWc`UoX=PeWT3Q=$mDvUCn@Z zU;w-e?}Pj;ZC8+WXDWQ9*DzK$g;Cgs5xa)bxrXtKhVi*6jAS&7;Z3n}etoJ$KcHee zU_7HSp96Ks7*)faVhZD+alk8~N9QR{+HbwW*ha%0WeOu4={`^x=Sa7N60}DbDnSJ* z^#Q?p=wc<1HYRlg!Jg<6puI5K*YN&=6vp||@d1sbOTDd97!PgCH%fQ_`mN$(RN6hq z$_PheepDFSXv|LvBOHzSS&3x%YK0Mw#{2?YpBPJPj2s&rm=w{zvPxSk;3*Y_7WJuYAkI?zz=FH#~{dWh0Q7WM$<1DT4_hv z%2GE1{?ha}CjFg}b!6Xw57k)NAIR^Cm3;tyRbyK!>F>c>#DQ5Ie5yq8)SX>h!T-u< zYZSRQTR9#GPDZ7yAlGTTt`eMrQpbW^vn{q3@ZIt`Cq=H`^7|(Qr=hYxX)hJa7VAxM_vj6?dT#g=~xWmx{%UppTq_`u{gUeir9-_GZ=%HnXpob}L z5GvaeZUM;;?j%(52t(mW#mPB1pp2XgM=9^l-Kdq^=}>uEMMvW6vuy2R*;cx99~5Gu4c}u*`Sp zMM@Z=7nk`Sy+mO)o3WQF!Of`H2m)!>VqcKw1mkR7-^Fum9Psc?EvVVGR%ESN$)LgBM#;*^!74s(L0pj zGjy~P%t!B3{C=pkA@Cca(r$#_AZ-O)1uE@BkajVq%ueWiiffOKRs06%IK_*tq^yF} z`FO?ci9VqCuIPhhq`VI)?i}=C#plrpir*G}MByz~hB-cp?DH|jABM{LBgj7GoDpPu za-M(_`^mWhVJGxy#fzOMmiZi=q_`#MGi6qzlNGlHeOB>R=oCdpATWE#Fn7p!vDFJo zv>p1Q677h-qZ~eNqd&{ z1hM5T#Yx-wq>R{A$^=f@(Whm^#?p3yc~QnneF$RjFBE1<={4v}RBS&-VeXW%Un%sT z8ar1pYoYU$pgCHvm{w?mLO(0x1{Lvh*ab>Zg)UUg5Ok43f2^^K6(jMlmEaCk+KsR_ zELE8OZ0xc!axN@an89Q0iZXklD-~Bn8x=41T&4IO&~KDL?E9@kKd`aiDdID*-z&jU z=nsmy75!16zu4HH6nR#(KP$c)y1Gmc^cRJGWn+I;m>*`uzaY@pY~=YQeMXV<^baMF zGXGiTSX9m#pikNaMlskYuw@dI1p+h4jI_BFiHC~#9)hUM8ECACAA+6-o+Cp(9w51~VFVa2)SBuha1o@qz=Oe`(iAq^PeskoR zL~sMpbriWa1nVly@JpZ5`m)HWNjRbQ15E`^jVa}fkxTd6t z{WegG$_h@lE#(8bPYik}PWIDN zk!wJ(iQ+i7f?j17qnj#D+C^{0U5sv4=1p{S*n(r1x|8+_;%5!ERK!OZY*l7=bZbSP zfdZ}_g8bG6+bZrvbUP)K_WlpWOWC(q7$srk{zfo6p*t#aT@U1MU<`$!pE5;!Sivr3 zPC)xA@+>OP%qef7yD4%%6-ZgZi9PpFE5k zb*kdU2B*R4*o~?T&M316JyUTBdY0mH=-G;sYr{E;6MKqXz{xS5t9Y@i*af`URqO>$ z?0kXZ4?!*KkNQt*brzr8Z z=yUMAG0~Uk3ra1`*bWkDS7I+nYn-+__)0D&3pMy|^OZ$L2OFB5pX zfsuP(A?BD|8zs37T~|qNM>{Bd;lRkfyAX4%a(^Sl9IM>Z$o&iN-7v1JlH7%I{BCp7 z??$(W9f)6w?hHp0zZX3QP9wfQdN!OxycQj-h`&&tjRj9#$+cMSYdq~#t{p-o>9Sq0 zEzql!n0Dr_R^r9zHHxW0uT>&RzfO_Jm&}RP0W@g;FO{A7JE|q@F;YOQc^)kUlQ?y%9p{%t;-9`5YBngZRaH zUq_1cZHpf*^`&iyirv9(i{7JzVjr4~;eq%S30U$K4A_GLCfJCx~-c2sN^ zv{I2i=P<8`&pRvt*E4?wT7(kFG1e;nTC}bV?OFVTDO;nop-_%*d)Nr%ICcdoH^}pM z*aM_owC%80nPupviri<1QdVI(YzA_CD?!Qu{$W&(Q}_m?90F}B+^WoKRLUg$3fn01 zTM=$shBg##r?`Dksbi35v-B7^4w{PzcTl7)hdU~fMR!u%LR7X3k+e0bSBPS?FJOa6 z+SG2aJ8@}8dnl2#uRURJ(xqKUIrgOtV*h@M+#`qkDgFUe$_J6Og##4%t&{7QT>s=A zE<9L~d#mseIF$8Up@%8K81!((KY|{i_z7r#Mb6joNF~A$;Q+;7haRQ)N717de?5AP z63KZmQ1LgQ$146Y^f<-eh#s%_$I%lMe-nD5;-5eVDgI{kB*j08o~-yG=qZYS3O!Zv zx1gsf{%Q1d#ScZLt%IM4o>@lP+F6Q|dKQ}sV*7KHNZRmV#ScTzRs1CMJjD-3&sUt( z`DKc~AH7`hZ=q7hkd)9X;acL7Pwa~=6WO-d4y?3ev6rw4#75x9qhc3`xCVt{3y?mg zP>vtm9;h6%un|bPg(V4O)4LCSaNU1fTqcbEAd9ivDeekko;_yNW$<`HyUncq;cDVWDlv4!wE$ax~{2@fif zltGS7*c%>JqIT#6#mjNaKEO{#A62~AK=uLtS@dzmi#?uD{1o&_#fxp8Qv7r1(~A8B zov1_(om6HkRO|)O`l#$%kn5K05273@`w-+BCfkLm8Tx#g?a&vLK+5uBnSIcgl&C%W zvf^(?rz&2yF%4ef81F!*D_*wuYMD*Z*UEg0zOHzw+c(Pmguba5vFnU7f1uLt!H8Yo zF7qe)j^d?VysLOA`+JIvcL?7v^9%Zc68w(NRE)IA4;At6h94=WC;G7>zTR+_V#HQb zA0R&6aJFKuLqAo-uM>V&W?%Gk#fvS!Q2gEKmx>p=&Qbh5=vRst8_!kzz34o}i@od1 z^g|nzr~^7*v0I`G6i?lV&rXmr5$W&fBI--(YO!L^M88(tF6a_P`m4jGikJFarr2}P z<%*ZOmGc?=7<8rLrJfrVxkpQ{L94j7{7C#8Mef%^X%is#bm4c3`wf+I8{E(64~my_ zTk?aKwj+7KUy90l;2%U+D}F30`vx!VOZF#p1KEcl$0uz9tkmZpN)(`fDt;WgM)9=G zXk$h8*K%7W!seAm@u#6J6n_TVLGjqRat9^ugkozUrma@?g-sfwqKR89lhMIuT&5ctZVsif{J-y$w)oU=l56v{bU`4MrJRdRk+V(&!C^{JA4 zh<*lNlYSg3`+$Tzl}i=AdT1(Xhn2K}M7BY_RZ=&}JY(`kG3%gKk$#>$bt#zbQKyK% zKOZWFI>|?h`2O>;Vs=Dxiu42In<<7m$a_Wn_4!0G*gjvOi2ps`Trt!~p7tOFN1!bg za|pVY67)w~DdtdgZ6!DoZLJvUGv7uD2B31BV5qzNx{CO`^Xn<*6tt}({_lJ{#hi+Y zT|oTc`SyyT-R3(e;up_%RLtopjavxLLou{qZbS=;_?7cjiW!AgE8_Fb*C=K@T2#ch znlCBl0kl>Te`~%@F%P1h6!E|2H&D!2bVEh_#QDyOc?j*Ih>tekRWY=`{6KBCO7INYU9nSh4HYiunBU+bC9Swyh$5yZm;F75n`|5&vCY+C5mYrL=Vr ze_meNH&{8oofIc+aA(EJvF@TcX^(vsE62U7;>1?FDKd^Pzq=y-y!;-DJpkQPaZ*=% zDKhRX&-G1kQg8bx_8@d$Mf`dBeu|7o%kQT+sn7itD{WHt0Zz6p+XZ_*D%%1l`;q)$ zuR#w{+)=2UZ(y%Q4^zZHm_J;x*P%x!;xEkiSM2rZk%}9L4p3ywQC_wS;#G@rpYWJwdUzp(iTtEOd|}>KP0sO%5K$Cf`^u`iXAY*g#Qa2zzx%>r+or+$lh<`4Bkz(IMFIL=a^b*Csjb5sVzbSv2V&6kASH%C6 zze2I^qgN{8i^_|QK*r$Y#V+7JN5vLkXQFca;O3&z4#0khO5KB-hu)yrkI@?yHy^!8 zv9r*d6}JE#qR2R!{4I)Gi4Ill59lyOd`|h{iv1BCp@<(UFYO8JPpGsZ5WiGj+6_n_ zRbJW(h>tmcyW;B6I~3Q5j#gw0MgC4DkaFFv_~X!f6f5gWI|F8^n!L0vFp^i=6Ug|E zytE-O>!ITm8Pk!!Uomab@rsN+$v>c&cIbmjAjkNSV%A5cZ9yQ%DD4SMdsNyG1Rj-k z1EvG|m=cH$A6HCARO|vWjwb)4A~$dOr<8!~`KJ}RsmM=MWK2zdl41(zGm4C@$xl{H z75c1V*Pv4ra|ZgH5}c1duNXPEUQnc;IWOlD7|yZ$ON#V4=U-OL+2~XyxCou5m~+rq zl;C1?x?%>SuPV}CoqtU+=c2DG(r=xALow%}Zz{oM=nTcoM&DATzc4T79+*$jcNFPA z%)hJHLr^&n!F5C5SL~ta2a4Mmm2(X2Vd#g7>yCb;*uzmdufX*{XDKqaIRA;_dZJQ3 zka5O&DHFI&(9aYZcbxxRalOzl6gvR@QgNH2a};|N`jz5(qjME|G&)a_{-u1qVvj)^ z6zOxy&sXd~RL*&DTc8USI}Kf=NdH5Av0|kTzgDC#BELkDF^l=7iu6h3mnkxaF~3}q z{)zkw#Y!EmRHVNm->Aqq$NVZq`Y!U{C|2tKTg6R8zf-In>-UP2d_O2wj{8SNeEIpG z6e~9PSrPw!ezju79=|B!@6Z3Lc&Ve`6n_HxyW*ve{!sjh=%0$0I$ERnK}JqPQ{Xxw z{>uW_g~D1S6wy|&F6o?8g?3O$`o(A!bRzvKbOYF!bnH{;4%BCOFG~Ftwk4gmP}mN3 zqVBdv`@){IG0Iuk2M%KW7tli#OT86n$AVpg9-&z3t#G7bskg!aIG((m69w7UX~ZdO z;dCXGsWK4P14tRE}B0Tnx91Mw9WK7%jW=0a5J7?P_|saHs_Z$au3lIziWpsvK1 zR*<>@FL?#(M0|$@IsUJSb3BD5z;(ewVTEF)4!I^28rkLz=qe?V`r@1{aBhpAsqhp0 zOkCQ=YQ;*u{GwQCr@t!FFI4zVk-n+I?~3&K6#h_>A?Tk#ej!d6wCltju)8x`X3(eBWLxRjwM^kV&4 z=%%n4@z2oBl|*c?1@s}EdaK$}N#t0!QlgRQ)=G3Ix{Z=xm#S@*L~O8~l87z;p(NP1 zYI`MF3*AA9ILE4XRASm#)lNz@2HjbS#-h7GU&?knx~me6LU&W5;ppy4Ona!>1NLNn z&ef{Dl!Use+FMDa-u8igsduTXeoC?*DjYz%)Z0Ny^eK9z690gnuEcVDXDG4Q{%j?t ztX1d0VC*ktJQvOQW`{gdx9Tb- zX1i6Kw^i4Wej$1-V9S{8R&kD1-9(&aRh(m0oCmRNW2h1zj1E)c!%?v##K)l{l=w7s zq~gy)Z&hNkht$Cxtba5*T8WQGrG4B*`XE&55)wJa`;@3VD)kCcPjs9T^+E4fqAuuo zCE65yK#97c4=Pb7^dTjZw*0UXbw(#BQE&7SB{&v+REbLHV@k9k`Zzp6c{V|xQlbse zrxo$JR!xLStkV^JMu~c$Q(Hayhi8 zVraY7TPpE7DCdt5e~j*<#BZUrt!nHPzmM(*`xD0w)d#?##9u`ZgZ{+dMvqitY*;-2 zF6FmuDSD-nhz&Tu1b-5GHC#g*PSER>n7XJQs^prX!<1ZmbhwghfsRme9ng_VPHcIr zlH+<+JqkFFa$=K*VFGcn>yz*l@ng`5O73WMl9Ho6SJMuK+)*g)t@;Jx9CP(dC0Bud zq~uzmvy@yrbS}(e{S(lIu!#6^=+{baA9R_L!^Sm%5>vM|v>zd^MPo(Ap46Z1!!L-`WdCZgy>szARJ4)5yhT0*fBQ- zy-mrDLvL4dW4SGNN{%*C43*pgD90h>Xg5XdBINp^9Gj3k2&K&yx!&ZCKq;e;I~=`C z$sLGZtK<$wZ&Y%JptMUNN4bk1C^_0-iQ^O!>|A15iF(N0fKCS1%bkW|e<4S^s~rOz zM{Zkmf)c%qKCR?7MQJBOj_XM++Yxe`q0cHg&Zk=1iIAq#UTUSyNIK_(kn4qVjS_O3 zqtldJZ}b%<*9Uz~Nz-2^{(ms{<$+NY+5cVLJ>8R;Tr;@|giKCC60R7+AvmC@5DrlU z0Zj}Zh=Kxg$Q@Kb6qOs)^}b*g1jQRy+!gOdMHbQZKv!Mmi07&t)ARehs_veiBf$5+ zpIUZOd0qYL)vNbjz4xjLh1b7YSr(987f03le?ia-~Uy>dN43(rCBxz$OQ9O`i`z2BI zbMTZ=yr@`*C;GF$5r07w{Y`iu@{`7&9vJ8+Z;CMScfQ^o@!P zxwRkjVgJSW8T8$c`9?*-Jl)?QiZT{Y^plD*6VGckmppiTk(8W6m1!v&!Iez z`aAF>I-+Rk&;A!tUc%4R56s>Dui$6u$6F}x;pe;Y{7e)L{n`JyC>r(S3zRPbL;ct< ziuPALzd`|RH0sBHP`<^_g!^}*XhgSPQNZh7jNez9D4v6Og72w#4&mt$#fvfgDj6je z^@s6H6U93mPajGK>VLvB2PGFjqwTK(C`I@g-}tIT6we=cb`-_)C!Uokb>MmQ{i_}* zJ@GU8^;IvFKKL19^A%*uS0nNBn|O{w8H1nEzpubIUx9~o^yw>%Hx&(Sef1AfTyNvK z8wK>y3-P3PP`u~kiT;0$_S`N!LFcdc;b-vY*Poz()^5C-JO98Hk^^;dwPLl9r9^UgIc zRsPh2k|OC+hSW|fhG(j$bcS@MbPl^a=*?r^6gD`Md0Bn^mJa7#6kIOpE=|*?N=(Yk zV435ySVmd4?Du8($4kCamR{sbA1@UJSXydP+IT5d%F9j78;_Kc+;*edu-tN%pOc$E zUdrjf3fkr%7}&NXNp|UNUE?K9a;uvADrDUMm?z0T-$ zM&CZC_wLfOOV1v4-D^*)>DINRb4lk;)m4=pD>{^yl@=5i6c+^w+qY|*-zGOFJIkHn z&hY!v(^6BCy`CghS9SbWq2*PwfG@y&0Uwp(teV=Itm0ZFD^OcpR~yKx;Xl=u)9JXg9Ud4@gEC*{IRiP-#!*>M%D7=#*WF8cQhM2 znwuH^yrVf7G%j`TKPrVmZq`iyZwBOX)Gz24bnVz5d;mXQivL18f)C))9NhmvDA=s* zzZ4>ca@1UJxpsrw(xs|kMG8|THdw-~oJ^Ikf-D+2#D%kN*(f#?MuQt*y3gm+ym^&1 zEWmIRijom1FO$nPS?|h1Y`N?)HeDb3@w%7UjOvne%S+EHa_v5f6Jd?VTHFfEFXCI6x<}X|$;Q+DUke9sG3wJK_f}cil15$OFvf7#G2ME%T)Zpk z-X@Ct+Vr@@Y6CZH_H5<*t1KAYzj{_Y41LG7+rlxXeVb0Wowb$zxmVilw@3>_`$`PG z9WaO4UI7y~ZuYmdL(+Mzz&vh$E8Ob1t+!!Tus!kp4IL)_wfgJn#nzkj?iHyAf30A9 zj|?LIVlNyS6vbaQp1AeY>`N?vx%XK(cq>_1;=VXws!jo>x>cAr>~D2S1Y@9Ix{0$? zF8I{$pP%~2=g(Hf?5M?C4*WXc-im~C%>h$!3NRyDh1qHMp<^N#-UpM9(Fe}Qr_u+E zvqtg)eX0<0%leMzXm~{UDKWm`r_Avk4wzryNq~&$C^5}*BQiiZ2ZUec(~{bOSkqM3 zrv!64!Q5nQFkv>>F!j*o*8!#+QV})q^STzHJ{WE>3Ox0ab zHn^O5vD+i-3S*Lv;HS$qa!3->G^tUA#XU+Inx2k)i#F-G>A8444f@CD^LxE*E1AMI zP;o{vF5?K~)WP&ABTb~2>NVwM>caVKC$y3A-cvK5y7D^XDbi2wvy6L|rL|9oVya}7 zgV$B3X?GY4j{eHVgua(^jmKQOvv(hRnLXKa#u=ok7XR?W;?A7kt^+;OpeMm6=Mcq@ z-W|nl5gG2_(Nm}IiS^)c!yn;esXXaBIh&8D;Ac#9CqEnh2tRY!at4{9sJE#)vE9<=8T+I8?dZ}%nMuHgHa zcAb2WcER`5uKcmxuFe0TgMUYtIAF*P%m_zN4rn>?l5d81rN)5G-(m zJHf1Qs|-jnTnONg^B8o=QHS*V~Tp&w>qW6_|Ct;;!;dE>CEPydbnte(rdQ(Rt-zHlyCP zJ7lamVk`@>amIae9~mnvp=0#dxSZ$%(&@M#eRjOAhKziT>n;IvKs9w~w7w;pK+XdO zas%r^^*CtcliFY{)HB%K&2Z-eS*VIks}h%s)*VC_3`(QMOjETu&<+-RrXTO62Xt>v zWsNV;Ejuey)3XX>JhbA{KsQ+YWyOKo8u3H%5_#DF{OhhxOVS*{N{(+q^TF(f9;Hyt~qwqg_q3!@TxJxuSDNDjyl;X{iyG-H74-B zW4770>=L6F^}_)(iQ6NVnkE`9F{V3Vw8PSeaWH9+wdGt6^{d3Uy#2%fH9o_fLOaH1 zT-qwMzeH;W3{k8~n(?fcximJoeoHzStPJ#%H5vJy8a4-NuJJmPWs8KkeW?+g24g=z zSZ)Gh8FxZR&QMhy%Swpk_+*wZSifVIG=vY~MuP94e|iUdNV0;JjjI_{ zP+aPKoJ4?}EXFRT2_`jZ&^(t&Lz&bjFDJ{FmXe&LOYK-Y-J4zMDk_m{PxF`5bW^i) z0%c{zMPR6GFi~AV(^SR(rt#LZ&#_*wZ)E;0*~YtBTbnoU{rJfR&t$V&-$TaX%x!Gs zFTb);+vXj9eAZIKIQ+}8rL%AQd9A9mP=>N>a$6{4B--caE_eAZiO4JVFY~cgjl;aF}Ch+pxxZ8#{ zMxz0?&1%>-0jZ;OLGZj3*fLTEll4r9szQb##O_*ECVAEDW|~V|jIowgCXc6ZXcMFt zm`+h#O&HKiT+k|IC1@&8>@UgmW9Zsey6VbIj?1a5(X)x`%9+h^#YN>XolG`lGtPVD zb>hBr&g{Lte(_VpfMbol9V%`9+kWA&K548pCwKGS`oH}#l3j9~n9=*p_k9mPHhaMF z>)f0heJ{&?rC9-cE`v1-d`DsK+-}bumn!3yHs~A${hDvj7~T)glb5iBbBA?P{aKl^ zT3l38RvySkAN(YPi!?pZy?crL$s4Tav(FiCyuQ(B*@F3!`LsEAa*X$U53vl_ciW7= z{_?A_5tC=b?4?Ym$usL#OddYp&G`-80Up4(KrXu`Kn{AKUpoX#X^NA0jcmdw%&@~Y5pvTr{-bMt27CF9KZKK|nKy}MkypD~{K{s-gfXPEx| zv7`URC-F^^y@&D545_WOREXRH4I&qGn(9g{YU{UjfnaWLLaEKIfT062I7FTbKwMj; zs1RMQh*4lk?$M)zFqhl5$<7208G*7IJtB-v;+taF>K#enbIs0u9r}%AujnC{xmG8+ zxcx$ORLEA>1U^sTnZ?{*B`xOj&02q&@)s~PCk4z3+~mdAosPK;y+~u^fVnDeoesU| zgn?dsF9A$Z1O|fg2L{hA*QtFX^}utb^x~0$kPGAo7--5MSVXw%hHU#02z_YYnO|cl zMIV#C5%s9h6~pyrq#jXh-Y=ppiD+vy(D>Ro z+|7Iu9JmjKzl+$!%Zb~Mz+gXP0vMxDq44J`_%3eU{GsjbyRGy^)VqpUmV% zr~Ja`VB1W{tTuU>IhhDbkeufdg#MT2Z4Y~)*cX7MfFOhdc|t|cz=AF#qu9s#*Zm?t z*!_|25BzWyYiImrqO66s*4=TH@u_FxjKBTOwR`(^Q`Y=Vtz=gj>qE=gOk*kdhta-H z^+H>&DL`6*4P!|&bP9`9;xzOL|98qYghgthS9wt{Jf1IagIH@04We~%h+TDr%?w#{ znA_`U1;1mp?P|gI%B4oEZ;5k{hG%jwAGln2`8XVWU9KPD=Oeg2y^;D03-YrjY0A3h(8<(Gu#W_NV|7I9 zdgN5({|RKfsT0RyER&>)Abe=CI?;u>F-j%2!K5KR*1T;T+Hi@oCxrWQL-&&=y!1%u zbpW#PGsX~=+Vo2`!7kuEgsxl?mP-nG2UJ8V;Smt_9tcU+b(3po5!%iu(qL69wPZrq z+8Q@KP&A}l`PsGBr;IgYjK&}IimqB6|K?ERA105Et zmFStGE&@(swqVM$QRYNp(lAGdwKkQJX`)shuaX}Q-7hzZDe}M(xTosZ86GACceB6=BF#ul zTZ=Dt5qs3!Iyro-F4Cem$?774wIxM`Z4sr-^rzBl9qwIER5!B|u6q;r_|naT3fX|M z{c@|a&+dDoo>z5Xvbp-bJB|b<4P5te-NI>rwQF58zX&=3hUSleSn2~sQRjWAIFj(*Y8Q(tEfcJ49A8!XS%6Q(VH5l<{ku?9= z_DqF;zkW*|lprTq!)zV*rX*Q2{ zgjJxJ)aeWt&ndCH$D&frDZG)C1ZvSN@rYS6I+)KSp4SjPRjOIF_x~_eVu+V$uCzkL zM6)GA%@|(g^gPLY5ilp7F9PPo^93*o=Zkpv#Pfy2oMgTTm_+jhI@onRbcI(c50*f_ zs|r)c%NVbbLo~=eWt0+YOJR*@|GR{Bm6x(^#;(vzXvW9nF$gov2`vI&!uF?jG3Osd z-!#wN&)`Az^gS+*P!IjJl9k5I^H`Wwt-_Ez673+q9^Veu_BIY&SME!+rT{)= zn>h!tgKYob5~E90JFD5bN6r;`PkI3At@khUaG#c z`Per^a<%Pd<~IJMviT9RcZ?x?Tr;KGU^mz%GR#1-O<<$I^*0`Ok1N>2B+Innfp*wv zT7|}q6Ids@-ma2a)`>mVuuqgp-8u}Y1s3m{<8GNK^8U~w!2m~IF#f^E+1R1^K@Tzh zy7z24b&vDK4y~)r7rJ)9)D3Abxl^)LQb{-k9nm? zDS}>Z9Whw)SJ?mRe+xa!$;1(a>2jtjOsNYfo1yYg-PL_p)8)xbRge~BwQ59WnjscH_gqsYiBRk8V&QrPEaILFS9?KJ| zL#m~viuo^h?!!*>WlP#+M~!_p{c9FXzHScd%8XAlS^6J0gw~*+Yvrqt2NvFR(?WSz zXzLN<7kkd}bq#nNV}Nyy_A6*mEOK&z0ED^A{eJ2ZH&m`~_P3*zsHN<3~Jy;X(OQ4kO~W z1Y^c+X?>)<$k#^?vXiWjPKn-J?m5P(9x-GG{dsKqI*yB2U&0*_SzjWK?HC6R3(u6j z&LmiSooV=;<3X_MFB~>OUI}0w<3g}55&ch)UjkUi`0#d-du*>iDL=%CgJYa{yKOjZ zf_xM7%`slQ-R>MVLEZ^q9plDfp}~MdeE!K2#NBQEAnAy^9~LqK@GoF~C{kW98@?3s zmsnl}MN)hU;<*g-5h2g_X?X-tOSdTq)I#R%M1?Nxl+U30@FqCsS92YMdg!6$#=}Ba zMRW|j3X;5*`=kWSLBsSPI&$Aq0P~q>edY>U8nR)z=0!Qcz>T%CMzHa>AM zVZij~Hobs39Bzz*c@r?R`1*vycvgq6j)jrZjN$Bn)pyt%_v{j5G7tTIgRhsxyDP%S zV&9GH%c=x@$pH>MBmLD588bvXjxl@qIe1WDAJB+Z8$#OIM?XK zc3OQQyCr-yb{wVV@DcfHk`=UzMc7ruv+%9p+d{@GJ-{pF(oWXQxh|pa>Qs1>w%po(gVs+E_ZjHNDrvn12G=J$Po_^!Wo*f&a`ME<#~OCnAdK~5@Qs)JWMrz!jj$3& z4xv=IR-;D3w@Q{+)*$9Gjwz=b$CxXm>q{g#1C_fU?2lWMae*EkTIC>H~+3f27VtmcX%6o4)X742PJ>pJdK4pAniUG z4E*-KR$xd5if^@qziS1C;#UIZFmfhhV^abj^3iY@#8A4$!x+OAk^vlsVp9w|Q*7GP zT1mXSLi&6ByEN_*njn4^*O%~@(JD~wEp#C;)OkAPV#y&ex^ z^m2|P?%#MlZXC()-iOPj1MGR?hQxk%*ZEuy9ANKpn1p_JZHItSdU2S9es}F#6Q+^F zB=oy$@0c)WahQaDckO!Vf=0Wq&2wUhd9{) zxpY?ekXnYeeNttxgM`43!jS)=C@{^CKQ@lU6L&SIrg-4U0`vMPnF6^|SV@WWC|W^f zs&d`;#{XE?38P0}#X1>(X8!ussEe<;_S%VR_OTzo{#Dov_?D}P<^uEZUaVx#$MGlO zLu)7##@nAA$9bXL8oQ0V1kf)NXIZ0mVt*HFUe_IHBTXs`76Wk={sOo((G|#BBzelC zWOBYB=h&Z(?qJUgx}bFLUdI9q|LH!sUtC?U9mFQF>7kG0KE^s@^c$|-#sp*2(6wXO zlc71spOJ6=)EJ3xFM)3s-$I|DF}bhlRgM#_Iqu+nB~6MP0w%}xH3kO0rhml4z}I58 zPc{qN7B^ohkHP^1|7~tG3}`}eGRk>KrI<<*oB%vQ8~Hxi5(Wf$__A;a_Xz}eye3sj z_4&ykK;8goAm}368ifB4Z2a7~R(|~n_Bgvb)FM}cK4(0k?mHTKSiU4w8B*lAp_^%3 zmKZx+-_lsBHAEZuDqt~~;kK9eJ-Nz~&xf;Fs z_~z00Y6pf?lg&b>V@HvzV~dOM9L z%fr@2%{wjU3o~Z<1)rMK2gI+{TLcUicaEGJqe1J3lOs&Lny5&Idgw}%h zO2}W@K2ujBQx=JwUrcW6ZC^-m2y@2T}&gXJc)spZsdgBRel2^N%Nbg!+jw(^~j=mx%F}&9$a8=LsEdp*0cXFrF3i$^<;o zi~8w+S)E`kcIbb#U@&h6xUkx?aNss~Wnxy{w1vgfXJx?17!!$)H^7z^A5P`}simUC`~xGw0uV z$&&x{4_#p5(PY2A$m7Jae<^cO69tN@%_=|S<{DC(`^xOF^WNY{M zcVpT=*eVQ-7sml}>A&&qK>pe|@HrW8_mcc|z)<`w!I<`O!oWY@GkSiBxHrK_0jW!{ zIyV`r7&=Rl7^2>TO?L?b2jnwR$00qVNgZ0{%grcqA;HWJdM6mc;w&o!o^U92XFxph zpw58rnfM95?{&bhSn3w+oSTBcH}J#1F5sua@jY?~VaXA+!ty1#zC00@Hyz)##TH`` zkJ;>2LpUlcDNbKu@tEjmgutsVJx2u7m4c=#4#^#c^dj)l~Y#9^pCE>{3+%`g5t<^}z3H0XP{ z?8fg>x%?(Bs?ik`jG2A#D>$5F-1`ZJ6nNgyf&FOq%WOGIa%rXzI;US(^#4o z6`B+&tcuvOfdux3mB4790oEY=0tRxp zpLD<7-#ywxQi0S_x~6_h0iqa%l$@d|>I4LQSQAZyi-)+83Mw_3$r|~=5*vip{Txn; z0~;O8D{Rk@Dc-(gVMpXVWcX5(b=*o&5FPri>DsM8uIa{Ya81wVxz~wl=Td9VuAg#A z8|Jxg%$V_ssHnNMHqX6&dA_5sse=7pxEn``&^qX{^px+Ai<4M1DnEjl%9r7ue?fl%@x7;6DFy0aiCJtx29dCm* z=CNbt_|_|lV4$b%vEq9AXRd?67k1uk%vd1L)$CU+FGs$Gec}C2)^~5!DZo^>3WFS0 zK|^n+L@?AZYu-SP^LbgOK*&H%29TAPnfnAYaC1Ey7a?cuhb_*OzWiatPI zqMsZFc2=UXfvk=6Q^;CcSDCUTZcbrdYD724sKLlbI{^Jt&ib(eF7Yj&JVxJ{PYSq$ z85!8Xl%Ij^KK8LRI^5}g%6$x2I~9??Vy3w=?7$?W zsYVIxF<#rUm7Vdix*Xd~#1`M&`~SZG%U7ObL%;c!4SUYa182JO`oTYcN8pldIQT~p zAEG_cS=DB!cIa4 z-Z63Gj#oH4@`FVtjH|g-pwU6>{3vLPE@VmIg|Zqq(yOf3p zh;IwChKaU?8Qa8AnQH>#56E1M1Li6D6IYPGoy}xhxLk^nlQdVtH}iEt2E01cg2^S> z$N=`ILGH*%kMzK5E2`2SzU{U9D1QOdloX6GmH{#yHJ}d84^pKX zT{&8S7hzeTH0jt^rik@}+ypoLCA8#c$&?&y`0PT8&JGh%fd;YmI+E-IZdrh&;e}KVqZfRzHjLpV3KYhmhOO`?I z7=L_r*C*XWFUy&sLyGt7DK`KG@Gr-K%bsRa_S_g}2a|6fctWoNhWnoo5sH5oF})q} z?@}Kf?H>vsjb*uI#9J>}ia4Ut^Q;<3Faqaf`7_9?+q*z}OLJ+%dkm z;@_;tvtzUezpMK7DL($pIKIZOTo*dz+N~@aI`LSDz2P$Y1YW!ukx7#$U*a;lozy>g z2BsMErFz}i4=oRdrKoC5ZN~lu{L1~-nxx|>J*H}-Fk{t5to_wtP#1o`Kc~>G6;x&f zRFyh_jomoRrd%)1C?|hcAe$deu|)30(pbvE2^Y@(*VhQ_|2l8(=Z7CR?xFloru;f> zmVtC9c6|5hH+xNg+}LT{vuP7M>$}iirJU_;A_kUWe@L$Gz}JV2%gdhyZJCvk-xh~u zz~!PaB*^NznP%WNbB^ij37w&~6Vyihx^YU`Itq}r%05cD7AZsWmhYkf%<&DO##;Y2ua6dX{_L?QL zA9-c(iqJ!k{(h@$eBxd@b^3xk8<)&`XNK`%_8*6*Oqp=ukn;;FI_-RD$vcy$ynWM{ zaZU9XoSzeDH)+$ncM-_Myx{orxed#M+bv7^oW$-e+ir=0K|JNHco^*C1RXH9(GFrE zceC0=?L)pKdbh~=F7`z)b-YXRg5!pH9=}iXLd1~l?{ayuAkJSc@c-Dt&0EfJxQ*3! zH?3KD``$w73DGahMkW|)pWAHIFOoHApMQsNNgSgxc>?wYy%WnL$XW(_G(&8FSLTD) zEgrE}EIdZtp}e#>C(DmxJsdnjTv1nNseC=q7k)D#Ty%|F%=~~4RbFlUWPCW|oq0R%sBaoK=BBr& zOnzs{LpwWF6r4Zg!U@2N2fy-u!#*KML~$&Hmt$tIN$~W zSu^U{R%%;R6zEVa_KnkFD_N{NVXOu)1H09pR$N@m0!4_-{PZ9BF5`|h-z+pfGJb#i z?QnPt>uKD6k6QB4zkf7_WuCR=j=e3veXwUMyM6t!zk{Z**<6U+AcGR;9svo60Hj=q zGj>FHP3OlzQb;@l;eB$7*Q>7?J&j%Jze1s7mFmAZ57c810@?u&;IvlGxBWytwa@1T z>M`D{q<_Wnd_8ok<6ZFWO2@mzx8mIuY;l5jdqv*m{B%nk-_}EC+3j=vb}#`N<)Rko`(&83>L~%9+h#@EkD@C{F~ey_s7w}6wnC4bcoSn+WaW2 zb52`2G-txQA1hOd!V8yj`Q4oIjkd6Js7i5^v6aTKZy;a0T6>m zrV?OOEL`q0`vx3sdav83dINP{nO_0SM8{~i(32p=wKQ?fK?k$Q1H94 z>obQDdVF(qK*5j7hpfNRLunebbj-)b_M41dFMlW>mR}5g_+iNS;P}|D49Wn3tTN{W zaF4_x?HA^r+)ZyzfsmTmtFexq7o20pDg<&Sb@NlWUmmpJ9<(8L>LwB*R z8*g8>k#)PrIFxnE{~lJ}JbwO-8#mslY(C!e;s4Kg2n1Lh(tn5l~# zpQZ8OvMs}(ERGGn)$ng2J~LUsICO~k7R6@-J}uJ0R@$L>fq*&8s#<}e zc!BuV>I8cv#kYPDFpy_Q=w{diH2FmOG9FLF0>CfUyWY##p+xT@zR(ICxW8WD)*?+6 z?K}MA95?Qd7BB}-0p^!efcddC7zYm=lFp3pFU=3i#Wv{~X1Vb+H~L3t0y&NG6*5?k z_~LQSg%bwnNwmbtY2>6hVZcjmqUE$TMh^P?jN{ySyfl`V+~Z9} zsIWuyPEH9T)T1E?HiQy zHm`#ef{0wVS-vqepUUR>Br3U#geG*s!2pLNY!*0J?G%#K}xe@=Hl zGJ=@gJM=rdprz#8va$h1-?8C_jF^4b$;Q!j>zO)5e*b7EK2Lf3Jbv*OAFmeaXxx}~ z1#j?kBpHVR4P*8@LYAW)cU$0DK>15;(lmJU7?L(*GOyrgw>Eqh;D+|xT%NzgvCW1v z3fN{~)xv+k!KZZADRvOE*Nn+*$flffe`d$L=UAU-^E%?#u$)b7sBxX~$Qzl3>8Sko{VKMxgO`Tf+X-(M+zj*Oh6!=JhIl4nMQG|Ul>8|TS)sgItO^04?m z68;ew?Vv2qc6P35V%pITD85$OA=xgzwVZ7fFpl{s+96v{z^nkR_?&gDpFne>rvpZg zo{yk8vIXrL>wd*B1MEP0 zg5$y0JG(i3SFnG^^+&)ET?9;`oQ)dfY$TyS9ERsho+sKj&g1jbsy|mj8`gJ0BaPY= zJm}hh_fw_fU?Iri$f1kO7MP;Be#&cvbKAjpK6!L#AG_js+s@fp)%m}%%R^tuU6hB6 zE;X0+>U~)^_QCOn&{v$I31Av8=uuwvRpQ+%c8L9ma=X?b+=8D=$@xzt1f_ zGxP#NN&N-A!9T7IoLBepIeP%fIdS|G4FlaFV&O6TjCN>DcstNj*Cparz>tk0zIB*Y zw(>3FXVK0I7Jmj-EY1fL*aIYIFn*49-i_vYF_)cvhhB*H4Tx`%UJy99NC%>EhX2S1 z`fLTS_@rE^d$1-O0*hfBlPuZK6zM8c_L~dS4B-!g(D(a&9vm%;Ey6Im!9}>S8T-8VwXQ_jD4wXb#_*j`j`8RZlMq4E^OC*th@0J zmHWCi_3YJT^^fy3aL4b1vA&rPJj-Eg?&Y(~itW-_Is8O$4k!A2;<1FSFU~qfTd>j) z|4q1OA*r0lHTEeBI84I*2uU4H7-%W9lW?zryMgu*uzm7#943Arfxww;Q^7Z@6XYlg zm=p4!u^Mx-FYO~hJMd6L!ryL8OuUca)MyEt*5*Ul!}qZJxqO)n*WrGQMHZcZ$6byP zF>q<%llJ+G3J&+SlpSJH1AGIx;H_m)ZxkcM5)!-hk!T0E#`W^Wr6a1&x$_(&Pn{Hc zs(ei6!D|Pzz0WHb){KYSH1xvpm+G#qQyHBh#lOwx{7=+F#0u9$^Rx{^^N_;vQ%(vhlNB{#L7ieL(vw|&*o2!#??ymy|{_}66VIWT@kwZOs8)Jq5$GG8UKvP4X&;g+<$qIh#)0 z8ApBNcAi#g(bwuT^wU)7?|klYdht06nga7FIK%EB`qV~(Cp{H?N<%DG&OyI&;dF@V z6i*k8ay(>b(#CzaCbeO0xZ|Oylgd3_#5n~j_dRIp;EPwxoq6;9S5A??4Yg6P40$hJ zG4q;h`VKv_{SagD8JA7I3>y+U9eLu|)9uDhzC4)qbBYf#?=1M8OVx?6a;v4;^;>dC zW0m-QICr`&cZTFgekE5OVsZqM3oRy77_M;$2}G$$fyNV|$+nR{VT?wZe>d0ch`$92 znN(OEsLn?iA5O{kti6aza#uC^B+WxoOS|LLVYv9@)kFi816f(2Bvg$1qkjk9zPi6!q<`dhCN+7pd1T zx9YteB*e6-9q@mtX2B!Bl;HWgDZqIgVI({6inr}(qrz%~#=}uRBC3A4{mqWfdK-7m zvuXyq5Z5Qov(iz2q20dbt(;}TbKET&lo5O)%p+|(+NiSHh{9d-R!7yJZ{n_bJ2~qk zxNC^yi#CvP<&p7FCyIJUZxBn283(IP-E){#ING%6 zp=k$aI=^Mr>##MP@HIAW;Ts(At{*JiAn%r$xQ)aia3*e$8<)$y9pBw#!F#sQ?lyZo zBlT+}VG9U8dewsW7FqQM+Se@jau0`hekXL8=Dqcvrl{9t>H zW3JS+~f^M3*Kk0-rLW|*H1bG3k9fQ2BmU>8MNYB)7DS|l7%z{ElPlG}z zEs-@>CBylRplEz`l1dVoUMcY~hGc3StvlX}EF=ZaSVd_RcZoFV$(A(koEQuNT4Z5! zs3B5PlJ&DRbaW7z)_qU!)wBC)T{=~i7Znz?qo^l5-3|x`-;)I0ZFU>Rei9 zA>obA)f1zFMSF&sg9Z7`%(S?-p4@l)H#h#{;t?aSF@^V6W~Q-Ewb@r)Gaq7o!M*2RY>M>eK4;E7{_2QjOV8|= zwf@D15f@&<{Vq_DJ@JK8atgK~RRP)@Q~EAp`*`D51e9k3QWjWMs6 zrQzYj>TMXaY((>)uiw%Jai){v6S=YN*{I1(Ki69YzX%r1nWH2cXy*Xnnv+sm>}W3qsbv|*1(|08V!Duaje?5l)%If#JyU&gpPye?zy7(GR4zGEZ>yCQTp=Le5gwq-i4LVe`4;_kd9@W!$U@q`_M_-&eRE&ewCh5>i6VVT6 zA3T+)9y-(s4;^aa5O%`z`73zqu=EcTw~^{A7H(X(J?Lm3y3cH93!SxN_c2nxhW5Q$ z^*VH@fcF+z_0W-a-?8TF#o9#RHRwnI4?q2lATH_1!|IE$@kvhHXvzr>QhyL96H-C^ zLh8~K3JB@Zz85pU!x9Y45)6FKJO2(18awBmQ$9U42@y)ilrJkU=26ue9^t2aKW<6$ zYY3n};1$R5b)~)#9r! z8R11gZ(qIY<>%I~e}U71iT;8P{fW=L*M#TDxTA;mxX7K&v+69GaG#{Kx1@q;y2lgVtJb8=CYOotPf6KndwlT!eEm%ZsXutMl{x>B%0@BftVt^gw<^ zcxpnIVA8{VhzOeWRvS*L<63#b}*_M~A z^9`CIhcLGsFw?j`aLS=(_!b;6u(d@@!iJ$aiu@vLjt&U+k4(>mGm$6UlHEF%@$7%0 zSrbh&9@{w~6D1jYTAOB}C-iBp%`^B8hGShd9`*;1iRa}ednwO>+#o#u#4Q0wFg`mI z_~{a2;vyJt>3ucFCGNoynXa(Vi%C#e}_toBLzwD238ucy|g*EBxg;<$q*YNakeJDDaoM%F3099a*jb zfZLHjtiAJoARO#Hcj>K{-Qzu66eo7DbH@*Vz~!t``S^{**%p<O6(as8rbS8jbWx*3)*zMCD3}keWKgIDKZdao{s~zii;w!R! zV)UoO&bEwh(+@>PwXHwRQ4!{_60bk4QH!^ko%-`cCNoX&IFmVV;jUS8cg<~t$?RcO z#wTf6L+7)p^XFYZWA+@U$t-s{+Uc3LFgRLVij=)*`(YumiGemS`+x*;YKkc4~=tw7-qBLbZdpK59 zNnB6zBi378STWgBmB%iQUSUP%MvNWBG97jle!)#u5t>B&ch;wFniI!C(*^MLM%?=4*s9G8okfa&gP zi`YOH`jL)A!ENkF7c-NmqbCN=_pv7iE+pZn=#G_!mXW;Nty4DyC!w0T-YVVtIvu3M%!@@aB7uG!h8}kPsI`;0 z48a?-; zm?m`HCNr4H;WpS1FLS%?-}p;}Rz<5X(E^U%;o_Pcp~CrtBkpPYQc{wI z4Txa>Xnrs5)nM1iTTlZqv=9Yrgx$qYmF8H*zJvac4(66%9WAs0^h!~YFRQH7SCowK zH6mr!?2Y4igqpGfS)~qT;7XP&LnFjYj!_7{(EsFuBX5{YzD<5Q>G%p#fKdv;SoV6T zA?e32EY21-0r-LL8zY^_?;9h2K;E=#HlAdA4%J@=Uv!uHv&HpWGC=I~4n?x;s_?>n z>SKyWA>JT9pn7jqy{OV1pu`T;Mo(wQ?k){m_>MR?=RWg8b&QY~B(H-&K@#Zlu6WxgxU z#w))e4NZ-AqV40GlRJwwRyL`z+Kob55 z*@s_8%iZtMCojKa^%OS97?_Bk6wR1$@4MsH8^<1A{=@3@UrfFl*0b;Q zNewrC&TjG?zdHeYeQNYdPMi1ql}p~7H0u6ItlDBUlAA_j#P-5@71xmMg&4Xntq-3q z_I`0623rZcxB7&)3aw=<-!!0Y^asyv!GvCVOGM>>BGDT39Ga)m0T83d;)1 zN&;xKeQ8mazdRXxqGH!_=wS3xu8vkedPZGwHq&d$UU_igGW4}aZSzyBrr&9FYRqqE z_4gnB``q!~1!-v$=O*>+KTl;3)LrMn!tTAZnD#97K8amtT-+BVFn)4z8emzco^gmR zy2`j^`*gPJ-f=cP$R|tmp!);wwAUUp`C3KPAE0dm@$k@DcSP#B4^qG%mL7@JbAL6j zhrinLae`O4KULJPU}p$;-024%vheXAC{Jz z?PHuH?R)N)#F@C9FSyT|!{fd_2mX~A>jjgZqo^V9Y-6mLHfnFLG#Y00mWSVIcPwBSn3mEm6tha6X_G~+*=WWchpz4 zQePcaPd;}+vrbk$;cVkWetwJ<_l*nOopF9sW+0Y?Htcb;$2o={W9F?5Pw^0rgPo8034xUNg&K!%j~6FYU5=Q0;=3C%wwpv0q&a6k$Zt{nY8?q z>!0{zv5-Y_h|8ip zU=0X*u>DnngkiMTy%3tt2RXw5~)8n$bZr0B|m8X|XtYlGa?= zraL9ex9k0T&Y9k}d&X()2J}$3J^gfc($_9ezuw1iXg!^~sO00@IZ{*5lZFLCI`-RG z-==UI7itYSp$&j^_XkC!ffBzHJRd?6u6x&n1b-EKZIDA-T1*MwwAV)5rGhkXx(Ymk zUzXf*!1&kBogdtD&a}4O{k4Q;!?(wmD6_sDX(J1N8SD*7{yT8Zkj4f*UMzl-A(Jg! z^D&;>U~C{0Pi@53Dm8*>9!6bwr(*vmHd^7zM8cCcS_v#;FkJnE@h?urIzOi(;pZSF z&t>ChSbBh8Hqlbx2PDmLY!|_g5`C}{3mh^U!AVUUr6JazPZ&b8Oi1uoK}$-V&nN+w zM9UhVlaA#0gW(zQ?R)+85AG>Bt6g$I!C5_JJ#<76QFk5E`t=?Rq>0}^M`bJU^b;Lp z`7J-fZ-g-g8AjvS3w|A6J|eVefH*JiZ-S0EdX;b#xAj>xw6SY`|DKWoZIcTy!nkJg zC=t+!8O?n@#`<2&e8(8JE`T~xHarm~{{Ci3<5JGr5=~KX zoYCU6MCB>F!%``ev!+a%dUHJh5?(NIu%^TOQ+4kb{RZm*$HLPhmuu$L%&d?P0p^q!O)HL8Z=}$Z653XXl>frGfT#pOK(Jcbl=I6Z9E} zJ34|pr`~a}IDGq{f> z-1g(}@PQy~09n&L{Ifa)eQAH9`zfJ;DUCzN$ni~!xSleXLNqCKaU-%H5PBroSO#N1>lvV~)=`KEsYosF}O;_>JSu^l$xZHH$4#ab!izk6QtpSMZ zfIH32lU&^w{Q^9xOtLPk%*)NhxsB+veOaaDaHd^8R=g46krVX)uG#LZ$Bzx>R%M;p zF)Q8GDk;t!F`gmjs0_Qhs&foYnxP|cZw>S;_9Q_RQ6P;+t5lV1*hW|){QjL{9I=5T zfb;q7JJ^juS{=!#J{|yNPa>FC)^)?&%^w*bUDJ5!EO|+27GmYkO`5rXXQ-#V>Z%!Y zz#?3pH_-RMYxki7chha)_2EAS9-^Md&ZlzUKXR_k*f|UTfjnr!wOkq*yr3O}Q;WiD z$bwb|!zJNnYLW}4o~H53)smXvJu0VlJg!+IiAonCR?xQPKzq6~GMBD^gX+t_1`iz5R4(^Zq5<3o6X#)MY~>4M;Sxv&xQ zAfXEx6qZSA*I>&~1b(utHG$w@b6auI#OAxhON!d%(@6`Qz#Uizn%Id5oTwME6prai zEQKQ>b>5-l{}5*pH{+bXvEY{?=@G7YpT(TVDMI=5)ELDD$n#0Y8eEO|6MPh;SMkftQd50(lTP2;Ahsj)z!XgD~JvY6DqAU_Y6)gp~u=w?&unaSS7 zcSyl7hm_(@ejk|7FS-059lWNgX%1#vaZ35d`J4YWuJ^(_u~pUhGV}1K`zK5%hQqvj z^RmfbzF{1iaS=}5x_SQmP}oS}W4lb9t2SV+pZhG%$^a=u_Ifr=aUhK;KMwf9X~qNm z`N8a{DhU?=0FDhE{d|lt;D$skQ05^rw&9pGlv9Rme*WQ8<|0lA52W*2}q3E?>Z z!An($lh86!NcvUa)Ek)`5btV>LfK4*8R>BqyJLs}!tv8t{W`aVDI zDLARj2MkWNSLf269?}=E%~ytd#qQUMgIN_1BTeG%VBe3~&WdpSSpk$&W9ueb2QZOi z2_0nR$A^Ih@WCE3vz_I}YJrbq?`pHrC90j((%aE@mU2Bf-3bF5YCHGyIKIVo1mUC6 zxA4wXP~c_mLwg$ht9e$?RvMbu_}`Oi1G1@cXC7)si!;{wg`L)&c@)BKW>sp#v4?~n z#(L>vyi+DqTe|$TTuJp|{8e7c{iVDf_vNkU^^c-{8TS>5`h&(jy#6KBPvNvjaHH!MM zpXkBuWr5Sdu<$j4PVykTUegYs=LCNv>i=rj6OVED@NcNE<94oS=Wuughew95d@Z-T zc|GpLYovNf!993iSpA@T@cz!*7xfO@sh*Esf^V-fznzS4bc*1FJMXUH-^T6-(3Sk0 z;@jbHkbj$^ns3?gnrH3L;@eYkpWWXa-{#|hTkU?09|vhV!CLqe|C>en6LKz6p{Ox(NMv zlg6BngLjl4Pm+&Em5RrUJo@-wf${;Pb$ zufK+F`IYyF=q%BxS=xrk6AFxp|aOu#Te={fWP!})9(KJ$iK z7oE`~EU>b2SX}({g{(lTtdPS-gILFYgoV#M&7OVWYM2wM@rOF-(bI-kp22#Q_bf4n z|7G_4yOjOM3*R5};AO0#tg=Jdz)qa+I6i!gJ^-F1GkGpk_(qJcm{Wv*WKPA_Tl}7| zzZjcV>M3v09Gm@UKXz1veSHsXzhtRnu-xmxIlBDl9KO$-d~xu|Sog)?YzTjbb-Rgm zfsszq(#Ni4V=)lV8}}P;jdblk{sr4?8(Y>SN$X zxd&%)e!3BQ>mII0QIEL|y2t8Ku5TPLBp>5ppd;<}xsL1=ueXpR;edf|yEhsJbW1Xp zsU_g!WaJno@$muOOncPN2Zx(*JhY6o6eK&rDCNJ&bgUJaoi^t{N}>g8_-IX3%mNJm z)%nyCV~^ihg{xd2G6u3H)?=jFaI}+BWSq~wm1h|}n%H=I{5T#s%SrHwI6g#{7V+=Q zh?Nq8t_3r6;$HpFbramc~D~xk-L-|iHOjl67<;BZ z@Wgo!%&O|Zsy@L&kgAe#j5Dt?|1g?A|*iq1|X zTN1kdWec9``k$ibDER0%qnBJq=UQ++Du+D)7}#g9gCG|Yp3#VRro(0;`GfBX*tm9Y zHu}gmuK4!KaKGp?n}}D%9lHp0!7r5pKDGQ(ICF^eDZC*};`a^Wo*3d&7nlZv!Xu`(x_42Pf4kE`3eX@E-&oFR|6>_WXz*U2=@m1{ z3&NX!|Bv|lc>4P_cSPTJiuV;dU$q?f0E4Q4nEtDy1$;!NZz!(aQB;mYk1(Snse$jO%auczd)5bxg^N>*qXo3TO^a=4VM8HM|+qK7j z#r75LJCqcWgCUJP3^=QaZif-BaGF>Yj{~LZ=s+gY{6sC9az4xbkeOY_=55@ueoDVF zZCTaUt)-oE+jzR%5rb@dvS@&177Gi%Dq zdNATW^j+}wkFE1IjWg$M4wI0#CmBWjzU4B|8M09Op}QDAYG3d+)kk<6>$nI!@wQYI z$AiS%S99K`cfs2Pb7J0>I)k^Ta^4oW9uD6b*X|DR_V*DO@bi4x{3FpQkoykC~){2mBGc(RAyh=lha3Qa_dME(G*B`UD<%WKG_3$MS2R) zToe&3S7qnuPDcoGd_A0%B=3Gi{~N3^#2JrKV<<+(+#f!Uk0k^k#?bl$h$zmMVE8Lz zID{?H7{Wrr9^~R8{=bO0wB=^4Py46wgSUF~6(0@m^7^#9-epx+){h*=ipKFlJob<^ zjPfs`bErr1me3hAjPfIV3>$bKO34<6EdkB%hH|aP&KeO|ChZCn8O}Nynz8y&U|lMe z5|3pRmlBgPU(HDngmvI^{WZB299fkHd;J7x9(%}WF!iGLPrhC@fCTnr$jdE#iF%5i z@p`QCnngX%$io~H^(0f|n6q5OJXGhv*Owuk1^+5y{t)sM@AY#>91Y88E1E*SRr(cw zktqe=4ztAiR%2!x547Z~ou6D7<8xEIC(2S|_lxoYy>ikB6fR;Z5c8Db~Mjf$(b<+T{z~gYZ^> z1t`Z4&c)i|h{O;R2_DuOds~J2A}mW0P+?{dS;Wqq!DC1iPOF z)erQ+W5`>eD+fiND9<6fPm$ws@`LRYb}0feI+#>e?8_)E;&GQ+zE)1y6FNa>Mz_jy zYGZm~tQl)G{-9TMmH#wDLUtc8_xT(O@}1xi7e5hr)u~Y}&C|iba7g?TA;g@rk?4MZC}ARhLU{B0b4x5|)P; z`Ej%h&E!@72Rn#{$rcU5c@^h5;OYo&CADMih*vWrVL+QtZEcr6fMkBw*}W_#6@fJ? z>Zk5;PQ~j&3WcI*J|flu9+fo}D{*^%BDT)wC+!Kta+JdrQJ?Ml9~hGO;^C1G`BjY*wb@keYEIT3PM+0We3vc+dEx z_WUA6!9u*#1#8Y4uxu>bee5B&hkm|&i~&a-+2oXixDI?3a~CC<3Ur?U#aa>GPka}p z6{Htgf>Aqwr)~Is(W2isi2vU(d-e@C%$jBI8eL%=-}IyrT5;&_t5(1E+Uiw*$Cz?F z$k(or*B-gazvE%olkDd8TFVrxemC%5X4QM^QEm0-L)S>;T~tap)Nd(0@1ke(;1;Av zC!Sb2A%=uXigYq%5tbE}y%%*_2A!zE|87nia}^Q=g99}JP!{E-g_VKItW1A;T71q% zm#*EqcB`Q7A_&*SQCO zd{Y$ZA~d4;Lo}j1=6fBqi_|;!TCO8~FW`|wZ?x*YB~kSj zypH^82VE(SWPbM*s~&R6rW2P-!}!|D-m9K~#%mMerX#=kfdn|~-l|sWtE1|X-z;$R zcCzXTH=B3L1@Aa;jLmQUki*jQDtfQ4v);+Cj(X&BgWm8K(s+L8`h(BuAnV@Btj@x$ zuEQQMO;@yLWD_Ped0A3Y!w`2W7D%2Z$>ZVs&aL^Lg8T-l30^;*zEsb1j%)4LJ@giK z=w0n-$RR9ZUnYriqL+F4O5!hLdy$26{6|e+IsY>BIc+p@U`?BE%B!nL3ia)CdaoYc zPpj$Lxhhy4jFm}g!X+d&mYjl2%D|ynh=u6IBKD6scMTHFPAI4j)C}(3Ca(=VcBAWS z2K8*)Ra+=uY)kysq?dYj$BxxSS4`>H@w_V`*om*fUy$G6JMfHyucCP$vft*xGA{c~ z?uzg_*%!pS3FgXC5eG1JPB)9kJvXu^9Pp9)o9M0syPZh=&C(|c>lc}JhtO#e_{FWj zFNuP;GBCPQ;pKpnK!df(q@hyKf@kjTc@v`F=H)z zY}#@xA#Iw)jYUE|uip(j#FRJkl}a%hfPDgEU?A+G49xyBf~P|oL|+{_dPwxuk(t=^ zoY_9JfLs|kRmbekKMz3RYk^trVyG2y2~o7)VX9(BX9=t3sxQFXinh%2@J81<(lWczfGe zJk01|CXSUi&-21(vawIoO-DuJhD*m;Bb3!#juo3@Yi2VmPqk0V2S!zVf1r2ny}O&9Y?93;q;A?mNC=RGAW{NI z4PAN(gpPFSJ=D+zq$x!Nq)6|gNKsL&pa_Cr8>m=lV!^M3oxIPPxx3j={C(g1iV8b;k|WhA zI}C=E4`2L0w$I}VEvq^7&@MK1R}0|$U$ztUD{9^dUP>A?anV=Axs~Ij6Nz!$jaHP6 zi}Ot56!Tx;secE3o2({&VNkST;gNN%@C)Kn=@(DLn){+E3&aZDS|q26`?_INF=*it zQ;-xAX_v)zkeeJrHDVYHVGriv=QzCc@AU=zbHDQG_QA~Q`qf>OqCo9XJ_GsKeNR%o zd!44f*ng@q&^)h61!Ukv<2;99|FJsSf5hz5R(tP1B?p&VUP`j8CXkHCXSnzfK>P^E z%MpVu>;G7W`PhN32*9;9sjL6Xa>^p_8+$K|_OGR>56(07;6x27VWM*v5{ZM|4lWcF z5`oJZgD82O4GbX{)p>`V}L~kKr5&qb`n`kIF4}fy7R(x7#_L^MvVk4RET!ObChD`YFE0$7i zIErGDwc(hOQhG;y3v#~<-+q7`hIEPVX27?502RPt-E`xda0yCtV_kR#B8)-u3*Zw; zc;pqJn29oc!y_OQft*$&@?Cw4e^Z9=xfC%-i(&zUa&V3XJ_X3Ai zMsb}~*-LD!H(VtfVGu@KDZvLOJxL!7`%Y3`0vhU~7z#*$q?Iad?Z5zVlq{pw9MZJs z3HntLT|KC6qsrk8GG~7_QGIn#7t4Lk(r*7^No#oa1@UaedQr1pUl?S?vxOuiJH9)v z2sxU`$?hCYGMOU8hoY^lMH4=oUA2CATI03@)ys?bx3g&XEnNn=I!anD5VRad8TI8) z7d}=&3q{yiRhxr#s;rB#CZ8?dY zr$RP@PDwT@2gGDQUobO2`on9-2lpv_=9FG=cE|T!cxN`5&r;hqZ``B>z<=QV z@T5VaQr9;`4p3{$0iXd=lOcM0k?IUrZeXCI1lj_TL2{h=ykWHR-gLtjZ0 z?WBBa1kM;o2&C_}lv1Q&Xb7SV;5;xI-XY0QtlQ~K&dH|2^<`Dw>~`vUYgTK2!2gM5 z_R5Dk_E~a@A7|?4@7;*!cSC!%Yu>kh>-Sk+(bb5ZYpbrUU%f+I#RerWzrJy9<`d28 zRZn{|q+

!(JiBG2n!cfZ)tj^7EP+a5}+>GJq^(1(K5D4YTlCLGf}|s}n3KJuNla zSV1PsG`v;T|8oU!qq?~iA_Q0c`%;!o>D#1LW)}58tj)In%c>G*W~P}hS>@Ua#M*Lb zZK)}=Ixt#PV*&0V2+%bd>u~$wC=Wv1dC3VPHmRG62pN>MaYROl92^uQk<~Vwap-UA zj`~P-YN`LrZe>@^YEmn{cDIDCRTp>fT+};lclD5eUvh-GeTUfW=yhrBTTN-gDmLu& zFRK=3UC^B1CGdp^y}a@x#!pnfvS}Bpb(1ww;!NE3J zWW!uf9r|qV&bobVzkT{SQ~B|eO9!;y8_%3}?)qxUH`CT_e!q2I-{x%#1GS`8`(J;# zq(Q~F4%HhjvaWxv`zyo7u5wfic`~hfy_UHG55?fme~8}Dxp~>>87jFmS%C(LgN;eT zh{&jhfx)72bx%unBs((T-lU9rBk7s^6E<>CASyxztP`sik?TfuOYzhnUU=^IbEEn% z+cDwd!nc?A9XoTxnAU9yhZPo%*P9g`?c43ZtWjHHL;OBjJL5><-Df&>8G7T{R!6 zRgA0Mxl8RUH=ceuJwLv8yZpj>-MiOI%1G+dyk&1ay5vVa`um?dzdEsA=SB@HS8C9( z3NahG?Xq;0ja5gL2+y>HR|MSSx4s&e*=sG_d5`fxh~c;DAjpiv149^FP4zBPe>) zOXo7_rrFSrQ2+w_?9TZT8Eh(qGTDc$*09u2Pdy6nH&R|FP^a$rw7(TEuHGkO+x{0{ zqy(8CU7xt$uD1A*`SH87kZ_)_mH>u$rFPyE;J;?bV+DF2RI%A;@{Zs?r3hl0Avzf= zhI|GC>kUJCp{12mbfC2*QFv>Z$S*}Fauk^q0AwKpK*D8@z`mVEIML3SfWHWoPbFwU zN$+0h#=BqE^o8}R;OZ@5GN5eu>Uq3Lz}HHB8}QjkZ-hM%`Hcd$axl3)|3d181RJ>l zW|OXScyXvTJ)~+c-fGKA?Y2P8kN0y&n)PpDB@Aqlx(6`$ zE9m_M{-MqWH&IM;aD@hlo$v$Aq~Tp<3i&wvg{oq;TFl@cUN7A(U&R)&8}b!A95K9` zO0R3L;@MR1v0Ywkc#D0^QOx2as~jTIUT%bfde%NDtKqc~RNN4Xw9Gb7N{ovkx1}(W zqWCq{Y$P+ONtQPB0)rHG93}4}hH4&)817xn{3V1{tDtZpzi!kkw6$%vWcNi?F<@Th zvvtPA`K)znjhY#$N!2tI#X>CTujY+dLpC~H?9K~HXMz4$LLf-k;*L~71v^cjt@x_` zs;_?$a1?0q4;ISB$9zYWKI_@i_&&wUJ^1x5 zc}djZqGpZEjEbqrN$yAxPvB@a%QieI?wBzzx`mFHi-1z2N~$!S+rsSz>dXwE8>Le9 zL(lAes?oOoTlPxa)vR2e zKdRN;jKX#BM}C+2(K$4DRUFwOym%E{bhG{aAff<{t_+~+o93QAxTJtp0IV{uh3=oR zF;qoIu&w~qlM{_oy_h96Pc<5-f_vB=U}3;7IEQ-i_@{2*t{>kdF}Ml(2Xb!Jk4yuh zmrTI2k$>M0KWM!4H|Iar8 za-4J--0l6OF2nqc81`_)+j_n$=1h4=mkLLGt=Amf&AxkRj+NKZo^Zo}=PWDzcFlQ~!VyMi&_uS((9sHa`3Ih0yEaI}gLB$)AC+^BY z<>U!u$&^op5Q8k)zV87^qCZJugx(7|@-f~UO)-+-hX~d+ksN_KKO1Ksg^O_ggtV8n zc<>cdZ|F3ICLu*^D7F*hEklqUQC@zmLTJ)1$Pc0c0ZdTRd!Ktr4}zmibYSmb^H$dj ze9ptmKo6v1(KzTKP|yR$1wG7th#rbS55OVtEWT_0rHlOTvxHkg58}I&H}DWWP>i1 zWK;I?akmceRh1d3@)KAF|3S~(734{jM;>{}#-GPclY0UfMZD1SVy~9qHD%)zFC@mz zw+CKcs@tisJkmYJ~EjML>Nw3+!w-_5@`>$21{JP$||p--nj4t42dA+GMv2UxZbtJ z!)S4Qaix3Tfcu>YIdrZH^!u>cR8U6b@2%RV^Wms4SZ%O@^cS+9V2v2gi<0IOTBDAA zqKH5$%hip_awV00CQe-^81rZvlyT22S)L2Nxg-woLIL4fIFX4`RytvG zt307w_pz*U`}C>bWu?xjU2}3pGQ7D4kA8O4D0RjCZ`xkpQ_!S#E7u1?Klt6$7i*v% z+d~jRjBFyqbsCQ{5l9n3vtB<44|1^p%YJ?`)?1WkOM27{kum4z=aw#r_AK9-n@YL_ zP|_8c2+<)Wfjp`;x2f+|f&Xc{&+poW+*s}#7W7scuVtIuZVAw{=jpHN78c;4^KRj_80w>!6W53$)N{f6MXcxJ`v~AN^z=Q z+|dXWWs1S!tqfOkx=SQ`B~*Yn=<4Jf{5O_9tWTd|C>e6w`o|aQE3RQfM~@z=E^~GJ z;txS*c!yZ$L1Uc*@RRNgw*^lKM-((F1tFJ9Lk&FSS!&7vO6&n2@bzWAp+h3&Ls6om zB5bHl7%ue3B&)w@!3<{#iVP<|=4fx@w{HPFaj-XvgIz#?;$V;a;*USR7*}?z`x3++ zSn13OSaIgwGxn<78p>jnOUsWhbH^@&)__;}9FpCSh#?+T?z=b#pBeim#wn(TU_k6_ zsn@umO*wuYwm^Q-0!_4E-1pSbug4=G{kHai;^mbH$j$(*>Z$= z#&Nw{%LizaL~K8Q9`eN>?)^2+)@i^*aTB1?a%TwR;tV}hH$}oP=v#i*YrWpj#CgSf zC5>U6&MVC~@>e{xNBmph+3 zgW*?p<|S7MM(hPv4l@!h-K%s0ZphZiNO24EUVRxFJW#Vi{4jg6FubbWo@MXP!u#5? zB5hS73RyjVke{7wbB2di42RU@eR^D+GVzO^Y#r~@^Wx;m7x6cw4eV)puyf}_O?X?m zF7s}odtbtWNWT7zp8}udVMYvn3jr)u;Q{Cpr(Q67W3>#uo?SHcMbY=ug|@0_J7e$9 zulKQK+as#j3i&BeK{db}7A{~0eCs6CyboI^p{D)jZ6(xfk9$7=H=P#=_cFHlQRC+8 z?72sd|B7sMV_)$c@{!2rELH2tapc8Gy$R#AuWIdwWIJdA-=(u7zq^9^ssndvpmUO| zb|p10DJ&52er2RCYAqH+=j zvATRKw*L6!_!?1>S@DzAx@yASnnQDPhUM;cedT)he2pR5*+Xiar*#P!#JaACeO=0s zB;pw-`9kB6FGSAnanP|@j3aOa_l`q)AJBdEyv#T&wXp-y((+)~icjglQHwqh=+3sqU{eN}#?gAC#=KWIMJfo7|FUdVSvv3YCqM%Xq zKHewr9Gh1m08ZmFG~+5*sJ2Rqv}+VbnQM=Lx5k^Jh&#dfMk(D!`}y$h#9I>Rv1Ut~=PzvvMiW>3l9kR3y;q!>Yk&hdyy=0*^or>_ z)N!numm&QH8cT|ev{QK$@1Q~>ss#{6IkON-fvC4!>fC75O0ih7aCH;Tjt2nO##V5& zn?JTkBLs;xu40Wb8PFy?yb`^jY41h()(e`JUZtskJn-Qa5!|X=5Aaw45pnQ5B?SBV zk~O=9uUjc&nljK($`~soeJm!L;y6hgi%PQkNo}kg%o>b&nj;MVYNjNEw)N#(_|F2n z2E5;IA70Grjb>>R*^~45hIb<5E~s~3bR_`Q2Ec017jX_&)1Ma`$h`pAo_!!5K>I*) z8`Yv79*6$5ylh;^OgaCivb}6voE0$+UAd9hIGt}fzC!uSYrO2e*Oe8zLgUjI(x{pJxBbKED0Qfu>(2WtP08J|*`TV)v>%Yt>*W>_PPm zbTWfePiMCPv(a-YWkHU9^H`yo@0%n7MQtBAg;*unzgT02B5Vu5sF7 zfM`P609g`++cFFVWzn|Q3^{AGkD=6ZFQj>5WA(0lm8;l|IW@XgqlolK3c#r|)&n44 z?GDm((}K{IKnsFT;xu^1N%s-s;Cl|QapDa$jyMy;mLzD(^BlyhxW}ObgO=U2M$dVO z?~O<9t=AmfS7w)=1382Z*HOC%{&qWQ$~Yw=Fbuu~*?313ITHsW* zLmB8`bufgsim0?1Ec=`Ncc)FeyZ;;h5&m90WlHfkrqB3IHtyr;Gd>>6KT;FeARqei?+LK=lph8(L4d7@> zLFo3r3l=OWC`V}(6C+ZB;$!0DViENlZH<;m zLB2l1azjZ$h*#4oDMO}t*!9~TUi#Z@uC_aK2C$CA`h$)2`zv+wYQb?!(3)V;HC#SG z1#vc{S`aEw_a3~($KMBynstkAF{7jb5aUaTAr4{u8L6)?8K%!JIiuZhx%3Mzmutg+ z|10;)Gz#xS5r(`tU_$cADx$wfrnu@^6bn=nlTVaU)!Sh;jpCoU#?h|btD;{J8%Gc+ zLjb!2&x#={6a}D#hlv~qaAT>m5yul7Dc_Q*5kbT#F;7&hK+gv^L0NO?wFI;y5vkjD zyUl{DWsNL{Z3r9e>{m6juah6rXK}xE^QsT2`sdx6Q*&4CRZUmeC}(G9YDXt)`LoNE z+NJ70LtV87r<*ANmG=LL`HVRlaSt)j$^aX7H3CjG=-^Z+fr1X8qro9V)s+O(Q%$Y$ zO`BpvbV!7i)NoTyYO>h(T)-9~x87o-n!t$fW2pO$lcKTr__>`sS=IMg^1H0s&Yk@1 zyZozNZ@tAn#s8Yk_1n)fPMu;I`~BwP@BI9!Q~W&s&Sq)d1HV6h{ClnS{mtSpa$n3Z z1DDZCN?sz2`G67RJqTq|3>0Rnt*q8?81ceGe0*S@hYeBHEjUpGr|>q20!|3)F^y&! zFY)hB@UKqrtLs^M-DT5Q^3-K@ae_Nv;}=%>@HuRv&ni~=8r#NuYZD9yw>dF$dNwysP+8b1bi0nuv9MA?D1@KSnSEo?~S& zTRyW?5p!;fIrH*28FMztIi)j!pO?*1G)Fm(ImpN??N)l%Sp8j^CH5tshkD~tar$1< zAQe6Mr2Z8ieDY9le2Td>#9WD2n(M(C5B0{Yl1g}G7T;_7X1rLg$9t|9e(AaT`{KD0 z&#L!c;JIFS7ISxtxf0(G&h^5#nER2KEAjroTyMP7Tn&~X;6dV_=6diCJb2+>JQs_? zT)7W4*VqT8fQQoAgdQG>DOkU1rKw6!$h$AWJ5s2wX#{x!SPL*X$P5yn$o8hLiqM#P zAYy=ys*D)O4h3sN+K}LA6qQ3P&55i@@H-*t;2uzWuAa_+QuD{X)OY`=QTzI>AFnp& zKTltEkiYZs$NcSs>W(*AaJv8(f2*47mFXXkgMRRes~W583TVrJd-D^_ILPV<7;%0O zv2YFY825X?sIa(TL_Q+S0nsmpVI*7h8On5~ri-IB%oxz&cWWr$7}-^?&v%7?OX} zVYJ44e$u=Zp9RB1j=T&Chf}nt5o9SY3JEQ#f(#;euu=!n6;(9C++e)hX7#mDlp(TA zVJEjz<&?Evf8!o8{5( z+9h86AAU~Icoy`sE`Y_R)X2*UAxNm$859j%dbI(5zNpp601;I_a|kOY6b`Eh1jYaS zEr{xJ*O3(kPk|)-mu1zz+02@;al8flkT2)QKj!D&=Z9g_`5etIC$M&Ffvmaecvt=V zH`N}lP4q{zs;6iSxXa=veU20E^s0c-;@=o486+F~AO;yavT8Qf7qEj?Op7ruK*`8U zgVmLkB}5`2uURCQ0BoXUK_{3KAi%Z&e}p!p_-&H47)lV^%ARrEQY-V7ydE}9094tf zsgo%)Puv$wi}0RsSsR(&1I-ZzGTey=;C@Qvfx8{iXCjnz@yhTpq7`~&h#z4o%kxHC z5(Cf;|b&#vh{X1&&D_2~H0nsV}2j5_# zI-L69iiAm6bDNF z(EZl|1XLQrUS-elh+nWK{we>P6)jcOy~{Z2Ke|?{16`fs`K6ou7yj1ux3+A5!v!N6 zV)%i3bm)LDnQm^lqR<@|cmRDD;>5bC#j1or`*WCaW)O`CeobU6>D8Q+U$Obqm4oVQ zxA`Z$Q;u!SM=!Wqzr9O~AdTHM_d5S)Fdm0}H||C-SKtDQ-;4Q4Q$E$E^nV%?EdEWH zq-DC7^#DvZ1@YSf2>HQAk?~r9rS&4?iX;ZOmLtO*CNKd(MwYZ*47G{$_ig63<}~0V0{SrO z5=Yv@Lb3I*U*JRmV+?i_{OAdQ6j2)mxr>pS#SX1KS-}BMfzGbeUraWuH5qq1tB!>H zll&WglI5{PT%!`{^zv_54c8j}LFbcp)`7tzQtI1$Nr@ay<@hyA4f?)|^hSXb7~ z<m{bPfbZZhdLPBE#b_NYur9GB!=f~Z1i?gb+y zh>FV0p@E`q>QinCc%*xVtk)>{6&(RzODsbD1Yafs)M)?n^~HRMTF9!ugiNiHkM&FU z?%hwpH7&;V8Ozfz0j?tKWg_4TCk`11KXIrC_fl}dz_nOG7fG?Nf<-c*EjY;E7uU*g zMunQF#&KChRxS}7R0eg)`dhPDwfRdsJYSnt=byBARSh2S)joEXHz}U$j8|u%x6AmN zgci_P5oqib;Y%l706a+dk>e6B$Wx5N&h`|$Q@YjADz^%)Qu2#RZrDR%zY4^~NNqvU zbU2_Y6^~93Az6?pkAR)b8vs~jI?!c_E+bkLVCSFATh{*hI{YlF)?$bDHelz~*inMr zHI*2ufL)$VGwNo;s)D<@4euvgpNi_$#{0>%FZzjlK|w8~JRyECNcj*JtLxTsfQVhJ zQA6KwlST8hGnceqQk$RUHT6HZx%pOY-F5z7-jOYzGY$!tT?7|JvVA=Dwyf^iiKwg*RqhTsc9sSfZ-xR0P< zI@~rUD028k*qHLwcbNa4(gh1j_qg5xaQ;&kE}R0=b^SHw;<8o$8LwY*mGG45qlZi+ z9tAkg3-}rne9CDPTmOvt0bBD+6`+fctYI7V z!D{^q^P940(Ug0wPwmiRy%0C!7k+QBdfpAOz?08@z)SH$q6#ZR!DtgU(-7^@mh@h} zlr94u$!3El7;B4(j1VzH*hkV$q{IVw-n;3wpT#Ugok#oV-c#2&?RB}Uz~1j_kQ+Yr zyep#&HZXGBT^2$2P9WPanjYyUvtESy0V>RhMI?!_rBuhqQV1whWIj8@fRak3zAHph zy*bL;fV)js5>OujM-8!7sZNJ9PUC_D!Hmm;qecz4Q9@V0e3RdJ*~+pb56)SA+U~lo z21dWNym+6Te;Bcsg}(X@d*bjx{$BXXI}2t_KXLM(eMhFx+LbABCk6DaQwFhH7E3us7S zLnegz(B%QzN`kNnIh0mGK|!{l@I<6Bg^*^59Qq`jJ_wI&B?~ScVE}UIuk*9N@gLxt zuTwOa*}2+?pZ(9mViu}~yKbnBYFvKdE9UEZf_*rCphol^>#m?04$ z|4zZ_cBW)kcP7Wh;4+AFW!9B+mM#w!f_{kBge}}k#=KC<^r7D=AqHquEo4OyW%i{b zL0J6ETe`i`a`C0n+ZEL=0o7E^0}t4=LH=1q&&FCI2* z(Fj{wa?3-k;~lb^^E>>`b%lC-aVI5~O>6$sqRDHw&Y64# z_zN$+VLk@@C4p+^=I;#zax%e~ap8Uz?N`k3eiotbG#pE~ggt}sNa5fz_Mf^y3S3pC zZ}_Sj2TOlemBoMtWpa>!#j#L<04Oa3nKMiw;~4)5l_*Qs3sYkbKInuc7*P#Dml! z0=I2Te@2{NGBBG#`VqXUxFmrRVyKfS^F`Mq@(D9-5V3!FDix)d(kjtW$?3>Q%t&>L zR9%Z#Yk8S}Y)7jEr^%U1>ALn5$<>MHfP%Ewx4v{{=ABnwx;bmqM{@=)tsLT<)scT3 zakkepiDz~(3qL(>X3p@AlP66!P3|y<&$)4!|FvxHotIYJoZlg*!^S3S7YwSCu`zqZ zoO>VaS=4b^=L2)+y#^Y=I!x4~*9HsXygc8O(BJ?a-b2JLP?k6nJYf8%yI-z!yFx=z zP~(HL$YpVGug~EXDD%zIoV)~ZB}6>Y9PA7p@!%Ah2$Gl(Q^5*R4z`Pnm_<0=%9x8C zp)mL_NDa#orvpH&~i+6qM`V{WJ7y7GBw05fs_pM*Izuy|V-h=i89>_15qXPx6JE9yRzBDbHn@8zpo$_E{N0ML zCe9c$d;5g5)5k7M{%P=((S3(D>@j3Ww_d|1@B-8Ge=;`s#FVLv6H~XWnf2cA!tSnp z>XOlY`i}l!K&Os<2X%Gr>@^X5G9GK8_~sxbDK8-qhCgy*fW<4-M1(T{#yW7Xj11K& zmcZ&AkZ5J+c|FL1v%$b9pnK?6Z^7Sn@e)J2^>C$}Ks#}@qRU0OR zPrkTj%k{~B%w4u@_3CBI=8_z21-V!mJi3zdR9<~iT@rw5&Qxj!fJAo$3~1uw>*liV z_!umLDap8cMn?(zKKi;E%$2(S!1*rffWl89#5(a+_i9L&Gr`i+Y}t>qo}K#a;Avki zV9!0p{|xTav0%V}?rYWz7(RUHpq?SjH|eMFmP`A0UYHO!qr-ru`TX78 zO}*O9^IKLkG_v zHDPYI{sX#qE5DvEIo()3Q>)db1syoL@d&NXYfV%KQl~XhJ(e4KMfW~ch{6RV2?`f( zA^1P-6Vw5fu1=;xTxvy87D;SkO|%|sa8LmHKhr)LH3(9~RaQjil$}0HN~mGS5Vh2? zPZ^hfPGr6zJqHaPK77F1wcQ5{?9r)r2>+`gdv4)Z(}p}db=2%1!?$n9Y@Oe{cD*)7 z8)WCSXjHp8OV3|Apu>!~goT~^FC~++I3qXog0lSxM9c*CLwb+sq`3FPeNf8n2mA}} z{Yao4C=aFPwE`i-#j@1F(DeUeAuOQyl7Mv9)f?Tr_wUzz?sztO-jE@~`*#m#RagvW zq^*FaoeHxzs_r#n+MpgW6M&=OO#WJ4vx@lh2sa%Je; z&~+UK1=WIR5aiz%f@fk|5PL-G3i79zQZ+LTt+V6_3JOqauo|KYBUOj+W|5EICfzOz zuh7-VG-B$s*yn3>q}^Eh_#HdN0wR8i$*UXY49QAp&7NPgqD4l8+@nWq;d8Tw9N6b) z-V+W(ljod~T$kr;h9U3e`70Zr$woYK{w!tpBgV~svyJ??2cI+NG4qSd%_sRM;aS9p z&=}<66|DrkIGJKi>>)TJNRwdRp^*q4f~k>2n2b$IR+4L4pA=qU5f@2!D`?HRx%dM? z1#6EDH82Dh6LFGit!C}NEy>Y8@77y<_?Wd58xHKTVA~}+3$UF-E>RzuFr`Jg{ynlx4{60vZUG(vnnl%o zD}Zc-zN^xG9QtnAhweT;2rpt}Nqc-BpY!}YwM^)`A@fx4Uo-7;p zTGt{r&lnFy-m80EslL}Nv}&=sfB9Uj@?Sm|tNoYH#j5}1bFun=`CMS3>~qh0-S7)+ z{LAM8D`lU1@Z$cyz)socLhmFzn+1M|4-|328=X5EcYjY%i}5|sHsxhWdNJQp5b5Lj zo_pN*p8OQgA^+UZ`c~7ghJTKSAE+<65#yqNx}5LspDtk)bS>x4AZ9`M z7tbMjm*X?ZZHDK3SZ>_nH>-4#7=Ph`@!6&D-x%|kd7f|ao8vWqjMsRvF@GC9N6@K! z@7!(jy&qwGrq}qqk0hK8#CwUpcCQ$peh#Ffebc{2k^RFmy47(rOrUD2}vBbn(by zaP(U&vIvl!MMUHh$v_ODVxr87jAyU-*?M=6Zk1tA5Sy`!^<#1YKvwVDFDjUKQbvGd>>Cyt# z9DF(EY`MYaen8!qS@!_@0+cIx(Qzrv3*O^26FQYd*R>ZO)(k`l1!g{1nN} zLk*qh4$XO?iN8tk)6q<|LFgSxPD|t*+l&@Sp%KI zad0H*cB)!b<4lsd5i!ju)&*A%c}>gCCOip%7DdtA24=nMjureO|8A%L*)iFO)c!QO zxvHJ-&(S9S@Pq5)8r5{|qUh-gy_Mu8^&p_$3GjbeaYu$eOWG^2l?#ixq0;7vW>2_k z+QKPoK0MwQkMD$~CR^maSQxq~Qj0eHp>6`xe}8r3AI0N8@zkInKX&xAsmR7VxtIAZ zU&!yhw%0Y+-AG{Nveyr;UJbK?IPV0XIFEZVK$7kAM~=^AFzVu5pOfnW{bN4-=7UR{ z-|qpxIbtU7_b~kC(5>`-ShL7M6!%4sZe{4U!W8F4Fi1koPDw4NTS2*^HS1-CTC*gL zG;Ew-cl%$nXaBVwRg@C=FJVJFjh{Sue8cTu@+&VisW<1pJ9jaC>3h4fJN0{W^~xQ4 zx9yYnieF7g0D#mu|erI4KZxUZ79K|HL_f%! z1x;MK<;_kVP2k+!rmo}bhfV@q=(9B*y`v(YV{GTn(nUYiIKAlk>+`j_M^-F5etg-A zBXqt{-wNsS1+v~#Fk+t27X+>ra;J+UI`L}W)F3OGRq1Vs%N+D=PzkD z`39=Alvb^G$fg(7MmKJ_E>PvIAn+T(-;vKR^3vc-bpKBL&&U_Q_M$--B7glc^$bYP z7){pTWGI?=?P?ZGPnZS<2N%j?Y%GeUEtloX5;B_MT62!+-~dkh14^ zjn89(-$U+|uXC`7O)r}->bYP&I3ML|ONhKZG5$avzXzXw^UL8AdX0hS@_G4?CkC7g z73jy{8|dkPyX0tO5u}oR-_IA-gJMI3JFd*0t%7JX!8nBaufWto2@cT}Y++V2QZg9A z^W_xX*$vhvYtQOL1Z=Dj+(J!Ar4HtjZj16w}j zKIG-q5u(AzPbE(?QFd-ie_u3$l7*UcNN8l4TE)gjM8qb=CdJ1^#6-k|QkYvrNPtf) zd_IN|9`}{%hN}XZLRMh}WWo&?;ckq>?2;w$Uzi<7kB{{3b;q9Ni`~6(_-Iq2t0OhN zb9Gc-rN(zaH|cJ`cM9sD*%icm!Bq#oAU!9-8b>!QOHX*rvn;KwVF(Ef3lo_TCYTuj z9b^N+Sc7yqSRJem^#sD~F0s^kOIYgCxy;Eg@t^sZ;VhX|P_tbh9ayc;D;c-?0R5d` z<6rS-1q^LVe=~OlPpC+is8sTm!D@qxsiqcrLDbvq5nE`gT_GZz%4_)gC>2@7GV>rr zt;4L^Lb9qO7ft-gR-JH_83F_~6x6^;AB@W%S(8;8^!$MhEOg!BmHk=O+>tHDeK2L| z3vqEThK&7b+k!uiR-eMZev5z0bmS1-XO7b>c|x@#e=gd7ZS1<)bJmJ8BH$LfCn;yR z6RL=Z!I_ogq)W>28S3Ikj?Yx5K5~2(MMOX1IkVaPM~=^V%=}{S`9hbJ@XTeuls(65 ze4ZLmHtw~qMQT?$j$DJTLT1u)U>jGPh;@6`_n6N;>wL`Tp7lQFbI-aT^SNjJkNMn# z2m0Kz-ZJ<-_;}3c9=wR>lkQ!9{pIjOd4+P{C4OihAM?HP^g?$(u|MWpti2b$-Qym3 z<>%m)1-!BTi;$%;N_t+U0AJB1MTCqZZ@^reD4t_{lQ4KOVp&OhfNVUj5MIw)~obCVF^>-INvGDHk zAy2UD?7)Y`dkTUqF_U-n9d~lX{6E)^o;hvQ*!i;~=QE#Uj!n$^$>czv>NR#P4EArn zb4}BtHdC)YzoBHwFB_LXzj52rg``Pgr-lyo%H{**nYQdHmQhx`O)oJVNTd;;)@Tmtk{LGTqRrl<~UV&(xN@H4R`r4)#$Pke=P2}F!M{zth4 zS%h?Vm^%I{Qwq}9LOu=|C6%&R&(Zq`TS-6pQ`*qRsN;=lv;r|p`LH-sOy^R z7<-L3r9XH+ct;xIo8tjfs_4~=I9^kK0c-QpJKA@+Yh);`^72zHq7iyUPBszAm%%cOpd)uA--GTC2i5!#^y{wGu7)i7U>IYmtV_ct9ecFv z(xqva{Cf2|sQd>u;&joJV}qvmo;_#Gr@;jq`sCDaTBB~`{S9l^XjC_+&x@U(UedjA zqQ5Elx&DPK$@MR3k!s!{&NePDno_EaqDYCNiUXqE!mME-6jUO@+z7eIg3u@P^S-<$ zXX!rdG*pIVu3^Y`9;rSj@kepcPYAonEetrN9*cOAMjB+D@y?BS=VNj(Kz{#24n`46 z?|^m^g?uD?p0D9oN1^;rO?Jk0(e)A1Jv&Q1>l1ww-V-5ftx(iTP@t+e0|?a8V*shN zi6R$E;GH(gM_&~hrfvTgN}d){g$Ak->`1bk(T3LzsVQl;Z(2OA7&dj$;0A-pk74rA;^}* z2vNT3CVW}hPNdO@BpN~U=rWuoQmeEikt0F?u5tdty72c=QsR|Q>#ylR@V)n*8#5n% zC~*VUVCn=If+$wLd>#y-Fe}J8kjT+Ang0Nvv^;i{7DD09o@^M(&}}LA;#szgujN-q z^Ut*@SG>1Fn*yZcojSl#LcH@o!0{lzyz@Vhxb*1!4+IQ{C+9qsYzor`^3VCzpul$z z+^+x9LRBl-sEy!9`DZ2K{Dy=6!URA3OW?hc3Iiqf1LOK%Vn5_~V+{X)9*yL`V#j%eS(-b!adIvNze1e?_z%`ok#F@(`t+dD#$Uyh&x!@=*d7N z=f-NF5(tXJKZI4m=RH|sY$tnJ&F5FJ(w-zeco(+y%Ke$_41(v8y-e>xJqf@AmRLWp zE~p!_9unW}Q5Gc?aO~dv{0krJAr_r zOfMr-t!3yXO|Miy~jqC(~NsyLQAiEpws&vm`eA+WK*m7_=t#jXS~yq z5D^y<=e`Fb>E!YEK;i(YbQ7fOZG<{|8(+MbZ(|wqCqK_JI*zYbZ#-9>%ew%13v6pG6jaLacilH705n&;LR1b<$FtDXs3ra(h zs)5`}vLK1AgsTCLbZlb`i;+nzh^8a!A)s|SHBvUI&J60qfsd){S~dy_dor?4ljO`9 zAEGdL6O`AfdGa)?!B3s5UFjpcsuFduu5yem20gmo9|EyA&AjrpO(fBbRrgiVTS z+Zeez&tUBgD>iaX+XSb{Y`}?ZY{>%%9#xEs9G!Xmyv)(z=M7sUU^W-xyJa~kiT^`R z3Rp6X?(z7Oeh*s3{Ut=s+6Yu6G-QMYl|=xLuY|`$_dD5#t3Ss5V3~a&=R=%n)(dAE z+NQt1f0%!0qBU9Oe301^sxBR0ciStr^M|kh`R8jFim?9BwpXvV8vA_Ls}~`!5ApxB zs^6$BUWfOQJcz;jD8~dgAedVp$bk`?A0k+RPu(`p)&Lp(_{|C0weBmQt13r_1#3u=#`d=aV ztI1!zAn;j)U&1jSszfOZ^Y_}}9E!zRLz;#=PX-(9ohO6nSBk(-RD4X#hf0bdwZO=z zd2nW45*V_NN%KMK^_@Q%W?KDuXStmMB<~=ld3Ot^f;oH@GyiViI^mCmIq>z zpqXPWA^=WAf=5PBHUw_$BKXZB-2~ua4nxaasVF?ePhc?}{y+*h^B;3cCE4WHk?W7S>nxdj28Z}dZ14>-e>1ZAz<2M54M z><+@)EEYJ7g#P6VUCcJF+2>>cQG&RvGvT%f&S+;7VMj#6(MV@Wpm?&b-HxgNeZ^VkXeaC-@ ze_g#G+!7O@obV>+{&p|hb)GlANaj#s3RSUkMW=ff@f_ssKPK&NJ4iNqhONrRI@9>{(WLLvbOD0JV=QP~jX<3p2RDnxm4g6U^V zb-)xwTpu#98H@?kCWA`&i1dCba=`foS4*V~NQV1KZVmMA@+fZbWr_Ej4o(;_j;TlH zj*;4w_VbuMENFGBZT#oAGpF^QHib8n$`x-k%`_ZbTChYcwv8u6Fn z43&$&6g|AX&Ja#DazaCb;LSn+sXRmO;C8oj%_96-z!-H&lkP0TyLLBhe9ys?t*kG9 zF=X_|a=Yu%q~6ZPOd^wrCL|z+!=mZPB!X&H2o~TJ+Bg>Bl}Yr_6k*ttGmNl*W46d7s$R8X zsv{1a24NaU>}(oK6PJ3}>&dNXGu(GbcObVk*avNmCx?g{CZN&>-7m#N^*Voz?_SKe zk6&=~Q(ddmbi}(wGu|2AtBuW8wO>Z}Mmt*WDqiz?!`3b8*K5%vg4JX`9=;V;WZ%!I;uqlhTUv${3<*@3NX7^}U*uP`P8DekgZZr<`6-*}%C6Dy>bb2$V)TzFakyCwwu2<09)ZyR3FM)LJ%}u4ra<%LeZ~695>Jvd2Xn4mB?4BNHcwq zuk?RSML%h#BqmUGv#?OAm1m(^dC-mh1V2|0)R2<}@08$Y2m*kI)u2Qs^L@1AxA`~W zCr@8)+be-ZUS4`@kxMfz9@%h}Mx~2~XIuG~&@3;j)&II) z?LJBuX-bFET>WSB8sINO$yQqAHM8O!nK6i7s*(|l(yh7^6ii(-b-Y|h;3RA!Oqq)K zP_$Vy_W{9o$H5RW$k@kJB{e$C8Y|n$QOPjMJGEO0ofK&SD@2@1DT64xLw+CKVv{~U zrzXqps6&3|SIh|YozbuRn-`~jyL9}@uP3SevSm=0CR08b%kTWvYvjd7$yM~?W8Jvq5m&j7x_8as5?l#{mu53!?xeVR9F9RqWDhk)*R zOx0GUqagD)o&ln>~X&y7}vRL*ByZ?|9N@iy_JDG zUJZI@Lw2*CL9X7xy<22$elPe{woY9gwSRiie&X$MfNwP5i=YfOfB}$D69mOT;CLGd z(x&Plh;B!#EK$V}B`Qs1O@>*@CYlC7w_9jdEZJ?R@7ptIhX) z%fDci_!nqXa*EaCr%L!iQ0ePxV^_w$;rpms2!5#N@npb+>!*I&^fUZ`6Ap)3A!F!t zl2%wzA)}?wvnFAa^--BfgeBdgJ6s4bEcfzbzP_D&g`R<_%!ir)(((S6xn1%?@z#op zGc?&s{hGrZ{%G=*l~WCcMV!dFaHbN2BvAooXt!f|=nQCaR2PYb=A?qByXXOHpZD>d zd~Nx0<{QU>lB{9)<0~sAav`g%r{V9zr23hNbK9%+AtCx;uc1ej3%SdX{Mz8h7{ply( zGx`3iTiP|zrhU=4a^}N zSV1g5(}*(^5lcd4C-C&Lo?x*`Y*uI#6`W}2yVnvH9EzM1PU?dmUA`CHqNufHK_Xis%w|vRCv7yp#TxN9__+)CM{Th8pIM9*|HJDu-{L8g zr}0~AeDA;CefRI)f2+r)UYh&d`B8t5?N>NQ;I$U=Q2mgrl&*BhYnQ_Od{dc^A1Z*U zA&6y*hAC?OIOkY_G`E*fBh z_gbxq*3iThtDhNF9xX}Wwiae{FeeFQM=ptD{NIukVb}9(tcf~)(4QUW`*|SyZ?6e< zuH>+{D~#;Hf2*yX$^9ZTST8)Y=s=Rm^;MwSet(;WXL9rIebl4?5W(tX3Ix0sSZz=N z3Ce}3C+@E%5(JQwqAD01w?ZcP__zy>8U{%pLD`bU0=67eAkRjzqgwi@l6rdId-qpr z&)j3f?%l(EySVf>)JdS+*>Ru)i#EZOiJ!UxH;ZYyz*iD1c2$&Kc|Ae{keeL@@f*m% zGy)Z0zd+vsN^r1H?>n~imklq&LeT97wScY6&##kTtF*M(SVc*zl2#?7awT-Dq$rj| z2Sgnbo`^uiZ6KVOsbCeLZ8$%5JCp?o4-0;nb=(ga^h~G2CJGqg>XejZ`*t4wVRwIK zdd1aq7@PA#CH~K^N7+Hfc#Ai?4vOLf*y^e~kE!o28^4T=*mq)CYjauhu zM?%ba{@$ACyw|75ew3g zMfXMFeU_E$aM-hQ?f8Ht*|SpccT4H>iHE*>g}=A+(r*6VE8iYUe170?7B!4@8OfqX zu&zT{g%Pf=-g5Ag`#T+{5`UeVoXcE8s|MX4k{MW4ud<OjQ-%S;P~C$fB1Jr z^bh~;(4hkdXs^ojkE+Uw!;m_V<%a%IU4hP~1mJdnLct>H9=CHp#sWwaF~oECmj0L% z*ei$y26hT02pmz+Da$fOi(L`;4GoWWXEES1L>%11o z*2FC;BuLeiz+it=F;}#K0cf!5Yf*8j7L^Y>!pdVdcQT{qGt4@PF^JxZio_G_v=WhH+_rTg6n_%Dvo1RR3sfjXQ~5b5F#_9GOf16(3Frsv_xbM8EsBt z%xrc*4?+|=;<_1JM^v6i8aQz%p|sPr-}HnlJ2v*2ZaqfoEZ4t;yZ$a^@lnNkvFmi> z7V#?oFyPj&*Zzr%Tv;+feWOlC_FHVz#Jt9hJDhv##Ma7f6VIsGmGk0{e)z_k%B>uq zd{Q$%2W;2`I#EnFK{L_df$89XHI?3ZJ*zTbzg!$9wS_G-Jka0dYYp~6@kU=|U`P;T zQW!4Ff&&IX=6Kj%Mh2plvoo?XvMQkfh$A631`ibqV>wcakj%ygA|gIcT->c+iQgCw zj}yYk1Vtr>x_vOv7OqP`HMWuOO6RLF<7mlST$0A`e8s;`!j8TyZH{&A6 za5K!Z@XJGdsir=lK#-wvF|Oz&2^?-iAgPakxnkO7H)51TL3tbZP11y$r9=JkE&lb! z?JVW!_!Yms7{)({p59BX|2!|*K7Q5fhgkTGX-PuK4~r#C7zSZYx98?sBJ8=0ffiC>2con_{fDOq z7KiZ<{T=+?xUDGmPIZNj#l~j$s@bMVlU^MbZ>1_kG11lg+Q9#Xd*3`zJwXSVLBqfP~P)Xn;V;P@-N$^D^KgSFKe z_utW41ePjSM(!aVMf9;8^bx0|DCj6b)R92c5szDu9{V75K(m3_1m&V0Bo2H(4)JKH zv;H{JAfzC!&P^NY*GKucuWV(GBjaEAb6q(9F!Z^B1D^|HIU!5$ZX3Vyz(J72>#XHZ zKeJY^2ON1VVCMI0pP3zeKO=b7;2GCm2qK#J+{Q0`P4(}oKGX#8*-T}+EMF29OU9o{ za51C?_`?GLdk-w6G-`Ta6gfk(-U%sfUBGOG+knhLMsX8l3rFY0dJNN^2~e(uNfn=W z$@5K)NKH)>C77AKvRZ7?szUu3shkqkDHG-vqpARG=jhA;_Gk(&@Xt-``z&iYGLltx z9_FR1-r}F^-NUNCy^3i^Qu!sv!HFBsP3VWKRpi`GmD_9WZkvPWcbOYGs$1&Xi^C7G z4tMUbPDh@-yf$^x^xLH;zpt#eTGPIR4S0cWXrf#rJH-Uq-B(0JaX~jkV2TXIk!ca) zwu?q4=wD>f`GJOI1(i6Oh9KeH=^) zMD{kcR>TJ?0r+STE{U2n!6^Rz!a~urWr&}Oi%X$d57NMuS}O3(dVUFJ7E3ovt7c7; zlbO<^Tj!3gTQ+^V+0%_0)UK7Bo19y{YFfqk*a*afAc6qupH*h!3qyk)1_%m#qP_rR zlM#uF;#zMuGhx^kelSmt5JIK0s)r(Gl*|(rYq-hFMFcfM>@oRC*oKuy53j9Tqwe$u z*_~c|ip5s1=3?FUFXw;noqec&wKb;5@(D)wzO6Z_%ZeAeo!ygO&1@MnNn{)S)4D>< zgxvaL>eLM1vUtI+V0DRqeE4O1a^Sh0+6lh*a{5(%@KCS%jk@z^A5KfsBIa zcjL@B$f7<6hA|Y_>V(_9iqJobpzqldNkHP-6P=ghJqJ!Xx*LdzP-V;JNlO`$+sIHB z8kQ8EM3ypUF&qdGukKo(Ia-oPdxQ6YY=OoZvghg_w@VvXt8jf!e!j3_r!I_tjcn33 zy_z*1$S<%I|Fl(u>h?+PXj0ybjBfwNT30>w?cPuK>+Wi{fnU|CSPMJ$=<8~x7Zlg& z93OKQC;?wwj?2}@!e$*!ou-LNIFU%iU^K*~ANM^I7$F)ykw*b{YLiLph1DDPp2`o- zG@CJprsLTU%!Ww}MfReDDj-YNniQ5mCb2NY^4hULvI|%djEH|hP56Ouhvlm4qZ5o@ zX0=-Jmi$Y$mpR$N#`T%=#D{vp={esHMJ@3#S!{cUJh4n-! z33;)$P#@&ui8Kh@y0IwH#0WkDQNG;afUO%v<8dhLP~1{O#kq)pC)l)#f5q6yp8Rs* zv%oPcy1JY>S6rR8WBb>ct_^Bom2bE2*m{B`9gTOn5{~k(k7K#QUhu1LB=}G&P)GKH z0s7DQ$&|%_X+Fl&DW)qWF8cqW?K=RXy0Wm}eecZ-y;l(_Ls3ys5D-BfI!IRpv7mrm zEFjph*H~i1lEhe|Xrd`=vKozvX-18SiHRwu_oA+e(NrTm{_os312Zxv+5g{vvj{V{ zpWDtoI@Kr92OAboq{BB)cqkUXm!`y;h>}a*< zUHM+rt3r74C<9+lGJ8Pc$I!0!#xIN^2*yIv^@E)uF+Z3%@R@hT^xH0brQ(t=P9E&s z+28-*vtKA*7!t*QvHg;yj9}xU4lRBA*7fUl#aGw-hYd)2Y@H~sdwhWM?9a=d=nZ@1 z>kxc2(%6L6eIcr|PiZ}?^f%hl^yeB74df*max>0B&|U}u7ZxRqG7RtDO|-Lj0xmtq ziWykpfV)<+l57s_?U+5}e726FPHU%|grS21WkdmPaIY1LI^h)uempcp9~{&vuu~wS z&-n_zJxMO&q$So23kIX@ty+XbU%~aWdKeRP~YdVwqq}XC*vr75N3kWnBiz6(%5Psud=hX z$1BJIHv&jN@eOQkh0!n$HHO#fNhQP;ynuG)-{r@f1+U!5?p+BCiC7a?SNxx-1JR3# zI)G~RRMnFzfplb4>M0qqV?jUlP}k!@|26ZUy?f5tbDTg|zMQkWirK7cST$4m=|<(! znNxmODRklmj|MDtl(nBm1hbEBxP3+&q0mc+Cvj7dR61_u`}mS-E^tG=FE~Id(W-=%pNAObly;Z5HAGwZ3A)4 z=E4jjq&u*;M;tw8 zdnXjI!{%_aq1Y9%c){{_t!q56UOmT&)7hdECzOx14zNDAy&-+j-19d;;M@KtE^Aq> z+PIH`egzQ=@D9&5WOzfj2jv?02U4d{lZ)}Fl$cf`M**YUmlKjSYn+gsJJIXf=q3=% zf^9mI5%`XwklO@FD%Xts@U*MD|N2^)b(hzSp0Tm9HnkyG`7u*k*)luKrt8iztKONn z_LfJ@nMI{jx6GQoJ+4PD$*Eac6_>H_(+%4$ub}&faGj2!-yx(k_JuLUo&DCK-#Teh z8y+|aXR!jhboSvgCS%t_SO}pA!LHVP1@Nwuue)XEH{AczT8VYjpz|9x&rF$*&i7s* zcWRj(j^056m%X)(M$P=5Kk8tZl<~8p%ze zgbE|og94cl9vav)s3+XAfzb#Aj{p{6>b~*G!r!yFRz)MD#mV004y76gKUVwB!h1%2e3P!XF zpHxhr|KYmrS6AG8pmxRs*>khA=Vj5HVDFCP=Mwydz+B-}!iwb{jvs7yOt^y>o!CQ}{th6Bc zBaXDZG_l0YVMX@rLDY%q-6OtdJZKaV6ah!8HtHCCe`8g90F#M}dWXnu#KFVf-RxB$ zKJc)jG!}0jF?-9(tJ}8zXVtd4vQ4F1l$M8U@7*+Q`o?uLM=xlosA!n)G4=VmqjpYm zw)H(eZ|2d76OYcEcih+3dD6~NbDy93)!d4zMT@G&%o881Ei0QoZFm_B!|4rw73<&% z)II~E%S!Ino>|)N%TXBKre+DfM<>q7Av(i)RaMq?=( zPp7tHmB4uj_L@&BfgE-`oAj}K`*^ZA&I!rl)`$MwtYLk0nK zJ??(v2CWfsJ^iHCaoj1!|+Sj%T@H}iV&MdeHN>Pc{5`;<}q{xP0^ z_k!+ZR|*UeJH!>|tqaOHbA&;(ZhUXv3HLZ} z%dd^2DiJcIkFp>rxBKe1>eu|Vqk7Gn>M85idCd88SN+w^Oldji;5hxlhWox*^iyL^ z?WRpNwT+l>>`k0!goWSMN3uGBoK-|;aj}pSEtwv1L1ZbrOCOohjt+e^+lWS6JKBX} z4fp38!%k9BLVKUlqXZS|D3Yc=2TPHs||7;mMMqA(Ko;05&29@@;m=1X0j z|6*qay1GE2gr4qwdErKCNb; z8+}G>HThNkIk}lWry!kTzi2fnpVH?Vq#x#=Q$6VO2zAB|6S94_BAJJHxy^9o!t`r|x3 zFObp~g3ga~y5{rGeU*Bk-+jq+n%7$!Z#%1YhPRznJ4583*!lx|8L`T>n$KRK^8B+L zA%xLql=`go1$f6Hwjet$en+J!kMJ;iS^icCr&QsDnoHUvxWb0<@Cjt1+|r)5HmDDm zP-nQ>2cG|3)aphykGwDK)l>ZsD_6u9wLQ_NoeF)fz~{OA^R6zm?qOmlzJSl6LfO-h zPZRA`CxlLPe1dNWlLG4Fe1&B;i9^d}2&4nCs^ByQG+^^gWw-={3d&ssnRI}wS5O#_ z2@H39=%FC@fUN-p0CbCUOI>23b;P)US&0!}So?O}kV#%%lZMp2y>?!4@aT~vM+Xl9-9o#1NF;5ey z3T|k19DdYQ_@KhXoWe|K#$i+QCt*2B)`MsO5Eo*hnQ~zaWvEgEZVcHm5+{5L5klO& zTm$%$bB_gMMT3YZV@7&7#?twSL3qcI^oNF3K?4{uf(EeW?Yfcm;;d11Z!1^68ejb( zy6)@cGh{;iM^nasjj{b}`Z%WCWaDOFm)nnt}b_``6KNG?OI6-AL~2QP!9B?v%}CbCd9$yjpq@=|34id&;ZfPpZ}2;Gee&gXL{zasUGR`M%A4`|SN{1vf!be$&%g2d8iYpqu) zxz3>fkDo81QsUu7run{4Fr{7Zkk-T&VEmLA|`?*8fYT*;m?+>K?(jje!@Tj~|(+z3An$jdw zd-n-vF+NA6{f54*SNpkM?Pmk)1{xni+V3dGX(k>v(ySf`$w#I0Nc#h6jVe7G)p9$8 zZ!vd2fc6gG&>aZ>1>7FrKo`_g=tmw5WOwW8r9&9g&@SGRECxYaM_M||@9>r-TtCXJ zZ-1@vS2zz@03DDl3l-|$YG{JCHyv_uUzSoekMVH_mnCqb#EdeQn4j$EuA$7;+bGA1m4HJWv4tv`sQ7nC3;0mkWvD zM@4azn2(pBU~elsYn+i0w&4&2y2D^b;_$qxVaJRgp zlUrV%n*+v|_8i)hDHeQ~hWKHfrcpei_CeVsI>@tlAMk3zO^;5nDr%cwbEB! zNmumWrjd_pJE!Y*c^)4xzSpia`@WIB$DCKdMb2uCuDvSn8QOOr$^mv3U zY#S=TvQdU?pRuO=4EhcksYY>pdwva+;2zeg!_z=F*FvVnIM~;FBrVKk%0Ul00f_tENpx&*kn=PcGELMuq!SBqt>CGn@(A1Wb zd@%7tNoSLvH8VTAPNRGyExWXI!zc5XjZew+o0UCwY&L$_bM|8PD;ha+c3$zQ@=+U} zE3Z7dV8yWk-7-p2JeA&6+1XX}W16>c%o~lR{wO$c?zBMD2bUtu8{XF#4|1A}@@X6# zgPsp=1esxmbj*q6&ZKc|10Su$1bW_O?4IuWc&+K=vzS5zrnj8JHxfURZFCrWR(3sb z^)U8j8$LE4`?zu9Ui+3~?PFhm(tPaf0>)ig$;ZxwgW$tn2H)i(_!!`@i36e(>yl19 zLt`cPNLIe{Wl+ z{I0zH>_v8p>Jd^={|H_`@Lcm`J?`@Ma}6c0`OF!$Zn5Aqv4B^PTGrvcL30<5cT+%@|LwcUJ1E@vZc^VDZSN-F z6Oo6b#k)xwG5zR@%(7`dKGTO~t~fe<>9COT6&2${hAmaD_!sY8-u`r2zPH%F?d{}? z2Z-tI1X@XbFqW|YKW`^Ew7Gfz#oI}J0Gi%TPU83_Wg+7#D#nGBEt&T8^32KxaY1F~ zax7%y>&eI4^m?N4wLhO|d{}glc`3!ZQ<}3ve<6#dsLY$2p4rK8veEW~%Tyv0Y-F%{ z^rgn~OCzt>1HwYVPAl6@g3$;U^OoenW(Yc;N+^^>aCBq_Ln~Rw7+>#Tgz7A_$5{t8@)^Wuu>*NMAYa(+m!dePnpz4{(Ib&7@VRTjX^b)Rx?OsBU(28uhF ze&hVDvlbpO@@1Jg+v&Z#v%`Bg74O{K}GkTxD^1w8Gc4r%M~zEYtpO&!w8TcdQRw0q&(x*u!%WA$zHF}?moI4cU8PT+0*pm~Ab#R=Zy4p1ZE zltk2XvR842ojQDQ$W&cZmIuo>qc;e-FrZXN!(y^ghkd%F$CVqyf5?9!2F!<^|G+Ia zNPMcl@e?m%YK#RuUbMJXr%zL~hBa=n~HHYgDBq&bcl zl)95Flr5pKwCfoW5)&HZ?n)0SZmNLAsY9eYQWnLB$9r?3x_7)cfC=HhrSsO|Aq6d& zx$ekIvY+&P{)#oLd&eimZeG)vdu;5u|JAy>SLZjp zT90YNebKo!P!hC0xHY{EFl)mFzXIRS!Vf)exRnD7!ptdwKx6$v>vPLS`v;Z#Q3(|7 zbWb4{Vlz`YftBJHe=q^f-Ml=kBt$#q8{JdCO|#uhG=5LH%)aFBES(T+z}o@!u`1KG zFO`V-vMj@$43VWtoK3-<$<*RKm}vl^5kI?H25GOh0cypr9R2K0jpXOuO&)lR?X)|8Cm_t6M zGGZnx=tUqDF#$)dGjo>cs5L4%japqT`*zr-($Y=C$~KjhY+`N*ugL!@8@9Ow^V?pp zpFju$V5*H<1hZe(wo?G!fN=GKx2KDrtDoAIR@<>HbJej$yJg8EMQWK1P9|dp@0?PlnNtU38tTfON5t+Box>J#=zFWRz+L0VK#IigsK9AAlGpC zx`}CLu3bCBe!qF-k#A4G@=fy-dqwA#8)%~mZR8o-fVDC>S`rIO#4-w;Rpw3LZP(re zjwMqQ*g5M2$ulg|GGKE5jns%V zlDb-^p`49cj@G7S+J1IW3YEK|+;OCFd10H}uRZM^!i3kP@$5f;*EU30R{~g27gI6JGs;O6`#nr^9(~bi&KoiI(I<(= zsn)#4zkiLr&v_U6{zsnwb^iV9>@@#=j#4kZBz!55Zs?ucut(Rt&hCSr%2GFER9K&e5RB&%ACEitn^&!1V5ILtPhX~&g4m_=$5{^=3d!1# zUm`oKF#OOsE>gcxPrcO0PV##GYEFWr`dH@PAT^2uTVCShK{@FfukT%6-@9Uz>3gkT z+xOub{yo|QfT1bfW>AN8iksAC7n`r zpr2wnavkU?bzM@O|7CvANc1%7OhF@FzuRBvOb?3Q5RgpA`9i(zuI>x5dwctmAI3CO zO_w6obSbhe{l97tb5tg5l)A|Vh|c>zO?JkR7Umod#=8*yw<@P6l##O16^qs+gF*^q zL}dm-{e%R=jX20q#=w5DtIBk?31B3%*qV*(1NMQ^Rq2XcWZSk;>hwQo2mWJdCkG(U zv)BN(Nttfm4CV*pkrlKP2CNg>CzsiKd@Z1T`8xmp3jh8JeUE+}fZp#R=>2rK|8*kW z|FJOF_GGRHq}wey;!$?#cc9LFu6*YRYvV6b1ZCbpnOBWvfbI|-!BB*X$*(qR#HU*Z zNw?W0B?<3DUnf|C1S$QfoQNoL3Gxx>5DB9IJTYMwf#5nGR~xJ~5qLD!U*PJ)<$JNr zQ-l8q_vIP%W}9*Q{a^-51{l5Pwmz$5=peE4w)6j1ol3oPwpcA4DJqW)O zKzra(+MD27i~^{n1Y+#9&?OjEC*)d0&779LZT6GC{jRy0eSVwll`+=Sf~R~4dQx}c z8x<`It~Icho`LGMSdJ0_<^Vbeur0y_6A+E++!%Q zRdk&d4O2=*yP_*aH%)=&a8`XKjzYqb1%Mhd?+YvM`3=Ub3U|nDW>OHbi;+1Om|) zKchU(hNRQSXYg^zbFif!`keB(LPt4TKM8&JQ_y#lUd~V0oO8GnO$l}vju?!SY*eKR zh+`q%C#4k3Sjm_k;;(4r>mo?VfW-o3KVoCE)5nfY z&mN2Mn$Chnpq;ZYKId>38U+pmLg)u?4gXw1z|mD`qKg988+oE-p*)3zY&;F`+8ylFYW*@L#@Gi;H<7Ai{>WeHA|tyh`QDqL-C zZD}&?`JJ#axCk2qU&u+Ws6PCW=mIu@0FxHxfWAUI1_2-N*T_c)jx1U(wY05tv=?o4 zwu4Pj8gTHz&e2GV9T{R^+1cAJ=Jmk;8ubWw)?#m}1+P=oVHgB@acxgqHNgGQX>D}v z)q$pR$J$^eYG+v)Cb_6w^BjKoDUR370&GLW12wf}My=D*O^hj0=zP;u1%0 z>gz4tHD%}H>ju?lN2LZQ3}9E-Q|r^_6!wbK_cgF9lrShNMNN2eL)zS;s8~u6SH1Z{ z-^6fzap9}yVh!Q`g9a;2J>^gjfiS#y5k3K(v z98Jp1=7LF;1g6g8;65Rbv1iCjgXskV1rfrBGcf>eVM;5!iXJ%=RPcSEeWtw z`^2X7`Gpbv!eUd{745&*WiQH!j0^3PCbF$>zTY=9G<&bVz#!b|ptNogtI_QMl9Qq&@9=hqTkMIXNVkqCFDeSlXPN zhRw+#O*qo%LbH5d9uvOA+4?ooZX#`i`i9&9mI`Ay37eCrq)ABoxkI@}VRLdu{sU>h zbVxf1o0F$B^q&3Il-6c*@(gTFj%XZ__8ZbHZBBN==Hw!7TG*T*&C=#%J8VuaN#~LF z2hz-JPOwfcF@JfC+;ry-o*K$ExPB?I4r3=lyzyF@f?_n!t8@xvxg-AmL;(%zt za9X*}O89kVM9p`jmC2-7y3g<*4ls!+(HyAWg)qQ-vz2V=g?AAW>%(_1C=1a$w1WeI z+VLdJSLj)6(N5cyjqAk3Q{aFtF);!t=*gpw&~1&VBP5VEwrXnGqV@J3sJ&Ra<|30W zvH<1Fi%QGIHRuTw(xpggkLF+CnvC=UoEd54k+cE;9jXYE>p#h(gKs|;gXgVYN@p>@ zvY78*bbL{Y6qmFtVn-D?i14wA>m+&`yOITq(X}1?7IBkKRCyccu8JO91y`=gMO69l z(9n2q#C3*98p3FI_KEwC6+nP$t@zRXMYkVEx3-S{(M?>(I`4jD!Gc4(S!d;&-G>$| zcx1Q2b+E@^*Yp_dnp{Z|W~E*9&63?jZ%vJdx@)L$4H^&iM$nW{cQMIL`K+FR3umz) zxBs}Ypjpa`%uug<=JqYCI`jI2yIy}45jb|8eSO!1ub)wN(%5C8f(@6i!M?#=&;u{0 zpD>B9!t!2(1C;9kWrGZBdvP(yOScLfKLlGFt?eYp?_`Y)FcKiUUfeT$_@0Y%=e)CL#PB`u%$sXOC{- z=ENXiJtBrCI79{f<=_rnGe`bE7Mcxa^k?+e^Xrovk0HjC6Z|*B!XzxJtMAU9{Vwy` z4L1k+OS!tc@y3P?HyZiBO3U=;YR5h@&EZ{#@rKfdhEl_5hj;8J?;l(H+;s0dit(y` zFqNe8qFe2=Glp#|Pso~ATGEi!w|raabO-_Oq}5168R(_4JW&9l=>x0UzJYA7k4mz7YyZP*OZNVZr{k?c%pz zBZB6qbwq@lM9`WL{Nook79MMD8;e#^NMs1$?7}U!mBT-z5S;N{Lc4?X7r!L9 zZh-&BA9Lm}+qr7xuH_9a(RM=1*RRawJP>I}JzO1$ zAZ^spORgjY1YWZ`zu^SIz)oY$ z(ue|)&6rYEvofSxiNul;ODgN76KymEJz1>sx@KfSmmpt1@6K8q#}SFiqe_Q{`bS6E z=^V=pSr8&hG~b%Nm~Zj}@)ZUf3haRA0rLeAlWdl7ctY4=4?i@GT#8@NY&$zR**fB* zroh94UR)l&9spPM@^o-_Fb3Xfdwsb8n1F$G(0jta3qPj$r{{T$r#P2YUpaB&N{chC z0rA}OPpJRX#!Z|)O`U!WreqrWSdKpahCaH%gFHZ}GK>k(iMBR&vglyz$TW7~=rwY# zlf5IL;h^VP32_#bR5rE(;xsteX&g#%rm28y4i1_z1dmfl0W`Y!yLWbPLls2jm?1Ye zIL~Q;aRwyncqzs^K1OoahwJp=dL1!f>NrAU!r5bAEqd?Rb6aa`x1M~panYjNJ-+Ip zM6#h5j~-?FHf7N`T3Qt*?cAv}E7zWQqPiLbTUPz-+fXX;@yKuRJ?13@ns%8E_qYao z3gB{c(xP$q>VrK!VxlRwWBcI666H6h`_5^h^Ms`)O8#` zxN;Zf{Kn|r`$mt4m=EKhDS1f!G@oz@O#QhUXygc>zz136Kt(#g+>MZmlQ@qTg zb^WlborMC`?#&a%AiYo zWQdm~pXSR_by`$pdRkPkRO$=FulO3=FK+J1M`26{cU;q~6L1;5j#RvFvd&4$pHThhpBI0v1$oh%r2m{Bbzs*+&W+=Uvk z`ND#@oh)t;S7M|21O~ZEMMp}SzNoAFqKUQ0msb`6$0la*}J1bYcH&1*K zWysd?9XS$umN+4UytHA8D$0rQ+oOl5MuOG3jMo@(*0?qqIBR&JFrm$vZ=?(W@2E(9 zQ0Gn_?uf<{$KuEt1!gGW@g{CK9Ef5hWmQe8NGhc>y(PRgDu9g|^i?Z)!6z;*47>wv zGcRv(z{#&Ww>S?k%_}V)sNAYvbWgQ7YQ)zsK65efPmkREoT9RHrky-*%_KIiXzDA@ zJ}G@9P2cPveUqa#y0lc~o#Q(rGm8xU6SKUlyEj!$oGZm|8h7A@C-?Lml#`ld800&p z+pf_Q7ii?@y~WkLhl%Iy-QpvA4evb8-ZefdZiFA`BLVg88Qn5DQ3wSOoka+P@Hh~X zqd*oPU};IYFb5S#Mki<{!HyloE5k3DTU^Q_Y;!WxllsN=A?P*_HwQZ*l!e-o?MxhG zb1*H7Z{NCD3E^R|EyMX@S`@%z#HEKkAYC}8nFf(#a4;bk%2T2ku;O$^sE>o6Yx?=+ zi!RKce__#zv+1GUPX4aR=Tg*BQ^Y(`x(x<1J zbDV3pe$#StrX_XtjCSe~(KD`^ucN*2eSH>hdVieZh`34!{iH^Lo4C*o$XO_H6a zKk`(kPVa_=zpU)|t>0_PTLc9ZTHj?>KgUT{l=*3EP#Mnqtn|Ao?zj zLCC$K*Mfu=`;HKT@RvA&jLKm}gkP{Cq7_pBdeEc6!&Rg8jnF`H#`SXm2Vk1w+o@t{ z%RzZZiw*li@eBNMoA`zJ_Wd_n4yCo+k8(`-SZUQ{qD{z}xUPT+D^WFLY74a6B}Oe6 z&F#?wm{R_qCR6#ihbO??W^@}G;u6(o)rD7j z7x(n_%Fr))RnhBguh`u$UpxPyz1`Q6rt!9P<{ebJ9Ou_p7?%ynop5@Sk2Z(}>m?D= zMD$BkM@Z+TB+>|N1RDtOh=$Bv6{p3D?(5l*AC>gx=dXxAD{=C{KO;r?I`T?FW$T-o zV0k@m&=7d&A*wdQ_F_iRQB0U0xM++t7m_vTQ|aiGaG&885XDvBZsajWYL99gHBAGePMT5djF=}{W;G~oc;E$;hFu{ z7p*QX&sRpoE@%6&UIwooQjU&dhCn5GDd?sFy9o;n1V{i|WD-7t&6x$vA2R)7L5#vj zVqvl!NZ+B1Zxt53eerGavUs({tHlQ<&(E>vlr*X{L#h>TY833%?!t+j!@Y5BI>RQ1 ziNUa11IvYT-_PP3yhVuXA~5yb`!YLoWuSYw?D=^h{Gx3Op}N> z#F+vpS0xSxO|ljB^IfxH%;s1h6zf9(+J|w>TttaCXZzJbLv3^Bj4PewY5(nIt;>}1 zjOE2e%MPSwW~Lf4Go{%nkyE53r)g0Zt`N-Vr$SFBRMFrD(Ok2R|S`4}-wA0ldE78>&U1_hPJ1Skd z+bk_QBVEW&i_5u~xrI9f*w%JUr4WY<}@}2!s7G|!tuu5ICA>*qkGOM&eGtN3jgx~ z`vCXn>O5zjRQt%TtxrDsVDF^(*oeXrY~v`J=Ll)On4!G^+y4rKogL0yd)x=@s~6WB zJ*o2X^gwP{#llVp#MWwawV<*e2E?xnE2(7$XABtej}RCK;RtQ)0Et6RP-a&KE^5NY z**9m-=E>0`ePf-2UAhJ|HcIo^NBic_ch^0H!`{t*pAtrN6PHU#pj!aWs8t4gU#8>1 zA$eEH(xW?IoH5w3#A{5c;2ye?wDkC^|SuG^tY3LUe z$OK?!br0&^*^itGc#ugTO4+G%pt7|9MQ`WQXx(%76|L01Uf7E(pLc)RF0cRnzHU`R zbCwStx*}ubG*{bi-n&0JBRwT0Q(QhYKf=#%_>747_!YAjY)HzBp4Za2U@hB~n~_yi zl(iY%tdZtR$=DO_LKeM&IJ5>GGG5pMIAn;;#9S5dcTO&i)2sbEWZ@xPaDn8P;e~?` zh#EWN3kR^7=rlcW_^H9lE`Q-uGpc^;<+OhNvg9jDBaVrKDI->mRVJ~Ck+FT$b8kK? z)4}u?Z$q4Q6nV*;EW{-`=kn?Okpr9+Jk#iP*#2rX|K7^O&z8z2w2feX8lv=ECX}qAQTz^35weqY=-f2a6=C;Z?vUwx&oP)oRfWN zSfka?mT6@MNF<4sgdk5ty(39uJl*r*I?tNRju)9mX+^}_U!UrQg_5LHzo%SL9{4uy zU$oD$c32tuAql3qIH2*1SBfz8(96QngMd_WXuS?g0UvF$APpCqVu}s)0$Qx zm~gml!9s%nP(?1_83dsq59$}hzsZ&8$O{&NvD(~25FE=6NWiW!-h8#G|F*3;vp;Gs zxCGXxWE2O5-ZN;@vhVvv^-lOaA*y#jn*Mw84O!)*GwVhxg{&^TXU}kD9h=#;XU{NY zt!aPYjPMZjWFdy-2V^Sa>%VPRsE>Qo()VtE+?&?^ds@l6cC^{*7Z>bG8{NM6)ia#V zqC0R;3(Vv*xP&_3o?4vR9$bE8x~18hP&khf~thQc|(jYoFe@@oD;bq-4;b z!Gi}4DgiBt-w+$65Y@_A|??=36_LNuxQ}kXt&%Q@hN_I-m>V=SK}z*@o08=CZ9S&7y);lTT zvevVDsCo^Ln&N8vt+Lg42jfgA>6N11!-c))D?QAvV0E2{+2EmE5s$?l>sJ)$;-gEC zv?y*MoQab3io-IdlhpjMDBuuyNKm&V^x=qyXWWu1NxeN)nTBi4S9YFb`UV8L$GRFy zX$ddPOm#YEYcn8Pd7SpraPR|K?4?k8k9naR{@!+=jOj^cynn%OVQMSD=@S#o1V3L7 zH;7jtJuvcHX5y7_<1u9>Rv}PNEjuvx(XMN~YWv1#MD$+q$&-!s>!TVxXGC^01jlXo z_?%Qba6p-Vu$Px>CmYX@%~g{ky8}E4Z=67#d*_YgDMnO;G!?k3tH2Xh8tkAv6CGi) zWD=AI;2A{_PK!aQL3}4LI78FfhCNtFrfvZ=-W8^7bXi#Dz^UWv9)=J|n17rU5WImo z00#W!shea20lEQ(Kndc)*~U&9i$mXdfR}Eo~s^c+?i++y9XC5FC+INymiuZ^k=yws#D4 zNj~4-CD6gXlT*TPAO29};04~sp@{l$K5S- z<4q)f1by-r!VG$MM;trtLpEJ#$cVs2Za!{&d$^nRiL_6~z9hc?`p*MBf?ZtoUa3F6 z{o#+rp25z}0iK1pv$9z1uz)muXiC5^C972}Yzy%GdjNxXU1id%QQqiQ(bqbf@#BB2Vg87-^$buKrr%=4RvI=ds|1ayEF& z`U>%}-J+icOHf>>d>A!4u5WoHCZjl~p5}Tc=<_q$wkOMJ5EE;Qju7e>WHPks!3z<> zfbklH6>qR>FeicuqY^exGua5`81Tx^vTSMoEH*^*uNBI3@?o6wK*f>n*S^ekmwD=q z?TrEPBU9a8ZN~xeR}eu#reWsIiem!EKy(LLU>tV1gGjRhkH* zsrIvTuYLZ-xpSYLy!yirS1}}T4ek9Q%)jBsOpt$ST(!0i&M#e{v7?@(h6}wAs5&t93U3hvv&9P94`omDay^wblo1F7> zq=j;agd8hDs-j#K_`aOz;EVHz5Hdg=NCyZ-m9GsTWvDkuJB}*j=!1Hkc`>dmDX1aN zres6sQ)tZ4JM`HRNzJdIjtcC%Y^;q=!cw#it5G8Z?vFGa3$tcqXp`a*j%9O;M z^u(mXFRBiV-}%b)(%E(6o|0-)>hpuU_X_VCv!Zv`u!yd~xpjtnC#RO`Y#hpS2h|J& z<%tGUv97uZhYfb^7`dvjEd;@6C0UE9q2bSf5KsnXV9J04NW?3aG4ktC*_cp^ybNGS zRx<;5#k@}BqmUq?S$5jDMBYl?$Y87h;LcjZ;>FIjq!xTcU=pKIv3RxYtLi5vu#KE*XYO|{npOco@jbXN}85Eq&5+Q8jH2Q0rVgY z_z?!Xb_{sqnRo{jJYVvhWAmn6y22uvpT#(KI^e{s%NUj$u!7Jd=B-}x9E<4aVfFQ& z+t`06wd@srTdp)MS<=M(lpmq@N6n^wIScpG9_0I<0;7k5Twrp*?~0fo*p$?O?Ephp zO5BG$hJb^aOa?m?|1QLoSzPfKc@27tY&@t&hZ-?0ByYJBf;fg;95^S1fsJKFA1Ti; z;e12Ghw7ki+J5l`#)a`LHm4D((kb6DHXy94^(xbv_y)SU+*Zrc{cjs^Im zsQ~RbV>Z5mEI{%DS)fsx85VD0HWyAH`8wkx4Lt14DUXb1-?AZn(@M(H!n3{3_Yx;5 z`JHs0vkI2(c}uEIt;-IN7|D3neHr?IaADq2Hx4bY zjt#;f3ET=!7n2!f+citrQ*FJb=s%{M##_x)!Xh7nb@+E?0(79^{^4*taYD#0t>DM} zOeczZy?L2TDBA|tCbk9J#(u4OcJ5clC+r+;bJZ?AvTT@*@7B@<4_rKyQd*MQe-y4) zsdmuOJ?AcG&B+Y#onO^|(8g)2_dafj?wv9K2CY~Le9SeH0eifZD4&u z00K~HvVaq$GW>!x7eYMX8j__bo)-b00UTAD#Eq&3m#$@ER!!%gN3J0`%Cn@xMXRgirPLYlw7*|nM@ljaZ2sv5m-{J5qu z<1%8$Buze2lQOi_U?>@y+&3?;Z+u=Z9&S^Tvuc4-Fe%wEE-`7`z?6x=15X&*D|yPm zU46TEi;eBpy)PRT6B63HcW6kAX>ClyemHI14=TjIX+IdZFjh7088f8)J2!i%*=FYk z$n7O8cDvbr@bWN%@|*1k(+#UW_l>&)4_1gz@jy@&2<+YQd@E%1EGyOVt?=sMvCq!? z>fZxL0?~P3%CKS5v_W&Tg8UX$4anX&ZOIdP$M(GXANG~ib}IQ~ItPfl8}r6!%dQEm#2{av<$5x`v1s{rQcbey+Q(?QG-J750jlzy={ zK4LCia`a0c9dlq}N=Zq|z|s=!sYJdVl+V~eXOHC#qgG}83%fQMTf#v1%3ARU(O&yI z>_)6$#35iAt#dR6(=QmT<9VkKTidfB_QIfSKSSROPs$$-Kl@DDJ<8W})7BiSyN>#@ z#UI!?)aNYR1rrW8hBq<0?f}2*BZkND;7Ypez6QVSK^OWI_ADDF{!n*lZR#B6zdG&s ztHbBsoeC7m{05N;Qezqok(c43>pc#U!vU_3TRho82U^kU^D$)A_+W=aRv zcYFC_luzL0yPMK2>MvGamb&xu0Cuoae+2BEGsI-H-@}w{S%1sBQW7uU)0A#ee~ofp zO6Kju*h#J5qCC>!C^roCN14*i%eOYSd~HmJL7kQUQT-Xb{@$i^EAaJDoy9~rnWr19rk7*<_ls`mKkfy!yaoN+(^E|8lKK9a zj{4R8k!nh}SU;6W598|#<`q`@SAp?m^Y+uNrjJ4YCi3)*yQWX&^=Dd5AB*}o@boNG zy2bd~)3Z(K7X4q0_SO1f9b={cM4#!re{f#2O23yR18*PlFe~Xr=${8qhoJ5*^*8YP zAu?6dE$CmaJdgH0F@FW7bc^woqke+f9q%|f+Zro z)Rf*net{`7aCZ)bjgTY&9|t#32|{8Tk^1nR#L?k`U_zw;^65geK+*5`J(bq_yZEa_ z*e>ou1b`8YuN;!*slrAC)a@Wq#N)sm?gb({7k#j+2iv*-$dUa`NB+Hk@!}=6ADut{ z$)~TM|L76KY*7>iy+}n{fAY3So)}~3WfCafwbeTXg_f-%f{0O2h_-h%9Xr;v|Jc(9 zmO8)OCG`dW$R)O)y!QI1pS||lCkFtJlBjG9sb|xJl-rm;w1-u~K7nde$L02Bu>;9~ z54f%*xaTrKf(#%dUC0F4C$HNce^`P*PTaEY7}>1A!4ChNllp^xxaC!$AilMb__fD; zLBJ6n^TkZw*Wxp&w?o!^|AXR$UcDY3(Wm(osznXh<>C{dRVSg$Lf*%vt0eEcQ&2}J z3V$KTL$ak9?~b5_cZl&ySxBFr$vu1aefi;~8=8V9PwU49tY;q4SzRH->oIf1>Iq?G z%f}C}Wv>v?%rt}{+te2rr_Z}JSWmd9o$jY6i8819*8&i?t?jPN?Ti?xnyM;!E z1!hd@x4t56xSg%{-s;t$H;v&_tOtJ~$B^X-<5XugPE`j%8Jv{b#cHaAjFt45tc;QO*-oqW^^S-M z&0e$Ju4&C%ETtwbe=6=}Ogc_i@h9}NLwrP9GV%Qo|fKX;;G)UJvp z2b|8^Cj@8Y+WOAPoUrWh=J?F?_&%AEoM9VO`p}Z~r>Yvq2L&#ko|L(%X6b<)Iep`E za$@=n;bZ+j3JRdPkefl~jQeZ3j1~U(wsnZk^Fxo#4V;+5=QTpd=aP z=xyRJyldI4ynBaDIC}D}sNPf8Jhr5d!O#a1BfF%AF$;Dv59N%*qPZ(}>`0IAo0b;e z7fcirz{x@zNN2d-0Eih{vX_3_^i=M28WhslrV&$l~+4iA_Tc*%?EAct~9CPX~ zbQ5BQRD;1NEJB5M69HkE5#7l!wRcqa*ofFreV1+l-5~#gX{zb?BJtUs@*nQ*aCiC7 zrZL+}E0g=?6x>r%yt*hauK)O9+egPGr^WP1OOEf6l-M(}U!v`R$;nxDj&_cd1`Hh6 zFKO(6ffF6=9O|-@ClA<^7}YB&saI4Y8yg?dJuWt)JKh6){(ixl&E{)%_EFeAzzH_z zFabw%@vVp(#V8835a^HsfRNs3xwcDrI|_bG`7D;JC*q;<)39y1w&@Dmh9q+tEB>HV`C zYZe_6S(lQgl6FJ%=*03`8=mgm{kCfwdcr`f`D;$g7{W&iIn!DfpIEoa4q=l1Sp9uGZ4 z^`cL$Pq7oylXsPC@z@6za;@sF={=7OO!4X4`^W=qTPc@oeN~^b`jMI&sIMpLYe0Q} zE!V;jy)EQgJ);x6QwJXDncg)oFTd{KDnmW%a!=}sv!(UFL#%~*SGC??4>B3^@lWv$ z-4Y866Z;hwIv4ayEGS6qhc^l88Lhm+wh2c-$GgbgOpG{zhmOwtsS){qQe1f1DatJf zu?c6x-_Qx7D=3%1O=jb_P=O5Cf+3+COb!l-@y4a7+9f`uADnONrB4`CG%$Hsy>e?* zU~!WBpv0uy(vk)L;&rcYmDpC{HpT}IAK2JbIl7CZn{<3-$ipG&1rbjlWU}+%QE3rt zJ{m@@Kuqz_uMe(T!E{$zX4SdhR$6|AJSt7RSNv7;G2SC1$2t(s8r&LU9}WL~{}4*O}50(XPGxK%}43yo2<6t)^#++r%e${p+o!=b-)fdHROC zrhm%Y-)J>G7xn+d(>IyYMf3i(r*Af;Tl9aTxK8|lmv6M1PW1bP_iu|S-JrXo6!h6i?YAzulB>LH{&y4ch-4D>;cr zG(|{%z?5#$ezo+8_=LO|={u~Z&z1&@hc!B+KWIv~Xun#_VkflpUf*d-x2V4-(i?dC zu8!%nr^O2Ppj3zDY#lEfR`rNWZ^X;Sv99hVX4=?dMcdBCzGh?DHfiWT-`B{0gJ71h z52mncwnYNYrxu5zIFt4X#xb*PpR8w-*jA|m>3fkr-k3hVEgkPv4c37WuI>{s-K)iM z*kWou?fV7!v@f^kLw=qQ`PT#atz&-hu(}JtfeknAU*wm-Pa*#X`IegBVm=C6f7kwL zwf+rqh?V*?QU6(9zq&uEen?h%{Wq-Sr~WUqTK^^qJE+5Wal`BUc>U`BrtvoO`Zock zwPXIm*59#gL^Z2e95s@48CBH}>D`g4$fv(^4I%A^vwbG~ws|19s1dcF{S zdh`A_a&I;+-#0rCiT*f`Fkk9Su!bbdmh%ij!HL%IbmKKwaj)xPg@BiZa8b1b z>EXz*s-6r~`hu$~Qu!?*Eis(vFu_(;w%Mzb+`@L7D)22I{HD0kCD{F}4s zcD>n$(_CUXGqrbAdP+=;JeL0v9o=d8*0TKJTZa$dR+eA3txO6v`;0%EeumDn#XE|kw&`N)#0(yGGztfARMQw;qw6Eouy;u8ACNA?H-T(J2JdRm>qpbj%= zeNN#Cd)GPriy0QT(hP5&z^D6<*&U`^`?ztMZw3F&#G6g~U6;Ym_L;{zvA!Z~X+1br zwylRuU|p9%e_SstV_xc-=j@kybj~)G8pbs+{Okgg!+I@Ju>evs=zAAnLTUL z#1X^uaS*$n*|H&J3u#l!~#JO>6huK2j!AeT1J!|fum?y!!z_$I*5N!NL#oZO9rf-(3_s$>mkzRkmctjPFbDY>i&xGusLhFH z521||-o}6U=lAeg*6KyA-JkRs$NeAD4XvM`wcCgS5`ES@iqGWtr5EB2eK;mNuoCDu z-sU#44l#Prk0M_m(vt=F`{;f3?ye5rj^64UgJXS|8MtFZw7oaX|7Lpz3>!9JKxrvk zKz~4ufj>%12jGMJM@drB(4k35C3pVjV@Q>Mk*3g??C=)F7#{|LaJkkMbo`Nj-lK^S zzXqrhEj~j?FSQgOH z!jh2|2nXsg$$dC1EQWS)E%Umdu1l)Jv?l*?9Si~0*z`A<*IHvGBGna<#~|pE;UEIn11uxh;mJa!2%H327|Z})2W1+R2O3F$pB4#Yc}KyP zKuWCBbFGJ$3Wz4IA2>22Fdzuh-Wj6|!_$NN>-I`@8nI7IT*RU^ePSvWuI1}m>BnAg zoyK&uu5S%edG%X^=rpDNHGj}@Nnx!uK-uWRDd-L-D4NLPMHI2;yR6 z6;?W6i@x`Uv{BCv$cvphcnD0o2&c)WQ1dO$41Xa=h!QpuMud&6gkzj^M1+VR?#OHa zKd7|bcS z)opQvgYtVzlaprRv^}M4*q*7=c9)dwRtAg9l;<<@@-nmGk#_O+@3QTmk+SCYZSg%; zzIQ_E_&-yD1V@0Lt6lB8eu-m$zQioY#COhOuN! zD%|_Cw%xeP_MiqpMyA49rkZ@+vdI3eyuP$dyAgF?ihpm?tbuP8j^s z#2Kfy6pz^P;<&ZnuW7#8Z&N|}i^^BIoBE59@f*%ej2Sp=$Ln=7Uw>fOx?djbr5uk= z>L*pR)HuZ73yg(L6}HH0t;e)`G36d)Yv7{80Sk>6IxGzGU<_tGwA(2ooYAn;gSwHt z7%- zK6Y-`-RxqQ#9vn1wLPI3^FM0$z5Q3zcC{OC%`j{C-F+R~J>pTPsR9a6xFH1AET+-g zSQ#xm_Kc%t7$=kVwsaLg*sr9yUis0RJ(nwfAYR(1q+SR34bkxk=vW2pa>O7804mOD zm5h!I8Zr=&?kmi^DZVk(xKaV&PCaDIH76*V(0St@Z(}>H((v2Q=NHO`=0{r8wpzc> zFSx9rGPOO>@BgMfur=1()7JiRAiq#I?AFGP?IHfdG3^JYb>iWK0~7;vcS9IV&=4vG z^vNtpO;9+eTsS~<;<1cjP7g2(c=d$G!{2ECmAHMGSR>8%NOLe(8GHI&-7mhM-E=vA zNi1I?eHQh*($qo+DC%xKX8V(Ao&3MFtMfCpduxVvquTD3{o;Ffw7ajRhq2uw9*0cp zgup#mE>2qOqjhytN6RoyL^yGM=KwqTqnGPdCG~)KDYuC|cb%Qw*V4^YFX(8TH%G#d z1vEJVq^e{@*c@m?5whBnoCFk1?5HN3hldGAJ48uwe@pWLIk_@!Kj|1A;RvMQ@Tf(2Mzi6ruSImQKI&^5;#U6V= z%ms{pHkdYsm;!g4B_M}~;1T3117<3ou=CY}gy|R-3eG#%KV?xlR`7qQdk^raitc~> z&b@bcQ%KoOFC^J)3SCG@g46{hK!6}E5Yh-z1pJ z+ViS1ob~Db_Ry9iY>v$+Pt1w;4~0OCwy|&YR__-5N8gzYE4S!>4)6b>hJ)(ff5cjI zEfGv0uv6@xW<&342g~XI`jD0-Nz~iXww(Azp{iP4BPbw`+2`0SD8Tv<4mfRK3^dY^O7#}O{0~LSyX0MfrA^1;2ZnNJm!r^8 zxa$SZWB4xg0-rO$J0SD_L%dB-dc*t1;QtJ7nf4ofZHJKWOh_;yJIlDii%ViAmF2*{ zMB!|iyoIpu;OI;9o*WU8E7TGiUdvA+uvjBZ#7_*?tW>LsR(kbUj@^8(bE?f~t=}j& z{CQ_?l`$8KUfap{Jtr}l{{3@vQ6F#t4T;bEk8$xU-tD-t!G()yigUMo>W>z_9q-Kj z^Hs07U?0ZeumUk}L#1$gNN6xlhR8jH*-s8cF$|L}1WslYFMv3VYu%gPGMNPS~I^+J^dqJK-U06%+I)6kvC+fF@2`=U7?fA+F6d)Ed zMgO7Ym1V4OG;_4rb-w+)4Bk%0{h83F0g~6ji7sM5bVRk!Xm>EX56fjO9n-s5X~avmW~U97%tz06y{nH1-oC!ydS%+ z;}b)!GG89xc*Zq7#bV3c+3WWEYYtLIT=dy-(->lk#~L?28zS-CcC~#J4AhkBMqO9y zN*Na3A<)#{!byuIi$%NZ@a>>BGM}}ry#4Sl$4y$=ViEJD4aw29w8etwOB=GnA#yMw z`oG|_$|y-mRQd2#lwr+4nRIFcLQC$4s`NfORKUlL}tXVGLx&+Pj71K6cU2t~I+A|AuQ5RSo z0k%5UHlm=l^)M_;ThFwsb44N-!W-~ag%xqr&Hsz z1_f(7gs18|c8m>{uN<$*k*6Qi4#>Y8tLcwdA<5-RBMfh-A3_0Od{!l1kc_3zUx5H8 zN4~?RYO9a4a#sG1wwg^juB{nyj7_FL9$-`POISC)b(b{Gk2(mlb< z2u5vX<)&FR-4S>8W8S7zjsy8cV=KUh*)3Q%Br|h0ij1ud0eukwr(8Lzyku;3^90pB z*_my87q)H6-wke%MuLX%-J83O1xJ(}ir^!kJF`u#bQo}uwB`|J_PH_th$*|KkoL+t z{0x%Ko`74O^~4yVjzf?#WL1DHNm%{h5{ z>ZSK2-5N#tg{wC@q=*hBg9_-=(W(@+gX0YK?1Dn>v2}ejNIuWOHCU2){}d=+co#3! zjOD$o>Z95m5K-|?U0>-Pj556wVfIzf;i?Ce&3J>l?YJtNWefO^9r*q(XoJ)b$dv^) zi+pArG0qPGb~%Q=@_ z`AYe!`o%B&FW=K);J^;;2MjQ-yjdYnXBTQl4{YCI(4Y?O2cns}{6%z+6%<-Ty2pE% zBoZ(YmAvKB@tOt3Ypxg2rLGMdNv~*yq$Uc21FF@FHAA;}-BTVJZ_zw_kZDUHts;dj z4fl$UdqyL#sMX6_1gu_#EU*r1MUf)x=rI$A*! z&qYjpK*ody7D8qqEEnM+jbZ|0OmKr_ency4B4RzKTOoQGZOLSFqezif%m)O@Vtdb@ zSEXMt{!Nu8r5Exxo3{-$_9WG&rOn{r%APG5EkA=RJuGS-!8^?;@ zutyLv7gmj4_MqzVoF?a^1C^lT z)PY;!=#t4P0zPnr(LzOrSSYFqM^)+{8P25GnDF?>c!>3lyyM8MF4Bc?+ohG9A8IMc zT(~tMngQ8b9AzYt=EQ9p82!#W(SbCLCORX1f{jN&QRA~PhNU(4ReXYL+SW8tPRZwM zS}PwbV5dN=4vw-E2T1{TKLj%Mg*Kh3^b$hQC;Q6EyV?M40DDIHL>s0JWKXlb;!}BF z8>$UukIUzI>AqQ79^1#Bt}<%F*k1PZEKy2)%Do+*=csz{DPL19P754!92M|o)N!k6 zB`x`?S1S)Fo|TRU_(> zHgJ|Gef8CsU#1^6{>4{ct*Sb5^eAxklMXlso4!I?F|u&QLuZ_d827hH=~9-|L0Vy7 z+6);;ktLydGH#zI#(}}x8q0o?H69KE1_Y!GWKbt#u7g{F|014*G1xaq;aY#hFvH^W zqnJy6{{DVLB|ks^5;MZg`}c3xu5H`aty{F9tRL+=qN z4-RAb4;H|y1|P%ig{;8dwV*&=qrFwZ+E-nj#@bJlw^gtX)2g4>-p02#chtnd#rq&T zQWLX-ZO1zW59Q}SgbMPX;;(kK7dXCT?JKmmD^Np){0LQ{z0H3OpjhON&v)Qo%~5tl z%ZB%q8=YOV!A0x)?epRq$3$cMjE@4#54XsYA;K*CNMRw!o&+i*m;)wvC0w5jKG-xX zCB!wxbX1UBSq(5XLb@*+0v}&rpP{fX_?861r^mN{ixy4b=ai7ZBtg(7&6^+{pYU@^ zuqD_Mt%A5gUWiLX{0|7q{`f!8QCs})lMm~0qw~CJqv1N%QZns4AVvv5i|q%9n;;zBnwueTQKqMhxrNK7ZJyEBUax_G&(3 zdb7@~hr`ib>E3L51=kb1;b?p|K*)NY2zhVbYeQu7(fbWM8q{l8XGfgZO*` zNIN;cK9q+-5W*5d@$wmR3Lsp*m4&FS9AACqI3@4;_=LQ}@zp70Q?8H~v(@rq$1JVf zF$;99t1pB!c0tfq=7d-p;i`y?^dD3$cGICG&N=B%lc|ri}JXZ6g%3I3YT3k&#xl(z%roE$5t^^eNR98=c)YjexoJh%mF&6o* zNUp`sjQf5=DVi=cuqufjP-h_dfM~!}*FY+XGU=?g9pB&BAHQjqy5ypW|TG?>E*|UHwshyuzlq7Kj0PS6NLm`(^$LhUuK&s1 zF4JrMElDkc+-~CT5?vO7h1V7qD07pwP(~O;06!avBI&rICQ7Z8LIqM32~p`8Ho0lh zmV$yUMeEjy&*Fy*-zeNtTug<?))Vd3WDHEYBt>Uy(?sxHJM6jG&wJFbBz$6$s(Iu2gb zaj-IRO~*llgntJ<9T(oDc?|uM{E=ag;d_1_=4VH2a5&krvR!hSJb9OvA%C<}E_1Bg z$=>1f{#{l8c#%&d#ctyXcMV>SibkW+*XSET!n$4~ZIrdOIv!F#X9cdB*{fHs5H8O1 zhCT94H(dBuYfyGM);ZShV(-Z}cRJR|WjnPj;G#%l0Dr@92RsFAQfpP!b3XG-98DlJ zBqqclU!~I5W{roA7;eB6Z!V(VV@k|X`#8YkalN;LJRaA3JJ{oKy|*nMkL$fn(e3J^ zR`2aFkH_`i4)=Im@9jvB$MxQh@_6j_b_1;HUd*riCkStY)rDs^5ym~l`-1PK0qL9! zdU_LsG!TQ}kJg&GKve?{GEybR5>kmwuOJbW{tC_r;td+M=JW>7hw^W|LPLqWnffbr zwR=N|#`Qm}p2qs$t)2${KdfGaI{f#rr81+GY}2xv z|3{HLv(4wGjvXBBroz-PtlSaNZct>e#vR&Z%7<=|CiiSNkb9tT zAlnI@B9ZAG>H=JJhc*hTi3SErTpgr+n1W`Q%_f*?5zLDFVkF~)aYP;~&tzXawm6o_ z$?_pbFZG9O)s3&>_ch|-_1l3g0!|7}PMNhx!;Z{a;FTrF>r5tt{&2gOeEfaToZgxb zT1(ekqr=P*_N_ca9-}2Yma?t#p{wfIYt`{&7m=m&*wBxlKe6Dqci6ioFjcZy8$$z; zNY|T@4-3IoWu+1lBTfyFgP`X}90KzFVWl`>umO@3ABVSN;roMLLcGgJQ^Q5#Y#UFe zoo?i=KU}8-A;g58NI9{U1$;1V+6UTiTeoP}KdiXMmY!R=@~5Rsf2vt7XS~fm+^e+# zEh;|Ht`orf6&3HZz%46&TDJ7uij_Yt(_RFS)@CpJ2()6N52h@fLlHk7G8)P#8vvAT z(D(`b0p}I_aG)JxKpIjc7Y+&gz?_@w7(u| zi1L!tD}3tV+1+l3a{+EqKquQ5@>UM8Bdt#*jWa^e3Tuk+umb7fVugT|(a60Lh%rXy z6`_xEr7F)tXb5v4kA(+$B@-Ekk=YwG)~_D69HYjj8@gQw`l8)oy4vwlh_$ z*^aa{K96eEl&p)Z@HEM}iz%987koo@YYwLDb^=GNN8i9(;Am3*4o6?4l1KMcm+p`; z=&YHw7D3F_BZe~hoFlq=z8b?Eno|7}n_h?CcCCh~+qD~p6O>Qv0&~hzO_3XdP6;Rz zjmQVmGzfT-?{rV zmHd#Hj2VsDg3H!c`9)fK%5JS(o?TtGldrQ??E7D9y3^Wswc$e+X3++)LmM(#CdmPk z&Y?g@MwCIELQy|=o8k52B;>07a&6V}$5b=b{XX!|1^&ElC}Js55_g9rtEY(cQO`92 z$n(1C^hc*HLs9kQUz9!U+D@{AI9ju5T7-o>}TnNu5C zOa;p7y2~{Maw|@b)z#(7KU_FVrd(IugfHp_J%D`<(F1NosNKz-LdTh?jj9Rfn*3kX zwd@+Io?26?u4d&x8nkepHK^%KlEKl1;;w17tdrWi2fGecgaVrNl62Rxy%(>*v%COX?%%wX7X ze4-HyvvNIMQ$9oPubEr3_M($h$o!6t{DFc2u7P^H=(~ zzUK%a;Eki)-{>;}TI>e)uK?U0f%1pTc1akajJ6g@N=i?|&P|d7_G-hL^ID;{LvyZL zh3QeucAY=ZcCsSIR;|*U+D@&=QBDtv*iJmy1px72hgNw0yjBDNC&DDq*w^83o14wY zn|&-Ql1a(7$lIcB6X+S?+|ClcqnDbNlw`3WR;-)^4|60P!{%$TAkz8Yp?&^sHik9( zX6DRqw3FJFx8K$_YbU?H_uj8rGdA|`yYxN>9P{?uY%FU|uW6ran^DOYszmhH?%3h? zzE3OoGex=e*PD$iIFM{yflJ_5a^>pfR_SK4;Gl=qh574M~duzb;Ld5Hq6qZjyP3iJ+M%2&Zq?5+G! zd7antx6~=#%9)>%>a{#bhV1IuE{g&O^j4n4KKEMQLcZT?c~^Os*YX+i4X@>M5vt!? zyOlDI310AACF7vtrF^S=)@%7*8QN7Z@W;K=lf6gYPhQ|p$hf2ArTmn<(`)&!^3UGN z4V~m~y_R=Y5I@7SenS_<-)nhSS==FOFmDarJ46pDTl>)EjPsx9Img6qV zv&w#H0lbK0wts=kr>Wjp0OpeXg7lDp5dlIP_7^ahVGjE{m|x{n(nhLB-oKHz1!-Py z3wzvc(1#DU55NY?ZJN+~Axyq6r6$3JCSTd;I~L&$uqEZ=LzYUh70c3q)~#vVY2BeU zjG66V%4`cmru!xo@PF8ZLb#*?2^6<({;LhCCrm(1s^lh)Q~%}G1fAV&SLE9qpImW# z;)V9Vx#-Hg(>0yW^&kus5D6YB+Ha57`To27 zg_wgbT6v-8A1)Y0r)NVL+>4K9zk1e>@|atc$I5Y@@VMgd!@lJHe^`IDzJU$apDBRt z{9Bkb=9K!1HQM(U>)4bo8)0waYkhzV#wAyzkX*s#h&3F~hUH!5GhWMk%k||GS3QGe zu@5w?r$pZe8kR3Zv|{3;4a--_OTCtFl*_!9KPoTtTK*RJh?n{yU*NFn*)9u`ANE=v zrDS?7Ph#(TEpH)1u=G-YSH#EjRz5=(^Qr+I*j#y>SNKYOe{KlBN`_|AOS@a;ue_G; z)#b;A^&Iz3PskS|yw-C-RrzTY-1@1o1O4a>XA zKY6Xcn|#n~d3X7o*YX~^oYJuVY^AMN_@445ujRdNQBQB#>-;g~C=Yn8r;qpb2>AlH z20X{z&`&XYEziA0`Fgd5SNM&}K(FOb>2g^;`f&MTkB5BG5ayEnv4`x?5a#l~0rM-) z1P$d2y&is^OLmhlph38Wd@+>E7bRT2=pP+T$Gqs|=wzHzarHT_F`V<<4t-p{xb>mW zO_K0>090z~LSNGNW1U-|AW&kd3Fm8Kty*a}7WN}t$SRTW?m&Z~>FVD8HCx7g*-`1-W z`*r}^^0zQ)5LX-S$qnmCXAX}&x!AGH@Ce;Emq-a?GTmg?Ii7Xp8|#%X0X*GfPhmlN z`D+{=_DyR3T zQQ8abzuGooQc0iQMG-l7rz(5y>fQS;`T_3Cl`*Qpa8*h%(Lk9@PB>FipO-5|C`Vid zd__4_*z^Y@c;*1SSxU6W!#NC?<5vzIA;AJc0Bwm45QJtCbYaVdEn&`%v>033D7Hm* z(dgWPW$O%AE1KM$6Iqngr)1KEZC~;Fi%|bLqD{RRxH>@!Zyf{ogL*Y9Mbn#%?-N*YzYaJMzdnH^M4KwFHgqGrkGwTwU~{7=JcW{gPjuARM(d7P8|(F08>xO9*d43_Z=GeIB9e-Q zVr#Gpn(c@I#Y3vpzO%9RopsFi_wT^H<+y2+dh0OM8<@DwmQp1dCF6Y)2UA>xGSec^FJL{u2GwFJuf8eUIV9cCP_2i@fTrFxcV z-PIaij|*l3k1pdP1;J2Ek`25b@O0kRMP3h>LtQ=S*LV&C{>fpoJa9%^hVi^D7t9#m z7U*AxGw>-h5#38LxT%N=wOgnA5I$C}HfhjYV@3Te<89*|qPtTQ__@)&AHDU=QOkKYPFcAHy^b^QgdCp9icy&h=o< zvd=y10ZpfIoJBo=X^6A)6)g1od0TIZwzQq1p1QU;%zU3ypu2$iT?5@QcbVI~1kUV5 zw|dSxt32>osC8$DI6k7Dv(CR7;zM(;PKMz0Ip7VZPM+W}?Hj^4YcO6NOhu3_Najez z8UPFe6SP}Q<55pBXz@PHcZT&x^PP3p=ld1Fdgo0%Mi6gXtl2ZtCf>F?pW!gXXQ*DZ zT_tT1FmB`7u%5HX2F>}E+q&lX)x{$MjR~*%e1>2?GwwiJJ#<=lfuXoYK8I@Y(O8%V zKD0)E;QgAR*CY6qi$8OI1-gfGm`WXHiU-a#ziMSmPWNRVICB_2cTkT+a|bXqcchc3 zkJDYu9T&62+!^BhMLq9x5PcBq`nvQ4Z`*y%au|-EYwgbzFm5y*f_Ymj<8u7wc+3k9 zS+LT^s)J%;)msIt{(RaD1MqZOg%0c=Vmi9K7$x^?E$`GRXoyv7FBD2|DA_7w5TkeAxr$ ztnBm{Q?%t1%i9w50LG(V>6jbO@wQIrV>;cVt%fjX+54Vtp`N|Go>O`~lRfGo8OI&w zEPKnd9*o6aj7c!dY(%FdjJHfqo?$ z<1xpo`M$6Lniqk49EWw6&jhSZhfVQYcaK*{em=SbJS^F0)M1T2XFf*t;BCCz6jxhb zg=tb-UJFlhW{M~${ODXv_;H#Fyj)@#y<6$LtR6PLiZgpR9p+Q`6LFis5q_p57}Rr^ zXi*DO&im(H&j8>&mT-XA5uNGIvVI(g0jPfkuYZWBAM|Wk{{Ym#g4eIZus)vk17-%| zsHPx?fy8Cb)jGbNJ!nn1%;2~XEa-P$(5Zeo;n-Q=NOcpPsBTUtQKx(VLNWJZOxPP` zlCbcuw45Cv*$aEd0U{LWG(gK%SMzq)=``q1^*i@tjm)8WOEwU^dq&&fF>kS()`L0g z{KaEV(m2fFbQ1NPWqG{sE*Xk&n1dGfa~uxvzMm!43UD|G`BKn?$_WRq%W*zO<)%@< zO_cwxVb7s@AR`{AttZ6?^-!;!*XoZ9hgEPv_H-Sr-`3ZO>Uaa~eyA1e_#CT;&r`U) zH;2DN<*EJ?oT<)(jK3wQ>O3e^8v6XJ)hqGw$@1uTCC2AI_|v7x-*Xy&z!t!3k&lne z4PdBeHv04or=Ng1>l8AO8~vQWYu)86k~ydzDHS~i43}32V?4a?>6Pg22fQyD-T{^5 zd7Lg7FXIR5WYmRn!dv#_dw5r!P45a_7v^N1>)kpX81J*^Skt=MNNYj~CtPt3+a}s! z{k*P;jl3O##hUmNAD{`XiH*clcpXNcsvBu4_X*952z9`&uEqJ~8B> zPWUj~3Wm3PM{T=Wg=n`@D+WIzdO%X*d}M>52gbKCFCQ$*r5(KdKJe*UoglU4{MBP_ za2Ue{)JgBA3K&E;yKJI-3bmup>&pdRtxaWs9n0If#wy*)?RvS<=Xzf}2K_iZ$4kJU zWx{VG7c{8VNpc#*df>%jYTpH33@{uPb+}`Ob%cJ&@0xqHhE?g%oQg3%FBsY=;gmFdO7+!M=ciR zgq!3m>U5JK8@~Ie>s@Ngto@s0q@#R1<5B-pyf2^W?{@L1KOP7@&BqOL5%E$98w}<`!}7CoXIGuZr+J;a93^|4 zlci?h1G9LYKk)vZLGx5+{c?;KYp&Osr~Z?}pA+zx1$?~bUQY0LxNuPa$#DQYjk~`Qqm#=d`UWCmT^?2Khus77%KBz6JX+xUw zz36Vf7tto3Dq#NgUgSIo9`G>d6GHceecppl%xM5~)_K)~PY`~!HWH3s--h@>cD$<3 z*@M6jW8)NKz{~lX7UjP~{Yhg+^2;nfk5G;}&p4f;&U$j9c zqOB@dd4slGbF1E1*7AwB#8`Tfr$k?fPf-2DCtl)xS%S6lH~P$fN2e#<<8B6SGr0b_S1DuVY znr2BUYBuPfD!pZh5wN&QM6m97;pFkR=fi&B`_njoScLj8XNi3ZK5Kl1%GHY~AY5+n z@*L+i<$GRE3>NU41bijNpYM_C6;Y1gf-gayB6#07M7b_!k(@A!$_*A#PLBmYQTy|9 zqbUESw%qW$(I}-D{85l9A5eSYlkhsi--C2yDCM+kqSJ0zL)w8C+!Qju3YnhX6*B+d ztXtpOwRHMHj*Bw~^_(%GT(9Rltrg+md>-YqP2FqDe{hPuMy#2-dcG6&h<2$SeXZ*C z>*c6NUt>Q=Px3wBTj5chZN|HDiz@A53x{9@jhl9vT&od%Wu2rB- z0jv~+zNCvo2UxG#J5&d>H~2gL5^RhZL%OIk8s74BB}RW087j>dDci zvpJ6;v+uXs8ynWa*Fk$p`+&xeT{U4$zeXcH4Fx5Ao{}V zky3p=kU;~C*$0MU_>`rm@Fp@&p}@&@7w!t~3sf_Q6+f^6J~8zreG6&Kt% z0gM#mRIw^_8|keu)-7E71f)2nRMi-@Caj5e3KgL4{&*=0cF{N~QIDL3h~7#iA_*aO zmO7VUO3_MTKg8-Vl+a~$q~eYT_2Lub6Rin&FV1FZ<^zH;3K2m!i+PL(leM#~2Z^AI z#E1ce3sH+(=5^{`cz564(^TzydBK+p)_il{%&|iUXrBSKcO&Pm%S&lKws&q}alx9G zi$)xrJMW23Z6{2O)G~E^iRQA6RVhVcUSOXWx$kWHypScG-aIZU_F`^=W{=g57siRki_eFXn6uR~Mi6v6DQ1N7nqqkMijk9y26{tk!1JJg~#7~t}PT1_*{c~s!#Jo+#2 zI>4S{$j2!9fxl5Jdb|lIV5~v*l-?0_ljw-TVv(ceAYy^i{Pd^$QLstlrY*v|Am1~^ zrXm|PD={fX1;%S!v8JgiE?K)xSYIBj7WBt|$w*|vVwnY|7K`Hp%E_YMWC7Z5^z$X9 zVgY>{wu?Cau!yU4>x}N9V$ivPye^Xua{2J#rXj|U!KPT{R@xP2kr&f%ZR>&iSfHz& zwk(Ur)YUiH=yRIdl*-i_CCk(u@qQz5Q@fYF2UZ{05zjCp<9eD=mF{lj>yOx)#u9|$ zGUl0bqoOeVrKs4b*qCS$n74lV5#g84!=%(tJ)-FGv*dAhN>2l;A^STujTJZN;>M(9~)sv9I)9-sw+)~N`yh_ehSkLer)Sq4*}Ku@;# z0P%{mUd}J8a1MISc_)ABk;jJU3}mtIVjMAU4c7;Khfd}@{yylyC46M?64rU(B1@_2 zdvbSE8K0N^`|OW^cU2f}Kw}Xhm|ES=#^7faU0aSeU6)t6Yf%4uJ1z)f-Za?m5O0f5 z;CETJ_M=l`>FRqdLwk>HWR0}n(LCB8rJhq(nC!SO+=w_8ZKb%siZM`$byT9Eh1mCS zofMa;UAIYneW8(Q$v~#CP zJIA6;L(kxxBaJc+S628O#GZ8>Jt4^zG!dQ|z)4}z;3?mjM(O-B!=A<&Cq!~s&MOq8|3-!!lcO{9G0eGkNUb4`zzR79Fh0@7DatoKr+^CxB5-k8M>sA~ zIxa+?V5y6}qo9z9W-DD}SJ)z7qYqJt%N==YZa@IhCm=W=I4IDaN`8V$>0ycuL9cZ5 zSXJfRGmc{p_L4x+G-}f(lU9vL298aFbpgkyS{xxjd%^L4N-rfn#6>Tk7p~2@HN9{q zxFs%ebz?`N#=w82v9zL*<^@quWjRmzmt%)0i7o;u+Z;#PY@Il9|M-XFv>*$uH8FPU zFm_d*xL}@*G%iw-eV)K`I9Yn)DvdOlm1M;B5c@Rd8BpU`QXoT&KEv&41|9U@;hKuU zL`ak{%D{zbhJC{D(aSH-yMTW*hoqhA1!aus4tSAg<{IJOXs=YI zF<5U(DG9K}wBr8;299+3cH94XJ0%ixw7q8Za=avVybI}VGn>y{o}OMhZ#gR$eFAOu zK7sE+4~Fl>jtAZSa(#nv=cax+?17T0wtNZT-TZPrz8sO`6QqT9m+Eoz z%LV@BuJSq^Ji#{-@VS7m)q(SN+j00%)L*NErgE~Iiu&txPE^l$)I&0d<3YC6c^~A; zY_VH}fbG{ixE0XMi2`fKB|xNBq97RgcvUIoU<2~)gptR&E+aiG)V3;NL}m49$AeR* zg<%hlSDZA8chO za45wA#b!9MVQnPBp5DRIMf+4AwM*@b^O37L)L++LEQqF`iu5CJo}5c(BJM`&b|zvc zT<0O+s-K1G^)n zCuiPZ%Zl>vL-U{k+V`Uvd?^y*Q3&7J!1p`DdmLZH zZ2^@iLmT2_<8Y1Xl-JKlG1>@qBo7G+3W^8{Pc)lT5={Ov&8^njkco7`gPBFJ!*umK z$7jztmoIld^Os|U^11fjU-!?SfB(IouUzqQ1xt2Rw`51=|am?lme)m)BN@PJL_MiWkHDBlpa$czH_MoAZW_ znUFWU?CkWyf~lhi&wm@IUG#Mf#vle`U{r&!iOF0Cx)XhjgaxIuy#t)oDX2#!#=roo z(-^3wP(A4VLcSBxFT`+;vLGlnA~+kQNEYcMdL?IMh<=!?nVA#>gF;}aAyytWOTKnQ zJN2aM>;K8F*^eh^?}k3Zg7>_|I=rw?duNj)O?my1RWF8aWKnM(Ir;Ow6W9Mx`MkFG z+9hq@VLAJOz1x9NAFZdMHE>TL$uR^PlF$H55ty1~D3W9nujwo}mrIVo8R{9v45dh| zU24c}W=>2_9f0J(SrDS)I>tbtO_ zloF%_q|1u7(Heli3L#FRM=+;cJ+h_nkoSn9m4%ib(=I-9SUdaZqD$MfNOh9K!gg)j z{!!mmcg;Is8uyPsS3bsUFYRLN;YNY%gVUPUNSpi}`{K}~Cr53chc+4P2YuC3m?t&~ zd@?aM1_AhuIMzUVUySE6*HKBiHcN`ab$6Lbpf4>&E1%zLSg46oy2z>_BT0gWD%E)T z25WNvl}Yoo_g4J5{V&#R_prM(t%G)oWwSDC>N#frx%ZOoQ_c(l z{YHE3ShGL6FvIEI1rhh7S>iR$OUBWhr@Vy%6Z4b1xXOKS??n>6uP9f6C*W6r*K`r( zIBy_ZC_C=BA#{e08>CPXb@~aI7NSmL6!lRWuN50Ff(BtylC-4HehMUL4rK;8t}$ZX z;8q2+A4=aCUZ&J5%NM}0n2K_#5yLF>d8`x@vcO66K*uX2eD??nq8aV_>|fo!ZiT`_~IT(Z1NmMzT(i z)bwSIt2ga=ni#t5dI({>g<+5qRI?Z=}T>!_7a^zg#-zJT2(wJk1qSGWp~g?*Wa2z*P_}D+se2hdhaNQ3&D<5rH(P z5Y0!Rm(TOSS6+3YpPAJb2++xYcNLwm<&EqQ*$#93&EV(MQ~f5DhFmZpe7@Uswu z>x*DSIWcxWe5h0)_tnQJf^%{@2y^YO1mT#oycl~728-kEVu+9kT~G7vW=8vHAm@jT zSz`)7!?`?{6`fTetul} zuEwhU%7W#>pk)DRR>&Bg z-qENa9)gvOrQs*OAeyp^-eEk~c3wX^rAZ@^+EJ%=lwOXG40SyeBav_Sx0yq1VYZM& zAOARFeh7k`fo_O7@AfBkEtNl3?#_5(=JQ8blVRCIM@OlwNq+Xg(b25Ab}b-d>zK0L zj|?t;=MS|>^{L6lceHKNQvB5=U0qPsYDU+bfuQ+gTCt%g=20-Tj(X1;Q3$wLa{$77 zQQzpR?E0$DCJSbhRLWIMSk8=bSvj1aNNELde(rjZZx4{9=t#5>9A)Eo!op~_U<;)% zQU-Je?)DTml-9I~ebr{cfah5FwokN~+9mCM)|N%Hi1hm_hAe7jIFT6D_(AQfQ*BQo z!_Ut{wBJk>Ra?ff$=|e_dT3HREKepa(?+PDqCX*s((Om6Q%pF@U`$*s9H?^no!Al9 zXf2D12GS_PqS1wdx`+8M*vuANumSrKw7X=3pzOF--UqOL^;7M{+=_*>wa;1e?i=o0 z@zYXmgyFTxWBXRa13Eo1dBS@S@VPw>>-9SDYKrU&*cp>dI9D_dMCwAhFJhfxl0&yV zo)pU<8yMwCpjRa4wrD0x>8+b(waBt1MuZ|#X;Zl=i6l(KyiU#F`Na4ZMB%e_@rz4e zS;+4Tb{V0|jp7A)TjPoqUAi3mwP4_Y{I$+K5qmV}+Wdh7^RFE5)?wM|h>De~rbSdN zTdo}Lba%I&fmhi(FHPLos{KDJwwx-T`o-qy2RgLcIPvIlb~Uh9*9jeKW>23sW5zud z_k!+2u>W-9{0PzFqDkik@dfOW#1|qu2wd2Yc#c|v4S%SbD#MeGdr|u_9T|wBs{mdjz}F9A-5MpUJq`y2+`q(6UO#MBTOjl9e$l{!@#z zr?jWFy|NGMF8it_)sIqmM(m$20=AdfW82c693^9Bqm6|a+g*m&A!)*9XvTa)kUZR= z!!yXrF;U1>i(uSYafm-AVM#-lY->r%ia;<>NN4)E>{~c?-)QaU3%h<>a+D4EF=53Q zv)S}27Szv^P->7_srP+)$i%qa#D&LgVn7CBf$@X zfY-)W4-H4q)4r?+>*u)Vw)f|izc_jFi{(vHwdE|eQ(j)Du0t^29e2w6tAi&lpY+0% z$%iMKkHc*+R;wR|c8U z#Zlv-KSew|8D|qAFk+=Zh%7ZCJ~drDjj`K2A?SpKWlnGy6F}wL12HbJ44eq}T zzab;+j5L1SUs|1r7=Ve=E|F{9&kqBL>%s_;i`_+hK_FV91*Kw-;=&Yy6w3L0RHahp z+F|f2B8NsBu*oef)#Na?AQ7}s3 zEL@z3kl@mW(=>KiZjR-#gprg=kHe3-@>}8DJH!07FIY3buzquk=X^Bh-VeW>K4OB*&Ed4AKTLqv}*m?ynKk7iO^%61(5Dikw%R*0=-vGA%4F z7Sfes+uyNh=G^=4E$p;ECZ*-r;RvGmZqdDS?weWk-UL-$FgitRSI{gtAt4yP6qx%X z;m4hZK3VCEM|uF9x+_r*mN?hdixMaV(0>w=OJy9gkxnSg66}i=B7rZNNb~}#I6Ctc zik!mOMr%*lJjYeIJYv9D#-iAqPb#1Mv3%N(`<8t?ooPR_l7iv+jbn$upVzD6z?ii+ zwy@J%Zmt{q>cZT~Bi8iP5__&50lF{Kma2~e$Hr1?>8|IHf(6V{EYu`uS`@^fuY^?r zvhG|gL5?P$IK*Rxq;G8qhVC$FR4ufM<>%X^X_ICyiz%I|Q#nTzeF3wl0O7VcIYQAT z0u<5E(cYjY)O^7nix}N$^Xs!N?A`mz?1_h`1xB@+U2c0k<*woLMwWIBj5QA)(^6Y{ zDYR$nS)ydre!wq&D{C-&w$!M}T;-x1*8 z-R*V=$&jS6bwTztU=uUQ&?~ET3q>l`mr*3bfdq z!5N%77Q*M8DNJs>>ATJwGFJDPzADfGLx}przKgRK{naaA#NBxl453p7?d+O4uY4{x zl7x*~&Cb+Kzds=F8L^_QEC__={_i#=z}Qg+t40ALl)=Awtg)jM1HP7JZ)+iWEy^Ev z^N~6SSy8azi7Z0^1z{~>9V&#OH5ezzoTrK!Q z$xxzOKDp@Wqwnmy?Y58KY(2PTRCu;+KJ#0x4QrR)x=m)&R$a8edJR}Md;VTuHSGN_ z{r%1=hV|9yC!b+GVpO$tQgW+yS%mXK*b;Xd!=z|v)5h8Z!+>G{RuyRs6ihnO?8hMn zDxYuTu|W8CT18+S%|rARgL6uH z8p%h*43H@f`yCdR&by4^3$d|HJvwDoa=Nu&>a)jg?=bbn$!uH4p~E_K8_b5Nm6H#Z zl^vQ~J!ZG>FTTc)-%>(@%MPVtlk3|rr(ZuhXLElrwF3No5g(s^&R>jUF~5?baqDTn zBPB69G$f#r(cr7F)EL^*pdA5AP!PCX$Deby+IhyL=1t=pBkyjIpO2Kxk~t@!O*#X4 zk4R`v<~peev2A5V@Q$UL0_6~c*vRDJ>#nSl|FkR_)qiS~b`9~2-}sb;x2TD2+c_jP zI6a|%n|X8M+bfHH?XM*VOdm6SZup#~ehC$&#DoRr2 zL6yX$Hn%lz8WA2AVh%zc8c>bP&55m`P2#hgk2iMr3@gkxER3WxQ-le}s*qGpR59P> z_5=4UAN=mV`%m;!R?pba207L#KWby=JvXAsLvuIee9=$ov~5s(`_i!;i?jhLcg`Ms z|K?%s!ov$@f5Arj|MihJtdZZ0qtouno4RdE$82VkZ|l)4v1J-fTrkFB(C!`dIbND> z_eTOD7VN`yWqtOiV)`e$RAyYuU8gZak4XR`9>l|jBsPRo@koVF5`-RdK+BiGbweoQ zADxmZE<8o2r#ZyLc|qvb!iWm`VL|LN@6WZ^}VF+uH)#ZFB0CBknydMrJIm1MPvlj#QK53Z41EBVFVpzptT2Cqr*b{ zOkhJzSSo2pptt9Tc0}j}a;d3F8Ev634v#>%3_;xpT@aC@K75b0SSTCwN34BSdzs0f z9={Z?{b?C7FlSWP{_pH~{xo+?Y+CCHEU;XlCX0A z*4MCZU_DUw8ur5*CrFwoqRJ%ExeLp{RO!o1m^>zKB2nNrBy0}+_!VPMtOdgZ^ju+M zYvI9A>5P_dkK}nPf_!*Bf!f>^e&m+NW0BjS$0AjW&8+PGTATQl(wlx8_B)QSt=ecg zyJn-~FndHBDfa{~;CI=$+`Ep?f9yeO+JAdy>`dn=!3JHffvywdOS1vll|S)>_NkoC2Cd91%w3s3q}TKVqt^blx$vlVrVTRB!z&t;aN(6Cb+dP| zffHd07!jJ=s8%9%8n_SXP2nf;*0!J>j0o`Q2j zRQ8H$n6mFf?bA;_S?Ud2*7=1cOJ4ZHE5c;gD~IfoYUqjiTGD5KEZ9a8nfeytP-{XI zqDmYgV16gP0#=yGWEcsoiwrm`CDsE203g9P#<~HKLMo&=^#f)QbOgEfz&)ue7;uU) z9vVm5HL)12ad6Ab1gUZ}vdVL}Z)YuEemP@s@t}-pCmwkCi!v6YbS`LpXCZ5u)+s(= z$m)tVUyxJL7wOqU+O_U7YC!2jd1ZTtw!fos2h0Z<`HeYw z+UGaFJo)32t=f2P^3l_!iHEnJ%zb{&Lpk=nuRpiu4{1c%3%NgJU*L?hpfZ*p`t!L06`FRGHj)~d%@(rs zLQjVbdRB)2dA5Wni=d32pcS%>+Jo8`h1zFovDTiw?fA^`A$wJ`qkf`Syz`u4oZ%v* z(PBX)OG-j`7+jA6pu1&=y$*#|jJ-i2ba-?kCz_HoKw&>eTq3EIA<9j4dxqar-onBeS`dCNz zOzL5s)PC7(8D&wamf(blm$cW|b~SQo8=HTS@l1fFU{vSDEo(LpZ58D6O+d)~nr#n(`!Z_`9fJYK1tXMJiVCrt+~!iTMT6TJE71k4 zAeeu+6hYDzIs@~Dem;$HgLDUS+2ZRU^X-1-#H3`L`b_?fk-^+-jUa&wTRO~pZrT=7 zwvgF!35!)$F>TDl$4eMn>y-8^_$ue?#0lNXmM@$APl#Z@Xg^{tt|aNoGWVs)51hOw z_l_gU&E{8>%_Xs`<{0)xoQVwUG5^CLQLYj?5pL6pj`Xx?)hokz)+tc9O{>IBaaOA_ zwvtf`JXJSpd4b8dhep7EAucvNIU<=XTdB#gP0+?kmMxual4+BqgJhPLWfmz7#j-c7 z*FGQL{+*}xohhIC<5OkNbYxMErFm^4yQk&l$EOsk#Z{8}baThK!g)B&$L?k7g9F>m zskyHe>!iiT6>TYu9kOx|owN4BZt)uE5CUyVce~w>7=2&lnNt;mT1gUtkeEsJfL&}P zO<-urC=YqEEg?QOI<#3>Gs?j%g|HAZ@iT7wChSu=<4=VyGlH^^i<1Uq=~~^H^4v{U z^!$*QxBWS0%%9s{9s(cqqMHXkD`GiAvP)P8R-B#Jr|2_v;!f?GSLgk_{y{~H+)!00VE5>`Qg5^ z(<*-4v*_blY*x;Y;cEsa_IqgLjFDem-r(Gx_(=7-(Fd`X6lt?oVHkk*7mA%I2`BY{ zM9NeiXo5RC7)hV~tU%s&_vCPPadf;p3gIYb+nk*mgA$;>P? z=VTy_z}(vW*C#CX#9!>s6WW&xKbkII&CVO__#-bnJ5NrCtYU#yHdT8dLAzcZS*=}9 z(C%Xk!sef2R~;MTR?Ul?wO0Eha_;Ilc|tttN0GW z5JiO03?m9y!7DK$ce2PX;g4sqX4+3aP462RnQmfnim^;xSS8KR?hm|a9gGG)m173k1vF z&(Am#3=wBegMrVx0+qT(Y73a5#H#?sJAMpqiM5q@f6;!M>m6XqRWxqzdTR>G+2Hgx zty-ExQ<9Ew0Q4V^UvlhIXCok(3o$0kZpLp;a`DrUk)+nmLoezAGq zL?tz&Up_niV$;3}%-k}re_pEt}hsy}M^erSg)a;9Wg9K?CX>KyHTcRhtBSK*Xrvd73 znEb>ihB8a@;MOGtJD=OK<;7=7-)vOBBAKg2rzm}XReh~4v`Jm81yhqs$gDQdIU z*&NRYoLAJXYJ0R-%~NVVhpcAck{C}g8hn9cVBZ+MFdzGaA4a()Zkia8!M74pwvW*S zjVOG$RUdA`gnJz$ zq;<46N=giYvkmUA_|o)A4zYoKTTOJ^%4G^k$w+qbb5K|g(SA#NTzTDbGuC!b_R&vD zPwboZ-71!~J3%v6923bbD*){IK4k(ucHM=SBhAVa1Ff@k!1N3=9kp46`K(H;NE)qu^4gkvmaf zI*{V-hu6=s>py*a^X9jXtE|OOcb1mkDd&u0`?Z~)J+<$o^1jwn`#QI4j{zJ9_{AA3 z4CAnuw2^)j;#&?eJntXN|?CL{46s42LS1a9afz%S^yk10WkKikwon~dckYAq~r zhuSYv{TE59NUMF38GYew_wT$3=Aal{xbc_x7?$)CjgdJ7^m1#9hBk&tO_CF>(0&C6 ziVWBg>7)b}@9$Dkh+~|UvkN!f1Wt6S4T3YYy}AN}jDd3K{^z%BVJ+m)o_BuyYq)kL zV8o!DQQdNnv##22Uuo&*I&_zB8#-#uYrD5S`mo&TN9L#f8TijlmdxBPY0WzXC3n2M z=ZG@PaVfh;+w_64N%1>px5HeRgfraF#!zk(A8&7Dg9(ep25_6WV5Kp}dZuxxf9p)+ za9qLcme`^?7`LY|UbSe(blW+$*$|`vZ_1i*9U%7v@i3ipn2J8b`|}r9=CcEmWh)-v>9q$U54vl%W(HiMG^us3Gz&DNH8e`Cft@ixi?z2k1sW zn+F8e-q2bw4h8#YmrlvaskRXOpX5h;!DST<)Aw8Gopq@dyND2u40KW@&Mf?a3>lfk zkWFS@m}#<(e{IpwrD@u=!1M=77QQxq{Hu$HElFc7(w7cf^y;{(`L@Er*(EWtCEaHf zs{>idJ>5$h$ChLdDoB#shVFK*>D+GQG<(lA&fTF;z;U~CJNAv1)UNYt=M$mB*A4C3 zp6zRIe_?m%+84UC*9P5g9}49XXsV4cSs^b9nr;?CeMm^KY+^c16G0b2Q!16~m+Gg0 z1R^IZg|h%-E_#wmrKlfFvW5auq(I+-^{2yO`FjP+hwF*drBl1iHn%lv0-S7|zW)5I z+TbLRl^#)F;7m1>RCjCYDj8`@hY6yVJdhr8Js^Em5vVFi?&x|;+G-)(qj{TcxU6WXzh9S^Q1Au z?|vWpp-Qwp5HTN&>N)UpM&AuzWBmk>^$R{fP`*f{YIgbb2s;6}0*D(=VB~l&KnlRt zXW<%yWV$H>@rnKmV}`G5M#|xid|V%Hq1qf5u3kMTAFf$XXU+qT?syfvYZ@lmABF?a zJ48uS?Sa0y6d+6C=0F%i$lHhnL8M@W=BETvzZE)3`}-Ods0<-NnoL7Ym^m^034mZ^ z9NXY2ICww+aEuCwij1I?uE9ZQs*%NPu{0w8wvdo?{Er(@_&-Lj``|NwRAksagnY zpXRVK!lMe>M0Q2{Y}aFfU+!<(KS52*S{(buw`!xqyPotno%1a{%xz7}o#)k8FwRD` z{C2`~62`p;zK2NguJ`jb;YbUD!`3jC-;jl93HHWs?uSTj`4Tx#6H0522ZSEFzGLW7 zqkXzxJMqaUtkr(j(s0+|>O6HH{T!Z*e`s$l_N%SNW{_c`?GY9;Q*Q0(Ly8UV=p&J8 z2cAB{dfGNc-nU@%V|Qs6f82g$!Sn2n&qpk}xPJQh((*~VqtDMy?&ouv&0~$aoymGt zJN<6Knn&)LSn(i@jV!g(`WjLoKZO7bcv=y2$9dk}&qsKKuu|~$QaZ^?QcP56d{{hQ z2}!Yqa1}&I1gYer^9+MI75fBfs&X>HqPShw!$etWwX)4u94HhsX_4SC(h zbvkQJwa?p8(Q)zg-o2+U?pU#7o;}riw$u2oc^lRaNFUn+v?ssd=D<6Syg4CqJ|}o{ z41MAlqwj0T7R%&P>Q)JN%5!yyyn)@%VfCMKZ{V2d@X$aQucbH^NA|8{h*M_1+Y7fF zasoDrgC?CZ<(#}yHpOBMP3StK-R65|eYtwose5teEdG|2OlDn|81~iZ=5NM#eyJZ4Y-o#bsX-gX?x4 zu0hFvzKJ<1kzYKj-Be}OM4n3_7$%qDh<%f`yl~~~qaM@V`X1~sGW7ZHnilu(T@hD_r{7T!wD~DvJ0mnq_LtE7%SXu%penun4y&mDxi9^>o ztk(Q~+}W42pxP|+MyLQuJ#9_3nnKdKzBiFgWE$GXh_G`?+2bedXJz4Oa2 z*-JA%o;>{#Iy+%OR)4k>717_G0oj5__vAzxY zI71NYG%#dyZyW==NpN5Qye{DQW@<#*PjoLVoKJB5N)T!Ck^h(TclP1@BX_aVXQu!2 zRXHNKtlx~j(^Ge{+qF0E?3F!$Eg!%C?)aHU?ml&3RL{Zr^D>5OVdkzmgMlVwn#Y}& zWx9W0G_2?SKZzbMHyp-(+PcsFrkM1NNHxoKX><-1UtM>{u)E?VTo&TtX~-hWmLD`6 zuIh;jQ1`PSLrn5R%aN0gtHBpxqQ`jXpXQneaH7h!DwmoUXp z7a$-?s#EPY66&e1rWlMl@N3Xb_A*16@$lIaGz&~3 z-GVs?!EJybtULie0T^X6Z$@OLE1XNSFkL)l-)U>US-1Aaf$qIu#?7v7T|3*+pzRvc zI-hDXr$_mAcJIq=TcpCh3G;Ul8z{d9T%x4W_E1Pe5(9^#9KNy|2vL!YEw^D*5sLu! z2pM`tGQcaN@h(><&WAeDo>1@MPBN=`xwHXx=9$bSLKKTDz^AO>1toDi}Q!GR{C z%eN_mChDM8nWLJ1(>g67K6H5M%qiBQcB%66GnSrmP|fkC?fle0==RkM}vG)Fn+nrL%8gtV!;qY0;7|V`$bjfa#3qG8NR$d76xcMhN3;m z7J~nb0SJ#HT<9Y(TZQ?a{>UU_NEmG=Y<%*>?EBWSZ&{b_Y28A;Vv}cBM}{UOwryef zWk+VmH9Ir|dwx`YQ=8*UW!giteAG95Gtq}`@&Y*+bPuBauMH?%rgaBvZ4yB5rxFrJ zcWMGcoBWB=-_GdR1GT^ghe0fc%xaM0K`S%^A*F)z!@nC$N_J`}__bE~O%F-!E)z{X2LBqrFOPzg6c{e!RfW1?-n+~{9U zGNq`~u$t;r{~vGf0UuSBzK`E?+a!~OkW4B`NMn&I|$=#6V3}zg#!M25Xy6Y#()!s`>=`w zyA5Zt$RxTOa25+dcyxbn%UL3*T{*$u`HtRKu!|I;ugtVBg@GrtLK5(WC_dd3gg_}u ztTH4z+GH_V{R{^97SUt6q)lIF-O?v#*SfDDb`?vVR#{oglK)L| z>!z<)un(oHO-lXZh4bn27yV<`$1{cw89HRf$JB;E&_`nj+_*}#!E09Y7wm1c0sN7@ z?c$G!aW_27W84?yd7Gn<*N>19EEBAEGSXO#IAs>GmvD!JymL|Bz!uZTLP;6yO)ZW7#0|N#m~rd9+HW&J1J;Ov^h6V6N9ahQ=x$aB3ocZ1 z5}T%Yd15b(8tkFcrer4B23k^E715jekkFi%*+q?+%Q+C*beb^WMJ$3L6jD39ZQ_4w zH))UT(0^qL4Cq8Q6=pgN;asmJ z-w(5!%nd)V4%##&N2_IiKWcB!n=wWEcH)eA>_fv3T4&blpUg`UcRR;R+Ap6W0Ijrs zsS{R#rS;ljDU}`5=|f+7Tn2rSf|XAB!v^n3sY{YjBY1h~AS6+PDP0;-(|ky+7L$QEF6RGyj@qb2l4I(>|4GV=N z7(idQPFP!CA@g1fQ#cD|~jBq+rbe$RF4A%)s-pb3C6<$zRHXmej4e zXW2K~b9y>PbsxUvP_3`O`o+;`;~?4*zv3O`bq6&<(+4qT6!|2%h8p~ zpPiBs-?Jd(c+~S-Hs3R?V$%4c15<~MEEjjKTW3UQf2h&L!`0oKKl`=t+kbMNK8*A9 z?}c$XzjY%75zp2}7(WKDie>p2Y=iU_Y#a2hD#Vk&0bb5=KLvyFUe=ReAE%AsJU*6q zJb3uMYU_UVWPAkc)^uul`ane-?9+pEaZkukhd4H-KeIdrJzZYm>O)y1fN-shOxhR?g(_ z>MMKlXB$8-SP6J~HosorI`dS=P+gDm#r&NcZi=BwW%PPC+!R9mP~xpGkK_M0CseK-c37Uf}pwE`Y+!V}Q9L9^~R<`M((ClgF{kJWv+zw!~5@YG)Bx!V+XWpAW$+?A%pD+*e`cGv9 zlxcuCxsWjS<*(63$Z*0p?zt!}BrIe7I^?#y=z8;ID(}9|^|RT{{aov=pKGn)oxqL- zRyN0ug?uHP(%;FiQ(Zssy1o-0YPr6L)9|BC1IxuHYypTDS_{29N`QA3{Y`d#L@_dp zD_L0u_eYQ%4}1;|qIhzn2NZ%Ry?Yf`@G~T0UG!@CLM9=IU}EQIKVw}-3@IAUVuueM zGJv5p8cwR>ePBp*SBgZ>_M^2bI?&ANK&bS zr_lhTZv!?_$V0Qdy+i|CGok^46+$KeRidgE5|yM%!hwpF$azaKDQRsVMEe^4(vxI& z%KVE@Dhij;q)JRosyDC4A3ey)G#WiBu;bfk2Df{doVoBFq03{VEm4tN%Cq=e{AgEg z5%bJEkPaz%e2djn^4!QP2Kl7+lxf+xk~tk%xR-YMlkFGo=y*S+EAQ}M^VQb%A1yU# zU;5lyK6aT&T=V3-71g7j{eI!ccWFs5)Ff>7Z{>djjdVo|`rQHvO?Rhb;J;|V_ z7JO_yXby!;ip&B76d4uj47o`VUy3Lal?xx1w$gEUm`mCV4CK-=xu(&DWP(DVPphmK z2=htpJI`uw$_uqOPMp@hsF@U?eHlJ(CR@5qd+X%8ulcd7njG-jnUg1HkJc8l#?l2R z#afo;l0OZv@bzw`++kQmC~{fyAYVKQc}Alya^@ zDfGxe+5EbUcS9n@9T^GQVd_V5nf8vnKs){H%i8BtCIxB#3L6h8j zUl^;3^8&R39UVuJ@Ir+b6NG4CNY}1Nud;VdOHD~i1gMb(IhRNo>fmiO2whkgAM6>7 zqNd18VoyW1iJ9=5=>v!) zX_48+DNj)y3SoAkZZV%f3&|2#=(In5$FFZ<&++S!zvQ8qf3b?n>n;$HtI(r#?XWt$O(e+7Id67T11w(S^OwuhaYa zb(BYOvik6|Y_RY6!lua2Id7vbaG}G7=wKKnV2t4VqF+Z!2?_}YELM~?XBhjwo!y7mJreD|b;c;E@#|5`d}!P=Y5Xr z-?m%_K71I)!V4E#@Zr%HPvSQ~zwjK+TKE&0(ehViMmx!jNVbDmU@(|r$CAMr`b_Mc z5gM8iRl{<$x3y*g0Y=X*ip&fRu}3b_US!$q%5CiY(Qdb7WZddFszu(Wsqbb^OHZGc z`7Q(Q7Y@zVcF9#3uMhzUagb)=^TM70MPEiv81?~KsB(*oHqxk3FxXY#o8%14dA99aJ`-z}$(yme*c^beeWXJv6L`IAFTxr=X;$9C^|95i6{ z$fKcCcna}(bWSfBcw12FlHhQYUGw5P`Wlgd4Z{jK9%ZqBVeTctC?<-@+*9Kx_yzgN9w8j5Ucz?E z%$}mn#0&s2NL5mA9msBBb$x_x3NlDK3=Z`7^Yx)E0|y307(8^? zAXlah0?H^ns4bS7cqk1oAb`IJ2^7U_IREOPNBR~xWK-awOZ;yIgn zU6}@q8}dy=)w6`JD>^r-iGE94cs~%oJuOdysi^M>AMB3g_n=r%T3xJy^rcit$&!>z zGGFUOhx?)q83{vEC$mNIfNaFDhhsYlqL60Yna0>T?My&^diO0yY;_^A{(i9`PvT&J zYN>a(@1`%&b{B3LGGyx@vCq{#7#F_2G1tRruKRU_BLNl$62>I*PdiBX1xSy3L;_76 zypf|G#=;bRG;D1{JM|o5oi~ZS{;vHN#e)53l+9bTXx@lhP1-k6%=p^=UmF{L4LW_y zKC0%q&0C+DSeAa|l$$4!EJ1vT@|-CTy>DJG$kmD%8bTpKkjVf(g7^%0+jQFss3Tvk zYraH;Gr?*Ow?){30su8(ASyjLmG1Q@w71Du%aZw+>)O}d}ui4lU?{C&lrkSCB%?(YkEg4Jc_4AR=89H1BRy# zp+qsY6&RpQ(xmtXodLI$9=02Q!(x)er9w=|b`OxX{x82jF9uTwiDHJD8&K5xS{|9( z8NeE8DG6PoEfKcPw&1{y9k43HS-27Non`8Q*HMCBMn^JI=s!ty4$MTFjqYa7NQVyK zGB6@2`}engn*Zf4?LXQNTUdujk3Bv7;l|ue<>7a1s9ZK<#_Z|ZO#75BIRkTYdry(> zV^`k0{iCHw@fnegc#4@X@0>SqMQLF8%*K_Mrp=sr+if%dPYgAgY*Epvc^CpTY7xfZ zQ}F(1SW=<4#8{vo$U)cw5P1ZD8W4Gy*Z>)uF9_ErfCsS$#C5R-*!TB z=xrDapNtRILjWWg@FhgT09OtJr68-f!RP@#gbW1CA2}7W9E}#Sa!i{*7;^%V{}f}T zOej1a5D*>h=Y`!Gxd?z}!6rt+i`61Zu?}knoGq^LK_hi96trH0&mDQLW8An ztPdFx#QcWndZzUT2}Ya>rFduRRz*yKAi3-ZHetqhFzhe< z=Ar%HE|~WAmKW~`-@17HBSW;Z(yFd3u4?4cs)Q;n+L02H&epRP5kT*Gn0ahkeQ9Us zjbAn{zvHfu@Zooe_p*Tt26Qf3HSF+`&ixk*LJwj-6gB@Ot-`zxrWjmEwy@eFzySd} zL=ltss zeVa1Di_Ov2c#Zz-hYgo^L~g&l@dviB`rVO@y6$m78O-g7BrFw0L5Otpw#U+%g-T)&QUpKAGa_=};dT+#JAejZf4p%Qu-T{n0Q*FNUub)5&gFF#|H z>h0rt51k)J*B^7eAF~nkTyuVu`qjO-&2^_A)lt0OH}vviEIygAOY>*vo9}?$=QyTT z_sL7Zp2vkN2EkWopnq^63<+4|%@q(WwR z)ez_xGDP#QEPv)vGnVWURoB5?^+EQehD*X2ae=fzeG~FN5R92T=%^v@286>Ox}u4g82xD z(yk_;7}jHXi}DQd5!)l!L$C?C>V(4#4jW<$LGTqYCU{s*%VgzISXg#I90MGPTZv{D zYk@oWcx~KKwT9;_t(6PR9lJb<`?<5%JZF&Je$RpbvT+*YD#x-6tLb3goBt-|FvrdG%{|dE=*lS{~0+d3v9xRe#>o z)Y9&K*U^8zg?{v|JcrYN{tD4gwz2WNzVrI~+Tc%xKH(~Z|UXL z=Xm)BjN4%vNAWZM+okW}_dx!;2wvt8`X1*8km*UrLpK!H)v@3Lot~-!)B-y}}TEdbjq?siTCQ`4u8A&a7W{?&tNlZM?AhkoM|_4QI7i z4&L@9=sKcpRc?WdYo!QL3o?Nbp2G7-WN4XcgMq1N2<%2K&^wUm66ujCkA_(VYb;Di zR%G`hstq_b^Dqp z?q=OLtQdM*x+pYlWoyDB4zV6*8$M(`4>f*$&+-jFpIg5E&6%m0&+@)p36lP);Iw$` z{YFoOFG8km3B)Ax9YRHU_Cpv?DQAS?fI#H(#{&E*iJTFg@cBX`o4}r7aqQ&}oD;QA zoz+skmMJS&e`9ApcTN>`yT^F;mi#(km;HsPyaH_A6{Bllf%#EV18`siq9lLjPq}$U}AMeD3u5q?l$UQ*u@RnpVg!r&dfU$%+?+wFX zq0mwAkvsYz^#<`ZaCpF=10~kT;8sScd{qbL?d?0>kNNtRdk^W~uUCF{R?i-p8L27B zNnPS&q7lE!|KHJ{@=2_K4uhA=V1piDw>g5b@jHSIcI775Z(4rw{Na;}H--T@+FqMdQpXAw44+uKuC%IT?%a|pe3>|G9xESKF?81KqUxfxL#vBt z%`B=Oy7sy&?4QFbO6uxLs*BbXO&nG?r(|Lg^(S--=ZDhw&D)T~9GVwI@c@wH@NXlA zTbK)7o66=IIbiV=rP4KmAR-h z&W%zduyRl*R8Vcj<&VW$_y7jfCRkMd^a zC+SBOQPPmx%<4J4yh>rxC=Utzu#l^~sYD{IEf|a;S?Ed8M?ghKdCW2#^aA^r;N?js zR5(v%h4fI&dqWK_V@)B001^@~1r*SsDJjY6SyUtot}l=R z4`_8_f4M7GtgkR&(9uLliUBZ)!)!#F7RGTrx{c%5;nbLx%NScOT;nFD6cEG}*~?S* zReb#b#0~CcML1kr^I!iro?r>v3aYCM@P`_wv7f363aaQ2FK}qV>el8phzpO+vw9iH zP6~u(yjq_~=y@){!wiD}aEU-pqM~h%AlaSOOj`W73SBd|vEoZje3{UzH3hW^B_h`n+iR#WgPw7YQ2fhAqnn*3of!$m;X= zBT9h4;*OpVfHj3EnMfL31wzKfab!oPd^^kxg6(W2nHR(nL?&N2Y>|%><{PF{PZ>Gw zsb|qLqSM@~L#oiuX!UjTCZjFCvD%s%#B>2_404pfywjg*y^_JGc>VX zGpjSljp|W7ZyVMC{4^Wo9Fh-JuWA7+!AqFjr0DkcCWW^c`BUt)vQt`(RRHWJ7|X$O zvCYF|1a%1;2fjm{qT^*~A;ZmPjj?ic4~BF(N|kD{2k=c(=~9<{ymrj4yVeaXobRaV z_r$Fw+cwWEEwn$G_C0G^;2pohFP!3v!J&q7?M;E}%hXLODJ-I}s?q zqjkWQsCJz+2^P$KY0h>`SSGwC80DYk7_<-Z zQ~DmGO0vGYkotpcSeVH8j)Il!-hTBRLq8mr?--72cMSRGD@XSqxyX*}KYH~lzI~4` zSJ>`jdyoA1CWCU6t>JTVJ-aAni2n!c z)}s=YYxf&n@25?Wp1~7zURyV=-6q1ZkKe$5BeF%Qj6!C}j39|akuY)XfrzBu!c>sK z@FzXfR4N^ADn(4|Z<{ycts=1CKbDq*CdyHS2Q0$m3kMv86ZD59z%k!mbchRz^^*}u zk01sHyiU%xGSVFmW;O*=@QB-z#;!CnN&7q}^^S_l4M_z+c$ZiBihh9|f`YvLq%YV% zoW|AFsnz4gRVPfiSG=g%`)c*pME{_u$YB2@K4$10`HYeSx-c(H{u~R_s1F(QZQ1cq z6hSP&+MyVHNioDoR#S{a;eU4gmPUQRx(?Jnc=EBYwX^+M@|)WGLs-|RkA2JFf{W9( z9&R|SJH_!2qh-6aCk?`lTDd=l*GT!gLOTb8Gew?vKcvlAmaNrq}FpGbI zm&)^?%tg#zHQ7hIoz3wXHy?MG2k@=29TaeNtQ#N%Lm*F7+QAS z{b!Vy@Vv^|RaAlTIvgy!R2YKzdf`jz?864lcW4i7SR+MS8aBlH{v(LyFdG za5o2>Vu9~%HyTMjxaK*8`$K-uh;i6r@a!Y(R9c$WUGfzR-rr(0Zhuev?v(z_b!{MK z>5@6Yfgp6E9NOR)(9#A8F=Hfvid*&=y>^^sonM2OI+s0Vw`+aHCRZD_3HOSPVm>%q zG4+k^pbf!rF_D5+T8?|=%z0>7UNCNnP^PZEqx))Ga}22$5%WqIL>b%I_xHTS);{*w z&p-3_FL9m|?`?kKzZnml4oc%8v3{>@neOQ^eeZnL5AOu7aaAi3sgq91^7PCdct*(OXvA54P`n!%s#0z*B{ye)&&0N#tK zg3vesservJ;!r%{PQjpTJU&|j3Ek700aYf0{dmtkFKyZ+PTTjyfdfzM<9zG@JBSe6 z3!;r=VrY+Cc9!?L&he&5AfygHA@Aj)0QR3D@^IE!`BGH9viS3v;#^iB&qow9_ATcd zx~$}U!zC+`?RA9odh?>z{v`f~Og>BthW&#veQw~yT=(2i+)?&y*FD>=YJY!9du_$q zwVv7+ECONPv?pzo8>HT_b+p;@u*YHWB@up0&Svr9X0tch^Ju>#s0gXIbA))%IYLQ( z@{(x-ZpcsU^Y4$*FmwVU%;Q(FAAT4=q-K(3Ydw5RgQvmUOF)`Y= z^x#6wtDVg+v{{casGioNxYPNG7_B`YAJ6if=Z-Ib?9M6=j|ta4({?Q?feTqqT%7iz z80|cF#{>_LsyiQBj(!>EyeLj-ej3twn9!ZimL$}S)gcjv1A4BUBvBql01GWeH^E~W z<`yqI zmH#__e^0-SSEHy8CTpXm8O`pT6D(k-UajecZpBw>M>x!z%E^r zK|B-o$TP)(uoo%95UN|p{R#$CzJ>vzC?|lybsvS{K?m6ZhLGQF>hhc-=KOZcrD)(uaBIjtgwRJoA%BHE>SeHq9;$Y(8~O z+i-^oGq8t?TxSy}@Fo?ZK6(br^_m+usLzCaTYKQ1=Pzh>w(0z%e^3|EJ_F4YfyRXo zs!I@gUFgro>u%hrE<$4V+jHT0&Hm_lZ5q|ppyf-WnxAUjGYDT2IH8ymwO@(bGMkFZVuqIT{_F8s^Fe(;kjs_z6WhFtrk=5~f0 zBZ(MB6r715CTIiLFQA^Ga)~MrCqW0JiGvZZzpb|%+cgk)DI=dRra*JBmBE!Oy{yH4 z@EOir>-O3EwrAdANi69MI)DlKUY&)0AEvjTf~i6|2{X|5s2rj%s-Hj=N}z!PQMgI! z+FLj3c?S(Nrq#AhFWqzRiHjFc@H(fU?~cK4stAcxXP$)!S&2Ty`sBS$s+!1XTWq)d z$X;sB5RYl^Yo9B}uMCl2xOC0?68QVf^eWy@uGKezDk!?a>#)MaW6qP<8S%P*%P*k_ zO1kMY2&w#iv1mI)<1)+u(wMPVq3zHGB!Nh5FQ4c%x~bG(EWPpX|NIZ$n*os@BTG`@QOq#flMT2pP<-zg}6?xd5Og?LKWJnN{D}$;Cp)3^9 zH~jd54Aq)}jCPlKQAF?#2n>W-(Y2?G$A156boJzsuRVU~)vwMMO`5KKJiatGIW6I} zb8()BeAt0czkBn54%{Wg|K+jy# zbB2JVNG_dOWOG$;Ts#mWFg1({^^Gi6U|ShC*ozsBTm{$R9tp@RMSo0f_%EKL6FmOH zb7R`qmzUI16`kB8BG&LaQri+p{&LI!w9smy69)nTW9;YW4UYuGR6opN9L3Bnz%CzD zFoLgwDbkPsryOlMy!neIj4l0q^I6SL`^b0Xs7ccpn>I-*b-v9$(qg~)mhHva(nr?3 zSAY7=F(Xz@eq_p>jIH=~^S6J)tSZIa+bBPYGkiLe6^zb9?MPNHV%_9D5Wx$fB)b-Y zD-WYgL2O`5bSyurOSks5$c`{nLT1!WK9o`@zJFKF{)(kHx8ZLdwTx5 ziBp{KNRFo0#l@Su_n!4aUETAudiU5epl5Z~m}T1fS7@F|!Y%NRMZ?ZOcIPmG;+E+o zNTjks`tyLHRgr5^j*j5welggUu{w0oR<|_cNeQ^K!AMHCv$n=&itBJ&-p|XznI>Ug zX?=a^@cMe`4g514KPWX_+FxHv*Guc0e&cs>LlB!*$PZ~N)h~EV<1@tJPmrAJjwB|p zC``S;6vd&01_2@K82{;5xFUjR!AD@+Ae%J>EHbqipMu+te6V=V1!Zh=Ww%~MfOEf>6l*{~_OHx|GX zh758Ho3vtiKUOqoXX7o^E10)&r_rZhy4@BTVGlNF^2EyXDLG+* zpQS~GM4J6+EXAg!@*eGW^)v9gaG`+jia7vZ6A>mtM<=z$l~52m2T8CV^hW<)*dd|$HbJkGg&2jdC$)2{)_h9voJrcXVyq-J}dR^nhv!VbUHKSG|LpsGENbI5AgV#=E3%zjScG=Ti>vJ&6?#oX{ou{>FM&G9Sgh{ z?Ao=!yMA{AOqThhM&*0wLmFpIcgXv-#p*}ccZc(t4U<2%L*29)qFWwFj)6`|0(>R( zF;OT9gTzOWujMF!Ny`AlL^n}NC@DYb=Wj8Y>3lMM#$j8|0Md%;0$g!^(_`|8DLYw7 zzpy>G%m40QThEHMM=I0UGUr*)(}@0Ag#HN=9wK^lWN##7Q2OvJxYlHa%&itL#%tdIjOHB ztFAxmaQY6rsyf%NT+!G#eaYs;r0jTR%ZW>4o7wI1p1pHB)a_X~&gvN7y+hX6c$$Bx~k#JHGR3aTB9qu2FbQL-$uOm*na<4*) z38oeYyAX72LD;j1d(iY7Q#-eAYH7xvJH5gNdi041@0)2)mG`lo^NdUG>&7CRzUyg; zUBX^`I^ZAj$k6oSdLw2Y%p2sF!K{;1DB#`H~d2X)X-PJ{=g>;ZE`3kc%a1;Z6@a~ua~MtE(rdmO2Jr>Vi>4@ zqYL(?TY60FHasM(EPHqj+r^4)Dc<5PRx}`N_bPQ;|Agc&skhA2PO^bjk)eS>KusN3 zW!F}UaiGuHK|Zb(gT4+z8t)sM7X}Q`U=Xt?^B-j450K>0KXoMtrho2~BH;kj(`fm1J!_A!=c@X zKzSq)VJwiUO_kA>CRSp?i4dvr6u?dVVQ{B#8og!?`;Hh&t3?NWhcLRZ!V%fQ(&IpJ z@ox3Axmt6cTHoPmCeK|7TQ2dUxoGQp_0v`x;-A~d-8NZg#&Zvi_VOBe;5qrYn4lfY z$zemC@8O**@y^|NXNz6ch-ejZ#TG(TBO$hoK7mw6A`qWcu&ny~`@1z_!UB;@R-3_U zlAJw8l^@>u(2>gVM;_dze!6|T_HXT94?f7km><#a^l^Tq6*aHKSh@5-Iv4|p@R9~Dey8~luEzuF#&Klp5=I$LN^SE4!Xg!c^Ud+Vnb_n zf8jZ71ZF1m=$4V5lGG&*$^D&iLSG>KlGqmvieO{54sIst$}`}CCnOZNw8e)P$>8YP zOww9etJD?ifK-NQplX9k7g~cx4<0u0wuS*i2ku%q?Uvj=RSTAD_xaC^>mM?t(=2Tx zP}yyf@j0HJdrz^HwB!_dPp{1Qfh3f59!x@6w+zTTw}eNHjLBsRNoHNb%(Ec(5M&C* zkpmFKW3^?Nw$TAoel2qG_3IZQ!RKS3!gKLc50B#Tr<@AZ% zZ03djrX41wP0#+NN6@Dh^r|BxH96j9PO>Dm>(eL}<#XdcZINJIeR{1V)JC9<)slzK zH3y9@giyPz9~)Y@qw$toa{EqPzII(hw%wkSWlwv1fIU4fGA;|a(0lS7T?*QE<(_%o z^LI9s<$L!khvbwuvXMG8KFmygDPDaA>+whQWrPqXoZ>y{6&HcojaBABAYx=9O9B@~ z@67^K3uZKH0J|};>DX=wmk%nVWH4|E*Z|Bh$>5&biPt~HR^0rdymY<1)ZnfLyc&BK zMQYysG0bW2Xy80skSGJ~DN<+PgjB6(%D855OK(G8Xw$RKnI*yc&lwp_xx6>eY$j-6+b%W zwYH=OcI%m)(sReS7V=|rLb7|N256_+w4qM=L|dbNgE`toI6-aDS9fp-P9w0GMTO3I zA*cxSv%nPO9MK*526rH95?ip6eOFZ^6?uGcR3i4aZLAYOeh{7oR6MW(gxIJJ7_C1k zT%H#i3GA8}Yv(SJU64osNgGlp@{s8SE503pq3WmQW)McETLwjM0zgxhC`y-jCznBI zIu^$kbn4eNFE_MLV(qeJwf2Hg&vkn$W0N{`?$f=yL;574OI4UPCnF*}itVoVTC~F& z)y?^R-F#NmDde1eWN$B$Oi3o0h`G7J-~nsNYCiHtI&lb@ugERcleXeWStRuza};9P zWGMeQhz&VCt(H6V1{b~KsVF8*!=IKd&kKYK+$l7K(ozxbq7rg*i};O>;L0C#cHZJ( z9&Y0x2M}^roXZyNWNiDqUjue{rl$5zV?FXy?cOt4$4<-T{i|!2Ol^EAE^=_vEPH=1 z&%x6!MfTwB+zdJCxZzE~+r0ukJs@mj7=d?!xB?inxv)fKTSXNu!=3B9g_=FkamEHk%`9f&^WY8%WAyei0Ut8_DQOf$&p6O?H`?qexGWxAow&I~49Ei*{5zTID{%OyipLQEmZ40YGqieJ+Xt3BcAMbC#`$NFb`}0+k1xXkfx>zEF?F)Al zWC()xy|H~eEY#!&ldmX*u#grln+}qqmf|E!u+AVL&T%pjTAkB}@4hm9RaI_0 zQ@!@#aEBA+w#4L^a%IUIVrgY*MXLYMgcy%pZ-ZAapP0g>wy5wp^u;rvwF35!Ah*np zu@O2Lbz?k+391PMYH~e@6{L9;W64omHRnir@*^xT22g{rU6&ooV^H$wzQY&gWiHrz zSHFVj&Jn4qqcS|EqO@CK*gv3G1*gY`MshnD=_e0pv((Q8t8iK8$|S_cVB5y<&*D+V zaGmNC1SbGW9PC=Eq|=4S+(BA@Y-?ed2*@Nz3I|N4*OiV%X`5bJZos?$q&S(w|LV*C z@_Tu@n5V_Ri`gHCy1JA_%FuKhXsw*30iIC@>2WI^&JS3^fZ?+j*4(;khf)$1AKz!< zv{h5*FWby=2kiit8QFST%hV1+#xy%x@N`r zNd^GDiP08xJm%9T)HMzB$y4ab>q^0iPqe3!)f0*t3|Hh1g!H0&YFoU51S{g-;)jJR zID-*8XWBF^j>%4TN^1t+8qWqU9jBeZ8XE(da|d`zC&--l>obS8<&H+CvZx4AQbSBI zT+s1DbV+P`$+d$=lE#a)8SLP2If0^b`h*Eq23#D3D}GFl3V$|st3N1)eLEZ{S6R(r zap7^nfk@jRn{6l7sqMb4+bU_N4zj1ZoOQ^;wxu~>Nov`(^QO*YtbSTj?_lG4oc%8P z_(um!u!i*a$$=P<-7Pg)-oI_0=aL8Ft@+xzd}*$yG$Jl>aiW*k>9p~EJoCV7#ips! z=h(0Jz#RmazTQRw2WhtKzC6F5j?-01Ee2PL%`}lRM~k13LEIiU=d4@SWG3CdY-aRe%TBgK zOz5APm2Xe7CZ?n%#AO@yOsvQ#4NY8KGshHgQT$-W0_Uy>M|^JToaBsXpmIUmz5FP^ za~hS0xve-}a0q>cVL}C53x{~Sc6DaqkxFE^(tx8KBpi@nkOLb4o+t$bdj5qW>(!0u0Q8Ys;jG- zIA<11>ISreF>~isSJ&4icF#<>I$%y+Wp&-0L|pf-V|CS4bLS*E90~HSIddjf&Yj7U z9hu2j4j>M;dScxi{76!*bL*yJLa+!np^T4lVNA3?LOf#4Q6_#SoPoAQ#63%qz)KKlGV_2qX);((OPC~W zutP&b0|G)LLV>3l5E1}}-(#~zYPfuhI zE~xCY#yNo{RBBI(h5gnT7qEuv4)^xE62K;O&>jW|IV;h2T~&Miy}E-mk`3skeK0}i znKsxWd=w4VgSk2G0qXQp=wUpr!Mf)Ooop2Xt@VUf| zb~kY}DLk(oWdKOgB$W`REKPFd=_+oVus`@+??yr3@*QuEyHdI)_e}V zg0zmXmp1Mta}zL+nVT>RmHmWQEh+U(lQ1EpEwOUkD&^_{jC&t82O zZH+=(gM}RatX&sW!8Z#aoZ>xYU?Zf!xMWr8+Mx`lU!#YPP@uRc8Ddev8}%(S5bft% zD9$5V@ZgD*fiVfSMX4j!Y+E^QQL-gV*|9P*Af#(bX2;mdIjN!kop?K%yybn(p6VBZ zg;nZvLOOZD(TD7dP6RKo73dbpiJ>98QUA5{!0 z0f_#kXGy}!(4Q6HeZ?u;|HZ>}21xF;4}%KYYRK+WCdfoKAwa0`v6OS7j2_I0-)I1x z3<{%dUh5k?RZmp!dIP{CJn2znpc@3wKX?U~xe(b0#$rK6WoN=7^*6f!N%?FI)DQN8 zNR5d~Cwr0QH!}ksEXX}J61|%aP4!(pYy6#?*)VX%O`DYD^u+khY{lf6t2<2HseW{> zvf-AogL)^9OU_S^nK%dW2@~P@M4ipeO=d;Z&Z>U!UH@>EhtVPaGft{uTjjUmNB^ez zlG0y~7ghSV#1j|EpW>LvH0*sYnT@0;OuibdKZ(oZ64o7tv>0{ZSU9tV!*fw)dvrvJl^#G-}~KOWl#_GpT}0XY*?7J+}BP1HASLC zHbVL00}_>yZl*=V5h~e8?RVypm{D2lBY%4E;OZWENROqXO;9kNg z2>80bqFh-CLR}QUMe`5cNF}kOz<-Nwt-$f+tGG|et>V13!G8Bix3Ea^cK)YjEj8Bt#JX|4NJ7Ob{V0f zT;F9xUYl-XOZUtMfqLH&f$sj3f?YIDZlzIA&A4W+VdaAi>Oix*12JTXPlkOJu4%pu zTYE5|LkGkP_;moOu3q%GVJ}iTK}#<#j{I$Qn@-eTbd9l;;G(g%9gWxbBhjdLq}kn( z3OW*2J&*Lm-YmtE0|hwAnaX%@T!u`9SY|&q#Yx0IV1}H z@OIOL*eGI8y1WMlMILr&No^K8yO1}gUsPn2xKElnCcnI|B}d&O&e4v52UKQ&2dL{( zQ|xhbm!+hPsb8)YwJ?OgLcf9NHwYe{29FxSQ&m07ae%K1`c+T0I0*DdMMeO;JP;u_ z{{{V0`;~q}`seZGpI%k#a}E71yg*_``Lg_!!4tzzu~RNTx-J}&utK{x6Uz*_r!LxXnE6-4XM_pzr&51IZ_Je_A>k&og?bylKWsqdbcnlJ;qBoi zsRp$e2Lq$8<6_MTmW1$5fl)zG?R(qj4`)l8mb7h^IOUpo1N{v1CL?F$$Q=B!#neiC zQA?7NQetN;OiC=9xky_xA}eb|+dp)4ocuj2LtaCxZ4;f(V^Vc%5MABbO}AAgrF0qd3W)Lpv@S<{dcjSnVNz@S4b zuGj}q2_`@9V4q;PB%uMe$@tJkG3c&sThDg!c9xZ)oqB`i-_a}@MQR@ZL@mN{`A2pd z`8YVwj<0aoa;b7sJt{E2P&1v^LN!uCHlImt`kTe}nJ}SGpNb0k$5DBCqv#Kh^p<~- zrlP+*1T%l?=c9ogGVrK2iI{6m^i_^{;T>EkdT$Q6O^8xT zYY)I}uIIzrDbexq%I%{csVEpwadh-{`NFWZWx1uLxn*nNXA-L9gW_uS2w%b7d2jsB z^LpkME*>~=ap55PcTifterfoV5B8fgpnqN8zIFWv%;|RruJ!GU>zHyFpK8p_4>3Mo zLO-Ht&{4v0q%098%*2#L06w%bSLjJt9);Av&~VN5@)KrD>mXVkncPkiq#9V=@xflf zyLQc}60vSp2W=a4YdYTiDqAH5NM{A3(3$swNmWFF1Ljf^nNcu`?#{(TR(T?6h7^!C zJpJz2MCt6QzIU%kD$3tF;WeW2fA}sfR{ExSj`A}!br)SQVYku+3!a-UiIW9fxiy`O z3O7YW`zb$^FVHNjxa~fokA;^SaKDeLr+I8>aCHOP{_UoRGvVs8X zigPHaySp%tMGPHY5NPwuiLvUp| zA$I_gVy?U+w;O@SvFUf(#lyS(3CLF=qi>U!c*jz z79yuy8ps!u9`D%+Nv@p3K*J-uEIuSw!40#p{6t{2gz^#sr8Qk&pfd{m(JTJoX$sEw zV?w7;KVRbIQZ@OVO z^n{?v%`9LF+?j(2a>{uiyj3!97!W6-8j6z=05qc~L>k?Z8*LII4LYHu%ro5%%dOV# zG!e33Yds&%uI-yQd`PCn&W^C`nqH3bGJCXLTQ#b1(73U{ml-{%aO~K^fn(G&UIhyZ zx^_)X@*1#kV3#f_+Vmd7inD+uBW~$YT+}nWh*G8y5A(bHaWhk22KPvG$9`jjBoVZ= zCAGj_Gts@* zb_L$}vR3lQs!9372WMK+k01}!F|sT@+U~k!wYx7_)76(f$J`bj9cS~%nv@eA9sj=m zGuETWq#Ua?9_?XQcR0^B_ibJPO^$2Xk5j%5ci<9mV`mZuko<=hDhln1io*9qWdbsJ z6iUL=r3JcATVwm%Kx=^8$Irhdot0T_aH7K&8Ek+_(rMc9;fFi!VPD^K|Jk$mZ`OjG zXWu=uVZ)hs?*d&-JDumWs^(*uEfIX)_)}64)OiCXObK&4GIxwR4qD7`1P9ujudLen z#rYk`S@vGD@zkk}ccK{VGu`FSn+F))L2h@#)jPy(I?olixp}TLM4suqr2LBZcj5I= zp3b$l4C1}TfY<8S66d0FkDh*-w%vJY%;Lpk5;HOqH2H z`PN4W6(-Qz2OTxhZivYOXSXm5uXX8=?E#js8@h_f4L2)8N0&yEGor=O=nBx*Jq?We z6!frt?b8o>4H?|$9rog$2VQXg%Ek;FG={NJg9naLUdR|SG`(^Ee(i0-OzKfW1}E0E z-+4(}jy%woTsK(KTXNl;el^RMOf{VU9xQIZ4EUI%cm^o{k;w2_6%~w z4aROw*!B3eb+~q%U+dmv(yv`T<2)xs;+oCa{VJSWDDQC6PKWx1OvLLJa9Qy$*vIH- zpMVzUqA5f7QMpev&m=jJ%Z2hmF8$r1OM*lfWd08!^F#GAZWO-OXGZhad}gqwEzZxh zNzEtVx3KVe5llxLxWQSx1#WW=Y?*}AJvO^R&jvI!ou0Wb@&TVIUOPHJIIVcXcrD_t zq{?1TJdaSX8bEoDgN+|{4Ol^I;NcTR8L_UE z5e6fhEV==>S~Fkt!PZUky6cYT!o=vJIk(U&ZN39d@3zW}@~F<`8CAEfsLU7{896GW zYB_s5D=jT2CoL^Yd$31(S{8m~Y3GN}kBy3oT~JywHwGKP+>-db+%5_E`3doPIb9R; z@@T&7l6PoR)g_P{TGkMRIT8rqPLSxN3Bq<@2rehTggc3TGc8=ndNk$eq?pU*MbcXr8n1=WE?fYP<<=wHdeS z!<8h@6!i9oFQ6=a+_}78mx09$7rSUhPP+}-lBVCIp!j^aTv2W`ki>{UCWXW_w9dwarAqM$5_IJ zuUNuSd6IclpFX3^Blk_6x(`*Mt|x%`w+efahfq#+ouKdniY210$n7%Yq7$0!QqCqI zzJXyQa{0r+Jlbez`c0QRtc5tj46@l3vGj|NuH2&Bb?yshcYe5O$;P)iPdFfdYBZ>s z0>=`OFVUxXSpQT;%9jXR#6!mKXu{=_FJbIBwg~@%b9ePClIsiPDH<;=6s-p;(WU(jvfW1!hE`g)p)R-#!5`vY3}^P0mj zx_Q0cW^JI}W^JJUJbv@%wSlg->R;##cDh2mEKOeCJYA)kPxd*U%dhWrVdwx!ESGVj z7|-oT>M{JD6}YBb>nZ;cC)~q)%gf*mu;jHC;fD!#3JLIU$xJi2cYTwU8QKVaF}e$# z^FC+o8~@S1yfnJ7a5QiPM~j!R;T4V^O+ucaon{$7XO|4i0xIB+oTB3Fo*rPWQ?hHY}@0aq<1x#YH(ihZbS|yzYEY>(TtUkmlx3X(2%R zz*Yq|LVSZk%@9~|N)jL{bx*6p_l)3x4q{*c5VZIwg#$Sdr9rVCHXgbJXRq$&H8j1R zI4iAB3G33WOJdJN{C`H^%sW|uIj)nxx$mIpz|O&5)?S^LgogD@43FyQjl<7;I&}gb znx}`qcZIQ6VpNCy|g~^~k3jGK;oxw_sBUt-t zf|jrSRCz?r+TFBuR|S>5`l5VV`vqgwqTdmN2ge?kqDu5_fBAItuO+{}HEpCOwFi!(5&f@lTL5bpXf`w%UKbr&{c>vJ z{X6Jf!_|-0u*$KO%=1m{y+!leRl=@ZlFta< z$`x=TcT5A;BWc-igW!+cM68mu?Ghf!<4)x?nYqN|N&?C-dpqYR?5y7V;ybMO(4o0f zoKlk4`@zQaq9WMvuDmI~*?a+YbPzK6o(MEi$nm@m^cGe>ylF6OfghH*&8FD0JFpHd z>b7dbCe&g$)t0|K!MRwn_8B}h@52}6Gi=3vs;Tio%!51Stx}Zo1NKBKuPa1XgBb7% zXiUg31eg=Ian7U!8e$Y%Mod@n*XNwGowJ`7FDXC#6g1?+4~K;Qo95L7SW(bOAlXD#m;oibY3L4B;-eIk*oLRr^v^D7?M7Rf`6Pr>b2h4F_R+|f`C zA>~n0CX$flo0LTqEgFS_HRvl@Fx;dZ3_ih3i0X`B`(WBdY3>NoEV?CpG0g!UPr8z> zDT3XTTORSpZr=tXRh?J5vFNTzqk1w{Ika$Cu#YvMhb^*r@|1#t(g0tp{O^2of>f7K zmN$IL&=KjKyPG?+#gj)2t0*4WEk^H;!SWLAgkgbT5qj}C=ZM6JM`3-4g&loiWu_ql zXS-4OKokIF5cO^|4Hf#NZn`dpW&hnoh*tcQ&q_KT+2V|JW`N6)Av1^o`;W^rI z!rzG2lkhi55MErFPJlLW0d`Ox#1f>?GURN#p)p7q;2xt&eBmkE6xag{g=?OX6~dS2 z!3k{=OI!~jn~IlLf$rh1c(TUx9m9w}gwXbR0uz(UU0ye_<+gd4)c1zuyX{iG{ zc`xXel+vwFc!Ydh3e?VbyKjkc-cDw-WX)kC^NhVmWxtY*HZMdT{|dDo{sS_MB%I?! zQP-|8GRy!B8zMXuY~m1d6^{R)xbYucXAxeD|6rySNLE+?nHSMWdYD_$S56^GJ#Vl28mC z2;DAI+6uEjQa`CdBw3P$Gf;~i@j!Vwt4FlCpJ)v7iA|uK=>hDCx%LSYT_NW#Uiui? zF$nXkt1ynYV;I<;5^s(mw^5W46bGBUko7E4(i*_a5qJg`*MN2)Is}J7B7OyH4e4K$ zC`efuWf%z;(xfRg*c57Nv7d2Ut1S>aoBj<+Ai6acSO6KV-!PLholQftlMQOePW)q+ zDYPUfP4#en?D7j$|1UJDKO4ZJ0)vwVux5cJ!~_H;7q9|LP)OoHoFn`xGh-elNf)#` zFpvC%NFj^2E)^bKsJwoNN<@EhJs*+_u90vdlKd{RVv~QT5dTP1WDL$lbp^xh5#YD#M8wXR|Ly7kNAW0t&;1K8EHTx5mHNq-+y5A2NH^Su}BFydUx z5xu-~$M7Uj)Gjt1l%CU0sOPbm!i6pR+NP*K0C&g&FdGyE_@RFhhEG?dHdhdZPX!|h zm;pbXLt>iF++NvjdGO$R1h4C zH4XCzp@ul$ci}axF}C70sOMdH4cd7r@H)JPL(<>)x@kc$fe}Io^2GiWh$Rkj0*i|) zf#6L%)J?1)GGUX81v0D)tHG}0xajje5E*CqIR)iF-hKgZujaj+23!eoOIez&LK;} zg9x)EtDpEH5HS*f<4jdY%6qqTiJuu|r@L@R(@6OLSmbRn1V z*6Zn+#$4uQ1bg)oG4)(O6#T%fqikdc)(yjH?g9!Ky*Or(QJC(5P$nb>;9vuit90}t zqmggd#tOm6jFgs4{?5$n9~V~qrKc%Jg;$QjX=qdXUwS+*o9cBvsTjSK25cNg7Yx#$ zS5Lk@|LmT?7)*uJOb144aW3hq4fsQwRDG-(4vd7%F4}7N6m4sPV8p2T*5h!#A6)1t zo^;#tenXI2KDBx!^YGqjOk}C?@o8!C@u}K(X|Y{WQ@hwwSw_F~G+XEBZeH?*PCO;L z1w_f#D=JvL-;$JQjZRFAc7XBBT5TxoJA~)U_CI!VV%lg+Y9_=fUg^J2+Sf z2}%zzWg9ju zYgoIsAv-NCJJ+5*%^qhVN!yo$I>)42xl7G7Q5o48y8nSPa83S{jDYFj-8YrN#WIrj}GwE2~yb zsa8}Hwf8%fYQ0lYDwVWKrCOz;-MjDa^IZ3R&q(F{{(L^)&*S&|@_6oC*Ez5AdY$WB z=eq9m|N5`>D_0z7pZ8wrL;F{Bvig<3`a*So$~~;Zl%d1uSAJ;TJgZ;Xa0S%<d^~C7aI#d0srJmWr@LxG_pV(!b?jgb*q%0K z>)jg5daHYzPx|LpZ2NPrs-`hscf%Q*t|WWYRf#JJoiNC(F5>yzO4|IIB{< z--t=^<*iZEr1pKeg*}uV^n&t{!=E;g=mI-O0NO@c%H zTS2RSo%B+gmi}GZYnrIL+;fc5U))u%+!NNi^kw&v+V}5FOS|Lg)<=9FMT)j6sIvK%;ESZSnGd@^9<|!+YTrY z=J=b@W&wrAzh5g4@j0x~*83l}Z)!%@j#Ax!_`xiwoyGN|Zx#BwqVH6{i2iA}`bBg_ zL-!<~+5z_Tei3F1>P=vqnqA#%^!JO6K|i>kGz;8Mp_2KOpO`-~?x5#Www65a$BRP6 z#*PNOO)q!y5pm2jps1Aol99Lb;q2jQ`r8j}>!RvMr*2xNrH9Fp{QR^I4b_t~LtBTk zxWE1sP2Jl-tNrZLGxhB2KTOed=jZ;o!}dx2>8JWwEk8Bp;hRgvGjO)KR5Y$_?-?VU zZLKj0zC59~&15+`Dc3^`v<3`w26fD7hW?^Woj<=Y{z@Gp)av+A)%!5k+kw$R&$+dN zwcZ68BWic64hh~Fpw70NH`nf{n+1C6UU<{eTCVfm3x*23sR^(-wcQzd3bRg-?_QiW zJWVIKZCwyibc(%`pDjH)(U-=b{}=m5>eM%{m-_m%WzBnPcMm^v!mM>g6=&Xz{|}Wh zHqtsv8N2@3A9MerjOo^|y{S3CnQoP#*20dW!o!BYWz76kyGaFMOJe@;(iJDw3wZN!7l-0wNOMnlNF`w6xjG3HtriBBWsh z5%0YEpvDb?8wS&L&PN*>(u&qwp@q;k`O_yu{hqhtNbRe&Yya?cWE2%SnX+wn)-FHu z8PV$l923kRt>34gC@|LVlUeWg$rrwX-!JCD|7p1XePfT1KZg6?bIhx^e!uG3)7|}l zu;(vB$p2`SsacK&#yaOu*6&1b`W}6?Y`u7j`lWtR`oFbswwd?!U+cPFZA~?y*`Tgk zzG>6)Wt%oF>pN^{Our#R9SzoJUcP?)<(cdA2lwe6AK$x={!&6zL#MA{#$jea`)Zt@gC-nIlgf@Pd?$B zv+;z#9$WK?`wmaAr%=upzAF~Ok1G`{Z)qkCeAmHRzF?;`+ZA8VW5O0www#VO-R=H) z^S;%H-aZ1WrB?Gv_OO`Pp^MbO3t|#-)@8&_Y1b}oK*p-WkV|i!r1SGCcSEzk zXC&pv*}mD?L1R=6K>cUHOX{I}mG zzYSLiW6vKuPFi#N=8Y~7)=f8kr>!kb?DS&MEk>h4KRi~`jjk0An=~P9 z^q5q3khZ;1mfv^WxW3mvszN9AA2>GoqBsWDn1l4Id!VPSCyV^tP_ymKIq0-4J~9ux zdpkn;vUxvODp$<2SZg=Gc29I%!0Ln+@z#2UQ9NDN(4$_jpi@WP&f4%VB&62vTdVN( zEB>_#uVVM~byE7=J=FZsGn;f!j!%x#_mw%{-Wesj+}uaKd#JbGZ9RwY@Ek6-p2Kfl zz5nn=x=Asdhi>PLmrf{d|{LcM|Aty`x{ZG)@&Q>h7GdFsJTA z@7xJpv7?>u?YLpXEXU^ZPi7AZ?iA8ts5|YsM^%)2e{#HGdxM@ORokKVCwH7@C*#;$ zN4-5!y}!j=f*#B=W^zf!gb43-*uA>-_v3Y!LT!hqL&K>!^k_Hsis9~G+O#vTq7j|p z@zjoH478!68|COi*C)CdQMMk#uM|H$k3SwSJ&&ImaXPGaBy;=&JkRO5{jNhNZ}Ghc z^xS?coNq8KF+TV7r(?>%AE+-v{T zGu&BZ{Z^2x)a1A<#+|LYKhKNxgF)uYAHFY0`_$B1*1%3zs#)erbu8VqNre{`>2x=D zht+=Wd6aa=xn4f`sxRHI)}_0DZMhoh*+w}pC*ABzrRQRuboj$vSJl4jzT5L2;kUb* zpX{o`c@Dbz(yeN$-FJHOJ-1ThyCA+lW7~Wn#cnw1fj(n>05wr-YnK*`g0WvGOX*p^ z6RKKTFAwj&L)OkBEp_LF_w5}LTwA+FT{m#p+S_uLj~uyt@y4|Yae3}La|aDtv~JX> zb&CcKTCVhc>#oY&M~r95+wW`gT@QJ$!SztxHAK0S+@E_cv%*)O<=zy#S9#`p=2`cq z*fY-?-!sp5jYdr|IXK+&*njojOg0~JO?Kb={PU{G&Yj#!*B0A1?9;yIPv$X)WaZ~C zT$Mj>)vB!3wqx`1R?T0vGAnQ8{FM|qgSC!t7{i=7q^XJiWogM9B^Yl?jkS3?wF|^1 z>l$_|zqj?m@z!2+sbV*?_{L}Ks!kvVZ$d(yf|T!p3CBX!)O;b zcHBjAW5(!oWZ1qmZ*oqcrW!1KHNabK);rzO$uD#>E0xbcGWA_*g4R?5n>k)rbL&@d zo!$zrcO_u`#)z8BszAH@(=XkJ)dpR$9mq0J=K~Ko-CwHnofnVk-+zpTG9Vd_DdtT9 zd{4GfIM;bbKMUES*Y`c-e39JJU)f~;9AWV|JsBp`e;IhAr;V>1F!|zA9JcJ{XOV3K zLxO`?deypBaJ!IpLCu5MYS#N1FJF&={*kl#(&(Ocu&s-ejS%ZqG3zb&dw9d|l^JJU z@@EWx>n(Re{dIq&)qcXbKj0wcLeEz`$Fw#L3Z!?#yQny@NgzF2-sPYTe80~AyZXm; z`l`YoZ20}n>Avc){lty4XWwwc?AbROO-Wz&py=p98p;%Tc?<2lCC=$qODRegdmBmZ zY3Et%giR+~J6WsF|Ipa`8yTy;*YR%`8UI3aOk92dw3-2;KAC2)BAbwZvw6G(` z3>rLo^x(nFz`O0!H=HwjCtMuO;?>uABkR1GYJ1acLSKM>-U_@US5_5Mk96npeOzxh zAA-J$sD9$8E%+J%boA9pSOK%Co+|5gb}m|I6|~e(uJ@TewJ=!kBc{6y>Z+>xxz#;< z^%n-ep!*2koWSDXi4zB3QZP~7`t}4W1jCE&;5yzaq)U*NbhCn;%T=z8F&bAG~&Vn`0mT8D`G22Zj%10 zVTbnNZNttFW&iD+N}*X>Md$7(tW!h_!hPw z@ZWoF@7n(!d%C-?p1o?_&v#aP^DTS9GMkkK`trP!*6B}R7k$Q$`HA8?n%-;GU)#`= zcx*HDbQo*@Kub#h0{^)fi?rHzU^gObkyc%XbgJLNsFzUH=kEAMEei@}rmBcj30@Sk zdT4qtt4!%Uns3zw+Q^9b1phsuhotVFIBlkrpI8TV0tf9-r_-EiXYzv6oY1fV-SQMC zz5PgoHVxa5s)oFF>QXh}tc9pv@@^WOHliIper!MD?eTNyGUU(LPptBj+q35-*|}5@ zWV7vF_Bd+8ui0Pq>(H6bj;rS8FZ&^Wo%?z&liz`4$7*vxz<&A+s{M71`h8};KCHI< zPIR{9ce}S5(>$M3zx+mmPgeNq*cJXdw5%|Ds*i0Kl9qG$cCFcQg_>R(YP(Rct}ygx zhT2L0_obsnqbFGE9xMMRbow&yLA6Kc1EHnv`?O+pp8ID@Ib%QOVf6uR z?MBks>b*K^{}-QZ2r>Q39(o#GSUuU+XsLpmT@ceSz-8LncMdcU_b7gG`uGX6c5mvT z^L~x_tvX<}*X!*ua9W$4mxx|=+Wb_zeND`yJ{u!?o8RskaoftC$%8k}d6}ERHxc=s z+z4k7zrgdYF>5`^O+P8Es1S$i=bpI~i;&dY8qx1TsMYxOey@X`S)T~+?>~|8F6$4K z&`#}J)_v{7_hU#a)B0>g-DD=`rfnOxJ)^E#@_AC~aHV=qi0^B&|Gc{Bo$Wi;ztH{z zb!}G4bLmS5cf}ZKFY=|mmGAqKd_KD_?d=fY(PkT31Z{dz2Q!Xz(#`3N0-5v{g?lCR zuj$!EE`2t#X{Qc#bBC30$7(%m!uR<+-^b3(5%1Yz22Jdln40uOPL3LRZ{Dp>+kfsp zaM|?dQnK8uK4|~K`W*|)FW;og{!5hQ467`ED;>^KmKWHTs3_XdrhknGSx!Rhf0JG3 zbiFlbiiuGw>P1I4_h|LB^}PILTbgV2eINP1vL;rwopjALlOlTcim**q3of~I(b8TK z9iq5C|JqK6ZVzK?LG4i$Mf>*LugC7ao`vp9)D~2*CR^`w{U!60+DY9EV+H|uq3d@y zKdEdv$M#4}Lsho9+RL2IZ#;7x&2b&tw`)tAtXcCARwg#`Z|lj|`?|EZwqmxnH)M;r zetI^H-t2DxCu%^)ns%Gjh&zm7cT8PyZ_j?t&1SEddz;;|*;sth)s7E;_~FL}vlpbL zUC?XKp00z_(&D1_sDaCPYxFWx%ucKybkgI(*W3g7HPr*+Hd(C)=kR|7$dtP=^%ZSG3wKG$U6}2m` zzWRr_yrDy`CvQVN|FE&a19|IPQ`54GYPofzt?S0Yv+du^vGPCC*lPS{c1Gr}-qZAf z=#Py@8gCg}moo&;JH{w7Cz*OrrgMn5hImC+(j%)RU#(OZ*~SyEB@JpkR{JLdSY=il zqW>!YS+&x5tG2hkzkGw#U19W)@2TLm(<{#D%w=0+ZwtJ==)EhL^vQRuouT9qdrX*_ z857jDC)^b({`=Z@h~J09=guv@-lM`?H(9Mc&mW!mc^p3}@qcrzY+l*iY;WeDP~Bv0v27V=r#f;-Z$T=JM0(_@_I$@y9m%9kKg=dZp6JC+~G`Av;>>?oVs? zXKU%L(ca)Ahe4)O|K95jLDekxq4U(*$)xjZ{SYbnN!?@qY*f(Jvicl#eTV_@q(*mQOGdPvsP4HqZE8fvZbJvo zx-5c59<$^<@7V6J6_B^}%INcR&5!2xOtVc(v(iRJ+A?j^coN#jx781D2c2tXI;|)& zTo(Y}#0aiWf7@99&r?yVP(|6MxeCqfn)~&8j~*s5a&6O$&IVH?=&_sc>Ec;LZGp{0 zJd3Q_f|9L9AGMaM9(%CFhyCTd)q1b4{m6c)>jSfkmCi9LMSWm@*4v-TKHN-d{nLJ7 zUwf5A!v)+U3&${;AS=?xwVT&7#dfuJmJ>NOXY+2IT=%~}* zaEvY1^9bo@EvDxYU;5)cH`~I^B4&N)(LAfLNgh|j-Q-7(SBrPwof-Tt3y-0mw9TGw zY^cMHw6h7lzk{V?Ofx-;iKf1-qsp1T^p;zeF2DKCFFv{R*TUP}HCq;`Caba+uD;=_ zUsapc-)!3S)k=yRCCLb6t&;9Di;C~62M%OZ`QEQa)SAL}J*EH$JvCsg!p-oAPL z-i7B{uzKhIv9o549h;G1Giz#X#nY^fIz~^^Wo9i;{AlYv$|sn0!!>-29&1U*3hx76 zme%IC?Y#w|y?t~|oa$}NP<`z0)O5EUK#H`UYCpG@m%MGwNUHXr(l=9>k!Puaaq@7z`g(+q;$$E>!4cW+h3 zw^v!ujBg)N&hzWe*}IeT)&6t6PbTMU>dx7dl5}%x z(QtjhufCq`U#(~H^tIp2hO1lmO#$>i4NM*3fut|SM#F)}#%$`JUNnG4tezh7?z2B$ zTW__uk_TF-?+r;RHa3*b0nW0NXQ#|!})hR!!`mD`s#Ija4WUzTV zGPw1pZ>2S4Ny+FqH6VE+s|kaKbXx8nzj*errBOkhQeymDX_0-N&)wtAxyDh-XZQHX zP%O2w(o<)1hA$mV-VY9JBz)6S8?@#<4YJceWi&SHw(t68$%fPok3YWQ(n)Ezm2Q|i zGNf}e-yU8`b07en@jBqVvswx(gm; z!+v91oq3hG|ZvS{mcF@+zYlf8$Cp|NlqEbz0g@Qd11!z#XW;Mjq5kEaRX~xGyOj9P1y)iZ73U^ z;yX|-sChSW8hR@=sy6!fn)0CdysUp0HSZHYpp#y8&V*zJu~qDn4I?g4)7xcEOzhmn zclE=U5Bp_aS$@o@mX;;u>583}Mz?=6&%O8jj69ECvf+{&@4E4l4I>s_n>{>H-|+}5 z%f~I4l$!I%iuDyMQicrg?Jsfqeor>e*ljcZc&`8@1GbuRQ&G*EW9c=n+%a zUVha*8N&t)?OS(kuIufFC(f~)dgE~K9Ez6K^Gto6hgWx8`xkb!rdml+=S_J=K>c;? z4rWvJ)0@4yt~Z{qu)pzyd);g3VBPeGYNzKHV=?cpzpPvN23#Bc{)Mslx#uWfYm8fH zYYhAQcb;ye=(ff!+qaWM*L}4$?sU)N#B)lo_$X=(bO5kw(CVh}&IzDSVyLqX`6}v= zDx_~e*L~_m_klZVYt%OP7}cS$knzy_YF+O2o(HIb^<-}OOz&I2cBa3-$+e=^?Y_$M z0#;A;{__;@M#6Mm?>|}MtG4P{2mM$O&L`t*pLV~d2K=Mez3!*)H`nvSz=lSp2@((>zs@AP4);zV2bieKH$lgpZlWykZ*WTbu z_YMAZ*V=4T-FC-)%#+vY#tJu^IwLJ*y>8m1m4Yo@XAF^$rlC#kR=TYkqxB2!-407v z8Eb8QT6c;loZB(HV?=>%YGKD_t;bC1IbmR7yXGB|CPya?MF;x(7^}=pB>t~|%XA+h z_qC6Cxv{E}h7LJt^fboWGKuGFGc;v%-WY52{6bCoLWirD%w*g4df`n~Q!`n;qyp5} z?vs}7_LQk%=Dl2st|!ycYtyr6iEQoZY?GM=ljZsDvK|$v+psxAh4@DWPU~;CHWD%> zjLICxhvbbH&HVYJ=8WyqCBocot~G9n>D#~ibvMTJ?cMu2y(yWJ2Uz0&vg1xRQD8oe z-Wss3Z;ovh^iqD^FQ;FNAt4WpkGs81U)x(ZUU^^C@Tk=jb$6tdZ|UcrZ#}Jiqb}py z7oNJzN-G`IJY?w5Msc;%o5cOX_eAj&`F!feK0bH($!)b0gC7a_N@t5M4VD0ZofYn8 zl!Ba-+kQDoxaEE7Porh_c$H|Qf5(1OdjBuemAcY+M?V?sERoU9m*ElEE2AA>fJ;W7 zN}uORee8&rg{S;DKgak1J*9Vj?4xDvX>rkC_!R+C0GZ41-J<1M_9HZ7pn;(O!KXkGa}&mp6_# z9p*k6^`GJSw0=B0cI?IENkixb!O(|$KNjYYHlH1P3r~i9jU@TcZI4NUhQ07D*E;?O z_uwozTcWEaVQ+cEZEMKSKj3lI`LXuh_O1jwp5*@I{56hNl!J4^v+Z2u0us>IjdEI_ zfoGi85Bu*v*0#>XXTv#_vOS&qlS4WFj56)OJ%-zW{O#s`MyFZJoR)T9+<*w)S-r@A zKNrh-$2Q(eoI7~#9Rsi%jm!{a&V@v|$-1XArI~%8O!~Lkhn-6(dw<1VnQNb{-a1X@ zBjOzd?fy@qZJdFlspq%)zb^q}_}%yu>_?@qAM&-YW4!PD1Ado=OMg4=-|~_))iTZ} zcvoqc-@pc`a2fag7V^%g!?Do4(Jy09mh5w4id<=XkZ1RQm%RG+or#iAAA2Ji|G!8c zwiV>@1t)!c8n&lpyu~j**MEK%_iWeT7){-#!P&2`!DboH@6~wi26XVs*!E!Oe~&R{ z8~K;nOM;E}`2G3;_fA}n`L;(MI}PL!9%s48IA=((y)o(5}|rK%Zkrr|EmpHrD8K^HXWS?(%KeXZeisv?mXLFcelN2kg&zUH|!i;@WSf?%~6Ve-}D$m!;>5eG2<;Z=pQ>NL_~dr9DrswAyP0 zlI83~9kdH|$|1OOsIO`+r_P#7orQK~gC@Agahu`xgyDpVXVu@yXnnkQrrWn7pH6)U z*Z#Q-viG1ZL0W9T(q8xpeFf4t-~e^4Zp;Ml3C2(=wb^X_djsVQ1UeI?-IYU*6$O))85}Heycohz@~a`8ON1`55?UL{C;@`!cHi)U&Zxa zE#vHMB;xdUv1gxc8~NUk>j~k#^T+4^PoMd}l6A~NCu91QjXa0W&;LQ}@iL8jI^K2< zzX|*fc=4RHk7Ta;H`2}7gLg$28C7?W9^rnSgzqTJ%^;oYKH$aPm}lfV(hRl}g!O@~ z-eY~v?{l8cC&vKnrJ(mK>1H47^M4E30FH4TpHWvhpW_|)EkHg8w=?A)oa-gRIh(Mj zWvrtbce8}ss4F`2Ex+-OXUMy9;;<@4KO^jM-A=b1t-5rfw6%xHG;^CI+SzHx{)0@l zFP95#8#qsuq<}U&XV1xGN2Ux47|(NytkoX-TAp$=kq){K%Ib5|eRKPOwq>Jo?$6h< zf;#C&M@z|Xkij$ELT| zT0UJC==581-w+O*r@@nu2h(9FTnU%Kdbreg?3YX7T+6J`7@Z{+GV2j*hRee+1KRl9 z_kHeJ{q0d|h!-hBXMIXJ*W3MvJPW(wQJ<^B?}0nvKZ*0c z`4+)8;Ko)6#v`)OxRZGik5fipk#x#KI@g_H@doeWH<7y+W>elj!1bLQDRL8x zggarj`I2lj_sH$IoBscB4eAMZws`@cG8-tvnBAFdoG*iU?naoc=r0b3-rOrqm}GLE zKszJBcv&u>?UCR=XWr@}^L)u-{@vB;E6IW$%#B+M(_uc`{C~p+&ug;tJV_2{M&HvQ z+(t6Ou?N32>V1Pb50nw?i8UJkBxel%-%6%45qALm3z_dF)A5yDpu-w0M?PG3Hfk$7 z8;8kG=VQ_J@!XnZ5bj4&C(YfNu>u?6n)QG)xhmKSjyR9`UEs2R#TnR%Ez zTl!nvqThx39mud+^B_55k_fb)KNz2Q!I zJtRk7_a8g&XQK8_c0b5rKQ`a7W0?F7hkg96TIgUQYT*&FjW>gH_JjeV4dSvcOE10{`VGc#hC35yor7~bPalsxU_h~3&p%#G>f12y}|9{2R*Z=<@)_5ypsrvcU<7Rqn%Nn=Qb!l%u z;v(Ii((MA>kEHvJtiB!kZFt0&@D5nx;||*`a-+srdkX)#cI%IMoObLVC)f3D-}v^~ z#)_?aIpe5SAAvQVN9~c?J4JeU9ImK{j$0A>28Ooy~nz5+S~uE@2{^f_!|6<`}=NnJd3mSZTk9Kby_G7 znrk(>T$~Age4qRK0qb=7b=PxsKbsX!e?$E~Ez;-hzw-52S$#~t{w04Noau6nEA)5* zbt_+gHEsL~uD^nOpv?YNdtCR;S>eoQ(B(?^zvzA--Hx-$5#>ks*;svE^zrEa9DV<| z4`Xy2x~~1K^Nn_^)yCCrTKbsiU)b)q&G9IB#(%C|o}s7CgnIl_#{Ke`ZtwWRsMmYt zI#Z`S6Li@3sW3m(Ls^%n!gx;C`(V|BSWsUG<9B{Nb%rqNy{+|_i$2$ObbKp(zH~9a zrk)D6Uzxt@r4_EmdtQSJ)Hh~os2e<>IfwU(b$|4I*X8Jp_sV+e8#mIXt3#jr(f;;9 zvbGU(0eFUj$&+g=SKpsWG6&nU?AOtz(d5ye!QaZH9+f`*8zdne;bI!av=aB+uKsNIu^xA8Oyp`@#GC0S^A|>A{6W7QX+Kg5oo_(_APNQ#ht|N=xYw#_E91^W{|Ewic51ye?EaWJdW@gm2QWP$SzS)xJD zO5NwfxN#n7e^@to|MPacGlV zt=ry4y1ZwG%QoH>k2QFgHspJ({{dt-xCr-8DFb^3!Fc2Pnt?zgJs0uAakw0U-~`yR{S)pAH^TvH&(6tNA-K( zdOqosC2#WTKd;tv>U&15ckm17!Cw8ouex^xINq_~v9=`qbeL}2rb@1JzD%XR;%a?v?x!qJ_INhN>g)3Lg+621 z_Vrgf=wCFZNQs7fm!|Vi&qs3XCLd$H_W`$e!>grt;4}P=(f_XV4!3W^Inr0x53Ku0 zn)UCiF;ub`k6h$f2`4DOYo!f&*NVAP?HY|GANS$6St4+|1=L74-p$tU7v(Ei|JK;Q zl-qc(KIY62<`dI~=tP_CE6Q;g?~qxPuXkjeqf!R&PO|zj%vx#hSjPIS7i5d}*Zl^L z*QB@YZe^n{?i%f9-z9rV=lAA)a*M@V(v)kR#4}xBOy(VuDob=;InJY>;1hm--;;T^ zEO|nskIl9`SE2ldd`X*qW&>qKh% z;Vyw2VKwA>k83_4j3$vpa?aMuF7mXN`RX;_!RPQUyo^5!s4TRO*>DGP?A+|y5AEPt z&@#(_9hEITe2T-h5oiUv=Cg~{HeeR5s|)lX{!Ga6+HeKp*IuVX9gt){N<(E+Oo7k`Q2)Wj+HRX$5h-|kU`ihUfi8IKL$epxtdD21pAGE zz3W_e0oPUYA$$fW;9mSTBhNqA1*AI^HyFxb6WojpJyg;kuAJJ`6M4Z zyyq@ls~wGu<ro8e+`y#{7>8wKnuF&aUe~<{|NuWk6FR4bl3p;-m&i2H3szk zC9aDNIb7U7*LLU$kHDkA{i^vLSC@^2pyl6&Pk|=7i#)4og4>mJ>9m!YDoRMW z$#Pi5Z@JZP!0*3J_aj*6tC%ayebC1iK7UI_`&svhz6IU);O&RlB28W85>)ev`KVl_ zksw!;GrTh2O?m8q#}i_>7$QrN8~5QM<(bo6aBkt^yK{( zL49%o@A7nsxB9;6N8#R0r9SeJexCm9SyJCgw7$pW>4O$+B+8uY`P`g~9{PKD|MfO5 z@pLuDaE?p9UoYnGAL{f;sOvuR^ge0fT7kQTynkE5YHj8lq<1X+-IPc(UD_K{cw0N#Xy-g55ft0j=~@wQXv;gU=I-2PFy>2>5Ue978C+; z?ZoAmT^!+nUdK{EucHF0n28<=k&pzW#kmo7z#(rhRX_wTIs?!dfX)DPvh$ZTD1u#3 z3DxWp5Df8vTtmVdk}kdbNTVHfMX(o=nq8yc>+Oz&hyZDo{Qx{;gBHGBo2}w z4e$@D1oSn}Hq7T9Y^I$9F1C3ae3rzLS(?t;T2p*DyF?1e6cV!&=_l}M`qhyv`j!d@%V zaz5ebyF^+CLJXurE|kC?ILfZdgoP0nmIhfsdcsIg80l$)zBb6VLAGr;R6?~#yM1t6 zBs>)2AO)5}F_512<*;9*qd){C0=hfq1L^9Bo{s2=z&|1#@Q=Vh0{;m7I|V~5>=o&Z zOlM>|qrdZEkuK=%QpL|yAVdSUBMFPdc4P$*)-?d4fUvH)PyjoCux>#>n!9DfMj%eN zV6$c$cHk(Uf*hwm|!3*hIldPjX`fe8$?19q(K%O1myc8-#-@c z@1FYI922=H2x1@! zvSB0afI}j2=!uJfJt70M;IPOb8<6%v$PYq(P%&(UT|k_{$PF%p?NBKakFI$9hoEZ+ zx`vS6A;=6tW(YDvkQs79WM~+~Lk6sat*{S{Q=JKgI7o+lC;z;dL;?O2GNAy<0s9kad1(qPg<{war14VhOhJB1ERg;w=$cXrdx7*^76dVn3b}yZ z%g}ondehLGhTb&vrlB_ty;IRMwFq{>VRqUk&NSjoBhED9OefBC;!G#b^g|-)0uc}g z_@!q6wr3Tx7sa~6tb(1gX1D|LV@r(*qU=pv7 zf-;eX=vj!Kh3LsfPj)<{LN=^}5+GgKq$?YlE0MVpTUTQ1$~4G<0w{&Oa2QUAEDC~1 zK;I(tEkfTS^esZ)BJ?dn-{K0ub`D$>0O-9c8PIt(aj!;hDRGt&e;M(Y>0{zA!+#m^ zmsN`_7YGuex-Zv6h~%Q@TJ)@d>k@!8UY7@@uon&sO=<|Eslv6aj1kGtg>sSADUc+Sg?RXv?E~UHOuUDq z0i6#M@8J?4-owOu_=HGVERfbM@JNNoqsTm(55>Uw)+ERfc?`M7kbfcw4#6>zavOv} z3?NsIT=_cK3fM2N7I`ugaGwf*a6r$tC`f=b$bkYVg9l5~{!@@^UZ`@8t|wC-O=F6o|YUBeFM0gf0kqEfk^weXpg%Qo!D8=z0xZuc7O8 zWM2;#c_R|`i&X9qd6Rf=V)I{dP$BYG7#tRPI|25Hyo1ema-jr}f9H_My8;n_t#`Aa zN@RZykf#0RuosSr9KhZI(s&>h(D7b4#6q&j`*9)%(Q}Y=97Og58-xM!A0z>GKOoKr z8(}N#fkSXyLL&zUO{t)tqszpA= z?_=aYM*d^uKh6W>KjwNq=6XIpCi005!k`3pz#%v;@+s;0Gy>uv1+pL?ieWocLY2tj z0LXwnK-|v+kogRmBg8vGyd%Urg5MGCN7{~%w$F2*07?P>s#MqqM@7CMEnjl}Wj3q> zeNNiGB>YRlzY2s1h=U}^fLz!JTSboIe>5Gid$bHHM7|CNY<^uN@(tnNREd0>2b_Of z4twD+U2`^wgc9KVyBNUzJ{gKde&GBE(ojv>enjVw==u@+Kdu98|415tJTCH6C=m8j zI*^W^2>a=v$j|8iIU3S{I6rR(^dAp|2-qv~3;KR3fO3&v(edjJk>7~-TR5QSL_DNI zCSdO*$0w`kmrDlh{k{}PL(N7&-jx7*;1GRL0(taV1wjVnvLlcU!eFB)Nr1zmRFNnn zSJ+(uLLnNCvMMZ6lp`Lh+02VDXFe2*3dj)EAPYEez1AQzGW`A`abph{E=8$>`H zpr-|TT5J^6l617xE_PcY+wu?`7Zn-^$cG{yngUsn55=$@DxnHoqFMz*6mWe0E>W!$ zfUwq_hY=PQ3&^)ggZ)5Q8^YQW)|Pl}k#9>_+Z-r>QrHE^wml}Qoejbu29h8Haz%xc z_He@6XN&53Drh#QUV-a){5A7uN40{Z$U19CBm zK%9QZMfJ}SH6Q@68;h+A2)_WG7w!XOE+S4`0#u0_xKz}jEK!5AMa82tey^w@Wuk_r z0%;jaykVp@AxYH5Cq#`1gQKEGqGJ^CM#qav!p<1Z$6{wJVabJ}#*^j=q+>$0sEGkk z2^^;!7BvYylk;I8d#4lgWo|=W-S((5!%-RL$o#hgh5eV3t zjlS9Fn~lENhX5UOusJ6hl7P5#a-j&yUEjlb}i491@67()14NHi>gfuMK3Z&txd{I~9cQxl%9~HF}JxjBJ z^QD|GivaA=PE*T}U!DTQUtTWinqbIiYqBfL?x()jqi$vW{+&cmRxjUgKS=1)YK~Z;Qh`Ku%asZpOt<=4o-;3?dX|PpP zNepZhbzc@>|9+RK2lk7i{i7a?0(3rvo`*@(!^cIH<%-%82Bc#PX?$cI;66(HtwB&O z>ajS$#^dOHA^?d0#0gR5O935EqWj4zQBM*66zAKrMQu+M^>mV`XVL(_XZMKOfsN<5 z#+~Tf$?@~sMeQmRwHvwJ#em!kZSJOr94TOE7XoslRj*5C6`PW^d-l!H;nGb}$ zSuW~dPyyAVK0xn>dqf@DFY41&;JQEE0oXho4k?fU_#NI02jQrw&kBGt^BLFu*)FJr zLqNRGT%wKy0%1o8J3`p!0gwdP{v5kiF|Zx5`$gD)oi7taeVGP1z%_hX3|!+^oPTvp z)KRYCC~5gR3JCiq7z&_D)VIk%*s*xP{SNm#-0z9|1M)v`?bYb7-YSYVg8H#U)KBu1h?M*e4geq7Y?ARzpBB4GD;9uxz5j_(Jq|Cd0B1oZxr4!MB-Ux@!}IFP1a zb6_JJ7WEtYenalJLQyAzVX3H-$el#)WT~j%qhY_O8vJWYM7hXs+6l^4Ey|rL%2Ol; z0}F-}LJ3rhp>ko57)C4{6T?;jyTq`ELZTQAj*8JR8Fq-#2-(00*e}L;OT}P}(P)f+ z6Fx}Qg!3l&2Svd;I4nj}j++*X(JTNqiqRao=0#!z6CM%-#1DyvL`Vm8gcL#_V6BUB(1q9GB|VJQ?s z8C1YQs1~DD0E9y$5 zrww-69E55y+G2-sNuzBnBm;KZ=0OpZ!(KQHC&XwM1d$LAsgMoppagcnJ~%2yxIidG zLn5TZQYeHnsDOh|Ek^qQ2!~imhD^wVA}EKwa7>I2K@bC}VswmzB)~rc{|NjeIFHBx z@*$!GC|?mr#po0Wl%Gyvh=!-@lZ4@K= zAfT@|`g)_UH~M;`uXj1@hZABj9%}T7hYVN;TY>cVA^m+rAr8_ZAIhK-NPi6JkHKCH z_F}LXgS{By#bB==Vf{#FKWz5HWK;L4e-=DUbz)upKI)T8sh2AAs%w z$w2%8=pV2Zh(F-47_os64aARK3WUY(fumwvAP@n>rJZG5K->$8U>6Ygf)ip~7zB}! z1jN6v5Xztes>Ha6@QY#~6>?!CVB?~FfQ>k8#DxOa5SI?fFAi@U~!7ex~#$X!|HaHFPpcDujydO@85g!DR5Dyu!4oYAT z92H|oAVfn7EQMmIfGRPDVtZ%|q(U|jcW4RhfPFyxVFKZh0Hk3U=^IA+hm`{97)CmV z9TOwL1`&X+gfggvYB4Sjf-EtHhd~^a0Q!fcd-w@4Mg%|e5@QtU9Yq>OZHGO8KW$xOGJGn@VO9;ONJE_626|j*?_@x4&VoV7G zWTsS#aaoBNX>npqMRsbH7}Ijan4SitCmoq|?4%zQV@94BGuHw7XOWH!=$DJx)$JfMI>;(5Pb_tOEz}1kBM<5 zdaf)NV^NqGiv{q@IWESMU1D5C+^b{3CC0LBF_vThntU-B7c{O#=ZYdRXbT$GC&6Ag zD8@>TS7B>a1?&?eKOV@F)tO?fi2|;hww@EhLX4Y&AOQ}G zQII9Z`fwob&H1ngj*4-M0P$~$gCs};WN*oZ5-1m=Fdj0*xK%@(4I9O{Ee4K>vGEY# z-j1!?N%QT<-j3Yu#J{}&h=2QD;JR*iiE&3TL_sp-KoRVM!(!YS2;0RdB7V_2z<$vV zz(&z=F*XstDFTqc8#{NSw>Vdfd(e3g$M;siJ~%4IW&y5ib2K2k8J(Mv-MkUD0y;MD zhht)t*dPpIfOM8ri*a87gadK!s}ke>Od!q!v4G42E-^|8FGYVTGNsskFkOs?NZ&)) ze>e`x#n^(*Ehofyq(Y3X*x8EQV=0gY`A`hop%Sq37WB_U1LArOuKmy?RTn?NNV`m!Vit#+@dOiz|im@vR z_JKY|W_JK&3KPQtdoL6M`SD`D7!?t)SB!szLn;&iVgKa#pIZSPFD1fKSO;a`5@Qc` zY1bNikbRl7y^R0Md*L7)72}l*APuj^1A6v`0(M^`4X@$8Zi5sk1@yha@f*m!LEK7? zEBA}>W{2&-A z#P}#xj6>M_7}-zI^=YCQhx5ev4EfKncO(eXVUHM}lZMZ?i&4dS)nPHdOn`DRzT!HL zMgwX72LEr-bu15#i}4-)-(|rGF@8YD4+nwc>QvYv#*blu`xANhvp|^`$FcoOBq09_ zY4{ZzzmoP}(f?Z@6aaQkp!-BV5OxxKC$aZ?JP=OX%Ajp!)Ks&lcMv2)p%}FRfbLrC z*X|X=jUJEQ^*LWm6$TkT^!Z^i4Zi+t?1!V^64MNYJSYavZF|L}{bkx?p&Y8kbnx{g zN2!=jT<1op5;GtX)&cSj_;L;HG_z445Ua)F+aqRkWP;Pg3_-4iK#7PDPy$aN#l-O$^ObaoGeC`baXle)ecl?R7_Jn9h$ zg!dr4M;7dXDlvQ7AOg_EJV&!9>84(9_DY9hF{25K-U^js_FgJxAN2MOf^aw}W=x!z z{W$N3o&LxV2!vcQsSlg6_+5bf1+kC_nNTX`g#xL-@kQ8)3x*h23Po^S%z-u_&Op*W z2$@0ounPzq90}+eTn1HQ#wSC8m_vv&gs>smuo3o&IW!tlfa77LV;E^mz{bV+U7P_q zfbNTtzqk~(!yY&+=I|Im*Kn?XL>yp05gmzp#T<#=k@%0|dPl8;YB5J+do*bsy#o%4 znG^xUPbw61i~w=RqylLeb3)9qoR1}ZY@R5QM$34n8cL=(#gGYdn_f|<8aEE)oKT5S z&+ybKTLX@h!F$Yde$Kqdh6KnI-?1sfnZD-rw@I*+`Ht<(>*p#gJr4YT@*O)Rh3{E< z{R1RG`SmoAaOKz2h~t$$nLv*3_Z^?7!qq>0$BiY%IO07f(Jgq)ES-F#BFv2P9UJW7 zk?1=%CEi@*JGMy#`+Rui?Hs@7J9cpVyYJX3=iA!)jsrL*2lch62GYzn!FSwHf@~SS z<3{*%hb@^vCI_$a9iPVpZNII?ti^lX=ifwn+K%~-gCxv;zVEoHbhh{R9XG>2&3D|K zJ$0A*j)OVA(RUoee!a!4msu#;vWzvNbLDdGY>tFWABmRU+=XyS!Dlw^NV$TL*+_+R zFBcJK9%r*G=^?TNHxs`_vbdh)P<*l^Lt>;S`n1N2urL?d9!%5i!~fpg|JnS{kiLXX zkclz|E~=-ahxoPBPl4ZWvX!F6=v+wp!q3stDNSeBJ_-BbG6RhnXIwceC#{fhu3-@p z8Q5QdyGZ8azfk7zSLeY3=vj9(0SWEL9vFlVvGnSkT+Dx+Zk^{j+=In(q4eVaDGdwI z-|KI~^*!>YY`CRQ-@%DiYI5XiD|Pw~dL^=OXQA~9tm%9YCsq17y?0jMMJ+p#97w_) zN2;`JI8Ulhsn(oynuaKR&b$k~xps}W^qkGEKQ%Li{hH91#ow9y)wZwZT&F|d0d04P zjJJ++$er-Iyzu7KVy;D(+iYU!9M>fw3s;xK%gMQM#83K<;+(qj40L)+?P5vbcroc( zKx(z`5{`2?(s?t1zuvqImn%71NXTrY!=*FK;(P)BbxHUuE#bmWWyppjr*mbobw~7l zT8=jT+;!!Noy*ZIE5CHeEM#;UoWYUz8C}dB)M?PZ-n;yFGU4Q*PQBJp|ElWiIsLkZ zVBc%)3hd}3{RCWrdn)hd;Io7@obu6kXlcFkD>&D2l90R_cMRnce!uy_mI%u4Fe__$Y7)l4;4!74=YEj~VO)k>YOTB|VCMzvM#_*HGMI;f5+LUmG| zRTmYhx~gufJKtRFp?a!bDq8hceNaPZ92C2c)S;g}P zs#QbOQ1Pf?DnVVWhD#SULM5t^YLptSlGGSAR*h51JRNV4mwV-PHC|0n6Zy{KBsH0j z38tz`)f9D^N>fwSG&NnNs~Kvhnx!(-Y&Az+t}@kJHBZe~S!#j0f{(;yt1HzawOHk- zCDK)0rLI;>rJGu&maA*zgvwRdsuk)wm8Y)fE2XPczFMu;sI_XHxs#hCF(wPzj{EGst46W>S0x;wx~zc zqiU;qOrq4|@-Ov-Dpya+TT&@+s;AU8wOu_ezpH1|vucNWPVH3Bt6gfhdO^LYD%3yJ zKlyge9`&+%MZK!_s@K%(>J3$?-cfFiZS{_NSM65^)O+fEbx?hvK2#s6L+WGo ziTYF>R-dUO>T^}4zEEGPuhdcXwfaVVtBy$z^_}`&{h+F)r}|O-q<&V%)i3H-^_x1O zPD(HJyQ)zxRjb^}LjgO&Cu$9eHcY-uYv=1YP9wl*z#D&#(a>mQ1RCcVjg2NokkQm= zW;8c~jS!;+U+W4rS{dgXt&K2#_b-KVD}wjG@47zL(OI8a`Q0raI@X)FjtsI zm`B2m#wPPpyo-rQhrG>5Hcv56HBU27H_tH7G|w{6HqSB7 zH8+{(ndh4qm=}WUtkwLc`7L8F^CI)x=EdeE=6B5R8he|UnwOcEo8L39fOpWZH2z^; zW!!6i-@Mwq#=O?N&b;2d!Tf=Fqj{70L-S_y7Wn1fADg$DKQW8o!r8~%Y~E(PX5Mbz zVcu!pW!`Px1GjTw&N1&b?=yd9{@lFZe8Bt#yovTp^Fi|=^I`K5^HHPUe9Zin`D^nx z#xdq^&EJ{7hab=SBfKT}C-ZT5(|N7=g!!cT6gVBOHlH@1G5=~lYd&W_Z@yr@X#UN7 z$^5(dviXYns`;Avy7`9rrumln5A$vF9rIoDJ@b9@pXR^J56lnEkIawFPt1RtpBg#y zKjvrVf6dR$FU&9D_jp72IjIWJhhJEx1rdu`+!DqD_-R+$l9pq+mSY3XYFjwwsx_0 zwRW?1xAw5+SoPLitHIjSN?1u_q2*gCE3g`^Cac+Mv0AOYti9p4Q07_tz#a8Zt^KU| zR-2WEUx>dAW6%bvVpgf3e!( z-GUBlg>{5=q;(X`1*32m`eu?p5IYqiyD^;ySQYpi~2tuzO zI@j7{ooAhIU0_{keZ%^u^)2fn>)Y1F)+N?=tnXTv!tZNc4tMUqXI)`kX{mS~a^&9KA z*6*y}TYs?rX#L50-1@Wig!QELl=T!+O(t%le1)w)KwnuJxYvzV%P*U)BfKht@~NVb;giC)U5MPmTW? zuUh}HKC}L7eQteWeaQ?~0q?Px41On#F~*r-Hj~U@F7sF=t76rxhD~CV*%UUFO=Hv9 z47L^9nr*|jWi#1!M!Rt;+n(*fc4W22$;L@=y=E5MiPf>4*=)88+m-Fcc4vFAIjo+| zWesdkmS9QdvlI(hBWq&KtcA6*z1ZGt9@~fQ%l2dQSsP2U49l_{3)up;KU>HSV2jv+ z>>ze9Tg;ZQL)cPwC|kysv%}cotlj8f9c%?V!dStMWJj^1*-F;Q@~n$>8%MAnR$!~x zY6D)0gWp5$g9Fybur;iotz`pjkPWe8*)SVnqil?=W9!)lwvipjj%O#p-SHFIN$g~H z3OkjZX1vZ$XJ@c8jd$2t>}+-pJC|)@=dttI1?)oh4faj;Ep`$6HoKTz0>8`rU3MwE zj9t#Y$F5*kva8tl+12bCb}hS(UC(Y{KVUbqo7fN8&FmKTBlcrdl5Bn**m)*yH#(vK3XAiJnuwSwV*+cAM_6U2FJ;r{;e$9Tve#?Hxe$W2E z{%E|#{=^<effTTK5ye` zp5a-Z;~`(b_vZ`w0q~2)2l9jX!F(}a!Vlp~`JsFnU(OHXhx2yc!B_Aj_>uf5el%an zJ9(aW@owJ33w#w{&3kztKZdX2{d_GS;DdaKAIpdN2p{ERd>voUH}H-8IDR}ofuG1v z;wSS{_^JFfemXycpUKbSXY+ITxqK5pkDt#k;1}|5@Ne>O@r(Gk`NjMa{vGh~oMC*& zI1^rb{Vu2!E76#(%|s&40sx%YVmz&;P*x$p6G2=YQr;@F)3G{4e}z{tW*s zf0jSTpXV>|7x~}#OZ@NrW&R3(mA}Sc=Wp;g`CI%S{B8aYf0w_<-{=42|KcC;5BW#@ zWBv*MH~*CX$8h*(2IK!VuH&B@JMl00m&Uci5Ebw%$d$&v@MD1U;f1B6jZULZFu{co zwvfURt|5${8B>gv#v8_d#w2({+B0qwmGG`km8cdqVv?9FriiIxnwTzTh^@rdVjHoo zm?^ds+Z%TpcY%+L8@C&G7!Ml{i5RtCELudX*vq&cyep@{6{9wzO6+ZHg5O}82fr3|zSvjnC+3Sbkv2{@t~9O^8Id*4 z5jl7t;v(Zx<1*uN;|k*j5gPZ11!8}(P#ho@i37z!;$X2@ED?u@rQ%SrOe`0NiNi&^ z=nyN!5#mU3lsHqF42VH7B#srsVnmFJF|kgp z7aPPzahy0_oFGmVCyA5ADdJRdnmApYA6IX~U#Z}__;%ae?xK>;zt`|3mABY>pO~!rVhvH^&i};cF zvA9+IL=?ri*eq@nw~IT(o#HNWx41|ARNO1>6F(C_7x#+?#4p4z#e?D@@vwMAJSrX& zzY@O|zY)I`zZ1U~e-M8Ze-e+2KZ_^Clj14y7xA=sM*LMgYkVl46VHnmjE{_u#f#!^ z;wABS@v?YDyeeK3uZuUto8m2apG+E$h_}T%;$88ccwhVzJghGo8SyW82j~OiY2z8= zug0_DL*qH)dE+JVk?{h&iTbhlMEqNPD*hur6aN*T!#>3q;!F5N(F)tNEt}cg7Pf6m z+p%5Svn%Z?yV|a?C)tzjDfU!*nmyf~VQ*z`ZEs_5YtOW|v$wZ*uy?d;?OFCtcAdSm zJ=@;J-qqgC-re5Ao@3YBbL|FuPdi~JZQoAWf!$~~+0Ax~-D>Y;?`_Ys_p$f2_p|5Q zZFbtu*jYPghxP({e|w>QfW62*&_2jM*j{Weu@AAA+K1Z9?B(`h_ThHB-C?h=kFbxl zkFt-pSK6I+-tMxy?H;>eud-L$y>_2{jJ?M0x7XSO_MkmvA8QZWBlf60X0Nl?+Z*hS z_Hp*{_6hch_DS~1_9^zM_G$L%_8In>_F4AX_Br;s_9pv0`+WNX`$GF0_BZWs*%#U0 zwlB6XvA<(~*S^%g%)Z?Io_&RVrG1tCefw(r8v9!NI{SM22Kxv0jrL9U5AB=nTkId% zKelhRe_|KyaeK3Un|-@|hkd7gmwmT=kNs2oUi&`#XZFwS`|StpU)aC2AG9B`AGRN{ zAGIH|e`WvL{*C=x`*-&5?LXLmwEtv3ZvWYS!hX_z%KnS}wEc|zSNmD}Is1A01^Y$& zZ}v;}-|d&}SL|2q*X-BrH|#gh|7Cw*e`tSXe{6qZ|J(l5 z{*V2c{a^cY`wRO^R>~?_Eo};UFS)mzC-;&2%KhYg*(TF6BeOCmL%BfiFBi%KXJV+ia7t1B`5V=$yDwoOS z@-TV0Y?mE!g*-wYDUXsz%ayWI=4F@cmOZi{SIO0~SN6$c+a#)VY zQ8^~p$@OxB+$fKe$IBDsiSi_QvOGneDo>NA%QNJe@+^6_JV%}@H_7wl`SJpJq5OvY zru>$?NPb&hEH9DYk>8b<%FE>C@_X_Md8NEceqUZKuaVcv>*V$F2KfVdqr6G}P~I$W zkw20@mbc2E$f6vVo8@itc6o=qQ{E--miNe?%6sK~@@Mkr@_zY%{Du6bd{90lAC`~E zN9AMkSMt~LH}bdgck=i05Au)lPx5j3XZeJDQa&aBBA=Ge$iK>G<#Y0R`GR~={!P9l z|1MvaugF*BYw~sZhI~`LCI2DcmhZ@S<$Lmd`A_*T`GNdUek4DZpU8j9Pvw8)XA*vh zSbibDgddQta7@Q?n8O|6*p74@$8|iX(y4N)of>D7GufHqOm(I?)14X4R?gPWHqN%r zOlLc1duIn{N2k`A?6F7}d zlhf?9IIYfJ&fd;EXCG%@XFq4Y)8?d|jFWY8PUtLf_IDOK2RMtI1D%7MgPq0B66X+S zsdK2a%vtUn<{a*{I~~pn=LqLW=P2iBXQk8WYV1B?wsMA>73=9?VRJB z>uhq)bIx}za4vMd;e6BimUEHwZRcX=66ZV4cb!X}%bd%d?>SdES2|ZY-*>Kdu5qq) zu5+$;Zg76!-00lo{Ls1CxyAXB^JC{$=O<3l8Fw~2w>h^vcQ|)CcR6=E_c%Xw?se{S ze&+n#x!-xf`GxaK=RxNo=V9j&=TYY|=U2|Jo!>aWb$;jk-uZ*`N9Rw@ze|4U9o^zgeUT|J?{^q>o{M~ukdBu6vdChs=U>hT&WFxN&d1It&cB^co&PwWIsbJ&cfN4GbPX3C)^aVEx!e`5?Ml~iUDtCf z-72@*t#K#0liexqRCk&?-JRiX@IN+ahJM>y35?kE#_f04x&!W@JLDeg4!a}ns5|DabJx2Y+>P#W?(yyk z?uqV6?#b>c?y2r+?&G(Jmzsvc(x}!$8$Z;tMsb8YOltd0 zH`CkB+uqy3+tI7_W_de#b>7b2Y;PBDS8q3OcW)1Gj#ux^^%}fAy@Z$ad@tn%UZdCK zHG3^ytGAc8w>Qt*$J^K2&ztYHd1)`>WxbpidJDY$y@lQZ-XiZn?;!7BZ?U(;JH%V+ z9qKLfmV1YJhkNZ_hquBz!aLGC$~)Ry>2-Q}ugmN9dc1a!Z&G10hv~^& zo6d(&=R+7^ejAl*YazIe!VHDFon$Ue->2#OG<~0L;%)syy?Iyv9UUAP9MKf1mJER8LyhlL(U7@gN(8h+x=4-?z~B zE%aRrwckSRw@~{n)P76UenuRaU)$A_SLh^?Ip1!}>7mkakfr`7h#rXu*7QvHK?=WX zNn-h=&(eias;s5i%XIe*caN=I)nC})W_kuk^WEKrfl*Z!#!RCQUBxaYTd>YlsJoI# zwzP?CcOE!|iet}m2^un@WDY5l%q4xE?aB`$BFWH~+2i!rEA1RHT23>Xn=9jyL!J}4 zQacGBy9gn5(MJmBlGODiu~IThC%lq`7ma8RM-o^nN+%Y}5Q}Aqq#3F=6Opuu=SIhd z2khL?NMHZpKqZASrlY3ABn^5JQ3#VX=!8m`q(RRRlVp&xL9!7?i=-(?(CB3mg=DLS zfu!ISQK+y5Kv?}rvNh!`h>hujGA%X#_`XxDNLIzF zYDmfjdVCs^mE~Ha(!Q_qbl_5se&iRW8%U7J_6u>d%7VLSc=LY5G*Ew4T1gaABm6 z6lRJ#m7-2XiVn3vGE7mYQq-vwbt*-j%F_2)`aVlU$rABMY=cCzwXh-SEsR<(F-tCD zpw{M6S_Zgl;p*Z1x`K*m{RiB+u*^y-SyKu=AzG;3A~C%a&r)JxHT=lVP@0U$#_Vwp3r1>PrNP zCaeWwKpO9Wa`#b^0%U+xGcrU#43SKc+Q{M1KajtPEiUPKWK~Ecc50+iZbViN&`e4s+X8E8@1UY^GR$S!0z)s4PcvCEC9{Ni z7N_DQD*8l{6uggi81#gC+)R{cCQ39%=|uNt>KKY2Fd*ee+A3lJ6eP%}j)&NBKT-hA zM40BBcX)Yp#Nm3{5Qpn=a}JND8_hB~G-;DLveI*8o#)UhPXxHkNCaWV%JlYWS|-ye zucKT)(Uy_}3k3bkC-5HJD9u#x1ek>sk8krg|Zq6vW-?AY>K>2 zQjy5GAd=7w4@4=&lBF0J)7laM(qIf`M6d*^@?}nnO0-c4MXpj>sm`{@LI9#sO+YrV z21;gJRDZT)*ZAeH2_slYLQLk#q(ao%2uYZuRE#LAVn{r!SWy>rk|rwHQ)N0w*$Nw( zCu59tMJhenLW9;wOags8P@`dV4>7DkQc?nk9th&k{mAkU}%W#Y5AC=Wn+%k9Xawv@F2iFv;b-YXgJ;=$Bsq#q6rUY9JY~ihr4e#m+A0(1~ zN~|uEEE!T4{3Ki5Fw*TR$@QBO5Je_J5<*u{lLTlbK@qKaAtY{SZREYGi=O`5uZ;y) z$CcUOvtET)Zy7H{I7x){iJ*Rj4Gk16By+9UT98iHKzI5JBO`qi*LR`l!^u|@#m}lK z8>aZO#lVlIDVHMg z3DC#_rKdGMEG;NZ(YVm$l}i!prijw1M!rUkmso>Vjp{_Qwaw{Y+t-7X?2ijQ8b`3| z2v|RKQ}mbhcQTa`{Uwfq1q+QGt#fmll90pK)Dx*!PS3z3M1ge z>p{VwWqA(Nqvkbm2o4~{tdcyY8s$L$DlH4T@?>jH48$lGG>L%{Dw`iq+K}w{}rM$t| z%4v{RP87yhPH1<9G$tXgfx#Jv2!v$OhD6}7nbr)=DK;2MZGe6kSRpm@!9v6dK{Lu# zfbL^h4bT`hMj^^ufXnZM4@>@INq~mqf)r%=u-23MFXmJZuj(7=ReBQk12m)f%{e(t z>?Vd|9Mjk=hRYlSYbY#^lPZh^aSEBVIWlQ;jUgLWT>;x|oeD?dD5XL%qMPtWw$L_y zG*LFuNHoz%Hc_up`zLcvL>;6CP^YDGbzyjIexRqTe*}yfocBicyoZtimgy)WF^Mv} z$AZHO)I@C9Ovtx3TcbG90)ml^2bF%Q8fASoTwQp(5l zqHt`YtWKDOaLJI2Jk#i9fXPWO>LApMGFS}ik${k7s+mTpnMSBNN+-@}CL-l1KS%k| zJb^j_WRHlLBO-=LYYYfArWqw7R14V55_=R8HVe+_s<6f1of zx$1Jwk+lqcE#;EK5Bg26I=~R>kz*4K?Hn{>Yx+mc=1Nw5SQ@NcX;5>eLCwLS)=U@< zY8nWuVmNwHt-WjXX=V`4yli2UMkI5?IZnIts!R-xzflaMB$v}mKImDnB3&jtClYxBBWsn&om>xDJ8+1_U^ z>Enm?tzMhAmh|>nOGePwkfH^07^dCDYYVI6n;Pgyf(;Lpn2`KKA*q*;{6t|Bj$%mu zqL9>0h+fuYNIR}!)KnX~V?tb$Lq57yLR!0rZRmap$p;XI8A)ynT!^J;8c)$WI+YEC z?lTdc=7Ip74?u3z6al%70(2XJ6Pj%4WHUISyEhJNk_EV>0`6i>Q1B6>EfAoS3EXNl z#AvA}0^Cf3FtW^%%L4Q)fP*JWrzw`UcLOx0;X6u?))(Zp4bb9;eAI6N8Q}r$y+FFA zI)ubjWTOP+VhM1+8}KE3a1;O^s*m(&K>O+eI?tfI&+~epTmOyO6tuw}q6-D=Z}jPe zw8{=?V>qPMc8J?BP!44#L^mRM)yX!&4P$_*9$dWxtPzF~WiBKST1X-v(guAO*o3g|uNGBH@!^x|wx>2=LWPEO<|$A2z28Wu@q&uXuTHFhIB|v{g52NAz3FOZ6t@Z91oj)b{wE+!9NNAVnp|eSUyhOA#GuX zv`!3ZD>J0^Vo0YULh@^cwA|z`&q2+KWQePH2&p{zv%|1iXt^cTjx3T0 zkVPOQC5>zis-Bc}wBJa!bAW6NCsyAX~%KK=t6hI_z6U?Nd6P)M$*9 zE_oCKbVoydq@2m87hv~cQlWNnzaPrcWD@OB;<^m_LEocJ12cvu5%kCdO#MLjI4E^m zcF_K8fIDVTj+8y_oB>SuN9GX@H#oKEd)%Rda@0O<4FXJfqIv*&Q2WTZ0Mqwm=LhI7 z1dE60hDJCzkTjhk%(C3ru-;VzKz|Hjix?`5fD%z^0YLpNoHfw6K-kLq`-Y=TJ@8OS z^9y8Z0s-t-bq|845Y|w`g@NvkRF&2oP)c(rgnG_|P1b9mopFyV3=cNwwYda?PPtK%_Gm9iA(+am2FGC02`O@>h*}6N)=Sh2g%z9@U&CE<}*Z4c*|rRrQS&z!jnBt^jcD z76$qYs}x#Q8W<)dE4yF`Ux>0a5M@;>XiWiJn)z&xs8Fm8 zN}3vPh|;D_XpIt`-i<@On#k1@qYPWQU7>F-DB1jIVOaH9B^8bx%l89NL+KGLqlh;! zI2y(6q5d&diCo(^pd;SevHsD%q5h4K==Aih>+8{!RmGwr)o@f|cyL2hMO7Z$6zJ`R zZ@l~n;LXmBEQB6xBc*Qomw5T?W`Y=)poCDbXQQsW<$MGT{|rJhhiHFbx; z$>ly#%G7wrC~Zotca$`#)I~~=BSXMX&|&SZPqZZ{3Wr2nAd12tv^j+h-7xcm3x-li z;h+|U<9;OOsI~oEvPE+eapTHk$NKvFr^HzVld323WX%=~IcZBqiz-E)R$b6ckMf{E z&GayaN}?5P=P`6w^{pNoF7&{W3G6_!(H$Hr40Mh4_ZLQ~PpRtB;lBL9>i)unWYT1) z(EY}?HZR7^9yoEKQr%chxe*O}g|($T539s-<(4(99M?d?lm@0w#35cF69-^B0{W*v z1(Y;Ub?g{OhdKv54CePF4Z(;-34Ca{Z*9TDvurw!{l=LdHoTgpPKEN-u|f(2oQC=f zQLg$d;nRfar`sw)kdR3KmpYg zTRMiA=a!Rt~mIbM5f)sf%5vrajKa;i;o|-Kr2lNDK28E^=OTu~tC%z;) z%iy3&!h$|(io)?L30;RmO{GYi=xZ1lTRSWUbU+-JmW8!LqZ?ty7Wsw|uzE!o2HhC+ zU;vY$%3Fm2?5!!N7X#S!QP43Mtib?w9aQ3448Xy!AedZLFoeOe7{IKm5=StAT@eM1 zVF2!31+B*brdA=A`8xm?tvG^1Y8C7~NhX_uHYI0T;&{V3TH8`uPs4hd3 zJ%H6X?Uysu46e$d6#$VcZ4N{QT%6N&{Wz+t45n4Djw55s$5+AD0qVQQ3(^Z zkFHv?or)3L=_oR(it17A!cm1ljVc6cR3T7Zfk2Ha1Zq?vP@@Wg8dV6?s6wDd6#_M? z5U5dwK#eK{ikuLrQH4N_DgqpGKofWuj5-DvfF>14p$h8dazrN0kbcMiuIh zMir2xv4r|cF^$ZGQ3X6=bBgNR7Ngqrl~IMNX;h&-R3_>>Qaxq*^b8EHMXpz|7=09| z>4WJJeH27oucAbsQW>O=0+H)u8Hzp%)LgG3nm(lhL>~nceN+_bqhd&(QgQ5^E{(m@ zQRG=&ygVl>Fit-Odt}M#uh6{J#mZ4N3aOfja5M6h(tt=a6^qeKftqHR9??ueL^Bm7 znw82R%@l|f)dTM`$J0OQIli5?GtqwmlpOX9*5(s5;$ zY)m+ylC>c9R%#)|_=u+#NECz)1}~FHjGy0MU^ECkb(JnM7wLoZKXQ5{c@3 zPY)bg9|4&;rqDggwetilSv<+!pxdqjuQAw$ecia@9A%dLEQyp4_Jcav48-bk^oD|p zX&WR(p5#;_aP)qO%8_7-bQSss*TVt}7GFBrO&@@Li!(3H-U%XZ0zI=}^wNqMJ+lC( zfJA+;eY#fL$&8sZDU6K5DU{JdkCPuB9$c>$eY(Zw zuo29tRig*Ok)Jk|CR3O)Hq=9XM#l&ovTdu@-{|G7 zHXW6D3EkDU@6?HX)@hTY4s7{Ji_Wgm+2yr@wxyfHCY?EL3u5TRDN%)A`3O$sDEn3C zt8QwLDs0w337IXk(RSBmft=+J;beatz!s<&;^_7atnOOb-CO8hQ>mj}`TqXF(G9R0 z-j`nu^wZ(kkRIShxH6^TVdRrWbTIji=pgeO@jx2DIHXN&2~TbD!D0vw$*iIH`rf`# zxW^0`Y z7><4u31(AMlJ^!s_K;c8w+d&=P}ek(?ny^F2zR34)>7NlA!xcVxTh^{+@n=5___XGSCZkj+yl1mOa@?1eVOb0!M-{ZakoRCDloyz2@;ede} z5kMf?$%JzOq{eYC24K`YNpi=*-3VP>5}oRP60ZP2h}EWX+rn?e{Zb${EmQH}3!KM6 z2OVvm`2h`UfH&&^MoA8+J8&FMw?~^>kdJCTK*t@x*lvI~@BDz+CBSVBfU!RT`hNk& zp$X8>3ox=3`ELQH_R)_EFtv|YCIF`P(H{&jwT~yK{Q%wX5F*_IbiV^kco2&O=zfQE z9G(E(?*O+@Ms{PiMYRrmO z#X7q!)q;9(Y$$4*G!>}iD5XYeT2Rdqj3rR3VymbbNi9-RSvy7FO^a)(DA9ofdum#R znG6onQ4CJuQ4G%0Q7l)Ag{9bnDCWV{$SCgYUy3a(#SSRN7L{TLmSP8$Vh5LEi%YR3 zrPv{**wRw$&{Aw!DYm>6JFFBtycBCM#X3r{6;Z4b*%CXgz0X7dPp`5ty^2;>2%$5Y zidAYqcl3?sPWpyc#{_BPuGA@1|^gPgW#B8M4yxdBPvoB3`&UvBl@Bw z7?cnfjOY{cy%C6lK|o0`2qwXZisGt{dQS^GgeI*5&$*UJDmy8Xk%&H#|21k!PxK%% z1jj@sDiMjygc4e0C?zg3QBq7~C~2a|P@=K|;PkbxR}Iw>0Q?UNFU(6d#Q}Xlm2!f{ zSWaWCn4fHk<=}DGs5X5lHZ@tdL?>ipWrJ8Pu>2_JfIS!o5Dkql%y&v&BYa`<)BrdS z)qaUeuP$$hM8&{I3X%_blOxwA(i2jqL@B6(bOk!8RH8uw9E#Q5Xhr}oc>x~H)oszDMuRv$Sx{z>rvV>3AAOZ5<-i39 zJ;aog2y{+O`3Zn{Nqy`&Dv2#48X3f?IyV80n(_tySS@MI0#r*9ajc15B#&^0p^~1&9@;5=8T0#7q0MS4iAcs-~aFbV6 zP`!8pL1-w-IH=p6v6eD%n&u|76fcGnMJ+YPQEe<&4MttOwx&2O)qM%#3^;}wZ>K3< zTT{F?JlEb_z5J^^N@le@5<<=8`r!DZ7EYZ5fELaO&^m&?$;Am7#<6RT+$J(n46DU_xzTy$LbHexT!$%l3$C|lfbParnrfA!#3a0kIJ6I$I|h}D;gQ$07KrFb!%1PRr~II4~1szD3HYio+5+7w5% zDc(IeV_xoFQ@m<$9>j9u?ZAO^l~Y|lDIFCAE{%&LoR^N}l*Jp0l?4@mxIDwz>FAqe z4o*gw0XW(m1CTz|rBlkWyp}lTa1gxwRZE;gEm&Xm#;*(+=!ZD@!6&4us41WHja3P6 zrl?F5esvEt2CB=P8k|%X=yJXm=@_Vlx(sTuMo<|_>TZ|5f)%S?UCBeRbOT9)SRVPC zw3n^{UakOCF$M8emjhxIsyhX7u!Mejq|5nwtji#r9f#BLrLQ43(sSBEQzJeh7Y@sp z3ge0S7^qIf$3S(cU4wd7g{N`iKzXp?K5vZ2f;f)_aSI7veTY?%i+_`g@gD@w#47VS0AR_f>)In;!W!NqDNp49lxYe_7~?r{9R-IQbp_R>{df&VyAw(($_BWK zs?$hXRwmfu%~b_(*aLPW_&IquR6#g_K&}l1O~tJu<>3a`SC1~O=n~oS%~SETmAZj!z?1&Iw`Nf^Tt+eDa`HgKY%Uz4-tH@fzCd!=v6Ia_{H+8+8!JLMeuX4?oi zyp9uZ=*V#b}L>44aG@R0+EH+N`Fc2q^0js4`Xyt?{uITH{9mqM`L{X^l_v zK}*K3Sx>i=7WC12x||X%;9I`B#BYJ^IDN1P&O3q-v~01&r!V45{Fbj>;_IzCcq&hC zU%=JbBs`fnJeb#e4Un9cIaI~k(+v0hwC5T!v`0FTq!Yw2Cn}FBz*wK3%$N%gz@$tw zI}ikgfHrgSLbfcrsg!I9fz8+E8^ce?Uj8}+$x**!7}8x!5Vj=tET zG8w3absAYedJv+e$t{fZ_74sYm9pr>Gwl0dQM?cVSA&r*K3p(wTD(&lb@Ja(D^M3Veg#IAe1{a0ZxqrN*f|WD|>S91YyqhuL={vVTP`bnow{&r& zl6cq}x~(@bfKBuWLB8IAfDzOi6mb2W*aYvk!${J|(ye=a#}(1_aWaL}<=>5%2sJvlgL)Xm_~N;d=1=~j7u0xq!NRGwr*eM1FX z{Q+{h6cWF-HHV?QRB;I$a4HPzY8!KnuD)}ulUz-ja&AD+bOgBL22MPrL_iD^(5qVk zzTg1&v5?mTys-l?QYN5RxdOV{M_WJ%+WLV|Z<#?z^+(S*;jKGJ*Rla23Ti;FG6i`1 zB@skdxN$QZj^ra_2RH%%(|5RK2Ui9N#w{_pnt%#|w!Q$?TUyG<)l>remO}cDUL6bY z#s<&@IU)!tA9o_*Y%P6~j%BBUdy z26*cb=s@4$eP6iBfdU*5M+U^<0iOK_I#78!(@$H1(Eq5v^nLWYAZ}4A^BU;^kN7CX z8PNTq0PhbgBb(9*KYU*V`cL&C#{+$^{S?ucc3$Bg5`LE=dZxmVuTf9s=~`3ij5#od zQM||u2U8K@6ke(Yi=8TfH&@jCx2TyYY!bS;LtTyOQ*ULbgC=S*jNq6xJUcC^J=~V zH7s%CYvsx+j0~tZI`V6(UtqzZhRO8m%7BGus2g=L>^v-xx-(I=JQlS=SO zh4|S3Un_z|e)j-H;lxc8h4VI16b|J?Q8=ul&yv7>S=6k4Hiyg0*2eNF?<5?9(TB(M zsed{%qYk2t46ZGmMoG|HNGZBbmZG^VMY=mhb6SdYc#7t>6zTF5&2cHx=_#7)Ql#5c zH0P!0W_gyL%gvG^%F;`eS$bC`OE*5V^de=J-dD-e%amDqXC+H7RA%YDl`OqfnWcAE zvUJ}vOZP3abl);diY`kJ3TEjIi7eg2%+gyD*=R1n$NxarlkO+GG{CFQkd9VXK<{4% zcxtDu39Y3>ima<^f*}xwOAq*aWPpcDZ1R4qPJX9^k7wr-hE5ai&H6DN~CBhk)jvEQe?@b$g)Y% zBM~V)wwXxbAs`58`lUla;Be8Sk)^{(;B!&1a<@>ro{Yf7iKCUJyV+T~o1LY{*s^pt zJBx>xpnUYb=0bpR+RoBDuUX=rEOAYixFt*Xs zGfP~SB`(VncV$ss!cG(QgYE)n=`L`V?gD4YEXmU9FiTvSC9coX+944pl`KA+wN^XclXPxh^kSSS2kdRpY;h&y~LwZDekNtG~d(gP^{-P5Du6MQhGO3FSP zDEhVDl`8F6(T#z}r}SajLG-nWV_)0wSo!-h_G8_XN(gIbPpniKy|M1eWkjf$o7-YlwuD*euF;&-ObtDXbTA)-y9l-z-0vb^zCcz&#XN>DTl>k1| zE!~F7(^y8fN)tx;ZB+3}4N>KjOFC^Oded-MIP=o2^tJg{1iPb|?> ziBtg2sN`3}4MGAdH50(2cd7*hqJm{BP33`;EoQW-6uAK?t|B$aAtg_%r+FFZ3;bP< zk9AinG;~?WhylQ#U*~N6n#8g0DTuHB0TIWCQu_;mLSe5*{q z*9azlBoH&dK6&MEVZ-RuE%KBkR8iW-VfE-EwE&kYVCfJQ*T72LhM8P0-q*cS(R*Tw z5&?QeZB-xaLTrR*)P|{6d^oRqs1V)RP+9>EUO1bgUdL1byqF5dWeI?5qP_;yjY{Q% zTnQzB^ttN({4gAdRu^>@5;b(cSRXottsh-0ID{Hh6Q248EF<{WTGH`ar>-2(2k~GL z1g2M*YtV@Z!A^Y)f^EGR1h4wWAlPY)LGVihF$i`5V-URTr6HOmn?PVt*+qj_rP)1# zB)#g@7DX0Ek>yb&A4LjLWH5?sbm?<=E3H!BN+uOi4I=_d1~$G{D_M~d2UX$eKvFq1 zFnDX!y^1)jMwj48Dqqu|5~@@JY&zn$&m=8$iovK=FKPxRG@RRD`vCf{?*)#)J9VRw zQN0pnRlPw9X2Z0&u&U>43XnKCs%T~O)wDH(@Oph8JRGQaRN)B44EV3YsQB_r_{Grw z$Nwsl6-nc5<8A)9VX&hO`afF(=zGt*;b}#W|nQJEmqb+B$MwcvLzcfo2CiX6lWE- zo261WS5L1wiOWHdjrB>y+D%PZ8O`S74J32aM0=0^jneL*o zw7qC7QiW#$JabWT2Nm04QU2~pMz<<)H#fREI(qUQ#fmu{9n^!4+8*dnUAkj#k=NJe zYKv@k9{OZwmb4e`x^z+2rC|i%lg_zCp~(%DsO=fIyVA8PQ+0PHqOblI?ao|xk?%1J zGBdTCYBxb!;|V?+D0E1B=aQNEr5){c9kV)Wi}Md{hrF4JE`-Y5qFrBfGIKT?CJwU% zur6H(>{6G`7tO9!#fok~q-gIkx9HT@Dr~EvTg>Q!B7pDw&JIo+^qMkbfu zV^)cAy!wfZREf1z%mEZK(DlyR+@`v`8dObeW2PFAV(m;oGQtvuwl1H=CaV6&=f$1j zEBLt7wfINXivR1c>qpSM14W=N2c`Llv+ zBUGHEprrs!(&IH5Dw?E;QVTTb2E>b#Go7`YI%|uQfoyY&Q|cEjYaeGl*^ZryRfW0@ zbBj~!7ah{R=uk|YISbOK>hx*#She7ZP!juJUwt@L<}`ZEds6f0)H zSXi@{w2vz}1ahS}!3aaMllGWZ2cJc8;0KkjJ^@KqxgF4x1%UqoNS!!X|6>Tp4P$B@ z5IIvc_T5}jQK6-9dc84jn7L)`#VK{^+FY?3*srP%ST0@LdDqrkSHKT4Pc_o%w4%T? z$g9YYPm^ z748Q8Q{nE=KNao){ZnB>eeFCgNPE`Tb{4nptOcc4(W!VM4`H!E@ob{LxaXYWo*<7& z5QPQ6v0p2Yb@`S$rP%*}O8`60E&9!~`sZ(YlHP%&NgwF&3}9r)UBIzd?SEpv;_^$lCi zn_F!8KNSVW?uO#6Fhs_T*|iO|3zSL#(k|SzX+hlrP(kf5@qyNb8L6eBV)`_o@Lr(1 zW)!!AVhq&jY+Y=;(nuG*%$&lehPv9?d7Gfly(bo{ZNU19qAnekt}S*doihKB_S;x3 zubp`t+l6o2kye`41*Hw`0|s?rXHmdtPZU>>tcp1}E3r&xPhFA2qzcN8W%4s2-q`{A zVaspwfEwukx-j1|vkqDap`Q@wR-nGGX#@~aDp`OMfx+Owa4>^xfeF-@SF@Eu!h*k~ zNy}{kv&@TVQ41LGU5FNS^MFkIl(LF0D3jXSux^2BRE^@kQJ(G$Qo3j?Yj3EX2NSx& z-o!+xv@{e&F&m(TkX5o>a1g)Bd7X7MTA=yo7Wa!<)6}Qo>Qn~KmR*j9cs}Tl21UiN zxK*Zo$xN72Yv*+|j3+9lf!wxD$Xz;f$%NeWgxu)cczs)bk*P24H78ym`Y38JTVLFJ z&L&_##bcX5(*GB3FrW>^1fZDHT~=(o3sOE023i`suGqN_B&`7?4?7grkGn9}DDKys z|9{8Q3%-uQ{$IFQ(Oc=Ud37x_XT|tsRtMp^02J_Eb0Vtj576FoW~nh#bfMmqNU#t{ zFdfAntP_y%sSU*@kn#imNBSbDu43BMVl$LEu)f#|!9j|OIUsj!2$OI`t%K_oLl+MM zGB2**Y#1R#mO!LJMGmRoT%l8zLPVz=s>&>YtYxZnCo!KH#Bb8>G{sdgDV$jns>F0 zJv2ON6n=SrncQE@6ZLWj+jc4W1ko>!6bG|33&d=$ldIEh&i3=SnLmC0l=(IDz4`V7 zhHZFIemZ0r^C$eTGVU=f!^n>BTyf4Ju!K0Lo#5RRe77{BgpQfxyQ-w0%2SLAHvgRN vWmFQ@U>zOvC#@5!#9`t9wl8ZCwcM`WA|kbjh^T0hA|fIpA|j$9Qlu0S zDIiirr1(Na1fs<(;m&CVJaX&4f^uh4#DP<=0%> z=B~O!RtT*}fe_uBU3E=f)AYKtY@sdc2Q58rx%1`$`IXN92e9r)cs|Nq}IQnkucYp8YYqLfR-9KI!ectYK z>&?9it{hZbsIeX3->eT9=lrR``8Xem^Q=C14jQubkH&DE&k`cHOTW8rxw-m;z0-vH z=P{gjz4PWF1J3GHb*xa|AU=`a|K>Yyt=hQZYMc)e!Wuu|u6qXg#jFED?UzCfyJWz? zTL<)U{0|6oXb;Hm7n;yT6;RlWxuBr?vIK&$St$Eqjq+yTE%E{2P&p1bK~4frkuL*Zl}mx|%jLioay9T1`3dk-xfQrw zB0X}S+z0$leh2(s9s(YbM}a>{M`-FSbr!IyssXI2kU~{g)dkj9jezMY6Bt%uU{pnc zO;i(LQFsagVCsaC+>s4IY1DO`mbt{wqCs!$5*NA;7?OleA>&-4QWW)N6l;;PLS z<|V*O%`U*}%^QHXn!SN{nEilvnRf$6ntue2HlfX&Zaxcq-h3YTqB#>d$D9M4Z_Wq4 zZoUazWG(_OH&+Y8{L1`BXx91G`M^$AUtmA$PT(MG5OA?~l=Mqb%r zI}D84$bY-3-4xi&ZU(%>;kzXbwJ2>z+76+o9Zow8{*kmJ z;QWyGgD@)Tm2{v{2_;+UtV*awm8w^&4y;=V^{3LgmCgmWuhaonN!BVvW$d_Ol+7w& zE%QTjh53=W()<{Cxd^fMOS?0zf7)GX1JdqJdn|2Y+LW|Ki1i1=f+h-kx@alV;5xzD zXNs<(hv*{)h#_LQ7%ybob{)Eifw$a0u%8%w+rV4z5QF>OJgC1|EYvLn(3Xw3d@4R{79b(Fzcief07|ohB@j9naL+gt62E4gN#|1^lH;Rr6i;j!L8pu%_X`+?X z#Cq&DC|%4KZ-T2ceMs8|+D$#74cdU80UAv=bSZ?lgipL7j7u-+k}lr3@~RHN&R1Ot zgp64vT@=QF#gg-{K*(yy5iN63URU6{3kXN#ya5~?CVEol2;j8Lfxw|rlzZlg^OhlG zm8PwMt=jd59^~u~uva<`9w7v@)74X4DAUaCnNuNIBa?J4V;?KCZ=x#>p}8S~2Uu!g z*7B@6*`|Lv+$8_H?9SN>vvz`-0Re9c3JZ&cHWnA3g%NvDV302C-ly3=xVQ7e|;CxMqG@1E3r9mc?{=W zk1Ffv94PJM97g`Wkb-}Uvn-kGtW7?5&zvb9*BR?kCwg@5EgiynzBI2S$C+P}lj_|0 zAkKAW$LTm#xI0dJlrx4XXPb9k)-j&{Wl5CJcjlFrIcdGwrFESECn6f1fOL{*MM^9w zK=Fw)yqGK|PWt+bHJl#8`MGR8&P>nGY3-cn(R6e=I7<`HUD}!ATwapvtoAs`_U63h ztnhq(^<)2v#pwLqlXEV>HG3z=Ii|97gly*pAwBLEr#wy(|1G!0q58qr%=OjDbGjEE zc2+yBNy@q18SYAZh}ZPS(JEwvb0<4oKKw3-0P#-TUJes`?xj1 z`Phxsd8BmgPLI;Ok{oAK;kT~EmGtq>Prgs^G^9M1(Z?lQRmzZMF_SgcFH7ur{IYZX zc%jamUukQkxZ-Vg`7t|RmoIbT5+{;^^0hm+$7O!~5^z4H*b~OU2ji(pq|RK*POVi- zOykMW?kK0IN3Ot#J#`#OBOSjdT>DScWR~O&NRo_5Rbw6Do&q4>ipBDyY6Yzlu{AdvU?}%dM7_YAfEGd%77=t zbW+~=c`6Ej@F>LgXq>JH6~6;=_Ekjw*OqZUsc4MON6x1ex!3XR-`P)^oua%;W!Z`4 zdc0J)&n=ECG4go6W%)VZmE{9|Q_s)w)3ck@&jv`w8%4xhNiSrX$IHs}IVlh4;c|mj zD^sEZ&%vChqI=%sPpgAJmQpb_tX$RcxIDoEC0PfLa3WOx@4U^ffDpoobs`J z`*Y57o;_YP4!zwv$<518XYWZWC=QnR2BMgGLPS|P;k-s_D$??tP;|!;cJFvS0cW0b zUEKcNR?YMCj%CzX&-*kSorB1O10`$h@f0VgG*$j3K37PsiN{>R!TqY&{w1cs*+QYH zN8~5O!|5#5=Ju`>vef7%=*m0eQiUs<=e$@Hj{DT(Ka+GmN4&-LyVU!^+GWR5aUW++ z#br}VI&Y`uSCs2KQ(?*CyeJM)kEn{K!1-r!xDgK7I<&{;WJXy-A_U9swkYo%o5{3Y>Vj(--1@VPx&3c)xye0Ep4%!VpEIMJ8H4@g>RPcW#1fdPGlBRt)f(5Hbskx z*wHhzn2sIqby{GaMvFZ~N4$4zL3^syZvh{6(E>9zkVm4$7F^5?}l9-H{K+lSI z#U$~b_*VQ=OVb_|8!?aZd99oFqP9;Pq#e+H(iRz?8ymF`j9v0PZH3BK*?Jw!J=?0+ z^?h$w*V8c{Y`A`r{i6M{-UsvVcA^i}tmf#)G&K+{mu3z^jGEb3v>-&^rYVc~@Ey+h z7H}tXEcB$HMYhmMkNFz7x_ZKy2YuZ^!5`FEPy?N}AaSqI&9F1aY=Y-Vx;fJM%p8w5 z6(l!BeS{}$2Ftwz*~NHkXPEam3(Y~!Ve@|6FB|4lke`bEX*?%ZNLeTIG3O(2Uj+9> za9#3?;Y%mvF}8c&ByT{4qeS~>q{KB z;J6i1m7!-f^sI)S)oQnMSna{S5Bqo6k2;5;cQy2`hThfCyIP#ZdHsYl4fTozmX*=~Ej^85xc46P=tig4zQ3suQ<^-exH4U2DK~p>5ODOYm zG0XQd?J;qgew(v4^mSu}9z^ z#W5HDc{q-OjtL0+gwtJ3$MF@M&%?eOWwi(Ue$Yp8`~|Xw;xf!{eb?M3F0&dTe;Z>@ z2c3aE6T2UK7IwOVi*Vcw|1HkEv_s-D*#2+eu7Umk9zUlkvvujd)SpYsghFU&ME zO>8tPo0Y{Tv#MEDY&Pqe^~IOw1?B}}t9hY$q1a|#Y+fwBGJk7!5Zih7?GDVi{Yvb% zI$NE^9;=JhMeMb%x2_late(~_V!!og>(AmlYl1aF9JHRao)q6(GpuLDA#1g@S{$)H z!;IS>tbNu#@sstPbx8bd{b2nl9A7nGElu~G?>k@f`C9re)NJ3yzBbxfzMFi#v}(R# zzTsLO-x%K*t-f!ZZ=BY^H`zB?Yv`Neo1!)HZS`%{8vDNSeXFHo_N~UMR9>ZkgvfoiZCr6#B+ z)KhAzdRk3W)71;=MfHlBqh3{W)jTy{{lo2_)H3y+TB$x(tJG?>Mt!P2Q|r}6wMlJO zU#e|tyZTyvqjsuq)h@ML?NNKxKDA$crw*#4>K9dL#>~FveV8>p+I-X;Z$4#CHJ>(L zGxwN#EomvMw$;#TWHq+Ztqd#E@>^NfMb;PAX6s99i?!AFlG`(;8EG=DN?KLS13sj+ zC}>*JHT?;ki6`Uo1wu8?H}fm!*C-gCU#DPrL8pS|o~HZ*C0wKUdBNEHto(3(ll)fs z&9Jx0Z(nc)cn3;y!ReTPtPIzsph`;jLc!^G>G?;B+>OPQ$2n5aI=@GOUbf5co!_s( zSK!MZm_LM$Nv>@{X;%~16)32ef2`m-F0Cs0!wR|;^voZbKPG>CL7#&D`IGaf-h`w7w0d_Uy;A2U{L=0{LKXqURT0Z zxao9LH?g2*L3%-;SYs8OHAVQEMHoPy*8>kS1yS=9=zWZiY+lF zdRO$qsOU3stJt8~Vz71z+Qyf(VcIaUNt>m;CpK&AvC^XuD?RoL2P-`qX|?ngdJC-u zwUb&)eWLz^cBB5J{*u;>)_Z7o(RvT<9{mR+sNHLXjj;BTQD78kvy4H;ecH=d-SN8i zDpq%F(7rV`8Jo3Zw5~%dlyzhs&5;2az%UeRFmzsDp`R@e$wPWgYEkuCwB|vtjnxi5 zy$-dXdR?=cSxv8J);4SF_00xm1HFNnZl>!EvHqcj-iX>#y|HS>S}e>V^(*oyPjwDuzKiCtX@_x z{amY$)kklNwGEH!`PAO(1=eJ1vVNX5&6=h+v!+|q_4BRgtmpLR)=X=r-on~p?bcgT ztE*pZ{bc>3xAiGsCB40`wy%+Xl`q?uqj&X1d9J-{YI+6dVi|H`aoK-qz}T1rJ()@)nol@BWkqJchKr3{Sb`>x+RPeP_vD}sM%YLM``tv@i^6QV-l@fGM>aLr8>rJnJF`kIaJq;S7lg+ zjkz)^qsBa1w`9zhO=VN#H5yMC3uyI{@i(kky59JR)+!k*$u^7~v_8o=D%Z&`Wi_lu z+AizSY9v{oRwH2z6l_K|B%6_qXcQtF(`qD{fz?RWWG0P8WER#THI&(8Q8EaN%8+4N zGbGz$%}{4~rMcbwM&3kLA#a9NTrGQA*H~R;FY89DyX*^lxLw`_8yF|=x5itO<%8A~ zYnmK^+W(UL6Rq!&6HxE>${E&vUnM!qcb4yR`7T!Zj8($-XWs;MDb-!oj_R)Z4b@$B z1=U^kTdKS2N~*i66RrDESNjh84yzut;z!*~Ykkx$G}=(NQJq$Os7|ZfX-$vnODlNP z9khZ+^+PT1pzgGL*gez$yQke#-E9xB2daTo3N?+aLOlbEn1sC> zx5}@I-|=d@*{Ju!v>IIF@8=pnl56}#uJKd3#;>H6ciKLx>v}`3>jkLm{q*xthws*J z;#z()*YbO4MILH1)$d7Mzo&5hp33$6Wvbs;a)kPARHpiE)T8=sWOMy4;QD<&*YB%n zU7j(GYxWzoF3+*~ZT;n&Pe%3R-L~YD8ws5`wn(O@z z)caiH8?N`?qTZi}dvB`o`)H+}^wCN^nMN!1WM!)TvL;sQJ&rI~sV7^LCCD~p36RE0 zJ=u>|>dCukrJlSOEA_sVgXLDZKd^<2kl)DN@)5R^(QGG=(yBc<2CMdt$g%P$+~cqq zM~-7_d4ksN$w_Q2Q)tzme2P}>$!BQQo}59e_T;m)YEM2#tM=scv}#YjNUQebOt!0+ zXkDIsnbzgWciFn$rxkf}HLb{#U(s4Txr5f?$(^(oPwu9*cyce+;!T$a%o*kk`5mpu zlLu)k()t*0~dX+53U94qPinHSHu|jhTNS8#70cjhT;-jhTNU8#71KdOGt_T2E&_M(gR!v9yNHd|ZDc(&3cd zwoo|KB-AX_D%2*_KGf0E7w%a^mGE$p>yg`7X2~v?jDZv^}&L`>xOd3K2RI zI>sUUMoyax2jKLuFI**DGh8p69_bqn#I=W`pgW(63pb67F2n7Nj1D&sw}xv=65%T% z;6#R=nhSR-4&OC$DsF0I-HEyIb>VK2!I7C~-l5J9jcjyXxQ|Dj;Bii5PPl&rc#^Jr z1TH*?uq+pT020HwHjS%LEHlERB9p>n!xO_(!qdYqglC86hu;Xl9bOWCKfE%$HvD;H zRd`EyM|e+o53Ig#_+a>GxG*9kX_0D?+K~p4%t$a2ixfm!MlO!D^I8Z#dM$xxwaNBV zx`w-T*0a;ZI_cG^cEs3U4GA z*c0heF&9lwc7cQO^FaSVVU7$8%1O(qmQy>YLEwSF(Ln!bdPy!q)FYRZ=^j&Kq&FnG zVh`pl&xz#}6FJGa_d+hg=g$ zaM4m*&N#4|C%ee_@?Fj(mT40?Z7ydK+|-;IIWu$S+Dm+(rAu zX^+YnU6zYfj#N(c3)XSZf{lV%k&e+$ksiTtq=)CC{ew-SoyvBR-oa*p;lWnHHj&=R zF4`&BKH4qXE!Z*Gk&e-BUfSpwt&(`=(!pJ+^7?f1VCyx4H%4l>F4!a31LfY2T(CDB zQ|`Hk!GV$ExZsfBu*i_ekl;vvCpsp%VUg0VPJ~@>jC(v$j9wSL&X4_MU8GTPd;~Qp zk`>7cP9`jNMq68vJJKP|$CcG-rCY%|5Gdw9A49^J1{GR;S`h58Gm&>I;f^cB?3`{#3e?zP)!b=^|*+DWvTxE^+1JC@Wh zpe=FRjd(lZwgW}Bo?zo_cd$6JG}pRdLm8vd*1PQ|w-=>tJJJfdvI4o$24j=;xDK?H zs9nW1Inwd?`Hykp$jBIsj-t`F(6SJ1-Y)bk&qZcM=Ax8dhwTNxMGuR3mLVp@0?uZ{ zvK^A#GDi*|&By$+{V(`uM|D_g75{urK~3mQM_xx!s?DRVqiv&CL_7K4fM2(0&y3OL z#K@?Oei_XogECr021Q1Z%jm%rpJlYlXp_;th~F`zBU6JiKxK5vxX}%fF)(9D#;}Yr z86&Ze&zKBdJy=g~;2>x(=}&RY%9xh%T*j=}3t7!#FObV>MVPmUTxO??*E8m3yq?)9 zZ&AiVaF%8)&RCYQB5$edV$CBjM5d6-OwU*onUb;IJ>p;XLC& z=855Pq;o5ploU9L z&B>dS*%Pi0j{UI@B97}ahi8t;9Gf{Yb4up)%oj3eXU@-jAagimN^l`PGxH69HQ?LW zkFr~mS(tegXYcdb%DkCy+wx}m)BM%^X_;#?KhNBfxg&E==D}c7NEG^|KMlUsqMiK% zqMgb4yZSS+*Y2K%17<&glNp|=5^7o~%{-OTC*x~X9=MDCc z@Q>i*=wLdIZ~DjOy-62sB!tTgw zl-0=pQ#?`9juGX#Xj(KaYkSrh>_f5^XAR5RP8{O7 zM^Iz3MtXFSAEd!wjD39GoUF-tbD|Bhrm=f2YgV*D-h!;TS+D0UAQxK#&D*nm31KNNNh>;;%q(ZShk+6M=$nVtXp=yXxHqTv}gOW zt3sB} ztD>s{BM9j{I+Ps3@iDundo0FD*<+)Vq9d{gVef;zzk8Pb0FIs;K~(ne>`~dHm`CR$ z5N>udm@dAC3%UuJU`;_O%`@xj+v=bE=N~I7O;g*eufzg4{M7ts2Kh6!| z`Ik6$4NMBm%xMys8JHTF0h|+ygttw?=M_ya74=at7uN$Ze7{Ik!pP)SMwXV{*pl48!@D+$O-0 zM1cd}oM}1F<;)5OK+Vl)LM~@v&gQV zvQnI5K|SaTR*6js)(qAQ){DInOpmRM><9*8Ysm$pvA2Uw^9Bc(#HQpe3N{a}4YrQG zoj0x`F4#7BMS|SUyq&Q?uv4&89;gI2Der__6G1L`oqJ3~*jUdZ-#$ThobyQ~6daV-0G5;%d;o5Ea1^=N*x1rBCAcHFCwMT_ zE_gIp7?Pp1P_JaK2>Kf`E>J{o68W0*B8X6h_H##&f zG%2(*G&M9MG&3|Ov>^0mXi;csXgS=f(7MpZ&^Gw)3mppm6c%AKTsd4LTqoQpoCOyS zHwiZjw}NXEZXfO#?gG~@JTQD?xJS4*jzkX(4+#$oj|`8=8;p_Jj_~-%72yNn&Ed)6 zY2nwy>%%K>{#UW|QNcnxq3q>jODhTnGh?Lzn?;bW0N zq*FwXbc^^RRU$Pb^&;uuL?eA7O(V_0ZHv8iuY2Kme^4d$Ht8(X}-CgIlw$Y8zZQORE)r{_=J$fjLRxx*$ z*PeMtv_ocYWwbtZavSAl<%ZGDG|OnxMC2Z$7;; zcUSI#+#|Wij$cZ#=5VcJZDUu&I>oNT$f#Rh%UI7?pICqN$q&Sa$41qDJ2o~iGd3kQ z5&M+bbQ6_OR_;p3-y)$(fR zH9*c~<^}U&u-2A&7w5Ih>wxy*I&iz@bGW!srIiQ1dI zsdQy%MP_2uy#S+E+*e@ax+-s7-bUo(&b)o-iGOM$YIkd5HmTgCMw2>C8a2sk0>i>g zic2v|=rJKMi*$(4jXlO5Veo8Rsj6W%uBmFNT9_$L-{VbF4OF_Qq%xHsGpBP@o~WUI zt9~o$t1H!&q5;0UdzEOYI;+m25oVtD7md{rHAF{zG)cywt_wDz!u{ z5uMe$>OFCd`arD^*I|z825}?irtT28Vm|7AF@WZwiu*7V^{BX?W}}J+%uMrKG1P2k zo-f9l*OQy#yY;nL zgSo78#9H56-+b}8Z@2HD*km8H4~nm8ZmZZqvs=YZdh;%JrEN~zEOw_I!hGyKG{=QY zr9PKR6E2lBluDt9V$Oww+=ml+JYTvYmryk>p=KzdhA4?f_-=At%mr>NB<5kHi;GZZ znc^JfN69rt$>kvTgDMCP<_SYGq9USzzpZ?Z%2m0LiK!UMBM)WVl*`!1W$fcJ_Mvp~ zO0T}Q7>zAy{wLU`3tV75Vi9>)K0%J%`7up?oz6y`?uykeH{k2ljm#U(-+}IC zb_0Erc@yaFW_Qub{Jr^m(ZcM3+OMPb-wy1H6*w{e&UHPugp1h{(qRdM(GA}RduR@O zxL?#WAAnVy%T`g7ts=ly5oW8%Wvi$~v%9g%N5U#Jwu&@ZMMIHBGrdJ6%=OL^k}X8S zLcS1|wb9xn6lQ&I7F96w`%6(7v%j~1-U|Dv%=Tl$eqIu1(R^@W`DXiG5z03Q7G=Sr z=88JL`LHVmyV@gc-(KHdQPsE4w@-w8`+fUCAMhOj{T-~XDqEd`)fu7^W|d39Gs}y< zF`dS?SB-5?!uFnG+cWfbdOJ~7zYQxp47S4pwnLlkFqiERa|F>wT5Nj;+n&L;SBq^A zmIvEw&9)a}+pB}Q`2kUjEwC9|V2rlL7FdTZuq9hyV{TJ5wmMzirf5YK z*`88;6}~3U7O1N`6}~CXcBs@n>K<_}TVqYO#zt(7HQ5>)u^m=t3#`tzSDkIoVoSS_ zEzMv{i>OIxl{MJgGl+{UEy``P#`dNvU~iQY?9B&zdl&u5GKDWdC)is9wzr0CZw=Vq z8nV6V>Jx?Uf3wvowN9-AO}3}24QTIO3)IyXwG}kkp;BKdT1Q6KsH+_c-&|*#JezH@ z8r!5|o6KUHwAd!I*e1_ro2SdZ;cvK?N)cG#TlP_i9Lw!@}uhqcW+&Hk|Y0r={Cn60s{ zd9Qh|sLeJRWSczS9AXX;d2Ed}*cvn08iQ<&P0Vdr17w){%mY|k_nmoA=xmKPTcgd^ zXt6aKR&%SlIFD`8V4L)@O`6BG$w~<}>0_HT*(QB#lQn(wd|1cFmTCGH_!bD0?Xwcw zXExhs4%=ro+h-2jXMpX~~q6Bb@;)dSvR zZNo|!`qr5COG`pAi}63qX-4S0OsHKZOf0%u5 zV!XlhK^xY7B2>DGmd(h*`Xfz$h<%&N?%CbX%X@$L}4<~K9-IXy_s$%7J(!9ihf~i z!B^CbuZ3%lV*QHNfoK>Tkp}t-ji#qFaw%xrnLdY5qxH<1dWq2di4grCApqEj(BvyM zZzEben@1N<5Usf0T0WNKxU4EnN7?s!My&fqDEhXCrf*`z7cNkOof$cQ@YfFF3??*K zr|}NaI(?B+(>Jp3R>mWQ=CzD8t6D=(55y>nkS$2wMYP;PXq|8T5%&ET#5W)GSz20!%?r^WBN<1 zb=LHGT;l&CwB95A){7eHywgBWD_81EaJ>feV}$A>LSG-g>b?e2XdU2d{DNiN63=Ey zuEW0Hv*gVz`3+01Vc$C#uOyDVSc@Vh+(t>ZQ}qLdGT0V$EKN zT4pddBUEoOPGeli{5^zP9YUS2&Ulk(gDt{X#5C7)gDuG5645VU`8Mq9hH@?CAHq;#1WjgqIu!e;cehtL#VYUU$lc1mTgn}g6STN*@bAs^*f2ys}dTVTD>m&e$O0kNsLiUb2%D6 z5Us9byovEaLis8q+Xd{3I2xf|!1#AUZ8IZlkd2u?o$*~l!SoEUWraLlT$hd|vLa4`> z&LETnC^wAm)H=!aOmoht4n*U53}IBDZm7$cKA*8QV}bJv_?HyPkYpXArQ0&(6K#CQ zzV#W|QdC=}*(&iIfi!bX#xnxaz-Lxb!sQ8;Y?Tq4q6HvMuXw&0%|?=Uedoo-KuIpneT; z(DDKWw}j#?mf6DCj`18qoh@4DtI+2&$IrfN3$KOFy-as!blCSRMs5}LiA?{EaWvyl zLbZ|UA%q5N*1o5nNU>#UhuN2{8-M+RjK*!9SjhYz3B|ve{ww2?l+U_rl}(6)zl4#@ z8|>>N#ClZXyvZCcLBnks)>Hehf5Cn0^MuAG>tWy)>o35q)?b;Pg1S-Dx1N1rHL{v- zG3a&HO~8#bdNDR*O}%Ek!}Ka1&tx)&7%wN3_cM+sH0w}UGm~P$y&Y*dY9SWm2acCz zz~5I(U$m1)s3Hx?q{0pJcgVW5CMpx1) zbD4jL^&jGRcX5nAGUq6Beq`Lw{H;uHW8W>Tjju&DBR%RI#yX6w*?gR6a{=QMjIXip zSByUq>Yp%HXEf;Qbd&V!7GLkx#FrdOa$NFF=6uR%aVV2gr5)oG77)j1#e7LA)IVgM zD_Q4ClGHyY&9WtHxQY;80wDZ5Bd13xrW+9IA91Lqtp9!D$QI0BLHgw&@|9ff#v-O! zn{IF@$@0^gKb`Y!KbPP^;ur^+Gmd18k6Hg`oU0qym#-Q!RO^m$Zv0I0vI&>|QPy*e zH6I`iW+%pb8Lwv?L@58m_ywWy6X`cwGkq_|axd$Am1RC>{zJ?k#xXv`Ddh4sIIoP6 z>^qYA=d=83PV)zx&b1us6P9_IeZQo1s>;MsX(S1nYW{l0bsTmL(;xE{tzwybD6Dyu z@dw6>S=$=c{657ccM(V3#Qce@VIup+=pNR%+3Eni)xy8ojC1Mk)o4O@yGBzp0?eU% zVI!CBh4p>h4&>2&t}GzFY|Ziqxs~Y5`sbOOA^91hQIo?qVr`9BvN7wdPuh&m9Ag8% zYo2Rb2=xcX_KcGmpRhgx|3^ZjG3#l}dTNnoeVN47>FX$VjoSwxa!fl+IirtY{#$$( z|2oNQ?@;X8K<2+q@oI}mr?!ptd_;VsHgWXVSmtNSC5^2~XPedA@HKLshaHjcT@==E zNM3fNv;isivRThw)>)UYw+81%L(YK)EORyIfT6xesLibB7QVV$*tZUa)xTmK%@|_5 zn`HEXq({G-V;Rfo|BCrvF=rx4YC9F~Q?y}Be@wJq*NOq_SlQt3B3j!?G*XM)F!%|B z(U8-b!|C*M${UadBfy+Y;^-@wQ;BFi&okz5${SJ2^)Z~o|DyDxM&TN@zcc?w z&L#Y84)OAH9(@6GZYR{gXWFfGlbDvwpGGL%=RB`6=K#JHq!~|gyl*qMWo*oNC1XBg zjFEdZBa3ML918^hJ`XH8hjqzE=Zy4t?He(!4D0bjEmZmLW&TK;cQl_6| ze1mZe<6+XQt!CWB_$A{9Mk`7QYB&!Dg-m!swOP?xec9=(`c;-;UTMw;%Jfy>&AaH#Vb^BB2Sm|SDcvzSwx zQ2mAJFeCTZrk`l*4(7PMyxWg7WzGeRoPK;;iQ=utoNPv}T_#(Q$yaS=FrTl~ltVsIjv;F~04`IBATa|~I9>@46l2I0E1|pPP%%MKvxIST-kC^_5>Bkw{vCJW& z^$!?FFsBJydW4?_M=8gQ*(QyLZ{cUTpAfB&CE94nl66?JE=lTc`*7Hr2Vc%@?K_HB zJ4pJqS4hA1Pm%XJi_=- z#-|w<5aL@H6!v|_{hS`o6a7t&J%jNaLVX+4l^8!~e1k$EPvEO<;&lE(D0?y8p6Qj0 z)d-F1%pb=&Jd4YV$8yF?OrOixf>00e^-dwwR&pQuS3=`5mSO8N9yG^-v&@GU)fmF` z6%ux>f6ZYJ6B_(ZLEpoiPZ(b!)C%$bSJU6*9-mu#;})*@Y&FKSOuOUc8BFhEWUDmz zj>#BBDNzyP%dzD$Lr=z4$YNo9vOJ2aY_K;tp}3C721RIJYjt>0Ql;2wHVr#=hB1EMePloPi`d{Qfs zl|bK~Kqr%rB%hXfMo;C+-{?tB@4@ae8>($$yG) z|Coe7$l+R??cP5ULDLhHqK*DA=W?9k#k?Jf5+2t*;*X2pdjFRrj{A?flz&K~r-!`7 z)8}!@Iy#$*LbNRJKMC$Pxm_%&jsDtDr04mPeyPs!wc-8VKO4wDwbta2<)&|TT;BbE zp))J~&2DFs>zn*%L-&7?-j|OP|3Mkom0WsBe0utquqFQyDAm6xi-hS}HE;3sA(nX_ zmyYx|Q+)3n^_Bh$<*dioMFr}?Jm>e$6{sr;e?Z+Dm-lLqvjtLk!iGOo-pN`hPm1fj zvycAn318SC{o@lD?YG zR@bqZI&(zIYf6eP9c?k{Cu;q65oDiq&mXPC-}$@S#E5gLXQlTSE~mOjIm4+naJnPZ zCTPk4pEqb;>CxViC0BW8Wgd&{MqCI9H*F*u<=8XOuf`K%2Zr_$i3DQ9H|V zBc<4i+6d1#>Bv2X^BVU8-EnO*Od*^nvA0H><4Lj?*t8RIalCVIsP|plBdn-QMl8k_>44+LcJKnTBgK(Jj%@# z=o{-y^hOs>9)|^L^yZIJ#r-)bv`Wr2uWj;<;LZ2+fi9}&C=Y+ckByO(mL=Mqj+FZVuzViNCn5-pf9Fgo*-dVOMkl5RMyc0YYkMPP4SGvZh zlEoj`%f4gc0Pa6`lC{x)eB90Z6HP_0sr>)>c$&RqdFk`yPX9693Y>o3$Jdyg+a!xN z?-nmis*%65#(9C|itMjg7A?rBZeGi9;(8MAUgI^yYptCN+`2`2v%x__UmwTP&AI6zfi8R+y$X!E4v3_4C>YQsDFyRnZnC+^3doAGv1DjcZ61ZKB3x z|HQT@)o8#8CdOS9)*J63t;gFEM>gL0f zC6+~ExKn$^lBkL3nKWeo_=;r>SDcqzHWd$7 zA<6hth;l}~71CCoP;ohxCrHmZi?+%h5kIDClj6SKn}!4(37-Eg(yj4s-&l0tE}V|I zvmR11MTzB&mL6M?eZVRcH>WK>5xxNaor#b8W^9Si0r-44A^1I==bhgv_T!|FljkfhnM!9_ z{Fzy5dn&FEMPt~~I!fxS_<6DJ(m|Sfta$o7PU10M%M!V$#oU)9^HQ8qFIHSnQ}~z3 zDlb&2zKJv)_b#B!sERy}V=vd27xs+$7sXz7`kb{CKSrwS<1+l@)CPB*sGgjNCmK&{zW`$VT(K=d@+SOWuGEGP%`bZfePL5q(-73!?v3esH=a^`ioCrKyMXyj^olg!^be5#ai=njS3FuDJ=xR!Q zpPQ^3?=!IBS?|xueDG4o224 z#uEgjYhgU@;;<>ld&&KX`~1_n&e>5Ms+jQRI21FEL*UK?>ro2vC(V*V$xm24-wO5< zp7@Cz$-dKz0`w^nkk-jORKz1Wcl;gaqF+_|WG^wy+K zigJ3yvEn+M6+}C46@CmXyY4k|Rv=wP&wt{fL8YjBcvq9^O;u7b_ay!)P{GNZSZN`X_MzM@fF}R8-Tv-Wk2;1;YP42XeRtmFc|z@I4j9Rl zB^TG8S_0#Ub_iYBdq$HW|8AU)Q_hERIyF_sdw`;GdFoUoYD#>U?>;?GHP13J1kz7^ zJw|%T+%tYweD8k7V>(R{lzd~9s5Ws9a3bHMou4r)khl2V4Q3KzbC$S#rvDkIQ&Vmj z_M*~iMYJ8H%=#0&PN=YR%~M{ zeBQ}+Dd@#h!;+ix1^K7)iA&NbEIzv!PogR~DnqE^xLs{-+TxmtDk&59#r@GTXKdk4 zj3>|H_UJ4~-&4AUPUa+^#kC=9(x}(9XhVb8%M`ErK!^Gr>ohmd&%QLZw^Xn zE#-3xQ#?1RNczgxTyY7vO)RS?skk1L5RWrTYbw9hJ&{-{B3smQUyvy4tp!NrRg^AV z<39CIl&?r#OO!uV+8z5Q&R0i{Z#q@2|NG%nKI1KsZ1>qk$=1LViq9AGICT6k)XI^G z@t+c%b4sDh2wdLm9^_a}H)zq*V|udC!&8>r3l+7LrPd00((&V|mP5+t5hb6-#G^~1 zoK5Z;ktF6xo}{`%IiYJS(c7LxGO{sO?!>j!KZ%%5SC9&p)9H%tSJ6{}5^(E9>7Mdr z(|7tbooos!7Oo;~dBrsSno_@ZPk&~w4eQ$;q8KozcP>%9nv*$Y#akrLZ_=F6sieHQ zbFN>>rwXY;q~f{p6zSl5>O`qT-$Z^1+Mjry*#4$|2XT6z4<^Qa^0fO5!|T^d-Zh`T zd6p-i!vA8(|IxK~sdA+BTg+5a;9XV*|Nqr&=f{-EuL~~ir+=$n5tRw^)GC*jPdzuM zSnmI1ITc@B#famTU6l%{Xjmbs1fgpa@x7`Jt@VB&jySA-=Z-h=5CBF|C+ooGn>7VF1mvb0j4oP?;M0DcJr_@gzQN{D_ zw<1S;3#eiBIz2PCaC)Bbo=nQU>PlfaB@qGW^<5$woPA%o-j$!dn z=2MHI;-QbXrmNyw;*zQ6vBZ7|%oF}#ArzHyK&&6t5F;$|CD)v2TA|Zy8)*;-q zoqYHc4q5hEofB5|KNFy0ci&|txBRzz{G8$Jvcebf6a3?=t;z{=(%xr2hLcX(aRNHK zkK_4kd+FjSp$nRS_pEqdOcu+z zU#|DoYw3OTzWRB3KfOPs2Ixce3-pKexq5qjKK{BpL|>bvya`aFHF zepr7^|G^093yp|znZDO(Z*(<$#*Icdqps22c+zNK{2i`~@egC6ajo&TvB9{(*aUZ< z@ul&tF~rzy>^B}UzJnVrE6eJ}qw;Lo!1%LlBpVq|$qX4WrplPiGhUSWvWxMOyiQ(c zd>|i^4;jnl!}4L{LpehJ$ygyDm6Py4x5@HdW3zlu?vqvI0eM(9lRwCxWh?oMbmS$f znyMk&s#>a+yj;~)b!B_iKsA=XQJE@JUa4|aSawuV6~!NHVk%EwqkgM?E3Z{osw?Gn z>MC`Wyk2!yon=>bi|Q|LP(#!Zd8>L*4VS&u2sJ|XQzO-%M1o{-iJSm&5#e_?{_caUwN;n1#-Chhx&&ctrn@p@=>)!EsJmx!P=MHkE740<%DVVm32xl55Q#W-ocnyv@8_Y32lTf|BO9=3b>N z%~JTwWo@grs%kZ~vQ#yzxz$3|u`aSMQuVA4tq)aw>mzG}YG8d~ZN(prw);Y=i7(Ih zfEw%@>Km?>_{R7iSMT}$>>IB>^iB3nRv-DE@;#$g`u^&BL4D$z>6@cA_~!cNt1Z4| zzW3BuzAt=VsIPsSeBY`azTLiq>U-Z0z8}=jJ~(yEmbO&C*wyXos?e@)*H@06Zl{~V z&a^X4&Ca!RP2JA3^Gw6O!v3u(?JMmoP1Ejb_b@HHr+u4Q&F*XWHEY}b?SbYw_8|LS zvw=OtzTa$Q53`4v>Gp7Yl$l|VwjVWv_Mh!Pn_+u`{iGSO|6)I7HnFGKGtGQ^jy=b0 zZNFx}W?p13wLdm5wm-2yF+11??Stl(X-1kfJEm1ht7>*iTbs7l?3}haZL@hz+Lp8} zW|y=>X@|^f(~hJaF|QLk{_3lXi?Npc64730;y28AeyZ9Qo6ApjmgF6Rp zz%Kl$DNU;)!dg|WCg@sPEm2jgt(^zDnbu4+(9YK`27QS(SV-+Y?IF;^w1+_t*N`f0 z4F1YoOB<`(chu$Cb0DS=PZhas)_vk|*|FHf? za7O8)girsIK3Z7%qxuAJChC(!b^S^GFT$@+(Vqf6Ri6sqr}bw*PuKqn{tW#&(9i47 ziyQS9^cTQ+QGW@XS^CSOfj(P*1@d$BIpDmizY5>E`drZS@&D-t`rq_7fd9}JA+C4y zcSIw7vHmXTW%@FNdQV>kdbPe5^r!kJ&|m6XkPln+ZAj-=`YzDB_1)00M?VZ2?X1wz z&PISy<6L1FO^tle1;+WHFEB0xw#Q$nD;w7vUGdK@w8FwdD||b!uW=7JgN*xx53TMH z(cQS;m<0Ms<4J@<8!gh%M!yOCr?F6Epr!sdaEbA*Xk;ui)`P#n*dP?O-JsESi~7bc zV>fi}G4_ZYW3RDSNVMhq!9i;d`g`Mh@msX%l|^HDmaKyReN~gyM1ia>tBaaw<w;5H)ju)1kASXfcN%|;Ov!qA-PZP6V=gE9svEF{0@2!%7gIzUVaY^ zhvXs9hvi}9z!CWa=%eyS@PCrWApeW}1*t8Rh2m=Tu8zp3{#9gC&njx6XKe^?HzL(0w zf9u<-4yuC)s*b87u#@TpM1L%*p+D{|YN*@rKfr40c6Ga`tNNmo52}NZ zIjW9A=0|l*G*Q2(UrRxzu9u4+~V zznWQ1++bEWtBY=C4fAYpYMQmgxfs*bhRiwUIiTy9bwJlO>w>Ol))O~ltW#g~HXE7^ z#c#|;W+QQ%+1P9>`k3ivIyfOSEG{zh&3tizd7gP5u$g(jxYTTJHWyvY7G`Hr$-Ktw zD(aXwn!gjR&6~`dK>yzSy|{%&NT4x70`@igitA~dB(5>HncHw(`^*EPn)#i1P}HE& zlE}emsUfhD)mUU(=~kAgg^^Qp@p~FMfyT&5NQ|7&+FPrw)#7YxjkOl^r`9@QSf5#+ ziOSY`YrU|n4Ho)wjIO>A0c)eRNu*nwt<9pT^`-Tt$hEduTR?BMwu0VneJw)P4r{ki z)*fpwLhZBmA(s8tVbDjcBcOk^U>%`uxtEc_vjh z6U}70#1fDpnJt1cN9Kqe8I`R>E7@AM5$Q5do*){_cJf5g0z0p(2*_@-JHI_u_7SG+ zEBlI=JYAm7c0bvl{b$NEMN>IIdZM+=muIm(P!1HC@)zGY=5Mfy=OS!t=$lq}0Ws>)5$~kfld$2@_>ppoOaV?Pdv;Ba4fb9q6gCZm= zvm&@5+AyBsV8_J1n(i4*01xnGD{!;Mu}b7BJrq z4_?UrkwML_lFJnC}IF8?59=x3G!e9~WD}z^Z z{8hoLSWgO0;#XG(CyT~d&r|ufI9N;w(}UCb_S)dJY-35Yz9~3^*l!NrOzbm*x3WDe zIE(e|!P^NR+gc=HTi?a`&kfGyn0dkZ>?seTR1{*i`lLWR*LN4lHd~d zJRDp~yjbBJzcTnZ->wd>X8+nCsU6%9d`aX4Uk+jw2VV)k#+hK9vyF8wqRKiKCn)P& zG*{L++gRtKi?YszRMxr3P}VtivS~KMI`56O-3J@p)i!ztHoDJSu7 z_4e57H?ZeMtoAnAY7c9x{TJG54`a2LV~gL1?Vh1+_jGLcM?@p6_9`KbM~z3tMaDAY zk8D40tQVb(7qI4~w&r8nnm-Y1ev4>nY{jN;iB10(k)rMR*2Y&@@TRulPsW1JW;+Kv z{$%WU)P)*v5N#M~=q)Zb`(w>#s__Qa%8obGc!S7eykP?CE6pqU?L;j2v$O?&78d-~ z?4OJsZ(_$!5xM46b1Hj^vFUTM>1VS47A$)Q%l`=GY$ z1KP3=YRmp4Ec;3k)HeM|*z{FwKZ-RU(AIoVTk|JrYd(lI{}kV@#*PnZJKn^OU&Hn~ ztob(Dnh#*jzrgk;Z2D8RO&`$Kyoojc9%r~4n?4tt{v*zLuep~aKf%5aX#3t|9OWSU z|BjU(H2+~9B4xfZzY;~}*I4|9w)pe3#cyEocg8O7g595o-QQKTvASXXCs{qL9w>p+ ztkc-j)9T5#(gR6a52R{6kbxe!NCX&}8ObpPRsq`=TNjIytBl)v88%#Fp3eT zE~2ki2r(1_{hWO&3ZaQs2pL)-T&5MmXsr-ZwKg!c5@?~7Knq(bffiZ`w9rbxw#)1? zFpw|b|EFr}{{*c6*SMlh z_9pE3*X`HQ8=LLT?0Ewv5JCxTW&6+QfdG2oEw9A;(mYAru#MxR)4Afept=1Br)(=-{{opw#q8|oo<=|<}aJAM9g=!2>oTA3? zSTlylT4{zftr?nW&5))wLsV;qG_4t$Y0Z$PHA7UZg?z0RhH15suhqgZtrq%gwQ#0Z z3;nfPI8&>I{#q@ZsntR^=Qigy;$>WrHRFP;m0FnWD7Da5tA#FFEu^6q7GmW;fMzJr znjxw+Lz>nMQLPzzYt3+))(kzhX6WrG&2XC544t)RI8AGYj%qX!ov;q&&_OGQG_4$Z zYUSW-m7+!%D;1N}SgANijg_)iYT;K}EnKSALSwBKng=cnTqw@dnxT1M zWMCxQN;x#wnxVPY49&G#7{jRQry?z|FYp-_zu{V_1>1GlR+^!U)(l;=X6U9hLt8c4 zDh6rI&{k`PR%nJ-M8tj7eO2VRo6rwotsm0S51T~@{qUwR-L0sIB&{M+Q4w#6fYuKk zwSMTJ^+Rv1A5PQyp|{o#r)mArS?dQ|>xT@jAF|O82hb#cbq}IO{*IRDse3r}-on$uZLTYsp)9T_xtu9(> zb&;agMQg1tOw`4x*u*_i7lu|Bd0JiMYIR|1brIC+;w03?KopD86#;a`AZ&M~D@=3+ zwyzw4u1M0lB30{(fYud`))mQGSG3c*;smWLlC`eL)Vd;wuDDL*$s14?0j(}vtuC^( zy0EmmXsLCDrFDg&b%m*Qg&`NBD@?5`T4-J2XkF1l>k3Ef3Pka2Bv^m~X|EMXwpJjGv;t`v92*=< zm`Z_Uqd+c4OE6APyc2^HMPIEwvbFYTq_sziRvj(1>aeuxXsK04OUCa}fM}1KIk%a? zTTlhJqCG-ddl*`K*jjreYwclZ?UAIlM{@A);N9Y6M*8pNS4xK%T8EfghZw^PQ zAtz`ZVxU7F7F~l&Q6mwpMv~P%0pfZgxIx5FAg_p)T6J_lby%WXl8yFgtF=c|YmY8k zd-T)V!_nHKtuT6hiQ*7W&qm$m+M8;-RM8>M6e$RJ5lUp2XNg4O!mh_3o zIzGAo@hmAT&I+BoDP={{&LjDj+$OnA+WzDD^$#7Bl3llqOUX{3*!b4^b4;I@KC#i# zCX4F-Z}8cl^3}g-Ap4t~)yWkp{gc+K{~JG%{Y{JMdTV!+)abM(sp>oRtyOZwK z>07^*+@ax;GA_A8%8KM_b%jamn`~jLzOLxcL`a17?YcrfP!sENBV8t~KSoNE%IRCu zxBO5_{O8}LWH$^W_nVY`dQoSV*!tEwd2RhQ9p7i8rD{ppn)v)l>!L<1$s>+l)V`GL z$ZqxdeM?F8hn7H~A)`qH%iC z4dj|ihZRXTB-1+8rITuX`!|}Y{!7~X}rqtBscmu-PL(P5=SR3OrD$cb<#qXC)Cm?Q!Po`66+3=TfLmLm}Ny$Rnm&& z9*JX;=bj+dF^PpxIa+Ner#3PbDZ^5RvF@ao*(tNzR3T2zQFQC4!cFU$h^0QBwE5?6 z<<~uuo=z;ubDJ$oKJ?#M>f=?PDGMomJy_-*SsD#VO`?R+mgq9KPp5IG6t3Z@YinSE zBy50&eZ2}pg_2ml)hABVW&CijoamPt%}jJQs*g$ZAga&MWu9DAOQNi)5EEPEWp>^7 zw2t-dqb?tbc#ryB{cre{ZbcF;#xcrlUF}ZPV^vdWZL?LZiC-koY&=@kOI4ConEK4d zt8i3JQJ?iWp3;f*ot@JEnCVIBNP0Qx<>Z;omc^b>=cGz=qwa*ZPo<7pbp4-}v^k@v zjpYt57Vcx%09~R%m8QXtRoNc}; zI?KO{vxUvP5KpBBvpzh>#BZz3_n!KmYsljmPuR|5wZ%@nw%FYXyEr@BI-t*8U$G8V z9aF+FB^*=2F(n-HdF|bHcI|eqVpq`StZd>L#hI1YU3npU?jhzyb+PZQeV^GlJ8Nr< zUGN_4*1t-e;rJtGNXQ)tS*2*X{T}ISlNLp!MUhG?JEblzzb*xa>NHWu=v1!D3x35` z+@4cgY~Neki!aY{k4T?Th?*5tnZcg`_jEUdkqP;TcuR*^@=cC*?|TvH(<)eX+faY?aP zYOD1b21qfLU!zFFO7<30TFL|JdCdSJl^iY;YibMmwuUP&V4h8KZQT4P$E&ozmA&gJ ztFLgxN9374f~!30dib_JZ)^0m1yve2&l1LSe6vQC@Y))8du^qxf=6LFC6v1n;x^9k zHcHiPuD&<$D{Hl~+mGY}nepSk^c>BV)Yqm3=oc|pq z=?Qp>lDwYWdrOtOZ~pG=z=1tSgw5@ zZ@v5#<*IdlM)$nZXjil_2 zl$aaq>pv-aBQ>*-nyE_8jil_2r0k8<(n4x!A@>L8a<=neK9s|KpsrvcsH>=ehk#yE z)m8IhK9|BHupCwhj~QAXvno894`;!(q*lnts4X?_hlTI}EP@B20v>|JPzeviQh0>6 zA`4nU9(1cMmFYk@s_hJphDo&YD&%rPE+^!2LM|udazZXAG5^^OWR}yk1Ay*P|B_UT5awQ>G z5^^OWR}yk1Ay*P|B_UV3J!nnSfv^a@lF%y&y;6rBC-gX>#|b@7=y5`i6MCG`LzdrNuPf25OSA1Kt7EBfkp` zdS&B%{@(*1z=!ZD?1R5h!mwIoTR5S%CU`X{`=t3#N%Q*N{M%{IH5@zrRV+oMP!TCq zL<$v=LPexd5h+we3Kfw;MWj#>DU`4m9^tdjW+0X#QmTlQDk7zdh^2^>Dk7zdNU0)H zs)&>-`svrAthnR97TtEWpywWl{r4sOv$otShH15NYkF-*>uI(()Ye$L_lWDcFG6}WZ*}(QIwH=)|Y0>NKl3+_> z$<+46&rmn&+a+y%G^i)aMmegkWF6Bk7+O2txg5qr5nKuLp#s*!i(JD?@Cv-a|65=y zyal`9J$N5JgpX>+2lm5X;6Uwo8Lu5LvcJ>E4Xs^8jH`%o6)~{Y~GMeJ3?UPbIx#9l@0 zHN;*+>~UhRBK9g`uOjv;V*feH@X=PmG0XC|?F(JDqdaHO*|;AT!UM1f9)t>b2o?j% zz<3yz!Xu(HGrc=AbE7jeyE`*ayEA?7cdfM^%!E`HTRK{eI2u}R%$)1Ye7DZbUSqDz z&((61L*H+aHOT*Cw(zZuBzhf`2DuS8c-NNEn6~RbZCReBy-Fw!)oy)XuEa^3IJQX~ z+a#`YrS*@pxaOko=D~a@hx_1uSO^b51v~_c;bB+`kHB(R0d-ayc8sqqHEbClTgJzh z@v&umWJfqbm~YAb)<$mqEt>z zU_|Y%z(sJE7)2eap^ns0N0drC%Ic@i)S&i$rrutc8EkE5B^GPfg)%QJ5I;#F}Ev$nh{a`U^_Y!IM5@|Km-GP<#4rQsT zb|__Ps9eVOW4de&l`HwIri`J_ng925o$awoM18MaUn-9D-l{|t98ZZ*J$%EGpmYA{ zvwp6&;(Kk2=W8phKfzj92g=rX7yDutya&7Ceb@sZz=!Y=9K!~&U#_jNUxD{wPi@5y z*(7puZH1fy*VL|%(`#1*D{CvhmDWH0td*5i!&%pG)-{}U4QE}$S=VsZHJo(~XI+Ek zRMXIM`iW;R#y;ArjVe@FZM)Rw48}+nBLwxm!m-ld z;|l6~iX*Bwk^Y`e|5J{;ZFv`~Unzk1pk4*+VfzF45IzFN*C^X+6!N>O;P_g|(xY0& zYiI?h!@p}GyD(>2Fk@Nhaoz=d){XU=%h-Ml@M3Mg4x8Z(*dl~A0xp7)fd4z@?+R-) zTmoa@QWy)D0lsgo%V9k5-bZ^5@N77|zvlF$%jFg3?7ODBqy{-cEc1!-o}m1jOM%nTLArQY=u9=HpY(_VIa@T z$@6mZyqr8QC(p~t^K$aMoIEcl&&$d4a`L>KJTE8D%gOU{^1PfpFDK7ek>_#7&MWnO z0<0wRzJRhX%0)c*3j1D#*BFU9=cqDrYi*55&uY@M9xf|W=}n7a z8e9YPh}N}m9sC-u2Szfj8{kGLft!F)P3vZ0RMTQq(;{r^HkbvBY+8(LT6aJxFtTag z31xu&Y~2NOVIE*L9UdR~i8jj*+9;P%v&I2-yc`dOfGsbtfC+$2UvIx8VR?x2C|^H% z?2huakn**V^0m--sdl#UGQ0w>!fUVzUay^Pt)hH91*-v-WW4|zfbk4#BQU06y$p7Ufjmg-NMhNL#az@^)k_u`B;Go>+f(#$Ly`=)d&1 zoE}@G{4JEx+SxJ}TERrVn+l9z$!V0e24j!GGX9?j=+EGC;JPV$3n_aGDSHdW`6gw+ zqzsq~U>Q6H>*00S4Co_s3wb^QE`pIz02jk(xCF+)r7#xAKa2dc$Ulqxv&cVtC|5u^ z;%;EEO>1bs36yL5GeAe#hu|yt8l^L|b~_qwI~s1g!*9`X+tG2`or!Euf%$CT$0z6O z+z$)k0jOaA5^=!Y$C#^0PeF+x*b~N60M$eSa+m6oLj?UYT&fD%#x6pdq(R$m_ zdfOe&3Cn&v8gDxqZ@Y_{lfMA2QF4uvYsA{$F89)^XF)cc3)HP3btH+qWJygZm&3nP zla+1#|7vYMwj%lO+xEv(+mEQ0!}hmiK~Rk zn6(9JPJjaea6v*4k{}sUpb<2NCXfnEAq|=Vcb^1zpF{}45P{~<0`#~zpWLw$*}$D` z5rtgf4wh&QZGbyjqAi>N?chXc58MS8F<`u2bbyY~2~L5|&;=Ny7u*FC-GQ-s!MMIS z4SE9O`=U4Wfxd7$^y4mCQf&&OcqwX3l~KGDqp`j}aD1aOZ*gDX71pHiv~hacI6Z9~YpxJ$t`KXk5NoawYpxJ$t`KXk z5NoawYpxJ$t`KXk5NoawYpxJ$t`KXk5NoawYpxJ$u8xN!x)`S}#;J>O>SCO_7^g1Asf%&y zVw}1dr!K~+i#)jwO(6}M0rxzqi*f2A_c|d0%>g@_x)>LkfPF({VmDAMhLx|glm1a&`KwF_}dQ#qxnoYGWIX)33kh|^BQX(!_1QT#FGF?%78 zk^ekK{_`05&tv32kCFd8M*i~{`OjnIKaY|BJVyTW>SizGG5Vj!=zkug|9Oo5=b7)q zE_fgIzz6Uld<4t}F+YY+U>|%2`vLzV<^lLCd=7tugTQ@ED+VV+2j~c$;1uWz-Jm<1 z3ca8=^nt!`I`o4xpg)`m1Hgm3MIJtY^6X1tEL;ZT;Bpubg}`&__7yMzu7rtj6-)x2 zQnx3=6yW)EyBMayH835n1)eFh?*h`)CQb1SlxLHsHfd@v0MgYaU2W3UUIY&U>1&g| zHtB0u!V-8GNMoBcwyWS#cmXy5^VE1gIFF};^X%7QGrR#?;4OF?w!;p12X+Ga!}Gs+ zJnNf>r=UEZ@Xh1--aLE+Ch@_}s|D*G3+mHu89CEstl`^6+4h7rY5( zz)ZLWZiQJu+TbT5kLR-Tf-B*1<`k}={i~+^tET;{rv0m?{i~+^tET;{rv0m?{i~+^ ztET;{rv0m?{i~+^tET;{rv0m?{i~+^tET;{rv0m?{i~+^tET;{rv0m?{i~+^tET;{ zrv0m?{i~+^!`lbsLMvzuZ6FWY!U@n0PK5Sw62#zS=l~s|6PyB_p$l|{ZqOZ0g&uGk z^n_l}8~Q+BI34=cR@2t~lrfn?+PXs8xmar-#p{htH>n&!>mar-#p{htH>n&!>mar-#p{htH>n z&!>mar-#p{htH>n&!>mar=2aKoh_lAEuoz)p`9(Eoh_lAEuoz)p`9(Eoh_lAEuo#Q zrj5;~jV)xhXpNp98RoME{~sCSDYV0?PfLYW;N|*HSK0K?Phg@ zF`zOy+zLVD^##)C>34=Sa{&Zo!Dr^n8xT`i$qEn!?p&5|m>uBxsZ8&Yj)HEpRH zAIhh<&S!k6l<}cb#)nk}Nc&ny`&vl*TF4ktDPu&Xj1iTJTC*jZ{8na-yvrwJ zAgIbxG*7AdKHGcX1Naa=0(7eRF?<610DWujhra;Y+x#nh4u6A#@OSK(7@Q0ppd)mG zQ=lt!gYIxD^n%{d2l~S4&=1al{%|G?01u{O!E%-8uu^nbDLSka9af4CD@BKuqQgqj zVWk!+VBH8Ma1+dcn_(v00$evbtP~wqiViD9hn1qkO3`7Z=&(|BSSdQJ6dhKI4l6~6 zm7>E+(P5?5-Q=gt_18Z8@tQK?y|AFY;={) zIE0P;Wn+KY*kATFz&M=EIGlYQV0+nj!Cb%wv$4VKa$wxTX57MN+`?wu!hQf2!Gll% z55Z!ngeCAWEQLp)3LXV)RvVku-T>IF_G_>SUI*+``wiFvZ^7HJ9d-crsl5{@Gd5+$ zri|E>5u0*he+rZhn{r?ugfHM9*s0mjn)#z``D_m-vwf_2H>3$#vly+p%Hev@o2#%^ zQm|H1uvU6ut@P3}nVx4XhH-7~6PIwGxP)<{W)aEl@^Y7>D z?5*vHqPZJIb9bP@oE`T~6wX$CZ@!nigBkPhz@FL^tf3S+7<>6V7y^_7c_EB|i(n*N zMh!;!pl?gjx25RYQuJ*p`nD8(TZ+CdmE@r$-z51Z$uCJhN%9EmsTbB$FYalVa8J7g zE22%L?doA=DN%D0VqqV@~iLHh;nq&(RWA3ki%KKQUX#k@lKtuZI# zv8IPP1ur$8c@3UvE--Iao@vaP$|sF^t2Nr1X5NMen!C+K%J+=Fd}i*%^W^8|UgbH)+=tJYrsikLLyY-Xd`o7Ue^cIs&41z# z<|Olw^7vvoczGFO1@P(eORF`W9>-XD_OI<} z*-5q@R(?&arT8+*u^v(WORPtg=Mrm~@>60hSAI&Y-zq;P)(YjP#ERpgq{v!{Kaz>o z6V7C3vh}1h&6#FBrTmdttMNo~gY|pmeZ;C!en+fl@Hldt^#|o^#ClHo8nMlOTnR9mkp-yzl;%6EvhMfnb~{*3Pse19rW z#Max+tIn&|PP~I`wcb^}K&*MGqm^Nkn)pZw^SZ7>}=&5!_HM+G3++V@35Vxd|=oo?bGpBalk%H`KYi5DNlFy+3wde#U70RiA?)qd`_HbkH@P- zUwbOvBSzXY@dI(S{Sf{huCpIk-iqzjcy#!U{Ric(*nUp=amfNr5m0_j*hVsW?zljfqckQisT=>v_OZiu@cPjr1_AYr)9<+DMFXTV$_k&bJ z`vc`i!TwNrP_REz9u(}o%6EeOvGSc@f1-RA+n*}03HE2oXR*Cs`7E~of&YWa_P><3 zV#iS4iXBUNJ8&H3t=I`DZ^cd{<<-Dxf>(q2PO9=&?4;wpV6hX%R{>>9`6qC4m45=K zmGW8av{qixoQ}#rfzwHOMRQI`!Yi87MR_K0x+%{DPIu**z&TZUCUANvuV~I`%-1`E z`2zic`R9TsK=i^qbiq7y!JGp8p?P{X!TEe%0K?%z7y%c-NKo&NEP#t)G+Y8>;8GY1 zm%%u=9L7T-6u}iR0j`9Ja1~5~t6?%sfvHdo)8HDI4r+ecn7%&eXFK!-c!xM2}{)KoPs)45u1amM1b1(#RFvL@^ z8h#H?Lk&Cwe}HG* z=nP$;D|CZXp$D7>J)sx$hCa|2PKSPQ4NQk?;W{AijO*clpagD$8E`X@rv`aykf#QD zYLKS}d1}lC@)iHop0R+rFkFYpHJDt3$u*cOwBPLnwCG3S}YX%d%7Tqbdu#AW^l?u0U!19w3sJO!)a_wY1O4ou2{NjboW zoM)~9%7953F#p7C7|H;i1B~#7I|cmM;7U3k!}|0W|3|d>1L5`7U^b@ZWifg z&4qa|A3lLk;V;Z-Y6OjeGL6qS507siKB7ImLVI>Dkk@t_Ag^um8V_%teG;4u9e8?; zV;zpgAF+qOEzkKz&yVulsPJ5V@3sQMa0vr%tsWkiJp3(rE@_R&B@a(ap8E!D0n*vs z2cH4w<{p5*!sqZeI0%1-f54aUPxu=C1;p#tG7n3D0VY^rLke)6lIz5ik|(=CcjyOa zKz|qnXTv#gE?frVfbuNILm`mI@(P#$R|0t^$umiwN%BmRXOcX_w~>e6R1Y7i9^QpK zyb5{v6!PS|unTs>`>+Q-2CfPJKpx&mJ$wLp_#O3vlqvj-dU*Qrf}@}SE(OjDpFUoY z^TDf+hu=^S-#H$hbG+bMSO@EYc=6lm;jhz6B2K(j1~W1_Bv{Q;~liv55Z!n zge5@A2vX*Mz317;IlKhq$bZ!9P(%OMd!FvX|KIF=c;3O|c?S>s$>VtkkLMjcqXNi# zo_9cV0r}4J4j#`t{C9e*+v!!P;Xl|@(c&_`pLja)ZjM*ao8JrN?7I)Rj=Com6VIVP z$ah>vgC`c%Q@`Io*Ymf0w}RuHSxFNap+g=-%;@+l8;{U(Mvvh$!CPeM=$y4B_F-yqnCX2l8;{U(Mvvh$wx2w z=p`S$gPK6=SVFZt*tAHC$Gmwfb+ zk6!Z8OFnwZM=$y4B_F-yqnCX2l8;{U(Mvvh$wx1#F)5#Cyp?A1>A8G*E}x#ur|0tN zxqNyqpPtJ{Gx=yHHIv*&Gx=yHAI;>WnS3;pk7n}GOg@^)M>F|oCLhh@qnUg(laFTd z(M&#?$wxE!XeJ-cgPK6=SVFZt*tAHC$Gmwfb+&y#AS=(&6}laFTd(M&#?$wxE! zXeJ-cWnS3;p zk7n}GOg@^)M>F|oCLhh@^TfN-P3p-9AKm1mn|ySWk8bkOO+LEGM>qNCCLi78qnmtm zlaFrl(M>+O$wxQ&=qBH|31+~}K;EL8e1p6-$Xj%ik8bkOO+LEGM>qNCCZC>b6g}4{ zdahCQT%+i@M$vPPqURb#&ozpkYZN`#D0;3@^jxFNmb_ty>ql$(Xe}SD<)gKHw3d(7 z^3hs8TFXak`DiU4t>vS&e6*I2*7DI>K3dC1Yx!s`AFbu1wS07z>b-n=FCU%dqqBT; zmXFTz(OEt^%RlPb`n%~x?qT1(e15n0Ql2M#?bYJw-Yel(f}WVW)`@5CtN45rmcwr$ z(R+Ey%fM03T0BK~tKs+XG*D*IcRu>gN8kDAJ0E@LqwoAWednX^eDs}gN8kDAJ0E@Lqwjp~tjD;s9y8yEJ@5g1 z2p_>-_!vHcPdWE}e0~P|;V*Ci{tBPN-{2tpUBtM%9^>wMjJxYG?ykqUyB@Pnfv(UE zy2Gi^3wlEz;2jX$U5{~hJ;vSj7(k4Q zqL=k;>Y<&-Hf51s)~A>C(Skl&&_@gU^s=LDU&Of6ALCAcj63}??)1mF(;u^WmlSvU zV>a)R;!b~zJN+^4^vAf5p-zKgON@ z7)+D)G_OKAPG`Q~PLY zpBW6wD$$;88dxPtYx`IwK3dyHYx~S@h%vh%#_Wa|vm0W}Ziq3vA;#>67_%E<$|na_ zi;vd!(b_&*+ed5rXl);@?W47Qw6@O-h!`^7O0vHY#!U(ts7=6HE`hRPLc{a9*()z#Q{O^P^m;-mgT$l&*;cmDG z?uGyF#|4-@62iI(Lj;;b3upyCR|;0$K@^@lTI0C%bT zgEDMTh7HQFK^ZnE!voo2 zh0B21d&cE39txodu7C+}B}{~?U=mynlVJ)>g<_Zn*O1QBfffs^@#xX^8~FZ4C}ICi zFavIenQ#l-3bz3xx>%2gN85Qa>__<_GOCE?O+BOO&~lQ7qOd<1JCfTcV7&M44L|Wt=6-I7^hdl~JChjbfojnO7M#tHe4i)OA>> zQLNJ_V=L>hPS;_bt}|D`lkgPruZG{l(@+D?z#rgQSOb5A=iyJV7S_QFumN6#jlg)| zPrm!WNHW%`hjr>S3LFSf?J=sfTsyVV!zdryka+hjr>S3LF zSf?J=sfTsyVV!zdr$7Gg2ug$b=>^PBFJOLp0rSrbtQUYX#S>)(%s($+{&@lO&kLA; zUcmhG0_L9=F#o)O`R4`9KQCbZc>(j!3#>O`EBqO@!8<^jVEKC1XUr@nEv&!l8OFVs z{Z?@JPDrYl%2SS&N8J$#voFFEXSA!#j4QC2wXN@vs2R!GwXN-3_VeTfR&wHQiSpFd zmhBUu9lt%1&-VQ0BtA)FtYy#c$p2jli&@NA%^uHym0~%2Sk4}nvxnvEVL5wP&K{Pt zhvn>HIeS>n9+tC*|r^3Sk4}nvxnvEVL5wP&K{Pthvn>HIeS>n z9+tC*|r^3Sk4}nvxnvEVL5wP&K{Pthvn>HIeS>n9+tC*|83X~ zJK!DI36yaxY7dLr!=m=Es68xd4~trj01Fnrsd&fU+ieLO?Q$U1mcLPuNl)zjFucOx}{04`;zZvFyuGZO_oGf}`Z69rh^(SJKuSjzd7@muUKtZxtN+r#?yu)aO4Zx8D` zaR+QW-;=N3dl!s6#sb%O!}N^$ri=|n#Ja=dif8lxaNwMex+6w^u4mp;Z@zP9j6OR^ zf30WaQzwGc*}jQS`dut?4~yKxBKNS!J)Q+A;8~CYo&_nuI`^>7J*@L1ch;7(ej(yj3*{sGIgS{T3l$X z;q7mmc+=Z1V=r%d`_kmqBFy`Wm{FE?W+$_U6*c?uPPBpM5OX+hLmmy|VG>M-5|{;Z zpd2b-CC9HZH}ICUZFZWui#MSia0Z)S+EI&_k65Wz#EM$&tWLbmte-7;ci9l$CO_I5 zZ%tx8Scx^unq!q)6;_qC(pqh;u{KzntZmjVYp->{`qCDn-6fYym}(EaRINu}ddZZ_ ztm`km^vX&0giEJ&I>nm7y0bNlbr*MdB(7)J@wr4&WYOVhn{zC z)QRYPHCj#(7Wr$0@!PCEodHbB;xjld@jq|VB-wides|4zTeXXD;=`|qjS z->Gi@lEm-v8ll5;2G)HaIsB>PLt`eszq9Um-dm>QxwGzbS>5OU#Ajf4;?oV)eNL+T ztot5)uYWIl*L|K}cOB0p{^vY&ymCw3|GWWH#b?)jrhHR(e)AKb^gR0d>pz{jiQ`jv z6Q+>7J2fToNzbMKr{}WOetISyZW8bHR^cb7B|aOg8w$=AesP3~(-Dl^z&wh2Ec<5Hgxg!#v z!MgLbMkfB}4W@~3dM7>ub-&}yeR_Z3nZ&2nS*N4P+q4rYZaYz@lQY~YV!srQGb_-> zS-=~~o>j5&wp88;FV2yRS)VJHu^!BuQ4MjPe46zT`8;c1Ze%@FZf5;UsjhDrBOQkL zmHdSD`MitB5EsZptcU9`o9T69y>6t}DSDlz*M0Q*OucUEPT*GqT$Oj8JDzpEtIGLV zE^iwW1KlyKf8ma1J;+t%;cWe@UV5$O;u@l_UZ2j|)LZJayXdL^@5hJ+l}&UMokSPW zm2IXsQae;S1Vu9cHxlV0L_69-WQuGN6|F=Y(N?q*?L|zdVxPu68xL+grt!4Kvl}mJ zRNlC{N#E2KOr4DL(e#-tvuQuM_XjjTNjXrN;HYrIR z)7WktY7%O4PwI6|CpBr`WO?e`CeNoXYdSmi`KC+KDjK(IvMu%Prq8B5(`;#z{i&Zf z-Ilhk+1gaQX;RbA(+)PcZ`B$Ji z&Bz8}nS~~^vdJ|S=VX2@$hpLSVfW)AKl1^+#PCwUzP zwvrhUEqg>tTJo;Y$oLi&ghQEV(T)(Na|MDlu=sx&gw!{1Qr$7OFk7^b4Ac9XtD~A9 zpkJX~;YfAd$!cGOS{=bFk=}EL-m`{1!y4@2yXLEf)qH33oe^46zG=x3D}>DHk+Upk zS<6K&zhLRmu`hd<3mF*`8PZ}gye1UJp-)+!vYfmx42W?YWC*y zhPl7+Mzha&!`VJ&;DkQX>VFfnkOTkQUhy>r-mvePHfK5$WBN}$xe z#$CnUJK5X8=^HpXP!O0FD08Q~PqLTi+If@Y>48%MV*=L&=DF9pPqBA4dt*-TKs(+B zcy(a5JI#GUr;{1l8YYj!cv`Ca|K%_#8!oB)-ym=8$ZoZS6MaQi-EoV;s(n%EaZ25u zx#2{6Bt&Pu$B2{&C$coLgf{78a}wW#=?9uq&iM7I>@iwaXv~%s&1dPDjh2+O@cz0O z631LGjL^ioJ*U;hkSzj{0rd;tst|L98QzND_advvy26@ZU1?3UuEHX_+L~-l;k#wD zAoq%Lai3Tq?iUNi17eYQP*lkF>P$kjgpom;9!i{@DtD$xG3S~0CB275_=x!!+g0Y{ zP?fa1?rO?~8-Di4lCf8xN9($8uM;v{(QwJ2#&Mo`oXY^-DtnBxko8xA1+!cW<16Ktm1ttfk28sjM1f~bB4crj8F>q6$B=A3hUk9!y)@MXB z=PT#y;|a5QZ;{1YCSPWj{j2V4yj}8jX4=2uZc%Tg=WUYAx95G4@A3Y~cij(|alhMr zpV{|20y6^lyKlSiB#Np*x*PPB1}SS`Nf}s?1{Rv(3Nv#cZ!(Qh&pJ?ldOLlbzSN?2 z)VY(XOBYh}3aC+6Q~#z>uVx2I17*~%Y1GB()UhYrRqm6jriI7Q?|dRY75l_zV!!x{ zI3WHiJ{Nxz2gTpT7vdk{OYu)}NPH!}7XK38h+3Lq!!QlYunoru7_K3Wpgc+5%{g(i z=*XWDJhIJqNk{#sdh^47hO##f{~5{#Is9iRyX5d6GYcC0F~^|6AF~Y_{4wvK!5=da z8vHRA;mDsE?kY~S?zSGVs;#Bgz19-z9&3TM0u}VQwHy_6pS9Rpgd%##T4?>&deC~p zy5IVp6}Kv_hpk7fN3CVnV^)>CNzRZr%bD^Pd8@ol&XTtaGiR7MiDxr<26_d02l@p1 z22Kz33!D+?A2>5GAm9b^17`&W27VD36gWF@PT<_Y;J|r-Apt)yly{*1DsVwyI8Stp zq)fy)Bp0);%)F{O~}bDX8lBTkj`sI$!Zlk>K-oj32kI-Yn|| zT-TLu&`omF+$L_S+tf{VQ`|;wV`}4*qAO2!{NIVqXth`L$(WT;0dB)0&Co)!NJd?2|V{OKUjF&SuWo*gVma!vaSH_-)ndq##vhsK7+hbDw3 zg{BIl)p+9ncj5e-P(sr~*M~|%GefgNrL^DkL*=1`p^DIw(1uV|XnAO5=!wwk&@-Vm zp|$LJIkYLXCA2NHBeW~Dhd%B}(MLVwg<5Lmw07D!ZF$zK9Z!12c)IF2=Xr8;9q*66 zk!QAU;pwdzI$u-?P$gkLrQj8wwtCIkiEz z<_WdYyf6DIXOeR@y{OST9gAcipZJi}|8L;`9sIBLc5c4t-|`@NwK3d2d@y3R>=c^H zJ10|H1VYop%Og|6ottN7#zNPJSBEx5wlp6enb~qqcx`BFBs;XD`NT*pb1XTtJKQtU zGcvH{Xq88i`H>~z{>`gHd&8R|ABIZ9gPM2BTo{@Y-Vxd#`Lg+d=1DD|5AO{fj64xK z)O=>-{IF0t%9&Y&(KDoMp*wZ6tM;^uvI+DfR!S4_j`qmb+;8+Aj*hGqMlLDE|LRvp z^ZD$nZV(Q~gxd0(Ng-_F`lCXfh0!RLZ`wE5m(Bk+BrI|rS||zo>kIaw9_oLq{#Q0t z#{R?m%t%VcZuTf^vHmza992uk81_$Pzq$fDoT8SDVeA`Mzc2KqS~Bw4r!>31(%f|H z&3(ekSdg(GH&F(x@V4-_T&@=T$;eF{M{MD>^zv(?4N@S=_u-YoP@f#8uEQa>^rA*W z()X$#>%BLG^pd`wy(*T(-tn{qEa^|OcSGG?J3K-ylsqFmLKsn%w+VZ2fUv>?!ULic z4##Fh&*!KP!c5K& zs!Hl~VdPZk<2kF)XkpVrvgFJ<_S@-Ss-@X#&gC5T9ofGtou%1Q_Ny_JBl|a`voxceH*42mzni}D z$dZO;Xr|f$^kUU%JEGU%BVI7r4XS3*8a!Meay!TJu)b~A-o{mBD|PZzHK-b?i`sMW^5>OC(3s~cu;sq`26t5@R;!U@Wk*`6vIMM zaV(wxpW4d7risz1AF`Q`rRo1uRm8YZy*ll6SfAz{R;cG6)~FK?tJK>L>(nE4?r^!2 z?a`UnDfOQiZTPP0LWP<+3&dV`uluq4sr!-pp}WuhjOW<@;vR56cmL)dbpOip>|e<3 zgtf!{()}mTwI6c7a=&)}CGQ~gm^@i_kax>>+;8Mgw^j;iNK?KmEosYuOqN0E$RwE} zcgaSwv1}sWlTBrsOqI=eCO$)kWJ?*A&1DN2;pzBHnI&^%ROZT7vW;vl^JH6jf@~*G z?h z-ExpTTfQ&Pk>|=^%RM?R2Fvs02Xct?3^)oYDmM&WRV;v$IC)_xx7+dAtxLoMJLLu(0`AKd%hmOimotwto|9WoL=jD2xkBMAV!<&kYLdTAIw)75!5gZgW2y0>lp{*e4=ACDhfCImgd#c~jjl`J zPb+^6dRf@Cta(c>17KK~IWyr_z~0N54W+;sFhg{6)H<+Pt(gVJnz@)}&UHB@dOOB( z*h)Ez)PL%p1HX7huis{E8FQ?2Evy9IyxUy;I%hBpfuS%=?N^>;biZe~=c(Vh9Kl_T z@ye@Aee7y~poq2YOvRtcbm!McH(&1mr&b4TlO&l!T3sj8fS2fnG?y$ zW}U6RC*1kM%4w4mV;@H-4Xw_dGNkV2@x3`-I5{nH?3|RG^z3i+p1H#1oKdbEajsX8iUB%iON z&3EF{#a)f%W+O&oaPIpGZMlsfVC)VByz3)WlG{(d(VdQr%w%_A=Un{2zV`jq{8NMCc@G*7X%AXE~ z^B9Y_Ftd;X*^F$l{6^fv?V~T;FSu*O)sf0rF#2diAFb{ySq*P`Ssztx zR3jR%t5FJd)G{0YZuYqBso8_GM`SN1oMwTdV~&b57S4#c z8XGTRbo>F4mQ|Hio%KxC`m9Y^Z)fev+MhK(Yf{$qtdgu*S#z?=vnsN>X7%LCZS#-J zh2*^(=6bd_@HCF2`ZDhDndFBm35G5ShAs()8o^N|ni^%QRABpc=XKVJv@k>l*E!Fe zudnrfb0OFJFjrh0Monmy(>{A= zHe*%X3tq<}#0xwvXW(b*W08i{aY#h5Iqu-@&q>jgXeb(uwvTp=_KgmV4vmhCj*Cu; zUKgDiy)#-KT^wB=eKNWxx-q&Xx-+^r`g!#0+(2$>Zj0PDxgBzQdjAV;dk(mhyh;WhQsB$d%>f{YvK5N=hYOBq^Dz`0bPClOl%j@fc9H`t@Et0)&=nn%R z9|po8I0pv95Eu%>;CvVkBVZ&Hz-Sl)V__VOha#8&6JZiehN& zO`|28oi#se(UEqN8vSf^eP;j6L777{M`Vu4EQ&76>`si|sr#8CGbuAYGdr_gX6MY_ znfaMRIDTyA#LVfLGcrpv@5!vlT$cGn=Chd_GB;=L$ow$#K<1$=JF9V4B&$_cEUSA~ zzpO!7!?FsZ1ES|dhqc_)a$Cz?E%&xO(DKV@-Mo1>nKdLc;6{?qv3NXQj07yuJ6le^okOt}0PWQX*q3#!= zx?gCc`-ME^w~jdvX3k#9zL~S1Qg70-G2en#m#Q5V#A8MS#9-2Xrm;?=M4Pn6SS`_P zRf_2;C>N|L5v(a6tm#o$-=fzugcT(m!my(MhqgC?_o-_C{@1Yg{+_iD$2>dV`5YOO zB$XsoNC;69GBlXUkWvYu5|W_-5fzf8Qkg@D;~3INoMR>(vn28VT>IMll>2wz_w&4- z|MT#Aug^Mb@3r^Z*IIkJ_FC)fMhoMt(9z=2vN#hoZ2_%cN3V%iqZW@mYrJr>7f$uU zHxMe^q0!Qy`05~F1AHUM6|e_#jP}Bpy%667@q|;|z6nn|b?iF0*42Y2KNU|+KSuW8 zx_u1iw@qQ>Jg(okYfujd#QmlQ&Oe(%+%p>DJaZ_FwurVt3+jx& z+C@9zF47ZM_b2gJ-{>G*<%dVd;7o9EwI3Uuh&#&+v~?#s4R@HixblA*U5dXJ;|{Pg zx(;_6^d*dL#2K(N`ZMkZhw#^)=mFdnPDam1FNqND4i|A&II#k;qOsB<6idVTQ8pHh zWyY$+YT)l{aCfR1yE#@bc4w?9{;nTu6l)f19czbs)g$=3eXMiru~_fefY?*9VfcGc zY-ntFY)ouiY*Oq^SPTDMcpKe4sjb~zA|*B~HYzqYHZk^kY({KO482rXV~b)-V#{M| zVjGd-X)HUoGxl>VCw2%ap2m*HPRB09F2^llSmSQIaJ*!^d^{e%Mwocncr>0FuM)2j zuN|)&Zy0Zav^w$n@ka4x@z(Kn@lNqa;yr~M-xS{w?-1`A?;h_P9~2)NA08ir)F@$M~N3f%q}B1>-;6zTrRL?zD47 zf%uyE#&~voXZ+`QPW({(c>HwyLi{qm<|wTHEZVNXS1hzwe9;<(r}|0uR1v~#gKvve zw7WH;D4vdgLf?er_Hi`mqs~PU6NM9n<4fYp|I?Ne^n~itY=_u3?Lm5bu)ICk-X2oC zJrwZvP|Vvyac>VXZx3PxM zd>qwUoJU3Rq<;vUUj5 z*T9{;5$@mvaOeI~ufc4Vd;jAT-!L36KUbGR-5iSN#m~dyPAo5WHg+*C;!eCkylA|1 zJRDEPE5)nFYXvPrl=|0{zuQQ>|Nm?aqI6<@VsT<=VohRGV#mL47x9zW`=x|Rq$JYt zZLf6v2+DIdelZ~uPNG1fXrgo?oJb}rC8{TCCF&&VCmJQ1C0ZxiB|0S@N%Tzg7v(ZW zWsJ+1k})IWy^Mt!OEOkwtWOL|3{4DAj7f}3OiH|&n3;Glu>j@xBC#^D4kg)^_&%{4 z`L4>7k)82<#-5BrDDk4ilEiY9d1E3wu`}^=A}4VuaXfK4aUpRzX^C=)9f=Xi8>0}y1`h5Vp&jTUtI#i_7~=#He6}ej2!6g}%e+V1?cqr4TlD zaF0Q+4ZP8ZzQ=e4h5j355&t3OFyc*}a)|$k-|$nRpD>nKp=U>Vgw33Egv}k?nb6B4 zg797^im;^vIVI6QQsaECkG{&io`+U;A4)M0=&DF=rv}+)K zKb}eYIu-2e5pRd5lm1RcyC&l8(bsE$Q`x=&@rUrtGSI1F*FwA_`hN{}s@XRp-U&Uy zo^-CYaUaDq&O|)l(B0X_Tg3Brz0j_ddBQ=@o2kyT_GqVueFy&PiZ^WB?VaoGJMq`! zc;|iw{)pOkTm1DXdXhbD=Qy?O2k_Tpcq1Qb=Q=mq?QnggcY8dv{L{+;-*^>Ved)TJ z>Ror!sIP)3gexI_#Rpg4Num_$d!{Juz4?~$o-WFvSHssL9arK*B8)5XZ=yE!NDwzW zd(bPP4)zpxHalC<-RfHR7KFFD_abcVK8Ub~i|1zdDHl)7?z1kg_U=d*Ps#4fE}oCw z@$PtpQ(Zh0yKlL8B6erE?<1V=eu;3oyBy(4>W%NNc2^_(*8LV?o_hx2?=Cz_sRdK< zoR?Z8wFttJsU;DXPA!YDd}?`w@zeyu%+v}9tEW~+SR?g%gg2(%i14P=n-JDdt&i}o z)Mf}d@HjszSxz8WEq*1Rp85_S(%5)SG;+dH_FX&2S(GJ z{I}QpO8@v8F#!Isaquckf*rH@4nX}s;OjW*PgJC98p6<8KJ7`xlr}c4QfoNcBq~jhwo3hYHG?Ee3_epnTdy~73N(t z52JULNTAh}5<-kvUK2yqWcXRe!O!xxm`I*J zL1Vz?iy7qi60T!J-$vIRS%h>rm^Z~o;P#UbTi*zMsc*?4p)0~{=-w;Qk0XtJoGG=m;W?Z7iDUW z62a^9zkI6uyMGn=P3ifL`hQLOH{PP4kJx|d2Nw8~q`>6nY2ni0c(_WqR=8fcNw{^m zL-?_9|M1Z8sPKgFo8dX(h2by4Yr664zB$q`(kya+q;sTa zWKd*S2g$J0-h}ABo^YSa!n!&Pn0=$9z2UD#FS*w zWO+OXR!`oHXTWC3`|Y^RPj}mrKPL|)^O6@bR7Qb}k{QvA zN*OgX>Si>`XqnMIE&9PWpoMPvO5_m!6frGkrHa*vHe)reA_*XGi%T%kM!8o{789I5A#Kz^?;L zL~EWTCgUpeHLfok#W!M;*o+aLTST_lDz=I3m?7<3{IbAzm?7;4_W6QQ2xMyde0}0AFMmwEu4U z5&bB}YCewhV4xnP2ji@KNSy$``Zd|nUNBlJl9f*z$uV>IWB`X&9c9;;u` z8dCduP-UB1sJneX+vFW>LeE8p`oD&P0hBj5WoFYy21d&fn5 zv!?HvoxN|A-SA!cQSZxgckjD$FZj77j#!IAq6EgHL~&t)EWu~kE&u|TSy{s?W$OmLc*;NjK zr+AbcEyu`-@-;b0PLWgP+j6G-P<|$t$j{{$a+zF(QMc>mCb<)mZh48i)7J$!ZE+b-nKk z`1J(T+$OKqzQYxaMk*Xo2XPfUrB160x_~aEOX#u~cUxE2*9~+-T+v$Sdv#0QO1JiF z_HlpI#}laApblU3YHkvGr_Vs&^O@*{{tkMc&qe?9FZ5Eq3L|va>U9{Uo2|F&gZc=5 zRpAZm&42VVr6(QwdbFCJ9_hCR>wi_N)Ba11 z7R#?qs>|E2s!guT3IEUQGN{SLUM0934foh|(r`;Y@od z;!oPoAbi@3;|ULO>T`^I-gkP5IQ1p={`Q_-gec_TYq*{5T%a%nZ-O80!sum+Q@ASx zj{`y%@44H3-DB@^@D`4or@ho{+72v%?KmfBJ9wH#-cZQF+cR=yJHL6l9o{<&eFVkFl|#g1nxuyFA^45>Pt!7P2|NuX{Y*V{i9$55_6@+s%*d@?*3WUP{}c81ngP z6bsUV_4d&IaPGspUfEDQKdul%FYA9<5~ScLyk%GC`#bILp z4%WGPt*g^%T<72GUA^YNE)jTx_~*J;ul+xl3A}k+z5dlX{@qfzw*N<-t8@MP<@AR0 zulu6E|5+3NX$|4PZ(~pP!l?)~c^Z7BRQj9KC;RD>y|p#<$MBX<_0y;N=~I#ZtLKrX zEd{a3`LSRrZI74I7K2!@l(x!gwA~=aOOexGN-m-_mNk45MQXU z^erzWk7)DIbT6FYg>QS|OfQ_}h3|ObY%iSSh3|UddtUgy7tZyxEx=;RY|nJr~8OSy5`Vdbj@L%3O(sxTY?xZuD)w9K@C}=ODI>SqEvqICGJXGdDFum!uS33SpKe`}fmj5Z|iH z(mHyAxAawS=|peoYu?gHv{c-Ul!4-2ghNDAT2tJEcrU!Ela-ny>@9H4BE&h1l>5D0 zIA>EcL_5Sc37oU3rNnG3?Iq@TYrgBP>DdZz^piPoE13bVjt9XSn42Vz!u zI>xuX^=Eo(&hplLht^bsklst-YUB1%PtrOH=SXS`^%Ua0)zesiGrYreM!e*$N#|p4 zh3f;>e1*1#8Qx)GH6FQ&VU~B4L8JZP7^(eaX|x|$U@5JmS5Yp#nsVu{5brCWr=^&& zluA1SDZS-L#J9*7u$>}u6s<2u)B5nWlWjNCI*QKU&5F+7P4te2lAvv)rcnDR59%Fj zqTXSD)DHGewX+HHNg}VN+S#ISr|s+dlvg*PT>1{mrMr0RboJKnjQBv^&0FUYZ=FZI zbsqD!{5aBk$f`)+D$!bS6x2>ONops(CE5vEAhna8@_NL#$(oc`-avU3+JLhab7#^~ zbS18RgY2D3`vM za_N>>|1RAMVGTKsa>?dKg_#IcEpv!*`jczNG*cj7f|j=cv7()cvG<*cvP_+cmlB<_*StU_*bzV z_*m%-M5)|C@U@~0@U&u^@D`$+@V#Qo@V{cq@WEos@Xz8J4Nt9hdtj@bup|q=`ayf3 zmeUJ9NZJFnrEEd1s1JOSv{kes>;bI^+v|s=+eClF`{9>9s4Qq#*h6=34?U1RQ1nK; z6n+~yc#lH)Q=6%lSh_{ELcEA-jr9kr`w*^HZ4jIS4m&3s7U|{bW;q{Q&XOM>+$Z&#*h@kA3F3p~YAoF*ze2p9{1jnt`6W`eNL*ELl~{(boWwOJwW?f!u#|oZ zOSAOT2si7YSihGZh_Htqgp{rN8HCyTS)}yQ&mruqhap!%{XF7>^f)ZtrpF`RPY*}f zTaQ3^LgTvRp42ZO%+qvTI;}@z%`JKi@)pr_btZ!_L%}R>OmZh*?ln`4(3I9NRtGa-A4|N6cY>n-swP5?H1=U5whiGgQ?F2`M zc7hV7-mPiNO*M`p^&U;OZKhEYv>z(TAWe0;MWas9TBuG>XgZ448b^Vv9m?jO(qxk} z8f8wsQBw(5YpT0dG{2X3u9fyQ3$wiOxmMQudn@L9({3NM70gNn%@Sc!)PEr;+MOs2 z?FrjH2*o)o+k2WNA0kB!cJTh*D({6-J8kK;$86aee^b8u{Px*~6s@8ywNupU{hn^d zs2O;Fyl|=)&ho<92<@Mo1@c-uZ;Xm;I z=JjX$>%(*4rNeLFE3Xfqf&cgH5N2i|`yfXUo17n;njf2)ADfjQ3-Xe+I4{{Nhy{7c zWgR~$oS(nquzCkR=3(rh`T96l>8840ALOCzRI4{LGFU2@7#W*j;g1m_PTM6t; z@3KMOz|NEwi<1$l>^HPlWOEJz% zG2SnE0D`=MohdEI8`zoBg1mv9$zK}e4eU&5LEga5losR->`Y$BAa7u2N(=G^?U~Yo zyg_>=zh#g&urs9vc>_CBT97xeGxndKH?T9M1$hHIQ(BNWuro^R=cO3inPQxmVr*xM zabAkCopFr$c>_CBT97xeGo=N213Q!dm5-NV!F~ffQ(Ca!z|NEw>=$M5+7K+7pBKyX z(}KK#ooT%wZ(wKg_6GY6>`ZAv-oVb37UT`=jIHJ84eU&5LEga5l*W0nSHH{@M z%S{vB z*qPFTyn&r5Ey#=Vd-VZ3=I0IUOld*hz|NEwEGbohdEI8`zoBI4^Sg`=uD$ ziehYMig8|wv7IRv`ZAv-oVb37UT`=jB@7Z4eU&5LEga5losR-?2IGJ z&l}j8(t^B!ohdEI8`v4P$j=+tnbLy1ft@KW$ctn5>Il}$&l}j8(t^B!ohfa$z;{y2 z+rAv{7s9^Y+H&Qvc#~8NR$IhMyhr0>AAXOE#L5xwm6l@G75o(gqGhXlTA}wNW+V=+ zzKnSgL#t(;5b!GDpVh(M0g2*0gucWIyr&3}0AHtn`_kzO#pTzZ4_#_9K@w@7b^adHo)cSBFCnd!^Ye@H)^el-1D z_^n8xNQp>#q(bDj$Q_Y;B5flNL>`Ph6nQ2xI`R?5wyukO8`%{(fl*_xGPKHbRj*Vl{odQ}Uzt}eN93gD zRL*Ih(>|v|PWPN)Iiqu4&6$!jJ7+~sR?eZEbGc5gn_DQiSZ?Xucy2PcQtpkpx8}CV z?U36gcWv(8+}wQw_HEerL zPhRf%wU@78{%ZOc6*I*`*+hP=+NfvMDD-oBPdiuDa3*T_M)YF36MfPKp#RxO)bKd; zO4^Oz2>3%^vW8hRud3m@P{Ykp!);K*o&6eKmHuP;k@REfm%`IAH$dq~6te`>i!{QB zYp&sr=p{KOvM90y{Ug7R{1Q1GIUf}mpLeZS!+oOzq7$MsqaS0W+VbcwuZ9I`*!F6; zWGsvtu9RQHEil?_1ZsFfY##bTeuCbRT*G@}2mBhgQNu;9s^PBj$q9`b&d9IfY}9b4 zVo`~zv7cr<|+ppp7|ES?%sNr*d4Hx~lHLP+9~XNm!6pYA?MJ)be-`|@ zf8YL}_K({?VSoSqJ!mTj%7LQ$Ki|K2|3}z=%Kp@SZ|)nGJ8bVcS{nSzZNB%@+=p;> zRm}MmR7hXIyt&Wi1;v&mt2+MWRw;nqXGCth>Cd?_f*_naaYBkEB;V%YsKt}-()rx zA`^3aBtJ_W&bYQ>u}mxDa;D1ojmuJeSn+u!nw98N@>0paD5dlRYoJ>T?iXgKk5@;CLtTr&hz;*wfvfTqKx%=ZU}J#;m|;H!Q}BFQO@fqvDy62i{AUWq(^{mp zPwVi{)U*z1!~gy}Z4Aeq9q6sM&>m-9c0R@!g%2@$=sAo6`WAgWC!v?;gnv8oWexg$ z(#$E@==lb3=vAXO{`bby46|QDPx@c&BhIq_&~yL4kG~v=F%&P@KRMspgK+nk_IO*^ z6YVR`3i||R(BEtyw)32?>L)SUV!g8wqrEQLSr}(A!=Wfvn9{kSm+;h+C4Jp6Ns`5^G7oJZV$olqovZ0(WKadO1`}b#kOt)2qss*N(H*2rq=H+ikflhxG;d80Zi8>=g_2_D<-)>01A73K5#RykbPl_T_Ra-6Sj|?Je6`W<$`$0R${zWK)oP- z6yL~F>PxlOR5K~EmO3tF6 zeM>f?; zeyWGd&-4hnM30o8>lfq~dKAXb6oO~DF#O7ORTQIT28v1QDOp4vF7`bv^llzFmH)N6V!e{m*rCIRo=`T{e})9QCqs)h#B~+$?|BxtN8fAja{umiOwA zY^hUZD{W+J?aE*D7PUbg(;d`YbBn1Xs^OPjtH`)~PdCx~OaXH%eh+ekDTr}Djb#Bf zUp}X6%CY)JxnFNmW~xeyg4J0OrCOV3O(?>uXaS&vPU2 z-2SFD6!YTHXoIiKwJKNbQ#tBa{8H3;ovACC>&*4KwyCLa!fYrv<0dBO6F0Y+dM2Spt1(U?(*`q^moaV4eWo>LD3999?G^4Odx86nyWQR9Zg#U=#|^nD zuI;RH*1Os6SMC~jt-HhB>TYq@yBpmNZXq|#jk(4x;HElj(4+lp=No6Wv(&xDtza%= zF7&ca#I5MY-K3l8X1ED=o%^+0*ezl&a$UEmTg)x)mT*hDrQFhP8T3Ie>y~rNyXkJ& zjkr-K3*Se3;ag8O{PR8W4XB^n*V*n4bO*V@m9nl`V?Hzs%}4e|S`ea?CY?_!Pgull%nTK*wE(!YtHWNA@HR+P8tJo$(|A&2Ud@_l(gpOQc5)B23q zB@bD(t^2I5*0bovf1`D;)zWHZwYEB2U96|Ap=Q1{&U|1NSmSkhYl8KvHQAbCO|@RP z=Iiy=0_#Kc{eM%ZTW?tl&3k6C`NT37ZqL>S=2P=AMwcxzpP419rut0wF`v6iw33yq zN#=bs*US^6#AxdV^MG}&d|l9}lr-xatD+S*?d478VXKU&ZWR=FnftB6;svXSRZP~F zH(SN6QnIpGCi|I(Ob64^bh64?MS^Qd{rJZ4@tkDIZk zyLrX*FypM!I>V}I{bhQZ@uruqY@Rc7%oU7`z0Ymqwsr4!Te_{}t=2X(%sL^T(p9ZA z>l^c+8DUkm&Ra#TEvC1bfT^FqwMtk!WeMv$@d19P@I&httD5z@Ro(i-^f9lRzGkB7 zXI?Y?%_RAqb-+ruE?N=mh!wStS~2yib)EI6dBRLK1I$1(#VTp-FoUcg#C&UySYYin zgUwWVjrFtoMO>%SMGX}e^;BGpQQfQ>=5_O=dBY4bZ_a#>8Rkj2$XnXa;ASZ$FJl`W%ctISaQWu`hHE2x9AhB_s$SEpr7bw=Kx&dU3A zs%)bR$hNwmykDouC-t>*h^{V2>H2cCZXn0#hVn&>eSA%~kdySiaRu$K*2oqFk{)D?$qn#9-S@E>cjG!J|fTSqiO=iaDAn>suHTNxm~_#>SHFeG*J@YPfOwJ zX=!{rErTzoW%1p#oN`2Yd^t^5LWJ?vG=guYQF%r5Lr;PJ=qK<5dI=0bAAy1BAutI2 z0|u*3;z{+e_#VA1eo*hp2XrCXP8XIB>LRkeE-D|=#bgIvTz1qYWG7uxKCDa0&bqYh zqRYsxx~yES$H}ksc)3PTkZbj;a-E(izt*qG^%(!TS8tO!db`ZkJLEq7tw}QtOd-?I z6gGEQH(57Zw^((oTdlg*ZC1U1{F2o*qN1oIJ{F6`C*o7_nOGt|7hk|j@VqtL8exsJ zUa&@4qs70Bl9R`*kE})3$JS!&6YEp!GiwR_N5AU}@GxA|f9gy6FY9*mh4rxc(&}ZF zT4T&Ioir<~IcBBxxmhi)7d0`jaxHPAs4Z?1H(R}}K2~3=pVi-b!Wv)=6wAd5u~MuO ztHoDhjaX}aVSQ;WwU$}StrgZvYn8rY2}@ea(w1e}mSZ)yT8PS`il{2C6}Pw#nXlaT zZg=-lYmhbAdJs{+T z>wUAznrOXd&9&yqU*&Q68^$C*k2lJ=7gz-4=k=n1D zi{>wHH0xsf6Mz1*Pwk`jF^tujW=_~&*{e;Sv(s7Zd}4oQFR?$jzqFUy%gnF#H})oT z${uJBH7Cs(^P4$tj@fTH-Ri0tMDHo9=1RB;vu@nwv@p%^CfWeAYutffJ!wS0cj8vD zi`d2Na&`f`q+Q5PvCG)0b}4nIZQHJ0+%91oyRco*PP2>JA=|OFUD~$nvUa*#730#T z;%&9Lv&8w#*=L`UFUyzgGxk~gv@_rN$XSH3*|VHE&b!Wg&il?>jL!bRS>Sx=EOe%u z1LjV1&>X^;q(3nR=aTcgb2%7`6lxH{ZZf8G8b>I;es5!_e!&4Tw{DYXO?Ci^_5{W3PeU!eA~Afmt^^>@Cn+ z8GAdlE`#3D0==6(>?fi17`%%Myo)mmTHlA#;34vWKM1{&nby!dd^$q!^m!3_m(MFu zctbp9K`B2$<%H*fkS_FYMizoLWn>xXJ&dF}X~syhWphSS*=WvnAO}P5WhB)Fc{P9> z25rSiDi4(#$hV;PF>)@HJUKvagtlemX6XHl+yQ-nkv~G)G4dqzLB<{iZO_=RK_6l; zPnHlJ82eW!*$dc5pq&_J8T4UB{t4~OC~BKs7)5QWE2F3_bYm3R`w@obcNOqL66y&k z{SDM}(8n1y5!#)>yq7}sVAL1To(#qs3ek&Ed!fA<%nBjUqtHYB4(-cms+WF@t^w`O zXtZ5Hzym|ufJRbI| z&}SI?1t_%%fLY0en8`TbLT54FsLOW{2i6tnY{r(*IgC9X`YvNbFfQD~CVRfm*pzoJ zq`HcMs^aIA;3|+w3hoK7@I}iF1<4|2tJpuay^kc^U0lFA`f+2^Q&`%kM z>_&D3n(ViPvHya8&e-drUog%_DCGeTooh=O`y!OuC9t!g%Nd94M8^i48PJuCLpEE* zz(Xd)YC!cy##-xRLD%_c=+{0eP%0B~E1)_i?gmsovQsBO<;Vu~_f{WTZyS^HJ9IlE zt3r2xoj9-Wgnq}!2GH*rSszMv1U4=IkwI@oA$|h8k(cW27Y4nYh1kRBV^C^;K(~eF zFzC4`L@tB=i}*mmpcf+?{|x#v!rjlPROmrQm4qH*R0MjMQPrSF0QQN#yh8lSpcgMb zZ2+_v^%j)c89;AmAx<(@E$Ar*J;()qPfv)mScl4Xj!}O=&ok)1DDX>r9yZyD{s!p3 zDDdlh0>8c|&{I|j$`8;-R*1hC^xPKWGNUR%uQ2dfdbeXbodk|oB0|86DWqcPPA<_V zJg_|pdl8}_6m5urw-ZxZGIXzyAqE~$AyXK-Z%D(yE9%{2y!%Wu#A)9Eo>C!ce}L{M zlJ)`MJ;l#CGv5865aIx1Ht+)EtDAyyv0IhGIVW|6&QGsg}jEL^HWx2 z;8hk9?SP>36%f0*gHfU7_-e)1JF?1fwYZ-W?g{;odIW4baF!PX*RA(Rs zZB1U!sD;p)K2+y7Fc_UBWG$b%?w752ziSS)dRH&fbk?k z-s(ejQkTJ)6CrP7FzQCgdJIOM2zqw$pnAYHh`?ABLDwb^vOz-z<2{7D!-wo~C!_M9 zclnTQ8Zj6XBGB`iq2s%oQAeS4&Jc|OwNaqRZq0lsUvoyI%47>4+6J{bpy^mz`cQjo z#b~PY);`Ze?_)5QM#wfk!=Y^%O?JB9X9V;CMw89j`HX`;$Y?4AZ-J)ebglwpLFxPinzl#hB(V@Y&Sc^D(p!qo0HJ^;rz<$LL|u{yx;6pI|iEe1K0DbReUb zL#a%}E-;wEm>Pl6jm&N+o%6&g@Dzh_XhJ^ia~e97!N@cr>3E1UfQ|uRteTKiZlLIx zsH{LGp;SIV?+O^X<&i>psqTTwfR1F04Sj*ZHy(izT^`;u{b;jaiFR~Uu5VR zT)xE6GroM8NjVQ4%P2ahUt#dgNXT&vJy&APlLvm4UPx+B0AG{@Mm~86+V(^SUzr5P zLU{idkil11ArCQv&ey{XMy?8Z#HR@KD5Iz?9P_yc`YWT!w#R*%L4RYk1hOP~&1cUK=g5J{zx?YeS z2|Wf{nxXrHD#K_hTUmy#(~9f}bXRD3CI$9Z=?uQo3x&2qkne%s13g}bMj1o)Ks|Zf z0*y0hMo=S-HgywpVb+9PNa7*LesI-VCWj4u4gc+SE!mk8=yD%9D~+kbO-2- zK69b9!A-c{l1=FN0r^=K{SC-RNbhnURQ6jLN%pJD(7g^{2t9NYXgx;ngHoFShT2_y z27MufYQT_Bl&uYFN#uSHk^BDzw z1Uw2xfX95^gg(w#L!sS$K7#h}SqJUuvmV;ZhxXN*F=(Tz59kYWK|h}yXn&typ-=c6 zfzt61=fOZmlRXD9x)O9SW6;*=eVZ`U#;F|uO?G~YF*Tu2Gx{dzvy8q4`W&Ngh7JSI zBk!Hi;f$tsLv{hCG;}0msz66ErVMm6qp42DFdB79@9>1Ca=ipz#&)QkQab~B3G@|4 zFN2O_^iR<7jNSvC!07$ZiHu2yzQ!23o=sv*26QrG$W~JrQxQ6qF?8L1opBCB-(U=# zuT=NIY6E@Chio>DF*s+`bf3l089u9^Z~IW0XEK`VWfo(o9^YZiHPG2U4WM&;?ts3> zn46&QGls5Ja~a(cI?spN(R{|lp&x(+u=8!u4;hnyE(FwmM}tL-QwaJoW9WG4cz{y` z`U&Hdfqu#uIyXOK%zaR*KVVuzKWCgU^b5v`Lcat{;R{_3r8)-gCMf+4Y?M{4VBBw@ zD;ak?lxzyzZP3-=E5tWL*8rS4Y)RRJ>yWm4U9u+8yPnnO8dYzTx?5aG42lN z7RKEQrS*VIY4kU6X**O7;L`S}e88psP=4T&J-=n#H0VyojX}R-Tm$`{aSK3yVBA#b zkBmdd_Y?RTb%EnlyBLSczMFB#9=|XS?5n8F0hijJZ~5p@$ha6MBSkGoVKqm)hGg@GHtg>;!_Ip$P|dM$gTJgSw<=H3G8} zc+VO1tbv&ayk`q~zQAk--tz=KQ((Nh_Y6VL5t!dVXw(ydxeJ6w9TN`PhK3ypw?DK5 z<30f`$KV$UgoZ5$XB!muA{?|Ejk?jOE6l1PbQQ)O480N5M*5S``k(>g?Vxvp&WJw+ z?E-Kd?zK?b2eyHt3i10=l%6#60~P^bDOM*IvN%Xq%6afkzYXVT++&Os+I7RskzWdzO_J&_TO zps#^R0PRUnW&|D66o%eQ^i+nvap~86euKWj2%Jy)O@{p9`YndOZ|iA{M4Q*s8S=C0 z89sT?w;A~ebf(V<=q!f(SbDb4N$4Dgd>i^*hTa|Zdp@V2v<%SuuAU3#fzx0r%~)iEt&AZXZv)#=PCC{d0M}y6K)+)wDnG8n zg!vRobpQ<6X*Xl2-hN>W+43Yfg>_&%ubxm>^ge;!tsZo5)Mpv;x$1L_fqnIP27Ob7 z{(}*%pcfhXo}n)>)+Fd(;0pGI_F>`Nws5TzqoBy|aRXE{<^d>H^0*diGvo`j91ud@ zBhVB^ra@r~%LUhfRG&Ds0At!i3o`WW!lFFDJPa-5QwCa?p*|*75g*D|lo5A9i!tVY zXmKCPSAr2QKuh}2HcI(WzS0bROR;EwK;8^3>qFZs=R^6>{s{UmWTCAP^u5^%GvxEO zA^^u~9)c!7643TC7}FV==|kJA;6vLWdsP9HuPPvWqwXv^en9Wv)^*@|upZR(L0h({ z&H%lmShal6uIZelbK1%VWNTnXLg_e(?cf$4v{$Q+&ri@>eRe_XGIVdTZu7~3)?+l4 z>vo3TeXaUFxzGlTcb+svoY)8MV7znqPQ;0Wfa;Yv3>tyP;23BE?gqbsras4^_kiZ$ z3}^xFg&n#;TQc;{VYOn+^U&5l7ohhsnzRjQi@Xb<_cQbiYCQnjfm7f?hTdna_KX^CI*y z#!%YhjCl##oiVh$2V-7__GApL+lw({p}iSH`T8*C6=+|^&^G!pW*oG?Pig2AjLv`# z@S%1((C07cAjZ)C2Qy|o^hw50S%xsWGISVYo`aIzftdrPdIjbRbOeAcU8-BM5$xeo z{nPOS`sQiTF%#PW9ValfZ8|pM1fb&q^i7HGJ>LDNDs+NR8uV44Z=e$yL+#=<#!y)% z`B2`;KIfrRe2PM+`fP!|&Y0fNHyA_ve3PN?@N`e|_!c_Nrv!Am&raw}hQ8rjvwXgT zzQc$QptF5;L&=Undr)*%&*u;5e8y0Fp?v^Dc3QxgzEIi+ zFl4iZjG=b)5o5@Hix|@%`Y~h3mWvrl$MT8K0qCbb>Cn%7E<%_1M4+Gh9D#n}6NP^1 za}>JNCk9={C@TMQpX;D2eEx*4WXu!LRg9SoT@Aj%F%E#PVGPyzS|6&%bv`?wUo&P9 zbiL0H&<%_ryKeN^1En?x1le_y&tB+e#tepLF=i^1+7_Vx4&FT=8~QWY%FuhBcRp;x zHt86*Gvwd3sC+=wfKrqj5j&QFY?_DJMxj2sC4l`(Hak2B_J=x>af3C&|P9rp=_ zo)Nuk{YgBNkqu5U^t@=DX6TvGySJUeI%LbUj2Q|&#~3=-&oibS^moP#hhAXJGtfU6 z^A7Z)Pa)`^KGdczF_Oymmk-(RGGm^FUSZ5^_*t%HsGieqW9;%mq@#%trU|qlW12$C zG3Fj<1I9^#-o-cu+6Xkpdtxe-)&ou&v^nDxg|=Xv;?S0iQxe*SaY{kkg8Pw|_W2;= zpit?Z8RvFr7sjD-b_Hm&4()Rq( zV*u^I#Wgh@b(fC1ahD1ahV2Of`-CM!-+97{5%r;(Q5B#TBN{+$MqLAS7|{?KVpK(F z3L{VtVZ$h#gJIZ<5U_n1^+(XRi*Nx(+z*8v3Hpu^M!gc^0VvucLEkjOg&BeN94^AB zdQj9oAyA*;VvK@)!gQQK^n{jR)O}F22}1OOmSX6;LAW#{dPB)BfW9S!%QB)5v>cuo6)o=}l`VNMvz5)4J!!;S|M;N|=A)jlw7DN61!Z$MH9}U-LB-!sKhJ2;rn;A*A zyoDj3X}As}$*#9DKTT)vG>L8TbH=zD` z;X4?03VJ6a=~(Y#)M;oVM$&ONX4DyI6GoB^?q<|kXj4W~o4kk7I5)!080vQxZqATT zFihtapgw5fdl_92+LEFEXyI0jPJ^~)WP|Pu^(_kbU^H#7CnIMAZf9A%9zV7(;z+!p}40UkeXssNYR^1VjF| z@JNRG;Dldb$X6Gp_5r9rPMF#RAfH^A+5w=xIbk|}pjSibm;v?63Da=`y%tKx2INjC z9S_j!pyL?12Rfc1-&=SBBhNx#W%Oa_L`I&2QriOh2y_x7&qJvV0euuo?FP`dzA&{F zpdW|6&X7Mb{02jQzVMq2^`QvA#n5-w@N~x94xPbJ-?uQeGk~$EB1~-y2+B+C2~huz zFts5dNRvQ7CqJF+&d&;ZGRqQxpD_5fSKT4E3!EFJVL!N^KO# zD^O~eK=gxt$*6YFrHr6+YZ;>+gwnYL#1l|zyFj&vu4Kdj=qg4%1YOODfzYoQ)d9MO z5rd%A7J=#rrS=EJVCdJ3>I7ZSh$o>N80rfU-pGjWq2Dly>W$7lAbx;uX6RdMIE$hF z!eKfO0e#~MQ~L&zj-A>Z(1oGf7)i&zozc`zb}*8T{aZ#Ch3;gie{uLbMi+xp`2h7b z4pW(cE)M;Xk#y`oF`C-y&y1vF-^J*X(A^C6M-KnO=u*%>4G4>R;_Crsx#kW`;X8T!r>KE_C@+g};_<`X{7 zNUG=G82bJb&SNCi`3Z);1%*#ClIs5yL*IwOrx{7ddWNCz0O7NYq~kuv(6@o`c}9{A zerM=gLHGhgeE`FMFq-P~B4g5^e=?>4^b%tVLH}Y*L+EA36oy`5%pHPGLlMDsg8aM@ zTo)q9ClXMs7ePIf|1yGlilig`8E6z#KzcXmHQ-vLe+;b-ZbbSpXl-yC($N+o^#Jyx z!_Y?H9@NES&=#OA)}ID_fRU)T2<;EZBhZH!iF%84WF+b>(g{3@ydObnTYa#7*e}wT zA-{5@A7j3N_Gie48hL^-UqS~k~v27QvzN$3#9tbjhnkY6nF zG-Fmmhce_(ijeJqSq&WqMx*@op|p?jLWt|36TnoY_lCX>-bVUz=uGfF(&<>{0vtDe zkBKY-pCY{pbP2$I$gdrt^>7@bGL*^<#I;b`77({UsocPQ2ufuI2Io#>72~#tu4dfs zP+A6D*gb-CDT4EZ{IU_W`^W~w$sQX4u5n@nbQ8dJO^}^&O(O*IL~uPLT&mA(#-)1M z%D7#i+W^`=`D7z#>x7}Qe-C~@`dH|XU>CM|0Qw8#c7pC<+|JOwjN28O18@$J&oZ)~ zF?6hy{~*#QLU9d=97ddMd<5XSAVCDz1VTOo{SDw+;8OcP!MKk>PXnCW)@tZ^@H^sb zp%)lQb@~S*shwVA^kwLu41KSQTw>@uS>!LqeH=>b0k?w?Q2|onTYx>Hg+US62iu4i zW$Y=?VvIc*S{&e9w$ZktB^iVLM@umV`-zqYWw6c%(6XQ$;)|i>K^XCmpb^GKn~S0l z(HPQ?LgS461~kFg)1XPlz)sN&#{LSL$=I+}v;t#b)9AH~vlCh!T!&+%GSmPyv9Hgd zH-H-vN4tvFW(?{mdK0)A>EA$aVazFL9mXCAy_KPcW7J2{sP*OalV80WgM!vevDHXI)HI1 zLdjl(VE@WcDl5wF(Dt7Ku%A;4`V4p$ajKu^7^ehu7~@b`$QHmsnWDo1?BP(kMlw!2 z=nG&J(%VBvgBKB}^1cMdBK|1!6)+C*F3<^#Lv{Wt<51mBWE`^hYm7s7n#35gTrry-r{WG3TQfzD#=BG7jjyBKsfW8<8O&SC5V(03V|&bjv( zyAbq!#!i9GW$ZH0d5oP3ozK{%pdT=b+SCHZwxJ&~whLVdK0=!*4*i(14RkSMQ~iDd zKE*l(p`S5!Q7E+!V27YzGPVO<%GesZoUuzoS1`5(UCG#Gp{p1>9lDxvt3r1%E^Hm$ z&A3yczkoeLgs5JQFfP@@Nyf#tV**Ij#ph6zgK+jkar}g{1d6f}4vr~?V2cgv%2gebs z!3eb7*e#5G4tfvcpblbamxMDPdM{{+IO;Ff3baOiCiFhg4so=p*n^-0;%EyooEwBQ z9oh*zhx2_MbOdAQ*hezvPUs6@6xN|~zQ{OlLnkoKQRu6T^Cxs7yhE4%=9+6Gv0UVQa1-b~JEruFGKVd=*pmh8oL}jBo1EKm*w71wY#K~sc80R>2 z2jftE?PQ!kpnJextlt<)$Bg3(;oOfMW1XqT2B6DvJFTJco#4--jpWi;5j%@=ZsXfzNyK1U`MhqqYXm>qXHn z#PbGGG|a6ZeWIdu#uM+LqTxM$^n;4l1yArN6|EM}a#6Hycm_}^P~RI*^pT3z3(saz zv^qR55=A=+&&x#7y5qS=6s<3w=qnX1C`o00QJiS23}Y&rh59*oK8Zpwpzku^pNe*- zB$eNRau+_A;`yK`cFtDrZ6b<+*e@zsv0?%Eds2ZNTMbS#| z#8|0lpo8*nM6ut5=TD+&BP1yxiK12GX-82351A3@DT-EwXOk!z@EMpPidKUsa2Ehx zotXOoa7aZf!cjdQQ8apDY*e&NJjaWo;iVPRMbRLKE1FR*1`OJ&K;Nh&f%hx^5JmkS z&p$;`>F-BGQUAizDC&>+4Bn%n{)*>6qNsRQp&wM#kR(-u=BQ|EVTNF=RJ0Cwf{)q& zM)Tu|IisRMF19HXMH?QGG;dzfJcFfU%dr|H~{ZTxr-w$A3 zAU6&`J|95e)$Vw1LU|aUArlU47Da_DJ@AMqDvfUo3dX07#S?sb;BkBgZ64Svib~^n zLKJl#o=>7Y1(*eRJ}rv67|&-=wxRwkJi)IAp2g?oc>WjV4SYTa&yPh>FU0c`QPg#K zev0xLUwP$uK^OL$H}0j+4S;d#0!D&GA$#z4jXAfE4_ z01q0&lg5MM{2fo=;0wG{!??cy9=|{vjum(Uw_ohT=UsU2M*)5vuS(Kk{GN*a6+C58 zBqyGVDC{RZZKBBN!(qE93g+Z6@JB^C6HiSPC-8e1_@tt}h$pp$BGJ2mTPo}xJX27B zUwJm3Zc${=$>B^<R;8}!Hj(35^4hK*M;xl;Q@L*Bw{qY=vvIt|r-wuP$ zsHo53xkMBVG;8tC%yxhShq58NL<59NG( zejm>ZMA6>E^FmQH;P~)GqB#G=liqz5;6K6>bb0t@%-0b-ZxKcNAD*|Oplui7{#{X= zpz*`h?x&~+4IRduQ_;S}lm3QzcMXuFKVKF_-6ctSSd^r1CH6~uUL^a^cy>VPir-#= zXC2B=eBOxXnY>8$BY4i?MY8{iEw*ELk<=gX9LI~Kg62UV_v=$_d$pjXNSfr4iX^|( zUOGwYBlVXCvnz&gsT?ygc(sH>1XXRZ#H36Q%bc0TJb`T4o#AoMlrqX$x-TPrrsVUo zv{YZ(Oes~$%T3LjiTsY-q6zsdw}KVq;m|E5oq zf(_lfcj!=7R$T0G*ldFb4II$FU*BN&KHdBD?$xtLhm$&-)UB>-m(I1FI+nFBYu~PI zO`Gbf%8EdFvA@{w^Olwr6&B>@=459%JPwaLBRwrOCE4XnvS~IA->THSHq49v6t9Ph zU#qRF)%|$=zVBo~=ZA+}`U|doh2<>hYR-R%s;*AIn(7v&?{&RU(CpM-a5krJ zbg^K0Fn{R_Sud0a(}Ma`$AN#OFy@0b)4$EZ<`<4N2ZQJJ4ccEg5WE8)r{e#i7lL=- z(HuN*M=02=9GD8B5C&J+=RkMXq;#n!Se3$T5*vY}bQwp8&H|N=A8E(wY3E2S9KV)38Hl8?w8S9+l;%*;!kZX`b;%x?LP6T#qq(xz5meiiSMH0K{|trY2}<6E;2t}ciVr%8@SWo1hm z4TZz#W9@S^^S2e^x02?v(;5&NYrWY9Zo^#G%KJB%Ft{uA{CF68kNq99k1_2p(IR-l zO{%So&#^wz{z2(k(LPQHj+qk+%(t>JCvo!@d6)X8bfst~4(5LIUAV`!wRyY2guzX! z8S&!{{b(JpGmCN&2%mcQXg%m_uJp{`!-&4v(|-?(p|40karY)^r^6fy?QDS-P;9_F&S9n=ZV7{SG_otG9cW!>rzv4OMFz}c z9A;WvJI|m$W8jxTJJQ!2=JdWhsMqMv4l#D=Ex^o#JxnmiIL!23cN;Kw8~712_yqEV z)(7oh$R#z;m~+)RYr~%g4*wK5L~!lBa6kJT^-9RaTxdE2f_*bnnWEX*h$N=k)wSrQ zyw2g2HCzP(b$pg&w~rrbgGxO?8kLSYD#%aIP0z)z)3E$xWVl_f!Zu9tU;$!&=EuL@ zoI0pR0a}Q(a;>%^VDIzdk64TJo%&zPm^SqR{cc*H>~llk>{nfOtV?~_n6q!qcBohC z%lLBsMh`Q$GXl$Z&D%f@Ho~<(8&6)OG6&za7 zw_>Gl-EF0B4tpDi6?ATe-2+$)ol60tbEcv7^Po`(I*srRU@i2{+l2;?9t*m+w)+hF zYoU9z3%aLvDF?A7{R7rQ|J1Jh4R2TQ0ks?91K`ZEW+uHzF>xfzn7UE2OY~5_$k-D91}rP zY0&-$2K!04D2HL&1+J-f$k50g@OwJcnG#+M-5Z)1_5j)&otkX7Pq5?Vq^d?ZA|u1) zDxzL!;0aN{9SrJfjk412tPYLrC7)LvTGLa0viex=N%~2zvs2jg>9g$bg!By|eSJu% zXmY(+FB}s&&-VfvG~7#$HAQf=RSy6Rt(^j9x9y9>FkEH>23Afrc&IDJn=a)^KIx=j zR|ivUT-#J|T>VV&yg5)HxKU+>+UYAT%+Jg5WZ-vcUd@%$rq<)_l&!%m$|{yM)#fkv zcIsN!HQ@Kw)rt@P>Lc>tKlT@9KC}Gfi~4&C^v{m!A2aFV>rzt}EYuJB4>sMFkvwH? z*#6F!51)H;ezL9M{v{86a&+00iF4jwGHuvo@H_9TM!H8|!hv%xyN{0#9Ax4^s>V8o z@kC*yv0TS6mtK+^)%sE^jJhZMcuSb@e+6D5?R*fvO#c}8Mmze)T!JdJJ5=2U+~vbc ztdWKU2fCPDWh1hfGz?gjRat>Srb;;Q-#$}gvTS0~W<#QpfykQbK$+i*q1KAR1(0;+oS5aNY7d?3qR3L-x+PGlr_zZL4t}05YQ(JB_$Q zYNAL)y)=qRMTPmf?)20Yr$Z`brJ5_djonu!cj@eQm(_N%WozEf0lzO*&dSUtn(?Zt zO@8??{f~`{-)C*NZNfcYs=oW`b5?FYukSsVuY0eWb*X$+|0we+miE$5DE2Dt3nK^Mj9I&mByHiIZ|X;Q@9DhrZr0%na!(-zwI*8 zAMJLt=ZKj!In16{RR+q63-hx*8L7$WeGRKgitT-l+uJEeL-$op>CmC$aYwTEs=;j3 za*D&=$X9FkY}P_?nvJw zN;9Tr5%iSLpr`mSi=%@hQeCnpWinawGTE*um`j;tRkMS%mUWnO*~a9VlBP*bpk)xD zqS%`-v-KpPE6UJ}&+jhFbXO)pVacfrm=u@;7eY2sVFim2px;-ad6+?#|EyYh8K=cD zgD3A;a?WKS$I*JvQh$UNpK2J_Fpxc)noczOTxckBZWEN5`s5FNzQ1?%z+!vxNM_I@#P=nX+v2`^o}! zUSg!)7#^ofZ`ZD6${CL_7x+nkciSfY=v6A~V&Nx!cjc?B-2Tl~`Y$g%sXw8Iz)%ma zG#P5erN3N9G$;68R%wngHzbocLk1>EZmBX@POML|4GSa5J40J!k~=-wX_K*|&`XGMm>Wv@9J zA$LEeAsO;@Gv|v_I4{qaUg7*@+K#3S-ptoO0W+5^jfcVdhxq^x8Zgp`mNqtD|126mx?-Zf9Q3PM{h`9aoj?dM&u;Xx)o+O zZu4s?OIyI;gdCxR#kWKD1%DU(Y&}FfQD2N0GuQV-fA&a!wel{qWkfp*n5`8UlG_4i zF53_f1OF88D`0^4Wit1n8GRsmE`B?|)v-ii;8#j-Wh~@Z;_bLH65&>Fi0Q*p2L3bn zLghXX@mpE?J8}C_80;=g00X*>jFHprrJQatFA=(})<;-j)V<+G&KCq@_@}@-=qI-y z(I38kp`U2a#C;6Ef)}mtoGbN+Z!eanoQv4T`1#>5Fb1e zDzLzeXa%Ow0yDA|7zg)>i8&dS2!_UP@)PjH`2ctlIN<9%=c}mm54H%_c@^utN6L{3 zq>F}cNr6Cb5629X7pAZzDQO*+etR-g5$u@hWTZyJH9>0)*7`5M)LFmrh)s%2*&g&?18{PCSYVl4FMzk8O-X>K;+gZ zU=;Xv03-YuRv5J7P>gmkGQbFbofQWCad?e(3OJ1LTUcSx4sNr~q$5~JQ%{p)#886mH+aH+AB&jM0Us%ia(GE_TU?cJY3lUYT zu6)bNh;{M3>QMbaxv462dm}B1jemt+0ZPId`bgexHg8u!1WK{ZgkEQAco0jZS2x*5 zm7&!vp9+0ispGnHUB}4E+fkFfzMldeDhKy)1irAoE3=D!-DJJ-JFU9I*Y+uowhUg)hnLc1 z9owr%j@4AlcMlBRUL`kS^u#rH{sq4?@JhPwr_jm$Qtx07=;A7D`exIhZ(-z8x&k+H zONuRKF8rX5SVNJ_+(3+(i;$!WjrEOf`Y-Fx`jEAK=3a)I{PbNZ7cDz`dvpJL*5Cbc zk^XEzo?GhOqraKCo@MNKij82(##NtRKWF8_?O!jwf6J!J4!-iTerN-R37VyT|HkdY zD>&{xlvnC|1ZC@cxbH&P#bxTXQU~dj;MjDlUF@*i9I!kLgBamO)uE9e$Z8nVWf*+4 z6t%4=FF|lS%acZieFxUT89U;fK-XHbjfHWXnRTM!e|HOe_CJ$*m*v!C4Ibd=@h=du z{N_tD_9-@4$+ya^B}xo@e9G4%fsc8H-V9EU=yrUr`MNG(7O?AL=`GR@=~4n_u3R1u zqx*rPtguUbuh^V!8XT%)U*l0%VYRTCIxe_s8R4fFDEM_ zEhQQE4ImO=x=ZT1lCOuXY@!F7rnrq+WII zCOuSHx%sIZ-zwI3fD10zZ6Ee~<}+;kp`Ui~WQ?EsK$72E=sU{P&Wyp&iQ4q9LB%#8oqHPYt`RkX2eVE^BABewr`{1u<;@c1_na(;L(f6DgS~eR??tSuP#3IfKiQI*- z-azf6pLe1i)wy)5kn7MX)D$kqP!GDE$4-y!8}Qr`W`3(MglEytT-g)fj@~`m2d=ko zPh`8GKcv5icIHSsL_1bHR__qg&H|~;-$TS&^!E_H7Rl0VjO#|=lk|RglOZw`J9&#- zc4-#SC^MHl6V5$#{76#wdD;sUb?%uVb%y^h1)4e|4V`0|a(e`}?NHg(8w*!#7P!{; zJhGy2WgFJ1M!uv5|LTv1mKVsE*mi9``W4~dR=Alt^uMTVzK3*xYJDW1>s+Z#uo4;& zgL83~oheEwdAMk^gQPZrb*oga1VIbZw4yf5(1OffP_MWiB=4@^icmQ_1v9VjjnV=s zLsJZ8h#d{BHK~FWBAQqI1>O%q6PojXvBT{iesfnZG+X49Z0nE z+#y>dX&bguj!G|&m!(K40*4L_0bH_h4BUA=j)`qTPwg>KXLc4!($Pvnmgpj0M|cV! za(saIrezoGcsi&{$Opuv%$~P0?)4Ex=ns zPT~tt4teT%!k7aNekq^jiv=hUKyp}Qd@5H}F<4bnGaov5dVxE%d?ufhGvrIoV72#U zO+9njEm>1pr|FgYw#@T>ymx+RBL;n)eCDy7H7l-IBM%JS|F?dO&jax$*Z;u_m>1Yr z+LgdZg>)xdL)_ZBeWhK+?W;SFXJ2XeaC_#?Q8!dD64&vMv-19j1eEtq$bTIPtit8v))+?Auc z+d5agU1a1&=FFPIas;rJIpeTnIBZ-l3uKl%D*Gkm1h7MDoI)NWBU8vO}RNeENS^%()PCwxmn zm%#R;S82M20 z_fZ)2P2I44thxl+>8Ft&nZL`Gkr=n~rf54jS-yMA{)E5OyGO@Dx{dxx+&uOO|1A$9 zSwVYUjB(Q3tMqOmbCh>MD;3ht|L?bDTB6KF?_9IBS6IcD@GeJl+~$dy=mKJ6l@=IQ^V}J~_+@=$yeK zQ{Lcf$xgPC%dA=VBv?!S?YwdtGU?%j^9+C0kC0!bpcxnW(@2$-8=*sroI2s}qo1Vp4Ix%yBQqK%DzzOSY-&ZiQ4YSW#IQh2AVt^?Wyd&D+JjmYz-{+V(9^|;N!0cus zAKBuQ5&ezAAcinHVLRnq28ws>mHY`|O1TUaFngrw31I?U267nOTCp%5Mjsm;JH^S^ ztt1PK@sd3yemhqR$Nv`d(_|UT{8q+N8ii5c46hRHw3x$EE(7_y5KB8DZV^+Gvcu{f`hZN)3le==;|e88Blx zOhVtkcCrCe%V84w{h+ES5!y9ClxzOJ|;{Wh8BpF=b<4?fKD> z#yX|KH#lLXXEST}a6tbw^ZCbe2c33G=akW7=gqTaAN}d`-?5J3z4i}@=9!a51fRyA zEoqg*bVlDym=9zRP8H>v*=5{?Aljk+%PO_g@;lk5nDbn;ktUS~eJM_xg4~l4h^@hA zgU_%cW%Ah|m)V`2VMne9S?)^Lu64}I@PAE#*QVQmu5~L%v8`-fXcl`^e@K7!ry=%t z^x68m1J;gan?mOtdt6@sxo+C!K6)RH58*d93_^DRM z!@xfiX`lF4x*?8#k>_ZIL7vAyu`s~Pv*_Fzz)PxB8|;t-CjoLlkso7|u^$Z`g{`udwsq)aO^rFHgT4X?BZ4%h<#E?fL^-XWRDu z6S`Zj548y?@~Y5ee<;V7 zyMOR!cVULjmCNU;mUS&dfI-zFQ`K>fM;>}U%Q*L@qXAG=$~CG2_hCr$w64Jr-CaCQn5>RWEmSh z@M`4MdsDsuNhL?yU_GYxYz{upc{I=JZt3L&bLgXYfJOkrX=I4m7h6CrGV5KV86+0R zS@$SBpYzh#`7~ij-taanKo@|)`}c%z#QS;No#!${^6U6-mRj2d?D=u+R_eX1FtA4! z#OF`Yn9cDZAAjJ8PmOr$r<_e`3_ie|O7qV0VDuq3=nD*;_n|@Eua;3gDk|g$Z0iUo z&bhXwc=GwsF2?W5B=}rQGBpeTBIy*AAsDz!D$CEvHzS;$VmYU`3?7CtiD#;e3|gg~ zT!9b7(C;;CsV-Z|fM7P8%04)vzj>C^TanRb;^=&RqaMDq31EI?^uY^Ij(AU1^A)cMR-e zvY8l%!5*r;@i2OK8gCSaEsvWM@K6*6xY|$W1Q0H%ef(CX_D}TP;5o|6%9hH4UbhN) zpFlKbOW7H@rf6i@**Or7Yyi9F8F+eyc_7-)Nl2*O;>)|KXkG&_aKBC(%~3s2hb_m;COs+7+NO;%x?Lyco^NM zVjKd7^V9F<_|bmkw~)C@;(yzs{WsWIt-#Q{@jhVQ%Hm-lmm_`PJo-k0d0T3QQTIsg z62SDb!a(;eh~+mCpC=f^r;&M?pNb`$jWFCP2tt6ppmHLWq{%j_CL=e?XGcPuB|M*C z4*fBq`qt-DYZ19mJh?oS&v_RAUAPb4s1 z=zf#Hu+~JoTuVKbe-3o4KvqFUAWCZbe`D$J3wu>G%V36u^kQgo^PiM#6Q6jFLrjVlZGF8Y5LJ3E#1o;JC2=u7<} zXbsDg+voRR)lEKyogzQn_sdHft~s|~=oGxZ%ZQKWE!{Fi{?*`7gGOvGwy!qW+DgJSPT5Yx*5 zekocJ**?Hic$*B})8l4RL7p3AfHZ>)1{oi_e?TNYD`vto-$x+7`l$Zf^-Dfr?Y3`W zDfpnjyZM}L=k~et@>Sbb_qhvu2QprK3VR3SjaTVEzx0&8RS$1uX-l5_X32e<@bBXL zH&Oq2|2V$-(%c|l^8=1A%f4s>hGZCrfeaffU@UXf6n;^4sObU*^7?%V9&Isx^=kDl zsTA25bB1pzMpUE}j!>Jb*k&WN#F~grP8;b!LYUNKB$^Z;aAJax4}rr$MQH&xDVXQ; zV)d-_cJOt`%gxGkr=>WgQdVjPpVy~8__i+k++J=xM)y$ZL(v6<^=q=W93UE0QDJVlJ?Uy+fk0tNo+z!XEbK#5lCTjQAHY zBU^>R9(H5iM`@f7${CA?uBc${*EuufI5z6>WwSo|*( z{o^~_IovxO4mq<1oar|ss7TH%VCsyvf@sV1n-NST-iMg_^#Vq|gTo|<9|C5F0fWc{ z+DWj-9Wb{UF!ytq1o1+^Y&T$D;V|)W!e7y6C;6!`E)R#9b#3gfaz)4nw3C4h?sD2s z8u2C=t9s{=8uC%auD~wRsG>q9c}ok+i^{Q`)Gbzaha=I-&b&A-hLQ+XPbcVFUKK8< z1nav#Oh!uf<;$O3{q6E6&h>^IEb%h0G!+)!w`uO|w& zbSfe5TGbKwZx#soF7zJIm*qRxGw|J_XJB8n(6xZeQxG$64_(U*{PqdIm}aU_ zQH`|RB-)G|Nr(4%nB*z&U?WrH3>{5!GdCq^da?VGr;&Micmc+oR_>uKj7W@-?|w=D z;q1zaZ`sI~Y}d8n`(~;_&Db|nb*%3_kKFrLb@hMleV7gZ=@&NgVI#Z!ALY~E^w7^h zq}Uf0L_d=akD`Li8HG`1J8fcsJB4&RZnIP3D8P~fUR8KgC_NB+KmA_CW7#`A@IU(} z=H=d_|NW5u+t`&KUvZ1az2J(E?C-4kV#BpxoTul>pIkkE;bk1J(1Gni&g07okKpaN zGipc&1`MrF944}t82lH(bvwWez!=hTIzq2t_o6~KQc#kUa14*j33SuWL!J*b6B;WY zRVg2pmt2VjdAZs6VS2S!)wq{Rj7rPVDpZV&)w7Cs;(jBj^i4h67?1IGg~T= zx(Dkruo(_KhAp`^dovtZ*d@t8AVwd#Lzg4Iq$n>3zsdGx1Zo{f2{-p0o7j);a1(tM zJKR=T=KL7{0{`P1%Q}bh}-lE&B30ke8XJ3?7(f>^v?A z`UwaaX+93rq##&@w)tjfxicV$GFfKJEy`qKXdZ8cs?_Fmb#rNCY*(&pA&Iu%e~13h z)N}7VJbA_$hOu!)kFG83jqmlDtHaX9wsPjxjm*EnG&$gal%+|qnFm0Q`e75SH!@Vc zOjR;4n@Eb1d4?(~Y|#oML)8aUKxxvjM@|vOfZPNZem%JZ*fdxOO$;f$0TRO8YEYU$ zy{!RG3TBnVhg4Ht)}g!u`r@ysEGtU_t>Byxkv*lUejk#mI@bAB`b6>syVpBq=hW7* zPHt@Ngv7>y0B&`_kxWPJpzNC5vi?&Zy{*7g?i%{z#wY)p?a#mLjlV9w;kkgTEcE>I zUzF#yz53ioehUO{rM!=29jk20KKJdnE&FuNC9ktd`|oDCZ!f*%jE|01vD5<_K3lE- z{`EoqDDXx6JQ_TZB4v^%+d+AH=9yWRQw)&8Z@7>%u@fE8DH+*b+S>_#eD^G?#rG2C{E+{JWqJM*7M1zy)!7E}gY7n%gHd7V9@4--Z-vW*dP7P(>M* z%%q`6yk*!9tnkAJu)qLh0?7evL$X0EDIW+Pu$Xo6V<JRVGA702NTsBeP10tvlbk^VOtpE1%qrU2oe}1MUdyIPL zH*J4?gp&X}cI{Ywo%lGt!CmD44Am}m+W9b*{1GZxssV)ch zcgrK7t=Uv&YsP^D_{#m=s)W53s8c6^i*1eY0oX?Sy%}z|JEzp47UR%6Y#;%ZVy`-b zAkzG-f_$*vY;alyo^p4V`gK{}T}%31_kn(Jm;U?In?7OwHTtcm>3guU$-n#4CY`VU zV}FMoeec@WPFi}u{)&Ff!w<6o--JF;D%b}Tn;E7O{dR-a=AqviI2&mC6TmZki$V+) zs=zRl6eiIgdn1LxVdOm*1ikP&GHC*UcwTe@m`Oo2o|~QNM&lV^zl@9|zEzhe?Zz|V zkSW&$u32Vb#GOAy8BwnMTHYDQiy(-0;qUF;AwO#t71;bFz|fFa(|OUD0b0{4Gh?|&Q+!CoE(1SiCq7<9zG|V zRk_x$T6te;%Gt|q+p@hN>px7r>z>0)Jo^9CvzIKrD#ckhqj&S!PfyA6>Ca}*-*?-h zMYB&GadL50%}e)Pv}@6#|6Vxh^rqo;L)xWzi{?JOdiQVO89o*+SFSMR$^g!0eeuEbHYTU8Sh4D*0#?;dza#tiUFSYLugIHo^2s9_PoH$b>x&lcT6gcuZL5k; z9yxyIqD4O*p>e=2wNu`4q0}{4tBJFGuwNcA?&hfO4YJ2sK8W=i(bPhz(C713`o)%c z^w_Jht|TpOUN9w=LcbqDG@quldBo4MzLamQ)Cb+Le|k=tzDfV{^~%?oX7X1ctcPgV$@F?JB1d{aYsi6J)4XJf|SJu z3fJINAg-ZvM4m%OUV*ruip)y@nld&|V=2NrCeR-nX`UoDnvg6ehmKw~CP(hebJ1dF z2lFiE2AUYnGweL25jrNcO|;j9mZz{$B=`Lkkn$2sU~9FHQuDECl(#H@p6sgc*}LMh z#{0(SB)_S5Gl*bV|LPy=uDg7wpag18dJ=oa@8@UOO%(gZi!lJ~7uWb2ix80^@Xg^h^@rDJ`x>3 zuq#nFwu^8;`hu}*5_AV4fQA{)V?Xmw0XG~MoKGJ>7b)I#Y8iSC zu8pD{^3CvfA%63)XveaK2pEdri2m$lm94ys;syd{51ZWz48;w^yA~wa=PBOxtAN2e z{D)x=w;b;_Rv6z;!~{S?=5JjZ<`y&#wSsYoDamhm$cvD1&c26xaC*?cEt z5@hEUo8|LEtEp_hn9EQuJ9lFZo`$~i^CsbCjikmzGr{1y%;lM2UL5V1?S^NFXAOR; z|Hw{W?k-H}y|62*XJbPyxWhUw)AfxTnYvis`%gRKTi!m8Yy6kb-(FT1H^;kyQ}h8i zG%kZ}%7ewZsR&oW2J*i&Fn~__<)1yea%FfKn%*^76 z3m%ct!!QN~OEFYc#-`uMM%Jo($etu<}urEWk#E&erc4qRFhJhhN`;LHX<7 zp6$wZE&kyQ`IC@;#=*sl56+N3L88w;W4AWeKYmI`1uDf@9ZzyvMQ_2U^W-by$4cXf z!l-Y^ae3iltQMHv3bJ)ta9_H3*BthZfU(FH0YmzpfSIcZe~oqR0PYE|Q5g1h zET19|=L67)AGpsU+)H5~ zfof0XDgE}cGeY;VtMuD$t_WlWhV<8u$p6Uu{uy&_uU@N1{}bwXEX2Bvp5Co)#%LXM zfjnQ{4{iq`bDMNi+1U~=1`Mr*0%ne6|vv&_Br6)PyL;=+g-%<*< za55BFO4{U>ML{qfY9~(5i&jl~A}1?dAw$EcMqu*DrzjfM9eOJN0wQT%SHtj>U46yq#18z zU$4Lo@tK&1MDvOG2V!{?|JcWVL|bMI7&wl^fB}>AxPVa>ahUjh5%Dnbdmi8%a2%uk z3~ZmgjkgoGpTVF((p^QL7bM7m6yrKB4YCs0iudt2@jf=4ziZZu3HDk2J3Q)RqjU&a zw2a-sc|Qj>>k7<666J|gP2|)`1*cA$>m3d}a%XUni*N+lmdvZ=6e~A}GOBI!OOBl( zAFh7NRvdcz=$DkU&D-R>{4*M)xZ${1T8+REe{mT2nBw!gTeJgRoc!VZWT}W=+Y)A8 zA{gk17-RHZ(iyR95A_GW1`7;)4X?+-KpyAlBRQ_Jx&0S4$IWwyNiIebFoCbw1Wa!P zb5OYu%;}D!oCfxCWE^`X7Ll3x?>)*7FsSS_!$j(`+io{;W{v~*YxI|pY-y=i376<+ zwm!y=Tw$C*Ilf#U#rbhmOg76FM^7Op*BhyQ5Qn(^1`^VrD%Xi4xw-qAJ=6Tm zsFITVzgpFBR__#N32XC=zP~87sNv%3vu@7IYh1GY#@xJm&pO7oJs)lk*0w*wfKak?H8>aeWZ`7`sQcW z`6w{pRp%U+rCuwJ)E`W>)T?D?`;cqXqGPhn74?>}AfDJ_9?Uj1=eGS_dgRN$X7p`5@uykua>#dC+IiTlcU~4li_!Xpl*MHB zM_VG`v7&cj`TEU}*Rt}oelzV{AsFoaJgAz#t#I<+(t0G{E!qfiSrK_>7Q?O~vu!oQ ztXKEa$;FT@W#M0K|FbQMku7d!lc2XEwZW7vs8NiXpi_L2@#lzap(wu8#03fj1BnO{ zG_aZ@vPDrQSp-T8Ajp=uze8b;2pcqXJlVoJWxKUhnS8euehpfeR@+;~sai&qqiaAp zIaapl??1yTglt)Ii;yjOx%IY1>-4ZGTx<<3go}wo%(H6jgA%gFlo2?4)hbie7Br8* za9a4FmI_?AmwHNrq{qcU(V1CDNJ>wGja*qFt9Cl|%LWM^U!7#5v%lzU=`tr{NW#X! zoU>iz)ovn1qj4l|OHq-Rooq<;VEe>i20}~E5*G!cj@ho z6%}e8rAu+`guak~F>r(ADaDB3Q@#Q17HTy188DpA&b5?aAQ2G9Qp}D7Y&FQwLnN>? zuQI>VosP@;2v4~z*F1X3kP+A~dSXl|)5=5t?RH#beWhmkD!oonk>+h4ar(z(bMFsPCF}@np&iPa)U3qGn+q!PRPt2IM9*o zwHKUr@zhn@#+8)Z_0`tpH|OS_cJ@+;*CtQzDK(ENSM43ddeQ-YRUHTIY;#(l^NwwQ zI=uGqjt%R#KY9K2Pn)!*ernPd*8T(1HtesK*_LhQ{%Sw;GVom#Mw-v{F{>Wn*Oyvh zV2ivR3xoT0KGhp+`#Jym=zg6j>n7sTX*@N9cHSan7}anSv7kbZOA~Xdtj3^j{gfqr z(vnWs-(x*lO}(@5v`ZS#d1hQ`@jYK}U3ybq?v!PGHS+YD(k}Fnc2?-Ew)Mg0@blaC z@Y-K?T)ScW6E|K*CbKj&{Jm{0?13VwW3XL8ezJ>Vqhy|NUp3dvC9DZXJS{gH{nVr) zRwROXxQBt$eU6=S;*7jOF0$pa&yJ0|^ zy}#yuN zEiS$aC2}3cps(gGrEU)iZohc%X|rYhOIxY_dRm6r@&679?s=cprKHk$^al3IN$+1x z14(6P>C@ZYGrz-_cA;x!K9)3nhWvy)m(lRfL_ayM?ZfTG$ln2#(9xVu_y()13i2tB zleVbC#!_aR`JP;_v1Iblk+fN!R62Y#lF4J>U#yyN_Yt$@AdRfm=~#SP<{cZoJ+iB^ zYCPTAV7K~lCdW7b4ApkPX7AYTuA-8-c><3O#XNy_z&~v;KFYn(`1;0aim!XT9(L2m ziRxiX+-j+Zo^G@=mm(z8K4|liXgjcB40w8Pq@M0u!F#!VW_b_kR@9!+4)v3N2bu?m zf3%l_zOsL`r~j`TpMKw#Zo0BdA5wOzd>#EA ziwd%{(o^BcfFPsQft7kZBBwTHz_lVB0A39iGiqCzepBa;$<=pW5Ig$!Se>Kuz^t}N zyA5r&pgEIRlP9@v~xcJ&jgi zQ$phP)R=UkIoM)#jL3RwQU=Z~kKOeM9iz-o+Zp}s%Gwnb=4QLo!QwvVGuBg!tHZLS zYTAk19!Vw1UD&+nl6oQ+NOVPwcZNiHCI>m|7Cj7^NKriuUvR@u6h~1X7j5{2&^Glj zD~=KXftccPl$XmSZ%J-NUWK?i892&eIR=ibfhy z$OA&EDI`Z1sjoCOSf2w9fjGdnQT&5b8zjv}H*tyF%vgTGQ6#Wtfd}vlZg-eQ2Z2tJ zMpXou)Z?V~Z3A5@x_C=)XM;Q0DV4Kw+Rnm!feNjn+{i??4ijguYGfEFMWLxYv)ah03k%2N8C^15#A%KaT}HppDa8udoCND9c1HSmv)w#|>opmMI4 zaTx@?EGbSe8w?*YWDwQ^14il{t8-EN@DW>JpqJg50LB-E!TPWZdv$0%7>t|<%Wshr zaV5`*AidAL?+5+I9yG)YMgNu0Y~wKw&Ib|{kB8ZfZVVRjvMr3`6=27wPq~>14qH-y&tf>eo8LyRm^3gMNJy61<%XxEav9N)|;YpjR#wrvPm|xFNvE11x(;w<0d%Ys}t#2aNu!T z0>N;dUTcJu1nIQi4iQg&9fU-mUR?*)4FuA=R14xM^QGeOYq2gan?kVl|OTI+Y?% zWxk@q?9B8uEUpEtz}PKdvYqLa<2Z%kgbV{?^Qv5VKo8e%I&>vGZd>#R|6-@DJoUmt zmQtsGso%o=YbP%mn)}O#SLizz!L7FX>V9f==F~NV`;@JJOukEa(uSRF@Yg}x8uE9_ zgTYVm@&APf_9W&(=f8u?-D;_m)J-}$IEL)Py3SA@?FIQV)?jFESbDMBL{_okB(aG& z6}p#UBDSlkt}@KTD!Ml@-b}=RHN_k)nTf293@jXrqSV0=iM_fEC!}=gocDA63>tm6 zF55SMF!Yok4s6IPG{^tSh<@*|Rp+Oq0t1-~7dLkA$5Pq*gWGsvJiguSm9>NtC!3>B zt6n$hnrjR7uWTGEsroEi=VNTx+5KgG<1>n!omnwRmM+bxEpr1MTn=G=xeY{kqBz7I z3F~*WPb2lsQFz#1w@2z{a^IzBXOFZsQooF1R(u}FAN@k4ekR3KjQY8hM$OmMu|#iX zy(>wc7=eG(^4|H@_eSaw<9Wk6F2qYj`-qnqWWdWt42kL&MeA{Y znuurh!I@u?b`blS7hV^?_TxNI3k>oqCnwM?8f;PgL~PI~p5R-uw1ND#uJLUUk4A8y zA!al#g0rO*U*Tg?)xAq1xUtWOjtMckyCU%WEcGKS_4_ULBQ5niDeh+AY?N7#K1XSU zVtt?y9v>5Zx5gr2OmqrumZ|Azd(AsEja7*DBmT`)Bt8xNdFyi9@;V~&Tma0dgHYr}O&TXMzNO0i#Cwb|9#t->LmVSr$~h_TGDLL!*NFD^w_O3VBi?s7l& z)=_$tA0xy3nnOm)EaFL#VQb3N@?UTE{;<9J6t5Wjt#6gTt@wU_x#PGtBWeb$$xX5~ ze12@gYi|n_D9?PJX&|Ai#PrWG{xdNCLg~t2YBoZaEyrI9U6*?uF`uO7($#i}Mqi9z z9UW(Y3qcY>1q&hoV(d{kK5~j>V=q%#8OBX}nc~K69kcvT;Mbdc-($?apt}p^`!(ew+e^(Hb5i{L&*f9R~et()b1>=`<0-^7L9+T>oC%?j!+YW8$`qis>CIG`PfdfJ?Z_Z8_ zz{dT&+#D!loWrqyg|sot=xN$xM}D3;az5+PQD>LOjG89iGUjkt(7N^})&meJm-jo7 z4KH%L{v&b)2u6J!c;PTmvA&bDNbX1YM3rYghVP~vL|ZdKSE_43PdrRG?M?h1aEad` zWDf7gEYT0_Luk50i2tWbCla&C_@aEN2`#Y6&DlVdc z2?Vs^%_DD4xv)v#>?Gl3>ee}QhYLVxiG-ns42v*y1d4_xr}yXXD&`q=}g)yOX& zz3YaT8|BTT&bwjQjI+j^f79^O;foPCgA6|a?`Lo6wBRHkxV`|#0s}!RM;WwfgXa-8 zgu_t`oKgd<12>qzLwhE5>)O6|hu#(C@Y9KLw`1*0FIFq#?juLTgm}gO1qII1h=Vh0 z;J_r;zeR`D(HV~z=q8{g`&=H^fZ_#O{XiZbMtTFqrNbiyKL~o`x*I8H&?5~!mD3^D zn??Ns=|!S{1D^C|Q9qZBvDD+dHBs*x!w@Tqz*FvkfS(`Jexx3;6(mQQ@LZ4Q@W>~E zz6+@`H2jP0eDFod@$P$sHbpr%MC%A=;7G!Job&?8!*9APVI{_Wk0!C=qB}B!M0y4e z^G8%yF8e4fO?lwp6|43vSM|43*PeORkZm*1cmKDHeOH)w`;TdV?z{Z2XXj3SXvK=v zFHL`A@}T_>UibEV(Leia+t-MRttWXaVq#ct;cFkhB@4_6e-~X&M`xiZ*pNS4YH@ob z`c6qG#_f%CQ|<{avy1%!_?1bO6@hZU7dz#1GjSBS2(TG9K8i6Tz*cA8_n4Ed;l9UK z5pd_ytaE2h?o*cACaZrpyC%1ejKSk)GsLi!adRu$*kaHEydWdO_5|!*kA$;dnbp0NG29B_WVnA8qINqCl!uZJdYO`%~^!JXiKvUnxR&L&2x=ep} ze#WH6hO6X@LP)R;Jw0#fft{g~xQ-W%NbV^E{0= zdE5v&-A0}U`ipy2slOG{xZvm_CgVgQXmTUqpn}1jWVg-2Eb;5blA4exR6%|RTr@@! zmaYe^BC7M2&<%@N^RhDG;!jOhZBhlRaB1WPhmuD=Z78;cc^V(B{#fy`<{LxCL9g=s z`kwxdm4kabGQ~LE82;;*6kn3g0_m)@SU*r}AcEnv*OBghTATLE_~;jgR@k1~I(6z+ z{SAQ=anLLBPcRQ#AtSx;_#;BDqQ_~N4P@|A-+>>9#>kYA;})BeJbq803>%jVv2ocF zvPqL;Cx=Gi^=n_4FM~X%*+Bd*D$ZqDr7PaR z4CG$pgE5vmutT7K}a5aGoB(J82n&OwVLkLW}&49hYZ%rcNx21^s7VTh4g zi3}@#$e0^@UyPRIn;+-5Jq@}mlWyaS`4b9~ndx3oJYhH*-t{8D8u3{;(-DV)m4d4) z=+?M;o9XlRwgkd{Y8AL4P|Ps_2FnEu*L)+{%W-gIoB%22uNuu=0k~F58-QHVMO7&epD89SZ4bhxeZ|WA@S&i$aL^0yl&7%WeB@4Ui#2 zp1|1;I6P?hmK=!GZ0NHRlvdE~G>i_eS)Pni5X_FLl5kKy;E*r*R8+`Nd>WZ}P+cP1 zxRt(hc|^LY@1y5z-tJw-YUa5oH#A$CY4HO z2A!#lW<*lx>?=~nN+33%uPM#6$)1xZXEVy}u-m8DF$aE$u0;j}`VIiDf0JJTZAYLc z1<7tIl}dsBF8mA#X7*YjTbPQFlpC%(H8Q(v z#)PSjS9<2K8eMOY&z`sZi@CO8)=`2u~kXukskmF z9f%87K*Oi?Oxz79-I%D>hD>9JB5J!%zrIV?6Ab=MN4Ei$o&5uNkbOjJSU6hK zsZ!f#_$W`fZkTHe?N6aK2fEh0@Y!+uN_aaKnE9>3U=NGY&Ri*euRG;?MbsGx_kYs3kT+&|7vht*C4LvyTb160-{4d- z`4sM3-2h@zopWgm3HXKTVZ6gnfV<^TGfA8=&M&$&@0KI+QuYk1dB)ao^e)kstqXn= zkf|+A-XPi$1*(4w`+H ze~Q$r>h9GTI_WitU6w}biN^Xw;6LO#vuI~e_*AoA$>usdugBeSQ+Yd!abH|y9CTmY z%c6a%x8j28`Rp0^9&35`eDUruv~&6HXg%(Rn`gdT{zoPMH-9(ogNu%BdIVl|F8Wox z`%~QeW_>rG2i*R)FTp$zY^480{{~cK9^eOR3mNAC-MAvO1}V$M4$>99eq(zndETIa zK_mN^)x2Et&r7{3Du)eqf%ay<_`soHU(q*e>sCJR574}0HuJ+M~#`wnZ@5HAuA2JrDwtex*|0T1AiFSL9cF%RidfrPXFu!_J4Kzieum<}ujJntT_hQA4Zq8v|#aWSl2N@wXL z{XJNqp>6PdGR>PRn`fY6%0At?(e2rD$DDgu&ArU-(~o#&JgJVY9;|7dDo<+f(8u1g za`lbMfn%k6C*LuhHB?kr28PnU{_qC$=|zsKN0G=*XHg9?=f&VJ8bgG?Xl#n0eNk`H zKFwp?m|MdI=FX2fI*-5iMYK<|Bk~RB$_4l?Y^5)t118hlI5qg^paJ49(D)d`6e*Fr zkZ`Pl+hbn%VchYfXbKdsnze4+f;2@>Wux@le>|gy{hecJ{?%5fRQjCqv34>g#LE$F+n1%n)NAkX8kPjgZ7zbDI4&hvqX{6h8>5<~XmImBC zVdGXF&K{vb8#!di$n3x6wtNo*gV0&01G8)L%Af+`@KVcBrg%MeA>mv{j5`yaCOWGW z2R6&FIqlM!&~U+s5x*%-EE|=Tl~s~eT!v_l*OSh}Iev&qOen+_Wt8Wj54B$8u+bG* zP*at!_h+&p`ukHB-hORX%FIVrvmaA`EHTIH| zRW>&iXxphbW1UKh+Do$j3uI9~`j;hnrMh5eSRLdShV}&Rg|z{jqgmhvb<;?wgAD0z zj*K*Cl6f{UIY)6lpd30=4 zBy-N>UFBi)H6Vi)kmvC{D0qxm4dpS0{}H^a@cVxROd{S5uhV_}zE|E3W?w6rSq`@5S=5fKf8(yasx&Q~@0VFwp7tgz1ckgy#~5Pt})N z+g11IBAy)4I}jiESnp+pan95IvF8+lw~YI1agrJ6IfY@~TF^7xVN7zuTL>Rb8qu@e zVy4#RAa8BKri*i5V>K@%6}8JPaJuqN(XQQS+j4Y8*A6!2BS*TxPd4t!rTtg|`K zFmMgXatV%e0r`-d)#1OD9PxMLnW(NF*T&o@Dpla`tMK;<+_MYb1jL{}EiK?BveX_h z?*pb7mg1VAGl^*onWV^`9lnJU_5w}^%)}&|39W#G_+~Fn<7yZzUb~(9ZYHP@lx4t+ zrZ8=G{12jFlY&Jh*pF9IRZ>~zD?oy28ox*$wqh|Wb{TxneG|lYb#xFBceep!+|bA2 zkKFABzXeQ$rNYGJskNIf$!q6L)@o`4-88jbTe-{a>(}1X zy%T#RR40G%y@BIvH!{!Ofo=QO1_Ir{XTT@s)u8vcTBUb_Y0K9$4g-1@_oRS^%<~7r zFGc7bFhuX&#C+0k1-(;!gx;|?-=ufmChiMOZ%OY2W6(SO7W7UqC!qIhBJ|GN1-&nB z*={&5Lhs_;^Yp2)^e)zC&J!xdgM{EIRYX0h#CM?=4Fo zGoZdXb&>w*^3-92PQ5f^zO7;R@)^x5FI?8}$jVTz{Bq;C% ziTFUkS4!b%IvADvr6X~zc)zqUOxigdiwdMiyinh(tYgIxxToU>tiKnJ7>kp-1p;Ex z!=2Sk8X5jctA=i4%rDL?Hc*i*rc}(NG>y+QWF_X;`~&bgLCiD$%6D5QnqR0~bzCG= z@PDH&z=$uf&ZAXt)4$K|`$WUS)t>(EE!I{-X@t* zA@b$YSNuh$Ehv$2k=2(ArZk8&!k_FJ1RJ)o{Nlb(uCT@+fHryp%D>JgzEx`H{vPwjsE(9Wg$ z5#V%4qe?7R#*{>a=X&(Jaezy6Rt9u>V7||Hq9h6WPC?g%&K;NC?OlXt1nD}F5+oQU z4IIoto)O^9h;zOD^qD-|8MK`C!&|_~`b-gi(+m$N0Bajf+D)*w9+Qf9!g|Vn&)jGa zlB9k|!!Z-j9>m@;E$9U*aaC86$~v*uS^0YOF9~p_SnaMFRRU|D4Q^z1&Y7Flx|!K} zm&wF_=uKL4=Tx?C!yb{HsN8TB^Pt$Lxg}vVl~}k+2%gyJ(^bQ4fW4b@$K*V^Y9Xwp zOP+4E?VVp&p{q`JCLqX(f_Q=hB{)WC)+H^>rM4;4eFA3*&qj){mgXKdo0WP^WWMdJ z(BfKZWxLrMnz_ugx37yx7Jm+$RU2T-q&-d`{H5$So@<2;TO9UOuB1CxoG#6FCW3m! zostBE#RG3-J`P~bE}CagRJc7XB+vr;8aOb`v&Vat+ z+6C!uz*$X&4rMRJK&nGMbO>jc{0QjmQf`}XbUKtwbN9BtMcJLM7Y4y=)uKCxAFp2@=yaFe$v@%#=pyt+ z1OxO&s>tJm`ny*Jog!U;8~0^|lv?7j`f9}1P#Hx?5xyF+dQv|y$)5a%q!lQ*nBFKd zAUw1Sa~$Vq@Jm!ccvxrX2I}?M(7N67LF|K@+u6BZ54UZzY7i&IBF-Phwr&NEg+gBT zs}D&m2&8jQ#I-eyw0mKR) z+Wljpw~F&5`qzks-YRSo+Bj$Q{7l*&kw3oHe}eRqcl-<9ag4_2hx_2sVyCtKzS!yR zgm<2CQ1of8HV$$D`M&GY+A)us-}lS|{`znGzOz->E5vu;ukSZ+%E_eRj^(>Q{rdab z0~_4y*Dm-X4PO5k@U7ndl!pmO=)p~4ucH1&%XPnT-ZWKsz8hFXJjosXO@XqWhe@of zcN`Pq1fJ2?qmgf&1f9wk{Fr}k2yIV1YeN3}-8|ni4E2o(KmEr%?do~I_D+87AN#d; z_G^Dt_~~nF+r`rkovaUcTpI59!RYU&4;T%30zU-p^N+=^(e8(@{_WbFpv@HH82%7v zy9Fz{%jqVEtzrpRHSFqh;4&Cc8OQeC5uJ(!q9}tU?Fy*5R0BVj*^@f zdSAEDTg+k{io1Zg ziO(>E_uLWRL3F@#4!!-6X_U40YtQr0B}*CGS8IDY+gxjVg@oiG-tm3o43_rS+FmJr zQfvDVoqxIgY*$I(89d{A>8H{1In7f$ANqYB1D={{M5@p&s|wZW^4?%{v+K7U-RzFU z*g6s6VKLSi?RKwmed#wA91lfRNX1hr(t`!s72j!cmq_lE2Q^_A`9ySe7$!HEe^ zSFd|iNlxbhN$gBI&vUTf(%k{09<5jtAD-O5*^ED4JpSiQ_RGsR-ud+xdB&2XGZsVX zNBhM41bhJgN{3%Lt-eO^i(EagqMdSWjV-ajOAOFZ;VMm(ro@#}CFvEk6mvp&Ca)qz z8Au8-2L=)By?0MlO~Cf{>0c6#)b5g&SPP$tbf&@oE2gdjS=*N+3Tjp4Nm6P??k86> zS8_ny!1-D-ttEq}wG0Uv%3Av+)#Bww=|sJ9J)u_1!P)NZ@*MxPS~SPY;Pp>qj<8co zlS`r$rb^jaaf(5WwuObNvH@|(h?LYO90vhKn{YDGM=@Wgm~Sf0Hwp8_1KmjpZkxAv z5o)5k87U5Ytxjf|)nuwURq$S-JfuEfCz z@wP+m(%K<+t@pJP9Tx2}<*^WXU?~R^1-f@~1zTakOy*F>w$V-9c0o}rUMXndhYXh8!feWFHLFA+8 z9^~uLLb-6&*T4yJ$URd`N!F6uq`Ck-;Y4lF`?>qVUQ+`lYMF`A;f-L3Y~9uz^tZF} zdH&WmzdYzHD6g-c%Z4^ABpeeY$B`tFyeC#P!1C^C@QZ%Y6dHHU=tI#jLbc;v9SW22 ztd3vmpBlMrkh(Y0N}=SQ=oiZVBSJF$Qrf`G>zDnu{6pPrUj*30GldtCMrA*AezSl3Ie94dVEey!UZ@A#Sv1- zjUCE^jh~BuM$06r6yOMaE zf1VUne|vdeJ$(a4lVO6kfCbSO$TNw40AB0?!7Jiuf&gkD6dH28I9b}+@O+nUOKAue zUvsa3xfQBDD5`1oNl~3-N900HFkpr7uD;xlKUNT~-Ubw_dt9}fbK8kpvxMkV{Xx9B zeQHi!Dk>{rmHLC=9aP6ax0F_rtkrj+IcT^^noF%PU8oeAnnL9&G_9-2>k|FTJ+=Ye z+hk>ix5}CKdRg>z`KeL;O}7+NkHah7F3k?1QSLsp*0|f0**KdKl(`}h!$T*AB*G%| zAMhPG0_Sl2wg9lmA}X5L7AAKG08rPZrrHhg-9f=yV!3MIc#4wTPQDYdjmS92w%0^x z-Hrntp|V}vv%qDcC(RZ2>0+Mj!*Q}TSK~4GPV`q*Z-1j@{4d^i<$iCw$@p${lBd6N zfb=JHR^azz{ms8W-Q(iB(39>E-@OETwBOl+|Ha2O?L;_#)Mp9lki@&>qk%q%WjJHj zeJZsq*J8YW{9ga@V5@Feb370ha29G~@chAGXYX2v7{*277vS3?A%XoJb%;fUSLjWt z4lzz1>@+DbPk;W>s|ohmL$~qci^eq_HnG=`;NY&kC#q%tdV2DXy1ar-;w$8`Cha@4 z#G)X-G~oCQXOQ4%P*Mo4O?WinCrVmY0WXL($5k#ulVQIOfypf-G9pOC(W+#`$Jvbv1O*%hI0XVBDL4U#!=uY3c`rH=gaFwawd|R2 z7%J4mBK1P7+Bu>8l;WruQHNDUbRE0;&QCaJG3LGldn_<2#jT!Svn;^0;;RL(e~fF3 z|HoX~wZlB4n&0je%dnX@{u+5;U7#A@rFE;O&iv5y#LZKtJl1pT97|Aa!{#lUIrGBO zn|*cPo&i`>R=tC_6LV-FwJ&LtnGhdtf@!rr$XXFr71xXZRJ1S{k^#I1J0=z8=VT*4 zZd71^)POY*ra0X5`33*m%s`6;<)hqxL5MJ`Fl*A7`wk1_U- zbIw>*Kf`#zimB87@iH;@W>V*pj*WBbrA0@8M+6=zbmidsK}}{%)?WK>#<;;n=F zPU)QRAd82s_kZ7fQ}5pK1+iN)d$Z27+aV)j!#4j5GJtjod=@mSJ=TY`ID+Pg_BP&j zqh;JMJf{ATA%Op&GorucUOi_yjWgA+|9EfzWdHu~RmF++ewS#SHqKZUp^x9l*PrxH zs9o1l<0HIz`srI`rYW9x19RC7@0fE)cPhp-2Ilqfz>G0T&n((O8)-}$o4#4g*fc+* z=nHpWe5*UoyOZkBA{+@NXvsE86-?P|!E#{;ap)BxOe*A);FO$olWm#Fl)J$$3g?nN z0vb}y#Y!Zgg&L$N4cD*kX0<$r1-<{#SFsV#K6QFSNI+T7p3`GlN_~Fm)0Jn3+0t3* z*>0ugfPo!)j*C=M9)9}y$M1hEIX$6we#>@kt=pa*^yK&(Ez-jp*3EC;r3e5ZwImG9 zl7Z>~!}AgMs8&Uuv{RG_O5EE*$;m1Z5vP-Ibk0n5q&l)wwcs^DnFJB1lH=gwHTQp_ z<01|~H@s&ai`e|z#+6@8inOm9rL0;K8~N~+Wv^ze8@ebobmBety1Mk392_!e$lxWR zhtv*pjt?97%)BX2#)nzXZhr7sy_;U@w$uE(wg%wS>7*+_^K0>YAecg(j3L2Y|B}FhJR(>r;K`#!)U004I0Q++ zBDK2LP|v^|8>MlHpw0Clu_)T^Fn)-Cb|{Udeelq0<>4W%T3C#Q&a@8cA<^7@qvvMl zL|Kj>*sXL-Kw#UPv{tEs0reZ?1O)aiExkvLz4?tAd-?nRduH?;*{4xPi`3*^Q~Nyp zZc?4E84HeY-m*nEXI#rctr~T0(LTR@r!q1B`PDzkOAJ*~h?HKEh8$Ot8Dt4Qt5}-( z;Du_iKTcbi0>+0S4TesAFppx^gJm7G4!1S4848Bg+p{6YP<8X)RRQXkA;C{PD!$RF z`X|MVZ$wJNN-V_B1&D8y9lN8WMkSU+?82s`8Vz}9)RUe-!Ka& z10`fQUMk>Dl*X4>Vwe#=loFCKYH+6kO=M-F1br(rN{F@t%|;a^p~?qwtAtUZ(gg5R z(GSMRzwZX5aoMO=V+6E83D5=+W}tLB1X=+*iv8+q9u*1sA{A-OBlfBCjk=yWAoYws zH^uzj#{>DGi;B9ec@7jV+I;jGw%Tco}{xC14q76{-(&_>iP2C0+`3!r$wruD@SCJk1xD^j;u zU>C4?{#`q0VVr?dAg#UCWCRKITk&<>A5Ghs#p-6AcYf4^EoV0bAYXGkbbv#uuPIBh zhVk&Pz5iL^)?)IkBa|5$YDmcDZyr?xHISFpmrHIE}BN$cl+KI9QS+OIlr{u+za zCw#S&*}QwsjHRqAoS?FuDY=SD{Bo!2tH!ffgM6tebCiVCWx;_l%oL2HY9bFG+971@ zR1|fh6d(u60h18j6l@9%9%X@I3>kjR$hQDlI|%-DPO!X8R$}&)TB{yVZAIAw@*$=@UumrPOFs9 z@^#~!ODH2fhd>-^obzJb&NixeZ*ml9YN4;}5dn-50(M=U?H1dm`5S#hV+Jhlj1ca;0fi`@v>Q&&Eq58x>|X+PPhB zuI;G%^+x%HbDr4C)HUCp>^}PNM94<8m$dnj zZGJB68#&KIwB1L(;lDEr(QGU3ngHNrf;8*SyCxk>r_nSK&Ic-xl&R84N||h|Fhh8S zXs3fJZXFl8n&$s=Pnct{RtZub$^Vw5io1H%T};a)pH6%)+5a+f zZA#o6t6xYU=CShmm)`eG@7hZ{#HI8N*k$5pJ3)Ve`xHDT$ymsvL8*|a9drM|I9w9# z(2I3tuS)H;$b$BIERPfpy@Kyu#B)hYyziP#u*K4t!WLVK1=VsiS@f8YPLTV(?+Si- z$nE@c^;eMh{rW)Of9;MwV|Y{lK8VG5`VQYJn#(Lxnirli{5K6A#7PTyu-8q%yIjOx z+obY4_c{*xN)`7ru@!J;)skrWxC&%NQ$c!becHby7!PccjW*Lrb_DPBs~=#8B3~r5 z^y7Mth|B9s_gkJ_QyU950_W&Iyi~v$D^-Z@2ZCRp4zUfuuO={rV7;*?qX8W7PLF@UJ}566himNu@7CRpch%n@cEayn<68qU z1dU01DDVzr3cQQE1MeClj>7w{z&p)X#xK67`Uqko{Q3az*5845O%M~|*9Um_&>eV3 zbLlMbPJ?F*f9(#uYlk{yTHcFtVc9xrB|RZ>f>=pXBQG?%iR{FQXqx09kmGdUGgwP? zziFXL))cw$O6y;OK{S_RgcsS7O+xeM@bi3kK)s9*qaDcJK{+sxHllo`Z4Apk&c9A+ z{YuCeA_+#-)am!g3vX`!Zt5Jdz5-VAy;G)$JsSfiiPl|fhwq)%Zak~$p{d=l%g_f= z!K1agA$^gUTa3rUj^-8(-+vW6xp#sFZ)qqPe0`4$27Q*gSAuX(jgBIZIuSW>?-IG+f0t@C}uVMx7}7CNT$raPzY`1s2~!-8)06_aPx|Azj6_Nk6EQ4}LP7GtNh znVn+kAEevEPEn1r7)`ZD(@~*VCy!c6xiXOApHh6!3_~Ez_JsnPx7Y--TVG?VaBx`sKoXtzFzzx4{OUq(k+O>c=>vRtY}e zegqN%sh0bWf=WQ)5fH5_>1$AUgdZhbyP7(YavYUaRz74K$Fe4-@YB{`F33;1$4{6v zX@b1QJ@DgS2_Eq+G2iw2e80g@q7y#~IuQ=(6t%%2gJ?y;k>9_HBJn^Q0s@3y3&koW z*l!~vq;M&m_*b0xKrQ(#0$NDBqw}nk`pp1OXJOXFao-&dpl$$C`vLv1Z>J;AU*zRh z0XQA@`#%2lmkam#j`}bH-wQXLLjgC=;hSQ8Z<~)d2H^Jgae8b(Ti_qoS{n!ZF|K;~ z9r#!CU7U?`+FokybT1MN@JZM0YocA?tJeOtqW8y{@&DEs{`DPa=Jt1Qc-|$P@Eh~{ z8tp_Ev~PXqX~!Ax|JGQk=^baF=Ddhj?yhwW?}7c2fMAOsSwLG>EJzEXcuRz z);ZUB*Kf}L?KsDnvxaAAr*ll-(&NW;{JZQuH}Gknpzks5lc1LZFF`N;)>Palq8&c# zCp_b0Ux|i^cFQ$SJMIVX{vjSXNFMI%PxWy1{u7zmubto&c%a3(dCrL+-dvxp!wK5# z9beGq%9{9r{RYW0SU`t@Bu7btW}_$l7zOZo?DI%<5sj=2(RIOC>VYTB0r!%xSl*zZ zU_(OlR2IY9yPs0a-6u*P?%L(yPIBv;+ab@Kg4EQ_H#YHyG;06O^abe00i}0r2EqXg z6}UN!t&G3S&tPmdu~{1bmOm%=A!i7=wKlr@1jeL&6R?YYJF4y5Fm2v5fg_j`)(Pzb zN1V0I+k`wpl0$+%JKh!=0J(~Ff)bGC4vUHiJjQSi$zhF-71EtPeU$Bkg~aYz3cCY( zZVhsU1+Qj};}}BKEG(;!b1w@|G=?de-JCmFbN5YtwjjV_NN$&id^&un)nV;^wCeuz zgV`27wEUx4Gw5H4&pFuU*ns}W+H!It(B^0g6nyz{G~f=FzQa$kw#M!?;HRim0XU`Q z!Zfr6_Jg06xWMVsVf6wH_&wo7hLfxL>+w4HuBZ651OmT%+D`ro_~2Xte%mB~4>-4Y zC%}iYE!qV5P|U2mHUW0f4}RjwH2BA{m9@1S-(jn2ZGT%nNW!A|r$AF}i?$hH zvrl1)1I8HIfA|M7hrX7ke0KW3tV#RG;E?+>_ZuG;jV&k`Tl68pUoBt|c0imKk;@1D~%3{a$!c=}v2NU1}N$l#~uQ$b2}Omw70IMPh!*t!UBs;61d zFey6@o*njLl0kqY3cFWM*=~!@$ZX+iHezlM#}L%M&U0Vd78YAKy`{5R)!gomq5Mgx zn2hW|Zr#AE&LIQ%Pwd96YThwB!}5JjOmH;IY^d^{{5Q4M-F zQ7hdiI;`$ky1G4xPr|}&R;;1;t~fiVwKcqf9~wNyV#60wx|CItL3XCpgqUa?dD-77 zSNHA$bTO_1xDP?QBQnBJH3Ol2#jXqJT(?85yqB3bY}Mqv?!cAI(9Vrx(i9!oggYmq zmUkbrs9m7>14S;(E)kFi-#H_KTZV3=k0BcCSO=aku%IR(B@EdwIt6$bH|As97(?L$ zWbBV6e`w;^Vp6OYjbp0`HuQ}Ye@%Q_ijLdr{yJ;I*mjCvaS}i+fb-e@2r>^l^v=h<2Ry*1rDYzSP<$O8@a|_kH&r3HPRerxD?!Hjbbf z({863x5Erxp`G8DbO+P7z$;YYhi8uBT%z6cyO1F@m?mg-U$k-WIyXA+VqD7@!d34$ zo;iRA8H9HIZvEY82JI?%mW~u%u3CYQAe^ak&lMY6LcdBCMAUF0^gpT}HD+=-Vg2{N zbcHfq{e5%_&YJBie`}Do#mIw~*&#vM5=wLZwhsgLu#^!@F9v^DhXANZy~ww2a|_yO=cWne0j zOA^7$_{dBRW+u`mm>JMJJ4iWha`;LOZoxlgJx1As9BJ>f(eB?$*gW|nKhUUMn z+r=?799S{_2%Nt_@@J$kR!F*HOMyk#!!f{0m~2g^>mr|ueIf3XA)X{QL0&Dpe@<8C zI^1iRY)d~TA29!N+C9_^$2{Co`qNY|tkMHx}#P{t|56x;8 z2PG6>62=u>84UM>3Vz>n!otWUhuvZOiu1E8K%45-CP z?!m|)giNw?e5(dqD=GbOJ5f?&Q7joR#-*i(TZNB`Z}BLPi{=3VKPK{s0R6>s`hnDL z@`lXh_Dz#Jr?)Jb+j7~C28qQbUf9MwIH7A)`1?tzt9Q0er|$#K&gy-DGe&As(lAQ% z-Xl9BfPu&hR}R`&z(zhPq>vQp$&l1G81_^XWO4{S-c%2MD+Xs8A@-V#%F)AH>x8=( z-oEE>Ty87M#ftO}UI>5jI4yhdK*$`x13@bf`0zvU38EdeFUi|J*V`X{p1O=8@X4=z zoTnW!BXHP@XJaM9?X(Z;bFY6N<|uH04weS*(Jc8UTf~BH<;xXogD3@^TUm&YD$=Ct>xMtzCuD`>kVdr*5TO7g zjzJxX)eyRr0#Ua{!>mH7OLDT^#-!x5l0um2fkF4wzHAZSG7fi zBLVnrg*i-)V)^u8{_De&K4$e^IK+bR5B}kSna|H^{`m6yUzk<0T{bw}zd6EJGV3eP zvQj3mU&((u^(;TatJky8$uC`*ymKG^p0sP9+~dtR0e?8wWQ)Egfl||wMzDF)3=AVp zpm4(EgykXHhj1oZ9@hFf;6$gZmUmX&|eWPX!X zJ7qQV8#XDupUc_D$vS`IHl|k={yCNx49hgQ2|voJp9TKM!aqC?TpaQVB}CzxBEc9Z z2>J*Z9#F_wLX9fK$6$?7z_%;Fg*!Psmm;miwHu0^sWQ0&KnO8Ksy1?lGMN-4*#-e( zC_{ilB|j4NI=?X^(Q%1&`Bx-Mje4EgXCx+l&YylW>Z=t8t|lgKk;_&d`Zh6XbB9Hi zr&-piS6KGbmPPnCKX>vJ|L_^hA~sJM6ny#QOP7_dx1I?8>ZKRI#=0H>Q9@Eu+*h~* zVL$+!5DiB|(W9?vj@-p+4Tq92Jj`r{NdWc@fQQ{8ps{U65;YtO!Yz#cUw3YNO^fyc^Xarpav!#{e&%ong3<_)aww`?~rd;G=Tsxsi# zPPO-okJDZofjikabE#5JNfvx8gkPcNkXIlO2%gyFLZWRnWy7~dxx`WeLyMhaE$M_| zAw~5jyGEC&!Xg~;6k|G@YdO6r$#I$WK68e-7CDl>`^dr`Om{z9vgElq#}h}VzqKeb z?w$uqer=e`;$D7>6&^gu-+t?5{&jA{U)g-egawL z`#>tkw}#v?&P|LHZE7dxbxrgc+TsMkjBlOLVMesDImc9w`hee~afUVBq4(LL_c;js z_{A7QeWcgX$7HFh?q2=7KKtLPm$*wm;5Pqtlw1L?C^=$GZ9S>(j(0uL*Ka*VUq~bP zzP7H^*Ry74xXpiEB`2*bGX=b&?!bq&`FQ#sLSMi2rEyhQpD?br&a(eHqp#mOi@r~Z zzS?^G_oZ?D)?4&_Q}or=-M{Zm^z~bJ>Z|-E`fBS>eZA|CzJBX3#wDTOvk%nQvkyjY zqjL)0<5$cZ^Or;MlSw_QuN$X;rno3?auoPR)``p@3|G3ICe~01W~|K6CEXg8Zq+K9 z6xl%jM6oIyQsTRa?70wW1DZ%DnamQY@|46^R;m2kOu4kM_xdVpM60cnCcnNgJnr6! z#d3!X{wX{`6{c_XrEpBF#s-#5{efgdU^B;kVd}he!|`+G!y0+Lt@j65la)tvf#FRCZ_jK>Y`=_ zyBgS051oB4A8VtsYp7Hd#@K{q+`&GbJ1fL;17#i(++E;&C~%r+%`w2~QUllvfb4Fx zM$E@VvKefeI3Z)C4K?L1@O&3}TVr$VlO2qDN=XuKR7e||!b~uGGF9<_!Xyh0z@#vN zRsrl1?FO;!B~ zl=<-l;W+4uCk`Hc10C?-M07YsWr2&Jq+V)DnnMe}ab*6Xe3;=bZ^D{=@l|pPKlcT{ z!ffN#hJ}up$ghIYnokdn;r=G_c!FfV67Kd@TPz*g8Cqvf-4#IwG@ zPZ}5CStzXg6a$4lkd&TqA{IhRQfGKfVpXVopMwyOk{zILC}4=N2AH7ovm^MQ?qQ+z zQ6K};1>L56S%WddayO|V@1CgO=L&D$DrE8U!X3O(S@A-CQf`_y|EJgGsWjoTGbBrG`r9JG3&tBeg4jH{@$>E@gDpUxi>$?rhm6(6jpAL zJk8zW)(yGLy@UQJR{0fb6YF@MpA>L8RZt}8RzER!8cenOaiNlW)O}l2+)K>67n7p>y6Ko zlep-m%=x=+a8?et6V?%+VHR57eD4CAQi^GjvH$YKeVM6j0UOCpES;}@qfy!c=fFz- z-XAPy4&;Yh?hVT1A;gRAo4E z>`B5g#$lw*hWb3!3SV!l*`!w=!g>i3t)>)SYcaBZorw^5j<^yAqG^?+>TW zIvkg{bR++67{309T;=YU#4rB%Jpa$iYsa_meVw`Y0QY{v(Fg}TBDXk+SR}iPWs@sG z4LlfUmBPT0I*d4nPb9!{R!yt$eQN?1PDaJus+Cy10I`xl?;g7RkqtcSh^(K~n$VRxGeb4P= zK^gUn)MCDJ?zh8-U3rMzbF=I6btGSOt=?_iV$1}Mj)Au+c=Xr^YzSEdKo$EEcohIe zqH5XbV~|~kIv<-UM8D%S5se$sRg)-O~VSb8V}hXX#uvY{6;=n`e83pNR% z?Xqkf3_A zhn`_MXSa>!mkMv5J)>Uu>#tkM>V=ze?hjardV%N#?e7V|7fyFSgmcE7Nc42AN=g7 z-bdun5uZKH&hmB(7P}JV2T{Xndc$0-+acf`ec!1jV7)-s6fW>lhYNQ&+Hr?pV3(_R z>0ItE!R0autgfNh2Rrdv6e12Bkw*dQB;mG(TdNk>Np%B&^$06EJVixH*_O`$J3rGg zl3*_x0}Tty9o6R<OsjYYBw{Oziqy}xT^tnOmY-=AIc`;-^(Djj*>`xuO!b#cZfeu( zfU;%eXNPznwr=5~^aS?~(m(LQ#km6Kz)P6ifGd#hanKFIG1^PRV8G)rh+EtmW&{a? zL`!oQe?ZA{-(|bsWts1?UGK8IKmJTLd~mZaDI(O5{;H?pxER-|rf7R*Y=)mQc`+Hs z;(Nrq;MT-;iRj^xMi2)d_aYbx+?m0_k`x>fOySJ9fS^$`gJuAM6-N?ugp$Kyw}X=* z4mjn-O!>9G@c4t)IW>(R;D5QFJ@aW77C3Xe-8Ob6(AoVT&OiN<|DmF20Z*GdY5WXv z7BT;EfXAu22u|sB12l*lk7XeGY5}zXcMj|!3nR)Xipxo-x4@Ucz(9MTE!moyL^PIp z;c|f1X@IetED(2_*#i~ubg&ByWWXvrZpLOwSc+36+O zG!l5~;dX#JN~MSo0Y#08k)#+$Oj2AOyb@(ib%Z-CxTgIGzGt{a6Z7V*LF`Cnt?4|S;ZH8Z~jxNXpqAU+&u zgrxWeY_QHwfLl{50zhVoN3(-bx5wJ+M23?mIe-Rv3e;~(fnz?Hz3}3;%C1Ba z)ZFQ5?y2{wd4P46*ln!lFLHlVD7&EL-Zn7Q`6&SGb!r(frL!Z-Z9bl%*T zPyTuM*|`txzCP;+-}B2a{HddalhxPFsen61%8EPwF<#> zQ#dIqEyL4?lE#2WQ%~HAm>4!f?+mm?-~J_$u}~nUIO=4?X5ce1)(98Or@$p}sv-tQ zSI3fwSy&)As+vi59Hx=7o?uhmqeIE+_X7$%?qgf;8y=I&T0pVa=8r?2 zKI1>Q(wJ2acVCy=6@UK7r%XXPn?UyV_m>6Ts9vE~10KjKfX`&PD#1QMbgz1and-1Q zl^?Zs6&fYb|6ahke|vEbwgQCz&XJ&AHJFTqa|RPs%^p=bwuTB!d2ud2u1+*nWu-)` z$mf&f!8uJG3Of-(qcr0@u6E5BV+HAN@pIuvSf5{hWqpp$y1x6Nxz8T{^W@8O=Pmtt18}Z)^)=I{fICZS zAg$GKE+``sn$1iIIU-Y)?^ncr!eg8QgOgx}z=TYrFeAAV$dx8iR!Nl%8Us2;pXAb>c>!o}Jpq#2sU{UAw;?5*z={ z`iR&j%X{YZ{D3c9_gYlMl=0*DL`IZGWTtjL%KH5LE9-lN|6KjkHO_-Zv%n2|nY3cb z?>nC6m&UM2$Iof;?17HoF28@v&IL2S1RlszQ`Ac}V?9&Ak#s8QAi++4yeLDsAB@v=oQo_Gd(ReDKS1aCYp+fSOTyRDJ+F*^pee_nA8p62}m)d zA6F=LeF(uom`Dese0YTavLaA27#fuurKC9JlREKx~( zxVRL+pTw3#0K-93=>gvLwD&(|wL6l9_5(VudtYQu3N6x?kbb z`7f;7p-}a~XZQ18nl!!nIEddeK}SwhuP`nnI>MkyCi)_e75I}={hhiUIkl6JTM)i5 zurvcaU_=~MZl-?QMa zw+=4vyQc4vMT?)MGf`0eona&LI#4dW#U%l0w$LEeAc|*DK3l}nz@~v+V8xng8a#}I zd<34d!IVMK`y9p&pZ%Kplq3P=;0;E7uuB-?_AZD|wZjkz?#YU49pp8FMVN#U(nmzd za)bXP6HFl-$Hck_VVYHMIo~fXem_&TJ+!t(z(^MLeRF;#G-=G!ELY90Dx0;xPMxZ0 z5&o0>)GSs%BQz(IXrx0SHeZH7G%Fxi)r7H zpS7F72dy1>Rke2HXT{Qa`}^9<*{)jKE2NKVZ67Q>S8IEv^i8epL&y^5`L1cH7oMRk zzSj0(tc9=LH!n+-1lgCy;WooYqX&Ly+*w0`@80>{<+*pBcX{re?_HjI=Y5yw-ud6< zxpy7txpy6W@O#(eF3)SO3w-_ceVw4^(G~km{!&^ye5zmaTQ3iO_`X+TJt-%Q_MWz$ z-gUn7y-_vr3;tc=J@|Lc!Zvu{^R#=ur#}Z@Mlob>fL2C=LjX4&2pwJotk^OV_dt_q zP)7+)24fYVPK@pekRv<+^5rg+sMVF`NJOT>tmrI^5t)?|0M`Y@UL*;w29`+N;38)s z95XecMTj-}H4dw)<9a$vzr6Otq2Uo5XFRaHPUM zyO%XalC$CJCgCjJ_2E+ZYre3cZkS;m!@y`dxx>(`o z!#8&ij%4jvi`nVhrasibV4k#Y;KLnbVh`{?r;mO#I%;%P)s~o;3DGmJ?)>3vOL$@b z(mCsYh{%Y~ZJ884^Zdpquh05*@%q*4*RNkkx!`Qb71K`S<7!>f!e)hIDF9b8GpN!Z zGFicyLV-I7+!1t2?C~?gq-aWx#5hQUuvLJy(+MypL>>vc1FAPG7kqVdX@0n#NPP(L zjeWo7;#h0w;)lle4YfY}-O@MT58&4fefyM6HJi)(Zw?RKR5c^eGIZRiF>#DF;qLIx zt4H)*o|G`RZ`I1ujcf9nwCPk_*!=!x-I_J+*r`j-V|xhq#e4+K>P0jOv^W|+WvY3v zj>J48rCbT}IWPmV2=HA-@+wj$iTNQ95i}ZN(?sYvsGwb5#g9uGe}taziGNA_Va@GragIo*`R*wo~yWVqv^_D11$r})>aO!nAIWS z!}1vedQ}9QSa`d6WwVyX#!curU|!$4m(SdH>%x3Fw^@(wc_l+OJkj#o9?h~Fb#)rW z+1B?9CPSJZ?m*0|n`i&xVj-kB!Ms6I!QZrh;3{MiwS-ktPp(EtDdv}yKxJ@4g3Ly- ze_C{|%bQ+}(iHh6DoWFH{&)^JJM;0oW=LB-Mo*Y-u?()-Y-Pcl22BbG7*y7GTnu+N zWb&KK&Q@7N=1iYf7HZq_bNH_9IbAxHHg48^bk`PzMWt;U=dIaTx@u&vc?n6&`j1#m zo_DlQ^D!SA)^Jvj#j#N4DqUUmLZhT*eMhYBESGg{Sy<5NnVrX<>Cm`Ex6#-ZZC?x=^Js`T z{(<$G!I+bgj^KSm5i_AAv0^F)$7c-#c`_oCE}b)IFH8^~Ws^h+ri_)K!PqYS;31|B zNz?MO>pD}D5@KT_>>)u?L)I{Wa$~~D&@)FchySp9QN`NaAy^su%pRdU-n75AH>>`6 zFJJkM{mD|A*)tH2-;=G~w7yezq_%Ih?d!^UW1l%}F&+$uZq9oyiDwY!61>oyTHDK! zHlVit6?%;f?R@*j87$59_8%yC5^elS>43MrowpsH8}N?xjZb&0*1wAGYV2Dy|5Cjd zbUl@(8w+c>a7!g|4pvJdg0PA}uVg|N7$SO< z{=_8T8y8r=W3MmHCx#B#IAK@ugUvb}DB(BKm7Ym_;(Z&s1lp!fYO-g2TpIs!cdLRA zUM%0bXWU~2gVM~FA5QTJQ#Z|MHEPh(-52n6z^d0Lf_9}-joM~fiZ9~6!9)X2f;e9* zO(>e6cp>>7e6{Z(YMg~5GTH#2Ek^ocld$vql<4e*G5p+d7MtASnFppk*&*TuxLsMh zlvQk!7rLjbt-#izq;C=2}2M_#W zHN4M#>*0AWR>k{#uXn#a&&BHao(mqA*2gH;ht^qJH_v){-Wx^OBHq*XlXzLN-o~@i zL%#7So=&vu?`co*BH0$dgTKX9*jgi@*{-FwM3G=SbW00QJHdaL&D(L-dL-km-PO_i zS@Tb(USQ1+9^kKBocb9*weMH9lMj%mvYj};RGZfdUbSXzUYuE63qurK(x5PYwRtsu zk&MA!8qOx{T^zHRWj(0Zla20WTDw7Ma_dH6u3v55BGhsXG!4O85%Duw{>!y9MBiU4 z_Kez%fs}%P_9PwslPMNS?>~k=D%z?4c!A@hzom?rY4oS|aenRPWH!>`p561BN6erc7$Q_CWHB_VNzSq~v=VFWD2@C@9Pr*C2&|tqx7=l@VdQ9Bf;% z<<_#kIbr6{g6&JTvZ9WwN=sLFaG$^@fzOe+JIUWCi*is0L5v`6zfm$SApS?l+n6g)9;z*xaz zXz6tsy%0`(LdJ~%-XVv2VnibOO*m6cntZMkF(I03l~jDH_2g~w`^0Gj%CJ=P6z2l{;qBL$AG}ot9{~8H-YV050GxzV zn0o@njE03mKJ_wWKB2S*Lx#L%1!-yi44F(0BNUnACyWa8dA3eq9z9}ZAVn(aoFUBSCFCT4N!qS<1fT^qA+*ijxTe5y)_R1OntkRs+g!>G7k_M!*;!;m?$Lr_VLLX;ZLVK;e^gK)vZM;SC-OOn zIK%bc-+v&wspkYZy%C^-&T4rd?vl5H=(Uzx06Zi(R&RgskXk$N41~Xy_Hy=Qt?dzy{Zn+P^QT|H2!CP?Za4ezj3_tf?oAEzxKQ2 z5D{^hSVy{tJUJOKzHdEEmfh{GpwyN?7mo^FCM*H22uVVcQj^ge)x9I^RwJTkn4Ply%0%CQ!choH5UN0k?NAGP zhz$F+#qsY4#YR2&+Vm#?c$6wMbpf&4_oZUF(vA;rzwkSy8F_=__%}ompv^G-h(q5 zGeDNKpVMeYtC_No=m=%#U&Y<~_w!q;F_mfZQzzH0J0(Bm?sID0x|2A&-LW4J!bdSi zcnTx%eLgIVAS%K-B+BL%iUQvGqJTF{{&u_7hCc!3cz_PghsGib*oE_;EID!&IiV%L z`e(gz<}6E?wBjUlom{aap^Ul8>tR{HZwUxjuw)h|7r5U!xEHYcqG~5$ zo#BsF{gZJdXi6q&WSi!oMnqxHqxF-9^k(&Qdn8B2 zZTWoG>IY1PN5ZCF*|Y3F&*skJpTD|dEmME}b<+*nq=(%^kKKQ-sahK=bbrIux*2VXJjrE}zQ*GU}^`Z5=%X_10 z;0wv0Vt+9_OyGyr#%O)-Obw?T8n!*o-#TFTTEcyG?!b%^Ma8Xf*Tr)o$y+M zzml2qCQ?={==q2jrbuw+U{Qi)P>9?XM}lEyf9={EX=<2rjGt!(FR)Q8-+i`kT#za9 zeD}KbO~K6@2bqF-+r>+AXP4mIhI56vZ+-DY#|P>yUBoVx40N?;ti1~%5mFxH=Kp|) zPXS{KN*YD}-M)fJ3iPmwVKnF~c};tCu<25lv{aCXjMSX8ocLIBBbDIcK<ZMLz+|m-*ao?u)bGpsGy!Nr1 ztG?g9ZteEntC#JhdjcN2YCo(!#Q`UgP5{;|UtWLm9uwY-$wKWaVn*SVB%v%}9q0w% zloTQbLl8l%s9i*22*omlDVOe<=kRElQ=k#}&z7v)V#07(ySH# zPyD~ymIVZK>Uc^m-?nPN^oYPM<5zC~x=F((?T<7qE^I95EZ|fw0M456!T^h5=Sk+) z;)P9~cwyy2I?r7V^_*J%!>v_#5wx1-YBJ1}%o6;nY4XT?uLr7%`N0ta1DPc=9Pi1g zo8is?qvx>8Z`Nm_Io<(T0>3N<1t0$e??!L|=Mjx1xlp63S9M!NPkk1ySAnQ*tHr0m z#<-pzSFZz<+G9VG|F5wh6pI2Lc}#hq;x5hN1}a_G>?`A67P(7{POt-G_}j^u{rPdZ z$nofV_pm9qR=eLqO&a_z&tG!nPg+y*MKjd_Ji>z&wWtsgOmVEpl5AkcD&a(%+?m2Z zga<8Np|}qbm4Lq}?jr?@Pt}pU(Fs_q6qd)X^Y>Waf9H2#Ssn7&J**#3V0HOppXGGm z=Q`BqYvk5)9aLI5PJi52+$Y#`ygmH^&8|KJ-*JM;se)F6CVyfWM6jY}#?Q(xka@DD zg-4wNMN1EnS4FnJ-=oYX>28l?FEEkYBT7w@=16xzi$#=C?S7JXc|mw=!Mp&!HL_9) zSIKOa?Q@mX)K0=|LMA-j$;VgaB0|`G+2Q3c^bBQAbC*`_hXh!9cJCM8ufy;FbMxlS z2V3}8w#Db>&OF#7%({Nq+=9Bt)Fh)w6Jxv!l4`c^;lIlWO|?> zbVXI=2IyRLe7=aa3X~E`V$GN)zea_+=E-hyt_Ti!u?EU6Vd^1R@HP!}5{74F|{ESN9iX=%AF*HEWkYHKu zfJdNFitxrw2LCPmaPbE0?%BXka$xo#rMMDE)gu%ro)6DwLwTFWAC0N=$FTt;R)yKt zuG*#pzypf^+OXx%CT}Gzs+jmF0ivymfWxW2kFSuweq9YdP@N%wFI;-^D7i*^Vu75v zGayP%f>>fOnkH#S3R<5ky2j{4$>Ko8mL8%E_^ukg4J3x*1lH0W`TQ_0HhGRV@ZGz@ z703n%wOo%PP)meqiA6!m-F%QtAVZ3XB@%nlD|wT{#R^z|KJIh=} z*_5~6#%iE81Lk}fa}J^CwHmQjBLT8eLUanvk%S^GMh1=r8p)vWA#!=AufqpF1+=15 zn%t#hFE1W!zA(8RKetYq^`$>9C}1vGH6(cTX?!7NG>xxPMjhuLuHlzkm;7}2$5vaH%F4~{%0&Jgf1k)AXwb9#qeDoqU37$0Y&j3lIa7mIvTzh7t#ClJH1c39BRiL&WnDUt`=ua{ffp5 z!0!UDyyx2R8`^{EjNysLVPCJS0n#HAI`mOb89?wH0eujA)R zc}1zX4S9dI>&sgYu{U`Gd;qv&%9Z^9~a25e#lI3w_O;dAS?VFjybtqUCfyT0qhZpkBwhN}ZIa4)w z2sjiW8Vo6>Hyft%8B#Tr5pnB+|=bE59Twe|K_2c~98a{E2 zSOnT|jVqvi>4@>57sCD#J_*^`D1+aNg3dToc()R77ZiZn^P2GN@(RxuXgi&xxlJ`7 z6G(J4lae!&GgDKd9nlV0-{I>_N>H;&iegd09^Q|HXgZ4?AsQf}Btov{=R$HcQ7fmM zw)@J^xcK8NVh?M~vKr&J`1t4e)!i-mxfZGHzCMcwSYt-ZY4`P6G$72HQWZ(E^nRwU zW+V8<)%@1}ecTOMnl1ZOesA!T!yh>#zvr%Bv3>aPCkNv^y^GwE^Rb3;ltU-d9u`a~ z6G60S`xS(5D~iSvY1>ZvFtP101zAHw;8PIC;=t=^TQ2sTD$n6$V=hR@1f@DS6ZYRO zEsJaoVw(00G({&@@LT*e+wnPTu%Mb1@nIXX!Yr}h^G+c*i~()hW^^k(%b$|#$@Tem zR_=a}Z?D?Wc-ub01Hg&^G{EW`TLKM1A%B?^h|!SXT3}e&f3J z>rd&~KWv!Um$f?kKD(dKAJWY(*Fl=a-e!w{X(s0IJi)4xL5X0^(%ON0fC>B~+C|J) zU;d#M^Tj{Z^}V1Q#+UG}FSaT9F0oDG;Ohk763be{3fHhi@psnozfgAc)+)k#Wg^mh z>U8QI0n=3tCIcC%wEBpo(+I>3a$C%hpap{Vg6j?n3JMRhCtK6Bm?1LeLsLPA-ct>c zo&Dz0`FQ*CuhzPM!ks^){x?0wT7r7?P}sTsllE7F>p03k?OM_r;o$f#sHGtu-=(^Y zwZ>G54HDK8uoVQN0%uK>qtXTq z;j+?0QDCg%1t;Z=+XC|V$8CZ8B47Aq$!uWee&~wO6+Oc1_MRmvxD?C=#axB`yIU`E zzef04RD>Nc=y6~czc?`3FC;3U(~*Y2j-nKjh_l+UN7}KhRu|8I6dT8{edNAb%BxD{ zYo9!6kKFYMc;dcn44-sDZglN>!7Wa`+N?-{l?LP8&N5L&elU_8RHp;=FvM>Jiz09miRpt0~DSTrB z8^(r@saWjbya}uO=I%=a;^PkSUnAc>T)+RARa1^mSTdqd{r#ssmyg&N)Q;K(Sji`T zv$ih|OacC0h(RR%v&JuyVpTzQQPDfe_>z44$N9 zBx82?Rg$7uIm*9o{v5vqnXVHRon_X~WrZ)Ve{%GA)SVrJnzQrRZc%mC{VPimRc8s0 zQu*U*EMO5)j_~W!yg$hcbQF#jS*eHn0K$rD`VnL##gf@l9D?Q4^gAiZh|dxEICLuq zrHErAQybmCIXeB!mIfK%y5yTsptLGn*{^C>kEobK{MN(#@h{h{{ADvlydU`34n3!S zuyn)Kc>=EQOrd}a@qr~yX!$#U8>R5LQGh|D#?Y=m+(3dZIz?2kSH`0gMt^YN=sq%J z44Amo7PWoR6lfoG22lB~!{kG^ro;x1eU*RrYR&^g9+<^DXdEGLGxp++ZpR*@^(nwP z)9kD`XF-9mv%;AaPM3H10OOpI?cRINKn23>2(E->(|681kz5{&D~PzJJb>FTOq-W9 zo5}9eR~7z)Ipd?&dcGQ-e14Zh$Rz_PFXdkfBnO6(>X)^ zQX|z6&XkIz)uo5BLD~WlAZyAZ=w*dPtiCYk!DqUJTW6I;MCOdnZP@u>>ApET zu6G;}8q&0+q%0&PHWW7?n*SjHAC% zpHFG)dS?teDn10}oho`J_dD`E@vw+uyn<=l$ne?yZ+_cRH(!4GoQ(a93ta1=52hG2sx1a^hgq%Z^7)4aLk< z+@}b$MjRb!ZlLEuhlz-@hRh_*0cFRP_MG6fqd zP7Gp8qOwlyocr1o^RefGr@l13^WY%9)EYl_|LoU(3OK@!2M_Jox?3D{yuE`4m9#}n z7w{Ojh596T$2e#>L}g%!B}7Ms+rvU(^`sygc-^BPn3K`?wU5{-lvPI??B$8pXv(#V zJbog4fToBzK6s_LC=()RqY0@ILuB9~yBPPv`=#qYT@`m<{N8s|epzkSaze|Iby!G4 z{^#+yg7H1a7Pi^dE|hdnAk61Vob-hJ=I zr*Y=nLf!}i+>sRFi31LwGUVk!-X17XQCvx(L_Uf-62$=}%7%)3x8m?a%@`qys1Q?b z6GZ^Y{FD!-9RDL4K#9$emYe;yigjm=d4n(F`NuYv9>+h<=kMq9Qwgk@jh~9U^%0`S zkIU`c*@q__<{z+n_#uC&!G=#7q72``c0c`?-G+OQl#9gGrlWE%j1-gL)&%CkENe^y z@j`=OeuB|qu!RK#^bHVv5xO$71WWWk^wso*F3D+2wc65B5%d{|+J;)7gQ#ezlLQ0m zHsYqo|3J1KC==o^fh)*hT}N5swj`~!TQ~o*_JP+X@Gs=O7m}jbq9i^$CU9^G`?@&5 z!lM2kbMGA(Mb*U(&z+gA*_18GrYD;{)3kiXcP(ux&_s|s)l&(k- z5XC}KK|mB0uz{$61yoc(1$%iElw|V#&Yj&5P#=B1_x(-OZ% z2oV{U5ZYEum+dcRV^A0?ybCB))@9YT6?M?jiRYtk#NM#oi21$ffphUJGyX&6*b61= zGR8d>_k{Iv$CFJoXI|>|LDy+r&UUT)RlM}|=gP~EArZ#9jQ5&NZT4OUi=@2|I~stf z=J@F7&O?R|tq;bi6Gr0Pf^!D8(nypZ)0g4=@@5off+Gs4a=j&Pxq}s=@DVO;BBL(f zM#zjypv7M@EE1a_H{^JeCMw?tu+9m}L5K3L{bERP(BsN4%4lX- zv^F51a*pzY7*%oo)mN`qTo;ebJ->A2naS5Dj~KQHFanG-5HEcnV*XNue(v6J%xH*b zdZRz+6@0@aIUgLK9yl^?BdVQO3g-thC_KIfcg>`P*ch`7`-lGZ<+VYP zunPNxoY^w40Nl$|aA8hR@X^#LI?#(Z^8G`UIDkT8>qjc5{Z~vZdmz2rz;jjKD3^TC z_FW`tb@~_jtslZ>fAiIS4c6&JH@$!yjs>ZkU3EU<2yGd4bMQ#}j5 z>la7Yc}vxKj>J~^lGEpI?#@^iIyaH0L8qz40;&cD#uf=$O5>m#Y0zWS2yzkqlzF-) zS%5Dx(Q30f#%zg+GaI$MRvc&m*1^~&!2Ee~MXOK>QtlyRkpaKb z&_E$e8BS468Dw)!e{V8apgbG{c*Q%t9>kC*FZL*X^&IO}GK|4xYsMxj8TTvi+^4io zlxs|O#Wdg+Hz3mGB0q*YNRe~4-Bp0dnmnJ>~=Asw4`tE4tcFwW`o{R4Q8^* zsy@bW6cvR`mT4yX!I^Q&1pr*k(1AEdOB!%Yz*cZl#5Sq!RD3srt+F~1cIo84$Qg}7 z#az&5ldH9c2gp;t38&~7H$XXkoo)H<8)>AArMgapbh*5o&6AaHSW(Azl?Frm=BK*N zY7=1F{O#S-9&IMu#`hg?SDvMOTwCRgw0%>lPi~r4Yh=u+8QQh;1ijJiGRlVw=eG6t zx!G^*fJtqQhKNA}#)y`>?=@%GJKMkieszz&%E7>#_KdY`+N6nJvbp1|^63xv&du(j zv*)j@5c_X?7x@a$b#)~-4eQahWs{b1Mo~<)^_Vv(&)uymJF5cDm9l{7G30C^{>%w2 ze!4KkJ;-9xNz4y|n=iuw=_?qFzJ`%NRxVxxS+$UQq%vy&QkY^z%*<#kGWJYLiii+| zr1Yfpw3NgIII=k-oG}g}3}GQe__#D~BgTOriyqo-2lGv2kbcNcr^JZ(IZ*W(h9XjB zIGwtMQ|}JG+lIfb*{|2WG;9c7D#3EPH2A?T%Ew+Gu`ek-Y$-=dCOMT+?BjqT zCC^*MS65A6#j2iuaaCkgRQRgrpHj9-1Hz&m;nS5HE!wb$+GKn9yh5B&moa}U*(^c- zh|i-snm9he(Sy@dNekbKAP7*n5@%<|zeXyGDLKI1>A=@H8+;wKrevibTdS;Ac3yBR z?^K;n{;-ra9W+`T&hD#QBkfS?>jsJ4UsYy_+d*#A>dw$#d|E3E1i9LRu|#1lT!@oS z7czwU1I<#QTp$jQh)DBbR4Sk}u7)CHXwu2d9u|Z%mLETGE)6jwG*vK``I$tcu|JpC z!AygMkUK=1fAL1cHw-HXl9Ha1o{*f7oRsK_ zN0t|7G$9Gf7NK-@7-je18Gty1@lUv?hBmN+!6;0Bvoq+3K6M$KU4mryx#Fcjv4bpn~@n(Vvtf&c+Iuh+88Ipur<0AIBi8yl)yIR`A2W@%>(3iD&nDBzTi~ zUGNHndE<}w&wI66<=cJOmSAOsm8}g{sq7C>J6~qf98wZqSJk?s&G}{?OEFwME*V;jrt4 z$ArfansDc1$`#e{2eX9#06dPsVh~XwJs<5#OxNykQGRBk@qO(~hf=sJ=P zqwWJ$cEG3RXca?yno0? zGpB!40cgWF5j^4|o);oj=<6J5Gt_t)Cm&`Ij2eRxj&czGMWpaDVJiA^aJ%3T zA^VbGHb_E-hy>aU&Pe39v8M*7nge4ju>roks0N)&oEU0lhw9LX=ol6QF`oi7Xw@KE zLOD-XVNF_HR!3iB*}#Fbt*k{F6fG#;9j;4`S`sDSrNr(IS577||F5rn5~fX#SQ~S5 zMvQnQI$3M%!G3I&->ze)e(%2g;$umL&ez4}%MP79v^lA#tBGngyrZ)2kj^rG&CC=`Vg2qw7ASzsjr4Tej?yoY}8sh&#ABi;OR7 zmR^*oG|z3@8vNo!=!q^uPZSQDMiN=eB2n4{hYH99ta}j7pzFZS=4v1b;*q2s1zhr~ zgK&Z-(wS+q1)78Ps+LDEQ8OG6=}W4>G-O->esnewU5NYJ39hh8E;BgdP3U~*$nPK3GXw&u>; zkdjEm0F?*dRSe3=4Rxj9K0L`rkkcW|9noO!X=nfukd=d+;(4*#5E~R9pTw&OFdg_u zQn~vamLX7e2`X?7ky?@a9FDt$)cydYn#t$a!XZ?Qqi4{FJ z>HNm{S@VBXUcQ_x7HsU>FA(rK0$%%3e*Qs6ZATGk6eiWt2`E9q=n)06yr}Pml74nx zmQYpDIJ{~Z5}}b}zC85(koUsQ^;1sgeHipn$b}Fvnk|y#my?v76ghHZ!G^*I3+igw zJ-ycSeh7cr0wlw|fiDAizRF;qnb^muGAMKw`UpdW58XDnFKG-zT8Mg6CiB%hm;k9& z6+1hETuD%4Lt@o46Q%5vRCS`@_UV|H+cGvgHoIAqqy!jl;duuCBiJoS*wgR> z6Iv9iOh6_;01pd|T%|-mN!tZCBu}WLMHT#TqDTx1nPw#jBke1ylW zikr;6Zj;@9c4M37W8F(Sm zAv3#m7n5!0ihG{&7w_|lvYofb`o8m|bX3`UKIM|~?EWF`I+iNc6lrQ)vt0S(;NH5s z+6+vsLwfVprOfZk)XiVbm1_5dJ$+=|s>2j_dY3({P0JR!<>V;qs9&IcALi3!;R$u~ znUY`#MD1{{RtDC@y$+9BB&7#b^eY`+*Hs?8wDo|faB_bJQOkxU z9JV`%$YDa23PBf?8>kfmH(W}@qnV3iPC#S?6&}X1Ck+9#Ji=7+oh`Lmw4vts_8qOE zZicZx%r6va6wFR*G^v|;Oa%vl3(OI5L=;wmAJ9SnBr2yiMYLAVw=t&nRJyNHF0j3` znX4b$-?^J<26N4fxCq~_6MK|pY-;;FR(qd#P0{3b6+fwS?mj_tV?qLmg<3}sIkN-d z-~xp*Y}*j{F+WbDf&v41B@l-LkOxyjy9~T292jY%1tADf(@Oa$JiNz%;mU>Kqc((x zE1!f%?FGk?#Nw0gJ6;g|#A6rJ>$Zv&X`ep+#G@~=*h5iuby0_vPhNzN74&Wfb>LOp|zqVYb^hE>dK=6a&NuRR2;V{u983!$Z2-KwKAucnK@Pv}Ghj zs2nKQVib|(Em3XCYW}e;4%);7OH8oY9B+vUFcK0vt(-bIdDW93JIFFb4QPzA1me_y zpms7=S-3q;mLKmF77-cV>G9mWfq^kA&x#%6Z~DjYkUOOZB{17-;ZFpIha>WDSH!-@ z6P3?`Vw#J4*dvmp3}nO7A760hH}=C1#=h5|kcDjuT%;@8b7YJ~E*s+zl>j27fMS9rj}6rdg(R+${gPhOEcv%@6}w|y zE*?*s>PjWi2NG*kaAa^~Xb6dRDJ0efXvxM2ye2quNhc8MInom8ti;kFhKs9`tWJ&R z@=}zNc%8i;H9hL5_rq<6ruA9c-WsNSdb3H?J?&>M_46C6G<&4|BhE+KJi;Q{6wdbZ z>2dh5=FH*4;-x3&Yz#HYgCCvr#3zTPuF5#=)a7Cc;X$(TAB3CvNodGI;6W6+t_zeD%chY9~TRZ8Z2m0E9xP?WG)YTJa3PT#h7oBtqq!B-domo!N z4oF4j2Nk2u;v4K2484_!nY46lBOsT&prb7~id;B}v*2-smA8m}lrOHgN_dSW9$_Ij zTIDJWf4b*rV#0`f?s_>XVWf?%Vxxa%{SPSP;H|k<8DGbIe*F*gRernitMVJC9or$u zEX7{Y3DNEdWTzn33+n}|Gah3(h|r)Aq2z-AZO}8P#u_Iry{^1-(x@y*V^vfNQa@j17;+Vg;`qdm*$>0k4;(gb_PG1s zpE~ii`F*#)cF#qho8+(S8IKsRi3a)B`Lq{)so$y6f%=^uUtv#e9PIy|?(XqwEZ;vw zJaIuy&C>13fcK|xCzaFUz6f5_^5PhdW2h!bQ^7Z|ik7mNyY0IvHkM(msT{w>KVZT9 zW%0|#Jml{;tbFLE0Of-HaVD&P;Qe9NzytHy)@AmNNM0mFuo~?47-^Um3<9 zOEC>0a1Oh3{5p(ZCsj7o@c{NA~(>6Rd7Uu?}?92b)+Kw2=XK&t5p<>@=n9+ zqvy#(kFeZZGeB4_ok-w6Nns}rseWs9%b27S%=z5v^OH5oSxrU%H7DbY9bTWl=)~aQ zkjIqThq^5qWU@`D%3oY+GFREUKhA>Ry2(ZyopgL=VR60i@z8OzFDzewZSl{YX5?3G z>^h^{_=h;2!COZDjngoyNe0ZL{3-q6@*s*u+`dl~%t1x4GZ?R-2kA0ftjkW41CnZA zl}{OK>xG+Xco7sU9c%8#VU-MCwxc`G4qq{Vi+q_#TTRI7ffLURTTYBD7CSYCAeGTH zB|9}62|tmg6~VrZAVs0e#0z<-8}Ws7bl;w!)v6vtzz6`W`=h_lw)s!kHi%VEu~|3$ zvUcs~)z-jgr?dVwtpjXNDF0bk{YXH-^zq|%Spp_q9_oHx|ZQRirgEo!w zH-tPlbMpRCqxMgl^<0R-zjD*y883{xG@}CEn?uWIi4RRGE*Up=U`aLREh5+1*P2kx zHQ-1Z;fN3U(KT#TU<5E-gUMsS!`HLFQoR`P2WIMSd z2)MzlSQr(#yR67Vh2HBV>5%KVUcM^x#eQkcW|8^3)SdfbW&9Rz)eHurH*4@aO zChD?^a41Lp<(YhJPVFBpUzJec>bDy&5(W#1-;*W-r+ozO(@V!P?qU@Likxrk6NdWh zsG`h$!oYY#84M(XD!AvtmIulbd}qJcoJrT^;_Mc`EF1F&AvxuY<9YAFEFoVn>04zj z&S{B~ZOw($0QPGx_aOkPdnj51Nv7m>RE~l#GJJLaf+Rb=Rp3?p7Q1cxd6t@KlxU9xl~UWvZs*Ulb~VaPAn>_s2*Fk{1oeHti7m=WfNbXzU(a^ zCu=yv{3) +Aos{vn4Dhu!vo+HfbZszedb>R4-_zwnKBuRqm8J6i1&myluE0L}3 z$n2e7N<5mPe3qgfU^ynXT^YnrF@OpEWaIqWfi>{t%rY{_v6M#^+DqiOCK98C8Bop9 z1QHO46klq_EI(vHqMQrfY`?&H8V9G1ckX#Hbj|1EL#>NvvfZq?67B4nbozZ~=pLnZ z%Gm8z>!h)xci>;!^v^d>{$>?Z>fSK+bVebv>gF`k7UzN=xJ7__a!RCfFp}?@OXFyqs7QE~&BWty; zW^JU*0A~!e+yP>zAAU$F-}dd+?|(=tfB4%CrHcn<*^d@49+(ZU)CeX|hFBuMSEGEc z)J{@z}VdI+OJEei8H<#cO6p)KiU+$n25P+HPIHjCjO|7 zU&qwaH8eXi+1<4o=O=WHdPVZ@{5sY~*M)#xIBy?cN7pOxy%zkrE03;GCkU1r`hEiE zfAc}p?V#yeO=2A;Al!m|IHWajgJI-v_IK2e)*w345^fDwGg0*51gJ-fhCyB{r(jx^Q1}?0a<=5)~k>g=irFF$8|Z9*0w+ z0KgqHY5!?~Zc#VO@^%>$GUP-huAT9Pa53T-R?@rm!W#=kUvZQhDX3zv`EL(_i(=M*GnE?-0Y? z0pB}%l->`k{|*kTNkY8l=u41OG)IM&h@eKDWOh*elHNj_9N|&XAzu+(nxpj>g~Pm6 zv9wh%!{>YNVKk!F(pGODGzKvU-*l;C;O%?js}}MR=VQ6`dHVh;<(f26OW7gjYH1E{ z!M1%5>WyeM^I+zryo}f2jFk!;9;RebDISb$>`;VJUTx4tc{mOyev}TTA}P^C zs&S&g;n~{=0Xt;KATC0Z3t^manWM}>1;f2@W!wxFiaFfC8GcNo4TV#lX9W zv}(>wG|SFTv`ch8S~)na)u=$0r7cncI&J^q0li z>zF)Z^q#%Db1sh^fv3A=JvDr#B33k{3&A6)UoF9 z(EBbZ*Dj41dp>&<&8pAH>f4ALwF~fUUi=-;5C_m%n!w-d z9B{|8`tR{9n?LJv=QCj#p4ISYH92>_cd@>+c#}U{Al>ndWwY<#-t!6EFV_hBF*S^x z^$@G%Flh+ze2s7tCn6vHLW~~sS|(WK>+%}l@>@UCJlo>>DSmzWBwcqBa^yecO?dwH zr*z#J*KhIbcRr)*@xqt#ThdE-{w{w$UP#09X}CVaua^qFk!ztZuFvx8d)Zm}Ns;Kq zIetAr=qO*5OL6@kr|T;OoBX)E3fJ%R=N-}CNqHWwKe$N!4Hj0*ifqI6hn)UYuqpC6 zDF@f*>3x6B#UF+1juT$qfK-h&k9rWyU{gpeOl?VqR z>x5%X-~MGDy(R9Q=UH#~T^*D^=g;2x&z;YfvN`gXauL4yZv72mz53>QwZEmp3HeJ6 zd_gs5ywBKP&$BJUHTg~X8$3H(e_egA;n_}cw0uIU#ItjMdT*leG1l)FJbMpS?0J6; z?>#C!As^Eu;@SJ&_atwBrNV2V+fe9gKB)f{rzM}^3U!=QS)wLLejLv}L@jF$GjXp6 zX0u?j|4urEXXnx1Y89TV)%UgvU&wFB-(fAjyFzCw;>a{1nk&!|qzSDkl8ih{&32tA zYT~1UC0UF?j0+ifZ@&j;I`V;~#?D(3CD$JCGDol(!kM^S{ar0*)F5}F6%TqWQrmb0 zP+rX_J2MS(Xm}WkO+eYunEkv%_Oyb^W`N4T5lE}GN?=Nf#x|3PQ&shF+93AJmb0bS zpnZ4COkWG#F%%Ug9X z5?^WMC}`2FZQpK*MRe92Kum)cHY9KEDlX3#b9sIsm*+uHQDYqPJY%r_GFHV(>b^~s zTuKG9IBL09ZLT4*}0 zkQXG6rIb`kM_04p!7q9_8P`K16?-F6b{_ zGZ{B@n#m$u;V_P9<$iIHJe7}w=Lf(@1U8iVm&kHl_P2vT4oR$t>eUo|l-XBD_w4Iy zn$)vrUz6`7<$fB3ylQZM_rZg^=Oa0ZItE=U@FLzZO!ti8k^1lCyKp~3NEDE@1W@MM zSx5&E?O~I{ILm=pkP)Dag9?sEVnrcjAGBLdZ`{|B-X>n7-k(hO z5kLI3QYpP9S9s@5^MxV<1~iHv7Unk07S=^Hr;re!*k8|^xDn4jAqO0?mecCc|JhdV zc!oQ;5*68wd3PIU@*UW{>q0Awb}1K+ul#6iVBngGWkap<*#eqzPyVmC*j}T~yT>5U zylWoEyvN$vCk^uk4(-JHkzZXjtbCo^?IEKhwhqE55J?njfNf0H3aGN3-+~XQKZCa0hrGp2pJTkaq z|D46owMp#Qw{4ix^wzEs>wi+FOK&5lljb$`0Hy^SI9M(h2qRDQM4~?ChPClVCefUD z5gNXC29gtQEU{m=w*-DOX?Oz=%CvBV3H%#4=-@-k(U(XdmX`aw^Q9%F-EB+znH+Z^ z&Y682E5imp*{Q;zndb+!kDS{1zNmywDg9?Co1{V8U|nW@EsM1qf#1 z6qx|W5H>Z~CW6Yr^kboDB%q(gVt2%g`@-iuQO4{;H;)eqk}{er*9K*aWsk6ttm}-2 z;K23l+J(w><=rFa*fAhAazTNYp8{UqU$DE8Cj;Lm3(r(MgQR39(~g7=vXBD65o967 zoUZGG2b^JIS`v$bX(l56_y*-O7>>7|+st~iZmTCN&nxSnysG5BiBI5j$ryWQj9o`^ zGu^>zjO0!-Mf|LS;4DfM5<_}e)CYmwi~vB`6f$(lNTPK$?zL;L#Vglz9j^Sb=t`sS z`3T6@4LZf63W<$|0|8v-KsH$svEN7o&qVqz$>a2g*lNbV>)_uPUy6Ob0-p|6d#Mor zxLCLE3i_$rhi}z?1pfC%!?;xxLhKLpB{+rzsSM*5?ijZOUrX{fjf=;a!&I{tl@0*$$6k+aM6=c%i zA&X^=>K$SyspU3VtTPlPp7oK6G0*=OWU;vT`J=4r#0D2xX=3x^#y^dTMOq7Ii79id zE#a8HM;05|_rJ?xz==4eNcWBAO(9q4%<@!5&=SLpGJ+MgIS5m236D_DJw%iR6doLgcAw|w+~Pqk1^j`YX`>k0GBfZMfE));FbrT!1E#()~P zZv3j@_FfS{E0%jYMW&~}>K~zAjk>1yO$=#r48;N>_(Z){9DQpRjR#JlOpZ3Knb5vn z>&|UDXJ@Hb`2poK`A#HA`oa>=es7&$^x|j0~Im_S))Mde@WF zPCXwRa{q_(hc34InBT6_N2QmIiH;ts{QRl1S?Q9K11eKF^NaQ=y_CA~H=5YXr%rs( z7T8xQy2y626c)|){XGAw^7_G@%FkN{6m%QRte>s9G`Dlsh`PZ|at7R~57`vu9ya9?b6!?|Q|`H}d~!*-M=WAaFdwMjd=)tce}s={23dpcf&RWw z4n+o|B(*3xq7e6v11~=am14U^BR?9s5<(v&Ro>>>K^cxylVdaDGOT6+9+|326&~C! z63@U#y0Yz@-M44kb*g`WUFRZ2H?f)A&ywV{An}RHXF5Do{cv1xfVrgojE86TduiD4 z-R*Zz-Iov%VD8&`%8m)eC%a8Ow>B`a&+aMH&#krv_1a_Wkh^HbUEQA?!IirlGYuMOnGhAoYyB$er?XI*QXHueW*TK+Nll32@JjgYazf} zUl53IAVG<{gfIt_cGmu()Iwzy{JUNYk6I?=DbeD8bWi`od*XkTG0J7OR`>L8;|;3_ z#$A=G;w&z&>4X?Jyf^SIHq^^PNd3j0vMeJG*J2LfJOq^P-qdQF^iNVtpbNg zHg%eQF#)ig1P-B)2_U`x%wHnXOJa~mbO8DvDqhsq-+%0;qT4Vabo8Gxo4bO-Fj81@C?*_JDZF{oAXz((~!Eu(&RdV1J1AwVwE&PQgyUJcj#zM(BC%a&(URBY ziMT@(C9TGpvhGjM@Sa|MZ~dR19bmhp-ZJS1A3$!b+x3R@tPg+op!b>R)f=7>tEFtI z9Pe$!vkmHrxqr=2+x;4f<)kC+Fb3c+FE7 zi%#y;_eLE&=&Hmv&en~0mxJSqGK z_O#n=SRTU~@Jp{uWxoiQs2$n|c=`_#KxB%OyrPX2)|IU9|6Ts!^)y(oC+P1BGna>CB$yD1c zUPD$3oo2t7?!B+w-*Dfh-lyl#fzrOgd-^MXdX9GVoZ4ycrE#$U^cBO$^>_1Qzn=~R z@x_p6erPWj^6wtv-#Mg?hwf`@8t%I^{66|Q#QS5ySJG%Pjra5KaZCCNvFkhW;;6a} zG$(vR=04gQ5^8mtBdnh0T7Lny(-W%gw4U8*I|b~aV`ZduVeJ)1<8H7% zn2)9(`ia-Pfqr$GH`sd|7tp`_JHJoLFrDU2x{q;f5Ufz7ufh1V&*((r3lJ2H?@Jq! z&+S*uNu{t)lI!Ggcp?z7`-bK?ZJl{qo5H0lQG9>}O zW8w6AN-Pti$_3eR_zz{X96I^<%@5eOX(}KD~KUh3QJzYrluR)+#JhH7!wpm9`9Rd595`mO)#R2vm)N%0jc`@7j`8 z&P7mN{O4xyawx)DOEPqQ@N+1D62lL1c%DCMvqzSl4ST#n0 z%`4`Hvc`&0_({VT2J*2EC-ybBGB1hEcPnnTAW50)?#<@cvjxiBdS#vpv)!;^zXcoi zzmtFDw~}j3N#Yr76pU?_&=I<+QjAUejFxy}Y+@I1fiXK{(h(s0jIHc0<;$}yjNP*Z z1V5xB>!mz>g!N**pHrSO_#z8uz=0bE>e)t01Pm^;5;vIgO9hB+xb@wpn@p&Hq*dI1&Jgea02aA zNu-gj&_GcU5dY$|B)vn+g!4w?lDzu6e9~3xlORSSDWGXgUiT7{VdQJQN=(Kv?Yfnk z3}eJoKmR;|RTa34#}~K<)?Q#$J=zTz+p~Rf!=9T582StA)jTKBFeD=jOErk89@$Nx zUmk^Ea(F@NhGLTtHSNAP60>%w?X)$2-w<(LpvcIqO&`3YAzV<3U^mf~@lO-#2ANFA z*x_$NmUoOtRka(TYPWjv3DGpP|4t^b*-7>4zk}}iRM>GgJ19Bfi!%~b%V3-1TxRfePl-5P+ zjhRy5Wv(wnIZUIEp~i&l0TS#4HT*k1{5!Dg-~JVi_bX%@>K*3pCg`C~(d%j&K7+w= zJ5s~v5TaoG^Vcv7`Sye~j#t+a^F~m-hv}AgR zg3?7A9iD0q*_XWcb@872cZ<`Rk{m8kD&aoj6u=ihildT)Vf!z4trQLH+L3doEKWVLx?C}0bst?J~2VuG>A z))7P27%o|;DlM8IcRKLST&r6gcKZH~)t%z9;xl{sUJX05qHA?tLPmT>p)Xr|`u&_v zajxD)r`~Uqm*D6*5Ts=v{9GbEel8(*__Ev!KbM=Tp9|)8yARB4__;Ju{aga?^kt!E zqUz`Jr)Q6`IY|4){aot4QB+)u7`?lCqNOrX)yr_l8d{`%&=+4zc<<^&t{PAxMIY%c}of-$p2f zGb~%Gj<0PR|J7G`5nX@DmdMqRNq7wyB%KAn`4^`mRETKpDFS2R=0XrLkTGa0a1=}I zvTuxXE|#Szg-d5l!!Gw+2{*%yGpn%%Wj2X}uxD_ow zX^Vxr&(A1zXO_{3XiO8OH0hLP54fi^4nwB~CmtLGZm~~D zNrOA2_T*+*a-ZS5lR`!%C(4dJc;k(WvrNiODNUSTH;?UCy5qZ-;cG@Zdoy{^crs9e z_ks&N^P>(LxOr72VHV86oB_0ITyfB5gWrg=YoNrI*w-DD8||6p+c{?=Ue06Mj>>o6 z&OR3@E@$Ce9-A}g@hvP|xw7T)IddM{qFhnubOgRuU%=POOj@(Q=)2M6Fbs8W-T}nX z0OGs@(CFeMQJb&4&<7=(KH5;9^mRVV>#OW!aqE=p&;S5I!*bn`e8~N4mWQ4}V`3W}9>P^BE6+KQT0L&f!Z#roF$$X6w6m>Qw%7 z&+l0SBkw6@`fg=@hTOys%9q8F&2>6gL`uV`*SEfxpHhJ=~ zsrdJi{rkn>f&H?21ij4ykfaS_fz`q=}3?WY##-RhwNsBz$`WgYbIrTck zlfY?~fa47_(+LJqXQ=!O;1FosZCbT#k<~OkH6_s%9%_MIM+FQeIwinpVqz)P4aHB& zmOz_G@l!m{HcnEW^f*ZJsG^+><`RDFs6HK1mlu`ukFHTzr>Bpyc>JOqzGv3w`$kMY zxoFm3duXu|V^&v(MB z)Ljf1X>@u`4Pb^;q8wHRf)yASy#ZoXRc+{}Dy)s%_`OmL340di@(fO?3* z@$Hq9Cf#+04b5rVv;}5xK{~7%2-<5BY(jgt+XqAjLQlR?j~qETSA`{T34${eE25u_ z=X_=d}1};qWEFP?}){O?Fx-mK!X)Q<4sKX||+fbN81w z4_KVByDp>ib_;vMyrZ*pm}Mw$iNTcQt?nxQ&K@5>Ug?io#wUP{PgUR1 zA|UwRyabC8?}N8DYISq}p%?Jx5s+Nq0T=6ZM4=#8fNwKDq#+bcfQ#9e0Mh^!z=M>B z8K{U$Tfzkv9ejIsR*=r=af`KsQ-_!*J~4p9Y*EJUZe25!_M=Am-sMx0m@Ug;2`&3| zH2B;zXy|bNrP`>Z*bG_Qs%2le{4J3VH^8$wf~Yc;lbV6O+>C{U2Zw3(rs6jFg@`IE zii-%0NH^+yi`#YWPjrLufZ|(ypuq?cdb9Ce;2NpzHMhTnUwkVxw z&>LmZWI$dFBcuflf*tFL47 zLk}r+$~U`rj~xr(EFAm%yU$<^0S^u7+D))hMSFL%4t#`$*fQkJ=A=yETSO=`YWWt| z34Aw4!`a0*$TtvP-G9HEN#g*#bh?O45jA(R&0R7Umu$*ccQz|6{%~wnfPcWo(RqEF zcG3svn`ZR+^ClOAYsv=D^olfli}V6ShM4rpdU9x-9mtKB|0wv9+8W8f)L!ua0R z=~1t*8oOL?G|VMRHEMl1*mUotd$P6)Q;oum$` zH1j zvETa$YPDIO=g_s$WBAZIqL~n#;z$V#4YK+BQlPiammB3hZs8tA0#gG}>L##{WTVV$Iq>|B2g6rlDM>zFmjTg9FcIURphPdvU=g0p>=Og$?dv*K)V5c7OkOqdU_Lr#SHOY*#TJi zf=V`uEuGOQzY6By54k1K>KEc4f~am^=BsTOK5ZdzMc6;y5C~E8#SVZ84lx^AYNs)x|Z1W{z8GO zaSnu&J;*gQk+-4{$ovu7aKDi-qbjFX~;6F{RHMFmV)_`!nMCN1^)!lr4hbh<+E zsuWy%RT|qVEv-XdlO`STSz#P*uGH$mMU37L#VkU}y;wkL0!e~X>qB^c=iY+kfE^48 zR=ros>qmHgCoBmhfeRk!awWaav);qJP+a_+(;7=2zBp5e*YMB1oUhF`a{+TY}>b?%w(EnRYM zCJ%*2A4!e-ActRc!y0vh-N0SYFbH4d>n6V=Mtu-p$jdj1sZ$TU^UHNsx8to|K|$z7 zOb}nX8LT-o>)hhI&dnrzfG98bLT!>Pp_71!`>04ndy)W+%2IG^hZIQ?0FG~pzDG0< z6Gi~=QaQF?sf^OG>1j^XMzvXiu30RLf_fkxdaKYi@F;4gEy^q7Eto~w+c~d-!gVxM zYY_J$15d-Zp`GnH@+t-)^(e|8W-xZi{dL#~i)GVjv2R{LI1^tw^sG)%^lf`~8*DJ< zyML`H4=`^YEe^`^vn)L`GN?lvAK#=77wzqHO#zv0l(PpnrFAZBmz&$!J~nB`@KMvG z?E8oBJi2ddYParrt=-*1#w2bkA2~-OH`~^4%$5P-DIZIAT9cCS;XdZ<^sIsK&cf>U z5Dw`cl3T%E+5+aK&h8GR!O3d^5QQMzLCS|)ECpZ6h&Dw?0DxFbaVp&NR2Jcr)U|W# zR@s@!iP4dPR$m_>p2Zu;Unq-|t9F`umOV>dG}67gI6d+p3tU6h7TF&4s}?EnNgzTa zuAIeFap;mmZ3CbTkFxbRzj*FT|U9UNEOExag92(#oVa^-J*vwP2=A4{S z+13#i5NT;OZpNv(Gf&P`+V&U=6>dsMn#Gb~PRbeIz5DoFmo?MRni`x0Ysy&Q)*K!q zPH{cSl)(tbDx{r-i##lJi2xN+&#KB>SU?0oi)*csq@G(i2*or~VN@g&;$tI|qmqM= zuvjY#5iCMafNN&wGBo9h1X?wuh>WMGReL<~>RhD@kcl7eF4sL&({@Il-+;9hFJ0;8 zGDbhG{Ab6Ovqj;W@QvR+IP-3sXf3RovLejpTPpia*tIV-^jy5_73INSTb@+j-F5em z4+O2hGVceralUo-#^)ZGoHPI^fvsRve%8Fs`6hTXfqlfbp+p!WIZ)Adg##6Sz=4Vo zh?HBzA=%6tZAdcGN2wM_2kfr$4+%HhhluYgj$nCXLY&huMmELmng2Egc%~hLMx08+R1QB&2LX(Q|iRz4r)=DA) zRxjw06N&%}Yjg&@Wt`b!^Y&uU_jQGJm0!8UUz99)*B@!3`~!W+SbthGLtX)!U96BQ z3XLCvCHun}T z>r>WK8JM+*ZO=s2p=EukF0zOWEP}ihu+xC0g%=76_krC~m8}FoHWhiI$OR5i0&ZZc zqs5?l=BWExso%#U?@_)KuZmyS1=R(!WcC6(qIAGFpOB_W7c>ga=xB=1^MT)u3I=Rz5VWjj-3k% zI(6)Yaqh%8PiPN9n;j!myN!s&L+%`6G`sJO0Lu`8lersD>q*C#cgRc&?h-@hky_Bt zsMmkn422QxK}?7U3yQJFU=xt7Kad4_CI{gRoP{@678M^Q{b*)$P;1UdPbsPJ^|gJm z?5k`;bY*ed>aKAGHGA6kj2Yd!z?CCS>y}zAN<|! zTMZDUQ$(MQ&ki_r|C;UMhjL=`4u#GZ85#Wp-*i1KO?+T+$*!@pD^qitcB)9qX`0zG zbu1a-Md1)&eFLzz3J!v`5jX*V*gwOX_6vq~J9>Cw%|nQL5v>2R8DLHMV8CBE0v%Mw z8`DAN8V{_!)5##65i#;WBobLXux9&*ukW^ILPdqnn0a;C7lEe8v8LRD_!do7P)}c8 z`po2_G}gBE__*e6cDEgrl9AqSP;#?$%x%9k9(f1rVXtzK6$PqX4rlVBN79;Gqvi0% z*`>leIx;kvYS>_qC=jo^4d#J1S!WBhk@yRELk+BsQ#7u8b>vHnXFjR?dhM>1Lcfzy zFMl?AVq(jtExSqMmoKc?TUA*yG9ST`BSS+2`;B8Om=;ww!gGKNR&lZvqx}&(a)#S( z#c7Hha41^<%7xvI;2iAi?kd_lFknh)A@_v51ky=0X}eRp9W{?yA)$Ua_+^9%AX5g8 zBYb`Mt(GDQR-%A(r?(0YM~l(42;lX-bRQuOjgU)6`Wle`MZvAZvwcH+%KQuN4qG0x zZ(($^*v<7fjvhFcSTf#1GpRz!2d{~ll%-fax`!;hNTO%%#J^{Xy z{J7NZ6T)!Kfkphrl*gK`!(wltWbs>2P`(It)6MQ z1zqNUb*z8IhCyNB)|^!7yJju4x`Oo7T#dFs^Lt&@fYO-9Q0(u6)(J_uEs~SkpdWP| zKgK$mgr3hCb;#MyC0{zGkZDQ4N-_qZfz=W7DO*hlZi;2<_3h7!-O!=pGbZQ@H5eno zECW%XR)qS+G8&N~n?k+`3n9-m#zl^lB=1N&$DGzCPjz?iZfU-< z%lN4Qov*gjr6*)|*X4fd_APDERhLT`QPV9qzoeqW>@sBlo0S-wk)W(*Gka#nE2}+l ze*-kdDmdNI*g%xK&Z|ji*fqCr4Ruhrw#FN+u8uitj+t3HbCEgkY8$<~d7Iwy=gLNL z&f2^ID~BpotST)v7r6MmR4wg7UzBgWkVW2Xk^SR^X;2Nq% z2b*Zvx_j`UWt;bu9a`9~r?W-Vyq?Y+se0{#@+T_S%^&*ssKRYc`LB-3Od2z0d|pA!nA`$a3k+n$ob*0vRYO}Y zosr)yUD?i7HRf@^SD?v~33wLG!6cNBcb*x;P25lpJ;tT^=2LX~fvfHUVf-NpK zKxc%_1PjQCvzIm_z>?j@9Y|fSwlqam7OFhLFg*yelH0%@h^txO=D8}1kUn2YX~Z26 zjuXAR3ck;bnn*staZnu+N&w%>st_t&+Xja?+t^#O*7>wjOP*H*(B__RLYy?j0iR1 zRK)pD$l?WrYY%fX)A4RV(_BNw4=k^vLSY~TH>P`VIB0#=Xz9h)5@?ki=dC^yv zbJadOY)+aK5n_zf2e^91RgDg4(m$+7yL82N7}hE{}E*@b~|-=1ibI3n%^N0 zVOK*E!XYfF!@|l}!0p1r5t8g<)I%o(>BqCHk=DW!>FecM*}f??IAL4qTeiySt;_wY z@|;bIt&yfJ8OAm!8&b0}lG(Vrg_}DL1`yEqIcc`6N8cvF;f@5C2J%W9xI524gQEhC za25ocWh0_S5Gkc{6V?7<6F0Xh|!i3JXD&^y0FXvk)2{=J4OvqURR!<6wyA$nHMn${ZE13 z-XHyk3h*vR_H+CP-*4_(1T=(xpaQ$BQ0nP~5>y66tl5A=mdnLKud_7;L;!qFjHZkf zZGGEo#ixF5XB1gra@bS9D*aM--k+2&KDh<^)!$+h=PDP{%QB@FWocNHzFnsU5DXpz z4CZ4DJ~Rfx0?HxGSrwiK!gH9y`!&WK!$IK9atgPx$879grW}b72iuhmjI{>~FqQSu z>{+ZFk@wT6X4UA)+?9^`a_WmC0jt=RPV{uoF7@niT`*|EdrdSpjJyi|ShjW<92?2R`rzVP*T z-+he4#jV0&WhJlc@t7c0oCT17Tq74JYgWKXYJ;SsInk>Gk zbwTks6v7C7b#~)ndQ;~9d9eOw64tP>^{#)LP=d<_lR!&`Zw)p#9UsoExjk!!bmN;YXiP`x6&-nhA_`Z+OV?Q>3 zgU!SWjXi1ahSDg?aepwuBn0$H5)o(turgG!B@vJ}D^O1#;0>I-RO12gG}{T{hiMe6%+b{$)W{@OK-e|}(Y?QxplF5u(mz?o2?pE|Ed+-xv_5EB9Zkpc`zB+Dl{ z4a1$M0f-3*3gyOZcwFrE#ehSFP*)66?(;oFWyDmSkW*b7Ka`+#=yrv%`#N^i={mP+ zU8uhp_{o+h_E`0qYuA>DY)zyz`w>L2=f*Z^o}M~q1io%Sndh8lsdxz2NciX?U?w zb7(IZl9b+-e?Nt#7}O(|{5ZIV8q-t-3eSAG1(sC%s$oR54c}g5`d*XYx?O*rwrhvc zL8Dvs(`wt~w(76_%y-JZ5u2W}_{RFLVR*UO#Wo| zy`$R~>GY<-`Q0YA<@gDB$Ohm~gs?;PpG7K7I8S>MEmuK#C<8JuEkhX~LQ?j6@DqCz zcUxPAELDHm*qwf7J5TcFhUTUCXvRN22_%D_nRV3_jC^6eJCxi11FQ+vcFpvZ8`duD47?|52X zGQLlBEA%ex10MedI8gn8{`=MP10E81M->8&&zzC7(*{_4+hcw%g1Y>vM1hLR4$Am| zC($x@}@e-L)O_=kH))%J*)^QX8H6NfuS zjEaO%@nC`ANJBMWzy}u*>md&Txk3de@>;T@aV$-b8jBPF^mlFD&fA*(f4qGMU{uBS z_no9Y%$YN1&di*dIY%d6>D0!EehCIe zwLMp7FarfH(VB) z?<5+5oZ)5`2B2OHKoNC88-VvgLc{>nj)tvnVA!lg)KPaKT79`e!Gh{ReMc}&=xW4r zh-bpKg=xWah+_AN>vot=H8U5+Cr=skZ0EqA^_`oyL+tNv?QGp*4?e(0)>pgc8S2jI zHgAzR@>h9sK^fvXx6aIJ6<;rxy|Mprddn5l=5Imgybpdj^#`#tv`O1`hl#KU8ZVN` z%qa88&?y*%)xi&n5m}Y?Ywi|y+SyR_v8U7HbMG?13T)}!`%#= z>Dubq@T4dxz#qnYn2KAYc(@!+)GF=UNXEvxP=+_t$RUtQD<*lG8PVE zH}-vKZdl~yWd-0?=Ym!v4Ek>Jb| zW@G8bJ|O|P?`Aor?zZ$unu}W?(_ZV;c8Jl~scoD4K(ah3_o4d>=h>N6JrEK(e^%+E zg)iqfZI++ktZ6=&dJMYc1ZXu#EwpY7rD049wPN?uJQf29g3NLK9+M5(b+l&)H0N7r zy^hC}q}kxz=LS=o)aQrdR0F2oIr=^O9S@^zuRvxhAv5GBF-w}TC(?jUbsGTVy`n%A z!|G1+k;_6IizjDzf~PPY0z+vIz;IOU0RYQqdKw+L!i`Z@dY0x~5%;>FhN~tmTHw3) zhmqB@lqWA?4X8TL;g(4|`uYbf@54Iu@b{ni(y(Fc?(z4ZTEx1J5AdJ$cAvJT218eS zK0Z6oY~EY1Z`UFRUOEfp$!*5ucbp7o6QlC&!}3}VYtwcleoQLLAJgW!=4q)}S*dBw z*}#m%q^3=i60wWq(h=C~o%;6$Z?^6BhcVpEm}Hl_z=(iy@dy;*rCid*cyehX*XXM* zRYSW7h2>f@h*9bjj>Z!)RAXgixGMmKCquO>&aMCyVj&7g%LuUS$wbreCpsw?m9`DF zfz;>0`C*YizFNFwM0$AS!jBrX8KKj6Zqs(C(bz>EU;IEvOYH2St&3KSpZjv!;7v0Y zyf>P?YtL$GZwq0COoCUZAge#>4~cPw^E}*3CZGHmR|_$OFqR-3xD!uz7+khv++euF zuyQ-*x4InjCb(8Md>MvSsQ*27_4`w-ou!L)-qYbBG^_?2O`Y1>NfYP~<%waX zo@Q-=!ylP7@X?O1Kn3JuXxTAF)sNxidXJ4P)-5WW)3AXj#0)qF zg!7>&Yx3>jZsXg0I_QD$09|6@r%RMm{f_Kyw@^JdtKE_prr`J&1xN6+yruqE;JkzH z9o*T8l*#@~%TR915YZwGBTB|cM8&0kXH8Z@qNWbuXCM3F;m2A1$*o^II&@J5nU8_{ zbzr65y#8<2C+5MjS+V@G;m6v(NU^e;TiDD;wn3 zbp4>&{??BXZHMSh)ob+~!{c=Q_QPWfmwr)# z?y2%Ka7I1CRa{{~+;E@y*VT9VXQI5HJ0Je+tIPim{7pr9e|LTj{8!X+{toK~`~g1m zJ3HQk2Ut7u1Ks&G@PF+1QjQe$2f6cW;6I}t19yo2V0V6v^55g$cQ4)-`62H78s!Td zKd>GmKh$SF;g1mb!`%5b@FSnyBl696%2$?%_J`joAJzxzp9r7%f2s%hIguaf&aXlL zJ_lSBi2Nv@`M*1UkV8d&w9kC-hg;aasK1Uozef8`qyB#j`eS_NUx1^Cx7pVyAL}#! zI^-jo6(PT_uYAM;J|^dj{CYm~W%Zb{P~_M5mG9hv@*yHW&S(D1j_>4-B0t_|{#mqt zzsR@v%)h1{lqc{o(4XMWufhN7e5*TO_81>h2Jkl%@{#Dy_vA0`Djwr;B0tGjzVjT~ z7bEIV_L+YL^w~td?T-0v1^yJD`4@q|vB*z#=htXob$*&VzXtt*s9!6e?knG^BEPwy zuYo(i2L4~6U#^S#8~VzZbf7OtedcF4f8)PO@T;%S@tGg*q@bTfUvqbUb^9fz;-!ZC4enM6e^;2odLy>3 z`wFhx-<1VB3>6_AKCLiO{7FD@$>6+!Hzn25_=k;Ce+DRHW!_rDQqK382vR=|6}5Cw!lUY5r+mgWwO_zx_P*x9kvZjX2K|5VOz z+_;0un4jA%>Ym2;7z|C*n-=Te2^hMv*Ze0#{Ks@*@7E1KX388^6lKk5ke>Z`c6v(F zMoC5ES}q-#-_Oq&``q|PsXg#Vbc6qdey=CtzUAFagV?l^l|!_{mqid#3FAz7mHpIZ z5!8+-oAiCWlj+kojhb~Z8XD)0iu{17+hTdAXtiS0?9jl`&k?aP@mWpNJ1ksd*tqy3 z{o^C<8J~-8cOnoKKL8qQ#3Lo*Yuoz}Y0Jyl2O+S*yijfIlMQkV+v*rFICgN@J7#OP z|3yCO8Q#S4<@!mJ*0c8NVMH`#RdohSy);`aV*OOv`Jj!+t_L&vNSLI_`43JwT-khq zSFR6B9g*Z|sRK#F_N!ai@syWRhsO>x?>7sY&iG%y4zkcx3;O9R@E~5A4m({Km-V5z zU`%J*bgk#ErZ;pMUGBS^=?!4Q-0Nj|)3n~-Ti#gPl1KA{4jZ!?W|#Q+j3O#@gpj8<-Md`On&UtMx}&hNW;& zxS`%7#e=7qquySSRbukXY@Sns`*x;;KF>Y$!SAa_CR-kxk>Bl!agS_R)hRcpOXu9? zov6){^E!VL{ThbT-7OS7O57atLz`o0=kKARq$og5!=Apg4KZ z#>+V-#YCIyhu07EM{L3{2Im)I@)H(2oSq6U)qMQKqB=d&F~q-pcI9r>nUg(gT14=u zH7&AwnEbMHvU-|KE&N-|y075jeAZa~IB?#q{__gg6zAl0?cAby5y=35j$yzf3q4J;R98xoGNl5$Jwh|e0p*=c zZD4F#YW;c)k-<|l(=rni>ZR0A!E?2`tZtQx#$=KuES9(k^$+Z9EWh;Wd;9|)xu;F1 zfZ*M8dOzCHFJOFIR*1_t_dnAotGm(IDkG!2(a?Ni<06ATt3gA0_ibu3x=p9afyTgL z9R|#4IV`XJ@IYh0CXMsiu-55mEn1|d;oyi%Va`AJ7jltk>u%WC zv~fc+lnV2gUgo;V!hDZIA=nk!M7NEZPI-i3UK1D^XlbGVytU1_dkK5G4`5t%_ncRrC8ds}KZl1jLGPz|7`;Mo{jWzBwx4m+dXITmdV7xt5eE;CE$oC#=QPv-0 z@vG8ieGSIu**TE2+`z)=9cpZ_huwRF)%H41(kUeIy z8KWULtEZnSH?v7^KmR`O^nHQnnzRS+xeTC zO^D8#;z1COnf`k=A#yS0VH3J#{Ve7)>n8Czr&beYvr`MXcj`3~v$h)}~D?e505znAF<&8oMRG z>e~hxsf9tQvO&TGncOp|J8FA&i8o^O0XG%!lw=CTDId+`&3qcQNjKreWu=+A#_`| z^BU`ilaasmLmK6A@1eYPv7f0|R+}O}W6$8e`C08sT4!|tD$w~Ud`|X}c7d;Vu$8(u zJ~A#eHC^-DPk{eT#kCdmXN-D_jf83qB^^t~L~&QCh>W;H003=}m?V5Y+Mw=)Si3J` zGz#zA-(1JqytSWcpgq4RDB=nA*1-5)EzQMwd0qPSeh61rf#2wq*?m$4+L>U-O)y+) zkmO-dHsaVtdl~7EXz^hdy4-;4+094>EwbKfG$#xVmlweMa(e0o$FwqYh3dEtl<;L$ zhBwROb>Cv$H3n}}S7|mtPQlk|=Z|&g%X>ZY5AaodlI}Rlk8|fU&-|UpAEf&N`Qv@& z59O<5o2Y++&-^iZkT=_-DBDYw&+IUo6{oXTaYF z-1#-?Ukm&xy6=!b(`WuZ84-JR-H|`bonNE=UGjhA5M>VXAM~03yxar$4ak4UonNE= z7kNiMTu(NVhu!%#@Hgch*=dnK+dCgJ|12NE4$4y?^U#s_?S7eu<%@WkSM6xn^I{WA zZr#b>)GO1D5#EarDY0j@>)QrH9J-C&4-en>-hF)2z4F!=-+;eHzR@sN=CQHtGkFTy zGEW-Gr_fkITc%WvmGNv8`#>Io{Q1&wKHQbBh5ry^4e?5IVNbDXV+C-dIVlDWkH?q; z+|g<{zzaCQPf+NX)eGKv!|;yoTfk{!81Pu>;c1J0qEe~B*XWZn=MDW&KJiafEI#lL z1^#^kzcxk*f3^!hsSz)FK!0bS_$SNDeZY?a{5gSN8{^boI=nIHCoAOL$_qc}zwQ%% znF77&1yA&UZy;J-8d zGknsYfc||-(68x4k_U`H$ioczZ6El{oPX%aC%bE0;oCi49`H#&+H1=5hNtobk9x-F zVIZm5&+rPMcm8bXtGg(Ctl4lQp+GvWT|a6N$n$A1)AbJh44rt`wYFOYsY(w?rm$&EzB#-Zjs%hc}}ASiCIZmp5E0W+}4G^>DB*f zFH^X#Y6&pDJ!WpRnjL(z;=d*a_A03`LP%n23W1zd^Y{NqNIb;_ZbBh1fxW8arBLc5 zmB4f8RQR5Z)MTc4Gz-8>BE*v!MK>ZtgSjR(fq^nE%~JQpgwzR&(vjRmnj-Y!N|?b@ za$4TCd?dLj^}r%D>85&cK>>e0EROG(F09Xk~l*;{89<`jBMRqX$TR9VQ5?IDGvOW-rW zLy~IhlA6E%OERZ>YRp`>f^uo2>+wPxnGP4^8w33;?KO4u*Y>~FPX8;htSPiYlRaB4 zjS%W8Mdqp0s#C>!bdd9sArtdhvfr1Ot!Pz%SqrmQjQnopOw3*~+gmx4R;O6I?srxg zo9M1d$$CHa4*{DXVCyQ~D<9FKxH$g+?5iAw9>E`?%wLA>KFUPO&RS)7RhjM1Uk!(G zPbFDzbX*qo;Gz&{@>3dvCPa(jd!3i59yf8QXFJ-l$w!%(zbW&q@+Y69x57F4QM8@2 z`tb5R1;5E2k|cbB#o)XERcm*95N8aF|8DU38=~OkLilyHBFYZ_$=$yGj@5TObo@CM zpj=`(>W3@`C=rvTqjHJw7Ik2ih2KT^{cpXM>nV^UelJ&UDvR~8lHLz1SlIROTVH_R z{&=2am2&Kvcnm=#l+ZV907k`tm|mcxd!1-H|BR~_ZLMQ9hXzCiMrr#P;UmYxP=Ntc z^;pC6Z~61qMJE4YZCVxk`3+YMt&8y0T71gQVcT&3P;T~a+4A0dTej?7`&-D*KIKom zYXA@Z#)+t+c9}1p+Dt^c5(&c&ZDXZ6iBH*tp=jA>6IKWR3zbo+jE$z3S_@P&R zl`yo+DAbiE8F^clqyC=k8Y97nWx)DMSh zc=?9wUlf^3=EOQYS>Oml=G*zdF-q%Gbf>4Grv}gJ-^+q_9%}_&4QoY=8|KLM_<=n* zy8at5t5+|LY2q90k~*oS>?*99dcUdE4(BUsclJ1Z2kQN%p&iV*L``5h&LwEaU2R4d zdDK|1k~*kE85|XINw(P2e$p zfCKNMwDHqS^n{Iu46Yvv5gr6@2{>zJzCwP8!6ZUGTFhK`fW=LH6pznx++#`o5bb1c zS(5*;UvY5?r>ql4|@)dBc51$ zx(`SqODsNhLvY?YpbEOgo@j}$TQ@L(9JR(bv^1<6R~KAvx^qKSp__zuFBHihW<(C9J_^XF=IId^d zU1D5g7S)Y0{Lb+rfy(<`$1x#||4GhEx*NKmc{0mK7gOx1hP(%Q9#bXnA$p!m3*r0g z1Enj@`;(=7d+S7aC<$d;7fmO_xPF2s+&I<7Lo3`v(eV*b6}ZNaxe_uBkZ+vmTBn0ttFxWdoc%^2Wl{sEC#4r8!jYA$=Qz0a+f9QwRXF^=01`o&q%3Ul=W~<>&F`%EaE5lmzyu- z&d&4;yBg+~H7}d2Bcg88cmEIS)~`spHSw->?+Rb5>jjTmcms^>y1UgzAFU1*M<3K` zhW0YKg=2$kU#Z4~9#6gOWDj=cC;10E)j?NPT0e+(?b81O+<_E39gdN)2+&v>$Z)C% z2%6s@5cFD6b5w)S>~Mn|u0R9?b5V^U3Lj>7T{q>n$rUGNG*bE{S1$WbtMP|lMr5B? zVK8&mX{!9csuRniJJhM~lYH}?8I24RlW)!NRc9q+=NEVXg$F_5qM_z6gx>`}ar^lU*h`@Vbf9?7m;Y?Ei8?^-Qwdhi`SuxQKq zoVnTlBsQ6|b1!UmGyq!EYjXZK>eatS_3rJCdT&j#=~sw)n;df2n_v@Nz zGDFUFSZ8Qt->nS|(^|{WPDEV_-Li(geWhtin5@3=I?s;T$sWGS);;a$M}7CL^APwr zRFjuLV8oq;00d^%*obG?P$na4vy&W((~=e;7Encw4IeT%xnmVGR=#6XQXgnovBf4& zIrBO%ZT0He^TTs~Vg9Qfsjm9KzyC^o`gd0`!>t`Q13W9HoPX*{ z5VtU#{5BvqhZN$EF~K_rFkXa3A4A-dT6zW|9WI4iLKV1h%Q06e8D?PGD|h*&7Zh$& z_jG-yXG*Vn91+~4db!a&ATYb1qFf30k1I}atb2ivunua}=Wvm_TN@+Kf{v|%4)`+& z!ZOnjE(|~iT-B4NgRfIM4yG|l>W;H+p^Zai_}WW?=Twqe1GCZXH%)kz+gEY|vtn!| zsgBIY`Nt_^GWs0uroLfQwVMX2E?wQiFzQcJ09;{kK%K=!1DHW9( zC;0Fe9BVaBuujy@=Rn6+K?nE%9xy40dV%;*O!*)KETEyw@x*{}Hy?28OKANZD8efB z&pKYo3CJcs@MDiVGE)T~SdpzlRTOo%#t1&*1;;u!BS`O`hx|2>lF09&B_=!wCOcBV z<}mW3Q=AkTA$w0fadlg8oQRXEq7@X)JyrUH+33w1^^1El3UVBkBbI!v%|*&^nhcgS zUH3N6uKab$*KPLQle-|RVx2Zctc~Vd_?9hu#q=c9%-$`I0geG%-pH8?4It*LH$?w| z?!fl{ALw5El}5MW-@fR++3SBsHwV9W!EYUncQg5#F^9m_JFdk-#~^$IE5`jDS*UC5 zR%P3Z z?W)Vf$+JdOa<*`xLV}Lac1tT?cWizKb)_)bwAx)43+DSA>HLJdE_qqyM) zUga(X>Sod+$1Q!CAr9kS|GJrC5?0~PaVb~>LKIeU+D!p}i|T1OA{A|aQ{(bii}3&_ z^X+wDJ`(qvQp|1Ewfh?QwJHn2cntcvEjn(>-n)fwb@a#Z7TtkCKet7P4ImHnVC`%C zLoZ2*5^gJz>ZiqTJjINZp{SFPQcDY-&C9y@-TFtGD#A{G;aUibe zR;!{~>*B#>FPhD>rj*)BpZ;QSbo7hPm6aQ`0bOIA{8ZVLl~?Egu;Phx^Ia=uCS3u& zOWgEYp|TUOFi5PAbr+uIyOvyN18!K+Hlq&_jWGdI2vpeZ1GW|=%#Q%O~8Gib>9=bl*c!~Cl&r<6Ta zy-K6~(?zMS{wv-4m@6)X4$~r=4HMfYEzfjC1SE zUaMVBLY|A3-@WqAOYQxFbdRIl4KJL?!&wC7-So=4Acgsb>fS}(t&mcph3_n_rX?(} zkI1|2mA7BoqB}@&^7MaVpSn|P#ZHuj?aohnPxpqd5%R7}@zQ%*9)(0kAC)8TeUbN< zSKdd!IZfdFqb5#_tHV;M{u|{iHof}S5vNwf-NlmO@JSXfPkf_dFMse2^-ccA*Ok4X zhMLPXd8w`d?#sZw1j1=3OOTpyNj}~>(v=F9;LbD*(Fteg1Tta_Fb;8w~WLTze1lS0B z7{(5*wS}pMWBCWi+i)Zmp&Y^!*G9MCt(i&7ogEC1=pO^T{&i@DX0#B|-*dZ-{`!7- zlZ>l*fGGh?R~HO4Nwah`poC@W-raBLP&oh~SWNkYMvBS8!5ynT9U_I*kV^#N+(1>8?X{NJiJ>LlZCJfM*{+G)Z|D6OSx+{=|_(cIg) zO1uNpCiiGFl|gS)nJAMY+I_pVe5q1vy{f>o4P9cvUE&`=^JC} z{)M?wq1)L2)chU5yAJ6vBTm$U0t{isFuX$-t-%p=y4A!fbRH~D@R%Z0Sv}<{f4|cD z^?=LPyup5c?elU6;Zy(Etuj89U8o$^BR8*S&%E3osOlBOPCKo;fK?H_xdx{ekj--% zll)B*{O=OC5W@>m;Ig$~XK=r+M=UV8?Kr8?Uj%e{EvMUB$6=HvOjlCu-I= ztls8lSnwxhv%XP(*!+xo?UOR_$TOA}R=lW*R$Am-3LLEAyNQBjc^={FH4^R?ZtZRn z)$Shm3jM+mUt2OXfNaWAlpS(~jR3@vk^K@gOejfX2JGzj-P9e&f37!Q)nyD)n%zdQ z@Fb2^9{N<;ww%?0yu${XMK%>(MU3 z#WS1=h~+81xCHM`0PGe5zmn0BLG?oF8Flb089+RsH@U)t4_nMy~V1RA~ zssePwpiXovQn#3BhOkZ1mKaNfIXLJ}bi>8Eo4w++7Fz>vE>D&n{oS-K5FC%IlyTd` zgKoZqTLr7LBI3$V2zG8Prz?A&+3+7Z;hSf^i$3+Q|FB$Yl-heHHA?Mq zJAfLc_L!-qzVl9bIsId!-hAhs+qd^0H~?Dxq(jbLMm_Fu(n(z$PB(2*y3|<8kaDCv zX{mitdRl@7(Nj{b2x8KxJ|>LD^*B6k#v#s_4i0C77_8qI7tnZ6=?D<05A_e0#c4$# z<2VXMG!ew=G?|QjB%{$ZD1@1erf$ufXJ$5O0#~8%wB9_gd0uXd%$&@e?5rjkO){D_ z)vhmTalqlUCm8+&F^-sPMXRm8J^i#`DSc6l}Q1Ha9 z14; z+aFW00?CzIWAG>2fa^;ApYGQW|E(%{sehY-e*N>?3~+qIa?8}i^8GA#ih8&^MH_f; z3jV%*r3@J?XVa$218l$AK`z*|iO!0udG3}BH{a*kXUEl#jKI`fFA7sgLKv12Rs=eb zZ~_PYiUS8au2bgVQko7Y&iXkLhl?0&Y(~HpPLL@;hF3Cl2b`|C;)^3-F?={TXpn+? zV$m4t4H`FS+^AtndI|!JYK)GKjYhyWjnTngjQ*c8m+kpqFjQUmKj9;n&O6T=F6e&8 z{GLQJ8kkay7c<(STzp(?46XBYuqa~jkc|@z@fnFdK7*An*_MoWpfWx%pG3)f9V`W8k276*l;N{;am0P2DnH;aWMt|Rvfk{ap7=gzZ}-ehLt-?))bH}8z9qSNC4&d! zvv2Q9SNf@gcyWWWvebOJeFc--@OBNRmeIi>lYRk>=LL=W*A3db(wiVuzpPXE(2=A5 zJkz5H0Z-{r!|^@avi2QxZyl;$)a)@}$koN{C}E-fYJ3Ei88=-{e>`jyrPIk=1%wCPp zOrBwbVMQ%Ahrxvw&>A_R#k|)CUvT9O;gfi`u*fhoZ9v`Cuqc@VQCp&9?+Vq{hteJD z)dq9a%O5SMT{|y*j_EfufA#ui^)~VE6)4nPeFr#H!`ll~SxjeF!h|UnE_z81Gr0%^ z!YnvFdqo*0C#&^GRpyN5bL7L7xsEw}4(ao1Jc0Cr9NI}P#sM>8>CxI5GdrBm^&t=1 zuna4-oPj9?K}S$8Dlk-60GEgIbv(?js9|yzo5L=v=87AuAXcd0Ip-O}V90Ks)B&*v27uHt(gXHsU|TQ? zROG->L6HHnVy1Y63Lg<>z|A>-ZbCHf5m6x#vLB|G67dIa%^AbtTw3a0Ip+g3aC>_zSZ?7I*Iu&;B*u5aXWrtQBauByUEyb23)>2^seo#z#EH9cyvfHKs zCsTBS>bl9A;r57CW2QFNR-Hx zZ7oLz7<2NTi}r8hxNl9ADW_HLM1Q|Fa{VQFBmGUyb6ZU`RhH$A@~<<$)dW9N8}{>i z@rNt})(tFuX5f2lz%!+#Yx@saTe@OJ>DmDU)(t3qW&nF{;4`HI*WnkXt{ZTOb+c#p zU(vFcJa$FPo?Y^D`gP0C>D#kqrObM@T+zKv^SHuFVb#% z)oL8p`t4HZ@lQAN@s4Hd*@x(BE*)h3^*ERZyh%#7TSf43osX@nUavRlO;KX&s$rzL zw#1FqaXdvik;3}BakF=>XlEmzInV1};Kxo)yYgYh z6m}7whcS{wng@Ue+-if19(bX$h;!*AoRhJJHa-gLx^Gh)Yt(-5y|*{nQK+1~R#ERN zKCxq`zAW{q3%U-{012Q_Uc$_YFG(JRSlDC+?PfFr*x!gMT{Rj}BgI{y%AiLKr8f4R zZ0BQ>)x^qjwlbCPwOv(yxK8STMjth;t?~}@V2lA|6*!=g^hrpAvkJaDT zJ){19tgP%93tG4Ir$vl)UAkw~<3BBekt*x3+H^bng!l&gE823+kR!!Qh#!Xe0Csd3 z3}Cs?8UYxeO^5>RW*tKOV&hSt-+^|UlB^EqZS$VGvaxL)pOiyaN7UorzI9r6oWhq~U`{So4)mbTDS=+W$28bbE`vt88*7$w?K!Tv)3kKK^@6|U zqEBlL24oe5X*cx8{<_^>xwWIhz<)ih9(#nC_Z`aw^G>-;Ih6xzagK~T9KLZ*=;t98 zCv2%wV|xR!YGaT_&vR!AMaN+X1+Nk10hS{yBX!Wv*uY~Uvqc`yC*JxbQ}n7^DP?QVX9+1F@C7 zwVOKG#%Hasn6Oz4y2sh~zf~5{*!l)_{ERw`Qi?rEs{_=Lvmv@TMr&VcCXUXr@&$fz zg+SoP%8NhX!anVCHD>-95Hslm;4O9Ih4F~tjtRyrbhGeVQR7$^gbTc8iV==mox0do z6%(KPb-KK*72CL(O_mQhny@Kq6zF9!kb~E7ZY1c1HO{TKfOp{?=!L4X;HcBW-%?9? zK}+R{Ll@Uo_T!BNCze%Ame+&c3BbF-jhAS}eHgOjf)BV#0nB6obR8qR=!J?Vw4k@N zRb{_*mkugVfL`F8R5?Uh#wLSc#@b+R?DFb(2%DW%(6#x%^pW6CvY= zC8sgAx<0z!fH>oBJ2&c+P#F$*al)7foUG+n+PukBOke@ z$NfZEK}hh_YGB>MzlAL!(=e(+ByjYB_+MCnK90`F;WgSILfDf-D>%lae}C{i#P@hS z?p)%zsB_6@n*7$}Y|{79-&@bdDRtTJYS8{~ANyAQp2g#9Ke&N2h~o%x_B|??pfw{E zYdA$W5u1020mud2n7l@!F=SyDx9bLhV3?R=;c^Uq?ic(6&=Pxyh-B_=fj=4mQ4$n` zYVh3E5`%>&BLvvwxN}Koqt9B;HM!E{Y~tCdbGGm6vq_EE??gU}SHIWD2Z?6KWd9=L zU|95Oohcv~F2d!}nF32l#JIq0DkZ|nv?7Jkk^oyv<*SS8B=y6Oifl=rVa53f+w=29 zwu0q+ND1nP>Vs;rWAbwBKJQ~Ye*K9($4bS6efr1^wU=5h z?sakJ(~eF4yN!);R#3;Iy>~h*h(z4+kUFlj0$j?b0B0;a3Mb&$a~p70fL~Ti0)EVz zIX0Y)O}lMeGjnvfx-#|FjakNBaSEHPx7_GbU#~7x9Gm9OGOns%b7tNcUBNzyLw4Ma z&T+88xcUG#7_3!r$Jj+9es>Xfi{1Ijl#ltDb36<1DCbVk=a+n@7x5`R(|hslKGO%$ z%V8h*7t76kraw-X@_fK=G|-H;tPH{_LyGj*fcy0erDqIoAaHS?lbjTeS~c&Hc&ojc%1+4GyNI< zv(NPHe2dTY4}8l2JIbbd!dLP3IA8CX&fPpe$zjd%LFaG$g0FO4eg2)#^f-Bg&-8d1 z=V0FWbqV~k&vYx_=`%f%V~gkmPcnG{@R4qVA4Fg2Dg3(6^wc}xN#iGc!l%nHZ273S z0laDYN^j_!&$>o3R$M;tG`>T6nbOQB{0zC5&-7&+?;L95$NPkp@?mK{$uQeF-=_=% z=3~g}Dh)<+JmCY+C;tHEbHJ?D#>?tE)%ArNhV8r~%$K!cuv@7ye@QLu*-e`?roc6{ z!j|uFa{j-c$*}o~`Y+68$$OO^d;b?x8c*4$blK;#e@}o{Yqh>xdncZM<>se+2cF{` zzJmSciQlbH^p!Q!-TFlD;5b0`mJ>Zp5!eR{d8@jIR6}RtaOnzr{cbP@GY^zHYj`@} zp9$6cvYEDh2IaSP|%ZW~}^nCt<&-5Zb+Glz%O|N?486;!r>jVE{xv|gm$N57( z(^vEHKGQey$9$&054V^;>c!mJ)@OP!KjJgJj-2l^J&~R9ncje}^qHQ|ebY0Y3%RPv zH!-)4u06NbgpmxGTgCkDmHxOkXL+SRqs>`f>D&1;K571d`;-mLtz&({ALpxmrk~{7 ze5U`#zxS1nx%Eq*>2b18{JMBDd3ehh=GLElrd#sXpOn$enzqFVof} zHQOuZ)&sTYRxg;3A*;3KRxg-O{sGMAfT=aNdg1xP4O2b0dck~I8wPjpJoifVXl|`n zH`a4*{on7JU?PmV`_4&TF6K$!`zQ97dk%Edi@69o9{q3vZK^c~dcl0!OEg`!g%>pCfp_*9DKK{?G@1I2Q8` zBK=*Y>kX%fEYRPiDjoYoO7EGUcJ^|nO4--vXq4XEA;_`+NNA03OC%{d=u^eyauI3j~J z52m)FPCM(v)aFly!y$m{Pwsv~uuOHkt0R+E_mW+j|3{ggebf8iD&G#q@Lqk*(Fxgk zCR0i4HibbE%N&dQ#rJG!E^N`FQ}3R$b_kl9t8cJV%ntWLXPuc9{j|5|75#*m5Y5Qv zy_7V`rsZRlye&Nj{=n-7;t~+ts|-(;f7S|csfoIuXDT-GS4n4$cnJqvDBNEcNeHur zQxzNuf$kw_)IiqN99AbPte&}EVv-I|e{ox;ig;^+jjqOcG>0`^Ij&CF>>l0j4G0|9 zK0TUs8EP)>5fD&TRMZQf>i*nQ{~A4EaHmfFqdJUDl{eqtvEzOB6&DUg8!pMim8W%A zu@?Q_LH+u@CdV*Y4pjb4Z@Ud=RZ2gL%TC19tMYKZ0`Q>{d}88q23mj**beXs$r9vC zth>f|7DbOVaQ3e~uSN^_^g81vN5?hj&?O*X$~`^$hsEsHT`fx)T^v2IsMFwaW1c+) zM2b9+Z$sU+{d&5XGr;ZFlX>+kt5;|Ir*Q4|5ZXY$XqbtY7gw7Gfj4i~a z_s;j%B4%nW($L>+Ak$}EGM(o`rdz6S$iFbVkm=?X{Yds%KHzG~v}+JRk9?^X;0^y% zt~dNPzX@y}D`N&@xwHq~8p7z!J}aY<0RJ<>Z9`R=)m3H2u_1RagSV4o3^TPdz<)q` zla-NA0IuODod%7n8)JO33g(3LjRqsvg7Lsp&OWE(Qjpd3;XLKKsB5vSor}Hj5Wh|f7|e6j zH$2G;27RLs6fhfIG#~Iqa}AhsytW{Da`V8|fBHZ{vxcW!0~c*@mN-t?#i)$0r)yDNRcRIfP% zOkLkFhJmhii49`_Fj!N4;#>>5!m9eMYJh8F!mxs@F%N4Ig;nnFN`;LGsQp{z%^0gD!bL4p^VMN%K7->ej~W0qJW| zw}+n5U`WppUetX;x~{=^^r!G);(@1}H`HJ}#1as9FMhp3x*=otYc=yQ#I zwp)Yo;Atb!SG5in^p$$ag@AG65%d9uUJO?C=$DZvJFr+V-2J@+OOsmVIKS!XhE21tJ9%oOjE?%uqYvcJ` zddnLR(c@9q7ryEeFeL9UF;Ej#$TxG0Q*J5;~`JAVanxJ8jOcLp)TVdQJ03NoSm!PF6UR! zS5{FMJz1o+$?LW2@`5SnChxj{r>($q(uL=x+IS>TQ3IwN_W9cL7V)R8pjpFHF1=Wr zW}K5tx(7sEupJ6{KIDZb3Vr&3z~h3EhI-+-7rN&=!UM~Rz{AsO<8fZbyq+##E^6&^ z?x@`^0h2H0NDbyw=MfF2TIK~zya%3g$u*Bw_m}gsTA;wcJLu8ylsmV0(cBC$=k;-r zu?jISOdyX{LLT!3tmpbngSA${j+0)yGpzG6@akQ#dgFlrpoea2M(Kw7Rp}?7jH}YC z;7R}7r==5pw09=@Jm_*S%c!gsI1lOH!G7GT!LaY8{hA$Pzu0dQ4DcKxUbtbTF`|8* zc#51Cl?6ltPX|#%Ll;3qq4TmXN#M_R;Wv5VFNAy~3H&Y?N#ma z8R=?AI@{q|=j|Xyflqq1gK|mW$JxH%!94;$IIHX?dE>K1*#qkF+Hxz^hAEd)YRkXq zhuwlt8lG~gxtC00#l(9G8lDnuFTbj_9qDpxRXTKwx>nFe>CFuHgEoRU7(Z3_Qo8db z)`-=3l8wMaoKe55+4BN+vfAAf)^FM&;yOwIPea^4)9^s&YpJ3Pr9Z3JOUZQKL9+Sh zIb)o=m?))j)wxSEcev!Q%JwAsC&sJY;2+}b!lx>KSMYc{yMdc`Vja%Kp_H~?thQB& z)_hhQ5A8$ca9VQ^9?6Cl14gV@X)oe?PDkB(r{L`w!NYRuXN_*XQ<(rSPklOW$ ze%~d^3VRq}db`V3+sQFM%PT&2sqt(N28|(4Cwj9(5|Z9Z>EZR zu{SA&K7t;Rg}oB>t`u~VoQg3m?1P|3+C=HjuhCysc0-~^{h~IH1^hRg8E_a1k3^TI`bnKtV8@<`iEeQ9x&zb ziXdPxuT{Z-UsZNfLDwKJx(c1YE8hsZ%0LHX1?CHq6_HN5Le|nhjd!J^9p5OWTDqX^ zvWC-R4OzSF=OMmve&NPRG>}}n>N??0uT@vMRNzfN;H|*G%DImr>7R4jnG$&`~blzUMWE z<~eV<^!R52#)lr4LNGUJXAT-nxig?PJp|*@a zF$Ng^jR#D*6zes{GC*I|83ggdsp&rtUO?|&RlXLyep>54d=jrkx)@_x`lsjuk&Zt2 zTJ!VO3#QsugF`0)quG39kGeXdt}g^V zz$jqWdEwa!{vc8d+7;u1ndKAaEdhhOJpzx*R_aj~YA}p5%#@OGRwUu&|NAk1->W;m_B$8P^9QdH4J{7X*`~>yHP`YwV^z#Afrs(HL=QTx32L!>d5%73P zCTa7FLI{w~wDhVqiV0_Vl1n*2P-mUiHZv*I|x&k+9Asw%-6J`Hy++H%6T(Yh=?jwa&+?&M;GhJ_U zEb1Y49A*Ad96PfX#||jC#Zo8j!DwY$ChM5pO#MzhwDQR)pnOZkRQ_*sE1rIJMIXBHW^YtAMgON&A6Ta8{fdE>w|B4wlz1z z8CBb;+HJb1?eCCr;jM=I-s=wit>SjcRf7&#a5YP#zw2z z8rk6ePHyE56Czdsp-g`D018Tk*aZj&c;u5w4uDOxvbJKa{#g-3#&{N*S!3dN}Gyc_q3` z$N~CKd8n%Y&~Ma#pz#6eD?U-FpdN+p_)5^aUVc{!g-q}K3Z&8+UVc}j8Sr5c=Vid7 zH*P;bWAHR8TP}X@px<~)CviVb-pVz3Yf)R?oM+H(4Q9ukV5Dr&)lj3$dDcbOfWM*Z zU+g8m67omwD8yq3v`{*vtii4lW0Sq)YKXE%YlzIARBq||7)(N5{iQs6bDa0$g(ut? zAkZxNWufz5HV7_}WQ++s^(E2O9{YL-ut_+Cw9xZ78IO{Hwjm3{Ap(6mt|7L5LEu(ACj75T8SIJ#{z!>F}P5Z&9zH4qhU@ z)TdrAVnObjG7)#dS=ByhOR7`4s8lK;h6219t%I8l9qsKgBB828gaD4mP z=g~V_r~FOa1%^%_)k+;Y0YifLL&Imd z?TwG{5I!mPZ}8CA3sj5s-#Z^6I-GmeV*2JoRoeA#*9GIZD6djn1{&1bAD~10LG5w# z9IFG-J~yvKdm$=olv{f2sa<0RenIhST67D2W3U+Uj#!UD^pA!MBw3bw+L+PiXholV zyp0)b)tyB{2KwbGwY&T-tvC3qD$O_LtdMAP?{|l%xPNtg-#G-2Km#l&lxVtyLSYL)T8YPNJgbihz|XuVZ7i+&rUm|aN8+D zT(`jsPa0luEd)4nUTd#U;~oQU4o!@Yc=)#m930%2*u#8JjZ6lcHaXyS=GC_vvW$kx zQI@41Wvf|$`llEtdgW)Ok-?7ls{wRlk)~a|1(5L=5L4p_ovVZB+x>FWgoT+Yz=Vg+ zC}h9`JG#0Qh0)5aa!wMydBEfsp##;If4<6Cy%ZLasyA%jY*2q@F@`?pu)rf;wbS=g z#u|5lw;v;ZD6RUz8|^j(0A#il`evr#ewVDkCxB3_XP z?>y!9G?pE$NpskCT>DX}Bvru%2u6UO4-waMukj@4`P5C1`&2^E^9<5cUEQ>;{aD_sKviBEwcfpCH0$t^#PTN#2|aMUC896vF9%{i`~{NQt5 zLSzcnX1IUN8iQJa$MudiF0}?azX6?p2s%IaN#}o+Z%~Dvd`nz%t=paX_Ql`OQ@^?& z^^h>=XK4hDc7$nwr$Nqp%YWOC=tY_ms4tZVD0&SGuI^1k{q^e|rv-Sig868Tv4L_SBQqy$_Tr3; zrcLH7W|Kw3#Q1i#4Z2aYD@<}c?Rl5hc#&a4NIDeh9(QSxeo>^SIi9Y*;{v^XkzpMI zc%)a~YZ2-B?)2)rA|m~=JH7fYgGgT?(i@@PsyhTCeV$0S0)N$chDdKi>CU$uPgkE$ zVD)f1rRr=y>74;z zWfP`!+>|Hy`lz?cjzxHS0T1rde&l$XMLHjX>~_#*6fCI4i}+#K3eeko)}JJ(4yK=K zrwt`2Di0B0-An8N_*EVATz17g&oJn%+2;7cW_eCZMXK$L!EgCJu~*oE{g=VGgZ(aOepBwRETnTF<5g5)Fka=bp`a~qxzcUM9nv$(8jQ^y ze3yIeEtcH0-f*wInFKt1EbwT1U1|m&>TZFIp;?1|1~=RW1Nm_Xv+%L5&91sPyBV|U zj<0+oT0P9#u?#mId>mqyp?;!6+i$t61-n2e<)hxZV4zIP;wrB8=3QxzC9ZmU?6J5^ z`>Pz*F-z>P^SZx`RniH4xzCIIcP)lNhDkb_M7goNVkxUMoaGk znfLF07TKT@>ml4FI4T9<<^g<J=z=1B0#gy>;& zXai+Xbnx3FvmszOYywz34uJy>X`s}VNolFJBuiZVx^N_F2G<+1h9>M{gnKmdWrilW zYyuXyJF99x@bGbEL6`9Ctyd;TM18o8&zK!yUVmflnlt0f>ZyQP_YGMT6g+L*lH|qn zwub~gFn;vLFqRShs`^Lxr1xhpeKW#8`uT^;$|sJ0Z+4&IV|w=+|HIS){U;6UHTUoY z^i?=`4+qwgUjFSi^+hMN^#a-&EyYQ#?RoUJ6Sqj_pigw@1?m%J2*k+MKEy51+6N!0 zb;3dd5#tRemS`4j6s=3-IXSKdS*VMeAqK0SD`tzHg1zx4_N&((im$KuMZdWDp#x3T zj~af-lAeE`)t#MU`$2v2rlV>2w)Kyn2w%W<$ot2_4b4$HT1 zgxVqR^Z@B-(ar?ezXV?>P?Q~kr2nu*sb#8rAJ-zL*zaZw&Z-Q21cb;q%XQ+PT zSs`!avWYbk1_I{%3+;Ij?XghgG713`9sti!IQEvg4ju<#e4;T8De)R9t@9N@YKDlMwv&h|Ld`B%=*?A#{Lx$#6CW)ssZYRGlO4$aLdV} zxfsA;w$xGWj5Fe&C94!?ubWU;M2x|<0E0{7!cZo4wT30j&^6|q#6)o1kc>!bLNE}Y zK@X-I^cea%iBe9sO@BBU&lFofV@|$4?$H4CX!!F?S-Sw8} zCtI5o-L{h1e<^-+!-QWj@``7@IdaJREB~{p=_@l&sfUiFU2ns5-#wM4&3|c#Zz>5L z^ghTkFhAFM9@0&Pl&-zCVSb9H6B=O}4A9bHDnX<{Hp_8S>odnq>NC=J&P#r9uY|G< zG@SZ6)MW6Z)UW{js4F#m=#6O z4(tLM?k{8djYGGi#|cDJGT6OQ-@747>?T`ks5!+Z3^xWtQ#puR<0W%WQ<4EZwunl~ zU>025*BP2>GLU0#YEDk3jxaRUl^PO?Gj{&?hYF3n>zSkW-^8P;-J-&S*PKBhOfJ2;`8 z|CfKI#|@Q)?ZN|f?)}SwLMv!rTbuqAe9(vk3|m&8r=%hBe%pJ%EbID^krRE zmz=za*#O&aZh@_prU8TNSr7cBE4s0Rr~UGRe5TT({>DQ1fWCIapGLpq?>n~a_+>g|(Wq|JW$2s3jv6c7zuS+=I(G}K zXdaU$!tWek2uq->=&)hY>&2Q6^eajq1+7USCM@_{pc1=ZBF)PdEGOz=h+~f$Pm2lg z+QMKw#CF=Xrnr*8azbx0*c+4T?pw^p%IYq4&rhZ52fv)W@xb!nkozCJp&NH}_>W(0 zJD63O5hy?9IHnutC}-14hfV_-LotR|K{gVl0iqLj$I)7@b1c3QsI9YWBt?iwzrDNA zK2f@l-1%tzQpc5!HuiC6YJFB>_qT?ctr1ppg3-S|sZZ#CggS$RAmMwo`cI@;D7IBX zvYb-z=8QdSQ+KkIo#x{9JttdbBmRChtYgP+;}Z|E^qcB6y?xvL6IMUhbI^y^m6VE; zlLpwEr!=I$#t+KNP#(SAXlj1Pp6DY*E!C~p{RlfjU8%3uGB~(`*vIb1cXi9cAal|X zVf=!UaIMTE#eSH^gwP1?j1qgGB*jDnXGk5Zcr8X@x@aQC;E;4OR!mU0C8~B?eCrs(NB3JiWLQLJY>giAOzEq!3f9kFN zVVHdTxuI;()iz^ykISKhTPa-~tZRw!VwO7Z4gmFTX^RBCV#|PK9SvP91hp4>F`yht zu#~#i7uA_1Z&*XatRXr~X)r{KkwKPk(GbiTN``v;kB~ug7c4xYp18@sQz^tj;d=()P&buS|$BPw!uB4~=IbM{Mm1{X-ub z9yx7&xOw`t$g=0mVN>OOZAQ(kdzF3g*4WjJTf8#mnNw3HeZ6k#Yq^cqj6HCKT@5O1 zJGxcngHtEXm_B{V1Jn<&Fe>ZO-g*@GlI$mVOgKmM0r)+j3u!B{I>I35a50HkvhdC? z)#LSq+bPg1;>L;z!hLLop=1F6*$1QU9i9^u<8SEHzyHKw^_!^YE-ZTCM30!5_#byS zRzJL#Il3+A{;Yk;AjZbrv*5_Mr*5x%cE9>V1_GTr(CZY+K+;hxENE$aedr*(-^9P( zUC3QD#rXn|<|`VuFBruw_`mF2>-bCE&Q;bH@lpm=Y!pE+Fb9_cHbTt7buwvQuY-5F zRL3a9g59AzD8)-LcAO(X5aA1tX_KbZwQfub1+Zf|^*Q_wqvx<-rNt6{V0>t!KA9ie zI`pZw;s1xZ_YRDrTKjI*zP-9 z_gv`{;TM04Rs8I`>c*}Zqpk1I^2G*AvG~WwN$bu`+HiT|YNmZU>joS4MdTl$i~l-3 zV(HfL!zQi=D8M~K_0L+8?TqjYsvTAY1A~c_Dj||oH(U#`6?_e7D02pnR8KSX@URe5 zlsO7tGsZiN+?{B`QgHI4>J2t#;vA0HxYjCey~0kg{HiBge_J_jUst1X#rg4x@k({i z%>MpCxmm5t0{lBcb1M)J-!+Y1I`Y`qF(=0Qh_BtX73Ad>FxELIpAIF~4swlVK5!>d zctmA(!LcZIEy*NiqqH2F=_0YV?j=a5HPkm6j082|L}*5;h=KzJk+oc_foy|$g}WX9 z96@>>C<2YcCSg>uI}ng03W?76xI`z(v?(T1lw=#4Epk0IHlB_jKUWP!65zefD3kVt zKT*A7H_Mu&Ogecy!nUtk*xYTeyQ2Q+7L(Qm2PAYUtG_skwXav%b;@k>9_gb!H!9bR zRHlSnKlsQyV`9R;GewN)pHq@*VJBHed@5s)Pp#sz9*@^XtfZF5hokNq;wLW4BO#^4 z3VYN((0cG^6mf+O4(sFnfI_ddGSntIloJ+I{S%A%P7CGWS}JeKJ>1F`Q?j~Hiw4vnKE&6SV*ZUvu}eV za>Ap2~|d5iwK|+fr7&lh@$CY9%sqr zIEDhC_s*lAR1lw-6z6o1=xTBild{^>e|4NWfxz1MrV~>peGL>AWR-c9ne?=~lQVY= z9=N2lE17fEs#q(ro4D>MCN1N@7iWR61_ z{ie;FQBl(JPHO&l?o4r1h+4jE*uS;!IR~5Dz{a^NJCM z=N<~cZaK+Vp^?YqynvX_s+mqHj22i2QhUm&<#(JqOx2|SbzHIA#Dq|r1>Ht`b*OP4 z!(ilqWJo3ePM;u-@J)l-M3d*ObFA#k!pT7_#IogD{k9JgIJFY0h0mFXvRTj&yU|vzsReBta z;>1`z^pVv52}$UcKsG)fj&TBgkEhm$)!xU1nE=;|cbJ6Zt50qa=SVVucOwV__8H(F zr?F%Vz-AJi1s#hL(R;uvf)Kal2Rcn!Sam6p?J@OCTd>+DhwfqG6MH`_vPtHZA58Tz z`zH=9i%5_If{Ti0&#_2`4$T9?3`LVVDvN(Mb!o&`xi;InnxyFu( zlSFgznqDWCn#XT*YNZ}4F>e?6LqE*h275}t;l9pEHVhaU(ys+o>dWRBbcABy$){|jL zWc7c1{9?CoUC2S@x8tny@Y0bcA9F>g-I*;GjGX;9OIWRV_PN&lxkh}lbXi4L#FoI0 z5U)6-quLA+kEOkUH* zKgH>cESpsfmrBIh|zFv3P**<%Qzv<}b{D<_U}S+kFii9*q6twc_rr z%pGIrguMIxer0(|YI1X}E;+G5wqCiNUHHiKxlj7amUk~(zLqp=?xtLNhII&&<%UjI z!)ECOxA2kDMNZLLAnhgy1KfHW01YBR7pfI`G@`gO5&9llwQGcOe5Hi9$E-b55x9gZ z#2U0FgV&J{#P)e_7rTR^BAv032~i2oxOmt@!s@9<#|o`jOALcBkK}v$H=d3d8jSF% zes5fUe!}>Dg~r#zms#qE#yJWS4nG+?uVu@z`?|7?;G+IHE!*_>56qKik2yYO%<<88 z2S1^auls1lUe23w&*nZ$KIFT?c67)Y(~eBg4Kg(Z0Z|ZJgH+V$C|_MpL8Bx=c|3j9P!LX zpIyqW?V>$AwL@xCcj+3Arygah{42$)Y3f(Ms-V{i#StjWxQ0)7%&j^1 z73}GKk}fsB1H zjgTdlES0d3!I+y|FVSYTm<&N^QxV7FxEvqbkixS#$00)j#0a$SwnK4+T&UIAbifOf zOI=*PsBA;gj+w0jE#K^)`&v7l6f||(At&0gcvdG!-^40*an{b(=HRq>8|M^#HA6~S z)xBj0tc$~j1J5pHt1L{ zCb=;oH~7sTSi>urd$cgg?T4l#EZB$J19K0#a75y2%z|8gyk`}}^hxX@TE%H}?1STE z+#>fNL@n~|6pNtMU_BAxp*B(h{QZPz7EP!{fi@JpraDrwB3?~~I1=a&yR+xl3D)4s zPq&N85vOz`$+H}_=$+eEJ|1MK7(H~Sg{6icL4nz+W8a!L`1x6Z{%q6dReELD$FoZM zj~&os{u`q($FG$3@?6Z(MK)ZVW0)pz0$}BY^hhKaHe9d$pKmLt#^q9hG0|ac$Zfb} zvIRHc%*0EoRCdYb1RQMaXq??6Er?VWEtp|6%zwM0vcJx!drsaGGYbn^^23%(*FtUI zd_HQtK6uM7k*v9rA(tFfzKwZe#K8I8!oxcxrl++o?zMN+$qkEkC7GLL40`%HSY3PQ z98Dn4Ckg1_93L8DfW+%nVd^jqC^KcGW@Zzt_8dTh15d7G?ES6Wb9)ci41_mS@oG#G%% zEi{MVwGI+Ss+Dt`A{Zdfi>}g_!B#5kxC==_c$Vsmsj&#v4#N#RM?x$^&3F)GG8+}U zLwK)>ARpc*ptfIyo}>Y)IgX#2-*Stx%k7jA?XH%I$IGtJUzf`?hdeK^Eojoyp=yKY z1lz9k7dt}N<2iXGgHyd-y!jO7@aX@09hb1%D||et;=Vk+>yQ>fL4mrwUWJnbmG3Q^ zzpQ-vT*rtY`zME6Dj$}LDXef=ufAQD_3WNK>F~hSw>S1Zsa$KK>=si1*E+zp0&qFG zCj|xbHCh?^kc37pv(T3b^ol$bLx9}6a+J~GCYzp&)Ltj*IU8MY%oz-NSfX(15X3;G zyCJea6j+@!H|Cs8`Ox}7%!R~99sqjNwb=*GbqWuPxqMi|vW_iUbnMUjz+QEGQ{NYr zubM;yW;f&^e@#c|T*q?{>A8Fhg-sj_O&oH}c&If9Wgr6yjv~y+{fWYA3c_;_88Fs? z<0>xrUx!9`AFB>UK_^5fJ^Zom*xD!3FuWHdLAr+4d3Q0i9Y2SuJ}nmfPFOAQanN&G zFJKrI4X4H!H5z_AIedr*idS@P8Z{o6Zt~d?x1#~8-{58EOFn+i4hi)N5(0vkU0b>J z^=^SIQrEagqb@^Pa-+ekHU5|a#6C`GTa*?OmNlrTd_#}XdwaHM7ny-=18$DT zp6{o+4ZiS#GM!&bA;|N-*I)3y>f;g8u*L&HHzI_7WY`1EP*sUYpaTfO@Ki&INC{uFA62B)D51g@j^RRpt134_L98*3d{pW1QGs*7Dr)EQ6gjAL==eyH+%7Hn zeGt=_L$~Di(<>h#U+BuEOOX-VS2_x-UX43*b82uv=-C~Y3Z9?2u2bv1uO8ida7mAM zltx=W&785aUt!Z>_sQ|`B*zo3R7;+5UR)XH#T6$+TrGH`KXrBEv9oyq6}q%El$%nD zxd|H{5M1>a{0#;pdGlc?mB`VpBS5fGxk?#q7J%Ec3MiPD;#@_gWV zA2L}s-oS()*fJj13W7s;+#TcqVuD$jf%!0kDz z%pQ6F0Iv;~l|#lLqmL@J)E&glLfi^mJIGBMrMv)Qump#LY9g+=iNk)(nPzT+!e^MH zPG`bVMuZ8MaLGdG(!iNcd*&7AY|VoO16e_4Pu0; z?m%F*2AY;O7&t9qc_<3g1+fKWUR#Nk!P$kIjtf^LfnthYy_lN=5^G0lC3JO~_23uo zjfD4Z-A9!G@Ap%IzTJorbQNZY9k{m02Y_)*vEFTJBI{rEiWzgdS0Td3@o! zS%0@&IA)u{Fm>{?5K|@34~vy=al)68>>2*YldC?Sl;7@T7slp|8_R{#sxyE`6q-V> z{14ZSUBVpIHsxo9JQj(_2i1RxPm=c&tXubtS1@FXVrd;iCgBQ~MC}xQ0^Z>@u0Lc9 znpuQ~2trI$h%3|uz1-$<8Mx6Ch^#|X5x&{z6o<}7B(TS^Ch6#GL7NWs8l+wGACL0U z8{;Bb%k0k%?Rz^rR1V+jIXGr#3TsgHNB8DUS-phb-G{XZk^%z@`xg?_J(yn|hR={?932R|SuT|Iy(1?#jJ&Fj|$dx1+ zsVWAUePF!p?>!Y(3lrj<_L#_UOFe5n>U%4gnVCXA7`b4GG`oPiqJ~R^7>hu$B#ZS7E=N~Hw7Q+j5);! zCAo)!IsXP>0g11~UG5T8gFU#xrbokV`TqaZ+1C<6D{+&7Fo(XmFC8e`!N_)uL5 z_b4j2|B&+Co`w4L>e+K}S`hMII~A9VF)KenwLQQ8Y<9RNYD$efolnJeS$J4te) z^7+SZB9XvU!#{ z-@OqsdwG;NB6{UBp0!cSXNOe4Ed?FuX7$g~Fwov$VVY`o)B7i`gFw;& zS&@m<7_dW_5^*guC4&KgxKe}xHS6(SyZ^Qu?bN-QJ#<4Nn-+|&#l_E)cZ~wjI5ov- z0ufQ2n}JQNt*rYxyuy;I1?9Vd)FoX*n&?=RgjnLacZ9heI|E?QiH%B$)~=_xqiZu4x6}OYUFjV=bSl^&^ zVyUL1@_XNtuleb|^UdyPKaYYzqLt$iv?lT$dewa z`4V=99Ct^52z8NA0bvH#!GP#Bfc6D#BMhQO?_Bz?6W2a~9J4YwR|y#|j0Ux)TX3J4_= z@RX&09Zpix|M4B}dJn>cBLasJI-_}kBW=eE5#g40aX>_Y#Pra%;>!m-Je^=dTuVGdi3+5+1JHt(yMf1T#z2^eyT;#NV%5&$d0- z`2aTY`t{?cC?>xA^o|SJ>!t*xH!Eo0x&Ub;Kzkfs4O~7vPBX>bh*w7i8-&HOPFN1s z4`7ZQg>~05!EJAA*w7WG!vG)kbRkzj!z9dS}RB^1e z<9&3bx0b?)#IY4w6{R3dWQ75Kn6OLn7!CpRzZh-7=*G39p#@_W7U&d_jCRKQT?%1wrO4kTy^zIqy*vB^T6AlCKNJRJgp>99u_BHVsszMQtD|Ny$ zpmf{|%Rr134vN4Q+#6HpE_|T%lOVJ=N=mPv?v2|>WNO?77n#XV1J$8MnC8a@XQ*!6 z251#@39O5Xs^YEbn@s`DTg1QkUaWaaadseXIme4mGuzR-_ma6>S5Q!e?Qbv6kru}?GqR-*( z`>!!v1GOVzAR4s02Ux3Ct7d@^2I+JHls1SH+@|38#|TIXJ!^;YQSidMvs`eZm|PB% zQ%^KUwJNw^m8ucPxteYR-{N+3tAW*S>aOX>Z=QT%}ngf8gy>Crq_ZeGL+*|hJ(X3|uC%UsAt$y76RP~Ci=Ik@Y**tSa^(phJV_D6VZY|pMSTow(drgm4 z&Dm2eTR#s{Mr*5-=~_Ydb->^07S^fCi@_8u>R5{gqE;7+71HvxrE6l{Ygk)4*fF$} ztQ<6lu~NRqh{*zl>6Z`xzorkE2P9=WsNQj)6Av9$?6wL*Rz`YiqlQTdfX9JFb~*e= zzlHG0v9dzN~OL`q4`ZOXnrJe%EGh z?6+WFW(2MO0<3>`&)0IWe?hm7!{a+7&Ye0#ZbnPqepq}5Q}=d7!!pnrQ)-??i;Eon zmD#PQPsnVyvU2nLN7?ryhV&UeYyjEfU^|g}p}vY%CViF(vEUi? zaGnClmI5%iO5k-DQRs=98>j{z1qcCPutsi6i36IG;tk}6@~wHoRnWkKVO&wG&+dEI$cj4Feseg!5}!Jhdgi>6h9yUxq_hqNRg&?yum?a0x}wm zMt=%|MZ6{c&m0nLK;h!OzuBdL4O>&ky{A;|ZT0k%?J|ScZcQIUpE3_U*;aE{xxkW@ zk61m=^Q;q!*ymKOr%%d7R^M}+U&*Gm9E3x(4!&EH(1WxSSwhe|VqDZ&g+WAwtO(m} zt@oT;i-`HULvZ@g?O3MXhc$yZUnWb3fg(t`r2~PxU{|VBP6wJnawA)%TzqO*)Z)(N$-Z56>KWL%Hzgg{TjV ztfA>yBWqyP3^;MOhrFMDPK?2S9OouO$9_zk1ReXok3SRAZ3y@!V}_UQoPDBnc^gyM zu3H;-eAF}CFa9s1cww4@4v`srU-6Q)vqH)pL}g5Nczaz1tZ{EX59cZH7to++{#&j1sNjYq2_2yG`?d3 z4^RWpZ0!CBG|9w|sW$>`T@QxH{I;GIL%!KE_K7Y=!-{hgY}Pe_8T|wNJ7&2D`v>I9 zC7$8Q;v09nys~rju`#eoNNDbSJuf%EGeXevb0Jgy|I|K_)9XR|glF&k)4l81CngWL zXP9h5WvS$RMSFXakl}eI zE4U6MkO#-;0wr!UB1?3%@wGi6A-{ghHG^6% zoRpI@X<_EXU9+-Wv0rBnYtwVh%EHtk?KoaTZsTz?(ZXbv9U{<;p>8dO&hV%=CaWL3 z+%gO|Ko11CddMvKR>n_uSgVI7aez$DpJAFb1vwDM#T|Z+b zV_EAZ8tFret;dD|%8DJY_wMt?cJVn+-Z-RO68%n6%H(s{w;*^rI`df`g$;(sW0Nh0 zN1Br)VBjnblcR7pZ#cGvvwnU9&#Jjz{Ct8TB$g-p5zrJGB+5Dp#*+{$jNRnIkr>@_ zZQl!rV|~KUEBk(QDi^QIsuFKY#6M@UAmA+?zH?Us@!#jzzk77f{77T_9%+VaqJzOci9l(4)bH4^kgQw(K?sI-O^ zQmAKWh%q=YK<`75XgYtgFxSe7uqUgS;h!8HnBA>G{n@F#6^p^0+YLOnPxTFP9qQI< zH52(dAlO`t)|>!uZ8_BRCJo5tM@QA>OykH;CuhKD1DT6#Wi4%p`Pl`v&{TI0irFho2}EOwgP;P-_Rlaa^j5kc{6g@w3k!syV3wV z6Z*5R;>&Wx$h>G z_QD?V5I70^kx7Nc#}FE9jMW5$!&Yy#;b6mhYE7w);-do|-`|y(KCo%8tBZB6l$huk zOK;cIz9At=Lz*RsOTIEN)0g(8r>|Y!q!|DOG+QyR^SWTfzV>tnhGK!k z7#%QBGJtLc=s+OiT_Ob{a+qgvnQ=OWvD-jcku-wTU+)-_CUFN25GPu$n;hBzl+RN2 zHjp5194P%knw*V9Tdk-KZ#bpH%;^!`Kg$hn)HWq2w9nPGp>rq4_BTXF#5YRU{In}I zbHyG-!=4}1E6M4(Dot2l;UmB13!66J?<&qi&!R)%Qv-7kH3q!gGDj{0GR=|yp!Nds zEp8p4VfS1GbMgs#?n#(K(aJ`A#PO`H1vVY=VXB)T0NNSsCh7(_5ErM5@9Hu(j2YOp z=VuF__OCxCs~*^N<&fpfMO^ z9csdWLfTF8UrCgYD-#Oxw;?G{-m$QYYLoBlf&pR=yXW9<8n_5`ER@lYxskUMA#(~jHd2mjrW>+ zmcN_0k0tN56qOH{1Es#nzVN5+t{T0!ao!uF)?O@UA4_+uG*f5%LBFO=pFWL#@4Pa$ zpmUe}u~*bJgTp{$2CTdWC1`Kk>htUZ)(kY4UGUOe%Co(L*e91z;r6%3pq>XJo^XV4 zqR226tM|onf=p-;%j4stDFKnluK>fSOEKX{Fi!)m}}A%`JoQbfiF31Tt%I*kN+ z!B0SdKL)B|l8-K&WHHzr93T`9iP;e~??T#Deenl6D&37 zKn7$HkX0{BZSDa|z|u8<>%Vye2N&=vetk$aH_*-FbtT&#jBWnUs^cH zPGu}2BQP-3Zg4<#H|cQ@QcP(=9AJfm9lH$;i8h_vB2h%c?nsSe;Ve-3RFmbo%L3ns zOI0p3GY=R$v|RbAeBjs>=4N7v4@*-bS(`7IpGMs2DV3F5*OZr8(UjSq=f#}aQF}3LY)5DI-14QSu~4TQ)^~H@zrjPk8Zlq5H|Qccc(@mtw`5_HOFc}TRNOu z=$#8lj$Hs=hu9B^LKb;F4xCuhW(CILSwV7ga(Z%_(d2MATeghR>kx@&kEyY+gAmac zK!4Sdfj!M@QAfsBV-$*kmg};k7#NkeV(CaE2lKiWW7#ru!Bnet$DOTNE!;l(y!7#_ zHim|Lw%0?^!6sP|)k=a6VvX2SK{YKc5Bu&EPzt zDd!32gl#IluBkMJ?~GG=_%#Q8i)XEY2RiAD7G6ADZ-$r|M)7}CcNqL<5<_4hAK#br zh;C;fh0<=W%McBqrOPP3+fx|UMJpT{g^dIH4 zR;BlN2H?6Z`|)QT0=zE*_v2;q59;)viP!jbwTAObJhKUZ<_O_&{>*>YaHcWpdq<#h z9p}4s)>y6Kj4`y9ShEpA&wq?jYcJDtFf%@edXT9#^r^QXtrzj%7j-lSaPl#${xODV z9N1)0NJ+HQ|GGaBbW?B>h0(C;R4IIMEMnZWW*cqITltDZc^b`b@c(h$Z zs%fMU8G_S}A7A3ss8eINkq`y1KmOF=$E%v+^uG{}K)sh(kBaytQ$kUj_t;?1cWhv| zvYQQ1wr_F8TjI0ZDz}vlVps9tZgK9NE;BPTXLY{gnYG)~jWz2$uvz+`&dOWjLA(}n z#6ZmbpymfC$H+8^RH7oT>dc0ff}dfqRgFeliWmsH7P0CP;qdBP3_$_@ z2wQ^H#YYFLODsY%z1-8AgQlvJoP43S@~CaMCdb8HV;xTJxiwFxyd$ohy8HWB$L<}I zj>fUZgO!gm+PuGLCu@53Q`U6ngwG!vG3Dx+_b-ka?AgFd%ccTk?AQM)UtkPu4bo-m zlOex_FF_V$V5oFmIW2ucHPzMYkpC9b_3EE6zVn zTBjc);MwZCaGl=u9)H)nlvVA$ewSar;DzC3{N}YHwCFei*$rNDwKf4axWszP4Is~6 z5aQKz0GpNaE%ZLzQ){OsMj43vL^#z7Tt}8;r%s)Sp2F%)4s6$@^N_&FEDnEl?mQTO z)th3Oe|Glbo#9z;n!kTZJnzZqHFRh%@%7r@O=i6`Y|4lckXr$#v-&6PJlMD5n6Dau z+*t6{>-4?|;Kf~$Rr>phI+*1|9fUN!UW;-@T5T+eU8*-R9=1C*8mWo;MP23p>6>Ib zOZzXsiIb$h7|2TRb+`DRzR1DU>wU^0F}Mh;@B1=2%dJ>}I3dn~qD&+)8lhVnh!d+K zBN!4-AQ98O0%P4EWSx8_MtPBqC@owN$s!`Q{J>be^vvIzKK{X? ze9cOF_S@hRm%T7`{=nX|PmN>&SCxh^D>Z!dld0dI?lyGRWRT+OSAla`z?C2fF$wOt z5a5Fzaw0T;a8@7;bYB68L_{P=2r^hK8XXKt2!cc?B$-25LdigeQ@#&{6oBJwH$|ZMqiTZ#>39jUTiwhQE z=YaoOKnUxDo$}LTqLG3V6)uVzui6G#Lr;zRr_QJ%{tu_bvJIm9mB`jivlj19F^idR>q~0k^?#a9VVGL62_~ zaB==ZlEa8*>;UYcka3Ykq=T}gg~~)OCe#F}1Wn@tOKe?5mNymDU z*$lax_vA*Z&>a}%_~Z2F@^oeD;eD}D%Gc4R-h(Y}gY-^#_HIp0;$e_=tvf{r1E4Hx(c513T<>rf8B+k7mS141C><8dqMVX6- zSl!CE?(ot|1p0jYuJZnpZYYebOb2fIvfGMedh5Mo$0qb4_=_rziNjb5@bnaV`1C-o zUIWz4D0BBqX1+er+&1a27kva@jgRjTSPT%{FOthoQ;IXkDTTHiOP@fwB0{+zqs*3q zh7Fm}Fs)%~Qxt!!pOg?62JfZGfZ$jy)kO;c2}IHvIXs}traA2Cl=h**% z@#Uq>#`*_NX&C?J_}Y52O38thWh)9sjhxZ2^_by5Z{9R;Vnob>LH$=1cIo`H?v4HX z5irgYbU1~e`-O;ioQrZ>H5#|6lI!ahE} z6V`G8@3#b*k*+g57|+dt?E{JJB-3pjF-RX*FO`3`1Sj8 zS849NUqm=`?!g$R)sLX5)jk*3z0VyX+~(h>ei1QRx=sTzeghv*v_`&6{hPcz^*mWk z@O*xqk0)M>@%Wc)QM``?_r-(?v7~9$QAN1$;zG1J3?$`b6a{ZJ1T(=N9Uf*e2ZtI$ zA;1K&ATM`KZOW;+#T+Q2>;dI5A}Lm~r=>RKwz#;j|L(r$`ueZv-=%pI3am=J*f)b+ z7W?)ax6)dDanY?;$Kv1HuZ;aUucCw1I&cPi!eks&v5mv8_PfA*)qWTH5w`$7=B4(# zpmq2i7cj3^)a$?<^t+(zwC=bLLB+cc=yws0{rDLdYWrPaJ;*@L)E+|Eum4#Fjs2fw zP^pd#3gLGR}J z5%knZ>NSA88cH{-gi#o8q{@gI3M*~O)6DqENhPV&W-&tQCpIKRA_30FTbj&Hkw!>~ zf|s?XY#&T4aA1nlUc6hOWvSxU*#{U)a6R>O%Z~@>A@? ze~ba`pj;_Y>)U|N5c)lo@E&Gbi4+TJvLI*@G1A>~5jtCANa&K3 zOn7+jVtUO*wZtt9V`27KjSq=okP*O}tTs3sNdN=WW;37kb2p7|zHzfL!!JM+l@-Ur zSPRcnQrl+N$IMc8=58z~*qAG}ySoc7r87c(aBxP#sY;3=7#^F zow1k#{ZVTooP}%DU2(;!;a_U7otpU1_k?}<_KzZqmP&d}-4YtwcWTdBvC7R1R`0F7 zpY@K6IHde;J^O4*?_sCbZ+vM`&!z{@tWv5D9#A~1NR}cR2L1$`Nfg?<+dvD@h~Z&4 zvv4P95R8fV8F(U9yAL3wcrK#4fG`>n<8h9t#OTBjE6UF32!DJyq@tJVswUT(Is`Dx z$`Y78_k|!9Q*?fLw{XXeEpOkFm9ON^-Mh~yjPFra{HUD;Wh!4UNpI!rQ=E=}eS29M z`)JOeuT6O8K%<@mdMw$|Y0!)jeVQG5hrO1Yo}NoTw7z1U^>xu)48fQS4j|Rz;d6oJ zPIIZd+TOWDMliu)k8nl0?yb5ym-v5O^}2KUUw2@1x*HQo=l}l8Zm?5%X=!=%16<+w z+!i$dq4cRSr%x#l(kImM_tGc3A`MRPyxCN2;qtsW9U_eIvvT@pPl$?#P9>k`83s~} zN&uu&90yqIsRC&yuwN2Vhmv8wF=1pfLu(jVTQxoiQgp$8%f(Tia45d~Ig9^$5@i^& z`Z;~z2^*&{B-H1x#<%uUqG3(iA-z`;W+IN{CgOi1V7yNezIN+FnWPN|V<1lf^SpJ<++6vr=9rFVUonT9c{I z*zt?Z4&|-JgX(1zYJAdKx0xVqL2c$GS7x)`tT+=JIqr?ersmA=#+W%`+=7L_jT}F2 z?)-6|iXlc*e2lY+8~Y(rtdgvdT~la8w)a@ZWGlW(jzp?%fbdOkHi*hJ`r}JD_en_( zvx{Q`OvfagQydQDa@BT`4i@cA5?!BAS- zd#*9?%=-~q7AJArwQ&LHM?WdcVF}I1 z`QAZJrkV-Y%p3~3Zm464BeJ3L#o3At(XC&ce(vQa(S4UW*|MgYfuWgQbH-X7tfkZ1 zCcE3zut3Qym%P94gz|-QZOouSV_*!AJih<^_sgE?zV*n;1)qGfaK({rMNgN5Z#)j4 z<2KOfIAIMO&EW9r9$IWlS{pE)-G^& ztCfMl*F!CQCC5NWKgEucs5_QIBn9rKUH@8Qv`gZ=DC96Xcw~2$<&Jj^v7Iix? zE2?7!I2aRBt8Yr*0e5XeQ{j)eIZj2MnSlV~}J9w;gp#3V>Y6gMdJ6;z0fR zS%k`iKY^k2uT_j@DT&It1MhYUl|#2FPqEYl<=oK85p0T6SuS<_@|RV2wnlIHd-X4@ zV$g?u=0ZkmTK$7&GuLs`vDiBOFxG|ZDMrwXj{JI&_c|B~>2Z*~p5oUBc&~To*U=+S zT*I$J^MSrIjMN^CPeboKKV5(5L3CZG|4Tu58Lq4P6l|}&modG!o%cHR+QfCWM;@+2 zXXfL7m4CU{vrl_wv-9GeLfVL%uklNZqLQwQ(LdtB!&@ zhi5TS$&G&uoAHlf;SU@3&!^cRHte5IqfnlR8rYz60|P}wgL@g^3`%=&V4+~bLP(5v z3K)iCSX`^1i$Wn~EFm<>WTeowuu!YT7-9-R@S1@ccxX}$(t3l~s6HX^7Fs%y754Y= zC-Nh$k*m)P8~%7+xGiGUoB92R+m!XTc0p{owN+{92(e=LmAwo1el%#%r6(6Yd3E^7 z6^m9bWbZFqxIo1R=z4YiU_7>D75TErFDB@OH^f$auP{#ge(iOadY$f5|3Bax?)#t! zY0dZ8Ti)-T#rNQI$MUE?1bp_%rE&C`zOVV4e;?QNOKPv<`E;G``!uV$@Bj8c?qeL? zr*ZlzwQ%5lwQzi(!cpU^0vsREIPULj!JmiE9F8AquIs1OUMDzkox|a(c|Px-qNV!i zn0JlNRul7rbqq{FTRX)1^mhG7F#^B6i6XAd*9QgJ@7r9bd*1zo?8L9eL!Ee z(ouyz!zi!)kj6_#0Vh2XsaOPwJch#o>g1cJ-p6&i|1SN;{TJ2GTE2h!ky^g4)X&s! z+W$Hp->32PJYO(fdY>F<-RPybDF>3fqkRC%vuq&3h+chH$(?6K`Yk#h(33yzM*jf zZ?s}sHGRf-ZM8fGeYA7eaAJ zGL&R!rP@jz(_%6(PsuV@Hvp!W%Au4ACg%_w@v$bC1Jx-I;Rh9n3pP}riHr4CvPTi% zBrK3DpRVcrsPa*ptmR!^`@1aG9E-ZzuOI$?xL&!WAGhrI@i_E4oHeh@vdkD!sM^Su zghd=+Ek3Ti#9AI$@Wa}9D;WFZ?*K*G>=OLeFj#D0=@+Mye0v%QL@lc znC+g?zFk{)t1N9$aPwyAO;eg^1N_n6F##@fG+hY_^p|8i1o`kVl*5Gyz#kULJRw*J zkb?t|T7`HbIAb70qav4{!8MLB-T{Hk-#@6-z=DE`{R=vFXwy0~qh*V<)W(gH8zv>j zIS~)c{~v6moJa@i1i~q&b5Z3fS2{(rq}y~Unt!=2{mXUn%(Uz&?To9;{fkN`g-&cY zslDk@Q)$n#DPl!M_SCk2$|GwVh6g>qjbvMitNelO)E?T3QH$hrnH~X(Y)ML z-lKd9EACd_dHlq}fnAn&9@urlxGn=bFaO6C_C>ey!ikf+4eYY4%b=pk6T1$AV8^Oo z_Ixa*RBu9ZJSsX+j04UE{#}6W7bZjZrwU0>{1H**kX&rj??14eZ!!Pxc50O0(6H}S zC5xfxJf3qz36UzqN$S2z*jHd4`nSPoP@zmbc4gj`lai09Qv_u~e-^5IKbk@;2_K%3 zx9WnmCiwN59u3rK;Q&zMwK*~a=U52^J_lo@z>4uvD5q}~7C#ps%kewj>4=qet~93; zO$cn-4NH_Qr(RbUZx}L=8Clj|W?`Fq$Xg4#cPkjwV_NG~vx#;c6K$eX8co(kp|6+( z3nc1Qib-UFN=qk$W(o*yq8aKg)CiwZ1Nfs%ivW9e0Dl;$)mvO$3wE+nV5y!=#Ktvv8 zO`%i$uOaVG;DS2FaEMWxB97DHI@4-h+IaTvIyPGQ`#n&N zQLB`-O#7~KhxO49&&%zs_Z^m(S5TFvACjNjMejR2H@7p}qaT`=m#^0k%gfE%ryoM2 z^uu%V^UfXs1nCErcUam% zm9fIC3=|qF#QKQBQf0E(9(~LuNZ;AHhw6cHnMq|OFCtYx=gdIJ7vWd`>PqR9_$Kh>=jz#2f2jCU z^@kT<#OkLN8){OR0Y{`z;tmK8Gn)t+R2L%6o(Q`cRv3b25NUwrREVR5Y}J%+35=oQ zzW2c91JRZZqz|QvtwE8&k?IV1W&itUU`mrIFt6s!h|gj|D+Vm>>zz=KoIA>)MrT>) zzjJzwQx^aAmvW--(*A7BeRI@Rv78yX1Jg=+w-`8e6Xwf0Dyw9~K@0JkpRvrCwJ@Yg zquTYWG~;fZQT=?>o_kGocv2;1&P?lwX6T3t$1X`5MrZI!kq%HDQZ$ zrj;vC-1<}5FmA{KwsYdH(Sy?Z^~xALaVs{SA^uFSk>xm00mO@`yhtm_Div-XWg6Rx}7S$5u&aA)=FD-&)czO(e*Dz@|4-3NaC z?djdm{&eW^gEwy;eEbmMUmGPxuGAgIe!$F+=-*Xr8OO^7?1t1${0!ExwGxfH?=yV= zQWYe8`Obr37W;fyx8QX|@8t*zmn`_rw1>d_UJWvCPB89Fn&+FGc{S>hnq` zHlunE)~I3bp++DP_Y$pAh(qehj?eS1CfCWj^0C#^NRa(zY=pto+*f&=^}(}#tNvBm zDd*xWBHOVEo)zgme`IjtdGfISV+|;{BbgNa@EQfbcHF(YQ~=D5%2F{}pNM+tRNfZJ zZCY+I2(tgWo^ zd-Ud-;V-pcUT;z>)IqrW*?_$i7NNq4rVGX3`|#@p0%c=>$6}r%SOjl@F%q;5CkV(* zv`s80J8NNFVw{5u(cFNpTFe2ZM$O`={T!!j4H%|#Fz4nInDeVXTwHreh5R*HVfz6M zL0T}ptt`cCt9sM>nIM<9-Xb`K>tZYE7fnmZd5!qVj)Pcg-Zq@5I@b4bMcZ2a=J-+M9Wk-jO zp;fdiE}cn#F`uf}o$OjlBc-cD{8C!dK>7Kj4SN07i^_GpcNFF|hR-XR&kIG3F)e;X zYvcz$QNcScgZbXHT*%X6DJF4qv1t1K6Snp3ZDK2SG9^W6FIMqs;rX+L&EjIQH7H^s zJzuRr6oL(9BFF@mttU;Plw6JIOHOHG0AS%i@2EayH3gS)M7c!~o)ZT&iP=%?di2_a z*AvvtKBX&YOM0o&Ir*FBfn7s}7Es9K}g@pwGH zB@2RdbOtCI!`BT~h}y~EHtP%zs(1g%v)D&8M0mF5Dn57u|f|Spt=`oa$_j{l4Bngguo(EVFq?L zd`;kvPq6*sa?SUG3o?5ydkL6#3bwo5f{|o^It@ZHz( z-B5ftpw5}ssAnEM3sI|4ls%_xtaD<5@_`NUsmk8S!%ND1d-Ku^O z-wzd<^O-dSX5th|RBr^UTTD_j52=6^ItX!?@a~5Og{tx$iN^c{ssV_+R9W5DILAlM z3HC3ZlTE*R&27>ML9oq|lkQ~8LnO|1%2lvOzKg(r^t3=db67ZF^lK+tBQ%?kBH=3{_h-?>j(b8aT-c=L^k_d_Jx-%cL)=@A9btG=V8u+y-r z-akJ)o$8?ibGYs)f^=b8AYE2^FOK;GHy-jn3Axtr619FM?#F1nW9_vgd{60p-{5_^ z`__}gKNeF23&t@1K0$pS&g6oB+)&@gxkwF}ktl4I-Wd5q-03)mcOJRsedi}iYw>3F z$$Pwu_ArFADgim>_udLxL@%|eT&(VE`JIRHE*nS=HO;;p%X-;gZRLr}YJc{uvXE6^ zZU0tM#DjcoyWGQ_5WaY0Y2O5~Cw_@S8U7OJy|~2|{PWI3Ru|L`>nk1%_Y7(MYMk=b zGi>d*w7x<*YATc=U&BWjK<_*XD=F8eY06QMx+IjgCu9L5Lg@ndTU3F4BMNaPTKb92QlP-1mO}Y4v@>PQ7@SOtrmEZ74 zd>v<4YR{ippFb1F38#YA%X=!zXcWwe51e!fDu799|C{HSi$%RdkNj1B4I|;1gGy2Dpo>Mh2A96n z7_pdGdRVw9ek+{9eqotM69kwMB*>INP^u=15(GGq-n*>wA-C1&V3d)IM-?$G83)uD z6qo{1Bvc5m2{RPG(q^>G?ic9aq|=ZFpO{7tvP68hee)Amd2xEXp}jf}P^yN9zfgJT z<^796h7blSx7GXvp36N%kh>^4KmzBL;NONyfjX_^=N7n?mIp%06eVDf4zWV*)M+(B zC=103@m4SCT9j)-Y>aA@MI0N!rlT-l6;yH1-)Ehg;!^(+rP$!oK z%EPGE%|8>3aawx&TtFf*JS^mtQP(WwB5I zy1^e_ABflp06_!@7prPQ(6O&JQjhrmG}98Q4s=-iUSC^e$nINfuY77!uCkmygXb8d zg1ZlNOWoo;7ed+PcqKmi$Di2lsh5@=Ty}BF+4FsRE*$#I&?O?9|I_-PPC&Lrc8T<| z{DKe$Z#pcAK|sY|vK$iIAls7&`U`V{_uP21aC&MGs~P8v=Y17bt0}-$g+LtzQ>eBw z23W;w71@W&XP@e4Hf{Z8cG>pSr`il@H?>e7JazC;&sr%xrs{2R=KAJs$Gzt42>C$jBkHF3z;I2Ww&a+EszJU;*z0j_ z5F8n92v;rm_@-p=MMsH31 z^BHT&a)%5YaIJe&%aG?1gWiRX2vqEj&jb7H-DsViI@J+ZkuWFt(G|_&nP$oM z#Pk^>&3a`+X0skGS~;d{Ix7YbNY0RV?HFyGv1@%r>y#E5y_{}VSDh9FZY?BC)BqDXR4Bqxi+*sPDNpo%thb-Gg)1>Z zqf1LnOwwNQd?F?+bJlO*a3muZ54iR>*2j(Y3BdaNcY3JR92g!He!m_{cwe&~@Y_)k zL2XQd=aIaiCIRx4ycpT&|tRuWJqR=1OrYLj` zhs;V{vx~`w1BQ)~WOS1R_pZgq48~ZKojSCrxCyZUW(>D57cNXyPbw8wcj54XoQwx{AqN5BsH$TB z5B3}G#s+(n-2a!MyzO0Rh}9evz}t8twc;VjNU@ooE8Gt>M;|FEq17C!5Ow#mEpObVR5b9#vrje|>?2WIq3aP}Ur;-a7Yc=ZI`8LWMT z@RmBWILs{27h1a+;q5R;pkfv(Hr=~`Tq)WQ(pX}-kV+a0ov-1@#UQ~0zhuNGB9#=P z2PhFe(2kK@6#w^uv`92YLhVHgrnvV|)LQXA6z(ZJlOpwu1_oMfh%iPVafuq92BQ^W z&9Nm0Nc7o8`-_!Iw|d*~V8uLd4DaI0^qYovYmmHa?h?`7*}ru{tg&5MHq3sJ^5bm# zH2v(&X)LnpdPb~k4r_A0RdG9gYtnlKR`sWRxVkac%iz`DI6gvFq}7NdX;6@%JAxC! zwh9a+Ayw=TEEIvFTw0W&KtAlYDlH=2%IGlhqQmM*=aQMXOc%_+CdJaYU7sGkEGfHE z^ihpkJF*^|t3#Xlb`$0(Z?YB{=?#=h$pSdr1I`bDukcH73R4d`+~mFj14Jz`3ZfoH zf5Mm!e=)%8j5A_E8UK4EobxxE%H;?EPPPdI{6)V~JT7~Wrp*cr_R`FvVsqM#bVFBH zYOpA!?MMqQ?C8vTtoI`Arr5ap$w`ezOjDj`IRm1?%r^c|TD18iWMC{{GyjkQdRV*jG zEDU$YV2ozL|1bnSUhyVgsmSPv{eP%?5BREz^lyCT)LYVTdO~_534wGV6%qoW1QL2D zp-7Vs0!oo;0qlYWP@149iWSQ)mbIa{wzcdo_7&{tS|GXS{J+nfdy^ab?)&?_@8=Jn z$=q|!oHH}ev}d039btzhTG2XTqFBd<#5#WhqJf^S#!SDi@qwYK-S)+2)w>$P?+w>J zU1VUEz9QgRt}I%I9>m>cpwBSv*ncBmZ`Fsm@13+Sk%!*2&-j;eP|7wQDJ|s#-R}|o zTTbHpjrhKk6$<)iI&|O>5?#QC5|cihVrUMCtrOdE2);u?Lc9_N0?CnG$uKl>$%a(6 z;Gv^SAMCyKp?BwK$L_w{_|f=k&mO=V1&h3fxj%LvGuNT5J-QvJ$}Z5A<2HQ{B`rp zlwe}McpLW!Qd``I@z{{L(Xmte4<6?9zhzZ#&2La&=T^VlFTcESK+}@T!=1*RCB+^4 zcc@6b(s;HeuT)bL<2&{aP@Z^M)-!TDcT;xsEY9rPj=wA}xMdkQx7dUcsTEx9k`N6x zGcz`Ro*#AsyoB1TKicaXv{wR9s=BlNqP+sBy}EH7x-A_+J{W z&*baUeJE~h88kgAcIp7)*>7E4qxuc1_1osR`SMwX117H`wr}6`vL0aj(#p!<*5pim zrcZvUCMP6x>=i62J9>0IgUnqEcP#c>x^3m~9)49&?SdifIc#lSVgymULp;WX)KZRd z`~>LSfu*xGVkBc++Gy6M{Y@ruULYyP0v2B3i$`{BGJN82G>L5_0kkz@im`E!HP@S% zagdkO06P06NxURAGRY>vSjjIL0Psohvcfhn-eMo2U`|deJkJKlA{JK7Vx#2k`;9~Y z)MFcHhvR<>QLDa>-!|-UCN2nx*<1t4XjLhtf$Drd-Ti)8(pg)a`wR0D!LY?aJP-Nfo{NB?C(>!LCb1cf)0iFnzVpJ58zh0auCm}cy;wuisA%nJamp3b= zlTUd`T6k8W(_zzkR>?3sY|u`CGw#TKrn*?2Esy+wH4Yt;@W|_#1qV=c=_*Xzr_3Yg$eE9|5K;MRiID}j{ z`VX1-yo4@r?p!c8N0D17TtYj>b&QJiI2FSwlupVLYnwOx9Zm~AHo>&_ z1NS91A?~M&7j+mB)+2Lys2W$BJ^iv!DRk@f{GOp98%Kmak)E0#oDx>ut=1tsv*dqd zWlfAtgrRk8Yy!V$v2)qh+9nB7LizncKa$-KFQ2cPR{V&c)gF83`Mdz3XN! zpSh;7DI>mTw|T`?4#$9*C*vUr;BE=L*Eszs^Yi+8*}$2j3jijF?7p$%K&PBQ8GbDhC~lZi)&P-%I#@3f_J!Nr@lAO`>F zl}X!6o||9OecQyB)XDr__kKRXxQCB6c1uI>iRRBx?s)A>>~AMn{RpfOWD4N_glqvW z#9rA#SgYQeeuzV*kv9nzAb?PW+7siJB*x;I!UvuySZLj=c{U|2FGH{}96O^{!Gg9G zf(7GYUf+~wtiTS4x4cgLH|Stz9!Zb}x)L4E!+itl0|%wmcmY1eTg;` zsmLAmnI|mcp-~gFI|R(YG9f^GxrvTWqdA?VAZcxh0nA8ZRay(ql{yWn)2-CXN__hw z$w}>SsUN@O?+TYlds0ZIIR847R-}cr&Y}+q_X#?v3xeDxp;6)AcwA-PlBnP!Nc{@CF-Ke-{V&K|w z;T=Pxg5p#1HEe?$$4}AaE47p)Gy=wbT7p+!x}Xb2e8!fpqvJLx09G=bL_urHXt z1h>l@(OhI0kK>KwJK$`Vpg=zdb8#FGUb>@OK_`bjaa@R&nVnwa(05E~DjX7(vu?(G zSLpZB-{vlH-y6?y4q-(;@7|p^r4|$xV>fybQ ze0thVi(TY@?Zin<0rRw^ZUx}lj?$6|SfV$%V3$W$VTCyIs>}b|v|HK!ChB_Rfk)Z$^bp$v9 zVz5kG4FeYi0Dl+fyWpt+o4!=ItnzelJZgGzY6MSDjezG~u}g0*HvSyKM@A|ocPSjz8}U+H zmKyWoO*>I+tncYN+>B89V;s{F6s&2S&Z59(%FZ%$=xj9qM~f z)Ysz$gq5O}^ntW%vh0(gP(=XiBzC^3To1cs%hY8#MTbACo)8Y zhyQwC#1mbrlQNnbI*)bA*V}^juNyZ%E3T`$ZC!k5WLB4=ptPn1xltj}ME5J8Lwip9 zf+h1zt4|PLSb&}my5nqKRa141u!}wIfFePerZb$HquFfm$_2>&4m#>_=F7~X*))gErvyUmHJsr@G!-kwWq?2M7K09>1|QM0?HhItM`+`O^RvDI z>=!$|3f=X*enMX%HIeJ4z^p4Y^33|Tt#I>ofV zaL-MdnQ-^q@rwg*RgyA`yZPM`beo)7kXfkT7PNWl`~}MNO0qgv6qjD!tK5m@3M`~&=_ zJMB${5uL7H>>sNfYpCpg&4`BksUYx0`M;FU3&^K4>f`U-V^VFPQxmp19$6terLcn_ zRVw`4;9E$Dexjigii;9ymkw8)#n9!Yre&pK@o}@BCkQPLR&X;WANlO9kJ<(VbG{)KWjD-Z_Fj0%tI>3?6 zLF&|GIsXiD^UHTs{nkqJ0A7wVf)?`af)>GSQoAyqgC@{m3${8zkP8MQz>h&0NyJ1J z25t5uLTisA2DFinU@FfhAC>Yf67q+3_Cz@?I#Mw`w0zJ*%gfrz2@BD)X^BY!MImA) zdWnf9gdM&F_%I;rx2I-kAe5AWA%P&NhoZJ~QD$o zQQoIf-mUue;A~UaFe-0lKjKI*0>~gxazJaQz|a$3GMbIh_3U;rN!tM!joGjs&|5ef z7>5JLgPn~ege#n<0uOo?#>4!)WrGbKEh!dLh%K?u5n_|*J3B}_Duy6R={=Tz@wkfwuLHZRdyL9Q?Y4O#@AfGwJw=T)&sf$i^(V5MzLxW`3 zH2X-L)UKf}nq8}pKwT0O;$mZ>!jmJC|C74N?WTqERHfZyF~dLL%&K^%4s?h{<&=`9 z+wqHR^~yx6ld~!ZmnXz$`gAA19g){hC`VnVpsx69=;gI`r{_Xz$jQk~ox3y#pd|CIG&T$? zEgj|?XpQ3Il<%aO@c(I(852WAHoG2oFZkd2kX;&iu$BiX-|=FksKvYc#k*;uJ!9yD zX9~128wAVn{}l~KATYH-f)Jpqz03G26}!Ce7s@D0iz%C*3uCJYOY#FQkM z0Np^uStFsTVkFo515U*i>=)r50Yx)3l3q_LvS2%BzX-R;B>wVcJ{QU#APRK_B94fu z8k+KxGzmU&POqOGGW8;VfYCzTP!Ajvre09RPaG&fh;?ckWrW#;m?Z-wDWhpqRp0^VkUq7u zoDT=idq6opc;oQO!GkM@Z-kanV&5wF%Ng2(Vy3vbEh8bXTl0j4y6)2xJa)%~f9mU1 z$3N*mugK{)?wbDn=N9|D{mCQWKmgfA~txEvs_|Rov0|>i@>~jAil(=2Cw_ukw_SbP28HgU6D$d@i8b z!XL2M6>-I?b?L<&@zQ$ZU(*Kln0@Oa5UZatj{nHAA#w0s$ z(Um4L$5UX@lSoOx@UA>>8q4_3#h_?PNu&dNX~4R$SPP*bR&8A`5)$ryt`%K6X=+mL znA-Vz=(th-fy?zZ!%_o_8IN_ns0UwHs+h1u_AXp{lKYeqK)*_scNt9tJ}{|%vt7h zK+ikcQg-SF(D11Hj#IZ-zS*a4KsxfxK6Q)r0&nSK=tdwgsoMKy3adrwf4~>i?G(PC zJq-QRgT^e9cPN|8)mjO3;=AWgw^f|ieEu`sD1j@9drONJMiDd4GV%!M z>vHXk;>2zmIqWLmLtI@p+nJwZ?{j6pm|$6&TRvRslI_=LDFi@r%OYj1dB6S#^d6}! zmsN>=*A=sY9ZabZ&|m-yB^Z`f^2s5a0+Nd8jo`rb`Yt&HG9?^{9bO}xb2<=*7o7nw zCHCMN1U!bZ-&ub}b&tB<#Yx@ZSX{rbs$xlukLccX?+La z#GC2;`_^f1Ir}cD&C1HnarQ>7f`X!Wt}(m&V4z9W50bW&4y^B9J`m1?Qp*hG@8)6c zCE`fDz6WRn5<~gc%4yS`FwE0%D4PaO-09RC!4*37dIIK7hiDoe(&QvfUOZy_omEHL zM(DVk-YT*3HWoekZoj>5VO7t8y^E5%YY#c==2sODt}jULp1j{tx1c(|Ixf0vT5@-7 zzhl6Bs(f5UdUA>OlD%wlSxQPqx~*hN1>*PYWmC#{WT0PIMw+erl=29F|FDi2x6MxX zhsGo3Qpga*&i)BIj$wjbe!qta^fitadmIOiTB|B~E~=_n)6@y@OH;{l)#3)|IW2kZ z9|M^M%Cul;9)MdYIHhC~6egzUN06wqW$d=ce&4pAf4ySsQ_b5B7!mFd-+k-G8{c~O zW-6E4{gL})^AYr>SkbS7$;C|u>?fQA*`grsb(u(Z>5v)g>F$8_*-t?G^|J`z1{vOS)S||~u~Yp6ZX6wyS*h!tvXpszX2Xzqja{=dy3yPywd_}}H?Pxv zKpr@?+L|3*w8Ehykx4GOAbR$wYC8}%tZ<$r%F6Slq2r%ZAb)EmGPD;yJ5=9+bN%~z zQUAJn{oSyC?%KKA{i0)PzrKT<_}i~eeZFYGz=AdV_8D)N)ekBwsYn0kExP-pVS^v_ zIsH6aMi06D@@1EA8Mb-WvRUq5rZ2yG#_E;RR;-@7TFl9Y`y*o*@D+52t0j)efO+}@ z+{+gCLR(y(dy(#s%&EAS?g(v$VF%KOxM|fw{_Gy*ettsmgC5?tZJj?`UPq^vg|@10 zUB%WCUz`UGc7SwGL|(mJ@17SiU~ZA0bKEt`{b2C&dR+&WuV!Hl;UP%M2hs!$n`g(& zmanZ|Vty@p32$+@fiz)04yj6#=!+3_rivGk$qzF#dSqB@j})%30+Nx?v|8e>-`;sk z=+w;n0uKxwQ?tg4 zDr|^Kolw|xxxfGBi3NkBQzjHnoXtPc^YU|RbuBM9zt*_dmRpclqiH$$d3}t}hAv4< zNJv{Uq+u~nNk~ZHS2T32EYI##(IdNKWo2e|WhJTw`G1nK&D6Bz;0apC78o{K?6J1V zbm9%M0~|gIqzCbEXK-qV=}U34`;9wCo!)=fm{Z#F-Ns*bqK(|sj4pCta|_1uP3D)U z9`Nu$544WuweZ21qJ9tF>|%Qr2=stuO01c8ui^s6TY7$+1i}cBj#Bc-Z`($PzaKaI z^*y^k+m!xZ$r0m4Wo_m36%|RNs;fsQ4&P0>ndbM@Om?U6MfBjZ5Z{F@9U|{en(FJr ze_=;gd}mDa&=~cdy?bd~oPNq!Y%VtwP_LW8+tqpMRp+f&OK0VXGFxrN?9rwVA>u)M z4is^)ouI0aUW2N_kGYYkTAy5)m)}ZN+8yNi$q}^lqg!Yxv@#`WEic{H=}(&`0^G3_ zKrxQtgBL|@jz6+~k1_f62aGpo)Ly9^$(gg52S-E%ao(kC?mUR#I|K!Ucc%93rA(32 z)T5xcXHQGB71jYP3ck8~oGjhey2*gj6S%DcWj9We)831nb7aq+Pd9XYzw`*N_-tzpXJk2s5qYaU@H7K>oZiw1VhZq`?<}0@#*B9K;?S85+{+MX7sP0>B2T zUQrNuL|>Rv!|#sYj~oATOzm4&XCaHqb}WDc1~{Bki8W-#5nlLnS^ePBl0o%b%LffE z?M|#9>hU(}5z<Vfe`;5cLjjFnu}qX~5*rxRevLsXA8U5S>plEF<2Q#sYd zN_3%`B=T0F))_T%GXrRS555Kv)d2(S&Z+$d4shq#FRSZYXLC;P*S}6dMT{fWB@IJL zN(K$S8?0>^I9pT&V`+r@J@<3w6D-dw$ zeg|4qoqj}+Hm_VJt3d0AIMz;Y8QJBE++MwPwM%z6#6*T9RBLLN(i};dld@o$uI83@ z;ygMezK1FoRu@R&&ZL@z-~dKk1usKY5`yZND3iVmVZij7iUmK*`=frwc(M)i-mR4H?m+auVUI=MBgpfGv-70f ze0RdgQ*4F9X`WgKM$x-PwjP`deFmT($>}Xe;-u=^ex0t4*lQfwh&nDreh-NJeDP86 zMYJcawr%pi_9nanIiO{s2?T9p;byAA-i<`tdVKFae9!Kcao9+Vcm`GZQ#@9ZQE%mio z9?4b#BwJg?}!vWyOtFbtz2;b~`KS)eCiZbokwvPF0#`>aDr zsW3hDb_+Eha+3%z{x5M+n3A#8($ib+dtgmYRdjrph|tW4*wT>Yk@Fk7jTzo$(4<*q z-$w`WFn>Q+V#kgnm#3w5%LlEWR~DMN*mI_`ZPq$MKIidp+oeSx<_M|{OCxE`5i_s4 z9Og!(bWg#S5!@d6_`)q-IZxV3Iz!BYjM0%!KTkTCazt=(d})+eNwLLNSSn9#H5i4- zLt47nLy6jAqNmnHKh?cT53B~p>|%ca@?{h!-q_$?^m2E`t+~La`P&EDRx0UMV~HC zz{;A4aU=DIHVXSJPzQ74xy&2lJ48i5_La<&y$n4RLLM~$tyUy`_Ej4sT)(~H9afI;|09;O451Z*B5v=iG!nwPR|9dhip>EoP5Hob3$$^BjDh9>Y| zs@xZ?ret@m<|BD}qSh;P3(k*k4^&V$18q(|47<&E-NGsOi!~YqP5}`S$MdNGpRsTX z+HSPNDWEmZ7pH*s$AnWLH9~+&8)T1#ej<^W4Dn#UCIAi2P6#(7N(1W@oIodIR%lBM z(-qHGG3MYu2$Y_XV8)^%2&Vu(C_!oD74Gp$05e`h63Q?-Z!cXh4u@Wb`kt0PpbkEnF?99{8z z1xN*2HN!@+vqo4bv0iy3e0%{+49&J$742cSg z9prB(hxbjPtOV3J5WUMLBVb zoDvD1jC}tf4{ZO~sblGg!VZ^GXkNgKM7XRmMZ+cr+yx-IR1%DOaHt^TP@wYg9y5tX zVsI;IO;3FbjfMV=%{w}-Cpmf}QewJWd9kE4qFqs8xvnTz>xdSsQ#uwbYn>vayCl!T z4D^g*jOuhEBl!Uo6&Ww~x7T*jG-ptpGQi%qv!->tCztb(czJ-s-rgd182Er@lDY9Y%H_H~Q-;`M6nx{u<2U zS*e)O@l{Z*e=uwakb~0b&;Hu zuDc-KqqWJJo?2GzCtNKAe4vgU74A(%_MvpXKGn_PdoQZRdSB>UkIEU;g;-p ziFb!*a^)zGXEK$w`GEXqoX+qW#&Rt4%tK^!2|FbPz(FcZD$zcKmx3E|+YOHoXd=cQ zm*x^Q3ML=nuS`=t4L{;ARZfmV^t}Wml-6A+U1d5(0PN9}l_Dv8na}e@TD&g^mV!y$ zq8547MHCTUlP+d*5Y9c8z*6jYT3{*HO9?(;DO#NNnFlPz_(Bdl6D){l9 zI23`N8VNga93g>DdoGN0nppwomy*&dkirCmmIQYpisZ^|H>~q@qg1j7t(g#(9vU4O zo0hLmwg;{sADR{#5!?aeo5v~#^CwKv6&!h$B26gp4D$jqir_8t(eJv#=O@&Qk%C18 z`N3A01;R`WDhQ5^ ziiMv|0juCbYA#%i2zANn!5%}5UQ66bF-9N`{GP|0uqALZf*y0Q*)|xE!O;ZA!w`pQ zfsi>If>@45=HL!mQfcNaI{S6D=91nfrzep)nq{R=?w9m>Wf|q`c~f;b)s>h%9Ud^V zi)T;v%OPbY#fAB~5S@n$cr&kRj*Bjdp6ClzAx07K&Ae!eS~{fZUilJ!yDXL%1FYDn zjcq7u80zPD)9M<{Z(x5rFcfA^To{xJT!MSF9%}c@j7&}MmY$JqoYYEFv(n&s)iFK$ z=U#=~RXHIpwG@bGG3o6PD}acW(IX*3x;v?Jr<4@PPCBKgWOqqS&fz@Am|PG?KxuJ8 znWD7(0{(#7pRmB_l;eJ4&aH&H0Qv(=OT-(1bn-Mi?SLg1uc03{V$8yRhY+esVVMT6 zP+x>Fhu6de48Ju*X;NvA5OzMwxQ`3uu)V8R&Uay2o>3-{!!RW~xL^9~T4_dFwx)MY z&&)P{22nb8)bygvjvdbnDJE3|_)O3sCpD>4PBPJ;3swtXVmlAou9OHuE|%z0ziu77OIlBM^{-r!}&zvR)IjjE(k zRh;)6ktp*Kd!|p{jcE|;>M-}u#$NL0GYoi6*{6+<}1NMINt1YFu_8=+K zdkpMTn9?oh0egQ^rZ*HMm8cH|+%>u9z&=IE-HdPuWU6>=o>+6t@(a9gF~aeh}t-Mf*hoB^$71l3a5uh@qNa^C~3VK`0+b`nHQ4w z)=S0~_XnHDjJf^snDKl0tHy7YmE2*_S)IJ)Rpov25B+b*87JJpc%8JBw6(|B$0!%z z`)n;KsK_)3$YhalNX_EKaK#}M-&WP7`*88M)jz*=)pH#V7k=IA$2YI~Q>^m-zt`=U zGkfQ{Uw>J*d)DQ<)(9QL2yLx=+V&x6v4xcbiC);>@C6nvpf{oC&(L!K;hgLFW;IJb zt)75o$kD~5v&e(3B$^LKB1hP5)Qxa&I&APhz&%ZSBZ-&^NDO3I-hhte#hC`{cnP=# zslY8r#GC2v+RZ#`_K!cx8{8A|y=;813%;j&mY_j*|9H~I*4&Lt) z&cl$C-{<4siBP&j$AfN^fIrr|t%%mROD5J3ouQ*yGGG!e5zv0qqoxS2?<4B`J*sb~4IJ$r(OPd*8Kbq** ze@3@!yYzvH?d3lGLv%2aFsZ zkPsN%&;#ei|FU+=+mAoB>AA#@__E6fADXa)^B&m2v6CoIGs+X?!4(Vy7f8|}at@A1 zfwAEQ!~ha1q&R{dJe3S*V4}>hl1s2spz!BOGV;lc;M6wJHQZB0L22_&T6B`-2nb&J zU+*i~B}1wM;sc6D^sW3db=I)RxR5CaR^D{C`b%~h=S#;Q8hp92`lH0>Ha#`_;mgFi zYF8TjrQ@Q{zQOX((P!UM7V`JCO!Tx%)qQhpMfm%*&-KwVjeh)bj0@RVC`~c*F)ofm z_ubbsE=Zq<_5xWv=cJ(jwb~GXOznk$XxIzb=M?kBgQo=qZX5#Pfv#mFE5rDV5u@iW z&Ph$oK{rDgymls<<9f=|Jmfyk{%qd#AJi)X_4;$4KlPq%4Cnjs4XK%MP!@y#k7r42 z0j;)=gAEf%b^d7i6g&J%WJQtZqW!^BGY70806;>@D5VMKg959MxDYFuyzT<2;6{}M zj}@0IF~k)HI|`@Q`uX$%VZr=s?$>-yf$uN*;M4_gz$oa!#7kF4Xy6bX;|@~!5jJ)*Y}9a7{j;r8apN>Ijcw6#L+1!WX#V^ zxA~6pt+E01_35|6M=7_C${C}K8zah>f^qW~oUyI5#L74t@<~KJc>*K{=+D#{JX{Cr zn2%;4jw9s|&%T-8cr(vFq>O91QJ&MhgXT07?6-8YGETxd=*V7omY9L&Jj|{zbT;RS z*_E^Vr986|L(MgZnzTN#)tDBRj-EQ-gCx)%?v>TW|t3)+>qHc%JY`p(J^-XLa z&)+xKTz7Kd`T8ctcZ#`5NszZ-^x<4d3~CH!z!t!M0?gMm%u^m;95f_+aq2N-BUpG+ z2%Ky%SpwC=vc83`IJt;H{y{!AN-|foXDrzj61sHp(p{mOJMyr9ZuxXtbkx(v*Z0rk zfmhF&x8~YKzw_9&-`;V@*H@!2In`j`-AoXDJBHyT3begwc<|6D1B?RDIruPEcaa`Y z>{V9N3gh!zUQRt=xQ`!YI|o6sqnm~HKf^~*;xWnz*}&Ws2Cjax)x+c9O$<>g&L9E5 z1GT-vCezey^>Z%fpYtae!|O2p2>0Wt@Tka$_D-WDfg@!$i5Ve-A!-tNp^oJ=`N-rP zdbY1|^WKwRC@1m@iZfSSo1dTCW#zSewy+8GjM3*&ej6m@3GBMZK}0ZZRz;$8h{3>% zGJcs|wc+zhBbgi1@z2&+Jx_u$bUt)^+sk+f?+R08xk-FUksD~14G(kJ8H5G<*B7>CSsxl8>ggRDQ4qYl)RbZ=4)uS95fjx%Wp?3?97f<@O zbmH-3D$y{EV+*P~-b%$uHS76Y`(%|Jy(uo5G3g@!RElFtT*2@W!j4ZN(=dWJqft+= z<6^i6NZ{RDy+);!Gkj_D?i?N%zA=154ny3N^l?y}AeU1Y-r=7uOza5?qfL*B%@YT%+rFo&#?K*Nv^ufoXy3 zCUNb-jKKB8Gp;AmHJ_w>4&UD>_=QZ>ezT+#=5H4N?BfT2p}it};5mA&um3y79oc>_ zLtiD^Z%Aod?Y?O+h!KuuO#w@$=n4dONG1n+S+ZhU*M+tBFV~+O*k(nTWFpnuz2v`TWlF^WB0&mJ1sfPvA9szrXwtMi{#V*kaR8u%-C>R9i@R{AZU{kPj zYz;3MG2ZT98__X1z2gd_e%_Rxi#r9S4KC;#V295v$}`BQmv5EVLMxP2nGuDY;2%bo zGTuC~dl2OyKXN}O14Obn!*UJdP6`0&Y3yOcSF`ZykbwCQzVgbxIgY{3aT|B-xNfA) z*#`zEmcQ<0_4CFxEq}P>k-r#U{$q3!{D#{zuzXi7my!wZywb!86^W<(mO6P zhRvSTdqH+kQhkx-#|&C*M;|%Cv%x!o7A`@H5RdOPhq%N;i=Y4kUGdTanpG}L&ppJr zb>YfjztPovQ}V>dDp`t7iAWFix=k;s=E{(j()VK?GVK zZE)^>5axm^9IZh8K(<;T-=`H8ELs^HFm21et@Fcfinwge^;b5a4}^7eQC;ijOd2?I z=!k{)FW-20`OqG{@;p^Wo&SV3n2!+>Ky}6z6YcL*&uV{|F9x8RR{N*n7-MhS-!-{0 z!pWUaB|Ewh4eay72JW=TEyq_@_uep>&U zQR^?e;_gXRU3=zx>IeU&$CZD(Ph;Ll*N!w_i+V!GaXJz)=1((P`8T6E1^0|)*1eW! zW2gHE^BvNKG%q`Kz$5cL;Fb9{k3);?F>eI=;E=~7ISgqqg+yXw8$&1BV9d}#JTR;g z$RKJHG`U=buryjcC7s$?4`Cn$H{2B1c;lGbEY-WDS_evkl@_NKL;48aZS$Pj_LBUr z{T%bSURYE(z_GxuVNq4rhN!fO#gnGb$uBL$f&AiX(VoWtJ1J67A^ubeoJkR^IKEK&WHTIj^@jR~iY4c0ZO88}Kn=LZZj2p}y zSj})2B#F5HPksMMXoO{x+Vunz4ej4D{{13b-! z12&1V@pd6iqiMpc<9C0(b9eZ=&Z2?vE_y%g*n*+e4#%{91NuQaq#W71rl4+M{?!lg z$f3n$0|u6q4aE3p9%z&qR|s5(%TM2aCawc~9=^6h6UNU% zXBJ*5FhSbs%cz8{x-xfND;`LaeBxy<9>^<#w`qrc1YT*L(NmsjPDUHgFut&KF~Cvq z=wdLIzX5vBa50wOFm_N;P`>rXU65tbSbn3W;_R{PgPl@tao7;rVhF>R9KGEKA0?)e z%&8&GJ>$NGn?jwzhxxPrd~@ms&zwMb8AyQsazWi4`nJE8WlDMod8RJ@9QC+IYVkGQ9ohX`WC?h zLn0694k{;0m*D#d-HlA5Jp?7PWq6eQVN}cTNNw>QckqNQTTr%^#YU`qk@*11{@3Pb zPrc$P`zzkEn~U8Kv**o6@%(z@!&AWNCqKwjn)i9jW5#6TBs4m@V@~sHr=Fqb7z@vM z%Fdfd7@G|PI>JcS_&8Jv;;e508LLV84uZU59t+**SDH0TAr}#-SULD-p$t< z{f!ysXnKBn+L`)Tv}ug7+6*$Mi#FY6PPg7Sr+erko&MVWh4Byb!T+vJg}4@NY8>d$ zGBi&9Ag*Otys_<>XL#V#Ph;NeqI_d^*IvT@^&IC;yRRL&W!8#WTSnh8d--hTyXjZ2 znz8EYnJZV#SdGpqv3r#x(ii#ylq--8==X30){0P)heJVWnM#mA5qqwfO86uJRh#jZ zBxhOErjv&p9j>V(D+A6rxf7aK-fHEAVR)~b_c9*YDs7sk_*!jzk1d8Z5KGq=7I4 ztgZ#nzkT}nxddle^jdhxril z)mdlw#K8^D0sv{_^)T1M6zfcZ7m7lA09ns3ZvLs3|GCy3aeIWjnLla_;7K>$Nb7vO zyT!;bcVeBkH{auKveqMaQ|mhYrQ0w9%s(OL2J1l34uZoJ$8<4yE+#M!{^A7u0H}K< z`SVL_u{<*wrUmVvwgV?4o|Nz+;6me8!;RNE;1ssQwQl2@gX@e+5REtgfxMGN-t|`A zvAB!vD?TpK$HCKC-shC1$Ql_^*5`P7R@N@q_uzl?AAJvpb2xAx33nU(@VbN7AZyU& zW+U0S+x!dYlGsx2zScvRYrS-Fk5|ST&uRB!=LDM#+NcsAi=~h(tDqP@6Ae3xMFmF( ztD??gvL>H@OyL#;QiM?OxyMK6CdiUqw+HC~cTSB+Ns$$Y4TgUHw<}|BOm+olMJEl+ z7+iW|d`LuoOk!<%-zt<9xmHT6<=5na7wMN!NRzz|ws@B%Nvq#@!+MuXInqPQRJ`l4 zt8jrUyV%wGJ~HVt*AKEm(Gjwg?Ng(vYl##2L&30l>Fz zoM}b3R3yaVLSfLFLOf_yj#wM(i+lyrjEEqBCI-2JaA4>K6&^BbbC#lG?q1kb_$oNA zx73Jq+zN@npdvj?>!;!9v7PwT7)0{gZHnbM=7+|Z@=3beT(u~XPfeazIUh&leWgA~%TutwWC~rv%waox0fsBmsGh1b3fGZ(fT0+*b?8$jZM97Tl z>r-n3!j!kJn{#icnoesQmZQ07UAo~vSeH5_de$XN?jErs>G^Y?k*j}I*U6-VFFjKIDaduyI2o_%VsdvNG$wy!}Q zh)t+-;UE6$hm8=pPcJ&P_t#N)&iG*Q#Pi2FRIOz9DG!4OJ7vE2|2k+XrU`7SAbmYM zs_$nH>zk|?=awJRer10>vwT_)7VCTOQs1|AGvD(KYCo3QKA5j+Z?Sc)_r7Iw)r*I| zBF)PzQ}2s+5uYn)E|%yR%`zz{U;keXag?7nl|70Lt7<~>|rgN z9i``ImFpnNdC&}2thgBq;@nFNLy^u3@rWtVweN3S11l#}J#Cs+OuyR)?Fu%H?m?#_ zp4sdy(`Hz|^()z<2=C}OvWIOyv7`1d#J?jBMO?$0ZR6PQ`W-xj($P0AmX^{;6{zoW zE2iJlw=7MnFcZaZx;`tI%iHdmEk3`$ke09#x|R>KM@9TRdq@5odsr=GN7Ye?ORX5T zz|G1|_Ph68`C$lDJnxA2{%U?Nw-4W*aee0Vb6%_KaTdol)bflwm>#S?F{;RLlw)>9>u(bYwc6CH`O;6ph7*6 z=2Ail-VaCGp)3S_Hs?PIWtgY`%CgiE?AZ&1h3aeUIdueo(v#*15&s=_%O4_8{J$9} zk23 z9=7+jg6$UeyZ3#49x%NSVxc@&wK2H{ElX z$FOIwMX2$_^!vO4-|5{NsNT5N`r+OuKKFgn*uG)CZQmhKoG8-h%2TYjCq()D_TIac zxZ=NjkG@?mcQ8B4z0E$-r^aW}VKZ7BaJ@G?4t$%^XU?TvV+yC zF3_%-B`eM5A687it)Txy#5L+-)(9*u^BKWXWT*KSJ(C|aZ$r4HHLd3z_?aauyAbxEToj)b z%omm2$Ty26{lOgvvF{UYLz@tnd?Da-hWSl^#u;nMF| z;~QAI{3Yuwe}y%l*8L^s3v#je9gb@R^CpBS`kuUoCF=uP!vOrI(0cDoTH`zbYAaP~ zL0vrUbiPlPs8? zqpwh!P)}NV_65QWas50im7X_$l|(Flf93hz4fh{Iz;jlL{?XeT)ZU7SKjOYB7Q;L1YX}0#QS%mjJL6vOAXj7q$&H* zpH2dcHH*ztSF%vCPujtv^;9-i&tQ*%kJR+};29SoTmimu1Ng;n!7m0O{uyx~;-1(O zjby)Tf3O1=O@r@Y-f2)DWS{F}z>^?WzhED!oxsmOfbg5?)_yUcv28H_W_us}PA2Or z_5&}VoHu~aaHDN1GNP3_jiHM+Xs4ljzIA~mZf)O&*~?@k0;^1UF^Qm5r})3N7X?r6TC3p8-o4aP(7ZNsefP}naxVz3w%WTC;Y@; zXPwoJtlbgqSkrJ8Cn=}_=9Ah=mO=q_N>TF= z9ibMqv#|#MjPI6WK6#8y!x~qk z#=@-SQFE`F!4|3~S(17s+U{oTheonh4(yTDLu`(AIjgq~VxuW7WHs*rpJlHW$ihhu z)G8Z$6MIhV@tg;kzjlHp>W!>ei(nb{CXDHDRs?&ULo}vEn8bR>3)oK7FJ1(iJEpTj z(6K-bV}sOOHbmLW`l|&P$GL2vO6eQflQhOfx^Gx9Xtx^IQxRzF=OPp!gdp@ms7Kg@ zkcrSA!J94{zk?BmBkYpW%)6vC7L5>t(2cI;1a`9=VZMntTuuPLkido@K8kn;?*9{U z8m@mpJc*vG*}NEG0KRt}LIpw%LT`jwp0FPAMuZUvRHj}C;}DwgUMb?82=r_e!e|6a zPhmU49)!6F_aTfyScGsT!aXQ2^9J=A@Fi2&6Vju2e+nBdJ;oArd`nrvcH4eoyYYKB zZ2P{!9JB}VNnoFBkebaW5od{@ntzumJP(uU=gq&{;#n&0-;Fe{A}+zRZ}IFlJo^^U zYSAV+utP1AW6ZmyQ>>@-1gn)J*bDNX*(!ybzoC59HpCRWVVK@5->n8;p?j!ID z^v7BswoQ#gsASvZ2id#w<2VcZTegJ1&SuL8+2zWcFgQGd_4|6P zyC1Rv>KL{RYpFv^VuR71Y3gXULS2Kk?sP;1MIZ4h5al)#P-QAv&ZE(5WZrMi0}q`Pd>{2B5z{{@y;9a zN9=(7CVK_fA4@~nU!@v$8RAE!!EC+!B5OuCjqtU+-~3YEXMQ5j!oKc)^JjUs`Ga(g z*cZmtV#_@dm`c$y4g z*pJNPr~^YCTqwI;sxj}8hM3<;gU!PzdjUc|LIOWvxa3l%Q-JTvASr@XNp6fS7rqsR z_cKkm2pw1=u7j{=VA5fXr!?_A1lQTXK(0N1-s!mcl9UWyAQ}7UWXyp$ zj}+fuKmmC?hddsZ+!&`WHUr}k0Foy zkjDf3ILpO%w<44ytU{Qj1hECWKU)A9ox${Mklo$9kYsi`wrAr(MY2wT)-*3LYBzIE{GcacrHwgMH+9ntc?uh<)V!jkpE( zTEZ5x7X1D@e*ayoW)EsT*;d5gAl^prz&usFOEGA865%uO5|@KVzQ$h7K0^2b?|*}| z-{AY-cz^3VxWn-@cZ4nEPTV_z=M;|PJICoa;uFZ@X|0+&5dR5zzODzdm-S#CWE;o* zY-3rNzMb8GFcQ~JT!*$^7non@gRuXg`D+ks@`Oo}b%XbpLH`WiSq1Np;_ps)9}?^>vM2aE`+U)0UyePbKZCs@ z9qjwCFT?n;kv^Xt=Q-lMDx1w$_{`r*`9;61O#QsF%-5BrUzP#pE0VM8d+mR@JLk_o zGB&)5e)zB6*T(1NyvvO55rpqF^^W(J%vr-c1o`NE=N9BAPVjE%KMCK71@Djk^}gso z-vxEP;xt)n)b(-RRM#8#3eRhGJ@9Cb!zxMv z^SN#6dY=EL{j6$?zfa&D3(xmW$QWUfmU2H!Pi77Hy|SUu{8L>8uUodd4LFqO)IJ2oo z`mg;OhkuvzzHBdk#P&8BZ+*w{6{C57d$Js7Hn8sBi_d(X!20zFnZ!HN-K}S67r{F= zpL)HFk1RKIY`1z!g?R(-Ls(Ckmv_8M+z;Yy;%wIT>_NmC(eWMER`aHguh?HGGJ|7) zgFe|HFOc>|_AqjB&xF45>&-GaF7Gk)jF7JE8)jKwNzAF1YY30g4$m|8?)c4mLK=+} z)?PiC3t9ZG)F-${NWOEEj1Djx<>p{-#~#X_+$1^6*j=iu!{BlGkThpmLpxT+<&9(y zqEYg#F_h7B9k0+P)9hd$hy5Dn?OTJjHfPP9W2DMyj0x9y@5{b?w&Mb057vvHuy!6U z!-75Aov?4hxEmjngK;z%!-MfM*caygF`vgd%{o!KxLpWi{^$Hco$M}$dgmbHhK}#z zd%Wy#`t76(_Ded`hvQ|i4;u8*pnnE?uawQQUHfaipN4%jKGr@bm4QBE;f_77A86x= zJxKPnn4=H0@8Tx=DEA{fUI_N#f_?1N?Hv*`;rl9;xKKo-oM>%E( z^}sVKn=(IJ-b{KD_YwF}SMCuVANmtIJ`A3paT|mF!)I4?fgEV^4%EIBf<3{@@} zmcTn&{1K5L(De9BrorQ0=%Ih?_&dP(q+^}&8DrU0>4(g6_KrR<_Ld0Ohad}PaQ_42 z@2AE`@~)Y}?=9}#@t2(}^~UGCceqY2W!?3U$aYF;`$M?-*#36L^z96F+xf_J`yWt* zJNVe~daiseto>Iw874yolmcJF3cmju=Vz|p5|^dg_C=7(J*U8K`;zM$zzQ#rw_O2W z^=an=^zA{|<05}8fvvc&g~cM6CfhlwuYE9_4Y%S^p+1l=RqSbG{z%a{5Yb$Wcws#Ge^DP;5ET#?`_JUqvQJj##o8~#rwh@Y!)BF~Fp z&H6UBj~4lx-GKI5+&uTTC*fud8@KB$u2b-jKv0nUYrmg3S8`>A+Rh4g8yVU55d>#A zEJO!o)9!Q6DtG%Kz&AvK-)P>p7CkM59nC%E-cEdV6zrF{%AUlz2l%#r@ZI&GzS=9{ zO_&WsVG!YSU>NS8Y=6N`nQnUz_lrP&x3ioM>Y<&o-F_Jab$Bsx$Zz{kz}Xt@D*(IO ze(v= zt;cnIsE_K{prh;~o!7BIZKi*IE#I)$AG{9_KKF31K8o`<)1;TVRb9!x)Z6wn$<%{+ z&Tr%FOZ?2SjM4Qf!Z)M#kKb=qs|Z_#dsRGMa8DTfzNe9=gMxQ%Wc*k2W_7CiAKIEe zT~!9{i!}SuKTpz|k#PWf;ME;v#-xsiboY*B`s9u~^~wL-L|=S9xKe&k(6;uIJ=*t^ zZre^b9%R4d!H!pPFP1Jr8{2l4bZe)7Y#T!PpDp`t9~`u2<~1`(_XFRLyIkkcX3e0l z{*xv9wx2Ht(ueoj-c`D6e>x~v*?${9fYN>}^;D;ZcGU5ECe6qmC2so|^jsnCw*6(d zzrRCvR8Nw-I_G5iLAg)gDW7sO=w5LgwZH7Xoge-E`&GuNo0wPJBq`g1{&0}&y=@~l zwxQ>G>Armod(63|3prcB7j5u7SDiNj}ED*7I;5ERkltyK?ktY7gUj z$qo86^)rYs!|YGF^H0}@w6i;x3WZP&^MOxX8?--TGdn~{5CwLI%o zExWX0&4ookT8p&2?G!r($hGGKa&7vd-Nq-s(;)}OLOm>j)v$%#revT$xX5&o=_1ob zCZB*3Zz-&S4ID*nLJueh;`xO6*cHJ)5(Uyn=D|XdB!Na)4x~*&&u&ey0ygq3X&2H( zx^nHB0?6%(o^HtO7F=8T^#S~M&w;VfAhJiD$eyWyu05BCBy*pP%w%LHBXcig?M3)r zg-`*tK)Su!ME33uxljr706lx7XYW={r^MKOkhxDeAakDu&q8bp-m*UJCKJ|WTqlB6`85TIXHlLhobLL!VV?uP{Iyvf%PJ30{lsvPF6Xl)wyV0A%(+W=~}HL}pLIde*=KXoetcv&fMt zPzaUa3$Dm4JUQ()3yf?IP*jAr}Zsp9f1}4Uq0AG~fq2I*2mFt16Upfgq{|^)4(W18cU-y1@d9;#&f`}AG6rDJfEW}4 zaR$_ivRq{$;q9%=GOlTVubbf9eV3D2JoEwElB_%>)k8k9f{EP!TM2kjz- zserD+Y9L+VGFS_3B1On7LS_*%iyC1$Y!E3p3t zWGr#U#$Y*Y;3PN`kTDLwap)MgROE~(ltUdf!3x+YGTw!BD1%y&N@P{00(Mu{zyfFn z?5=DVsUoZjnN`?bMOf7mz<&b%6Y!sa|AhIl4AzQFMCU~0Oq?T9og^|T8_Ixqljg!w zSPAQ)Rb(=8CZ|CT5N9%RCN~1|Ca;1G&?Yja8^oX#DgpUZ8UT4ykT(T+Q;=7a0_dzk zXASbE5@+fnSPpANrjLa>SO5z}W;6m}XQFE+>1UCCRt^xawmU2nnLUrwiblZ<2;8JQ zs|D7;7Ll_Bx{1`ekS=l#GR`d&IS*Us)WUpN2I!yDCUQP;&yNA&7Y5XbT(knvfALZv zKbH{qlFcIZCSXTB@#~3OUkP)d0f<{q-1_xE+Dnrl3gu7>jey=u$=jtH0Nt0N`?4ND zoXe1P8L}>G0AyXx{k)jS6>w#m$W`eg^HZS^Dxe1HVF|2;jUv~O*K5&vE%L4<{93}V zZGvVX&b7q3wq0Zae%Il5J-V;Yg-Veda$vJa!+Mb$vF)Y>A~z$Wu?~peNSQQ}{uUR~ zp$uxF5wPJF!f$C6xityW0C~5T!(3PdYhaVeZ35VNTNFxQEX;uhSPClv8=BD5gq|k! zH=)026>R3!rU~7l5b(dfS>z7n+<}}shxo$W$91| z6+pUWq+7NO)nWlLm51ykOs(YMs9O0Ah&rD zEQhtQS>y>5xW-k1U8 z`3>^?MhmQmR$=Q6vY|u-ak6^3$XoDsDy$QE2mNcRfw=FsiM)^B+W8_MAnya@eXtZ( z!X}Xqk@aB|u=T?_k&lq^5&k5Rb!m_TV}U%ZTLLItw}sc|O+bD==KhmLkx#4HRw@DF zu1C)L1wj1uD*$2ZN%NTtsgMn2K$_3y0_i_n25X^BwjgH(|i>>0j?je;H};C|f% zt)h%1z-=^(V!uI|n?zZhSIVcwlv4<6VY6_21S}Wj6Q2|46>EDHStcqe2Bo5QOBK~6 z9Z1uq0%~DCECSMXK~5Labwy6s?vMk->pBOTU^%RZc2V8B19H0|w_6R=19G|%ryFs0 zZxOWz`u4!qJ#p{3MpSYmED^O=ov6KYMeS1t)i4(b+Xq|sSp^%QO;if<_9foFqhJQi zgN4un$lG_5#J4E-OW_)YG9cc53t$sQ1N7~Woc)or{|ZsvD`7Qk1oCx2 zGNeNxQ~+gkzWAB_LO=sP40 zR){*Z5Xzwj>Y)jmVKr<7(x)XuIuJLl0%~DCEP~~*7B-7IY^kWj=ZHFj_(!Y*^4i0N zRLBPM+k^b}mzwHOzx0unIPbI#K{RMMDY+*0vB=7ai8`(jhV~$Qa=Q*O4aM(=eK_(Mv>~+AOMqIHw`&bo8E%tTAk1XhTeFpnSdAk9SNR4)}ZX@RK8InXF-N(m5$^@N(549i4KL*BGhh(a!u!C069 zb76s~>7<)ZKBljNb+8HAM9oNn9#9H%0DY`M)Qr`l&P4xA(#~86%K*Qbq?=_zDqz#B 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Ç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 literal 0 HcmV?d00001 diff --git a/Extern/imgui/Inter-Regular.ttf b/Extern/imgui/Inter-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b7aaca8de1fe458399e17311d35d543a1fa2f984 GIT binary patch literal 411640 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 literal 0 HcmV?d00001 diff --git a/Extern/imgui/License-Inter.txt b/Extern/imgui/License-Inter.txt new file mode 100644 index 000000000..9b2ca37b3 --- /dev/null +++ b/Extern/imgui/License-Inter.txt @@ -0,0 +1,92 @@ +Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION AND CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/OVP/D3D9Client/CMakeLists.txt b/OVP/D3D9Client/CMakeLists.txt index f868c49c5..3e7b351e3 100644 --- a/OVP/D3D9Client/CMakeLists.txt +++ b/OVP/D3D9Client/CMakeLists.txt @@ -175,6 +175,8 @@ target_include_directories(D3D9Client PUBLIC ${DXSDK_DIR}/Include ${imgui_SOURCE_DIR}/ ${imgui_SOURCE_DIR}/backends/ + SDL3::SDL3 + SDL3_image::SDL3_image ) target_link_directories(D3D9Client PUBLIC @@ -203,6 +205,8 @@ target_link_libraries(D3D9Client odbccp32.lib version.lib msimg32.lib + SDL3::SDL3 + SDL3_image::SDL3_image ) set_target_properties(D3D9Client @@ -232,10 +236,12 @@ add_dependencies(D3D9Client ${OrbiterTgt} Orbitersdk D3D9Client_Interface + SDL3::SDL3 + SDL3_image::SDL3_image ) install(TARGETS D3D9Client - LIBRARY + LIBRARY DESTINATION ${ORBITER_INSTALL_PLUGIN_DIR} ) diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index 32ea4999b..f4b52c3df 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -312,7 +312,7 @@ D3D9Client::~D3D9Client() // ============================================================== -// +// bool D3D9Client::ChkDev(const char *fnc) const { if (pDevice) return false; @@ -382,7 +382,7 @@ bool D3D9Client::clbkInitialise() // ============================================================== // This is called when a simulation session will begin // -HWND D3D9Client::clbkCreateRenderWindow() +std::shared_ptr D3D9Client::clbkCreateRenderWindow() { _TRACE; @@ -391,7 +391,7 @@ HWND D3D9Client::clbkCreateRenderWindow() if (!g_pD3DObject) return NULL; Config->WriteParams(); - + uEnableLog = Config->DebugLvl; pSplashScreen = NULL; pBackBuffer = NULL; @@ -426,8 +426,8 @@ HWND D3D9Client::clbkCreateRenderWindow() hRenderWnd = GraphicsClient::clbkCreateRenderWindow(); - LogAlw("Window Handle = %s",_PTR(hRenderWnd)); - SetWindowText(hRenderWnd, "[D3D9Client]"); + LogAlw("Window Handle = %s",_PTR(hRenderWnd->Win32Handle())); + SDL_SetWindowTitle(hRenderWnd->Inner(), "[D3D9Client]"); LogOk("Starting to initialize device and 3D environment..."); @@ -435,7 +435,7 @@ HWND D3D9Client::clbkCreateRenderWindow() WriteLog("[DirectX 9 Initialized]"); - HRESULT hr = pFramework->Initialize(hRenderWnd, GetVideoData()); + HRESULT hr = pFramework->Initialize(hRenderWnd->Win32Handle(), GetVideoData()); if (hr!=S_OK) { LogErr("ERROR: Failed to initialize 3D Framework"); @@ -443,13 +443,13 @@ HWND D3D9Client::clbkCreateRenderWindow() } RECT rect; - GetClientRect(hRenderWnd, &rect); - HDC hWnd = GetDC(hRenderWnd); + GetClientRect(hRenderWnd->Win32Handle(), &rect); + HDC hWnd = GetDC(hRenderWnd->Win32Handle()); HBRUSH hBr = CreateSolidBrush(RGB(0,0,0)); FillRect(hWnd, &rect, hBr); DeleteObject(hBr); - ReleaseDC(hRenderWnd, hWnd); - ValidateRect(hRenderWnd, NULL); // avoids white flash after splash screen + ReleaseDC(hRenderWnd->Win32Handle(), hWnd); + ValidateRect(hRenderWnd->Win32Handle(), NULL); // avoids white flash after splash screen pCaps = pFramework->GetCaps(); @@ -501,7 +501,7 @@ HWND D3D9Client::clbkCreateRenderWindow() SplashScreen(); // Warning SurfNative is not yet fully initialized here - ShowWindow(hRenderWnd, SW_SHOW); + SDL_ShowWindow(hRenderWnd->Inner()); OutputLoadStatus("Building Shader Programs...",0); @@ -595,7 +595,7 @@ void D3D9Client::clbkPostCreation() // Create Window Manager ----------------------------------------- // if (Config->gcGUIMode != 0) { - pWM = new WindowManager(hRenderWnd, ModuleInstance(), !(GetVideoData()->fullscreen)); + pWM = new WindowManager(hRenderWnd->Win32Handle(), ModuleInstance(), !(GetVideoData()->fullscreen)); if (pWM->IsOK() == false) SAFE_DELETE(pWM); } @@ -672,9 +672,9 @@ void D3D9Client::SketchPadTest() oapiReleaseTexture(hSrc); oapiReleaseTexture(hTgt); - + // Run Different Kind of Tests - // + // hTgt = oapiCreateSurfaceEx(768, 512, OAPISURFACE_RENDERTARGET); @@ -716,11 +716,11 @@ void D3D9Client::SketchPadTest() HPOLY hOutline = pCore->CreatePoly(NULL, Pol, 6, PF_CONNECT); HPOLY hOutline2 = pCore->CreatePoly(NULL, Pol, 6); - Vtx[0].color = 0xFFFF0000; - Vtx[1].color = 0xFFFFFF00; - Vtx[2].color = 0xFFF0FF00; - Vtx[3].color = 0xFF00FFFF; - Vtx[4].color = 0xFF0000FF; + Vtx[0].color = 0xFFFF0000; + Vtx[1].color = 0xFFFFFF00; + Vtx[2].color = 0xFFF0FF00; + Vtx[3].color = 0xFF00FFFF; + Vtx[4].color = 0xFF0000FF; Vtx[5].color = 0xFFFF00FF; Vtx[0].pos = FVECTOR2(-1, 0); @@ -734,7 +734,7 @@ void D3D9Client::SketchPadTest() Vtx[0].color = 0xFF00FF00; // Green - Vtx[1].color = 0xFF00FF00; // Green + Vtx[1].color = 0xFF00FF00; // Green Vtx[2].color = 0xFFFF00FF; // Mangenta Vtx[3].color = 0xFFFF00FF; // Mangenta Vtx[4].color = 0xFF0000FF; // Blue @@ -1688,11 +1688,11 @@ int D3D9Client::clbkVisEvent(OBJHANDLE hObj, VISHANDLE vis, DWORD msg, DWORD_PTR // ============================================================== // -void D3D9Client::PickTerrain(DWORD uMsg, int xpos, int ypos) +void D3D9Client::PickTerrain(Uint32 uMsg, int xpos, int ypos) { - bool bUD = (uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP || uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN); + bool bUD = (uMsg == SDL_EVENT_MOUSE_BUTTON_UP || uMsg == SDL_EVENT_MOUSE_BUTTON_DOWN); bool bPrs = IsGenericProcEnabled(GENERICPROC_PICK_TERRAIN) && bUD; - bool bHov = IsGenericProcEnabled(GENERICPROC_HOVER_TERRAIN) && (uMsg == WM_MOUSEMOVE || uMsg == WM_MOUSEWHEEL); + bool bHov = IsGenericProcEnabled(GENERICPROC_HOVER_TERRAIN) && (uMsg == SDL_EVENT_MOUSE_MOTION || uMsg == SDL_EVENT_MOUSE_WHEEL); if (bPrs || bHov) { gcCore::PickGround pg = gcCore2::ScanScreen(xpos, ypos); @@ -1702,225 +1702,167 @@ void D3D9Client::PickTerrain(DWORD uMsg, int xpos, int ypos) } } +static bool EventIsKeyboard(Uint32 type) { + return type >= SDL_EVENT_KEY_UP && type < SDL_EVENT_MOUSE_MOTION; +} + +static bool EventIsMouse(Uint32 type) { + return type >= SDL_EVENT_MOUSE_MOTION && + type < SDL_EVENT_JOYSTICK_AXIS_MOTION; +} // ============================================================== // Message handler for render window -LRESULT D3D9Client::RenderWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - static bool bTrackMouse = false; - static short xpos=0, ypos=0; - - D3D9Pick pick; - - if (hRenderWnd!=hWnd && uMsg!= WM_NCDESTROY) { - LogErr("Invalid Window !! RenderWndProc() called after calling clbkDestroyRenderWindow() uMsg=0x%X", uMsg); - return 0; - } - - if (bRunning && DebugControls::IsActive()) { - // Must update camera to correspond MAIN_SCENE due to Pick() function, - // because env-maps have altered camera settings - // GetScene()->UpdateCameraFromOrbiter(RENDERPASS_PICKSCENE); - // Obsolete: since moving env/cam stuff in pre-scene - } - - if (pWM) if (pWM->MainWindowProc(hWnd, uMsg, wParam, lParam)) return 0; - - - switch (uMsg) - { - case WM_MOUSELEAVE: - { - if (bTrackMouse && bRunning) GraphicsClient::RenderWndProc (hWnd, WM_LBUTTONUP, 0, 0); - return 0; - } - - case WM_MBUTTONDOWN: - { - break; - } - - case WM_RBUTTONUP: - case WM_RBUTTONDOWN: - { - int xp = GET_X_LPARAM(lParam); - int yp = GET_Y_LPARAM(lParam); - PickTerrain(uMsg, xp, yp); - break; - } - - - case WM_LBUTTONDOWN: - { - bTrackMouse = true; - xpos = GET_X_LPARAM(lParam); - ypos = GET_Y_LPARAM(lParam); - - GetScene()->vPickRay = GetScene()->GetPickingRay(xpos, ypos); - - TRACKMOUSEEVENT te; te.cbSize = sizeof(TRACKMOUSEEVENT); te.dwFlags = TME_LEAVE; te.hwndTrack = hRenderWnd; - TrackMouseEvent(&te); - - bool bShift = (GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0; - bool bCtrl = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0; - bool bPckVsl = IsGenericProcEnabled(GENERICPROC_PICK_VESSEL); - - if (DebugControls::IsActive() || bPckVsl || (bShift && bCtrl)) { - pick = GetScene()->PickScene(xpos, ypos); - if (bPckVsl) { - gcCore::PickData out; - out.hVessel = pick.vObj->GetObjectA(); - out.mesh = MESHHANDLE(pick.pMesh); - out.group = pick.group; - out.pos = _FV(pick.pos); - out.normal = _FV(pick.normal); - out.dist = pick.dist; - MakeGenericProcCall(GENERICPROC_PICK_VESSEL, sizeof(gcCore::PickData), &out); - } - } - - PickTerrain(uMsg, xpos, ypos); - - // No Debug Controls - if (bShift && bCtrl && !DebugControls::IsActive() && !oapiCameraInternal()) { - - if (!pick.pMesh) break; - - OBJHANDLE hObj = pick.vObj->Object(); - if (oapiGetObjectType(hObj) == OBJTP_VESSEL) { - oapiSetFocusObject(hObj); - } - - break; - } - - // With Debug Controls - if (DebugControls::IsActive()) { - - DWORD flags = *(DWORD*)GetConfigParam(CFGPRM_GETDEBUGFLAGS); - - if (flags&DBG_FLAGS_PICK) { - - if (!pick.pMesh) break; - - if (bShift && bCtrl) { - OBJHANDLE hObj = pick.vObj->Object(); - if (oapiGetObjectType(hObj)==OBJTP_VESSEL) { - oapiSetFocusObject(hObj); - break; - } - } - else if (pick.group>=0) { - DebugControls::SetVisual(pick.vObj); - DebugControls::SelectMesh(pick.pMesh); - DebugControls::SelectGroup(pick.group); - DebugControls::SetGroupHighlight(true); - DebugControls::SetPickPos(pick.pos); - } - } - } - - break; - } - - case WM_LBUTTONUP: - { - int xp = GET_X_LPARAM(lParam); - int yp = GET_Y_LPARAM(lParam); - - PickTerrain(uMsg, xp, yp); - - if (DebugControls::IsActive()) { - DWORD flags = *(DWORD*)GetConfigParam(CFGPRM_GETDEBUGFLAGS); - if (flags&DBG_FLAGS_PICK) { - DebugControls::SetGroupHighlight(false); - } - } - bTrackMouse = false; - break; - } - - case WM_KEYDOWN: - { - bool bShift = (GetAsyncKeyState(VK_SHIFT) & 0x8000)!=0; - bool bCtrl = (GetAsyncKeyState(VK_CONTROL) & 0x8000)!=0; - if (wParam == 'C' && bShift && bCtrl) bControlPanel = !bControlPanel; - if (wParam == 'N' && bShift && bCtrl) Config->bCloudNormals = !Config->bCloudNormals; - if (wParam == 'F' && bShift && bCtrl) { - if (bFreeze) bFreezeEnable = bFreeze = false; - else bFreezeEnable = true; - } - if (wParam == 'A' && bFreeze) bFreezeRenderAll = !bFreezeRenderAll; - - break; - } - - case WM_MOUSEWHEEL: - { - if (DebugControls::IsActive()) { - short d = GET_WHEEL_DELTA_WPARAM(wParam); - if (d<-1) d=-1; - if (d>1) d=1; - double speed = *(double *)GetConfigParam(CFGPRM_GETCAMERASPEED); - speed *= (DebugControls::GetVisualSize()/100.0); - if (scene->CameraPan(_V(0,0,double(d))*2.0, speed)) return 0; - } - - PickTerrain(uMsg, xpos, ypos); - break; - } - - case WM_MOUSEMOVE: - - if (DebugControls::IsActive()) - { - - double x = double(GET_X_LPARAM(lParam) - xpos); - double y = double(GET_Y_LPARAM(lParam) - ypos); - xpos = GET_X_LPARAM(lParam); - ypos = GET_Y_LPARAM(lParam); - - if (bTrackMouse) { - double speed = *(double *)GetConfigParam(CFGPRM_GETCAMERASPEED); - speed *= (DebugControls::GetVisualSize() / 100.0); - if (scene->CameraPan(_V(-x, y, 0)*0.05, speed)) return 0; - } - } - - xpos = GET_X_LPARAM(lParam); - ypos = GET_Y_LPARAM(lParam); - - PickTerrain(uMsg, xpos, ypos); - - break; - - case WM_MOVE: - // If in windowed mode, move the Framework's window - break; - - case WM_SYSCOMMAND: - switch (wParam) { - case SC_KEYMENU: - // trap Alt system keys - return 1; - case SC_MOVE: - case SC_SIZE: - case SC_MAXIMIZE: - case SC_MONITORPOWER: - // Prevent moving/sizing and power loss in fullscreen mode - if (bFullscreen) return 1; - break; - } - break; - - case WM_SYSKEYUP: - if (bFullscreen) return 0; // trap Alt-key - break; - } - - if (!bRunning && uMsg>=0x0200 && uMsg<=0x020E) return 0; - return GraphicsClient::RenderWndProc (hWnd, uMsg, wParam, lParam); +bool D3D9Client::RenderWndProc(const SDL_Event &event, bool &wantsOut) { + static bool bTrackMouse = false; + static short xpos = 0, ypos = 0; + + D3D9Pick pick; + + if (hRenderWnd == nullptr) { + LogErr("Invalid Window !! RenderWndProc() called after calling " + "clbkDestroyRenderWindow()"); + return false; + } + + if (bRunning && DebugControls::IsActive()) { + // Must update camera to correspond MAIN_SCENE due to Pick() function, + // because env-maps have altered camera settings + // GetScene()->UpdateCameraFromOrbiter(RENDERPASS_PICKSCENE); + // Obsolete: since moving env/cam stuff in pre-scene + } + + if (pWM) + if (pWM->MainWindowProc(event)) + return true; + + if (event.type == SDL_EVENT_QUIT || + (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && + event.window.windowID == SDL_GetWindowID(hRenderWnd->Inner()))) { + wantsOut = true; + return true; + } + + if ((event.type == SDL_EVENT_WINDOW_MOUSE_LEAVE && + event.window.windowID == SDL_GetWindowID(hRenderWnd->Inner()) && bTrackMouse && bRunning) || + (event.type == SDL_EVENT_MOUSE_BUTTON_UP && + event.button.button == SDL_BUTTON_LEFT)) { + float xpf, xpy = 0; + SDL_GetMouseState(&xpf, &xpy); + + PickTerrain(event.type, xpf, xpy); + + if (DebugControls::IsActive()) { + DWORD flags = *(DWORD *)GetConfigParam(CFGPRM_GETDEBUGFLAGS); + if (flags & DBG_FLAGS_PICK) { + DebugControls::SetGroupHighlight(false); + } + } + bTrackMouse = false; + } else if ((event.type == SDL_EVENT_MOUSE_BUTTON_UP || event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) && event.button.button == SDL_BUTTON_RIGHT) { + int xp = event.button.x; + int yp = event.button.y; + PickTerrain(event.type, xp, yp); + } else if ((event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) && event.button.button == SDL_BUTTON_LEFT) { + bTrackMouse = true; + xpos = event.button.x; + ypos = event.button.y; + + GetScene()->vPickRay = GetScene()->GetPickingRay(xpos, ypos); + + bool bShift = (GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0; + bool bCtrl = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0; + bool bPckVsl = IsGenericProcEnabled(GENERICPROC_PICK_VESSEL); + + if (DebugControls::IsActive() || bPckVsl || (bShift && bCtrl)) { + pick = GetScene()->PickScene(xpos, ypos); + if (bPckVsl) { + gcCore::PickData out; + out.hVessel = pick.vObj->GetObjectA(); + out.mesh = MESHHANDLE(pick.pMesh); + out.group = pick.group; + out.pos = _FV(pick.pos); + out.normal = _FV(pick.normal); + out.dist = pick.dist; + MakeGenericProcCall(GENERICPROC_PICK_VESSEL, + sizeof(gcCore::PickData), &out); + } + } + + PickTerrain(event.type, xpos, ypos); + + // No Debug Controls + if (bShift && bCtrl && !DebugControls::IsActive() && + !oapiCameraInternal()) { + + if (!pick.pMesh) + return true; + + OBJHANDLE hObj = pick.vObj->Object(); + if (oapiGetObjectType(hObj) == OBJTP_VESSEL) { + oapiSetFocusObject(hObj); + } + + return true; + } + + // With Debug Controls + if (DebugControls::IsActive()) { + + DWORD flags = *(DWORD *)GetConfigParam(CFGPRM_GETDEBUGFLAGS); + + if (flags & DBG_FLAGS_PICK) { + if (!pick.pMesh) + return true; + + if (bShift && bCtrl) { + OBJHANDLE hObj = pick.vObj->Object(); + if (oapiGetObjectType(hObj) == OBJTP_VESSEL) { + oapiSetFocusObject(hObj); + return true; + } + } else if (pick.group >= 0) { + DebugControls::SetVisual(pick.vObj); + DebugControls::SelectMesh(pick.pMesh); + DebugControls::SelectGroup(pick.group); + DebugControls::SetGroupHighlight(true); + DebugControls::SetPickPos(pick.pos); + } + } + } + } else if (event.type == SDL_EVENT_KEY_DOWN) { + bool bShift = (event.key.mod & SDL_KMOD_SHIFT) != 0; + bool bCtrl = (event.key.mod & SDL_KMOD_CTRL) != 0; + if (event.key.key == SDLK_C && bShift && bCtrl) + bControlPanel = !bControlPanel; + if (event.key.key == SDLK_N && bShift && bCtrl) + Config->bCloudNormals = !Config->bCloudNormals; + if (event.key.key == SDLK_F && bShift && bCtrl) { + if (bFreeze) + bFreezeEnable = bFreeze = false; + else + bFreezeEnable = true; + } + if (event.key.key == SDLK_A && bFreeze) + bFreezeRenderAll = !bFreezeRenderAll; + } else if (event.type == SDL_EVENT_MOUSE_WHEEL) { + if (DebugControls::IsActive()) { + short d = event.wheel.y; + if (d < -1) + d = -1; + if (d > 1) + d = 1; + double speed = *(double *)GetConfigParam(CFGPRM_GETCAMERASPEED); + speed *= (DebugControls::GetVisualSize() / 100.0); + if (scene->CameraPan(_V(0, 0, double(d)) * 2.0, speed)) + return 0; + } + + PickTerrain(event.type, xpos, ypos); + } + + return GraphicsClient::RenderWndProc(event, wantsOut); } @@ -2106,9 +2048,9 @@ bool oapi::D3D9Client::SaveSurfaceToFile (const D3DSURFACE_DESC* desc, D3DLOCKED bool oapi::D3D9Client::SaveSurfaceToClipboard (const D3DSURFACE_DESC* desc) { - if (OpenClipboard(hRenderWnd)) + if (OpenClipboard(hRenderWnd->Win32Handle())) { - HDC hDC = GetDC(hRenderWnd); + HDC hDC = GetDC(hRenderWnd->Win32Handle()); HDC hdcmem = CreateCompatibleDC(hDC); HBITMAP hBm = CreateCompatibleBitmap(hDC, desc->Width, desc->Height); @@ -2201,7 +2143,7 @@ SURFHANDLE D3D9Client::clbkLoadSurface (const char *fname, DWORD attrib, bool bP } */ } - + return NatLoadSurface(fname, attrib, bPath); } @@ -2251,7 +2193,7 @@ SURFHANDLE D3D9Client::clbkCreateSurface(DWORD w, DWORD h, SURFHANDLE hTemplate) DWORD attrib = OAPISURFACE_PF_XRGB | OAPISURFACE_RENDERTARGET | OAPISURFACE_TEXTURE; if (hTemplate) attrib = SURFACE(hTemplate)->GetOAPIFlags(); - + SURFHANDLE hNew = NatCreateSurface(w, h, attrib); SURFACE(hNew)->SetName("clbkCreateSurface"); return hNew; @@ -2403,7 +2345,7 @@ bool D3D9Client::clbkBlt(SURFHANDLE tgt, DWORD tgtx, DWORD tgty, SURFHANDLE src, bool D3D9Client::clbkScaleBlt (SURFHANDLE tgt, DWORD tgtx, DWORD tgty, DWORD tgtw, DWORD tgth, SURFHANDLE src, DWORD srcx, DWORD srcy, DWORD srcw, DWORD srch, DWORD flag) const { - + if (src==NULL) { oapiWriteLog((char*)"ERROR: oapiBlt() Source surface is NULL"); return false; } if (tgt==NULL) tgt = pFramework->GetBackBufferHandle(); @@ -2494,7 +2436,7 @@ bool D3D9Client::clbkScaleBlt (SURFHANDLE tgt, DWORD tgtx, DWORD tgty, DWORD tgt { // Texture Update: Source is in system memory and target is a texture - // + // if (sd->Pool == D3DPOOL_SYSTEMMEM) { if (S_OK == pDevice->UpdateSurface(pss, &rs, pts, &tp)) return true; @@ -2506,14 +2448,14 @@ bool D3D9Client::clbkScaleBlt (SURFHANDLE tgt, DWORD tgtx, DWORD tgty, DWORD tgt // Screen Capture: Target is in system memory and source is a render taeget - // + // if ((td->Pool == D3DPOOL_SYSTEMMEM) && (sd->Usage & D3DUSAGE_RENDERTARGET)) { if (S_OK == pDevice->GetRenderTargetData(pss, pts)) { SURFACE(tgt)->Flags |= OAPISURFACE_CAPTURE; return true; } - + LogErr("oapiBlt() GetRenderTargetData() Failed"); BltError(src, tgt, &rs, &rt); return false; @@ -2538,7 +2480,7 @@ bool D3D9Client::clbkScaleBlt (SURFHANDLE tgt, DWORD tgtx, DWORD tgty, DWORD tgt return true; } else - { + { pSkp->StretchRect(src, &rs, &rt); clbkReleaseSketchpad_const(pSkp); return true; @@ -2594,7 +2536,7 @@ bool D3D9Client::clbkCopyBitmap(SURFHANDLE pdds, HBITMAP hbm, int x, int y, int SURFACE(pdds)->SetName("clbkCopyBitmap"); return true; } - else + else { LPDIRECT3DTEXTURE9 pTemp = NULL; LPDIRECT3DSURFACE9 pSrf = NULL; @@ -2625,7 +2567,7 @@ bool D3D9Client::clbkCopyBitmap(SURFHANDLE pdds, HBITMAP hbm, int x, int y, int else { pSrf->Release(); assert(false); - } + } } } DeleteDC(hdcImage); @@ -2976,7 +2918,7 @@ void D3D9Client::SplashScreen() RECT rS; - GetWindowRect(hRenderWnd, &rS); + GetWindowRect(hRenderWnd->Win32Handle(), &rS); LogAlw("Splash Window Size = [%u, %u]", rS.right - rS.left, rS.bottom - rS.top); LogAlw("Splash Window LeftTop = [%d, %d]", rS.left, rS.top); diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 9109f8b85..223bc84eb 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -82,7 +82,7 @@ struct _D3D9Stats DWORD TexChanges; ///< Number of texture changes DWORD MtrlChanges; ///< Number of material changes } Mesh; ///< Mesh related statistics - + struct { D3D9Time Update; ///< clbkUpdate D3D9Time Scene; ///< clbkRenderScene @@ -141,7 +141,7 @@ namespace oapi { // The DX9 render client for Orbiter // ============================================================== -class D3D9Client : public GraphicsClient +class D3D9Client : public GraphicsClient { friend class ::Scene; // <= likes to call Render2DOverlay() @@ -525,23 +525,7 @@ class D3D9Client : public GraphicsClient */ ScreenAnnotation* clbkCreateAnnotation(); - /** - * \brief Render window message handler - * - * Derived classes should also call the base class method to allow - * default message processing. - * \param hWnd render window handle - * \param uMsg Windows message identifier - * \param wParam WPARAM message parameter - * \param lParam LPARAM message parameter - * \return The return value depends on the message being processed. - * \note This is the standard Windows message handler for the render - * window. - * \note This method currently intercepts only the WM_CLOSE and WM_DESTROY - * messages, and passes everything else to the Orbiter core message - * handler. - */ - LRESULT RenderWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + bool RenderWndProc(const SDL_Event &event, bool &wantsOut) override; /** * \brief Message handler for 'video' tab in Orbiter Launchpad dialog @@ -1043,7 +1027,6 @@ class D3D9Client : public GraphicsClient void clbkImGuiShutdown() override; uint64_t clbkImGuiSurfaceTexture(SURFHANDLE surf) override; - HWND GetRenderWindow () const { return hRenderWnd; } CD3DFramework9 * GetFramework() const { return pFramework; } Scene * GetScene() const { return scene; } MeshManager * GetMeshMgr() const { return meshmgr; } @@ -1071,7 +1054,7 @@ class D3D9Client : public GraphicsClient bool IsGenericProcEnabled(DWORD id) const; void SetScenarioName(const std::string &path) { scenarioName = path; }; void HackFriendlyHack(); - void PickTerrain(DWORD uMsg, int xpos, int ypos); + void PickTerrain(Uint32 uMsg, int xpos, int ypos); DEVMESHHANDLE GetDevMesh(MESHHANDLE hMesh); HANDLE GetMainThread() const { return hMainThread; } @@ -1119,7 +1102,7 @@ class D3D9Client : public GraphicsClient * \note Derived classes should perform any required per-session * initialisation of the 3D render environment here. */ - HWND clbkCreateRenderWindow (); + std::shared_ptr clbkCreateRenderWindow () override; /** * \brief Simulation startup finalisation @@ -1316,7 +1299,7 @@ class D3D9Client : public GraphicsClient const char * pCustomSplashScreen; DWORD pSplashTextColor; - HWND hRenderWnd; // render window handle + std::shared_ptr hRenderWnd; // render window handle bool bControlPanel; bool bScatterUpdate; diff --git a/OVP/D3D9Client/D3D9Config.h b/OVP/D3D9Client/D3D9Config.h index 8f10ce7f2..c64885c20 100644 --- a/OVP/D3D9Client/D3D9Config.h +++ b/OVP/D3D9Client/D3D9Config.h @@ -54,7 +54,7 @@ class D3D9Config { double Separation; ///< StereoScopic 3D depth of field separation \[m\] (10.0...100.0, default=65) double SunAngle; ///< Sun-angle above horizon when night-lights set it \[deg\] (0.1...20.0, default=10) double BumpAmp; ///< Bump map amplification setting (0.1...10.0, default=1) - float PlanetGlow; ///< Intensity of planet glow effect (0.01...2.0, default=0.7) + double PlanetGlow; ///< Intensity of planet glow effect (0.01...2.0, default=0.7) double FrameRate; ///< Frame-rate limiter double OrbitalShadowMult; ///< Multiplier for cloud shadows for Orbital flight int EnableLimiter; ///< Enable frame-rate limiter @@ -97,16 +97,16 @@ class D3D9Config { int bLocalGlares; int bIrradiance; int bAtmoQuality; - int NoPlanetAA; ///< Disable planet surface anti-aliasing to prevent white pixels at horizon + int NoPlanetAA; ///< Disable planet surface anti-aliasing to prevent white pixels at horizon char *DebugFont; ///< Font face for debug lines (default="Fixed") char *SolCfg; ///< Solar system to use (default="Sol") - float GFXIntensity; ///< Post Processing | Light glow intensity (0.0...1.0, default=0.5) - float GFXDistance; ///< Post Processing | Light glow distance (0.0...1.0, default=0.8) - float GFXThreshold; ///< Post Processing | Glow threshold (0.5...2.0, default=1.1) - float GFXGamma; ///< Post Processing | Gamma (0.3...2.5, default=1.0) - float GFXSunIntensity; ///< Light Configuration| Sunlight Intensity (0.5...2.5, default=1.2) - float GFXLocalMax; ///< Light Configuration| Local Lights Max (0.001...1.0, default=0.5) - float GFXGlare; ///< Sun glare intensity| (0.001...1.0, default=0.5) + double GFXIntensity; ///< Post Processing | Light glow intensity (0.0...1.0, default=0.5) + double GFXDistance; ///< Post Processing | Light glow distance (0.0...1.0, default=0.8) + double GFXThreshold; ///< Post Processing | Glow threshold (0.5...2.0, default=1.1) + double GFXGamma; ///< Post Processing | Gamma (0.3...2.5, default=1.0) + double GFXSunIntensity; ///< Light Configuration| Sunlight Intensity (0.5...2.5, default=1.2) + double GFXLocalMax; ///< Light Configuration| Local Lights Max (0.001...1.0, default=0.5) + double GFXGlare; ///< Sun glare intensity| (0.001...1.0, default=0.5) std::map AtmoCfg; diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 828323d06..0a3b98eae 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -32,7 +32,7 @@ extern D3D9Client *g_client; // Little binary helper #define SETFLAG(bitmap, bit, value) (value ? bitmap |= bit : bitmap &= ~bit) -#define CLAMP(x,a,b) min(max(a,x),b) +#define CLAMP(x,a,b) min(max(a,x),b) namespace DebugControls { @@ -70,20 +70,27 @@ class GFXDialog: public ImGuiDialog ImGui::PushItemWidth(150.0); ImGui::SeparatorText("Post Processing Configuration"); - - ImGui::SliderFloatReset("Light glow intensity", &Config->GFXIntensity, 0.0f, 1.0f, 0.5f, "%1.2f"); - ImGui::SliderFloatReset("Light glow distance", &Config->GFXDistance, 0.0f, 1.0f, 0.8f, "%1.2f"); - ImGui::SliderFloatReset("Glow threshold", &Config->GFXThreshold, 0.5f, 2.0f, 1.1f, "%1.2f"); - ImGui::SliderFloatReset("Gamma", &Config->GFXGamma, 0.3f, 2.5f, 1.0f, "%1.2f"); + auto min = 0.0; auto max = 1.0; auto def = 0.5; + ImGui::SliderScalarReset("Light glow intensity", ImGuiDataType_Double, sizeof(double), &Config->GFXIntensity, &min, &max, &def, "%1.2f"); + min = 0.0; max = 1.0; def = 0.8; + ImGui::SliderScalarReset("Light glow distance", ImGuiDataType_Double, sizeof(double), &Config->GFXDistance, &min, &max, &def, "%1.2f"); + min = 0.5; max = 2.0; def = 1.1; + ImGui::SliderScalarReset("Glow threshold", ImGuiDataType_Double, sizeof(double), &Config->GFXThreshold, &min, &max, &def, "%1.2f"); + min = 0.3; max = 2.5; def = 1.0; + ImGui::SliderScalarReset("Gamma", ImGuiDataType_Double, sizeof(double), &Config->GFXGamma, &min, &max, &def, "%1.2f"); ImGui::SeparatorText("Light Configuration"); - ImGui::SliderFloatReset("Sunlight Intensity", &Config->GFXSunIntensity, 0.5f, 2.5f, 1.2f, "%1.2f"); - ImGui::SliderFloatReset("Indirect Lighting", &Config->PlanetGlow, 0.01f, 2.0f, 0.7f, "%1.2f"); - ImGui::SliderFloatReset("Local Lights Max", &Config->GFXLocalMax, 0.001f, 1.0f, 0.5f, "%1.2f"); - ImGui::SliderFloatReset("Sun Glare Intensity", &Config->GFXGlare, 0.001f, 1.0f, 0.5f, "%1.2f"); + min = 0.5; max = 2.5; def = 1.2; + ImGui::SliderScalarReset("Sunlight Intensity", ImGuiDataType_Double, sizeof(double), &Config->GFXSunIntensity, &min, &max, &def, "%1.2f"); + min = 0.01; max = 2.0; def = 0.7; + ImGui::SliderScalarReset("Indirect Lighting", ImGuiDataType_Double, sizeof(double), &Config->PlanetGlow, &min, &max, &def, "%1.2f"); + min = 0.001; max = 1.0; def = 0.5; + ImGui::SliderScalarReset("Local Lights Max", ImGuiDataType_Double, sizeof(double), &Config->GFXLocalMax, &min, &max, &def, "%1.2f"); + min = 0.001; max = 1.0; def = 0.5; + ImGui::SliderScalarReset("Sun Glare Intensity", ImGuiDataType_Double, sizeof(double), &Config->GFXGlare, &min, &max, &def, "%1.2f"); - if(ImGui::Button("Recrete Sun/Glares")) { + if(ImGui::Button("Recreate Sun/Glares")) { g_client->GetScene()->CreateSunGlare(); } ImGui::PopItemWidth(); @@ -139,7 +146,7 @@ const void *GetConfigParam (DWORD paramtype) float GetFloatFromBox(HWND hWnd, int item) { char lbl[32]; - GetWindowTextA(GetDlgItem(hWnd, item), lbl, 32); + GetWindowTextA(GetDlgItem(hWnd, item), lbl, 32); return float(atof(lbl)); } @@ -148,14 +155,14 @@ float GetFloatFromBox(HWND hWnd, int item) HWND CreateToolTip(int toolID, HWND hDlg, PTSTR pszText) { if (!toolID || !hDlg || !pszText) return NULL; - + // Get the window of the tool. HWND hwndTool = GetDlgItem(hDlg, toolID); // Create the tooltip. g_hInst is the global instance handle. HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL, WS_POPUP |TTS_ALWAYSTIP | TTS_BALLOON, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hDlg, NULL, g_hInst, NULL); - + if (!hwndTool || !hwndTip) return NULL; - + // Associate the tooltip with the tool. TOOLINFO toolInfo = { 0 }; toolInfo.cbSize = sizeof(toolInfo); @@ -211,7 +218,7 @@ void Create() dwGFX = oapiRegisterCustomCmd((char*)"D3D9 Graphics Controls", (char*)"This dialog allows to control various graphics options", OpenGFXDlgClbk, gfxDlg); resbias = 4.0 + Config->LODBias; - + memset(&OpenTex, 0, sizeof(OPENFILENAME)); memset(OpenFileName, 0, sizeof(OpenFileName)); @@ -373,13 +380,13 @@ void InitMatList(WORD shader) { LRESULT idx = SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0); SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_RESETCONTENT, 0, 0); - + Dropdown.clear(); if (shader == SHADER_NULL) { std::list list = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17 }; for (auto x : list) Dropdown.push_back(PrmList[x]); - for (auto x : Dropdown) SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_ADDSTRING, 0, (LPARAM)x.name.c_str()); + for (auto x : Dropdown) SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_ADDSTRING, 0, (LPARAM)x.name.c_str()); } if (shader == SHADER_METALNESS) { @@ -501,7 +508,7 @@ void OpenDlgClbk(void *context) SendDlgItemMessage(hDlg, IDC_DBG_MATADJ, TBM_SETRANGEMIN, 1, 0); SendDlgItemMessage(hDlg, IDC_DBG_MATADJ, TBM_SETTICFREQ, 1, 0); SendDlgItemMessage(hDlg, IDC_DBG_MATADJ, TBM_SETPOS, 1, 0); - + // Set the "pick" checked SendDlgItemMessage(hDlg, IDC_DBG_PICK, BM_SETCHECK, 1, 0); @@ -566,7 +573,7 @@ void OpenDlgClbk(void *context) Params[6].var[0] = DefVar(0.5f, 2, LIN, "Angle dependency"); Params[6].var[1] = DefVar(0, 1, LIN, "Maximum intensity"); Params[6].var[2] = DefVar(10.0f, 4096.0f, SQRT, "Specular lobe size"); - + // Emission2 Params[7].var[0] = DefVar(0, 2, LIN, "Red"); Params[7].var[1] = DefVar(0, 2, LIN, "Green"); @@ -577,10 +584,10 @@ void OpenDlgClbk(void *context) // SpecialFX Params[9].var[0] = DefVar(0, 1, LIN, "Part Temperature"); - + // Unused index 10 - + // Tuning ------------------------------------------------------------------------------------- // Albedo int i = 11; @@ -622,10 +629,10 @@ void SetTuningValue(int idx, D3DCOLORVALUE *pClr, DWORD clr, float value) case 0: pClr->r = CLAMP(value, mi, mx); break; case 1: pClr->g = CLAMP(value, mi, mx); break; case 2: pClr->b = CLAMP(value, mi, mx); break; - case 3: + case 3: { - if (Params[idx].var[clr].bGamma) pClr->a = 1.0f / CLAMP(value, mi, mx); - else pClr->a = CLAMP(value, mi, mx); + if (Params[idx].var[clr].bGamma) pClr->a = 1.0f / CLAMP(value, mi, mx); + else pClr->a = CLAMP(value, mi, mx); } break; } } @@ -638,7 +645,7 @@ float GetTuningValue(int idx, D3DCOLORVALUE *pClr, DWORD clr) case 0: return pClr->r; case 1: return pClr->g; case 2: return pClr->b; - case 3: + case 3: { if (Params[idx].var[clr].bGamma) return 1.0f / pClr->a; else return pClr->a; @@ -671,7 +678,7 @@ void UpdateShader() vVessel *vVes = (vVessel *)vObj; MatMgr *pMgr = vVes->GetMaterialManager(); - + switch (Shader) { case 0: hMesh->SetDefaultShader(SHADER_NULL); @@ -697,7 +704,7 @@ void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); if (!hMesh) return; - + DWORD matidx = hMesh->GetMeshGroupMaterialIdx(sGroup); DWORD texidx = hMesh->GetMeshGroupTextureIdx(sGroup); @@ -827,7 +834,7 @@ void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) hMesh->SetMaterial(&Mat, matidx); vVessel *vVes = (vVessel *)vObj; - vVes->GetMaterialManager()->RegisterMaterialChange(hMesh, matidx, &Mat); + vVes->GetMaterialManager()->RegisterMaterialChange(hMesh, matidx, &Mat); } @@ -864,7 +871,7 @@ bool IsMaterialModified(DWORD MatPrp) if (!hMesh) return false; DWORD matidx = hMesh->GetMeshGroupMaterialIdx(sGroup); - + D3D9MatExt Mat; if (!hMesh->GetMaterial(&Mat, matidx)) return false; @@ -914,7 +921,7 @@ float GetMaterialValue(DWORD MatPrp, DWORD clr) DWORD texidx = hMesh->GetMeshGroupTextureIdx(sGroup); const D3D9MatExt *pMat = hMesh->GetMaterial(matidx); - + if (!pMat) return 0.0f; D3D9Tune Tune; @@ -1088,7 +1095,7 @@ void DisplayMat(bool bRed, bool bGreen, bool bBlue, bool bAlpha) char lbl[32]; DWORD MatPrp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); - + float r = GetMaterialValue(MatPrp, 0); float g = GetMaterialValue(MatPrp, 1); float b = GetMaterialValue(MatPrp, 2); @@ -1097,7 +1104,7 @@ void DisplayMat(bool bRed, bool bGreen, bool bBlue, bool bAlpha) if (bRed) sprintf_s(lbl,32,"%3.3f", r); else sprintf_s(lbl,32,""); SetWindowText(GetDlgItem(hDlg, IDC_DBG_RED), lbl); - + if (bGreen) sprintf_s(lbl,32,"%3.3f", g); else sprintf_s(lbl,32,""); SetWindowText(GetDlgItem(hDlg, IDC_DBG_GREEN), lbl); @@ -1111,11 +1118,11 @@ void DisplayMat(bool bRed, bool bGreen, bool bBlue, bool bAlpha) SetWindowText(GetDlgItem(hDlg, IDC_DBG_ALPHA), lbl); if (bRed) EnableWindow(GetDlgItem(hDlg, IDC_DBG_RED), true); - else EnableWindow(GetDlgItem(hDlg, IDC_DBG_RED), false); + else EnableWindow(GetDlgItem(hDlg, IDC_DBG_RED), false); if (bGreen) EnableWindow(GetDlgItem(hDlg, IDC_DBG_GREEN), true); - else EnableWindow(GetDlgItem(hDlg, IDC_DBG_GREEN), false); + else EnableWindow(GetDlgItem(hDlg, IDC_DBG_GREEN), false); if (bBlue) EnableWindow(GetDlgItem(hDlg, IDC_DBG_BLUE), true); - else EnableWindow(GetDlgItem(hDlg, IDC_DBG_BLUE), false); + else EnableWindow(GetDlgItem(hDlg, IDC_DBG_BLUE), false); if (bAlpha) EnableWindow(GetDlgItem(hDlg, IDC_DBG_ALPHA), true); else EnableWindow(GetDlgItem(hDlg, IDC_DBG_ALPHA), false); @@ -1133,7 +1140,7 @@ void UpdateMaterialDisplay(bool bSetup) OBJHANDLE hObj = vObj->GetObjectA(); if (!oapiIsVessel(hObj)) return; - + D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); if (!hMesh) return; @@ -1154,7 +1161,7 @@ void UpdateMaterialDisplay(bool bSetup) if (bSetup) SelColor = 0; DWORD MatPrp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); - + DisplayMat(Params[MatPrp].var[0].bUsed, Params[MatPrp].var[1].bUsed, Params[MatPrp].var[2].bUsed, Params[MatPrp].var[3].bUsed); SetToolTip(IDC_DBG_RED, hTipRed, Params[MatPrp].var[0].tip); @@ -1175,7 +1182,7 @@ void UpdateMaterialDisplay(bool bSetup) sprintf_s(lbl, 256, "Mesh: %s", RemovePath(hMesh->GetName())); SetWindowText(GetDlgItem(hDlg, IDC_DBG_MESHNAME), lbl); - + GetWindowText(GetDlgItem(hDlg, IDC_DBG_MESHGRP), lbl2, 64); if (strcmp(lbl, lbl2)) SetWindowText(GetDlgItem(hDlg, IDC_DBG_MESHGRP), lbl); // Avoid causing flashing } @@ -1195,8 +1202,8 @@ bool IsSelectedGroupRendered() void UpdateColorSlider(WORD pos) { float val = float(pos)/255.0f; - - DWORD MatPrp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); + + DWORD MatPrp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); bool bLink = (SendDlgItemMessageA(hDlg, IDC_DBG_LINK, BM_GETCHECK, 0, 0)==BST_CHECKED); bool bExtend = (SendDlgItemMessageA(hDlg, IDC_DBG_EXTEND, BM_GETCHECK, 0, 0) == BST_CHECKED); @@ -1214,7 +1221,7 @@ void UpdateColorSlider(WORD pos) float old = GetMaterialValue(MatPrp, SelColor); float fct = val/old; - + if (old<1e-4) fct = val; if (bLink) { @@ -1272,7 +1279,7 @@ void SetupMeshGroups() { char lbl[256]; - if (!vObj) return; + if (!vObj) return; SetWindowText(GetDlgItem(hDlg, IDC_DBG_VISUAL), visual); @@ -1347,7 +1354,7 @@ void SetVisual(vObject *vo) // void UpdateVisual() { - if (!vObj || !hDlg) return; + if (!vObj || !hDlg) return; nMesh = vObj->GetMeshCount(); sprintf_s(visual, 64, "Visual: %s", vObj->GetName()); SetupMeshGroups(); @@ -1369,14 +1376,14 @@ void UpdateVisual() for (DWORD j = 0; j < nemitter; j++) { const LightEmitter *em = vessel->GetLightEmitter(j); - + if (em->GetType() == LightEmitter::LT_SPOT) { const SpotLight *sl = static_cast(em); double P = sl->GetPenumbra()*DEG; double U = sl->GetUmbra()*DEG; double R = sl->GetRange(); sprintf_s(line, 64, "%s P%1.0f U%1.0f R%1.0f", _PTR(em), P, U, R); - } + } if (em->GetType() == LightEmitter::LT_POINT) { const PointLight *pl = static_cast(em); @@ -1443,12 +1450,12 @@ D3DXCOLOR ProcessColor(D3DXVECTOR4 C, PCParam *prm, int x, int y) // Swap color channels C = D3DXVECTOR4(C.z, C.y, C.z, C.x); - + if (c>0.001) { D3DXVECTOR4 rnd((float)oapiRand(),(float)oapiRand(), (float)oapiRand(), (float)oapiRand()); C += (rnd*2.0f-1.0f) * (c/(2.0f+fMip)); } - + // Reduce contrast if (prm->Func & 0x2) { @@ -1484,7 +1491,7 @@ bool Execute(HWND hWnd, LPOPENFILENAME pOF) if (SendDlgItemMessageA(hDlg, IDC_DBG_NORM, BM_GETCHECK, 0, 0)==BST_CHECKED) Func |= 0x1; if (SendDlgItemMessageA(hDlg, IDC_DBG_FADE, BM_GETCHECK, 0, 0)==BST_CHECKED) Func |= 0x2; if (SendDlgItemMessageA(hDlg, IDC_DBG_SEAMS, BM_GETCHECK, 0, 0)==BST_CHECKED) Func |= 0x4; - + if (Action>=0 && Action<=2) { LPDIRECT3DTEXTURE9 pTex = NULL; @@ -1495,7 +1502,7 @@ bool Execute(HWND hWnd, LPOPENFILENAME pOF) HR(D3DXCreateTextureFromFileExA(pDevice, pOF->lpstrFile, D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT, D3DX_DEFAULT, 0, &info, NULL, &pTex)); if (!pTex) { - LogErr("Failed to open a file [%s]", pOF->lpstrFile); + LogErr("Failed to open a file [%s]", pOF->lpstrFile); return false; } @@ -1512,7 +1519,7 @@ bool Execute(HWND hWnd, LPOPENFILENAME pOF) if (!pSave) return false; - + // Process texture ---------------------------------------------- // for (DWORD n=0;n>n; DWORD h = info.Height>>n; - HR(pTex->LockRect(n, &in, NULL, 0)); + HR(pTex->LockRect(n, &in, NULL, 0)); HR(pWork->LockRect(n, &out, NULL, 0)); DWORD *pIn = (DWORD *)in.pBits; DWORD *pOut = (DWORD *)out.pBits; @@ -1532,14 +1539,14 @@ bool Execute(HWND hWnd, LPOPENFILENAME pOF) prm.a = GetFloatFromBox(hDlg, IDC_DBG_VARA); prm.b = GetFloatFromBox(hDlg, IDC_DBG_VARB); prm.c = GetFloatFromBox(hDlg, IDC_DBG_VARC); - + for (DWORD y=0;yGetScene()->GetCameraProxyVisual(); + vPlanet *vP = g_client->GetScene()->GetCameraProxyVisual(); if (vP) vP->SetMicroTexture(pSave, Target-1); SAFE_RELEASE(pSave); return true; @@ -1619,7 +1626,7 @@ bool Execute(HWND hWnd, LPOPENFILENAME pOF) return false; } - + // ============================================================================================= // @@ -1692,13 +1699,13 @@ void CreateSamplingKernel() { int s = 27; int k = 0; - + VECTOR3 *data = new VECTOR3[s]; - + double d = 0.0; double a = 0.0; - - for (int i = 0; i < s; i++) { + + for (int i = 0; i < s; i++) { double z = (oapiRand()*2.0 - 1.0) * (PI2 / 8); data[i].x = sqrt(d) * sin(a+z); data[i].y = sqrt(d) * cos(a+z); @@ -1765,7 +1772,7 @@ INT_PTR CALLBACK ViewProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) static bool isOpen = false; // IDC_DBG_MORE (full or reduced width) DWORD Prp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); - + switch (uMsg) { case WM_INITDIALOG: @@ -1805,7 +1812,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) OpenTex.hwndOwner = hWnd; DWORD Prp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); - + switch (uMsg) { case WM_INITDIALOG: @@ -1821,7 +1828,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (HWND(lParam)==GetDlgItem(hWnd, IDC_DBG_SPEED)) { if (pos==0) pos = WORD(SendDlgItemMessage(hDlg, IDC_DBG_SPEED, TBM_GETPOS, 0, 0)); - double fpos = pow(2.0,double(pos)*13.0/200.0); + double fpos = pow(2.0,double(pos)*13.0/200.0); sprintf_s(lbl,32,"%1.0f",fpos); SetWindowTextA(GetDlgItem(hWnd, IDC_DBG_SPEEDDSP), lbl); camSpeed = fpos/50.0; @@ -1847,7 +1854,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDCANCEL: Close(); break; - + case IDC_DBG_KERNEL: { CreateSamplingKernel(); @@ -1947,7 +1954,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_MATPRP: if (HIWORD(wParam)==CBN_SELCHANGE) { UpdateMaterialDisplay(true); - SetColorSlider(); + SetColorSlider(); } break; @@ -1971,38 +1978,38 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (HIWORD(wParam)==CBN_SELCHANGE) camMode = DWORD(SendDlgItemMessage(hWnd, IDC_DBG_CAMERA, CB_GETCURSEL, 0, 0)); break; - case IDC_DBG_MSHUP: + case IDC_DBG_MSHUP: if (HIWORD(wParam)==BN_CLICKED) sMesh--; SetupMeshGroups(); break; - case IDC_DBG_MSHDN: + case IDC_DBG_MSHDN: if (HIWORD(wParam)==BN_CLICKED) sMesh++; SetupMeshGroups(); break; - case IDC_DBG_GRPUP: + case IDC_DBG_GRPUP: if (HIWORD(wParam)==BN_CLICKED) sGroup--; SetupMeshGroups(); break; - case IDC_DBG_GRPDN: - if (HIWORD(wParam)==BN_CLICKED) sGroup++; + case IDC_DBG_GRPDN: + if (HIWORD(wParam)==BN_CLICKED) sGroup++; SetupMeshGroups(); break; - - case IDC_DBG_MESH: + + case IDC_DBG_MESH: if (HIWORD(wParam)==EN_KILLFOCUS) { char cbuf[32]; - GetWindowText(GetDlgItem(hWnd, IDC_DBG_MESH), cbuf, 32); + GetWindowText(GetDlgItem(hWnd, IDC_DBG_MESH), cbuf, 32); for (int i=0; i<32;i++) if (cbuf[i]==0 || cbuf[i]=='/') { cbuf[i]=0; break; } sMesh = atoi(cbuf); SetupMeshGroups(); } break; - case IDC_DBG_GROUP: + case IDC_DBG_GROUP: if (HIWORD(wParam)==EN_KILLFOCUS) { char cbuf[32]; GetWindowText(GetDlgItem(hWnd, IDC_DBG_GROUP), cbuf, 32); @@ -2079,8 +2086,8 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_VARC: case IDC_DBG_FILE: break; - - default: + + default: LogErr("LOWORD(%hu), HIWORD(0x%hX)",LOWORD(wParam),HIWORD(wParam)); break; } diff --git a/OVP/D3D9Client/Log.cpp b/OVP/D3D9Client/Log.cpp index 2a8a9f86d..95d699640 100644 --- a/OVP/D3D9Client/Log.cpp +++ b/OVP/D3D9Client/Log.cpp @@ -75,7 +75,7 @@ void RuntimeError(const char* File, const char* Fnc, UINT Line) if (Config->DebugLvl == 0) return; char buf[256]; sprintf_s(buf, 256, "[%s] [%s] Line: %u See Orbiter.log for details.", File, Fnc, Line); - MessageBoxA(g_client->GetRenderWindow(), buf, "Critical Error:", MB_OK); + MessageBoxA(g_client->GetRenderWindow()->Win32Handle(), buf, "Critical Error:", MB_OK); DebugBreak(); } diff --git a/OVP/D3D9Client/WindowMgr.cpp b/OVP/D3D9Client/WindowMgr.cpp index 1d86a8fc3..87e562568 100644 --- a/OVP/D3D9Client/WindowMgr.cpp +++ b/OVP/D3D9Client/WindowMgr.cpp @@ -60,7 +60,7 @@ inline DWORD _Colour(const FVECTOR4 *c) if (r > 0xFF) r = 0xFF; if (g > 0xFF) g = 0xFF; if (b > 0xFF) b = 0xFF; - + return (b << 16) | (g << 8) | r; } // =============================================================================================== @@ -192,9 +192,9 @@ Node::Node(SideBar *pSB, const char *label, HWND hDlg, DWORD color, Node *pP) : HDC hSrc = CreateCompatibleDC(hDC); HDC hTgt = CreateCompatibleDC(hDC); - + GetObject(hTit, sizeof(BITMAP), &bm); - + hBmp = CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); pSB->ReleaseDC(hDC); @@ -205,11 +205,11 @@ Node::Node(SideBar *pSB, const char *label, HWND hDlg, DWORD color, Node *pP) : // Recolorize the title bar for (int y = 0; y < bm.bmHeight; y++) { - for (int x = 0; x < bm.bmWidth; x++) { + for (int x = 0; x < bm.bmWidth; x++) { COLORREF cr = GetPixel(hSrc, x, y); FVECTOR4 c = _Colour(cr); FVECTOR4 out = (clr * c.b) + (white * c.g); - SetPixel(hTgt, x, y, _Colour(&out)); + SetPixel(hTgt, x, y, _Colour(&out)); } } @@ -307,8 +307,8 @@ int Node::Paint(HDC hDC, int y) int wof = 0, hof = 0; DWORD ck = 0; - if (pSB->GetStyle() == gcGUI::DS_FLOAT) x += 1; - + if (pSB->GetStyle() == gcGUI::DS_FLOAT) x += 1; + if (hBmp) { if (pParent) { SelectObject(hDC, pMgr->GetSubTitleFont()); @@ -324,11 +324,11 @@ int Node::Paint(HDC hDC, int y) } } - + // Draw Title Bars ----------------------------- // if (hBmp) { - + HDC hSr = CreateCompatibleDC(hDC); int z = width - bm.bmHeight - 3; @@ -337,20 +337,20 @@ int Node::Paint(HDC hDC, int y) SelectObject(hSr, hBmp); BitBlt(hDC, x, y, width - 10, bm.bmHeight, hSr, 0, 0, SRCCOPY); - BitBlt(hDC, width - 10 - x, y, 10, bm.bmHeight, hSr, bm.bmWidth - 10, 0, SRCCOPY); + BitBlt(hDC, width - 10 - x, y, 10, bm.bmHeight, hSr, bm.bmWidth - 10, 0, SRCCOPY); TextOut(hDC, wof, y + hof, Label, lstrlen(Label)); - + DeleteDC(hSr); if (bOpen) PaintIcon(hDC, x, y, 0); else PaintIcon(hDC, x, y, 1); if (bClose) PaintIcon(hDC, z, y, 2); - + y += bm.bmHeight; } pos = { x, y }; - + if (bOpen && hDlg) { RECT r; GetWindowRect(hDlg, &r); @@ -366,9 +366,9 @@ int Node::Paint(HDC hDC, int y) void Node::PaintIcon(HDC hDC, int x, int y, int id) { WindowManager *pMgr = pSB->GetWM(); - DWORD yell = RGB(255, 255, 0); - DWORD mang = RGB(255, 0, 255); - + DWORD yell = RGB(255, 255, 0); + DWORD mang = RGB(255, 0, 255); + HBITMAP hIco = pMgr->GetBitmap(gcGUI::BM_ICONS); if (hIco) { @@ -402,11 +402,11 @@ int Node::Spacer(HDC hDC, int y) int width = pSB->GetWidth(); int h = CellSize(); - + SelectObject(hDC, (HBRUSH)GetStockObject(GRAY_BRUSH)); SelectObject(hDC, (HPEN)GetStockObject(NULL_PEN)); Rectangle(hDC, 0, y, width + 1, y + h + 1); - + return y + h; } @@ -541,7 +541,7 @@ WindowManager::WindowManager(HWND hAppMainWindow, HINSTANCE _hInst, bool bWindow DWORD flags = 0; if (Config->gcGUIMode == 1) flags |= CS_NOCLOSE; - WNDCLASS wc; + WNDCLASS wc; memset(&wc, 0, sizeof(WNDCLASS)); wc.style = flags | CS_OWNDC | CS_SAVEBITS; wc.lpfnWndProc = SideBarWndProc; @@ -572,7 +572,7 @@ WindowManager::WindowManager(HWND hAppMainWindow, HINSTANCE _hInst, bool bWindow hAppFont = CreateFont(cfg.txt_main_size, 0, 0, 0, cfg.txt_main_weight, false, false, 0, 0, 0, 2, CLEARTYPE_QUALITY, 49, cfg.fnt_main); hSubFont = CreateFont(cfg.txt_sub_size, 0, 0, 0, cfg.txt_sub_weight, false, false, 0, 0, 0, 2, CLEARTYPE_QUALITY, 49, cfg.fnt_sub); - + if (!hAppFont) LogErr("Font Not Found [%s]", cfg.fnt_main); if (!hSubFont) LogErr("Font Not Found [%s]", cfg.fnt_sub); @@ -611,7 +611,7 @@ WindowManager::~WindowManager() oapiUnregisterCustomCmd(Cmd); for(SideBar* sb : sbList) delete sb; - + UnregisterClass("SideBarWnd", hInst); UnregisterClass("Floater", hInst); @@ -675,7 +675,7 @@ HNODE WindowManager::RegisterApplication(gcGUIApp *pPtr, const char *label, HWND if (Config->gcGUIMode >= 2) docked = gcGUI::DS_FLOAT; if (docked == gcGUI::DS_FLOAT) pSB = NewSideBar(NULL); - + if (Config->gcGUIMode == 3) { HWND hWnd = pSB->GetHWND(); SetWindowText(hWnd, label); @@ -946,11 +946,11 @@ SideBar* WindowManager::StartDrag(Node *pAN, int x, int y) for (Node * an : pSBOld->wList) if (an->pParent == pAN) tmp.push_back(an); - for (Node * an : tmp) + for (Node * an : tmp) { - pSBOld->RemoveWindow(an); // Cant remove directly from a list being browsed + pSBOld->RemoveWindow(an); // Cant remove directly from a list being browsed pSBNew->AddWindow(an); - } + } } sbDrag = pSBNew; @@ -959,7 +959,7 @@ SideBar* WindowManager::StartDrag(Node *pAN, int x, int y) y -= ptOffset.y; pSBNew->ResetWindow(x, y); - + InvalidateRect(pSBNew->GetHWND(), NULL, true); InvalidateRect(pSBOld->GetHWND(), NULL, true); @@ -989,7 +989,7 @@ void WindowManager::Drag(int x, int y) x -= ptOffset.x; y -= ptOffset.y; - RECT rect; + RECT rect; SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0); int t = sbDrag->GetTopNode()->bm.bmHeight; @@ -1043,7 +1043,7 @@ SideBar *WindowManager::FindDestination() if (a > z) { z = a; sbDest = sb; } } } - + if (sbDest != pOld && pOld != NULL) { qInsert.pTgt = NULL; qInsert.List.clear(); @@ -1059,33 +1059,16 @@ SideBar *WindowManager::FindDestination() // =============================================================================================== // Orbiter Application Main Window Proc // -bool WindowManager::MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +bool WindowManager::MainWindowProc(const SDL_Event &event) { static int xpos, ypos; - switch (uMsg) { - - case WM_MOUSELEAVE: - case WM_MBUTTONDOWN: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - return false; - - case WM_KEYDOWN: - { - return false; - } - - case WM_MOUSEWHEEL: - return false; - - case WM_MOUSEMOVE: - xpos = GET_X_LPARAM(lParam); - ypos = GET_Y_LPARAM(lParam); - MouseMoved(xpos, ypos); - break; - } - - return false; + if (event.type == SDL_EVENT_MOUSE_MOTION) { + xpos = event.motion.x; + ypos = event.motion.y; + MouseMoved(xpos, ypos); + return true; + } + return false; } @@ -1102,7 +1085,7 @@ bool WindowManager::MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l SideBar::SideBar(class WindowManager *_pMgr, DWORD _state) { pMgr = _pMgr; - + HWND hMainWnd = pMgr->GetMainWindow(); hInst = pMgr->GetInstance(); width = pMgr->GetWidth(); @@ -1130,7 +1113,7 @@ SideBar::SideBar(class WindowManager *_pMgr, DWORD _state) DWORD exstyle = 0; DWORD style = 0; - if (Config->gcGUIMode == 1) { + if (Config->gcGUIMode == 1) { if (state == gcGUI::DS_RIGHT) xref = r.right; if (state == gcGUI::DS_LEFT) xref = -width; if (state == gcGUI::DS_FLOAT) xref = width, height = width; @@ -1174,7 +1157,7 @@ SideBar::SideBar(class WindowManager *_pMgr, DWORD _state) // =============================================================================================== // SideBar::~SideBar() -{ +{ for (Node *v : wList) { if (v->hDlg) DestroyWindow(v->hDlg); @@ -1371,8 +1354,8 @@ void SideBar::GetVisualList(vector &tmp) { if (Config->gcGUIMode == 3) { for (Node* ap : wList) if (ap->hDlg) tmp.push_back(ap); - } - else + } + else { for (Node* ap : wList) { Node* pPar = ap->pParent; @@ -1477,7 +1460,7 @@ bool SideBar::TryInsert(SideBar *sbIn) tInsert *pIns = pMgr->InsertList(); if (pIns->pTgt != this) return false; - + map &wIns = pIns->List; map wPrev = wIns; @@ -1486,7 +1469,7 @@ bool SideBar::TryInsert(SideBar *sbIn) int yp = sbIn->GetRect().top - GetRect().top; int h = sbIn->ComputeLength(); int y = rollpos; - + Node *pNode = sbIn->GetTopNode(); if (!pNode) return false; @@ -1509,7 +1492,7 @@ bool SideBar::Apply() SideBar *pDG = pMgr->GetDraged(); tInsert *pIns = pMgr->InsertList(); - if ((pIns->pTgt == this) && (pIns->List.size()>0)) + if ((pIns->pTgt == this) && (pIns->List.size()>0)) { for (auto &var : pIns->List) { @@ -1541,189 +1524,189 @@ LRESULT SideBar::SideBarWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar static int xof, yof; static bool bUpdate = false; - HWND hMain = pMgr->GetMainWindow(); - - switch(uMsg) { - - case WM_KEYDOWN: - { - pMgr->MainWindowProc(hWnd, uMsg, wParam, lParam); - break; - } - - - case WM_MOUSEWHEEL: - { - if (GetStyle() == gcGUI::DS_FLOAT) break; - - int old = rollpos; - short d = GET_WHEEL_DELTA_WPARAM(wParam); - if (d>0) rollpos += pMgr->cfg.scroll; - else rollpos -= pMgr->cfg.scroll; - int q = height - wndlen; - if (q > 0) q = 0; - if (rollpos > 0) rollpos = 0; - if (rollpos < q) rollpos = q; - if (old != rollpos) Invalidate(); - break; - } - - case WM_LBUTTONDOWN: - { - xpos = GET_X_LPARAM(lParam); - ypos = GET_Y_LPARAM(lParam); - - for (Node* nd : wList) - { - Node *pPar = nd->pParent; - - if (pPar) { - if (pPar->GetSideBar() == this) { - if (pPar->bOpen == false) continue; - } - } - - if (PointInside(xpos, ypos, &(nd->trect))) { - - if (nd->bClose && PointInside(xpos, ypos, &(nd->crect))) { - dnClose = nd; - } - else { - xof = xpos - nd->trect.left; - yof = ypos - nd->trect.top; - dnNode = nd; - } - TRACKMOUSEEVENT te; te.cbSize = sizeof(TRACKMOUSEEVENT); te.dwFlags = TME_LEAVE; te.hwndTrack = hBar; - TrackMouseEvent(&te); - break; // break for - } - } - break; - } - - case WM_LBUTTONUP: - { - int xp = GET_X_LPARAM(lParam); - int yp = GET_Y_LPARAM(lParam); - - SideBar *pDG = pMgr->GetDraged(); - - if (pDG) { - SideBar *pTgt = pMgr->FindDestination(); - if (pTgt) pTgt->Apply(); - pMgr->EndDrag(); - ReleaseCapture(); - dnNode = NULL; - dnClose = NULL; - break; - } - - if (dnNode) { - if (dnNode->GetSideBar() == this) { - if (PointInside(xp, yp, &(dnNode->trect))) { - dnNode->bOpen = !dnNode->bOpen; - if (IsFloater()) RescaleWindow(); - Invalidate(); - DWORD msg = (dnNode->bOpen ? gcGUI::MSG_OPEN_NODE : gcGUI::MSG_CLOSE_NODE); - dnNode->pApp->clbkMessage(msg, dnNode, 0); - } - } - } - - if (dnClose) { - if (dnClose->GetSideBar() == this) { - if (PointInside(xp, yp, &(dnClose->crect))) { - if (dnClose->pApp->clbkMessage(gcGUI::MSG_CLOSE_APP, NULL, 0)) - { - pMgr->CloseWindow(dnClose); - } - } - } - } - - dnNode = NULL; - dnClose = NULL; - break; - } - - - case WM_MOUSELEAVE: - { - dnNode = NULL; - dnClose = NULL; - break; - } - - - case WM_MOUSEMOVE: - { - int dx = abs(GET_X_LPARAM(lParam) - xpos); - int dy = abs(GET_Y_LPARAM(lParam) - ypos); - int x = GET_X_LPARAM(lParam); - int y = GET_Y_LPARAM(lParam); - - if (Config->gcGUIMode < 3) { - - POINT scp = { x, y }; - ClientToScreen(hWnd, &scp); - - // Begin Moving a Window - // - if (dnNode && IsFloater() && (GetTopNode() == dnNode) && (dx > 1 || dy > 1)) - { - SetCapture(hBar); - pMgr->SetOffset(xof, yof); - pMgr->BeginMove(dnNode, scp.x, scp.y); - dnNode = NULL; - dnClose = NULL; - break; - } - - // Detach a window from a dock - // - if (Config->gcGUIMode == 1) { - if (dnNode && dx > 25) { - SetCapture(hBar); - pMgr->SetOffset(xof, yof); - SideBar* pTgt = pMgr->StartDrag(dnNode, scp.x, scp.y); - dnNode = NULL; - dnClose = NULL; - break; - } - } - - // Move a dragged window and try to insert content into a dock - // - if (pMgr->GetDraged()) { - pMgr->MouseMoved(scp.x, scp.y); - pMgr->Drag(scp.x, scp.y); - SideBar *pTgt = pMgr->FindDestination(); - SideBar *pDG = pMgr->GetDraged(); - if (pTgt) if (pTgt->IsOpen()) { - if (pTgt->TryInsert(pDG)) { - if (pTgt->GetStyle() == gcGUI::DS_FLOAT) pTgt->RescaleWindow(); - pTgt->Invalidate(); - pDG->Invalidate(); - } - } - break; - } - } - break; - } - - case WM_PAINT: - PaintWindow(); - break; - - case WM_ERASEBKGND: - return 1; - - default: - break; - } - - + // HWND hMain = pMgr->GetMainWindow(); + // + // switch(uMsg) { + // + // case WM_KEYDOWN: + // { + // pMgr->MainWindowProc(hWnd, uMsg, wParam, lParam); + // break; + // } + // + // + // case WM_MOUSEWHEEL: + // { + // if (GetStyle() == gcGUI::DS_FLOAT) break; + // + // int old = rollpos; + // short d = GET_WHEEL_DELTA_WPARAM(wParam); + // if (d>0) rollpos += pMgr->cfg.scroll; + // else rollpos -= pMgr->cfg.scroll; + // int q = height - wndlen; + // if (q > 0) q = 0; + // if (rollpos > 0) rollpos = 0; + // if (rollpos < q) rollpos = q; + // if (old != rollpos) Invalidate(); + // break; + // } + // + // case WM_LBUTTONDOWN: + // { + // xpos = GET_X_LPARAM(lParam); + // ypos = GET_Y_LPARAM(lParam); + // + // for (Node* nd : wList) + // { + // Node *pPar = nd->pParent; + // + // if (pPar) { + // if (pPar->GetSideBar() == this) { + // if (pPar->bOpen == false) continue; + // } + // } + // + // if (PointInside(xpos, ypos, &(nd->trect))) { + // + // if (nd->bClose && PointInside(xpos, ypos, &(nd->crect))) { + // dnClose = nd; + // } + // else { + // xof = xpos - nd->trect.left; + // yof = ypos - nd->trect.top; + // dnNode = nd; + // } + // TRACKMOUSEEVENT te; te.cbSize = sizeof(TRACKMOUSEEVENT); te.dwFlags = TME_LEAVE; te.hwndTrack = hBar; + // TrackMouseEvent(&te); + // break; // break for + // } + // } + // break; + // } + // + // case WM_LBUTTONUP: + // { + // int xp = GET_X_LPARAM(lParam); + // int yp = GET_Y_LPARAM(lParam); + // + // SideBar *pDG = pMgr->GetDraged(); + // + // if (pDG) { + // SideBar *pTgt = pMgr->FindDestination(); + // if (pTgt) pTgt->Apply(); + // pMgr->EndDrag(); + // ReleaseCapture(); + // dnNode = NULL; + // dnClose = NULL; + // break; + // } + // + // if (dnNode) { + // if (dnNode->GetSideBar() == this) { + // if (PointInside(xp, yp, &(dnNode->trect))) { + // dnNode->bOpen = !dnNode->bOpen; + // if (IsFloater()) RescaleWindow(); + // Invalidate(); + // DWORD msg = (dnNode->bOpen ? gcGUI::MSG_OPEN_NODE : gcGUI::MSG_CLOSE_NODE); + // dnNode->pApp->clbkMessage(msg, dnNode, 0); + // } + // } + // } + // + // if (dnClose) { + // if (dnClose->GetSideBar() == this) { + // if (PointInside(xp, yp, &(dnClose->crect))) { + // if (dnClose->pApp->clbkMessage(gcGUI::MSG_CLOSE_APP, NULL, 0)) + // { + // pMgr->CloseWindow(dnClose); + // } + // } + // } + // } + // + // dnNode = NULL; + // dnClose = NULL; + // break; + // } + // + // + // case WM_MOUSELEAVE: + // { + // dnNode = NULL; + // dnClose = NULL; + // break; + // } + // + // + // case WM_MOUSEMOVE: + // { + // int dx = abs(GET_X_LPARAM(lParam) - xpos); + // int dy = abs(GET_Y_LPARAM(lParam) - ypos); + // int x = GET_X_LPARAM(lParam); + // int y = GET_Y_LPARAM(lParam); + // + // if (Config->gcGUIMode < 3) { + // + // POINT scp = { x, y }; + // ClientToScreen(hWnd, &scp); + // + // // Begin Moving a Window + // // + // if (dnNode && IsFloater() && (GetTopNode() == dnNode) && (dx > 1 || dy > 1)) + // { + // SetCapture(hBar); + // pMgr->SetOffset(xof, yof); + // pMgr->BeginMove(dnNode, scp.x, scp.y); + // dnNode = NULL; + // dnClose = NULL; + // break; + // } + // + // // Detach a window from a dock + // // + // if (Config->gcGUIMode == 1) { + // if (dnNode && dx > 25) { + // SetCapture(hBar); + // pMgr->SetOffset(xof, yof); + // SideBar* pTgt = pMgr->StartDrag(dnNode, scp.x, scp.y); + // dnNode = NULL; + // dnClose = NULL; + // break; + // } + // } + // + // // Move a dragged window and try to insert content into a dock + // // + // if (pMgr->GetDraged()) { + // pMgr->MouseMoved(scp.x, scp.y); + // pMgr->Drag(scp.x, scp.y); + // SideBar *pTgt = pMgr->FindDestination(); + // SideBar *pDG = pMgr->GetDraged(); + // if (pTgt) if (pTgt->IsOpen()) { + // if (pTgt->TryInsert(pDG)) { + // if (pTgt->GetStyle() == gcGUI::DS_FLOAT) pTgt->RescaleWindow(); + // pTgt->Invalidate(); + // pDG->Invalidate(); + // } + // } + // break; + // } + // } + // break; + // } + // + // case WM_PAINT: + // PaintWindow(); + // break; + // + // case WM_ERASEBKGND: + // return 1; + // + // default: + // break; + // } + // + // TODO TODO TODO return DefWindowProc(hWnd, uMsg, wParam, lParam); } @@ -1743,7 +1726,7 @@ int SideBar::ComputeLength() if (bInsert) for (auto &var : wIns) if (var.second == NULL) y += var.first->CellSize(); - for (Node* ap : drawList) + for (Node* ap : drawList) { y += ap->CellSize(); if (bInsert) for (auto &var : wIns) if (var.second == ap) y += var.first->CellSize(); @@ -1772,7 +1755,7 @@ void SideBar::PaintWindow() map &wIns = pIns->List; bool bInsert = (pIns->pTgt == this) && (wIns.size() > 0); - + if (bInsert) for (auto &var : wIns) { if (var.second == NULL) y = var.first->Spacer(hDC, y); @@ -1815,10 +1798,10 @@ void SideBar::PaintWindow() for (Node* ap : wList) { bool bFound = false; for (Node* q : drawList) if (q == ap) { bFound = true; break; } - + if (bFound && ap->hDlg) { if (ap->bOpen) ap->Move(); - else ShowWindow(ap->hDlg, SW_HIDE); + else ShowWindow(ap->hDlg, SW_HIDE); } else if (ap->hDlg) ShowWindow(ap->hDlg, SW_HIDE); } diff --git a/OVP/D3D9Client/WindowMgr.h b/OVP/D3D9Client/WindowMgr.h index 9f9f02f8c..0e6624d07 100644 --- a/OVP/D3D9Client/WindowMgr.h +++ b/OVP/D3D9Client/WindowMgr.h @@ -23,11 +23,13 @@ #ifndef __WNDMGR_H #define __WNDMGR_H -#include #include "gcCore.h" -#include -#include #include "gcGUI.h" +#include +#include +#include + +#include using namespace std; @@ -119,11 +121,11 @@ class SideBar Node * FindClosest(vector &vis, Node *pPar, int yval); Node * FindNode(HWND hDlg); DWORD GetAutoColor(); - + WindowManager *GetWM() const { return pMgr; } vector wList; - + private: class WindowManager *pMgr; @@ -176,7 +178,7 @@ class WindowManager : public gcGUIBase // =============================================================================================== // - bool MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + bool MainWindowProc(const SDL_Event &event); void Animate(); int GetWidth() const { return width; } HWND GetMainWindow() const { return hMainWnd; } @@ -196,7 +198,7 @@ class WindowManager : public gcGUIBase HBITMAP GetBitmap(int id) const; HFONT GetAppTitleFont() const { return hAppFont; } HFONT GetSubTitleFont() const { return hSubFont; } - + // =============================================================================================== // @@ -234,7 +236,7 @@ class WindowManager : public gcGUIBase Conf cfg; private: - + tInsert qInsert; vector sbList; SideBar * sbDrag; diff --git a/OVP/D3D9Client/gcConst.cpp b/OVP/D3D9Client/gcConst.cpp index e319f9e3c..4e7868594 100644 --- a/OVP/D3D9Client/gcConst.cpp +++ b/OVP/D3D9Client/gcConst.cpp @@ -3,9 +3,9 @@ // // Copyright (C) 2013-2016 Jarmo Nikkanen // -// 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 +// 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. @@ -31,7 +31,7 @@ extern class D3D9Client *g_client; // Custom SwapChain Interface // =============================================================================================== // -HSWAP gcConst::RegisterSwap(HWND hWnd, HSWAP hData, int AA) +HSWAP gcConst::RegisterSwap(HWND hWnd, HSWAP hData, int AA) { return gcCore::RegisterSwap(hWnd, hData, AA); } @@ -39,21 +39,21 @@ HSWAP gcConst::RegisterSwap(HWND hWnd, HSWAP hData, int AA) // =============================================================================================== // void gcConst::FlipSwap(HSWAP hSwap) -{ +{ gcCore::FlipSwap(hSwap); } // =============================================================================================== // SURFHANDLE gcConst::GetRenderTarget(HSWAP hSwap) -{ +{ return gcCore::GetRenderTarget(hSwap); } // =============================================================================================== // void gcConst::ReleaseSwap(HSWAP hSwap) -{ +{ gcCore::ReleaseSwap(hSwap); } @@ -328,7 +328,7 @@ HBITMAP gcConst::LoadBitmapFromFile(const char* fname) // HWND gcConst::GetRenderWindow() { - return g_client->GetRenderWindow(); + return g_client->GetRenderWindow()->Win32Handle(); } diff --git a/OVP/D3D9Client/gcCore.cpp b/OVP/D3D9Client/gcCore.cpp index 76c0d04be..c903dec4f 100644 --- a/OVP/D3D9Client/gcCore.cpp +++ b/OVP/D3D9Client/gcCore.cpp @@ -100,8 +100,8 @@ DLLCLBK void gcBindCoreMethod(void** ppFnc, const char* name) // Custom SwapChain Interface // =============================================================================================== // -HSWAP gcCore::RegisterSwap(HWND hWnd, HSWAP hData, int AA) -{ +HSWAP gcCore::RegisterSwap(HWND hWnd, HSWAP hData, int AA) +{ gcSwap * pData = (gcSwap*)hData; D3DPRESENT_PARAMETERS pp; @@ -129,7 +129,7 @@ HSWAP gcCore::RegisterSwap(HWND hWnd, HSWAP hData, int AA) { if (!pData) pData = new gcSwap(); else pData->Release(); - + LPDIRECT3DSURFACE9 pBack = NULL; HR(pSwap->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBack)); @@ -151,23 +151,23 @@ HSWAP gcCore::RegisterSwap(HWND hWnd, HSWAP hData, int AA) // =============================================================================================== // -void gcCore::FlipSwap(HSWAP hSwap) -{ +void gcCore::FlipSwap(HSWAP hSwap) +{ HR(((gcSwap*)hSwap)->pSwap->Present(0, 0, 0, 0, 0)); } // =============================================================================================== // -SURFHANDLE gcCore::GetRenderTarget(HSWAP hSwap) -{ +SURFHANDLE gcCore::GetRenderTarget(HSWAP hSwap) +{ return ((gcSwap*)hSwap)->hSurf; } // =============================================================================================== // -void gcCore::ReleaseSwap(HSWAP hSwap) -{ +void gcCore::ReleaseSwap(HSWAP hSwap) +{ if (hSwap) delete ((gcSwap*)hSwap); } @@ -567,7 +567,7 @@ HBITMAP gcCore::LoadBitmapFromFile(const char* fname) // HWND gcCore::GetRenderWindow() { - return g_client->GetRenderWindow(); + return g_client->GetRenderWindow()->Win32Handle(); } diff --git a/OVP/GDIClient/CMakeLists.txt b/OVP/GDIClient/CMakeLists.txt index 1e424bccd..60780f912 100644 --- a/OVP/GDIClient/CMakeLists.txt +++ b/OVP/GDIClient/CMakeLists.txt @@ -10,17 +10,19 @@ add_library(GDIClient SHARED ) target_include_directories(GDIClient - PUBLIC ${CMAKE_SOURCE_DIR}/Orbitersdk/include + PUBLIC ${CMAKE_SOURCE_DIR}/Orbitersdk/include imgui ) add_dependencies(GDIClient ${OrbiterTgt} Orbitersdk + imgui ) target_link_libraries(GDIClient ${ORBITER_LIB} ${ORBITER_SDK_LIB} + imgui ) # Installation diff --git a/OVP/GDIClient/GDIClient.cpp b/OVP/GDIClient/GDIClient.cpp index 37f6cf047..3819e4169 100644 --- a/OVP/GDIClient/GDIClient.cpp +++ b/OVP/GDIClient/GDIClient.cpp @@ -104,10 +104,10 @@ bool GDIClient::clbkSaveSurfaceToImage (SURFHANDLE surf, const char *fname, Imag if (fname == NULL) { // copy device-dependent bitmap to clipboard - if (OpenClipboard (GetRenderWindow())) { + if (OpenClipboard (GetRenderWindow()->Win32Handle())) { EmptyClipboard(); SetClipboardData(CF_BITMAP,hbm); - CloseClipboard(); + CloseClipboard(); } } else { BITMAP bmp; @@ -115,16 +115,16 @@ bool GDIClient::clbkSaveSurfaceToImage (SURFHANDLE surf, const char *fname, Imag GetObject (hbm, sizeof(BITMAP), &bmp); // map to device-independent bitmap - bi.biSize = sizeof(BITMAPINFOHEADER); - bi.biWidth = bmp.bmWidth; + bi.biSize = sizeof(BITMAPINFOHEADER); + bi.biWidth = bmp.bmWidth; bi.biHeight = -bmp.bmHeight; - bi.biPlanes = 1; - bi.biBitCount = 24; - bi.biCompression = BI_RGB; - bi.biSizeImage = 0; + bi.biPlanes = 1; + bi.biBitCount = 24; + bi.biCompression = BI_RGB; + bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; - bi.biClrUsed = 0; + bi.biClrUsed = 0; bi.biClrImportant = 0; oapi::ImageData imgdata; @@ -141,7 +141,7 @@ bool GDIClient::clbkSaveSurfaceToImage (SURFHANDLE surf, const char *fname, Imag WriteImageDataToFile (imgdata, fname, fmt, quality); - GlobalUnlock(hDIB); + GlobalUnlock(hDIB); GlobalFree(hDIB); } DeleteObject(hbm); diff --git a/Orbitersdk/CMakeLists.txt b/Orbitersdk/CMakeLists.txt index 8c24a8f87..9dd849165 100644 --- a/Orbitersdk/CMakeLists.txt +++ b/Orbitersdk/CMakeLists.txt @@ -31,6 +31,8 @@ add_custom_target(copy_sdk_include ) add_dependencies(Orbitersdk copy_sdk_include + SDL3::SDL3 + SDL3_image::SDL3_image ) if(ORBITER_MAKE_DOC) diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 9c33af69c..408af3107 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -12,7 +12,10 @@ #define __GRAPHICSAPI_H #include "Orbitersdk.h" + +#include #include +#include "imgui.h" #include #ifndef _WIN32 @@ -124,7 +127,7 @@ typedef void *HDC; /** * File path for celestial sphere background textures * \par Parameter type: - * *char + * const std::filesystem::path* */ #define CFGPRM_CSPHERETEXTURE 0x0013 @@ -199,7 +202,7 @@ typedef void *HDC; /** * Path to background star texture * \par Parameter type: - * *char + * const std::filesystem::path* */ #define CFGPRM_CSPHERESTARTEXTURE 0x001D @@ -385,6 +388,72 @@ class Sketchpad; class ParticleStream; class ScreenAnnotation; +class OAPIFUNC ImCtxBase; +class OAPIFUNC WithImCtx; + +class OAPIFUNC ImCtxBase { + public: + virtual ~ImCtxBase(); + + ImCtxBase(const ImCtxBase &) = delete; + + ImCtxBase &operator=(const ImCtxBase &) = delete; + + [[nodiscard]] ImFont *DefaultFont() const { return m_defaultFont; } + [[nodiscard]] ImFont *ItalicFont() const { return m_italicFont; } + [[nodiscard]] ImFont *BoldFont() const { return m_boldFont; } + [[nodiscard]] ImFont *BoldItalicFont() const { return m_boldItalicFont; } + [[nodiscard]] ImFont *HdgFont() const { return m_hdgFont; } + [[nodiscard]] ImFont *MonoFont() const { return m_monoFont; } + [[nodiscard]] Orbiter *App() const { return m_app; } + + WithImCtx PushLocal(); + protected: + friend WithImCtx; + ImCtxBase(Orbiter* app, ImGuiContext* context); + Orbiter *m_app; + ImGuiContext *m_context; + ImFont *m_defaultFont; + ImFont *m_italicFont; + ImFont *m_boldFont; + ImFont *m_boldItalicFont; + ImFont *m_hdgFont; + ImFont *m_monoFont; + + virtual bool ConsumeEvent(const SDL_Event &event, bool &wantsOut) = 0; + + [[nodiscard]] virtual bool BeginFrame() = 0; + + virtual void EndFrame() = 0; +}; + +class OAPIFUNC WithImCtx { + public: + + WithImCtx &operator=(const WithImCtx &) = delete; + + ~WithImCtx(); + + ImCtxBase *operator->() const; + + [[nodiscard]] ImCtxBase *Inner() const; + + bool ConsumeEvent(const SDL_Event &event, bool &wantsOut) const; + + [[nodiscard]] bool BeginFrame() const; + + void EndFrame() const; + + protected: + WithImCtx(const WithImCtx &) = default; + + private: + friend ImCtxBase; + WithImCtx(ImCtxBase *inner, ImGuiContext *lastContext); + ImCtxBase *inner; + ImGuiContext *lastContext; +}; + // ====================================================================== // class GraphicsClient // ====================================================================== @@ -464,7 +533,7 @@ class OAPIFUNC GraphicsClient: public Module { * \param str Text string to print */ virtual void clbkDebugString(const char *str) {} - + /** * \brief Texture request * @@ -788,25 +857,17 @@ class OAPIFUNC GraphicsClient: public Module { /** * \brief Returns the handle of the main render window. */ - HWND GetRenderWindow () const { return hRenderWnd; } + const std::shared_ptr& GetRenderWindow () const { return hRenderWnd; } - /** - * \brief Render window message handler - * - * Derived classes should also call the base class method to allow - * default message processing. - * \param hWnd render window handle - * \param uMsg Windows message identifier - * \param wParam WPARAM message parameter - * \param lParam LPARAM message parameter - * \return The return value depends on the message being processed. - * \note This is the standard Windows message handler for the render - * window. - * \note This method currently intercepts only the WM_CLOSE and WM_DESTROY - * messages, and passes everything else to the Orbiter core message - * handler. - */ - virtual LRESULT RenderWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + /** + * \brief Event handler for the render window. + * + * Be sure to call ConsumeEvent on your ImCtx here. + * \param event The event to consume + * \param wantsOut Set to true if the render window should be closed + * \return True if the event was consumed + */ + virtual bool RenderWndProc(const SDL_Event &event, bool &wantsOut); /** * \brief Message handler for 'video' tab in Orbiter Launchpad dialog @@ -856,7 +917,7 @@ class OAPIFUNC GraphicsClient: public Module { * \brief returns a list of popup windows owned by the render window. * \param [out] hPopupWnd on exit, points to a list of window handles * \return Number of entries in the list. - * \note The list returned by this method contains the handles of + * \note The list returned by this method contains the handles of * popup windows that are to be rendered on top of the render viewport * (e.g. dialog boxes). * \note A client can use this list if it requires a special method of @@ -1041,7 +1102,7 @@ class OAPIFUNC GraphicsClient: public Module { /** * \brief Create a surface for texturing, as a blitting source, etc. - * + * * Surfaces are used for offscreen bitmap and texture manipulation, * blitting and rendering. * Derived classes should create a device-specific surface, and @@ -1366,7 +1427,7 @@ class OAPIFUNC GraphicsClient: public Module { */ virtual Font *clbkCreateFont (int height, bool prop, const char *face, FontStyle style = FontStyle::FONT_NORMAL, int orientation = 0) const { return NULL; } virtual Font* clbkCreateFontEx (int height, char* face, int width = 0, int weight = 400, FontStyle style = FontStyle::FONT_NORMAL, float spacing = 0.0f) const { return NULL; } - + /** * \brief De-allocate a font resource. * \param font pointer to font resource @@ -1441,7 +1502,7 @@ class OAPIFUNC GraphicsClient: public Module { // @} /** - * \brief Constructs a synthetic elevation grid for a tile by interpolating + * \brief Constructs a synthetic elevation grid for a tile by interpolating * ancestor elevation data * \param emgr elevation manager handle (retrieve with oapiElevationManager) * \param [in] ilat patch latitude index @@ -1521,7 +1582,7 @@ class OAPIFUNC GraphicsClient: public Module { * \note Derived classes should perform any required per-session * initialisation of the 3D render environment here. */ - virtual HWND clbkCreateRenderWindow (); + virtual std::shared_ptr clbkCreateRenderWindow (); /** * \brief Simulation startup finalisation @@ -1633,7 +1694,7 @@ class OAPIFUNC GraphicsClient: public Module { /** * \brief Change the default splash screen - * + * * Called before clbkCreateRenderWindow to override the default splash screen * image and text color. * @@ -1843,9 +1904,9 @@ class OAPIFUNC GraphicsClient: public Module { * \return Render window handle * \note This is called after clbkCreateRenderWindow returns. */ - HWND InitRenderWnd (HWND hWnd); + void InitRenderWnd (std::shared_ptr& hWnd); - HWND hRenderWnd; // render window handle + std::shared_ptr hRenderWnd; // render window handle HINSTANCE hOrbiterInst; // orbiter core instance handle VIDEODATA VideoData; // the standard video options from config @@ -2068,4 +2129,4 @@ OAPIFUNC bool oapiRegisterGraphicsClient (oapi::GraphicsClient *gc); OAPIFUNC bool oapiUnregisterGraphicsClient (oapi::GraphicsClient *gc); -#endif // !__GRAPHICSAPI_H \ No newline at end of file +#endif // !__GRAPHICSAPI_H diff --git a/Orbitersdk/include/ModuleAPI.h b/Orbitersdk/include/ModuleAPI.h index 79d1d0f71..4db3e4e31 100644 --- a/Orbitersdk/include/ModuleAPI.h +++ b/Orbitersdk/include/ModuleAPI.h @@ -10,6 +10,7 @@ #ifndef __MODULEAPI_H #define __MODULEAPI_H +#include namespace oapi { @@ -29,7 +30,7 @@ namespace oapi { * \brief Creates a new ModuleNV instance. * \param hDLL DLL library instance handle (see \ref InitModule) */ - ModuleNV (HINSTANCE hDLL); + explicit ModuleNV (HINSTANCE hDLL); /** * \brief Module interface version @@ -95,7 +96,7 @@ namespace oapi { * \brief Creates a new Module instance. * \param hDLL DLL library instance handle (see \ref InitModule) */ - Module (HINSTANCE hDLL); + explicit Module (HINSTANCE hDLL); virtual ~Module(); /** @@ -259,9 +260,7 @@ namespace oapi { * \brief Process mouse events * * Called to offer a mouse event to the module. - * \param event Event type. This is a Windows message identifier (WM_xxx) such as WM_LBUTTONDOWN. - * \param state Keyboard state during mouse event. This corresponds to the WPARAM value passed to - * the window message handler for mouse events (e.g. MK_CONTROL). + * \param event The SDL mouse event. * \param x Mouse x position in render window at event * \param y Mouse y position in render window at event * \return Returning true prevents the event from entering the standard Orbiter processing queue @@ -274,7 +273,7 @@ namespace oapi { * \note Mouse-processing of the Orbiter main menu cannot be blocked. * \sa clbkProcessKeyboardImmediate, clbkProcessKeyboardBuffered */ - virtual bool clbkProcessMouse (UINT event, DWORD state, DWORD x, DWORD y) { return false; } + virtual bool clbkProcessMouse (const SDL_Event &event, DWORD x, DWORD y) { return false; } /** * \brief Process immediate keyboard events diff --git a/Orbitersdk/include/SDLWrappers.h b/Orbitersdk/include/SDLWrappers.h new file mode 100644 index 000000000..3d138e8bd --- /dev/null +++ b/Orbitersdk/include/SDLWrappers.h @@ -0,0 +1,63 @@ +#ifndef SDLWRAPPERS_H +#define SDLWRAPPERS_H + +#include +#include +#include + +namespace sdl { + +class UnmanagedWindow { +public: + UnmanagedWindow(const UnmanagedWindow &) = delete; + UnmanagedWindow &operator=(const UnmanagedWindow &) = delete; + + UnmanagedWindow(UnmanagedWindow &&other) noexcept : m_inner(other.m_inner) { + other.m_inner = nullptr; + } + + UnmanagedWindow(std::string_view title, int width, int height, + SDL_WindowFlags flags); + + ~UnmanagedWindow(); + + [[nodiscard]] SDL_Window *Inner() const { return m_inner; } + + [[nodiscard]] HWND Win32Handle() const { + return (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(m_inner), + SDL_PROP_WINDOW_WIN32_HWND_POINTER, + nullptr); + } + +private: + SDL_Window *m_inner = nullptr; +}; + +class ManagedWindow { +public: + ManagedWindow(const ManagedWindow &) = delete; + + ManagedWindow &operator=(const ManagedWindow &) = delete; + + ManagedWindow(ManagedWindow &&other) noexcept + : m_inner(other.m_inner), m_device(other.m_device) { + other.m_inner = nullptr; + other.m_device = nullptr; + } + + ManagedWindow(std::string_view title, int width, int height, + SDL_WindowFlags flags); + + ~ManagedWindow(); + + [[nodiscard]] SDL_Window *Inner() const { return m_inner; } + [[nodiscard]] SDL_GPUDevice *Device() const { return m_device; } + +private: + SDL_Window *m_inner = nullptr; + SDL_GPUDevice *m_device = nullptr; +}; + +} // namespace sdl + +#endif // SDLWRAPPERS_H diff --git a/Orbitersdk/include/imgui_extras.h b/Orbitersdk/include/imgui_extras.h index 95b0aa86c..cb9b7b4fa 100644 --- a/Orbitersdk/include/imgui_extras.h +++ b/Orbitersdk/include/imgui_extras.h @@ -13,6 +13,7 @@ enum class ImGuiFont { namespace ImGui { OAPIFUNC bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format = "%.3f"); + OAPIFUNC bool SliderScalarReset(const char* label, ImGuiDataType dtype, size_t t_size, void* v, const void *v_min, const void *v_max, const void *v_default, const char* display_format = "%.3f"); OAPIFUNC void HelpMarker(const char* desc, bool sameline = true); OAPIFUNC void BeginGroupPanel(const char* name, const ImVec2& size = ImVec2(-1.0f, -1.0f)); OAPIFUNC void EndGroupPanel(); diff --git a/Sound/XRSound/LICENSE b/Sound/XRSound/LICENSE index 2fc172fd5..73d9692bf 100644 --- a/Sound/XRSound/LICENSE +++ b/Sound/XRSound/LICENSE @@ -30,7 +30,7 @@ about the ikkLang license. Its license as of 31-July-2021 is quoted below: The irrKlang License irrKlang's source codes, documentation and binaries contained within the -distributed archive are copyright Nikolaus Gebhardt / Ambiera 2001-2020. +distributed archive are copyright (c) Nikolaus Gebhardt / Ambiera 2001-2020. The contents of the irrKlang distribution archive may not be redistributed, reproduced, modified, transmitted, broadcast, published or adapted in any way, diff --git a/Sound/XRSound/src/CMakeLists.txt b/Sound/XRSound/src/CMakeLists.txt index 497c2ecac..8ad26fc3f 100644 --- a/Sound/XRSound/src/CMakeLists.txt +++ b/Sound/XRSound/src/CMakeLists.txt @@ -23,12 +23,14 @@ target_include_directories(XRSound_dll PUBLIC ${ORBITER_SOURCE_SDK_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Utils ${IRRKLANG_DIR}/include + SDL3::SDL3 ) -target_link_libraries(XRSound_dll +target_link_libraries(XRSound_dll PUBLIC ${ORBITER_LIB} ${ORBITER_SDK_LIB} ${IRRKLANG_LIB} + SDL3::SDL3 ) add_dependencies(XRSound_dll @@ -54,8 +56,11 @@ set_target_properties(XRSound_lib target_include_directories(XRSound_lib PUBLIC ${ORBITER_SOURCE_SDK_INCLUDE_DIR} + SDL3::SDL3 ) +target_link_libraries(XRSound_lib PUBLIC SDL3::SDL3) + install(TARGETS XRSound_lib ARCHIVE DESTINATION ${ORBITER_INSTALL_SDK_DIR}/XRSound ) diff --git a/Src/Celbody/Vsop87/CMakeLists.txt b/Src/Celbody/Vsop87/CMakeLists.txt index c66fb74fe..72f394a67 100644 --- a/Src/Celbody/Vsop87/CMakeLists.txt +++ b/Src/Celbody/Vsop87/CMakeLists.txt @@ -14,11 +14,11 @@ add_dependencies(Vsop87 ) target_include_directories(Vsop87 - PUBLIC ${CMAKE_SOURCE_DIR}/Orbitersdk/include + PUBLIC ${CMAKE_SOURCE_DIR}/Orbitersdk/include SDL3::SDL3 ) target_link_libraries(Vsop87 - ${ORBITER_LIB} + ${ORBITER_LIB} SDL3::SDL3 ) set(VSOP87_LIB $) diff --git a/Src/Orbiter/CMakeLists.txt b/Src/Orbiter/CMakeLists.txt index 2a4bf503b..89a5e603c 100644 --- a/Src/Orbiter/CMakeLists.txt +++ b/Src/Orbiter/CMakeLists.txt @@ -110,6 +110,7 @@ set(common_src D3d7util.cpp D3dmath.cpp Di7frame.cpp + SDLWrappers.cpp # Graphics interface base class for GDI clients ${GDICLIENT_DIR}/GDIClient.cpp # Utils @@ -121,6 +122,7 @@ set(common_src Orbiter.rc Orbiter.ico ${imgui_SOURCE_DIR}/backends/imgui_impl_win32.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_sdl3.cpp ) set(Orbiter_includes @@ -141,6 +143,8 @@ set(Orbiter_common_libs ${HTMLHELP_LIB} $ $ + SDL3::SDL3 + SDL3_image::SDL3_image ) set(Orbiter_libs dxguid.lib @@ -183,7 +187,7 @@ install(FILES $ DESTINATION ${ORBITER_INSTALL_SDK_DI # Copy library to its Orbitersdk/lib location so that external project integrated into the build can find it add_custom_command(TARGET ${OrbiterTgt} POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${ORBITER_BINARY_SDK_DIR}/lib - COMMAND ${CMAKE_COMMAND} -E copy ${ORBITER_LIB} ${ORBITER_BINARY_SDK_DIR}/lib/ + COMMAND ${CMAKE_COMMAND} -E copy ${ORBITER_LIB} ${ORBITER_BINARY_SDK_DIR}/lib/ ) string(TIMESTAMP DATE "%d %b %Y") diff --git a/Src/Orbiter/Camera.cpp b/Src/Orbiter/Camera.cpp index 207970b21..25055321f 100644 --- a/Src/Orbiter/Camera.cpp +++ b/Src/Orbiter/Camera.cpp @@ -69,7 +69,7 @@ Camera::Camera (double _nearplane, double _farplane) has_tref = false; movehead = false; ExtCtrlMode = 0; - GetCursorPos (&pm); + SDL_GetMouseState (&pm.x, &pm.y); mmoveT = -1000.0; ap_int = ap_ext = RAD*25.0; ap = &ap_ext; @@ -90,51 +90,51 @@ Camera::~Camera () ClearPresets(); } -bool Camera::ProcessMouse (UINT event, DWORD state, DWORD x, DWORD y, const char *kstate) +bool Camera::ProcessMouse (const SDL_Event &event, DWORD x, DWORD y, const char *kstate) { - if (event != WM_MOUSEWHEEL) + if (event.type != SDL_EVENT_MOUSE_WHEEL) mx = (int)x, my = (int)y; - switch (event) { - case WM_LBUTTONDOWN: - mbdown[0] = true; - return true; - case WM_RBUTTONDOWN: - mbdown[1] = true; - g_pOrbiter->InitRotationMode(); - return true; - case WM_LBUTTONUP: - if (mbdown[0]) { - mbdown[0] = false; - return true; - } - break; - case WM_RBUTTONUP: - if (mbdown[1]) { - mbdown[1] = false; - g_pOrbiter->ExitRotationMode(); - return true; - } - break; - case WM_MOUSEWHEEL: - if (KEYMOD_CONTROL(kstate)) { - } - else { - short zDelta = (short)HIWORD(state); - if (external_view) - ShiftDist(-zDelta*0.001); - else - g_pOrbiter->IncFOV(zDelta*(-2.0 / 120.0*RAD)); - } return true; - break; - } + if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_LEFT) { + mbdown[0] = true; + return true; + } + if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_RIGHT) { + mbdown[1] = true; + g_pOrbiter->InitRotationMode(); + return true; + } + if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_LEFT) { + if (mbdown[0]) { + mbdown[0] = false; + return true; + } + } + if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_RIGHT) { + if (mbdown[1]) { + mbdown[1] = false; + g_pOrbiter->ExitRotationMode(); + return true; + } + } + if (event.type == SDL_EVENT_MOUSE_WHEEL) { + if (!KEYMOD_CONTROL(kstate)) { + double zDelta = event.wheel.y * 120.0; + if (external_view) + ShiftDist(-zDelta*0.001); + else + g_pOrbiter->IncFOV(zDelta*(-2.0 / 120.0*RAD)); + return true; + } + } + return false; } void Camera::UpdateMouse () { - POINT pt; - GetCursorPos (&pt); + SDL_FPoint pt; + SDL_GetMouseState(&pt.x, &pt.y); if (pt.x != pm.x || pt.y != pm.y) { pm.x = pt.x, pm.y = pt.y; mmoveT = td.SysT0; @@ -143,11 +143,9 @@ void Camera::UpdateMouse () if (mbdown[1]) { int dx, dy, x0, y0; x0 = pt.x, y0 = pt.y; - if (!g_pOrbiter->IsFullscreen()) - ScreenToClient (g_pOrbiter->GetRenderWnd(), &pt); dx = pt.x - mx; dy = pt.y - my; - SetCursorPos (x0-dx, y0-dy); + SDL_WarpMouseInWindow(nullptr, x0-dx, y0-dy); if (!(dx || dy)) return; if (external_view) { @@ -808,7 +806,7 @@ void Camera::SetGroundObserver_TargetLock (bool lock) go.phi = atan2 (-hdir.x, hdir.z); OutputGroundObserverParams(); } - + SendDlgMessage (2, this); } } @@ -829,7 +827,7 @@ void Camera::GroundObserverShift (double dx, double dz, double dh) { if (!external_view || extmode != CAMERA_GROUNDOBSERVER) return; double r; - + Vector dsz (grot.m13, grot.m23, grot.m33); // dz: go forward/backward w.r.t. camera view direction Vector dsx (grot.m11, grot.m21, grot.m31); // dx: go sideways w.r.t. camera view direction dirref->GlobalToEquatorial (gpos + dsz*dz + dsx*dx, go.lng, go.lat, r); @@ -868,7 +866,7 @@ void Camera::OutputGroundObserverParams () const HWND dlg = dlgmgr->IsEntry (g_pOrbiter->GetInstance(), IDD_CAMERA); if (dlg) { char cbuf[256]; - sprintf (cbuf, "Lng = %+0.6f\r\nLat = %+0.6f\r\nAlt = %0.2fm\r\nPhi = %0.2f\r\nTheta = %0.2f", + sprintf (cbuf, "Lng = %+0.6f�\r\nLat = %+0.6f�\r\nAlt = %0.2fm\r\nPhi = %0.2f�\r\nTheta = %0.2f�", DEG*go.lng, DEG*go.lat, go.alt, DEG*go.phi, DEG*go.tht); SendDlgMessage (1, cbuf); } @@ -896,7 +894,7 @@ DWORD Camera::UpdateExternalControl (ExternalCameraControl *ecc) if (ECC->clbkPoll (&data)) { go.phi = data.yaw; go.tht = data.pitch; - } + } } } else { // track mode if (cmode & CAMMODE_TRACK) { @@ -1463,7 +1461,7 @@ bool Camera::Read (ifstream &ifs) extmode = CAMERA_TARGETFROMOBJECT; else if (!_stricmp (ctrackmode, "Ground") && (dirref = g_psys->GetObj (cdirref, true))) extmode = CAMERA_GROUNDOBSERVER; - else + else extmode = CAMERA_TARGETRELATIVE; } return true; @@ -1582,7 +1580,7 @@ CameraMode *CameraMode::Create (char *str) } else { cm = new CameraMode_Cockpit; TRACENEW } - + if (!(pc = strtok (NULL, ":")) || !(cm->target = (OBJHANDLE)g_psys->GetObj (trim_string (pc), true))) { delete cm; return 0; @@ -1637,7 +1635,7 @@ void CameraMode_Cockpit::Init (char *str) cmode = CM_CURRENT; str += 7; } - + } void CameraMode_Cockpit::GetDescr (char *str, int len) @@ -1687,7 +1685,7 @@ void CameraMode_Track::Init (char *str) void CameraMode_Track::Store (char *str) { static const char *tmstr[6] = {"CURRENT","RELATIVE", "ABSDIR", "GLOBAL", "TARGETTOREF", "TARGETFROMREF"}; - sprintf (str, "Track:%s%:%0.2f:%s %0.3f %0.3f %0.3f", + sprintf (str, "Track:%s%:%0.2f:%s %0.3f %0.3f %0.3f", target ? ((Body*)target)->Name() : "-", fov, tmstr[tmode], reldist, phi, theta); if (tmode == TM_TARGETTOREF || tmode == TM_TARGETFROMREF) { diff --git a/Src/Orbiter/Camera.h b/Src/Orbiter/Camera.h index 5292a7d64..14c035e67 100644 --- a/Src/Orbiter/Camera.h +++ b/Src/Orbiter/Camera.h @@ -15,11 +15,15 @@ #ifndef __CAMERA_H #define __CAMERA_H -#include -#include +#include "CamAPI.h" #include "Vecmat.h" #include "elevmgr.h" -#include "CamAPI.h" +#include +#include +#include +#include +#include +namespace fs = std::filesystem; class Body; class Planet; @@ -54,7 +58,7 @@ class Camera { public: Camera (double _nearplane = 1.0, double _farplane = 1e8); // Create a camera with given y-aperture [rad] and viewing fustrum limits - + ~Camera(); void SetCMode (const CameraMode *cm); @@ -71,7 +75,7 @@ class Camera { inline bool IsExternal () const { return external_view; } inline bool IsInternal () const { return !external_view; } - + bool IsCockpitForward () const; // Return true if we are in cockpit mode and the camera points forward (+z) @@ -173,7 +177,7 @@ class Camera { void Drag (const Vector &gshift); // Displace camera by 'gshift' (global coords) from its - // 'natural' position. The camera will automatically + // 'natural' position. The camera will automatically // gradually move back (external camera mode only) void GroundObserverShift (double dx, double dz, double dh); @@ -236,7 +240,7 @@ class Camera { void SetGroundObserver_TerrainLimit (double alt); void OutputGroundObserverParams () const; - bool ProcessMouse (UINT event, DWORD state, DWORD x, DWORD y, const char *kstate); + bool ProcessMouse (const SDL_Event &event, DWORD x, DWORD y, const char *kstate); void UpdateMouse (); void ClearPresets (); @@ -320,7 +324,7 @@ class Camera { DWORD ExtCtrlMode; // if camera is externally controlled, this contains bitflags for data types // (see CAMDATA_xxx constants in CamAPI.h) - POINT pm; // last cursor position + SDL_FPoint pm; // last cursor position double mmoveT; // time of last mouse move Vector gpos; // current camera pos in global coords @@ -402,4 +406,4 @@ class Camera { }; -#endif // !__CAMERA_H \ No newline at end of file +#endif // !__CAMERA_H diff --git a/Src/Orbiter/Config.cpp b/Src/Orbiter/Config.cpp index 8dfd28897..01cd34ba2 100644 --- a/Src/Orbiter/Config.cpp +++ b/Src/Orbiter/Config.cpp @@ -229,7 +229,7 @@ CFG_FONTPRM CfgFontPrm_default = { 1.0f, // dlgFont_Scale (scaling factor for inline dialog fonts) "Arial", // dlgFont1_Face (default dialog font face name) 14.0f, // ImGui_FontSize - "Roboto-Medium.ttf" // ImGui_FontFile + "Inter" // ImGui_FontFile }; CFG_CAMERAPRM CfgCameraPrm_default = { @@ -344,7 +344,7 @@ bool GetItemString (istream &is, const char *label, char *val) while (is.getline (cbuf, 512)) { cl = trim_string(cbuf); if (!_stricmp(cl, "END_PARSE")) return false; - + for (i = 0; cl[i] && cl[i] != '='; i++); cv = (cl[i] ? cl+(i+1) : cl+i); for (cl[i--] = '\0'; i >= 0 && (cl[i] == ' ' || cl[i] == '\t'); i--) @@ -461,6 +461,10 @@ Config::Config(char* fname) Load(fname); } +static bool operator==(const SDL_GUID a, const SDL_GUID b) { + return memcmp(&a.data, &b.data, 16) == 0; +} + bool Config::Load(const char *fname) { int i; @@ -531,8 +535,18 @@ bool Config::Load(const char *fname) if (GetInt (ifs, "WindowHeight", i)) CfgDevPrm.WinH = (DWORD)i; // Joystick information - if (GetInt (ifs, "JoystickIndex", i)) - CfgJoystickPrm.Joy_idx = (DWORD)i; + if (GetString (ifs, "JoystickIndex", cbuf)) { + const auto guid = SDL_StringToGUID(cbuf); + auto njoy = 0; + const auto joylist = SDL_GetJoysticks(&njoy); + CfgJoystickPrm.Joy_idx = 0; + for (int joyix = 0; joyix < njoy; joyix++) { + if (SDL_GetJoystickGUIDForID(joylist[joyix]) == guid) { + CfgJoystickPrm.Joy_idx = joylist[joyix]; + } + } + SDL_free(joylist); + } if (GetInt (ifs, "JoystickThrottleAxis", i)) CfgJoystickPrm.ThrottleAxis = max (0, min (3, i)); if (GetInt (ifs, "JoystickThrottleSaturation", i)) @@ -761,7 +775,7 @@ bool Config::Load(const char *fname) if (GetReal (ifs, "DialogFont_Scale", d)) CfgFontPrm.dlgFont_Scale = (float)d; GetString (ifs, "DialogFont1_Face", CfgFontPrm.dlgFont1_Face); if (GetReal (ifs, "ImGui_FontSize", d)) CfgFontPrm.ImGui_FontSize = (float)d; - GetString (ifs, "ImGui_FontFile", CfgFontPrm.ImGui_FontFile); + GetString (ifs, "ImGui_FontName", CfgFontPrm.ImGui_FontName); // misc. options if (GetString (ifs, "LPadRect", cbuf)) { @@ -962,7 +976,7 @@ BOOL Config::Write (const char *fname) const ofs << "LPadRect = " << rLaunchpad.left << ' ' << rLaunchpad.top << ' ' << rLaunchpad.right << ' ' << rLaunchpad.bottom << '\n'; - if (strcmp (CfgDirPrm.ConfigDir, CfgDirPrm_default.ConfigDir) || + if (strcmp (CfgDirPrm.ConfigDir, CfgDirPrm_default.ConfigDir) || strcmp (CfgDirPrm.MeshDir, CfgDirPrm_default.MeshDir) || strcmp (CfgDirPrm.TextureDir, CfgDirPrm_default.TextureDir) || strcmp (CfgDirPrm.HightexDir, CfgDirPrm_default.HightexDir) || @@ -1250,8 +1264,12 @@ BOOL Config::Write (const char *fname) const if (memcmp (&CfgJoystickPrm, &CfgJoystickPrm_default, sizeof(CFG_JOYSTICKPRM)) || bEchoAll) { ofs << "\n; === Joystick parameters ===\n"; - if (CfgJoystickPrm.Joy_idx != CfgJoystickPrm_default.Joy_idx || bEchoAll) - ofs << "JoystickIndex = " << CfgJoystickPrm.Joy_idx << '\n'; + if (CfgJoystickPrm.Joy_idx != CfgJoystickPrm_default.Joy_idx || bEchoAll) { + const auto guid = SDL_GetJoystickGUIDForID(CfgJoystickPrm.Joy_idx); + char cbuf[33]; + SDL_GUIDToString(guid, cbuf, 33); + ofs << "JoystickIndex = " << cbuf << '\n'; + } if (CfgJoystickPrm.ThrottleAxis != CfgJoystickPrm_default.ThrottleAxis || bEchoAll) ofs << "JoystickThrottleAxis = " << CfgJoystickPrm.ThrottleAxis << '\n'; if (CfgJoystickPrm.ThrottleSaturation != CfgJoystickPrm_default.ThrottleSaturation || bEchoAll) @@ -1338,8 +1356,8 @@ BOOL Config::Write (const char *fname) const ofs << "DialogFont1_Face = " << CfgFontPrm.dlgFont1_Face << '\n'; if (CfgFontPrm.ImGui_FontSize != CfgFontPrm_default.ImGui_FontSize || bEchoAll) ofs << "ImGui_FontSize = " << CfgFontPrm.ImGui_FontSize << '\n'; - if (strcmp (CfgFontPrm.ImGui_FontFile, CfgFontPrm_default.ImGui_FontFile) || bEchoAll) - ofs << "ImGui_FontFile = " << CfgFontPrm.ImGui_FontFile << '\n'; + if (strcmp (CfgFontPrm.ImGui_FontName, CfgFontPrm_default.ImGui_FontName) || bEchoAll) + ofs << "ImGui_FontName = " << CfgFontPrm.ImGui_FontName << '\n'; } if (memcmp (&CfgWindowPos, &CfgWindowPos_default, sizeof(CFG_WINDOWPOS)) || bEchoAll) { @@ -1600,4 +1618,4 @@ GDIResources::~GDIResources () DeleteObject (dlgF1r); DeleteObject (dlgF1i); DeleteObject (dlgF2); -} \ No newline at end of file +} diff --git a/Src/Orbiter/Config.h b/Src/Orbiter/Config.h index edad56299..ee7efd5cc 100644 --- a/Src/Orbiter/Config.h +++ b/Src/Orbiter/Config.h @@ -11,12 +11,16 @@ #define __CONFIG_H //#include -#include +#include "GraphicsAPI.h" #include "Vecmat.h" -#include #include +#include #include -#include "GraphicsAPI.h" +#include +#include + +#include +namespace fs = std::filesystem; // dynamic state propagation methods #define MAX_PROP_LEVEL 5 @@ -218,11 +222,11 @@ struct CFG_DEVPRM { }; struct CFG_JOYSTICKPRM { - DWORD Joy_idx; // joystick device index (0=disabled) - DWORD Deadzone; // central deadzone range for all axes (0-10000) - DWORD ThrottleAxis; // joystick throttle axis (0=none, 1=z-axis, 2=slider 0, 3=slider 1) - DWORD ThrottleSaturation; // saturation level for joystick throttle control (0-10000) - bool bThrottleIgnore; // ignore joystick throttle setting on start + SDL_JoystickID Joy_idx; // joystick device index (0=disabled) + DWORD Deadzone; // central deadzone range for all axes (0-10000) + DWORD ThrottleAxis; // joystick throttle axis (0=none, 1=z-axis, 2=slider 0, 3=slider 1) + DWORD ThrottleSaturation; // saturation level for joystick throttle control (0-10000) + bool bThrottleIgnore; // ignore joystick throttle setting on start }; struct CFG_UIPRM { // user interface options @@ -251,10 +255,11 @@ struct CFG_DEMOPRM { }; struct CFG_FONTPRM { - float dlgFont_Scale; // font scaling factor - char dlgFont1_Face[64]; // dialog font face name - float ImGui_FontSize; // Font size for ImGui dialogs - char ImGui_FontFile[256]; // Font file for ImGui default font + float dlgFont_Scale; // font scaling factor + char dlgFont1_Face[64]; // dialog font face name + float ImGui_FontSize; // Font size for ImGui dialogs + char ImGui_FontName[256]; // Font name (file: `{FontName}-{Weight}.ttf`) where + // Weight is `Regular`, `Italic`, `Bold`, or `BoldItalic` }; struct CFG_CAMERAPRM { @@ -311,7 +316,7 @@ bool GetItemVector (std::istream &is, const char *label, Vector &val); bool GetItemVECTOR (std::istream &is, const char *label, VECTOR3 &val); bool FindLine (std::istream &is, const char *line); -// scans stream 'is' from beginning for a line beginning with 'line' +// scans stream 'is' from beginning for a line beginning with 'line' // and leaves file pointer on the beginning of the next line // return value is false if line is not found @@ -486,4 +491,4 @@ GDIResources *g_gdires = 0; extern GDIResources *g_gdires; #endif -#endif // !__CONFIG_H \ No newline at end of file +#endif // !__CONFIG_H diff --git a/Src/Orbiter/Defpanel.cpp b/Src/Orbiter/Defpanel.cpp index 7e0327999..e1c63413c 100644 --- a/Src/Orbiter/Defpanel.cpp +++ b/Src/Orbiter/Defpanel.cpp @@ -91,7 +91,7 @@ DefaultPanel::DefaultPanel (Pane *_pane, int cidx): pane(_pane) rcsmode = -1; rcsdispmode = 1; - + mfdFont = NULL; mfdPen = NULL; @@ -248,7 +248,7 @@ void DefaultPanel::SetGeometry () Idx[i*6+j] = i*4+idx[j]; } navgrp = mesh.AddGroup (Vtx, nVtx, Idx, nIdx, 0, 0); - + // engine status display Vtx = new NTVERTEX[nVtx = 27*4]; Idx = new WORD[nIdx = 27*6]; @@ -539,25 +539,20 @@ void DefaultPanel::Render () gc->clbkRender2DPanel (&surf, (MESHHANDLE)&mesh, &transf, transpmfd); } -bool DefaultPanel::ProcessMouse (UINT event, DWORD state, int x, int y) +bool DefaultPanel::ProcessMouse (const SDL_Event &event, int x, int y) { - switch (event) { - case WM_LBUTTONDOWN: - mstate = PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED; - break; - case WM_RBUTTONDOWN: - mstate = PANEL_MOUSE_RBDOWN | PANEL_MOUSE_RBPRESSED; - break; - case WM_LBUTTONUP: - mstate = PANEL_MOUSE_LBUP; - break; - case WM_RBUTTONUP: - mstate = PANEL_MOUSE_RBUP; - break; - default: - mstate = 0; - break; - } + if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_LEFT) { + mstate = PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_RIGHT) { + mstate = PANEL_MOUSE_RBDOWN | PANEL_MOUSE_RBPRESSED; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_LEFT) { + mstate = PANEL_MOUSE_LBUP; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_RIGHT) { + mstate = PANEL_MOUSE_RBUP; + } else { + mstate = 0; + } + if (mstate & PANEL_MOUSE_DOWN) { // locate mouse event int mfd, btn; if (GetMFDButton (x, y, mfd, btn)) { diff --git a/Src/Orbiter/Defpanel.h b/Src/Orbiter/Defpanel.h index f50d53cce..1b55a202f 100644 --- a/Src/Orbiter/Defpanel.h +++ b/Src/Orbiter/Defpanel.h @@ -30,7 +30,7 @@ class DefaultPanel { // Render the glass cockpit overlay on top of the target surface void Render (); - bool ProcessMouse (UINT event, DWORD state, int x, int y); + bool ProcessMouse (const SDL_Event &event, int x, int y); void GetButtonState (int &state, int &mfd, int &btn); inline void SetMouseState (int state) { mstate = state; } inline void SetNavDisplayMode (int mode) { navdispmode = mode; } @@ -104,4 +104,4 @@ class DefaultPanel { char engstat_str[4][8]; // status strings for engine display block }; -#endif // !__DEFPANEL_H \ No newline at end of file +#endif // !__DEFPANEL_H diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index c10a6357e..3b51ebdd6 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -13,6 +13,7 @@ #include "imgui.h" #include "imgui_extras.h" #include "imgui_impl_win32.h" +#include "imgui_impl_sdl3.h" #include "IconsFontAwesome6.h" #include #include @@ -52,7 +53,7 @@ static DIALOGENTRY *de_create = 0; // ================================================================== // class DialogManager -DialogManager::DialogManager (Orbiter *orbiter, HWND hAppWnd) +DialogManager::DialogManager (Orbiter *orbiter, HWND hAppWnd) : ImCtxBase(orbiter, ImGui::CreateContext()) { pOrbiter = orbiter; gc = orbiter->GetGraphicsClient(); @@ -320,7 +321,7 @@ INT_PTR OrbiterDefDialogProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_SETCURSOR: // implements "focus follows mouse" behaviour if (!g_pOrbiter->StickyFocus() && g_pOrbiter->Cfg()->CfgUIPrm.MouseFocusMode == 2 && GetFocus() != hDlg && - !IsChild (hDlg, GetFocus()) && GetParent (hDlg) == g_pOrbiter->GetRenderWnd()) { + !IsChild (hDlg, GetFocus()) && GetParent (hDlg) == g_pOrbiter->GetRenderWnd()->Win32Handle()) { SetFocus (hDlg); return FALSE; } @@ -409,7 +410,7 @@ DWORD WINAPI DlgThreadProc (void *data) // ==================================================================== // End tread management // ==================================================================== -// +// // ==================================================================== // ImGui // ==================================================================== @@ -421,7 +422,7 @@ const ImWchar* GetGlyphRangesOrbiter() static const ImWchar ranges[] = { 0x0020, 0x00FF, // Basic Latin + Latin Supplement - 0x00A0, 0x02D9, // Polish characters + 0x00A0, 0x02D9, // Polish characters 0x0393, 0x03C2, // Greek characters 0x221A, 0x221A, // √ 0x222B, 0x222B, // ∫ @@ -432,101 +433,11 @@ const ImWchar* GetGlyphRangesOrbiter() return &ranges[0]; } -// Styling adapted from https://gist.github.com/dougbinks/8089b4bbaccaaf6fa204236978d165a9 -static void ImGuiSetStyle(bool bStyleDark_, float alpha_) -{ - // Setup Dear ImGui style - ImGui::StyleColorsClassic(); - ImGui::StyleColorsLight(); - ImGuiStyle& style = ImGui::GetStyle(); - - style.Alpha = 1.0f; - style.FrameRounding = 3.0f; - style.WindowRounding = 3.0f; - style.ChildRounding = 3.0f; - style.PopupRounding = 3.0f; - style.ScrollbarRounding = 3.0f; - style.GrabRounding = 3.0f; - style.TabRounding = 3.0f; - style.WindowMenuButtonPosition = ImGuiDir_Right; - return; - // light style from Pacôme Danhiez (user itamago) https://github.com/ocornut/imgui/pull/511#issuecomment-175719267 - style.Colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); - style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - style.Colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 0.94f); - style.Colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f); - style.Colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.39f); - style.Colors[ImGuiCol_BorderShadow] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f); - style.Colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f); - style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); - style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); - style.Colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f); - style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f); - style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f); - style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f); - style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f); - style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 1.00f); - style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.59f, 0.59f, 0.59f, 1.00f); - style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f); - style.Colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); - style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - style.Colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); - style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); - style.Colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); - style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); - style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - style.Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.50f); - style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); - style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); - style.Colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); - style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); - style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); - style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); - - if( bStyleDark_ ) - { - for (int i = 0; i <= ImGuiCol_COUNT; i++) - { - ImVec4& col = style.Colors[i]; - float H, S, V; - ImGui::ColorConvertRGBtoHSV( col.x, col.y, col.z, H, S, V ); - - if( S < 0.1f ) - { - V = 1.0f - V; - } - ImGui::ColorConvertHSVtoRGB( H, S, V, col.x, col.y, col.z ); - if( col.w < 1.00f ) - { - col.w *= alpha_; - } - } - } - else - { - for (int i = 0; i <= ImGuiCol_COUNT; i++) - { - ImVec4& col = style.Colors[i]; - if( col.w < 1.00f ) - { - col.x *= alpha_; - col.y *= alpha_; - col.z *= alpha_; - col.w *= alpha_; - } - } - } -} - void DialogManager::InitImGui() { if(!gc) return; - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); + WithImCtx _ = PushLocal(); ImGuiIO& io = ImGui::GetIO(); // Viewports don't play nice when in full screen mode if(!pOrbiter->IsFullscreen()) @@ -535,24 +446,7 @@ void DialogManager::InitImGui() //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls //io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; - ImGuiSetStyle(true, 1.0f); // Dark, alpha - - ImFontConfig config; - - static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; - ImFontConfig icons_config; - icons_config.MergeMode = true; - icons_config.PixelSnapH = true; - icons_config.FontDataOwnedByAtlas = false; - - const CFG_FONTPRM &prm = g_pOrbiter->Cfg()->CfgFontPrm; - defaultFont = io.Fonts->AddFontFromFileTTF(prm.ImGui_FontFile, prm.ImGui_FontSize, &config, ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); - io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, &icons_config, icons_ranges); - monoFont = io.Fonts->AddFontFromFileTTF("Cousine-Regular.ttf", prm.ImGui_FontSize, &config, ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); - io.Fonts->Build(); - - - ImGui_ImplWin32_Init(hWnd); + ImGui_ImplSDL3_InitForOther(g_pOrbiter->GetRenderWnd()->Inner()); gc->clbkImGuiInit(); } @@ -560,45 +454,80 @@ void DialogManager::ShutdownImGui() { if(!gc) return; + WithImCtx _ = PushLocal(); gc->clbkImGuiShutdown(); - ImGui_ImplWin32_Shutdown(); - ImGui::DestroyContext(); + ImGui_ImplSDL3_Shutdown(); +} + +static bool EventIsKeyboard(Uint32 type) { + return type >= SDL_EVENT_KEY_UP && type < SDL_EVENT_MOUSE_MOTION; +} + +static bool EventIsMouse(Uint32 type) { + return type >= SDL_EVENT_MOUSE_MOTION && + type < SDL_EVENT_JOYSTICK_AXIS_MOTION; +} + +bool DialogManager::ConsumeEvent(const SDL_Event &event, bool &wantsOut) { + bool consumed = false; + WithImCtx _ = PushLocal(); + ImGui_ImplSDL3_ProcessEvent(&event); + ImGuiIO &io = ImGui::GetIO(); + if ((io.WantCaptureMouse && EventIsMouse(event.type)) || + (io.WantCaptureKeyboard && EventIsKeyboard(event.type))) { + consumed = true; + } + // close requested are ignored TBD, until this uses Win32 + + return consumed; +} + +bool DialogManager::BeginFrame() { + WithImCtx _ = PushLocal(); + gc->clbkImGuiNewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + //ImGui::ShowDemoWindow(); + + // Render notifications + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.f); // Round borders + // ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(43.f / 255.f, 43.f / 255.f, 43.f / 255.f, 240.f / 255.f)); // Background color + RenderNotifications(); // <-- Here we render all notifications + ImGui::PopStyleVar(1); // Don't forget to Pop() + // ImGui::PopStyleColor(1); + + // We can't use a range-based loop here because Show() may unregister the current dialog + for (auto it = DlgImGuiList.begin(); it != DlgImGuiList.end();) + { + auto current = it++; + if ((*current)->IsActive()) { + (*current)->Display(); + } + } + return true; +} + +void DialogManager::EndFrame() { + WithImCtx _ = PushLocal(); + ImGui::EndFrame(); } void DialogManager::ImGuiNewFrame() { if(!gc) return; - - gc->clbkImGuiNewFrame(); - ImGui_ImplWin32_NewFrame(); - ImGui::NewFrame(); - - //ImGui::ShowDemoWindow(); - - // Render notifications - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.f); // Round borders -// ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(43.f / 255.f, 43.f / 255.f, 43.f / 255.f, 240.f / 255.f)); // Background color - RenderNotifications(); // <-- Here we render all notifications - ImGui::PopStyleVar(1); // Don't forget to Pop() -// ImGui::PopStyleColor(1); - - // We can't use a range-based loop here because Show() may unregister the current dialog - for (auto it = DlgImGuiList.begin(); it != DlgImGuiList.end();) - { - auto current = it++; - if ((*current)->IsActive()) { - (*current)->Display(); - } - } - ImGui::EndFrame(); + WithImCtx _ = PushLocal(); + if (BeginFrame()) { + EndFrame(); + } } ImFont *DialogManager::GetFont(ImGuiFont f) { switch(f) { - case ImGuiFont::MONO: return monoFont; - case ImGuiFont::DEFAULT: return defaultFont; - default: return defaultFont; + case ImGuiFont::MONO: return MonoFont(); + case ImGuiFont::DEFAULT: return DefaultFont(); + default: return DefaultFont(); } } @@ -634,7 +563,7 @@ void ImGuiDialog::Display() { if (!active) OnClose(); } -/* +/* Notification handling, borrowed heavily from https://github.com/patrickcjk/imgui-notify Added: - permanent discardable notifications @@ -741,7 +670,7 @@ struct Notification } else if(elapsed > FADE_TIME + duration) { // disappearing color.w = 1.0f - (elapsed - FADE_TIME - duration) / FADE_TIME; } else { // steady - color.w = 1.0; + color.w = 1.0; } if(h < height) { @@ -885,6 +814,38 @@ namespace ImGui { return ret; } + DLLEXPORT bool SliderScalarReset(const char* label, ImGuiDataType dtype, const size_t t_size, void* v, const void *v_min, const void *v_max, const void *v_default, const char* display_format) + { + bool ret = ImGui::SliderScalar(label, dtype, v, v_min, v_max, display_format); + if (ImGui::BeginPopupContextItem(label)) + { + char buf[64]; + char fmt[64]; + snprintf(fmt, 64, "Reset to %s", display_format); + if (dtype == ImGuiDataType_S32 || dtype == ImGuiDataType_U32) + snprintf(buf, 64, fmt, *(const ImU32*)v_default); + if (dtype == ImGuiDataType_S64 || dtype == ImGuiDataType_U64) + snprintf(buf, 64, fmt, *(const ImU64*)v_default); + if (dtype == ImGuiDataType_Float) + snprintf(buf, 64, fmt, *(const float*)v_default); + if (dtype == ImGuiDataType_Double) + snprintf(buf, 64, fmt, *(const double*)v_default); + if (dtype == ImGuiDataType_S8) + snprintf(buf, 64, fmt, *(const ImS8*)v_default); + if (dtype == ImGuiDataType_U8) + snprintf(buf, 64, fmt, *(const ImU8*)v_default); + if (dtype == ImGuiDataType_S16) + snprintf(buf, 64, fmt, *(const ImS16*)v_default); + if (dtype == ImGuiDataType_U16) + snprintf(buf, 64, fmt, *(const ImU16*)v_default); + if (ImGui::MenuItem(buf)) + memcpy(v, v_default, t_size); + ImGui::MenuItem("Close"); + ImGui::EndPopup(); + } + return ret; + } + DLLEXPORT void PushFont(ImGuiFont f) { ImGui::PushFont(g_pOrbiter->DlgMgr()->GetFont(f)); diff --git a/Src/Orbiter/DlgMgr.h b/Src/Orbiter/DlgMgr.h index 292cf6ad6..68edc3d89 100644 --- a/Src/Orbiter/DlgMgr.h +++ b/Src/Orbiter/DlgMgr.h @@ -22,10 +22,10 @@ struct DIALOGENTRY { struct DIALOGENTRY *prev, *next; }; -class DialogManager { +class DialogManager : public oapi::ImCtxBase { public: DialogManager(Orbiter *orbiter, HWND hAppWnd); - ~DialogManager(); + ~DialogManager() override; void Init (HWND hAppWnd); void Clear (); @@ -49,7 +49,7 @@ class DialogManager { DlgType *MakeEntry (HINSTANCE hInst = 0, void *context = 0) { if (!hInst) hInst = g_pOrbiter->GetInstance(); - HWND hParent = g_pOrbiter->GetRenderWnd(); + HWND hParent = g_pOrbiter->GetRenderWnd()->Win32Handle(); DlgType *pDlg = new DlgType (hInst, hParent, context); AddEntry (pDlg); return pDlg; @@ -225,10 +225,14 @@ class DialogManager { private: void InitImGui(); void ShutdownImGui(); - ImFont *defaultFont; - ImFont *monoFont; +protected: + friend Orbiter; + // this only handles event handling for the case where WinAPI is *not* used. + bool ConsumeEvent(const SDL_Event &event, bool &wantsOut) override; + bool BeginFrame() override; + void EndFrame() override; }; INT_PTR OrbiterDefDialogProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -#endif // !__DLGMGR_H \ No newline at end of file +#endif // !__DLGMGR_H diff --git a/Src/Orbiter/FlightRecorder.cpp b/Src/Orbiter/FlightRecorder.cpp index 8f748f58e..7439c3e43 100644 --- a/Src/Orbiter/FlightRecorder.cpp +++ b/Src/Orbiter/FlightRecorder.cpp @@ -923,7 +923,7 @@ void Orbiter::FRecorder_Play () g_pOrbiter->Timejump(tgtmjd, PROP_ORBITAL_FIXEDSURF); } } else if (!_strnicmp (s, "ENDSESSION", 10)) { - if (hRenderWnd) PostMessage (hRenderWnd, WM_CLOSE, 0, 0); + if (hRenderWnd) PostMessage (hRenderWnd->Win32Handle(), WM_CLOSE, 0, 0); } } *FRsys_stream >> frec_sys_simt; // read time for next event diff --git a/Src/Orbiter/GraphicsAPI.cpp b/Src/Orbiter/GraphicsAPI.cpp index 4681cfbe6..8455d9271 100644 --- a/Src/Orbiter/GraphicsAPI.cpp +++ b/Src/Orbiter/GraphicsAPI.cpp @@ -4,20 +4,22 @@ #define STRICT 1 #define OAPI_IMPLEMENTATION -#include "Orbiter.h" -#include "Launchpad.h" -#include "LpadTab.h" -#include "TabVideo.h" -#include "Psys.h" -#include "Pane.h" -#include "VCockpit.h" #include "GraphicsAPI.h" #include "DlgMgr.h" +#include "Launchpad.h" #include "Log.h" +#include "LpadTab.h" +#include "Orbiter.h" +#include "Pane.h" +#include "Psys.h" +#include "TabVideo.h" #include "Util.h" +#include "VCockpit.h" #include "resource.h" -#include + +#include #include +#include namespace fs = std::filesystem; using std::min; @@ -41,7 +43,6 @@ OAPIFUNC INT_PTR CALLBACK LaunchpadVideoWndProc (HWND hWnd, UINT uMsg, WPARAM wP GraphicsClient::GraphicsClient (HINSTANCE hInstance): Module (hInstance) { - hOrbiterInst = g_pOrbiter->GetInstance(); VideoData.fullscreen = false; VideoData.forceenum = true; VideoData.trystencil = false; @@ -65,7 +66,7 @@ GraphicsClient::GraphicsClient (HINSTANCE hInstance): Module (hInstance) ); if (hr != S_OK) m_pIWICFactory = NULL; - + } // ====================================================================== @@ -81,12 +82,12 @@ GraphicsClient::~GraphicsClient () bool GraphicsClient::clbkInitialise () { // Register a window class for the render window - WNDCLASS wndClass = {0, ::WndProc, 0, 0, hModule, - LoadIcon (g_pOrbiter->GetInstance(), MAKEINTRESOURCE(IDI_MAIN_ICON)), - LoadCursor (NULL, IDC_ARROW), - (HBRUSH)GetStockObject (WHITE_BRUSH), - NULL, strWndClass}; - RegisterClass (&wndClass); + // WNDCLASS wndClass = {0, ::WndProc, 0, 0, hModule, + // LoadIcon (g_pOrbiter->GetInstance(), MAKEINTRESOURCE(IDI_MAIN_ICON)), + // LoadCursor (NULL, IDC_ARROW), + // (HBRUSH)GetStockObject (WHITE_BRUSH), + // NULL, strWndClass}; + // RegisterClass (&wndClass); if (clbkUseLaunchpadVideoTab() && g_pOrbiter->Launchpad()) { hVid = g_pOrbiter->Launchpad()->GetTab(PG_VID)->TabWnd(); @@ -268,20 +269,17 @@ const void *GraphicsClient::GetConfigParam (DWORD paramtype) const // ====================================================================== -HWND GraphicsClient::clbkCreateRenderWindow () -{ - HWND hWnd; +std::shared_ptr GraphicsClient::clbkCreateRenderWindow() { + std::shared_ptr window; - if (VideoData.fullscreen) { - hWnd = CreateWindow (strWndClass, "", // dummy window - WS_POPUP | WS_EX_TOPMOST| WS_VISIBLE, - CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, 0, 0, hModule, (LPVOID)this); - } else { - hWnd = CreateWindow (strWndClass, "", - WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_VISIBLE, - CW_USEDEFAULT, CW_USEDEFAULT, VideoData.winw, VideoData.winh, 0, 0, hModule, (LPVOID)this); - } - return hWnd; + if (VideoData.fullscreen) { + window = std::make_shared("", 10, 10, + SDL_WINDOW_FULLSCREEN); + } else { + window = std::make_shared("", VideoData.winw, + VideoData.winh, 0); + } + return window; } // ====================================================================== @@ -429,7 +427,7 @@ HBITMAP ReadImageFromDecoder (IWICImagingFactory *m_pIWICFactory, IWICBitmapDeco HBITMAP GraphicsClient::ReadImageFromMemory (BYTE *pBuf, DWORD nBuf, UINT w, UINT h) { IWICBitmapDecoder *piDecoder = NULL; - + IWICStream *piStream; m_pIWICFactory->CreateStream(&piStream); piStream->InitializeFromMemory(pBuf,nBuf); @@ -645,40 +643,25 @@ bool GraphicsClient::clbkCopyBitmap (SURFHANDLE pdds, HBITMAP hbm, // ====================================================================== -HWND GraphicsClient::InitRenderWnd (HWND hWnd) -{ - if (!hWnd) { // create a dummy window - hWnd = CreateWindow (strWndClass, "", - WS_POPUP | WS_VISIBLE, - CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, 0, 0, hModule, 0); - } - SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG_PTR)this); - // store class instance with window for access in the message handler - - char title[256], cbuf[128]; - extern const TCHAR *g_strAppTitle; - strcpy (title, g_strAppTitle); - GetWindowText (hWnd, cbuf, 128); - if (cbuf[0]) { - strcat (title, " "); - strcat (title, cbuf); - } - SetWindowText (hWnd, title); - hRenderWnd = hWnd; - return hRenderWnd; + +extern const TCHAR* g_strAppTitle; + +void GraphicsClient::InitRenderWnd( + std::shared_ptr &window) { + if (!window) { + window = std::make_shared("", 10, 10, 0); + } + + auto title = std::string(g_strAppTitle) + " " + + SDL_GetWindowTitle(window->Inner()); + SDL_SetWindowTitle(window->Inner(), title.c_str()); } // ====================================================================== - -LRESULT GraphicsClient::RenderWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - // graphics-specific stuff to go here - default: - return g_pOrbiter->MsgProc (hWnd, uMsg, wParam, lParam); - } - return DefWindowProc (hWnd, uMsg, wParam, lParam); +bool GraphicsClient::RenderWndProc(const SDL_Event &event, + bool &wantsOut) { + return g_pOrbiter->MsgProc(event, wantsOut); } // ====================================================================== @@ -883,27 +866,6 @@ void ScreenAnnotation::Render () // ====================================================================== // Nonmember functions -//----------------------------------------------------------------------- -// Name: WndProc() -// Desc: Static msg handler which passes messages from the render window -// to the application class. -//----------------------------------------------------------------------- -DLLEXPORT LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - GraphicsClient *gc = (GraphicsClient*)GetWindowLongPtr (hWnd, GWLP_USERDATA); - if (gc) return gc->RenderWndProc (hWnd, uMsg, wParam, lParam); - else return DefWindowProc (hWnd, uMsg, wParam, lParam); -} - -// ====================================================================== - -DLLEXPORT INT_PTR CALLBACK LaunchpadVideoWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - GraphicsClient *gc = (GraphicsClient*)GetWindowLongPtr (hWnd, GWLP_USERDATA); - if (gc) return gc->LaunchpadVideoWndProc (hWnd, uMsg, wParam, lParam); - else return FALSE; -} - // ====================================================================== // API interface: register/unregister the graphics client @@ -916,3 +878,206 @@ DLLEXPORT bool oapiUnregisterGraphicsClient (GraphicsClient *gc) { return g_pOrbiter->RemoveGraphicsClient (gc); } + +DLLEXPORT bool WithImCtx::ConsumeEvent(const SDL_Event &event, + bool &wantsOut) const { + return inner->ConsumeEvent(event, wantsOut); +}; + +DLLEXPORT bool WithImCtx::BeginFrame() const { return inner->BeginFrame(); } + +DLLEXPORT void WithImCtx::EndFrame() const { return inner->EndFrame(); } + +DLLEXPORT WithImCtx::WithImCtx(ImCtxBase *inner, ImGuiContext *lastContext) + : inner(inner), lastContext(lastContext) {} + +DLLEXPORT WithImCtx::~WithImCtx() { + if (lastContext) + ImGui::SetCurrentContext(lastContext); +} + +DLLEXPORT ImCtxBase *WithImCtx::operator->() const { return inner; } + +DLLEXPORT ImCtxBase *WithImCtx::Inner() const { return inner; } + +DLLEXPORT WithImCtx ImCtxBase::PushLocal() { + const auto lastContext = ImGui::GetCurrentContext(); + ImGui::SetCurrentContext(m_context); + return {this, lastContext}; +}; + +// Styling adapted from +// https://gist.github.com/dougbinks/8089b4bbaccaaf6fa204236978d165a9 +static void ImGuiSetStyle(bool bStyleDark_, float alpha_) { + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + // ImGui::StyleColorsClassic(); + // ImGui::StyleColorsLight(); + ImGuiStyle &style = ImGui::GetStyle(); + + style.Alpha = 1.0f; + style.FrameRounding = 3.0f; + style.WindowRounding = 3.0f; + style.ChildRounding = 3.0f; + style.PopupRounding = 3.0f; + style.ScrollbarRounding = 3.0f; + style.GrabRounding = 3.0f; + style.TabRounding = 3.0f; + style.WindowMenuButtonPosition = ImGuiDir_Right; + style.Colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + style.Colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); + style.Colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + style.Colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); + style.Colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); + style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + style.Colors[ImGuiCol_FrameBg] = ImVec4(0.63f, 0.13f, 0.13f, 0.50f); + style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.94f, 0.41f, 0.36f, 0.50f); + style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.78f, 0.27f, 0.24f, 0.50f); + style.Colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); + style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.63f, 0.13f, 0.13f, 0.75f); + style.Colors[ImGuiCol_TitleBgCollapsed] = + ImVec4(0.00f, 0.00f, 0.00f, 0.51f); + style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); + style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); + style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); + style.Colors[ImGuiCol_ScrollbarGrabHovered] = + ImVec4(0.41f, 0.41f, 0.41f, 1.00f); + style.Colors[ImGuiCol_ScrollbarGrabActive] = + ImVec4(0.51f, 0.51f, 0.51f, 1.00f); + // Not very set on the white checkmark, but the light red didn't look the + // best either... TODO!!! + style.Colors[ImGuiCol_CheckMark] = ImVec4(0.94f, 0.41f, 0.36f, 1.00f); + style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.94f, 0.41f, 0.36f, 0.66f); + style.Colors[ImGuiCol_SliderGrabActive] = + ImVec4(0.94f, 0.41f, 0.36f, 0.66f); + style.Colors[ImGuiCol_Button] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); + style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.94f, 0.41f, 0.36f, 0.54f); + style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.78f, 0.27f, 0.24f, 0.54f); + style.Colors[ImGuiCol_Header] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); + style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.94f, 0.41f, 0.36f, 0.66f); + style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.78f, 0.27f, 0.24f, 0.66f); + style.Colors[ImGuiCol_Separator] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); + style.Colors[ImGuiCol_SeparatorHovered] = + ImVec4(0.94f, 0.41f, 0.36f, 0.66f); + style.Colors[ImGuiCol_SeparatorActive] = ImVec4(0.78f, 0.27f, 0.24f, 0.66f); + style.Colors[ImGuiCol_ResizeGrip] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); + style.Colors[ImGuiCol_ResizeGripHovered] = + ImVec4(0.94f, 0.41f, 0.36f, 0.66f); + style.Colors[ImGuiCol_ResizeGripActive] = + ImVec4(0.78f, 0.27f, 0.24f, 0.66f); + style.Colors[ImGuiCol_TabHovered] = ImVec4(0.94f, 0.41f, 0.36f, 0.66f); + style.Colors[ImGuiCol_Tab] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); + style.Colors[ImGuiCol_TabSelected] = ImVec4(0.78f, 0.27f, 0.24f, 0.66f); + style.Colors[ImGuiCol_TabSelectedOverline] = + ImVec4(0.94f, 0.41f, 0.36f, 1.00f); + style.Colors[ImGuiCol_TabDimmed] = ImVec4(0.63f, 0.13f, 0.13f, 0.13f); + style.Colors[ImGuiCol_TabDimmedSelected] = + ImVec4(0.78f, 0.27f, 0.24f, 0.13f); + style.Colors[ImGuiCol_TabDimmedSelectedOverline] = + ImVec4(0.94f, 0.41f, 0.36f, 0.13f); + style.Colors[ImGuiCol_DockingPreview] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); + style.Colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); + style.Colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + style.Colors[ImGuiCol_PlotLinesHovered] = + ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + style.Colors[ImGuiCol_PlotHistogramHovered] = + ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + style.Colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f); + style.Colors[ImGuiCol_TableBorderStrong] = + ImVec4(0.31f, 0.31f, 0.35f, 1.00f); + style.Colors[ImGuiCol_TableBorderLight] = + ImVec4(0.23f, 0.23f, 0.25f, 1.00f); + style.Colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + style.Colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); + style.Colors[ImGuiCol_TextLink] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + style.Colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); + style.Colors[ImGuiCol_NavCursor] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); + style.Colors[ImGuiCol_NavWindowingHighlight] = + ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + style.Colors[ImGuiCol_NavWindowingDimBg] = + ImVec4(0.80f, 0.80f, 0.80f, 0.20f); + style.Colors[ImGuiCol_ModalWindowDimBg] = + ImVec4(0.80f, 0.80f, 0.80f, 0.35f); +} + +DLLEXPORT ImCtxBase::ImCtxBase(Orbiter *app, ImGuiContext *context) + : m_app(app), m_context(context) { +#ifdef _DEBUG + IMGUI_CHECKVERSION(); +#endif + const auto savedContext = ImGui::GetCurrentContext(); + ImGui::SetCurrentContext(m_context); + + ImGuiIO &io = ImGui::GetIO(); + if (!m_app->IsFullscreen()) + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + io.IniFilename = nullptr; + io.LogFilename = nullptr; + + ImGuiSetStyle(false, 1.0f); + + ImFontConfig config; + + static constexpr ImWchar icons_ranges[] = {ICON_MIN_FA, ICON_MAX_FA, 0}; + ImFontConfig icons_config; + icons_config.MergeMode = true; + icons_config.PixelSnapH = true; + icons_config.FontDataOwnedByAtlas = false; + icons_config.GlyphOffset.y = 1; + + const CFG_FONTPRM &prm = m_app->Cfg()->CfgFontPrm; + + auto defaultFontFile = + std::string(prm.ImGui_FontName).append("-Regular.ttf"); + auto italicFontFile = std::string(prm.ImGui_FontName).append("-Italic.ttf"); + auto boldFontFile = std::string(prm.ImGui_FontName).append("-Bold.ttf"); + auto boldItalicFontFile = + std::string(prm.ImGui_FontName).append("-BoldItalic.ttf"); + + m_defaultFont = io.Fonts->AddFontFromFileTTF( + defaultFontFile.c_str(), prm.ImGui_FontSize, &config, + ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, + &icons_config, icons_ranges); + m_italicFont = io.Fonts->AddFontFromFileTTF( + italicFontFile.c_str(), prm.ImGui_FontSize, &config, + ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, + &icons_config, icons_ranges); + m_boldFont = io.Fonts->AddFontFromFileTTF( + boldFontFile.c_str(), prm.ImGui_FontSize, &config, + ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, + &icons_config, icons_ranges); + m_boldItalicFont = io.Fonts->AddFontFromFileTTF( + boldItalicFontFile.c_str(), prm.ImGui_FontSize, &config, + ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, + &icons_config, icons_ranges); + m_hdgFont = io.Fonts->AddFontFromFileTTF( + defaultFontFile.c_str(), prm.ImGui_FontSize * 1.5f, &config, + ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, + &icons_config, icons_ranges); + // weird alignment issues otherwise, yippee (sarcastic) + config.GlyphOffset.y = 1; + m_monoFont = io.Fonts->AddFontFromFileTTF( + "Cousine-Regular.ttf", prm.ImGui_FontSize, &config, + ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + io.Fonts->Build(); + + if (savedContext) + ImGui::SetCurrentContext(savedContext); +} + +DLLEXPORT ImCtxBase::~ImCtxBase() { + const auto savedContext = ImGui::GetCurrentContext(); + ImGui::SetCurrentContext(m_context); + ImGui::DestroyContext(); + if (savedContext) + ImGui::SetCurrentContext(savedContext); +} diff --git a/Src/Orbiter/Keymap.cpp b/Src/Orbiter/Keymap.cpp index 86c216c5c..b39254ffe 100644 --- a/Src/Orbiter/Keymap.cpp +++ b/Src/Orbiter/Keymap.cpp @@ -114,41 +114,41 @@ struct { WORD defkey; const char *itemstr; } lkeyspec[LKEY_COUNT] = { - {OAPI_KEY_LEFT | KMOD_ALT, "CockpitCamRotateLeft"}, - {OAPI_KEY_RIGHT | KMOD_ALT, "CockpitCamRotateRight"}, - {OAPI_KEY_UP | KMOD_ALT, "CockpitCamRotateUp"}, - {OAPI_KEY_DOWN | KMOD_ALT, "CockpitCamRotateDown"}, - {OAPI_KEY_DOWN | KMOD_CTRL | KMOD_ALT, "CockpitCamDontLean"}, - {OAPI_KEY_UP | KMOD_CTRL | KMOD_ALT, "CockpitCamLeanForward"}, - {OAPI_KEY_LEFT | KMOD_CTRL | KMOD_ALT, "CockpitCamLeanLeft"}, - {OAPI_KEY_RIGHT | KMOD_CTRL | KMOD_ALT, "CockpitCamLeanRight"}, + {OAPI_KEY_LEFT | OKMOD_ALT, "CockpitCamRotateLeft"}, + {OAPI_KEY_RIGHT | OKMOD_ALT, "CockpitCamRotateRight"}, + {OAPI_KEY_UP | OKMOD_ALT, "CockpitCamRotateUp"}, + {OAPI_KEY_DOWN | OKMOD_ALT, "CockpitCamRotateDown"}, + {OAPI_KEY_DOWN | OKMOD_CTRL | OKMOD_ALT, "CockpitCamDontLean"}, + {OAPI_KEY_UP | OKMOD_CTRL | OKMOD_ALT, "CockpitCamLeanForward"}, + {OAPI_KEY_LEFT | OKMOD_CTRL | OKMOD_ALT, "CockpitCamLeanLeft"}, + {OAPI_KEY_RIGHT | OKMOD_CTRL | OKMOD_ALT, "CockpitCamLeanRight"}, {OAPI_KEY_HOME, "CockpitResetCam"}, {OAPI_KEY_LEFT, "PanelShiftLeft"}, {OAPI_KEY_RIGHT, "PanelShiftRight"}, {OAPI_KEY_UP, "PanelShiftUp"}, {OAPI_KEY_DOWN, "PanelShiftDown"}, - {OAPI_KEY_LEFT | KMOD_CTRL, "PanelSwitchLeft"}, - {OAPI_KEY_RIGHT | KMOD_CTRL, "PanelSwitchRight"}, - {OAPI_KEY_UP | KMOD_CTRL, "PanelSwitchUp"}, - {OAPI_KEY_DOWN | KMOD_CTRL, "PanelSwitchDown"}, - {OAPI_KEY_LEFT | KMOD_CTRL, "TrackCamRotateLeft"}, - {OAPI_KEY_RIGHT | KMOD_CTRL, "TrackCamRotateRight"}, - {OAPI_KEY_UP | KMOD_CTRL, "TrackCamRotateUp"}, - {OAPI_KEY_DOWN | KMOD_CTRL, "TrackCamRotateDown"}, + {OAPI_KEY_LEFT | OKMOD_CTRL, "PanelSwitchLeft"}, + {OAPI_KEY_RIGHT | OKMOD_CTRL, "PanelSwitchRight"}, + {OAPI_KEY_UP | OKMOD_CTRL, "PanelSwitchUp"}, + {OAPI_KEY_DOWN | OKMOD_CTRL, "PanelSwitchDown"}, + {OAPI_KEY_LEFT | OKMOD_CTRL, "TrackCamRotateLeft"}, + {OAPI_KEY_RIGHT | OKMOD_CTRL, "TrackCamRotateRight"}, + {OAPI_KEY_UP | OKMOD_CTRL, "TrackCamRotateUp"}, + {OAPI_KEY_DOWN | OKMOD_CTRL, "TrackCamRotateDown"}, {OAPI_KEY_NEXT, "TrackCamAdvance"}, {OAPI_KEY_PRIOR, "TrackCamRetreat"}, {OAPI_KEY_LEFT, "GroundCamTiltLeft"}, {OAPI_KEY_RIGHT, "GroundCamTiltRight"}, {OAPI_KEY_UP, "GroundCamTiltUp"}, {OAPI_KEY_DOWN, "GroundCamTiltDown"}, - {OAPI_KEY_ADD | KMOD_CTRL, "IncMainThrust"}, - {OAPI_KEY_SUBTRACT | KMOD_CTRL, "DecMainThrust"}, + {OAPI_KEY_ADD | OKMOD_CTRL, "IncMainThrust"}, + {OAPI_KEY_SUBTRACT | OKMOD_CTRL, "DecMainThrust"}, {OAPI_KEY_MULTIPLY, "KillMainRetroThrust"}, {OAPI_KEY_ADD, "OverrideFullMainThrust"}, {OAPI_KEY_SUBTRACT, "OverrideFullRetroThrust"}, {OAPI_KEY_NUMPAD0, "IncHoverThrust"}, {OAPI_KEY_DECIMAL, "DecHoverThrust"}, - {OAPI_KEY_DIVIDE | KMOD_CTRL, "RCSEnable"}, + {OAPI_KEY_DIVIDE | OKMOD_CTRL, "RCSEnable"}, {OAPI_KEY_DIVIDE, "RCSMode"}, {OAPI_KEY_NUMPAD2, "RCSPitchUp"}, {OAPI_KEY_NUMPAD8, "RCSPitchDown"}, @@ -162,18 +162,18 @@ struct { {OAPI_KEY_NUMPAD3, "RCSRight"}, {OAPI_KEY_NUMPAD6, "RCSForward"}, {OAPI_KEY_NUMPAD9, "RCSBack"}, - {OAPI_KEY_NUMPAD2 | KMOD_CTRL, "LPRCSPitchUp"}, - {OAPI_KEY_NUMPAD8 | KMOD_CTRL, "LPRCSPitchDown"}, - {OAPI_KEY_NUMPAD1 | KMOD_CTRL, "LPRCSYawLeft"}, - {OAPI_KEY_NUMPAD3 | KMOD_CTRL, "LPRCSYawRight"}, - {OAPI_KEY_NUMPAD4 | KMOD_CTRL, "LPRCSBankLeft"}, - {OAPI_KEY_NUMPAD6 | KMOD_CTRL, "LPRCSBankRight"}, - {OAPI_KEY_NUMPAD2 | KMOD_CTRL, "LPRCSUp"}, - {OAPI_KEY_NUMPAD8 | KMOD_CTRL, "LPRCSDown"}, - {OAPI_KEY_NUMPAD1 | KMOD_CTRL, "LPRCSLeft"}, - {OAPI_KEY_NUMPAD3 | KMOD_CTRL, "LPRCSRight"}, - {OAPI_KEY_NUMPAD6 | KMOD_CTRL, "LPRCSForward"}, - {OAPI_KEY_NUMPAD9 | KMOD_CTRL, "LPRCSBack"}, + {OAPI_KEY_NUMPAD2 | OKMOD_CTRL, "LPRCSPitchUp"}, + {OAPI_KEY_NUMPAD8 | OKMOD_CTRL, "LPRCSPitchDown"}, + {OAPI_KEY_NUMPAD1 | OKMOD_CTRL, "LPRCSYawLeft"}, + {OAPI_KEY_NUMPAD3 | OKMOD_CTRL, "LPRCSYawRight"}, + {OAPI_KEY_NUMPAD4 | OKMOD_CTRL, "LPRCSBankLeft"}, + {OAPI_KEY_NUMPAD6 | OKMOD_CTRL, "LPRCSBankRight"}, + {OAPI_KEY_NUMPAD2 | OKMOD_CTRL, "LPRCSUp"}, + {OAPI_KEY_NUMPAD8 | OKMOD_CTRL, "LPRCSDown"}, + {OAPI_KEY_NUMPAD1 | OKMOD_CTRL, "LPRCSLeft"}, + {OAPI_KEY_NUMPAD3 | OKMOD_CTRL, "LPRCSRight"}, + {OAPI_KEY_NUMPAD6 | OKMOD_CTRL, "LPRCSForward"}, + {OAPI_KEY_NUMPAD9 | OKMOD_CTRL, "LPRCSBack"}, {OAPI_KEY_A, "NMHoldAltitude"}, {OAPI_KEY_L, "NMHLevel"}, {OAPI_KEY_LBRACKET, "NMPrograde"}, @@ -181,43 +181,43 @@ struct { {OAPI_KEY_SEMICOLON, "NMNormal"}, {OAPI_KEY_APOSTROPHE, "NMAntinormal"}, {OAPI_KEY_NUMPAD5, "NMKillrot"}, - {OAPI_KEY_D | KMOD_CTRL, "Undock"}, + {OAPI_KEY_D | OKMOD_CTRL, "Undock"}, {OAPI_KEY_DELETE, "IncElevatorTrim"}, {OAPI_KEY_INSERT, "DecElevatorTrim"}, {OAPI_KEY_COMMA, "WheelbrakeLeft"}, {OAPI_KEY_PERIOD, "WheelbrakeRight"}, - {OAPI_KEY_H | KMOD_CTRL, "HUD"}, + {OAPI_KEY_H | OKMOD_CTRL, "HUD"}, {OAPI_KEY_H, "HUDMode"}, - {OAPI_KEY_R | KMOD_CTRL, "HUDReference"}, - {OAPI_KEY_R | KMOD_CTRL | KMOD_ALT, "HUDTarget"}, - {OAPI_KEY_H | KMOD_ALT, "HUDColour"}, + {OAPI_KEY_R | OKMOD_CTRL, "HUDReference"}, + {OAPI_KEY_R | OKMOD_CTRL | OKMOD_ALT, "HUDTarget"}, + {OAPI_KEY_H | OKMOD_ALT, "HUDColour"}, {OAPI_KEY_T, "IncSimSpeed"}, {OAPI_KEY_R, "DecSimSpeed"}, {OAPI_KEY_X, "IncFOV"}, {OAPI_KEY_Z, "DecFOV"}, - {OAPI_KEY_X | KMOD_CTRL, "StepIncFOV"}, - {OAPI_KEY_Z | KMOD_CTRL, "StepDecFOV"}, + {OAPI_KEY_X | OKMOD_CTRL, "StepIncFOV"}, + {OAPI_KEY_Z | OKMOD_CTRL, "StepDecFOV"}, {OAPI_KEY_F4, "MainMenu"}, - {OAPI_KEY_F1 | KMOD_ALT, "DlgHelp"}, - {OAPI_KEY_F1 | KMOD_CTRL, "DlgCamera"}, - {OAPI_KEY_F2 | KMOD_CTRL, "DlgSimspeed"}, - {OAPI_KEY_F4 | KMOD_CTRL, "DlgCustomCmd"}, - {OAPI_KEY_F9 | KMOD_CTRL, "DlgVisualHelpers"}, - {OAPI_KEY_F5 | KMOD_CTRL, "DlgRecorder"}, - {OAPI_KEY_I | KMOD_CTRL, "DlgInfo"}, - {OAPI_KEY_M | KMOD_CTRL, "DlgMap"}, + {OAPI_KEY_F1 | OKMOD_ALT, "DlgHelp"}, + {OAPI_KEY_F1 | OKMOD_CTRL, "DlgCamera"}, + {OAPI_KEY_F2 | OKMOD_CTRL, "DlgSimspeed"}, + {OAPI_KEY_F4 | OKMOD_CTRL, "DlgCustomCmd"}, + {OAPI_KEY_F9 | OKMOD_CTRL, "DlgVisualHelpers"}, + {OAPI_KEY_F5 | OKMOD_CTRL, "DlgRecorder"}, + {OAPI_KEY_I | OKMOD_CTRL, "DlgInfo"}, + {OAPI_KEY_M | OKMOD_CTRL, "DlgMap"}, {OAPI_KEY_F1, "ToggleCamInternal"}, {OAPI_KEY_F2, "ToggleTrackMode"}, {OAPI_KEY_F8, "TogglePanelMode"}, {OAPI_KEY_F9, "TogglePlanetarium"}, - {OAPI_KEY_F9 | KMOD_ALT, "ToggleSurfaceLabels"}, - {OAPI_KEY_C | KMOD_CTRL, "ToggleRecPlay"}, - {OAPI_KEY_P | KMOD_CTRL, "Pause"}, - {OAPI_KEY_S | KMOD_CTRL, "Quicksave"}, - {OAPI_KEY_Q | KMOD_CTRL, "Quit"}, + {OAPI_KEY_F9 | OKMOD_ALT, "ToggleSurfaceLabels"}, + {OAPI_KEY_C | OKMOD_CTRL, "ToggleRecPlay"}, + {OAPI_KEY_P | OKMOD_CTRL, "Pause"}, + {OAPI_KEY_S | OKMOD_CTRL, "Quicksave"}, + {OAPI_KEY_Q | OKMOD_CTRL, "Quit"}, {OAPI_KEY_F3, "DlgSelectVessel"}, - {OAPI_KEY_F3 | KMOD_CTRL, "SelectPrevVessel"}, - {OAPI_KEY_SYSRQ | KMOD_CTRL, "DlgCapture"}, + {OAPI_KEY_F3 | OKMOD_CTRL, "SelectPrevVessel"}, + {OAPI_KEY_SYSRQ | OKMOD_CTRL, "DlgCapture"}, {OAPI_KEY_F6, "DlgOptions"} }; @@ -278,10 +278,10 @@ bool Keymap::IsLogicalKey (DWORD &key, char *kstate, int lfunc, bool clearkey) c bool Keymap::IsMatchingModifier (char *kstate, WORD key) const { WORD kmod; - if (kmod = (key & KMOD_CTRL)) { - if (kmod == KMOD_CTRL) { + if (kmod = (key & OKMOD_CTRL)) { + if (kmod == OKMOD_CTRL) { if (!KEYMOD_CONTROL(kstate)) return false; - } else if (kmod == KMOD_LCTRL) { + } else if (kmod == OKMOD_LCTRL) { if (!KEYMOD_LCONTROL(kstate)) return false; } else { if (!KEYMOD_RCONTROL(kstate)) return false; @@ -290,10 +290,10 @@ bool Keymap::IsMatchingModifier (char *kstate, WORD key) const if (KEYMOD_CONTROL(kstate)) return false; } - if (kmod = (key & KMOD_SHIFT)) { - if (kmod == KMOD_SHIFT) { + if (kmod = (key & OKMOD_SHIFT)) { + if (kmod == OKMOD_SHIFT) { if (!KEYMOD_SHIFT(kstate)) return false; - } else if (kmod == KMOD_LSHIFT) { + } else if (kmod == OKMOD_LSHIFT) { if (!KEYMOD_LSHIFT(kstate)) return false; } else { if (!KEYMOD_RSHIFT(kstate)) return false; @@ -302,10 +302,10 @@ bool Keymap::IsMatchingModifier (char *kstate, WORD key) const if (KEYMOD_SHIFT(kstate)) return false; } - if (kmod = (key & KMOD_ALT)) { - if (kmod == KMOD_ALT) { + if (kmod = (key & OKMOD_ALT)) { + if (kmod == OKMOD_ALT) { if (!KEYMOD_ALT(kstate)) return false; - } else if (kmod == KMOD_LALT) { + } else if (kmod == OKMOD_LALT) { if (!KEYMOD_LALT(kstate)) return false; } else { if (!KEYMOD_RALT(kstate)) return false; @@ -329,15 +329,15 @@ bool Keymap::ScanStr (char *cbuf, WORD &key) const for (;;) { tok = strtok (NULL, " "); if (!tok) break; - if (!_stricmp (tok, "LSHIFT")) key |= KMOD_LSHIFT; - else if (!_stricmp (tok, "RSHIFT")) key |= KMOD_RSHIFT; - else if (!_stricmp (tok, "SHIFT")) key |= KMOD_SHIFT; - else if (!_stricmp (tok, "LCTRL")) key |= KMOD_LCTRL; - else if (!_stricmp (tok, "RCTRL")) key |= KMOD_RCTRL; - else if (!_stricmp (tok, "CTRL")) key |= KMOD_CTRL; - else if (!_stricmp (tok, "LALT")) key |= KMOD_LALT; - else if (!_stricmp (tok, "RALT")) key |= KMOD_RALT; - else if (!_stricmp (tok, "ALT")) key |= KMOD_ALT; + if (!_stricmp (tok, "LSHIFT")) key |= OKMOD_LSHIFT; + else if (!_stricmp (tok, "RSHIFT")) key |= OKMOD_RSHIFT; + else if (!_stricmp (tok, "SHIFT")) key |= OKMOD_SHIFT; + else if (!_stricmp (tok, "LCTRL")) key |= OKMOD_LCTRL; + else if (!_stricmp (tok, "RCTRL")) key |= OKMOD_RCTRL; + else if (!_stricmp (tok, "CTRL")) key |= OKMOD_CTRL; + else if (!_stricmp (tok, "LALT")) key |= OKMOD_LALT; + else if (!_stricmp (tok, "RALT")) key |= OKMOD_RALT; + else if (!_stricmp (tok, "ALT")) key |= OKMOD_ALT; } return true; } @@ -352,25 +352,25 @@ char *Keymap::PrintStr (char *cbuf, WORD &key) const cbuf[0] = '\0'; } else { strcpy (cbuf, keyname[i].name); - if (kmod = (key & KMOD_SHIFT)) { + if (kmod = (key & OKMOD_SHIFT)) { switch (kmod) { - case KMOD_SHIFT: strcat (cbuf, " SHIFT"); break; - case KMOD_LSHIFT: strcat (cbuf, " LSHIFT"); break; - case KMOD_RSHIFT: strcat (cbuf, " RSHIFT"); break; + case OKMOD_SHIFT: strcat (cbuf, " SHIFT"); break; + case OKMOD_LSHIFT: strcat (cbuf, " LSHIFT"); break; + case OKMOD_RSHIFT: strcat (cbuf, " RSHIFT"); break; } } - if (kmod = (key & KMOD_CTRL)) { + if (kmod = (key & OKMOD_CTRL)) { switch (kmod) { - case KMOD_CTRL: strcat (cbuf, " CTRL"); break; - case KMOD_LCTRL: strcat (cbuf, " LCTRL"); break; - case KMOD_RCTRL: strcat (cbuf, " RCTRL"); break; + case OKMOD_CTRL: strcat (cbuf, " CTRL"); break; + case OKMOD_LCTRL: strcat (cbuf, " LCTRL"); break; + case OKMOD_RCTRL: strcat (cbuf, " RCTRL"); break; } } - if (kmod = (key & KMOD_ALT)) { + if (kmod = (key & OKMOD_ALT)) { switch (kmod) { - case KMOD_ALT: strcat (cbuf, " ALT"); break; - case KMOD_LALT: strcat (cbuf, " LALT"); break; - case KMOD_RALT: strcat (cbuf, " RALT"); break; + case OKMOD_ALT: strcat (cbuf, " ALT"); break; + case OKMOD_LALT: strcat (cbuf, " LALT"); break; + case OKMOD_RALT: strcat (cbuf, " RALT"); break; } } } diff --git a/Src/Orbiter/Keymap.h b/Src/Orbiter/Keymap.h index fd1daecd8..c5e0f7b6b 100644 --- a/Src/Orbiter/Keymap.h +++ b/Src/Orbiter/Keymap.h @@ -12,15 +12,15 @@ #include "Orbitersdk.h" // key modifier list -#define KMOD_LSHIFT 0x0100 -#define KMOD_RSHIFT 0x0200 -#define KMOD_SHIFT (KMOD_LSHIFT|KMOD_RSHIFT) -#define KMOD_LCTRL 0x0400 -#define KMOD_RCTRL 0x0800 -#define KMOD_CTRL (KMOD_LCTRL|KMOD_RCTRL) -#define KMOD_LALT 0x1000 -#define KMOD_RALT 0x2000 -#define KMOD_ALT (KMOD_LALT|KMOD_RALT) +#define OKMOD_LSHIFT 0x0100 +#define OKMOD_RSHIFT 0x0200 +#define OKMOD_SHIFT (OKMOD_LSHIFT|OKMOD_RSHIFT) +#define OKMOD_LCTRL 0x0400 +#define OKMOD_RCTRL 0x0800 +#define OKMOD_CTRL (OKMOD_LCTRL|OKMOD_RCTRL) +#define OKMOD_LALT 0x1000 +#define OKMOD_RALT 0x2000 +#define OKMOD_ALT (OKMOD_LALT|OKMOD_RALT) class Keymap { public: diff --git a/Src/Orbiter/MenuInfoBar.cpp b/Src/Orbiter/MenuInfoBar.cpp index 36acf51af..1f075589d 100644 --- a/Src/Orbiter/MenuInfoBar.cpp +++ b/Src/Orbiter/MenuInfoBar.cpp @@ -583,7 +583,7 @@ void MenuInfoBar::Update (double t) case CAMERA_GLOBALFRAME: strcpy (cbuf, "track (global frame)"); break; case CAMERA_TARGETTOOBJECT: strcpy (cbuf, "target to "); strcat (cbuf, g_camera->GetDirRef()->Name()); break; case CAMERA_TARGETFROMOBJECT: strcpy (cbuf, "target from "); strcat (cbuf, g_camera->GetDirRef()->Name()); break; - case CAMERA_GROUNDOBSERVER: + case CAMERA_GROUNDOBSERVER: strcpy (cbuf, "ground "); strcat (cbuf, g_camera->GroundObserver_TargetLock() ? "(tgt-lock)" : "(free)"); break; @@ -624,11 +624,11 @@ void MenuInfoBar::Update (double t) } } -bool MenuInfoBar::ProcessMouse (UINT event, DWORD state, DWORD x, DWORD y) +bool MenuInfoBar::ProcessMouse (const SDL_Event &event, DWORD x, DWORD y) { x = (DWORD)(x / transf.m11); // account for menu squeezing - if (event == WM_MOUSEMOVE) { + if (event.type == SDL_EVENT_MOUSE_MOTION) { if (menumode == 2) { if (y <= scrollzone && menustate != 1) { menustate = 2; @@ -658,7 +658,7 @@ bool MenuInfoBar::ProcessMouse (UINT event, DWORD state, DWORD x, DWORD y) itemHighlight = item; } } - if (event == WM_LBUTTONDOWN && itemHighlight >= 0) { + if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_LEFT && itemHighlight >= 0) { switch (itemHighlight) { case 0: g_pOrbiter->DlgMgr()->EnsureEntry (); @@ -697,11 +697,11 @@ bool MenuInfoBar::ProcessMouse (UINT event, DWORD state, DWORD x, DWORD y) return true; case 11: g_pOrbiter->PreCloseSession(); - DestroyWindow (g_pOrbiter->GetRenderWnd()); + // DestroyWindow (g_pOrbiter->GetRenderWnd()); return true; } } - if (event == WM_RBUTTONDOWN && y <= scrollpos && x >= menuX && x < menuX+menuW) { + if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_LEFT && y <= scrollpos && x >= menuX && x < menuX+menuW) { g_pOrbiter->DlgMgr()->EnsureEntry (); return true; } diff --git a/Src/Orbiter/MenuInfoBar.h b/Src/Orbiter/MenuInfoBar.h index 127527c5c..a8e888e91 100644 --- a/Src/Orbiter/MenuInfoBar.h +++ b/Src/Orbiter/MenuInfoBar.h @@ -27,7 +27,7 @@ class MenuInfoBar { MenuInfoBar (const Pane *_pane); ~MenuInfoBar (); void Update (double t); - bool ProcessMouse (UINT event, DWORD state, DWORD x, DWORD y); + bool ProcessMouse (const SDL_Event &event, DWORD x, DWORD y); void Render (); void SetFOV (double fov); void SetWarp (double warp); @@ -87,4 +87,4 @@ class MenuInfoBar { MATRIX3 transf; }; -#endif // !__MENUINFOBAR_H \ No newline at end of file +#endif // !__MENUINFOBAR_H diff --git a/Src/Orbiter/MfdMap_old.cpp b/Src/Orbiter/MfdMap_old.cpp index 9a2df67d4..7c370b79d 100644 --- a/Src/Orbiter/MfdMap_old.cpp +++ b/Src/Orbiter/MfdMap_old.cpp @@ -341,15 +341,15 @@ void Instrument_MapOld::UpdateDraw (oapi::Sketchpad *skp) strcpy (datastr[0]+13, btgt->Name()); skp->Text (x1, y+dy, datastr[0], strlen(datastr[0])); btgt->EquPos (blng, blat); - sprintf (cbuf, " Pos: %6.2f%c %6.2f%c", + sprintf (cbuf, " Pos: %6.2f°%c %6.2f°%c", Deg(fabs(blng)), blng >= 0.0 ? 'E':'W', Deg(fabs(blat)), blat >= 0.0 ? 'N':'S'); skp->Text (x1, y+2*dy, cbuf, strlen (cbuf)); if (sp) { rad = refplanet->Size(); Orthodome (sp->lng, sp->lat, blng, blat, adist, hdg); - sprintf (cbuf, " Dst: %s (%0.2f)", DistStr (adist*rad), Deg(adist)); + sprintf (cbuf, " Dst: %s (%0.2f°)", DistStr (adist*rad), Deg(adist)); skp->Text (x1, y+3*dy, cbuf, strlen (cbuf)); - sprintf (cbuf, " Dir: %6.2f", Deg(hdg)); + sprintf (cbuf, " Dir: %6.2f°", Deg(hdg)); skp->Text (x1, y+4*dy, cbuf, strlen (cbuf)); } } else { @@ -366,7 +366,7 @@ void Instrument_MapOld::UpdateDraw (oapi::Sketchpad *skp) if (tel && otgt->ElRef() == refplanet) { double lng, lat, r; refplanet->GlobalToEquatorial (otgt->GPos(), lng, lat, r); - sprintf (cbuf, " Pos: %6.2f%c %6.2f%c", + sprintf (cbuf, " Pos: %6.2f°%c %6.2f°%c", Deg(fabs(lng)), lng >= 0.0 ? 'E':'W', Deg(fabs(lat)), lat >= 0.0 ? 'N':'S'); skp->Text (x1, y, cbuf, strlen (cbuf)); y += dy; sprintf (cbuf, " Alt: %s", DistStr (r - refplanet->Size())); @@ -557,7 +557,7 @@ void Instrument_MapOld::CalcOrbitProj (const Elements *el, const Planet *planet, for (i = 0; i < npt05; i++) { rl.Set (mul (R, Vector(cosp[i],0,sinp[i]))); x = rl.x, y = rl.y, z = rl.z; - lng = atan2 (z,x) + Pi; // maps start at -Pi (180W) + lng = atan2 (z,x) + Pi; // maps start at -Pi (180°W) lat = atan(y/std::hypot(x,z)); sp[i].x = (int)(lng*f1); if ((sp[i+npt05].x = sp[i].x + mapw05) >= mapw) sp[i+npt05].x -= mapw; diff --git a/Src/Orbiter/ModuleAPI.cpp b/Src/Orbiter/ModuleAPI.cpp index c491f083c..10363b059 100644 --- a/Src/Orbiter/ModuleAPI.cpp +++ b/Src/Orbiter/ModuleAPI.cpp @@ -63,7 +63,7 @@ void Module::clbkSimulationStart (RenderMode mode) { // backward compatibility call (deprecated) void (*opcOpenRenderViewport)(HWND,DWORD,DWORD,BOOL) = (void(*)(HWND,DWORD,DWORD,BOOL))GetProcAddress (hModule, "opcOpenRenderViewport"); - if (opcOpenRenderViewport) opcOpenRenderViewport (g_pOrbiter->GetRenderWnd(), g_pOrbiter->ViewW(), g_pOrbiter->ViewH(), g_pOrbiter->IsFullscreen()?TRUE:FALSE); + if (opcOpenRenderViewport) opcOpenRenderViewport (g_pOrbiter->GetRenderWnd()->Win32Handle(), g_pOrbiter->ViewW(), g_pOrbiter->ViewH(), g_pOrbiter->IsFullscreen()?TRUE:FALSE); } // ====================================================================== diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index b9d78a584..d9832706d 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -7,44 +7,49 @@ // Enable visual styles. Source: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773175(v=vs.85).aspx #pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") -#include -#include +// causes some collisions with Keymap.h +#define SDL_DISABLE_OLD_NAMES +#undef SDL_MAIN_USE_CALLBACKS +#include +#include +#include #include -#include #include -#include -#include "cmdline.h" -#include "D3d7util.h" -#include "D3dmath.h" -#include "Log.h" -#include "console_ng.h" -#include "State.h" + #include "Astro.h" +#include "Base.h" #include "Camera.h" -#include "Pane.h" -#include "Select.h" +#include "ConsoleManager.h" +#include "CustomControls.h" +#include "D3d7util.h" +#include "D3dmath.h" +#include "DialogWin.h" +#include "Dialogs.h" +#include "DlgCtrl.h" +#include "DlgHelp.h" // temporary #include "DlgMgr.h" -#include "Psys.h" -#include "Base.h" -#include "Vessel.h" -#include "resource.h" -#include "Orbiter.h" +#include "GraphicsAPI.h" +#include "Help.h" #include "Launchpad.h" +#include "Log.h" +#include "Memstat.h" #include "MenuInfoBar.h" -#include "Dialogs.h" -#include "DialogWin.h" +#include "Orbiter.h" +#include "Pane.h" +#include "Psys.h" #include "Script.h" -#include "Memstat.h" -#include "CustomControls.h" -#include "Help.h" +#include "Select.h" +#include "State.h" #include "Util.h" -#include "DlgHelp.h" // temporary +#include "Vessel.h" +#include "about.hpp" +#include "cmdline.h" +#include "console_ng.h" #include "htmlctrl.h" -#include "DlgCtrl.h" -#include "GraphicsAPI.h" -#include "ConsoleManager.h" #include "imgui.h" -#include "imgui_impl_win32.h" +#include "resource.h" + +#include #include namespace fs = std::filesystem; @@ -58,7 +63,7 @@ extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg //#define OUTPUT_TEXTURE_INFO -#define KEYDOWN(name,key) (name[key] & 0x80) +#define KEYDOWN(name,key) (name[key] & 0x80) const int MAX_TEXTURE_BUFSIZE = 8000000; // Texture manager buffer size. Should be determined from @@ -162,17 +167,13 @@ int _matherr(struct _exception *except ) return 0; } - -// ======================================================================= -// WinMain() -// Application entry containing message loop - - -INT WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, LPSTR strCmdLine, INT nCmdShow) -{ +int main(int argc, char **argv) { #ifdef _CRTDBG_MAP_ALLOC _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif + SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_EVENTS); + + SDL_SetAppMetadata("OpenOrbiter", SIG7, "uk.ac.ucl.medphys.orbit"); // Verify working directory char dir[1024]; @@ -185,12 +186,12 @@ INT WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, LPSTR strCmdLine, INT nCmdSh // If we're not running from actual console, hide the window if (ConsoleManager::IsConsoleExclusive()) ConsoleManager::ShowConsole(false); - + SetEnvironmentVars(); g_pOrbiter = new Orbiter; // application instance // Parse command line - orbiter::CommandLine::Parse(g_pOrbiter, strCmdLine); + orbiter::CommandLine::Parse(g_pOrbiter, argc, const_cast(argv)); // Initialise the log INITLOG("Orbiter.log", g_pOrbiter->Cfg()->CfgCmdlinePrm.bAppendLog); // init log file @@ -205,14 +206,14 @@ INT WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, LPSTR strCmdLine, INT nCmdSh srand(12345); LOGOUT("Timer precision: %g sec", fine_counter_step); + auto hInstance = GetModuleHandle(nullptr); + oapiRegisterCustomControls(hInstance); - HRESULT hr; // Create application - if (FAILED (hr = g_pOrbiter->Create (hInstance))) { + if (!g_pOrbiter->Create()) { LOGOUT("Application creation failed"); - MessageBox (NULL, "Application creation failed!\nTerminating.", - "Orbiter Error", MB_OK | MB_ICONERROR); + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Orbiter Error", "Application creation failed!\nTerminating.", NULL); return 0; } @@ -220,6 +221,7 @@ INT WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, LPSTR strCmdLine, INT nCmdSh g_pOrbiter->Run (); delete g_pOrbiter; + SDL_Quit(); return 0; } @@ -252,10 +254,10 @@ bool Orbiter::InitializeWorld (char *name) g_camera->ResizeViewport (viewW, viewH); if (g_psys) delete g_psys; - auto outputCallback = [](const char* msg, int line, void* callbackContext) - { + auto outputCallback = [](const char* msg, int line, void* callbackContext) + { Orbiter* _this = static_cast(callbackContext); - _this->OutputLoadStatus(msg, line); + _this->OutputLoadStatus(msg, line); }; g_psys = new PlanetarySystem(name, pConfig, outputCallback, this); TRACENEW @@ -299,6 +301,7 @@ Orbiter::Orbiter () fine_counter_step = 1.0 / freq; } + hInst = GetModuleHandle(nullptr); pDI = new DInput(this); TRACENEW pConfig = new Config; TRACENEW pState = NULL; @@ -328,6 +331,7 @@ Orbiter::Orbiter () bFastExit = false; bRoughType = false; bStartVideoTab = false; + bShouldQuit = false; //lstatus.bkgDC = 0; cfglen = 0; ncustomcmd = 0; @@ -357,46 +361,45 @@ Orbiter::~Orbiter () // Name: Create() // Desc: This method selects a D3D device //----------------------------------------------------------------------------- -HRESULT Orbiter::Create (HINSTANCE hInstance) +bool Orbiter::Create() { - if (m_pLaunchpad) return S_OK; // already created + if (m_pLaunchpad) return true; // already created - HRESULT hr; - WNDCLASS wndClass; + HRESULT hr; + WNDCLASS wndClass; - // Enable tab controls - InitCommonControls(); - LoadLibrary ("riched20.dll"); + // Enable tab controls + InitCommonControls(); + LoadLibrary ("riched20.dll"); - // parameter manager - parses from master config file - hInst = hInstance; pConfig->Load(MasterConfigFile); strcpy (cfgpath, pConfig->CfgDirPrm.ConfigDir); cfglen = strlen (cfgpath); - if (FAILED (hr = pDI->Create (hInstance))) return hr; + if (FAILED (hr = pDI->Create (hInst))) return false; - // validate configuration - if (pConfig->CfgJoystickPrm.Joy_idx > GetDInput()->NumJoysticks()) pConfig->CfgJoystickPrm.Joy_idx = 0; + // // validate configuration + // if (SDL_GetJoystickNameForID(pConfig->CfgJoystickPrm.Joy_idx) == nullptr) + // pConfig->CfgJoystickPrm.Joy_idx = 0; // Read key mapping from file (or write default keymap) if (!keymap.Read ("keymap.cfg")) keymap.Write ("keymap.cfg"); pState = new State(); TRACENEW - // Register main dialog window class - GetClassInfo (hInstance, "#32770", &wndClass); // override default dialog class - wndClass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_MAIN_ICON)); - RegisterClass (&wndClass); + // Register main dialog window class + GetClassInfo (hInst, "#32770", &wndClass); // override default dialog class + wndClass.hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDI_MAIN_ICON)); + RegisterClass (&wndClass); - // Find out if we are running under Linux/WINE - HKEY key; - long ret = RegOpenKeyEx (HKEY_CURRENT_USER, TEXT("Software\\Wine"), 0, KEY_QUERY_VALUE, &key); - RegCloseKey (key); - bWINEenv = (ret == ERROR_SUCCESS); + // Find out if we are running under Linux/WINE + HKEY key; + long ret = RegOpenKeyEx (HKEY_CURRENT_USER, TEXT("Software\\Wine"), 0, KEY_QUERY_VALUE, &key); + RegCloseKey (key); + bWINEenv = (ret == ERROR_SUCCESS); - // Register HTML viewer class - RegisterHtmlCtrl (hInstance, UseHtmlInline()); - CustomCtrl::RegisterClass (hInstance); + // Register HTML viewer class + RegisterHtmlCtrl (hInst, UseHtmlInline()); + CustomCtrl::RegisterClass (hInst); if (pConfig->CfgCmdlinePrm.bFastExit) SetFastExit(true); @@ -404,10 +407,10 @@ HRESULT Orbiter::Create (HINSTANCE hInstance) OpenVideoTab(); if (pConfig->CfgDemoPrm.bBkImage) { - hBk = CreateDialog (hInstance, MAKEINTRESOURCE(IDD_DEMOBK), NULL, BkMsgProc); + hBk = CreateDialog (hInst, MAKEINTRESOURCE(IDD_DEMOBK), NULL, BkMsgProc); ShowWindow (hBk, SW_MAXIMIZE); } - + // Create the "launchpad" main dialog window m_pLaunchpad = new orbiter::LaunchpadDialog (this); TRACENEW m_pLaunchpad->Create (bStartVideoTab); @@ -435,8 +438,8 @@ HRESULT Orbiter::Create (HINSTANCE hInstance) ActivateRoughType(); memstat = new MemStat; - - return S_OK; + + return true; } //----------------------------------------------------------------------------- @@ -576,7 +579,7 @@ HINSTANCE Orbiter::LoadModule (const char *path, const char *name) } } - // Can't initialize DirectX in DllMain(), let's do it over here (jarmonik 28.12.2023) + // Can't initialize DirectX in DllMain(), let's do it over here (jarmonik 28.12.2023) if (hDLL) { if (register_module == gclient && gclient != NULL) { if (gclient->clbkInitialise() == false) { @@ -584,7 +587,7 @@ HINSTANCE Orbiter::LoadModule (const char *path, const char *name) RemoveGraphicsClient(gclient); FreeLibrary(hDLL); LOGOUT_ERR("Client Initialization Failed. Unloading %s", name); - hDLL = NULL; + hDLL = NULL; return NULL; } } @@ -678,7 +681,8 @@ VOID Orbiter::Launch (const char *scenario) // Name: CreateRenderWindow() // Desc: Create the window used for rendering the scene //----------------------------------------------------------------------------- -HWND Orbiter::CreateRenderWindow (Config *pCfg, const char *scenario) +std::shared_ptr +Orbiter::CreateRenderWindow(Config *pCfg, const char* scenario) { DWORD i; @@ -687,37 +691,37 @@ HWND Orbiter::CreateRenderWindow (Config *pCfg, const char *scenario) LOGOUT("**** Creating simulation session"); m_pLaunchpad->Hide(); // hide launchpad dialog while the render window is visible - + if (gclient) { if(pState->SplashScreen()) gclient->clbkSetSplashScreen(pState->SplashScreen(), pState->SplashColor()); - hRenderWnd = gclient->InitRenderWnd (gclient->clbkCreateRenderWindow()); + hRenderWnd = std::move(gclient->clbkCreateRenderWindow()); + gclient->InitRenderWnd(hRenderWnd); GetRenderParameters (); } else { - hRenderWnd = NULL; + hRenderWnd = nullptr; m_pConsole = new orbiter::ConsoleNG(this); } - pDI->SetRenderWindow(hRenderWnd); - if (hRenderWnd) { - bActive = true; + pDI->SetRenderWindow(hRenderWnd->Win32Handle()); + bActive = true; - // Create keyboard device - if (!pDI->CreateKbdDevice ()) { - CloseSession (); - return 0; - } + // Create keyboard device + if (!pDI->CreateKbdDevice ()) { + CloseSession (); + return 0; + } - // Create joystick device - if (pDI->CreateJoyDevice ()) - plZ4 = 1; // invalidate + // Create joystick device + if (pDI->CreateJoyDevice ()) + plZ4 = 1; // invalidate } if (gclient) { // GDI resources - NOT VALID FOR ALL CLIENTS! - InitializeGDIResources (hRenderWnd); - pDlgMgr = new DialogManager (this, hRenderWnd); + InitializeGDIResources (hRenderWnd->Win32Handle()); + pDlgMgr = new DialogManager (this, hRenderWnd->Win32Handle()); // global dialog resources g_select = new Select(); TRACENEW @@ -962,7 +966,7 @@ void Orbiter::GetRenderParameters () gclient->clbkGetViewportSize (&viewW, &viewH); viewBPP = (gclient->clbkGetRenderParam (RP_COLOURDEPTH, &val) ? val:0); bFullscreen = gclient->clbkFullscreenMode(); - bUseStencil = (pConfig->CfgDevPrm.bTryStencil && + bUseStencil = (pConfig->CfgDevPrm.bTryStencil && gclient->clbkGetRenderParam (RP_STENCILDEPTH, &val) && val >= 1); } @@ -981,12 +985,16 @@ void Orbiter::BroadcastGlobalInit () HRESULT Orbiter::Render3DEnvironment (bool hidedialogs) { if (gclient) { - if(!hidedialogs) - pDlgMgr->ImGuiNewFrame(); + if(!hidedialogs) { + WithImCtx _ = pDlgMgr->PushLocal(); + pDlgMgr->ImGuiNewFrame(); + } gclient->clbkRenderScene (); Output2DData (); - if(!hidedialogs) - gclient->clbkImGuiRenderDrawData(); + if(!hidedialogs) { + WithImCtx _ = pDlgMgr->PushLocal(); + gclient->clbkImGuiRenderDrawData(); + } gclient->clbkDisplayFrame (); } return S_OK; @@ -998,74 +1006,84 @@ HRESULT Orbiter::Render3DEnvironment (bool hidedialogs) //----------------------------------------------------------------------------- void Orbiter::ScreenToClient (POINT *pt) const { - if (!IsFullscreen() && hRenderWnd) - ::ScreenToClient (hRenderWnd, pt); + // if (!IsFullscreen() && hRenderWnd) + // ::ScreenToClient (hRenderWnd, pt); } //----------------------------------------------------------------------------- // Name: Run() // Desc: Message-processing loop. Idle time is used to render the scene. //----------------------------------------------------------------------------- -INT Orbiter::Run () -{ - // Recieve and process Windows messages - BOOL bGotMsg, bCanRender, bpCanRender = TRUE; - MSG msg; - PeekMessage (&msg, NULL, 0U, 0U, PM_NOREMOVE); +void Orbiter::Run() { + if (!pConfig->CfgCmdlinePrm.LaunchScenario.empty()) + Launch(pConfig->CfgCmdlinePrm.LaunchScenario.c_str()); - if (!pConfig->CfgCmdlinePrm.LaunchScenario.empty()) - Launch (pConfig->CfgCmdlinePrm.LaunchScenario.c_str()); - // otherwise wait for the user to make a selection from the scenario - // list in the launchpad dialog + SDL_Event event = {}; + bool hadEvent; + bool bpCanRender = true; + while (!ShouldQuit()) { + // Use PollMessage() if the app is active, so we can use idle time to + // render the scene. Else, use GetMessage() to avoid eating CPU time. + if (bSession) { + hadEvent = SDL_PollEvent(&event); + } else { + hadEvent = SDL_WaitEvent(&event); + } - while (WM_QUIT != msg.message) { + if (hadEvent) { + bool consumed = false; + + if (gclient && hRenderWnd != nullptr) { + consumed = consumed || pDlgMgr->ConsumeEvent(event, bShouldQuit); + consumed = consumed || gclient->RenderWndProc(event, bShouldQuit); + } + + if (ShouldQuit()) + break; + } else { + if (bSession) { + bActive = hRenderWnd != nullptr && bVisible && + (SDL_GetKeyboardFocus() == hRenderWnd->Inner()); + if (bAllowInput) + bActive = true, bAllowInput = false; + if (BeginTimeStep(bRunning)) { + UpdateWorld(); + EndTimeStep(bRunning); + if (bVisible) { + if (bActive) + UserInput(); + bRenderOnce = true; + } + if (bRunning && bCapture) { + CaptureVideoFrame(); + } + } + if (m_pConsole) + m_pConsole->ParseCmd(); + } + } - // Use PeekMessage() if the app is active, so we can use idle time to - // render the scene. Else, use GetMessage() to avoid eating CPU time. - if (bSession) { - bGotMsg = PeekMessage (&msg, NULL, 0U, 0U, PM_REMOVE); - } else { - bGotMsg = GetMessage (&msg, NULL, 0U, 0U); - } - if (bGotMsg) { - if (!m_pLaunchpad || !m_pLaunchpad->ConsumeMessage(&msg)) { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - } else { - if (bSession) { - if (bAllowInput) bActive = true, bAllowInput = false; - if (BeginTimeStep (bRunning)) { - UpdateWorld(); - EndTimeStep (bRunning); - if (bVisible) { - if (bActive) UserInput (); - bRenderOnce = TRUE; - } - if (bRunning && bCapture) { - CaptureVideoFrame (); - } - } - if (m_pConsole) - m_pConsole->ParseCmd(); - } + if (bRenderOnce && bVisible) { + // TODO: what should replace this? + if (FAILED(Render3DEnvironment())) {} + // if (hRenderWnd) + // DestroyWindow(hRenderWnd); + bRenderOnce = false; } - if (bRenderOnce && bVisible) { - if (FAILED (Render3DEnvironment ())) - if (hRenderWnd) DestroyWindow (hRenderWnd); - bRenderOnce = FALSE; - } - if (bSession) { - bCanRender = TRUE; - if (bCanRender && !bpCanRender) - RestoreDeviceObjects (); - bpCanRender = bCanRender; - } else - bpCanRender = TRUE; + if (bSession) { + bool bCanRender = true; + if (bCanRender && !bpCanRender) + RestoreDeviceObjects(); + bpCanRender = bCanRender; + } else { + bpCanRender = true; + } + } + if (bSession) { + PreCloseSession(); + CloseSession(); } - hRenderWnd = NULL; - return msg.wParam; } void Orbiter::SingleFrame () @@ -1086,7 +1104,7 @@ void Orbiter::SingleFrame () void Orbiter::TerminateOnError () { LogOut (">>> TERMINATING <<<"); - if (hRenderWnd) ShowWindow (hRenderWnd, FALSE); + if (hRenderWnd) SDL_HideWindow(hRenderWnd->Inner()); MessageBox (NULL, "Terminating after critical error. See Orbiter.log for details.", "Orbiter: Critical Error", MB_OK | MB_ICONERROR); @@ -1116,40 +1134,28 @@ void Orbiter::InitRotationMode () { bKeepFocus = true; - // Checks if the cursor is already hidden - if (g_iCursorShowCount == 0) { - g_iCursorShowCount = ShowCursor(FALSE); - } - - SetCapture (hRenderWnd); + if (g_iCursorShowCount == 0) { + g_iCursorShowCount -= 1; + SDL_HideCursor(); + } - // Limit cursor to render window confines, so we don't miss the button up event - if (!bFullscreen && hRenderWnd) { - RECT rClient; - GetClientRect (hRenderWnd, &rClient); - POINT pLeftTop = {rClient.left, rClient.top}; - POINT pRightBottom = {rClient.right, rClient.bottom}; - ClientToScreen (hRenderWnd, &pLeftTop); - ClientToScreen (hRenderWnd, &pRightBottom); - RECT rScreen = {pLeftTop.x, pLeftTop.y, pRightBottom.x, pRightBottom.y}; - ClipCursor (&rScreen); - } + if (hRenderWnd) { + SDL_SetWindowRelativeMouseMode(hRenderWnd->Inner(), true); + } } void Orbiter::ExitRotationMode () { bKeepFocus = false; - ReleaseCapture (); - // Checks if the cursor is already hidden - if (g_iCursorShowCount < 0) { - g_iCursorShowCount = ShowCursor (TRUE); - } + if (g_iCursorShowCount < 0) { + SDL_ShowCursor(); + g_iCursorShowCount += 1; + } - // Release cursor from render window confines - if (!bFullscreen && hRenderWnd) { - ClipCursor (NULL); - } + if (hRenderWnd) { + SDL_SetWindowRelativeMouseMode(hRenderWnd->Inner(), false); + } } void Orbiter::OnOptionChanged(DWORD cat, DWORD item) @@ -1599,7 +1605,7 @@ oapi::ScreenAnnotation *Orbiter::CreateAnnotation (bool exclusive, double size, if (!gclient) return NULL; oapi::ScreenAnnotation *sn = gclient->clbkCreateAnnotation(); if (!sn) return NULL; - + sn->SetSize (size); VECTOR3 c = { (col & 0xFF)/256.0, ((col>>8 ) & 0xFF)/256.0, @@ -1881,7 +1887,7 @@ void Orbiter::EndTimeStep (bool running) // check for termination of demo mode if (SessionLimitReached()) - if (hRenderWnd) PostMessage(hRenderWnd, WM_CLOSE, 0, 0); + if (hRenderWnd) PostMessage(hRenderWnd->Win32Handle(), WM_CLOSE, 0, 0); else CloseSession(); } @@ -2027,7 +2033,9 @@ VOID Orbiter::UpdateWorld () g_bStateUpdate = false; if (!KillVessels()) // kill any vessels marked for deletion - if (hRenderWnd) DestroyWindow (hRenderWnd); + {} + // TODO + // if (hRenderWnd) DestroyWindow (hRenderWnd); //g_texmanager->OutputInfo(); } @@ -2059,12 +2067,13 @@ HRESULT Orbiter::UserInput () (g_select && g_select->IsActive())) skipkbd = true; if (didev = GetDInput()->GetKbdDevice()) { - ImGuiIO& io = ImGui::GetIO(); + WithImCtx _ = pDlgMgr->PushLocal(); + ImGuiIO& io = ImGui::GetIO(); // keyboard input: immediate key interpretation hr = didev->GetDeviceState (sizeof(buffer), &buffer); if ((hr == DIERR_NOTACQUIRED || hr == DIERR_INPUTLOST) && SUCCEEDED (didev->Acquire())) hr = didev->GetDeviceState (sizeof(buffer), &buffer); - + // Direct input bypasses the proc loop so we skip it here if (SUCCEEDED (hr) && !io.WantCaptureKeyboard) for (i = 0; i < 256; i++) @@ -2352,7 +2361,7 @@ void Orbiter::KbdInputBuffered_System (char *kstate, DIDEVICEOBJECTDATA *dod, DW if (bPlayback) EndPlayback(); else ToggleRecorder (); } else if (keymap.IsLogicalKey (key, kstate, OAPI_LKEY_Quit)) { - if (hRenderWnd) PostMessage (hRenderWnd, WM_CLOSE, 0, 0); + if (hRenderWnd) PostMessage (hRenderWnd->Win32Handle(), WM_CLOSE, 0, 0); } else if (keymap.IsLogicalKey (key, kstate, OAPI_LKEY_SelectPrevVessel)) { if (g_pfocusobj) SetFocusObject (g_pfocusobj); } @@ -2501,32 +2510,32 @@ void Orbiter::UserJoyInput_OnRunning (DIJOYSTATE2 *js) } } -bool Orbiter::MouseEvent (UINT event, DWORD state, DWORD x, DWORD y) +bool Orbiter::MouseEvent (const SDL_Event &event, DWORD x, DWORD y) { // Prioritizes mouse handling while in rotation mode if (g_pOrbiter->StickyFocus()) { - if (event == WM_MOUSEMOVE) return false; // may be lifted later - if (g_camera->ProcessMouse(event, state, x, y, simkstate)) return true; + if (event.type == SDL_EVENT_MOUSE_MOTION) return false; // may be lifted later + if (g_camera->ProcessMouse(event, x, y, simkstate)) return true; } - if (g_pane->MIBar() && g_pane->MIBar()->ProcessMouse (event, state, x, y)) return true; - if (BroadcastMouseEvent (event, state, x, y)) return true; - if (event == WM_MOUSEMOVE) return false; // may be lifted later + if (g_pane->MIBar() && g_pane->MIBar()->ProcessMouse (event, x, y)) return true; + if (BroadcastMouseEvent (event, x, y)) return true; + if (event.type == SDL_EVENT_MOUSE_MOTION) return false; // may be lifted later if (bRunning) { - if (g_pane->ProcessMouse_OnRunning (event, state, x, y, simkstate)) return true; + if (g_pane->ProcessMouse_OnRunning (event, x, y, simkstate)) return true; } - if (g_pane->ProcessMouse_System(event, state, x, y, simkstate)) return true; - if (g_camera->ProcessMouse (event, state, x, y, simkstate)) return true; + if (g_pane->ProcessMouse_System(event, x, y, simkstate)) return true; + if (g_camera->ProcessMouse (event, x, y, simkstate)) return true; return false; } -bool Orbiter::BroadcastMouseEvent (UINT event, DWORD state, DWORD x, DWORD y) +bool Orbiter::BroadcastMouseEvent (const SDL_Event &event, DWORD x, DWORD y) { bool consume = false; for (auto it = m_Plugin.begin(); it != m_Plugin.end(); it++) - if (it->pModule && it->pModule->clbkProcessMouse(event, state, x, y)) + if (it->pModule && it->pModule->clbkProcessMouse(event, x, y)) consume = true; return consume; @@ -2563,142 +2572,26 @@ void Orbiter::BroadcastBufferedKeyboardEvent (char *kstate, DIDEVICEOBJECTDATA * // Desc: Render window message handler //----------------------------------------------------------------------------- -LRESULT Orbiter::MsgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam)) - return 0; - - switch (uMsg) { - - case WM_ACTIVATE: - bActive = (wParam != WA_INACTIVE); - return 0; - - // *** User Keyboard Input *** - case WM_CHAR: - case WM_KEYDOWN: - if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureKeyboard) { - return 0; - } - - break; - - // Mouse event handler - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_LBUTTONUP: - case WM_RBUTTONUP: { - if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureMouse) { - return 0; - } - - if (MouseEvent(uMsg, wParam, LOWORD(lParam), HIWORD(lParam))) - break; //return 0; - } break; - case WM_MOUSEWHEEL: { - if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureMouse) { - return 0; - } - - int x = LOWORD(lParam); - int y = HIWORD(lParam); - if (!bFullscreen) { - POINT pt = { x, y }; - ScreenToClient(&pt); // for some reason this message passes screen coordinates - x = pt.x; - y = pt.y; - } - if (MouseEvent(uMsg, wParam, x, y)) - break; //return 0; - } break; - case WM_MOUSEMOVE: { - if (ImGuiIO& io = ImGui::GetIO(); io.WantCaptureMouse) { - return 0; - } - - int x = LOWORD(lParam); - int y = HIWORD(lParam); - MouseEvent(uMsg, wParam, x, y); - if (!bKeepFocus && pConfig->CfgUIPrm.MouseFocusMode != 0 && GetFocus() != hWnd) { - if (GetWindowThreadProcessId(hWnd, NULL) == GetWindowThreadProcessId(GetFocus(), NULL)) - SetFocus(hWnd); - } - } - return 0; - -#ifdef UNDEF - // These messages could be intercepted to suspend the simulation - // during resizing and menu operations. Not a good idea for real-time - // applications though - case WM_ENTERMENULOOP: // Pause the app when menus are displayed - Pause (TRUE); - break; - - case WM_EXITMENULOOP: // Resume when menu is closed - Pause (FALSE); - break; - - case WM_ENTERSIZEMOVE: // Pause during resizing or moving - if (m_bRunning) Suspend (); - break; - - case WM_EXITSIZEMOVE: // Resume after resizing or moving - if (m_bRunning) Resume (); - break; -#endif - - case WM_GETMINMAXINFO: - ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100; - ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100; - break; - - case WM_POWERBROADCAST: - switch (wParam) { - case PBT_APMQUERYSUSPEND: - // At this point, the app should save any data for open - // network connections, files, etc.., and prepare to go into - // a suspended mode. - Freeze (true); - return TRUE; - - case PBT_APMRESUMESUSPEND: - // At this point, the app should recover any data, network - // connections, files, etc.., and resume running from when - // the app was suspended. - Freeze (false); - return TRUE; - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case SC_MONITORPOWER: - // Prevent potential crashes when the monitor powers down - return 1; - - case IDM_EXIT: - // Recieved key/menu command to exit render window - SendMessage (hWnd, WM_CLOSE, 0, 0); - return 0; - } - break; - - case WM_NCHITTEST: - // Prevent the user from selecting the menu in fullscreen mode - if (IsFullscreen()) return HTCLIENT; - break; - - // shutdown options - case WM_CLOSE: - PreCloseSession(); - DestroyWindow (hWnd); - return 0; - - case WM_DESTROY: - CloseSession (); - break; - } - return DefWindowProc (hWnd, uMsg, wParam, lParam); +bool Orbiter::MsgProc (const SDL_Event &event, bool &wantsOut) +{ + // TODO: get DlgMgr working again + // if (ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam)) + // return 0; + + if (event.type == SDL_EVENT_MOUSE_BUTTON_UP || event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) { + if (MouseEvent(event, static_cast(event.button.x), static_cast(event.button.y))) + return true; + } else if (event.type == SDL_EVENT_MOUSE_WHEEL) { + if (MouseEvent(event, static_cast(event.wheel.mouse_x), static_cast(event.wheel.mouse_y))) + return true; + } else if (event.type == SDL_EVENT_MOUSE_MOTION) { + if (MouseEvent(event, static_cast(event.motion.x), static_cast(event.motion.y))) + return true; + // TODO + // if (!bKeepFocus && pConfig->CfgUIPrm.MouseFocusMode != 0 && SDL_GetMouseFocus() != hRenderWnd->Inner()) { + // SetFocus(hWnd); + } + return false; } //----------------------------------------------------------------------------- @@ -2760,7 +2653,7 @@ bool Orbiter::RemoveGraphicsClient (oapi::GraphicsClient *gc) bool Orbiter::RegisterWindow (HINSTANCE hInstance, HWND hWnd, DWORD flag) { - return (pDlgMgr ? (pDlgMgr->AddWindow (hInstance, hWnd, hRenderWnd, flag) != NULL) : NULL); + return (pDlgMgr ? (pDlgMgr->AddWindow (hInstance, hWnd, hRenderWnd->Win32Handle(), flag) != NULL) : NULL); } void Orbiter::UpdateDeallocationProgress() @@ -2780,12 +2673,12 @@ HWND Orbiter::OpenDialogEx (int id, DLGPROC pDlg, DWORD flag, void *context) HWND Orbiter::OpenDialog (HINSTANCE hInstance, int id, DLGPROC pDlg, void *context) { - return (pDlgMgr ? pDlgMgr->OpenDialog (hInstance, id, hRenderWnd, pDlg, context) : NULL); + return (pDlgMgr ? pDlgMgr->OpenDialog (hInstance, id, hRenderWnd->Win32Handle(), pDlg, context) : NULL); } HWND Orbiter::OpenDialogEx (HINSTANCE hInstance, int id, DLGPROC pDlg, DWORD flag, void *context) { - return (pDlgMgr ? pDlgMgr->OpenDialogEx (hInstance, id, hRenderWnd, pDlg, flag, context) : NULL); + return (pDlgMgr ? pDlgMgr->OpenDialogEx (hInstance, id, hRenderWnd->Win32Handle(), pDlg, flag, context) : NULL); } void Orbiter::OpenHelp (const HELPCONTEXT *hcontext) diff --git a/Src/Orbiter/Orbiter.h b/Src/Orbiter/Orbiter.h index e0e2498b8..3b53bf718 100644 --- a/Src/Orbiter/Orbiter.h +++ b/Src/Orbiter/Orbiter.h @@ -4,14 +4,16 @@ #ifndef ORBITER_H #define ORBITER_H +#include #include "Config.h" #include "Input.h" #include "Select.h" #include "Keymap.h" -#include -#include +#include + #include "Mesh.h" #include "TimeData.h" +#include class DInput; class Config; @@ -51,17 +53,17 @@ class Orbiter { Orbiter (); ~Orbiter (); - HRESULT Create (HINSTANCE); + bool Create (); VOID Launch (const char *scenario); void CloseApp (bool fast_shutdown = false); int GetVersion () const; - HWND CreateRenderWindow (Config *pCfg, const char *scenario); + std::shared_ptr CreateRenderWindow (Config *pCfg, const char *scenario); void PreCloseSession(); void CloseSession (); void GetRenderParameters (); bool InitializeWorld (char *name); void ScreenToClient (POINT *pt) const; - LRESULT MsgProc (HWND, UINT, WPARAM, LPARAM); + bool MsgProc (const SDL_Event &event, bool &wantsOut); HRESULT Render3DEnvironment(bool hidedialogs = false); VOID Output2DData (); void OutputLoadStatus (const char *msg, int line); @@ -72,7 +74,9 @@ class Orbiter { void ExitRotationMode (); bool StickyFocus() const { return bKeepFocus; } void OpenVideoTab() { bStartVideoTab = true; } - INT Run (); + void Run (); + void SetShouldQuit() { bShouldQuit = true; }; + bool ShouldQuit() { return bShouldQuit; } void SingleFrame (); void Pause (bool bPause); void Freeze (bool bFreeze); @@ -155,7 +159,7 @@ class Orbiter { // Accessor functions inline HINSTANCE GetInstance() const { return hInst; } - inline HWND GetRenderWnd() const { return hRenderWnd; } + inline const std::shared_ptr& GetRenderWnd() const { return hRenderWnd; } inline bool IsFullscreen() const { return bFullscreen; } inline DWORD ViewW() const { return viewW; } inline DWORD ViewH() const { return viewH; } @@ -167,6 +171,7 @@ class Orbiter { inline State* PState() const { return pState; } inline bool IsActive() const { return bActive; } // temporary inline bool IsRunning() const { return bRunning; } + inline bool HasSession() const { return bSession; } inline bool UseStencil() const { return bUseStencil; } inline void SetFastExit (bool fexit) { bFastExit = fexit; } inline bool UseHtmlInline() { return (pConfig->CfgDebugPrm.bHtmlScnDesc == 1 || pConfig->CfgDebugPrm.bHtmlScnDesc == 2 && !bWINEenv); } @@ -309,8 +314,8 @@ class Orbiter { void KbdInputBuffered_OnRunning (char *kstate, DIDEVICEOBJECTDATA *dod, DWORD n); void UserJoyInput_System (DIJOYSTATE2 *js); void UserJoyInput_OnRunning (DIJOYSTATE2 *js); - bool MouseEvent (UINT event, DWORD state, DWORD x, DWORD y); - bool BroadcastMouseEvent (UINT event, DWORD state, DWORD x, DWORD y); + bool MouseEvent (const SDL_Event &event, DWORD x, DWORD y); + bool BroadcastMouseEvent (const SDL_Event &event, DWORD x, DWORD y); bool BroadcastImmediateKeyboardEvent (char *kstate); void BroadcastBufferedKeyboardEvent (char *kstate, DIDEVICEOBJECTDATA *dod, DWORD n); @@ -352,7 +357,7 @@ class Orbiter { orbiter::ConsoleNG* m_pConsole; // The console window opened when Orbiter server is launched without a graphics client DInput *pDI; HINSTANCE hInst; // orbiter instance handle - HWND hRenderWnd; // render window handle (NULL if no render support) + std::shared_ptr hRenderWnd; // render window handle (NULL if no render support) HWND hBk; // background window handle (demo mode only) BOOL bRenderOnce; // flag for single frame render request BOOL bEnableLighting; @@ -393,6 +398,9 @@ class Orbiter { bool bFastExit; // terminate on simulation end? bool bSysClearType; // is cleartype enabled on the user's system? bool bRoughType; // font-smoothing disabled? + bool bShouldQuit; + + std::string currentScenario; // Manual joystick/keyboard attitude inputs DWORD ctrlJoystick[15]; diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index 15fc17055..b3922f124 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -2185,7 +2185,8 @@ DLLEXPORT void oapiCloseDialog (HWND hDlg) DLLEXPORT void oapiCloseDialog(ImGuiDialog *e) { - g_pOrbiter->DlgMgr()->DelEntry(e); + if (g_pOrbiter->DlgMgr()) + g_pOrbiter->DlgMgr()->DelEntry(e); } DLLEXPORT void *oapiGetDialogContext (HWND hDlg) @@ -2196,7 +2197,7 @@ DLLEXPORT void *oapiGetDialogContext (HWND hDlg) DLLEXPORT bool oapiRegisterWindow (HINSTANCE hDLLInst, HWND hWnd, DWORD flag) { - return g_pOrbiter->RegisterWindow (hDLLInst, hWnd, flag); + return g_pOrbiter->RegisterWindow (hDLLInst, hWnd, flag); } DLLEXPORT bool oapiAddTitleButton (DWORD msgid, HBITMAP hBmp, DWORD flag) diff --git a/Src/Orbiter/Pane.cpp b/Src/Orbiter/Pane.cpp index 1208ddc84..420301f77 100644 --- a/Src/Orbiter/Pane.cpp +++ b/Src/Orbiter/Pane.cpp @@ -27,8 +27,8 @@ static COLORREF normalColor = RGB ( 0, 255, 0); static COLORREF infoColor = RGB (224, 192, 0); static COLORREF brightColor = RGB (255, 224, 128); - -Pane::Pane (oapi::GraphicsClient *gclient, HWND hwnd, int width, int height, int bpp) + +Pane::Pane (oapi::GraphicsClient *gclient, std::shared_ptr hwnd, int width, int height, int bpp) { // Note: gclient is assumed to be a valid pointer. Nongraphics orbiter // instances should not create a Pane. @@ -57,11 +57,11 @@ Pane::Pane (oapi::GraphicsClient *gclient, HWND hwnd, int width, int height, int panel2d = 0; panel = 0; vcockpit = 0; - + if (gc) mibar = new MenuInfoBar (this); else mibar = NULL; - + i = g_pOrbiter->Cfg()->CfgInstrumentPrm.bMfdPow2; if (i == 2) { DWORD val; @@ -145,29 +145,31 @@ bool Pane::MFDConsumeKeyBuffered (int id, DWORD key) return false; } -bool Pane::ProcessMouse_System(UINT event, DWORD state, DWORD x, DWORD y, const char *kstate) +bool Pane::ProcessMouse_System(const SDL_Event &event, DWORD x, DWORD y, + const char *kstate) { if (g_camera->IsExternal()) return false; // respond to mouse events only in cockpit mode bool consumed = false; - if (defpanel) /*consumed = defpanel->ProcessMouse(event, state, x, y)*/; - else if (panel2d) consumed = panel2d->ProcessMouse_System(event, state, x, y, kstate); - else if (panel) /*consumed = panel->ProcessMouse(event, state, x, y)*/; - else if (vcockpit) /*consumed = vcockpit->ProcessMouse(event, state, x, y)*/; + if (defpanel) /*consumed = defpanel->ProcessMouse(event, state, x, y)*/ {} + else if (panel2d) {consumed = panel2d->ProcessMouse_System(event, x, y, kstate);} + else if (panel) /*consumed = panel->ProcessMouse(event, state, x, y)*/ {} + else if (vcockpit) /*consumed = vcockpit->ProcessMouse(event, state, x, y)*/ {} return consumed; } -bool Pane::ProcessMouse_OnRunning (UINT event, DWORD state, DWORD x, DWORD y, const char *kstate) +bool Pane::ProcessMouse_OnRunning (const SDL_Event &event, DWORD x, DWORD y, + const char *kstate) { if (g_camera->IsExternal()) return false; // respond to mouse events only in cockpit mode bool consumed = false; - if (defpanel) consumed = defpanel->ProcessMouse (event, state, x, y); - else if (panel2d) consumed = panel2d->ProcessMouse_OnRunning (event, state, x, y, kstate); - else if (panel) consumed = panel->ProcessMouse (event, state, x, y); - else if (vcockpit) consumed = vcockpit->ProcessMouse (event, state, x, y); + if (defpanel) consumed = defpanel->ProcessMouse (event, x, y); + else if (panel2d) consumed = panel2d->ProcessMouse_OnRunning (event, x, y, kstate); + else if (panel) consumed = panel->ProcessMouse (event, x, y); + else if (vcockpit) consumed = vcockpit->ProcessMouse (event, x, y); return consumed; } @@ -190,7 +192,7 @@ bool Pane::SetPanelMode (int pmode, bool force) if (pmode == panelmode && !force) return true; // nothing to do panelmode = pmode; - + Vessel::UnsetCameraMovement(); for (i = 0; i < MAXMFD; i++) { @@ -905,7 +907,7 @@ bool Pane::OpenMFD (INT_PTR id, int type, ifstream *ifs) // Try to create a new mode with this key Instrument *newinstr = 0; if (ifs || type != MFD_NONE) { - newinstr = (ifs ? + newinstr = (ifs ? Instrument::Create (*ifs, this, id, spec, g_focusobj) : Instrument::Create (type, this, id, spec, g_focusobj) ); if (!newinstr) return false; // no mode found diff --git a/Src/Orbiter/Pane.h b/Src/Orbiter/Pane.h index 6bc1ded42..1fa09bf07 100644 --- a/Src/Orbiter/Pane.h +++ b/Src/Orbiter/Pane.h @@ -32,7 +32,7 @@ class Vessel; struct MFDspec { // panel MFD specs Instrument *instr; // pointer to MFD instance - int lastmode; // last MFD mode + int lastmode; // last MFD mode bool exist; // MFD present? bool active; // MFD switched on? double upDTscale; // refresh interval scale @@ -55,7 +55,7 @@ class Pane { friend class MenuInfoBar; public: - Pane (oapi::GraphicsClient *gclient, HWND hwnd, int width, int height, int bpp); + Pane (oapi::GraphicsClient *gclient, std::shared_ptr hwnd, int width, int height, int bpp); // Create a new pane with dimension width x height x bpp ~Pane (); @@ -92,9 +92,11 @@ class Pane { bool MFDConsumeKeyBuffered (int id, DWORD key); // Process a buffered key for MFD id - bool ProcessMouse_System(UINT event, DWORD state, DWORD x, DWORD y, const char *kstate); + bool ProcessMouse_System(const SDL_Event &event, DWORD x, DWORD y, + const char *kstate); - bool ProcessMouse_OnRunning (UINT event, DWORD state, DWORD x, DWORD y, const char *kstate); + bool ProcessMouse_OnRunning (const SDL_Event &event, DWORD x, DWORD y, + const char *kstate); // Process a mouse click/release void SetFOV (double _fov); @@ -271,7 +273,7 @@ class Pane { oapi::GraphicsClient *gc; // client instance int W, H, BPP; // pane dimensions int scaleW; - HWND hWnd; // window handle + std::shared_ptr hWnd; // window handle int colidx; // HUD colour index COLORREF hudCol; // HUD colour double hudIntens; // HUD intensity (VC only) @@ -315,4 +317,4 @@ inline void Pane::DrawDefaultHUD (oapi::Sketchpad *skp) inline void Pane::RenderDefaultHUD () { if (hud) hud->RenderDefault (); } -#endif // !__PANE_H \ No newline at end of file +#endif // !__PANE_H diff --git a/Src/Orbiter/Panel.cpp b/Src/Orbiter/Panel.cpp index 710327837..c05535d6d 100644 --- a/Src/Orbiter/Panel.cpp +++ b/Src/Orbiter/Panel.cpp @@ -33,7 +33,7 @@ Panel::Panel (int _id, const Pane *_pane, double _scale) if (g_pOrbiter->IsFullscreen()) cwnd = 0; else - cwnd = g_pOrbiter->GetRenderWnd(); + cwnd = g_pOrbiter->GetRenderWnd()->Win32Handle(); narea = nareabuf = 0; idx_mfocus = aid_mfocus = mstate = 0; @@ -373,23 +373,21 @@ void Panel::Area2Screen (const RECT &srcR, RECT &tgtR) const Point2Screen (srcR.right, srcR.bottom, tgtR.right, tgtR.bottom); } -bool Panel::ProcessMouse (UINT event, DWORD state, int x, int y) +bool Panel::ProcessMouse (const SDL_Event &event, int x, int y) { mstate = 0; - switch (event) { - case WM_LBUTTONDOWN: - state = PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED; - break; - case WM_RBUTTONDOWN: - state = PANEL_MOUSE_RBDOWN | PANEL_MOUSE_RBPRESSED; - break; - case WM_LBUTTONUP: - state = PANEL_MOUSE_LBUP; - break; - case WM_RBUTTONUP: - state = PANEL_MOUSE_RBUP; - break; - } + auto state = 0; + + if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_LEFT) { + state = PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_RIGHT) { + state = PANEL_MOUSE_RBDOWN | PANEL_MOUSE_RBPRESSED; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_LEFT) { + state = PANEL_MOUSE_LBUP; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_RIGHT) { + state = PANEL_MOUSE_RBUP; + } + if (state & PANEL_MOUSE_DOWN) { // locate mouse event int i; x -= X0, y -= Y0; diff --git a/Src/Orbiter/Panel.h b/Src/Orbiter/Panel.h index eec5ab0ec..ba670ebe1 100644 --- a/Src/Orbiter/Panel.h +++ b/Src/Orbiter/Panel.h @@ -79,7 +79,7 @@ class Panel { inline void MFDSize (int id, int &w, int &h) const { w = mfd[id].w, h = mfd[id].h; } - bool ProcessMouse (UINT event, DWORD state, int x, int y); + bool ProcessMouse (const SDL_Event &event, int x, int y); void GetMouseState (int &idx, int &state, int &mx, int &my) const; //{ idx = idx_mfocus; state = mstate; mx = mousex, my = mousey; } @@ -92,7 +92,7 @@ class Panel { private: inline int AreaIndex (int aid) const - { + { for (int i = 0; i < narea; i++) if (area[i]->id == aid) return i; return -1; } @@ -145,4 +145,4 @@ class Panel { } mfd[MAXMFD]; }; -#endif // !__PANEL_H \ No newline at end of file +#endif // !__PANEL_H diff --git a/Src/Orbiter/Panel2D.cpp b/Src/Orbiter/Panel2D.cpp index 6def184ff..6007634be 100644 --- a/Src/Orbiter/Panel2D.cpp +++ b/Src/Orbiter/Panel2D.cpp @@ -41,7 +41,7 @@ Panel2D::Panel2D (int _id, Pane *_pane, double scale) mstate = 0; if (g_pOrbiter->IsFullscreen()) cwnd = 0; - else cwnd = g_pOrbiter->GetRenderWnd(); + else cwnd = g_pOrbiter->GetRenderWnd()->Win32Handle(); for (i = 0; i < 4; i++) connect[i] = -1; @@ -139,7 +139,7 @@ void Panel2D::SetActiveScale (double scale, bool force) if (shiftflag & PANEL_ATTACH_BOTTOM) y0 = max (y0, viewH-tgtH); else if (shiftflag & PANEL_ATTACH_TOP) y0 = min (y0, 0.0); - if (panelscale == 1.0) { // pixel alignment + if (panelscale == 1.0) { // pixel alignment x0 = floor(x0+0.5); y0 = floor(y0+0.5); } @@ -281,49 +281,36 @@ void Panel2D::Render () } } -bool Panel2D::ProcessMouse_System(UINT event, DWORD state, int x, int y, const char *kstate) +bool Panel2D::ProcessMouse_System(const SDL_Event &event, int x, int y, + const char *kstate) { // Windows event handler for mouse events - switch (event) { - case WM_MOUSEWHEEL: - if ((KEYMOD_CONTROL(kstate))) { - short zDelta = (short)HIWORD(state); + if (event.type == SDL_EVENT_MOUSE_WHEEL) { + if ((KEYMOD_CONTROL(kstate))) { + double zDelta = event.wheel.y * 120.0; zoomaction = (zDelta < 0 ? ZOOM_OUT : ZOOM_IN); refx = x, refy = y; return true; } - break; } return false; } -bool Panel2D::ProcessMouse_OnRunning (UINT event, DWORD state, int x, int y, const char *kstate) +bool Panel2D::ProcessMouse_OnRunning (const SDL_Event &event, int x, int y, + const char *kstate) { mstate = 0; - - // Windows event handler for mouse events - switch (event) { - case WM_LBUTTONDOWN: - state = PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED; - break; - case WM_RBUTTONDOWN: - state = PANEL_MOUSE_RBDOWN | PANEL_MOUSE_RBPRESSED; - break; - case WM_LBUTTONUP: - state = PANEL_MOUSE_LBUP; - break; - case WM_RBUTTONUP: - state = PANEL_MOUSE_RBUP; - break; - //case WM_MOUSEWHEEL: - // if ((KEYMOD_CONTROL(kstate))) { - // short zDelta = (short)HIWORD(state); - // zoomaction = (zDelta < 0 ? ZOOM_OUT : ZOOM_IN); - // refx = x, refy = y; - // return true; - // } - // break; - } + auto state = 0; + + if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_LEFT) { + state = PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_RIGHT) { + state = PANEL_MOUSE_RBDOWN | PANEL_MOUSE_RBPRESSED; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_LEFT) { + state = PANEL_MOUSE_LBUP; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_RIGHT) { + state = PANEL_MOUSE_RBUP; + } // mouse state event handler (button-down events only) if (state & PANEL_MOUSE_DOWN) { diff --git a/Src/Orbiter/Panel2D.h b/Src/Orbiter/Panel2D.h index 33e8a9556..a6047d055 100644 --- a/Src/Orbiter/Panel2D.h +++ b/Src/Orbiter/Panel2D.h @@ -5,7 +5,7 @@ // class Panel2D // Vessel cockpit represented by 2D instrument panels // -// This replaces the 'Panel' class. It represents the panels with +// This replaces the 'Panel' class. It represents the panels with // textured 3D billboards instead of bitmap overlays // ======================================================================= @@ -123,22 +123,22 @@ class Panel2D { /** * \brief Process a mouse event for the panel. * \param event event type (see \ref panel_mouse) - * \param state mouse button state * \param x mouse screen x position * \param y mouse screen y position * \return \e true if the panel processes the event. */ - bool ProcessMouse_System(UINT event, DWORD state, int x, int y, const char *kstate); + bool ProcessMouse_System(const SDL_Event &event, int x, int y, + const char *kstate); /** * \brief Process a mouse event for the panel while the simulation is active. * \param event event type (see \ref panel_mouse) - * \param state mouse button state * \param x mouse screen x position * \param y mouse screen y position * \return \e true if the panel processes the event. */ - bool ProcessMouse_OnRunning (UINT event, DWORD state, int x, int y, const char *kstate); + bool ProcessMouse_OnRunning (const SDL_Event &event, int x, int y, + const char *kstate); void GetMouseState (int &idx, int &state, int &mx, int &my) const; @@ -168,7 +168,7 @@ class Panel2D { * \return area list index (>= 0) or -1 if area doesn't exist */ inline int AreaIndex (int aid) const - { + { for (int i = 0; i < narea; i++) if (area[i]->id == aid) return i; return -1; } @@ -241,4 +241,4 @@ class Panel2D { } mfdspec[MAXMFD]; }; -#endif // !__PANEL2D_H \ No newline at end of file +#endif // !__PANEL2D_H diff --git a/Src/Orbiter/SDLWrappers.cpp b/Src/Orbiter/SDLWrappers.cpp new file mode 100644 index 000000000..2dbc76d59 --- /dev/null +++ b/Src/Orbiter/SDLWrappers.cpp @@ -0,0 +1,72 @@ +#include "SDLWrappers.h" + +#include +#include + +sdl::ManagedWindow::ManagedWindow(const std::string_view title, const int width, + const int height, + const SDL_WindowFlags flags) { + m_inner = SDL_CreateWindow(title.data(), width, height, flags); + if (m_inner == nullptr) { + LOGOUT_ERR("SDL_CreateWindow() failed: %s", SDL_GetError()); + throw std::runtime_error("Failed to create window"); + } + +#ifdef _DEBUG + m_device = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV | + SDL_GPU_SHADERFORMAT_DXIL | + SDL_GPU_SHADERFORMAT_METALLIB, + true, nullptr); +#else + m_device = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV | + SDL_GPU_SHADERFORMAT_DXIL | + SDL_GPU_SHADERFORMAT_METALLIB, + false, nullptr); +#endif + if (m_device == nullptr) { + LOGOUT_ERR("SDL_CreateGPUDevice() failed: %s", SDL_GetError()); + throw std::runtime_error("Failed to create GPU device"); + } + + if (!SDL_ClaimWindowForGPUDevice(m_device, m_inner)) { + LOGOUT_ERR("SDL_ClaimWindowForGPUDevice() failed: %s", SDL_GetError()); + SDL_DestroyGPUDevice(m_device); + SDL_DestroyWindow(m_inner); + throw std::runtime_error("Failed to claim window"); + } + + if (!SDL_SetGPUSwapchainParameters(m_device, m_inner, + SDL_GPU_SWAPCHAINCOMPOSITION_SDR, + SDL_GPU_PRESENTMODE_VSYNC)) { + LOGOUT_ERR("SDL_SetGPUSwapchainParameters() failed: %s", + SDL_GetError()); + SDL_ReleaseWindowFromGPUDevice(m_device, m_inner); + SDL_DestroyGPUDevice(m_device); + SDL_DestroyWindow(m_inner); + throw std::runtime_error("Failed to set swapchain parameters"); + }; +} + +sdl::ManagedWindow::~ManagedWindow() { + if (m_device && m_inner) + SDL_ReleaseWindowFromGPUDevice(m_device, m_inner); + if (m_device) + SDL_DestroyGPUDevice(m_device); + if (m_inner) + SDL_DestroyWindow(m_inner); +} + +sdl::UnmanagedWindow::UnmanagedWindow(const std::string_view title, + const int width, const int height, + const SDL_WindowFlags flags) { + m_inner = SDL_CreateWindow(title.data(), width, height, flags); + if (m_inner == nullptr) { + LOGOUT_ERR("SDL_CreateWindow() failed: %s", SDL_GetError()); + throw std::runtime_error("Failed to create window"); + } +} + +sdl::UnmanagedWindow::~UnmanagedWindow() { + if (m_inner) + SDL_DestroyWindow(m_inner); +} diff --git a/Src/Orbiter/VCockpit.cpp b/Src/Orbiter/VCockpit.cpp index c6fe3b49a..e83fd4797 100644 --- a/Src/Orbiter/VCockpit.cpp +++ b/Src/Orbiter/VCockpit.cpp @@ -34,7 +34,7 @@ VirtualCockpit::VirtualCockpit (int _id, const Pane *_pane) if (g_pOrbiter->IsFullscreen()) cwnd = 0; else - cwnd = g_pOrbiter->GetRenderWnd(); + cwnd = g_pOrbiter->GetRenderWnd()->Win32Handle(); for (i = 0; i < 4; i++) connect[i] = -1; } @@ -346,23 +346,21 @@ bool VirtualCockpit::SetClickZone_Quadrilateral (int i, return true; } -bool VirtualCockpit::ProcessMouse (UINT event, DWORD state, int x, int y) +bool VirtualCockpit::ProcessMouse (const SDL_Event &event, int x, int y) { mstate = 0; - switch (event) { - case WM_LBUTTONDOWN: - state = PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED; - break; - case WM_RBUTTONDOWN: - state = PANEL_MOUSE_RBDOWN | PANEL_MOUSE_RBPRESSED; - break; - case WM_LBUTTONUP: - state = PANEL_MOUSE_LBUP; - break; - case WM_RBUTTONUP: - state = PANEL_MOUSE_RBUP; - break; - } + auto state = 0; + + if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_LEFT) { + state = PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_RIGHT) { + state = PANEL_MOUSE_RBDOWN | PANEL_MOUSE_RBPRESSED; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_LEFT) { + state = PANEL_MOUSE_LBUP; + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_RIGHT) { + state = PANEL_MOUSE_RBUP; + } + if (state & PANEL_MOUSE_DOWN) { // locate mouse event idx_mfocus = -1; diff --git a/Src/Orbiter/VCockpit.h b/Src/Orbiter/VCockpit.h index 8c70eea4a..82f62acc7 100644 --- a/Src/Orbiter/VCockpit.h +++ b/Src/Orbiter/VCockpit.h @@ -63,7 +63,7 @@ class VirtualCockpit { bool SetClickZone_Spherical (int i, const Vector &cnt, double rad); bool SetClickZone_Quadrilateral (int i, const Vector &p1, const Vector &p2, const Vector &p3, const Vector &p4); - bool ProcessMouse (UINT event, DWORD state, int x, int y); + bool ProcessMouse (const SDL_Event &event, int x, int y); void GetMouseState (int &idx, int &state, Vector &xs) const; inline void SetMouseState (int state) { mstate = state; } @@ -79,7 +79,7 @@ class VirtualCockpit { private: inline int AreaIndex (int aid) const - { + { for (int i = 0; i < narea; i++) if (area[i]->id == aid) return i; return -1; } @@ -128,4 +128,4 @@ class VirtualCockpit { int narea, nareabuf; }; -#endif // !__VCOCKPIT_H \ No newline at end of file +#endif // !__VCOCKPIT_H diff --git a/Src/Orbiter/cmdline.cpp b/Src/Orbiter/cmdline.cpp index ff257af11..e6a6cde83 100644 --- a/Src/Orbiter/cmdline.cpp +++ b/Src/Orbiter/cmdline.cpp @@ -2,15 +2,22 @@ // Licensed under the MIT License #include +#include #include #include "cmdline.h" #include "Orbiter.h" #include "Launchpad.h" -CommandLine::CommandLine(const PSTR cmdLine) +CommandLine::CommandLine(int argc, const char** cmdLine) { - m_cmdLine = (std::string(cmdLine ? cmdLine : "")); - ParseCmdLine(cmdLine); + auto ss = std::stringstream(); + for (int i = 1; i < argc; i++) { + if (i != 1) + ss << " "; + ss << (cmdLine[i] ? cmdLine[i] : ""); + } + m_cmdLine = ss.str(); + ParseCmdLine(); } const char* CommandLine::CmdLine() const @@ -28,9 +35,9 @@ bool CommandLine::GetOption(UINT id, const std::string** value) const return false; } -void CommandLine::ParseCmdLine(const PSTR cmdLine) +void CommandLine::ParseCmdLine() { - PSTR pc = cmdLine; + const char *pc = m_cmdLine.c_str(); bool groupKey = false; while (*pc) { @@ -42,7 +49,7 @@ void CommandLine::ParseCmdLine(const PSTR cmdLine) } } -bool CommandLine::ParseNextOption(PSTR& cmdLine, bool& groupKey, Option& option) +bool CommandLine::ParseNextOption(const char*& cmdLine, bool& groupKey, Option& option) { bool isLongKey; bool isQuotedVal; @@ -70,7 +77,7 @@ bool CommandLine::ParseNextOption(PSTR& cmdLine, bool& groupKey, Option& option) } const char* termKeyChar = (isLongKey ? " \t=" : " \t"); // '=' as key-value separator only allowed for long keys std::set termK(termKeyChar, termKeyChar + strlen(termKeyChar) + 1); // include '\0' in set - PSTR endKey = cmdLine; + const char* endKey = cmdLine; while (termK.find(*endKey) == termK.end()) endKey++; size_t keyLen = endKey - cmdLine; @@ -85,7 +92,7 @@ bool CommandLine::ParseNextOption(PSTR& cmdLine, bool& groupKey, Option& option) else { cmdLine = endKey; // advance command line pointer } - + // Parse value, if present while (*cmdLine == ' ' || *cmdLine == '\t') cmdLine++; // skip whitespace if (*cmdLine == '\0' || *cmdLine == '-') { // end of options or next item is key: no value @@ -104,7 +111,7 @@ bool CommandLine::ParseNextOption(PSTR& cmdLine, bool& groupKey, Option& option) cmdLine++; // skip starting quotes const char* termValChar = (isQuotedParam || isQuotedVal ? "\"" : " \t"); // for quoted values, only accept quotes as terminator std::set termV(termValChar, termValChar + strlen(termValChar) + 1); // include '\0' in set - PSTR endVal = cmdLine; + const char* endVal = cmdLine; while (termV.find(*endVal) == termV.end()) endVal++; size_t valLen = endVal - cmdLine; @@ -148,11 +155,8 @@ void CommandLine::ApplyOptions() } } - - - -orbiter::CommandLine::CommandLine(Orbiter* pOrbiter, const PSTR cmdLine) - : ::CommandLine(cmdLine) +orbiter::CommandLine::CommandLine(Orbiter* pOrbiter, int argc, const char **cmdLine) + : ::CommandLine(argc, cmdLine) , m_pOrbiter(pOrbiter) { CFG_CMDLINEPRM& cfg = m_pOrbiter->Cfg()->CfgCmdlinePrm; @@ -259,8 +263,8 @@ void orbiter::CommandLine::PrintHelpAndExit() const exit(0); } -orbiter::CommandLine& orbiter::CommandLine::InstanceImpl(Orbiter* pOrbiter, const PSTR cmdLine) +orbiter::CommandLine& orbiter::CommandLine::InstanceImpl(Orbiter* pOrbiter, int argc, const char **cmdLine) { - static orbiter::CommandLine instance{ pOrbiter, cmdLine }; + static orbiter::CommandLine instance{ pOrbiter, argc, cmdLine }; return instance; } diff --git a/Src/Orbiter/cmdline.h b/Src/Orbiter/cmdline.h index fefc303d2..abd47e6ca 100644 --- a/Src/Orbiter/cmdline.h +++ b/Src/Orbiter/cmdline.h @@ -20,12 +20,12 @@ class CommandLine void operator=(CommandLine const&) = delete; const char* CmdLine() const; - bool GetOption(UINT id, const std::string** value) const; + bool GetOption(unsigned int id, const std::string** value) const; protected: struct Key { - UINT id; - PCSTR longName; + unsigned int id; + const char* longName; char shortName; bool hasArgument; }; @@ -36,9 +36,9 @@ class CommandLine }; std::vector


", sz) == 0) { + ImGui::Separator(); + return true; + } + if (strncmp(str, "", sz) == 0) { + m_is_underline = true; + return true; + } + if (strncmp(str, "", sz) == 0) { + m_is_underline = false; + return true; + } + + const size_t div_sz = 4; + if (strncmp(str, " div_sz ? div_sz : sz) == 0) { + m_div_stack.emplace_back(get_div_class(str + div_sz, str_end)); + html_div(m_div_stack.back(), true); + return true; + } + if (strncmp(str, "", sz) == 0) { + if (m_div_stack.empty())return false; + html_div(m_div_stack.back(), false); + m_div_stack.pop_back(); + return true; + } + return false; +} + + +void imgui_md::html_div(const std::string& dclass, bool e) +{ + //Example: +#if 0 + if (dclass == "red") { + if (e) { + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255)); + } else { + ImGui::PopStyleColor(); + } + } +#endif + (void)dclass; (void)e; +} + +void imgui_md::render_code_block() +{ + m_is_code = true; + push_code_style(); + + const char* begin = m_code_block.data(); + const char *end = m_code_block.data() + m_code_block.size(); + render_text(begin, end); + + pop_code_style(); + m_is_code = false; +} + +void imgui_md::push_code_style() +{ + ImGui::PushFont(get_font()); + + // Make code a little more blue + auto color = ImGui::GetStyle().Colors[ImGuiCol_Text]; + color.z *= 1.15f; + ImGui::PushStyleColor(ImGuiCol_Text, color); + +} +void imgui_md::pop_code_style() +{ + ImGui::PopStyleColor(); + ImGui::PopFont(); +} + + +void imgui_md::render_inline_code(const char *str, const char *str_end) +{ + m_is_code = true; + push_code_style(); + render_text(str, str_end); + pop_code_style(); + m_is_code = false; +} + +int imgui_md::text(MD_TEXTTYPE type, const char* str, const char* str_end) +{ + switch (type) { + case MD_TEXT_NORMAL: + render_text(str, str_end); + break; + case MD_TEXT_CODE: + if (m_is_code_block) + m_code_block += std::string(str, str_end); + else + render_inline_code(str, str_end); + break; + case MD_TEXT_NULLCHAR: + break; + case MD_TEXT_BR: + ImGui::NewLine(); + break; + case MD_TEXT_SOFTBR: + soft_break(); + break; + case MD_TEXT_ENTITY: + if (!render_entity(str, str_end)) { + render_text(str, str_end); + }; + break; + case MD_TEXT_HTML: + if (!check_html(str, str_end)) { + render_text(str, str_end); + } + break; + case MD_TEXT_LATEXMATH: + render_text(str, str_end); + break; + default: + break; + } + + if (m_is_table_header) { + const float x = ImGui::GetCursorPosX(); + if (x > m_table_last_pos.x)m_table_last_pos.x = x; + } + + return 0; +} + +int imgui_md::block(MD_BLOCKTYPE type, void* d, bool e) +{ + switch (type) + { + case MD_BLOCK_DOC: + BLOCK_DOC(e); + break; + case MD_BLOCK_QUOTE: + BLOCK_QUOTE(e); + break; + case MD_BLOCK_UL: + BLOCK_UL((MD_BLOCK_UL_DETAIL*)d, e); + break; + case MD_BLOCK_OL: + BLOCK_OL((MD_BLOCK_OL_DETAIL*)d, e); + break; + case MD_BLOCK_LI: + BLOCK_LI((MD_BLOCK_LI_DETAIL*)d, e); + break; + case MD_BLOCK_HR: + BLOCK_HR(e); + break; + case MD_BLOCK_H: + BLOCK_H((MD_BLOCK_H_DETAIL*)d, e); + break; + case MD_BLOCK_CODE: + BLOCK_CODE((MD_BLOCK_CODE_DETAIL*)d, e); + break; + case MD_BLOCK_HTML: + BLOCK_HTML(e); + break; + case MD_BLOCK_P: + BLOCK_P(e); + break; + case MD_BLOCK_TABLE: + BLOCK_TABLE((MD_BLOCK_TABLE_DETAIL*)d, e); + break; + case MD_BLOCK_THEAD: + BLOCK_THEAD(e); + break; + case MD_BLOCK_TBODY: + BLOCK_TBODY(e); + break; + case MD_BLOCK_TR: + BLOCK_TR(e); + break; + case MD_BLOCK_TH: + BLOCK_TH((MD_BLOCK_TD_DETAIL*)d, e); + break; + case MD_BLOCK_TD: + BLOCK_TD((MD_BLOCK_TD_DETAIL*)d, e); + break; + default: + assert(false); + break; + } + + return 0; +} + +int imgui_md::span(MD_SPANTYPE type, void* d, bool e) +{ + switch (type) + { + case MD_SPAN_EM: + SPAN_EM(e); + break; + case MD_SPAN_STRONG: + SPAN_STRONG(e); + break; + case MD_SPAN_A: + SPAN_A((MD_SPAN_A_DETAIL*)d, e); + break; + case MD_SPAN_IMG: + SPAN_IMG((MD_SPAN_IMG_DETAIL*)d, e); + break; + case MD_SPAN_CODE: + SPAN_CODE(e); + break; + case MD_SPAN_DEL: + SPAN_DEL(e); + break; + case MD_SPAN_LATEXMATH: + SPAN_LATEXMATH(e); + break; + case MD_SPAN_LATEXMATH_DISPLAY: + SPAN_LATEXMATH_DISPLAY(e); + break; + case MD_SPAN_WIKILINK: + SPAN_WIKILINK((MD_SPAN_WIKILINK_DETAIL*)d, e); + break; + case MD_SPAN_U: + SPAN_U(e); + break; + default: + assert(false); + break; + } + + return 0; +} + +int imgui_md::print(const char* str, const char* str_end) +{ + if (str >= str_end) + return 0; + + // Markdown rendering always start with a call to ImGui::NewLine() + ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetFontSize() - ImGui::GetStyle().FramePadding.y); + return md_parse(str, (MD_SIZE)(str_end - str), &m_md, this); +} + +//////////////////////////////////////////////////////////////////////////////// + +ImFont* imgui_md::get_font() const +{ + return nullptr;//default font + + //Example: +#if 0 + if (m_is_table_header) { + return g_font_bold; + } + + switch (m_hlevel) + { + case 0: + return m_is_strong ? g_font_bold : g_font_regular; + case 1: + return g_font_bold_large; + default: + return g_font_bold; + } +#endif + +}; + +ImVec4 LinkColor() +{ + auto col_text = ImGui::GetStyle().Colors[ImGuiCol_Text]; + + float h, s, v; + ImGui::ColorConvertRGBtoHSV(col_text.x, col_text.y, col_text.z, h, s, v); + h = 0.57f; + if (v >= 0.8f) + v = 0.8f; + if (v <= 0.5f) + v = 0.5f; + if (s <= 0.5f) + s = 0.5f; + + ImGui::ColorConvertHSVtoRGB(h, s, v, col_text.x, col_text.y, col_text.z); + return col_text; +} + + +ImVec4 imgui_md::get_color() const +{ + if (!m_href.empty()) + { + return LinkColor(); + } + return ImGui::GetStyle().Colors[ImGuiCol_Text]; +} + + +bool imgui_md::get_image(image_info& nfo) const +{ + //Use m_href to identify images + + //Example - Imgui font texture + nfo.texture_id = ImGui::GetIO().Fonts->TexID; + nfo.size = { 100,50 }; + nfo.uv0 = { 0,0 }; + nfo.uv1 = { 1,1 }; + nfo.col_tint = { 1,1,1,1 }; + nfo.col_border = { 0,0,0,0 }; + + return true; +}; + +void imgui_md::open_url() const +{ + //Example: + +#if 0 + if (!m_is_image) { + SDL_OpenURL(m_href.c_str()); + } else { + //image clicked + } +#endif +} + +void imgui_md::soft_break() +{ + // Convert a soft break (e.g. a new line inside a paragraph into a space) + ImGui::TextUnformatted(" "); + ImGui::SameLine(0.0f, 0.0f); +} diff --git a/Src/Orbiter/imgui_md.h b/Src/Orbiter/imgui_md.h new file mode 100644 index 000000000..44d7e1168 --- /dev/null +++ b/Src/Orbiter/imgui_md.h @@ -0,0 +1,173 @@ +/* + * imgui_md: Markdown for Dear ImGui using MD4C + * (http://https://github.com/mekhontsev/imgui_md) + * + * Copyright (c) 2021 Dmitry Mekhontsev + * + * 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 IMGUI_MD_H +#define IMGUI_MD_H + +#include "md4c.h" +#include "imgui.h" +#include +#include + +struct imgui_md +{ + imgui_md(); + virtual ~imgui_md() {}; + + //returns 0 on success + int print(const char* str, const char* str_end); + + //for example, these flags can be changed in div callback + + //draw border + bool m_table_border = true; + //render header in a different way than other rows + bool m_table_header_highlight = true; + +protected: + + virtual void BLOCK_DOC(bool); + virtual void BLOCK_QUOTE(bool); + virtual void BLOCK_UL(const MD_BLOCK_UL_DETAIL*, bool); + virtual void BLOCK_OL(const MD_BLOCK_OL_DETAIL*, bool); + virtual void BLOCK_LI(const MD_BLOCK_LI_DETAIL*, bool); + virtual void BLOCK_HR(bool e); + virtual void BLOCK_H(const MD_BLOCK_H_DETAIL* d, bool e); + virtual void BLOCK_CODE(const MD_BLOCK_CODE_DETAIL*, bool); + virtual void BLOCK_HTML(bool); + virtual void BLOCK_P(bool); + virtual void BLOCK_TABLE(const MD_BLOCK_TABLE_DETAIL*, bool); + virtual void BLOCK_THEAD(bool); + virtual void BLOCK_TBODY(bool); + virtual void BLOCK_TR(bool); + virtual void BLOCK_TH(const MD_BLOCK_TD_DETAIL*, bool); + virtual void BLOCK_TD(const MD_BLOCK_TD_DETAIL*, bool); + + virtual void SPAN_EM(bool e); + virtual void SPAN_STRONG(bool e); + virtual void SPAN_A(const MD_SPAN_A_DETAIL* d, bool e); + virtual void SPAN_IMG(const MD_SPAN_IMG_DETAIL*, bool); + virtual void SPAN_CODE(bool); + virtual void SPAN_DEL(bool); + virtual void SPAN_LATEXMATH(bool); + virtual void SPAN_LATEXMATH_DISPLAY(bool); + virtual void SPAN_WIKILINK(const MD_SPAN_WIKILINK_DETAIL*, bool); + virtual void SPAN_U(bool); + + //////////////////////////////////////////////////////////////////////////// + + struct image_info + { + ImTextureID texture_id; + ImVec2 size; + ImVec2 uv0; + ImVec2 uv1; + ImVec4 col_tint; + ImVec4 col_border; + }; + + //use m_href to identify image + virtual bool get_image(image_info& nfo) const; + + virtual ImFont* get_font() const; + virtual ImVec4 get_color() const; + + // By default, code blocks are rendered as text with the code font, but you can override this + virtual void render_code_block(); + + //url == m_href + virtual void open_url() const; + + //returns true if the term has been processed + virtual bool render_entity(const char* str, const char* str_end); + + //returns true if the term has been processed + virtual bool check_html(const char* str, const char* str_end); + + //called when '\n' in source text where it is not semantically meaningful + virtual void soft_break(); + + //e==true : enter + //e==false : leave + virtual void html_div(const std::string& dclass, bool e); + //////////////////////////////////////////////////////////////////////////// + + virtual void push_code_style(); + virtual void pop_code_style(); + + //current state + std::string m_href;//empty if no link/image + std::string m_img_src;//empty if no link/image + + bool m_is_underline=false; + bool m_is_strikethrough = false; + bool m_is_em = false; + bool m_is_strong = false; + bool m_is_table_header = false; + bool m_is_table_body = false; + bool m_is_image = false; + bool m_is_code = false; // true for block code and inline code + bool m_is_code_block = false; + std::string m_code_block_language; + std::string m_code_block; + unsigned m_hlevel=0;//0 - no heading + +private: + + int text(MD_TEXTTYPE type, const char* str, const char* str_end); + int block(MD_BLOCKTYPE type, void* d, bool e); + int span(MD_SPANTYPE type, void* d, bool e); + + void render_text(const char* str, const char* str_end); + void render_inline_code(const char* str, const char* str_end); + + void set_font(bool e); + void set_color(bool e); + void set_href(bool e, const MD_ATTRIBUTE& src); + void set_img_src(bool e, const MD_ATTRIBUTE& src); + + static void line(ImColor c, bool under); + + //table state + int m_table_next_column = 0; + ImVec2 m_table_last_pos; + std::vector m_table_col_pos; + std::vector m_table_row_pos; + + //list state + struct list_info + { + unsigned cur_ol; + char delim; + bool is_ol; + }; + std::vector m_list_stack; + + std::vector m_div_stack; + + MD_PARSER m_md; +}; + +#endif /* IMGUI_MD_H */ \ No newline at end of file diff --git a/Src/Orbiter/md4c.c b/Src/Orbiter/md4c.c new file mode 100644 index 000000000..e3f5cf9d0 --- /dev/null +++ b/Src/Orbiter/md4c.c @@ -0,0 +1,6492 @@ +/* + * MD4C: Markdown parser for C + * (http://github.com/mity/md4c) + * + * Copyright (c) 2016-2024 Martin Mitáš + * + * 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 "md4c.h" + +#include +#include +#include +#include +#include + + +/***************************** + *** Miscellaneous Stuff *** + *****************************/ + +#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199409L + /* C89/90 or old compilers in general may not understand "inline". */ + #if defined __GNUC__ + #define inline __inline__ + #elif defined _MSC_VER + #define inline __inline + #else + #define inline + #endif +#endif + +/* Make the UTF-8 support the default. */ +#if !defined MD4C_USE_ASCII && !defined MD4C_USE_UTF8 && !defined MD4C_USE_UTF16 + #define MD4C_USE_UTF8 +#endif + +/* Magic for making wide literals with MD4C_USE_UTF16. */ +#ifdef _T + #undef _T +#endif +#if defined MD4C_USE_UTF16 + #define _T(x) L##x +#else + #define _T(x) x +#endif + +/* Misc. macros. */ +#define SIZEOF_ARRAY(a) (sizeof(a) / sizeof(a[0])) + +#define STRINGIZE_(x) #x +#define STRINGIZE(x) STRINGIZE_(x) + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +#ifndef TRUE + #define TRUE 1 + #define FALSE 0 +#endif + +#define MD_LOG(msg) \ + do { \ + if(ctx->parser.debug_log != NULL) \ + ctx->parser.debug_log((msg), ctx->userdata); \ + } while(0) + +#ifdef DEBUG + #define MD_ASSERT(cond) \ + do { \ + if(!(cond)) { \ + MD_LOG(__FILE__ ":" STRINGIZE(__LINE__) ": " \ + "Assertion '" STRINGIZE(cond) "' failed."); \ + exit(1); \ + } \ + } while(0) + + #define MD_UNREACHABLE() MD_ASSERT(1 == 0) +#else + #ifdef __GNUC__ + #define MD_ASSERT(cond) do { if(!(cond)) __builtin_unreachable(); } while(0) + #define MD_UNREACHABLE() do { __builtin_unreachable(); } while(0) + #elif defined _MSC_VER && _MSC_VER > 120 + #define MD_ASSERT(cond) do { __assume(cond); } while(0) + #define MD_UNREACHABLE() do { __assume(0); } while(0) + #else + #define MD_ASSERT(cond) do {} while(0) + #define MD_UNREACHABLE() do {} while(0) + #endif +#endif + +/* For falling through case labels in switch statements. */ +#if defined __clang__ && __clang_major__ >= 12 + #define MD_FALLTHROUGH() __attribute__((fallthrough)) +#elif defined __GNUC__ && __GNUC__ >= 7 + #define MD_FALLTHROUGH() __attribute__((fallthrough)) +#else + #define MD_FALLTHROUGH() ((void)0) +#endif + +/* Suppress "unused parameter" warnings. */ +#define MD_UNUSED(x) ((void)x) + + +/****************************** + *** Some internal limits *** + ******************************/ + +/* We limit code span marks to lower than 32 backticks. This solves the + * pathologic case of too many openers, each of different length: Their + * resolving would be then O(n^2). */ +#define CODESPAN_MARK_MAXLEN 32 + +/* We limit column count of tables to prevent quadratic explosion of output + * from pathological input of a table thousands of columns and thousands + * of rows where rows are requested with as little as single character + * per-line, relying on us to "helpfully" fill all the missing "". */ +#define TABLE_MAXCOLCOUNT 128 + + +/************************ + *** Internal Types *** + ************************/ + +/* These are omnipresent so lets save some typing. */ +#define CHAR MD_CHAR +#define SZ MD_SIZE +#define OFF MD_OFFSET + +#define SZ_MAX (sizeof(SZ) == 8 ? UINT64_MAX : UINT32_MAX) +#define OFF_MAX (sizeof(OFF) == 8 ? UINT64_MAX : UINT32_MAX) + +typedef struct MD_MARK_tag MD_MARK; +typedef struct MD_BLOCK_tag MD_BLOCK; +typedef struct MD_CONTAINER_tag MD_CONTAINER; +typedef struct MD_REF_DEF_tag MD_REF_DEF; + + +/* During analyzes of inline marks, we need to manage stacks of unresolved + * openers of the given type. + * The stack connects the marks via MD_MARK::next; + */ +typedef struct MD_MARKSTACK_tag MD_MARKSTACK; +struct MD_MARKSTACK_tag { + int top; /* -1 if empty. */ +}; + +/* Context propagated through all the parsing. */ +typedef struct MD_CTX_tag MD_CTX; +struct MD_CTX_tag { + /* Immutable stuff (parameters of md_parse()). */ + const CHAR* text; + SZ size; + MD_PARSER parser; + void* userdata; + + /* When this is true, it allows some optimizations. */ + int doc_ends_with_newline; + + /* Helper temporary growing buffer. */ + CHAR* buffer; + unsigned alloc_buffer; + + /* Reference definitions. */ + MD_REF_DEF* ref_defs; + int n_ref_defs; + int alloc_ref_defs; + void** ref_def_hashtable; + int ref_def_hashtable_size; + SZ max_ref_def_output; + + /* Stack of inline/span markers. + * This is only used for parsing a single block contents but by storing it + * here we may reuse the stack for subsequent blocks; i.e. we have fewer + * (re)allocations. */ + MD_MARK* marks; + int n_marks; + int alloc_marks; + +#if defined MD4C_USE_UTF16 + char mark_char_map[128]; +#else + char mark_char_map[256]; +#endif + + /* For resolving of inline spans. */ + MD_MARKSTACK opener_stacks[16]; +#define ASTERISK_OPENERS_oo_mod3_0 (ctx->opener_stacks[0]) /* Opener-only */ +#define ASTERISK_OPENERS_oo_mod3_1 (ctx->opener_stacks[1]) +#define ASTERISK_OPENERS_oo_mod3_2 (ctx->opener_stacks[2]) +#define ASTERISK_OPENERS_oc_mod3_0 (ctx->opener_stacks[3]) /* Both opener and closer candidate */ +#define ASTERISK_OPENERS_oc_mod3_1 (ctx->opener_stacks[4]) +#define ASTERISK_OPENERS_oc_mod3_2 (ctx->opener_stacks[5]) +#define UNDERSCORE_OPENERS_oo_mod3_0 (ctx->opener_stacks[6]) /* Opener-only */ +#define UNDERSCORE_OPENERS_oo_mod3_1 (ctx->opener_stacks[7]) +#define UNDERSCORE_OPENERS_oo_mod3_2 (ctx->opener_stacks[8]) +#define UNDERSCORE_OPENERS_oc_mod3_0 (ctx->opener_stacks[9]) /* Both opener and closer candidate */ +#define UNDERSCORE_OPENERS_oc_mod3_1 (ctx->opener_stacks[10]) +#define UNDERSCORE_OPENERS_oc_mod3_2 (ctx->opener_stacks[11]) +#define TILDE_OPENERS_1 (ctx->opener_stacks[12]) +#define TILDE_OPENERS_2 (ctx->opener_stacks[13]) +#define BRACKET_OPENERS (ctx->opener_stacks[14]) +#define DOLLAR_OPENERS (ctx->opener_stacks[15]) + + /* Stack of dummies which need to call free() for pointers stored in them. + * These are constructed during inline parsing and freed after all the block + * is processed (i.e. all callbacks referring those strings are called). */ + MD_MARKSTACK ptr_stack; + + /* For resolving table rows. */ + int n_table_cell_boundaries; + int table_cell_boundaries_head; + int table_cell_boundaries_tail; + + /* For resolving links. */ + int unresolved_link_head; + int unresolved_link_tail; + + /* For resolving raw HTML. */ + OFF html_comment_horizon; + OFF html_proc_instr_horizon; + OFF html_decl_horizon; + OFF html_cdata_horizon; + + /* For block analysis. + * Notes: + * -- It holds MD_BLOCK as well as MD_LINE structures. After each + * MD_BLOCK, its (multiple) MD_LINE(s) follow. + * -- For MD_BLOCK_HTML and MD_BLOCK_CODE, MD_VERBATIMLINE(s) are used + * instead of MD_LINE(s). + */ + void* block_bytes; + MD_BLOCK* current_block; + int n_block_bytes; + int alloc_block_bytes; + + /* For container block analysis. */ + MD_CONTAINER* containers; + int n_containers; + int alloc_containers; + + /* Minimal indentation to call the block "indented code block". */ + unsigned code_indent_offset; + + /* Contextual info for line analysis. */ + SZ code_fence_length; /* For checking closing fence length. */ + int html_block_type; /* For checking closing raw HTML condition. */ + int last_line_has_list_loosening_effect; + int last_list_item_starts_with_two_blank_lines; +}; + +enum MD_LINETYPE_tag { + MD_LINE_BLANK, + MD_LINE_HR, + MD_LINE_ATXHEADER, + MD_LINE_SETEXTHEADER, + MD_LINE_SETEXTUNDERLINE, + MD_LINE_INDENTEDCODE, + MD_LINE_FENCEDCODE, + MD_LINE_HTML, + MD_LINE_TEXT, + MD_LINE_TABLE, + MD_LINE_TABLEUNDERLINE +}; +typedef enum MD_LINETYPE_tag MD_LINETYPE; + +typedef struct MD_LINE_ANALYSIS_tag MD_LINE_ANALYSIS; +struct MD_LINE_ANALYSIS_tag { + MD_LINETYPE type; + unsigned data; + int enforce_new_block; + OFF beg; + OFF end; + unsigned indent; /* Indentation level. */ +}; + +typedef struct MD_LINE_tag MD_LINE; +struct MD_LINE_tag { + OFF beg; + OFF end; +}; + +typedef struct MD_VERBATIMLINE_tag MD_VERBATIMLINE; +struct MD_VERBATIMLINE_tag { + OFF beg; + OFF end; + OFF indent; +}; + + +/***************** + *** Helpers *** + *****************/ + +/* Character accessors. */ +#define CH(off) (ctx->text[(off)]) +#define STR(off) (ctx->text + (off)) + +/* Character classification. + * Note we assume ASCII compatibility of code points < 128 here. */ +#define ISIN_(ch, ch_min, ch_max) ((ch_min) <= (unsigned)(ch) && (unsigned)(ch) <= (ch_max)) +#define ISANYOF_(ch, palette) ((ch) != _T('\0') && md_strchr((palette), (ch)) != NULL) +#define ISANYOF2_(ch, ch1, ch2) ((ch) == (ch1) || (ch) == (ch2)) +#define ISANYOF3_(ch, ch1, ch2, ch3) ((ch) == (ch1) || (ch) == (ch2) || (ch) == (ch3)) +#define ISASCII_(ch) ((unsigned)(ch) <= 127) +#define ISBLANK_(ch) (ISANYOF2_((ch), _T(' '), _T('\t'))) +#define ISNEWLINE_(ch) (ISANYOF2_((ch), _T('\r'), _T('\n'))) +#define ISWHITESPACE_(ch) (ISBLANK_(ch) || ISANYOF2_((ch), _T('\v'), _T('\f'))) +#define ISCNTRL_(ch) ((unsigned)(ch) <= 31 || (unsigned)(ch) == 127) +#define ISPUNCT_(ch) (ISIN_(ch, 33, 47) || ISIN_(ch, 58, 64) || ISIN_(ch, 91, 96) || ISIN_(ch, 123, 126)) +#define ISUPPER_(ch) (ISIN_(ch, _T('A'), _T('Z'))) +#define ISLOWER_(ch) (ISIN_(ch, _T('a'), _T('z'))) +#define ISALPHA_(ch) (ISUPPER_(ch) || ISLOWER_(ch)) +#define ISDIGIT_(ch) (ISIN_(ch, _T('0'), _T('9'))) +#define ISXDIGIT_(ch) (ISDIGIT_(ch) || ISIN_(ch, _T('A'), _T('F')) || ISIN_(ch, _T('a'), _T('f'))) +#define ISALNUM_(ch) (ISALPHA_(ch) || ISDIGIT_(ch)) + +#define ISANYOF(off, palette) ISANYOF_(CH(off), (palette)) +#define ISANYOF2(off, ch1, ch2) ISANYOF2_(CH(off), (ch1), (ch2)) +#define ISANYOF3(off, ch1, ch2, ch3) ISANYOF3_(CH(off), (ch1), (ch2), (ch3)) +#define ISASCII(off) ISASCII_(CH(off)) +#define ISBLANK(off) ISBLANK_(CH(off)) +#define ISNEWLINE(off) ISNEWLINE_(CH(off)) +#define ISWHITESPACE(off) ISWHITESPACE_(CH(off)) +#define ISCNTRL(off) ISCNTRL_(CH(off)) +#define ISPUNCT(off) ISPUNCT_(CH(off)) +#define ISUPPER(off) ISUPPER_(CH(off)) +#define ISLOWER(off) ISLOWER_(CH(off)) +#define ISALPHA(off) ISALPHA_(CH(off)) +#define ISDIGIT(off) ISDIGIT_(CH(off)) +#define ISXDIGIT(off) ISXDIGIT_(CH(off)) +#define ISALNUM(off) ISALNUM_(CH(off)) + + +#if defined MD4C_USE_UTF16 + #define md_strchr wcschr +#else + #define md_strchr strchr +#endif + + +/* Case insensitive check of string equality. */ +static inline int +md_ascii_case_eq(const CHAR* s1, const CHAR* s2, SZ n) +{ + OFF i; + for(i = 0; i < n; i++) { + CHAR ch1 = s1[i]; + CHAR ch2 = s2[i]; + + if(ISLOWER_(ch1)) + ch1 += ('A'-'a'); + if(ISLOWER_(ch2)) + ch2 += ('A'-'a'); + if(ch1 != ch2) + return FALSE; + } + return TRUE; +} + +static inline int +md_ascii_eq(const CHAR* s1, const CHAR* s2, SZ n) +{ + return memcmp(s1, s2, n * sizeof(CHAR)) == 0; +} + +static int +md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ size) +{ + OFF off = 0; + int ret = 0; + + while(1) { + while(off < size && str[off] != _T('\0')) + off++; + + if(off > 0) { + ret = ctx->parser.text(type, str, off, ctx->userdata); + if(ret != 0) + return ret; + + str += off; + size -= off; + off = 0; + } + + if(off >= size) + return 0; + + ret = ctx->parser.text(MD_TEXT_NULLCHAR, _T(""), 1, ctx->userdata); + if(ret != 0) + return ret; + off++; + } +} + + +#define MD_CHECK(func) \ + do { \ + ret = (func); \ + if(ret < 0) \ + goto abort; \ + } while(0) + + +#define MD_TEMP_BUFFER(sz) \ + do { \ + if(sz > ctx->alloc_buffer) { \ + CHAR* new_buffer; \ + SZ new_size = ((sz) + (sz) / 2 + 128) & ~127; \ + \ + new_buffer = realloc(ctx->buffer, new_size); \ + if(new_buffer == NULL) { \ + MD_LOG("realloc() failed."); \ + ret = -1; \ + goto abort; \ + } \ + \ + ctx->buffer = new_buffer; \ + ctx->alloc_buffer = new_size; \ + } \ + } while(0) + + +#define MD_ENTER_BLOCK(type, arg) \ + do { \ + ret = ctx->parser.enter_block((type), (arg), ctx->userdata); \ + if(ret != 0) { \ + MD_LOG("Aborted from enter_block() callback."); \ + goto abort; \ + } \ + } while(0) + +#define MD_LEAVE_BLOCK(type, arg) \ + do { \ + ret = ctx->parser.leave_block((type), (arg), ctx->userdata); \ + if(ret != 0) { \ + MD_LOG("Aborted from leave_block() callback."); \ + goto abort; \ + } \ + } while(0) + +#define MD_ENTER_SPAN(type, arg) \ + do { \ + ret = ctx->parser.enter_span((type), (arg), ctx->userdata); \ + if(ret != 0) { \ + MD_LOG("Aborted from enter_span() callback."); \ + goto abort; \ + } \ + } while(0) + +#define MD_LEAVE_SPAN(type, arg) \ + do { \ + ret = ctx->parser.leave_span((type), (arg), ctx->userdata); \ + if(ret != 0) { \ + MD_LOG("Aborted from leave_span() callback."); \ + goto abort; \ + } \ + } while(0) + +#define MD_TEXT(type, str, size) \ + do { \ + if(size > 0) { \ + ret = ctx->parser.text((type), (str), (size), ctx->userdata); \ + if(ret != 0) { \ + MD_LOG("Aborted from text() callback."); \ + goto abort; \ + } \ + } \ + } while(0) + +#define MD_TEXT_INSECURE(type, str, size) \ + do { \ + if(size > 0) { \ + ret = md_text_with_null_replacement(ctx, type, str, size); \ + if(ret != 0) { \ + MD_LOG("Aborted from text() callback."); \ + goto abort; \ + } \ + } \ + } while(0) + + +/* If the offset falls into a gap between line, we return the following + * line. */ +static const MD_LINE* +md_lookup_line(OFF off, const MD_LINE* lines, MD_SIZE n_lines, MD_SIZE* p_line_index) +{ + MD_SIZE lo, hi; + MD_SIZE pivot; + const MD_LINE* line; + + lo = 0; + hi = n_lines - 1; + while(lo <= hi) { + pivot = (lo + hi) / 2; + line = &lines[pivot]; + + if(off < line->beg) { + if(hi == 0 || lines[hi-1].end < off) { + if(p_line_index != NULL) + *p_line_index = pivot; + return line; + } + hi = pivot - 1; + } else if(off > line->end) { + lo = pivot + 1; + } else { + if(p_line_index != NULL) + *p_line_index = pivot; + return line; + } + } + + return NULL; +} + + +/************************* + *** Unicode Support *** + *************************/ + +typedef struct MD_UNICODE_FOLD_INFO_tag MD_UNICODE_FOLD_INFO; +struct MD_UNICODE_FOLD_INFO_tag { + unsigned codepoints[3]; + unsigned n_codepoints; +}; + + +#if defined MD4C_USE_UTF16 || defined MD4C_USE_UTF8 + /* Binary search over sorted "map" of codepoints. Consecutive sequences + * of codepoints may be encoded in the map by just using the + * (MIN_CODEPOINT | 0x40000000) and (MAX_CODEPOINT | 0x80000000). + * + * Returns index of the found record in the map (in the case of ranges, + * the minimal value is used); or -1 on failure. */ + static int + md_unicode_bsearch__(unsigned codepoint, const unsigned* map, size_t map_size) + { + int beg, end; + int pivot_beg, pivot_end; + + beg = 0; + end = (int) map_size-1; + while(beg <= end) { + /* Pivot may be a range, not just a single value. */ + pivot_beg = pivot_end = (beg + end) / 2; + if(map[pivot_end] & 0x40000000) + pivot_end++; + if(map[pivot_beg] & 0x80000000) + pivot_beg--; + + if(codepoint < (map[pivot_beg] & 0x00ffffff)) + end = pivot_beg - 1; + else if(codepoint > (map[pivot_end] & 0x00ffffff)) + beg = pivot_end + 1; + else + return pivot_beg; + } + + return -1; + } + + static int + md_is_unicode_whitespace__(unsigned codepoint) + { +#define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) +#define S(cp) (cp) + /* Unicode "Zs" category. + * (generated by scripts/build_whitespace_map.py) */ + static const unsigned WHITESPACE_MAP[] = { + S(0x0020), S(0x00a0), S(0x1680), R(0x2000,0x200a), S(0x202f), S(0x205f), S(0x3000) + }; +#undef R +#undef S + + /* The ASCII ones are the most frequently used ones, also CommonMark + * specification requests few more in this range. */ + if(codepoint <= 0x7f) + return ISWHITESPACE_(codepoint); + + return (md_unicode_bsearch__(codepoint, WHITESPACE_MAP, SIZEOF_ARRAY(WHITESPACE_MAP)) >= 0); + } + + static int + md_is_unicode_punct__(unsigned codepoint) + { +#define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) +#define S(cp) (cp) + /* Unicode general "P" and "S" categories. + * (generated by scripts/build_punct_map.py) */ + static const unsigned PUNCT_MAP[] = { + R(0x0021,0x002f), R(0x003a,0x0040), R(0x005b,0x0060), R(0x007b,0x007e), R(0x00a1,0x00a9), + R(0x00ab,0x00ac), R(0x00ae,0x00b1), S(0x00b4), R(0x00b6,0x00b8), S(0x00bb), S(0x00bf), S(0x00d7), + S(0x00f7), R(0x02c2,0x02c5), R(0x02d2,0x02df), R(0x02e5,0x02eb), S(0x02ed), R(0x02ef,0x02ff), S(0x0375), + S(0x037e), R(0x0384,0x0385), S(0x0387), S(0x03f6), S(0x0482), R(0x055a,0x055f), R(0x0589,0x058a), + R(0x058d,0x058f), S(0x05be), S(0x05c0), S(0x05c3), S(0x05c6), R(0x05f3,0x05f4), R(0x0606,0x060f), + S(0x061b), R(0x061d,0x061f), R(0x066a,0x066d), S(0x06d4), S(0x06de), S(0x06e9), R(0x06fd,0x06fe), + R(0x0700,0x070d), R(0x07f6,0x07f9), R(0x07fe,0x07ff), R(0x0830,0x083e), S(0x085e), S(0x0888), + R(0x0964,0x0965), S(0x0970), R(0x09f2,0x09f3), R(0x09fa,0x09fb), S(0x09fd), S(0x0a76), R(0x0af0,0x0af1), + S(0x0b70), R(0x0bf3,0x0bfa), S(0x0c77), S(0x0c7f), S(0x0c84), S(0x0d4f), S(0x0d79), S(0x0df4), S(0x0e3f), + S(0x0e4f), R(0x0e5a,0x0e5b), R(0x0f01,0x0f17), R(0x0f1a,0x0f1f), S(0x0f34), S(0x0f36), S(0x0f38), + R(0x0f3a,0x0f3d), S(0x0f85), R(0x0fbe,0x0fc5), R(0x0fc7,0x0fcc), R(0x0fce,0x0fda), R(0x104a,0x104f), + R(0x109e,0x109f), S(0x10fb), R(0x1360,0x1368), R(0x1390,0x1399), S(0x1400), R(0x166d,0x166e), + R(0x169b,0x169c), R(0x16eb,0x16ed), R(0x1735,0x1736), R(0x17d4,0x17d6), R(0x17d8,0x17db), + R(0x1800,0x180a), S(0x1940), R(0x1944,0x1945), R(0x19de,0x19ff), R(0x1a1e,0x1a1f), R(0x1aa0,0x1aa6), + R(0x1aa8,0x1aad), R(0x1b5a,0x1b6a), R(0x1b74,0x1b7e), R(0x1bfc,0x1bff), R(0x1c3b,0x1c3f), + R(0x1c7e,0x1c7f), R(0x1cc0,0x1cc7), S(0x1cd3), S(0x1fbd), R(0x1fbf,0x1fc1), R(0x1fcd,0x1fcf), + R(0x1fdd,0x1fdf), R(0x1fed,0x1fef), R(0x1ffd,0x1ffe), R(0x2010,0x2027), R(0x2030,0x205e), + R(0x207a,0x207e), R(0x208a,0x208e), R(0x20a0,0x20c0), R(0x2100,0x2101), R(0x2103,0x2106), + R(0x2108,0x2109), S(0x2114), R(0x2116,0x2118), R(0x211e,0x2123), S(0x2125), S(0x2127), S(0x2129), + S(0x212e), R(0x213a,0x213b), R(0x2140,0x2144), R(0x214a,0x214d), S(0x214f), R(0x218a,0x218b), + R(0x2190,0x2426), R(0x2440,0x244a), R(0x249c,0x24e9), R(0x2500,0x2775), R(0x2794,0x2b73), + R(0x2b76,0x2b95), R(0x2b97,0x2bff), R(0x2ce5,0x2cea), R(0x2cf9,0x2cfc), R(0x2cfe,0x2cff), S(0x2d70), + R(0x2e00,0x2e2e), R(0x2e30,0x2e5d), R(0x2e80,0x2e99), R(0x2e9b,0x2ef3), R(0x2f00,0x2fd5), + R(0x2ff0,0x2fff), R(0x3001,0x3004), R(0x3008,0x3020), S(0x3030), R(0x3036,0x3037), R(0x303d,0x303f), + R(0x309b,0x309c), S(0x30a0), S(0x30fb), R(0x3190,0x3191), R(0x3196,0x319f), R(0x31c0,0x31e3), S(0x31ef), + R(0x3200,0x321e), R(0x322a,0x3247), S(0x3250), R(0x3260,0x327f), R(0x328a,0x32b0), R(0x32c0,0x33ff), + R(0x4dc0,0x4dff), R(0xa490,0xa4c6), R(0xa4fe,0xa4ff), R(0xa60d,0xa60f), S(0xa673), S(0xa67e), + R(0xa6f2,0xa6f7), R(0xa700,0xa716), R(0xa720,0xa721), R(0xa789,0xa78a), R(0xa828,0xa82b), + R(0xa836,0xa839), R(0xa874,0xa877), R(0xa8ce,0xa8cf), R(0xa8f8,0xa8fa), S(0xa8fc), R(0xa92e,0xa92f), + S(0xa95f), R(0xa9c1,0xa9cd), R(0xa9de,0xa9df), R(0xaa5c,0xaa5f), R(0xaa77,0xaa79), R(0xaade,0xaadf), + R(0xaaf0,0xaaf1), S(0xab5b), R(0xab6a,0xab6b), S(0xabeb), S(0xfb29), R(0xfbb2,0xfbc2), R(0xfd3e,0xfd4f), + S(0xfdcf), R(0xfdfc,0xfdff), R(0xfe10,0xfe19), R(0xfe30,0xfe52), R(0xfe54,0xfe66), R(0xfe68,0xfe6b), + R(0xff01,0xff0f), R(0xff1a,0xff20), R(0xff3b,0xff40), R(0xff5b,0xff65), R(0xffe0,0xffe6), + R(0xffe8,0xffee), R(0xfffc,0xfffd), R(0x10100,0x10102), R(0x10137,0x1013f), R(0x10179,0x10189), + R(0x1018c,0x1018e), R(0x10190,0x1019c), S(0x101a0), R(0x101d0,0x101fc), S(0x1039f), S(0x103d0), + S(0x1056f), S(0x10857), R(0x10877,0x10878), S(0x1091f), S(0x1093f), R(0x10a50,0x10a58), S(0x10a7f), + S(0x10ac8), R(0x10af0,0x10af6), R(0x10b39,0x10b3f), R(0x10b99,0x10b9c), S(0x10ead), R(0x10f55,0x10f59), + R(0x10f86,0x10f89), R(0x11047,0x1104d), R(0x110bb,0x110bc), R(0x110be,0x110c1), R(0x11140,0x11143), + R(0x11174,0x11175), R(0x111c5,0x111c8), S(0x111cd), S(0x111db), R(0x111dd,0x111df), R(0x11238,0x1123d), + S(0x112a9), R(0x1144b,0x1144f), R(0x1145a,0x1145b), S(0x1145d), S(0x114c6), R(0x115c1,0x115d7), + R(0x11641,0x11643), R(0x11660,0x1166c), S(0x116b9), R(0x1173c,0x1173f), S(0x1183b), R(0x11944,0x11946), + S(0x119e2), R(0x11a3f,0x11a46), R(0x11a9a,0x11a9c), R(0x11a9e,0x11aa2), R(0x11b00,0x11b09), + R(0x11c41,0x11c45), R(0x11c70,0x11c71), R(0x11ef7,0x11ef8), R(0x11f43,0x11f4f), R(0x11fd5,0x11ff1), + S(0x11fff), R(0x12470,0x12474), R(0x12ff1,0x12ff2), R(0x16a6e,0x16a6f), S(0x16af5), R(0x16b37,0x16b3f), + R(0x16b44,0x16b45), R(0x16e97,0x16e9a), S(0x16fe2), S(0x1bc9c), S(0x1bc9f), R(0x1cf50,0x1cfc3), + R(0x1d000,0x1d0f5), R(0x1d100,0x1d126), R(0x1d129,0x1d164), R(0x1d16a,0x1d16c), R(0x1d183,0x1d184), + R(0x1d18c,0x1d1a9), R(0x1d1ae,0x1d1ea), R(0x1d200,0x1d241), S(0x1d245), R(0x1d300,0x1d356), S(0x1d6c1), + S(0x1d6db), S(0x1d6fb), S(0x1d715), S(0x1d735), S(0x1d74f), S(0x1d76f), S(0x1d789), S(0x1d7a9), + S(0x1d7c3), R(0x1d800,0x1d9ff), R(0x1da37,0x1da3a), R(0x1da6d,0x1da74), R(0x1da76,0x1da83), + R(0x1da85,0x1da8b), S(0x1e14f), S(0x1e2ff), R(0x1e95e,0x1e95f), S(0x1ecac), S(0x1ecb0), S(0x1ed2e), + R(0x1eef0,0x1eef1), R(0x1f000,0x1f02b), R(0x1f030,0x1f093), R(0x1f0a0,0x1f0ae), R(0x1f0b1,0x1f0bf), + R(0x1f0c1,0x1f0cf), R(0x1f0d1,0x1f0f5), R(0x1f10d,0x1f1ad), R(0x1f1e6,0x1f202), R(0x1f210,0x1f23b), + R(0x1f240,0x1f248), R(0x1f250,0x1f251), R(0x1f260,0x1f265), R(0x1f300,0x1f6d7), R(0x1f6dc,0x1f6ec), + R(0x1f6f0,0x1f6fc), R(0x1f700,0x1f776), R(0x1f77b,0x1f7d9), R(0x1f7e0,0x1f7eb), S(0x1f7f0), + R(0x1f800,0x1f80b), R(0x1f810,0x1f847), R(0x1f850,0x1f859), R(0x1f860,0x1f887), R(0x1f890,0x1f8ad), + R(0x1f8b0,0x1f8b1), R(0x1f900,0x1fa53), R(0x1fa60,0x1fa6d), R(0x1fa70,0x1fa7c), R(0x1fa80,0x1fa88), + R(0x1fa90,0x1fabd), R(0x1fabf,0x1fac5), R(0x1face,0x1fadb), R(0x1fae0,0x1fae8), R(0x1faf0,0x1faf8), + R(0x1fb00,0x1fb92), R(0x1fb94,0x1fbca) + }; +#undef R +#undef S + + /* The ASCII ones are the most frequently used ones, also CommonMark + * specification requests few more in this range. */ + if(codepoint <= 0x7f) + return ISPUNCT_(codepoint); + + return (md_unicode_bsearch__(codepoint, PUNCT_MAP, SIZEOF_ARRAY(PUNCT_MAP)) >= 0); + } + + static void + md_get_unicode_fold_info(unsigned codepoint, MD_UNICODE_FOLD_INFO* info) + { +#define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) +#define S(cp) (cp) + /* Unicode "Pc", "Pd", "Pe", "Pf", "Pi", "Po", "Ps" categories. + * (generated by scripts/build_folding_map.py) */ + static const unsigned FOLD_MAP_1[] = { + R(0x0041,0x005a), S(0x00b5), R(0x00c0,0x00d6), R(0x00d8,0x00de), R(0x0100,0x012e), R(0x0132,0x0136), + R(0x0139,0x0147), R(0x014a,0x0176), S(0x0178), R(0x0179,0x017d), S(0x017f), S(0x0181), S(0x0182), + S(0x0184), S(0x0186), S(0x0187), S(0x0189), S(0x018a), S(0x018b), S(0x018e), S(0x018f), S(0x0190), + S(0x0191), S(0x0193), S(0x0194), S(0x0196), S(0x0197), S(0x0198), S(0x019c), S(0x019d), S(0x019f), + R(0x01a0,0x01a4), S(0x01a6), S(0x01a7), S(0x01a9), S(0x01ac), S(0x01ae), S(0x01af), S(0x01b1), S(0x01b2), + S(0x01b3), S(0x01b5), S(0x01b7), S(0x01b8), S(0x01bc), S(0x01c4), S(0x01c5), S(0x01c7), S(0x01c8), + S(0x01ca), R(0x01cb,0x01db), R(0x01de,0x01ee), S(0x01f1), S(0x01f2), S(0x01f4), S(0x01f6), S(0x01f7), + R(0x01f8,0x021e), S(0x0220), R(0x0222,0x0232), S(0x023a), S(0x023b), S(0x023d), S(0x023e), S(0x0241), + S(0x0243), S(0x0244), S(0x0245), R(0x0246,0x024e), S(0x0345), S(0x0370), S(0x0372), S(0x0376), S(0x037f), + S(0x0386), R(0x0388,0x038a), S(0x038c), S(0x038e), S(0x038f), R(0x0391,0x03a1), R(0x03a3,0x03ab), + S(0x03c2), S(0x03cf), S(0x03d0), S(0x03d1), S(0x03d5), S(0x03d6), R(0x03d8,0x03ee), S(0x03f0), S(0x03f1), + S(0x03f4), S(0x03f5), S(0x03f7), S(0x03f9), S(0x03fa), R(0x03fd,0x03ff), R(0x0400,0x040f), + R(0x0410,0x042f), R(0x0460,0x0480), R(0x048a,0x04be), S(0x04c0), R(0x04c1,0x04cd), R(0x04d0,0x052e), + R(0x0531,0x0556), R(0x10a0,0x10c5), S(0x10c7), S(0x10cd), R(0x13f8,0x13fd), S(0x1c80), S(0x1c81), + S(0x1c82), S(0x1c83), S(0x1c84), S(0x1c85), S(0x1c86), S(0x1c87), S(0x1c88), R(0x1c90,0x1cba), + R(0x1cbd,0x1cbf), R(0x1e00,0x1e94), S(0x1e9b), R(0x1ea0,0x1efe), R(0x1f08,0x1f0f), R(0x1f18,0x1f1d), + R(0x1f28,0x1f2f), R(0x1f38,0x1f3f), R(0x1f48,0x1f4d), S(0x1f59), S(0x1f5b), S(0x1f5d), S(0x1f5f), + R(0x1f68,0x1f6f), S(0x1fb8), S(0x1fb9), S(0x1fba), S(0x1fbb), S(0x1fbe), R(0x1fc8,0x1fcb), S(0x1fd8), + S(0x1fd9), S(0x1fda), S(0x1fdb), S(0x1fe8), S(0x1fe9), S(0x1fea), S(0x1feb), S(0x1fec), S(0x1ff8), + S(0x1ff9), S(0x1ffa), S(0x1ffb), S(0x2126), S(0x212a), S(0x212b), S(0x2132), R(0x2160,0x216f), S(0x2183), + R(0x24b6,0x24cf), R(0x2c00,0x2c2f), S(0x2c60), S(0x2c62), S(0x2c63), S(0x2c64), R(0x2c67,0x2c6b), + S(0x2c6d), S(0x2c6e), S(0x2c6f), S(0x2c70), S(0x2c72), S(0x2c75), S(0x2c7e), S(0x2c7f), R(0x2c80,0x2ce2), + S(0x2ceb), S(0x2ced), S(0x2cf2), R(0xa640,0xa66c), R(0xa680,0xa69a), R(0xa722,0xa72e), R(0xa732,0xa76e), + S(0xa779), S(0xa77b), S(0xa77d), R(0xa77e,0xa786), S(0xa78b), S(0xa78d), S(0xa790), S(0xa792), + R(0xa796,0xa7a8), S(0xa7aa), S(0xa7ab), S(0xa7ac), S(0xa7ad), S(0xa7ae), S(0xa7b0), S(0xa7b1), S(0xa7b2), + S(0xa7b3), R(0xa7b4,0xa7c2), S(0xa7c4), S(0xa7c5), S(0xa7c6), S(0xa7c7), S(0xa7c9), S(0xa7d0), S(0xa7d6), + S(0xa7d8), S(0xa7f5), R(0xab70,0xabbf), R(0xff21,0xff3a), R(0x10400,0x10427), R(0x104b0,0x104d3), + R(0x10570,0x1057a), R(0x1057c,0x1058a), R(0x1058c,0x10592), S(0x10594), S(0x10595), R(0x10c80,0x10cb2), + R(0x118a0,0x118bf), R(0x16e40,0x16e5f), R(0x1e900,0x1e921) + }; + static const unsigned FOLD_MAP_1_DATA[] = { + 0x0061, 0x007a, 0x03bc, 0x00e0, 0x00f6, 0x00f8, 0x00fe, 0x0101, 0x012f, 0x0133, 0x0137, 0x013a, 0x0148, + 0x014b, 0x0177, 0x00ff, 0x017a, 0x017e, 0x0073, 0x0253, 0x0183, 0x0185, 0x0254, 0x0188, 0x0256, 0x0257, + 0x018c, 0x01dd, 0x0259, 0x025b, 0x0192, 0x0260, 0x0263, 0x0269, 0x0268, 0x0199, 0x026f, 0x0272, 0x0275, + 0x01a1, 0x01a5, 0x0280, 0x01a8, 0x0283, 0x01ad, 0x0288, 0x01b0, 0x028a, 0x028b, 0x01b4, 0x01b6, 0x0292, + 0x01b9, 0x01bd, 0x01c6, 0x01c6, 0x01c9, 0x01c9, 0x01cc, 0x01cc, 0x01dc, 0x01df, 0x01ef, 0x01f3, 0x01f3, + 0x01f5, 0x0195, 0x01bf, 0x01f9, 0x021f, 0x019e, 0x0223, 0x0233, 0x2c65, 0x023c, 0x019a, 0x2c66, 0x0242, + 0x0180, 0x0289, 0x028c, 0x0247, 0x024f, 0x03b9, 0x0371, 0x0373, 0x0377, 0x03f3, 0x03ac, 0x03ad, 0x03af, + 0x03cc, 0x03cd, 0x03ce, 0x03b1, 0x03c1, 0x03c3, 0x03cb, 0x03c3, 0x03d7, 0x03b2, 0x03b8, 0x03c6, 0x03c0, + 0x03d9, 0x03ef, 0x03ba, 0x03c1, 0x03b8, 0x03b5, 0x03f8, 0x03f2, 0x03fb, 0x037b, 0x037d, 0x0450, 0x045f, + 0x0430, 0x044f, 0x0461, 0x0481, 0x048b, 0x04bf, 0x04cf, 0x04c2, 0x04ce, 0x04d1, 0x052f, 0x0561, 0x0586, + 0x2d00, 0x2d25, 0x2d27, 0x2d2d, 0x13f0, 0x13f5, 0x0432, 0x0434, 0x043e, 0x0441, 0x0442, 0x0442, 0x044a, + 0x0463, 0xa64b, 0x10d0, 0x10fa, 0x10fd, 0x10ff, 0x1e01, 0x1e95, 0x1e61, 0x1ea1, 0x1eff, 0x1f00, 0x1f07, + 0x1f10, 0x1f15, 0x1f20, 0x1f27, 0x1f30, 0x1f37, 0x1f40, 0x1f45, 0x1f51, 0x1f53, 0x1f55, 0x1f57, 0x1f60, + 0x1f67, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x03b9, 0x1f72, 0x1f75, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0x1fe0, + 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x03c9, 0x006b, 0x00e5, 0x214e, 0x2170, + 0x217f, 0x2184, 0x24d0, 0x24e9, 0x2c30, 0x2c5f, 0x2c61, 0x026b, 0x1d7d, 0x027d, 0x2c68, 0x2c6c, 0x0251, + 0x0271, 0x0250, 0x0252, 0x2c73, 0x2c76, 0x023f, 0x0240, 0x2c81, 0x2ce3, 0x2cec, 0x2cee, 0x2cf3, 0xa641, + 0xa66d, 0xa681, 0xa69b, 0xa723, 0xa72f, 0xa733, 0xa76f, 0xa77a, 0xa77c, 0x1d79, 0xa77f, 0xa787, 0xa78c, + 0x0265, 0xa791, 0xa793, 0xa797, 0xa7a9, 0x0266, 0x025c, 0x0261, 0x026c, 0x026a, 0x029e, 0x0287, 0x029d, + 0xab53, 0xa7b5, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8, 0xa7ca, 0xa7d1, 0xa7d7, 0xa7d9, 0xa7f6, 0x13a0, + 0x13ef, 0xff41, 0xff5a, 0x10428, 0x1044f, 0x104d8, 0x104fb, 0x10597, 0x105a1, 0x105a3, 0x105b1, 0x105b3, + 0x105b9, 0x105bb, 0x105bc, 0x10cc0, 0x10cf2, 0x118c0, 0x118df, 0x16e60, 0x16e7f, 0x1e922, 0x1e943 + }; + static const unsigned FOLD_MAP_2[] = { + S(0x00df), S(0x0130), S(0x0149), S(0x01f0), S(0x0587), S(0x1e96), S(0x1e97), S(0x1e98), S(0x1e99), + S(0x1e9a), S(0x1e9e), S(0x1f50), R(0x1f80,0x1f87), R(0x1f88,0x1f8f), R(0x1f90,0x1f97), R(0x1f98,0x1f9f), + R(0x1fa0,0x1fa7), R(0x1fa8,0x1faf), S(0x1fb2), S(0x1fb3), S(0x1fb4), S(0x1fb6), S(0x1fbc), S(0x1fc2), + S(0x1fc3), S(0x1fc4), S(0x1fc6), S(0x1fcc), S(0x1fd6), S(0x1fe4), S(0x1fe6), S(0x1ff2), S(0x1ff3), + S(0x1ff4), S(0x1ff6), S(0x1ffc), S(0xfb00), S(0xfb01), S(0xfb02), S(0xfb05), S(0xfb06), S(0xfb13), + S(0xfb14), S(0xfb15), S(0xfb16), S(0xfb17) + }; + static const unsigned FOLD_MAP_2_DATA[] = { + 0x0073,0x0073, 0x0069,0x0307, 0x02bc,0x006e, 0x006a,0x030c, 0x0565,0x0582, 0x0068,0x0331, 0x0074,0x0308, + 0x0077,0x030a, 0x0079,0x030a, 0x0061,0x02be, 0x0073,0x0073, 0x03c5,0x0313, 0x1f00,0x03b9, 0x1f07,0x03b9, + 0x1f00,0x03b9, 0x1f07,0x03b9, 0x1f20,0x03b9, 0x1f27,0x03b9, 0x1f20,0x03b9, 0x1f27,0x03b9, 0x1f60,0x03b9, + 0x1f67,0x03b9, 0x1f60,0x03b9, 0x1f67,0x03b9, 0x1f70,0x03b9, 0x03b1,0x03b9, 0x03ac,0x03b9, 0x03b1,0x0342, + 0x03b1,0x03b9, 0x1f74,0x03b9, 0x03b7,0x03b9, 0x03ae,0x03b9, 0x03b7,0x0342, 0x03b7,0x03b9, 0x03b9,0x0342, + 0x03c1,0x0313, 0x03c5,0x0342, 0x1f7c,0x03b9, 0x03c9,0x03b9, 0x03ce,0x03b9, 0x03c9,0x0342, 0x03c9,0x03b9, + 0x0066,0x0066, 0x0066,0x0069, 0x0066,0x006c, 0x0073,0x0074, 0x0073,0x0074, 0x0574,0x0576, 0x0574,0x0565, + 0x0574,0x056b, 0x057e,0x0576, 0x0574,0x056d + }; + static const unsigned FOLD_MAP_3[] = { + S(0x0390), S(0x03b0), S(0x1f52), S(0x1f54), S(0x1f56), S(0x1fb7), S(0x1fc7), S(0x1fd2), S(0x1fd3), + S(0x1fd7), S(0x1fe2), S(0x1fe3), S(0x1fe7), S(0x1ff7), S(0xfb03), S(0xfb04) + }; + static const unsigned FOLD_MAP_3_DATA[] = { + 0x03b9,0x0308,0x0301, 0x03c5,0x0308,0x0301, 0x03c5,0x0313,0x0300, 0x03c5,0x0313,0x0301, + 0x03c5,0x0313,0x0342, 0x03b1,0x0342,0x03b9, 0x03b7,0x0342,0x03b9, 0x03b9,0x0308,0x0300, + 0x03b9,0x0308,0x0301, 0x03b9,0x0308,0x0342, 0x03c5,0x0308,0x0300, 0x03c5,0x0308,0x0301, + 0x03c5,0x0308,0x0342, 0x03c9,0x0342,0x03b9, 0x0066,0x0066,0x0069, 0x0066,0x0066,0x006c + }; +#undef R +#undef S + static const struct { + const unsigned* map; + const unsigned* data; + size_t map_size; + unsigned n_codepoints; + } FOLD_MAP_LIST[] = { + { FOLD_MAP_1, FOLD_MAP_1_DATA, SIZEOF_ARRAY(FOLD_MAP_1), 1 }, + { FOLD_MAP_2, FOLD_MAP_2_DATA, SIZEOF_ARRAY(FOLD_MAP_2), 2 }, + { FOLD_MAP_3, FOLD_MAP_3_DATA, SIZEOF_ARRAY(FOLD_MAP_3), 3 } + }; + + int i; + + /* Fast path for ASCII characters. */ + if(codepoint <= 0x7f) { + info->codepoints[0] = codepoint; + if(ISUPPER_(codepoint)) + info->codepoints[0] += 'a' - 'A'; + info->n_codepoints = 1; + return; + } + + /* Try to locate the codepoint in any of the maps. */ + for(i = 0; i < (int) SIZEOF_ARRAY(FOLD_MAP_LIST); i++) { + int index; + + index = md_unicode_bsearch__(codepoint, FOLD_MAP_LIST[i].map, FOLD_MAP_LIST[i].map_size); + if(index >= 0) { + /* Found the mapping. */ + unsigned n_codepoints = FOLD_MAP_LIST[i].n_codepoints; + const unsigned* map = FOLD_MAP_LIST[i].map; + const unsigned* codepoints = FOLD_MAP_LIST[i].data + (index * n_codepoints); + + memcpy(info->codepoints, codepoints, sizeof(unsigned) * n_codepoints); + info->n_codepoints = n_codepoints; + + if(FOLD_MAP_LIST[i].map[index] != codepoint) { + /* The found mapping maps whole range of codepoints, + * i.e. we have to offset info->codepoints[0] accordingly. */ + if((map[index] & 0x00ffffff)+1 == codepoints[0]) { + /* Alternating type of the range. */ + info->codepoints[0] = codepoint + ((codepoint & 0x1) == (map[index] & 0x1) ? 1 : 0); + } else { + /* Range to range kind of mapping. */ + info->codepoints[0] += (codepoint - (map[index] & 0x00ffffff)); + } + } + + return; + } + } + + /* No mapping found. Map the codepoint to itself. */ + info->codepoints[0] = codepoint; + info->n_codepoints = 1; + } +#endif + + +#if defined MD4C_USE_UTF16 + #define IS_UTF16_SURROGATE_HI(word) (((WORD)(word) & 0xfc00) == 0xd800) + #define IS_UTF16_SURROGATE_LO(word) (((WORD)(word) & 0xfc00) == 0xdc00) + #define UTF16_DECODE_SURROGATE(hi, lo) (0x10000 + ((((unsigned)(hi) & 0x3ff) << 10) | (((unsigned)(lo) & 0x3ff) << 0))) + + static unsigned + md_decode_utf16le__(const CHAR* str, SZ str_size, SZ* p_size) + { + if(IS_UTF16_SURROGATE_HI(str[0])) { + if(1 < str_size && IS_UTF16_SURROGATE_LO(str[1])) { + if(p_size != NULL) + *p_size = 2; + return UTF16_DECODE_SURROGATE(str[0], str[1]); + } + } + + if(p_size != NULL) + *p_size = 1; + return str[0]; + } + + static unsigned + md_decode_utf16le_before__(MD_CTX* ctx, OFF off) + { + if(off > 2 && IS_UTF16_SURROGATE_HI(CH(off-2)) && IS_UTF16_SURROGATE_LO(CH(off-1))) + return UTF16_DECODE_SURROGATE(CH(off-2), CH(off-1)); + + return CH(off); + } + + /* No whitespace uses surrogates, so no decoding needed here. */ + #define ISUNICODEWHITESPACE_(codepoint) md_is_unicode_whitespace__(codepoint) + #define ISUNICODEWHITESPACE(off) md_is_unicode_whitespace__(CH(off)) + #define ISUNICODEWHITESPACEBEFORE(off) md_is_unicode_whitespace__(CH((off)-1)) + + #define ISUNICODEPUNCT(off) md_is_unicode_punct__(md_decode_utf16le__(STR(off), ctx->size - (off), NULL)) + #define ISUNICODEPUNCTBEFORE(off) md_is_unicode_punct__(md_decode_utf16le_before__(ctx, off)) + + static inline int + md_decode_unicode(const CHAR* str, OFF off, SZ str_size, SZ* p_char_size) + { + return md_decode_utf16le__(str+off, str_size-off, p_char_size); + } +#elif defined MD4C_USE_UTF8 + #define IS_UTF8_LEAD1(byte) ((unsigned char)(byte) <= 0x7f) + #define IS_UTF8_LEAD2(byte) (((unsigned char)(byte) & 0xe0) == 0xc0) + #define IS_UTF8_LEAD3(byte) (((unsigned char)(byte) & 0xf0) == 0xe0) + #define IS_UTF8_LEAD4(byte) (((unsigned char)(byte) & 0xf8) == 0xf0) + #define IS_UTF8_TAIL(byte) (((unsigned char)(byte) & 0xc0) == 0x80) + + static unsigned + md_decode_utf8__(const CHAR* str, SZ str_size, SZ* p_size) + { + if(!IS_UTF8_LEAD1(str[0])) { + if(IS_UTF8_LEAD2(str[0])) { + if(1 < str_size && IS_UTF8_TAIL(str[1])) { + if(p_size != NULL) + *p_size = 2; + + return (((unsigned int)str[0] & 0x1f) << 6) | + (((unsigned int)str[1] & 0x3f) << 0); + } + } else if(IS_UTF8_LEAD3(str[0])) { + if(2 < str_size && IS_UTF8_TAIL(str[1]) && IS_UTF8_TAIL(str[2])) { + if(p_size != NULL) + *p_size = 3; + + return (((unsigned int)str[0] & 0x0f) << 12) | + (((unsigned int)str[1] & 0x3f) << 6) | + (((unsigned int)str[2] & 0x3f) << 0); + } + } else if(IS_UTF8_LEAD4(str[0])) { + if(3 < str_size && IS_UTF8_TAIL(str[1]) && IS_UTF8_TAIL(str[2]) && IS_UTF8_TAIL(str[3])) { + if(p_size != NULL) + *p_size = 4; + + return (((unsigned int)str[0] & 0x07) << 18) | + (((unsigned int)str[1] & 0x3f) << 12) | + (((unsigned int)str[2] & 0x3f) << 6) | + (((unsigned int)str[3] & 0x3f) << 0); + } + } + } + + if(p_size != NULL) + *p_size = 1; + return (unsigned) str[0]; + } + + static unsigned + md_decode_utf8_before__(MD_CTX* ctx, OFF off) + { + if(!IS_UTF8_LEAD1(CH(off-1))) { + if(off > 1 && IS_UTF8_LEAD2(CH(off-2)) && IS_UTF8_TAIL(CH(off-1))) + return (((unsigned int)CH(off-2) & 0x1f) << 6) | + (((unsigned int)CH(off-1) & 0x3f) << 0); + + if(off > 2 && IS_UTF8_LEAD3(CH(off-3)) && IS_UTF8_TAIL(CH(off-2)) && IS_UTF8_TAIL(CH(off-1))) + return (((unsigned int)CH(off-3) & 0x0f) << 12) | + (((unsigned int)CH(off-2) & 0x3f) << 6) | + (((unsigned int)CH(off-1) & 0x3f) << 0); + + if(off > 3 && IS_UTF8_LEAD4(CH(off-4)) && IS_UTF8_TAIL(CH(off-3)) && IS_UTF8_TAIL(CH(off-2)) && IS_UTF8_TAIL(CH(off-1))) + return (((unsigned int)CH(off-4) & 0x07) << 18) | + (((unsigned int)CH(off-3) & 0x3f) << 12) | + (((unsigned int)CH(off-2) & 0x3f) << 6) | + (((unsigned int)CH(off-1) & 0x3f) << 0); + } + + return (unsigned) CH(off-1); + } + + #define ISUNICODEWHITESPACE_(codepoint) md_is_unicode_whitespace__(codepoint) + #define ISUNICODEWHITESPACE(off) md_is_unicode_whitespace__(md_decode_utf8__(STR(off), ctx->size - (off), NULL)) + #define ISUNICODEWHITESPACEBEFORE(off) md_is_unicode_whitespace__(md_decode_utf8_before__(ctx, off)) + + #define ISUNICODEPUNCT(off) md_is_unicode_punct__(md_decode_utf8__(STR(off), ctx->size - (off), NULL)) + #define ISUNICODEPUNCTBEFORE(off) md_is_unicode_punct__(md_decode_utf8_before__(ctx, off)) + + static inline unsigned + md_decode_unicode(const CHAR* str, OFF off, SZ str_size, SZ* p_char_size) + { + return md_decode_utf8__(str+off, str_size-off, p_char_size); + } +#else + #define ISUNICODEWHITESPACE_(codepoint) ISWHITESPACE_(codepoint) + #define ISUNICODEWHITESPACE(off) ISWHITESPACE(off) + #define ISUNICODEWHITESPACEBEFORE(off) ISWHITESPACE((off)-1) + + #define ISUNICODEPUNCT(off) ISPUNCT(off) + #define ISUNICODEPUNCTBEFORE(off) ISPUNCT((off)-1) + + static inline void + md_get_unicode_fold_info(unsigned codepoint, MD_UNICODE_FOLD_INFO* info) + { + info->codepoints[0] = codepoint; + if(ISUPPER_(codepoint)) + info->codepoints[0] += 'a' - 'A'; + info->n_codepoints = 1; + } + + static inline unsigned + md_decode_unicode(const CHAR* str, OFF off, SZ str_size, SZ* p_size) + { + *p_size = 1; + return (unsigned) str[off]; + } +#endif + + +/************************************* + *** Helper string manipulations *** + *************************************/ + +/* Fill buffer with copy of the string between 'beg' and 'end' but replace any + * line breaks with given replacement character. + * + * NOTE: Caller is responsible to make sure the buffer is large enough. + * (Given the output is always shorter than input, (end - beg) is good idea + * what the caller should allocate.) + */ +static void +md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines, + CHAR line_break_replacement_char, CHAR* buffer, SZ* p_size) +{ + CHAR* ptr = buffer; + int line_index = 0; + OFF off = beg; + + MD_UNUSED(n_lines); + + while(1) { + const MD_LINE* line = &lines[line_index]; + OFF line_end = line->end; + if(end < line_end) + line_end = end; + + while(off < line_end) { + *ptr = CH(off); + ptr++; + off++; + } + + if(off >= end) { + *p_size = (MD_SIZE)(ptr - buffer); + return; + } + + *ptr = line_break_replacement_char; + ptr++; + + line_index++; + off = lines[line_index].beg; + } +} + +/* Wrapper of md_merge_lines() which allocates new buffer for the output string. + */ +static int +md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines, + CHAR line_break_replacement_char, CHAR** p_str, SZ* p_size) +{ + CHAR* buffer; + + buffer = (CHAR*) malloc(sizeof(CHAR) * (end - beg)); + if(buffer == NULL) { + MD_LOG("malloc() failed."); + return -1; + } + + md_merge_lines(ctx, beg, end, lines, n_lines, + line_break_replacement_char, buffer, p_size); + + *p_str = buffer; + return 0; +} + +static OFF +md_skip_unicode_whitespace(const CHAR* label, OFF off, SZ size) +{ + SZ char_size; + unsigned codepoint; + + while(off < size) { + codepoint = md_decode_unicode(label, off, size, &char_size); + if(!ISUNICODEWHITESPACE_(codepoint) && !ISNEWLINE_(label[off])) + break; + off += char_size; + } + + return off; +} + + +/****************************** + *** Recognizing raw HTML *** + ******************************/ + +/* md_is_html_tag() may be called when processing inlines (inline raw HTML) + * or when breaking document to blocks (checking for start of HTML block type 7). + * + * When breaking document to blocks, we do not yet know line boundaries, but + * in that case the whole tag has to live on a single line. We distinguish this + * by n_lines == 0. + */ +static int +md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) +{ + int attr_state; + OFF off = beg; + OFF line_end = (n_lines > 0) ? lines[0].end : ctx->size; + MD_SIZE line_index = 0; + + MD_ASSERT(CH(beg) == _T('<')); + + if(off + 1 >= line_end) + return FALSE; + off++; + + /* For parsing attributes, we need a little state automaton below. + * State -1: no attributes are allowed. + * State 0: attribute could follow after some whitespace. + * State 1: after a whitespace (attribute name may follow). + * State 2: after attribute name ('=' MAY follow). + * State 3: after '=' (value specification MUST follow). + * State 41: in middle of unquoted attribute value. + * State 42: in middle of single-quoted attribute value. + * State 43: in middle of double-quoted attribute value. + */ + attr_state = 0; + + if(CH(off) == _T('/')) { + /* Closer tag "". No attributes may be present. */ + attr_state = -1; + off++; + } + + /* Tag name */ + if(off >= line_end || !ISALPHA(off)) + return FALSE; + off++; + while(off < line_end && (ISALNUM(off) || CH(off) == _T('-'))) + off++; + + /* (Optional) attributes (if not closer), (optional) '/' (if not closer) + * and final '>'. */ + while(1) { + while(off < line_end && !ISNEWLINE(off)) { + if(attr_state > 40) { + if(attr_state == 41 && (ISBLANK(off) || ISANYOF(off, _T("\"'=<>`")))) { + attr_state = 0; + off--; /* Put the char back for re-inspection in the new state. */ + } else if(attr_state == 42 && CH(off) == _T('\'')) { + attr_state = 0; + } else if(attr_state == 43 && CH(off) == _T('"')) { + attr_state = 0; + } + off++; + } else if(ISWHITESPACE(off)) { + if(attr_state == 0) + attr_state = 1; + off++; + } else if(attr_state <= 2 && CH(off) == _T('>')) { + /* End. */ + goto done; + } else if(attr_state <= 2 && CH(off) == _T('/') && off+1 < line_end && CH(off+1) == _T('>')) { + /* End with digraph '/>' */ + off++; + goto done; + } else if((attr_state == 1 || attr_state == 2) && (ISALPHA(off) || CH(off) == _T('_') || CH(off) == _T(':'))) { + off++; + /* Attribute name */ + while(off < line_end && (ISALNUM(off) || ISANYOF(off, _T("_.:-")))) + off++; + attr_state = 2; + } else if(attr_state == 2 && CH(off) == _T('=')) { + /* Attribute assignment sign */ + off++; + attr_state = 3; + } else if(attr_state == 3) { + /* Expecting start of attribute value. */ + if(CH(off) == _T('"')) + attr_state = 43; + else if(CH(off) == _T('\'')) + attr_state = 42; + else if(!ISANYOF(off, _T("\"'=<>`")) && !ISNEWLINE(off)) + attr_state = 41; + else + return FALSE; + off++; + } else { + /* Anything unexpected. */ + return FALSE; + } + } + + /* We have to be on a single line. See definition of start condition + * of HTML block, type 7. */ + if(n_lines == 0) + return FALSE; + + line_index++; + if(line_index >= n_lines) + return FALSE; + + off = lines[line_index].beg; + line_end = lines[line_index].end; + + if(attr_state == 0 || attr_state == 41) + attr_state = 1; + + if(off >= max_end) + return FALSE; + } + +done: + if(off >= max_end) + return FALSE; + + *p_end = off+1; + return TRUE; +} + +static int +md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len, + const MD_LINE* lines, MD_SIZE n_lines, + OFF beg, OFF max_end, OFF* p_end, + OFF* p_scan_horizon) +{ + OFF off = beg; + MD_SIZE line_index = 0; + + if(off < *p_scan_horizon && *p_scan_horizon >= max_end - len) { + /* We have already scanned the range up to the max_end so we know + * there is nothing to see. */ + return FALSE; + } + + while(TRUE) { + while(off + len <= lines[line_index].end && off + len <= max_end) { + if(md_ascii_eq(STR(off), str, len)) { + /* Success. */ + *p_end = off + len; + return TRUE; + } + off++; + } + + line_index++; + if(off >= max_end || line_index >= n_lines) { + /* Failure. */ + *p_scan_horizon = off; + return FALSE; + } + + off = lines[line_index].beg; + } +} + +static int +md_is_html_comment(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) +{ + OFF off = beg; + + MD_ASSERT(CH(beg) == _T('<')); + + if(off + 4 >= lines[0].end) + return FALSE; + if(CH(off+1) != _T('!') || CH(off+2) != _T('-') || CH(off+3) != _T('-')) + return FALSE; + + /* Skip only "" or "" */ + off += 2; + + /* Scan for ordinary comment closer "-->". */ + return md_scan_for_html_closer(ctx, _T("-->"), 3, + lines, n_lines, off, max_end, p_end, &ctx->html_comment_horizon); +} + +static int +md_is_html_processing_instruction(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) +{ + OFF off = beg; + + if(off + 2 >= lines[0].end) + return FALSE; + if(CH(off+1) != _T('?')) + return FALSE; + off += 2; + + return md_scan_for_html_closer(ctx, _T("?>"), 2, + lines, n_lines, off, max_end, p_end, &ctx->html_proc_instr_horizon); +} + +static int +md_is_html_declaration(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) +{ + OFF off = beg; + + if(off + 2 >= lines[0].end) + return FALSE; + if(CH(off+1) != _T('!')) + return FALSE; + off += 2; + + /* Declaration name. */ + if(off >= lines[0].end || !ISALPHA(off)) + return FALSE; + off++; + while(off < lines[0].end && ISALPHA(off)) + off++; + + return md_scan_for_html_closer(ctx, _T(">"), 1, + lines, n_lines, off, max_end, p_end, &ctx->html_decl_horizon); +} + +static int +md_is_html_cdata(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) +{ + static const CHAR open_str[] = _T("= lines[0].end) + return FALSE; + if(memcmp(STR(off), open_str, open_size) != 0) + return FALSE; + off += open_size; + + return md_scan_for_html_closer(ctx, _T("]]>"), 3, + lines, n_lines, off, max_end, p_end, &ctx->html_cdata_horizon); +} + +static int +md_is_html_any(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) +{ + MD_ASSERT(CH(beg) == _T('<')); + return (md_is_html_tag(ctx, lines, n_lines, beg, max_end, p_end) || + md_is_html_comment(ctx, lines, n_lines, beg, max_end, p_end) || + md_is_html_processing_instruction(ctx, lines, n_lines, beg, max_end, p_end) || + md_is_html_declaration(ctx, lines, n_lines, beg, max_end, p_end) || + md_is_html_cdata(ctx, lines, n_lines, beg, max_end, p_end)); +} + + +/**************************** + *** Recognizing Entity *** + ****************************/ + +static int +md_is_hex_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) +{ + OFF off = beg; + MD_UNUSED(ctx); + + while(off < max_end && ISXDIGIT_(text[off]) && off - beg <= 8) + off++; + + if(1 <= off - beg && off - beg <= 6) { + *p_end = off; + return TRUE; + } else { + return FALSE; + } +} + +static int +md_is_dec_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) +{ + OFF off = beg; + MD_UNUSED(ctx); + + while(off < max_end && ISDIGIT_(text[off]) && off - beg <= 8) + off++; + + if(1 <= off - beg && off - beg <= 7) { + *p_end = off; + return TRUE; + } else { + return FALSE; + } +} + +static int +md_is_named_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) +{ + OFF off = beg; + MD_UNUSED(ctx); + + if(off < max_end && ISALPHA_(text[off])) + off++; + else + return FALSE; + + while(off < max_end && ISALNUM_(text[off]) && off - beg <= 48) + off++; + + if(2 <= off - beg && off - beg <= 48) { + *p_end = off; + return TRUE; + } else { + return FALSE; + } +} + +static int +md_is_entity_str(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) +{ + int is_contents; + OFF off = beg; + + MD_ASSERT(text[off] == _T('&')); + off++; + + if(off+2 < max_end && text[off] == _T('#') && (text[off+1] == _T('x') || text[off+1] == _T('X'))) + is_contents = md_is_hex_entity_contents(ctx, text, off+2, max_end, &off); + else if(off+1 < max_end && text[off] == _T('#')) + is_contents = md_is_dec_entity_contents(ctx, text, off+1, max_end, &off); + else + is_contents = md_is_named_entity_contents(ctx, text, off, max_end, &off); + + if(is_contents && off < max_end && text[off] == _T(';')) { + *p_end = off+1; + return TRUE; + } else { + return FALSE; + } +} + +static inline int +md_is_entity(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end) +{ + return md_is_entity_str(ctx, ctx->text, beg, max_end, p_end); +} + + +/****************************** + *** Attribute Management *** + ******************************/ + +typedef struct MD_ATTRIBUTE_BUILD_tag MD_ATTRIBUTE_BUILD; +struct MD_ATTRIBUTE_BUILD_tag { + CHAR* text; + MD_TEXTTYPE* substr_types; + OFF* substr_offsets; + int substr_count; + int substr_alloc; + MD_TEXTTYPE trivial_types[1]; + OFF trivial_offsets[2]; +}; + + +#define MD_BUILD_ATTR_NO_ESCAPES 0x0001 + +static int +md_build_attr_append_substr(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build, + MD_TEXTTYPE type, OFF off) +{ + if(build->substr_count >= build->substr_alloc) { + MD_TEXTTYPE* new_substr_types; + OFF* new_substr_offsets; + + build->substr_alloc = (build->substr_alloc > 0 + ? build->substr_alloc + build->substr_alloc / 2 + : 8); + new_substr_types = (MD_TEXTTYPE*) realloc(build->substr_types, + build->substr_alloc * sizeof(MD_TEXTTYPE)); + if(new_substr_types == NULL) { + MD_LOG("realloc() failed."); + return -1; + } + /* Note +1 to reserve space for final offset (== raw_size). */ + new_substr_offsets = (OFF*) realloc(build->substr_offsets, + (build->substr_alloc+1) * sizeof(OFF)); + if(new_substr_offsets == NULL) { + MD_LOG("realloc() failed."); + free(new_substr_types); + return -1; + } + + build->substr_types = new_substr_types; + build->substr_offsets = new_substr_offsets; + } + + build->substr_types[build->substr_count] = type; + build->substr_offsets[build->substr_count] = off; + build->substr_count++; + return 0; +} + +static void +md_free_attribute(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build) +{ + MD_UNUSED(ctx); + + if(build->substr_alloc > 0) { + free(build->text); + free(build->substr_types); + free(build->substr_offsets); + } +} + +static int +md_build_attribute(MD_CTX* ctx, const CHAR* raw_text, SZ raw_size, + unsigned flags, MD_ATTRIBUTE* attr, MD_ATTRIBUTE_BUILD* build) +{ + OFF raw_off, off; + int is_trivial; + int ret = 0; + + memset(build, 0, sizeof(MD_ATTRIBUTE_BUILD)); + + /* If there is no backslash and no ampersand, build trivial attribute + * without any malloc(). */ + is_trivial = TRUE; + for(raw_off = 0; raw_off < raw_size; raw_off++) { + if(ISANYOF3_(raw_text[raw_off], _T('\\'), _T('&'), _T('\0'))) { + is_trivial = FALSE; + break; + } + } + + if(is_trivial) { + build->text = (CHAR*) (raw_size ? raw_text : NULL); + build->substr_types = build->trivial_types; + build->substr_offsets = build->trivial_offsets; + build->substr_count = 1; + build->substr_alloc = 0; + build->trivial_types[0] = MD_TEXT_NORMAL; + build->trivial_offsets[0] = 0; + build->trivial_offsets[1] = raw_size; + off = raw_size; + } else { + build->text = (CHAR*) malloc(raw_size * sizeof(CHAR)); + if(build->text == NULL) { + MD_LOG("malloc() failed."); + goto abort; + } + + raw_off = 0; + off = 0; + + while(raw_off < raw_size) { + if(raw_text[raw_off] == _T('\0')) { + MD_CHECK(md_build_attr_append_substr(ctx, build, MD_TEXT_NULLCHAR, off)); + memcpy(build->text + off, raw_text + raw_off, 1); + off++; + raw_off++; + continue; + } + + if(raw_text[raw_off] == _T('&')) { + OFF ent_end; + + if(md_is_entity_str(ctx, raw_text, raw_off, raw_size, &ent_end)) { + MD_CHECK(md_build_attr_append_substr(ctx, build, MD_TEXT_ENTITY, off)); + memcpy(build->text + off, raw_text + raw_off, ent_end - raw_off); + off += ent_end - raw_off; + raw_off = ent_end; + continue; + } + } + + if(build->substr_count == 0 || build->substr_types[build->substr_count-1] != MD_TEXT_NORMAL) + MD_CHECK(md_build_attr_append_substr(ctx, build, MD_TEXT_NORMAL, off)); + + if(!(flags & MD_BUILD_ATTR_NO_ESCAPES) && + raw_text[raw_off] == _T('\\') && raw_off+1 < raw_size && + (ISPUNCT_(raw_text[raw_off+1]) || ISNEWLINE_(raw_text[raw_off+1]))) + raw_off++; + + build->text[off++] = raw_text[raw_off++]; + } + build->substr_offsets[build->substr_count] = off; + } + + attr->text = build->text; + attr->size = off; + attr->substr_offsets = build->substr_offsets; + attr->substr_types = build->substr_types; + return 0; + +abort: + md_free_attribute(ctx, build); + return -1; +} + + +/********************************************* + *** Dictionary of Reference Definitions *** + *********************************************/ + +#define MD_FNV1A_BASE 2166136261U +#define MD_FNV1A_PRIME 16777619U + +static inline unsigned +md_fnv1a(unsigned base, const void* data, size_t n) +{ + const unsigned char* buf = (const unsigned char*) data; + unsigned hash = base; + size_t i; + + for(i = 0; i < n; i++) { + hash ^= buf[i]; + hash *= MD_FNV1A_PRIME; + } + + return hash; +} + + +struct MD_REF_DEF_tag { + CHAR* label; + CHAR* title; + unsigned hash; + SZ label_size; + SZ title_size; + OFF dest_beg; + OFF dest_end; + unsigned char label_needs_free : 1; + unsigned char title_needs_free : 1; +}; + +/* Label equivalence is quite complicated with regards to whitespace and case + * folding. This complicates computing a hash of it as well as direct comparison + * of two labels. */ + +static unsigned +md_link_label_hash(const CHAR* label, SZ size) +{ + unsigned hash = MD_FNV1A_BASE; + OFF off; + unsigned codepoint; + int is_whitespace = FALSE; + + off = md_skip_unicode_whitespace(label, 0, size); + while(off < size) { + SZ char_size; + + codepoint = md_decode_unicode(label, off, size, &char_size); + is_whitespace = ISUNICODEWHITESPACE_(codepoint) || ISNEWLINE_(label[off]); + + if(is_whitespace) { + codepoint = ' '; + hash = md_fnv1a(hash, &codepoint, sizeof(unsigned)); + off = md_skip_unicode_whitespace(label, off, size); + } else { + MD_UNICODE_FOLD_INFO fold_info; + + md_get_unicode_fold_info(codepoint, &fold_info); + hash = md_fnv1a(hash, fold_info.codepoints, fold_info.n_codepoints * sizeof(unsigned)); + off += char_size; + } + } + + return hash; +} + +static OFF +md_link_label_cmp_load_fold_info(const CHAR* label, OFF off, SZ size, + MD_UNICODE_FOLD_INFO* fold_info) +{ + unsigned codepoint; + SZ char_size; + + if(off >= size) { + /* Treat end of a link label as a whitespace. */ + goto whitespace; + } + + codepoint = md_decode_unicode(label, off, size, &char_size); + off += char_size; + if(ISUNICODEWHITESPACE_(codepoint)) { + /* Treat all whitespace as equivalent */ + goto whitespace; + } + + /* Get real folding info. */ + md_get_unicode_fold_info(codepoint, fold_info); + return off; + +whitespace: + fold_info->codepoints[0] = _T(' '); + fold_info->n_codepoints = 1; + return md_skip_unicode_whitespace(label, off, size); +} + +static int +md_link_label_cmp(const CHAR* a_label, SZ a_size, const CHAR* b_label, SZ b_size) +{ + OFF a_off; + OFF b_off; + MD_UNICODE_FOLD_INFO a_fi = { { 0 }, 0 }; + MD_UNICODE_FOLD_INFO b_fi = { { 0 }, 0 }; + OFF a_fi_off = 0; + OFF b_fi_off = 0; + int cmp; + + a_off = md_skip_unicode_whitespace(a_label, 0, a_size); + b_off = md_skip_unicode_whitespace(b_label, 0, b_size); + while(a_off < a_size || a_fi_off < a_fi.n_codepoints || + b_off < b_size || b_fi_off < b_fi.n_codepoints) + { + /* If needed, load fold info for next char. */ + if(a_fi_off >= a_fi.n_codepoints) { + a_fi_off = 0; + a_off = md_link_label_cmp_load_fold_info(a_label, a_off, a_size, &a_fi); + } + if(b_fi_off >= b_fi.n_codepoints) { + b_fi_off = 0; + b_off = md_link_label_cmp_load_fold_info(b_label, b_off, b_size, &b_fi); + } + + cmp = b_fi.codepoints[b_fi_off] - a_fi.codepoints[a_fi_off]; + if(cmp != 0) + return cmp; + + a_fi_off++; + b_fi_off++; + } + + return 0; +} + +typedef struct MD_REF_DEF_LIST_tag MD_REF_DEF_LIST; +struct MD_REF_DEF_LIST_tag { + int n_ref_defs; + int alloc_ref_defs; + MD_REF_DEF* ref_defs[]; /* Valid items always point into ctx->ref_defs[] */ +}; + +static int +md_ref_def_cmp(const void* a, const void* b) +{ + const MD_REF_DEF* a_ref = *(const MD_REF_DEF**)a; + const MD_REF_DEF* b_ref = *(const MD_REF_DEF**)b; + + if(a_ref->hash < b_ref->hash) + return -1; + else if(a_ref->hash > b_ref->hash) + return +1; + else + return md_link_label_cmp(a_ref->label, a_ref->label_size, b_ref->label, b_ref->label_size); +} + +static int +md_ref_def_cmp_for_sort(const void* a, const void* b) +{ + int cmp; + + cmp = md_ref_def_cmp(a, b); + + /* Ensure stability of the sorting. */ + if(cmp == 0) { + const MD_REF_DEF* a_ref = *(const MD_REF_DEF**)a; + const MD_REF_DEF* b_ref = *(const MD_REF_DEF**)b; + + if(a_ref < b_ref) + cmp = -1; + else if(a_ref > b_ref) + cmp = +1; + else + cmp = 0; + } + + return cmp; +} + +static int +md_build_ref_def_hashtable(MD_CTX* ctx) +{ + int i, j; + + if(ctx->n_ref_defs == 0) + return 0; + + ctx->ref_def_hashtable_size = (ctx->n_ref_defs * 5) / 4; + ctx->ref_def_hashtable = malloc(ctx->ref_def_hashtable_size * sizeof(void*)); + if(ctx->ref_def_hashtable == NULL) { + MD_LOG("malloc() failed."); + goto abort; + } + memset(ctx->ref_def_hashtable, 0, ctx->ref_def_hashtable_size * sizeof(void*)); + + /* Each member of ctx->ref_def_hashtable[] can be: + * -- NULL, + * -- pointer to the MD_REF_DEF in ctx->ref_defs[], or + * -- pointer to a MD_REF_DEF_LIST, which holds multiple pointers to + * such MD_REF_DEFs. + */ + for(i = 0; i < ctx->n_ref_defs; i++) { + MD_REF_DEF* def = &ctx->ref_defs[i]; + void* bucket; + MD_REF_DEF_LIST* list; + + def->hash = md_link_label_hash(def->label, def->label_size); + bucket = ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size]; + + if(bucket == NULL) { + /* The bucket is empty. Make it just point to the def. */ + ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size] = def; + continue; + } + + if(ctx->ref_defs <= (MD_REF_DEF*) bucket && (MD_REF_DEF*) bucket < ctx->ref_defs + ctx->n_ref_defs) { + /* The bucket already contains one ref. def. Lets see whether it + * is the same label (ref. def. duplicate) or different one + * (hash conflict). */ + MD_REF_DEF* old_def = (MD_REF_DEF*) bucket; + + if(md_link_label_cmp(def->label, def->label_size, old_def->label, old_def->label_size) == 0) { + /* Duplicate label: Ignore this ref. def. */ + continue; + } + + /* Make the bucket complex, i.e. able to hold more ref. defs. */ + list = (MD_REF_DEF_LIST*) malloc(sizeof(MD_REF_DEF_LIST) + 2 * sizeof(MD_REF_DEF*)); + if(list == NULL) { + MD_LOG("malloc() failed."); + goto abort; + } + list->ref_defs[0] = old_def; + list->ref_defs[1] = def; + list->n_ref_defs = 2; + list->alloc_ref_defs = 2; + ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size] = list; + continue; + } + + /* Append the def to the complex bucket list. + * + * Note in this case we ignore potential duplicates to avoid expensive + * iterating over the complex bucket. Below, we revisit all the complex + * buckets and handle it more cheaply after the complex bucket contents + * is sorted. */ + list = (MD_REF_DEF_LIST*) bucket; + if(list->n_ref_defs >= list->alloc_ref_defs) { + int alloc_ref_defs = list->alloc_ref_defs + list->alloc_ref_defs / 2; + MD_REF_DEF_LIST* list_tmp = (MD_REF_DEF_LIST*) realloc(list, + sizeof(MD_REF_DEF_LIST) + alloc_ref_defs * sizeof(MD_REF_DEF*)); + if(list_tmp == NULL) { + MD_LOG("realloc() failed."); + goto abort; + } + list = list_tmp; + list->alloc_ref_defs = alloc_ref_defs; + ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size] = list; + } + + list->ref_defs[list->n_ref_defs] = def; + list->n_ref_defs++; + } + + /* Sort the complex buckets so we can use bsearch() with them. */ + for(i = 0; i < ctx->ref_def_hashtable_size; i++) { + void* bucket = ctx->ref_def_hashtable[i]; + MD_REF_DEF_LIST* list; + + if(bucket == NULL) + continue; + if(ctx->ref_defs <= (MD_REF_DEF*) bucket && (MD_REF_DEF*) bucket < ctx->ref_defs + ctx->n_ref_defs) + continue; + + list = (MD_REF_DEF_LIST*) bucket; + qsort(list->ref_defs, list->n_ref_defs, sizeof(MD_REF_DEF*), md_ref_def_cmp_for_sort); + + /* Disable all duplicates in the complex bucket by forcing all such + * records to point to the 1st such ref. def. I.e. no matter which + * record is found during the lookup, it will always point to the right + * ref. def. in ctx->ref_defs[]. */ + for(j = 1; j < list->n_ref_defs; j++) { + if(md_ref_def_cmp(&list->ref_defs[j-1], &list->ref_defs[j]) == 0) + list->ref_defs[j] = list->ref_defs[j-1]; + } + } + + return 0; + +abort: + return -1; +} + +static void +md_free_ref_def_hashtable(MD_CTX* ctx) +{ + if(ctx->ref_def_hashtable != NULL) { + int i; + + for(i = 0; i < ctx->ref_def_hashtable_size; i++) { + void* bucket = ctx->ref_def_hashtable[i]; + if(bucket == NULL) + continue; + if(ctx->ref_defs <= (MD_REF_DEF*) bucket && (MD_REF_DEF*) bucket < ctx->ref_defs + ctx->n_ref_defs) + continue; + free(bucket); + } + + free(ctx->ref_def_hashtable); + } +} + +static const MD_REF_DEF* +md_lookup_ref_def(MD_CTX* ctx, const CHAR* label, SZ label_size) +{ + unsigned hash; + void* bucket; + + if(ctx->ref_def_hashtable_size == 0) + return NULL; + + hash = md_link_label_hash(label, label_size); + bucket = ctx->ref_def_hashtable[hash % ctx->ref_def_hashtable_size]; + + if(bucket == NULL) { + return NULL; + } else if(ctx->ref_defs <= (MD_REF_DEF*) bucket && (MD_REF_DEF*) bucket < ctx->ref_defs + ctx->n_ref_defs) { + const MD_REF_DEF* def = (MD_REF_DEF*) bucket; + + if(md_link_label_cmp(def->label, def->label_size, label, label_size) == 0) + return def; + else + return NULL; + } else { + MD_REF_DEF_LIST* list = (MD_REF_DEF_LIST*) bucket; + MD_REF_DEF key_buf; + const MD_REF_DEF* key = &key_buf; + const MD_REF_DEF** ret; + + key_buf.label = (CHAR*) label; + key_buf.label_size = label_size; + key_buf.hash = md_link_label_hash(key_buf.label, key_buf.label_size); + + ret = (const MD_REF_DEF**) bsearch(&key, list->ref_defs, + list->n_ref_defs, sizeof(MD_REF_DEF*), md_ref_def_cmp); + if(ret != NULL) + return *ret; + else + return NULL; + } +} + + +/*************************** + *** Recognizing Links *** + ***************************/ + +/* Note this code is partially shared between processing inlines and blocks + * as reference definitions and links share some helper parser functions. + */ + +typedef struct MD_LINK_ATTR_tag MD_LINK_ATTR; +struct MD_LINK_ATTR_tag { + OFF dest_beg; + OFF dest_end; + + CHAR* title; + SZ title_size; + int title_needs_free; +}; + + +static int +md_is_link_label(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, + OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index, + OFF* p_contents_beg, OFF* p_contents_end) +{ + OFF off = beg; + OFF contents_beg = 0; + OFF contents_end = 0; + MD_SIZE line_index = 0; + int len = 0; + + *p_beg_line_index = 0; + + if(CH(off) != _T('[')) + return FALSE; + off++; + + while(1) { + OFF line_end = lines[line_index].end; + + while(off < line_end) { + if(CH(off) == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { + if(contents_end == 0) { + contents_beg = off; + *p_beg_line_index = line_index; + } + contents_end = off + 2; + off += 2; + } else if(CH(off) == _T('[')) { + return FALSE; + } else if(CH(off) == _T(']')) { + if(contents_beg < contents_end) { + /* Success. */ + *p_contents_beg = contents_beg; + *p_contents_end = contents_end; + *p_end = off+1; + *p_end_line_index = line_index; + return TRUE; + } else { + /* Link label must have some non-whitespace contents. */ + return FALSE; + } + } else { + unsigned codepoint; + SZ char_size; + + codepoint = md_decode_unicode(ctx->text, off, ctx->size, &char_size); + if(!ISUNICODEWHITESPACE_(codepoint)) { + if(contents_end == 0) { + contents_beg = off; + *p_beg_line_index = line_index; + } + contents_end = off + char_size; + } + + off += char_size; + } + + len++; + if(len > 999) + return FALSE; + } + + line_index++; + len++; + if(line_index < n_lines) + off = lines[line_index].beg; + else + break; + } + + return FALSE; +} + +static int +md_is_link_destination_A(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, + OFF* p_contents_beg, OFF* p_contents_end) +{ + OFF off = beg; + + if(off >= max_end || CH(off) != _T('<')) + return FALSE; + off++; + + while(off < max_end) { + if(CH(off) == _T('\\') && off+1 < max_end && ISPUNCT(off+1)) { + off += 2; + continue; + } + + if(ISNEWLINE(off) || CH(off) == _T('<')) + return FALSE; + + if(CH(off) == _T('>')) { + /* Success. */ + *p_contents_beg = beg+1; + *p_contents_end = off; + *p_end = off+1; + return TRUE; + } + + off++; + } + + return FALSE; +} + +static int +md_is_link_destination_B(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, + OFF* p_contents_beg, OFF* p_contents_end) +{ + OFF off = beg; + int parenthesis_level = 0; + + while(off < max_end) { + if(CH(off) == _T('\\') && off+1 < max_end && ISPUNCT(off+1)) { + off += 2; + continue; + } + + if(ISWHITESPACE(off) || ISCNTRL(off)) + break; + + /* Link destination may include balanced pairs of unescaped '(' ')'. + * Note we limit the maximal nesting level by 32 to protect us from + * https://github.com/jgm/cmark/issues/214 */ + if(CH(off) == _T('(')) { + parenthesis_level++; + if(parenthesis_level > 32) + return FALSE; + } else if(CH(off) == _T(')')) { + if(parenthesis_level == 0) + break; + parenthesis_level--; + } + + off++; + } + + if(parenthesis_level != 0 || off == beg) + return FALSE; + + /* Success. */ + *p_contents_beg = beg; + *p_contents_end = off; + *p_end = off; + return TRUE; +} + +static inline int +md_is_link_destination(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, + OFF* p_contents_beg, OFF* p_contents_end) +{ + if(CH(beg) == _T('<')) + return md_is_link_destination_A(ctx, beg, max_end, p_end, p_contents_beg, p_contents_end); + else + return md_is_link_destination_B(ctx, beg, max_end, p_end, p_contents_beg, p_contents_end); +} + +static int +md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, + OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index, + OFF* p_contents_beg, OFF* p_contents_end) +{ + OFF off = beg; + CHAR closer_char; + MD_SIZE line_index = 0; + + /* White space with up to one line break. */ + while(off < lines[line_index].end && ISWHITESPACE(off)) + off++; + if(off >= lines[line_index].end) { + line_index++; + if(line_index >= n_lines) + return FALSE; + off = lines[line_index].beg; + } + if(off == beg) + return FALSE; + + *p_beg_line_index = line_index; + + /* First char determines how to detect end of it. */ + switch(CH(off)) { + case _T('"'): closer_char = _T('"'); break; + case _T('\''): closer_char = _T('\''); break; + case _T('('): closer_char = _T(')'); break; + default: return FALSE; + } + off++; + + *p_contents_beg = off; + + while(line_index < n_lines) { + OFF line_end = lines[line_index].end; + + while(off < line_end) { + if(CH(off) == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { + off++; + } else if(CH(off) == closer_char) { + /* Success. */ + *p_contents_end = off; + *p_end = off+1; + *p_end_line_index = line_index; + return TRUE; + } else if(closer_char == _T(')') && CH(off) == _T('(')) { + /* ()-style title cannot contain (unescaped '(')) */ + return FALSE; + } + + off++; + } + + line_index++; + } + + return FALSE; +} + +/* Returns 0 if it is not a reference definition. + * + * Returns N > 0 if it is a reference definition. N then corresponds to the + * number of lines forming it). In this case the definition is stored for + * resolving any links referring to it. + * + * Returns -1 in case of an error (out of memory). + */ +static int +md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) +{ + OFF label_contents_beg; + OFF label_contents_end; + MD_SIZE label_contents_line_index; + int label_is_multiline = FALSE; + OFF dest_contents_beg; + OFF dest_contents_end; + OFF title_contents_beg; + OFF title_contents_end; + MD_SIZE title_contents_line_index; + int title_is_multiline = FALSE; + OFF off; + MD_SIZE line_index = 0; + MD_SIZE tmp_line_index; + MD_REF_DEF* def = NULL; + int ret = 0; + + /* Link label. */ + if(!md_is_link_label(ctx, lines, n_lines, lines[0].beg, + &off, &label_contents_line_index, &line_index, + &label_contents_beg, &label_contents_end)) + return FALSE; + label_is_multiline = (label_contents_line_index != line_index); + + /* Colon. */ + if(off >= lines[line_index].end || CH(off) != _T(':')) + return FALSE; + off++; + + /* Optional white space with up to one line break. */ + while(off < lines[line_index].end && ISWHITESPACE(off)) + off++; + if(off >= lines[line_index].end) { + line_index++; + if(line_index >= n_lines) + return FALSE; + off = lines[line_index].beg; + } + + /* Link destination. */ + if(!md_is_link_destination(ctx, off, lines[line_index].end, + &off, &dest_contents_beg, &dest_contents_end)) + return FALSE; + + /* (Optional) title. Note we interpret it as an title only if nothing + * more follows on its last line. */ + if(md_is_link_title(ctx, lines + line_index, n_lines - line_index, off, + &off, &title_contents_line_index, &tmp_line_index, + &title_contents_beg, &title_contents_end) + && off >= lines[line_index + tmp_line_index].end) + { + title_is_multiline = (tmp_line_index != title_contents_line_index); + title_contents_line_index += line_index; + line_index += tmp_line_index; + } else { + /* Not a title. */ + title_is_multiline = FALSE; + title_contents_beg = off; + title_contents_end = off; + title_contents_line_index = 0; + } + + /* Nothing more can follow on the last line. */ + if(off < lines[line_index].end) + return FALSE; + + /* So, it _is_ a reference definition. Remember it. */ + if(ctx->n_ref_defs >= ctx->alloc_ref_defs) { + MD_REF_DEF* new_defs; + + ctx->alloc_ref_defs = (ctx->alloc_ref_defs > 0 + ? ctx->alloc_ref_defs + ctx->alloc_ref_defs / 2 + : 16); + new_defs = (MD_REF_DEF*) realloc(ctx->ref_defs, ctx->alloc_ref_defs * sizeof(MD_REF_DEF)); + if(new_defs == NULL) { + MD_LOG("realloc() failed."); + goto abort; + } + + ctx->ref_defs = new_defs; + } + def = &ctx->ref_defs[ctx->n_ref_defs]; + memset(def, 0, sizeof(MD_REF_DEF)); + + if(label_is_multiline) { + MD_CHECK(md_merge_lines_alloc(ctx, label_contents_beg, label_contents_end, + lines + label_contents_line_index, n_lines - label_contents_line_index, + _T(' '), &def->label, &def->label_size)); + def->label_needs_free = TRUE; + } else { + def->label = (CHAR*) STR(label_contents_beg); + def->label_size = label_contents_end - label_contents_beg; + } + + if(title_is_multiline) { + MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end, + lines + title_contents_line_index, n_lines - title_contents_line_index, + _T('\n'), &def->title, &def->title_size)); + def->title_needs_free = TRUE; + } else { + def->title = (CHAR*) STR(title_contents_beg); + def->title_size = title_contents_end - title_contents_beg; + } + + def->dest_beg = dest_contents_beg; + def->dest_end = dest_contents_end; + + /* Success. */ + ctx->n_ref_defs++; + return line_index + 1; + +abort: + /* Failure. */ + if(def != NULL && def->label_needs_free) + free(def->label); + if(def != NULL && def->title_needs_free) + free(def->title); + return ret; +} + +static int +md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, + OFF beg, OFF end, MD_LINK_ATTR* attr) +{ + const MD_REF_DEF* def; + const MD_LINE* beg_line; + int is_multiline; + CHAR* label; + SZ label_size; + int ret = FALSE; + + MD_ASSERT(CH(beg) == _T('[') || CH(beg) == _T('!')); + MD_ASSERT(CH(end-1) == _T(']')); + + if(ctx->max_ref_def_output == 0) + return FALSE; + + beg += (CH(beg) == _T('!') ? 2 : 1); + end--; + + /* Find lines corresponding to the beg and end positions. */ + beg_line = md_lookup_line(beg, lines, n_lines, NULL); + is_multiline = (end > beg_line->end); + + if(is_multiline) { + MD_CHECK(md_merge_lines_alloc(ctx, beg, end, beg_line, + (int)(n_lines - (beg_line - lines)), _T(' '), &label, &label_size)); + } else { + label = (CHAR*) STR(beg); + label_size = end - beg; + } + + def = md_lookup_ref_def(ctx, label, label_size); + if(def != NULL) { + attr->dest_beg = def->dest_beg; + attr->dest_end = def->dest_end; + attr->title = def->title; + attr->title_size = def->title_size; + attr->title_needs_free = FALSE; + } + + if(is_multiline) + free(label); + + if(def != NULL) { + /* See https://github.com/mity/md4c/issues/238 */ + MD_SIZE output_size_estimation = def->label_size + def->title_size + def->dest_end - def->dest_beg; + if(output_size_estimation < ctx->max_ref_def_output) { + ctx->max_ref_def_output -= output_size_estimation; + ret = TRUE; + } else { + MD_LOG("Too many link reference definition instantiations."); + ctx->max_ref_def_output = 0; + } + } + +abort: + return ret; +} + +static int +md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, + OFF beg, OFF* p_end, MD_LINK_ATTR* attr) +{ + MD_SIZE line_index = 0; + MD_SIZE tmp_line_index; + OFF title_contents_beg; + OFF title_contents_end; + MD_SIZE title_contents_line_index; + int title_is_multiline; + OFF off = beg; + int ret = FALSE; + + md_lookup_line(off, lines, n_lines, &line_index); + + MD_ASSERT(CH(off) == _T('(')); + off++; + + /* Optional white space with up to one line break. */ + while(off < lines[line_index].end && ISWHITESPACE(off)) + off++; + if(off >= lines[line_index].end && (off >= ctx->size || ISNEWLINE(off))) { + line_index++; + if(line_index >= n_lines) + return FALSE; + off = lines[line_index].beg; + } + + /* Link destination may be omitted, but only when not also having a title. */ + if(off < ctx->size && CH(off) == _T(')')) { + attr->dest_beg = off; + attr->dest_end = off; + attr->title = NULL; + attr->title_size = 0; + attr->title_needs_free = FALSE; + off++; + *p_end = off; + return TRUE; + } + + /* Link destination. */ + if(!md_is_link_destination(ctx, off, lines[line_index].end, + &off, &attr->dest_beg, &attr->dest_end)) + return FALSE; + + /* (Optional) title. */ + if(md_is_link_title(ctx, lines + line_index, n_lines - line_index, off, + &off, &title_contents_line_index, &tmp_line_index, + &title_contents_beg, &title_contents_end)) + { + title_is_multiline = (tmp_line_index != title_contents_line_index); + title_contents_line_index += line_index; + line_index += tmp_line_index; + } else { + /* Not a title. */ + title_is_multiline = FALSE; + title_contents_beg = off; + title_contents_end = off; + title_contents_line_index = 0; + } + + /* Optional whitespace followed with final ')'. */ + while(off < lines[line_index].end && ISWHITESPACE(off)) + off++; + if(off >= lines[line_index].end) { + line_index++; + if(line_index >= n_lines) + return FALSE; + off = lines[line_index].beg; + } + if(CH(off) != _T(')')) + goto abort; + off++; + + if(title_contents_beg >= title_contents_end) { + attr->title = NULL; + attr->title_size = 0; + attr->title_needs_free = FALSE; + } else if(!title_is_multiline) { + attr->title = (CHAR*) STR(title_contents_beg); + attr->title_size = title_contents_end - title_contents_beg; + attr->title_needs_free = FALSE; + } else { + MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end, + lines + title_contents_line_index, n_lines - title_contents_line_index, + _T('\n'), &attr->title, &attr->title_size)); + attr->title_needs_free = TRUE; + } + + *p_end = off; + ret = TRUE; + +abort: + return ret; +} + +static void +md_free_ref_defs(MD_CTX* ctx) +{ + int i; + + for(i = 0; i < ctx->n_ref_defs; i++) { + MD_REF_DEF* def = &ctx->ref_defs[i]; + + if(def->label_needs_free) + free(def->label); + if(def->title_needs_free) + free(def->title); + } + + free(ctx->ref_defs); +} + + +/****************************************** + *** Processing Inlines (a.k.a Spans) *** + ******************************************/ + +/* We process inlines in few phases: + * + * (1) We go through the block text and collect all significant characters + * which may start/end a span or some other significant position into + * ctx->marks[]. Core of this is what md_collect_marks() does. + * + * We also do some very brief preliminary context-less analysis, whether + * it might be opener or closer (e.g. of an emphasis span). + * + * This speeds the other steps as we do not need to re-iterate over all + * characters anymore. + * + * (2) We analyze each potential mark types, in order by their precedence. + * + * In each md_analyze_XXX() function, we re-iterate list of the marks, + * skipping already resolved regions (in preceding precedences) and try to + * resolve them. + * + * (2.1) For trivial marks, which are single (e.g. HTML entity), we just mark + * them as resolved. + * + * (2.2) For range-type marks, we analyze whether the mark could be closer + * and, if yes, whether there is some preceding opener it could satisfy. + * + * If not we check whether it could be really an opener and if yes, we + * remember it so subsequent closers may resolve it. + * + * (3) Finally, when all marks were analyzed, we render the block contents + * by calling MD_RENDERER::text() callback, interrupting by ::enter_span() + * or ::close_span() whenever we reach a resolved mark. + */ + + +/* The mark structure. + * + * '\\': Maybe escape sequence. + * '\0': NULL char. + * '*': Maybe (strong) emphasis start/end. + * '_': Maybe (strong) emphasis start/end. + * '~': Maybe strikethrough start/end (needs MD_FLAG_STRIKETHROUGH). + * '`': Maybe code span start/end. + * '&': Maybe start of entity. + * ';': Maybe end of entity. + * '<': Maybe start of raw HTML or autolink. + * '>': Maybe end of raw HTML or autolink. + * '[': Maybe start of link label or link text. + * '!': Equivalent of '[' for image. + * ']': Maybe end of link label or link text. + * '@': Maybe permissive e-mail auto-link (needs MD_FLAG_PERMISSIVEEMAILAUTOLINKS). + * ':': Maybe permissive URL auto-link (needs MD_FLAG_PERMISSIVEURLAUTOLINKS). + * '.': Maybe permissive WWW auto-link (needs MD_FLAG_PERMISSIVEWWWAUTOLINKS). + * 'D': Dummy mark, it reserves a space for splitting a previous mark + * (e.g. emphasis) or to make more space for storing some special data + * related to the preceding mark (e.g. link). + * + * Note that not all instances of these chars in the text imply creation of the + * structure. Only those which have (or may have, after we see more context) + * the special meaning. + * + * (Keep this struct as small as possible to fit as much of them into CPU + * cache line.) + */ +struct MD_MARK_tag { + OFF beg; + OFF end; + + /* For unresolved openers, 'next' may be used to form a stack of + * unresolved open openers. + * + * When resolved with MD_MARK_OPENER/CLOSER flag, next/prev is index of the + * respective closer/opener. + */ + int prev; + int next; + CHAR ch; + unsigned char flags; +}; + +/* Mark flags (these apply to ALL mark types). */ +#define MD_MARK_POTENTIAL_OPENER 0x01 /* Maybe opener. */ +#define MD_MARK_POTENTIAL_CLOSER 0x02 /* Maybe closer. */ +#define MD_MARK_OPENER 0x04 /* Definitely opener. */ +#define MD_MARK_CLOSER 0x08 /* Definitely closer. */ +#define MD_MARK_RESOLVED 0x10 /* Resolved in any definite way. */ + +/* Mark flags specific for various mark types (so they can share bits). */ +#define MD_MARK_EMPH_OC 0x20 /* Opener/closer mixed candidate. Helper for the "rule of 3". */ +#define MD_MARK_EMPH_MOD3_0 0x40 +#define MD_MARK_EMPH_MOD3_1 0x80 +#define MD_MARK_EMPH_MOD3_2 (0x40 | 0x80) +#define MD_MARK_EMPH_MOD3_MASK (0x40 | 0x80) +#define MD_MARK_AUTOLINK 0x20 /* Distinguisher for '<', '>'. */ +#define MD_MARK_AUTOLINK_MISSING_MAILTO 0x40 +#define MD_MARK_VALIDPERMISSIVEAUTOLINK 0x20 /* For permissive autolinks. */ +#define MD_MARK_HASNESTEDBRACKETS 0x20 /* For '[' to rule out invalid link labels early */ + +static MD_MARKSTACK* +md_emph_stack(MD_CTX* ctx, MD_CHAR ch, unsigned flags) +{ + MD_MARKSTACK* stack; + + switch(ch) { + case '*': stack = &ASTERISK_OPENERS_oo_mod3_0; break; + case '_': stack = &UNDERSCORE_OPENERS_oo_mod3_0; break; + default: MD_UNREACHABLE(); + } + + if(flags & MD_MARK_EMPH_OC) + stack += 3; + + switch(flags & MD_MARK_EMPH_MOD3_MASK) { + case MD_MARK_EMPH_MOD3_0: stack += 0; break; + case MD_MARK_EMPH_MOD3_1: stack += 1; break; + case MD_MARK_EMPH_MOD3_2: stack += 2; break; + default: MD_UNREACHABLE(); + } + + return stack; +} + +static MD_MARKSTACK* +md_opener_stack(MD_CTX* ctx, int mark_index) +{ + MD_MARK* mark = &ctx->marks[mark_index]; + + switch(mark->ch) { + case _T('*'): + case _T('_'): return md_emph_stack(ctx, mark->ch, mark->flags); + + case _T('~'): return (mark->end - mark->beg == 1) ? &TILDE_OPENERS_1 : &TILDE_OPENERS_2; + + case _T('!'): + case _T('['): return &BRACKET_OPENERS; + + default: MD_UNREACHABLE(); + } +} + +static MD_MARK* +md_add_mark(MD_CTX* ctx) +{ + if(ctx->n_marks >= ctx->alloc_marks) { + MD_MARK* new_marks; + + ctx->alloc_marks = (ctx->alloc_marks > 0 + ? ctx->alloc_marks + ctx->alloc_marks / 2 + : 64); + new_marks = realloc(ctx->marks, ctx->alloc_marks * sizeof(MD_MARK)); + if(new_marks == NULL) { + MD_LOG("realloc() failed."); + return NULL; + } + + ctx->marks = new_marks; + } + + return &ctx->marks[ctx->n_marks++]; +} + +#define ADD_MARK_() \ + do { \ + mark = md_add_mark(ctx); \ + if(mark == NULL) { \ + ret = -1; \ + goto abort; \ + } \ + } while(0) + +#define ADD_MARK(ch_, beg_, end_, flags_) \ + do { \ + ADD_MARK_(); \ + mark->beg = (beg_); \ + mark->end = (end_); \ + mark->prev = -1; \ + mark->next = -1; \ + mark->ch = (char)(ch_); \ + mark->flags = (flags_); \ + } while(0) + + +static inline void +md_mark_stack_push(MD_CTX* ctx, MD_MARKSTACK* stack, int mark_index) +{ + ctx->marks[mark_index].next = stack->top; + stack->top = mark_index; +} + +static inline int +md_mark_stack_pop(MD_CTX* ctx, MD_MARKSTACK* stack) +{ + int top = stack->top; + if(top >= 0) + stack->top = ctx->marks[top].next; + return top; +} + +/* Sometimes, we need to store a pointer into the mark. It is quite rare + * so we do not bother to make MD_MARK use union, and it can only happen + * for dummy marks. */ +static inline void +md_mark_store_ptr(MD_CTX* ctx, int mark_index, void* ptr) +{ + MD_MARK* mark = &ctx->marks[mark_index]; + MD_ASSERT(mark->ch == 'D'); + + /* Check only members beg and end are misused for this. */ + MD_ASSERT(sizeof(void*) <= 2 * sizeof(OFF)); + memcpy(mark, &ptr, sizeof(void*)); +} + +static inline void* +md_mark_get_ptr(MD_CTX* ctx, int mark_index) +{ + void* ptr; + MD_MARK* mark = &ctx->marks[mark_index]; + MD_ASSERT(mark->ch == 'D'); + memcpy(&ptr, mark, sizeof(void*)); + return ptr; +} + +static inline void +md_resolve_range(MD_CTX* ctx, int opener_index, int closer_index) +{ + MD_MARK* opener = &ctx->marks[opener_index]; + MD_MARK* closer = &ctx->marks[closer_index]; + + /* Interconnect opener and closer and mark both as resolved. */ + opener->next = closer_index; + closer->prev = opener_index; + + opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; + closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED; +} + + +#define MD_ROLLBACK_CROSSING 0 +#define MD_ROLLBACK_ALL 1 + +/* In the range ctx->marks[opener_index] ... [closer_index], undo some or all + * resolvings accordingly to these rules: + * + * (1) All stacks of openers are cut so that any pending potential openers + * are discarded from future consideration. + * + * (2) If 'how' is MD_ROLLBACK_ALL, then ALL resolved marks inside the range + * are thrown away and turned into dummy marks ('D'). + * + * WARNING: Do not call for arbitrary range of opener and closer. + * This must form (potentially) valid range not crossing nesting boundaries + * of already resolved ranges. + */ +static void +md_rollback(MD_CTX* ctx, int opener_index, int closer_index, int how) +{ + int i; + + for(i = 0; i < (int) SIZEOF_ARRAY(ctx->opener_stacks); i++) { + MD_MARKSTACK* stack = &ctx->opener_stacks[i]; + while(stack->top >= opener_index) + md_mark_stack_pop(ctx, stack); + } + + if(how == MD_ROLLBACK_ALL) { + for(i = opener_index + 1; i < closer_index; i++) { + ctx->marks[i].ch = 'D'; + ctx->marks[i].flags = 0; + } + } +} + +static void +md_build_mark_char_map(MD_CTX* ctx) +{ + memset(ctx->mark_char_map, 0, sizeof(ctx->mark_char_map)); + + ctx->mark_char_map['\\'] = 1; + ctx->mark_char_map['*'] = 1; + ctx->mark_char_map['_'] = 1; + ctx->mark_char_map['`'] = 1; + ctx->mark_char_map['&'] = 1; + ctx->mark_char_map[';'] = 1; + ctx->mark_char_map['<'] = 1; + ctx->mark_char_map['>'] = 1; + ctx->mark_char_map['['] = 1; + ctx->mark_char_map['!'] = 1; + ctx->mark_char_map[']'] = 1; + ctx->mark_char_map['\0'] = 1; + + if(ctx->parser.flags & MD_FLAG_STRIKETHROUGH) + ctx->mark_char_map['~'] = 1; + + if(ctx->parser.flags & MD_FLAG_LATEXMATHSPANS) + ctx->mark_char_map['$'] = 1; + + if(ctx->parser.flags & MD_FLAG_PERMISSIVEEMAILAUTOLINKS) + ctx->mark_char_map['@'] = 1; + + if(ctx->parser.flags & MD_FLAG_PERMISSIVEURLAUTOLINKS) + ctx->mark_char_map[':'] = 1; + + if(ctx->parser.flags & MD_FLAG_PERMISSIVEWWWAUTOLINKS) + ctx->mark_char_map['.'] = 1; + + if((ctx->parser.flags & MD_FLAG_TABLES) || (ctx->parser.flags & MD_FLAG_WIKILINKS)) + ctx->mark_char_map['|'] = 1; + + if(ctx->parser.flags & MD_FLAG_COLLAPSEWHITESPACE) { + int i; + + for(i = 0; i < (int) sizeof(ctx->mark_char_map); i++) { + if(ISWHITESPACE_(i)) + ctx->mark_char_map[i] = 1; + } + } +} + +static int +md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, + MD_MARK* opener, MD_MARK* closer, + OFF last_potential_closers[CODESPAN_MARK_MAXLEN], + int* p_reached_paragraph_end) +{ + OFF opener_beg = beg; + OFF opener_end; + OFF closer_beg; + OFF closer_end; + SZ mark_len; + OFF line_end; + int has_space_after_opener = FALSE; + int has_eol_after_opener = FALSE; + int has_space_before_closer = FALSE; + int has_eol_before_closer = FALSE; + int has_only_space = TRUE; + MD_SIZE line_index = 0; + + line_end = lines[0].end; + opener_end = opener_beg; + while(opener_end < line_end && CH(opener_end) == _T('`')) + opener_end++; + has_space_after_opener = (opener_end < line_end && CH(opener_end) == _T(' ')); + has_eol_after_opener = (opener_end == line_end); + + /* The caller needs to know end of the opening mark even if we fail. */ + opener->end = opener_end; + + mark_len = opener_end - opener_beg; + if(mark_len > CODESPAN_MARK_MAXLEN) + return FALSE; + + /* Check whether we already know there is no closer of this length. + * If so, re-scan does no sense. This fixes issue #59. */ + if(last_potential_closers[mark_len-1] >= lines[n_lines-1].end || + (*p_reached_paragraph_end && last_potential_closers[mark_len-1] < opener_end)) + return FALSE; + + closer_beg = opener_end; + closer_end = opener_end; + + /* Find closer mark. */ + while(TRUE) { + while(closer_beg < line_end && CH(closer_beg) != _T('`')) { + if(CH(closer_beg) != _T(' ')) + has_only_space = FALSE; + closer_beg++; + } + closer_end = closer_beg; + while(closer_end < line_end && CH(closer_end) == _T('`')) + closer_end++; + + if(closer_end - closer_beg == mark_len) { + /* Success. */ + has_space_before_closer = (closer_beg > lines[line_index].beg && CH(closer_beg-1) == _T(' ')); + has_eol_before_closer = (closer_beg == lines[line_index].beg); + break; + } + + if(closer_end - closer_beg > 0) { + /* We have found a back-tick which is not part of the closer. */ + has_only_space = FALSE; + + /* But if we eventually fail, remember it as a potential closer + * of its own length for future attempts. This mitigates needs for + * rescans. */ + if(closer_end - closer_beg < CODESPAN_MARK_MAXLEN) { + if(closer_beg > last_potential_closers[closer_end - closer_beg - 1]) + last_potential_closers[closer_end - closer_beg - 1] = closer_beg; + } + } + + if(closer_end >= line_end) { + line_index++; + if(line_index >= n_lines) { + /* Reached end of the paragraph and still nothing. */ + *p_reached_paragraph_end = TRUE; + return FALSE; + } + /* Try on the next line. */ + line_end = lines[line_index].end; + closer_beg = lines[line_index].beg; + } else { + closer_beg = closer_end; + } + } + + /* If there is a space or a new line both after and before the opener + * (and if the code span is not made of spaces only), consume one initial + * and one trailing space as part of the marks. */ + if(!has_only_space && + (has_space_after_opener || has_eol_after_opener) && + (has_space_before_closer || has_eol_before_closer)) + { + if(has_space_after_opener) + opener_end++; + else + opener_end = lines[1].beg; + + if(has_space_before_closer) + closer_beg--; + else { + /* Go back to the end of prev line */ + closer_beg = lines[line_index-1].end; + /* But restore any trailing whitespace */ + while(closer_beg < ctx->size && ISBLANK(closer_beg)) + closer_beg++; + } + } + + opener->ch = _T('`'); + opener->beg = opener_beg; + opener->end = opener_end; + opener->flags = MD_MARK_POTENTIAL_OPENER; + closer->ch = _T('`'); + closer->beg = closer_beg; + closer->end = closer_end; + closer->flags = MD_MARK_POTENTIAL_CLOSER; + return TRUE; +} + +static int +md_is_autolink_uri(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end) +{ + OFF off = beg+1; + + MD_ASSERT(CH(beg) == _T('<')); + + /* Check for scheme. */ + if(off >= max_end || !ISASCII(off)) + return FALSE; + off++; + while(1) { + if(off >= max_end) + return FALSE; + if(off - beg > 32) + return FALSE; + if(CH(off) == _T(':') && off - beg >= 3) + break; + if(!ISALNUM(off) && CH(off) != _T('+') && CH(off) != _T('-') && CH(off) != _T('.')) + return FALSE; + off++; + } + + /* Check the path after the scheme. */ + while(off < max_end && CH(off) != _T('>')) { + if(ISWHITESPACE(off) || ISCNTRL(off) || CH(off) == _T('<')) + return FALSE; + off++; + } + + if(off >= max_end) + return FALSE; + + MD_ASSERT(CH(off) == _T('>')); + *p_end = off+1; + return TRUE; +} + +static int +md_is_autolink_email(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end) +{ + OFF off = beg + 1; + int label_len; + + MD_ASSERT(CH(beg) == _T('<')); + + /* The code should correspond to this regexp: + /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+ + @[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])? + (?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ + */ + + /* Username (before '@'). */ + while(off < max_end && (ISALNUM(off) || ISANYOF(off, _T(".!#$%&'*+/=?^_`{|}~-")))) + off++; + if(off <= beg+1) + return FALSE; + + /* '@' */ + if(off >= max_end || CH(off) != _T('@')) + return FALSE; + off++; + + /* Labels delimited with '.'; each label is sequence of 1 - 63 alnum + * characters or '-', but '-' is not allowed as first or last char. */ + label_len = 0; + while(off < max_end) { + if(ISALNUM(off)) + label_len++; + else if(CH(off) == _T('-') && label_len > 0) + label_len++; + else if(CH(off) == _T('.') && label_len > 0 && CH(off-1) != _T('-')) + label_len = 0; + else + break; + + if(label_len > 63) + return FALSE; + + off++; + } + + if(label_len <= 0 || off >= max_end || CH(off) != _T('>') || CH(off-1) == _T('-')) + return FALSE; + + *p_end = off+1; + return TRUE; +} + +static int +md_is_autolink(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, int* p_missing_mailto) +{ + if(md_is_autolink_uri(ctx, beg, max_end, p_end)) { + *p_missing_mailto = FALSE; + return TRUE; + } + + if(md_is_autolink_email(ctx, beg, max_end, p_end)) { + *p_missing_mailto = TRUE; + return TRUE; + } + + return FALSE; +} + +static int +md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int table_mode) +{ + MD_SIZE line_index; + int ret = 0; + MD_MARK* mark; + OFF codespan_last_potential_closers[CODESPAN_MARK_MAXLEN] = { 0 }; + int codespan_scanned_till_paragraph_end = FALSE; + + for(line_index = 0; line_index < n_lines; line_index++) { + const MD_LINE* line = &lines[line_index]; + OFF off = line->beg; + + while(TRUE) { + CHAR ch; + +#ifdef MD4C_USE_UTF16 + /* For UTF-16, mark_char_map[] covers only ASCII. */ + #define IS_MARK_CHAR(off) ((CH(off) < SIZEOF_ARRAY(ctx->mark_char_map)) && \ + (ctx->mark_char_map[(unsigned char) CH(off)])) +#else + /* For 8-bit encodings, mark_char_map[] covers all 256 elements. */ + #define IS_MARK_CHAR(off) (ctx->mark_char_map[(unsigned char) CH(off)]) +#endif + + /* Optimization: Use some loop unrolling. */ + while(off + 3 < line->end && !IS_MARK_CHAR(off+0) && !IS_MARK_CHAR(off+1) + && !IS_MARK_CHAR(off+2) && !IS_MARK_CHAR(off+3)) + off += 4; + while(off < line->end && !IS_MARK_CHAR(off+0)) + off++; + + if(off >= line->end) + break; + + ch = CH(off); + + /* A backslash escape. + * It can go beyond line->end as it may involve escaped new + * line to form a hard break. */ + if(ch == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { + /* Hard-break cannot be on the last line of the block. */ + if(!ISNEWLINE(off+1) || line_index+1 < n_lines) + ADD_MARK(ch, off, off+2, MD_MARK_RESOLVED); + off += 2; + continue; + } + + /* A potential (string) emphasis start/end. */ + if(ch == _T('*') || ch == _T('_')) { + OFF tmp = off+1; + int left_level; /* What precedes: 0 = whitespace; 1 = punctuation; 2 = other char. */ + int right_level; /* What follows: 0 = whitespace; 1 = punctuation; 2 = other char. */ + + while(tmp < line->end && CH(tmp) == ch) + tmp++; + + if(off == line->beg || ISUNICODEWHITESPACEBEFORE(off)) + left_level = 0; + else if(ISUNICODEPUNCTBEFORE(off)) + left_level = 1; + else + left_level = 2; + + if(tmp == line->end || ISUNICODEWHITESPACE(tmp)) + right_level = 0; + else if(ISUNICODEPUNCT(tmp)) + right_level = 1; + else + right_level = 2; + + /* Intra-word underscore doesn't have special meaning. */ + if(ch == _T('_') && left_level == 2 && right_level == 2) { + left_level = 0; + right_level = 0; + } + + if(left_level != 0 || right_level != 0) { + unsigned flags = 0; + + if(left_level > 0 && left_level >= right_level) + flags |= MD_MARK_POTENTIAL_CLOSER; + if(right_level > 0 && right_level >= left_level) + flags |= MD_MARK_POTENTIAL_OPENER; + if(flags == (MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER)) + flags |= MD_MARK_EMPH_OC; + + /* For "the rule of three" we need to remember the original + * size of the mark (modulo three), before we potentially + * split the mark when being later resolved partially by some + * shorter closer. */ + switch((tmp - off) % 3) { + case 0: flags |= MD_MARK_EMPH_MOD3_0; break; + case 1: flags |= MD_MARK_EMPH_MOD3_1; break; + case 2: flags |= MD_MARK_EMPH_MOD3_2; break; + } + + ADD_MARK(ch, off, tmp, flags); + + /* During resolving, multiple asterisks may have to be + * split into independent span start/ends. Consider e.g. + * "**foo* bar*". Therefore we push also some empty dummy + * marks to have enough space for that. */ + off++; + while(off < tmp) { + ADD_MARK('D', off, off, 0); + off++; + } + continue; + } + + off = tmp; + continue; + } + + /* A potential code span start/end. */ + if(ch == _T('`')) { + MD_MARK opener; + MD_MARK closer; + int is_code_span; + + is_code_span = md_is_code_span(ctx, line, n_lines - line_index, off, + &opener, &closer, codespan_last_potential_closers, + &codespan_scanned_till_paragraph_end); + if(is_code_span) { + ADD_MARK(opener.ch, opener.beg, opener.end, opener.flags); + ADD_MARK(closer.ch, closer.beg, closer.end, closer.flags); + md_resolve_range(ctx, ctx->n_marks-2, ctx->n_marks-1); + off = closer.end; + + /* Advance the current line accordingly. */ + if(off > line->end) + line = md_lookup_line(off, lines, n_lines, &line_index); + continue; + } + + off = opener.end; + continue; + } + + /* A potential entity start. */ + if(ch == _T('&')) { + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); + off++; + continue; + } + + /* A potential entity end. */ + if(ch == _T(';')) { + /* We surely cannot be entity unless the previous mark is '&'. */ + if(ctx->n_marks > 0 && ctx->marks[ctx->n_marks-1].ch == _T('&')) + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); + + off++; + continue; + } + + /* A potential autolink or raw HTML start/end. */ + if(ch == _T('<')) { + int is_autolink; + OFF autolink_end; + int missing_mailto; + + if(!(ctx->parser.flags & MD_FLAG_NOHTMLSPANS)) { + int is_html; + OFF html_end; + + /* Given the nature of the raw HTML, we have to recognize + * it here. Doing so later in md_analyze_lt_gt() could + * open can of worms of quadratic complexity. */ + is_html = md_is_html_any(ctx, line, n_lines - line_index, off, + lines[n_lines-1].end, &html_end); + if(is_html) { + ADD_MARK(_T('<'), off, off, MD_MARK_OPENER | MD_MARK_RESOLVED); + ADD_MARK(_T('>'), html_end, html_end, MD_MARK_CLOSER | MD_MARK_RESOLVED); + ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; + ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; + off = html_end; + + /* Advance the current line accordingly. */ + if(off > line->end) + line = md_lookup_line(off, lines, n_lines, &line_index); + continue; + } + } + + is_autolink = md_is_autolink(ctx, off, lines[n_lines-1].end, + &autolink_end, &missing_mailto); + if(is_autolink) { + unsigned flags = MD_MARK_RESOLVED | MD_MARK_AUTOLINK; + if(missing_mailto) + flags |= MD_MARK_AUTOLINK_MISSING_MAILTO; + + ADD_MARK(_T('<'), off, off+1, MD_MARK_OPENER | flags); + ADD_MARK(_T('>'), autolink_end-1, autolink_end, MD_MARK_CLOSER | flags); + ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; + ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; + off = autolink_end; + continue; + } + + off++; + continue; + } + + /* A potential link or its part. */ + if(ch == _T('[') || (ch == _T('!') && off+1 < line->end && CH(off+1) == _T('['))) { + OFF tmp = (ch == _T('[') ? off+1 : off+2); + ADD_MARK(ch, off, tmp, MD_MARK_POTENTIAL_OPENER); + off = tmp; + /* Two dummies to make enough place for data we need if it is + * a link. */ + ADD_MARK('D', off, off, 0); + ADD_MARK('D', off, off, 0); + continue; + } + if(ch == _T(']')) { + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); + off++; + continue; + } + + /* A potential permissive e-mail autolink. */ + if(ch == _T('@')) { + if(line->beg + 1 <= off && ISALNUM(off-1) && + off + 3 < line->end && ISALNUM(off+1)) + { + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); + /* Push a dummy as a reserve for a closer. */ + ADD_MARK('D', line->beg, line->end, 0); + } + + off++; + continue; + } + + /* A potential permissive URL autolink. */ + if(ch == _T(':')) { + static struct { + const CHAR* scheme; + SZ scheme_size; + const CHAR* suffix; + SZ suffix_size; + } scheme_map[] = { + /* In the order from the most frequently used, arguably. */ + { _T("http"), 4, _T("//"), 2 }, + { _T("https"), 5, _T("//"), 2 }, + { _T("ftp"), 3, _T("//"), 2 } + }; + int scheme_index; + + for(scheme_index = 0; scheme_index < (int) SIZEOF_ARRAY(scheme_map); scheme_index++) { + const CHAR* scheme = scheme_map[scheme_index].scheme; + const SZ scheme_size = scheme_map[scheme_index].scheme_size; + const CHAR* suffix = scheme_map[scheme_index].suffix; + const SZ suffix_size = scheme_map[scheme_index].suffix_size; + + if(line->beg + scheme_size <= off && md_ascii_eq(STR(off-scheme_size), scheme, scheme_size) && + off + 1 + suffix_size < line->end && md_ascii_eq(STR(off+1), suffix, suffix_size)) + { + ADD_MARK(ch, off-scheme_size, off+1+suffix_size, MD_MARK_POTENTIAL_OPENER); + /* Push a dummy as a reserve for a closer. */ + ADD_MARK('D', line->beg, line->end, 0); + off += 1 + suffix_size; + break; + } + } + + off++; + continue; + } + + /* A potential permissive WWW autolink. */ + if(ch == _T('.')) { + if(line->beg + 3 <= off && md_ascii_eq(STR(off-3), _T("www"), 3) && + (off-3 == line->beg || ISUNICODEWHITESPACEBEFORE(off-3) || ISUNICODEPUNCTBEFORE(off-3))) + { + ADD_MARK(ch, off-3, off+1, MD_MARK_POTENTIAL_OPENER); + /* Push a dummy as a reserve for a closer. */ + ADD_MARK('D', line->beg, line->end, 0); + off++; + continue; + } + + off++; + continue; + } + + /* A potential table cell boundary or wiki link label delimiter. */ + if((table_mode || ctx->parser.flags & MD_FLAG_WIKILINKS) && ch == _T('|')) { + ADD_MARK(ch, off, off+1, 0); + off++; + continue; + } + + /* A potential strikethrough/equation start/end. */ + if(ch == _T('$') || ch == _T('~')) { + OFF tmp = off+1; + + while(tmp < line->end && CH(tmp) == ch) + tmp++; + + if(tmp - off <= 2) { + unsigned flags = MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER; + + if(off > line->beg && !ISUNICODEWHITESPACEBEFORE(off) && !ISUNICODEPUNCTBEFORE(off)) + flags &= ~MD_MARK_POTENTIAL_OPENER; + if(tmp < line->end && !ISUNICODEWHITESPACE(tmp) && !ISUNICODEPUNCT(tmp)) + flags &= ~MD_MARK_POTENTIAL_CLOSER; + if(flags != 0) + ADD_MARK(ch, off, tmp, flags); + } + + off = tmp; + continue; + } + + /* Turn non-trivial whitespace into single space. */ + if(ISWHITESPACE_(ch)) { + OFF tmp = off+1; + + while(tmp < line->end && ISWHITESPACE(tmp)) + tmp++; + + if(tmp - off > 1 || ch != _T(' ')) + ADD_MARK(ch, off, tmp, MD_MARK_RESOLVED); + + off = tmp; + continue; + } + + /* NULL character. */ + if(ch == _T('\0')) { + ADD_MARK(ch, off, off+1, MD_MARK_RESOLVED); + off++; + continue; + } + + off++; + } + } + + /* Add a dummy mark at the end of the mark vector to simplify + * process_inlines(). */ + ADD_MARK(127, ctx->size, ctx->size, MD_MARK_RESOLVED); + +abort: + return ret; +} + +static void +md_analyze_bracket(MD_CTX* ctx, int mark_index) +{ + /* We cannot really resolve links here as for that we would need + * more context. E.g. a following pair of brackets (reference link), + * or enclosing pair of brackets (if the inner is the link, the outer + * one cannot be.) + * + * Therefore we here only construct a list of '[' ']' pairs ordered by + * position of the closer. This allows us to analyze what is or is not + * link in the right order, from inside to outside in case of nested + * brackets. + * + * The resolving itself is deferred to md_resolve_links(). + */ + + MD_MARK* mark = &ctx->marks[mark_index]; + + if(mark->flags & MD_MARK_POTENTIAL_OPENER) { + if(BRACKET_OPENERS.top >= 0) + ctx->marks[BRACKET_OPENERS.top].flags |= MD_MARK_HASNESTEDBRACKETS; + + md_mark_stack_push(ctx, &BRACKET_OPENERS, mark_index); + return; + } + + if(BRACKET_OPENERS.top >= 0) { + int opener_index = md_mark_stack_pop(ctx, &BRACKET_OPENERS); + MD_MARK* opener = &ctx->marks[opener_index]; + + /* Interconnect the opener and closer. */ + opener->next = mark_index; + mark->prev = opener_index; + + /* Add the pair into a list of potential links for md_resolve_links(). + * Note we misuse opener->prev for this as opener->next points to its + * closer. */ + if(ctx->unresolved_link_tail >= 0) + ctx->marks[ctx->unresolved_link_tail].prev = opener_index; + else + ctx->unresolved_link_head = opener_index; + ctx->unresolved_link_tail = opener_index; + opener->prev = -1; + } +} + +/* Forward declaration. */ +static void md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, + int mark_beg, int mark_end); + +static int +md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) +{ + int opener_index = ctx->unresolved_link_head; + OFF last_link_beg = 0; + OFF last_link_end = 0; + OFF last_img_beg = 0; + OFF last_img_end = 0; + + while(opener_index >= 0) { + MD_MARK* opener = &ctx->marks[opener_index]; + int closer_index = opener->next; + MD_MARK* closer = &ctx->marks[closer_index]; + int next_index = opener->prev; + MD_MARK* next_opener; + MD_MARK* next_closer; + MD_LINK_ATTR attr; + int is_link = FALSE; + + if(next_index >= 0) { + next_opener = &ctx->marks[next_index]; + next_closer = &ctx->marks[next_opener->next]; + } else { + next_opener = NULL; + next_closer = NULL; + } + + /* If nested ("[ [ ] ]"), we need to make sure that: + * - The outer does not end inside of (...) belonging to the inner. + * - The outer cannot be link if the inner is link (i.e. not image). + * + * (Note we here analyze from inner to outer as the marks are ordered + * by closer->beg.) + */ + if((opener->beg < last_link_beg && closer->end < last_link_end) || + (opener->beg < last_img_beg && closer->end < last_img_end) || + (opener->beg < last_link_end && opener->ch == '[')) + { + opener_index = next_index; + continue; + } + + /* Recognize and resolve wiki links. + * Wiki-links maybe '[[destination]]' or '[[destination|label]]'. + */ + if ((ctx->parser.flags & MD_FLAG_WIKILINKS) && + (opener->end - opener->beg == 1) && /* not image */ + next_opener != NULL && /* double '[' opener */ + next_opener->ch == '[' && + (next_opener->beg == opener->beg - 1) && + (next_opener->end - next_opener->beg == 1) && + next_closer != NULL && /* double ']' closer */ + next_closer->ch == ']' && + (next_closer->beg == closer->beg + 1) && + (next_closer->end - next_closer->beg == 1)) + { + MD_MARK* delim = NULL; + int delim_index; + OFF dest_beg, dest_end; + + is_link = TRUE; + + /* We don't allow destination to be longer than 100 characters. + * Lets scan to see whether there is '|'. (If not then the whole + * wiki-link has to be below the 100 characters.) */ + delim_index = opener_index + 1; + while(delim_index < closer_index) { + MD_MARK* m = &ctx->marks[delim_index]; + if(m->ch == '|') { + delim = m; + break; + } + if(m->ch != 'D') { + if(m->beg - opener->end > 100) + break; + if(m->ch != 'D' && (m->flags & MD_MARK_OPENER)) + delim_index = m->next; + } + delim_index++; + } + + dest_beg = opener->end; + dest_end = (delim != NULL) ? delim->beg : closer->beg; + if(dest_end - dest_beg == 0 || dest_end - dest_beg > 100) + is_link = FALSE; + + /* There may not be any new line in the destination. */ + if(is_link) { + OFF off; + for(off = dest_beg; off < dest_end; off++) { + if(ISNEWLINE(off)) { + is_link = FALSE; + break; + } + } + } + + if(is_link) { + if(delim != NULL) { + if(delim->end < closer->beg) { + md_rollback(ctx, opener_index, delim_index, MD_ROLLBACK_ALL); + md_rollback(ctx, delim_index, closer_index, MD_ROLLBACK_CROSSING); + delim->flags |= MD_MARK_RESOLVED; + opener->end = delim->beg; + } else { + /* The pipe is just before the closer: [[foo|]] */ + md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL); + closer->beg = delim->beg; + delim = NULL; + } + } + + opener->beg = next_opener->beg; + opener->next = closer_index; + opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; + + closer->end = next_closer->end; + closer->prev = opener_index; + closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED; + + last_link_beg = opener->beg; + last_link_end = closer->end; + + if(delim != NULL) + md_analyze_link_contents(ctx, lines, n_lines, delim_index+1, closer_index); + + opener_index = next_opener->prev; + continue; + } + } + + if(next_opener != NULL && next_opener->beg == closer->end) { + if(next_closer->beg > closer->end + 1) { + /* Might be full reference link. */ + if(!(next_opener->flags & MD_MARK_HASNESTEDBRACKETS)) + is_link = md_is_link_reference(ctx, lines, n_lines, next_opener->beg, next_closer->end, &attr); + } else { + /* Might be shortcut reference link. */ + if(!(opener->flags & MD_MARK_HASNESTEDBRACKETS)) + is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); + } + + if(is_link < 0) + return -1; + + if(is_link) { + /* Eat the 2nd "[...]". */ + closer->end = next_closer->end; + + /* Do not analyze the label as a standalone link in the next + * iteration. */ + next_index = ctx->marks[next_index].prev; + } + } else { + if(closer->end < ctx->size && CH(closer->end) == _T('(')) { + /* Might be inline link. */ + OFF inline_link_end = UINT_MAX; + + is_link = md_is_inline_link_spec(ctx, lines, n_lines, closer->end, &inline_link_end, &attr); + if(is_link < 0) + return -1; + + /* Check the closing ')' is not inside an already resolved range + * (i.e. a range with a higher priority), e.g. a code span. */ + if(is_link) { + int i = closer_index + 1; + + while(i < ctx->n_marks) { + MD_MARK* mark = &ctx->marks[i]; + + if(mark->beg >= inline_link_end) + break; + if((mark->flags & (MD_MARK_OPENER | MD_MARK_RESOLVED)) == (MD_MARK_OPENER | MD_MARK_RESOLVED)) { + if(ctx->marks[mark->next].beg >= inline_link_end) { + /* Cancel the link status. */ + if(attr.title_needs_free) + free(attr.title); + is_link = FALSE; + break; + } + + i = mark->next + 1; + } else { + i++; + } + } + } + + if(is_link) { + /* Eat the "(...)" */ + closer->end = inline_link_end; + } + } + + if(!is_link) { + /* Might be collapsed reference link. */ + if(!(opener->flags & MD_MARK_HASNESTEDBRACKETS)) + is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); + if(is_link < 0) + return -1; + } + } + + if(is_link) { + /* Resolve the brackets as a link. */ + opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; + closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED; + + /* If it is a link, we store the destination and title in the two + * dummy marks after the opener. */ + MD_ASSERT(ctx->marks[opener_index+1].ch == 'D'); + ctx->marks[opener_index+1].beg = attr.dest_beg; + ctx->marks[opener_index+1].end = attr.dest_end; + + MD_ASSERT(ctx->marks[opener_index+2].ch == 'D'); + md_mark_store_ptr(ctx, opener_index+2, attr.title); + /* The title might or might not have been allocated for us. */ + if(attr.title_needs_free) + md_mark_stack_push(ctx, &ctx->ptr_stack, opener_index+2); + ctx->marks[opener_index+2].prev = attr.title_size; + + if(opener->ch == '[') { + last_link_beg = opener->beg; + last_link_end = closer->end; + } else { + last_img_beg = opener->beg; + last_img_end = closer->end; + } + + md_analyze_link_contents(ctx, lines, n_lines, opener_index+1, closer_index); + + /* If the link text is formed by nothing but permissive autolink, + * suppress the autolink. + * See https://github.com/mity/md4c/issues/152 for more info. */ + if(ctx->parser.flags & MD_FLAG_PERMISSIVEAUTOLINKS) { + MD_MARK* first_nested; + MD_MARK* last_nested; + + first_nested = opener + 1; + while(first_nested->ch == _T('D') && first_nested < closer) + first_nested++; + + last_nested = closer - 1; + while(first_nested->ch == _T('D') && last_nested > opener) + last_nested--; + + if((first_nested->flags & MD_MARK_RESOLVED) && + first_nested->beg == opener->end && + ISANYOF_(first_nested->ch, _T("@:.")) && + first_nested->next == (last_nested - ctx->marks) && + last_nested->end == closer->beg) + { + first_nested->ch = _T('D'); + first_nested->flags &= ~MD_MARK_RESOLVED; + last_nested->ch = _T('D'); + last_nested->flags &= ~MD_MARK_RESOLVED; + } + } + } + + opener_index = next_index; + } + + return 0; +} + +/* Analyze whether the mark '&' starts a HTML entity. + * If so, update its flags as well as flags of corresponding closer ';'. */ +static void +md_analyze_entity(MD_CTX* ctx, int mark_index) +{ + MD_MARK* opener = &ctx->marks[mark_index]; + MD_MARK* closer; + OFF off; + + /* Cannot be entity if there is no closer as the next mark. + * (Any other mark between would mean strange character which cannot be + * part of the entity. + * + * So we can do all the work on '&' and do not call this later for the + * closing mark ';'. + */ + if(mark_index + 1 >= ctx->n_marks) + return; + closer = &ctx->marks[mark_index+1]; + if(closer->ch != ';') + return; + + if(md_is_entity(ctx, opener->beg, closer->end, &off)) { + MD_ASSERT(off == closer->end); + + md_resolve_range(ctx, mark_index, mark_index+1); + opener->end = closer->end; + } +} + +static void +md_analyze_table_cell_boundary(MD_CTX* ctx, int mark_index) +{ + MD_MARK* mark = &ctx->marks[mark_index]; + mark->flags |= MD_MARK_RESOLVED; + mark->next = -1; + + if(ctx->table_cell_boundaries_head < 0) + ctx->table_cell_boundaries_head = mark_index; + else + ctx->marks[ctx->table_cell_boundaries_tail].next = mark_index; + ctx->table_cell_boundaries_tail = mark_index; + ctx->n_table_cell_boundaries++; +} + +/* Split a longer mark into two. The new mark takes the given count of + * characters. May only be called if an adequate number of dummy 'D' marks + * follows. + */ +static int +md_split_emph_mark(MD_CTX* ctx, int mark_index, SZ n) +{ + MD_MARK* mark = &ctx->marks[mark_index]; + int new_mark_index = mark_index + (mark->end - mark->beg - n); + MD_MARK* dummy = &ctx->marks[new_mark_index]; + + MD_ASSERT(mark->end - mark->beg > n); + MD_ASSERT(dummy->ch == 'D'); + + memcpy(dummy, mark, sizeof(MD_MARK)); + mark->end -= n; + dummy->beg = mark->end; + + return new_mark_index; +} + +static void +md_analyze_emph(MD_CTX* ctx, int mark_index) +{ + MD_MARK* mark = &ctx->marks[mark_index]; + + /* If we can be a closer, try to resolve with the preceding opener. */ + if(mark->flags & MD_MARK_POTENTIAL_CLOSER) { + MD_MARK* opener = NULL; + int opener_index = 0; + MD_MARKSTACK* opener_stacks[6]; + int i, n_opener_stacks; + unsigned flags = mark->flags; + + n_opener_stacks = 0; + + /* Apply the rule of 3 */ + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_0 | MD_MARK_EMPH_OC); + if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_1 | MD_MARK_EMPH_OC); + if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_2 | MD_MARK_EMPH_OC); + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_0); + if(!(flags & MD_MARK_EMPH_OC) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_1); + if(!(flags & MD_MARK_EMPH_OC) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_2); + + /* Opener is the most recent mark from the allowed stacks. */ + for(i = 0; i < n_opener_stacks; i++) { + if(opener_stacks[i]->top >= 0) { + int m_index = opener_stacks[i]->top; + MD_MARK* m = &ctx->marks[m_index]; + + if(opener == NULL || m->end > opener->end) { + opener_index = m_index; + opener = m; + } + } + } + + /* Resolve, if we have found matching opener. */ + if(opener != NULL) { + SZ opener_size = opener->end - opener->beg; + SZ closer_size = mark->end - mark->beg; + MD_MARKSTACK* stack = md_opener_stack(ctx, opener_index); + + if(opener_size > closer_size) { + opener_index = md_split_emph_mark(ctx, opener_index, closer_size); + md_mark_stack_push(ctx, stack, opener_index); + } else if(opener_size < closer_size) { + md_split_emph_mark(ctx, mark_index, closer_size - opener_size); + } + + /* Above we were only peeking. */ + md_mark_stack_pop(ctx, stack); + + md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING); + md_resolve_range(ctx, opener_index, mark_index); + return; + } + } + + /* If we could not resolve as closer, we may be yet be an opener. */ + if(mark->flags & MD_MARK_POTENTIAL_OPENER) + md_mark_stack_push(ctx, md_emph_stack(ctx, mark->ch, mark->flags), mark_index); +} + +static void +md_analyze_tilde(MD_CTX* ctx, int mark_index) +{ + MD_MARK* mark = &ctx->marks[mark_index]; + MD_MARKSTACK* stack = md_opener_stack(ctx, mark_index); + + /* We attempt to be Github Flavored Markdown compatible here. GFM accepts + * only tildes sequences of length 1 and 2, and the length of the opener + * and closer has to match. */ + + if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && stack->top >= 0) { + int opener_index = stack->top; + + md_mark_stack_pop(ctx, stack); + md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING); + md_resolve_range(ctx, opener_index, mark_index); + return; + } + + if(mark->flags & MD_MARK_POTENTIAL_OPENER) + md_mark_stack_push(ctx, stack, mark_index); +} + +static void +md_analyze_dollar(MD_CTX* ctx, int mark_index) +{ + MD_MARK* mark = &ctx->marks[mark_index]; + + if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && DOLLAR_OPENERS.top >= 0) { + /* If the potential closer has a non-matching number of $, discard */ + MD_MARK* opener = &ctx->marks[DOLLAR_OPENERS.top]; + int opener_index = DOLLAR_OPENERS.top; + MD_MARK* closer = mark; + int closer_index = mark_index; + + if(opener->end - opener->beg == closer->end - closer->beg) { + /* We are the matching closer */ + md_mark_stack_pop(ctx, &DOLLAR_OPENERS); + md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL); + md_resolve_range(ctx, opener_index, closer_index); + + /* Discard all pending openers: Latex math span do not allow + * nesting. */ + DOLLAR_OPENERS.top = -1; + return; + } + } + + if(mark->flags & MD_MARK_POTENTIAL_OPENER) + md_mark_stack_push(ctx, &DOLLAR_OPENERS, mark_index); +} + +static MD_MARK* +md_scan_left_for_resolved_mark(MD_CTX* ctx, MD_MARK* mark_from, OFF off, MD_MARK** p_cursor) +{ + MD_MARK* mark; + + for(mark = mark_from; mark >= ctx->marks; mark--) { + if(mark->ch == 'D' || mark->beg > off) + continue; + if(mark->beg <= off && off < mark->end && (mark->flags & MD_MARK_RESOLVED)) { + if(p_cursor != NULL) + *p_cursor = mark; + return mark; + } + if(mark->end <= off) + break; + } + + if(p_cursor != NULL) + *p_cursor = mark; + return NULL; +} + +static MD_MARK* +md_scan_right_for_resolved_mark(MD_CTX* ctx, MD_MARK* mark_from, OFF off, MD_MARK** p_cursor) +{ + MD_MARK* mark; + + for(mark = mark_from; mark < ctx->marks + ctx->n_marks; mark++) { + if(mark->ch == 'D' || mark->end <= off) + continue; + if(mark->beg <= off && off < mark->end && (mark->flags & MD_MARK_RESOLVED)) { + if(p_cursor != NULL) + *p_cursor = mark; + return mark; + } + if(mark->beg > off) + break; + } + + if(p_cursor != NULL) + *p_cursor = mark; + return NULL; +} + +static void +md_analyze_permissive_autolink(MD_CTX* ctx, int mark_index) +{ + static const struct { + const MD_CHAR start_char; + const MD_CHAR delim_char; + const MD_CHAR* allowed_nonalnum_chars; + int min_components; + const MD_CHAR optional_end_char; + } URL_MAP[] = { + { _T('\0'), _T('.'), _T(".-_"), 2, _T('\0') }, /* host, mandatory */ + { _T('/'), _T('/'), _T("/.-_"), 0, _T('/') }, /* path */ + { _T('?'), _T('&'), _T("&.-+_=()"), 1, _T('\0') }, /* query */ + { _T('#'), _T('\0'), _T(".-+_") , 1, _T('\0') } /* fragment */ + }; + + MD_MARK* opener = &ctx->marks[mark_index]; + MD_MARK* closer = &ctx->marks[mark_index + 1]; /* The dummy. */ + OFF line_beg = closer->beg; /* md_collect_mark() set this for us */ + OFF line_end = closer->end; /* ditto */ + OFF beg = opener->beg; + OFF end = opener->end; + MD_MARK* left_cursor = opener; + int left_boundary_ok = FALSE; + MD_MARK* right_cursor = opener; + int right_boundary_ok = FALSE; + unsigned i; + + MD_ASSERT(closer->ch == 'D'); + + if(opener->ch == '@') { + MD_ASSERT(CH(opener->beg) == _T('@')); + + /* Scan backwards for the user name (before '@'). */ + while(beg > line_beg) { + if(ISALNUM(beg-1)) + beg--; + else if(beg >= line_beg+2 && ISALNUM(beg-2) && + ISANYOF(beg-1, _T(".-_+")) && + md_scan_left_for_resolved_mark(ctx, left_cursor, beg-1, &left_cursor) == NULL && + ISALNUM(beg)) + beg--; + else + break; + } + if(beg == opener->beg) /* empty user name */ + return; + } + + /* Verify there's line boundary, whitespace, allowed punctuation or + * resolved emphasis mark just before the suspected autolink. */ + if(beg == line_beg || ISUNICODEWHITESPACEBEFORE(beg) || ISANYOF(beg-1, _T("({["))) { + left_boundary_ok = TRUE; + } else if(ISANYOF(beg-1, _T("*_~"))) { + MD_MARK* left_mark; + + left_mark = md_scan_left_for_resolved_mark(ctx, left_cursor, beg-1, &left_cursor); + if(left_mark != NULL && (left_mark->flags & MD_MARK_OPENER)) + left_boundary_ok = TRUE; + } + if(!left_boundary_ok) + return; + + for(i = 0; i < SIZEOF_ARRAY(URL_MAP); i++) { + int n_components = 0; + int n_open_brackets = 0; + + if(URL_MAP[i].start_char != _T('\0')) { + if(end >= line_end || CH(end) != URL_MAP[i].start_char) + continue; + if(URL_MAP[i].min_components > 0 && (end+1 >= line_end || !ISALNUM(end+1))) + continue; + end++; + } + + while(end < line_end) { + if(ISALNUM(end)) { + if(n_components == 0) + n_components++; + end++; + } else if(end < line_end && + ISANYOF(end, URL_MAP[i].allowed_nonalnum_chars) && + md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor) == NULL && + ((end > line_beg && (ISALNUM(end-1) || CH(end-1) == _T(')'))) || CH(end) == _T('(')) && + ((end+1 < line_end && (ISALNUM(end+1) || CH(end+1) == _T('('))) || CH(end) == _T(')'))) + { + if(CH(end) == URL_MAP[i].delim_char) + n_components++; + + /* brackets have to be balanced. */ + if(CH(end) == _T('(')) { + n_open_brackets++; + } else if(CH(end) == _T(')')) { + if(n_open_brackets <= 0) + break; + n_open_brackets--; + } + + end++; + } else { + break; + } + } + + if(end < line_end && URL_MAP[i].optional_end_char != _T('\0') && + CH(end) == URL_MAP[i].optional_end_char) + end++; + + if(n_components < URL_MAP[i].min_components || n_open_brackets != 0) + return; + + if(opener->ch == '@') /* E-mail autolinks wants only the host. */ + break; + } + + /* Verify there's line boundary, whitespace, allowed punctuation or + * resolved emphasis mark just after the suspected autolink. */ + if(end == line_end || ISUNICODEWHITESPACE(end) || ISANYOF(end, _T(")}].!?,;"))) { + right_boundary_ok = TRUE; + } else { + MD_MARK* right_mark; + + right_mark = md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor); + if(right_mark != NULL && (right_mark->flags & MD_MARK_CLOSER)) + right_boundary_ok = TRUE; + } + if(!right_boundary_ok) + return; + + /* Success, we are an autolink. */ + opener->beg = beg; + opener->end = beg; + closer->beg = end; + closer->end = end; + closer->ch = opener->ch; + md_resolve_range(ctx, mark_index, mark_index + 1); +} + +#define MD_ANALYZE_NOSKIP_EMPH 0x01 + +static inline void +md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, + int mark_beg, int mark_end, const CHAR* mark_chars, unsigned flags) +{ + int i = mark_beg; + OFF last_end = lines[0].beg; + + MD_UNUSED(lines); + MD_UNUSED(n_lines); + + while(i < mark_end) { + MD_MARK* mark = &ctx->marks[i]; + + /* Skip resolved spans. */ + if(mark->flags & MD_MARK_RESOLVED) { + if((mark->flags & MD_MARK_OPENER) && + !((flags & MD_ANALYZE_NOSKIP_EMPH) && ISANYOF_(mark->ch, "*_~"))) + { + MD_ASSERT(i < mark->next); + i = mark->next + 1; + } else { + i++; + } + continue; + } + + /* Skip marks we do not want to deal with. */ + if(!ISANYOF_(mark->ch, mark_chars)) { + i++; + continue; + } + + /* The resolving in previous step could have expanded a mark. */ + if(mark->beg < last_end) { + i++; + continue; + } + + /* Analyze the mark. */ + switch(mark->ch) { + case '[': /* Pass through. */ + case '!': /* Pass through. */ + case ']': md_analyze_bracket(ctx, i); break; + case '&': md_analyze_entity(ctx, i); break; + case '|': md_analyze_table_cell_boundary(ctx, i); break; + case '_': /* Pass through. */ + case '*': md_analyze_emph(ctx, i); break; + case '~': md_analyze_tilde(ctx, i); break; + case '$': md_analyze_dollar(ctx, i); break; + case '.': /* Pass through. */ + case ':': /* Pass through. */ + case '@': md_analyze_permissive_autolink(ctx, i); break; + } + + if(mark->flags & MD_MARK_RESOLVED) { + if(mark->flags & MD_MARK_OPENER) + last_end = ctx->marks[mark->next].end; + else + last_end = mark->end; + } + + i++; + } +} + +/* Analyze marks (build ctx->marks). */ +static int +md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int table_mode) +{ + int ret; + + /* Reset the previously collected stack of marks. */ + ctx->n_marks = 0; + + /* Collect all marks. */ + MD_CHECK(md_collect_marks(ctx, lines, n_lines, table_mode)); + + /* (1) Links. */ + md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("[]!"), 0); + MD_CHECK(md_resolve_links(ctx, lines, n_lines)); + BRACKET_OPENERS.top = -1; + ctx->unresolved_link_head = -1; + ctx->unresolved_link_tail = -1; + + if(table_mode) { + /* (2) Analyze table cell boundaries. */ + MD_ASSERT(n_lines == 1); + ctx->n_table_cell_boundaries = 0; + md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("|"), 0); + return ret; + } + + /* (3) Emphasis and strong emphasis; permissive autolinks. */ + md_analyze_link_contents(ctx, lines, n_lines, 0, ctx->n_marks); + +abort: + return ret; +} + +static void +md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, + int mark_beg, int mark_end) +{ + int i; + + md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("&"), 0); + md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("*_~$"), 0); + + if((ctx->parser.flags & MD_FLAG_PERMISSIVEAUTOLINKS) != 0) { + /* These have to be processed last, as they may be greedy and expand + * from their original mark. Also their implementation must be careful + * not to cross any (previously) resolved marks when doing so. */ + md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("@:."), MD_ANALYZE_NOSKIP_EMPH); + } + + for(i = 0; i < (int) SIZEOF_ARRAY(ctx->opener_stacks); i++) + ctx->opener_stacks[i].top = -1; +} + +static int +md_enter_leave_span_a(MD_CTX* ctx, int enter, MD_SPANTYPE type, + const CHAR* dest, SZ dest_size, int is_autolink, + const CHAR* title, SZ title_size) +{ + MD_ATTRIBUTE_BUILD href_build = { 0 }; + MD_ATTRIBUTE_BUILD title_build = { 0 }; + MD_SPAN_A_DETAIL det; + int ret = 0; + + /* Note we here rely on fact that MD_SPAN_A_DETAIL and + * MD_SPAN_IMG_DETAIL are binary-compatible. */ + memset(&det, 0, sizeof(MD_SPAN_A_DETAIL)); + MD_CHECK(md_build_attribute(ctx, dest, dest_size, + (is_autolink ? MD_BUILD_ATTR_NO_ESCAPES : 0), + &det.href, &href_build)); + MD_CHECK(md_build_attribute(ctx, title, title_size, 0, &det.title, &title_build)); + det.is_autolink = is_autolink; + if(enter) + MD_ENTER_SPAN(type, &det); + else + MD_LEAVE_SPAN(type, &det); + +abort: + md_free_attribute(ctx, &href_build); + md_free_attribute(ctx, &title_build); + return ret; +} + +static int +md_enter_leave_span_wikilink(MD_CTX* ctx, int enter, const CHAR* target, SZ target_size) +{ + MD_ATTRIBUTE_BUILD target_build = { 0 }; + MD_SPAN_WIKILINK_DETAIL det; + int ret = 0; + + memset(&det, 0, sizeof(MD_SPAN_WIKILINK_DETAIL)); + MD_CHECK(md_build_attribute(ctx, target, target_size, 0, &det.target, &target_build)); + + if (enter) + MD_ENTER_SPAN(MD_SPAN_WIKILINK, &det); + else + MD_LEAVE_SPAN(MD_SPAN_WIKILINK, &det); + +abort: + md_free_attribute(ctx, &target_build); + return ret; +} + + +/* Render the output, accordingly to the analyzed ctx->marks. */ +static int +md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) +{ + MD_TEXTTYPE text_type; + const MD_LINE* line = lines; + MD_MARK* prev_mark = NULL; + MD_MARK* mark; + OFF off = lines[0].beg; + OFF end = lines[n_lines-1].end; + OFF tmp; + int enforce_hardbreak = 0; + int ret = 0; + + /* Find first resolved mark. Note there is always at least one resolved + * mark, the dummy last one after the end of the latest line we actually + * never really reach. This saves us of a lot of special checks and cases + * in this function. */ + mark = ctx->marks; + while(!(mark->flags & MD_MARK_RESOLVED)) + mark++; + + text_type = MD_TEXT_NORMAL; + + while(1) { + /* Process the text up to the next mark or end-of-line. */ + tmp = (line->end < mark->beg ? line->end : mark->beg); + if(tmp > off) { + MD_TEXT(text_type, STR(off), tmp - off); + off = tmp; + } + + /* If reached the mark, process it and move to next one. */ + if(off >= mark->beg) { + switch(mark->ch) { + case '\\': /* Backslash escape. */ + if(ISNEWLINE(mark->beg+1)) + enforce_hardbreak = 1; + else + MD_TEXT(text_type, STR(mark->beg+1), 1); + break; + + case ' ': /* Non-trivial space. */ + MD_TEXT(text_type, _T(" "), 1); + break; + + case '`': /* Code span. */ + if(mark->flags & MD_MARK_OPENER) { + MD_ENTER_SPAN(MD_SPAN_CODE, NULL); + text_type = MD_TEXT_CODE; + } else { + MD_LEAVE_SPAN(MD_SPAN_CODE, NULL); + text_type = MD_TEXT_NORMAL; + } + break; + + case '_': /* Underline (or emphasis if we fall through). */ + if(ctx->parser.flags & MD_FLAG_UNDERLINE) { + if(mark->flags & MD_MARK_OPENER) { + while(off < mark->end) { + MD_ENTER_SPAN(MD_SPAN_U, NULL); + off++; + } + } else { + while(off < mark->end) { + MD_LEAVE_SPAN(MD_SPAN_U, NULL); + off++; + } + } + break; + } + MD_FALLTHROUGH(); + + case '*': /* Emphasis, strong emphasis. */ + if(mark->flags & MD_MARK_OPENER) { + if((mark->end - off) % 2) { + MD_ENTER_SPAN(MD_SPAN_EM, NULL); + off++; + } + while(off + 1 < mark->end) { + MD_ENTER_SPAN(MD_SPAN_STRONG, NULL); + off += 2; + } + } else { + while(off + 1 < mark->end) { + MD_LEAVE_SPAN(MD_SPAN_STRONG, NULL); + off += 2; + } + if((mark->end - off) % 2) { + MD_LEAVE_SPAN(MD_SPAN_EM, NULL); + off++; + } + } + break; + + case '~': + if(mark->flags & MD_MARK_OPENER) + MD_ENTER_SPAN(MD_SPAN_DEL, NULL); + else + MD_LEAVE_SPAN(MD_SPAN_DEL, NULL); + break; + + case '$': + if(mark->flags & MD_MARK_OPENER) { + MD_ENTER_SPAN((mark->end - off) % 2 ? MD_SPAN_LATEXMATH : MD_SPAN_LATEXMATH_DISPLAY, NULL); + text_type = MD_TEXT_LATEXMATH; + } else { + MD_LEAVE_SPAN((mark->end - off) % 2 ? MD_SPAN_LATEXMATH : MD_SPAN_LATEXMATH_DISPLAY, NULL); + text_type = MD_TEXT_NORMAL; + } + break; + + case '[': /* Link, wiki link, image. */ + case '!': + case ']': + { + const MD_MARK* opener = (mark->ch != ']' ? mark : &ctx->marks[mark->prev]); + const MD_MARK* closer = &ctx->marks[opener->next]; + const MD_MARK* dest_mark; + const MD_MARK* title_mark; + + if ((opener->ch == '[' && closer->ch == ']') && + opener->end - opener->beg >= 2 && + closer->end - closer->beg >= 2) + { + int has_label = (opener->end - opener->beg > 2); + SZ target_sz; + + if(has_label) + target_sz = opener->end - (opener->beg+2); + else + target_sz = closer->beg - opener->end; + + MD_CHECK(md_enter_leave_span_wikilink(ctx, (mark->ch != ']'), + has_label ? STR(opener->beg+2) : STR(opener->end), + target_sz)); + + break; + } + + dest_mark = opener+1; + MD_ASSERT(dest_mark->ch == 'D'); + title_mark = opener+2; + MD_ASSERT(title_mark->ch == 'D'); + + MD_CHECK(md_enter_leave_span_a(ctx, (mark->ch != ']'), + (opener->ch == '!' ? MD_SPAN_IMG : MD_SPAN_A), + STR(dest_mark->beg), dest_mark->end - dest_mark->beg, FALSE, + md_mark_get_ptr(ctx, (int)(title_mark - ctx->marks)), + title_mark->prev)); + + /* link/image closer may span multiple lines. */ + if(mark->ch == ']') { + while(mark->end > line->end) + line++; + } + + break; + } + + case '<': + case '>': /* Autolink or raw HTML. */ + if(!(mark->flags & MD_MARK_AUTOLINK)) { + /* Raw HTML. */ + if(mark->flags & MD_MARK_OPENER) + text_type = MD_TEXT_HTML; + else + text_type = MD_TEXT_NORMAL; + break; + } + /* Pass through, if auto-link. */ + MD_FALLTHROUGH(); + + case '@': /* Permissive e-mail autolink. */ + case ':': /* Permissive URL autolink. */ + case '.': /* Permissive WWW autolink. */ + { + MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]); + MD_MARK* closer = &ctx->marks[opener->next]; + const CHAR* dest = STR(opener->end); + SZ dest_size = closer->beg - opener->end; + + /* For permissive auto-links we do not know closer mark + * position at the time of md_collect_marks(), therefore + * it can be out-of-order in ctx->marks[]. + * + * With this flag, we make sure that we output the closer + * only if we processed the opener. */ + if(mark->flags & MD_MARK_OPENER) + closer->flags |= MD_MARK_VALIDPERMISSIVEAUTOLINK; + + if(opener->ch == '@' || opener->ch == '.' || + (opener->ch == '<' && (opener->flags & MD_MARK_AUTOLINK_MISSING_MAILTO))) + { + dest_size += 7; + MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); + memcpy(ctx->buffer, + (opener->ch == '.' ? _T("http://") : _T("mailto:")), + 7 * sizeof(CHAR)); + memcpy(ctx->buffer + 7, dest, (dest_size-7) * sizeof(CHAR)); + dest = ctx->buffer; + } + + if(closer->flags & MD_MARK_VALIDPERMISSIVEAUTOLINK) + MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER), + MD_SPAN_A, dest, dest_size, TRUE, NULL, 0)); + break; + } + + case '&': /* Entity. */ + MD_TEXT(MD_TEXT_ENTITY, STR(mark->beg), mark->end - mark->beg); + break; + + case '\0': + MD_TEXT(MD_TEXT_NULLCHAR, _T(""), 1); + break; + + case 127: + goto abort; + } + + off = mark->end; + + /* Move to next resolved mark. */ + prev_mark = mark; + mark++; + while(!(mark->flags & MD_MARK_RESOLVED) || mark->beg < off) + mark++; + } + + /* If reached end of line, move to next one. */ + if(off >= line->end) { + /* If it is the last line, we are done. */ + if(off >= end) + break; + + if(text_type == MD_TEXT_CODE || text_type == MD_TEXT_LATEXMATH) { + MD_ASSERT(prev_mark != NULL); + MD_ASSERT(ISANYOF2_(prev_mark->ch, '`', '$') && (prev_mark->flags & MD_MARK_OPENER)); + MD_ASSERT(ISANYOF2_(mark->ch, '`', '$') && (mark->flags & MD_MARK_CLOSER)); + + /* Inside a code span, trailing line whitespace has to be + * outputted. */ + tmp = off; + while(off < ctx->size && ISBLANK(off)) + off++; + if(off > tmp) + MD_TEXT(text_type, STR(tmp), off-tmp); + + /* and new lines are transformed into single spaces. */ + if(off == line->end) + MD_TEXT(text_type, _T(" "), 1); + } else if(text_type == MD_TEXT_HTML) { + /* Inside raw HTML, we output the new line verbatim, including + * any trailing spaces. */ + tmp = off; + while(tmp < end && ISBLANK(tmp)) + tmp++; + if(tmp > off) + MD_TEXT(MD_TEXT_HTML, STR(off), tmp - off); + MD_TEXT(MD_TEXT_HTML, _T("\n"), 1); + } else { + /* Output soft or hard line break. */ + MD_TEXTTYPE break_type = MD_TEXT_SOFTBR; + + if(text_type == MD_TEXT_NORMAL) { + if(enforce_hardbreak || (ctx->parser.flags & MD_FLAG_HARD_SOFT_BREAKS)) { + break_type = MD_TEXT_BR; + } else { + while(off < ctx->size && ISBLANK(off)) + off++; + if(off >= line->end + 2 && CH(off-2) == _T(' ') && CH(off-1) == _T(' ') && ISNEWLINE(off)) + break_type = MD_TEXT_BR; + } + } + + MD_TEXT(break_type, _T("\n"), 1); + } + + /* Move to the next line. */ + line++; + off = line->beg; + + enforce_hardbreak = 0; + } + } + +abort: + return ret; +} + + +/*************************** + *** Processing Tables *** + ***************************/ + +static void +md_analyze_table_alignment(MD_CTX* ctx, OFF beg, OFF end, MD_ALIGN* align, int n_align) +{ + static const MD_ALIGN align_map[] = { MD_ALIGN_DEFAULT, MD_ALIGN_LEFT, MD_ALIGN_RIGHT, MD_ALIGN_CENTER }; + OFF off = beg; + + while(n_align > 0) { + int index = 0; /* index into align_map[] */ + + while(CH(off) != _T('-')) + off++; + if(off > beg && CH(off-1) == _T(':')) + index |= 1; + while(off < end && CH(off) == _T('-')) + off++; + if(off < end && CH(off) == _T(':')) + index |= 2; + + *align = align_map[index]; + align++; + n_align--; + } + +} + +/* Forward declaration. */ +static int md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines); + +static int +md_process_table_cell(MD_CTX* ctx, MD_BLOCKTYPE cell_type, MD_ALIGN align, OFF beg, OFF end) +{ + MD_LINE line; + MD_BLOCK_TD_DETAIL det; + int ret = 0; + + while(beg < end && ISWHITESPACE(beg)) + beg++; + while(end > beg && ISWHITESPACE(end-1)) + end--; + + det.align = align; + line.beg = beg; + line.end = end; + + MD_ENTER_BLOCK(cell_type, &det); + MD_CHECK(md_process_normal_block_contents(ctx, &line, 1)); + MD_LEAVE_BLOCK(cell_type, &det); + +abort: + return ret; +} + +static int +md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end, + const MD_ALIGN* align, int col_count) +{ + MD_LINE line; + OFF* pipe_offs = NULL; + int i, j, k, n; + int ret = 0; + + line.beg = beg; + line.end = end; + + /* Break the line into table cells by identifying pipe characters who + * form the cell boundary. */ + MD_CHECK(md_analyze_inlines(ctx, &line, 1, TRUE)); + + /* We have to remember the cell boundaries in local buffer because + * ctx->marks[] shall be reused during cell contents processing. */ + n = ctx->n_table_cell_boundaries + 2; + pipe_offs = (OFF*) malloc(n * sizeof(OFF)); + if(pipe_offs == NULL) { + MD_LOG("malloc() failed."); + ret = -1; + goto abort; + } + j = 0; + pipe_offs[j++] = beg; + for(i = ctx->table_cell_boundaries_head; i >= 0; i = ctx->marks[i].next) { + MD_MARK* mark = &ctx->marks[i]; + pipe_offs[j++] = mark->end; + } + pipe_offs[j++] = end+1; + + /* Process cells. */ + MD_ENTER_BLOCK(MD_BLOCK_TR, NULL); + k = 0; + for(i = 0; i < j-1 && k < col_count; i++) { + if(pipe_offs[i] < pipe_offs[i+1]-1) + MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], pipe_offs[i], pipe_offs[i+1]-1)); + } + /* Make sure we call enough table cells even if the current table contains + * too few of them. */ + while(k < col_count) + MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], 0, 0)); + MD_LEAVE_BLOCK(MD_BLOCK_TR, NULL); + +abort: + free(pipe_offs); + + ctx->table_cell_boundaries_head = -1; + ctx->table_cell_boundaries_tail = -1; + + return ret; +} + +static int +md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines, MD_SIZE n_lines) +{ + MD_ALIGN* align; + MD_SIZE line_index; + int ret = 0; + + /* At least two lines have to be present: The column headers and the line + * with the underlines. */ + MD_ASSERT(n_lines >= 2); + + align = malloc(col_count * sizeof(MD_ALIGN)); + if(align == NULL) { + MD_LOG("malloc() failed."); + ret = -1; + goto abort; + } + + md_analyze_table_alignment(ctx, lines[1].beg, lines[1].end, align, col_count); + + MD_ENTER_BLOCK(MD_BLOCK_THEAD, NULL); + MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TH, + lines[0].beg, lines[0].end, align, col_count)); + MD_LEAVE_BLOCK(MD_BLOCK_THEAD, NULL); + + if(n_lines > 2) { + MD_ENTER_BLOCK(MD_BLOCK_TBODY, NULL); + for(line_index = 2; line_index < n_lines; line_index++) { + MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TD, + lines[line_index].beg, lines[line_index].end, align, col_count)); + } + MD_LEAVE_BLOCK(MD_BLOCK_TBODY, NULL); + } + +abort: + free(align); + return ret; +} + + +/************************** + *** Processing Block *** + **************************/ + +#define MD_BLOCK_CONTAINER_OPENER 0x01 +#define MD_BLOCK_CONTAINER_CLOSER 0x02 +#define MD_BLOCK_CONTAINER (MD_BLOCK_CONTAINER_OPENER | MD_BLOCK_CONTAINER_CLOSER) +#define MD_BLOCK_LOOSE_LIST 0x04 +#define MD_BLOCK_SETEXT_HEADER 0x08 + +struct MD_BLOCK_tag { + MD_BLOCKTYPE type : 8; + unsigned flags : 8; + + /* MD_BLOCK_H: Header level (1 - 6) + * MD_BLOCK_CODE: Non-zero if fenced, zero if indented. + * MD_BLOCK_LI: Task mark character (0 if not task list item, 'x', 'X' or ' '). + * MD_BLOCK_TABLE: Column count (as determined by the table underline). + */ + unsigned data : 16; + + /* Leaf blocks: Count of lines (MD_LINE or MD_VERBATIMLINE) on the block. + * MD_BLOCK_LI: Task mark offset in the input doc. + * MD_BLOCK_OL: Start item number. + */ + MD_SIZE n_lines; +}; + +struct MD_CONTAINER_tag { + CHAR ch; + unsigned is_loose : 8; + unsigned is_task : 8; + unsigned start; + unsigned mark_indent; + unsigned contents_indent; + OFF block_byte_off; + OFF task_mark_off; +}; + + +static int +md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) +{ + int i; + int ret; + + MD_CHECK(md_analyze_inlines(ctx, lines, n_lines, FALSE)); + MD_CHECK(md_process_inlines(ctx, lines, n_lines)); + +abort: + /* Free any temporary memory blocks stored within some dummy marks. */ + for(i = ctx->ptr_stack.top; i >= 0; i = ctx->marks[i].next) + free(md_mark_get_ptr(ctx, i)); + ctx->ptr_stack.top = -1; + + return ret; +} + +static int +md_process_verbatim_block_contents(MD_CTX* ctx, MD_TEXTTYPE text_type, const MD_VERBATIMLINE* lines, MD_SIZE n_lines) +{ + static const CHAR indent_chunk_str[] = _T(" "); + static const SZ indent_chunk_size = SIZEOF_ARRAY(indent_chunk_str) - 1; + + MD_SIZE line_index; + int ret = 0; + + for(line_index = 0; line_index < n_lines; line_index++) { + const MD_VERBATIMLINE* line = &lines[line_index]; + int indent = line->indent; + + MD_ASSERT(indent >= 0); + + /* Output code indentation. */ + while(indent > (int) indent_chunk_size) { + MD_TEXT(text_type, indent_chunk_str, indent_chunk_size); + indent -= indent_chunk_size; + } + if(indent > 0) + MD_TEXT(text_type, indent_chunk_str, indent); + + /* Output the code line itself. */ + MD_TEXT_INSECURE(text_type, STR(line->beg), line->end - line->beg); + + /* Enforce end-of-line. */ + MD_TEXT(text_type, _T("\n"), 1); + } + +abort: + return ret; +} + +static int +md_process_code_block_contents(MD_CTX* ctx, int is_fenced, const MD_VERBATIMLINE* lines, MD_SIZE n_lines) +{ + if(is_fenced) { + /* Skip the first line in case of fenced code: It is the fence. + * (Only the starting fence is present due to logic in md_analyze_line().) */ + lines++; + n_lines--; + } else { + /* Ignore blank lines at start/end of indented code block. */ + while(n_lines > 0 && lines[0].beg == lines[0].end) { + lines++; + n_lines--; + } + while(n_lines > 0 && lines[n_lines-1].beg == lines[n_lines-1].end) { + n_lines--; + } + } + + if(n_lines == 0) + return 0; + + return md_process_verbatim_block_contents(ctx, MD_TEXT_CODE, lines, n_lines); +} + +static int +md_setup_fenced_code_detail(MD_CTX* ctx, const MD_BLOCK* block, MD_BLOCK_CODE_DETAIL* det, + MD_ATTRIBUTE_BUILD* info_build, MD_ATTRIBUTE_BUILD* lang_build) +{ + const MD_VERBATIMLINE* fence_line = (const MD_VERBATIMLINE*)(block + 1); + OFF beg = fence_line->beg; + OFF end = fence_line->end; + OFF lang_end; + CHAR fence_ch = CH(fence_line->beg); + int ret = 0; + + /* Skip the fence itself. */ + while(beg < ctx->size && CH(beg) == fence_ch) + beg++; + /* Trim initial spaces. */ + while(beg < ctx->size && CH(beg) == _T(' ')) + beg++; + + /* Trim trailing spaces. */ + while(end > beg && CH(end-1) == _T(' ')) + end--; + + /* Build info string attribute. */ + MD_CHECK(md_build_attribute(ctx, STR(beg), end - beg, 0, &det->info, info_build)); + + /* Build info string attribute. */ + lang_end = beg; + while(lang_end < end && !ISWHITESPACE(lang_end)) + lang_end++; + MD_CHECK(md_build_attribute(ctx, STR(beg), lang_end - beg, 0, &det->lang, lang_build)); + + det->fence_char = fence_ch; + +abort: + return ret; +} + +static int +md_process_leaf_block(MD_CTX* ctx, const MD_BLOCK* block) +{ + union { + MD_BLOCK_H_DETAIL header; + MD_BLOCK_CODE_DETAIL code; + MD_BLOCK_TABLE_DETAIL table; + } det; + MD_ATTRIBUTE_BUILD info_build; + MD_ATTRIBUTE_BUILD lang_build; + int is_in_tight_list; + int clean_fence_code_detail = FALSE; + int ret = 0; + + memset(&det, 0, sizeof(det)); + + if(ctx->n_containers == 0) + is_in_tight_list = FALSE; + else + is_in_tight_list = !ctx->containers[ctx->n_containers-1].is_loose; + + switch(block->type) { + case MD_BLOCK_H: + det.header.level = block->data; + break; + + case MD_BLOCK_CODE: + /* For fenced code block, we may need to set the info string. */ + if(block->data != 0) { + memset(&det.code, 0, sizeof(MD_BLOCK_CODE_DETAIL)); + clean_fence_code_detail = TRUE; + MD_CHECK(md_setup_fenced_code_detail(ctx, block, &det.code, &info_build, &lang_build)); + } + break; + + case MD_BLOCK_TABLE: + det.table.col_count = block->data; + det.table.head_row_count = 1; + det.table.body_row_count = block->n_lines - 2; + break; + + default: + /* Noop. */ + break; + } + + if(!is_in_tight_list || block->type != MD_BLOCK_P) + MD_ENTER_BLOCK(block->type, (void*) &det); + + /* Process the block contents accordingly to is type. */ + switch(block->type) { + case MD_BLOCK_HR: + /* noop */ + break; + + case MD_BLOCK_CODE: + MD_CHECK(md_process_code_block_contents(ctx, (block->data != 0), + (const MD_VERBATIMLINE*)(block + 1), block->n_lines)); + break; + + case MD_BLOCK_HTML: + MD_CHECK(md_process_verbatim_block_contents(ctx, MD_TEXT_HTML, + (const MD_VERBATIMLINE*)(block + 1), block->n_lines)); + break; + + case MD_BLOCK_TABLE: + MD_CHECK(md_process_table_block_contents(ctx, block->data, + (const MD_LINE*)(block + 1), block->n_lines)); + break; + + default: + MD_CHECK(md_process_normal_block_contents(ctx, + (const MD_LINE*)(block + 1), block->n_lines)); + break; + } + + if(!is_in_tight_list || block->type != MD_BLOCK_P) + MD_LEAVE_BLOCK(block->type, (void*) &det); + +abort: + if(clean_fence_code_detail) { + md_free_attribute(ctx, &info_build); + md_free_attribute(ctx, &lang_build); + } + return ret; +} + +static int +md_process_all_blocks(MD_CTX* ctx) +{ + int byte_off = 0; + int ret = 0; + + /* ctx->containers now is not needed for detection of lists and list items + * so we reuse it for tracking what lists are loose or tight. We rely + * on the fact the vector is large enough to hold the deepest nesting + * level of lists. */ + ctx->n_containers = 0; + + while(byte_off < ctx->n_block_bytes) { + MD_BLOCK* block = (MD_BLOCK*)((char*)ctx->block_bytes + byte_off); + union { + MD_BLOCK_UL_DETAIL ul; + MD_BLOCK_OL_DETAIL ol; + MD_BLOCK_LI_DETAIL li; + } det; + + switch(block->type) { + case MD_BLOCK_UL: + det.ul.is_tight = (block->flags & MD_BLOCK_LOOSE_LIST) ? FALSE : TRUE; + det.ul.mark = (CHAR) block->data; + break; + + case MD_BLOCK_OL: + det.ol.start = block->n_lines; + det.ol.is_tight = (block->flags & MD_BLOCK_LOOSE_LIST) ? FALSE : TRUE; + det.ol.mark_delimiter = (CHAR) block->data; + break; + + case MD_BLOCK_LI: + det.li.is_task = (block->data != 0); + det.li.task_mark = (CHAR) block->data; + det.li.task_mark_offset = (OFF) block->n_lines; + break; + + default: + /* noop */ + break; + } + + if(block->flags & MD_BLOCK_CONTAINER) { + if(block->flags & MD_BLOCK_CONTAINER_CLOSER) { + MD_LEAVE_BLOCK(block->type, &det); + + if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL || block->type == MD_BLOCK_QUOTE) + ctx->n_containers--; + } + + if(block->flags & MD_BLOCK_CONTAINER_OPENER) { + MD_ENTER_BLOCK(block->type, &det); + + if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL) { + ctx->containers[ctx->n_containers].is_loose = (block->flags & MD_BLOCK_LOOSE_LIST); + ctx->n_containers++; + } else if(block->type == MD_BLOCK_QUOTE) { + /* This causes that any text in a block quote, even if + * nested inside a tight list item, is wrapped with + *

...

. */ + ctx->containers[ctx->n_containers].is_loose = TRUE; + ctx->n_containers++; + } + } + } else { + MD_CHECK(md_process_leaf_block(ctx, block)); + + if(block->type == MD_BLOCK_CODE || block->type == MD_BLOCK_HTML) + byte_off += block->n_lines * sizeof(MD_VERBATIMLINE); + else + byte_off += block->n_lines * sizeof(MD_LINE); + } + + byte_off += sizeof(MD_BLOCK); + } + + ctx->n_block_bytes = 0; + +abort: + return ret; +} + + +/************************************ + *** Grouping Lines into Blocks *** + ************************************/ + +static void* +md_push_block_bytes(MD_CTX* ctx, int n_bytes) +{ + void* ptr; + + if(ctx->n_block_bytes + n_bytes > ctx->alloc_block_bytes) { + void* new_block_bytes; + + ctx->alloc_block_bytes = (ctx->alloc_block_bytes > 0 + ? ctx->alloc_block_bytes + ctx->alloc_block_bytes / 2 + : 512); + new_block_bytes = realloc(ctx->block_bytes, ctx->alloc_block_bytes); + if(new_block_bytes == NULL) { + MD_LOG("realloc() failed."); + return NULL; + } + + /* Fix the ->current_block after the reallocation. */ + if(ctx->current_block != NULL) { + OFF off_current_block = (OFF) ((char*) ctx->current_block - (char*) ctx->block_bytes); + ctx->current_block = (MD_BLOCK*) ((char*) new_block_bytes + off_current_block); + } + + ctx->block_bytes = new_block_bytes; + } + + ptr = (char*)ctx->block_bytes + ctx->n_block_bytes; + ctx->n_block_bytes += n_bytes; + return ptr; +} + +static int +md_start_new_block(MD_CTX* ctx, const MD_LINE_ANALYSIS* line) +{ + MD_BLOCK* block; + + MD_ASSERT(ctx->current_block == NULL); + + block = (MD_BLOCK*) md_push_block_bytes(ctx, sizeof(MD_BLOCK)); + if(block == NULL) + return -1; + + switch(line->type) { + case MD_LINE_HR: + block->type = MD_BLOCK_HR; + break; + + case MD_LINE_ATXHEADER: + case MD_LINE_SETEXTHEADER: + block->type = MD_BLOCK_H; + break; + + case MD_LINE_FENCEDCODE: + case MD_LINE_INDENTEDCODE: + block->type = MD_BLOCK_CODE; + break; + + case MD_LINE_TEXT: + block->type = MD_BLOCK_P; + break; + + case MD_LINE_HTML: + block->type = MD_BLOCK_HTML; + break; + + case MD_LINE_BLANK: + case MD_LINE_SETEXTUNDERLINE: + case MD_LINE_TABLEUNDERLINE: + default: + MD_UNREACHABLE(); + break; + } + + block->flags = 0; + block->data = line->data; + block->n_lines = 0; + + ctx->current_block = block; + return 0; +} + +/* Eat from start of current (textual) block any reference definitions and + * remember them so we can resolve any links referring to them. + * + * (Reference definitions can only be at start of it as they cannot break + * a paragraph.) + */ +static int +md_consume_link_reference_definitions(MD_CTX* ctx) +{ + MD_LINE* lines = (MD_LINE*) (ctx->current_block + 1); + MD_SIZE n_lines = ctx->current_block->n_lines; + MD_SIZE n = 0; + + /* Compute how many lines at the start of the block form one or more + * reference definitions. */ + while(n < n_lines) { + int n_link_ref_lines; + + n_link_ref_lines = md_is_link_reference_definition(ctx, + lines + n, n_lines - n); + /* Not a reference definition? */ + if(n_link_ref_lines == 0) + break; + + /* We fail if it is the ref. def. but it could not be stored due + * a memory allocation error. */ + if(n_link_ref_lines < 0) + return -1; + + n += n_link_ref_lines; + } + + /* If there was at least one reference definition, we need to remove + * its lines from the block, or perhaps even the whole block. */ + if(n > 0) { + if(n == n_lines) { + /* Remove complete block. */ + ctx->n_block_bytes -= n * sizeof(MD_LINE); + ctx->n_block_bytes -= sizeof(MD_BLOCK); + ctx->current_block = NULL; + } else { + /* Remove just some initial lines from the block. */ + memmove(lines, lines + n, (n_lines - n) * sizeof(MD_LINE)); + ctx->current_block->n_lines -= n; + ctx->n_block_bytes -= n * sizeof(MD_LINE); + } + } + + return 0; +} + +static int +md_end_current_block(MD_CTX* ctx) +{ + int ret = 0; + + if(ctx->current_block == NULL) + return ret; + + /* Check whether there is a reference definition. (We do this here instead + * of in md_analyze_line() because reference definition can take multiple + * lines.) */ + if(ctx->current_block->type == MD_BLOCK_P || + (ctx->current_block->type == MD_BLOCK_H && (ctx->current_block->flags & MD_BLOCK_SETEXT_HEADER))) + { + MD_LINE* lines = (MD_LINE*) (ctx->current_block + 1); + if(lines[0].beg < ctx->size && CH(lines[0].beg) == _T('[')) { + MD_CHECK(md_consume_link_reference_definitions(ctx)); + if(ctx->current_block == NULL) + return ret; + } + } + + if(ctx->current_block->type == MD_BLOCK_H && (ctx->current_block->flags & MD_BLOCK_SETEXT_HEADER)) { + MD_SIZE n_lines = ctx->current_block->n_lines; + + if(n_lines > 1) { + /* Get rid of the underline. */ + ctx->current_block->n_lines--; + ctx->n_block_bytes -= sizeof(MD_LINE); + } else { + /* Only the underline has left after eating the ref. defs. + * Keep the line as beginning of a new ordinary paragraph. */ + ctx->current_block->type = MD_BLOCK_P; + return 0; + } + } + + /* Mark we are not building any block anymore. */ + ctx->current_block = NULL; + +abort: + return ret; +} + +static int +md_add_line_into_current_block(MD_CTX* ctx, const MD_LINE_ANALYSIS* analysis) +{ + MD_ASSERT(ctx->current_block != NULL); + + if(ctx->current_block->type == MD_BLOCK_CODE || ctx->current_block->type == MD_BLOCK_HTML) { + MD_VERBATIMLINE* line; + + line = (MD_VERBATIMLINE*) md_push_block_bytes(ctx, sizeof(MD_VERBATIMLINE)); + if(line == NULL) + return -1; + + line->indent = analysis->indent; + line->beg = analysis->beg; + line->end = analysis->end; + } else { + MD_LINE* line; + + line = (MD_LINE*) md_push_block_bytes(ctx, sizeof(MD_LINE)); + if(line == NULL) + return -1; + + line->beg = analysis->beg; + line->end = analysis->end; + } + ctx->current_block->n_lines++; + + return 0; +} + +static int +md_push_container_bytes(MD_CTX* ctx, MD_BLOCKTYPE type, unsigned start, + unsigned data, unsigned flags) +{ + MD_BLOCK* block; + int ret = 0; + + MD_CHECK(md_end_current_block(ctx)); + + block = (MD_BLOCK*) md_push_block_bytes(ctx, sizeof(MD_BLOCK)); + if(block == NULL) + return -1; + + block->type = type; + block->flags = flags; + block->data = data; + block->n_lines = start; + +abort: + return ret; +} + + + +/*********************** + *** Line Analysis *** + ***********************/ + +static int +md_is_hr_line(MD_CTX* ctx, OFF beg, OFF* p_end, OFF* p_killer) +{ + OFF off = beg + 1; + int n = 1; + + while(off < ctx->size && (CH(off) == CH(beg) || CH(off) == _T(' ') || CH(off) == _T('\t'))) { + if(CH(off) == CH(beg)) + n++; + off++; + } + + if(n < 3) { + *p_killer = off; + return FALSE; + } + + /* Nothing else can be present on the line. */ + if(off < ctx->size && !ISNEWLINE(off)) { + *p_killer = off; + return FALSE; + } + + *p_end = off; + return TRUE; +} + +static int +md_is_atxheader_line(MD_CTX* ctx, OFF beg, OFF* p_beg, OFF* p_end, unsigned* p_level) +{ + int n; + OFF off = beg + 1; + + while(off < ctx->size && CH(off) == _T('#') && off - beg < 7) + off++; + n = off - beg; + + if(n > 6) + return FALSE; + *p_level = n; + + if(!(ctx->parser.flags & MD_FLAG_PERMISSIVEATXHEADERS) && off < ctx->size && + !ISBLANK(off) && !ISNEWLINE(off)) + return FALSE; + + while(off < ctx->size && ISBLANK(off)) + off++; + *p_beg = off; + *p_end = off; + return TRUE; +} + +static int +md_is_setext_underline(MD_CTX* ctx, OFF beg, OFF* p_end, unsigned* p_level) +{ + OFF off = beg + 1; + + while(off < ctx->size && CH(off) == CH(beg)) + off++; + + /* Optionally, space(s) or tabs can follow. */ + while(off < ctx->size && ISBLANK(off)) + off++; + + /* But nothing more is allowed on the line. */ + if(off < ctx->size && !ISNEWLINE(off)) + return FALSE; + + *p_level = (CH(beg) == _T('=') ? 1 : 2); + *p_end = off; + return TRUE; +} + +static int +md_is_table_underline(MD_CTX* ctx, OFF beg, OFF* p_end, unsigned* p_col_count) +{ + OFF off = beg; + int found_pipe = FALSE; + unsigned col_count = 0; + + if(off < ctx->size && CH(off) == _T('|')) { + found_pipe = TRUE; + off++; + while(off < ctx->size && ISWHITESPACE(off)) + off++; + } + + while(1) { + int delimited = FALSE; + + /* Cell underline ("-----", ":----", "----:" or ":----:") */ + if(off < ctx->size && CH(off) == _T(':')) + off++; + if(off >= ctx->size || CH(off) != _T('-')) + return FALSE; + while(off < ctx->size && CH(off) == _T('-')) + off++; + if(off < ctx->size && CH(off) == _T(':')) + off++; + + col_count++; + if(col_count > TABLE_MAXCOLCOUNT) { + MD_LOG("Suppressing table (column_count >" STRINGIZE(TABLE_MAXCOLCOUNT) ")"); + return FALSE; + } + + /* Pipe delimiter (optional at the end of line). */ + while(off < ctx->size && ISWHITESPACE(off)) + off++; + if(off < ctx->size && CH(off) == _T('|')) { + delimited = TRUE; + found_pipe = TRUE; + off++; + while(off < ctx->size && ISWHITESPACE(off)) + off++; + } + + /* Success, if we reach end of line. */ + if(off >= ctx->size || ISNEWLINE(off)) + break; + + if(!delimited) + return FALSE; + } + + if(!found_pipe) + return FALSE; + + *p_end = off; + *p_col_count = col_count; + return TRUE; +} + +static int +md_is_opening_code_fence(MD_CTX* ctx, OFF beg, OFF* p_end) +{ + OFF off = beg; + + while(off < ctx->size && CH(off) == CH(beg)) + off++; + + /* Fence must have at least three characters. */ + if(off - beg < 3) + return FALSE; + + ctx->code_fence_length = off - beg; + + /* Optionally, space(s) can follow. */ + while(off < ctx->size && CH(off) == _T(' ')) + off++; + + /* Optionally, an info string can follow. */ + while(off < ctx->size && !ISNEWLINE(off)) { + /* Backtick-based fence must not contain '`' in the info string. */ + if(CH(beg) == _T('`') && CH(off) == _T('`')) + return FALSE; + off++; + } + + *p_end = off; + return TRUE; +} + +static int +md_is_closing_code_fence(MD_CTX* ctx, CHAR ch, OFF beg, OFF* p_end) +{ + OFF off = beg; + int ret = FALSE; + + /* Closing fence must have at least the same length and use same char as + * opening one. */ + while(off < ctx->size && CH(off) == ch) + off++; + if(off - beg < ctx->code_fence_length) + goto out; + + /* Optionally, space(s) can follow */ + while(off < ctx->size && CH(off) == _T(' ')) + off++; + + /* But nothing more is allowed on the line. */ + if(off < ctx->size && !ISNEWLINE(off)) + goto out; + + ret = TRUE; + +out: + /* Note we set *p_end even on failure: If we are not closing fence, caller + * would eat the line anyway without any parsing. */ + *p_end = off; + return ret; +} + + +/* Helper data for md_is_html_block_start_condition() and + * md_is_html_block_end_condition() */ +typedef struct TAG_tag TAG; +struct TAG_tag { + const CHAR* name; + unsigned len : 8; +}; + +#ifdef X + #undef X +#endif +#define X(name) { _T(name), (sizeof(name)-1) / sizeof(CHAR) } +#define Xend { NULL, 0 } + +static const TAG t1[] = { X("pre"), X("script"), X("style"), X("textarea"), Xend }; + +static const TAG a6[] = { X("address"), X("article"), X("aside"), Xend }; +static const TAG b6[] = { X("base"), X("basefont"), X("blockquote"), X("body"), Xend }; +static const TAG c6[] = { X("caption"), X("center"), X("col"), X("colgroup"), Xend }; +static const TAG d6[] = { X("dd"), X("details"), X("dialog"), X("dir"), + X("div"), X("dl"), X("dt"), Xend }; +static const TAG f6[] = { X("fieldset"), X("figcaption"), X("figure"), X("footer"), + X("form"), X("frame"), X("frameset"), Xend }; +static const TAG h6[] = { X("h1"), X("h2"), X("h3"), X("h4"), X("h5"), X("h6"), + X("head"), X("header"), X("hr"), X("html"), Xend }; +static const TAG i6[] = { X("iframe"), Xend }; +static const TAG l6[] = { X("legend"), X("li"), X("link"), Xend }; +static const TAG m6[] = { X("main"), X("menu"), X("menuitem"), Xend }; +static const TAG n6[] = { X("nav"), X("noframes"), Xend }; +static const TAG o6[] = { X("ol"), X("optgroup"), X("option"), Xend }; +static const TAG p6[] = { X("p"), X("param"), Xend }; +static const TAG s6[] = { X("search"), X("section"), X("summary"), Xend }; +static const TAG t6[] = { X("table"), X("tbody"), X("td"), X("tfoot"), X("th"), + X("thead"), X("title"), X("tr"), X("track"), Xend }; +static const TAG u6[] = { X("ul"), Xend }; +static const TAG xx[] = { Xend }; + +#undef X +#undef Xend + +/* Returns type of the raw HTML block, or FALSE if it is not HTML block. + * (Refer to CommonMark specification for details about the types.) + */ +static int +md_is_html_block_start_condition(MD_CTX* ctx, OFF beg) +{ + /* Type 6 is started by a long list of allowed tags. We use two-level + * tree to speed-up the search. */ + static const TAG* map6[26] = { + a6, b6, c6, d6, xx, f6, xx, h6, i6, xx, xx, l6, m6, + n6, o6, p6, xx, xx, s6, t6, u6, xx, xx, xx, xx, xx + }; + OFF off = beg + 1; + int i; + + /* Check for type 1: size) { + if(md_ascii_case_eq(STR(off), t1[i].name, t1[i].len)) + return 1; + } + } + + /* Check for type 2: "), 3, p_end) ? 2 : FALSE); + + case 3: + return (md_line_contains(ctx, beg, _T("?>"), 2, p_end) ? 3 : FALSE); + + case 4: + return (md_line_contains(ctx, beg, _T(">"), 1, p_end) ? 4 : FALSE); + + case 5: + return (md_line_contains(ctx, beg, _T("]]>"), 3, p_end) ? 5 : FALSE); + + case 6: /* Pass through */ + case 7: + if(beg >= ctx->size || ISNEWLINE(beg)) { + /* Blank line ends types 6 and 7. */ + *p_end = beg; + return ctx->html_block_type; + } + return FALSE; + + default: + MD_UNREACHABLE(); + } + return FALSE; +} + + +static int +md_is_container_compatible(const MD_CONTAINER* pivot, const MD_CONTAINER* container) +{ + /* Block quote has no "items" like lists. */ + if(container->ch == _T('>')) + return FALSE; + + if(container->ch != pivot->ch) + return FALSE; + if(container->mark_indent > pivot->contents_indent) + return FALSE; + + return TRUE; +} + +static int +md_push_container(MD_CTX* ctx, const MD_CONTAINER* container) +{ + if(ctx->n_containers >= ctx->alloc_containers) { + MD_CONTAINER* new_containers; + + ctx->alloc_containers = (ctx->alloc_containers > 0 + ? ctx->alloc_containers + ctx->alloc_containers / 2 + : 16); + new_containers = realloc(ctx->containers, ctx->alloc_containers * sizeof(MD_CONTAINER)); + if(new_containers == NULL) { + MD_LOG("realloc() failed."); + return -1; + } + + ctx->containers = new_containers; + } + + memcpy(&ctx->containers[ctx->n_containers++], container, sizeof(MD_CONTAINER)); + return 0; +} + +static int +md_enter_child_containers(MD_CTX* ctx, int n_children) +{ + int i; + int ret = 0; + + for(i = ctx->n_containers - n_children; i < ctx->n_containers; i++) { + MD_CONTAINER* c = &ctx->containers[i]; + int is_ordered_list = FALSE; + + switch(c->ch) { + case _T(')'): + case _T('.'): + is_ordered_list = TRUE; + MD_FALLTHROUGH(); + + case _T('-'): + case _T('+'): + case _T('*'): + /* Remember offset in ctx->block_bytes so we can revisit the + * block if we detect it is a loose list. */ + md_end_current_block(ctx); + c->block_byte_off = ctx->n_block_bytes; + + MD_CHECK(md_push_container_bytes(ctx, + (is_ordered_list ? MD_BLOCK_OL : MD_BLOCK_UL), + c->start, c->ch, MD_BLOCK_CONTAINER_OPENER)); + MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, + c->task_mark_off, + (c->is_task ? CH(c->task_mark_off) : 0), + MD_BLOCK_CONTAINER_OPENER)); + break; + + case _T('>'): + MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_QUOTE, 0, 0, MD_BLOCK_CONTAINER_OPENER)); + break; + + default: + MD_UNREACHABLE(); + break; + } + } + +abort: + return ret; +} + +static int +md_leave_child_containers(MD_CTX* ctx, int n_keep) +{ + int ret = 0; + + while(ctx->n_containers > n_keep) { + MD_CONTAINER* c = &ctx->containers[ctx->n_containers-1]; + int is_ordered_list = FALSE; + + switch(c->ch) { + case _T(')'): + case _T('.'): + is_ordered_list = TRUE; + MD_FALLTHROUGH(); + + case _T('-'): + case _T('+'): + case _T('*'): + MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, + c->task_mark_off, (c->is_task ? CH(c->task_mark_off) : 0), + MD_BLOCK_CONTAINER_CLOSER)); + MD_CHECK(md_push_container_bytes(ctx, + (is_ordered_list ? MD_BLOCK_OL : MD_BLOCK_UL), 0, + c->ch, MD_BLOCK_CONTAINER_CLOSER)); + break; + + case _T('>'): + MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_QUOTE, 0, + 0, MD_BLOCK_CONTAINER_CLOSER)); + break; + + default: + MD_UNREACHABLE(); + break; + } + + ctx->n_containers--; + } + +abort: + return ret; +} + +static int +md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTAINER* p_container) +{ + OFF off = beg; + OFF max_end; + + if(off >= ctx->size || indent >= ctx->code_indent_offset) + return FALSE; + + /* Check for block quote mark. */ + if(CH(off) == _T('>')) { + off++; + p_container->ch = _T('>'); + p_container->is_loose = FALSE; + p_container->is_task = FALSE; + p_container->mark_indent = indent; + p_container->contents_indent = indent + 1; + *p_end = off; + return TRUE; + } + + /* Check for list item bullet mark. */ + if(ISANYOF(off, _T("-+*")) && (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) { + p_container->ch = CH(off); + p_container->is_loose = FALSE; + p_container->is_task = FALSE; + p_container->mark_indent = indent; + p_container->contents_indent = indent + 1; + *p_end = off+1; + return TRUE; + } + + /* Check for ordered list item marks. */ + max_end = off + 9; + if(max_end > ctx->size) + max_end = ctx->size; + p_container->start = 0; + while(off < max_end && ISDIGIT(off)) { + p_container->start = p_container->start * 10 + CH(off) - _T('0'); + off++; + } + if(off > beg && + off < ctx->size && + (CH(off) == _T('.') || CH(off) == _T(')')) && + (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) + { + p_container->ch = CH(off); + p_container->is_loose = FALSE; + p_container->is_task = FALSE; + p_container->mark_indent = indent; + p_container->contents_indent = indent + off - beg + 1; + *p_end = off+1; + return TRUE; + } + + return FALSE; +} + +static unsigned +md_line_indentation(MD_CTX* ctx, unsigned total_indent, OFF beg, OFF* p_end) +{ + OFF off = beg; + unsigned indent = total_indent; + + while(off < ctx->size && ISBLANK(off)) { + if(CH(off) == _T('\t')) + indent = (indent + 4) & ~3; + else + indent++; + off++; + } + + *p_end = off; + return indent - total_indent; +} + +static const MD_LINE_ANALYSIS md_dummy_blank_line = { MD_LINE_BLANK, 0, 0, 0, 0, 0 }; + +/* Analyze type of the line and find some its properties. This serves as a + * main input for determining type and boundaries of a block. */ +static int +md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, + const MD_LINE_ANALYSIS* pivot_line, MD_LINE_ANALYSIS* line) +{ + unsigned total_indent = 0; + int n_parents = 0; + int n_brothers = 0; + int n_children = 0; + MD_CONTAINER container = { 0 }; + int prev_line_has_list_loosening_effect = ctx->last_line_has_list_loosening_effect; + OFF off = beg; + OFF hr_killer = 0; + int ret = 0; + + line->indent = md_line_indentation(ctx, total_indent, off, &off); + total_indent += line->indent; + line->beg = off; + line->enforce_new_block = FALSE; + + /* Given the indentation and block quote marks '>', determine how many of + * the current containers are our parents. */ + while(n_parents < ctx->n_containers) { + MD_CONTAINER* c = &ctx->containers[n_parents]; + + if(c->ch == _T('>') && line->indent < ctx->code_indent_offset && + off < ctx->size && CH(off) == _T('>')) + { + /* Block quote mark. */ + off++; + total_indent++; + line->indent = md_line_indentation(ctx, total_indent, off, &off); + total_indent += line->indent; + + /* The optional 1st space after '>' is part of the block quote mark. */ + if(line->indent > 0) + line->indent--; + + line->beg = off; + + } else if(c->ch != _T('>') && line->indent >= c->contents_indent) { + /* List. */ + line->indent -= c->contents_indent; + } else { + break; + } + + n_parents++; + } + + if(off >= ctx->size || ISNEWLINE(off)) { + /* Blank line does not need any real indentation to be nested inside + * a list. */ + if(n_brothers + n_children == 0) { + while(n_parents < ctx->n_containers && ctx->containers[n_parents].ch != _T('>')) + n_parents++; + } + } + + while(TRUE) { + /* Check whether we are fenced code continuation. */ + if(pivot_line->type == MD_LINE_FENCEDCODE) { + line->beg = off; + + /* We are another MD_LINE_FENCEDCODE unless we are closing fence + * which we transform into MD_LINE_BLANK. */ + if(line->indent < ctx->code_indent_offset) { + if(md_is_closing_code_fence(ctx, CH(pivot_line->beg), off, &off)) { + line->type = MD_LINE_BLANK; + ctx->last_line_has_list_loosening_effect = FALSE; + break; + } + } + + /* Change indentation accordingly to the initial code fence. */ + if(n_parents == ctx->n_containers) { + if(line->indent > pivot_line->indent) + line->indent -= pivot_line->indent; + else + line->indent = 0; + + line->type = MD_LINE_FENCEDCODE; + break; + } + } + + /* Check whether we are HTML block continuation. */ + if(pivot_line->type == MD_LINE_HTML && ctx->html_block_type > 0) { + if(n_parents < ctx->n_containers) { + /* HTML block is implicitly ended if the enclosing container + * block ends. */ + ctx->html_block_type = 0; + } else { + int html_block_type; + + html_block_type = md_is_html_block_end_condition(ctx, off, &off); + if(html_block_type > 0) { + MD_ASSERT(html_block_type == ctx->html_block_type); + + /* Make sure this is the last line of the block. */ + ctx->html_block_type = 0; + + /* Some end conditions serve as blank lines at the same time. */ + if(html_block_type == 6 || html_block_type == 7) { + line->type = MD_LINE_BLANK; + line->indent = 0; + break; + } + } + + line->type = MD_LINE_HTML; + n_parents = ctx->n_containers; + break; + } + } + + /* Check for blank line. */ + if(off >= ctx->size || ISNEWLINE(off)) { + if(pivot_line->type == MD_LINE_INDENTEDCODE && n_parents == ctx->n_containers) { + line->type = MD_LINE_INDENTEDCODE; + if(line->indent > ctx->code_indent_offset) + line->indent -= ctx->code_indent_offset; + else + line->indent = 0; + ctx->last_line_has_list_loosening_effect = FALSE; + } else { + line->type = MD_LINE_BLANK; + ctx->last_line_has_list_loosening_effect = (n_parents > 0 && + n_brothers + n_children == 0 && + ctx->containers[n_parents-1].ch != _T('>')); + + #if 1 + /* See https://github.com/mity/md4c/issues/6 + * + * This ugly checking tests we are in (yet empty) list item but + * not its very first line (i.e. not the line with the list + * item mark). + * + * If we are such a blank line, then any following non-blank + * line which would be part of the list item actually has to + * end the list because according to the specification, "a list + * item can begin with at most one blank line." + */ + if(n_parents > 0 && ctx->containers[n_parents-1].ch != _T('>') && + n_brothers + n_children == 0 && ctx->current_block == NULL && + ctx->n_block_bytes > (int) sizeof(MD_BLOCK)) + { + MD_BLOCK* top_block = (MD_BLOCK*) ((char*)ctx->block_bytes + ctx->n_block_bytes - sizeof(MD_BLOCK)); + if(top_block->type == MD_BLOCK_LI) + ctx->last_list_item_starts_with_two_blank_lines = TRUE; + } + #endif + } + break; + } else { + #if 1 + /* This is the 2nd half of the hack. If the flag is set (i.e. there + * was a 2nd blank line at the beginning of the list item) and if + * we would otherwise still belong to the list item, we enforce + * the end of the list. */ + if(ctx->last_list_item_starts_with_two_blank_lines) { + if(n_parents > 0 && n_parents == ctx->n_containers && + ctx->containers[n_parents-1].ch != _T('>') && + n_brothers + n_children == 0 && ctx->current_block == NULL && + ctx->n_block_bytes > (int) sizeof(MD_BLOCK)) + { + MD_BLOCK* top_block = (MD_BLOCK*) ((char*)ctx->block_bytes + ctx->n_block_bytes - sizeof(MD_BLOCK)); + if(top_block->type == MD_BLOCK_LI) { + n_parents--; + + line->indent = total_indent; + if(n_parents > 0) + line->indent -= MIN(line->indent, ctx->containers[n_parents-1].contents_indent); + } + } + + ctx->last_list_item_starts_with_two_blank_lines = FALSE; + } + #endif + ctx->last_line_has_list_loosening_effect = FALSE; + } + + /* Check whether we are Setext underline. */ + if(line->indent < ctx->code_indent_offset && pivot_line->type == MD_LINE_TEXT + && off < ctx->size && ISANYOF2(off, _T('='), _T('-')) + && (n_parents == ctx->n_containers)) + { + unsigned level; + + if(md_is_setext_underline(ctx, off, &off, &level)) { + line->type = MD_LINE_SETEXTUNDERLINE; + line->data = level; + break; + } + } + + /* Check for thematic break line. */ + if(line->indent < ctx->code_indent_offset + && off < ctx->size && off >= hr_killer + && ISANYOF(off, _T("-_*"))) + { + if(md_is_hr_line(ctx, off, &off, &hr_killer)) { + line->type = MD_LINE_HR; + break; + } + } + + /* Check for "brother" container. I.e. whether we are another list item + * in already started list. */ + if(n_parents < ctx->n_containers && n_brothers + n_children == 0) { + OFF tmp; + + if(md_is_container_mark(ctx, line->indent, off, &tmp, &container) && + md_is_container_compatible(&ctx->containers[n_parents], &container)) + { + pivot_line = &md_dummy_blank_line; + + off = tmp; + + total_indent += container.contents_indent - container.mark_indent; + line->indent = md_line_indentation(ctx, total_indent, off, &off); + total_indent += line->indent; + line->beg = off; + + /* Some of the following whitespace actually still belongs to the mark. */ + if(off >= ctx->size || ISNEWLINE(off)) { + container.contents_indent++; + } else if(line->indent <= ctx->code_indent_offset) { + container.contents_indent += line->indent; + line->indent = 0; + } else { + container.contents_indent += 1; + line->indent--; + } + + ctx->containers[n_parents].mark_indent = container.mark_indent; + ctx->containers[n_parents].contents_indent = container.contents_indent; + + n_brothers++; + continue; + } + } + + /* Check for indented code. + * Note indented code block cannot interrupt a paragraph. */ + if(line->indent >= ctx->code_indent_offset && (pivot_line->type != MD_LINE_TEXT)) { + line->type = MD_LINE_INDENTEDCODE; + line->indent -= ctx->code_indent_offset; + line->data = 0; + break; + } + + /* Check for start of a new container block. */ + if(line->indent < ctx->code_indent_offset && + md_is_container_mark(ctx, line->indent, off, &off, &container)) + { + if(pivot_line->type == MD_LINE_TEXT && n_parents == ctx->n_containers && + (off >= ctx->size || ISNEWLINE(off)) && container.ch != _T('>')) + { + /* Noop. List mark followed by a blank line cannot interrupt a paragraph. */ + } else if(pivot_line->type == MD_LINE_TEXT && n_parents == ctx->n_containers && + ISANYOF2_(container.ch, _T('.'), _T(')')) && container.start != 1) + { + /* Noop. Ordered list cannot interrupt a paragraph unless the start index is 1. */ + } else { + total_indent += container.contents_indent - container.mark_indent; + line->indent = md_line_indentation(ctx, total_indent, off, &off); + total_indent += line->indent; + + line->beg = off; + line->data = container.ch; + + /* Some of the following whitespace actually still belongs to the mark. */ + if(off >= ctx->size || ISNEWLINE(off)) { + container.contents_indent++; + } else if(line->indent <= ctx->code_indent_offset) { + container.contents_indent += line->indent; + line->indent = 0; + } else { + container.contents_indent += 1; + line->indent--; + } + + if(n_brothers + n_children == 0) + pivot_line = &md_dummy_blank_line; + + if(n_children == 0) + MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers)); + + n_children++; + MD_CHECK(md_push_container(ctx, &container)); + continue; + } + } + + /* Check whether we are table continuation. */ + if(pivot_line->type == MD_LINE_TABLE && n_parents == ctx->n_containers) { + line->type = MD_LINE_TABLE; + break; + } + + /* Check for ATX header. */ + if(line->indent < ctx->code_indent_offset && + off < ctx->size && CH(off) == _T('#')) + { + unsigned level; + + if(md_is_atxheader_line(ctx, off, &line->beg, &off, &level)) { + line->type = MD_LINE_ATXHEADER; + line->data = level; + break; + } + } + + /* Check whether we are starting code fence. */ + if(line->indent < ctx->code_indent_offset && + off < ctx->size && ISANYOF2(off, _T('`'), _T('~'))) + { + if(md_is_opening_code_fence(ctx, off, &off)) { + line->type = MD_LINE_FENCEDCODE; + line->data = 1; + line->enforce_new_block = TRUE; + break; + } + } + + /* Check for start of raw HTML block. */ + if(off < ctx->size && CH(off) == _T('<') + && !(ctx->parser.flags & MD_FLAG_NOHTMLBLOCKS)) + { + ctx->html_block_type = md_is_html_block_start_condition(ctx, off); + + /* HTML block type 7 cannot interrupt paragraph. */ + if(ctx->html_block_type == 7 && pivot_line->type == MD_LINE_TEXT) + ctx->html_block_type = 0; + + if(ctx->html_block_type > 0) { + /* The line itself also may immediately close the block. */ + if(md_is_html_block_end_condition(ctx, off, &off) == ctx->html_block_type) { + /* Make sure this is the last line of the block. */ + ctx->html_block_type = 0; + } + + line->enforce_new_block = TRUE; + line->type = MD_LINE_HTML; + break; + } + } + + /* Check for table underline. */ + if((ctx->parser.flags & MD_FLAG_TABLES) && pivot_line->type == MD_LINE_TEXT + && off < ctx->size && ISANYOF3(off, _T('|'), _T('-'), _T(':')) + && n_parents == ctx->n_containers) + { + unsigned col_count; + + if(ctx->current_block != NULL && ctx->current_block->n_lines == 1 && + md_is_table_underline(ctx, off, &off, &col_count)) + { + line->data = col_count; + line->type = MD_LINE_TABLEUNDERLINE; + break; + } + } + + /* By default, we are normal text line. */ + line->type = MD_LINE_TEXT; + if(pivot_line->type == MD_LINE_TEXT && n_brothers + n_children == 0) { + /* Lazy continuation. */ + n_parents = ctx->n_containers; + } + + /* Check for task mark. */ + if((ctx->parser.flags & MD_FLAG_TASKLISTS) && n_brothers + n_children > 0 && + ISANYOF_(ctx->containers[ctx->n_containers-1].ch, _T("-+*.)"))) + { + OFF tmp = off; + + while(tmp < ctx->size && tmp < off + 3 && ISBLANK(tmp)) + tmp++; + if(tmp + 2 < ctx->size && CH(tmp) == _T('[') && + ISANYOF(tmp+1, _T("xX ")) && CH(tmp+2) == _T(']') && + (tmp + 3 == ctx->size || ISBLANK(tmp+3) || ISNEWLINE(tmp+3))) + { + MD_CONTAINER* task_container = (n_children > 0 ? &ctx->containers[ctx->n_containers-1] : &container); + task_container->is_task = TRUE; + task_container->task_mark_off = tmp + 1; + off = tmp + 3; + while(off < ctx->size && ISWHITESPACE(off)) + off++; + line->beg = off; + } + } + + break; + } + + /* Scan for end of the line. + * + * Note this is quite a bottleneck of the parsing as we here iterate almost + * over compete document. + */ +#if defined __linux__ && !defined MD4C_USE_UTF16 + /* Recent glibc versions have superbly optimized strcspn(), even using + * vectorization if available. */ + if(ctx->doc_ends_with_newline && off < ctx->size) { + while(TRUE) { + off += (OFF) strcspn(STR(off), "\r\n"); + + /* strcspn() can stop on zero terminator; but that can appear + * anywhere in the Markfown input... */ + if(CH(off) == _T('\0')) + off++; + else + break; + } + } else +#endif + { + /* Optimization: Use some loop unrolling. */ + while(off + 3 < ctx->size && !ISNEWLINE(off+0) && !ISNEWLINE(off+1) + && !ISNEWLINE(off+2) && !ISNEWLINE(off+3)) + off += 4; + while(off < ctx->size && !ISNEWLINE(off)) + off++; + } + + /* Set end of the line. */ + line->end = off; + + /* But for ATX header, we should exclude the optional trailing mark. */ + if(line->type == MD_LINE_ATXHEADER) { + OFF tmp = line->end; + while(tmp > line->beg && ISBLANK(tmp-1)) + tmp--; + while(tmp > line->beg && CH(tmp-1) == _T('#')) + tmp--; + if(tmp == line->beg || ISBLANK(tmp-1) || (ctx->parser.flags & MD_FLAG_PERMISSIVEATXHEADERS)) + line->end = tmp; + } + + /* Trim trailing spaces. */ + if(line->type != MD_LINE_INDENTEDCODE && line->type != MD_LINE_FENCEDCODE && line->type != MD_LINE_HTML) { + while(line->end > line->beg && ISBLANK(line->end-1)) + line->end--; + } + + /* Eat also the new line. */ + if(off < ctx->size && CH(off) == _T('\r')) + off++; + if(off < ctx->size && CH(off) == _T('\n')) + off++; + + *p_end = off; + + /* If we belong to a list after seeing a blank line, the list is loose. */ + if(prev_line_has_list_loosening_effect && line->type != MD_LINE_BLANK && n_parents + n_brothers > 0) { + MD_CONTAINER* c = &ctx->containers[n_parents + n_brothers - 1]; + if(c->ch != _T('>')) { + MD_BLOCK* block = (MD_BLOCK*) (((char*)ctx->block_bytes) + c->block_byte_off); + block->flags |= MD_BLOCK_LOOSE_LIST; + } + } + + /* Leave any containers we are not part of anymore. */ + if(n_children == 0 && n_parents + n_brothers < ctx->n_containers) + MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers)); + + /* Enter any container we found a mark for. */ + if(n_brothers > 0) { + MD_ASSERT(n_brothers == 1); + MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, + ctx->containers[n_parents].task_mark_off, + (ctx->containers[n_parents].is_task ? CH(ctx->containers[n_parents].task_mark_off) : 0), + MD_BLOCK_CONTAINER_CLOSER)); + MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, + container.task_mark_off, + (container.is_task ? CH(container.task_mark_off) : 0), + MD_BLOCK_CONTAINER_OPENER)); + ctx->containers[n_parents].is_task = container.is_task; + ctx->containers[n_parents].task_mark_off = container.task_mark_off; + } + + if(n_children > 0) + MD_CHECK(md_enter_child_containers(ctx, n_children)); + +abort: + return ret; +} + +static int +md_process_line(MD_CTX* ctx, const MD_LINE_ANALYSIS** p_pivot_line, MD_LINE_ANALYSIS* line) +{ + const MD_LINE_ANALYSIS* pivot_line = *p_pivot_line; + int ret = 0; + + /* Blank line ends current leaf block. */ + if(line->type == MD_LINE_BLANK) { + MD_CHECK(md_end_current_block(ctx)); + *p_pivot_line = &md_dummy_blank_line; + return 0; + } + + if(line->enforce_new_block) + MD_CHECK(md_end_current_block(ctx)); + + /* Some line types form block on their own. */ + if(line->type == MD_LINE_HR || line->type == MD_LINE_ATXHEADER) { + MD_CHECK(md_end_current_block(ctx)); + + /* Add our single-line block. */ + MD_CHECK(md_start_new_block(ctx, line)); + MD_CHECK(md_add_line_into_current_block(ctx, line)); + MD_CHECK(md_end_current_block(ctx)); + *p_pivot_line = &md_dummy_blank_line; + return 0; + } + + /* MD_LINE_SETEXTUNDERLINE changes meaning of the current block and ends it. */ + if(line->type == MD_LINE_SETEXTUNDERLINE) { + MD_ASSERT(ctx->current_block != NULL); + ctx->current_block->type = MD_BLOCK_H; + ctx->current_block->data = line->data; + ctx->current_block->flags |= MD_BLOCK_SETEXT_HEADER; + MD_CHECK(md_add_line_into_current_block(ctx, line)); + MD_CHECK(md_end_current_block(ctx)); + if(ctx->current_block == NULL) { + *p_pivot_line = &md_dummy_blank_line; + } else { + /* This happens if we have consumed all the body as link ref. defs. + * and downgraded the underline into start of a new paragraph block. */ + line->type = MD_LINE_TEXT; + *p_pivot_line = line; + } + return 0; + } + + /* MD_LINE_TABLEUNDERLINE changes meaning of the current block. */ + if(line->type == MD_LINE_TABLEUNDERLINE) { + MD_ASSERT(ctx->current_block != NULL); + MD_ASSERT(ctx->current_block->n_lines == 1); + ctx->current_block->type = MD_BLOCK_TABLE; + ctx->current_block->data = line->data; + MD_ASSERT(pivot_line != &md_dummy_blank_line); + ((MD_LINE_ANALYSIS*)pivot_line)->type = MD_LINE_TABLE; + MD_CHECK(md_add_line_into_current_block(ctx, line)); + return 0; + } + + /* The current block also ends if the line has different type. */ + if(line->type != pivot_line->type) + MD_CHECK(md_end_current_block(ctx)); + + /* The current line may start a new block. */ + if(ctx->current_block == NULL) { + MD_CHECK(md_start_new_block(ctx, line)); + *p_pivot_line = line; + } + + /* In all other cases the line is just a continuation of the current block. */ + MD_CHECK(md_add_line_into_current_block(ctx, line)); + +abort: + return ret; +} + +static int +md_process_doc(MD_CTX *ctx) +{ + const MD_LINE_ANALYSIS* pivot_line = &md_dummy_blank_line; + MD_LINE_ANALYSIS line_buf[2]; + MD_LINE_ANALYSIS* line = &line_buf[0]; + OFF off = 0; + int ret = 0; + + MD_ENTER_BLOCK(MD_BLOCK_DOC, NULL); + + while(off < ctx->size) { + if(line == pivot_line) + line = (line == &line_buf[0] ? &line_buf[1] : &line_buf[0]); + + MD_CHECK(md_analyze_line(ctx, off, &off, pivot_line, line)); + MD_CHECK(md_process_line(ctx, &pivot_line, line)); + } + + md_end_current_block(ctx); + + MD_CHECK(md_build_ref_def_hashtable(ctx)); + + /* Process all blocks. */ + MD_CHECK(md_leave_child_containers(ctx, 0)); + MD_CHECK(md_process_all_blocks(ctx)); + + MD_LEAVE_BLOCK(MD_BLOCK_DOC, NULL); + +abort: + +#if 0 + /* Output some memory consumption statistics. */ + { + char buffer[256]; + sprintf(buffer, "Alloced %u bytes for block buffer.", + (unsigned)(ctx->alloc_block_bytes)); + MD_LOG(buffer); + + sprintf(buffer, "Alloced %u bytes for containers buffer.", + (unsigned)(ctx->alloc_containers * sizeof(MD_CONTAINER))); + MD_LOG(buffer); + + sprintf(buffer, "Alloced %u bytes for marks buffer.", + (unsigned)(ctx->alloc_marks * sizeof(MD_MARK))); + MD_LOG(buffer); + + sprintf(buffer, "Alloced %u bytes for aux. buffer.", + (unsigned)(ctx->alloc_buffer * sizeof(MD_CHAR))); + MD_LOG(buffer); + } +#endif + + return ret; +} + + +/******************** + *** Public API *** + ********************/ + +int +md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userdata) +{ + MD_CTX ctx; + int i; + int ret; + + if(parser->abi_version != 0) { + if(parser->debug_log != NULL) + parser->debug_log("Unsupported abi_version.", userdata); + return -1; + } + + /* Setup context structure. */ + memset(&ctx, 0, sizeof(MD_CTX)); + ctx.text = text; + ctx.size = size; + memcpy(&ctx.parser, parser, sizeof(MD_PARSER)); + ctx.userdata = userdata; + ctx.code_indent_offset = (ctx.parser.flags & MD_FLAG_NOINDENTEDCODEBLOCKS) ? (OFF)(-1) : 4; + md_build_mark_char_map(&ctx); + ctx.doc_ends_with_newline = (size > 0 && ISNEWLINE_(text[size-1])); + ctx.max_ref_def_output = MIN(MIN(16 * (uint64_t)size, (uint64_t)(1024 * 1024)), (uint64_t)SZ_MAX); + + /* Reset all mark stacks and lists. */ + for(i = 0; i < (int) SIZEOF_ARRAY(ctx.opener_stacks); i++) + ctx.opener_stacks[i].top = -1; + ctx.ptr_stack.top = -1; + ctx.unresolved_link_head = -1; + ctx.unresolved_link_tail = -1; + ctx.table_cell_boundaries_head = -1; + ctx.table_cell_boundaries_tail = -1; + + /* All the work. */ + ret = md_process_doc(&ctx); + + /* Clean-up. */ + md_free_ref_defs(&ctx); + md_free_ref_def_hashtable(&ctx); + free(ctx.buffer); + free(ctx.marks); + free(ctx.block_bytes); + free(ctx.containers); + + return ret; +} diff --git a/Src/Orbiter/md4c.h b/Src/Orbiter/md4c.h new file mode 100644 index 000000000..e4a34746b --- /dev/null +++ b/Src/Orbiter/md4c.h @@ -0,0 +1,407 @@ +/* + * MD4C: Markdown parser for C + * (http://github.com/mity/md4c) + * + * Copyright (c) 2016-2024 Martin Mitáš + * + * 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 MD4C_H +#define MD4C_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined MD4C_USE_UTF16 + /* Magic to support UTF-16. Note that in order to use it, you have to define + * the macro MD4C_USE_UTF16 both when building MD4C as well as when + * including this header in your code. */ + #ifdef _WIN32 + #include + typedef WCHAR MD_CHAR; + #else + #error MD4C_USE_UTF16 is only supported on Windows. + #endif +#else + typedef char MD_CHAR; +#endif + +typedef unsigned MD_SIZE; +typedef unsigned MD_OFFSET; + + +/* Block represents a part of document hierarchy structure like a paragraph + * or list item. + */ +typedef enum MD_BLOCKTYPE { + /* ... */ + MD_BLOCK_DOC = 0, + + /*
...
*/ + MD_BLOCK_QUOTE, + + /*
    ...
+ * Detail: Structure MD_BLOCK_UL_DETAIL. */ + MD_BLOCK_UL, + + /*
    ...
+ * Detail: Structure MD_BLOCK_OL_DETAIL. */ + MD_BLOCK_OL, + + /*
  • ...
  • + * Detail: Structure MD_BLOCK_LI_DETAIL. */ + MD_BLOCK_LI, + + /*
    */ + MD_BLOCK_HR, + + /*

    ...

    (for levels up to 6) + * Detail: Structure MD_BLOCK_H_DETAIL. */ + MD_BLOCK_H, + + /*
    ...
    + * Note the text lines within code blocks are terminated with '\n' + * instead of explicit MD_TEXT_BR. */ + MD_BLOCK_CODE, + + /* Raw HTML block. This itself does not correspond to any particular HTML + * tag. The contents of it _is_ raw HTML source intended to be put + * in verbatim form to the HTML output. */ + MD_BLOCK_HTML, + + /*

    ...

    */ + MD_BLOCK_P, + + /* ...
    and its contents. + * Detail: Structure MD_BLOCK_TABLE_DETAIL (for MD_BLOCK_TABLE), + * structure MD_BLOCK_TD_DETAIL (for MD_BLOCK_TH and MD_BLOCK_TD) + * Note all of these are used only if extension MD_FLAG_TABLES is enabled. */ + MD_BLOCK_TABLE, + MD_BLOCK_THEAD, + MD_BLOCK_TBODY, + MD_BLOCK_TR, + MD_BLOCK_TH, + MD_BLOCK_TD +} MD_BLOCKTYPE; + +/* Span represents an in-line piece of a document which should be rendered with + * the same font, color and other attributes. A sequence of spans forms a block + * like paragraph or list item. */ +typedef enum MD_SPANTYPE { + /* ... */ + MD_SPAN_EM, + + /* ... */ + MD_SPAN_STRONG, + + /*
    ... + * Detail: Structure MD_SPAN_A_DETAIL. */ + MD_SPAN_A, + + /* ... + * Detail: Structure MD_SPAN_IMG_DETAIL. + * Note: Image text can contain nested spans and even nested images. + * If rendered into ALT attribute of HTML tag, it's responsibility + * of the parser to deal with it. + */ + MD_SPAN_IMG, + + /* ... */ + MD_SPAN_CODE, + + /* ... + * Note: Recognized only when MD_FLAG_STRIKETHROUGH is enabled. + */ + MD_SPAN_DEL, + + /* For recognizing inline ($) and display ($$) equations + * Note: Recognized only when MD_FLAG_LATEXMATHSPANS is enabled. + */ + MD_SPAN_LATEXMATH, + MD_SPAN_LATEXMATH_DISPLAY, + + /* Wiki links + * Note: Recognized only when MD_FLAG_WIKILINKS is enabled. + */ + MD_SPAN_WIKILINK, + + /* ... + * Note: Recognized only when MD_FLAG_UNDERLINE is enabled. */ + MD_SPAN_U +} MD_SPANTYPE; + +/* Text is the actual textual contents of span. */ +typedef enum MD_TEXTTYPE { + /* Normal text. */ + MD_TEXT_NORMAL = 0, + + /* NULL character. CommonMark requires replacing NULL character with + * the replacement char U+FFFD, so this allows caller to do that easily. */ + MD_TEXT_NULLCHAR, + + /* Line breaks. + * Note these are not sent from blocks with verbatim output (MD_BLOCK_CODE + * or MD_BLOCK_HTML). In such cases, '\n' is part of the text itself. */ + MD_TEXT_BR, /*
    (hard break) */ + MD_TEXT_SOFTBR, /* '\n' in source text where it is not semantically meaningful (soft break) */ + + /* Entity. + * (a) Named entity, e.g.   + * (Note MD4C does not have a list of known entities. + * Anything matching the regexp /&[A-Za-z][A-Za-z0-9]{1,47};/ is + * treated as a named entity.) + * (b) Numerical entity, e.g. Ӓ + * (c) Hexadecimal entity, e.g. ካ + * + * As MD4C is mostly encoding agnostic, application gets the verbatim + * entity text into the MD_PARSER::text_callback(). */ + MD_TEXT_ENTITY, + + /* Text in a code block (inside MD_BLOCK_CODE) or inlined code (`code`). + * If it is inside MD_BLOCK_CODE, it includes spaces for indentation and + * '\n' for new lines. MD_TEXT_BR and MD_TEXT_SOFTBR are not sent for this + * kind of text. */ + MD_TEXT_CODE, + + /* Text is a raw HTML. If it is contents of a raw HTML block (i.e. not + * an inline raw HTML), then MD_TEXT_BR and MD_TEXT_SOFTBR are not used. + * The text contains verbatim '\n' for the new lines. */ + MD_TEXT_HTML, + + /* Text is inside an equation. This is processed the same way as inlined code + * spans (`code`). */ + MD_TEXT_LATEXMATH +} MD_TEXTTYPE; + + +/* Alignment enumeration. */ +typedef enum MD_ALIGN { + MD_ALIGN_DEFAULT = 0, /* When unspecified. */ + MD_ALIGN_LEFT, + MD_ALIGN_CENTER, + MD_ALIGN_RIGHT +} MD_ALIGN; + + +/* String attribute. + * + * This wraps strings which are outside of a normal text flow and which are + * propagated within various detailed structures, but which still may contain + * string portions of different types like e.g. entities. + * + * So, for example, lets consider this image: + * + * ![image alt text](http://example.org/image.png 'foo " bar') + * + * The image alt text is propagated as a normal text via the MD_PARSER::text() + * callback. However, the image title ('foo " bar') is propagated as + * MD_ATTRIBUTE in MD_SPAN_IMG_DETAIL::title. + * + * Then the attribute MD_SPAN_IMG_DETAIL::title shall provide the following: + * -- [0]: "foo " (substr_types[0] == MD_TEXT_NORMAL; substr_offsets[0] == 0) + * -- [1]: """ (substr_types[1] == MD_TEXT_ENTITY; substr_offsets[1] == 4) + * -- [2]: " bar" (substr_types[2] == MD_TEXT_NORMAL; substr_offsets[2] == 10) + * -- [3]: (n/a) (n/a ; substr_offsets[3] == 14) + * + * Note that these invariants are always guaranteed: + * -- substr_offsets[0] == 0 + * -- substr_offsets[LAST+1] == size + * -- Currently, only MD_TEXT_NORMAL, MD_TEXT_ENTITY, MD_TEXT_NULLCHAR + * substrings can appear. This could change only of the specification + * changes. + */ +typedef struct MD_ATTRIBUTE { + const MD_CHAR* text; + MD_SIZE size; + const MD_TEXTTYPE* substr_types; + const MD_OFFSET* substr_offsets; +} MD_ATTRIBUTE; + + +/* Detailed info for MD_BLOCK_UL. */ +typedef struct MD_BLOCK_UL_DETAIL { + int is_tight; /* Non-zero if tight list, zero if loose. */ + MD_CHAR mark; /* Item bullet character in MarkDown source of the list, e.g. '-', '+', '*'. */ +} MD_BLOCK_UL_DETAIL; + +/* Detailed info for MD_BLOCK_OL. */ +typedef struct MD_BLOCK_OL_DETAIL { + unsigned start; /* Start index of the ordered list. */ + int is_tight; /* Non-zero if tight list, zero if loose. */ + MD_CHAR mark_delimiter; /* Character delimiting the item marks in MarkDown source, e.g. '.' or ')' */ +} MD_BLOCK_OL_DETAIL; + +/* Detailed info for MD_BLOCK_LI. */ +typedef struct MD_BLOCK_LI_DETAIL { + int is_task; /* Can be non-zero only with MD_FLAG_TASKLISTS */ + MD_CHAR task_mark; /* If is_task, then one of 'x', 'X' or ' '. Undefined otherwise. */ + MD_OFFSET task_mark_offset; /* If is_task, then offset in the input of the char between '[' and ']'. */ +} MD_BLOCK_LI_DETAIL; + +/* Detailed info for MD_BLOCK_H. */ +typedef struct MD_BLOCK_H_DETAIL { + unsigned level; /* Header level (1 - 6) */ +} MD_BLOCK_H_DETAIL; + +/* Detailed info for MD_BLOCK_CODE. */ +typedef struct MD_BLOCK_CODE_DETAIL { + MD_ATTRIBUTE info; + MD_ATTRIBUTE lang; + MD_CHAR fence_char; /* The character used for fenced code block; or zero for indented code block. */ +} MD_BLOCK_CODE_DETAIL; + +/* Detailed info for MD_BLOCK_TABLE. */ +typedef struct MD_BLOCK_TABLE_DETAIL { + unsigned col_count; /* Count of columns in the table. */ + unsigned head_row_count; /* Count of rows in the table header (currently always 1) */ + unsigned body_row_count; /* Count of rows in the table body */ +} MD_BLOCK_TABLE_DETAIL; + +/* Detailed info for MD_BLOCK_TH and MD_BLOCK_TD. */ +typedef struct MD_BLOCK_TD_DETAIL { + MD_ALIGN align; +} MD_BLOCK_TD_DETAIL; + +/* Detailed info for MD_SPAN_A. */ +typedef struct MD_SPAN_A_DETAIL { + MD_ATTRIBUTE href; + MD_ATTRIBUTE title; + int is_autolink; /* nonzero if this is an autolink */ +} MD_SPAN_A_DETAIL; + +/* Detailed info for MD_SPAN_IMG. */ +typedef struct MD_SPAN_IMG_DETAIL { + MD_ATTRIBUTE src; + MD_ATTRIBUTE title; +} MD_SPAN_IMG_DETAIL; + +/* Detailed info for MD_SPAN_WIKILINK. */ +typedef struct MD_SPAN_WIKILINK { + MD_ATTRIBUTE target; +} MD_SPAN_WIKILINK_DETAIL; + +/* Flags specifying extensions/deviations from CommonMark specification. + * + * By default (when MD_PARSER::flags == 0), we follow CommonMark specification. + * The following flags may allow some extensions or deviations from it. + */ +#define MD_FLAG_COLLAPSEWHITESPACE 0x0001 /* In MD_TEXT_NORMAL, collapse non-trivial whitespace into single ' ' */ +#define MD_FLAG_PERMISSIVEATXHEADERS 0x0002 /* Do not require space in ATX headers ( ###header ) */ +#define MD_FLAG_PERMISSIVEURLAUTOLINKS 0x0004 /* Recognize URLs as autolinks even without '<', '>' */ +#define MD_FLAG_PERMISSIVEEMAILAUTOLINKS 0x0008 /* Recognize e-mails as autolinks even without '<', '>' and 'mailto:' */ +#define MD_FLAG_NOINDENTEDCODEBLOCKS 0x0010 /* Disable indented code blocks. (Only fenced code works.) */ +#define MD_FLAG_NOHTMLBLOCKS 0x0020 /* Disable raw HTML blocks. */ +#define MD_FLAG_NOHTMLSPANS 0x0040 /* Disable raw HTML (inline). */ +#define MD_FLAG_TABLES 0x0100 /* Enable tables extension. */ +#define MD_FLAG_STRIKETHROUGH 0x0200 /* Enable strikethrough extension. */ +#define MD_FLAG_PERMISSIVEWWWAUTOLINKS 0x0400 /* Enable WWW autolinks (even without any scheme prefix, if they begin with 'www.') */ +#define MD_FLAG_TASKLISTS 0x0800 /* Enable task list extension. */ +#define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */ +#define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */ +#define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */ +#define MD_FLAG_HARD_SOFT_BREAKS 0x8000 /* Force all soft breaks to act as hard breaks. */ + +#define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS) +#define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS) + +/* Convenient sets of flags corresponding to well-known Markdown dialects. + * + * Note we may only support subset of features of the referred dialect. + * The constant just enables those extensions which bring us as close as + * possible given what features we implement. + * + * ABI compatibility note: Meaning of these can change in time as new + * extensions, bringing the dialect closer to the original, are implemented. + */ +#define MD_DIALECT_COMMONMARK 0 +#define MD_DIALECT_GITHUB (MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH | MD_FLAG_TASKLISTS) + +/* Parser structure. + */ +typedef struct MD_PARSER { + /* Reserved. Set to zero. + */ + unsigned abi_version; + + /* Dialect options. Bitmask of MD_FLAG_xxxx values. + */ + unsigned flags; + + /* Caller-provided rendering callbacks. + * + * For some block/span types, more detailed information is provided in a + * type-specific structure pointed by the argument 'detail'. + * + * The last argument of all callbacks, 'userdata', is just propagated from + * md_parse() and is available for any use by the application. + * + * Note any strings provided to the callbacks as their arguments or as + * members of any detail structure are generally not zero-terminated. + * Application has to take the respective size information into account. + * + * Any rendering callback may abort further parsing of the document by + * returning non-zero. + */ + int (*enter_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/); + int (*leave_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/); + + int (*enter_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/); + int (*leave_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/); + + int (*text)(MD_TEXTTYPE /*type*/, const MD_CHAR* /*text*/, MD_SIZE /*size*/, void* /*userdata*/); + + /* Debug callback. Optional (may be NULL). + * + * If provided and something goes wrong, this function gets called. + * This is intended for debugging and problem diagnosis for developers; + * it is not intended to provide any errors suitable for displaying to an + * end user. + */ + void (*debug_log)(const char* /*msg*/, void* /*userdata*/); + + /* Reserved. Set to NULL. + */ + void (*syntax)(void); +} MD_PARSER; + + +/* For backward compatibility. Do not use in new code. + */ +typedef MD_PARSER MD_RENDERER; + + +/* Parse the Markdown document stored in the string 'text' of size 'size'. + * The parser provides callbacks to be called during the parsing so the + * caller can render the document on the screen or convert the Markdown + * to another format. + * + * Zero is returned on success. If a runtime error occurs (e.g. a memory + * fails), -1 is returned. If the processing is aborted due any callback + * returning non-zero, the return value of the callback is returned. + */ +int md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userdata); + + +#ifdef __cplusplus + } /* extern "C" { */ +#endif + +#endif /* MD4C_H */ diff --git a/Src/Orbitersdk/CMakeLists.txt b/Src/Orbitersdk/CMakeLists.txt index 601dabd9d..bc69f0b84 100644 --- a/Src/Orbitersdk/CMakeLists.txt +++ b/Src/Orbitersdk/CMakeLists.txt @@ -23,7 +23,7 @@ set_target_properties(Orbitersdk add_custom_command(TARGET Orbitersdk POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${ORBITER_BINARY_SDK_DIR}/lib - COMMAND ${CMAKE_COMMAND} -E copy ${ORBITER_SDK_LIB} ${ORBITER_BINARY_SDK_DIR}/lib/ + COMMAND ${CMAKE_COMMAND} -E copy $ ${ORBITER_BINARY_SDK_DIR}/lib/ ) # Installation: Orbiter addon entry interface library to SDK folder to be included by addons From 00340b27e5332e6371ac6ce96cbb7bda5d61a83e Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Sun, 23 Feb 2025 17:19:30 -0600 Subject: [PATCH 31/51] Fix WinAPI messages to Launchpad --- Src/Orbiter/Orbiter.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index d9832706d..ef3e8af6a 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -1019,18 +1019,18 @@ void Orbiter::Run() { Launch(pConfig->CfgCmdlinePrm.LaunchScenario.c_str()); SDL_Event event = {}; + MSG msg; + PeekMessage (&msg, NULL, 0U, 0U, PM_NOREMOVE); + bool hadEvent; bool bpCanRender = true; - while (!ShouldQuit()) { - // Use PollMessage() if the app is active, so we can use idle time to - // render the scene. Else, use GetMessage() to avoid eating CPU time. - if (bSession) { - hadEvent = SDL_PollEvent(&event); - } else { - hadEvent = SDL_WaitEvent(&event); - } - - if (hadEvent) { + while (!ShouldQuit() && msg.message != WM_QUIT) { + if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { + if (!m_pLaunchpad || !m_pLaunchpad->ConsumeMessage(&msg)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } else if (SDL_PollEvent(&event)) { bool consumed = false; if (gclient && hRenderWnd != nullptr) { From 4b6229d5fd30b6465b98f2b6a2e0985a4640f648 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Sun, 23 Feb 2025 17:52:55 -0600 Subject: [PATCH 32/51] Remove vendored libraries These are necessary for the Launchpad, but I might go about it differently in that PR. They're not needed here though. --- Src/Orbiter/imgui_md.cpp | 912 ------ Src/Orbiter/imgui_md.h | 173 - Src/Orbiter/md4c.c | 6492 -------------------------------------- Src/Orbiter/md4c.h | 407 --- 4 files changed, 7984 deletions(-) delete mode 100644 Src/Orbiter/imgui_md.cpp delete mode 100644 Src/Orbiter/imgui_md.h delete mode 100644 Src/Orbiter/md4c.c delete mode 100644 Src/Orbiter/md4c.h diff --git a/Src/Orbiter/imgui_md.cpp b/Src/Orbiter/imgui_md.cpp deleted file mode 100644 index dddee5522..000000000 --- a/Src/Orbiter/imgui_md.cpp +++ /dev/null @@ -1,912 +0,0 @@ -/* - * imgui_md: Markdown for Dear ImGui using MD4C - * (http://https://github.com/mekhontsev/imgui_md) - * - * Copyright (c) 2021 Dmitry Mekhontsev - * - * 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 "imgui_md.h" - -#include - - -imgui_md::imgui_md() -{ - m_md.abi_version = 0; - - m_md.flags = MD_FLAG_TABLES | MD_FLAG_UNDERLINE | MD_FLAG_STRIKETHROUGH; - - m_md.enter_block = [](MD_BLOCKTYPE t, void* d, void* u) { - return ((imgui_md*)u)->block(t, d, true); - }; - - m_md.leave_block = [](MD_BLOCKTYPE t, void* d, void* u) { - return ((imgui_md*)u)->block(t, d, false); - }; - - m_md.enter_span = [](MD_SPANTYPE t, void* d, void* u) { - return ((imgui_md*)u)->span(t, d, true); - }; - - m_md.leave_span = [](MD_SPANTYPE t, void* d, void* u) { - return ((imgui_md*)u)->span(t, d, false); - }; - - m_md.text = [](MD_TEXTTYPE t, const MD_CHAR* text, MD_SIZE size, void* u) { - return ((imgui_md*)u)->text(t, text, text + size); - }; - - m_md.debug_log = nullptr; - - m_md.syntax = nullptr; - - //////////////////////////////////////////////////////////////////////////// - - m_table_last_pos = ImVec2(0, 0); - -} - -void imgui_md::BLOCK_UL(const MD_BLOCK_UL_DETAIL* d, bool e) -{ - if (e) { - m_list_stack.push_back(list_info{ 0, d->mark, false }); - } else { - m_list_stack.pop_back(); - if (m_list_stack.empty())ImGui::NewLine(); - } -} - -void imgui_md::BLOCK_OL(const MD_BLOCK_OL_DETAIL* d, bool e) -{ - if (e) { - m_list_stack.push_back(list_info{ d->start, d->mark_delimiter, true }); - } else { - m_list_stack.pop_back(); - if (m_list_stack.empty())ImGui::NewLine(); - } -} - -void imgui_md::BLOCK_LI(const MD_BLOCK_LI_DETAIL*, bool e) -{ - if (e) { - ImGui::NewLine(); - - list_info& nfo = m_list_stack.back(); - if (nfo.is_ol) { - ImGui::Text("%d%c", nfo.cur_ol++, nfo.delim); - ImGui::SameLine(); - } else { - if (nfo.delim == '*') { - float cx = ImGui::GetCursorPosX(); - cx -= ImGui::GetStyle().FramePadding.x * 2; - ImGui::SetCursorPosX(cx); - ImGui::Bullet(); - } else { - ImGui::Text("%c", nfo.delim); - ImGui::SameLine(); - } - } - - ImGui::Indent(); - } else { - ImGui::Unindent(); - } -} - -void imgui_md::BLOCK_HR(bool e) -{ - if (!e) { - ImGui::NewLine(); - ImGui::Separator(); - - } -} - -void imgui_md::BLOCK_H(const MD_BLOCK_H_DETAIL* d, bool e) -{ - if (e) { - m_hlevel = d->level; - ImGui::NewLine(); - } else { - m_hlevel = 0; - } - - set_font(e); - - if (!e) { - if (d->level <= 2) { - ImGui::NewLine(); - ImGui::Separator(); - } - } -} - -void imgui_md::BLOCK_DOC(bool) -{ - -} - -void imgui_md::BLOCK_QUOTE(bool) -{ - -} - -void imgui_md::BLOCK_CODE(const MD_BLOCK_CODE_DETAIL* detail, bool e) -{ - m_is_code_block = e; - - if (m_is_code_block) - m_code_block = ""; - else - render_code_block(); - - if (detail->lang.text == NULL) - m_code_block_language = ""; - else - m_code_block_language = std::string(detail->lang.text, detail->lang.size); -} - -void imgui_md::BLOCK_HTML(bool) -{ - -} - -void imgui_md::BLOCK_P(bool) -{ - if (!m_list_stack.empty())return; - ImGui::NewLine(); -} - -void imgui_md::BLOCK_TABLE(const MD_BLOCK_TABLE_DETAIL*, bool e) -{ - if (e) { - m_table_row_pos.clear(); - m_table_col_pos.clear(); - - m_table_last_pos = ImGui::GetCursorPos(); - } else { - - ImGui::NewLine(); - - if (m_table_border) { - - m_table_last_pos.y = ImGui::GetCursorPos().y; - - m_table_col_pos.push_back(m_table_last_pos.x); - m_table_row_pos.push_back(m_table_last_pos.y); - - const ImVec2 wp = ImGui::GetWindowPos(); - const ImVec2 sp = ImGui::GetStyle().ItemSpacing; - const float wx = wp.x + sp.x / 2; - const float wy = wp.y - sp.y / 2 - ImGui::GetScrollY(); - - for (int i = 0; i < m_table_col_pos.size(); ++i) { - m_table_col_pos[i] += wx; - } - - for (int i = 0; i < m_table_row_pos.size(); ++i) { - m_table_row_pos[i] += wy; - } - - //////////////////////////////////////////////////////////////////// - - const ImColor c = ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]; - - ImDrawList* dl = ImGui::GetWindowDrawList(); - - const float xmin = m_table_col_pos.front(); - const float xmax = m_table_col_pos.back(); - for (int i = 0; i < m_table_row_pos.size(); ++i) { - const float p = m_table_row_pos[i]; - dl->AddLine(ImVec2(xmin, p), ImVec2(xmax, p), c, - i == 1 && m_table_header_highlight ? 2.0f : 1.0f); - } - - const float ymin = m_table_row_pos.front(); - const float ymax = m_table_row_pos.back(); - for (int i = 0; i < m_table_col_pos.size(); ++i) { - const float p = m_table_col_pos[i]; - dl->AddLine(ImVec2(p, ymin), ImVec2(p, ymax), c, 1.0f); - } - } - } - - -} - -void imgui_md::BLOCK_THEAD(bool e) -{ - m_is_table_header = e; - if (m_table_header_highlight)set_font(e); -} - -void imgui_md::BLOCK_TBODY(bool e) -{ - m_is_table_body = e; -} - -void imgui_md::BLOCK_TR(bool e) -{ - ImGui::SetCursorPosY(m_table_last_pos.y); - - if (e) { - m_table_next_column = 0; - ImGui::NewLine(); - m_table_row_pos.push_back(ImGui::GetCursorPosY()); - } -} - -void imgui_md::BLOCK_TH(const MD_BLOCK_TD_DETAIL* d, bool e) -{ - BLOCK_TD(d, e); - -} - -void imgui_md::BLOCK_TD(const MD_BLOCK_TD_DETAIL*, bool e) -{ - if (e) { - - if (m_table_next_column < m_table_col_pos.size()) { - ImGui::SetCursorPosX(m_table_col_pos[m_table_next_column]); - } else { - m_table_col_pos.push_back(m_table_last_pos.x); - } - - ++m_table_next_column; - - ImGui::Indent(m_table_col_pos[m_table_next_column - 1]); - ImGui::SetCursorPos( - ImVec2(m_table_col_pos[m_table_next_column - 1], m_table_row_pos.back())); - - } else { - const ImVec2 p = ImGui::GetCursorPos(); - ImGui::Unindent(m_table_col_pos[m_table_next_column - 1]); - ImGui::SetCursorPosX(p.x); - if (p.y > m_table_last_pos.y)m_table_last_pos.y = p.y; - } - ImGui::TextUnformatted(""); - - if (!m_table_border && e && m_table_next_column==1 ) { - ImGui::SameLine(0.0f, 0.0f); - } else { - ImGui::SameLine(); - } - -} - -//////////////////////////////////////////////////////////////////////////////// -void imgui_md::set_href(bool e, const MD_ATTRIBUTE& src) -{ - if (e) { - m_href.assign(src.text, src.size); - } else { - m_href.clear(); - } -} - -void imgui_md::set_img_src(bool e, const MD_ATTRIBUTE& src) -{ - if (e) { - m_img_src.assign(src.text, src.size); - } else { - m_img_src.clear(); - } -} - - -void imgui_md::set_font(bool e) -{ - if (e) { - ImGui::PushFont(get_font()); - } else { - ImGui::PopFont(); - } -} - -void imgui_md::set_color(bool e) -{ - if (e) { - ImGui::PushStyleColor(ImGuiCol_Text, get_color()); - } else { - ImGui::PopStyleColor(); - } -} - -void imgui_md::line(ImColor c, bool under) -{ - ImVec2 mi = ImGui::GetItemRectMin(); - ImVec2 ma = ImGui::GetItemRectMax(); - - if (!under) { - ma.y -= ImGui::GetFontSize() / 2; - } - - mi.y = ma.y; - - float lineThickness = ImGui::GetFontSize() / 14.5f; - ImGui::GetWindowDrawList()->AddLine(mi, ma, c, lineThickness); -} - -void imgui_md::SPAN_A(const MD_SPAN_A_DETAIL* d, bool e) -{ - set_href(e, d->href); - set_color(e); -} - - -void imgui_md::SPAN_EM(bool e) -{ - m_is_em = e; - set_font(e); -} - -void imgui_md::SPAN_STRONG(bool e) -{ - m_is_strong = e; - set_font(e); -} - - -void imgui_md::SPAN_IMG(const MD_SPAN_IMG_DETAIL* d, bool e) -{ - m_is_image = e; - - set_img_src(e, d->src); - - if (e) { - - image_info nfo; - if (get_image(nfo)) { - - const float scale = ImGui::GetIO().FontGlobalScale; - nfo.size.x *= scale; - nfo.size.y *= scale; - - - ImVec2 const csz = ImGui::GetContentRegionAvail(); - if (nfo.size.x > csz.x) { - const float r = nfo.size.y / nfo.size.x; - nfo.size.x = csz.x; - nfo.size.y = csz.x * r; - } - - ImGui::Image(nfo.texture_id, nfo.size, nfo.uv0, nfo.uv1, nfo.col_tint, nfo.col_border); - ImGui::SameLine(); - - if (ImGui::IsItemHovered()) { - - //if (d->title.size) { - // ImGui::SetTooltip("%.*s", (int)d->title.size, d->title.text); - //} - - if (ImGui::IsMouseClicked(0)) { - open_url(); - } - } - } - } -} - -void imgui_md::SPAN_CODE(bool) -{ - -} - - -void imgui_md::SPAN_LATEXMATH(bool) -{ - -} - -void imgui_md::SPAN_LATEXMATH_DISPLAY(bool) -{ - -} - -void imgui_md::SPAN_WIKILINK(const MD_SPAN_WIKILINK_DETAIL*, bool) -{ - -} - -void imgui_md::SPAN_U(bool e) -{ - m_is_underline = e; -} - -void imgui_md::SPAN_DEL(bool e) -{ - m_is_strikethrough = e; -} - -void imgui_md::render_text(const char* str, const char* str_end) -{ - const float scale = ImGui::GetIO().FontGlobalScale; - const ImGuiStyle& s = ImGui::GetStyle(); - bool is_lf = false; - - while (!m_is_image && str < str_end) { - - const char* te = str_end; - - if (!m_is_table_header) { - - float wl = ImGui::GetContentRegionAvail().x; - - if (m_is_table_body) { - wl = (m_table_next_column < m_table_col_pos.size() ? - m_table_col_pos[m_table_next_column] : m_table_last_pos.x); - wl -= ImGui::GetCursorPosX(); - } - - te = ImGui::GetFont()->CalcWordWrapPositionA( - scale, str, str_end, wl); - - if (te == str)++te; - } - - - ImGui::TextUnformatted(str, te); - - if (te > str && *(te - 1) == '\n') { - is_lf = true; - } - - if (!m_href.empty()) { - - ImVec4 c; - if (ImGui::IsItemHovered()) { - - ImGui::SetTooltip("%s", m_href.c_str()); - c = ImVec4(0.451f, 0.69f, 0.984f, 1.00f); - if (ImGui::IsMouseClicked(0)) { - open_url(); - } - } else { - c = s.Colors[ImGuiCol_TextLink]; - } - line(c, true); - } - if (m_is_underline) { - line(s.Colors[ImGuiCol_Text], true); - } - if (m_is_strikethrough) { - line(s.Colors[ImGuiCol_Text], false); - } - - str = te; - - while (str < str_end && *str == ' ')++str; - } - - if (!is_lf) - { - ImGui::SameLine(0.0f, 0.0f); - } -} - - -bool imgui_md::render_entity(const char* str, const char* str_end) -{ - const size_t sz = str_end - str; - if (strncmp(str, " ", sz) == 0) { - ImGui::TextUnformatted(""); ImGui::SameLine(); - return true; - } - return false; -} - -static bool skip_spaces(const std::string& d, size_t& p) -{ - for (; p < d.length(); ++p) { - if (d[p] != ' ' && d[p] != '\t') { - break; - } - } - return p < d.length(); -} - -static std::string get_div_class(const char* str, const char* str_end) -{ - if (str_end <= str)return ""; - - std::string d(str, str_end - str); - if (d.back() == '>')d.pop_back(); - - const char attr[] = "class"; - size_t p = d.find(attr); - if (p == std::string::npos)return ""; - p += sizeof(attr)-1; - - if (!skip_spaces(d, p))return ""; - - if (d[p] != '=')return ""; - ++p; - - if (!skip_spaces(d, p))return ""; - - bool has_q = false; - - if (d[p] == '"' || d[p] == '\'') { - has_q = true; - ++p; - } - if (p == d.length())return ""; - - if (!has_q) { - if (!skip_spaces(d, p))return ""; - } - - size_t pe; - for (pe = p; pe < d.length(); ++pe) { - - const char c = d[pe]; - - if (has_q) { - if (c == '"' || c == '\'') { - break; - } - } else { - if (c == ' ' || c == '\t') { - break; - } - } - } - - return d.substr(p, pe - p); - -} - -bool imgui_md::check_html(const char* str, const char* str_end) -{ - const size_t sz = str_end - str; - - if (strncmp(str, "
    ", sz) == 0) { - ImGui::NewLine(); - return true; - } - if (strncmp(str, "
    ", sz) == 0) { - ImGui::Separator(); - return true; - } - if (strncmp(str, "", sz) == 0) { - m_is_underline = true; - return true; - } - if (strncmp(str, "", sz) == 0) { - m_is_underline = false; - return true; - } - - const size_t div_sz = 4; - if (strncmp(str, " div_sz ? div_sz : sz) == 0) { - m_div_stack.emplace_back(get_div_class(str + div_sz, str_end)); - html_div(m_div_stack.back(), true); - return true; - } - if (strncmp(str, "", sz) == 0) { - if (m_div_stack.empty())return false; - html_div(m_div_stack.back(), false); - m_div_stack.pop_back(); - return true; - } - return false; -} - - -void imgui_md::html_div(const std::string& dclass, bool e) -{ - //Example: -#if 0 - if (dclass == "red") { - if (e) { - ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255)); - } else { - ImGui::PopStyleColor(); - } - } -#endif - (void)dclass; (void)e; -} - -void imgui_md::render_code_block() -{ - m_is_code = true; - push_code_style(); - - const char* begin = m_code_block.data(); - const char *end = m_code_block.data() + m_code_block.size(); - render_text(begin, end); - - pop_code_style(); - m_is_code = false; -} - -void imgui_md::push_code_style() -{ - ImGui::PushFont(get_font()); - - // Make code a little more blue - auto color = ImGui::GetStyle().Colors[ImGuiCol_Text]; - color.z *= 1.15f; - ImGui::PushStyleColor(ImGuiCol_Text, color); - -} -void imgui_md::pop_code_style() -{ - ImGui::PopStyleColor(); - ImGui::PopFont(); -} - - -void imgui_md::render_inline_code(const char *str, const char *str_end) -{ - m_is_code = true; - push_code_style(); - render_text(str, str_end); - pop_code_style(); - m_is_code = false; -} - -int imgui_md::text(MD_TEXTTYPE type, const char* str, const char* str_end) -{ - switch (type) { - case MD_TEXT_NORMAL: - render_text(str, str_end); - break; - case MD_TEXT_CODE: - if (m_is_code_block) - m_code_block += std::string(str, str_end); - else - render_inline_code(str, str_end); - break; - case MD_TEXT_NULLCHAR: - break; - case MD_TEXT_BR: - ImGui::NewLine(); - break; - case MD_TEXT_SOFTBR: - soft_break(); - break; - case MD_TEXT_ENTITY: - if (!render_entity(str, str_end)) { - render_text(str, str_end); - }; - break; - case MD_TEXT_HTML: - if (!check_html(str, str_end)) { - render_text(str, str_end); - } - break; - case MD_TEXT_LATEXMATH: - render_text(str, str_end); - break; - default: - break; - } - - if (m_is_table_header) { - const float x = ImGui::GetCursorPosX(); - if (x > m_table_last_pos.x)m_table_last_pos.x = x; - } - - return 0; -} - -int imgui_md::block(MD_BLOCKTYPE type, void* d, bool e) -{ - switch (type) - { - case MD_BLOCK_DOC: - BLOCK_DOC(e); - break; - case MD_BLOCK_QUOTE: - BLOCK_QUOTE(e); - break; - case MD_BLOCK_UL: - BLOCK_UL((MD_BLOCK_UL_DETAIL*)d, e); - break; - case MD_BLOCK_OL: - BLOCK_OL((MD_BLOCK_OL_DETAIL*)d, e); - break; - case MD_BLOCK_LI: - BLOCK_LI((MD_BLOCK_LI_DETAIL*)d, e); - break; - case MD_BLOCK_HR: - BLOCK_HR(e); - break; - case MD_BLOCK_H: - BLOCK_H((MD_BLOCK_H_DETAIL*)d, e); - break; - case MD_BLOCK_CODE: - BLOCK_CODE((MD_BLOCK_CODE_DETAIL*)d, e); - break; - case MD_BLOCK_HTML: - BLOCK_HTML(e); - break; - case MD_BLOCK_P: - BLOCK_P(e); - break; - case MD_BLOCK_TABLE: - BLOCK_TABLE((MD_BLOCK_TABLE_DETAIL*)d, e); - break; - case MD_BLOCK_THEAD: - BLOCK_THEAD(e); - break; - case MD_BLOCK_TBODY: - BLOCK_TBODY(e); - break; - case MD_BLOCK_TR: - BLOCK_TR(e); - break; - case MD_BLOCK_TH: - BLOCK_TH((MD_BLOCK_TD_DETAIL*)d, e); - break; - case MD_BLOCK_TD: - BLOCK_TD((MD_BLOCK_TD_DETAIL*)d, e); - break; - default: - assert(false); - break; - } - - return 0; -} - -int imgui_md::span(MD_SPANTYPE type, void* d, bool e) -{ - switch (type) - { - case MD_SPAN_EM: - SPAN_EM(e); - break; - case MD_SPAN_STRONG: - SPAN_STRONG(e); - break; - case MD_SPAN_A: - SPAN_A((MD_SPAN_A_DETAIL*)d, e); - break; - case MD_SPAN_IMG: - SPAN_IMG((MD_SPAN_IMG_DETAIL*)d, e); - break; - case MD_SPAN_CODE: - SPAN_CODE(e); - break; - case MD_SPAN_DEL: - SPAN_DEL(e); - break; - case MD_SPAN_LATEXMATH: - SPAN_LATEXMATH(e); - break; - case MD_SPAN_LATEXMATH_DISPLAY: - SPAN_LATEXMATH_DISPLAY(e); - break; - case MD_SPAN_WIKILINK: - SPAN_WIKILINK((MD_SPAN_WIKILINK_DETAIL*)d, e); - break; - case MD_SPAN_U: - SPAN_U(e); - break; - default: - assert(false); - break; - } - - return 0; -} - -int imgui_md::print(const char* str, const char* str_end) -{ - if (str >= str_end) - return 0; - - // Markdown rendering always start with a call to ImGui::NewLine() - ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetFontSize() - ImGui::GetStyle().FramePadding.y); - return md_parse(str, (MD_SIZE)(str_end - str), &m_md, this); -} - -//////////////////////////////////////////////////////////////////////////////// - -ImFont* imgui_md::get_font() const -{ - return nullptr;//default font - - //Example: -#if 0 - if (m_is_table_header) { - return g_font_bold; - } - - switch (m_hlevel) - { - case 0: - return m_is_strong ? g_font_bold : g_font_regular; - case 1: - return g_font_bold_large; - default: - return g_font_bold; - } -#endif - -}; - -ImVec4 LinkColor() -{ - auto col_text = ImGui::GetStyle().Colors[ImGuiCol_Text]; - - float h, s, v; - ImGui::ColorConvertRGBtoHSV(col_text.x, col_text.y, col_text.z, h, s, v); - h = 0.57f; - if (v >= 0.8f) - v = 0.8f; - if (v <= 0.5f) - v = 0.5f; - if (s <= 0.5f) - s = 0.5f; - - ImGui::ColorConvertHSVtoRGB(h, s, v, col_text.x, col_text.y, col_text.z); - return col_text; -} - - -ImVec4 imgui_md::get_color() const -{ - if (!m_href.empty()) - { - return LinkColor(); - } - return ImGui::GetStyle().Colors[ImGuiCol_Text]; -} - - -bool imgui_md::get_image(image_info& nfo) const -{ - //Use m_href to identify images - - //Example - Imgui font texture - nfo.texture_id = ImGui::GetIO().Fonts->TexID; - nfo.size = { 100,50 }; - nfo.uv0 = { 0,0 }; - nfo.uv1 = { 1,1 }; - nfo.col_tint = { 1,1,1,1 }; - nfo.col_border = { 0,0,0,0 }; - - return true; -}; - -void imgui_md::open_url() const -{ - //Example: - -#if 0 - if (!m_is_image) { - SDL_OpenURL(m_href.c_str()); - } else { - //image clicked - } -#endif -} - -void imgui_md::soft_break() -{ - // Convert a soft break (e.g. a new line inside a paragraph into a space) - ImGui::TextUnformatted(" "); - ImGui::SameLine(0.0f, 0.0f); -} diff --git a/Src/Orbiter/imgui_md.h b/Src/Orbiter/imgui_md.h deleted file mode 100644 index 44d7e1168..000000000 --- a/Src/Orbiter/imgui_md.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * imgui_md: Markdown for Dear ImGui using MD4C - * (http://https://github.com/mekhontsev/imgui_md) - * - * Copyright (c) 2021 Dmitry Mekhontsev - * - * 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 IMGUI_MD_H -#define IMGUI_MD_H - -#include "md4c.h" -#include "imgui.h" -#include -#include - -struct imgui_md -{ - imgui_md(); - virtual ~imgui_md() {}; - - //returns 0 on success - int print(const char* str, const char* str_end); - - //for example, these flags can be changed in div callback - - //draw border - bool m_table_border = true; - //render header in a different way than other rows - bool m_table_header_highlight = true; - -protected: - - virtual void BLOCK_DOC(bool); - virtual void BLOCK_QUOTE(bool); - virtual void BLOCK_UL(const MD_BLOCK_UL_DETAIL*, bool); - virtual void BLOCK_OL(const MD_BLOCK_OL_DETAIL*, bool); - virtual void BLOCK_LI(const MD_BLOCK_LI_DETAIL*, bool); - virtual void BLOCK_HR(bool e); - virtual void BLOCK_H(const MD_BLOCK_H_DETAIL* d, bool e); - virtual void BLOCK_CODE(const MD_BLOCK_CODE_DETAIL*, bool); - virtual void BLOCK_HTML(bool); - virtual void BLOCK_P(bool); - virtual void BLOCK_TABLE(const MD_BLOCK_TABLE_DETAIL*, bool); - virtual void BLOCK_THEAD(bool); - virtual void BLOCK_TBODY(bool); - virtual void BLOCK_TR(bool); - virtual void BLOCK_TH(const MD_BLOCK_TD_DETAIL*, bool); - virtual void BLOCK_TD(const MD_BLOCK_TD_DETAIL*, bool); - - virtual void SPAN_EM(bool e); - virtual void SPAN_STRONG(bool e); - virtual void SPAN_A(const MD_SPAN_A_DETAIL* d, bool e); - virtual void SPAN_IMG(const MD_SPAN_IMG_DETAIL*, bool); - virtual void SPAN_CODE(bool); - virtual void SPAN_DEL(bool); - virtual void SPAN_LATEXMATH(bool); - virtual void SPAN_LATEXMATH_DISPLAY(bool); - virtual void SPAN_WIKILINK(const MD_SPAN_WIKILINK_DETAIL*, bool); - virtual void SPAN_U(bool); - - //////////////////////////////////////////////////////////////////////////// - - struct image_info - { - ImTextureID texture_id; - ImVec2 size; - ImVec2 uv0; - ImVec2 uv1; - ImVec4 col_tint; - ImVec4 col_border; - }; - - //use m_href to identify image - virtual bool get_image(image_info& nfo) const; - - virtual ImFont* get_font() const; - virtual ImVec4 get_color() const; - - // By default, code blocks are rendered as text with the code font, but you can override this - virtual void render_code_block(); - - //url == m_href - virtual void open_url() const; - - //returns true if the term has been processed - virtual bool render_entity(const char* str, const char* str_end); - - //returns true if the term has been processed - virtual bool check_html(const char* str, const char* str_end); - - //called when '\n' in source text where it is not semantically meaningful - virtual void soft_break(); - - //e==true : enter - //e==false : leave - virtual void html_div(const std::string& dclass, bool e); - //////////////////////////////////////////////////////////////////////////// - - virtual void push_code_style(); - virtual void pop_code_style(); - - //current state - std::string m_href;//empty if no link/image - std::string m_img_src;//empty if no link/image - - bool m_is_underline=false; - bool m_is_strikethrough = false; - bool m_is_em = false; - bool m_is_strong = false; - bool m_is_table_header = false; - bool m_is_table_body = false; - bool m_is_image = false; - bool m_is_code = false; // true for block code and inline code - bool m_is_code_block = false; - std::string m_code_block_language; - std::string m_code_block; - unsigned m_hlevel=0;//0 - no heading - -private: - - int text(MD_TEXTTYPE type, const char* str, const char* str_end); - int block(MD_BLOCKTYPE type, void* d, bool e); - int span(MD_SPANTYPE type, void* d, bool e); - - void render_text(const char* str, const char* str_end); - void render_inline_code(const char* str, const char* str_end); - - void set_font(bool e); - void set_color(bool e); - void set_href(bool e, const MD_ATTRIBUTE& src); - void set_img_src(bool e, const MD_ATTRIBUTE& src); - - static void line(ImColor c, bool under); - - //table state - int m_table_next_column = 0; - ImVec2 m_table_last_pos; - std::vector m_table_col_pos; - std::vector m_table_row_pos; - - //list state - struct list_info - { - unsigned cur_ol; - char delim; - bool is_ol; - }; - std::vector m_list_stack; - - std::vector m_div_stack; - - MD_PARSER m_md; -}; - -#endif /* IMGUI_MD_H */ \ No newline at end of file diff --git a/Src/Orbiter/md4c.c b/Src/Orbiter/md4c.c deleted file mode 100644 index e3f5cf9d0..000000000 --- a/Src/Orbiter/md4c.c +++ /dev/null @@ -1,6492 +0,0 @@ -/* - * MD4C: Markdown parser for C - * (http://github.com/mity/md4c) - * - * Copyright (c) 2016-2024 Martin Mitáš - * - * 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 "md4c.h" - -#include -#include -#include -#include -#include - - -/***************************** - *** Miscellaneous Stuff *** - *****************************/ - -#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199409L - /* C89/90 or old compilers in general may not understand "inline". */ - #if defined __GNUC__ - #define inline __inline__ - #elif defined _MSC_VER - #define inline __inline - #else - #define inline - #endif -#endif - -/* Make the UTF-8 support the default. */ -#if !defined MD4C_USE_ASCII && !defined MD4C_USE_UTF8 && !defined MD4C_USE_UTF16 - #define MD4C_USE_UTF8 -#endif - -/* Magic for making wide literals with MD4C_USE_UTF16. */ -#ifdef _T - #undef _T -#endif -#if defined MD4C_USE_UTF16 - #define _T(x) L##x -#else - #define _T(x) x -#endif - -/* Misc. macros. */ -#define SIZEOF_ARRAY(a) (sizeof(a) / sizeof(a[0])) - -#define STRINGIZE_(x) #x -#define STRINGIZE(x) STRINGIZE_(x) - -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -#ifndef TRUE - #define TRUE 1 - #define FALSE 0 -#endif - -#define MD_LOG(msg) \ - do { \ - if(ctx->parser.debug_log != NULL) \ - ctx->parser.debug_log((msg), ctx->userdata); \ - } while(0) - -#ifdef DEBUG - #define MD_ASSERT(cond) \ - do { \ - if(!(cond)) { \ - MD_LOG(__FILE__ ":" STRINGIZE(__LINE__) ": " \ - "Assertion '" STRINGIZE(cond) "' failed."); \ - exit(1); \ - } \ - } while(0) - - #define MD_UNREACHABLE() MD_ASSERT(1 == 0) -#else - #ifdef __GNUC__ - #define MD_ASSERT(cond) do { if(!(cond)) __builtin_unreachable(); } while(0) - #define MD_UNREACHABLE() do { __builtin_unreachable(); } while(0) - #elif defined _MSC_VER && _MSC_VER > 120 - #define MD_ASSERT(cond) do { __assume(cond); } while(0) - #define MD_UNREACHABLE() do { __assume(0); } while(0) - #else - #define MD_ASSERT(cond) do {} while(0) - #define MD_UNREACHABLE() do {} while(0) - #endif -#endif - -/* For falling through case labels in switch statements. */ -#if defined __clang__ && __clang_major__ >= 12 - #define MD_FALLTHROUGH() __attribute__((fallthrough)) -#elif defined __GNUC__ && __GNUC__ >= 7 - #define MD_FALLTHROUGH() __attribute__((fallthrough)) -#else - #define MD_FALLTHROUGH() ((void)0) -#endif - -/* Suppress "unused parameter" warnings. */ -#define MD_UNUSED(x) ((void)x) - - -/****************************** - *** Some internal limits *** - ******************************/ - -/* We limit code span marks to lower than 32 backticks. This solves the - * pathologic case of too many openers, each of different length: Their - * resolving would be then O(n^2). */ -#define CODESPAN_MARK_MAXLEN 32 - -/* We limit column count of tables to prevent quadratic explosion of output - * from pathological input of a table thousands of columns and thousands - * of rows where rows are requested with as little as single character - * per-line, relying on us to "helpfully" fill all the missing "". */ -#define TABLE_MAXCOLCOUNT 128 - - -/************************ - *** Internal Types *** - ************************/ - -/* These are omnipresent so lets save some typing. */ -#define CHAR MD_CHAR -#define SZ MD_SIZE -#define OFF MD_OFFSET - -#define SZ_MAX (sizeof(SZ) == 8 ? UINT64_MAX : UINT32_MAX) -#define OFF_MAX (sizeof(OFF) == 8 ? UINT64_MAX : UINT32_MAX) - -typedef struct MD_MARK_tag MD_MARK; -typedef struct MD_BLOCK_tag MD_BLOCK; -typedef struct MD_CONTAINER_tag MD_CONTAINER; -typedef struct MD_REF_DEF_tag MD_REF_DEF; - - -/* During analyzes of inline marks, we need to manage stacks of unresolved - * openers of the given type. - * The stack connects the marks via MD_MARK::next; - */ -typedef struct MD_MARKSTACK_tag MD_MARKSTACK; -struct MD_MARKSTACK_tag { - int top; /* -1 if empty. */ -}; - -/* Context propagated through all the parsing. */ -typedef struct MD_CTX_tag MD_CTX; -struct MD_CTX_tag { - /* Immutable stuff (parameters of md_parse()). */ - const CHAR* text; - SZ size; - MD_PARSER parser; - void* userdata; - - /* When this is true, it allows some optimizations. */ - int doc_ends_with_newline; - - /* Helper temporary growing buffer. */ - CHAR* buffer; - unsigned alloc_buffer; - - /* Reference definitions. */ - MD_REF_DEF* ref_defs; - int n_ref_defs; - int alloc_ref_defs; - void** ref_def_hashtable; - int ref_def_hashtable_size; - SZ max_ref_def_output; - - /* Stack of inline/span markers. - * This is only used for parsing a single block contents but by storing it - * here we may reuse the stack for subsequent blocks; i.e. we have fewer - * (re)allocations. */ - MD_MARK* marks; - int n_marks; - int alloc_marks; - -#if defined MD4C_USE_UTF16 - char mark_char_map[128]; -#else - char mark_char_map[256]; -#endif - - /* For resolving of inline spans. */ - MD_MARKSTACK opener_stacks[16]; -#define ASTERISK_OPENERS_oo_mod3_0 (ctx->opener_stacks[0]) /* Opener-only */ -#define ASTERISK_OPENERS_oo_mod3_1 (ctx->opener_stacks[1]) -#define ASTERISK_OPENERS_oo_mod3_2 (ctx->opener_stacks[2]) -#define ASTERISK_OPENERS_oc_mod3_0 (ctx->opener_stacks[3]) /* Both opener and closer candidate */ -#define ASTERISK_OPENERS_oc_mod3_1 (ctx->opener_stacks[4]) -#define ASTERISK_OPENERS_oc_mod3_2 (ctx->opener_stacks[5]) -#define UNDERSCORE_OPENERS_oo_mod3_0 (ctx->opener_stacks[6]) /* Opener-only */ -#define UNDERSCORE_OPENERS_oo_mod3_1 (ctx->opener_stacks[7]) -#define UNDERSCORE_OPENERS_oo_mod3_2 (ctx->opener_stacks[8]) -#define UNDERSCORE_OPENERS_oc_mod3_0 (ctx->opener_stacks[9]) /* Both opener and closer candidate */ -#define UNDERSCORE_OPENERS_oc_mod3_1 (ctx->opener_stacks[10]) -#define UNDERSCORE_OPENERS_oc_mod3_2 (ctx->opener_stacks[11]) -#define TILDE_OPENERS_1 (ctx->opener_stacks[12]) -#define TILDE_OPENERS_2 (ctx->opener_stacks[13]) -#define BRACKET_OPENERS (ctx->opener_stacks[14]) -#define DOLLAR_OPENERS (ctx->opener_stacks[15]) - - /* Stack of dummies which need to call free() for pointers stored in them. - * These are constructed during inline parsing and freed after all the block - * is processed (i.e. all callbacks referring those strings are called). */ - MD_MARKSTACK ptr_stack; - - /* For resolving table rows. */ - int n_table_cell_boundaries; - int table_cell_boundaries_head; - int table_cell_boundaries_tail; - - /* For resolving links. */ - int unresolved_link_head; - int unresolved_link_tail; - - /* For resolving raw HTML. */ - OFF html_comment_horizon; - OFF html_proc_instr_horizon; - OFF html_decl_horizon; - OFF html_cdata_horizon; - - /* For block analysis. - * Notes: - * -- It holds MD_BLOCK as well as MD_LINE structures. After each - * MD_BLOCK, its (multiple) MD_LINE(s) follow. - * -- For MD_BLOCK_HTML and MD_BLOCK_CODE, MD_VERBATIMLINE(s) are used - * instead of MD_LINE(s). - */ - void* block_bytes; - MD_BLOCK* current_block; - int n_block_bytes; - int alloc_block_bytes; - - /* For container block analysis. */ - MD_CONTAINER* containers; - int n_containers; - int alloc_containers; - - /* Minimal indentation to call the block "indented code block". */ - unsigned code_indent_offset; - - /* Contextual info for line analysis. */ - SZ code_fence_length; /* For checking closing fence length. */ - int html_block_type; /* For checking closing raw HTML condition. */ - int last_line_has_list_loosening_effect; - int last_list_item_starts_with_two_blank_lines; -}; - -enum MD_LINETYPE_tag { - MD_LINE_BLANK, - MD_LINE_HR, - MD_LINE_ATXHEADER, - MD_LINE_SETEXTHEADER, - MD_LINE_SETEXTUNDERLINE, - MD_LINE_INDENTEDCODE, - MD_LINE_FENCEDCODE, - MD_LINE_HTML, - MD_LINE_TEXT, - MD_LINE_TABLE, - MD_LINE_TABLEUNDERLINE -}; -typedef enum MD_LINETYPE_tag MD_LINETYPE; - -typedef struct MD_LINE_ANALYSIS_tag MD_LINE_ANALYSIS; -struct MD_LINE_ANALYSIS_tag { - MD_LINETYPE type; - unsigned data; - int enforce_new_block; - OFF beg; - OFF end; - unsigned indent; /* Indentation level. */ -}; - -typedef struct MD_LINE_tag MD_LINE; -struct MD_LINE_tag { - OFF beg; - OFF end; -}; - -typedef struct MD_VERBATIMLINE_tag MD_VERBATIMLINE; -struct MD_VERBATIMLINE_tag { - OFF beg; - OFF end; - OFF indent; -}; - - -/***************** - *** Helpers *** - *****************/ - -/* Character accessors. */ -#define CH(off) (ctx->text[(off)]) -#define STR(off) (ctx->text + (off)) - -/* Character classification. - * Note we assume ASCII compatibility of code points < 128 here. */ -#define ISIN_(ch, ch_min, ch_max) ((ch_min) <= (unsigned)(ch) && (unsigned)(ch) <= (ch_max)) -#define ISANYOF_(ch, palette) ((ch) != _T('\0') && md_strchr((palette), (ch)) != NULL) -#define ISANYOF2_(ch, ch1, ch2) ((ch) == (ch1) || (ch) == (ch2)) -#define ISANYOF3_(ch, ch1, ch2, ch3) ((ch) == (ch1) || (ch) == (ch2) || (ch) == (ch3)) -#define ISASCII_(ch) ((unsigned)(ch) <= 127) -#define ISBLANK_(ch) (ISANYOF2_((ch), _T(' '), _T('\t'))) -#define ISNEWLINE_(ch) (ISANYOF2_((ch), _T('\r'), _T('\n'))) -#define ISWHITESPACE_(ch) (ISBLANK_(ch) || ISANYOF2_((ch), _T('\v'), _T('\f'))) -#define ISCNTRL_(ch) ((unsigned)(ch) <= 31 || (unsigned)(ch) == 127) -#define ISPUNCT_(ch) (ISIN_(ch, 33, 47) || ISIN_(ch, 58, 64) || ISIN_(ch, 91, 96) || ISIN_(ch, 123, 126)) -#define ISUPPER_(ch) (ISIN_(ch, _T('A'), _T('Z'))) -#define ISLOWER_(ch) (ISIN_(ch, _T('a'), _T('z'))) -#define ISALPHA_(ch) (ISUPPER_(ch) || ISLOWER_(ch)) -#define ISDIGIT_(ch) (ISIN_(ch, _T('0'), _T('9'))) -#define ISXDIGIT_(ch) (ISDIGIT_(ch) || ISIN_(ch, _T('A'), _T('F')) || ISIN_(ch, _T('a'), _T('f'))) -#define ISALNUM_(ch) (ISALPHA_(ch) || ISDIGIT_(ch)) - -#define ISANYOF(off, palette) ISANYOF_(CH(off), (palette)) -#define ISANYOF2(off, ch1, ch2) ISANYOF2_(CH(off), (ch1), (ch2)) -#define ISANYOF3(off, ch1, ch2, ch3) ISANYOF3_(CH(off), (ch1), (ch2), (ch3)) -#define ISASCII(off) ISASCII_(CH(off)) -#define ISBLANK(off) ISBLANK_(CH(off)) -#define ISNEWLINE(off) ISNEWLINE_(CH(off)) -#define ISWHITESPACE(off) ISWHITESPACE_(CH(off)) -#define ISCNTRL(off) ISCNTRL_(CH(off)) -#define ISPUNCT(off) ISPUNCT_(CH(off)) -#define ISUPPER(off) ISUPPER_(CH(off)) -#define ISLOWER(off) ISLOWER_(CH(off)) -#define ISALPHA(off) ISALPHA_(CH(off)) -#define ISDIGIT(off) ISDIGIT_(CH(off)) -#define ISXDIGIT(off) ISXDIGIT_(CH(off)) -#define ISALNUM(off) ISALNUM_(CH(off)) - - -#if defined MD4C_USE_UTF16 - #define md_strchr wcschr -#else - #define md_strchr strchr -#endif - - -/* Case insensitive check of string equality. */ -static inline int -md_ascii_case_eq(const CHAR* s1, const CHAR* s2, SZ n) -{ - OFF i; - for(i = 0; i < n; i++) { - CHAR ch1 = s1[i]; - CHAR ch2 = s2[i]; - - if(ISLOWER_(ch1)) - ch1 += ('A'-'a'); - if(ISLOWER_(ch2)) - ch2 += ('A'-'a'); - if(ch1 != ch2) - return FALSE; - } - return TRUE; -} - -static inline int -md_ascii_eq(const CHAR* s1, const CHAR* s2, SZ n) -{ - return memcmp(s1, s2, n * sizeof(CHAR)) == 0; -} - -static int -md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ size) -{ - OFF off = 0; - int ret = 0; - - while(1) { - while(off < size && str[off] != _T('\0')) - off++; - - if(off > 0) { - ret = ctx->parser.text(type, str, off, ctx->userdata); - if(ret != 0) - return ret; - - str += off; - size -= off; - off = 0; - } - - if(off >= size) - return 0; - - ret = ctx->parser.text(MD_TEXT_NULLCHAR, _T(""), 1, ctx->userdata); - if(ret != 0) - return ret; - off++; - } -} - - -#define MD_CHECK(func) \ - do { \ - ret = (func); \ - if(ret < 0) \ - goto abort; \ - } while(0) - - -#define MD_TEMP_BUFFER(sz) \ - do { \ - if(sz > ctx->alloc_buffer) { \ - CHAR* new_buffer; \ - SZ new_size = ((sz) + (sz) / 2 + 128) & ~127; \ - \ - new_buffer = realloc(ctx->buffer, new_size); \ - if(new_buffer == NULL) { \ - MD_LOG("realloc() failed."); \ - ret = -1; \ - goto abort; \ - } \ - \ - ctx->buffer = new_buffer; \ - ctx->alloc_buffer = new_size; \ - } \ - } while(0) - - -#define MD_ENTER_BLOCK(type, arg) \ - do { \ - ret = ctx->parser.enter_block((type), (arg), ctx->userdata); \ - if(ret != 0) { \ - MD_LOG("Aborted from enter_block() callback."); \ - goto abort; \ - } \ - } while(0) - -#define MD_LEAVE_BLOCK(type, arg) \ - do { \ - ret = ctx->parser.leave_block((type), (arg), ctx->userdata); \ - if(ret != 0) { \ - MD_LOG("Aborted from leave_block() callback."); \ - goto abort; \ - } \ - } while(0) - -#define MD_ENTER_SPAN(type, arg) \ - do { \ - ret = ctx->parser.enter_span((type), (arg), ctx->userdata); \ - if(ret != 0) { \ - MD_LOG("Aborted from enter_span() callback."); \ - goto abort; \ - } \ - } while(0) - -#define MD_LEAVE_SPAN(type, arg) \ - do { \ - ret = ctx->parser.leave_span((type), (arg), ctx->userdata); \ - if(ret != 0) { \ - MD_LOG("Aborted from leave_span() callback."); \ - goto abort; \ - } \ - } while(0) - -#define MD_TEXT(type, str, size) \ - do { \ - if(size > 0) { \ - ret = ctx->parser.text((type), (str), (size), ctx->userdata); \ - if(ret != 0) { \ - MD_LOG("Aborted from text() callback."); \ - goto abort; \ - } \ - } \ - } while(0) - -#define MD_TEXT_INSECURE(type, str, size) \ - do { \ - if(size > 0) { \ - ret = md_text_with_null_replacement(ctx, type, str, size); \ - if(ret != 0) { \ - MD_LOG("Aborted from text() callback."); \ - goto abort; \ - } \ - } \ - } while(0) - - -/* If the offset falls into a gap between line, we return the following - * line. */ -static const MD_LINE* -md_lookup_line(OFF off, const MD_LINE* lines, MD_SIZE n_lines, MD_SIZE* p_line_index) -{ - MD_SIZE lo, hi; - MD_SIZE pivot; - const MD_LINE* line; - - lo = 0; - hi = n_lines - 1; - while(lo <= hi) { - pivot = (lo + hi) / 2; - line = &lines[pivot]; - - if(off < line->beg) { - if(hi == 0 || lines[hi-1].end < off) { - if(p_line_index != NULL) - *p_line_index = pivot; - return line; - } - hi = pivot - 1; - } else if(off > line->end) { - lo = pivot + 1; - } else { - if(p_line_index != NULL) - *p_line_index = pivot; - return line; - } - } - - return NULL; -} - - -/************************* - *** Unicode Support *** - *************************/ - -typedef struct MD_UNICODE_FOLD_INFO_tag MD_UNICODE_FOLD_INFO; -struct MD_UNICODE_FOLD_INFO_tag { - unsigned codepoints[3]; - unsigned n_codepoints; -}; - - -#if defined MD4C_USE_UTF16 || defined MD4C_USE_UTF8 - /* Binary search over sorted "map" of codepoints. Consecutive sequences - * of codepoints may be encoded in the map by just using the - * (MIN_CODEPOINT | 0x40000000) and (MAX_CODEPOINT | 0x80000000). - * - * Returns index of the found record in the map (in the case of ranges, - * the minimal value is used); or -1 on failure. */ - static int - md_unicode_bsearch__(unsigned codepoint, const unsigned* map, size_t map_size) - { - int beg, end; - int pivot_beg, pivot_end; - - beg = 0; - end = (int) map_size-1; - while(beg <= end) { - /* Pivot may be a range, not just a single value. */ - pivot_beg = pivot_end = (beg + end) / 2; - if(map[pivot_end] & 0x40000000) - pivot_end++; - if(map[pivot_beg] & 0x80000000) - pivot_beg--; - - if(codepoint < (map[pivot_beg] & 0x00ffffff)) - end = pivot_beg - 1; - else if(codepoint > (map[pivot_end] & 0x00ffffff)) - beg = pivot_end + 1; - else - return pivot_beg; - } - - return -1; - } - - static int - md_is_unicode_whitespace__(unsigned codepoint) - { -#define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) -#define S(cp) (cp) - /* Unicode "Zs" category. - * (generated by scripts/build_whitespace_map.py) */ - static const unsigned WHITESPACE_MAP[] = { - S(0x0020), S(0x00a0), S(0x1680), R(0x2000,0x200a), S(0x202f), S(0x205f), S(0x3000) - }; -#undef R -#undef S - - /* The ASCII ones are the most frequently used ones, also CommonMark - * specification requests few more in this range. */ - if(codepoint <= 0x7f) - return ISWHITESPACE_(codepoint); - - return (md_unicode_bsearch__(codepoint, WHITESPACE_MAP, SIZEOF_ARRAY(WHITESPACE_MAP)) >= 0); - } - - static int - md_is_unicode_punct__(unsigned codepoint) - { -#define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) -#define S(cp) (cp) - /* Unicode general "P" and "S" categories. - * (generated by scripts/build_punct_map.py) */ - static const unsigned PUNCT_MAP[] = { - R(0x0021,0x002f), R(0x003a,0x0040), R(0x005b,0x0060), R(0x007b,0x007e), R(0x00a1,0x00a9), - R(0x00ab,0x00ac), R(0x00ae,0x00b1), S(0x00b4), R(0x00b6,0x00b8), S(0x00bb), S(0x00bf), S(0x00d7), - S(0x00f7), R(0x02c2,0x02c5), R(0x02d2,0x02df), R(0x02e5,0x02eb), S(0x02ed), R(0x02ef,0x02ff), S(0x0375), - S(0x037e), R(0x0384,0x0385), S(0x0387), S(0x03f6), S(0x0482), R(0x055a,0x055f), R(0x0589,0x058a), - R(0x058d,0x058f), S(0x05be), S(0x05c0), S(0x05c3), S(0x05c6), R(0x05f3,0x05f4), R(0x0606,0x060f), - S(0x061b), R(0x061d,0x061f), R(0x066a,0x066d), S(0x06d4), S(0x06de), S(0x06e9), R(0x06fd,0x06fe), - R(0x0700,0x070d), R(0x07f6,0x07f9), R(0x07fe,0x07ff), R(0x0830,0x083e), S(0x085e), S(0x0888), - R(0x0964,0x0965), S(0x0970), R(0x09f2,0x09f3), R(0x09fa,0x09fb), S(0x09fd), S(0x0a76), R(0x0af0,0x0af1), - S(0x0b70), R(0x0bf3,0x0bfa), S(0x0c77), S(0x0c7f), S(0x0c84), S(0x0d4f), S(0x0d79), S(0x0df4), S(0x0e3f), - S(0x0e4f), R(0x0e5a,0x0e5b), R(0x0f01,0x0f17), R(0x0f1a,0x0f1f), S(0x0f34), S(0x0f36), S(0x0f38), - R(0x0f3a,0x0f3d), S(0x0f85), R(0x0fbe,0x0fc5), R(0x0fc7,0x0fcc), R(0x0fce,0x0fda), R(0x104a,0x104f), - R(0x109e,0x109f), S(0x10fb), R(0x1360,0x1368), R(0x1390,0x1399), S(0x1400), R(0x166d,0x166e), - R(0x169b,0x169c), R(0x16eb,0x16ed), R(0x1735,0x1736), R(0x17d4,0x17d6), R(0x17d8,0x17db), - R(0x1800,0x180a), S(0x1940), R(0x1944,0x1945), R(0x19de,0x19ff), R(0x1a1e,0x1a1f), R(0x1aa0,0x1aa6), - R(0x1aa8,0x1aad), R(0x1b5a,0x1b6a), R(0x1b74,0x1b7e), R(0x1bfc,0x1bff), R(0x1c3b,0x1c3f), - R(0x1c7e,0x1c7f), R(0x1cc0,0x1cc7), S(0x1cd3), S(0x1fbd), R(0x1fbf,0x1fc1), R(0x1fcd,0x1fcf), - R(0x1fdd,0x1fdf), R(0x1fed,0x1fef), R(0x1ffd,0x1ffe), R(0x2010,0x2027), R(0x2030,0x205e), - R(0x207a,0x207e), R(0x208a,0x208e), R(0x20a0,0x20c0), R(0x2100,0x2101), R(0x2103,0x2106), - R(0x2108,0x2109), S(0x2114), R(0x2116,0x2118), R(0x211e,0x2123), S(0x2125), S(0x2127), S(0x2129), - S(0x212e), R(0x213a,0x213b), R(0x2140,0x2144), R(0x214a,0x214d), S(0x214f), R(0x218a,0x218b), - R(0x2190,0x2426), R(0x2440,0x244a), R(0x249c,0x24e9), R(0x2500,0x2775), R(0x2794,0x2b73), - R(0x2b76,0x2b95), R(0x2b97,0x2bff), R(0x2ce5,0x2cea), R(0x2cf9,0x2cfc), R(0x2cfe,0x2cff), S(0x2d70), - R(0x2e00,0x2e2e), R(0x2e30,0x2e5d), R(0x2e80,0x2e99), R(0x2e9b,0x2ef3), R(0x2f00,0x2fd5), - R(0x2ff0,0x2fff), R(0x3001,0x3004), R(0x3008,0x3020), S(0x3030), R(0x3036,0x3037), R(0x303d,0x303f), - R(0x309b,0x309c), S(0x30a0), S(0x30fb), R(0x3190,0x3191), R(0x3196,0x319f), R(0x31c0,0x31e3), S(0x31ef), - R(0x3200,0x321e), R(0x322a,0x3247), S(0x3250), R(0x3260,0x327f), R(0x328a,0x32b0), R(0x32c0,0x33ff), - R(0x4dc0,0x4dff), R(0xa490,0xa4c6), R(0xa4fe,0xa4ff), R(0xa60d,0xa60f), S(0xa673), S(0xa67e), - R(0xa6f2,0xa6f7), R(0xa700,0xa716), R(0xa720,0xa721), R(0xa789,0xa78a), R(0xa828,0xa82b), - R(0xa836,0xa839), R(0xa874,0xa877), R(0xa8ce,0xa8cf), R(0xa8f8,0xa8fa), S(0xa8fc), R(0xa92e,0xa92f), - S(0xa95f), R(0xa9c1,0xa9cd), R(0xa9de,0xa9df), R(0xaa5c,0xaa5f), R(0xaa77,0xaa79), R(0xaade,0xaadf), - R(0xaaf0,0xaaf1), S(0xab5b), R(0xab6a,0xab6b), S(0xabeb), S(0xfb29), R(0xfbb2,0xfbc2), R(0xfd3e,0xfd4f), - S(0xfdcf), R(0xfdfc,0xfdff), R(0xfe10,0xfe19), R(0xfe30,0xfe52), R(0xfe54,0xfe66), R(0xfe68,0xfe6b), - R(0xff01,0xff0f), R(0xff1a,0xff20), R(0xff3b,0xff40), R(0xff5b,0xff65), R(0xffe0,0xffe6), - R(0xffe8,0xffee), R(0xfffc,0xfffd), R(0x10100,0x10102), R(0x10137,0x1013f), R(0x10179,0x10189), - R(0x1018c,0x1018e), R(0x10190,0x1019c), S(0x101a0), R(0x101d0,0x101fc), S(0x1039f), S(0x103d0), - S(0x1056f), S(0x10857), R(0x10877,0x10878), S(0x1091f), S(0x1093f), R(0x10a50,0x10a58), S(0x10a7f), - S(0x10ac8), R(0x10af0,0x10af6), R(0x10b39,0x10b3f), R(0x10b99,0x10b9c), S(0x10ead), R(0x10f55,0x10f59), - R(0x10f86,0x10f89), R(0x11047,0x1104d), R(0x110bb,0x110bc), R(0x110be,0x110c1), R(0x11140,0x11143), - R(0x11174,0x11175), R(0x111c5,0x111c8), S(0x111cd), S(0x111db), R(0x111dd,0x111df), R(0x11238,0x1123d), - S(0x112a9), R(0x1144b,0x1144f), R(0x1145a,0x1145b), S(0x1145d), S(0x114c6), R(0x115c1,0x115d7), - R(0x11641,0x11643), R(0x11660,0x1166c), S(0x116b9), R(0x1173c,0x1173f), S(0x1183b), R(0x11944,0x11946), - S(0x119e2), R(0x11a3f,0x11a46), R(0x11a9a,0x11a9c), R(0x11a9e,0x11aa2), R(0x11b00,0x11b09), - R(0x11c41,0x11c45), R(0x11c70,0x11c71), R(0x11ef7,0x11ef8), R(0x11f43,0x11f4f), R(0x11fd5,0x11ff1), - S(0x11fff), R(0x12470,0x12474), R(0x12ff1,0x12ff2), R(0x16a6e,0x16a6f), S(0x16af5), R(0x16b37,0x16b3f), - R(0x16b44,0x16b45), R(0x16e97,0x16e9a), S(0x16fe2), S(0x1bc9c), S(0x1bc9f), R(0x1cf50,0x1cfc3), - R(0x1d000,0x1d0f5), R(0x1d100,0x1d126), R(0x1d129,0x1d164), R(0x1d16a,0x1d16c), R(0x1d183,0x1d184), - R(0x1d18c,0x1d1a9), R(0x1d1ae,0x1d1ea), R(0x1d200,0x1d241), S(0x1d245), R(0x1d300,0x1d356), S(0x1d6c1), - S(0x1d6db), S(0x1d6fb), S(0x1d715), S(0x1d735), S(0x1d74f), S(0x1d76f), S(0x1d789), S(0x1d7a9), - S(0x1d7c3), R(0x1d800,0x1d9ff), R(0x1da37,0x1da3a), R(0x1da6d,0x1da74), R(0x1da76,0x1da83), - R(0x1da85,0x1da8b), S(0x1e14f), S(0x1e2ff), R(0x1e95e,0x1e95f), S(0x1ecac), S(0x1ecb0), S(0x1ed2e), - R(0x1eef0,0x1eef1), R(0x1f000,0x1f02b), R(0x1f030,0x1f093), R(0x1f0a0,0x1f0ae), R(0x1f0b1,0x1f0bf), - R(0x1f0c1,0x1f0cf), R(0x1f0d1,0x1f0f5), R(0x1f10d,0x1f1ad), R(0x1f1e6,0x1f202), R(0x1f210,0x1f23b), - R(0x1f240,0x1f248), R(0x1f250,0x1f251), R(0x1f260,0x1f265), R(0x1f300,0x1f6d7), R(0x1f6dc,0x1f6ec), - R(0x1f6f0,0x1f6fc), R(0x1f700,0x1f776), R(0x1f77b,0x1f7d9), R(0x1f7e0,0x1f7eb), S(0x1f7f0), - R(0x1f800,0x1f80b), R(0x1f810,0x1f847), R(0x1f850,0x1f859), R(0x1f860,0x1f887), R(0x1f890,0x1f8ad), - R(0x1f8b0,0x1f8b1), R(0x1f900,0x1fa53), R(0x1fa60,0x1fa6d), R(0x1fa70,0x1fa7c), R(0x1fa80,0x1fa88), - R(0x1fa90,0x1fabd), R(0x1fabf,0x1fac5), R(0x1face,0x1fadb), R(0x1fae0,0x1fae8), R(0x1faf0,0x1faf8), - R(0x1fb00,0x1fb92), R(0x1fb94,0x1fbca) - }; -#undef R -#undef S - - /* The ASCII ones are the most frequently used ones, also CommonMark - * specification requests few more in this range. */ - if(codepoint <= 0x7f) - return ISPUNCT_(codepoint); - - return (md_unicode_bsearch__(codepoint, PUNCT_MAP, SIZEOF_ARRAY(PUNCT_MAP)) >= 0); - } - - static void - md_get_unicode_fold_info(unsigned codepoint, MD_UNICODE_FOLD_INFO* info) - { -#define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) -#define S(cp) (cp) - /* Unicode "Pc", "Pd", "Pe", "Pf", "Pi", "Po", "Ps" categories. - * (generated by scripts/build_folding_map.py) */ - static const unsigned FOLD_MAP_1[] = { - R(0x0041,0x005a), S(0x00b5), R(0x00c0,0x00d6), R(0x00d8,0x00de), R(0x0100,0x012e), R(0x0132,0x0136), - R(0x0139,0x0147), R(0x014a,0x0176), S(0x0178), R(0x0179,0x017d), S(0x017f), S(0x0181), S(0x0182), - S(0x0184), S(0x0186), S(0x0187), S(0x0189), S(0x018a), S(0x018b), S(0x018e), S(0x018f), S(0x0190), - S(0x0191), S(0x0193), S(0x0194), S(0x0196), S(0x0197), S(0x0198), S(0x019c), S(0x019d), S(0x019f), - R(0x01a0,0x01a4), S(0x01a6), S(0x01a7), S(0x01a9), S(0x01ac), S(0x01ae), S(0x01af), S(0x01b1), S(0x01b2), - S(0x01b3), S(0x01b5), S(0x01b7), S(0x01b8), S(0x01bc), S(0x01c4), S(0x01c5), S(0x01c7), S(0x01c8), - S(0x01ca), R(0x01cb,0x01db), R(0x01de,0x01ee), S(0x01f1), S(0x01f2), S(0x01f4), S(0x01f6), S(0x01f7), - R(0x01f8,0x021e), S(0x0220), R(0x0222,0x0232), S(0x023a), S(0x023b), S(0x023d), S(0x023e), S(0x0241), - S(0x0243), S(0x0244), S(0x0245), R(0x0246,0x024e), S(0x0345), S(0x0370), S(0x0372), S(0x0376), S(0x037f), - S(0x0386), R(0x0388,0x038a), S(0x038c), S(0x038e), S(0x038f), R(0x0391,0x03a1), R(0x03a3,0x03ab), - S(0x03c2), S(0x03cf), S(0x03d0), S(0x03d1), S(0x03d5), S(0x03d6), R(0x03d8,0x03ee), S(0x03f0), S(0x03f1), - S(0x03f4), S(0x03f5), S(0x03f7), S(0x03f9), S(0x03fa), R(0x03fd,0x03ff), R(0x0400,0x040f), - R(0x0410,0x042f), R(0x0460,0x0480), R(0x048a,0x04be), S(0x04c0), R(0x04c1,0x04cd), R(0x04d0,0x052e), - R(0x0531,0x0556), R(0x10a0,0x10c5), S(0x10c7), S(0x10cd), R(0x13f8,0x13fd), S(0x1c80), S(0x1c81), - S(0x1c82), S(0x1c83), S(0x1c84), S(0x1c85), S(0x1c86), S(0x1c87), S(0x1c88), R(0x1c90,0x1cba), - R(0x1cbd,0x1cbf), R(0x1e00,0x1e94), S(0x1e9b), R(0x1ea0,0x1efe), R(0x1f08,0x1f0f), R(0x1f18,0x1f1d), - R(0x1f28,0x1f2f), R(0x1f38,0x1f3f), R(0x1f48,0x1f4d), S(0x1f59), S(0x1f5b), S(0x1f5d), S(0x1f5f), - R(0x1f68,0x1f6f), S(0x1fb8), S(0x1fb9), S(0x1fba), S(0x1fbb), S(0x1fbe), R(0x1fc8,0x1fcb), S(0x1fd8), - S(0x1fd9), S(0x1fda), S(0x1fdb), S(0x1fe8), S(0x1fe9), S(0x1fea), S(0x1feb), S(0x1fec), S(0x1ff8), - S(0x1ff9), S(0x1ffa), S(0x1ffb), S(0x2126), S(0x212a), S(0x212b), S(0x2132), R(0x2160,0x216f), S(0x2183), - R(0x24b6,0x24cf), R(0x2c00,0x2c2f), S(0x2c60), S(0x2c62), S(0x2c63), S(0x2c64), R(0x2c67,0x2c6b), - S(0x2c6d), S(0x2c6e), S(0x2c6f), S(0x2c70), S(0x2c72), S(0x2c75), S(0x2c7e), S(0x2c7f), R(0x2c80,0x2ce2), - S(0x2ceb), S(0x2ced), S(0x2cf2), R(0xa640,0xa66c), R(0xa680,0xa69a), R(0xa722,0xa72e), R(0xa732,0xa76e), - S(0xa779), S(0xa77b), S(0xa77d), R(0xa77e,0xa786), S(0xa78b), S(0xa78d), S(0xa790), S(0xa792), - R(0xa796,0xa7a8), S(0xa7aa), S(0xa7ab), S(0xa7ac), S(0xa7ad), S(0xa7ae), S(0xa7b0), S(0xa7b1), S(0xa7b2), - S(0xa7b3), R(0xa7b4,0xa7c2), S(0xa7c4), S(0xa7c5), S(0xa7c6), S(0xa7c7), S(0xa7c9), S(0xa7d0), S(0xa7d6), - S(0xa7d8), S(0xa7f5), R(0xab70,0xabbf), R(0xff21,0xff3a), R(0x10400,0x10427), R(0x104b0,0x104d3), - R(0x10570,0x1057a), R(0x1057c,0x1058a), R(0x1058c,0x10592), S(0x10594), S(0x10595), R(0x10c80,0x10cb2), - R(0x118a0,0x118bf), R(0x16e40,0x16e5f), R(0x1e900,0x1e921) - }; - static const unsigned FOLD_MAP_1_DATA[] = { - 0x0061, 0x007a, 0x03bc, 0x00e0, 0x00f6, 0x00f8, 0x00fe, 0x0101, 0x012f, 0x0133, 0x0137, 0x013a, 0x0148, - 0x014b, 0x0177, 0x00ff, 0x017a, 0x017e, 0x0073, 0x0253, 0x0183, 0x0185, 0x0254, 0x0188, 0x0256, 0x0257, - 0x018c, 0x01dd, 0x0259, 0x025b, 0x0192, 0x0260, 0x0263, 0x0269, 0x0268, 0x0199, 0x026f, 0x0272, 0x0275, - 0x01a1, 0x01a5, 0x0280, 0x01a8, 0x0283, 0x01ad, 0x0288, 0x01b0, 0x028a, 0x028b, 0x01b4, 0x01b6, 0x0292, - 0x01b9, 0x01bd, 0x01c6, 0x01c6, 0x01c9, 0x01c9, 0x01cc, 0x01cc, 0x01dc, 0x01df, 0x01ef, 0x01f3, 0x01f3, - 0x01f5, 0x0195, 0x01bf, 0x01f9, 0x021f, 0x019e, 0x0223, 0x0233, 0x2c65, 0x023c, 0x019a, 0x2c66, 0x0242, - 0x0180, 0x0289, 0x028c, 0x0247, 0x024f, 0x03b9, 0x0371, 0x0373, 0x0377, 0x03f3, 0x03ac, 0x03ad, 0x03af, - 0x03cc, 0x03cd, 0x03ce, 0x03b1, 0x03c1, 0x03c3, 0x03cb, 0x03c3, 0x03d7, 0x03b2, 0x03b8, 0x03c6, 0x03c0, - 0x03d9, 0x03ef, 0x03ba, 0x03c1, 0x03b8, 0x03b5, 0x03f8, 0x03f2, 0x03fb, 0x037b, 0x037d, 0x0450, 0x045f, - 0x0430, 0x044f, 0x0461, 0x0481, 0x048b, 0x04bf, 0x04cf, 0x04c2, 0x04ce, 0x04d1, 0x052f, 0x0561, 0x0586, - 0x2d00, 0x2d25, 0x2d27, 0x2d2d, 0x13f0, 0x13f5, 0x0432, 0x0434, 0x043e, 0x0441, 0x0442, 0x0442, 0x044a, - 0x0463, 0xa64b, 0x10d0, 0x10fa, 0x10fd, 0x10ff, 0x1e01, 0x1e95, 0x1e61, 0x1ea1, 0x1eff, 0x1f00, 0x1f07, - 0x1f10, 0x1f15, 0x1f20, 0x1f27, 0x1f30, 0x1f37, 0x1f40, 0x1f45, 0x1f51, 0x1f53, 0x1f55, 0x1f57, 0x1f60, - 0x1f67, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x03b9, 0x1f72, 0x1f75, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0x1fe0, - 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x03c9, 0x006b, 0x00e5, 0x214e, 0x2170, - 0x217f, 0x2184, 0x24d0, 0x24e9, 0x2c30, 0x2c5f, 0x2c61, 0x026b, 0x1d7d, 0x027d, 0x2c68, 0x2c6c, 0x0251, - 0x0271, 0x0250, 0x0252, 0x2c73, 0x2c76, 0x023f, 0x0240, 0x2c81, 0x2ce3, 0x2cec, 0x2cee, 0x2cf3, 0xa641, - 0xa66d, 0xa681, 0xa69b, 0xa723, 0xa72f, 0xa733, 0xa76f, 0xa77a, 0xa77c, 0x1d79, 0xa77f, 0xa787, 0xa78c, - 0x0265, 0xa791, 0xa793, 0xa797, 0xa7a9, 0x0266, 0x025c, 0x0261, 0x026c, 0x026a, 0x029e, 0x0287, 0x029d, - 0xab53, 0xa7b5, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8, 0xa7ca, 0xa7d1, 0xa7d7, 0xa7d9, 0xa7f6, 0x13a0, - 0x13ef, 0xff41, 0xff5a, 0x10428, 0x1044f, 0x104d8, 0x104fb, 0x10597, 0x105a1, 0x105a3, 0x105b1, 0x105b3, - 0x105b9, 0x105bb, 0x105bc, 0x10cc0, 0x10cf2, 0x118c0, 0x118df, 0x16e60, 0x16e7f, 0x1e922, 0x1e943 - }; - static const unsigned FOLD_MAP_2[] = { - S(0x00df), S(0x0130), S(0x0149), S(0x01f0), S(0x0587), S(0x1e96), S(0x1e97), S(0x1e98), S(0x1e99), - S(0x1e9a), S(0x1e9e), S(0x1f50), R(0x1f80,0x1f87), R(0x1f88,0x1f8f), R(0x1f90,0x1f97), R(0x1f98,0x1f9f), - R(0x1fa0,0x1fa7), R(0x1fa8,0x1faf), S(0x1fb2), S(0x1fb3), S(0x1fb4), S(0x1fb6), S(0x1fbc), S(0x1fc2), - S(0x1fc3), S(0x1fc4), S(0x1fc6), S(0x1fcc), S(0x1fd6), S(0x1fe4), S(0x1fe6), S(0x1ff2), S(0x1ff3), - S(0x1ff4), S(0x1ff6), S(0x1ffc), S(0xfb00), S(0xfb01), S(0xfb02), S(0xfb05), S(0xfb06), S(0xfb13), - S(0xfb14), S(0xfb15), S(0xfb16), S(0xfb17) - }; - static const unsigned FOLD_MAP_2_DATA[] = { - 0x0073,0x0073, 0x0069,0x0307, 0x02bc,0x006e, 0x006a,0x030c, 0x0565,0x0582, 0x0068,0x0331, 0x0074,0x0308, - 0x0077,0x030a, 0x0079,0x030a, 0x0061,0x02be, 0x0073,0x0073, 0x03c5,0x0313, 0x1f00,0x03b9, 0x1f07,0x03b9, - 0x1f00,0x03b9, 0x1f07,0x03b9, 0x1f20,0x03b9, 0x1f27,0x03b9, 0x1f20,0x03b9, 0x1f27,0x03b9, 0x1f60,0x03b9, - 0x1f67,0x03b9, 0x1f60,0x03b9, 0x1f67,0x03b9, 0x1f70,0x03b9, 0x03b1,0x03b9, 0x03ac,0x03b9, 0x03b1,0x0342, - 0x03b1,0x03b9, 0x1f74,0x03b9, 0x03b7,0x03b9, 0x03ae,0x03b9, 0x03b7,0x0342, 0x03b7,0x03b9, 0x03b9,0x0342, - 0x03c1,0x0313, 0x03c5,0x0342, 0x1f7c,0x03b9, 0x03c9,0x03b9, 0x03ce,0x03b9, 0x03c9,0x0342, 0x03c9,0x03b9, - 0x0066,0x0066, 0x0066,0x0069, 0x0066,0x006c, 0x0073,0x0074, 0x0073,0x0074, 0x0574,0x0576, 0x0574,0x0565, - 0x0574,0x056b, 0x057e,0x0576, 0x0574,0x056d - }; - static const unsigned FOLD_MAP_3[] = { - S(0x0390), S(0x03b0), S(0x1f52), S(0x1f54), S(0x1f56), S(0x1fb7), S(0x1fc7), S(0x1fd2), S(0x1fd3), - S(0x1fd7), S(0x1fe2), S(0x1fe3), S(0x1fe7), S(0x1ff7), S(0xfb03), S(0xfb04) - }; - static const unsigned FOLD_MAP_3_DATA[] = { - 0x03b9,0x0308,0x0301, 0x03c5,0x0308,0x0301, 0x03c5,0x0313,0x0300, 0x03c5,0x0313,0x0301, - 0x03c5,0x0313,0x0342, 0x03b1,0x0342,0x03b9, 0x03b7,0x0342,0x03b9, 0x03b9,0x0308,0x0300, - 0x03b9,0x0308,0x0301, 0x03b9,0x0308,0x0342, 0x03c5,0x0308,0x0300, 0x03c5,0x0308,0x0301, - 0x03c5,0x0308,0x0342, 0x03c9,0x0342,0x03b9, 0x0066,0x0066,0x0069, 0x0066,0x0066,0x006c - }; -#undef R -#undef S - static const struct { - const unsigned* map; - const unsigned* data; - size_t map_size; - unsigned n_codepoints; - } FOLD_MAP_LIST[] = { - { FOLD_MAP_1, FOLD_MAP_1_DATA, SIZEOF_ARRAY(FOLD_MAP_1), 1 }, - { FOLD_MAP_2, FOLD_MAP_2_DATA, SIZEOF_ARRAY(FOLD_MAP_2), 2 }, - { FOLD_MAP_3, FOLD_MAP_3_DATA, SIZEOF_ARRAY(FOLD_MAP_3), 3 } - }; - - int i; - - /* Fast path for ASCII characters. */ - if(codepoint <= 0x7f) { - info->codepoints[0] = codepoint; - if(ISUPPER_(codepoint)) - info->codepoints[0] += 'a' - 'A'; - info->n_codepoints = 1; - return; - } - - /* Try to locate the codepoint in any of the maps. */ - for(i = 0; i < (int) SIZEOF_ARRAY(FOLD_MAP_LIST); i++) { - int index; - - index = md_unicode_bsearch__(codepoint, FOLD_MAP_LIST[i].map, FOLD_MAP_LIST[i].map_size); - if(index >= 0) { - /* Found the mapping. */ - unsigned n_codepoints = FOLD_MAP_LIST[i].n_codepoints; - const unsigned* map = FOLD_MAP_LIST[i].map; - const unsigned* codepoints = FOLD_MAP_LIST[i].data + (index * n_codepoints); - - memcpy(info->codepoints, codepoints, sizeof(unsigned) * n_codepoints); - info->n_codepoints = n_codepoints; - - if(FOLD_MAP_LIST[i].map[index] != codepoint) { - /* The found mapping maps whole range of codepoints, - * i.e. we have to offset info->codepoints[0] accordingly. */ - if((map[index] & 0x00ffffff)+1 == codepoints[0]) { - /* Alternating type of the range. */ - info->codepoints[0] = codepoint + ((codepoint & 0x1) == (map[index] & 0x1) ? 1 : 0); - } else { - /* Range to range kind of mapping. */ - info->codepoints[0] += (codepoint - (map[index] & 0x00ffffff)); - } - } - - return; - } - } - - /* No mapping found. Map the codepoint to itself. */ - info->codepoints[0] = codepoint; - info->n_codepoints = 1; - } -#endif - - -#if defined MD4C_USE_UTF16 - #define IS_UTF16_SURROGATE_HI(word) (((WORD)(word) & 0xfc00) == 0xd800) - #define IS_UTF16_SURROGATE_LO(word) (((WORD)(word) & 0xfc00) == 0xdc00) - #define UTF16_DECODE_SURROGATE(hi, lo) (0x10000 + ((((unsigned)(hi) & 0x3ff) << 10) | (((unsigned)(lo) & 0x3ff) << 0))) - - static unsigned - md_decode_utf16le__(const CHAR* str, SZ str_size, SZ* p_size) - { - if(IS_UTF16_SURROGATE_HI(str[0])) { - if(1 < str_size && IS_UTF16_SURROGATE_LO(str[1])) { - if(p_size != NULL) - *p_size = 2; - return UTF16_DECODE_SURROGATE(str[0], str[1]); - } - } - - if(p_size != NULL) - *p_size = 1; - return str[0]; - } - - static unsigned - md_decode_utf16le_before__(MD_CTX* ctx, OFF off) - { - if(off > 2 && IS_UTF16_SURROGATE_HI(CH(off-2)) && IS_UTF16_SURROGATE_LO(CH(off-1))) - return UTF16_DECODE_SURROGATE(CH(off-2), CH(off-1)); - - return CH(off); - } - - /* No whitespace uses surrogates, so no decoding needed here. */ - #define ISUNICODEWHITESPACE_(codepoint) md_is_unicode_whitespace__(codepoint) - #define ISUNICODEWHITESPACE(off) md_is_unicode_whitespace__(CH(off)) - #define ISUNICODEWHITESPACEBEFORE(off) md_is_unicode_whitespace__(CH((off)-1)) - - #define ISUNICODEPUNCT(off) md_is_unicode_punct__(md_decode_utf16le__(STR(off), ctx->size - (off), NULL)) - #define ISUNICODEPUNCTBEFORE(off) md_is_unicode_punct__(md_decode_utf16le_before__(ctx, off)) - - static inline int - md_decode_unicode(const CHAR* str, OFF off, SZ str_size, SZ* p_char_size) - { - return md_decode_utf16le__(str+off, str_size-off, p_char_size); - } -#elif defined MD4C_USE_UTF8 - #define IS_UTF8_LEAD1(byte) ((unsigned char)(byte) <= 0x7f) - #define IS_UTF8_LEAD2(byte) (((unsigned char)(byte) & 0xe0) == 0xc0) - #define IS_UTF8_LEAD3(byte) (((unsigned char)(byte) & 0xf0) == 0xe0) - #define IS_UTF8_LEAD4(byte) (((unsigned char)(byte) & 0xf8) == 0xf0) - #define IS_UTF8_TAIL(byte) (((unsigned char)(byte) & 0xc0) == 0x80) - - static unsigned - md_decode_utf8__(const CHAR* str, SZ str_size, SZ* p_size) - { - if(!IS_UTF8_LEAD1(str[0])) { - if(IS_UTF8_LEAD2(str[0])) { - if(1 < str_size && IS_UTF8_TAIL(str[1])) { - if(p_size != NULL) - *p_size = 2; - - return (((unsigned int)str[0] & 0x1f) << 6) | - (((unsigned int)str[1] & 0x3f) << 0); - } - } else if(IS_UTF8_LEAD3(str[0])) { - if(2 < str_size && IS_UTF8_TAIL(str[1]) && IS_UTF8_TAIL(str[2])) { - if(p_size != NULL) - *p_size = 3; - - return (((unsigned int)str[0] & 0x0f) << 12) | - (((unsigned int)str[1] & 0x3f) << 6) | - (((unsigned int)str[2] & 0x3f) << 0); - } - } else if(IS_UTF8_LEAD4(str[0])) { - if(3 < str_size && IS_UTF8_TAIL(str[1]) && IS_UTF8_TAIL(str[2]) && IS_UTF8_TAIL(str[3])) { - if(p_size != NULL) - *p_size = 4; - - return (((unsigned int)str[0] & 0x07) << 18) | - (((unsigned int)str[1] & 0x3f) << 12) | - (((unsigned int)str[2] & 0x3f) << 6) | - (((unsigned int)str[3] & 0x3f) << 0); - } - } - } - - if(p_size != NULL) - *p_size = 1; - return (unsigned) str[0]; - } - - static unsigned - md_decode_utf8_before__(MD_CTX* ctx, OFF off) - { - if(!IS_UTF8_LEAD1(CH(off-1))) { - if(off > 1 && IS_UTF8_LEAD2(CH(off-2)) && IS_UTF8_TAIL(CH(off-1))) - return (((unsigned int)CH(off-2) & 0x1f) << 6) | - (((unsigned int)CH(off-1) & 0x3f) << 0); - - if(off > 2 && IS_UTF8_LEAD3(CH(off-3)) && IS_UTF8_TAIL(CH(off-2)) && IS_UTF8_TAIL(CH(off-1))) - return (((unsigned int)CH(off-3) & 0x0f) << 12) | - (((unsigned int)CH(off-2) & 0x3f) << 6) | - (((unsigned int)CH(off-1) & 0x3f) << 0); - - if(off > 3 && IS_UTF8_LEAD4(CH(off-4)) && IS_UTF8_TAIL(CH(off-3)) && IS_UTF8_TAIL(CH(off-2)) && IS_UTF8_TAIL(CH(off-1))) - return (((unsigned int)CH(off-4) & 0x07) << 18) | - (((unsigned int)CH(off-3) & 0x3f) << 12) | - (((unsigned int)CH(off-2) & 0x3f) << 6) | - (((unsigned int)CH(off-1) & 0x3f) << 0); - } - - return (unsigned) CH(off-1); - } - - #define ISUNICODEWHITESPACE_(codepoint) md_is_unicode_whitespace__(codepoint) - #define ISUNICODEWHITESPACE(off) md_is_unicode_whitespace__(md_decode_utf8__(STR(off), ctx->size - (off), NULL)) - #define ISUNICODEWHITESPACEBEFORE(off) md_is_unicode_whitespace__(md_decode_utf8_before__(ctx, off)) - - #define ISUNICODEPUNCT(off) md_is_unicode_punct__(md_decode_utf8__(STR(off), ctx->size - (off), NULL)) - #define ISUNICODEPUNCTBEFORE(off) md_is_unicode_punct__(md_decode_utf8_before__(ctx, off)) - - static inline unsigned - md_decode_unicode(const CHAR* str, OFF off, SZ str_size, SZ* p_char_size) - { - return md_decode_utf8__(str+off, str_size-off, p_char_size); - } -#else - #define ISUNICODEWHITESPACE_(codepoint) ISWHITESPACE_(codepoint) - #define ISUNICODEWHITESPACE(off) ISWHITESPACE(off) - #define ISUNICODEWHITESPACEBEFORE(off) ISWHITESPACE((off)-1) - - #define ISUNICODEPUNCT(off) ISPUNCT(off) - #define ISUNICODEPUNCTBEFORE(off) ISPUNCT((off)-1) - - static inline void - md_get_unicode_fold_info(unsigned codepoint, MD_UNICODE_FOLD_INFO* info) - { - info->codepoints[0] = codepoint; - if(ISUPPER_(codepoint)) - info->codepoints[0] += 'a' - 'A'; - info->n_codepoints = 1; - } - - static inline unsigned - md_decode_unicode(const CHAR* str, OFF off, SZ str_size, SZ* p_size) - { - *p_size = 1; - return (unsigned) str[off]; - } -#endif - - -/************************************* - *** Helper string manipulations *** - *************************************/ - -/* Fill buffer with copy of the string between 'beg' and 'end' but replace any - * line breaks with given replacement character. - * - * NOTE: Caller is responsible to make sure the buffer is large enough. - * (Given the output is always shorter than input, (end - beg) is good idea - * what the caller should allocate.) - */ -static void -md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines, - CHAR line_break_replacement_char, CHAR* buffer, SZ* p_size) -{ - CHAR* ptr = buffer; - int line_index = 0; - OFF off = beg; - - MD_UNUSED(n_lines); - - while(1) { - const MD_LINE* line = &lines[line_index]; - OFF line_end = line->end; - if(end < line_end) - line_end = end; - - while(off < line_end) { - *ptr = CH(off); - ptr++; - off++; - } - - if(off >= end) { - *p_size = (MD_SIZE)(ptr - buffer); - return; - } - - *ptr = line_break_replacement_char; - ptr++; - - line_index++; - off = lines[line_index].beg; - } -} - -/* Wrapper of md_merge_lines() which allocates new buffer for the output string. - */ -static int -md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines, - CHAR line_break_replacement_char, CHAR** p_str, SZ* p_size) -{ - CHAR* buffer; - - buffer = (CHAR*) malloc(sizeof(CHAR) * (end - beg)); - if(buffer == NULL) { - MD_LOG("malloc() failed."); - return -1; - } - - md_merge_lines(ctx, beg, end, lines, n_lines, - line_break_replacement_char, buffer, p_size); - - *p_str = buffer; - return 0; -} - -static OFF -md_skip_unicode_whitespace(const CHAR* label, OFF off, SZ size) -{ - SZ char_size; - unsigned codepoint; - - while(off < size) { - codepoint = md_decode_unicode(label, off, size, &char_size); - if(!ISUNICODEWHITESPACE_(codepoint) && !ISNEWLINE_(label[off])) - break; - off += char_size; - } - - return off; -} - - -/****************************** - *** Recognizing raw HTML *** - ******************************/ - -/* md_is_html_tag() may be called when processing inlines (inline raw HTML) - * or when breaking document to blocks (checking for start of HTML block type 7). - * - * When breaking document to blocks, we do not yet know line boundaries, but - * in that case the whole tag has to live on a single line. We distinguish this - * by n_lines == 0. - */ -static int -md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - int attr_state; - OFF off = beg; - OFF line_end = (n_lines > 0) ? lines[0].end : ctx->size; - MD_SIZE line_index = 0; - - MD_ASSERT(CH(beg) == _T('<')); - - if(off + 1 >= line_end) - return FALSE; - off++; - - /* For parsing attributes, we need a little state automaton below. - * State -1: no attributes are allowed. - * State 0: attribute could follow after some whitespace. - * State 1: after a whitespace (attribute name may follow). - * State 2: after attribute name ('=' MAY follow). - * State 3: after '=' (value specification MUST follow). - * State 41: in middle of unquoted attribute value. - * State 42: in middle of single-quoted attribute value. - * State 43: in middle of double-quoted attribute value. - */ - attr_state = 0; - - if(CH(off) == _T('/')) { - /* Closer tag "". No attributes may be present. */ - attr_state = -1; - off++; - } - - /* Tag name */ - if(off >= line_end || !ISALPHA(off)) - return FALSE; - off++; - while(off < line_end && (ISALNUM(off) || CH(off) == _T('-'))) - off++; - - /* (Optional) attributes (if not closer), (optional) '/' (if not closer) - * and final '>'. */ - while(1) { - while(off < line_end && !ISNEWLINE(off)) { - if(attr_state > 40) { - if(attr_state == 41 && (ISBLANK(off) || ISANYOF(off, _T("\"'=<>`")))) { - attr_state = 0; - off--; /* Put the char back for re-inspection in the new state. */ - } else if(attr_state == 42 && CH(off) == _T('\'')) { - attr_state = 0; - } else if(attr_state == 43 && CH(off) == _T('"')) { - attr_state = 0; - } - off++; - } else if(ISWHITESPACE(off)) { - if(attr_state == 0) - attr_state = 1; - off++; - } else if(attr_state <= 2 && CH(off) == _T('>')) { - /* End. */ - goto done; - } else if(attr_state <= 2 && CH(off) == _T('/') && off+1 < line_end && CH(off+1) == _T('>')) { - /* End with digraph '/>' */ - off++; - goto done; - } else if((attr_state == 1 || attr_state == 2) && (ISALPHA(off) || CH(off) == _T('_') || CH(off) == _T(':'))) { - off++; - /* Attribute name */ - while(off < line_end && (ISALNUM(off) || ISANYOF(off, _T("_.:-")))) - off++; - attr_state = 2; - } else if(attr_state == 2 && CH(off) == _T('=')) { - /* Attribute assignment sign */ - off++; - attr_state = 3; - } else if(attr_state == 3) { - /* Expecting start of attribute value. */ - if(CH(off) == _T('"')) - attr_state = 43; - else if(CH(off) == _T('\'')) - attr_state = 42; - else if(!ISANYOF(off, _T("\"'=<>`")) && !ISNEWLINE(off)) - attr_state = 41; - else - return FALSE; - off++; - } else { - /* Anything unexpected. */ - return FALSE; - } - } - - /* We have to be on a single line. See definition of start condition - * of HTML block, type 7. */ - if(n_lines == 0) - return FALSE; - - line_index++; - if(line_index >= n_lines) - return FALSE; - - off = lines[line_index].beg; - line_end = lines[line_index].end; - - if(attr_state == 0 || attr_state == 41) - attr_state = 1; - - if(off >= max_end) - return FALSE; - } - -done: - if(off >= max_end) - return FALSE; - - *p_end = off+1; - return TRUE; -} - -static int -md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len, - const MD_LINE* lines, MD_SIZE n_lines, - OFF beg, OFF max_end, OFF* p_end, - OFF* p_scan_horizon) -{ - OFF off = beg; - MD_SIZE line_index = 0; - - if(off < *p_scan_horizon && *p_scan_horizon >= max_end - len) { - /* We have already scanned the range up to the max_end so we know - * there is nothing to see. */ - return FALSE; - } - - while(TRUE) { - while(off + len <= lines[line_index].end && off + len <= max_end) { - if(md_ascii_eq(STR(off), str, len)) { - /* Success. */ - *p_end = off + len; - return TRUE; - } - off++; - } - - line_index++; - if(off >= max_end || line_index >= n_lines) { - /* Failure. */ - *p_scan_horizon = off; - return FALSE; - } - - off = lines[line_index].beg; - } -} - -static int -md_is_html_comment(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - - MD_ASSERT(CH(beg) == _T('<')); - - if(off + 4 >= lines[0].end) - return FALSE; - if(CH(off+1) != _T('!') || CH(off+2) != _T('-') || CH(off+3) != _T('-')) - return FALSE; - - /* Skip only "" or "" */ - off += 2; - - /* Scan for ordinary comment closer "-->". */ - return md_scan_for_html_closer(ctx, _T("-->"), 3, - lines, n_lines, off, max_end, p_end, &ctx->html_comment_horizon); -} - -static int -md_is_html_processing_instruction(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - - if(off + 2 >= lines[0].end) - return FALSE; - if(CH(off+1) != _T('?')) - return FALSE; - off += 2; - - return md_scan_for_html_closer(ctx, _T("?>"), 2, - lines, n_lines, off, max_end, p_end, &ctx->html_proc_instr_horizon); -} - -static int -md_is_html_declaration(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - - if(off + 2 >= lines[0].end) - return FALSE; - if(CH(off+1) != _T('!')) - return FALSE; - off += 2; - - /* Declaration name. */ - if(off >= lines[0].end || !ISALPHA(off)) - return FALSE; - off++; - while(off < lines[0].end && ISALPHA(off)) - off++; - - return md_scan_for_html_closer(ctx, _T(">"), 1, - lines, n_lines, off, max_end, p_end, &ctx->html_decl_horizon); -} - -static int -md_is_html_cdata(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - static const CHAR open_str[] = _T("= lines[0].end) - return FALSE; - if(memcmp(STR(off), open_str, open_size) != 0) - return FALSE; - off += open_size; - - return md_scan_for_html_closer(ctx, _T("]]>"), 3, - lines, n_lines, off, max_end, p_end, &ctx->html_cdata_horizon); -} - -static int -md_is_html_any(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - MD_ASSERT(CH(beg) == _T('<')); - return (md_is_html_tag(ctx, lines, n_lines, beg, max_end, p_end) || - md_is_html_comment(ctx, lines, n_lines, beg, max_end, p_end) || - md_is_html_processing_instruction(ctx, lines, n_lines, beg, max_end, p_end) || - md_is_html_declaration(ctx, lines, n_lines, beg, max_end, p_end) || - md_is_html_cdata(ctx, lines, n_lines, beg, max_end, p_end)); -} - - -/**************************** - *** Recognizing Entity *** - ****************************/ - -static int -md_is_hex_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - MD_UNUSED(ctx); - - while(off < max_end && ISXDIGIT_(text[off]) && off - beg <= 8) - off++; - - if(1 <= off - beg && off - beg <= 6) { - *p_end = off; - return TRUE; - } else { - return FALSE; - } -} - -static int -md_is_dec_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - MD_UNUSED(ctx); - - while(off < max_end && ISDIGIT_(text[off]) && off - beg <= 8) - off++; - - if(1 <= off - beg && off - beg <= 7) { - *p_end = off; - return TRUE; - } else { - return FALSE; - } -} - -static int -md_is_named_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - MD_UNUSED(ctx); - - if(off < max_end && ISALPHA_(text[off])) - off++; - else - return FALSE; - - while(off < max_end && ISALNUM_(text[off]) && off - beg <= 48) - off++; - - if(2 <= off - beg && off - beg <= 48) { - *p_end = off; - return TRUE; - } else { - return FALSE; - } -} - -static int -md_is_entity_str(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) -{ - int is_contents; - OFF off = beg; - - MD_ASSERT(text[off] == _T('&')); - off++; - - if(off+2 < max_end && text[off] == _T('#') && (text[off+1] == _T('x') || text[off+1] == _T('X'))) - is_contents = md_is_hex_entity_contents(ctx, text, off+2, max_end, &off); - else if(off+1 < max_end && text[off] == _T('#')) - is_contents = md_is_dec_entity_contents(ctx, text, off+1, max_end, &off); - else - is_contents = md_is_named_entity_contents(ctx, text, off, max_end, &off); - - if(is_contents && off < max_end && text[off] == _T(';')) { - *p_end = off+1; - return TRUE; - } else { - return FALSE; - } -} - -static inline int -md_is_entity(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end) -{ - return md_is_entity_str(ctx, ctx->text, beg, max_end, p_end); -} - - -/****************************** - *** Attribute Management *** - ******************************/ - -typedef struct MD_ATTRIBUTE_BUILD_tag MD_ATTRIBUTE_BUILD; -struct MD_ATTRIBUTE_BUILD_tag { - CHAR* text; - MD_TEXTTYPE* substr_types; - OFF* substr_offsets; - int substr_count; - int substr_alloc; - MD_TEXTTYPE trivial_types[1]; - OFF trivial_offsets[2]; -}; - - -#define MD_BUILD_ATTR_NO_ESCAPES 0x0001 - -static int -md_build_attr_append_substr(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build, - MD_TEXTTYPE type, OFF off) -{ - if(build->substr_count >= build->substr_alloc) { - MD_TEXTTYPE* new_substr_types; - OFF* new_substr_offsets; - - build->substr_alloc = (build->substr_alloc > 0 - ? build->substr_alloc + build->substr_alloc / 2 - : 8); - new_substr_types = (MD_TEXTTYPE*) realloc(build->substr_types, - build->substr_alloc * sizeof(MD_TEXTTYPE)); - if(new_substr_types == NULL) { - MD_LOG("realloc() failed."); - return -1; - } - /* Note +1 to reserve space for final offset (== raw_size). */ - new_substr_offsets = (OFF*) realloc(build->substr_offsets, - (build->substr_alloc+1) * sizeof(OFF)); - if(new_substr_offsets == NULL) { - MD_LOG("realloc() failed."); - free(new_substr_types); - return -1; - } - - build->substr_types = new_substr_types; - build->substr_offsets = new_substr_offsets; - } - - build->substr_types[build->substr_count] = type; - build->substr_offsets[build->substr_count] = off; - build->substr_count++; - return 0; -} - -static void -md_free_attribute(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build) -{ - MD_UNUSED(ctx); - - if(build->substr_alloc > 0) { - free(build->text); - free(build->substr_types); - free(build->substr_offsets); - } -} - -static int -md_build_attribute(MD_CTX* ctx, const CHAR* raw_text, SZ raw_size, - unsigned flags, MD_ATTRIBUTE* attr, MD_ATTRIBUTE_BUILD* build) -{ - OFF raw_off, off; - int is_trivial; - int ret = 0; - - memset(build, 0, sizeof(MD_ATTRIBUTE_BUILD)); - - /* If there is no backslash and no ampersand, build trivial attribute - * without any malloc(). */ - is_trivial = TRUE; - for(raw_off = 0; raw_off < raw_size; raw_off++) { - if(ISANYOF3_(raw_text[raw_off], _T('\\'), _T('&'), _T('\0'))) { - is_trivial = FALSE; - break; - } - } - - if(is_trivial) { - build->text = (CHAR*) (raw_size ? raw_text : NULL); - build->substr_types = build->trivial_types; - build->substr_offsets = build->trivial_offsets; - build->substr_count = 1; - build->substr_alloc = 0; - build->trivial_types[0] = MD_TEXT_NORMAL; - build->trivial_offsets[0] = 0; - build->trivial_offsets[1] = raw_size; - off = raw_size; - } else { - build->text = (CHAR*) malloc(raw_size * sizeof(CHAR)); - if(build->text == NULL) { - MD_LOG("malloc() failed."); - goto abort; - } - - raw_off = 0; - off = 0; - - while(raw_off < raw_size) { - if(raw_text[raw_off] == _T('\0')) { - MD_CHECK(md_build_attr_append_substr(ctx, build, MD_TEXT_NULLCHAR, off)); - memcpy(build->text + off, raw_text + raw_off, 1); - off++; - raw_off++; - continue; - } - - if(raw_text[raw_off] == _T('&')) { - OFF ent_end; - - if(md_is_entity_str(ctx, raw_text, raw_off, raw_size, &ent_end)) { - MD_CHECK(md_build_attr_append_substr(ctx, build, MD_TEXT_ENTITY, off)); - memcpy(build->text + off, raw_text + raw_off, ent_end - raw_off); - off += ent_end - raw_off; - raw_off = ent_end; - continue; - } - } - - if(build->substr_count == 0 || build->substr_types[build->substr_count-1] != MD_TEXT_NORMAL) - MD_CHECK(md_build_attr_append_substr(ctx, build, MD_TEXT_NORMAL, off)); - - if(!(flags & MD_BUILD_ATTR_NO_ESCAPES) && - raw_text[raw_off] == _T('\\') && raw_off+1 < raw_size && - (ISPUNCT_(raw_text[raw_off+1]) || ISNEWLINE_(raw_text[raw_off+1]))) - raw_off++; - - build->text[off++] = raw_text[raw_off++]; - } - build->substr_offsets[build->substr_count] = off; - } - - attr->text = build->text; - attr->size = off; - attr->substr_offsets = build->substr_offsets; - attr->substr_types = build->substr_types; - return 0; - -abort: - md_free_attribute(ctx, build); - return -1; -} - - -/********************************************* - *** Dictionary of Reference Definitions *** - *********************************************/ - -#define MD_FNV1A_BASE 2166136261U -#define MD_FNV1A_PRIME 16777619U - -static inline unsigned -md_fnv1a(unsigned base, const void* data, size_t n) -{ - const unsigned char* buf = (const unsigned char*) data; - unsigned hash = base; - size_t i; - - for(i = 0; i < n; i++) { - hash ^= buf[i]; - hash *= MD_FNV1A_PRIME; - } - - return hash; -} - - -struct MD_REF_DEF_tag { - CHAR* label; - CHAR* title; - unsigned hash; - SZ label_size; - SZ title_size; - OFF dest_beg; - OFF dest_end; - unsigned char label_needs_free : 1; - unsigned char title_needs_free : 1; -}; - -/* Label equivalence is quite complicated with regards to whitespace and case - * folding. This complicates computing a hash of it as well as direct comparison - * of two labels. */ - -static unsigned -md_link_label_hash(const CHAR* label, SZ size) -{ - unsigned hash = MD_FNV1A_BASE; - OFF off; - unsigned codepoint; - int is_whitespace = FALSE; - - off = md_skip_unicode_whitespace(label, 0, size); - while(off < size) { - SZ char_size; - - codepoint = md_decode_unicode(label, off, size, &char_size); - is_whitespace = ISUNICODEWHITESPACE_(codepoint) || ISNEWLINE_(label[off]); - - if(is_whitespace) { - codepoint = ' '; - hash = md_fnv1a(hash, &codepoint, sizeof(unsigned)); - off = md_skip_unicode_whitespace(label, off, size); - } else { - MD_UNICODE_FOLD_INFO fold_info; - - md_get_unicode_fold_info(codepoint, &fold_info); - hash = md_fnv1a(hash, fold_info.codepoints, fold_info.n_codepoints * sizeof(unsigned)); - off += char_size; - } - } - - return hash; -} - -static OFF -md_link_label_cmp_load_fold_info(const CHAR* label, OFF off, SZ size, - MD_UNICODE_FOLD_INFO* fold_info) -{ - unsigned codepoint; - SZ char_size; - - if(off >= size) { - /* Treat end of a link label as a whitespace. */ - goto whitespace; - } - - codepoint = md_decode_unicode(label, off, size, &char_size); - off += char_size; - if(ISUNICODEWHITESPACE_(codepoint)) { - /* Treat all whitespace as equivalent */ - goto whitespace; - } - - /* Get real folding info. */ - md_get_unicode_fold_info(codepoint, fold_info); - return off; - -whitespace: - fold_info->codepoints[0] = _T(' '); - fold_info->n_codepoints = 1; - return md_skip_unicode_whitespace(label, off, size); -} - -static int -md_link_label_cmp(const CHAR* a_label, SZ a_size, const CHAR* b_label, SZ b_size) -{ - OFF a_off; - OFF b_off; - MD_UNICODE_FOLD_INFO a_fi = { { 0 }, 0 }; - MD_UNICODE_FOLD_INFO b_fi = { { 0 }, 0 }; - OFF a_fi_off = 0; - OFF b_fi_off = 0; - int cmp; - - a_off = md_skip_unicode_whitespace(a_label, 0, a_size); - b_off = md_skip_unicode_whitespace(b_label, 0, b_size); - while(a_off < a_size || a_fi_off < a_fi.n_codepoints || - b_off < b_size || b_fi_off < b_fi.n_codepoints) - { - /* If needed, load fold info for next char. */ - if(a_fi_off >= a_fi.n_codepoints) { - a_fi_off = 0; - a_off = md_link_label_cmp_load_fold_info(a_label, a_off, a_size, &a_fi); - } - if(b_fi_off >= b_fi.n_codepoints) { - b_fi_off = 0; - b_off = md_link_label_cmp_load_fold_info(b_label, b_off, b_size, &b_fi); - } - - cmp = b_fi.codepoints[b_fi_off] - a_fi.codepoints[a_fi_off]; - if(cmp != 0) - return cmp; - - a_fi_off++; - b_fi_off++; - } - - return 0; -} - -typedef struct MD_REF_DEF_LIST_tag MD_REF_DEF_LIST; -struct MD_REF_DEF_LIST_tag { - int n_ref_defs; - int alloc_ref_defs; - MD_REF_DEF* ref_defs[]; /* Valid items always point into ctx->ref_defs[] */ -}; - -static int -md_ref_def_cmp(const void* a, const void* b) -{ - const MD_REF_DEF* a_ref = *(const MD_REF_DEF**)a; - const MD_REF_DEF* b_ref = *(const MD_REF_DEF**)b; - - if(a_ref->hash < b_ref->hash) - return -1; - else if(a_ref->hash > b_ref->hash) - return +1; - else - return md_link_label_cmp(a_ref->label, a_ref->label_size, b_ref->label, b_ref->label_size); -} - -static int -md_ref_def_cmp_for_sort(const void* a, const void* b) -{ - int cmp; - - cmp = md_ref_def_cmp(a, b); - - /* Ensure stability of the sorting. */ - if(cmp == 0) { - const MD_REF_DEF* a_ref = *(const MD_REF_DEF**)a; - const MD_REF_DEF* b_ref = *(const MD_REF_DEF**)b; - - if(a_ref < b_ref) - cmp = -1; - else if(a_ref > b_ref) - cmp = +1; - else - cmp = 0; - } - - return cmp; -} - -static int -md_build_ref_def_hashtable(MD_CTX* ctx) -{ - int i, j; - - if(ctx->n_ref_defs == 0) - return 0; - - ctx->ref_def_hashtable_size = (ctx->n_ref_defs * 5) / 4; - ctx->ref_def_hashtable = malloc(ctx->ref_def_hashtable_size * sizeof(void*)); - if(ctx->ref_def_hashtable == NULL) { - MD_LOG("malloc() failed."); - goto abort; - } - memset(ctx->ref_def_hashtable, 0, ctx->ref_def_hashtable_size * sizeof(void*)); - - /* Each member of ctx->ref_def_hashtable[] can be: - * -- NULL, - * -- pointer to the MD_REF_DEF in ctx->ref_defs[], or - * -- pointer to a MD_REF_DEF_LIST, which holds multiple pointers to - * such MD_REF_DEFs. - */ - for(i = 0; i < ctx->n_ref_defs; i++) { - MD_REF_DEF* def = &ctx->ref_defs[i]; - void* bucket; - MD_REF_DEF_LIST* list; - - def->hash = md_link_label_hash(def->label, def->label_size); - bucket = ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size]; - - if(bucket == NULL) { - /* The bucket is empty. Make it just point to the def. */ - ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size] = def; - continue; - } - - if(ctx->ref_defs <= (MD_REF_DEF*) bucket && (MD_REF_DEF*) bucket < ctx->ref_defs + ctx->n_ref_defs) { - /* The bucket already contains one ref. def. Lets see whether it - * is the same label (ref. def. duplicate) or different one - * (hash conflict). */ - MD_REF_DEF* old_def = (MD_REF_DEF*) bucket; - - if(md_link_label_cmp(def->label, def->label_size, old_def->label, old_def->label_size) == 0) { - /* Duplicate label: Ignore this ref. def. */ - continue; - } - - /* Make the bucket complex, i.e. able to hold more ref. defs. */ - list = (MD_REF_DEF_LIST*) malloc(sizeof(MD_REF_DEF_LIST) + 2 * sizeof(MD_REF_DEF*)); - if(list == NULL) { - MD_LOG("malloc() failed."); - goto abort; - } - list->ref_defs[0] = old_def; - list->ref_defs[1] = def; - list->n_ref_defs = 2; - list->alloc_ref_defs = 2; - ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size] = list; - continue; - } - - /* Append the def to the complex bucket list. - * - * Note in this case we ignore potential duplicates to avoid expensive - * iterating over the complex bucket. Below, we revisit all the complex - * buckets and handle it more cheaply after the complex bucket contents - * is sorted. */ - list = (MD_REF_DEF_LIST*) bucket; - if(list->n_ref_defs >= list->alloc_ref_defs) { - int alloc_ref_defs = list->alloc_ref_defs + list->alloc_ref_defs / 2; - MD_REF_DEF_LIST* list_tmp = (MD_REF_DEF_LIST*) realloc(list, - sizeof(MD_REF_DEF_LIST) + alloc_ref_defs * sizeof(MD_REF_DEF*)); - if(list_tmp == NULL) { - MD_LOG("realloc() failed."); - goto abort; - } - list = list_tmp; - list->alloc_ref_defs = alloc_ref_defs; - ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size] = list; - } - - list->ref_defs[list->n_ref_defs] = def; - list->n_ref_defs++; - } - - /* Sort the complex buckets so we can use bsearch() with them. */ - for(i = 0; i < ctx->ref_def_hashtable_size; i++) { - void* bucket = ctx->ref_def_hashtable[i]; - MD_REF_DEF_LIST* list; - - if(bucket == NULL) - continue; - if(ctx->ref_defs <= (MD_REF_DEF*) bucket && (MD_REF_DEF*) bucket < ctx->ref_defs + ctx->n_ref_defs) - continue; - - list = (MD_REF_DEF_LIST*) bucket; - qsort(list->ref_defs, list->n_ref_defs, sizeof(MD_REF_DEF*), md_ref_def_cmp_for_sort); - - /* Disable all duplicates in the complex bucket by forcing all such - * records to point to the 1st such ref. def. I.e. no matter which - * record is found during the lookup, it will always point to the right - * ref. def. in ctx->ref_defs[]. */ - for(j = 1; j < list->n_ref_defs; j++) { - if(md_ref_def_cmp(&list->ref_defs[j-1], &list->ref_defs[j]) == 0) - list->ref_defs[j] = list->ref_defs[j-1]; - } - } - - return 0; - -abort: - return -1; -} - -static void -md_free_ref_def_hashtable(MD_CTX* ctx) -{ - if(ctx->ref_def_hashtable != NULL) { - int i; - - for(i = 0; i < ctx->ref_def_hashtable_size; i++) { - void* bucket = ctx->ref_def_hashtable[i]; - if(bucket == NULL) - continue; - if(ctx->ref_defs <= (MD_REF_DEF*) bucket && (MD_REF_DEF*) bucket < ctx->ref_defs + ctx->n_ref_defs) - continue; - free(bucket); - } - - free(ctx->ref_def_hashtable); - } -} - -static const MD_REF_DEF* -md_lookup_ref_def(MD_CTX* ctx, const CHAR* label, SZ label_size) -{ - unsigned hash; - void* bucket; - - if(ctx->ref_def_hashtable_size == 0) - return NULL; - - hash = md_link_label_hash(label, label_size); - bucket = ctx->ref_def_hashtable[hash % ctx->ref_def_hashtable_size]; - - if(bucket == NULL) { - return NULL; - } else if(ctx->ref_defs <= (MD_REF_DEF*) bucket && (MD_REF_DEF*) bucket < ctx->ref_defs + ctx->n_ref_defs) { - const MD_REF_DEF* def = (MD_REF_DEF*) bucket; - - if(md_link_label_cmp(def->label, def->label_size, label, label_size) == 0) - return def; - else - return NULL; - } else { - MD_REF_DEF_LIST* list = (MD_REF_DEF_LIST*) bucket; - MD_REF_DEF key_buf; - const MD_REF_DEF* key = &key_buf; - const MD_REF_DEF** ret; - - key_buf.label = (CHAR*) label; - key_buf.label_size = label_size; - key_buf.hash = md_link_label_hash(key_buf.label, key_buf.label_size); - - ret = (const MD_REF_DEF**) bsearch(&key, list->ref_defs, - list->n_ref_defs, sizeof(MD_REF_DEF*), md_ref_def_cmp); - if(ret != NULL) - return *ret; - else - return NULL; - } -} - - -/*************************** - *** Recognizing Links *** - ***************************/ - -/* Note this code is partially shared between processing inlines and blocks - * as reference definitions and links share some helper parser functions. - */ - -typedef struct MD_LINK_ATTR_tag MD_LINK_ATTR; -struct MD_LINK_ATTR_tag { - OFF dest_beg; - OFF dest_end; - - CHAR* title; - SZ title_size; - int title_needs_free; -}; - - -static int -md_is_link_label(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, - OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index, - OFF* p_contents_beg, OFF* p_contents_end) -{ - OFF off = beg; - OFF contents_beg = 0; - OFF contents_end = 0; - MD_SIZE line_index = 0; - int len = 0; - - *p_beg_line_index = 0; - - if(CH(off) != _T('[')) - return FALSE; - off++; - - while(1) { - OFF line_end = lines[line_index].end; - - while(off < line_end) { - if(CH(off) == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { - if(contents_end == 0) { - contents_beg = off; - *p_beg_line_index = line_index; - } - contents_end = off + 2; - off += 2; - } else if(CH(off) == _T('[')) { - return FALSE; - } else if(CH(off) == _T(']')) { - if(contents_beg < contents_end) { - /* Success. */ - *p_contents_beg = contents_beg; - *p_contents_end = contents_end; - *p_end = off+1; - *p_end_line_index = line_index; - return TRUE; - } else { - /* Link label must have some non-whitespace contents. */ - return FALSE; - } - } else { - unsigned codepoint; - SZ char_size; - - codepoint = md_decode_unicode(ctx->text, off, ctx->size, &char_size); - if(!ISUNICODEWHITESPACE_(codepoint)) { - if(contents_end == 0) { - contents_beg = off; - *p_beg_line_index = line_index; - } - contents_end = off + char_size; - } - - off += char_size; - } - - len++; - if(len > 999) - return FALSE; - } - - line_index++; - len++; - if(line_index < n_lines) - off = lines[line_index].beg; - else - break; - } - - return FALSE; -} - -static int -md_is_link_destination_A(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, - OFF* p_contents_beg, OFF* p_contents_end) -{ - OFF off = beg; - - if(off >= max_end || CH(off) != _T('<')) - return FALSE; - off++; - - while(off < max_end) { - if(CH(off) == _T('\\') && off+1 < max_end && ISPUNCT(off+1)) { - off += 2; - continue; - } - - if(ISNEWLINE(off) || CH(off) == _T('<')) - return FALSE; - - if(CH(off) == _T('>')) { - /* Success. */ - *p_contents_beg = beg+1; - *p_contents_end = off; - *p_end = off+1; - return TRUE; - } - - off++; - } - - return FALSE; -} - -static int -md_is_link_destination_B(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, - OFF* p_contents_beg, OFF* p_contents_end) -{ - OFF off = beg; - int parenthesis_level = 0; - - while(off < max_end) { - if(CH(off) == _T('\\') && off+1 < max_end && ISPUNCT(off+1)) { - off += 2; - continue; - } - - if(ISWHITESPACE(off) || ISCNTRL(off)) - break; - - /* Link destination may include balanced pairs of unescaped '(' ')'. - * Note we limit the maximal nesting level by 32 to protect us from - * https://github.com/jgm/cmark/issues/214 */ - if(CH(off) == _T('(')) { - parenthesis_level++; - if(parenthesis_level > 32) - return FALSE; - } else if(CH(off) == _T(')')) { - if(parenthesis_level == 0) - break; - parenthesis_level--; - } - - off++; - } - - if(parenthesis_level != 0 || off == beg) - return FALSE; - - /* Success. */ - *p_contents_beg = beg; - *p_contents_end = off; - *p_end = off; - return TRUE; -} - -static inline int -md_is_link_destination(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, - OFF* p_contents_beg, OFF* p_contents_end) -{ - if(CH(beg) == _T('<')) - return md_is_link_destination_A(ctx, beg, max_end, p_end, p_contents_beg, p_contents_end); - else - return md_is_link_destination_B(ctx, beg, max_end, p_end, p_contents_beg, p_contents_end); -} - -static int -md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, - OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index, - OFF* p_contents_beg, OFF* p_contents_end) -{ - OFF off = beg; - CHAR closer_char; - MD_SIZE line_index = 0; - - /* White space with up to one line break. */ - while(off < lines[line_index].end && ISWHITESPACE(off)) - off++; - if(off >= lines[line_index].end) { - line_index++; - if(line_index >= n_lines) - return FALSE; - off = lines[line_index].beg; - } - if(off == beg) - return FALSE; - - *p_beg_line_index = line_index; - - /* First char determines how to detect end of it. */ - switch(CH(off)) { - case _T('"'): closer_char = _T('"'); break; - case _T('\''): closer_char = _T('\''); break; - case _T('('): closer_char = _T(')'); break; - default: return FALSE; - } - off++; - - *p_contents_beg = off; - - while(line_index < n_lines) { - OFF line_end = lines[line_index].end; - - while(off < line_end) { - if(CH(off) == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { - off++; - } else if(CH(off) == closer_char) { - /* Success. */ - *p_contents_end = off; - *p_end = off+1; - *p_end_line_index = line_index; - return TRUE; - } else if(closer_char == _T(')') && CH(off) == _T('(')) { - /* ()-style title cannot contain (unescaped '(')) */ - return FALSE; - } - - off++; - } - - line_index++; - } - - return FALSE; -} - -/* Returns 0 if it is not a reference definition. - * - * Returns N > 0 if it is a reference definition. N then corresponds to the - * number of lines forming it). In this case the definition is stored for - * resolving any links referring to it. - * - * Returns -1 in case of an error (out of memory). - */ -static int -md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) -{ - OFF label_contents_beg; - OFF label_contents_end; - MD_SIZE label_contents_line_index; - int label_is_multiline = FALSE; - OFF dest_contents_beg; - OFF dest_contents_end; - OFF title_contents_beg; - OFF title_contents_end; - MD_SIZE title_contents_line_index; - int title_is_multiline = FALSE; - OFF off; - MD_SIZE line_index = 0; - MD_SIZE tmp_line_index; - MD_REF_DEF* def = NULL; - int ret = 0; - - /* Link label. */ - if(!md_is_link_label(ctx, lines, n_lines, lines[0].beg, - &off, &label_contents_line_index, &line_index, - &label_contents_beg, &label_contents_end)) - return FALSE; - label_is_multiline = (label_contents_line_index != line_index); - - /* Colon. */ - if(off >= lines[line_index].end || CH(off) != _T(':')) - return FALSE; - off++; - - /* Optional white space with up to one line break. */ - while(off < lines[line_index].end && ISWHITESPACE(off)) - off++; - if(off >= lines[line_index].end) { - line_index++; - if(line_index >= n_lines) - return FALSE; - off = lines[line_index].beg; - } - - /* Link destination. */ - if(!md_is_link_destination(ctx, off, lines[line_index].end, - &off, &dest_contents_beg, &dest_contents_end)) - return FALSE; - - /* (Optional) title. Note we interpret it as an title only if nothing - * more follows on its last line. */ - if(md_is_link_title(ctx, lines + line_index, n_lines - line_index, off, - &off, &title_contents_line_index, &tmp_line_index, - &title_contents_beg, &title_contents_end) - && off >= lines[line_index + tmp_line_index].end) - { - title_is_multiline = (tmp_line_index != title_contents_line_index); - title_contents_line_index += line_index; - line_index += tmp_line_index; - } else { - /* Not a title. */ - title_is_multiline = FALSE; - title_contents_beg = off; - title_contents_end = off; - title_contents_line_index = 0; - } - - /* Nothing more can follow on the last line. */ - if(off < lines[line_index].end) - return FALSE; - - /* So, it _is_ a reference definition. Remember it. */ - if(ctx->n_ref_defs >= ctx->alloc_ref_defs) { - MD_REF_DEF* new_defs; - - ctx->alloc_ref_defs = (ctx->alloc_ref_defs > 0 - ? ctx->alloc_ref_defs + ctx->alloc_ref_defs / 2 - : 16); - new_defs = (MD_REF_DEF*) realloc(ctx->ref_defs, ctx->alloc_ref_defs * sizeof(MD_REF_DEF)); - if(new_defs == NULL) { - MD_LOG("realloc() failed."); - goto abort; - } - - ctx->ref_defs = new_defs; - } - def = &ctx->ref_defs[ctx->n_ref_defs]; - memset(def, 0, sizeof(MD_REF_DEF)); - - if(label_is_multiline) { - MD_CHECK(md_merge_lines_alloc(ctx, label_contents_beg, label_contents_end, - lines + label_contents_line_index, n_lines - label_contents_line_index, - _T(' '), &def->label, &def->label_size)); - def->label_needs_free = TRUE; - } else { - def->label = (CHAR*) STR(label_contents_beg); - def->label_size = label_contents_end - label_contents_beg; - } - - if(title_is_multiline) { - MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end, - lines + title_contents_line_index, n_lines - title_contents_line_index, - _T('\n'), &def->title, &def->title_size)); - def->title_needs_free = TRUE; - } else { - def->title = (CHAR*) STR(title_contents_beg); - def->title_size = title_contents_end - title_contents_beg; - } - - def->dest_beg = dest_contents_beg; - def->dest_end = dest_contents_end; - - /* Success. */ - ctx->n_ref_defs++; - return line_index + 1; - -abort: - /* Failure. */ - if(def != NULL && def->label_needs_free) - free(def->label); - if(def != NULL && def->title_needs_free) - free(def->title); - return ret; -} - -static int -md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - OFF beg, OFF end, MD_LINK_ATTR* attr) -{ - const MD_REF_DEF* def; - const MD_LINE* beg_line; - int is_multiline; - CHAR* label; - SZ label_size; - int ret = FALSE; - - MD_ASSERT(CH(beg) == _T('[') || CH(beg) == _T('!')); - MD_ASSERT(CH(end-1) == _T(']')); - - if(ctx->max_ref_def_output == 0) - return FALSE; - - beg += (CH(beg) == _T('!') ? 2 : 1); - end--; - - /* Find lines corresponding to the beg and end positions. */ - beg_line = md_lookup_line(beg, lines, n_lines, NULL); - is_multiline = (end > beg_line->end); - - if(is_multiline) { - MD_CHECK(md_merge_lines_alloc(ctx, beg, end, beg_line, - (int)(n_lines - (beg_line - lines)), _T(' '), &label, &label_size)); - } else { - label = (CHAR*) STR(beg); - label_size = end - beg; - } - - def = md_lookup_ref_def(ctx, label, label_size); - if(def != NULL) { - attr->dest_beg = def->dest_beg; - attr->dest_end = def->dest_end; - attr->title = def->title; - attr->title_size = def->title_size; - attr->title_needs_free = FALSE; - } - - if(is_multiline) - free(label); - - if(def != NULL) { - /* See https://github.com/mity/md4c/issues/238 */ - MD_SIZE output_size_estimation = def->label_size + def->title_size + def->dest_end - def->dest_beg; - if(output_size_estimation < ctx->max_ref_def_output) { - ctx->max_ref_def_output -= output_size_estimation; - ret = TRUE; - } else { - MD_LOG("Too many link reference definition instantiations."); - ctx->max_ref_def_output = 0; - } - } - -abort: - return ret; -} - -static int -md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - OFF beg, OFF* p_end, MD_LINK_ATTR* attr) -{ - MD_SIZE line_index = 0; - MD_SIZE tmp_line_index; - OFF title_contents_beg; - OFF title_contents_end; - MD_SIZE title_contents_line_index; - int title_is_multiline; - OFF off = beg; - int ret = FALSE; - - md_lookup_line(off, lines, n_lines, &line_index); - - MD_ASSERT(CH(off) == _T('(')); - off++; - - /* Optional white space with up to one line break. */ - while(off < lines[line_index].end && ISWHITESPACE(off)) - off++; - if(off >= lines[line_index].end && (off >= ctx->size || ISNEWLINE(off))) { - line_index++; - if(line_index >= n_lines) - return FALSE; - off = lines[line_index].beg; - } - - /* Link destination may be omitted, but only when not also having a title. */ - if(off < ctx->size && CH(off) == _T(')')) { - attr->dest_beg = off; - attr->dest_end = off; - attr->title = NULL; - attr->title_size = 0; - attr->title_needs_free = FALSE; - off++; - *p_end = off; - return TRUE; - } - - /* Link destination. */ - if(!md_is_link_destination(ctx, off, lines[line_index].end, - &off, &attr->dest_beg, &attr->dest_end)) - return FALSE; - - /* (Optional) title. */ - if(md_is_link_title(ctx, lines + line_index, n_lines - line_index, off, - &off, &title_contents_line_index, &tmp_line_index, - &title_contents_beg, &title_contents_end)) - { - title_is_multiline = (tmp_line_index != title_contents_line_index); - title_contents_line_index += line_index; - line_index += tmp_line_index; - } else { - /* Not a title. */ - title_is_multiline = FALSE; - title_contents_beg = off; - title_contents_end = off; - title_contents_line_index = 0; - } - - /* Optional whitespace followed with final ')'. */ - while(off < lines[line_index].end && ISWHITESPACE(off)) - off++; - if(off >= lines[line_index].end) { - line_index++; - if(line_index >= n_lines) - return FALSE; - off = lines[line_index].beg; - } - if(CH(off) != _T(')')) - goto abort; - off++; - - if(title_contents_beg >= title_contents_end) { - attr->title = NULL; - attr->title_size = 0; - attr->title_needs_free = FALSE; - } else if(!title_is_multiline) { - attr->title = (CHAR*) STR(title_contents_beg); - attr->title_size = title_contents_end - title_contents_beg; - attr->title_needs_free = FALSE; - } else { - MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end, - lines + title_contents_line_index, n_lines - title_contents_line_index, - _T('\n'), &attr->title, &attr->title_size)); - attr->title_needs_free = TRUE; - } - - *p_end = off; - ret = TRUE; - -abort: - return ret; -} - -static void -md_free_ref_defs(MD_CTX* ctx) -{ - int i; - - for(i = 0; i < ctx->n_ref_defs; i++) { - MD_REF_DEF* def = &ctx->ref_defs[i]; - - if(def->label_needs_free) - free(def->label); - if(def->title_needs_free) - free(def->title); - } - - free(ctx->ref_defs); -} - - -/****************************************** - *** Processing Inlines (a.k.a Spans) *** - ******************************************/ - -/* We process inlines in few phases: - * - * (1) We go through the block text and collect all significant characters - * which may start/end a span or some other significant position into - * ctx->marks[]. Core of this is what md_collect_marks() does. - * - * We also do some very brief preliminary context-less analysis, whether - * it might be opener or closer (e.g. of an emphasis span). - * - * This speeds the other steps as we do not need to re-iterate over all - * characters anymore. - * - * (2) We analyze each potential mark types, in order by their precedence. - * - * In each md_analyze_XXX() function, we re-iterate list of the marks, - * skipping already resolved regions (in preceding precedences) and try to - * resolve them. - * - * (2.1) For trivial marks, which are single (e.g. HTML entity), we just mark - * them as resolved. - * - * (2.2) For range-type marks, we analyze whether the mark could be closer - * and, if yes, whether there is some preceding opener it could satisfy. - * - * If not we check whether it could be really an opener and if yes, we - * remember it so subsequent closers may resolve it. - * - * (3) Finally, when all marks were analyzed, we render the block contents - * by calling MD_RENDERER::text() callback, interrupting by ::enter_span() - * or ::close_span() whenever we reach a resolved mark. - */ - - -/* The mark structure. - * - * '\\': Maybe escape sequence. - * '\0': NULL char. - * '*': Maybe (strong) emphasis start/end. - * '_': Maybe (strong) emphasis start/end. - * '~': Maybe strikethrough start/end (needs MD_FLAG_STRIKETHROUGH). - * '`': Maybe code span start/end. - * '&': Maybe start of entity. - * ';': Maybe end of entity. - * '<': Maybe start of raw HTML or autolink. - * '>': Maybe end of raw HTML or autolink. - * '[': Maybe start of link label or link text. - * '!': Equivalent of '[' for image. - * ']': Maybe end of link label or link text. - * '@': Maybe permissive e-mail auto-link (needs MD_FLAG_PERMISSIVEEMAILAUTOLINKS). - * ':': Maybe permissive URL auto-link (needs MD_FLAG_PERMISSIVEURLAUTOLINKS). - * '.': Maybe permissive WWW auto-link (needs MD_FLAG_PERMISSIVEWWWAUTOLINKS). - * 'D': Dummy mark, it reserves a space for splitting a previous mark - * (e.g. emphasis) or to make more space for storing some special data - * related to the preceding mark (e.g. link). - * - * Note that not all instances of these chars in the text imply creation of the - * structure. Only those which have (or may have, after we see more context) - * the special meaning. - * - * (Keep this struct as small as possible to fit as much of them into CPU - * cache line.) - */ -struct MD_MARK_tag { - OFF beg; - OFF end; - - /* For unresolved openers, 'next' may be used to form a stack of - * unresolved open openers. - * - * When resolved with MD_MARK_OPENER/CLOSER flag, next/prev is index of the - * respective closer/opener. - */ - int prev; - int next; - CHAR ch; - unsigned char flags; -}; - -/* Mark flags (these apply to ALL mark types). */ -#define MD_MARK_POTENTIAL_OPENER 0x01 /* Maybe opener. */ -#define MD_MARK_POTENTIAL_CLOSER 0x02 /* Maybe closer. */ -#define MD_MARK_OPENER 0x04 /* Definitely opener. */ -#define MD_MARK_CLOSER 0x08 /* Definitely closer. */ -#define MD_MARK_RESOLVED 0x10 /* Resolved in any definite way. */ - -/* Mark flags specific for various mark types (so they can share bits). */ -#define MD_MARK_EMPH_OC 0x20 /* Opener/closer mixed candidate. Helper for the "rule of 3". */ -#define MD_MARK_EMPH_MOD3_0 0x40 -#define MD_MARK_EMPH_MOD3_1 0x80 -#define MD_MARK_EMPH_MOD3_2 (0x40 | 0x80) -#define MD_MARK_EMPH_MOD3_MASK (0x40 | 0x80) -#define MD_MARK_AUTOLINK 0x20 /* Distinguisher for '<', '>'. */ -#define MD_MARK_AUTOLINK_MISSING_MAILTO 0x40 -#define MD_MARK_VALIDPERMISSIVEAUTOLINK 0x20 /* For permissive autolinks. */ -#define MD_MARK_HASNESTEDBRACKETS 0x20 /* For '[' to rule out invalid link labels early */ - -static MD_MARKSTACK* -md_emph_stack(MD_CTX* ctx, MD_CHAR ch, unsigned flags) -{ - MD_MARKSTACK* stack; - - switch(ch) { - case '*': stack = &ASTERISK_OPENERS_oo_mod3_0; break; - case '_': stack = &UNDERSCORE_OPENERS_oo_mod3_0; break; - default: MD_UNREACHABLE(); - } - - if(flags & MD_MARK_EMPH_OC) - stack += 3; - - switch(flags & MD_MARK_EMPH_MOD3_MASK) { - case MD_MARK_EMPH_MOD3_0: stack += 0; break; - case MD_MARK_EMPH_MOD3_1: stack += 1; break; - case MD_MARK_EMPH_MOD3_2: stack += 2; break; - default: MD_UNREACHABLE(); - } - - return stack; -} - -static MD_MARKSTACK* -md_opener_stack(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - switch(mark->ch) { - case _T('*'): - case _T('_'): return md_emph_stack(ctx, mark->ch, mark->flags); - - case _T('~'): return (mark->end - mark->beg == 1) ? &TILDE_OPENERS_1 : &TILDE_OPENERS_2; - - case _T('!'): - case _T('['): return &BRACKET_OPENERS; - - default: MD_UNREACHABLE(); - } -} - -static MD_MARK* -md_add_mark(MD_CTX* ctx) -{ - if(ctx->n_marks >= ctx->alloc_marks) { - MD_MARK* new_marks; - - ctx->alloc_marks = (ctx->alloc_marks > 0 - ? ctx->alloc_marks + ctx->alloc_marks / 2 - : 64); - new_marks = realloc(ctx->marks, ctx->alloc_marks * sizeof(MD_MARK)); - if(new_marks == NULL) { - MD_LOG("realloc() failed."); - return NULL; - } - - ctx->marks = new_marks; - } - - return &ctx->marks[ctx->n_marks++]; -} - -#define ADD_MARK_() \ - do { \ - mark = md_add_mark(ctx); \ - if(mark == NULL) { \ - ret = -1; \ - goto abort; \ - } \ - } while(0) - -#define ADD_MARK(ch_, beg_, end_, flags_) \ - do { \ - ADD_MARK_(); \ - mark->beg = (beg_); \ - mark->end = (end_); \ - mark->prev = -1; \ - mark->next = -1; \ - mark->ch = (char)(ch_); \ - mark->flags = (flags_); \ - } while(0) - - -static inline void -md_mark_stack_push(MD_CTX* ctx, MD_MARKSTACK* stack, int mark_index) -{ - ctx->marks[mark_index].next = stack->top; - stack->top = mark_index; -} - -static inline int -md_mark_stack_pop(MD_CTX* ctx, MD_MARKSTACK* stack) -{ - int top = stack->top; - if(top >= 0) - stack->top = ctx->marks[top].next; - return top; -} - -/* Sometimes, we need to store a pointer into the mark. It is quite rare - * so we do not bother to make MD_MARK use union, and it can only happen - * for dummy marks. */ -static inline void -md_mark_store_ptr(MD_CTX* ctx, int mark_index, void* ptr) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - MD_ASSERT(mark->ch == 'D'); - - /* Check only members beg and end are misused for this. */ - MD_ASSERT(sizeof(void*) <= 2 * sizeof(OFF)); - memcpy(mark, &ptr, sizeof(void*)); -} - -static inline void* -md_mark_get_ptr(MD_CTX* ctx, int mark_index) -{ - void* ptr; - MD_MARK* mark = &ctx->marks[mark_index]; - MD_ASSERT(mark->ch == 'D'); - memcpy(&ptr, mark, sizeof(void*)); - return ptr; -} - -static inline void -md_resolve_range(MD_CTX* ctx, int opener_index, int closer_index) -{ - MD_MARK* opener = &ctx->marks[opener_index]; - MD_MARK* closer = &ctx->marks[closer_index]; - - /* Interconnect opener and closer and mark both as resolved. */ - opener->next = closer_index; - closer->prev = opener_index; - - opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; - closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED; -} - - -#define MD_ROLLBACK_CROSSING 0 -#define MD_ROLLBACK_ALL 1 - -/* In the range ctx->marks[opener_index] ... [closer_index], undo some or all - * resolvings accordingly to these rules: - * - * (1) All stacks of openers are cut so that any pending potential openers - * are discarded from future consideration. - * - * (2) If 'how' is MD_ROLLBACK_ALL, then ALL resolved marks inside the range - * are thrown away and turned into dummy marks ('D'). - * - * WARNING: Do not call for arbitrary range of opener and closer. - * This must form (potentially) valid range not crossing nesting boundaries - * of already resolved ranges. - */ -static void -md_rollback(MD_CTX* ctx, int opener_index, int closer_index, int how) -{ - int i; - - for(i = 0; i < (int) SIZEOF_ARRAY(ctx->opener_stacks); i++) { - MD_MARKSTACK* stack = &ctx->opener_stacks[i]; - while(stack->top >= opener_index) - md_mark_stack_pop(ctx, stack); - } - - if(how == MD_ROLLBACK_ALL) { - for(i = opener_index + 1; i < closer_index; i++) { - ctx->marks[i].ch = 'D'; - ctx->marks[i].flags = 0; - } - } -} - -static void -md_build_mark_char_map(MD_CTX* ctx) -{ - memset(ctx->mark_char_map, 0, sizeof(ctx->mark_char_map)); - - ctx->mark_char_map['\\'] = 1; - ctx->mark_char_map['*'] = 1; - ctx->mark_char_map['_'] = 1; - ctx->mark_char_map['`'] = 1; - ctx->mark_char_map['&'] = 1; - ctx->mark_char_map[';'] = 1; - ctx->mark_char_map['<'] = 1; - ctx->mark_char_map['>'] = 1; - ctx->mark_char_map['['] = 1; - ctx->mark_char_map['!'] = 1; - ctx->mark_char_map[']'] = 1; - ctx->mark_char_map['\0'] = 1; - - if(ctx->parser.flags & MD_FLAG_STRIKETHROUGH) - ctx->mark_char_map['~'] = 1; - - if(ctx->parser.flags & MD_FLAG_LATEXMATHSPANS) - ctx->mark_char_map['$'] = 1; - - if(ctx->parser.flags & MD_FLAG_PERMISSIVEEMAILAUTOLINKS) - ctx->mark_char_map['@'] = 1; - - if(ctx->parser.flags & MD_FLAG_PERMISSIVEURLAUTOLINKS) - ctx->mark_char_map[':'] = 1; - - if(ctx->parser.flags & MD_FLAG_PERMISSIVEWWWAUTOLINKS) - ctx->mark_char_map['.'] = 1; - - if((ctx->parser.flags & MD_FLAG_TABLES) || (ctx->parser.flags & MD_FLAG_WIKILINKS)) - ctx->mark_char_map['|'] = 1; - - if(ctx->parser.flags & MD_FLAG_COLLAPSEWHITESPACE) { - int i; - - for(i = 0; i < (int) sizeof(ctx->mark_char_map); i++) { - if(ISWHITESPACE_(i)) - ctx->mark_char_map[i] = 1; - } - } -} - -static int -md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, - MD_MARK* opener, MD_MARK* closer, - OFF last_potential_closers[CODESPAN_MARK_MAXLEN], - int* p_reached_paragraph_end) -{ - OFF opener_beg = beg; - OFF opener_end; - OFF closer_beg; - OFF closer_end; - SZ mark_len; - OFF line_end; - int has_space_after_opener = FALSE; - int has_eol_after_opener = FALSE; - int has_space_before_closer = FALSE; - int has_eol_before_closer = FALSE; - int has_only_space = TRUE; - MD_SIZE line_index = 0; - - line_end = lines[0].end; - opener_end = opener_beg; - while(opener_end < line_end && CH(opener_end) == _T('`')) - opener_end++; - has_space_after_opener = (opener_end < line_end && CH(opener_end) == _T(' ')); - has_eol_after_opener = (opener_end == line_end); - - /* The caller needs to know end of the opening mark even if we fail. */ - opener->end = opener_end; - - mark_len = opener_end - opener_beg; - if(mark_len > CODESPAN_MARK_MAXLEN) - return FALSE; - - /* Check whether we already know there is no closer of this length. - * If so, re-scan does no sense. This fixes issue #59. */ - if(last_potential_closers[mark_len-1] >= lines[n_lines-1].end || - (*p_reached_paragraph_end && last_potential_closers[mark_len-1] < opener_end)) - return FALSE; - - closer_beg = opener_end; - closer_end = opener_end; - - /* Find closer mark. */ - while(TRUE) { - while(closer_beg < line_end && CH(closer_beg) != _T('`')) { - if(CH(closer_beg) != _T(' ')) - has_only_space = FALSE; - closer_beg++; - } - closer_end = closer_beg; - while(closer_end < line_end && CH(closer_end) == _T('`')) - closer_end++; - - if(closer_end - closer_beg == mark_len) { - /* Success. */ - has_space_before_closer = (closer_beg > lines[line_index].beg && CH(closer_beg-1) == _T(' ')); - has_eol_before_closer = (closer_beg == lines[line_index].beg); - break; - } - - if(closer_end - closer_beg > 0) { - /* We have found a back-tick which is not part of the closer. */ - has_only_space = FALSE; - - /* But if we eventually fail, remember it as a potential closer - * of its own length for future attempts. This mitigates needs for - * rescans. */ - if(closer_end - closer_beg < CODESPAN_MARK_MAXLEN) { - if(closer_beg > last_potential_closers[closer_end - closer_beg - 1]) - last_potential_closers[closer_end - closer_beg - 1] = closer_beg; - } - } - - if(closer_end >= line_end) { - line_index++; - if(line_index >= n_lines) { - /* Reached end of the paragraph and still nothing. */ - *p_reached_paragraph_end = TRUE; - return FALSE; - } - /* Try on the next line. */ - line_end = lines[line_index].end; - closer_beg = lines[line_index].beg; - } else { - closer_beg = closer_end; - } - } - - /* If there is a space or a new line both after and before the opener - * (and if the code span is not made of spaces only), consume one initial - * and one trailing space as part of the marks. */ - if(!has_only_space && - (has_space_after_opener || has_eol_after_opener) && - (has_space_before_closer || has_eol_before_closer)) - { - if(has_space_after_opener) - opener_end++; - else - opener_end = lines[1].beg; - - if(has_space_before_closer) - closer_beg--; - else { - /* Go back to the end of prev line */ - closer_beg = lines[line_index-1].end; - /* But restore any trailing whitespace */ - while(closer_beg < ctx->size && ISBLANK(closer_beg)) - closer_beg++; - } - } - - opener->ch = _T('`'); - opener->beg = opener_beg; - opener->end = opener_end; - opener->flags = MD_MARK_POTENTIAL_OPENER; - closer->ch = _T('`'); - closer->beg = closer_beg; - closer->end = closer_end; - closer->flags = MD_MARK_POTENTIAL_CLOSER; - return TRUE; -} - -static int -md_is_autolink_uri(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg+1; - - MD_ASSERT(CH(beg) == _T('<')); - - /* Check for scheme. */ - if(off >= max_end || !ISASCII(off)) - return FALSE; - off++; - while(1) { - if(off >= max_end) - return FALSE; - if(off - beg > 32) - return FALSE; - if(CH(off) == _T(':') && off - beg >= 3) - break; - if(!ISALNUM(off) && CH(off) != _T('+') && CH(off) != _T('-') && CH(off) != _T('.')) - return FALSE; - off++; - } - - /* Check the path after the scheme. */ - while(off < max_end && CH(off) != _T('>')) { - if(ISWHITESPACE(off) || ISCNTRL(off) || CH(off) == _T('<')) - return FALSE; - off++; - } - - if(off >= max_end) - return FALSE; - - MD_ASSERT(CH(off) == _T('>')); - *p_end = off+1; - return TRUE; -} - -static int -md_is_autolink_email(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg + 1; - int label_len; - - MD_ASSERT(CH(beg) == _T('<')); - - /* The code should correspond to this regexp: - /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+ - @[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])? - (?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ - */ - - /* Username (before '@'). */ - while(off < max_end && (ISALNUM(off) || ISANYOF(off, _T(".!#$%&'*+/=?^_`{|}~-")))) - off++; - if(off <= beg+1) - return FALSE; - - /* '@' */ - if(off >= max_end || CH(off) != _T('@')) - return FALSE; - off++; - - /* Labels delimited with '.'; each label is sequence of 1 - 63 alnum - * characters or '-', but '-' is not allowed as first or last char. */ - label_len = 0; - while(off < max_end) { - if(ISALNUM(off)) - label_len++; - else if(CH(off) == _T('-') && label_len > 0) - label_len++; - else if(CH(off) == _T('.') && label_len > 0 && CH(off-1) != _T('-')) - label_len = 0; - else - break; - - if(label_len > 63) - return FALSE; - - off++; - } - - if(label_len <= 0 || off >= max_end || CH(off) != _T('>') || CH(off-1) == _T('-')) - return FALSE; - - *p_end = off+1; - return TRUE; -} - -static int -md_is_autolink(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, int* p_missing_mailto) -{ - if(md_is_autolink_uri(ctx, beg, max_end, p_end)) { - *p_missing_mailto = FALSE; - return TRUE; - } - - if(md_is_autolink_email(ctx, beg, max_end, p_end)) { - *p_missing_mailto = TRUE; - return TRUE; - } - - return FALSE; -} - -static int -md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int table_mode) -{ - MD_SIZE line_index; - int ret = 0; - MD_MARK* mark; - OFF codespan_last_potential_closers[CODESPAN_MARK_MAXLEN] = { 0 }; - int codespan_scanned_till_paragraph_end = FALSE; - - for(line_index = 0; line_index < n_lines; line_index++) { - const MD_LINE* line = &lines[line_index]; - OFF off = line->beg; - - while(TRUE) { - CHAR ch; - -#ifdef MD4C_USE_UTF16 - /* For UTF-16, mark_char_map[] covers only ASCII. */ - #define IS_MARK_CHAR(off) ((CH(off) < SIZEOF_ARRAY(ctx->mark_char_map)) && \ - (ctx->mark_char_map[(unsigned char) CH(off)])) -#else - /* For 8-bit encodings, mark_char_map[] covers all 256 elements. */ - #define IS_MARK_CHAR(off) (ctx->mark_char_map[(unsigned char) CH(off)]) -#endif - - /* Optimization: Use some loop unrolling. */ - while(off + 3 < line->end && !IS_MARK_CHAR(off+0) && !IS_MARK_CHAR(off+1) - && !IS_MARK_CHAR(off+2) && !IS_MARK_CHAR(off+3)) - off += 4; - while(off < line->end && !IS_MARK_CHAR(off+0)) - off++; - - if(off >= line->end) - break; - - ch = CH(off); - - /* A backslash escape. - * It can go beyond line->end as it may involve escaped new - * line to form a hard break. */ - if(ch == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { - /* Hard-break cannot be on the last line of the block. */ - if(!ISNEWLINE(off+1) || line_index+1 < n_lines) - ADD_MARK(ch, off, off+2, MD_MARK_RESOLVED); - off += 2; - continue; - } - - /* A potential (string) emphasis start/end. */ - if(ch == _T('*') || ch == _T('_')) { - OFF tmp = off+1; - int left_level; /* What precedes: 0 = whitespace; 1 = punctuation; 2 = other char. */ - int right_level; /* What follows: 0 = whitespace; 1 = punctuation; 2 = other char. */ - - while(tmp < line->end && CH(tmp) == ch) - tmp++; - - if(off == line->beg || ISUNICODEWHITESPACEBEFORE(off)) - left_level = 0; - else if(ISUNICODEPUNCTBEFORE(off)) - left_level = 1; - else - left_level = 2; - - if(tmp == line->end || ISUNICODEWHITESPACE(tmp)) - right_level = 0; - else if(ISUNICODEPUNCT(tmp)) - right_level = 1; - else - right_level = 2; - - /* Intra-word underscore doesn't have special meaning. */ - if(ch == _T('_') && left_level == 2 && right_level == 2) { - left_level = 0; - right_level = 0; - } - - if(left_level != 0 || right_level != 0) { - unsigned flags = 0; - - if(left_level > 0 && left_level >= right_level) - flags |= MD_MARK_POTENTIAL_CLOSER; - if(right_level > 0 && right_level >= left_level) - flags |= MD_MARK_POTENTIAL_OPENER; - if(flags == (MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER)) - flags |= MD_MARK_EMPH_OC; - - /* For "the rule of three" we need to remember the original - * size of the mark (modulo three), before we potentially - * split the mark when being later resolved partially by some - * shorter closer. */ - switch((tmp - off) % 3) { - case 0: flags |= MD_MARK_EMPH_MOD3_0; break; - case 1: flags |= MD_MARK_EMPH_MOD3_1; break; - case 2: flags |= MD_MARK_EMPH_MOD3_2; break; - } - - ADD_MARK(ch, off, tmp, flags); - - /* During resolving, multiple asterisks may have to be - * split into independent span start/ends. Consider e.g. - * "**foo* bar*". Therefore we push also some empty dummy - * marks to have enough space for that. */ - off++; - while(off < tmp) { - ADD_MARK('D', off, off, 0); - off++; - } - continue; - } - - off = tmp; - continue; - } - - /* A potential code span start/end. */ - if(ch == _T('`')) { - MD_MARK opener; - MD_MARK closer; - int is_code_span; - - is_code_span = md_is_code_span(ctx, line, n_lines - line_index, off, - &opener, &closer, codespan_last_potential_closers, - &codespan_scanned_till_paragraph_end); - if(is_code_span) { - ADD_MARK(opener.ch, opener.beg, opener.end, opener.flags); - ADD_MARK(closer.ch, closer.beg, closer.end, closer.flags); - md_resolve_range(ctx, ctx->n_marks-2, ctx->n_marks-1); - off = closer.end; - - /* Advance the current line accordingly. */ - if(off > line->end) - line = md_lookup_line(off, lines, n_lines, &line_index); - continue; - } - - off = opener.end; - continue; - } - - /* A potential entity start. */ - if(ch == _T('&')) { - ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); - off++; - continue; - } - - /* A potential entity end. */ - if(ch == _T(';')) { - /* We surely cannot be entity unless the previous mark is '&'. */ - if(ctx->n_marks > 0 && ctx->marks[ctx->n_marks-1].ch == _T('&')) - ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); - - off++; - continue; - } - - /* A potential autolink or raw HTML start/end. */ - if(ch == _T('<')) { - int is_autolink; - OFF autolink_end; - int missing_mailto; - - if(!(ctx->parser.flags & MD_FLAG_NOHTMLSPANS)) { - int is_html; - OFF html_end; - - /* Given the nature of the raw HTML, we have to recognize - * it here. Doing so later in md_analyze_lt_gt() could - * open can of worms of quadratic complexity. */ - is_html = md_is_html_any(ctx, line, n_lines - line_index, off, - lines[n_lines-1].end, &html_end); - if(is_html) { - ADD_MARK(_T('<'), off, off, MD_MARK_OPENER | MD_MARK_RESOLVED); - ADD_MARK(_T('>'), html_end, html_end, MD_MARK_CLOSER | MD_MARK_RESOLVED); - ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; - ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; - off = html_end; - - /* Advance the current line accordingly. */ - if(off > line->end) - line = md_lookup_line(off, lines, n_lines, &line_index); - continue; - } - } - - is_autolink = md_is_autolink(ctx, off, lines[n_lines-1].end, - &autolink_end, &missing_mailto); - if(is_autolink) { - unsigned flags = MD_MARK_RESOLVED | MD_MARK_AUTOLINK; - if(missing_mailto) - flags |= MD_MARK_AUTOLINK_MISSING_MAILTO; - - ADD_MARK(_T('<'), off, off+1, MD_MARK_OPENER | flags); - ADD_MARK(_T('>'), autolink_end-1, autolink_end, MD_MARK_CLOSER | flags); - ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; - ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; - off = autolink_end; - continue; - } - - off++; - continue; - } - - /* A potential link or its part. */ - if(ch == _T('[') || (ch == _T('!') && off+1 < line->end && CH(off+1) == _T('['))) { - OFF tmp = (ch == _T('[') ? off+1 : off+2); - ADD_MARK(ch, off, tmp, MD_MARK_POTENTIAL_OPENER); - off = tmp; - /* Two dummies to make enough place for data we need if it is - * a link. */ - ADD_MARK('D', off, off, 0); - ADD_MARK('D', off, off, 0); - continue; - } - if(ch == _T(']')) { - ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); - off++; - continue; - } - - /* A potential permissive e-mail autolink. */ - if(ch == _T('@')) { - if(line->beg + 1 <= off && ISALNUM(off-1) && - off + 3 < line->end && ISALNUM(off+1)) - { - ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); - /* Push a dummy as a reserve for a closer. */ - ADD_MARK('D', line->beg, line->end, 0); - } - - off++; - continue; - } - - /* A potential permissive URL autolink. */ - if(ch == _T(':')) { - static struct { - const CHAR* scheme; - SZ scheme_size; - const CHAR* suffix; - SZ suffix_size; - } scheme_map[] = { - /* In the order from the most frequently used, arguably. */ - { _T("http"), 4, _T("//"), 2 }, - { _T("https"), 5, _T("//"), 2 }, - { _T("ftp"), 3, _T("//"), 2 } - }; - int scheme_index; - - for(scheme_index = 0; scheme_index < (int) SIZEOF_ARRAY(scheme_map); scheme_index++) { - const CHAR* scheme = scheme_map[scheme_index].scheme; - const SZ scheme_size = scheme_map[scheme_index].scheme_size; - const CHAR* suffix = scheme_map[scheme_index].suffix; - const SZ suffix_size = scheme_map[scheme_index].suffix_size; - - if(line->beg + scheme_size <= off && md_ascii_eq(STR(off-scheme_size), scheme, scheme_size) && - off + 1 + suffix_size < line->end && md_ascii_eq(STR(off+1), suffix, suffix_size)) - { - ADD_MARK(ch, off-scheme_size, off+1+suffix_size, MD_MARK_POTENTIAL_OPENER); - /* Push a dummy as a reserve for a closer. */ - ADD_MARK('D', line->beg, line->end, 0); - off += 1 + suffix_size; - break; - } - } - - off++; - continue; - } - - /* A potential permissive WWW autolink. */ - if(ch == _T('.')) { - if(line->beg + 3 <= off && md_ascii_eq(STR(off-3), _T("www"), 3) && - (off-3 == line->beg || ISUNICODEWHITESPACEBEFORE(off-3) || ISUNICODEPUNCTBEFORE(off-3))) - { - ADD_MARK(ch, off-3, off+1, MD_MARK_POTENTIAL_OPENER); - /* Push a dummy as a reserve for a closer. */ - ADD_MARK('D', line->beg, line->end, 0); - off++; - continue; - } - - off++; - continue; - } - - /* A potential table cell boundary or wiki link label delimiter. */ - if((table_mode || ctx->parser.flags & MD_FLAG_WIKILINKS) && ch == _T('|')) { - ADD_MARK(ch, off, off+1, 0); - off++; - continue; - } - - /* A potential strikethrough/equation start/end. */ - if(ch == _T('$') || ch == _T('~')) { - OFF tmp = off+1; - - while(tmp < line->end && CH(tmp) == ch) - tmp++; - - if(tmp - off <= 2) { - unsigned flags = MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER; - - if(off > line->beg && !ISUNICODEWHITESPACEBEFORE(off) && !ISUNICODEPUNCTBEFORE(off)) - flags &= ~MD_MARK_POTENTIAL_OPENER; - if(tmp < line->end && !ISUNICODEWHITESPACE(tmp) && !ISUNICODEPUNCT(tmp)) - flags &= ~MD_MARK_POTENTIAL_CLOSER; - if(flags != 0) - ADD_MARK(ch, off, tmp, flags); - } - - off = tmp; - continue; - } - - /* Turn non-trivial whitespace into single space. */ - if(ISWHITESPACE_(ch)) { - OFF tmp = off+1; - - while(tmp < line->end && ISWHITESPACE(tmp)) - tmp++; - - if(tmp - off > 1 || ch != _T(' ')) - ADD_MARK(ch, off, tmp, MD_MARK_RESOLVED); - - off = tmp; - continue; - } - - /* NULL character. */ - if(ch == _T('\0')) { - ADD_MARK(ch, off, off+1, MD_MARK_RESOLVED); - off++; - continue; - } - - off++; - } - } - - /* Add a dummy mark at the end of the mark vector to simplify - * process_inlines(). */ - ADD_MARK(127, ctx->size, ctx->size, MD_MARK_RESOLVED); - -abort: - return ret; -} - -static void -md_analyze_bracket(MD_CTX* ctx, int mark_index) -{ - /* We cannot really resolve links here as for that we would need - * more context. E.g. a following pair of brackets (reference link), - * or enclosing pair of brackets (if the inner is the link, the outer - * one cannot be.) - * - * Therefore we here only construct a list of '[' ']' pairs ordered by - * position of the closer. This allows us to analyze what is or is not - * link in the right order, from inside to outside in case of nested - * brackets. - * - * The resolving itself is deferred to md_resolve_links(). - */ - - MD_MARK* mark = &ctx->marks[mark_index]; - - if(mark->flags & MD_MARK_POTENTIAL_OPENER) { - if(BRACKET_OPENERS.top >= 0) - ctx->marks[BRACKET_OPENERS.top].flags |= MD_MARK_HASNESTEDBRACKETS; - - md_mark_stack_push(ctx, &BRACKET_OPENERS, mark_index); - return; - } - - if(BRACKET_OPENERS.top >= 0) { - int opener_index = md_mark_stack_pop(ctx, &BRACKET_OPENERS); - MD_MARK* opener = &ctx->marks[opener_index]; - - /* Interconnect the opener and closer. */ - opener->next = mark_index; - mark->prev = opener_index; - - /* Add the pair into a list of potential links for md_resolve_links(). - * Note we misuse opener->prev for this as opener->next points to its - * closer. */ - if(ctx->unresolved_link_tail >= 0) - ctx->marks[ctx->unresolved_link_tail].prev = opener_index; - else - ctx->unresolved_link_head = opener_index; - ctx->unresolved_link_tail = opener_index; - opener->prev = -1; - } -} - -/* Forward declaration. */ -static void md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - int mark_beg, int mark_end); - -static int -md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) -{ - int opener_index = ctx->unresolved_link_head; - OFF last_link_beg = 0; - OFF last_link_end = 0; - OFF last_img_beg = 0; - OFF last_img_end = 0; - - while(opener_index >= 0) { - MD_MARK* opener = &ctx->marks[opener_index]; - int closer_index = opener->next; - MD_MARK* closer = &ctx->marks[closer_index]; - int next_index = opener->prev; - MD_MARK* next_opener; - MD_MARK* next_closer; - MD_LINK_ATTR attr; - int is_link = FALSE; - - if(next_index >= 0) { - next_opener = &ctx->marks[next_index]; - next_closer = &ctx->marks[next_opener->next]; - } else { - next_opener = NULL; - next_closer = NULL; - } - - /* If nested ("[ [ ] ]"), we need to make sure that: - * - The outer does not end inside of (...) belonging to the inner. - * - The outer cannot be link if the inner is link (i.e. not image). - * - * (Note we here analyze from inner to outer as the marks are ordered - * by closer->beg.) - */ - if((opener->beg < last_link_beg && closer->end < last_link_end) || - (opener->beg < last_img_beg && closer->end < last_img_end) || - (opener->beg < last_link_end && opener->ch == '[')) - { - opener_index = next_index; - continue; - } - - /* Recognize and resolve wiki links. - * Wiki-links maybe '[[destination]]' or '[[destination|label]]'. - */ - if ((ctx->parser.flags & MD_FLAG_WIKILINKS) && - (opener->end - opener->beg == 1) && /* not image */ - next_opener != NULL && /* double '[' opener */ - next_opener->ch == '[' && - (next_opener->beg == opener->beg - 1) && - (next_opener->end - next_opener->beg == 1) && - next_closer != NULL && /* double ']' closer */ - next_closer->ch == ']' && - (next_closer->beg == closer->beg + 1) && - (next_closer->end - next_closer->beg == 1)) - { - MD_MARK* delim = NULL; - int delim_index; - OFF dest_beg, dest_end; - - is_link = TRUE; - - /* We don't allow destination to be longer than 100 characters. - * Lets scan to see whether there is '|'. (If not then the whole - * wiki-link has to be below the 100 characters.) */ - delim_index = opener_index + 1; - while(delim_index < closer_index) { - MD_MARK* m = &ctx->marks[delim_index]; - if(m->ch == '|') { - delim = m; - break; - } - if(m->ch != 'D') { - if(m->beg - opener->end > 100) - break; - if(m->ch != 'D' && (m->flags & MD_MARK_OPENER)) - delim_index = m->next; - } - delim_index++; - } - - dest_beg = opener->end; - dest_end = (delim != NULL) ? delim->beg : closer->beg; - if(dest_end - dest_beg == 0 || dest_end - dest_beg > 100) - is_link = FALSE; - - /* There may not be any new line in the destination. */ - if(is_link) { - OFF off; - for(off = dest_beg; off < dest_end; off++) { - if(ISNEWLINE(off)) { - is_link = FALSE; - break; - } - } - } - - if(is_link) { - if(delim != NULL) { - if(delim->end < closer->beg) { - md_rollback(ctx, opener_index, delim_index, MD_ROLLBACK_ALL); - md_rollback(ctx, delim_index, closer_index, MD_ROLLBACK_CROSSING); - delim->flags |= MD_MARK_RESOLVED; - opener->end = delim->beg; - } else { - /* The pipe is just before the closer: [[foo|]] */ - md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL); - closer->beg = delim->beg; - delim = NULL; - } - } - - opener->beg = next_opener->beg; - opener->next = closer_index; - opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; - - closer->end = next_closer->end; - closer->prev = opener_index; - closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED; - - last_link_beg = opener->beg; - last_link_end = closer->end; - - if(delim != NULL) - md_analyze_link_contents(ctx, lines, n_lines, delim_index+1, closer_index); - - opener_index = next_opener->prev; - continue; - } - } - - if(next_opener != NULL && next_opener->beg == closer->end) { - if(next_closer->beg > closer->end + 1) { - /* Might be full reference link. */ - if(!(next_opener->flags & MD_MARK_HASNESTEDBRACKETS)) - is_link = md_is_link_reference(ctx, lines, n_lines, next_opener->beg, next_closer->end, &attr); - } else { - /* Might be shortcut reference link. */ - if(!(opener->flags & MD_MARK_HASNESTEDBRACKETS)) - is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); - } - - if(is_link < 0) - return -1; - - if(is_link) { - /* Eat the 2nd "[...]". */ - closer->end = next_closer->end; - - /* Do not analyze the label as a standalone link in the next - * iteration. */ - next_index = ctx->marks[next_index].prev; - } - } else { - if(closer->end < ctx->size && CH(closer->end) == _T('(')) { - /* Might be inline link. */ - OFF inline_link_end = UINT_MAX; - - is_link = md_is_inline_link_spec(ctx, lines, n_lines, closer->end, &inline_link_end, &attr); - if(is_link < 0) - return -1; - - /* Check the closing ')' is not inside an already resolved range - * (i.e. a range with a higher priority), e.g. a code span. */ - if(is_link) { - int i = closer_index + 1; - - while(i < ctx->n_marks) { - MD_MARK* mark = &ctx->marks[i]; - - if(mark->beg >= inline_link_end) - break; - if((mark->flags & (MD_MARK_OPENER | MD_MARK_RESOLVED)) == (MD_MARK_OPENER | MD_MARK_RESOLVED)) { - if(ctx->marks[mark->next].beg >= inline_link_end) { - /* Cancel the link status. */ - if(attr.title_needs_free) - free(attr.title); - is_link = FALSE; - break; - } - - i = mark->next + 1; - } else { - i++; - } - } - } - - if(is_link) { - /* Eat the "(...)" */ - closer->end = inline_link_end; - } - } - - if(!is_link) { - /* Might be collapsed reference link. */ - if(!(opener->flags & MD_MARK_HASNESTEDBRACKETS)) - is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); - if(is_link < 0) - return -1; - } - } - - if(is_link) { - /* Resolve the brackets as a link. */ - opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; - closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED; - - /* If it is a link, we store the destination and title in the two - * dummy marks after the opener. */ - MD_ASSERT(ctx->marks[opener_index+1].ch == 'D'); - ctx->marks[opener_index+1].beg = attr.dest_beg; - ctx->marks[opener_index+1].end = attr.dest_end; - - MD_ASSERT(ctx->marks[opener_index+2].ch == 'D'); - md_mark_store_ptr(ctx, opener_index+2, attr.title); - /* The title might or might not have been allocated for us. */ - if(attr.title_needs_free) - md_mark_stack_push(ctx, &ctx->ptr_stack, opener_index+2); - ctx->marks[opener_index+2].prev = attr.title_size; - - if(opener->ch == '[') { - last_link_beg = opener->beg; - last_link_end = closer->end; - } else { - last_img_beg = opener->beg; - last_img_end = closer->end; - } - - md_analyze_link_contents(ctx, lines, n_lines, opener_index+1, closer_index); - - /* If the link text is formed by nothing but permissive autolink, - * suppress the autolink. - * See https://github.com/mity/md4c/issues/152 for more info. */ - if(ctx->parser.flags & MD_FLAG_PERMISSIVEAUTOLINKS) { - MD_MARK* first_nested; - MD_MARK* last_nested; - - first_nested = opener + 1; - while(first_nested->ch == _T('D') && first_nested < closer) - first_nested++; - - last_nested = closer - 1; - while(first_nested->ch == _T('D') && last_nested > opener) - last_nested--; - - if((first_nested->flags & MD_MARK_RESOLVED) && - first_nested->beg == opener->end && - ISANYOF_(first_nested->ch, _T("@:.")) && - first_nested->next == (last_nested - ctx->marks) && - last_nested->end == closer->beg) - { - first_nested->ch = _T('D'); - first_nested->flags &= ~MD_MARK_RESOLVED; - last_nested->ch = _T('D'); - last_nested->flags &= ~MD_MARK_RESOLVED; - } - } - } - - opener_index = next_index; - } - - return 0; -} - -/* Analyze whether the mark '&' starts a HTML entity. - * If so, update its flags as well as flags of corresponding closer ';'. */ -static void -md_analyze_entity(MD_CTX* ctx, int mark_index) -{ - MD_MARK* opener = &ctx->marks[mark_index]; - MD_MARK* closer; - OFF off; - - /* Cannot be entity if there is no closer as the next mark. - * (Any other mark between would mean strange character which cannot be - * part of the entity. - * - * So we can do all the work on '&' and do not call this later for the - * closing mark ';'. - */ - if(mark_index + 1 >= ctx->n_marks) - return; - closer = &ctx->marks[mark_index+1]; - if(closer->ch != ';') - return; - - if(md_is_entity(ctx, opener->beg, closer->end, &off)) { - MD_ASSERT(off == closer->end); - - md_resolve_range(ctx, mark_index, mark_index+1); - opener->end = closer->end; - } -} - -static void -md_analyze_table_cell_boundary(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - mark->flags |= MD_MARK_RESOLVED; - mark->next = -1; - - if(ctx->table_cell_boundaries_head < 0) - ctx->table_cell_boundaries_head = mark_index; - else - ctx->marks[ctx->table_cell_boundaries_tail].next = mark_index; - ctx->table_cell_boundaries_tail = mark_index; - ctx->n_table_cell_boundaries++; -} - -/* Split a longer mark into two. The new mark takes the given count of - * characters. May only be called if an adequate number of dummy 'D' marks - * follows. - */ -static int -md_split_emph_mark(MD_CTX* ctx, int mark_index, SZ n) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - int new_mark_index = mark_index + (mark->end - mark->beg - n); - MD_MARK* dummy = &ctx->marks[new_mark_index]; - - MD_ASSERT(mark->end - mark->beg > n); - MD_ASSERT(dummy->ch == 'D'); - - memcpy(dummy, mark, sizeof(MD_MARK)); - mark->end -= n; - dummy->beg = mark->end; - - return new_mark_index; -} - -static void -md_analyze_emph(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - /* If we can be a closer, try to resolve with the preceding opener. */ - if(mark->flags & MD_MARK_POTENTIAL_CLOSER) { - MD_MARK* opener = NULL; - int opener_index = 0; - MD_MARKSTACK* opener_stacks[6]; - int i, n_opener_stacks; - unsigned flags = mark->flags; - - n_opener_stacks = 0; - - /* Apply the rule of 3 */ - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_0 | MD_MARK_EMPH_OC); - if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_1 | MD_MARK_EMPH_OC); - if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_2 | MD_MARK_EMPH_OC); - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_0); - if(!(flags & MD_MARK_EMPH_OC) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_1); - if(!(flags & MD_MARK_EMPH_OC) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_2); - - /* Opener is the most recent mark from the allowed stacks. */ - for(i = 0; i < n_opener_stacks; i++) { - if(opener_stacks[i]->top >= 0) { - int m_index = opener_stacks[i]->top; - MD_MARK* m = &ctx->marks[m_index]; - - if(opener == NULL || m->end > opener->end) { - opener_index = m_index; - opener = m; - } - } - } - - /* Resolve, if we have found matching opener. */ - if(opener != NULL) { - SZ opener_size = opener->end - opener->beg; - SZ closer_size = mark->end - mark->beg; - MD_MARKSTACK* stack = md_opener_stack(ctx, opener_index); - - if(opener_size > closer_size) { - opener_index = md_split_emph_mark(ctx, opener_index, closer_size); - md_mark_stack_push(ctx, stack, opener_index); - } else if(opener_size < closer_size) { - md_split_emph_mark(ctx, mark_index, closer_size - opener_size); - } - - /* Above we were only peeking. */ - md_mark_stack_pop(ctx, stack); - - md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING); - md_resolve_range(ctx, opener_index, mark_index); - return; - } - } - - /* If we could not resolve as closer, we may be yet be an opener. */ - if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_stack_push(ctx, md_emph_stack(ctx, mark->ch, mark->flags), mark_index); -} - -static void -md_analyze_tilde(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - MD_MARKSTACK* stack = md_opener_stack(ctx, mark_index); - - /* We attempt to be Github Flavored Markdown compatible here. GFM accepts - * only tildes sequences of length 1 and 2, and the length of the opener - * and closer has to match. */ - - if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && stack->top >= 0) { - int opener_index = stack->top; - - md_mark_stack_pop(ctx, stack); - md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING); - md_resolve_range(ctx, opener_index, mark_index); - return; - } - - if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_stack_push(ctx, stack, mark_index); -} - -static void -md_analyze_dollar(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && DOLLAR_OPENERS.top >= 0) { - /* If the potential closer has a non-matching number of $, discard */ - MD_MARK* opener = &ctx->marks[DOLLAR_OPENERS.top]; - int opener_index = DOLLAR_OPENERS.top; - MD_MARK* closer = mark; - int closer_index = mark_index; - - if(opener->end - opener->beg == closer->end - closer->beg) { - /* We are the matching closer */ - md_mark_stack_pop(ctx, &DOLLAR_OPENERS); - md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL); - md_resolve_range(ctx, opener_index, closer_index); - - /* Discard all pending openers: Latex math span do not allow - * nesting. */ - DOLLAR_OPENERS.top = -1; - return; - } - } - - if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_stack_push(ctx, &DOLLAR_OPENERS, mark_index); -} - -static MD_MARK* -md_scan_left_for_resolved_mark(MD_CTX* ctx, MD_MARK* mark_from, OFF off, MD_MARK** p_cursor) -{ - MD_MARK* mark; - - for(mark = mark_from; mark >= ctx->marks; mark--) { - if(mark->ch == 'D' || mark->beg > off) - continue; - if(mark->beg <= off && off < mark->end && (mark->flags & MD_MARK_RESOLVED)) { - if(p_cursor != NULL) - *p_cursor = mark; - return mark; - } - if(mark->end <= off) - break; - } - - if(p_cursor != NULL) - *p_cursor = mark; - return NULL; -} - -static MD_MARK* -md_scan_right_for_resolved_mark(MD_CTX* ctx, MD_MARK* mark_from, OFF off, MD_MARK** p_cursor) -{ - MD_MARK* mark; - - for(mark = mark_from; mark < ctx->marks + ctx->n_marks; mark++) { - if(mark->ch == 'D' || mark->end <= off) - continue; - if(mark->beg <= off && off < mark->end && (mark->flags & MD_MARK_RESOLVED)) { - if(p_cursor != NULL) - *p_cursor = mark; - return mark; - } - if(mark->beg > off) - break; - } - - if(p_cursor != NULL) - *p_cursor = mark; - return NULL; -} - -static void -md_analyze_permissive_autolink(MD_CTX* ctx, int mark_index) -{ - static const struct { - const MD_CHAR start_char; - const MD_CHAR delim_char; - const MD_CHAR* allowed_nonalnum_chars; - int min_components; - const MD_CHAR optional_end_char; - } URL_MAP[] = { - { _T('\0'), _T('.'), _T(".-_"), 2, _T('\0') }, /* host, mandatory */ - { _T('/'), _T('/'), _T("/.-_"), 0, _T('/') }, /* path */ - { _T('?'), _T('&'), _T("&.-+_=()"), 1, _T('\0') }, /* query */ - { _T('#'), _T('\0'), _T(".-+_") , 1, _T('\0') } /* fragment */ - }; - - MD_MARK* opener = &ctx->marks[mark_index]; - MD_MARK* closer = &ctx->marks[mark_index + 1]; /* The dummy. */ - OFF line_beg = closer->beg; /* md_collect_mark() set this for us */ - OFF line_end = closer->end; /* ditto */ - OFF beg = opener->beg; - OFF end = opener->end; - MD_MARK* left_cursor = opener; - int left_boundary_ok = FALSE; - MD_MARK* right_cursor = opener; - int right_boundary_ok = FALSE; - unsigned i; - - MD_ASSERT(closer->ch == 'D'); - - if(opener->ch == '@') { - MD_ASSERT(CH(opener->beg) == _T('@')); - - /* Scan backwards for the user name (before '@'). */ - while(beg > line_beg) { - if(ISALNUM(beg-1)) - beg--; - else if(beg >= line_beg+2 && ISALNUM(beg-2) && - ISANYOF(beg-1, _T(".-_+")) && - md_scan_left_for_resolved_mark(ctx, left_cursor, beg-1, &left_cursor) == NULL && - ISALNUM(beg)) - beg--; - else - break; - } - if(beg == opener->beg) /* empty user name */ - return; - } - - /* Verify there's line boundary, whitespace, allowed punctuation or - * resolved emphasis mark just before the suspected autolink. */ - if(beg == line_beg || ISUNICODEWHITESPACEBEFORE(beg) || ISANYOF(beg-1, _T("({["))) { - left_boundary_ok = TRUE; - } else if(ISANYOF(beg-1, _T("*_~"))) { - MD_MARK* left_mark; - - left_mark = md_scan_left_for_resolved_mark(ctx, left_cursor, beg-1, &left_cursor); - if(left_mark != NULL && (left_mark->flags & MD_MARK_OPENER)) - left_boundary_ok = TRUE; - } - if(!left_boundary_ok) - return; - - for(i = 0; i < SIZEOF_ARRAY(URL_MAP); i++) { - int n_components = 0; - int n_open_brackets = 0; - - if(URL_MAP[i].start_char != _T('\0')) { - if(end >= line_end || CH(end) != URL_MAP[i].start_char) - continue; - if(URL_MAP[i].min_components > 0 && (end+1 >= line_end || !ISALNUM(end+1))) - continue; - end++; - } - - while(end < line_end) { - if(ISALNUM(end)) { - if(n_components == 0) - n_components++; - end++; - } else if(end < line_end && - ISANYOF(end, URL_MAP[i].allowed_nonalnum_chars) && - md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor) == NULL && - ((end > line_beg && (ISALNUM(end-1) || CH(end-1) == _T(')'))) || CH(end) == _T('(')) && - ((end+1 < line_end && (ISALNUM(end+1) || CH(end+1) == _T('('))) || CH(end) == _T(')'))) - { - if(CH(end) == URL_MAP[i].delim_char) - n_components++; - - /* brackets have to be balanced. */ - if(CH(end) == _T('(')) { - n_open_brackets++; - } else if(CH(end) == _T(')')) { - if(n_open_brackets <= 0) - break; - n_open_brackets--; - } - - end++; - } else { - break; - } - } - - if(end < line_end && URL_MAP[i].optional_end_char != _T('\0') && - CH(end) == URL_MAP[i].optional_end_char) - end++; - - if(n_components < URL_MAP[i].min_components || n_open_brackets != 0) - return; - - if(opener->ch == '@') /* E-mail autolinks wants only the host. */ - break; - } - - /* Verify there's line boundary, whitespace, allowed punctuation or - * resolved emphasis mark just after the suspected autolink. */ - if(end == line_end || ISUNICODEWHITESPACE(end) || ISANYOF(end, _T(")}].!?,;"))) { - right_boundary_ok = TRUE; - } else { - MD_MARK* right_mark; - - right_mark = md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor); - if(right_mark != NULL && (right_mark->flags & MD_MARK_CLOSER)) - right_boundary_ok = TRUE; - } - if(!right_boundary_ok) - return; - - /* Success, we are an autolink. */ - opener->beg = beg; - opener->end = beg; - closer->beg = end; - closer->end = end; - closer->ch = opener->ch; - md_resolve_range(ctx, mark_index, mark_index + 1); -} - -#define MD_ANALYZE_NOSKIP_EMPH 0x01 - -static inline void -md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - int mark_beg, int mark_end, const CHAR* mark_chars, unsigned flags) -{ - int i = mark_beg; - OFF last_end = lines[0].beg; - - MD_UNUSED(lines); - MD_UNUSED(n_lines); - - while(i < mark_end) { - MD_MARK* mark = &ctx->marks[i]; - - /* Skip resolved spans. */ - if(mark->flags & MD_MARK_RESOLVED) { - if((mark->flags & MD_MARK_OPENER) && - !((flags & MD_ANALYZE_NOSKIP_EMPH) && ISANYOF_(mark->ch, "*_~"))) - { - MD_ASSERT(i < mark->next); - i = mark->next + 1; - } else { - i++; - } - continue; - } - - /* Skip marks we do not want to deal with. */ - if(!ISANYOF_(mark->ch, mark_chars)) { - i++; - continue; - } - - /* The resolving in previous step could have expanded a mark. */ - if(mark->beg < last_end) { - i++; - continue; - } - - /* Analyze the mark. */ - switch(mark->ch) { - case '[': /* Pass through. */ - case '!': /* Pass through. */ - case ']': md_analyze_bracket(ctx, i); break; - case '&': md_analyze_entity(ctx, i); break; - case '|': md_analyze_table_cell_boundary(ctx, i); break; - case '_': /* Pass through. */ - case '*': md_analyze_emph(ctx, i); break; - case '~': md_analyze_tilde(ctx, i); break; - case '$': md_analyze_dollar(ctx, i); break; - case '.': /* Pass through. */ - case ':': /* Pass through. */ - case '@': md_analyze_permissive_autolink(ctx, i); break; - } - - if(mark->flags & MD_MARK_RESOLVED) { - if(mark->flags & MD_MARK_OPENER) - last_end = ctx->marks[mark->next].end; - else - last_end = mark->end; - } - - i++; - } -} - -/* Analyze marks (build ctx->marks). */ -static int -md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int table_mode) -{ - int ret; - - /* Reset the previously collected stack of marks. */ - ctx->n_marks = 0; - - /* Collect all marks. */ - MD_CHECK(md_collect_marks(ctx, lines, n_lines, table_mode)); - - /* (1) Links. */ - md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("[]!"), 0); - MD_CHECK(md_resolve_links(ctx, lines, n_lines)); - BRACKET_OPENERS.top = -1; - ctx->unresolved_link_head = -1; - ctx->unresolved_link_tail = -1; - - if(table_mode) { - /* (2) Analyze table cell boundaries. */ - MD_ASSERT(n_lines == 1); - ctx->n_table_cell_boundaries = 0; - md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("|"), 0); - return ret; - } - - /* (3) Emphasis and strong emphasis; permissive autolinks. */ - md_analyze_link_contents(ctx, lines, n_lines, 0, ctx->n_marks); - -abort: - return ret; -} - -static void -md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - int mark_beg, int mark_end) -{ - int i; - - md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("&"), 0); - md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("*_~$"), 0); - - if((ctx->parser.flags & MD_FLAG_PERMISSIVEAUTOLINKS) != 0) { - /* These have to be processed last, as they may be greedy and expand - * from their original mark. Also their implementation must be careful - * not to cross any (previously) resolved marks when doing so. */ - md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("@:."), MD_ANALYZE_NOSKIP_EMPH); - } - - for(i = 0; i < (int) SIZEOF_ARRAY(ctx->opener_stacks); i++) - ctx->opener_stacks[i].top = -1; -} - -static int -md_enter_leave_span_a(MD_CTX* ctx, int enter, MD_SPANTYPE type, - const CHAR* dest, SZ dest_size, int is_autolink, - const CHAR* title, SZ title_size) -{ - MD_ATTRIBUTE_BUILD href_build = { 0 }; - MD_ATTRIBUTE_BUILD title_build = { 0 }; - MD_SPAN_A_DETAIL det; - int ret = 0; - - /* Note we here rely on fact that MD_SPAN_A_DETAIL and - * MD_SPAN_IMG_DETAIL are binary-compatible. */ - memset(&det, 0, sizeof(MD_SPAN_A_DETAIL)); - MD_CHECK(md_build_attribute(ctx, dest, dest_size, - (is_autolink ? MD_BUILD_ATTR_NO_ESCAPES : 0), - &det.href, &href_build)); - MD_CHECK(md_build_attribute(ctx, title, title_size, 0, &det.title, &title_build)); - det.is_autolink = is_autolink; - if(enter) - MD_ENTER_SPAN(type, &det); - else - MD_LEAVE_SPAN(type, &det); - -abort: - md_free_attribute(ctx, &href_build); - md_free_attribute(ctx, &title_build); - return ret; -} - -static int -md_enter_leave_span_wikilink(MD_CTX* ctx, int enter, const CHAR* target, SZ target_size) -{ - MD_ATTRIBUTE_BUILD target_build = { 0 }; - MD_SPAN_WIKILINK_DETAIL det; - int ret = 0; - - memset(&det, 0, sizeof(MD_SPAN_WIKILINK_DETAIL)); - MD_CHECK(md_build_attribute(ctx, target, target_size, 0, &det.target, &target_build)); - - if (enter) - MD_ENTER_SPAN(MD_SPAN_WIKILINK, &det); - else - MD_LEAVE_SPAN(MD_SPAN_WIKILINK, &det); - -abort: - md_free_attribute(ctx, &target_build); - return ret; -} - - -/* Render the output, accordingly to the analyzed ctx->marks. */ -static int -md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) -{ - MD_TEXTTYPE text_type; - const MD_LINE* line = lines; - MD_MARK* prev_mark = NULL; - MD_MARK* mark; - OFF off = lines[0].beg; - OFF end = lines[n_lines-1].end; - OFF tmp; - int enforce_hardbreak = 0; - int ret = 0; - - /* Find first resolved mark. Note there is always at least one resolved - * mark, the dummy last one after the end of the latest line we actually - * never really reach. This saves us of a lot of special checks and cases - * in this function. */ - mark = ctx->marks; - while(!(mark->flags & MD_MARK_RESOLVED)) - mark++; - - text_type = MD_TEXT_NORMAL; - - while(1) { - /* Process the text up to the next mark or end-of-line. */ - tmp = (line->end < mark->beg ? line->end : mark->beg); - if(tmp > off) { - MD_TEXT(text_type, STR(off), tmp - off); - off = tmp; - } - - /* If reached the mark, process it and move to next one. */ - if(off >= mark->beg) { - switch(mark->ch) { - case '\\': /* Backslash escape. */ - if(ISNEWLINE(mark->beg+1)) - enforce_hardbreak = 1; - else - MD_TEXT(text_type, STR(mark->beg+1), 1); - break; - - case ' ': /* Non-trivial space. */ - MD_TEXT(text_type, _T(" "), 1); - break; - - case '`': /* Code span. */ - if(mark->flags & MD_MARK_OPENER) { - MD_ENTER_SPAN(MD_SPAN_CODE, NULL); - text_type = MD_TEXT_CODE; - } else { - MD_LEAVE_SPAN(MD_SPAN_CODE, NULL); - text_type = MD_TEXT_NORMAL; - } - break; - - case '_': /* Underline (or emphasis if we fall through). */ - if(ctx->parser.flags & MD_FLAG_UNDERLINE) { - if(mark->flags & MD_MARK_OPENER) { - while(off < mark->end) { - MD_ENTER_SPAN(MD_SPAN_U, NULL); - off++; - } - } else { - while(off < mark->end) { - MD_LEAVE_SPAN(MD_SPAN_U, NULL); - off++; - } - } - break; - } - MD_FALLTHROUGH(); - - case '*': /* Emphasis, strong emphasis. */ - if(mark->flags & MD_MARK_OPENER) { - if((mark->end - off) % 2) { - MD_ENTER_SPAN(MD_SPAN_EM, NULL); - off++; - } - while(off + 1 < mark->end) { - MD_ENTER_SPAN(MD_SPAN_STRONG, NULL); - off += 2; - } - } else { - while(off + 1 < mark->end) { - MD_LEAVE_SPAN(MD_SPAN_STRONG, NULL); - off += 2; - } - if((mark->end - off) % 2) { - MD_LEAVE_SPAN(MD_SPAN_EM, NULL); - off++; - } - } - break; - - case '~': - if(mark->flags & MD_MARK_OPENER) - MD_ENTER_SPAN(MD_SPAN_DEL, NULL); - else - MD_LEAVE_SPAN(MD_SPAN_DEL, NULL); - break; - - case '$': - if(mark->flags & MD_MARK_OPENER) { - MD_ENTER_SPAN((mark->end - off) % 2 ? MD_SPAN_LATEXMATH : MD_SPAN_LATEXMATH_DISPLAY, NULL); - text_type = MD_TEXT_LATEXMATH; - } else { - MD_LEAVE_SPAN((mark->end - off) % 2 ? MD_SPAN_LATEXMATH : MD_SPAN_LATEXMATH_DISPLAY, NULL); - text_type = MD_TEXT_NORMAL; - } - break; - - case '[': /* Link, wiki link, image. */ - case '!': - case ']': - { - const MD_MARK* opener = (mark->ch != ']' ? mark : &ctx->marks[mark->prev]); - const MD_MARK* closer = &ctx->marks[opener->next]; - const MD_MARK* dest_mark; - const MD_MARK* title_mark; - - if ((opener->ch == '[' && closer->ch == ']') && - opener->end - opener->beg >= 2 && - closer->end - closer->beg >= 2) - { - int has_label = (opener->end - opener->beg > 2); - SZ target_sz; - - if(has_label) - target_sz = opener->end - (opener->beg+2); - else - target_sz = closer->beg - opener->end; - - MD_CHECK(md_enter_leave_span_wikilink(ctx, (mark->ch != ']'), - has_label ? STR(opener->beg+2) : STR(opener->end), - target_sz)); - - break; - } - - dest_mark = opener+1; - MD_ASSERT(dest_mark->ch == 'D'); - title_mark = opener+2; - MD_ASSERT(title_mark->ch == 'D'); - - MD_CHECK(md_enter_leave_span_a(ctx, (mark->ch != ']'), - (opener->ch == '!' ? MD_SPAN_IMG : MD_SPAN_A), - STR(dest_mark->beg), dest_mark->end - dest_mark->beg, FALSE, - md_mark_get_ptr(ctx, (int)(title_mark - ctx->marks)), - title_mark->prev)); - - /* link/image closer may span multiple lines. */ - if(mark->ch == ']') { - while(mark->end > line->end) - line++; - } - - break; - } - - case '<': - case '>': /* Autolink or raw HTML. */ - if(!(mark->flags & MD_MARK_AUTOLINK)) { - /* Raw HTML. */ - if(mark->flags & MD_MARK_OPENER) - text_type = MD_TEXT_HTML; - else - text_type = MD_TEXT_NORMAL; - break; - } - /* Pass through, if auto-link. */ - MD_FALLTHROUGH(); - - case '@': /* Permissive e-mail autolink. */ - case ':': /* Permissive URL autolink. */ - case '.': /* Permissive WWW autolink. */ - { - MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]); - MD_MARK* closer = &ctx->marks[opener->next]; - const CHAR* dest = STR(opener->end); - SZ dest_size = closer->beg - opener->end; - - /* For permissive auto-links we do not know closer mark - * position at the time of md_collect_marks(), therefore - * it can be out-of-order in ctx->marks[]. - * - * With this flag, we make sure that we output the closer - * only if we processed the opener. */ - if(mark->flags & MD_MARK_OPENER) - closer->flags |= MD_MARK_VALIDPERMISSIVEAUTOLINK; - - if(opener->ch == '@' || opener->ch == '.' || - (opener->ch == '<' && (opener->flags & MD_MARK_AUTOLINK_MISSING_MAILTO))) - { - dest_size += 7; - MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); - memcpy(ctx->buffer, - (opener->ch == '.' ? _T("http://") : _T("mailto:")), - 7 * sizeof(CHAR)); - memcpy(ctx->buffer + 7, dest, (dest_size-7) * sizeof(CHAR)); - dest = ctx->buffer; - } - - if(closer->flags & MD_MARK_VALIDPERMISSIVEAUTOLINK) - MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER), - MD_SPAN_A, dest, dest_size, TRUE, NULL, 0)); - break; - } - - case '&': /* Entity. */ - MD_TEXT(MD_TEXT_ENTITY, STR(mark->beg), mark->end - mark->beg); - break; - - case '\0': - MD_TEXT(MD_TEXT_NULLCHAR, _T(""), 1); - break; - - case 127: - goto abort; - } - - off = mark->end; - - /* Move to next resolved mark. */ - prev_mark = mark; - mark++; - while(!(mark->flags & MD_MARK_RESOLVED) || mark->beg < off) - mark++; - } - - /* If reached end of line, move to next one. */ - if(off >= line->end) { - /* If it is the last line, we are done. */ - if(off >= end) - break; - - if(text_type == MD_TEXT_CODE || text_type == MD_TEXT_LATEXMATH) { - MD_ASSERT(prev_mark != NULL); - MD_ASSERT(ISANYOF2_(prev_mark->ch, '`', '$') && (prev_mark->flags & MD_MARK_OPENER)); - MD_ASSERT(ISANYOF2_(mark->ch, '`', '$') && (mark->flags & MD_MARK_CLOSER)); - - /* Inside a code span, trailing line whitespace has to be - * outputted. */ - tmp = off; - while(off < ctx->size && ISBLANK(off)) - off++; - if(off > tmp) - MD_TEXT(text_type, STR(tmp), off-tmp); - - /* and new lines are transformed into single spaces. */ - if(off == line->end) - MD_TEXT(text_type, _T(" "), 1); - } else if(text_type == MD_TEXT_HTML) { - /* Inside raw HTML, we output the new line verbatim, including - * any trailing spaces. */ - tmp = off; - while(tmp < end && ISBLANK(tmp)) - tmp++; - if(tmp > off) - MD_TEXT(MD_TEXT_HTML, STR(off), tmp - off); - MD_TEXT(MD_TEXT_HTML, _T("\n"), 1); - } else { - /* Output soft or hard line break. */ - MD_TEXTTYPE break_type = MD_TEXT_SOFTBR; - - if(text_type == MD_TEXT_NORMAL) { - if(enforce_hardbreak || (ctx->parser.flags & MD_FLAG_HARD_SOFT_BREAKS)) { - break_type = MD_TEXT_BR; - } else { - while(off < ctx->size && ISBLANK(off)) - off++; - if(off >= line->end + 2 && CH(off-2) == _T(' ') && CH(off-1) == _T(' ') && ISNEWLINE(off)) - break_type = MD_TEXT_BR; - } - } - - MD_TEXT(break_type, _T("\n"), 1); - } - - /* Move to the next line. */ - line++; - off = line->beg; - - enforce_hardbreak = 0; - } - } - -abort: - return ret; -} - - -/*************************** - *** Processing Tables *** - ***************************/ - -static void -md_analyze_table_alignment(MD_CTX* ctx, OFF beg, OFF end, MD_ALIGN* align, int n_align) -{ - static const MD_ALIGN align_map[] = { MD_ALIGN_DEFAULT, MD_ALIGN_LEFT, MD_ALIGN_RIGHT, MD_ALIGN_CENTER }; - OFF off = beg; - - while(n_align > 0) { - int index = 0; /* index into align_map[] */ - - while(CH(off) != _T('-')) - off++; - if(off > beg && CH(off-1) == _T(':')) - index |= 1; - while(off < end && CH(off) == _T('-')) - off++; - if(off < end && CH(off) == _T(':')) - index |= 2; - - *align = align_map[index]; - align++; - n_align--; - } - -} - -/* Forward declaration. */ -static int md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines); - -static int -md_process_table_cell(MD_CTX* ctx, MD_BLOCKTYPE cell_type, MD_ALIGN align, OFF beg, OFF end) -{ - MD_LINE line; - MD_BLOCK_TD_DETAIL det; - int ret = 0; - - while(beg < end && ISWHITESPACE(beg)) - beg++; - while(end > beg && ISWHITESPACE(end-1)) - end--; - - det.align = align; - line.beg = beg; - line.end = end; - - MD_ENTER_BLOCK(cell_type, &det); - MD_CHECK(md_process_normal_block_contents(ctx, &line, 1)); - MD_LEAVE_BLOCK(cell_type, &det); - -abort: - return ret; -} - -static int -md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end, - const MD_ALIGN* align, int col_count) -{ - MD_LINE line; - OFF* pipe_offs = NULL; - int i, j, k, n; - int ret = 0; - - line.beg = beg; - line.end = end; - - /* Break the line into table cells by identifying pipe characters who - * form the cell boundary. */ - MD_CHECK(md_analyze_inlines(ctx, &line, 1, TRUE)); - - /* We have to remember the cell boundaries in local buffer because - * ctx->marks[] shall be reused during cell contents processing. */ - n = ctx->n_table_cell_boundaries + 2; - pipe_offs = (OFF*) malloc(n * sizeof(OFF)); - if(pipe_offs == NULL) { - MD_LOG("malloc() failed."); - ret = -1; - goto abort; - } - j = 0; - pipe_offs[j++] = beg; - for(i = ctx->table_cell_boundaries_head; i >= 0; i = ctx->marks[i].next) { - MD_MARK* mark = &ctx->marks[i]; - pipe_offs[j++] = mark->end; - } - pipe_offs[j++] = end+1; - - /* Process cells. */ - MD_ENTER_BLOCK(MD_BLOCK_TR, NULL); - k = 0; - for(i = 0; i < j-1 && k < col_count; i++) { - if(pipe_offs[i] < pipe_offs[i+1]-1) - MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], pipe_offs[i], pipe_offs[i+1]-1)); - } - /* Make sure we call enough table cells even if the current table contains - * too few of them. */ - while(k < col_count) - MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], 0, 0)); - MD_LEAVE_BLOCK(MD_BLOCK_TR, NULL); - -abort: - free(pipe_offs); - - ctx->table_cell_boundaries_head = -1; - ctx->table_cell_boundaries_tail = -1; - - return ret; -} - -static int -md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines, MD_SIZE n_lines) -{ - MD_ALIGN* align; - MD_SIZE line_index; - int ret = 0; - - /* At least two lines have to be present: The column headers and the line - * with the underlines. */ - MD_ASSERT(n_lines >= 2); - - align = malloc(col_count * sizeof(MD_ALIGN)); - if(align == NULL) { - MD_LOG("malloc() failed."); - ret = -1; - goto abort; - } - - md_analyze_table_alignment(ctx, lines[1].beg, lines[1].end, align, col_count); - - MD_ENTER_BLOCK(MD_BLOCK_THEAD, NULL); - MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TH, - lines[0].beg, lines[0].end, align, col_count)); - MD_LEAVE_BLOCK(MD_BLOCK_THEAD, NULL); - - if(n_lines > 2) { - MD_ENTER_BLOCK(MD_BLOCK_TBODY, NULL); - for(line_index = 2; line_index < n_lines; line_index++) { - MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TD, - lines[line_index].beg, lines[line_index].end, align, col_count)); - } - MD_LEAVE_BLOCK(MD_BLOCK_TBODY, NULL); - } - -abort: - free(align); - return ret; -} - - -/************************** - *** Processing Block *** - **************************/ - -#define MD_BLOCK_CONTAINER_OPENER 0x01 -#define MD_BLOCK_CONTAINER_CLOSER 0x02 -#define MD_BLOCK_CONTAINER (MD_BLOCK_CONTAINER_OPENER | MD_BLOCK_CONTAINER_CLOSER) -#define MD_BLOCK_LOOSE_LIST 0x04 -#define MD_BLOCK_SETEXT_HEADER 0x08 - -struct MD_BLOCK_tag { - MD_BLOCKTYPE type : 8; - unsigned flags : 8; - - /* MD_BLOCK_H: Header level (1 - 6) - * MD_BLOCK_CODE: Non-zero if fenced, zero if indented. - * MD_BLOCK_LI: Task mark character (0 if not task list item, 'x', 'X' or ' '). - * MD_BLOCK_TABLE: Column count (as determined by the table underline). - */ - unsigned data : 16; - - /* Leaf blocks: Count of lines (MD_LINE or MD_VERBATIMLINE) on the block. - * MD_BLOCK_LI: Task mark offset in the input doc. - * MD_BLOCK_OL: Start item number. - */ - MD_SIZE n_lines; -}; - -struct MD_CONTAINER_tag { - CHAR ch; - unsigned is_loose : 8; - unsigned is_task : 8; - unsigned start; - unsigned mark_indent; - unsigned contents_indent; - OFF block_byte_off; - OFF task_mark_off; -}; - - -static int -md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) -{ - int i; - int ret; - - MD_CHECK(md_analyze_inlines(ctx, lines, n_lines, FALSE)); - MD_CHECK(md_process_inlines(ctx, lines, n_lines)); - -abort: - /* Free any temporary memory blocks stored within some dummy marks. */ - for(i = ctx->ptr_stack.top; i >= 0; i = ctx->marks[i].next) - free(md_mark_get_ptr(ctx, i)); - ctx->ptr_stack.top = -1; - - return ret; -} - -static int -md_process_verbatim_block_contents(MD_CTX* ctx, MD_TEXTTYPE text_type, const MD_VERBATIMLINE* lines, MD_SIZE n_lines) -{ - static const CHAR indent_chunk_str[] = _T(" "); - static const SZ indent_chunk_size = SIZEOF_ARRAY(indent_chunk_str) - 1; - - MD_SIZE line_index; - int ret = 0; - - for(line_index = 0; line_index < n_lines; line_index++) { - const MD_VERBATIMLINE* line = &lines[line_index]; - int indent = line->indent; - - MD_ASSERT(indent >= 0); - - /* Output code indentation. */ - while(indent > (int) indent_chunk_size) { - MD_TEXT(text_type, indent_chunk_str, indent_chunk_size); - indent -= indent_chunk_size; - } - if(indent > 0) - MD_TEXT(text_type, indent_chunk_str, indent); - - /* Output the code line itself. */ - MD_TEXT_INSECURE(text_type, STR(line->beg), line->end - line->beg); - - /* Enforce end-of-line. */ - MD_TEXT(text_type, _T("\n"), 1); - } - -abort: - return ret; -} - -static int -md_process_code_block_contents(MD_CTX* ctx, int is_fenced, const MD_VERBATIMLINE* lines, MD_SIZE n_lines) -{ - if(is_fenced) { - /* Skip the first line in case of fenced code: It is the fence. - * (Only the starting fence is present due to logic in md_analyze_line().) */ - lines++; - n_lines--; - } else { - /* Ignore blank lines at start/end of indented code block. */ - while(n_lines > 0 && lines[0].beg == lines[0].end) { - lines++; - n_lines--; - } - while(n_lines > 0 && lines[n_lines-1].beg == lines[n_lines-1].end) { - n_lines--; - } - } - - if(n_lines == 0) - return 0; - - return md_process_verbatim_block_contents(ctx, MD_TEXT_CODE, lines, n_lines); -} - -static int -md_setup_fenced_code_detail(MD_CTX* ctx, const MD_BLOCK* block, MD_BLOCK_CODE_DETAIL* det, - MD_ATTRIBUTE_BUILD* info_build, MD_ATTRIBUTE_BUILD* lang_build) -{ - const MD_VERBATIMLINE* fence_line = (const MD_VERBATIMLINE*)(block + 1); - OFF beg = fence_line->beg; - OFF end = fence_line->end; - OFF lang_end; - CHAR fence_ch = CH(fence_line->beg); - int ret = 0; - - /* Skip the fence itself. */ - while(beg < ctx->size && CH(beg) == fence_ch) - beg++; - /* Trim initial spaces. */ - while(beg < ctx->size && CH(beg) == _T(' ')) - beg++; - - /* Trim trailing spaces. */ - while(end > beg && CH(end-1) == _T(' ')) - end--; - - /* Build info string attribute. */ - MD_CHECK(md_build_attribute(ctx, STR(beg), end - beg, 0, &det->info, info_build)); - - /* Build info string attribute. */ - lang_end = beg; - while(lang_end < end && !ISWHITESPACE(lang_end)) - lang_end++; - MD_CHECK(md_build_attribute(ctx, STR(beg), lang_end - beg, 0, &det->lang, lang_build)); - - det->fence_char = fence_ch; - -abort: - return ret; -} - -static int -md_process_leaf_block(MD_CTX* ctx, const MD_BLOCK* block) -{ - union { - MD_BLOCK_H_DETAIL header; - MD_BLOCK_CODE_DETAIL code; - MD_BLOCK_TABLE_DETAIL table; - } det; - MD_ATTRIBUTE_BUILD info_build; - MD_ATTRIBUTE_BUILD lang_build; - int is_in_tight_list; - int clean_fence_code_detail = FALSE; - int ret = 0; - - memset(&det, 0, sizeof(det)); - - if(ctx->n_containers == 0) - is_in_tight_list = FALSE; - else - is_in_tight_list = !ctx->containers[ctx->n_containers-1].is_loose; - - switch(block->type) { - case MD_BLOCK_H: - det.header.level = block->data; - break; - - case MD_BLOCK_CODE: - /* For fenced code block, we may need to set the info string. */ - if(block->data != 0) { - memset(&det.code, 0, sizeof(MD_BLOCK_CODE_DETAIL)); - clean_fence_code_detail = TRUE; - MD_CHECK(md_setup_fenced_code_detail(ctx, block, &det.code, &info_build, &lang_build)); - } - break; - - case MD_BLOCK_TABLE: - det.table.col_count = block->data; - det.table.head_row_count = 1; - det.table.body_row_count = block->n_lines - 2; - break; - - default: - /* Noop. */ - break; - } - - if(!is_in_tight_list || block->type != MD_BLOCK_P) - MD_ENTER_BLOCK(block->type, (void*) &det); - - /* Process the block contents accordingly to is type. */ - switch(block->type) { - case MD_BLOCK_HR: - /* noop */ - break; - - case MD_BLOCK_CODE: - MD_CHECK(md_process_code_block_contents(ctx, (block->data != 0), - (const MD_VERBATIMLINE*)(block + 1), block->n_lines)); - break; - - case MD_BLOCK_HTML: - MD_CHECK(md_process_verbatim_block_contents(ctx, MD_TEXT_HTML, - (const MD_VERBATIMLINE*)(block + 1), block->n_lines)); - break; - - case MD_BLOCK_TABLE: - MD_CHECK(md_process_table_block_contents(ctx, block->data, - (const MD_LINE*)(block + 1), block->n_lines)); - break; - - default: - MD_CHECK(md_process_normal_block_contents(ctx, - (const MD_LINE*)(block + 1), block->n_lines)); - break; - } - - if(!is_in_tight_list || block->type != MD_BLOCK_P) - MD_LEAVE_BLOCK(block->type, (void*) &det); - -abort: - if(clean_fence_code_detail) { - md_free_attribute(ctx, &info_build); - md_free_attribute(ctx, &lang_build); - } - return ret; -} - -static int -md_process_all_blocks(MD_CTX* ctx) -{ - int byte_off = 0; - int ret = 0; - - /* ctx->containers now is not needed for detection of lists and list items - * so we reuse it for tracking what lists are loose or tight. We rely - * on the fact the vector is large enough to hold the deepest nesting - * level of lists. */ - ctx->n_containers = 0; - - while(byte_off < ctx->n_block_bytes) { - MD_BLOCK* block = (MD_BLOCK*)((char*)ctx->block_bytes + byte_off); - union { - MD_BLOCK_UL_DETAIL ul; - MD_BLOCK_OL_DETAIL ol; - MD_BLOCK_LI_DETAIL li; - } det; - - switch(block->type) { - case MD_BLOCK_UL: - det.ul.is_tight = (block->flags & MD_BLOCK_LOOSE_LIST) ? FALSE : TRUE; - det.ul.mark = (CHAR) block->data; - break; - - case MD_BLOCK_OL: - det.ol.start = block->n_lines; - det.ol.is_tight = (block->flags & MD_BLOCK_LOOSE_LIST) ? FALSE : TRUE; - det.ol.mark_delimiter = (CHAR) block->data; - break; - - case MD_BLOCK_LI: - det.li.is_task = (block->data != 0); - det.li.task_mark = (CHAR) block->data; - det.li.task_mark_offset = (OFF) block->n_lines; - break; - - default: - /* noop */ - break; - } - - if(block->flags & MD_BLOCK_CONTAINER) { - if(block->flags & MD_BLOCK_CONTAINER_CLOSER) { - MD_LEAVE_BLOCK(block->type, &det); - - if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL || block->type == MD_BLOCK_QUOTE) - ctx->n_containers--; - } - - if(block->flags & MD_BLOCK_CONTAINER_OPENER) { - MD_ENTER_BLOCK(block->type, &det); - - if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL) { - ctx->containers[ctx->n_containers].is_loose = (block->flags & MD_BLOCK_LOOSE_LIST); - ctx->n_containers++; - } else if(block->type == MD_BLOCK_QUOTE) { - /* This causes that any text in a block quote, even if - * nested inside a tight list item, is wrapped with - *

    ...

    . */ - ctx->containers[ctx->n_containers].is_loose = TRUE; - ctx->n_containers++; - } - } - } else { - MD_CHECK(md_process_leaf_block(ctx, block)); - - if(block->type == MD_BLOCK_CODE || block->type == MD_BLOCK_HTML) - byte_off += block->n_lines * sizeof(MD_VERBATIMLINE); - else - byte_off += block->n_lines * sizeof(MD_LINE); - } - - byte_off += sizeof(MD_BLOCK); - } - - ctx->n_block_bytes = 0; - -abort: - return ret; -} - - -/************************************ - *** Grouping Lines into Blocks *** - ************************************/ - -static void* -md_push_block_bytes(MD_CTX* ctx, int n_bytes) -{ - void* ptr; - - if(ctx->n_block_bytes + n_bytes > ctx->alloc_block_bytes) { - void* new_block_bytes; - - ctx->alloc_block_bytes = (ctx->alloc_block_bytes > 0 - ? ctx->alloc_block_bytes + ctx->alloc_block_bytes / 2 - : 512); - new_block_bytes = realloc(ctx->block_bytes, ctx->alloc_block_bytes); - if(new_block_bytes == NULL) { - MD_LOG("realloc() failed."); - return NULL; - } - - /* Fix the ->current_block after the reallocation. */ - if(ctx->current_block != NULL) { - OFF off_current_block = (OFF) ((char*) ctx->current_block - (char*) ctx->block_bytes); - ctx->current_block = (MD_BLOCK*) ((char*) new_block_bytes + off_current_block); - } - - ctx->block_bytes = new_block_bytes; - } - - ptr = (char*)ctx->block_bytes + ctx->n_block_bytes; - ctx->n_block_bytes += n_bytes; - return ptr; -} - -static int -md_start_new_block(MD_CTX* ctx, const MD_LINE_ANALYSIS* line) -{ - MD_BLOCK* block; - - MD_ASSERT(ctx->current_block == NULL); - - block = (MD_BLOCK*) md_push_block_bytes(ctx, sizeof(MD_BLOCK)); - if(block == NULL) - return -1; - - switch(line->type) { - case MD_LINE_HR: - block->type = MD_BLOCK_HR; - break; - - case MD_LINE_ATXHEADER: - case MD_LINE_SETEXTHEADER: - block->type = MD_BLOCK_H; - break; - - case MD_LINE_FENCEDCODE: - case MD_LINE_INDENTEDCODE: - block->type = MD_BLOCK_CODE; - break; - - case MD_LINE_TEXT: - block->type = MD_BLOCK_P; - break; - - case MD_LINE_HTML: - block->type = MD_BLOCK_HTML; - break; - - case MD_LINE_BLANK: - case MD_LINE_SETEXTUNDERLINE: - case MD_LINE_TABLEUNDERLINE: - default: - MD_UNREACHABLE(); - break; - } - - block->flags = 0; - block->data = line->data; - block->n_lines = 0; - - ctx->current_block = block; - return 0; -} - -/* Eat from start of current (textual) block any reference definitions and - * remember them so we can resolve any links referring to them. - * - * (Reference definitions can only be at start of it as they cannot break - * a paragraph.) - */ -static int -md_consume_link_reference_definitions(MD_CTX* ctx) -{ - MD_LINE* lines = (MD_LINE*) (ctx->current_block + 1); - MD_SIZE n_lines = ctx->current_block->n_lines; - MD_SIZE n = 0; - - /* Compute how many lines at the start of the block form one or more - * reference definitions. */ - while(n < n_lines) { - int n_link_ref_lines; - - n_link_ref_lines = md_is_link_reference_definition(ctx, - lines + n, n_lines - n); - /* Not a reference definition? */ - if(n_link_ref_lines == 0) - break; - - /* We fail if it is the ref. def. but it could not be stored due - * a memory allocation error. */ - if(n_link_ref_lines < 0) - return -1; - - n += n_link_ref_lines; - } - - /* If there was at least one reference definition, we need to remove - * its lines from the block, or perhaps even the whole block. */ - if(n > 0) { - if(n == n_lines) { - /* Remove complete block. */ - ctx->n_block_bytes -= n * sizeof(MD_LINE); - ctx->n_block_bytes -= sizeof(MD_BLOCK); - ctx->current_block = NULL; - } else { - /* Remove just some initial lines from the block. */ - memmove(lines, lines + n, (n_lines - n) * sizeof(MD_LINE)); - ctx->current_block->n_lines -= n; - ctx->n_block_bytes -= n * sizeof(MD_LINE); - } - } - - return 0; -} - -static int -md_end_current_block(MD_CTX* ctx) -{ - int ret = 0; - - if(ctx->current_block == NULL) - return ret; - - /* Check whether there is a reference definition. (We do this here instead - * of in md_analyze_line() because reference definition can take multiple - * lines.) */ - if(ctx->current_block->type == MD_BLOCK_P || - (ctx->current_block->type == MD_BLOCK_H && (ctx->current_block->flags & MD_BLOCK_SETEXT_HEADER))) - { - MD_LINE* lines = (MD_LINE*) (ctx->current_block + 1); - if(lines[0].beg < ctx->size && CH(lines[0].beg) == _T('[')) { - MD_CHECK(md_consume_link_reference_definitions(ctx)); - if(ctx->current_block == NULL) - return ret; - } - } - - if(ctx->current_block->type == MD_BLOCK_H && (ctx->current_block->flags & MD_BLOCK_SETEXT_HEADER)) { - MD_SIZE n_lines = ctx->current_block->n_lines; - - if(n_lines > 1) { - /* Get rid of the underline. */ - ctx->current_block->n_lines--; - ctx->n_block_bytes -= sizeof(MD_LINE); - } else { - /* Only the underline has left after eating the ref. defs. - * Keep the line as beginning of a new ordinary paragraph. */ - ctx->current_block->type = MD_BLOCK_P; - return 0; - } - } - - /* Mark we are not building any block anymore. */ - ctx->current_block = NULL; - -abort: - return ret; -} - -static int -md_add_line_into_current_block(MD_CTX* ctx, const MD_LINE_ANALYSIS* analysis) -{ - MD_ASSERT(ctx->current_block != NULL); - - if(ctx->current_block->type == MD_BLOCK_CODE || ctx->current_block->type == MD_BLOCK_HTML) { - MD_VERBATIMLINE* line; - - line = (MD_VERBATIMLINE*) md_push_block_bytes(ctx, sizeof(MD_VERBATIMLINE)); - if(line == NULL) - return -1; - - line->indent = analysis->indent; - line->beg = analysis->beg; - line->end = analysis->end; - } else { - MD_LINE* line; - - line = (MD_LINE*) md_push_block_bytes(ctx, sizeof(MD_LINE)); - if(line == NULL) - return -1; - - line->beg = analysis->beg; - line->end = analysis->end; - } - ctx->current_block->n_lines++; - - return 0; -} - -static int -md_push_container_bytes(MD_CTX* ctx, MD_BLOCKTYPE type, unsigned start, - unsigned data, unsigned flags) -{ - MD_BLOCK* block; - int ret = 0; - - MD_CHECK(md_end_current_block(ctx)); - - block = (MD_BLOCK*) md_push_block_bytes(ctx, sizeof(MD_BLOCK)); - if(block == NULL) - return -1; - - block->type = type; - block->flags = flags; - block->data = data; - block->n_lines = start; - -abort: - return ret; -} - - - -/*********************** - *** Line Analysis *** - ***********************/ - -static int -md_is_hr_line(MD_CTX* ctx, OFF beg, OFF* p_end, OFF* p_killer) -{ - OFF off = beg + 1; - int n = 1; - - while(off < ctx->size && (CH(off) == CH(beg) || CH(off) == _T(' ') || CH(off) == _T('\t'))) { - if(CH(off) == CH(beg)) - n++; - off++; - } - - if(n < 3) { - *p_killer = off; - return FALSE; - } - - /* Nothing else can be present on the line. */ - if(off < ctx->size && !ISNEWLINE(off)) { - *p_killer = off; - return FALSE; - } - - *p_end = off; - return TRUE; -} - -static int -md_is_atxheader_line(MD_CTX* ctx, OFF beg, OFF* p_beg, OFF* p_end, unsigned* p_level) -{ - int n; - OFF off = beg + 1; - - while(off < ctx->size && CH(off) == _T('#') && off - beg < 7) - off++; - n = off - beg; - - if(n > 6) - return FALSE; - *p_level = n; - - if(!(ctx->parser.flags & MD_FLAG_PERMISSIVEATXHEADERS) && off < ctx->size && - !ISBLANK(off) && !ISNEWLINE(off)) - return FALSE; - - while(off < ctx->size && ISBLANK(off)) - off++; - *p_beg = off; - *p_end = off; - return TRUE; -} - -static int -md_is_setext_underline(MD_CTX* ctx, OFF beg, OFF* p_end, unsigned* p_level) -{ - OFF off = beg + 1; - - while(off < ctx->size && CH(off) == CH(beg)) - off++; - - /* Optionally, space(s) or tabs can follow. */ - while(off < ctx->size && ISBLANK(off)) - off++; - - /* But nothing more is allowed on the line. */ - if(off < ctx->size && !ISNEWLINE(off)) - return FALSE; - - *p_level = (CH(beg) == _T('=') ? 1 : 2); - *p_end = off; - return TRUE; -} - -static int -md_is_table_underline(MD_CTX* ctx, OFF beg, OFF* p_end, unsigned* p_col_count) -{ - OFF off = beg; - int found_pipe = FALSE; - unsigned col_count = 0; - - if(off < ctx->size && CH(off) == _T('|')) { - found_pipe = TRUE; - off++; - while(off < ctx->size && ISWHITESPACE(off)) - off++; - } - - while(1) { - int delimited = FALSE; - - /* Cell underline ("-----", ":----", "----:" or ":----:") */ - if(off < ctx->size && CH(off) == _T(':')) - off++; - if(off >= ctx->size || CH(off) != _T('-')) - return FALSE; - while(off < ctx->size && CH(off) == _T('-')) - off++; - if(off < ctx->size && CH(off) == _T(':')) - off++; - - col_count++; - if(col_count > TABLE_MAXCOLCOUNT) { - MD_LOG("Suppressing table (column_count >" STRINGIZE(TABLE_MAXCOLCOUNT) ")"); - return FALSE; - } - - /* Pipe delimiter (optional at the end of line). */ - while(off < ctx->size && ISWHITESPACE(off)) - off++; - if(off < ctx->size && CH(off) == _T('|')) { - delimited = TRUE; - found_pipe = TRUE; - off++; - while(off < ctx->size && ISWHITESPACE(off)) - off++; - } - - /* Success, if we reach end of line. */ - if(off >= ctx->size || ISNEWLINE(off)) - break; - - if(!delimited) - return FALSE; - } - - if(!found_pipe) - return FALSE; - - *p_end = off; - *p_col_count = col_count; - return TRUE; -} - -static int -md_is_opening_code_fence(MD_CTX* ctx, OFF beg, OFF* p_end) -{ - OFF off = beg; - - while(off < ctx->size && CH(off) == CH(beg)) - off++; - - /* Fence must have at least three characters. */ - if(off - beg < 3) - return FALSE; - - ctx->code_fence_length = off - beg; - - /* Optionally, space(s) can follow. */ - while(off < ctx->size && CH(off) == _T(' ')) - off++; - - /* Optionally, an info string can follow. */ - while(off < ctx->size && !ISNEWLINE(off)) { - /* Backtick-based fence must not contain '`' in the info string. */ - if(CH(beg) == _T('`') && CH(off) == _T('`')) - return FALSE; - off++; - } - - *p_end = off; - return TRUE; -} - -static int -md_is_closing_code_fence(MD_CTX* ctx, CHAR ch, OFF beg, OFF* p_end) -{ - OFF off = beg; - int ret = FALSE; - - /* Closing fence must have at least the same length and use same char as - * opening one. */ - while(off < ctx->size && CH(off) == ch) - off++; - if(off - beg < ctx->code_fence_length) - goto out; - - /* Optionally, space(s) can follow */ - while(off < ctx->size && CH(off) == _T(' ')) - off++; - - /* But nothing more is allowed on the line. */ - if(off < ctx->size && !ISNEWLINE(off)) - goto out; - - ret = TRUE; - -out: - /* Note we set *p_end even on failure: If we are not closing fence, caller - * would eat the line anyway without any parsing. */ - *p_end = off; - return ret; -} - - -/* Helper data for md_is_html_block_start_condition() and - * md_is_html_block_end_condition() */ -typedef struct TAG_tag TAG; -struct TAG_tag { - const CHAR* name; - unsigned len : 8; -}; - -#ifdef X - #undef X -#endif -#define X(name) { _T(name), (sizeof(name)-1) / sizeof(CHAR) } -#define Xend { NULL, 0 } - -static const TAG t1[] = { X("pre"), X("script"), X("style"), X("textarea"), Xend }; - -static const TAG a6[] = { X("address"), X("article"), X("aside"), Xend }; -static const TAG b6[] = { X("base"), X("basefont"), X("blockquote"), X("body"), Xend }; -static const TAG c6[] = { X("caption"), X("center"), X("col"), X("colgroup"), Xend }; -static const TAG d6[] = { X("dd"), X("details"), X("dialog"), X("dir"), - X("div"), X("dl"), X("dt"), Xend }; -static const TAG f6[] = { X("fieldset"), X("figcaption"), X("figure"), X("footer"), - X("form"), X("frame"), X("frameset"), Xend }; -static const TAG h6[] = { X("h1"), X("h2"), X("h3"), X("h4"), X("h5"), X("h6"), - X("head"), X("header"), X("hr"), X("html"), Xend }; -static const TAG i6[] = { X("iframe"), Xend }; -static const TAG l6[] = { X("legend"), X("li"), X("link"), Xend }; -static const TAG m6[] = { X("main"), X("menu"), X("menuitem"), Xend }; -static const TAG n6[] = { X("nav"), X("noframes"), Xend }; -static const TAG o6[] = { X("ol"), X("optgroup"), X("option"), Xend }; -static const TAG p6[] = { X("p"), X("param"), Xend }; -static const TAG s6[] = { X("search"), X("section"), X("summary"), Xend }; -static const TAG t6[] = { X("table"), X("tbody"), X("td"), X("tfoot"), X("th"), - X("thead"), X("title"), X("tr"), X("track"), Xend }; -static const TAG u6[] = { X("ul"), Xend }; -static const TAG xx[] = { Xend }; - -#undef X -#undef Xend - -/* Returns type of the raw HTML block, or FALSE if it is not HTML block. - * (Refer to CommonMark specification for details about the types.) - */ -static int -md_is_html_block_start_condition(MD_CTX* ctx, OFF beg) -{ - /* Type 6 is started by a long list of allowed tags. We use two-level - * tree to speed-up the search. */ - static const TAG* map6[26] = { - a6, b6, c6, d6, xx, f6, xx, h6, i6, xx, xx, l6, m6, - n6, o6, p6, xx, xx, s6, t6, u6, xx, xx, xx, xx, xx - }; - OFF off = beg + 1; - int i; - - /* Check for type 1: size) { - if(md_ascii_case_eq(STR(off), t1[i].name, t1[i].len)) - return 1; - } - } - - /* Check for type 2: "), 3, p_end) ? 2 : FALSE); - - case 3: - return (md_line_contains(ctx, beg, _T("?>"), 2, p_end) ? 3 : FALSE); - - case 4: - return (md_line_contains(ctx, beg, _T(">"), 1, p_end) ? 4 : FALSE); - - case 5: - return (md_line_contains(ctx, beg, _T("]]>"), 3, p_end) ? 5 : FALSE); - - case 6: /* Pass through */ - case 7: - if(beg >= ctx->size || ISNEWLINE(beg)) { - /* Blank line ends types 6 and 7. */ - *p_end = beg; - return ctx->html_block_type; - } - return FALSE; - - default: - MD_UNREACHABLE(); - } - return FALSE; -} - - -static int -md_is_container_compatible(const MD_CONTAINER* pivot, const MD_CONTAINER* container) -{ - /* Block quote has no "items" like lists. */ - if(container->ch == _T('>')) - return FALSE; - - if(container->ch != pivot->ch) - return FALSE; - if(container->mark_indent > pivot->contents_indent) - return FALSE; - - return TRUE; -} - -static int -md_push_container(MD_CTX* ctx, const MD_CONTAINER* container) -{ - if(ctx->n_containers >= ctx->alloc_containers) { - MD_CONTAINER* new_containers; - - ctx->alloc_containers = (ctx->alloc_containers > 0 - ? ctx->alloc_containers + ctx->alloc_containers / 2 - : 16); - new_containers = realloc(ctx->containers, ctx->alloc_containers * sizeof(MD_CONTAINER)); - if(new_containers == NULL) { - MD_LOG("realloc() failed."); - return -1; - } - - ctx->containers = new_containers; - } - - memcpy(&ctx->containers[ctx->n_containers++], container, sizeof(MD_CONTAINER)); - return 0; -} - -static int -md_enter_child_containers(MD_CTX* ctx, int n_children) -{ - int i; - int ret = 0; - - for(i = ctx->n_containers - n_children; i < ctx->n_containers; i++) { - MD_CONTAINER* c = &ctx->containers[i]; - int is_ordered_list = FALSE; - - switch(c->ch) { - case _T(')'): - case _T('.'): - is_ordered_list = TRUE; - MD_FALLTHROUGH(); - - case _T('-'): - case _T('+'): - case _T('*'): - /* Remember offset in ctx->block_bytes so we can revisit the - * block if we detect it is a loose list. */ - md_end_current_block(ctx); - c->block_byte_off = ctx->n_block_bytes; - - MD_CHECK(md_push_container_bytes(ctx, - (is_ordered_list ? MD_BLOCK_OL : MD_BLOCK_UL), - c->start, c->ch, MD_BLOCK_CONTAINER_OPENER)); - MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, - c->task_mark_off, - (c->is_task ? CH(c->task_mark_off) : 0), - MD_BLOCK_CONTAINER_OPENER)); - break; - - case _T('>'): - MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_QUOTE, 0, 0, MD_BLOCK_CONTAINER_OPENER)); - break; - - default: - MD_UNREACHABLE(); - break; - } - } - -abort: - return ret; -} - -static int -md_leave_child_containers(MD_CTX* ctx, int n_keep) -{ - int ret = 0; - - while(ctx->n_containers > n_keep) { - MD_CONTAINER* c = &ctx->containers[ctx->n_containers-1]; - int is_ordered_list = FALSE; - - switch(c->ch) { - case _T(')'): - case _T('.'): - is_ordered_list = TRUE; - MD_FALLTHROUGH(); - - case _T('-'): - case _T('+'): - case _T('*'): - MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, - c->task_mark_off, (c->is_task ? CH(c->task_mark_off) : 0), - MD_BLOCK_CONTAINER_CLOSER)); - MD_CHECK(md_push_container_bytes(ctx, - (is_ordered_list ? MD_BLOCK_OL : MD_BLOCK_UL), 0, - c->ch, MD_BLOCK_CONTAINER_CLOSER)); - break; - - case _T('>'): - MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_QUOTE, 0, - 0, MD_BLOCK_CONTAINER_CLOSER)); - break; - - default: - MD_UNREACHABLE(); - break; - } - - ctx->n_containers--; - } - -abort: - return ret; -} - -static int -md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTAINER* p_container) -{ - OFF off = beg; - OFF max_end; - - if(off >= ctx->size || indent >= ctx->code_indent_offset) - return FALSE; - - /* Check for block quote mark. */ - if(CH(off) == _T('>')) { - off++; - p_container->ch = _T('>'); - p_container->is_loose = FALSE; - p_container->is_task = FALSE; - p_container->mark_indent = indent; - p_container->contents_indent = indent + 1; - *p_end = off; - return TRUE; - } - - /* Check for list item bullet mark. */ - if(ISANYOF(off, _T("-+*")) && (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) { - p_container->ch = CH(off); - p_container->is_loose = FALSE; - p_container->is_task = FALSE; - p_container->mark_indent = indent; - p_container->contents_indent = indent + 1; - *p_end = off+1; - return TRUE; - } - - /* Check for ordered list item marks. */ - max_end = off + 9; - if(max_end > ctx->size) - max_end = ctx->size; - p_container->start = 0; - while(off < max_end && ISDIGIT(off)) { - p_container->start = p_container->start * 10 + CH(off) - _T('0'); - off++; - } - if(off > beg && - off < ctx->size && - (CH(off) == _T('.') || CH(off) == _T(')')) && - (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) - { - p_container->ch = CH(off); - p_container->is_loose = FALSE; - p_container->is_task = FALSE; - p_container->mark_indent = indent; - p_container->contents_indent = indent + off - beg + 1; - *p_end = off+1; - return TRUE; - } - - return FALSE; -} - -static unsigned -md_line_indentation(MD_CTX* ctx, unsigned total_indent, OFF beg, OFF* p_end) -{ - OFF off = beg; - unsigned indent = total_indent; - - while(off < ctx->size && ISBLANK(off)) { - if(CH(off) == _T('\t')) - indent = (indent + 4) & ~3; - else - indent++; - off++; - } - - *p_end = off; - return indent - total_indent; -} - -static const MD_LINE_ANALYSIS md_dummy_blank_line = { MD_LINE_BLANK, 0, 0, 0, 0, 0 }; - -/* Analyze type of the line and find some its properties. This serves as a - * main input for determining type and boundaries of a block. */ -static int -md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, - const MD_LINE_ANALYSIS* pivot_line, MD_LINE_ANALYSIS* line) -{ - unsigned total_indent = 0; - int n_parents = 0; - int n_brothers = 0; - int n_children = 0; - MD_CONTAINER container = { 0 }; - int prev_line_has_list_loosening_effect = ctx->last_line_has_list_loosening_effect; - OFF off = beg; - OFF hr_killer = 0; - int ret = 0; - - line->indent = md_line_indentation(ctx, total_indent, off, &off); - total_indent += line->indent; - line->beg = off; - line->enforce_new_block = FALSE; - - /* Given the indentation and block quote marks '>', determine how many of - * the current containers are our parents. */ - while(n_parents < ctx->n_containers) { - MD_CONTAINER* c = &ctx->containers[n_parents]; - - if(c->ch == _T('>') && line->indent < ctx->code_indent_offset && - off < ctx->size && CH(off) == _T('>')) - { - /* Block quote mark. */ - off++; - total_indent++; - line->indent = md_line_indentation(ctx, total_indent, off, &off); - total_indent += line->indent; - - /* The optional 1st space after '>' is part of the block quote mark. */ - if(line->indent > 0) - line->indent--; - - line->beg = off; - - } else if(c->ch != _T('>') && line->indent >= c->contents_indent) { - /* List. */ - line->indent -= c->contents_indent; - } else { - break; - } - - n_parents++; - } - - if(off >= ctx->size || ISNEWLINE(off)) { - /* Blank line does not need any real indentation to be nested inside - * a list. */ - if(n_brothers + n_children == 0) { - while(n_parents < ctx->n_containers && ctx->containers[n_parents].ch != _T('>')) - n_parents++; - } - } - - while(TRUE) { - /* Check whether we are fenced code continuation. */ - if(pivot_line->type == MD_LINE_FENCEDCODE) { - line->beg = off; - - /* We are another MD_LINE_FENCEDCODE unless we are closing fence - * which we transform into MD_LINE_BLANK. */ - if(line->indent < ctx->code_indent_offset) { - if(md_is_closing_code_fence(ctx, CH(pivot_line->beg), off, &off)) { - line->type = MD_LINE_BLANK; - ctx->last_line_has_list_loosening_effect = FALSE; - break; - } - } - - /* Change indentation accordingly to the initial code fence. */ - if(n_parents == ctx->n_containers) { - if(line->indent > pivot_line->indent) - line->indent -= pivot_line->indent; - else - line->indent = 0; - - line->type = MD_LINE_FENCEDCODE; - break; - } - } - - /* Check whether we are HTML block continuation. */ - if(pivot_line->type == MD_LINE_HTML && ctx->html_block_type > 0) { - if(n_parents < ctx->n_containers) { - /* HTML block is implicitly ended if the enclosing container - * block ends. */ - ctx->html_block_type = 0; - } else { - int html_block_type; - - html_block_type = md_is_html_block_end_condition(ctx, off, &off); - if(html_block_type > 0) { - MD_ASSERT(html_block_type == ctx->html_block_type); - - /* Make sure this is the last line of the block. */ - ctx->html_block_type = 0; - - /* Some end conditions serve as blank lines at the same time. */ - if(html_block_type == 6 || html_block_type == 7) { - line->type = MD_LINE_BLANK; - line->indent = 0; - break; - } - } - - line->type = MD_LINE_HTML; - n_parents = ctx->n_containers; - break; - } - } - - /* Check for blank line. */ - if(off >= ctx->size || ISNEWLINE(off)) { - if(pivot_line->type == MD_LINE_INDENTEDCODE && n_parents == ctx->n_containers) { - line->type = MD_LINE_INDENTEDCODE; - if(line->indent > ctx->code_indent_offset) - line->indent -= ctx->code_indent_offset; - else - line->indent = 0; - ctx->last_line_has_list_loosening_effect = FALSE; - } else { - line->type = MD_LINE_BLANK; - ctx->last_line_has_list_loosening_effect = (n_parents > 0 && - n_brothers + n_children == 0 && - ctx->containers[n_parents-1].ch != _T('>')); - - #if 1 - /* See https://github.com/mity/md4c/issues/6 - * - * This ugly checking tests we are in (yet empty) list item but - * not its very first line (i.e. not the line with the list - * item mark). - * - * If we are such a blank line, then any following non-blank - * line which would be part of the list item actually has to - * end the list because according to the specification, "a list - * item can begin with at most one blank line." - */ - if(n_parents > 0 && ctx->containers[n_parents-1].ch != _T('>') && - n_brothers + n_children == 0 && ctx->current_block == NULL && - ctx->n_block_bytes > (int) sizeof(MD_BLOCK)) - { - MD_BLOCK* top_block = (MD_BLOCK*) ((char*)ctx->block_bytes + ctx->n_block_bytes - sizeof(MD_BLOCK)); - if(top_block->type == MD_BLOCK_LI) - ctx->last_list_item_starts_with_two_blank_lines = TRUE; - } - #endif - } - break; - } else { - #if 1 - /* This is the 2nd half of the hack. If the flag is set (i.e. there - * was a 2nd blank line at the beginning of the list item) and if - * we would otherwise still belong to the list item, we enforce - * the end of the list. */ - if(ctx->last_list_item_starts_with_two_blank_lines) { - if(n_parents > 0 && n_parents == ctx->n_containers && - ctx->containers[n_parents-1].ch != _T('>') && - n_brothers + n_children == 0 && ctx->current_block == NULL && - ctx->n_block_bytes > (int) sizeof(MD_BLOCK)) - { - MD_BLOCK* top_block = (MD_BLOCK*) ((char*)ctx->block_bytes + ctx->n_block_bytes - sizeof(MD_BLOCK)); - if(top_block->type == MD_BLOCK_LI) { - n_parents--; - - line->indent = total_indent; - if(n_parents > 0) - line->indent -= MIN(line->indent, ctx->containers[n_parents-1].contents_indent); - } - } - - ctx->last_list_item_starts_with_two_blank_lines = FALSE; - } - #endif - ctx->last_line_has_list_loosening_effect = FALSE; - } - - /* Check whether we are Setext underline. */ - if(line->indent < ctx->code_indent_offset && pivot_line->type == MD_LINE_TEXT - && off < ctx->size && ISANYOF2(off, _T('='), _T('-')) - && (n_parents == ctx->n_containers)) - { - unsigned level; - - if(md_is_setext_underline(ctx, off, &off, &level)) { - line->type = MD_LINE_SETEXTUNDERLINE; - line->data = level; - break; - } - } - - /* Check for thematic break line. */ - if(line->indent < ctx->code_indent_offset - && off < ctx->size && off >= hr_killer - && ISANYOF(off, _T("-_*"))) - { - if(md_is_hr_line(ctx, off, &off, &hr_killer)) { - line->type = MD_LINE_HR; - break; - } - } - - /* Check for "brother" container. I.e. whether we are another list item - * in already started list. */ - if(n_parents < ctx->n_containers && n_brothers + n_children == 0) { - OFF tmp; - - if(md_is_container_mark(ctx, line->indent, off, &tmp, &container) && - md_is_container_compatible(&ctx->containers[n_parents], &container)) - { - pivot_line = &md_dummy_blank_line; - - off = tmp; - - total_indent += container.contents_indent - container.mark_indent; - line->indent = md_line_indentation(ctx, total_indent, off, &off); - total_indent += line->indent; - line->beg = off; - - /* Some of the following whitespace actually still belongs to the mark. */ - if(off >= ctx->size || ISNEWLINE(off)) { - container.contents_indent++; - } else if(line->indent <= ctx->code_indent_offset) { - container.contents_indent += line->indent; - line->indent = 0; - } else { - container.contents_indent += 1; - line->indent--; - } - - ctx->containers[n_parents].mark_indent = container.mark_indent; - ctx->containers[n_parents].contents_indent = container.contents_indent; - - n_brothers++; - continue; - } - } - - /* Check for indented code. - * Note indented code block cannot interrupt a paragraph. */ - if(line->indent >= ctx->code_indent_offset && (pivot_line->type != MD_LINE_TEXT)) { - line->type = MD_LINE_INDENTEDCODE; - line->indent -= ctx->code_indent_offset; - line->data = 0; - break; - } - - /* Check for start of a new container block. */ - if(line->indent < ctx->code_indent_offset && - md_is_container_mark(ctx, line->indent, off, &off, &container)) - { - if(pivot_line->type == MD_LINE_TEXT && n_parents == ctx->n_containers && - (off >= ctx->size || ISNEWLINE(off)) && container.ch != _T('>')) - { - /* Noop. List mark followed by a blank line cannot interrupt a paragraph. */ - } else if(pivot_line->type == MD_LINE_TEXT && n_parents == ctx->n_containers && - ISANYOF2_(container.ch, _T('.'), _T(')')) && container.start != 1) - { - /* Noop. Ordered list cannot interrupt a paragraph unless the start index is 1. */ - } else { - total_indent += container.contents_indent - container.mark_indent; - line->indent = md_line_indentation(ctx, total_indent, off, &off); - total_indent += line->indent; - - line->beg = off; - line->data = container.ch; - - /* Some of the following whitespace actually still belongs to the mark. */ - if(off >= ctx->size || ISNEWLINE(off)) { - container.contents_indent++; - } else if(line->indent <= ctx->code_indent_offset) { - container.contents_indent += line->indent; - line->indent = 0; - } else { - container.contents_indent += 1; - line->indent--; - } - - if(n_brothers + n_children == 0) - pivot_line = &md_dummy_blank_line; - - if(n_children == 0) - MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers)); - - n_children++; - MD_CHECK(md_push_container(ctx, &container)); - continue; - } - } - - /* Check whether we are table continuation. */ - if(pivot_line->type == MD_LINE_TABLE && n_parents == ctx->n_containers) { - line->type = MD_LINE_TABLE; - break; - } - - /* Check for ATX header. */ - if(line->indent < ctx->code_indent_offset && - off < ctx->size && CH(off) == _T('#')) - { - unsigned level; - - if(md_is_atxheader_line(ctx, off, &line->beg, &off, &level)) { - line->type = MD_LINE_ATXHEADER; - line->data = level; - break; - } - } - - /* Check whether we are starting code fence. */ - if(line->indent < ctx->code_indent_offset && - off < ctx->size && ISANYOF2(off, _T('`'), _T('~'))) - { - if(md_is_opening_code_fence(ctx, off, &off)) { - line->type = MD_LINE_FENCEDCODE; - line->data = 1; - line->enforce_new_block = TRUE; - break; - } - } - - /* Check for start of raw HTML block. */ - if(off < ctx->size && CH(off) == _T('<') - && !(ctx->parser.flags & MD_FLAG_NOHTMLBLOCKS)) - { - ctx->html_block_type = md_is_html_block_start_condition(ctx, off); - - /* HTML block type 7 cannot interrupt paragraph. */ - if(ctx->html_block_type == 7 && pivot_line->type == MD_LINE_TEXT) - ctx->html_block_type = 0; - - if(ctx->html_block_type > 0) { - /* The line itself also may immediately close the block. */ - if(md_is_html_block_end_condition(ctx, off, &off) == ctx->html_block_type) { - /* Make sure this is the last line of the block. */ - ctx->html_block_type = 0; - } - - line->enforce_new_block = TRUE; - line->type = MD_LINE_HTML; - break; - } - } - - /* Check for table underline. */ - if((ctx->parser.flags & MD_FLAG_TABLES) && pivot_line->type == MD_LINE_TEXT - && off < ctx->size && ISANYOF3(off, _T('|'), _T('-'), _T(':')) - && n_parents == ctx->n_containers) - { - unsigned col_count; - - if(ctx->current_block != NULL && ctx->current_block->n_lines == 1 && - md_is_table_underline(ctx, off, &off, &col_count)) - { - line->data = col_count; - line->type = MD_LINE_TABLEUNDERLINE; - break; - } - } - - /* By default, we are normal text line. */ - line->type = MD_LINE_TEXT; - if(pivot_line->type == MD_LINE_TEXT && n_brothers + n_children == 0) { - /* Lazy continuation. */ - n_parents = ctx->n_containers; - } - - /* Check for task mark. */ - if((ctx->parser.flags & MD_FLAG_TASKLISTS) && n_brothers + n_children > 0 && - ISANYOF_(ctx->containers[ctx->n_containers-1].ch, _T("-+*.)"))) - { - OFF tmp = off; - - while(tmp < ctx->size && tmp < off + 3 && ISBLANK(tmp)) - tmp++; - if(tmp + 2 < ctx->size && CH(tmp) == _T('[') && - ISANYOF(tmp+1, _T("xX ")) && CH(tmp+2) == _T(']') && - (tmp + 3 == ctx->size || ISBLANK(tmp+3) || ISNEWLINE(tmp+3))) - { - MD_CONTAINER* task_container = (n_children > 0 ? &ctx->containers[ctx->n_containers-1] : &container); - task_container->is_task = TRUE; - task_container->task_mark_off = tmp + 1; - off = tmp + 3; - while(off < ctx->size && ISWHITESPACE(off)) - off++; - line->beg = off; - } - } - - break; - } - - /* Scan for end of the line. - * - * Note this is quite a bottleneck of the parsing as we here iterate almost - * over compete document. - */ -#if defined __linux__ && !defined MD4C_USE_UTF16 - /* Recent glibc versions have superbly optimized strcspn(), even using - * vectorization if available. */ - if(ctx->doc_ends_with_newline && off < ctx->size) { - while(TRUE) { - off += (OFF) strcspn(STR(off), "\r\n"); - - /* strcspn() can stop on zero terminator; but that can appear - * anywhere in the Markfown input... */ - if(CH(off) == _T('\0')) - off++; - else - break; - } - } else -#endif - { - /* Optimization: Use some loop unrolling. */ - while(off + 3 < ctx->size && !ISNEWLINE(off+0) && !ISNEWLINE(off+1) - && !ISNEWLINE(off+2) && !ISNEWLINE(off+3)) - off += 4; - while(off < ctx->size && !ISNEWLINE(off)) - off++; - } - - /* Set end of the line. */ - line->end = off; - - /* But for ATX header, we should exclude the optional trailing mark. */ - if(line->type == MD_LINE_ATXHEADER) { - OFF tmp = line->end; - while(tmp > line->beg && ISBLANK(tmp-1)) - tmp--; - while(tmp > line->beg && CH(tmp-1) == _T('#')) - tmp--; - if(tmp == line->beg || ISBLANK(tmp-1) || (ctx->parser.flags & MD_FLAG_PERMISSIVEATXHEADERS)) - line->end = tmp; - } - - /* Trim trailing spaces. */ - if(line->type != MD_LINE_INDENTEDCODE && line->type != MD_LINE_FENCEDCODE && line->type != MD_LINE_HTML) { - while(line->end > line->beg && ISBLANK(line->end-1)) - line->end--; - } - - /* Eat also the new line. */ - if(off < ctx->size && CH(off) == _T('\r')) - off++; - if(off < ctx->size && CH(off) == _T('\n')) - off++; - - *p_end = off; - - /* If we belong to a list after seeing a blank line, the list is loose. */ - if(prev_line_has_list_loosening_effect && line->type != MD_LINE_BLANK && n_parents + n_brothers > 0) { - MD_CONTAINER* c = &ctx->containers[n_parents + n_brothers - 1]; - if(c->ch != _T('>')) { - MD_BLOCK* block = (MD_BLOCK*) (((char*)ctx->block_bytes) + c->block_byte_off); - block->flags |= MD_BLOCK_LOOSE_LIST; - } - } - - /* Leave any containers we are not part of anymore. */ - if(n_children == 0 && n_parents + n_brothers < ctx->n_containers) - MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers)); - - /* Enter any container we found a mark for. */ - if(n_brothers > 0) { - MD_ASSERT(n_brothers == 1); - MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, - ctx->containers[n_parents].task_mark_off, - (ctx->containers[n_parents].is_task ? CH(ctx->containers[n_parents].task_mark_off) : 0), - MD_BLOCK_CONTAINER_CLOSER)); - MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, - container.task_mark_off, - (container.is_task ? CH(container.task_mark_off) : 0), - MD_BLOCK_CONTAINER_OPENER)); - ctx->containers[n_parents].is_task = container.is_task; - ctx->containers[n_parents].task_mark_off = container.task_mark_off; - } - - if(n_children > 0) - MD_CHECK(md_enter_child_containers(ctx, n_children)); - -abort: - return ret; -} - -static int -md_process_line(MD_CTX* ctx, const MD_LINE_ANALYSIS** p_pivot_line, MD_LINE_ANALYSIS* line) -{ - const MD_LINE_ANALYSIS* pivot_line = *p_pivot_line; - int ret = 0; - - /* Blank line ends current leaf block. */ - if(line->type == MD_LINE_BLANK) { - MD_CHECK(md_end_current_block(ctx)); - *p_pivot_line = &md_dummy_blank_line; - return 0; - } - - if(line->enforce_new_block) - MD_CHECK(md_end_current_block(ctx)); - - /* Some line types form block on their own. */ - if(line->type == MD_LINE_HR || line->type == MD_LINE_ATXHEADER) { - MD_CHECK(md_end_current_block(ctx)); - - /* Add our single-line block. */ - MD_CHECK(md_start_new_block(ctx, line)); - MD_CHECK(md_add_line_into_current_block(ctx, line)); - MD_CHECK(md_end_current_block(ctx)); - *p_pivot_line = &md_dummy_blank_line; - return 0; - } - - /* MD_LINE_SETEXTUNDERLINE changes meaning of the current block and ends it. */ - if(line->type == MD_LINE_SETEXTUNDERLINE) { - MD_ASSERT(ctx->current_block != NULL); - ctx->current_block->type = MD_BLOCK_H; - ctx->current_block->data = line->data; - ctx->current_block->flags |= MD_BLOCK_SETEXT_HEADER; - MD_CHECK(md_add_line_into_current_block(ctx, line)); - MD_CHECK(md_end_current_block(ctx)); - if(ctx->current_block == NULL) { - *p_pivot_line = &md_dummy_blank_line; - } else { - /* This happens if we have consumed all the body as link ref. defs. - * and downgraded the underline into start of a new paragraph block. */ - line->type = MD_LINE_TEXT; - *p_pivot_line = line; - } - return 0; - } - - /* MD_LINE_TABLEUNDERLINE changes meaning of the current block. */ - if(line->type == MD_LINE_TABLEUNDERLINE) { - MD_ASSERT(ctx->current_block != NULL); - MD_ASSERT(ctx->current_block->n_lines == 1); - ctx->current_block->type = MD_BLOCK_TABLE; - ctx->current_block->data = line->data; - MD_ASSERT(pivot_line != &md_dummy_blank_line); - ((MD_LINE_ANALYSIS*)pivot_line)->type = MD_LINE_TABLE; - MD_CHECK(md_add_line_into_current_block(ctx, line)); - return 0; - } - - /* The current block also ends if the line has different type. */ - if(line->type != pivot_line->type) - MD_CHECK(md_end_current_block(ctx)); - - /* The current line may start a new block. */ - if(ctx->current_block == NULL) { - MD_CHECK(md_start_new_block(ctx, line)); - *p_pivot_line = line; - } - - /* In all other cases the line is just a continuation of the current block. */ - MD_CHECK(md_add_line_into_current_block(ctx, line)); - -abort: - return ret; -} - -static int -md_process_doc(MD_CTX *ctx) -{ - const MD_LINE_ANALYSIS* pivot_line = &md_dummy_blank_line; - MD_LINE_ANALYSIS line_buf[2]; - MD_LINE_ANALYSIS* line = &line_buf[0]; - OFF off = 0; - int ret = 0; - - MD_ENTER_BLOCK(MD_BLOCK_DOC, NULL); - - while(off < ctx->size) { - if(line == pivot_line) - line = (line == &line_buf[0] ? &line_buf[1] : &line_buf[0]); - - MD_CHECK(md_analyze_line(ctx, off, &off, pivot_line, line)); - MD_CHECK(md_process_line(ctx, &pivot_line, line)); - } - - md_end_current_block(ctx); - - MD_CHECK(md_build_ref_def_hashtable(ctx)); - - /* Process all blocks. */ - MD_CHECK(md_leave_child_containers(ctx, 0)); - MD_CHECK(md_process_all_blocks(ctx)); - - MD_LEAVE_BLOCK(MD_BLOCK_DOC, NULL); - -abort: - -#if 0 - /* Output some memory consumption statistics. */ - { - char buffer[256]; - sprintf(buffer, "Alloced %u bytes for block buffer.", - (unsigned)(ctx->alloc_block_bytes)); - MD_LOG(buffer); - - sprintf(buffer, "Alloced %u bytes for containers buffer.", - (unsigned)(ctx->alloc_containers * sizeof(MD_CONTAINER))); - MD_LOG(buffer); - - sprintf(buffer, "Alloced %u bytes for marks buffer.", - (unsigned)(ctx->alloc_marks * sizeof(MD_MARK))); - MD_LOG(buffer); - - sprintf(buffer, "Alloced %u bytes for aux. buffer.", - (unsigned)(ctx->alloc_buffer * sizeof(MD_CHAR))); - MD_LOG(buffer); - } -#endif - - return ret; -} - - -/******************** - *** Public API *** - ********************/ - -int -md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userdata) -{ - MD_CTX ctx; - int i; - int ret; - - if(parser->abi_version != 0) { - if(parser->debug_log != NULL) - parser->debug_log("Unsupported abi_version.", userdata); - return -1; - } - - /* Setup context structure. */ - memset(&ctx, 0, sizeof(MD_CTX)); - ctx.text = text; - ctx.size = size; - memcpy(&ctx.parser, parser, sizeof(MD_PARSER)); - ctx.userdata = userdata; - ctx.code_indent_offset = (ctx.parser.flags & MD_FLAG_NOINDENTEDCODEBLOCKS) ? (OFF)(-1) : 4; - md_build_mark_char_map(&ctx); - ctx.doc_ends_with_newline = (size > 0 && ISNEWLINE_(text[size-1])); - ctx.max_ref_def_output = MIN(MIN(16 * (uint64_t)size, (uint64_t)(1024 * 1024)), (uint64_t)SZ_MAX); - - /* Reset all mark stacks and lists. */ - for(i = 0; i < (int) SIZEOF_ARRAY(ctx.opener_stacks); i++) - ctx.opener_stacks[i].top = -1; - ctx.ptr_stack.top = -1; - ctx.unresolved_link_head = -1; - ctx.unresolved_link_tail = -1; - ctx.table_cell_boundaries_head = -1; - ctx.table_cell_boundaries_tail = -1; - - /* All the work. */ - ret = md_process_doc(&ctx); - - /* Clean-up. */ - md_free_ref_defs(&ctx); - md_free_ref_def_hashtable(&ctx); - free(ctx.buffer); - free(ctx.marks); - free(ctx.block_bytes); - free(ctx.containers); - - return ret; -} diff --git a/Src/Orbiter/md4c.h b/Src/Orbiter/md4c.h deleted file mode 100644 index e4a34746b..000000000 --- a/Src/Orbiter/md4c.h +++ /dev/null @@ -1,407 +0,0 @@ -/* - * MD4C: Markdown parser for C - * (http://github.com/mity/md4c) - * - * Copyright (c) 2016-2024 Martin Mitáš - * - * 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 MD4C_H -#define MD4C_H - -#ifdef __cplusplus - extern "C" { -#endif - -#if defined MD4C_USE_UTF16 - /* Magic to support UTF-16. Note that in order to use it, you have to define - * the macro MD4C_USE_UTF16 both when building MD4C as well as when - * including this header in your code. */ - #ifdef _WIN32 - #include - typedef WCHAR MD_CHAR; - #else - #error MD4C_USE_UTF16 is only supported on Windows. - #endif -#else - typedef char MD_CHAR; -#endif - -typedef unsigned MD_SIZE; -typedef unsigned MD_OFFSET; - - -/* Block represents a part of document hierarchy structure like a paragraph - * or list item. - */ -typedef enum MD_BLOCKTYPE { - /* ... */ - MD_BLOCK_DOC = 0, - - /*
    ...
    */ - MD_BLOCK_QUOTE, - - /*
      ...
    - * Detail: Structure MD_BLOCK_UL_DETAIL. */ - MD_BLOCK_UL, - - /*
      ...
    - * Detail: Structure MD_BLOCK_OL_DETAIL. */ - MD_BLOCK_OL, - - /*
  • ...
  • - * Detail: Structure MD_BLOCK_LI_DETAIL. */ - MD_BLOCK_LI, - - /*
    */ - MD_BLOCK_HR, - - /*

    ...

    (for levels up to 6) - * Detail: Structure MD_BLOCK_H_DETAIL. */ - MD_BLOCK_H, - - /*
    ...
    - * Note the text lines within code blocks are terminated with '\n' - * instead of explicit MD_TEXT_BR. */ - MD_BLOCK_CODE, - - /* Raw HTML block. This itself does not correspond to any particular HTML - * tag. The contents of it _is_ raw HTML source intended to be put - * in verbatim form to the HTML output. */ - MD_BLOCK_HTML, - - /*

    ...

    */ - MD_BLOCK_P, - - /* ...
    and its contents. - * Detail: Structure MD_BLOCK_TABLE_DETAIL (for MD_BLOCK_TABLE), - * structure MD_BLOCK_TD_DETAIL (for MD_BLOCK_TH and MD_BLOCK_TD) - * Note all of these are used only if extension MD_FLAG_TABLES is enabled. */ - MD_BLOCK_TABLE, - MD_BLOCK_THEAD, - MD_BLOCK_TBODY, - MD_BLOCK_TR, - MD_BLOCK_TH, - MD_BLOCK_TD -} MD_BLOCKTYPE; - -/* Span represents an in-line piece of a document which should be rendered with - * the same font, color and other attributes. A sequence of spans forms a block - * like paragraph or list item. */ -typedef enum MD_SPANTYPE { - /* ... */ - MD_SPAN_EM, - - /* ... */ - MD_SPAN_STRONG, - - /* ... - * Detail: Structure MD_SPAN_A_DETAIL. */ - MD_SPAN_A, - - /* ... - * Detail: Structure MD_SPAN_IMG_DETAIL. - * Note: Image text can contain nested spans and even nested images. - * If rendered into ALT attribute of HTML tag, it's responsibility - * of the parser to deal with it. - */ - MD_SPAN_IMG, - - /* ... */ - MD_SPAN_CODE, - - /* ... - * Note: Recognized only when MD_FLAG_STRIKETHROUGH is enabled. - */ - MD_SPAN_DEL, - - /* For recognizing inline ($) and display ($$) equations - * Note: Recognized only when MD_FLAG_LATEXMATHSPANS is enabled. - */ - MD_SPAN_LATEXMATH, - MD_SPAN_LATEXMATH_DISPLAY, - - /* Wiki links - * Note: Recognized only when MD_FLAG_WIKILINKS is enabled. - */ - MD_SPAN_WIKILINK, - - /* ... - * Note: Recognized only when MD_FLAG_UNDERLINE is enabled. */ - MD_SPAN_U -} MD_SPANTYPE; - -/* Text is the actual textual contents of span. */ -typedef enum MD_TEXTTYPE { - /* Normal text. */ - MD_TEXT_NORMAL = 0, - - /* NULL character. CommonMark requires replacing NULL character with - * the replacement char U+FFFD, so this allows caller to do that easily. */ - MD_TEXT_NULLCHAR, - - /* Line breaks. - * Note these are not sent from blocks with verbatim output (MD_BLOCK_CODE - * or MD_BLOCK_HTML). In such cases, '\n' is part of the text itself. */ - MD_TEXT_BR, /*
    (hard break) */ - MD_TEXT_SOFTBR, /* '\n' in source text where it is not semantically meaningful (soft break) */ - - /* Entity. - * (a) Named entity, e.g.   - * (Note MD4C does not have a list of known entities. - * Anything matching the regexp /&[A-Za-z][A-Za-z0-9]{1,47};/ is - * treated as a named entity.) - * (b) Numerical entity, e.g. Ӓ - * (c) Hexadecimal entity, e.g. ካ - * - * As MD4C is mostly encoding agnostic, application gets the verbatim - * entity text into the MD_PARSER::text_callback(). */ - MD_TEXT_ENTITY, - - /* Text in a code block (inside MD_BLOCK_CODE) or inlined code (`code`). - * If it is inside MD_BLOCK_CODE, it includes spaces for indentation and - * '\n' for new lines. MD_TEXT_BR and MD_TEXT_SOFTBR are not sent for this - * kind of text. */ - MD_TEXT_CODE, - - /* Text is a raw HTML. If it is contents of a raw HTML block (i.e. not - * an inline raw HTML), then MD_TEXT_BR and MD_TEXT_SOFTBR are not used. - * The text contains verbatim '\n' for the new lines. */ - MD_TEXT_HTML, - - /* Text is inside an equation. This is processed the same way as inlined code - * spans (`code`). */ - MD_TEXT_LATEXMATH -} MD_TEXTTYPE; - - -/* Alignment enumeration. */ -typedef enum MD_ALIGN { - MD_ALIGN_DEFAULT = 0, /* When unspecified. */ - MD_ALIGN_LEFT, - MD_ALIGN_CENTER, - MD_ALIGN_RIGHT -} MD_ALIGN; - - -/* String attribute. - * - * This wraps strings which are outside of a normal text flow and which are - * propagated within various detailed structures, but which still may contain - * string portions of different types like e.g. entities. - * - * So, for example, lets consider this image: - * - * ![image alt text](http://example.org/image.png 'foo " bar') - * - * The image alt text is propagated as a normal text via the MD_PARSER::text() - * callback. However, the image title ('foo " bar') is propagated as - * MD_ATTRIBUTE in MD_SPAN_IMG_DETAIL::title. - * - * Then the attribute MD_SPAN_IMG_DETAIL::title shall provide the following: - * -- [0]: "foo " (substr_types[0] == MD_TEXT_NORMAL; substr_offsets[0] == 0) - * -- [1]: """ (substr_types[1] == MD_TEXT_ENTITY; substr_offsets[1] == 4) - * -- [2]: " bar" (substr_types[2] == MD_TEXT_NORMAL; substr_offsets[2] == 10) - * -- [3]: (n/a) (n/a ; substr_offsets[3] == 14) - * - * Note that these invariants are always guaranteed: - * -- substr_offsets[0] == 0 - * -- substr_offsets[LAST+1] == size - * -- Currently, only MD_TEXT_NORMAL, MD_TEXT_ENTITY, MD_TEXT_NULLCHAR - * substrings can appear. This could change only of the specification - * changes. - */ -typedef struct MD_ATTRIBUTE { - const MD_CHAR* text; - MD_SIZE size; - const MD_TEXTTYPE* substr_types; - const MD_OFFSET* substr_offsets; -} MD_ATTRIBUTE; - - -/* Detailed info for MD_BLOCK_UL. */ -typedef struct MD_BLOCK_UL_DETAIL { - int is_tight; /* Non-zero if tight list, zero if loose. */ - MD_CHAR mark; /* Item bullet character in MarkDown source of the list, e.g. '-', '+', '*'. */ -} MD_BLOCK_UL_DETAIL; - -/* Detailed info for MD_BLOCK_OL. */ -typedef struct MD_BLOCK_OL_DETAIL { - unsigned start; /* Start index of the ordered list. */ - int is_tight; /* Non-zero if tight list, zero if loose. */ - MD_CHAR mark_delimiter; /* Character delimiting the item marks in MarkDown source, e.g. '.' or ')' */ -} MD_BLOCK_OL_DETAIL; - -/* Detailed info for MD_BLOCK_LI. */ -typedef struct MD_BLOCK_LI_DETAIL { - int is_task; /* Can be non-zero only with MD_FLAG_TASKLISTS */ - MD_CHAR task_mark; /* If is_task, then one of 'x', 'X' or ' '. Undefined otherwise. */ - MD_OFFSET task_mark_offset; /* If is_task, then offset in the input of the char between '[' and ']'. */ -} MD_BLOCK_LI_DETAIL; - -/* Detailed info for MD_BLOCK_H. */ -typedef struct MD_BLOCK_H_DETAIL { - unsigned level; /* Header level (1 - 6) */ -} MD_BLOCK_H_DETAIL; - -/* Detailed info for MD_BLOCK_CODE. */ -typedef struct MD_BLOCK_CODE_DETAIL { - MD_ATTRIBUTE info; - MD_ATTRIBUTE lang; - MD_CHAR fence_char; /* The character used for fenced code block; or zero for indented code block. */ -} MD_BLOCK_CODE_DETAIL; - -/* Detailed info for MD_BLOCK_TABLE. */ -typedef struct MD_BLOCK_TABLE_DETAIL { - unsigned col_count; /* Count of columns in the table. */ - unsigned head_row_count; /* Count of rows in the table header (currently always 1) */ - unsigned body_row_count; /* Count of rows in the table body */ -} MD_BLOCK_TABLE_DETAIL; - -/* Detailed info for MD_BLOCK_TH and MD_BLOCK_TD. */ -typedef struct MD_BLOCK_TD_DETAIL { - MD_ALIGN align; -} MD_BLOCK_TD_DETAIL; - -/* Detailed info for MD_SPAN_A. */ -typedef struct MD_SPAN_A_DETAIL { - MD_ATTRIBUTE href; - MD_ATTRIBUTE title; - int is_autolink; /* nonzero if this is an autolink */ -} MD_SPAN_A_DETAIL; - -/* Detailed info for MD_SPAN_IMG. */ -typedef struct MD_SPAN_IMG_DETAIL { - MD_ATTRIBUTE src; - MD_ATTRIBUTE title; -} MD_SPAN_IMG_DETAIL; - -/* Detailed info for MD_SPAN_WIKILINK. */ -typedef struct MD_SPAN_WIKILINK { - MD_ATTRIBUTE target; -} MD_SPAN_WIKILINK_DETAIL; - -/* Flags specifying extensions/deviations from CommonMark specification. - * - * By default (when MD_PARSER::flags == 0), we follow CommonMark specification. - * The following flags may allow some extensions or deviations from it. - */ -#define MD_FLAG_COLLAPSEWHITESPACE 0x0001 /* In MD_TEXT_NORMAL, collapse non-trivial whitespace into single ' ' */ -#define MD_FLAG_PERMISSIVEATXHEADERS 0x0002 /* Do not require space in ATX headers ( ###header ) */ -#define MD_FLAG_PERMISSIVEURLAUTOLINKS 0x0004 /* Recognize URLs as autolinks even without '<', '>' */ -#define MD_FLAG_PERMISSIVEEMAILAUTOLINKS 0x0008 /* Recognize e-mails as autolinks even without '<', '>' and 'mailto:' */ -#define MD_FLAG_NOINDENTEDCODEBLOCKS 0x0010 /* Disable indented code blocks. (Only fenced code works.) */ -#define MD_FLAG_NOHTMLBLOCKS 0x0020 /* Disable raw HTML blocks. */ -#define MD_FLAG_NOHTMLSPANS 0x0040 /* Disable raw HTML (inline). */ -#define MD_FLAG_TABLES 0x0100 /* Enable tables extension. */ -#define MD_FLAG_STRIKETHROUGH 0x0200 /* Enable strikethrough extension. */ -#define MD_FLAG_PERMISSIVEWWWAUTOLINKS 0x0400 /* Enable WWW autolinks (even without any scheme prefix, if they begin with 'www.') */ -#define MD_FLAG_TASKLISTS 0x0800 /* Enable task list extension. */ -#define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */ -#define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */ -#define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */ -#define MD_FLAG_HARD_SOFT_BREAKS 0x8000 /* Force all soft breaks to act as hard breaks. */ - -#define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS) -#define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS) - -/* Convenient sets of flags corresponding to well-known Markdown dialects. - * - * Note we may only support subset of features of the referred dialect. - * The constant just enables those extensions which bring us as close as - * possible given what features we implement. - * - * ABI compatibility note: Meaning of these can change in time as new - * extensions, bringing the dialect closer to the original, are implemented. - */ -#define MD_DIALECT_COMMONMARK 0 -#define MD_DIALECT_GITHUB (MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH | MD_FLAG_TASKLISTS) - -/* Parser structure. - */ -typedef struct MD_PARSER { - /* Reserved. Set to zero. - */ - unsigned abi_version; - - /* Dialect options. Bitmask of MD_FLAG_xxxx values. - */ - unsigned flags; - - /* Caller-provided rendering callbacks. - * - * For some block/span types, more detailed information is provided in a - * type-specific structure pointed by the argument 'detail'. - * - * The last argument of all callbacks, 'userdata', is just propagated from - * md_parse() and is available for any use by the application. - * - * Note any strings provided to the callbacks as their arguments or as - * members of any detail structure are generally not zero-terminated. - * Application has to take the respective size information into account. - * - * Any rendering callback may abort further parsing of the document by - * returning non-zero. - */ - int (*enter_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/); - int (*leave_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/); - - int (*enter_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/); - int (*leave_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/); - - int (*text)(MD_TEXTTYPE /*type*/, const MD_CHAR* /*text*/, MD_SIZE /*size*/, void* /*userdata*/); - - /* Debug callback. Optional (may be NULL). - * - * If provided and something goes wrong, this function gets called. - * This is intended for debugging and problem diagnosis for developers; - * it is not intended to provide any errors suitable for displaying to an - * end user. - */ - void (*debug_log)(const char* /*msg*/, void* /*userdata*/); - - /* Reserved. Set to NULL. - */ - void (*syntax)(void); -} MD_PARSER; - - -/* For backward compatibility. Do not use in new code. - */ -typedef MD_PARSER MD_RENDERER; - - -/* Parse the Markdown document stored in the string 'text' of size 'size'. - * The parser provides callbacks to be called during the parsing so the - * caller can render the document on the screen or convert the Markdown - * to another format. - * - * Zero is returned on success. If a runtime error occurs (e.g. a memory - * fails), -1 is returned. If the processing is aborted due any callback - * returning non-zero, the return value of the callback is returned. - */ -int md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userdata); - - -#ifdef __cplusplus - } /* extern "C" { */ -#endif - -#endif /* MD4C_H */ From 0d5d00882ad26255186406a38a48136fef469d91 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Sun, 23 Feb 2025 18:25:43 -0600 Subject: [PATCH 33/51] Hopefully fix whitespace issues --- OVP/D3D9Client/CMakeLists.txt | 2 +- OVP/D3D9Client/D3D9Client.cpp | 38 ++++----- OVP/D3D9Client/D3D9Client.h | 4 +- OVP/D3D9Client/D3D9Config.h | 2 +- OVP/D3D9Client/DebugControls.cpp | 136 +++++++++++++++---------------- OVP/D3D9Client/WindowMgr.cpp | 80 +++++++++--------- OVP/D3D9Client/WindowMgr.h | 8 +- OVP/D3D9Client/gcConst.cpp | 14 ++-- OVP/D3D9Client/gcCore.cpp | 18 ++-- OVP/GDIClient/GDIClient.cpp | 18 ++-- Orbitersdk/include/GraphicsAPI.h | 16 ++-- Sound/XRSound/LICENSE | 54 ------------ Src/Orbiter/CMakeLists.txt | 2 +- Src/Orbiter/Camera.cpp | 10 +-- Src/Orbiter/Camera.h | 8 +- Src/Orbiter/Config.cpp | 6 +- Src/Orbiter/Config.h | 4 +- Src/Orbiter/Defpanel.cpp | 4 +- Src/Orbiter/Defpanel.h | 2 +- Src/Orbiter/DlgMgr.cpp | 8 +- Src/Orbiter/DlgMgr.h | 2 +- Src/Orbiter/GraphicsAPI.cpp | 4 +- Src/Orbiter/MenuInfoBar.cpp | 2 +- Src/Orbiter/MenuInfoBar.h | 2 +- Src/Orbiter/Orbiter.cpp | 26 +++--- Src/Orbiter/OrbiterAPI.cpp | 2 +- Src/Orbiter/Pane.cpp | 8 +- Src/Orbiter/Pane.h | 4 +- Src/Orbiter/Panel.h | 4 +- Src/Orbiter/Panel2D.cpp | 2 +- Src/Orbiter/Panel2D.h | 6 +- Src/Orbiter/VCockpit.h | 4 +- Src/Orbiter/cmdline.cpp | 2 +- Src/Orbiter/cmdline.h | 2 +- 34 files changed, 225 insertions(+), 279 deletions(-) delete mode 100644 Sound/XRSound/LICENSE diff --git a/OVP/D3D9Client/CMakeLists.txt b/OVP/D3D9Client/CMakeLists.txt index 3e7b351e3..136357dc7 100644 --- a/OVP/D3D9Client/CMakeLists.txt +++ b/OVP/D3D9Client/CMakeLists.txt @@ -241,7 +241,7 @@ add_dependencies(D3D9Client ) install(TARGETS D3D9Client - LIBRARY + LIBRARY DESTINATION ${ORBITER_INSTALL_PLUGIN_DIR} ) diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index f4b52c3df..8962a2617 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -312,7 +312,7 @@ D3D9Client::~D3D9Client() // ============================================================== -// +// bool D3D9Client::ChkDev(const char *fnc) const { if (pDevice) return false; @@ -391,7 +391,7 @@ std::shared_ptr D3D9Client::clbkCreateRenderWindow() if (!g_pD3DObject) return NULL; Config->WriteParams(); - + uEnableLog = Config->DebugLvl; pSplashScreen = NULL; pBackBuffer = NULL; @@ -672,9 +672,9 @@ void D3D9Client::SketchPadTest() oapiReleaseTexture(hSrc); oapiReleaseTexture(hTgt); - + // Run Different Kind of Tests - // + // hTgt = oapiCreateSurfaceEx(768, 512, OAPISURFACE_RENDERTARGET); @@ -716,11 +716,11 @@ void D3D9Client::SketchPadTest() HPOLY hOutline = pCore->CreatePoly(NULL, Pol, 6, PF_CONNECT); HPOLY hOutline2 = pCore->CreatePoly(NULL, Pol, 6); - Vtx[0].color = 0xFFFF0000; - Vtx[1].color = 0xFFFFFF00; - Vtx[2].color = 0xFFF0FF00; - Vtx[3].color = 0xFF00FFFF; - Vtx[4].color = 0xFF0000FF; + Vtx[0].color = 0xFFFF0000; + Vtx[1].color = 0xFFFFFF00; + Vtx[2].color = 0xFFF0FF00; + Vtx[3].color = 0xFF00FFFF; + Vtx[4].color = 0xFF0000FF; Vtx[5].color = 0xFFFF00FF; Vtx[0].pos = FVECTOR2(-1, 0); @@ -734,7 +734,7 @@ void D3D9Client::SketchPadTest() Vtx[0].color = 0xFF00FF00; // Green - Vtx[1].color = 0xFF00FF00; // Green + Vtx[1].color = 0xFF00FF00; // Green Vtx[2].color = 0xFFFF00FF; // Mangenta Vtx[3].color = 0xFFFF00FF; // Mangenta Vtx[4].color = 0xFF0000FF; // Blue @@ -2143,7 +2143,7 @@ SURFHANDLE D3D9Client::clbkLoadSurface (const char *fname, DWORD attrib, bool bP } */ } - + return NatLoadSurface(fname, attrib, bPath); } @@ -2193,7 +2193,7 @@ SURFHANDLE D3D9Client::clbkCreateSurface(DWORD w, DWORD h, SURFHANDLE hTemplate) DWORD attrib = OAPISURFACE_PF_XRGB | OAPISURFACE_RENDERTARGET | OAPISURFACE_TEXTURE; if (hTemplate) attrib = SURFACE(hTemplate)->GetOAPIFlags(); - + SURFHANDLE hNew = NatCreateSurface(w, h, attrib); SURFACE(hNew)->SetName("clbkCreateSurface"); return hNew; @@ -2345,7 +2345,7 @@ bool D3D9Client::clbkBlt(SURFHANDLE tgt, DWORD tgtx, DWORD tgty, SURFHANDLE src, bool D3D9Client::clbkScaleBlt (SURFHANDLE tgt, DWORD tgtx, DWORD tgty, DWORD tgtw, DWORD tgth, SURFHANDLE src, DWORD srcx, DWORD srcy, DWORD srcw, DWORD srch, DWORD flag) const { - + if (src==NULL) { oapiWriteLog((char*)"ERROR: oapiBlt() Source surface is NULL"); return false; } if (tgt==NULL) tgt = pFramework->GetBackBufferHandle(); @@ -2436,7 +2436,7 @@ bool D3D9Client::clbkScaleBlt (SURFHANDLE tgt, DWORD tgtx, DWORD tgty, DWORD tgt { // Texture Update: Source is in system memory and target is a texture - // + // if (sd->Pool == D3DPOOL_SYSTEMMEM) { if (S_OK == pDevice->UpdateSurface(pss, &rs, pts, &tp)) return true; @@ -2448,14 +2448,14 @@ bool D3D9Client::clbkScaleBlt (SURFHANDLE tgt, DWORD tgtx, DWORD tgty, DWORD tgt // Screen Capture: Target is in system memory and source is a render taeget - // + // if ((td->Pool == D3DPOOL_SYSTEMMEM) && (sd->Usage & D3DUSAGE_RENDERTARGET)) { if (S_OK == pDevice->GetRenderTargetData(pss, pts)) { SURFACE(tgt)->Flags |= OAPISURFACE_CAPTURE; return true; } - + LogErr("oapiBlt() GetRenderTargetData() Failed"); BltError(src, tgt, &rs, &rt); return false; @@ -2480,7 +2480,7 @@ bool D3D9Client::clbkScaleBlt (SURFHANDLE tgt, DWORD tgtx, DWORD tgty, DWORD tgt return true; } else - { + { pSkp->StretchRect(src, &rs, &rt); clbkReleaseSketchpad_const(pSkp); return true; @@ -2536,7 +2536,7 @@ bool D3D9Client::clbkCopyBitmap(SURFHANDLE pdds, HBITMAP hbm, int x, int y, int SURFACE(pdds)->SetName("clbkCopyBitmap"); return true; } - else + else { LPDIRECT3DTEXTURE9 pTemp = NULL; LPDIRECT3DSURFACE9 pSrf = NULL; @@ -2567,7 +2567,7 @@ bool D3D9Client::clbkCopyBitmap(SURFHANDLE pdds, HBITMAP hbm, int x, int y, int else { pSrf->Release(); assert(false); - } + } } } DeleteDC(hdcImage); diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 223bc84eb..1de1296ea 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -82,7 +82,7 @@ struct _D3D9Stats DWORD TexChanges; ///< Number of texture changes DWORD MtrlChanges; ///< Number of material changes } Mesh; ///< Mesh related statistics - + struct { D3D9Time Update; ///< clbkUpdate D3D9Time Scene; ///< clbkRenderScene @@ -141,7 +141,7 @@ namespace oapi { // The DX9 render client for Orbiter // ============================================================== -class D3D9Client : public GraphicsClient +class D3D9Client : public GraphicsClient { friend class ::Scene; // <= likes to call Render2DOverlay() diff --git a/OVP/D3D9Client/D3D9Config.h b/OVP/D3D9Client/D3D9Config.h index c64885c20..c23be7f34 100644 --- a/OVP/D3D9Client/D3D9Config.h +++ b/OVP/D3D9Client/D3D9Config.h @@ -97,7 +97,7 @@ class D3D9Config { int bLocalGlares; int bIrradiance; int bAtmoQuality; - int NoPlanetAA; ///< Disable planet surface anti-aliasing to prevent white pixels at horizon + int NoPlanetAA; ///< Disable planet surface anti-aliasing to prevent white pixels at horizon char *DebugFont; ///< Font face for debug lines (default="Fixed") char *SolCfg; ///< Solar system to use (default="Sol") double GFXIntensity; ///< Post Processing | Light glow intensity (0.0...1.0, default=0.5) diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 0a3b98eae..0b904b2c9 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -32,7 +32,7 @@ extern D3D9Client *g_client; // Little binary helper #define SETFLAG(bitmap, bit, value) (value ? bitmap |= bit : bitmap &= ~bit) -#define CLAMP(x,a,b) min(max(a,x),b) +#define CLAMP(x,a,b) min(max(a,x),b) namespace DebugControls { @@ -146,7 +146,7 @@ const void *GetConfigParam (DWORD paramtype) float GetFloatFromBox(HWND hWnd, int item) { char lbl[32]; - GetWindowTextA(GetDlgItem(hWnd, item), lbl, 32); + GetWindowTextA(GetDlgItem(hWnd, item), lbl, 32); return float(atof(lbl)); } @@ -155,14 +155,14 @@ float GetFloatFromBox(HWND hWnd, int item) HWND CreateToolTip(int toolID, HWND hDlg, PTSTR pszText) { if (!toolID || !hDlg || !pszText) return NULL; - + // Get the window of the tool. HWND hwndTool = GetDlgItem(hDlg, toolID); // Create the tooltip. g_hInst is the global instance handle. HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL, WS_POPUP |TTS_ALWAYSTIP | TTS_BALLOON, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hDlg, NULL, g_hInst, NULL); - + if (!hwndTool || !hwndTip) return NULL; - + // Associate the tooltip with the tool. TOOLINFO toolInfo = { 0 }; toolInfo.cbSize = sizeof(toolInfo); @@ -218,7 +218,7 @@ void Create() dwGFX = oapiRegisterCustomCmd((char*)"D3D9 Graphics Controls", (char*)"This dialog allows to control various graphics options", OpenGFXDlgClbk, gfxDlg); resbias = 4.0 + Config->LODBias; - + memset(&OpenTex, 0, sizeof(OPENFILENAME)); memset(OpenFileName, 0, sizeof(OpenFileName)); @@ -380,13 +380,13 @@ void InitMatList(WORD shader) { LRESULT idx = SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0); SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_RESETCONTENT, 0, 0); - + Dropdown.clear(); if (shader == SHADER_NULL) { std::list list = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17 }; for (auto x : list) Dropdown.push_back(PrmList[x]); - for (auto x : Dropdown) SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_ADDSTRING, 0, (LPARAM)x.name.c_str()); + for (auto x : Dropdown) SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_ADDSTRING, 0, (LPARAM)x.name.c_str()); } if (shader == SHADER_METALNESS) { @@ -508,7 +508,7 @@ void OpenDlgClbk(void *context) SendDlgItemMessage(hDlg, IDC_DBG_MATADJ, TBM_SETRANGEMIN, 1, 0); SendDlgItemMessage(hDlg, IDC_DBG_MATADJ, TBM_SETTICFREQ, 1, 0); SendDlgItemMessage(hDlg, IDC_DBG_MATADJ, TBM_SETPOS, 1, 0); - + // Set the "pick" checked SendDlgItemMessage(hDlg, IDC_DBG_PICK, BM_SETCHECK, 1, 0); @@ -573,7 +573,7 @@ void OpenDlgClbk(void *context) Params[6].var[0] = DefVar(0.5f, 2, LIN, "Angle dependency"); Params[6].var[1] = DefVar(0, 1, LIN, "Maximum intensity"); Params[6].var[2] = DefVar(10.0f, 4096.0f, SQRT, "Specular lobe size"); - + // Emission2 Params[7].var[0] = DefVar(0, 2, LIN, "Red"); Params[7].var[1] = DefVar(0, 2, LIN, "Green"); @@ -584,10 +584,10 @@ void OpenDlgClbk(void *context) // SpecialFX Params[9].var[0] = DefVar(0, 1, LIN, "Part Temperature"); - + // Unused index 10 - + // Tuning ------------------------------------------------------------------------------------- // Albedo int i = 11; @@ -629,10 +629,10 @@ void SetTuningValue(int idx, D3DCOLORVALUE *pClr, DWORD clr, float value) case 0: pClr->r = CLAMP(value, mi, mx); break; case 1: pClr->g = CLAMP(value, mi, mx); break; case 2: pClr->b = CLAMP(value, mi, mx); break; - case 3: + case 3: { - if (Params[idx].var[clr].bGamma) pClr->a = 1.0f / CLAMP(value, mi, mx); - else pClr->a = CLAMP(value, mi, mx); + if (Params[idx].var[clr].bGamma) pClr->a = 1.0f / CLAMP(value, mi, mx); + else pClr->a = CLAMP(value, mi, mx); } break; } } @@ -645,7 +645,7 @@ float GetTuningValue(int idx, D3DCOLORVALUE *pClr, DWORD clr) case 0: return pClr->r; case 1: return pClr->g; case 2: return pClr->b; - case 3: + case 3: { if (Params[idx].var[clr].bGamma) return 1.0f / pClr->a; else return pClr->a; @@ -678,7 +678,7 @@ void UpdateShader() vVessel *vVes = (vVessel *)vObj; MatMgr *pMgr = vVes->GetMaterialManager(); - + switch (Shader) { case 0: hMesh->SetDefaultShader(SHADER_NULL); @@ -704,7 +704,7 @@ void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); if (!hMesh) return; - + DWORD matidx = hMesh->GetMeshGroupMaterialIdx(sGroup); DWORD texidx = hMesh->GetMeshGroupTextureIdx(sGroup); @@ -834,7 +834,7 @@ void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) hMesh->SetMaterial(&Mat, matidx); vVessel *vVes = (vVessel *)vObj; - vVes->GetMaterialManager()->RegisterMaterialChange(hMesh, matidx, &Mat); + vVes->GetMaterialManager()->RegisterMaterialChange(hMesh, matidx, &Mat); } @@ -871,7 +871,7 @@ bool IsMaterialModified(DWORD MatPrp) if (!hMesh) return false; DWORD matidx = hMesh->GetMeshGroupMaterialIdx(sGroup); - + D3D9MatExt Mat; if (!hMesh->GetMaterial(&Mat, matidx)) return false; @@ -921,7 +921,7 @@ float GetMaterialValue(DWORD MatPrp, DWORD clr) DWORD texidx = hMesh->GetMeshGroupTextureIdx(sGroup); const D3D9MatExt *pMat = hMesh->GetMaterial(matidx); - + if (!pMat) return 0.0f; D3D9Tune Tune; @@ -1095,7 +1095,7 @@ void DisplayMat(bool bRed, bool bGreen, bool bBlue, bool bAlpha) char lbl[32]; DWORD MatPrp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); - + float r = GetMaterialValue(MatPrp, 0); float g = GetMaterialValue(MatPrp, 1); float b = GetMaterialValue(MatPrp, 2); @@ -1104,7 +1104,7 @@ void DisplayMat(bool bRed, bool bGreen, bool bBlue, bool bAlpha) if (bRed) sprintf_s(lbl,32,"%3.3f", r); else sprintf_s(lbl,32,""); SetWindowText(GetDlgItem(hDlg, IDC_DBG_RED), lbl); - + if (bGreen) sprintf_s(lbl,32,"%3.3f", g); else sprintf_s(lbl,32,""); SetWindowText(GetDlgItem(hDlg, IDC_DBG_GREEN), lbl); @@ -1118,11 +1118,11 @@ void DisplayMat(bool bRed, bool bGreen, bool bBlue, bool bAlpha) SetWindowText(GetDlgItem(hDlg, IDC_DBG_ALPHA), lbl); if (bRed) EnableWindow(GetDlgItem(hDlg, IDC_DBG_RED), true); - else EnableWindow(GetDlgItem(hDlg, IDC_DBG_RED), false); + else EnableWindow(GetDlgItem(hDlg, IDC_DBG_RED), false); if (bGreen) EnableWindow(GetDlgItem(hDlg, IDC_DBG_GREEN), true); - else EnableWindow(GetDlgItem(hDlg, IDC_DBG_GREEN), false); + else EnableWindow(GetDlgItem(hDlg, IDC_DBG_GREEN), false); if (bBlue) EnableWindow(GetDlgItem(hDlg, IDC_DBG_BLUE), true); - else EnableWindow(GetDlgItem(hDlg, IDC_DBG_BLUE), false); + else EnableWindow(GetDlgItem(hDlg, IDC_DBG_BLUE), false); if (bAlpha) EnableWindow(GetDlgItem(hDlg, IDC_DBG_ALPHA), true); else EnableWindow(GetDlgItem(hDlg, IDC_DBG_ALPHA), false); @@ -1140,7 +1140,7 @@ void UpdateMaterialDisplay(bool bSetup) OBJHANDLE hObj = vObj->GetObjectA(); if (!oapiIsVessel(hObj)) return; - + D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); if (!hMesh) return; @@ -1161,7 +1161,7 @@ void UpdateMaterialDisplay(bool bSetup) if (bSetup) SelColor = 0; DWORD MatPrp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); - + DisplayMat(Params[MatPrp].var[0].bUsed, Params[MatPrp].var[1].bUsed, Params[MatPrp].var[2].bUsed, Params[MatPrp].var[3].bUsed); SetToolTip(IDC_DBG_RED, hTipRed, Params[MatPrp].var[0].tip); @@ -1182,7 +1182,7 @@ void UpdateMaterialDisplay(bool bSetup) sprintf_s(lbl, 256, "Mesh: %s", RemovePath(hMesh->GetName())); SetWindowText(GetDlgItem(hDlg, IDC_DBG_MESHNAME), lbl); - + GetWindowText(GetDlgItem(hDlg, IDC_DBG_MESHGRP), lbl2, 64); if (strcmp(lbl, lbl2)) SetWindowText(GetDlgItem(hDlg, IDC_DBG_MESHGRP), lbl); // Avoid causing flashing } @@ -1202,8 +1202,8 @@ bool IsSelectedGroupRendered() void UpdateColorSlider(WORD pos) { float val = float(pos)/255.0f; - - DWORD MatPrp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); + + DWORD MatPrp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); bool bLink = (SendDlgItemMessageA(hDlg, IDC_DBG_LINK, BM_GETCHECK, 0, 0)==BST_CHECKED); bool bExtend = (SendDlgItemMessageA(hDlg, IDC_DBG_EXTEND, BM_GETCHECK, 0, 0) == BST_CHECKED); @@ -1221,7 +1221,7 @@ void UpdateColorSlider(WORD pos) float old = GetMaterialValue(MatPrp, SelColor); float fct = val/old; - + if (old<1e-4) fct = val; if (bLink) { @@ -1279,7 +1279,7 @@ void SetupMeshGroups() { char lbl[256]; - if (!vObj) return; + if (!vObj) return; SetWindowText(GetDlgItem(hDlg, IDC_DBG_VISUAL), visual); @@ -1354,7 +1354,7 @@ void SetVisual(vObject *vo) // void UpdateVisual() { - if (!vObj || !hDlg) return; + if (!vObj || !hDlg) return; nMesh = vObj->GetMeshCount(); sprintf_s(visual, 64, "Visual: %s", vObj->GetName()); SetupMeshGroups(); @@ -1376,14 +1376,14 @@ void UpdateVisual() for (DWORD j = 0; j < nemitter; j++) { const LightEmitter *em = vessel->GetLightEmitter(j); - + if (em->GetType() == LightEmitter::LT_SPOT) { const SpotLight *sl = static_cast(em); double P = sl->GetPenumbra()*DEG; double U = sl->GetUmbra()*DEG; double R = sl->GetRange(); sprintf_s(line, 64, "%s P%1.0f U%1.0f R%1.0f", _PTR(em), P, U, R); - } + } if (em->GetType() == LightEmitter::LT_POINT) { const PointLight *pl = static_cast(em); @@ -1450,12 +1450,12 @@ D3DXCOLOR ProcessColor(D3DXVECTOR4 C, PCParam *prm, int x, int y) // Swap color channels C = D3DXVECTOR4(C.z, C.y, C.z, C.x); - + if (c>0.001) { D3DXVECTOR4 rnd((float)oapiRand(),(float)oapiRand(), (float)oapiRand(), (float)oapiRand()); C += (rnd*2.0f-1.0f) * (c/(2.0f+fMip)); } - + // Reduce contrast if (prm->Func & 0x2) { @@ -1491,7 +1491,7 @@ bool Execute(HWND hWnd, LPOPENFILENAME pOF) if (SendDlgItemMessageA(hDlg, IDC_DBG_NORM, BM_GETCHECK, 0, 0)==BST_CHECKED) Func |= 0x1; if (SendDlgItemMessageA(hDlg, IDC_DBG_FADE, BM_GETCHECK, 0, 0)==BST_CHECKED) Func |= 0x2; if (SendDlgItemMessageA(hDlg, IDC_DBG_SEAMS, BM_GETCHECK, 0, 0)==BST_CHECKED) Func |= 0x4; - + if (Action>=0 && Action<=2) { LPDIRECT3DTEXTURE9 pTex = NULL; @@ -1502,7 +1502,7 @@ bool Execute(HWND hWnd, LPOPENFILENAME pOF) HR(D3DXCreateTextureFromFileExA(pDevice, pOF->lpstrFile, D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT, D3DX_DEFAULT, 0, &info, NULL, &pTex)); if (!pTex) { - LogErr("Failed to open a file [%s]", pOF->lpstrFile); + LogErr("Failed to open a file [%s]", pOF->lpstrFile); return false; } @@ -1519,7 +1519,7 @@ bool Execute(HWND hWnd, LPOPENFILENAME pOF) if (!pSave) return false; - + // Process texture ---------------------------------------------- // for (DWORD n=0;n>n; DWORD h = info.Height>>n; - HR(pTex->LockRect(n, &in, NULL, 0)); + HR(pTex->LockRect(n, &in, NULL, 0)); HR(pWork->LockRect(n, &out, NULL, 0)); DWORD *pIn = (DWORD *)in.pBits; DWORD *pOut = (DWORD *)out.pBits; @@ -1539,14 +1539,14 @@ bool Execute(HWND hWnd, LPOPENFILENAME pOF) prm.a = GetFloatFromBox(hDlg, IDC_DBG_VARA); prm.b = GetFloatFromBox(hDlg, IDC_DBG_VARB); prm.c = GetFloatFromBox(hDlg, IDC_DBG_VARC); - + for (DWORD y=0;yGetScene()->GetCameraProxyVisual(); + vPlanet *vP = g_client->GetScene()->GetCameraProxyVisual(); if (vP) vP->SetMicroTexture(pSave, Target-1); SAFE_RELEASE(pSave); return true; @@ -1626,7 +1626,7 @@ bool Execute(HWND hWnd, LPOPENFILENAME pOF) return false; } - + // ============================================================================================= // @@ -1699,13 +1699,13 @@ void CreateSamplingKernel() { int s = 27; int k = 0; - + VECTOR3 *data = new VECTOR3[s]; - + double d = 0.0; double a = 0.0; - - for (int i = 0; i < s; i++) { + + for (int i = 0; i < s; i++) { double z = (oapiRand()*2.0 - 1.0) * (PI2 / 8); data[i].x = sqrt(d) * sin(a+z); data[i].y = sqrt(d) * cos(a+z); @@ -1772,7 +1772,7 @@ INT_PTR CALLBACK ViewProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) static bool isOpen = false; // IDC_DBG_MORE (full or reduced width) DWORD Prp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); - + switch (uMsg) { case WM_INITDIALOG: @@ -1812,7 +1812,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) OpenTex.hwndOwner = hWnd; DWORD Prp = DropdownList(DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_GETCURSEL, 0, 0))); - + switch (uMsg) { case WM_INITDIALOG: @@ -1828,7 +1828,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (HWND(lParam)==GetDlgItem(hWnd, IDC_DBG_SPEED)) { if (pos==0) pos = WORD(SendDlgItemMessage(hDlg, IDC_DBG_SPEED, TBM_GETPOS, 0, 0)); - double fpos = pow(2.0,double(pos)*13.0/200.0); + double fpos = pow(2.0,double(pos)*13.0/200.0); sprintf_s(lbl,32,"%1.0f",fpos); SetWindowTextA(GetDlgItem(hWnd, IDC_DBG_SPEEDDSP), lbl); camSpeed = fpos/50.0; @@ -1854,7 +1854,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDCANCEL: Close(); break; - + case IDC_DBG_KERNEL: { CreateSamplingKernel(); @@ -1954,7 +1954,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_MATPRP: if (HIWORD(wParam)==CBN_SELCHANGE) { UpdateMaterialDisplay(true); - SetColorSlider(); + SetColorSlider(); } break; @@ -1978,38 +1978,38 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (HIWORD(wParam)==CBN_SELCHANGE) camMode = DWORD(SendDlgItemMessage(hWnd, IDC_DBG_CAMERA, CB_GETCURSEL, 0, 0)); break; - case IDC_DBG_MSHUP: + case IDC_DBG_MSHUP: if (HIWORD(wParam)==BN_CLICKED) sMesh--; SetupMeshGroups(); break; - case IDC_DBG_MSHDN: + case IDC_DBG_MSHDN: if (HIWORD(wParam)==BN_CLICKED) sMesh++; SetupMeshGroups(); break; - case IDC_DBG_GRPUP: + case IDC_DBG_GRPUP: if (HIWORD(wParam)==BN_CLICKED) sGroup--; SetupMeshGroups(); break; - case IDC_DBG_GRPDN: - if (HIWORD(wParam)==BN_CLICKED) sGroup++; + case IDC_DBG_GRPDN: + if (HIWORD(wParam)==BN_CLICKED) sGroup++; SetupMeshGroups(); break; - - case IDC_DBG_MESH: + + case IDC_DBG_MESH: if (HIWORD(wParam)==EN_KILLFOCUS) { char cbuf[32]; - GetWindowText(GetDlgItem(hWnd, IDC_DBG_MESH), cbuf, 32); + GetWindowText(GetDlgItem(hWnd, IDC_DBG_MESH), cbuf, 32); for (int i=0; i<32;i++) if (cbuf[i]==0 || cbuf[i]=='/') { cbuf[i]=0; break; } sMesh = atoi(cbuf); SetupMeshGroups(); } break; - case IDC_DBG_GROUP: + case IDC_DBG_GROUP: if (HIWORD(wParam)==EN_KILLFOCUS) { char cbuf[32]; GetWindowText(GetDlgItem(hWnd, IDC_DBG_GROUP), cbuf, 32); @@ -2086,8 +2086,8 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_VARC: case IDC_DBG_FILE: break; - - default: + + default: LogErr("LOWORD(%hu), HIWORD(0x%hX)",LOWORD(wParam),HIWORD(wParam)); break; } diff --git a/OVP/D3D9Client/WindowMgr.cpp b/OVP/D3D9Client/WindowMgr.cpp index 87e562568..e83f4fabb 100644 --- a/OVP/D3D9Client/WindowMgr.cpp +++ b/OVP/D3D9Client/WindowMgr.cpp @@ -60,7 +60,7 @@ inline DWORD _Colour(const FVECTOR4 *c) if (r > 0xFF) r = 0xFF; if (g > 0xFF) g = 0xFF; if (b > 0xFF) b = 0xFF; - + return (b << 16) | (g << 8) | r; } // =============================================================================================== @@ -192,9 +192,9 @@ Node::Node(SideBar *pSB, const char *label, HWND hDlg, DWORD color, Node *pP) : HDC hSrc = CreateCompatibleDC(hDC); HDC hTgt = CreateCompatibleDC(hDC); - + GetObject(hTit, sizeof(BITMAP), &bm); - + hBmp = CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); pSB->ReleaseDC(hDC); @@ -205,11 +205,11 @@ Node::Node(SideBar *pSB, const char *label, HWND hDlg, DWORD color, Node *pP) : // Recolorize the title bar for (int y = 0; y < bm.bmHeight; y++) { - for (int x = 0; x < bm.bmWidth; x++) { + for (int x = 0; x < bm.bmWidth; x++) { COLORREF cr = GetPixel(hSrc, x, y); FVECTOR4 c = _Colour(cr); FVECTOR4 out = (clr * c.b) + (white * c.g); - SetPixel(hTgt, x, y, _Colour(&out)); + SetPixel(hTgt, x, y, _Colour(&out)); } } @@ -307,8 +307,8 @@ int Node::Paint(HDC hDC, int y) int wof = 0, hof = 0; DWORD ck = 0; - if (pSB->GetStyle() == gcGUI::DS_FLOAT) x += 1; - + if (pSB->GetStyle() == gcGUI::DS_FLOAT) x += 1; + if (hBmp) { if (pParent) { SelectObject(hDC, pMgr->GetSubTitleFont()); @@ -324,11 +324,11 @@ int Node::Paint(HDC hDC, int y) } } - + // Draw Title Bars ----------------------------- // if (hBmp) { - + HDC hSr = CreateCompatibleDC(hDC); int z = width - bm.bmHeight - 3; @@ -337,20 +337,20 @@ int Node::Paint(HDC hDC, int y) SelectObject(hSr, hBmp); BitBlt(hDC, x, y, width - 10, bm.bmHeight, hSr, 0, 0, SRCCOPY); - BitBlt(hDC, width - 10 - x, y, 10, bm.bmHeight, hSr, bm.bmWidth - 10, 0, SRCCOPY); + BitBlt(hDC, width - 10 - x, y, 10, bm.bmHeight, hSr, bm.bmWidth - 10, 0, SRCCOPY); TextOut(hDC, wof, y + hof, Label, lstrlen(Label)); - + DeleteDC(hSr); if (bOpen) PaintIcon(hDC, x, y, 0); else PaintIcon(hDC, x, y, 1); if (bClose) PaintIcon(hDC, z, y, 2); - + y += bm.bmHeight; } pos = { x, y }; - + if (bOpen && hDlg) { RECT r; GetWindowRect(hDlg, &r); @@ -366,9 +366,9 @@ int Node::Paint(HDC hDC, int y) void Node::PaintIcon(HDC hDC, int x, int y, int id) { WindowManager *pMgr = pSB->GetWM(); - DWORD yell = RGB(255, 255, 0); - DWORD mang = RGB(255, 0, 255); - + DWORD yell = RGB(255, 255, 0); + DWORD mang = RGB(255, 0, 255); + HBITMAP hIco = pMgr->GetBitmap(gcGUI::BM_ICONS); if (hIco) { @@ -402,11 +402,11 @@ int Node::Spacer(HDC hDC, int y) int width = pSB->GetWidth(); int h = CellSize(); - + SelectObject(hDC, (HBRUSH)GetStockObject(GRAY_BRUSH)); SelectObject(hDC, (HPEN)GetStockObject(NULL_PEN)); Rectangle(hDC, 0, y, width + 1, y + h + 1); - + return y + h; } @@ -541,7 +541,7 @@ WindowManager::WindowManager(HWND hAppMainWindow, HINSTANCE _hInst, bool bWindow DWORD flags = 0; if (Config->gcGUIMode == 1) flags |= CS_NOCLOSE; - WNDCLASS wc; + WNDCLASS wc; memset(&wc, 0, sizeof(WNDCLASS)); wc.style = flags | CS_OWNDC | CS_SAVEBITS; wc.lpfnWndProc = SideBarWndProc; @@ -572,7 +572,7 @@ WindowManager::WindowManager(HWND hAppMainWindow, HINSTANCE _hInst, bool bWindow hAppFont = CreateFont(cfg.txt_main_size, 0, 0, 0, cfg.txt_main_weight, false, false, 0, 0, 0, 2, CLEARTYPE_QUALITY, 49, cfg.fnt_main); hSubFont = CreateFont(cfg.txt_sub_size, 0, 0, 0, cfg.txt_sub_weight, false, false, 0, 0, 0, 2, CLEARTYPE_QUALITY, 49, cfg.fnt_sub); - + if (!hAppFont) LogErr("Font Not Found [%s]", cfg.fnt_main); if (!hSubFont) LogErr("Font Not Found [%s]", cfg.fnt_sub); @@ -611,7 +611,7 @@ WindowManager::~WindowManager() oapiUnregisterCustomCmd(Cmd); for(SideBar* sb : sbList) delete sb; - + UnregisterClass("SideBarWnd", hInst); UnregisterClass("Floater", hInst); @@ -675,7 +675,7 @@ HNODE WindowManager::RegisterApplication(gcGUIApp *pPtr, const char *label, HWND if (Config->gcGUIMode >= 2) docked = gcGUI::DS_FLOAT; if (docked == gcGUI::DS_FLOAT) pSB = NewSideBar(NULL); - + if (Config->gcGUIMode == 3) { HWND hWnd = pSB->GetHWND(); SetWindowText(hWnd, label); @@ -946,11 +946,11 @@ SideBar* WindowManager::StartDrag(Node *pAN, int x, int y) for (Node * an : pSBOld->wList) if (an->pParent == pAN) tmp.push_back(an); - for (Node * an : tmp) + for (Node * an : tmp) { - pSBOld->RemoveWindow(an); // Cant remove directly from a list being browsed + pSBOld->RemoveWindow(an); // Cant remove directly from a list being browsed pSBNew->AddWindow(an); - } + } } sbDrag = pSBNew; @@ -959,7 +959,7 @@ SideBar* WindowManager::StartDrag(Node *pAN, int x, int y) y -= ptOffset.y; pSBNew->ResetWindow(x, y); - + InvalidateRect(pSBNew->GetHWND(), NULL, true); InvalidateRect(pSBOld->GetHWND(), NULL, true); @@ -989,7 +989,7 @@ void WindowManager::Drag(int x, int y) x -= ptOffset.x; y -= ptOffset.y; - RECT rect; + RECT rect; SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0); int t = sbDrag->GetTopNode()->bm.bmHeight; @@ -1043,7 +1043,7 @@ SideBar *WindowManager::FindDestination() if (a > z) { z = a; sbDest = sb; } } } - + if (sbDest != pOld && pOld != NULL) { qInsert.pTgt = NULL; qInsert.List.clear(); @@ -1085,7 +1085,7 @@ bool WindowManager::MainWindowProc(const SDL_Event &event) SideBar::SideBar(class WindowManager *_pMgr, DWORD _state) { pMgr = _pMgr; - + HWND hMainWnd = pMgr->GetMainWindow(); hInst = pMgr->GetInstance(); width = pMgr->GetWidth(); @@ -1113,7 +1113,7 @@ SideBar::SideBar(class WindowManager *_pMgr, DWORD _state) DWORD exstyle = 0; DWORD style = 0; - if (Config->gcGUIMode == 1) { + if (Config->gcGUIMode == 1) { if (state == gcGUI::DS_RIGHT) xref = r.right; if (state == gcGUI::DS_LEFT) xref = -width; if (state == gcGUI::DS_FLOAT) xref = width, height = width; @@ -1157,7 +1157,7 @@ SideBar::SideBar(class WindowManager *_pMgr, DWORD _state) // =============================================================================================== // SideBar::~SideBar() -{ +{ for (Node *v : wList) { if (v->hDlg) DestroyWindow(v->hDlg); @@ -1354,8 +1354,8 @@ void SideBar::GetVisualList(vector &tmp) { if (Config->gcGUIMode == 3) { for (Node* ap : wList) if (ap->hDlg) tmp.push_back(ap); - } - else + } + else { for (Node* ap : wList) { Node* pPar = ap->pParent; @@ -1460,7 +1460,7 @@ bool SideBar::TryInsert(SideBar *sbIn) tInsert *pIns = pMgr->InsertList(); if (pIns->pTgt != this) return false; - + map &wIns = pIns->List; map wPrev = wIns; @@ -1469,7 +1469,7 @@ bool SideBar::TryInsert(SideBar *sbIn) int yp = sbIn->GetRect().top - GetRect().top; int h = sbIn->ComputeLength(); int y = rollpos; - + Node *pNode = sbIn->GetTopNode(); if (!pNode) return false; @@ -1492,7 +1492,7 @@ bool SideBar::Apply() SideBar *pDG = pMgr->GetDraged(); tInsert *pIns = pMgr->InsertList(); - if ((pIns->pTgt == this) && (pIns->List.size()>0)) + if ((pIns->pTgt == this) && (pIns->List.size()>0)) { for (auto &var : pIns->List) { @@ -1726,7 +1726,7 @@ int SideBar::ComputeLength() if (bInsert) for (auto &var : wIns) if (var.second == NULL) y += var.first->CellSize(); - for (Node* ap : drawList) + for (Node* ap : drawList) { y += ap->CellSize(); if (bInsert) for (auto &var : wIns) if (var.second == ap) y += var.first->CellSize(); @@ -1755,7 +1755,7 @@ void SideBar::PaintWindow() map &wIns = pIns->List; bool bInsert = (pIns->pTgt == this) && (wIns.size() > 0); - + if (bInsert) for (auto &var : wIns) { if (var.second == NULL) y = var.first->Spacer(hDC, y); @@ -1798,10 +1798,10 @@ void SideBar::PaintWindow() for (Node* ap : wList) { bool bFound = false; for (Node* q : drawList) if (q == ap) { bFound = true; break; } - + if (bFound && ap->hDlg) { if (ap->bOpen) ap->Move(); - else ShowWindow(ap->hDlg, SW_HIDE); + else ShowWindow(ap->hDlg, SW_HIDE); } else if (ap->hDlg) ShowWindow(ap->hDlg, SW_HIDE); } diff --git a/OVP/D3D9Client/WindowMgr.h b/OVP/D3D9Client/WindowMgr.h index 0e6624d07..d9558b863 100644 --- a/OVP/D3D9Client/WindowMgr.h +++ b/OVP/D3D9Client/WindowMgr.h @@ -121,11 +121,11 @@ class SideBar Node * FindClosest(vector &vis, Node *pPar, int yval); Node * FindNode(HWND hDlg); DWORD GetAutoColor(); - + WindowManager *GetWM() const { return pMgr; } vector wList; - + private: class WindowManager *pMgr; @@ -198,7 +198,7 @@ class WindowManager : public gcGUIBase HBITMAP GetBitmap(int id) const; HFONT GetAppTitleFont() const { return hAppFont; } HFONT GetSubTitleFont() const { return hSubFont; } - + // =============================================================================================== // @@ -236,7 +236,7 @@ class WindowManager : public gcGUIBase Conf cfg; private: - + tInsert qInsert; vector sbList; SideBar * sbDrag; diff --git a/OVP/D3D9Client/gcConst.cpp b/OVP/D3D9Client/gcConst.cpp index 4e7868594..4498986e0 100644 --- a/OVP/D3D9Client/gcConst.cpp +++ b/OVP/D3D9Client/gcConst.cpp @@ -3,9 +3,9 @@ // // Copyright (C) 2013-2016 Jarmo Nikkanen // -// 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 +// 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. @@ -31,7 +31,7 @@ extern class D3D9Client *g_client; // Custom SwapChain Interface // =============================================================================================== // -HSWAP gcConst::RegisterSwap(HWND hWnd, HSWAP hData, int AA) +HSWAP gcConst::RegisterSwap(HWND hWnd, HSWAP hData, int AA) { return gcCore::RegisterSwap(hWnd, hData, AA); } @@ -39,21 +39,21 @@ HSWAP gcConst::RegisterSwap(HWND hWnd, HSWAP hData, int AA) // =============================================================================================== // void gcConst::FlipSwap(HSWAP hSwap) -{ +{ gcCore::FlipSwap(hSwap); } // =============================================================================================== // SURFHANDLE gcConst::GetRenderTarget(HSWAP hSwap) -{ +{ return gcCore::GetRenderTarget(hSwap); } // =============================================================================================== // void gcConst::ReleaseSwap(HSWAP hSwap) -{ +{ gcCore::ReleaseSwap(hSwap); } diff --git a/OVP/D3D9Client/gcCore.cpp b/OVP/D3D9Client/gcCore.cpp index c903dec4f..8d52324d0 100644 --- a/OVP/D3D9Client/gcCore.cpp +++ b/OVP/D3D9Client/gcCore.cpp @@ -100,8 +100,8 @@ DLLCLBK void gcBindCoreMethod(void** ppFnc, const char* name) // Custom SwapChain Interface // =============================================================================================== // -HSWAP gcCore::RegisterSwap(HWND hWnd, HSWAP hData, int AA) -{ +HSWAP gcCore::RegisterSwap(HWND hWnd, HSWAP hData, int AA) +{ gcSwap * pData = (gcSwap*)hData; D3DPRESENT_PARAMETERS pp; @@ -129,7 +129,7 @@ HSWAP gcCore::RegisterSwap(HWND hWnd, HSWAP hData, int AA) { if (!pData) pData = new gcSwap(); else pData->Release(); - + LPDIRECT3DSURFACE9 pBack = NULL; HR(pSwap->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBack)); @@ -151,23 +151,23 @@ HSWAP gcCore::RegisterSwap(HWND hWnd, HSWAP hData, int AA) // =============================================================================================== // -void gcCore::FlipSwap(HSWAP hSwap) -{ +void gcCore::FlipSwap(HSWAP hSwap) +{ HR(((gcSwap*)hSwap)->pSwap->Present(0, 0, 0, 0, 0)); } // =============================================================================================== // -SURFHANDLE gcCore::GetRenderTarget(HSWAP hSwap) -{ +SURFHANDLE gcCore::GetRenderTarget(HSWAP hSwap) +{ return ((gcSwap*)hSwap)->hSurf; } // =============================================================================================== // -void gcCore::ReleaseSwap(HSWAP hSwap) -{ +void gcCore::ReleaseSwap(HSWAP hSwap) +{ if (hSwap) delete ((gcSwap*)hSwap); } diff --git a/OVP/GDIClient/GDIClient.cpp b/OVP/GDIClient/GDIClient.cpp index 3819e4169..b5364638e 100644 --- a/OVP/GDIClient/GDIClient.cpp +++ b/OVP/GDIClient/GDIClient.cpp @@ -107,7 +107,7 @@ bool GDIClient::clbkSaveSurfaceToImage (SURFHANDLE surf, const char *fname, Imag if (OpenClipboard (GetRenderWindow()->Win32Handle())) { EmptyClipboard(); SetClipboardData(CF_BITMAP,hbm); - CloseClipboard(); + CloseClipboard(); } } else { BITMAP bmp; @@ -115,16 +115,16 @@ bool GDIClient::clbkSaveSurfaceToImage (SURFHANDLE surf, const char *fname, Imag GetObject (hbm, sizeof(BITMAP), &bmp); // map to device-independent bitmap - bi.biSize = sizeof(BITMAPINFOHEADER); - bi.biWidth = bmp.bmWidth; + bi.biSize = sizeof(BITMAPINFOHEADER); + bi.biWidth = bmp.bmWidth; bi.biHeight = -bmp.bmHeight; - bi.biPlanes = 1; - bi.biBitCount = 24; - bi.biCompression = BI_RGB; - bi.biSizeImage = 0; + bi.biPlanes = 1; + bi.biBitCount = 24; + bi.biCompression = BI_RGB; + bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; - bi.biClrUsed = 0; + bi.biClrUsed = 0; bi.biClrImportant = 0; oapi::ImageData imgdata; @@ -141,7 +141,7 @@ bool GDIClient::clbkSaveSurfaceToImage (SURFHANDLE surf, const char *fname, Imag WriteImageDataToFile (imgdata, fname, fmt, quality); - GlobalUnlock(hDIB); + GlobalUnlock(hDIB); GlobalFree(hDIB); } DeleteObject(hbm); diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 408af3107..f3cce81ac 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -127,7 +127,7 @@ typedef void *HDC; /** * File path for celestial sphere background textures * \par Parameter type: - * const std::filesystem::path* + * *char */ #define CFGPRM_CSPHERETEXTURE 0x0013 @@ -202,7 +202,7 @@ typedef void *HDC; /** * Path to background star texture * \par Parameter type: - * const std::filesystem::path* + * *char */ #define CFGPRM_CSPHERESTARTEXTURE 0x001D @@ -533,7 +533,7 @@ class OAPIFUNC GraphicsClient: public Module { * \param str Text string to print */ virtual void clbkDebugString(const char *str) {} - + /** * \brief Texture request * @@ -917,7 +917,7 @@ class OAPIFUNC GraphicsClient: public Module { * \brief returns a list of popup windows owned by the render window. * \param [out] hPopupWnd on exit, points to a list of window handles * \return Number of entries in the list. - * \note The list returned by this method contains the handles of + * \note The list returned by this method contains the handles of * popup windows that are to be rendered on top of the render viewport * (e.g. dialog boxes). * \note A client can use this list if it requires a special method of @@ -1102,7 +1102,7 @@ class OAPIFUNC GraphicsClient: public Module { /** * \brief Create a surface for texturing, as a blitting source, etc. - * + * * Surfaces are used for offscreen bitmap and texture manipulation, * blitting and rendering. * Derived classes should create a device-specific surface, and @@ -1427,7 +1427,7 @@ class OAPIFUNC GraphicsClient: public Module { */ virtual Font *clbkCreateFont (int height, bool prop, const char *face, FontStyle style = FontStyle::FONT_NORMAL, int orientation = 0) const { return NULL; } virtual Font* clbkCreateFontEx (int height, char* face, int width = 0, int weight = 400, FontStyle style = FontStyle::FONT_NORMAL, float spacing = 0.0f) const { return NULL; } - + /** * \brief De-allocate a font resource. * \param font pointer to font resource @@ -1502,7 +1502,7 @@ class OAPIFUNC GraphicsClient: public Module { // @} /** - * \brief Constructs a synthetic elevation grid for a tile by interpolating + * \brief Constructs a synthetic elevation grid for a tile by interpolating * ancestor elevation data * \param emgr elevation manager handle (retrieve with oapiElevationManager) * \param [in] ilat patch latitude index @@ -1694,7 +1694,7 @@ class OAPIFUNC GraphicsClient: public Module { /** * \brief Change the default splash screen - * + * * Called before clbkCreateRenderWindow to override the default splash screen * image and text color. * diff --git a/Sound/XRSound/LICENSE b/Sound/XRSound/LICENSE deleted file mode 100644 index 73d9692bf..000000000 --- a/Sound/XRSound/LICENSE +++ /dev/null @@ -1,54 +0,0 @@ -MIT License - -Copyright (c) 2021 Douglas E. Beachy - -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. - -============================================================================= - -DEPENDENCIES: - -1) XRSound uses the irrKlang Sound Engine. -See https://www.ambiera.com/irrklang/license.html for details -about the ikkLang license. Its license as of 31-July-2021 is quoted below: - -The irrKlang License -irrKlang's source codes, documentation and binaries contained within the -distributed archive are copyright (c) Nikolaus Gebhardt / Ambiera 2001-2020. - -The contents of the irrKlang distribution archive may not be redistributed, -reproduced, modified, transmitted, broadcast, published or adapted in any way, -shape or form, without the prior written consent of the owner, Nikolaus -Gebhardt. - -The irrKlang.dll, irrKlang.so and libirrklang.dylib files may be -redistributed without the author's prior permission in non-commercial -products, and must remain unmodified except for compressing the file. - -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 REGENTS 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/Src/Orbiter/CMakeLists.txt b/Src/Orbiter/CMakeLists.txt index 89a5e603c..cf639df95 100644 --- a/Src/Orbiter/CMakeLists.txt +++ b/Src/Orbiter/CMakeLists.txt @@ -187,7 +187,7 @@ install(FILES $ DESTINATION ${ORBITER_INSTALL_SDK_DI # Copy library to its Orbitersdk/lib location so that external project integrated into the build can find it add_custom_command(TARGET ${OrbiterTgt} POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${ORBITER_BINARY_SDK_DIR}/lib - COMMAND ${CMAKE_COMMAND} -E copy ${ORBITER_LIB} ${ORBITER_BINARY_SDK_DIR}/lib/ + COMMAND ${CMAKE_COMMAND} -E copy ${ORBITER_LIB} ${ORBITER_BINARY_SDK_DIR}/lib/ ) string(TIMESTAMP DATE "%d %b %Y") diff --git a/Src/Orbiter/Camera.cpp b/Src/Orbiter/Camera.cpp index 25055321f..c316ad7d6 100644 --- a/Src/Orbiter/Camera.cpp +++ b/Src/Orbiter/Camera.cpp @@ -894,7 +894,7 @@ DWORD Camera::UpdateExternalControl (ExternalCameraControl *ecc) if (ECC->clbkPoll (&data)) { go.phi = data.yaw; go.tht = data.pitch; - } + } } } else { // track mode if (cmode & CAMMODE_TRACK) { @@ -1461,7 +1461,7 @@ bool Camera::Read (ifstream &ifs) extmode = CAMERA_TARGETFROMOBJECT; else if (!_stricmp (ctrackmode, "Ground") && (dirref = g_psys->GetObj (cdirref, true))) extmode = CAMERA_GROUNDOBSERVER; - else + else extmode = CAMERA_TARGETRELATIVE; } return true; @@ -1580,7 +1580,7 @@ CameraMode *CameraMode::Create (char *str) } else { cm = new CameraMode_Cockpit; TRACENEW } - + if (!(pc = strtok (NULL, ":")) || !(cm->target = (OBJHANDLE)g_psys->GetObj (trim_string (pc), true))) { delete cm; return 0; @@ -1635,7 +1635,7 @@ void CameraMode_Cockpit::Init (char *str) cmode = CM_CURRENT; str += 7; } - + } void CameraMode_Cockpit::GetDescr (char *str, int len) @@ -1685,7 +1685,7 @@ void CameraMode_Track::Init (char *str) void CameraMode_Track::Store (char *str) { static const char *tmstr[6] = {"CURRENT","RELATIVE", "ABSDIR", "GLOBAL", "TARGETTOREF", "TARGETFROMREF"}; - sprintf (str, "Track:%s%:%0.2f:%s %0.3f %0.3f %0.3f", + sprintf (str, "Track:%s%:%0.2f:%s %0.3f %0.3f %0.3f", target ? ((Body*)target)->Name() : "-", fov, tmstr[tmode], reldist, phi, theta); if (tmode == TM_TARGETTOREF || tmode == TM_TARGETFROMREF) { diff --git a/Src/Orbiter/Camera.h b/Src/Orbiter/Camera.h index 14c035e67..df3b0d716 100644 --- a/Src/Orbiter/Camera.h +++ b/Src/Orbiter/Camera.h @@ -58,7 +58,7 @@ class Camera { public: Camera (double _nearplane = 1.0, double _farplane = 1e8); // Create a camera with given y-aperture [rad] and viewing fustrum limits - + ~Camera(); void SetCMode (const CameraMode *cm); @@ -75,7 +75,7 @@ class Camera { inline bool IsExternal () const { return external_view; } inline bool IsInternal () const { return !external_view; } - + bool IsCockpitForward () const; // Return true if we are in cockpit mode and the camera points forward (+z) @@ -177,7 +177,7 @@ class Camera { void Drag (const Vector &gshift); // Displace camera by 'gshift' (global coords) from its - // 'natural' position. The camera will automatically + // 'natural' position. The camera will automatically // gradually move back (external camera mode only) void GroundObserverShift (double dx, double dz, double dh); @@ -406,4 +406,4 @@ class Camera { }; -#endif // !__CAMERA_H +#endif // !__CAMERA_H \ No newline at end of file diff --git a/Src/Orbiter/Config.cpp b/Src/Orbiter/Config.cpp index 01cd34ba2..9758c63ba 100644 --- a/Src/Orbiter/Config.cpp +++ b/Src/Orbiter/Config.cpp @@ -344,7 +344,7 @@ bool GetItemString (istream &is, const char *label, char *val) while (is.getline (cbuf, 512)) { cl = trim_string(cbuf); if (!_stricmp(cl, "END_PARSE")) return false; - + for (i = 0; cl[i] && cl[i] != '='; i++); cv = (cl[i] ? cl+(i+1) : cl+i); for (cl[i--] = '\0'; i >= 0 && (cl[i] == ' ' || cl[i] == '\t'); i--) @@ -976,7 +976,7 @@ BOOL Config::Write (const char *fname) const ofs << "LPadRect = " << rLaunchpad.left << ' ' << rLaunchpad.top << ' ' << rLaunchpad.right << ' ' << rLaunchpad.bottom << '\n'; - if (strcmp (CfgDirPrm.ConfigDir, CfgDirPrm_default.ConfigDir) || + if (strcmp (CfgDirPrm.ConfigDir, CfgDirPrm_default.ConfigDir) || strcmp (CfgDirPrm.MeshDir, CfgDirPrm_default.MeshDir) || strcmp (CfgDirPrm.TextureDir, CfgDirPrm_default.TextureDir) || strcmp (CfgDirPrm.HightexDir, CfgDirPrm_default.HightexDir) || @@ -1618,4 +1618,4 @@ GDIResources::~GDIResources () DeleteObject (dlgF1r); DeleteObject (dlgF1i); DeleteObject (dlgF2); -} +} \ No newline at end of file diff --git a/Src/Orbiter/Config.h b/Src/Orbiter/Config.h index ee7efd5cc..ebfec9a0f 100644 --- a/Src/Orbiter/Config.h +++ b/Src/Orbiter/Config.h @@ -316,7 +316,7 @@ bool GetItemVector (std::istream &is, const char *label, Vector &val); bool GetItemVECTOR (std::istream &is, const char *label, VECTOR3 &val); bool FindLine (std::istream &is, const char *line); -// scans stream 'is' from beginning for a line beginning with 'line' +// scans stream 'is' from beginning for a line beginning with 'line' // and leaves file pointer on the beginning of the next line // return value is false if line is not found @@ -491,4 +491,4 @@ GDIResources *g_gdires = 0; extern GDIResources *g_gdires; #endif -#endif // !__CONFIG_H +#endif // !__CONFIG_H \ No newline at end of file diff --git a/Src/Orbiter/Defpanel.cpp b/Src/Orbiter/Defpanel.cpp index e1c63413c..7e331f381 100644 --- a/Src/Orbiter/Defpanel.cpp +++ b/Src/Orbiter/Defpanel.cpp @@ -91,7 +91,7 @@ DefaultPanel::DefaultPanel (Pane *_pane, int cidx): pane(_pane) rcsmode = -1; rcsdispmode = 1; - + mfdFont = NULL; mfdPen = NULL; @@ -248,7 +248,7 @@ void DefaultPanel::SetGeometry () Idx[i*6+j] = i*4+idx[j]; } navgrp = mesh.AddGroup (Vtx, nVtx, Idx, nIdx, 0, 0); - + // engine status display Vtx = new NTVERTEX[nVtx = 27*4]; Idx = new WORD[nIdx = 27*6]; diff --git a/Src/Orbiter/Defpanel.h b/Src/Orbiter/Defpanel.h index 1b55a202f..465584840 100644 --- a/Src/Orbiter/Defpanel.h +++ b/Src/Orbiter/Defpanel.h @@ -104,4 +104,4 @@ class DefaultPanel { char engstat_str[4][8]; // status strings for engine display block }; -#endif // !__DEFPANEL_H +#endif // !__DEFPANEL_H \ No newline at end of file diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index 3b51ebdd6..a9812d3be 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -410,7 +410,7 @@ DWORD WINAPI DlgThreadProc (void *data) // ==================================================================== // End tread management // ==================================================================== -// +// // ==================================================================== // ImGui // ==================================================================== @@ -422,7 +422,7 @@ const ImWchar* GetGlyphRangesOrbiter() static const ImWchar ranges[] = { 0x0020, 0x00FF, // Basic Latin + Latin Supplement - 0x00A0, 0x02D9, // Polish characters + 0x00A0, 0x02D9, // Polish characters 0x0393, 0x03C2, // Greek characters 0x221A, 0x221A, // √ 0x222B, 0x222B, // ∫ @@ -563,7 +563,7 @@ void ImGuiDialog::Display() { if (!active) OnClose(); } -/* +/* Notification handling, borrowed heavily from https://github.com/patrickcjk/imgui-notify Added: - permanent discardable notifications @@ -670,7 +670,7 @@ struct Notification } else if(elapsed > FADE_TIME + duration) { // disappearing color.w = 1.0f - (elapsed - FADE_TIME - duration) / FADE_TIME; } else { // steady - color.w = 1.0; + color.w = 1.0; } if(h < height) { diff --git a/Src/Orbiter/DlgMgr.h b/Src/Orbiter/DlgMgr.h index 68edc3d89..43bd9ee71 100644 --- a/Src/Orbiter/DlgMgr.h +++ b/Src/Orbiter/DlgMgr.h @@ -235,4 +235,4 @@ class DialogManager : public oapi::ImCtxBase { INT_PTR OrbiterDefDialogProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -#endif // !__DLGMGR_H +#endif // !__DLGMGR_H \ No newline at end of file diff --git a/Src/Orbiter/GraphicsAPI.cpp b/Src/Orbiter/GraphicsAPI.cpp index 8455d9271..89d044c99 100644 --- a/Src/Orbiter/GraphicsAPI.cpp +++ b/Src/Orbiter/GraphicsAPI.cpp @@ -66,7 +66,7 @@ GraphicsClient::GraphicsClient (HINSTANCE hInstance): Module (hInstance) ); if (hr != S_OK) m_pIWICFactory = NULL; - + } // ====================================================================== @@ -427,7 +427,7 @@ HBITMAP ReadImageFromDecoder (IWICImagingFactory *m_pIWICFactory, IWICBitmapDeco HBITMAP GraphicsClient::ReadImageFromMemory (BYTE *pBuf, DWORD nBuf, UINT w, UINT h) { IWICBitmapDecoder *piDecoder = NULL; - + IWICStream *piStream; m_pIWICFactory->CreateStream(&piStream); piStream->InitializeFromMemory(pBuf,nBuf); diff --git a/Src/Orbiter/MenuInfoBar.cpp b/Src/Orbiter/MenuInfoBar.cpp index 1f075589d..9bc272e67 100644 --- a/Src/Orbiter/MenuInfoBar.cpp +++ b/Src/Orbiter/MenuInfoBar.cpp @@ -583,7 +583,7 @@ void MenuInfoBar::Update (double t) case CAMERA_GLOBALFRAME: strcpy (cbuf, "track (global frame)"); break; case CAMERA_TARGETTOOBJECT: strcpy (cbuf, "target to "); strcat (cbuf, g_camera->GetDirRef()->Name()); break; case CAMERA_TARGETFROMOBJECT: strcpy (cbuf, "target from "); strcat (cbuf, g_camera->GetDirRef()->Name()); break; - case CAMERA_GROUNDOBSERVER: + case CAMERA_GROUNDOBSERVER: strcpy (cbuf, "ground "); strcat (cbuf, g_camera->GroundObserver_TargetLock() ? "(tgt-lock)" : "(free)"); break; diff --git a/Src/Orbiter/MenuInfoBar.h b/Src/Orbiter/MenuInfoBar.h index a8e888e91..4cc288146 100644 --- a/Src/Orbiter/MenuInfoBar.h +++ b/Src/Orbiter/MenuInfoBar.h @@ -87,4 +87,4 @@ class MenuInfoBar { MATRIX3 transf; }; -#endif // !__MENUINFOBAR_H +#endif // !__MENUINFOBAR_H \ No newline at end of file diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index ef3e8af6a..e2ecb369a 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -63,7 +63,7 @@ extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg //#define OUTPUT_TEXTURE_INFO -#define KEYDOWN(name,key) (name[key] & 0x80) +#define KEYDOWN(name,key) (name[key] & 0x80) const int MAX_TEXTURE_BUFSIZE = 8000000; // Texture manager buffer size. Should be determined from @@ -186,7 +186,7 @@ int main(int argc, char **argv) { // If we're not running from actual console, hide the window if (ConsoleManager::IsConsoleExclusive()) ConsoleManager::ShowConsole(false); - + SetEnvironmentVars(); g_pOrbiter = new Orbiter; // application instance @@ -254,10 +254,10 @@ bool Orbiter::InitializeWorld (char *name) g_camera->ResizeViewport (viewW, viewH); if (g_psys) delete g_psys; - auto outputCallback = [](const char* msg, int line, void* callbackContext) - { + auto outputCallback = [](const char* msg, int line, void* callbackContext) + { Orbiter* _this = static_cast(callbackContext); - _this->OutputLoadStatus(msg, line); + _this->OutputLoadStatus(msg, line); }; g_psys = new PlanetarySystem(name, pConfig, outputCallback, this); TRACENEW @@ -410,7 +410,7 @@ bool Orbiter::Create() hBk = CreateDialog (hInst, MAKEINTRESOURCE(IDD_DEMOBK), NULL, BkMsgProc); ShowWindow (hBk, SW_MAXIMIZE); } - + // Create the "launchpad" main dialog window m_pLaunchpad = new orbiter::LaunchpadDialog (this); TRACENEW m_pLaunchpad->Create (bStartVideoTab); @@ -438,7 +438,7 @@ bool Orbiter::Create() ActivateRoughType(); memstat = new MemStat; - + return true; } @@ -579,7 +579,7 @@ HINSTANCE Orbiter::LoadModule (const char *path, const char *name) } } - // Can't initialize DirectX in DllMain(), let's do it over here (jarmonik 28.12.2023) + // Can't initialize DirectX in DllMain(), let's do it over here (jarmonik 28.12.2023) if (hDLL) { if (register_module == gclient && gclient != NULL) { if (gclient->clbkInitialise() == false) { @@ -587,7 +587,7 @@ HINSTANCE Orbiter::LoadModule (const char *path, const char *name) RemoveGraphicsClient(gclient); FreeLibrary(hDLL); LOGOUT_ERR("Client Initialization Failed. Unloading %s", name); - hDLL = NULL; + hDLL = NULL; return NULL; } } @@ -691,7 +691,7 @@ Orbiter::CreateRenderWindow(Config *pCfg, const char* scenario) LOGOUT("**** Creating simulation session"); m_pLaunchpad->Hide(); // hide launchpad dialog while the render window is visible - + if (gclient) { if(pState->SplashScreen()) gclient->clbkSetSplashScreen(pState->SplashScreen(), pState->SplashColor()); @@ -966,7 +966,7 @@ void Orbiter::GetRenderParameters () gclient->clbkGetViewportSize (&viewW, &viewH); viewBPP = (gclient->clbkGetRenderParam (RP_COLOURDEPTH, &val) ? val:0); bFullscreen = gclient->clbkFullscreenMode(); - bUseStencil = (pConfig->CfgDevPrm.bTryStencil && + bUseStencil = (pConfig->CfgDevPrm.bTryStencil && gclient->clbkGetRenderParam (RP_STENCILDEPTH, &val) && val >= 1); } @@ -1605,7 +1605,7 @@ oapi::ScreenAnnotation *Orbiter::CreateAnnotation (bool exclusive, double size, if (!gclient) return NULL; oapi::ScreenAnnotation *sn = gclient->clbkCreateAnnotation(); if (!sn) return NULL; - + sn->SetSize (size); VECTOR3 c = { (col & 0xFF)/256.0, ((col>>8 ) & 0xFF)/256.0, @@ -2073,7 +2073,7 @@ HRESULT Orbiter::UserInput () hr = didev->GetDeviceState (sizeof(buffer), &buffer); if ((hr == DIERR_NOTACQUIRED || hr == DIERR_INPUTLOST) && SUCCEEDED (didev->Acquire())) hr = didev->GetDeviceState (sizeof(buffer), &buffer); - + // Direct input bypasses the proc loop so we skip it here if (SUCCEEDED (hr) && !io.WantCaptureKeyboard) for (i = 0; i < 256; i++) diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index b3922f124..e101bc27b 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -2197,7 +2197,7 @@ DLLEXPORT void *oapiGetDialogContext (HWND hDlg) DLLEXPORT bool oapiRegisterWindow (HINSTANCE hDLLInst, HWND hWnd, DWORD flag) { - return g_pOrbiter->RegisterWindow (hDLLInst, hWnd, flag); + return g_pOrbiter->RegisterWindow (hDLLInst, hWnd, flag); } DLLEXPORT bool oapiAddTitleButton (DWORD msgid, HBITMAP hBmp, DWORD flag) diff --git a/Src/Orbiter/Pane.cpp b/Src/Orbiter/Pane.cpp index 420301f77..41dfc8551 100644 --- a/Src/Orbiter/Pane.cpp +++ b/Src/Orbiter/Pane.cpp @@ -57,11 +57,11 @@ Pane::Pane (oapi::GraphicsClient *gclient, std::shared_ptr panel2d = 0; panel = 0; vcockpit = 0; - + if (gc) mibar = new MenuInfoBar (this); else mibar = NULL; - + i = g_pOrbiter->Cfg()->CfgInstrumentPrm.bMfdPow2; if (i == 2) { DWORD val; @@ -192,7 +192,7 @@ bool Pane::SetPanelMode (int pmode, bool force) if (pmode == panelmode && !force) return true; // nothing to do panelmode = pmode; - + Vessel::UnsetCameraMovement(); for (i = 0; i < MAXMFD; i++) { @@ -907,7 +907,7 @@ bool Pane::OpenMFD (INT_PTR id, int type, ifstream *ifs) // Try to create a new mode with this key Instrument *newinstr = 0; if (ifs || type != MFD_NONE) { - newinstr = (ifs ? + newinstr = (ifs ? Instrument::Create (*ifs, this, id, spec, g_focusobj) : Instrument::Create (type, this, id, spec, g_focusobj) ); if (!newinstr) return false; // no mode found diff --git a/Src/Orbiter/Pane.h b/Src/Orbiter/Pane.h index 1fa09bf07..272ed6b55 100644 --- a/Src/Orbiter/Pane.h +++ b/Src/Orbiter/Pane.h @@ -32,7 +32,7 @@ class Vessel; struct MFDspec { // panel MFD specs Instrument *instr; // pointer to MFD instance - int lastmode; // last MFD mode + int lastmode; // last MFD mode bool exist; // MFD present? bool active; // MFD switched on? double upDTscale; // refresh interval scale @@ -317,4 +317,4 @@ inline void Pane::DrawDefaultHUD (oapi::Sketchpad *skp) inline void Pane::RenderDefaultHUD () { if (hud) hud->RenderDefault (); } -#endif // !__PANE_H +#endif // !__PANE_H \ No newline at end of file diff --git a/Src/Orbiter/Panel.h b/Src/Orbiter/Panel.h index ba670ebe1..4bbe7bc5f 100644 --- a/Src/Orbiter/Panel.h +++ b/Src/Orbiter/Panel.h @@ -92,7 +92,7 @@ class Panel { private: inline int AreaIndex (int aid) const - { + { for (int i = 0; i < narea; i++) if (area[i]->id == aid) return i; return -1; } @@ -145,4 +145,4 @@ class Panel { } mfd[MAXMFD]; }; -#endif // !__PANEL_H +#endif // !__PANEL_H \ No newline at end of file diff --git a/Src/Orbiter/Panel2D.cpp b/Src/Orbiter/Panel2D.cpp index 6007634be..c4e7f2b8f 100644 --- a/Src/Orbiter/Panel2D.cpp +++ b/Src/Orbiter/Panel2D.cpp @@ -139,7 +139,7 @@ void Panel2D::SetActiveScale (double scale, bool force) if (shiftflag & PANEL_ATTACH_BOTTOM) y0 = max (y0, viewH-tgtH); else if (shiftflag & PANEL_ATTACH_TOP) y0 = min (y0, 0.0); - if (panelscale == 1.0) { // pixel alignment + if (panelscale == 1.0) { // pixel alignment x0 = floor(x0+0.5); y0 = floor(y0+0.5); } diff --git a/Src/Orbiter/Panel2D.h b/Src/Orbiter/Panel2D.h index a6047d055..1b7b47700 100644 --- a/Src/Orbiter/Panel2D.h +++ b/Src/Orbiter/Panel2D.h @@ -5,7 +5,7 @@ // class Panel2D // Vessel cockpit represented by 2D instrument panels // -// This replaces the 'Panel' class. It represents the panels with +// This replaces the 'Panel' class. It represents the panels with // textured 3D billboards instead of bitmap overlays // ======================================================================= @@ -168,7 +168,7 @@ class Panel2D { * \return area list index (>= 0) or -1 if area doesn't exist */ inline int AreaIndex (int aid) const - { + { for (int i = 0; i < narea; i++) if (area[i]->id == aid) return i; return -1; } @@ -241,4 +241,4 @@ class Panel2D { } mfdspec[MAXMFD]; }; -#endif // !__PANEL2D_H +#endif // !__PANEL2D_H \ No newline at end of file diff --git a/Src/Orbiter/VCockpit.h b/Src/Orbiter/VCockpit.h index 82f62acc7..e23c39d96 100644 --- a/Src/Orbiter/VCockpit.h +++ b/Src/Orbiter/VCockpit.h @@ -79,7 +79,7 @@ class VirtualCockpit { private: inline int AreaIndex (int aid) const - { + { for (int i = 0; i < narea; i++) if (area[i]->id == aid) return i; return -1; } @@ -128,4 +128,4 @@ class VirtualCockpit { int narea, nareabuf; }; -#endif // !__VCOCKPIT_H +#endif // !__VCOCKPIT_H \ No newline at end of file diff --git a/Src/Orbiter/cmdline.cpp b/Src/Orbiter/cmdline.cpp index e6a6cde83..0c30d498a 100644 --- a/Src/Orbiter/cmdline.cpp +++ b/Src/Orbiter/cmdline.cpp @@ -92,7 +92,7 @@ bool CommandLine::ParseNextOption(const char*& cmdLine, bool& groupKey, Option& else { cmdLine = endKey; // advance command line pointer } - + // Parse value, if present while (*cmdLine == ' ' || *cmdLine == '\t') cmdLine++; // skip whitespace if (*cmdLine == '\0' || *cmdLine == '-') { // end of options or next item is key: no value diff --git a/Src/Orbiter/cmdline.h b/Src/Orbiter/cmdline.h index abd47e6ca..7cb46d63b 100644 --- a/Src/Orbiter/cmdline.h +++ b/Src/Orbiter/cmdline.h @@ -90,4 +90,4 @@ namespace orbiter { } -#endif // !__cmdline_h +#endif // !__cmdline_h \ No newline at end of file From fbe2312e6f6372c019e2924a6b7a9ba713bf501a Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Mon, 24 Feb 2025 22:46:58 -0600 Subject: [PATCH 34/51] Revert irrelevant changes --- Extern/imgui/CMakeLists.txt | 4 +- Extern/imgui/Inter-Bold.ttf | Bin 420428 -> 0 bytes Extern/imgui/Inter-BoldItalic.ttf | Bin 425296 -> 0 bytes Extern/imgui/Inter-Italic.ttf | Bin 417388 -> 0 bytes Extern/imgui/Inter-Regular.ttf | Bin 411640 -> 0 bytes Extern/imgui/License-Inter.txt | 92 ------------- OVP/D3D9Client/D3D9Config.h | 16 +-- OVP/D3D9Client/DebugControls.cpp | 27 ++-- Orbitersdk/include/GraphicsAPI.h | 68 +--------- Orbitersdk/include/imgui_extras.h | 1 - Src/Orbiter/Config.cpp | 8 +- Src/Orbiter/Config.h | 13 +- Src/Orbiter/DlgMgr.cpp | 216 +++++++++++++++++++----------- Src/Orbiter/DlgMgr.h | 13 +- Src/Orbiter/GraphicsAPI.cpp | 212 ++--------------------------- Src/Orbiter/Orbiter.cpp | 9 +- 16 files changed, 186 insertions(+), 493 deletions(-) delete mode 100644 Extern/imgui/Inter-Bold.ttf delete mode 100644 Extern/imgui/Inter-BoldItalic.ttf delete mode 100644 Extern/imgui/Inter-Italic.ttf delete mode 100644 Extern/imgui/Inter-Regular.ttf delete mode 100644 Extern/imgui/License-Inter.txt diff --git a/Extern/imgui/CMakeLists.txt b/Extern/imgui/CMakeLists.txt index fe7b6f581..84b5b14c0 100644 --- a/Extern/imgui/CMakeLists.txt +++ b/Extern/imgui/CMakeLists.txt @@ -11,10 +11,10 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(imgui) -install(FILES Inter-Regular.ttf Inter-Italic.ttf Inter-Bold.ttf Inter-BoldItalic.ttf fa-solid-900.ttf ${imgui_SOURCE_DIR}/misc/fonts/Cousine-Regular.ttf +install(FILES ${imgui_SOURCE_DIR}/misc/fonts/Roboto-Medium.ttf fa-solid-900.ttf ${imgui_SOURCE_DIR}/misc/fonts/Cousine-Regular.ttf DESTINATION ${ORBITER_INSTALL_ROOT_DIR} ) -file(COPY Inter-Regular.ttf Inter-Italic.ttf Inter-Bold.ttf Inter-BoldItalic.ttf ${imgui_SOURCE_DIR}/misc/fonts/Cousine-Regular.ttf fa-solid-900.ttf DESTINATION ${ORBITER_BINARY_ROOT_DIR}) +file(COPY ${imgui_SOURCE_DIR}/misc/fonts/Roboto-Medium.ttf fa-solid-900.ttf ${imgui_SOURCE_DIR}/misc/fonts/Cousine-Regular.ttf DESTINATION ${ORBITER_BINARY_ROOT_DIR}) install(FILES ${imgui_SOURCE_DIR}/imgui.h ${imgui_SOURCE_DIR}/imconfig.h DESTINATION ${ORBITER_INSTALL_SDK_DIR}/include diff --git a/Extern/imgui/Inter-Bold.ttf b/Extern/imgui/Inter-Bold.ttf deleted file mode 100644 index 9fb9b751e5b2441054f6eef670da7b3f53a3505a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 420428 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 45vPrwCj8&%8F=IDq-RRM%sJ98 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%0DY`M)Qr`l&P4xA(#~86%K*Qbq?=_zDqz#B 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Ç!=ES%%+1Xl6glRJU4cVulS<;E%t^t)E;aa-tlV{nG?~3SX-HOQ z_Z!l^P0M|Z$3!&>@5LO3h>OLAfPa86QHQ?|@l}kUn2-%JnQob0LOaj%m0PcAc|zzm zMd&P`y99M<39(CD_h0yV~o^_3})TM^(_#T600dQr4f1eJrUaf+beczFXQoRG>SzaQn! z_~7C%NG|^MZ9GSGf%ie@Hkd}DON07~*h8=L)~?Qfg?5SFqqh+Z<||Z}8_&Z1(C)hG z)AxA{Lhn;KN`1-@TzQ|9Z|xKMA9B-SHu+cEGXeCQ&E>zTPT-^P#j66(_ixKvQ`v5Q z{~(^fgTEt!-hs1l(r$i-UI(7{iMaw^%aFT7G5>MI0wdFd&f%8(KGrL3dTO6!^{p?@-thg4k74o-_{S<6&+d!RukwjB~)=jLe`wr`69u#wSl&F>K|k?2JS9F==dYBj~A) z-p#2Rl%`1c%K@VwU$mJ?J)X+GtbM=joYu0y_QBMPKVNM6F!L`g`}B^lSBOs;UfDYD z!^0h<{)dkIZSDiRq@7o09$`7}x{;adp7RFlyl?iE?b411r+@e$FrS}CL^+E-$a;b& z&&pJi$5cqd2=XU^%wB3xB+wJSGyHtfP#2YqhDeghAh_siCWBnYB^aFM{2}Z7;^?Q# zE|fj{6DwvfrufE(6g4GM!V7ur=}&C_G4IoZ_kDt(GLiO@`cI4@2$UPqAu#^}!_2UU zDiAObFyLc?L})KHs>BE#A_Ny`cJ0+&UxK9MXg3;<_~spx=)0aBWY2z}kL&TW=YD$G zt!*28@fUF$4bK_UkA~NBN*Z!~h%`*P_G8{>2k!f{1mo<3aUus4(snFmBY_&jaSLO> zL@YWNt?Z>H0v4oHj4?I_4I>>^48`g+V^d_1Nhkw=1kLqOVGcToJ`#rR=+iTvg@2x@ zU6!A5f1m#8<@nr-J#7nCZJYe$yrcnSAk=i_@eH82Tmm_ZgqR8sGD&T-(AGH1usNPTF$Y zhJI>_dk*lhiYD;Qdo+Q&H_`+)-rY66Hk3Il zMu?TVf<)I96h8#6&f}%2q6D@qDYQVJL^dceDBc<0vxnViKx7oMI>|d=2qiU4cNlQr z0lDhh;vmv^ArUY~2i1-W0cz*4A*|E-muo_T_s(za7;@h?>oST5nv6;LF%x@F>FyWu z_Kpql2yrz*VRv3B$k{w;fu;7R$t-)FubYXar*u}r`NCJw-2Y+nVcuQ zCg|sCwXemxRvTgd1L#{K1BSxl`+^$7pDjb&{V9seQsU^kc{W?eudmgHavqULJOVsm zwkWp#q{r{H{zNnrRwbUojhc$Zl29S=XZLuC+$(GKHle~t(8qR(i%^}e*-p1$(6 zOX><5hYZgw`uafp8-Eu2o}U$^3V)>Eo_e~(|EzpmQ^k!p^CrQFaiOLN+Sqts@5@QN zugkdJ44hAtF?YPveo_{(@e|*W84fYy8|HZ*{M>_fi}Ey-n=A{@&|tJav50 zhF}SpH3_3`X`|QQrG9uE9NOq-yR}~{XcbDcf!bi4yq|ry^h5OUXTu!K1w0LLG@jbJ z<|ag#(Ae8*>mr``L-eQbb=1~^PY%h05Y7imh$1i`hf9zfKs!M^iAOsWkR{sb;n?F5 zR;!6Pbq?rJP>g7Uf=@)q;Luf3B)%{w`(r4=7LLBP&)&%q7~iWTn*|{Dij5D|9$V=7p=S>kdiM?9JD>MSaUqb^ z1jGgE?`nTteO0*Bc6}3X|0mBFPT`XYP4K;C!VVBe-ex;EI~&N2EODMxauwVGi3SAX zs4!b_pudHu`Ny$10`X00{_O-iuROUtY`98E>K-F@6YnJn+e&jyZun*^+>TKmBxPVn))r~NhW+~en}k>`_lo(b+JZZlN2Tw4h9*)wAAc0*pY2t&qz zFa{+9V-82$7^tZcjuu_OYZOc-F5tzLB9*}_;DH=Pplvvbc#xTVNW_CYk%J+Ubqml; zbb19m1EA`VBVF!4ekS{AQ=U4L5blp;xonl7axg?6fJRXZTP;gUNwq>CYWFQ zV&A@fv$cNg@!9+KiPbn;R)?vf4C5oY4n7bch{qnmZj#{Zs|$8OT3wSx6G9O$j^az9q?F}LaHJAJ1j~ojPy|TZgX^EfT zgr*i>qv0P-&GpHJuT=ym_q*Jro8&f60YMSJ`U@~EFp1YYBh9qc46$)ih9 z>JJw_T!>Ht0jMPdXOb|;8o&@(OKQId_*2cV z6YO#QNBugd$w=M5>Fff)gv#3y1(=ffdASyX1u7AoKZ?hBZ=auZU z_j^oEPjAY7UyE6(nXh%5n36KF+cowxh6q_^5NZMq#JYu1c0Q!sc6IF#oq>r9^f-NpE$*LM6IwpYP!BeRRfqS_w%v9ptL(gZp6?nRmfvXHMC4#ctoQ zWsMfVhFN$0wCfmCw?6k^+00L#e1;HIw;{d-eZwRq=g}F=WLie;KfSVH7q|#zIfW;R zm;@6MUe(AwKUC2We-*z-E27-phKnymy1O;OuBZuz-3xiY+90YsDp-XMc`ko5S<2Z! zN+y%VV)QO_fz3@6Q^*K{Hr7z9Yz%{CAw!~|WR_tPT?{c(6~9~@o;qMhndtW)cMtZ4 zwrm-T)#kO7Be+A<{#m}Ig#E?6pyiA%y1eMh;39ZnPPRy9QWEeJvyxNv{)=o)oGSE)kCv9^TED3jOiKB#^;tc*b|heBC4j& zobI?m3+cQmRnleB1-SpdJOSpWLevBz=c*pq97qtWg(%I^AVo`3iq}}JU(E4d)QgqE zSQYMYDn=5tprjyxG2P~M0z#a5?2@TdN_cq8yY_mE)fkiKVq^c{zE4`*!MXdOrWS81 zD%w;mZojqK>bN`X=+?B+GiNwW;J18uop3DtPsVwQNotNqo{Xt*v`(*v$ zk3t_d&uf}+UsLw{)w52y4i#!Y)n@0JjH9x%^NglZ9zuI$vunhpnmtdAU3Bu!(cQNk zVt**j&Mu`tK9B4068RFtWKvSO-hb*uPqX1IqnL=707*OFo?BSEG#Xe@F~#%nCD^dS>!iM0OBIV!O)0oOoWG1 z(0|*r*V`dZjc_zGy-TOWc*4``>uUy{!k5iG*&<4W@bZMZU)!a^-{#5AA4EnyEA|Lh>WNKFQgRTJuV=;dgJCp;b~fF z|7jh|%MHfVVMA9*$G`n}`(GBaIySEOZ*0P=>sI71E)Pv;K2$R5aNlLMThCqC!s6K< zqC@+}B@e8`^u_>QCqUEVg%pY)iwngb1ib)0V`ZAX(QP_aufwWhLne1{2D|t&k;Rni z5mKlWSd8w`$!V*PVgS!kJkCTIUE~u%@%^1)3ECIWt$AW_Xx3}lp_A{Nv^6aJl|P4x ze$yXr+_OEpw>@9`Q%`HxzCFfTq@X6r_kdr3yy>HFXS{wlE7C43+r56%&IFe5e&F;y zL!WT&bX>^t7x@0ngDqnN@R>4CKxYu9s$x1S6iQWTHXA`#Ap2nb5 zI&k{3_L=tPg6T8ov1}Il+SvmKrad+BnYWJZVLsYVdyl;JT>Xtb8ei?Q$KKmfGamu>r6FsSS2v z4j0~TXaci^1-IjbxcE%K#DM*op;vQ6=rj3;$vZ)ndkcSMF2 zMQ+{_)m@x)<%#Nm@Wn_ z6!&W48GLQyepTYemSk(+v%$r-f8(g&GF93$E5y={#^YjPi>ip^~e9 zA{L4JyVH2&9k(ukL?Y`Mk+1!SOx?p0o0gwAWf0J0yXiWhO)o0^l0t%!xwwm zR3tqgVj0oe<+>GRL2ON=HqTsp@DOS#xwieV@zAgh6$kFtbxYL!QcAgQnS-$z%#D;X z26-wCbVB6Uhk34-@$32EAEWs7de8NB{5sB36btxuh^^2u8Yw;j{S3hMCk-{w!|1xf z{BP}ReqBEc7WPqo7VP!+(%ED4s2}}|F^mVs81zHeH(fvTOnm{vr|bExS5+H-?@8W& zqc{?uto0i$5OwG87JP+@N7QizXH8&2URe#H2cUXXNlFkw6Op_I#X%H?M8aN&W{6q2 z=>`fL0-5p|T#$tO#re`3>g$M$Kouuu8StB-L3sOZrkqG{!-8`x@~;WgCXLGD5B!wi3|0-00gMu+%E7;&pgnM;Mk@%i$XcF zQ;Yh-v}I6}b!Sb&KFfV`;9L&8)l?1lo|*r*b$RHQr@*azcx z^oh1buR1@zVSDeW(Bx~&>!wDC+9okF--k^RBYIbjoe?F@Z@hAJ<t3G_R_#siZv)P_#yIeso>yQT(c77D7QE*=`lsuB z95AZr{ZkET^n=Zf-(H=|8(RYSDVyoO0Gi<$kDa%V=fAT7ZzxhY@917wAXM{Y(&5oA zADg08zm5xu=E=Ytmv}Fo$N`EmnUOWa(@wei8|_@4c6d(uOn**-Ez0|xy8Wi-4ANQN zKlQr`>%I&0Se4HH==rUDN$u%3KhyC&Pmfo4f3TVv7wh+N9dDFT@j}1|{C&^r{ox+( zPp+Z<=)Q66E%#~sxKHm_2kY(Ca{m54AgHK2AgUth7seyBekJ_`9<7QU_tEbm(De|5 zgx}d5erV6nB3H#v&<_)OLYA>8p9{a28_o;BC}dGUWt9J#8?HwplN?&`rZ{`gre~(x zq9W3Fuek4c%4OHVpC5eU`)X%Y+$HUUC-=WGmR;U*Y~9!EkL>(v$wON=eYohb_WBz~ z-q7ASvg88{598aX?NDZLnYd?OcZ9Z(4^omr?$u^g?ZjkYL-G_N!7x2U55*wxaJ&%j ziVJc%QC$ELb=<*-QBiC(7yUy~euHS1E@_a!l%ud!m;3iSR(s*^mG(&c(=7R^{clv6 zUT1UfU-|63u*guy`n9vqW<|0;w!Fn2>X>?rrM-6SWtM(o@kjS;eQ4QN+mGG-&4w}A z57M|dV`#|;)HG2}I}R-X^@WiRdJiQ%`(SiD8HiWa!7t?eLg2%%%146(DW{z=$ndb~ zIT`E2=05S}lVb8*cg$H$kh*D-Jm=afQP|=hEfS+eeOvaOoGJBzjme%DE#fr-j^;u{ zQzhgUk|ZToj$p3>}z$9&QH>l`{{7moKSn+CIT~DCg8COP4*fh<(?&GPhS{ z$B{d$t9MfWsExK>oT>g1)J8pn(5v*0hJ+v&;e7YZdET&l33Z(i?SojY|*awYnj%-y=? zWM-s0Ao52>_(GEbtYQEw7<(ld&=Jf6GdBk?R7WA~mH;hvbBK z1oQI$0s<*%$BD{oa2*+3RMNyn*m`~x4*9Z#&x;mq z8&wmzI(O9}t>5wSL#rd|B3E}?ezh-v9oTEqQ6wG#KE-09_|KJ?`(&59nRCB|XBXbLgm0+C@xjzy&v_61y$`E%= zm8(hl6xa#^>>Sud>0|}$BOcuEVp$)aVGGuOdU}~z`$hYbJ*)L%5gmCyr!|ArQ!LT( z1yVg>GZYgSlX_}nE-gK%ecdS8MdtpyR#V98v^^!#f9N^klDrr8Tsl`K^DGq}6pF8J z7s6v!MZwDfXeqEt{1j^Gsq)H46XN)uK^}6PjL`J>47+SoOV(;HJ^7S&`hmI~Z2z~& zpr1BE-dk5&RX=Fm=B;apHa;x&WUojiWNj2`F<$-b(-N{sa$1VGbT$dnl#2UAo3E%z z(r)#2wEs#N0vVCFS6|oLLsPg@SS`OR{~2L-Hux!0;5i$ZR}4&+=nz?i$iYd;1mv#) zhfyD2R!A47B2<(SkNt}53g}OW7_J0GBXTP%h3-W_Q_#ocOi3R=u+TFk+U z>|>Js6@RMo3Nq-FGNg9)Lsq_~_v_|vFs+U1*0qn(I9l5+W{X8-+1X`-va^Q(hhNvC zmFHU52^Im~bYC9@`X~xE54UB>1$Us5u5*2ERi>ErPGLDNOYo)mJIqkd0`rI{w z#r^m%HfrXesoE4Ry8qJQWqs@F^UG!(2i~N$HcJb{=Ya?RXuYfDM;#AZe)Qmh*!r>- zt)5n`7(|UYgJx*Qu3ptXsaV|mQD(Ve zhK3(l*|I@{^2gN_4H~v|0N)ENLR*QtVURzSe>4a*bD`ndueuHY+OK@(OgJHiD>c$; zU_bI*QIub#S|~_6!SWNmMXV4AG%+RGxROxrOmOnTCJgbkl$S;dgo_Y32Gwq}6=%;L zXPXA!y<~CUAq#qD_B-BCzIxH3qP~lzm?cSLa?5fvl2>*ZN}pKW))QFw2eIz{6!)yJ zdoe9GDl_4O8&m|!Z_&MhwD1Zl^xOcecV1#q=Tn+$v={$zReN$;UF9dN!>saU1Iqf2 zt0^2*z7z@t!+FHBr7xuyF-OQFxAHVh*2AtCH;M>S1u-OkXsjd*)|rQXer_9+aI|M0 z(renbd7F~&O@3wgTUu-Qubby>?6|qZt3zLHVQ-(G_{a}GJTme8#?uoXzUDqX;WTh@ zlxCOC8%|?gHesO*$|lx{)2<{jS$tD`1D3WeJBZfZ@EiX9Dy>GMok?dab|o!5uQNB| zV4-m2FF~vVAKqPw?2((#!X`DFQKB*(uoxN9GB!ebh5prAA9#SV2Ohwpzbm{geXN{7 zT#23bJe*G`rvxF0$Q=ZpHW8%`=)s1#Y%VM12|)5;l&h#)ugD^VBPBynnT7QEZ0MO{ zP|F+I#ALH9Tb5Risk+#f^4~ebr z?_;!WJySwDhXvVsVB%OySR>>Qm0s`{0cV0xz>e2}G~bNO2-y3jMaYr`V@0&?olXXqiX*_-SvN+(5^6Zjg+MAIMIAUyTmr& zgH1ZJ^cc*ila3+w24^3Rl(vYaB%do!4#AjO-_xqtfYyruke>Sl_KN{z@DL#6R#+vY zts_N)umNW;{ySgW%W7~N&wU2F)hxLOtQN>Fq&jNRwCe=QiuP2U<%UHbrjbH6fyg!| zy0;xPL<-`-UF4#;5c?ivSB+5}T`2yE=wckS1#cKWxbBZ|G6!R+b<4_vwKyEw{MQlf^@HUr1|KM0HT2MiZ|_OE=i3c5P9dgssTz&>I{7(TAqXGQ z(>pQR+Y>$tbo2LvW6a5%ippJ<9{ZsU_FftcFauPBd&!)VMPiw2*9Q7lE-%S%%u~~^ zT*Z-2Vb;l|^;rXbt^Kx)D|_6xX5-PtYbO=mS=_rm$4{}Z|NA`?&lfeMEH9pLsQ%ji z{)=j$4130E_)5)3R405U@c}f#fi9H)F2U-EAY|AjKxGPn6l-xoEKfjfc`jvBo~`%D zH4Ib1ux_}JV2Gnp3}1V<)wgm*Nq$2gHEny#L!0%B?S}und>`9FBWfG3wEkerx*M*@ z$G_0WdqwOgJ)zhkzq$C1j)L0&+YP%IiD`hYI0x;Ff-%@CgSYYxjIBjrWbE#TAE`FP z{O61|M(iiPuk|c0X3x1@dcQlwq0&=I1|)Fxj8TL<7ld7}7;Nwr=IjcQEU}usq>vqo zau1iJ4GUTF862{6{1MiHs$5OLvui!inz$_J!cz%3u7n&W%@w7VAEVh{i~DLLV#MRp z1{SEj^T_ca>&Y|PyZXE9FsDB4=fsJ+zB7?w0KrtBlQsDIoDd2}LaMm2UXA_f5w`E1 zQ(`~%hyMLhqV;|6oK_3R#ol5xs9!n3YQV$3*fU{RPbN;s+Vh|R3T^+_A2wR$XpNnm{=bpd*6$3@gtoswu*!tN2VvT~lYqV;~ z!v0F|(S_Py-Jc-m?t{*qS%T(5pCST@|H6&}EA4#U;XY}b0B*CvC==vaaPk&LvggCJ zZtN(W!AzJXYyqd}44Jh~heHtHV25u4)Bsjk0tX2ofCoMVRs*6furj1tQxgT|SU}}A z4Rk++H~)mvA9a2~g--PfuhJ zfLZ%H3qgf7l5f9~H%U)IW%>WiPpSBav@O)#5GFnu=AIO;M6F%>w>4`3`_{*>?ibqQ z4wbYZ4-7_)!87LF3vK%w-XJ7mV?Xp~vE%MqSfm6W=eXly37tD@AE3`G?vF)N>*IWH zD+1|i38+Akz_&MhLW_k6C)xwGQz&iJ+5PdQL6)ay%=Gb@Lb%*|!TmA&+ViZwx19z> z-`fhq*(UB!f>~K=7wx?O)W|tvzBFTskI&2*(4`=MY;|8{$6C)q*9#ZAajd0k;@E8x z)#^ZtN|K6scm!V!j(kEXx#{{hR$nTVD%Zku&@Ci z!xpBemm7__scGd#Q+M~(6;-_^_FP`odt%QS`KhVB`*ca^3qHJC_*uLtM!~G`s!-FS zdSrT4#~Iw8D_@l~#6u#&FPHdsi6TlrO!&D8@D_p-ms4?5Bw((*O#?_NP;$@5#RWQfeQ27vaGBX7uWkm7JVsTob%wY}fupnaKqQe5bFBOo;5&MV-E`bC+I(FsI~2Vl(V# ziZDpu_f!GU1}1S60YpiLLCi=&3pr|os3_^euOfQ82iE$cE<+06Szb46x*s^c;AxSy$?%09rtfg0`>P1G;X?aoA)soUmOxUnDmp4ZSEs4`tcrZ5!PU@=48dK zM{k-RUPDLG0kgQyDT16~S|DekG)7pNZn|-s_epfNjiDxQNAj=Xc*n|L^msga-!#0> za05K~_+fAcCc^+P@b?M&`v6x+b~oM7-^aO$7oL({5XMjw_H**iWD)PY=NHdAU)Q>c z=UVT-iHC8PCBTJty>r4WOwy)vv-Yp$cW%eSY#>7j;0`*F$nH$o-Q7K;d;OPRYWJ~m zfbFZAQ(VPiTXr3H!gR+S0E!n^;6oH@@J*oia?jnZcWwh+XcI7eimQU%m3g~5Y5SYm zO6^yy4dmj1;#a~E(Cm78=ULcOxHe5_8w24>LP>8z7H})lGQq8&bzuM!4Iql7GqNEv z@T!|{>$8VggsR3=U4d^egTv+o@l?dGLfqfHc={TvJ*|CR*!(YslXVeM!-P7>58)zF z`=L4vNPYR@qNT$3){T)(#@zkHuAC1o-r1SnsAuWBLkwrm2&4Y5`cBb)jb#$*DEvBz zMIMsAL*G08Z~DIaW)mNG6ZI{wI3%t@-~W_XNEUS=WGwXzYHWeWx^l=|Y@?$)SpKl% zb7#*#JmT2=dGq8|6Smyjuw~=8&08C`0_HgPiPei8B?EL+ASTw^j*2+o`9auT$j8O^ zN@`Y%x3Ka=n^(+}auR}r+d}Zj0GQ}9hOqhJ1AG$9s=cqhc#y*=x^@@(+I+@OFpGQq zd<&=aq(wT4+6D)e3y6O})-0Whiu@z8OoA^pV>7|J0fh&+#?${ra{d*@l?o>9a%EG@7_Q0SzDL=*|76CkMJa3%0h42Z0yJU|g#l2KXd zP?+#xaHWHk;F{)#SmdbAoOA@r;7Cfzd*UAAWVqHyRwps+@CHS7KeOGH+`0YQ&HR}s7`N@N$$X?s7^&W+eJd~EzK@s)x9y05ZN z^-Nj_K}9V6Rbd_QAI58n9S8#%(3uXLF=XiEB!Ll0u+c5zIyc?9fg-3l%@`z+$f7#% zbh^|#?NkYD39rJokf>$ycfQoBDa*lI6NK+{JtjqWk?W^adU9W(FU%HEvy#@*ZQzC81Z3v(uyudCcuxnU?fx>ftfz1nje zHzDv)EgG9F90NB%%f9A=8G0!*vR1Eou4ciyFGJN$&Avq)qZ|CGfHQ>H%eV2T3!@;&g@Yz z`}sTP{c(0dk6A-Y7M2cNRH8k+8+)VxwEuJ1Sjg5MDbRUw3IacPRIh}H4-B;t^B93( zChl{DsU7p?EHIsBae~{T{N`C$z zAM=!!743dd34u4O^7E_cPg1!)|VNIz!{*;^U}pFjqpohQ*AG zoNUzk;}&P+fT^kt$$dFQ4!EIFI}lOPW7u%B&&D~ms{in6zr{Z5$5-EBO_Wu`8YYI- zX2Puoj+$ zp$IdwjRLDs)0&8|)_?hoP&w+z_(fI0Ms2&A+dHEuy1Qfgfv=dUQ_u18zWb&Huf6wy znJEPWoc5xGA~rVVv9ymJ8HvkdU@1GfIpbU~CG zj`WYbQ5PiK^uogvnxwNMFafRGoI69rkRx;E&c(;EaRsG*q9v^_efVX_`*tn%U3}kt z_-EIYs)4@cqpM4O%ZaZF%v}Loov&UI0=;rQVQ3hvAYefdWiWg_N)37)k5UUqbs}6N zGYPmR%1wY#*P)d#r1HEq(224{UR#KchD6q}b`-km)Xv0?>^^)%NcPIEJ_%{%u0AVA zO_YC(Pnvue>!+R1@6nsBa=(W$5k5`e`{zztA>H2V0{S3Rcm}WuJAEQ1)jxRp{&{82u5|^${c1ZoGe%?r4+=1^lZF?8c~Qds`phU= z!eT<~L@<*T7y)nwVPyLYa41mCVQS_8A>e{5-%dzlAlU#P5Dp|HQgIy{Q>QkP=Y$c@ z)}xe%wzk-Gq;BWgD2ohJkFrLQTL8F5S!6fwJsYi?OAmx2B2G}yd?(Zeiy`+;sOgfr zYWWN?zkA30FsH2|m$0piyzhZ|z_u(F-SSOp-jpQg8^txHz5}bUuKnfHtqqvJ)uZEZ zBm+?-)gqdtFhQP1m`4X70Idi^#X6vti0H^Dx(_+?wzv7=+?0Yu2uOA9IQ`%?lVK|5 zQQ`Edm8J9=T{%2Bb7iJECZ{whZ{>2si`pmMrY+K*W_@z|=4uNiL}9iZl1~evz`t1U zZY9rAAV`FW!!D644B940je3Y-HC(C~;b3cETyR{FlOKG}-%fr$o9?ZqA%GC8d@T5a z-x=;nu_JQk$Hb29T`?j!b9Gk8*x@dwWG&AOt}b)sEgw~{Zi!E->Xd%RV(lr`cTr(P z4FBw@EfSMx-<|?2yJL+0LMEqT$#64(L*pM%T(JZM4Xs3>5nsIOh!fzUa*8xO$pB}E zJ`z62=WXUVOPQ+|cBC3rni8pAS!6Qx)9x0N`Zy9v?)ykSCFU9?z~(bS$6T_bI}aDKYQ@M~P7LJ1OdNnzxSxo=$5F;> z`)3%$+`#%ymK5J;*=p(#JtW=Ixh}9SbTyXi4(&hXve+oAbt9PH9V>xD1gFh_(-zP- zqmatslmKbW>okDT0szxXZea=0{ubv!2ssbj?xu}tmItfLP z{}1TjN66y+cQ7M@hz!O9@gfq8E9euJb`qbs+6tp_U|^tE6Q}AfQjimIHbIis(0k#7 z?=0O@y!3(h=c!kY9mCo2-<&+jLRlcat7WzOio3OSC1Q6ybGg3ew_ERwcI&O^>rLe| zb)kBs~2{Gh; zi&O}VFg8KRf_Ps^vX)c_Wtd6Wtr7gLu;Mm1A+W>+#>H9Vcx7U~()BZNu=v`l9mno9?}+ATOx^p`bnot%t-U@zrO05ZaE%U;c74W-uAVjW zzQWv${@2B^UcGkAhmg~^$W_qV$)4XSK4zvNE1%X+hf5sb;^475wH!Z3AV*0KhI)-f zQ;iaV#Gr!&gx08v#zvD5f@mRQ(kCQRW=7=!#4^M&p=)+}YKNq_6lV%ftVH!hE*v?S z!?ztsLVgD(H%l!p4jRr?6SemSH-*Mb@23N$#t<-~+HaB1y7AM~$|l_))D-mPLd}T@ z=|zg{?C2UBEXn)&^%66SuLC77?`C0VQ>r5}u5&^(;35KFj|lt)O9g8`0=0npr#jfIpGWN;xcsSIPy0>!3qKwqw^S2g1OH%yaHK0-WwMY1dfXus;H5SJxswwZTg)@ zP6sXt=>NjdhQEsMn z>T*l(th_QGQ+iSENQ+T4jGJg%{_O0u;Y*7*Hw>QLC$@63_PjN0L_zlPt zqmx%9Atr{3sX$g(#XMr7`?Smr*CG;yd8}h5_r$c5uR6nk>bY3(Ivxe;Z+k{8&C3yxaxctv472yRcA) z9Ersw?W5B13`|v52#|j#tH^2M@-era0S;U`PS%?O4*#vK=Um>%h&J88&iJ{!9uRnr zSoG%Yd(ocG>`_(CF>9qY*mv}b0dpG-3*^qd1`LLToi-@FFu-pC#K;b|o$`?tcPuV$ z%55s^m@r^O`M?1|enTdIAC-$Oig{*2rf4+04jW-M$M}voFO2YEAh)%Xt=a3oZxbqT zRzXl;P@7O8!N6`HsR9gN%Pmbmzv-Lv+n4l^!I%Xo%nOe z<%r4Q@3Y_yWVT~-t~=Ionv_$kS-un!bIUgv;}ne1-$1#JUOPQ@B?Vz%)3*1H;0-s} z=_T#}`7S`4I&OKHVxJ-o(<1P?mRHf=`{>VC=)%X~G@{xspE92Iy8TLD#CV)wv$S<=p0-LHM(+_YSEmYJyD&h< zA<}n4sC#q`=}~_V08Cy%xHFM$%{^Om6UfAmQkB`@o0Z+`fEJd3^QSt>x3f6M*`p$Ytcdaz zxy9K_2N35F#0%GOa*8vLLY#@%{z!txemV^FK95>&n9@7^Bs4zM`h6=>V{cYzClhe!U0?g%UV>aAT zGT5X#q8+`|Ap`Bss$t!R+g}s^n$RmN9vqXovp{qDfnLW8yL5aZnv(!E2beK~M>E3_ zspF1-YD~P?xKt;=R58R;{wwi%V^LNR755vh^APGny~@q#_V-%CR&0t3OvZl{XvrrE zs8cZ!E_y*LWrtp^aHy7qEP&H7>#)67I+`Lbs}^8>c7@YNsxE6=0u_ zcNIgoGI`e?F96?X2;jW#yuH2u88ffcsOt@kzf_F zbR!5BH*M0V1WPXRxFI(2LyJ_aepzP!Jk?0pO#q|6g0oU2SKDtP^a*6bAI;@y~E>U2KF2rEC!^?NAA7T zxcqQ(LcTVumps~6DJz>C?|8TW_>ra(P)We0<$LMd);kRQASZSZxEDOH5cS6te`tAF zX>7lh;Hr=&1PI2+A=ZuWxY;fzhY3jts6@g2Fl&IH51Dq`%uBpj1`!S}{F3t9OGMRm z%nBw=Czu!iLP)Z?cD}`wm(nxa9JqH@;(+MH<#R06cO9_ir!EWj&CBX#@aZ@u$kZ(@ zd5oW7-?++dgKf6jKGS9gg?=u+GJIke_o1-3dHs9Z3n!#xXW_88UwyS_5leN7+hUW2 z9HCGcD%1*7*-CxwDapM)hDF6Hu~9Pu10XdSLJaZ@s5?@y&14InVevIfMjz&5oBHq9SAWYq-OrF#@aeRGUP1Tsul@-H> z4JjK`I-s~;Q2~w(?%4wc(lXQ2QaX3+kc1$9M{FQW0rdX>J1W6(O6K$sF>cyMPQ6aj z_%G>(U&;-?f^PVA<8wE*yzySkH`DxgxSw7!tBGGcV2z zSXx_C??1zU3R*ex>KXpa>S}BKr>OB+ncW|r=66?JeVt{R8lRJy_3MNge#>j?YVc$n zI#Pa|X`!FEYww!g&D}JO9<8xVH#jqMx@yl3ZE6~t)GJT^d1zzf(BvLHuDxG=N7GPO z?>-6oXK(3U&mH$)${QQYlX80{(xNQjR@=t!c&9vy)*t$ckzJ^chJ)ozF?5j#PMqC<$d3zCQ8%1W>?SAq?7B65NZ*J`yF0@>hDR@!{G z`B8EDwi$udY`*qLSODwRQfEG0)6AL%vFhyqT*zg`Wpco%l5Mltq4{+M>slUWH5TpE z!>m)Cc0n9iw9Y(Vtg^5n+TM@HS#}j&i^+d^oJAVR`sZu!)L`zcHgojd z8-gtr1vLPtM1tHRSOyG(NH0uPc!FYe^tvpOZEd*Zb7Pad2;2okJYvxeH&N~%-q`>d z1-uAbQ9lbJe@@0o_s7Af6Gdm>LyCRz)yXurFO{%XH)_KK3!b|}HX5(*k0`CdA zZ;hz9PkrR|`R|XzxTFx2XdqO91D&_;1EiFEt8qdc5=LWSEwu(B4uIEhiOWZ+ zSFTK$pFFhppu+BTy$Y&E&RQ|~FQk;Twz|70j@E6;Pl)?`0k9pMlH55Ga2~6I)NVBLbHv3_88Vs> zS@*&7c{MVF`jwxr-vnRN_=LcOZzICxzxD6mt7+$6Jj8_mKi=_2%mYzG@U3_~#FzzC zTORY^v55hPxbNBz4q^q)Wadv*&G_2H9L z_ZHCUO}O_JSxF!XUJz2rzT1J226_t^*hK)zf#<~QW7ShdZo)+n2H+(D z)B#Ocf}(#bK)r1cpJRbt#A3AotRAQuZwpm;jHDZ(x?t!t+uH$EyW)ZA9UhoYx?!BR z0*uC>0~O^fS>??_Bv##_}lFuOM|@yvb*_s+W{6MCOmiycwmQB zI~a6n1dTaw07(zn2^4rG!ckzPis?oW4I|YtGnqI^GoehbNi~&+gdoU0E+oz#6AhON z79R4g5haX;U>5A#Ha^{csEc!?5P+oNIH`8TL99v}Q5YWOP!|W)56&#@6-JwEHeDS(N>ZHa@kR(KtAj|0~9| z`=R^^QF@Mo)YO9Zf0S>agvno^W|FGD0NjxTP5zJcj3E}dV}~XG_Si#^haV2+8t#r$ zYkiGA5~7vL;~WI{q(n!jxK2?KA@)%Fjga^IUF>N$n;T}yY`J&Ozwb4#R57?l9d5z+bUIfop)i-FrVhuv%o*=fA zukYbxB#6O1fDb0rQZ-5J-f}-*hVxo|ZGJYmIHB8mvrm2#C)9RexdBE>h!-5*Pnrf( zLPTGXFduK;9$xD8Q9vfc2;iONZ>GFuolITFMm8g(m(e&PBa{B67o-;!rl%F*v5#SC zsRPW6f`h~CmYNQZz;?zbRHO|uI9==>oX2E4en~ttO%Y90`_A+b#%M-g8+c!y+(LrT z@8(RA=ib2RT$ZQWifyZ*ZMC#9zH9O|@Xb){P><~rV85Zn7o;JORm`5kj}W9tQp9x# zc>LhJP(S;%d~S~4a-WjI!Umt^e)SvWYXh4H7mgTFICu#%*hS$H`JniYdLO3-|2@Xc z6Z?aJNIhS?-HLnDI&aE2V!MhbXZrY#TGk(*zCNRtW@ZgH8hfW_4mX*4$_EQ(78Xq} zD41SUIJ01JNmf?B{+XE=7ZZL4UKaueW}%4IXu!i3NDh>Z!eBaq?Tm+)v04Fu0UxH! zKA1Ufx?XwK5!Zepbuls2z%HyB88_{7TcguA=dB<>4F3E^fRzx zgU4`Zu+GUzRn_=zLkg;mmg+J;%lrjeRbzB~e9V`rBjf>PmE4xdT3^xzVub_XbMfR% zKtMqtiNArLS^Mn0dS7o_*I%`*|Bb<+LmFj8rzVW? z7EKt_dvQ*9o06^rB0_GBNMJs+zC%y#25S_0lGk}ZKiA85UOCq*a9*j{YW>N2+{54zY)}CzrQlEyFq>c34vBbE^eE$3%M;>0d!ZX@>MHV^3|3LUC!Y`@_ znq&Uv3_rKSIlvC@IbiO$c00LAAfThGlzrl0v?v-nTDp)eY~B;P2#6>7^_v3Han-)m zkf#suKI|(h5)99QJbhc<+7{mBEzSMftz1TKco8D1*jYK<+tEUP!I^vhjdKO6ZuDK} z3Ih6om2^0pAa=DuIbS;W}$ox4pXmZzyVR;$O>+ea3 zn$>lzmX{HFnV&%_UJS!ibA`ytNE$`@9-l-bpuqJ%c z`oFiolZcs;fKZA-&H~gJU!GNdFJ*P-%Ow$OMrC!)$ZnRN?_M17;HaE_eX^T%_uk;@ z)uB^6m#YYqSEJm0bCju_qTJjp=ajG+cQi_El$Q~F-Ky5DyLlgP*)zXYR@W|iYwYN> zYSXnFeM$EmGC#4tHHd|iZauJ(H1yxDDhVI>cK8&FdIe(#}26Pfjbj} zovbHWlpnbWN9l!7Byib49Gw+$8WA=7e^Lla7-~!6s~O+v~KLUCf|+ zIvi?EbvSH_r=x@exI-xi`gR@ayINXneuk9@(<}nEK!BB)qzHrwX>IE%(x&Id`A?l$ z@OSO-vIRTN-|~vLS>=&WKYH@Xk3QY1#(aF`hu&E0QTAVr>^>Nw)RHiLrZl(Yrf@AF zGM^OX%7H$dR@r)D<_FPQ)LZo)t^80+czpibZ_nRkS)NZ!OAObi%rP#{9BjV%>{M+H z%+r-;&5_<;9A8oX=5{(w)#`Q;Jw}}|24lS}yh_%`X>TE2sjM5ZIo`h(UtK5cu3=&6 zy@T9sT9{XA*IqI5#xYu#j23xpM)k^Q^B!x3^AXahFC{9Ke%oz}r)p86>SkW(Ks5&t zE2`g%S*?@R^g|^h`vsRHP|0vI;L+MQ5il!MA6?7KgL8Wq4Gt=g{@Y!5FZZ@`_sZ?q z9@|tMbJ{xY>^kI%PB*Vz>#fYl@16nddAIU=?<{Ly?YeiKfAo9ghU;fOTD0ND>t|K| zG;aBdaVzf_xBSj=cPV?jLn_9SmoX`a{Jj*}YJJ3Z{~6!p>i!tN!Sr>OEruZit|FiEug zNWJRDZbE&O?3k(^X{#sN*6fs(B2USp2b-;q8=0~x_=$l7d(HBu-P?LZ=VzbqFrxKc z*$=FuoJPeaZ-V!2Yp;LK^`Ezujfe=vv{yDr)J@dlm;#qn=N4-mQy)hsHFev_nUeks zOtQWPuNOFOE2&o|-P9DHf`Q#Numt1Za3wk`c7{K2RrcVxRWIGydhNlmD3&ENi4xR7 zE(l@*Z2p=b{d|#t=smi<24*n4t>=$E^5B9ohn)+b@xJ$0+K}Eg*(kBf3|H_yBIow` z_hkF3#`-7b2BU<#%p?BonJJ9RrKs@;jSl5IHAX38VQp>WS{$0V!*<$J-e0$;mM1)L z@K1BT*wLaq|5NV==7y0g`=t)f?Jzi{{|YQ5v5))A(LvVQ`egpIpV|jpR|g=pi+3&hPU+Xx(OIGKbyk{puWd9H`!TZcLzDo>$CI%u$ZB z%r3ch|7-;(ow`*z1*m->y~wW5rjSEEggS&cfI$O*}Z0&pET+^tw&6gCNZ75q)b@Y zB)v%oibEgRYCdeVb{wFt)9pN6&bDTtWvlFKw#N)17RHR$A$<>Pm|GU8w7AWk6Cbj+zHaAZ*->o&p-{2x zv=VhFR4hBS%mr9>^g!SFu)3E3%dWPM0hV1=0aB0(No(uSZrGvKIe)UQBj)WLnyd2A zj?sVl6dFpJ!x7Zd8EM;QIpVNgBh}|RW;tM^Ik>fv-^r?d9g(!J+6Vg{xaZmTVE7+s z!Xb`k#v#|$^d6UVv}-v-4IssK)eOaPRUJ(+UKNK@lR+HVE@g>K(Q1v=ah31Kef7fY zrybATbyt}d?L9^P`tt4k<+UFe8=l$bI_piR8YPMz+0`y-TU#y!{W0F6UxzY)z_<|mI<;|1Ed)ML zgShC(DkVEtV8?(_7srL^F}3=$H{-q?A8L=fdw1xTp%%stZ7QD%>XXws)9votzH=L= zcn@pM?$65W*}8St?(N!kEy&2|lBfEh;h97pAFImaY?a4;+m#+m8g;JQstgW;hACy2 zWI&i;I!ENizG7uO$7ZG20Ikln)fz7EabzAE8tCbx)wlOJ~_i%PbcU824yIOb8!@NsA`>@rOhblj^9)}v> zKVN6sgDVb-q#8m?+28oJshCvYIJa(DFE$}Cl{wlgeT6W?FEOSb>Y*%>)74P2eD*`T zY_(bOtR6qDXFIpEO{bQc)+jomhs(*<-*7B#GI^fc(Y9NLrZtXE=xSMXYgG0h zxDVf+W5icMd_jT!;by*txJh)1#Gr;H7dEPQ`tJqlRGrw_bX6`~e?0FNt>M`6t2e30 zH*D}8-nNbSz2;$=|6h(jDgi>OhODv&wf{zaZ^GR2yVtI-mVhd8#n0Tm_nPA)W|x3G z1?NCxq!OW^k29yR9~sXZZHO&T6wpGAO0c(9K8+%*{B5h8lf8P#T`Qu>gR%zp?~hd{ zM~^NY%Wm#4e7IT^wTgYDv(8SZy*-C<-sHGxr$cSo)&?P*^GcCz>!^#%Ic_V$ZQ#^z zARx~QLDbR$B+Dp=%ay{YNcqT!H@~X9sj|&mrg6RF`_pmV4j$~*;Cte$yxnYM zHFX?=-sY$JhttG9dRwhFLu(S;)Ez<)+Z6fHmM!4HTQL4l7g5~CI*wgTakI;kTY1Rq zuQpp;`)mc%Be}%DpAuB8_R~aQ~)A3fyv4qH@>g65w{#%3B~C&s2xFX@?4cf@EoAR^YyXbLs?@|p%=r2wcN}e9Y9{q<&g|QW?IT{Ar((q& z!#k#SXrC0{DdO7DoDp4eMhs})x;Sfi{`ofX@#!s+GRJgHO-+nzsq$WFnhUJ)w*5$3 zL-?6`ior^Tm0)6HorNc+-ijDO? z-Z{h(mla+xF*JC>@ZLSbTyc%MhPazIjObMy95Ss>pB^DWP0XVO4Lc#$b>+|=6Z;NK zP3zb^(HNfL+9;I3_0n5mQA=0aSK2>KsR6wRlfkTU>@I4T&S=~) zE*1_)f|d|CBf!)0b2vD1y4X?s#H1`_w3bi)1rIbF>n0U1G=q<92lugc#z-z##^@j zdUJVR<@Y(PyD`tGR#XJumQ}_}l%C2$_86M7L`e5jWS)~B?H)VA z8K3TOq$V|<(kH5R<@mbG%*Vo=39Z_6(+ailxahiO_o#=*)l`-5J)JsK`U)GZVd$i& z-Q=sjnM6r-VgA&iHDFi9#cn=b`3o=ny7GzDT&<3vJ)H1*PIo@p|FtPC}@{E!lfU@ybvfw0!dd)<^o^!@zW z2yEZ&y%w`8M}C*0e%PH4eoAHhZA&w|j=g#mMq%!sF{M@AwO#t57uCG`(6$M2<_;s) z`*}N58fQP2mpKLt4*g5|@5P#~s;3^*)0NH|wl^?oh|yW5T4hftU_6B8$5?}dP18t4 zCme?v0Eb$_e6}}i?&HO_H!z5Mfpo3xhvX#LCYQYR|1>(vtxa@w?AoRt&MfE`pHPt6bM>6)+aElo)KRs{7m($jg5E%^j}MsFsV?LatjajZ zC5sc}b<`)=Y@>mxmI_o=loUN$)09DNO3)8a;bv>4KIzkWFwhT2a#HEks#;~wsxs^P zDso)k<^3i^PH;yo84?~}zft{|M2x#D_3&=m%hzUIeYH=+Ad5Vek*DVLv9|tof^C(H zb7>GptHhZasyi^ns5!U>%xu7f<0=xji;JOI8v^sF=1fZTJ%v?5899jDaV)viy92q(oJY#HyOEmviA6BWZ^6=RMOts84HM57o8k zWJh~fA2#?c7H64ebc){I*(=lG2sMltj!8j<84k1g;w(*zNp-#(m08d?F*dAqZ*PUx zHaWUZ>%Ll_gnAJz`&!<&6QHxdX8deTq3=Xs>A+9X3TFxCTppp04m5)zMzF=AJZcA| zYva@sJvb_|L0n|hsHQ2Y%7(qoug|HP9{jzVyUu*Qn>KOAdR}`ZD@xfXnR65NNglsB zr)3!z)fHVZQj%r1-rsL_z)DHv%Ua_ahD!8`SB;mvtR({>y_7B&T@wH#QM3)a)$SFBi3&@V;p0BG!3Cu#v3o$<0n2~ zlY)(b9v8&$Ru@?)S#CC}H4W>lS!-}gY$}$6{T4Bj?3^*1`?e`jz8e$*L#GWYIhs3s z@$kr`=qACjb>ef~?Q^P+B3HDzqt*C{PIHpxXwgRNrVR*;rdD%F%wPn} zk`fG|OTmFCLc_RE!)m|GKD3SUU>gv_oFJv}t4LIt5vb2QQ?m`+W75Q!#K1Dg!-z96 zHlwUrL688LWK_NXOdDL|4<|4o%}$o2~!ZVWP4* z)1jb~wxaS#esa3=MXK38%j~euQijL?{V^g0gZJ!~P`+fd%5lj)a_EROtK$;nY(>zn zQbmkX1|tmHBrQT!QLf5|ADx>Xx^(F;*JOpnubb3uG1pkn*Tw{FNN5GUdwX{)n-X=! zwCzUC#x_wrIyc#pCo5DfK8w(h8j`-sYJq$dlFEjXO}j9;J1${GDl1?`>T;njwkH+d ztxJcTq?DwT*c7Zv1=wGjs!@Au$AnuoS=oKPUQ%{ib~VFNfqOYv^_NE*T=Q8X~jmz%gvp1FIK>IJ=S*Oo{Z(P|4X^ouD7AZ+-=9$JBJ`Mk* zM4uU|rrnbaSDi+?+cd!tl^zz~qIrDJ!uYgSjT@&c#Y(fX4Qt~R>QmWWO2sxrKUJT3 zd64Fz)iV#M-4clSZhWIK2P^p<1fLe0Zgk#RE#H3`0qjg$hT7@GsHMOzB z(L9Zk|B~FShG8guTa#vK@lBhh#y4rvqDd3g#_+4oo6EgVJ3eDnBzVeo@El5)u*>5*6JjU^Q5o*iTX_No`#90`}w2&x+RGcNpFQ z(fZC%{hg0C&5KI=tlWD?<);f~XgAFN`@qnbw8P$`-Meea-ezj9KWlzzS?o#e`|S~y zS9Y+}IhQ#Bo{Zn{xMBh+u`#Sm#i0(`Ld!u7Mp-wlVjot1)ApNA-|w5YJGngLtB&8i zI`yRl^UGgLSKd79?%U3uU9@V}jjKw3RW$ll&WFuN_hIUzOuA~e{)E0u^XpIez8mkT z?;(0^-?3`e)9mSZmyPEE*{X&-VY0Eb^BnSZ%0BmM|GTxw+`Ys*r*nUa+61_n+$I?- z*`EGqy80=$uD(90apg;82j*|yY^Ij8!Nr{z=vpoe&#moedLnfuvVPgPW=#N{OI`!ANKKyGLp|oY~Sv2g|Qm?B}7>SIn9_HX<0tlU@<4D ztv=hF3s#mJO2f2-xC>U*?5W*e_my!8Hn#T8);@e`kq!3UHRqmok>L$CmNwg+*JId~ z%|jwW>+~obI3ULH-TY0{p1FSFWA7!N(dG|X*nMKp>$(>~bk*cN^7Rh+YT&mEXB!)3 z!=qR;P4U1X5LJ6Tnus(i-n7c0F;<<#kcx}<`JfP&@G|nb^oZ08ggO*J?c7rRv27Kb zT9Gzvr90#0a;-!EX(bU6Ax8JX`FYPbn?1TwMCA3)%)RGs$9J9j-Z^Pv_k}~ei+@gd zZ_~tS&tCU9<8Q5ZyZ(~hU$LuSOMl&O-l9F>tWPidqr7E}(V;z2@KC<9zV{k!4P&CC zcZELRs?V4>P@5cM;C_hzj(m(ZXUNpBx_1u=Ythr~%4}g4Yg39x-%z6DW4dUHKNyhn za0V-eE_Wk%qh+nN^*<?Sclv!%Me1@%=ZDCB& zaFQWPaJ7$V+(7#a#wvo@|6_qei6ofgF;%6`0S)t#eBO+um+^&6S0aYIqM{Nal48)` z3<+o(D@msWMd|XXTcS5-+ecNuloB1b_dSP}auwhLJ@3scCq#xW2nlJ?J2r7aVt9xC zVRaVN2~C)vxKy7!X@m2_pMLt;HGbaU!TsC3^;XKr!Gnvk-qLdJQ00_i#w5c5P1l7C zthzZ2`7L#xV40~w@Aip#62d=UD$B^~ev7mu7dL2O;To#^Fm1@YD|a;dpEzfC<^r{8Vl8c}~N>^eK_-HR8KEa^_wHgng6 zO1EAfV^_JS{-{T#|9USG*FR(kVHsN$vO;PB4H?Jr3S0z&V0Mbkb zD1`tnRrM(Zpe7rU$dTQqAt>={r!y}jy?vW5!^0x_H>_yZ=wR&9$Jqd&_Y zHZ!kPD0w0zbapHaUQ$Md&1RC)h>ogtpLx2VaMh54NyD3U8k1evXXS{3Nmn#)eT}xI zOTQa3GTL>`89pT=BiBybs_1lr7%o|6wy3!nTrK(5C=U{iEIfgNk zkk>>F`9xK7MhP4wBf(Ie!9RK^V_TX**%i-!e&>3M19fjxdb3muxFuVnARX=l5kwRXFf$1YtM-6kR~ zq#-KbbsSH5{<&z2)45J_bfMR1518l7?zUWsqLAn0Wvj}8Mh&N7iQ9BRClUPsLb+60)<~jYa^B3yAt~Af%mIZ2`^Ab93J_emC7#u07X3*P-^oWLFmQQ0q zNi{f~`e7w6^JFy*BIhrqrCzg2i%7+)>T<9@t%l0txh<)pQu_~Tl7wOXR-JYesy&;7 zRVGp|S(E-8U8GOu%U5ny8}mP_`QZBi?wZQ50})hzt!tqJ97Kh2iE@erE)#$wlD9$|Fea(nUbsWx|B4y z>i=W#lR+CL69`IBU)peWt8SC(pX~P4MyQYeYgtF;HMra`p>cDnHE8w5 z^+{xnzEmYDF|FGJVQGbRp zTpM8P&c?-Hm7}KSqasJqy!M8+hR&>7f()%T4aaYl@R+ljE+aFQ5+n2Vw*}M_M=Nrv?TX@&nc9*dhudIN2K&e~M;QZRW4Nvw9+FbY3=a#64vr?UD>5<|zCe|J zT=nr-z2@|-7xd;XRei3j0}6GO4+Ls2;M(WkL(Xf>7wt3kcY!mrQTRR+#W-_&SRj;{gp8e~?lXCKdf=A`#<_8CjGQ1w${CHq)?tlTgxr#%k%PFMq!(8X> z5urw3O|x?p<(gw}rj3+x0{DPu<<3PUViL?0qlS1F`4P;`=KK zdI_0j-xe^WlAxAoU_M*%=x;9_)jvP_5?3p{=V)P<={NIJqmVvXm($^AK5@||n9hLX zqi+9D%x#W@$T;XSQKi68fw8M}44e9Vq3Cu=Z%Q=f-$$k-FaB+0dCdaJsl6Rlz3@V^ zs`6F2$JyD0N$iuXh>MMhiohgKK=V^cR@iM|n`^VRKG}&@={o*;kpgIHHQmQgFX)15 zV*+}RhBn^x81K4D{Bz``){pE%i}ERo}6n!0++)Z@+B< zeqVjj?+NO6KsTH3lj&F0^{p>={s~k-H9c$QZngHTw%28s4Dzi!F^G(^^|C2REIVpg z+sjVFs`vH|rpBei2#MAr?W=Y$>PBGSy7Db6bTvs|P3sB0ZyL0{%b!6Mol-6QM^tc_ z#!5<9)8Yub)((5AvzOi4acY6^1@h@`UTy1crsO4tvm8|EZE{>u`|ok;xN<>)tQK|6 zO=A`+;j!%lXM}_eYmyb2nlRQ|G=5y~MLFSFW4a8A3|8uz>-!cFq}E&^OzkvZ{mq-r?GW|6YA>9`~oZp)*Hp%byn#I;3%C zjH>V96Gr!)mmS{hs_p|Kf=m7Nt@Lsap~4cQ%E?t2v~8qMC%1Yz!^4#6zCbx4_odjv z!v2EVy0}vYXt~X&T;0>@h;I?7;R$03?;LWlc-iz(Et6VQwXt^}_uM(KG1Ne{v9jb$ z{np;bF;OAGs)kh?tDSXMwvE+lc=Uvu!$Zg4wSM)rF$?0REW3N*71VG*8Tgvfy(f%)!XZUDUR|n^yv5PN{0vnX`~Ma}DY_ zrAb?=wb(oSmeB`R-{PxLO_fdiLEHF0RJL&|*4#BYazXTjMJwkGtx>kZaeexh+&OjL zqt|rL$q$qb9hAcky>b!bn>#xzm^Bqo;Cv1)^Pg3SHtQRF_yE1 zL9T)QRq<_p_fcI|lo*L_Ww^`PxP>FI&_zRvRo%(9UImp4UR1@daUtEZy7vvner!%& z+aV$2BJUZ0Q%2IbE@LLn%y*Hgy}?vqsaKUy&uZKpysCWa_ZQ!tnS>V0OXlfPGzSF$NefdD=-fxe9?~O6# zl4p<6{odm$8|3X>@4en%?J>IFQ}+8YTFt&j*M8gU(mD|Q7@Gf~Z4K2Cs_ivvx2sX< z^!Den(nny0CSR7OHOxoTN>QXr#-y>6>U;}LR*Bx~ z#a6_dUDtY+4AzV@@O^M$vr3$$NF zmN&?%Z}Zyh_OqLfL7?n=K@1(CNJNUdZ|DPSX+N%_vD@#f2A-=L8gmv!{E(xZkn@s=;k@I=9(W(Ty@W+d+wQZ_q~&#nKK4a($Vj5 zW!dM;{=QW=T4heHy1Z1ZP#9@2chWqO{;?LnVDU?kPcniG*21JTrF+-)#ztP3F4J6Tc~8& zGRDYoBWFKF^&MZvnyN=%*62-(`DkDU1g0Zh33+m|7Nsa$)oEL<>a?wtYAciWTopY_ z>s_7VECCu;*J@;E)`xs&iSe3y1N()n04?c)JO~w7ZpIto$a*LWXHzN2>kf^yr@DBsGkRgOlImok`85=cHl%sXcHRLQj|N zyFN7I3uYE@y?nt9J-ScoJSRV^O<@7HxU}1L?j*lYLVt3(KmH%fuiAuNk|<^8cim<3 zo4Nhj4=+KS(l)F7Dq5Wx3k}(4ldgAO0R&jvyixgg%DO(lK7LD;@sXbEyfOH^`pvLvRGt>x?Ql8sV#%_q4$h20;Fw(42Y z-Y(jbd3P>Q^>N-i)cdscXX*p_(aJ6U`q&bvkIF6PB=7sqn>hW@5)p_dB8pAQ>^&5R z>Gx)h>r4HJ1`!Usuo`OI zWKNo!QZGC;reU|_UVXH=^XPQm-|mJ z_BWM>G5S;bYsRh2C5pqq3EG6Qz{<{a%9LqBA48-St613ju3_L+U974m^WV*kx>*~O zN`I;vgG#OKx^sZh$_1B-)dj@?Wi|rQF!nrRs7(c%KaM;siMD8%Z(9M=ueuN4uB5t$ z-|stY`e$IC=IElW+x3CRdju;yoid!RUY$B-I0tAh?>Q~AWqyA1jQk!{t}cp4ajngx zh>~$WRm}$WQmw?yS*mq=U9RF!&Mc`bB}rxv5+N?%^3kN*mG#B{WkdK+zTcw$FFL8&%LkJ$mC2d!e5`C8H-$9$z!t2_g$2cs1_}U z>4Mwic7~88x1u^A6jqJzlh>*$yS4hR%DEkktzA>KPfARPZ^CtkTy++n9FcsX6zWn# zd-oBbQc;T9`mgr$pxHTfN<;ee>^Ui z=9gv({l_h#G62gc%yaBp72l~IVwncELJ)OBPKr^cBzY8%D=((n7v5{?v)qL3#-N~} z(4f#LOrI*-jhyOzW>1w`igrhp>C;WBgM8^XfBJ&mIdqi|V}m~*SJcQyj6ZR#V=(2? zQ~bGT0#jH`0;MYT#bn7eMldOwWASI0122;u#htj2o%i5VT$CMJR^{hYJ3mqKMpb^) z(8n4KRbr?+SX75+D zL>|;QxG~ueMw#_OpQ?2{TqsC+ts@~&qW5cz0@fC-wYgr8hYol7{g#sQQJuMU*PS!X z_1rD8RE3Q-59&RfHzOxq8@*1A+2$R+sqpAW5^9{n#)SFCbCg|Nf9_IM*jVrHKY{q+#vMH^~=@&5_A z!jUJBn^2k@ORU5H&+!Z$5;)(L6V7ksP3H%=$8g&sx(0riKjpuAzW-o&*BR?@bvQc9 zh?=l|at@ORtKJ>Pp8CJXINQ&wGQ#;WVR384F=-K;DI*ljga22Ntv{6|ywww1xVVz+_>KDbW4Hl-Hk=|iD5&4npY88I zk*}Ya3w^G7t^sEUxkbIhmahHYbzDZc{eE0^$bWzN+BIC>bl)Q<+*@!T#9hz(AGIhD z;aa1uQT|jM|IV-Sqo-2NBA=_C^&QemPqnVFpVjZ*!Me5DJN#DpG4yQTv(a7NRPWgv ze{I}B9lt6k%%iw(;J$;KqD6s-Kv-kFHZu^$4tKj{8UF)tG?%X(ZRrEFJvLO|bk4$^ zN8KFIqCi9-4YQMsF&TqZzweP=rov&r%d?||_NWEU=jDWB8Q-pzV)flz`Umi+q;ifL z;p%vKI9>FEKLo4iAMxku41o=2=0#yN>WXDTUrWFL$H=dqzN?3%RfqYNbg#lEl3(?#-hXL%%=?&=?vqHrtDY~7ulN># zDmTy0G#TTVU+sP1JFfdqu-xw&wja%0i)+I=e&IRr?tk6AS^wI~*FDxy{Za2({cfwd zJ{p&2=M>yqf%>jo{5W5V6yhy#iXnpN-)w2(-^|m|S5yqIUE5(8L zmvglrC11ffZo4@==lb4RowXlrY!CRs&AjkzjpsX1;n0-(QS$uH-|+hz?X=a?#+Ozv z+x4ZBV|*t0`flsEdZ)i;m4Go-e*IyLW0Yeem?S-HS3TE&bpo1KzIIx=0|(*%1%BYU zt}z+CtW2wwP8`1P)*5|=dbYmuqY$^Ay}n;9sroi)pwdQNk-o=% zPUknUmV;sypD|kUUAlDlV=Asf;CEG91nS&Tq1wbsF?TaA{Oxop*ZF7Z?uf$QoAl8t zz<7SG`tSecXO-5)c#}L-<>!y5@A{l^`?mB8N+!%#%mc@Oa%(_+1B`WaRr5i(VWNd# zS_c*MS7e6%GWG7XJihPNTE9Q#*AMF?eiizdA=KYwkSkrxTF*l=%cTZY<-y&8@;SMofFhM>pT5XY3Tp1{4~DsY`wwvHTLgYWu$(qGzZEB zme>E>kLRsmp88GyxVj3z@VvvSWX%q*dRP7X|HQLO<6^uh6X=^0>~#Il>i2(yO8nP` zKN8O^a-VsN^?_--a-VahJm!P-^@ZoaJD+QgVJ@hSd#o+Q@tuNWmd_3R{x7&6aG&I+ z0POHrkjH6~@JHc@l_K*|`qPcpVfK3~9o@MrMxB9{NOM=P%yEUtd(L=?cb;W$XR%-C z#=fzTy~85*i|ij*+fKMw@&0qpM4xLB&ezyq{5wA?zNT`$W1M)LFR>@VB_G?6y&s|S zV(zxSa^7RT>)K`=b-iyLHBZYR`#dn5b>k*rL5*dP>i8%5r2N>=|C8e%?C*zjK3F3M z9lL;X*GRD|R*t)#;2VCOcW@q6XT3I@^S%+c+v52>8S8F>n`(XL$mRVfJRg=DT%XBI z=d+T}y;d{mheI73<$!ay95=T}Z^t0^ss9&XzG_w4eQm2`oBgDXjpdSOyG7E$yj{9D z?!gUwtIds;OnYuu^ZOryb)NeFgHUne_cystZ^wMpPWt)X9KWmH^#o196@FK}y9n0j zyc-5`x&QM6^H0)|eZ+P4-c0S!e7MTIlX@5C;TP#6e`LJ=0Y8qt(v`hiKW9hUdxqry zZ^C?CHkyBzLe8!E#w`I@Pnln1S9qRv!ugnW!uVN|s@kcT`u!^?1y9o#UChI4tz9;r zw{|(3lV4!cPt8MopXPs7zn>xg7iGBP7WSyknS+*sfBN1t#@3UM^~!bLPaG3)QEaM$7$N<*{NmqVtnp?O` z=6;<-=r>@C;?NzAg~lH z2hW1Z;5HEOHr|sn&bYSGs{bFjoCG;^hRAm?vXsyj;rvBAFtuQ z2e$g%Ww?962C$F(N&wLAI+-!@s@|WvStA2+o3XzbXx5W$?$)x6=WS+~^}QJ;f5APg ze=9HP-%$2%8RH74tREGOsdA4o)jI8Zj=jdWasWSH;7-y{!5Nq;j{@P_Ku3ghcI=my z`f+QU{sg+v&Dhr*lS9UKS!L?blQU%^dWu*khICyj=fGLB6dHc17Ec@B#Mrrtci-cG zBmN`te=~j~`K}NFdV>!5y&J!?cy{TNuZ1v(g(OQ`vTTx&ilp^hTrE|Q19LO-6xRd^ok0~`IW`hG814gLXkg8Th=8&}~F_#C|C zcOS%k%8xIM&DJvGYx%qJjm$D$WxVRL0~+3|j$v}AYq0DNz&s(JmzMz_jRmrmvHBwJ^G2cU(hDTmD3u3^Yb$YX)gF)#qm}QOJ=<3G-k2sY z;D4zKqxa!=6WOetl_&Z3vT>!nOFbThmvXH!MsCJ^%y>$kQ{aqsM!#BqhDQ1qV-<1S z&--oiR~t*^b>lAin=wvy7%* zkBtS4-+adG0_!KEkiK4E^)N~~8_cu5(C!BhSOrEa-?LeXU)~$jte^4!cNIqO!|x{6 zr`lQTbH1IY455@E$Y^hEHpW=nagQ2LS*H~!Lo3SA(zt`O#46&rpZD9WQ#KHOH14u~ zHO5)rQU zq9T20IHiseK^p+QLK1b4#Oa45Sl=aaMu@olzuOu0cNMp=vr>u9i!_rba zY<+|q4#J5476sCHl{8)?joGA8N*W7@f1Uzq+)JFxNMkN(EF+DZ{l7Pn#;c^UhctGR z#y_=F(t~)*KoOV^<{EFZ$J@(ZZ-d<8{TXkg^>NzjEUIQPSMK zFwSXB_4~9=dUNhleNkKM9HXr@1~O(sv=ZZ8ZG;gl73iy1Fh6KWct33n*NPwXj+N(gLOj0Q>f=L7X$2e*{+G+qWcBKw!;NF7P*)TMH^<% zjaZlP`4#-Af9}6YanM9L=^i5|?L9PnEqm`ACevLT<%8fCrkKZcqvyZqAcTrHPd;rc8{v>`+ z6937-Gx0|de+2PI@a_!X6;2Y5?N_;^v7NMfP!>#U>ve!my`I@!tD;wA%bt`m}BUR93 zw=-WeocZ#av%Bnfj*0jv)0euRPJ@h%YO4?&1rrt>qDAIq>WJP{u*xJ{r@knD*yk7u=l!(pXujmDgKhp zJAogf=!(z-4?*XP;mp$=8q#};UIguC1auj=_|_@Ld`laXIrqmQ7Z!)y;x+P{J^?|c z3G}fh>`Nwa4vdqm8hq{QJnqh1nUq#F39nXqpZqv%E(Ng_1X+?hq*yvGoX+=wh_N?01M+>%oWA~GI?JlFtD+@AN5~7Ljb`MJ{O%d}tz5>6+M^E#%>pj__2GI8 z==q#$c=wz>S-NuGQGVuA>m4Js#{w{J)k0W#9|Pfjw8jO{NMF<*(|**# zony7f6hA@nR;at5RoW^%d0NW8=n^&~?61yqc4hoJ`^h50 z_v6eS34iV;M+_F@!leQHpk%XHwyXEfFv5+JLhN^BI~MY+cx+#i=IgS{9By$ZrzGMx zU7aV)`qroHhYqSfK|XHg3?E~|OF#KV>f-->$5)*7he@tICP&B~p63w0z#JjBfVQ?f zoHM41uN~9|VW1kE$vwVCr5bH3{q+T>m79@LER*u79RUI+Be;D=>}O)m+A5AcP_A8C$I z<5SUIZTf1p@k)8eLTk0hs6E#{1zm*ns?oSAnOl7HM`&8k*)olNR6ci~e&B3ReXZi| zxu^Ku%6do9;S?Ro9^cHfs!sg$_T`Gsq{hBYyQ0m1Hy5Zh0`q0HIl-R8mdF5e4|T&D z>o`PyRT*(rn=4)hHX-NP^T9Z{v{94X47elG)4cl>8_-y z`)Qwc+J2g&6IvpB{BIO!vximvDcK+AOzQE^<2AY6Jx=Zm9>SbGP`$H`I0srM+MLN_zL4{vQf@i^I>ZT{e2I8Pthj^64!^0CNhV4 zaJh52bpZN68)vEYFLQ|2fN{E&cU$3c&NbeHM)L`M9T<;TV~q83Sn+rDM6H#LP2d({_e~%F7c>Qbk zLMPcDeJzK;m7q*NA>ZrWth2_0@`Q08be99-bi6OGn}&oqzLo-!N-P^y4gu#uKfsyH z{;j?haxUA9yNzo67?=92oXoprU?*690hJkiQ(&I0Oas~A6L1}V_5-5uoZ)vo*aO;u zBOo8tL({>nLdh@zE8P1dQkK*@HJH!T>q0z3_V<@Z7#ya!k-&H;61{SGgr zUlC0{cwa%eE9da6umw;*oVy0SOmqDi5C52=l7%y?R#h*nOi7F8)0957q7!)Sm}w*Ym1Oq^Ye^ zFb<+9@~M`s`Yip<4Xra({}g_HntTG%^)#&|efJfkOp7!g!X7dHv}v;6c$azKHx8cA zrlBn^p1Jyu(52T|PwVeXXU5n%b{bRlZrlJj*E*{0w7%EFtb4SH)<)*It>(X&yPgpx z_pqJ#uGFr#&ajVoz!+$K=Zukl+7H+ldlCDCyfZsVa@Af!{obw};@ctR+WypU_880w z*HEda9PrU_e`6jPuU)3E1^Sn2C+H(R^#`;#J>7cU$g-|9+FF0+dB5JvdR_13-KQJY z4!yURwmE;8zEy}`)^zH0Gc>_(p{Y^-9yh;_g7wsU9rWwo#N7*4tNzTsW&wF>%>YCu4-M>UkMgweMo(s(K}k$-FNGA8LcGCAg@&SCr!tcg459?-iSoo!i0H5>V|?wU?1D=t>7Ry zgBATa&>56~)gqCEkIDq36GfcSlfg=`9UKB@k!=qL*`NrJ#~8xIkiS^ch$U?7Ffa$K z1AD*;;1Q`84+;Qr)++_&fc(@u#SLA=8Am?iN&xZ2Z2|kiX_5NTAQw#M4p+i9I0%l3 zG&DgvC;~IUYOo6&1?00)BhV5I0<%CFAil=XGEH81qVf%?gb}B;zL0uCt#FIptNu-%9U=)}INGo|aAfGAZGlhJn6oC^Wsl=PQ7_1XX za|7Z{!(Tf7)GZq6_)DJwh&!FQ(}}woaW_i_ok0oUdo#i}+Xv2wG>->_Yd!~*1LACc zQltg%TjYXKpcHHXdja2ChJs8m3=pm*@wMCujsTBHE5f!a0F%K=!1q>L0dcn?&DL?C zGbjOz!4|L|oEFK52Be!Y3d{m!fbSW6&rAnJU~&H`m%H#h`{zr!l96C42^k&e-T ze00nP1%UKAo)GCodY$3{?>bEel)KY*a0rk_=M5s*7?v*h?}GoX`0q;ox{_|!`2hc2 z*MZ$4-9~{@P!9OrJrfKAa{zw26GwOA$S00`;>ah>{25?1*aeP?uzX98WKamEgH>QB zpd39sA_eh)a0TSGfV2y?1LEvSoIQ!N=O8c(l!3kA5I8H+s}aZp6TmXC6&wU7MS7Qm zeSkE2lSW}Ez<(kB3r~ymnE}XSpIst-CnM?*2hu^2ND=<}wQuvlbd9Ow*6fcm`!><6bsu8amP!5}ahklvNs z!687JS2Y58U;3V+m7I4CaFkU>6{bl4ES83qU#82TqBM4+q%*|KssL9{=O_f|DXw zF9T&@Hz4c;6QqM8FaxXx#65wyCy;(9m%)2S%WeV|6$phqP3TaFs4^zm~6#Pt4emo*miEnC4Pyj}OS%7>_-46Bv@;ddb z$TZ@cMtswVZyNDUBh6`~IgK=@5#RJvfcUN@zH5o^y6Ipsz|VDCMXp~7h;v3cDmVwh z8IhTBpfe!cjeMUqL1cDIKwf5#0_0^j?`IQc_FixZoIs0|=bKK7+|2Jeg#FWLk$ICr zDZuYM@;&dA$b1u!=lSG$p@4XiQl3kR_g3ED%JXf*z;v(}tOGm2esBU1_o8Uf5)=UP zw1}{aRszbh=ny!AUMb~RoCyj+377*`fh_<(i-~J7aV?1k#I@v@$kLr6x9<{JwpC;~ z&v)SWj{N|?cbpMf5ekTN#V{~kWaUbcJMnWTe(uE2oy2!nG-wIP+g;@Cu2~{?Hv)WH zH3KXITSe}{y*FFrzGRWrxqvwCFB5q{VK*Q@51Jqy6am6MxEheZ2loNKmyuQ(X_b*y z8EKV~R@nxy7n~M($PMB_E*JzRgHo^#>;$Cw&f>sEm+U=KI~Nb6zzK1>`Bmx-*;2E?^~1|Yumgj;`9EMXSqsv4#@@^yVHsWvNDnJ?=$>U=Jl0hNZ3e>w(BITjrq{t@RO@!UV_f6z;(_*j- zkmhE>ZVm^7L>`Y9*^;Xr>X_3D~1LFG2C@>$K5!qe}$^da~C$6VS|7qUuAiW*re@AC93=sbg^0;Fi*bNSW zQzCygK_ie2iogUgAFKvj!9j3RWT${QkO>OGEU*%k1LAw`jL0s&?;?M@_`a(I%mJ&w z7C!kbo2@w=lgS)nFGOJVE71GAIP(=Lqq9Ks+Dv z{v#6{17}5!QpTgCd6amL63@{YU>Vo|i0kM`UJ&War4-LY&?1SSB=aEx@1?E(kENs-S&K{DtJPKz9O zgO;EGi~_U3N~*XatD=^J1`5q9Ps|zz2GDyk5G^d@PF!r$aikAMdW+p`JV4T2#5ojpb$(4t3*x{ z&*@%n&(;pL4{0?j-b-P=LP*zE=>Yg7`c5_S2jW|V{7qCsQO%o1=!G{-X0oax}CXs#2Y zxe4oD4YrCFG+ne{blyYCL<=1R2orh?oE5FkQPIK(Qx}p^-8hg53ITrV5~l7dum$V^ zM*v~M@fV&8ioqOE26llXfV@YzK|06-#1ny^2>e9O0;CtUPPAz96unrq81fT?AI|n# z>{-#`h5^2DPS@h_7q=7a2b3w!BU*j((tvmy6oVOH8Q1`JfrH?rXblC#0pe^p2;i^b zDzF_K1gAx76b>@MATSvaPb1=Kv|F^sGr%EmO0*^>XaurB5tsnxgVkUw*b9z=Gom#O z1<9Z@7zU<`7SD5n8{j{&0E_~&K$&Psxqz_A#eh5{mjd1=ZwLFpF>qG2lyHy^@&JBQ z$Y07bumS7>2f<0vQU&Z3EseA|>uc#}L~BN#INNK@$VanbfIKx@4AuesHro$Qh}PT$ z_-kGOCV<7D9P9-rL~CJ!Mu2!)5KoI)qP2_zXGCj7K3d_YHF;~jSTxS(T1Gk8En4Pk zK;GK80r_roRsHbG2x_N<`~DS+v4vK%9Mciq^Ln;J^P_(FTBll!^17 zHn>La<;C~qJt{^|dc|T&7XvL&AGF`N*T8cJmm}sMU9*zIeyG0wb8tj5S;1+FM zHrOZH_-L>Nkml966XL;9(I##X?V3`6pGkW}n@k*2NN37c(Kvr-QxA&9*+QG14)Akr zG9b=t3&1ci0n7r6!D>)0+I57x4!_qO0Ve@vy50@aK`!7s=MU}r-GKaDe^j&?CPfem0gAm1~|=S=+1JT2Od0>VK&$OL&{5FqT0 zrC=Q(y&De!{Lcynx2(*8R6G2bc|PW7;Lf0Mfo>4A239hf9_MYk9bqIUiGGHx$uvlAZ*B1le?fNl52LQenAl`yGOuL~c0D4#- zX*Z6?7Tav5EnLpDn_$0rE7NX)ebF|i-MW}*x2rw{*PfNl3eXE#ue=*Y@K)46M$1( z3v6ZD`aGZ?Py;jpbAi=NdpiZ7EZ*q@K%Va!z&fUFSj@EdAgA{r@Av00?F0C2>JLfMQ@EFdmo%ECN;mo0#?) z1B!uxz<6L5un1TMY+~AG1{4DWf$_jB06cyUUO(>xqyXgU^M$}#U?%%`x``$o5U;qG`-$On>AdMf&fev5=)3!s_+s6VM zfgMcy5$XK@#ZRqF`w3<6(;@(6^wSyueEqzbX}|Oa<^$W9_G>+`foZ=D2N34>VqhM_ zbQ(bXKO6w|KZ^kP|22zo))QF5@M|al?7RqA#JE0+al-(LfdRl6paYl(ECtp8n;AD5 z&>JWR5XWo<<^rH;t_C&%I~ce60f=vbwzUq}&bZwRXaJT2TNrmh$63s{n+L$ng_}1J z*vNQfKI3^cKnDPt`3Rd2I)y35i;!NoKEQNf4zPjo?)AV@#(TiM2g2{N48V6+(AyO} z?uPGf@b3j4dcl2n#M@&4fHe1<$2j)6IOfN^_g2RDLK=H51hzAd`7qym5##$50kaq{ zM*QN%jPKi*@%>=lZw0Uh*Z^!}e18Wh2FiiqKm&ky`!4{N0SLSQCg2yw`+#PjzQ90W z3@{TwzWadBKC6L^0C+ec4?w;S0KW%}0-Au?0C+rLIj|Pk4D4Y1z@9)qAO(yCI)J&r zVqhh(9@xtGK?cwpK-ve@19O0-z&c<%<9$Kv;9>xD4hEfrLFZu5IT(337&HzB|A!#{ zAxWSH0F6Ut0`mdTIb=1k5!lZ7p?N?bU;r=*XaZ&f3xVap24EZG{Tu*k_A3X50}a3| zU;%)1`>g>s0Z99>BA_oY5Euir0&{>xzzSd;u!Zsd4Cnz5vGk&-O z^aF-79)&pyb5xicfLXu-U?s4L@t6Vh1qK3RfL34*un1TItOK?%9%n!=APNiy#skxV zd5k9@j|9?4jAb0_0FHG4PtF3sOGye?!gy&7&;)?bQqU|zx@COA2a|M1vCNk0Qe8u z#Q0zX=nD)4kjCJd0MZzYGzPB*kcT080B8&u42%b+0}FxWz*=B4u!Heqi-B@rEHDdL z46FgRGJYKVj!OXzz+3=+$E^f50pPKw2AHIq46Bq#6Bj7ipA21(S3Ty06EU=*;0@v-xOMZgLGG8hZD(-?p_r$vFmz<6LffUu{5#%Zg74Zt?WPj>+1=0-G4GH-Ht4XOLb7VKNAl zL7WWYOoaa=_)mgc!zjiZiy1$I0jn9GJeKjMF#!0PG5~=86y&3MKI1LRfK`mQu3`L4 z&}u{2c7*N719~&w*@y9|$iviLj8DUNT3=u|Wx?`-gU_728p zZe{#m_?`nE&RNO$xk&F^xXmg8W-@*r?B_d-U(gc(PqXJTeqjv&^Tmr8pM&%-=?5V0 zrJyqxbT02;{E7{XUkSe}8-VqU&s)a$Rf7SzUA2z!tH(2bO&$P#=7Z+7h;vXaKO8@ms;eZ8ePFJ{TAS%ml#0?Mnghd;1pP7seO&29f~M zSlj^20u}%(0q}bV__?Dm09toUXZ%i>@7&1vT@2_2M1fI26EGWC$oLY_x_d6;_Y?uE z8Naul@uhtjzi$8lI`_eT-%J4f+_w~12_UWez|Z}Nb3f9!zZ@72fT#Px)BOv8WsE;C z7U%##|AEE8YQ~o#%(88aKR6hG{h?L>v>#dltN}JK{xHHU2hYo4e+0B1+0OW*aC;2q z75F|rkntzV8Go`jumo5IAl{RpyV3!Q0r;;R4j}x>S&ToG2O#{@;N$7#z*=A{npzPg?9wcv9t^8FfUyfznD2q4_+GZ}vaG~d|3_&TJyt_c7yZzBAg z@Ou;dyp;zm0)%-J*2S4Ffg0(w|fFfAO(P*cR=Hv4q!9m?;`xWYZ%`! z5LnLmdkFL1O2*$u{P)KKp!GpdpcO#+8+!wb8UGM|A0pk45%1$ojBlF7_$LVSDf~a3 z$M|RcfK`ldUcmV0z!wOIy&V1}(%S;sTbh6kjDH0lzuLz5*AC-biy8k0@xNKi__qrg z{~!FffyQ@HpdJ8!SP$~=mofeWc=`e1w%0KJ<5&QB_^BV`KZAd)&-ia!8UK9?<2z;p zzcBts5@-UD)?Wzo*BD?ru#xF(Ah49_+Hhb8)A?ei>tmR1hp)a~TeP0yV$_0P!OTmxu6qeSrpG3DfiY04bmYK$wC} zOvm1bUbK$s-4LeRG6L+~LBBg*sqcaKJq7^7fhJ%BfHZrKV)`zix649cCDV6}0-(F= ze5UV)IJ@E73-Nk^w_e+szIzhrVEP`tfNf0Qa|M9(u}7iz1`m4`0j3zW40rQ!DAksQW0P*?)2Ty1EA&7qn==XDgUzmOv z!uHPt;CJ{OUpv9D%S$3RS&@L=*3JwrW^pj1M`4>Kn*Y!mefrU&T+#8qY^bu8SET>z{AHZc7-(7+s0uL1uxDPRr&{~Gw$fUlaZOh0}M0Qy6b{!rw3=zL%q zunyS9^kGFn6EGK83an-N@K#_Runbto^b`644ZtrI)2w2SY z6Z3$7*hjmVEW0(*U9C;SYSQVPibZPsR(;2;*3R_r@`+u zq;dKtrjJ_zY-jp-xQ*`sKzlsW8o!)rj73JX+00{;m<`Pf?$fZ#8PoKFJlNsO_Sfz~ z51<(?%)jnc$#>k9e~ zbF?$a?6P95jm#04uO@RI%ny+{Un|z$B69)mv3;-1V0u^mKr-WJnRG}`(APNL5*$Nj z^lSS0WHxXQ;5jmzFn>X23wQH8GTUqqyjQ2_I54AxBuy80+$NCO!+l3cSGq^w4k=4> z9_wdZN9KIi%LvjczCrlwTX-oB>;%3|+}O@oj)x z8*2}R90J!`)&#nBEXn$Vrl5KxQfY+GVXOk_#NjdllrpTICEz!Ljbz6IM~3Je26K*5 zn3J&kiITf^&~5>*#s4o;%u)M4r!pGp7b7Rl;IXSD8j)Y&Qw;vv@T~_AQ}AtLli}8a z8eJ@9G6muKXH6pzq8;HnW$a2xS4g%U{{`=&3_4II?YMh!IQ|PCMPUl)AO8R7FUm}D z=1Y2_L`O<)I@mPHohVTiLX}PiskX~9C(_j~TC^`GAlAR#U9gt3ORu)Q9 z?chYz<5t8F5*M|h313k&CqZ(`a(i;FCeu4>JUcM!CIJ9n{7u43Lb>3Xleh?VTvI`!M&gm&Q+LB*L+nXeU(}>(h(-n0-Ev7 z$!;QCI>AHEMU>F=ki8jp5vK+rr{UX%exeTaMBOTubud>SM4uqacO?E!0l%UyPXtsB zJ5f{q&XJIxkU}e{wX@OqiW=QDl}7mGQV}VOIyDh>N7PHvb9I0_K|$0@A<+!VpcXEo zrivb~m<`&AhLC2P>}v(5s$_~mQ}n)JmyUnrT1X&FJ)Db?7=77aKizQSpNrXCjI)3H zhjAJMGwXvodOy35z06)>b@(YG9X}9bYL;eej^=8f7SZywe62t$)QYrjT6e97)>GR> z+f~~QKm5Hre&Bsit+%$9wzswqM$dh<{j~kHKH34=f!aY@U+rM+5baQ{pLUqmUprij zYB4RYCA6eg!scnETA5bP4$vy_8rYHA0PQI4Xzdtwpf(Wo@DHt0t73m?)mlnRYd$+j z8>9`^hG@rX$7wa%@!C*rm^K_O;8jR?4SPj9K^vis)JAEe@e?U0X=AjLwNtcHwXxc1 z+UeRjyZ}^-8+LVCy_V4?YLm1Etx-Eeo2)fyQ?zESMQhd0)Y`OmtwZZ%2WwNcY1(vl zh&DqzOFNtWqRrI)rJbXltIg8R)6Ul}&}M5FY8Po2YjdE(wb!)QwKueN+MC*2+JA8K@NMlK?Okny_MY~> z_JOuh`%wEx`&iqgeWHD;eWq>JKG(j`zSOp8UuplUw$w@gdfWL@xyq3emIZv7?1M=Px2C8%FB2;ui!`UBl!S+6hE3D z!w2$8Ud5|DW{k$e;%%}?Yf@iF{l zehNR8kA;G=l%LMW;qLBcKAzX|3A~Qi^9-NJC-DYW#vAz=d@^t1Q+P9P;jR2k-p1Q` z2P@~D>>akAz0Df75qw8!RPU-@WR{G{2D%=U(2uK*Rvz}0{rsZjr`wyAsfJNVqf!{@#fbpd=bBu z-^Op}i}@Y=PJS0(!tdty@O$}E{Jz`$`~kjU&CMKukcrKFLo_|jla&{;Op=%>6`p5 zs6D3e_55xA4u2QFkhp=r$KS_|%n$fR{vrQ}f6Os$#sAB{=3DtU{9FD%zKws!zvn;j?fggn6B~@TA@GI_dbBqF3;&h>#((EK z_#gaF{+Ia0Bm7XHjvv!9b^P?D?&z-W=@C6o&({m|LcK`urgvvU^d5RoeHVRKeK))i`oa1k`k{J1{V=`1ez+dh zV|rXq=t;dqFV)NRa*QqSV&OVXKSDoJAAnzzJQ_WA2b-!NqYu<8^(wtuPw8ph*9Yl? z^&$GP`f+-Ve!MXY;ay-`0ypR70OQ}kxNMQ_#5)Z6rSy+iNRr|Q%6>G}-)Ed6Y} z5;s%-mwt|Zu0BgY53`@?`uX|=`fU9|{UZHheU5&Kekp!!aISv2euaLeJ`XdGnYi71 zt9}*c2s7|b+|~Lu`h5Lb{W|@6eSv<1exv?xeW8AnezSgyzDU1SzfHegU##Du->KiF zFVXMT@6qqom+JTF_v;Vn%k&5JhxCW_<@zJ~qxxg|3jJ~Y3A`}zpuSRn3U6{gtv{o$ z(x1gTXq5iEz8bIEy`aCSzof6xU)EpIU)9&@uj#MrZ|LjvH}$vl|LE)WxAk}MX2-kw z2K_z#eYOMdrF@`o)IZce(m&QW>7U@mhD-F%^v!s?=5zfE{Y!m|{+0e;{cC-z{*C^v z{y%-2{+<54{)4_<|55)*|5^V<|5g7@|6Sjq|G~zv^YlOUzvM5Sor|k3v+$dEx`E&L zGAzS39K$s{BVyzk`9^_JXcQUUjP6Dcqo=Wpv8%D0(aYG~*u&V<=xyv}>}~906dU^* z`x*NieT)N)1C4`>zQ)1EA;zIbKjSc?zj3$`HDX5GNEk_@#3(h&jB=v_ufQH*9BB+- zrx-^WM;pf&1C2_f%BVI{cw;kd_{Jct0LQW?j3LIcY^!mcQDYo$3^j%s!;KS+5ynVk zlrh>k(KyK%W1MW9Vw`G>HBMuv8K)cLjPXXTF~O)~UmEpB2Jc9GV@xs{j7H-OW3tg? zOfi~`7NgZT(`Yl=jSi#Jm}*QjrW-Sivy8Kina012bBuG1S;l$B`NjptY~w=XBI9CX zj&X@`sd1Sx*SOrc!no3yXIy1mZCqo_H?B3VGp;ul7&jO<8viyH8aEj?8@CvXj9ZP{ zjN6UH#vR6;#$Cn|<8I>~<6dK_ai4L&@qn?+cn}B2A2J>`mK%>4j~b5|D~!jDCyXbJ zmBv%X)5bH#D&tw>IpcX_wef=SqVbZk#(3Fy#dy_NYrJN>ZoFZvGu|}bGX7(%H{Leh zG2S&c81EVH8y^@OjSr2FjE{{?#wW(7#%IQ6<8$K+<4a?U@s;sk<7;E9@s07V@jqjm z@tyI#@q@A5_|f>u_}Tcy_|^E$_}$oH{9*iQ{ADuy&LcN<(=bibGHuf_UDIR#HX~-9 znQs=Dg=Uf2&FpUWFngN2n7f+0nZ3;2%{|OL&EDo-=HBK$X0f@ixu3be*~dJ}wuu9%3G9_A?JN`m|7=F#Rc=0LO3tTL<3 zl$kbtbC5aM9AX}89%t5=$D2dVVdil21apKr(i~-uHcvE9GRK%Fo2Qtknq$q=%+t+r z=6JK#oM6_O^=8JLXihR4%trGJbF$fFPBEL!7PHkn(`+-_%?`8EoN7*kHfA=vj$Me~ zlbUYMFwZj2HfNguGS4y3HD{UUndh4qn6u3b&5O*7%{k^J=B4Ik=3Mh~^9u7y_Om(9 zyo&W;J=rei)ofR`8|!6W!**wTusxw^m~UQdUT0o!E--H}Z#4gHE;Mg4Z#Hi+7n!%3 zx0$z_i_JUCJI%YyCFb4cJ?6dUQu99Ze)9oynfajkkomB=+hI ze=&bGe=~nKcbI>ef3io}W6)-qY&m;`y@0oX|FW2+S=`bs!!j)kKO^f{E`A%c8@t!? z*j`q|!s}1$c`F|;Ha*Rr!3!SuuzlFRY(BddtA#6B0WL;tV=JIZy9>V%UT76r-K_3b z538rOi?yq@o7KzO-P*(2lPzXd?0ohdRtou6Z+0nud1x;S@6cQOSjE=9)_&Ih>;iTZ z-l^_m9l+*T2eOOse$4`Q1G|weWOv{NrpK+m*1^^x)}dBE>oBXob+{F^VpiNrSV^nI zDz(b2a;w5R!aC9#U>#*0Z5?9`v?{GCtJ+FgY0I|;S%a-1*0I)cR*iMMHPjkr4Yy9P zMpz@QQPybdMC&ALjCHbgigl_r);i5P-5O_&w`#2kR-ILEWvq$TB&)${w9c?5TTRv! ztJ!L?TCFp!Hmlw0usW@&)--FnHN!f~I@_9Q{mVMXI@g+IooAhIU0}_&F0?MPF1F@a zm*9QLORdYSxz^>@71ov3JnJg!YU>(nzICm2oprsnz`DV@(fYTw(7MUG*}BDAWZi1r zX5DTrw(hX*wC=K&Sa)0ZSoc~>t^2I|tp}`S)`QkV*2C6v>k;cw>oIGE^|5-Me8MNjrFqiiuJ0s7COimt=FvAtv9T7)|=K_ z(1m`?s_|mf71nyTfxU-oN*`EnvyJRS_KEcl`-p9_-nBMZ?^*9#A6Of$53P@|1M;!8 z$@;|l)cVZYY<+HhVSQ>^<$?_Fneh_C9v8y|2BWy}#YZKEOWEKFIECA8a3DA8Plr53~E*hucv*X2{{4Z69L~v@7i@yV_3KY1_94*@NvN_ObSHc8z_!J=7j% z54TUSN7y6nQTAy2MEfLrjD50wihZg*);`TX-5zI;w`=VQcAZ^sXY7ggB)h?Gw9l|7 z+fDWqyV-8BTkSLLHoM*KusiLk_B4CCJ;OfBKHHvY|I0qdKG&XQpJ$(MUtrI+FSIYR zFSh5{m)Muum)Ude%k3-dEA4sqRrb~PHTHb_TKhWtdV7I=gMFj@Z+oGAlYO&&i@nIc z)xOQX-Ck_pVc%)rWiPSsw(qg;wU^rW+4tKI*vsq(?T74#?dA3(_M`S=_6qxP`w9C= zd!_x9{j~jzy~=*pe$Ia0UTwc%zi7W?ud!dYU$I}c*V?byuiJ0f>+Cn}x9tDe>+QGg zckFlV4fcEX`}PO+M*BniBl}}}ll_VPsr{L~+5X)A!v50UVt-}-*Z$hxYJX#YYyZ#Q zW`AdYZ~tI#w|}&MvVXRJv46FHvwydD*nil6+J6Z}xWgUYF&xve9NTdm*YTW)ljr0+ z1x}$;2#(#)12wf4CgH8Y-gtP zFXtTRTxXVZo^!r)fiv5=(7DLD*qP&8;#}%n=FD|2cdl@*bmlo%IafQ^IP;xro$H+I zodwPf&W+B$orTU#&dts(&LZbl=QihdXR&jKbEk8cv&6aExyQNJS?b*9-0wW#EOQ=o z9&#RbmOGC)k2;SzE1bujC!8mpmCjSn)6O%_D(6|}Ip=w2wey1WqVtlo#(CL!#d+0P z>%8W??!4iwbKZ2`a{lA2ciwj1ao%+{IPW>{J0Cb3oe!OloR6JN&L_^N&S%bM=X2)^ z=Sydc^Of^o=WA!H^NsVZ^FL>s^PTg(^MkY9`O*2w`Puo!`PKQ&`Q6#!{NeoR{N*xN zb2`lH@Can!|mzr;_mA1=Js-TclU7jbbGsd zxqG|&xW(?i?tbq6ZXfpm_dxd`x37D!dx(3e+s{4B?e8A$M%|bjcN1>XEpbcTGPm5V zaF1}0bO*RcxktOlxC7lvx5}+{Q*PSz-9hePcZhqedz@S29`6oyhq=Su6WkH*NOzPw z+C9-d$sOaK?4IJD>W+0!b5D22x#QhhcY<5z*1H*ZqC3fLa2wq-+{tc}JH>5wTijOn zOt;N#cRSopcd9$ho$k(X&vMUpXS)A#&vDOnXSwIO=erlUv)v2bi`_-@Vqo&b{7U;NIZg=>FSX=-%Ys?B3!oa&L8Sb8mMSyLY&E zx_7xt+`HX-+J_d)j|_hEOr`-uCf`nm)%#~SKYPlYwqjr8}2&yP4_MLKkj<>ZTB7bU3Y`~p8LN0 zfxFTD(EZ5$*xlrQ;(qFW=5BUBcfWAIbho%)x&L*)cDK6UxZk?}bGNzQx!=1#xZB+y z-Jjf_-Cx{a-QV2b-5u^9?w{^o9`iJhd%9*F2Z9q1k8_4N++4)G54`gw|84e^fk zj`M1~5cM6dnbA)d1Jhjy;HnXy|LbD-s#>rZ@gFQP4McxdN1Qm z^d@-?UZZ!0H`#0Qrg+U>i`VL%>9u+7UWeD|P4%XE)4dtqS>D;+Oz&UbIo`S6Eblz; zeD4Bpws)a-k$15-$GgP4)Vs`^>s{_$;a%y?^RDu)_O9{fd)Io`dDnXjyc@h5y?=WP zy_>w7y<5CR-mTtk-tFFE?+))y?=EkNcei(scdxh9yU)Add%#=fJ?K5;J?t&_9`PRa z9`jask9$vePkJl8r@W`VXS`M3v)*&w^WJLj1@A@gC2x)QviFMjs<+mA&3oN@!&~RQ z>AmIs$6N2c?Y-l@>uvDf^WOJ9@HToMdLMZodz-vZyidK)yv^R{-WT4N-WKmG@4w#H z-d67$?_2MG-Zt+$?|bhDZ@c%S_mlUt_lx(d_nY^-x5N9x`_ua?!XjFPNA!phF(X#Q zjyMrF;zc5nyhwheAW|49igb%~kMxN2jO-HGHL_czS7i6d9+5pGy(4=?_KxfmDUR$L z*)Otxq)+64$bpfAB7GwVM-GV`8tE4~EYd%6cqAH$MdFb}BpE4*lt#)T<&lcW5s@P! z10qL7j*c7?85pUIR7I*IsYp8FM+QX(M}|a>jT{%Li5wpp8W|QD9yuX0A~G^EDl$59 zV&tUAn8?YIQzEBE#zszyoE{nHRkk%YPpYl!?8roGJZ6kAUai&PBa-)8BeByuVTH21G|)GG@eYTc;zt_J{C8sG95&$yev{( z*VtCqIb~u~X1Z5h-_lWASC?t-5Mfbfl67QNWieK+XeNA_m1wNI(n{6UqJ~g#m9un| zii{+gR+5ROV{tPzp|(vi67%Cu>MR+1oSmkMmX;OGOXv7Vt2$?;v*|?RDvS717UN37 z=@?}_MpY>mxD#J7;)_Z&tx6JADsZPNR!vo`nnYSnbgKiAmYV5~&bDSd-P+#R)Y6K}6k$@1wR z%ga#>LdWC6Us4X7{G>9W&PMwa!}0RS;2d|7<9LkZ9w&Ln1D>cHp(!JB1wqLG(O8AdCG6GKkdDTt`iwn< zn#d5<7Z2&u7fW(z5Rx5y6&q=)Rq5(VV+dNdEB*{>%VZ`?lax=MaI0_3v}M{Gsl!ZA zrV^B?prcd0K+I22rV^B?1Z65gnMzUo6va=GP*Nm3YPQK}nLea{EHWfWJzH7QK?SNP z%eqygb`6=-Ry#E#46^@2?HrP;O2S!63Q7}ytQbaGBjFu`Y zFhMktV{_S8Eh(ugK%z`lh$K~rSc1BZv?`i(f_k_FwYY?AanYn2oTEuqk5LWF&EslY zTWc`_iOGRXB$lYMYO*~@EUjqc8_=f8r>Y4C4_QqxVF>(Hbx9|Qhos~I4LQY+@02Md zd`SXBYPB^qlyI`d8k$WQEu9D^sk=y0ccFw3OD8MMp$#o9ll64-BuO`^dSwVtv6NK3 zb2N!DRrGktG>JhC(a}U%DIcm>id9#c!x~!9=MSTHI84^8{9z59m^rm|PHC#`>`?Ma z(EyiLxj+q)?r}9NqIIe^9#@@EG_E=ye91j1oTO@J=_CoPgalSXg;q`e)#R@x9Jnnom5{}1t(8pE>vysD~jr0P^crCg$_a#Br`qOr=PKBA#T zNI2%FtDO_ZwRMO>w?>32PD!aXB3E(ZG*gSmNKhptn35nV5=@B{Y&;h8`H1PN43pK? zNJ%&{a_6=e%r;7?m`aIyDKTD3)w5KlhDxZ0_*f-%^=fR0#$%P%D9NlGg<%bb&QfBp zl-Mh!axaq!LK4+^q88)Ze?o10#vY|4p%_o3^-;B*=4ereto8BJArw5-bJXt4;$ zAKj%wj}8wrDVj>Ai1U;hiesvykH)BjkE?kYazZ&SBT1BzB+3GJl6x6tOf^4LK=KcI ztDp*~h6I1gxUVuE4?2J{5=>b-a#F5ztdr!hVVxw)%{?g?Ze*27t0`?PO|$eg&Cb(m zRvt~NWkxjVSL@XcjZ&7eszl`E9DR~6<*__%oh;K+m(AJesg;RV}t_b5%8#uBh~Cb8A{@40}goX04pT z%WhwFxX~na+{vJxr$IcE>qe5P5@SNpKgG(4gA&RyIFXW3%^GVb)i~lb493dKBXzk- za$%MQd3nUO^etxEnd?xl2=S|i#dm? zt|Y%$b*WiDqh(TqQQty?WIS1BXQ*Sy$P)K5IbJhVpEB9BF`lWijt4oWNp@PTVX#J_ zGNiRon$|#Rnnb5*VVzbBY1AF6BUMz#swofEB;jhROTkJYq0&#P@iCe#QFSGmDl;>p zkn_g1*0y!@pEyqRiu%Oo75g@m!FQdmdTj{Y0gPN z7IMrtM0h33(x@>B)gm$}RJ@bAM2N=X32RbLWHFzz5RVy?`nT74q8i3aqcEyUq(q3U zsAiE=Lq3AYZUkSd4HYG3gUDh;{%w*YpC`>?42&BMg0F@gUy9)v2{ujwjR)LNLD8xx zU7=D-R#g=uJ58DP_QtM@72j%9BZ(ABJSD~-tXWe1>*}Vo8jYf@G*VS+lvPO$P;p-d zup4tt5`zbI=F|}4L5)`HJ4~Xg6!q#V6?AQLg{0&X)O?a^#(+7k?7lEhrf-7Eg?i$2f~szU zB%LTRCyVm3CaWP@WFl5k={8MitXGn33O9N+(qjspG@6i2t0~tR#S+z4Q?^E7_Dy9+ zi?%c^*3yZT)zrVeJsOWR$vK@gt753Al$L^Q;yJ%~X|=StB3WsQsI+rIzyNtjF0vki zm9V8EY^e%cQqm#?o2>Q?uqkVQG+q`nr^tpY|JG;Pp^>Ur4TIL0X>^aWu0gxitR$vq z+hd}{X>OV*+kzw>t4LeTA;~36t>&!cu#BJ~C`qjV{huNoxT`i8tFAVh!J^qBmjNwQ zuUllj&Tr{5Ym&vPrr}W7QT(***3exB-(ZMS{&A&yz}QRfLEWL*b2>?_R&{T&bTIHJ zMJyT!`KwV3(|xLQYPJSD<%^c(X*FAeJ9W2e$i?i6M4L`TT0+Z!7Fq_-H@pl`lL(*6 z#8(SCXqFTMK26Vj60l!J6X3Fh(Gs-Uq*5Yax?g6tWP+NIEK}_&sdS;3+EN*n1YgzO zl4>m(jbr_KCN-e8a6?L_%r@Ci%D>7duWe#udxPjFq1=`gC0>?x+Nio&ZJ`=dQf9T~ zY776GV9%Ct?XZLXit)DBID8uvQnxTjhIrdb_|i6Zi>>uhVv1&EWP zAYNH+b_jtP9YG1jN)uK`SO~J(f{EZu)u@!JVHq)BQKom0(jrzFC^A3{${9tDJmaxI zYXXwN$Xps|P12=-t|VO+3w(uo$m*2+rr9Z5rD%9jntR5D!kt=ar);HWr(EH5c5SO& z1|c>7jRk5}wPeQNBv&Z-$`uAyHnJq}r8ZSYB~(TwR2H~X%_t)wrO7`{{=qn*`Utc= z5@MQ!=*RR<2&z+7lt57BP!TyQN8}VsLDQPwnX5;Egvv;PCOC$^s54ksWa9;Tr*s(# zM5%oPy_3jo){XQ|;1G12PEy24)mA!cblv_2KPm;hdn=p6^$A!=_{=g*Eg_D+2AkYB4@3JACS1d{TP&rK%Kt zQhxZ<-S|pn81rfS&<~QTRJsLUEimD)bOb&vMEy#oOYmty>-*IXt-;koEJ4F~f)<5| zRML`pCZW?GUS(2ErV)?agY^ZeAd_mw4}aCaC210# zR2vC!mr}=J`q3n95+{`=2;t*qt=zPge?xN$+Aa2# zJ^=G?rJ(R>mF?3mr%$VGU+pO%oN6<^(uqMuOmh>p`w2VIQLA^@CByitHs_N%$fqXn z({8g*`VF6Uoqf`C__X`%E5XP7sxo5&nt(Y;Gz+sn(}bPY3@Li(D|4Aomb#{v_6*Kl zsUWdPV8E25Tga?}6^2~IyhZkFKJBjhwAA-WtLfA1#HU?RpO)i(S==}aEb4#*goGX^ zVZ~+L#s)13i`I!g?aTSJUi4{e-zO!FPx?Kdv`Rj87d~m1eCjrQRckQuCZVgg0Xr2Q z?YsK4;P+|&)mQtkF~7RZ><}G|(TMJ;oA?v-=Q1;{aFM3Gu%D6^Dc60PUHh~H;!~gO ztDO+&Nr*Sv-SBCB<&*BxCuO@&vu&T0?mj8o{ZtuNYhu@)PjA%QvI=UdZfYI?ZI5an ziR!r7F1yQ)+D^MuRfeAQ?UJ{`ogDMX9x6rJCh%#U;L~=2PwNGr6zM+Ap?$S9hDsu6 zI@Dv*c7RXo0bgyBK*=uq7<|k0)`mt0m?X9ob#QIAh+f^3e?uIRM%<_QtWTP8pXRkb zX~=z=-}0(8S5+jMR8<6D>ZDb*MpsXrb+CCxbLXV0#t1J3iZ6A#YPtYB4H2qZV`v~c zYLgh7a6$UyPR9;Pf=-t-ib8j0ZgrmVE*l<(pGUS8et3D0W z7#c*BdKq@ghtl<;Q>SGIZ8j#=_7B2QXRo$_U?={A>5(dKD77fQ+HOHON?+}B!A^Xt z?g8?k^i{=$o#N9xKdJPEnDLO@)Fd1VBq?WnQ%1V8O>PmvA|vBlZnb9G(TRv|0ah6o z8|RW2d@GEm#J60z{P%}OlfSEhRBr8rjEwerWtT_>l>#w)=SBXU_p=q z?EAO1Obu2T);*Lvaw^JZksO@%R@5hCSZeE|l~FR{#A7*( zs_`c)-OThljQmi+kPCGH?eV2XIrKo`~NBfu@bMPHPbwyv#BZ5 zL3v6PbhI_rHcx8GbaAGhOm*n-lFG_Rs4_>O#062ASYa*^X^&*4Wc?zFqzacyS=xo- z8X`T|{-{QA!kNi5z4dfl9N6N~^JdbLW&ct66@i z##K3)DXkqdFk)M^{o66?wI--fo%+VsV$VLL;8CaVv29fac) z^?`z4*f6+?PpkTzsXiE0g=4$=U{^%gI@Jg2U16K1J{Wd|4QdwgIZJ+AHD<%1Fl!1A z;qb_pV>t|JKoo$P{V%CLyX`eoSFr|kT0hLK>$yU>5{%0 z)rFB}3NRI@IYSUU)cc5V;oe8syYxQ7p=<9WNy};{OjPZpQB_i5l%+aBl`1}>RPhm| zijT+&KB83d5v7WcC{=t!sp2C_6(3Qm_=r-)N0cf)qEzt_;>1UkDn6oA@e!qpk0@1q zM5*E_ z0Fs%olgxxs$xN7(%(B6i%w%XKGig*ZlfiQ`6V|ZIggua%jHLu4gXN52nF%jpmkUH} zanL}c^z^W+bz4j=9AQ^0ub9$!z#ha?Q?i&^n8IDH%wi=`7hSS!NDXj1-13{IDy@cHgiU%uEUhd6U=1Q zvF!db?R;pBF*j_iQ#;OqXI9S=O~f&O5XW>OtO>5%P!J|L2T717IT1~|a=%3QIGBn| z$TYP~!vYJ7FKMi!2$ zm9`|_*{Xuqw@gzxtcWF)OJ{36xE_EvLu85ZKq zMZ_`nutlXn!4!{Peehn11) z8LE`7K3)||($(;gmc2DHUJs8{mYb>bDcs=>i-u5G4Wzf}Kp93!rXX?Zv>Z zdY%}m<8aVll8Y&&dOW7iv*WACR;g`^c!}CCg|KOvst&&3JdRS((dJn^NyVB}*Ti5~ zEjdZq!Erd59&K*HUv=wArMQD#rJGdO$l^(=E=jem0lUgiQt5wTS4ERldS2L7wIcm3 z?3BLJ{sEQ<&`W^17c#=x}4tsfb zwPX?V+WxAh*B8mf3T7XH1I;+H_HJ24WDufA&Q(KEx~b`C$fZCjPqH!2>=d0hG<}q6 zcZ~QGux3Zq44kt1GT8#_NgJgsIc=1(2Wlo|^Au4rg_Q*wr>;6)QC^_Df>p8fu1u7x zez3DONSk^pbjg8Bq3CJRH3xPTLiMUDRn;?6w@6O8-YJOJGu%rBjxG-DiD4BZ84l8s z38(PLg!6P{N@q=e)-)(EMR3nAFuQ}ZrXg9=v02k`SyN5cbbQt{G;11`H4V?2PRN=@ zWKAQprcqhb=&b3)tm&kzX-w91a@KT8V9Ha~Qe|3dpGg1_xyn-R`Lw!HHl>WFV0lu{ z9mJ8flj6|om~3)#mrYbvTICgP7(^%6Fvua>FvuQi7(tY5!w7=p8V0!p4I_w=Z5ZSb zZWuun(!G&YH4L(38wS~_VFW?ds*Z9`3p-^inh4FgY>^bUC}<;rd;OU4<$}dqGw#WmjqURU4+)50J+zr@JEFu}Yt(x`!|9ZU zsg;JQsdMdR1*89-qgYC|M`EZfM-K-fW#g1Su*k+4SY#hTanfNy`eE+M!aS5IDHLRH zqJ^?i9?oESI2+|*Ig~4U1tE#ufE~Ocyo^b61=~RH|~tj$2HM$HLsro>0gxJjcUq#ub}F zO)XkdW0zzVOSldbh(cU*Q5L!zBP~L?O%)xdG{a0KR8rY%8dMS0kQ7+L5t3nfVjnG_ zi$zqpCMUyXK()W1L9$)sir)B{|aQ1;W%y!>pEu zSuG7`4`XNge|!O z!3EM#JxGS@K{7mx!7~FP0_kv^bg1s&xZzU)4mJGx-ukC}4PaN~Us^0^H>a z9*3oJbrF_a^@AlGhw29?jl7N2-3C#a87Yn|m94`Aem zTUc^3#WBOMPq-h!0YpilAiHNSt-%h0sJXdGvM`DhL&CM|e7P(?1Eo5+Ygf@p10e$9 zlmMw8gsq3#&JkK@sHf^>Xd#ziu3gqcZSITXNMd_m2EgWyNLHvkRodCpP133q?>IdY z*hFBmb<0ib$)$UU7&*y;iBo;({(q8gs7N8u(EPx!4%OuZ&asG$N}35gFp{%`rf1NX zdeXuiDTeQ2N>O*cb1UQJ2b&er)(z^X>_H0Y zvKw@!LT}mFF6)-q-;nOz5e!;Y?5t#+ddgiAxJ#F&IvK7=-fet>lCfSF}l*CJXHDcM2##46)=&jRnb^zW)j8TT`m}{!&QZig(f{w zx|}M9uE3J(M?f+}h1TJU3a!Hfi(*6an_Y)f`=DjrKdgDnvy1Lv&6{%x7TM*0Uxt@s z%S;~r!I?xfg7Te~;S?jh3@`u3Ww_iUqA+^TQ7@hLPm?*TKuq%4;ST!GVta7R@GiuOK$WqCN4KYRqw~1oqN#{fyh;7FX zDL;9HGo`M!HBjY)8L8UFOi^ww;;Wd9tE;1!+)7nACP#7y7GJ5V$2YC6npI#0V&lXS z4q0{J45IuB>h6Tv2{Yu`ZKtli1DgkR4X(U=Av_Iq3sWVt@!-*h@=`C;-q6(2(wg<6 zQ_0wyQ9;$E1zg`%a*3}s`(AB__RLYq|`6dF%f=Sq8>Zol(kJJkJbn9xx zrO=&Rz)LvFP66Nx7ezakiku;CfS_Xo;k?OWd$hR;7e5>8Ty^aL&SsN%*+E8#RpK(Q zIGe97k|-i2NpX0;skWoBIU?`HLZEcf8aHWGNyXHGXk=S%GN78s5`w?nBtQwuO$1y~ zr)r|^pQ9wHWa(ynJb2)P?q8+pMYJ@%gqBu^=^<^I4!&v=1Jxa6%xvKJw zT5*>RM}g`L94x6b&~)mAUp$ISCTb{;8Lf@28C(2;xIFq&eXT6>eQ$)QB{+nXX_I72 z(j}g}7c8ATDVm&blAh8?s$DTC+LR=cRAG|z%u`amvVc2Ns;(#1ts2;sWRmm@RFbaW z(Kbz#wrB8_+gkV%{ovgobu$j`vTfk28fucB0ZOVHD$!(c&01|Z zt%hU$WLMi(xIUmd2-=>4U2Z#xNv@O<=C|~vc=XIwQr)V6TvUxn`sA;63vvFH;;GXa z2&ZaVk{Vc&YEV+$qQ-TBAfLpK+NMIjDPC|3THO?cyQ-;4bu$ohpm^#|F0Nas2ArfC znWP$?ROj;{2MSN;?rGZ&`493-@q_2=)Hb4+UMqRv)fmxnCh3k(Qr+F z$Uo6jH6HR&=_g3Ov^$EsLMmQ@Jl7U?|YJ6pm@ufX!x{DH1jS}v%(&8%{2fniK@s*7VU$wUzQ)LIclpMZN za`*<_BBi6cV@!l(CxJsVGJIu)x~Pc<4ODpaI+E|G>ZY+|ktK|8lx`kiJkJZysVTTh zHmY6|5i1>X56F_gx^squ(L|O`UPbBTRkWm}07tDm8tZDsc!h4*QJYia#^ozRvv^0N zc5*(70NcBDEhq={)pA4+b-m^BJZu1G+G?A`fH%1?Y{3Ly@P>9$irWqCA}Mk1xgcZ) zNf{)rcHEw?PY<2N=~)1*w-g<^6C9^I!tvmxzu>8l;DIu_ zp&h5ko#MeOOw?7zsVj)nP!bQONz^sO=~8i=Zk)yG+F+czggA8xaq2?isib;Q2#fr> zW-{VbOkl*Bn81jGGl3BYYUFtj+-X%kYdn=!%gc(A+)3;hj;hE5Uh-rAj)^UHMATSeBr^J3(Vwg8J|Tjcp0)%M&!lC8$qN&{&tCzCA%>UV?6ar|5mw z6m>)?dipR$Z=a;-R%VKxKupmaC@FdhF-32or07Y+6upU(qNfp4^fpS0?nI{OPGpMi zM5d^tOVJBA~fsI$2X$s%A^k z1kJ7z!4oU=RFpYr9?n=wA+&!_h%pd%0!9Pwp)Mn^8& zJLnQUnj=7CpxPWg{gqIM0iy|;10~ccBiJkR#dNiHLd#TnI#I=wc(1pqb%{3ErQ87XFH9;2=6LcXlK^GAdbP+K@7Zek8;V?lL4ij|YFhLK9 zB~&jKO$4==W-1A~fS927Ruc56RD#}SOVF!O30g`dXep7PSG*E5lS$CbCP5E5B-GK$ zXhI#-!Iy?#I;aDMi!6;49T(f1)=N$TZb6n&qp zeQ|obD^AyA<21jGE3Tt)nyyg6Q-cA78`5#ye# zlqtaw6{o3XoaRGuI>`mb>CK+XapIf>S=3{!yQ&9!;LXa91iWEjZ{F+*FnOAuYTkUA_&G^ajmsw-%!ZNqs(aSu*pZ#Qrv@-Mj!h01Z;S=TMc2n8#o`-bum8q~~kxJQTEzq3xt8tc&h zLhunGCv?a_MK%LcRXVO&p3%YF3q8J{?k^pc4V!o&8+H>yw(2e+vB44cLz?0j7!(z3 zJcMj`^herU`4{F^YNe$RZNAKGP`UG^fC8ICPybW~hGBtWbYQ3r44J^t5*TK96deyL znDkz`GA~9H8vqS>G*GwM{NVveawH9g?nI1Vnm)6!I93tW^4T_%^bZo+-FtCt3vvvxc zuUb@K!wf)8@MS7l8%6FR9(58tH`F#wq$oIG-aJV)(41pLI8p#?=+sWa^;ELv$u@!) z6-5fl5(LaGFN7a9Hbbio;o?k(#D$?y)sXBKK}0rn$QN}qXGRkfY{;! z500I6-4(y`r&dJTf|9&jOS}}IOGR$5H8e@`7z_d31H(8WuyMjaUmbg+>=vR!o-8g5 zgzX|M*^7k#|JB*mJvVV(@w@t1`2!ncTZUu_xym9#t(9;Z0uC`o>`FG^CXtPyyCi{K zOQuajARjbw+q4O^X{j>pdtW+}_fF@moKBrS@zy-^FLb8UcG^rH`Wm~xb5|?NV7JrY z8QtH#=XcLN=iGD8mGD@r0^1%K-~s%mF8W=`kg|&}jkY2E@q(x=QJKO2x#P^LKX`iw zU%+-7g28KQnxf*a-5$vLP5fmbPK}C~@--gWDsu5iq=w^Bzd5#bKDwuN4R_DaZm~Iw z+v{|ZyH$@s{6-Lc%aw`+mK*IJ<1dq0!Qj5w`)jeQqp#n>7o)$1ukqu{k^>9cP8Uf1 z<|BJtzsXOG*MzpYiDy-Q-G86rDVU##Ptp&BNL>|T<7)b^oBvGR*!jHKy*Kn^T^ho3v*4xTiAdgH-YUnHKhJNm{`>U5l6Moo)&G+Ick;c& zZ?^Oa!TRFW^kjRzj=qft9i2TJpSSgXv86Y8x1)PKxf<&yVM!8~+^Q$#{JI!im?!<> z6_<`1bky^&%jPAQ68YdWJZ(?Z>*lhN%aQO%IA*1VI6A&vB+Vk}UoTR^GIM6GNJ&dJ z){>)HVLLS9NZ+@^#HeG3`J_V$XK7W^9uvR`8kDN7wi1a1)KG5aV2(#ygIUc!C;?5o zHKL6`W|FA6D_(0%V`h<379|UmbzEML#vG?jFl0m0{Tijlue6S815UMGCB5qAD4F*b zUv@z@ny#c;4MSzmkTk_;%JXCxv0>3s47GcbCRsko%=uIsAfW4?Nj`Kc?*! zDQ(HBq*OkDPZ_7?QpU8Y$F#8nnBo^nSK&q^WFyQh+meOst`V8fuaxntbxKd;JCC+DN@FwUZ>C!iD;X9&^2un>0;UeC6=#~ zR)-;!nJ7}PCE40RxRnyipupa;?=i)%C~NzyR_~y2s`f;#lQ{j>_C(qfY0(NW!GY_( ztTxSnH&q2&7`!1Q4Hy|)iLEt*O0>klF4O5SW?^#2weCrSod2f1Hn2w|tJosL%y|lQR%iBKe}OD+wYwye@1(r>^-%GuKY2R zJ}wwfA-%`oW42JF{Z^=PdjRp~_Ax6=a{IUyrnoh%FwN~jE7ZAt!U{9o9JpB1gl|Q{VwZ5dBYZm&N=wk*!mfV8sXs)nvY*}l z<=~%$T~EP3ZcX^d?P2)GZ65w{I}ZQ2Jp%u@JqrK0{RaHwb^`u!Te9S|I!MPX>C*vU zqUdQp=R|;(N}RKk79A_lF`UPzaTMl|u{$0}Gng{Du>V&E(y>V2jJG%()T^9v^z=lS z*0NO>MUi*$nXd5c#yM`uXO-p8LR+M#`e>Oz_1V!{9v5Sus;jy(V@`#~wJiI30`Y(Y zJI?WOSc0h{owQ2(r;9Z8zoq zb`%jlh1xYn`$0>goaPlR+#_u2cM2=bk}2hM6FQ&YPLribAL*tYvnBalQ_2hOT1uv+ zv6dQ7KknIFY5P#Lu|6y?XMNJK+uM&TPL@`PZl#ptH%v<7Qbn;#Ie`J}d#Dc&&k0}} z>c2S~Oc^Ftn1!Ec)GE-o!y+(*OR|n4g3U-H;c$aIWC=6|d|R;*NxZfz>DF3EmgzVa z5*DP#+p#dG5vJ1}5%r;%NI7fH@uIwoGqFrL6GfWDl3S9~xX{`9L^KGcovk1}kKTER zI`3VgO?))-e6zhVyVdTyr#`#M?7@#Z=PJ;6- zi=IRC0!OimaLZX-!f~`-v^b&Z1%&w}t0lxNKn*}+uwb<`HL?hxMlLdE4x%OIFu24V z2A7$`;M>+3s-Xkq0^x24@~ky28oL4%jlIk~jis+JPoY*~RE}Wf!9x$}UE4D7zTl zRCY1Cg&0qFHthR+%p}0AE}JQz1z+auiwyL(O*p2spEP+t%e8fv%OE0A1i0e!{xo@{&MEN$cTRMvk-{# zwjUOJCXzx_!o%9V1$>0K=eGMtxxd~c;sMVHkMPi+dOj3ds(i1$)Mnx{nCF#;-qo+` hm-P#&nN&%a>CE87y0-ZdrGAAQzOt5X=%P{){{cdCT{-{& diff --git a/Extern/imgui/Inter-Regular.ttf b/Extern/imgui/Inter-Regular.ttf deleted file mode 100644 index b7aaca8de1fe458399e17311d35d543a1fa2f984..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 411640 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 diff --git a/Extern/imgui/License-Inter.txt b/Extern/imgui/License-Inter.txt deleted file mode 100644 index 9b2ca37b3..000000000 --- a/Extern/imgui/License-Inter.txt +++ /dev/null @@ -1,92 +0,0 @@ -Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter) - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION AND CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/OVP/D3D9Client/D3D9Config.h b/OVP/D3D9Client/D3D9Config.h index c23be7f34..8f10ce7f2 100644 --- a/OVP/D3D9Client/D3D9Config.h +++ b/OVP/D3D9Client/D3D9Config.h @@ -54,7 +54,7 @@ class D3D9Config { double Separation; ///< StereoScopic 3D depth of field separation \[m\] (10.0...100.0, default=65) double SunAngle; ///< Sun-angle above horizon when night-lights set it \[deg\] (0.1...20.0, default=10) double BumpAmp; ///< Bump map amplification setting (0.1...10.0, default=1) - double PlanetGlow; ///< Intensity of planet glow effect (0.01...2.0, default=0.7) + float PlanetGlow; ///< Intensity of planet glow effect (0.01...2.0, default=0.7) double FrameRate; ///< Frame-rate limiter double OrbitalShadowMult; ///< Multiplier for cloud shadows for Orbital flight int EnableLimiter; ///< Enable frame-rate limiter @@ -100,13 +100,13 @@ class D3D9Config { int NoPlanetAA; ///< Disable planet surface anti-aliasing to prevent white pixels at horizon char *DebugFont; ///< Font face for debug lines (default="Fixed") char *SolCfg; ///< Solar system to use (default="Sol") - double GFXIntensity; ///< Post Processing | Light glow intensity (0.0...1.0, default=0.5) - double GFXDistance; ///< Post Processing | Light glow distance (0.0...1.0, default=0.8) - double GFXThreshold; ///< Post Processing | Glow threshold (0.5...2.0, default=1.1) - double GFXGamma; ///< Post Processing | Gamma (0.3...2.5, default=1.0) - double GFXSunIntensity; ///< Light Configuration| Sunlight Intensity (0.5...2.5, default=1.2) - double GFXLocalMax; ///< Light Configuration| Local Lights Max (0.001...1.0, default=0.5) - double GFXGlare; ///< Sun glare intensity| (0.001...1.0, default=0.5) + float GFXIntensity; ///< Post Processing | Light glow intensity (0.0...1.0, default=0.5) + float GFXDistance; ///< Post Processing | Light glow distance (0.0...1.0, default=0.8) + float GFXThreshold; ///< Post Processing | Glow threshold (0.5...2.0, default=1.1) + float GFXGamma; ///< Post Processing | Gamma (0.3...2.5, default=1.0) + float GFXSunIntensity; ///< Light Configuration| Sunlight Intensity (0.5...2.5, default=1.2) + float GFXLocalMax; ///< Light Configuration| Local Lights Max (0.001...1.0, default=0.5) + float GFXGlare; ///< Sun glare intensity| (0.001...1.0, default=0.5) std::map AtmoCfg; diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 0b904b2c9..828323d06 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -70,27 +70,20 @@ class GFXDialog: public ImGuiDialog ImGui::PushItemWidth(150.0); ImGui::SeparatorText("Post Processing Configuration"); - auto min = 0.0; auto max = 1.0; auto def = 0.5; - ImGui::SliderScalarReset("Light glow intensity", ImGuiDataType_Double, sizeof(double), &Config->GFXIntensity, &min, &max, &def, "%1.2f"); - min = 0.0; max = 1.0; def = 0.8; - ImGui::SliderScalarReset("Light glow distance", ImGuiDataType_Double, sizeof(double), &Config->GFXDistance, &min, &max, &def, "%1.2f"); - min = 0.5; max = 2.0; def = 1.1; - ImGui::SliderScalarReset("Glow threshold", ImGuiDataType_Double, sizeof(double), &Config->GFXThreshold, &min, &max, &def, "%1.2f"); - min = 0.3; max = 2.5; def = 1.0; - ImGui::SliderScalarReset("Gamma", ImGuiDataType_Double, sizeof(double), &Config->GFXGamma, &min, &max, &def, "%1.2f"); + + ImGui::SliderFloatReset("Light glow intensity", &Config->GFXIntensity, 0.0f, 1.0f, 0.5f, "%1.2f"); + ImGui::SliderFloatReset("Light glow distance", &Config->GFXDistance, 0.0f, 1.0f, 0.8f, "%1.2f"); + ImGui::SliderFloatReset("Glow threshold", &Config->GFXThreshold, 0.5f, 2.0f, 1.1f, "%1.2f"); + ImGui::SliderFloatReset("Gamma", &Config->GFXGamma, 0.3f, 2.5f, 1.0f, "%1.2f"); ImGui::SeparatorText("Light Configuration"); - min = 0.5; max = 2.5; def = 1.2; - ImGui::SliderScalarReset("Sunlight Intensity", ImGuiDataType_Double, sizeof(double), &Config->GFXSunIntensity, &min, &max, &def, "%1.2f"); - min = 0.01; max = 2.0; def = 0.7; - ImGui::SliderScalarReset("Indirect Lighting", ImGuiDataType_Double, sizeof(double), &Config->PlanetGlow, &min, &max, &def, "%1.2f"); - min = 0.001; max = 1.0; def = 0.5; - ImGui::SliderScalarReset("Local Lights Max", ImGuiDataType_Double, sizeof(double), &Config->GFXLocalMax, &min, &max, &def, "%1.2f"); - min = 0.001; max = 1.0; def = 0.5; - ImGui::SliderScalarReset("Sun Glare Intensity", ImGuiDataType_Double, sizeof(double), &Config->GFXGlare, &min, &max, &def, "%1.2f"); + ImGui::SliderFloatReset("Sunlight Intensity", &Config->GFXSunIntensity, 0.5f, 2.5f, 1.2f, "%1.2f"); + ImGui::SliderFloatReset("Indirect Lighting", &Config->PlanetGlow, 0.01f, 2.0f, 0.7f, "%1.2f"); + ImGui::SliderFloatReset("Local Lights Max", &Config->GFXLocalMax, 0.001f, 1.0f, 0.5f, "%1.2f"); + ImGui::SliderFloatReset("Sun Glare Intensity", &Config->GFXGlare, 0.001f, 1.0f, 0.5f, "%1.2f"); - if(ImGui::Button("Recreate Sun/Glares")) { + if(ImGui::Button("Recrete Sun/Glares")) { g_client->GetScene()->CreateSunGlare(); } ImGui::PopItemWidth(); diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index f3cce81ac..fd5b612b6 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -388,72 +388,6 @@ class Sketchpad; class ParticleStream; class ScreenAnnotation; -class OAPIFUNC ImCtxBase; -class OAPIFUNC WithImCtx; - -class OAPIFUNC ImCtxBase { - public: - virtual ~ImCtxBase(); - - ImCtxBase(const ImCtxBase &) = delete; - - ImCtxBase &operator=(const ImCtxBase &) = delete; - - [[nodiscard]] ImFont *DefaultFont() const { return m_defaultFont; } - [[nodiscard]] ImFont *ItalicFont() const { return m_italicFont; } - [[nodiscard]] ImFont *BoldFont() const { return m_boldFont; } - [[nodiscard]] ImFont *BoldItalicFont() const { return m_boldItalicFont; } - [[nodiscard]] ImFont *HdgFont() const { return m_hdgFont; } - [[nodiscard]] ImFont *MonoFont() const { return m_monoFont; } - [[nodiscard]] Orbiter *App() const { return m_app; } - - WithImCtx PushLocal(); - protected: - friend WithImCtx; - ImCtxBase(Orbiter* app, ImGuiContext* context); - Orbiter *m_app; - ImGuiContext *m_context; - ImFont *m_defaultFont; - ImFont *m_italicFont; - ImFont *m_boldFont; - ImFont *m_boldItalicFont; - ImFont *m_hdgFont; - ImFont *m_monoFont; - - virtual bool ConsumeEvent(const SDL_Event &event, bool &wantsOut) = 0; - - [[nodiscard]] virtual bool BeginFrame() = 0; - - virtual void EndFrame() = 0; -}; - -class OAPIFUNC WithImCtx { - public: - - WithImCtx &operator=(const WithImCtx &) = delete; - - ~WithImCtx(); - - ImCtxBase *operator->() const; - - [[nodiscard]] ImCtxBase *Inner() const; - - bool ConsumeEvent(const SDL_Event &event, bool &wantsOut) const; - - [[nodiscard]] bool BeginFrame() const; - - void EndFrame() const; - - protected: - WithImCtx(const WithImCtx &) = default; - - private: - friend ImCtxBase; - WithImCtx(ImCtxBase *inner, ImGuiContext *lastContext); - ImCtxBase *inner; - ImGuiContext *lastContext; -}; - // ====================================================================== // class GraphicsClient // ====================================================================== @@ -2129,4 +2063,4 @@ OAPIFUNC bool oapiRegisterGraphicsClient (oapi::GraphicsClient *gc); OAPIFUNC bool oapiUnregisterGraphicsClient (oapi::GraphicsClient *gc); -#endif // !__GRAPHICSAPI_H +#endif // !__GRAPHICSAPI_H \ No newline at end of file diff --git a/Orbitersdk/include/imgui_extras.h b/Orbitersdk/include/imgui_extras.h index cb9b7b4fa..95b0aa86c 100644 --- a/Orbitersdk/include/imgui_extras.h +++ b/Orbitersdk/include/imgui_extras.h @@ -13,7 +13,6 @@ enum class ImGuiFont { namespace ImGui { OAPIFUNC bool SliderFloatReset(const char* label, float* v, float v_min, float v_max, float v_default, const char* display_format = "%.3f"); - OAPIFUNC bool SliderScalarReset(const char* label, ImGuiDataType dtype, size_t t_size, void* v, const void *v_min, const void *v_max, const void *v_default, const char* display_format = "%.3f"); OAPIFUNC void HelpMarker(const char* desc, bool sameline = true); OAPIFUNC void BeginGroupPanel(const char* name, const ImVec2& size = ImVec2(-1.0f, -1.0f)); OAPIFUNC void EndGroupPanel(); diff --git a/Src/Orbiter/Config.cpp b/Src/Orbiter/Config.cpp index 9758c63ba..0a37e604c 100644 --- a/Src/Orbiter/Config.cpp +++ b/Src/Orbiter/Config.cpp @@ -229,7 +229,7 @@ CFG_FONTPRM CfgFontPrm_default = { 1.0f, // dlgFont_Scale (scaling factor for inline dialog fonts) "Arial", // dlgFont1_Face (default dialog font face name) 14.0f, // ImGui_FontSize - "Inter" // ImGui_FontFile + "Roboto-Medium.ttf" // ImGui_FontFile }; CFG_CAMERAPRM CfgCameraPrm_default = { @@ -775,7 +775,7 @@ bool Config::Load(const char *fname) if (GetReal (ifs, "DialogFont_Scale", d)) CfgFontPrm.dlgFont_Scale = (float)d; GetString (ifs, "DialogFont1_Face", CfgFontPrm.dlgFont1_Face); if (GetReal (ifs, "ImGui_FontSize", d)) CfgFontPrm.ImGui_FontSize = (float)d; - GetString (ifs, "ImGui_FontName", CfgFontPrm.ImGui_FontName); + GetString (ifs, "ImGui_FontFile", CfgFontPrm.ImGui_FontFile); // misc. options if (GetString (ifs, "LPadRect", cbuf)) { @@ -1356,8 +1356,8 @@ BOOL Config::Write (const char *fname) const ofs << "DialogFont1_Face = " << CfgFontPrm.dlgFont1_Face << '\n'; if (CfgFontPrm.ImGui_FontSize != CfgFontPrm_default.ImGui_FontSize || bEchoAll) ofs << "ImGui_FontSize = " << CfgFontPrm.ImGui_FontSize << '\n'; - if (strcmp (CfgFontPrm.ImGui_FontName, CfgFontPrm_default.ImGui_FontName) || bEchoAll) - ofs << "ImGui_FontName = " << CfgFontPrm.ImGui_FontName << '\n'; + if (strcmp (CfgFontPrm.ImGui_FontFile, CfgFontPrm_default.ImGui_FontFile) || bEchoAll) + ofs << "ImGui_FontFile = " << CfgFontPrm.ImGui_FontFile << '\n'; } if (memcmp (&CfgWindowPos, &CfgWindowPos_default, sizeof(CFG_WINDOWPOS)) || bEchoAll) { diff --git a/Src/Orbiter/Config.h b/Src/Orbiter/Config.h index ebfec9a0f..a7fa77420 100644 --- a/Src/Orbiter/Config.h +++ b/Src/Orbiter/Config.h @@ -255,11 +255,10 @@ struct CFG_DEMOPRM { }; struct CFG_FONTPRM { - float dlgFont_Scale; // font scaling factor - char dlgFont1_Face[64]; // dialog font face name - float ImGui_FontSize; // Font size for ImGui dialogs - char ImGui_FontName[256]; // Font name (file: `{FontName}-{Weight}.ttf`) where - // Weight is `Regular`, `Italic`, `Bold`, or `BoldItalic` + float dlgFont_Scale; // font scaling factor + char dlgFont1_Face[64]; // dialog font face name + float ImGui_FontSize; // Font size for ImGui dialogs + char ImGui_FontFile[256]; // Font file for ImGui default font }; struct CFG_CAMERAPRM { @@ -316,7 +315,7 @@ bool GetItemVector (std::istream &is, const char *label, Vector &val); bool GetItemVECTOR (std::istream &is, const char *label, VECTOR3 &val); bool FindLine (std::istream &is, const char *line); -// scans stream 'is' from beginning for a line beginning with 'line' +// scans stream 'is' from beginning for a line beginning with 'line' // and leaves file pointer on the beginning of the next line // return value is false if line is not found @@ -491,4 +490,4 @@ GDIResources *g_gdires = 0; extern GDIResources *g_gdires; #endif -#endif // !__CONFIG_H \ No newline at end of file +#endif // !__CONFIG_H diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index a9812d3be..f893ffd55 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -53,7 +53,7 @@ static DIALOGENTRY *de_create = 0; // ================================================================== // class DialogManager -DialogManager::DialogManager (Orbiter *orbiter, HWND hAppWnd) : ImCtxBase(orbiter, ImGui::CreateContext()) +DialogManager::DialogManager (Orbiter *orbiter, HWND hAppWnd) { pOrbiter = orbiter; gc = orbiter->GetGraphicsClient(); @@ -433,11 +433,101 @@ const ImWchar* GetGlyphRangesOrbiter() return &ranges[0]; } +// Styling adapted from https://gist.github.com/dougbinks/8089b4bbaccaaf6fa204236978d165a9 +static void ImGuiSetStyle(bool bStyleDark_, float alpha_) +{ + // Setup Dear ImGui style + ImGui::StyleColorsClassic(); + ImGui::StyleColorsLight(); + ImGuiStyle& style = ImGui::GetStyle(); + + style.Alpha = 1.0f; + style.FrameRounding = 3.0f; + style.WindowRounding = 3.0f; + style.ChildRounding = 3.0f; + style.PopupRounding = 3.0f; + style.ScrollbarRounding = 3.0f; + style.GrabRounding = 3.0f; + style.TabRounding = 3.0f; + style.WindowMenuButtonPosition = ImGuiDir_Right; + return; + // light style from Pacôme Danhiez (user itamago) https://github.com/ocornut/imgui/pull/511#issuecomment-175719267 + style.Colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + style.Colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 0.94f); + style.Colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f); + style.Colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.39f); + style.Colors[ImGuiCol_BorderShadow] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f); + style.Colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f); + style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + style.Colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f); + style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f); + style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f); + style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f); + style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f); + style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 1.00f); + style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.59f, 0.59f, 0.59f, 1.00f); + style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f); + style.Colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); + style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + style.Colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + style.Colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); + style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + style.Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.50f); + style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + style.Colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + + if( bStyleDark_ ) + { + for (int i = 0; i <= ImGuiCol_COUNT; i++) + { + ImVec4& col = style.Colors[i]; + float H, S, V; + ImGui::ColorConvertRGBtoHSV( col.x, col.y, col.z, H, S, V ); + + if( S < 0.1f ) + { + V = 1.0f - V; + } + ImGui::ColorConvertHSVtoRGB( H, S, V, col.x, col.y, col.z ); + if( col.w < 1.00f ) + { + col.w *= alpha_; + } + } + } + else + { + for (int i = 0; i <= ImGuiCol_COUNT; i++) + { + ImVec4& col = style.Colors[i]; + if( col.w < 1.00f ) + { + col.x *= alpha_; + col.y *= alpha_; + col.z *= alpha_; + col.w *= alpha_; + } + } + } +} + void DialogManager::InitImGui() { if(!gc) return; - WithImCtx _ = PushLocal(); + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); // Viewports don't play nice when in full screen mode if(!pOrbiter->IsFullscreen()) @@ -446,7 +536,23 @@ void DialogManager::InitImGui() //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls //io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; - ImGui_ImplSDL3_InitForOther(g_pOrbiter->GetRenderWnd()->Inner()); + ImGuiSetStyle(true, 1.0f); // Dark, alpha + + ImFontConfig config; + + static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; + ImFontConfig icons_config; + icons_config.MergeMode = true; + icons_config.PixelSnapH = true; + icons_config.FontDataOwnedByAtlas = false; + + const CFG_FONTPRM &prm = g_pOrbiter->Cfg()->CfgFontPrm; + defaultFont = io.Fonts->AddFontFromFileTTF(prm.ImGui_FontFile, prm.ImGui_FontSize, &config, ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, &icons_config, icons_ranges); + monoFont = io.Fonts->AddFontFromFileTTF("Cousine-Regular.ttf", prm.ImGui_FontSize, &config, ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + io.Fonts->Build(); + + ImGui_ImplSDL3_InitForOther(g_pOrbiter->GetRenderWnd()->Inner()); gc->clbkImGuiInit(); } @@ -454,9 +560,9 @@ void DialogManager::ShutdownImGui() { if(!gc) return; - WithImCtx _ = PushLocal(); gc->clbkImGuiShutdown(); - ImGui_ImplSDL3_Shutdown(); + ImGui_ImplSDL3_Shutdown(); + ImGui::DestroyContext(); } static bool EventIsKeyboard(Uint32 type) { @@ -470,64 +576,52 @@ static bool EventIsMouse(Uint32 type) { bool DialogManager::ConsumeEvent(const SDL_Event &event, bool &wantsOut) { bool consumed = false; - WithImCtx _ = PushLocal(); ImGui_ImplSDL3_ProcessEvent(&event); ImGuiIO &io = ImGui::GetIO(); if ((io.WantCaptureMouse && EventIsMouse(event.type)) || (io.WantCaptureKeyboard && EventIsKeyboard(event.type))) { consumed = true; } - // close requested are ignored TBD, until this uses Win32 + // close requested are ignored TBD, until this doesn't use Win32 return consumed; } -bool DialogManager::BeginFrame() { - WithImCtx _ = PushLocal(); - gc->clbkImGuiNewFrame(); - ImGui_ImplWin32_NewFrame(); - ImGui::NewFrame(); - - //ImGui::ShowDemoWindow(); - - // Render notifications - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.f); // Round borders - // ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(43.f / 255.f, 43.f / 255.f, 43.f / 255.f, 240.f / 255.f)); // Background color - RenderNotifications(); // <-- Here we render all notifications - ImGui::PopStyleVar(1); // Don't forget to Pop() - // ImGui::PopStyleColor(1); - - // We can't use a range-based loop here because Show() may unregister the current dialog - for (auto it = DlgImGuiList.begin(); it != DlgImGuiList.end();) - { - auto current = it++; - if ((*current)->IsActive()) { - (*current)->Display(); - } - } - return true; -} - -void DialogManager::EndFrame() { - WithImCtx _ = PushLocal(); - ImGui::EndFrame(); -} - void DialogManager::ImGuiNewFrame() { if(!gc) return; - WithImCtx _ = PushLocal(); - if (BeginFrame()) { - EndFrame(); - } + + gc->clbkImGuiNewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + //ImGui::ShowDemoWindow(); + + // Render notifications + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.f); // Round borders + // ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(43.f / 255.f, 43.f / 255.f, 43.f / 255.f, 240.f / 255.f)); // Background color + RenderNotifications(); // <-- Here we render all notifications + ImGui::PopStyleVar(1); // Don't forget to Pop() + // ImGui::PopStyleColor(1); + + // We can't use a range-based loop here because Show() may unregister the current dialog + for (auto it = DlgImGuiList.begin(); it != DlgImGuiList.end();) + { + auto current = it++; + if ((*current)->IsActive()) { + (*current)->Display(); + } + } + + ImGui::EndFrame(); } ImFont *DialogManager::GetFont(ImGuiFont f) { switch(f) { - case ImGuiFont::MONO: return MonoFont(); - case ImGuiFont::DEFAULT: return DefaultFont(); - default: return DefaultFont(); + case ImGuiFont::MONO: return monoFont; + case ImGuiFont::DEFAULT: return defaultFont; + default: return defaultFont; } } @@ -814,38 +908,6 @@ namespace ImGui { return ret; } - DLLEXPORT bool SliderScalarReset(const char* label, ImGuiDataType dtype, const size_t t_size, void* v, const void *v_min, const void *v_max, const void *v_default, const char* display_format) - { - bool ret = ImGui::SliderScalar(label, dtype, v, v_min, v_max, display_format); - if (ImGui::BeginPopupContextItem(label)) - { - char buf[64]; - char fmt[64]; - snprintf(fmt, 64, "Reset to %s", display_format); - if (dtype == ImGuiDataType_S32 || dtype == ImGuiDataType_U32) - snprintf(buf, 64, fmt, *(const ImU32*)v_default); - if (dtype == ImGuiDataType_S64 || dtype == ImGuiDataType_U64) - snprintf(buf, 64, fmt, *(const ImU64*)v_default); - if (dtype == ImGuiDataType_Float) - snprintf(buf, 64, fmt, *(const float*)v_default); - if (dtype == ImGuiDataType_Double) - snprintf(buf, 64, fmt, *(const double*)v_default); - if (dtype == ImGuiDataType_S8) - snprintf(buf, 64, fmt, *(const ImS8*)v_default); - if (dtype == ImGuiDataType_U8) - snprintf(buf, 64, fmt, *(const ImU8*)v_default); - if (dtype == ImGuiDataType_S16) - snprintf(buf, 64, fmt, *(const ImS16*)v_default); - if (dtype == ImGuiDataType_U16) - snprintf(buf, 64, fmt, *(const ImU16*)v_default); - if (ImGui::MenuItem(buf)) - memcpy(v, v_default, t_size); - ImGui::MenuItem("Close"); - ImGui::EndPopup(); - } - return ret; - } - DLLEXPORT void PushFont(ImGuiFont f) { ImGui::PushFont(g_pOrbiter->DlgMgr()->GetFont(f)); diff --git a/Src/Orbiter/DlgMgr.h b/Src/Orbiter/DlgMgr.h index 43bd9ee71..45b50c1a4 100644 --- a/Src/Orbiter/DlgMgr.h +++ b/Src/Orbiter/DlgMgr.h @@ -22,10 +22,10 @@ struct DIALOGENTRY { struct DIALOGENTRY *prev, *next; }; -class DialogManager : public oapi::ImCtxBase { +class DialogManager { public: DialogManager(Orbiter *orbiter, HWND hAppWnd); - ~DialogManager() override; + ~DialogManager(); void Init (HWND hAppWnd); void Clear (); @@ -222,15 +222,12 @@ class DialogManager : public oapi::ImCtxBase { void ImGuiNewFrame(); ImFont *GetFont(ImGuiFont f); + bool ConsumeEvent(const SDL_Event &event, bool &wantsOut); private: void InitImGui(); void ShutdownImGui(); -protected: - friend Orbiter; - // this only handles event handling for the case where WinAPI is *not* used. - bool ConsumeEvent(const SDL_Event &event, bool &wantsOut) override; - bool BeginFrame() override; - void EndFrame() override; + ImFont *defaultFont; + ImFont *monoFont; }; INT_PTR OrbiterDefDialogProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); diff --git a/Src/Orbiter/GraphicsAPI.cpp b/Src/Orbiter/GraphicsAPI.cpp index 89d044c99..f9b862b5d 100644 --- a/Src/Orbiter/GraphicsAPI.cpp +++ b/Src/Orbiter/GraphicsAPI.cpp @@ -866,6 +866,15 @@ void ScreenAnnotation::Render () // ====================================================================== // Nonmember functions +// ====================================================================== + +DLLEXPORT INT_PTR CALLBACK LaunchpadVideoWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + GraphicsClient *gc = (GraphicsClient*)GetWindowLongPtr (hWnd, GWLP_USERDATA); + if (gc) return gc->LaunchpadVideoWndProc (hWnd, uMsg, wParam, lParam); + else return FALSE; +} + // ====================================================================== // API interface: register/unregister the graphics client @@ -878,206 +887,3 @@ DLLEXPORT bool oapiUnregisterGraphicsClient (GraphicsClient *gc) { return g_pOrbiter->RemoveGraphicsClient (gc); } - -DLLEXPORT bool WithImCtx::ConsumeEvent(const SDL_Event &event, - bool &wantsOut) const { - return inner->ConsumeEvent(event, wantsOut); -}; - -DLLEXPORT bool WithImCtx::BeginFrame() const { return inner->BeginFrame(); } - -DLLEXPORT void WithImCtx::EndFrame() const { return inner->EndFrame(); } - -DLLEXPORT WithImCtx::WithImCtx(ImCtxBase *inner, ImGuiContext *lastContext) - : inner(inner), lastContext(lastContext) {} - -DLLEXPORT WithImCtx::~WithImCtx() { - if (lastContext) - ImGui::SetCurrentContext(lastContext); -} - -DLLEXPORT ImCtxBase *WithImCtx::operator->() const { return inner; } - -DLLEXPORT ImCtxBase *WithImCtx::Inner() const { return inner; } - -DLLEXPORT WithImCtx ImCtxBase::PushLocal() { - const auto lastContext = ImGui::GetCurrentContext(); - ImGui::SetCurrentContext(m_context); - return {this, lastContext}; -}; - -// Styling adapted from -// https://gist.github.com/dougbinks/8089b4bbaccaaf6fa204236978d165a9 -static void ImGuiSetStyle(bool bStyleDark_, float alpha_) { - // Setup Dear ImGui style - ImGui::StyleColorsDark(); - // ImGui::StyleColorsClassic(); - // ImGui::StyleColorsLight(); - ImGuiStyle &style = ImGui::GetStyle(); - - style.Alpha = 1.0f; - style.FrameRounding = 3.0f; - style.WindowRounding = 3.0f; - style.ChildRounding = 3.0f; - style.PopupRounding = 3.0f; - style.ScrollbarRounding = 3.0f; - style.GrabRounding = 3.0f; - style.TabRounding = 3.0f; - style.WindowMenuButtonPosition = ImGuiDir_Right; - style.Colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - style.Colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); - style.Colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - style.Colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); - style.Colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); - style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - style.Colors[ImGuiCol_FrameBg] = ImVec4(0.63f, 0.13f, 0.13f, 0.50f); - style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.94f, 0.41f, 0.36f, 0.50f); - style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.78f, 0.27f, 0.24f, 0.50f); - style.Colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); - style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.63f, 0.13f, 0.13f, 0.75f); - style.Colors[ImGuiCol_TitleBgCollapsed] = - ImVec4(0.00f, 0.00f, 0.00f, 0.51f); - style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); - style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); - style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); - style.Colors[ImGuiCol_ScrollbarGrabHovered] = - ImVec4(0.41f, 0.41f, 0.41f, 1.00f); - style.Colors[ImGuiCol_ScrollbarGrabActive] = - ImVec4(0.51f, 0.51f, 0.51f, 1.00f); - // Not very set on the white checkmark, but the light red didn't look the - // best either... TODO!!! - style.Colors[ImGuiCol_CheckMark] = ImVec4(0.94f, 0.41f, 0.36f, 1.00f); - style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.94f, 0.41f, 0.36f, 0.66f); - style.Colors[ImGuiCol_SliderGrabActive] = - ImVec4(0.94f, 0.41f, 0.36f, 0.66f); - style.Colors[ImGuiCol_Button] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); - style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.94f, 0.41f, 0.36f, 0.54f); - style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.78f, 0.27f, 0.24f, 0.54f); - style.Colors[ImGuiCol_Header] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); - style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.94f, 0.41f, 0.36f, 0.66f); - style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.78f, 0.27f, 0.24f, 0.66f); - style.Colors[ImGuiCol_Separator] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); - style.Colors[ImGuiCol_SeparatorHovered] = - ImVec4(0.94f, 0.41f, 0.36f, 0.66f); - style.Colors[ImGuiCol_SeparatorActive] = ImVec4(0.78f, 0.27f, 0.24f, 0.66f); - style.Colors[ImGuiCol_ResizeGrip] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); - style.Colors[ImGuiCol_ResizeGripHovered] = - ImVec4(0.94f, 0.41f, 0.36f, 0.66f); - style.Colors[ImGuiCol_ResizeGripActive] = - ImVec4(0.78f, 0.27f, 0.24f, 0.66f); - style.Colors[ImGuiCol_TabHovered] = ImVec4(0.94f, 0.41f, 0.36f, 0.66f); - style.Colors[ImGuiCol_Tab] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); - style.Colors[ImGuiCol_TabSelected] = ImVec4(0.78f, 0.27f, 0.24f, 0.66f); - style.Colors[ImGuiCol_TabSelectedOverline] = - ImVec4(0.94f, 0.41f, 0.36f, 1.00f); - style.Colors[ImGuiCol_TabDimmed] = ImVec4(0.63f, 0.13f, 0.13f, 0.13f); - style.Colors[ImGuiCol_TabDimmedSelected] = - ImVec4(0.78f, 0.27f, 0.24f, 0.13f); - style.Colors[ImGuiCol_TabDimmedSelectedOverline] = - ImVec4(0.94f, 0.41f, 0.36f, 0.13f); - style.Colors[ImGuiCol_DockingPreview] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); - style.Colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); - style.Colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); - style.Colors[ImGuiCol_PlotLinesHovered] = - ImVec4(1.00f, 0.43f, 0.35f, 1.00f); - style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - style.Colors[ImGuiCol_PlotHistogramHovered] = - ImVec4(1.00f, 0.60f, 0.00f, 1.00f); - style.Colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f); - style.Colors[ImGuiCol_TableBorderStrong] = - ImVec4(0.31f, 0.31f, 0.35f, 1.00f); - style.Colors[ImGuiCol_TableBorderLight] = - ImVec4(0.23f, 0.23f, 0.25f, 1.00f); - style.Colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - style.Colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); - style.Colors[ImGuiCol_TextLink] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); - style.Colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); - style.Colors[ImGuiCol_NavCursor] = ImVec4(0.63f, 0.13f, 0.13f, 0.40f); - style.Colors[ImGuiCol_NavWindowingHighlight] = - ImVec4(1.00f, 1.00f, 1.00f, 0.70f); - style.Colors[ImGuiCol_NavWindowingDimBg] = - ImVec4(0.80f, 0.80f, 0.80f, 0.20f); - style.Colors[ImGuiCol_ModalWindowDimBg] = - ImVec4(0.80f, 0.80f, 0.80f, 0.35f); -} - -DLLEXPORT ImCtxBase::ImCtxBase(Orbiter *app, ImGuiContext *context) - : m_app(app), m_context(context) { -#ifdef _DEBUG - IMGUI_CHECKVERSION(); -#endif - const auto savedContext = ImGui::GetCurrentContext(); - ImGui::SetCurrentContext(m_context); - - ImGuiIO &io = ImGui::GetIO(); - if (!m_app->IsFullscreen()) - io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; - io.IniFilename = nullptr; - io.LogFilename = nullptr; - - ImGuiSetStyle(false, 1.0f); - - ImFontConfig config; - - static constexpr ImWchar icons_ranges[] = {ICON_MIN_FA, ICON_MAX_FA, 0}; - ImFontConfig icons_config; - icons_config.MergeMode = true; - icons_config.PixelSnapH = true; - icons_config.FontDataOwnedByAtlas = false; - icons_config.GlyphOffset.y = 1; - - const CFG_FONTPRM &prm = m_app->Cfg()->CfgFontPrm; - - auto defaultFontFile = - std::string(prm.ImGui_FontName).append("-Regular.ttf"); - auto italicFontFile = std::string(prm.ImGui_FontName).append("-Italic.ttf"); - auto boldFontFile = std::string(prm.ImGui_FontName).append("-Bold.ttf"); - auto boldItalicFontFile = - std::string(prm.ImGui_FontName).append("-BoldItalic.ttf"); - - m_defaultFont = io.Fonts->AddFontFromFileTTF( - defaultFontFile.c_str(), prm.ImGui_FontSize, &config, - ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); - io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, - &icons_config, icons_ranges); - m_italicFont = io.Fonts->AddFontFromFileTTF( - italicFontFile.c_str(), prm.ImGui_FontSize, &config, - ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); - io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, - &icons_config, icons_ranges); - m_boldFont = io.Fonts->AddFontFromFileTTF( - boldFontFile.c_str(), prm.ImGui_FontSize, &config, - ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); - io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, - &icons_config, icons_ranges); - m_boldItalicFont = io.Fonts->AddFontFromFileTTF( - boldItalicFontFile.c_str(), prm.ImGui_FontSize, &config, - ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); - io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, - &icons_config, icons_ranges); - m_hdgFont = io.Fonts->AddFontFromFileTTF( - defaultFontFile.c_str(), prm.ImGui_FontSize * 1.5f, &config, - ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); - io.Fonts->AddFontFromFileTTF("fa-solid-900.ttf", prm.ImGui_FontSize, - &icons_config, icons_ranges); - // weird alignment issues otherwise, yippee (sarcastic) - config.GlyphOffset.y = 1; - m_monoFont = io.Fonts->AddFontFromFileTTF( - "Cousine-Regular.ttf", prm.ImGui_FontSize, &config, - ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); - io.Fonts->Build(); - - if (savedContext) - ImGui::SetCurrentContext(savedContext); -} - -DLLEXPORT ImCtxBase::~ImCtxBase() { - const auto savedContext = ImGui::GetCurrentContext(); - ImGui::SetCurrentContext(m_context); - ImGui::DestroyContext(); - if (savedContext) - ImGui::SetCurrentContext(savedContext); -} diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index e2ecb369a..2920d6c56 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -985,16 +985,12 @@ void Orbiter::BroadcastGlobalInit () HRESULT Orbiter::Render3DEnvironment (bool hidedialogs) { if (gclient) { - if(!hidedialogs) { - WithImCtx _ = pDlgMgr->PushLocal(); + if(!hidedialogs) pDlgMgr->ImGuiNewFrame(); - } gclient->clbkRenderScene (); Output2DData (); - if(!hidedialogs) { - WithImCtx _ = pDlgMgr->PushLocal(); + if(!hidedialogs) gclient->clbkImGuiRenderDrawData(); - } gclient->clbkDisplayFrame (); } return S_OK; @@ -2067,7 +2063,6 @@ HRESULT Orbiter::UserInput () (g_select && g_select->IsActive())) skipkbd = true; if (didev = GetDInput()->GetKbdDevice()) { - WithImCtx _ = pDlgMgr->PushLocal(); ImGuiIO& io = ImGui::GetIO(); // keyboard input: immediate key interpretation hr = didev->GetDeviceState (sizeof(buffer), &buffer); From af229474436af12c0a3a1b3b109d1359a779310a Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Mon, 24 Feb 2025 22:47:06 -0600 Subject: [PATCH 35/51] Fix DlgHelp --- Src/Orbiter/DlgHelp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/Orbiter/DlgHelp.cpp b/Src/Orbiter/DlgHelp.cpp index 2fcc7ebe2..fd0e65d77 100644 --- a/Src/Orbiter/DlgHelp.cpp +++ b/Src/Orbiter/DlgHelp.cpp @@ -18,7 +18,7 @@ void DlgHelp::OnDraw() {} void DlgHelp::OpenHelp(const HELPCONTEXT *hc) { char buf[256]; - HWND hWnd = (HWND)(ImGui::GetMainViewport()->PlatformHandle); + HWND hWnd = (HWND)(ImGui::GetMainViewport()->PlatformHandleRaw); if(hc->topic) snprintf(buf, 256, "%s::%s", hc->helpfile, hc->topic); else From 073f1f374ddb81e13615354a0adf7a723defd80a Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Mon, 24 Feb 2025 22:58:25 -0600 Subject: [PATCH 36/51] Fix exit button --- Src/Orbiter/MenuInfoBar.cpp | 2 +- Src/Orbiter/Orbiter.cpp | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/Src/Orbiter/MenuInfoBar.cpp b/Src/Orbiter/MenuInfoBar.cpp index 9bc272e67..9a2b45974 100644 --- a/Src/Orbiter/MenuInfoBar.cpp +++ b/Src/Orbiter/MenuInfoBar.cpp @@ -697,7 +697,7 @@ bool MenuInfoBar::ProcessMouse (const SDL_Event &event, DWORD x, DWORD y) return true; case 11: g_pOrbiter->PreCloseSession(); - // DestroyWindow (g_pOrbiter->GetRenderWnd()); + g_pOrbiter->CloseSession(); return true; } } diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 2920d6c56..d710ac05f 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -1014,18 +1014,20 @@ void Orbiter::Run() { if (!pConfig->CfgCmdlinePrm.LaunchScenario.empty()) Launch(pConfig->CfgCmdlinePrm.LaunchScenario.c_str()); - SDL_Event event = {}; + SDL_Event event = {}; MSG msg; PeekMessage (&msg, NULL, 0U, 0U, PM_NOREMOVE); bool hadEvent; bool bpCanRender = true; while (!ShouldQuit() && msg.message != WM_QUIT) { - if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { + if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { if (!m_pLaunchpad || !m_pLaunchpad->ConsumeMessage(&msg)) { TranslateMessage (&msg); DispatchMessage (&msg); } + if (m_pLaunchpad && (msg.message == WM_CLOSE || msg.message == WM_DESTROY) && msg.hwnd == m_pLaunchpad->hDlg) + break; } else if (SDL_PollEvent(&event)) { bool consumed = false; @@ -1060,10 +1062,9 @@ void Orbiter::Run() { } if (bRenderOnce && bVisible) { - // TODO: what should replace this? - if (FAILED(Render3DEnvironment())) {} - // if (hRenderWnd) - // DestroyWindow(hRenderWnd); + if (FAILED(Render3DEnvironment())) { + g_pOrbiter->CloseSession(); + } bRenderOnce = false; } @@ -2569,10 +2570,6 @@ void Orbiter::BroadcastBufferedKeyboardEvent (char *kstate, DIDEVICEOBJECTDATA * bool Orbiter::MsgProc (const SDL_Event &event, bool &wantsOut) { - // TODO: get DlgMgr working again - // if (ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam)) - // return 0; - if (event.type == SDL_EVENT_MOUSE_BUTTON_UP || event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) { if (MouseEvent(event, static_cast(event.button.x), static_cast(event.button.y))) return true; From 091bfcdc0cfb8d14a139951a86a0f88fdf925352 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Mon, 24 Feb 2025 23:00:50 -0600 Subject: [PATCH 37/51] Whoops --- Sound/XRSound/LICENSE | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Sound/XRSound/LICENSE diff --git a/Sound/XRSound/LICENSE b/Sound/XRSound/LICENSE new file mode 100644 index 000000000..73d9692bf --- /dev/null +++ b/Sound/XRSound/LICENSE @@ -0,0 +1,54 @@ +MIT License + +Copyright (c) 2021 Douglas E. Beachy + +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. + +============================================================================= + +DEPENDENCIES: + +1) XRSound uses the irrKlang Sound Engine. +See https://www.ambiera.com/irrklang/license.html for details +about the ikkLang license. Its license as of 31-July-2021 is quoted below: + +The irrKlang License +irrKlang's source codes, documentation and binaries contained within the +distributed archive are copyright (c) Nikolaus Gebhardt / Ambiera 2001-2020. + +The contents of the irrKlang distribution archive may not be redistributed, +reproduced, modified, transmitted, broadcast, published or adapted in any way, +shape or form, without the prior written consent of the owner, Nikolaus +Gebhardt. + +The irrKlang.dll, irrKlang.so and libirrklang.dylib files may be +redistributed without the author's prior permission in non-commercial +products, and must remain unmodified except for compressing the file. + +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 REGENTS 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. From 7a5aeee7d57601d4b284953fa29cea5074822388 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Mon, 24 Feb 2025 23:01:48 -0600 Subject: [PATCH 38/51] Whoops pt.2 --- Sound/XRSound/LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sound/XRSound/LICENSE b/Sound/XRSound/LICENSE index 73d9692bf..bc512b7d0 100644 --- a/Sound/XRSound/LICENSE +++ b/Sound/XRSound/LICENSE @@ -30,7 +30,7 @@ about the ikkLang license. Its license as of 31-July-2021 is quoted below: The irrKlang License irrKlang's source codes, documentation and binaries contained within the -distributed archive are copyright (c) Nikolaus Gebhardt / Ambiera 2001-2020. +distributed archive are copyright � Nikolaus Gebhardt / Ambiera 2001-2020. The contents of the irrKlang distribution archive may not be redistributed, reproduced, modified, transmitted, broadcast, published or adapted in any way, From 12f4d04ced326b4a39ec6b283b6028cbe0394277 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Mon, 24 Feb 2025 23:12:32 -0600 Subject: [PATCH 39/51] Remove irrelevant TODO I'm honestly not sure if this behaviour is implemented elsewhere, or what the exact purpose of this originally was, since this was only called in the render window. --- Src/Orbiter/Orbiter.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index d710ac05f..8605700ad 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -2579,9 +2579,6 @@ bool Orbiter::MsgProc (const SDL_Event &event, bool &wantsOut) } else if (event.type == SDL_EVENT_MOUSE_MOTION) { if (MouseEvent(event, static_cast(event.motion.x), static_cast(event.motion.y))) return true; - // TODO - // if (!bKeepFocus && pConfig->CfgUIPrm.MouseFocusMode != 0 && SDL_GetMouseFocus() != hRenderWnd->Inner()) { - // SetFocus(hWnd); } return false; } From 99b0f54ed3e139d281112b8b030a402187391985 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Tue, 25 Feb 2025 23:03:18 -0600 Subject: [PATCH 40/51] Keyboard input --- Orbitersdk/include/OrbiterAPI.h | 205 ++++++++++++++++---------------- Src/Orbiter/Input.cpp | 8 ++ Src/Orbiter/Input.h | 6 + Src/Orbiter/Orbiter.cpp | 155 ++++++++++++------------ Src/Orbiter/Orbiter.h | 6 +- 5 files changed, 198 insertions(+), 182 deletions(-) diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 57fa3bced..b5390bebf 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -28,6 +28,7 @@ #include #include #include +#include #if defined(_MSC_VER) && (_MSC_VER < 1920 ) // Microsoft Visual Studio Version 2017 and lower #include @@ -6907,108 +6908,108 @@ OAPIFUNC void oapiTriggerRedrawArea (int panel_id, int vc_id, int area_id); */ // ====================================================================== //@{ -#define OAPI_KEY_ESCAPE 0x01 ///< Escape key -#define OAPI_KEY_1 0x02 ///< '1' key on main keyboard -#define OAPI_KEY_2 0x03 ///< '2' key on main keyboard -#define OAPI_KEY_3 0x04 ///< '3' key on main keyboard -#define OAPI_KEY_4 0x05 ///< '4' key on main keyboard -#define OAPI_KEY_5 0x06 ///< '5' key on main keyboard -#define OAPI_KEY_6 0x07 ///< '6' key on main keyboard -#define OAPI_KEY_7 0x08 ///< '7' key on main keyboard -#define OAPI_KEY_8 0x09 ///< '8' key on main keyboard -#define OAPI_KEY_9 0x0A ///< '9' key on main keyboard -#define OAPI_KEY_0 0x0B ///< '0' key on main keyboard -#define OAPI_KEY_MINUS 0x0C ///< '-' key on main keyboard -#define OAPI_KEY_EQUALS 0x0D ///< '=' key on main keyboard -#define OAPI_KEY_BACK 0x0E ///< backspace key -#define OAPI_KEY_TAB 0x0F ///< tab key -#define OAPI_KEY_Q 0x10 ///< 'Q' key -#define OAPI_KEY_W 0x11 ///< 'W' key -#define OAPI_KEY_E 0x12 ///< 'E' key -#define OAPI_KEY_R 0x13 ///< 'R' key -#define OAPI_KEY_T 0x14 ///< 'T' key -#define OAPI_KEY_Y 0x15 ///< 'Y' key -#define OAPI_KEY_U 0x16 ///< 'U' key -#define OAPI_KEY_I 0x17 ///< 'I' key -#define OAPI_KEY_O 0x18 ///< 'O' key -#define OAPI_KEY_P 0x19 ///< 'P' key -#define OAPI_KEY_LBRACKET 0x1A ///< '[' (left bracket) key -#define OAPI_KEY_RBRACKET 0x1B ///< ']' (right bracket) key -#define OAPI_KEY_RETURN 0x1C ///< 'Enter' key on main keyboard -#define OAPI_KEY_LCONTROL 0x1D ///< Left 'Ctrl' key -#define OAPI_KEY_A 0x1E ///< 'A' key -#define OAPI_KEY_S 0x1F ///< 'S' key -#define OAPI_KEY_D 0x20 ///< 'D' key -#define OAPI_KEY_F 0x21 ///< 'F' key -#define OAPI_KEY_G 0x22 ///< 'G' key -#define OAPI_KEY_H 0x23 ///< 'H' key -#define OAPI_KEY_J 0x24 ///< 'J' key -#define OAPI_KEY_K 0x25 ///< 'K' key -#define OAPI_KEY_L 0x26 ///< 'L' key -#define OAPI_KEY_SEMICOLON 0x27 ///< ';' (semicolon) key -#define OAPI_KEY_APOSTROPHE 0x28 ///< ' (apostrophe) key -#define OAPI_KEY_GRAVE 0x29 ///< accent grave -#define OAPI_KEY_LSHIFT 0x2A ///< Left 'Shift' key -#define OAPI_KEY_BACKSLASH 0x2B ///< '\' (Backslash) key -#define OAPI_KEY_Z 0x2C ///< 'Z' key -#define OAPI_KEY_X 0x2D ///< 'X' key -#define OAPI_KEY_C 0x2E ///< 'C' key -#define OAPI_KEY_V 0x2F ///< 'V' key -#define OAPI_KEY_B 0x30 ///< 'B' key -#define OAPI_KEY_N 0x31 ///< 'N' key -#define OAPI_KEY_M 0x32 ///< 'M' key -#define OAPI_KEY_COMMA 0x33 ///< ',' (comma) key -#define OAPI_KEY_PERIOD 0x34 ///< '.' key on main keyboard -#define OAPI_KEY_SLASH 0x35 ///< '/' key on main keyboard -#define OAPI_KEY_RSHIFT 0x36 ///< Right 'Shift' key -#define OAPI_KEY_MULTIPLY 0x37 ///< * on numeric keypad -#define OAPI_KEY_LALT 0x38 ///< left Alt -#define OAPI_KEY_SPACE 0x39 ///< 'Space' key -#define OAPI_KEY_CAPITAL 0x3A ///< caps lock key -#define OAPI_KEY_F1 0x3B ///< F1 function key -#define OAPI_KEY_F2 0x3C ///< F2 function key -#define OAPI_KEY_F3 0x3D ///< F3 function key -#define OAPI_KEY_F4 0x3E ///< F4 function key -#define OAPI_KEY_F5 0x3F ///< F5 function key -#define OAPI_KEY_F6 0x40 ///< F6 function key -#define OAPI_KEY_F7 0x41 ///< F7 function key -#define OAPI_KEY_F8 0x42 ///< F8 function key -#define OAPI_KEY_F9 0x43 ///< F9 function key -#define OAPI_KEY_F10 0x44 ///< F10 function key -#define OAPI_KEY_NUMLOCK 0x45 ///< 'Num Lock' key -#define OAPI_KEY_SCROLL 0x46 ///< Scroll lock -#define OAPI_KEY_NUMPAD7 0x47 ///< '7' key on numeric keypad -#define OAPI_KEY_NUMPAD8 0x48 ///< '8' key on numeric keypad -#define OAPI_KEY_NUMPAD9 0x49 ///< '9' key on numeric keypad -#define OAPI_KEY_SUBTRACT 0x4A ///< '-' key on numeric keypad -#define OAPI_KEY_NUMPAD4 0x4B ///< '4' key on numeric keypad -#define OAPI_KEY_NUMPAD5 0x4C ///< '5' key on numeric keypad -#define OAPI_KEY_NUMPAD6 0x4D ///< '6' key on numeric keypad -#define OAPI_KEY_ADD 0x4E ///< '+' key on numeric keypad -#define OAPI_KEY_NUMPAD1 0x4F ///< '1' key on numeric keypad -#define OAPI_KEY_NUMPAD2 0x50 ///< '2' key on numeric keypad -#define OAPI_KEY_NUMPAD3 0x51 ///< '3' key on numeric keypad -#define OAPI_KEY_NUMPAD0 0x52 ///< '0' key on numeric keypad -#define OAPI_KEY_DECIMAL 0x53 ///< '.' key on numeric keypad -#define OAPI_KEY_OEM_102 0x56 ///< | \< \> on UK/German keyboards -#define OAPI_KEY_F11 0x57 ///< F11 function key -#define OAPI_KEY_F12 0x58 ///< F12 function key -#define OAPI_KEY_NUMPADENTER 0x9C ///< Enter on numeric keypad -#define OAPI_KEY_RCONTROL 0x9D ///< right Control key -#define OAPI_KEY_DIVIDE 0xB5 ///< '/' key on numeric keypad -#define OAPI_KEY_SYSRQ 0xB7 ///< SysRq/PrtScn key -#define OAPI_KEY_RALT 0xB8 ///< right Alt -#define OAPI_KEY_PAUSE 0xC5 ///< Break/Pause key -#define OAPI_KEY_HOME 0xC7 ///< Home on cursor keypad -#define OAPI_KEY_UP 0xC8 ///< up-arrow on cursor keypad -#define OAPI_KEY_PRIOR 0xC9 ///< PgUp on cursor keypad -#define OAPI_KEY_LEFT 0xCB ///< left-arrow on cursor keypad -#define OAPI_KEY_RIGHT 0xCD ///< right-arrow on cursor keypad -#define OAPI_KEY_END 0xCF ///< End on cursor keypad -#define OAPI_KEY_DOWN 0xD0 ///< down-arrow on cursor keypad -#define OAPI_KEY_NEXT 0xD1 ///< PgDn on cursor keypad -#define OAPI_KEY_INSERT 0xD2 ///< Insert on cursor keypad -#define OAPI_KEY_DELETE 0xD3 ///< Delete on cursor keypad +#define OAPI_KEY_ESCAPE SDL_SCANCODE_ESCAPE ///< Escape key +#define OAPI_KEY_1 SDL_SCANCODE_1 ///< '1' key on main keyboard +#define OAPI_KEY_2 SDL_SCANCODE_2 ///< '2' key on main keyboard +#define OAPI_KEY_3 SDL_SCANCODE_3 ///< '3' key on main keyboard +#define OAPI_KEY_4 SDL_SCANCODE_4 ///< '4' key on main keyboard +#define OAPI_KEY_5 SDL_SCANCODE_5 ///< '5' key on main keyboard +#define OAPI_KEY_6 SDL_SCANCODE_6 ///< '6' key on main keyboard +#define OAPI_KEY_7 SDL_SCANCODE_7 ///< '7' key on main keyboard +#define OAPI_KEY_8 SDL_SCANCODE_8 ///< '8' key on main keyboard +#define OAPI_KEY_9 SDL_SCANCODE_9 ///< '9' key on main keyboard +#define OAPI_KEY_0 SDL_SCANCODE_0 ///< '0' key on main keyboard +#define OAPI_KEY_MINUS SDL_SCANCODE_MINUS ///< '-' key on main keyboard +#define OAPI_KEY_EQUALS SDL_SCANCODE_EQUALS ///< '=' key on main keyboard +#define OAPI_KEY_BACK SDL_SCANCODE_BACKSPACE ///< backspace key +#define OAPI_KEY_TAB SDL_SCANCODE_TAB ///< tab key +#define OAPI_KEY_Q SDL_SCANCODE_Q ///< 'Q' key +#define OAPI_KEY_W SDL_SCANCODE_W ///< 'W' key +#define OAPI_KEY_E SDL_SCANCODE_E ///< 'E' key +#define OAPI_KEY_R SDL_SCANCODE_R ///< 'R' key +#define OAPI_KEY_T SDL_SCANCODE_T ///< 'T' key +#define OAPI_KEY_Y SDL_SCANCODE_Y ///< 'Y' key +#define OAPI_KEY_U SDL_SCANCODE_U ///< 'U' key +#define OAPI_KEY_I SDL_SCANCODE_I ///< 'I' key +#define OAPI_KEY_O SDL_SCANCODE_O ///< 'O' key +#define OAPI_KEY_P SDL_SCANCODE_P ///< 'P' key +#define OAPI_KEY_LBRACKET SDL_SCANCODE_LEFTBRACKET ///< '[' (left bracket) key +#define OAPI_KEY_RBRACKET SDL_SCANCODE_RIGHTBRACKET ///< ']' (right bracket) key +#define OAPI_KEY_RETURN SDL_SCANCODE_RETURN ///< 'Enter' key on main keyboard +#define OAPI_KEY_LCONTROL SDL_SCANCODE_LCTRL ///< Left 'Ctrl' key +#define OAPI_KEY_A SDL_SCANCODE_A ///< 'A' key +#define OAPI_KEY_S SDL_SCANCODE_S ///< 'S' key +#define OAPI_KEY_D SDL_SCANCODE_D ///< 'D' key +#define OAPI_KEY_F SDL_SCANCODE_F ///< 'F' key +#define OAPI_KEY_G SDL_SCANCODE_G ///< 'G' key +#define OAPI_KEY_H SDL_SCANCODE_H ///< 'H' key +#define OAPI_KEY_J SDL_SCANCODE_J ///< 'J' key +#define OAPI_KEY_K SDL_SCANCODE_K ///< 'K' key +#define OAPI_KEY_L SDL_SCANCODE_L ///< 'L' key +#define OAPI_KEY_SEMICOLON SDL_SCANCODE_SEMICOLON ///< ';' (semicolon) key +#define OAPI_KEY_APOSTROPHE SDL_SCANCODE_APOSTROPHE ///< ' (apostrophe) key +#define OAPI_KEY_GRAVE SDL_SCANCODE_GRAVE ///< accent grave +#define OAPI_KEY_LSHIFT SDL_SCANCODE_LSHIFT ///< Left 'Shift' key +#define OAPI_KEY_BACKSLASH SDL_SCANCODE_BACKSLASH ///< '\' (Backslash) key +#define OAPI_KEY_Z SDL_SCANCODE_Z ///< 'Z' key +#define OAPI_KEY_X SDL_SCANCODE_X ///< 'X' key +#define OAPI_KEY_C SDL_SCANCODE_C ///< 'C' key +#define OAPI_KEY_V SDL_SCANCODE_V ///< 'V' key +#define OAPI_KEY_B SDL_SCANCODE_B ///< 'B' key +#define OAPI_KEY_N SDL_SCANCODE_N ///< 'N' key +#define OAPI_KEY_M SDL_SCANCODE_M ///< 'M' key +#define OAPI_KEY_COMMA SDL_SCANCODE_COMMA ///< ',' (comma) key +#define OAPI_KEY_PERIOD SDL_SCANCODE_PERIOD ///< '.' key on main keyboard +#define OAPI_KEY_SLASH SDL_SCANCODE_SLASH ///< '/' key on main keyboard +#define OAPI_KEY_RSHIFT SDL_SCANCODE_RSHIFT ///< Right 'Shift' key +#define OAPI_KEY_MULTIPLY SDL_SCANCODE_KP_MULTIPLY ///< * on numeric keypad +#define OAPI_KEY_LALT SDL_SCANCODE_LALT ///< left Alt +#define OAPI_KEY_SPACE SDL_SCANCODE_SPACE ///< 'Space' key +#define OAPI_KEY_CAPITAL SDL_SCANCODE_CAPSLOCK ///< caps lock key +#define OAPI_KEY_F1 SDL_SCANCODE_F1 ///< F1 function key +#define OAPI_KEY_F2 SDL_SCANCODE_F2 ///< F2 function key +#define OAPI_KEY_F3 SDL_SCANCODE_F3 ///< F3 function key +#define OAPI_KEY_F4 SDL_SCANCODE_F4 ///< F4 function key +#define OAPI_KEY_F5 SDL_SCANCODE_F5 ///< F5 function key +#define OAPI_KEY_F6 SDL_SCANCODE_F6 ///< F6 function key +#define OAPI_KEY_F7 SDL_SCANCODE_F7 ///< F7 function key +#define OAPI_KEY_F8 SDL_SCANCODE_F8 ///< F8 function key +#define OAPI_KEY_F9 SDL_SCANCODE_F9 ///< F9 function key +#define OAPI_KEY_F10 SDL_SCANCODE_F10 ///< F10 function key +#define OAPI_KEY_NUMLOCK SDL_SCANCODE_NUMLOCKCLEAR ///< 'Num Lock' key +#define OAPI_KEY_SCROLL SDL_SCANCODE_SCROLLLOCK ///< Scroll lock +#define OAPI_KEY_NUMPAD7 SDL_SCANCODE_KP_7 ///< '7' key on numeric keypad +#define OAPI_KEY_NUMPAD8 SDL_SCANCODE_KP_8 ///< '8' key on numeric keypad +#define OAPI_KEY_NUMPAD9 SDL_SCANCODE_KP_9 ///< '9' key on numeric keypad +#define OAPI_KEY_SUBTRACT SDL_SCANCODE_KP_MINUS ///< '-' key on numeric keypad +#define OAPI_KEY_NUMPAD4 SDL_SCANCODE_KP_4 ///< '4' key on numeric keypad +#define OAPI_KEY_NUMPAD5 SDL_SCANCODE_KP_5 ///< '5' key on numeric keypad +#define OAPI_KEY_NUMPAD6 SDL_SCANCODE_KP_6 ///< '6' key on numeric keypad +#define OAPI_KEY_ADD SDL_SCANCODE_KP_PLUS ///< '+' key on numeric keypad +#define OAPI_KEY_NUMPAD1 SDL_SCANCODE_KP_1 ///< '1' key on numeric keypad +#define OAPI_KEY_NUMPAD2 SDL_SCANCODE_KP_2 ///< '2' key on numeric keypad +#define OAPI_KEY_NUMPAD3 SDL_SCANCODE_KP_3 ///< '3' key on numeric keypad +#define OAPI_KEY_NUMPAD0 SDL_SCANCODE_KP_0 ///< '0' key on numeric keypad +#define OAPI_KEY_DECIMAL SDL_SCANCODE_KP_DECIMAL ///< '.' key on numeric keypad +#define OAPI_KEY_OEM_102 SDL_SCANCODE_NONUSBACKSLASH ///< | \< \> on UK/German keyboards +#define OAPI_KEY_F11 SDL_SCANCODE_F11 ///< F11 function key +#define OAPI_KEY_F12 SDL_SCANCODE_F12 ///< F12 function key +#define OAPI_KEY_NUMPADENTER SDL_SCANCODE_KP_ENTER ///< Enter on numeric keypad +#define OAPI_KEY_RCONTROL SDL_SCANCODE_RCTRL ///< right Control key +#define OAPI_KEY_DIVIDE SDL_SCANCODE_KP_DIVIDE ///< '/' key on numeric keypad +#define OAPI_KEY_SYSRQ SDL_SCANCODE_PRINTSCREEN ///< SysRq/PrtScn key +#define OAPI_KEY_RALT SDL_SCANCODE_RALT ///< right Alt +#define OAPI_KEY_PAUSE SDL_SCANCODE_PAUSE ///< Break/Pause key +#define OAPI_KEY_HOME SDL_SCANCODE_HOME ///< Home on cursor keypad +#define OAPI_KEY_UP SDL_SCANCODE_UP ///< up-arrow on cursor keypad +#define OAPI_KEY_PRIOR SDL_SCANCODE_PAGEUP ///< PgUp on cursor keypad +#define OAPI_KEY_LEFT SDL_SCANCODE_LEFT ///< left-arrow on cursor keypad +#define OAPI_KEY_RIGHT SDL_SCANCODE_RIGHT ///< right-arrow on cursor keypad +#define OAPI_KEY_END SDL_SCANCODE_END ///< End on cursor keypad +#define OAPI_KEY_DOWN SDL_SCANCODE_DOWN ///< down-arrow on cursor keypad +#define OAPI_KEY_NEXT SDL_SCANCODE_PAGEDOWN ///< PgDn on cursor keypad +#define OAPI_KEY_INSERT SDL_SCANCODE_INSERT ///< Insert on cursor keypad +#define OAPI_KEY_DELETE SDL_SCANCODE_DELETE ///< Delete on cursor keypad //@} #define KEYDOWN(buf,key) (buf[key] & 0x80) diff --git a/Src/Orbiter/Input.cpp b/Src/Orbiter/Input.cpp index 606452f5f..a208e75b7 100644 --- a/Src/Orbiter/Input.cpp +++ b/Src/Orbiter/Input.cpp @@ -248,3 +248,11 @@ HRESULT DInput::SetJoystickProperties () } return DI_OK; } + +bool DInput::ConsumeEvent(const SDL_Event &event) { + if (event.type == SDL_EVENT_KEY_UP || event.type == SDL_EVENT_KEY_DOWN) { + m_bufferedEvents.push_back(event.key); + return true; + } + return false; +} diff --git a/Src/Orbiter/Input.h b/Src/Orbiter/Input.h index 8a1c9ac52..94e17b088 100644 --- a/Src/Orbiter/Input.h +++ b/Src/Orbiter/Input.h @@ -10,6 +10,9 @@ #include "Di7frame.h" +#include +#include + class DInput { friend class Orbiter; @@ -40,6 +43,8 @@ class DInput { int ThrottleOfs; // throttle data offset }; + bool ConsumeEvent(const SDL_Event &event); + protected: HRESULT SetJoystickProperties (); @@ -48,6 +53,7 @@ class DInput { CDIFramework7 *diframe; JoyProp joyprop; HWND m_hWnd; + std::list m_bufferedEvents; }; #endif // !__INPUT_H \ No newline at end of file diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 8605700ad..91744d4a0 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -673,6 +673,7 @@ VOID Orbiter::Launch (const char *scenario) long m0 = memstat->HeapUsage(); CreateRenderWindow (pConfig, scenario); + SDL_InitSubSystem(SDL_INIT_VIDEO); simheapsize = memstat->HeapUsage()-m0; SetCursor (hCursor); } @@ -953,6 +954,7 @@ void Orbiter::CloseSession () } } LOGOUT("**** Closing simulation session"); + SDL_QuitSubSystem(SDL_INIT_VIDEO); } // ======================================================================= @@ -1018,7 +1020,6 @@ void Orbiter::Run() { MSG msg; PeekMessage (&msg, NULL, 0U, 0U, PM_NOREMOVE); - bool hadEvent; bool bpCanRender = true; while (!ShouldQuit() && msg.message != WM_QUIT) { if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { @@ -1026,40 +1027,36 @@ void Orbiter::Run() { TranslateMessage (&msg); DispatchMessage (&msg); } - if (m_pLaunchpad && (msg.message == WM_CLOSE || msg.message == WM_DESTROY) && msg.hwnd == m_pLaunchpad->hDlg) + if (msg.message == WM_CLOSE || msg.message == WM_DESTROY || msg.message == WM_QUIT) break; } else if (SDL_PollEvent(&event)) { - bool consumed = false; - if (gclient && hRenderWnd != nullptr) { - consumed = consumed || pDlgMgr->ConsumeEvent(event, bShouldQuit); - consumed = consumed || gclient->RenderWndProc(event, bShouldQuit); - } - - if (ShouldQuit()) - break; - } else { - if (bSession) { - bActive = hRenderWnd != nullptr && bVisible && - (SDL_GetKeyboardFocus() == hRenderWnd->Inner()); - if (bAllowInput) - bActive = true, bAllowInput = false; - if (BeginTimeStep(bRunning)) { - UpdateWorld(); - EndTimeStep(bRunning); - if (bVisible) { - if (bActive) - UserInput(); - bRenderOnce = true; - } - if (bRunning && bCapture) { - CaptureVideoFrame(); - } - } - if (m_pConsole) - m_pConsole->ParseCmd(); + bool consumed = pDlgMgr->ConsumeEvent(event, bShouldQuit); + consumed = consumed || pDI->ConsumeEvent(event); + consumed = consumed || gclient->RenderWndProc(event, bShouldQuit); } - } + } else { + if (bSession) { + bActive = hRenderWnd != nullptr && bVisible && + (SDL_GetKeyboardFocus() == hRenderWnd->Inner()); + if (bAllowInput) + bActive = true, bAllowInput = false; + if (BeginTimeStep(bRunning)) { + UpdateWorld(); + EndTimeStep(bRunning); + if (bVisible) { + if (bActive) + UserInput(); + bRenderOnce = true; + } + if (bRunning && bCapture) { + CaptureVideoFrame(); + } + } + if (m_pConsole) + m_pConsole->ParseCmd(); + } + } if (bRenderOnce && bVisible) { if (FAILED(Render3DEnvironment())) { @@ -2063,35 +2060,30 @@ HRESULT Orbiter::UserInput () if ((g_input && g_input->IsActive()) || (g_select && g_select->IsActive())) skipkbd = true; - if (didev = GetDInput()->GetKbdDevice()) { - ImGuiIO& io = ImGui::GetIO(); - // keyboard input: immediate key interpretation - hr = didev->GetDeviceState (sizeof(buffer), &buffer); - if ((hr == DIERR_NOTACQUIRED || hr == DIERR_INPUTLOST) && SUCCEEDED (didev->Acquire())) - hr = didev->GetDeviceState (sizeof(buffer), &buffer); - - // Direct input bypasses the proc loop so we skip it here - if (SUCCEEDED (hr) && !io.WantCaptureKeyboard) - for (i = 0; i < 256; i++) - simkstate[i] |= buffer[i]; - bool consume = BroadcastImmediateKeyboardEvent (simkstate); - if (!skipkbd && !consume) { - KbdInputImmediate_System (simkstate); - if (bRunning) KbdInputImmediate_OnRunning (simkstate); + ImGuiIO& io = ImGui::GetIO(); + // keyboard input: immediate key interpretation + auto numkey = 0; + const auto kstate = SDL_GetKeyboardState(&numkey); + for (i = 0; i < numkey; i++) { + if (i >= sizeof(buffer)) break; + buffer[i] = kstate[i] ? 0x80 : 0x00; + if (!io.WantCaptureKeyboard) + simkstate[i] |= buffer[i]; + } + + bool consume = BroadcastImmediateKeyboardEvent (simkstate); + if (!skipkbd && !consume) { + KbdInputImmediate_System (simkstate); + if (bRunning) KbdInputImmediate_OnRunning (simkstate); + } + // keyboard input: buffered key events + if (!io.WantCaptureKeyboard) { + BroadcastBufferedKeyboardEvent (buffer); + if (!skipkbd) { + KbdInputBuffered_System (buffer); + if (bRunning) KbdInputBuffered_OnRunning (buffer); } - - // keyboard input: buffered key events - hr = didev->GetDeviceData (sizeof(DIDEVICEOBJECTDATA), dod, &dwItems, 0); - if ((hr == DIERR_NOTACQUIRED || hr == DIERR_INPUTLOST) && SUCCEEDED (didev->Acquire())) - hr = didev->GetDeviceData (sizeof(DIDEVICEOBJECTDATA), dod, &dwItems, 0); - if (SUCCEEDED (hr) && !io.WantCaptureKeyboard) { - BroadcastBufferedKeyboardEvent (buffer, dod, dwItems); - if (!skipkbd) { - KbdInputBuffered_System (buffer, dod, dwItems); - if (bRunning) KbdInputBuffered_OnRunning (buffer, dod, dwItems); - } - } - //if (hr == DI_BUFFEROVERFLOW) MessageBeep (-1); + pDI->m_bufferedEvents.clear(); } for (i = 0; i < 15; i++) ctrlTotal[i] = ctrlKeyboard[i]; // update attitude requests @@ -2128,9 +2120,9 @@ bool Orbiter::SendKbdBuffered(DWORD key, DWORD *mod, DWORD nmod, bool onRunningO memset (buffer, 0, 256); for (int i = 0; i < nmod; i++) buffer[mod[i]] = 0x80; - BroadcastBufferedKeyboardEvent (buffer, &dod, 1); - KbdInputBuffered_System (buffer, &dod, 1); - KbdInputBuffered_OnRunning (buffer, &dod, 1); + BroadcastBufferedKeyboardEvent (buffer); + KbdInputBuffered_System (buffer); + KbdInputBuffered_OnRunning (buffer); return true; } @@ -2327,12 +2319,12 @@ void Orbiter::KbdInputImmediate_OnRunning (char *kstate) // Desc: General user keyboard buffered key interpretation. Processes keys // which are also interpreted when simulation is paused //----------------------------------------------------------------------------- -void Orbiter::KbdInputBuffered_System (char *kstate, DIDEVICEOBJECTDATA *dod, DWORD n) +void Orbiter::KbdInputBuffered_System (char *kstate) { - for (DWORD i = 0; i < n; i++) { + for (const auto& evt : pDI->m_bufferedEvents) { - if (!(dod[i].dwData & 0x80)) continue; // only process key down events - DWORD key = dod[i].dwOfs; + if (!evt.down) continue; // only process key down events + DWORD key = evt.scancode; if (keymap.IsLogicalKey(key, kstate, OAPI_LKEY_Pause)) TogglePause(); else if (keymap.IsLogicalKey(key, kstate, OAPI_LKEY_Quicksave)) Quicksave(); @@ -2386,12 +2378,11 @@ void Orbiter::KbdInputBuffered_System (char *kstate, DIDEVICEOBJECTDATA *dod, DW // Name: KbdInputBuffered_OnRunning () // Desc: User keyboard buffered key interpretation in running simulation //----------------------------------------------------------------------------- -void Orbiter::KbdInputBuffered_OnRunning (char *kstate, DIDEVICEOBJECTDATA *dod, DWORD n) +void Orbiter::KbdInputBuffered_OnRunning (char *kstate) { - for (DWORD i = 0; i < n; i++) { - - DWORD key = dod[i].dwOfs; - bool bdown = (dod[i].dwData & 0x80) != 0; + for (const auto &evt : pDI->m_bufferedEvents) { + DWORD key = evt.scancode; + bool bdown = evt.down; if (g_focusobj->ConsumeBufferedKey (key, bdown, kstate)) // offer key to vessel for processing continue; @@ -2413,7 +2404,7 @@ void Orbiter::KbdInputBuffered_OnRunning (char *kstate, DIDEVICEOBJECTDATA *dod, } else if (KEYMOD_SHIFT (kstate)) { // Shift-key combinations (reserved for MFD control) - int id = (KEYDOWN (kstate, DIK_LSHIFT) ? 0 : 1); + int id = (KEYDOWN (kstate, SDL_SCANCODE_LSHIFT) ? 0 : 1); g_pane->MFDConsumeKeyBuffered (id, key); } else if (KEYMOD_ALT (kstate)) { // ALT-Key combinations @@ -2548,18 +2539,28 @@ bool Orbiter::BroadcastImmediateKeyboardEvent (char *kstate) return consume; } -void Orbiter::BroadcastBufferedKeyboardEvent (char *kstate, DIDEVICEOBJECTDATA *dod, DWORD n) +void Orbiter::BroadcastBufferedKeyboardEvent (char *kstate) { - for (DWORD i = 0; i < n; i++) { + auto evt = pDI->m_bufferedEvents.begin(); + while (evt != pDI->m_bufferedEvents.end()) { bool consume = false; - if (!(dod[i].dwData & 0x80)) continue; // only process key down events - DWORD key = dod[i].dwOfs; + if (!evt->down) { + // only process key down events + ++evt; + continue; + } + DWORD key = evt->scancode; for (auto it = m_Plugin.begin(); it != m_Plugin.end(); it++) if (it->pModule && it->pModule->clbkProcessKeyboardBuffered(key, kstate, bRunning)) consume = true; - if (consume) dod[i].dwData = 0; // remove key from process queue + if (consume) { + // remove key from process queue + evt = pDI->m_bufferedEvents.erase(evt); + } else { + ++evt; + } } } diff --git a/Src/Orbiter/Orbiter.h b/Src/Orbiter/Orbiter.h index 3b53bf718..2b3bd3c35 100644 --- a/Src/Orbiter/Orbiter.h +++ b/Src/Orbiter/Orbiter.h @@ -310,14 +310,14 @@ class Orbiter { HRESULT UserInput (); void KbdInputImmediate_System (char *kstate); void KbdInputImmediate_OnRunning (char *buffer); - void KbdInputBuffered_System (char *kstate, DIDEVICEOBJECTDATA *dod, DWORD n); - void KbdInputBuffered_OnRunning (char *kstate, DIDEVICEOBJECTDATA *dod, DWORD n); + void KbdInputBuffered_System (char *kstate); + void KbdInputBuffered_OnRunning (char *kstate); void UserJoyInput_System (DIJOYSTATE2 *js); void UserJoyInput_OnRunning (DIJOYSTATE2 *js); bool MouseEvent (const SDL_Event &event, DWORD x, DWORD y); bool BroadcastMouseEvent (const SDL_Event &event, DWORD x, DWORD y); bool BroadcastImmediateKeyboardEvent (char *kstate); - void BroadcastBufferedKeyboardEvent (char *kstate, DIDEVICEOBJECTDATA *dod, DWORD n); + void BroadcastBufferedKeyboardEvent (char *kstate); void BroadcastGlobalInit(); From f0399744b675601cfcc1315ea1c0d250c2208ced Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Wed, 26 Feb 2025 15:51:24 -0600 Subject: [PATCH 41/51] SDLWrappers: OAPIFUNC/DLLEXPORT --- Orbitersdk/include/SDLWrappers.h | 5 +++-- Src/Orbiter/SDLWrappers.cpp | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Orbitersdk/include/SDLWrappers.h b/Orbitersdk/include/SDLWrappers.h index 3d138e8bd..7751c8e03 100644 --- a/Orbitersdk/include/SDLWrappers.h +++ b/Orbitersdk/include/SDLWrappers.h @@ -4,10 +4,11 @@ #include #include #include +#include namespace sdl { -class UnmanagedWindow { +class OAPIFUNC UnmanagedWindow { public: UnmanagedWindow(const UnmanagedWindow &) = delete; UnmanagedWindow &operator=(const UnmanagedWindow &) = delete; @@ -33,7 +34,7 @@ class UnmanagedWindow { SDL_Window *m_inner = nullptr; }; -class ManagedWindow { +class OAPIFUNC ManagedWindow { public: ManagedWindow(const ManagedWindow &) = delete; diff --git a/Src/Orbiter/SDLWrappers.cpp b/Src/Orbiter/SDLWrappers.cpp index 2dbc76d59..19be24256 100644 --- a/Src/Orbiter/SDLWrappers.cpp +++ b/Src/Orbiter/SDLWrappers.cpp @@ -1,9 +1,10 @@ +#define OAPI_IMPLEMENTATION #include "SDLWrappers.h" #include #include -sdl::ManagedWindow::ManagedWindow(const std::string_view title, const int width, +DLLEXPORT sdl::ManagedWindow::ManagedWindow(const std::string_view title, const int width, const int height, const SDL_WindowFlags flags) { m_inner = SDL_CreateWindow(title.data(), width, height, flags); @@ -47,7 +48,7 @@ sdl::ManagedWindow::ManagedWindow(const std::string_view title, const int width, }; } -sdl::ManagedWindow::~ManagedWindow() { +DLLEXPORT sdl::ManagedWindow::~ManagedWindow() { if (m_device && m_inner) SDL_ReleaseWindowFromGPUDevice(m_device, m_inner); if (m_device) @@ -56,7 +57,7 @@ sdl::ManagedWindow::~ManagedWindow() { SDL_DestroyWindow(m_inner); } -sdl::UnmanagedWindow::UnmanagedWindow(const std::string_view title, +DLLEXPORT sdl::UnmanagedWindow::UnmanagedWindow(const std::string_view title, const int width, const int height, const SDL_WindowFlags flags) { m_inner = SDL_CreateWindow(title.data(), width, height, flags); @@ -66,7 +67,7 @@ sdl::UnmanagedWindow::UnmanagedWindow(const std::string_view title, } } -sdl::UnmanagedWindow::~UnmanagedWindow() { +DLLEXPORT sdl::UnmanagedWindow::~UnmanagedWindow() { if (m_inner) SDL_DestroyWindow(m_inner); -} +} \ No newline at end of file From 3e1c67c0a83e067f00559382d8272fa05414ba3e Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Wed, 26 Feb 2025 15:54:16 -0600 Subject: [PATCH 42/51] Fix mouse --- Src/Orbiter/Launchpad.cpp | 2 + Src/Orbiter/Orbiter.cpp | 85 ++++++++++++++++----------------------- Src/Orbiter/htmlctrl.c | 7 ++-- 3 files changed, 41 insertions(+), 53 deletions(-) diff --git a/Src/Orbiter/Launchpad.cpp b/Src/Orbiter/Launchpad.cpp index b5bbbcd93..760a42aa9 100644 --- a/Src/Orbiter/Launchpad.cpp +++ b/Src/Orbiter/Launchpad.cpp @@ -324,6 +324,7 @@ INT_PTR orbiter::LaunchpadDialog::DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, if (pCfg->CfgDemoPrm.bBlockExit) return TRUE; UpdateConfig (); DestroyWindow (hWnd); + g_pOrbiter->SetShouldQuit(); return TRUE; case WM_DESTROY: if (pCfg->CfgDemoPrm.bDemo && timerid) { @@ -430,6 +431,7 @@ INT_PTR orbiter::LaunchpadDialog::DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, PostMessage (hWnd, WM_COMMAND, IDLAUNCH, 0); } return 0; + default: break; } return FALSE; } diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 91744d4a0..586d5356d 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -171,7 +171,7 @@ int main(int argc, char **argv) { #ifdef _CRTDBG_MAP_ALLOC _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif - SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_EVENTS); + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS); SDL_SetAppMetadata("OpenOrbiter", SIG7, "uk.ac.ucl.medphys.orbit"); @@ -673,7 +673,6 @@ VOID Orbiter::Launch (const char *scenario) long m0 = memstat->HeapUsage(); CreateRenderWindow (pConfig, scenario); - SDL_InitSubSystem(SDL_INIT_VIDEO); simheapsize = memstat->HeapUsage()-m0; SetCursor (hCursor); } @@ -954,7 +953,6 @@ void Orbiter::CloseSession () } } LOGOUT("**** Closing simulation session"); - SDL_QuitSubSystem(SDL_INIT_VIDEO); } // ======================================================================= @@ -1017,45 +1015,40 @@ void Orbiter::Run() { Launch(pConfig->CfgCmdlinePrm.LaunchScenario.c_str()); SDL_Event event = {}; - MSG msg; - PeekMessage (&msg, NULL, 0U, 0U, PM_NOREMOVE); - - bool bpCanRender = true; - while (!ShouldQuit() && msg.message != WM_QUIT) { - if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { - if (!m_pLaunchpad || !m_pLaunchpad->ConsumeMessage(&msg)) { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - if (msg.message == WM_CLOSE || msg.message == WM_DESTROY || msg.message == WM_QUIT) - break; - } else if (SDL_PollEvent(&event)) { - if (gclient && hRenderWnd != nullptr) { - bool consumed = pDlgMgr->ConsumeEvent(event, bShouldQuit); - consumed = consumed || pDI->ConsumeEvent(event); - consumed = consumed || gclient->RenderWndProc(event, bShouldQuit); - } - } else { - if (bSession) { - bActive = hRenderWnd != nullptr && bVisible && - (SDL_GetKeyboardFocus() == hRenderWnd->Inner()); - if (bAllowInput) - bActive = true, bAllowInput = false; - if (BeginTimeStep(bRunning)) { - UpdateWorld(); - EndTimeStep(bRunning); - if (bVisible) { - if (bActive) - UserInput(); - bRenderOnce = true; - } - if (bRunning && bCapture) { - CaptureVideoFrame(); - } + bool bpCanRender = true; + while (!ShouldQuit()) { + while (SDL_PollEvent(&event)) { + if (gclient && hRenderWnd != nullptr) { + bool consumed = pDlgMgr->ConsumeEvent(event, bShouldQuit); + consumed = consumed || pDI->ConsumeEvent(event); + consumed = consumed || gclient->RenderWndProc(event, bShouldQuit); + } + if (event.type == SDL_EVENT_QUIT) { + bShouldQuit = true; + } + if (bShouldQuit) { + break; + } + } + if (bSession) { + bActive = hRenderWnd != nullptr && bVisible && + (SDL_GetKeyboardFocus() == hRenderWnd->Inner()); + if (bAllowInput) + bActive = true, bAllowInput = false; + if (BeginTimeStep(bRunning)) { + UpdateWorld(); + EndTimeStep(bRunning); + if (bVisible) { + if (bActive) + UserInput(); + bRenderOnce = true; + } + if (bRunning && bCapture) { + CaptureVideoFrame(); } - if (m_pConsole) - m_pConsole->ParseCmd(); } + if (m_pConsole) + m_pConsole->ParseCmd(); } if (bRenderOnce && bVisible) { @@ -1128,13 +1121,9 @@ void Orbiter::InitRotationMode () { bKeepFocus = true; - if (g_iCursorShowCount == 0) { - g_iCursorShowCount -= 1; - SDL_HideCursor(); - } - if (hRenderWnd) { SDL_SetWindowRelativeMouseMode(hRenderWnd->Inner(), true); + SDL_CaptureMouse(true); } } @@ -1142,13 +1131,9 @@ void Orbiter::ExitRotationMode () { bKeepFocus = false; - if (g_iCursorShowCount < 0) { - SDL_ShowCursor(); - g_iCursorShowCount += 1; - } - if (hRenderWnd) { SDL_SetWindowRelativeMouseMode(hRenderWnd->Inner(), false); + SDL_CaptureMouse(false); } } diff --git a/Src/Orbiter/htmlctrl.c b/Src/Orbiter/htmlctrl.c index 74efbd94b..9d6077664 100644 --- a/Src/Orbiter/htmlctrl.c +++ b/Src/Orbiter/htmlctrl.c @@ -1914,8 +1914,9 @@ LRESULT CALLBACK WindowProcDummy(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa void RegisterHtmlCtrl (HINSTANCE hInstance, BOOL active) { - if (OleInitialize(NULL) == S_OK) - { + // OleInitialize is already called as part of SDL setup + //if (OleInitialize(NULL) == S_OK) + //{ WNDCLASSEX wc; // Register the class of our window to host the browser. 'WindowProc' is our message handler @@ -1926,5 +1927,5 @@ void RegisterHtmlCtrl (HINSTANCE hInstance, BOOL active) wc.lpfnWndProc = (active ? WindowProc : WindowProcDummy); wc.lpszClassName = &ClassName[0]; RegisterClassEx(&wc); - } + //} } From a62ae38a051af2b868d2272c49af3dd2c3fedd28 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Wed, 26 Feb 2025 21:27:34 -0600 Subject: [PATCH 43/51] Fix TerrainToolkit mouse processing --- OVP/D3D9Client/samples/TerrainToolKit/ToolKit.cpp | 6 +++--- OVP/D3D9Client/samples/TerrainToolKit/ToolKit.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OVP/D3D9Client/samples/TerrainToolKit/ToolKit.cpp b/OVP/D3D9Client/samples/TerrainToolKit/ToolKit.cpp index c3a3f61fd..d872b6b97 100644 --- a/OVP/D3D9Client/samples/TerrainToolKit/ToolKit.cpp +++ b/OVP/D3D9Client/samples/TerrainToolKit/ToolKit.cpp @@ -1135,7 +1135,7 @@ void ToolKit::clbkMouseClick(int iUser, void *pData) // ================================================================================================= // Orbiter Module Callback // -bool ToolKit::clbkProcessMouse(UINT event, DWORD state, DWORD x, DWORD y) +bool ToolKit::clbkProcessMouse(const SDL_Event& event, DWORD x, DWORD y) { if (!pCore) return false; @@ -1148,7 +1148,7 @@ bool ToolKit::clbkProcessMouse(UINT event, DWORD state, DWORD x, DWORD y) pick.dist = 1e16f; pick.grp_inst = -1; - if (event == WM_LBUTTONDOWN) { + if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_LEFT) { down_corner = -1; // down_corner is the ID of the draggable corner balls if (bImport && hOverlay) { for (int i = 0; i < 4; i++) { @@ -1160,7 +1160,7 @@ bool ToolKit::clbkProcessMouse(UINT event, DWORD state, DWORD x, DWORD y) } } - if (event == WM_LBUTTONUP) down_corner = -1; + if (event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_LEFT) down_corner = -1; if ((x != xpos || y != ypos) && down_corner >= 0) diff --git a/OVP/D3D9Client/samples/TerrainToolKit/ToolKit.h b/OVP/D3D9Client/samples/TerrainToolKit/ToolKit.h index e9d519a18..008d72884 100644 --- a/OVP/D3D9Client/samples/TerrainToolKit/ToolKit.h +++ b/OVP/D3D9Client/samples/TerrainToolKit/ToolKit.h @@ -129,7 +129,7 @@ class ToolKit : public gcGUIApp, public oapi::Module void clbkSimulationStart(RenderMode rm); void clbkSimulationEnd(); void clbkPreStep(double simt, double simdt, double mjd); - bool clbkProcessMouse(UINT event, DWORD state, DWORD x, DWORD y); + bool clbkProcessMouse(const SDL_Event& event, DWORD x, DWORD y) override; bool clbkProcessKeyboardBuffered(DWORD key, char kstate[256], bool simRunning); // From D3D9Client From c179cc6c5210a8837520ae89241623017f9defef Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Fri, 28 Feb 2025 20:14:03 -0600 Subject: [PATCH 44/51] Joystick with SDL3 --- Src/Orbiter/Config.cpp | 9 +- Src/Orbiter/Config.h | 4 +- Src/Orbiter/Input.cpp | 223 ++++++++--------------------------- Src/Orbiter/Input.h | 30 +++-- Src/Orbiter/OptionsPages.cpp | 41 +++++-- Src/Orbiter/OptionsPages.h | 6 + Src/Orbiter/Orbiter.cpp | 92 +++++++-------- Src/Orbiter/Orbiter.h | 9 +- 8 files changed, 150 insertions(+), 264 deletions(-) diff --git a/Src/Orbiter/Config.cpp b/Src/Orbiter/Config.cpp index 0a37e604c..8330c148b 100644 --- a/Src/Orbiter/Config.cpp +++ b/Src/Orbiter/Config.cpp @@ -194,9 +194,9 @@ CFG_DEVPRM CfgDevPrm_default = { CFG_JOYSTICKPRM CfgJoystickPrm_default = { 0, // Joy_idx (joystick device index, 0=disabled) - 2500, // Deadzone (neutralise joystick axes within 20% of central position) + 6500, // Deadzone (neutralise joystick axes within 20% of central position) 1, // ThrottleAxis (z-axis by default) - 9500, // ThrottleSaturation (saturate throttle at the last 5% each end) + 31100, // ThrottleSaturation (saturate throttle at the last 5% each end) true // bThrottleIgnore (ignore throttle setting on simulation start) }; @@ -543,6 +543,7 @@ bool Config::Load(const char *fname) for (int joyix = 0; joyix < njoy; joyix++) { if (SDL_GetJoystickGUIDForID(joylist[joyix]) == guid) { CfgJoystickPrm.Joy_idx = joylist[joyix]; + break; } } SDL_free(joylist); @@ -550,9 +551,9 @@ bool Config::Load(const char *fname) if (GetInt (ifs, "JoystickThrottleAxis", i)) CfgJoystickPrm.ThrottleAxis = max (0, min (3, i)); if (GetInt (ifs, "JoystickThrottleSaturation", i)) - CfgJoystickPrm.ThrottleSaturation = max (0, min (10000, i)); + CfgJoystickPrm.ThrottleSaturation = max (0, min (32768, i)); if (GetInt (ifs, "JoystickDeadzone", i)) - CfgJoystickPrm.Deadzone = max (0, min (10000, i)); + CfgJoystickPrm.Deadzone = max (0, min (32768, i)); GetBool (ifs, "IgnoreThrottleOnStart", CfgJoystickPrm.bThrottleIgnore); // planet render parameters diff --git a/Src/Orbiter/Config.h b/Src/Orbiter/Config.h index a7fa77420..02407183e 100644 --- a/Src/Orbiter/Config.h +++ b/Src/Orbiter/Config.h @@ -223,9 +223,9 @@ struct CFG_DEVPRM { struct CFG_JOYSTICKPRM { SDL_JoystickID Joy_idx; // joystick device index (0=disabled) - DWORD Deadzone; // central deadzone range for all axes (0-10000) + DWORD Deadzone; // central deadzone range for all axes (0-32768) DWORD ThrottleAxis; // joystick throttle axis (0=none, 1=z-axis, 2=slider 0, 3=slider 1) - DWORD ThrottleSaturation; // saturation level for joystick throttle control (0-10000) + DWORD ThrottleSaturation; // saturation level for joystick throttle control (0-32768) bool bThrottleIgnore; // ignore joystick throttle setting on start }; diff --git a/Src/Orbiter/Input.cpp b/Src/Orbiter/Input.cpp index a208e75b7..e85124e56 100644 --- a/Src/Orbiter/Input.cpp +++ b/Src/Orbiter/Input.cpp @@ -9,54 +9,20 @@ #include "Log.h" #include "Orbiter.h" -DInput::DInput (Orbiter *pOrbiter) +DInput::DInput (Orbiter *pOrbiter) : orbiter(pOrbiter), joystick(nullptr), joyprop(), m_hWnd(nullptr) { - orbiter = pOrbiter; - diframe = NULL; - m_hWnd = NULL; } DInput::~DInput () { - Destroy(); -} - -HRESULT DInput::Create (HINSTANCE hInst) -{ - if (NULL == (diframe = new CDIFramework7())) { - LOGOUT_ERR ("DirectInput: Could not create DI environment"); - return E_OUTOFMEMORY; - } - return diframe->Create (hInst); -} - -void DInput::Destroy () -{ - if (diframe) { - delete diframe; - diframe = NULL; - } + DestroyDevices(); } void DInput::SetRenderWindow(HWND hWnd) { - if (diframe) - diframe->DestroyDevices(); m_hWnd = hWnd; } -bool DInput::CreateKbdDevice() -{ - if (!m_hWnd) return false; // no render window defined - - if (FAILED (diframe->CreateKbdDevice (m_hWnd))) { - LOGOUT("ERROR: Could not create keyboard device"); - return false; // we need the keyboard, so give up - } - GetKbdDevice()->Acquire(); - return true; -} - bool DInput::CreateJoyDevice () { if (!m_hWnd) return false; // no render window defined @@ -64,34 +30,23 @@ bool DInput::CreateJoyDevice () Config *pcfg = orbiter->Cfg(); if (!pcfg->CfgJoystickPrm.Joy_idx) return false; // no joystick requested - if (FAILED (diframe->CreateJoyDevice (m_hWnd, pcfg->CfgJoystickPrm.Joy_idx-1))) { - LOGOUT_ERR("Could not create joystick device"); - return false; - } - - HRESULT hr = GetJoyDevice()->Acquire(); - if (hr == DIERR_OTHERAPPHASPRIO) { - Sleep(1000); - hr = GetJoyDevice()->Acquire(); - } - switch (hr) { - case DIERR_OTHERAPPHASPRIO: - hr = DI_OK; - break; - } - - if (SetJoystickProperties () != DI_OK) { - LOGOUT_ERR("Could not set joystick properties"); + joystick = SDL_OpenJoystick(pcfg->CfgJoystickPrm.Joy_idx); + if (!joystick) { + LOGOUT_ERR("Could not acquire joystick: %s", SDL_GetError()); return false; } + SetJoystickProperties(); return true; } void DInput::DestroyDevices () { - diframe->DestroyDevices(); + if (joystick) { + SDL_CloseJoystick(joystick); + joystick = nullptr; + } } void DInput::OptionChanged(DWORD cat, DWORD item) @@ -99,154 +54,72 @@ void DInput::OptionChanged(DWORD cat, DWORD item) if (cat == OPTCAT_JOYSTICK) { switch (item) { case OPTITEM_JOYSTICK_DEVICE: - diframe->DestroyJoyDevice(); + DestroyDevices(); CreateJoyDevice(); break; case OPTITEM_JOYSTICK_PARAM: SetJoystickProperties(); break; + default: break; } } } -bool DInput::PollJoystick (DIJOYSTATE2 *js) -{ - // todo: return joystick data in device-independent format - // allow collecting data from more than one joystick - - LPDIRECTINPUTDEVICE8 dev = GetJoyDevice(); - if (!dev) return false; - HRESULT hr = dev->Poll(); - //if (hr == DI_OK || hr == DI_NOEFFECT) // ignore error flag from poll. appears to occasionally return DIERR_UNPLUGGED - hr = dev->GetDeviceState (sizeof(DIJOYSTATE2), js); - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { - if (SUCCEEDED(dev->Acquire())) { - dev->Poll(); - hr = dev->GetDeviceState(sizeof(DIJOYSTATE2), js); - } - } - return (hr == S_OK); +bool DInput::PollJoystick (JoyState *js) const { + const auto& joyprm = orbiter->Cfg()->CfgJoystickPrm; + const auto deadzone = static_cast(joyprm.Deadzone); + js->xAx = PollAxisWithDeadzone(joyprop.xAxId, deadzone); + js->yAx = PollAxisWithDeadzone(joyprop.yAxId, deadzone); + if (joyprop.bRudder) { + js->zRot = PollAxisWithDeadzone(joyprop.zRotId, deadzone); + } else js->zRot = 0; + if (joyprop.bThrottle) { + js->throttle = PollAxisWithDeadzone(joyprop.ThrottleOfs, deadzone); + } else js->throttle = 0; + js->hat = SDL_GetJoystickHat(joystick, 0); + js->btn3 = SDL_GetJoystickButton(joystick, 2); + return true; } -HRESULT DInput::SetJoystickProperties () -{ - LPDIRECTINPUTDEVICE8 dev = GetJoyDevice(); - if (!dev) return DI_OK; +Sint16 DInput::PollAxisWithDeadzone(const int axis, const Sint16 deadzone) const { + if (!joystick) return 0; - HRESULT hr; - DIPROPRANGE diprg; - DIPROPDWORD diprw; - joyprop.bRudder = false; - joyprop.bThrottle = false; - Config *pcfg = orbiter->Cfg(); - - // x-axis range - diprg.diph.dwSize = sizeof (diprg); - diprg.diph.dwHeaderSize = sizeof (diprg.diph); - diprg.diph.dwObj = DIJOFS_X; - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.lMin = -1000; - diprg.lMax = +1000; - if ((hr = dev->SetProperty (DIPROP_RANGE, &diprg.diph)) != DI_OK) - return hr; - - // x-axis deadzone - diprw.diph.dwSize = sizeof (diprw); - diprw.diph.dwHeaderSize = sizeof (diprw.diph); - diprw.diph.dwObj = DIJOFS_X; - diprw.diph.dwHow = DIPH_BYOFFSET; - diprw.dwData = pcfg->CfgJoystickPrm.Deadzone; - if ((hr = dev->SetProperty (DIPROP_DEADZONE, &diprw.diph)) != DI_OK) - return hr; + const Sint16 axval = SDL_GetJoystickAxis(joystick, axis); - // y-axis range - diprg.diph.dwSize = sizeof (diprg); - diprg.diph.dwHeaderSize = sizeof (diprg.diph); - diprg.diph.dwObj = DIJOFS_Y; - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.lMin = -1000; - diprg.lMax = +1000; - if ((hr = dev->SetProperty (DIPROP_RANGE, &diprg.diph)) != DI_OK) - return hr; - - // y-axis deadzone - diprw.diph.dwSize = sizeof (diprw); - diprw.diph.dwHeaderSize = sizeof (diprw.diph); - diprw.diph.dwObj = DIJOFS_Y; - diprw.diph.dwHow = DIPH_BYOFFSET; - diprw.dwData = pcfg->CfgJoystickPrm.Deadzone; - if ((hr = dev->SetProperty (DIPROP_DEADZONE, &diprw.diph)) != DI_OK) - return hr; + if (abs(axval) < deadzone) return 0; + return axval; +} - joyprop.bRudder = true; +void DInput::SetJoystickProperties() { + if (!joystick) return; + auto naxes = SDL_GetNumJoystickAxes(joystick); + joyprop.xAxId = 0; + joyprop.yAxId = 1; + if (naxes > 2) { + // Probably have a rudder axis. + // TODO: better input config + joyprop.bRudder = true; + joyprop.zRotId = 2; + } joyprop.bThrottle = true; - - diprg.diph.dwSize = sizeof (diprg); - diprg.diph.dwHeaderSize = sizeof (diprg.diph); - diprg.diph.dwObj = DIJOFS_RZ; - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.lMin = -1000; - diprg.lMax = +1000; - if (dev->SetProperty (DIPROP_RANGE, &diprg.diph) != DI_OK) - joyprop.bRudder = false; - - diprw.diph.dwSize = sizeof (diprw); - diprw.diph.dwHeaderSize = sizeof (diprw.diph); - diprw.diph.dwObj = DIJOFS_RZ; - diprw.diph.dwHow = DIPH_BYOFFSET; - diprw.dwData = pcfg->CfgJoystickPrm.Deadzone; - if (dev->SetProperty (DIPROP_DEADZONE, &diprw.diph) != DI_OK) - joyprop.bRudder = false; - - // z-axis range (throttle) - DWORD thaxis; - DIJOYSTATE2 js2; - switch (pcfg->CfgJoystickPrm.ThrottleAxis) { + switch (orbiter->Cfg()->CfgJoystickPrm.ThrottleAxis) { case 1: LOGOUT ("Joystick throttle: Z-AXIS"); - thaxis = DIJOFS_Z; - joyprop.ThrottleOfs = (BYTE*)&js2.lZ - (BYTE*)&js2; + joyprop.ThrottleOfs = 2; break; case 2: LOGOUT ("Joystick throttle: SLIDER 0"); - thaxis = DIJOFS_SLIDER(0); - joyprop.ThrottleOfs = (BYTE*)&js2.rglSlider[0] - (BYTE*)&js2; + joyprop.ThrottleOfs = 3; break; case 3: LOGOUT ("Joystick throttle: SLIDER 1"); - thaxis = DIJOFS_SLIDER(1); - joyprop.ThrottleOfs = (BYTE*)&js2.rglSlider[1] - (BYTE*)&js2; + joyprop.ThrottleOfs = 4; break; default: joyprop.bThrottle = false; LOGOUT ("Joystick throttle disabled by user"); - return DI_OK; - } - - diprg.diph.dwSize = sizeof (diprg); - diprg.diph.dwHeaderSize = sizeof (diprg.diph); - diprg.diph.dwObj = thaxis; - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.lMin = -1000; - diprg.lMax = 0; - if ((hr = dev->SetProperty (DIPROP_RANGE, &diprg.diph)) != DI_OK) { - joyprop.bThrottle = false; - LOGOUT("No joystick throttle control detected"); - LOGOUT_DIERR(hr); - return DI_OK; - } - LOGOUT("Joystick throttle control detected"); - - // throttle saturation at extreme ends - diprw.diph.dwSize = sizeof (diprw); - diprw.diph.dwHeaderSize = sizeof (diprw.diph); - diprw.diph.dwObj = thaxis; - diprw.diph.dwHow = DIPH_BYOFFSET; - diprw.dwData = pcfg->CfgJoystickPrm.ThrottleSaturation; - if (dev->SetProperty (DIPROP_SATURATION, &diprw.diph) != DI_OK) { - LOGOUT_ERR("Setting joystick throttle saturation failed"); + break; } - return DI_OK; } bool DInput::ConsumeEvent(const SDL_Event &event) { diff --git a/Src/Orbiter/Input.h b/Src/Orbiter/Input.h index 94e17b088..4490d2a13 100644 --- a/Src/Orbiter/Input.h +++ b/Src/Orbiter/Input.h @@ -13,6 +13,15 @@ #include #include +struct JoyState { + Sint16 xAx; + Sint16 yAx; + Sint16 zRot; + Sint16 throttle; + Uint8 hat; + bool btn3; +}; + class DInput { friend class Orbiter; @@ -20,40 +29,39 @@ class DInput { DInput (Orbiter *pOrbiter); ~DInput (); - HRESULT Create (HINSTANCE hInst); - void Destroy (); - void SetRenderWindow(HWND hWnd); - bool CreateKbdDevice(); bool CreateJoyDevice (); void DestroyDevices (); - inline CDIFramework7 *GetDIFrame() const { return diframe; } - inline const LPDIRECTINPUTDEVICE8 GetKbdDevice() const { return diframe->GetKbdDevice(); } - inline const LPDIRECTINPUTDEVICE8 GetJoyDevice() const { return diframe->GetJoyDevice(); } + inline SDL_Joystick* GetJoyDevice() const { return joystick; } void OptionChanged(DWORD cat, DWORD item); - bool PollJoystick (DIJOYSTATE2 *js); + bool PollJoystick (JoyState *js) const; struct JoyProp { bool bThrottle; // joystick has throttle control bool bRudder; // joystick has rudder control - int ThrottleOfs; // throttle data offset + int ThrottleOfs; // throttle axis ID + int xAxId; // X-axis ID + int yAxId; // Y-axis ID + int zRotId; // Z rotation axis ID }; bool ConsumeEvent(const SDL_Event &event); protected: - HRESULT SetJoystickProperties (); + void SetJoystickProperties (); private: Orbiter *orbiter; - CDIFramework7 *diframe; + SDL_Joystick* joystick; JoyProp joyprop; HWND m_hWnd; std::list m_bufferedEvents; + + Sint16 PollAxisWithDeadzone(int axis, Sint16 deadzone) const; }; #endif // !__INPUT_H \ No newline at end of file diff --git a/Src/Orbiter/OptionsPages.cpp b/Src/Orbiter/OptionsPages.cpp index bb22b42e1..19f728785 100644 --- a/Src/Orbiter/OptionsPages.cpp +++ b/Src/Orbiter/OptionsPages.cpp @@ -1147,10 +1147,19 @@ BOOL OptionsPage_UI::OnCommand(HWND hPage, WORD ctrlId, WORD notification, HWND // ====================================================================== OptionsPage_Joystick::OptionsPage_Joystick(OptionsPageContainer* container) - : OptionsPage(container) + : OptionsPage(container), m_joylist(nullptr), m_njoy(0) { } + OptionsPage_Joystick::~OptionsPage_Joystick() { + if (m_joylist) { + SDL_free(m_joylist); + m_joylist = nullptr; + m_njoy = 0; + } +} + + // ---------------------------------------------------------------------- int OptionsPage_Joystick::ResourceId() const @@ -1180,16 +1189,24 @@ void OptionsPage_Joystick::UpdateControls(HWND hPage) { char cbuf[256]; - SendDlgItemMessage(hPage, IDC_OPT_JOY_DEVICE, CB_SETCURSEL, (WPARAM)Cfg()->CfgJoystickPrm.Joy_idx, 0); + auto joyix = 0; + for (int i = 0; i < m_njoy; ++i) { + if (Cfg()->CfgJoystickPrm.Joy_idx == m_joylist[i]) { + joyix = i + 1; + break; + } + } + + SendDlgItemMessage(hPage, IDC_OPT_JOY_DEVICE, CB_SETCURSEL, (WPARAM)joyix, 0); SendDlgItemMessage(hPage, IDC_OPT_JOY_THROTTLE, CB_SETCURSEL, (WPARAM)Cfg()->CfgJoystickPrm.ThrottleAxis, 0); SendDlgItemMessage(hPage, IDC_OPT_JOY_INIT, BM_SETCHECK, Cfg()->CfgJoystickPrm.bThrottleIgnore ? BST_CHECKED : BST_UNCHECKED, 0); - int sat = Cfg()->CfgJoystickPrm.ThrottleSaturation / 10; + int sat = Cfg()->CfgJoystickPrm.ThrottleSaturation; oapiSetGaugePos(GetDlgItem(hPage, IDC_OPT_JOY_SAT), sat); sprintf(cbuf, "%d", sat); SetWindowText(GetDlgItem(hPage, IDC_OPT_JOY_STATIC1), cbuf); - int dz = Cfg()->CfgJoystickPrm.Deadzone / 10; + int dz = Cfg()->CfgJoystickPrm.Deadzone; oapiSetGaugePos(GetDlgItem(hPage, IDC_OPT_JOY_DEAD), dz); sprintf(cbuf, "%d", dz); SetWindowText(GetDlgItem(hPage, IDC_OPT_JOY_STATIC2), cbuf); @@ -1210,21 +1227,19 @@ BOOL OptionsPage_Joystick::OnInitDialog(HWND hPage, WPARAM wParam, LPARAM lParam { OptionsPage::OnInitDialog(hPage, wParam, lParam); - DWORD ndev; - DIDEVICEINSTANCE* joylist; - g_pOrbiter->GetDInput()->GetJoysticks(&joylist, &ndev); + m_joylist = SDL_GetJoysticks(&m_njoy); SendDlgItemMessage(hPage, IDC_OPT_JOY_DEVICE, CB_RESETCONTENT, 0, 0); SendDlgItemMessage(hPage, IDC_OPT_JOY_DEVICE, CB_ADDSTRING, 0, (LPARAM)""); - for (int i = 0; i < ndev; i++) - SendDlgItemMessage(hPage, IDC_OPT_JOY_DEVICE, CB_ADDSTRING, 0, (LPARAM)(joylist[i].tszProductName)); + for (int i = 0; i < m_njoy; i++) + SendDlgItemMessage(hPage, IDC_OPT_JOY_DEVICE, CB_ADDSTRING, 0, (LPARAM)(SDL_GetJoystickNameForID(m_joylist[i]))); const char* thmode[4] = { "", "Z-axis", "Slider 0", "Slider 1" }; SendDlgItemMessage(hPage, IDC_OPT_JOY_THROTTLE, CB_RESETCONTENT, 0, 0); for (int i = 0; i < ARRAYSIZE(thmode); i++) SendDlgItemMessage(hPage, IDC_OPT_JOY_THROTTLE, CB_ADDSTRING, 0, (LPARAM)thmode[i]); - GAUGEPARAM gp = { 0, 1000, GAUGEPARAM::LEFT, GAUGEPARAM::BLACK }; + GAUGEPARAM gp = { 0, 32768, GAUGEPARAM::LEFT, GAUGEPARAM::BLACK }; oapiSetGaugeParams(GetDlgItem(hPage, IDC_OPT_JOY_SAT), &gp); oapiSetGaugeParams(GetDlgItem(hPage, IDC_OPT_JOY_DEAD), &gp); @@ -1239,7 +1254,7 @@ BOOL OptionsPage_Joystick::OnCommand(HWND hPage, WORD ctrlId, WORD notification, case IDC_OPT_JOY_DEVICE: if (notification == CBN_SELCHANGE) { DWORD idx = (DWORD)SendDlgItemMessage(hPage, IDC_OPT_JOY_DEVICE, CB_GETCURSEL, 0, 0); - Cfg()->CfgJoystickPrm.Joy_idx = idx; + Cfg()->CfgJoystickPrm.Joy_idx = m_joylist[idx - 1]; g_pOrbiter->OnOptionChanged(OPTCAT_JOYSTICK, OPTITEM_JOYSTICK_DEVICE); UpdateControls(hPage); return FALSE; @@ -1276,7 +1291,7 @@ BOOL OptionsPage_Joystick::OnHScroll(HWND hPage, WPARAM wParam, LPARAM lParam) case SB_LINELEFT: case SB_LINERIGHT: val = HIWORD(wParam); - Cfg()->CfgJoystickPrm.ThrottleSaturation = val * 10; + Cfg()->CfgJoystickPrm.ThrottleSaturation = val; UpdateControls(hPage); g_pOrbiter->OnOptionChanged(OPTCAT_JOYSTICK, OPTITEM_JOYSTICK_PARAM); return 0; @@ -1288,7 +1303,7 @@ BOOL OptionsPage_Joystick::OnHScroll(HWND hPage, WPARAM wParam, LPARAM lParam) case SB_LINELEFT: case SB_LINERIGHT: val = HIWORD(wParam); - Cfg()->CfgJoystickPrm.Deadzone = val * 10; + Cfg()->CfgJoystickPrm.Deadzone = val; UpdateControls(hPage); g_pOrbiter->OnOptionChanged(OPTCAT_JOYSTICK, OPTITEM_JOYSTICK_PARAM); return 0; diff --git a/Src/Orbiter/OptionsPages.h b/Src/Orbiter/OptionsPages.h index 8e44fb7eb..76bd45714 100644 --- a/Src/Orbiter/OptionsPages.h +++ b/Src/Orbiter/OptionsPages.h @@ -17,6 +17,7 @@ #include #include "CustomControls.h" #include "OrbiterAPI.h" +#include class OptionsPage; class Config; @@ -326,6 +327,7 @@ class OptionsPage_UI : public OptionsPage { class OptionsPage_Joystick : public OptionsPage { public: OptionsPage_Joystick(OptionsPageContainer* container); + ~OptionsPage_Joystick() override; int ResourceId() const; const char* Name() const; const HELPCONTEXT* HelpContext() const; @@ -335,6 +337,10 @@ class OptionsPage_Joystick : public OptionsPage { BOOL OnInitDialog(HWND hPage, WPARAM wParam, LPARAM lParam); BOOL OnCommand(HWND hPage, WORD ctrlId, WORD notification, HWND hCtrl); BOOL OnHScroll(HWND hPage, WPARAM wParam, LPARAM lParam); + +private: + SDL_JoystickID* m_joylist; + int m_njoy; }; /************************************************************************ diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 586d5356d..779d29b76 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -375,12 +375,6 @@ bool Orbiter::Create() pConfig->Load(MasterConfigFile); strcpy (cfgpath, pConfig->CfgDirPrm.ConfigDir); cfglen = strlen (cfgpath); - if (FAILED (hr = pDI->Create (hInst))) return false; - - // // validate configuration - // if (SDL_GetJoystickNameForID(pConfig->CfgJoystickPrm.Joy_idx) == nullptr) - // pConfig->CfgJoystickPrm.Joy_idx = 0; - // Read key mapping from file (or write default keymap) if (!keymap.Read ("keymap.cfg")) keymap.Write ("keymap.cfg"); @@ -707,12 +701,6 @@ Orbiter::CreateRenderWindow(Config *pCfg, const char* scenario) pDI->SetRenderWindow(hRenderWnd->Win32Handle()); bActive = true; - // Create keyboard device - if (!pDI->CreateKbdDevice ()) { - CloseSession (); - return 0; - } - // Create joystick device if (pDI->CreateJoyDevice ()) plZ4 = 1; // invalidate @@ -848,9 +836,9 @@ Orbiter::CreateRenderWindow(Config *pCfg, const char* scenario) // suppress throttle update on launch if (pDI->joyprop.bThrottle && pCfg->CfgJoystickPrm.bThrottleIgnore) { - DIJOYSTATE2 js; + JoyState js; if (pDI->PollJoystick(&js)) - plZ4 = *(long*)(((BYTE*)&js) + pDI->joyprop.ThrottleOfs) >> 3; + plZ4 = js.throttle; } return hRenderWnd; @@ -2074,7 +2062,7 @@ HRESULT Orbiter::UserInput () for (i = 0; i < 15; i++) ctrlTotal[i] = ctrlKeyboard[i]; // update attitude requests // joystick input - DIJOYSTATE2 js; + JoyState js; if (pDI->PollJoystick (&js)) { UserJoyInput_System (&js); // general joystick functions if (bRunning) UserJoyInput_OnRunning (&js); // joystick vessel control functions @@ -2409,33 +2397,32 @@ void Orbiter::KbdInputBuffered_OnRunning (char *kstate) // Name: UserJoyInput_System () // Desc: General user joystick input (also functional when paused) //----------------------------------------------------------------------------- -void Orbiter::UserJoyInput_System (DIJOYSTATE2 *js) +void Orbiter::UserJoyInput_System (JoyState *js) { - if (LOWORD (js->rgdwPOV[0]) != 0xFFFF) { - DWORD dir = js->rgdwPOV[0]; + if (js->hat != SDL_HAT_CENTERED) { if (g_camera->IsExternal()) { // use the joystick's coolie hat to rotate external camera - if (js->rgbButtons[2]) { // shift instrument panel - if (dir < 5000 || dir > 31000) g_camera->Rotate (0, td.SysDT); - else if (dir > 13000 && dir < 23000) g_camera->Rotate (0, -td.SysDT); - if (dir > 4000 && dir < 14000) g_camera->Rotate (-td.SysDT, 0); - else if (dir > 22000 && dir < 32000) g_camera->Rotate ( td.SysDT, 0); + if (js->btn3) { // shift instrument panel + if ((js->hat & SDL_HAT_UP) != 0) g_camera->Rotate (0, td.SysDT); + else if ((js->hat & SDL_HAT_DOWN) != 0) g_camera->Rotate (0, -td.SysDT); + if ((js->hat & SDL_HAT_RIGHT) != 0) g_camera->Rotate (-td.SysDT, 0); + else if ((js->hat & SDL_HAT_LEFT) != 0) g_camera->Rotate ( td.SysDT, 0); } else { - if (dir < 5000 || dir > 31000) g_camera->AddTheta (-td.SysDT); - else if (dir > 13000 && dir < 23000) g_camera->AddTheta ( td.SysDT); - if (dir > 4000 && dir < 14000) g_camera->AddPhi ( td.SysDT); - else if (dir > 22000 && dir < 32000) g_camera->AddPhi (-td.SysDT); + if ((js->hat & SDL_HAT_UP) != 0) g_camera->AddTheta (-td.SysDT); + else if ((js->hat & SDL_HAT_DOWN) != 0) g_camera->AddTheta ( td.SysDT); + if ((js->hat & SDL_HAT_RIGHT) != 0) g_camera->AddPhi ( td.SysDT); + else if ((js->hat & SDL_HAT_LEFT) != 0) g_camera->AddPhi (-td.SysDT); } } else { // internal view - if (js->rgbButtons[2]) { // shift instrument panel - if (dir < 5000 || dir > 31000) g_pane->ShiftPanel (0.0, td.SysDT*pConfig->CfgLogicPrm.PanelScrollSpeed); - else if (dir > 13000 && dir < 23000) g_pane->ShiftPanel (0.0, -td.SysDT*pConfig->CfgLogicPrm.PanelScrollSpeed); - if (dir > 4000 && dir < 14000) g_pane->ShiftPanel (-td.SysDT*pConfig->CfgLogicPrm.PanelScrollSpeed, 0.0); - else if (dir > 22000 && dir < 32000) g_pane->ShiftPanel ( td.SysDT*pConfig->CfgLogicPrm.PanelScrollSpeed, 0.0); + if (js->btn3) { // shift instrument panel + if ((js->hat & SDL_HAT_UP) != 0) g_pane->ShiftPanel (0.0, td.SysDT*pConfig->CfgLogicPrm.PanelScrollSpeed); + else if ((js->hat & SDL_HAT_DOWN) != 0) g_pane->ShiftPanel (0.0, -td.SysDT*pConfig->CfgLogicPrm.PanelScrollSpeed); + if ((js->hat & SDL_HAT_RIGHT) != 0) g_pane->ShiftPanel (-td.SysDT*pConfig->CfgLogicPrm.PanelScrollSpeed, 0.0); + else if ((js->hat & SDL_HAT_LEFT) != 0) g_pane->ShiftPanel ( td.SysDT*pConfig->CfgLogicPrm.PanelScrollSpeed, 0.0); } else { // rotate camera - if (dir < 5000 || dir > 31000) g_camera->Rotate (0, td.SysDT, true); - else if (dir > 13000 && dir < 23000) g_camera->Rotate (0, -td.SysDT, true); - if (dir > 4000 && dir < 14000) g_camera->Rotate (-td.SysDT, 0, true); - else if (dir > 22000 && dir < 32000) g_camera->Rotate ( td.SysDT, 0, true); + if ((js->hat & SDL_HAT_UP) != 0) g_camera->Rotate (0, td.SysDT, true); + else if ((js->hat & SDL_HAT_DOWN) != 0) g_camera->Rotate (0, -td.SysDT, true); + if ((js->hat & SDL_HAT_RIGHT) != 0) g_camera->Rotate (-td.SysDT, 0, true); + else if ((js->hat & SDL_HAT_LEFT) != 0) g_camera->Rotate ( td.SysDT, 0, true); } } } @@ -2445,36 +2432,37 @@ void Orbiter::UserJoyInput_System (DIJOYSTATE2 *js) // Name: UserJoyInput_OnRunning () // Desc: User joystick input query for running simulation (ship controls etc.) //----------------------------------------------------------------------------- -void Orbiter::UserJoyInput_OnRunning (DIJOYSTATE2 *js) +void Orbiter::UserJoyInput_OnRunning (JoyState *js) { if (bEnableAtt) { - if (js->lX) { - if (js->rgbButtons[2]) { // emulate rudder control - if (js->lX > 0) ctrlJoystick[THGROUP_ATT_YAWRIGHT] = js->lX; - else ctrlJoystick[THGROUP_ATT_YAWLEFT] = -js->lX; + if (js->xAx) { + if (js->btn3) { // emulate rudder control + if (js->xAx > 0) ctrlJoystick[THGROUP_ATT_YAWRIGHT] = js->xAx; + else ctrlJoystick[THGROUP_ATT_YAWLEFT] = -js->xAx; } else { // rotation (bank) - if (js->lX > 0) ctrlJoystick[THGROUP_ATT_BANKRIGHT] = js->lX; - else ctrlJoystick[THGROUP_ATT_BANKLEFT] = -js->lX; + if (js->xAx > 0) ctrlJoystick[THGROUP_ATT_BANKRIGHT] = js->xAx; + else ctrlJoystick[THGROUP_ATT_BANKLEFT] = -js->xAx; } } - if (js->lY) { // rotation (pitch) or translation (vertical) - if (js->lY > 0) ctrlJoystick[THGROUP_ATT_PITCHUP] = ctrlJoystick[THGROUP_ATT_UP] = js->lY; - else ctrlJoystick[THGROUP_ATT_PITCHDOWN] = ctrlJoystick[THGROUP_ATT_DOWN] = -js->lY; + if (js->yAx) { // rotation (pitch) or translation (vertical) + if (js->yAx > 0) ctrlJoystick[THGROUP_ATT_PITCHUP] = ctrlJoystick[THGROUP_ATT_UP] = js->yAx; + else ctrlJoystick[THGROUP_ATT_PITCHDOWN] = ctrlJoystick[THGROUP_ATT_DOWN] = -js->yAx; } - if (js->lRz) { // rotation (yaw) or translation (transversal) - if (js->lRz > 0) ctrlJoystick[THGROUP_ATT_YAWRIGHT] = ctrlJoystick[THGROUP_ATT_RIGHT] = js->lRz; - else ctrlJoystick[THGROUP_ATT_YAWLEFT] = ctrlJoystick[THGROUP_ATT_LEFT] = -js->lRz; + if (js->zRot) { // rotation (yaw) or translation (transversal) + if (js->zRot > 0) ctrlJoystick[THGROUP_ATT_YAWRIGHT] = ctrlJoystick[THGROUP_ATT_RIGHT] = js->zRot; + else ctrlJoystick[THGROUP_ATT_YAWLEFT] = ctrlJoystick[THGROUP_ATT_LEFT] = -js->zRot; } } if (pDI->joyprop.bThrottle) { // main thrusters via throttle control - long lZ4 = *(long*)(((BYTE*)js)+pDI->joyprop.ThrottleOfs) >> 3; + long lZ4 = js->throttle; if (lZ4 != plZ4) { if (ignorefirst) { - if (abs(lZ4-plZ4) > 10) ignorefirst = false; + if (abs(lZ4-plZ4) > 128) ignorefirst = false; else return; } - double th = -0.008 * (plZ4 = lZ4); + // Map [-32768, 32767] to [0, 1] + double th = -((plZ4 = lZ4) - 32768) / 65536.0; if (th > 1.0) th = 1.0; g_focusobj->SetThrusterGroupLevel (THGROUP_MAIN, th); g_focusobj->SetThrusterGroupLevel (THGROUP_RETRO, 0.0); diff --git a/Src/Orbiter/Orbiter.h b/Src/Orbiter/Orbiter.h index 2b3bd3c35..af5b0d3d6 100644 --- a/Src/Orbiter/Orbiter.h +++ b/Src/Orbiter/Orbiter.h @@ -176,11 +176,6 @@ class Orbiter { inline void SetFastExit (bool fexit) { bFastExit = fexit; } inline bool UseHtmlInline() { return (pConfig->CfgDebugPrm.bHtmlScnDesc == 1 || pConfig->CfgDebugPrm.bHtmlScnDesc == 2 && !bWINEenv); } - // DirectInput components - inline CDIFramework7 *GetDInput() const { return pDI->GetDIFrame(); } - inline LPDIRECTINPUTDEVICE8 GetKbdDevice() const { return pDI->GetKbdDevice(); } - inline LPDIRECTINPUTDEVICE8 GetJoyDevice() const { return pDI->GetJoyDevice(); } - // memory monitor MemStat *memstat; long simheapsize; // memory allocated during CreateRenderWindow @@ -312,8 +307,8 @@ class Orbiter { void KbdInputImmediate_OnRunning (char *buffer); void KbdInputBuffered_System (char *kstate); void KbdInputBuffered_OnRunning (char *kstate); - void UserJoyInput_System (DIJOYSTATE2 *js); - void UserJoyInput_OnRunning (DIJOYSTATE2 *js); + void UserJoyInput_System (JoyState *js); + void UserJoyInput_OnRunning (JoyState *js); bool MouseEvent (const SDL_Event &event, DWORD x, DWORD y); bool BroadcastMouseEvent (const SDL_Event &event, DWORD x, DWORD y); bool BroadcastImmediateKeyboardEvent (char *kstate); From 1b11e21b832beae26daf8b087b9250e645c82a81 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Fri, 28 Feb 2025 20:31:05 -0600 Subject: [PATCH 45/51] Cleanup; remove SDL3_image --- CMakeLists.txt | 2 +- Extern/CMakeLists.txt | 1 - Extern/SDL3_image/CMakeLists.txt | 39 ------------------- OVP/D3D9Client/CMakeLists.txt | 3 -- Orbitersdk/CMakeLists.txt | 1 - Orbitersdk/include/GraphicsAPI.h | 2 +- .../{SDLWrappers.h => SDL3/SDL_oapi.h} | 17 +++++++- Src/Orbiter/CMakeLists.txt | 1 - Src/Orbiter/SDLWrappers.cpp | 2 +- 9 files changed, 19 insertions(+), 49 deletions(-) delete mode 100644 Extern/SDL3_image/CMakeLists.txt rename Orbitersdk/include/{SDLWrappers.h => SDL3/SDL_oapi.h} (77%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 478eee3ff..3a09a65dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,7 @@ set(ORBITER_INSTALL_DOC_DIR ${ORBITER_INSTALL_ROOT_DIR}/Doc) set(ORBITER_INSTALL_UTILS_DIR ${ORBITER_INSTALL_ROOT_DIR}/Utils) set(ORBITER_INSTALL_SDK_DIR ${ORBITER_INSTALL_ROOT_DIR}/Orbitersdk) -set(ORBITER_SDK_LIB $ SDL3::SDL3 SDL3_image::SDL3_image) +set(ORBITER_SDK_LIB $ SDL3::SDL3) set(ORBITER_DLGCTRL_LIB $) set(LUAINTERPRETER_LIB $) set(GDICLIENT_LIB $) diff --git a/Extern/CMakeLists.txt b/Extern/CMakeLists.txt index 0dea842f3..da77e26d9 100644 --- a/Extern/CMakeLists.txt +++ b/Extern/CMakeLists.txt @@ -8,7 +8,6 @@ add_subdirectory(Lua) add_subdirectory(zlib) add_subdirectory(imgui) add_subdirectory(SDL3) -add_subdirectory(SDL3_image) ## LFS add_library(lfs SHARED luafilesystem/src/lfs.c) diff --git a/Extern/SDL3_image/CMakeLists.txt b/Extern/SDL3_image/CMakeLists.txt deleted file mode 100644 index 6947b0a41..000000000 --- a/Extern/SDL3_image/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -project(SDL3_image) - -Include(FetchContent) - -# These formats we need -set(SDLIMAGE_BMP ON) -set(SDLIMAGE_JPG ON) -set(SDLIMAGE_PNG ON) -set(SDLIMAGE_GIF ON) -# Disable auto-enabled formats that we don't need (which add some additional dependencies) -set(SDLIMAGE_AVIF OFF) -set(SDLIMAGE_LBM OFF) -set(SDLIMAGE_PCX OFF) -set(SDLIMAGE_PNM OFF) -set(SDLIMAGE_QOI OFF) -set(SDLIMAGE_SVG OFF) -set(SDLIMAGE_TGA OFF) -set(SDLIMAGE_TIF OFF) -set(SDLIMAGE_WEBP OFF) -set(SDLIMAGE_XCF OFF) -set(SDLIMAGE_XPM OFF) -set(SDLIMAGE_XV OFF) - -FetchContent_Declare( - SDL3_image - GIT_REPOSITORY https://github.com/libsdl-org/SDL_Image.git - GIT_TAG release-3.2.0 -) -FetchContent_MakeAvailable(SDL3_image) - -set_target_properties(SDL3_image-shared PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${ORBITER_BINARY_ROOT_DIR} - LIBRARY_OUTPUT_DIRECTORY ${ORBITER_BINARY_ROOT_DIR} - RUNTIME_OUTPUT_DIRECTORY ${ORBITER_BINARY_ROOT_DIR} -) -file(GLOB SDL3_image_HEADERS "${SDL3_image_SOURCE_DIR}/include/SDL3_image/*.h") -file(COPY ${SDL3_image_HEADERS} DESTINATION "${ORBITER_BINARY_SDK_DIR}/include/SDL3_image") - -install(TARGETS SDL3_image-shared RUNTIME DESTINATION ${ORBITER_INSTALL_ROOT_DIR}) \ No newline at end of file diff --git a/OVP/D3D9Client/CMakeLists.txt b/OVP/D3D9Client/CMakeLists.txt index 136357dc7..7f7d02dda 100644 --- a/OVP/D3D9Client/CMakeLists.txt +++ b/OVP/D3D9Client/CMakeLists.txt @@ -176,7 +176,6 @@ target_include_directories(D3D9Client PUBLIC ${imgui_SOURCE_DIR}/ ${imgui_SOURCE_DIR}/backends/ SDL3::SDL3 - SDL3_image::SDL3_image ) target_link_directories(D3D9Client PUBLIC @@ -206,7 +205,6 @@ target_link_libraries(D3D9Client version.lib msimg32.lib SDL3::SDL3 - SDL3_image::SDL3_image ) set_target_properties(D3D9Client @@ -237,7 +235,6 @@ add_dependencies(D3D9Client Orbitersdk D3D9Client_Interface SDL3::SDL3 - SDL3_image::SDL3_image ) install(TARGETS D3D9Client diff --git a/Orbitersdk/CMakeLists.txt b/Orbitersdk/CMakeLists.txt index 9dd849165..912ad8f1a 100644 --- a/Orbitersdk/CMakeLists.txt +++ b/Orbitersdk/CMakeLists.txt @@ -32,7 +32,6 @@ add_custom_target(copy_sdk_include add_dependencies(Orbitersdk copy_sdk_include SDL3::SDL3 - SDL3_image::SDL3_image ) if(ORBITER_MAKE_DOC) diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index fd5b612b6..ad3db4d95 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -13,7 +13,7 @@ #include "Orbitersdk.h" -#include +#include #include #include "imgui.h" #include diff --git a/Orbitersdk/include/SDLWrappers.h b/Orbitersdk/include/SDL3/SDL_oapi.h similarity index 77% rename from Orbitersdk/include/SDLWrappers.h rename to Orbitersdk/include/SDL3/SDL_oapi.h index 7751c8e03..4c5d78bd1 100644 --- a/Orbitersdk/include/SDLWrappers.h +++ b/Orbitersdk/include/SDL3/SDL_oapi.h @@ -1,16 +1,23 @@ #ifndef SDLWRAPPERS_H #define SDLWRAPPERS_H +#include #include #include #include -#include namespace sdl { +/** + * \brief A wrapper for \ref SDL_Window which handles deletion and move. + * + * It is expected to be used with an external graphics API, e.g. OpenGL, Vulkan, + * or DirectX, rather than SDLGPU, hence "unmanaged". + */ class OAPIFUNC UnmanagedWindow { public: UnmanagedWindow(const UnmanagedWindow &) = delete; + UnmanagedWindow &operator=(const UnmanagedWindow &) = delete; UnmanagedWindow(UnmanagedWindow &&other) noexcept : m_inner(other.m_inner) { @@ -20,6 +27,8 @@ class OAPIFUNC UnmanagedWindow { UnmanagedWindow(std::string_view title, int width, int height, SDL_WindowFlags flags); + explicit UnmanagedWindow(SDL_Window *window) : m_inner(window) {} + ~UnmanagedWindow(); [[nodiscard]] SDL_Window *Inner() const { return m_inner; } @@ -34,6 +43,12 @@ class OAPIFUNC UnmanagedWindow { SDL_Window *m_inner = nullptr; }; +/** + * \brief A wrapper for \ref SDL_Window and \ref SDL_GPUDevice which handles + * setup, deletion, and move. + * + * It is expected to be used with SDLGPU, hence "managed". + */ class OAPIFUNC ManagedWindow { public: ManagedWindow(const ManagedWindow &) = delete; diff --git a/Src/Orbiter/CMakeLists.txt b/Src/Orbiter/CMakeLists.txt index cf639df95..fe39f3ca2 100644 --- a/Src/Orbiter/CMakeLists.txt +++ b/Src/Orbiter/CMakeLists.txt @@ -144,7 +144,6 @@ set(Orbiter_common_libs $ $ SDL3::SDL3 - SDL3_image::SDL3_image ) set(Orbiter_libs dxguid.lib diff --git a/Src/Orbiter/SDLWrappers.cpp b/Src/Orbiter/SDLWrappers.cpp index 19be24256..5fbb3d676 100644 --- a/Src/Orbiter/SDLWrappers.cpp +++ b/Src/Orbiter/SDLWrappers.cpp @@ -1,5 +1,5 @@ #define OAPI_IMPLEMENTATION -#include "SDLWrappers.h" +#include "SDL3/SDL_oapi.h" #include #include From ec2b5a182735530c343cd7f073ce2ffa0724d3d8 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Fri, 28 Feb 2025 20:38:53 -0600 Subject: [PATCH 46/51] Remove unused include --- Orbitersdk/include/GraphicsAPI.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index ad3db4d95..d64c38e98 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -15,7 +15,6 @@ #include #include -#include "imgui.h" #include #ifndef _WIN32 From bd0802ae25eee9135024130bc1b5609c712068ec Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Fri, 28 Feb 2025 20:40:35 -0600 Subject: [PATCH 47/51] Fix encoding issue --- Src/Orbiter/Camera.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/Orbiter/Camera.cpp b/Src/Orbiter/Camera.cpp index c316ad7d6..f80343d09 100644 --- a/Src/Orbiter/Camera.cpp +++ b/Src/Orbiter/Camera.cpp @@ -866,7 +866,7 @@ void Camera::OutputGroundObserverParams () const HWND dlg = dlgmgr->IsEntry (g_pOrbiter->GetInstance(), IDD_CAMERA); if (dlg) { char cbuf[256]; - sprintf (cbuf, "Lng = %+0.6f�\r\nLat = %+0.6f�\r\nAlt = %0.2fm\r\nPhi = %0.2f�\r\nTheta = %0.2f�", + sprintf (cbuf, "Lng = %+0.6f°\r\nLat = %+0.6f°\r\nAlt = %0.2fm\r\nPhi = %0.2f°\r\nTheta = %0.2f°", DEG*go.lng, DEG*go.lat, go.alt, DEG*go.phi, DEG*go.tht); SendDlgMessage (1, cbuf); } From 94e39dbb7d89437267f1cbbb26b7d1997ea8a1cd Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Fri, 28 Feb 2025 20:43:29 -0600 Subject: [PATCH 48/51] Undo name change --- Src/Orbiter/Orbiter.cpp | 28 ++++++++++++++-------------- Src/Orbiter/Orbiter.h | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 779d29b76..d700ba368 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -301,7 +301,7 @@ Orbiter::Orbiter () fine_counter_step = 1.0 / freq; } - hInst = GetModuleHandle(nullptr); + hInstance = GetModuleHandle(nullptr); pDI = new DInput(this); TRACENEW pConfig = new Config; TRACENEW pState = NULL; @@ -381,8 +381,8 @@ bool Orbiter::Create() pState = new State(); TRACENEW // Register main dialog window class - GetClassInfo (hInst, "#32770", &wndClass); // override default dialog class - wndClass.hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDI_MAIN_ICON)); + GetClassInfo (hInstance, "#32770", &wndClass); // override default dialog class + wndClass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_MAIN_ICON)); RegisterClass (&wndClass); // Find out if we are running under Linux/WINE @@ -392,8 +392,8 @@ bool Orbiter::Create() bWINEenv = (ret == ERROR_SUCCESS); // Register HTML viewer class - RegisterHtmlCtrl (hInst, UseHtmlInline()); - CustomCtrl::RegisterClass (hInst); + RegisterHtmlCtrl (hInstance, UseHtmlInline()); + CustomCtrl::RegisterClass (hInstance); if (pConfig->CfgCmdlinePrm.bFastExit) SetFastExit(true); @@ -401,7 +401,7 @@ bool Orbiter::Create() OpenVideoTab(); if (pConfig->CfgDemoPrm.bBkImage) { - hBk = CreateDialog (hInst, MAKEINTRESOURCE(IDD_DEMOBK), NULL, BkMsgProc); + hBk = CreateDialog (hInstance, MAKEINTRESOURCE(IDD_DEMOBK), NULL, BkMsgProc); ShowWindow (hBk, SW_MAXIMIZE); } @@ -474,7 +474,7 @@ VOID Orbiter::CloseApp (bool fast_shutdown) delete []customcmd; customcmd = NULL; } - oapiUnregisterCustomControls (hInst); + oapiUnregisterCustomControls (hInstance); } timeEndPeriod (1); } @@ -1391,7 +1391,7 @@ VOID Orbiter::SetFOV (double fov, bool limit_range) // update Camera dialog HWND hCamDlg; - if (pDlgMgr && (hCamDlg = pDlgMgr->IsEntry (hInst, IDD_CAMERA))) + if (pDlgMgr && (hCamDlg = pDlgMgr->IsEntry (hInstance, IDD_CAMERA))) SendMessage (hCamDlg, WM_APP, 0, (LPARAM)&fov); } @@ -1408,7 +1408,7 @@ VOID Orbiter::IncFOV (double dfov) // update Camera dialog HWND hCamDlg; - if (pDlgMgr && (hCamDlg = pDlgMgr->IsEntry (hInst, IDD_CAMERA))) + if (pDlgMgr && (hCamDlg = pDlgMgr->IsEntry (hInstance, IDD_CAMERA))) SendMessage (hCamDlg, WM_APP, 0, (LPARAM)&fov); } @@ -1486,7 +1486,7 @@ void Orbiter::TogglePlanetariumMode() plnFlag ^= PLN_ENABLE; if (pDlgMgr) { - DlgOptions* dlg = pDlgMgr->EntryExists(hInst); + DlgOptions* dlg = pDlgMgr->EntryExists(hInstance); if (dlg) dlg->Update(); } @@ -1500,7 +1500,7 @@ void Orbiter::ToggleLabelDisplay() mkrFlag ^= MKR_ENABLE; if (pDlgMgr) { - DlgOptions* dlg = pDlgMgr->EntryExists(hInst); + DlgOptions* dlg = pDlgMgr->EntryExists(hInstance); if (dlg) dlg->Update(); } } @@ -1561,7 +1561,7 @@ void Orbiter::EndPlayback () if (snote_playback) snote_playback->ClearText(); bPlayback = false; if (pDlgMgr) { - HWND hDlg = pDlgMgr->IsEntry (hInst, IDD_RECPLAY); + HWND hDlg = pDlgMgr->IsEntry (hInstance, IDD_RECPLAY); if (hDlg) PostMessage (hDlg, WM_USER+1, 0, 0); } if (g_pane && g_pane->MIBar()) g_pane->MIBar()->SetPlayback(false); @@ -2626,12 +2626,12 @@ void Orbiter::UpdateDeallocationProgress() HWND Orbiter::OpenDialog (int id, DLGPROC pDlg, void *context) { - return OpenDialog (hInst, id, pDlg, context); + return OpenDialog (hInstance, id, pDlg, context); } HWND Orbiter::OpenDialogEx (int id, DLGPROC pDlg, DWORD flag, void *context) { - return OpenDialogEx (hInst, id, pDlg, flag, context); + return OpenDialogEx (hInstance, id, pDlg, flag, context); } HWND Orbiter::OpenDialog (HINSTANCE hInstance, int id, DLGPROC pDlg, void *context) diff --git a/Src/Orbiter/Orbiter.h b/Src/Orbiter/Orbiter.h index af5b0d3d6..cda3733e6 100644 --- a/Src/Orbiter/Orbiter.h +++ b/Src/Orbiter/Orbiter.h @@ -158,7 +158,7 @@ class Orbiter { // Increase camera field of view by dfov // Accessor functions - inline HINSTANCE GetInstance() const { return hInst; } + inline HINSTANCE GetInstance() const { return hInstance; } inline const std::shared_ptr& GetRenderWnd() const { return hRenderWnd; } inline bool IsFullscreen() const { return bFullscreen; } inline DWORD ViewW() const { return viewW; } @@ -351,7 +351,7 @@ class Orbiter { DialogManager *pDlgMgr; orbiter::ConsoleNG* m_pConsole; // The console window opened when Orbiter server is launched without a graphics client DInput *pDI; - HINSTANCE hInst; // orbiter instance handle + HINSTANCE hInstance; // orbiter instance handle std::shared_ptr hRenderWnd; // render window handle (NULL if no render support) HWND hBk; // background window handle (demo mode only) BOOL bRenderOnce; // flag for single frame render request From 0db66d09de925b8959c960ed615d29274f3c3484 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Fri, 28 Feb 2025 20:44:44 -0600 Subject: [PATCH 49/51] Remove added field which is never used --- Src/Orbiter/Orbiter.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Src/Orbiter/Orbiter.h b/Src/Orbiter/Orbiter.h index cda3733e6..a57978d49 100644 --- a/Src/Orbiter/Orbiter.h +++ b/Src/Orbiter/Orbiter.h @@ -395,8 +395,6 @@ class Orbiter { bool bRoughType; // font-smoothing disabled? bool bShouldQuit; - std::string currentScenario; - // Manual joystick/keyboard attitude inputs DWORD ctrlJoystick[15]; DWORD ctrlKeyboard[15]; From 75742bda6f41798560e221caaa8ece2af95a6bc8 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Fri, 28 Feb 2025 20:46:25 -0600 Subject: [PATCH 50/51] Undo encoding change --- Src/Orbiter/MfdMap_old.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Src/Orbiter/MfdMap_old.cpp b/Src/Orbiter/MfdMap_old.cpp index 7c370b79d..716689315 100644 --- a/Src/Orbiter/MfdMap_old.cpp +++ b/Src/Orbiter/MfdMap_old.cpp @@ -341,15 +341,15 @@ void Instrument_MapOld::UpdateDraw (oapi::Sketchpad *skp) strcpy (datastr[0]+13, btgt->Name()); skp->Text (x1, y+dy, datastr[0], strlen(datastr[0])); btgt->EquPos (blng, blat); - sprintf (cbuf, " Pos: %6.2f°%c %6.2f°%c", + sprintf (cbuf, " Pos: %6.2f�%c %6.2f�%c", Deg(fabs(blng)), blng >= 0.0 ? 'E':'W', Deg(fabs(blat)), blat >= 0.0 ? 'N':'S'); skp->Text (x1, y+2*dy, cbuf, strlen (cbuf)); if (sp) { rad = refplanet->Size(); Orthodome (sp->lng, sp->lat, blng, blat, adist, hdg); - sprintf (cbuf, " Dst: %s (%0.2f°)", DistStr (adist*rad), Deg(adist)); + sprintf (cbuf, " Dst: %s (%0.2f�)", DistStr (adist*rad), Deg(adist)); skp->Text (x1, y+3*dy, cbuf, strlen (cbuf)); - sprintf (cbuf, " Dir: %6.2f°", Deg(hdg)); + sprintf (cbuf, " Dir: %6.2f�", Deg(hdg)); skp->Text (x1, y+4*dy, cbuf, strlen (cbuf)); } } else { @@ -366,7 +366,7 @@ void Instrument_MapOld::UpdateDraw (oapi::Sketchpad *skp) if (tel && otgt->ElRef() == refplanet) { double lng, lat, r; refplanet->GlobalToEquatorial (otgt->GPos(), lng, lat, r); - sprintf (cbuf, " Pos: %6.2f°%c %6.2f°%c", + sprintf (cbuf, " Pos: %6.2f�%c %6.2f�%c", Deg(fabs(lng)), lng >= 0.0 ? 'E':'W', Deg(fabs(lat)), lat >= 0.0 ? 'N':'S'); skp->Text (x1, y, cbuf, strlen (cbuf)); y += dy; sprintf (cbuf, " Alt: %s", DistStr (r - refplanet->Size())); @@ -557,7 +557,7 @@ void Instrument_MapOld::CalcOrbitProj (const Elements *el, const Planet *planet, for (i = 0; i < npt05; i++) { rl.Set (mul (R, Vector(cosp[i],0,sinp[i]))); x = rl.x, y = rl.y, z = rl.z; - lng = atan2 (z,x) + Pi; // maps start at -Pi (180°W) + lng = atan2 (z,x) + Pi; // maps start at -Pi (180�W) lat = atan(y/std::hypot(x,z)); sp[i].x = (int)(lng*f1); if ((sp[i+npt05].x = sp[i].x + mapw05) >= mapw) sp[i+npt05].x -= mapw; From b3e31c237648c67f9405c203eb091ee6ad033206 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Fri, 28 Feb 2025 20:55:42 -0600 Subject: [PATCH 51/51] Resolve some TODOs --- OVP/D3D9Client/WindowMgr.cpp | 389 ++++++++++++++++++----------------- OVP/D3D9Client/WindowMgr.h | 1 + Src/Orbiter/Orbiter.cpp | 7 +- 3 files changed, 210 insertions(+), 187 deletions(-) diff --git a/OVP/D3D9Client/WindowMgr.cpp b/OVP/D3D9Client/WindowMgr.cpp index e83f4fabb..7743bc351 100644 --- a/OVP/D3D9Client/WindowMgr.cpp +++ b/OVP/D3D9Client/WindowMgr.cpp @@ -1071,12 +1071,34 @@ bool WindowManager::MainWindowProc(const SDL_Event &event) return false; } +bool WindowManager::MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static int xpos, ypos; + switch (uMsg) { + case WM_MOUSELEAVE: + case WM_MBUTTONDOWN: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + return false; + case WM_KEYDOWN: + { + return false; + } + case WM_MOUSEWHEEL: + return false; + case WM_MOUSEMOVE: + xpos = GET_X_LPARAM(lParam); + ypos = GET_Y_LPARAM(lParam); + MouseMoved(xpos, ypos); + break; + } - + return false; +} // =============================================================================================== // SideBar Implementation @@ -1524,189 +1546,188 @@ LRESULT SideBar::SideBarWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar static int xof, yof; static bool bUpdate = false; - // HWND hMain = pMgr->GetMainWindow(); - // - // switch(uMsg) { - // - // case WM_KEYDOWN: - // { - // pMgr->MainWindowProc(hWnd, uMsg, wParam, lParam); - // break; - // } - // - // - // case WM_MOUSEWHEEL: - // { - // if (GetStyle() == gcGUI::DS_FLOAT) break; - // - // int old = rollpos; - // short d = GET_WHEEL_DELTA_WPARAM(wParam); - // if (d>0) rollpos += pMgr->cfg.scroll; - // else rollpos -= pMgr->cfg.scroll; - // int q = height - wndlen; - // if (q > 0) q = 0; - // if (rollpos > 0) rollpos = 0; - // if (rollpos < q) rollpos = q; - // if (old != rollpos) Invalidate(); - // break; - // } - // - // case WM_LBUTTONDOWN: - // { - // xpos = GET_X_LPARAM(lParam); - // ypos = GET_Y_LPARAM(lParam); - // - // for (Node* nd : wList) - // { - // Node *pPar = nd->pParent; - // - // if (pPar) { - // if (pPar->GetSideBar() == this) { - // if (pPar->bOpen == false) continue; - // } - // } - // - // if (PointInside(xpos, ypos, &(nd->trect))) { - // - // if (nd->bClose && PointInside(xpos, ypos, &(nd->crect))) { - // dnClose = nd; - // } - // else { - // xof = xpos - nd->trect.left; - // yof = ypos - nd->trect.top; - // dnNode = nd; - // } - // TRACKMOUSEEVENT te; te.cbSize = sizeof(TRACKMOUSEEVENT); te.dwFlags = TME_LEAVE; te.hwndTrack = hBar; - // TrackMouseEvent(&te); - // break; // break for - // } - // } - // break; - // } - // - // case WM_LBUTTONUP: - // { - // int xp = GET_X_LPARAM(lParam); - // int yp = GET_Y_LPARAM(lParam); - // - // SideBar *pDG = pMgr->GetDraged(); - // - // if (pDG) { - // SideBar *pTgt = pMgr->FindDestination(); - // if (pTgt) pTgt->Apply(); - // pMgr->EndDrag(); - // ReleaseCapture(); - // dnNode = NULL; - // dnClose = NULL; - // break; - // } - // - // if (dnNode) { - // if (dnNode->GetSideBar() == this) { - // if (PointInside(xp, yp, &(dnNode->trect))) { - // dnNode->bOpen = !dnNode->bOpen; - // if (IsFloater()) RescaleWindow(); - // Invalidate(); - // DWORD msg = (dnNode->bOpen ? gcGUI::MSG_OPEN_NODE : gcGUI::MSG_CLOSE_NODE); - // dnNode->pApp->clbkMessage(msg, dnNode, 0); - // } - // } - // } - // - // if (dnClose) { - // if (dnClose->GetSideBar() == this) { - // if (PointInside(xp, yp, &(dnClose->crect))) { - // if (dnClose->pApp->clbkMessage(gcGUI::MSG_CLOSE_APP, NULL, 0)) - // { - // pMgr->CloseWindow(dnClose); - // } - // } - // } - // } - // - // dnNode = NULL; - // dnClose = NULL; - // break; - // } - // - // - // case WM_MOUSELEAVE: - // { - // dnNode = NULL; - // dnClose = NULL; - // break; - // } - // - // - // case WM_MOUSEMOVE: - // { - // int dx = abs(GET_X_LPARAM(lParam) - xpos); - // int dy = abs(GET_Y_LPARAM(lParam) - ypos); - // int x = GET_X_LPARAM(lParam); - // int y = GET_Y_LPARAM(lParam); - // - // if (Config->gcGUIMode < 3) { - // - // POINT scp = { x, y }; - // ClientToScreen(hWnd, &scp); - // - // // Begin Moving a Window - // // - // if (dnNode && IsFloater() && (GetTopNode() == dnNode) && (dx > 1 || dy > 1)) - // { - // SetCapture(hBar); - // pMgr->SetOffset(xof, yof); - // pMgr->BeginMove(dnNode, scp.x, scp.y); - // dnNode = NULL; - // dnClose = NULL; - // break; - // } - // - // // Detach a window from a dock - // // - // if (Config->gcGUIMode == 1) { - // if (dnNode && dx > 25) { - // SetCapture(hBar); - // pMgr->SetOffset(xof, yof); - // SideBar* pTgt = pMgr->StartDrag(dnNode, scp.x, scp.y); - // dnNode = NULL; - // dnClose = NULL; - // break; - // } - // } - // - // // Move a dragged window and try to insert content into a dock - // // - // if (pMgr->GetDraged()) { - // pMgr->MouseMoved(scp.x, scp.y); - // pMgr->Drag(scp.x, scp.y); - // SideBar *pTgt = pMgr->FindDestination(); - // SideBar *pDG = pMgr->GetDraged(); - // if (pTgt) if (pTgt->IsOpen()) { - // if (pTgt->TryInsert(pDG)) { - // if (pTgt->GetStyle() == gcGUI::DS_FLOAT) pTgt->RescaleWindow(); - // pTgt->Invalidate(); - // pDG->Invalidate(); - // } - // } - // break; - // } - // } - // break; - // } - // - // case WM_PAINT: - // PaintWindow(); - // break; - // - // case WM_ERASEBKGND: - // return 1; - // - // default: - // break; - // } - // - // TODO TODO TODO + HWND hMain = pMgr->GetMainWindow(); + + switch(uMsg) { + + case WM_KEYDOWN: + { + pMgr->MainWindowProc(hWnd, uMsg, wParam, lParam); + break; + } + + + case WM_MOUSEWHEEL: + { + if (GetStyle() == gcGUI::DS_FLOAT) break; + + int old = rollpos; + short d = GET_WHEEL_DELTA_WPARAM(wParam); + if (d>0) rollpos += pMgr->cfg.scroll; + else rollpos -= pMgr->cfg.scroll; + int q = height - wndlen; + if (q > 0) q = 0; + if (rollpos > 0) rollpos = 0; + if (rollpos < q) rollpos = q; + if (old != rollpos) Invalidate(); + break; + } + + case WM_LBUTTONDOWN: + { + xpos = GET_X_LPARAM(lParam); + ypos = GET_Y_LPARAM(lParam); + + for (Node* nd : wList) + { + Node *pPar = nd->pParent; + + if (pPar) { + if (pPar->GetSideBar() == this) { + if (pPar->bOpen == false) continue; + } + } + + if (PointInside(xpos, ypos, &(nd->trect))) { + + if (nd->bClose && PointInside(xpos, ypos, &(nd->crect))) { + dnClose = nd; + } + else { + xof = xpos - nd->trect.left; + yof = ypos - nd->trect.top; + dnNode = nd; + } + TRACKMOUSEEVENT te; te.cbSize = sizeof(TRACKMOUSEEVENT); te.dwFlags = TME_LEAVE; te.hwndTrack = hBar; + TrackMouseEvent(&te); + break; // break for + } + } + break; + } + + case WM_LBUTTONUP: + { + int xp = GET_X_LPARAM(lParam); + int yp = GET_Y_LPARAM(lParam); + + SideBar *pDG = pMgr->GetDraged(); + + if (pDG) { + SideBar *pTgt = pMgr->FindDestination(); + if (pTgt) pTgt->Apply(); + pMgr->EndDrag(); + ReleaseCapture(); + dnNode = NULL; + dnClose = NULL; + break; + } + + if (dnNode) { + if (dnNode->GetSideBar() == this) { + if (PointInside(xp, yp, &(dnNode->trect))) { + dnNode->bOpen = !dnNode->bOpen; + if (IsFloater()) RescaleWindow(); + Invalidate(); + DWORD msg = (dnNode->bOpen ? gcGUI::MSG_OPEN_NODE : gcGUI::MSG_CLOSE_NODE); + dnNode->pApp->clbkMessage(msg, dnNode, 0); + } + } + } + + if (dnClose) { + if (dnClose->GetSideBar() == this) { + if (PointInside(xp, yp, &(dnClose->crect))) { + if (dnClose->pApp->clbkMessage(gcGUI::MSG_CLOSE_APP, NULL, 0)) + { + pMgr->CloseWindow(dnClose); + } + } + } + } + + dnNode = NULL; + dnClose = NULL; + break; + } + + + case WM_MOUSELEAVE: + { + dnNode = NULL; + dnClose = NULL; + break; + } + + + case WM_MOUSEMOVE: + { + int dx = abs(GET_X_LPARAM(lParam) - xpos); + int dy = abs(GET_Y_LPARAM(lParam) - ypos); + int x = GET_X_LPARAM(lParam); + int y = GET_Y_LPARAM(lParam); + + if (Config->gcGUIMode < 3) { + + POINT scp = { x, y }; + ClientToScreen(hWnd, &scp); + + // Begin Moving a Window + // + if (dnNode && IsFloater() && (GetTopNode() == dnNode) && (dx > 1 || dy > 1)) + { + SetCapture(hBar); + pMgr->SetOffset(xof, yof); + pMgr->BeginMove(dnNode, scp.x, scp.y); + dnNode = NULL; + dnClose = NULL; + break; + } + + // Detach a window from a dock + // + if (Config->gcGUIMode == 1) { + if (dnNode && dx > 25) { + SetCapture(hBar); + pMgr->SetOffset(xof, yof); + SideBar* pTgt = pMgr->StartDrag(dnNode, scp.x, scp.y); + dnNode = NULL; + dnClose = NULL; + break; + } + } + + // Move a dragged window and try to insert content into a dock + // + if (pMgr->GetDraged()) { + pMgr->MouseMoved(scp.x, scp.y); + pMgr->Drag(scp.x, scp.y); + SideBar *pTgt = pMgr->FindDestination(); + SideBar *pDG = pMgr->GetDraged(); + if (pTgt) if (pTgt->IsOpen()) { + if (pTgt->TryInsert(pDG)) { + if (pTgt->GetStyle() == gcGUI::DS_FLOAT) pTgt->RescaleWindow(); + pTgt->Invalidate(); + pDG->Invalidate(); + } + } + break; + } + } + break; + } + + case WM_PAINT: + PaintWindow(); + break; + + case WM_ERASEBKGND: + return 1; + + default: + break; + } + return DefWindowProc(hWnd, uMsg, wParam, lParam); } diff --git a/OVP/D3D9Client/WindowMgr.h b/OVP/D3D9Client/WindowMgr.h index d9558b863..bc4e0a481 100644 --- a/OVP/D3D9Client/WindowMgr.h +++ b/OVP/D3D9Client/WindowMgr.h @@ -179,6 +179,7 @@ class WindowManager : public gcGUIBase // =============================================================================================== // bool MainWindowProc(const SDL_Event &event); + bool MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void Animate(); int GetWidth() const { return width; } HWND GetMainWindow() const { return hMainWnd; } diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index d700ba368..879ac4242 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -2000,9 +2000,10 @@ VOID Orbiter::UpdateWorld () g_bStateUpdate = false; if (!KillVessels()) // kill any vessels marked for deletion - {} - // TODO - // if (hRenderWnd) DestroyWindow (hRenderWnd); + { + // FIXME(@ThePuzzlemaker): I'm not really sure what's the best way to go about this + SDL_DestroyWindow(hRenderWnd->Inner()); + } //g_texmanager->OutputInfo(); }